cpufreq: airoha: Add EN7581 Cpufreq SMC driver
PATCH v2 1/1 cpufreq: airoha: Add EN7581 Cpufreq SMC driver
Add simple Cpufreq driver for Airoha EN7581 SoC that control CPU frequency scaling with SMC APIs.
All CPU share the same frequency and can't be controlled independently. Current shared CPU frequency is returned by the related SMC command.
Add SoC compatible to cpufreq-dt-plat block list as a dedicated cpufreq driver is needed with OPP v2 nodes declared in DTS.
---
Changes v2:
- Fix kernel bot error with missing slab.h and bitfield.h header
- Limit COMPILE_TEST to ARM64 due to smcc 1.2
drivers/cpufreq/Kconfig.arm | 8 ++ drivers/cpufreq/Makefile | 1 + drivers/cpufreq/airoha-cpufreq.c | 183 +++++++++++++++++++++++++++ drivers/cpufreq/cpufreq-dt-platdev.c | 2 + 4 files changed, 194 insertions(+) create mode 100644 drivers/cpufreq/airoha-cpufreq.c
drivers/cpufreq/Kconfig.arm +8 -0
@@ -15,6 +15,14 @@ config ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM To compile this driver as a module, choose M here: the module will be called sun50i-cpufreq-nvmem. +config ARM_AIROHA_SOC_CPUFREQ + tristate "Airoha EN7581 SoC CPUFreq support" + depends on ARCH_AIROHA || (COMPILE_TEST && ARM64) + select PM_OPP + default ARCH_AIROHA + help + This adds the CPUFreq driver for Airoha EN7581 SoCs. + config ARM_APPLE_SOC_CPUFREQ tristate "Apple Silicon SoC CPUFreq support" depends on ARCH_APPLE || (COMPILE_TEST && 64BIT)
drivers/cpufreq/Makefile +1 -0
@@ -52,6 +52,7 @@ obj-$(CONFIG_X86_AMD_FREQ_SENSITIVITY) += amd_freq_sensitivity.o ################################################################################## # ARM SoC drivers +obj-$(CONFIG_ARM_AIROHA_SOC_CPUFREQ) += airoha-cpufreq.o obj-$(CONFIG_ARM_APPLE_SOC_CPUFREQ) += apple-soc-cpufreq.o obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ) += armada-37xx-cpufreq.o obj-$(CONFIG_ARM_ARMADA_8K_CPUFREQ) += armada-8k-cpufreq.o
drivers/cpufreq/airoha-cpufreq.c new file +183 -0
183 lines not on this page · raw message
drivers/cpufreq/cpufreq-dt-platdev.c +2 -0
@@ -103,6 +103,8 @@ static const struct of_device_id allowlist[] __initconst = {* platforms using "operating-points-v2" property. */ static const struct of_device_id blocklist[]__initconst = { + { .compatible ="airoha,en7581" , }, + { .compatible ="allwinner,sun50i-h6" , }, { .compatible ="allwinner,sun50i-h616" , }, { .compatible ="allwinner,sun50i-h618" , },
Signature · 1 line
2.45.2
Quoted 10 lines · Christian Marangi
Add simple Cpufreq driver for Airoha EN7581 SoC that control CPU frequency scaling with SMC APIs.
All CPU share the same frequency and can't be controlled independently. Current shared CPU frequency is returned by the related SMC command.
Add SoC compatible to cpufreq-dt-plat block list as a dedicated cpufreq driver is needed with OPP v2 nodes declared in DTS.
Signed-off-by Christian Marangi <[email protected]>
Sorry to ask but any news with this?
Signature · 1 line
Ansuel
Viresh Kumar
maintainerQuoted 6 lines · Christian Marangi
Add simple Cpufreq driver for Airoha EN7581 SoC that control CPU frequency scaling with SMC APIs.
All CPU share the same frequency and can't be controlled independently. Current shared CPU frequency is returned by the related SMC command.
Quoted 8 lines
Add SoC compatible to cpufreq-dt-plat block list as a dedicated cpufreq driver is needed with OPP v2 nodes declared in DTS.
Signed-off-by Christian Marangi <[email protected]>---
Changes v2:
- Fix kernel bot error with missingslab.handbitfield.hheader
- LimitCOMPILE_TESTto ARM64 due to smcc 1.2
Hi,
Sorry for delay at my side to review this driver.
Now that I looked at it, I don't see a lot of special stuff happening in the driver. There are many other platforms with similar situation. What we have done for all them, which rely on OPPs coming from DT, is to add a clk for the CPUs and do all this magically smcc stuff from clk_get_rate() and clk_set_rate(). Once that is done, you should be able to reuse the cpufreq-dt driver as is.
So a CPU clk is the only missing thing in your case I guess.
Signature · 1 line
viresh
Quoted 20 lines · Viresh Kumar
Quoted 6 lines · Christian Marangi
Add simple Cpufreq driver for Airoha EN7581 SoC that control CPU frequency scaling with SMC APIs.
All CPU share the same frequency and can't be controlled independently. Current shared CPU frequency is returned by the related SMC command.
Quoted 8 lines
Add SoC compatible to cpufreq-dt-plat block list as a dedicated cpufreq driver is needed with OPP v2 nodes declared in DTS.
Signed-off-by Christian Marangi <[email protected]>---
Changes v2:
- Fix kernel bot error with missingslab.handbitfield.hheader
- LimitCOMPILE_TESTto ARM64 due to smcc 1.2Hi,
Sorry for delay at my side to review this driver.
Quoted 8 lines
Now that I looked at it, I don't see a lot of special stuff happening in the driver. There are many other platforms with similar situation. What we have done for all them, which rely on OPPs coming from DT, is to add a clk for the CPUs and do all this magically smcc stuff from
clk_get_rate()andclk_set_rate(). Once that is done, you should be able to reuse the cpufreq-dt driver as is.So a CPU clk is the only missing thing in your case I guess.
Hi Viresh,
thanks a lot for the follow-up. I will see what I can do, 2 main problem I see is that, contrary to other driver, for this Airoha SoC, there are no parents or no clock to enable... It's really just entirely handled by ATF and smccc call.
And also the SMCCC requires an index and not the clock itself. This was handy for a cpufreq driver as it passed the OPP index, problematic for a clock driver as set_rate pass the clock. So I guess I will have to define the OPP phandle also in the clock node struct. (and map it?)
The main problem in doing that is the performance hit on having to cycle every time the OPPs to find the correct index...
(yes they really implemented this thing with the ATF specifically with the cpufreq scenario in mind)
Wonder if you have any hint on any of this.
Signature · 1 line
Ansuel
Viresh Kumar
maintainerQuoted 32 lines · Christian Marangi
Quoted 20 lines · Viresh Kumar
Quoted 6 lines · Christian Marangi
Add simple Cpufreq driver for Airoha EN7581 SoC that control CPU frequency scaling with SMC APIs.
All CPU share the same frequency and can't be controlled independently. Current shared CPU frequency is returned by the related SMC command.
Quoted 8 lines
Add SoC compatible to cpufreq-dt-plat block list as a dedicated cpufreq driver is needed with OPP v2 nodes declared in DTS.
Signed-off-by Christian Marangi <[email protected]>---
Changes v2:
- Fix kernel bot error with missingslab.handbitfield.hheader
- LimitCOMPILE_TESTto ARM64 due to smcc 1.2Hi,
Sorry for delay at my side to review this driver.
Quoted 8 lines
Now that I looked at it, I don't see a lot of special stuff happening in the driver. There are many other platforms with similar situation. What we have done for all them, which rely on OPPs coming from DT, is to add a clk for the CPUs and do all this magically smcc stuff from
clk_get_rate()andclk_set_rate(). Once that is done, you should be able to reuse the cpufreq-dt driver as is.So a CPU clk is the only missing thing in your case I guess.
Hi Viresh,
Quoted 7 lines
thanks a lot for the follow-up. I will see what I can do, 2 main problem I see is that, contrary to other driver, for this Airoha SoC, there are no parents or no clock to enable... It's really just entirely handled by ATF and smccc call.
And also the SMCCC requires an index and not the clock itself. This was handy for a cpufreq driver as it passed the OPP index
Right, but the OPP table for the CPU must contain frequencies too, isn't it ? So you already have index to frequency conversion available ?
Can't you just add a clk driver for the CPU, which uses OPP core to parse the OPP table of the CPU and set a clk-index table in the clk driver ? So once the clk driver gets a request for a particular frequency, it just finds the respective index and sets it ?
Quoted 3 lines
problematic for a
clock driver asset_ratepass the clock. So I guess I will have to define the OPP phandle also in the clock node struct. (and map it?)
I am not suggesting a clk in DT, but just in code, added by a cpufreq driver for your platform, which at the end creates cpufreq-dt device. There are many which are creating the device on the fly, like tegra20-cpufreq.c.
Quoted 2 lines
The main problem in doing that is the performance hit on having to cycle every time the OPPs to find the correct index...
I think it would be traversing an array in the clk driver eventually and that won't be that bad ?
Quoted 2 lines
(yes they really implemented this thing with the ATF specifically with the cpufreq scenario in mind)
Signature · 1 line
viresh
Quoted 57 lines · Viresh Kumar
Quoted 32 lines · Christian Marangi
Quoted 20 lines · Viresh Kumar
Quoted 6 lines · Christian Marangi
Add simple Cpufreq driver for Airoha EN7581 SoC that control CPU frequency scaling with SMC APIs.
All CPU share the same frequency and can't be controlled independently. Current shared CPU frequency is returned by the related SMC command.
Quoted 8 lines
Add SoC compatible to cpufreq-dt-plat block list as a dedicated cpufreq driver is needed with OPP v2 nodes declared in DTS.
Signed-off-by Christian Marangi <[email protected]>---
Changes v2:
- Fix kernel bot error with missingslab.handbitfield.hheader
- LimitCOMPILE_TESTto ARM64 due to smcc 1.2Hi,
Sorry for delay at my side to review this driver.
Quoted 8 lines
Now that I looked at it, I don't see a lot of special stuff happening in the driver. There are many other platforms with similar situation. What we have done for all them, which rely on OPPs coming from DT, is to add a clk for the CPUs and do all this magically smcc stuff from
clk_get_rate()andclk_set_rate(). Once that is done, you should be able to reuse the cpufreq-dt driver as is.So a CPU clk is the only missing thing in your case I guess.
Hi Viresh,
Quoted 7 lines
thanks a lot for the follow-up. I will see what I can do, 2 main problem I see is that, contrary to other driver, for this Airoha SoC, there are no parents or no clock to enable... It's really just entirely handled by ATF and smccc call.
And also the SMCCC requires an index and not the clock itself. This was handy for a cpufreq driver as it passed the OPP index
Right, but the OPP table for the CPU must contain frequencies too, isn't it ? So you already have index to frequency conversion available ?
Can't you just add a clk driver for the CPU, which uses OPP core to parse the OPP table of the CPU and set a clk-index table in the clk driver ? So once the clk driver gets a request for a particular frequency, it just finds the respective index and sets it ?
Quoted 3 lines
problematic for a
clock driver asset_ratepass the clock. So I guess I will have to define the OPP phandle also in the clock node struct. (and map it?)I am not suggesting a clk in DT, but just in code, added by a cpufreq driver for your platform, which at the end creates cpufreq-dt device. There are many which are creating the device on the fly, like
tegra20-cpufreq.c.
Quoted 9 lines
Quoted 2 lines
The main problem in doing that is the performance hit on having to cycle every time the OPPs to find the correct index...
I think it would be traversing an array in the clk driver eventually and that won't be that bad ?
Quoted 2 lines
(yes they really implemented this thing with the ATF specifically with the cpufreq scenario in mind)
Hi Viresh,
sorry for the delay... I checked the example and other cpufreq driver that register a simple cpufreq-dt. None of the current driver implements a full clk provider internally and I have some fear it might be problematic to have mixed stuff, eventually I feel I should implement a small clk driver that implements determine_rate, set_rate, a compatible and all sort. And still we would have the double reference of OPP Index->Freq Clock->OPP index.
I wonder if a much easier and better solution for this is (similar to how we do with suspend and resume) add entry in the struct cpufreq_dt_platform_data, to permit to define simple .target_index and .get and overwrite the default one cpufreq-dt.
This permits to both reduce greatly the airoha-cpufreq driver, register a simple cpufreq-dt and prevent any kind of overhead. After all the .target_index and .get doesn't do anything fancy, they just call the OPP set and clk get rate.
What do you think? Changes are really trivial since this is already implemented for suspend and resume.
Signature · 1 line
Ansuel
Viresh Kumar
maintainerQuoted 3 lines · Christian Marangi
sorry for the delay... I checked the example and other cpufreq driver that register a simple cpufreq-dt. None of the current driver implements a full clk provider internally
Yeah, that may be done from platform code for those drivers instead of the cpufreq driver.
Quoted 5 lines
and I have some fear it might be
problematic to have mixed stuff, eventually I feel I should implement a small clk driver that implementsdetermine_rate,set_rate, a compatible and all sort. And still we would have the double reference of OPPIndex->FreqClock->OPPindex.
One way to avoid that would be to use performance-state stuff and model this as a genpd. In that case, opp->level field (which you can set as index only in your case) will be programmed as is by the genpd core. That's why I cc'd Ulf earlier as it looked more suited to your case.
Quoted 4 lines
I wonder if a much easier and better solution for this is (similar to how we do with suspend and resume) add entry in the struct
cpufreq_dt_platform_data, to permit to define simple .target_index and .get and overwrite the default one cpufreq-dt.
Easier, sure. Better, I doubt that :(
The OPP core currently configures a lot of stuff from set-opp API, like clk, regulators, genpd (performance state), bandwidth, etc and I really want to use that infrastructure for everyone instead of starting to open code that in drivers. The suspend/resume callbacks are special as the OPP core doesn't know what to do in that case and so it was left for the drivers to handle that.
Quoted 4 lines
This permits to both reduce greatly the airoha-cpufreq driver, register a simple cpufreq-dt and prevent any kind of overhead. After all the .target_index and .get doesn't do anything fancy, they just call the OPP set and clk get rate.
Yeah, clk-get is pretty simple but opp-set isn't and then there is scope of further enhancements / improvements in the future which can be best handled if we keep that code common for everyone.
Quoted 2 lines
What do you think? Changes are really trivial since this is already implemented for suspend and resume.
I think you can model it as a performance state (which lot of platforms are doing as well), and then you won't have the index->clk->index issue anymore.
Signature · 1 line
viresh
Quoted 14 lines · Viresh Kumar
Quoted 3 lines · Christian Marangi
sorry for the delay... I checked the example and other cpufreq driver that register a simple cpufreq-dt. None of the current driver implements a full clk provider internally
Yeah, that may be done from platform code for those drivers instead of the cpufreq driver.
Quoted 5 lines
and I have some fear it might be
problematic to have mixed stuff, eventually I feel I should implement a small clk driver that implementsdetermine_rate,set_rate, a compatible and all sort. And still we would have the double reference of OPPIndex->FreqClock->OPPindex.
Quoted 5 lines
One way to avoid that would be to use performance-state stuff and model this as a genpd. In that case,
opp->levelfield (which you can set as index only in your case) will be programmed as is by the genpd core. That's why I cc'd Ulf earlier as it looked more suited to your case.
Hi I just sent v4 that exactly implement that. It was hard but at the end I manage to make use of it :D
Quoted 5 lines
Quoted 4 lines
I wonder if a much easier and better solution for this is (similar to how we do with suspend and resume) add entry in the struct
cpufreq_dt_platform_data, to permit to define simple .target_index and .get and overwrite the default one cpufreq-dt.
Quoted 8 lines
Easier, sure. Better, I doubt that :(
The OPP core currently configures a lot of stuff from set-opp API, like clk, regulators, genpd (performance state), bandwidth, etc and I really want to use that infrastructure for everyone instead of starting to open code that in drivers. The suspend/resume callbacks are special as the OPP core doesn't know what to do in that case and so it was left for the drivers to handle that.
Yep, totally understandable and i can see the problem in open coding it. Easier fort devs but leaves space for random implementation that can be implemented with OPP and PD
Quoted 9 lines
Quoted 4 lines
This permits to both reduce greatly the airoha-cpufreq driver, register a simple cpufreq-dt and prevent any kind of overhead. After all the .target_index and .get doesn't do anything fancy, they just call the OPP set and clk get rate.
Yeah, clk-get is pretty simple but opp-set isn't and then there is scope of further enhancements / improvements in the future which can be best handled if we keep that code common for everyone.
Quoted 6 lines
Quoted 2 lines
What do you think? Changes are really trivial since this is already implemented for suspend and resume.
I think you can model it as a performance state (which lot of platforms are doing as well), and then you won't have the
index->clk->indexissue anymore.
Hope you can check v4 if everything is OK. A dedicated node was required for the clk provider and the PD provider but that is O.K. if that means transparent handling for cpufreq-dt.
Thanks a lot on the hint on how to correctly implement this!
Signature · 1 line
Ansuel