3 #if SYSTEM_MODULE_CLOCK
6 LOCAL A_UINT32 cticks = 0;
8 #define A_BAND_DEFAULT 0 // not ust now, avoiding compile error/warning, Ryan
10 LOCAL int curr_band = A_BAND_DEFAULT;
11 LOCAL void cmnos_pll_init(void);
13 /* We accept frequencies within this deviation from an expected frequency. */
14 #define A_REFCLK_DEVIATION 800000
16 #define A_REFCLK_UNKNOWN SYS_CFG_REFCLK_UNKNOWN
17 #define A_REFCLK_10_MHZ SYS_CFG_REFCLK_10_MHZ
18 #define A_REFCLK_20_MHZ SYS_CFG_REFCLK_20_MHZ
19 #define A_REFCLK_40_MHZ SYS_CFG_REFCLK_40_MHZ
21 LOCAL const struct cmnos_clock_s {
22 A_refclk_speed_t refclk_speed;
23 A_UINT32 ticks_per_sec;
24 // below are useless so far, ryan
25 A_UINT32 pll_ctrl_5ghz;
26 A_UINT32 pll_ctrl_24ghz;
27 A_UINT32 pll_settling_time; /* 50us */
28 } cmnos_clocking_table[] = {
58 #define CMNOS_CLOCKING_TABLE_NUM_ENTRIES \
59 (sizeof(cmnos_clocking_table)/sizeof(cmnos_clocking_table[0]))
61 LOCAL struct cmnos_clock_s *clock_info;
64 LOCAL void cmnos_tick(void);
67 * In case we have PLL initialization problems, software can arrange
68 * (e.g. through BMI) to skip PLL initialization, and other software
71 int cmnos_skip_pll_init = 0;
72 A_UINT32 pll_ctrl_setting_24ghz = 0;
73 A_UINT32 pll_ctrl_setting_5ghz = 0;
76 * Use default hardware values for clock-related registers.
77 * The defaults can be overridden through BMI, EJTAG, or patches.
79 * CPU clock frequencies depend on what mode we're in (2.4GHz or 5GHz):
80 * NB: AR6001 has a "reduced power" mode, but we don't use it.
82 * AR6001/AR6002 FPGA CPU clock is always at 40MHz
84 * AR6001 Rev 2.x supports 4 CPU speed selections:
86 * 2.4GHz: 44, 88, 141, refclk
87 * 5 GHz: 40, 80, 128, refclk
89 * AR6002 supports 7 CPU/SoC speed selections via CORE_CLK:
90 * CORE_CLK.DIV setting: 6,7 5 4 3 2 1 0
91 * divisor: 16 14 12 10 8 6 4
92 * 2.4GHz (pll at 352MHz): 22 25.1, 29.3, 35.2, 44, 58.7, 88
93 * 5 GHz (pll at 320MHz): 20 22.9, 26.7, 32, 40, 53.3, 80
96 #if defined(DISABLE_SYNC_DURING_PLL_UPDATE_WAR)
97 A_UINT32 cpu_clock_setting;
100 //A_COMPILE_TIME_ASSERT(verify_host_interest_small_enough,
101 // (sizeof(struct host_interest_s) <= HOST_INTEREST_MAX_SIZE))
103 //A_COMPILE_TIME_ASSERT(verify_flash_is_present_addr,
104 // ((A_UINT32)&HOST_INTEREST->hi_flash_is_present) == FLASH_IS_PRESENT_TARGADDR)
108 cmnos_delay_us(int us)
110 // A_UINT32 start_time = A_RTC_REG_READ(LF_TIMER_COUNT0_ADDRESS);
111 // unsigned int num_LF_ticks = (us+29) / 30 + 1; /* ~30.5us per LF tick */
112 //A_UINT32 ref_clk = (clock_info->ticks_per_sec)/1000/1000;
113 A_UINT32 ref_clk = (clock_info->ticks_per_sec) >> 20;
114 A_UINT32 start_time = NOW();
115 unsigned int num_ticks = us*ref_clk; // system_freq == number of ticks per 1us
117 while ( (NOW() - start_time) < num_ticks) {
123 * Return the number of milliseconds since startup.
124 * For this purpose, a "millisecond" is approximated by
125 * 1/32 of a 32KHz clock.
128 cmnos_milliseconds(void)
130 //unsigned int lowfreq_timer;
132 //lowfreq_timer = A_RTC_REG_READ(LF_TIMER_COUNT0_ADDRESS);
133 //lowfreq_timer = NOW();
135 /* LF0 timer counts at 32KHz, so adjust to approximate Ms with >> 5. */
136 //lowfreq_timer = lowfreq_timer;
139 * NB: We do not account for wrap, which occurs every 36
140 * hours when the 32768Hz low frequency timer wraps the
149 /* Expect 40MHz on AR6001 and 26MHz on AR6002 */
150 //LOCAL A_refclk_speed_t cmnos_refclk_speed;
153 cmnos_refclk_speed_get(void)
155 return clock_info->ticks_per_sec;
158 /* The UART is clocked at the reference clock frequency. */
160 cmnos_uart_frequency(void)
164 return clock_info->ticks_per_sec;
166 return clock_info->ticks_per_sec;
170 /* do we need keep a struct to hold the data ?*/
176 * Adjust any state that needs adjusting when the clock
180 cmnos_sysclk_change(void)
182 /* OS may override this function */
187 cmnos_clockregs_init(void)
190 /* we might don't need this init() */
194 * Make whatever system-level changes are needed in order to operate
195 * in the specified wireless band.
197 * For AR6K, we just need to set the PLL appropriately.
200 cmnos_wlan_band_set(int which_band)
203 /* we don't have wlan need to config */
210 /* we don't have pll now, */
214 cmnos_clock_init(A_UINT32 ref_clk)
219 /* Look up the nearest supported frequency. */
221 i < CMNOS_CLOCKING_TABLE_NUM_ENTRIES-1;
224 A_UINT32 ticks_per_sec;
226 ticks_per_sec = cmnos_clocking_table[i].ticks_per_sec;
227 if ((ref_clk > ticks_per_sec - A_REFCLK_DEVIATION) &&
228 (ref_clk < ticks_per_sec + A_REFCLK_DEVIATION))
234 clock_info = (struct cmnos_clock_s *)&cmnos_clocking_table[i];
235 // HOST_INTEREST->hi_clock_info = (A_UINT32)clock_info;
240 ////////////////////////////////////////////////////////////////////////
241 // software emulate ticks on millisecond based
247 set_ccompare0(xthal_get_ccompare(XTENSA_TIMER_0)+ONE_MSEC);
252 static A_UINT32 last_tick = 0;
253 A_UINT32 current_tick = NOW();
256 // tick is 32 bit register, will overflow soon
257 if( current_tick < last_tick )
259 delta_tick = (A_UINT32 )((0xffffffff-last_tick)+current_tick+1)/(1000);
263 delta_tick = (A_UINT32 ) (current_tick - last_tick)/(1000);
267 last_tick = current_tick;
269 cticks += delta_tick;
273 ////////////////////////////////////////////////////////////////////////
276 cmnos_clock_module_install(struct clock_api *tbl)
278 tbl->_clock_init = cmnos_clock_init;
279 tbl->_clockregs_init = cmnos_clockregs_init;
280 tbl->_delay_us = cmnos_delay_us;
281 tbl->_wlan_band_set = cmnos_wlan_band_set;
282 tbl->_refclk_speed_get = cmnos_refclk_speed_get;
283 tbl->_milliseconds = cmnos_milliseconds;
284 tbl->_uart_frequency = cmnos_uart_frequency;
285 tbl->_sysclk_change = cmnos_sysclk_change;
287 tbl->_clock_tick = cmnos_tick;
289 #endif /* SYSTEM_MODULE_CLOCK */