From 7a22d62449cf2d2922485fb7727d4fe9af975be5 Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Mon, 13 Jul 2026 17:27:54 -0400 Subject: [PATCH 1/5] bcm2711/mailbox: Invalidate cache before read Cache must be invalidated before the buffer is read since the VideoCore's write will not invalidate the cache. Signed-off-by: Matteo Golin --- arch/arm64/src/bcm2711/bcm2711_mailbox.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/src/bcm2711/bcm2711_mailbox.c b/arch/arm64/src/bcm2711/bcm2711_mailbox.c index 27d277a7daf11..eb8d66d455ef5 100644 --- a/arch/arm64/src/bcm2711/bcm2711_mailbox.c +++ b/arch/arm64/src/bcm2711/bcm2711_mailbox.c @@ -282,6 +282,8 @@ static int bcm2711_mbox_sendreq(FAR uint32_t *buf, uint8_t n) * docs). */ + up_invalidate_dcache(bufptr, bufptr + n); /* So we read fresh data */ + if (retbuf != bufptr) { ipcerr("Expected %08x, got %08x", bufptr, res); From ea6713bd49a0436bbfbe8e2fbea0a2d7c36e3f1c Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Mon, 13 Jul 2026 17:29:00 -0400 Subject: [PATCH 2/5] bcm2711/sdio: Moderate improvement to multi-block transfers I document the issues encountered with multi-block transfers, namely the block count failing to be set correctly. Even though I did test with that issue corrected, it required modifications to the upper-half MMCSD driver which I am not prepared to test. It also did not fix the time-out on multi-block transfers, likely because the method of verifying FIFOs have space to write is finicky. For now, limiting the block count of transfers resolves the bug! Signed-off-by: Matteo Golin --- arch/arm64/src/bcm2711/bcm2711_sdio.c | 20 +++++++++++++++++-- .../arm64/src/bcm2711/hardware/bcm2711_sdio.h | 5 ++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/arch/arm64/src/bcm2711/bcm2711_sdio.c b/arch/arm64/src/bcm2711/bcm2711_sdio.c index 093d7c065c151..ef7aed5451f8d 100644 --- a/arch/arm64/src/bcm2711/bcm2711_sdio.c +++ b/arch/arm64/src/bcm2711/bcm2711_sdio.c @@ -65,6 +65,10 @@ #define BWAIT_TIMEOUT_US (50000) +#if CONFIG_MMCSD_MULTIBLOCK_LIMIT > 1 +#warning "This driver experiences issues with multi-block transfers" +#endif + /**************************************************************************** * Private Types ****************************************************************************/ @@ -1196,12 +1200,16 @@ static int bcm2711_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, cmdtm_val |= (BCM_SDIO_CMDTM_CMD_ISDATA | BCM_SDIO_CMDTM_TM_DAT_DIR); } - /* Set multi-block transfer flag */ + /* Set multi-block transfer flag. Also, we automatically send CMD12 at the + * end of the transfer in order to stop it. The upper-half driver does not + * do this. + */ if (cmd & MMCSD_MULTIBLOCK) { cmdtm_val |= (BCM_SDIO_CMDTM_TM_MULTI_BLOCK | BCM_SDIO_CMDTM_TM_BLKCNT_EN); + cmdtm_val |= BCM_SDIO_CMDTM_TM_AUTO_CMD_EN_CMD12; } /* Set index of command */ @@ -1241,6 +1249,14 @@ static void bcm2711_blocksetup(FAR struct sdio_dev_s *dev, DEBUGASSERT(nblocks <= 0xffff); /* Maximum transfer count */ DEBUGASSERT(blocklen <= 1023); /* Maximum block size (limited by FIFO) */ + /* WARNING: if we attempt to set the block count while either DAT/CMD + * inhibit statuses are high in the STATUS register, it will fail. I've + * determined this happens during multi-block transfers because the MMCSD + * upper-half driver configures the block size _after_ sending CMD25. If I + * reverse the order, block count is set properly. For now, my strategy is + * to limit transfers to 1 block. + */ + regval |= (blocklen & BCM_SDIO_BLKSIZECNT_BLKSIZE_MASK); regval |= ((nblocks & BCM_SDIO_BLKSIZECNT_BLKCNT_MASK) << BCM_SDIO_BLKSIZECNT_BLKCNT_SHIFTLEN); @@ -2124,7 +2140,7 @@ struct sdio_dev_s *bcm2711_sdio_initialize(int slotno) * 0x80000008 response code, not sure why that happens though. */ - err = bcm2711_mbox_getclkrate(priv->clkid, &priv->baseclk, false); + err = bcm2711_mbox_getclkrate(priv->clkid, &priv->baseclk, true); if (err != -EAGAIN && err != 0) { mcerr("Couldn't determine base clock rate for EMMC%d: %d\n", diff --git a/arch/arm64/src/bcm2711/hardware/bcm2711_sdio.h b/arch/arm64/src/bcm2711/hardware/bcm2711_sdio.h index 802918e40f9bf..fc1baaafec0d1 100644 --- a/arch/arm64/src/bcm2711/hardware/bcm2711_sdio.h +++ b/arch/arm64/src/bcm2711/hardware/bcm2711_sdio.h @@ -105,7 +105,10 @@ #define BCM_SDIO_BLKSIZECNT_BLKCNT_MASK (0xffff) #define BCM_SDIO_CMDTM_TM_BLKCNT_EN (1 << 1) -#define BCM_SDIO_CMDTM_TM_AUTO_CMD_EN (0x3 << 2) +#define BCM_SDIO_CMDTM_TM_AUTO_CMD_EN_MASK (0x3 << 2) +#define BCM_SDIO_CMDTM_TM_AUTO_CMD_EN_NONE (0x0 << 2) +#define BCM_SDIO_CMDTM_TM_AUTO_CMD_EN_CMD12 (0x1 << 2) +#define BCM_SDIO_CMDTM_TM_AUTO_CMD_EN_CMD23 (0x2 << 2) #define BCM_SDIO_CMDTM_TM_DAT_DIR (1 << 4) #define BCM_SDIO_CMDTM_TM_MULTI_BLOCK (1 << 5) From 8744ecf0b5c840482fb7a86d6bb063c251dfe180 Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Mon, 13 Jul 2026 17:32:28 -0400 Subject: [PATCH 3/5] boards/raspberrypi-4b: Bug fix for broken SD card behaviour Introduces a fixed configuration for the SD card that does not break for multi-block transfers. Signed-off-by: Matteo Golin --- boards/arm64/bcm2711/raspberrypi-4b/configs/sd/defconfig | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/boards/arm64/bcm2711/raspberrypi-4b/configs/sd/defconfig b/boards/arm64/bcm2711/raspberrypi-4b/configs/sd/defconfig index 6ae41febc3a10..f38de55978868 100644 --- a/boards/arm64/bcm2711/raspberrypi-4b/configs/sd/defconfig +++ b/boards/arm64/bcm2711/raspberrypi-4b/configs/sd/defconfig @@ -22,14 +22,7 @@ CONFIG_BUILTIN=y CONFIG_DEBUG_ASSERTIONS=y CONFIG_DEBUG_ASSERTIONS_EXPRESSION=y CONFIG_DEBUG_FEATURES=y -CONFIG_DEBUG_FS=y -CONFIG_DEBUG_FS_ERROR=y CONFIG_DEBUG_FULLOPT=y -CONFIG_DEBUG_IPC=y -CONFIG_DEBUG_IPC_ERROR=y -CONFIG_DEBUG_IPC_WARN=y -CONFIG_DEBUG_MEMCARD=y -CONFIG_DEBUG_MEMCARD_ERROR=y CONFIG_DEBUG_SYMBOLS=y CONFIG_DEFAULT_TASK_STACKSIZE=8192 CONFIG_EXPERIMENTAL=y @@ -44,6 +37,7 @@ CONFIG_HAVE_CXXINITIALIZE=y CONFIG_IDLETHREAD_STACKSIZE=8192 CONFIG_INIT_ENTRYPOINT="nsh_main" CONFIG_INTELHEX_BINARY=y +CONFIG_MMCSD_MULTIBLOCK_LIMIT=1 CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_FILEIOSIZE=512 CONFIG_NSH_READLINE=y From 4f38373789d4b9141a8f064ba55487367810581c Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Mon, 13 Jul 2026 17:36:24 -0400 Subject: [PATCH 4/5] docs/raspberrypi-4b: Documentation about the SD card updated Updated the documentation to reflect the fix of buggy SD card behaviour at the sacrifice of slower performance. Signed-off-by: Matteo Golin --- .../platforms/arm64/bcm2711/index.rst | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/Documentation/platforms/arm64/bcm2711/index.rst b/Documentation/platforms/arm64/bcm2711/index.rst index 98307f92caa1b..f6dcdc0b4c98f 100644 --- a/Documentation/platforms/arm64/bcm2711/index.rst +++ b/Documentation/platforms/arm64/bcm2711/index.rst @@ -52,23 +52,17 @@ PCM No The EMMC2 peripheral connects to the microSD card slot on the :doc:`Raspberry Pi 4B `. Currently, it - has been tested using a 32GB Samsung microSD card and it has passed testing - with that. The only quirks are: + has passed testing with a few different uSD cards. The only quirks are: * No card insertion/removal interrupts work, so hotswapping isn't possible - * The :doc:`sdstress ` example works - unless the 'number of bytes' option is greater than 1023. I suspect this is - something to do with the FIFO depth being only 1023 bytes. - - However, the 64GB microSD card exhibits very strange behaviour. There are - often data CRC errors that prevent the boot filesystem from mounting. When - that somehow passes (intermittent), running ``ls`` on the filesystem repeatedly - sometimes causes certain files to disappear from the listing (they are not - deleted and appear again on next boot), or causes their filenames to be shown - in all caps. Writing to the card with ``echo`` often fails with data CRC - error or timeout, and then the card is buggy for the remainder of the - session. **It is not recommended to use 64GB cards with this implementation - for the time being.** + * Multi-block transfers must be restricted to 1 block at a time + (``CONFIG_MMCSD_MULTIBLOCK_LIMIT=1``), since the upper-half driver's method + of doing block setup is not immediately compatible with the BCM2711 EMMC + controller. Changes to the common-upperhalf would require extensive + testing, so this performance sacrifice is done for correct behaviour in the + short-term. + + All in all, be aware of issues with the SD card implementation. Supported Boards ================ From 87fe90eb06c6d8ab26821be7033a815678628c4b Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Mon, 13 Jul 2026 17:42:11 -0400 Subject: [PATCH 5/5] boards/raspberrypi-4b: Fix nxinit configuration SD issues Propagate the solution for SD card bugs to the nxinit configuration, which also uses the nxinit configuration. Signed-off-by: Matteo Golin --- boards/arm64/bcm2711/raspberrypi-4b/configs/nxinit/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/arm64/bcm2711/raspberrypi-4b/configs/nxinit/defconfig b/boards/arm64/bcm2711/raspberrypi-4b/configs/nxinit/defconfig index 857a1faa08ff5..bfb710b2638a1 100644 --- a/boards/arm64/bcm2711/raspberrypi-4b/configs/nxinit/defconfig +++ b/boards/arm64/bcm2711/raspberrypi-4b/configs/nxinit/defconfig @@ -36,6 +36,7 @@ CONFIG_IDLETHREAD_STACKSIZE=8192 CONFIG_INIT_ENTRYPOINT="init_main" CONFIG_INTELHEX_BINARY=y CONFIG_LIBC_EXECFUNCS=y +CONFIG_MMCSD_MULTIBLOCK_LIMIT=1 CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_FILEIOSIZE=512 CONFIG_NSH_READLINE=y