Lines Matching +full:force +full:- +full:internal +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0-only
8 * Date: 2016-8-24
21 #include "sdhci-pltfm.h"
22 #include "sdhci-xenon.h"
41 dev_err(mmc_dev(host->mmc), "Internal clock never stabilised.\n"); in xenon_enable_internal_clk()
42 return -ETIMEDOUT; in xenon_enable_internal_clk()
50 /* Set SDCLK-off-while-idle */
91 host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; in xenon_enable_sdhc()
93 * Force to clear BUS_TEST to in xenon_enable_sdhc()
96 host->mmc->caps &= ~MMC_CAP_BUS_WIDTH_TEST; in xenon_enable_sdhc()
137 /* Disable the Re-Tuning Request functionality */ in xenon_retune_setup()
142 /* Disable the Re-tuning Interrupt */ in xenon_retune_setup()
150 /* Force to use Tuning Mode 1 */ in xenon_retune_setup()
151 host->tuning_mode = SDHCI_TUNING_MODE_1; in xenon_retune_setup()
152 /* Set re-tuning period */ in xenon_retune_setup()
153 host->tuning_count = 1 << (priv->tuning_count - 1); in xenon_retune_setup()
167 /* Disable tuning request and auto-retuning again */ in xenon_reset_exit()
188 xenon_reset_exit(host, priv->sdhc_id, mask); in xenon_reset()
224 struct mmc_host *mmc = host->mmc; in xenon_set_power()
225 u8 pwr = host->pwr; in xenon_set_power()
229 if (host->pwr == pwr) in xenon_set_power()
232 if (host->pwr == 0) in xenon_set_power()
235 if (!IS_ERR(mmc->supply.vmmc)) in xenon_set_power()
236 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); in xenon_set_power()
289 if ((ios->timing == MMC_TIMING_MMC_HS400) || in xenon_set_ios()
290 (ios->timing == MMC_TIMING_MMC_HS200) || in xenon_set_ios()
291 (ios->timing == MMC_TIMING_MMC_HS)) { in xenon_set_ios()
292 host->preset_enabled = false; in xenon_set_ios()
293 host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; in xenon_set_ios()
294 host->flags &= ~SDHCI_PV_ENABLED; in xenon_set_ios()
300 host->quirks2 &= ~SDHCI_QUIRK2_PRESET_VALUE_BROKEN; in xenon_set_ios()
306 if (host->clock > XENON_DEFAULT_SDCLK_FREQ) in xenon_set_ios()
307 xenon_set_sdclk_off_idle(host, priv->sdhc_id, true); in xenon_set_ios()
317 * disabled. However, sdhci_set_clock will also disable the Internal in xenon_start_signal_voltage_switch()
319 * If Internal clock is disabled, the 3.3V/1.8V bit can not be updated. in xenon_start_signal_voltage_switch()
320 * Thus here manually enable internal clock. in xenon_start_signal_voltage_switch()
322 * After switch completes, it is unnecessary to disable internal clock, in xenon_start_signal_voltage_switch()
323 * since keeping internal clock active obeys SD spec. in xenon_start_signal_voltage_switch()
327 xenon_soc_pad_ctrl(host, ios->signal_voltage); in xenon_start_signal_voltage_switch()
334 if (PTR_ERR(mmc->supply.vqmmc) == -ENODEV) in xenon_start_signal_voltage_switch()
342 * priv->init_card_type will be used in PHY timing adjustment.
351 priv->init_card_type = card->type; in xenon_init_card()
358 if (host->timing == MMC_TIMING_UHS_DDR50 || in xenon_execute_tuning()
359 host->timing == MMC_TIMING_MMC_DDR52) in xenon_execute_tuning()
363 * Currently force Xenon driver back to support mode 1 only, in xenon_execute_tuning()
367 if (host->tuning_mode != SDHCI_TUNING_MODE_1) in xenon_execute_tuning()
379 u8 sdhc_id = priv->sdhc_id; in xenon_enable_sdio_irq()
401 host->mmc_host_ops.set_ios = xenon_set_ios; in xenon_replace_mmc_host_ops()
402 host->mmc_host_ops.start_signal_voltage_switch = in xenon_replace_mmc_host_ops()
404 host->mmc_host_ops.init_card = xenon_init_card; in xenon_replace_mmc_host_ops()
405 host->mmc_host_ops.execute_tuning = xenon_execute_tuning; in xenon_replace_mmc_host_ops()
406 host->mmc_host_ops.enable_sdio_irq = xenon_enable_sdio_irq; in xenon_replace_mmc_host_ops()
411 * sdhc-id: the index of current SDHC.
413 * tun-count: the interval between re-tuning
417 struct device_node *np = pdev->dev.of_node; in xenon_probe_dt()
419 struct mmc_host *mmc = host->mmc; in xenon_probe_dt()
426 if (of_device_is_compatible(np, "marvell,armada-ap806-sdhci")) in xenon_probe_dt()
427 host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200; in xenon_probe_dt()
430 if (!of_property_read_u32(np, "marvell,xenon-sdhc-id", &sdhc_id)) { in xenon_probe_dt()
436 return -EINVAL; in xenon_probe_dt()
439 priv->sdhc_id = sdhc_id; in xenon_probe_dt()
442 if (!of_property_read_u32(np, "marvell,xenon-tun-count", in xenon_probe_dt()
445 dev_err(mmc_dev(mmc), "Wrong Re-tuning Count. Set default value %d\n", in xenon_probe_dt()
450 priv->tuning_count = tuning_count; in xenon_probe_dt()
459 u8 sdhc_id = priv->sdhc_id; in xenon_sdhc_prepare()
470 /* Disable SDCLK-Off-While-Idle before card init */ in xenon_sdhc_prepare()
482 u8 sdhc_id = priv->sdhc_id; in xenon_sdhc_unprepare()
509 pltfm_host->clk = devm_clk_get(&pdev->dev, "core"); in xenon_probe()
510 if (IS_ERR(pltfm_host->clk)) { in xenon_probe()
511 err = PTR_ERR(pltfm_host->clk); in xenon_probe()
512 dev_err(&pdev->dev, "Failed to setup input clk: %d\n", err); in xenon_probe()
515 err = clk_prepare_enable(pltfm_host->clk); in xenon_probe()
519 priv->axi_clk = devm_clk_get(&pdev->dev, "axi"); in xenon_probe()
520 if (IS_ERR(priv->axi_clk)) { in xenon_probe()
521 err = PTR_ERR(priv->axi_clk); in xenon_probe()
522 if (err == -EPROBE_DEFER) in xenon_probe()
525 err = clk_prepare_enable(priv->axi_clk); in xenon_probe()
530 err = mmc_of_parse(host->mmc); in xenon_probe()
547 pm_runtime_get_noresume(&pdev->dev); in xenon_probe()
548 pm_runtime_set_active(&pdev->dev); in xenon_probe()
549 pm_runtime_set_autosuspend_delay(&pdev->dev, 50); in xenon_probe()
550 pm_runtime_use_autosuspend(&pdev->dev); in xenon_probe()
551 pm_runtime_enable(&pdev->dev); in xenon_probe()
552 pm_suspend_ignore_children(&pdev->dev, 1); in xenon_probe()
558 pm_runtime_put_autosuspend(&pdev->dev); in xenon_probe()
563 pm_runtime_disable(&pdev->dev); in xenon_probe()
564 pm_runtime_put_noidle(&pdev->dev); in xenon_probe()
567 clk_disable_unprepare(priv->axi_clk); in xenon_probe()
569 clk_disable_unprepare(pltfm_host->clk); in xenon_probe()
581 pm_runtime_get_sync(&pdev->dev); in xenon_remove()
582 pm_runtime_disable(&pdev->dev); in xenon_remove()
583 pm_runtime_put_noidle(&pdev->dev); in xenon_remove()
588 clk_disable_unprepare(priv->axi_clk); in xenon_remove()
589 clk_disable_unprepare(pltfm_host->clk); in xenon_remove()
606 priv->restore_needed = true; in xenon_suspend()
623 if (host->tuning_mode != SDHCI_TUNING_MODE_3) in xenon_runtime_suspend()
624 mmc_retune_needed(host->mmc); in xenon_runtime_suspend()
626 clk_disable_unprepare(pltfm_host->clk); in xenon_runtime_suspend()
628 * Need to update the priv->clock here, or when runtime resume in xenon_runtime_suspend()
629 * back, phy don't aware the clock change and won't adjust phy in xenon_runtime_suspend()
632 priv->clock = 0; in xenon_runtime_suspend()
643 ret = clk_prepare_enable(pltfm_host->clk); in xenon_runtime_resume()
649 if (priv->restore_needed) { in xenon_runtime_resume()
653 priv->restore_needed = false; in xenon_runtime_resume()
661 clk_disable_unprepare(pltfm_host->clk); in xenon_runtime_resume()
675 { .compatible = "marvell,armada-ap806-sdhci",},
676 { .compatible = "marvell,armada-cp110-sdhci",},
677 { .compatible = "marvell,armada-3700-sdhci",},
684 .name = "xenon-sdhci",