diff options
author | Marek Vasut | 2018-04-08 17:41:14 +0200 |
---|---|---|
committer | Marek Vasut | 2018-04-11 23:11:57 +0200 |
commit | db1266d69648aa58a2c59273e4d3b773e0fd4f0f (patch) | |
tree | d563de7a904f18364b4ebcc482fbbb8f6e2f182c /drivers/mmc | |
parent | 620fd85c0b650b4061ba5c989276d58c27280be2 (diff) |
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 <marek.vasut+renesas@gmail.com>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/matsushita-common.c | 42 | ||||
-rw-r--r-- | 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 ec5469850b7..9f7f47c86b4 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 e517a2d56b1..c1b28a0128f 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, |