mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-14 00:24:41 -04:00
msm: kgsl: Dynamically create an OPP table at runtime
The other reason why we define a OPP table for each target is for devfreq. This is equally as silly as the first reason because we already have a frequency table and forcing the developer to define it twice only invites a mistake. Remove the need for the static OPP table and create it dynamically, at run time, from the information we already have. Change-Id: Ic0dedbada16ec0832c0d531f39460f14aadc1bdd Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
This commit is contained in:
parent
2cb2a1140c
commit
3a2f09f384
3 changed files with 35 additions and 52 deletions
|
|
@ -885,6 +885,40 @@ static void adreno_of_get_ca_aware_properties(struct adreno_device *adreno_dev,
|
|||
}
|
||||
}
|
||||
|
||||
/* Dynamically build the OPP table for the GPU device */
|
||||
static void adreno_build_opp_table(struct device *dev, struct kgsl_pwrctrl *pwr)
|
||||
{
|
||||
unsigned long freq = 0;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* First an annoying step: Some targets have clock drivers that
|
||||
* "helpfully" builds a OPP table for us but usually it is wrong.
|
||||
* Go through and filter out unsupported frequencies
|
||||
*/
|
||||
|
||||
for (;;) {
|
||||
struct dev_pm_opp *opp = dev_pm_opp_find_freq_ceil(dev, &freq);
|
||||
|
||||
if (IS_ERR(opp))
|
||||
break;
|
||||
|
||||
for (i = 0; i < pwr->num_pwrlevels; i++) {
|
||||
if (freq == pwr->pwrlevels[i].gpu_freq)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == pwr->num_pwrlevels)
|
||||
dev_pm_opp_remove(dev, freq);
|
||||
|
||||
freq++;
|
||||
}
|
||||
|
||||
/* Now add all of our supported frequencies into the tree */
|
||||
for (i = 0; i < pwr->num_pwrlevels; i++)
|
||||
dev_pm_opp_add(dev, pwr->pwrlevels[i].gpu_freq, 0);
|
||||
}
|
||||
|
||||
static int adreno_of_parse_pwrlevels(struct adreno_device *adreno_dev,
|
||||
struct device_node *node)
|
||||
{
|
||||
|
|
@ -893,17 +927,6 @@ static int adreno_of_parse_pwrlevels(struct adreno_device *adreno_dev,
|
|||
struct device_node *child;
|
||||
int ret;
|
||||
|
||||
/* ADD the GPU OPP table if we define it */
|
||||
if (of_find_property(device->pdev->dev.of_node,
|
||||
"operating-points-v2", NULL)) {
|
||||
ret = dev_pm_opp_of_add_table(&device->pdev->dev);
|
||||
if (ret) {
|
||||
dev_err(device->dev,
|
||||
"Unable to set the GPU OPP table: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
pwr->num_pwrlevels = 0;
|
||||
|
||||
for_each_child_of_node(node, child) {
|
||||
|
|
@ -971,6 +994,7 @@ static int adreno_of_parse_pwrlevels(struct adreno_device *adreno_dev,
|
|||
"qcom,bus-max", &level->bus_max);
|
||||
}
|
||||
|
||||
adreno_build_opp_table(&device->pdev->dev, pwr);
|
||||
return 0;
|
||||
out:
|
||||
of_node_put(child);
|
||||
|
|
|
|||
|
|
@ -1584,43 +1584,6 @@ static int kgsl_pwrctrl_clk_set_rate(struct clk *grp_clk, unsigned int freq,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool _gpu_freq_supported(struct kgsl_pwrctrl *pwr, unsigned int freq)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = pwr->num_pwrlevels - 1; i >= 0; i--) {
|
||||
if (pwr->pwrlevels[i].gpu_freq == freq)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void kgsl_pwrctrl_disable_unused_opp(struct kgsl_device *device,
|
||||
struct device *dev)
|
||||
{
|
||||
struct dev_pm_opp *opp;
|
||||
unsigned long freq = 0;
|
||||
int ret;
|
||||
|
||||
ret = dev_pm_opp_get_opp_count(dev);
|
||||
/* Return early, If no OPP table or OPP count is zero */
|
||||
if (ret <= 0)
|
||||
return;
|
||||
|
||||
while (1) {
|
||||
opp = dev_pm_opp_find_freq_ceil(dev, &freq);
|
||||
if (IS_ERR(opp))
|
||||
break;
|
||||
|
||||
if (!_gpu_freq_supported(&device->pwrctrl, freq))
|
||||
dev_pm_opp_disable(dev, freq);
|
||||
|
||||
dev_pm_opp_put(opp);
|
||||
freq++;
|
||||
}
|
||||
}
|
||||
|
||||
static u32 *kgsl_bus_get_table(struct platform_device *pdev, int *count)
|
||||
{
|
||||
u32 *levels;
|
||||
|
|
@ -1702,8 +1665,6 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
|
|||
pwr->pwrlevels[i].gpu_freq = freq;
|
||||
}
|
||||
|
||||
kgsl_pwrctrl_disable_unused_opp(device, &pdev->dev);
|
||||
|
||||
kgsl_clk_set_rate(device, pwr->num_pwrlevels - 1);
|
||||
|
||||
freq = clk_round_rate(pwr->grp_clks[6], KGSL_RBBMTIMER_CLK_FREQ);
|
||||
|
|
|
|||
|
|
@ -198,7 +198,5 @@ void kgsl_pwrctrl_busy_time(struct kgsl_device *device, u64 time, u64 busy);
|
|||
void kgsl_pwrctrl_set_constraint(struct kgsl_device *device,
|
||||
struct kgsl_pwr_constraint *pwrc, uint32_t id);
|
||||
int kgsl_pwrctrl_set_default_gpu_pwrlevel(struct kgsl_device *device);
|
||||
void kgsl_pwrctrl_disable_unused_opp(struct kgsl_device *device,
|
||||
struct device *dev);
|
||||
|
||||
#endif /* __KGSL_PWRCTRL_H */
|
||||
|
|
|
|||
Loading…
Reference in a new issue