aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorDouglas Anderson <dianders@chromium.org>2016-05-12 14:31:50 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2016-05-23 05:45:47 -0400
commitd4aa908c7978f60557a799ca53b5ae4166fd8355 (patch)
treeea02d8c1fb6f78de87e57cd5b6180eda84724da2 /drivers/mmc
parent225faf871ec24f3fa6daa4d2324b5de56690e1c5 (diff)
mmc: dw_mmc: rockchip: Set the drive phase properly
Historically for Rockchip devices we've relied on the power-on default (or perhaps the firmware setting) to get the correct drive phase for dw_mmc devices. This worked OK for the most part, but: * Relying on the setting just "being right" is a bit fragile. * As soon as there is an instance where the power on default is wrong or where the firmware didn't configure this properly then we'll get a mysterious failure. In commit 7a03fe6f48f3 ("clk: rockchip: reset init state before mmc card initialization") we actually started setting this explicitly in the kernel, but that commit wasn't quite right and also wasn't quite enough. See <https://patchwork.kernel.org/patch/9085311/> for some details. Let's explicitly set this phase in dw_mmc. The comments inside this patch try to explain the situation quite throughly, but the high level overview of this is: Before this patch on rk3288 devices tested (after revert of the clock patch described above): * eMMC: 180 degrees * SDMMC/SDIO0/SDIO1: 90 degrees After this patch: * Use 90 degree phase offset usually. * Use 180 degree phase offset for MMC_DDR52, SDR104, HS200. That means we are _changing_ behavior for those devices in this way: * If we have HS200 eMMC or DDR52 eMMC, we'll run ID mode at 90 degrees (vs 180) but otherwise have no change. * For any non-HS200 / non-DDR52 eMMC devices we'll now _always_ run at 90 degrees (vs 180). It seems fairly unlikely that building modern hardware is using an eMMC that isn't using DDR52 or HS200, of course. * For SDR104 cards we'll now run with 180 degree phase offset (vs 90). It's expected that 90 degree phase offset would have worked OK, but this gives us extra margin. I have tested this by inserting my collection of uSD cards (mostly UHS, though a few not) into a veyron_minnie and confirmed that they still seem to enumerate properly. For a subset of them I tried putting a filesystem on them and also tried running mmc_test. Fixes: 7a03fe6f48f3 ("clk: rockchip: reset init state before mmc card initialization") Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Tested-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/dw_mmc-rockchip.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
index 2b4bcd212767..358b0dc853b0 100644
--- a/drivers/mmc/host/dw_mmc-rockchip.c
+++ b/drivers/mmc/host/dw_mmc-rockchip.c
@@ -66,6 +66,70 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
66 /* Make sure we use phases which we can enumerate with */ 66 /* Make sure we use phases which we can enumerate with */
67 if (!IS_ERR(priv->sample_clk)) 67 if (!IS_ERR(priv->sample_clk))
68 clk_set_phase(priv->sample_clk, priv->default_sample_phase); 68 clk_set_phase(priv->sample_clk, priv->default_sample_phase);
69
70 /*
71 * Set the drive phase offset based on speed mode to achieve hold times.
72 *
73 * NOTE: this is _not_ a value that is dynamically tuned and is also
74 * _not_ a value that will vary from board to board. It is a value
75 * that could vary between different SoC models if they had massively
76 * different output clock delays inside their dw_mmc IP block (delay_o),
77 * but since it's OK to overshoot a little we don't need to do complex
78 * calculations and can pick values that will just work for everyone.
79 *
80 * When picking values we'll stick with picking 0/90/180/270 since
81 * those can be made very accurately on all known Rockchip SoCs.
82 *
83 * Note that these values match values from the DesignWare Databook
84 * tables for the most part except for SDR12 and "ID mode". For those
85 * two modes the databook calculations assume a clock in of 50MHz. As
86 * seen above, we always use a clock in rate that is exactly the
87 * card's input clock (times RK3288_CLKGEN_DIV, but that gets divided
88 * back out before the controller sees it).
89 *
90 * From measurement of a single device, it appears that delay_o is
91 * about .5 ns. Since we try to leave a bit of margin, it's expected
92 * that numbers here will be fine even with much larger delay_o
93 * (the 1.4 ns assumed by the DesignWare Databook would result in the
94 * same results, for instance).
95 */
96 if (!IS_ERR(priv->drv_clk)) {
97 int phase;
98
99 /*
100 * In almost all cases a 90 degree phase offset will provide
101 * sufficient hold times across all valid input clock rates
102 * assuming delay_o is not absurd for a given SoC. We'll use
103 * that as a default.
104 */
105 phase = 90;
106
107 switch (ios->timing) {
108 case MMC_TIMING_MMC_DDR52:
109 /*
110 * Since clock in rate with MMC_DDR52 is doubled when
111 * bus width is 8 we need to double the phase offset
112 * to get the same timings.
113 */
114 if (ios->bus_width == MMC_BUS_WIDTH_8)
115 phase = 180;
116 break;
117 case MMC_TIMING_UHS_SDR104:
118 case MMC_TIMING_MMC_HS200:
119 /*
120 * In the case of 150 MHz clock (typical max for
121 * Rockchip SoCs), 90 degree offset will add a delay
122 * of 1.67 ns. That will meet min hold time of .8 ns
123 * as long as clock output delay is < .87 ns. On
124 * SoCs measured this seems to be OK, but it doesn't
125 * hurt to give margin here, so we use 180.
126 */
127 phase = 180;
128 break;
129 }
130
131 clk_set_phase(priv->drv_clk, phase);
132 }
69} 133}
70 134
71#define NUM_PHASES 360 135#define NUM_PHASES 360