From cb0b6b035a356e958bf964803e87539464f01bf2 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 13 Apr 2018 23:51:33 +0200 Subject: mmc: tmio: Rename Matsushita to TMIO Synchronize the naming with Linux, call the common code TMIO. No functional change. Signed-off-by: Marek Vasut Cc: Jaehoon Chung Cc: Masahiro Yamada --- drivers/mmc/Makefile | 4 +- drivers/mmc/matsushita-common.c | 787 ---------------------------------------- drivers/mmc/matsushita-common.h | 151 -------- drivers/mmc/renesas-sdhi.c | 108 +++--- drivers/mmc/tmio-common.c | 787 ++++++++++++++++++++++++++++++++++++++++ drivers/mmc/tmio-common.h | 151 ++++++++ drivers/mmc/uniphier-sd.c | 16 +- 7 files changed, 1002 insertions(+), 1002 deletions(-) delete mode 100644 drivers/mmc/matsushita-common.c delete mode 100644 drivers/mmc/matsushita-common.h create mode 100644 drivers/mmc/tmio-common.c create mode 100644 drivers/mmc/tmio-common.h diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index f2c6280686..cf46c332f1 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -62,6 +62,6 @@ obj-$(CONFIG_MMC_SDHCI_XENON) += xenon_sdhci.o obj-$(CONFIG_MMC_SDHCI_ZYNQ) += zynq_sdhci.o obj-$(CONFIG_MMC_SUNXI) += sunxi_mmc.o -obj-$(CONFIG_MMC_UNIPHIER) += matsushita-common.o uniphier-sd.o -obj-$(CONFIG_RENESAS_SDHI) += matsushita-common.o renesas-sdhi.o +obj-$(CONFIG_MMC_UNIPHIER) += tmio-common.o uniphier-sd.o +obj-$(CONFIG_RENESAS_SDHI) += tmio-common.o renesas-sdhi.o obj-$(CONFIG_MMC_BCM2835) += bcm2835_sdhost.o diff --git a/drivers/mmc/matsushita-common.c b/drivers/mmc/matsushita-common.c deleted file mode 100644 index e22a9de5da..0000000000 --- a/drivers/mmc/matsushita-common.c +++ /dev/null @@ -1,787 +0,0 @@ -/* - * Copyright (C) 2016 Socionext Inc. - * Author: Masahiro Yamada - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "matsushita-common.h" - -DECLARE_GLOBAL_DATA_PTR; - -static u64 matsu_sd_readq(struct matsu_sd_priv *priv, unsigned int reg) -{ - return readq(priv->regbase + (reg << 1)); -} - -static void matsu_sd_writeq(struct matsu_sd_priv *priv, - u64 val, unsigned int reg) -{ - writeq(val, priv->regbase + (reg << 1)); -} - -static u16 matsu_sd_readw(struct matsu_sd_priv *priv, unsigned int reg) -{ - return readw(priv->regbase + (reg >> 1)); -} - -static void matsu_sd_writew(struct matsu_sd_priv *priv, - u16 val, unsigned int reg) -{ - writew(val, priv->regbase + (reg >> 1)); -} - -u32 matsu_sd_readl(struct matsu_sd_priv *priv, unsigned int reg) -{ - u32 val; - - if (priv->caps & MATSU_SD_CAP_64BIT) - return readl(priv->regbase + (reg << 1)); - else if (priv->caps & MATSU_SD_CAP_16BIT) { - val = readw(priv->regbase + (reg >> 1)) & 0xffff; - if ((reg == MATSU_SD_RSP10) || (reg == MATSU_SD_RSP32) || - (reg == MATSU_SD_RSP54) || (reg == MATSU_SD_RSP76)) { - val |= readw(priv->regbase + (reg >> 1) + 2) << 16; - } - return val; - } else - return readl(priv->regbase + reg); -} - -void matsu_sd_writel(struct matsu_sd_priv *priv, - u32 val, unsigned int reg) -{ - if (priv->caps & MATSU_SD_CAP_64BIT) - writel(val, priv->regbase + (reg << 1)); - else if (priv->caps & MATSU_SD_CAP_16BIT) { - writew(val & 0xffff, priv->regbase + (reg >> 1)); - if (reg == MATSU_SD_INFO1 || reg == MATSU_SD_INFO1_MASK || - reg == MATSU_SD_INFO2 || reg == MATSU_SD_INFO2_MASK || - reg == MATSU_SD_ARG) - writew(val >> 16, priv->regbase + (reg >> 1) + 2); - } else - 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 matsu_sd_check_error(struct udevice *dev) -{ - struct matsu_sd_priv *priv = dev_get_priv(dev); - u32 info2 = matsu_sd_readl(priv, MATSU_SD_INFO2); - - if (info2 & MATSU_SD_INFO2_ERR_RTO) { - /* - * TIMEOUT must be returned for unsupported command. Do not - * display error log since this might be a part of sequence to - * distinguish between SD and MMC. - */ - return -ETIMEDOUT; - } - - if (info2 & MATSU_SD_INFO2_ERR_TO) { - dev_err(dev, "timeout error\n"); - return -ETIMEDOUT; - } - - if (info2 & (MATSU_SD_INFO2_ERR_END | MATSU_SD_INFO2_ERR_CRC | - MATSU_SD_INFO2_ERR_IDX)) { - dev_err(dev, "communication out of sync\n"); - return -EILSEQ; - } - - if (info2 & (MATSU_SD_INFO2_ERR_ILA | MATSU_SD_INFO2_ERR_ILR | - MATSU_SD_INFO2_ERR_ILW)) { - dev_err(dev, "illegal access\n"); - return -EIO; - } - - return 0; -} - -static int matsu_sd_wait_for_irq(struct udevice *dev, unsigned int reg, - u32 flag) -{ - struct matsu_sd_priv *priv = dev_get_priv(dev); - long wait = 1000000; - int ret; - - while (!(matsu_sd_readl(priv, reg) & flag)) { - if (wait-- < 0) { - dev_err(dev, "timeout\n"); - return -ETIMEDOUT; - } - - ret = matsu_sd_check_error(dev); - if (ret) - return ret; - - udelay(1); - } - - return 0; -} - -#define matsu_pio_read_fifo(__width, __suffix) \ -static void matsu_pio_read_fifo_##__width(struct matsu_sd_priv *priv, \ - char *pbuf, uint blksz) \ -{ \ - u##__width *buf = (u##__width *)pbuf; \ - int i; \ - \ - if (likely(IS_ALIGNED((uintptr_t)buf, ((__width) / 8)))) { \ - for (i = 0; i < blksz / ((__width) / 8); i++) { \ - *buf++ = matsu_sd_read##__suffix(priv, \ - MATSU_SD_BUF); \ - } \ - } else { \ - for (i = 0; i < blksz / ((__width) / 8); i++) { \ - u##__width data; \ - data = matsu_sd_read##__suffix(priv, \ - MATSU_SD_BUF); \ - put_unaligned(data, buf++); \ - } \ - } \ -} - -matsu_pio_read_fifo(64, q) -matsu_pio_read_fifo(32, l) -matsu_pio_read_fifo(16, w) - -static int matsu_sd_pio_read_one_block(struct udevice *dev, char *pbuf, - uint blocksize) -{ - struct matsu_sd_priv *priv = dev_get_priv(dev); - int ret; - - /* wait until the buffer is filled with data */ - ret = matsu_sd_wait_for_irq(dev, MATSU_SD_INFO2, - MATSU_SD_INFO2_BRE); - if (ret) - return ret; - - /* - * Clear the status flag _before_ read the buffer out because - * MATSU_SD_INFO2_BRE is edge-triggered, not level-triggered. - */ - matsu_sd_writel(priv, 0, MATSU_SD_INFO2); - - if (priv->caps & MATSU_SD_CAP_64BIT) - matsu_pio_read_fifo_64(priv, pbuf, blocksize); - else if (priv->caps & MATSU_SD_CAP_16BIT) - matsu_pio_read_fifo_16(priv, pbuf, blocksize); - else - matsu_pio_read_fifo_32(priv, pbuf, blocksize); - - return 0; -} - -#define matsu_pio_write_fifo(__width, __suffix) \ -static void matsu_pio_write_fifo_##__width(struct matsu_sd_priv *priv, \ - const char *pbuf, uint blksz)\ -{ \ - const u##__width *buf = (const u##__width *)pbuf; \ - int i; \ - \ - if (likely(IS_ALIGNED((uintptr_t)buf, ((__width) / 8)))) { \ - for (i = 0; i < blksz / ((__width) / 8); i++) { \ - matsu_sd_write##__suffix(priv, *buf++, \ - MATSU_SD_BUF); \ - } \ - } else { \ - for (i = 0; i < blksz / ((__width) / 8); i++) { \ - u##__width data = get_unaligned(buf++); \ - matsu_sd_write##__suffix(priv, data, \ - MATSU_SD_BUF); \ - } \ - } \ -} - -matsu_pio_write_fifo(64, q) -matsu_pio_write_fifo(32, l) -matsu_pio_write_fifo(16, w) - -static int matsu_sd_pio_write_one_block(struct udevice *dev, - const char *pbuf, uint blocksize) -{ - struct matsu_sd_priv *priv = dev_get_priv(dev); - int ret; - - /* wait until the buffer becomes empty */ - ret = matsu_sd_wait_for_irq(dev, MATSU_SD_INFO2, - MATSU_SD_INFO2_BWE); - if (ret) - return ret; - - matsu_sd_writel(priv, 0, MATSU_SD_INFO2); - - if (priv->caps & MATSU_SD_CAP_64BIT) - matsu_pio_write_fifo_64(priv, pbuf, blocksize); - else if (priv->caps & MATSU_SD_CAP_16BIT) - matsu_pio_write_fifo_16(priv, pbuf, blocksize); - else - matsu_pio_write_fifo_32(priv, pbuf, blocksize); - - return 0; -} - -static int matsu_sd_pio_xfer(struct udevice *dev, struct mmc_data *data) -{ - const char *src = data->src; - char *dest = data->dest; - int i, ret; - - for (i = 0; i < data->blocks; i++) { - if (data->flags & MMC_DATA_READ) - ret = matsu_sd_pio_read_one_block(dev, dest, - data->blocksize); - else - ret = matsu_sd_pio_write_one_block(dev, src, - data->blocksize); - if (ret) - return ret; - - if (data->flags & MMC_DATA_READ) - dest += data->blocksize; - else - src += data->blocksize; - } - - return 0; -} - -static void matsu_sd_dma_start(struct matsu_sd_priv *priv, - dma_addr_t dma_addr) -{ - u32 tmp; - - matsu_sd_writel(priv, 0, MATSU_SD_DMA_INFO1); - matsu_sd_writel(priv, 0, MATSU_SD_DMA_INFO2); - - /* enable DMA */ - tmp = matsu_sd_readl(priv, MATSU_SD_EXTMODE); - tmp |= MATSU_SD_EXTMODE_DMA_EN; - matsu_sd_writel(priv, tmp, MATSU_SD_EXTMODE); - - matsu_sd_writel(priv, dma_addr & U32_MAX, MATSU_SD_DMA_ADDR_L); - - /* suppress the warning "right shift count >= width of type" */ - dma_addr >>= min_t(int, 32, 8 * sizeof(dma_addr)); - - matsu_sd_writel(priv, dma_addr & U32_MAX, MATSU_SD_DMA_ADDR_H); - - matsu_sd_writel(priv, MATSU_SD_DMA_CTL_START, MATSU_SD_DMA_CTL); -} - -static int matsu_sd_dma_wait_for_irq(struct udevice *dev, u32 flag, - unsigned int blocks) -{ - struct matsu_sd_priv *priv = dev_get_priv(dev); - long wait = 1000000 + 10 * blocks; - - while (!(matsu_sd_readl(priv, MATSU_SD_DMA_INFO1) & flag)) { - if (wait-- < 0) { - dev_err(dev, "timeout during DMA\n"); - return -ETIMEDOUT; - } - - udelay(10); - } - - if (matsu_sd_readl(priv, MATSU_SD_DMA_INFO2)) { - dev_err(dev, "error during DMA\n"); - return -EIO; - } - - return 0; -} - -static int matsu_sd_dma_xfer(struct udevice *dev, struct mmc_data *data) -{ - struct matsu_sd_priv *priv = dev_get_priv(dev); - size_t len = data->blocks * data->blocksize; - void *buf; - enum dma_data_direction dir; - dma_addr_t dma_addr; - u32 poll_flag, tmp; - int ret; - - tmp = matsu_sd_readl(priv, MATSU_SD_DMA_MODE); - - if (data->flags & MMC_DATA_READ) { - buf = data->dest; - dir = DMA_FROM_DEVICE; - /* - * The DMA READ completion flag position differs on Socionext - * and Renesas SoCs. It is bit 20 on Socionext SoCs and using - * bit 17 is a hardware bug and forbidden. It is bit 17 on - * Renesas SoCs and bit 20 does not work on them. - */ - poll_flag = (priv->caps & MATSU_SD_CAP_RCAR) ? - MATSU_SD_DMA_INFO1_END_RD : - MATSU_SD_DMA_INFO1_END_RD2; - tmp |= MATSU_SD_DMA_MODE_DIR_RD; - } else { - buf = (void *)data->src; - dir = DMA_TO_DEVICE; - poll_flag = MATSU_SD_DMA_INFO1_END_WR; - tmp &= ~MATSU_SD_DMA_MODE_DIR_RD; - } - - matsu_sd_writel(priv, tmp, MATSU_SD_DMA_MODE); - - dma_addr = __dma_map_single(buf, len, dir); - - matsu_sd_dma_start(priv, dma_addr); - - ret = matsu_sd_dma_wait_for_irq(dev, poll_flag, data->blocks); - - __dma_unmap_single(dma_addr, len, dir); - - return ret; -} - -/* check if the address is DMA'able */ -static bool matsu_sd_addr_is_dmaable(unsigned long addr) -{ - if (!IS_ALIGNED(addr, MATSU_SD_DMA_MINALIGN)) - return false; - -#if defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARM64) && \ - defined(CONFIG_SPL_BUILD) - /* - * For UniPhier ARMv7 SoCs, the stack is allocated in the locked ways - * of L2, which is unreachable from the DMA engine. - */ - if (addr < CONFIG_SPL_STACK) - return false; -#endif - - return true; -} - -int matsu_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, - struct mmc_data *data) -{ - struct matsu_sd_priv *priv = dev_get_priv(dev); - int ret; - u32 tmp; - - if (matsu_sd_readl(priv, MATSU_SD_INFO2) & MATSU_SD_INFO2_CBSY) { - dev_err(dev, "command busy\n"); - return -EBUSY; - } - - /* clear all status flags */ - matsu_sd_writel(priv, 0, MATSU_SD_INFO1); - matsu_sd_writel(priv, 0, MATSU_SD_INFO2); - - /* disable DMA once */ - tmp = matsu_sd_readl(priv, MATSU_SD_EXTMODE); - tmp &= ~MATSU_SD_EXTMODE_DMA_EN; - matsu_sd_writel(priv, tmp, MATSU_SD_EXTMODE); - - matsu_sd_writel(priv, cmd->cmdarg, MATSU_SD_ARG); - - tmp = cmd->cmdidx; - - if (data) { - matsu_sd_writel(priv, data->blocksize, MATSU_SD_SIZE); - matsu_sd_writel(priv, data->blocks, MATSU_SD_SECCNT); - - /* Do not send CMD12 automatically */ - tmp |= MATSU_SD_CMD_NOSTOP | MATSU_SD_CMD_DATA; - - if (data->blocks > 1) - tmp |= MATSU_SD_CMD_MULTI; - - if (data->flags & MMC_DATA_READ) - tmp |= MATSU_SD_CMD_RD; - } - - /* - * Do not use the response type auto-detection on this hardware. - * CMD8, for example, has different response types on SD and eMMC, - * while this controller always assumes the response type for SD. - * Set the response type manually. - */ - switch (cmd->resp_type) { - case MMC_RSP_NONE: - tmp |= MATSU_SD_CMD_RSP_NONE; - break; - case MMC_RSP_R1: - tmp |= MATSU_SD_CMD_RSP_R1; - break; - case MMC_RSP_R1b: - tmp |= MATSU_SD_CMD_RSP_R1B; - break; - case MMC_RSP_R2: - tmp |= MATSU_SD_CMD_RSP_R2; - break; - case MMC_RSP_R3: - tmp |= MATSU_SD_CMD_RSP_R3; - break; - default: - dev_err(dev, "unknown response type\n"); - return -EINVAL; - } - - dev_dbg(dev, "sending CMD%d (SD_CMD=%08x, SD_ARG=%08x)\n", - cmd->cmdidx, tmp, cmd->cmdarg); - matsu_sd_writel(priv, tmp, MATSU_SD_CMD); - - ret = matsu_sd_wait_for_irq(dev, MATSU_SD_INFO1, - MATSU_SD_INFO1_RSP); - if (ret) - return ret; - - if (cmd->resp_type & MMC_RSP_136) { - u32 rsp_127_104 = matsu_sd_readl(priv, MATSU_SD_RSP76); - u32 rsp_103_72 = matsu_sd_readl(priv, MATSU_SD_RSP54); - u32 rsp_71_40 = matsu_sd_readl(priv, MATSU_SD_RSP32); - u32 rsp_39_8 = matsu_sd_readl(priv, MATSU_SD_RSP10); - - cmd->response[0] = ((rsp_127_104 & 0x00ffffff) << 8) | - ((rsp_103_72 & 0xff000000) >> 24); - cmd->response[1] = ((rsp_103_72 & 0x00ffffff) << 8) | - ((rsp_71_40 & 0xff000000) >> 24); - cmd->response[2] = ((rsp_71_40 & 0x00ffffff) << 8) | - ((rsp_39_8 & 0xff000000) >> 24); - cmd->response[3] = (rsp_39_8 & 0xffffff) << 8; - } else { - /* bit 39-8 */ - cmd->response[0] = matsu_sd_readl(priv, MATSU_SD_RSP10); - } - - if (data) { - /* use DMA if the HW supports it and the buffer is aligned */ - if (priv->caps & MATSU_SD_CAP_DMA_INTERNAL && - matsu_sd_addr_is_dmaable((long)data->src)) - ret = matsu_sd_dma_xfer(dev, data); - else - ret = matsu_sd_pio_xfer(dev, data); - - ret = matsu_sd_wait_for_irq(dev, MATSU_SD_INFO1, - MATSU_SD_INFO1_CMP); - if (ret) - return ret; - } - - matsu_sd_wait_for_irq(dev, MATSU_SD_INFO2, MATSU_SD_INFO2_SCLKDIVEN); - - return ret; -} - -static int matsu_sd_set_bus_width(struct matsu_sd_priv *priv, - struct mmc *mmc) -{ - u32 val, tmp; - - switch (mmc->bus_width) { - case 0: - case 1: - val = MATSU_SD_OPTION_WIDTH_1; - break; - case 4: - val = MATSU_SD_OPTION_WIDTH_4; - break; - case 8: - val = MATSU_SD_OPTION_WIDTH_8; - break; - default: - return -EINVAL; - } - - tmp = matsu_sd_readl(priv, MATSU_SD_OPTION); - tmp &= ~MATSU_SD_OPTION_WIDTH_MASK; - tmp |= val; - matsu_sd_writel(priv, tmp, MATSU_SD_OPTION); - - return 0; -} - -static void matsu_sd_set_ddr_mode(struct matsu_sd_priv *priv, - struct mmc *mmc) -{ - u32 tmp; - - tmp = matsu_sd_readl(priv, MATSU_SD_IF_MODE); - if (mmc->ddr_mode) - tmp |= MATSU_SD_IF_MODE_DDR; - else - tmp &= ~MATSU_SD_IF_MODE_DDR; - matsu_sd_writel(priv, tmp, MATSU_SD_IF_MODE); -} - -static void matsu_sd_set_clk_rate(struct matsu_sd_priv *priv, - struct mmc *mmc) -{ - unsigned int divisor; - u32 val, tmp; - - if (!mmc->clock) - return; - - divisor = DIV_ROUND_UP(priv->mclk, mmc->clock); - - if (divisor <= 1) - val = (priv->caps & MATSU_SD_CAP_RCAR) ? - MATSU_SD_CLKCTL_RCAR_DIV1 : MATSU_SD_CLKCTL_DIV1; - else if (divisor <= 2) - val = MATSU_SD_CLKCTL_DIV2; - else if (divisor <= 4) - val = MATSU_SD_CLKCTL_DIV4; - else if (divisor <= 8) - val = MATSU_SD_CLKCTL_DIV8; - else if (divisor <= 16) - val = MATSU_SD_CLKCTL_DIV16; - else if (divisor <= 32) - val = MATSU_SD_CLKCTL_DIV32; - else if (divisor <= 64) - val = MATSU_SD_CLKCTL_DIV64; - else if (divisor <= 128) - val = MATSU_SD_CLKCTL_DIV128; - else if (divisor <= 256) - val = MATSU_SD_CLKCTL_DIV256; - else if (divisor <= 512 || !(priv->caps & MATSU_SD_CAP_DIV1024)) - val = MATSU_SD_CLKCTL_DIV512; - else - val = MATSU_SD_CLKCTL_DIV1024; - - tmp = matsu_sd_readl(priv, MATSU_SD_CLKCTL); - if (tmp & MATSU_SD_CLKCTL_SCLKEN && - (tmp & MATSU_SD_CLKCTL_DIV_MASK) == val) - return; - - /* stop the clock before changing its rate to avoid a glitch signal */ - tmp &= ~MATSU_SD_CLKCTL_SCLKEN; - matsu_sd_writel(priv, tmp, MATSU_SD_CLKCTL); - - tmp &= ~MATSU_SD_CLKCTL_DIV_MASK; - tmp |= val | MATSU_SD_CLKCTL_OFFEN; - matsu_sd_writel(priv, tmp, MATSU_SD_CLKCTL); - - tmp |= MATSU_SD_CLKCTL_SCLKEN; - matsu_sd_writel(priv, tmp, MATSU_SD_CLKCTL); - - udelay(1000); -} - -static void matsu_sd_set_pins(struct udevice *dev) -{ - __maybe_unused struct mmc *mmc = mmc_get_mmc_dev(dev); - -#ifdef CONFIG_DM_REGULATOR - struct matsu_sd_priv *priv = dev_get_priv(dev); - - if (priv->vqmmc_dev) { - if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) - regulator_set_value(priv->vqmmc_dev, 1800000); - else - regulator_set_value(priv->vqmmc_dev, 3300000); - regulator_set_enable(priv->vqmmc_dev, true); - } -#endif - -#ifdef CONFIG_PINCTRL - switch (mmc->selected_mode) { - case MMC_LEGACY: - case SD_LEGACY: - case MMC_HS: - case SD_HS: - case MMC_HS_52: - case MMC_DDR_52: - pinctrl_select_state(dev, "default"); - break; - case UHS_SDR12: - case UHS_SDR25: - case UHS_SDR50: - case UHS_DDR50: - case UHS_SDR104: - case MMC_HS_200: - pinctrl_select_state(dev, "state_uhs"); - break; - default: - break; - } -#endif -} - -int matsu_sd_set_ios(struct udevice *dev) -{ - struct matsu_sd_priv *priv = dev_get_priv(dev); - struct mmc *mmc = mmc_get_mmc_dev(dev); - int ret; - - dev_dbg(dev, "clock %uHz, DDRmode %d, width %u\n", - mmc->clock, mmc->ddr_mode, mmc->bus_width); - - ret = matsu_sd_set_bus_width(priv, mmc); - if (ret) - return ret; - matsu_sd_set_ddr_mode(priv, mmc); - matsu_sd_set_clk_rate(priv, mmc); - matsu_sd_set_pins(dev); - - return 0; -} - -int matsu_sd_get_cd(struct udevice *dev) -{ - struct matsu_sd_priv *priv = dev_get_priv(dev); - - if (priv->caps & MATSU_SD_CAP_NONREMOVABLE) - return 1; - - return !!(matsu_sd_readl(priv, MATSU_SD_INFO1) & - MATSU_SD_INFO1_CD); -} - -static void matsu_sd_host_init(struct matsu_sd_priv *priv) -{ - u32 tmp; - - /* soft reset of the host */ - tmp = matsu_sd_readl(priv, MATSU_SD_SOFT_RST); - tmp &= ~MATSU_SD_SOFT_RST_RSTX; - matsu_sd_writel(priv, tmp, MATSU_SD_SOFT_RST); - tmp |= MATSU_SD_SOFT_RST_RSTX; - matsu_sd_writel(priv, tmp, MATSU_SD_SOFT_RST); - - /* FIXME: implement eMMC hw_reset */ - - matsu_sd_writel(priv, MATSU_SD_STOP_SEC, MATSU_SD_STOP); - - /* - * Connected to 32bit AXI. - * This register dropped backward compatibility at version 0x10. - * Write an appropriate value depending on the IP version. - */ - if (priv->version >= 0x10) - matsu_sd_writel(priv, 0x101, MATSU_SD_HOST_MODE); - else - matsu_sd_writel(priv, 0x0, MATSU_SD_HOST_MODE); - - if (priv->caps & MATSU_SD_CAP_DMA_INTERNAL) { - tmp = matsu_sd_readl(priv, MATSU_SD_DMA_MODE); - tmp |= MATSU_SD_DMA_MODE_ADDR_INC; - matsu_sd_writel(priv, tmp, MATSU_SD_DMA_MODE); - } -} - -int matsu_sd_bind(struct udevice *dev) -{ - struct matsu_sd_plat *plat = dev_get_platdata(dev); - - return mmc_bind(dev, &plat->mmc, &plat->cfg); -} - -int matsu_sd_probe(struct udevice *dev, u32 quirks) -{ - struct matsu_sd_plat *plat = dev_get_platdata(dev); - struct matsu_sd_priv *priv = dev_get_priv(dev); - struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); - fdt_addr_t base; - struct clk clk; - int ret; - - base = devfdt_get_addr(dev); - if (base == FDT_ADDR_T_NONE) - return -EINVAL; - - priv->regbase = devm_ioremap(dev, base, SZ_2K); - if (!priv->regbase) - return -ENOMEM; - -#ifdef CONFIG_DM_REGULATOR - device_get_supply_regulator(dev, "vqmmc-supply", &priv->vqmmc_dev); -#endif - - ret = clk_get_by_index(dev, 0, &clk); - if (ret < 0) { - dev_err(dev, "failed to get host clock\n"); - return ret; - } - - /* set to max rate */ - priv->mclk = clk_set_rate(&clk, ULONG_MAX); - if (IS_ERR_VALUE(priv->mclk)) { - dev_err(dev, "failed to set rate for host clock\n"); - clk_free(&clk); - return priv->mclk; - } - - ret = clk_enable(&clk); - clk_free(&clk); - if (ret) { - dev_err(dev, "failed to enable host clock\n"); - return ret; - } - - ret = mmc_of_parse(dev, &plat->cfg); - if (ret < 0) { - dev_err(dev, "failed to parse host caps\n"); - return ret; - } - - plat->cfg.name = dev->name; - plat->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; - - if (quirks) - priv->caps = quirks; - - priv->version = matsu_sd_readl(priv, MATSU_SD_VERSION) & - MATSU_SD_VERSION_IP; - dev_dbg(dev, "version %x\n", priv->version); - if (priv->version >= 0x10) { - priv->caps |= MATSU_SD_CAP_DMA_INTERNAL; - priv->caps |= MATSU_SD_CAP_DIV1024; - } - - if (fdt_get_property(gd->fdt_blob, dev_of_offset(dev), "non-removable", - NULL)) - priv->caps |= MATSU_SD_CAP_NONREMOVABLE; - - matsu_sd_host_init(priv); - - plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34; - plat->cfg.f_min = priv->mclk / - (priv->caps & MATSU_SD_CAP_DIV1024 ? 1024 : 512); - plat->cfg.f_max = priv->mclk; - plat->cfg.b_max = U32_MAX; /* max value of MATSU_SD_SECCNT */ - - upriv->mmc = &plat->mmc; - - return 0; -} diff --git a/drivers/mmc/matsushita-common.h b/drivers/mmc/matsushita-common.h deleted file mode 100644 index 34631cb43e..0000000000 --- a/drivers/mmc/matsushita-common.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2016 Socionext Inc. - * Author: Masahiro Yamada - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __MATSUSHITA_COMMON_H__ -#define __MATSUSHITA_COMMON_H__ - -#define MATSU_SD_CMD 0x000 /* command */ -#define MATSU_SD_CMD_NOSTOP BIT(14) /* No automatic CMD12 issue */ -#define MATSU_SD_CMD_MULTI BIT(13) /* multiple block transfer */ -#define MATSU_SD_CMD_RD BIT(12) /* 1: read, 0: write */ -#define MATSU_SD_CMD_DATA BIT(11) /* data transfer */ -#define MATSU_SD_CMD_APP BIT(6) /* ACMD preceded by CMD55 */ -#define MATSU_SD_CMD_NORMAL (0 << 8)/* auto-detect of resp-type */ -#define MATSU_SD_CMD_RSP_NONE (3 << 8)/* response: none */ -#define MATSU_SD_CMD_RSP_R1 (4 << 8)/* response: R1, R5, R6, R7 */ -#define MATSU_SD_CMD_RSP_R1B (5 << 8)/* response: R1b, R5b */ -#define MATSU_SD_CMD_RSP_R2 (6 << 8)/* response: R2 */ -#define MATSU_SD_CMD_RSP_R3 (7 << 8)/* response: R3, R4 */ -#define MATSU_SD_ARG 0x008 /* command argument */ -#define MATSU_SD_STOP 0x010 /* stop action control */ -#define MATSU_SD_STOP_SEC BIT(8) /* use sector count */ -#define MATSU_SD_STOP_STP BIT(0) /* issue CMD12 */ -#define MATSU_SD_SECCNT 0x014 /* sector counter */ -#define MATSU_SD_RSP10 0x018 /* response[39:8] */ -#define MATSU_SD_RSP32 0x020 /* response[71:40] */ -#define MATSU_SD_RSP54 0x028 /* response[103:72] */ -#define MATSU_SD_RSP76 0x030 /* response[127:104] */ -#define MATSU_SD_INFO1 0x038 /* IRQ status 1 */ -#define MATSU_SD_INFO1_CD BIT(5) /* state of card detect */ -#define MATSU_SD_INFO1_INSERT BIT(4) /* card inserted */ -#define MATSU_SD_INFO1_REMOVE BIT(3) /* card removed */ -#define MATSU_SD_INFO1_CMP BIT(2) /* data complete */ -#define MATSU_SD_INFO1_RSP BIT(0) /* response complete */ -#define MATSU_SD_INFO2 0x03c /* IRQ status 2 */ -#define MATSU_SD_INFO2_ERR_ILA BIT(15) /* illegal access err */ -#define MATSU_SD_INFO2_CBSY BIT(14) /* command busy */ -#define MATSU_SD_INFO2_SCLKDIVEN BIT(13) /* command setting reg ena */ -#define MATSU_SD_INFO2_BWE BIT(9) /* write buffer ready */ -#define MATSU_SD_INFO2_BRE BIT(8) /* read buffer ready */ -#define MATSU_SD_INFO2_DAT0 BIT(7) /* SDDAT0 */ -#define MATSU_SD_INFO2_ERR_RTO BIT(6) /* response time out */ -#define MATSU_SD_INFO2_ERR_ILR BIT(5) /* illegal read err */ -#define MATSU_SD_INFO2_ERR_ILW BIT(4) /* illegal write err */ -#define MATSU_SD_INFO2_ERR_TO BIT(3) /* time out error */ -#define MATSU_SD_INFO2_ERR_END BIT(2) /* END bit error */ -#define MATSU_SD_INFO2_ERR_CRC BIT(1) /* CRC error */ -#define MATSU_SD_INFO2_ERR_IDX BIT(0) /* cmd index error */ -#define MATSU_SD_INFO1_MASK 0x040 -#define MATSU_SD_INFO2_MASK 0x044 -#define MATSU_SD_CLKCTL 0x048 /* clock divisor */ -#define MATSU_SD_CLKCTL_DIV_MASK 0x104ff -#define MATSU_SD_CLKCTL_DIV1024 BIT(16) /* SDCLK = CLK / 1024 */ -#define MATSU_SD_CLKCTL_DIV512 BIT(7) /* SDCLK = CLK / 512 */ -#define MATSU_SD_CLKCTL_DIV256 BIT(6) /* SDCLK = CLK / 256 */ -#define MATSU_SD_CLKCTL_DIV128 BIT(5) /* SDCLK = CLK / 128 */ -#define MATSU_SD_CLKCTL_DIV64 BIT(4) /* SDCLK = CLK / 64 */ -#define MATSU_SD_CLKCTL_DIV32 BIT(3) /* SDCLK = CLK / 32 */ -#define MATSU_SD_CLKCTL_DIV16 BIT(2) /* SDCLK = CLK / 16 */ -#define MATSU_SD_CLKCTL_DIV8 BIT(1) /* SDCLK = CLK / 8 */ -#define MATSU_SD_CLKCTL_DIV4 BIT(0) /* SDCLK = CLK / 4 */ -#define MATSU_SD_CLKCTL_DIV2 0 /* SDCLK = CLK / 2 */ -#define MATSU_SD_CLKCTL_DIV1 BIT(10) /* SDCLK = CLK */ -#define MATSU_SD_CLKCTL_RCAR_DIV1 0xff /* SDCLK = CLK (RCar ver.) */ -#define MATSU_SD_CLKCTL_OFFEN BIT(9) /* stop SDCLK when unused */ -#define MATSU_SD_CLKCTL_SCLKEN BIT(8) /* SDCLK output enable */ -#define MATSU_SD_SIZE 0x04c /* block size */ -#define MATSU_SD_OPTION 0x050 -#define MATSU_SD_OPTION_WIDTH_MASK (5 << 13) -#define MATSU_SD_OPTION_WIDTH_1 (4 << 13) -#define MATSU_SD_OPTION_WIDTH_4 (0 << 13) -#define MATSU_SD_OPTION_WIDTH_8 (1 << 13) -#define MATSU_SD_BUF 0x060 /* read/write buffer */ -#define MATSU_SD_EXTMODE 0x1b0 -#define MATSU_SD_EXTMODE_DMA_EN BIT(1) /* transfer 1: DMA, 0: pio */ -#define MATSU_SD_SOFT_RST 0x1c0 -#define MATSU_SD_SOFT_RST_RSTX BIT(0) /* reset deassert */ -#define MATSU_SD_VERSION 0x1c4 /* version register */ -#define MATSU_SD_VERSION_IP 0xff /* IP version */ -#define MATSU_SD_HOST_MODE 0x1c8 -#define MATSU_SD_IF_MODE 0x1cc -#define MATSU_SD_IF_MODE_DDR BIT(0) /* DDR mode */ -#define MATSU_SD_VOLT 0x1e4 /* voltage switch */ -#define MATSU_SD_VOLT_MASK (3 << 0) -#define MATSU_SD_VOLT_OFF (0 << 0) -#define MATSU_SD_VOLT_330 (1 << 0)/* 3.3V signal */ -#define MATSU_SD_VOLT_180 (2 << 0)/* 1.8V signal */ -#define MATSU_SD_DMA_MODE 0x410 -#define MATSU_SD_DMA_MODE_DIR_RD BIT(16) /* 1: from device, 0: to dev */ -#define MATSU_SD_DMA_MODE_ADDR_INC BIT(0) /* 1: address inc, 0: fixed */ -#define MATSU_SD_DMA_CTL 0x414 -#define MATSU_SD_DMA_CTL_START BIT(0) /* start DMA (auto cleared) */ -#define MATSU_SD_DMA_RST 0x418 -#define MATSU_SD_DMA_RST_RD BIT(9) -#define MATSU_SD_DMA_RST_WR BIT(8) -#define MATSU_SD_DMA_INFO1 0x420 -#define MATSU_SD_DMA_INFO1_END_RD2 BIT(20) /* DMA from device is complete (uniphier) */ -#define MATSU_SD_DMA_INFO1_END_RD BIT(17) /* DMA from device is complete (renesas) */ -#define MATSU_SD_DMA_INFO1_END_WR BIT(16) /* DMA to device is complete */ -#define MATSU_SD_DMA_INFO1_MASK 0x424 -#define MATSU_SD_DMA_INFO2 0x428 -#define MATSU_SD_DMA_INFO2_ERR_RD BIT(17) -#define MATSU_SD_DMA_INFO2_ERR_WR BIT(16) -#define MATSU_SD_DMA_INFO2_MASK 0x42c -#define MATSU_SD_DMA_ADDR_L 0x440 -#define MATSU_SD_DMA_ADDR_H 0x444 - -/* alignment required by the DMA engine of this controller */ -#define MATSU_SD_DMA_MINALIGN 0x10 - -struct matsu_sd_plat { - struct mmc_config cfg; - struct mmc mmc; -}; - -struct matsu_sd_priv { - void __iomem *regbase; - unsigned long mclk; - unsigned int version; - u32 caps; -#define MATSU_SD_CAP_NONREMOVABLE BIT(0) /* Nonremovable e.g. eMMC */ -#define MATSU_SD_CAP_DMA_INTERNAL BIT(1) /* have internal DMA engine */ -#define MATSU_SD_CAP_DIV1024 BIT(2) /* divisor 1024 is available */ -#define MATSU_SD_CAP_64BIT BIT(3) /* Controller is 64bit */ -#define MATSU_SD_CAP_16BIT BIT(4) /* Controller is 16bit */ -#define MATSU_SD_CAP_RCAR_GEN2 BIT(5) /* Renesas RCar version of IP */ -#define MATSU_SD_CAP_RCAR_GEN3 BIT(6) /* Renesas RCar version of IP */ -#define MATSU_SD_CAP_RCAR_UHS BIT(7) /* Renesas RCar UHS/SDR modes */ -#define MATSU_SD_CAP_RCAR \ - (MATSU_SD_CAP_RCAR_GEN2 | MATSU_SD_CAP_RCAR_GEN3) -#ifdef CONFIG_DM_REGULATOR - struct udevice *vqmmc_dev; -#endif -}; - -int matsu_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, - struct mmc_data *data); -int matsu_sd_set_ios(struct udevice *dev); -int matsu_sd_get_cd(struct udevice *dev); - -int matsu_sd_bind(struct udevice *dev); -int matsu_sd_probe(struct udevice *dev, u32 quirks); - -u32 matsu_sd_readl(struct matsu_sd_priv *priv, unsigned int reg); -void matsu_sd_writel(struct matsu_sd_priv *priv, - u32 val, unsigned int reg); - -#endif /* __MATSUSHITA_COMMON_H__ */ diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c index 8564f42e20..56a43ca7d3 100644 --- a/drivers/mmc/renesas-sdhi.c +++ b/drivers/mmc/renesas-sdhi.c @@ -16,7 +16,7 @@ #include #include -#include "matsushita-common.h" +#include "tmio-common.h" #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) @@ -38,86 +38,86 @@ #define RENESAS_SDHI_MAX_TAP 3 -static unsigned int renesas_sdhi_init_tuning(struct matsu_sd_priv *priv) +static unsigned int renesas_sdhi_init_tuning(struct tmio_sd_priv *priv) { u32 reg; /* Initialize SCC */ - matsu_sd_writel(priv, 0, MATSU_SD_INFO1); + tmio_sd_writel(priv, 0, TMIO_SD_INFO1); - reg = matsu_sd_readl(priv, MATSU_SD_CLKCTL); - reg &= ~MATSU_SD_CLKCTL_SCLKEN; - matsu_sd_writel(priv, reg, MATSU_SD_CLKCTL); + reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL); + reg &= ~TMIO_SD_CLKCTL_SCLKEN; + tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL); /* Set sampling clock selection range */ - matsu_sd_writel(priv, 0x8 << RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT, + tmio_sd_writel(priv, 0x8 << RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT, RENESAS_SDHI_SCC_DTCNTL); - reg = matsu_sd_readl(priv, RENESAS_SDHI_SCC_DTCNTL); + reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_DTCNTL); reg |= RENESAS_SDHI_SCC_DTCNTL_TAPEN; - matsu_sd_writel(priv, reg, RENESAS_SDHI_SCC_DTCNTL); + tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_DTCNTL); - reg = matsu_sd_readl(priv, RENESAS_SDHI_SCC_CKSEL); + reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_CKSEL); reg |= RENESAS_SDHI_SCC_CKSEL_DTSEL; - matsu_sd_writel(priv, reg, RENESAS_SDHI_SCC_CKSEL); + tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_CKSEL); - reg = matsu_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); + reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); reg &= ~RENESAS_SDHI_SCC_RVSCNTL_RVSEN; - matsu_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); + tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); - matsu_sd_writel(priv, 0x300 /* scc_tappos */, + tmio_sd_writel(priv, 0x300 /* scc_tappos */, RENESAS_SDHI_SCC_DT2FF); - reg = matsu_sd_readl(priv, MATSU_SD_CLKCTL); - reg |= MATSU_SD_CLKCTL_SCLKEN; - matsu_sd_writel(priv, reg, MATSU_SD_CLKCTL); + reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL); + reg |= TMIO_SD_CLKCTL_SCLKEN; + tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL); /* Read TAPNUM */ - return (matsu_sd_readl(priv, RENESAS_SDHI_SCC_DTCNTL) >> + return (tmio_sd_readl(priv, RENESAS_SDHI_SCC_DTCNTL) >> RENESAS_SDHI_SCC_DTCNTL_TAPNUM_SHIFT) & RENESAS_SDHI_SCC_DTCNTL_TAPNUM_MASK; } -static void renesas_sdhi_reset_tuning(struct matsu_sd_priv *priv) +static void renesas_sdhi_reset_tuning(struct tmio_sd_priv *priv) { u32 reg; /* Reset SCC */ - reg = matsu_sd_readl(priv, MATSU_SD_CLKCTL); - reg &= ~MATSU_SD_CLKCTL_SCLKEN; - matsu_sd_writel(priv, reg, MATSU_SD_CLKCTL); + reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL); + reg &= ~TMIO_SD_CLKCTL_SCLKEN; + tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL); - reg = matsu_sd_readl(priv, RENESAS_SDHI_SCC_CKSEL); + reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_CKSEL); reg &= ~RENESAS_SDHI_SCC_CKSEL_DTSEL; - matsu_sd_writel(priv, reg, RENESAS_SDHI_SCC_CKSEL); + tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_CKSEL); - reg = matsu_sd_readl(priv, MATSU_SD_CLKCTL); - reg |= MATSU_SD_CLKCTL_SCLKEN; - matsu_sd_writel(priv, reg, MATSU_SD_CLKCTL); + reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL); + reg |= TMIO_SD_CLKCTL_SCLKEN; + tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL); - reg = matsu_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); + reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); reg &= ~RENESAS_SDHI_SCC_RVSCNTL_RVSEN; - matsu_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); + tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); - reg = matsu_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); + reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); reg &= ~RENESAS_SDHI_SCC_RVSCNTL_RVSEN; - matsu_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); + tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); } -static void renesas_sdhi_prepare_tuning(struct matsu_sd_priv *priv, +static void renesas_sdhi_prepare_tuning(struct tmio_sd_priv *priv, unsigned long tap) { /* Set sampling clock position */ - matsu_sd_writel(priv, tap, RENESAS_SDHI_SCC_TAPSET); + tmio_sd_writel(priv, tap, RENESAS_SDHI_SCC_TAPSET); } -static unsigned int renesas_sdhi_compare_scc_data(struct matsu_sd_priv *priv) +static unsigned int renesas_sdhi_compare_scc_data(struct tmio_sd_priv *priv) { /* Get comparison of sampling data */ - return matsu_sd_readl(priv, RENESAS_SDHI_SCC_SMPCMP); + return tmio_sd_readl(priv, RENESAS_SDHI_SCC_SMPCMP); } -static int renesas_sdhi_select_tuning(struct matsu_sd_priv *priv, +static int renesas_sdhi_select_tuning(struct tmio_sd_priv *priv, unsigned int tap_num, unsigned int taps, unsigned int smpcmp) { @@ -132,7 +132,7 @@ static int renesas_sdhi_select_tuning(struct matsu_sd_priv *priv, u32 reg; /* Clear SCC_RVSREQ */ - matsu_sd_writel(priv, 0, RENESAS_SDHI_SCC_RVSREQ); + tmio_sd_writel(priv, 0, RENESAS_SDHI_SCC_RVSREQ); /* Merge the results */ for (i = 0; i < tap_num * 2; i++) { @@ -211,19 +211,19 @@ static int renesas_sdhi_select_tuning(struct matsu_sd_priv *priv, return -EIO; /* Set SCC */ - matsu_sd_writel(priv, tap_set, RENESAS_SDHI_SCC_TAPSET); + tmio_sd_writel(priv, tap_set, RENESAS_SDHI_SCC_TAPSET); /* Enable auto re-tuning */ - reg = matsu_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); + reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); reg |= RENESAS_SDHI_SCC_RVSCNTL_RVSEN; - matsu_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); + tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); return 0; } int renesas_sdhi_execute_tuning(struct udevice *dev, uint opcode) { - struct matsu_sd_priv *priv = dev_get_priv(dev); + struct tmio_sd_priv *priv = dev_get_priv(dev); struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct mmc *mmc = upriv->mmc; unsigned int tap_num; @@ -232,7 +232,7 @@ int renesas_sdhi_execute_tuning(struct udevice *dev, uint opcode) u32 caps; /* Only supported on Renesas RCar */ - if (!(priv->caps & MATSU_SD_CAP_RCAR_UHS)) + if (!(priv->caps & TMIO_SD_CAP_RCAR_UHS)) return -EINVAL; /* clock tuning is not needed for upto 52MHz */ @@ -258,7 +258,7 @@ int renesas_sdhi_execute_tuning(struct udevice *dev, uint opcode) /* Force PIO for the tuning */ caps = priv->caps; - priv->caps &= ~MATSU_SD_CAP_DMA_INTERNAL; + priv->caps &= ~TMIO_SD_CAP_DMA_INTERNAL; ret = mmc_send_tuning(mmc, opcode, NULL); @@ -288,12 +288,12 @@ out: static int renesas_sdhi_set_ios(struct udevice *dev) { - int ret = matsu_sd_set_ios(dev); + int ret = tmio_sd_set_ios(dev); mdelay(10); #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) - struct matsu_sd_priv *priv = dev_get_priv(dev); + struct tmio_sd_priv *priv = dev_get_priv(dev); renesas_sdhi_reset_tuning(priv); #endif @@ -302,17 +302,17 @@ static int renesas_sdhi_set_ios(struct udevice *dev) } static const struct dm_mmc_ops renesas_sdhi_ops = { - .send_cmd = matsu_sd_send_cmd, + .send_cmd = tmio_sd_send_cmd, .set_ios = renesas_sdhi_set_ios, - .get_cd = matsu_sd_get_cd, + .get_cd = tmio_sd_get_cd, #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) .execute_tuning = renesas_sdhi_execute_tuning, #endif }; -#define RENESAS_GEN2_QUIRKS MATSU_SD_CAP_RCAR_GEN2 +#define RENESAS_GEN2_QUIRKS TMIO_SD_CAP_RCAR_GEN2 #define RENESAS_GEN3_QUIRKS \ - MATSU_SD_CAP_64BIT | MATSU_SD_CAP_RCAR_GEN3 | MATSU_SD_CAP_RCAR_UHS + TMIO_SD_CAP_64BIT | TMIO_SD_CAP_RCAR_GEN3 | TMIO_SD_CAP_RCAR_UHS static const struct udevice_id renesas_sdhi_match[] = { { .compatible = "renesas,sdhi-r8a7790", .data = RENESAS_GEN2_QUIRKS }, @@ -345,10 +345,10 @@ static int renesas_sdhi_probe(struct udevice *dev) } if (fdt_resource_size(®_res) == 0x100) - quirks |= MATSU_SD_CAP_16BIT; + quirks |= TMIO_SD_CAP_16BIT; } - ret = matsu_sd_probe(dev, quirks); + ret = tmio_sd_probe(dev, quirks); #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) if (!ret) renesas_sdhi_reset_tuning(dev_get_priv(dev)); @@ -360,9 +360,9 @@ U_BOOT_DRIVER(renesas_sdhi) = { .name = "renesas-sdhi", .id = UCLASS_MMC, .of_match = renesas_sdhi_match, - .bind = matsu_sd_bind, + .bind = tmio_sd_bind, .probe = renesas_sdhi_probe, - .priv_auto_alloc_size = sizeof(struct matsu_sd_priv), - .platdata_auto_alloc_size = sizeof(struct matsu_sd_plat), + .priv_auto_alloc_size = sizeof(struct tmio_sd_priv), + .platdata_auto_alloc_size = sizeof(struct tmio_sd_plat), .ops = &renesas_sdhi_ops, }; diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c new file mode 100644 index 0000000000..5f1c9c0bd4 --- /dev/null +++ b/drivers/mmc/tmio-common.c @@ -0,0 +1,787 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tmio-common.h" + +DECLARE_GLOBAL_DATA_PTR; + +static u64 tmio_sd_readq(struct tmio_sd_priv *priv, unsigned int reg) +{ + return readq(priv->regbase + (reg << 1)); +} + +static void tmio_sd_writeq(struct tmio_sd_priv *priv, + u64 val, unsigned int reg) +{ + writeq(val, priv->regbase + (reg << 1)); +} + +static u16 tmio_sd_readw(struct tmio_sd_priv *priv, unsigned int reg) +{ + return readw(priv->regbase + (reg >> 1)); +} + +static void tmio_sd_writew(struct tmio_sd_priv *priv, + u16 val, unsigned int reg) +{ + writew(val, priv->regbase + (reg >> 1)); +} + +u32 tmio_sd_readl(struct tmio_sd_priv *priv, unsigned int reg) +{ + u32 val; + + if (priv->caps & TMIO_SD_CAP_64BIT) + return readl(priv->regbase + (reg << 1)); + else if (priv->caps & TMIO_SD_CAP_16BIT) { + val = readw(priv->regbase + (reg >> 1)) & 0xffff; + if ((reg == TMIO_SD_RSP10) || (reg == TMIO_SD_RSP32) || + (reg == TMIO_SD_RSP54) || (reg == TMIO_SD_RSP76)) { + val |= readw(priv->regbase + (reg >> 1) + 2) << 16; + } + return val; + } else + return readl(priv->regbase + reg); +} + +void tmio_sd_writel(struct tmio_sd_priv *priv, + u32 val, unsigned int reg) +{ + if (priv->caps & TMIO_SD_CAP_64BIT) + writel(val, priv->regbase + (reg << 1)); + else if (priv->caps & TMIO_SD_CAP_16BIT) { + writew(val & 0xffff, priv->regbase + (reg >> 1)); + if (reg == TMIO_SD_INFO1 || reg == TMIO_SD_INFO1_MASK || + reg == TMIO_SD_INFO2 || reg == TMIO_SD_INFO2_MASK || + reg == TMIO_SD_ARG) + writew(val >> 16, priv->regbase + (reg >> 1) + 2); + } else + 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 tmio_sd_priv *priv = dev_get_priv(dev); + u32 info2 = tmio_sd_readl(priv, TMIO_SD_INFO2); + + if (info2 & TMIO_SD_INFO2_ERR_RTO) { + /* + * TIMEOUT must be returned for unsupported command. Do not + * display error log since this might be a part of sequence to + * distinguish between SD and MMC. + */ + return -ETIMEDOUT; + } + + if (info2 & TMIO_SD_INFO2_ERR_TO) { + dev_err(dev, "timeout error\n"); + return -ETIMEDOUT; + } + + if (info2 & (TMIO_SD_INFO2_ERR_END | TMIO_SD_INFO2_ERR_CRC | + TMIO_SD_INFO2_ERR_IDX)) { + dev_err(dev, "communication out of sync\n"); + return -EILSEQ; + } + + if (info2 & (TMIO_SD_INFO2_ERR_ILA | TMIO_SD_INFO2_ERR_ILR | + TMIO_SD_INFO2_ERR_ILW)) { + dev_err(dev, "illegal access\n"); + return -EIO; + } + + return 0; +} + +static int tmio_sd_wait_for_irq(struct udevice *dev, unsigned int reg, + u32 flag) +{ + struct tmio_sd_priv *priv = dev_get_priv(dev); + long wait = 1000000; + int ret; + + while (!(tmio_sd_readl(priv, reg) & flag)) { + if (wait-- < 0) { + dev_err(dev, "timeout\n"); + return -ETIMEDOUT; + } + + ret = tmio_sd_check_error(dev); + if (ret) + return ret; + + udelay(1); + } + + return 0; +} + +#define tmio_pio_read_fifo(__width, __suffix) \ +static void tmio_pio_read_fifo_##__width(struct tmio_sd_priv *priv, \ + char *pbuf, uint blksz) \ +{ \ + u##__width *buf = (u##__width *)pbuf; \ + int i; \ + \ + if (likely(IS_ALIGNED((uintptr_t)buf, ((__width) / 8)))) { \ + for (i = 0; i < blksz / ((__width) / 8); i++) { \ + *buf++ = tmio_sd_read##__suffix(priv, \ + TMIO_SD_BUF); \ + } \ + } else { \ + for (i = 0; i < blksz / ((__width) / 8); i++) { \ + u##__width data; \ + data = tmio_sd_read##__suffix(priv, \ + TMIO_SD_BUF); \ + put_unaligned(data, buf++); \ + } \ + } \ +} + +tmio_pio_read_fifo(64, q) +tmio_pio_read_fifo(32, l) +tmio_pio_read_fifo(16, w) + +static int tmio_sd_pio_read_one_block(struct udevice *dev, char *pbuf, + uint blocksize) +{ + struct tmio_sd_priv *priv = dev_get_priv(dev); + int ret; + + /* wait until the buffer is filled with data */ + ret = tmio_sd_wait_for_irq(dev, TMIO_SD_INFO2, + TMIO_SD_INFO2_BRE); + if (ret) + return ret; + + /* + * Clear the status flag _before_ read the buffer out because + * TMIO_SD_INFO2_BRE is edge-triggered, not level-triggered. + */ + tmio_sd_writel(priv, 0, TMIO_SD_INFO2); + + if (priv->caps & TMIO_SD_CAP_64BIT) + tmio_pio_read_fifo_64(priv, pbuf, blocksize); + else if (priv->caps & TMIO_SD_CAP_16BIT) + tmio_pio_read_fifo_16(priv, pbuf, blocksize); + else + tmio_pio_read_fifo_32(priv, pbuf, blocksize); + + return 0; +} + +#define tmio_pio_write_fifo(__width, __suffix) \ +static void tmio_pio_write_fifo_##__width(struct tmio_sd_priv *priv, \ + const char *pbuf, uint blksz)\ +{ \ + const u##__width *buf = (const u##__width *)pbuf; \ + int i; \ + \ + if (likely(IS_ALIGNED((uintptr_t)buf, ((__width) / 8)))) { \ + for (i = 0; i < blksz / ((__width) / 8); i++) { \ + tmio_sd_write##__suffix(priv, *buf++, \ + TMIO_SD_BUF); \ + } \ + } else { \ + for (i = 0; i < blksz / ((__width) / 8); i++) { \ + u##__width data = get_unaligned(buf++); \ + tmio_sd_write##__suffix(priv, data, \ + TMIO_SD_BUF); \ + } \ + } \ +} + +tmio_pio_write_fifo(64, q) +tmio_pio_write_fifo(32, l) +tmio_pio_write_fifo(16, w) + +static int tmio_sd_pio_write_one_block(struct udevice *dev, + const char *pbuf, uint blocksize) +{ + struct tmio_sd_priv *priv = dev_get_priv(dev); + int ret; + + /* wait until the buffer becomes empty */ + ret = tmio_sd_wait_for_irq(dev, TMIO_SD_INFO2, + TMIO_SD_INFO2_BWE); + if (ret) + return ret; + + tmio_sd_writel(priv, 0, TMIO_SD_INFO2); + + if (priv->caps & TMIO_SD_CAP_64BIT) + tmio_pio_write_fifo_64(priv, pbuf, blocksize); + else if (priv->caps & TMIO_SD_CAP_16BIT) + tmio_pio_write_fifo_16(priv, pbuf, blocksize); + else + tmio_pio_write_fifo_32(priv, pbuf, blocksize); + + return 0; +} + +static int tmio_sd_pio_xfer(struct udevice *dev, struct mmc_data *data) +{ + const char *src = data->src; + char *dest = data->dest; + int i, ret; + + for (i = 0; i < data->blocks; i++) { + if (data->flags & MMC_DATA_READ) + ret = tmio_sd_pio_read_one_block(dev, dest, + data->blocksize); + else + ret = tmio_sd_pio_write_one_block(dev, src, + data->blocksize); + if (ret) + return ret; + + if (data->flags & MMC_DATA_READ) + dest += data->blocksize; + else + src += data->blocksize; + } + + return 0; +} + +static void tmio_sd_dma_start(struct tmio_sd_priv *priv, + dma_addr_t dma_addr) +{ + u32 tmp; + + tmio_sd_writel(priv, 0, TMIO_SD_DMA_INFO1); + tmio_sd_writel(priv, 0, TMIO_SD_DMA_INFO2); + + /* enable DMA */ + tmp = tmio_sd_readl(priv, TMIO_SD_EXTMODE); + tmp |= TMIO_SD_EXTMODE_DMA_EN; + tmio_sd_writel(priv, tmp, TMIO_SD_EXTMODE); + + tmio_sd_writel(priv, dma_addr & U32_MAX, TMIO_SD_DMA_ADDR_L); + + /* suppress the warning "right shift count >= width of type" */ + dma_addr >>= min_t(int, 32, 8 * sizeof(dma_addr)); + + tmio_sd_writel(priv, dma_addr & U32_MAX, TMIO_SD_DMA_ADDR_H); + + tmio_sd_writel(priv, TMIO_SD_DMA_CTL_START, TMIO_SD_DMA_CTL); +} + +static int tmio_sd_dma_wait_for_irq(struct udevice *dev, u32 flag, + unsigned int blocks) +{ + struct tmio_sd_priv *priv = dev_get_priv(dev); + long wait = 1000000 + 10 * blocks; + + while (!(tmio_sd_readl(priv, TMIO_SD_DMA_INFO1) & flag)) { + if (wait-- < 0) { + dev_err(dev, "timeout during DMA\n"); + return -ETIMEDOUT; + } + + udelay(10); + } + + if (tmio_sd_readl(priv, TMIO_SD_DMA_INFO2)) { + dev_err(dev, "error during DMA\n"); + return -EIO; + } + + return 0; +} + +static int tmio_sd_dma_xfer(struct udevice *dev, struct mmc_data *data) +{ + struct tmio_sd_priv *priv = dev_get_priv(dev); + size_t len = data->blocks * data->blocksize; + void *buf; + enum dma_data_direction dir; + dma_addr_t dma_addr; + u32 poll_flag, tmp; + int ret; + + tmp = tmio_sd_readl(priv, TMIO_SD_DMA_MODE); + + if (data->flags & MMC_DATA_READ) { + buf = data->dest; + dir = DMA_FROM_DEVICE; + /* + * The DMA READ completion flag position differs on Socionext + * and Renesas SoCs. It is bit 20 on Socionext SoCs and using + * bit 17 is a hardware bug and forbidden. It is bit 17 on + * Renesas SoCs and bit 20 does not work on them. + */ + poll_flag = (priv->caps & TMIO_SD_CAP_RCAR) ? + TMIO_SD_DMA_INFO1_END_RD : + TMIO_SD_DMA_INFO1_END_RD2; + tmp |= TMIO_SD_DMA_MODE_DIR_RD; + } else { + buf = (void *)data->src; + dir = DMA_TO_DEVICE; + poll_flag = TMIO_SD_DMA_INFO1_END_WR; + tmp &= ~TMIO_SD_DMA_MODE_DIR_RD; + } + + tmio_sd_writel(priv, tmp, TMIO_SD_DMA_MODE); + + dma_addr = __dma_map_single(buf, len, dir); + + tmio_sd_dma_start(priv, dma_addr); + + ret = tmio_sd_dma_wait_for_irq(dev, poll_flag, data->blocks); + + __dma_unmap_single(dma_addr, len, dir); + + return ret; +} + +/* check if the address is DMA'able */ +static bool tmio_sd_addr_is_dmaable(unsigned long addr) +{ + if (!IS_ALIGNED(addr, TMIO_SD_DMA_MINALIGN)) + return false; + +#if defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARM64) && \ + defined(CONFIG_SPL_BUILD) + /* + * For UniPhier ARMv7 SoCs, the stack is allocated in the locked ways + * of L2, which is unreachable from the DMA engine. + */ + if (addr < CONFIG_SPL_STACK) + return false; +#endif + + return true; +} + +int tmio_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct tmio_sd_priv *priv = dev_get_priv(dev); + int ret; + u32 tmp; + + if (tmio_sd_readl(priv, TMIO_SD_INFO2) & TMIO_SD_INFO2_CBSY) { + dev_err(dev, "command busy\n"); + return -EBUSY; + } + + /* clear all status flags */ + tmio_sd_writel(priv, 0, TMIO_SD_INFO1); + tmio_sd_writel(priv, 0, TMIO_SD_INFO2); + + /* disable DMA once */ + tmp = tmio_sd_readl(priv, TMIO_SD_EXTMODE); + tmp &= ~TMIO_SD_EXTMODE_DMA_EN; + tmio_sd_writel(priv, tmp, TMIO_SD_EXTMODE); + + tmio_sd_writel(priv, cmd->cmdarg, TMIO_SD_ARG); + + tmp = cmd->cmdidx; + + if (data) { + tmio_sd_writel(priv, data->blocksize, TMIO_SD_SIZE); + tmio_sd_writel(priv, data->blocks, TMIO_SD_SECCNT); + + /* Do not send CMD12 automatically */ + tmp |= TMIO_SD_CMD_NOSTOP | TMIO_SD_CMD_DATA; + + if (data->blocks > 1) + tmp |= TMIO_SD_CMD_MULTI; + + if (data->flags & MMC_DATA_READ) + tmp |= TMIO_SD_CMD_RD; + } + + /* + * Do not use the response type auto-detection on this hardware. + * CMD8, for example, has different response types on SD and eMMC, + * while this controller always assumes the response type for SD. + * Set the response type manually. + */ + switch (cmd->resp_type) { + case MMC_RSP_NONE: + tmp |= TMIO_SD_CMD_RSP_NONE; + break; + case MMC_RSP_R1: + tmp |= TMIO_SD_CMD_RSP_R1; + break; + case MMC_RSP_R1b: + tmp |= TMIO_SD_CMD_RSP_R1B; + break; + case MMC_RSP_R2: + tmp |= TMIO_SD_CMD_RSP_R2; + break; + case MMC_RSP_R3: + tmp |= TMIO_SD_CMD_RSP_R3; + break; + default: + dev_err(dev, "unknown response type\n"); + return -EINVAL; + } + + dev_dbg(dev, "sending CMD%d (SD_CMD=%08x, SD_ARG=%08x)\n", + cmd->cmdidx, tmp, cmd->cmdarg); + tmio_sd_writel(priv, tmp, TMIO_SD_CMD); + + ret = tmio_sd_wait_for_irq(dev, TMIO_SD_INFO1, + TMIO_SD_INFO1_RSP); + if (ret) + return ret; + + if (cmd->resp_type & MMC_RSP_136) { + u32 rsp_127_104 = tmio_sd_readl(priv, TMIO_SD_RSP76); + u32 rsp_103_72 = tmio_sd_readl(priv, TMIO_SD_RSP54); + u32 rsp_71_40 = tmio_sd_readl(priv, TMIO_SD_RSP32); + u32 rsp_39_8 = tmio_sd_readl(priv, TMIO_SD_RSP10); + + cmd->response[0] = ((rsp_127_104 & 0x00ffffff) << 8) | + ((rsp_103_72 & 0xff000000) >> 24); + cmd->response[1] = ((rsp_103_72 & 0x00ffffff) << 8) | + ((rsp_71_40 & 0xff000000) >> 24); + cmd->response[2] = ((rsp_71_40 & 0x00ffffff) << 8) | + ((rsp_39_8 & 0xff000000) >> 24); + cmd->response[3] = (rsp_39_8 & 0xffffff) << 8; + } else { + /* bit 39-8 */ + cmd->response[0] = tmio_sd_readl(priv, TMIO_SD_RSP10); + } + + 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((long)data->src)) + ret = tmio_sd_dma_xfer(dev, data); + else + ret = tmio_sd_pio_xfer(dev, data); + + ret = tmio_sd_wait_for_irq(dev, TMIO_SD_INFO1, + TMIO_SD_INFO1_CMP); + if (ret) + return ret; + } + + tmio_sd_wait_for_irq(dev, TMIO_SD_INFO2, TMIO_SD_INFO2_SCLKDIVEN); + + return ret; +} + +static int tmio_sd_set_bus_width(struct tmio_sd_priv *priv, + struct mmc *mmc) +{ + u32 val, tmp; + + switch (mmc->bus_width) { + case 0: + case 1: + val = TMIO_SD_OPTION_WIDTH_1; + break; + case 4: + val = TMIO_SD_OPTION_WIDTH_4; + break; + case 8: + val = TMIO_SD_OPTION_WIDTH_8; + break; + default: + return -EINVAL; + } + + tmp = tmio_sd_readl(priv, TMIO_SD_OPTION); + tmp &= ~TMIO_SD_OPTION_WIDTH_MASK; + tmp |= val; + tmio_sd_writel(priv, tmp, TMIO_SD_OPTION); + + return 0; +} + +static void tmio_sd_set_ddr_mode(struct tmio_sd_priv *priv, + struct mmc *mmc) +{ + u32 tmp; + + tmp = tmio_sd_readl(priv, TMIO_SD_IF_MODE); + if (mmc->ddr_mode) + tmp |= TMIO_SD_IF_MODE_DDR; + else + tmp &= ~TMIO_SD_IF_MODE_DDR; + tmio_sd_writel(priv, tmp, TMIO_SD_IF_MODE); +} + +static void tmio_sd_set_clk_rate(struct tmio_sd_priv *priv, + struct mmc *mmc) +{ + unsigned int divisor; + u32 val, tmp; + + if (!mmc->clock) + return; + + divisor = DIV_ROUND_UP(priv->mclk, mmc->clock); + + if (divisor <= 1) + val = (priv->caps & TMIO_SD_CAP_RCAR) ? + TMIO_SD_CLKCTL_RCAR_DIV1 : TMIO_SD_CLKCTL_DIV1; + else if (divisor <= 2) + val = TMIO_SD_CLKCTL_DIV2; + else if (divisor <= 4) + val = TMIO_SD_CLKCTL_DIV4; + else if (divisor <= 8) + val = TMIO_SD_CLKCTL_DIV8; + else if (divisor <= 16) + val = TMIO_SD_CLKCTL_DIV16; + else if (divisor <= 32) + val = TMIO_SD_CLKCTL_DIV32; + else if (divisor <= 64) + val = TMIO_SD_CLKCTL_DIV64; + else if (divisor <= 128) + val = TMIO_SD_CLKCTL_DIV128; + else if (divisor <= 256) + val = TMIO_SD_CLKCTL_DIV256; + else if (divisor <= 512 || !(priv->caps & TMIO_SD_CAP_DIV1024)) + val = TMIO_SD_CLKCTL_DIV512; + else + val = TMIO_SD_CLKCTL_DIV1024; + + tmp = tmio_sd_readl(priv, TMIO_SD_CLKCTL); + if (tmp & TMIO_SD_CLKCTL_SCLKEN && + (tmp & TMIO_SD_CLKCTL_DIV_MASK) == val) + return; + + /* stop the clock before changing its rate to avoid a glitch signal */ + tmp &= ~TMIO_SD_CLKCTL_SCLKEN; + tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL); + + tmp &= ~TMIO_SD_CLKCTL_DIV_MASK; + tmp |= val | TMIO_SD_CLKCTL_OFFEN; + tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL); + + tmp |= TMIO_SD_CLKCTL_SCLKEN; + tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL); + + udelay(1000); +} + +static void tmio_sd_set_pins(struct udevice *dev) +{ + __maybe_unused struct mmc *mmc = mmc_get_mmc_dev(dev); + +#ifdef CONFIG_DM_REGULATOR + struct tmio_sd_priv *priv = dev_get_priv(dev); + + if (priv->vqmmc_dev) { + if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) + regulator_set_value(priv->vqmmc_dev, 1800000); + else + regulator_set_value(priv->vqmmc_dev, 3300000); + regulator_set_enable(priv->vqmmc_dev, true); + } +#endif + +#ifdef CONFIG_PINCTRL + switch (mmc->selected_mode) { + case MMC_LEGACY: + case SD_LEGACY: + case MMC_HS: + case SD_HS: + case MMC_HS_52: + case MMC_DDR_52: + pinctrl_select_state(dev, "default"); + break; + case UHS_SDR12: + case UHS_SDR25: + case UHS_SDR50: + case UHS_DDR50: + case UHS_SDR104: + case MMC_HS_200: + pinctrl_select_state(dev, "state_uhs"); + break; + default: + break; + } +#endif +} + +int tmio_sd_set_ios(struct udevice *dev) +{ + struct tmio_sd_priv *priv = dev_get_priv(dev); + struct mmc *mmc = mmc_get_mmc_dev(dev); + int ret; + + dev_dbg(dev, "clock %uHz, DDRmode %d, width %u\n", + mmc->clock, mmc->ddr_mode, mmc->bus_width); + + ret = tmio_sd_set_bus_width(priv, mmc); + if (ret) + return ret; + tmio_sd_set_ddr_mode(priv, mmc); + tmio_sd_set_clk_rate(priv, mmc); + tmio_sd_set_pins(dev); + + return 0; +} + +int tmio_sd_get_cd(struct udevice *dev) +{ + struct tmio_sd_priv *priv = dev_get_priv(dev); + + if (priv->caps & TMIO_SD_CAP_NONREMOVABLE) + return 1; + + return !!(tmio_sd_readl(priv, TMIO_SD_INFO1) & + TMIO_SD_INFO1_CD); +} + +static void tmio_sd_host_init(struct tmio_sd_priv *priv) +{ + u32 tmp; + + /* soft reset of the host */ + tmp = tmio_sd_readl(priv, TMIO_SD_SOFT_RST); + tmp &= ~TMIO_SD_SOFT_RST_RSTX; + tmio_sd_writel(priv, tmp, TMIO_SD_SOFT_RST); + tmp |= TMIO_SD_SOFT_RST_RSTX; + tmio_sd_writel(priv, tmp, TMIO_SD_SOFT_RST); + + /* FIXME: implement eMMC hw_reset */ + + tmio_sd_writel(priv, TMIO_SD_STOP_SEC, TMIO_SD_STOP); + + /* + * Connected to 32bit AXI. + * 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 + 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); + tmp |= TMIO_SD_DMA_MODE_ADDR_INC; + tmio_sd_writel(priv, tmp, TMIO_SD_DMA_MODE); + } +} + +int tmio_sd_bind(struct udevice *dev) +{ + struct tmio_sd_plat *plat = dev_get_platdata(dev); + + return mmc_bind(dev, &plat->mmc, &plat->cfg); +} + +int tmio_sd_probe(struct udevice *dev, u32 quirks) +{ + struct tmio_sd_plat *plat = dev_get_platdata(dev); + struct tmio_sd_priv *priv = dev_get_priv(dev); + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + fdt_addr_t base; + struct clk clk; + int ret; + + base = devfdt_get_addr(dev); + if (base == FDT_ADDR_T_NONE) + return -EINVAL; + + priv->regbase = devm_ioremap(dev, base, SZ_2K); + if (!priv->regbase) + return -ENOMEM; + +#ifdef CONFIG_DM_REGULATOR + device_get_supply_regulator(dev, "vqmmc-supply", &priv->vqmmc_dev); +#endif + + ret = clk_get_by_index(dev, 0, &clk); + if (ret < 0) { + dev_err(dev, "failed to get host clock\n"); + return ret; + } + + /* set to max rate */ + priv->mclk = clk_set_rate(&clk, ULONG_MAX); + if (IS_ERR_VALUE(priv->mclk)) { + dev_err(dev, "failed to set rate for host clock\n"); + clk_free(&clk); + return priv->mclk; + } + + ret = clk_enable(&clk); + clk_free(&clk); + if (ret) { + dev_err(dev, "failed to enable host clock\n"); + return ret; + } + + ret = mmc_of_parse(dev, &plat->cfg); + if (ret < 0) { + dev_err(dev, "failed to parse host caps\n"); + return ret; + } + + plat->cfg.name = dev->name; + plat->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; + + if (quirks) + priv->caps = quirks; + + priv->version = tmio_sd_readl(priv, TMIO_SD_VERSION) & + TMIO_SD_VERSION_IP; + dev_dbg(dev, "version %x\n", priv->version); + if (priv->version >= 0x10) { + priv->caps |= TMIO_SD_CAP_DMA_INTERNAL; + priv->caps |= TMIO_SD_CAP_DIV1024; + } + + if (fdt_get_property(gd->fdt_blob, dev_of_offset(dev), "non-removable", + NULL)) + priv->caps |= TMIO_SD_CAP_NONREMOVABLE; + + tmio_sd_host_init(priv); + + plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34; + plat->cfg.f_min = priv->mclk / + (priv->caps & TMIO_SD_CAP_DIV1024 ? 1024 : 512); + plat->cfg.f_max = priv->mclk; + plat->cfg.b_max = U32_MAX; /* max value of TMIO_SD_SECCNT */ + + upriv->mmc = &plat->mmc; + + return 0; +} diff --git a/drivers/mmc/tmio-common.h b/drivers/mmc/tmio-common.h new file mode 100644 index 0000000000..ef9404409d --- /dev/null +++ b/drivers/mmc/tmio-common.h @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __TMIO_COMMON_H__ +#define __TMIO_COMMON_H__ + +#define TMIO_SD_CMD 0x000 /* command */ +#define TMIO_SD_CMD_NOSTOP BIT(14) /* No automatic CMD12 issue */ +#define TMIO_SD_CMD_MULTI BIT(13) /* multiple block transfer */ +#define TMIO_SD_CMD_RD BIT(12) /* 1: read, 0: write */ +#define TMIO_SD_CMD_DATA BIT(11) /* data transfer */ +#define TMIO_SD_CMD_APP BIT(6) /* ACMD preceded by CMD55 */ +#define TMIO_SD_CMD_NORMAL (0 << 8)/* auto-detect of resp-type */ +#define TMIO_SD_CMD_RSP_NONE (3 << 8)/* response: none */ +#define TMIO_SD_CMD_RSP_R1 (4 << 8)/* response: R1, R5, R6, R7 */ +#define TMIO_SD_CMD_RSP_R1B (5 << 8)/* response: R1b, R5b */ +#define TMIO_SD_CMD_RSP_R2 (6 << 8)/* response: R2 */ +#define TMIO_SD_CMD_RSP_R3 (7 << 8)/* response: R3, R4 */ +#define TMIO_SD_ARG 0x008 /* command argument */ +#define TMIO_SD_STOP 0x010 /* stop action control */ +#define TMIO_SD_STOP_SEC BIT(8) /* use sector count */ +#define TMIO_SD_STOP_STP BIT(0) /* issue CMD12 */ +#define TMIO_SD_SECCNT 0x014 /* sector counter */ +#define TMIO_SD_RSP10 0x018 /* response[39:8] */ +#define TMIO_SD_RSP32 0x020 /* response[71:40] */ +#define TMIO_SD_RSP54 0x028 /* response[103:72] */ +#define TMIO_SD_RSP76 0x030 /* response[127:104] */ +#define TMIO_SD_INFO1 0x038 /* IRQ status 1 */ +#define TMIO_SD_INFO1_CD BIT(5) /* state of card detect */ +#define TMIO_SD_INFO1_INSERT BIT(4) /* card inserted */ +#define TMIO_SD_INFO1_REMOVE BIT(3) /* card removed */ +#define TMIO_SD_INFO1_CMP BIT(2) /* data complete */ +#define TMIO_SD_INFO1_RSP BIT(0) /* response complete */ +#define TMIO_SD_INFO2 0x03c /* IRQ status 2 */ +#define TMIO_SD_INFO2_ERR_ILA BIT(15) /* illegal access err */ +#define TMIO_SD_INFO2_CBSY BIT(14) /* command busy */ +#define TMIO_SD_INFO2_SCLKDIVEN BIT(13) /* command setting reg ena */ +#define TMIO_SD_INFO2_BWE BIT(9) /* write buffer ready */ +#define TMIO_SD_INFO2_BRE BIT(8) /* read buffer ready */ +#define TMIO_SD_INFO2_DAT0 BIT(7) /* SDDAT0 */ +#define TMIO_SD_INFO2_ERR_RTO BIT(6) /* response time out */ +#define TMIO_SD_INFO2_ERR_ILR BIT(5) /* illegal read err */ +#define TMIO_SD_INFO2_ERR_ILW BIT(4) /* illegal write err */ +#define TMIO_SD_INFO2_ERR_TO BIT(3) /* time out error */ +#define TMIO_SD_INFO2_ERR_END BIT(2) /* END bit error */ +#define TMIO_SD_INFO2_ERR_CRC BIT(1) /* CRC error */ +#define TMIO_SD_INFO2_ERR_IDX BIT(0) /* cmd index error */ +#define TMIO_SD_INFO1_MASK 0x040 +#define TMIO_SD_INFO2_MASK 0x044 +#define TMIO_SD_CLKCTL 0x048 /* clock divisor */ +#define TMIO_SD_CLKCTL_DIV_MASK 0x104ff +#define TMIO_SD_CLKCTL_DIV1024 BIT(16) /* SDCLK = CLK / 1024 */ +#define TMIO_SD_CLKCTL_DIV512 BIT(7) /* SDCLK = CLK / 512 */ +#define TMIO_SD_CLKCTL_DIV256 BIT(6) /* SDCLK = CLK / 256 */ +#define TMIO_SD_CLKCTL_DIV128 BIT(5) /* SDCLK = CLK / 128 */ +#define TMIO_SD_CLKCTL_DIV64 BIT(4) /* SDCLK = CLK / 64 */ +#define TMIO_SD_CLKCTL_DIV32 BIT(3) /* SDCLK = CLK / 32 */ +#define TMIO_SD_CLKCTL_DIV16 BIT(2) /* SDCLK = CLK / 16 */ +#define TMIO_SD_CLKCTL_DIV8 BIT(1) /* SDCLK = CLK / 8 */ +#define TMIO_SD_CLKCTL_DIV4 BIT(0) /* SDCLK = CLK / 4 */ +#define TMIO_SD_CLKCTL_DIV2 0 /* SDCLK = CLK / 2 */ +#define TMIO_SD_CLKCTL_DIV1 BIT(10) /* SDCLK = CLK */ +#define TMIO_SD_CLKCTL_RCAR_DIV1 0xff /* SDCLK = CLK (RCar ver.) */ +#define TMIO_SD_CLKCTL_OFFEN BIT(9) /* stop SDCLK when unused */ +#define TMIO_SD_CLKCTL_SCLKEN BIT(8) /* SDCLK output enable */ +#define TMIO_SD_SIZE 0x04c /* block size */ +#define TMIO_SD_OPTION 0x050 +#define TMIO_SD_OPTION_WIDTH_MASK (5 << 13) +#define TMIO_SD_OPTION_WIDTH_1 (4 << 13) +#define TMIO_SD_OPTION_WIDTH_4 (0 << 13) +#define TMIO_SD_OPTION_WIDTH_8 (1 << 13) +#define TMIO_SD_BUF 0x060 /* read/write buffer */ +#define TMIO_SD_EXTMODE 0x1b0 +#define TMIO_SD_EXTMODE_DMA_EN BIT(1) /* transfer 1: DMA, 0: pio */ +#define TMIO_SD_SOFT_RST 0x1c0 +#define TMIO_SD_SOFT_RST_RSTX BIT(0) /* reset deassert */ +#define TMIO_SD_VERSION 0x1c4 /* version register */ +#define TMIO_SD_VERSION_IP 0xff /* IP version */ +#define TMIO_SD_HOST_MODE 0x1c8 +#define TMIO_SD_IF_MODE 0x1cc +#define TMIO_SD_IF_MODE_DDR BIT(0) /* DDR mode */ +#define TMIO_SD_VOLT 0x1e4 /* voltage switch */ +#define TMIO_SD_VOLT_MASK (3 << 0) +#define TMIO_SD_VOLT_OFF (0 << 0) +#define TMIO_SD_VOLT_330 (1 << 0)/* 3.3V signal */ +#define TMIO_SD_VOLT_180 (2 << 0)/* 1.8V signal */ +#define TMIO_SD_DMA_MODE 0x410 +#define TMIO_SD_DMA_MODE_DIR_RD BIT(16) /* 1: from device, 0: to dev */ +#define TMIO_SD_DMA_MODE_ADDR_INC BIT(0) /* 1: address inc, 0: fixed */ +#define TMIO_SD_DMA_CTL 0x414 +#define TMIO_SD_DMA_CTL_START BIT(0) /* start DMA (auto cleared) */ +#define TMIO_SD_DMA_RST 0x418 +#define TMIO_SD_DMA_RST_RD BIT(9) +#define TMIO_SD_DMA_RST_WR BIT(8) +#define TMIO_SD_DMA_INFO1 0x420 +#define TMIO_SD_DMA_INFO1_END_RD2 BIT(20) /* DMA from device is complete (uniphier) */ +#define TMIO_SD_DMA_INFO1_END_RD BIT(17) /* DMA from device is complete (renesas) */ +#define TMIO_SD_DMA_INFO1_END_WR BIT(16) /* DMA to device is complete */ +#define TMIO_SD_DMA_INFO1_MASK 0x424 +#define TMIO_SD_DMA_INFO2 0x428 +#define TMIO_SD_DMA_INFO2_ERR_RD BIT(17) +#define TMIO_SD_DMA_INFO2_ERR_WR BIT(16) +#define TMIO_SD_DMA_INFO2_MASK 0x42c +#define TMIO_SD_DMA_ADDR_L 0x440 +#define TMIO_SD_DMA_ADDR_H 0x444 + +/* alignment required by the DMA engine of this controller */ +#define TMIO_SD_DMA_MINALIGN 0x10 + +struct tmio_sd_plat { + struct mmc_config cfg; + struct mmc mmc; +}; + +struct tmio_sd_priv { + void __iomem *regbase; + unsigned long mclk; + unsigned int version; + u32 caps; +#define TMIO_SD_CAP_NONREMOVABLE BIT(0) /* Nonremovable e.g. eMMC */ +#define TMIO_SD_CAP_DMA_INTERNAL BIT(1) /* have internal DMA engine */ +#define TMIO_SD_CAP_DIV1024 BIT(2) /* divisor 1024 is available */ +#define TMIO_SD_CAP_64BIT BIT(3) /* Controller is 64bit */ +#define TMIO_SD_CAP_16BIT BIT(4) /* Controller is 16bit */ +#define TMIO_SD_CAP_RCAR_GEN2 BIT(5) /* Renesas RCar version of IP */ +#define TMIO_SD_CAP_RCAR_GEN3 BIT(6) /* Renesas RCar version of IP */ +#define TMIO_SD_CAP_RCAR_UHS BIT(7) /* Renesas RCar UHS/SDR modes */ +#define TMIO_SD_CAP_RCAR \ + (TMIO_SD_CAP_RCAR_GEN2 | TMIO_SD_CAP_RCAR_GEN3) +#ifdef CONFIG_DM_REGULATOR + struct udevice *vqmmc_dev; +#endif +}; + +int tmio_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data); +int tmio_sd_set_ios(struct udevice *dev); +int tmio_sd_get_cd(struct udevice *dev); + +int tmio_sd_bind(struct udevice *dev); +int tmio_sd_probe(struct udevice *dev, u32 quirks); + +u32 tmio_sd_readl(struct tmio_sd_priv *priv, unsigned int reg); +void tmio_sd_writel(struct tmio_sd_priv *priv, + u32 val, unsigned int reg); + +#endif /* __TMIO_COMMON_H__ */ diff --git a/drivers/mmc/uniphier-sd.c b/drivers/mmc/uniphier-sd.c index 42eb9c2c84..47379b0328 100644 --- a/drivers/mmc/uniphier-sd.c +++ b/drivers/mmc/uniphier-sd.c @@ -17,12 +17,12 @@ #include #include -#include "matsushita-common.h" +#include "tmio-common.h" static const struct dm_mmc_ops uniphier_sd_ops = { - .send_cmd = matsu_sd_send_cmd, - .set_ios = matsu_sd_set_ios, - .get_cd = matsu_sd_get_cd, + .send_cmd = tmio_sd_send_cmd, + .set_ios = tmio_sd_set_ios, + .get_cd = tmio_sd_get_cd, }; static const struct udevice_id uniphier_sd_match[] = { @@ -32,16 +32,16 @@ static const struct udevice_id uniphier_sd_match[] = { static int uniphier_sd_probe(struct udevice *dev) { - return matsu_sd_probe(dev, 0); + return tmio_sd_probe(dev, 0); } U_BOOT_DRIVER(uniphier_mmc) = { .name = "uniphier-mmc", .id = UCLASS_MMC, .of_match = uniphier_sd_match, - .bind = matsu_sd_bind, + .bind = tmio_sd_bind, .probe = uniphier_sd_probe, - .priv_auto_alloc_size = sizeof(struct matsu_sd_priv), - .platdata_auto_alloc_size = sizeof(struct matsu_sd_plat), + .priv_auto_alloc_size = sizeof(struct tmio_sd_priv), + .platdata_auto_alloc_size = sizeof(struct tmio_sd_plat), .ops = &uniphier_sd_ops, }; -- cgit v1.2.3