123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563 |
- /** @file
- This file implement the MMC Host Protocol for the ARM PrimeCell PL180.
- Copyright (c) 2011-2012, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "PL180Mci.h"
- #include <Library/DevicePathLib.h>
- #include <Library/BaseMemoryLib.h>
- EFI_MMC_HOST_PROTOCOL *gpMmcHost;
- // Untested ...
- //#define USE_STREAM
- #define MMCI0_BLOCKLEN 512
- #define MMCI0_POW2_BLOCKLEN 9
- #define MMCI0_TIMEOUT 1000
- #define SYS_MCI_CARDIN BIT0
- #define SYS_MCI_WPROT BIT1
- BOOLEAN
- MciIsPowerOn (
- VOID
- )
- {
- return ((MmioRead32 (MCI_POWER_CONTROL_REG) & MCI_POWER_ON) == MCI_POWER_ON);
- }
- EFI_STATUS
- MciInitialize (
- VOID
- )
- {
- MCI_TRACE ("MciInitialize()");
- return EFI_SUCCESS;
- }
- BOOLEAN
- MciIsCardPresent (
- IN EFI_MMC_HOST_PROTOCOL *This
- )
- {
- return (MmioRead32 (FixedPcdGet32 (PcdPL180SysMciRegAddress)) & SYS_MCI_CARDIN);
- }
- BOOLEAN
- MciIsReadOnly (
- IN EFI_MMC_HOST_PROTOCOL *This
- )
- {
- return (MmioRead32 (FixedPcdGet32 (PcdPL180SysMciRegAddress)) & SYS_MCI_WPROT);
- }
- // Convert block size to 2^n
- STATIC
- UINT32
- GetPow2BlockLen (
- IN UINT32 BlockLen
- )
- {
- UINTN Loop;
- UINTN Pow2BlockLen;
- Loop = 0x8000;
- Pow2BlockLen = 15;
- do {
- Loop = (Loop >> 1) & 0xFFFF;
- Pow2BlockLen--;
- } while (Pow2BlockLen && (!(Loop & BlockLen)));
- return Pow2BlockLen;
- }
- VOID
- MciPrepareDataPath (
- IN UINTN TransferDirection
- )
- {
- // Set Data Length & Data Timer
- MmioWrite32 (MCI_DATA_TIMER_REG, 0xFFFFFFF);
- MmioWrite32 (MCI_DATA_LENGTH_REG, MMCI0_BLOCKLEN);
- #ifndef USE_STREAM
- //Note: we are using a hardcoded BlockLen (==512). If we decide to use a variable size, we could
- // compute the pow2 of BlockLen with the above function GetPow2BlockLen ()
- MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_DMA_ENABLE | TransferDirection | (MMCI0_POW2_BLOCKLEN << 4));
- #else
- MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_DMA_ENABLE | TransferDirection | MCI_DATACTL_STREAM_TRANS);
- #endif
- }
- EFI_STATUS
- MciSendCommand (
- IN EFI_MMC_HOST_PROTOCOL *This,
- IN MMC_CMD MmcCmd,
- IN UINT32 Argument
- )
- {
- UINT32 Status;
- UINT32 Cmd;
- UINTN RetVal;
- UINTN CmdCtrlReg;
- UINT32 DoneMask;
- RetVal = EFI_SUCCESS;
- if ((MmcCmd == MMC_CMD17) || (MmcCmd == MMC_CMD11)) {
- MciPrepareDataPath (MCI_DATACTL_CARD_TO_CONT);
- } else if ((MmcCmd == MMC_CMD24) || (MmcCmd == MMC_CMD20)) {
- MciPrepareDataPath (MCI_DATACTL_CONT_TO_CARD);
- } else if (MmcCmd == MMC_CMD6) {
- MmioWrite32 (MCI_DATA_TIMER_REG, 0xFFFFFFF);
- MmioWrite32 (MCI_DATA_LENGTH_REG, 64);
- #ifndef USE_STREAM
- MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_CARD_TO_CONT | GetPow2BlockLen (64));
- #else
- MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_CARD_TO_CONT | MCI_DATACTL_STREAM_TRANS);
- #endif
- } else if (MmcCmd == MMC_ACMD51) {
- MmioWrite32 (MCI_DATA_TIMER_REG, 0xFFFFFFF);
- /* SCR register is 8 bytes long. */
- MmioWrite32 (MCI_DATA_LENGTH_REG, 8);
- #ifndef USE_STREAM
- MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_CARD_TO_CONT | GetPow2BlockLen (8));
- #else
- MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_CARD_TO_CONT | MCI_DATACTL_STREAM_TRANS);
- #endif
- }
- // Create Command for PL180
- Cmd = (MMC_GET_INDX (MmcCmd) & INDX_MASK) | MCI_CPSM_ENABLE;
- if (MmcCmd & MMC_CMD_WAIT_RESPONSE) {
- Cmd |= MCI_CPSM_WAIT_RESPONSE;
- }
- if (MmcCmd & MMC_CMD_LONG_RESPONSE) {
- Cmd |= MCI_CPSM_LONG_RESPONSE;
- }
- // Clear Status register static flags
- MmioWrite32 (MCI_CLEAR_STATUS_REG, MCI_CLR_ALL_STATUS);
- // Write to command argument register
- MmioWrite32 (MCI_ARGUMENT_REG, Argument);
- // Write to command register
- MmioWrite32 (MCI_COMMAND_REG, Cmd);
- DoneMask = (Cmd & MCI_CPSM_WAIT_RESPONSE)
- ? (MCI_STATUS_CMD_RESPEND | MCI_STATUS_CMD_ERROR)
- : (MCI_STATUS_CMD_SENT | MCI_STATUS_CMD_ERROR);
- do {
- Status = MmioRead32 (MCI_STATUS_REG);
- } while (! (Status & DoneMask));
- if ((Status & MCI_STATUS_CMD_ERROR)) {
- // Clear Status register error flags
- MmioWrite32 (MCI_CLEAR_STATUS_REG, MCI_STATUS_CMD_ERROR);
- if ((Status & MCI_STATUS_CMD_START_BIT_ERROR)) {
- DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) Start bit Error! Response:0x%X Status:0x%x\n", (Cmd & 0x3F), MmioRead32 (MCI_RESPONSE0_REG), Status));
- RetVal = EFI_NO_RESPONSE;
- } else if ((Status & MCI_STATUS_CMD_CMDTIMEOUT)) {
- //DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) TIMEOUT! Response:0x%X Status:0x%x\n", (Cmd & 0x3F), MmioRead32 (MCI_RESPONSE0_REG), Status));
- RetVal = EFI_TIMEOUT;
- } else if ((!(MmcCmd & MMC_CMD_NO_CRC_RESPONSE)) && (Status & MCI_STATUS_CMD_CMDCRCFAIL)) {
- // The CMD1 and response type R3 do not contain CRC. We should ignore the CRC failed Status.
- RetVal = EFI_CRC_ERROR;
- }
- }
- // Disable Command Path
- CmdCtrlReg = MmioRead32 (MCI_COMMAND_REG);
- MmioWrite32 (MCI_COMMAND_REG, (CmdCtrlReg & ~MCI_CPSM_ENABLE));
- return RetVal;
- }
- EFI_STATUS
- MciReceiveResponse (
- IN EFI_MMC_HOST_PROTOCOL *This,
- IN MMC_RESPONSE_TYPE Type,
- IN UINT32* Buffer
- )
- {
- if (Buffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- if ( (Type == MMC_RESPONSE_TYPE_R1)
- || (Type == MMC_RESPONSE_TYPE_R1b)
- || (Type == MMC_RESPONSE_TYPE_R3)
- || (Type == MMC_RESPONSE_TYPE_R6)
- || (Type == MMC_RESPONSE_TYPE_R7))
- {
- Buffer[0] = MmioRead32 (MCI_RESPONSE3_REG);
- } else if (Type == MMC_RESPONSE_TYPE_R2) {
- Buffer[0] = MmioRead32 (MCI_RESPONSE0_REG);
- Buffer[1] = MmioRead32 (MCI_RESPONSE1_REG);
- Buffer[2] = MmioRead32 (MCI_RESPONSE2_REG);
- Buffer[3] = MmioRead32 (MCI_RESPONSE3_REG);
- }
- return EFI_SUCCESS;
- }
- EFI_STATUS
- MciReadBlockData (
- IN EFI_MMC_HOST_PROTOCOL *This,
- IN EFI_LBA Lba,
- IN UINTN Length,
- IN UINT32* Buffer
- )
- {
- UINTN Loop;
- UINTN Finish;
- UINTN Status;
- EFI_STATUS RetVal;
- UINTN DataCtrlReg;
- EFI_TPL Tpl;
- RetVal = EFI_SUCCESS;
- // Read data from the RX FIFO
- Loop = 0;
- if (Length < MMCI0_BLOCKLEN) {
- Finish = Length / 4;
- } else {
- Finish = MMCI0_BLOCKLEN / 4;
- }
- // Raise the TPL at the highest level to disable Interrupts.
- Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
- do {
- // Read the Status flags
- Status = MmioRead32 (MCI_STATUS_REG);
- // Do eight reads if possible else a single read
- if (Status & MCI_STATUS_CMD_RXFIFOHALFFULL) {
- Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
- Loop++;
- Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
- Loop++;
- Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
- Loop++;
- Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
- Loop++;
- Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
- Loop++;
- Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
- Loop++;
- Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
- Loop++;
- Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
- Loop++;
- } else if (Status & MCI_STATUS_CMD_RXDATAAVAILBL) {
- Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
- Loop++;
- } else {
- //Check for error conditions and timeouts
- if (Status & MCI_STATUS_CMD_DATATIMEOUT) {
- DEBUG ((EFI_D_ERROR, "MciReadBlockData(): TIMEOUT! Response:0x%X Status:0x%x\n", MmioRead32 (MCI_RESPONSE0_REG), Status));
- RetVal = EFI_TIMEOUT;
- break;
- } else if (Status & MCI_STATUS_CMD_DATACRCFAIL) {
- DEBUG ((EFI_D_ERROR, "MciReadBlockData(): CRC Error! Response:0x%X Status:0x%x\n", MmioRead32 (MCI_RESPONSE0_REG), Status));
- RetVal = EFI_CRC_ERROR;
- break;
- } else if (Status & MCI_STATUS_CMD_START_BIT_ERROR) {
- DEBUG ((EFI_D_ERROR, "MciReadBlockData(): Start-bit Error! Response:0x%X Status:0x%x\n", MmioRead32 (MCI_RESPONSE0_REG), Status));
- RetVal = EFI_NO_RESPONSE;
- break;
- }
- }
- //clear RX over run flag
- if(Status & MCI_STATUS_CMD_RXOVERRUN) {
- MmioWrite32(MCI_CLEAR_STATUS_REG, MCI_STATUS_CMD_RXOVERRUN);
- }
- } while ((Loop < Finish));
- // Restore Tpl
- gBS->RestoreTPL (Tpl);
- // Clear Status flags
- MmioWrite32 (MCI_CLEAR_STATUS_REG, MCI_CLR_ALL_STATUS);
- //Disable Data path
- DataCtrlReg = MmioRead32 (MCI_DATA_CTL_REG);
- MmioWrite32 (MCI_DATA_CTL_REG, (DataCtrlReg & MCI_DATACTL_DISABLE_MASK));
- return RetVal;
- }
- EFI_STATUS
- MciWriteBlockData (
- IN EFI_MMC_HOST_PROTOCOL *This,
- IN EFI_LBA Lba,
- IN UINTN Length,
- IN UINT32* Buffer
- )
- {
- UINTN Loop;
- UINTN Finish;
- UINTN Timer;
- UINTN Status;
- EFI_STATUS RetVal;
- UINTN DataCtrlReg;
- EFI_TPL Tpl;
- RetVal = EFI_SUCCESS;
- // Write the data to the TX FIFO
- Loop = 0;
- Finish = MMCI0_BLOCKLEN / 4;
- Timer = MMCI0_TIMEOUT * 100;
- // Raise the TPL at the highest level to disable Interrupts.
- Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
- do {
- // Read the Status flags
- Status = MmioRead32 (MCI_STATUS_REG);
- // Do eight writes if possible else a single write
- if (Status & MCI_STATUS_CMD_TXFIFOHALFEMPTY) {
- MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
- Loop++;
- MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
- Loop++;
- MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
- Loop++;
- MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
- Loop++;
- MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
- Loop++;
- MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
- Loop++;
- MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
- Loop++;
- MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
- Loop++;
- } else if (!(Status & MCI_STATUS_CMD_TXFIFOFULL)) {
- MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
- Loop++;
- } else {
- // Check for error conditions and timeouts
- if (Status & MCI_STATUS_CMD_DATATIMEOUT) {
- DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): TIMEOUT! Response:0x%X Status:0x%x\n", MmioRead32 (MCI_RESPONSE0_REG), Status));
- RetVal = EFI_TIMEOUT;
- goto Exit;
- } else if (Status & MCI_STATUS_CMD_DATACRCFAIL) {
- DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): CRC Error! Response:0x%X Status:0x%x\n", MmioRead32 (MCI_RESPONSE0_REG), Status));
- RetVal = EFI_CRC_ERROR;
- goto Exit;
- } else if (Status & MCI_STATUS_CMD_TX_UNDERRUN) {
- DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): TX buffer Underrun! Response:0x%X Status:0x%x, Number of bytes written 0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status, Loop));
- RetVal = EFI_BUFFER_TOO_SMALL;
- ASSERT(0);
- goto Exit;
- }
- }
- } while (Loop < Finish);
- // Restore Tpl
- gBS->RestoreTPL (Tpl);
- // Wait for FIFO to drain
- Timer = MMCI0_TIMEOUT * 60;
- Status = MmioRead32 (MCI_STATUS_REG);
- #ifndef USE_STREAM
- // Single block
- while (((Status & MCI_STATUS_TXDONE) != MCI_STATUS_TXDONE) && Timer) {
- #else
- // Stream
- while (((Status & MCI_STATUS_CMD_DATAEND) != MCI_STATUS_CMD_DATAEND) && Timer) {
- #endif
- NanoSecondDelay(10);
- Status = MmioRead32 (MCI_STATUS_REG);
- Timer--;
- }
- // Clear Status flags
- MmioWrite32 (MCI_CLEAR_STATUS_REG, MCI_CLR_ALL_STATUS);
- if (Timer == 0) {
- DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): Data End timeout Number of words written 0x%x\n", Loop));
- RetVal = EFI_TIMEOUT;
- }
- Exit:
- // Disable Data path
- DataCtrlReg = MmioRead32 (MCI_DATA_CTL_REG);
- MmioWrite32 (MCI_DATA_CTL_REG, (DataCtrlReg & MCI_DATACTL_DISABLE_MASK));
- return RetVal;
- }
- EFI_STATUS
- MciNotifyState (
- IN EFI_MMC_HOST_PROTOCOL *This,
- IN MMC_STATE State
- )
- {
- UINT32 Data32;
- switch (State) {
- case MmcInvalidState:
- ASSERT (0);
- break;
- case MmcHwInitializationState:
- // If device already turn on then restart it
- Data32 = MmioRead32 (MCI_POWER_CONTROL_REG);
- if ((Data32 & 0x2) == MCI_POWER_UP) {
- MCI_TRACE ("MciNotifyState(MmcHwInitializationState): TurnOff MCI");
- // Turn off
- MmioWrite32 (MCI_CLOCK_CONTROL_REG, 0);
- MmioWrite32 (MCI_POWER_CONTROL_REG, 0);
- MicroSecondDelay (100);
- }
- MCI_TRACE ("MciNotifyState(MmcHwInitializationState): TurnOn MCI");
- // Setup clock
- // - 0x1D = 29 => should be the clock divider to be less than 400kHz at MCLK = 24Mhz
- MmioWrite32 (MCI_CLOCK_CONTROL_REG, 0x1D | MCI_CLOCK_ENABLE | MCI_CLOCK_POWERSAVE);
- // Set the voltage
- MmioWrite32 (MCI_POWER_CONTROL_REG, MCI_POWER_OPENDRAIN | (15<<2));
- MmioWrite32 (MCI_POWER_CONTROL_REG, MCI_POWER_ROD | MCI_POWER_OPENDRAIN | (15<<2) | MCI_POWER_UP);
- MicroSecondDelay (10);
- MmioWrite32 (MCI_POWER_CONTROL_REG, MCI_POWER_ROD | MCI_POWER_OPENDRAIN | (15<<2) | MCI_POWER_ON);
- MicroSecondDelay (100);
- // Set Data Length & Data Timer
- MmioWrite32 (MCI_DATA_TIMER_REG, 0xFFFFF);
- MmioWrite32 (MCI_DATA_LENGTH_REG, 8);
- ASSERT ((MmioRead32 (MCI_POWER_CONTROL_REG) & 0x3) == MCI_POWER_ON);
- break;
- case MmcIdleState:
- MCI_TRACE ("MciNotifyState(MmcIdleState)");
- break;
- case MmcReadyState:
- MCI_TRACE ("MciNotifyState(MmcReadyState)");
- break;
- case MmcIdentificationState:
- MCI_TRACE ("MciNotifyState (MmcIdentificationState)");
- break;
- case MmcStandByState:{
- volatile UINT32 PwrCtrlReg;
- MCI_TRACE ("MciNotifyState (MmcStandByState)");
- // Enable MCICMD push-pull drive
- PwrCtrlReg = MmioRead32 (MCI_POWER_CONTROL_REG);
- //Disable Open Drain output
- PwrCtrlReg &= ~ (MCI_POWER_OPENDRAIN);
- MmioWrite32 (MCI_POWER_CONTROL_REG, PwrCtrlReg);
- // Set MMCI0 clock to 4MHz (24MHz may be possible with cache enabled)
- //
- // Note: Increasing clock speed causes TX FIFO under-run errors.
- // So careful when optimising this driver for higher performance.
- //
- MmioWrite32(MCI_CLOCK_CONTROL_REG,0x02 | MCI_CLOCK_ENABLE | MCI_CLOCK_POWERSAVE);
- // Set MMCI0 clock to 24MHz (by bypassing the divider)
- //MmioWrite32(MCI_CLOCK_CONTROL_REG,MCI_CLOCK_BYPASS | MCI_CLOCK_ENABLE);
- break;
- }
- case MmcTransferState:
- //MCI_TRACE ("MciNotifyState(MmcTransferState)");
- break;
- case MmcSendingDataState:
- MCI_TRACE ("MciNotifyState(MmcSendingDataState)");
- break;
- case MmcReceiveDataState:
- MCI_TRACE ("MciNotifyState(MmcReceiveDataState)");
- break;
- case MmcProgrammingState:
- MCI_TRACE ("MciNotifyState(MmcProgrammingState)");
- break;
- case MmcDisconnectState:
- MCI_TRACE ("MciNotifyState(MmcDisconnectState)");
- break;
- default:
- ASSERT (0);
- }
- return EFI_SUCCESS;
- }
- EFI_GUID mPL180MciDevicePathGuid = EFI_CALLER_ID_GUID;
- EFI_STATUS
- MciBuildDevicePath (
- IN EFI_MMC_HOST_PROTOCOL *This,
- IN EFI_DEVICE_PATH_PROTOCOL **DevicePath
- )
- {
- EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode;
- NewDevicePathNode = CreateDeviceNode (HARDWARE_DEVICE_PATH, HW_VENDOR_DP, sizeof (VENDOR_DEVICE_PATH));
- CopyGuid (& ((VENDOR_DEVICE_PATH*)NewDevicePathNode)->Guid, &mPL180MciDevicePathGuid);
- *DevicePath = NewDevicePathNode;
- return EFI_SUCCESS;
- }
- EFI_MMC_HOST_PROTOCOL gMciHost = {
- MMC_HOST_PROTOCOL_REVISION,
- MciIsCardPresent,
- MciIsReadOnly,
- MciBuildDevicePath,
- MciNotifyState,
- MciSendCommand,
- MciReceiveResponse,
- MciReadBlockData,
- MciWriteBlockData
- };
- EFI_STATUS
- PL180MciDxeInitialize (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- EFI_STATUS Status;
- EFI_HANDLE Handle;
- DEBUG ((EFI_D_WARN, "Probing ID registers at 0x%lx for a PL180\n",
- MCI_PERIPH_ID_REG0));
- // Check if this is a PL180
- if (MmioRead8 (MCI_PERIPH_ID_REG0) != MCI_PERIPH_ID0 ||
- MmioRead8 (MCI_PERIPH_ID_REG1) != MCI_PERIPH_ID1 ||
- MmioRead8 (MCI_PERIPH_ID_REG2) != MCI_PERIPH_ID2 ||
- MmioRead8 (MCI_PCELL_ID_REG0) != MCI_PCELL_ID0 ||
- MmioRead8 (MCI_PCELL_ID_REG1) != MCI_PCELL_ID1 ||
- MmioRead8 (MCI_PCELL_ID_REG2) != MCI_PCELL_ID2 ||
- MmioRead8 (MCI_PCELL_ID_REG3) != MCI_PCELL_ID3) {
- DEBUG ((EFI_D_WARN, "Probing ID registers at 0x%lx for a PL180"
- " failed\n", MCI_PERIPH_ID_REG0));
- return EFI_NOT_FOUND;
- }
- Handle = NULL;
- MCI_TRACE ("PL180MciDxeInitialize()");
- //Publish Component Name, BlockIO protocol interfaces
- Status = gBS->InstallMultipleProtocolInterfaces (
- &Handle,
- &gEfiMmcHostProtocolGuid, &gMciHost,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
- return EFI_SUCCESS;
- }
|