diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2012-12-26 01:12:24 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2012-12-26 01:17:28 +0100 |
commit | 09e6b890e64312f1d11d2e529d405b4df615b3bd (patch) | |
tree | bcdf6e2c405e52fc2bdc6ca56c3d4a02da668c73 /firmware | |
parent | e2da3f47d335dad87362354c36ea7e27bc26676b (diff) | |
download | rockbox-09e6b890e64312f1d11d2e529d405b4df615b3bd.tar.gz rockbox-09e6b890e64312f1d11d2e529d405b4df615b3bd.zip |
imx233: rework cpu frequency scaling
When changing the cpu frequency, it is important to make sure that
HBUS stays at a reasonable frequency otherwise the chip will
crash. Special care is needed about auto-slow and clk_p/clk_h
ratio on intermediate steps.
Change-Id: Ief9f68ddf286caabe75c879718dac5027ab1560f
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/arm/imx233/system-imx233.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/firmware/target/arm/imx233/system-imx233.c b/firmware/target/arm/imx233/system-imx233.c index 8d34562f9f..6dde16d863 100644 --- a/firmware/target/arm/imx233/system-imx233.c +++ b/firmware/target/arm/imx233/system-imx233.c | |||
@@ -158,16 +158,31 @@ void udelay(unsigned us) | |||
158 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 158 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
159 | void set_cpu_frequency(long frequency) | 159 | void set_cpu_frequency(long frequency) |
160 | { | 160 | { |
161 | (void) frequency; | 161 | /* don't change the frequency if it is useless (changes are expensive) */ |
162 | if(cpu_frequency == frequency) | ||
163 | return; | ||
164 | |||
165 | cpu_frequency = frequency; | ||
166 | /* disable auto-slow (enable back afterwards) */ | ||
167 | imx233_clkctrl_enable_auto_slow(false); | ||
168 | /* go back to a known state in safe way: | ||
169 | * clk_p@24 MHz | ||
170 | * clk_h@6 MHz | ||
171 | * WARNING: we must absolutely avoid that clk_h be too low or too high | ||
172 | * during the change. We first change the clk_p/clk_h ratio to 4 so | ||
173 | * that it cannot be too high (480/4=120 MHz max) or too low | ||
174 | * (24/4=6 MHz min). Then we switch clk_p to bypass. We chose a ratio of 4 | ||
175 | * which is greater than all clk_p/clk_h ratios used below so that further | ||
176 | * changes are safe too */ | ||
177 | imx233_clkctrl_set_clock_divisor(CLK_HBUS, 4); | ||
178 | imx233_clkctrl_set_bypass_pll(CLK_CPU, true); | ||
179 | |||
162 | switch(frequency) | 180 | switch(frequency) |
163 | { | 181 | { |
164 | case IMX233_CPUFREQ_454_MHz: | 182 | case IMX233_CPUFREQ_454_MHz: |
165 | /* go back to a known state: everything at 24MHz ! */ | ||
166 | imx233_clkctrl_set_bypass_pll(CLK_CPU, true); | ||
167 | imx233_clkctrl_set_clock_divisor(CLK_HBUS, 1); | ||
168 | /* set VDDD to 1.550 mV (brownout at 1.450 mV) */ | 183 | /* set VDDD to 1.550 mV (brownout at 1.450 mV) */ |
169 | imx233_power_set_regulator(REGULATOR_VDDD, 1550, 1450); | 184 | imx233_power_set_regulator(REGULATOR_VDDD, 1550, 1450); |
170 | /* clk_h@clk_p/2 */ | 185 | /* clk_h@clk_p/3 */ |
171 | imx233_clkctrl_set_clock_divisor(CLK_HBUS, 3); | 186 | imx233_clkctrl_set_clock_divisor(CLK_HBUS, 3); |
172 | /* clk_p@ref_cpu/1*18/19 */ | 187 | /* clk_p@ref_cpu/1*18/19 */ |
173 | imx233_clkctrl_set_fractional_divisor(CLK_CPU, 19); | 188 | imx233_clkctrl_set_fractional_divisor(CLK_CPU, 19); |
@@ -180,9 +195,6 @@ void set_cpu_frequency(long frequency) | |||
180 | * clk_h@130.91 MHz */ | 195 | * clk_h@130.91 MHz */ |
181 | break; | 196 | break; |
182 | case IMX233_CPUFREQ_261_MHz: | 197 | case IMX233_CPUFREQ_261_MHz: |
183 | /* go back to a known state: everything at 24MHz ! */ | ||
184 | imx233_clkctrl_set_bypass_pll(CLK_CPU, true); | ||
185 | imx233_clkctrl_set_clock_divisor(CLK_HBUS, 1); | ||
186 | /* set VDDD to 1.275 mV (brownout at 1.175 mV) */ | 198 | /* set VDDD to 1.275 mV (brownout at 1.175 mV) */ |
187 | imx233_power_set_regulator(REGULATOR_VDDD, 1275, 1175); | 199 | imx233_power_set_regulator(REGULATOR_VDDD, 1275, 1175); |
188 | /* clk_h@clk_p/2 */ | 200 | /* clk_h@clk_p/2 */ |
@@ -200,6 +212,9 @@ void set_cpu_frequency(long frequency) | |||
200 | default: | 212 | default: |
201 | break; | 213 | break; |
202 | } | 214 | } |
215 | |||
216 | /* enable auto slow again */ | ||
217 | imx233_clkctrl_enable_auto_slow(true); | ||
203 | } | 218 | } |
204 | #endif | 219 | #endif |
205 | 220 | ||