1 /* 2 * Driver for Marvell Xenon SDHC as a platform device 3 * 4 * Copyright (C) 2016 Marvell, All Rights Reserved. 5 * 6 * Author: Hu Ziji <huziji@marvell.com> 7 * Date: 2016-8-24 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation version 2. 12 * 13 * Inspired by Jisheng Zhang <jszhang@marvell.com> 14 * Special thanks to Video BG4 project team. 15 */ 16 17 #include <linux/delay.h> 18 #include <linux/ktime.h> 19 #include <linux/module.h> 20 #include <linux/of.h> 21 #include <linux/pm.h> 22 #include <linux/pm_runtime.h> 23 24 #include "sdhci-pltfm.h" 25 #include "sdhci-xenon.h" 26 27 static int xenon_enable_internal_clk(struct sdhci_host *host) 28 { 29 u32 reg; 30 ktime_t timeout; 31 32 reg = sdhci_readl(host, SDHCI_CLOCK_CONTROL); 33 reg |= SDHCI_CLOCK_INT_EN; 34 sdhci_writel(host, reg, SDHCI_CLOCK_CONTROL); 35 /* Wait max 20 ms */ 36 timeout = ktime_add_ms(ktime_get(), 20); 37 while (1) { 38 bool timedout = ktime_after(ktime_get(), timeout); 39 40 reg = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 41 if (reg & SDHCI_CLOCK_INT_STABLE) 42 break; 43 if (timedout) { 44 dev_err(mmc_dev(host->mmc), "Internal clock never stabilised.\n"); 45 return -ETIMEDOUT; 46 } 47 usleep_range(900, 1100); 48 } 49 50 return 0; 51 } 52 53 /* Set SDCLK-off-while-idle */ 54 static void xenon_set_sdclk_off_idle(struct sdhci_host *host, 55 unsigned char sdhc_id, bool enable) 56 { 57 u32 reg; 58 u32 mask; 59 60 reg = sdhci_readl(host, XENON_SYS_OP_CTRL); 61 /* Get the bit shift basing on the SDHC index */ 62 mask = (0x1 << (XENON_SDCLK_IDLEOFF_ENABLE_SHIFT + sdhc_id)); 63 if (enable) 64 reg |= mask; 65 else 66 reg &= ~mask; 67 68 sdhci_writel(host, reg, XENON_SYS_OP_CTRL); 69 } 70 71 /* Enable/Disable the Auto Clock Gating function */ 72 static void xenon_set_acg(struct sdhci_host *host, bool enable) 73 { 74 u32 reg; 75 76 reg = sdhci_readl(host, XENON_SYS_OP_CTRL); 77 if (enable) 78 reg &= ~XENON_AUTO_CLKGATE_DISABLE_MASK; 79 else 80 reg |= XENON_AUTO_CLKGATE_DISABLE_MASK; 81 sdhci_writel(host, reg, XENON_SYS_OP_CTRL); 82 } 83 84 /* Enable this SDHC */ 85 static void xenon_enable_sdhc(struct sdhci_host *host, 86 unsigned char sdhc_id) 87 { 88 u32 reg; 89 90 reg = sdhci_readl(host, XENON_SYS_OP_CTRL); 91 reg |= (BIT(sdhc_id) << XENON_SLOT_ENABLE_SHIFT); 92 sdhci_writel(host, reg, XENON_SYS_OP_CTRL); 93 94 host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; 95 /* 96 * Force to clear BUS_TEST to 97 * skip bus_test_pre and bus_test_post 98 */ 99 host->mmc->caps &= ~MMC_CAP_BUS_WIDTH_TEST; 100 } 101 102 /* Disable this SDHC */ 103 static void xenon_disable_sdhc(struct sdhci_host *host, 104 unsigned char sdhc_id) 105 { 106 u32 reg; 107 108 reg = sdhci_readl(host, XENON_SYS_OP_CTRL); 109 reg &= ~(BIT(sdhc_id) << XENON_SLOT_ENABLE_SHIFT); 110 sdhci_writel(host, reg, XENON_SYS_OP_CTRL); 111 } 112 113 /* Enable Parallel Transfer Mode */ 114 static void xenon_enable_sdhc_parallel_tran(struct sdhci_host *host, 115 unsigned char sdhc_id) 116 { 117 u32 reg; 118 119 reg = sdhci_readl(host, XENON_SYS_EXT_OP_CTRL); 120 reg |= BIT(sdhc_id); 121 sdhci_writel(host, reg, XENON_SYS_EXT_OP_CTRL); 122 } 123 124 /* Mask command conflict error */ 125 static void xenon_mask_cmd_conflict_err(struct sdhci_host *host) 126 { 127 u32 reg; 128 129 reg = sdhci_readl(host, XENON_SYS_EXT_OP_CTRL); 130 reg |= XENON_MASK_CMD_CONFLICT_ERR; 131 sdhci_writel(host, reg, XENON_SYS_EXT_OP_CTRL); 132 } 133 134 static void xenon_retune_setup(struct sdhci_host *host) 135 { 136 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 137 struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); 138 u32 reg; 139 140 /* Disable the Re-Tuning Request functionality */ 141 reg = sdhci_readl(host, XENON_SLOT_RETUNING_REQ_CTRL); 142 reg &= ~XENON_RETUNING_COMPATIBLE; 143 sdhci_writel(host, reg, XENON_SLOT_RETUNING_REQ_CTRL); 144 145 /* Disable the Re-tuning Interrupt */ 146 reg = sdhci_readl(host, SDHCI_SIGNAL_ENABLE); 147 reg &= ~SDHCI_INT_RETUNE; 148 sdhci_writel(host, reg, SDHCI_SIGNAL_ENABLE); 149 reg = sdhci_readl(host, SDHCI_INT_ENABLE); 150 reg &= ~SDHCI_INT_RETUNE; 151 sdhci_writel(host, reg, SDHCI_INT_ENABLE); 152 153 /* Force to use Tuning Mode 1 */ 154 host->tuning_mode = SDHCI_TUNING_MODE_1; 155 /* Set re-tuning period */ 156 host->tuning_count = 1 << (priv->tuning_count - 1); 157 } 158 159 /* 160 * Operations inside struct sdhci_ops 161 */ 162 /* Recover the Register Setting cleared during SOFTWARE_RESET_ALL */ 163 static void xenon_reset_exit(struct sdhci_host *host, 164 unsigned char sdhc_id, u8 mask) 165 { 166 /* Only SOFTWARE RESET ALL will clear the register setting */ 167 if (!(mask & SDHCI_RESET_ALL)) 168 return; 169 170 /* Disable tuning request and auto-retuning again */ 171 xenon_retune_setup(host); 172 173 xenon_set_acg(host, true); 174 175 xenon_set_sdclk_off_idle(host, sdhc_id, false); 176 177 xenon_mask_cmd_conflict_err(host); 178 } 179 180 static void xenon_reset(struct sdhci_host *host, u8 mask) 181 { 182 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 183 struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); 184 185 sdhci_reset(host, mask); 186 xenon_reset_exit(host, priv->sdhc_id, mask); 187 } 188 189 /* 190 * Xenon defines different values for HS200 and HS400 191 * in Host_Control_2 192 */ 193 static void xenon_set_uhs_signaling(struct sdhci_host *host, 194 unsigned int timing) 195 { 196 u16 ctrl_2; 197 198 ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); 199 /* Select Bus Speed Mode for host */ 200 ctrl_2 &= ~SDHCI_CTRL_UHS_MASK; 201 if (timing == MMC_TIMING_MMC_HS200) 202 ctrl_2 |= XENON_CTRL_HS200; 203 else if (timing == MMC_TIMING_UHS_SDR104) 204 ctrl_2 |= SDHCI_CTRL_UHS_SDR104; 205 else if (timing == MMC_TIMING_UHS_SDR12) 206 ctrl_2 |= SDHCI_CTRL_UHS_SDR12; 207 else if (timing == MMC_TIMING_UHS_SDR25) 208 ctrl_2 |= SDHCI_CTRL_UHS_SDR25; 209 else if (timing == MMC_TIMING_UHS_SDR50) 210 ctrl_2 |= SDHCI_CTRL_UHS_SDR50; 211 else if ((timing == MMC_TIMING_UHS_DDR50) || 212 (timing == MMC_TIMING_MMC_DDR52)) 213 ctrl_2 |= SDHCI_CTRL_UHS_DDR50; 214 else if (timing == MMC_TIMING_MMC_HS400) 215 ctrl_2 |= XENON_CTRL_HS400; 216 sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); 217 } 218 219 static void xenon_set_power(struct sdhci_host *host, unsigned char mode, 220 unsigned short vdd) 221 { 222 struct mmc_host *mmc = host->mmc; 223 u8 pwr = host->pwr; 224 225 sdhci_set_power_noreg(host, mode, vdd); 226 227 if (host->pwr == pwr) 228 return; 229 230 if (host->pwr == 0) 231 vdd = 0; 232 233 if (!IS_ERR(mmc->supply.vmmc)) 234 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); 235 } 236 237 static void xenon_voltage_switch(struct sdhci_host *host) 238 { 239 /* Wait for 5ms after set 1.8V signal enable bit */ 240 usleep_range(5000, 5500); 241 } 242 243 static const struct sdhci_ops sdhci_xenon_ops = { 244 .voltage_switch = xenon_voltage_switch, 245 .set_clock = sdhci_set_clock, 246 .set_power = xenon_set_power, 247 .set_bus_width = sdhci_set_bus_width, 248 .reset = xenon_reset, 249 .set_uhs_signaling = xenon_set_uhs_signaling, 250 .get_max_clock = sdhci_pltfm_clk_get_max_clock, 251 }; 252 253 static const struct sdhci_pltfm_data sdhci_xenon_pdata = { 254 .ops = &sdhci_xenon_ops, 255 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | 256 SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER | 257 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, 258 }; 259 260 /* 261 * Xenon Specific Operations in mmc_host_ops 262 */ 263 static void xenon_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 264 { 265 struct sdhci_host *host = mmc_priv(mmc); 266 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 267 struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); 268 u32 reg; 269 270 /* 271 * HS400/HS200/eMMC HS doesn't have Preset Value register. 272 * However, sdhci_set_ios will read HS400/HS200 Preset register. 273 * Disable Preset Value register for HS400/HS200. 274 * eMMC HS with preset_enabled set will trigger a bug in 275 * get_preset_value(). 276 */ 277 if ((ios->timing == MMC_TIMING_MMC_HS400) || 278 (ios->timing == MMC_TIMING_MMC_HS200) || 279 (ios->timing == MMC_TIMING_MMC_HS)) { 280 host->preset_enabled = false; 281 host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; 282 host->flags &= ~SDHCI_PV_ENABLED; 283 284 reg = sdhci_readw(host, SDHCI_HOST_CONTROL2); 285 reg &= ~SDHCI_CTRL_PRESET_VAL_ENABLE; 286 sdhci_writew(host, reg, SDHCI_HOST_CONTROL2); 287 } else { 288 host->quirks2 &= ~SDHCI_QUIRK2_PRESET_VALUE_BROKEN; 289 } 290 291 sdhci_set_ios(mmc, ios); 292 xenon_phy_adj(host, ios); 293 294 if (host->clock > XENON_DEFAULT_SDCLK_FREQ) 295 xenon_set_sdclk_off_idle(host, priv->sdhc_id, true); 296 } 297 298 static int xenon_start_signal_voltage_switch(struct mmc_host *mmc, 299 struct mmc_ios *ios) 300 { 301 struct sdhci_host *host = mmc_priv(mmc); 302 303 /* 304 * Before SD/SDIO set signal voltage, SD bus clock should be 305 * disabled. However, sdhci_set_clock will also disable the Internal 306 * clock in mmc_set_signal_voltage(). 307 * If Internal clock is disabled, the 3.3V/1.8V bit can not be updated. 308 * Thus here manually enable internal clock. 309 * 310 * After switch completes, it is unnecessary to disable internal clock, 311 * since keeping internal clock active obeys SD spec. 312 */ 313 xenon_enable_internal_clk(host); 314 315 xenon_soc_pad_ctrl(host, ios->signal_voltage); 316 317 /* 318 * If Vqmmc is fixed on platform, vqmmc regulator should be unavailable. 319 * Thus SDHCI_CTRL_VDD_180 bit might not work then. 320 * Skip the standard voltage switch to avoid any issue. 321 */ 322 if (PTR_ERR(mmc->supply.vqmmc) == -ENODEV) 323 return 0; 324 325 return sdhci_start_signal_voltage_switch(mmc, ios); 326 } 327 328 /* 329 * Update card type. 330 * priv->init_card_type will be used in PHY timing adjustment. 331 */ 332 static void xenon_init_card(struct mmc_host *mmc, struct mmc_card *card) 333 { 334 struct sdhci_host *host = mmc_priv(mmc); 335 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 336 struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); 337 338 /* Update card type*/ 339 priv->init_card_type = card->type; 340 } 341 342 static int xenon_execute_tuning(struct mmc_host *mmc, u32 opcode) 343 { 344 struct sdhci_host *host = mmc_priv(mmc); 345 346 if (host->timing == MMC_TIMING_UHS_DDR50 || 347 host->timing == MMC_TIMING_MMC_DDR52) 348 return 0; 349 350 /* 351 * Currently force Xenon driver back to support mode 1 only, 352 * even though Xenon might claim to support mode 2 or mode 3. 353 * It requires more time to test mode 2/mode 3 on more platforms. 354 */ 355 if (host->tuning_mode != SDHCI_TUNING_MODE_1) 356 xenon_retune_setup(host); 357 358 return sdhci_execute_tuning(mmc, opcode); 359 } 360 361 static void xenon_enable_sdio_irq(struct mmc_host *mmc, int enable) 362 { 363 struct sdhci_host *host = mmc_priv(mmc); 364 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 365 struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); 366 u32 reg; 367 u8 sdhc_id = priv->sdhc_id; 368 369 sdhci_enable_sdio_irq(mmc, enable); 370 371 if (enable) { 372 /* 373 * Set SDIO Card Inserted indication 374 * to enable detecting SDIO async irq. 375 */ 376 reg = sdhci_readl(host, XENON_SYS_CFG_INFO); 377 reg |= (1 << (sdhc_id + XENON_SLOT_TYPE_SDIO_SHIFT)); 378 sdhci_writel(host, reg, XENON_SYS_CFG_INFO); 379 } else { 380 /* Clear SDIO Card Inserted indication */ 381 reg = sdhci_readl(host, XENON_SYS_CFG_INFO); 382 reg &= ~(1 << (sdhc_id + XENON_SLOT_TYPE_SDIO_SHIFT)); 383 sdhci_writel(host, reg, XENON_SYS_CFG_INFO); 384 } 385 } 386 387 static void xenon_replace_mmc_host_ops(struct sdhci_host *host) 388 { 389 host->mmc_host_ops.set_ios = xenon_set_ios; 390 host->mmc_host_ops.start_signal_voltage_switch = 391 xenon_start_signal_voltage_switch; 392 host->mmc_host_ops.init_card = xenon_init_card; 393 host->mmc_host_ops.execute_tuning = xenon_execute_tuning; 394 host->mmc_host_ops.enable_sdio_irq = xenon_enable_sdio_irq; 395 } 396 397 /* 398 * Parse Xenon specific DT properties: 399 * sdhc-id: the index of current SDHC. 400 * Refer to XENON_SYS_CFG_INFO register 401 * tun-count: the interval between re-tuning 402 */ 403 static int xenon_probe_dt(struct platform_device *pdev) 404 { 405 struct device_node *np = pdev->dev.of_node; 406 struct sdhci_host *host = platform_get_drvdata(pdev); 407 struct mmc_host *mmc = host->mmc; 408 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 409 struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); 410 u32 sdhc_id, nr_sdhc; 411 u32 tuning_count; 412 413 /* Disable HS200 on Armada AP806 */ 414 if (of_device_is_compatible(np, "marvell,armada-ap806-sdhci")) 415 host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200; 416 417 sdhc_id = 0x0; 418 if (!of_property_read_u32(np, "marvell,xenon-sdhc-id", &sdhc_id)) { 419 nr_sdhc = sdhci_readl(host, XENON_SYS_CFG_INFO); 420 nr_sdhc &= XENON_NR_SUPPORTED_SLOT_MASK; 421 if (unlikely(sdhc_id > nr_sdhc)) { 422 dev_err(mmc_dev(mmc), "SDHC Index %d exceeds Number of SDHCs %d\n", 423 sdhc_id, nr_sdhc); 424 return -EINVAL; 425 } 426 } 427 priv->sdhc_id = sdhc_id; 428 429 tuning_count = XENON_DEF_TUNING_COUNT; 430 if (!of_property_read_u32(np, "marvell,xenon-tun-count", 431 &tuning_count)) { 432 if (unlikely(tuning_count >= XENON_TMR_RETUN_NO_PRESENT)) { 433 dev_err(mmc_dev(mmc), "Wrong Re-tuning Count. Set default value %d\n", 434 XENON_DEF_TUNING_COUNT); 435 tuning_count = XENON_DEF_TUNING_COUNT; 436 } 437 } 438 priv->tuning_count = tuning_count; 439 440 return xenon_phy_parse_dt(np, host); 441 } 442 443 static int xenon_sdhc_prepare(struct sdhci_host *host) 444 { 445 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 446 struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); 447 u8 sdhc_id = priv->sdhc_id; 448 449 /* Enable SDHC */ 450 xenon_enable_sdhc(host, sdhc_id); 451 452 /* Enable ACG */ 453 xenon_set_acg(host, true); 454 455 /* Enable Parallel Transfer Mode */ 456 xenon_enable_sdhc_parallel_tran(host, sdhc_id); 457 458 /* Disable SDCLK-Off-While-Idle before card init */ 459 xenon_set_sdclk_off_idle(host, sdhc_id, false); 460 461 xenon_mask_cmd_conflict_err(host); 462 463 return 0; 464 } 465 466 static void xenon_sdhc_unprepare(struct sdhci_host *host) 467 { 468 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 469 struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); 470 u8 sdhc_id = priv->sdhc_id; 471 472 /* disable SDHC */ 473 xenon_disable_sdhc(host, sdhc_id); 474 } 475 476 static int xenon_probe(struct platform_device *pdev) 477 { 478 struct sdhci_pltfm_host *pltfm_host; 479 struct sdhci_host *host; 480 struct xenon_priv *priv; 481 int err; 482 483 host = sdhci_pltfm_init(pdev, &sdhci_xenon_pdata, 484 sizeof(struct xenon_priv)); 485 if (IS_ERR(host)) 486 return PTR_ERR(host); 487 488 pltfm_host = sdhci_priv(host); 489 priv = sdhci_pltfm_priv(pltfm_host); 490 491 /* 492 * Link Xenon specific mmc_host_ops function, 493 * to replace standard ones in sdhci_ops. 494 */ 495 xenon_replace_mmc_host_ops(host); 496 497 pltfm_host->clk = devm_clk_get(&pdev->dev, "core"); 498 if (IS_ERR(pltfm_host->clk)) { 499 err = PTR_ERR(pltfm_host->clk); 500 dev_err(&pdev->dev, "Failed to setup input clk: %d\n", err); 501 goto free_pltfm; 502 } 503 err = clk_prepare_enable(pltfm_host->clk); 504 if (err) 505 goto free_pltfm; 506 507 priv->axi_clk = devm_clk_get(&pdev->dev, "axi"); 508 if (IS_ERR(priv->axi_clk)) { 509 err = PTR_ERR(priv->axi_clk); 510 if (err == -EPROBE_DEFER) 511 goto err_clk; 512 } else { 513 err = clk_prepare_enable(priv->axi_clk); 514 if (err) 515 goto err_clk; 516 } 517 518 err = mmc_of_parse(host->mmc); 519 if (err) 520 goto err_clk_axi; 521 522 sdhci_get_of_property(pdev); 523 524 xenon_set_acg(host, false); 525 526 /* Xenon specific dt parse */ 527 err = xenon_probe_dt(pdev); 528 if (err) 529 goto err_clk_axi; 530 531 err = xenon_sdhc_prepare(host); 532 if (err) 533 goto err_clk_axi; 534 535 pm_runtime_get_noresume(&pdev->dev); 536 pm_runtime_set_active(&pdev->dev); 537 pm_runtime_set_autosuspend_delay(&pdev->dev, 50); 538 pm_runtime_use_autosuspend(&pdev->dev); 539 pm_runtime_enable(&pdev->dev); 540 pm_suspend_ignore_children(&pdev->dev, 1); 541 542 err = sdhci_add_host(host); 543 if (err) 544 goto remove_sdhc; 545 546 pm_runtime_put_autosuspend(&pdev->dev); 547 548 return 0; 549 550 remove_sdhc: 551 pm_runtime_disable(&pdev->dev); 552 pm_runtime_put_noidle(&pdev->dev); 553 xenon_sdhc_unprepare(host); 554 err_clk_axi: 555 clk_disable_unprepare(priv->axi_clk); 556 err_clk: 557 clk_disable_unprepare(pltfm_host->clk); 558 free_pltfm: 559 sdhci_pltfm_free(pdev); 560 return err; 561 } 562 563 static int xenon_remove(struct platform_device *pdev) 564 { 565 struct sdhci_host *host = platform_get_drvdata(pdev); 566 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 567 struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); 568 569 pm_runtime_get_sync(&pdev->dev); 570 pm_runtime_disable(&pdev->dev); 571 pm_runtime_put_noidle(&pdev->dev); 572 573 sdhci_remove_host(host, 0); 574 575 xenon_sdhc_unprepare(host); 576 clk_disable_unprepare(priv->axi_clk); 577 clk_disable_unprepare(pltfm_host->clk); 578 579 sdhci_pltfm_free(pdev); 580 581 return 0; 582 } 583 584 #ifdef CONFIG_PM_SLEEP 585 static int xenon_suspend(struct device *dev) 586 { 587 struct sdhci_host *host = dev_get_drvdata(dev); 588 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 589 struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); 590 int ret; 591 592 ret = pm_runtime_force_suspend(dev); 593 594 priv->restore_needed = true; 595 return ret; 596 } 597 #endif 598 599 #ifdef CONFIG_PM 600 static int xenon_runtime_suspend(struct device *dev) 601 { 602 struct sdhci_host *host = dev_get_drvdata(dev); 603 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 604 struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); 605 int ret; 606 607 ret = sdhci_runtime_suspend_host(host); 608 if (ret) 609 return ret; 610 611 if (host->tuning_mode != SDHCI_TUNING_MODE_3) 612 mmc_retune_needed(host->mmc); 613 614 clk_disable_unprepare(pltfm_host->clk); 615 /* 616 * Need to update the priv->clock here, or when runtime resume 617 * back, phy don't aware the clock change and won't adjust phy 618 * which will cause cmd err 619 */ 620 priv->clock = 0; 621 return 0; 622 } 623 624 static int xenon_runtime_resume(struct device *dev) 625 { 626 struct sdhci_host *host = dev_get_drvdata(dev); 627 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 628 struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); 629 int ret; 630 631 ret = clk_prepare_enable(pltfm_host->clk); 632 if (ret) { 633 dev_err(dev, "can't enable mainck\n"); 634 return ret; 635 } 636 637 if (priv->restore_needed) { 638 ret = xenon_sdhc_prepare(host); 639 if (ret) 640 goto out; 641 priv->restore_needed = false; 642 } 643 644 ret = sdhci_runtime_resume_host(host); 645 if (ret) 646 goto out; 647 return 0; 648 out: 649 clk_disable_unprepare(pltfm_host->clk); 650 return ret; 651 } 652 #endif /* CONFIG_PM */ 653 654 static const struct dev_pm_ops sdhci_xenon_dev_pm_ops = { 655 SET_SYSTEM_SLEEP_PM_OPS(xenon_suspend, 656 pm_runtime_force_resume) 657 SET_RUNTIME_PM_OPS(xenon_runtime_suspend, 658 xenon_runtime_resume, 659 NULL) 660 }; 661 662 static const struct of_device_id sdhci_xenon_dt_ids[] = { 663 { .compatible = "marvell,armada-ap806-sdhci",}, 664 { .compatible = "marvell,armada-cp110-sdhci",}, 665 { .compatible = "marvell,armada-3700-sdhci",}, 666 {} 667 }; 668 MODULE_DEVICE_TABLE(of, sdhci_xenon_dt_ids); 669 670 static struct platform_driver sdhci_xenon_driver = { 671 .driver = { 672 .name = "xenon-sdhci", 673 .of_match_table = sdhci_xenon_dt_ids, 674 .pm = &sdhci_xenon_dev_pm_ops, 675 }, 676 .probe = xenon_probe, 677 .remove = xenon_remove, 678 }; 679 680 module_platform_driver(sdhci_xenon_driver); 681 682 MODULE_DESCRIPTION("SDHCI platform driver for Marvell Xenon SDHC"); 683 MODULE_AUTHOR("Hu Ziji <huziji@marvell.com>"); 684 MODULE_LICENSE("GPL v2"); 685