@@ -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 );
@@ -1731,6 +1767,19 @@ static int sdhci_transfer(int dir, uint32_t cmd_index, uint32_t block_addr,
17311767 return status ;
17321768}
17331769
1770+ static int sdhci_init_internal (void );
1771+
1772+ int sdhci_init (void )
1773+ {
1774+ int status ;
1775+
1776+ sdhci_in_init = 1 ;
1777+ status = sdhci_init_internal ();
1778+ sdhci_in_init = 0 ;
1779+
1780+ return status ;
1781+ }
1782+
17341783/* Public API: Read from MMC/SD card */
17351784int sdhci_read (uint32_t cmd_index , uint32_t block_addr , uint32_t * dst , uint32_t sz )
17361785{
@@ -1747,7 +1796,7 @@ int sdhci_write(uint32_t cmd_index, uint32_t block_addr, const uint32_t* src, ui
17471796 * Controller Initialization
17481797 * ============================================================================ */
17491798
1750- int sdhci_init (void )
1799+ static int sdhci_init_internal (void )
17511800{
17521801 int status = 0 ;
17531802 uint32_t reg , cap ;
@@ -1768,7 +1817,7 @@ int sdhci_init(void)
17681817 * not be ready to accept register writes on some platforms. */
17691818 udelay (1000 ); /* 1ms */
17701819
1771- #if SDHCI_SKIP_HOST_RESET == 0
1820+ #ifndef SDHCI_SKIP_HOST_RESET_ENABLED
17721821 /* Reset the host controller unless an earlier boot stage initialized it. */
17731822 sdhci_reg_or (SDHCI_HRS00 , SDHCI_HRS00_SWR );
17741823 /* Bit will clear when reset is done */
0 commit comments