MdeModulePkg/SdMmcPciHcDxe: Add UhsSignaling to SdMmcOverride protocol

Some SD Host Controllers use different values in Host Control 2 Register
to select UHS Mode. This patch adds a new UhsSignaling type routine to
the NotifyPhase of the SdMmcOverride protocol.

UHS signaling configuration is moved to a common, default routine
(SdMmcHcUhsSignaling). After it is executed, the protocol producer
can override the values if needed.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Hao Wu <hao.a.wu@intel.com>
This commit is contained in:
Tomasz Michalec
2018-11-10 07:01:25 +08:00
committed by Hao Wu
parent 49c9953425
commit a4708009cc
5 changed files with 181 additions and 60 deletions

View File

@@ -740,10 +740,13 @@ EmmcSwitchToHighSpeed (
IN UINT8 BusWidth
)
{
EFI_STATUS Status;
UINT8 HsTiming;
UINT8 HostCtrl1;
UINT8 HostCtrl2;
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);
Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusWidth);
if (EFI_ERROR (Status)) {
@@ -758,25 +761,15 @@ 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) {
HostCtrl2 = BIT2;
Timing = SdMmcMmcHsDdr;
} else if (ClockFreq == 52) {
HostCtrl2 = BIT0;
Timing = SdMmcMmcHsSdr;
} else {
HostCtrl2 = 0;
Timing = SdMmcMmcLegacy;
}
Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -814,10 +807,13 @@ EmmcSwitchToHS200 (
IN UINT8 BusWidth
)
{
EFI_STATUS Status;
UINT8 HsTiming;
UINT8 HostCtrl2;
UINT16 ClockCtrl;
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);
if ((BusWidth != 4) && (BusWidth != 8)) {
return EFI_INVALID_PARAMETER;
@@ -837,22 +833,14 @@ EmmcSwitchToHS200 (
if (EFI_ERROR (Status)) {
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 SDR104
//
HostCtrl2 = BIT0 | BIT1;
Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
Timing = SdMmcMmcHs200;
Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit
//
@@ -910,9 +898,12 @@ EmmcSwitchToHS400 (
IN UINT32 ClockFreq
)
{
EFI_STATUS Status;
UINT8 HsTiming;
UINT8 HostCtrl2;
EFI_STATUS Status;
UINT8 HsTiming;
SD_MMC_BUS_MODE Timing;
SD_MMC_HC_PRIVATE_DATA *Private;
Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq, 8);
if (EFI_ERROR (Status)) {
@@ -933,19 +924,10 @@ EmmcSwitchToHS400 (
if (EFI_ERROR (Status)) {
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 HS400
//
HostCtrl2 = BIT0 | BIT2;
Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
Timing = SdMmcMmcHs400;
Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);
if (EFI_ERROR (Status)) {
return Status;
}