summaryrefslogtreecommitdiff
path: root/MdeModulePkg
diff options
context:
space:
mode:
authorFeng Tian <feng.tian@intel.com>2016-04-29 16:02:50 +0800
committerFeng Tian <feng.tian@intel.com>2016-05-06 16:09:59 +0800
commite7e89b0861fa561c2c13eee3271655c100b3abb9 (patch)
treedcc806bdf5daf94b9245be516297d32129b28d12 /MdeModulePkg
parentcb9cb9e2aaec95f89f3c0dfc411226aa6c42461a (diff)
downloadedk2-e7e89b0861fa561c2c13eee3271655c100b3abb9.zip
edk2-e7e89b0861fa561c2c13eee3271655c100b3abb9.tar.gz
edk2-e7e89b0861fa561c2c13eee3271655c100b3abb9.tar.bz2
MdeModulePkg/SdMmcPciHcDxe: Using PIO rather than DMA for clock tuning
The original code is using ADMA mode to do clock tuning procedure. It may have problem on some SD/MMC host controllers as there is no way to know when to send next tuning cmd. Update it to PIO mode to strictly follow SD Host Controller Simplified Specification 3.0 Figure 2-29. By this way, if the Buffer Read Ready interrupt is set, we could know it's ok to send the next clock tuning cmd. Cc: Wu, Hao A <hao.a.wu@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Feng Tian <feng.tian@intel.com>
Diffstat (limited to 'MdeModulePkg')
-rw-r--r--MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c120
-rw-r--r--MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHci.c70
-rw-r--r--MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.c72
3 files changed, 164 insertions, 98 deletions
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
index 72af1e7..8978182 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
@@ -1265,48 +1265,53 @@ SdMmcCreateTrb (
goto Error;
}
- if (Trb->Read) {
- Flag = EfiPciIoOperationBusMasterWrite;
+ if (Trb->DataLen < Trb->BlockSize) {
+ Trb->BlockSize = (UINT16)Trb->DataLen;
+ }
+
+ if (((Private->Slot[Trb->Slot].CardType == EmmcCardType) &&
+ (Packet->SdMmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK)) ||
+ ((Private->Slot[Trb->Slot].CardType == SdCardType) &&
+ (Packet->SdMmcCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK))) {
+ Trb->Mode = SdMmcPioMode;
} else {
- Flag = EfiPciIoOperationBusMasterRead;
- }
-
- PciIo = Private->PciIo;
- if (Trb->DataLen != 0) {
- MapLength = Trb->DataLen;
- Status = PciIo->Map (
- PciIo,
- Flag,
- Trb->Data,
- &MapLength,
- &Trb->DataPhy,
- &Trb->DataMap
- );
- if (EFI_ERROR (Status) || (Trb->DataLen != MapLength)) {
- Status = EFI_BAD_BUFFER_SIZE;
- goto Error;
+ if (Trb->Read) {
+ Flag = EfiPciIoOperationBusMasterWrite;
+ } else {
+ Flag = EfiPciIoOperationBusMasterRead;
}
- }
- if ((Trb->DataLen % Trb->BlockSize) != 0) {
- if (Trb->DataLen < Trb->BlockSize) {
- Trb->BlockSize = (UINT16)Trb->DataLen;
+ PciIo = Private->PciIo;
+ if (Trb->DataLen != 0) {
+ MapLength = Trb->DataLen;
+ Status = PciIo->Map (
+ PciIo,
+ Flag,
+ Trb->Data,
+ &MapLength,
+ &Trb->DataPhy,
+ &Trb->DataMap
+ );
+ if (EFI_ERROR (Status) || (Trb->DataLen != MapLength)) {
+ Status = EFI_BAD_BUFFER_SIZE;
+ goto Error;
+ }
}
- }
- if (Trb->DataLen == 0) {
- Trb->Mode = SdMmcNoData;
- } else if (Private->Capability[Slot].Adma2 != 0) {
- Trb->Mode = SdMmcAdmaMode;
- Status = BuildAdmaDescTable (Trb);
- if (EFI_ERROR (Status)) {
- PciIo->Unmap (PciIo, Trb->DataMap);
- goto Error;
+ if (Trb->DataLen == 0) {
+ Trb->Mode = SdMmcNoData;
+ } else if (Private->Capability[Slot].Adma2 != 0) {
+ Trb->Mode = SdMmcAdmaMode;
+ Status = BuildAdmaDescTable (Trb);
+ if (EFI_ERROR (Status)) {
+ PciIo->Unmap (PciIo, Trb->DataMap);
+ goto Error;
+ }
+ } else if (Private->Capability[Slot].Sdma != 0) {
+ Trb->Mode = SdMmcSdmaMode;
+ } else {
+ Trb->Mode = SdMmcPioMode;
}
- } else if (Private->Capability[Slot].Sdma != 0) {
- Trb->Mode = SdMmcSdmaMode;
- } else {
- Trb->Mode = SdMmcPioMode;
}
if (Event != NULL) {
@@ -1392,15 +1397,6 @@ SdMmcCheckTrbEnv (
// the Present State register to be 0
//
PresentState = BIT0 | BIT1;
- //
- // For Send Tuning Block cmd, just wait for Command Inhibit (CMD) to be 0
- //
- if (((Private->Slot[Trb->Slot].CardType == EmmcCardType) &&
- (Packet->SdMmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK)) ||
- ((Private->Slot[Trb->Slot].CardType == SdCardType) &&
- (Packet->SdMmcCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK))) {
- PresentState = BIT0;
- }
} else {
//
// Wait Command Inhibit (CMD) in the Present State register
@@ -1565,7 +1561,13 @@ SdMmcExecTrb (
return Status;
}
- BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);
+ BlkCount = 0;
+ if (Trb->Mode != SdMmcNoData) {
+ //
+ // Calcuate Block Count.
+ //
+ BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);
+ }
Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_BLK_COUNT, FALSE, sizeof (BlkCount), &BlkCount);
if (EFI_ERROR (Status)) {
return Status;
@@ -1585,7 +1587,7 @@ SdMmcExecTrb (
if (Trb->Read) {
TransMode |= BIT4;
}
- if (BlkCount != 0) {
+ if (BlkCount > 1) {
TransMode |= BIT5 | BIT1;
}
//
@@ -1665,6 +1667,7 @@ SdMmcCheckTrbResult (
UINT32 SdmaAddr;
UINT8 Index;
UINT8 SwReset;
+ UINT32 PioLength;
SwReset = 0;
Packet = Trb->Packet;
@@ -1814,12 +1817,25 @@ SdMmcCheckTrbResult (
((Private->Slot[Trb->Slot].CardType == SdCardType) &&
(Packet->SdMmcCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK))) {
//
- // While performing tuning procedure (Execute Tuning is set to 1),
- // Transfer Completeis not set to 1
- // Refer to SD Host Controller Simplified Specification 3.0 table 2-23 for details.
+ // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,
+ // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.
+ // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.
//
- Status = EFI_SUCCESS;
- goto Done;
+ if ((IntStatus & BIT5) == BIT5) {
+ //
+ // Clear Buffer Read Ready interrupt at first.
+ //
+ IntStatus = BIT5;
+ SdMmcHcRwMmio (Private->PciIo, Trb->Slot, SD_MMC_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus);
+ //
+ // Read data out from Buffer Port register
+ //
+ for (PioLength = 0; PioLength < Trb->DataLen; PioLength += 4) {
+ SdMmcHcRwMmio (Private->PciIo, Trb->Slot, SD_MMC_HC_BUF_DAT_PORT, TRUE, 4, (UINT8*)Trb->Data + PioLength);
+ }
+ Status = EFI_SUCCESS;
+ goto Done;
+ }
}
Status = EFI_NOT_READY;
diff --git a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHci.c b/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHci.c
index 569a86a..3ffc477 100644
--- a/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHci.c
+++ b/MdeModulePkg/Bus/Sd/EmmcBlockIoPei/EmmcHci.c
@@ -1032,26 +1032,27 @@ EmmcPeimCreateTrb (
goto Error;
}
- if ((Trb->DataLen % Trb->BlockSize) != 0) {
- if (Trb->DataLen < Trb->BlockSize) {
- Trb->BlockSize = (UINT16)Trb->DataLen;
- }
+ if (Trb->DataLen < Trb->BlockSize) {
+ Trb->BlockSize = (UINT16)Trb->DataLen;
}
- if (Trb->DataLen == 0) {
- Trb->Mode = EmmcNoData;
- } else if (Capability.Adma2 != 0) {
- Trb->Mode = EmmcAdmaMode;
- Status = BuildAdmaDescTable (Trb);
- if (EFI_ERROR (Status)) {
- goto Error;
- }
- } else if (Capability.Sdma != 0) {
- Trb->Mode = EmmcSdmaMode;
- } else {
+ if (Packet->EmmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK) {
Trb->Mode = EmmcPioMode;
+ } else {
+ if (Trb->DataLen == 0) {
+ Trb->Mode = EmmcNoData;
+ } else if (Capability.Adma2 != 0) {
+ Trb->Mode = EmmcAdmaMode;
+ Status = BuildAdmaDescTable (Trb);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ } else if (Capability.Sdma != 0) {
+ Trb->Mode = EmmcSdmaMode;
+ } else {
+ Trb->Mode = EmmcPioMode;
+ }
}
-
return Trb;
Error:
@@ -1111,9 +1112,6 @@ EmmcPeimCheckTrbEnv (
// the Present State register to be 0
//
PresentState = BIT0 | BIT1;
- if (Packet->EmmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK) {
- PresentState = BIT0;
- }
} else {
//
// Wait Command Inhibit (CMD) in the Present State register
@@ -1273,7 +1271,14 @@ EmmcPeimExecTrb (
return Status;
}
- BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);
+ BlkCount = 0;
+ if (Trb->Mode != EmmcNoData) {
+ //
+ // Calcuate Block Count.
+ //
+ BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);
+ }
+
Status = EmmcPeimHcRwMmio (Bar + EMMC_HC_BLK_COUNT, FALSE, sizeof (BlkCount), &BlkCount);
if (EFI_ERROR (Status)) {
return Status;
@@ -1293,7 +1298,7 @@ EmmcPeimExecTrb (
if (Trb->Read) {
TransMode |= BIT4;
}
- if (BlkCount != 0) {
+ if (BlkCount > 1) {
TransMode |= BIT5 | BIT1;
}
}
@@ -1365,6 +1370,7 @@ EmmcPeimCheckTrbResult (
UINT32 SdmaAddr;
UINT8 Index;
UINT8 SwReset;
+ UINT32 PioLength;
SwReset = 0;
Packet = Trb->Packet;
@@ -1497,8 +1503,26 @@ EmmcPeimCheckTrbResult (
}
if (Packet->EmmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK) {
- Status = EFI_SUCCESS;
- goto Done;
+ //
+ // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,
+ // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.
+ // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.
+ //
+ if ((IntStatus & BIT5) == BIT5) {
+ //
+ // Clear Buffer Read Ready interrupt at first.
+ //
+ IntStatus = BIT5;
+ EmmcPeimHcRwMmio (Bar + EMMC_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus);
+ //
+ // Read data out from Buffer Port register
+ //
+ for (PioLength = 0; PioLength < Trb->DataLen; PioLength += 4) {
+ EmmcPeimHcRwMmio (Bar + EMMC_HC_BUF_DAT_PORT, TRUE, 4, (UINT8*)Trb->Data + PioLength);
+ }
+ Status = EFI_SUCCESS;
+ goto Done;
+ }
}
Status = EFI_NOT_READY;
diff --git a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.c b/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.c
index 48e4ae6..3f327f8 100644
--- a/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.c
+++ b/MdeModulePkg/Bus/Sd/SdBlockIoPei/SdHci.c
@@ -1032,26 +1032,27 @@ SdPeimCreateTrb (
goto Error;
}
- if ((Trb->DataLen % Trb->BlockSize) != 0) {
- if (Trb->DataLen < Trb->BlockSize) {
- Trb->BlockSize = (UINT16)Trb->DataLen;
- }
+ if (Trb->DataLen < Trb->BlockSize) {
+ Trb->BlockSize = (UINT16)Trb->DataLen;
}
- if (Trb->DataLen == 0) {
- Trb->Mode = SdNoData;
- } else if (Capability.Adma2 != 0) {
- Trb->Mode = SdAdmaMode;
- Status = BuildAdmaDescTable (Trb);
- if (EFI_ERROR (Status)) {
- goto Error;
- }
- } else if (Capability.Sdma != 0) {
- Trb->Mode = SdSdmaMode;
- } else {
+ if (Packet->SdCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK) {
Trb->Mode = SdPioMode;
+ } else {
+ if (Trb->DataLen == 0) {
+ Trb->Mode = SdNoData;
+ } else if (Capability.Adma2 != 0) {
+ Trb->Mode = SdAdmaMode;
+ Status = BuildAdmaDescTable (Trb);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ } else if (Capability.Sdma != 0) {
+ Trb->Mode = SdSdmaMode;
+ } else {
+ Trb->Mode = SdPioMode;
+ }
}
-
return Trb;
Error:
@@ -1111,9 +1112,6 @@ SdPeimCheckTrbEnv (
// the Present State register to be 0
//
PresentState = BIT0 | BIT1;
- if (Packet->SdCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK) {
- PresentState = BIT0;
- }
} else {
//
// Wait Command Inhibit (CMD) in the Present State register
@@ -1273,7 +1271,13 @@ SdPeimExecTrb (
return Status;
}
- BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);
+ BlkCount = 0;
+ if (Trb->Mode != SdNoData) {
+ //
+ // Calcuate Block Count.
+ //
+ BlkCount = (UINT16)(Trb->DataLen / Trb->BlockSize);
+ }
Status = SdPeimHcRwMmio (Bar + SD_HC_BLK_COUNT, FALSE, sizeof (BlkCount), &BlkCount);
if (EFI_ERROR (Status)) {
return Status;
@@ -1293,9 +1297,12 @@ SdPeimExecTrb (
if (Trb->Read) {
TransMode |= BIT4;
}
- if (BlkCount != 0) {
+ if (BlkCount > 1) {
TransMode |= BIT5 | BIT1;
}
+ //
+ // SD memory card needs to use AUTO CMD12 feature.
+ //
if (BlkCount > 1) {
TransMode |= BIT2;
}
@@ -1368,6 +1375,7 @@ SdPeimCheckTrbResult (
UINT32 SdmaAddr;
UINT8 Index;
UINT8 SwReset;
+ UINT32 PioLength;
SwReset = 0;
Packet = Trb->Packet;
@@ -1500,8 +1508,26 @@ SdPeimCheckTrbResult (
}
if (Packet->SdCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK) {
- Status = EFI_SUCCESS;
- goto Done;
+ //
+ // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,
+ // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.
+ // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.
+ //
+ if ((IntStatus & BIT5) == BIT5) {
+ //
+ // Clear Buffer Read Ready interrupt at first.
+ //
+ IntStatus = BIT5;
+ SdPeimHcRwMmio (Bar + SD_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus);
+ //
+ // Read data out from Buffer Port register
+ //
+ for (PioLength = 0; PioLength < Trb->DataLen; PioLength += 4) {
+ SdPeimHcRwMmio (Bar + SD_HC_BUF_DAT_PORT, TRUE, 4, (UINT8*)Trb->Data + PioLength);
+ }
+ Status = EFI_SUCCESS;
+ goto Done;
+ }
}
Status = EFI_NOT_READY;