layerscape: add linux 4.9 support
[openwrt/staging/wigyori.git] / target / linux / layerscape / patches-4.9 / 812-mmc-layerscape-support.patch
1 From b31046c51c72232363711f0c623df08bf28c37e4 Mon Sep 17 00:00:00 2001
2 From: Yangbo Lu <yangbo.lu@nxp.com>
3 Date: Mon, 25 Sep 2017 12:21:30 +0800
4 Subject: [PATCH] mmc: layerscape support
5
6 This is a integrated patch for layerscape mmc support.
7
8 Adrian Hunter <adrian.hunter@intel.com>
9 Jaehoon Chung <jh80.chung@samsung.com>
10 Masahiro Yamada <yamada.masahiro@socionext.com>
11 Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
12 ---
13 drivers/mmc/host/Kconfig | 1 +
14 drivers/mmc/host/sdhci-esdhc.h | 52 +++++---
15 drivers/mmc/host/sdhci-of-esdhc.c | 251 ++++++++++++++++++++++++++++++++++++--
16 drivers/mmc/host/sdhci.c | 45 ++++---
17 drivers/mmc/host/sdhci.h | 3 +
18 5 files changed, 306 insertions(+), 46 deletions(-)
19
20 diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
21 index 5274f503..a1135a92 100644
22 --- a/drivers/mmc/host/Kconfig
23 +++ b/drivers/mmc/host/Kconfig
24 @@ -144,6 +144,7 @@ config MMC_SDHCI_OF_ESDHC
25 depends on MMC_SDHCI_PLTFM
26 depends on PPC || ARCH_MXC || ARCH_LAYERSCAPE
27 select MMC_SDHCI_IO_ACCESSORS
28 + select FSL_GUTS
29 help
30 This selects the Freescale eSDHC controller support.
31
32 diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
33 index de132e28..98898a30 100644
34 --- a/drivers/mmc/host/sdhci-esdhc.h
35 +++ b/drivers/mmc/host/sdhci-esdhc.h
36 @@ -24,30 +24,46 @@
37 SDHCI_QUIRK_PIO_NEEDS_DELAY | \
38 SDHCI_QUIRK_NO_HISPD_BIT)
39
40 -#define ESDHC_PROCTL 0x28
41 -
42 -#define ESDHC_SYSTEM_CONTROL 0x2c
43 -#define ESDHC_CLOCK_MASK 0x0000fff0
44 -#define ESDHC_PREDIV_SHIFT 8
45 -#define ESDHC_DIVIDER_SHIFT 4
46 -#define ESDHC_CLOCK_PEREN 0x00000004
47 -#define ESDHC_CLOCK_HCKEN 0x00000002
48 -#define ESDHC_CLOCK_IPGEN 0x00000001
49 -
50 /* pltfm-specific */
51 #define ESDHC_HOST_CONTROL_LE 0x20
52
53 /*
54 - * P2020 interpretation of the SDHCI_HOST_CONTROL register
55 + * eSDHC register definition
56 */
57 -#define ESDHC_CTRL_4BITBUS (0x1 << 1)
58 -#define ESDHC_CTRL_8BITBUS (0x2 << 1)
59 -#define ESDHC_CTRL_BUSWIDTH_MASK (0x3 << 1)
60
61 -/* OF-specific */
62 -#define ESDHC_DMA_SYSCTL 0x40c
63 -#define ESDHC_DMA_SNOOP 0x00000040
64 +/* Present State Register */
65 +#define ESDHC_PRSSTAT 0x24
66 +#define ESDHC_CLOCK_STABLE 0x00000008
67 +
68 +/* Protocol Control Register */
69 +#define ESDHC_PROCTL 0x28
70 +#define ESDHC_VOLT_SEL 0x00000400
71 +#define ESDHC_CTRL_4BITBUS (0x1 << 1)
72 +#define ESDHC_CTRL_8BITBUS (0x2 << 1)
73 +#define ESDHC_CTRL_BUSWIDTH_MASK (0x3 << 1)
74 +#define ESDHC_HOST_CONTROL_RES 0x01
75 +
76 +/* System Control Register */
77 +#define ESDHC_SYSTEM_CONTROL 0x2c
78 +#define ESDHC_CLOCK_MASK 0x0000fff0
79 +#define ESDHC_PREDIV_SHIFT 8
80 +#define ESDHC_DIVIDER_SHIFT 4
81 +#define ESDHC_CLOCK_SDCLKEN 0x00000008
82 +#define ESDHC_CLOCK_PEREN 0x00000004
83 +#define ESDHC_CLOCK_HCKEN 0x00000002
84 +#define ESDHC_CLOCK_IPGEN 0x00000001
85 +
86 +/* Host Controller Capabilities Register 2 */
87 +#define ESDHC_CAPABILITIES_1 0x114
88 +
89 +/* Tuning Block Control Register */
90 +#define ESDHC_TBCTL 0x120
91 +#define ESDHC_TB_EN 0x00000004
92
93 -#define ESDHC_HOST_CONTROL_RES 0x01
94 +/* Control Register for DMA transfer */
95 +#define ESDHC_DMA_SYSCTL 0x40c
96 +#define ESDHC_PERIPHERAL_CLK_SEL 0x00080000
97 +#define ESDHC_FLUSH_ASYNC_FIFO 0x00040000
98 +#define ESDHC_DMA_SNOOP 0x00000040
99
100 #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
101 diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
102 index 3c27401c..4b0f375b 100644
103 --- a/drivers/mmc/host/sdhci-of-esdhc.c
104 +++ b/drivers/mmc/host/sdhci-of-esdhc.c
105 @@ -16,8 +16,12 @@
106 #include <linux/err.h>
107 #include <linux/io.h>
108 #include <linux/of.h>
109 +#include <linux/of_address.h>
110 #include <linux/delay.h>
111 #include <linux/module.h>
112 +#include <linux/sys_soc.h>
113 +#include <linux/clk.h>
114 +#include <linux/ktime.h>
115 #include <linux/mmc/host.h>
116 #include "sdhci-pltfm.h"
117 #include "sdhci-esdhc.h"
118 @@ -28,8 +32,12 @@
119 struct sdhci_esdhc {
120 u8 vendor_ver;
121 u8 spec_ver;
122 + bool quirk_incorrect_hostver;
123 + unsigned int peripheral_clock;
124 };
125
126 +static void esdhc_clock_enable(struct sdhci_host *host, bool enable);
127 +
128 /**
129 * esdhc_read*_fixup - Fixup the value read from incompatible eSDHC register
130 * to make it compatible with SD spec.
131 @@ -80,6 +88,17 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host,
132 return ret;
133 }
134
135 + /*
136 + * DTS properties of mmc host are used to enable each speed mode
137 + * according to soc and board capability. So clean up
138 + * SDR50/SDR104/DDR50 support bits here.
139 + */
140 + if (spec_reg == SDHCI_CAPABILITIES_1) {
141 + ret = value & (~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 |
142 + SDHCI_SUPPORT_DDR50));
143 + return ret;
144 + }
145 +
146 ret = value;
147 return ret;
148 }
149 @@ -87,6 +106,8 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host,
150 static u16 esdhc_readw_fixup(struct sdhci_host *host,
151 int spec_reg, u32 value)
152 {
153 + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
154 + struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
155 u16 ret;
156 int shift = (spec_reg & 0x2) * 8;
157
158 @@ -94,6 +115,12 @@ static u16 esdhc_readw_fixup(struct sdhci_host *host,
159 ret = value & 0xffff;
160 else
161 ret = (value >> shift) & 0xffff;
162 + /* Workaround for T4240-R1.0-R2.0 eSDHC which has incorrect
163 + * vendor version and spec version information.
164 + */
165 + if ((spec_reg == SDHCI_HOST_VERSION) &&
166 + (esdhc->quirk_incorrect_hostver))
167 + ret = (VENDOR_V_23 << SDHCI_VENDOR_VER_SHIFT) | SDHCI_SPEC_200;
168 return ret;
169 }
170
171 @@ -235,7 +262,11 @@ static u32 esdhc_be_readl(struct sdhci_host *host, int reg)
172 u32 ret;
173 u32 value;
174
175 - value = ioread32be(host->ioaddr + reg);
176 + if (reg == SDHCI_CAPABILITIES_1)
177 + value = ioread32be(host->ioaddr + ESDHC_CAPABILITIES_1);
178 + else
179 + value = ioread32be(host->ioaddr + reg);
180 +
181 ret = esdhc_readl_fixup(host, reg, value);
182
183 return ret;
184 @@ -246,7 +277,11 @@ static u32 esdhc_le_readl(struct sdhci_host *host, int reg)
185 u32 ret;
186 u32 value;
187
188 - value = ioread32(host->ioaddr + reg);
189 + if (reg == SDHCI_CAPABILITIES_1)
190 + value = ioread32(host->ioaddr + ESDHC_CAPABILITIES_1);
191 + else
192 + value = ioread32(host->ioaddr + reg);
193 +
194 ret = esdhc_readl_fixup(host, reg, value);
195
196 return ret;
197 @@ -404,15 +439,25 @@ static int esdhc_of_enable_dma(struct sdhci_host *host)
198 static unsigned int esdhc_of_get_max_clock(struct sdhci_host *host)
199 {
200 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
201 + struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
202
203 - return pltfm_host->clock;
204 + if (esdhc->peripheral_clock)
205 + return esdhc->peripheral_clock;
206 + else
207 + return pltfm_host->clock;
208 }
209
210 static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
211 {
212 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
213 + struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
214 + unsigned int clock;
215
216 - return pltfm_host->clock / 256 / 16;
217 + if (esdhc->peripheral_clock)
218 + clock = esdhc->peripheral_clock;
219 + else
220 + clock = pltfm_host->clock;
221 + return clock / 256 / 16;
222 }
223
224 static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
225 @@ -421,17 +466,34 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
226 struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
227 int pre_div = 1;
228 int div = 1;
229 + ktime_t timeout;
230 u32 temp;
231
232 host->mmc->actual_clock = 0;
233
234 - if (clock == 0)
235 + if (clock == 0) {
236 + esdhc_clock_enable(host, false);
237 return;
238 + }
239
240 /* Workaround to start pre_div at 2 for VNN < VENDOR_V_23 */
241 if (esdhc->vendor_ver < VENDOR_V_23)
242 pre_div = 2;
243
244 + /*
245 + * Limit SD clock to 167MHz for ls1046a according to its datasheet
246 + */
247 + if (clock > 167000000 &&
248 + of_find_compatible_node(NULL, NULL, "fsl,ls1046a-esdhc"))
249 + clock = 167000000;
250 +
251 + /*
252 + * Limit SD clock to 125MHz for ls1012a according to its datasheet
253 + */
254 + if (clock > 125000000 &&
255 + of_find_compatible_node(NULL, NULL, "fsl,ls1012a-esdhc"))
256 + clock = 125000000;
257 +
258 /* Workaround to reduce the clock frequency for p1010 esdhc */
259 if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) {
260 if (clock > 20000000)
261 @@ -441,8 +503,8 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
262 }
263
264 temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
265 - temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
266 - | ESDHC_CLOCK_MASK);
267 + temp &= ~(ESDHC_CLOCK_SDCLKEN | ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN |
268 + ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
269 sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
270
271 while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
272 @@ -462,7 +524,20 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
273 | (div << ESDHC_DIVIDER_SHIFT)
274 | (pre_div << ESDHC_PREDIV_SHIFT));
275 sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
276 - mdelay(1);
277 +
278 + /* Wait max 20 ms */
279 + timeout = ktime_add_ms(ktime_get(), 20);
280 + while (!(sdhci_readl(host, ESDHC_PRSSTAT) & ESDHC_CLOCK_STABLE)) {
281 + if (ktime_after(ktime_get(), timeout)) {
282 + pr_err("%s: Internal clock never stabilised.\n",
283 + mmc_hostname(host->mmc));
284 + return;
285 + }
286 + udelay(10);
287 + }
288 +
289 + temp |= ESDHC_CLOCK_SDCLKEN;
290 + sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
291 }
292
293 static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
294 @@ -487,6 +562,33 @@ static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
295 sdhci_writel(host, ctrl, ESDHC_PROCTL);
296 }
297
298 +static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
299 +{
300 + u32 val;
301 + ktime_t timeout;
302 +
303 + val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
304 +
305 + if (enable)
306 + val |= ESDHC_CLOCK_SDCLKEN;
307 + else
308 + val &= ~ESDHC_CLOCK_SDCLKEN;
309 +
310 + sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL);
311 +
312 + /* Wait max 20 ms */
313 + timeout = ktime_add_ms(ktime_get(), 20);
314 + val = ESDHC_CLOCK_STABLE;
315 + while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) {
316 + if (ktime_after(ktime_get(), timeout)) {
317 + pr_err("%s: Internal clock never stabilised.\n",
318 + mmc_hostname(host->mmc));
319 + break;
320 + }
321 + udelay(10);
322 + }
323 +}
324 +
325 static void esdhc_reset(struct sdhci_host *host, u8 mask)
326 {
327 sdhci_reset(host, mask);
328 @@ -495,6 +597,95 @@ static void esdhc_reset(struct sdhci_host *host, u8 mask)
329 sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
330 }
331
332 +/* The SCFG, Supplemental Configuration Unit, provides SoC specific
333 + * configuration and status registers for the device. There is a
334 + * SDHC IO VSEL control register on SCFG for some platforms. It's
335 + * used to support SDHC IO voltage switching.
336 + */
337 +static const struct of_device_id scfg_device_ids[] = {
338 + { .compatible = "fsl,t1040-scfg", },
339 + { .compatible = "fsl,ls1012a-scfg", },
340 + { .compatible = "fsl,ls1046a-scfg", },
341 + {}
342 +};
343 +
344 +/* SDHC IO VSEL control register definition */
345 +#define SCFG_SDHCIOVSELCR 0x408
346 +#define SDHCIOVSELCR_TGLEN 0x80000000
347 +#define SDHCIOVSELCR_VSELVAL 0x60000000
348 +#define SDHCIOVSELCR_SDHC_VS 0x00000001
349 +
350 +static int esdhc_signal_voltage_switch(struct mmc_host *mmc,
351 + struct mmc_ios *ios)
352 +{
353 + struct sdhci_host *host = mmc_priv(mmc);
354 + struct device_node *scfg_node;
355 + void __iomem *scfg_base = NULL;
356 + u32 sdhciovselcr;
357 + u32 val;
358 +
359 + /*
360 + * Signal Voltage Switching is only applicable for Host Controllers
361 + * v3.00 and above.
362 + */
363 + if (host->version < SDHCI_SPEC_300)
364 + return 0;
365 +
366 + val = sdhci_readl(host, ESDHC_PROCTL);
367 +
368 + switch (ios->signal_voltage) {
369 + case MMC_SIGNAL_VOLTAGE_330:
370 + val &= ~ESDHC_VOLT_SEL;
371 + sdhci_writel(host, val, ESDHC_PROCTL);
372 + return 0;
373 + case MMC_SIGNAL_VOLTAGE_180:
374 + scfg_node = of_find_matching_node(NULL, scfg_device_ids);
375 + if (scfg_node)
376 + scfg_base = of_iomap(scfg_node, 0);
377 + if (scfg_base) {
378 + sdhciovselcr = SDHCIOVSELCR_TGLEN |
379 + SDHCIOVSELCR_VSELVAL;
380 + iowrite32be(sdhciovselcr,
381 + scfg_base + SCFG_SDHCIOVSELCR);
382 +
383 + val |= ESDHC_VOLT_SEL;
384 + sdhci_writel(host, val, ESDHC_PROCTL);
385 + mdelay(5);
386 +
387 + sdhciovselcr = SDHCIOVSELCR_TGLEN |
388 + SDHCIOVSELCR_SDHC_VS;
389 + iowrite32be(sdhciovselcr,
390 + scfg_base + SCFG_SDHCIOVSELCR);
391 + iounmap(scfg_base);
392 + } else {
393 + val |= ESDHC_VOLT_SEL;
394 + sdhci_writel(host, val, ESDHC_PROCTL);
395 + }
396 + return 0;
397 + default:
398 + return 0;
399 + }
400 +}
401 +
402 +static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
403 +{
404 + struct sdhci_host *host = mmc_priv(mmc);
405 + u32 val;
406 +
407 + /* Use tuning block for tuning procedure */
408 + esdhc_clock_enable(host, false);
409 + val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
410 + val |= ESDHC_FLUSH_ASYNC_FIFO;
411 + sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
412 +
413 + val = sdhci_readl(host, ESDHC_TBCTL);
414 + val |= ESDHC_TB_EN;
415 + sdhci_writel(host, val, ESDHC_TBCTL);
416 + esdhc_clock_enable(host, true);
417 +
418 + return sdhci_execute_tuning(mmc, opcode);
419 +}
420 +
421 #ifdef CONFIG_PM_SLEEP
422 static u32 esdhc_proctl;
423 static int esdhc_of_suspend(struct device *dev)
424 @@ -575,10 +766,19 @@ static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = {
425 .ops = &sdhci_esdhc_le_ops,
426 };
427
428 +static struct soc_device_attribute soc_incorrect_hostver[] = {
429 + { .family = "QorIQ T4240", .revision = "1.0", },
430 + { .family = "QorIQ T4240", .revision = "2.0", },
431 + { },
432 +};
433 +
434 static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
435 {
436 struct sdhci_pltfm_host *pltfm_host;
437 struct sdhci_esdhc *esdhc;
438 + struct device_node *np;
439 + struct clk *clk;
440 + u32 val;
441 u16 host_ver;
442
443 pltfm_host = sdhci_priv(host);
444 @@ -588,6 +788,36 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
445 esdhc->vendor_ver = (host_ver & SDHCI_VENDOR_VER_MASK) >>
446 SDHCI_VENDOR_VER_SHIFT;
447 esdhc->spec_ver = host_ver & SDHCI_SPEC_VER_MASK;
448 + if (soc_device_match(soc_incorrect_hostver))
449 + esdhc->quirk_incorrect_hostver = true;
450 + else
451 + esdhc->quirk_incorrect_hostver = false;
452 +
453 + np = pdev->dev.of_node;
454 + clk = of_clk_get(np, 0);
455 + if (!IS_ERR(clk)) {
456 + /*
457 + * esdhc->peripheral_clock would be assigned with a value
458 + * which is eSDHC base clock when use periperal clock.
459 + * For ls1046a, the clock value got by common clk API is
460 + * peripheral clock while the eSDHC base clock is 1/2
461 + * peripheral clock.
462 + */
463 + if (of_device_is_compatible(np, "fsl,ls1046a-esdhc"))
464 + esdhc->peripheral_clock = clk_get_rate(clk) / 2;
465 + else
466 + esdhc->peripheral_clock = clk_get_rate(clk);
467 +
468 + clk_put(clk);
469 + }
470 +
471 + if (esdhc->peripheral_clock) {
472 + esdhc_clock_enable(host, false);
473 + val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
474 + val |= ESDHC_PERIPHERAL_CLK_SEL;
475 + sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
476 + esdhc_clock_enable(host, true);
477 + }
478 }
479
480 static int sdhci_esdhc_probe(struct platform_device *pdev)
481 @@ -610,6 +840,11 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
482 if (IS_ERR(host))
483 return PTR_ERR(host);
484
485 + host->mmc_host_ops.start_signal_voltage_switch =
486 + esdhc_signal_voltage_switch;
487 + host->mmc_host_ops.execute_tuning = esdhc_execute_tuning;
488 + host->tuning_delay = 1;
489 +
490 esdhc_init(pdev, host);
491
492 sdhci_get_of_property(pdev);
493 diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
494 index 7d275e72..099c3bf5 100644
495 --- a/drivers/mmc/host/sdhci.c
496 +++ b/drivers/mmc/host/sdhci.c
497 @@ -1624,26 +1624,24 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
498
499 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
500
501 - if ((ios->timing == MMC_TIMING_SD_HS ||
502 - ios->timing == MMC_TIMING_MMC_HS)
503 - && !(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT))
504 - ctrl |= SDHCI_CTRL_HISPD;
505 - else
506 - ctrl &= ~SDHCI_CTRL_HISPD;
507 + if (!(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)) {
508 + if ((ios->timing == MMC_TIMING_SD_HS ||
509 + ios->timing == MMC_TIMING_MMC_HS ||
510 + ios->timing == MMC_TIMING_MMC_HS400 ||
511 + ios->timing == MMC_TIMING_MMC_HS200 ||
512 + ios->timing == MMC_TIMING_MMC_DDR52 ||
513 + ios->timing == MMC_TIMING_UHS_SDR50 ||
514 + ios->timing == MMC_TIMING_UHS_SDR104 ||
515 + ios->timing == MMC_TIMING_UHS_DDR50 ||
516 + ios->timing == MMC_TIMING_UHS_SDR25))
517 + ctrl |= SDHCI_CTRL_HISPD;
518 + else
519 + ctrl &= ~SDHCI_CTRL_HISPD;
520 + }
521
522 if (host->version >= SDHCI_SPEC_300) {
523 u16 clk, ctrl_2;
524
525 - /* In case of UHS-I modes, set High Speed Enable */
526 - if ((ios->timing == MMC_TIMING_MMC_HS400) ||
527 - (ios->timing == MMC_TIMING_MMC_HS200) ||
528 - (ios->timing == MMC_TIMING_MMC_DDR52) ||
529 - (ios->timing == MMC_TIMING_UHS_SDR50) ||
530 - (ios->timing == MMC_TIMING_UHS_SDR104) ||
531 - (ios->timing == MMC_TIMING_UHS_DDR50) ||
532 - (ios->timing == MMC_TIMING_UHS_SDR25))
533 - ctrl |= SDHCI_CTRL_HISPD;
534 -
535 if (!host->preset_enabled) {
536 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
537 /*
538 @@ -1956,7 +1954,7 @@ static int sdhci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
539 return 0;
540 }
541
542 -static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
543 +int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
544 {
545 struct sdhci_host *host = mmc_priv(mmc);
546 u16 ctrl;
547 @@ -2015,6 +2013,9 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
548 return err;
549 }
550
551 + if (host->tuning_delay < 0)
552 + host->tuning_delay = opcode == MMC_SEND_TUNING_BLOCK;
553 +
554 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
555 ctrl |= SDHCI_CTRL_EXEC_TUNING;
556 if (host->quirks2 & SDHCI_QUIRK2_TUNING_WORK_AROUND)
557 @@ -2127,9 +2128,10 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
558
559 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
560
561 - /* eMMC spec does not require a delay between tuning cycles */
562 - if (opcode == MMC_SEND_TUNING_BLOCK)
563 - mdelay(1);
564 + /* Spec does not require a delay between tuning cycles */
565 + if (host->tuning_delay > 0)
566 + mdelay(host->tuning_delay);
567 +
568 } while (ctrl & SDHCI_CTRL_EXEC_TUNING);
569
570 /*
571 @@ -2165,6 +2167,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
572 spin_unlock_irqrestore(&host->lock, flags);
573 return err;
574 }
575 +EXPORT_SYMBOL_GPL(sdhci_execute_tuning);
576
577 static int sdhci_select_drive_strength(struct mmc_card *card,
578 unsigned int max_dtr, int host_drv,
579 @@ -2997,6 +3000,8 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev,
580
581 host->flags = SDHCI_SIGNALING_330;
582
583 + host->tuning_delay = -1;
584 +
585 return host;
586 }
587
588 diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
589 index 2570455b..088bed43 100644
590 --- a/drivers/mmc/host/sdhci.h
591 +++ b/drivers/mmc/host/sdhci.h
592 @@ -524,6 +524,8 @@ struct sdhci_host {
593 #define SDHCI_TUNING_MODE_1 0
594 #define SDHCI_TUNING_MODE_2 1
595 #define SDHCI_TUNING_MODE_3 2
596 + /* Delay (ms) between tuning commands */
597 + int tuning_delay;
598
599 unsigned long private[0] ____cacheline_aligned;
600 };
601 @@ -689,6 +691,7 @@ void sdhci_set_power_noreg(struct sdhci_host *host, unsigned char mode,
602 void sdhci_set_bus_width(struct sdhci_host *host, int width);
603 void sdhci_reset(struct sdhci_host *host, u8 mask);
604 void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
605 +int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);
606
607 #ifdef CONFIG_PM
608 extern int sdhci_suspend_host(struct sdhci_host *host);
609 --
610 2.14.1
611