mmc: tmio: Configure HOST_MODE WMODE according to bus width
[pandora-u-boot.git] / drivers / mmc / tmio-common.c
index 138de59..6e656e5 100644 (file)
@@ -95,7 +95,7 @@ static void __dma_unmap_single(dma_addr_t addr, size_t size,
                invalidate_dcache_range(addr, addr + size);
 }
 
-static int tmio_sd_check_error(struct udevice *dev)
+static int tmio_sd_check_error(struct udevice *dev, struct mmc_cmd *cmd)
 {
        struct tmio_sd_priv *priv = dev_get_priv(dev);
        u32 info2 = tmio_sd_readl(priv, TMIO_SD_INFO2);
@@ -116,7 +116,9 @@ static int tmio_sd_check_error(struct udevice *dev)
 
        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");
+               if ((cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK) &&
+                   (cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK_HS200))
+                       dev_err(dev, "communication out of sync\n");
                return -EILSEQ;
        }
 
@@ -129,8 +131,8 @@ static int tmio_sd_check_error(struct udevice *dev)
        return 0;
 }
 
-static int tmio_sd_wait_for_irq(struct udevice *dev, unsigned int reg,
-                                   u32 flag)
+static int tmio_sd_wait_for_irq(struct udevice *dev, struct mmc_cmd *cmd,
+                               unsigned int reg, u32 flag)
 {
        struct tmio_sd_priv *priv = dev_get_priv(dev);
        long wait = 1000000;
@@ -142,7 +144,7 @@ static int tmio_sd_wait_for_irq(struct udevice *dev, unsigned int reg,
                        return -ETIMEDOUT;
                }
 
-               ret = tmio_sd_check_error(dev);
+               ret = tmio_sd_check_error(dev, cmd);
                if (ret)
                        return ret;
 
@@ -178,15 +180,15 @@ 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)
+static int tmio_sd_pio_read_one_block(struct udevice *dev, struct mmc_cmd *cmd,
+                                     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);
+       ret = tmio_sd_wait_for_irq(dev, cmd, TMIO_SD_INFO2,
+                                  TMIO_SD_INFO2_BRE);
        if (ret)
                return ret;
 
@@ -231,15 +233,15 @@ 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,
+static int tmio_sd_pio_write_one_block(struct udevice *dev, struct mmc_cmd *cmd,
                                           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);
+       ret = tmio_sd_wait_for_irq(dev, cmd, TMIO_SD_INFO2,
+                                  TMIO_SD_INFO2_BWE);
        if (ret)
                return ret;
 
@@ -255,7 +257,8 @@ static int tmio_sd_pio_write_one_block(struct udevice *dev,
        return 0;
 }
 
