提交 16e821e3 编写于 作者: M Maxime Ripard 提交者: Ulf Hansson

mmc: sunxi: Mask DATA0 when updating the clock

The A64 MMC controllers need DATA0 to be masked while updating the clock,
otherwise any subsequent command will result in a timeout.

It's not really clear at this point what DATA0 is exactly, but this
behaviour is present in Allwinner's tree, and has been suggested by
Allwinner engineers as fixes for the timeout.
Signed-off-by: NMaxime Ripard <maxime.ripard@free-electrons.com>
Tested-by: NFlorian Vaussard <florian.vaussard@heig-vd.ch>
Acked-by: NChen-Yu Tsai <wens@csie.org>
Signed-off-by: NUlf Hansson <ulf.hansson@linaro.org>
上级 9a37e53e
...@@ -101,6 +101,7 @@ ...@@ -101,6 +101,7 @@
(SDXC_SOFT_RESET | SDXC_FIFO_RESET | SDXC_DMA_RESET) (SDXC_SOFT_RESET | SDXC_FIFO_RESET | SDXC_DMA_RESET)
/* clock control bits */ /* clock control bits */
#define SDXC_MASK_DATA0 BIT(31)
#define SDXC_CARD_CLOCK_ON BIT(16) #define SDXC_CARD_CLOCK_ON BIT(16)
#define SDXC_LOW_POWER_ON BIT(17) #define SDXC_LOW_POWER_ON BIT(17)
...@@ -254,6 +255,9 @@ struct sunxi_mmc_cfg { ...@@ -254,6 +255,9 @@ struct sunxi_mmc_cfg {
/* does the IP block support autocalibration? */ /* does the IP block support autocalibration? */
bool can_calibrate; bool can_calibrate;
/* Does DATA0 needs to be masked while the clock is updated */
bool mask_data0;
bool needs_new_timings; bool needs_new_timings;
}; };
...@@ -657,10 +661,12 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en) ...@@ -657,10 +661,12 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
u32 rval; u32 rval;
rval = mmc_readl(host, REG_CLKCR); rval = mmc_readl(host, REG_CLKCR);
rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON); rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON | SDXC_MASK_DATA0);
if (oclk_en) if (oclk_en)
rval |= SDXC_CARD_CLOCK_ON; rval |= SDXC_CARD_CLOCK_ON;
if (host->cfg->mask_data0)
rval |= SDXC_MASK_DATA0;
mmc_writel(host, REG_CLKCR, rval); mmc_writel(host, REG_CLKCR, rval);
...@@ -680,6 +686,11 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en) ...@@ -680,6 +686,11 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
return -EIO; return -EIO;
} }
if (host->cfg->mask_data0) {
rval = mmc_readl(host, REG_CLKCR);
mmc_writel(host, REG_CLKCR, rval & ~SDXC_MASK_DATA0);
}
return 0; return 0;
} }
...@@ -1081,6 +1092,7 @@ static const struct sunxi_mmc_cfg sun50i_a64_cfg = { ...@@ -1081,6 +1092,7 @@ static const struct sunxi_mmc_cfg sun50i_a64_cfg = {
.idma_des_size_bits = 16, .idma_des_size_bits = 16,
.clk_delays = NULL, .clk_delays = NULL,
.can_calibrate = true, .can_calibrate = true,
.mask_data0 = true,
.needs_new_timings = true, .needs_new_timings = true,
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册