IN UINT8 BusWidth\r
)\r
{\r
- EFI_STATUS Status;\r
- UINT8 HsTiming;\r
- UINT8 HostCtrl1;\r
- UINT8 HostCtrl2;\r
+ EFI_STATUS Status;\r
+ UINT8 HsTiming;\r
+ UINT8 HostCtrl1;\r
+ SD_MMC_BUS_MODE Timing;\r
+ SD_MMC_HC_PRIVATE_DATA *Private;\r
+\r
+ Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);\r
\r
Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusWidth);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
- //\r
- // Clean UHS Mode Select field of Host Control 2 reigster before update\r
- //\r
- HostCtrl2 = (UINT8)~0x7;\r
- Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Set UHS Mode Select field of Host Control 2 reigster to SDR12/25/50\r
- //\r
if (IsDdr) {\r
- HostCtrl2 = BIT2;\r
+ Timing = SdMmcMmcHsDdr;\r
} else if (ClockFreq == 52) {\r
- HostCtrl2 = BIT0;\r
+ Timing = SdMmcMmcHsSdr;\r
} else {\r
- HostCtrl2 = 0;\r
+ Timing = SdMmcMmcLegacy;\r
}\r
- Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
+\r
+ Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
IN UINT8 BusWidth\r
)\r
{\r
- EFI_STATUS Status;\r
- UINT8 HsTiming;\r
- UINT8 HostCtrl2;\r
- UINT16 ClockCtrl;\r
+ EFI_STATUS Status;\r
+ UINT8 HsTiming;\r
+ UINT16 ClockCtrl;\r
+ SD_MMC_BUS_MODE Timing;\r
+ SD_MMC_HC_PRIVATE_DATA *Private;\r
+\r
+ Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);\r
\r
if ((BusWidth != 4) && (BusWidth != 8)) {\r
return EFI_INVALID_PARAMETER;\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- //\r
- // Clean UHS Mode Select field of Host Control 2 reigster before update\r
- //\r
- HostCtrl2 = (UINT8)~0x7;\r
- Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Set UHS Mode Select field of Host Control 2 reigster to SDR104\r
- //\r
- HostCtrl2 = BIT0 | BIT1;\r
- Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
+\r
+ Timing = SdMmcMmcHs200;\r
+\r
+ Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+\r
//\r
// Wait Internal Clock Stable in the Clock Control register to be 1 before set SD Clock Enable bit\r
//\r
IN UINT32 ClockFreq\r
)\r
{\r
- EFI_STATUS Status;\r
- UINT8 HsTiming;\r
- UINT8 HostCtrl2;\r
+ EFI_STATUS Status;\r
+ UINT8 HsTiming;\r
+ SD_MMC_BUS_MODE Timing;\r
+ SD_MMC_HC_PRIVATE_DATA *Private;\r
+\r
+ Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);\r
\r
Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq, 8);\r
if (EFI_ERROR (Status)) {\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- //\r
- // Clean UHS Mode Select field of Host Control 2 reigster before update\r
- //\r
- HostCtrl2 = (UINT8)~0x7;\r
- Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Set UHS Mode Select field of Host Control 2 reigster to HS400\r
- //\r
- HostCtrl2 = BIT0 | BIT2;\r
- Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
+\r
+ Timing = SdMmcMmcHs400;\r
+\r
+ Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
UINT8 BusWidth;\r
UINT8 AccessMode;\r
UINT8 HostCtrl1;\r
- UINT8 HostCtrl2;\r
UINT8 SwitchResp[64];\r
+ SD_MMC_BUS_MODE Timing;\r
SD_MMC_HC_PRIVATE_DATA *Private;\r
\r
Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);\r
if (S18A && (Capability->Sdr104 != 0) && ((SwitchResp[13] & BIT3) != 0)) {\r
ClockFreq = 208;\r
AccessMode = 3;\r
+ Timing = SdMmcUhsSdr104;\r
} else if (S18A && (Capability->Sdr50 != 0) && ((SwitchResp[13] & BIT2) != 0)) {\r
ClockFreq = 100;\r
AccessMode = 2;\r
+ Timing = SdMmcUhsSdr50;\r
} else if (S18A && (Capability->Ddr50 != 0) && ((SwitchResp[13] & BIT4) != 0)) {\r
ClockFreq = 50;\r
AccessMode = 4;\r
+ Timing = SdMmcUhsDdr50;\r
} else if ((SwitchResp[13] & BIT1) != 0) {\r
ClockFreq = 50;\r
AccessMode = 1;\r
+ Timing = SdMmcUhsSdr25;\r
} else {\r
ClockFreq = 25;\r
AccessMode = 0;\r
+ Timing = SdMmcUhsSdr12;\r
}\r
\r
Status = SdCardSwitch (PassThru, Slot, AccessMode, 0xF, 0xF, 0xF, TRUE, SwitchResp);\r
}\r
}\r
\r
- HostCtrl2 = (UINT8)~0x7;\r
- Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- HostCtrl2 = AccessMode;\r
- Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
+ Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, Timing);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
return Status;\r
}\r
\r
+/**\r
+ Set SD Host Controler control 2 registry according to selected speed.\r
+\r
+ @param[in] ControllerHandle The handle of the controller.\r
+ @param[in] PciIo The PCI IO protocol instance.\r
+ @param[in] Slot The slot number of the SD card to send the command to.\r
+ @param[in] Timing The timing to select.\r
+\r
+ @retval EFI_SUCCESS The timing is set successfully.\r
+ @retval Others The timing isn't set successfully.\r
+**/\r
+EFI_STATUS\r
+SdMmcHcUhsSignaling (\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT8 Slot,\r
+ IN SD_MMC_BUS_MODE Timing\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 HostCtrl2;\r
+\r
+ HostCtrl2 = (UINT8)~SD_MMC_HC_CTRL_UHS_MASK;\r
+ Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ switch (Timing) {\r
+ case SdMmcUhsSdr12:\r
+ HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR12;\r
+ break;\r
+ case SdMmcUhsSdr25:\r
+ HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR25;\r
+ break;\r
+ case SdMmcUhsSdr50:\r
+ HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR50;\r
+ break;\r
+ case SdMmcUhsSdr104:\r
+ HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR104;\r
+ break;\r
+ case SdMmcUhsDdr50:\r
+ HostCtrl2 = SD_MMC_HC_CTRL_UHS_DDR50;\r
+ break;\r
+ case SdMmcMmcLegacy:\r
+ HostCtrl2 = SD_MMC_HC_CTRL_MMC_LEGACY;\r
+ break;\r
+ case SdMmcMmcHsSdr:\r
+ HostCtrl2 = SD_MMC_HC_CTRL_MMC_HS_SDR;\r
+ break;\r
+ case SdMmcMmcHsDdr:\r
+ HostCtrl2 = SD_MMC_HC_CTRL_MMC_HS_DDR;\r
+ break;\r
+ case SdMmcMmcHs200:\r
+ HostCtrl2 = SD_MMC_HC_CTRL_MMC_HS200;\r
+ break;\r
+ case SdMmcMmcHs400:\r
+ HostCtrl2 = SD_MMC_HC_CTRL_MMC_HS400;\r
+ break;\r
+ default:\r
+ HostCtrl2 = 0;\r
+ break;\r
+ }\r
+ Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (mOverride != NULL && mOverride->NotifyPhase != NULL) {\r
+ Status = mOverride->NotifyPhase (\r
+ ControllerHandle,\r
+ Slot,\r
+ EdkiiSdMmcUhsSignaling,\r
+ &Timing\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a: SD/MMC uhs signaling notifier callback failed - %r\n",\r
+ __FUNCTION__,\r
+ Status\r
+ ));\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
Turn on/off LED.\r
\r
#define SD_MMC_HC_SLOT_INT_STS 0xFC\r
#define SD_MMC_HC_CTRL_VER 0xFE\r
\r
+//\r
+// SD Host Controller bits to HOST_CTRL2 register\r
+//\r
+#define SD_MMC_HC_CTRL_UHS_MASK 0x0007\r
+#define SD_MMC_HC_CTRL_UHS_SDR12 0x0000\r
+#define SD_MMC_HC_CTRL_UHS_SDR25 0x0001\r
+#define SD_MMC_HC_CTRL_UHS_SDR50 0x0002\r
+#define SD_MMC_HC_CTRL_UHS_SDR104 0x0003\r
+#define SD_MMC_HC_CTRL_UHS_DDR50 0x0004\r
+#define SD_MMC_HC_CTRL_MMC_LEGACY 0x0000\r
+#define SD_MMC_HC_CTRL_MMC_HS_SDR 0x0001\r
+#define SD_MMC_HC_CTRL_MMC_HS_DDR 0x0004\r
+#define SD_MMC_HC_CTRL_MMC_HS200 0x0003\r
+#define SD_MMC_HC_CTRL_MMC_HS400 0x0005\r
+\r
//\r
// The transfer modes supported by SD Host Controller\r
// Simplified Spec 3.0 Table 1-2\r
IN UINT8 Slot\r
);\r
\r
+/**\r
+ Set SD Host Controller control 2 registry according to selected speed.\r
+\r
+ @param[in] ControllerHandle The handle of the controller.\r
+ @param[in] PciIo The PCI IO protocol instance.\r
+ @param[in] Slot The slot number of the SD card to send the command to.\r
+ @param[in] Timing The timing to select.\r
+\r
+ @retval EFI_SUCCESS The timing is set successfully.\r
+ @retval Others The timing isn't set successfully.\r
+**/\r
+EFI_STATUS\r
+SdMmcHcUhsSignaling (\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT8 Slot,\r
+ IN SD_MMC_BUS_MODE Timing\r
+ );\r
+\r
#endif\r
\r
typedef struct _EDKII_SD_MMC_OVERRIDE EDKII_SD_MMC_OVERRIDE;\r
\r
+//\r
+// Bus timing modes\r
+//\r
+typedef enum {\r
+ SdMmcUhsSdr12,\r
+ SdMmcUhsSdr25,\r
+ SdMmcUhsSdr50,\r
+ SdMmcUhsSdr104,\r
+ SdMmcUhsDdr50,\r
+ SdMmcMmcLegacy,\r
+ SdMmcMmcHsSdr,\r
+ SdMmcMmcHsDdr,\r
+ SdMmcMmcHs200,\r
+ SdMmcMmcHs400,\r
+} SD_MMC_BUS_MODE;\r
+\r
typedef enum {\r
EdkiiSdMmcResetPre,\r
EdkiiSdMmcResetPost,\r
EdkiiSdMmcInitHostPre,\r
EdkiiSdMmcInitHostPost,\r
+ EdkiiSdMmcUhsSignaling,\r
} EDKII_SD_MMC_PHASE_TYPE;\r
\r
/**\r