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