Lines Matching +full:mmc +full:- +full:card
1 // SPDX-License-Identifier: GPL-2.0
9 #include <linux/dma-mapping.h>
12 #include <linux/mmc/host.h>
13 #include <linux/mmc/mmc.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()
154 writew_relaxed(val, host->ioaddr + reg); in sdhci_sprd_writew()
164 * it by mistake will lead the card not work. So here we need to work in sdhci_sprd_writeb()
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() local
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() local
429 mmc_regulator_set_ocr(host->mmc, mmc->supply.vmmc, 0); in sdhci_sprd_set_power()
431 mmc_regulator_disable_vqmmc(mmc); in sdhci_sprd_set_power()
434 mmc_regulator_enable_vqmmc(mmc); in sdhci_sprd_set_power()
437 mmc_regulator_set_ocr(host->mmc, mmc->supply.vmmc, vdd); in sdhci_sprd_set_power()
460 static void sdhci_sprd_check_auto_cmd23(struct mmc_host *mmc, in sdhci_sprd_check_auto_cmd23() argument
463 struct sdhci_host *host = mmc_priv(mmc); in sdhci_sprd_check_auto_cmd23()
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()
479 static void sdhci_sprd_request(struct mmc_host *mmc, struct mmc_request *mrq) in sdhci_sprd_request() argument
481 sdhci_sprd_check_auto_cmd23(mmc, mrq); in sdhci_sprd_request()
483 sdhci_request(mmc, mrq); in sdhci_sprd_request()
486 static int sdhci_sprd_request_atomic(struct mmc_host *mmc, in sdhci_sprd_request_atomic() argument
489 sdhci_sprd_check_auto_cmd23(mmc, mrq); in sdhci_sprd_request_atomic()
491 return sdhci_request_atomic(mmc, mrq); in sdhci_sprd_request_atomic()
494 static int sdhci_sprd_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios) in sdhci_sprd_voltage_switch() argument
496 struct sdhci_host *host = mmc_priv(mmc); in sdhci_sprd_voltage_switch()
500 if (!IS_ERR(mmc->supply.vqmmc)) { in sdhci_sprd_voltage_switch()
501 ret = mmc_regulator_set_vqmmc(mmc, ios); in sdhci_sprd_voltage_switch()
504 mmc_hostname(mmc)); 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()
518 mmc_hostname(mmc)); 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()
530 mmc_hostname(mmc)); in sdhci_sprd_voltage_switch()
545 static void sdhci_sprd_hs400_enhanced_strobe(struct mmc_host *mmc, in sdhci_sprd_hs400_enhanced_strobe() argument
548 struct sdhci_host *host = mmc_priv(mmc); in sdhci_sprd_hs400_enhanced_strobe()
550 u32 *p = sprd_host->phy_delay; in sdhci_sprd_hs400_enhanced_strobe()
553 if (!ios->enhanced_strobe) in sdhci_sprd_hs400_enhanced_strobe()
571 static int mmc_send_tuning_cmd(struct mmc_card *card) in mmc_send_tuning_cmd() argument
573 return mmc_send_status(card, NULL); in mmc_send_tuning_cmd()
576 static int mmc_send_tuning_data(struct mmc_card *card) in mmc_send_tuning_data() argument
583 return -ENOMEM; in mmc_send_tuning_data()
585 ret = mmc_sd_switch(card, 0, 0, 0, status); in mmc_send_tuning_data()
592 static int sdhci_sprd_get_best_clk_sample(struct mmc_host *mmc, u8 *value) in sdhci_sprd_get_best_clk_sample() argument
602 pr_debug("%s: tuning ok: %d\n", mmc_hostname(mmc), i); in sdhci_sprd_get_best_clk_sample()
605 pr_debug("%s: tuning fail: %d\n", mmc_hostname(mmc), i); in sdhci_sprd_get_best_clk_sample()
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()
627 static int sdhci_sprd_tuning(struct mmc_host *mmc, struct mmc_card *card, in sdhci_sprd_tuning() argument
630 struct sdhci_host *host = mmc_priv(mmc); in sdhci_sprd_tuning()
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()
663 value[i] = !mmc_send_tuning_cmd(card); in sdhci_sprd_tuning()
665 value[i] = !mmc_send_tuning_data(card); in sdhci_sprd_tuning()
668 best_clk_sample = sdhci_sprd_get_best_clk_sample(mmc, value); 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()
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()
694 static int sdhci_sprd_prepare_sd_hs_cmd_tuning(struct mmc_host *mmc, struct mmc_card *card) in sdhci_sprd_prepare_sd_hs_cmd_tuning() argument
696 return sdhci_sprd_tuning(mmc, card, SDHCI_SPRD_TUNING_SD_HS_CMD); in sdhci_sprd_prepare_sd_hs_cmd_tuning()
699 static int sdhci_sprd_execute_sd_hs_data_tuning(struct mmc_host *mmc, struct mmc_card *card) in sdhci_sprd_execute_sd_hs_data_tuning() argument
701 return sdhci_sprd_tuning(mmc, card, SDHCI_SPRD_TUNING_SD_HS_DATA); in sdhci_sprd_execute_sd_hs_data_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");