Merge "msm: kgsl: Add GPU Cx ipeak client support on SDM660"

This commit is contained in:
Linux Build Service Account 2017-02-28 17:03:51 -08:00 committed by Gerrit - the friendly Code Review server
commit eee829e625
3 changed files with 86 additions and 1 deletions

View file

@ -110,6 +110,17 @@ Optional Properties:
- qcom,l2pc-cpu-mask-latency:
The CPU mask latency in microseconds to avoid L2PC
on masked CPUs.
- qcom,gpu-cx-ipeak:
To handle Cx peak current limit.
<phandle bit>
phandle - phandle of cx ipeak device node
bit - bit number of client in relevant register
- qcom,gpu-cx-ipeak-clk:
GPU clock threshold for Cx Ipeak voting. KGSL votes
to Cx Ipeak driver when GPU clock crosses this threshold.
Cx Ipeak can limit peak current based on voting from other clients.
- qcom,force-32bit:
Force the GPU to use 32 bit data sizes even if
it is capable of doing 64 bit.

View file

@ -361,6 +361,26 @@ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device,
if (new_level == old_level)
return;
if (pwr->gpu_cx_ipeak) {
unsigned int old_freq = pwr->pwrlevels[old_level].gpu_freq;
unsigned int new_freq = pwr->pwrlevels[new_level].gpu_freq;
/*
* Set Cx ipeak vote for GPU if it tries to cross
* threshold frequency.
*/
if (old_freq < pwr->gpu_cx_ipeak_clk &&
new_freq >= pwr->gpu_cx_ipeak_clk) {
int ret = cx_ipeak_update(pwr->gpu_cx_ipeak, true);
if (ret) {
KGSL_PWR_ERR(device,
"cx_ipeak_update failed %d\n", ret);
return;
}
}
}
kgsl_pwrscale_update_stats(device);
/*
@ -422,6 +442,24 @@ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device,
/* Timestamp the frequency change */
device->pwrscale.freq_change_time = ktime_to_ms(ktime_get());
if (pwr->gpu_cx_ipeak) {
unsigned int old_freq = pwr->pwrlevels[old_level].gpu_freq;
unsigned int new_freq = pwr->pwrlevels[new_level].gpu_freq;
/*
* Reset Cx ipeak vote for GPU if it goes below
* threshold frequency.
*/
if (old_freq >= pwr->gpu_cx_ipeak_clk &&
new_freq < pwr->gpu_cx_ipeak_clk) {
int ret = cx_ipeak_update(pwr->gpu_cx_ipeak, false);
if (ret)
KGSL_PWR_ERR(device,
"cx_ipeak_update failed %d\n", ret);
}
}
}
EXPORT_SYMBOL(kgsl_pwrctrl_pwrlevel_change);
@ -2217,8 +2255,37 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
of_property_read_string(pdev->dev.of_node, "qcom,tsens-name",
&pwr->tsens_name);
/* Cx ipeak client support */
if (of_find_property(pdev->dev.of_node, "qcom,gpu-cx-ipeak", NULL)) {
if (!of_property_read_u32(pdev->dev.of_node,
"qcom,gpu-cx-ipeak-clk", &pwr->gpu_cx_ipeak_clk)) {
pwr->gpu_cx_ipeak = cx_ipeak_register(pdev->dev.of_node,
"qcom,gpu-cx-ipeak");
} else {
KGSL_PWR_ERR(device, "failed to get gpu cxip clk\n");
result = -EINVAL;
goto error_cleanup_pwr_limit;
}
if (IS_ERR(pwr->gpu_cx_ipeak)) {
result = PTR_ERR(pwr->gpu_cx_ipeak);
KGSL_PWR_ERR(device,
"Failed to register Cx ipeak client %d\n",
result);
goto error_cleanup_pwr_limit;
}
}
return result;
error_cleanup_pwr_limit:
pwr->power_flags = 0;
if (!IS_ERR_OR_NULL(pwr->sysfs_pwr_limit)) {
list_del(&pwr->sysfs_pwr_limit->node);
kfree(pwr->sysfs_pwr_limit);
pwr->sysfs_pwr_limit = NULL;
}
kfree(pwr->bus_ib);
error_cleanup_pcl:
_close_pcl(pwr);
error_cleanup_ocmem_pcl:
@ -2238,6 +2305,8 @@ void kgsl_pwrctrl_close(struct kgsl_device *device)
KGSL_PWR_INFO(device, "close device %d\n", device->id);
cx_ipeak_unregister(pwr->gpu_cx_ipeak);
pwr->power_flags = 0;
if (!IS_ERR_OR_NULL(pwr->sysfs_pwr_limit)) {

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -14,6 +14,7 @@
#define __KGSL_PWRCTRL_H
#include <linux/pm_qos.h>
#include <soc/qcom/cx_ipeak.h>
/*****************************************************************************
** power flags
@ -153,6 +154,8 @@ struct kgsl_regulator {
* isense_clk_indx - index of isense clock, 0 if no isense
* isense_clk_on_level - isense clock rate is XO rate below this level.
* tsens_name - pointer to temperature sensor name of GPU temperature sensor
* gpu_cx_ipeak - pointer to cx ipeak client used by GPU
* gpu_cx_ipeak_clk - GPU threshold frequency to call cx ipeak driver API
*/
struct kgsl_pwrctrl {
@ -206,6 +209,8 @@ struct kgsl_pwrctrl {
unsigned int gpu_bimc_int_clk_freq;
bool gpu_bimc_interface_enabled;
const char *tsens_name;
struct cx_ipeak_client *gpu_cx_ipeak;
unsigned int gpu_cx_ipeak_clk;
};
int kgsl_pwrctrl_init(struct kgsl_device *device);