goto Error;\r
}\r
\r
- if (Trb->Read) {\r
- Flag = EfiPciIoOperationBusMasterWrite;\r
+ if (Trb->DataLen < Trb->BlockSize) {\r
+ Trb->BlockSize = (UINT16)Trb->DataLen;\r
+ }\r
+\r
+ if (((Private->Slot[Trb->Slot].CardType == EmmcCardType) &&\r
+ (Packet->SdMmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK)) ||\r
+ ((Private->Slot[Trb->Slot].CardType == SdCardType) &&\r
+ (Packet->SdMmcCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK))) {\r
+ Trb->Mode = SdMmcPioMode;\r
} else {\r
- Flag = EfiPciIoOperationBusMasterRead;\r
- }\r
-\r
- PciIo = Private->PciIo;\r
- if (Trb->DataLen != 0) {\r
- MapLength = Trb->DataLen;\r
- Status = PciIo->Map (\r
- PciIo,\r
- Flag,\r
- Trb->Data,\r
- &MapLength,\r
- &Trb->DataPhy,\r
- &Trb->DataMap\r
- );\r
- if (EFI_ERROR (Status) || (Trb->DataLen != MapLength)) {\r
- Status = EFI_BAD_BUFFER_SIZE;\r
- goto Error;\r
+ if (Trb->Read) {\r
+ Flag = EfiPciIoOperationBusMasterWrite;\r
+ } else {\r
+ Flag = EfiPciIoOperationBusMasterRead;\r
}\r
- }\r
\r
- if ((Trb->DataLen % Trb->BlockSize) != 0) {\r
- if (Trb->DataLen < Trb->BlockSize) {\r
- Trb->BlockSize = (UINT16)Trb->DataLen;\r
+ PciIo = Private->PciIo;\r
+ if (Trb->DataLen != 0) {\r
+ MapLength = Trb->DataLen;\r
+ Status = PciIo->Map (\r
+ PciIo,\r
+ Flag,\r
+ Trb->Data,\r
+ &MapLength,\r
+ &Trb->DataPhy,\r
+ &Trb->DataMap\r
+ );\r
+ if (EFI_ERROR (Status) || (Trb->DataLen != MapLength)) {\r
+ Status = EFI_BAD_BUFFER_SIZE;\r
+ goto Error;\r
+ }\r
}\r
- }\r
\r
- if (Trb->DataLen == 0) {\r
- Trb->Mode = SdMmcNoData;\r
- } else if (Private->Capability[Slot].Adma2 != 0) {\r
- Trb->Mode = SdMmcAdmaMode;\r
- Status = BuildAdmaDescTable (Trb);\r
- if (EFI_ERROR (Status)) {\r
- PciIo->Unmap (PciIo, Trb->DataMap);\r
- goto Error;\r
+ if (Trb->DataLen == 0) {\r
+ Trb->Mode = SdMmcNoData;\r
+ } else if (Private->Capability[Slot].Adma2 != 0) {\r
+ Trb->Mode = SdMmcAdmaMode;\r
+ Status = BuildAdmaDescTable (Trb);\r
+ if (EFI_ERROR (Status)) {\r
+ PciIo->Unmap (PciIo, Trb->DataMap);\r
+ goto Error;\r
+ }\r
+ } else if (Private->Capability[Slot].Sdma != 0) {\r
+ Trb->Mode = SdMmcSdmaMode;\r
+ } else {\r
+ Trb->Mode = SdMmcPioMode;\r
}\r
- } else if (Private->Capability[Slot].Sdma != 0) {\r
- Trb->Mode = SdMmcSdmaMode;\r
- } else {\r
- Trb->Mode = SdMmcPioMode;\r
}\r
\r
if (Event != NULL) {\r
// the Present State register to be 0\r
//\r
PresentState = BIT0 | BIT1;\r
- //\r
- // For Send Tuning Block cmd, just wait for Command Inhibit (CMD) to be 0\r
- //\r
- if (((Private->Slot[Trb->Slot].CardType == EmmcCardType) &&\r
- (Packet->SdMmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK)) ||\r
- ((Private->Slot[Trb->Slot].CardType == SdCardType) &&\r
- (Packet->SdMmcCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK))) {\r
- PresentState = BIT0;\r
- }\r
} else {\r
//\r
// Wait Command Inhibit (CMD) in the Present State register\r
return Status;\r
}\r
\r
- BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);\r
+ BlkCount = 0;\r
+ if (Trb->Mode != SdMmcNoData) {\r
+ //\r
+ // Calcuate Block Count.\r
+ //\r
+ BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);\r
+ }\r
Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_BLK_COUNT, FALSE, sizeof (BlkCount), &BlkCount);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
if (Trb->Read) {\r
TransMode |= BIT4;\r
}\r
- if (BlkCount != 0) {\r
+ if (BlkCount > 1) {\r
TransMode |= BIT5 | BIT1;\r
}\r
//\r
UINT32 SdmaAddr;\r
UINT8 Index;\r
UINT8 SwReset;\r
+ UINT32 PioLength;\r
\r
SwReset = 0;\r
Packet = Trb->Packet;\r
((Private->Slot[Trb->Slot].CardType == SdCardType) &&\r
(Packet->SdMmcCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK))) {\r
//\r
- // While performing tuning procedure (Execute Tuning is set to 1),\r
- // Transfer Completeis not set to 1\r
- // Refer to SD Host Controller Simplified Specification 3.0 table 2-23 for details.\r
+ // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,\r
+ // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.\r
+ // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.\r
//\r
- Status = EFI_SUCCESS;\r
- goto Done;\r
+ if ((IntStatus & BIT5) == BIT5) {\r
+ //\r
+ // Clear Buffer Read Ready interrupt at first.\r
+ //\r
+ IntStatus = BIT5;\r
+ SdMmcHcRwMmio (Private->PciIo, Trb->Slot, SD_MMC_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus);\r
+ //\r
+ // Read data out from Buffer Port register\r
+ //\r
+ for (PioLength = 0; PioLength < Trb->DataLen; PioLength += 4) {\r
+ SdMmcHcRwMmio (Private->PciIo, Trb->Slot, SD_MMC_HC_BUF_DAT_PORT, TRUE, 4, (UINT8*)Trb->Data + PioLength);\r
+ }\r
+ Status = EFI_SUCCESS;\r
+ goto Done;\r
+ }\r
}\r
\r
Status = EFI_NOT_READY;\r
goto Error;\r
}\r
\r
- if ((Trb->DataLen % Trb->BlockSize) != 0) {\r
- if (Trb->DataLen < Trb->BlockSize) {\r
- Trb->BlockSize = (UINT16)Trb->DataLen;\r
- }\r
+ if (Trb->DataLen < Trb->BlockSize) {\r
+ Trb->BlockSize = (UINT16)Trb->DataLen;\r
}\r
\r
- if (Trb->DataLen == 0) {\r
- Trb->Mode = EmmcNoData;\r
- } else if (Capability.Adma2 != 0) {\r
- Trb->Mode = EmmcAdmaMode;\r
- Status = BuildAdmaDescTable (Trb);\r
- if (EFI_ERROR (Status)) {\r
- goto Error;\r
- }\r
- } else if (Capability.Sdma != 0) {\r
- Trb->Mode = EmmcSdmaMode;\r
- } else {\r
+ if (Packet->EmmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK) {\r
Trb->Mode = EmmcPioMode;\r
+ } else {\r
+ if (Trb->DataLen == 0) {\r
+ Trb->Mode = EmmcNoData;\r
+ } else if (Capability.Adma2 != 0) {\r
+ Trb->Mode = EmmcAdmaMode;\r
+ Status = BuildAdmaDescTable (Trb);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Error;\r
+ }\r
+ } else if (Capability.Sdma != 0) {\r
+ Trb->Mode = EmmcSdmaMode;\r
+ } else {\r
+ Trb->Mode = EmmcPioMode;\r
+ }\r
}\r
-\r
return Trb;\r
\r
Error:\r
// the Present State register to be 0\r
//\r
PresentState = BIT0 | BIT1;\r
- if (Packet->EmmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK) {\r
- PresentState = BIT0;\r
- }\r
} else {\r
//\r
// Wait Command Inhibit (CMD) in the Present State register\r
return Status;\r
}\r
\r
- BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);\r
+ BlkCount = 0;\r
+ if (Trb->Mode != EmmcNoData) {\r
+ //\r
+ // Calcuate Block Count.\r
+ //\r
+ BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);\r
+ }\r
+\r
Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_BLK_COUNT, FALSE, sizeof (BlkCount), &BlkCount);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
if (Trb->Read) {\r
TransMode |= BIT4;\r
}\r
- if (BlkCount != 0) {\r
+ if (BlkCount > 1) {\r
TransMode |= BIT5 | BIT1;\r
}\r
}\r
UINT32 SdmaAddr;\r
UINT8 Index;\r
UINT8 SwReset;\r
+ UINT32 PioLength;\r
\r
SwReset = 0;\r
Packet = Trb->Packet;\r
}\r
\r
if (Packet->EmmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK) {\r
- Status = EFI_SUCCESS;\r
- goto Done;\r
+ //\r
+ // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,\r
+ // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.\r
+ // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.\r
+ //\r
+ if ((IntStatus & BIT5) == BIT5) {\r
+ //\r
+ // Clear Buffer Read Ready interrupt at first.\r
+ //\r
+ IntStatus = BIT5;\r
+ EmmcPeimHcRwMmio (Bar + EMMC_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus);\r
+ //\r
+ // Read data out from Buffer Port register\r
+ //\r
+ for (PioLength = 0; PioLength < Trb->DataLen; PioLength += 4) {\r
+ EmmcPeimHcRwMmio (Bar + EMMC_HC_BUF_DAT_PORT, TRUE, 4, (UINT8*)Trb->Data + PioLength);\r
+ }\r
+ Status = EFI_SUCCESS;\r
+ goto Done;\r
+ }\r
}\r
\r
Status = EFI_NOT_READY;\r
goto Error;\r
}\r
\r
- if ((Trb->DataLen % Trb->BlockSize) != 0) {\r
- if (Trb->DataLen < Trb->BlockSize) {\r
- Trb->BlockSize = (UINT16)Trb->DataLen;\r
- }\r
+ if (Trb->DataLen < Trb->BlockSize) {\r
+ Trb->BlockSize = (UINT16)Trb->DataLen;\r
}\r
\r
- if (Trb->DataLen == 0) {\r
- Trb->Mode = SdNoData;\r
- } else if (Capability.Adma2 != 0) {\r
- Trb->Mode = SdAdmaMode;\r
- Status = BuildAdmaDescTable (Trb);\r
- if (EFI_ERROR (Status)) {\r
- goto Error;\r
- }\r
- } else if (Capability.Sdma != 0) {\r
- Trb->Mode = SdSdmaMode;\r
- } else {\r
+ if (Packet->SdCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK) {\r
Trb->Mode = SdPioMode;\r
+ } else {\r
+ if (Trb->DataLen == 0) {\r
+ Trb->Mode = SdNoData;\r
+ } else if (Capability.Adma2 != 0) {\r
+ Trb->Mode = SdAdmaMode;\r
+ Status = BuildAdmaDescTable (Trb);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Error;\r
+ }\r
+ } else if (Capability.Sdma != 0) {\r
+ Trb->Mode = SdSdmaMode;\r
+ } else {\r
+ Trb->Mode = SdPioMode;\r
+ }\r
}\r
-\r
return Trb;\r
\r
Error:\r
// the Present State register to be 0\r
//\r
PresentState = BIT0 | BIT1;\r
- if (Packet->SdCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK) {\r
- PresentState = BIT0;\r
- }\r
} else {\r
//\r
// Wait Command Inhibit (CMD) in the Present State register\r
return Status;\r
}\r
\r
- BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);\r
+ BlkCount = 0;\r
+ if (Trb->Mode != SdNoData) {\r
+ //\r
+ // Calcuate Block Count.\r
+ //\r
+ BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);\r
+ }\r
Status = SdPeimHcRwMmio (Bar + SD_HC_BLK_COUNT, FALSE, sizeof (BlkCount), &BlkCount);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
if (Trb->Read) {\r
TransMode |= BIT4;\r
}\r
- if (BlkCount != 0) {\r
+ if (BlkCount > 1) {\r
TransMode |= BIT5 | BIT1;\r
}\r
+ //\r
+ // SD memory card needs to use AUTO CMD12 feature.\r
+ //\r
if (BlkCount > 1) {\r
TransMode |= BIT2;\r
}\r
UINT32 SdmaAddr;\r
UINT8 Index;\r
UINT8 SwReset;\r
+ UINT32 PioLength;\r
\r
SwReset = 0;\r
Packet = Trb->Packet;\r
}\r
\r
if (Packet->SdCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK) {\r
- Status = EFI_SUCCESS;\r
- goto Done;\r
+ //\r
+ // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,\r
+ // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.\r
+ // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.\r
+ //\r
+ if ((IntStatus & BIT5) == BIT5) {\r
+ //\r
+ // Clear Buffer Read Ready interrupt at first.\r
+ //\r
+ IntStatus = BIT5;\r
+ SdPeimHcRwMmio (Bar + SD_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus);\r
+ //\r
+ // Read data out from Buffer Port register\r
+ //\r
+ for (PioLength = 0; PioLength < Trb->DataLen; PioLength += 4) {\r
+ SdPeimHcRwMmio (Bar + SD_HC_BUF_DAT_PORT, TRUE, 4, (UINT8*)Trb->Data + PioLength);\r
+ }\r
+ Status = EFI_SUCCESS;\r
+ goto Done;\r
+ }\r
}\r
\r
Status = EFI_NOT_READY;\r