2
0

819-sdhc-support-layerscape.patch 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. From 6ca94d2e7dc72b21703e6d9be4e8ec3ad4a26f41 Mon Sep 17 00:00:00 2001
  2. From: Biwen Li <[email protected]>
  3. Date: Wed, 17 Apr 2019 18:59:02 +0800
  4. Subject: [PATCH] sdhc: support layerscape
  5. This is an integrated patch of sdhc for layerscape
  6. Signed-off-by: Biwen Li <[email protected]>
  7. Signed-off-by: Mathew McBride <[email protected]>
  8. Signed-off-by: Ulf Hansson <[email protected]>
  9. Signed-off-by: Yangbo Lu <[email protected]>
  10. Signed-off-by: Yinbo Zhu <[email protected]>
  11. ---
  12. drivers/mmc/core/mmc.c | 3 +
  13. drivers/mmc/host/sdhci-esdhc.h | 25 +++
  14. drivers/mmc/host/sdhci-of-esdhc.c | 270 ++++++++++++++++++++++++++----
  15. drivers/mmc/host/sdhci.c | 9 +-
  16. drivers/mmc/host/sdhci.h | 1 +
  17. include/linux/mmc/card.h | 1 +
  18. include/linux/mmc/host.h | 2 +
  19. 7 files changed, 272 insertions(+), 39 deletions(-)
  20. --- a/drivers/mmc/core/mmc.c
  21. +++ b/drivers/mmc/core/mmc.c
  22. @@ -1174,6 +1174,9 @@ static int mmc_select_hs400(struct mmc_c
  23. goto out_err;
  24. /* Switch card to DDR */
  25. + if (host->ops->prepare_ddr_to_hs400)
  26. + host->ops->prepare_ddr_to_hs400(host);
  27. +
  28. err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
  29. EXT_CSD_BUS_WIDTH,
  30. EXT_CSD_DDR_BUS_WIDTH_8,
  31. --- a/drivers/mmc/host/sdhci-esdhc.h
  32. +++ b/drivers/mmc/host/sdhci-esdhc.h
  33. @@ -59,7 +59,32 @@
  34. /* Tuning Block Control Register */
  35. #define ESDHC_TBCTL 0x120
  36. +#define ESDHC_HS400_WNDW_ADJUST 0x00000040
  37. +#define ESDHC_HS400_MODE 0x00000010
  38. #define ESDHC_TB_EN 0x00000004
  39. +#define ESDHC_TBPTR 0x128
  40. +
  41. +/* SD Clock Control Register */
  42. +#define ESDHC_SDCLKCTL 0x144
  43. +#define ESDHC_LPBK_CLK_SEL 0x80000000
  44. +#define ESDHC_CMD_CLK_CTL 0x00008000
  45. +
  46. +/* SD Timing Control Register */
  47. +#define ESDHC_SDTIMNGCTL 0x148
  48. +#define ESDHC_FLW_CTL_BG 0x00008000
  49. +
  50. +/* DLL Config 0 Register */
  51. +#define ESDHC_DLLCFG0 0x160
  52. +#define ESDHC_DLL_ENABLE 0x80000000
  53. +#define ESDHC_DLL_FREQ_SEL 0x08000000
  54. +
  55. +/* DLL Config 1 Register */
  56. +#define ESDHC_DLLCFG1 0x164
  57. +#define ESDHC_DLL_PD_PULSE_STRETCH_SEL 0x80000000
  58. +
  59. +/* DLL Status 0 Register */
  60. +#define ESDHC_DLLSTAT0 0x170
  61. +#define ESDHC_DLL_STS_SLV_LOCK 0x08000000
  62. /* Control Register for DMA transfer */
  63. #define ESDHC_DMA_SYSCTL 0x40c
  64. --- a/drivers/mmc/host/sdhci-of-esdhc.c
  65. +++ b/drivers/mmc/host/sdhci-of-esdhc.c
  66. @@ -30,11 +30,61 @@
  67. #define VENDOR_V_22 0x12
  68. #define VENDOR_V_23 0x13
  69. +#define MMC_TIMING_NUM (MMC_TIMING_MMC_HS400 + 1)
  70. +
  71. +struct esdhc_clk_fixup {
  72. + const unsigned int sd_dflt_max_clk;
  73. + const unsigned int max_clk[MMC_TIMING_NUM];
  74. +};
  75. +
  76. +static const struct esdhc_clk_fixup ls1021a_esdhc_clk = {
  77. + .sd_dflt_max_clk = 25000000,
  78. + .max_clk[MMC_TIMING_MMC_HS] = 46500000,
  79. + .max_clk[MMC_TIMING_SD_HS] = 46500000,
  80. +};
  81. +
  82. +static const struct esdhc_clk_fixup ls1046a_esdhc_clk = {
  83. + .sd_dflt_max_clk = 25000000,
  84. + .max_clk[MMC_TIMING_UHS_SDR104] = 167000000,
  85. + .max_clk[MMC_TIMING_MMC_HS200] = 167000000,
  86. +};
  87. +
  88. +static const struct esdhc_clk_fixup ls1012a_esdhc_clk = {
  89. + .sd_dflt_max_clk = 25000000,
  90. + .max_clk[MMC_TIMING_UHS_SDR104] = 125000000,
  91. + .max_clk[MMC_TIMING_MMC_HS200] = 125000000,
  92. +};
  93. +
  94. +static const struct esdhc_clk_fixup p1010_esdhc_clk = {
  95. + .sd_dflt_max_clk = 20000000,
  96. + .max_clk[MMC_TIMING_LEGACY] = 20000000,
  97. + .max_clk[MMC_TIMING_MMC_HS] = 42000000,
  98. + .max_clk[MMC_TIMING_SD_HS] = 40000000,
  99. +};
  100. +
  101. +static const struct of_device_id sdhci_esdhc_of_match[] = {
  102. + { .compatible = "fsl,ls1021a-esdhc", .data = &ls1021a_esdhc_clk},
  103. + { .compatible = "fsl,ls1046a-esdhc", .data = &ls1046a_esdhc_clk},
  104. + { .compatible = "fsl,ls1012a-esdhc", .data = &ls1012a_esdhc_clk},
  105. + { .compatible = "fsl,p1010-esdhc", .data = &p1010_esdhc_clk},
  106. + { .compatible = "fsl,mpc8379-esdhc" },
  107. + { .compatible = "fsl,mpc8536-esdhc" },
  108. + { .compatible = "fsl,esdhc" },
  109. + { }
  110. +};
  111. +MODULE_DEVICE_TABLE(of, sdhci_esdhc_of_match);
  112. +
  113. struct sdhci_esdhc {
  114. u8 vendor_ver;
  115. u8 spec_ver;
  116. bool quirk_incorrect_hostver;
  117. + bool quirk_limited_clk_division;
  118. + bool quirk_unreliable_pulse_detection;
  119. + bool quirk_fixup_tuning;
  120. + bool quirk_incorrect_delay_chain;
  121. unsigned int peripheral_clock;
  122. + const struct esdhc_clk_fixup *clk_fixup;
  123. + u32 div_ratio;
  124. };
  125. /**
  126. @@ -495,13 +545,20 @@ static void esdhc_clock_enable(struct sd
  127. }
  128. }
  129. +static struct soc_device_attribute soc_incorrect_delay_chain[] = {
  130. + { .family = "QorIQ LX2160A", .revision = "1.0", },
  131. + { },
  132. +};
  133. +
  134. static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
  135. {
  136. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  137. struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
  138. int pre_div = 1;
  139. int div = 1;
  140. + int division;
  141. ktime_t timeout;
  142. + long fixup = 0;
  143. u32 temp;
  144. host->mmc->actual_clock = 0;
  145. @@ -515,27 +572,14 @@ static void esdhc_of_set_clock(struct sd
  146. if (esdhc->vendor_ver < VENDOR_V_23)
  147. pre_div = 2;
  148. - /*
  149. - * Limit SD clock to 167MHz for ls1046a according to its datasheet
  150. - */
  151. - if (clock > 167000000 &&
  152. - of_find_compatible_node(NULL, NULL, "fsl,ls1046a-esdhc"))
  153. - clock = 167000000;
  154. + if (host->mmc->card && mmc_card_sd(host->mmc->card) &&
  155. + esdhc->clk_fixup && host->mmc->ios.timing == MMC_TIMING_LEGACY)
  156. + fixup = esdhc->clk_fixup->sd_dflt_max_clk;
  157. + else if (esdhc->clk_fixup)
  158. + fixup = esdhc->clk_fixup->max_clk[host->mmc->ios.timing];
  159. - /*
  160. - * Limit SD clock to 125MHz for ls1012a according to its datasheet
  161. - */
  162. - if (clock > 125000000 &&
  163. - of_find_compatible_node(NULL, NULL, "fsl,ls1012a-esdhc"))
  164. - clock = 125000000;
  165. -
  166. - /* Workaround to reduce the clock frequency for p1010 esdhc */
  167. - if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) {
  168. - if (clock > 20000000)
  169. - clock -= 5000000;
  170. - if (clock > 40000000)
  171. - clock -= 5000000;
  172. - }
  173. + if (fixup && clock > fixup)
  174. + clock = fixup;
  175. temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
  176. temp &= ~(ESDHC_CLOCK_SDCLKEN | ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN |
  177. @@ -548,9 +592,30 @@ static void esdhc_of_set_clock(struct sd
  178. while (host->max_clk / pre_div / div > clock && div < 16)
  179. div++;
  180. + if (esdhc->quirk_limited_clk_division &&
  181. + clock == MMC_HS200_MAX_DTR &&
  182. + (host->mmc->ios.timing == MMC_TIMING_MMC_HS400 ||
  183. + host->flags & SDHCI_HS400_TUNING)) {
  184. + division = pre_div * div;
  185. + if (division <= 4) {
  186. + pre_div = 4;
  187. + div = 1;
  188. + } else if (division <= 8) {
  189. + pre_div = 4;
  190. + div = 2;
  191. + } else if (division <= 12) {
  192. + pre_div = 4;
  193. + div = 3;
  194. + } else {
  195. + pr_warn("%s: using upsupported clock division.\n",
  196. + mmc_hostname(host->mmc));
  197. + }
  198. + }
  199. +
  200. dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n",
  201. clock, host->max_clk / pre_div / div);
  202. host->mmc->actual_clock = host->max_clk / pre_div / div;
  203. + esdhc->div_ratio = pre_div * div;
  204. pre_div >>= 1;
  205. div--;
  206. @@ -560,6 +625,29 @@ static void esdhc_of_set_clock(struct sd
  207. | (pre_div << ESDHC_PREDIV_SHIFT));
  208. sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
  209. + if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400 &&
  210. + clock == MMC_HS200_MAX_DTR) {
  211. + temp = sdhci_readl(host, ESDHC_TBCTL);
  212. + sdhci_writel(host, temp | ESDHC_HS400_MODE, ESDHC_TBCTL);
  213. + temp = sdhci_readl(host, ESDHC_SDCLKCTL);
  214. + sdhci_writel(host, temp | ESDHC_CMD_CLK_CTL, ESDHC_SDCLKCTL);
  215. + esdhc_clock_enable(host, true);
  216. +
  217. + temp = sdhci_readl(host, ESDHC_DLLCFG0);
  218. + temp |= ESDHC_DLL_ENABLE;
  219. + if (host->mmc->actual_clock == MMC_HS200_MAX_DTR ||
  220. + esdhc->quirk_incorrect_delay_chain == false)
  221. + temp |= ESDHC_DLL_FREQ_SEL;
  222. + sdhci_writel(host, temp, ESDHC_DLLCFG0);
  223. + temp = sdhci_readl(host, ESDHC_TBCTL);
  224. + sdhci_writel(host, temp | ESDHC_HS400_WNDW_ADJUST, ESDHC_TBCTL);
  225. +
  226. + esdhc_clock_enable(host, false);
  227. + temp = sdhci_readl(host, ESDHC_DMA_SYSCTL);
  228. + temp |= ESDHC_FLUSH_ASYNC_FIFO;
  229. + sdhci_writel(host, temp, ESDHC_DMA_SYSCTL);
  230. + }
  231. +
  232. /* Wait max 20 ms */
  233. timeout = ktime_add_ms(ktime_get(), 20);
  234. while (1) {
  235. @@ -575,6 +663,7 @@ static void esdhc_of_set_clock(struct sd
  236. udelay(10);
  237. }
  238. + temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
  239. temp |= ESDHC_CLOCK_SDCLKEN;
  240. sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
  241. }
  242. @@ -603,6 +692,8 @@ static void esdhc_pltfm_set_bus_width(st
  243. static void esdhc_reset(struct sdhci_host *host, u8 mask)
  244. {
  245. + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  246. + struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
  247. u32 val;
  248. sdhci_reset(host, mask);
  249. @@ -617,6 +708,12 @@ static void esdhc_reset(struct sdhci_hos
  250. val = sdhci_readl(host, ESDHC_TBCTL);
  251. val &= ~ESDHC_TB_EN;
  252. sdhci_writel(host, val, ESDHC_TBCTL);
  253. +
  254. + if (esdhc->quirk_unreliable_pulse_detection) {
  255. + val = sdhci_readl(host, ESDHC_DLLCFG1);
  256. + val &= ~ESDHC_DLL_PD_PULSE_STRETCH_SEL;
  257. + sdhci_writel(host, val, ESDHC_DLLCFG1);
  258. + }
  259. }
  260. }
  261. @@ -628,6 +725,7 @@ static void esdhc_reset(struct sdhci_hos
  262. static const struct of_device_id scfg_device_ids[] = {
  263. { .compatible = "fsl,t1040-scfg", },
  264. { .compatible = "fsl,ls1012a-scfg", },
  265. + { .compatible = "fsl,ls1043a-scfg", },
  266. { .compatible = "fsl,ls1046a-scfg", },
  267. {}
  268. };
  269. @@ -690,23 +788,91 @@ static int esdhc_signal_voltage_switch(s
  270. }
  271. }
  272. -static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
  273. +static struct soc_device_attribute soc_fixup_tuning[] = {
  274. + { .family = "QorIQ T1040", .revision = "1.0", },
  275. + { .family = "QorIQ T2080", .revision = "1.0", },
  276. + { .family = "QorIQ T1023", .revision = "1.0", },
  277. + { .family = "QorIQ LS1021A", .revision = "1.0", },
  278. + { .family = "QorIQ LS1080A", .revision = "1.0", },
  279. + { .family = "QorIQ LS2080A", .revision = "1.0", },
  280. + { .family = "QorIQ LS1012A", .revision = "1.0", },
  281. + { .family = "QorIQ LS1043A", .revision = "1.*", },
  282. + { .family = "QorIQ LS1046A", .revision = "1.0", },
  283. + { },
  284. +};
  285. +
  286. +static void esdhc_tuning_block_enable(struct sdhci_host *host, bool enable)
  287. {
  288. - struct sdhci_host *host = mmc_priv(mmc);
  289. u32 val;
  290. - /* Use tuning block for tuning procedure */
  291. esdhc_clock_enable(host, false);
  292. +
  293. val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
  294. val |= ESDHC_FLUSH_ASYNC_FIFO;
  295. sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
  296. val = sdhci_readl(host, ESDHC_TBCTL);
  297. - val |= ESDHC_TB_EN;
  298. + if (enable)
  299. + val |= ESDHC_TB_EN;
  300. + else
  301. + val &= ~ESDHC_TB_EN;
  302. sdhci_writel(host, val, ESDHC_TBCTL);
  303. +
  304. esdhc_clock_enable(host, true);
  305. +}
  306. +
  307. +static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
  308. +{
  309. + struct sdhci_host *host = mmc_priv(mmc);
  310. + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  311. + struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
  312. + bool hs400_tuning;
  313. + u32 val;
  314. + int ret;
  315. +
  316. + if (esdhc->quirk_limited_clk_division &&
  317. + host->flags & SDHCI_HS400_TUNING)
  318. + esdhc_of_set_clock(host, host->clock);
  319. +
  320. + esdhc_tuning_block_enable(host, true);
  321. +
  322. + hs400_tuning = host->flags & SDHCI_HS400_TUNING;
  323. + ret = sdhci_execute_tuning(mmc, opcode);
  324. +
  325. + if (hs400_tuning) {
  326. + val = sdhci_readl(host, ESDHC_SDTIMNGCTL);
  327. + val |= ESDHC_FLW_CTL_BG;
  328. + sdhci_writel(host, val, ESDHC_SDTIMNGCTL);
  329. + }
  330. - return sdhci_execute_tuning(mmc, opcode);
  331. + if (host->tuning_err == -EAGAIN && esdhc->quirk_fixup_tuning) {
  332. +
  333. + /* program TBPTR[TB_WNDW_END_PTR] = 3*DIV_RATIO and
  334. + * program TBPTR[TB_WNDW_START_PTR] = 5*DIV_RATIO
  335. + */
  336. + val = sdhci_readl(host, ESDHC_TBPTR);
  337. + val = (val & ~((0x7f << 8) | 0x7f)) |
  338. + (3 * esdhc->div_ratio) | ((5 * esdhc->div_ratio) << 8);
  339. + sdhci_writel(host, val, ESDHC_TBPTR);
  340. +
  341. + /* program the software tuning mode by setting
  342. + * TBCTL[TB_MODE]=2'h3
  343. + */
  344. + val = sdhci_readl(host, ESDHC_TBCTL);
  345. + val |= 0x3;
  346. + sdhci_writel(host, val, ESDHC_TBCTL);
  347. + sdhci_execute_tuning(mmc, opcode);
  348. + }
  349. + return ret;
  350. +}
  351. +
  352. +static void esdhc_set_uhs_signaling(struct sdhci_host *host,
  353. + unsigned int timing)
  354. +{
  355. + if (timing == MMC_TIMING_MMC_HS400)
  356. + esdhc_tuning_block_enable(host, true);
  357. + else
  358. + sdhci_set_uhs_signaling(host, timing);
  359. }
  360. #ifdef CONFIG_PM_SLEEP
  361. @@ -755,7 +921,7 @@ static const struct sdhci_ops sdhci_esdh
  362. .adma_workaround = esdhc_of_adma_workaround,
  363. .set_bus_width = esdhc_pltfm_set_bus_width,
  364. .reset = esdhc_reset,
  365. - .set_uhs_signaling = sdhci_set_uhs_signaling,
  366. + .set_uhs_signaling = esdhc_set_uhs_signaling,
  367. };
  368. static const struct sdhci_ops sdhci_esdhc_le_ops = {
  369. @@ -772,7 +938,7 @@ static const struct sdhci_ops sdhci_esdh
  370. .adma_workaround = esdhc_of_adma_workaround,
  371. .set_bus_width = esdhc_pltfm_set_bus_width,
  372. .reset = esdhc_reset,
  373. - .set_uhs_signaling = sdhci_set_uhs_signaling,
  374. + .set_uhs_signaling = esdhc_set_uhs_signaling,
  375. };
  376. static const struct sdhci_pltfm_data sdhci_esdhc_be_pdata = {
  377. @@ -798,8 +964,20 @@ static struct soc_device_attribute soc_i
  378. { },
  379. };
  380. +static struct soc_device_attribute soc_fixup_sdhc_clkdivs[] = {
  381. + { .family = "QorIQ LX2160A", .revision = "1.0", },
  382. + { .family = "QorIQ LX2160A", .revision = "2.0", },
  383. + { },
  384. +};
  385. +
  386. +static struct soc_device_attribute soc_unreliable_pulse_detection[] = {
  387. + { .family = "QorIQ LX2160A", .revision = "1.0", },
  388. + { },
  389. +};
  390. +
  391. static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
  392. {
  393. + const struct of_device_id *match;
  394. struct sdhci_pltfm_host *pltfm_host;
  395. struct sdhci_esdhc *esdhc;
  396. struct device_node *np;
  397. @@ -819,6 +997,24 @@ static void esdhc_init(struct platform_d
  398. else
  399. esdhc->quirk_incorrect_hostver = false;
  400. + if (soc_device_match(soc_fixup_sdhc_clkdivs))
  401. + esdhc->quirk_limited_clk_division = true;
  402. + else
  403. + esdhc->quirk_limited_clk_division = false;
  404. +
  405. + if (soc_device_match(soc_unreliable_pulse_detection))
  406. + esdhc->quirk_unreliable_pulse_detection = true;
  407. + else
  408. + esdhc->quirk_unreliable_pulse_detection = false;
  409. +
  410. + if (soc_device_match(soc_incorrect_delay_chain))
  411. + esdhc->quirk_incorrect_delay_chain = true;
  412. + else
  413. + esdhc->quirk_incorrect_delay_chain = false;
  414. +
  415. + match = of_match_node(sdhci_esdhc_of_match, pdev->dev.of_node);
  416. + if (match)
  417. + esdhc->clk_fixup = match->data;
  418. np = pdev->dev.of_node;
  419. clk = of_clk_get(np, 0);
  420. if (!IS_ERR(clk)) {
  421. @@ -846,6 +1042,12 @@ static void esdhc_init(struct platform_d
  422. }
  423. }
  424. +static int esdhc_prepare_ddr_to_hs400(struct mmc_host *mmc)
  425. +{
  426. + esdhc_tuning_block_enable(mmc_priv(mmc), false);
  427. + return 0;
  428. +}
  429. +
  430. static int sdhci_esdhc_probe(struct platform_device *pdev)
  431. {
  432. struct sdhci_host *host;
  433. @@ -869,6 +1071,7 @@ static int sdhci_esdhc_probe(struct plat
  434. host->mmc_host_ops.start_signal_voltage_switch =
  435. esdhc_signal_voltage_switch;
  436. host->mmc_host_ops.execute_tuning = esdhc_execute_tuning;
  437. + host->mmc_host_ops.prepare_ddr_to_hs400 = esdhc_prepare_ddr_to_hs400;
  438. host->tuning_delay = 1;
  439. esdhc_init(pdev, host);
  440. @@ -877,6 +1080,11 @@ static int sdhci_esdhc_probe(struct plat
  441. pltfm_host = sdhci_priv(host);
  442. esdhc = sdhci_pltfm_priv(pltfm_host);
  443. + if (soc_device_match(soc_fixup_tuning))
  444. + esdhc->quirk_fixup_tuning = true;
  445. + else
  446. + esdhc->quirk_fixup_tuning = false;
  447. +
  448. if (esdhc->vendor_ver == VENDOR_V_22)
  449. host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23;
  450. @@ -923,14 +1131,6 @@ static int sdhci_esdhc_probe(struct plat
  451. return ret;
  452. }
  453. -static const struct of_device_id sdhci_esdhc_of_match[] = {
  454. - { .compatible = "fsl,mpc8379-esdhc" },
  455. - { .compatible = "fsl,mpc8536-esdhc" },
  456. - { .compatible = "fsl,esdhc" },
  457. - { }
  458. -};
  459. -MODULE_DEVICE_TABLE(of, sdhci_esdhc_of_match);
  460. -
  461. static struct platform_driver sdhci_esdhc_driver = {
  462. .driver = {
  463. .name = "sdhci-esdhc",
  464. --- a/drivers/mmc/host/sdhci.c
  465. +++ b/drivers/mmc/host/sdhci.c
  466. @@ -2148,7 +2148,7 @@ static void sdhci_send_tuning(struct sdh
  467. }
  468. -static void __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
  469. +static int __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
  470. {
  471. int i;
  472. @@ -2165,13 +2165,13 @@ static void __sdhci_execute_tuning(struc
  473. pr_info("%s: Tuning timeout, falling back to fixed sampling clock\n",
  474. mmc_hostname(host->mmc));
  475. sdhci_abort_tuning(host, opcode);
  476. - return;
  477. + return -ETIMEDOUT;
  478. }
  479. ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  480. if (!(ctrl & SDHCI_CTRL_EXEC_TUNING)) {
  481. if (ctrl & SDHCI_CTRL_TUNED_CLK)
  482. - return; /* Success! */
  483. + return 0; /* Success! */
  484. break;
  485. }
  486. @@ -2183,6 +2183,7 @@ static void __sdhci_execute_tuning(struc
  487. pr_info("%s: Tuning failed, falling back to fixed sampling clock\n",
  488. mmc_hostname(host->mmc));
  489. sdhci_reset_tuning(host);
  490. + return -EAGAIN;
  491. }
  492. int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
  493. @@ -2244,7 +2245,7 @@ int sdhci_execute_tuning(struct mmc_host
  494. sdhci_start_tuning(host);
  495. - __sdhci_execute_tuning(host, opcode);
  496. + host->tuning_err = __sdhci_execute_tuning(host, opcode);
  497. sdhci_end_tuning(host);
  498. out:
  499. --- a/drivers/mmc/host/sdhci.h
  500. +++ b/drivers/mmc/host/sdhci.h
  501. @@ -545,6 +545,7 @@ struct sdhci_host {
  502. unsigned int tuning_count; /* Timer count for re-tuning */
  503. unsigned int tuning_mode; /* Re-tuning mode supported by host */
  504. + unsigned int tuning_err; /* Error code for re-tuning */
  505. #define SDHCI_TUNING_MODE_1 0
  506. #define SDHCI_TUNING_MODE_2 1
  507. #define SDHCI_TUNING_MODE_3 2
  508. --- a/include/linux/mmc/card.h
  509. +++ b/include/linux/mmc/card.h
  510. @@ -156,6 +156,7 @@ struct sd_switch_caps {
  511. #define UHS_DDR50_MAX_DTR 50000000
  512. #define UHS_SDR25_MAX_DTR UHS_DDR50_MAX_DTR
  513. #define UHS_SDR12_MAX_DTR 25000000
  514. +#define DEFAULT_SPEED_MAX_DTR UHS_SDR12_MAX_DTR
  515. unsigned int sd3_bus_mode;
  516. #define UHS_SDR12_BUS_SPEED 0
  517. #define HIGH_SPEED_BUS_SPEED 1
  518. --- a/include/linux/mmc/host.h
  519. +++ b/include/linux/mmc/host.h
  520. @@ -145,6 +145,8 @@ struct mmc_host_ops {
  521. /* Prepare HS400 target operating frequency depending host driver */
  522. int (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios);
  523. + int (*prepare_ddr_to_hs400)(struct mmc_host *host);
  524. +
  525. /* Prepare enhanced strobe depending host driver */
  526. void (*hs400_enhanced_strobe)(struct mmc_host *host,
  527. struct mmc_ios *ios);