Commit db1266d69648aa58a2c59273e4d3b773e0fd4f0f
1 parent
620fd85c0b
Exists in
smarc_8mq_lf_v2020.04
and in
14 other branches
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>
Showing 2 changed files with 39 additions and 4 deletions Side-by-side Diff
drivers/mmc/matsushita-common.c
| ... | ... | @@ -32,11 +32,31 @@ |
| 32 | 32 | writeq(val, priv->regbase + (reg << 1)); |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | +static u16 matsu_sd_readw(struct matsu_sd_priv *priv, unsigned int reg) | |
| 36 | +{ | |
| 37 | + return readw(priv->regbase + (reg >> 1)); | |
| 38 | +} | |
| 39 | + | |
| 40 | +static void matsu_sd_writew(struct matsu_sd_priv *priv, | |
| 41 | + u16 val, unsigned int reg) | |
| 42 | +{ | |
| 43 | + writew(val, priv->regbase + (reg >> 1)); | |
| 44 | +} | |
| 45 | + | |
| 35 | 46 | static u32 matsu_sd_readl(struct matsu_sd_priv *priv, unsigned int reg) |
| 36 | 47 | { |
| 48 | + u32 val; | |
| 49 | + | |
| 37 | 50 | if (priv->caps & MATSU_SD_CAP_64BIT) |
| 38 | 51 | return readl(priv->regbase + (reg << 1)); |
| 39 | - else | |
| 52 | + else if (priv->caps & MATSU_SD_CAP_16BIT) { | |
| 53 | + val = readw(priv->regbase + (reg >> 1)) & 0xffff; | |
| 54 | + if ((reg == MATSU_SD_RSP10) || (reg == MATSU_SD_RSP32) || | |
| 55 | + (reg == MATSU_SD_RSP54) || (reg == MATSU_SD_RSP76)) { | |
| 56 | + val |= readw(priv->regbase + (reg >> 1) + 2) << 16; | |
| 57 | + } | |
| 58 | + return val; | |
| 59 | + } else | |
| 40 | 60 | return readl(priv->regbase + reg); |
| 41 | 61 | } |
| 42 | 62 | |
| ... | ... | @@ -45,7 +65,11 @@ |
| 45 | 65 | { |
| 46 | 66 | if (priv->caps & MATSU_SD_CAP_64BIT) |
| 47 | 67 | writel(val, priv->regbase + (reg << 1)); |
| 48 | - else | |
| 68 | + if (priv->caps & MATSU_SD_CAP_16BIT) { | |
| 69 | + writew(val & 0xffff, priv->regbase + (reg >> 1)); | |
| 70 | + if (val >> 16) | |
| 71 | + writew(val >> 16, priv->regbase + (reg >> 1) + 2); | |
| 72 | + } else | |
| 49 | 73 | writel(val, priv->regbase + reg); |
| 50 | 74 | } |
| 51 | 75 | |
| ... | ... | @@ -150,6 +174,7 @@ |
| 150 | 174 | |
| 151 | 175 | matsu_pio_read_fifo(64, q) |
| 152 | 176 | matsu_pio_read_fifo(32, l) |
| 177 | +matsu_pio_read_fifo(16, w) | |
| 153 | 178 | |
| 154 | 179 | static int matsu_sd_pio_read_one_block(struct udevice *dev, char *pbuf, |
| 155 | 180 | uint blocksize) |
| ... | ... | @@ -171,6 +196,8 @@ |
| 171 | 196 | |
| 172 | 197 | if (priv->caps & MATSU_SD_CAP_64BIT) |
| 173 | 198 | matsu_pio_read_fifo_64(priv, pbuf, blocksize); |
| 199 | + else if (priv->caps & MATSU_SD_CAP_16BIT) | |
| 200 | + matsu_pio_read_fifo_16(priv, pbuf, blocksize); | |
| 174 | 201 | else |
| 175 | 202 | matsu_pio_read_fifo_32(priv, pbuf, blocksize); |
| 176 | 203 | |
| ... | ... | @@ -200,6 +227,7 @@ |
| 200 | 227 | |
| 201 | 228 | matsu_pio_write_fifo(64, q) |
| 202 | 229 | matsu_pio_write_fifo(32, l) |
| 230 | +matsu_pio_write_fifo(16, w) | |
| 203 | 231 | |
| 204 | 232 | static int matsu_sd_pio_write_one_block(struct udevice *dev, |
| 205 | 233 | const char *pbuf, uint blocksize) |
| ... | ... | @@ -217,6 +245,8 @@ |
| 217 | 245 | |
| 218 | 246 | if (priv->caps & MATSU_SD_CAP_64BIT) |
| 219 | 247 | matsu_pio_write_fifo_64(priv, pbuf, blocksize); |
| 248 | + else if (priv->caps & MATSU_SD_CAP_16BIT) | |
| 249 | + matsu_pio_write_fifo_16(priv, pbuf, blocksize); | |
| 220 | 250 | else |
| 221 | 251 | matsu_pio_write_fifo_32(priv, pbuf, blocksize); |
| 222 | 252 | |
| ... | ... | @@ -602,8 +632,12 @@ |
| 602 | 632 | * This register dropped backward compatibility at version 0x10. |
| 603 | 633 | * Write an appropriate value depending on the IP version. |
| 604 | 634 | */ |
| 605 | - matsu_sd_writel(priv, priv->version >= 0x10 ? 0x00000101 : 0x00000000, | |
| 606 | - MATSU_SD_HOST_MODE); | |
| 635 | + if (priv->version >= 0x10) | |
| 636 | + matsu_sd_writel(priv, 0x101, MATSU_SD_HOST_MODE); | |
| 637 | + else if (priv->caps & MATSU_SD_CAP_16BIT) | |
| 638 | + matsu_sd_writel(priv, 0x1, MATSU_SD_HOST_MODE); | |
| 639 | + else | |
| 640 | + matsu_sd_writel(priv, 0x0, MATSU_SD_HOST_MODE); | |
| 607 | 641 | |
| 608 | 642 | if (priv->caps & MATSU_SD_CAP_DMA_INTERNAL) { |
| 609 | 643 | tmp = matsu_sd_readl(priv, MATSU_SD_DMA_MODE); |
drivers/mmc/matsushita-common.h
| ... | ... | @@ -123,6 +123,7 @@ |
| 123 | 123 | #define MATSU_SD_CAP_DMA_INTERNAL BIT(1) /* have internal DMA engine */ |
| 124 | 124 | #define MATSU_SD_CAP_DIV1024 BIT(2) /* divisor 1024 is available */ |
| 125 | 125 | #define MATSU_SD_CAP_64BIT BIT(3) /* Controller is 64bit */ |
| 126 | +#define MATSU_SD_CAP_16BIT BIT(4) /* Controller is 16bit */ | |
| 126 | 127 | }; |
| 127 | 128 | |
| 128 | 129 | int matsu_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, |