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