mirror of
https://github.com/apache/nuttx.git
synced 2026-10-10 07:40:27 +00:00
arch/arm/imxrt: Support imxrt118x in the uSDHC driver
- Add the missing clock gating macros for imxrt118x - Change sw_cd_gpio from int32_t to gpio_pinset_t (64-bits on 118x) - Invalidate cache again after the data has been received. Cache might be refilled by a prefetch or, in theory, by cpu read touching the same cache line - even though the latter should not happen. - Map any DMA accesses to/from DTCM to the shadow address window, which gives the uSDHC DMA access to the DTCM. Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
This commit is contained in:
parent
87ae65fa6e
commit
f5edfc61df
2 changed files with 32 additions and 6 deletions
|
|
@ -275,6 +275,9 @@ EXTERN const struct clock_configuration_s g_initial_clkconfig;
|
|||
#define imxrt_clockoff_lpspi5() imxrt_ccm_gate_on(CCM_LPCG_LPSPI5, false)
|
||||
#define imxrt_clockoff_lpspi6() imxrt_ccm_gate_on(CCM_LPCG_LPSPI6, false)
|
||||
|
||||
#define imxrt_clockall_usdhc1() imxrt_ccm_gate_on(CCM_LPCG_USDHC1, true)
|
||||
#define imxrt_clockall_usdhc2() imxrt_ccm_gate_on(CCM_LPCG_USDHC2, true)
|
||||
|
||||
#define imxrt_clockall_usboh3() imxrt_ccm_gate_on(CCM_LPCG_USB, true)
|
||||
#define imxrt_clockoff_usboh3() imxrt_ccm_gate_on(CCM_LPCG_USB, false)
|
||||
#define imxrt_clockrun_usboh3() imxrt_ccm_gate_on(CCM_LPCG_USB, true)
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include "arm_internal.h"
|
||||
#include "imxrt_config.h"
|
||||
#include "imxrt_gpio.h"
|
||||
#include "imxrt_dtcm.h"
|
||||
#include "hardware/imxrt_pinmux.h"
|
||||
#include "hardware/imxrt_ccm.h"
|
||||
#include "imxrt_periphclks.h"
|
||||
|
|
@ -198,7 +199,7 @@ struct imxrt_dev_s
|
|||
void *do_sdio_arg; /* arg for SDIO card ISR */
|
||||
|
||||
uint32_t addr; /* Base address of this instances */
|
||||
uint32_t sw_cd_gpio; /* If a non USDHCx CD pin is used,
|
||||
gpio_pinset_t sw_cd_gpio; /* If a non USDHCx CD pin is used,
|
||||
* this is its GPIO */
|
||||
uint32_t cd_invert; /* If true invert the CD pin */
|
||||
};
|
||||
|
|
@ -1037,6 +1038,9 @@ static void imxrt_recvdma(struct imxrt_dev_s *priv)
|
|||
{
|
||||
/* In an aligned case, we have always received all blocks */
|
||||
|
||||
up_invalidate_dcache((uintptr_t)priv->buffer,
|
||||
(uintptr_t)priv->buffer + priv->remaining);
|
||||
|
||||
priv->remaining = 0;
|
||||
}
|
||||
|
||||
|
|
@ -3005,6 +3009,8 @@ static int imxrt_dmarecvsetup(struct sdio_dev_s *dev,
|
|||
uint8_t *buffer, size_t buflen)
|
||||
{
|
||||
struct imxrt_dev_s *priv = (struct imxrt_dev_s *)dev;
|
||||
uint32_t dma_address;
|
||||
bool ok;
|
||||
|
||||
DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0);
|
||||
#if defined(CONFIG_ARCH_HAVE_SDIO_PREFLIGHT)
|
||||
|
|
@ -3062,19 +3068,28 @@ static int imxrt_dmarecvsetup(struct sdio_dev_s *dev,
|
|||
/* Configure the RX DMA */
|
||||
|
||||
imxrt_configxfrints(priv, USDHC_DMADONE_INTS);
|
||||
|
||||
#if defined(CONFIG_ARMV7M_DCACHE)
|
||||
if (priv->unaligned_rx)
|
||||
{
|
||||
putreg32((uint32_t) priv->rxbuffer,
|
||||
priv->addr + IMXRT_USDHC_DSADDR_OFFSET);
|
||||
ok = imxrt_dma_address(priv->rxbuffer, priv->blocksize,
|
||||
&dma_address);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
putreg32((uint32_t) priv->buffer,
|
||||
priv->addr + IMXRT_USDHC_DSADDR_OFFSET);
|
||||
ok = imxrt_dma_address(priv->buffer, buflen, &dma_address);
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
mcerr("ERROR: buffer %p (len %zu) is not DMA-reachable\n",
|
||||
priv->buffer, buflen);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
putreg32(dma_address, priv->addr + IMXRT_USDHC_DSADDR_OFFSET);
|
||||
|
||||
/* Sample the register state */
|
||||
|
||||
imxrt_sample(priv, SAMPLENDX_AFTER_SETUP);
|
||||
|
|
@ -3106,6 +3121,7 @@ static int imxrt_dmasendsetup(struct sdio_dev_s *dev,
|
|||
const uint8_t *buffer, size_t buflen)
|
||||
{
|
||||
struct imxrt_dev_s *priv = (struct imxrt_dev_s *)dev;
|
||||
uint32_t dma_address;
|
||||
|
||||
DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0);
|
||||
DEBUGASSERT(((uint32_t) buffer & 3) == 0);
|
||||
|
|
@ -3136,7 +3152,14 @@ static int imxrt_dmasendsetup(struct sdio_dev_s *dev,
|
|||
|
||||
/* Configure the TX DMA */
|
||||
|
||||
putreg32((uint32_t) buffer, priv->addr + IMXRT_USDHC_DSADDR_OFFSET);
|
||||
if (!imxrt_dma_address(buffer, buflen, &dma_address))
|
||||
{
|
||||
mcerr("ERROR: buffer %p (len %zu) is not DMA-reachable\n",
|
||||
buffer, buflen);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
putreg32(dma_address, priv->addr + IMXRT_USDHC_DSADDR_OFFSET);
|
||||
|
||||
/* Sample the register state */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue