aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSharat Masetty <smasetty@codeaurora.org>2018-10-04 05:41:42 -0400
committerRob Clark <robdclark@gmail.com>2018-10-04 09:14:20 -0400
commitde0a3d094de0858f091cf353c437e912ca41a506 (patch)
tree90ee21de75988516758d4d3b0be388833dc90df9
parentc28aa2031f64701d4a1a78f97147e93fc5eb0c04 (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>
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_gpu.c16
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.c43
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.h5
3 files changed, 41 insertions, 23 deletions
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 6a6849309b6a..40b4f8a0ae6d 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -1436,12 +1436,20 @@ static struct msm_ringbuffer *a5xx_active_ring(struct msm_gpu *gpu)
1436 return a5xx_gpu->cur_ring; 1436 return a5xx_gpu->cur_ring;
1437} 1437}
1438 1438
1439static int a5xx_gpu_busy(struct msm_gpu *gpu, uint64_t *value) 1439static unsigned long a5xx_gpu_busy(struct msm_gpu *gpu)
1440{ 1440{
1441 *value = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO, 1441 u64 busy_cycles;
1442 REG_A5XX_RBBM_PERFCTR_RBBM_0_HI); 1442 unsigned long busy_time;
1443 1443
1444 return 0; 1444 busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO,
1445 REG_A5XX_RBBM_PERFCTR_RBBM_0_HI);
1446
1447 busy_time = (busy_cycles - gpu->devfreq.busy_cycles) /
1448 (clk_get_rate(gpu->core_clk) / 1000000);
1449
1450 gpu->devfreq.busy_cycles = busy_cycles;
1451
1452 return busy_time;
1445} 1453}
1446 1454
1447static const struct adreno_gpu_funcs funcs = { 1455static const struct adreno_gpu_funcs funcs = {
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,
41 if (IS_ERR(opp)) 41 if (IS_ERR(opp))
42 return PTR_ERR(opp); 42 return PTR_ERR(opp);
43 43
44 clk_set_rate(gpu->core_clk, *freq); 44 if (gpu->funcs->gpu_set_freq)
45 gpu->funcs->gpu_set_freq(gpu, (u64)*freq);
46 else
47 clk_set_rate(gpu->core_clk, *freq);
48
45 dev_pm_opp_put(opp); 49 dev_pm_opp_put(opp);
46 50
47 return 0; 51 return 0;
@@ -51,16 +55,14 @@ static int msm_devfreq_get_dev_status(struct device *dev,
51 struct devfreq_dev_status *status) 55 struct devfreq_dev_status *status)
52{ 56{
53 struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev)); 57 struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev));
54 u64 cycles;
55 u32 freq = ((u32) status->current_frequency) / 1000000;
56 ktime_t time; 58 ktime_t time;
57 59
58 status->current_frequency = (unsigned long) clk_get_rate(gpu->core_clk); 60 if (gpu->funcs->gpu_get_freq)
59 gpu->funcs->gpu_busy(gpu, &cycles); 61 status->current_frequency = gpu->funcs->gpu_get_freq(gpu);
60 62 else
61 status->busy_time = ((u32) (cycles - gpu->devfreq.busy_cycles)) / freq; 63 status->current_frequency = clk_get_rate(gpu->core_clk);
62 64
63 gpu->devfreq.busy_cycles = cycles; 65 status->busy_time = gpu->funcs->gpu_busy(gpu);
64 66
65 time = ktime_get(); 67 time = ktime_get();
66 status->total_time = ktime_us_delta(time, gpu->devfreq.time); 68 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)
73{ 75{
74 struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev)); 76 struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev));
75 77
76 *freq = (unsigned long) clk_get_rate(gpu->core_clk); 78 if (gpu->funcs->gpu_get_freq)
79 *freq = gpu->funcs->gpu_get_freq(gpu);
80 else
81 *freq = clk_get_rate(gpu->core_clk);
77 82
78 return 0; 83 return 0;
79} 84}
@@ -88,7 +93,7 @@ static struct devfreq_dev_profile msm_devfreq_profile = {
88static void msm_devfreq_init(struct msm_gpu *gpu) 93static void msm_devfreq_init(struct msm_gpu *gpu)
89{ 94{
90 /* We need target support to do devfreq */ 95 /* We need target support to do devfreq */
91 if (!gpu->funcs->gpu_busy || !gpu->core_clk) 96 if (!gpu->funcs->gpu_busy)
92 return; 97 return;
93 98
94 msm_devfreq_profile.initial_freq = gpu->fast_rate; 99 msm_devfreq_profile.initial_freq = gpu->fast_rate;
@@ -186,6 +191,14 @@ static int disable_axi(struct msm_gpu *gpu)
186 return 0; 191 return 0;
187} 192}
188 193
194void msm_gpu_resume_devfreq(struct msm_gpu *gpu)
195{
196 gpu->devfreq.busy_cycles = 0;
197 gpu->devfreq.time = ktime_get();
198
199 devfreq_resume_device(gpu->devfreq.devfreq);
200}
201
189int msm_gpu_pm_resume(struct msm_gpu *gpu) 202int msm_gpu_pm_resume(struct msm_gpu *gpu)
190{ 203{
191 int ret; 204 int ret;
@@ -204,12 +217,7 @@ int msm_gpu_pm_resume(struct msm_gpu *gpu)
204 if (ret) 217 if (ret)
205 return ret; 218 return ret;
206 219
207 if (gpu->devfreq.devfreq) { 220 msm_gpu_resume_devfreq(gpu);
208 gpu->devfreq.busy_cycles = 0;
209 gpu->devfreq.time = ktime_get();
210
211 devfreq_resume_device(gpu->devfreq.devfreq);
212 }
213 221
214 gpu->needs_hw_init = true; 222 gpu->needs_hw_init = true;
215 223
@@ -222,8 +230,7 @@ int msm_gpu_pm_suspend(struct msm_gpu *gpu)
222 230
223 DBG("%s", gpu->name); 231 DBG("%s", gpu->name);
224 232
225 if (gpu->devfreq.devfreq) 233 devfreq_suspend_device(gpu->devfreq.devfreq);
226 devfreq_suspend_device(gpu->devfreq.devfreq);
227 234
228 ret = disable_axi(gpu); 235 ret = disable_axi(gpu);
229 if (ret) 236 if (ret)
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 9122ee6e55e4..f82bac086666 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -70,9 +70,11 @@ struct msm_gpu_funcs {
70 /* for generation specific debugfs: */ 70 /* for generation specific debugfs: */
71 int (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor); 71 int (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor);
72#endif 72#endif
73 int (*gpu_busy)(struct msm_gpu *gpu, uint64_t *value); 73 unsigned long (*gpu_busy)(struct msm_gpu *gpu);
74 struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu); 74 struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu);
75 int (*gpu_state_put)(struct msm_gpu_state *state); 75 int (*gpu_state_put)(struct msm_gpu_state *state);
76 unsigned long (*gpu_get_freq)(struct msm_gpu *gpu);
77 void (*gpu_set_freq)(struct msm_gpu *gpu, unsigned long freq);
76}; 78};
77 79
78struct msm_gpu { 80struct msm_gpu {
@@ -264,6 +266,7 @@ static inline void gpu_write64(struct msm_gpu *gpu, u32 lo, u32 hi, u64 val)
264 266
265int msm_gpu_pm_suspend(struct msm_gpu *gpu); 267int msm_gpu_pm_suspend(struct msm_gpu *gpu);
266int msm_gpu_pm_resume(struct msm_gpu *gpu); 268int msm_gpu_pm_resume(struct msm_gpu *gpu);
269void msm_gpu_resume_devfreq(struct msm_gpu *gpu);
267 270
268int msm_gpu_hw_init(struct msm_gpu *gpu); 271int msm_gpu_hw_init(struct msm_gpu *gpu);
269 272