diff mbox series

[U-Boot,03/15] mmc: uniphier: Add support for 16bit variant

Message ID 20180409153105.13597-3-marek.vasut+renesas@gmail.com
State Accepted
Commit db1266d69648aa58a2c59273e4d3b773e0fd4f0f
Delegated to: Jaehoon Chung
Headers show
Series [U-Boot,01/15] mmc: uniphier: Factor out FIFO accessors | expand

Commit Message

Marek Vasut April 9, 2018, 3:30 p.m. UTC
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>
---
 drivers/mmc/matsushita-common.c | 42 +++++++++++++++++++++++++++++++++++++----
 drivers/mmc/matsushita-common.h |  1 +
 2 files changed, 39 insertions(+), 4 deletions(-)
diff mbox series

Patch

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,