mirror of https://github.com/acidanthera/audk.git
MdeModulePkg/SdMmcPciHcDxe: allow HC capabilities to be overridden
Invoke the newly introduced SD/MMC override protocol to override the capabilities register after reading it from the device registers, and to call the pre/post host init and reset hooks at the appropriate times. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Hao Wu <hao.a.wu@intel.com> Reviewed-by: Star Zeng <star.zeng@intel.com>
This commit is contained in:
parent
c7be0dd5b9
commit
b23fc39cd3
|
@ -17,6 +17,8 @@
|
|||
|
||||
#include "SdMmcPciHcDxe.h"
|
||||
|
||||
EDKII_SD_MMC_OVERRIDE *mOverride;
|
||||
|
||||
//
|
||||
// Driver Global Variables
|
||||
//
|
||||
|
@ -281,14 +283,14 @@ SdMmcPciHcEnumerateDevice (
|
|||
//
|
||||
// Reset the specified slot of the SD/MMC Pci Host Controller
|
||||
//
|
||||
Status = SdMmcHcReset (Private->PciIo, Slot);
|
||||
Status = SdMmcHcReset (Private, Slot);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// Reinitialize slot and restart identification process for the new attached device
|
||||
//
|
||||
Status = SdMmcHcInitHost (Private->PciIo, Slot, Private->Capability[Slot]);
|
||||
Status = SdMmcHcInitHost (Private, Slot);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -601,6 +603,20 @@ SdMmcPciHcDriverBindingStart (
|
|||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Attempt to locate the singleton instance of the SD/MMC override protocol,
|
||||
// which implements platform specific workarounds for non-standard SDHCI
|
||||
// implementations.
|
||||
//
|
||||
if (mOverride == NULL) {
|
||||
Status = gBS->LocateProtocol (&gEdkiiSdMmcOverrideProtocolGuid, NULL,
|
||||
(VOID **)&mOverride);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "%a: found SD/MMC override protocol\n",
|
||||
__FUNCTION__));
|
||||
}
|
||||
}
|
||||
|
||||
Support64BitDma = TRUE;
|
||||
for (Slot = FirstBar; Slot < (FirstBar + SlotNum); Slot++) {
|
||||
Private->Slot[Slot].Enable = TRUE;
|
||||
|
@ -609,6 +625,17 @@ SdMmcPciHcDriverBindingStart (
|
|||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
if (mOverride != NULL && mOverride->Capability != NULL) {
|
||||
Status = mOverride->Capability (
|
||||
Controller,
|
||||
Slot,
|
||||
&Private->Capability[Slot]);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_WARN, "%a: Failed to override capability - %r\n",
|
||||
__FUNCTION__, Status));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
DumpCapabilityReg (Slot, &Private->Capability[Slot]);
|
||||
|
||||
Support64BitDma &= Private->Capability[Slot].SysBus64;
|
||||
|
@ -627,7 +654,7 @@ SdMmcPciHcDriverBindingStart (
|
|||
//
|
||||
// Reset the specified slot of the SD/MMC Pci Host Controller
|
||||
//
|
||||
Status = SdMmcHcReset (PciIo, Slot);
|
||||
Status = SdMmcHcReset (Private, Slot);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -642,7 +669,7 @@ SdMmcPciHcDriverBindingStart (
|
|||
continue;
|
||||
}
|
||||
|
||||
Status = SdMmcHcInitHost (PciIo, Slot, Private->Capability[Slot]);
|
||||
Status = SdMmcHcInitHost (Private, Slot);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
#include <Protocol/DriverBinding.h>
|
||||
#include <Protocol/ComponentName.h>
|
||||
#include <Protocol/ComponentName2.h>
|
||||
#include <Protocol/SdMmcOverride.h>
|
||||
#include <Protocol/SdMmcPassThru.h>
|
||||
|
||||
#include "SdMmcPciHci.h"
|
||||
|
@ -43,6 +44,8 @@ extern EFI_COMPONENT_NAME_PROTOCOL gSdMmcPciHcComponentName;
|
|||
extern EFI_COMPONENT_NAME2_PROTOCOL gSdMmcPciHcComponentName2;
|
||||
extern EFI_DRIVER_BINDING_PROTOCOL gSdMmcPciHcDriverBinding;
|
||||
|
||||
extern EDKII_SD_MMC_OVERRIDE *mOverride;
|
||||
|
||||
#define SD_MMC_HC_PRIVATE_SIGNATURE SIGNATURE_32 ('s', 'd', 't', 'f')
|
||||
|
||||
#define SD_MMC_HC_PRIVATE_FROM_THIS(a) \
|
||||
|
@ -782,4 +785,37 @@ SdCardIdentification (
|
|||
IN UINT8 Slot
|
||||
);
|
||||
|
||||
/**
|
||||
Software reset the specified SD/MMC host controller.
|
||||
|
||||
@param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
|
||||
@param[in] Slot The slot number of the SD card to send the command to.
|
||||
|
||||
@retval EFI_SUCCESS The software reset executes successfully.
|
||||
@retval Others The software reset fails.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SdMmcHcReset (
|
||||
IN SD_MMC_HC_PRIVATE_DATA *Private,
|
||||
IN UINT8 Slot
|
||||
);
|
||||
|
||||
/**
|
||||
Initial SD/MMC host controller with lowest clock frequency, max power and max timeout value
|
||||
at initialization.
|
||||
|
||||
@param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
|
||||
@param[in] Slot The slot number of the SD card to send the command to.
|
||||
|
||||
@retval EFI_SUCCESS The host controller is initialized successfully.
|
||||
@retval Others The host controller isn't initialized successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SdMmcHcInitHost (
|
||||
IN SD_MMC_HC_PRIVATE_DATA *Private,
|
||||
IN UINT8 Slot
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
DevicePathLib
|
||||
|
@ -61,6 +62,7 @@
|
|||
DebugLib
|
||||
|
||||
[Protocols]
|
||||
gEdkiiSdMmcOverrideProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiDevicePathProtocolGuid ## TO_START
|
||||
gEfiPciIoProtocolGuid ## TO_START
|
||||
gEfiSdMmcPassThruProtocolGuid ## BY_START
|
||||
|
|
|
@ -419,7 +419,7 @@ SdMmcHcWaitMmioSet (
|
|||
/**
|
||||
Software reset the specified SD/MMC host controller and enable all interrupts.
|
||||
|
||||
@param[in] PciIo The PCI IO protocol instance.
|
||||
@param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
|
||||
@param[in] Slot The slot number of the SD card to send the command to.
|
||||
|
||||
@retval EFI_SUCCESS The software reset executes successfully.
|
||||
|
@ -428,13 +428,32 @@ SdMmcHcWaitMmioSet (
|
|||
**/
|
||||
EFI_STATUS
|
||||
SdMmcHcReset (
|
||||
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
||||
IN SD_MMC_HC_PRIVATE_DATA *Private,
|
||||
IN UINT8 Slot
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT8 SwReset;
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
|
||||
//
|
||||
// Notify the SD/MMC override protocol that we are about to reset
|
||||
// the SD/MMC host controller.
|
||||
//
|
||||
if (mOverride != NULL && mOverride->NotifyPhase != NULL) {
|
||||
Status = mOverride->NotifyPhase (
|
||||
Private->ControllerHandle,
|
||||
Slot,
|
||||
EdkiiSdMmcResetPre);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_WARN,
|
||||
"%a: SD/MMC pre reset notifier callback failed - %r\n",
|
||||
__FUNCTION__, Status));
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
PciIo = Private->PciIo;
|
||||
SwReset = 0xFF;
|
||||
Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_SW_RST, FALSE, sizeof (SwReset), &SwReset);
|
||||
|
||||
|
@ -456,10 +475,32 @@ SdMmcHcReset (
|
|||
DEBUG ((DEBUG_INFO, "SdMmcHcReset: reset done with %r\n", Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Enable all interrupt after reset all.
|
||||
//
|
||||
Status = SdMmcHcEnableInterrupt (PciIo, Slot);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "SdMmcHcReset: SdMmcHcEnableInterrupt done with %r\n",
|
||||
Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Notify the SD/MMC override protocol that we have just reset
|
||||
// the SD/MMC host controller.
|
||||
//
|
||||
if (mOverride != NULL && mOverride->NotifyPhase != NULL) {
|
||||
Status = mOverride->NotifyPhase (
|
||||
Private->ControllerHandle,
|
||||
Slot,
|
||||
EdkiiSdMmcResetPost);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_WARN,
|
||||
"%a: SD/MMC post reset notifier callback failed - %r\n",
|
||||
__FUNCTION__, Status));
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@ -1021,9 +1062,8 @@ SdMmcHcInitTimeoutCtrl (
|
|||
Initial SD/MMC host controller with lowest clock frequency, max power and max timeout value
|
||||
at initialization.
|
||||
|
||||
@param[in] PciIo The PCI IO protocol instance.
|
||||
@param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
|
||||
@param[in] Slot The slot number of the SD card to send the command to.
|
||||
@param[in] Capability The capability of the slot.
|
||||
|
||||
@retval EFI_SUCCESS The host controller is initialized successfully.
|
||||
@retval Others The host controller isn't initialized successfully.
|
||||
|
@ -1031,12 +1071,33 @@ SdMmcHcInitTimeoutCtrl (
|
|||
**/
|
||||
EFI_STATUS
|
||||
SdMmcHcInitHost (
|
||||
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
||||
IN UINT8 Slot,
|
||||
IN SD_MMC_HC_SLOT_CAP Capability
|
||||
IN SD_MMC_HC_PRIVATE_DATA *Private,
|
||||
IN UINT8 Slot
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS Status;
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
SD_MMC_HC_SLOT_CAP Capability;
|
||||
|
||||
//
|
||||
// Notify the SD/MMC override protocol that we are about to initialize
|
||||
// the SD/MMC host controller.
|
||||
//
|
||||
if (mOverride != NULL && mOverride->NotifyPhase != NULL) {
|
||||
Status = mOverride->NotifyPhase (
|
||||
Private->ControllerHandle,
|
||||
Slot,
|
||||
EdkiiSdMmcInitHostPre);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_WARN,
|
||||
"%a: SD/MMC pre init notifier callback failed - %r\n",
|
||||
__FUNCTION__, Status));
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
PciIo = Private->PciIo;
|
||||
Capability = Private->Capability[Slot];
|
||||
|
||||
Status = SdMmcHcInitClockFreq (PciIo, Slot, Capability);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
@ -1049,6 +1110,25 @@ SdMmcHcInitHost (
|
|||
}
|
||||
|
||||
Status = SdMmcHcInitTimeoutCtrl (PciIo, Slot);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Notify the SD/MMC override protocol that we are have just initialized
|
||||
// the SD/MMC host controller.
|
||||
//
|
||||
if (mOverride != NULL && mOverride->NotifyPhase != NULL) {
|
||||
Status = mOverride->NotifyPhase (
|
||||
Private->ControllerHandle,
|
||||
Slot,
|
||||
EdkiiSdMmcInitHostPost);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_WARN,
|
||||
"%a: SD/MMC post init notifier callback failed - %r\n",
|
||||
__FUNCTION__, Status));
|
||||
}
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -297,22 +297,6 @@ SdMmcHcWaitMmioSet (
|
|||
IN UINT64 Timeout
|
||||
);
|
||||
|
||||
/**
|
||||
Software reset the specified SD/MMC host controller.
|
||||
|
||||
@param[in] PciIo The PCI IO protocol instance.
|
||||
@param[in] Slot The slot number of the SD card to send the command to.
|
||||
|
||||
@retval EFI_SUCCESS The software reset executes successfully.
|
||||
@retval Others The software reset fails.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SdMmcHcReset (
|
||||
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
||||
IN UINT8 Slot
|
||||
);
|
||||
|
||||
/**
|
||||
Set all interrupt status bits in Normal and Error Interrupt Status Enable
|
||||
register.
|
||||
|
@ -524,23 +508,4 @@ SdMmcHcInitTimeoutCtrl (
|
|||
IN UINT8 Slot
|
||||
);
|
||||
|
||||
/**
|
||||
Initial SD/MMC host controller with lowest clock frequency, max power and max timeout value
|
||||
at initialization.
|
||||
|
||||
@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] Capability The capability of the slot.
|
||||
|
||||
@retval EFI_SUCCESS The host controller is initialized successfully.
|
||||
@retval Others The host controller isn't initialized successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SdMmcHcInitHost (
|
||||
IN EFI_PCI_IO_PROTOCOL *PciIo,
|
||||
IN UINT8 Slot,
|
||||
IN SD_MMC_HC_SLOT_CAP Capability
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue