+BOOLEAN
+CardPresent (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Data;
+
+ //
+ // Card detect is a GPIO0 on the TPS65950
+ //
+ Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, GPIODATAIN1), 1, &Data);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ if ((Data & CARD_DETECT_BIT) == CARD_DETECT_BIT) {
+ // No Card present
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+EFI_STATUS
+DetectCard (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ if (!CardPresent ()) {
+ return EFI_NO_MEDIA;
+ }
+
+ //Initialize MMC host controller clocks.
+ Status = InitializeMMCHS ();
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "Initialize MMC host controller fails. Status: %x\n", Status));
+ return Status;
+ }
+
+ //Software reset of the MMCHS host controller.
+ MmioWrite32 (MMCHS_SYSCONFIG, SOFTRESET);
+ gBS->Stall(1000);
+ while ((MmioRead32 (MMCHS_SYSSTATUS) & RESETDONE_MASK) != RESETDONE);
+
+ //Soft reset for all.
+ MmioWrite32 (MMCHS_SYSCTL, SRA);
+ gBS->Stall(1000);
+ while ((MmioRead32 (MMCHS_SYSCTL) & SRA) != 0x0);
+
+ //Voltage capabilities initialization. Activate VS18 and VS30.
+ MmioOr32 (MMCHS_CAPA, (VS30 | VS18));
+
+ //Wakeup configuration
+ MmioOr32 (MMCHS_SYSCONFIG, ENAWAKEUP);
+ MmioOr32 (MMCHS_HCTL, IWE);
+
+ //MMCHS Controller default initialization
+ MmioOr32 (MMCHS_CON, (OD | DW8_1_4_BIT | CEATA_OFF));
+
+ MmioWrite32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_OFF));
+
+ //Enable internal clock
+ MmioOr32 (MMCHS_SYSCTL, ICE);
+
+ //Set the clock frequency to 80KHz.
+ UpdateMMCHSClkFrequency (CLKD_80KHZ);
+
+ //Enable SD bus power.
+ MmioOr32 (MMCHS_HCTL, (SDBP_ON));
+
+ //Poll till SD bus power bit is set.
+ while ((MmioRead32 (MMCHS_HCTL) & SDBP_MASK) != SDBP_ON);
+
+ //Card idenfication
+ Status = PerformCardIdenfication ();
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "No MMC/SD card detected.\n"));
+ return Status;
+ }
+
+ //Get CSD (Card specific data) for the detected card.
+ Status = GetCardSpecificData();
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //Configure the card in data transfer mode.
+ Status = PerformCardConfiguration();
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //Patch the Media structure.
+ gMMCHSMedia.LastBlock = (gCardInfo.NumBlocks - 1);
+ gMMCHSMedia.BlockSize = gCardInfo.BlockSize;
+ gMMCHSMedia.ReadOnly = (MmioRead32 (GPIO1_BASE + GPIO_DATAIN) & BIT23) == BIT23;
+ gMMCHSMedia.MediaPresent = TRUE;
+ gMMCHSMedia.MediaId++;
+ gMediaChange = FALSE;
+
+ return Status;
+}
+
+