cpufreq: Add S3C2416/S3C2450 cpufreq driver
Subsystems (2)
RFC 1/1 cpufreq: Add S3C2416/S3C2450 cpufreq driver
The S3C2416/S3C2450 SoCs support two sources for the armclk.
The first source is the so called armdiv which divides the msysclk down to provide necessary cpu rates. In this mode the core voltage must be always at 1.3V. The frequency from the armdiv is not allowed to be lower than the hclk frequency.
In the second mode the armclk can be fed directly from the hclk in the so called "dynamic voltags scaling" (dvs) mode. Here the armdiv isn't used at all. Also in this mode the core voltage may be lowered. Existing hardware and tests with it suggest 1.0V as sufficient.
When changing the clock source to the armdiv from the hclk, the SoC shows stability issues if the new frequency is higher as the current hclk frequency. Hence the driver always forces the armdiv to the hclk frequency before the source change and lets the cpufreq issue another set_target call for higher frequencies.
To mark the hclk frequency as lower as the corresponding armdiv frequency it is set 1MHz below the real frequency. This lets the cpufreq framework change between 133MHz based on hclk and 133MHz based on armdiv at will.
---
As the title says, this is only a RFC and I'd like to solicit comments for the driver in general and also on the handling of the dvs mode. I don't know if there are better ways to handle switching back and forth between the regular clock and the same frequency using the dvs mode than by the software-only 1MHz difference I'm currently using.
drivers/cpufreq/Kconfig.arm | 21 ++ drivers/cpufreq/Makefile | 1 + drivers/cpufreq/s3c2416-cpufreq.c | 501 +++++++++++++++++++++++++++++++++++++ 3 files changed, 523 insertions(+), 0 deletions(-) create mode 100644 drivers/cpufreq/s3c2416-cpufreq.c
drivers/cpufreq/Kconfig.arm +21 -0
@@ -2,6 +2,27 @@ # ARM CPU Frequency scaling drivers # +config ARM_S3C2416_CPUFREQ + bool "S3C2416 CPU Frequency scaling support" + help + This adds the CPUFreq driver for the Samsung S3C2416 and + S3C2450 SoC. The S3C2416 supports changing the rate of the + armdiv clock source and also entering a so called dynamic + voltage scaling mode in which it is possible to reduce the + core voltage of the cpu. + + If in doubt, say N. + +config ARM_S3C2416_CPUFREQ_VCORESCALE + bool "Allow voltage scaling for S3C2416 arm core (DANGEROUS)" + depends on ARM_S3C2416_CPUFREQ && REGULATOR + help + Enable CPU voltage scaling when entering the dvs mode. + It uses information gathered through existing hardware and + tests but not documented in any datasheet. + + If in doubt, say N. + config ARM_S3C64XX_CPUFREQ bool "Samsung S3C64XX" depends on CPU_S3C6410
drivers/cpufreq/Makefile +1 -0
@@ -40,6 +40,7 @@ obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o ################################################################################## # ARM SoC drivers obj-$(CONFIG_UX500_SOC_DB8500) += db8500-cpufreq.o +obj-$(CONFIG_ARM_S3C2416_CPUFREQ) += s3c2416-cpufreq.o obj-$(CONFIG_ARM_S3C64XX_CPUFREQ) += s3c64xx-cpufreq.o obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ) += exynos4210-cpufreq.o
drivers/cpufreq/s3c2416-cpufreq.c new file +501 -0
501 lines not on this page · raw message
Signature · 1 line
1.7.2.3
Hi.
On Thu, Dec 29, 2011 at 11:58 PM, Heiko Stübner <[email protected]> wrote:
...
Quoted 1 line
+static int
__inits3c2416_cpufreq_driver_init(struct cpufreq_policy *policy)
...
Quoted 5 lines
+
s3c_freq->armdiv=clk_get(NULL, "armdiv");
+ if (IS_ERR(s3c_freq->armdiv)) {
+ pr_err("cpufreq: Unable to obtain ARMDIV: %ld\n",
+ PTR_ERR(s3c_freq->armdiv));
+ returnPTR_ERR(s3c_freq->armdiv);
Quoted 8 lines
+ }
+
+s3c_freq->hclk=clk_get(NULL, "hclk");
+ if (IS_ERR(s3c_freq->hclk)) {
+ pr_warn("cpufreq: Unable to obtain HCLK: %ld\n",
+ PTR_ERR(s3c_freq->hclk));
+s3c_freq->hclk= NULL; /*we can live without hclk */
+ }
clk_put allready obtained "armdiv"?
Quoted 7 lines
+
+s3c_freq->armclk=clk_get(NULL, "armclk");
+ if (IS_ERR(s3c_freq->armclk)) {
+ pr_err("cpufreq: Unable to obtain ARMCLK: %ld\n",
+ PTR_ERR(s3c_freq->armclk));
+ returnPTR_ERR(s3c_freq->armclk);
+ }
Same for "hclk" and "armclk"?
Am Freitag 30 Dezember 2011, 08:48:30 schrieb Dron Gus:
Quoted 34 lines
Hi.
On Thu, Dec 29, 2011 at 11:58 PM, Heiko Stübner <[email protected]> wrote:
...Quoted 2 lines
+static int
__inits3c2416_cpufreq_driver_init(struct cpufreq_policy *policy)...
drivers/cpufreq/s3c2416-cpufreq.c line 386
Quoted 13 lines
drivers/cpufreq/s3c2416-cpufreq.c new file +13
-0+ s3c_freq->armdiv =clk_get (NULL ,"armdiv" ); +if (IS_ERR (s3c_freq->armdiv)) { +pr_err ("cpufreq: Unable to obtain ARMDIV: %ld\n" , +PTR_ERR (s3c_freq->armdiv)); +return PTR_ERR (s3c_freq->armdiv); + } + + s3c_freq->hclk =clk_get (NULL ,"hclk" ); +if (IS_ERR (s3c_freq->hclk)) { +pr_warn ("cpufreq: Unable to obtain HCLK: %ld\n" , +PTR_ERR (s3c_freq->hclk)); + s3c_freq->hclk =NULL ;/*we can live without hclk */ + }
clk_putallready obtained "armdiv"?drivers/cpufreq/s3c2416-cpufreq.c line 393
Quoted 7 lines
drivers/cpufreq/s3c2416-cpufreq.c new file +7
-0+ + s3c_freq->armclk =clk_get (NULL ,"armclk" ); +if (IS_ERR (s3c_freq->armclk)) { +pr_err ("cpufreq: Unable to obtain ARMCLK: %ld\n" , +PTR_ERR (s3c_freq->armclk)); +return PTR_ERR (s3c_freq->armclk); + }
Quoted 1 line
Same for "hclk" and "armclk"?
thanks for finding those, it seems probe also needs a lot more love.
As you were also working on S3C2416 stuff, could you possibly test the driver and see if it still hangs for you?
After I introduced the switch from hclk to armdiv using a forced armdiv=hclk frequency the hangs stopped for me and the devices ran hours with varying workloads without hangs. (also including voltage scaling)
Heiko
would it be possible to use clk-reg-cpufreq driver I sent out?
Thanks
Richard
Hi Richard,
Am Freitag 30 Dezember 2011, 09:23:21 schrieb Richard Zhao:
Quoted 1 line
would it be possible to use clk-reg-cpufreq driver I sent out?
I thought about it when your driver was introduced first. It would be possible if the frequency scaling would only happen on the armdiv.
But as you probably saw in the code the S3C2416 has two clock sources for the armclk (armdiv and hclk) and also special requirements on the switch of those (i.e. when switching to armdiv, force the frequency to be the same as the hclk, to prevent stability issues).
Therefore I don't think these behaviour requirements can be modelled with your clk-reg-cpufreq driver.
Heiko