sunxi: mmc: group non-DM specific functions
[platform/kernel/u-boot.git] / drivers / mmc / am654_sdhci.c
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
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
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
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
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
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
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
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
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
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 static const struct am654_driver_data sdhci_am64_8bit_drvdata = {
474         .ops = &am654_sdhci_ops,
475         .flags = DLL_PRESENT | DLL_CALIB,
476 };
477
478 static const struct am654_driver_data sdhci_am64_4bit_drvdata = {
479         .ops = &j721e_4bit_sdhci_ops,
480         .flags = IOMUX_PRESENT,
481 };
482
483 const struct soc_attr am654_sdhci_soc_attr[] = {
484         { .family = "AM65X", .revision = "SR1.0", .data = &am654_sr1_drv_data},
485         {/* sentinel */}
486 };
487
488 static int sdhci_am654_get_otap_delay(struct udevice *dev,
489                                       struct mmc_config *cfg)
490 {
491         struct am654_sdhci_plat *plat = dev_get_plat(dev);
492         int ret;
493         int i;
494
495         /* ti,otap-del-sel-legacy is mandatory */
496         ret = dev_read_u32(dev, "ti,otap-del-sel-legacy",
497                            &plat->otap_del_sel[0]);
498         if (ret)
499                 return ret;
500         /*
501          * Remove the corresponding capability if an otap-del-sel
502          * value is not found
503          */
504         for (i = MMC_HS; i <= MMC_HS_400; i++) {
505                 ret = dev_read_u32(dev, td[i].otap_binding,
506                                    &plat->otap_del_sel[i]);
507                 if (ret) {
508                         dev_dbg(dev, "Couldn't find %s\n", td[i].otap_binding);
509                         /*
510                          * Remove the corresponding capability
511                          * if an otap-del-sel value is not found
512                          */
513                         cfg->host_caps &= ~td[i].capability;
514                 }
515
516                 if (td[i].itap_binding)
517                         dev_read_u32(dev, td[i].itap_binding,
518                                      &plat->itap_del_sel[i]);
519         }
520
521         return 0;
522 }
523
524 static int am654_sdhci_probe(struct udevice *dev)
525 {
526         struct am654_driver_data *drv_data =
527                         (struct am654_driver_data *)dev_get_driver_data(dev);
528         struct am654_sdhci_plat *plat = dev_get_plat(dev);
529         struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
530         struct sdhci_host *host = dev_get_priv(dev);
531         struct mmc_config *cfg = &plat->cfg;
532         const struct soc_attr *soc;
533         const struct am654_driver_data *soc_drv_data;
534         struct clk clk;
535         unsigned long clock;
536         int ret;
537
538         ret = clk_get_by_name(dev, "clk_xin", &clk);
539         if (ret) {
540                 dev_err(dev, "failed to get clock\n");
541                 return ret;
542         }
543
544         clock = clk_get_rate(&clk);
545         if (IS_ERR_VALUE(clock)) {
546                 dev_err(dev, "failed to get rate\n");
547                 return clock;
548         }
549
550         host->max_clk = clock;
551         host->mmc = &plat->mmc;
552         host->mmc->dev = dev;
553         host->ops = drv_data->ops;
554         ret = sdhci_setup_cfg(cfg, host, cfg->f_max,
555                               AM654_SDHCI_MIN_FREQ);
556         if (ret)
557                 return ret;
558
559         ret = sdhci_am654_get_otap_delay(dev, cfg);
560         if (ret)
561                 return ret;
562
563         /* Update ops based on SoC revision */
564         soc = soc_device_match(am654_sdhci_soc_attr);
565         if (soc && soc->data) {
566                 soc_drv_data = soc->data;
567                 host->ops = soc_drv_data->ops;
568         }
569
570         host->mmc->priv = host;
571         upriv->mmc = host->mmc;
572
573         regmap_init_mem_index(dev_ofnode(dev), &plat->base, 1);
574
575         return 0;
576 }
577
578 static int am654_sdhci_of_to_plat(struct udevice *dev)
579 {
580         struct am654_sdhci_plat *plat = dev_get_plat(dev);
581         struct sdhci_host *host = dev_get_priv(dev);
582         struct mmc_config *cfg = &plat->cfg;
583         u32 drv_strength;
584         int ret;
585
586         host->name = dev->name;
587         host->ioaddr = (void *)dev_read_addr(dev);
588         plat->non_removable = dev_read_bool(dev, "non-removable");
589
590         if (plat->flags & DLL_PRESENT) {
591                 ret = dev_read_u32(dev, "ti,trm-icp", &plat->trm_icp);
592                 if (ret)
593                         return ret;
594
595                 ret = dev_read_u32(dev, "ti,driver-strength-ohm",
596                                    &drv_strength);
597                 if (ret)
598                         return ret;
599
600                 switch (drv_strength) {
601                 case 50:
602                         plat->drv_strength = DRIVER_STRENGTH_50_OHM;
603                         break;
604                 case 33:
605                         plat->drv_strength = DRIVER_STRENGTH_33_OHM;
606                         break;
607                 case 66:
608                         plat->drv_strength = DRIVER_STRENGTH_66_OHM;
609                         break;
610                 case 100:
611                         plat->drv_strength = DRIVER_STRENGTH_100_OHM;
612                         break;
613                 case 40:
614                         plat->drv_strength = DRIVER_STRENGTH_40_OHM;
615                         break;
616                 default:
617                         dev_err(dev, "Invalid driver strength\n");
618                         return -EINVAL;
619                 }
620         }
621
622         dev_read_u32(dev, "ti,strobe-sel", &plat->strb_sel);
623         dev_read_u32(dev, "ti,clkbuf-sel", &plat->clkbuf_sel);
624
625         ret = mmc_of_parse(dev, cfg);
626         if (ret)
627                 return ret;
628
629         return 0;
630 }
631
632 static int am654_sdhci_bind(struct udevice *dev)
633 {
634         struct am654_driver_data *drv_data =
635                         (struct am654_driver_data *)dev_get_driver_data(dev);
636         struct am654_sdhci_plat *plat = dev_get_plat(dev);
637         const struct soc_attr *soc;
638         const struct am654_driver_data *soc_drv_data;
639
640         plat->flags = drv_data->flags;
641
642         /* Update flags based on SoC revision */
643         soc = soc_device_match(am654_sdhci_soc_attr);
644         if (soc && soc->data) {
645                 soc_drv_data = soc->data;
646                 plat->flags = soc_drv_data->flags;
647         }
648
649         return sdhci_bind(dev, &plat->mmc, &plat->cfg);
650 }
651
652 static const struct udevice_id am654_sdhci_ids[] = {
653         {
654                 .compatible = "ti,am654-sdhci-5.1",
655                 .data = (ulong)&am654_drv_data,
656         },
657         {
658                 .compatible = "ti,j721e-sdhci-8bit",
659                 .data = (ulong)&j721e_8bit_drv_data,
660         },
661         {
662                 .compatible = "ti,j721e-sdhci-4bit",
663                 .data = (ulong)&j721e_4bit_drv_data,
664         },
665         {
666                 .compatible = "ti,am64-sdhci-8bit",
667                 .data = (ulong)&sdhci_am64_8bit_drvdata,
668         },
669         {
670                 .compatible = "ti,am64-sdhci-4bit",
671                 .data = (ulong)&sdhci_am64_4bit_drvdata,
672         },
673         {
674                 .compatible = "ti,am62-sdhci",
675                 .data = (ulong)&sdhci_am64_4bit_drvdata,
676         },
677         { }
678 };
679
680 U_BOOT_DRIVER(am654_sdhci_drv) = {
681         .name           = "am654_sdhci",
682         .id             = UCLASS_MMC,
683         .of_match       = am654_sdhci_ids,
684         .of_to_plat = am654_sdhci_of_to_plat,
685         .ops            = &sdhci_ops,
686         .bind           = am654_sdhci_bind,
687         .probe          = am654_sdhci_probe,
688         .priv_auto      = sizeof(struct sdhci_host),
689         .plat_auto      = sizeof(struct am654_sdhci_plat),
690 };