00001
00041 #ifndef CHIP_CLK_H_INCLUDED
00042 #define CHIP_CLK_H_INCLUDED
00043
00044 #include <app/clk-config.h>
00045 #include <board/clk.h>
00046 #include <flash/flashc.h>
00047
00048
00049 #define PM_RCOSC_MIN_RATE 100000
00050 #define PM_RCOSC_MAX_RATE 120000
00051
00052 #define PM_NR_OSCS 2
00053 #define PM_NR_PLLS 2
00054
00058 enum pm_mainclk_src {
00059 PM_MAINCLK_SRC_RCOSC = 0,
00060 PM_MAINCLK_SRC_OSC0 = 1,
00061 PM_MAINCLK_SRC_PLL0 = 2,
00062 };
00063
00067 enum pm_pll_src {
00068 PM_PLL_SRC_OSC0 = 0,
00069 PM_PLL_SRC_OSC1 = 1,
00070 };
00071
00078 enum pm_genclk_src {
00079 PM_GENCLK_SRC_OSC0 = 0,
00080 PM_GENCLK_SRC_OSC1 = 1,
00081 PM_GENCLK_SRC_PLL0 = 2,
00082 PM_GENCLK_SRC_PLL1 = 3,
00083 };
00084
00085 #include <pm/pm_v2.h>
00086
00095 static inline uint32_t pm_priv_osc_startup(unsigned long us)
00096 {
00097 if (us == 0)
00098 return PM_OSC_STARTUP_0;
00099 if (us <= 560)
00100 return PM_OSC_STARTUP_64;
00101 if (us <= 1100)
00102 return PM_OSC_STARTUP_128;
00103 if (us <= 18000)
00104 return PM_OSC_STARTUP_2048;
00105 if (us <= 36000)
00106 return PM_OSC_STARTUP_4096;
00107 if (us <= 71000)
00108 return PM_OSC_STARTUP_8192;
00109
00110 build_assert(is_constant(us) && us <= 142000);
00111
00112 return PM_OSC_STARTUP_16384;
00113 }
00114
00115 static inline unsigned long pm_priv_get_pll_src_rate(enum pm_pll_src src)
00116 {
00117 switch (src) {
00118 #ifdef BOARD_OSC0_HZ
00119 case PM_PLL_SRC_OSC0:
00120 return BOARD_OSC0_HZ;
00121 #endif
00122 #ifdef BOARD_OSC1_HZ
00123 case PM_PLL_SRC_OSC1:
00124 return BOARD_OSC1_HZ;
00125 #endif
00126 default:
00127 unhandled_case(src);
00128 return 0;
00129 }
00130 }
00131
00132 static inline uint32_t pm_priv_pll_rate_opt(unsigned long rate)
00133 {
00134 if (rate < 170000000)
00135 return PM_PLL_VCO_MHZ_80_180;
00136 else
00137 return PM_PLL_VCO_MHZ_160_240;
00138 }
00139
00140 #if defined(CONFIG_CLK_OSC0_MAIN)
00141 static inline unsigned long get_main_clock_rate(void)
00142 {
00143 return BOARD_OSC0_HZ;
00144 }
00145 #else
00146
00147 extern unsigned long main_clock_rate;
00148
00149 static inline void pm_set_main_clock(enum pm_mainclk_src source)
00150 {
00151 unsigned long old_rate;
00152 unsigned long new_rate;
00153
00154 switch (source) {
00155 case PM_MAINCLK_SRC_RCOSC:
00156 new_rate = PM_RCOSC_MAX_RATE;
00157 break;
00158 case PM_MAINCLK_SRC_OSC0:
00159 new_rate = BOARD_OSC0_HZ;
00160 break;
00161 case PM_MAINCLK_SRC_PLL0:
00162 new_rate = pm_get_pll_rate(0);
00163 break;
00164 }
00165
00166 old_rate = main_clock_rate;
00167 if (new_rate > old_rate)
00168 flashc_adjust_wait_state(new_rate >> CONFIG_CLK_HSB_SHIFT);
00169
00170 pm_priv_set_main_clock(source, new_rate);
00171
00172 if (new_rate < old_rate)
00173 flashc_adjust_wait_state(new_rate >> CONFIG_CLK_HSB_SHIFT);
00174 }
00175
00184 static inline unsigned long get_main_clock_rate(void)
00185 {
00186 return main_clock_rate;
00187 }
00188 #endif
00189
00190 #if defined(CONFIG_CLK_FIXED_DIVIDERS)
00191 static inline unsigned long get_cpu_clock_rate(void)
00192 {
00193 return get_main_clock_rate() >> CONFIG_CLK_CPU_SHIFT;
00194 }
00195
00196 static inline unsigned long get_hsb_clock_rate(void)
00197 {
00198 return get_main_clock_rate() >> CONFIG_CLK_HSB_SHIFT;
00199 }
00200
00201 static inline unsigned long get_pba_clock_rate(void)
00202 {
00203 return get_main_clock_rate() >> CONFIG_CLK_PBA_SHIFT;
00204 }
00205
00206 static inline unsigned long get_pbb_clock_rate(void)
00207 {
00208 return get_main_clock_rate() >> CONFIG_CLK_PBB_SHIFT;
00209 }
00210 #else
00211 extern unsigned long get_sync_clock_rate(unsigned int shift);
00212
00214 static inline unsigned long get_cpu_clock_rate(void)
00215 {
00216 return get_sync_clock_rate(0);
00217 }
00218
00220 static inline unsigned long get_hsb_clock_rate(void)
00221 {
00222 return get_sync_clock_rate(8);
00223 }
00224
00226 static inline unsigned long get_pba_clock_rate(void)
00227 {
00228 return get_sync_clock_rate(16);
00229 }
00230
00232 static inline unsigned long get_pbb_clock_rate(void)
00233 {
00234 return get_sync_clock_rate(24);
00235 }
00236 #endif
00237
00239 static inline unsigned long get_smc_hclk_rate(void)
00240 {
00241 return get_hsb_clock_rate();
00242 }
00243
00251 static inline unsigned long get_usart_pclk_rate(unsigned int id)
00252 {
00253 return get_pbb_clock_rate();
00254 }
00255
00263 static inline unsigned long get_spi_pclk_rate(unsigned int id)
00264 {
00265 return get_pbb_clock_rate();
00266 }
00267
00275 static inline unsigned long get_mci_pclk_rate(unsigned int id)
00276 {
00277 return get_pba_clock_rate();
00278 }
00279
00288 static inline void pm_init_osc(unsigned int id)
00289 {
00290 uint32_t ctrl;
00291
00292 switch (id) {
00293 case 0:
00294 assert(!(pm_read_reg(MCCTRL) & PM_MCCTRL_OSCEN(0)));
00295 if (BOARD_OSC0_XTAL)
00296 ctrl = PM_OSC_MODE_XTAL;
00297 else
00298 ctrl = PM_OSC_MODE_EXT;
00299 ctrl |= pm_priv_osc_startup(BOARD_OSC0_STARTUP_US);
00300 pm_write_reg(OSCCTRL(0), ctrl);
00301 break;
00302
00303 #ifdef BOARD_OSC1_HZ
00304 case 1:
00305 assert(!(pm_read_reg(MCCTRL) & PM_MCCTRL_OSCEN(1)));
00306 if (BOARD_OSC1_XTAL)
00307 ctrl = PM_OSC_MODE_XTAL;
00308 else
00309 ctrl = PM_OSC_MODE_EXT;
00310 ctrl |= pm_priv_osc_startup(BOARD_OSC1_STARTUP_US);
00311 pm_write_reg(OSCCTRL(1), ctrl);
00312 break;
00313 #endif
00314 default:
00315 unhandled_case(id);
00316 break;
00317 }
00318 }
00319
00328 static inline int clk_enable_usbb(void)
00329 {
00330
00331 #if (BOARD_OSC0_HZ == 12000000)
00332 return pm_enable_genclk(4, PM_GENCLK_SRC_OSC0, 1);
00333 #elif (BOARD_OSC1_HZ == 12000000)
00334 return pm_enable_genclk(4, PM_GENCLK_SRC_OSC1, 1);
00335 #else
00336
00337
00338
00339
00340 return board_enable_usbb_clk();
00341 #endif
00342 }
00343
00344 #endif
00345