From 80fec463dfbdd5a365d515e75ea32275397b8bfb Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Wed, 21 Jan 2026 13:51:55 +0000 Subject: [PATCH] stm32h7: panic on sdmmc FIFO or DMA errors FIFO errors shouldn't be possible with hardware flow control enabled. DMA errors shouldn't occur unless a bad memory address was passed. Don't bother checking for ITCM/DTCM in the transfer setup and instead just wait for the IDMATE error; if the RM0433 reference manual is to be believed then SDMMC1 _only_ has access to AXI bus memories, and checking for all invalid destinations would be very verbose. Change-Id: I2b22b56009933e16c5adde4d36b7a906cee57791 --- firmware/target/arm/stm32/sdmmc-stm32h7.c | 27 +++++------------------ 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/firmware/target/arm/stm32/sdmmc-stm32h7.c b/firmware/target/arm/stm32/sdmmc-stm32h7.c index 8ec64a7d1d..4147c0a95a 100644 --- a/firmware/target/arm/stm32/sdmmc-stm32h7.c +++ b/firmware/target/arm/stm32/sdmmc-stm32h7.c @@ -273,27 +273,6 @@ int stm32h7_sdmmc_submit_command(void *controller, if (buff_size > MAX_DATA_LEN) panicf("%s: buffer too big", __func__); - /* - * IDMA on the SDMMC controller can't access the DTCM. - * This is only possible by bounce-buffering in one of - * the other memories accessible to IDMA, then using - * another DMA process to copy the resulting buffer to - * DTCM, which seems unnecessarily convoluted. - */ - if ((uintptr_t)buff_addr >= STM32_DTCM_BASE && - (uintptr_t)buff_addr < STM32_DTCM_BASE + STM32_DTCM_SIZE) - panicf("%s: buffer in DTCM not supported", __func__); - - /* - * Must assign to a variable to prevent GCC from whining - * about 'limited range of data type', because the ITCM - * is mapped at address 0. - */ - static const uintptr_t itcm_base = STM32_ITCM_BASE; - if ((uintptr_t)buff_addr >= itcm_base && - (uintptr_t)buff_addr < itcm_base + STM32_ITCM_SIZE) - panicf("%s: buffer in ITCM not supported", __func__); - /* Set block size */ uint32_t dctrl = 0; uint32_t dblocksize = find_first_set_bit(cmd->block_len); @@ -481,8 +460,12 @@ void stm32h7_sdmmc_irq_handler(struct stm32h7_sdmmc_controller *ctl) ctl->cmd_error = SDMMC_STATUS_TIMEOUT; else if (reg_vreadf(star, SDMMC_STAR, DCRCFAIL)) ctl->cmd_error = SDMMC_STATUS_INVALID_CRC; - else if (star & DATA_ERROR_BITS) + else if (reg_vreadf(star, SDMMC_STAR, DABORT)) ctl->cmd_error = SDMMC_STATUS_ERROR; + else if (reg_vreadf(star, SDMMC_STAR, IDMATE)) + panicf("sdmmc dma err: %08lx", reg_readl(ctl->regs, SDMMC_IDMABASE0R)); + else if (star & DATA_ERROR_BITS) + panicf("sdmmc data error: %08lx", star); } ctl->cmd_wait &= ~WAIT_DATA;