Message ID | 1527244246-10519-4-git-send-email-smasetty@codeaurora.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Fri, May 25, 2018 at 04:00:46PM +0530, Sharat Masetty wrote: > devfreq framework requires the drivers to provide busy time estimations. > The GPU driver relies on the hardware performance counters 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> > --- > drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 15 +++++++++++---- > drivers/gpu/drm/msm/msm_gpu.c | 23 ++++++++++++++--------- > drivers/gpu/drm/msm/msm_gpu.h | 4 +++- > 3 files changed, 28 insertions(+), 14 deletions(-) > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > index d39400e..a35a840 100644 > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > @@ -1219,12 +1219,19 @@ static struct msm_ringbuffer *a5xx_active_ring(struct msm_gpu *gpu) > return a5xx_gpu->cur_ring; > } > > -static int a5xx_gpu_busy(struct msm_gpu *gpu, uint64_t *value) > +static u64 a5xx_gpu_busy(struct msm_gpu *gpu) > { > - *value = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO, > - REG_A5XX_RBBM_PERFCTR_RBBM_0_HI); > + u64 busy_cycles, busy_time; > > - return 0; > + busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO, > + REG_A5XX_RBBM_PERFCTR_RBBM_0_HI); > + > + busy_time = (busy_cycles - gpu->devfreq.busy_cycles) / > + (clk_get_rate(gpu->core_clk) / 1000000); > + > + gpu->devfreq.busy_cycles = busy_cycles; > + > + return busy_time; > } > > static 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 d8d4fc9..f437ee8 100644 > --- a/drivers/gpu/drm/msm/msm_gpu.c > +++ b/drivers/gpu/drm/msm/msm_gpu.c > @@ -40,7 +40,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; > @@ -50,16 +54,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); > @@ -72,7 +74,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); This will get ugly on a 32 bit build. I think that as long as the reset of the subsystem uses unsigned long we might as well too. I can put on my fortune tellers hat and guess we're probably not going to see a 4GB core running on a 32 bit target in the near future. > return 0; > } > diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h > index 1876b81..d3f02e7 100644 > --- a/drivers/gpu/drm/msm/msm_gpu.h > +++ b/drivers/gpu/drm/msm/msm_gpu.h > @@ -68,7 +68,9 @@ struct msm_gpu_funcs { > /* for generation specific debugfs: */ > int (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor); > #endif > - int (*gpu_busy)(struct msm_gpu *gpu, uint64_t *value); > + u64 (*gpu_busy)(struct msm_gpu *gpu); > + u64 (*gpu_get_freq)(struct msm_gpu *gpu); > + int (*gpu_set_freq)(struct msm_gpu *gpu, u64 freq); So go ahead and change both of these to an unsigned long and that should help the casting. Jordan > }; > > struct msm_gpu { > -- > 1.9.1 >
Hi Sharat,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on robclark/msm-next]
[also build test ERROR on v4.17-rc6]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Sharat-Masetty/drm-msm-re-factor-devfreq-common-code/20180527-191724
base: git://people.freedesktop.org/~robclark/linux msm-next
config: arm-multi_v7_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm
All errors (new ones prefixed by >>):
drivers/gpu/drm/msm/adreno/a5xx_gpu.o: In function `a5xx_gpu_busy':
>> a5xx_gpu.c:(.text+0xcc): undefined reference to `__aeabi_uldivmod'
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index d39400e..a35a840 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1219,12 +1219,19 @@ static struct msm_ringbuffer *a5xx_active_ring(struct msm_gpu *gpu) return a5xx_gpu->cur_ring; } -static int a5xx_gpu_busy(struct msm_gpu *gpu, uint64_t *value) +static u64 a5xx_gpu_busy(struct msm_gpu *gpu) { - *value = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO, - REG_A5XX_RBBM_PERFCTR_RBBM_0_HI); + u64 busy_cycles, busy_time; - return 0; + busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO, + REG_A5XX_RBBM_PERFCTR_RBBM_0_HI); + + busy_time = (busy_cycles - gpu->devfreq.busy_cycles) / + (clk_get_rate(gpu->core_clk) / 1000000); + + gpu->devfreq.busy_cycles = busy_cycles; + + return busy_time; } static 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 d8d4fc9..f437ee8 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -40,7 +40,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; @@ -50,16 +54,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); @@ -72,7 +74,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; } diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 1876b81..d3f02e7 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -68,7 +68,9 @@ struct msm_gpu_funcs { /* for generation specific debugfs: */ int (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor); #endif - int (*gpu_busy)(struct msm_gpu *gpu, uint64_t *value); + u64 (*gpu_busy)(struct msm_gpu *gpu); + u64 (*gpu_get_freq)(struct msm_gpu *gpu); + int (*gpu_set_freq)(struct msm_gpu *gpu, u64 freq); }; struct msm_gpu {
devfreq framework requires the drivers to provide busy time estimations. The GPU driver relies on the hardware performance counters 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> --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 15 +++++++++++---- drivers/gpu/drm/msm/msm_gpu.c | 23 ++++++++++++++--------- drivers/gpu/drm/msm/msm_gpu.h | 4 +++- 3 files changed, 28 insertions(+), 14 deletions(-)