From db1266d69648aa58a2c59273e4d3b773e0fd4f0f Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 8 Apr 2018 17:41:14 +0200 Subject: [PATCH] mmc: uniphier: Add support for 16bit variant Add support for 16bit mutation of the Matsushita SD IP. Since some registers are internally 32bit, the matsu_sd_{read,write}l() has to special-case this 16bit variant a bit. Signed-off-by: Marek Vasut Cc: Jaehoon Chung Cc: Masahiro Yamada --- drivers/mmc/matsushita-common.c | 42 +++++++++++++++++++++++++++++---- drivers/mmc/matsushita-common.h | 1 + 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/matsushita-common.c b/drivers/mmc/matsushita-common.c index ec5469850b..9f7f47c86b 100644 --- a/drivers/mmc/matsushita-common.c +++ b/drivers/mmc/matsushita-common.c @@ -32,11 +32,31 @@ static void matsu_sd_writeq(struct matsu_sd_priv *priv, 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)); +} + static 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 + 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); } @@ -45,7 +65,11 @@ static void matsu_sd_writel(struct matsu_sd_priv *priv, { 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 (val >> 16) + writew(val >> 16, priv->regbase + (reg >> 1) + 2); + } else writel(val, priv->regbase + reg); } @@ -150,6 +174,7 @@ static void matsu_pio_read_fifo_##__width(struct matsu_sd_priv *priv, \ 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) @@ -171,6 +196,8 @@ static int matsu_sd_pio_read_one_block(struct udevice *dev, char *pbuf, 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); @@ -200,6 +227,7 @@ static void matsu_pio_write_fifo_##__width(struct matsu_sd_priv *priv, \ 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) @@ -217,6 +245,8 @@ static int matsu_sd_pio_write_one_block(struct udevice *dev, 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); @@ -602,8 +632,12 @@ static void matsu_sd_host_init(struct matsu_sd_priv *priv) * This register dropped backward compatibility at version 0x10. * Write an appropriate value depending on the IP version. */ - matsu_sd_writel(priv, priv->version >= 0x10 ? 0x00000101 : 0x00000000, - MATSU_SD_HOST_MODE); + if (priv->version >= 0x10) + matsu_sd_writel(priv, 0x101, MATSU_SD_HOST_MODE); + else if (priv->caps & MATSU_SD_CAP_16BIT) + matsu_sd_writel(priv, 0x1, 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); diff --git a/drivers/mmc/matsushita-common.h b/drivers/mmc/matsushita-common.h index e517a2d56b..c1b28a0128 100644 --- a/drivers/mmc/matsushita-common.h +++ b/drivers/mmc/matsushita-common.h @@ -123,6 +123,7 @@ struct matsu_sd_priv { #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 */ }; int matsu_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, -- 2.25.1