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