/** @file
*
*  Copyright (c) 2011-2015, ARM Limited. All rights reserved.
*
*  SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/

#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/TimerLib.h>

#include "Mmc.h"

typedef union {
  UINT32 Raw;
  OCR    Ocr;
} OCR_RESPONSE;

#define MAX_RETRY_COUNT         1000
#define CMD_RETRY_COUNT         20
#define RCA_SHIFT_OFFSET        16
#define EMMC_CARD_SIZE          512
#define EMMC_ECSD_SIZE_OFFSET   53

#define EXTCSD_BUS_WIDTH        183
#define EXTCSD_HS_TIMING        185

#define EMMC_TIMING_BACKWARD    0
#define EMMC_TIMING_HS          1
#define EMMC_TIMING_HS200       2
#define EMMC_TIMING_HS400       3

#define EMMC_BUS_WIDTH_1BIT     0
#define EMMC_BUS_WIDTH_4BIT     1
#define EMMC_BUS_WIDTH_8BIT     2
#define EMMC_BUS_WIDTH_DDR_4BIT 5
#define EMMC_BUS_WIDTH_DDR_8BIT 6

#define EMMC_SWITCH_ERROR       (1 << 7)

#define SD_BUS_WIDTH_1BIT       (1 << 0)
#define SD_BUS_WIDTH_4BIT       (1 << 2)

#define SD_CCC_SWITCH           (1 << 10)

#define DEVICE_STATE(x)         (((x) >> 9) & 0xf)
typedef enum _EMMC_DEVICE_STATE {
  EMMC_IDLE_STATE = 0,
  EMMC_READY_STATE,
  EMMC_IDENT_STATE,
  EMMC_STBY_STATE,
  EMMC_TRAN_STATE,
  EMMC_DATA_STATE,
  EMMC_RCV_STATE,
  EMMC_PRG_STATE,
  EMMC_DIS_STATE,
  EMMC_BTST_STATE,
  EMMC_SLP_STATE
} EMMC_DEVICE_STATE;

UINT32 mEmmcRcaCount = 0;

STATIC
EFI_STATUS
EFIAPI
EmmcGetDeviceState (
  IN  MMC_HOST_INSTANCE    *MmcHostInstance,
  OUT EMMC_DEVICE_STATE    *State
  )
{
  EFI_MMC_HOST_PROTOCOL *Host;
  EFI_STATUS Status;
  UINT32     Data, RCA;

  if (State == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Host = MmcHostInstance->MmcHost;
  RCA = MmcHostInstance->CardInfo.RCA << RCA_SHIFT_OFFSET;
  Status = Host->SendCommand (Host, MMC_CMD13, RCA);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "EmmcGetDeviceState(): Failed to get card status, Status=%r.\n", Status));
    return Status;
  }
  Status = Host->ReceiveResponse (Host, MMC_RESPONSE_TYPE_R1, &Data);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "EmmcGetDeviceState(): Failed to get response of CMD13, Status=%r.\n", Status));
    return Status;
  }
  if (Data & EMMC_SWITCH_ERROR) {
    DEBUG ((EFI_D_ERROR, "EmmcGetDeviceState(): Failed to switch expected mode, Status=%r.\n", Status));
    return EFI_DEVICE_ERROR;
  }
  *State = DEVICE_STATE(Data);
  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
EmmcSetEXTCSD (
  IN MMC_HOST_INSTANCE     *MmcHostInstance,
  UINT32                   ExtCmdIndex,
  UINT32                   Value
  )
{
  EFI_MMC_HOST_PROTOCOL *Host;
  EMMC_DEVICE_STATE     State;
  EFI_STATUS Status;
  UINT32     Argument;

  Host  = MmcHostInstance->MmcHost;
  Argument = EMMC_CMD6_ARG_ACCESS(3) | EMMC_CMD6_ARG_INDEX(ExtCmdIndex) |
             EMMC_CMD6_ARG_VALUE(Value) | EMMC_CMD6_ARG_CMD_SET(1);
  Status = Host->SendCommand (Host, MMC_CMD6, Argument);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "EmmcSetEXTCSD(): Failed to send CMD6, Status=%r.\n", Status));
    return Status;
  }
  // Make sure device exiting prog mode
  do {
    Status = EmmcGetDeviceState (MmcHostInstance, &State);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "EmmcSetEXTCSD(): Failed to get device state, Status=%r.\n", Status));
      return Status;
    }
  } while (State == EMMC_PRG_STATE);
  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
EmmcIdentificationMode (
  IN MMC_HOST_INSTANCE     *MmcHostInstance,
  IN OCR_RESPONSE           Response
  )
{
  EFI_MMC_HOST_PROTOCOL *Host;
  EFI_BLOCK_IO_MEDIA    *Media;
  EFI_STATUS Status;
  EMMC_DEVICE_STATE     State;
  UINT32     RCA;

  Host  = MmcHostInstance->MmcHost;
  Media = MmcHostInstance->BlockIo.Media;

  // Fetch card identity register
  Status = Host->SendCommand (Host, MMC_CMD2, 0);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): Failed to send CMD2, Status=%r.\n", Status));
    return Status;
  }

  Status = Host->ReceiveResponse (Host, MMC_RESPONSE_TYPE_R2, (UINT32 *)&(MmcHostInstance->CardInfo.CIDData));
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): CID retrieval error, Status=%r.\n", Status));
    return Status;
  }

  // Assign a relative address value to the card
  MmcHostInstance->CardInfo.RCA = ++mEmmcRcaCount; // TODO: might need a more sophisticated way of doing this
  RCA = MmcHostInstance->CardInfo.RCA << RCA_SHIFT_OFFSET;
  Status = Host->SendCommand (Host, MMC_CMD3, RCA);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): RCA set error, Status=%r.\n", Status));
    return Status;
  }

  // Fetch card specific data
  Status = Host->SendCommand (Host, MMC_CMD9, RCA);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): Failed to send CMD9, Status=%r.\n", Status));
    return Status;
  }

  Status = Host->ReceiveResponse (Host, MMC_RESPONSE_TYPE_R2, (UINT32 *)&(MmcHostInstance->CardInfo.CSDData));
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): CSD retrieval error, Status=%r.\n", Status));
    return Status;
  }

  // Select the card
  Status = Host->SendCommand (Host, MMC_CMD7, RCA);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): Card selection error, Status=%r.\n", Status));
  }

  if (MMC_HOST_HAS_SETIOS(Host)) {
    // Set 1-bit bus width
    Status = Host->SetIos (Host, 0, 1, EMMCBACKWARD);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): Set 1-bit bus width error, Status=%r.\n", Status));
      return Status;
    }

    // Set 1-bit bus width for EXTCSD
    Status = EmmcSetEXTCSD (MmcHostInstance, EXTCSD_BUS_WIDTH, EMMC_BUS_WIDTH_1BIT);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): Set extcsd bus width error, Status=%r.\n", Status));
      return Status;
    }
  }

  // Fetch ECSD
  MmcHostInstance->CardInfo.ECSDData = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ECSD)));
  if (MmcHostInstance->CardInfo.ECSDData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  Status = Host->SendCommand (Host, MMC_CMD8, 0);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): ECSD fetch error, Status=%r.\n", Status));
  }

  Status = Host->ReadBlockData (Host, 0, 512, (UINT32 *)MmcHostInstance->CardInfo.ECSDData);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): ECSD read error, Status=%r.\n", Status));
    goto FreePageExit;
  }

  // Make sure device exiting data mode
  do {
    Status = EmmcGetDeviceState (MmcHostInstance, &State);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): Failed to get device state, Status=%r.\n", Status));
      goto FreePageExit;
    }
  } while (State == EMMC_DATA_STATE);

  // Set up media
  Media->BlockSize = EMMC_CARD_SIZE; // 512-byte support is mandatory for eMMC cards
  Media->MediaId = MmcHostInstance->CardInfo.CIDData.PSN;
  Media->ReadOnly = MmcHostInstance->CardInfo.CSDData.PERM_WRITE_PROTECT;
  Media->LogicalBlocksPerPhysicalBlock = 1;
  Media->IoAlign = 4;
  // Compute last block using bits [215:212] of the ECSD
  Media->LastBlock = MmcHostInstance->CardInfo.ECSDData->SECTOR_COUNT - 1; // eMMC isn't supposed to report this for
  // Cards <2GB in size, but the model does.

  // Setup card type
  MmcHostInstance->CardInfo.CardType = EMMC_CARD;
  return EFI_SUCCESS;

FreePageExit:
  FreePages (MmcHostInstance->CardInfo.ECSDData, EFI_SIZE_TO_PAGES (sizeof (ECSD)));
  return Status;
}

STATIC
EFI_STATUS
InitializeEmmcDevice (
  IN  MMC_HOST_INSTANCE   *MmcHostInstance
  )
{
  EFI_MMC_HOST_PROTOCOL *Host;
  EFI_STATUS Status = EFI_SUCCESS;
  ECSD       *ECSDData;
  UINT32     BusClockFreq, Idx, BusMode;
  UINT32     TimingMode[4] = {EMMCHS52DDR1V2, EMMCHS52DDR1V8, EMMCHS52, EMMCHS26};

  Host  = MmcHostInstance->MmcHost;
  ECSDData = MmcHostInstance->CardInfo.ECSDData;
  if (ECSDData->DEVICE_TYPE == EMMCBACKWARD)
    return EFI_SUCCESS;

  if (!MMC_HOST_HAS_SETIOS(Host)) {
    return EFI_SUCCESS;
  }
  Status = EmmcSetEXTCSD (MmcHostInstance, EXTCSD_HS_TIMING, EMMC_TIMING_HS);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "InitializeEmmcDevice(): Failed to switch high speed mode, Status:%r.\n", Status));
    return Status;
  }

  for (Idx = 0; Idx < 4; Idx++) {
    switch (TimingMode[Idx]) {
    case EMMCHS52DDR1V2:
    case EMMCHS52DDR1V8:
    case EMMCHS52:
      BusClockFreq = 52000000;
      break;
    case EMMCHS26:
      BusClockFreq = 26000000;
      break;
    default:
      return EFI_UNSUPPORTED;
    }
    Status = Host->SetIos (Host, BusClockFreq, 8, TimingMode[Idx]);
    if (!EFI_ERROR (Status)) {
      switch (TimingMode[Idx]) {
      case EMMCHS52DDR1V2:
      case EMMCHS52DDR1V8:
        BusMode = EMMC_BUS_WIDTH_DDR_8BIT;
        break;
      case EMMCHS52:
      case EMMCHS26:
        BusMode = EMMC_BUS_WIDTH_8BIT;
        break;
      default:
        return EFI_UNSUPPORTED;
      }
      Status = EmmcSetEXTCSD (MmcHostInstance, EXTCSD_BUS_WIDTH, BusMode);
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "InitializeEmmcDevice(): Failed to set EXTCSD bus width, Status:%r\n", Status));
      }
      return Status;
    }
  }
  return Status;
}

STATIC
UINT32
CreateSwitchCmdArgument (
  IN  UINT32 Mode,
  IN  UINT8  Group,
  IN  UINT8  Value
  )
{
  UINT32 Argument;

  Argument = Mode << 31 | 0x00FFFFFF;
  Argument &= ~(0xF << (Group * 4));
  Argument |= Value << (Group * 4);

  return Argument;
}

STATIC
EFI_STATUS
InitializeSdMmcDevice (
  IN  MMC_HOST_INSTANCE   *MmcHostInstance
  )
{
  UINT32        CmdArg;
  UINT32        Response[4];
  UINT32        Buffer[128];
  UINT32        Speed;
  UINTN         BlockSize;
  UINTN         CardSize;
  UINTN         NumBlocks;
  BOOLEAN       CccSwitch;
  SCR           Scr;
  EFI_STATUS    Status;
  EFI_MMC_HOST_PROTOCOL     *MmcHost;

  Speed = SD_DEFAULT_SPEED;
  MmcHost = MmcHostInstance->MmcHost;

  // Send a command to get Card specific data
  CmdArg = MmcHostInstance->CardInfo.RCA << 16;
  Status = MmcHost->SendCommand (MmcHost, MMC_CMD9, CmdArg);
  if (EFI_ERROR (Status)) {
    DEBUG((EFI_D_ERROR, "InitializeSdMmcDevice(MMC_CMD9): Error, Status=%r\n", Status));
    return Status;
  }

  // Read Response
  Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_CSD, Response);
  if (EFI_ERROR (Status)) {
    DEBUG((EFI_D_ERROR, "InitializeSdMmcDevice(): Failed to receive CSD, Status=%r\n", Status));
    return Status;
  }
  PrintCSD (Response);
  if (MMC_CSD_GET_CCC(Response) & SD_CCC_SWITCH) {
    CccSwitch = TRUE;
  } else {
    CccSwitch = FALSE;
  }

  if (MmcHostInstance->CardInfo.CardType == SD_CARD_2_HIGH) {
    CardSize = HC_MMC_CSD_GET_DEVICESIZE (Response);
    NumBlocks = ((CardSize + 1) * 1024);
    BlockSize = 1 << MMC_CSD_GET_READBLLEN (Response);
  } else {
    CardSize = MMC_CSD_GET_DEVICESIZE (Response);
    NumBlocks = (CardSize + 1) * (1 << (MMC_CSD_GET_DEVICESIZEMULT (Response) + 2));
    BlockSize = 1 << MMC_CSD_GET_READBLLEN (Response);
  }

  // For >=2G card, BlockSize may be 1K, but the transfer size is 512 bytes.
  if (BlockSize > 512) {
    NumBlocks = MultU64x32 (NumBlocks, BlockSize / 512);
    BlockSize = 512;
  }

  MmcHostInstance->BlockIo.Media->LastBlock    = (NumBlocks - 1);
  MmcHostInstance->BlockIo.Media->BlockSize    = BlockSize;
  MmcHostInstance->BlockIo.Media->ReadOnly     = MmcHost->IsReadOnly (MmcHost);
  MmcHostInstance->BlockIo.Media->MediaPresent = TRUE;
  MmcHostInstance->BlockIo.Media->MediaId++;

  CmdArg = MmcHostInstance->CardInfo.RCA << 16;
  Status = MmcHost->SendCommand (MmcHost, MMC_CMD7, CmdArg);
  if (EFI_ERROR (Status)) {
    DEBUG((EFI_D_ERROR, "InitializeSdMmcDevice(MMC_CMD7): Error and Status = %r\n", Status));
    return Status;
  }

  Status = MmcHost->SendCommand (MmcHost, MMC_CMD55, CmdArg);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a (MMC_CMD55): Error and Status = %r\n", __FUNCTION__, Status));
    return Status;
  }
  Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_R1, Response);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a (MMC_CMD55): Error and Status = %r\n", __FUNCTION__, Status));
    return Status;
  }
  if ((Response[0] & MMC_STATUS_APP_CMD) == 0) {
    return EFI_SUCCESS;
  }

  /* SCR */
  Status = MmcHost->SendCommand (MmcHost, MMC_ACMD51, 0);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "%a(MMC_ACMD51): Error and Status = %r\n", __func__, Status));
    return Status;
  } else {
    Status = MmcHost->ReadBlockData (MmcHost, 0, 8, Buffer);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "%a(MMC_ACMD51): ReadBlockData Error and Status = %r\n", __func__, Status));
      return Status;
    }
    CopyMem (&Scr, Buffer, 8);
    if (Scr.SD_SPEC == 2) {
      if (Scr.SD_SPEC3 == 1) {
	if (Scr.SD_SPEC4 == 1) {
          DEBUG ((EFI_D_INFO, "Found SD Card for Spec Version 4.xx\n"));
	} else {
          DEBUG ((EFI_D_INFO, "Found SD Card for Spec Version 3.0x\n"));
	}
      } else {
	if (Scr.SD_SPEC4 == 0) {
          DEBUG ((EFI_D_INFO, "Found SD Card for Spec Version 2.0\n"));
	} else {
	  DEBUG ((EFI_D_ERROR, "Found invalid SD Card\n"));
	}
      }
    } else {
      if ((Scr.SD_SPEC3 == 0) && (Scr.SD_SPEC4 == 0)) {
        if (Scr.SD_SPEC == 1) {
	  DEBUG ((EFI_D_INFO, "Found SD Card for Spec Version 1.10\n"));
	} else {
	  DEBUG ((EFI_D_INFO, "Found SD Card for Spec Version 1.0\n"));
	}
      } else {
        DEBUG ((EFI_D_ERROR, "Found invalid SD Card\n"));
      }
    }
  }
  if (CccSwitch) {
    /* SD Switch, Mode:0, Group:0, Value:0 */
    CmdArg = CreateSwitchCmdArgument(0, 0, 0);
    Status = MmcHost->SendCommand (MmcHost, MMC_CMD6, CmdArg);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "%a (MMC_CMD6): Error and Status = %r\n", __FUNCTION__, Status));
       return Status;
    } else {
      Status = MmcHost->ReadBlockData (MmcHost, 0, SWITCH_CMD_DATA_LENGTH, Buffer);
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "%a (MMC_CMD6): ReadBlockData Error and Status = %r\n", __FUNCTION__, Status));
        return Status;
      }
    }

    if (!(Buffer[3] & SD_HIGH_SPEED_SUPPORTED)) {
      DEBUG ((DEBUG_INFO, "%a : High Speed not supported by Card\n", __FUNCTION__));
    } else {
      Speed = SD_HIGH_SPEED;

      /* SD Switch, Mode:1, Group:0, Value:1 */
      CmdArg = CreateSwitchCmdArgument(1, 0, 1);
      Status = MmcHost->SendCommand (MmcHost, MMC_CMD6, CmdArg);
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "%a (MMC_CMD6): Error and Status = %r\n", __FUNCTION__, Status));
        return Status;
      } else {
        Status = MmcHost->ReadBlockData (MmcHost, 0, SWITCH_CMD_DATA_LENGTH, Buffer);
        if (EFI_ERROR (Status)) {
          DEBUG ((DEBUG_ERROR, "%a (MMC_CMD6): ReadBlockData Error and Status = %r\n", __FUNCTION__, Status));
          return Status;
        }

        if ((Buffer[4] & SWITCH_CMD_SUCCESS_MASK) != 0x01000000) {
          DEBUG((DEBUG_ERROR, "Problem switching SD card into high-speed mode\n"));
          return Status;
        }
      }
    }
  }
  if (Scr.SD_BUS_WIDTHS & SD_BUS_WIDTH_4BIT) {
    CmdArg = MmcHostInstance->CardInfo.RCA << 16;
    Status = MmcHost->SendCommand (MmcHost, MMC_CMD55, CmdArg);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "%a (MMC_CMD55): Error and Status = %r\n", __FUNCTION__, Status));
      return Status;
    }
    /* Width: 4 */
    Status = MmcHost->SendCommand (MmcHost, MMC_CMD6, 2);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "%a (MMC_CMD6): Error and Status = %r\n", __FUNCTION__, Status));
      return Status;
    }
  }
  if (MMC_HOST_HAS_SETIOS(MmcHost)) {
    Status = MmcHost->SetIos (MmcHost, Speed, BUSWIDTH_4, EMMCBACKWARD);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "%a (SetIos): Error and Status = %r\n", __FUNCTION__, Status));
      return Status;
    }
  }
  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
MmcIdentificationMode (
  IN MMC_HOST_INSTANCE     *MmcHostInstance
  )
{
  EFI_STATUS              Status;
  UINT32                  Response[4];
  UINTN                   Timeout;
  UINTN                   CmdArg;
  BOOLEAN                 IsHCS;
  EFI_MMC_HOST_PROTOCOL   *MmcHost;
  OCR_RESPONSE            OcrResponse;

  MmcHost = MmcHostInstance->MmcHost;
  CmdArg = 0;
  IsHCS = FALSE;

  if (MmcHost == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  // We can get into this function if we restart the identification mode
  if (MmcHostInstance->State == MmcHwInitializationState) {
    // Initialize the MMC Host HW
    Status = MmcNotifyState (MmcHostInstance, MmcHwInitializationState);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcHwInitializationState, Status=%r.\n", Status));
      return Status;
    }
  }

  Status = MmcHost->SendCommand (MmcHost, MMC_CMD0, 0);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD0): Error, Status=%r.\n", Status));
    return Status;
  }
  Status = MmcNotifyState (MmcHostInstance, MmcIdleState);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcIdleState, Status=%r.\n", Status));
    return Status;
  }

  // Send CMD1 to get OCR (MMC)
  // This command only valid for MMC and eMMC
  Timeout = MAX_RETRY_COUNT;
  do {
    Status = MmcHost->SendCommand (MmcHost, MMC_CMD1, EMMC_CMD1_CAPACITY_GREATER_THAN_2GB);
    if (EFI_ERROR (Status))
      break;
    Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_OCR, (UINT32 *)&OcrResponse);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive OCR, Status=%r.\n", Status));
      return Status;
    }
    Timeout--;
  } while (!OcrResponse.Ocr.PowerUp && (Timeout > 0));
  if (Status == EFI_SUCCESS) {
    if (!OcrResponse.Ocr.PowerUp) {
      DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD1): Card initialisation failure, Status=%r.\n", Status));
      return EFI_DEVICE_ERROR;
    }
    OcrResponse.Ocr.PowerUp = 0;
    if (OcrResponse.Raw == EMMC_CMD1_CAPACITY_GREATER_THAN_2GB) {
      MmcHostInstance->CardInfo.OCRData.AccessMode = BIT1;
    }
    else {
      MmcHostInstance->CardInfo.OCRData.AccessMode = 0x0;
    }
    // Check whether MMC or eMMC
    if (OcrResponse.Raw == EMMC_CMD1_CAPACITY_GREATER_THAN_2GB ||
        OcrResponse.Raw == EMMC_CMD1_CAPACITY_LESS_THAN_2GB) {
      return EmmcIdentificationMode (MmcHostInstance, OcrResponse);
    }
  }

  // Are we using SDIO ?
  Status = MmcHost->SendCommand (MmcHost, MMC_CMD5, 0);
  if (Status == EFI_SUCCESS) {
    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD5): Error - SDIO not supported, Status=%r.\n", Status));
    return EFI_UNSUPPORTED;
  }

  // Check which kind of card we are using. Ver2.00 or later SD Memory Card (PL180 is SD v1.1)
  CmdArg = (0x0UL << 12 | BIT8 | 0xCEUL << 0);
  Status = MmcHost->SendCommand (MmcHost, MMC_CMD8, CmdArg);
  if (Status == EFI_SUCCESS) {
    DEBUG ((EFI_D_ERROR, "Card is SD2.0 => Supports high capacity\n"));
    IsHCS = TRUE;
    Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_R7, Response);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive response to CMD8, Status=%r.\n", Status));
      return Status;
    }
    PrintResponseR1 (Response[0]);
    // Check if it is valid response
    if (Response[0] != CmdArg) {
      DEBUG ((EFI_D_ERROR, "The Card is not usable\n"));
      return EFI_UNSUPPORTED;
    }
  } else {
    DEBUG ((EFI_D_ERROR, "Not a SD2.0 Card\n"));
  }

  // We need to wait for the MMC or SD card is ready => (gCardInfo.OCRData.PowerUp == 1)
  Timeout = MAX_RETRY_COUNT;
  while (Timeout > 0) {
    // SD Card or MMC Card ? CMD55 indicates to the card that the next command is an application specific command
    Status = MmcHost->SendCommand (MmcHost, MMC_CMD55, 0);
    if (Status == EFI_SUCCESS) {
      DEBUG ((EFI_D_INFO, "Card should be SD\n"));
      if (IsHCS) {
        MmcHostInstance->CardInfo.CardType = SD_CARD_2;
      } else {
        MmcHostInstance->CardInfo.CardType = SD_CARD;
      }

      // Note: The first time CmdArg will be zero
      CmdArg = ((UINTN *) &(MmcHostInstance->CardInfo.OCRData))[0];
      if (IsHCS) {
        CmdArg |= BIT30;
      }
      Status = MmcHost->SendCommand (MmcHost, MMC_ACMD41, CmdArg);
      if (!EFI_ERROR (Status)) {
        Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_OCR, Response);
        if (EFI_ERROR (Status)) {
          DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive OCR, Status=%r.\n", Status));
          return Status;
        }
        ((UINT32 *) &(MmcHostInstance->CardInfo.OCRData))[0] = Response[0];
      }
    } else {
      DEBUG ((EFI_D_INFO, "Card should be MMC\n"));
      MmcHostInstance->CardInfo.CardType = MMC_CARD;

      Status = MmcHost->SendCommand (MmcHost, MMC_CMD1, 0x800000);
      if (!EFI_ERROR (Status)) {
        Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_OCR, Response);
        if (EFI_ERROR (Status)) {
          DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive OCR, Status=%r.\n", Status));
          return Status;
        }
        ((UINT32 *) &(MmcHostInstance->CardInfo.OCRData))[0] = Response[0];
      }
    }

    if (!EFI_ERROR (Status)) {
      if (!MmcHostInstance->CardInfo.OCRData.PowerUp) {
        gBS->Stall (1);
        Timeout--;
      } else {
        if ((MmcHostInstance->CardInfo.CardType == SD_CARD_2) && (MmcHostInstance->CardInfo.OCRData.AccessMode & BIT1)) {
          MmcHostInstance->CardInfo.CardType = SD_CARD_2_HIGH;
          DEBUG ((EFI_D_ERROR, "High capacity card.\n"));
        }
        break;  // The MMC/SD card is ready. Continue the Identification Mode
      }
    } else {
      gBS->Stall (1);
      Timeout--;
    }
  }

  if (Timeout == 0) {
    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(): No Card\n"));
    return EFI_NO_MEDIA;
  } else {
    PrintOCR (Response[0]);
  }

  Status = MmcNotifyState (MmcHostInstance, MmcReadyState);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcReadyState\n"));
    return Status;
  }

  Status = MmcHost->SendCommand (MmcHost, MMC_CMD2, 0);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD2): Error\n"));
    return Status;
  }
  Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_CID, Response);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive CID, Status=%r.\n", Status));
    return Status;
  }

  PrintCID (Response);

  Status = MmcHost->NotifyState (MmcHost, MmcIdentificationState);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcIdentificationState\n"));
    return Status;
  }

  //
  // Note, SD specifications say that "if the command execution causes a state change, it
  // will be visible to the host in the response to the next command"
  // The status returned for this CMD3 will be 2 - identification
  //
  CmdArg = 1;
  Status = MmcHost->SendCommand (MmcHost, MMC_CMD3, CmdArg);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD3): Error\n"));
    return Status;
  }

  Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_RCA, Response);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive RCA, Status=%r.\n", Status));
    return Status;
  }
  PrintRCA (Response[0]);

  // For MMC card, RCA is assigned by CMD3 while CMD3 dumps the RCA for SD card
  if (MmcHostInstance->CardInfo.CardType != MMC_CARD) {
    MmcHostInstance->CardInfo.RCA = Response[0] >> 16;
  } else {
    MmcHostInstance->CardInfo.RCA = CmdArg;
  }
  Status = MmcNotifyState (MmcHostInstance, MmcStandByState);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcStandByState\n"));
    return Status;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
InitializeMmcDevice (
  IN  MMC_HOST_INSTANCE   *MmcHostInstance
  )
{
  EFI_STATUS              Status;
  EFI_MMC_HOST_PROTOCOL   *MmcHost;
  UINTN                   BlockCount;

  BlockCount = 1;
  MmcHost = MmcHostInstance->MmcHost;

  Status = MmcIdentificationMode (MmcHostInstance);
  if (EFI_ERROR (Status)) {
    DEBUG((EFI_D_ERROR, "InitializeMmcDevice(): Error in Identification Mode, Status=%r\n", Status));
    return Status;
  }

  Status = MmcNotifyState (MmcHostInstance, MmcTransferState);
  if (EFI_ERROR (Status)) {
    DEBUG((EFI_D_ERROR, "InitializeMmcDevice(): Error MmcTransferState, Status=%r\n", Status));
    return Status;
  }

  if (MmcHostInstance->CardInfo.CardType != EMMC_CARD) {
    Status = InitializeSdMmcDevice (MmcHostInstance);
  } else {
    Status = InitializeEmmcDevice (MmcHostInstance);
  }
  if (EFI_ERROR (Status)) {
    return Status;
  }

  // Set Block Length
  Status = MmcHost->SendCommand (MmcHost, MMC_CMD16, MmcHostInstance->BlockIo.Media->BlockSize);
  if (EFI_ERROR (Status)) {
    DEBUG((EFI_D_ERROR, "InitializeMmcDevice(MMC_CMD16): Error MmcHostInstance->BlockIo.Media->BlockSize: %d and Error = %r\n",
                        MmcHostInstance->BlockIo.Media->BlockSize, Status));
    return Status;
  }

  // Block Count (not used). Could return an error for SD card
  if (MmcHostInstance->CardInfo.CardType == MMC_CARD) {
    Status = MmcHost->SendCommand (MmcHost, MMC_CMD23, BlockCount);
    if (EFI_ERROR (Status)) {
      DEBUG((EFI_D_ERROR, "InitializeMmcDevice(MMC_CMD23): Error, Status=%r\n", Status));
      return Status;
    }
  }

  return EFI_SUCCESS;
}