-static int tmio_sd_pio_xfer(struct udevice *dev, struct mmc_data *data)
+static int tmio_sd_pio_xfer(struct udevice *dev, struct mmc_cmd *cmd,
+                           struct mmc_data *data)
 {
        const char *src = data->src;
        char *dest = data->dest;
@@ -263,10 +266,10 @@ static int tmio_sd_pio_xfer(struct udevice *dev, struct mmc_data *data)
 
        for (i = 0; i < data->blocks; i++) {
                if (data->flags & MMC_DATA_READ)
-                       ret = tmio_sd_pio_read_one_block(dev, dest,
+                       ret = tmio_sd_pio_read_one_block(dev, cmd, dest,
                                                             data->blocksize);
                else
-                       ret = tmio_sd_pio_write_one_block(dev, src,
+                       ret = tmio_sd_pio_write_one_block(dev, cmd, src,
                                                              data->blocksize);
                if (ret)
                        return ret;
@@ -344,12 +347,10 @@ static int tmio_sd_dma_xfer(struct udevice *dev, struct mmc_data *data)
                /*
                 * 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.
+                * bit 17 is a hardware bug and forbidden. It is either bit 17
+                * or bit 20 on Renesas SoCs, depending on SoC.
                 */
-               poll_flag = (priv->caps & TMIO_SD_CAP_RCAR) ?
-                           TMIO_SD_DMA_INFO1_END_RD :
-                           TMIO_SD_DMA_INFO1_END_RD2;
+               poll_flag = priv->read_poll_flag;
                tmp |= TMIO_SD_DMA_MODE_DIR_RD;
        } else {
                buf = (void *)data->src;
@@ -366,6 +367,9 @@ static int tmio_sd_dma_xfer(struct udevice *dev, struct mmc_data *data)
 
        ret = tmio_sd_dma_wait_for_irq(dev, poll_flag, data->blocks);
 
+       if (poll_flag == TMIO_SD_DMA_INFO1_END_RD)
+               udelay(1);
+
        __dma_unmap_single(dma_addr, len, dir);
 
        return ret;
@@ -468,8 +472,8 @@ int tmio_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
                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);
+       ret = tmio_sd_wait_for_irq(dev, cmd, TMIO_SD_INFO1,
+                                  TMIO_SD_INFO1_RSP);
        if (ret)
                return ret;
 
@@ -497,17 +501,18 @@ int tmio_sd_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
                    tmio_sd_addr_is_dmaable(data->src))
                        ret = tmio_sd_dma_xfer(dev, data);
                else
-                       ret = tmio_sd_pio_xfer(dev, data);
+                       ret = tmio_sd_pio_xfer(dev, cmd, data);
+               if (ret)
+                       return ret;
 
-               ret = tmio_sd_wait_for_irq(dev, TMIO_SD_INFO1,
-                                              TMIO_SD_INFO1_CMP);
+               ret = tmio_sd_wait_for_irq(dev, cmd, 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;
+       return tmio_sd_wait_for_irq(dev, cmd, TMIO_SD_INFO2,
+                                   TMIO_SD_INFO2_SCLKDIVEN);
 }
 
 static int tmio_sd_set_bus_width(struct tmio_sd_priv *priv,
@@ -551,55 +556,76 @@ static void tmio_sd_set_ddr_mode(struct tmio_sd_priv *priv,
        tmio_sd_writel(priv, tmp, TMIO_SD_IF_MODE);
 }
 
-static void tmio_sd_set_clk_rate(struct tmio_sd_priv *priv,
-                                    struct mmc *mmc)
+static ulong tmio_sd_clk_get_rate(struct tmio_sd_priv *priv)
 {
-       unsigned int divisor;
-       u32 val, tmp;
+       return priv->clk_get_rate(priv);
+}
 
-       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;
+static void tmio_sd_set_clk_rate(struct tmio_sd_priv *priv, struct mmc *mmc)
+{
+       unsigned int divisor;
+       u32 tmp, val = 0;
+       ulong mclk;
+
+       if (mmc->clock) {
+               mclk = tmio_sd_clk_get_rate(priv);
+
+               divisor = DIV_ROUND_UP(mclk, mmc->clock);
+
+               /* Do not set divider to 0xff in DDR mode */
+               if (mmc->ddr_mode && (divisor == 1))
+                       divisor = 2;
+
+               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;
+       if (mmc->clock &&
+           !((tmp & TMIO_SD_CLKCTL_SCLKEN) &&
+             ((tmp & TMIO_SD_CLKCTL_DIV_MASK) == val))) {
+               /*
+                * 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);
 
-       /* 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);
+               /* Change the clock rate. */
+               tmp &= ~TMIO_SD_CLKCTL_DIV_MASK;
+               tmp |= val;
+       }
 
-       tmp &= ~TMIO_SD_CLKCTL_DIV_MASK;
-       tmp |= val | TMIO_SD_CLKCTL_OFFEN;
-       tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL);
+       /* Enable or Disable the clock */
+       if (mmc->clk_disable) {
+               tmp |= TMIO_SD_CLKCTL_OFFEN;
+               tmp &= ~TMIO_SD_CLKCTL_SCLKEN;
+       } else {
+               tmp &= ~TMIO_SD_CLKCTL_OFFEN;
+               tmp |= TMIO_SD_CLKCTL_SCLKEN;
+       }
 
-       tmp |= TMIO_SD_CLKCTL_SCLKEN;
        tmio_sd_writel(priv, tmp, TMIO_SD_CLKCTL);
 
        udelay(1000);
@@ -622,26 +648,10 @@ static void tmio_sd_set_pins(struct udevice *dev)
 #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:
+       if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180)
                pinctrl_select_state(dev, "state_uhs");
-               break;
-       default:
-               break;
-       }
+       else
+               pinctrl_select_state(dev, "default");
 #endif
 }
 
@@ -654,11 +664,11 @@ int tmio_sd_set_ios(struct udevice *dev)
        dev_dbg(dev, "clock %uHz, DDRmode %d, width %u\n",
                mmc->clock, mmc->ddr_mode, mmc->bus_width);
 
+       tmio_sd_set_clk_rate(priv, mmc);
        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;
@@ -695,10 +705,14 @@ static void tmio_sd_host_init(struct tmio_sd_priv *priv)
         * 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
+       if (priv->version >= 0x10) {
+               if (priv->caps & TMIO_SD_CAP_64BIT)
+                       tmio_sd_writel(priv, 0x100, TMIO_SD_HOST_MODE);
+               else
+                       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);
@@ -720,6 +734,7 @@ int tmio_sd_probe(struct udevice *dev, u32 quirks)
        struct tmio_sd_priv *priv = dev_get_priv(dev);
        struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
        fdt_addr_t base;
+       ulong mclk;
        int ret;
 
        base = devfdt_get_addr(dev);
@@ -732,6 +747,8 @@ int tmio_sd_probe(struct udevice *dev, u32 quirks)
 
 #ifdef CONFIG_DM_REGULATOR
        device_get_supply_regulator(dev, "vqmmc-supply", &priv->vqmmc_dev);
+       if (priv->vqmmc_dev)
+               regulator_set_value(priv->vqmmc_dev, 3300000);
 #endif
 
        ret = mmc_of_parse(dev, &plat->cfg);
@@ -760,10 +777,12 @@ int tmio_sd_probe(struct udevice *dev, u32 quirks)
 
        tmio_sd_host_init(priv);
 
+       mclk = tmio_sd_clk_get_rate(priv);
+
        plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
-       plat->cfg.f_min = priv->mclk /
+       plat->cfg.f_min = mclk /
                        (priv->caps & TMIO_SD_CAP_DIV1024 ? 1024 : 512);
-       plat->cfg.f_max = priv->mclk;
+       plat->cfg.f_max = mclk;
        plat->cfg.b_max = U32_MAX; /* max value of TMIO_SD_SECCNT */
 
        upriv->mmc = &plat->mmc;