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,
hao.a.wu@intel.com, ard.biesheuvel@linaro.org,
nadavh@marvell.com, mw@semihalf.com, jsd@semihalf.com,
tm@semihalf.com
Subject: [PATCH v2 4/4] MdeModulePkg/SdMmcPciHcDxe: Allow overriding base clock frequency
Date: Fri, 5 Oct 2018 15:25:11 +0200 [thread overview]
Message-ID: <1538745911-22484-5-git-send-email-mw@semihalf.com> (raw)
In-Reply-To: <1538745911-22484-1-git-send-email-mw@semihalf.com>
Some SdMmc host controllers are run by clocks with different
frequency than it is reflected in Capabilities Register 1.
It is allowed by SDHCI specification ver. 4.2 - if BaseClkFreq
field value of the Capability Register 1 is zero, the clock
frequency must be obtained via another method.
Because the bitfield is only 8 bits wide, a maximum value
that could be obtained from hardware is 255MHz.
In case the actual frequency exceeds 255MHz, the 8-bit BaseClkFreq
member of SD_MMC_HC_SLOT_CAP structure occurs to be not sufficient
to be used for setting the clock speed in SdMmcHcClockSupply
function.
This patch adds new UINT32 array ('BaseClkFreq[]') to
SD_MMC_HC_PRIVATE_DATA structure for specifying
the input clock speed for each slot of the host controller.
All routines that are used for clock configuration are
updated accordingly.
This patch also adds new IN OUT BaseClockFreq field
in the Capability callback of the SdMmcOverride,
protocol which allows to update BaseClkFreq value.
The patch reuses original commit from edk2-platforms:
20f6f144d3a8 ("Marvell/Drivers: XenonDxe: Allow overriding base clock
frequency")
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
---
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h | 6 +++++
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h | 12 +++++----
MdeModulePkg/Include/Protocol/SdMmcOverride.h | 5 +++-
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c | 4 +--
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c | 4 +--
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.c | 18 +++++++++++--
MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c | 27 +++++++++++---------
7 files changed, 52 insertions(+), 24 deletions(-)
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
index c683600..8c1a589 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.h
@@ -118,6 +118,12 @@ typedef struct {
UINT64 MaxCurrent[SD_MMC_HC_MAX_SLOT];
UINT32 ControllerVersion;
+
+ //
+ // Some controllers may require to override base clock frequency
+ // value stored in Capabilities Register 1.
+ //
+ UINT32 BaseClkFreq[SD_MMC_HC_MAX_SLOT];
} SD_MMC_HC_PRIVATE_DATA;
#define SD_MMC_HC_TRB_SIG SIGNATURE_32 ('T', 'R', 'B', 'T')
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h
index a03160d..f01ba21 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h
@@ -173,12 +173,14 @@ typedef struct {
@param[in] Slot The slot number of the SD card to send the command to.
@param[in] Capability The buffer to store the capability data.
+ @param[in] BaseClkFreq The base clock frequency of host controller in MHz.
**/
VOID
DumpCapabilityReg (
IN UINT8 Slot,
- IN SD_MMC_HC_SLOT_CAP *Capability
+ IN SD_MMC_HC_SLOT_CAP *Capability,
+ IN UINT32 BaseClkFreq
);
/**
@@ -431,7 +433,7 @@ SdMmcHcStopClock (
@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] ClockFreq The max clock frequency to be set. The unit is KHz.
- @param[in] Capability The capability of the slot.
+ @param[in] BaseClkFreq The base clock frequency of host controller in MHz.
@retval EFI_SUCCESS The clock is supplied successfully.
@retval Others The clock isn't supplied successfully.
@@ -442,7 +444,7 @@ SdMmcHcClockSupply (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT8 Slot,
IN UINT64 ClockFreq,
- IN SD_MMC_HC_SLOT_CAP Capability
+ IN UINT32 BaseClkFreq
);
/**
@@ -490,7 +492,7 @@ SdMmcHcSetBusWidth (
@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] Capability The capability of the slot.
+ @param[in] BaseClkFreq The base clock frequency of host controller in MHz.
@retval EFI_SUCCESS The clock is supplied successfully.
@retval Others The clock isn't supplied successfully.
@@ -500,7 +502,7 @@ EFI_STATUS
SdMmcHcInitClockFreq (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT8 Slot,
- IN SD_MMC_HC_SLOT_CAP Capability
+ IN UINT32 BaseClkFreq
);
/**
diff --git a/MdeModulePkg/Include/Protocol/SdMmcOverride.h b/MdeModulePkg/Include/Protocol/SdMmcOverride.h
index d9daada..27023d3 100644
--- a/MdeModulePkg/Include/Protocol/SdMmcOverride.h
+++ b/MdeModulePkg/Include/Protocol/SdMmcOverride.h
@@ -43,6 +43,8 @@ typedef enum {
@param[in] ControllerHandle The EFI_HANDLE of the controller.
@param[in] Slot The 0 based slot index.
@param[in,out] SdMmcHcSlotCapability The SDHCI capability structure.
+ @param[in,out] BaseClkFreq The base clock frequency value that
+ optionally can be updated.
@retval EFI_SUCCESS The override function completed successfully.
@retval EFI_NOT_FOUND The specified controller or slot does not exist.
@@ -54,7 +56,8 @@ EFI_STATUS
(EFIAPI * EDKII_SD_MMC_CAPABILITY) (
IN EFI_HANDLE ControllerHandle,
IN UINT8 Slot,
- IN OUT VOID *SdMmcHcSlotCapability
+ IN OUT VOID *SdMmcHcSlotCapability,
+ IN OUT UINT32 *BaseClkFreq
);
/**
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
index 7e75283..27ccd63 100755
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
@@ -705,7 +705,7 @@ EmmcSwitchClockFreq (
//
// Convert the clock freq unit from MHz to KHz.
//
- Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, Private->Capability[Slot]);
+ Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, Private->BaseClkFreq[Slot]);
return Status;
}
@@ -1099,7 +1099,7 @@ EmmcSetBusMode (
return Status;
}
- ASSERT (Private->Capability[Slot].BaseClkFreq != 0);
+ ASSERT (Private->BaseClkFreq[Slot] != 0);
//
// Check if the Host Controller support 8bits bus width.
//
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
index 057a4e2..9ea13be 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
@@ -882,7 +882,7 @@ SdCardSetBusMode (
}
}
- Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, *Capability);
+ Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, Private->BaseClkFreq[Slot]);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -1081,7 +1081,7 @@ SdCardIdentification (
goto Error;
}
- SdMmcHcInitClockFreq (PciIo, Slot, Private->Capability[Slot]);
+ SdMmcHcInitClockFreq (PciIo, Slot, Private->BaseClkFreq[Slot]);
gBS->Stall (1000);
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.c
index bf9869d..d7cc0ce 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.c
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.c
@@ -625,18 +625,32 @@ SdMmcPciHcDriverBindingStart (
if (EFI_ERROR (Status)) {
continue;
}
+
+ Private->BaseClkFreq[Slot] = Private->Capability[Slot].BaseClkFreq;
+
if (mOverride != NULL && mOverride->Capability != NULL) {
Status = mOverride->Capability (
Controller,
Slot,
- &Private->Capability[Slot]);
+ &Private->Capability[Slot],
+ &Private->BaseClkFreq[Slot]
+ );
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "%a: Failed to override capability - %r\n",
__FUNCTION__, Status));
continue;
}
}
- DumpCapabilityReg (Slot, &Private->Capability[Slot]);
+
+ //
+ // According to SDHCI specification ver. 4.2, BaseClkFreq field value of
+ // the Capability Register 1 can be zero, which means a need for obtaining
+ // the clock frequency via another method. Fail in case it is not updated
+ // by SW at this point.
+ //
+ ASSERT (Private->BaseClkFreq[Slot] != 0);
+
+ DumpCapabilityReg (Slot, &Private->Capability[Slot], Private->BaseClkFreq[Slot]);
Support64BitDma &= Private->Capability[Slot].SysBus64;
diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
index 38d6202..9f50754 100644
--- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
+++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
@@ -22,12 +22,14 @@
@param[in] Slot The slot number of the SD card to send the command to.
@param[in] Capability The buffer to store the capability data.
+ @param[in] BaseClkFreq The base clock frequency of host controller in MHz.
**/
VOID
DumpCapabilityReg (
IN UINT8 Slot,
- IN SD_MMC_HC_SLOT_CAP *Capability
+ IN SD_MMC_HC_SLOT_CAP *Capability,
+ IN UINT32 BaseClkFreq
)
{
//
@@ -35,7 +37,10 @@ DumpCapabilityReg (
//
DEBUG ((DEBUG_INFO, " == Slot [%d] Capability is 0x%x ==\n", Slot, Capability));
DEBUG ((DEBUG_INFO, " Timeout Clk Freq %d%a\n", Capability->TimeoutFreq, (Capability->TimeoutUnit) ? "MHz" : "KHz"));
- DEBUG ((DEBUG_INFO, " Base Clk Freq %dMHz\n", Capability->BaseClkFreq));
+ if (Capability->BaseClkFreq != BaseClkFreq) {
+ DEBUG ((DEBUG_INFO, " Controller register value overriden:\n"));
+ }
+ DEBUG ((DEBUG_INFO, " Base Clk Freq %dMHz\n", BaseClkFreq));
DEBUG ((DEBUG_INFO, " Max Blk Len %dbytes\n", 512 * (1 << Capability->MaxBlkLen)));
DEBUG ((DEBUG_INFO, " 8-bit Support %a\n", Capability->BusWidth8 ? "TRUE" : "FALSE"));
DEBUG ((DEBUG_INFO, " ADMA2 Support %a\n", Capability->Adma2 ? "TRUE" : "FALSE"));
@@ -721,7 +726,7 @@ SdMmcHcStopClock (
@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] ClockFreq The max clock frequency to be set. The unit is KHz.
- @param[in] Capability The capability of the slot.
+ @param[in] BaseClkFreq The base clock frequency of host controller in MHz.
@retval EFI_SUCCESS The clock is supplied successfully.
@retval Others The clock isn't supplied successfully.
@@ -732,11 +737,10 @@ SdMmcHcClockSupply (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT8 Slot,
IN UINT64 ClockFreq,
- IN SD_MMC_HC_SLOT_CAP Capability
+ IN UINT32 BaseClkFreq
)
{
EFI_STATUS Status;
- UINT32 BaseClkFreq;
UINT32 SettingFreq;
UINT32 Divisor;
UINT32 Remainder;
@@ -746,9 +750,8 @@ SdMmcHcClockSupply (
//
// Calculate a divisor for SD clock frequency
//
- ASSERT (Capability.BaseClkFreq != 0);
+ ASSERT (BaseClkFreq != 0);
- BaseClkFreq = Capability.BaseClkFreq;
if (ClockFreq == 0) {
return EFI_INVALID_PARAMETER;
}
@@ -939,7 +942,7 @@ SdMmcHcSetBusWidth (
@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] Capability The capability of the slot.
+ @param[in] BaseClkFreq The base clock frequency of host controller in MHz.
@retval EFI_SUCCESS The clock is supplied successfully.
@retval Others The clock isn't supplied successfully.
@@ -949,7 +952,7 @@ EFI_STATUS
SdMmcHcInitClockFreq (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT8 Slot,
- IN SD_MMC_HC_SLOT_CAP Capability
+ IN UINT32 BaseClkFreq
)
{
EFI_STATUS Status;
@@ -958,7 +961,7 @@ SdMmcHcInitClockFreq (
//
// Calculate a divisor for SD clock frequency
//
- if (Capability.BaseClkFreq == 0) {
+ if (BaseClkFreq == 0) {
//
// Don't support get Base Clock Frequency information via another method
//
@@ -968,7 +971,7 @@ SdMmcHcInitClockFreq (
// Supply 400KHz clock frequency at initialization phase.
//
InitFreq = 400;
- Status = SdMmcHcClockSupply (PciIo, Slot, InitFreq, Capability);
+ Status = SdMmcHcClockSupply (PciIo, Slot, InitFreq, BaseClkFreq);
return Status;
}
@@ -1102,7 +1105,7 @@ SdMmcHcInitHost (
PciIo = Private->PciIo;
Capability = Private->Capability[Slot];
- Status = SdMmcHcInitClockFreq (PciIo, Slot, Capability);
+ Status = SdMmcHcInitClockFreq (PciIo, Slot, Private->BaseClkFreq[Slot]);
if (EFI_ERROR (Status)) {
return Status;
}
--
2.7.4
next prev parent reply other threads:[~2018-10-05 13:25 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-05 13:25 [PATCH v2 0/4] SdMmcOverride extension Marcin Wojtas
2018-10-05 13:25 ` [PATCH v2 1/4] MdeModulePkg/SdMmcPciHcDxe: Add an optional parameter in NotifyPhase Marcin Wojtas
2018-10-08 12:21 ` Ard Biesheuvel
2018-10-05 13:25 ` [PATCH v2 2/4] MdeModulePkg/SdMmcPciHcDxe: Add UhsSignaling to SdMmcOverride protocol Marcin Wojtas
2018-10-05 15:12 ` Philippe Mathieu-Daudé
2018-10-05 15:17 ` Marcin Wojtas
2018-10-08 12:41 ` Ard Biesheuvel
2018-10-08 12:59 ` Marcin Wojtas
2018-10-08 13:07 ` Ard Biesheuvel
2018-10-08 13:17 ` Marcin Wojtas
2018-10-08 13:27 ` Ard Biesheuvel
2018-10-08 13:37 ` Marcin Wojtas
2018-10-08 13:43 ` Ard Biesheuvel
2018-10-08 14:52 ` Marcin Wojtas
2018-10-08 15:10 ` Ard Biesheuvel
2018-10-09 11:22 ` Wu, Hao A
2018-10-09 11:32 ` Marcin Wojtas
2018-10-09 11:45 ` Ard Biesheuvel
2018-10-09 11:51 ` Marcin Wojtas
2018-10-11 15:43 ` Marcin Wojtas
2018-10-12 1:39 ` Wu, Hao A
2018-10-12 5:06 ` Marcin Wojtas
2018-10-12 15:55 ` Ard Biesheuvel
2018-10-12 16:04 ` Marcin Wojtas
2018-10-12 16:24 ` Ard Biesheuvel
2018-10-12 16:49 ` Marcin Wojtas
2018-11-01 7:04 ` Wu, Hao A
2018-11-02 8:21 ` Marcin Wojtas
2018-11-02 12:16 ` Marcin Wojtas
2018-11-03 2:57 ` Wu, Hao A
2018-10-05 13:25 ` [PATCH v2 3/4] MdeModulePkg/SdMmcPciHcDxe: Add SwitchClockFreqPost to SdMmcOverride Marcin Wojtas
2018-10-08 12:44 ` Ard Biesheuvel
2018-11-01 7:06 ` Wu, Hao A
2018-11-02 9:39 ` Marcin Wojtas
2018-11-03 3:19 ` Wu, Hao A
2018-10-05 13:25 ` Marcin Wojtas [this message]
2018-10-08 12:49 ` [PATCH v2 4/4] MdeModulePkg/SdMmcPciHcDxe: Allow overriding base clock frequency Ard Biesheuvel
2018-11-01 7:11 ` Wu, Hao A
2018-11-02 9:52 ` Marcin Wojtas
2018-10-12 5:24 ` [PATCH v2 0/4] SdMmcOverride extension Wu, Hao A
2018-10-12 5:33 ` Marcin Wojtas
2018-10-12 12:48 ` Wu, Hao A
2018-10-12 12:50 ` Marcin Wojtas
2018-10-25 12:43 ` Marcin Wojtas
2018-10-26 7:22 ` Wu, Hao A
2018-11-01 7:11 ` Wu, Hao A
2018-11-02 10:09 ` 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=1538745911-22484-5-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