1 /** 2 * SDHCI Controller driver for TI's OMAP SoCs 3 * 4 * Copyright (C) 2017 Texas Instruments 5 * Author: Kishon Vijay Abraham I <kishon@ti.com> 6 * 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 of 9 * the License as published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include <linux/delay.h> 21 #include <linux/mmc/slot-gpio.h> 22 #include <linux/module.h> 23 #include <linux/of.h> 24 #include <linux/of_device.h> 25 #include <linux/platform_device.h> 26 #include <linux/pm_runtime.h> 27 #include <linux/regulator/consumer.h> 28 29 #include "sdhci-pltfm.h" 30 31 #define SDHCI_OMAP_CON 0x12c 32 #define CON_DW8 BIT(5) 33 #define CON_DMA_MASTER BIT(20) 34 #define CON_INIT BIT(1) 35 #define CON_OD BIT(0) 36 37 #define SDHCI_OMAP_CMD 0x20c 38 39 #define SDHCI_OMAP_HCTL 0x228 40 #define HCTL_SDBP BIT(8) 41 #define HCTL_SDVS_SHIFT 9 42 #define HCTL_SDVS_MASK (0x7 << HCTL_SDVS_SHIFT) 43 #define HCTL_SDVS_33 (0x7 << HCTL_SDVS_SHIFT) 44 #define HCTL_SDVS_30 (0x6 << HCTL_SDVS_SHIFT) 45 #define HCTL_SDVS_18 (0x5 << HCTL_SDVS_SHIFT) 46 47 #define SDHCI_OMAP_SYSCTL 0x22c 48 #define SYSCTL_CEN BIT(2) 49 #define SYSCTL_CLKD_SHIFT 6 50 #define SYSCTL_CLKD_MASK 0x3ff 51 52 #define SDHCI_OMAP_STAT 0x230 53 54 #define SDHCI_OMAP_IE 0x234 55 #define INT_CC_EN BIT(0) 56 57 #define SDHCI_OMAP_AC12 0x23c 58 #define AC12_V1V8_SIGEN BIT(19) 59 60 #define SDHCI_OMAP_CAPA 0x240 61 #define CAPA_VS33 BIT(24) 62 #define CAPA_VS30 BIT(25) 63 #define CAPA_VS18 BIT(26) 64 65 #define SDHCI_OMAP_TIMEOUT 1 /* 1 msec */ 66 67 #define SYSCTL_CLKD_MAX 0x3FF 68 69 #define IOV_1V8 1800000 /* 180000 uV */ 70 #define IOV_3V0 3000000 /* 300000 uV */ 71 #define IOV_3V3 3300000 /* 330000 uV */ 72 73 struct sdhci_omap_data { 74 u32 offset; 75 }; 76 77 struct sdhci_omap_host { 78 void __iomem *base; 79 struct device *dev; 80 struct regulator *pbias; 81 bool pbias_enabled; 82 struct sdhci_host *host; 83 u8 bus_mode; 84 u8 power_mode; 85 }; 86 87 static inline u32 sdhci_omap_readl(struct sdhci_omap_host *host, 88 unsigned int offset) 89 { 90 return readl(host->base + offset); 91 } 92 93 static inline void sdhci_omap_writel(struct sdhci_omap_host *host, 94 unsigned int offset, u32 data) 95 { 96 writel(data, host->base + offset); 97 } 98 99 static int sdhci_omap_set_pbias(struct sdhci_omap_host *omap_host, 100 bool power_on, unsigned int iov) 101 { 102 int ret; 103 struct device *dev = omap_host->dev; 104 105 if (IS_ERR(omap_host->pbias)) 106 return 0; 107 108 if (power_on) { 109 ret = regulator_set_voltage(omap_host->pbias, iov, iov); 110 if (ret) { 111 dev_err(dev, "pbias set voltage failed\n"); 112 return ret; 113 } 114 115 if (omap_host->pbias_enabled) 116 return 0; 117 118 ret = regulator_enable(omap_host->pbias); 119 if (ret) { 120 dev_err(dev, "pbias reg enable fail\n"); 121 return ret; 122 } 123 124 omap_host->pbias_enabled = true; 125 } else { 126 if (!omap_host->pbias_enabled) 127 return 0; 128 129 ret = regulator_disable(omap_host->pbias); 130 if (ret) { 131 dev_err(dev, "pbias reg disable fail\n"); 132 return ret; 133 } 134 omap_host->pbias_enabled = false; 135 } 136 137 return 0; 138 } 139 140 static int sdhci_omap_enable_iov(struct sdhci_omap_host *omap_host, 141 unsigned int iov) 142 { 143 int ret; 144 struct sdhci_host *host = omap_host->host; 145 struct mmc_host *mmc = host->mmc; 146 147 ret = sdhci_omap_set_pbias(omap_host, false, 0); 148 if (ret) 149 return ret; 150 151 if (!IS_ERR(mmc->supply.vqmmc)) { 152 ret = regulator_set_voltage(mmc->supply.vqmmc, iov, iov); 153 if (ret) { 154 dev_err(mmc_dev(mmc), "vqmmc set voltage failed\n"); 155 return ret; 156 } 157 } 158 159 ret = sdhci_omap_set_pbias(omap_host, true, iov); 160 if (ret) 161 return ret; 162 163 return 0; 164 } 165 166 static void sdhci_omap_conf_bus_power(struct sdhci_omap_host *omap_host, 167 unsigned char signal_voltage) 168 { 169 u32 reg; 170 ktime_t timeout; 171 172 reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL); 173 reg &= ~HCTL_SDVS_MASK; 174 175 if (signal_voltage == MMC_SIGNAL_VOLTAGE_330) 176 reg |= HCTL_SDVS_33; 177 else 178 reg |= HCTL_SDVS_18; 179 180 sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg); 181 182 reg |= HCTL_SDBP; 183 sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg); 184 185 /* wait 1ms */ 186 timeout = ktime_add_ms(ktime_get(), SDHCI_OMAP_TIMEOUT); 187 while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL) & HCTL_SDBP)) { 188 if (WARN_ON(ktime_after(ktime_get(), timeout))) 189 return; 190 usleep_range(5, 10); 191 } 192 } 193 194 static int sdhci_omap_start_signal_voltage_switch(struct mmc_host *mmc, 195 struct mmc_ios *ios) 196 { 197 u32 reg; 198 int ret; 199 unsigned int iov; 200 struct sdhci_host *host = mmc_priv(mmc); 201 struct sdhci_pltfm_host *pltfm_host; 202 struct sdhci_omap_host *omap_host; 203 struct device *dev; 204 205 pltfm_host = sdhci_priv(host); 206 omap_host = sdhci_pltfm_priv(pltfm_host); 207 dev = omap_host->dev; 208 209 if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) { 210 reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA); 211 if (!(reg & CAPA_VS33)) 212 return -EOPNOTSUPP; 213 214 sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage); 215 216 reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12); 217 reg &= ~AC12_V1V8_SIGEN; 218 sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg); 219 220 iov = IOV_3V3; 221 } else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) { 222 reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA); 223 if (!(reg & CAPA_VS18)) 224 return -EOPNOTSUPP; 225 226 sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage); 227 228 reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12); 229 reg |= AC12_V1V8_SIGEN; 230 sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg); 231 232 iov = IOV_1V8; 233 } else { 234 return -EOPNOTSUPP; 235 } 236 237 ret = sdhci_omap_enable_iov(omap_host, iov); 238 if (ret) { 239 dev_err(dev, "failed to switch IO voltage to %dmV\n", iov); 240 return ret; 241 } 242 243 dev_dbg(dev, "IO voltage switched to %dmV\n", iov); 244 return 0; 245 } 246 247 static void sdhci_omap_set_bus_mode(struct sdhci_omap_host *omap_host, 248 unsigned int mode) 249 { 250 u32 reg; 251 252 if (omap_host->bus_mode == mode) 253 return; 254 255 reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON); 256 if (mode == MMC_BUSMODE_OPENDRAIN) 257 reg |= CON_OD; 258 else 259 reg &= ~CON_OD; 260 sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg); 261 262 omap_host->bus_mode = mode; 263 } 264 265 static void sdhci_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 266 { 267 struct sdhci_host *host = mmc_priv(mmc); 268 struct sdhci_pltfm_host *pltfm_host; 269 struct sdhci_omap_host *omap_host; 270 271 pltfm_host = sdhci_priv(host); 272 omap_host = sdhci_pltfm_priv(pltfm_host); 273 274 sdhci_omap_set_bus_mode(omap_host, ios->bus_mode); 275 sdhci_set_ios(mmc, ios); 276 } 277 278 static u16 sdhci_omap_calc_divisor(struct sdhci_pltfm_host *host, 279 unsigned int clock) 280 { 281 u16 dsor; 282 283 dsor = DIV_ROUND_UP(clk_get_rate(host->clk), clock); 284 if (dsor > SYSCTL_CLKD_MAX) 285 dsor = SYSCTL_CLKD_MAX; 286 287 return dsor; 288 } 289 290 static void sdhci_omap_start_clock(struct sdhci_omap_host *omap_host) 291 { 292 u32 reg; 293 294 reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL); 295 reg |= SYSCTL_CEN; 296 sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg); 297 } 298 299 static void sdhci_omap_stop_clock(struct sdhci_omap_host *omap_host) 300 { 301 u32 reg; 302 303 reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL); 304 reg &= ~SYSCTL_CEN; 305 sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg); 306 } 307 308 static void sdhci_omap_set_clock(struct sdhci_host *host, unsigned int clock) 309 { 310 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 311 struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host); 312 unsigned long clkdiv; 313 314 sdhci_omap_stop_clock(omap_host); 315 316 if (!clock) 317 return; 318 319 clkdiv = sdhci_omap_calc_divisor(pltfm_host, clock); 320 clkdiv = (clkdiv & SYSCTL_CLKD_MASK) << SYSCTL_CLKD_SHIFT; 321 sdhci_enable_clk(host, clkdiv); 322 323 sdhci_omap_start_clock(omap_host); 324 } 325 326 static void sdhci_omap_set_power(struct sdhci_host *host, unsigned char mode, 327 unsigned short vdd) 328 { 329 struct mmc_host *mmc = host->mmc; 330 331 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); 332 } 333 334 static int sdhci_omap_enable_dma(struct sdhci_host *host) 335 { 336 u32 reg; 337 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 338 struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host); 339 340 reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON); 341 reg |= CON_DMA_MASTER; 342 sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg); 343 344 return 0; 345 } 346 347 static unsigned int sdhci_omap_get_min_clock(struct sdhci_host *host) 348 { 349 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 350 351 return clk_get_rate(pltfm_host->clk) / SYSCTL_CLKD_MAX; 352 } 353 354 static void sdhci_omap_set_bus_width(struct sdhci_host *host, int width) 355 { 356 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 357 struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host); 358 u32 reg; 359 360 reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON); 361 if (width == MMC_BUS_WIDTH_8) 362 reg |= CON_DW8; 363 else 364 reg &= ~CON_DW8; 365 sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg); 366 367 sdhci_set_bus_width(host, width); 368 } 369 370 static void sdhci_omap_init_74_clocks(struct sdhci_host *host, u8 power_mode) 371 { 372 u32 reg; 373 ktime_t timeout; 374 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 375 struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host); 376 377 if (omap_host->power_mode == power_mode) 378 return; 379 380 if (power_mode != MMC_POWER_ON) 381 return; 382 383 disable_irq(host->irq); 384 385 reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON); 386 reg |= CON_INIT; 387 sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg); 388 sdhci_omap_writel(omap_host, SDHCI_OMAP_CMD, 0x0); 389 390 /* wait 1ms */ 391 timeout = ktime_add_ms(ktime_get(), SDHCI_OMAP_TIMEOUT); 392 while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_STAT) & INT_CC_EN)) { 393 if (WARN_ON(ktime_after(ktime_get(), timeout))) 394 return; 395 usleep_range(5, 10); 396 } 397 398 reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON); 399 reg &= ~CON_INIT; 400 sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg); 401 sdhci_omap_writel(omap_host, SDHCI_OMAP_STAT, INT_CC_EN); 402 403 enable_irq(host->irq); 404 405 omap_host->power_mode = power_mode; 406 } 407 408 static struct sdhci_ops sdhci_omap_ops = { 409 .set_clock = sdhci_omap_set_clock, 410 .set_power = sdhci_omap_set_power, 411 .enable_dma = sdhci_omap_enable_dma, 412 .get_max_clock = sdhci_pltfm_clk_get_max_clock, 413 .get_min_clock = sdhci_omap_get_min_clock, 414 .set_bus_width = sdhci_omap_set_bus_width, 415 .platform_send_init_74_clocks = sdhci_omap_init_74_clocks, 416 .reset = sdhci_reset, 417 .set_uhs_signaling = sdhci_set_uhs_signaling, 418 }; 419 420 static int sdhci_omap_set_capabilities(struct sdhci_omap_host *omap_host) 421 { 422 u32 reg; 423 int ret = 0; 424 struct device *dev = omap_host->dev; 425 struct regulator *vqmmc; 426 427 vqmmc = regulator_get(dev, "vqmmc"); 428 if (IS_ERR(vqmmc)) { 429 ret = PTR_ERR(vqmmc); 430 goto reg_put; 431 } 432 433 /* voltage capabilities might be set by boot loader, clear it */ 434 reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA); 435 reg &= ~(CAPA_VS18 | CAPA_VS30 | CAPA_VS33); 436 437 if (regulator_is_supported_voltage(vqmmc, IOV_3V3, IOV_3V3)) 438 reg |= CAPA_VS33; 439 if (regulator_is_supported_voltage(vqmmc, IOV_1V8, IOV_1V8)) 440 reg |= CAPA_VS18; 441 442 sdhci_omap_writel(omap_host, SDHCI_OMAP_CAPA, reg); 443 444 reg_put: 445 regulator_put(vqmmc); 446 447 return ret; 448 } 449 450 static const struct sdhci_pltfm_data sdhci_omap_pdata = { 451 .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | 452 SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | 453 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | 454 SDHCI_QUIRK_NO_HISPD_BIT | 455 SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC, 456 .quirks2 = SDHCI_QUIRK2_NO_1_8_V | 457 SDHCI_QUIRK2_ACMD23_BROKEN | 458 SDHCI_QUIRK2_RSP_136_HAS_CRC, 459 .ops = &sdhci_omap_ops, 460 }; 461 462 static const struct sdhci_omap_data dra7_data = { 463 .offset = 0x200, 464 }; 465 466 static const struct of_device_id omap_sdhci_match[] = { 467 { .compatible = "ti,dra7-sdhci", .data = &dra7_data }, 468 {}, 469 }; 470 MODULE_DEVICE_TABLE(of, omap_sdhci_match); 471 472 static int sdhci_omap_probe(struct platform_device *pdev) 473 { 474 int ret; 475 u32 offset; 476 struct device *dev = &pdev->dev; 477 struct sdhci_host *host; 478 struct sdhci_pltfm_host *pltfm_host; 479 struct sdhci_omap_host *omap_host; 480 struct mmc_host *mmc; 481 const struct of_device_id *match; 482 struct sdhci_omap_data *data; 483 484 match = of_match_device(omap_sdhci_match, dev); 485 if (!match) 486 return -EINVAL; 487 488 data = (struct sdhci_omap_data *)match->data; 489 if (!data) { 490 dev_err(dev, "no sdhci omap data\n"); 491 return -EINVAL; 492 } 493 offset = data->offset; 494 495 host = sdhci_pltfm_init(pdev, &sdhci_omap_pdata, 496 sizeof(*omap_host)); 497 if (IS_ERR(host)) { 498 dev_err(dev, "Failed sdhci_pltfm_init\n"); 499 return PTR_ERR(host); 500 } 501 502 pltfm_host = sdhci_priv(host); 503 omap_host = sdhci_pltfm_priv(pltfm_host); 504 omap_host->host = host; 505 omap_host->base = host->ioaddr; 506 omap_host->dev = dev; 507 host->ioaddr += offset; 508 509 mmc = host->mmc; 510 ret = mmc_of_parse(mmc); 511 if (ret) 512 goto err_pltfm_free; 513 514 pltfm_host->clk = devm_clk_get(dev, "fck"); 515 if (IS_ERR(pltfm_host->clk)) { 516 ret = PTR_ERR(pltfm_host->clk); 517 goto err_pltfm_free; 518 } 519 520 ret = clk_set_rate(pltfm_host->clk, mmc->f_max); 521 if (ret) { 522 dev_err(dev, "failed to set clock to %d\n", mmc->f_max); 523 goto err_pltfm_free; 524 } 525 526 omap_host->pbias = devm_regulator_get_optional(dev, "pbias"); 527 if (IS_ERR(omap_host->pbias)) { 528 ret = PTR_ERR(omap_host->pbias); 529 if (ret != -ENODEV) 530 goto err_pltfm_free; 531 dev_dbg(dev, "unable to get pbias regulator %d\n", ret); 532 } 533 omap_host->pbias_enabled = false; 534 535 /* 536 * omap_device_pm_domain has callbacks to enable the main 537 * functional clock, interface clock and also configure the 538 * SYSCONFIG register of omap devices. The callback will be invoked 539 * as part of pm_runtime_get_sync. 540 */ 541 pm_runtime_enable(dev); 542 ret = pm_runtime_get_sync(dev); 543 if (ret < 0) { 544 dev_err(dev, "pm_runtime_get_sync failed\n"); 545 pm_runtime_put_noidle(dev); 546 goto err_rpm_disable; 547 } 548 549 ret = sdhci_omap_set_capabilities(omap_host); 550 if (ret) { 551 dev_err(dev, "failed to set system capabilities\n"); 552 goto err_put_sync; 553 } 554 555 host->mmc_host_ops.get_ro = mmc_gpio_get_ro; 556 host->mmc_host_ops.start_signal_voltage_switch = 557 sdhci_omap_start_signal_voltage_switch; 558 host->mmc_host_ops.set_ios = sdhci_omap_set_ios; 559 560 sdhci_read_caps(host); 561 host->caps |= SDHCI_CAN_DO_ADMA2; 562 563 ret = sdhci_add_host(host); 564 if (ret) 565 goto err_put_sync; 566 567 return 0; 568 569 err_put_sync: 570 pm_runtime_put_sync(dev); 571 572 err_rpm_disable: 573 pm_runtime_disable(dev); 574 575 err_pltfm_free: 576 sdhci_pltfm_free(pdev); 577 return ret; 578 } 579 580 static int sdhci_omap_remove(struct platform_device *pdev) 581 { 582 struct device *dev = &pdev->dev; 583 struct sdhci_host *host = platform_get_drvdata(pdev); 584 585 sdhci_remove_host(host, true); 586 pm_runtime_put_sync(dev); 587 pm_runtime_disable(dev); 588 sdhci_pltfm_free(pdev); 589 590 return 0; 591 } 592 593 static struct platform_driver sdhci_omap_driver = { 594 .probe = sdhci_omap_probe, 595 .remove = sdhci_omap_remove, 596 .driver = { 597 .name = "sdhci-omap", 598 .of_match_table = omap_sdhci_match, 599 }, 600 }; 601 602 module_platform_driver(sdhci_omap_driver); 603 604 MODULE_DESCRIPTION("SDHCI driver for OMAP SoCs"); 605 MODULE_AUTHOR("Texas Instruments Inc."); 606 MODULE_LICENSE("GPL v2"); 607 MODULE_ALIAS("platform:sdhci_omap"); 608