Lines Matching +full:irq +full:- +full:status +full:- +full:read +full:- +full:quirk
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
17 #include <linux/reset-controller.h>
28 #include "ufshcd-pltfrm.h"
29 #include "ufs-qcom.h"
37 /* De-emphasis for gear-5 */
139 * ufs_qcom_config_ice_allocator() - ICE core allocator configuration
145 struct ufs_hba *hba = host->hba; in ufs_qcom_config_ice_allocator()
149 if (!(host->caps & UFS_QCOM_CAP_ICE_CONFIG) || in ufs_qcom_config_ice_allocator()
150 !(host->hba->caps & UFSHCD_CAP_CRYPTO)) in ufs_qcom_config_ice_allocator()
161 if (host->hba->caps & UFSHCD_CAP_CRYPTO) in ufs_qcom_ice_enable()
162 qcom_ice_enable(host->ice); in ufs_qcom_ice_enable()
169 struct ufs_hba *hba = host->hba; in ufs_qcom_ice_init()
170 struct blk_crypto_profile *profile = &hba->crypto_profile; in ufs_qcom_ice_init()
171 struct device *dev = hba->dev; in ufs_qcom_ice_init()
179 if (ice == ERR_PTR(-EOPNOTSUPP)) { in ufs_qcom_ice_init()
187 host->ice = ice; in ufs_qcom_ice_init()
198 profile->ll_ops = ufs_qcom_crypto_ops; in ufs_qcom_ice_init()
199 profile->max_dun_bytes_supported = 8; in ufs_qcom_ice_init()
200 profile->key_types_supported = qcom_ice_get_supported_key_type(ice); in ufs_qcom_ice_init()
201 profile->dev = dev; in ufs_qcom_ice_init()
204 * Currently this driver only supports AES-256-XTS. All known versions in ufs_qcom_ice_init()
215 profile->modes_supported[BLK_ENCRYPTION_MODE_AES_256_XTS] |= in ufs_qcom_ice_init()
219 hba->caps |= UFSHCD_CAP_CRYPTO; in ufs_qcom_ice_init()
220 hba->quirks |= UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE; in ufs_qcom_ice_init()
226 if (host->hba->caps & UFSHCD_CAP_CRYPTO) in ufs_qcom_ice_resume()
227 return qcom_ice_resume(host->ice); in ufs_qcom_ice_resume()
234 if (host->hba->caps & UFSHCD_CAP_CRYPTO) in ufs_qcom_ice_suspend()
235 return qcom_ice_suspend(host->ice); in ufs_qcom_ice_suspend()
249 err = qcom_ice_program_key(host->ice, slot, key); in ufs_qcom_ice_keyslot_program()
263 err = qcom_ice_evict_key(host->ice, slot); in ufs_qcom_ice_keyslot_evict()
275 return qcom_ice_derive_sw_secret(host->ice, eph_key, eph_key_size, in ufs_qcom_ice_derive_sw_secret()
286 return qcom_ice_import_key(host->ice, raw_key, raw_key_size, lt_key); in ufs_qcom_ice_import_key()
295 return qcom_ice_generate_key(host->ice, lt_key); in ufs_qcom_ice_generate_key()
305 return qcom_ice_prepare_key(host->ice, lt_key, lt_key_size, eph_key); in ufs_qcom_ice_prepare_key()
346 if (!host->is_lane_clks_enabled) in ufs_qcom_disable_lane_clks()
349 clk_bulk_disable_unprepare(host->num_clks, host->clks); in ufs_qcom_disable_lane_clks()
351 host->is_lane_clks_enabled = false; in ufs_qcom_disable_lane_clks()
358 err = clk_bulk_prepare_enable(host->num_clks, host->clks); in ufs_qcom_enable_lane_clks()
362 host->is_lane_clks_enabled = true; in ufs_qcom_enable_lane_clks()
370 struct device *dev = host->hba->dev; in ufs_qcom_init_lane_clks()
375 err = devm_clk_bulk_get_all(dev, &host->clks); in ufs_qcom_init_lane_clks()
379 host->num_clks = err; in ufs_qcom_init_lane_clks()
413 dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n", in ufs_qcom_check_hibern8()
417 dev_err(hba->dev, "%s: invalid TX_FSM_STATE = %d\n", in ufs_qcom_check_hibern8()
426 ufshcd_rmwl(host->hba, QUNIPRO_SEL, QUNIPRO_SEL, REG_UFS_CFG1); in ufs_qcom_select_unipro_mode()
428 if (host->hw_ver.major >= 0x05) in ufs_qcom_select_unipro_mode()
429 ufshcd_rmwl(host->hba, QUNIPRO_G4_SEL, 0, REG_UFS_CFG0); in ufs_qcom_select_unipro_mode()
433 * ufs_qcom_host_reset - reset host controller and PHY
441 if (!host->core_reset) in ufs_qcom_host_reset()
444 reenable_intr = hba->is_irq_enabled; in ufs_qcom_host_reset()
447 ret = reset_control_assert(host->core_reset); in ufs_qcom_host_reset()
449 dev_err(hba->dev, "%s: core_reset assert failed, err = %d\n", in ufs_qcom_host_reset()
456 * is at least 3-4 sleep clock (32.7KHz) cycles, which comes to in ufs_qcom_host_reset()
461 ret = reset_control_deassert(host->core_reset); in ufs_qcom_host_reset()
463 dev_err(hba->dev, "%s: core_reset deassert failed, err = %d\n", in ufs_qcom_host_reset()
480 if (host->hw_ver.major >= 0x4) in ufs_qcom_get_hs_gear()
483 /* Default is HS-G3 */ in ufs_qcom_get_hs_gear()
490 struct ufs_host_params *host_params = &host->host_params; in ufs_qcom_power_up_sequence()
491 struct phy *phy = host->generic_phy; in ufs_qcom_power_up_sequence()
496 * HW ver 5 can only support up to HS-G5 Rate-A due to HW limitations. in ufs_qcom_power_up_sequence()
497 * If the HS-G5 PHY gear is used, update host_params->hs_rate to Rate-A, in ufs_qcom_power_up_sequence()
498 * so that the subsequent power mode change shall stick to Rate-A. in ufs_qcom_power_up_sequence()
500 if (host->hw_ver.major == 0x5 && host->phy_gear == UFS_HS_G5) in ufs_qcom_power_up_sequence()
501 host_params->hs_rate = PA_HS_MODE_A; in ufs_qcom_power_up_sequence()
503 mode = host_params->hs_rate == PA_HS_MODE_B ? PHY_MODE_UFS_HS_B : PHY_MODE_UFS_HS_A; in ufs_qcom_power_up_sequence()
510 if (phy->power_count) in ufs_qcom_power_up_sequence()
514 /* phy initialization - calibrate the phy */ in ufs_qcom_power_up_sequence()
517 dev_err(hba->dev, "%s: phy init failed, ret = %d\n", in ufs_qcom_power_up_sequence()
522 ret = phy_set_mode_ext(phy, mode, host->phy_gear); in ufs_qcom_power_up_sequence()
526 /* power on phy - start serdes and phy's power and clocks */ in ufs_qcom_power_up_sequence()
529 dev_err(hba->dev, "%s: phy power on failed, ret = %d\n", in ufs_qcom_power_up_sequence()
536 dev_err(hba->dev, "Failed to calibrate PHY: %d\n", ret); in ufs_qcom_power_up_sequence()
552 * Internal hardware sub-modules within the UTP controller control the CGCs.
553 * Hardware CGCs disable the clock to inactivate UTP sub-modules not involved
585 dev_err(hba->dev, "hw clk gating enabled failed\n"); in ufs_qcom_enable_hw_clk_gating()
589 enum ufs_notify_change_status status) in ufs_qcom_hce_enable_notify() argument
594 switch (status) { in ufs_qcom_hce_enable_notify()
615 dev_err(hba->dev, "%s: invalid status %d\n", __func__, status); in ufs_qcom_hce_enable_notify()
616 err = -EINVAL; in ufs_qcom_hce_enable_notify()
623 * ufs_qcom_cfg_timers - Configure ufs qcom cfg timers
628 * Return: zero for success and non-zero in case of a failure.
643 if (host->hw_ver.major < 4 && !ufshcd_is_intr_aggr_allowed(hba)) in ufs_qcom_cfg_timers()
646 if (hba->use_pm_opp && freq != ULONG_MAX) { in ufs_qcom_cfg_timers()
652 list_for_each_entry(clki, &hba->clk_list_head, list) { in ufs_qcom_cfg_timers()
653 if (!strcmp(clki->name, "core_clk")) { in ufs_qcom_cfg_timers()
655 clk_freq = clki->max_freq; in ufs_qcom_cfg_timers()
660 clk_freq = clki->max_freq; in ufs_qcom_cfg_timers()
662 clk_freq = clk_get_rate(clki->clk); in ufs_qcom_cfg_timers()
687 enum ufs_notify_change_status status) in ufs_qcom_link_startup_notify() argument
691 switch (status) { in ufs_qcom_link_startup_notify()
694 dev_err(hba->dev, "%s: ufs_qcom_cfg_timers() failed\n", in ufs_qcom_link_startup_notify()
696 return -EINVAL; in ufs_qcom_link_startup_notify()
701 dev_err(hba->dev, "cfg core clk ctrl failed\n"); in ufs_qcom_link_startup_notify()
724 if (!host->device_reset) in ufs_qcom_device_reset_ctrl()
727 gpiod_set_value_cansleep(host->device_reset, asserted); in ufs_qcom_device_reset_ctrl()
731 enum ufs_notify_change_status status) in ufs_qcom_suspend() argument
735 if (status == PRE_CHANGE) in ufs_qcom_suspend()
743 if (ufs_qcom_is_link_off(hba) && host->device_reset) { in ufs_qcom_suspend()
751 * beyond the permissible limit for low-power mode (LPM). in ufs_qcom_suspend()
773 host->hw_ver.major == 5 && in ufs_qcom_resume()
774 host->hw_ver.minor == 0 && in ufs_qcom_resume()
775 host->hw_ver.step == 0) { in ufs_qcom_resume()
794 if (host->dev_ref_clk_ctrl_mmio && in ufs_qcom_dev_ref_clk_ctrl()
795 (enable ^ host->is_dev_ref_clk_enabled)) { in ufs_qcom_dev_ref_clk_ctrl()
796 u32 temp = readl_relaxed(host->dev_ref_clk_ctrl_mmio); in ufs_qcom_dev_ref_clk_ctrl()
799 temp |= host->dev_ref_clk_en_mask; in ufs_qcom_dev_ref_clk_ctrl()
801 temp &= ~host->dev_ref_clk_en_mask; in ufs_qcom_dev_ref_clk_ctrl()
812 gating_wait = host->hba->dev_info.clk_gating_wait_us; in ufs_qcom_dev_ref_clk_ctrl()
820 * HS-MODE to LS-MODE or HIBERN8 state. Give it in ufs_qcom_dev_ref_clk_ctrl()
828 writel_relaxed(temp, host->dev_ref_clk_ctrl_mmio); in ufs_qcom_dev_ref_clk_ctrl()
834 readl(host->dev_ref_clk_ctrl_mmio); in ufs_qcom_dev_ref_clk_ctrl()
844 host->is_dev_ref_clk_enabled = enable; in ufs_qcom_dev_ref_clk_ctrl()
850 struct device *dev = host->hba->dev; in ufs_qcom_icc_set_bw()
853 ret = icc_set_bw(host->icc_ddr, 0, mem_bw); in ufs_qcom_icc_set_bw()
859 ret = icc_set_bw(host->icc_cpu, 0, cfg_bw); in ufs_qcom_icc_set_bw()
870 struct ufs_pa_layer_attr *p = &host->dev_req_params; in ufs_qcom_get_bw_table()
871 int gear = max_t(u32, p->gear_rx, p->gear_tx); in ufs_qcom_get_bw_table()
872 int lane = max_t(u32, p->lane_rx, p->lane_tx); in ufs_qcom_get_bw_table()
885 if (p->hs_rate == PA_HS_MODE_B) in ufs_qcom_get_bw_table()
915 dev_err(hba->dev, "%s: failed equalizer lane %d\n", in ufs_qcom_set_tx_hs_equalizer()
921 enum ufs_notify_change_status status, in ufs_qcom_pwr_change_notify() argument
926 struct ufs_host_params *host_params = &host->host_params; in ufs_qcom_pwr_change_notify()
931 return -EINVAL; in ufs_qcom_pwr_change_notify()
934 switch (status) { in ufs_qcom_pwr_change_notify()
938 dev_err(hba->dev, "%s: failed to determine capabilities\n", in ufs_qcom_pwr_change_notify()
945 * gear, so that, if quirk UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH is enabled, in ufs_qcom_pwr_change_notify()
949 if (hba->ufshcd_state == UFSHCD_STATE_RESET) { in ufs_qcom_pwr_change_notify()
955 if (host->phy_gear == dev_req_params->gear_tx) in ufs_qcom_pwr_change_notify()
956 hba->quirks &= ~UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH; in ufs_qcom_pwr_change_notify()
958 host->phy_gear = dev_req_params->gear_tx; in ufs_qcom_pwr_change_notify()
962 if (!ufshcd_is_hs_mode(&hba->pwr_info) && in ufs_qcom_pwr_change_notify()
966 if (host->hw_ver.major >= 0x4) { in ufs_qcom_pwr_change_notify()
968 dev_req_params->gear_tx, in ufs_qcom_pwr_change_notify()
972 if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_TX_DEEMPHASIS_TUNING) in ufs_qcom_pwr_change_notify()
974 dev_req_params->gear_tx, dev_req_params->lane_tx); in ufs_qcom_pwr_change_notify()
979 memcpy(&host->dev_req_params, in ufs_qcom_pwr_change_notify()
985 if (ufshcd_is_hs_mode(&hba->pwr_info) && in ufs_qcom_pwr_change_notify()
990 ret = -EINVAL; in ufs_qcom_pwr_change_notify()
1019 dev_err(hba->dev, "Failed (%d) set PA_TX_HSG1_SYNC_LENGTH\n", err); in ufs_qcom_override_pa_tx_hsg1_sync_len()
1026 if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME) in ufs_qcom_apply_dev_quirks()
1029 if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_TX_HSG1_SYNC_LENGTH) in ufs_qcom_apply_dev_quirks()
1035 /* UFS device-specific quirks */
1039 .quirk = UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM },
1042 .quirk = UFS_DEVICE_QUIRK_DELAY_AFTER_LPM },
1045 .quirk = UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE },
1048 .quirk = UFS_DEVICE_QUIRK_PA_TX_HSG1_SYNC_LENGTH |
1064 * ufs_qcom_advertise_quirks - advertise the known QCOM UFS controller quirks
1074 const struct ufs_qcom_drvdata *drvdata = of_device_get_match_data(hba->dev); in ufs_qcom_advertise_quirks()
1077 if (host->hw_ver.major == 0x2) in ufs_qcom_advertise_quirks()
1078 hba->quirks |= UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION; in ufs_qcom_advertise_quirks()
1080 if (host->hw_ver.major > 0x3) in ufs_qcom_advertise_quirks()
1081 hba->quirks |= UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH; in ufs_qcom_advertise_quirks()
1083 if (drvdata && drvdata->quirks) in ufs_qcom_advertise_quirks()
1084 hba->quirks |= drvdata->quirks; in ufs_qcom_advertise_quirks()
1089 struct ufs_host_params *host_params = &host->host_params; in ufs_qcom_set_phy_gear()
1099 host->phy_gear = host_params->hs_tx_gear; in ufs_qcom_set_phy_gear()
1101 if (host->hw_ver.major < 0x4) { in ufs_qcom_set_phy_gear()
1107 host->phy_gear = UFS_HS_G2; in ufs_qcom_set_phy_gear()
1108 } else if (host->hw_ver.major >= 0x5) { in ufs_qcom_set_phy_gear()
1109 val = ufshcd_readl(host->hba, REG_UFS_DEBUG_SPARE_CFG); in ufs_qcom_set_phy_gear()
1114 * REINIT quirk as the negotiated gear won't change during boot. in ufs_qcom_set_phy_gear()
1118 host->hba->quirks &= ~UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH; in ufs_qcom_set_phy_gear()
1121 * For UFS 3.1 device and older, power up the PHY using HS-G4 in ufs_qcom_set_phy_gear()
1125 host->phy_gear = UFS_HS_G4; in ufs_qcom_set_phy_gear()
1132 struct ufs_host_params *host_params = &host->host_params; in ufs_qcom_parse_gear_limits()
1133 u32 hs_gear_old = host_params->hs_tx_gear; in ufs_qcom_parse_gear_limits()
1136 if (host_params->hs_tx_gear != hs_gear_old) { in ufs_qcom_parse_gear_limits()
1137 host->phy_gear = host_params->hs_tx_gear; in ufs_qcom_parse_gear_limits()
1144 struct ufs_host_params *host_params = &host->host_params; in ufs_qcom_set_host_params()
1149 host_params->hs_tx_gear = host_params->hs_rx_gear = ufs_qcom_get_hs_gear(hba); in ufs_qcom_set_host_params()
1156 if (host->hw_ver.major >= 0x5) in ufs_qcom_set_host_caps()
1157 host->caps |= UFS_QCOM_CAP_ICE_CONFIG; in ufs_qcom_set_host_caps()
1162 hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_HIBERN8_WITH_CLK_GATING; in ufs_qcom_set_caps()
1163 hba->caps |= UFSHCD_CAP_CLK_SCALING | UFSHCD_CAP_WB_WITH_CLK_SCALING; in ufs_qcom_set_caps()
1164 hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND; in ufs_qcom_set_caps()
1165 hba->caps |= UFSHCD_CAP_WB_EN; in ufs_qcom_set_caps()
1166 hba->caps |= UFSHCD_CAP_AGGR_POWER_COLLAPSE; in ufs_qcom_set_caps()
1167 hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND; in ufs_qcom_set_caps()
1173 * ufs_qcom_setup_clocks - enables/disable clocks
1176 * @status: PRE_CHANGE or POST_CHANGE notify
1184 * Return: 0 on success, non-zero on failure.
1187 enum ufs_notify_change_status status) in ufs_qcom_setup_clocks() argument
1201 phy = host->generic_phy; in ufs_qcom_setup_clocks()
1203 switch (status) { in ufs_qcom_setup_clocks()
1210 dev_err(hba->dev, "enable lane clks failed, ret=%d\n", err); in ufs_qcom_setup_clocks()
1222 dev_err(hba->dev, "phy power off failed, ret=%d\n", err); in ufs_qcom_setup_clocks()
1231 dev_err(hba->dev, "phy power on failed, ret = %d\n", err); in ufs_qcom_setup_clocks()
1236 if (ufshcd_is_hs_mode(&hba->pwr_info)) in ufs_qcom_setup_clocks()
1256 ufs_qcom_assert_reset(host->hba); in ufs_qcom_reset_assert()
1267 ufs_qcom_deassert_reset(host->hba); in ufs_qcom_reset_deassert()
1284 struct device *dev = host->hba->dev; in ufs_qcom_icc_init()
1287 host->icc_ddr = devm_of_icc_get(dev, "ufs-ddr"); in ufs_qcom_icc_init()
1288 if (IS_ERR(host->icc_ddr)) in ufs_qcom_icc_init()
1289 return dev_err_probe(dev, PTR_ERR(host->icc_ddr), in ufs_qcom_icc_init()
1292 host->icc_cpu = devm_of_icc_get(dev, "cpu-ufs"); in ufs_qcom_icc_init()
1293 if (IS_ERR(host->icc_cpu)) in ufs_qcom_icc_init()
1294 return dev_err_probe(dev, PTR_ERR(host->icc_cpu), in ufs_qcom_icc_init()
1311 * ufs_qcom_init - bind phy with controller
1317 * Return: -EPROBE_DEFER if binding fails, returns negative error
1323 struct device *dev = hba->dev; in ufs_qcom_init()
1326 const struct ufs_qcom_drvdata *drvdata = of_device_get_match_data(hba->dev); in ufs_qcom_init()
1330 return -ENOMEM; in ufs_qcom_init()
1333 host->hba = hba; in ufs_qcom_init()
1337 host->core_reset = devm_reset_control_get_optional(hba->dev, "rst"); in ufs_qcom_init()
1338 if (IS_ERR(host->core_reset)) { in ufs_qcom_init()
1339 err = dev_err_probe(dev, PTR_ERR(host->core_reset), in ufs_qcom_init()
1344 /* Fire up the reset controller. Failure here is non-fatal. */ in ufs_qcom_init()
1345 host->rcdev.of_node = dev->of_node; in ufs_qcom_init()
1346 host->rcdev.ops = &ufs_qcom_reset_ops; in ufs_qcom_init()
1347 host->rcdev.owner = dev->driver->owner; in ufs_qcom_init()
1348 host->rcdev.nr_resets = 1; in ufs_qcom_init()
1349 err = devm_reset_controller_register(dev, &host->rcdev); in ufs_qcom_init()
1354 host->generic_phy = devm_phy_get(dev, "ufsphy"); in ufs_qcom_init()
1355 if (IS_ERR(host->generic_phy)) { in ufs_qcom_init()
1356 err = dev_err_probe(dev, PTR_ERR(host->generic_phy), "Failed to get PHY\n"); in ufs_qcom_init()
1365 host->device_reset = devm_gpiod_get_optional(dev, "reset", in ufs_qcom_init()
1367 if (IS_ERR(host->device_reset)) { in ufs_qcom_init()
1368 err = dev_err_probe(dev, PTR_ERR(host->device_reset), in ufs_qcom_init()
1373 ufs_qcom_get_controller_revision(hba, &host->hw_ver.major, in ufs_qcom_init()
1374 &host->hw_ver.minor, &host->hw_ver.step); in ufs_qcom_init()
1376 host->dev_ref_clk_ctrl_mmio = hba->mmio_base + REG_UFS_CFG1; in ufs_qcom_init()
1377 host->dev_ref_clk_en_mask = BIT(26); in ufs_qcom_init()
1379 list_for_each_entry(clki, &hba->clk_list_head, list) { in ufs_qcom_init()
1380 if (!strcmp(clki->name, "core_clk_unipro")) in ufs_qcom_init()
1381 clki->keep_link_active = true; in ufs_qcom_init()
1403 /* Failure is non-fatal */ in ufs_qcom_init()
1407 if (drvdata && drvdata->no_phy_retention) in ufs_qcom_init()
1408 hba->spm_lvl = UFS_PM_LVL_5; in ufs_qcom_init()
1423 phy_power_off(host->generic_phy); in ufs_qcom_exit()
1424 phy_exit(host->generic_phy); in ufs_qcom_exit()
1428 * ufs_qcom_set_clk_40ns_cycles - Configure 40ns clk cycles
1449 if (host->hw_ver.major < 4) in ufs_qcom_set_clk_40ns_cycles()
1483 dev_err(hba->dev, "UNIPRO clk freq %u MHz not supported\n", in ufs_qcom_set_clk_40ns_cycles()
1485 return -EINVAL; in ufs_qcom_set_clk_40ns_cycles()
1501 struct list_head *head = &hba->clk_list_head; in ufs_qcom_set_core_clk_ctrl()
1508 if (hba->use_pm_opp && freq != ULONG_MAX) { in ufs_qcom_set_core_clk_ctrl()
1517 if (!IS_ERR_OR_NULL(clki->clk) && in ufs_qcom_set_core_clk_ctrl()
1518 !strcmp(clki->name, "core_clk_unipro")) { in ufs_qcom_set_core_clk_ctrl()
1519 if (!clki->max_freq) { in ufs_qcom_set_core_clk_ctrl()
1525 cycles_in_1us = ceil(clki->max_freq, HZ_PER_MHZ); in ufs_qcom_set_core_clk_ctrl()
1530 cycles_in_1us = ceil(clki->max_freq, HZ_PER_MHZ); in ufs_qcom_set_core_clk_ctrl()
1532 cycles_in_1us = ceil(clk_get_rate(clki->clk), HZ_PER_MHZ); in ufs_qcom_set_core_clk_ctrl()
1545 if (host->hw_ver.major >= 4) { in ufs_qcom_set_core_clk_ctrl()
1547 return -ERANGE; in ufs_qcom_set_core_clk_ctrl()
1552 return -ERANGE; in ufs_qcom_set_core_clk_ctrl()
1576 dev_err(hba->dev, "%s ufs cfg timer failed\n", __func__); in ufs_qcom_clk_scale_up_pre_change()
1615 dev_err(hba->dev, "%s: ufs_qcom_cfg_timers() failed\n", __func__); in ufs_qcom_clk_scale_down_post_change()
1624 enum ufs_notify_change_status status) in ufs_qcom_clk_scale_notify() argument
1633 if (status == PRE_CHANGE) { in ufs_qcom_clk_scale_notify()
1667 ufshcd_rmwl(host->hba, UFS_REG_TEST_BUS_EN, in ufs_qcom_enable_test_bus()
1669 ufshcd_rmwl(host->hba, TEST_BUS_EN, TEST_BUS_EN, REG_UFS_CFG1); in ufs_qcom_enable_test_bus()
1675 host->testbus.select_major = TSTBUS_UNIPRO; in ufs_qcom_get_default_testbus_cfg()
1676 host->testbus.select_minor = 37; in ufs_qcom_get_default_testbus_cfg()
1681 if (host->testbus.select_major >= TSTBUS_MAX) { in ufs_qcom_testbus_cfg_is_ok()
1682 dev_err(host->hba->dev, in ufs_qcom_testbus_cfg_is_ok()
1684 __func__, host->testbus.select_major); in ufs_qcom_testbus_cfg_is_ok()
1698 return -EINVAL; in ufs_qcom_testbus_config()
1701 return -EPERM; in ufs_qcom_testbus_config()
1703 switch (host->testbus.select_major) { in ufs_qcom_testbus_config()
1760 ufshcd_rmwl(host->hba, TEST_BUS_SEL, in ufs_qcom_testbus_config()
1761 (u32)host->testbus.select_major << 19, in ufs_qcom_testbus_config()
1763 ufshcd_rmwl(host->hba, mask, in ufs_qcom_testbus_config()
1764 (u32)host->testbus.select_minor << offset, in ufs_qcom_testbus_config()
1785 host->testbus.select_major = j; in ufs_qcom_dump_testbus()
1788 host->testbus.select_minor = i; in ufs_qcom_dump_testbus()
1804 return -EINVAL; in ufs_qcom_dump_regs()
1808 return -ENOMEM; in ufs_qcom_dump_regs()
1822 struct ufshcd_mcq_opr_info_t *opr = &hba->mcq_opr[0]; in ufs_qcom_dump_mcq_hci_regs()
1823 void __iomem *mcq_vs_base = hba->mcq_base + UFS_MEM_VS_BASE; in ufs_qcom_dump_mcq_hci_regs()
1833 {hba->mcq_base, 0x0, 256 * 4, "MCQ HCI-0 "}, in ufs_qcom_dump_mcq_hci_regs()
1834 {hba->mcq_base, 0x400, 256 * 4, "MCQ HCI-1 "}, in ufs_qcom_dump_mcq_hci_regs()
1835 {mcq_vs_base, 0x0, 5 * 4, "MCQ VS-0 "}, in ufs_qcom_dump_mcq_hci_regs()
1836 {opr->base, 0x0, 256 * 4, "MCQ SQD-0 "}, in ufs_qcom_dump_mcq_hci_regs()
1837 {opr->base, 0x400, 256 * 4, "MCQ SQD-1 "}, in ufs_qcom_dump_mcq_hci_regs()
1838 {opr->base, 0x800, 256 * 4, "MCQ SQD-2 "}, in ufs_qcom_dump_mcq_hci_regs()
1839 {opr->base, 0xc00, 256 * 4, "MCQ SQD-3 "}, in ufs_qcom_dump_mcq_hci_regs()
1840 {opr->base, 0x1000, 256 * 4, "MCQ SQD-4 "}, in ufs_qcom_dump_mcq_hci_regs()
1841 {opr->base, 0x1400, 256 * 4, "MCQ SQD-5 "}, in ufs_qcom_dump_mcq_hci_regs()
1842 {opr->base, 0x1800, 256 * 4, "MCQ SQD-6 "}, in ufs_qcom_dump_mcq_hci_regs()
1843 {opr->base, 0x1c00, 256 * 4, "MCQ SQD-7 "}, in ufs_qcom_dump_mcq_hci_regs()
1861 dev_err(hba->dev, "HW_H8_ENTER_CNT=%d\n", ufshcd_readl(hba, REG_UFS_HW_H8_ENTER_CNT)); in ufs_qcom_dump_dbg_regs()
1862 dev_err(hba->dev, "HW_H8_EXIT_CNT=%d\n", ufshcd_readl(hba, REG_UFS_HW_H8_EXIT_CNT)); in ufs_qcom_dump_dbg_regs()
1864 dev_err(hba->dev, "SW_H8_ENTER_CNT=%d\n", ufshcd_readl(hba, REG_UFS_SW_H8_ENTER_CNT)); in ufs_qcom_dump_dbg_regs()
1865 dev_err(hba->dev, "SW_H8_EXIT_CNT=%d\n", ufshcd_readl(hba, REG_UFS_SW_H8_EXIT_CNT)); in ufs_qcom_dump_dbg_regs()
1867 dev_err(hba->dev, "SW_AFTER_HW_H8_ENTER_CNT=%d\n", in ufs_qcom_dump_dbg_regs()
1889 /* clear bit 17 - UTP_DBG_RAMS_EN */ in ufs_qcom_dump_dbg_regs()
1913 if (hba->mcq_enabled) { in ufs_qcom_dump_dbg_regs()
1921 if (hba->mcq_enabled) in ufs_qcom_dump_dbg_regs()
1932 * ufs_qcom_device_reset() - toggle the (optional) device reset line
1933 * @hba: per-adapter instance
1942 if (!host->device_reset) in ufs_qcom_device_reset()
1943 return -EOPNOTSUPP; in ufs_qcom_device_reset()
1962 p->polling_ms = 60; in ufs_qcom_config_scaling_param()
1963 p->timer = DEVFREQ_TIMER_DELAYED; in ufs_qcom_config_scaling_param()
1964 d->upthreshold = 70; in ufs_qcom_config_scaling_param()
1965 d->downdifferential = 5; in ufs_qcom_config_scaling_param()
1967 hba->clk_scaling.suspend_on_no_request = true; in ufs_qcom_config_scaling_param()
1972 struct platform_device *pdev = to_platform_device(hba->dev); in ufs_qcom_mcq_config_resource()
1978 dev_err(hba->dev, "MCQ resource not found in device tree\n"); in ufs_qcom_mcq_config_resource()
1979 return -ENODEV; in ufs_qcom_mcq_config_resource()
1982 hba->mcq_base = devm_ioremap_resource(hba->dev, res); in ufs_qcom_mcq_config_resource()
1983 if (IS_ERR(hba->mcq_base)) { in ufs_qcom_mcq_config_resource()
1984 dev_err(hba->dev, "Failed to map MCQ region: %ld\n", in ufs_qcom_mcq_config_resource()
1985 PTR_ERR(hba->mcq_base)); in ufs_qcom_mcq_config_resource()
1986 return PTR_ERR(hba->mcq_base); in ufs_qcom_mcq_config_resource()
2003 * - mmio_base = UFS_HCI_BASE in ufs_qcom_op_runtime_config()
2004 * - mcq_base = MCQ_CONFIG_BASE = mmio_base + (UFS_QCOM_MCQCAP_QCFGPTR * 0x200) in ufs_qcom_op_runtime_config()
2005 * - Doorbell registers are at: mmio_base + (UFS_QCOM_MCQCAP_QCFGPTR * 0x200) + in ufs_qcom_op_runtime_config()
2006 * - UFS_QCOM_MCQ_SQD_OFFSET in ufs_qcom_op_runtime_config()
2007 * - Which is also: mcq_base + UFS_QCOM_MCQ_SQD_OFFSET in ufs_qcom_op_runtime_config()
2019 * - doorbell_physical_addr = mmio_base + doorbell_offset in ufs_qcom_op_runtime_config()
2020 * - doorbell_physical_addr = mcq_base + (doorbell_offset - MCQ_CONFIG_OFFSET) in ufs_qcom_op_runtime_config()
2023 opr = &hba->mcq_opr[i]; in ufs_qcom_op_runtime_config()
2024 opr->offset = doorbell_offsets[i]; /* Offset relative to mmio_base */ in ufs_qcom_op_runtime_config()
2025 opr->stride = UFS_QCOM_MCQ_STRIDE; /* 256 bytes between queues */ in ufs_qcom_op_runtime_config()
2029 * base = mcq_base + (doorbell_offset - MCQ_CONFIG_OFFSET) in ufs_qcom_op_runtime_config()
2031 opr->base = hba->mcq_base + (opr->offset - UFS_QCOM_MCQ_CONFIG_OFFSET); in ufs_qcom_op_runtime_config()
2046 /* Read from MCQ vendor-specific register in MCQ region */ in ufs_qcom_get_outstanding_cqs()
2047 *ocqs = readl(hba->mcq_base + UFS_MEM_CQIS_VS); in ufs_qcom_get_outstanding_cqs()
2061 unsigned int irq; member
2066 static irqreturn_t ufs_qcom_mcq_esi_handler(int irq, void *data) in ufs_qcom_mcq_esi_handler() argument
2069 struct ufs_hba *hba = qi->hba; in ufs_qcom_mcq_esi_handler()
2070 struct ufs_hw_queue *hwq = &hba->uhq[qi->idx]; in ufs_qcom_mcq_esi_handler()
2072 ufshcd_mcq_write_cqis(hba, 0x1, qi->idx); in ufs_qcom_mcq_esi_handler()
2083 if (host->esi_enabled) in ufs_qcom_config_esi()
2090 nr_irqs = hba->nr_hw_queues - hba->nr_queues[HCTX_TYPE_POLL]; in ufs_qcom_config_esi()
2092 ret = platform_device_msi_init_and_alloc_irqs(hba->dev, nr_irqs, in ufs_qcom_config_esi()
2095 dev_warn(hba->dev, "Platform MSI not supported or failed, continuing without ESI\n"); in ufs_qcom_config_esi()
2099 struct ufs_qcom_irq *qi = devm_kcalloc(hba->dev, nr_irqs, sizeof(*qi), GFP_KERNEL); in ufs_qcom_config_esi()
2102 platform_device_msi_free_irqs_all(hba->dev); in ufs_qcom_config_esi()
2103 return -ENOMEM; in ufs_qcom_config_esi()
2107 qi[idx].irq = msi_get_virq(hba->dev, idx); in ufs_qcom_config_esi()
2111 ret = devm_request_irq(hba->dev, qi[idx].irq, ufs_qcom_mcq_esi_handler, in ufs_qcom_config_esi()
2112 IRQF_SHARED, "qcom-mcq-esi", qi + idx); in ufs_qcom_config_esi()
2114 dev_err(hba->dev, "%s: Failed to request IRQ for %d, err = %d\n", in ufs_qcom_config_esi()
2115 __func__, qi[idx].irq, ret); in ufs_qcom_config_esi()
2118 devm_free_irq(hba->dev, qi[j].irq, qi + j); in ufs_qcom_config_esi()
2119 platform_device_msi_free_irqs_all(hba->dev); in ufs_qcom_config_esi()
2120 devm_kfree(hba->dev, qi); in ufs_qcom_config_esi()
2125 if (host->hw_ver.major >= 6) { in ufs_qcom_config_esi()
2126 ufshcd_rmwl(hba, ESI_VEC_MASK, FIELD_PREP(ESI_VEC_MASK, MAX_ESI_VEC - 1), in ufs_qcom_config_esi()
2130 host->esi_enabled = true; in ufs_qcom_config_esi()
2143 opp = dev_pm_opp_find_freq_exact_indexed(hba->dev, freq, 0, true); in ufs_qcom_opp_freq_to_clk_freq()
2145 dev_err(hba->dev, "Failed to find OPP for exact frequency %lu\n", freq); in ufs_qcom_opp_freq_to_clk_freq()
2149 list_for_each_entry(clki, &hba->clk_list_head, list) { in ufs_qcom_opp_freq_to_clk_freq()
2150 if (!strcmp(clki->name, name)) { in ufs_qcom_opp_freq_to_clk_freq()
2159 dev_err(hba->dev, "Failed to find clock '%s' in clk list\n", name); in ufs_qcom_opp_freq_to_clk_freq()
2176 if (!hba->use_pm_opp) in ufs_qcom_freq_to_gear_speed()
2199 dev_err(hba->dev, "%s: Unsupported clock freq : %lu\n", __func__, freq); in ufs_qcom_freq_to_gear_speed()
2203 return min_t(u32, gear, hba->max_pwr_info.info.gear_rx); in ufs_qcom_freq_to_gear_speed()
2207 * struct ufs_hba_qcom_vops - UFS QCOM specific variant operations
2238 * ufs_qcom_probe - probe routine of the driver
2241 * Return: zero for success and non-zero for failure.
2246 struct device *dev = &pdev->dev; in ufs_qcom_probe()
2257 * ufs_qcom_remove - set driver_data of the device to NULL
2268 if (host->esi_enabled) in ufs_qcom_remove()
2269 platform_device_msi_free_irqs_all(hba->dev); in ufs_qcom_remove()
2279 { .compatible = "qcom,sm8550-ufshc", .data = &ufs_qcom_sm8550_drvdata },
2280 { .compatible = "qcom,sm8650-ufshc", .data = &ufs_qcom_sm8550_drvdata },
2310 .name = "ufshcd-qcom",