diff mbox series

[22/31] soc/tegra: Migrate to dev_pm_opp_set_config()

Message ID 449b344f037c7ef1970bc84d31e0d4c4cb4d2951.1653564321.git.viresh.kumar@linaro.org
State New
Headers show
Series OPP: Add new configuration interface: dev_pm_opp_set_config() | expand

Commit Message

Viresh Kumar May 26, 2022, 11:42 a.m. UTC
The OPP core now provides a unified API for setting all configuration
types, i.e. dev_pm_opp_set_config().

Lets start using it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/soc/tegra/common.c | 8 ++++++--
 drivers/soc/tegra/pmc.c    | 8 ++++++--
 2 files changed, 12 insertions(+), 4 deletions(-)

Comments

Viresh Kumar June 24, 2022, 12:48 a.m. UTC | #1
On 26-05-22, 17:12, Viresh Kumar wrote:
> The OPP core now provides a unified API for setting all configuration
> types, i.e. dev_pm_opp_set_config().
> 
> Lets start using it.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
>  drivers/soc/tegra/common.c | 8 ++++++--
>  drivers/soc/tegra/pmc.c    | 8 ++++++--
>  2 files changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/soc/tegra/common.c b/drivers/soc/tegra/common.c
> index 49a5360f4507..7ba15cb836e8 100644
> --- a/drivers/soc/tegra/common.c
> +++ b/drivers/soc/tegra/common.c
> @@ -107,6 +107,10 @@ int devm_tegra_core_dev_init_opp_table(struct device *dev,
>  {
>  	u32 hw_version;
>  	int err;
> +	struct dev_pm_opp_config config = {
> +		.supported_hw = &hw_version,
> +		.supported_hw_count = 1,
> +	};
>  
>  	/* Tegra114+ doesn't support OPP yet */
>  	if (!of_machine_is_compatible("nvidia,tegra20") &&
> @@ -118,9 +122,9 @@ int devm_tegra_core_dev_init_opp_table(struct device *dev,
>  	else
>  		hw_version = BIT(tegra_sku_info.soc_speedo_id);
>  
> -	err = devm_pm_opp_set_supported_hw(dev, &hw_version, 1);
> +	err = devm_pm_opp_set_config(dev, &config);
>  	if (err) {
> -		dev_err(dev, "failed to set OPP supported HW: %d\n", err);
> +		dev_err(dev, "failed to set OPP config: %d\n", err);
>  		return err;
>  	}

Jon/Dmitry,

Because of the update [1] to previous patch 21/31, I am updating this
file as (fresh diff):

diff --git a/drivers/soc/tegra/common.c b/drivers/soc/tegra/common.c
index 9f3fdeb1a11c..cd53e46c4058 100644
--- a/drivers/soc/tegra/common.c
+++ b/drivers/soc/tegra/common.c
@@ -107,36 +107,42 @@ int devm_tegra_core_dev_init_opp_table(struct device *dev,
 {
        u32 hw_version;
        int err;
-
-       /*
-        * For some devices we don't have any OPP table in the DT, and in order
-        * to use the same code path for all the devices, we create a dummy OPP
-        * table for them via this call. The dummy OPP table is only capable of
-        * doing clk_set_rate() on invocation of dev_pm_opp_set_rate() and
-        * doesn't provide any other functionality.
-        */
-       err = devm_pm_opp_set_clkname(dev, NULL);
-       if (err) {
-               dev_err(dev, "failed to set OPP clk: %d\n", err);
-               return err;
-       }
-
-       /* Tegra114+ doesn't support OPP yet */
-       if (!of_machine_is_compatible("nvidia,tegra20") &&
-           !of_machine_is_compatible("nvidia,tegra30"))
-               return -ENODEV;
-
-       if (of_machine_is_compatible("nvidia,tegra20"))
+       struct dev_pm_opp_config config = {
+               /*
+                * For some devices we don't have any OPP table in the DT, and
+                * in order to use the same code path for all the devices, we
+                * create a dummy OPP table for them via this. The dummy OPP
+                * table is only capable of doing clk_set_rate() on invocation
+                * of dev_pm_opp_set_rate() and doesn't provide any other
+                * functionality.
+                */
+               .clk_names = NULL,
+               .clk_count = 1,
+       };
+
+       if (of_machine_is_compatible("nvidia,tegra20")) {
                hw_version = BIT(tegra_sku_info.soc_process_id);
-       else
+               config.supported_hw = &hw_version;
+               config.supported_hw_count = 1;
+       } else if (of_machine_is_compatible("nvidia,tegra30")) {
                hw_version = BIT(tegra_sku_info.soc_speedo_id);
+               config.supported_hw = &hw_version;
+               config.supported_hw_count = 1;
+       }

-       err = devm_pm_opp_set_supported_hw(dev, &hw_version, 1);
+       err = devm_pm_opp_set_config(dev, &config);
        if (err) {
-               dev_err(dev, "failed to set OPP supported HW: %d\n", err);
+               dev_err(dev, "failed to set OPP config: %d\n", err);
                return err;
        }

+       /*
+        * Tegra114+ doesn't support OPP yet, return early for non tegra20/30
+        * case.
+        */
+       if (!config.supported_hw)
+               return -ENODEV;
+
        /*
         * Older device-trees have an empty OPP table, we will get
         * -ENODEV from devm_pm_opp_of_add_table() in this case.

-------------------------8<-------------------------

The idea here is to always set the clk name (to NULL) and skip other
stuff for SoCs other than tegra 20/30.

Just see if you can find something odd with the review of it, I will
resend it properly later once the issues are settled.
Viresh Kumar June 24, 2022, 12:57 a.m. UTC | #2
On 24-06-22, 06:18, Viresh Kumar wrote:
> +       struct dev_pm_opp_config config = {
> +               /*
> +                * For some devices we don't have any OPP table in the DT, and
> +                * in order to use the same code path for all the devices, we
> +                * create a dummy OPP table for them via this. The dummy OPP
> +                * table is only capable of doing clk_set_rate() on invocation
> +                * of dev_pm_opp_set_rate() and doesn't provide any other
> +                * functionality.
> +                */
> +               .clk_names = NULL,
> +               .clk_count = 1,
> +       };

Slight modification here, sorry about that. We just need to set the
name as NULL and not the array itself.

diff --git a/drivers/soc/tegra/common.c b/drivers/soc/tegra/common.c
index cd53e46c4058..6a099d764cce 100644
--- a/drivers/soc/tegra/common.c
+++ b/drivers/soc/tegra/common.c
@@ -116,7 +116,7 @@ int devm_tegra_core_dev_init_opp_table(struct device *dev,
                 * of dev_pm_opp_set_rate() and doesn't provide any other
                 * functionality.
                 */
-               .clk_names = NULL,
+               .clk_names = (const char *[]){ NULL },
                .clk_count = 1,
        };
Dmitry Osipenko June 26, 2022, 10:14 p.m. UTC | #3
24.06.2022 03:57, Viresh Kumar пишет:
> On 24-06-22, 06:18, Viresh Kumar wrote:
>> +       struct dev_pm_opp_config config = {
>> +               /*
>> +                * For some devices we don't have any OPP table in the DT, and
>> +                * in order to use the same code path for all the devices, we
>> +                * create a dummy OPP table for them via this. The dummy OPP
>> +                * table is only capable of doing clk_set_rate() on invocation
>> +                * of dev_pm_opp_set_rate() and doesn't provide any other
>> +                * functionality.
>> +                */
>> +               .clk_names = NULL,
>> +               .clk_count = 1,
>> +       };
> 
> Slight modification here, sorry about that. We just need to set the
> name as NULL and not the array itself.
> 
> diff --git a/drivers/soc/tegra/common.c b/drivers/soc/tegra/common.c
> index cd53e46c4058..6a099d764cce 100644
> --- a/drivers/soc/tegra/common.c
> +++ b/drivers/soc/tegra/common.c
> @@ -116,7 +116,7 @@ int devm_tegra_core_dev_init_opp_table(struct device *dev,
>                  * of dev_pm_opp_set_rate() and doesn't provide any other
>                  * functionality.
>                  */
> -               .clk_names = NULL,
> +               .clk_names = (const char *[]){ NULL },
>                 .clk_count = 1,
>         };
> 

Looks okay. If you'll solve the cpufreq problem where OPP config is set
by two drivers for the same cpu device and will keep the set_opp()
helper that is needed by the Tegra 3d driver, then it all should work
for Tegra. Looking forward to the next update of the OPP patches, thank you.
Viresh Kumar June 27, 2022, 6:45 a.m. UTC | #4
On 27-06-22, 01:14, Dmitry Osipenko wrote:
> Looks okay. If you'll solve the cpufreq problem where OPP config is set
> by two drivers for the same cpu device

This is supported, there is some early freeing of resources on the
removal path though, the reasoning for which I already gave in another
email. Though, I am open to sorting that out as well, but nothing
breaks the code for now AFAICT.

> and will keep the set_opp()
> helper that is needed by the Tegra 3d driver, then it all should work
> for Tegra.

I have responded to that as well on another thread.

> Looking forward to the next update of the OPP patches, thank you.

All that I have is already pushed to linux-next, I don't have any more
changes. Yes I still need to send the updated changes to list.
Dmitry Osipenko June 27, 2022, 7:14 a.m. UTC | #5
27.06.2022 09:45, Viresh Kumar пишет:
>> Looks okay. If you'll solve the cpufreq problem where OPP config is set
>> by two drivers for the same cpu device
> This is supported, there is some early freeing of resources on the
> removal path though, the reasoning for which I already gave in another
> email. Though, I am open to sorting that out as well, but nothing
> breaks the code for now AFAICT.
> 

In case of Tegra, we use tegra-cpufreq driver that sets supported_hw and
registers cpufreq-dt. If cpufreq-dt driver defers the probe, then the
supported_hw will be lost on the re-probe. I haven't checked yet, but I
suppose that cpufreq-dt driver defers on Tegra30 because of the CPU
regulator and that's why we get the "OPP table is missing" error.
Viresh Kumar June 27, 2022, 7:21 a.m. UTC | #6
On 27-06-22, 10:14, Dmitry Osipenko wrote:
> 27.06.2022 09:45, Viresh Kumar пишет:
> >> Looks okay. If you'll solve the cpufreq problem where OPP config is set
> >> by two drivers for the same cpu device
> > This is supported, there is some early freeing of resources on the
> > removal path though, the reasoning for which I already gave in another
> > email. Though, I am open to sorting that out as well, but nothing
> > breaks the code for now AFAICT.
> > 
> 
> In case of Tegra, we use tegra-cpufreq driver that sets supported_hw and
> registers cpufreq-dt. If cpufreq-dt driver defers the probe, then the
> supported_hw will be lost on the re-probe. I haven't checked yet, but I
> suppose that cpufreq-dt driver defers on Tegra30 because of the CPU
> regulator and that's why we get the "OPP table is missing" error.

Aha, I get it now. I see, this is a real problem. Will fix it. Give me
some time to think. Thanks.
Viresh Kumar June 28, 2022, 10:11 a.m. UTC | #7
On 28-06-22, 13:08, Dmitry Osipenko wrote:
> The opp/linux-next works fine, thank you.
> 
> Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>

Thanks. I should add this to all the core + tegra -patches in that
branch, right ?

> BTW, the idr_alloc() is obsoleted by xa_alloc().

The earlier interface isn't deprecated, right ? I really don't want to
go change it again :)
Dmitry Osipenko June 28, 2022, 10:16 a.m. UTC | #8
On 6/28/22 13:11, Viresh Kumar wrote:
> On 28-06-22, 13:08, Dmitry Osipenko wrote:
>> The opp/linux-next works fine, thank you.
>>
>> Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> 
> Thanks. I should add this to all the core + tegra -patches in that
> branch, right ?

Yes, please.

>> BTW, the idr_alloc() is obsoleted by xa_alloc().
> 
> The earlier interface isn't deprecated, right ? I really don't want to
> go change it again :)
> 

It has been in a process of deprecation for a couple years now. All IDR
instances are slowly converting to XA. You won't need to take mutex with
xa_alloc().
Viresh Kumar June 28, 2022, 11 a.m. UTC | #9
On 28-06-22, 13:16, Dmitry Osipenko wrote:
> It has been in a process of deprecation for a couple years now. All IDR
> instances are slowly converting to XA. You won't need to take mutex with
> xa_alloc().

Okay, migrated to it now and pushed :)
Jon Hunter June 29, 2022, 5:03 p.m. UTC | #10
On 28/06/2022 11:08, Dmitry Osipenko wrote:
> On 6/28/22 10:09, Viresh Kumar wrote:
>> On 27-06-22, 12:51, Viresh Kumar wrote:
>>> On 27-06-22, 10:14, Dmitry Osipenko wrote:
>>>> 27.06.2022 09:45, Viresh Kumar пишет:
>>>>>> Looks okay. If you'll solve the cpufreq problem where OPP config is set
>>>>>> by two drivers for the same cpu device
>>>>> This is supported, there is some early freeing of resources on the
>>>>> removal path though, the reasoning for which I already gave in another
>>>>> email. Though, I am open to sorting that out as well, but nothing
>>>>> breaks the code for now AFAICT.
>>>>>
>>>>
>>>> In case of Tegra, we use tegra-cpufreq driver that sets supported_hw and
>>>> registers cpufreq-dt. If cpufreq-dt driver defers the probe, then the
>>>> supported_hw will be lost on the re-probe. I haven't checked yet, but I
>>>> suppose that cpufreq-dt driver defers on Tegra30 because of the CPU
>>>> regulator and that's why we get the "OPP table is missing" error.
>>>
>>> Aha, I get it now. I see, this is a real problem. Will fix it. Give me
>>> some time to think. Thanks.
>>
>> Okay, I fixed this in opp/linux-next, can you or Jon please give it a
>> go on tegra30 to see if the issue is fixed ?
>>
>> FWIW, I have fixed this with the IDR API and the OPP core will only
>> free the resources in clear-config, that the corresponding set-config
>> has configured. I have tested it with the clk API only though.
>>
>> Once you confirm, I will resend all the patches and hope no issues are
>> left here.
>>
>> Thanks for helping out guys. Really appreciate it.
>>
> 
> The opp/linux-next works fine, thank you.
> 
> Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>


Today's -next is also working fine for me too!

Thanks
Jon
diff mbox series

Patch

diff --git a/drivers/soc/tegra/common.c b/drivers/soc/tegra/common.c
index 49a5360f4507..7ba15cb836e8 100644
--- a/drivers/soc/tegra/common.c
+++ b/drivers/soc/tegra/common.c
@@ -107,6 +107,10 @@  int devm_tegra_core_dev_init_opp_table(struct device *dev,
 {
 	u32 hw_version;
 	int err;
+	struct dev_pm_opp_config config = {
+		.supported_hw = &hw_version,
+		.supported_hw_count = 1,
+	};
 
 	/* Tegra114+ doesn't support OPP yet */
 	if (!of_machine_is_compatible("nvidia,tegra20") &&
@@ -118,9 +122,9 @@  int devm_tegra_core_dev_init_opp_table(struct device *dev,
 	else
 		hw_version = BIT(tegra_sku_info.soc_speedo_id);
 
-	err = devm_pm_opp_set_supported_hw(dev, &hw_version, 1);
+	err = devm_pm_opp_set_config(dev, &config);
 	if (err) {
-		dev_err(dev, "failed to set OPP supported HW: %d\n", err);
+		dev_err(dev, "failed to set OPP config: %d\n", err);
 		return err;
 	}
 
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index fdf508e03400..01ec76dd433d 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -1366,6 +1366,10 @@  static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np)
 	struct generic_pm_domain *genpd;
 	const char *rname = "core";
 	int err;
+	struct dev_pm_opp_config config = {
+		.regulator_names = &rname,
+		.regulator_count = 1,
+	};
 
 	genpd = devm_kzalloc(pmc->dev, sizeof(*genpd), GFP_KERNEL);
 	if (!genpd)
@@ -1375,10 +1379,10 @@  static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np)
 	genpd->set_performance_state = tegra_pmc_core_pd_set_performance_state;
 	genpd->opp_to_performance_state = tegra_pmc_core_pd_opp_to_performance_state;
 
-	err = devm_pm_opp_set_regulators(pmc->dev, &rname, 1);
+	err = devm_pm_opp_set_config(pmc->dev, &config);
 	if (err)
 		return dev_err_probe(pmc->dev, err,
-				     "failed to set core OPP regulator\n");
+				     "failed to set OPP config\n");
 
 	err = pm_genpd_init(genpd, NULL, false);
 	if (err) {