Lines Matching +full:read +full:- +full:strobe +full:- +full:delay

1 // SPDX-License-Identifier: GPL-2.0
8 #include <linux/delay.h>
9 #include <linux/dma-mapping.h>
22 #include "sdhci-pltfm.h"
105 { "sprd,phy-delay-legacy", MMC_TIMING_LEGACY, },
106 { "sprd,phy-delay-sd-highspeed", MMC_TIMING_SD_HS, },
107 { "sprd,phy-delay-sd-uhs-sdr50", MMC_TIMING_UHS_SDR50, },
108 { "sprd,phy-delay-sd-uhs-sdr104", MMC_TIMING_UHS_SDR104, },
109 { "sprd,phy-delay-mmc-highspeed", MMC_TIMING_MMC_HS, },
110 { "sprd,phy-delay-mmc-ddr52", MMC_TIMING_MMC_DDR52, },
111 { "sprd,phy-delay-mmc-hs200", MMC_TIMING_MMC_HS200, },
112 { "sprd,phy-delay-mmc-hs400", MMC_TIMING_MMC_HS400, },
113 { "sprd,phy-delay-mmc-hs400es", MMC_TIMING_MMC_HS400 + 1, },
133 return readl_relaxed(host->ioaddr + reg); in sdhci_sprd_readl()
145 writel_relaxed(val, host->ioaddr + reg); in sdhci_sprd_writel()
150 /* SDHCI_BLOCK_COUNT is Read Only on Spreadtrum's platform */ in sdhci_sprd_writew()
154 writew_relaxed(val, host->ioaddr + reg); in sdhci_sprd_writew()
168 if (readb_relaxed(host->ioaddr + reg) & SDHCI_HW_RESET_CARD) in sdhci_sprd_writeb()
172 writeb_relaxed(val, host->ioaddr + reg); in sdhci_sprd_writeb()
237 div = sdhci_sprd_calc_div(sprd_host->base_rate, clk); in _sdhci_sprd_set_clock()
282 pr_err("%s: DLL locked fail!\n", mmc_hostname(host->mmc)); in sdhci_sprd_enable_phy_dll()
284 mmc_hostname(host->mmc), in sdhci_sprd_enable_phy_dll()
296 } else if (clock != host->clock) { in sdhci_sprd_set_clock()
323 return clk_round_rate(sprd_host->clk_sdio, ULONG_MAX); in sdhci_sprd_get_max_clock()
335 struct mmc_host *mmc = host->mmc; in sdhci_sprd_set_uhs_signaling()
336 u32 *p = sprd_host->phy_delay; in sdhci_sprd_set_uhs_signaling()
339 if (timing == host->timing) in sdhci_sprd_set_uhs_signaling()
376 if (!mmc->ios.enhanced_strobe) in sdhci_sprd_set_uhs_signaling()
390 val = readb_relaxed(host->ioaddr + SDHCI_SOFTWARE_RESET); in sdhci_sprd_hw_reset()
392 writeb_relaxed(val, host->ioaddr + SDHCI_SOFTWARE_RESET); in sdhci_sprd_hw_reset()
397 writeb_relaxed(val, host->ioaddr + SDHCI_SOFTWARE_RESET); in sdhci_sprd_hw_reset()
416 if (mmc_hsq_finalize_request(host->mmc, mrq)) in sdhci_sprd_request_done()
419 mmc_request_done(host->mmc, mrq); in sdhci_sprd_request_done()
425 struct mmc_host *mmc = host->mmc; in sdhci_sprd_set_power()
429 mmc_regulator_set_ocr(host->mmc, mmc->supply.vmmc, 0); in sdhci_sprd_set_power()
437 mmc_regulator_set_ocr(host->mmc, mmc->supply.vmmc, vdd); in sdhci_sprd_set_power()
466 host->flags |= sprd_host->flags & SDHCI_AUTO_CMD23; in sdhci_sprd_check_auto_cmd23()
469 * From version 4.10 onward, ARGUMENT2 register is also as 32-bit in sdhci_sprd_check_auto_cmd23()
473 if (host->version >= SDHCI_SPEC_410 && in sdhci_sprd_check_auto_cmd23()
474 mrq->sbc && (mrq->sbc->arg & SDHCI_SPRD_ARG2_STUFF) && in sdhci_sprd_check_auto_cmd23()
475 (host->flags & SDHCI_AUTO_CMD23)) in sdhci_sprd_check_auto_cmd23()
476 host->flags &= ~SDHCI_AUTO_CMD23; in sdhci_sprd_check_auto_cmd23()
500 if (!IS_ERR(mmc->supply.vqmmc)) { in sdhci_sprd_voltage_switch()
509 if (IS_ERR(sprd_host->pinctrl)) in sdhci_sprd_voltage_switch()
512 switch (ios->signal_voltage) { in sdhci_sprd_voltage_switch()
514 ret = pinctrl_select_state(sprd_host->pinctrl, in sdhci_sprd_voltage_switch()
515 sprd_host->pins_uhs); in sdhci_sprd_voltage_switch()
526 ret = pinctrl_select_state(sprd_host->pinctrl, in sdhci_sprd_voltage_switch()
527 sprd_host->pins_default); in sdhci_sprd_voltage_switch()
550 u32 *p = sprd_host->phy_delay; in sdhci_sprd_hs400_enhanced_strobe()
553 if (!ios->enhanced_strobe) in sdhci_sprd_hs400_enhanced_strobe()
558 /* Set HS400 enhanced strobe mode */ in sdhci_sprd_hs400_enhanced_strobe()
566 /* Set the PHY DLL delay value for HS400 enhanced strobe mode */ in sdhci_sprd_hs400_enhanced_strobe()
583 return -ENOMEM; in mmc_send_tuning_data()
608 range_end = i - 1; in sdhci_sprd_get_best_clk_sample()
615 return -EIO; in sdhci_sprd_get_best_clk_sample()
619 range_end = i - 1; in sdhci_sprd_get_best_clk_sample()
622 middle_range = range_end - (range_length - 1) / 2; in sdhci_sprd_get_best_clk_sample()
632 u32 *p = sprd_host->phy_delay; in sdhci_sprd_tuning()
641 return -ENOMEM; in sdhci_sprd_tuning()
649 dll_dly = p[mmc->ios.timing]; in sdhci_sprd_tuning()
670 dev_err(mmc_dev(host->mmc), "all tuning phase fail!\n"); in sdhci_sprd_tuning()
676 p[mmc->ios.timing] &= ~SDHCI_SPRD_CMD_DLY_MASK; in sdhci_sprd_tuning()
677 p[mmc->ios.timing] |= ((best_clk_sample << 8) & SDHCI_SPRD_CMD_DLY_MASK); in sdhci_sprd_tuning()
679 p[mmc->ios.timing] &= ~(SDHCI_SPRD_POSRD_DLY_MASK); in sdhci_sprd_tuning()
680 p[mmc->ios.timing] |= ((best_clk_sample << 16) & SDHCI_SPRD_POSRD_DLY_MASK); in sdhci_sprd_tuning()
683 pr_debug("%s: the best clk sample %d, delay value 0x%08x\n", in sdhci_sprd_tuning()
684 mmc_hostname(host->mmc), best_clk_sample, p[mmc->ios.timing]); in sdhci_sprd_tuning()
687 sdhci_writel(host, p[mmc->ios.timing], SDHCI_SPRD_REG_32_DLL_DLY); in sdhci_sprd_tuning()
707 u32 *p = sprd_host->phy_delay; in sdhci_sprd_phy_param_parse()
743 host->dma_mask = DMA_BIT_MASK(64); in sdhci_sprd_probe()
744 pdev->dev.dma_mask = &host->dma_mask; in sdhci_sprd_probe()
745 host->mmc_host_ops.request = sdhci_sprd_request; in sdhci_sprd_probe()
746 host->mmc_host_ops.hs400_enhanced_strobe = in sdhci_sprd_probe()
748 host->mmc_host_ops.prepare_sd_hs_tuning = in sdhci_sprd_probe()
750 host->mmc_host_ops.execute_sd_hs_tuning = in sdhci_sprd_probe()
759 host->mmc_host_ops.start_signal_voltage_switch = in sdhci_sprd_probe()
762 host->mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | in sdhci_sprd_probe()
765 ret = mmc_of_parse(host->mmc); in sdhci_sprd_probe()
769 if (!mmc_card_is_removable(host->mmc)) in sdhci_sprd_probe()
770 host->mmc_host_ops.request_atomic = sdhci_sprd_request_atomic; in sdhci_sprd_probe()
772 host->always_defer_done = true; in sdhci_sprd_probe()
775 sdhci_sprd_phy_param_parse(sprd_host, pdev->dev.of_node); in sdhci_sprd_probe()
777 sprd_host->pinctrl = devm_pinctrl_get(&pdev->dev); in sdhci_sprd_probe()
778 if (!IS_ERR(sprd_host->pinctrl)) { in sdhci_sprd_probe()
779 sprd_host->pins_uhs = in sdhci_sprd_probe()
780 pinctrl_lookup_state(sprd_host->pinctrl, "state_uhs"); in sdhci_sprd_probe()
781 if (IS_ERR(sprd_host->pins_uhs)) { in sdhci_sprd_probe()
782 ret = PTR_ERR(sprd_host->pins_uhs); in sdhci_sprd_probe()
786 sprd_host->pins_default = in sdhci_sprd_probe()
787 pinctrl_lookup_state(sprd_host->pinctrl, "default"); in sdhci_sprd_probe()
788 if (IS_ERR(sprd_host->pins_default)) { in sdhci_sprd_probe()
789 ret = PTR_ERR(sprd_host->pins_default); in sdhci_sprd_probe()
794 clk = devm_clk_get(&pdev->dev, "sdio"); in sdhci_sprd_probe()
799 sprd_host->clk_sdio = clk; in sdhci_sprd_probe()
800 sprd_host->base_rate = clk_get_rate(sprd_host->clk_sdio); in sdhci_sprd_probe()
801 if (!sprd_host->base_rate) in sdhci_sprd_probe()
802 sprd_host->base_rate = SDHCI_SPRD_CLK_DEF_RATE; in sdhci_sprd_probe()
804 clk = devm_clk_get(&pdev->dev, "enable"); in sdhci_sprd_probe()
809 sprd_host->clk_enable = clk; in sdhci_sprd_probe()
811 clk = devm_clk_get(&pdev->dev, "2x_enable"); in sdhci_sprd_probe()
813 sprd_host->clk_2x_enable = clk; in sdhci_sprd_probe()
815 ret = clk_prepare_enable(sprd_host->clk_sdio); in sdhci_sprd_probe()
819 ret = clk_prepare_enable(sprd_host->clk_enable); in sdhci_sprd_probe()
823 ret = clk_prepare_enable(sprd_host->clk_2x_enable); in sdhci_sprd_probe()
828 host->version = sdhci_readw(host, SDHCI_HOST_VERSION); in sdhci_sprd_probe()
829 sprd_host->version = ((host->version & SDHCI_VENDOR_VER_MASK) >> in sdhci_sprd_probe()
832 pm_runtime_get_noresume(&pdev->dev); in sdhci_sprd_probe()
833 pm_runtime_set_active(&pdev->dev); in sdhci_sprd_probe()
834 pm_runtime_enable(&pdev->dev); in sdhci_sprd_probe()
835 pm_runtime_set_autosuspend_delay(&pdev->dev, 50); in sdhci_sprd_probe()
836 pm_runtime_use_autosuspend(&pdev->dev); in sdhci_sprd_probe()
837 pm_suspend_ignore_children(&pdev->dev, 1); in sdhci_sprd_probe()
842 * Supply the existing CAPS, but clear the UHS-I modes. This in sdhci_sprd_probe()
847 host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | in sdhci_sprd_probe()
850 ret = mmc_regulator_get_supply(host->mmc); in sdhci_sprd_probe()
858 sprd_host->flags = host->flags; in sdhci_sprd_probe()
860 hsq = devm_kzalloc(&pdev->dev, sizeof(*hsq), GFP_KERNEL); in sdhci_sprd_probe()
862 ret = -ENOMEM; in sdhci_sprd_probe()
866 ret = mmc_hsq_init(hsq, host->mmc); in sdhci_sprd_probe()
874 pm_runtime_mark_last_busy(&pdev->dev); in sdhci_sprd_probe()
875 pm_runtime_put_autosuspend(&pdev->dev); in sdhci_sprd_probe()
883 pm_runtime_put_noidle(&pdev->dev); in sdhci_sprd_probe()
884 pm_runtime_disable(&pdev->dev); in sdhci_sprd_probe()
885 pm_runtime_set_suspended(&pdev->dev); in sdhci_sprd_probe()
887 clk_disable_unprepare(sprd_host->clk_2x_enable); in sdhci_sprd_probe()
890 clk_disable_unprepare(sprd_host->clk_enable); in sdhci_sprd_probe()
893 clk_disable_unprepare(sprd_host->clk_sdio); in sdhci_sprd_probe()
907 clk_disable_unprepare(sprd_host->clk_sdio); in sdhci_sprd_remove()
908 clk_disable_unprepare(sprd_host->clk_enable); in sdhci_sprd_remove()
909 clk_disable_unprepare(sprd_host->clk_2x_enable); in sdhci_sprd_remove()
915 { .compatible = "sprd,sdhci-r11", },
926 mmc_hsq_suspend(host->mmc); in sdhci_sprd_runtime_suspend()
929 clk_disable_unprepare(sprd_host->clk_sdio); in sdhci_sprd_runtime_suspend()
930 clk_disable_unprepare(sprd_host->clk_enable); in sdhci_sprd_runtime_suspend()
931 clk_disable_unprepare(sprd_host->clk_2x_enable); in sdhci_sprd_runtime_suspend()
942 ret = clk_prepare_enable(sprd_host->clk_2x_enable); in sdhci_sprd_runtime_resume()
946 ret = clk_prepare_enable(sprd_host->clk_enable); in sdhci_sprd_runtime_resume()
950 ret = clk_prepare_enable(sprd_host->clk_sdio); in sdhci_sprd_runtime_resume()
955 mmc_hsq_resume(host->mmc); in sdhci_sprd_runtime_resume()
960 clk_disable_unprepare(sprd_host->clk_enable); in sdhci_sprd_runtime_resume()
963 clk_disable_unprepare(sprd_host->clk_2x_enable); in sdhci_sprd_runtime_resume()
990 MODULE_ALIAS("platform:sdhci-sprd-r11");