Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 9 additions & 15 deletions Documentation/platforms/arm64/bcm2711/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,17 @@ PCM No

The EMMC2 peripheral connects to the microSD card slot on the :doc:`Raspberry
Pi 4B </platforms/arm64/bcm2711/boards/raspberrypi-4b/index>`. 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 </applications/testing/sd_stress/index>` 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
================
Expand Down
2 changes: 2 additions & 0 deletions arch/arm64/src/bcm2711/bcm2711_mailbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
20 changes: 18 additions & 2 deletions arch/arm64/src/bcm2711/bcm2711_sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
****************************************************************************/
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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",
Expand Down
5 changes: 4 additions & 1 deletion arch/arm64/src/bcm2711/hardware/bcm2711_sdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 1 addition & 7 deletions boards/arm64/bcm2711/raspberrypi-4b/configs/sd/defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Loading