forked from len0rd/rockbox
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
This commit is contained in:
parent
e2da3f47d3
commit
09e6b890e6
1 changed files with 23 additions and 8 deletions
|
@ -158,16 +158,31 @@ void udelay(unsigned us)
|
||||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||||
void set_cpu_frequency(long frequency)
|
void set_cpu_frequency(long frequency)
|
||||||
{
|
{
|
||||||
(void) frequency;
|
/* don't change the frequency if it is useless (changes are expensive) */
|
||||||
|
if(cpu_frequency == frequency)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cpu_frequency = frequency;
|
||||||
|
/* disable auto-slow (enable back afterwards) */
|
||||||
|
imx233_clkctrl_enable_auto_slow(false);
|
||||||
|
/* go back to a known state in safe way:
|
||||||
|
* clk_p@24 MHz
|
||||||
|
* clk_h@6 MHz
|
||||||
|
* WARNING: we must absolutely avoid that clk_h be too low or too high
|
||||||
|
* during the change. We first change the clk_p/clk_h ratio to 4 so
|
||||||
|
* that it cannot be too high (480/4=120 MHz max) or too low
|
||||||
|
* (24/4=6 MHz min). Then we switch clk_p to bypass. We chose a ratio of 4
|
||||||
|
* which is greater than all clk_p/clk_h ratios used below so that further
|
||||||
|
* changes are safe too */
|
||||||
|
imx233_clkctrl_set_clock_divisor(CLK_HBUS, 4);
|
||||||
|
imx233_clkctrl_set_bypass_pll(CLK_CPU, true);
|
||||||
|
|
||||||
switch(frequency)
|
switch(frequency)
|
||||||
{
|
{
|
||||||
case IMX233_CPUFREQ_454_MHz:
|
case IMX233_CPUFREQ_454_MHz:
|
||||||
/* go back to a known state: everything at 24MHz ! */
|
|
||||||
imx233_clkctrl_set_bypass_pll(CLK_CPU, true);
|
|
||||||
imx233_clkctrl_set_clock_divisor(CLK_HBUS, 1);
|
|
||||||
/* set VDDD to 1.550 mV (brownout at 1.450 mV) */
|
/* set VDDD to 1.550 mV (brownout at 1.450 mV) */
|
||||||
imx233_power_set_regulator(REGULATOR_VDDD, 1550, 1450);
|
imx233_power_set_regulator(REGULATOR_VDDD, 1550, 1450);
|
||||||
/* clk_h@clk_p/2 */
|
/* clk_h@clk_p/3 */
|
||||||
imx233_clkctrl_set_clock_divisor(CLK_HBUS, 3);
|
imx233_clkctrl_set_clock_divisor(CLK_HBUS, 3);
|
||||||
/* clk_p@ref_cpu/1*18/19 */
|
/* clk_p@ref_cpu/1*18/19 */
|
||||||
imx233_clkctrl_set_fractional_divisor(CLK_CPU, 19);
|
imx233_clkctrl_set_fractional_divisor(CLK_CPU, 19);
|
||||||
|
@ -180,9 +195,6 @@ void set_cpu_frequency(long frequency)
|
||||||
* clk_h@130.91 MHz */
|
* clk_h@130.91 MHz */
|
||||||
break;
|
break;
|
||||||
case IMX233_CPUFREQ_261_MHz:
|
case IMX233_CPUFREQ_261_MHz:
|
||||||
/* go back to a known state: everything at 24MHz ! */
|
|
||||||
imx233_clkctrl_set_bypass_pll(CLK_CPU, true);
|
|
||||||
imx233_clkctrl_set_clock_divisor(CLK_HBUS, 1);
|
|
||||||
/* set VDDD to 1.275 mV (brownout at 1.175 mV) */
|
/* set VDDD to 1.275 mV (brownout at 1.175 mV) */
|
||||||
imx233_power_set_regulator(REGULATOR_VDDD, 1275, 1175);
|
imx233_power_set_regulator(REGULATOR_VDDD, 1275, 1175);
|
||||||
/* clk_h@clk_p/2 */
|
/* clk_h@clk_p/2 */
|
||||||
|
@ -200,6 +212,9 @@ void set_cpu_frequency(long frequency)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* enable auto slow again */
|
||||||
|
imx233_clkctrl_enable_auto_slow(true);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue