@@ -585,6 +585,16 @@ static uint32_t sdhci_get_response_type(uint8_t resp_type)
585585
586586#define DEVICE_BUSY 1
587587
588+ /* When an earlier boot stage owns the controller (skip host reset), engage
589+ * per-command line-reset recovery; the other targets still soft-reset at init. */
590+ #if defined(SDHCI_SKIP_HOST_RESET ) && ((SDHCI_SKIP_HOST_RESET + 0 ) != 0 )
591+ #define SDHCI_SKIP_HOST_RESET_ENABLED
592+ #endif
593+
594+ /* Set only while sdhci_init() runs the card-identification sequence. */
595+ static int sdhci_in_init = 0 ;
596+
597+ #ifdef SDHCI_SKIP_HOST_RESET_ENABLED
588598static int sdhci_reset_cmd_line (void )
589599{
590600 uint32_t timeout = 0x000FFFFF ;
@@ -595,6 +605,7 @@ static int sdhci_reset_cmd_line(void)
595605
596606 return (timeout > 0U ) ? 0 : -1 ;
597607}
608+ #endif
598609
599610static int sdhci_send_cmd_internal (uint32_t cmd_type ,
600611 uint32_t cmd_index , uint32_t cmd_arg , uint8_t resp_type )
@@ -609,7 +620,16 @@ static int sdhci_send_cmd_internal(uint32_t cmd_type,
609620#endif
610621
611622 /* wait for command line to be idle */
612- while ((SDHCI_REG (SDHCI_SRS09 ) & SDHCI_SRS09_CICMD ) != 0 );
623+ while (((SDHCI_REG (SDHCI_SRS09 ) & SDHCI_SRS09_CICMD ) != 0U ) &&
624+ (-- timeout > 0U )) {}
625+ if (timeout == 0U ) {
626+ wolfBoot_printf ("sdhci_send_cmd: command inhibit timeout on entry\n" );
627+ #ifdef SDHCI_SKIP_HOST_RESET_ENABLED
628+ if (sdhci_reset_cmd_line () != 0 )
629+ wolfBoot_printf ("sdhci_send_cmd: command line reset timeout\n" );
630+ #endif
631+ }
632+ timeout = 0x000FFFFF ;
613633
614634 /* set command argument and command transfer registers */
615635 SDHCI_REG_SET (SDHCI_SRS02 , cmd_arg );
@@ -635,8 +655,10 @@ static int sdhci_send_cmd_internal(uint32_t cmd_type,
635655 "error SRS12=0x%08X\n" ,
636656 cmd_index , cmd_arg , resp_type , SDHCI_REG (SDHCI_SRS12 ));
637657 status = -1 ; /* error */
658+ #ifdef SDHCI_SKIP_HOST_RESET_ENABLED
638659 if (sdhci_reset_cmd_line () != 0 )
639660 wolfBoot_printf ("sdhci_send_cmd: command line reset timeout\n" );
661+ #endif
640662 }
641663
642664 SDHCI_REG_SET (SDHCI_SRS12 , SDHCI_SRS12_CC ); /* clear command complete */
@@ -646,8 +668,10 @@ static int sdhci_send_cmd_internal(uint32_t cmd_type,
646668 if (timeout == 0U ) {
647669 wolfBoot_printf ("sdhci_send_cmd: command inhibit timeout\n" );
648670 status = -1 ;
671+ #ifdef SDHCI_SKIP_HOST_RESET_ENABLED
649672 if (sdhci_reset_cmd_line () != 0 )
650673 wolfBoot_printf ("sdhci_send_cmd: command line reset timeout\n" );
674+ #endif
651675 }
652676
653677 if (status == 0 ) {
@@ -661,8 +685,11 @@ static int sdhci_send_cmd_internal(uint32_t cmd_type,
661685 }
662686 }
663687
664- #if SDHCI_WAIT_AFTER_CMD_US > 0U
665- udelay (SDHCI_WAIT_AFTER_CMD_US );
688+ #if defined(SDHCI_WAIT_AFTER_CMD_US ) && ((SDHCI_WAIT_AFTER_CMD_US + 0 ) != 0 )
689+ /* Cadence controllers need a settle window after the card-init sequence;
690+ * confine it to init so bulk data commands do not pay it per block. */
691+ if (sdhci_in_init != 0 )
692+ udelay (SDHCI_WAIT_AFTER_CMD_US );
666693#endif
667694
668695 return status ;
@@ -744,8 +771,13 @@ void sdhci_shutdown(void)
744771/* Reset data and command lines to recover from errors */
745772static inline void sdhci_reset_lines (void )
746773{
774+ uint32_t timeout = 0x000FFFFF ;
775+
747776 sdhci_reg_or (SDHCI_SRS11 , SDHCI_SRS11_RESET_DAT_CMD );
748- while (SDHCI_REG (SDHCI_SRS11 ) & SDHCI_SRS11_RESET_DAT_CMD );
777+ while (((SDHCI_REG (SDHCI_SRS11 ) & SDHCI_SRS11_RESET_DAT_CMD ) != 0U ) &&
778+ (-- timeout > 0U )) {}
779+ if (timeout == 0U )
780+ wolfBoot_printf ("sdhci_reset_lines: reset timeout\n" );
749781}
750782
751783/* ============================================================================
@@ -836,6 +868,10 @@ static int sdcard_power_init_seq(uint32_t voltage)
836868 }
837869 if (status != 0 ) {
838870 wolfBoot_printf ("SD: CMD8 failed after %d retries\n" , retries );
871+ wolfBoot_printf ("SD: SRS09=0x%08X SRS10=0x%08X SRS11=0x%08X "
872+ "SRS15=0x%08X\n" ,
873+ SDHCI_REG (SDHCI_SRS09 ), SDHCI_REG (SDHCI_SRS10 ),
874+ SDHCI_REG (SDHCI_SRS11 ), SDHCI_REG (SDHCI_SRS15 ));
839875 }
840876 else if (retries > 0 ) {
841877 wolfBoot_printf ("SD: CMD8 succeeded after %d retries\n" , retries );
@@ -1748,6 +1784,19 @@ static int sdhci_transfer(int dir, uint32_t cmd_index, uint32_t block_addr,
17481784 return status ;
17491785}
17501786
1787+ static int sdhci_init_internal (void );
1788+
1789+ int sdhci_init (void )
1790+ {
1791+ int status ;
1792+
1793+ sdhci_in_init = 1 ;
1794+ status = sdhci_init_internal ();
1795+ sdhci_in_init = 0 ;
1796+
1797+ return status ;
1798+ }
1799+
17511800/* Public API: Read from MMC/SD card */
17521801int sdhci_read (uint32_t cmd_index , uint32_t block_addr , uint32_t * dst , uint32_t sz )
17531802{
@@ -1764,7 +1813,7 @@ int sdhci_write(uint32_t cmd_index, uint32_t block_addr, const uint32_t* src, ui
17641813 * Controller Initialization
17651814 * ============================================================================ */
17661815
1767- int sdhci_init (void )
1816+ static int sdhci_init_internal (void )
17681817{
17691818 int status = 0 ;
17701819 uint32_t reg , cap ;
@@ -1785,7 +1834,7 @@ int sdhci_init(void)
17851834 * not be ready to accept register writes on some platforms. */
17861835 udelay (1000 ); /* 1ms */
17871836
1788- #if SDHCI_SKIP_HOST_RESET == 0
1837+ #ifndef SDHCI_SKIP_HOST_RESET_ENABLED
17891838 /* Reset the host controller unless an earlier boot stage initialized it. */
17901839 sdhci_reg_or (SDHCI_HRS00 , SDHCI_HRS00_SWR );
17911840 /* Bit will clear when reset is done */
0 commit comments