From: "Jeremy Linton" <jeremy.linton@arm.com>
To: Andrei Warkentin <awarkentin@vmware.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "ard.biesheuvel@arm.com" <ard.biesheuvel@arm.com>,
"leif@nuviainc.com" <leif@nuviainc.com>,
"pete@akeo.ie" <pete@akeo.ie>,
"andrey.warkentin@gmail.com" <andrey.warkentin@gmail.com>,
"samer.el-haj-mahmoud@arm.com" <samer.el-haj-mahmoud@arm.com>
Subject: Re: [edk2-devel] [PATCH 4/7] Platform/RaspberryPi/Arasan: Add write delay and voltage/clock config
Date: Tue, 15 Dec 2020 12:46:10 -0600 [thread overview]
Message-ID: <b3048481-94c0-ffa4-2bcc-addb7f6e9744@arm.com> (raw)
In-Reply-To: <SJ0PR05MB7580764A0287E5449F19B83DB9C60@SJ0PR05MB7580.namprd05.prod.outlook.com>
Hi,
On 12/15/20 12:26 PM, Andrei Warkentin wrote:
> I believe that applies only to the Arasan integration, not MMC2.
>
> I'm trying to recollect why I thought this didn't matter (or how it was getting mitigated), but i'm drawing a blank. I'm okay doing it.
Well, I think it "works" without it, although it appears both uboot and
linux have similar workarounds for both controllers. So "works" might be
a case of works for me but not for you. That is a large part of the
problem around using PNP0D40 as the _CID too. It works for both
controllers, despite the lack of careful alignment controls, or this
workaround in linux with the straight sdhci_acpi driver. If I can figure
out how to suppress/quirk the cmd12 warnings the emmc2 it would almost
be worth doing.
A good part of this set is just based on me banging my head and
inserting trace/prints in the linux and uboot gpio/mailbox and mmc
paths, and then supporting the most obvious differences. So while I
backed a few things out, some of these things remain (like this) because
there is a bit of documentation in those drivers claiming there is a
clock domain crossing bug. What the actual details, or how to reproduce
aren't included.
>
> Reviewed-by: Andrei Warkentin <awarkentin@vmware.com>
> ________________________________
> From: devel@edk2.groups.io <devel@edk2.groups.io> on behalf of Jeremy Linton via groups.io <jeremy.linton=arm.com@groups.io>
> Sent: Monday, December 14, 2020 5:23 PM
> To: devel@edk2.groups.io <devel@edk2.groups.io>
> Cc: ard.biesheuvel@arm.com <ard.biesheuvel@arm.com>; leif@nuviainc.com <leif@nuviainc.com>; pete@akeo.ie <pete@akeo.ie>; andrey.warkentin@gmail.com <andrey.warkentin@gmail.com>; samer.el-haj-mahmoud@arm.com <samer.el-haj-mahmoud@arm.com>; Jeremy Linton <jeremy.linton@arm.com>
> Subject: [edk2-devel] [PATCH 4/7] Platform/RaspberryPi/Arasan: Add write delay and voltage/clock config
>
> 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.
>
> Futher, 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 <jeremy.linton@arm.com>
> ---
> .../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 0cb7e85b38..a7b538a91a 100644
> --- a/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c
> +++ b/Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c
> @@ -18,6 +18,56 @@ UINT32 LastExecutedCommand = (UINT32) -1;
> STATIC RASPBERRY_PI_FIRMWARE_PROTOCOL *mFwProtocol;
>
> STATIC UINTN MMCHS_BASE;
>
>
>
> +STATIC
>
> +UINT32
>
> +EFIAPI
>
> +SdMmioWrite32 (
>
> + IN UINTN Address,
>
> + IN UINT32 Value
>
> + )
>
> +{
>
> + UINT32 ret;
>
> + ret = (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) == EFI_TIMEOUT) {
>
> DEBUG ((DEBUG_ERROR, "Failed to SoftReset with mask 0x%x\n", Mask));
>
> return EFI_TIMEOUT;
>
> @@ -326,29 +378,29 @@ MMCSendCommand (
> }
>
>
>
> if (IsAppCmd && MmcCmd == ACMD22) {
>
> - MmioWrite32 (MMCHS_BLK, 4);
>
> + SdMmioWrite32 (MMCHS_BLK, 4);
>
> } else if (IsAppCmd && MmcCmd == ACMD51) {
>
> - MmioWrite32 (MMCHS_BLK, 8);
>
> + SdMmioWrite32 (MMCHS_BLK, 8);
>
> } else if (!IsAppCmd && MmcCmd == CMD6) {
>
> - MmioWrite32 (MMCHS_BLK, 64);
>
> + SdMmioWrite32 (MMCHS_BLK, 64);
>
> } else if (IsADTCCmd) {
>
> - MmioWrite32 (MMCHS_BLK, BLEN_512BYTES);
>
> + SdMmioWrite32 (MMCHS_BLK, BLEN_512BYTES);
>
> }
>
>
>
> // Set Data timeout counter value to max value.
>
> - MmioAndThenOr32 (MMCHS_SYSCTL, (UINT32) ~DTO_MASK, DTO_VAL);
>
> + SdMmioAndThenOr32 (MMCHS_SYSCTL, (UINT32) ~DTO_MASK, DTO_VAL);
>
>
>
> //
>
> // 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));
>
>
>
> // Set command argument register
>
> - MmioWrite32 (MMCHS_ARG, Argument);
>
> + SdMmioWrite32 (MMCHS_ARG, Argument);
>
>
>
> // Send the command
>
> - MmioWrite32 (MMCHS_CMD, MmcCmd);
>
> + SdMmioWrite32 (MMCHS_CMD, MmcCmd);
>
>
>
> // Check for the command status.
>
> while (RetryCount < MAX_RETRY_COUNT) {
>
> @@ -373,7 +425,7 @@ MMCSendCommand (
>
>
> // Check if command is completed.
>
> if ((MmcStatus & CC) == CC) {
>
> - MmioWrite32 (MMCHS_INT_STAT, CC);
>
> + SdMmioWrite32 (MMCHS_INT_STAT, CC);
>
> break;
>
> }
>
>
>
> @@ -428,6 +480,21 @@ MMCNotifyState (
> return Status;
>
> }
>
>
>
> + DEBUG ((DEBUG_MMCHOST_SD, "ArasanMMCHost: CAP %X CAPH %X\n", MmioRead32(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", MmioRead32(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 initialization speed
>
> Status = CalculateClockFrequencyDivisor (400000, &Divisor, NULL);
>
> if (EFI_ERROR (Status)) {
>
> @@ -436,10 +503,15 @@ MMCNotifyState (
> }
>
>
>
> // Set Data Timeout Counter value, set clock frequency, enable internal 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) != ICS);
>
> +
>
> + DEBUG ((DEBUG_MMCHOST_SD, "ArasanMMCHost: AC12 %X HCTL %X\n", MmioRead32(MMCHS_AC12),MmioRead32(MMCHS_HCTL)));
>
>
>
> // Enable interrupts
>
> - MmioWrite32 (MMCHS_IE, ALL_EN);
>
> + SdMmioWrite32 (MMCHS_IE, ALL_EN);
>
> }
>
> break;
>
> case MmcIdleState:
>
> @@ -452,7 +524,7 @@ MMCNotifyState (
> ClockFrequency = 25000000;
>
>
>
> // First turn off the clock
>
> - MmioAnd32 (MMCHS_SYSCTL, ~CEN);
>
> + SdMmioAnd32 (MMCHS_SYSCTL, ~CEN);
>
>
>
> Status = CalculateClockFrequencyDivisor (ClockFrequency, &Divisor, NULL);
>
> if (EFI_ERROR (Status)) {
>
> @@ -462,13 +534,13 @@ MMCNotifyState (
> }
>
>
>
> // Setup new divisor
>
> - MmioAndThenOr32 (MMCHS_SYSCTL, (UINT32) ~CLKD_MASK, Divisor);
>
> + SdMmioAndThenOr32 (MMCHS_SYSCTL, (UINT32) ~CLKD_MASK, Divisor);
>
>
>
> // Wait for the clock to stabilise
>
> while ((MmioRead32 (MMCHS_SYSCTL) & ICS_MASK) != ICS);
>
>
>
> // Set Data Timeout Counter value, set clock frequency, enable internal clock
>
> - MmioOr32 (MMCHS_SYSCTL, CEN);
>
> + SdMmioOr32 (MMCHS_SYSCTL, CEN);
>
> break;
>
> case MmcTransferState:
>
> break;
>
> @@ -635,7 +707,7 @@ MMCReadBlockData (
> while (RetryCount < MAX_RETRY_COUNT) {
>
> MmcStatus = MmioRead32 (MMCHS_INT_STAT);
>
> if ((MmcStatus & BRR) != 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);
>
> }
>
>
>
> - MmioWrite32 (MMCHS_INT_STAT, BRR);
>
> + SdMmioWrite32 (MMCHS_INT_STAT, BRR);
>
> return EFI_SUCCESS;
>
> }
>
>
>
> @@ -699,13 +771,13 @@ MMCWriteBlockData (
> while (RetryCount < MAX_RETRY_COUNT) {
>
> MmcStatus = MmioRead32 (MMCHS_INT_STAT);
>
> if ((MmcStatus & BWR) != 0) {
>
> - MmioWrite32 (MMCHS_INT_STAT, BWR);
>
> + SdMmioWrite32 (MMCHS_INT_STAT, BWR);
>
> /*
>
> * Can write data.
>
> */
>
> mFwProtocol->SetLed (TRUE);
>
> for (Count = 0; Count < BlockLen; Count += 4, Buffer++) {
>
> - MmioWrite32 (MMCHS_DATA, *Buffer);
>
> + SdMmioWrite32 (MMCHS_DATA, *Buffer);
>
> }
>
>
>
> mFwProtocol->SetLed (FALSE);
>
> @@ -726,7 +798,7 @@ MMCWriteBlockData (
> gBS->Stall (STALL_AFTER_WRITE_US);
>
> }
>
>
>
> - MmioWrite32 (MMCHS_INT_STAT, BWR);
>
> + SdMmioWrite32 (MMCHS_INT_STAT, BWR);
>
> return EFI_SUCCESS;
>
> }
>
>
>
> 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)
>
>
>
> #define MAX_DIVISOR_VALUE 1023
>
> --
> 2.13.7
>
>
>
> -=-=-=-=-=-=
> Groups.io Links: You receive all messages sent to this group.
> View/Reply Online (#68816): https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F68816&data=04%7C01%7Cawarkentin%40vmware.com%7C121bf8f78f3b437be80708d8a0875a08%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C637435850504293478%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=6UBUDOHEs8MHLhK7%2B9DkL4NAdxzwttiJRvE88aqD%2BHw%3D&reserved=0
> Mute This Topic: https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgroups.io%2Fmt%2F78964893%2F4387333&data=04%7C01%7Cawarkentin%40vmware.com%7C121bf8f78f3b437be80708d8a0875a08%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C637435850504293478%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=OVqu67c28Qqnk25HasY%2BxkEC0KgOBQfxZWJxGZ0nJlk%3D&reserved=0
> Group Owner: devel+owner@edk2.groups.io
> Unsubscribe: https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Funsub&data=04%7C01%7Cawarkentin%40vmware.com%7C121bf8f78f3b437be80708d8a0875a08%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C637435850504293478%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=aXFzE1B1xX6JQeXymAEmWa2Z99welypR6HTHXrv1%2B7E%3D&reserved=0 [awarkentin@vmware.com]
> -=-=-=-=-=-=
>
>
>
next prev parent reply other threads:[~2020-12-15 18:46 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-14 23:23 [PATCH 0/7] Enable emmc2 controller rpi4 Jeremy Linton
2020-12-14 23:23 ` [PATCH 1/7] Platform/RaspberryPi: Update VPU mailbox constants Jeremy Linton
2020-12-15 18:15 ` [edk2-devel] " Andrei Warkentin
2020-12-14 23:23 ` [PATCH 2/7] Platform/RaspberryPi: Add further mailbox helpers Jeremy Linton
2020-12-15 18:18 ` [edk2-devel] " Andrei Warkentin
2020-12-14 23:23 ` [PATCH 3/7] Platform/RaspberryPi: Split MMC register defintions Jeremy Linton
2020-12-15 18:17 ` [edk2-devel] " Andrei Warkentin
2020-12-14 23:23 ` [PATCH 4/7] Platform/RaspberryPi/Arasan: Add write delay and voltage/clock config Jeremy Linton
2020-12-15 18:26 ` [edk2-devel] " Andrei Warkentin
2020-12-15 18:46 ` Jeremy Linton [this message]
2020-12-15 18:52 ` Andrei Warkentin
2020-12-14 23:23 ` [PATCH 5/7] Platform/RaspberryPi/Arasan: Select the correct base frequency Jeremy Linton
2020-12-15 18:18 ` [edk2-devel] " Andrei Warkentin
2020-12-14 23:23 ` [PATCH 6/7] Platform/RaspberryPi: Power up sd, and tweak GPIOs Jeremy Linton
2020-12-15 18:21 ` [edk2-devel] " Andrei Warkentin
2020-12-15 18:55 ` Jeremy Linton
2020-12-15 19:36 ` Andrei Warkentin
2020-12-15 20:15 ` Jeremy Linton
2020-12-14 23:23 ` [PATCH 7/7] Platform/RaspberryPi: Correct device path removal Jeremy Linton
2020-12-15 18:19 ` [edk2-devel] " Andrei Warkentin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b3048481-94c0-ffa4-2bcc-addb7f6e9744@arm.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox