diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-11-03 09:42:11 -0500 |
---|---|---|
committer | Ben Dooks <ben-linux@fluff.org> | 2009-11-30 20:35:38 -0500 |
commit | 43f1069ef9af9a0b1fa1a1d6b49b2b05e1efc998 (patch) | |
tree | ac36835c0e6b0bfb0264fe7f62dfbf272179def0 /arch | |
parent | 383af9c2586e0c51e27ed4f186a2f23f8e889054 (diff) |
ARM: S3C64XX: Separate out regulator and frequency latencies
Currently the transition latency reported by the S3C64xx cpufreq
driver includes both the time for the CPU to reclock itself and
the time for a regulator to change voltage. This means that if
a regulator is not in use then the transition latency reported
is excessively high.
In future the regulator API will be extended to report latencies
so the driver will be able to query the performance of a given
regulator.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/plat-s3c64xx/cpufreq.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/arch/arm/plat-s3c64xx/cpufreq.c b/arch/arm/plat-s3c64xx/cpufreq.c index bdc3c96971f5..61276bf73927 100644 --- a/arch/arm/plat-s3c64xx/cpufreq.c +++ b/arch/arm/plat-s3c64xx/cpufreq.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | static struct clk *armclk; | 20 | static struct clk *armclk; |
21 | static struct regulator *vddarm; | 21 | static struct regulator *vddarm; |
22 | static unsigned long regulator_latency; | ||
22 | 23 | ||
23 | #ifdef CONFIG_CPU_S3C6410 | 24 | #ifdef CONFIG_CPU_S3C6410 |
24 | struct s3c64xx_dvfs { | 25 | struct s3c64xx_dvfs { |
@@ -141,7 +142,7 @@ err: | |||
141 | } | 142 | } |
142 | 143 | ||
143 | #ifdef CONFIG_REGULATOR | 144 | #ifdef CONFIG_REGULATOR |
144 | static void __init s3c64xx_cpufreq_constrain_voltages(void) | 145 | static void __init s3c64xx_cpufreq_config_regulator(void) |
145 | { | 146 | { |
146 | int count, v, i, found; | 147 | int count, v, i, found; |
147 | struct cpufreq_frequency_table *freq; | 148 | struct cpufreq_frequency_table *freq; |
@@ -150,11 +151,10 @@ static void __init s3c64xx_cpufreq_constrain_voltages(void) | |||
150 | count = regulator_count_voltages(vddarm); | 151 | count = regulator_count_voltages(vddarm); |
151 | if (count < 0) { | 152 | if (count < 0) { |
152 | pr_err("cpufreq: Unable to check supported voltages\n"); | 153 | pr_err("cpufreq: Unable to check supported voltages\n"); |
153 | return; | ||
154 | } | 154 | } |
155 | 155 | ||
156 | freq = s3c64xx_freq_table; | 156 | freq = s3c64xx_freq_table; |
157 | while (freq->frequency != CPUFREQ_TABLE_END) { | 157 | while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) { |
158 | if (freq->frequency == CPUFREQ_ENTRY_INVALID) | 158 | if (freq->frequency == CPUFREQ_ENTRY_INVALID) |
159 | continue; | 159 | continue; |
160 | 160 | ||
@@ -175,6 +175,10 @@ static void __init s3c64xx_cpufreq_constrain_voltages(void) | |||
175 | 175 | ||
176 | freq++; | 176 | freq++; |
177 | } | 177 | } |
178 | |||
179 | /* Guess based on having to do an I2C/SPI write; in future we | ||
180 | * will be able to query the regulator performance here. */ | ||
181 | regulator_latency = 1 * 1000 * 1000; | ||
178 | } | 182 | } |
179 | #endif | 183 | #endif |
180 | 184 | ||
@@ -206,7 +210,7 @@ static int __init s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
206 | pr_err("cpufreq: Only frequency scaling available\n"); | 210 | pr_err("cpufreq: Only frequency scaling available\n"); |
207 | vddarm = NULL; | 211 | vddarm = NULL; |
208 | } else { | 212 | } else { |
209 | s3c64xx_cpufreq_constrain_voltages(); | 213 | s3c64xx_cpufreq_config_regulator(); |
210 | } | 214 | } |
211 | #endif | 215 | #endif |
212 | 216 | ||
@@ -233,9 +237,11 @@ static int __init s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
233 | 237 | ||
234 | policy->cur = clk_get_rate(armclk) / 1000; | 238 | policy->cur = clk_get_rate(armclk) / 1000; |
235 | 239 | ||
236 | /* Pick a conservative guess in ns: we'll need ~1 I2C/SPI | 240 | /* Datasheet says PLL stabalisation time (if we were to use |
237 | * write plus clock reprogramming. */ | 241 | * the PLLs, which we don't currently) is ~300us worst case, |
238 | policy->cpuinfo.transition_latency = 2 * 1000 * 1000; | 242 | * but add some fudge. |
243 | */ | ||
244 | policy->cpuinfo.transition_latency = (500 * 1000) + regulator_latency; | ||
239 | 245 | ||
240 | ret = cpufreq_frequency_table_cpuinfo(policy, s3c64xx_freq_table); | 246 | ret = cpufreq_frequency_table_cpuinfo(policy, s3c64xx_freq_table); |
241 | if (ret != 0) { | 247 | if (ret != 0) { |