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