From 0a36ea7400111becfde142f3ec2dcb440aa26a76 Mon Sep 17 00:00:00 2001 From: Jari Nippula Date: Wed, 5 Feb 2025 14:33:59 +0200 Subject: [PATCH 1/5] arch/risc-v/src/mpfs/mpfs_coremmc.c fifo_size parse fix fifo_size is defined in bits 5:4 in VR register. --- arch/risc-v/src/mpfs/mpfs_coremmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/risc-v/src/mpfs/mpfs_coremmc.c b/arch/risc-v/src/mpfs/mpfs_coremmc.c index ebc836afd645e..b665f2852e74f 100644 --- a/arch/risc-v/src/mpfs/mpfs_coremmc.c +++ b/arch/risc-v/src/mpfs/mpfs_coremmc.c @@ -989,7 +989,7 @@ static bool mpfs_device_reset(struct sdio_dev_s *dev) /* Store fifo size for later to check no fifo overruns occur */ - fifo_size = ((getreg8(MPFS_COREMMC_VR) >> 2) & 0x3); + fifo_size = ((getreg8(MPFS_COREMMC_VR) >> 4) & 0x3); if (fifo_size == 0) { priv->fifo_depth = 512; From 0198b076107592c8daf216f3f74de30d9da9e83b Mon Sep 17 00:00:00 2001 From: Jari Nippula Date: Wed, 5 Feb 2025 14:37:17 +0200 Subject: [PATCH 2/5] arch/risc-v/src/mpfs/mpfs_coremmc.c: increase aligned buffer Increase size of alignment fix buffer to 4K to support multiblock transfer. --- arch/risc-v/src/mpfs/mpfs_coremmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/risc-v/src/mpfs/mpfs_coremmc.c b/arch/risc-v/src/mpfs/mpfs_coremmc.c index b665f2852e74f..7cd91dadeffbe 100644 --- a/arch/risc-v/src/mpfs/mpfs_coremmc.c +++ b/arch/risc-v/src/mpfs/mpfs_coremmc.c @@ -252,7 +252,7 @@ struct mpfs_dev_s g_coremmc_dev = /* Not all requests are 32-bit aligned, use a spare buffer workaround */ -static uint32_t g_aligned_buffer[512 / 4]; +static uint32_t g_aligned_buffer[4096 / 4]; /**************************************************************************** * Private Functions From b4e191f179cbb43ac92696924ad8a18514ef1ef6 Mon Sep 17 00:00:00 2001 From: Jari Nippula Date: Wed, 5 Feb 2025 15:01:45 +0200 Subject: [PATCH 3/5] arch/risc-v/src/mpfs/mpfs_coremmc.c: 4-bit mode support and FIC0 clk fix --- arch/risc-v/src/mpfs/mpfs_coremmc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/risc-v/src/mpfs/mpfs_coremmc.c b/arch/risc-v/src/mpfs/mpfs_coremmc.c index 7cd91dadeffbe..fd8e1cb86d727 100644 --- a/arch/risc-v/src/mpfs/mpfs_coremmc.c +++ b/arch/risc-v/src/mpfs/mpfs_coremmc.c @@ -123,7 +123,7 @@ /* Clocks and timing */ -#define MPFS_FPGA_FIC0_CLK (50000000) +#define MPFS_FPGA_FIC0_CLK (125000000) #define COREMMC_CMDTIMEOUT (100000) #define COREMMC_LONGTIMEOUT (100000000) @@ -1072,6 +1072,11 @@ static sdio_capset_t mpfs_capabilities(struct sdio_dev_s *dev) caps |= SDIO_CAPS_1BIT_ONLY; } + if ((getreg8(MPFS_COREMMC_VR) >> 2) & 3) + { + caps |= SDIO_CAPS_4BIT; + } + return caps; } From 4f0f9c14ee8b17788889cb95351571abe0daa99e Mon Sep 17 00:00:00 2001 From: Jari Nippula Date: Wed, 5 Feb 2025 18:08:28 +0200 Subject: [PATCH 4/5] arch/risc-v/src/mpfs/mpfs_emmcsd.c: handle unaligned write buffer --- arch/risc-v/src/mpfs/mpfs_emmcsd.c | 51 ++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/arch/risc-v/src/mpfs/mpfs_emmcsd.c b/arch/risc-v/src/mpfs/mpfs_emmcsd.c index 1eb726bc47c71..6ad05b45b8921 100644 --- a/arch/risc-v/src/mpfs/mpfs_emmcsd.c +++ b/arch/risc-v/src/mpfs/mpfs_emmcsd.c @@ -414,6 +414,10 @@ struct mpfs_dev_s g_emmcsd_dev = .waitsem = SEM_INITIALIZER(0), }; +/* Not all requests are 32-bit aligned, use a spare buffer workaround */ + +static uint32_t g_aligned_buffer[4096 / 4]; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -2139,7 +2143,11 @@ static int mpfs_recvsetup(struct sdio_dev_s *dev, uint8_t *buffer, mcinfo("Receive: %zu bytes\n", nbytes); DEBUGASSERT(priv != NULL && buffer != NULL && nbytes > 0); - DEBUGASSERT(((uintptr_t)buffer & 3) == 0); + if (((uintptr_t)buffer & 3) != 0) + { + mcerr("Unaligned buffer: %p\n", buffer); + return -EFAULT; + } priv->buffer = (uint32_t *)buffer; priv->remaining = nbytes; @@ -2194,13 +2202,33 @@ static int mpfs_sendsetup(struct sdio_dev_s *dev, const mcinfo("Send: %zu bytes\n", nbytes); DEBUGASSERT(priv != NULL && buffer != NULL && nbytes > 0); - DEBUGASSERT(((uintptr_t)buffer & 3) == 0); mpfs_check_lines_busy(priv); + /* Unaligned (not 32-bit aligned) writes seem to be possible. Copy data to + * an aligned buffer in this case. + */ + + if (((uintptr_t)buffer & 3) != 0) + { + if (nbytes <= sizeof(g_aligned_buffer)) + { + memcpy((uint8_t *)g_aligned_buffer, buffer, nbytes); + priv->buffer = g_aligned_buffer; + } + else + { + mcerr("Request doesn't fit the aligned buffer!\n"); + return -EFAULT; + } + } + else + { + priv->buffer = (uint32_t *)buffer; + } + /* Save the source buffer information for use by the interrupt handler */ - priv->buffer = (uint32_t *)buffer; priv->remaining = nbytes; priv->receivecnt = 0; priv->polltransfer = true; @@ -2317,13 +2345,24 @@ static int mpfs_dmasendsetup(struct sdio_dev_s *dev, DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); if (((uintptr_t)buffer & 3) != 0) { - mcerr("Unaligned buffer: %p\n", buffer); - return -EFAULT; + if (buflen <= sizeof(g_aligned_buffer)) + { + memcpy((uint8_t *)g_aligned_buffer, buffer, buflen); + priv->buffer = g_aligned_buffer; + } + else + { + mcerr("Request doesn't fit the aligned buffer!\n"); + return -EFAULT; + } + } + else + { + priv->buffer = (uint32_t *)buffer; } /* Save the source buffer information for use by the interrupt handler */ - priv->buffer = (uint32_t *)buffer; priv->remaining = buflen; priv->receivecnt = 0; priv->polltransfer = false; From 150cc99417d3f5243ecd857134209f62cae6b3f9 Mon Sep 17 00:00:00 2001 From: Jari Nippula Date: Wed, 5 Feb 2025 18:09:19 +0200 Subject: [PATCH 5/5] mmcsd: Allow multiblock transfer --- arch/risc-v/src/mpfs/Kconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/risc-v/src/mpfs/Kconfig b/arch/risc-v/src/mpfs/Kconfig index c4fe16f410952..793ce55ea4360 100644 --- a/arch/risc-v/src/mpfs/Kconfig +++ b/arch/risc-v/src/mpfs/Kconfig @@ -416,8 +416,6 @@ config MPFS_EMMCSD select ARCH_HAVE_SDIO select SDIO_BLOCKSETUP select SDIO_DMA - select FAT_DMAMEMORY - select FAT_FORCE_INDIRECT select GRAN default n ---help---