blob: 0df3568f073bcada37a612f574c01fdb5f6a1ca1 [file] [log] [blame]
Lokesh Vutlabc9979f2018-08-27 15:57:54 +05301// SPDX-License-Identifier: GPL-2.0+
2/*
Nishanth Menoneaa39c62023-11-01 15:56:03 -05003 * Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com/
Lokesh Vutlabc9979f2018-08-27 15:57:54 +05304 *
5 * Texas Instruments' K3 SD Host Controller Interface
6 */
7
8#include <clk.h>
Lokesh Vutlabc9979f2018-08-27 15:57:54 +05309#include <dm.h>
10#include <malloc.h>
Faiz Abbas7a7e2c72021-02-04 15:10:53 +053011#include <mmc.h>
Lokesh Vutlabc9979f2018-08-27 15:57:54 +053012#include <power-domain.h>
Faiz Abbase9aed582019-06-11 00:43:38 +053013#include <regmap.h>
Lokesh Vutlabc9979f2018-08-27 15:57:54 +053014#include <sdhci.h>
Faiz Abbas2c2fc962021-02-04 15:10:50 +053015#include <soc.h>
Simon Glass9bc15642020-02-03 07:36:16 -070016#include <dm/device_compat.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060017#include <linux/bitops.h>
Simon Glassd66c5f72020-02-03 07:36:15 -070018#include <linux/err.h>
Lokesh Vutlabc9979f2018-08-27 15:57:54 +053019
Faiz Abbase9aed582019-06-11 00:43:38 +053020/* CTL_CFG Registers */
21#define CTL_CFG_2 0x14
22
23#define SLOTTYPE_MASK GENMASK(31, 30)
24#define SLOTTYPE_EMBEDDED BIT(30)
25
26/* PHY Registers */
27#define PHY_CTRL1 0x100
28#define PHY_CTRL2 0x104
29#define PHY_CTRL3 0x108
30#define PHY_CTRL4 0x10C
31#define PHY_CTRL5 0x110
32#define PHY_CTRL6 0x114
33#define PHY_STAT1 0x130
34#define PHY_STAT2 0x134
35
36#define IOMUX_ENABLE_SHIFT 31
37#define IOMUX_ENABLE_MASK BIT(IOMUX_ENABLE_SHIFT)
38#define OTAPDLYENA_SHIFT 20
39#define OTAPDLYENA_MASK BIT(OTAPDLYENA_SHIFT)
40#define OTAPDLYSEL_SHIFT 12
41#define OTAPDLYSEL_MASK GENMASK(15, 12)
42#define STRBSEL_SHIFT 24
Faiz Abbas8cc051e2020-01-16 19:42:19 +053043#define STRBSEL_4BIT_MASK GENMASK(27, 24)
44#define STRBSEL_8BIT_MASK GENMASK(31, 24)
Faiz Abbase9aed582019-06-11 00:43:38 +053045#define SEL50_SHIFT 8
46#define SEL50_MASK BIT(SEL50_SHIFT)
47#define SEL100_SHIFT 9
48#define SEL100_MASK BIT(SEL100_SHIFT)
Faiz Abbas8cc051e2020-01-16 19:42:19 +053049#define FREQSEL_SHIFT 8
50#define FREQSEL_MASK GENMASK(10, 8)
Faiz Abbasc73f04e2021-02-04 15:10:52 +053051#define CLKBUFSEL_SHIFT 0
52#define CLKBUFSEL_MASK GENMASK(2, 0)
Faiz Abbase9aed582019-06-11 00:43:38 +053053#define DLL_TRIM_ICP_SHIFT 4
54#define DLL_TRIM_ICP_MASK GENMASK(7, 4)
55#define DR_TY_SHIFT 20
56#define DR_TY_MASK GENMASK(22, 20)
57#define ENDLL_SHIFT 1
58#define ENDLL_MASK BIT(ENDLL_SHIFT)
59#define DLLRDY_SHIFT 0
60#define DLLRDY_MASK BIT(DLLRDY_SHIFT)
61#define PDB_SHIFT 0
62#define PDB_MASK BIT(PDB_SHIFT)
63#define CALDONE_SHIFT 1
64#define CALDONE_MASK BIT(CALDONE_SHIFT)
65#define RETRIM_SHIFT 17
66#define RETRIM_MASK BIT(RETRIM_SHIFT)
Faiz Abbasdef2a0f2021-02-04 15:10:51 +053067#define SELDLYTXCLK_SHIFT 17
68#define SELDLYTXCLK_MASK BIT(SELDLYTXCLK_SHIFT)
69#define SELDLYRXCLK_SHIFT 16
70#define SELDLYRXCLK_MASK BIT(SELDLYRXCLK_SHIFT)
71#define ITAPDLYSEL_SHIFT 0
72#define ITAPDLYSEL_MASK GENMASK(4, 0)
73#define ITAPDLYENA_SHIFT 8
74#define ITAPDLYENA_MASK BIT(ITAPDLYENA_SHIFT)
75#define ITAPCHGWIN_SHIFT 9
76#define ITAPCHGWIN_MASK BIT(ITAPCHGWIN_SHIFT)
Faiz Abbase9aed582019-06-11 00:43:38 +053077
78#define DRIVER_STRENGTH_50_OHM 0x0
79#define DRIVER_STRENGTH_33_OHM 0x1
80#define DRIVER_STRENGTH_66_OHM 0x2
81#define DRIVER_STRENGTH_100_OHM 0x3
82#define DRIVER_STRENGTH_40_OHM 0x4
83
Faiz Abbasd8fb3092019-06-11 00:43:31 +053084#define AM654_SDHCI_MIN_FREQ 400000
Faiz Abbasdef2a0f2021-02-04 15:10:51 +053085#define CLOCK_TOO_SLOW_HZ 50000000
Lokesh Vutlabc9979f2018-08-27 15:57:54 +053086
Judith Mendez87bcbde2024-04-18 14:00:58 -050087#define ENABLE 0x1
88
Faiz Abbasd8fb3092019-06-11 00:43:31 +053089struct am654_sdhci_plat {
Lokesh Vutlabc9979f2018-08-27 15:57:54 +053090 struct mmc_config cfg;
91 struct mmc mmc;
Faiz Abbase9aed582019-06-11 00:43:38 +053092 struct regmap *base;
93 bool non_removable;
Faiz Abbas7101e122020-07-29 07:03:41 +053094 u32 otap_del_sel[MMC_MODES_END];
Faiz Abbasdef2a0f2021-02-04 15:10:51 +053095 u32 itap_del_sel[MMC_MODES_END];
Judith Mendez87bcbde2024-04-18 14:00:58 -050096 u32 itap_del_ena[MMC_MODES_END];
Faiz Abbase9aed582019-06-11 00:43:38 +053097 u32 trm_icp;
98 u32 drv_strength;
Faiz Abbas8cc051e2020-01-16 19:42:19 +053099 u32 strb_sel;
Faiz Abbasc73f04e2021-02-04 15:10:52 +0530100 u32 clkbuf_sel;
Faiz Abbasfd8be702019-06-13 10:29:51 +0530101 u32 flags;
Judith Mendez81c1d442024-04-18 14:00:56 -0500102 bool dll_enable;
Faiz Abbasb7f57bb2021-02-04 15:10:48 +0530103#define DLL_PRESENT BIT(0)
104#define IOMUX_PRESENT BIT(1)
105#define FREQSEL_2_BIT BIT(2)
106#define STRBSEL_4_BIT BIT(3)
Faiz Abbas947e8f32021-02-04 15:10:49 +0530107#define DLL_CALIB BIT(4)
Emanuele Ghidolifde0dff2024-07-02 21:54:29 +0200108 u32 quirks;
109#define SDHCI_AM654_QUIRK_FORCE_CDTEST BIT(0)
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530110};
111
Faiz Abbasc6eb9e72020-02-26 13:44:33 +0530112struct timing_data {
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530113 const char *otap_binding;
114 const char *itap_binding;
Faiz Abbasc6eb9e72020-02-26 13:44:33 +0530115 u32 capability;
116};
117
Judith Mendez81c1d442024-04-18 14:00:56 -0500118struct window {
119 u8 start;
120 u8 end;
121 u8 length;
122};
123
Faiz Abbasc6eb9e72020-02-26 13:44:33 +0530124static const struct timing_data td[] = {
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530125 [MMC_LEGACY] = {"ti,otap-del-sel-legacy",
126 "ti,itap-del-sel-legacy",
127 0},
Judith Mendez14e6fb22025-04-17 18:43:31 -0500128 [MMC_HS] = {"ti,otap-del-sel-mmc-hs26",
129 "ti,itap-del-sel-mmc-hs26",
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530130 MMC_CAP(MMC_HS)},
131 [SD_HS] = {"ti,otap-del-sel-sd-hs",
132 "ti,itap-del-sel-sd-hs",
133 MMC_CAP(SD_HS)},
Judith Mendez14e6fb22025-04-17 18:43:31 -0500134 [MMC_HS_52] = {"ti,otap-del-sel-mmc-hs",
135 "ti,itap-del-sel-mmc-hs",
136 MMC_CAP(MMC_HS_52)},
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530137 [UHS_SDR12] = {"ti,otap-del-sel-sdr12",
138 "ti,itap-del-sel-sdr12",
139 MMC_CAP(UHS_SDR12)},
140 [UHS_SDR25] = {"ti,otap-del-sel-sdr25",
141 "ti,itap-del-sel-sdr25",
142 MMC_CAP(UHS_SDR25)},
143 [UHS_SDR50] = {"ti,otap-del-sel-sdr50",
144 NULL,
145 MMC_CAP(UHS_SDR50)},
146 [UHS_SDR104] = {"ti,otap-del-sel-sdr104",
147 NULL,
148 MMC_CAP(UHS_SDR104)},
149 [UHS_DDR50] = {"ti,otap-del-sel-ddr50",
150 NULL,
151 MMC_CAP(UHS_DDR50)},
152 [MMC_DDR_52] = {"ti,otap-del-sel-ddr52",
153 "ti,itap-del-sel-ddr52",
154 MMC_CAP(MMC_DDR_52)},
155 [MMC_HS_200] = {"ti,otap-del-sel-hs200",
156 NULL,
157 MMC_CAP(MMC_HS_200)},
158 [MMC_HS_400] = {"ti,otap-del-sel-hs400",
159 NULL,
160 MMC_CAP(MMC_HS_400)},
Faiz Abbasc6eb9e72020-02-26 13:44:33 +0530161};
162
Faiz Abbas8cc051e2020-01-16 19:42:19 +0530163struct am654_driver_data {
164 const struct sdhci_ops *ops;
165 u32 flags;
166};
167
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530168static int am654_sdhci_setup_dll(struct am654_sdhci_plat *plat,
169 unsigned int speed)
170{
171 int sel50, sel100, freqsel;
172 u32 mask, val;
173 int ret;
174
175 /* Disable delay chain mode */
176 regmap_update_bits(plat->base, PHY_CTRL5,
177 SELDLYTXCLK_MASK | SELDLYRXCLK_MASK, 0);
178
179 if (plat->flags & FREQSEL_2_BIT) {
180 switch (speed) {
181 case 200000000:
182 sel50 = 0;
183 sel100 = 0;
184 break;
185 case 100000000:
186 sel50 = 0;
187 sel100 = 1;
188 break;
189 default:
190 sel50 = 1;
191 sel100 = 0;
192 }
193
194 /* Configure PHY DLL frequency */
195 mask = SEL50_MASK | SEL100_MASK;
196 val = (sel50 << SEL50_SHIFT) | (sel100 << SEL100_SHIFT);
197 regmap_update_bits(plat->base, PHY_CTRL5, mask, val);
198 } else {
199 switch (speed) {
200 case 200000000:
201 freqsel = 0x0;
202 break;
203 default:
204 freqsel = 0x4;
205 }
206 regmap_update_bits(plat->base, PHY_CTRL5, FREQSEL_MASK,
207 freqsel << FREQSEL_SHIFT);
208 }
209
210 /* Configure DLL TRIM */
211 mask = DLL_TRIM_ICP_MASK;
212 val = plat->trm_icp << DLL_TRIM_ICP_SHIFT;
213
214 /* Configure DLL driver strength */
215 mask |= DR_TY_MASK;
216 val |= plat->drv_strength << DR_TY_SHIFT;
217 regmap_update_bits(plat->base, PHY_CTRL1, mask, val);
218
219 /* Enable DLL */
220 regmap_update_bits(plat->base, PHY_CTRL1, ENDLL_MASK,
221 0x1 << ENDLL_SHIFT);
222 /*
223 * Poll for DLL ready. Use a one second timeout.
224 * Works in all experiments done so far
225 */
226 ret = regmap_read_poll_timeout(plat->base, PHY_STAT1, val,
227 val & DLLRDY_MASK, 1000, 1000000);
228
229 return ret;
230}
231
232static void am654_sdhci_write_itapdly(struct am654_sdhci_plat *plat,
Judith Mendez87bcbde2024-04-18 14:00:58 -0500233 u32 itapdly, u32 enable)
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530234{
Judith Mendez87bcbde2024-04-18 14:00:58 -0500235 regmap_update_bits(plat->base, PHY_CTRL4, ITAPDLYENA_MASK,
236 enable << ITAPDLYENA_SHIFT);
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530237 /* Set ITAPCHGWIN before writing to ITAPDLY */
238 regmap_update_bits(plat->base, PHY_CTRL4, ITAPCHGWIN_MASK,
239 1 << ITAPCHGWIN_SHIFT);
240 regmap_update_bits(plat->base, PHY_CTRL4, ITAPDLYSEL_MASK,
241 itapdly << ITAPDLYSEL_SHIFT);
242 regmap_update_bits(plat->base, PHY_CTRL4, ITAPCHGWIN_MASK, 0);
243}
244
245static void am654_sdhci_setup_delay_chain(struct am654_sdhci_plat *plat,
246 int mode)
247{
248 u32 mask, val;
249
250 val = 1 << SELDLYTXCLK_SHIFT | 1 << SELDLYRXCLK_SHIFT;
251 mask = SELDLYTXCLK_MASK | SELDLYRXCLK_MASK;
252 regmap_update_bits(plat->base, PHY_CTRL5, mask, val);
253
Judith Mendez87bcbde2024-04-18 14:00:58 -0500254 am654_sdhci_write_itapdly(plat, plat->itap_del_sel[mode],
255 plat->itap_del_ena[mode]);
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530256}
257
Faiz Abbase9aed582019-06-11 00:43:38 +0530258static int am654_sdhci_set_ios_post(struct sdhci_host *host)
259{
260 struct udevice *dev = host->mmc->dev;
Simon Glassfa20e932020-12-03 16:55:20 -0700261 struct am654_sdhci_plat *plat = dev_get_plat(dev);
Faiz Abbase9aed582019-06-11 00:43:38 +0530262 unsigned int speed = host->mmc->clock;
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530263 int mode = host->mmc->selected_mode;
Faiz Abbasc6eb9e72020-02-26 13:44:33 +0530264 u32 otap_del_sel;
Faiz Abbase9aed582019-06-11 00:43:38 +0530265 u32 mask, val;
266 int ret;
267
268 /* Reset SD Clock Enable */
269 val = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
270 val &= ~SDHCI_CLOCK_CARD_EN;
271 sdhci_writew(host, val, SDHCI_CLOCK_CONTROL);
272
Faiz Abbas2c45a2c2021-02-04 15:10:47 +0530273 regmap_update_bits(plat->base, PHY_CTRL1, ENDLL_MASK, 0);
Faiz Abbase9aed582019-06-11 00:43:38 +0530274
275 /* restart clock */
276 sdhci_set_clock(host->mmc, speed);
277
278 /* switch phy back on */
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530279 otap_del_sel = plat->otap_del_sel[mode];
280 mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
281 val = (1 << OTAPDLYENA_SHIFT) |
282 (otap_del_sel << OTAPDLYSEL_SHIFT);
Faiz Abbas8cc051e2020-01-16 19:42:19 +0530283
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530284 /* Write to STRBSEL for HS400 speed mode */
285 if (host->mmc->selected_mode == MMC_HS_400) {
286 if (plat->flags & STRBSEL_4_BIT)
287 mask |= STRBSEL_4BIT_MASK;
288 else
289 mask |= STRBSEL_8BIT_MASK;
Faiz Abbas8cc051e2020-01-16 19:42:19 +0530290
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530291 val |= plat->strb_sel << STRBSEL_SHIFT;
292 }
Faiz Abbas947e8f32021-02-04 15:10:49 +0530293
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530294 regmap_update_bits(plat->base, PHY_CTRL4, mask, val);
Faiz Abbas947e8f32021-02-04 15:10:49 +0530295
Judith Mendezc9eb1dc2024-04-18 14:00:59 -0500296 if ((mode > UHS_SDR25 || mode == MMC_DDR_52) && speed >= CLOCK_TOO_SLOW_HZ) {
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530297 ret = am654_sdhci_setup_dll(plat, speed);
Faiz Abbase9aed582019-06-11 00:43:38 +0530298 if (ret)
299 return ret;
Judith Mendez81c1d442024-04-18 14:00:56 -0500300
301 plat->dll_enable = true;
Judith Mendez5d217152024-04-18 14:01:00 -0500302 if (mode == MMC_HS_400) {
303 plat->itap_del_ena[mode] = ENABLE;
304 plat->itap_del_sel[mode] = plat->itap_del_sel[mode - 1];
305 }
306
Judith Mendezc9eb1dc2024-04-18 14:00:59 -0500307 am654_sdhci_write_itapdly(plat, plat->itap_del_sel[mode],
308 plat->itap_del_ena[mode]);
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530309 } else {
310 am654_sdhci_setup_delay_chain(plat, mode);
Judith Mendez81c1d442024-04-18 14:00:56 -0500311 plat->dll_enable = false;
Faiz Abbase9aed582019-06-11 00:43:38 +0530312 }
313
Faiz Abbasc73f04e2021-02-04 15:10:52 +0530314 regmap_update_bits(plat->base, PHY_CTRL5, CLKBUFSEL_MASK,
315 plat->clkbuf_sel);
316
Faiz Abbase9aed582019-06-11 00:43:38 +0530317 return 0;
318}
319
Faiz Abbase9aed582019-06-11 00:43:38 +0530320int am654_sdhci_init(struct am654_sdhci_plat *plat)
321{
322 u32 ctl_cfg_2 = 0;
323 u32 mask, val;
324 int ret;
325
326 /* Reset OTAP to default value */
327 mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
328 regmap_update_bits(plat->base, PHY_CTRL4, mask, 0x0);
329
Faiz Abbas947e8f32021-02-04 15:10:49 +0530330 if (plat->flags & DLL_CALIB) {
Faiz Abbasfd8be702019-06-13 10:29:51 +0530331 regmap_read(plat->base, PHY_STAT1, &val);
332 if (~val & CALDONE_MASK) {
333 /* Calibrate IO lines */
334 regmap_update_bits(plat->base, PHY_CTRL1, PDB_MASK,
335 PDB_MASK);
336 ret = regmap_read_poll_timeout(plat->base, PHY_STAT1,
337 val, val & CALDONE_MASK,
338 1, 20);
339 if (ret)
340 return ret;
341 }
Faiz Abbasfd8be702019-06-13 10:29:51 +0530342 }
Faiz Abbase9aed582019-06-11 00:43:38 +0530343
344 /* Enable pins by setting IO mux to 0 */
Faiz Abbas8cc051e2020-01-16 19:42:19 +0530345 if (plat->flags & IOMUX_PRESENT)
346 regmap_update_bits(plat->base, PHY_CTRL1, IOMUX_ENABLE_MASK, 0);
Faiz Abbase9aed582019-06-11 00:43:38 +0530347
348 /* Set slot type based on SD or eMMC */
349 if (plat->non_removable)
350 ctl_cfg_2 = SLOTTYPE_EMBEDDED;
351
352 regmap_update_bits(plat->base, CTL_CFG_2, SLOTTYPE_MASK, ctl_cfg_2);
353
354 return 0;
355}
356
Faiz Abbase4425cb2020-02-26 13:44:34 +0530357#define MAX_SDCD_DEBOUNCE_TIME 2000
Emanuele Ghidolifde0dff2024-07-02 21:54:29 +0200358static int am654_sdhci_cd_poll(struct mmc *mmc)
Faiz Abbase4425cb2020-02-26 13:44:34 +0530359{
Faiz Abbase4425cb2020-02-26 13:44:34 +0530360 unsigned long start;
361 int val;
362
363 /*
364 * The controller takes about 1 second to debounce the card detect line
365 * and doesn't let us power on until that time is up. Instead of waiting
366 * for 1 second at every stage, poll on the CARD_PRESENT bit upto a
367 * maximum of 2 seconds to be safe..
368 */
369 start = get_timer(0);
370 do {
371 if (get_timer(start) > MAX_SDCD_DEBOUNCE_TIME)
372 return -ENOMEDIUM;
373
Emanuele Ghidolifde0dff2024-07-02 21:54:29 +0200374 val = mmc_getcd(mmc);
Faiz Abbase4425cb2020-02-26 13:44:34 +0530375 } while (!val);
376
Emanuele Ghidolifde0dff2024-07-02 21:54:29 +0200377 return 0;
378}
379
380static int am654_sdhci_deferred_probe(struct sdhci_host *host)
381{
382 struct udevice *dev = host->mmc->dev;
383 struct am654_sdhci_plat *plat = dev_get_plat(dev);
384 int ret;
385
386 if (!(plat->quirks & SDHCI_AM654_QUIRK_FORCE_CDTEST)) {
387 if (am654_sdhci_cd_poll(host->mmc))
388 return -ENOMEDIUM;
389 }
390
Faiz Abbase4425cb2020-02-26 13:44:34 +0530391 am654_sdhci_init(plat);
392
Emanuele Ghidolifde0dff2024-07-02 21:54:29 +0200393 ret = sdhci_probe(dev);
394
395 if (plat->quirks & SDHCI_AM654_QUIRK_FORCE_CDTEST) {
396 u8 hostctrlreg = sdhci_readb(host, SDHCI_HOST_CONTROL);
397
398 hostctrlreg |= SDHCI_CTRL_CD_TEST_INS | SDHCI_CTRL_CD_TEST;
399 sdhci_writeb(host, hostctrlreg, SDHCI_HOST_CONTROL);
400 }
401
402 return ret;
Faiz Abbase4425cb2020-02-26 13:44:34 +0530403}
404
Faiz Abbas36c8c5c2021-02-04 15:10:54 +0530405static void am654_sdhci_write_b(struct sdhci_host *host, u8 val, int reg)
406{
407 if (reg == SDHCI_HOST_CONTROL) {
408 switch (host->mmc->selected_mode) {
409 /*
410 * According to the data manual, HISPD bit
411 * should not be set in these speed modes.
412 */
413 case SD_HS:
414 case MMC_HS:
Judith Mendez45c34f92025-04-17 18:43:32 -0500415 case MMC_HS_52:
Faiz Abbas36c8c5c2021-02-04 15:10:54 +0530416 val &= ~SDHCI_CTRL_HISPD;
417 default:
418 break;
419 }
420 }
421
422 writeb(val, host->ioaddr + reg);
423}
Tom Rinidec7ea02024-05-20 13:35:03 -0600424#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING)
Judith Mendez81c1d442024-04-18 14:00:56 -0500425#define ITAPDLY_LENGTH 32
426#define ITAPDLY_LAST_INDEX (ITAPDLY_LENGTH - 1)
427
428static u32 am654_sdhci_calculate_itap(struct udevice *dev, struct window
429 *fail_window, u8 num_fails, bool circular_buffer)
430{
431 u8 itap = 0, start_fail = 0, end_fail = 0, pass_length = 0;
432 u8 first_fail_start = 0, last_fail_end = 0;
433 struct window pass_window = {0, 0, 0};
434 int prev_fail_end = -1;
435 u8 i;
436
437 if (!num_fails)
438 return ITAPDLY_LAST_INDEX >> 1;
439
440 if (fail_window->length == ITAPDLY_LENGTH) {
441 dev_err(dev, "No passing ITAPDLY, return 0\n");
442 return 0;
443 }
444
445 first_fail_start = fail_window->start;
446 last_fail_end = fail_window[num_fails - 1].end;
447
448 for (i = 0; i < num_fails; i++) {
449 start_fail = fail_window[i].start;
450 end_fail = fail_window[i].end;
451 pass_length = start_fail - (prev_fail_end + 1);
452
453 if (pass_length > pass_window.length) {
454 pass_window.start = prev_fail_end + 1;
455 pass_window.length = pass_length;
456 }
457 prev_fail_end = end_fail;
458 }
459
460 if (!circular_buffer)
461 pass_length = ITAPDLY_LAST_INDEX - last_fail_end;
462 else
463 pass_length = ITAPDLY_LAST_INDEX - last_fail_end + first_fail_start;
464
465 if (pass_length > pass_window.length) {
466 pass_window.start = last_fail_end + 1;
467 pass_window.length = pass_length;
468 }
469
470 if (!circular_buffer)
471 itap = pass_window.start + (pass_window.length >> 1);
472 else
473 itap = (pass_window.start + (pass_window.length >> 1)) % ITAPDLY_LENGTH;
474
475 return (itap > ITAPDLY_LAST_INDEX) ? ITAPDLY_LAST_INDEX >> 1 : itap;
476}
477
Faiz Abbas7a7e2c72021-02-04 15:10:53 +0530478static int am654_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
479{
480 struct udevice *dev = mmc->dev;
481 struct am654_sdhci_plat *plat = dev_get_plat(dev);
Judith Mendez81c1d442024-04-18 14:00:56 -0500482 struct window fail_window[ITAPDLY_LENGTH];
Judith Mendez87bcbde2024-04-18 14:00:58 -0500483 int mode = mmc->selected_mode;
Judith Mendez81c1d442024-04-18 14:00:56 -0500484 u8 curr_pass, itap;
485 u8 fail_index = 0;
486 u8 prev_pass = 1;
487
488 memset(fail_window, 0, sizeof(fail_window));
Faiz Abbas7a7e2c72021-02-04 15:10:53 +0530489
490 /* Enable ITAPDLY */
Judith Mendez87bcbde2024-04-18 14:00:58 -0500491 plat->itap_del_ena[mode] = ENABLE;
Faiz Abbas7a7e2c72021-02-04 15:10:53 +0530492
Judith Mendez81c1d442024-04-18 14:00:56 -0500493 for (itap = 0; itap < ITAPDLY_LENGTH; itap++) {
Judith Mendez87bcbde2024-04-18 14:00:58 -0500494 am654_sdhci_write_itapdly(plat, itap, plat->itap_del_ena[mode]);
Faiz Abbas7a7e2c72021-02-04 15:10:53 +0530495
Judith Mendez81c1d442024-04-18 14:00:56 -0500496 curr_pass = !mmc_send_tuning(mmc, opcode);
497
498 if (!curr_pass && prev_pass)
499 fail_window[fail_index].start = itap;
Faiz Abbas7a7e2c72021-02-04 15:10:53 +0530500
Judith Mendez81c1d442024-04-18 14:00:56 -0500501 if (!curr_pass) {
502 fail_window[fail_index].end = itap;
503 fail_window[fail_index].length++;
504 }
505
506 if (curr_pass && !prev_pass)
507 fail_index++;
Faiz Abbas7a7e2c72021-02-04 15:10:53 +0530508
Judith Mendez81c1d442024-04-18 14:00:56 -0500509 prev_pass = curr_pass;
Faiz Abbas7a7e2c72021-02-04 15:10:53 +0530510 }
Judith Mendez81c1d442024-04-18 14:00:56 -0500511
512 if (fail_window[fail_index].length != 0)
513 fail_index++;
514
515 itap = am654_sdhci_calculate_itap(dev, fail_window, fail_index,
516 plat->dll_enable);
517
Judith Mendez5d217152024-04-18 14:01:00 -0500518 /* Save ITAPDLY */
519 plat->itap_del_sel[mode] = itap;
520
Judith Mendez87bcbde2024-04-18 14:00:58 -0500521 am654_sdhci_write_itapdly(plat, itap, plat->itap_del_ena[mode]);
Faiz Abbas7a7e2c72021-02-04 15:10:53 +0530522
523 return 0;
524}
525#endif
Judith Mendezc9268d52025-04-17 18:43:33 -0500526
527void am654_sdhci_set_control_reg(struct sdhci_host *host)
528{
529 struct mmc *mmc = host->mmc;
530
531 sdhci_set_voltage(host);
532
533 if (mmc->selected_mode > MMC_HS_52)
534 sdhci_set_uhs_timing(host);
535}
536
Faiz Abbase4425cb2020-02-26 13:44:34 +0530537const struct sdhci_ops am654_sdhci_ops = {
Tom Rinidec7ea02024-05-20 13:35:03 -0600538#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING)
Faiz Abbas7a7e2c72021-02-04 15:10:53 +0530539 .platform_execute_tuning = am654_sdhci_execute_tuning,
540#endif
Faiz Abbase4425cb2020-02-26 13:44:34 +0530541 .deferred_probe = am654_sdhci_deferred_probe,
542 .set_ios_post = &am654_sdhci_set_ios_post,
Judith Mendezc9268d52025-04-17 18:43:33 -0500543 .set_control_reg = am654_sdhci_set_control_reg,
Faiz Abbas36c8c5c2021-02-04 15:10:54 +0530544 .write_b = am654_sdhci_write_b,
Faiz Abbase4425cb2020-02-26 13:44:34 +0530545};
546
547const struct am654_driver_data am654_drv_data = {
548 .ops = &am654_sdhci_ops,
Faiz Abbas2c2fc962021-02-04 15:10:50 +0530549 .flags = DLL_PRESENT | IOMUX_PRESENT | FREQSEL_2_BIT | STRBSEL_4_BIT,
550};
551
552const struct am654_driver_data am654_sr1_drv_data = {
553 .ops = &am654_sdhci_ops,
Faiz Abbas947e8f32021-02-04 15:10:49 +0530554 .flags = IOMUX_PRESENT | FREQSEL_2_BIT | DLL_PRESENT | DLL_CALIB |
555 STRBSEL_4_BIT,
Faiz Abbase4425cb2020-02-26 13:44:34 +0530556};
557
558const struct am654_driver_data j721e_8bit_drv_data = {
559 .ops = &am654_sdhci_ops,
Faiz Abbas947e8f32021-02-04 15:10:49 +0530560 .flags = DLL_PRESENT | DLL_CALIB,
Faiz Abbase4425cb2020-02-26 13:44:34 +0530561};
562
563static int j721e_4bit_sdhci_set_ios_post(struct sdhci_host *host)
564{
565 struct udevice *dev = host->mmc->dev;
Simon Glassfa20e932020-12-03 16:55:20 -0700566 struct am654_sdhci_plat *plat = dev_get_plat(dev);
Nitin Yadav83db1f92024-04-18 14:00:57 -0500567 int mode = host->mmc->selected_mode;
568 u32 otap_del_sel;
Judith Mendez87bcbde2024-04-18 14:00:58 -0500569 u32 itap_del_ena;
Nitin Yadav83db1f92024-04-18 14:00:57 -0500570 u32 itap_del_sel;
571 u32 mask, val;
Faiz Abbase4425cb2020-02-26 13:44:34 +0530572
Nitin Yadav83db1f92024-04-18 14:00:57 -0500573 otap_del_sel = plat->otap_del_sel[mode];
574
Faiz Abbase4425cb2020-02-26 13:44:34 +0530575 mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
Nitin Yadav83db1f92024-04-18 14:00:57 -0500576 val = (1 << OTAPDLYENA_SHIFT) |
577 (otap_del_sel << OTAPDLYSEL_SHIFT);
578
Judith Mendez87bcbde2024-04-18 14:00:58 -0500579 itap_del_ena = plat->itap_del_ena[mode];
Nitin Yadav83db1f92024-04-18 14:00:57 -0500580 itap_del_sel = plat->itap_del_sel[mode];
581
582 mask |= ITAPDLYENA_MASK | ITAPDLYSEL_MASK;
Judith Mendez87bcbde2024-04-18 14:00:58 -0500583 val |= (itap_del_ena << ITAPDLYENA_SHIFT) |
Nitin Yadav83db1f92024-04-18 14:00:57 -0500584 (itap_del_sel << ITAPDLYSEL_SHIFT);
585
586 regmap_update_bits(plat->base, PHY_CTRL4, ITAPCHGWIN_MASK,
587 1 << ITAPCHGWIN_SHIFT);
Faiz Abbase4425cb2020-02-26 13:44:34 +0530588 regmap_update_bits(plat->base, PHY_CTRL4, mask, val);
Nitin Yadav83db1f92024-04-18 14:00:57 -0500589 regmap_update_bits(plat->base, PHY_CTRL4, ITAPCHGWIN_MASK, 0);
Faiz Abbase4425cb2020-02-26 13:44:34 +0530590
Faiz Abbasc73f04e2021-02-04 15:10:52 +0530591 regmap_update_bits(plat->base, PHY_CTRL5, CLKBUFSEL_MASK,
592 plat->clkbuf_sel);
593
Faiz Abbase4425cb2020-02-26 13:44:34 +0530594 return 0;
595}
596
597const struct sdhci_ops j721e_4bit_sdhci_ops = {
Tom Rinidec7ea02024-05-20 13:35:03 -0600598#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING)
Faiz Abbas7a7e2c72021-02-04 15:10:53 +0530599 .platform_execute_tuning = am654_sdhci_execute_tuning,
600#endif
Faiz Abbase4425cb2020-02-26 13:44:34 +0530601 .deferred_probe = am654_sdhci_deferred_probe,
602 .set_ios_post = &j721e_4bit_sdhci_set_ios_post,
Judith Mendezc9268d52025-04-17 18:43:33 -0500603 .set_control_reg = am654_sdhci_set_control_reg,
Faiz Abbas36c8c5c2021-02-04 15:10:54 +0530604 .write_b = am654_sdhci_write_b,
Faiz Abbase4425cb2020-02-26 13:44:34 +0530605};
606
607const struct am654_driver_data j721e_4bit_drv_data = {
608 .ops = &j721e_4bit_sdhci_ops,
609 .flags = IOMUX_PRESENT,
610};
611
Dave Gerlach057d6af2021-04-23 11:27:40 -0500612static const struct am654_driver_data sdhci_am64_8bit_drvdata = {
613 .ops = &am654_sdhci_ops,
614 .flags = DLL_PRESENT | DLL_CALIB,
615};
616
617static const struct am654_driver_data sdhci_am64_4bit_drvdata = {
618 .ops = &j721e_4bit_sdhci_ops,
619 .flags = IOMUX_PRESENT,
620};
621
Faiz Abbas2c2fc962021-02-04 15:10:50 +0530622const struct soc_attr am654_sdhci_soc_attr[] = {
623 { .family = "AM65X", .revision = "SR1.0", .data = &am654_sr1_drv_data},
624 {/* sentinel */}
625};
626
Faiz Abbasc6eb9e72020-02-26 13:44:33 +0530627static int sdhci_am654_get_otap_delay(struct udevice *dev,
628 struct mmc_config *cfg)
629{
Simon Glassfa20e932020-12-03 16:55:20 -0700630 struct am654_sdhci_plat *plat = dev_get_plat(dev);
Faiz Abbasc6eb9e72020-02-26 13:44:33 +0530631 int ret;
632 int i;
633
634 /* ti,otap-del-sel-legacy is mandatory */
635 ret = dev_read_u32(dev, "ti,otap-del-sel-legacy",
636 &plat->otap_del_sel[0]);
637 if (ret)
638 return ret;
639 /*
640 * Remove the corresponding capability if an otap-del-sel
641 * value is not found
642 */
Nitin Yadav83db1f92024-04-18 14:00:57 -0500643 for (i = MMC_LEGACY; i <= MMC_HS_400; i++) {
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530644 ret = dev_read_u32(dev, td[i].otap_binding,
645 &plat->otap_del_sel[i]);
Faiz Abbasc6eb9e72020-02-26 13:44:33 +0530646 if (ret) {
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530647 dev_dbg(dev, "Couldn't find %s\n", td[i].otap_binding);
Faiz Abbasc6eb9e72020-02-26 13:44:33 +0530648 /*
649 * Remove the corresponding capability
650 * if an otap-del-sel value is not found
651 */
652 cfg->host_caps &= ~td[i].capability;
653 }
Faiz Abbasdef2a0f2021-02-04 15:10:51 +0530654
Judith Mendez87bcbde2024-04-18 14:00:58 -0500655 if (td[i].itap_binding) {
656 ret = dev_read_u32(dev, td[i].itap_binding,
657 &plat->itap_del_sel[i]);
658
659 if (!ret)
660 plat->itap_del_ena[i] = ENABLE;
661 }
Faiz Abbasc6eb9e72020-02-26 13:44:33 +0530662 }
663
664 return 0;
665}
666
Faiz Abbasd8fb3092019-06-11 00:43:31 +0530667static int am654_sdhci_probe(struct udevice *dev)
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530668{
Faiz Abbas8cc051e2020-01-16 19:42:19 +0530669 struct am654_driver_data *drv_data =
670 (struct am654_driver_data *)dev_get_driver_data(dev);
Simon Glassfa20e932020-12-03 16:55:20 -0700671 struct am654_sdhci_plat *plat = dev_get_plat(dev);
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530672 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
673 struct sdhci_host *host = dev_get_priv(dev);
Faiz Abbase9aed582019-06-11 00:43:38 +0530674 struct mmc_config *cfg = &plat->cfg;
Faiz Abbas2c2fc962021-02-04 15:10:50 +0530675 const struct soc_attr *soc;
676 const struct am654_driver_data *soc_drv_data;
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530677 struct clk clk;
678 unsigned long clock;
679 int ret;
680
Faiz Abbasdc2bcc22020-01-16 19:42:18 +0530681 ret = clk_get_by_name(dev, "clk_xin", &clk);
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530682 if (ret) {
683 dev_err(dev, "failed to get clock\n");
684 return ret;
685 }
686
687 clock = clk_get_rate(&clk);
688 if (IS_ERR_VALUE(clock)) {
689 dev_err(dev, "failed to get rate\n");
690 return clock;
691 }
692
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530693 host->max_clk = clock;
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530694 host->mmc = &plat->mmc;
Faiz Abbase9aed582019-06-11 00:43:38 +0530695 host->mmc->dev = dev;
Faiz Abbas36c8c5c2021-02-04 15:10:54 +0530696 host->ops = drv_data->ops;
Faiz Abbase9aed582019-06-11 00:43:38 +0530697 ret = sdhci_setup_cfg(cfg, host, cfg->f_max,
698 AM654_SDHCI_MIN_FREQ);
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530699 if (ret)
700 return ret;
Faiz Abbas8cc051e2020-01-16 19:42:19 +0530701
Faiz Abbasc6eb9e72020-02-26 13:44:33 +0530702 ret = sdhci_am654_get_otap_delay(dev, cfg);
703 if (ret)
704 return ret;
705
Faiz Abbas2c2fc962021-02-04 15:10:50 +0530706 /* Update ops based on SoC revision */
707 soc = soc_device_match(am654_sdhci_soc_attr);
708 if (soc && soc->data) {
709 soc_drv_data = soc->data;
710 host->ops = soc_drv_data->ops;
711 }
712
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530713 host->mmc->priv = host;
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530714 upriv->mmc = host->mmc;
715
Faiz Abbase9aed582019-06-11 00:43:38 +0530716 regmap_init_mem_index(dev_ofnode(dev), &plat->base, 1);
717
Emanuele Ghidolifde0dff2024-07-02 21:54:29 +0200718 if (plat->quirks & SDHCI_AM654_QUIRK_FORCE_CDTEST)
719 am654_sdhci_deferred_probe(host);
720
Faiz Abbase4425cb2020-02-26 13:44:34 +0530721 return 0;
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530722}
723
Simon Glassaad29ae2020-12-03 16:55:21 -0700724static int am654_sdhci_of_to_plat(struct udevice *dev)
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530725{
Simon Glassfa20e932020-12-03 16:55:20 -0700726 struct am654_sdhci_plat *plat = dev_get_plat(dev);
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530727 struct sdhci_host *host = dev_get_priv(dev);
Faiz Abbase9aed582019-06-11 00:43:38 +0530728 struct mmc_config *cfg = &plat->cfg;
729 u32 drv_strength;
730 int ret;
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530731
732 host->name = dev->name;
Johan Jonker8d5d8e02023-03-13 01:32:04 +0100733 host->ioaddr = dev_read_addr_ptr(dev);
Faiz Abbase9aed582019-06-11 00:43:38 +0530734 plat->non_removable = dev_read_bool(dev, "non-removable");
735
Faiz Abbasfd8be702019-06-13 10:29:51 +0530736 if (plat->flags & DLL_PRESENT) {
737 ret = dev_read_u32(dev, "ti,trm-icp", &plat->trm_icp);
738 if (ret)
739 return ret;
740
741 ret = dev_read_u32(dev, "ti,driver-strength-ohm",
742 &drv_strength);
743 if (ret)
744 return ret;
Faiz Abbase9aed582019-06-11 00:43:38 +0530745
Faiz Abbasfd8be702019-06-13 10:29:51 +0530746 switch (drv_strength) {
747 case 50:
748 plat->drv_strength = DRIVER_STRENGTH_50_OHM;
749 break;
750 case 33:
751 plat->drv_strength = DRIVER_STRENGTH_33_OHM;
752 break;
753 case 66:
754 plat->drv_strength = DRIVER_STRENGTH_66_OHM;
755 break;
756 case 100:
757 plat->drv_strength = DRIVER_STRENGTH_100_OHM;
758 break;
759 case 40:
760 plat->drv_strength = DRIVER_STRENGTH_40_OHM;
761 break;
762 default:
763 dev_err(dev, "Invalid driver strength\n");
764 return -EINVAL;
765 }
Faiz Abbase9aed582019-06-11 00:43:38 +0530766 }
767
Aswath Govindraju4509fb62021-05-25 15:08:23 +0530768 dev_read_u32(dev, "ti,strobe-sel", &plat->strb_sel);
Faiz Abbasc73f04e2021-02-04 15:10:52 +0530769 dev_read_u32(dev, "ti,clkbuf-sel", &plat->clkbuf_sel);
Emanuele Ghidolifde0dff2024-07-02 21:54:29 +0200770 if (dev_read_bool(dev, "ti,fails-without-test-cd"))
771 plat->quirks |= SDHCI_AM654_QUIRK_FORCE_CDTEST;
Faiz Abbasc73f04e2021-02-04 15:10:52 +0530772
Faiz Abbase9aed582019-06-11 00:43:38 +0530773 ret = mmc_of_parse(dev, cfg);
774 if (ret)
775 return ret;
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530776
777 return 0;
778}
779
Faiz Abbasd8fb3092019-06-11 00:43:31 +0530780static int am654_sdhci_bind(struct udevice *dev)
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530781{
Faiz Abbas8cc051e2020-01-16 19:42:19 +0530782 struct am654_driver_data *drv_data =
783 (struct am654_driver_data *)dev_get_driver_data(dev);
Simon Glassfa20e932020-12-03 16:55:20 -0700784 struct am654_sdhci_plat *plat = dev_get_plat(dev);
Faiz Abbas2c2fc962021-02-04 15:10:50 +0530785 const struct soc_attr *soc;
786 const struct am654_driver_data *soc_drv_data;
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530787
Faiz Abbas8cc051e2020-01-16 19:42:19 +0530788 plat->flags = drv_data->flags;
789
Faiz Abbas2c2fc962021-02-04 15:10:50 +0530790 /* Update flags based on SoC revision */
791 soc = soc_device_match(am654_sdhci_soc_attr);
792 if (soc && soc->data) {
793 soc_drv_data = soc->data;
794 plat->flags = soc_drv_data->flags;
795 }
796
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530797 return sdhci_bind(dev, &plat->mmc, &plat->cfg);
798}
799
Faiz Abbasd8fb3092019-06-11 00:43:31 +0530800static const struct udevice_id am654_sdhci_ids[] = {
Faiz Abbasfd8be702019-06-13 10:29:51 +0530801 {
802 .compatible = "ti,am654-sdhci-5.1",
Faiz Abbas8cc051e2020-01-16 19:42:19 +0530803 .data = (ulong)&am654_drv_data,
Faiz Abbasfd8be702019-06-13 10:29:51 +0530804 },
805 {
806 .compatible = "ti,j721e-sdhci-8bit",
Faiz Abbas8cc051e2020-01-16 19:42:19 +0530807 .data = (ulong)&j721e_8bit_drv_data,
Faiz Abbasfd8be702019-06-13 10:29:51 +0530808 },
809 {
810 .compatible = "ti,j721e-sdhci-4bit",
Faiz Abbas8cc051e2020-01-16 19:42:19 +0530811 .data = (ulong)&j721e_4bit_drv_data,
Faiz Abbasfd8be702019-06-13 10:29:51 +0530812 },
Dave Gerlach057d6af2021-04-23 11:27:40 -0500813 {
814 .compatible = "ti,am64-sdhci-8bit",
815 .data = (ulong)&sdhci_am64_8bit_drvdata,
816 },
817 {
818 .compatible = "ti,am64-sdhci-4bit",
819 .data = (ulong)&sdhci_am64_4bit_drvdata,
820 },
Aswath Govindraju71b9a7b2022-05-25 13:38:39 +0530821 {
822 .compatible = "ti,am62-sdhci",
823 .data = (ulong)&sdhci_am64_4bit_drvdata,
824 },
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530825 { }
826};
827
Faiz Abbasd8fb3092019-06-11 00:43:31 +0530828U_BOOT_DRIVER(am654_sdhci_drv) = {
829 .name = "am654_sdhci",
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530830 .id = UCLASS_MMC,
Faiz Abbasd8fb3092019-06-11 00:43:31 +0530831 .of_match = am654_sdhci_ids,
Simon Glassaad29ae2020-12-03 16:55:21 -0700832 .of_to_plat = am654_sdhci_of_to_plat,
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530833 .ops = &sdhci_ops,
Faiz Abbasd8fb3092019-06-11 00:43:31 +0530834 .bind = am654_sdhci_bind,
835 .probe = am654_sdhci_probe,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700836 .priv_auto = sizeof(struct sdhci_host),
Simon Glass71fa5b42020-12-03 16:55:18 -0700837 .plat_auto = sizeof(struct am654_sdhci_plat),
Lokesh Vutlabc9979f2018-08-27 15:57:54 +0530838};