@@ -1869,6 +1869,8 @@ static int test_ext_flash(QspiDev_t* dev)
18691869/* Standard SDHCI Software Reset is in the Clock/Timeout/Reset register */
18701870#define STD_SDHCI_RESET_REG 0x2C /* Clock Control / Timeout / SW Reset */
18711871#define STD_SDHCI_SRA (1U << 24) /* Software Reset for All */
1872+ #define STD_SDHCI_SRCMD (1U << 25) /* Software Reset for CMD Line */
1873+ #define STD_SDHCI_SRDAT (1U << 26) /* Software Reset for DAT Line */
18721874
18731875/* Handle reads from Cadence HRS registers (0x000-0x1FF) */
18741876static uint32_t zynqmp_sdhci_hrs_read (uint32_t hrs_offset )
@@ -1878,7 +1880,10 @@ static uint32_t zynqmp_sdhci_hrs_read(uint32_t hrs_offset)
18781880 switch (hrs_offset ) {
18791881 case 0x000 : /* HRS00 - Software Reset */
18801882 {
1881- /* Map standard SRA (bit 24 of 0x2C) to Cadence SWR (bit 0) */
1883+ /* Map standard SRA (bit 24 of 0x2C) to Cadence SWR (bit 0).
1884+ * SRA is safe because sdhci_platform_init() sets the slot type
1885+ * to "Embedded", so the controller accepts BP/SDCE writes after
1886+ * reset. */
18821887 uint32_t val = * ((volatile uint32_t * )(base + STD_SDHCI_RESET_REG ));
18831888 return (val & STD_SDHCI_SRA ) ? 1U : 0U ;
18841889 }
@@ -1898,7 +1903,12 @@ static void zynqmp_sdhci_hrs_write(uint32_t hrs_offset, uint32_t val)
18981903
18991904 switch (hrs_offset ) {
19001905 case 0x000 : /* HRS00 - Software Reset */
1901- if (val & 1U ) { /* SWR bit -> standard SRA */
1906+ if (val & 1U ) {
1907+ /* Issue SRA (Software Reset for All).
1908+ * This is safe because sdhci_platform_init() configures the
1909+ * IOU_SLCR slot type to "Embedded" before this reset, so the
1910+ * controller will accept Bus Power and SD Clock Enable writes
1911+ * during the subsequent initialization. */
19021912 uint32_t reg = * ((volatile uint32_t * )(base + STD_SDHCI_RESET_REG ));
19031913 reg |= STD_SDHCI_SRA ;
19041914 * ((volatile uint32_t * )(base + STD_SDHCI_RESET_REG )) = reg ;
@@ -1940,26 +1950,51 @@ void sdhci_reg_write(uint32_t offset, uint32_t val)
19401950/* Platform initialization - called from sdhci_init()
19411951 * FSBL already initializes the SD controller on ZynqMP when booting from SD,
19421952 * so we don't need to configure clocks/reset (CRL_APB registers).
1943- * We verify the SDHCI controller is accessible via standard register reads. */
1953+ *
1954+ * However, the FSBL uses GPIO-based card detect (polling MIO45 as GPIO)
1955+ * rather than the SDHCI controller's built-in CD mechanism. The default
1956+ * IOU_SLCR SD_CONFIG_REG2 slot type is "Removable" (00), but MIO45 is not
1957+ * routed to the SDHCI controller as a CD function. This causes the Arasan
1958+ * SDHCI to report Card Inserted=0 and gate writes to Bus Power and SD Clock
1959+ * Enable registers.
1960+ *
1961+ * Fix: Set SD1 slot type to "Embedded" (01) in IOU_SLCR SD_CONFIG_REG2.
1962+ * This makes the controller always assert Card Inserted and Card State
1963+ * Stable, allowing normal SDHCI register access. */
19441964void sdhci_platform_init (void )
19451965{
1966+ uint32_t reg ;
1967+
1968+ /* Set SD1 slot type to "Embedded Slot for One Device" (01).
1969+ * This feeds into the SDHCI Capabilities register bits 31:30 and makes
1970+ * the controller report card as always present, bypassing the physical
1971+ * CD pin that is not connected to the SDHCI controller on ZCU102. */
1972+ reg = IOU_SLCR_SD_CONFIG_REG2 ;
1973+ reg &= ~SD_CONFIG_REG2_SD1_SLOTTYPE_MASK ;
1974+ reg |= (1UL << SD_CONFIG_REG2_SD1_SLOTTYPE_SHIFT ); /* 01 = Embedded */
1975+ IOU_SLCR_SD_CONFIG_REG2 = reg ;
1976+
19461977#ifdef DEBUG_SDHCI
1947- volatile uint8_t * base = (volatile uint8_t * )ZYNQMP_SDHCI_BASE ;
1948- uint32_t val ;
1978+ {
1979+ volatile uint8_t * base = (volatile uint8_t * )ZYNQMP_SDHCI_BASE ;
1980+ uint32_t val ;
19491981
1950- wolfBoot_printf ("sdhci_platform_init: SD%d at 0x%x\n" ,
1951- (ZYNQMP_SDHCI_BASE == ZYNQMP_SD0_BASE ) ? 0 : 1 ,
1952- (unsigned int )ZYNQMP_SDHCI_BASE );
1982+ wolfBoot_printf ("sdhci_platform_init: SD%d at 0x%x\n" ,
1983+ (ZYNQMP_SDHCI_BASE == ZYNQMP_SD0_BASE ) ? 0 : 1 ,
1984+ (unsigned int )ZYNQMP_SDHCI_BASE );
19531985
1954- /* Read standard SDHCI registers to verify controller access */
1955- val = * ((volatile uint32_t * )(base + 0x24 )); /* Present State */
1956- wolfBoot_printf (" Present State: 0x%x\n" , (unsigned int )val );
1986+ wolfBoot_printf (" SD_CONFIG_REG2: 0x%x\n" ,
1987+ (unsigned int )IOU_SLCR_SD_CONFIG_REG2 );
19571988
1958- val = * ((volatile uint32_t * )(base + 0x40 )); /* Capabilities */
1959- wolfBoot_printf (" Capabilities: 0x%x\n" , (unsigned int )val );
1960- (void )val ;
1989+ /* Read standard SDHCI registers to verify controller access */
1990+ val = * ((volatile uint32_t * )(base + 0x24 )); /* Present State */
1991+ wolfBoot_printf (" Present State: 0x%x\n" , (unsigned int )val );
1992+
1993+ val = * ((volatile uint32_t * )(base + 0x40 )); /* Capabilities */
1994+ wolfBoot_printf (" Capabilities: 0x%x\n" , (unsigned int )val );
1995+ (void )val ;
1996+ }
19611997#endif
1962- /* FSBL already configured SD1 - no clock/reset setup needed */
19631998}
19641999
19652000/* Platform interrupt setup - called from sdhci_init()
@@ -1971,7 +2006,7 @@ void sdhci_platform_irq_init(void)
19712006#endif
19722007}
19732008
1974- /* Platform bus mode selection - called from sdhci_init() */
2009+ /* Platform bus mode selection - called from sdhci_init() after software reset */
19752010void sdhci_platform_set_bus_mode (int is_emmc )
19762011{
19772012 (void )is_emmc ;
0 commit comments