From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-io0-x231.google.com (mail-io0-x231.google.com [IPv6:2607:f8b0:4001:c06::231]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 0827E81C97 for ; Wed, 23 Nov 2016 00:58:47 -0800 (PST) Received: by mail-io0-x231.google.com with SMTP id j65so12913906iof.0 for ; Wed, 23 Nov 2016 00:58:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=jaLnzIkV1iVIUKZS++gJ6XkXH0C2zuCu6MZZcgQTpoI=; b=RrrV+/dF02Kh69nL7e5vCX8lGO3342v6NhKy9Li2knuhRvaSTEe7lh1Jwy+Qxfdrwl beIT8F0z63qs6/Lawzj17+ATpcmqaYNWT4jmfiRSc9zZx8RfWj6h3Bx24nnW1djvdXi9 BgHvv4XyMwIcXlMROr5xOPTJ//4RuZdS5mcUg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=jaLnzIkV1iVIUKZS++gJ6XkXH0C2zuCu6MZZcgQTpoI=; b=gDGbq5Hzcrl5DUxM1q0ZGCfnhtMVZCijAVvIZBWs+kS0jxBfyABDP+z9giMKK/bUO6 zVebvywXg3TBLUC/flo6JsBdOgYLrCqv7tlwed84ihaI7lIX0CJNvrc+LR3GADARvuH7 IoaapWDI8jWFaXpgf3+sOjuUCzhMeleniVSUABNkyZjjL6YhlxGezAVo0ZfhehBzp2GM pHwRVThPdV/IoFZ1R5cOCUwQo6YBymYtVg1PK64HwwSAMZQLo4u/2YklROSZg3kTBIZJ cgRJuqaGM/W7By7jpkTObOE61VTseYnPZnkvoBlG9/3zfIVUoIPBF5CGKPYQNLIe1JbU z6dQ== X-Gm-Message-State: AKaTC00jAWOhz8Lwa2Z7phcmgrNQa/J86+9QeyXiFB/gfiww8fq3+eE4/lywJYrxcQ8LJNC5rQ9hEwfY605ZV1Mo X-Received: by 10.107.18.39 with SMTP id a39mr1978169ioj.45.1479891526272; Wed, 23 Nov 2016 00:58:46 -0800 (PST) MIME-Version: 1.0 Received: by 10.107.59.147 with HTTP; Wed, 23 Nov 2016 00:58:45 -0800 (PST) In-Reply-To: <1479884921-25398-3-git-send-email-haojian.zhuang@linaro.org> References: <1479884921-25398-1-git-send-email-haojian.zhuang@linaro.org> <1479884921-25398-3-git-send-email-haojian.zhuang@linaro.org> From: Ard Biesheuvel Date: Wed, 23 Nov 2016 08:58:45 +0000 Message-ID: To: Haojian Zhuang Cc: Ryan Harkin , edk2-devel-01 , Leif Lindholm Subject: Re: [PATCH v7 2/4] MmcDxe: set iospeed and bus width in SD stack X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Nov 2016 08:58:47 -0000 Content-Type: text/plain; charset=UTF-8 On 23 November 2016 at 07:08, Haojian Zhuang wrote: > Add more SD commands to support 4-bit bus width & iospeed. > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Haojian Zhuang > Tested-by: Ryan Harkin > --- > EmbeddedPkg/Include/Protocol/MmcHost.h | 3 + > EmbeddedPkg/Universal/MmcDxe/Mmc.h | 16 ++++ > EmbeddedPkg/Universal/MmcDxe/MmcIdentification.c | 106 +++++++++++++++++++++++ > 3 files changed, 125 insertions(+) > > diff --git a/EmbeddedPkg/Include/Protocol/MmcHost.h b/EmbeddedPkg/Include/Protocol/MmcHost.h > index 9d7a604..445e53f 100644 > --- a/EmbeddedPkg/Include/Protocol/MmcHost.h > +++ b/EmbeddedPkg/Include/Protocol/MmcHost.h > @@ -64,11 +64,14 @@ typedef UINT32 MMC_CMD; > #define MMC_CMD24 (MMC_INDX(24) | MMC_CMD_WAIT_RESPONSE) > #define MMC_CMD55 (MMC_INDX(55) | MMC_CMD_WAIT_RESPONSE) > #define MMC_ACMD41 (MMC_INDX(41) | MMC_CMD_WAIT_RESPONSE | MMC_CMD_NO_CRC_RESPONSE) > +#define MMC_ACMD51 (MMC_INDX(51) | MMC_CMD_WAIT_RESPONSE) > > // Valid responses for CMD1 in eMMC > #define EMMC_CMD1_CAPACITY_LESS_THAN_2GB 0x00FF8080 // Capacity <= 2GB, byte addressing used > #define EMMC_CMD1_CAPACITY_GREATER_THAN_2GB 0x40FF8080 // Capacity > 2GB, 512-byte sector addressing used > > +#define MMC_STATUS_APP_CMD (1 << 5) > + > typedef enum _MMC_STATE { > MmcInvalidState = 0, > MmcHwInitializationState, > diff --git a/EmbeddedPkg/Universal/MmcDxe/Mmc.h b/EmbeddedPkg/Universal/MmcDxe/Mmc.h > index fb3f6c9..6bc85e0 100644 > --- a/EmbeddedPkg/Universal/MmcDxe/Mmc.h > +++ b/EmbeddedPkg/Universal/MmcDxe/Mmc.h > @@ -80,6 +80,22 @@ typedef struct { > UINT32 PowerUp: 1; // This bit is set to LOW if the card has not finished the power up routine > } OCR; > > +typedef struct { > + UINT8 SD_SPEC: 4; // SD Memory Card - Spec. Version [59:56] > + UINT8 SCR_STRUCTURE: 4; // SCR Structure [63:60] > + UINT8 SD_BUS_WIDTHS: 4; // DAT Bus widths supported [51:48] > + UINT8 DATA_STAT_AFTER_ERASE: 1; // Data Status after erases [55] > + UINT8 SD_SECURITY: 3; // CPRM Security Support [54:52] > + UINT8 EX_SECURITY_1: 1; // Extended Security Support [43] > + UINT8 SD_SPEC4: 1; // Spec. Version 4.00 or higher [42] > + UINT8 RESERVED_1: 2; // Reserved [41:40] > + UINT8 SD_SPEC3: 1; // Spec. Version 3.00 or higher [47] > + UINT8 EX_SECURITY_2: 3; // Extended Security Support [46:44] > + UINT8 CMD_SUPPORT: 4; // Command Support bits [35:32] > + UINT8 RESERVED_2: 4; // Reserved [39:36] > + UINT32 RESERVED_3; // Manufacturer Usage [31:0] > +} SCR; > + > typedef struct { > UINT32 NOT_USED; // 1 [0:0] > UINT32 CRC; // CRC7 checksum [7:1] > diff --git a/EmbeddedPkg/Universal/MmcDxe/MmcIdentification.c b/EmbeddedPkg/Universal/MmcDxe/MmcIdentification.c > index 7441459..c47a92b 100644 > --- a/EmbeddedPkg/Universal/MmcDxe/MmcIdentification.c > +++ b/EmbeddedPkg/Universal/MmcDxe/MmcIdentification.c > @@ -12,6 +12,9 @@ > * > **/ > > +#include > +#include > + > #include "Mmc.h" > > typedef union { > @@ -41,6 +44,11 @@ typedef union { > > #define EMMC_SWITCH_ERROR (1 << 7) > > +#define SD_BUS_WIDTH_1BIT (1 << 0) > +#define SD_BUS_WIDTH_4BIT (1 << 2) > + > +#define SD_CCC_SWITCH (1 << 10) > + > #define DEVICE_STATE(x) (((x) >> 9) & 0xf) > typedef enum _EMMC_DEVICE_STATE { > EMMC_IDLE_STATE = 0, > @@ -296,9 +304,12 @@ InitializeSdMmcDevice ( > { > UINT32 CmdArg; > UINT32 Response[4]; > + UINT32 Buffer[128]; > UINTN BlockSize; > UINTN CardSize; > UINTN NumBlocks; > + BOOLEAN CccSwitch; > + SCR Scr; > EFI_STATUS Status; > EFI_MMC_HOST_PROTOCOL *MmcHost; > > @@ -319,6 +330,11 @@ InitializeSdMmcDevice ( > return Status; > } > PrintCSD (Response); > + if (MMC_CSD_GET_CCC(Response) & SD_CCC_SWITCH) { > + CccSwitch = TRUE; > + } else { > + CccSwitch = FALSE; > + } > > if (MmcHostInstance->CardInfo.CardType == SD_CARD_2_HIGH) { > CardSize = HC_MMC_CSD_GET_DEVICESIZE (Response); > @@ -349,6 +365,96 @@ InitializeSdMmcDevice ( > return Status; > } > > + Status = MmcHost->SendCommand (MmcHost, MMC_CMD55, CmdArg); > + if (EFI_ERROR (Status)) { > + DEBUG ((EFI_D_ERROR, "%a(MMC_CMD55): Error and Status = %r\n", Status)); > + return Status; > + } > + Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_R1, Response); > + if (EFI_ERROR (Status)) { > + DEBUG ((EFI_D_ERROR, "%a(MMC_CMD55): Error and Status = %r\n", Status)); > + return Status; > + } > + if ((Response[0] & MMC_STATUS_APP_CMD) == 0) { > + return EFI_SUCCESS; > + } > + > + /* SCR */ > + Status = MmcHost->SendCommand (MmcHost, MMC_ACMD51, 0); > + if (EFI_ERROR (Status)) { > + DEBUG ((EFI_D_ERROR, "%a(MMC_ACMD51): Error and Status = %r\n", __func__, Status)); > + return Status; > + } else { > + Status = MmcHost->ReadBlockData (MmcHost, 0, 8, Buffer); > + if (EFI_ERROR (Status)) { > + DEBUG ((EFI_D_ERROR, "%a(MMC_ACMD51): ReadBlockData Error and Status = %r\n", __func__, Status)); > + return Status; > + } > + CopyMem (&Scr, Buffer, 8); > + if (Scr.SD_SPEC == 2) { > + if (Scr.SD_SPEC3 == 1) { > + if (Scr.SD_SPEC4 == 1) { > + DEBUG ((EFI_D_INFO, "Found SD Card for Spec Version 4.xx\n")); > + } else { > + DEBUG ((EFI_D_INFO, "Found SD Card for Spec Version 3.0x\n")); > + } > + } else { > + if (Scr.SD_SPEC4 == 0) { > + DEBUG ((EFI_D_INFO, "Found SD Card for Spec Version 2.0\n")); > + } else { > + DEBUG ((EFI_D_ERROR, "Found invalid SD Card\n")); > + } > + } > + } else { > + if ((Scr.SD_SPEC3 == 0) && (Scr.SD_SPEC4 == 0)) { > + if (Scr.SD_SPEC == 1) { > + DEBUG ((EFI_D_INFO, "Found SD Card for Spec Version 1.10\n")); > + } else { > + DEBUG ((EFI_D_INFO, "Found SD Card for Spec Version 1.0\n")); > + } > + } else { > + DEBUG ((EFI_D_ERROR, "Found invalid SD Card\n")); > + } > + } > + } > + if (CccSwitch) { > + /* SD Switch, Mode:1, Group:0, Value:1 */ > + CmdArg = 1 << 31 | 0x00FFFFFF; > + CmdArg &= ~(0xF << (0 * 4)); > + CmdArg |= 1 << (0 * 4); > + Status = MmcHost->SendCommand (MmcHost, MMC_CMD6, CmdArg); > + if (EFI_ERROR (Status)) { > + DEBUG ((EFI_D_ERROR, "%a(MMC_CMD6): Error and Status = %r\n", Status)); > + return Status; > + } else { > + Status = MmcHost->ReadBlockData (MmcHost, 0, 64, Buffer); > + if (EFI_ERROR (Status)) { > + DEBUG ((EFI_D_ERROR, "%a(MMC_CMD6): ReadBlockData Error and Status = %r\n", Status)); > + return Status; > + } > + } > + } > + if (Scr.SD_BUS_WIDTHS & SD_BUS_WIDTH_4BIT) { > + CmdArg = MmcHostInstance->CardInfo.RCA << 16; > + Status = MmcHost->SendCommand (MmcHost, MMC_CMD55, CmdArg); > + if (EFI_ERROR (Status)) { > + DEBUG ((EFI_D_ERROR, "%a(MMC_CMD55): Error and Status = %r\n", Status)); > + return Status; > + } > + /* Width: 4 */ > + Status = MmcHost->SendCommand (MmcHost, MMC_CMD6, 2); > + if (EFI_ERROR (Status)) { > + DEBUG ((EFI_D_ERROR, "%a(MMC_CMD6): Error and Status = %r\n", Status)); > + return Status; > + } > + } > + if (MMC_HOST_HAS_SETIOS(MmcHost)) { > + Status = MmcHost->SetIos (MmcHost, 24 * 1000 * 1000, 4, EMMCBACKWARD); Could you explain where the constant comes from? > + if (EFI_ERROR (Status)) { > + DEBUG ((EFI_D_ERROR, "%a(SetIos): Error and Status = %r\n", Status)); > + return Status; > + } > + } > return EFI_SUCCESS; > } > > -- > 2.7.4 >