U-Boot's i.MX uSDHC probe calls fsl_esdhc_init(), which resets the
controller and programs INT_STATUS_EN. esdhc_init_common() is then
called, 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]>

---

Changes in v3:
- Preserve status enables for byte, halfword and word RSTA writes
- Integrate RSTA handling with the uSDHC clock translation

 hw/sd/sdhci.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 40cf407876..3bcad3e518 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1840,6 +1840,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
@@ -2127,7 +2128,22 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, 
unsigned size)
         return;
     }
     if ((offset & ~3) == SDHC_CLKCON) {
+        uint16_t norintstsen = s->norintstsen;
+        uint16_t errintstsen = s->errintstsen;
+        bool reset_all = (val << ((offset & 3) * 8)) & ESDHC_SYSCTL_RSTA;
+
         esdhc_write(opaque, offset, val, size);
+        if (reset_all) {
+            /*
+             * U-Boot programs INT_STATUS_EN before issuing another RSTA.
+             * Preserve status enables for this initialization sequence.
+             * Signal enables and pending status retain generic reset
+             * semantics. This compatibility behavior is not specified
+             * by the reference manual.
+             */
+            s->norintstsen = norintstsen;
+            s->errintstsen = errintstsen;
+        }
         return;
     }
     if ((offset & ~3) == SDHC_TRNMOD) {
-- 
2.53.0


Reply via email to