Loading drivers/gpu/msm/adreno.c +7 −0 Original line number Diff line number Diff line Loading @@ -3572,9 +3572,16 @@ static void adreno_regulator_disable_poll(struct kgsl_device *device) { struct kgsl_pwrctrl *pwr = &device->pwrctrl; /* Set the parent in retention voltage to disable CPR interrupts */ kgsl_regulator_set_voltage(device->dev, pwr->gx_gdsc_parent, pwr->gx_gdsc_parent_min_corner); if (!kgsl_regulator_disable_wait(pwr->gx_gdsc, 200)) dev_err(device->dev, "Regulator vdd is stuck on\n"); /* Remove the vote for the vdd parent supply */ kgsl_regulator_set_voltage(device->dev, pwr->gx_gdsc_parent, 0); if (!kgsl_regulator_disable_wait(pwr->cx_gdsc, 200)) dev_err(device->dev, "Regulator vddcx is stuck on\n"); } Loading drivers/gpu/msm/kgsl_pwrctrl.c +28 −2 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ #include "kgsl_pwrscale.h" #include "kgsl_sysfs.h" #include "kgsl_trace.h" #include "kgsl_util.h" #define UPDATE_BUSY_VAL 1000000 Loading Loading @@ -1328,8 +1329,15 @@ static int enable_regulators(struct kgsl_device *device) return 0; ret = enable_regulator(&device->pdev->dev, pwr->cx_gdsc, "vddcx"); if (!ret) { /* Set parent in retention voltage to power up vdd supply */ ret = kgsl_regulator_set_voltage(device->dev, pwr->gx_gdsc_parent, pwr->gx_gdsc_parent_min_corner); if (!ret) ret = enable_regulator(&device->pdev->dev, pwr->gx_gdsc, "vdd"); ret = enable_regulator(&device->pdev->dev, pwr->gx_gdsc, "vdd"); } if (ret) { clear_bit(KGSL_PWRFLAGS_POWER_ON, &pwr->power_flags); Loading Loading @@ -1572,6 +1580,24 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) if (of_property_read_bool(pdev->dev.of_node, "vdd-supply")) pwr->gx_gdsc = devm_regulator_get(&pdev->dev, "vdd"); if (of_property_read_bool(pdev->dev.of_node, "vdd-parent-supply")) { pwr->gx_gdsc_parent = devm_regulator_get(&pdev->dev, "vdd-parent"); if (IS_ERR(pwr->gx_gdsc_parent)) { dev_err(device->dev, "Failed to get vdd-parent regulator:%d\n", PTR_ERR(pwr->gx_gdsc_parent)); return -ENODEV; } if (of_property_read_u32(pdev->dev.of_node, "vdd-parent-min-corner", &pwr->gx_gdsc_parent_min_corner)) { dev_err(device->dev, "vdd-parent-min-corner not found\n"); return -ENODEV; } } pwr->power_flags = 0; pm_runtime_enable(&pdev->dev); Loading drivers/gpu/msm/kgsl_pwrctrl.h +4 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,10 @@ struct kgsl_pwrctrl { struct regulator *cx_gdsc; /** @gx_gdsc: Pointer to the GX domain regulator if applicable */ struct regulator *gx_gdsc; /** @gx_gdsc: Pointer to the GX domain parent supply */ struct regulator *gx_gdsc_parent; /** @gx_gdsc_parent_min_corner: Minimum supply voltage for GX parent */ u32 gx_gdsc_parent_min_corner; int isense_clk_indx; int isense_clk_on_level; unsigned long power_flags; Loading drivers/gpu/msm/kgsl_util.c +16 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ #include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/ktime.h> #include <linux/regulator/consumer.h> #include <linux/string.h> Loading Loading @@ -44,3 +45,18 @@ struct clk *kgsl_of_clk_by_name(struct clk_bulk_data *clks, int count, return NULL; } int kgsl_regulator_set_voltage(struct device *dev, struct regulator *reg, u32 voltage) { int ret; if (IS_ERR_OR_NULL(reg)) return 0; ret = regulator_set_voltage(reg, voltage, INT_MAX); if (ret) dev_err(dev, "Regulator set voltage:%d failed:%d\n", voltage, ret); return ret; } drivers/gpu/msm/kgsl_util.h +11 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2019, The Linux Foundation. All rights reserved. * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #ifndef _KGSL_UTIL_H_ Loading Loading @@ -32,4 +32,14 @@ bool kgsl_regulator_disable_wait(struct regulator *reg, u32 timeout); */ struct clk *kgsl_of_clk_by_name(struct clk_bulk_data *clks, int count, const char *id); /** * kgsl_regulator_set_voltage - Set voltage level for regulator * @dev: A &struct device pointer * @reg: A &struct regulator handle * @voltage: Voltage value to set regulator * * Return: 0 on success and negative error on failure. */ int kgsl_regulator_set_voltage(struct device *dev, struct regulator *reg, u32 voltage); #endif Loading
drivers/gpu/msm/adreno.c +7 −0 Original line number Diff line number Diff line Loading @@ -3572,9 +3572,16 @@ static void adreno_regulator_disable_poll(struct kgsl_device *device) { struct kgsl_pwrctrl *pwr = &device->pwrctrl; /* Set the parent in retention voltage to disable CPR interrupts */ kgsl_regulator_set_voltage(device->dev, pwr->gx_gdsc_parent, pwr->gx_gdsc_parent_min_corner); if (!kgsl_regulator_disable_wait(pwr->gx_gdsc, 200)) dev_err(device->dev, "Regulator vdd is stuck on\n"); /* Remove the vote for the vdd parent supply */ kgsl_regulator_set_voltage(device->dev, pwr->gx_gdsc_parent, 0); if (!kgsl_regulator_disable_wait(pwr->cx_gdsc, 200)) dev_err(device->dev, "Regulator vddcx is stuck on\n"); } Loading
drivers/gpu/msm/kgsl_pwrctrl.c +28 −2 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ #include "kgsl_pwrscale.h" #include "kgsl_sysfs.h" #include "kgsl_trace.h" #include "kgsl_util.h" #define UPDATE_BUSY_VAL 1000000 Loading Loading @@ -1328,8 +1329,15 @@ static int enable_regulators(struct kgsl_device *device) return 0; ret = enable_regulator(&device->pdev->dev, pwr->cx_gdsc, "vddcx"); if (!ret) { /* Set parent in retention voltage to power up vdd supply */ ret = kgsl_regulator_set_voltage(device->dev, pwr->gx_gdsc_parent, pwr->gx_gdsc_parent_min_corner); if (!ret) ret = enable_regulator(&device->pdev->dev, pwr->gx_gdsc, "vdd"); ret = enable_regulator(&device->pdev->dev, pwr->gx_gdsc, "vdd"); } if (ret) { clear_bit(KGSL_PWRFLAGS_POWER_ON, &pwr->power_flags); Loading Loading @@ -1572,6 +1580,24 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) if (of_property_read_bool(pdev->dev.of_node, "vdd-supply")) pwr->gx_gdsc = devm_regulator_get(&pdev->dev, "vdd"); if (of_property_read_bool(pdev->dev.of_node, "vdd-parent-supply")) { pwr->gx_gdsc_parent = devm_regulator_get(&pdev->dev, "vdd-parent"); if (IS_ERR(pwr->gx_gdsc_parent)) { dev_err(device->dev, "Failed to get vdd-parent regulator:%d\n", PTR_ERR(pwr->gx_gdsc_parent)); return -ENODEV; } if (of_property_read_u32(pdev->dev.of_node, "vdd-parent-min-corner", &pwr->gx_gdsc_parent_min_corner)) { dev_err(device->dev, "vdd-parent-min-corner not found\n"); return -ENODEV; } } pwr->power_flags = 0; pm_runtime_enable(&pdev->dev); Loading
drivers/gpu/msm/kgsl_pwrctrl.h +4 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,10 @@ struct kgsl_pwrctrl { struct regulator *cx_gdsc; /** @gx_gdsc: Pointer to the GX domain regulator if applicable */ struct regulator *gx_gdsc; /** @gx_gdsc: Pointer to the GX domain parent supply */ struct regulator *gx_gdsc_parent; /** @gx_gdsc_parent_min_corner: Minimum supply voltage for GX parent */ u32 gx_gdsc_parent_min_corner; int isense_clk_indx; int isense_clk_on_level; unsigned long power_flags; Loading
drivers/gpu/msm/kgsl_util.c +16 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ #include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/ktime.h> #include <linux/regulator/consumer.h> #include <linux/string.h> Loading Loading @@ -44,3 +45,18 @@ struct clk *kgsl_of_clk_by_name(struct clk_bulk_data *clks, int count, return NULL; } int kgsl_regulator_set_voltage(struct device *dev, struct regulator *reg, u32 voltage) { int ret; if (IS_ERR_OR_NULL(reg)) return 0; ret = regulator_set_voltage(reg, voltage, INT_MAX); if (ret) dev_err(dev, "Regulator set voltage:%d failed:%d\n", voltage, ret); return ret; }
drivers/gpu/msm/kgsl_util.h +11 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2019, The Linux Foundation. All rights reserved. * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #ifndef _KGSL_UTIL_H_ Loading Loading @@ -32,4 +32,14 @@ bool kgsl_regulator_disable_wait(struct regulator *reg, u32 timeout); */ struct clk *kgsl_of_clk_by_name(struct clk_bulk_data *clks, int count, const char *id); /** * kgsl_regulator_set_voltage - Set voltage level for regulator * @dev: A &struct device pointer * @reg: A &struct regulator handle * @voltage: Voltage value to set regulator * * Return: 0 on success and negative error on failure. */ int kgsl_regulator_set_voltage(struct device *dev, struct regulator *reg, u32 voltage); #endif