* [PATCH] patch1_add_support_bh720_emmc_chip
@ 2019-01-28 7:35 Mike Li (WH)
2019-01-29 2:31 ` Wu, Hao A
0 siblings, 1 reply; 2+ messages in thread
From: Mike Li (WH) @ 2019-01-28 7:35 UTC (permalink / raw)
To: edk2-devel@lists.01.org
---
.../Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c | 253 ++++++++++++------
.../Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h | 47 +---
2 files changed, 178 insertions(+), 122 deletions(-)
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
index 4ef849fd09..ac79a2f791 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
@@ -527,17 +527,35 @@ EmmcTuningClkForHs200 (
if (EFI_ERROR (Status)) {
return Status;
}
+
+ if(BhtHostPciSupport(PciIo)){
+ //set data transfer with 4bit
+ Status = SdMmcHcSetBusWidth (PciIo, Slot, 4);
+ //enable hardware tuning
+ HostCtrl2 = (~0x10);
+ Status = SdMmcHcAndMmio (PciIo, Slot, 0x110,sizeof (HostCtrl2), &HostCtrl2);
+
+ Status = EmmcSendTuningBlk (PassThru, Slot, 4);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "EmmcTuningClkForHs200: Send tuning block fails with %r\n", Status));
+ return Status;
+ }
+
+ }
//
// Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
//
Retry = 0;
do {
- Status = EmmcSendTuningBlk (PassThru, Slot, BusWidth);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "EmmcTuningClkForHs200: Send tuning block fails with %r\n", Status));
- return Status;
- }
-
+ if(!BhtHostPciSupport(PciIo)){
+ Status = EmmcSendTuningBlk (PassThru, Slot, BusWidth);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "EmmcTuningClkForHs200: Send tuning block fails with %r\n", Status));
+ return Status;
+ }
+ } else {
+ gBS->Stall(5000);
+ }
Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);
if (EFI_ERROR (Status)) {
return Status;
@@ -548,6 +566,10 @@ EmmcTuningClkForHs200 (
}
if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) {
+ if(BhtHostPciSupport(PciIo)){
+ //set data transfer with default
+ Status = SdMmcHcSetBusWidth (PciIo, Slot, BusWidth);
+ }
return EFI_SUCCESS;
}
} while (++Retry < 40);
@@ -652,7 +674,6 @@ EmmcSwitchBusWidth (
@param[in] Slot The slot number of the SD card to send the command to.
@param[in] Rca The relative device address to be assigned.
@param[in] HsTiming The value to be written to HS_TIMING field of EXT_CSD register.
- @param[in] Timing The bus mode timing indicator.
@param[in] ClockFreq The max clock frequency to be set, the unit is MHz.
@retval EFI_SUCCESS The operation is done correctly.
@@ -666,7 +687,6 @@ EmmcSwitchClockFreq (
IN UINT8 Slot,
IN UINT16 Rca,
IN UINT8 HsTiming,
- IN SD_MMC_BUS_MODE Timing,
IN UINT32 ClockFreq
)
{
@@ -708,28 +728,7 @@ EmmcSwitchClockFreq (
//
// Convert the clock freq unit from MHz to KHz.
//
- Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, Private->BaseClkFreq[Slot], Private->ControllerVersion[Slot]);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- if (mOverride != NULL && mOverride->NotifyPhase != NULL) {
- Status = mOverride->NotifyPhase (
- Private->ControllerHandle,
- Slot,
- EdkiiSdMmcSwitchClockFreqPost,
- &Timing
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "%a: SD/MMC switch clock freq post notifier callback failed - %r\n",
- __FUNCTION__,
- Status
- ));
- return Status;
- }
- }
+ Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, Private->Capability[Slot]);
return Status;
}
@@ -764,13 +763,10 @@ EmmcSwitchToHighSpeed (
IN UINT8 BusWidth
)
{
- EFI_STATUS Status;
- UINT8 HsTiming;
- UINT8 HostCtrl1;
- SD_MMC_BUS_MODE Timing;
- SD_MMC_HC_PRIVATE_DATA *Private;
-
- Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
+ EFI_STATUS Status;
+ UINT8 HsTiming;
+ UINT8 HostCtrl1;
+ UINT8 HostCtrl2;
Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusWidth);
if (EFI_ERROR (Status)) {
@@ -785,21 +781,31 @@ EmmcSwitchToHighSpeed (
return Status;
}
+ //
+ // Clean UHS Mode Select field of Host Control 2 reigster before update
+ //
+ HostCtrl2 = (UINT8)~0x7;
+ Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Set UHS Mode Select field of Host Control 2 reigster to SDR12/25/50
+ //
if (IsDdr) {
- Timing = SdMmcMmcHsDdr;
+ HostCtrl2 = BIT2;
} else if (ClockFreq == 52) {
- Timing = SdMmcMmcHsSdr;
+ HostCtrl2 = BIT0;
} else {
- Timing = SdMmcMmcLegacy;
+ HostCtrl2 = 0;
}
-
- Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);
+ Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
if (EFI_ERROR (Status)) {
return Status;
}
HsTiming = 1;
- Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, Timing, ClockFreq);
+ Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, ClockFreq);
return Status;
}
@@ -831,13 +837,10 @@ EmmcSwitchToHS200 (
IN UINT8 BusWidth
)
{
- EFI_STATUS Status;
- UINT8 HsTiming;
- UINT16 ClockCtrl;
- SD_MMC_BUS_MODE Timing;
- SD_MMC_HC_PRIVATE_DATA *Private;
-
- Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
+ EFI_STATUS Status;
+ UINT8 HsTiming;
+ UINT8 HostCtrl2;
+ UINT16 ClockCtrl;
if ((BusWidth != 4) && (BusWidth != 8)) {
return EFI_INVALID_PARAMETER;
@@ -857,29 +860,60 @@ EmmcSwitchToHS200 (
if (EFI_ERROR (Status)) {
return Status;
}
-
- Timing = SdMmcMmcHs200;
-
- Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);
+ //
+ // Clean UHS Mode Select field of Host Control 2 reigster before update
+ //
+ HostCtrl2 = (UINT8)~0x7;
+ Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Set UHS Mode Select field of Host Control 2 reigster to SDR104
+ //
+ HostCtrl2 = BIT0 | BIT1;
+ Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
if (EFI_ERROR (Status)) {
return Status;
}
-
//
// Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit
//
- Status = SdMmcHcWaitMmioSet (
- PciIo,
- Slot,
- SD_MMC_HC_CLOCK_CTRL,
- sizeof (ClockCtrl),
- BIT1,
- BIT1,
- SD_MMC_HC_GENERIC_TIMEOUT
+ if (BhtHostPciSupport(PciIo)) {
+ Status = SdMmcHcWaitMmioSet (
+ PciIo,
+ Slot,
+ 0x1cc,
+ sizeof (ClockCtrl),
+ BIT14,
+ BIT14,
+ SD_MMC_HC_GENERIC_TIMEOUT
);
+ }
+ else {
+ Status = SdMmcHcWaitMmioSet (
+ PciIo,
+ Slot,
+ SD_MMC_HC_CLOCK_CTRL,
+ sizeof (ClockCtrl),
+ BIT1,
+ BIT1,
+ SD_MMC_HC_GENERIC_TIMEOUT
+ );
+ }
if (EFI_ERROR (Status)) {
return Status;
}
+
+ if (BhtHostPciSupport(PciIo)){
+ //Wait 2nd Card Detect debounce Finished by wait twice of debounce max time
+ UINT32 value32;
+ while (1) {
+ Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof(value32), &value32);
+ if (((value32 >> 18) & 0x01) == ((value32 >> 16) & 0x01))
+ break;
+ }
+ }
//
// Set SD Clock Enable in the Clock Control register to 1
//
@@ -887,12 +921,33 @@ EmmcSwitchToHS200 (
Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_CLOCK_CTRL, sizeof (ClockCtrl), &ClockCtrl);
HsTiming = 2;
- Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, Timing, ClockFreq);
+ Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, ClockFreq);
if (EFI_ERROR (Status)) {
return Status;
}
- Status = EmmcTuningClkForHs200 (PciIo, PassThru, Slot, BusWidth);
+ if (BhtHostPciSupport(PciIo)){
+ Status = SdMmcHcWaitMmioSet (
+ PciIo,
+ Slot,
+ 0x1cc,
+ sizeof (ClockCtrl),
+ BIT11,
+ BIT11,
+ SD_MMC_CLOCK_STABLE_TIMEOUT
+ );
+ if (EFI_ERROR(Status)) {
+ DbgMsg(L"Wait Clock Stable timeout, ClockFreq=%d\n", ClockFreq);
+ return Status;
+ }
+ }
+
+ if (EFI_ERROR(Status)) {
+ DbgMsg(L"Emmc tuning failed\n");
+ return Status;
+ }
+
+
return Status;
}
@@ -922,12 +977,9 @@ EmmcSwitchToHS400 (
IN UINT32 ClockFreq
)
{
- EFI_STATUS Status;
- UINT8 HsTiming;
- SD_MMC_BUS_MODE Timing;
- SD_MMC_HC_PRIVATE_DATA *Private;
-
- Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
+ EFI_STATUS Status;
+ UINT8 HsTiming;
+ UINT8 HostCtrl2;
Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq, 8);
if (EFI_ERROR (Status)) {
@@ -937,7 +989,7 @@ EmmcSwitchToHS400 (
// Set to Hight Speed timing and set the clock frequency to a value less than 52MHz.
//
HsTiming = 1;
- Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, SdMmcMmcHsSdr, 52);
+ Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, 52);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -948,16 +1000,25 @@ EmmcSwitchToHS400 (
if (EFI_ERROR (Status)) {
return Status;
}
-
- Timing = SdMmcMmcHs400;
-
- Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);
+ //
+ // Clean UHS Mode Select field of Host Control 2 reigster before update
+ //
+ HostCtrl2 = (UINT8)~0x7;
+ Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Set UHS Mode Select field of Host Control 2 reigster to HS400
+ //
+ HostCtrl2 = BIT0 | BIT2;
+ Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
if (EFI_ERROR (Status)) {
return Status;
}
HsTiming = 3;
- Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, Timing, ClockFreq);
+ Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, ClockFreq);
return Status;
}
@@ -1008,7 +1069,7 @@ EmmcSetBusMode (
return Status;
}
- ASSERT (Private->BaseClkFreq[Slot] != 0);
+ ASSERT (Private->Capability[Slot].BaseClkFreq != 0);
//
// Check if the Host Controller support 8bits bus width.
//
@@ -1080,6 +1141,42 @@ EmmcSetBusMode (
// Execute HS200 timing switch procedure
//
Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq, BusWidth);
+ if (EFI_ERROR(Status)) {
+ if (BhtHostPciSupport(PciIo)) {
+ UINT32 val32;
+ DbgMsg(L"switch to HS200 200MHZ failed, freq decrease to 100MHz\n");
+ ClockFreq = 100;
+
+ SdMmcHcRwMmio (PciIo, Slot, 0x3C, TRUE, sizeof(val32), &val32);
+ val32 &= ~BIT22;
+ SdMmcHcRwMmio (PciIo, Slot, 0x3C, FALSE, sizeof(val32), &val32);
+ val32 = (BIT26 | BIT25);
+ SdMmcHcOrMmio (PciIo, Slot, 0x2C, sizeof(val32), &val32);
+
+ Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq, BusWidth);
+ if (EFI_ERROR(Status)) {
+ if (((ExtCsd.DeviceType & BIT1) != 0) && (Private->Capability[Slot].HighSpeed != 0)) {
+ DbgMsg(L"switch to HS200 100MHZ failed, mode decrease to HS 50MHz\n");
+
+ HsTiming = 1;
+ IsDdr = FALSE;
+ ClockFreq = 52;
+ Status = EmmcSwitchToHighSpeed (PciIo, PassThru, Slot, Rca, ClockFreq, IsDdr, BusWidth);
+ }
+ else if (((ExtCsd.DeviceType & BIT0) != 0) && (Private->Capability[Slot].HighSpeed != 0)) {
+ DbgMsg(L"switch to HS200 100MHZ failed, mode decrease to HS 25MHz\n");
+
+ HsTiming = 1;
+ IsDdr = FALSE;
+ ClockFreq = 26;
+ Status = EmmcSwitchToHighSpeed (PciIo, PassThru, Slot, Rca, ClockFreq, IsDdr, BusWidth);
+ }
+ else {
+ DbgMsg(L"switch to HS200 100MHZ failed, but emmc chip didn't support hs mode\n");
+ }
+ }
+ }
+ }
} else {
//
// Execute High Speed timing switch procedure
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
index 1bb701a503..0d14b53105 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
@@ -36,7 +36,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/DriverBinding.h>
#include <Protocol/ComponentName.h>
#include <Protocol/ComponentName2.h>
-#include <Protocol/SdMmcOverride.h>
#include <Protocol/SdMmcPassThru.h>
#include "SdMmcPciHci.h"
@@ -45,8 +44,6 @@ extern EFI_COMPONENT_NAME_PROTOCOL gSdMmcPciHcComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gSdMmcPciHcComponentName2;
extern EFI_DRIVER_BINDING_PROTOCOL gSdMmcPciHcDriverBinding;
-extern EDKII_SD_MMC_OVERRIDE *mOverride;
-
#define SD_MMC_HC_PRIVATE_SIGNATURE SIGNATURE_32 ('s', 'd', 't', 'f')
#define SD_MMC_HC_PRIVATE_FROM_THIS(a) \
@@ -56,6 +53,7 @@ extern EDKII_SD_MMC_OVERRIDE *mOverride;
// Generic time out value, 1 microsecond as unit.
//
#define SD_MMC_HC_GENERIC_TIMEOUT 1 * 1000 * 1000
+#define SD_MMC_CLOCK_STABLE_TIMEOUT 3 * 1000
//
// SD/MMC async transfer timer interval, set by experience.
@@ -117,13 +115,8 @@ typedef struct {
SD_MMC_HC_SLOT Slot[SD_MMC_HC_MAX_SLOT];
SD_MMC_HC_SLOT_CAP Capability[SD_MMC_HC_MAX_SLOT];
UINT64 MaxCurrent[SD_MMC_HC_MAX_SLOT];
- UINT16 ControllerVersion[SD_MMC_HC_MAX_SLOT];
- //
- // Some controllers may require to override base clock frequency
- // value stored in Capabilities Register 1.
- //
- UINT32 BaseClkFreq[SD_MMC_HC_MAX_SLOT];
+ UINT32 ControllerVersion;
} SD_MMC_HC_PRIVATE_DATA;
#define SD_MMC_HC_TRB_SIG SIGNATURE_32 ('T', 'R', 'B', 'T')
@@ -150,8 +143,7 @@ typedef struct {
BOOLEAN Started;
UINT64 Timeout;
- SD_MMC_HC_ADMA_32_DESC_LINE *Adma32Desc;
- SD_MMC_HC_ADMA_64_DESC_LINE *Adma64Desc;
+ SD_MMC_HC_ADMA_DESC_LINE *AdmaDesc;
EFI_PHYSICAL_ADDRESS AdmaDescPhy;
VOID *AdmaMap;
UINT32 AdmaPages;
@@ -792,37 +784,4 @@ SdCardIdentification (
IN UINT8 Slot
);
-/**
- Software reset the specified SD/MMC host controller.
-
- @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
- @param[in] Slot The slot number of the SD card to send the command to.
-
- @retval EFI_SUCCESS The software reset executes successfully.
- @retval Others The software reset fails.
-
-**/
-EFI_STATUS
-SdMmcHcReset (
- IN SD_MMC_HC_PRIVATE_DATA *Private,
- IN UINT8 Slot
- );
-
-/**
- Initial SD/MMC host controller with lowest clock frequency, max power and max timeout value
- at initialization.
-
- @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
- @param[in] Slot The slot number of the SD card to send the command to.
-
- @retval EFI_SUCCESS The host controller is initialized successfully.
- @retval Others The host controller isn't initialized successfully.
-
-**/
-EFI_STATUS
-SdMmcHcInitHost (
- IN SD_MMC_HC_PRIVATE_DATA *Private,
- IN UINT8 Slot
- );
-
#endif
--
2.19.1.windows.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] patch1_add_support_bh720_emmc_chip
2019-01-28 7:35 [PATCH] patch1_add_support_bh720_emmc_chip Mike Li (WH)
@ 2019-01-29 2:31 ` Wu, Hao A
0 siblings, 0 replies; 2+ messages in thread
From: Wu, Hao A @ 2019-01-29 2:31 UTC (permalink / raw)
To: Mike Li (WH), edk2-devel@lists.01.org
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Mike
> Li (WH)
> Sent: Monday, January 28, 2019 3:36 PM
> To: edk2-devel@lists.01.org
> Subject: [edk2] [PATCH] patch1_add_support_bh720_emmc_chip
Hi,
Thanks for the contribution. I saw you sent out a total of 3 patches for
the SdMmcPciHcDxe driver, and they seem to be related.
Could you please help to do the below things that will help for reviewing
your patches:
* Rebase your changes to the latest mater branch of the edk2;
* Generate a patch series rather than separate patch files if you think
they are related;
* Help to provide detailed information on the purpose of the patches or
the issue you met in the log message of each commit.
You may get some help by referring:
https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Development-Process
Thanks in advance.
Best Regards,
Hao Wu
>
> ---
> .../Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c | 253 ++++++++++++------
> .../Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h | 47 +---
> 2 files changed, 178 insertions(+), 122 deletions(-)
>
> diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
> b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
> index 4ef849fd09..ac79a2f791 100644
> --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
> +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
> @@ -527,17 +527,35 @@ EmmcTuningClkForHs200 (
> if (EFI_ERROR (Status)) {
> return Status;
> }
> +
> + if(BhtHostPciSupport(PciIo)){
> + //set data transfer with 4bit
> + Status = SdMmcHcSetBusWidth (PciIo, Slot, 4);
> + //enable hardware tuning
> + HostCtrl2 = (~0x10);
> + Status = SdMmcHcAndMmio (PciIo, Slot, 0x110,sizeof
> (HostCtrl2), &HostCtrl2);
> +
> + Status = EmmcSendTuningBlk (PassThru, Slot, 4);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "EmmcTuningClkForHs200: Send
> tuning block fails with %r\n", Status));
> + return Status;
> + }
> +
> + }
> //
> // Ask the device to send a sequence of tuning blocks till the tuning procedure
> is done.
> //
> Retry = 0;
> do {
> - Status = EmmcSendTuningBlk (PassThru, Slot, BusWidth);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR, "EmmcTuningClkForHs200: Send tuning block
> fails with %r\n", Status));
> - return Status;
> - }
> -
> + if(!BhtHostPciSupport(PciIo)){
> + Status = EmmcSendTuningBlk (PassThru, Slot, BusWidth);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "EmmcTuningClkForHs200: Send tuning
> block fails with %r\n", Status));
> + return Status;
> + }
> + } else {
> + gBS->Stall(5000);
> + }
> Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE,
> sizeof (HostCtrl2), &HostCtrl2);
> if (EFI_ERROR (Status)) {
> return Status;
> @@ -548,6 +566,10 @@ EmmcTuningClkForHs200 (
> }
>
> if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) {
> + if(BhtHostPciSupport(PciIo)){
> + //set data transfer with default
> + Status = SdMmcHcSetBusWidth (PciIo, Slot, BusWidth);
> + }
> return EFI_SUCCESS;
> }
> } while (++Retry < 40);
> @@ -652,7 +674,6 @@ EmmcSwitchBusWidth (
> @param[in] Slot The slot number of the SD card to send the command
> to.
> @param[in] Rca The relative device address to be assigned.
> @param[in] HsTiming The value to be written to HS_TIMING field of
> EXT_CSD register.
> - @param[in] Timing The bus mode timing indicator.
> @param[in] ClockFreq The max clock frequency to be set, the unit is MHz.
>
> @retval EFI_SUCCESS The operation is done correctly.
> @@ -666,7 +687,6 @@ EmmcSwitchClockFreq (
> IN UINT8 Slot,
> IN UINT16 Rca,
> IN UINT8 HsTiming,
> - IN SD_MMC_BUS_MODE Timing,
> IN UINT32 ClockFreq
> )
> {
> @@ -708,28 +728,7 @@ EmmcSwitchClockFreq (
> //
> // Convert the clock freq unit from MHz to KHz.
> //
> - Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, Private-
> >BaseClkFreq[Slot], Private->ControllerVersion[Slot]);
> - if (EFI_ERROR (Status)) {
> - return Status;
> - }
> -
> - if (mOverride != NULL && mOverride->NotifyPhase != NULL) {
> - Status = mOverride->NotifyPhase (
> - Private->ControllerHandle,
> - Slot,
> - EdkiiSdMmcSwitchClockFreqPost,
> - &Timing
> - );
> - if (EFI_ERROR (Status)) {
> - DEBUG ((
> - DEBUG_ERROR,
> - "%a: SD/MMC switch clock freq post notifier callback failed - %r\n",
> - __FUNCTION__,
> - Status
> - ));
> - return Status;
> - }
> - }
> + Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, Private-
> >Capability[Slot]);
>
> return Status;
> }
> @@ -764,13 +763,10 @@ EmmcSwitchToHighSpeed (
> IN UINT8 BusWidth
> )
> {
> - EFI_STATUS Status;
> - UINT8 HsTiming;
> - UINT8 HostCtrl1;
> - SD_MMC_BUS_MODE Timing;
> - SD_MMC_HC_PRIVATE_DATA *Private;
> -
> - Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
> + EFI_STATUS Status;
> + UINT8 HsTiming;
> + UINT8 HostCtrl1;
> + UINT8 HostCtrl2;
>
> Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusWidth);
> if (EFI_ERROR (Status)) {
> @@ -785,21 +781,31 @@ EmmcSwitchToHighSpeed (
> return Status;
> }
>
> + //
> + // Clean UHS Mode Select field of Host Control 2 reigster before update
> + //
> + HostCtrl2 = (UINT8)~0x7;
> + Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof
> (HostCtrl2), &HostCtrl2);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> + //
> + // Set UHS Mode Select field of Host Control 2 reigster to SDR12/25/50
> + //
> if (IsDdr) {
> - Timing = SdMmcMmcHsDdr;
> + HostCtrl2 = BIT2;
> } else if (ClockFreq == 52) {
> - Timing = SdMmcMmcHsSdr;
> + HostCtrl2 = BIT0;
> } else {
> - Timing = SdMmcMmcLegacy;
> + HostCtrl2 = 0;
> }
> -
> - Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot,
> Timing);
> + Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof
> (HostCtrl2), &HostCtrl2);
> if (EFI_ERROR (Status)) {
> return Status;
> }
>
> HsTiming = 1;
> - Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, Timing,
> ClockFreq);
> + Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming,
> ClockFreq);
>
> return Status;
> }
> @@ -831,13 +837,10 @@ EmmcSwitchToHS200 (
> IN UINT8 BusWidth
> )
> {
> - EFI_STATUS Status;
> - UINT8 HsTiming;
> - UINT16 ClockCtrl;
> - SD_MMC_BUS_MODE Timing;
> - SD_MMC_HC_PRIVATE_DATA *Private;
> -
> - Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
> + EFI_STATUS Status;
> + UINT8 HsTiming;
> + UINT8 HostCtrl2;
> + UINT16 ClockCtrl;
>
> if ((BusWidth != 4) && (BusWidth != 8)) {
> return EFI_INVALID_PARAMETER;
> @@ -857,29 +860,60 @@ EmmcSwitchToHS200 (
> if (EFI_ERROR (Status)) {
> return Status;
> }
> -
> - Timing = SdMmcMmcHs200;
> -
> - Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot,
> Timing);
> + //
> + // Clean UHS Mode Select field of Host Control 2 reigster before update
> + //
> + HostCtrl2 = (UINT8)~0x7;
> + Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof
> (HostCtrl2), &HostCtrl2);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> + //
> + // Set UHS Mode Select field of Host Control 2 reigster to SDR104
> + //
> + HostCtrl2 = BIT0 | BIT1;
> + Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof
> (HostCtrl2), &HostCtrl2);
> if (EFI_ERROR (Status)) {
> return Status;
> }
> -
> //
> // Wait Internal Clock Stable in the Clock Control register to be 1 before set
> SD Clock Enable bit
> //
> - Status = SdMmcHcWaitMmioSet (
> - PciIo,
> - Slot,
> - SD_MMC_HC_CLOCK_CTRL,
> - sizeof (ClockCtrl),
> - BIT1,
> - BIT1,
> - SD_MMC_HC_GENERIC_TIMEOUT
> + if (BhtHostPciSupport(PciIo)) {
> + Status = SdMmcHcWaitMmioSet (
> + PciIo,
> + Slot,
> + 0x1cc,
> + sizeof (ClockCtrl),
> + BIT14,
> + BIT14,
> + SD_MMC_HC_GENERIC_TIMEOUT
> );
> + }
> + else {
> + Status = SdMmcHcWaitMmioSet (
> + PciIo,
> + Slot,
> + SD_MMC_HC_CLOCK_CTRL,
> + sizeof (ClockCtrl),
> + BIT1,
> + BIT1,
> + SD_MMC_HC_GENERIC_TIMEOUT
> + );
> + }
> if (EFI_ERROR (Status)) {
> return Status;
> }
> +
> + if (BhtHostPciSupport(PciIo)){
> + //Wait 2nd Card Detect debounce Finished by wait twice of debounce max
> time
> + UINT32 value32;
> + while (1) {
> + Status = SdMmcHcRwMmio (PciIo, Slot,
> SD_MMC_HC_PRESENT_STATE, TRUE, sizeof(value32), &value32);
> + if (((value32 >> 18) & 0x01) == ((value32 >> 16) & 0x01))
> + break;
> + }
> + }
> //
> // Set SD Clock Enable in the Clock Control register to 1
> //
> @@ -887,12 +921,33 @@ EmmcSwitchToHS200 (
> Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_CLOCK_CTRL, sizeof
> (ClockCtrl), &ClockCtrl);
>
> HsTiming = 2;
> - Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, Timing,
> ClockFreq);
> + Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming,
> ClockFreq);
> if (EFI_ERROR (Status)) {
> return Status;
> }
>
> - Status = EmmcTuningClkForHs200 (PciIo, PassThru, Slot, BusWidth);
> + if (BhtHostPciSupport(PciIo)){
> + Status = SdMmcHcWaitMmioSet (
> + PciIo,
> + Slot,
> + 0x1cc,
> + sizeof (ClockCtrl),
> + BIT11,
> + BIT11,
> + SD_MMC_CLOCK_STABLE_TIMEOUT
> + );
> + if (EFI_ERROR(Status)) {
> + DbgMsg(L"Wait Clock Stable timeout, ClockFreq=%d\n", ClockFreq);
> + return Status;
> + }
> + }
> +
> + if (EFI_ERROR(Status)) {
> + DbgMsg(L"Emmc tuning failed\n");
> + return Status;
> + }
> +
> +
>
> return Status;
> }
> @@ -922,12 +977,9 @@ EmmcSwitchToHS400 (
> IN UINT32 ClockFreq
> )
> {
> - EFI_STATUS Status;
> - UINT8 HsTiming;
> - SD_MMC_BUS_MODE Timing;
> - SD_MMC_HC_PRIVATE_DATA *Private;
> -
> - Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
> + EFI_STATUS Status;
> + UINT8 HsTiming;
> + UINT8 HostCtrl2;
>
> Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq, 8);
> if (EFI_ERROR (Status)) {
> @@ -937,7 +989,7 @@ EmmcSwitchToHS400 (
> // Set to Hight Speed timing and set the clock frequency to a value less than
> 52MHz.
> //
> HsTiming = 1;
> - Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming,
> SdMmcMmcHsSdr, 52);
> + Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, 52);
> if (EFI_ERROR (Status)) {
> return Status;
> }
> @@ -948,16 +1000,25 @@ EmmcSwitchToHS400 (
> if (EFI_ERROR (Status)) {
> return Status;
> }
> -
> - Timing = SdMmcMmcHs400;
> -
> - Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot,
> Timing);
> + //
> + // Clean UHS Mode Select field of Host Control 2 reigster before update
> + //
> + HostCtrl2 = (UINT8)~0x7;
> + Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof
> (HostCtrl2), &HostCtrl2);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> + //
> + // Set UHS Mode Select field of Host Control 2 reigster to HS400
> + //
> + HostCtrl2 = BIT0 | BIT2;
> + Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof
> (HostCtrl2), &HostCtrl2);
> if (EFI_ERROR (Status)) {
> return Status;
> }
>
> HsTiming = 3;
> - Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming, Timing,
> ClockFreq);
> + Status = EmmcSwitchClockFreq (PciIo, PassThru, Slot, Rca, HsTiming,
> ClockFreq);
>
> return Status;
> }
> @@ -1008,7 +1069,7 @@ EmmcSetBusMode (
> return Status;
> }
>
> - ASSERT (Private->BaseClkFreq[Slot] != 0);
> + ASSERT (Private->Capability[Slot].BaseClkFreq != 0);
> //
> // Check if the Host Controller support 8bits bus width.
> //
> @@ -1080,6 +1141,42 @@ EmmcSetBusMode (
> // Execute HS200 timing switch procedure
> //
> Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq,
> BusWidth);
> + if (EFI_ERROR(Status)) {
> + if (BhtHostPciSupport(PciIo)) {
> + UINT32 val32;
> + DbgMsg(L"switch to HS200 200MHZ failed, freq decrease to
> 100MHz\n");
> + ClockFreq = 100;
> +
> + SdMmcHcRwMmio (PciIo, Slot, 0x3C, TRUE, sizeof(val32),
> &val32);
> + val32 &= ~BIT22;
> + SdMmcHcRwMmio (PciIo, Slot, 0x3C, FALSE, sizeof(val32), &val32);
> + val32 = (BIT26 | BIT25);
> + SdMmcHcOrMmio (PciIo, Slot, 0x2C, sizeof(val32), &val32);
> +
> + Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca,
> ClockFreq, BusWidth);
> + if (EFI_ERROR(Status)) {
> + if (((ExtCsd.DeviceType & BIT1) != 0) && (Private-
> >Capability[Slot].HighSpeed != 0)) {
> + DbgMsg(L"switch to HS200 100MHZ failed, mode
> decrease to HS 50MHz\n");
> +
> + HsTiming = 1;
> + IsDdr = FALSE;
> + ClockFreq = 52;
> + Status = EmmcSwitchToHighSpeed (PciIo, PassThru,
> Slot, Rca, ClockFreq, IsDdr, BusWidth);
> + }
> + else if (((ExtCsd.DeviceType & BIT0) != 0) && (Private-
> >Capability[Slot].HighSpeed != 0)) {
> + DbgMsg(L"switch to HS200 100MHZ failed, mode
> decrease to HS 25MHz\n");
> +
> + HsTiming = 1;
> + IsDdr = FALSE;
> + ClockFreq = 26;
> + Status = EmmcSwitchToHighSpeed (PciIo, PassThru,
> Slot, Rca, ClockFreq, IsDdr, BusWidth);
> + }
> + else {
> + DbgMsg(L"switch to HS200 100MHZ failed, but emmc
> chip didn't support hs mode\n");
> + }
> + }
> + }
> + }
> } else {
> //
> // Execute High Speed timing switch procedure
> diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
> b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
> index 1bb701a503..0d14b53105 100644
> --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
> +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
> @@ -36,7 +36,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY
> KIND, EITHER EXPRESS OR IMPLIED.
> #include <Protocol/DriverBinding.h>
> #include <Protocol/ComponentName.h>
> #include <Protocol/ComponentName2.h>
> -#include <Protocol/SdMmcOverride.h>
> #include <Protocol/SdMmcPassThru.h>
>
> #include "SdMmcPciHci.h"
> @@ -45,8 +44,6 @@ extern EFI_COMPONENT_NAME_PROTOCOL
> gSdMmcPciHcComponentName;
> extern EFI_COMPONENT_NAME2_PROTOCOL
> gSdMmcPciHcComponentName2;
> extern EFI_DRIVER_BINDING_PROTOCOL gSdMmcPciHcDriverBinding;
>
> -extern EDKII_SD_MMC_OVERRIDE *mOverride;
> -
> #define SD_MMC_HC_PRIVATE_SIGNATURE SIGNATURE_32 ('s', 'd', 't', 'f')
>
> #define SD_MMC_HC_PRIVATE_FROM_THIS(a) \
> @@ -56,6 +53,7 @@ extern EDKII_SD_MMC_OVERRIDE *mOverride;
> // Generic time out value, 1 microsecond as unit.
> //
> #define SD_MMC_HC_GENERIC_TIMEOUT 1 * 1000 * 1000
> +#define SD_MMC_CLOCK_STABLE_TIMEOUT 3 * 1000
>
> //
> // SD/MMC async transfer timer interval, set by experience.
> @@ -117,13 +115,8 @@ typedef struct {
> SD_MMC_HC_SLOT Slot[SD_MMC_HC_MAX_SLOT];
> SD_MMC_HC_SLOT_CAP Capability[SD_MMC_HC_MAX_SLOT];
> UINT64 MaxCurrent[SD_MMC_HC_MAX_SLOT];
> - UINT16 ControllerVersion[SD_MMC_HC_MAX_SLOT];
>
> - //
> - // Some controllers may require to override base clock frequency
> - // value stored in Capabilities Register 1.
> - //
> - UINT32 BaseClkFreq[SD_MMC_HC_MAX_SLOT];
> + UINT32 ControllerVersion;
> } SD_MMC_HC_PRIVATE_DATA;
>
> #define SD_MMC_HC_TRB_SIG SIGNATURE_32 ('T', 'R', 'B', 'T')
> @@ -150,8 +143,7 @@ typedef struct {
> BOOLEAN Started;
> UINT64 Timeout;
>
> - SD_MMC_HC_ADMA_32_DESC_LINE *Adma32Desc;
> - SD_MMC_HC_ADMA_64_DESC_LINE *Adma64Desc;
> + SD_MMC_HC_ADMA_DESC_LINE *AdmaDesc;
> EFI_PHYSICAL_ADDRESS AdmaDescPhy;
> VOID *AdmaMap;
> UINT32 AdmaPages;
> @@ -792,37 +784,4 @@ SdCardIdentification (
> IN UINT8 Slot
> );
>
> -/**
> - Software reset the specified SD/MMC host controller.
> -
> - @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA
> instance.
> - @param[in] Slot The slot number of the SD card to send the command
> to.
> -
> - @retval EFI_SUCCESS The software reset executes successfully.
> - @retval Others The software reset fails.
> -
> -**/
> -EFI_STATUS
> -SdMmcHcReset (
> - IN SD_MMC_HC_PRIVATE_DATA *Private,
> - IN UINT8 Slot
> - );
> -
> -/**
> - Initial SD/MMC host controller with lowest clock frequency, max power and
> max timeout value
> - at initialization.
> -
> - @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA
> instance.
> - @param[in] Slot The slot number of the SD card to send the command
> to.
> -
> - @retval EFI_SUCCESS The host controller is initialized successfully.
> - @retval Others The host controller isn't initialized successfully.
> -
> -**/
> -EFI_STATUS
> -SdMmcHcInitHost (
> - IN SD_MMC_HC_PRIVATE_DATA *Private,
> - IN UINT8 Slot
> - );
> -
> #endif
> --
> 2.19.1.windows.1
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2019-01-29 2:31 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-01-28 7:35 [PATCH] patch1_add_support_bh720_emmc_chip Mike Li (WH)
2019-01-29 2:31 ` Wu, Hao A
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox