1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
4 *
5 * Texas Instruments' K3 SD Host Controller Interface
6 */
7
8 #include <clk.h>
9 #include <common.h>
10 #include <dm.h>
11 #include <malloc.h>
12 #include <mmc.h>
13 #include <power-domain.h>
14 #include <regmap.h>
15 #include <sdhci.h>
16 #include <soc.h>
17 #include <dm/device_compat.h>
18 #include <linux/bitops.h>
19 #include <linux/err.h>
20
21 /* CTL_CFG Registers */
22 #define CTL_CFG_2 0x14
23
24 #define SLOTTYPE_MASK GENMASK(31, 30)
25 #define SLOTTYPE_EMBEDDED BIT(30)
26
27 /* PHY Registers */
28 #define PHY_CTRL1 0x100
29 #define PHY_CTRL2 0x104
30 #define PHY_CTRL3 0x108
31 #define PHY_CTRL4 0x10C
32 #define PHY_CTRL5 0x110
33 #define PHY_CTRL6 0x114
34 #define PHY_STAT1 0x130
35 #define PHY_STAT2 0x134
36
37 #define IOMUX_ENABLE_SHIFT 31
38 #define IOMUX_ENABLE_MASK BIT(IOMUX_ENABLE_SHIFT)
39 #define OTAPDLYENA_SHIFT 20
40 #define OTAPDLYENA_MASK BIT(OTAPDLYENA_SHIFT)
41 #define OTAPDLYSEL_SHIFT 12
42 #define OTAPDLYSEL_MASK GENMASK(15, 12)
43 #define STRBSEL_SHIFT 24
44 #define STRBSEL_4BIT_MASK GENMASK(27, 24)
45 #define STRBSEL_8BIT_MASK GENMASK(31, 24)
46 #define SEL50_SHIFT 8
47 #define SEL50_MASK BIT(SEL50_SHIFT)
48 #define SEL100_SHIFT 9
49 #define SEL100_MASK BIT(SEL100_SHIFT)
50 #define FREQSEL_SHIFT 8
51 #define FREQSEL_MASK GENMASK(10, 8)
52 #define CLKBUFSEL_SHIFT 0
53 #define CLKBUFSEL_MASK GENMASK(2, 0)
54 #define DLL_TRIM_ICP_SHIFT 4
55 #define DLL_TRIM_ICP_MASK GENMASK(7, 4)
56 #define DR_TY_SHIFT 20
57 #define DR_TY_MASK GENMASK(22, 20)
58 #define ENDLL_SHIFT 1
59 #define ENDLL_MASK BIT(ENDLL_SHIFT)
60 #define DLLRDY_SHIFT 0
61 #define DLLRDY_MASK BIT(DLLRDY_SHIFT)
62 #define PDB_SHIFT 0
63 #define PDB_MASK BIT(PDB_SHIFT)
64 #define CALDONE_SHIFT 1
65 #define CALDONE_MASK BIT(CALDONE_SHIFT)
66 #define RETRIM_SHIFT 17
67 #define RETRIM_MASK BIT(RETRIM_SHIFT)
68 #define SELDLYTXCLK_SHIFT 17
69 #define SELDLYTXCLK_MASK BIT(SELDLYTXCLK_SHIFT)
70 #define SELDLYRXCLK_SHIFT 16
71 #define SELDLYRXCLK_MASK BIT(SELDLYRXCLK_SHIFT)
72 #define ITAPDLYSEL_SHIFT 0
73 #define ITAPDLYSEL_MASK GENMASK(4, 0)
74 #define ITAPDLYENA_SHIFT 8
75 #define ITAPDLYENA_MASK BIT(ITAPDLYENA_SHIFT)
76 #define ITAPCHGWIN_SHIFT 9
77 #define ITAPCHGWIN_MASK BIT(ITAPCHGWIN_SHIFT)
78
79 #define DRIVER_STRENGTH_50_OHM 0x0
80 #define DRIVER_STRENGTH_33_OHM 0x1
81 #define DRIVER_STRENGTH_66_OHM 0x2
82 #define DRIVER_STRENGTH_100_OHM 0x3
83 #define DRIVER_STRENGTH_40_OHM 0x4
84
85 #define AM654_SDHCI_MIN_FREQ 400000
86 #define CLOCK_TOO_SLOW_HZ 50000000
87
88 struct am654_sdhci_plat {
89 struct mmc_config cfg;
90 struct mmc mmc;
91 struct regmap *base;
92 bool non_removable;
93 u32 otap_del_sel[MMC_MODES_END];
94 u32 itap_del_sel[MMC_MODES_END];
95 u32 trm_icp;
96 u32 drv_strength;
97 u32 strb_sel;
98 u32 clkbuf_sel;
99 u32 flags;
100 #define DLL_PRESENT BIT(0)
101 #define IOMUX_PRESENT BIT(1)
102 #define FREQSEL_2_BIT BIT(2)
103 #define STRBSEL_4_BIT BIT(3)
104 #define DLL_CALIB BIT(4)
105 };
106
107 struct timing_data {
108 const char *otap_binding;
109 const char *itap_binding;
110 u32 capability;
111 };
112
113 static const struct timing_data td[] = {
114 [MMC_LEGACY] = {"ti,otap-del-sel-legacy",
115 "ti,itap-del-sel-legacy",
116 0},
117 [MMC_HS] = {"ti,otap-del-sel-mmc-hs",
118 "ti,itap-del-sel-mms-hs",
119 MMC_CAP(MMC_HS)},
120 [SD_HS] = {"ti,otap-del-sel-sd-hs",
121 "ti,itap-del-sel-sd-hs",
122 MMC_CAP(SD_HS)},
123 [UHS_SDR12] = {"ti,otap-del-sel-sdr12",
124 "ti,itap-del-sel-sdr12",
125 MMC_CAP(UHS_SDR12)},
126 [UHS_SDR25] = {"ti,otap-del-sel-sdr25",
127 "ti,itap-del-sel-sdr25",
128 MMC_CAP(UHS_SDR25)},
129 [UHS_SDR50] = {"ti,otap-del-sel-sdr50",
130 NULL,
131 MMC_CAP(UHS_SDR50)},
132 [UHS_SDR104] = {"ti,otap-del-sel-sdr104",
133 NULL,
134 MMC_CAP(UHS_SDR104)},
135 [UHS_DDR50] = {"ti,otap-del-sel-ddr50",
136 NULL,
137 MMC_CAP(UHS_DDR50)},
138 [MMC_DDR_52] = {"ti,otap-del-sel-ddr52",
139 "ti,itap-del-sel-ddr52",
140 MMC_CAP(MMC_DDR_52)},
141 [MMC_HS_200] = {"ti,otap-del-sel-hs200",
142 NULL,
143 MMC_CAP(MMC_HS_200)},
144 [MMC_HS_400] = {"ti,otap-del-sel-hs400",
145 NULL,
146 MMC_CAP(MMC_HS_400)},
147 };
148
149 struct am654_driver_data {
150 const struct sdhci_ops *ops;
151 u32 flags;
152 };
153
am654_sdhci_setup_dll(struct am654_sdhci_plat * plat,unsigned int speed)154 static int am654_sdhci_setup_dll(struct am654_sdhci_plat *plat,
155 unsigned int speed)
156 {
157 int sel50, sel100, freqsel;
158 u32 mask, val;
159 int ret;
160
161 /* Disable delay chain mode */
162 regmap_update_bits(plat->base, PHY_CTRL5,
163 SELDLYTXCLK_MASK | SELDLYRXCLK_MASK, 0);
164
165 if (plat->flags & FREQSEL_2_BIT) {
166 switch (speed) {
167 case 200000000:
168 sel50 = 0;
169 sel100 = 0;
170 break;
171 case 100000000:
172 sel50 = 0;
173 sel100 = 1;
174 break;
175 default:
176 sel50 = 1;
177 sel100 = 0;
178 }
179
180 /* Configure PHY DLL frequency */
181 mask = SEL50_MASK | SEL100_MASK;
182 val = (sel50 << SEL50_SHIFT) | (sel100 << SEL100_SHIFT);
183 regmap_update_bits(plat->base, PHY_CTRL5, mask, val);
184 } else {
185 switch (speed) {
186 case 200000000:
187 freqsel = 0x0;
188 break;
189 default:
190 freqsel = 0x4;
191 }
192 regmap_update_bits(plat->base, PHY_CTRL5, FREQSEL_MASK,
193 freqsel << FREQSEL_SHIFT);
194 }
195
196 /* Configure DLL TRIM */
197 mask = DLL_TRIM_ICP_MASK;
198 val = plat->trm_icp << DLL_TRIM_ICP_SHIFT;
199
200 /* Configure DLL driver strength */
201 mask |= DR_TY_MASK;
202 val |= plat->drv_strength << DR_TY_SHIFT;
203 regmap_update_bits(plat->base, PHY_CTRL1, mask, val);
204
205 /* Enable DLL */
206 regmap_update_bits(plat->base, PHY_CTRL1, ENDLL_MASK,
207 0x1 << ENDLL_SHIFT);
208 /*
209 * Poll for DLL ready. Use a one second timeout.
210 * Works in all experiments done so far
211 */
212 ret = regmap_read_poll_timeout(plat->base, PHY_STAT1, val,
213 val & DLLRDY_MASK, 1000, 1000000);
214
215 return ret;
216 }
217
am654_sdhci_write_itapdly(struct am654_sdhci_plat * plat,u32 itapdly)218 static void am654_sdhci_write_itapdly(struct am654_sdhci_plat *plat,
219 u32 itapdly)
220 {
221 /* Set ITAPCHGWIN before writing to ITAPDLY */
222 regmap_update_bits(plat->base, PHY_CTRL4, ITAPCHGWIN_MASK,
223 1 << ITAPCHGWIN_SHIFT);
224 regmap_update_bits(plat->base, PHY_CTRL4, ITAPDLYSEL_MASK,
225 itapdly << ITAPDLYSEL_SHIFT);
226 regmap_update_bits(plat->base, PHY_CTRL4, ITAPCHGWIN_MASK, 0);
227 }
228
am654_sdhci_setup_delay_chain(struct am654_sdhci_plat * plat,int mode)229 static void am654_sdhci_setup_delay_chain(struct am654_sdhci_plat *plat,
230 int mode)
231 {
232 u32 mask, val;
233
234 val = 1 << SELDLYTXCLK_SHIFT | 1 << SELDLYRXCLK_SHIFT;
235 mask = SELDLYTXCLK_MASK | SELDLYRXCLK_MASK;
236 regmap_update_bits(plat->base, PHY_CTRL5, mask, val);
237
238 am654_sdhci_write_itapdly(plat, plat->itap_del_sel[mode]);
239 }
240
am654_sdhci_set_ios_post(struct sdhci_host * host)241 static int am654_sdhci_set_ios_post(struct sdhci_host *host)
242 {
243 struct udevice *dev = host->mmc->dev;
244 struct am654_sdhci_plat *plat = dev_get_plat(dev);
245 unsigned int speed = host->mmc->clock;
246 int mode = host->mmc->selected_mode;
247 u32 otap_del_sel;
248 u32 mask, val;
249 int ret;
250
251 /* Reset SD Clock Enable */
252 val = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
253 val &= ~SDHCI_CLOCK_CARD_EN;
254 sdhci_writew(host, val, SDHCI_CLOCK_CONTROL);
255
256 regmap_update_bits(plat->base, PHY_CTRL1, ENDLL_MASK, 0);
257
258 /* restart clock */
259 sdhci_set_clock(host->mmc, speed);
260
261 /* switch phy back on */
262 otap_del_sel = plat->otap_del_sel[mode];
263 mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
264 val = (1 << OTAPDLYENA_SHIFT) |
265 (otap_del_sel << OTAPDLYSEL_SHIFT);
266
267 /* Write to STRBSEL for HS400 speed mode */
268 if (host->mmc->selected_mode == MMC_HS_400) {
269 if (plat->flags & STRBSEL_4_BIT)
270 mask |= STRBSEL_4BIT_MASK;
271 else
272 mask |= STRBSEL_8BIT_MASK;
273
274 val |= plat->strb_sel << STRBSEL_SHIFT;
275 }
276
277 regmap_update_bits(plat->base, PHY_CTRL4, mask, val);
278
279 if (mode > UHS_SDR25 && speed >= CLOCK_TOO_SLOW_HZ) {
280 ret = am654_sdhci_setup_dll(plat, speed);
281 if (ret)
282 return ret;
283 } else {
284 am654_sdhci_setup_delay_chain(plat, mode);
285 }
286
287 regmap_update_bits(plat->base, PHY_CTRL5, CLKBUFSEL_MASK,
288 plat->clkbuf_sel);
289
290 return 0;
291 }
292
am654_sdhci_init(struct am654_sdhci_plat * plat)293 int am654_sdhci_init(struct am654_sdhci_plat *plat)
294 {
295 u32 ctl_cfg_2 = 0;
296 u32 mask, val;
297 int ret;
298
299 /* Reset OTAP to default value */
300 mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
301 regmap_update_bits(plat->base, PHY_CTRL4, mask, 0x0);
302
303 if (plat->flags & DLL_CALIB) {
304 regmap_read(plat->base, PHY_STAT1, &val);
305 if (~val & CALDONE_MASK) {
306 /* Calibrate IO lines */
307 regmap_update_bits(plat->base, PHY_CTRL1, PDB_MASK,
308 PDB_MASK);
309 ret = regmap_read_poll_timeout(plat->base, PHY_STAT1,
310 val, val & CALDONE_MASK,
311 1, 20);
312 if (ret)
313 return ret;
314 }
315 }
316
317 /* Enable pins by setting IO mux to 0 */
318 if (plat->flags & IOMUX_PRESENT)
319 regmap_update_bits(plat->base, PHY_CTRL1, IOMUX_ENABLE_MASK, 0);
320
321 /* Set slot type based on SD or eMMC */
322 if (plat->non_removable)
323 ctl_cfg_2 = SLOTTYPE_EMBEDDED;
324
325 regmap_update_bits(plat->base, CTL_CFG_2, SLOTTYPE_MASK, ctl_cfg_2);
326
327 return 0;
328 }
329
330 #define MAX_SDCD_DEBOUNCE_TIME 2000
am654_sdhci_deferred_probe(struct sdhci_host * host)331 static int am654_sdhci_deferred_probe(struct sdhci_host *host)
332 {
333 struct udevice *dev = host->mmc->dev;
334 struct am654_sdhci_plat *plat = dev_get_plat(dev);
335 unsigned long start;
336 int val;
337
338 /*
339 * The controller takes about 1 second to debounce the card detect line
340 * and doesn't let us power on until that time is up. Instead of waiting
341 * for 1 second at every stage, poll on the CARD_PRESENT bit upto a
342 * maximum of 2 seconds to be safe..
343 */
344 start = get_timer(0);
345 do {
346 if (get_timer(start) > MAX_SDCD_DEBOUNCE_TIME)
347 return -ENOMEDIUM;
348
349 val = mmc_getcd(host->mmc);
350 } while (!val);
351
352 am654_sdhci_init(plat);
353
354 return sdhci_probe(dev);
355 }
356
am654_sdhci_write_b(struct sdhci_host * host,u8 val,int reg)357 static void am654_sdhci_write_b(struct sdhci_host *host, u8 val, int reg)
358 {
359 if (reg == SDHCI_HOST_CONTROL) {
360 switch (host->mmc->selected_mode) {
361 /*
362 * According to the data manual, HISPD bit
363 * should not be set in these speed modes.
364 */
365 case SD_HS:
366 case MMC_HS:
367 case UHS_SDR12:
368 case UHS_SDR25:
369 val &= ~SDHCI_CTRL_HISPD;
370 default:
371 break;
372 }
373 }
374
375 writeb(val, host->ioaddr + reg);
376 }
377 #ifdef MMC_SUPPORTS_TUNING
378 #define ITAP_MAX 32
am654_sdhci_execute_tuning(struct mmc * mmc,u8 opcode)379 static int am654_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
380 {
381 struct udevice *dev = mmc->dev;
382 struct am654_sdhci_plat *plat = dev_get_plat(dev);
383 int cur_val, prev_val = 1, fail_len = 0, pass_window = 0, pass_len;
384 u32 itap;
385
386 /* Enable ITAPDLY */
387 regmap_update_bits(plat->base, PHY_CTRL4, ITAPDLYENA_MASK,
388 1 << ITAPDLYENA_SHIFT);
389
390 for (itap = 0; itap < ITAP_MAX; itap++) {
391 am654_sdhci_write_itapdly(plat, itap);
392
393 cur_val = !mmc_send_tuning(mmc, opcode, NULL);
394 if (cur_val && !prev_val)
395 pass_window = itap;
396
397 if (!cur_val)
398 fail_len++;
399
400 prev_val = cur_val;
401 }
402 /*
403 * Having determined the length of the failing window and start of
404 * the passing window calculate the length of the passing window and
405 * set the final value halfway through it considering the range as a
406 * circular buffer
407 */
408 pass_len = ITAP_MAX - fail_len;
409 itap = (pass_window + (pass_len >> 1)) % ITAP_MAX;
410 am654_sdhci_write_itapdly(plat, itap);
411
412 return 0;
413 }
414 #endif
415 const struct sdhci_ops am654_sdhci_ops = {
416 #ifdef MMC_SUPPORTS_TUNING
417 .platform_execute_tuning = am654_sdhci_execute_tuning,
418 #endif
419 .deferred_probe = am654_sdhci_deferred_probe,
420 .set_ios_post = &am654_sdhci_set_ios_post,
421 .set_control_reg = sdhci_set_control_reg,
422 .write_b = am654_sdhci_write_b,
423 };
424
425 const struct am654_driver_data am654_drv_data = {
426 .ops = &am654_sdhci_ops,
427 .flags = DLL_PRESENT | IOMUX_PRESENT | FREQSEL_2_BIT | STRBSEL_4_BIT,
428 };
429
430 const struct am654_driver_data am654_sr1_drv_data = {
431 .ops = &am654_sdhci_ops,
432 .flags = IOMUX_PRESENT | FREQSEL_2_BIT | DLL_PRESENT | DLL_CALIB |
433 STRBSEL_4_BIT,
434 };
435
436 const struct am654_driver_data j721e_8bit_drv_data = {
437 .ops = &am654_sdhci_ops,
438 .flags = DLL_PRESENT | DLL_CALIB,
439 };
440
j721e_4bit_sdhci_set_ios_post(struct sdhci_host * host)441 static int j721e_4bit_sdhci_set_ios_post(struct sdhci_host *host)
442 {
443 struct udevice *dev = host->mmc->dev;
444 struct am654_sdhci_plat *plat = dev_get_plat(dev);
445 u32 otap_del_sel, mask, val;
446
447 otap_del_sel = plat->otap_del_sel[host->mmc->selected_mode];
448 mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
449 val = (1 << OTAPDLYENA_SHIFT) | (otap_del_sel << OTAPDLYSEL_SHIFT);
450 regmap_update_bits(plat->base, PHY_CTRL4, mask, val);
451
452 regmap_update_bits(plat->base, PHY_CTRL5, CLKBUFSEL_MASK,
453 plat->clkbuf_sel);
454
455 return 0;
456 }
457
458 const struct sdhci_ops j721e_4bit_sdhci_ops = {
459 #ifdef MMC_SUPPORTS_TUNING
460 .platform_execute_tuning = am654_sdhci_execute_tuning,
461 #endif
462 .deferred_probe = am654_sdhci_deferred_probe,
463 .set_ios_post = &j721e_4bit_sdhci_set_ios_post,
464 .set_control_reg = sdhci_set_control_reg,
465 .write_b = am654_sdhci_write_b,
466 };
467
468 const struct am654_driver_data j721e_4bit_drv_data = {
469 .ops = &j721e_4bit_sdhci_ops,
470 .flags = IOMUX_PRESENT,
471 };
472
473 const struct soc_attr am654_sdhci_soc_attr[] = {
474 { .family = "AM65X", .revision = "SR1.0", .data = &am654_sr1_drv_data},
475 {/* sentinel */}
476 };
477
sdhci_am654_get_otap_delay(struct udevice * dev,struct mmc_config * cfg)478 static int sdhci_am654_get_otap_delay(struct udevice *dev,
479 struct mmc_config *cfg)
480 {
481 struct am654_sdhci_plat *plat = dev_get_plat(dev);
482 int ret;
483 int i;
484
485 /* ti,otap-del-sel-legacy is mandatory */
486 ret = dev_read_u32(dev, "ti,otap-del-sel-legacy",
487 &plat->otap_del_sel[0]);
488 if (ret)
489 return ret;
490 /*
491 * Remove the corresponding capability if an otap-del-sel
492 * value is not found
493 */
494 for (i = MMC_HS; i <= MMC_HS_400; i++) {
495 ret = dev_read_u32(dev, td[i].otap_binding,
496 &plat->otap_del_sel[i]);
497 if (ret) {
498 dev_dbg(dev, "Couldn't find %s\n", td[i].otap_binding);
499 /*
500 * Remove the corresponding capability
501 * if an otap-del-sel value is not found
502 */
503 cfg->host_caps &= ~td[i].capability;
504 }
505
506 if (td[i].itap_binding)
507 dev_read_u32(dev, td[i].itap_binding,
508 &plat->itap_del_sel[i]);
509 }
510
511 return 0;
512 }
513
am654_sdhci_probe(struct udevice * dev)514 static int am654_sdhci_probe(struct udevice *dev)
515 {
516 struct am654_driver_data *drv_data =
517 (struct am654_driver_data *)dev_get_driver_data(dev);
518 struct am654_sdhci_plat *plat = dev_get_plat(dev);
519 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
520 struct sdhci_host *host = dev_get_priv(dev);
521 struct mmc_config *cfg = &plat->cfg;
522 const struct soc_attr *soc;
523 const struct am654_driver_data *soc_drv_data;
524 struct clk clk;
525 unsigned long clock;
526 int ret;
527
528 ret = clk_get_by_name(dev, "clk_xin", &clk);
529 if (ret) {
530 dev_err(dev, "failed to get clock\n");
531 return ret;
532 }
533
534 clock = clk_get_rate(&clk);
535 if (IS_ERR_VALUE(clock)) {
536 dev_err(dev, "failed to get rate\n");
537 return clock;
538 }
539
540 host->max_clk = clock;
541 host->mmc = &plat->mmc;
542 host->mmc->dev = dev;
543 host->ops = drv_data->ops;
544 ret = sdhci_setup_cfg(cfg, host, cfg->f_max,
545 AM654_SDHCI_MIN_FREQ);
546 if (ret)
547 return ret;
548
549 ret = sdhci_am654_get_otap_delay(dev, cfg);
550 if (ret)
551 return ret;
552
553 /* Update ops based on SoC revision */
554 soc = soc_device_match(am654_sdhci_soc_attr);
555 if (soc && soc->data) {
556 soc_drv_data = soc->data;
557 host->ops = soc_drv_data->ops;
558 }
559
560 host->mmc->priv = host;
561 upriv->mmc = host->mmc;
562
563 regmap_init_mem_index(dev_ofnode(dev), &plat->base, 1);
564
565 return 0;
566 }
567
am654_sdhci_of_to_plat(struct udevice * dev)568 static int am654_sdhci_of_to_plat(struct udevice *dev)
569 {
570 struct am654_sdhci_plat *plat = dev_get_plat(dev);
571 struct sdhci_host *host = dev_get_priv(dev);
572 struct mmc_config *cfg = &plat->cfg;
573 u32 drv_strength;
574 int ret;
575
576 host->name = dev->name;
577 host->ioaddr = (void *)dev_read_addr(dev);
578 plat->non_removable = dev_read_bool(dev, "non-removable");
579
580 if (plat->flags & DLL_PRESENT) {
581 ret = dev_read_u32(dev, "ti,trm-icp", &plat->trm_icp);
582 if (ret)
583 return ret;
584
585 ret = dev_read_u32(dev, "ti,driver-strength-ohm",
586 &drv_strength);
587 if (ret)
588 return ret;
589
590 switch (drv_strength) {
591 case 50:
592 plat->drv_strength = DRIVER_STRENGTH_50_OHM;
593 break;
594 case 33:
595 plat->drv_strength = DRIVER_STRENGTH_33_OHM;
596 break;
597 case 66:
598 plat->drv_strength = DRIVER_STRENGTH_66_OHM;
599 break;
600 case 100:
601 plat->drv_strength = DRIVER_STRENGTH_100_OHM;
602 break;
603 case 40:
604 plat->drv_strength = DRIVER_STRENGTH_40_OHM;
605 break;
606 default:
607 dev_err(dev, "Invalid driver strength\n");
608 return -EINVAL;
609 }
610 }
611
612 dev_read_u32(dev, "ti,clkbuf-sel", &plat->clkbuf_sel);
613
614 ret = mmc_of_parse(dev, cfg);
615 if (ret)
616 return ret;
617
618 return 0;
619 }
620
am654_sdhci_bind(struct udevice * dev)621 static int am654_sdhci_bind(struct udevice *dev)
622 {
623 struct am654_driver_data *drv_data =
624 (struct am654_driver_data *)dev_get_driver_data(dev);
625 struct am654_sdhci_plat *plat = dev_get_plat(dev);
626 const struct soc_attr *soc;
627 const struct am654_driver_data *soc_drv_data;
628
629 plat->flags = drv_data->flags;
630
631 /* Update flags based on SoC revision */
632 soc = soc_device_match(am654_sdhci_soc_attr);
633 if (soc && soc->data) {
634 soc_drv_data = soc->data;
635 plat->flags = soc_drv_data->flags;
636 }
637
638 return sdhci_bind(dev, &plat->mmc, &plat->cfg);
639 }
640
641 static const struct udevice_id am654_sdhci_ids[] = {
642 {
643 .compatible = "ti,am654-sdhci-5.1",
644 .data = (ulong)&am654_drv_data,
645 },
646 {
647 .compatible = "ti,j721e-sdhci-8bit",
648 .data = (ulong)&j721e_8bit_drv_data,
649 },
650 {
651 .compatible = "ti,j721e-sdhci-4bit",
652 .data = (ulong)&j721e_4bit_drv_data,
653 },
654 { }
655 };
656
657 U_BOOT_DRIVER(am654_sdhci_drv) = {
658 .name = "am654_sdhci",
659 .id = UCLASS_MMC,
660 .of_match = am654_sdhci_ids,
661 .of_to_plat = am654_sdhci_of_to_plat,
662 .ops = &sdhci_ops,
663 .bind = am654_sdhci_bind,
664 .probe = am654_sdhci_probe,
665 .priv_auto = sizeof(struct sdhci_host),
666 .plat_auto = sizeof(struct am654_sdhci_plat),
667 };
668