Lines Matching +full:sdhci +full:- +full:8
1 // SPDX-License-Identifier: GPL-2.0-only
7 #include <linux/dma-mapping.h>
23 #include <linux/mmc/slot-gpio.h>
27 #include "sdhci-pltfm.h"
45 #define SDHCI_TEGRA_CAP_OVERRIDES_DQS_TRIM_SHIFT 8
110 #define NVQUIRK_DIS_CARD_CLK_CONFIG_TAP BIT(8)
176 const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; in tegra_sdhci_readw()
178 if (unlikely((soc_data->nvquirks & NVQUIRK_FORCE_SDHCI_SPEC_200) && in tegra_sdhci_readw()
184 return readw(host->ioaddr + reg); in tegra_sdhci_readw()
197 pltfm_host->xfer_mode_shadow = val; in tegra_sdhci_writew()
200 writel((val << 16) | pltfm_host->xfer_mode_shadow, in tegra_sdhci_writew()
201 host->ioaddr + SDHCI_TRANSFER_MODE); in tegra_sdhci_writew()
205 writew(val, host->ioaddr + reg); in tegra_sdhci_writew()
212 const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; in tegra_sdhci_writel()
221 writel(val, host->ioaddr + reg); in tegra_sdhci_writel()
223 if (unlikely((soc_data->nvquirks & NVQUIRK_ENABLE_BLOCK_GAP_DET) && in tegra_sdhci_writel()
226 u8 gap_ctrl = readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL); in tegra_sdhci_writel()
231 writeb(gap_ctrl, host->ioaddr + SDHCI_BLOCK_GAP_CONTROL); in tegra_sdhci_writel()
271 writew(val, host->ioaddr + reg); in tegra210_sdhci_writew()
283 * Write-enable shall be assumed if GPIO is missing in a board's in tegra_sdhci_get_ro()
284 * device-tree because SDHCI's WRITE_PROTECT bit doesn't work on in tegra_sdhci_get_ro()
287 return mmc_gpio_get_ro(host->mmc); in tegra_sdhci_get_ro()
299 * means that valid pinctrl info is required on SDHCI instances capable in tegra_sdhci_is_pad_and_regulator_valid()
300 * of performing voltage switching. Whether or not an SDHCI instance is in tegra_sdhci_is_pad_and_regulator_valid()
304 if (!(tegra_host->soc_data->nvquirks & NVQUIRK_NEEDS_PAD_CONTROL)) in tegra_sdhci_is_pad_and_regulator_valid()
307 if (IS_ERR(host->mmc->supply.vqmmc)) in tegra_sdhci_is_pad_and_regulator_valid()
310 has_1v8 = regulator_is_supported_voltage(host->mmc->supply.vqmmc, in tegra_sdhci_is_pad_and_regulator_valid()
313 has_3v3 = regulator_is_supported_voltage(host->mmc->supply.vqmmc, in tegra_sdhci_is_pad_and_regulator_valid()
317 return tegra_host->pad_control_available; in tegra_sdhci_is_pad_and_regulator_valid()
327 const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; in tegra_sdhci_set_tap()
337 if (soc_data->nvquirks & NVQUIRK_DIS_CARD_CLK_CONFIG_TAP) in tegra_sdhci_set_tap()
345 if (soc_data->nvquirks & NVQUIRK_DIS_CARD_CLK_CONFIG_TAP && in tegra_sdhci_set_tap()
361 if (ios->enhanced_strobe) in tegra_sdhci_hs400_enhanced_strobe()
374 const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; in tegra_sdhci_reset()
382 tegra_sdhci_set_tap(host, tegra_host->default_tap); in tegra_sdhci_reset()
396 /* Erratum: Enable SDHCI spec v3.00 support */ in tegra_sdhci_reset()
397 if (soc_data->nvquirks & NVQUIRK_ENABLE_SDHCI_SPEC_300) in tegra_sdhci_reset()
400 if (soc_data->nvquirks & NVQUIRK_ENABLE_SDR50) in tegra_sdhci_reset()
402 if (soc_data->nvquirks & NVQUIRK_ENABLE_DDR50) in tegra_sdhci_reset()
404 if (soc_data->nvquirks & NVQUIRK_ENABLE_SDR104) in tegra_sdhci_reset()
406 if (soc_data->nvquirks & NVQUIRK_ENABLE_SDR50) in tegra_sdhci_reset()
410 clk_ctrl |= tegra_host->default_trim << SDHCI_CLOCK_CTRL_TRIM_SHIFT; in tegra_sdhci_reset()
415 if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB) { in tegra_sdhci_reset()
421 tegra_host->pad_calib_required = true; in tegra_sdhci_reset()
424 tegra_host->ddr_signaling = false; in tegra_sdhci_reset()
465 &tegra_host->autocal_offsets; in tegra_sdhci_set_padctrl()
474 if (tegra_host->pinctrl_state_1v8_drv) { in tegra_sdhci_set_padctrl()
476 tegra_host->pinctrl_state_1v8_drv; in tegra_sdhci_set_padctrl()
478 drvup = offsets->pull_up_1v8_timeout; in tegra_sdhci_set_padctrl()
479 drvdn = offsets->pull_down_1v8_timeout; in tegra_sdhci_set_padctrl()
482 if (tegra_host->pinctrl_state_3v3_drv) { in tegra_sdhci_set_padctrl()
484 tegra_host->pinctrl_state_3v3_drv; in tegra_sdhci_set_padctrl()
486 drvup = offsets->pull_up_3v3_timeout; in tegra_sdhci_set_padctrl()
487 drvdn = offsets->pull_down_3v3_timeout; in tegra_sdhci_set_padctrl()
492 ret = pinctrl_select_state(tegra_host->pinctrl_sdmmc, in tegra_sdhci_set_padctrl()
495 dev_err(mmc_dev(host->mmc), in tegra_sdhci_set_padctrl()
508 if (!tegra_host->pad_control_available) in tegra_sdhci_set_padctrl()
512 ret = pinctrl_select_state(tegra_host->pinctrl_sdmmc, in tegra_sdhci_set_padctrl()
513 tegra_host->pinctrl_state_1v8); in tegra_sdhci_set_padctrl()
515 dev_err(mmc_dev(host->mmc), in tegra_sdhci_set_padctrl()
518 ret = pinctrl_select_state(tegra_host->pinctrl_sdmmc, in tegra_sdhci_set_padctrl()
519 tegra_host->pinctrl_state_3v3); in tegra_sdhci_set_padctrl()
521 dev_err(mmc_dev(host->mmc), in tegra_sdhci_set_padctrl()
534 tegra_host->autocal_offsets; in tegra_sdhci_pad_autocalib()
535 struct mmc_ios *ios = &host->mmc->ios; in tegra_sdhci_pad_autocalib()
541 switch (ios->timing) { in tegra_sdhci_pad_autocalib()
543 pdpu = offsets.pull_down_sdr104 << 8 | offsets.pull_up_sdr104; in tegra_sdhci_pad_autocalib()
546 pdpu = offsets.pull_down_hs400 << 8 | offsets.pull_up_hs400; in tegra_sdhci_pad_autocalib()
549 if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) in tegra_sdhci_pad_autocalib()
550 pdpu = offsets.pull_down_1v8 << 8 | offsets.pull_up_1v8; in tegra_sdhci_pad_autocalib()
552 pdpu = offsets.pull_down_3v3 << 8 | offsets.pull_up_3v3; in tegra_sdhci_pad_autocalib()
555 /* Set initial offset before auto-calibration */ in tegra_sdhci_pad_autocalib()
568 ret = readl_poll_timeout(host->ioaddr + SDHCI_TEGRA_AUTO_CAL_STATUS, in tegra_sdhci_pad_autocalib()
577 dev_err(mmc_dev(host->mmc), "Pad autocal timed out\n"); in tegra_sdhci_pad_autocalib()
584 ret = tegra_sdhci_set_padctrl(host, ios->signal_voltage, false); in tegra_sdhci_pad_autocalib()
586 dev_err(mmc_dev(host->mmc), in tegra_sdhci_pad_autocalib()
596 &tegra_host->autocal_offsets; in tegra_sdhci_parse_pad_autocal_dt()
599 err = device_property_read_u32(host->mmc->parent, in tegra_sdhci_parse_pad_autocal_dt()
600 "nvidia,pad-autocal-pull-up-offset-3v3", in tegra_sdhci_parse_pad_autocal_dt()
601 &autocal->pull_up_3v3); in tegra_sdhci_parse_pad_autocal_dt()
603 autocal->pull_up_3v3 = 0; in tegra_sdhci_parse_pad_autocal_dt()
605 err = device_property_read_u32(host->mmc->parent, in tegra_sdhci_parse_pad_autocal_dt()
606 "nvidia,pad-autocal-pull-down-offset-3v3", in tegra_sdhci_parse_pad_autocal_dt()
607 &autocal->pull_down_3v3); in tegra_sdhci_parse_pad_autocal_dt()
609 autocal->pull_down_3v3 = 0; in tegra_sdhci_parse_pad_autocal_dt()
611 err = device_property_read_u32(host->mmc->parent, in tegra_sdhci_parse_pad_autocal_dt()
612 "nvidia,pad-autocal-pull-up-offset-1v8", in tegra_sdhci_parse_pad_autocal_dt()
613 &autocal->pull_up_1v8); in tegra_sdhci_parse_pad_autocal_dt()
615 autocal->pull_up_1v8 = 0; in tegra_sdhci_parse_pad_autocal_dt()
617 err = device_property_read_u32(host->mmc->parent, in tegra_sdhci_parse_pad_autocal_dt()
618 "nvidia,pad-autocal-pull-down-offset-1v8", in tegra_sdhci_parse_pad_autocal_dt()
619 &autocal->pull_down_1v8); in tegra_sdhci_parse_pad_autocal_dt()
621 autocal->pull_down_1v8 = 0; in tegra_sdhci_parse_pad_autocal_dt()
623 err = device_property_read_u32(host->mmc->parent, in tegra_sdhci_parse_pad_autocal_dt()
624 "nvidia,pad-autocal-pull-up-offset-sdr104", in tegra_sdhci_parse_pad_autocal_dt()
625 &autocal->pull_up_sdr104); in tegra_sdhci_parse_pad_autocal_dt()
627 autocal->pull_up_sdr104 = autocal->pull_up_1v8; in tegra_sdhci_parse_pad_autocal_dt()
629 err = device_property_read_u32(host->mmc->parent, in tegra_sdhci_parse_pad_autocal_dt()
630 "nvidia,pad-autocal-pull-down-offset-sdr104", in tegra_sdhci_parse_pad_autocal_dt()
631 &autocal->pull_down_sdr104); in tegra_sdhci_parse_pad_autocal_dt()
633 autocal->pull_down_sdr104 = autocal->pull_down_1v8; in tegra_sdhci_parse_pad_autocal_dt()
635 err = device_property_read_u32(host->mmc->parent, in tegra_sdhci_parse_pad_autocal_dt()
636 "nvidia,pad-autocal-pull-up-offset-hs400", in tegra_sdhci_parse_pad_autocal_dt()
637 &autocal->pull_up_hs400); in tegra_sdhci_parse_pad_autocal_dt()
639 autocal->pull_up_hs400 = autocal->pull_up_1v8; in tegra_sdhci_parse_pad_autocal_dt()
641 err = device_property_read_u32(host->mmc->parent, in tegra_sdhci_parse_pad_autocal_dt()
642 "nvidia,pad-autocal-pull-down-offset-hs400", in tegra_sdhci_parse_pad_autocal_dt()
643 &autocal->pull_down_hs400); in tegra_sdhci_parse_pad_autocal_dt()
645 autocal->pull_down_hs400 = autocal->pull_down_1v8; in tegra_sdhci_parse_pad_autocal_dt()
648 * Different fail-safe drive strength values based on the signaling in tegra_sdhci_parse_pad_autocal_dt()
653 if (!(tegra_host->soc_data->nvquirks & NVQUIRK_NEEDS_PAD_CONTROL)) in tegra_sdhci_parse_pad_autocal_dt()
656 err = device_property_read_u32(host->mmc->parent, in tegra_sdhci_parse_pad_autocal_dt()
657 "nvidia,pad-autocal-pull-up-offset-3v3-timeout", in tegra_sdhci_parse_pad_autocal_dt()
658 &autocal->pull_up_3v3_timeout); in tegra_sdhci_parse_pad_autocal_dt()
660 if (!IS_ERR(tegra_host->pinctrl_state_3v3) && in tegra_sdhci_parse_pad_autocal_dt()
661 (tegra_host->pinctrl_state_3v3_drv == NULL)) in tegra_sdhci_parse_pad_autocal_dt()
662 pr_warn("%s: Missing autocal timeout 3v3-pad drvs\n", in tegra_sdhci_parse_pad_autocal_dt()
663 mmc_hostname(host->mmc)); in tegra_sdhci_parse_pad_autocal_dt()
664 autocal->pull_up_3v3_timeout = 0; in tegra_sdhci_parse_pad_autocal_dt()
667 err = device_property_read_u32(host->mmc->parent, in tegra_sdhci_parse_pad_autocal_dt()
668 "nvidia,pad-autocal-pull-down-offset-3v3-timeout", in tegra_sdhci_parse_pad_autocal_dt()
669 &autocal->pull_down_3v3_timeout); in tegra_sdhci_parse_pad_autocal_dt()
671 if (!IS_ERR(tegra_host->pinctrl_state_3v3) && in tegra_sdhci_parse_pad_autocal_dt()
672 (tegra_host->pinctrl_state_3v3_drv == NULL)) in tegra_sdhci_parse_pad_autocal_dt()
673 pr_warn("%s: Missing autocal timeout 3v3-pad drvs\n", in tegra_sdhci_parse_pad_autocal_dt()
674 mmc_hostname(host->mmc)); in tegra_sdhci_parse_pad_autocal_dt()
675 autocal->pull_down_3v3_timeout = 0; in tegra_sdhci_parse_pad_autocal_dt()
678 err = device_property_read_u32(host->mmc->parent, in tegra_sdhci_parse_pad_autocal_dt()
679 "nvidia,pad-autocal-pull-up-offset-1v8-timeout", in tegra_sdhci_parse_pad_autocal_dt()
680 &autocal->pull_up_1v8_timeout); in tegra_sdhci_parse_pad_autocal_dt()
682 if (!IS_ERR(tegra_host->pinctrl_state_1v8) && in tegra_sdhci_parse_pad_autocal_dt()
683 (tegra_host->pinctrl_state_1v8_drv == NULL)) in tegra_sdhci_parse_pad_autocal_dt()
684 pr_warn("%s: Missing autocal timeout 1v8-pad drvs\n", in tegra_sdhci_parse_pad_autocal_dt()
685 mmc_hostname(host->mmc)); in tegra_sdhci_parse_pad_autocal_dt()
686 autocal->pull_up_1v8_timeout = 0; in tegra_sdhci_parse_pad_autocal_dt()
689 err = device_property_read_u32(host->mmc->parent, in tegra_sdhci_parse_pad_autocal_dt()
690 "nvidia,pad-autocal-pull-down-offset-1v8-timeout", in tegra_sdhci_parse_pad_autocal_dt()
691 &autocal->pull_down_1v8_timeout); in tegra_sdhci_parse_pad_autocal_dt()
693 if (!IS_ERR(tegra_host->pinctrl_state_1v8) && in tegra_sdhci_parse_pad_autocal_dt()
694 (tegra_host->pinctrl_state_1v8_drv == NULL)) in tegra_sdhci_parse_pad_autocal_dt()
695 pr_warn("%s: Missing autocal timeout 1v8-pad drvs\n", in tegra_sdhci_parse_pad_autocal_dt()
696 mmc_hostname(host->mmc)); in tegra_sdhci_parse_pad_autocal_dt()
697 autocal->pull_down_1v8_timeout = 0; in tegra_sdhci_parse_pad_autocal_dt()
706 ktime_t since_calib = ktime_sub(ktime_get(), tegra_host->last_calib); in tegra_sdhci_request()
711 tegra_host->last_calib = ktime_get(); in tegra_sdhci_request()
723 err = device_property_read_u32(host->mmc->parent, "nvidia,default-tap", in tegra_sdhci_parse_tap_and_trim()
724 &tegra_host->default_tap); in tegra_sdhci_parse_tap_and_trim()
726 tegra_host->default_tap = 0; in tegra_sdhci_parse_tap_and_trim()
728 err = device_property_read_u32(host->mmc->parent, "nvidia,default-trim", in tegra_sdhci_parse_tap_and_trim()
729 &tegra_host->default_trim); in tegra_sdhci_parse_tap_and_trim()
731 tegra_host->default_trim = 0; in tegra_sdhci_parse_tap_and_trim()
733 err = device_property_read_u32(host->mmc->parent, "nvidia,dqs-trim", in tegra_sdhci_parse_tap_and_trim()
734 &tegra_host->dqs_trim); in tegra_sdhci_parse_tap_and_trim()
736 tegra_host->dqs_trim = 0x11; in tegra_sdhci_parse_tap_and_trim()
744 if (device_property_read_bool(host->mmc->parent, "supports-cqe")) in tegra_sdhci_parse_dt()
745 tegra_host->enable_hwcq = true; in tegra_sdhci_parse_dt()
747 tegra_host->enable_hwcq = false; in tegra_sdhci_parse_dt()
763 * In DDR50/52 modes the Tegra SDHCI controllers require the SDHCI in tegra_sdhci_set_clock()
764 * divider to be configured to divided the host clock by two. The SDHCI in tegra_sdhci_set_clock()
766 * sdhci_calc_clk(). The divider is calculated from host->max_clk and in tegra_sdhci_set_clock()
769 * By setting the host->max_clk to clock * 2 the divider calculation in tegra_sdhci_set_clock()
774 host_clk = tegra_host->ddr_signaling ? clock * 2 : clock; in tegra_sdhci_set_clock()
775 clk_set_rate(pltfm_host->clk, host_clk); in tegra_sdhci_set_clock()
776 tegra_host->curr_clk_rate = host_clk; in tegra_sdhci_set_clock()
777 if (tegra_host->ddr_signaling) in tegra_sdhci_set_clock()
778 host->max_clk = host_clk; in tegra_sdhci_set_clock()
780 host->max_clk = clk_get_rate(pltfm_host->clk); in tegra_sdhci_set_clock()
784 if (tegra_host->pad_calib_required) { in tegra_sdhci_set_clock()
786 tegra_host->pad_calib_required = false; in tegra_sdhci_set_clock()
794 return clk_round_rate(pltfm_host->clk, UINT_MAX); in tegra_sdhci_get_max_clock()
817 err = readl_poll_timeout(host->ioaddr + SDHCI_TEGRA_VENDOR_DLLCAL_STA, in tegra_sdhci_hs400_dll_cal()
821 dev_err(mmc_dev(host->mmc), in tegra_sdhci_hs400_dll_cal()
842 u8 total_tuning_words = host->tuning_loop_count / TUNING_WORD_BIT_SIZE; in tegra_sdhci_tap_correction()
845 * Read auto-tuned results and extract good valid passing window by in tegra_sdhci_tap_correction()
846 * filtering out un-wanted bubble/partial/merged windows. in tegra_sdhci_tap_correction()
875 end_pass_tap = tap - 1; in tegra_sdhci_tap_correction()
879 window = end_pass_tap - start_pass_tap; in tegra_sdhci_tap_correction()
887 tegra_host->tuned_tap_delay = tap; in tegra_sdhci_tap_correction()
900 edge1 = first_fail_tap + (first_pass_tap - first_fail_tap) / 2; in tegra_sdhci_tap_correction()
901 if (edge1 - 1 > fixed_tap) in tegra_sdhci_tap_correction()
902 tegra_host->tuned_tap_delay = edge1 - fixed_tap; in tegra_sdhci_tap_correction()
904 tegra_host->tuned_tap_delay = edge1 + fixed_tap; in tegra_sdhci_tap_correction()
912 const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; in tegra_sdhci_post_tuning()
921 tegra_host->tuned_tap_delay = (val & SDHCI_CLOCK_CTRL_TAP_MASK) >> in tegra_sdhci_post_tuning()
923 if (soc_data->min_tap_delay && soc_data->max_tap_delay) { in tegra_sdhci_post_tuning()
924 min_tap_dly = soc_data->min_tap_delay; in tegra_sdhci_post_tuning()
925 max_tap_dly = soc_data->max_tap_delay; in tegra_sdhci_post_tuning()
926 clk_rate_mhz = tegra_host->curr_clk_rate / USEC_PER_SEC; in tegra_sdhci_post_tuning()
947 window_width = end_tap - start_tap; in tegra_sdhci_post_tuning()
948 num_iter = host->tuning_loop_count; in tegra_sdhci_post_tuning()
954 if (start_tap == 0 || (end_tap == (num_iter - 1)) || in tegra_sdhci_post_tuning()
955 (end_tap == num_iter - 2) || window_width >= thdupper) { in tegra_sdhci_post_tuning()
957 mmc_hostname(host->mmc)); in tegra_sdhci_post_tuning()
963 tegra_sdhci_set_tap(host, tegra_host->tuned_tap_delay); in tegra_sdhci_post_tuning()
972 if (!err && !host->tuning_err) in tegra_sdhci_execute_hw_tuning()
989 tegra_host->ddr_signaling = false; in tegra_sdhci_set_uhs_signaling()
1005 tegra_host->ddr_signaling = true; in tegra_sdhci_set_uhs_signaling()
1023 host->tuning_loop_count = (iter == TRIES_128) ? 128 : 256; in tegra_sdhci_set_uhs_signaling()
1029 if (tegra_host->tuned_tap_delay && !set_default_tap) in tegra_sdhci_set_uhs_signaling()
1030 tegra_sdhci_set_tap(host, tegra_host->tuned_tap_delay); in tegra_sdhci_set_uhs_signaling()
1032 tegra_sdhci_set_tap(host, tegra_host->default_tap); in tegra_sdhci_set_uhs_signaling()
1035 tegra_sdhci_set_dqs_trim(host, tegra_host->dqs_trim); in tegra_sdhci_set_uhs_signaling()
1053 if (!mmc_send_tuning(host->mmc, opcode, NULL)) in tegra_sdhci_execute_tuning()
1062 if (mmc_send_tuning(host->mmc, opcode, NULL)) { in tegra_sdhci_execute_tuning()
1063 max--; in tegra_sdhci_execute_tuning()
1070 tegra_sdhci_set_tap(host, min + ((max - min) * 3 / 4)); in tegra_sdhci_execute_tuning()
1072 return mmc_send_tuning(host->mmc, opcode, NULL); in tegra_sdhci_execute_tuning()
1083 if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) { in sdhci_tegra_start_signal_voltage_switch()
1084 ret = tegra_sdhci_set_padctrl(host, ios->signal_voltage, true); in sdhci_tegra_start_signal_voltage_switch()
1088 } else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) { in sdhci_tegra_start_signal_voltage_switch()
1092 ret = tegra_sdhci_set_padctrl(host, ios->signal_voltage, true); in sdhci_tegra_start_signal_voltage_switch()
1095 if (tegra_host->pad_calib_required) in sdhci_tegra_start_signal_voltage_switch()
1104 tegra_host->pinctrl_sdmmc = devm_pinctrl_get(dev); in tegra_sdhci_init_pinctrl_info()
1105 if (IS_ERR(tegra_host->pinctrl_sdmmc)) { in tegra_sdhci_init_pinctrl_info()
1107 PTR_ERR(tegra_host->pinctrl_sdmmc)); in tegra_sdhci_init_pinctrl_info()
1108 return -1; in tegra_sdhci_init_pinctrl_info()
1111 tegra_host->pinctrl_state_1v8_drv = pinctrl_lookup_state( in tegra_sdhci_init_pinctrl_info()
1112 tegra_host->pinctrl_sdmmc, "sdmmc-1v8-drv"); in tegra_sdhci_init_pinctrl_info()
1113 if (IS_ERR(tegra_host->pinctrl_state_1v8_drv)) { in tegra_sdhci_init_pinctrl_info()
1114 if (PTR_ERR(tegra_host->pinctrl_state_1v8_drv) == -ENODEV) in tegra_sdhci_init_pinctrl_info()
1115 tegra_host->pinctrl_state_1v8_drv = NULL; in tegra_sdhci_init_pinctrl_info()
1118 tegra_host->pinctrl_state_3v3_drv = pinctrl_lookup_state( in tegra_sdhci_init_pinctrl_info()
1119 tegra_host->pinctrl_sdmmc, "sdmmc-3v3-drv"); in tegra_sdhci_init_pinctrl_info()
1120 if (IS_ERR(tegra_host->pinctrl_state_3v3_drv)) { in tegra_sdhci_init_pinctrl_info()
1121 if (PTR_ERR(tegra_host->pinctrl_state_3v3_drv) == -ENODEV) in tegra_sdhci_init_pinctrl_info()
1122 tegra_host->pinctrl_state_3v3_drv = NULL; in tegra_sdhci_init_pinctrl_info()
1125 tegra_host->pinctrl_state_3v3 = in tegra_sdhci_init_pinctrl_info()
1126 pinctrl_lookup_state(tegra_host->pinctrl_sdmmc, "sdmmc-3v3"); in tegra_sdhci_init_pinctrl_info()
1127 if (IS_ERR(tegra_host->pinctrl_state_3v3)) { in tegra_sdhci_init_pinctrl_info()
1129 PTR_ERR(tegra_host->pinctrl_state_3v3)); in tegra_sdhci_init_pinctrl_info()
1130 return -1; in tegra_sdhci_init_pinctrl_info()
1133 tegra_host->pinctrl_state_1v8 = in tegra_sdhci_init_pinctrl_info()
1134 pinctrl_lookup_state(tegra_host->pinctrl_sdmmc, "sdmmc-1v8"); in tegra_sdhci_init_pinctrl_info()
1135 if (IS_ERR(tegra_host->pinctrl_state_1v8)) { in tegra_sdhci_init_pinctrl_info()
1137 PTR_ERR(tegra_host->pinctrl_state_1v8)); in tegra_sdhci_init_pinctrl_info()
1138 return -1; in tegra_sdhci_init_pinctrl_info()
1141 tegra_host->pad_control_available = true; in tegra_sdhci_init_pinctrl_info()
1150 const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; in tegra_sdhci_voltage_switch()
1152 if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB) in tegra_sdhci_voltage_switch()
1153 tegra_host->pad_calib_required = true; in tegra_sdhci_voltage_switch()
1158 struct mmc_host *mmc = cq_host->mmc; in tegra_cqhci_writel()
1165 * cqhci_host_ops enable where SDHCI DMA and BLOCK_SIZE registers need in tegra_cqhci_writel()
1166 * to be re-configured. in tegra_cqhci_writel()
1167 * Tegra CQHCI/SDHCI prevents write access to block size register when in tegra_cqhci_writel()
1169 * SDHCI block registers prior to exiting CQE halt state. in tegra_cqhci_writel()
1174 writel(val, cq_host->mmio + reg); in tegra_cqhci_writel()
1187 writel(val, cq_host->mmio + reg); in tegra_cqhci_writel()
1189 writel(val, cq_host->mmio + reg); in tegra_cqhci_writel()
1198 const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; in sdhci_tegra_update_dcmd_desc()
1200 if (soc_data->nvquirks & NVQUIRK_CQHCI_DCMD_R1B_CMD_TIMING && in sdhci_tegra_update_dcmd_desc()
1201 mrq->cmd->flags & MMC_RSP_R1B) in sdhci_tegra_update_dcmd_desc()
1207 struct cqhci_host *cq_host = mmc->cqe_private; in sdhci_tegra_cqe_enable()
1211 * Tegra CQHCI/SDMMC design prevents write access to sdhci block size in sdhci_tegra_cqe_enable()
1214 * programming block size in sdhci controller and enable it back. in sdhci_tegra_cqe_enable()
1216 if (!cq_host->activated) { in sdhci_tegra_cqe_enable()
1251 cqhci_irq(host->mmc, intmask, cmd_error, data_error); in sdhci_tegra_cqhci_irq()
1275 if (cmd && cmd->busy_timeout >= 11 * HZ) in tegra_sdhci_set_timeout()
1296 const struct sdhci_tegra_soc_data *soc = tegra->soc_data; in tegra_sdhci_set_dma_mask()
1297 struct device *dev = mmc_dev(host->mmc); in tegra_sdhci_set_dma_mask()
1299 if (soc->dma_mask) in tegra_sdhci_set_dma_mask()
1300 return dma_set_mask_and_coherent(dev, soc->dma_mask); in tegra_sdhci_set_dma_mask()
1345 * Auto-CMD23 leads to "Got command interrupt 0x00010000 even
1502 { .compatible = "nvidia,tegra194-sdhci", .data = &soc_data_tegra194 },
1503 { .compatible = "nvidia,tegra186-sdhci", .data = &soc_data_tegra186 },
1504 { .compatible = "nvidia,tegra210-sdhci", .data = &soc_data_tegra210 },
1505 { .compatible = "nvidia,tegra124-sdhci", .data = &soc_data_tegra124 },
1506 { .compatible = "nvidia,tegra114-sdhci", .data = &soc_data_tegra114 },
1507 { .compatible = "nvidia,tegra30-sdhci", .data = &soc_data_tegra30 },
1508 { .compatible = "nvidia,tegra20-sdhci", .data = &soc_data_tegra20 },
1521 if (!tegra_host->enable_hwcq) in sdhci_tegra_add_host()
1530 host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD; in sdhci_tegra_add_host()
1532 cq_host = devm_kzalloc(host->mmc->parent, in sdhci_tegra_add_host()
1535 ret = -ENOMEM; in sdhci_tegra_add_host()
1539 cq_host->mmio = host->ioaddr + SDHCI_TEGRA_CQE_BASE_ADDR; in sdhci_tegra_add_host()
1540 cq_host->ops = &sdhci_tegra_cqhci_ops; in sdhci_tegra_add_host()
1542 dma64 = host->flags & SDHCI_USE_64_BIT_DMA; in sdhci_tegra_add_host()
1544 cq_host->caps |= CQHCI_TASK_DESC_SZ_128; in sdhci_tegra_add_host()
1546 ret = cqhci_init(cq_host, host->mmc, dma64); in sdhci_tegra_add_host()
1571 match = of_match_device(sdhci_tegra_dt_match, &pdev->dev); in sdhci_tegra_probe()
1573 return -EINVAL; in sdhci_tegra_probe()
1574 soc_data = match->data; in sdhci_tegra_probe()
1576 host = sdhci_pltfm_init(pdev, soc_data->pdata, sizeof(*tegra_host)); in sdhci_tegra_probe()
1582 tegra_host->ddr_signaling = false; in sdhci_tegra_probe()
1583 tegra_host->pad_calib_required = false; in sdhci_tegra_probe()
1584 tegra_host->pad_control_available = false; in sdhci_tegra_probe()
1585 tegra_host->soc_data = soc_data; in sdhci_tegra_probe()
1587 if (soc_data->nvquirks & NVQUIRK_NEEDS_PAD_CONTROL) { in sdhci_tegra_probe()
1588 rc = tegra_sdhci_init_pinctrl_info(&pdev->dev, tegra_host); in sdhci_tegra_probe()
1590 host->mmc_host_ops.start_signal_voltage_switch = in sdhci_tegra_probe()
1595 if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB) in sdhci_tegra_probe()
1596 host->mmc_host_ops.request = tegra_sdhci_request; in sdhci_tegra_probe()
1598 host->mmc_host_ops.hs400_enhanced_strobe = in sdhci_tegra_probe()
1601 if (!host->ops->platform_execute_tuning) in sdhci_tegra_probe()
1602 host->mmc_host_ops.execute_tuning = in sdhci_tegra_probe()
1605 rc = mmc_of_parse(host->mmc); in sdhci_tegra_probe()
1609 if (tegra_host->soc_data->nvquirks & NVQUIRK_ENABLE_DDR50) in sdhci_tegra_probe()
1610 host->mmc->caps |= MMC_CAP_1_8V_DDR; in sdhci_tegra_probe()
1613 host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY; in sdhci_tegra_probe()
1617 tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power", in sdhci_tegra_probe()
1619 if (IS_ERR(tegra_host->power_gpio)) { in sdhci_tegra_probe()
1620 rc = PTR_ERR(tegra_host->power_gpio); in sdhci_tegra_probe()
1639 if (soc_data->nvquirks & NVQUIRK_HAS_TMCLK) { in sdhci_tegra_probe()
1640 clk = devm_clk_get(&pdev->dev, "tmclk"); in sdhci_tegra_probe()
1643 if (rc == -EPROBE_DEFER) in sdhci_tegra_probe()
1646 dev_warn(&pdev->dev, "failed to get tmclk: %d\n", rc); in sdhci_tegra_probe()
1653 dev_err(&pdev->dev, in sdhci_tegra_probe()
1658 tegra_host->tmclk = clk; in sdhci_tegra_probe()
1661 clk = devm_clk_get(mmc_dev(host->mmc), NULL); in sdhci_tegra_probe()
1663 rc = dev_err_probe(&pdev->dev, PTR_ERR(clk), in sdhci_tegra_probe()
1668 pltfm_host->clk = clk; in sdhci_tegra_probe()
1670 tegra_host->rst = devm_reset_control_get_exclusive(&pdev->dev, in sdhci_tegra_probe()
1671 "sdhci"); in sdhci_tegra_probe()
1672 if (IS_ERR(tegra_host->rst)) { in sdhci_tegra_probe()
1673 rc = PTR_ERR(tegra_host->rst); in sdhci_tegra_probe()
1674 dev_err(&pdev->dev, "failed to get reset control: %d\n", rc); in sdhci_tegra_probe()
1678 rc = reset_control_assert(tegra_host->rst); in sdhci_tegra_probe()
1684 rc = reset_control_deassert(tegra_host->rst); in sdhci_tegra_probe()
1697 reset_control_assert(tegra_host->rst); in sdhci_tegra_probe()
1699 clk_disable_unprepare(pltfm_host->clk); in sdhci_tegra_probe()
1701 clk_disable_unprepare(tegra_host->tmclk); in sdhci_tegra_probe()
1716 reset_control_assert(tegra_host->rst); in sdhci_tegra_remove()
1718 clk_disable_unprepare(pltfm_host->clk); in sdhci_tegra_remove()
1719 clk_disable_unprepare(tegra_host->tmclk); in sdhci_tegra_remove()
1733 if (host->mmc->caps2 & MMC_CAP2_CQE) { in sdhci_tegra_suspend()
1734 ret = cqhci_suspend(host->mmc); in sdhci_tegra_suspend()
1741 cqhci_resume(host->mmc); in sdhci_tegra_suspend()
1745 clk_disable_unprepare(pltfm_host->clk); in sdhci_tegra_suspend()
1755 ret = clk_prepare_enable(pltfm_host->clk); in sdhci_tegra_resume()
1763 if (host->mmc->caps2 & MMC_CAP2_CQE) { in sdhci_tegra_resume()
1764 ret = cqhci_resume(host->mmc); in sdhci_tegra_resume()
1774 clk_disable_unprepare(pltfm_host->clk); in sdhci_tegra_resume()
1784 .name = "sdhci-tegra",
1795 MODULE_DESCRIPTION("SDHCI driver for Tegra");