mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 04:42:04 -04:00
msm: kgsl: Remove "zero" power level
There was a time, long long ago, when having a "zero" power level made sense because a "zero" powerlevel wasn't really "zero". That is no longer the case and it is silly to force the DT to define it for EVERY. SINGLE. TARGET. Get rid of it and assume that zero is, well... zero. Change-Id: Ic0dedbadc5551585de893cdb5b3ed948a62aa430 Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
This commit is contained in:
parent
186835c7d3
commit
152a9e1a0c
10 changed files with 60 additions and 50 deletions
|
|
@ -842,7 +842,7 @@ static void adreno_of_get_ca_target_pwrlevel(struct adreno_device *adreno_dev,
|
|||
of_property_read_u32(node, "qcom,ca-target-pwrlevel",
|
||||
&ca_target_pwrlevel);
|
||||
|
||||
if (ca_target_pwrlevel > device->pwrctrl.num_pwrlevels - 2)
|
||||
if (ca_target_pwrlevel >= device->pwrctrl.num_pwrlevels)
|
||||
ca_target_pwrlevel = 1;
|
||||
|
||||
device->pwrscale.ctxt_aware_target_pwrlevel = ca_target_pwrlevel;
|
||||
|
|
@ -907,15 +907,27 @@ static int adreno_of_parse_pwrlevels(struct adreno_device *adreno_dev,
|
|||
pwr->num_pwrlevels = 0;
|
||||
|
||||
for_each_child_of_node(node, child) {
|
||||
unsigned int index;
|
||||
unsigned int index, freq = 0;
|
||||
struct kgsl_pwrlevel *level;
|
||||
|
||||
if (of_property_read_u32(child, "reg", &index)) {
|
||||
dev_err(device->dev,
|
||||
"%pOF: powerlevel index not found\n", child);
|
||||
of_node_put(child);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (of_property_read_u32(child, "qcom,gpu-freq", &freq)) {
|
||||
dev_err(device->dev,
|
||||
"%pOF: Unable to read qcom,gpu-freq\n", child);
|
||||
of_node_put(child);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Ignore "zero" powerlevels */
|
||||
if (!freq)
|
||||
continue;
|
||||
|
||||
if (index >= KGSL_MAX_PWRLEVELS) {
|
||||
dev_err(device->dev,
|
||||
"%pOF: Pwrlevel index %d is out of range\n",
|
||||
|
|
@ -928,12 +940,7 @@ static int adreno_of_parse_pwrlevels(struct adreno_device *adreno_dev,
|
|||
|
||||
level = &pwr->pwrlevels[index];
|
||||
|
||||
if (of_property_read_u32(child, "qcom,gpu-freq",
|
||||
&level->gpu_freq)) {
|
||||
dev_err(device->dev,
|
||||
"%pOF: Unable to read qcom,gpu-freq\n", child);
|
||||
return -EINVAL;
|
||||
}
|
||||
level->gpu_freq = freq;
|
||||
|
||||
of_property_read_u32(child, "qcom,acd-level",
|
||||
&level->acd_level);
|
||||
|
|
@ -944,6 +951,7 @@ static int adreno_of_parse_pwrlevels(struct adreno_device *adreno_dev,
|
|||
dev_err(device->dev,
|
||||
"%pOF: Couldn't read the bus frequency for power level %d\n",
|
||||
child, index);
|
||||
of_node_put(child);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -968,7 +976,7 @@ static void adreno_of_get_initial_pwrlevel(struct adreno_device *adreno_dev,
|
|||
|
||||
of_property_read_u32(node, "qcom,initial-pwrlevel", &init_level);
|
||||
|
||||
if (init_level < 0 || init_level > pwr->num_pwrlevels)
|
||||
if (init_level < 0 || init_level >= pwr->num_pwrlevels)
|
||||
init_level = 1;
|
||||
|
||||
pwr->active_pwrlevel = init_level;
|
||||
|
|
|
|||
|
|
@ -934,14 +934,13 @@ static uint32_t _write_voltage_table(struct adreno_device *adreno_dev,
|
|||
const struct adreno_a5xx_core *a5xx_core = to_a5xx_core(adreno_dev);
|
||||
int i;
|
||||
struct dev_pm_opp *opp;
|
||||
int levels = pwr->num_pwrlevels - 1;
|
||||
unsigned int mvolt = 0;
|
||||
|
||||
kgsl_regwrite(device, addr++, a5xx_core->max_power);
|
||||
kgsl_regwrite(device, addr++, levels);
|
||||
kgsl_regwrite(device, addr++, pwr->num_pwrlevels);
|
||||
|
||||
/* Write voltage in mV and frequency in MHz */
|
||||
for (i = 0; i < levels; i++) {
|
||||
for (i = 0; i < pwr->num_pwrlevels; i++) {
|
||||
opp = dev_pm_opp_find_freq_exact(&device->pdev->dev,
|
||||
pwr->pwrlevels[i].gpu_freq, true);
|
||||
/* _opp_get returns uV, convert to mV */
|
||||
|
|
@ -953,7 +952,7 @@ static uint32_t _write_voltage_table(struct adreno_device *adreno_dev,
|
|||
kgsl_regwrite(device, addr++,
|
||||
pwr->pwrlevels[i].gpu_freq / 1000000);
|
||||
}
|
||||
return (levels * 2 + 2);
|
||||
return (pwr->num_pwrlevels * 2 + 2);
|
||||
}
|
||||
|
||||
static uint32_t lm_limit(struct adreno_device *adreno_dev)
|
||||
|
|
|
|||
|
|
@ -830,7 +830,8 @@ static int a6xx_gmu_gfx_rail_on(struct kgsl_device *device)
|
|||
{
|
||||
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
|
||||
struct gmu_device *gmu = KGSL_GMU_DEVICE(device);
|
||||
unsigned int perf_idx = pwr->num_pwrlevels - pwr->default_pwrlevel - 1;
|
||||
unsigned int perf_idx = gmu->num_gpupwrlevels -
|
||||
pwr->default_pwrlevel - 1;
|
||||
uint32_t default_opp = gmu->rpmh_votes.gx_votes[perf_idx];
|
||||
|
||||
gmu_core_regwrite(device, A6XX_GMU_BOOT_SLUMBER_OPTION,
|
||||
|
|
|
|||
|
|
@ -486,7 +486,7 @@ static int gmu_memory_probe(struct kgsl_device *device)
|
|||
* to index being used by GMU/RPMh.
|
||||
*/
|
||||
static int gmu_dcvs_set(struct kgsl_device *device,
|
||||
unsigned int gpu_pwrlevel, unsigned int bus_level)
|
||||
int gpu_pwrlevel, int bus_level)
|
||||
{
|
||||
int ret = 0;
|
||||
struct gmu_device *gmu = KGSL_GMU_DEVICE(device);
|
||||
|
|
@ -1193,7 +1193,7 @@ static void gmu_acd_probe(struct kgsl_device *device, struct gmu_device *gmu,
|
|||
cmd->enable_by_level = 0;
|
||||
|
||||
for (i = 0, cmd_idx = 0; i < numlvl; i++) {
|
||||
acd_level = pwr->pwrlevels[numlvl - i - 1].acd_level;
|
||||
acd_level = pwr->pwrlevels[numlvl - i].acd_level;
|
||||
if (acd_level) {
|
||||
cmd->enable_by_level |= (1 << i);
|
||||
cmd->data[cmd_idx++] = acd_level;
|
||||
|
|
@ -1218,7 +1218,7 @@ static int gmu_probe(struct kgsl_device *device, struct device_node *node)
|
|||
struct kgsl_hfi *hfi;
|
||||
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
|
||||
int i = 0, ret = -ENXIO;
|
||||
int i = 0, ret = -ENXIO, index = 0;
|
||||
|
||||
gmu = kzalloc(sizeof(struct gmu_device), GFP_KERNEL);
|
||||
|
||||
|
|
@ -1288,13 +1288,14 @@ static int gmu_probe(struct kgsl_device *device, struct device_node *node)
|
|||
tasklet_init(&hfi->tasklet, hfi_receiver, (unsigned long) gmu);
|
||||
hfi->kgsldev = device;
|
||||
|
||||
gmu->num_gpupwrlevels = pwr->num_pwrlevels;
|
||||
/* Add a dummy level for "off" that the GMU expects */
|
||||
gmu->gpu_freqs[index++] = 0;
|
||||
|
||||
for (i = 0; i < gmu->num_gpupwrlevels; i++) {
|
||||
int j = gmu->num_gpupwrlevels - 1 - i;
|
||||
/* GMU power levels are in ascending order */
|
||||
for (i = pwr->num_pwrlevels - 1; i >= 0; i--)
|
||||
gmu->gpu_freqs[index++] = pwr->pwrlevels[i].gpu_freq;
|
||||
|
||||
gmu->gpu_freqs[i] = pwr->pwrlevels[j].gpu_freq;
|
||||
}
|
||||
gmu->num_gpupwrlevels = pwr->num_pwrlevels + 1;
|
||||
|
||||
gmu->icc_path = of_icc_get(&gmu->pdev->dev, NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -153,8 +153,8 @@ void gmu_core_snapshot(struct kgsl_device *device)
|
|||
gmu_core_ops->snapshot(device);
|
||||
}
|
||||
|
||||
int gmu_core_dcvs_set(struct kgsl_device *device, unsigned int gpu_pwrlevel,
|
||||
unsigned int bus_level)
|
||||
int gmu_core_dcvs_set(struct kgsl_device *device, int gpu_pwrlevel,
|
||||
int bus_level)
|
||||
{
|
||||
struct gmu_core_ops *gmu_core_ops = GMU_CORE_OPS(device);
|
||||
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ struct gmu_core_ops {
|
|||
int (*probe)(struct kgsl_device *device, struct device_node *node);
|
||||
void (*remove)(struct kgsl_device *device);
|
||||
int (*dcvs_set)(struct kgsl_device *device,
|
||||
unsigned int gpu_pwrlevel, unsigned int bus_level);
|
||||
int gpu_pwrlevel, int bus_level);
|
||||
int (*init)(struct kgsl_device *device);
|
||||
int (*start)(struct kgsl_device *device);
|
||||
void (*stop)(struct kgsl_device *device);
|
||||
|
|
@ -187,8 +187,8 @@ void gmu_core_snapshot(struct kgsl_device *device);
|
|||
bool gmu_core_gpmu_isenabled(struct kgsl_device *device);
|
||||
bool gmu_core_scales_bandwidth(struct kgsl_device *device);
|
||||
bool gmu_core_isenabled(struct kgsl_device *device);
|
||||
int gmu_core_dcvs_set(struct kgsl_device *device, unsigned int gpu_pwrlevel,
|
||||
unsigned int bus_level);
|
||||
int gmu_core_dcvs_set(struct kgsl_device *device, int gpu_pwrlevel,
|
||||
int bus_level);
|
||||
int gmu_core_acd_set(struct kgsl_device *device, unsigned int val);
|
||||
bool gmu_core_regulator_isenabled(struct kgsl_device *device);
|
||||
bool gmu_core_is_register_offset(struct kgsl_device *device,
|
||||
|
|
|
|||
|
|
@ -443,8 +443,8 @@ static void kgsl_pwrctrl_set_thermal_pwrlevel(struct kgsl_device *device,
|
|||
|
||||
mutex_lock(&device->mutex);
|
||||
|
||||
if (level > pwr->num_pwrlevels - 2)
|
||||
level = pwr->num_pwrlevels - 2;
|
||||
if (level >= pwr->num_pwrlevels)
|
||||
level = pwr->num_pwrlevels - 1;
|
||||
|
||||
pwr->thermal_pwrlevel = level;
|
||||
|
||||
|
|
@ -524,8 +524,8 @@ static void kgsl_pwrctrl_min_pwrlevel_set(struct kgsl_device *device,
|
|||
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
|
||||
|
||||
mutex_lock(&device->mutex);
|
||||
if (level > pwr->num_pwrlevels - 2)
|
||||
level = pwr->num_pwrlevels - 2;
|
||||
if (level >= pwr->num_pwrlevels)
|
||||
level = pwr->num_pwrlevels - 1;
|
||||
|
||||
/* You can't set a minimum power level lower than the maximum */
|
||||
if (level < pwr->max_pwrlevel)
|
||||
|
|
@ -572,7 +572,7 @@ static ssize_t num_pwrlevels_show(struct device *dev,
|
|||
struct kgsl_device *device = dev_get_drvdata(dev);
|
||||
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", pwr->num_pwrlevels - 1);
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", pwr->num_pwrlevels);
|
||||
}
|
||||
|
||||
/* Given a GPU clock value, return the lowest matching powerlevel */
|
||||
|
|
@ -581,7 +581,7 @@ static int _get_nearest_pwrlevel(struct kgsl_pwrctrl *pwr, unsigned int clock)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = pwr->num_pwrlevels - 2; i >= 0; i--) {
|
||||
for (i = pwr->num_pwrlevels - 1; i >= 0; i--) {
|
||||
if (abs(pwr->pwrlevels[i].gpu_freq - clock) < 5000000)
|
||||
return i;
|
||||
}
|
||||
|
|
@ -728,7 +728,7 @@ static ssize_t gpu_available_frequencies_show(struct device *dev,
|
|||
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
|
||||
int index, num_chars = 0;
|
||||
|
||||
for (index = 0; index < pwr->num_pwrlevels - 1; index++) {
|
||||
for (index = 0; index < pwr->num_pwrlevels; index++) {
|
||||
num_chars += scnprintf(buf + num_chars,
|
||||
PAGE_SIZE - num_chars - 1,
|
||||
"%d ", pwr->pwrlevels[index].gpu_freq);
|
||||
|
|
@ -750,7 +750,7 @@ static ssize_t gpu_clock_stats_show(struct device *dev,
|
|||
mutex_lock(&device->mutex);
|
||||
kgsl_pwrscale_update_stats(device);
|
||||
mutex_unlock(&device->mutex);
|
||||
for (index = 0; index < pwr->num_pwrlevels - 1; index++)
|
||||
for (index = 0; index < pwr->num_pwrlevels; index++)
|
||||
num_chars += scnprintf(buf + num_chars, PAGE_SIZE - num_chars,
|
||||
"%llu ", pwr->clock_times[index]);
|
||||
|
||||
|
|
@ -925,8 +925,8 @@ static ssize_t default_pwrlevel_store(struct device *dev,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (level > pwr->num_pwrlevels - 2)
|
||||
goto done;
|
||||
if (level >= pwr->num_pwrlevels)
|
||||
return count;
|
||||
|
||||
mutex_lock(&device->mutex);
|
||||
pwr->default_pwrlevel = level;
|
||||
|
|
@ -934,7 +934,6 @@ static ssize_t default_pwrlevel_store(struct device *dev,
|
|||
= pwr->pwrlevels[level].gpu_freq;
|
||||
|
||||
mutex_unlock(&device->mutex);
|
||||
done:
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
@ -1063,7 +1062,7 @@ static ssize_t freq_table_mhz_show(struct device *dev,
|
|||
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
|
||||
int index, num_chars = 0;
|
||||
|
||||
for (index = 0; index < pwr->num_pwrlevels - 1; index++) {
|
||||
for (index = 0; index < pwr->num_pwrlevels; index++) {
|
||||
num_chars += scnprintf(buf + num_chars,
|
||||
PAGE_SIZE - num_chars - 1,
|
||||
"%d ", pwr->pwrlevels[index].gpu_freq / 1000000);
|
||||
|
|
@ -1589,7 +1588,7 @@ static bool _gpu_freq_supported(struct kgsl_pwrctrl *pwr, unsigned int freq)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = pwr->num_pwrlevels - 2; i >= 0; i--) {
|
||||
for (i = pwr->num_pwrlevels - 1; i >= 0; i--) {
|
||||
if (pwr->pwrlevels[i].gpu_freq == freq)
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1687,7 +1686,7 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
|
|||
/* Initialize the user and thermal clock constraints */
|
||||
|
||||
pwr->max_pwrlevel = 0;
|
||||
pwr->min_pwrlevel = pwr->num_pwrlevels - 2;
|
||||
pwr->min_pwrlevel = pwr->num_pwrlevels - 1;
|
||||
pwr->thermal_pwrlevel = 0;
|
||||
pwr->thermal_pwrlevel_floor = pwr->min_pwrlevel;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
#define KGSL_RBBMTIMER_CLK_FREQ KGSL_XO_CLK_FREQ
|
||||
#define KGSL_ISENSE_CLK_FREQ 200000000
|
||||
|
||||
#define KGSL_PWRLEVEL_OFF -1
|
||||
|
||||
enum kgsl_pwrctrl_timer_type {
|
||||
KGSL_PWR_IDLE_TIMER,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -644,7 +644,7 @@ static int opp_notify(struct notifier_block *nb,
|
|||
min_level = pwr->thermal_pwrlevel_floor;
|
||||
|
||||
/* Thermal limit cannot be lower than lowest non-zero operating freq */
|
||||
for (level = 0; level < (pwr->num_pwrlevels - 1); level++) {
|
||||
for (level = 0; level < pwr->num_pwrlevels; level++) {
|
||||
if (pwr->pwrlevels[level].gpu_freq == max_freq)
|
||||
max_level = level;
|
||||
if (pwr->pwrlevels[level].gpu_freq == min_freq)
|
||||
|
|
@ -678,7 +678,7 @@ static void pwrscale_busmon_create(struct kgsl_device *device,
|
|||
bus_profile->profile.get_dev_status = kgsl_busmon_get_dev_status;
|
||||
bus_profile->profile.get_cur_freq = kgsl_busmon_get_cur_freq;
|
||||
|
||||
bus_profile->profile.max_state = pwr->num_pwrlevels - 1;
|
||||
bus_profile->profile.max_state = pwr->num_pwrlevels;
|
||||
bus_profile->profile.freq_table = table;
|
||||
|
||||
dev->parent = &pdev->dev;
|
||||
|
|
@ -736,16 +736,14 @@ int kgsl_pwrscale_init(struct kgsl_device *device, struct platform_device *pdev,
|
|||
|
||||
srcu_init_notifier_head(&pwrscale->nh);
|
||||
|
||||
|
||||
/* do not include the 'off' level or duplicate freq. levels */
|
||||
for (i = 0; i < (pwr->num_pwrlevels - 1); i++)
|
||||
for (i = 0; i < pwr->num_pwrlevels; i++)
|
||||
pwrscale->freq_table[i] = pwr->pwrlevels[i].gpu_freq;
|
||||
|
||||
/*
|
||||
* Max_state is the number of valid power levels.
|
||||
* The valid power levels range from 0 - (max_state - 1)
|
||||
*/
|
||||
gpu_profile->profile.max_state = pwr->num_pwrlevels - 1;
|
||||
gpu_profile->profile.max_state = pwr->num_pwrlevels;
|
||||
/* link storage array to the devfreq profile pointer */
|
||||
gpu_profile->profile.freq_table = pwrscale->freq_table;
|
||||
|
||||
|
|
|
|||
|
|
@ -410,16 +410,18 @@ error_rgmu:
|
|||
* to index being used by GMU/RPMh.
|
||||
*/
|
||||
static int rgmu_dcvs_set(struct kgsl_device *device,
|
||||
unsigned int pwrlevel, unsigned int bus_level)
|
||||
int pwrlevel, int bus_level)
|
||||
{
|
||||
struct rgmu_device *rgmu = KGSL_RGMU_DEVICE(device);
|
||||
int ret;
|
||||
unsigned long rate;
|
||||
|
||||
if (pwrlevel == INVALID_DCVS_IDX)
|
||||
return -EINVAL;
|
||||
|
||||
ret = clk_set_rate(rgmu->gpu_clk,
|
||||
device->pwrctrl.pwrlevels[pwrlevel].gpu_freq);
|
||||
rate = device->pwrctrl.pwrlevels[pwrlevel].gpu_freq;
|
||||
|
||||
ret = clk_set_rate(rgmu->gpu_clk, rate);
|
||||
if (ret)
|
||||
dev_err(&rgmu->pdev->dev, "Couldn't set the GPU clock\n");
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue