]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/Universal/MmcDxe/MmcBlockIo.c
MmcDxe: Adding eMMC support
[mirror_edk2.git] / EmbeddedPkg / Universal / MmcDxe / MmcBlockIo.c
index 4b9b64e46f0bd7cac74e3a184d53516bd97181e8..04c82613d5b7b80f6641bdeaef6755cc1fcc2e55 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 *\r
-*  Copyright (c) 2011-2013, ARM Limited. All rights reserved.\r
+*  Copyright (c) 2011-2014, ARM Limited. All rights reserved.\r
 *\r
 *  This program and the accompanying materials\r
 *  are licensed and made available under the terms and conditions of the BSD License\r
@@ -17,9 +17,6 @@
 \r
 #include "Mmc.h"\r
 \r
-#define MAX_RETRY_COUNT  1000\r
-#define CMD_RETRY_COUNT  20\r
-\r
 EFI_STATUS\r
 MmcNotifyState (\r
   IN MMC_HOST_INSTANCE *MmcHostInstance,\r
@@ -65,259 +62,6 @@ MmcGetCardStatus (
   return Status;\r
 }\r
 \r
-EFI_STATUS\r
-EFIAPI\r
-MmcIdentificationMode (\r
-  IN MMC_HOST_INSTANCE     *MmcHostInstance\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-  UINT32                  Response[4];\r
-  UINTN                   Timeout;\r
-  UINTN                   CmdArg;\r
-  BOOLEAN                 IsHCS;\r
-  EFI_MMC_HOST_PROTOCOL   *MmcHost;\r
-\r
-  MmcHost = MmcHostInstance->MmcHost;\r
-  CmdArg = 0;\r
-  IsHCS = FALSE;\r
-\r
-  if (MmcHost == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  // We can get into this function if we restart the identification mode\r
-  if (MmcHostInstance->State == MmcHwInitializationState) {\r
-    // Initialize the MMC Host HW\r
-    Status = MmcNotifyState (MmcHostInstance, MmcHwInitializationState);\r
-    if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcHwInitializationState\n"));\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  Status = MmcHost->SendCommand (MmcHost, MMC_CMD0, 0);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD0): Error\n"));\r
-    return Status;\r
-  }\r
-\r
-  Status = MmcNotifyState (MmcHostInstance, MmcIdleState);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcIdleState\n"));\r
-    return Status;\r
-  }\r
-\r
-  // Are we using SDIO ?\r
-  Status = MmcHost->SendCommand (MmcHost, MMC_CMD5, 0);\r
-  if (Status == EFI_SUCCESS) {\r
-    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD5): Error - SDIO not supported.\n"));\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  // Check which kind of card we are using. Ver2.00 or later SD Memory Card (PL180 is SD v1.1)\r
-  CmdArg = (0x0UL << 12 | BIT8 | 0xCEUL << 0);\r
-  Status = MmcHost->SendCommand (MmcHost, MMC_CMD8, CmdArg);\r
-  if (Status == EFI_SUCCESS) {\r
-    DEBUG ((EFI_D_ERROR, "Card is SD2.0 => Supports high capacity\n"));\r
-    IsHCS = TRUE;\r
-    MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_R7, Response);\r
-    PrintResponseR1 (Response[0]);\r
-    //check if it is valid response\r
-    if (Response[0] != CmdArg) {\r
-      DEBUG ((EFI_D_ERROR, "The Card is not usable\n"));\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-  } else {\r
-    DEBUG ((EFI_D_ERROR, "Not a SD2.0 Card\n"));\r
-  }\r
-\r
-  // We need to wait for the MMC or SD card is ready => (gCardInfo.OCRData.PowerUp == 1)\r
-  Timeout = MAX_RETRY_COUNT;\r
-  while (Timeout > 0) {\r
-    // SD Card or MMC Card ? CMD55 indicates to the card that the next command is an application specific command\r
-    Status = MmcHost->SendCommand (MmcHost, MMC_CMD55, 0);\r
-    if (Status == EFI_SUCCESS) {\r
-      DEBUG ((EFI_D_INFO, "Card should be SD\n"));\r
-      if (IsHCS) {\r
-        MmcHostInstance->CardInfo.CardType = SD_CARD_2;\r
-      } else {\r
-        MmcHostInstance->CardInfo.CardType = SD_CARD;\r
-      }\r
-\r
-      // Note: The first time CmdArg will be zero\r
-      CmdArg = ((UINTN *) &(MmcHostInstance->CardInfo.OCRData))[0];\r
-      if (IsHCS) {\r
-        CmdArg |= BIT30;\r
-      }\r
-      Status = MmcHost->SendCommand (MmcHost, MMC_ACMD41, CmdArg);\r
-      if (!EFI_ERROR (Status)) {\r
-        MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_OCR, Response);\r
-        ((UINT32 *) &(MmcHostInstance->CardInfo.OCRData))[0] = Response[0];\r
-      }\r
-    } else {\r
-      DEBUG ((EFI_D_INFO, "Card should be MMC\n"));\r
-      MmcHostInstance->CardInfo.CardType = MMC_CARD;\r
-\r
-      Status = MmcHost->SendCommand (MmcHost, MMC_CMD1, 0x800000);\r
-      if (!EFI_ERROR (Status)) {\r
-        MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_OCR, Response);\r
-        ((UINT32 *) &(MmcHostInstance->CardInfo.OCRData))[0] = Response[0];\r
-      }\r
-    }\r
-\r
-    if (!EFI_ERROR (Status)) {\r
-      if (!MmcHostInstance->CardInfo.OCRData.PowerUp) {\r
-        MicroSecondDelay (1);\r
-        Timeout--;\r
-      } else {\r
-        if ((MmcHostInstance->CardInfo.CardType == SD_CARD_2) && (MmcHostInstance->CardInfo.OCRData.AccessMode & BIT1)) {\r
-          MmcHostInstance->CardInfo.CardType = SD_CARD_2_HIGH;\r
-          DEBUG ((EFI_D_ERROR, "High capacity card.\n"));\r
-        }\r
-        break;  // The MMC/SD card is ready. Continue the Identification Mode\r
-      }\r
-    } else {\r
-      MicroSecondDelay (1);\r
-      Timeout--;\r
-    }\r
-  }\r
-\r
-  if (Timeout == 0) {\r
-    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(): No Card\n"));\r
-    return EFI_NO_MEDIA;\r
-  } else {\r
-    PrintOCR (Response[0]);\r
-  }\r
-\r
-  Status = MmcNotifyState (MmcHostInstance, MmcReadyState);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcReadyState\n"));\r
-    return Status;\r
-  }\r
-\r
-  Status = MmcHost->SendCommand (MmcHost, MMC_CMD2, 0);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD2): Error\n"));\r
-    return Status;\r
-  }\r
-  MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_CID, Response);\r
-  PrintCID (Response);\r
-\r
-  Status = MmcNotifyState (MmcHostInstance, MmcIdentificationState);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcIdentificationState\n"));\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Note, SD specifications say that "if the command execution causes a state change, it\r
-  // will be visible to the host in the response to the next command"\r
-  // The status returned for this CMD3 will be 2 - identification\r
-  //\r
-  CmdArg = 1;\r
-  Status = MmcHost->SendCommand (MmcHost, MMC_CMD3, CmdArg);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD3): Error\n"));\r
-    return Status;\r
-  }\r
-\r
-  MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_RCA, Response);\r
-  PrintRCA (Response[0]);\r
-\r
-  // For MMC card, RCA is assigned by CMD3 while CMD3 dumps the RCA for SD card\r
-  if (MmcHostInstance->CardInfo.CardType != MMC_CARD) {\r
-    MmcHostInstance->CardInfo.RCA = Response[0] >> 16;\r
-  } else {\r
-    MmcHostInstance->CardInfo.RCA = CmdArg;\r
-  }\r
-\r
-  Status = MmcNotifyState (MmcHostInstance, MmcStandByState);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcStandByState\n"));\r
-    return Status;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS InitializeMmcDevice (\r
-  IN  MMC_HOST_INSTANCE   *MmcHostInstance\r
-  )\r
-{\r
-  UINT32                  Response[4];\r
-  EFI_STATUS              Status;\r
-  UINTN                   CardSize, NumBlocks, BlockSize, CmdArg;\r
-  EFI_MMC_HOST_PROTOCOL   *MmcHost;\r
-  UINTN                   BlockCount;\r
-\r
-  BlockCount = 1;\r
-  MmcHost = MmcHostInstance->MmcHost;\r
-\r
-  MmcIdentificationMode (MmcHostInstance);\r
-\r
-  //Send a command to get Card specific data\r
-  CmdArg = MmcHostInstance->CardInfo.RCA << 16;\r
-  Status = MmcHost->SendCommand (MmcHost, MMC_CMD9, CmdArg);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG((EFI_D_ERROR, "InitializeMmcDevice(MMC_CMD9): Error, Status=%r\n", Status));\r
-    return Status;\r
-  }\r
-  //Read Response\r
-  MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_CSD, Response);\r
-  PrintCSD (Response);\r
-\r
-  if (MmcHostInstance->CardInfo.CardType == SD_CARD_2_HIGH) {\r
-    CardSize = HC_MMC_CSD_GET_DEVICESIZE (Response);\r
-    NumBlocks = ((CardSize + 1) * 1024);\r
-    BlockSize = 1 << MMC_CSD_GET_READBLLEN (Response);\r
-  } else {\r
-    CardSize = MMC_CSD_GET_DEVICESIZE (Response);\r
-    NumBlocks = (CardSize + 1) * (1 << (MMC_CSD_GET_DEVICESIZEMULT (Response) + 2));\r
-    BlockSize = 1 << MMC_CSD_GET_READBLLEN (Response);\r
-  }\r
-\r
-  //For >=2G card, BlockSize may be 1K, but the transfer size is 512 bytes.\r
-  if (BlockSize > 512) {\r
-    NumBlocks = MultU64x32 (NumBlocks, BlockSize/512);\r
-    BlockSize = 512;\r
-  }\r
-\r
-  MmcHostInstance->BlockIo.Media->LastBlock    = (NumBlocks - 1);\r
-  MmcHostInstance->BlockIo.Media->BlockSize    = BlockSize;\r
-  MmcHostInstance->BlockIo.Media->ReadOnly     = MmcHost->IsReadOnly (MmcHost);\r
-  MmcHostInstance->BlockIo.Media->MediaPresent = TRUE;\r
-  MmcHostInstance->BlockIo.Media->MediaId++;\r
-\r
-  CmdArg = MmcHostInstance->CardInfo.RCA << 16;\r
-  Status = MmcHost->SendCommand (MmcHost, MMC_CMD7, CmdArg);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG((EFI_D_ERROR, "InitializeMmcDevice(MMC_CMD7): Error and Status = %r\n", Status));\r
-    return Status;\r
-  }\r
-\r
-  Status = MmcNotifyState (MmcHostInstance, MmcTransferState);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG((EFI_D_ERROR, "InitializeMmcDevice(): Error MmcTransferState\n"));\r
-    return Status;\r
-  }\r
-\r
-  // Set Block Length\r
-  Status = MmcHost->SendCommand (MmcHost, MMC_CMD16, MmcHostInstance->BlockIo.Media->BlockSize);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG((EFI_D_ERROR, "InitializeMmcDevice(MMC_CMD16): Error MmcHostInstance->BlockIo.Media->BlockSize: %d and Error = %r\n",\r
-                        MmcHostInstance->BlockIo.Media->BlockSize, Status));\r
-    return Status;\r
-  }\r
-\r
-  // Block Count (not used). Could return an error for SD card\r
-  if (MmcHostInstance->CardInfo.CardType == MMC_CARD) {\r
-    MmcHost->SendCommand (MmcHost, MMC_CMD23, BlockCount);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
 EFI_STATUS\r
 EFIAPI\r
 MmcReset (\r