mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-09 21:22:39 -05:00
imx233: add function to change cpu/hbus frequency safely
Change-Id: I88e9ad54ba65846ae4d94ae03009b3656f2489f2
This commit is contained in:
parent
3e2f3efd89
commit
1f3979821c
2 changed files with 34 additions and 0 deletions
|
|
@ -189,6 +189,38 @@ bool imx233_clkctrl_get_bypass(enum imx233_clock_t clk)
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void imx233_clkctrl_set_cpu_hbus_div(int cpu_idiv, int cpu_fdiv, int hbus_div)
|
||||||
|
{
|
||||||
|
/* disable interrupts to avoid an IRQ being triggered at the point
|
||||||
|
* where we are slow/weird speeds, that would result in massive slow-down... */
|
||||||
|
int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS);
|
||||||
|
/* we need to be very careful here: putting the wrong dividers could blow-up the
|
||||||
|
* frequency and result in crash, also the cpu could be running from XTAL or
|
||||||
|
* PLL at this point */
|
||||||
|
int old_cpu_fdiv = imx233_clkctrl_get_frac_div(CLK_CPU);
|
||||||
|
int old_hbus_div = imx233_clkctrl_get_div(CLK_HBUS);
|
||||||
|
/* since HBUS is tied to cpu, we first ensure that the HBUS is safe to handle
|
||||||
|
* both old and new speed: take maximum of old and new dividers */
|
||||||
|
if(hbus_div > old_hbus_div)
|
||||||
|
imx233_clkctrl_set_div(CLK_HBUS, hbus_div);
|
||||||
|
/* we are about to change cpu speed: we first ensure that the fractional
|
||||||
|
* divider is safe to handle both old and new integer divided frequency: take max */
|
||||||
|
if(cpu_fdiv > old_cpu_fdiv)
|
||||||
|
imx233_clkctrl_set_frac_div(CLK_CPU, cpu_fdiv);
|
||||||
|
/* we are safe for major divider change */
|
||||||
|
imx233_clkctrl_set_div(CLK_CPU, cpu_idiv);
|
||||||
|
/* if the final fractional divider is lower than previous one, it's time to switch */
|
||||||
|
if(cpu_fdiv < old_cpu_fdiv)
|
||||||
|
imx233_clkctrl_set_frac_div(CLK_CPU, cpu_fdiv);
|
||||||
|
/* if we were running from XTAL, switch to PLL */
|
||||||
|
imx233_clkctrl_set_bypass(CLK_CPU, false);
|
||||||
|
/* finally restore HBUS to its proper value */
|
||||||
|
if(hbus_div < old_hbus_div)
|
||||||
|
imx233_clkctrl_set_div(CLK_HBUS, hbus_div);
|
||||||
|
/* we are free again */
|
||||||
|
restore_interrupt(oldstatus);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void imx233_clkctrl_enable_usb(bool enable)
|
void imx233_clkctrl_enable_usb(bool enable)
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,8 @@ void imx233_clkctrl_set_frac_div(enum imx233_clock_t clk, int fracdiv);
|
||||||
int imx233_clkctrl_get_frac_div(enum imx233_clock_t clk);
|
int imx233_clkctrl_get_frac_div(enum imx233_clock_t clk);
|
||||||
void imx233_clkctrl_set_bypass(enum imx233_clock_t clk, bool bypass);
|
void imx233_clkctrl_set_bypass(enum imx233_clock_t clk, bool bypass);
|
||||||
bool imx233_clkctrl_get_bypass(enum imx233_clock_t clk);
|
bool imx233_clkctrl_get_bypass(enum imx233_clock_t clk);
|
||||||
|
/* all-in-one function which handle all quirks */
|
||||||
|
void imx233_clkctrl_set_cpu_hbus_div(int cpu_idiv, int cpu_fdiv, int hbus_div);
|
||||||
#endif
|
#endif
|
||||||
void imx233_clkctrl_enable_usb(bool enable);
|
void imx233_clkctrl_enable_usb(bool enable);
|
||||||
bool imx233_clkctrl_is_usb_enabled(void);
|
bool imx233_clkctrl_is_usb_enabled(void);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue