MdeModulePkg/SdMmcPciHcDxe: Hook SwitchClockFreq after SD clock start

For eMMC modules we used to notify the platform about frequency
change only after sending CMD13 which meant that platform
might not get a chance to apply required post frequency
change fixes to get the clock stable. To fix this
notification has been moved to SdMmcHcClockSupply function
just after we start the SD clock. During first time setup
the notification won't be sent to avoid changing old behavior.

Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Marcin Wojtas <mw@semihalf.com>
Cc: Zhichao Gao <zhichao.gao@intel.com>
Cc: Liming Gao <liming.gao@intel.com>

Signed-off-by: Mateusz Albecki <mateusz.albecki@intel.com>
Tested-by: Marcin Wojtas <mw@semihalf.com>
Tested-by: Hao A Wu <hao.a.wu@intel.com>
Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
This commit is contained in:
Albecki, Mateusz
2019-12-21 01:13:11 +08:00
committed by mergify[bot]
parent b948a49615
commit 49accdedf9
5 changed files with 81 additions and 142 deletions

View File

@@ -1145,29 +1145,11 @@ SdCardSetBusMode (
return Status;
}
Status = SdMmcHcClockSupply (PciIo, Slot, BusMode.ClockFreq * 1000, Private->BaseClkFreq[Slot], Private->ControllerVersion[Slot]);
Status = SdMmcHcClockSupply (Private, Slot, BusMode.BusTiming, FALSE, BusMode.ClockFreq * 1000);
if (EFI_ERROR (Status)) {
return Status;
}
if (mOverride != NULL && mOverride->NotifyPhase != NULL) {
Status = mOverride->NotifyPhase (
Private->ControllerHandle,
Slot,
EdkiiSdMmcSwitchClockFreqPost,
&BusMode.BusTiming
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: SD/MMC switch clock freq post notifier callback failed - %r\n",
__FUNCTION__,
Status
));
return Status;
}
}
if ((BusMode.BusTiming == SdMmcUhsSdr104) || ((BusMode.BusTiming == SdMmcUhsSdr50) && (Capability->TuningSDR50 != 0))) {
Status = SdCardTuningClock (PciIo, PassThru, Slot);
if (EFI_ERROR (Status)) {
@@ -1345,7 +1327,13 @@ SdCardIdentification (
goto Error;
}
SdMmcHcInitClockFreq (PciIo, Slot, Private->BaseClkFreq[Slot], Private->ControllerVersion[Slot]);
//
// Restart the clock with first time parameters.
// NOTE: it is not required to actually restart the clock
// and go through internal clock setup again. Some time
// could be saved if we simply started the SD clock.
//
SdMmcHcClockSupply (Private, Slot, 0, TRUE, 400);
gBS->Stall (1000);