Loading arch/arm64/boot/dts/qcom/kona.dtsi +66 −0 Original line number Diff line number Diff line Loading @@ -1637,6 +1637,12 @@ clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "bps_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 1>; qcom,support-hw-trigger; qcom,retain-regs; }; Loading @@ -1649,6 +1655,12 @@ clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "ife_0_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 1>; qcom,retain-regs; }; Loading @@ -1660,6 +1672,12 @@ clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "ife_1_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 1>; qcom,retain-regs; }; Loading @@ -1671,6 +1689,12 @@ clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "ipe_0_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 1>; qcom,support-hw-trigger; qcom,retain-regs; }; Loading @@ -1683,6 +1707,12 @@ clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "sbi_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 1>; qcom,retain-regs; }; Loading @@ -1694,6 +1724,12 @@ clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "titan_top_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 1>; qcom,retain-regs; }; Loading @@ -1706,6 +1742,12 @@ clocks = <&clock_gcc GCC_DISP_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "mdss_core_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_DISPLAY_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_DISPLAY_CFG 0 1>; qcom,support-hw-trigger; qcom,retain-regs; }; Loading Loading @@ -1774,6 +1816,12 @@ clocks = <&clock_gcc GCC_VIDEO_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "mvs0_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VENUS_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VENUS_CFG 0 1>; qcom,retain-regs; }; Loading @@ -1785,6 +1833,12 @@ clocks = <&clock_gcc GCC_VIDEO_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "mvs0c_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VENUS_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VENUS_CFG 0 1>; qcom,retain-regs; }; Loading @@ -1796,6 +1850,12 @@ clocks = <&clock_gcc GCC_VIDEO_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "mvs1_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VENUS_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VENUS_CFG 0 1>; qcom,support-hw-trigger; qcom,retain-regs; }; Loading @@ -1808,6 +1868,12 @@ clocks = <&clock_gcc GCC_VIDEO_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "mvs1c_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VENUS_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VENUS_CFG 0 1>; qcom,retain-regs; }; Loading drivers/clk/qcom/gdsc-regulator.c +157 −51 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include <linux/delay.h> #include <linux/err.h> #include <linux/of.h> #include <linux/msm-bus.h> #include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> Loading Loading @@ -55,6 +56,8 @@ struct gdsc { struct clk **clocks; struct regulator *parent_regulator; struct reset_control **reset_clocks; struct msm_bus_scale_pdata *bus_pdata; u32 bus_handle; bool toggle_mem; bool toggle_periph; bool toggle_logic; Loading @@ -66,6 +69,7 @@ struct gdsc { bool is_gdsc_enabled; bool allow_clear; bool reset_aon; bool is_bus_enabled; int clock_count; int reset_count; int root_clk_idx; Loading @@ -77,8 +81,6 @@ enum gdscr_status { DISABLED, }; static DEFINE_MUTEX(gdsc_seq_lock); static inline u32 gdsc_mb(struct gdsc *gds) { u32 reg; Loading Loading @@ -137,6 +139,8 @@ static int gdsc_is_enabled(struct regulator_dev *rdev) { struct gdsc *sc = rdev_get_drvdata(rdev); uint32_t regval; int ret; bool is_enabled = false; if (!sc->toggle_logic) return !sc->resets_asserted; Loading Loading @@ -165,6 +169,15 @@ static int gdsc_is_enabled(struct regulator_dev *rdev) } } if (sc->bus_handle && !sc->is_bus_enabled) { ret = msm_bus_scale_client_update_request(sc->bus_handle, 1); if (ret) { dev_err(&rdev->dev, "bus scaling failed, ret=%d\n", ret); goto end; } } regmap_read(sc->regmap, REG_OFFSET, ®val); if (regval & PWR_ON_MASK) { Loading @@ -173,21 +186,20 @@ static int gdsc_is_enabled(struct regulator_dev *rdev) * votable GDS registers. Check the SW_COLLAPSE_MASK to * determine if HLOS has voted for it. */ if (!(regval & SW_COLLAPSE_MASK)) { if (sc->parent_regulator) { regulator_disable(sc->parent_regulator); regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); } return true; } if (!(regval & SW_COLLAPSE_MASK)) is_enabled = true; } if (sc->bus_handle && !sc->is_bus_enabled) msm_bus_scale_client_update_request(sc->bus_handle, 0); end: if (sc->parent_regulator) { regulator_disable(sc->parent_regulator); regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); } return false; return is_enabled; } static int gdsc_enable(struct regulator_dev *rdev) Loading @@ -196,15 +208,21 @@ static int gdsc_enable(struct regulator_dev *rdev) uint32_t regval, hw_ctrl_regval = 0x0; int i, ret = 0; mutex_lock(&gdsc_seq_lock); if (sc->parent_regulator) { ret = regulator_set_voltage(sc->parent_regulator, RPMH_REGULATOR_LEVEL_LOW_SVS, INT_MAX); if (ret) { mutex_unlock(&gdsc_seq_lock); if (ret) return ret; } if (sc->bus_handle) { ret = msm_bus_scale_client_update_request(sc->bus_handle, 1); if (ret) { dev_err(&rdev->dev, "bus scaling failed, ret=%d\n", ret); goto end; } sc->is_bus_enabled = true; } if (sc->root_en || sc->force_root_en) Loading Loading @@ -349,11 +367,13 @@ static int gdsc_enable(struct regulator_dev *rdev) sc->is_gdsc_enabled = true; end: if (ret && sc->bus_handle) { msm_bus_scale_client_update_request(sc->bus_handle, 0); sc->is_bus_enabled = false; } if (sc->parent_regulator) regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); mutex_unlock(&gdsc_seq_lock); return ret; } Loading @@ -363,16 +383,12 @@ static int gdsc_disable(struct regulator_dev *rdev) uint32_t regval; int i, ret = 0; mutex_lock(&gdsc_seq_lock); if (sc->parent_regulator) { ret = regulator_set_voltage(sc->parent_regulator, RPMH_REGULATOR_LEVEL_LOW_SVS, INT_MAX); if (ret) { mutex_unlock(&gdsc_seq_lock); if (ret) return ret; } } if (sc->force_root_en) clk_prepare_enable(sc->clocks[sc->root_clk_idx]); Loading Loading @@ -431,13 +447,19 @@ static int gdsc_disable(struct regulator_dev *rdev) if ((sc->is_gdsc_enabled && sc->root_en) || sc->force_root_en) clk_disable_unprepare(sc->clocks[sc->root_clk_idx]); if (sc->bus_handle) { ret = msm_bus_scale_client_update_request(sc->bus_handle, 0); if (ret) dev_err(&rdev->dev, "bus scaling failed, ret=%d\n", ret); sc->is_bus_enabled = false; } if (sc->parent_regulator) regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); sc->is_gdsc_enabled = false; mutex_unlock(&gdsc_seq_lock); return ret; } Loading @@ -447,33 +469,43 @@ static unsigned int gdsc_get_mode(struct regulator_dev *rdev) uint32_t regval; int ret; mutex_lock(&gdsc_seq_lock); if (sc->parent_regulator) { ret = regulator_set_voltage(sc->parent_regulator, RPMH_REGULATOR_LEVEL_LOW_SVS, INT_MAX); if (ret) { mutex_unlock(&gdsc_seq_lock); if (ret) return ret; } ret = regulator_enable(sc->parent_regulator); if (ret) { regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); mutex_unlock(&gdsc_seq_lock); return ret; } } if (sc->bus_handle && !sc->is_bus_enabled) { ret = msm_bus_scale_client_update_request(sc->bus_handle, 1); if (ret) { dev_err(&rdev->dev, "bus scaling failed, ret=%d\n", ret); if (sc->parent_regulator) { regulator_disable(sc->parent_regulator); regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); } return ret; } } regmap_read(sc->regmap, REG_OFFSET, ®val); if (sc->bus_handle && !sc->is_bus_enabled) msm_bus_scale_client_update_request(sc->bus_handle, 0); if (sc->parent_regulator) { regulator_disable(sc->parent_regulator); regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); } mutex_unlock(&gdsc_seq_lock); if (regval & HW_CONTROL_MASK) return REGULATOR_MODE_FAST; Loading @@ -486,20 +518,29 @@ static int gdsc_set_mode(struct regulator_dev *rdev, unsigned int mode) uint32_t regval; int ret = 0; mutex_lock(&gdsc_seq_lock); if (sc->parent_regulator) { ret = regulator_set_voltage(sc->parent_regulator, RPMH_REGULATOR_LEVEL_LOW_SVS, INT_MAX); if (ret) { mutex_unlock(&gdsc_seq_lock); if (ret) return ret; } ret = regulator_enable(sc->parent_regulator); if (ret) { regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); mutex_unlock(&gdsc_seq_lock); return ret; } } if (sc->bus_handle && !sc->is_bus_enabled) { ret = msm_bus_scale_client_update_request(sc->bus_handle, 1); if (ret) { dev_err(&rdev->dev, "bus scaling failed, ret=%d\n", ret); if (sc->parent_regulator) { regulator_disable(sc->parent_regulator); regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); } return ret; } } Loading Loading @@ -530,30 +571,25 @@ static int gdsc_set_mode(struct regulator_dev *rdev, unsigned int mode) /* * There may be a race with internal HW trigger signal, * that will result in GDSC going through a power down and * up cycle. If we poll too early, status bit will * indicate 'on' before the GDSC can finish the power cycle. * Account for this case by waiting 1us before polling. * up cycle. Account for this case by waiting 1us before * proceeding. */ gdsc_mb(sc); udelay(1); ret = poll_gdsc_status(sc, ENABLED); if (ret) dev_err(&rdev->dev, "%s set_mode timed out: 0x%x\n", sc->rdesc.name, regval); break; default: ret = -EINVAL; break; } if (sc->bus_handle && !sc->is_bus_enabled) msm_bus_scale_client_update_request(sc->bus_handle, 0); if (sc->parent_regulator) { regulator_disable(sc->parent_regulator); regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); } mutex_unlock(&gdsc_seq_lock); return ret; } Loading Loading @@ -751,6 +787,26 @@ static int gdsc_get_resources(struct gdsc *sc, struct platform_device *pdev) } } if (of_find_property(pdev->dev.of_node, "qcom,msm-bus,name", NULL)) { sc->bus_pdata = msm_bus_cl_get_pdata(pdev); if (!sc->bus_pdata) { dev_err(&pdev->dev, "Failed to get bus config data\n"); return -EINVAL; } sc->bus_handle = msm_bus_scale_register_client(sc->bus_pdata); if (!sc->bus_handle) { dev_err(&pdev->dev, "Failed to register bus client\n"); /* * msm_bus_scale_register_client() returns 0 for all * errors including when called before the bus driver * probes. Therefore, return -EPROBE_DEFER here so that * probing can be retried and this case handled. */ return -EPROBE_DEFER; } } return 0; } Loading @@ -773,7 +829,22 @@ static int gdsc_probe(struct platform_device *pdev) ret = gdsc_get_resources(sc, pdev); if (ret) return ret; goto err; if (sc->bus_handle) { /* * Request non-zero bus bandwidth to ensure that the slave * hardware block containing the GDSC is not disconnected from * the bus. This allows register IO for the GDSC to succeed. */ ret = msm_bus_scale_client_update_request(sc->bus_handle, 1); if (ret) { dev_err(&pdev->dev, "bus scaling failed, ret=%d\n", ret); goto err; } sc->is_bus_enabled = true; } /* * Disable HW trigger: collapse/restore occur based on registers writes. Loading Loading @@ -801,7 +872,19 @@ static int gdsc_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "%s enable timed out: 0x%x\n", sc->rdesc.name, regval); return ret; goto err; } } if (sc->bus_handle) { regmap_read(sc->regmap, REG_OFFSET, ®val); if (!(regval & PWR_ON_MASK) || (regval & SW_COLLAPSE_MASK)) { /* * Software is not enabling the GDSC so remove the * bus vote. */ msm_bus_scale_client_update_request(sc->bus_handle, 0); sc->is_bus_enabled = false; } } Loading Loading @@ -835,11 +918,33 @@ static int gdsc_probe(struct platform_device *pdev) ret = PTR_ERR(sc->rdev); dev_err(&pdev->dev, "regulator_register(\"%s\") failed, ret=%d\n", sc->rdesc.name, ret); return ret; goto err; } platform_set_drvdata(pdev, sc); return 0; err: if (sc->bus_handle) { if (sc->is_bus_enabled) msm_bus_scale_client_update_request(sc->bus_handle, 0); msm_bus_scale_unregister_client(sc->bus_handle); } return ret; } static int gdsc_remove(struct platform_device *pdev) { struct gdsc *sc = platform_get_drvdata(pdev); if (sc->bus_handle) { if (sc->is_bus_enabled) msm_bus_scale_client_update_request(sc->bus_handle, 0); msm_bus_scale_unregister_client(sc->bus_handle); } return 0; } Loading @@ -850,6 +955,7 @@ static const struct of_device_id gdsc_match_table[] = { static struct platform_driver gdsc_driver = { .probe = gdsc_probe, .remove = gdsc_remove, .driver = { .name = "gdsc", .of_match_table = gdsc_match_table, Loading Loading
arch/arm64/boot/dts/qcom/kona.dtsi +66 −0 Original line number Diff line number Diff line Loading @@ -1637,6 +1637,12 @@ clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "bps_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 1>; qcom,support-hw-trigger; qcom,retain-regs; }; Loading @@ -1649,6 +1655,12 @@ clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "ife_0_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 1>; qcom,retain-regs; }; Loading @@ -1660,6 +1672,12 @@ clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "ife_1_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 1>; qcom,retain-regs; }; Loading @@ -1671,6 +1689,12 @@ clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "ipe_0_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 1>; qcom,support-hw-trigger; qcom,retain-regs; }; Loading @@ -1683,6 +1707,12 @@ clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "sbi_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 1>; qcom,retain-regs; }; Loading @@ -1694,6 +1724,12 @@ clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "titan_top_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_CAMERA_CFG 0 1>; qcom,retain-regs; }; Loading @@ -1706,6 +1742,12 @@ clocks = <&clock_gcc GCC_DISP_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "mdss_core_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_DISPLAY_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_DISPLAY_CFG 0 1>; qcom,support-hw-trigger; qcom,retain-regs; }; Loading Loading @@ -1774,6 +1816,12 @@ clocks = <&clock_gcc GCC_VIDEO_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "mvs0_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VENUS_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VENUS_CFG 0 1>; qcom,retain-regs; }; Loading @@ -1785,6 +1833,12 @@ clocks = <&clock_gcc GCC_VIDEO_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "mvs0c_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VENUS_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VENUS_CFG 0 1>; qcom,retain-regs; }; Loading @@ -1796,6 +1850,12 @@ clocks = <&clock_gcc GCC_VIDEO_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "mvs1_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VENUS_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VENUS_CFG 0 1>; qcom,support-hw-trigger; qcom,retain-regs; }; Loading @@ -1808,6 +1868,12 @@ clocks = <&clock_gcc GCC_VIDEO_AHB_CLK>; parent-supply = <&VDD_MMCX_LEVEL>; vdd_parent-supply = <&VDD_MMCX_LEVEL>; qcom,msm-bus,name = "mvs1c_gdsc_ahb"; qcom,msm-bus,num-cases = <2>; qcom,msm-bus,num-paths = <1>; qcom,msm-bus,vectors-KBps = <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VENUS_CFG 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VENUS_CFG 0 1>; qcom,retain-regs; }; Loading
drivers/clk/qcom/gdsc-regulator.c +157 −51 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include <linux/delay.h> #include <linux/err.h> #include <linux/of.h> #include <linux/msm-bus.h> #include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> Loading Loading @@ -55,6 +56,8 @@ struct gdsc { struct clk **clocks; struct regulator *parent_regulator; struct reset_control **reset_clocks; struct msm_bus_scale_pdata *bus_pdata; u32 bus_handle; bool toggle_mem; bool toggle_periph; bool toggle_logic; Loading @@ -66,6 +69,7 @@ struct gdsc { bool is_gdsc_enabled; bool allow_clear; bool reset_aon; bool is_bus_enabled; int clock_count; int reset_count; int root_clk_idx; Loading @@ -77,8 +81,6 @@ enum gdscr_status { DISABLED, }; static DEFINE_MUTEX(gdsc_seq_lock); static inline u32 gdsc_mb(struct gdsc *gds) { u32 reg; Loading Loading @@ -137,6 +139,8 @@ static int gdsc_is_enabled(struct regulator_dev *rdev) { struct gdsc *sc = rdev_get_drvdata(rdev); uint32_t regval; int ret; bool is_enabled = false; if (!sc->toggle_logic) return !sc->resets_asserted; Loading Loading @@ -165,6 +169,15 @@ static int gdsc_is_enabled(struct regulator_dev *rdev) } } if (sc->bus_handle && !sc->is_bus_enabled) { ret = msm_bus_scale_client_update_request(sc->bus_handle, 1); if (ret) { dev_err(&rdev->dev, "bus scaling failed, ret=%d\n", ret); goto end; } } regmap_read(sc->regmap, REG_OFFSET, ®val); if (regval & PWR_ON_MASK) { Loading @@ -173,21 +186,20 @@ static int gdsc_is_enabled(struct regulator_dev *rdev) * votable GDS registers. Check the SW_COLLAPSE_MASK to * determine if HLOS has voted for it. */ if (!(regval & SW_COLLAPSE_MASK)) { if (sc->parent_regulator) { regulator_disable(sc->parent_regulator); regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); } return true; } if (!(regval & SW_COLLAPSE_MASK)) is_enabled = true; } if (sc->bus_handle && !sc->is_bus_enabled) msm_bus_scale_client_update_request(sc->bus_handle, 0); end: if (sc->parent_regulator) { regulator_disable(sc->parent_regulator); regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); } return false; return is_enabled; } static int gdsc_enable(struct regulator_dev *rdev) Loading @@ -196,15 +208,21 @@ static int gdsc_enable(struct regulator_dev *rdev) uint32_t regval, hw_ctrl_regval = 0x0; int i, ret = 0; mutex_lock(&gdsc_seq_lock); if (sc->parent_regulator) { ret = regulator_set_voltage(sc->parent_regulator, RPMH_REGULATOR_LEVEL_LOW_SVS, INT_MAX); if (ret) { mutex_unlock(&gdsc_seq_lock); if (ret) return ret; } if (sc->bus_handle) { ret = msm_bus_scale_client_update_request(sc->bus_handle, 1); if (ret) { dev_err(&rdev->dev, "bus scaling failed, ret=%d\n", ret); goto end; } sc->is_bus_enabled = true; } if (sc->root_en || sc->force_root_en) Loading Loading @@ -349,11 +367,13 @@ static int gdsc_enable(struct regulator_dev *rdev) sc->is_gdsc_enabled = true; end: if (ret && sc->bus_handle) { msm_bus_scale_client_update_request(sc->bus_handle, 0); sc->is_bus_enabled = false; } if (sc->parent_regulator) regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); mutex_unlock(&gdsc_seq_lock); return ret; } Loading @@ -363,16 +383,12 @@ static int gdsc_disable(struct regulator_dev *rdev) uint32_t regval; int i, ret = 0; mutex_lock(&gdsc_seq_lock); if (sc->parent_regulator) { ret = regulator_set_voltage(sc->parent_regulator, RPMH_REGULATOR_LEVEL_LOW_SVS, INT_MAX); if (ret) { mutex_unlock(&gdsc_seq_lock); if (ret) return ret; } } if (sc->force_root_en) clk_prepare_enable(sc->clocks[sc->root_clk_idx]); Loading Loading @@ -431,13 +447,19 @@ static int gdsc_disable(struct regulator_dev *rdev) if ((sc->is_gdsc_enabled && sc->root_en) || sc->force_root_en) clk_disable_unprepare(sc->clocks[sc->root_clk_idx]); if (sc->bus_handle) { ret = msm_bus_scale_client_update_request(sc->bus_handle, 0); if (ret) dev_err(&rdev->dev, "bus scaling failed, ret=%d\n", ret); sc->is_bus_enabled = false; } if (sc->parent_regulator) regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); sc->is_gdsc_enabled = false; mutex_unlock(&gdsc_seq_lock); return ret; } Loading @@ -447,33 +469,43 @@ static unsigned int gdsc_get_mode(struct regulator_dev *rdev) uint32_t regval; int ret; mutex_lock(&gdsc_seq_lock); if (sc->parent_regulator) { ret = regulator_set_voltage(sc->parent_regulator, RPMH_REGULATOR_LEVEL_LOW_SVS, INT_MAX); if (ret) { mutex_unlock(&gdsc_seq_lock); if (ret) return ret; } ret = regulator_enable(sc->parent_regulator); if (ret) { regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); mutex_unlock(&gdsc_seq_lock); return ret; } } if (sc->bus_handle && !sc->is_bus_enabled) { ret = msm_bus_scale_client_update_request(sc->bus_handle, 1); if (ret) { dev_err(&rdev->dev, "bus scaling failed, ret=%d\n", ret); if (sc->parent_regulator) { regulator_disable(sc->parent_regulator); regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); } return ret; } } regmap_read(sc->regmap, REG_OFFSET, ®val); if (sc->bus_handle && !sc->is_bus_enabled) msm_bus_scale_client_update_request(sc->bus_handle, 0); if (sc->parent_regulator) { regulator_disable(sc->parent_regulator); regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); } mutex_unlock(&gdsc_seq_lock); if (regval & HW_CONTROL_MASK) return REGULATOR_MODE_FAST; Loading @@ -486,20 +518,29 @@ static int gdsc_set_mode(struct regulator_dev *rdev, unsigned int mode) uint32_t regval; int ret = 0; mutex_lock(&gdsc_seq_lock); if (sc->parent_regulator) { ret = regulator_set_voltage(sc->parent_regulator, RPMH_REGULATOR_LEVEL_LOW_SVS, INT_MAX); if (ret) { mutex_unlock(&gdsc_seq_lock); if (ret) return ret; } ret = regulator_enable(sc->parent_regulator); if (ret) { regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); mutex_unlock(&gdsc_seq_lock); return ret; } } if (sc->bus_handle && !sc->is_bus_enabled) { ret = msm_bus_scale_client_update_request(sc->bus_handle, 1); if (ret) { dev_err(&rdev->dev, "bus scaling failed, ret=%d\n", ret); if (sc->parent_regulator) { regulator_disable(sc->parent_regulator); regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); } return ret; } } Loading Loading @@ -530,30 +571,25 @@ static int gdsc_set_mode(struct regulator_dev *rdev, unsigned int mode) /* * There may be a race with internal HW trigger signal, * that will result in GDSC going through a power down and * up cycle. If we poll too early, status bit will * indicate 'on' before the GDSC can finish the power cycle. * Account for this case by waiting 1us before polling. * up cycle. Account for this case by waiting 1us before * proceeding. */ gdsc_mb(sc); udelay(1); ret = poll_gdsc_status(sc, ENABLED); if (ret) dev_err(&rdev->dev, "%s set_mode timed out: 0x%x\n", sc->rdesc.name, regval); break; default: ret = -EINVAL; break; } if (sc->bus_handle && !sc->is_bus_enabled) msm_bus_scale_client_update_request(sc->bus_handle, 0); if (sc->parent_regulator) { regulator_disable(sc->parent_regulator); regulator_set_voltage(sc->parent_regulator, 0, INT_MAX); } mutex_unlock(&gdsc_seq_lock); return ret; } Loading Loading @@ -751,6 +787,26 @@ static int gdsc_get_resources(struct gdsc *sc, struct platform_device *pdev) } } if (of_find_property(pdev->dev.of_node, "qcom,msm-bus,name", NULL)) { sc->bus_pdata = msm_bus_cl_get_pdata(pdev); if (!sc->bus_pdata) { dev_err(&pdev->dev, "Failed to get bus config data\n"); return -EINVAL; } sc->bus_handle = msm_bus_scale_register_client(sc->bus_pdata); if (!sc->bus_handle) { dev_err(&pdev->dev, "Failed to register bus client\n"); /* * msm_bus_scale_register_client() returns 0 for all * errors including when called before the bus driver * probes. Therefore, return -EPROBE_DEFER here so that * probing can be retried and this case handled. */ return -EPROBE_DEFER; } } return 0; } Loading @@ -773,7 +829,22 @@ static int gdsc_probe(struct platform_device *pdev) ret = gdsc_get_resources(sc, pdev); if (ret) return ret; goto err; if (sc->bus_handle) { /* * Request non-zero bus bandwidth to ensure that the slave * hardware block containing the GDSC is not disconnected from * the bus. This allows register IO for the GDSC to succeed. */ ret = msm_bus_scale_client_update_request(sc->bus_handle, 1); if (ret) { dev_err(&pdev->dev, "bus scaling failed, ret=%d\n", ret); goto err; } sc->is_bus_enabled = true; } /* * Disable HW trigger: collapse/restore occur based on registers writes. Loading Loading @@ -801,7 +872,19 @@ static int gdsc_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "%s enable timed out: 0x%x\n", sc->rdesc.name, regval); return ret; goto err; } } if (sc->bus_handle) { regmap_read(sc->regmap, REG_OFFSET, ®val); if (!(regval & PWR_ON_MASK) || (regval & SW_COLLAPSE_MASK)) { /* * Software is not enabling the GDSC so remove the * bus vote. */ msm_bus_scale_client_update_request(sc->bus_handle, 0); sc->is_bus_enabled = false; } } Loading Loading @@ -835,11 +918,33 @@ static int gdsc_probe(struct platform_device *pdev) ret = PTR_ERR(sc->rdev); dev_err(&pdev->dev, "regulator_register(\"%s\") failed, ret=%d\n", sc->rdesc.name, ret); return ret; goto err; } platform_set_drvdata(pdev, sc); return 0; err: if (sc->bus_handle) { if (sc->is_bus_enabled) msm_bus_scale_client_update_request(sc->bus_handle, 0); msm_bus_scale_unregister_client(sc->bus_handle); } return ret; } static int gdsc_remove(struct platform_device *pdev) { struct gdsc *sc = platform_get_drvdata(pdev); if (sc->bus_handle) { if (sc->is_bus_enabled) msm_bus_scale_client_update_request(sc->bus_handle, 0); msm_bus_scale_unregister_client(sc->bus_handle); } return 0; } Loading @@ -850,6 +955,7 @@ static const struct of_device_id gdsc_match_table[] = { static struct platform_driver gdsc_driver = { .probe = gdsc_probe, .remove = gdsc_remove, .driver = { .name = "gdsc", .of_match_table = gdsc_match_table, Loading