Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coremmc multiblock support #351

Closed
wants to merge 5 commits into from
Closed
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
2 changes: 0 additions & 2 deletions arch/risc-v/src/mpfs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,6 @@ config MPFS_EMMCSD
select ARCH_HAVE_SDIO
select SDIO_BLOCKSETUP
select SDIO_DMA
select FAT_DMAMEMORY
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work with kernel mode? If I remember correctly we had to enable FORCE_INDIRECT and for that we needed FAT_DMAMEMORY, because otherwise the MMC driver and/or MMC DMA would write directly to user space memory. DMA only works with physical addresses (and user addresses are virtual) so this fails miserably.

FORCE_INDIRECT makes the file system read the media in 512B blocks, which are properly aligned AND DMA safe! These 512B blocks are then moved to the user buffer.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this does not work in kernel mode as such. So, change not usable.

select FAT_FORCE_INDIRECT
select GRAN
default n
---help---
Expand Down
11 changes: 8 additions & 3 deletions arch/risc-v/src/mpfs/mpfs_coremmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
51 changes: 45 additions & 6 deletions arch/risc-v/src/mpfs/mpfs_emmcsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
****************************************************************************/
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Loading