mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 05:39:54 -04:00
msm: kgsl: Add support for voting vdd parent supply voltage
For RPM based targets which have the dedicated GFX rails requires voting of vdd parent supply. Hence add support to vote for vdd parent supply. Change-Id: I3301b9b5f07d8e928a64b7013ec40b7c54e596ca Signed-off-by: Hareesh Gundu <hareeshg@codeaurora.org>
This commit is contained in:
parent
c19cc3d79e
commit
a545441b50
5 changed files with 66 additions and 3 deletions
|
|
@ -3574,9 +3574,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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -1329,8 +1330,15 @@ static int enable_regulators(struct kgsl_device *device)
|
|||
return 0;
|
||||
|
||||
ret = enable_regulator(&device->pdev->dev, pwr->cx_gdsc, "vddcx");
|
||||
if (!ret)
|
||||
ret = enable_regulator(&device->pdev->dev, pwr->gx_gdsc, "vdd");
|
||||
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");
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
clear_bit(KGSL_PWRFLAGS_POWER_ON, &pwr->power_flags);
|
||||
|
|
@ -1573,6 +1581,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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* 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_
|
||||
|
|
@ -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…
Reference in a new issue