1 /*
2 * (C) Copyright 2016 Fuzhou Rockchip Electronics Co., Ltd
3 *
4 * Rockchip SD Host Controller Interface
5 *
6 * SPDX-License-Identifier: GPL-2.0+
7 */
8
9 #include <asm/arch/hardware.h>
10 #include <common.h>
11 #include <dm.h>
12 #include <dt-structs.h>
13 #include <linux/libfdt.h>
14 #include <malloc.h>
15 #include <mapmem.h>
16 #include <sdhci.h>
17 #include <clk.h>
18 #include <syscon.h>
19 #include <dm/ofnode.h>
20 #include <asm/arch/clock.h>
21
22 DECLARE_GLOBAL_DATA_PTR;
23 /* 400KHz is max freq for card ID etc. Use that as min */
24 #define EMMC_MIN_FREQ 400000
25 #define KHz (1000)
26 #define MHz (1000 * KHz)
27
28 #define PHYCTRL_CALDONE_MASK 0x1
29 #define PHYCTRL_CALDONE_SHIFT 0x6
30 #define PHYCTRL_CALDONE_DONE 0x1
31 #define PHYCTRL_DLLRDY_MASK 0x1
32 #define PHYCTRL_DLLRDY_SHIFT 0x5
33 #define PHYCTRL_DLLRDY_DONE 0x1
34 #define PHYCTRL_FREQSEL_200M 0x0
35 #define PHYCTRL_FREQSEL_50M 0x1
36 #define PHYCTRL_FREQSEL_100M 0x2
37 #define PHYCTRL_FREQSEL_150M 0x3
38 #define PHYCTRL_DLL_LOCK_WO_TMOUT(x) \
39 ((((x) >> PHYCTRL_DLLRDY_SHIFT) & PHYCTRL_DLLRDY_MASK) ==\
40 PHYCTRL_DLLRDY_DONE)
41
42 #define ARASAN_VENDOR_REGISTER 0x78
43 #define ARASAN_VENDOR_ENHANCED_STROBE BIT(0)
44
45 /* DWC IP vendor area 1 pointer */
46 #define DWCMSHC_P_VENDOR_AREA1 0xe8
47 #define DWCMSHC_AREA1_MASK GENMASK(11, 0)
48 /* Rockchip specific Registers */
49 #define DWCMSHC_CTRL_HS400 0x7
50 #define DWCMSHC_CARD_IS_EMMC BIT(0)
51 #define DWCMSHC_ENHANCED_STROBE BIT(8)
52
53 #define DWCMSHC_HOST_CTRL3 0x508
54 #define DWCMSHC_EMMC_CONTROL 0x52c
55 #define DWCMSHC_EMMC_ATCTRL 0x540
56 #define DWCMSHC_EMMC_DLL_CTRL 0x800
57 #define DWCMSHC_EMMC_DLL_CTRL_RESET BIT(1)
58 #define DWCMSHC_EMMC_DLL_RXCLK 0x804
59 #define DWCMSHC_EMMC_DLL_TXCLK 0x808
60 #define DWCMSHC_EMMC_DLL_STRBIN 0x80c
61 #define DECMSHC_EMMC_DLL_CMDOUT 0x810
62 #define DWCMSHC_EMMC_DLL_STATUS0 0x840
63 #define DWCMSHC_EMMC_DLL_STATUS1 0x844
64 #define DWCMSHC_EMMC_DLL_START BIT(0)
65 #define DWCMSHC_EMMC_DLL_START_POINT 16
66 #define DWCMSHC_EMMC_DLL_START_DEFAULT 5
67 #define DWCMSHC_EMMC_DLL_INC_VALUE 2
68 #define DWCMSHC_EMMC_DLL_INC 8
69 #define DWCMSHC_EMMC_DLL_BYPASS BIT(24)
70 #define DWCMSHC_EMMC_DLL_DLYENA BIT(27)
71 #define DLL_TXCLK_TAPNUM_DEFAULT 0x10
72 #define DLL_TXCLK_TAPNUM_90_DEGREES 0x9
73 #define DLL_STRBIN_TAPNUM_DEFAULT 0x4
74 #define DLL_STRBIN_DELAY_NUM_OFFSET 16
75 #define DLL_STRBIN_TAPNUM_FROM_SW BIT(24)
76 #define DLL_STRBIN_DELAY_NUM_SEL BIT(26)
77 #define DLL_TXCLK_TAPNUM_FROM_SW BIT(24)
78 #define DLL_TXCLK_NO_INVERTER BIT(29)
79 #define DWCMSHC_EMMC_DLL_LOCKED BIT(8)
80 #define DWCMSHC_EMMC_DLL_TIMEOUT BIT(9)
81 #define DLL_TAP_VALUE_SEL BIT(25)
82 #define DLL_TAP_VALUE_OFFSET 8
83 #define DLL_RXCLK_NO_INVERTER BIT(29)
84 #define DLL_RXCLK_ORI_GATE BIT(31)
85 #define DLL_CMDOUT_TAPNUM_90_DEGREES 0x8
86 #define DLL_CMDOUT_TAPNUM_FROM_SW BIT(24)
87 #define DLL_CMDOUT_SRC_CLK_NEG BIT(28)
88 #define DLL_CMDOUT_EN_SRC_CLK_NEG BIT(29)
89 #define DLL_CMDOUT_BOTH_CLK_EDGE BIT(30)
90
91 #define DWCMSHC_ENHANCED_STROBE BIT(8)
92 #define DLL_LOCK_WO_TMOUT(x) \
93 ((((x) & DWCMSHC_EMMC_DLL_LOCKED) == DWCMSHC_EMMC_DLL_LOCKED) && \
94 (((x) & DWCMSHC_EMMC_DLL_TIMEOUT) == 0))
95 #define ROCKCHIP_MAX_CLKS 3
96
97 struct rockchip_sdhc_plat {
98 #if CONFIG_IS_ENABLED(OF_PLATDATA)
99 struct dtd_rockchip_rk3399_sdhci_5_1 dtplat;
100 #endif
101 struct mmc_config cfg;
102 struct mmc mmc;
103 };
104
105 struct rockchip_emmc_phy {
106 u32 emmcphy_con[7];
107 u32 reserved;
108 u32 emmcphy_status;
109 };
110
111 struct rockchip_sdhc {
112 struct sdhci_host host;
113 struct udevice *dev;
114 void *base;
115 struct rockchip_emmc_phy *phy;
116 struct clk emmc_clk;
117 };
118
119 struct sdhci_data {
120 int (*emmc_set_clock)(struct sdhci_host *host, unsigned int clock);
121 void (*set_ios_post)(struct sdhci_host *host);
122 int (*set_enhanced_strobe)(struct sdhci_host *host);
123 int (*get_phy)(struct udevice *dev);
124 u32 flags;
125 #define RK_DLL_CMD_OUT BIT(1)
126 #define RK_RXCLK_NO_INVERTER BIT(2)
127 #define RK_TAP_VALUE_SEL BIT(3)
128
129 u8 hs200_tx_tap;
130 u8 hs400_tx_tap;
131 u8 hs400_cmd_tap;
132 u8 hs400_strbin_tap;
133 u8 ddr50_strbin_delay_num;
134 };
135
rk3399_emmc_phy_power_on(struct rockchip_emmc_phy * phy,u32 clock)136 static void rk3399_emmc_phy_power_on(struct rockchip_emmc_phy *phy, u32 clock)
137 {
138 u32 caldone, dllrdy, freqsel;
139 uint start;
140
141 writel(RK_CLRSETBITS(7 << 4, 0), &phy->emmcphy_con[6]);
142 writel(RK_CLRSETBITS(1 << 11, 1 << 11), &phy->emmcphy_con[0]);
143 writel(RK_CLRSETBITS(0xf << 7, 6 << 7), &phy->emmcphy_con[0]);
144
145 /*
146 * According to the user manual, calpad calibration
147 * cycle takes more than 2us without the minimal recommended
148 * value, so we may need a little margin here
149 */
150 udelay(3);
151 writel(RK_CLRSETBITS(1, 1), &phy->emmcphy_con[6]);
152
153 /*
154 * According to the user manual, it asks driver to
155 * wait 5us for calpad busy trimming. But it seems that
156 * 5us of caldone isn't enough for all cases.
157 */
158 udelay(500);
159 caldone = readl(&phy->emmcphy_status);
160 caldone = (caldone >> PHYCTRL_CALDONE_SHIFT) & PHYCTRL_CALDONE_MASK;
161 if (caldone != PHYCTRL_CALDONE_DONE) {
162 printf("%s: caldone timeout.\n", __func__);
163 return;
164 }
165
166 /* Set the frequency of the DLL operation */
167 if (clock < 75 * MHz)
168 freqsel = PHYCTRL_FREQSEL_50M;
169 else if (clock < 125 * MHz)
170 freqsel = PHYCTRL_FREQSEL_100M;
171 else if (clock < 175 * MHz)
172 freqsel = PHYCTRL_FREQSEL_150M;
173 else
174 freqsel = PHYCTRL_FREQSEL_200M;
175
176 /* Set the frequency of the DLL operation */
177 writel(RK_CLRSETBITS(3 << 12, freqsel << 12), &phy->emmcphy_con[0]);
178 writel(RK_CLRSETBITS(1 << 1, 1 << 1), &phy->emmcphy_con[6]);
179
180 /* REN Enable on STRB Line for HS400 */
181 writel(RK_CLRSETBITS(0, 1 << 9), &phy->emmcphy_con[2]);
182
183 start = get_timer(0);
184
185 do {
186 udelay(1);
187 dllrdy = readl(&phy->emmcphy_status);
188 dllrdy = (dllrdy >> PHYCTRL_DLLRDY_SHIFT) & PHYCTRL_DLLRDY_MASK;
189 if (dllrdy == PHYCTRL_DLLRDY_DONE)
190 break;
191 } while (get_timer(start) < 50000);
192
193 if (dllrdy != PHYCTRL_DLLRDY_DONE)
194 printf("%s: dllrdy timeout.\n", __func__);
195 }
196
rk3399_emmc_phy_power_off(struct rockchip_emmc_phy * phy)197 static void rk3399_emmc_phy_power_off(struct rockchip_emmc_phy *phy)
198 {
199 writel(RK_CLRSETBITS(1, 0), &phy->emmcphy_con[6]);
200 writel(RK_CLRSETBITS(1 << 1, 0), &phy->emmcphy_con[6]);
201 }
202
rockchip_emmc_set_clock(struct sdhci_host * host,unsigned int clock)203 static int rockchip_emmc_set_clock(struct sdhci_host *host, unsigned int clock)
204 {
205 unsigned int div, clk = 0, timeout;
206 unsigned int input_clk;
207 struct rockchip_sdhc *priv =
208 container_of(host, struct rockchip_sdhc, host);
209
210 /* Wait max 20 ms */
211 timeout = 200;
212 while (sdhci_readl(host, SDHCI_PRESENT_STATE) &
213 (SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT)) {
214 if (timeout == 0) {
215 printf("%s: Timeout to wait cmd & data inhibit\n",
216 __func__);
217 return -EBUSY;
218 }
219
220 timeout--;
221 udelay(100);
222 }
223 sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
224
225 if (clock == 0)
226 return 0;
227
228 input_clk = clk_set_rate(&priv->emmc_clk, clock);
229 if (IS_ERR_VALUE(input_clk))
230 input_clk = host->max_clk;
231
232 if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
233 /*
234 * Check if the Host Controller supports Programmable Clock
235 * Mode.
236 */
237 if (host->clk_mul) {
238 for (div = 1; div <= 1024; div++) {
239 if ((input_clk / div) <= clock)
240 break;
241 }
242
243 /*
244 * Set Programmable Clock Mode in the Clock
245 * Control register.
246 */
247 clk = SDHCI_PROG_CLOCK_MODE;
248 div--;
249 } else {
250 /* Version 3.00 divisors must be a multiple of 2. */
251 if (input_clk <= clock) {
252 div = 1;
253 } else {
254 for (div = 2;
255 div < SDHCI_MAX_DIV_SPEC_300;
256 div += 2) {
257 if ((input_clk / div) <= clock)
258 break;
259 }
260 }
261 div >>= 1;
262 }
263 } else {
264 /* Version 2.00 divisors must be a power of 2. */
265 for (div = 1; div < SDHCI_MAX_DIV_SPEC_200; div *= 2) {
266 if ((input_clk / div) <= clock)
267 break;
268 }
269 div >>= 1;
270 }
271
272 clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
273 clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
274 << SDHCI_DIVIDER_HI_SHIFT;
275 clk |= SDHCI_CLOCK_INT_EN;
276 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
277
278 sdhci_enable_clk(host, clk);
279
280 return 0;
281 }
282
rk3399_emmc_get_phy(struct udevice * dev)283 static int rk3399_emmc_get_phy(struct udevice *dev)
284 {
285 struct rockchip_sdhc *priv = dev_get_priv(dev);
286
287 #if CONFIG_IS_ENABLED(OF_PLATDATA)
288 priv->phy = (struct rockchip_emmc_phy *)0xff77f780;
289 #else
290 ofnode phy_node;
291 void *grf_base;
292 u32 grf_phy_offset, phandle;
293
294 phandle = dev_read_u32_default(dev, "phys", 0);
295 phy_node = ofnode_get_by_phandle(phandle);
296 if (!ofnode_valid(phy_node)) {
297 debug("Not found emmc phy device\n");
298 return -ENODEV;
299 }
300
301 grf_base = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
302 if (IS_ERR(grf_base))
303 printf("%s Get syscon grf failed", __func__);
304 grf_phy_offset = ofnode_read_u32_default(phy_node, "reg", 0);
305
306 priv->phy = (struct rockchip_emmc_phy *)(grf_base + grf_phy_offset);
307 #endif
308 return 0;
309 }
310
rk3399_sdhci_emmc_set_clock(struct sdhci_host * host,unsigned int clock)311 static int rk3399_sdhci_emmc_set_clock(struct sdhci_host *host, unsigned int clock)
312 {
313 struct rockchip_sdhc *priv =
314 container_of(host, struct rockchip_sdhc, host);
315 int cycle_phy = host->clock != clock &&
316 clock > EMMC_MIN_FREQ;
317
318 if (cycle_phy)
319 rk3399_emmc_phy_power_off(priv->phy);
320
321 rockchip_emmc_set_clock(host, clock);
322
323 if (cycle_phy)
324 rk3399_emmc_phy_power_on(priv->phy, clock);
325
326 return 0;
327 }
328
dwcmshc_sdhci_emmc_set_clock(struct sdhci_host * host,unsigned int clock)329 static int dwcmshc_sdhci_emmc_set_clock(struct sdhci_host *host, unsigned int clock)
330 {
331 struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
332 struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
333 u32 txclk_tapnum, extra, dll_lock_value;
334 int timeout = 500, ret;
335
336 ret = rockchip_emmc_set_clock(host, clock);
337
338 /* Disable output clock while config DLL */
339 sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
340
341 if (clock >= 100 * MHz) {
342 /* reset DLL */
343 sdhci_writel(host, DWCMSHC_EMMC_DLL_CTRL_RESET, DWCMSHC_EMMC_DLL_CTRL);
344 udelay(1);
345 sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_CTRL);
346
347 extra = 0x1 << 16 | /* tune clock stop en */
348 0x2 << 17 | /* pre-change delay */
349 0x3 << 19; /* post-change delay */
350 sdhci_writel(host, extra, DWCMSHC_EMMC_ATCTRL);
351
352 /* Init DLL settings */
353 extra = DWCMSHC_EMMC_DLL_START_DEFAULT << DWCMSHC_EMMC_DLL_START_POINT |
354 DWCMSHC_EMMC_DLL_INC_VALUE << DWCMSHC_EMMC_DLL_INC |
355 DWCMSHC_EMMC_DLL_START;
356 sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_CTRL);
357
358 while (1) {
359 if (timeout < 0) {
360 ret = -ETIMEDOUT;
361 goto exit;
362 }
363 if (DLL_LOCK_WO_TMOUT((sdhci_readl(host, DWCMSHC_EMMC_DLL_STATUS0))))
364 break;
365 udelay(1);
366 timeout--;
367 }
368 dll_lock_value = ((sdhci_readl(host, DWCMSHC_EMMC_DLL_STATUS0) & 0xFF) * 2 ) & 0xFF;
369 extra = DWCMSHC_EMMC_DLL_DLYENA | DLL_RXCLK_ORI_GATE;
370 if (data->flags & RK_RXCLK_NO_INVERTER)
371 extra |= DLL_RXCLK_NO_INVERTER;
372 if (data->flags & RK_TAP_VALUE_SEL)
373 extra |= DLL_TAP_VALUE_SEL | (dll_lock_value << DLL_TAP_VALUE_OFFSET);
374 sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_RXCLK);
375
376 txclk_tapnum = data->hs200_tx_tap;
377 if ((data->flags & RK_DLL_CMD_OUT) &&
378 (host->mmc->timing == MMC_TIMING_MMC_HS400 ||
379 host->mmc->timing == MMC_TIMING_MMC_HS400ES)) {
380 txclk_tapnum = data->hs400_tx_tap;
381
382 extra = DLL_CMDOUT_SRC_CLK_NEG |
383 DLL_CMDOUT_BOTH_CLK_EDGE |
384 DWCMSHC_EMMC_DLL_DLYENA |
385 data->hs400_cmd_tap |
386 DLL_CMDOUT_TAPNUM_FROM_SW;
387 if (data->flags & RK_TAP_VALUE_SEL)
388 extra |= DLL_TAP_VALUE_SEL | (dll_lock_value << DLL_TAP_VALUE_OFFSET);
389 sdhci_writel(host, extra, DECMSHC_EMMC_DLL_CMDOUT);
390 }
391
392 extra = DWCMSHC_EMMC_DLL_DLYENA |
393 DLL_TXCLK_TAPNUM_FROM_SW |
394 DLL_TXCLK_NO_INVERTER|
395 txclk_tapnum;
396 if (data->flags & RK_TAP_VALUE_SEL)
397 extra |= DLL_TAP_VALUE_SEL | (dll_lock_value << DLL_TAP_VALUE_OFFSET);
398 sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_TXCLK);
399
400 extra = DWCMSHC_EMMC_DLL_DLYENA |
401 data->hs400_strbin_tap |
402 DLL_STRBIN_TAPNUM_FROM_SW;
403 if (data->flags & RK_TAP_VALUE_SEL)
404 extra |= DLL_TAP_VALUE_SEL | (dll_lock_value << DLL_TAP_VALUE_OFFSET);
405 sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_STRBIN);
406 } else {
407 /* disable dll */
408 sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_CTRL);
409
410 /* Disable cmd conflict check */
411 extra = sdhci_readl(host, DWCMSHC_HOST_CTRL3);
412 extra &= ~BIT(0);
413 sdhci_writel(host, extra, DWCMSHC_HOST_CTRL3);
414
415 /* reset the clock phase when the frequency is lower than 100MHz */
416 sdhci_writel(host, DWCMSHC_EMMC_DLL_BYPASS | DWCMSHC_EMMC_DLL_START, DWCMSHC_EMMC_DLL_CTRL);
417 sdhci_writel(host, DLL_RXCLK_ORI_GATE, DWCMSHC_EMMC_DLL_RXCLK);
418 sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK);
419 sdhci_writel(host, 0, DECMSHC_EMMC_DLL_CMDOUT);
420 /*
421 * Before switching to hs400es mode, the driver will enable
422 * enhanced strobe first. PHY needs to configure the parameters
423 * of enhanced strobe first.
424 */
425 extra = DWCMSHC_EMMC_DLL_DLYENA |
426 DLL_STRBIN_DELAY_NUM_SEL |
427 data->ddr50_strbin_delay_num << DLL_STRBIN_DELAY_NUM_OFFSET;
428 sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_STRBIN);
429 }
430
431 exit:
432 /* enable output clock */
433 sdhci_enable_clk(host, 0);
434
435 return ret;
436 }
437
dwcmshc_sdhci_set_enhanced_strobe(struct sdhci_host * host)438 static int dwcmshc_sdhci_set_enhanced_strobe(struct sdhci_host *host)
439 {
440 struct mmc *mmc = host->mmc;
441 u32 vendor;
442
443 vendor = sdhci_readl(host, DWCMSHC_EMMC_CONTROL);
444 if (mmc->timing == MMC_TIMING_MMC_HS400ES)
445 vendor |= DWCMSHC_ENHANCED_STROBE;
446 else
447 vendor &= ~DWCMSHC_ENHANCED_STROBE;
448 sdhci_writel(host, vendor, DWCMSHC_EMMC_CONTROL);
449
450 /* some emmc device need a delay before send command */
451 udelay(100);
452
453 return 0;
454 }
455
dwcmshc_sdhci_set_ios_post(struct sdhci_host * host)456 static void dwcmshc_sdhci_set_ios_post(struct sdhci_host *host)
457 {
458 u16 ctrl;
459 u32 timing = host->mmc->timing;
460
461 if (timing == MMC_TIMING_MMC_HS400 || timing == MMC_TIMING_MMC_HS400ES) {
462 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
463 ctrl &= ~SDHCI_CTRL_UHS_MASK;
464 ctrl |= DWCMSHC_CTRL_HS400;
465 sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
466
467 /* set CARD_IS_EMMC bit to enable Data Strobe for HS400 */
468 ctrl = sdhci_readw(host, DWCMSHC_EMMC_CONTROL);
469 ctrl |= DWCMSHC_CARD_IS_EMMC;
470 sdhci_writew(host, ctrl, DWCMSHC_EMMC_CONTROL);
471 }
472 }
473
dwcmshc_emmc_get_phy(struct udevice * dev)474 static int dwcmshc_emmc_get_phy(struct udevice *dev)
475 {
476 return 0;
477 }
478
rockchip_sdhci_set_clock(struct sdhci_host * host,unsigned int clock)479 static int rockchip_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
480 {
481 struct rockchip_sdhc *priv =
482 container_of(host, struct rockchip_sdhc, host);
483 struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
484 if (!data)
485 return -EINVAL;
486
487 return data->emmc_set_clock(host, clock);
488 }
489
rockchip_sdhci_set_ios_post(struct sdhci_host * host)490 static void rockchip_sdhci_set_ios_post(struct sdhci_host *host)
491 {
492 struct rockchip_sdhc *priv =
493 container_of(host, struct rockchip_sdhc, host);
494 struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
495
496 if (data && data->set_ios_post)
497 data->set_ios_post(host);
498 }
499
rockchip_sdhci_set_enhanced_strobe(struct sdhci_host * host)500 static int rockchip_sdhci_set_enhanced_strobe(struct sdhci_host *host)
501 {
502 struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
503 struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
504
505 if (data->set_enhanced_strobe)
506 return data->set_enhanced_strobe(host);
507
508 return -ENOTSUPP;
509 }
510
511 static struct sdhci_ops rockchip_sdhci_ops = {
512 .set_clock = rockchip_sdhci_set_clock,
513 .set_ios_post = rockchip_sdhci_set_ios_post,
514 .set_enhanced_strobe = rockchip_sdhci_set_enhanced_strobe,
515 };
516
rockchip_sdhci_probe(struct udevice * dev)517 static int rockchip_sdhci_probe(struct udevice *dev)
518 {
519 struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(dev);
520 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
521 struct rockchip_sdhc_plat *plat = dev_get_platdata(dev);
522 struct rockchip_sdhc *prv = dev_get_priv(dev);
523 struct sdhci_host *host = &prv->host;
524 int max_frequency, ret;
525 struct clk clk;
526
527 #if CONFIG_IS_ENABLED(OF_PLATDATA)
528 struct dtd_rockchip_rk3399_sdhci_5_1 *dtplat = &plat->dtplat;
529
530 host->name = dev->name;
531 host->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
532 host->host_caps |= MMC_MODE_8BIT;
533 max_frequency = dtplat->max_frequency;
534 ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &clk);
535 #else
536 max_frequency = dev_read_u32_default(dev, "max-frequency", 0);
537 switch (dev_read_u32_default(dev, "bus-width", 4)) {
538 case 8:
539 host->host_caps |= MMC_MODE_8BIT;
540 break;
541 case 4:
542 host->host_caps |= MMC_MODE_4BIT;
543 break;
544 case 1:
545 break;
546 default:
547 printf("Invalid \"bus-width\" value\n");
548 return -EINVAL;
549 }
550 ret = clk_get_by_index(dev, 0, &clk);
551 #endif
552 if (!ret) {
553 ret = clk_set_rate(&clk, max_frequency);
554 if (IS_ERR_VALUE(ret))
555 printf("%s clk set rate fail!\n", __func__);
556 } else {
557 printf("%s fail to get clk\n", __func__);
558 }
559
560 prv->emmc_clk = clk;
561 prv->dev = dev;
562 ret = data->get_phy(dev);
563 if (ret)
564 return ret;
565
566 host->ops = &rockchip_sdhci_ops;
567
568 host->max_clk = max_frequency;
569
570 if (dev_read_bool(dev, "mmc-hs200-1_8v"))
571 host->host_caps |= MMC_MODE_HS200;
572 else if (dev_read_bool(dev, "mmc-hs400-1_8v"))
573 host->host_caps |= MMC_MODE_HS400;
574
575 if (data->set_enhanced_strobe && dev_read_bool(dev, "mmc-hs400-enhanced-strobe"))
576 host->host_caps |= MMC_MODE_HS400ES;
577
578 ret = sdhci_setup_cfg(&plat->cfg, host, 0, EMMC_MIN_FREQ);
579
580 plat->cfg.fixed_drv_type = dev_read_u32_default(dev, "fixed-emmc-driver-type", 0);
581
582 host->mmc = &plat->mmc;
583 if (ret)
584 return ret;
585 host->mmc->priv = &prv->host;
586 host->mmc->dev = dev;
587 upriv->mmc = host->mmc;
588
589 return sdhci_probe(dev);
590 }
591
rockchip_sdhci_of_to_plat(struct udevice * dev)592 static int rockchip_sdhci_of_to_plat(struct udevice *dev)
593 {
594 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
595 struct sdhci_host *host = dev_get_priv(dev);
596
597 host->name = dev->name;
598 host->ioaddr = dev_read_addr_ptr(dev);
599 #endif
600
601 return 0;
602 }
603
rockchip_sdhci_bind(struct udevice * dev)604 static int rockchip_sdhci_bind(struct udevice *dev)
605 {
606 struct rockchip_sdhc_plat *plat = dev_get_platdata(dev);
607
608 return sdhci_bind(dev, &plat->mmc, &plat->cfg);
609 }
610
611 static const struct sdhci_data arasan_data = {
612 .emmc_set_clock = rk3399_sdhci_emmc_set_clock,
613 .get_phy = rk3399_emmc_get_phy,
614 };
615
616 static const struct sdhci_data rk3568_data = {
617 .emmc_set_clock = dwcmshc_sdhci_emmc_set_clock,
618 .get_phy = dwcmshc_emmc_get_phy,
619 .flags = RK_RXCLK_NO_INVERTER,
620 .hs200_tx_tap = 16,
621 .hs400_tx_tap = 8,
622 .hs400_cmd_tap = 8,
623 .hs400_strbin_tap = 3,
624 .ddr50_strbin_delay_num = 16,
625 };
626
627 static const struct sdhci_data rk3588_data = {
628 .emmc_set_clock = dwcmshc_sdhci_emmc_set_clock,
629 .get_phy = dwcmshc_emmc_get_phy,
630 .set_ios_post = dwcmshc_sdhci_set_ios_post,
631 .set_enhanced_strobe = dwcmshc_sdhci_set_enhanced_strobe,
632 .flags = RK_DLL_CMD_OUT,
633 .hs200_tx_tap = 16,
634 .hs400_tx_tap = 9,
635 .hs400_cmd_tap = 8,
636 .hs400_strbin_tap = 3,
637 .ddr50_strbin_delay_num = 16,
638 };
639
640 static const struct sdhci_data rk3528_data = {
641 .emmc_set_clock = dwcmshc_sdhci_emmc_set_clock,
642 .get_phy = dwcmshc_emmc_get_phy,
643 .set_ios_post = dwcmshc_sdhci_set_ios_post,
644 .set_enhanced_strobe = dwcmshc_sdhci_set_enhanced_strobe,
645 .flags = RK_DLL_CMD_OUT | RK_TAP_VALUE_SEL,
646 .hs200_tx_tap = 12,
647 .hs400_tx_tap = 6,
648 .hs400_cmd_tap = 6,
649 .hs400_strbin_tap = 3,
650 .ddr50_strbin_delay_num = 10,
651 };
652
653 static const struct sdhci_data rk3562_data = {
654 .emmc_set_clock = dwcmshc_sdhci_emmc_set_clock,
655 .get_phy = dwcmshc_emmc_get_phy,
656 .set_ios_post = dwcmshc_sdhci_set_ios_post,
657 .set_enhanced_strobe = dwcmshc_sdhci_set_enhanced_strobe,
658 .flags = RK_DLL_CMD_OUT | RK_TAP_VALUE_SEL,
659 .hs200_tx_tap = 12,
660 .hs400_tx_tap = 6,
661 .hs400_cmd_tap = 6,
662 .hs400_strbin_tap = 3,
663 .ddr50_strbin_delay_num = 10,
664 };
665
666 static const struct udevice_id sdhci_ids[] = {
667 {
668 .compatible = "arasan,sdhci-5.1",
669 .data = (ulong)&arasan_data,
670 },
671 {
672 .compatible = "snps,dwcmshc-sdhci",
673 .data = (ulong)&rk3568_data,
674 },
675 {
676 .compatible = "rockchip,rk3528-dwcmshc",
677 .data = (ulong)&rk3528_data,
678 },
679 {
680 .compatible = "rockchip,rk3562-dwcmshc",
681 .data = (ulong)&rk3562_data,
682 },
683 {
684 .compatible = "rockchip,rk3588-dwcmshc",
685 .data = (ulong)&rk3588_data,
686 },
687 { }
688 };
689
690 U_BOOT_DRIVER(arasan_sdhci_drv) = {
691 .name = "rockchip_sdhci_5_1",
692 .id = UCLASS_MMC,
693 .of_match = sdhci_ids,
694 .ofdata_to_platdata = rockchip_sdhci_of_to_plat,
695 .ops = &sdhci_ops,
696 .bind = rockchip_sdhci_bind,
697 .probe = rockchip_sdhci_probe,
698 .priv_auto_alloc_size = sizeof(struct rockchip_sdhc),
699 .platdata_auto_alloc_size = sizeof(struct rockchip_sdhc_plat),
700 };
701