• Home
  • Raw
  • Download

Lines Matching +full:power +full:- +full:stable +full:- +full:time

3  * Copyright (C) 2011 - 2012 Michal Simek <monstr@monstr.eu>
8 * Based on sdhci-of-esdhc.c
22 #include <linux/clk-provider.h>
31 #include "sdhci-pltfm.h"
40 * On some SoCs the syscon area has a feature where the upper 16-bits of
41 * each 32-bit register act as a write mask for the lower 16-bits. This allows
49 * struct sdhci_arasan_soc_ctl_field - Field used in sdhci_arasan_soc_ctl_map
53 * @shift: Bit offset within @reg of this field (or -1 if not avail)
62 * struct sdhci_arasan_soc_ctl_map - Map in syscon to corecfg registers
106 * internal clock even when the clock isn't stable */
117 * sdhci_arasan_syscon_write - Write to a field in soc_ctl registers
134 struct regmap *soc_ctl_base = sdhci_arasan->soc_ctl_base; in sdhci_arasan_syscon_write()
135 u32 reg = fld->reg; in sdhci_arasan_syscon_write()
136 u16 width = fld->width; in sdhci_arasan_syscon_write()
137 s16 shift = fld->shift; in sdhci_arasan_syscon_write()
147 return -EINVAL; in sdhci_arasan_syscon_write()
149 if (sdhci_arasan->soc_ctl_map->hiword_update) in sdhci_arasan_syscon_write()
161 mmc_hostname(host->mmc), ret); in sdhci_arasan_syscon_write()
172 if (!IS_ERR(sdhci_arasan->phy)) { in sdhci_arasan_set_clock()
173 if (!sdhci_arasan->is_phy_on && clock <= PHY_CLK_TOO_SLOW_HZ) { in sdhci_arasan_set_clock()
175 * If PHY off, set clock to max speed and power PHY on. in sdhci_arasan_set_clock()
177 * Although PHY docs apparently suggest power cycling in sdhci_arasan_set_clock()
184 * do is to power it on at a faster speed and then slam in sdhci_arasan_set_clock()
185 * through low speeds without power cycling. in sdhci_arasan_set_clock()
187 sdhci_set_clock(host, host->max_clk); in sdhci_arasan_set_clock()
188 phy_power_on(sdhci_arasan->phy); in sdhci_arasan_set_clock()
189 sdhci_arasan->is_phy_on = true; in sdhci_arasan_set_clock()
198 * At higher clock speeds the PHY is fine being power in sdhci_arasan_set_clock()
199 * cycled and docs say you _should_ power cycle when in sdhci_arasan_set_clock()
206 if (ctrl_phy && sdhci_arasan->is_phy_on) { in sdhci_arasan_set_clock()
207 phy_power_off(sdhci_arasan->phy); in sdhci_arasan_set_clock()
208 sdhci_arasan->is_phy_on = false; in sdhci_arasan_set_clock()
213 if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_CLOCK_UNSTABLE) in sdhci_arasan_set_clock()
217 * stable. Trying to use a clock without waiting here results in sdhci_arasan_set_clock()
224 phy_power_on(sdhci_arasan->phy); in sdhci_arasan_set_clock()
225 sdhci_arasan->is_phy_on = true; in sdhci_arasan_set_clock()
236 if (ios->enhanced_strobe) in sdhci_arasan_hs400_enhanced_strobe()
252 if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_FORCE_CDTEST) { in sdhci_arasan_reset()
262 switch (ios->signal_voltage) { in sdhci_arasan_voltage_switch()
278 return -EINVAL; in sdhci_arasan_voltage_switch()
284 if (!IS_ERR(host->mmc->supply.vmmc)) { in sdhci_arasan_set_power()
285 struct mmc_host *mmc = host->mmc; in sdhci_arasan_set_power()
287 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); in sdhci_arasan_set_power()
318 cqhci_irq(host->mmc, intmask, cmd_error, data_error); in sdhci_arasan_cqhci_irq()
368 * sdhci_arasan_suspend - Suspend method for the driver
372 * Put the device in a low power state.
381 if (host->tuning_mode != SDHCI_TUNING_MODE_3) in sdhci_arasan_suspend()
382 mmc_retune_needed(host->mmc); in sdhci_arasan_suspend()
384 if (sdhci_arasan->has_cqe) { in sdhci_arasan_suspend()
385 ret = cqhci_suspend(host->mmc); in sdhci_arasan_suspend()
394 if (!IS_ERR(sdhci_arasan->phy) && sdhci_arasan->is_phy_on) { in sdhci_arasan_suspend()
395 ret = phy_power_off(sdhci_arasan->phy); in sdhci_arasan_suspend()
397 dev_err(dev, "Cannot power off phy.\n"); in sdhci_arasan_suspend()
401 sdhci_arasan->is_phy_on = false; in sdhci_arasan_suspend()
404 clk_disable(pltfm_host->clk); in sdhci_arasan_suspend()
405 clk_disable(sdhci_arasan->clk_ahb); in sdhci_arasan_suspend()
411 * sdhci_arasan_resume - Resume method for the driver
424 ret = clk_enable(sdhci_arasan->clk_ahb); in sdhci_arasan_resume()
430 ret = clk_enable(pltfm_host->clk); in sdhci_arasan_resume()
436 if (!IS_ERR(sdhci_arasan->phy) && host->mmc->actual_clock) { in sdhci_arasan_resume()
437 ret = phy_power_on(sdhci_arasan->phy); in sdhci_arasan_resume()
439 dev_err(dev, "Cannot power on phy.\n"); in sdhci_arasan_resume()
442 sdhci_arasan->is_phy_on = true; in sdhci_arasan_resume()
451 if (sdhci_arasan->has_cqe) in sdhci_arasan_resume()
452 return cqhci_resume(host->mmc); in sdhci_arasan_resume()
462 /* SoC-specific compatible strings w/ soc_ctl_map */
464 .compatible = "rockchip,rk3399-sdhci-5.1",
469 { .compatible = "arasan,sdhci-8.9a" },
470 { .compatible = "arasan,sdhci-5.1" },
471 { .compatible = "arasan,sdhci-4.9a" },
478 * sdhci_arasan_sdcardclk_recalc_rate - Return the card clock rate
493 struct sdhci_host *host = sdhci_arasan->host; in sdhci_arasan_sdcardclk_recalc_rate()
495 return host->mmc->actual_clock; in sdhci_arasan_sdcardclk_recalc_rate()
503 * sdhci_arasan_update_clockmultiplier - Set corecfg_clockmultiplier
509 * - Many existing devices don't seem to do this and work fine. To keep
513 * - The value of corecfg_clockmultiplier should sync with that of corresponding
515 * once at probe time and never called again.
525 sdhci_arasan->soc_ctl_map; in sdhci_arasan_update_clockmultiplier()
532 if (!sdhci_arasan->soc_ctl_base) { in sdhci_arasan_update_clockmultiplier()
533 pr_warn("%s: Have regmap, but no soc-ctl-syscon\n", in sdhci_arasan_update_clockmultiplier()
534 mmc_hostname(host->mmc)); in sdhci_arasan_update_clockmultiplier()
538 sdhci_arasan_syscon_write(host, &soc_ctl_map->clockmultiplier, value); in sdhci_arasan_update_clockmultiplier()
542 * sdhci_arasan_update_baseclkfreq - Set corecfg_baseclkfreq
548 * - Many existing devices don't seem to do this and work fine. To keep
552 * - It's assumed that clk_xin is not dynamic and that we use the SDHCI divider
554 * at probe time and never called again.
563 sdhci_arasan->soc_ctl_map; in sdhci_arasan_update_baseclkfreq()
564 u32 mhz = DIV_ROUND_CLOSEST(clk_get_rate(pltfm_host->clk), 1000000); in sdhci_arasan_update_baseclkfreq()
571 if (!sdhci_arasan->soc_ctl_base) { in sdhci_arasan_update_baseclkfreq()
572 pr_warn("%s: Have regmap, but no soc-ctl-syscon\n", in sdhci_arasan_update_baseclkfreq()
573 mmc_hostname(host->mmc)); in sdhci_arasan_update_baseclkfreq()
577 sdhci_arasan_syscon_write(host, &soc_ctl_map->baseclkfreq, mhz); in sdhci_arasan_update_baseclkfreq()
581 * sdhci_arasan_register_sdclk - Register the sdclk for a PHY to use
587 * Note: without seriously re-architecting SDHCI's clock code and testing on
593 * re-architecting SDHCI if we see some benefit to it.
604 struct device_node *np = dev->of_node; in sdhci_arasan_register_sdclk()
610 if (!of_find_property(np, "#clock-cells", NULL)) in sdhci_arasan_register_sdclk()
613 ret = of_property_read_string_index(np, "clock-output-names", 0, in sdhci_arasan_register_sdclk()
616 dev_err(dev, "DT has #clock-cells but no clock-output-names\n"); in sdhci_arasan_register_sdclk()
626 sdhci_arasan->sdcardclk_hw.init = &sdcardclk_init; in sdhci_arasan_register_sdclk()
627 sdhci_arasan->sdcardclk = in sdhci_arasan_register_sdclk()
628 devm_clk_register(dev, &sdhci_arasan->sdcardclk_hw); in sdhci_arasan_register_sdclk()
629 sdhci_arasan->sdcardclk_hw.init = NULL; in sdhci_arasan_register_sdclk()
632 sdhci_arasan->sdcardclk); in sdhci_arasan_register_sdclk()
640 * sdhci_arasan_unregister_sdclk - Undoes sdhci_arasan_register_sdclk()
642 * Should be called any time we're exiting and sdhci_arasan_register_sdclk()
649 struct device_node *np = dev->of_node; in sdhci_arasan_unregister_sdclk()
651 if (!of_find_property(np, "#clock-cells", NULL)) in sdhci_arasan_unregister_sdclk()
654 of_clk_del_provider(dev->of_node); in sdhci_arasan_unregister_sdclk()
659 struct sdhci_host *host = sdhci_arasan->host; in sdhci_arasan_add_host()
664 if (!sdhci_arasan->has_cqe) in sdhci_arasan_add_host()
671 cq_host = devm_kzalloc(host->mmc->parent, in sdhci_arasan_add_host()
674 ret = -ENOMEM; in sdhci_arasan_add_host()
678 cq_host->mmio = host->ioaddr + SDHCI_ARASAN_CQE_BASE_ADDR; in sdhci_arasan_add_host()
679 cq_host->ops = &sdhci_arasan_cqhci_ops; in sdhci_arasan_add_host()
681 dma64 = host->flags & SDHCI_USE_64_BIT_DMA; in sdhci_arasan_add_host()
683 cq_host->caps |= CQHCI_TASK_DESC_SZ_128; in sdhci_arasan_add_host()
685 ret = cqhci_init(cq_host, host->mmc, dma64); in sdhci_arasan_add_host()
709 struct device_node *np = pdev->dev.of_node; in sdhci_arasan_probe()
712 if (of_device_is_compatible(pdev->dev.of_node, "arasan,sdhci-5.1")) in sdhci_arasan_probe()
724 sdhci_arasan->host = host; in sdhci_arasan_probe()
726 match = of_match_node(sdhci_arasan_of_match, pdev->dev.of_node); in sdhci_arasan_probe()
727 sdhci_arasan->soc_ctl_map = match->data; in sdhci_arasan_probe()
729 node = of_parse_phandle(pdev->dev.of_node, "arasan,soc-ctl-syscon", 0); in sdhci_arasan_probe()
731 sdhci_arasan->soc_ctl_base = syscon_node_to_regmap(node); in sdhci_arasan_probe()
734 if (IS_ERR(sdhci_arasan->soc_ctl_base)) { in sdhci_arasan_probe()
735 ret = PTR_ERR(sdhci_arasan->soc_ctl_base); in sdhci_arasan_probe()
736 if (ret != -EPROBE_DEFER) in sdhci_arasan_probe()
737 dev_err(&pdev->dev, "Can't get syscon: %d\n", in sdhci_arasan_probe()
743 sdhci_arasan->clk_ahb = devm_clk_get(&pdev->dev, "clk_ahb"); in sdhci_arasan_probe()
744 if (IS_ERR(sdhci_arasan->clk_ahb)) { in sdhci_arasan_probe()
745 dev_err(&pdev->dev, "clk_ahb clock not found.\n"); in sdhci_arasan_probe()
746 ret = PTR_ERR(sdhci_arasan->clk_ahb); in sdhci_arasan_probe()
750 clk_xin = devm_clk_get(&pdev->dev, "clk_xin"); in sdhci_arasan_probe()
752 dev_err(&pdev->dev, "clk_xin clock not found.\n"); in sdhci_arasan_probe()
757 ret = clk_prepare_enable(sdhci_arasan->clk_ahb); in sdhci_arasan_probe()
759 dev_err(&pdev->dev, "Unable to enable AHB clock.\n"); in sdhci_arasan_probe()
765 dev_err(&pdev->dev, "Unable to enable SD clock.\n"); in sdhci_arasan_probe()
771 if (of_property_read_bool(np, "xlnx,fails-without-test-cd")) in sdhci_arasan_probe()
772 sdhci_arasan->quirks |= SDHCI_ARASAN_QUIRK_FORCE_CDTEST; in sdhci_arasan_probe()
774 if (of_property_read_bool(np, "xlnx,int-clock-stable-broken")) in sdhci_arasan_probe()
775 sdhci_arasan->quirks |= SDHCI_ARASAN_QUIRK_CLOCK_UNSTABLE; in sdhci_arasan_probe()
777 pltfm_host->clk = clk_xin; in sdhci_arasan_probe()
779 if (of_device_is_compatible(pdev->dev.of_node, in sdhci_arasan_probe()
780 "rockchip,rk3399-sdhci-5.1")) in sdhci_arasan_probe()
785 ret = sdhci_arasan_register_sdclk(sdhci_arasan, clk_xin, &pdev->dev); in sdhci_arasan_probe()
789 ret = mmc_of_parse(host->mmc); in sdhci_arasan_probe()
791 if (ret != -EPROBE_DEFER) in sdhci_arasan_probe()
792 dev_err(&pdev->dev, "parsing dt failed (%d)\n", ret); in sdhci_arasan_probe()
796 sdhci_arasan->phy = ERR_PTR(-ENODEV); in sdhci_arasan_probe()
797 if (of_device_is_compatible(pdev->dev.of_node, in sdhci_arasan_probe()
798 "arasan,sdhci-5.1")) { in sdhci_arasan_probe()
799 sdhci_arasan->phy = devm_phy_get(&pdev->dev, in sdhci_arasan_probe()
801 if (IS_ERR(sdhci_arasan->phy)) { in sdhci_arasan_probe()
802 ret = PTR_ERR(sdhci_arasan->phy); in sdhci_arasan_probe()
803 dev_err(&pdev->dev, "No phy for arasan,sdhci-5.1.\n"); in sdhci_arasan_probe()
807 ret = phy_init(sdhci_arasan->phy); in sdhci_arasan_probe()
809 dev_err(&pdev->dev, "phy_init err.\n"); in sdhci_arasan_probe()
813 host->mmc_host_ops.hs400_enhanced_strobe = in sdhci_arasan_probe()
815 host->mmc_host_ops.start_signal_voltage_switch = in sdhci_arasan_probe()
817 sdhci_arasan->has_cqe = true; in sdhci_arasan_probe()
818 host->mmc->caps2 |= MMC_CAP2_CQE; in sdhci_arasan_probe()
820 if (!of_property_read_bool(np, "disable-cqe-dcmd")) in sdhci_arasan_probe()
821 host->mmc->caps2 |= MMC_CAP2_CQE_DCMD; in sdhci_arasan_probe()
831 if (!IS_ERR(sdhci_arasan->phy)) in sdhci_arasan_probe()
832 phy_exit(sdhci_arasan->phy); in sdhci_arasan_probe()
834 sdhci_arasan_unregister_sdclk(&pdev->dev); in sdhci_arasan_probe()
838 clk_disable_unprepare(sdhci_arasan->clk_ahb); in sdhci_arasan_probe()
850 struct clk *clk_ahb = sdhci_arasan->clk_ahb; in sdhci_arasan_remove()
852 if (!IS_ERR(sdhci_arasan->phy)) { in sdhci_arasan_remove()
853 if (sdhci_arasan->is_phy_on) in sdhci_arasan_remove()
854 phy_power_off(sdhci_arasan->phy); in sdhci_arasan_remove()
855 phy_exit(sdhci_arasan->phy); in sdhci_arasan_remove()
858 sdhci_arasan_unregister_sdclk(&pdev->dev); in sdhci_arasan_remove()
869 .name = "sdhci-arasan",