Commit 39cc281f authored by Maxime Ripard's avatar Maxime Ripard Committed by Ulf Hansson

mmc: sunxi: Fix clock frequency change sequence

The SD specification documents that the clock frequency should only be
changed once gated (Section 3.2.3 - SD Clock Frequency Change Sequence).

The current code first modifies the parent clock, gates it and then
modifies the internal divider. This means that since the parent clock rate
might be changed, the bus clock might be changed as well before it is
gated, which breaks the specification.

Move the gating before the parent rate modification.
Signed-off-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
Tested-by: default avatarFlorian Vaussard <florian.vaussard@heig-vd.ch>
Acked-by: default avatarChen-Yu Tsai <wens@csie.org>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 1ed21719
...@@ -761,6 +761,10 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, ...@@ -761,6 +761,10 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
u32 rval, clock = ios->clock; u32 rval, clock = ios->clock;
int ret; int ret;
ret = sunxi_mmc_oclk_onoff(host, 0);
if (ret)
return ret;
/* 8 bit DDR requires a higher module clock */ /* 8 bit DDR requires a higher module clock */
if (ios->timing == MMC_TIMING_MMC_DDR52 && if (ios->timing == MMC_TIMING_MMC_DDR52 &&
ios->bus_width == MMC_BUS_WIDTH_8) ios->bus_width == MMC_BUS_WIDTH_8)
...@@ -783,10 +787,6 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, ...@@ -783,10 +787,6 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
return ret; return ret;
} }
ret = sunxi_mmc_oclk_onoff(host, 0);
if (ret)
return ret;
/* clear internal divider */ /* clear internal divider */
rval = mmc_readl(host, REG_CLKCR); rval = mmc_readl(host, REG_CLKCR);
rval &= ~0xff; rval &= ~0xff;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment