diff --git a/arch/arm/src/imxrt/imxrt_clockconfig_ver3.h b/arch/arm/src/imxrt/imxrt_clockconfig_ver3.h index 3d6b19ab9bf..a5c12da6206 100644 --- a/arch/arm/src/imxrt/imxrt_clockconfig_ver3.h +++ b/arch/arm/src/imxrt/imxrt_clockconfig_ver3.h @@ -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) diff --git a/arch/arm/src/imxrt/imxrt_usdhc.c b/arch/arm/src/imxrt/imxrt_usdhc.c index d021f2a99e5..9bce9e756ff 100644 --- a/arch/arm/src/imxrt/imxrt_usdhc.c +++ b/arch/arm/src/imxrt/imxrt_usdhc.c @@ -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 */