From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf0-x232.google.com (mail-pf0-x232.google.com [IPv6:2607:f8b0:400e:c00::232]) (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 889AA81EBC for ; Tue, 22 Nov 2016 23:09:01 -0800 (PST) Received: by mail-pf0-x232.google.com with SMTP id c4so1791397pfb.1 for ; Tue, 22 Nov 2016 23:09:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=cEuMoh13McNzaFizcpubLJ+/qrP99xZ2y00wR6xpxLE=; b=RLMaZ3Ny66u1cNOey5ivBjlby9B5Y80awHgr+Eudc+h3lmr7GAZh+V29aTRBUIz3OP 8OSEMWDF2zzQFjbesVA4e2Fj+ylrBWF7nBK/s0SDZikggOvd69oZfVY5Gi6xkaUNVAVT 0fxcR4UE3UoIpVKwobuhte1h61X6c+HtKmigw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=cEuMoh13McNzaFizcpubLJ+/qrP99xZ2y00wR6xpxLE=; b=AEfnV9Z5vCvmW+LDH7/RlhvnXd9jI9ijZ3hjc7gsxHnjpJcFriPHM8b/otnV+IkgB1 j/xviNgaulXBkYM4GflQxYZS78TZFqibbUmXMFyZJYAYN7lMcp4FcPjpgEWoAjVTueKA QsCb6ne8c5Zg/W/NAvjc3rMduwIttgvoTsG/OdLnylMUKOI7l7uWdnxJpuMn89AspihW CmsrDbBRZo9Y766IhIZo1yB8VKpygqpA1EMETRzWdp/RHG/04Rp3G0sKJCqufxD49YVr zOspagF8P5NMdZ16o5oF/iB7+FznI5eK/C28c5wGYGCltMxZfH/zaTCFI0cGDCGWGeJD 67fA== X-Gm-Message-State: AKaTC03C8iyC4tAkAHL+6StiU+9e6po/7CO/lkNaor6YedpcetZNttetpX32dJvygy0xPC7B X-Received: by 10.84.216.25 with SMTP id m25mr3690848pli.117.1479884941192; Tue, 22 Nov 2016 23:09:01 -0800 (PST) Received: from localhost.localdomain ([45.56.159.99]) by smtp.gmail.com with ESMTPSA id 65sm49873730pfn.12.2016.11.22.23.08.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 22 Nov 2016 23:09:00 -0800 (PST) From: Haojian Zhuang To: ryan.harkin@linaro.org, edk2-devel@lists.01.org, leif.lindholm@linaro.org, ard.biesheuvel@linaro.org Cc: Haojian Zhuang Date: Wed, 23 Nov 2016 15:08:39 +0800 Message-Id: <1479884921-25398-3-git-send-email-haojian.zhuang@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1479884921-25398-1-git-send-email-haojian.zhuang@linaro.org> References: <1479884921-25398-1-git-send-email-haojian.zhuang@linaro.org> Subject: [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 07:09:01 -0000 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); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a(SetIos): Error and Status = %r\n", Status)); + return Status; + } + } return EFI_SUCCESS; } -- 2.7.4