U-Boot's i.MX uSDHC probe calls fsl_esdhc_init(), which resets the controller and programs INT_STATUS_EN. It then calls esdhc_init_common(), which issues a second RSTA and only clears the BRR/BWR status enables afterward.
The generic SDHCI reset clears QEMU's normal and error status-enable fields. Consequently, the second RSTA removes command-complete, transfer-complete, DMA, and error enables. Commands still reach the card, but QEMU does not latch completion status, so U-Boot times out and fails to expose an MMC block device. Preserve the normal and error status-enable fields around RSTA in the i.MX uSDHC register path. Signal enables still follow the generic reset because U-Boot disables interrupt signaling and polls INT_STATUS. The IMX6ULRM describes RSTA as clearing read-write state and does not document INT_STATUS_EN as reset-persistent. Treat this as compatibility with U-Boot's established two-reset initialization sequence rather than as behavior directly specified by the reference manual. Signed-off-by: Bin Meng <[email protected]> --- (no changes since v1) hw/sd/sdhci.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index b6e447a805..4d7bbdbe7a 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -1822,6 +1822,7 @@ static void sdhci_bus_class_init(ObjectClass *klass, const void *data) #define ESDHC_TUNING_CTRL 0xcc #define ESDHC_TUNE_CTRL_STATUS 0x68 #define ESDHC_WTMK_LVL 0x44 +#define ESDHC_SYSCTL_RSTA BIT(24) /* Undocumented register used by guests working around erratum ERR004536 */ #define ESDHC_UNDOCUMENTED_REG27 0x6c @@ -2117,6 +2118,32 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) sdhci_write(opaque, offset, val | s->trnmod, size); break; + case SDHC_CLKCON: + if (value & ESDHC_SYSCTL_RSTA) { + uint16_t norintstsen = s->norintstsen; + uint16_t errintstsen = s->errintstsen; + + esdhc_write(opaque, offset, val, size); + + /* + * U-Boot programs INT_STATUS_EN in fsl_esdhc_init(), then issues + * another RSTA from esdhc_init_common(). It only clears BRR/BWR + * after that reset and relies on the remaining enables while + * polling INT_STATUS for command, transfer, and error completion. + * + * The generic SDHCI reset clears both status-enable fields, + * leaving U-Boot with no completion status. Preserve them across + * this uSDHC-specific RSTA path. Signal enables still follow + * generic reset semantics because U-Boot disables interrupt + * signaling for polling. + */ + s->norintstsen = norintstsen; + s->errintstsen = errintstsen; + } else { + esdhc_write(opaque, offset, val, size); + } + break; + default: esdhc_write(opaque, offset, val, size); break; -- 2.53.0
