Loading drivers/firmware/qcom_scm-smc.c +17 −0 Original line number Diff line number Diff line Loading @@ -816,6 +816,23 @@ int __qcom_scm_config_cpu_errata(struct device *dev) return qcom_scm_call(dev, &desc); } void __qcom_scm_phy_update_scm_level_shifter(struct device *dev, u32 val) { int ret; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_BOOT, .cmd = QCOM_SCM_QUSB2PHY_LVL_SHIFTER_CMD_ID, .owner = ARM_SMCCC_OWNER_SIP }; desc.args[0] = val; desc.arginfo = QCOM_SCM_ARGS(1); ret = qcom_scm_call(dev, &desc); if (ret) pr_err("Failed to update scm level shifter=0x%x\n", ret); } bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral) { int ret; Loading drivers/firmware/qcom_scm.c +8 −0 Original line number Diff line number Diff line Loading @@ -174,6 +174,14 @@ int qcom_scm_config_cpu_errata(void) } EXPORT_SYMBOL(qcom_scm_config_cpu_errata); void qcom_scm_phy_update_scm_level_shifter(u32 val) { struct device *dev = __scm ? __scm->dev : NULL; __qcom_scm_phy_update_scm_level_shifter(dev, val); } EXPORT_SYMBOL(qcom_scm_phy_update_scm_level_shifter); /** * qcom_scm_pas_supported() - Check if the peripheral authentication service is * available for the given peripherial Loading drivers/firmware/qcom_scm.h +2 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #define QCOM_SCM_BOOT_SWITCH_MODE 0x0f #define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10 #define QCOM_SCM_BOOT_CONFIG_CPU_ERRATA 0x12 #define QCOM_SCM_QUSB2PHY_LVL_SHIFTER_CMD_ID 0x1B extern int __qcom_scm_set_cold_boot_addr(struct device *dev, void *entry, const cpumask_t *cpus); extern int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, Loading @@ -29,6 +30,7 @@ extern int __qcom_scm_spin_cpu(struct device *dev); extern int __qcom_scm_set_dload_mode(struct device *dev, enum qcom_download_mode mode); extern int __qcom_scm_config_cpu_errata(struct device *dev); extern void __qcom_scm_phy_update_scm_level_shifter(struct device *dev, u32 val); #define QCOM_SCM_FLUSH_FLAG_MASK 0x3 #define QCOM_SCM_SVC_PIL 0x02 Loading drivers/usb/phy/phy-msm-qusb.c +23 −13 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. */ #include <linux/module.h> Loading @@ -14,6 +14,8 @@ #include <linux/debugfs.h> #include <linux/platform_device.h> #include <linux/power_supply.h> #include <linux/qcom_scm.h> #include <linux/arm-smccc.h> #include <linux/regulator/consumer.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> Loading Loading @@ -129,6 +131,7 @@ struct qusb_phy { bool ulpi_mode; bool dpdm_enable; bool is_se_clk; bool scm_lvl_shifter; struct regulator_desc dpdm_rdesc; struct regulator_dev *dpdm_rdev; Loading @@ -145,6 +148,18 @@ struct qusb_phy { u8 tune5; }; static void qusb_phy_update_tcsr_level_shifter(struct qusb_phy *qphy, u32 val) { if (qphy->tcsr_clamp_dig_n) { writel_relaxed(val, qphy->tcsr_clamp_dig_n); dev_dbg(qphy->phy.dev, "update tcsr level shifter: %d\n", val); } else if (qphy->scm_lvl_shifter) { dev_dbg(qphy->phy.dev, "update scm level shifter: %d\n", val); qcom_scm_phy_update_scm_level_shifter(val); } } static void qusb_phy_enable_clocks(struct qusb_phy *qphy, bool on) { dev_dbg(qphy->phy.dev, "%s(): on:%d\n", __func__, on); Loading Loading @@ -662,9 +677,7 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend) /* Make sure that above write is completed */ wmb(); if (qphy->tcsr_clamp_dig_n) writel_relaxed(0x0, qphy->tcsr_clamp_dig_n); qusb_phy_update_tcsr_level_shifter(qphy, 0); } qusb_phy_enable_clocks(qphy, false); Loading @@ -690,9 +703,7 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend) qphy->base + QUSB2PHY_PORT_INTR_CTRL); } else { qusb_phy_enable_power(qphy, true); if (qphy->tcsr_clamp_dig_n) writel_relaxed(0x1, qphy->tcsr_clamp_dig_n); qusb_phy_update_tcsr_level_shifter(qphy, 1); qusb_phy_enable_clocks(qphy, true); } qphy->suspended = false; Loading Loading @@ -749,9 +760,7 @@ static int qusb_phy_dpdm_regulator_enable(struct regulator_dev *rdev) } qphy->dpdm_enable = true; if (qphy->put_into_high_z_state) { if (qphy->tcsr_clamp_dig_n) writel_relaxed(0x1, qphy->tcsr_clamp_dig_n); qusb_phy_update_tcsr_level_shifter(qphy, 1); qusb_phy_gdsc(qphy, true); qusb_phy_enable_clocks(qphy, true); Loading Loading @@ -809,9 +818,7 @@ static int qusb_phy_dpdm_regulator_disable(struct regulator_dev *rdev) if (qphy->dpdm_enable) { /* If usb core is active, rely on set_suspend to clamp phy */ if (!qphy->cable_connected) { if (qphy->tcsr_clamp_dig_n) writel_relaxed(0x0, qphy->tcsr_clamp_dig_n); qusb_phy_update_tcsr_level_shifter(qphy, 0); } ret = qusb_phy_enable_power(qphy, false); if (ret < 0) { Loading Loading @@ -972,6 +979,9 @@ static int qusb_phy_probe(struct platform_device *pdev) } } qphy->scm_lvl_shifter = of_property_read_bool(dev->of_node, "qcom,secure-level-shifter"); ret = of_property_read_u32(dev->of_node, "qcom,usb-hs-ac-bitmask", &qphy->usb_hs_ac_bitmask); if (!ret) { Loading include/linux/qcom_scm.h +2 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ extern int qcom_scm_spin_cpu(void); extern void qcom_scm_set_download_mode(enum qcom_download_mode mode, phys_addr_t tcsr_boot_misc); extern int qcom_scm_config_cpu_errata(void); extern void qcom_scm_phy_update_scm_level_shifter(u32 val); extern bool qcom_scm_pas_supported(u32 peripheral); extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size); Loading Loading @@ -219,6 +220,7 @@ static inline void qcom_scm_set_download_mode(enum qcom_download_mode mode, phys_addr_t tcsr_boot_misc) {} static inline int qcom_scm_config_cpu_errata(void) { return -ENODEV; } static inline void qcom_scm_phy_update_scm_level_shifter(u32 val) {} static inline bool qcom_scm_pas_supported(u32 peripheral) { return false; } static inline int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size) { return -ENODEV; } Loading Loading
drivers/firmware/qcom_scm-smc.c +17 −0 Original line number Diff line number Diff line Loading @@ -816,6 +816,23 @@ int __qcom_scm_config_cpu_errata(struct device *dev) return qcom_scm_call(dev, &desc); } void __qcom_scm_phy_update_scm_level_shifter(struct device *dev, u32 val) { int ret; struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_BOOT, .cmd = QCOM_SCM_QUSB2PHY_LVL_SHIFTER_CMD_ID, .owner = ARM_SMCCC_OWNER_SIP }; desc.args[0] = val; desc.arginfo = QCOM_SCM_ARGS(1); ret = qcom_scm_call(dev, &desc); if (ret) pr_err("Failed to update scm level shifter=0x%x\n", ret); } bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral) { int ret; Loading
drivers/firmware/qcom_scm.c +8 −0 Original line number Diff line number Diff line Loading @@ -174,6 +174,14 @@ int qcom_scm_config_cpu_errata(void) } EXPORT_SYMBOL(qcom_scm_config_cpu_errata); void qcom_scm_phy_update_scm_level_shifter(u32 val) { struct device *dev = __scm ? __scm->dev : NULL; __qcom_scm_phy_update_scm_level_shifter(dev, val); } EXPORT_SYMBOL(qcom_scm_phy_update_scm_level_shifter); /** * qcom_scm_pas_supported() - Check if the peripheral authentication service is * available for the given peripherial Loading
drivers/firmware/qcom_scm.h +2 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #define QCOM_SCM_BOOT_SWITCH_MODE 0x0f #define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10 #define QCOM_SCM_BOOT_CONFIG_CPU_ERRATA 0x12 #define QCOM_SCM_QUSB2PHY_LVL_SHIFTER_CMD_ID 0x1B extern int __qcom_scm_set_cold_boot_addr(struct device *dev, void *entry, const cpumask_t *cpus); extern int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, Loading @@ -29,6 +30,7 @@ extern int __qcom_scm_spin_cpu(struct device *dev); extern int __qcom_scm_set_dload_mode(struct device *dev, enum qcom_download_mode mode); extern int __qcom_scm_config_cpu_errata(struct device *dev); extern void __qcom_scm_phy_update_scm_level_shifter(struct device *dev, u32 val); #define QCOM_SCM_FLUSH_FLAG_MASK 0x3 #define QCOM_SCM_SVC_PIL 0x02 Loading
drivers/usb/phy/phy-msm-qusb.c +23 −13 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. */ #include <linux/module.h> Loading @@ -14,6 +14,8 @@ #include <linux/debugfs.h> #include <linux/platform_device.h> #include <linux/power_supply.h> #include <linux/qcom_scm.h> #include <linux/arm-smccc.h> #include <linux/regulator/consumer.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> Loading Loading @@ -129,6 +131,7 @@ struct qusb_phy { bool ulpi_mode; bool dpdm_enable; bool is_se_clk; bool scm_lvl_shifter; struct regulator_desc dpdm_rdesc; struct regulator_dev *dpdm_rdev; Loading @@ -145,6 +148,18 @@ struct qusb_phy { u8 tune5; }; static void qusb_phy_update_tcsr_level_shifter(struct qusb_phy *qphy, u32 val) { if (qphy->tcsr_clamp_dig_n) { writel_relaxed(val, qphy->tcsr_clamp_dig_n); dev_dbg(qphy->phy.dev, "update tcsr level shifter: %d\n", val); } else if (qphy->scm_lvl_shifter) { dev_dbg(qphy->phy.dev, "update scm level shifter: %d\n", val); qcom_scm_phy_update_scm_level_shifter(val); } } static void qusb_phy_enable_clocks(struct qusb_phy *qphy, bool on) { dev_dbg(qphy->phy.dev, "%s(): on:%d\n", __func__, on); Loading Loading @@ -662,9 +677,7 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend) /* Make sure that above write is completed */ wmb(); if (qphy->tcsr_clamp_dig_n) writel_relaxed(0x0, qphy->tcsr_clamp_dig_n); qusb_phy_update_tcsr_level_shifter(qphy, 0); } qusb_phy_enable_clocks(qphy, false); Loading @@ -690,9 +703,7 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend) qphy->base + QUSB2PHY_PORT_INTR_CTRL); } else { qusb_phy_enable_power(qphy, true); if (qphy->tcsr_clamp_dig_n) writel_relaxed(0x1, qphy->tcsr_clamp_dig_n); qusb_phy_update_tcsr_level_shifter(qphy, 1); qusb_phy_enable_clocks(qphy, true); } qphy->suspended = false; Loading Loading @@ -749,9 +760,7 @@ static int qusb_phy_dpdm_regulator_enable(struct regulator_dev *rdev) } qphy->dpdm_enable = true; if (qphy->put_into_high_z_state) { if (qphy->tcsr_clamp_dig_n) writel_relaxed(0x1, qphy->tcsr_clamp_dig_n); qusb_phy_update_tcsr_level_shifter(qphy, 1); qusb_phy_gdsc(qphy, true); qusb_phy_enable_clocks(qphy, true); Loading Loading @@ -809,9 +818,7 @@ static int qusb_phy_dpdm_regulator_disable(struct regulator_dev *rdev) if (qphy->dpdm_enable) { /* If usb core is active, rely on set_suspend to clamp phy */ if (!qphy->cable_connected) { if (qphy->tcsr_clamp_dig_n) writel_relaxed(0x0, qphy->tcsr_clamp_dig_n); qusb_phy_update_tcsr_level_shifter(qphy, 0); } ret = qusb_phy_enable_power(qphy, false); if (ret < 0) { Loading Loading @@ -972,6 +979,9 @@ static int qusb_phy_probe(struct platform_device *pdev) } } qphy->scm_lvl_shifter = of_property_read_bool(dev->of_node, "qcom,secure-level-shifter"); ret = of_property_read_u32(dev->of_node, "qcom,usb-hs-ac-bitmask", &qphy->usb_hs_ac_bitmask); if (!ret) { Loading
include/linux/qcom_scm.h +2 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ extern int qcom_scm_spin_cpu(void); extern void qcom_scm_set_download_mode(enum qcom_download_mode mode, phys_addr_t tcsr_boot_misc); extern int qcom_scm_config_cpu_errata(void); extern void qcom_scm_phy_update_scm_level_shifter(u32 val); extern bool qcom_scm_pas_supported(u32 peripheral); extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size); Loading Loading @@ -219,6 +220,7 @@ static inline void qcom_scm_set_download_mode(enum qcom_download_mode mode, phys_addr_t tcsr_boot_misc) {} static inline int qcom_scm_config_cpu_errata(void) { return -ENODEV; } static inline void qcom_scm_phy_update_scm_level_shifter(u32 val) {} static inline bool qcom_scm_pas_supported(u32 peripheral) { return false; } static inline int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size) { return -ENODEV; } Loading