linux-arm-msm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sharat Masetty <smasetty-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
To: freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH 5/5] drm/msm/A6x: Add devfreq support in A6x
Date: Fri, 24 Aug 2018 15:24:04 +0530	[thread overview]
Message-ID: <a521dbe8-1215-3474-67e6-adf575c73edd@codeaurora.org> (raw)
In-Reply-To: <20180823160024.GF30125-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org>



On 8/23/2018 9:30 PM, Jordan Crouse wrote:
> On Thu, Aug 23, 2018 at 02:48:31PM +0530, Sharat Masetty wrote:
>> Implement routines to estimate GPU busy time and fetching the
>> current frequency for the polling interval. This is required by
>> the devfreq framework which recommends a frequency change if needed.
>> The driver code then tries to set this new frequency on the GPU by
>> sending an Out Of Band(OOB) request.
> 
> "sending an Out of Band (OOB) request _to the GMU_". Otherwise it is a little
> confusing as to who is doing what.
> 
>>
>> Signed-off-by: Sharat Masetty <smasetty@codeaurora.org>
>> ---
>>   drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 46 +++++++++++++++++++++++++++++++----
>>   drivers/gpu/drm/msm/adreno/a6xx_gmu.h |  2 ++
>>   drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 27 ++++++++++++++++++++
>>   drivers/gpu/drm/msm/adreno/a6xx_gpu.h |  2 ++
>>   4 files changed, 72 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
>> index f6634c0..92ff48b 100644
>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
>> @@ -67,8 +67,10 @@ static bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
>>   		A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_CLK_OFF));
>>   }
>>   
>> -static int a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
>> +static int __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
>>   {
>> +	int ret;
> 
> Should be a u32 since we are doing a gmu_read().
> 
>> +
>>   	gmu_write(gmu, REG_A6XX_GMU_DCVS_ACK_OPTION, 0);
>>   
>>   	gmu_write(gmu, REG_A6XX_GMU_DCVS_PERF_SETTING,
>> @@ -84,7 +86,41 @@ static int a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index)
>>   	a6xx_gmu_set_oob(gmu, GMU_OOB_DCVS_SET);
>>   	a6xx_gmu_clear_oob(gmu, GMU_OOB_DCVS_SET);
>>   
>> -	return gmu_read(gmu, REG_A6XX_GMU_DCVS_RETURN);
>> +	ret = gmu_read(gmu, REG_A6XX_GMU_DCVS_RETURN);
>> +	if (!ret)
>> +		gmu->cur_freq = gmu->gpu_freqs[index];
>> +
> 
> 'ret' from the register read won't be an appropriate Unix error message so it
> should be translated - otherwise it will be confusing because
> 'a6xx_gmu_set_freq' otherwise returns 0 or valid error messages.
> 
>> +	return ret;
>> +}
>> +
>> +int a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq)
>> +{
>> +	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
>> +	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
>> +	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
>> +	u32 perf_index = 0;
>> +
>> +	if (freq == gmu->cur_freq)
>> +		return 0;
>> +
>> +	//TODO: Use a hashmap instead? This gets called potentially every ~10 ms
> 
> Please don't use C++ style comments.  A TODO is okay, but I would prefer if you
> solved this question.  I'm not sure if walking a short list of 10 items is a big
> concern if it happens every 10ms or so.
Sure, I will take care of this...
> 
>> +	for (perf_index = 0; perf_index < gmu->nr_gpu_freqs; perf_index++)
>> +		if (freq == gmu->gpu_freqs[perf_index])
>> +			break;
> 
> Are you positive we don't need to worry about rounding here - will devfreq
> *always* give you an exact frequency value? I  know the clock subsystem allows
> for rounding.  You might want to double check just to be sure that we don't need
> to worry about that here.
> 
> In particular, I would be concerned about the userspace governor for devfreq
> where the user can set anything they want.  I'm not 100% sure that gets vetted
> against the OPP table before we get to this point.
> 
>> +	if (perf_index == gmu->nr_gpu_freqs)
>> +		return -EINVAL;
> 
> Related to the previous comment slightly, if devfreq wants to set a frequency of
> a hundred million HZ is it an error or should we just clamp to the highest
> available frequency and call it good?
For this and the comment above, we use the devfreq_recommended_opp() 
function to get a proper OPP from our OPP list in the dt for the GPU 
device.
> 
>> +	return  __a6xx_gmu_set_freq(gmu, perf_index);
>> +}
>> +
>> +unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu)
>> +{
>> +	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
>> +	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
>> +	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
>> +
>> +	return  gmu->cur_freq;
>>   }
>>   
>>   static bool a6xx_gmu_check_idle_level(struct a6xx_gmu *gmu)
>> @@ -629,8 +665,8 @@ int a6xx_gmu_reset(struct a6xx_gpu *a6xx_gpu)
>>   	if (!ret)
>>   		ret = a6xx_hfi_start(gmu, GMU_COLD_BOOT);
>>   
>> -	/* Set the GPU back to the highest power frequency */
>> -	a6xx_gmu_set_freq(gmu, gmu->nr_gpu_freqs - 1);
>> +	/* Save the current frequency for devfreq */
>> +	gmu->cur_freq = gmu->gpu_freqs[gmu->nr_gpu_freqs - 1];
> 
> I'm not sure I understand this change - don't we need to set the frequency
> GPU immediately out of reset even if DCVS is expected to change it soon?
Oops, this somehow slipped my attention and should not be here. I will 
revert this. Thanks for the catch.
> 
>>   
>>   out:
>>   	if (ret)
>> @@ -671,7 +707,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
>>   	ret = a6xx_hfi_start(gmu, status);
>>   
>>   	/* Set the GPU to the highest power frequency */
>> -	a6xx_gmu_set_freq(gmu, gmu->nr_gpu_freqs - 1);
>> +	__a6xx_gmu_set_freq(gmu, gmu->nr_gpu_freqs - 1);
>>   
>>   out:
>>   	/* Make sure to turn off the boot OOB request on error */
>> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
>> index f9e4dfe..ce6e5ca 100644
>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
>> @@ -77,6 +77,8 @@ struct a6xx_gmu {
>>   	unsigned long gmu_freqs[4];
>>   	u32 cx_arc_votes[4];
>>   
>> +	unsigned long cur_freq;
>> +
> 
> This could just be 'freq'.
> 
>>   	struct a6xx_hfi_queue queues[2];
>>   
>>   	struct tasklet_struct hfi_tasklet;
>> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>> index 3429d33a..af90706 100644
>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>> @@ -7,6 +7,8 @@
>>   #include "a6xx_gpu.h"
>>   #include "a6xx_gmu.xml.h"
>>   
>> +#include <linux/devfreq.h>
>> +
>>   static inline bool _a6xx_check_idle(struct msm_gpu *gpu)
>>   {
>>   	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
>> @@ -682,6 +684,8 @@ static int a6xx_pm_resume(struct msm_gpu *gpu)
>>   
>>   	gpu->needs_hw_init = true;
>>   
>> +	msm_gpu_resume_devfreq(gpu);
>> +
>>   	return ret;
>>   }
>>   
>> @@ -690,6 +694,8 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu)
>>   	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
>>   	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
>>   
>> +	devfreq_suspend_device(gpu->devfreq.devfreq);
>> +
>>   	/*
>>   	 * Make sure the GMU is idle before continuing (because some transitions
>>   	 * may use VBIF
>> @@ -753,6 +759,24 @@ static void a6xx_destroy(struct msm_gpu *gpu)
>>   	kfree(a6xx_gpu);
>>   }
>>   
>> +static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu)
>> +{
>> +	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
>> +	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
>> +	u64 busy_cycles;
>> +	unsigned long busy_time;
>> +
>> +	busy_cycles = gmu_read64(&a6xx_gpu->gmu,
>> +			REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L,
>> +			REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H);
>> +
>> +	busy_time = ((busy_cycles - gpu->devfreq.busy_cycles) * 10) / 192;
>> +
>> +	gpu->devfreq.busy_cycles = busy_cycles;
>> +
>> +	return busy_time;
>> +}
>> +
>>   static const struct adreno_gpu_funcs funcs = {
>>   	.base = {
>>   		.get_param = adreno_get_param,
>> @@ -768,6 +792,9 @@ static void a6xx_destroy(struct msm_gpu *gpu)
>>   #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
>>   		.show = a6xx_show,
>>   #endif
>> +		.gpu_busy = a6xx_gpu_busy,
>> +		.gpu_get_freq = a6xx_gmu_get_freq,
>> +		.gpu_set_freq = a6xx_gmu_set_freq,
>>   	},
>>   	.get_timestamp = a6xx_get_timestamp,
>>   };
>> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
>> index 32c2501..f236767 100644
>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
>> @@ -56,5 +56,7 @@ struct a6xx_gpu {
>>   
>>   int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node, struct platform_device *gpu_pdev);
>>   void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu);
>> +int a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq);
>> +unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu);
>>   
>>   #endif /* __A6XX_GPU_H__ */
>> -- 
>> 1.9.1
>>
> 

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
Linux Foundation Collaborative Project
_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

  parent reply	other threads:[~2018-08-24  9:54 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-23  9:18 [PATCH 0/5] msm/drm: A6x DCVS series Sharat Masetty
     [not found] ` <1535015911-2040-1-git-send-email-smasetty-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-08-23  9:18   ` [PATCH 1/5] drm/msm: suspend devfreq on init Sharat Masetty
     [not found]     ` <1535015911-2040-2-git-send-email-smasetty-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-08-23 15:39       ` Jordan Crouse
2018-08-23  9:18   ` [PATCH 2/5] drm/msm: unregister devfreq upon clean up Sharat Masetty
     [not found]     ` <1535015911-2040-3-git-send-email-smasetty-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-08-23 15:42       ` Jordan Crouse
2018-08-23  9:18   ` [PATCH 3/5] drm/msm/A6x: Add gmu_read64() register read op Sharat Masetty
2018-08-23 15:44     ` Jordan Crouse
2018-08-23  9:18   ` [PATCH 4/5] drm/msm: re-factor devfreq code Sharat Masetty
     [not found]     ` <1535015911-2040-5-git-send-email-smasetty-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-08-23 15:48       ` Jordan Crouse
2018-08-23  9:18   ` [PATCH 5/5] drm/msm/A6x: Add devfreq support in A6x Sharat Masetty
2018-08-23 16:00     ` Jordan Crouse
     [not found]       ` <20180823160024.GF30125-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org>
2018-08-24  9:54         ` Sharat Masetty [this message]
2018-08-24 14:45           ` [Freedreno] " Jordan Crouse
2018-08-23 15:38   ` [PATCH 0/5] msm/drm: A6x DCVS series Jordan Crouse

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a521dbe8-1215-3474-67e6-adf575c73edd@codeaurora.org \
    --to=smasetty-sgv2jx0feol9jmxxk+q4oq@public.gmane.org \
    --cc=dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).