mirror of https://github.com/acidanthera/audk.git
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:
parent
49c9953425
commit
a4708009cc
|
@ -743,7 +743,10 @@ EmmcSwitchToHighSpeed (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT8 HsTiming;
|
UINT8 HsTiming;
|
||||||
UINT8 HostCtrl1;
|
UINT8 HostCtrl1;
|
||||||
UINT8 HostCtrl2;
|
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);
|
Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusWidth);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
@ -758,25 +761,15 @@ EmmcSwitchToHighSpeed (
|
||||||
return 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 SDR12/25/50
|
|
||||||
//
|
|
||||||
if (IsDdr) {
|
if (IsDdr) {
|
||||||
HostCtrl2 = BIT2;
|
Timing = SdMmcMmcHsDdr;
|
||||||
} else if (ClockFreq == 52) {
|
} else if (ClockFreq == 52) {
|
||||||
HostCtrl2 = BIT0;
|
Timing = SdMmcMmcHsSdr;
|
||||||
} else {
|
} 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)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -816,8 +809,11 @@ EmmcSwitchToHS200 (
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT8 HsTiming;
|
UINT8 HsTiming;
|
||||||
UINT8 HostCtrl2;
|
|
||||||
UINT16 ClockCtrl;
|
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)) {
|
if ((BusWidth != 4) && (BusWidth != 8)) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
|
@ -837,22 +833,14 @@ EmmcSwitchToHS200 (
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// Clean UHS Mode Select field of Host Control 2 reigster before update
|
Timing = SdMmcMmcHs200;
|
||||||
//
|
|
||||||
HostCtrl2 = (UINT8)~0x7;
|
Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);
|
||||||
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)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit
|
// Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit
|
||||||
//
|
//
|
||||||
|
@ -912,7 +900,10 @@ EmmcSwitchToHS400 (
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT8 HsTiming;
|
UINT8 HsTiming;
|
||||||
UINT8 HostCtrl2;
|
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);
|
Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq, 8);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
@ -933,19 +924,10 @@ EmmcSwitchToHS400 (
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// Clean UHS Mode Select field of Host Control 2 reigster before update
|
Timing = SdMmcMmcHs400;
|
||||||
//
|
|
||||||
HostCtrl2 = (UINT8)~0x7;
|
Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);
|
||||||
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)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -784,8 +784,8 @@ SdCardSetBusMode (
|
||||||
UINT8 BusWidth;
|
UINT8 BusWidth;
|
||||||
UINT8 AccessMode;
|
UINT8 AccessMode;
|
||||||
UINT8 HostCtrl1;
|
UINT8 HostCtrl1;
|
||||||
UINT8 HostCtrl2;
|
|
||||||
UINT8 SwitchResp[64];
|
UINT8 SwitchResp[64];
|
||||||
|
SD_MMC_BUS_MODE Timing;
|
||||||
SD_MMC_HC_PRIVATE_DATA *Private;
|
SD_MMC_HC_PRIVATE_DATA *Private;
|
||||||
|
|
||||||
Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
|
Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
|
||||||
|
@ -817,18 +817,23 @@ SdCardSetBusMode (
|
||||||
if (S18A && (Capability->Sdr104 != 0) && ((SwitchResp[13] & BIT3) != 0)) {
|
if (S18A && (Capability->Sdr104 != 0) && ((SwitchResp[13] & BIT3) != 0)) {
|
||||||
ClockFreq = 208;
|
ClockFreq = 208;
|
||||||
AccessMode = 3;
|
AccessMode = 3;
|
||||||
|
Timing = SdMmcUhsSdr104;
|
||||||
} else if (S18A && (Capability->Sdr50 != 0) && ((SwitchResp[13] & BIT2) != 0)) {
|
} else if (S18A && (Capability->Sdr50 != 0) && ((SwitchResp[13] & BIT2) != 0)) {
|
||||||
ClockFreq = 100;
|
ClockFreq = 100;
|
||||||
AccessMode = 2;
|
AccessMode = 2;
|
||||||
|
Timing = SdMmcUhsSdr50;
|
||||||
} else if (S18A && (Capability->Ddr50 != 0) && ((SwitchResp[13] & BIT4) != 0)) {
|
} else if (S18A && (Capability->Ddr50 != 0) && ((SwitchResp[13] & BIT4) != 0)) {
|
||||||
ClockFreq = 50;
|
ClockFreq = 50;
|
||||||
AccessMode = 4;
|
AccessMode = 4;
|
||||||
|
Timing = SdMmcUhsDdr50;
|
||||||
} else if ((SwitchResp[13] & BIT1) != 0) {
|
} else if ((SwitchResp[13] & BIT1) != 0) {
|
||||||
ClockFreq = 50;
|
ClockFreq = 50;
|
||||||
AccessMode = 1;
|
AccessMode = 1;
|
||||||
|
Timing = SdMmcUhsSdr25;
|
||||||
} else {
|
} else {
|
||||||
ClockFreq = 25;
|
ClockFreq = 25;
|
||||||
AccessMode = 0;
|
AccessMode = 0;
|
||||||
|
Timing = SdMmcUhsSdr12;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = SdCardSwitch (PassThru, Slot, AccessMode, 0xF, 0xF, 0xF, TRUE, SwitchResp);
|
Status = SdCardSwitch (PassThru, Slot, AccessMode, 0xF, 0xF, 0xF, TRUE, SwitchResp);
|
||||||
|
@ -854,13 +859,7 @@ SdCardSetBusMode (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HostCtrl2 = (UINT8)~0x7;
|
Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);
|
||||||
Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
HostCtrl2 = AccessMode;
|
|
||||||
Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1137,6 +1137,95 @@ SdMmcHcInitHost (
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set SD Host Controler control 2 registry according to selected speed.
|
||||||
|
|
||||||
|
@param[in] ControllerHandle The handle of the controller.
|
||||||
|
@param[in] PciIo The PCI IO protocol instance.
|
||||||
|
@param[in] Slot The slot number of the SD card to send the command to.
|
||||||
|
@param[in] Timing The timing to select.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The timing is set successfully.
|
||||||
|
@retval Others The timing isn't set successfully.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
SdMmcHcUhsSignaling (
|
||||||
|
IN EFI_HANDLE ControllerHandle,
|
||||||
|
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
||||||
|
IN UINT8 Slot,
|
||||||
|
IN SD_MMC_BUS_MODE Timing
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINT8 HostCtrl2;
|
||||||
|
|
||||||
|
HostCtrl2 = (UINT8)~SD_MMC_HC_CTRL_UHS_MASK;
|
||||||
|
Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (Timing) {
|
||||||
|
case SdMmcUhsSdr12:
|
||||||
|
HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR12;
|
||||||
|
break;
|
||||||
|
case SdMmcUhsSdr25:
|
||||||
|
HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR25;
|
||||||
|
break;
|
||||||
|
case SdMmcUhsSdr50:
|
||||||
|
HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR50;
|
||||||
|
break;
|
||||||
|
case SdMmcUhsSdr104:
|
||||||
|
HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR104;
|
||||||
|
break;
|
||||||
|
case SdMmcUhsDdr50:
|
||||||
|
HostCtrl2 = SD_MMC_HC_CTRL_UHS_DDR50;
|
||||||
|
break;
|
||||||
|
case SdMmcMmcLegacy:
|
||||||
|
HostCtrl2 = SD_MMC_HC_CTRL_MMC_LEGACY;
|
||||||
|
break;
|
||||||
|
case SdMmcMmcHsSdr:
|
||||||
|
HostCtrl2 = SD_MMC_HC_CTRL_MMC_HS_SDR;
|
||||||
|
break;
|
||||||
|
case SdMmcMmcHsDdr:
|
||||||
|
HostCtrl2 = SD_MMC_HC_CTRL_MMC_HS_DDR;
|
||||||
|
break;
|
||||||
|
case SdMmcMmcHs200:
|
||||||
|
HostCtrl2 = SD_MMC_HC_CTRL_MMC_HS200;
|
||||||
|
break;
|
||||||
|
case SdMmcMmcHs400:
|
||||||
|
HostCtrl2 = SD_MMC_HC_CTRL_MMC_HS400;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
HostCtrl2 = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mOverride != NULL && mOverride->NotifyPhase != NULL) {
|
||||||
|
Status = mOverride->NotifyPhase (
|
||||||
|
ControllerHandle,
|
||||||
|
Slot,
|
||||||
|
EdkiiSdMmcUhsSignaling,
|
||||||
|
&Timing
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"%a: SD/MMC uhs signaling notifier callback failed - %r\n",
|
||||||
|
__FUNCTION__,
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Turn on/off LED.
|
Turn on/off LED.
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,21 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#define SD_MMC_HC_SLOT_INT_STS 0xFC
|
#define SD_MMC_HC_SLOT_INT_STS 0xFC
|
||||||
#define SD_MMC_HC_CTRL_VER 0xFE
|
#define SD_MMC_HC_CTRL_VER 0xFE
|
||||||
|
|
||||||
|
//
|
||||||
|
// SD Host Controller bits to HOST_CTRL2 register
|
||||||
|
//
|
||||||
|
#define SD_MMC_HC_CTRL_UHS_MASK 0x0007
|
||||||
|
#define SD_MMC_HC_CTRL_UHS_SDR12 0x0000
|
||||||
|
#define SD_MMC_HC_CTRL_UHS_SDR25 0x0001
|
||||||
|
#define SD_MMC_HC_CTRL_UHS_SDR50 0x0002
|
||||||
|
#define SD_MMC_HC_CTRL_UHS_SDR104 0x0003
|
||||||
|
#define SD_MMC_HC_CTRL_UHS_DDR50 0x0004
|
||||||
|
#define SD_MMC_HC_CTRL_MMC_LEGACY 0x0000
|
||||||
|
#define SD_MMC_HC_CTRL_MMC_HS_SDR 0x0001
|
||||||
|
#define SD_MMC_HC_CTRL_MMC_HS_DDR 0x0004
|
||||||
|
#define SD_MMC_HC_CTRL_MMC_HS200 0x0003
|
||||||
|
#define SD_MMC_HC_CTRL_MMC_HS400 0x0005
|
||||||
|
|
||||||
//
|
//
|
||||||
// The transfer modes supported by SD Host Controller
|
// The transfer modes supported by SD Host Controller
|
||||||
// Simplified Spec 3.0 Table 1-2
|
// Simplified Spec 3.0 Table 1-2
|
||||||
|
@ -518,4 +533,23 @@ SdMmcHcInitTimeoutCtrl (
|
||||||
IN UINT8 Slot
|
IN UINT8 Slot
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set SD Host Controller control 2 registry according to selected speed.
|
||||||
|
|
||||||
|
@param[in] ControllerHandle The handle of the controller.
|
||||||
|
@param[in] PciIo The PCI IO protocol instance.
|
||||||
|
@param[in] Slot The slot number of the SD card to send the command to.
|
||||||
|
@param[in] Timing The timing to select.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The timing is set successfully.
|
||||||
|
@retval Others The timing isn't set successfully.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
SdMmcHcUhsSignaling (
|
||||||
|
IN EFI_HANDLE ControllerHandle,
|
||||||
|
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
||||||
|
IN UINT8 Slot,
|
||||||
|
IN SD_MMC_BUS_MODE Timing
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,11 +26,28 @@
|
||||||
|
|
||||||
typedef struct _EDKII_SD_MMC_OVERRIDE EDKII_SD_MMC_OVERRIDE;
|
typedef struct _EDKII_SD_MMC_OVERRIDE EDKII_SD_MMC_OVERRIDE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bus timing modes
|
||||||
|
//
|
||||||
|
typedef enum {
|
||||||
|
SdMmcUhsSdr12,
|
||||||
|
SdMmcUhsSdr25,
|
||||||
|
SdMmcUhsSdr50,
|
||||||
|
SdMmcUhsSdr104,
|
||||||
|
SdMmcUhsDdr50,
|
||||||
|
SdMmcMmcLegacy,
|
||||||
|
SdMmcMmcHsSdr,
|
||||||
|
SdMmcMmcHsDdr,
|
||||||
|
SdMmcMmcHs200,
|
||||||
|
SdMmcMmcHs400,
|
||||||
|
} SD_MMC_BUS_MODE;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EdkiiSdMmcResetPre,
|
EdkiiSdMmcResetPre,
|
||||||
EdkiiSdMmcResetPost,
|
EdkiiSdMmcResetPost,
|
||||||
EdkiiSdMmcInitHostPre,
|
EdkiiSdMmcInitHostPre,
|
||||||
EdkiiSdMmcInitHostPost,
|
EdkiiSdMmcInitHostPost,
|
||||||
|
EdkiiSdMmcUhsSignaling,
|
||||||
} EDKII_SD_MMC_PHASE_TYPE;
|
} EDKII_SD_MMC_PHASE_TYPE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue