[2/3] firmware: arm_scmi: Add support for marking certain frequencies as boost

Message ID 20240117110443.2060704-3-quic_sibis@quicinc.com
State New
Headers
Series cpufreq: scmi: Add boost frequency support |

Commit Message

Sibi Sankar Jan. 17, 2024, 11:04 a.m. UTC
  All opps above the sustained level/frequency are treated as boost, so mark
them accordingly.

Suggested-by: Sudeep Holla <sudeep.holla@arm.com>
Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
---
 drivers/firmware/arm_scmi/perf.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
  

Comments

Sudeep Holla Jan. 31, 2024, 11:25 a.m. UTC | #1
On Wed, Jan 17, 2024 at 04:34:42PM +0530, Sibi Sankar wrote:
> All opps above the sustained level/frequency are treated as boost, so mark
> them accordingly.
> 
> Suggested-by: Sudeep Holla <sudeep.holla@arm.com>
> Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
> ---
>  drivers/firmware/arm_scmi/perf.c | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
> index e286f04ee6e3..d3fb8c804b3d 100644
> --- a/drivers/firmware/arm_scmi/perf.c
> +++ b/drivers/firmware/arm_scmi/perf.c
> @@ -811,7 +811,7 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
>  				     struct device *dev, u32 domain)
>  {
>  	int idx, ret;
> -	unsigned long freq;
> +	unsigned long freq, sustained_freq;
>  	struct dev_pm_opp_data data = {};
>  	struct perf_dom_info *dom;
>  
> @@ -819,12 +819,21 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
>  	if (IS_ERR(dom))
>  		return PTR_ERR(dom);
>  
> +	if (!dom->level_indexing_mode)
> +		sustained_freq = dom->sustained_perf_level * dom->mult_factor;
> +	else
> +		sustained_freq = dom->sustained_freq_khz * dom->mult_factor;
> +

Can't we just use dom->sustained_freq_khz * 1000UL in both the cases ?

Other than that this series looks good to me but it would be good to
explain how you would use this. Since it is enabled by default, do you
plan to disable boost at time and when ? If it is for thermal reasons,
why your other series handling thermal and limits notification from the
firmware not sufficient.
  
Pierre Gondois Jan. 31, 2024, 2:29 p.m. UTC | #2
Hello Sibi,

On 1/17/24 12:04, Sibi Sankar wrote:
> All opps above the sustained level/frequency are treated as boost, so mark
> them accordingly.
> 
> Suggested-by: Sudeep Holla <sudeep.holla@arm.com>
> Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
> ---
>   drivers/firmware/arm_scmi/perf.c | 11 ++++++++++-
>   1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
> index e286f04ee6e3..d3fb8c804b3d 100644
> --- a/drivers/firmware/arm_scmi/perf.c
> +++ b/drivers/firmware/arm_scmi/perf.c
> @@ -811,7 +811,7 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
>   				     struct device *dev, u32 domain)
>   {
>   	int idx, ret;
> -	unsigned long freq;
> +	unsigned long freq, sustained_freq;
>   	struct dev_pm_opp_data data = {};
>   	struct perf_dom_info *dom;
>   
> @@ -819,12 +819,21 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
>   	if (IS_ERR(dom))
>   		return PTR_ERR(dom);
>   
> +	if (!dom->level_indexing_mode)
> +		sustained_freq = dom->sustained_perf_level * dom->mult_factor;
> +	else
> +		sustained_freq = dom->sustained_freq_khz * dom->mult_factor;
> +
>   	for (idx = 0; idx < dom->opp_count; idx++) {
>   		if (!dom->level_indexing_mode)
>   			freq = dom->opp[idx].perf * dom->mult_factor;
>   		else
>   			freq = dom->opp[idx].indicative_freq * dom->mult_factor;
>   
> +		/* All opps above the sustained level/frequency are treated as boost */
> +		if (sustained_freq && freq > sustained_freq)

It seems the sustained_freq is not optional since SCMI v1.0,
is it necessary to check that (sustained_freq != 0) ?

> +			data.turbo = true;
> +
>   		data.level = dom->opp[idx].perf;
>   		data.freq = freq;
>
  
Sudeep Holla Jan. 31, 2024, 4:08 p.m. UTC | #3
On Wed, Jan 31, 2024 at 03:29:43PM +0100, Pierre Gondois wrote:
> Hello Sibi,
> 
> On 1/17/24 12:04, Sibi Sankar wrote:
> > All opps above the sustained level/frequency are treated as boost, so mark
> > them accordingly.
> > 
> > Suggested-by: Sudeep Holla <sudeep.holla@arm.com>
> > Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
> > ---
> >   drivers/firmware/arm_scmi/perf.c | 11 ++++++++++-
> >   1 file changed, 10 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
> > index e286f04ee6e3..d3fb8c804b3d 100644
> > --- a/drivers/firmware/arm_scmi/perf.c
> > +++ b/drivers/firmware/arm_scmi/perf.c
> > @@ -811,7 +811,7 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
> >   				     struct device *dev, u32 domain)
> >   {
> >   	int idx, ret;
> > -	unsigned long freq;
> > +	unsigned long freq, sustained_freq;
> >   	struct dev_pm_opp_data data = {};
> >   	struct perf_dom_info *dom;
> > @@ -819,12 +819,21 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
> >   	if (IS_ERR(dom))
> >   		return PTR_ERR(dom);
> > +	if (!dom->level_indexing_mode)
> > +		sustained_freq = dom->sustained_perf_level * dom->mult_factor;
> > +	else
> > +		sustained_freq = dom->sustained_freq_khz * dom->mult_factor;
> > +
> >   	for (idx = 0; idx < dom->opp_count; idx++) {
> >   		if (!dom->level_indexing_mode)
> >   			freq = dom->opp[idx].perf * dom->mult_factor;
> >   		else
> >   			freq = dom->opp[idx].indicative_freq * dom->mult_factor;
> > +		/* All opps above the sustained level/frequency are treated as boost */
> > +		if (sustained_freq && freq > sustained_freq)
>
> It seems the sustained_freq is not optional since SCMI v1.0,
> is it necessary to check that (sustained_freq != 0) ?
>

Technically correct, we don't have to. But since day 1, we checked and
handled 0 for perf_level specifically to avoid division by zero. I am
just worried if there are any platforms in the wild with these values as
0. We can start without the check and add it if someone complains perhaps ?
  
Sibi Sankar Feb. 13, 2024, 8:03 a.m. UTC | #4
On 1/31/24 21:38, Sudeep Holla wrote:
> On Wed, Jan 31, 2024 at 03:29:43PM +0100, Pierre Gondois wrote:
>> Hello Sibi,
>>
>> On 1/17/24 12:04, Sibi Sankar wrote:
>>> All opps above the sustained level/frequency are treated as boost, so mark
>>> them accordingly.
>>>

Sudeep/Pierre,

Thanks for taking time to review the series.

>>> Suggested-by: Sudeep Holla <sudeep.holla@arm.com>
>>> Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
>>> ---
>>>    drivers/firmware/arm_scmi/perf.c | 11 ++++++++++-
>>>    1 file changed, 10 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
>>> index e286f04ee6e3..d3fb8c804b3d 100644
>>> --- a/drivers/firmware/arm_scmi/perf.c
>>> +++ b/drivers/firmware/arm_scmi/perf.c
>>> @@ -811,7 +811,7 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
>>>    				     struct device *dev, u32 domain)
>>>    {
>>>    	int idx, ret;
>>> -	unsigned long freq;
>>> +	unsigned long freq, sustained_freq;
>>>    	struct dev_pm_opp_data data = {};
>>>    	struct perf_dom_info *dom;
>>> @@ -819,12 +819,21 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
>>>    	if (IS_ERR(dom))
>>>    		return PTR_ERR(dom);
>>> +	if (!dom->level_indexing_mode)
>>> +		sustained_freq = dom->sustained_perf_level * dom->mult_factor;
>>> +	else
>>> +		sustained_freq = dom->sustained_freq_khz * dom->mult_factor;
>>> +
>>>    	for (idx = 0; idx < dom->opp_count; idx++) {
>>>    		if (!dom->level_indexing_mode)
>>>    			freq = dom->opp[idx].perf * dom->mult_factor;
>>>    		else
>>>    			freq = dom->opp[idx].indicative_freq * dom->mult_factor;
>>> +		/* All opps above the sustained level/frequency are treated as boost */
>>> +		if (sustained_freq && freq > sustained_freq)
>>
>> It seems the sustained_freq is not optional since SCMI v1.0,
>> is it necessary to check that (sustained_freq != 0) ?
>>
> 
> Technically correct, we don't have to. But since day 1, we checked and
> handled 0 for perf_level specifically to avoid division by zero. I am
> just worried if there are any platforms in the wild with these values as
> 0. We can start without the check and add it if someone complains perhaps ?

sure will drop the check in the re-spin.

-Sibi

>
  
Sibi Sankar Feb. 13, 2024, 8:30 a.m. UTC | #5
On 1/31/24 16:55, Sudeep Holla wrote:
> On Wed, Jan 17, 2024 at 04:34:42PM +0530, Sibi Sankar wrote:
>> All opps above the sustained level/frequency are treated as boost, so mark
>> them accordingly.
>>
>> Suggested-by: Sudeep Holla <sudeep.holla@arm.com>
>> Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
>> ---
>>   drivers/firmware/arm_scmi/perf.c | 11 ++++++++++-
>>   1 file changed, 10 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
>> index e286f04ee6e3..d3fb8c804b3d 100644
>> --- a/drivers/firmware/arm_scmi/perf.c
>> +++ b/drivers/firmware/arm_scmi/perf.c
>> @@ -811,7 +811,7 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
>>   				     struct device *dev, u32 domain)
>>   {
>>   	int idx, ret;
>> -	unsigned long freq;
>> +	unsigned long freq, sustained_freq;
>>   	struct dev_pm_opp_data data = {};
>>   	struct perf_dom_info *dom;
>>   
>> @@ -819,12 +819,21 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
>>   	if (IS_ERR(dom))
>>   		return PTR_ERR(dom);
>>   
>> +	if (!dom->level_indexing_mode)
>> +		sustained_freq = dom->sustained_perf_level * dom->mult_factor;
>> +	else
>> +		sustained_freq = dom->sustained_freq_khz * dom->mult_factor;
>> +
> 
> Can't we just use dom->sustained_freq_khz * 1000UL in both the cases ?

sure, I retained sustained_perf_level because I wasn't sure how the
sustained_perf_level would be populated in systems not using level
indexing mode.

> 
> Other than that this series looks good to me but it would be good to
> explain how you would use this. Since it is enabled by default, do you
> plan to disable boost at time and when ? If it is for thermal reasons,
> why your other series handling thermal and limits notification from the
> firmware not sufficient.

Boost frequencies defined in X1E are achievable by only one CPU in a
cluster i.e. either the other CPUs in the same cluster should be in low
power mode or offline. So it's mostly for book keeping i.e. we wouldn't
to intimate incorrectly that the CPUs are running at max possible
frequency when it's actually running at a lower frequency.

-Sibi

>
  

Patch

diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
index e286f04ee6e3..d3fb8c804b3d 100644
--- a/drivers/firmware/arm_scmi/perf.c
+++ b/drivers/firmware/arm_scmi/perf.c
@@ -811,7 +811,7 @@  static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
 				     struct device *dev, u32 domain)
 {
 	int idx, ret;
-	unsigned long freq;
+	unsigned long freq, sustained_freq;
 	struct dev_pm_opp_data data = {};
 	struct perf_dom_info *dom;
 
@@ -819,12 +819,21 @@  static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
 	if (IS_ERR(dom))
 		return PTR_ERR(dom);
 
+	if (!dom->level_indexing_mode)
+		sustained_freq = dom->sustained_perf_level * dom->mult_factor;
+	else
+		sustained_freq = dom->sustained_freq_khz * dom->mult_factor;
+
 	for (idx = 0; idx < dom->opp_count; idx++) {
 		if (!dom->level_indexing_mode)
 			freq = dom->opp[idx].perf * dom->mult_factor;
 		else
 			freq = dom->opp[idx].indicative_freq * dom->mult_factor;
 
+		/* All opps above the sustained level/frequency are treated as boost */
+		if (sustained_freq && freq > sustained_freq)
+			data.turbo = true;
+
 		data.level = dom->opp[idx].perf;
 		data.freq = freq;