aboutsummaryrefslogtreecommitdiffstats
path: root/Drivers/Mmc/DwSdDxe/DwSdDxe.c
diff options
context:
space:
mode:
Diffstat (limited to 'Drivers/Mmc/DwSdDxe/DwSdDxe.c')
-rw-r--r--Drivers/Mmc/DwSdDxe/DwSdDxe.c756
1 files changed, 0 insertions, 756 deletions
diff --git a/Drivers/Mmc/DwSdDxe/DwSdDxe.c b/Drivers/Mmc/DwSdDxe/DwSdDxe.c
deleted file mode 100644
index cbe6b77..0000000
--- a/Drivers/Mmc/DwSdDxe/DwSdDxe.c
+++ /dev/null
@@ -1,756 +0,0 @@
-/** @file
- This file implement the MMC Host Protocol for the DesignWare SD.
-
- Copyright (c) 2014-2016, Linaro Limited. All rights reserved.
- Copyright (c) 2014-2016, Hisilicon Limited. All rights reserved.
-
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include <Library/BaseMemoryLib.h>
-#include <Library/CacheMaintenanceLib.h>
-#include <Library/DebugLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/IoLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/PcdLib.h>
-#include <Library/TimerLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiLib.h>
-#include <Protocol/MmcHost.h>
-
-#include <Library/PrintLib.h>
-#include <Library/SerialPortLib.h>
-
-#include "DwSd.h"
-
-#define DWSD_DESC_PAGE 1
-#define DWSD_BLOCK_SIZE 512
-#define DWSD_DMA_BUF_SIZE (512 * 8)
-
-#define DWSD_DMA_THRESHOLD 16
-
-#define MAX_IDLE_LOOPS 1000000
-
-typedef struct {
- UINT32 Des0;
- UINT32 Des1;
- UINT32 Des2;
- UINT32 Des3;
-} DWSD_IDMAC_DESCRIPTOR;
-
-EFI_MMC_HOST_PROTOCOL *gpMmcHost;
-DWSD_IDMAC_DESCRIPTOR *gpIdmacDesc;
-EFI_GUID mDwSdDevicePathGuid = EFI_CALLER_ID_GUID;
-STATIC UINT32 mDwSdCommand;
-STATIC UINT32 mDwSdArgument;
-
-EFI_STATUS
-DwSdSendCommand (
- IN EFI_MMC_HOST_PROTOCOL *This,
- IN MMC_CMD MmcCmd,
- IN UINT32 Argument
- );
-EFI_STATUS
-DwSdReceiveResponse (
- IN EFI_MMC_HOST_PROTOCOL *This,
- IN MMC_RESPONSE_TYPE Type,
- IN UINT32* Buffer
- );
-
-EFI_STATUS
-DwSdReadBlockData (
- IN EFI_MMC_HOST_PROTOCOL *This,
- IN EFI_LBA Lba,
- IN UINTN Length,
- IN UINT32* Buffer
- );
-
-BOOLEAN
-DwSdIsPowerOn (
- VOID
- )
-{
- return TRUE;
-}
-
-EFI_STATUS
-DwSdInitialize (
- VOID
- )
-{
- DEBUG ((EFI_D_BLKIO, "DwSdInitialize()"));
- return EFI_SUCCESS;
-}
-
-BOOLEAN
-DwSdIsCardPresent (
- IN EFI_MMC_HOST_PROTOCOL *This
- )
-{
- UINT32 Value;
-
- /*
- * FIXME
- * At first, reading GPIO pin shouldn't exist in SD driver. We need to
- * add some callbacks to handle settings for hardware platform.
- * In the second, reading GPIO pin should be based on GPIO driver. Now
- * GPIO driver could only be used for one PL061 gpio controller. And it's
- * used to detect jumper setting. As a workaround, we have to read the gpio
- * register instead at here.
- *
- */
- Value = MmioRead32 (0xf8012000 + (1 << 2));
- if (Value)
- return FALSE;
- return TRUE;
-}
-
-BOOLEAN
-DwSdIsReadOnly (
- IN EFI_MMC_HOST_PROTOCOL *This
- )
-{
- /* FIXME */
- return FALSE;
-}
-
-EFI_STATUS
-DwSdBuildDevicePath (
- 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, &mDwSdDevicePathGuid);
-
- *DevicePath = NewDevicePathNode;
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-DwSdUpdateClock (
- VOID
- )
-{
- UINT32 Data;
-
- /* CMD_UPDATE_CLK */
- Data = BIT_CMD_WAIT_PRVDATA_COMPLETE | BIT_CMD_UPDATE_CLOCK_ONLY |
- BIT_CMD_START;
- MmioWrite32 (DWSD_CMD, Data);
- while (1) {
- Data = MmioRead32 (DWSD_CMD);
- if (!(Data & CMD_START_BIT))
- break;
- Data = MmioRead32 (DWSD_RINTSTS);
- if (Data & DWSD_INT_HLE)
- {
- Print (L"failed to update mmc clock frequency\n");
- return EFI_DEVICE_ERROR;
- }
- }
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-DwSdSetClock (
- IN UINTN ClockFreq
- )
-{
- UINT32 Divider, Rate, Data, Count;
- EFI_STATUS Status;
- BOOLEAN Found = FALSE;
-
- for (Divider = 1; Divider < 256; Divider++) {
- Rate = PcdGet32 (PcdDwSdDxeClockFrequencyInHz);
- if ((Rate / (2 * Divider)) <= ClockFreq) {
- Found = TRUE;
- break;
- }
- }
- if (Found == FALSE)
- return EFI_NOT_FOUND;
-
- // Wait until MMC is idle
- Count = 0;
- do {
- Data = MmioRead32 (DWSD_STATUS);
- if (Count++ > MAX_IDLE_LOOPS)
- break;
- } while (Data & DWSD_STS_DATA_BUSY);
-
- // Disable MMC clock first
- MmioWrite32 (DWSD_CLKENA, 0);
- Status = DwSdUpdateClock ();
- ASSERT (!EFI_ERROR (Status));
-
- MmioWrite32 (DWSD_CLKDIV, Divider);
- Status = DwSdUpdateClock ();
- ASSERT (!EFI_ERROR (Status));
-
- // Enable MMC clock
- MmioWrite32 (DWSD_CLKENA, 1);
- MmioWrite32 (DWSD_CLKSRC, 0);
- Status = DwSdUpdateClock ();
- ASSERT (!EFI_ERROR (Status));
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-DwSdNotifyState (
- IN EFI_MMC_HOST_PROTOCOL *This,
- IN MMC_STATE State
- )
-{
- UINT32 Data;
- EFI_STATUS Status;
-
- switch (State) {
- case MmcInvalidState:
- ASSERT (0);
- break;
- case MmcHwInitializationState:
- MmioWrite32 (DWSD_PWREN, 1);
-
- // If device already turn on then restart it
- Data = DWSD_CTRL_RESET_ALL;
- MmioWrite32 (DWSD_CTRL, Data);
- do {
- // Wait until reset operation finished
- Data = MmioRead32 (DWSD_CTRL);
- } while (Data & DWSD_CTRL_RESET_ALL);
-
- MmioWrite32 (DWSD_RINTSTS, ~0);
- MmioWrite32 (DWSD_INTMASK, 0);
- MmioWrite32 (DWSD_TMOUT, ~0);
- MmioWrite32 (DWSD_IDINTEN, 0);
- MmioWrite32 (DWSD_BMOD, DWSD_IDMAC_SWRESET);
-
- MmioWrite32 (DWSD_BLKSIZ, DWSD_BLOCK_SIZE);
- do {
- Data = MmioRead32 (DWSD_BMOD);
- } while (Data & DWSD_IDMAC_SWRESET);
-
-
- Data = DWSD_DMA_BURST_SIZE(2) | DWSD_FIFO_TWMARK(8) | DWSD_FIFO_RWMARK(7) | (2 << 28);
- MmioWrite32 (DWSD_FIFOTH, Data);
- Data = DWSD_CARD_RD_THR(512) | DWSD_CARD_RD_THR_EN;
- MmioWrite32 (DWSD_CARDTHRCTL, Data);
-
- // Set Data Length & Data Timer
- MmioWrite32 (DWSD_CTYPE, 0);
- MmioWrite32 (DWSD_DEBNCE, 0x00ffffff);
-
- // Setup clock that could not be higher than 400KHz.
- Status = DwSdSetClock (400000);
- ASSERT (!EFI_ERROR (Status));
- MicroSecondDelay (100);
-
- break;
- case MmcIdleState:
- break;
- case MmcReadyState:
- break;
- case MmcIdentificationState:
- break;
- case MmcStandByState:
- break;
- case MmcTransferState:
- break;
- case MmcSendingDataState:
- break;
- case MmcReceiveDataState:
- break;
- case MmcProgrammingState:
- break;
- case MmcDisconnectState:
- break;
- default:
- ASSERT (0);
- }
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-SendCommand (
- IN MMC_CMD MmcCmd,
- IN UINT32 Argument
- )
-{
- UINT32 Data, ErrMask, Count;
-
- MmioWrite32 (DWSD_RINTSTS, ~0);
- MmioWrite32 (DWSD_CMDARG, Argument);
- MicroSecondDelay(500);
- // Wait until MMC is idle
- Count = 0;
- do {
- Data = MmioRead32 (DWSD_STATUS);
- if (Count++ > MAX_IDLE_LOOPS)
- break;
- } while (Data & DWSD_STS_DATA_BUSY);
-
- MmioWrite32 (DWSD_CMD, MmcCmd);
-
- ErrMask = DWSD_INT_EBE | DWSD_INT_HLE | DWSD_INT_RTO |
- DWSD_INT_RCRC | DWSD_INT_RE;
- ErrMask |= DWSD_INT_DCRC | DWSD_INT_DRT | DWSD_INT_SBE;
- do {
- MicroSecondDelay(500);
- Data = MmioRead32 (DWSD_RINTSTS);
-
- if (Data & ErrMask) {
- DEBUG ((EFI_D_ERROR, "Data:%x, ErrMask:%x, TBBCNT:%x, TCBCNT:%x, BYTCNT:%x, BLKSIZ:%x\n", Data, ErrMask, MmioRead32 (DWSD_TBBCNT), MmioRead32 (DWSD_TCBCNT), MmioRead32 (DWSD_BYTCNT), MmioRead32 (DWSD_BLKSIZ)));
- return EFI_DEVICE_ERROR;
- }
- if (Data & DWSD_INT_DTO) // Transfer Done
- break;
- } while (!(Data & DWSD_INT_CMD_DONE));
- MmcCmd &= 0x3f;
- if (MmcCmd == 17)
- MicroSecondDelay(100);
- else if (MmcCmd != 13)
- MicroSecondDelay(5000);
-
- return EFI_SUCCESS;
-}
-
-UINTN ACmd = 0;
-
-EFI_STATUS
-DwSdSendCommand (
- IN EFI_MMC_HOST_PROTOCOL *This,
- IN MMC_CMD MmcCmd,
- IN UINT32 Argument
- )
-{
- UINT32 Cmd = 0;
- EFI_STATUS Status = EFI_SUCCESS;
- BOOLEAN Pending = FALSE;
- UINT32 Data;
-
- switch (MMC_GET_INDX(MmcCmd)) {
- case MMC_INDX(0):
- //Cmd = BIT_CMD_SEND_INIT;
- Cmd = BIT_CMD_WAIT_PRVDATA_COMPLETE;
- break;
- case MMC_INDX(1):
- Cmd = BIT_CMD_RESPONSE_EXPECT;
- break;
- case MMC_INDX(2):
- Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_LONG_RESPONSE |
- BIT_CMD_CHECK_RESPONSE_CRC | BIT_CMD_WAIT_PRVDATA_COMPLETE;
- break;
- case MMC_INDX(3):
- Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
- BIT_CMD_WAIT_PRVDATA_COMPLETE;
- break;
- case MMC_INDX(6):
- if (!ACmd) {
- Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
- BIT_CMD_DATA_EXPECTED | BIT_CMD_WAIT_PRVDATA_COMPLETE;
- } else {
- Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
- BIT_CMD_WAIT_PRVDATA_COMPLETE;
- }
- if (!ACmd)
- Pending = TRUE;
- break;
- case MMC_INDX(7):
- if (Argument)
- Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
- BIT_CMD_WAIT_PRVDATA_COMPLETE;
- else
- Cmd = 0;
- break;
- case MMC_INDX(8):
- Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
- BIT_CMD_READ |
- BIT_CMD_WAIT_PRVDATA_COMPLETE;
- break;
- case MMC_INDX(9):
- Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
- BIT_CMD_LONG_RESPONSE | BIT_CMD_WAIT_PRVDATA_COMPLETE;
- break;
- case MMC_INDX(12):
- Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
- BIT_CMD_STOP_ABORT_CMD;
- break;
- case MMC_INDX(13):
- Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC;
- break;
- case MMC_INDX(17):
- case MMC_INDX(18):
- Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
- BIT_CMD_DATA_EXPECTED | BIT_CMD_READ |
- BIT_CMD_WAIT_PRVDATA_COMPLETE;
- Pending = TRUE;
- Data = MmioRead32 (DWSD_CTRL);
- Data |= DWSD_CTRL_FIFO_RESET;
- MmioWrite32 (DWSD_CTRL, Data);
- while (MmioRead32 (DWSD_CTRL) & DWSD_CTRL_FIFO_RESET) {
- };
- break;
- case MMC_INDX(24):
- case MMC_INDX(25):
- Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
- BIT_CMD_DATA_EXPECTED | BIT_CMD_WRITE |
- BIT_CMD_WAIT_PRVDATA_COMPLETE;
- Pending = TRUE;
- break;
- case MMC_INDX(30):
- Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
- BIT_CMD_DATA_EXPECTED;
- break;
- case MMC_INDX(41):
- Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_WAIT_PRVDATA_COMPLETE;
- break;
- case MMC_INDX(51):
- Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC |
- BIT_CMD_DATA_EXPECTED | BIT_CMD_READ |
- BIT_CMD_WAIT_PRVDATA_COMPLETE;
- Pending = TRUE;
- break;
- case MMC_INDX(55):
- Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC;
- ACmd = 1;
- break;
- default:
- Cmd = BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC;
- break;
- }
-
- Cmd |= MMC_GET_INDX(MmcCmd) | BIT_CMD_USE_HOLD_REG | BIT_CMD_START;
- if (Pending) {
- mDwSdCommand = Cmd;
- mDwSdArgument = Argument;
- } else {
- mDwSdCommand = 0;
- mDwSdArgument = 0;
- Status = SendCommand (Cmd, Argument);
- }
- /* Clear ACMD */
- if (MMC_GET_INDX(MmcCmd) != MMC_INDX(55))
- ACmd = 0;
- return Status;
-}
-
-EFI_STATUS
-DwSdReceiveResponse (
- 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 (DWSD_RESP0);
- } else if (Type == MMC_RESPONSE_TYPE_R2) {
- Buffer[0] = MmioRead32 (DWSD_RESP0);
- Buffer[1] = MmioRead32 (DWSD_RESP1);
- Buffer[2] = MmioRead32 (DWSD_RESP2);
- Buffer[3] = MmioRead32 (DWSD_RESP3);
- }
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-PrepareDmaData (
- IN DWSD_IDMAC_DESCRIPTOR* IdmacDesc,
- IN UINTN Length,
- IN UINT32* Buffer
- )
-{
- UINTN Cnt, Idx, LastIdx, Blks;
-
- if (Length % 4) {
- DEBUG ((EFI_D_ERROR, "Length isn't aligned with 4\n"));
- return EFI_BAD_BUFFER_SIZE;
- }
- if (Length < DWSD_DMA_THRESHOLD) {
- return EFI_BUFFER_TOO_SMALL;
- }
- Cnt = (Length + DWSD_DMA_BUF_SIZE - 1) / DWSD_DMA_BUF_SIZE;
- Blks = (Length + DWSD_BLOCK_SIZE - 1 ) / DWSD_BLOCK_SIZE;
- Length = DWSD_BLOCK_SIZE * Blks;
-
- for (Idx = 0; Idx < Cnt; Idx++) {
- (IdmacDesc + Idx)->Des0 = DWSD_IDMAC_DES0_OWN | DWSD_IDMAC_DES0_CH |
- DWSD_IDMAC_DES0_DIC;
- (IdmacDesc + Idx)->Des1 = DWSD_IDMAC_DES1_BS1(DWSD_DMA_BUF_SIZE);
- /* Buffer Address */
- (IdmacDesc + Idx)->Des2 = (UINT32)((UINTN)Buffer + DWSD_DMA_BUF_SIZE * Idx);
- /* Next Descriptor Address */
- (IdmacDesc + Idx)->Des3 = (UINT32)((UINTN)IdmacDesc +
- (sizeof(DWSD_IDMAC_DESCRIPTOR) * (Idx + 1)));
- }
- /* First Descriptor */
- IdmacDesc->Des0 |= DWSD_IDMAC_DES0_FS;
- /* Last Descriptor */
- LastIdx = Cnt - 1;
- (IdmacDesc + LastIdx)->Des0 |= DWSD_IDMAC_DES0_LD;
- (IdmacDesc + LastIdx)->Des0 &= ~(DWSD_IDMAC_DES0_DIC | DWSD_IDMAC_DES0_CH);
- (IdmacDesc + LastIdx)->Des1 = DWSD_IDMAC_DES1_BS1(Length -
- (LastIdx * DWSD_DMA_BUF_SIZE));
- /* Set the Next field of Last Descriptor */
- (IdmacDesc + LastIdx)->Des3 = 0;
- MmioWrite32 (DWSD_DBADDR, (UINT32)((UINTN)IdmacDesc));
-
- return EFI_SUCCESS;
-}
-
-VOID
-StartDma (
- UINTN Length
- )
-{
- UINT32 Data;
-
- Data = MmioRead32 (DWSD_CTRL);
- Data |= DWSD_CTRL_INT_EN | DWSD_CTRL_DMA_EN | DWSD_CTRL_IDMAC_EN;
- MmioWrite32 (DWSD_CTRL, Data);
- Data = MmioRead32 (DWSD_BMOD);
- Data |= DWSD_IDMAC_ENABLE | DWSD_IDMAC_FB;
- MmioWrite32 (DWSD_BMOD, Data);
-
- MmioWrite32 (DWSD_BLKSIZ, DWSD_BLOCK_SIZE);
- MmioWrite32 (DWSD_BYTCNT, Length);
-}
-
-STATIC
-EFI_STATUS
-ReadFifo (
- IN UINTN Length,
- IN UINT32* Buffer
- )
-{
- UINT32 Data, Received, Count;
-
- Received = 0;
- Count = (Length + 3) / 4;
- while (Received < Count) {
- Data = MmioRead32 (DWSD_RINTSTS);
- if (Data & DWSD_INT_CMD_DONE) {
- *(Buffer + Received) = MmioRead32 (DWSD_FIFO_START);
- Received++;
- } else {
- DEBUG ((EFI_D_ERROR, "Received:%d, RINTSTS:%x\n", Received, Data));
- }
- }
- while (1) {
- Data = MmioRead32 (DWSD_RINTSTS);
- if (Data & DWSD_INT_DTO)
- break;
- }
- /* FIXME */
- MicroSecondDelay (1000);
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-DwSdReadBlockData (
- IN EFI_MMC_HOST_PROTOCOL *This,
- IN EFI_LBA Lba,
- IN UINTN Length,
- IN UINT32* Buffer
- )
-{
- EFI_STATUS Status;
- UINT32 DescPages, CountPerPage, Count, Data;
- EFI_TPL Tpl;
-
- Tpl = gBS->RaiseTPL (TPL_NOTIFY);
-
- CountPerPage = EFI_PAGE_SIZE / 16;
- Count = (Length + DWSD_DMA_BUF_SIZE - 1) / DWSD_DMA_BUF_SIZE;
- DescPages = (Count + CountPerPage - 1) / CountPerPage;
-
- InvalidateDataCacheRange (Buffer, Length);
-
- Status = PrepareDmaData (gpIdmacDesc, Length, Buffer);
- if (EFI_ERROR (Status)) {
- if (Status == EFI_BUFFER_TOO_SMALL) {
- Data = MmioRead32 (DWSD_CTRL);
- Data |= DWSD_CTRL_FIFO_RESET;
- MmioWrite32 (DWSD_CTRL, Data);
- while (MmioRead32 (DWSD_CTRL) & DWSD_CTRL_FIFO_RESET) {
- };
-
- Status = SendCommand (mDwSdCommand, mDwSdArgument);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Failed to read data from FIFO, mDwSdCommand:%x, mDwSdArgument:%x, Status:%r\n", mDwSdCommand, mDwSdArgument, Status));
- goto out;
- }
- Status = ReadFifo (Length, Buffer);
- }
- goto out;
- } else {
-
- WriteBackDataCacheRange (gpIdmacDesc, DescPages * EFI_PAGE_SIZE);
- StartDma (Length);
-
- Status = SendCommand (mDwSdCommand, mDwSdArgument);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Failed to read data, mDwSdCommand:%x, mDwSdArgument:%x, Status:%r\n", mDwSdCommand, mDwSdArgument, Status));
- goto out;
- }
-
- /* Wait until data transfer finished */
- while (MmioRead32 (DWSD_TCBCNT) < MmioRead32 (DWSD_BYTCNT)) {
- }
-
- }
-out:
- // Restore Tpl
- gBS->RestoreTPL (Tpl);
- return Status;
-}
-
-EFI_STATUS
-DwSdWriteBlockData (
- IN EFI_MMC_HOST_PROTOCOL *This,
- IN EFI_LBA Lba,
- IN UINTN Length,
- IN UINT32* Buffer
- )
-{
- EFI_STATUS Status;
- UINT32 DescPages, CountPerPage, Count;
- EFI_TPL Tpl;
-
- Tpl = gBS->RaiseTPL (TPL_NOTIFY);
-
- CountPerPage = EFI_PAGE_SIZE / 16;
- Count = (Length + DWSD_DMA_BUF_SIZE - 1) / DWSD_DMA_BUF_SIZE;
- DescPages = (Count + CountPerPage - 1) / CountPerPage;
-
- WriteBackDataCacheRange (Buffer, Length);
-
- Status = PrepareDmaData (gpIdmacDesc, Length, Buffer);
- if (EFI_ERROR (Status))
- goto out;
-
- WriteBackDataCacheRange (gpIdmacDesc, DescPages * EFI_PAGE_SIZE);
- StartDma (Length);
-
- Status = SendCommand (mDwSdCommand, mDwSdArgument);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Failed to write data, mDwSdCommand:%x, mDwSdArgument:%x, Status:%r\n", mDwSdCommand, mDwSdArgument, Status));
- goto out;
- }
-out:
- // Restore Tpl
- gBS->RestoreTPL (Tpl);
- return Status;
-}
-
-EFI_STATUS
-DwSdSetIos (
- IN EFI_MMC_HOST_PROTOCOL *This,
- IN UINT32 BusClockFreq,
- IN UINT32 BusWidth,
- IN UINT32 TimingMode
- )
-{
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 Data;
-
- if (TimingMode != EMMCBACKWARD) {
- Data = MmioRead32 (DWSD_UHSREG);
- switch (TimingMode) {
- case EMMCHS52DDR1V2:
- case EMMCHS52DDR1V8:
- Data |= 1 << 16;
- break;
- case EMMCHS52:
- case EMMCHS26:
- Data &= ~(1 << 16);
- break;
- default:
- return EFI_UNSUPPORTED;
- }
- MmioWrite32 (DWSD_UHSREG, Data);
- }
-
- switch (BusWidth) {
- case 1:
- MmioWrite32 (DWSD_CTYPE, 0);
- break;
- case 4:
- MmioWrite32 (DWSD_CTYPE, 1);
- break;
- case 8:
- MmioWrite32 (DWSD_CTYPE, 1 << 16);
- break;
- default:
- return EFI_UNSUPPORTED;
- }
- if (BusClockFreq) {
- Status = DwSdSetClock (BusClockFreq);
- }
- return Status;
-}
-
-BOOLEAN
-DwSdIsMultiBlock (
- IN EFI_MMC_HOST_PROTOCOL *This
- )
-{
- return TRUE;
-}
-
-EFI_MMC_HOST_PROTOCOL gMciHost = {
- MMC_HOST_PROTOCOL_REVISION,
- DwSdIsCardPresent,
- DwSdIsReadOnly,
- DwSdBuildDevicePath,
- DwSdNotifyState,
- DwSdSendCommand,
- DwSdReceiveResponse,
- DwSdReadBlockData,
- DwSdWriteBlockData,
- DwSdSetIos,
- DwSdIsMultiBlock
-};
-
-EFI_STATUS
-DwSdDxeInitialize (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- EFI_HANDLE Handle;
-
- Handle = NULL;
-
- DEBUG ((EFI_D_BLKIO, "DwSdDxeInitialize()\n"));
-
- //Publish Component Name, BlockIO protocol interfaces
- Status = gBS->InstallMultipleProtocolInterfaces (
- &Handle,
- &gEfiMmcHostProtocolGuid, &gMciHost,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-
- return EFI_SUCCESS;
-}