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 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 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 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 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 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 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 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 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 474 static int dwcmshc_emmc_get_phy(struct udevice *dev) 475 { 476 return 0; 477 } 478 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 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 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 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 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 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