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
