From patchwork Tue Apr 5 09:49:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryan Harkin X-Patchwork-Id: 65060 Delivered-To: patch@linaro.org Received: by 10.112.199.169 with SMTP id jl9csp359544lbc; Tue, 5 Apr 2016 02:49:22 -0700 (PDT) X-Received: by 10.98.18.71 with SMTP id a68mr28290488pfj.41.1459849762747; Tue, 05 Apr 2016 02:49:22 -0700 (PDT) Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id r18si25913913pfi.140.2016.04.05.02.49.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 05 Apr 2016 02:49:22 -0700 (PDT) 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; dkim=neutral (body hash did not verify) header.i=@linaro.org; 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; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 960EF1A1EFD; Tue, 5 Apr 2016 02:49:21 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-oi0-x233.google.com (mail-oi0-x233.google.com [IPv6:2607:f8b0:4003:c06::233]) (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 7F90F1A1E3A for ; Tue, 5 Apr 2016 02:49:20 -0700 (PDT) Received: by mail-oi0-x233.google.com with SMTP id p188so10708956oih.2 for ; Tue, 05 Apr 2016 02:49:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc; bh=s8DZuQF4+fkyI4wNgyGlE+zL9azdJrzOIAcqsz9t+Zk=; b=Iq4Bp2BU49pa8wmdgAMaC+/mORzx3CVEtjU63h1VeZquUWm8J8dj7KQSmRIj45pmCL ig1ndRkxUMtQ6z4QDcgou8SIHee8A0ExftUjJImprXL1S4r3HQ+hNms90omr9thQdW/r oPkULQkJY99c5jwMvpeEa6RT3SMOb1EJZ6JTw= 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:date :message-id:subject:from:to:cc; bh=s8DZuQF4+fkyI4wNgyGlE+zL9azdJrzOIAcqsz9t+Zk=; b=DrRSInnpUc+iwwB9+yPWXWr/ORLo1rCW6v3C7FQPmhQcosqF2I8AQkS2+p7WGh563h 3/E5eoO0Mva3RTXhejYegY0KYhhNb0BeddYWIbdeUD2YdtBhmxdGz6EqYHeesh3SInI7 RSCL42cY5M4WiwhfdPiQeoR2inVBMO4yaapKtyTgM5z1erlse9fn2ao36aQqBPQjI0vD hD4HX5EZrxarTkVJUQnJ4h4KDa/0j1mzVQUt3b8tcDG+/8AsBEz1QTjh0ywO4BR1gtE2 ip6RrDiGFJl0qaW7VLJ2UVhcd4F9y6s1bUDlebhJmpyD46jVlvtHfjsbn/M0nF/ktM2G Qhng== X-Gm-Message-State: AD7BkJLzjREmuuDbdxlsmpJ+FgQgG9JIot9wQrtHrmgNoge6vVv+oGdEKmB+GcU9COm5x6PDdZaNiTs3U6t6CdSs MIME-Version: 1.0 X-Received: by 10.157.37.194 with SMTP id q60mr6889810ota.47.1459849759699; Tue, 05 Apr 2016 02:49:19 -0700 (PDT) Received: by 10.76.12.101 with HTTP; Tue, 5 Apr 2016 02:49:19 -0700 (PDT) In-Reply-To: References: <1458650901-7229-1-git-send-email-haojian.zhuang@linaro.org> <1458650901-7229-9-git-send-email-haojian.zhuang@linaro.org> Date: Tue, 5 Apr 2016 10:49:19 +0100 Message-ID: From: Ryan Harkin To: Haojian Zhuang Subject: Re: [edk2] [PATCH v2 8/9] MmcDxe: set iospeed and bus width in SD stack X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: "edk2-devel@lists.01.org" , Leif Lindholm , Ard Biesheuvel Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" On 5 April 2016 at 09:37, Ryan Harkin wrote: > On 5 April 2016 at 03:57, Haojian Zhuang wrote: >> On 5 April 2016 at 01:17, Ryan Harkin wrote: >>> Hi Haojian, >>> >>> I've had time to investigate where TC2 is hanging with your patches >>> applied and narrowed it down to the single line of code marked below. >>> >>> I'm going to read the code now and see if I can work out what it's >>> trying to do, but I thought I'd tell you sooner because you might have >>> a better idea. >>> >>> On 22 March 2016 at 12:48, Haojian Zhuang wrote: >>>> 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 | 3 + >>>> EmbeddedPkg/Universal/MmcDxe/Mmc.h | 17 +++ >>>> EmbeddedPkg/Universal/MmcDxe/MmcIdentification.c | 138 ++++++++++++++++++++--- >>>> 3 files changed, 142 insertions(+), 16 deletions(-) >>>> >>>> diff --git a/EmbeddedPkg/Include/Protocol/MmcHost.h b/EmbeddedPkg/Include/Protocol/MmcHost.h >>>> index 5e3a2b7..e9a74f0 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 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..125d3f9 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,95 @@ 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); >>> >>> ^^ TC2 hangs at this line >>> >> >> Ryan, >> >> Could you help to check where it hangs in >> ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.c? >> > > I guess you mean, "where in function MciReadBlockData does it hang?". > > I'll have a look this asap. > I made this mod to the code to add DEBUG: And after the InitializeSdMmcDevice debug, I see this output continuously: RMH: MciReadBlockData(234): 0x40 If I add an MmioWrite32 to clear the flags at the start of the read block function, I see the same behaviour, except it reads 0x00 continuously instead of 0x40. > >> I checked that PL180 supports SD v0.96. But I only found SD v1.10. In >> SD v1.10, SCR (ACMD51) >> is defined. So I also assume that SCR should be supported in PL180. >> >> Best Regards >> Haojian _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.c b/ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.c index 5526aac..7ddcf46 100644 --- a/ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.c +++ b/ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.c @@ -231,6 +231,7 @@ MciReadBlockData ( do { // Read the Status flags Status = MmioRead32 (MCI_STATUS_REG); +DEBUG ((EFI_D_ERROR, "RMH: MciReadBlockData(%d): 0x%x\n", __LINE__, Status));^M // Do eight reads if possible else a single read if (Status & MCI_STATUS_CMD_RXFIFOHALFFULL) {