Lines Matching +full:mmc +full:- +full:host
1 // SPDX-License-Identifier: GPL-2.0
3 // Secure Digital Host Controller
9 #include <linux/dma-mapping.h>
12 #include <linux/mmc/host.h>
13 #include <linux/mmc/mmc.h>
22 #include "sdhci-pltfm.h"
90 int flags; /* backup of host attribute */
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, },
116 #define TO_SPRD_HOST(host) sdhci_pltfm_priv(sdhci_priv(host)) argument
118 static void sdhci_sprd_init_config(struct sdhci_host *host) in sdhci_sprd_init_config() argument
123 val = sdhci_readl(host, SDHCI_SPRD_REG_DEBOUNCE); in sdhci_sprd_init_config()
125 sdhci_writel(host, val, SDHCI_SPRD_REG_DEBOUNCE); in sdhci_sprd_init_config()
128 static inline u32 sdhci_sprd_readl(struct sdhci_host *host, int reg) in sdhci_sprd_readl() argument
133 return readl_relaxed(host->ioaddr + reg); in sdhci_sprd_readl()
136 static inline void sdhci_sprd_writel(struct sdhci_host *host, u32 val, int reg) in sdhci_sprd_writel() argument
145 writel_relaxed(val, host->ioaddr + reg); in sdhci_sprd_writel()
148 static inline void sdhci_sprd_writew(struct sdhci_host *host, u16 val, int reg) in sdhci_sprd_writew() argument
154 writew_relaxed(val, host->ioaddr + reg); in sdhci_sprd_writew()
157 static inline void sdhci_sprd_writeb(struct sdhci_host *host, u8 val, int reg) in sdhci_sprd_writeb() argument
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()
175 static inline void sdhci_sprd_sd_clk_off(struct sdhci_host *host) in sdhci_sprd_sd_clk_off() argument
177 u16 ctrl = sdhci_readw(host, SDHCI_CLOCK_CONTROL); in sdhci_sprd_sd_clk_off()
180 sdhci_writew(host, ctrl, SDHCI_CLOCK_CONTROL); in sdhci_sprd_sd_clk_off()
183 static inline void sdhci_sprd_sd_clk_on(struct sdhci_host *host) in sdhci_sprd_sd_clk_on() argument
187 ctrl = sdhci_readw(host, SDHCI_CLOCK_CONTROL); in sdhci_sprd_sd_clk_on()
189 sdhci_writew(host, ctrl, SDHCI_CLOCK_CONTROL); in sdhci_sprd_sd_clk_on()
193 sdhci_sprd_set_dll_invert(struct sdhci_host *host, u32 mask, bool en) in sdhci_sprd_set_dll_invert() argument
197 dll_dly_offset = sdhci_readl(host, SDHCI_SPRD_REG_32_DLL_DLY_OFFSET); in sdhci_sprd_set_dll_invert()
202 sdhci_writel(host, dll_dly_offset, SDHCI_SPRD_REG_32_DLL_DLY_OFFSET); in sdhci_sprd_set_dll_invert()
229 static inline void _sdhci_sprd_set_clock(struct sdhci_host *host, in _sdhci_sprd_set_clock() argument
232 struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host); in _sdhci_sprd_set_clock()
235 sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); in _sdhci_sprd_set_clock()
237 div = sdhci_sprd_calc_div(sprd_host->base_rate, clk); in _sdhci_sprd_set_clock()
239 sdhci_enable_clk(host, div); in _sdhci_sprd_set_clock()
241 val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI); in _sdhci_sprd_set_clock()
247 sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI); in _sdhci_sprd_set_clock()
252 sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI); in _sdhci_sprd_set_clock()
257 static void sdhci_sprd_enable_phy_dll(struct sdhci_host *host) in sdhci_sprd_enable_phy_dll() argument
261 tmp = sdhci_readl(host, SDHCI_SPRD_REG_32_DLL_CFG); in sdhci_sprd_enable_phy_dll()
263 sdhci_writel(host, tmp, SDHCI_SPRD_REG_32_DLL_CFG); in sdhci_sprd_enable_phy_dll()
267 tmp = sdhci_readl(host, SDHCI_SPRD_REG_32_DLL_CFG); in sdhci_sprd_enable_phy_dll()
270 sdhci_writel(host, tmp, SDHCI_SPRD_REG_32_DLL_CFG); in sdhci_sprd_enable_phy_dll()
274 tmp = sdhci_readl(host, SDHCI_SPRD_REG_32_DLL_CFG); in sdhci_sprd_enable_phy_dll()
276 sdhci_writel(host, tmp, SDHCI_SPRD_REG_32_DLL_CFG); in sdhci_sprd_enable_phy_dll()
281 2000, USEC_PER_SEC, false, host, SDHCI_SPRD_REG_32_DLL_STS0)) { in sdhci_sprd_enable_phy_dll()
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()
285 sdhci_readl(host, SDHCI_SPRD_REG_32_DLL_STS0), in sdhci_sprd_enable_phy_dll()
286 sdhci_readl(host, SDHCI_SPRD_REG_32_DLL_CFG)); in sdhci_sprd_enable_phy_dll()
290 static void sdhci_sprd_set_clock(struct sdhci_host *host, unsigned int clock) in sdhci_sprd_set_clock() argument
295 sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); in sdhci_sprd_set_clock()
296 } else if (clock != host->clock) { in sdhci_sprd_set_clock()
297 sdhci_sprd_sd_clk_off(host); in sdhci_sprd_set_clock()
298 _sdhci_sprd_set_clock(host, clock); in sdhci_sprd_set_clock()
302 sdhci_sprd_set_dll_invert(host, SDHCI_SPRD_BIT_CMD_DLY_INV | in sdhci_sprd_set_clock()
306 _sdhci_sprd_set_clock(host, clock); in sdhci_sprd_set_clock()
310 * According to the Spreadtrum SD host specification, when we changed in sdhci_sprd_set_clock()
316 sdhci_sprd_enable_phy_dll(host); in sdhci_sprd_set_clock()
319 static unsigned int sdhci_sprd_get_max_clock(struct sdhci_host *host) in sdhci_sprd_get_max_clock() argument
321 struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host); in sdhci_sprd_get_max_clock()
323 return clk_round_rate(sprd_host->clk_sdio, ULONG_MAX); in sdhci_sprd_get_max_clock()
326 static unsigned int sdhci_sprd_get_min_clock(struct sdhci_host *host) in sdhci_sprd_get_min_clock() argument
331 static void sdhci_sprd_set_uhs_signaling(struct sdhci_host *host, in sdhci_sprd_set_uhs_signaling() argument
334 struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host); in sdhci_sprd_set_uhs_signaling()
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()
342 ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); in sdhci_sprd_set_uhs_signaling()
343 /* Select Bus Speed Mode for host */ in sdhci_sprd_set_uhs_signaling()
374 sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); in sdhci_sprd_set_uhs_signaling()
376 if (!mmc->ios.enhanced_strobe) in sdhci_sprd_set_uhs_signaling()
377 sdhci_writel(host, p[timing], SDHCI_SPRD_REG_32_DLL_DLY); in sdhci_sprd_set_uhs_signaling()
380 static void sdhci_sprd_hw_reset(struct sdhci_host *host) in sdhci_sprd_hw_reset() argument
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()
401 static unsigned int sdhci_sprd_get_max_timeout_count(struct sdhci_host *host) in sdhci_sprd_get_max_timeout_count() argument
407 static unsigned int sdhci_sprd_get_ro(struct sdhci_host *host) in sdhci_sprd_get_ro() argument
412 static void sdhci_sprd_request_done(struct sdhci_host *host, in sdhci_sprd_request_done() argument
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()
422 static void sdhci_sprd_set_power(struct sdhci_host *host, unsigned char mode, in sdhci_sprd_set_power() argument
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() local
464 struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host); 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()
471 * CMD23 argument on Spreadtrum's sd host controller. 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() local
497 struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host); 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()
540 sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); 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() local
549 struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host); 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()
556 sdhci_sprd_sd_clk_off(host); in sdhci_sprd_hs400_enhanced_strobe()
559 ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); in sdhci_sprd_hs400_enhanced_strobe()
562 sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); in sdhci_sprd_hs400_enhanced_strobe()
564 sdhci_sprd_sd_clk_on(host); in sdhci_sprd_hs400_enhanced_strobe()
567 sdhci_writel(host, p[MMC_TIMING_MMC_HS400 + 1], in sdhci_sprd_hs400_enhanced_strobe()
583 return -ENOMEM; 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() local
631 struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host); in sdhci_sprd_tuning()
632 u32 *p = sprd_host->phy_delay; in sdhci_sprd_tuning()
641 return -ENOMEM; in sdhci_sprd_tuning()
643 sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); in sdhci_sprd_tuning()
645 dll_cfg = sdhci_readl(host, SDHCI_SPRD_REG_32_DLL_CFG); in sdhci_sprd_tuning()
647 sdhci_writel(host, dll_cfg, SDHCI_SPRD_REG_32_DLL_CFG); in sdhci_sprd_tuning()
649 dll_dly = p[mmc->ios.timing]; in sdhci_sprd_tuning()
660 sdhci_writel(host, dll_dly, SDHCI_SPRD_REG_32_DLL_DLY); 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()
733 struct sdhci_host *host; in sdhci_sprd_probe() local
739 host = sdhci_pltfm_init(pdev, &sdhci_sprd_pdata, sizeof(*sprd_host)); in sdhci_sprd_probe()
740 if (IS_ERR(host)) in sdhci_sprd_probe()
741 return PTR_ERR(host); in sdhci_sprd_probe()
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()
755 * signal for Spreadtrum SD host controller, since our voltage regulator in sdhci_sprd_probe()
757 * the standard SD host controller to change the I/O voltage. 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()
774 sprd_host = TO_SPRD_HOST(host); 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()
827 sdhci_sprd_init_config(host); 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()
839 sdhci_enable_v4_mode(host); in sdhci_sprd_probe()
842 * Supply the existing CAPS, but clear the UHS-I modes. This in sdhci_sprd_probe()
846 sdhci_read_caps(host); 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()
854 ret = sdhci_setup_host(host); 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()
870 ret = __sdhci_add_host(host); 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()
880 sdhci_cleanup_host(host); 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()
902 struct sdhci_host *host = platform_get_drvdata(pdev); in sdhci_sprd_remove() local
903 struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host); in sdhci_sprd_remove()
905 sdhci_remove_host(host, 0); in sdhci_sprd_remove()
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", },
923 struct sdhci_host *host = dev_get_drvdata(dev); in sdhci_sprd_runtime_suspend() local
924 struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host); in sdhci_sprd_runtime_suspend()
926 mmc_hsq_suspend(host->mmc); in sdhci_sprd_runtime_suspend()
927 sdhci_runtime_suspend_host(host); 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()
938 struct sdhci_host *host = dev_get_drvdata(dev); in sdhci_sprd_runtime_resume() local
939 struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host); in sdhci_sprd_runtime_resume()
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()
954 sdhci_runtime_resume_host(host, 1); 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()
988 MODULE_DESCRIPTION("Spreadtrum sdio host controller r11 driver");
990 MODULE_ALIAS("platform:sdhci-sprd-r11");