Lines Matching +full:mmc +full:- +full:hs400 +full:- +full:enhanced +full:- +full:strobe
1 // SPDX-License-Identifier: GPL-2.0
9 #include <linux/dma-mapping.h>
21 #include "sdhci-pltfm.h"
91 { "sprd,phy-delay-legacy", MMC_TIMING_LEGACY, },
92 { "sprd,phy-delay-sd-highspeed", MMC_TIMING_SD_HS, },
93 { "sprd,phy-delay-sd-uhs-sdr50", MMC_TIMING_UHS_SDR50, },
94 { "sprd,phy-delay-sd-uhs-sdr104", MMC_TIMING_UHS_SDR104, },
95 { "sprd,phy-delay-mmc-highspeed", MMC_TIMING_MMC_HS, },
96 { "sprd,phy-delay-mmc-ddr52", MMC_TIMING_MMC_DDR52, },
97 { "sprd,phy-delay-mmc-hs200", MMC_TIMING_MMC_HS200, },
98 { "sprd,phy-delay-mmc-hs400", MMC_TIMING_MMC_HS400, },
99 { "sprd,phy-delay-mmc-hs400es", MMC_TIMING_MMC_HS400 + 1, },
119 return readl_relaxed(host->ioaddr + reg); in sdhci_sprd_readl()
131 writel_relaxed(val, host->ioaddr + reg); in sdhci_sprd_writel()
140 writew_relaxed(val, host->ioaddr + reg); in sdhci_sprd_writew()
154 if (readb_relaxed(host->ioaddr + reg) & SDHCI_HW_RESET_CARD) in sdhci_sprd_writeb()
158 writeb_relaxed(val, host->ioaddr + reg); in sdhci_sprd_writeb()
223 div = sdhci_sprd_calc_div(sprd_host->base_rate, clk); in _sdhci_sprd_set_clock()
267 } else if (clock != host->clock) { in sdhci_sprd_set_clock()
294 return clk_round_rate(sprd_host->clk_sdio, ULONG_MAX); in sdhci_sprd_get_max_clock()
306 struct mmc_host *mmc = host->mmc; in sdhci_sprd_set_uhs_signaling() local
307 u32 *p = sprd_host->phy_delay; in sdhci_sprd_set_uhs_signaling()
310 if (timing == host->timing) in sdhci_sprd_set_uhs_signaling()
347 if (!mmc->ios.enhanced_strobe) in sdhci_sprd_set_uhs_signaling()
361 val = readb_relaxed(host->ioaddr + SDHCI_SOFTWARE_RESET); in sdhci_sprd_hw_reset()
363 writeb_relaxed(val, host->ioaddr + SDHCI_SOFTWARE_RESET); in sdhci_sprd_hw_reset()
368 writeb_relaxed(val, host->ioaddr + SDHCI_SOFTWARE_RESET); in sdhci_sprd_hw_reset()
387 if (mmc_hsq_finalize_request(host->mmc, mrq)) in sdhci_sprd_request_done()
390 mmc_request_done(host->mmc, mrq); in sdhci_sprd_request_done()
409 static void sdhci_sprd_check_auto_cmd23(struct mmc_host *mmc, in sdhci_sprd_check_auto_cmd23() argument
412 struct sdhci_host *host = mmc_priv(mmc); in sdhci_sprd_check_auto_cmd23()
415 host->flags |= sprd_host->flags & SDHCI_AUTO_CMD23; in sdhci_sprd_check_auto_cmd23()
418 * From version 4.10 onward, ARGUMENT2 register is also as 32-bit in sdhci_sprd_check_auto_cmd23()
422 if (host->version >= SDHCI_SPEC_410 && in sdhci_sprd_check_auto_cmd23()
423 mrq->sbc && (mrq->sbc->arg & SDHCI_SPRD_ARG2_STUFF) && in sdhci_sprd_check_auto_cmd23()
424 (host->flags & SDHCI_AUTO_CMD23)) in sdhci_sprd_check_auto_cmd23()
425 host->flags &= ~SDHCI_AUTO_CMD23; in sdhci_sprd_check_auto_cmd23()
428 static void sdhci_sprd_request(struct mmc_host *mmc, struct mmc_request *mrq) in sdhci_sprd_request() argument
430 sdhci_sprd_check_auto_cmd23(mmc, mrq); in sdhci_sprd_request()
432 sdhci_request(mmc, mrq); in sdhci_sprd_request()
435 static int sdhci_sprd_request_atomic(struct mmc_host *mmc, in sdhci_sprd_request_atomic() argument
438 sdhci_sprd_check_auto_cmd23(mmc, mrq); in sdhci_sprd_request_atomic()
440 return sdhci_request_atomic(mmc, mrq); in sdhci_sprd_request_atomic()
443 static int sdhci_sprd_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios) in sdhci_sprd_voltage_switch() argument
445 struct sdhci_host *host = mmc_priv(mmc); in sdhci_sprd_voltage_switch()
449 if (!IS_ERR(mmc->supply.vqmmc)) { in sdhci_sprd_voltage_switch()
450 ret = mmc_regulator_set_vqmmc(mmc, ios); in sdhci_sprd_voltage_switch()
453 mmc_hostname(mmc)); in sdhci_sprd_voltage_switch()
458 if (IS_ERR(sprd_host->pinctrl)) in sdhci_sprd_voltage_switch()
461 switch (ios->signal_voltage) { in sdhci_sprd_voltage_switch()
463 ret = pinctrl_select_state(sprd_host->pinctrl, in sdhci_sprd_voltage_switch()
464 sprd_host->pins_uhs); in sdhci_sprd_voltage_switch()
467 mmc_hostname(mmc)); in sdhci_sprd_voltage_switch()
475 ret = pinctrl_select_state(sprd_host->pinctrl, in sdhci_sprd_voltage_switch()
476 sprd_host->pins_default); in sdhci_sprd_voltage_switch()
479 mmc_hostname(mmc)); in sdhci_sprd_voltage_switch()
492 static void sdhci_sprd_hs400_enhanced_strobe(struct mmc_host *mmc, in sdhci_sprd_hs400_enhanced_strobe() argument
495 struct sdhci_host *host = mmc_priv(mmc); in sdhci_sprd_hs400_enhanced_strobe()
497 u32 *p = sprd_host->phy_delay; in sdhci_sprd_hs400_enhanced_strobe()
500 if (!ios->enhanced_strobe) in sdhci_sprd_hs400_enhanced_strobe()
505 /* Set HS400 enhanced strobe mode */ in sdhci_sprd_hs400_enhanced_strobe()
513 /* Set the PHY DLL delay value for HS400 enhanced strobe mode */ in sdhci_sprd_hs400_enhanced_strobe()
521 u32 *p = sprd_host->phy_delay; in sdhci_sprd_phy_param_parse()
558 host->dma_mask = DMA_BIT_MASK(64); in sdhci_sprd_probe()
559 pdev->dev.dma_mask = &host->dma_mask; in sdhci_sprd_probe()
560 host->mmc_host_ops.request = sdhci_sprd_request; in sdhci_sprd_probe()
561 host->mmc_host_ops.hs400_enhanced_strobe = in sdhci_sprd_probe()
569 host->mmc_host_ops.start_signal_voltage_switch = in sdhci_sprd_probe()
572 host->mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | in sdhci_sprd_probe()
575 ret = mmc_of_parse(host->mmc); in sdhci_sprd_probe()
579 if (!mmc_card_is_removable(host->mmc)) in sdhci_sprd_probe()
580 host->mmc_host_ops.request_atomic = sdhci_sprd_request_atomic; in sdhci_sprd_probe()
582 host->always_defer_done = true; in sdhci_sprd_probe()
585 sdhci_sprd_phy_param_parse(sprd_host, pdev->dev.of_node); in sdhci_sprd_probe()
587 sprd_host->pinctrl = devm_pinctrl_get(&pdev->dev); in sdhci_sprd_probe()
588 if (!IS_ERR(sprd_host->pinctrl)) { in sdhci_sprd_probe()
589 sprd_host->pins_uhs = in sdhci_sprd_probe()
590 pinctrl_lookup_state(sprd_host->pinctrl, "state_uhs"); in sdhci_sprd_probe()
591 if (IS_ERR(sprd_host->pins_uhs)) { in sdhci_sprd_probe()
592 ret = PTR_ERR(sprd_host->pins_uhs); in sdhci_sprd_probe()
596 sprd_host->pins_default = in sdhci_sprd_probe()
597 pinctrl_lookup_state(sprd_host->pinctrl, "default"); in sdhci_sprd_probe()
598 if (IS_ERR(sprd_host->pins_default)) { in sdhci_sprd_probe()
599 ret = PTR_ERR(sprd_host->pins_default); in sdhci_sprd_probe()
604 clk = devm_clk_get(&pdev->dev, "sdio"); in sdhci_sprd_probe()
609 sprd_host->clk_sdio = clk; in sdhci_sprd_probe()
610 sprd_host->base_rate = clk_get_rate(sprd_host->clk_sdio); in sdhci_sprd_probe()
611 if (!sprd_host->base_rate) in sdhci_sprd_probe()
612 sprd_host->base_rate = SDHCI_SPRD_CLK_DEF_RATE; in sdhci_sprd_probe()
614 clk = devm_clk_get(&pdev->dev, "enable"); in sdhci_sprd_probe()
619 sprd_host->clk_enable = clk; in sdhci_sprd_probe()
621 clk = devm_clk_get(&pdev->dev, "2x_enable"); in sdhci_sprd_probe()
623 sprd_host->clk_2x_enable = clk; in sdhci_sprd_probe()
625 ret = clk_prepare_enable(sprd_host->clk_sdio); in sdhci_sprd_probe()
629 ret = clk_prepare_enable(sprd_host->clk_enable); in sdhci_sprd_probe()
633 ret = clk_prepare_enable(sprd_host->clk_2x_enable); in sdhci_sprd_probe()
638 host->version = sdhci_readw(host, SDHCI_HOST_VERSION); in sdhci_sprd_probe()
639 sprd_host->version = ((host->version & SDHCI_VENDOR_VER_MASK) >> in sdhci_sprd_probe()
642 pm_runtime_get_noresume(&pdev->dev); in sdhci_sprd_probe()
643 pm_runtime_set_active(&pdev->dev); in sdhci_sprd_probe()
644 pm_runtime_enable(&pdev->dev); in sdhci_sprd_probe()
645 pm_runtime_set_autosuspend_delay(&pdev->dev, 50); in sdhci_sprd_probe()
646 pm_runtime_use_autosuspend(&pdev->dev); in sdhci_sprd_probe()
647 pm_suspend_ignore_children(&pdev->dev, 1); in sdhci_sprd_probe()
652 * Supply the existing CAPS, but clear the UHS-I modes. This in sdhci_sprd_probe()
656 host->caps = sdhci_readl(host, SDHCI_CAPABILITIES); in sdhci_sprd_probe()
657 host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); in sdhci_sprd_probe()
658 host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | in sdhci_sprd_probe()
665 sprd_host->flags = host->flags; in sdhci_sprd_probe()
667 hsq = devm_kzalloc(&pdev->dev, sizeof(*hsq), GFP_KERNEL); in sdhci_sprd_probe()
669 ret = -ENOMEM; in sdhci_sprd_probe()
673 ret = mmc_hsq_init(hsq, host->mmc); in sdhci_sprd_probe()
681 pm_runtime_mark_last_busy(&pdev->dev); in sdhci_sprd_probe()
682 pm_runtime_put_autosuspend(&pdev->dev); in sdhci_sprd_probe()
690 pm_runtime_put_noidle(&pdev->dev); in sdhci_sprd_probe()
691 pm_runtime_disable(&pdev->dev); in sdhci_sprd_probe()
692 pm_runtime_set_suspended(&pdev->dev); in sdhci_sprd_probe()
694 clk_disable_unprepare(sprd_host->clk_2x_enable); in sdhci_sprd_probe()
697 clk_disable_unprepare(sprd_host->clk_enable); in sdhci_sprd_probe()
700 clk_disable_unprepare(sprd_host->clk_sdio); in sdhci_sprd_probe()
711 struct mmc_host *mmc = host->mmc; in sdhci_sprd_remove() local
713 mmc_remove_host(mmc); in sdhci_sprd_remove()
714 clk_disable_unprepare(sprd_host->clk_sdio); in sdhci_sprd_remove()
715 clk_disable_unprepare(sprd_host->clk_enable); in sdhci_sprd_remove()
716 clk_disable_unprepare(sprd_host->clk_2x_enable); in sdhci_sprd_remove()
718 mmc_free_host(mmc); in sdhci_sprd_remove()
724 { .compatible = "sprd,sdhci-r11", },
735 mmc_hsq_suspend(host->mmc); in sdhci_sprd_runtime_suspend()
738 clk_disable_unprepare(sprd_host->clk_sdio); in sdhci_sprd_runtime_suspend()
739 clk_disable_unprepare(sprd_host->clk_enable); in sdhci_sprd_runtime_suspend()
740 clk_disable_unprepare(sprd_host->clk_2x_enable); in sdhci_sprd_runtime_suspend()
751 ret = clk_prepare_enable(sprd_host->clk_2x_enable); in sdhci_sprd_runtime_resume()
755 ret = clk_prepare_enable(sprd_host->clk_enable); in sdhci_sprd_runtime_resume()
759 ret = clk_prepare_enable(sprd_host->clk_sdio); in sdhci_sprd_runtime_resume()
764 mmc_hsq_resume(host->mmc); in sdhci_sprd_runtime_resume()
769 clk_disable_unprepare(sprd_host->clk_enable); in sdhci_sprd_runtime_resume()
772 clk_disable_unprepare(sprd_host->clk_2x_enable); in sdhci_sprd_runtime_resume()
799 MODULE_ALIAS("platform:sdhci-sprd-r11");