00001 00038 #include <assert.h> 00039 #include <clk/sys.h> 00040 #include <clk/osc.h> 00041 #include <regs/xmega_clk.h> 00042 00043 #ifdef CONFIG_PLL0_SOURCE 00044 static void sysclk_init_pll(void) 00045 { 00046 struct pll_config pllcfg; 00047 00048 switch (CONFIG_PLL0_SOURCE) { 00049 case PLL_SRC_RC2MHZ: 00050 break; 00051 case PLL_SRC_RC32MHZ: 00052 osc_enable(OSC_ID_RC32M); 00053 do { } while (!osc_is_running(OSC_ID_RC32M)); 00054 break; 00055 case PLL_SRC_XOSC: 00056 osc_enable(OSC_ID_XOSC); 00057 do { } while (!osc_is_running(OSC_ID_XOSC)); 00058 break; 00059 default: 00060 unhandled_case(CONFIG_PLL0_SOURCE); 00061 break; 00062 } 00063 00064 pll_config_defaults(&pllcfg, 0); 00065 pll_enable(&pllcfg, 0); 00066 pll_wait_for_lock(0); 00067 } 00068 #endif 00069 00070 void sysclk_init(void) 00071 { 00072 unsigned int i; 00073 00074 build_assert(CONFIG_SYSCLK_SOURCE <= SYSCLK_SRC_PLL); 00075 build_assert(CONFIG_SYSCLK_PSADIV <= XMEGA_CLK_PSADIV_512); 00076 build_assert((CONFIG_SYSCLK_PSADIV & 0x01) 00077 || (CONFIG_SYSCLK_PSADIV == 0)); 00078 build_assert(CONFIG_SYSCLK_PSBCDIV <= XMEGA_CLK_PSBCDIV_2_2); 00079 00080 /* Turn off all peripheral clocks that can be turned off */ 00081 for (i = 0; i <= XMEGA_PR_PRPF; i++) 00082 mmio_write8((void *)(PR_BASE + i), 0xff); 00083 00084 /* Set up system clock prescalers if different from defaults */ 00085 if (CONFIG_SYSCLK_PSADIV != XMEGA_CLK_PSADIV_1 00086 || CONFIG_SYSCLK_PSBCDIV != XMEGA_CLK_PSBCDIV_1_1) { 00087 clk_write_ccp_reg(PSCTRL, CLK_BF(PSADIV, CONFIG_SYSCLK_PSADIV) 00088 | CLK_BF(PSBCDIV, CONFIG_SYSCLK_PSBCDIV)); 00089 } 00090 00091 /* 00092 * Switch to the selected initial system clock source, unless 00093 * the default internal 2 MHz oscillator is selected. 00094 */ 00095 if (CONFIG_SYSCLK_SOURCE != SYSCLK_SRC_RC2MHZ) { 00096 bool need_rc2mhz = false; 00097 00098 switch (CONFIG_SYSCLK_SOURCE) { 00099 case SYSCLK_SRC_RC32MHZ: 00100 osc_enable(OSC_ID_RC32M); 00101 do { } while (!osc_is_running(OSC_ID_RC32M)); 00102 break; 00103 00104 case SYSCLK_SRC_RC32KHZ: 00105 osc_enable(OSC_ID_RC32K); 00106 do { } while (!osc_is_running(OSC_ID_RC32K)); 00107 break; 00108 00109 #ifdef CONFIG_PLL0_SOURCE 00110 case SYSCLK_SRC_PLL: 00111 if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) 00112 need_rc2mhz = true; 00113 sysclk_init_pll(); 00114 break; 00115 #endif 00116 00117 default: 00118 unhandled_case(CONFIG_SYSCLK_SOURCE); 00119 return; 00120 } 00121 00122 clk_write_ccp_reg(CTRL, CLK_BF(SCLKSEL, CONFIG_SYSCLK_SOURCE)); 00123 assert(clk_read_reg(CTRL) 00124 == CLK_BF(SCLKSEL, CONFIG_SYSCLK_SOURCE)); 00125 if (!need_rc2mhz) 00126 osc_disable(OSC_ID_RC2M); 00127 } 00128 }
1.6.3