Skip to content

Commit 39fd71f

Browse files
committed
Bound remaining SDHCI waits and scope Agilex 5 command settle to init
1 parent 211de1d commit 39fd71f

3 files changed

Lines changed: 63 additions & 16 deletions

File tree

‎hal/agilex5.c‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,14 @@ void uart_write(const char *buf, uint32_t len)
6767
if (buf[i] == '\n') {
6868
while (((UART_REG(UART_LSR) & UART_LSR_THRE) == 0U) &&
6969
(--timeout != 0U)) {}
70-
UART_REG(UART_THR) = '\r';
70+
if (timeout != 0U)
71+
UART_REG(UART_THR) = '\r';
7172
timeout = UART_TIMEOUT;
7273
}
7374
while (((UART_REG(UART_LSR) & UART_LSR_THRE) == 0U) &&
7475
(--timeout != 0U)) {}
75-
UART_REG(UART_THR) = (uint32_t)(uint8_t)buf[i];
76+
if (timeout != 0U)
77+
UART_REG(UART_THR) = (uint32_t)(uint8_t)buf[i];
7678
}
7779
}
7880
#else

‎include/sdhci.h‎

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -483,15 +483,11 @@ void sdhci_platform_init(void);
483483
* to the card clock and return that, keeping the internal divider ~1. */
484484
uint32_t sdhci_platform_set_clock(uint32_t clock_khz, uint32_t base_clk_khz);
485485

486-
/* Preserve a host controller initialized by an earlier boot stage. */
487-
#ifndef SDHCI_SKIP_HOST_RESET
488-
#define SDHCI_SKIP_HOST_RESET 0
489-
#endif
486+
/* Preserve a host controller initialized by an earlier boot stage.
487+
* Opt in with -DSDHCI_SKIP_HOST_RESET=1. */
490488

491-
/* Optional controller settling time after each command. */
492-
#ifndef SDHCI_WAIT_AFTER_CMD_US
493-
#define SDHCI_WAIT_AFTER_CMD_US 0U
494-
#endif
489+
/* Optional controller settle time in microseconds after each init command.
490+
* Opt in with -DSDHCI_WAIT_AFTER_CMD_US=<us>. */
495491

496492
/* Platform interrupt setup (PLIC/NVIC/GIC/etc.) */
497493
void sdhci_platform_irq_init(void);

‎src/sdhci.c‎

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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
588598
static 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

599610
static 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 */
745772
static 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 */
17351784
int 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

Comments
 (0)