]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
MdeModulePkg/SdMmcPciHcDxe: Hook SwitchClockFreq after SD clock start
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / SdMmcPciHcDxe / SdMmcPciHci.c
index b9d04e0f17a20d6212860f654b6d78f4eeaefcdb..f667264c5e7177d762c3e7eb06b38a46ccb105c1 100644 (file)
@@ -763,11 +763,11 @@ SdMmcHcStopClock (
 \r
   Refer to SD Host Controller Simplified spec 3.0 Section 3.2.1 for details.\r
 \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] ClockFreq      The max clock frequency to be set. The unit is KHz.\r
-  @param[in] BaseClkFreq    The base clock frequency of host controller in MHz.\r
-  @param[in] ControllerVer  The version of host controller.\r
+  @param[in] Private         A pointer to the SD_MMC_HC_PRIVATE_DATA instance.\r
+  @param[in] Slot            The slot number of the SD card to send the command to.\r
+  @param[in] BusTiming       BusTiming at which the frequency change is done.\r
+  @param[in] FirstTimeSetup  Flag to indicate whether the clock is being setup for the first time.\r
+  @param[in] ClockFreq       The max clock frequency to be set. The unit is KHz.\r
 \r
   @retval EFI_SUCCESS       The clock is supplied successfully.\r
   @retval Others            The clock isn't supplied successfully.\r
@@ -775,11 +775,11 @@ SdMmcHcStopClock (
 **/\r
 EFI_STATUS\r
 SdMmcHcClockSupply (\r
-  IN EFI_PCI_IO_PROTOCOL    *PciIo,\r
-  IN UINT8                  Slot,\r
-  IN UINT64                 ClockFreq,\r
-  IN UINT32                 BaseClkFreq,\r
-  IN UINT16                 ControllerVer\r
+  IN SD_MMC_HC_PRIVATE_DATA  *Private,\r
+  IN UINT8                   Slot,\r
+  IN SD_MMC_BUS_MODE         BusTiming,\r
+  IN BOOLEAN                 FirstTimeSetup,\r
+  IN UINT64                  ClockFreq\r
   )\r
 {\r
   EFI_STATUS                Status;\r
@@ -787,13 +787,15 @@ SdMmcHcClockSupply (
   UINT32                    Divisor;\r
   UINT32                    Remainder;\r
   UINT16                    ClockCtrl;\r
+  UINT32                    BaseClkFreq;\r
+  UINT16                    ControllerVer;\r
+  EFI_PCI_IO_PROTOCOL       *PciIo;\r
 \r
-  //\r
-  // Calculate a divisor for SD clock frequency\r
-  //\r
-  ASSERT (BaseClkFreq != 0);\r
+  PciIo = Private->PciIo;\r
+  BaseClkFreq = Private->BaseClkFreq[Slot];\r
+  ControllerVer = Private->ControllerVersion[Slot];\r
 \r
-  if (ClockFreq == 0) {\r
+  if (BaseClkFreq == 0 || ClockFreq == 0) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -883,6 +885,29 @@ SdMmcHcClockSupply (
   ClockCtrl = BIT2;\r
   Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_CLOCK_CTRL, sizeof (ClockCtrl), &ClockCtrl);\r
 \r
+  //\r
+  // We don't notify the platform on first time setup to avoid changing\r
+  // legacy behavior. During first time setup we also don't know what type\r
+  // of the card slot it is and which enum value of BusTiming applies.\r
+  //\r
+  if (!FirstTimeSetup && mOverride != NULL && mOverride->NotifyPhase != NULL) {\r
+    Status = mOverride->NotifyPhase (\r
+                          Private->ControllerHandle,\r
+                          Slot,\r
+                          EdkiiSdMmcSwitchClockFreqPost,\r
+                          &BusTiming\r
+                          );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((\r
+        DEBUG_ERROR,\r
+        "%a: SD/MMC switch clock freq post notifier callback failed - %r\n",\r
+        __FUNCTION__,\r
+        Status\r
+        ));\r
+      return Status;\r
+    }\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
@@ -1038,49 +1063,6 @@ SdMmcHcInitV4Enhancements (
   return EFI_SUCCESS;\r
 }\r
 \r
-/**\r
-  Supply SD/MMC card with lowest clock frequency at initialization.\r
-\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] BaseClkFreq    The base clock frequency of host controller in MHz.\r
-  @param[in] ControllerVer  The version of host controller.\r
-\r
-  @retval EFI_SUCCESS       The clock is supplied successfully.\r
-  @retval Others            The clock isn't supplied successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-SdMmcHcInitClockFreq (\r
-  IN EFI_PCI_IO_PROTOCOL    *PciIo,\r
-  IN UINT8                  Slot,\r
-  IN UINT32                 BaseClkFreq,\r
-  IN UINT16                 ControllerVer\r
-  )\r
-{\r
-  EFI_STATUS                Status;\r
-  UINT32                    InitFreq;\r
-\r
-  //\r
-  // According to SDHCI specification ver. 4.2, BaseClkFreq field value of\r
-  // the Capability Register 1 can be zero, which means a need for obtaining\r
-  // the clock frequency via another method. Fail in case it is not updated\r
-  // by SW at this point.\r
-  //\r
-  if (BaseClkFreq == 0) {\r
-    //\r
-    // Don't support get Base Clock Frequency information via another method\r
-    //\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-  //\r
-  // Supply 400KHz clock frequency at initialization phase.\r
-  //\r
-  InitFreq = 400;\r
-  Status = SdMmcHcClockSupply (PciIo, Slot, InitFreq, BaseClkFreq, ControllerVer);\r
-  return Status;\r
-}\r
-\r
 /**\r
   Supply SD/MMC card with maximum voltage at initialization.\r
 \r
@@ -1216,7 +1198,14 @@ SdMmcHcInitHost (
     return Status;\r
   }\r
 \r
-  Status = SdMmcHcInitClockFreq (PciIo, Slot, Private->BaseClkFreq[Slot], Private->ControllerVersion[Slot]);\r
+  //\r
+  // Perform first time clock setup with 400 KHz frequency.\r
+  // We send the 0 as the BusTiming value because at this time\r
+  // we still do not know the slot type and which enum value will apply.\r
+  // Since it is a first time setup SdMmcHcClockSupply won't notify\r
+  // the platofrm driver anyway so it doesn't matter.\r
+  //\r
+  Status = SdMmcHcClockSupply (Private, Slot, 0, TRUE, 400);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r