void system_init(void) { /* NOTE: don't use anything here that might require tick task ! * It is initialized by kernel_init *after* system_init(). * The main() will naturally set cpu speed to normal after kernel_init() * so don't bother if the cpu is running at 24MHz here. * Make sure IO clock is running at expected speed */ imx233_clkctrl_init(); imx233_clkctrl_enable(CLK_PLL, true); #if IMX233_SUBTARGET >= 3700 imx233_clkctrl_set_frac_div(CLK_IO, 18); // clk_io@clk_pll #endif imx233_rtc_init(); imx233_icoll_init(); imx233_pinctrl_init(); imx233_timrot_init(); imx233_dma_init(); imx233_ssp_init(); #if IMX233_SUBTARGET >= 3700 imx233_dcp_init(); #endif imx233_pwm_init(); imx233_lradc_init(); imx233_power_init(); imx233_i2c_init(); imx233_powermgmt_init(); /* setup watchdog */ watchdog_init(); /* make sure auto-slow is disable now, we don't know at which frequency we * are running and auto-slow could violate constraints on {xbus,hbus} */ imx233_clkctrl_enable_auto_slow(false); imx233_clkctrl_set_auto_slow_div(BV_CLKCTRL_HBUS_SLOW_DIV__BY8); cpu_frequency = imx233_clkctrl_get_freq(CLK_CPU); #if !defined(BOOTLOADER) && CONFIG_TUNER != 0 fmradio_i2c_init(); #endif }
void imx233_set_cpu_frequency(long frequency) { #if IMX233_SUBTARGET >= 3780 /* don't change the frequency if it is useless (changes are expensive) */ if(cpu_frequency == frequency) return; struct cpufreq_profile_t *prof = cpu_profiles; while(prof->cpu_freq != 0 && prof->cpu_freq != frequency) prof++; if(prof->cpu_freq == 0) return; /* disable auto-slow (enable back afterwards) */ imx233_clkctrl_enable_auto_slow(false); /* set VDDIO to the right value */ imx233_power_set_regulator(REGULATOR_VDDIO, 3300, 3125); /* WARNING watch out the order ! */ if(frequency > cpu_frequency) { /* Change VDDD regulator */ imx233_power_set_regulator(REGULATOR_VDDD, prof->vddd, prof->vddd_bo); /* Change ARM cache timings */ imx233_digctl_set_arm_cache_timings(prof->arm_cache_timings); /* Switch CPU to crystal at 24MHz */ imx233_clkctrl_set_bypass(CLK_CPU, true); /* Program CPU divider for PLL */ imx233_clkctrl_set_frac_div(CLK_CPU, prof->cpu_fdiv); imx233_clkctrl_set_div(CLK_CPU, prof->cpu_idiv); /* Change the HBUS divider to its final value */ imx233_clkctrl_set_div(CLK_HBUS, prof->hbus_div); /* Switch back CPU to PLL */ imx233_clkctrl_set_bypass(CLK_CPU, false); /* Set the new EMI frequency */ imx233_emi_set_frequency(prof->emi_freq); } else { /* Switch CPU to crystal at 24MHz */ imx233_clkctrl_set_bypass(CLK_CPU, true); /* Program HBUS divider to its final value */ imx233_clkctrl_set_div(CLK_HBUS, prof->hbus_div); /* Program CPU divider for PLL */ imx233_clkctrl_set_frac_div(CLK_CPU, prof->cpu_fdiv); imx233_clkctrl_set_div(CLK_CPU, prof->cpu_idiv); /* Switch back CPU to PLL */ imx233_clkctrl_set_bypass(CLK_CPU, false); /* Set the new EMI frequency */ imx233_emi_set_frequency(prof->emi_freq); /* Change ARM cache timings */ imx233_digctl_set_arm_cache_timings(prof->arm_cache_timings); /* Change VDDD regulator */ imx233_power_set_regulator(REGULATOR_VDDD, prof->vddd, prof->vddd_bo); } /* enable auto slow again */ imx233_clkctrl_enable_auto_slow(true); /* update frequency */ cpu_frequency = frequency; #else (void) frequency; #endif }