diff options
author | Sharat Masetty <smasetty@codeaurora.org> | 2018-10-04 15:11:42 +0530 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2018-10-04 09:14:20 -0400 |
commit | de0a3d094de0858f091cf353c437e912ca41a506 (patch) | |
tree | 90ee21de75988516758d4d3b0be388833dc90df9 /drivers/gpu/drm/msm/msm_gpu.c | |
parent | c28aa2031f64701d4a1a78f97147e93fc5eb0c04 (diff) |
drm/msm: re-factor devfreq code
The devfreq framework requires the drivers to provide busy time estimations.
The GPU driver relies on the hardware performance counteres for the busy time
estimations, but different hardware revisions have counters which can be
sourced from different clocks. So the busy time estimation will be target
dependent. Additionally on targets where the clocks are completely controlled
by the on chip microcontroller, fetching and setting the current GPU frequency
will be different. This patch aims to embrace these differences by re-factoring
the devfreq code a bit.
Signed-off-by: Sharat Masetty <smasetty@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/msm_gpu.c')
-rw-r--r-- | drivers/gpu/drm/msm/msm_gpu.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 3378a9d5a2a2..11aac8337066 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -41,7 +41,11 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq, if (IS_ERR(opp)) return PTR_ERR(opp); - clk_set_rate(gpu->core_clk, *freq); + if (gpu->funcs->gpu_set_freq) + gpu->funcs->gpu_set_freq(gpu, (u64)*freq); + else + clk_set_rate(gpu->core_clk, *freq); + dev_pm_opp_put(opp); return 0; @@ -51,16 +55,14 @@ static int msm_devfreq_get_dev_status(struct device *dev, struct devfreq_dev_status *status) { struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev)); - u64 cycles; - u32 freq = ((u32) status->current_frequency) / 1000000; ktime_t time; - status->current_frequency = (unsigned long) clk_get_rate(gpu->core_clk); - gpu->funcs->gpu_busy(gpu, &cycles); - - status->busy_time = ((u32) (cycles - gpu->devfreq.busy_cycles)) / freq; + if (gpu->funcs->gpu_get_freq) + status->current_frequency = gpu->funcs->gpu_get_freq(gpu); + else + status->current_frequency = clk_get_rate(gpu->core_clk); - gpu->devfreq.busy_cycles = cycles; + status->busy_time = gpu->funcs->gpu_busy(gpu); time = ktime_get(); status->total_time = ktime_us_delta(time, gpu->devfreq.time); @@ -73,7 +75,10 @@ static int msm_devfreq_get_cur_freq(struct device *dev, unsigned long *freq) { struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev)); - *freq = (unsigned long) clk_get_rate(gpu->core_clk); + if (gpu->funcs->gpu_get_freq) + *freq = gpu->funcs->gpu_get_freq(gpu); + else + *freq = clk_get_rate(gpu->core_clk); return 0; } @@ -88,7 +93,7 @@ static struct devfreq_dev_profile msm_devfreq_profile = { static void msm_devfreq_init(struct msm_gpu *gpu) { /* We need target support to do devfreq */ - if (!gpu->funcs->gpu_busy || !gpu->core_clk) + if (!gpu->funcs->gpu_busy) return; msm_devfreq_profile.initial_freq = gpu->fast_rate; @@ -186,6 +191,14 @@ static int disable_axi(struct msm_gpu *gpu) return 0; } +void msm_gpu_resume_devfreq(struct msm_gpu *gpu) +{ + gpu->devfreq.busy_cycles = 0; + gpu->devfreq.time = ktime_get(); + + devfreq_resume_device(gpu->devfreq.devfreq); +} + int msm_gpu_pm_resume(struct msm_gpu *gpu) { int ret; @@ -204,12 +217,7 @@ int msm_gpu_pm_resume(struct msm_gpu *gpu) if (ret) return ret; - if (gpu->devfreq.devfreq) { - gpu->devfreq.busy_cycles = 0; - gpu->devfreq.time = ktime_get(); - - devfreq_resume_device(gpu->devfreq.devfreq); - } + msm_gpu_resume_devfreq(gpu); gpu->needs_hw_init = true; @@ -222,8 +230,7 @@ int msm_gpu_pm_suspend(struct msm_gpu *gpu) DBG("%s", gpu->name); - if (gpu->devfreq.devfreq) - devfreq_suspend_device(gpu->devfreq.devfreq); + devfreq_suspend_device(gpu->devfreq.devfreq); ret = disable_axi(gpu); if (ret) |