From: Marcin Wojtas <mw@semihalf.com>
To: edk2-devel@lists.01.org
Cc: feng.tian@intel.com, michael.d.kinney@intel.com,
liming.gao@intel.com, leif.lindholm@linaro.org,
ard.biesheuvel@linaro.org, nadavh@marvell.com, mw@semihalf.com,
jsd@semihalf.com, Tomasz Michalec <tm@semihalf.com>
Subject: [PATCH 2/7] MdeModulePkg/SdMmcPciHcDxe: Add UhsSignaling to SdMmcOverride protocol
Date: Mon, 3 Sep 2018 06:54:08 +0200 [thread overview]
Message-ID: <1535950453-27147-3-git-send-email-mw@semihalf.com> (raw)
In-Reply-To: <1535950453-27147-1-git-send-email-mw@semihalf.com>
From: Tomasz Michalec <tm@semihalf.com>
Some SD Host Controlers use different values in Host Control 2 Register
to select UHS Mode. This patch adds new UhsSignaling callback to
the SdMmcOverride protocol. UHS signaling configuration is moved
to a common, default routine (SdMmcHcUhsSignaling),
which is called when SdMmcOverride does not cover this functionality.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
---
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h | 50 +++++++
MdeModulePkg/Include/Protocol/SdMmcOverride.h | 26 ++++
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c | 150 ++++++++++++--------
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c | 36 +++--
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c | 69 +++++++++
5 files changed, 263 insertions(+), 68 deletions(-)
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h
index e3fadb5..525828c 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h
@@ -68,6 +68,39 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define SD_MMC_HC_HOST_CTRL1_HS_ENABLE (1 << 2)
//
+// SD Host Controler bits to HOST_CTRL2 register
+//
+#define SD_MMC_HC_CTRL_UHS_MASK 0x0007
+#define SD_MMC_HC_CTRL_UHS_SDR12 0x0000
+#define SD_MMC_HC_CTRL_UHS_SDR25 0x0001
+#define SD_MMC_HC_CTRL_UHS_SDR50 0x0002
+#define SD_MMC_HC_CTRL_UHS_SDR104 0x0003
+#define SD_MMC_HC_CTRL_UHS_DDR50 0x0004
+#define SD_MMC_HC_CTRL_MMC_DDR52 0x0004
+#define SD_MMC_HC_CTRL_MMC_SDR50 0x0002
+#define SD_MMC_HC_CTRL_MMC_SDR25 0x0001
+#define SD_MMC_HC_CTRL_MMC_SDR12 0x0000
+#define SD_MMC_HC_CTRL_HS200 0x0003
+#define SD_MMC_HC_CTRL_HS400 0x0005
+
+//
+// Timing modes for uhs
+//
+typedef enum {
+ SdMmcUhsSdr12,
+ SdMmcUhsSdr25,
+ SdMmcUhsSdr50,
+ SdMmcUhsSdr104,
+ SdMmcUhsDdr50,
+ SdMmcMmcDdr52,
+ SdMmcMmcSdr50,
+ SdMmcMmcSdr25,
+ SdMmcMmcSdr12,
+ SdMmcMmcHs200,
+ SdMmcMmcHs400,
+} SD_MMC_UHS_TIMING;
+
+//
// The transfer modes supported by SD Host Controller
// Simplified Spec 3.0 Table 1-2
//
@@ -513,4 +546,21 @@ SdMmcHcInitTimeoutCtrl (
IN UINT8 Slot
);
+/**
+ Set SD Host Controler control 2 registry according to selected speed.
+
+ @param[in] PciIo The PCI IO protocol instance.
+ @param[in] Slot The slot number of the SD card to send the command to.
+ @param[in] Timing The timing to select.
+
+ @retval EFI_SUCCESS The timing is set successfully.
+ @retval Others The timing isn't set successfully.
+**/
+EFI_STATUS
+SdMmcHcUhsSignaling (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT8 Slot,
+ IN SD_MMC_UHS_TIMING Timing
+ );
+
#endif
diff --git a/MdeModulePkg/Include/Protocol/SdMmcOverride.h b/MdeModulePkg/Include/Protocol/SdMmcOverride.h
index 0766252..a7a57e8 100644
--- a/MdeModulePkg/Include/Protocol/SdMmcOverride.h
+++ b/MdeModulePkg/Include/Protocol/SdMmcOverride.h
@@ -17,6 +17,7 @@
#ifndef __SD_MMC_OVERRIDE_H__
#define __SD_MMC_OVERRIDE_H__
+#include <Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h>
#include <Protocol/SdMmcPassThru.h>
#define EDKII_SD_MMC_OVERRIDE_PROTOCOL_GUID \
@@ -77,6 +78,27 @@ EFI_STATUS
IN EDKII_SD_MMC_PHASE_TYPE PhaseType
);
+/**
+
+ Override function for uhs signaling
+
+ @param[in] ControllerHandle The EFI_HANDLE of the controller.
+ @param[in] Slot The 0 based slot index.
+ @param[in] Timing The timing which should be set by
+ host controller.
+
+ @retval EFI_SUCCESS The override function completed successfully.
+ @retval EFI_NOT_FOUND The specified controller or slot does not exist.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EDKII_SD_MMC_UHS_SIGNALING) (
+ IN EFI_HANDLE ControllerHandle,
+ IN UINT8 Slot,
+ IN SD_MMC_UHS_TIMING Timing
+ );
+
struct _EDKII_SD_MMC_OVERRIDE {
//
// Protocol version of this implementation
@@ -90,6 +112,10 @@ struct _EDKII_SD_MMC_OVERRIDE {
// Callback to invoke SD/MMC override hooks
//
EDKII_SD_MMC_NOTIFY_PHASE NotifyPhase;
+ //
+ // Callback to override SD/MMC host controller uhs signaling
+ //
+ EDKII_SD_MMC_UHS_SIGNALING UhsSignaling;
};
extern EFI_GUID gEdkiiSdMmcOverrideProtocolGuid;
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
index b3903b4..d285249 100755
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
@@ -740,10 +740,13 @@ EmmcSwitchToHighSpeed (
IN UINT8 BusWidth
)
{
- EFI_STATUS Status;
- UINT8 HsTiming;
- UINT8 HostCtrl1;
- UINT8 HostCtrl2;
+ EFI_STATUS Status;
+ UINT8 HsTiming;
+ UINT8 HostCtrl1;
+ SD_MMC_UHS_TIMING Timing;
+ SD_MMC_HC_PRIVATE_DATA *Private;
+
+ Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusWidth);
if (EFI_ERROR (Status)) {
@@ -758,27 +761,36 @@ EmmcSwitchToHighSpeed (
return Status;
}
- //
- // Clean UHS Mode Select field of Host Control 2 reigster before update
- //
- HostCtrl2 = (UINT8)~0x7;
- Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Set UHS Mode Select field of Host Control 2 reigster to SDR12/25/50
- //
if (IsDdr) {
- HostCtrl2 = BIT2;
+ Timing = SdMmcMmcDdr52;
} else if (ClockFreq == 52) {
- HostCtrl2 = BIT0;
+ Timing = SdMmcMmcSdr50;
+ } else if (ClockFreq == 26) {
+ Timing = SdMmcMmcSdr25;
} else {
- HostCtrl2 = 0;
+ Timing = SdMmcMmcSdr12;
}
- Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
- if (EFI_ERROR (Status)) {
- return Status;
+
+ if (mOverride != NULL && mOverride->UhsSignaling != NULL) {
+ Status = mOverride->UhsSignaling (
+ Private->ControllerHandle,
+ Slot,
+ Timing
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: SD/MMC uhs signaling notifier callback failed - %r\n",
+ __FUNCTION__,
+ Status
+ ));
+ return Status;
+ }
+ } else {
+ Status = SdMmcHcUhsSignaling (PciIo, Slot, Timing);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
}
HsTiming = 1;
@@ -814,10 +826,13 @@ EmmcSwitchToHS200 (
IN UINT8 BusWidth
)
{
- EFI_STATUS Status;
- UINT8 HsTiming;
- UINT8 HostCtrl1;
- UINT8 HostCtrl2;
+ EFI_STATUS Status;
+ UINT8 HsTiming;
+ UINT8 HostCtrl1;
+ SD_MMC_UHS_TIMING Timing;
+ SD_MMC_HC_PRIVATE_DATA *Private;
+
+ Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
if ((BusWidth != 4) && (BusWidth != 8)) {
return EFI_INVALID_PARAMETER;
@@ -835,21 +850,29 @@ EmmcSwitchToHS200 (
if (EFI_ERROR (Status)) {
return Status;
}
- //
- // Clean UHS Mode Select field of Host Control 2 reigster before update
- //
- HostCtrl2 = (UINT8)~0x7;
- Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Set UHS Mode Select field of Host Control 2 reigster to SDR104
- //
- HostCtrl2 = BIT0 | BIT1;
- Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
- if (EFI_ERROR (Status)) {
- return Status;
+
+ Timing = SdMmcMmcHs200;
+
+ if (mOverride != NULL && mOverride->UhsSignaling != NULL) {
+ Status = mOverride->UhsSignaling (
+ Private->ControllerHandle,
+ Slot,
+ Timing
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: SD/MMC uhs signaling notifier callback failed - %r\n",
+ __FUNCTION__,
+ Status
+ ));
+ return Status;
+ }
+ } else {
+ Status = SdMmcHcUhsSignaling (PciIo, Slot, Timing);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
}
HsTiming = 2;
@@ -888,9 +911,12 @@ EmmcSwitchToHS400 (
IN UINT32 ClockFreq
)
{
- EFI_STATUS Status;
- UINT8 HsTiming;
- UINT8 HostCtrl2;
+ EFI_STATUS Status;
+ UINT8 HsTiming;
+ SD_MMC_UHS_TIMING Timing;
+ SD_MMC_HC_PRIVATE_DATA *Private;
+
+ Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq, 8);
if (EFI_ERROR (Status)) {
@@ -911,21 +937,29 @@ EmmcSwitchToHS400 (
if (EFI_ERROR (Status)) {
return Status;
}
- //
- // Clean UHS Mode Select field of Host Control 2 reigster before update
- //
- HostCtrl2 = (UINT8)~0x7;
- Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Set UHS Mode Select field of Host Control 2 reigster to HS400
- //
- HostCtrl2 = BIT0 | BIT2;
- Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
- if (EFI_ERROR (Status)) {
- return Status;
+
+ Timing = SdMmcMmcHs400;
+
+ if (mOverride != NULL && mOverride->UhsSignaling != NULL) {
+ Status = mOverride->UhsSignaling (
+ Private->ControllerHandle,
+ Slot,
+ Timing
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: SD/MMC uhs signaling notifier callback failed - %r\n",
+ __FUNCTION__,
+ Status
+ ));
+ return Status;
+ }
+ } else {
+ Status = SdMmcHcUhsSignaling (PciIo, Slot, Timing);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
}
HsTiming = 3;
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
index 8c93933..f45a367 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
@@ -784,8 +784,8 @@ SdCardSetBusMode (
UINT8 BusWidth;
UINT8 AccessMode;
UINT8 HostCtrl1;
- UINT8 HostCtrl2;
UINT8 SwitchResp[64];
+ SD_MMC_UHS_TIMING Timing;
SD_MMC_HC_PRIVATE_DATA *Private;
Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
@@ -817,18 +817,23 @@ SdCardSetBusMode (
if (S18A && (Capability->Sdr104 != 0) && ((SwitchResp[13] & BIT3) != 0)) {
ClockFreq = 208;
AccessMode = 3;
+ Timing = SdMmcUhsSdr104;
} else if (S18A && (Capability->Sdr50 != 0) && ((SwitchResp[13] & BIT2) != 0)) {
ClockFreq = 100;
AccessMode = 2;
+ Timing = SdMmcUhsSdr50;
} else if (S18A && (Capability->Ddr50 != 0) && ((SwitchResp[13] & BIT4) != 0)) {
ClockFreq = 50;
AccessMode = 4;
+ Timing = SdMmcUhsDdr50;
} else if ((SwitchResp[13] & BIT1) != 0) {
ClockFreq = 50;
AccessMode = 1;
+ Timing = SdMmcUhsSdr25;
} else {
ClockFreq = 25;
AccessMode = 0;
+ Timing = SdMmcUhsSdr12;
}
Status = SdCardSwitch (PassThru, Slot, AccessMode, 0xF, 0xF, 0xF, TRUE, SwitchResp);
@@ -854,15 +859,26 @@ SdCardSetBusMode (
}
}
- HostCtrl2 = (UINT8)~0x7;
- Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- HostCtrl2 = AccessMode;
- Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
- if (EFI_ERROR (Status)) {
- return Status;
+ if (mOverride != NULL && mOverride->UhsSignaling != NULL) {
+ Status = mOverride->UhsSignaling (
+ Private->ControllerHandle,
+ Slot,
+ Timing
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: SD/MMC uhs signaling notifier callback failed - %r\n",
+ __FUNCTION__,
+ Status
+ ));
+ return Status;
+ }
+ } else {
+ Status = SdMmcHcUhsSignaling (PciIo, Slot, Timing);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
}
Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, *Capability);
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
index 9672b5b..95627da 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
@@ -1133,6 +1133,75 @@ SdMmcHcInitHost (
}
/**
+ Set SD Host Controler control 2 registry according to selected speed.
+
+ @param[in] PciIo The PCI IO protocol instance.
+ @param[in] Slot The slot number of the SD card to send the command to.
+ @param[in] Timing The timing to select.
+
+ @retval EFI_SUCCESS The timing is set successfully.
+ @retval Others The timing isn't set successfully.
+**/
+EFI_STATUS
+SdMmcHcUhsSignaling (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT8 Slot,
+ IN SD_MMC_UHS_TIMING Timing
+ )
+{
+ EFI_STATUS Status;
+ UINT8 HostCtrl2;
+
+ HostCtrl2 = (UINT8)~SD_MMC_HC_CTRL_UHS_MASK;
+ Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ switch (Timing) {
+ case SdMmcUhsSdr12:
+ HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR12;
+ break;
+ case SdMmcUhsSdr25:
+ HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR25;
+ break;
+ case SdMmcUhsSdr50:
+ HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR50;
+ break;
+ case SdMmcUhsSdr104:
+ HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR104;
+ break;
+ case SdMmcUhsDdr50:
+ HostCtrl2 = SD_MMC_HC_CTRL_UHS_DDR50;
+ break;
+ case SdMmcMmcDdr52:
+ HostCtrl2 = SD_MMC_HC_CTRL_MMC_DDR52;
+ break;
+ case SdMmcMmcSdr50:
+ HostCtrl2 = SD_MMC_HC_CTRL_MMC_SDR50;
+ break;
+ case SdMmcMmcSdr25:
+ HostCtrl2 = SD_MMC_HC_CTRL_MMC_SDR25;
+ break;
+ case SdMmcMmcSdr12:
+ HostCtrl2 = SD_MMC_HC_CTRL_MMC_SDR12;
+ break;
+ case SdMmcMmcHs200:
+ HostCtrl2 = SD_MMC_HC_CTRL_HS200;
+ break;
+ case SdMmcMmcHs400:
+ HostCtrl2 = SD_MMC_HC_CTRL_HS400;
+ break;
+ default:
+ HostCtrl2 = 0;
+ break;
+ }
+ Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
+
+ return Status;
+}
+
+/**
Turn on/off LED.
@param[in] PciIo The PCI IO protocol instance.
--
2.7.4
next prev parent reply other threads:[~2018-09-03 4:54 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-03 4:54 [PATCH 0/7] SdMmc fixes and SdMmcOverride extension Marcin Wojtas
2018-09-03 4:54 ` [PATCH 1/7] MdeModulePkg/SdMmcPciHcDxe: Fix HS200 operation Marcin Wojtas
2018-09-03 4:54 ` Marcin Wojtas [this message]
2018-09-03 4:54 ` [PATCH 3/7] MdeModulePkg/SdMmcPciHcDxe: Add SwitchClockFreqPost to SdMmcOverride Marcin Wojtas
2018-09-03 4:54 ` [PATCH 4/7] MdeModulePkg/SdMmcPciHcDxe: Allow overriding base clock frequency Marcin Wojtas
2018-09-03 4:54 ` [PATCH 5/7] MdeModulePkg/SdMmcPciHcDxe: Adjust eMMC clock and bus width sequence Marcin Wojtas
2018-09-03 4:54 ` [PATCH 6/7] MdeModulePkg/SdMmcPciHcDxe: Fix SdMmcHcReset to set only necesery bits Marcin Wojtas
2018-09-03 4:54 ` [PATCH 7/7] MdeModulePkg/SdMmcPciHcDxe: Execute card detect only for RemovableSlot Marcin Wojtas
2018-09-05 6:29 ` [PATCH 0/7] SdMmc fixes and SdMmcOverride extension Wu, Hao A
2018-09-06 14:12 ` Ard Biesheuvel
2018-09-06 14:17 ` Marcin Wojtas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1535950453-27147-3-git-send-email-mw@semihalf.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox