From patchwork Fri Feb 26 09:27:55 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haojian Zhuang X-Patchwork-Id: 62979 Delivered-To: patch@linaro.org Received: by 10.112.199.169 with SMTP id jl9csp608667lbc; Fri, 26 Feb 2016 01:28:51 -0800 (PST) X-Received: by 10.98.89.4 with SMTP id n4mr616106pfb.81.1456478931664; Fri, 26 Feb 2016 01:28:51 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id l9si18787153pfi.44.2016.02.26.01.28.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 26 Feb 2016 01:28:51 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dkim=neutral (body hash did not verify) header.i=@linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 240F81A1E14; Fri, 26 Feb 2016 01:28:56 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-ob0-x22f.google.com (mail-ob0-x22f.google.com [IPv6:2607:f8b0:4003:c01::22f]) (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 616E41A1E0D for ; Fri, 26 Feb 2016 01:28:54 -0800 (PST) Received: by mail-ob0-x22f.google.com with SMTP id jq7so72835870obb.0 for ; Fri, 26 Feb 2016 01:28:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=message-id:from:to:cc:subject:date:in-reply-to:references :mime-version; bh=kHKsXyLPEOzICH+VM+D01uyePgSFxsiXaH6FEE/+H3E=; b=F46wnYZveQFEslRR8ojn7BxYggFQClTTHB32936c9u4dBqVdZWJCIBT4JupvHqfK/a U4D4wSmo6XIFgErXrkHsuLEbRRRia2x1cTHPrkaxC/wd+YTmAA1Xe0ekoetSWjnbBMrp 2C+xNhDwqfCmcXxyEK9F/Ew0qiCEgVHVI8vcg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:message-id:from:to:cc:subject:date:in-reply-to :references:mime-version; bh=kHKsXyLPEOzICH+VM+D01uyePgSFxsiXaH6FEE/+H3E=; b=SfPsNP1YFo+ZejsYbNX7FS1+YwgLHSxC+eDSABT+QCwT0im//ssxJPMAh/vp/r52de GxawhVlz5NwyairGCoqhi4psYIrV16LXMjzh0QW2y1JMfTmcT3L12OTRd6PPxKbwHKzC UqtqyKTGgDbZuetnE7wC9PhTq/8NzE5kN4ESoLdIL5N9geKENIOC8gFrHxVp1s7JEbaN QwLlnSnJxqpW5Wx66mOBA1/mKv43co8NgHLov+S7KWfxHCQnDBF4s4PNERoB8vxOyu5j qjLLQJjrxoVUIVOX6+D2TDm5+LjAvt3ro1ZBHfvJ2qYKBKKo0VD7kluR0gZFHi1fPlpB zoIQ== X-Gm-Message-State: AD7BkJKVEHK5LelIGmFYw9G8+yDt8x73S2g6hiPDSR2kmDHwHgZF4KyHEEA9FKDaLovnn7UH X-Received: by 10.60.76.10 with SMTP id g10mr375498oew.50.1456478928757; Fri, 26 Feb 2016 01:28:48 -0800 (PST) Received: from mail.hotmail.com (blu004-wss1s2.hotmail.com. [134.170.2.217]) by smtp.gmail.com with ESMTPSA id y9sm8253693obg.4.2016.02.26.01.28.47 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 26 Feb 2016 01:28:47 -0800 (PST) Received: from BLU437-SMTP102 ([134.170.2.215]) by BLU004-WSS1S2.hotmail.com over TLS secured channel with Microsoft SMTPSVC(7.5.7601.23008); Fri, 26 Feb 2016 01:28:46 -0800 X-TMN: [73ibiagLtphLkTCwuzv11sAWVuzLUJ7n] Message-ID: From: Haojian Zhuang To: edk2-devel@lists.01.org, leif.lindholm@linaro.org, ard.biesheuvel@linaro.org Date: Fri, 26 Feb 2016 17:27:55 +0800 X-Mailer: git-send-email 1.9.1 In-Reply-To: <1456478876-23434-1-git-send-email-haojian.zhuang@linaro.org> References: <1456478876-23434-1-git-send-email-haojian.zhuang@linaro.org> X-OriginalArrivalTime: 26 Feb 2016 09:28:44.0524 (UTC) FILETIME=[166F62C0:01D17078] MIME-Version: 1.0 Cc: Haojian Zhuang Subject: [edk2] [PATCH 8/9] MmcDxe: set iospeed and bus width in SD stack X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" Add more SD commands to support 4-bit bus width & iospeed. It's not formal code. And it needs to be updated later. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Haojian Zhuang --- EmbeddedPkg/Include/Protocol/MmcHost.h | 1 + EmbeddedPkg/Universal/MmcDxe/Mmc.h | 17 +++ EmbeddedPkg/Universal/MmcDxe/MmcIdentification.c | 130 ++++++++++++++++++++--- 3 files changed, 132 insertions(+), 16 deletions(-) -- 1.9.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/EmbeddedPkg/Include/Protocol/MmcHost.h b/EmbeddedPkg/Include/Protocol/MmcHost.h index 5e3a2b7..ce0a024 100644 --- a/EmbeddedPkg/Include/Protocol/MmcHost.h +++ b/EmbeddedPkg/Include/Protocol/MmcHost.h @@ -62,6 +62,7 @@ typedef UINT32 MMC_CMD; #define MMC_CMD20 (MMC_INDX(20) | MMC_CMD_WAIT_RESPONSE) #define MMC_CMD23 (MMC_INDX(23) | MMC_CMD_WAIT_RESPONSE) #define MMC_CMD24 (MMC_INDX(24) | MMC_CMD_WAIT_RESPONSE) +#define MMC_CMD51 (MMC_INDX(51) | 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) diff --git a/EmbeddedPkg/Universal/MmcDxe/Mmc.h b/EmbeddedPkg/Universal/MmcDxe/Mmc.h index 0ccbc80..a62ba32 100644 --- a/EmbeddedPkg/Universal/MmcDxe/Mmc.h +++ b/EmbeddedPkg/Universal/MmcDxe/Mmc.h @@ -75,6 +75,23 @@ typedef struct { UINT32 PowerUp: 1; // This bit is set to LOW if the card has not finished the power up routine } OCR; +/* For little endian CPU */ +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 f806bfc..9daa662 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, @@ -69,28 +77,30 @@ EmmcGetDeviceState ( { EFI_MMC_HOST_PROTOCOL *Host; EFI_STATUS Status; - UINT32 Data, RCA; + UINT32 Rsp[4], RCA; if (State == NULL) return EFI_INVALID_PARAMETER; Host = MmcHostInstance->MmcHost; RCA = MmcHostInstance->CardInfo.RCA << RCA_SHIFT_OFFSET; - Status = Host->SendCommand (Host, MMC_CMD13, RCA); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EmmcGetDeviceState(): Failed to get card status, Status=%r.\n", Status)); - return Status; - } - Status = Host->ReceiveResponse (Host, MMC_RESPONSE_TYPE_R1, &Data); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EmmcGetDeviceState(): Failed to get response of CMD13, Status=%r.\n", Status)); - return Status; - } - if (Data & EMMC_SWITCH_ERROR) { - DEBUG ((EFI_D_ERROR, "EmmcGetDeviceState(): Failed to switch expected mode, Status=%r.\n", Status)); - return EFI_DEVICE_ERROR; - } - *State = DEVICE_STATE(Data); + do { + Status = Host->SendCommand (Host, MMC_CMD13, RCA); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "EmmcGetDeviceState(): Failed to get card status, Status=%r.\n", Status)); + return Status; + } + Status = Host->ReceiveResponse (Host, MMC_RESPONSE_TYPE_R1, Rsp); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "EmmcGetDeviceState(): Failed to get response of CMD13, Status=%r.\n", Status)); + return Status; + } + if (Rsp[0] & EMMC_SWITCH_ERROR) { + DEBUG ((EFI_D_ERROR, "EmmcGetDeviceState(): Failed to switch expected mode, Status=%r.\n", Status)); + return EFI_DEVICE_ERROR; + } + } while (!(Rsp[0] & MMC_R0_READY_FOR_DATA)); + *State = MMC_R0_CURRENTSTATE(Rsp); return EFI_SUCCESS; } @@ -305,9 +315,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; @@ -328,6 +341,10 @@ 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); @@ -358,6 +375,87 @@ 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; + } + /* SCR */ + Status = MmcHost->SendCommand (MmcHost, MMC_CMD51, 0); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a(MMC_CMD51): Error and Status = %r\n", Status)); + return Status; + } else { + Status = MmcHost->ReadBlockData (MmcHost, 0, 8, Buffer); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "%a(MMC_CMD51): ReadBlockData Error and Status = %r\n", 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 (MmcHost->SetIos) { + 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; }