MdeModulePkg/SdMmcPciHcDxe: add Bayhub support
Add support for Bayhub eMMC controller found on AMD Stoneyridge Chromebooks. Test: build/boot various google/kahlee-based devices Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
This commit is contained in:
committed by
Tim Crawford
parent
e167ed1a3d
commit
587653cd8b
@@ -521,15 +521,34 @@ EmmcTuningClkForHs200 (
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if(BhtHostPciSupport(PciIo)) {
|
||||
//set data transfer with 4bit
|
||||
Status = SdMmcHcSetBusWidth (PciIo, Slot, 4);
|
||||
//enable hardware tuning
|
||||
HostCtrl2 = (UINT8)(~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);
|
||||
@@ -542,6 +561,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);
|
||||
@@ -874,9 +897,53 @@ EmmcSwitchToHS200 (
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, BusMode->BusTiming, BusMode->ClockFreq);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
if (BhtHostPciSupport(PciIo)){
|
||||
BusMode->BusTiming = SdMmcMmcHs200;
|
||||
Status = EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength,
|
||||
BusMode->BusTiming, BusMode->ClockFreq);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = SdMmcHcWaitMmioSet (
|
||||
PciIo,
|
||||
Slot,
|
||||
0x1cc,
|
||||
sizeof (Rca),
|
||||
BIT14,
|
||||
BIT14,
|
||||
SD_MMC_HC_GENERIC_TIMEOUT
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//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;
|
||||
}
|
||||
}
|
||||
|
||||
Status = SdMmcHcWaitMmioSet (
|
||||
PciIo,
|
||||
Slot,
|
||||
0x1cc,
|
||||
sizeof (Rca),
|
||||
BIT11,
|
||||
BIT11,
|
||||
SD_MMC_CLOCK_STABLE_TIMEOUT
|
||||
);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
} else {
|
||||
Status = EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, BusMode->BusTiming, BusMode->ClockFreq);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
Status = EmmcTuningClkForHs200 (PciIo, PassThru, Slot, BusMode->BusWidth);
|
||||
@@ -1263,10 +1330,89 @@ EmmcSetBusMode (
|
||||
DEBUG ((DEBUG_INFO, "EmmcSetBusMode: Target bus mode: timing = %d, width = %d, clock freq = %d, driver strength = %d\n",
|
||||
BusMode.BusTiming, BusMode.BusWidth, BusMode.ClockFreq, BusMode.DriverStrength.Emmc));
|
||||
|
||||
if (BhtHostPciSupport(PciIo)) {
|
||||
UINT8 EmmcVar;
|
||||
UINTN EmmcVarSize;
|
||||
Status = gRT->GetVariable (
|
||||
L"EMMC_FORCE_CARD_MODE",
|
||||
&gEfiGenericVariableGuid,
|
||||
NULL,
|
||||
&EmmcVarSize,
|
||||
&EmmcVar
|
||||
);
|
||||
if (!EFI_ERROR(Status) && EmmcVar <= 2) {
|
||||
if (EmmcVar == 2) {
|
||||
BusMode.BusTiming = SdMmcMmcHs200;
|
||||
BusMode.ClockFreq = 200;
|
||||
} else if (EmmcVar == 1) {
|
||||
BusMode.BusTiming = SdMmcMmcHs200;
|
||||
BusMode.ClockFreq = 100;
|
||||
} else {
|
||||
BusMode.BusTiming = SdMmcMmcHsSdr;
|
||||
BusMode.ClockFreq = 52;
|
||||
}
|
||||
} else {
|
||||
BusMode.BusTiming = SdMmcMmcHsSdr;
|
||||
BusMode.ClockFreq = 52;
|
||||
}
|
||||
}
|
||||
|
||||
if (BusMode.BusTiming == SdMmcMmcHs400) {
|
||||
//
|
||||
// Execute HS400 timing switch procedure
|
||||
//
|
||||
Status = EmmcSwitchToHS400 (PciIo, PassThru, Slot, Rca, &BusMode);
|
||||
} else if (BusMode.BusTiming == SdMmcMmcHs200) {
|
||||
//
|
||||
// Execute HS200 timing switch procedure
|
||||
//
|
||||
Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, &BusMode);
|
||||
|
||||
if (EFI_ERROR(Status)) {
|
||||
if (BhtHostPciSupport(PciIo)) {
|
||||
UINT32 val32;
|
||||
UINT16 EmmcVar;
|
||||
UINTN EmmcVarSize;
|
||||
#if !defined(HS100_ALLPASS_PHASE) || HS100_ALLPASS_PHASE > 10 || HS100_ALLPASS_PHASE < 0
|
||||
#error "HS100_ALLPASS_PHASE is undefined or value is invalid"
|
||||
#else
|
||||
val32 = PciBhtRead32(PciIo, 0x300);
|
||||
val32 &= 0xFF0FFFFF;
|
||||
EmmcVarSize = sizeof(EmmcVar);
|
||||
Status = gRT->GetVariable (
|
||||
L"EMMC_HS100_ALLPASS_PHASE",
|
||||
&gEfiGenericVariableGuid,
|
||||
NULL,
|
||||
&EmmcVarSize,
|
||||
&EmmcVar
|
||||
);
|
||||
if (EFI_ERROR(Status) || EmmcVar > 10)
|
||||
EmmcVar = HS100_ALLPASS_PHASE;
|
||||
val32 |= (EmmcVar << 20);
|
||||
PciBhtWrite32(PciIo, 0x300, 0x21000033 | val32);
|
||||
#endif
|
||||
BusMode.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, &BusMode);
|
||||
if (EFI_ERROR(Status)) {
|
||||
if (((ExtCsd.DeviceType & BIT1) != 0) && (Private->Capability[Slot].HighSpeed != 0)) {
|
||||
BusMode.BusTiming = SdMmcMmcHsSdr;
|
||||
BusMode.ClockFreq = 52;
|
||||
Status = EmmcSwitchToHighSpeed (PciIo, PassThru, Slot, Rca, &BusMode);
|
||||
} else if (((ExtCsd.DeviceType & BIT0) != 0) && (Private->Capability[Slot].HighSpeed != 0)) {
|
||||
BusMode.BusTiming = SdMmcMmcHsSdr;
|
||||
BusMode.ClockFreq = 26;
|
||||
Status = EmmcSwitchToHighSpeed (PciIo, PassThru, Slot, Rca, &BusMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// Note that EmmcSwitchToHighSpeed is also called for SdMmcMmcLegacy
|
||||
|
Reference in New Issue
Block a user