This commit adds a new function arch_invalidate_dcache_by_addr(). It takes the same parameters as arch_invalidate_dcache(), but performs invalidation of only the lines in cache that need to be invalidated. This new function could be used as a a direct replacement for arch_invalidate_dcache().

The user of this invalidation are mmcsd_sdio currently.  The mmcsd_sdio driver makes calls for dcache invalidation through the chip specific architecture function SDIO_DMARECVSETUP(). I changed the arch/arm/stm32f7 chips to use arch_invalidate_dcache_by_addr() instead of arch_invalidate_dcache().

This commit includes additional changes to mmcsd_sdio.c.  I created SDIO_DMADELYDINVLDT() (DMA delayed invalidate) to invalidate store-into mode dcaches after the DMA transfer.  I have been using SDIO_DMADELYDINVLDT() for several weeks now and it has fixed the problems that I previously reported regarding non-cache aligned buffer invalidation errors (for my store-through dcache). However, it does not permit use of unaligned DMA buffers for store-into mode dcaches.

SDIO_DMADELYDINVLDT() is a NoOp unless the chip specific Kconfig file selects CONFIG_ARCH_HAVE_SDIO_DELAYED_INVLDT. I have modified all the stm32f7 chips to select it.
This commit is contained in:
Bob Feretich
2018-11-20 14:03:42 -06:00
committed by Gregory Nutt
parent 5499c884a5
commit c6851201c0
8 changed files with 232 additions and 16 deletions
+10
View File
@@ -3,6 +3,7 @@
*
* Copyright (C) 2009-2013, 2016-2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Bob Feretich <bob.fereich@rafresearch.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -1408,6 +1409,9 @@ static ssize_t mmcsd_readsingle(FAR struct mmcsd_state_s *priv,
ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR,
MMCSD_BLOCK_RDATADELAY);
#ifdef CONFIG_SDIO_DMA
SDIO_DMADELYDINVLDT(priv->dev, buffer, priv->blocksize);
#endif
if (ret != OK)
{
ferr("ERROR: CMD17 transfer failed: %d\n", ret);
@@ -1550,6 +1554,10 @@ static ssize_t mmcsd_readmultiple(FAR struct mmcsd_state_s *priv,
/* Send STOP_TRANSMISSION */
ret = mmcsd_stoptransmission(priv);
#ifdef CONFIG_SDIO_DMA
SDIO_DMADELYDINVLDT(priv->dev, buffer, priv->blocksize * nblocks);
#endif
if (ret != OK)
{
ferr("ERROR: mmcsd_stoptransmission failed: %d\n", ret);
@@ -1794,6 +1802,8 @@ static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv,
*
* Description:
* Write multiple, contiguous blocks of data to the physical device.
* This function expects that the data to be written is contained in
* one large buffer that is pointed to by buffer.
*
****************************************************************************/