From nobody Fri Mar 29 00:01:28 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+70017+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+70017+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1610086469; cv=none; d=zohomail.com; s=zohoarc; b=U8ZORoIRriFgDyQ5/AY7wPV2J/O763ctkYWCft9k6QtiAl5Ylw/sovtGtAATt+ErDcp2vKXIieGFPlv8DgzqDFSFHtOcpugRATqAXZtqSATSMy0Vzaqg6MDdtfliXAeotERMfaQ9yHhWj3Lxl93II6WDl+akFiM968dhZQTUMZQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1610086469; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=OsJdvDVm0E6ygJWRo7ajqdt76rGt+zfcsBss34Fybaw=; b=iRXPb4vYnkU5K3YUvLqvBOggFipmpYimCumaX28e2uvsWCD9yJlSrJLnu3uqkUx6ORUKoM2hbPJLRcqEU3GfLIGxdWkkoLaGQ2BZDC8U+jgrfqQJYtpazPfDII15TVvzapT5hAENFBSShzffGg8Xa5Q5x+DbaKyVu2rUBT7gtRQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+70017+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 161008646962475.62985606648704; Thu, 7 Jan 2021 22:14:29 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id BPiwYY1788612xOaenyJvOD2; Thu, 07 Jan 2021 22:14:29 -0800 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web11.367.1610086462564489498 for ; Thu, 07 Jan 2021 22:14:22 -0800 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 2731E11FB; Thu, 7 Jan 2021 22:14:22 -0800 (PST) X-Received: from mammon-tx2.austin.arm.com (mammon-tx2.austin.arm.com [10.118.28.62]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 1E9D73F66E; Thu, 7 Jan 2021 22:14:22 -0800 (PST) From: "Jeremy Linton" To: devel@edk2.groups.io Cc: ard.biesheuvel@arm.com, leif@nuviainc.com, pete@akeo.ie, samer.el-haj-mahmoud@arm.com, awarkentin@vmware.com, Jeremy Linton , Philippe Mathieu-Daude Subject: [edk2-devel] [PATCH v5 4/7] Platform/RaspberryPi/Arasan: Add write delay and voltage/clock config Date: Fri, 8 Jan 2021 00:14:08 -0600 Message-Id: <20210108061411.1721734-5-jeremy.linton@arm.com> In-Reply-To: <20210108061411.1721734-1-jeremy.linton@arm.com> References: <20210108061411.1721734-1-jeremy.linton@arm.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,jeremy.linton@arm.com X-Gm-Message-State: c7phVf9x5FOTaXl3pkLH0Sizx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1610086469; bh=QeCWGgQ+NLbUnWTGXPnhi4QMCvalE86VqUyuxcUnG5g=; h=Cc:Date:From:Reply-To:Subject:To; b=iLKH8yg+KgETV88Ulm9HhvQfVSrODCtpxlaAV55Jc0UZE/Fw+Wo2fD8kQOBtB7YAdgj HSmR79jvluraA5rGjroZyGbY3seAVwcjE7XmAjD1SAH1WvMLnF5D9GB7xunrPC3WV8aRb yKA8TghBOaC3yE9vTam2DtA+7gA4ihtLYog= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" The uboot and Linux drivers have notes that there is a clock domain crossing problem that happens with back to back writes to the SD controllers on the rpi. Its not clear if this is still applicable to the rpi4/eMMC2 but it seems wise to add it. Further, we need to assure that the card voltage is set to 3.3V, and we should try and follow some of the SDHCI docs when it comes to changing the clock. Signed-off-by: Jeremy Linton Reviewed-by: Andrei Warkentin Reviewed-by: Philippe Mathieu-Daude --- .../Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c | 112 +++++++++++++++++= ---- .../Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.h | 1 + 2 files changed, 93 insertions(+), 20 deletions(-) diff --git a/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe= .c b/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c index 379b271187..91f7c41c6c 100644 --- a/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c +++ b/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c @@ -18,6 +18,56 @@ UINT32 LastExecutedCommand =3D (UINT32) -1; STATIC RASPBERRY_PI_FIRMWARE_PROTOCOL *mFwProtocol; STATIC UINTN mMmcHsBase; =20 +STATIC +UINT32 +EFIAPI +SdMmioWrite32 ( + IN UINTN Address, + IN UINT32 Value + ) +{ + UINT32 ret; + ret =3D (UINT32)MmioWrite32 (Address, Value); + // There is a bug about clock domain crossing on writes, delay to avoid = it + gBS->Stall (STALL_AFTER_REG_WRITE_US); + return ret; +} + +STATIC +UINT32 +EFIAPI +SdMmioOr32 ( + IN UINTN Address, + IN UINT32 OrData + ) +{ + return SdMmioWrite32 (Address, MmioRead32 (Address) | OrData); +} + +STATIC +UINT32 +EFIAPI +SdMmioAnd32 ( + IN UINTN Address, + IN UINT32 AndData + ) +{ + return SdMmioWrite32 (Address, MmioRead32 (Address) & AndData); +} + +STATIC +UINT32 +EFIAPI +SdMmioAndThenOr32 ( + IN UINTN Address, + IN UINT32 AndData, + IN UINT32 OrData + ) +{ + return SdMmioWrite32 (Address, (MmioRead32 (Address) & AndData) | OrData= ); +} + + /** These SD commands are optional, according to the SD Spec **/ @@ -175,7 +225,9 @@ SoftReset ( IN UINT32 Mask ) { - MmioOr32 (MMCHS_SYSCTL, Mask); + DEBUG ((DEBUG_MMCHOST_SD, "SoftReset with mask 0x%x\n", Mask)); + + SdMmioOr32 (MMCHS_SYSCTL, Mask); if (PollRegisterWithMask (MMCHS_SYSCTL, Mask, 0) =3D=3D EFI_TIMEOUT) { DEBUG ((DEBUG_ERROR, "Failed to SoftReset with mask 0x%x\n", Mask)); return EFI_TIMEOUT; @@ -326,29 +378,29 @@ MMCSendCommand ( } =20 if (IsAppCmd && MmcCmd =3D=3D ACMD22) { - MmioWrite32 (MMCHS_BLK, 4); + SdMmioWrite32 (MMCHS_BLK, 4); } else if (IsAppCmd && MmcCmd =3D=3D ACMD51) { - MmioWrite32 (MMCHS_BLK, 8); + SdMmioWrite32 (MMCHS_BLK, 8); } else if (!IsAppCmd && MmcCmd =3D=3D CMD6) { - MmioWrite32 (MMCHS_BLK, 64); + SdMmioWrite32 (MMCHS_BLK, 64); } else if (IsADTCCmd) { - MmioWrite32 (MMCHS_BLK, BLEN_512BYTES); + SdMmioWrite32 (MMCHS_BLK, BLEN_512BYTES); } =20 // Set Data timeout counter value to max value. - MmioAndThenOr32 (MMCHS_SYSCTL, (UINT32) ~DTO_MASK, DTO_VAL); + SdMmioAndThenOr32 (MMCHS_SYSCTL, (UINT32) ~DTO_MASK, DTO_VAL); =20 // // Clear Interrupt Status Register, but not the Card Inserted bit // to avoid messing with card detection logic. // - MmioWrite32 (MMCHS_INT_STAT, ALL_EN & ~(CARD_INS)); + SdMmioWrite32 (MMCHS_INT_STAT, ALL_EN & ~(CARD_INS)); =20 // Set command argument register - MmioWrite32 (MMCHS_ARG, Argument); + SdMmioWrite32 (MMCHS_ARG, Argument); =20 // Send the command - MmioWrite32 (MMCHS_CMD, MmcCmd); + SdMmioWrite32 (MMCHS_CMD, MmcCmd); =20 // Check for the command status. while (RetryCount < MAX_RETRY_COUNT) { @@ -373,7 +425,7 @@ MMCSendCommand ( =20 // Check if command is completed. if ((MmcStatus & CC) =3D=3D CC) { - MmioWrite32 (MMCHS_INT_STAT, CC); + SdMmioWrite32 (MMCHS_INT_STAT, CC); break; } =20 @@ -428,6 +480,21 @@ MMCNotifyState ( return Status; } =20 + DEBUG ((DEBUG_MMCHOST_SD, "ArasanMMCHost: CAP %X CAPH %X\n", MmioRea= d32(MMCHS_CAPA),MmioRead32(MMCHS_CUR_CAPA))); + + // Lets switch to card detect test mode. + SdMmioOr32 (MMCHS_HCTL, BIT7|BIT6); + + // set card voltage + SdMmioAnd32 (MMCHS_HCTL, ~SDBP_ON); + SdMmioAndThenOr32 (MMCHS_HCTL, (UINT32) ~SDBP_MASK, SDVS_3_3_V); + SdMmioOr32 (MMCHS_HCTL, SDBP_ON); + + DEBUG ((DEBUG_MMCHOST_SD, "ArasanMMCHost: AC12 %X HCTL %X\n", MmioRe= ad32(MMCHS_AC12),MmioRead32(MMCHS_HCTL))); + + // First turn off the clock + SdMmioAnd32 (MMCHS_SYSCTL, ~CEN); + // Attempt to set the clock to 400Khz which is the expected initiali= zation speed Status =3D CalculateClockFrequencyDivisor (400000, &Divisor, NULL); if (EFI_ERROR (Status)) { @@ -436,10 +503,15 @@ MMCNotifyState ( } =20 // Set Data Timeout Counter value, set clock frequency, enable inter= nal clock - MmioOr32 (MMCHS_SYSCTL, DTO_VAL | Divisor | CEN | ICS | ICE); + SdMmioOr32 (MMCHS_SYSCTL, DTO_VAL | Divisor | CEN | ICS | ICE); + SdMmioOr32 (MMCHS_HCTL, SDBP_ON); + // wait for ICS + while ((MmioRead32 (MMCHS_SYSCTL) & ICS_MASK) !=3D ICS); + + DEBUG ((DEBUG_MMCHOST_SD, "ArasanMMCHost: AC12 %X HCTL %X\n", MmioRe= ad32(MMCHS_AC12),MmioRead32(MMCHS_HCTL))); =20 // Enable interrupts - MmioWrite32 (MMCHS_IE, ALL_EN); + SdMmioWrite32 (MMCHS_IE, ALL_EN); } break; case MmcIdleState: @@ -452,7 +524,7 @@ MMCNotifyState ( ClockFrequency =3D 25000000; =20 // First turn off the clock - MmioAnd32 (MMCHS_SYSCTL, ~CEN); + SdMmioAnd32 (MMCHS_SYSCTL, ~CEN); =20 Status =3D CalculateClockFrequencyDivisor (ClockFrequency, &Divisor, N= ULL); if (EFI_ERROR (Status)) { @@ -462,13 +534,13 @@ MMCNotifyState ( } =20 // Setup new divisor - MmioAndThenOr32 (MMCHS_SYSCTL, (UINT32) ~CLKD_MASK, Divisor); + SdMmioAndThenOr32 (MMCHS_SYSCTL, (UINT32) ~CLKD_MASK, Divisor); =20 // Wait for the clock to stabilise while ((MmioRead32 (MMCHS_SYSCTL) & ICS_MASK) !=3D ICS); =20 // Set Data Timeout Counter value, set clock frequency, enable interna= l clock - MmioOr32 (MMCHS_SYSCTL, CEN); + SdMmioOr32 (MMCHS_SYSCTL, CEN); break; case MmcTransferState: break; @@ -635,7 +707,7 @@ MMCReadBlockData ( while (RetryCount < MAX_RETRY_COUNT) { MmcStatus =3D MmioRead32 (MMCHS_INT_STAT); if ((MmcStatus & BRR) !=3D 0) { - MmioWrite32 (MMCHS_INT_STAT, BRR); + SdMmioWrite32 (MMCHS_INT_STAT, BRR); /* * Data is ready. */ @@ -662,7 +734,7 @@ MMCReadBlockData ( gBS->Stall (STALL_AFTER_READ_US); } =20 - MmioWrite32 (MMCHS_INT_STAT, BRR); + SdMmioWrite32 (MMCHS_INT_STAT, BRR); return EFI_SUCCESS; } =20 @@ -699,13 +771,13 @@ MMCWriteBlockData ( while (RetryCount < MAX_RETRY_COUNT) { MmcStatus =3D MmioRead32 (MMCHS_INT_STAT); if ((MmcStatus & BWR) !=3D 0) { - MmioWrite32 (MMCHS_INT_STAT, BWR); + SdMmioWrite32 (MMCHS_INT_STAT, BWR); /* * Can write data. */ mFwProtocol->SetLed (TRUE); for (Count =3D 0; Count < BlockLen; Count +=3D 4, Buffer++) { - MmioWrite32 (MMCHS_DATA, *Buffer); + SdMmioWrite32 (MMCHS_DATA, *Buffer); } =20 mFwProtocol->SetLed (FALSE); @@ -726,7 +798,7 @@ MMCWriteBlockData ( gBS->Stall (STALL_AFTER_WRITE_US); } =20 - MmioWrite32 (MMCHS_INT_STAT, BWR); + SdMmioWrite32 (MMCHS_INT_STAT, BWR); return EFI_SUCCESS; } =20 diff --git a/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe= .h b/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.h index 6cd600f738..e94606cc5b 100644 --- a/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.h +++ b/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.h @@ -37,6 +37,7 @@ #define STALL_AFTER_REC_RESP_US (50) #define STALL_AFTER_WRITE_US (200) #define STALL_AFTER_READ_US (20) +#define STALL_AFTER_REG_WRITE_US (10) #define STALL_AFTER_RETRY_US (20) =20 #define MAX_DIVISOR_VALUE 1023 --=20 2.13.7 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#70017): https://edk2.groups.io/g/devel/message/70017 Mute This Topic: https://groups.io/mt/79518680/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-