On Mon, Aug 27, 2018 at 12:47:19PM +0530, Sharat Masetty wrote: > 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@xxxxxxxxxxxxxx> > --- > drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 16 +++++++++--- > drivers/gpu/drm/msm/msm_gpu.c | 49 ++++++++++++++++++++--------------- > drivers/gpu/drm/msm/msm_gpu.h | 5 +++- > 3 files changed, 44 insertions(+), 26 deletions(-) > > diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > index 897f3e2..043e680 100644 > --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c > @@ -1369,12 +1369,20 @@ 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 unsigned long 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; > + unsigned long 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 8d6bc0c..26c1c3a 100644 > --- a/drivers/gpu/drm/msm/msm_gpu.c > +++ b/drivers/gpu/drm/msm/msm_gpu.c > @@ -36,12 +36,16 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq, > struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev)); > struct dev_pm_opp *opp; > > - opp = dev_pm_opp_find_freq_ceil(dev, freq); > + opp = devfreq_recommended_opp(dev, freq, flags); > + if (IS_ERR(opp)) > + return PTR_ERR(opp); > > - if (!IS_ERR(opp)) { > + if (gpu->funcs->gpu_set_freq) > + gpu->funcs->gpu_set_freq(gpu, (u64)*freq); Depending on how the interconnect patches end up looking it might make more sense for us to send the OPP itself to gpu_set_freq() but we'll put a pin in that until we know more. Jordan -- The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project