#include <common.h>
#include <clk.h>
+#include <cpu_func.h>
#include <fdtdec.h>
#include <mmc.h>
#include <dm.h>
+#include <dm/device_compat.h>
#include <dm/pinctrl.h>
#include <linux/compat.h>
-#include <linux/dma-direction.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/sizes.h>
#include <power/regulator.h>
writel(val, priv->regbase + reg);
}
-static dma_addr_t __dma_map_single(void *ptr, size_t size,
- enum dma_data_direction dir)
-{
- unsigned long addr = (unsigned long)ptr;
-
- if (dir == DMA_FROM_DEVICE)
- invalidate_dcache_range(addr, addr + size);
- else
- flush_dcache_range(addr, addr + size);
-
- return addr;
-}
-
-static void __dma_unmap_single(dma_addr_t addr, size_t size,
- enum dma_data_direction dir)
-{
- if (dir != DMA_TO_DEVICE)
- invalidate_dcache_range(addr, addr + size);
-}
-
static int tmio_sd_check_error(struct udevice *dev, struct mmc_cmd *cmd)
{
struct tmio_sd_priv *priv = dev_get_priv(dev);
tmio_sd_writel(priv, tmp, TMIO_SD_DMA_MODE);
- dma_addr = __dma_map_single(buf, len, dir);
+ dma_addr = dma_map_single(buf, len, dir);
tmio_sd_dma_start(priv, dma_addr);
if (poll_flag == TMIO_SD_DMA_INFO1_END_RD)
udelay(1);
- __dma_unmap_single(dma_addr, len, dir);
+ dma_unmap_single(dma_addr, len, dir);
return ret;
}
/* check if the address is DMA'able */
-static bool tmio_sd_addr_is_dmaable(const char *src)
+static bool tmio_sd_addr_is_dmaable(struct mmc_data *data)
{
- uintptr_t addr = (uintptr_t)src;
+ uintptr_t addr = (uintptr_t)data->src;
if (!IS_ALIGNED(addr, TMIO_SD_DMA_MINALIGN))
return false;
#if defined(CONFIG_RCAR_GEN3)
+ if (!(data->flags & MMC_DATA_READ) && !IS_ALIGNED(addr, 128))
+ return false;
/* Gen3 DMA has 32bit limit */
if (addr >> 32)
return false;
if (data) {
/* use DMA if the HW supports it and the buffer is aligned */
if (priv->caps & TMIO_SD_CAP_DMA_INTERNAL &&
- tmio_sd_addr_is_dmaable(data->src))
+ tmio_sd_addr_is_dmaable(data))
ret = tmio_sd_dma_xfer(dev, data);
else
ret = tmio_sd_pio_xfer(dev, cmd, data);
* This register dropped backward compatibility at version 0x10.
* Write an appropriate value depending on the IP version.
*/
- if (priv->version >= 0x10)
- tmio_sd_writel(priv, 0x101, TMIO_SD_HOST_MODE);
- else
+ if (priv->version >= 0x10) {
+ if (priv->caps & TMIO_SD_CAP_64BIT)
+ tmio_sd_writel(priv, 0x000, TMIO_SD_HOST_MODE);
+ else
+ tmio_sd_writel(priv, 0x101, TMIO_SD_HOST_MODE);
+ } else {
tmio_sd_writel(priv, 0x0, TMIO_SD_HOST_MODE);
+ }
if (priv->caps & TMIO_SD_CAP_DMA_INTERNAL) {
tmp = tmio_sd_readl(priv, TMIO_SD_DMA_MODE);
plat->cfg.f_min = mclk /
(priv->caps & TMIO_SD_CAP_DIV1024 ? 1024 : 512);
plat->cfg.f_max = mclk;
- plat->cfg.b_max = U32_MAX; /* max value of TMIO_SD_SECCNT */
+ if (quirks & TMIO_SD_CAP_16BIT)
+ plat->cfg.b_max = U16_MAX; /* max value of TMIO_SD_SECCNT */
+ else
+ plat->cfg.b_max = U32_MAX; /* max value of TMIO_SD_SECCNT */
upriv->mmc = &plat->mmc;