Lines Matching +full:timeout +full:- +full:tap +full:- +full:ms
1 // SPDX-License-Identifier: GPL-2.0-only
9 #include <linux/dma-mapping.h>
20 #include <linux/mmc/slot-gpio.h>
32 #include "sdhci-cqhci.h"
33 #include "sdhci-pltfm.h"
122 * NVQUIRK_HAS_TMCLK is for SoC's having separate timeout clock for Tegra
123 * SDMMC hardware data timeout.
192 const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; in tegra_sdhci_readw()
194 if (unlikely((soc_data->nvquirks & NVQUIRK_FORCE_SDHCI_SPEC_200) && in tegra_sdhci_readw()
200 return readw(host->ioaddr + reg); in tegra_sdhci_readw()
213 pltfm_host->xfer_mode_shadow = val; in tegra_sdhci_writew()
216 writel((val << 16) | pltfm_host->xfer_mode_shadow, in tegra_sdhci_writew()
217 host->ioaddr + SDHCI_TRANSFER_MODE); in tegra_sdhci_writew()
221 writew(val, host->ioaddr + reg); in tegra_sdhci_writew()
228 const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; in tegra_sdhci_writel()
230 /* Seems like we're getting spurious timeout and crc errors, so in tegra_sdhci_writel()
237 writel(val, host->ioaddr + reg); in tegra_sdhci_writel()
239 if (unlikely((soc_data->nvquirks & NVQUIRK_ENABLE_BLOCK_GAP_DET) && in tegra_sdhci_writel()
242 u8 gap_ctrl = readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL); in tegra_sdhci_writel()
247 writeb(gap_ctrl, host->ioaddr + SDHCI_BLOCK_GAP_CONTROL); in tegra_sdhci_writel()
283 writew(val, host->ioaddr + reg); in tegra210_sdhci_writew()
295 * Write-enable shall be assumed if GPIO is missing in a board's in tegra_sdhci_get_ro()
296 * device-tree because SDHCI's WRITE_PROTECT bit doesn't work on in tegra_sdhci_get_ro()
299 return mmc_gpio_get_ro(host->mmc); in tegra_sdhci_get_ro()
316 if (!(tegra_host->soc_data->nvquirks & NVQUIRK_NEEDS_PAD_CONTROL)) in tegra_sdhci_is_pad_and_regulator_valid()
319 if (IS_ERR(host->mmc->supply.vqmmc)) in tegra_sdhci_is_pad_and_regulator_valid()
322 has_1v8 = regulator_is_supported_voltage(host->mmc->supply.vqmmc, in tegra_sdhci_is_pad_and_regulator_valid()
325 has_3v3 = regulator_is_supported_voltage(host->mmc->supply.vqmmc, in tegra_sdhci_is_pad_and_regulator_valid()
329 return tegra_host->pad_control_available; in tegra_sdhci_is_pad_and_regulator_valid()
335 static void tegra_sdhci_set_tap(struct sdhci_host *host, unsigned int tap) in tegra_sdhci_set_tap() argument
339 const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; in tegra_sdhci_set_tap()
344 * Touching the tap values is a bit tricky on some SoC generations. in tegra_sdhci_set_tap()
346 * the tap values are changed. in tegra_sdhci_set_tap()
349 if (soc_data->nvquirks & NVQUIRK_DIS_CARD_CLK_CONFIG_TAP) in tegra_sdhci_set_tap()
354 reg |= tap << SDHCI_CLOCK_CTRL_TAP_SHIFT; in tegra_sdhci_set_tap()
357 if (soc_data->nvquirks & NVQUIRK_DIS_CARD_CLK_CONFIG_TAP && in tegra_sdhci_set_tap()
369 const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; in tegra_sdhci_reset()
377 tegra_sdhci_set_tap(host, tegra_host->default_tap); in tegra_sdhci_reset()
392 if (soc_data->nvquirks & NVQUIRK_ENABLE_SDHCI_SPEC_300) in tegra_sdhci_reset()
395 if (soc_data->nvquirks & NVQUIRK_ENABLE_SDR50) in tegra_sdhci_reset()
397 if (soc_data->nvquirks & NVQUIRK_ENABLE_DDR50) in tegra_sdhci_reset()
399 if (soc_data->nvquirks & NVQUIRK_ENABLE_SDR104) in tegra_sdhci_reset()
401 if (soc_data->nvquirks & NVQUIRK_ENABLE_SDR50) in tegra_sdhci_reset()
405 clk_ctrl |= tegra_host->default_trim << SDHCI_CLOCK_CTRL_TRIM_SHIFT; in tegra_sdhci_reset()
410 if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB) { in tegra_sdhci_reset()
416 tegra_host->pad_calib_required = true; in tegra_sdhci_reset()
419 tegra_host->ddr_signaling = false; in tegra_sdhci_reset()
460 &tegra_host->autocal_offsets; in tegra_sdhci_set_padctrl()
469 if (tegra_host->pinctrl_state_1v8_drv) { in tegra_sdhci_set_padctrl()
471 tegra_host->pinctrl_state_1v8_drv; in tegra_sdhci_set_padctrl()
473 drvup = offsets->pull_up_1v8_timeout; in tegra_sdhci_set_padctrl()
474 drvdn = offsets->pull_down_1v8_timeout; in tegra_sdhci_set_padctrl()
477 if (tegra_host->pinctrl_state_3v3_drv) { in tegra_sdhci_set_padctrl()
479 tegra_host->pinctrl_state_3v3_drv; in tegra_sdhci_set_padctrl()
481 drvup = offsets->pull_up_3v3_timeout; in tegra_sdhci_set_padctrl()
482 drvdn = offsets->pull_down_3v3_timeout; in tegra_sdhci_set_padctrl()
487 ret = pinctrl_select_state(tegra_host->pinctrl_sdmmc, in tegra_sdhci_set_padctrl()
490 dev_err(mmc_dev(host->mmc), in tegra_sdhci_set_padctrl()
503 if (!tegra_host->pad_control_available) in tegra_sdhci_set_padctrl()
507 ret = pinctrl_select_state(tegra_host->pinctrl_sdmmc, in tegra_sdhci_set_padctrl()
508 tegra_host->pinctrl_state_1v8); in tegra_sdhci_set_padctrl()
510 dev_err(mmc_dev(host->mmc), in tegra_sdhci_set_padctrl()
513 ret = pinctrl_select_state(tegra_host->pinctrl_sdmmc, in tegra_sdhci_set_padctrl()
514 tegra_host->pinctrl_state_3v3); in tegra_sdhci_set_padctrl()
516 dev_err(mmc_dev(host->mmc), in tegra_sdhci_set_padctrl()
529 tegra_host->autocal_offsets; in tegra_sdhci_pad_autocalib()
530 struct mmc_ios *ios = &host->mmc->ios; in tegra_sdhci_pad_autocalib()
536 switch (ios->timing) { in tegra_sdhci_pad_autocalib()
544 if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) in tegra_sdhci_pad_autocalib()
550 /* Set initial offset before auto-calibration */ in tegra_sdhci_pad_autocalib()
562 /* 10 ms timeout */ in tegra_sdhci_pad_autocalib()
563 ret = readl_poll_timeout(host->ioaddr + SDHCI_TEGRA_AUTO_CAL_STATUS, in tegra_sdhci_pad_autocalib()
572 dev_err(mmc_dev(host->mmc), "Pad autocal timed out\n"); in tegra_sdhci_pad_autocalib()
579 ret = tegra_sdhci_set_padctrl(host, ios->signal_voltage, false); in tegra_sdhci_pad_autocalib()
581 dev_err(mmc_dev(host->mmc), in tegra_sdhci_pad_autocalib()
591 &tegra_host->autocal_offsets; in tegra_sdhci_parse_pad_autocal_dt()
594 err = device_property_read_u32(mmc_dev(host->mmc), in tegra_sdhci_parse_pad_autocal_dt()
595 "nvidia,pad-autocal-pull-up-offset-3v3", in tegra_sdhci_parse_pad_autocal_dt()
596 &autocal->pull_up_3v3); in tegra_sdhci_parse_pad_autocal_dt()
598 autocal->pull_up_3v3 = 0; in tegra_sdhci_parse_pad_autocal_dt()
600 err = device_property_read_u32(mmc_dev(host->mmc), in tegra_sdhci_parse_pad_autocal_dt()
601 "nvidia,pad-autocal-pull-down-offset-3v3", in tegra_sdhci_parse_pad_autocal_dt()
602 &autocal->pull_down_3v3); in tegra_sdhci_parse_pad_autocal_dt()
604 autocal->pull_down_3v3 = 0; in tegra_sdhci_parse_pad_autocal_dt()
606 err = device_property_read_u32(mmc_dev(host->mmc), in tegra_sdhci_parse_pad_autocal_dt()
607 "nvidia,pad-autocal-pull-up-offset-1v8", in tegra_sdhci_parse_pad_autocal_dt()
608 &autocal->pull_up_1v8); in tegra_sdhci_parse_pad_autocal_dt()
610 autocal->pull_up_1v8 = 0; in tegra_sdhci_parse_pad_autocal_dt()
612 err = device_property_read_u32(mmc_dev(host->mmc), in tegra_sdhci_parse_pad_autocal_dt()
613 "nvidia,pad-autocal-pull-down-offset-1v8", in tegra_sdhci_parse_pad_autocal_dt()
614 &autocal->pull_down_1v8); in tegra_sdhci_parse_pad_autocal_dt()
616 autocal->pull_down_1v8 = 0; in tegra_sdhci_parse_pad_autocal_dt()
618 err = device_property_read_u32(mmc_dev(host->mmc), in tegra_sdhci_parse_pad_autocal_dt()
619 "nvidia,pad-autocal-pull-up-offset-sdr104", in tegra_sdhci_parse_pad_autocal_dt()
620 &autocal->pull_up_sdr104); in tegra_sdhci_parse_pad_autocal_dt()
622 autocal->pull_up_sdr104 = autocal->pull_up_1v8; in tegra_sdhci_parse_pad_autocal_dt()
624 err = device_property_read_u32(mmc_dev(host->mmc), in tegra_sdhci_parse_pad_autocal_dt()
625 "nvidia,pad-autocal-pull-down-offset-sdr104", in tegra_sdhci_parse_pad_autocal_dt()
626 &autocal->pull_down_sdr104); in tegra_sdhci_parse_pad_autocal_dt()
628 autocal->pull_down_sdr104 = autocal->pull_down_1v8; in tegra_sdhci_parse_pad_autocal_dt()
630 err = device_property_read_u32(mmc_dev(host->mmc), in tegra_sdhci_parse_pad_autocal_dt()
631 "nvidia,pad-autocal-pull-up-offset-hs400", in tegra_sdhci_parse_pad_autocal_dt()
632 &autocal->pull_up_hs400); in tegra_sdhci_parse_pad_autocal_dt()
634 autocal->pull_up_hs400 = autocal->pull_up_1v8; in tegra_sdhci_parse_pad_autocal_dt()
636 err = device_property_read_u32(mmc_dev(host->mmc), in tegra_sdhci_parse_pad_autocal_dt()
637 "nvidia,pad-autocal-pull-down-offset-hs400", in tegra_sdhci_parse_pad_autocal_dt()
638 &autocal->pull_down_hs400); in tegra_sdhci_parse_pad_autocal_dt()
640 autocal->pull_down_hs400 = autocal->pull_down_1v8; in tegra_sdhci_parse_pad_autocal_dt()
643 * Different fail-safe drive strength values based on the signaling in tegra_sdhci_parse_pad_autocal_dt()
648 if (!(tegra_host->soc_data->nvquirks & NVQUIRK_NEEDS_PAD_CONTROL)) in tegra_sdhci_parse_pad_autocal_dt()
651 err = device_property_read_u32(mmc_dev(host->mmc), in tegra_sdhci_parse_pad_autocal_dt()
652 "nvidia,pad-autocal-pull-up-offset-3v3-timeout", in tegra_sdhci_parse_pad_autocal_dt()
653 &autocal->pull_up_3v3_timeout); in tegra_sdhci_parse_pad_autocal_dt()
655 if (!IS_ERR(tegra_host->pinctrl_state_3v3) && in tegra_sdhci_parse_pad_autocal_dt()
656 (tegra_host->pinctrl_state_3v3_drv == NULL)) in tegra_sdhci_parse_pad_autocal_dt()
657 pr_warn("%s: Missing autocal timeout 3v3-pad drvs\n", in tegra_sdhci_parse_pad_autocal_dt()
658 mmc_hostname(host->mmc)); in tegra_sdhci_parse_pad_autocal_dt()
659 autocal->pull_up_3v3_timeout = 0; in tegra_sdhci_parse_pad_autocal_dt()
662 err = device_property_read_u32(mmc_dev(host->mmc), in tegra_sdhci_parse_pad_autocal_dt()
663 "nvidia,pad-autocal-pull-down-offset-3v3-timeout", in tegra_sdhci_parse_pad_autocal_dt()
664 &autocal->pull_down_3v3_timeout); in tegra_sdhci_parse_pad_autocal_dt()
666 if (!IS_ERR(tegra_host->pinctrl_state_3v3) && in tegra_sdhci_parse_pad_autocal_dt()
667 (tegra_host->pinctrl_state_3v3_drv == NULL)) in tegra_sdhci_parse_pad_autocal_dt()
668 pr_warn("%s: Missing autocal timeout 3v3-pad drvs\n", in tegra_sdhci_parse_pad_autocal_dt()
669 mmc_hostname(host->mmc)); in tegra_sdhci_parse_pad_autocal_dt()
670 autocal->pull_down_3v3_timeout = 0; in tegra_sdhci_parse_pad_autocal_dt()
673 err = device_property_read_u32(mmc_dev(host->mmc), in tegra_sdhci_parse_pad_autocal_dt()
674 "nvidia,pad-autocal-pull-up-offset-1v8-timeout", in tegra_sdhci_parse_pad_autocal_dt()
675 &autocal->pull_up_1v8_timeout); in tegra_sdhci_parse_pad_autocal_dt()
677 if (!IS_ERR(tegra_host->pinctrl_state_1v8) && in tegra_sdhci_parse_pad_autocal_dt()
678 (tegra_host->pinctrl_state_1v8_drv == NULL)) in tegra_sdhci_parse_pad_autocal_dt()
679 pr_warn("%s: Missing autocal timeout 1v8-pad drvs\n", in tegra_sdhci_parse_pad_autocal_dt()
680 mmc_hostname(host->mmc)); in tegra_sdhci_parse_pad_autocal_dt()
681 autocal->pull_up_1v8_timeout = 0; in tegra_sdhci_parse_pad_autocal_dt()
684 err = device_property_read_u32(mmc_dev(host->mmc), in tegra_sdhci_parse_pad_autocal_dt()
685 "nvidia,pad-autocal-pull-down-offset-1v8-timeout", in tegra_sdhci_parse_pad_autocal_dt()
686 &autocal->pull_down_1v8_timeout); in tegra_sdhci_parse_pad_autocal_dt()
688 if (!IS_ERR(tegra_host->pinctrl_state_1v8) && in tegra_sdhci_parse_pad_autocal_dt()
689 (tegra_host->pinctrl_state_1v8_drv == NULL)) in tegra_sdhci_parse_pad_autocal_dt()
690 pr_warn("%s: Missing autocal timeout 1v8-pad drvs\n", in tegra_sdhci_parse_pad_autocal_dt()
691 mmc_hostname(host->mmc)); in tegra_sdhci_parse_pad_autocal_dt()
692 autocal->pull_down_1v8_timeout = 0; in tegra_sdhci_parse_pad_autocal_dt()
701 ktime_t since_calib = ktime_sub(ktime_get(), tegra_host->last_calib); in tegra_sdhci_request()
703 /* 100 ms calibration interval is specified in the TRM */ in tegra_sdhci_request()
706 tegra_host->last_calib = ktime_get(); in tegra_sdhci_request()
718 err = device_property_read_u32(mmc_dev(host->mmc), "nvidia,default-tap", in tegra_sdhci_parse_tap_and_trim()
719 &tegra_host->default_tap); in tegra_sdhci_parse_tap_and_trim()
721 tegra_host->default_tap = 0; in tegra_sdhci_parse_tap_and_trim()
723 err = device_property_read_u32(mmc_dev(host->mmc), "nvidia,default-trim", in tegra_sdhci_parse_tap_and_trim()
724 &tegra_host->default_trim); in tegra_sdhci_parse_tap_and_trim()
726 tegra_host->default_trim = 0; in tegra_sdhci_parse_tap_and_trim()
728 err = device_property_read_u32(mmc_dev(host->mmc), "nvidia,dqs-trim", in tegra_sdhci_parse_tap_and_trim()
729 &tegra_host->dqs_trim); in tegra_sdhci_parse_tap_and_trim()
731 tegra_host->dqs_trim = 0x11; in tegra_sdhci_parse_tap_and_trim()
739 if (device_property_read_bool(mmc_dev(host->mmc), "supports-cqe")) in tegra_sdhci_parse_dt()
740 tegra_host->enable_hwcq = true; in tegra_sdhci_parse_dt()
742 tegra_host->enable_hwcq = false; in tegra_sdhci_parse_dt()
752 struct device *dev = mmc_dev(host->mmc); in tegra_sdhci_set_clock()
763 * sdhci_calc_clk(). The divider is calculated from host->max_clk and in tegra_sdhci_set_clock()
766 * By setting the host->max_clk to clock * 2 the divider calculation in tegra_sdhci_set_clock()
771 host_clk = tegra_host->ddr_signaling ? clock * 2 : clock; in tegra_sdhci_set_clock()
778 tegra_host->curr_clk_rate = clk_get_rate(pltfm_host->clk); in tegra_sdhci_set_clock()
779 if (tegra_host->ddr_signaling) in tegra_sdhci_set_clock()
780 host->max_clk = host_clk; in tegra_sdhci_set_clock()
782 host->max_clk = clk_get_rate(pltfm_host->clk); in tegra_sdhci_set_clock()
786 if (tegra_host->pad_calib_required) { in tegra_sdhci_set_clock()
788 tegra_host->pad_calib_required = false; in tegra_sdhci_set_clock()
800 if (ios->enhanced_strobe) { in tegra_sdhci_hs400_enhanced_strobe()
822 return clk_round_rate(pltfm_host->clk, UINT_MAX); in tegra_sdhci_get_max_clock()
844 /* 1 ms sleep, 5 ms timeout */ in tegra_sdhci_hs400_dll_cal()
845 err = readl_poll_timeout(host->ioaddr + SDHCI_TEGRA_VENDOR_DLLCAL_STA, in tegra_sdhci_hs400_dll_cal()
849 dev_err(mmc_dev(host->mmc), in tegra_sdhci_hs400_dll_cal()
859 u8 word, bit, edge1, tap, window; in tegra_sdhci_tap_correction() local
870 u8 total_tuning_words = host->tuning_loop_count / TUNING_WORD_BIT_SIZE; in tegra_sdhci_tap_correction()
873 * Read auto-tuned results and extract good valid passing window by in tegra_sdhci_tap_correction()
874 * filtering out un-wanted bubble/partial/merged windows. in tegra_sdhci_tap_correction()
884 tap = word * TUNING_WORD_BIT_SIZE + bit; in tegra_sdhci_tap_correction()
889 first_fail_tap = tap; in tegra_sdhci_tap_correction()
894 start_pass_tap = tap; in tegra_sdhci_tap_correction()
897 first_pass_tap = tap; in tegra_sdhci_tap_correction()
903 end_pass_tap = tap - 1; in tegra_sdhci_tap_correction()
907 window = end_pass_tap - start_pass_tap; in tegra_sdhci_tap_correction()
910 start_pass_tap = tap; in tegra_sdhci_tap_correction()
913 /* set tap at middle of valid window */ in tegra_sdhci_tap_correction()
914 tap = start_pass_tap + window / 2; in tegra_sdhci_tap_correction()
915 tegra_host->tuned_tap_delay = tap; in tegra_sdhci_tap_correction()
927 /* set tap location at fixed tap relative to the first edge */ in tegra_sdhci_tap_correction()
928 edge1 = first_fail_tap + (first_pass_tap - first_fail_tap) / 2; in tegra_sdhci_tap_correction()
929 if (edge1 - 1 > fixed_tap) in tegra_sdhci_tap_correction()
930 tegra_host->tuned_tap_delay = edge1 - fixed_tap; in tegra_sdhci_tap_correction()
932 tegra_host->tuned_tap_delay = edge1 + fixed_tap; in tegra_sdhci_tap_correction()
940 const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; in tegra_sdhci_post_tuning()
947 /* retain HW tuned tap to use incase if no correction is needed */ in tegra_sdhci_post_tuning()
949 tegra_host->tuned_tap_delay = (val & SDHCI_CLOCK_CTRL_TAP_MASK) >> in tegra_sdhci_post_tuning()
951 if (soc_data->min_tap_delay && soc_data->max_tap_delay) { in tegra_sdhci_post_tuning()
952 min_tap_dly = soc_data->min_tap_delay; in tegra_sdhci_post_tuning()
953 max_tap_dly = soc_data->max_tap_delay; in tegra_sdhci_post_tuning()
954 clk_rate_mhz = tegra_host->curr_clk_rate / USEC_PER_SEC; in tegra_sdhci_post_tuning()
965 * fixed tap is used when HW tuning result contains single edge in tegra_sdhci_post_tuning()
966 * and tap is set at fixed tap delay relative to the first edge in tegra_sdhci_post_tuning()
975 window_width = end_tap - start_tap; in tegra_sdhci_post_tuning()
976 num_iter = host->tuning_loop_count; in tegra_sdhci_post_tuning()
982 if (start_tap == 0 || (end_tap == (num_iter - 1)) || in tegra_sdhci_post_tuning()
983 (end_tap == num_iter - 2) || window_width >= thdupper) { in tegra_sdhci_post_tuning()
985 mmc_hostname(host->mmc)); in tegra_sdhci_post_tuning()
991 tegra_sdhci_set_tap(host, tegra_host->tuned_tap_delay); in tegra_sdhci_post_tuning()
1000 if (!err && !host->tuning_err) in tegra_sdhci_execute_hw_tuning()
1017 tegra_host->ddr_signaling = false; in tegra_sdhci_set_uhs_signaling()
1023 /* Don't set default tap on tunable modes. */ in tegra_sdhci_set_uhs_signaling()
1033 tegra_host->ddr_signaling = true; in tegra_sdhci_set_uhs_signaling()
1051 host->tuning_loop_count = (iter == TRIES_128) ? 128 : 256; in tegra_sdhci_set_uhs_signaling()
1057 if (tegra_host->tuned_tap_delay && !set_default_tap) in tegra_sdhci_set_uhs_signaling()
1058 tegra_sdhci_set_tap(host, tegra_host->tuned_tap_delay); in tegra_sdhci_set_uhs_signaling()
1060 tegra_sdhci_set_tap(host, tegra_host->default_tap); in tegra_sdhci_set_uhs_signaling()
1063 tegra_sdhci_set_dqs_trim(host, tegra_host->dqs_trim); in tegra_sdhci_set_uhs_signaling()
1074 * Start search for minimum tap value at 10, as smaller values are in tegra_sdhci_execute_tuning()
1081 if (!mmc_send_tuning(host->mmc, opcode, NULL)) in tegra_sdhci_execute_tuning()
1086 /* Find the maximum tap value that still passes. */ in tegra_sdhci_execute_tuning()
1090 if (mmc_send_tuning(host->mmc, opcode, NULL)) { in tegra_sdhci_execute_tuning()
1091 max--; in tegra_sdhci_execute_tuning()
1097 /* The TRM states the ideal tap value is at 75% in the passing range. */ in tegra_sdhci_execute_tuning()
1098 tegra_sdhci_set_tap(host, min + ((max - min) * 3 / 4)); in tegra_sdhci_execute_tuning()
1100 return mmc_send_tuning(host->mmc, opcode, NULL); in tegra_sdhci_execute_tuning()
1111 if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) { in sdhci_tegra_start_signal_voltage_switch()
1112 ret = tegra_sdhci_set_padctrl(host, ios->signal_voltage, true); in sdhci_tegra_start_signal_voltage_switch()
1116 } else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) { in sdhci_tegra_start_signal_voltage_switch()
1120 ret = tegra_sdhci_set_padctrl(host, ios->signal_voltage, true); in sdhci_tegra_start_signal_voltage_switch()
1123 if (tegra_host->pad_calib_required) in sdhci_tegra_start_signal_voltage_switch()
1132 tegra_host->pinctrl_sdmmc = devm_pinctrl_get(dev); in tegra_sdhci_init_pinctrl_info()
1133 if (IS_ERR(tegra_host->pinctrl_sdmmc)) { in tegra_sdhci_init_pinctrl_info()
1135 PTR_ERR(tegra_host->pinctrl_sdmmc)); in tegra_sdhci_init_pinctrl_info()
1136 return -1; in tegra_sdhci_init_pinctrl_info()
1139 tegra_host->pinctrl_state_1v8_drv = pinctrl_lookup_state( in tegra_sdhci_init_pinctrl_info()
1140 tegra_host->pinctrl_sdmmc, "sdmmc-1v8-drv"); in tegra_sdhci_init_pinctrl_info()
1141 if (IS_ERR(tegra_host->pinctrl_state_1v8_drv)) { in tegra_sdhci_init_pinctrl_info()
1142 if (PTR_ERR(tegra_host->pinctrl_state_1v8_drv) == -ENODEV) in tegra_sdhci_init_pinctrl_info()
1143 tegra_host->pinctrl_state_1v8_drv = NULL; in tegra_sdhci_init_pinctrl_info()
1146 tegra_host->pinctrl_state_3v3_drv = pinctrl_lookup_state( in tegra_sdhci_init_pinctrl_info()
1147 tegra_host->pinctrl_sdmmc, "sdmmc-3v3-drv"); in tegra_sdhci_init_pinctrl_info()
1148 if (IS_ERR(tegra_host->pinctrl_state_3v3_drv)) { in tegra_sdhci_init_pinctrl_info()
1149 if (PTR_ERR(tegra_host->pinctrl_state_3v3_drv) == -ENODEV) in tegra_sdhci_init_pinctrl_info()
1150 tegra_host->pinctrl_state_3v3_drv = NULL; in tegra_sdhci_init_pinctrl_info()
1153 tegra_host->pinctrl_state_3v3 = in tegra_sdhci_init_pinctrl_info()
1154 pinctrl_lookup_state(tegra_host->pinctrl_sdmmc, "sdmmc-3v3"); in tegra_sdhci_init_pinctrl_info()
1155 if (IS_ERR(tegra_host->pinctrl_state_3v3)) { in tegra_sdhci_init_pinctrl_info()
1157 PTR_ERR(tegra_host->pinctrl_state_3v3)); in tegra_sdhci_init_pinctrl_info()
1158 return -1; in tegra_sdhci_init_pinctrl_info()
1161 tegra_host->pinctrl_state_1v8 = in tegra_sdhci_init_pinctrl_info()
1162 pinctrl_lookup_state(tegra_host->pinctrl_sdmmc, "sdmmc-1v8"); in tegra_sdhci_init_pinctrl_info()
1163 if (IS_ERR(tegra_host->pinctrl_state_1v8)) { in tegra_sdhci_init_pinctrl_info()
1165 PTR_ERR(tegra_host->pinctrl_state_1v8)); in tegra_sdhci_init_pinctrl_info()
1166 return -1; in tegra_sdhci_init_pinctrl_info()
1169 tegra_host->pad_control_available = true; in tegra_sdhci_init_pinctrl_info()
1178 const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; in tegra_sdhci_voltage_switch()
1180 if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB) in tegra_sdhci_voltage_switch()
1181 tegra_host->pad_calib_required = true; in tegra_sdhci_voltage_switch()
1186 struct mmc_host *mmc = cq_host->mmc; in tegra_cqhci_writel()
1189 ktime_t timeout; in tegra_cqhci_writel() local
1195 * to be re-configured. in tegra_cqhci_writel()
1204 writel(val, cq_host->mmio + reg); in tegra_cqhci_writel()
1205 timeout = ktime_add_us(ktime_get(), 50); in tegra_cqhci_writel()
1207 timed_out = ktime_compare(ktime_get(), timeout) > 0; in tegra_cqhci_writel()
1217 writel(val, cq_host->mmio + reg); in tegra_cqhci_writel()
1219 writel(val, cq_host->mmio + reg); in tegra_cqhci_writel()
1228 const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; in sdhci_tegra_update_dcmd_desc()
1230 if (soc_data->nvquirks & NVQUIRK_CQHCI_DCMD_R1B_CMD_TIMING && in sdhci_tegra_update_dcmd_desc()
1231 mrq->cmd->flags & MMC_RSP_R1B) in sdhci_tegra_update_dcmd_desc()
1237 struct cqhci_host *cq_host = mmc->cqe_private; in sdhci_tegra_cqe_enable()
1247 if (!cq_host->activated) { in sdhci_tegra_cqe_enable()
1283 cqhci_irq(host->mmc, intmask, cmd_error, data_error); in sdhci_tegra_cqhci_irq()
1294 * HW busy detection timeout is based on programmed data timeout in tegra_sdhci_set_timeout()
1295 * counter and maximum supported timeout is 11s which may not be in tegra_sdhci_set_timeout()
1300 * without HW timeout. in tegra_sdhci_set_timeout()
1303 * more than maximum HW busy timeout of 11s otherwise use finite in tegra_sdhci_set_timeout()
1307 if (cmd && cmd->busy_timeout >= 11 * MSEC_PER_SEC) in tegra_sdhci_set_timeout()
1318 struct cqhci_host *cq_host = mmc->cqe_private; in sdhci_tegra_cqe_pre_enable()
1328 struct cqhci_host *cq_host = mmc->cqe_private; in sdhci_tegra_cqe_post_disable()
1352 const struct sdhci_tegra_soc_data *soc = tegra->soc_data; in tegra_sdhci_set_dma_mask()
1353 struct device *dev = mmc_dev(host->mmc); in tegra_sdhci_set_dma_mask()
1355 if (soc->dma_mask) in tegra_sdhci_set_dma_mask()
1356 return dma_set_mask_and_coherent(dev, soc->dma_mask); in tegra_sdhci_set_dma_mask()
1402 * Auto-CMD23 leads to "Got command interrupt 0x00010000 even
1577 { .compatible = "nvidia,tegra234-sdhci", .data = &soc_data_tegra234 },
1578 { .compatible = "nvidia,tegra194-sdhci", .data = &soc_data_tegra194 },
1579 { .compatible = "nvidia,tegra186-sdhci", .data = &soc_data_tegra186 },
1580 { .compatible = "nvidia,tegra210-sdhci", .data = &soc_data_tegra210 },
1581 { .compatible = "nvidia,tegra124-sdhci", .data = &soc_data_tegra124 },
1582 { .compatible = "nvidia,tegra114-sdhci", .data = &soc_data_tegra114 },
1583 { .compatible = "nvidia,tegra30-sdhci", .data = &soc_data_tegra30 },
1584 { .compatible = "nvidia,tegra20-sdhci", .data = &soc_data_tegra20 },
1597 if (!tegra_host->enable_hwcq) in sdhci_tegra_add_host()
1606 host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD; in sdhci_tegra_add_host()
1608 cq_host = devm_kzalloc(mmc_dev(host->mmc), in sdhci_tegra_add_host()
1611 ret = -ENOMEM; in sdhci_tegra_add_host()
1615 cq_host->mmio = host->ioaddr + SDHCI_TEGRA_CQE_BASE_ADDR; in sdhci_tegra_add_host()
1616 cq_host->ops = &sdhci_tegra_cqhci_ops; in sdhci_tegra_add_host()
1618 dma64 = host->flags & SDHCI_USE_64_BIT_DMA; in sdhci_tegra_add_host()
1620 cq_host->caps |= CQHCI_TASK_DESC_SZ_128; in sdhci_tegra_add_host()
1622 ret = cqhci_init(cq_host, host->mmc, dma64); in sdhci_tegra_add_host()
1643 if (tegra_host->soc_data->nvquirks & NVQUIRK_PROGRAM_STREAMID) { in sdhci_tegra_program_stream_id()
1644 tegra_sdhci_writel(host, FIELD_PREP(GENMASK(15, 8), tegra_host->stream_id) | in sdhci_tegra_program_stream_id()
1645 FIELD_PREP(GENMASK(7, 0), tegra_host->stream_id), in sdhci_tegra_program_stream_id()
1659 soc_data = of_device_get_match_data(&pdev->dev); in sdhci_tegra_probe()
1661 return -EINVAL; in sdhci_tegra_probe()
1663 host = sdhci_pltfm_init(pdev, soc_data->pdata, sizeof(*tegra_host)); in sdhci_tegra_probe()
1669 tegra_host->ddr_signaling = false; in sdhci_tegra_probe()
1670 tegra_host->pad_calib_required = false; in sdhci_tegra_probe()
1671 tegra_host->pad_control_available = false; in sdhci_tegra_probe()
1672 tegra_host->soc_data = soc_data; in sdhci_tegra_probe()
1674 if (soc_data->nvquirks & NVQUIRK_HAS_ANDROID_GPT_SECTOR) in sdhci_tegra_probe()
1675 host->mmc->caps2 |= MMC_CAP2_ALT_GPT_TEGRA; in sdhci_tegra_probe()
1677 if (soc_data->nvquirks & NVQUIRK_NEEDS_PAD_CONTROL) { in sdhci_tegra_probe()
1678 rc = tegra_sdhci_init_pinctrl_info(&pdev->dev, tegra_host); in sdhci_tegra_probe()
1680 host->mmc_host_ops.start_signal_voltage_switch = in sdhci_tegra_probe()
1685 if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB) in sdhci_tegra_probe()
1686 host->mmc_host_ops.request = tegra_sdhci_request; in sdhci_tegra_probe()
1688 host->mmc_host_ops.hs400_enhanced_strobe = in sdhci_tegra_probe()
1691 if (!host->ops->platform_execute_tuning) in sdhci_tegra_probe()
1692 host->mmc_host_ops.execute_tuning = in sdhci_tegra_probe()
1695 rc = mmc_of_parse(host->mmc); in sdhci_tegra_probe()
1699 if (tegra_host->soc_data->nvquirks & NVQUIRK_ENABLE_DDR50) in sdhci_tegra_probe()
1700 host->mmc->caps |= MMC_CAP_1_8V_DDR; in sdhci_tegra_probe()
1703 host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY; in sdhci_tegra_probe()
1706 host->mmc->caps |= MMC_CAP_CD_WAKE; in sdhci_tegra_probe()
1710 if (tegra_host->soc_data->nvquirks & NVQUIRK_PROGRAM_STREAMID && in sdhci_tegra_probe()
1711 !tegra_dev_iommu_get_stream_id(&pdev->dev, &tegra_host->stream_id)) { in sdhci_tegra_probe()
1712 dev_warn(mmc_dev(host->mmc), "missing IOMMU stream ID\n"); in sdhci_tegra_probe()
1713 tegra_host->stream_id = 0x7f; in sdhci_tegra_probe()
1716 tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power", in sdhci_tegra_probe()
1718 if (IS_ERR(tegra_host->power_gpio)) { in sdhci_tegra_probe()
1719 rc = PTR_ERR(tegra_host->power_gpio); in sdhci_tegra_probe()
1725 * timeout clock and SW can choose TMCLK or SDCLK for hardware in sdhci_tegra_probe()
1726 * data timeout through the bit USE_TMCLK_FOR_DATA_TIMEOUT of in sdhci_tegra_probe()
1731 * With TMCLK of 12Mhz provides maximum data timeout period that can in sdhci_tegra_probe()
1732 * be achieved is 11s better than using SDCLK for data timeout. in sdhci_tegra_probe()
1738 if (soc_data->nvquirks & NVQUIRK_HAS_TMCLK) { in sdhci_tegra_probe()
1739 clk = devm_clk_get(&pdev->dev, "tmclk"); in sdhci_tegra_probe()
1742 if (rc == -EPROBE_DEFER) in sdhci_tegra_probe()
1745 dev_warn(&pdev->dev, "failed to get tmclk: %d\n", rc); in sdhci_tegra_probe()
1752 dev_err(&pdev->dev, in sdhci_tegra_probe()
1757 tegra_host->tmclk = clk; in sdhci_tegra_probe()
1760 clk = devm_clk_get(mmc_dev(host->mmc), NULL); in sdhci_tegra_probe()
1762 rc = dev_err_probe(&pdev->dev, PTR_ERR(clk), in sdhci_tegra_probe()
1766 pltfm_host->clk = clk; in sdhci_tegra_probe()
1768 tegra_host->rst = devm_reset_control_get_exclusive(&pdev->dev, in sdhci_tegra_probe()
1770 if (IS_ERR(tegra_host->rst)) { in sdhci_tegra_probe()
1771 rc = PTR_ERR(tegra_host->rst); in sdhci_tegra_probe()
1772 dev_err(&pdev->dev, "failed to get reset control: %d\n", rc); in sdhci_tegra_probe()
1776 rc = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); in sdhci_tegra_probe()
1780 pm_runtime_enable(&pdev->dev); in sdhci_tegra_probe()
1781 rc = pm_runtime_resume_and_get(&pdev->dev); in sdhci_tegra_probe()
1785 rc = reset_control_assert(tegra_host->rst); in sdhci_tegra_probe()
1791 rc = reset_control_deassert(tegra_host->rst); in sdhci_tegra_probe()
1806 reset_control_assert(tegra_host->rst); in sdhci_tegra_probe()
1808 pm_runtime_put_sync_suspend(&pdev->dev); in sdhci_tegra_probe()
1810 pm_runtime_disable(&pdev->dev); in sdhci_tegra_probe()
1813 clk_disable_unprepare(tegra_host->tmclk); in sdhci_tegra_probe()
1828 reset_control_assert(tegra_host->rst); in sdhci_tegra_remove()
1831 pm_runtime_put_sync_suspend(&pdev->dev); in sdhci_tegra_remove()
1832 pm_runtime_force_suspend(&pdev->dev); in sdhci_tegra_remove()
1834 clk_disable_unprepare(tegra_host->tmclk); in sdhci_tegra_remove()
1843 clk_disable_unprepare(pltfm_host->clk); in sdhci_tegra_runtime_suspend()
1853 return clk_prepare_enable(pltfm_host->clk); in sdhci_tegra_runtime_resume()
1862 if (host->mmc->caps2 & MMC_CAP2_CQE) { in sdhci_tegra_suspend()
1863 ret = cqhci_suspend(host->mmc); in sdhci_tegra_suspend()
1870 cqhci_resume(host->mmc); in sdhci_tegra_suspend()
1877 cqhci_resume(host->mmc); in sdhci_tegra_suspend()
1881 return mmc_gpio_set_cd_wake(host->mmc, true); in sdhci_tegra_suspend()
1889 ret = mmc_gpio_set_cd_wake(host->mmc, false); in sdhci_tegra_resume()
1903 if (host->mmc->caps2 & MMC_CAP2_CQE) { in sdhci_tegra_resume()
1904 ret = cqhci_resume(host->mmc); in sdhci_tegra_resume()
1927 .name = "sdhci-tegra",