Lines Matching +full:syscon +full:- +full:poweroff

1 // SPDX-License-Identifier: GPL-2.0
9 #include <linux/arm-smccc.h>
21 #include "ufshcd-crypto.h"
22 #include "ufshcd-pltfrm.h"
25 #include "ufs-mediatek.h"
28 #include "ufs-mediatek-trace.h"
55 { .compatible = "mediatek,mt8183-ufshci" },
63 return !!(host->caps & UFS_MTK_CAP_BOOST_CRYPT_ENGINE); in ufs_mtk_is_boost_crypt_enabled()
70 return !!(host->caps & UFS_MTK_CAP_VA09_PWR_CTRL); in ufs_mtk_is_va09_supported()
77 return !!(host->caps & UFS_MTK_CAP_BROKEN_VCC); in ufs_mtk_is_broken_vcc()
122 dev_info(hba->dev, "%s: crypto enable failed, err: %lu\n", in ufs_mtk_crypto_enable()
124 hba->caps &= ~UFSHCD_CAP_CRYPTO; in ufs_mtk_crypto_enable()
132 reset_control_assert(host->hci_reset); in ufs_mtk_host_reset()
133 reset_control_assert(host->crypto_reset); in ufs_mtk_host_reset()
134 reset_control_assert(host->unipro_reset); in ufs_mtk_host_reset()
138 reset_control_deassert(host->unipro_reset); in ufs_mtk_host_reset()
139 reset_control_deassert(host->crypto_reset); in ufs_mtk_host_reset()
140 reset_control_deassert(host->hci_reset); in ufs_mtk_host_reset()
147 *rc = devm_reset_control_get(hba->dev, str); in ufs_mtk_init_reset_control()
149 dev_info(hba->dev, "Failed to get reset control %s: %ld\n", in ufs_mtk_init_reset_control()
159 ufs_mtk_init_reset_control(hba, &host->hci_reset, in ufs_mtk_init_reset()
161 ufs_mtk_init_reset_control(hba, &host->unipro_reset, in ufs_mtk_init_reset()
163 ufs_mtk_init_reset_control(hba, &host->crypto_reset, in ufs_mtk_init_reset()
174 if (host->unipro_lpm) { in ufs_mtk_hce_enable_notify()
175 hba->vps->hba_enable_delay_us = 0; in ufs_mtk_hce_enable_notify()
177 hba->vps->hba_enable_delay_us = 600; in ufs_mtk_hce_enable_notify()
181 if (hba->caps & UFSHCD_CAP_CRYPTO) in ufs_mtk_hce_enable_notify()
184 if (host->caps & UFS_MTK_CAP_DISABLE_AH8) { in ufs_mtk_hce_enable_notify()
185 spin_lock_irqsave(hba->host->host_lock, flags); in ufs_mtk_hce_enable_notify()
188 spin_unlock_irqrestore(hba->host->host_lock, in ufs_mtk_hce_enable_notify()
191 hba->capabilities &= ~MASK_AUTO_HIBERN8_SUPPORT; in ufs_mtk_hce_enable_notify()
192 hba->ahit = 0; in ufs_mtk_hce_enable_notify()
202 struct device *dev = hba->dev; in ufs_mtk_bind_mphy()
203 struct device_node *np = dev->of_node; in ufs_mtk_bind_mphy()
206 host->mphy = devm_of_phy_get_by_index(dev, np, 0); in ufs_mtk_bind_mphy()
208 if (host->mphy == ERR_PTR(-EPROBE_DEFER)) { in ufs_mtk_bind_mphy()
213 err = -EPROBE_DEFER; in ufs_mtk_bind_mphy()
217 } else if (IS_ERR(host->mphy)) { in ufs_mtk_bind_mphy()
218 err = PTR_ERR(host->mphy); in ufs_mtk_bind_mphy()
219 if (err != -ENODEV) { in ufs_mtk_bind_mphy()
226 host->mphy = NULL; in ufs_mtk_bind_mphy()
231 if (err == -ENODEV) in ufs_mtk_bind_mphy()
244 if (host->ref_clk_enabled == on) in ufs_mtk_setup_ref_clk()
249 ufshcd_delay_us(host->ref_clk_ungating_wait_us, 10); in ufs_mtk_setup_ref_clk()
268 dev_err(hba->dev, "missing ack of refclk req, reg: 0x%x\n", value); in ufs_mtk_setup_ref_clk()
270 ufs_mtk_ref_clk_notify(host->ref_clk_enabled, res); in ufs_mtk_setup_ref_clk()
272 return -ETIMEDOUT; in ufs_mtk_setup_ref_clk()
275 host->ref_clk_enabled = on; in ufs_mtk_setup_ref_clk()
277 ufshcd_delay_us(host->ref_clk_gating_wait_us, 10); in ufs_mtk_setup_ref_clk()
289 if (hba->dev_info.clk_gating_wait_us) { in ufs_mtk_setup_ref_clk_wait_us()
290 host->ref_clk_gating_wait_us = in ufs_mtk_setup_ref_clk_wait_us()
291 hba->dev_info.clk_gating_wait_us; in ufs_mtk_setup_ref_clk_wait_us()
293 host->ref_clk_gating_wait_us = gating_us; in ufs_mtk_setup_ref_clk_wait_us()
296 host->ref_clk_ungating_wait_us = ungating_us; in ufs_mtk_setup_ref_clk_wait_us()
322 return -ETIMEDOUT; in ufs_mtk_wait_link_state()
328 struct phy *mphy = host->mphy; in ufs_mtk_mphy_power_on()
332 if (!mphy || !(on ^ host->mphy_powered_on)) in ufs_mtk_mphy_power_on()
337 ret = regulator_enable(host->reg_va09); in ufs_mtk_mphy_power_on()
349 ret = regulator_disable(host->reg_va09); in ufs_mtk_mphy_power_on()
356 dev_info(hba->dev, in ufs_mtk_mphy_power_on()
361 host->mphy_powered_on = on; in ufs_mtk_mphy_power_on()
392 cfg = host->crypt; in ufs_mtk_boost_crypt()
393 volt = cfg->vcore_volt; in ufs_mtk_boost_crypt()
394 reg = cfg->reg_vcore; in ufs_mtk_boost_crypt()
396 ret = clk_prepare_enable(cfg->clk_crypt_mux); in ufs_mtk_boost_crypt()
398 dev_info(hba->dev, "clk_prepare_enable(): %d\n", in ufs_mtk_boost_crypt()
406 dev_info(hba->dev, in ufs_mtk_boost_crypt()
411 ret = clk_set_parent(cfg->clk_crypt_mux, in ufs_mtk_boost_crypt()
412 cfg->clk_crypt_perf); in ufs_mtk_boost_crypt()
414 dev_info(hba->dev, in ufs_mtk_boost_crypt()
420 ret = clk_set_parent(cfg->clk_crypt_mux, in ufs_mtk_boost_crypt()
421 cfg->clk_crypt_lp); in ufs_mtk_boost_crypt()
423 dev_info(hba->dev, in ufs_mtk_boost_crypt()
430 dev_info(hba->dev, in ufs_mtk_boost_crypt()
435 clk_disable_unprepare(cfg->clk_crypt_mux); in ufs_mtk_boost_crypt()
443 ret = ufs_mtk_get_host_clk(hba->dev, name, clk); in ufs_mtk_init_host_clk()
445 dev_info(hba->dev, "%s: failed to get %s: %d", __func__, in ufs_mtk_init_host_clk()
456 struct device *dev = hba->dev; in ufs_mtk_init_boost_crypt()
460 host->crypt = devm_kzalloc(dev, sizeof(*(host->crypt)), in ufs_mtk_init_boost_crypt()
462 if (!host->crypt) in ufs_mtk_init_boost_crypt()
465 reg = devm_regulator_get_optional(dev, "dvfsrc-vcore"); in ufs_mtk_init_boost_crypt()
467 dev_info(dev, "failed to get dvfsrc-vcore: %ld", in ufs_mtk_init_boost_crypt()
472 if (of_property_read_u32(dev->of_node, "boost-crypt-vcore-min", in ufs_mtk_init_boost_crypt()
474 dev_info(dev, "failed to get boost-crypt-vcore-min"); in ufs_mtk_init_boost_crypt()
478 cfg = host->crypt; in ufs_mtk_init_boost_crypt()
480 &cfg->clk_crypt_mux)) in ufs_mtk_init_boost_crypt()
484 &cfg->clk_crypt_lp)) in ufs_mtk_init_boost_crypt()
488 &cfg->clk_crypt_perf)) in ufs_mtk_init_boost_crypt()
491 cfg->reg_vcore = reg; in ufs_mtk_init_boost_crypt()
492 cfg->vcore_volt = volt; in ufs_mtk_init_boost_crypt()
493 host->caps |= UFS_MTK_CAP_BOOST_CRYPT_ENGINE; in ufs_mtk_init_boost_crypt()
503 host->reg_va09 = regulator_get(hba->dev, "va09"); in ufs_mtk_init_va09_pwr_ctrl()
504 if (!host->reg_va09) in ufs_mtk_init_va09_pwr_ctrl()
505 dev_info(hba->dev, "failed to get va09"); in ufs_mtk_init_va09_pwr_ctrl()
507 host->caps |= UFS_MTK_CAP_VA09_PWR_CTRL; in ufs_mtk_init_va09_pwr_ctrl()
513 struct device_node *np = hba->dev->of_node; in ufs_mtk_init_host_caps()
515 if (of_property_read_bool(np, "mediatek,ufs-boost-crypt")) in ufs_mtk_init_host_caps()
518 if (of_property_read_bool(np, "mediatek,ufs-support-va09")) in ufs_mtk_init_host_caps()
521 if (of_property_read_bool(np, "mediatek,ufs-disable-ah8")) in ufs_mtk_init_host_caps()
522 host->caps |= UFS_MTK_CAP_DISABLE_AH8; in ufs_mtk_init_host_caps()
524 if (of_property_read_bool(np, "mediatek,ufs-broken-vcc")) in ufs_mtk_init_host_caps()
525 host->caps |= UFS_MTK_CAP_BROKEN_VCC; in ufs_mtk_init_host_caps()
527 dev_info(hba->dev, "caps: 0x%x", host->caps); in ufs_mtk_init_host_caps()
538 phy_power_on(host->mphy); in ufs_mtk_scale_perf()
540 phy_power_off(host->mphy); in ufs_mtk_scale_perf()
544 * ufs_mtk_setup_clocks - enables/disable clocks
549 * Returns 0 on success, non-zero on failure.
573 * Gate ref-clk and poweroff mphy if link state is in in ufs_mtk_setup_clocks()
574 * OFF or Hibern8 by either Auto-Hibern8 or in ufs_mtk_setup_clocks()
598 if (host->hw_ver.major) in ufs_mtk_get_controller_version()
602 host->hw_ver.major = 2; in ufs_mtk_get_controller_version()
607 host->hw_ver.major = 3; in ufs_mtk_get_controller_version()
612 if (hba->ufs_version < ufshci_version(3, 0)) in ufs_mtk_get_controller_version()
613 hba->ufs_version = ufshci_version(3, 0); in ufs_mtk_get_controller_version()
620 return hba->ufs_version; in ufs_mtk_get_ufs_hci_version()
624 * ufs_mtk_init - find other essential mmio bases
630 * Returns -EPROBE_DEFER if binding fails, returns negative error
636 struct device *dev = hba->dev; in ufs_mtk_init()
642 err = -ENOMEM; in ufs_mtk_init()
647 host->hba = hba; in ufs_mtk_init()
652 err = -EINVAL; in ufs_mtk_init()
666 hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND; in ufs_mtk_init()
668 /* Enable clock-gating */ in ufs_mtk_init()
669 hba->caps |= UFSHCD_CAP_CLK_GATING; in ufs_mtk_init()
672 hba->caps |= UFSHCD_CAP_CRYPTO; in ufs_mtk_init()
675 hba->caps |= UFSHCD_CAP_WB_EN; in ufs_mtk_init()
676 hba->quirks |= UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL; in ufs_mtk_init()
677 hba->vps->wb_flush_threshold = UFS_WB_BUF_REMAIN_PERCENT(80); in ufs_mtk_init()
679 if (host->caps & UFS_MTK_CAP_DISABLE_AH8) in ufs_mtk_init()
680 hba->caps |= UFSHCD_CAP_HIBERN8_WITH_CLK_GATING; in ufs_mtk_init()
720 if (host->hw_ver.major >= 3) { in ufs_mtk_pre_pwr_change()
722 dev_req_params->gear_tx, in ufs_mtk_pre_pwr_change()
744 ret = -EINVAL; in ufs_mtk_pwr_change_notify()
761 * Forcibly set as non-LPM mode if UIC commands is failed in ufs_mtk_unipro_set_lpm()
762 * to use default hba_enable_delay_us value for re-enabling in ufs_mtk_unipro_set_lpm()
765 host->unipro_lpm = lpm; in ufs_mtk_unipro_set_lpm()
809 if (ufshcd_is_auto_hibern8_supported(hba) && hba->ahit) in ufs_mtk_setup_clk_gating()
811 hba->ahit); in ufs_mtk_setup_clk_gating()
814 spin_lock_irqsave(hba->host->host_lock, flags); in ufs_mtk_setup_clk_gating()
815 hba->clk_gating.delay_ms = ah_ms + 5; in ufs_mtk_setup_clk_gating()
816 spin_unlock_irqrestore(hba->host->host_lock, flags); in ufs_mtk_setup_clk_gating()
827 hba->ahit = FIELD_PREP(UFSHCI_AHIBERN8_TIMER_MASK, 10) | in ufs_mtk_post_link()
848 ret = -EINVAL; in ufs_mtk_link_startup_notify()
878 dev_info(hba->dev, "device reset done\n"); in ufs_mtk_device_reset()
924 if (!hba->vreg_info.vccq2 || !hba->vreg_info.vcc) in ufs_mtk_vreg_set_lpm()
927 if (lpm && !hba->vreg_info.vcc->enabled) in ufs_mtk_vreg_set_lpm()
928 regulator_set_mode(hba->vreg_info.vccq2->reg, in ufs_mtk_vreg_set_lpm()
931 regulator_set_mode(hba->vreg_info.vccq2->reg, in ufs_mtk_vreg_set_lpm()
949 * ufshcd_suspend() re-enabling regulators while vreg is still in ufs_mtk_suspend()
950 * in low-power mode. in ufs_mtk_suspend()
969 return -EAGAIN; in ufs_mtk_suspend()
995 ufshcd_dump_regs(hba, REG_UFS_REFCLK_CTRL, 0x4, "Ref-Clk Ctrl "); in ufs_mtk_dbg_register_dump()
1000 REG_UFS_REJECT_MON - REG_UFS_MPHYCTRL + 4, in ufs_mtk_dbg_register_dump()
1010 struct ufs_dev_info *dev_info = &hba->dev_info; in ufs_mtk_apply_dev_quirks()
1011 u16 mid = dev_info->wmanufacturerid; in ufs_mtk_apply_dev_quirks()
1035 if (ufs_mtk_is_broken_vcc(hba) && hba->vreg_info.vcc && in ufs_mtk_fixup_dev_quirks()
1036 (hba->dev_quirks & UFS_DEVICE_QUIRK_DELAY_AFTER_LPM)) { in ufs_mtk_fixup_dev_quirks()
1037 hba->vreg_info.vcc->always_on = true; in ufs_mtk_fixup_dev_quirks()
1039 * VCC will be kept always-on thus we don't in ufs_mtk_fixup_dev_quirks()
1042 hba->dev_quirks &= ~(UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM | in ufs_mtk_fixup_dev_quirks()
1056 * struct ufs_hba_mtk_vops - UFS MTK specific variant operations
1079 * ufs_mtk_probe - probe routine of the driver
1082 * Return zero for success and non-zero for failure
1087 struct device *dev = &pdev->dev; in ufs_mtk_probe()
1093 "ti,syscon-reset"); in ufs_mtk_probe()
1095 dev_notice(dev, "find ti,syscon-reset fail\n"); in ufs_mtk_probe()
1103 link = device_link_add(dev, &reset_pdev->dev, in ufs_mtk_probe()
1110 if (link->status == DL_STATE_DORMANT) { in ufs_mtk_probe()
1111 err = -EPROBE_DEFER; in ufs_mtk_probe()
1128 * ufs_mtk_remove - set driver_data of the device to NULL
1137 pm_runtime_get_sync(&(pdev)->dev); in ufs_mtk_remove()
1154 .name = "ufshcd-mtk",