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