On Tue, Sep 22, 2026 at 1:33 AM Bernhard Beschow <[email protected]> wrote:
>
>
>
> Am 4. September 2026 16:14:29 UTC schrieb Bin Meng 
> <[email protected]>:
> >U-Boot's i.MX uSDHC driver enables IPGEN, HCKEN, PEREN and CKEN in
> >VEND_SPEC rather than the standard SDHCI clock-control fields. QEMU
> >only checks the standard fields before issuing a command. It therefore
> >silently drops U-Boot's MMC commands even though the controller clocks
> >are enabled. U-Boot eventually times out waiting for command completion
> >and cannot load the kernel and device tree from the SD card.
> >
> >Accept the complete vendor clock-gate set as another valid clock source
> >for i.MX uSDHC. Also report SDSTB when the vendor IP and host clocks
> >are enabled, matching the state U-Boot polls while changing the clock.
> >
> >Keep this behavior behind an i.MX uSDHC quirk because the shared eSDHC
> >paths also serve controllers which use the standard SDHCI fields.
> >
> >Reference: IMX6ULRM (Rev 2), section 56.8.10, 56.8.12 and 56.8.26
> >https://www.nxp.com/webapp/Download?colCode=IMX6ULRM
> >
> >Signed-off-by: Bin Meng <[email protected]>
> >Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
> >
> >---
> >
> >Changes in v2:
> >- rebase on top of the microchip polarfire soc series
> >
> > include/hw/sd/sdhci.h |  7 ++++++-
> > hw/sd/sdhci.c         | 27 ++++++++++++++++++++++++---
> > 2 files changed, 30 insertions(+), 4 deletions(-)
> >
> >diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
> >index 2d03e37653..83d465774b 100644
> >--- a/include/hw/sd/sdhci.h
> >+++ b/include/hw/sd/sdhci.h
> >@@ -112,7 +112,12 @@ typedef struct SDHCIState SDHCIState;
> >  * Controller does not provide transfer-complete interrupt when not
> >  * busy.
> >  */
> >-#define SDHCI_QUIRK_NO_BUSY_IRQ    BIT(0)
> >+#define SDHCI_QUIRK_NO_BUSY_IRQ          BIT(0)
> >+/*
> >+ * Controller uses vendor-specific clock gates in place of the standard
> >+ * SDHCI clock-control fields
> >+ */
> >+#define SDHCI_QUIRK_CLOCKS_IN_VENDOR     BIT(1)
> >
> > #define TYPE_PCI_SDHCI "sdhci-pci"
> > DECLARE_INSTANCE_CHECKER(SDHCIState, PCI_SDHCI,
> >diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
> >index 14c312a691..b6e447a805 100644
> >--- a/hw/sd/sdhci.c
> >+++ b/hw/sd/sdhci.c
> >@@ -1107,9 +1107,11 @@ static void sdhci_data_transfer(SDHCIState *s)
> >     }
> > }
> >
> >+static bool sdhci_clocks_on(SDHCIState *s);
> >+
> > static bool sdhci_can_issue_command(SDHCIState *s)
> > {
> >-    if (!SDHC_CLOCK_IS_ON(s->clkcon) ||
> >+    if (!sdhci_clocks_on(s) ||
> >         (((s->prnsts & SDHC_DATA_INHIBIT) || s->stopped_state) &&
> >         ((s->cmdreg & SDHC_CMD_DATA_PRESENT) ||
> >         ((s->cmdreg & SDHC_CMD_RESPONSE) == SDHC_CMD_RSP_WITH_BUSY &&
> >@@ -1810,6 +1812,10 @@ static void sdhci_bus_class_init(ObjectClass *klass, 
> >const void *data)
> >
> > #define ESDHC_VENDOR_SPEC               0xc0
> > #define ESDHC_FRC_SDCLK_ON              (1 << 8)
> >+#define ESDHC_VENDOR_IPGEN              (1 << 11)
> >+#define ESDHC_VENDOR_HCKEN              (1 << 12)
> >+#define ESDHC_VENDOR_PEREN              (1 << 13)
> >+#define ESDHC_VENDOR_CKEN               (1 << 14)
> >
> > #define ESDHC_DLL_CTRL                  0x60
> >
> >@@ -1826,6 +1832,16 @@ static void sdhci_bus_class_init(ObjectClass *klass, 
> >const void *data)
> > #define ESDHC_PRNSTS_SDSTB              (1 << 3)
> > #define ESDHC_PRNSTS_CLOCK_GATE_OFF     BIT(7)
> >
> >+static bool sdhci_clocks_on(SDHCIState *s)
> >+{
> >+    uint32_t vendor_clocks = ESDHC_VENDOR_IPGEN | ESDHC_VENDOR_HCKEN |
> >+                             ESDHC_VENDOR_PEREN | ESDHC_VENDOR_CKEN;
> >+
> >+    return SDHC_CLOCK_IS_ON(s->clkcon) ||
> >+           ((s->quirks & SDHCI_QUIRK_CLOCKS_IN_VENDOR) &&
> >+            (s->vendor_spec & vendor_clocks) == vendor_clocks);
> >+}
> >+
>
> Rather than accumulating vendor-specific quirks in generic code, can we not 
> remap in device-specific "virtual" methods such as usdhc_{read,write}?
>

Will do in v3.

Regards,
Bin

Reply via email to