FreeCalypso > hg > leo2moko-debug
comparison chipsetsw/drivers/drv_core/clkm/clkm.c @ 0:509db1a7b7b8
initial import: leo2moko-r1
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Mon, 01 Jun 2015 03:24:05 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:509db1a7b7b8 |
---|---|
1 /****************************************************************************** | |
2 TEXAS INSTRUMENTS INCORPORATED PROPRIETARY INFORMATION | |
3 | |
4 Property of Texas Instruments -- For Unrestricted Internal Use Only | |
5 Unauthorized reproduction and/or distribution is strictly prohibited. This | |
6 product is protected under copyright law and trade secret law as an | |
7 unpublished work. Created 1987, (C) Copyright 1997 Texas Instruments. All | |
8 rights reserved. | |
9 | |
10 | |
11 Filename : clkm.c | |
12 | |
13 Description : Set of functions useful to test the Saturn | |
14 CLKM peripheral | |
15 | |
16 Project : drivers | |
17 | |
18 Author : pmonteil@tif.ti.com Patrice Monteil. | |
19 | |
20 Version number : 1.13 | |
21 | |
22 Date : 05/23/03 | |
23 | |
24 Previous delta : 10/23/01 14:43:31 | |
25 | |
26 Sccs Id (SID) : '@(#) clkm.c 1.11 10/23/01 14:43:31 ' | |
27 | |
28 *****************************************************************************/ | |
29 | |
30 //############################################################ | |
31 //############################################################ | |
32 //### Be careful: this file must be placed in Flash Memory ### | |
33 //### and compiled in 16 bits length intructions ### | |
34 //### (CF. the function wait_ARM_cycles() ### | |
35 //############################################################ | |
36 //############################################################ | |
37 | |
38 #include "l1sw.cfg" | |
39 #include "chipset.cfg" | |
40 #include "board.cfg" | |
41 #include "swconfig.cfg" | |
42 | |
43 #if (OP_L1_STANDALONE == 0) | |
44 #include "main/sys_types.h" | |
45 #else | |
46 #include "sys_types.h" | |
47 #endif | |
48 | |
49 #include "clkm.h" | |
50 | |
51 | |
52 #if (CHIPSET == 12) | |
53 #include "sys_memif.h" | |
54 #else | |
55 #include "memif/mem.h" | |
56 #endif | |
57 | |
58 #if (BOARD == 34) | |
59 #include "armio/armio.h" | |
60 #include "timer/timer.h" | |
61 #endif | |
62 | |
63 static SYS_UWORD32 ratio_wait_loop = 0; | |
64 | |
65 #if (CHIPSET == 12) | |
66 const double dsp_div_value[CLKM_NB_DSP_DIV_VALUE] = {1, 1.5, 2, 3}; | |
67 #endif | |
68 | |
69 #if (BOARD == 34) | |
70 /* | |
71 * CLKM_InitARMClock() | |
72 * | |
73 * This init is for VTCX0 = 13 MHz | |
74 * (use CLKM_VTCXO_26 if VTCX0 is 26 MHz) | |
75 * Parameters : src : 0x0 means EXT CLK (mpu dpll) selected | |
76 * 0x1 means VTCX0 selected | |
77 * div : Division factor applied to clock | |
78 * source | |
79 * (div = 3 -> divise by 3/2 in fact) | |
80 * WARNING : reverse order in comparison to ULYSSE | |
81 * | |
82 * Return : none | |
83 * Functionality :Initialize the ARM Clock frequency | |
84 */ | |
85 | |
86 void CLKM_InitARMClock(int src, int div) | |
87 { | |
88 SYS_UWORD16 cntl = * (volatile SYS_UWORD16 *) CLKM_ARM_CLK; | |
89 int clk_xp5, clk_div; | |
90 | |
91 if (div == 3) | |
92 clk_xp5 = 1; | |
93 else | |
94 clk_xp5 = 0; | |
95 | |
96 if (div == 2) | |
97 clk_div = 1; | |
98 else if (div == 4) | |
99 clk_div = 0; | |
100 else | |
101 clk_div = 3; | |
102 | |
103 cntl &= ~(MASK_ARM_MCLK_1P5 | CLKM_MCLK_DIV); | |
104 cntl |= ((clk_xp5 << 3) | (clk_div << 4)); | |
105 | |
106 * (volatile SYS_UWORD16 *) CLKM_ARM_CLK = cntl; | |
107 if (src) | |
108 CLKM_EnableDPLL(0); | |
109 else | |
110 CLKM_EnableDPLL(1); | |
111 } | |
112 | |
113 /* | |
114 * CLKM_SetMclkDiv | |
115 * | |
116 * Set divider | |
117 * | |
118 * Parameter : 2-bit divider as per spec (0-7) | |
119 * | |
120 * Side-effect : compute magic delay for busy loops | |
121 * | |
122 */ | |
123 void CLKM_SetMclkDiv(int div) | |
124 { | |
125 volatile SYS_UWORD16 clkm_ctrl; | |
126 clkm_ctrl = *((volatile SYS_UWORD16 *) CLKM_ARM_CLK); // read register | |
127 clkm_ctrl &= ~CLKM_MCLK_DIV; | |
128 clkm_ctrl |= (div << 4); | |
129 *((volatile SYS_UWORD16 *) CLKM_ARM_CLK) = clkm_ctrl; | |
130 } | |
131 | |
132 /* | |
133 * CLKM_EnableDPLL | |
134 * | |
135 * Enable or disable 48mhz PLL for ARM clock | |
136 * | |
137 * Parameter : 1 or 0 | |
138 * | |
139 * Side-effect : compute magic delay for busy loops | |
140 * | |
141 */ | |
142 void CLKM_EnableDPLL(int enable) | |
143 { | |
144 volatile SYS_UWORD16 clkm_ctrl; | |
145 | |
146 // read CLKM register | |
147 clkm_ctrl = *((volatile SYS_UWORD16 *) CLKM_ARM_CLK); | |
148 | |
149 if (enable) | |
150 { | |
151 // PARAMETERS tuned for the AVENGER 2 reference design | |
152 // we wait before accessing external memory at wake up | |
153 // we have 2.5 ms margin before the first IT TDMA, we wait | |
154 // | |
155 // 5000 loop cycles | |
156 // 5000 * 5 arm7 cycles | |
157 // giving <= 1 ms at 26 MHz | |
158 // | |
159 wait_ARM_cycles(5000); | |
160 } | |
161 else | |
162 { | |
163 // reset bit for VTCXO | |
164 clkm_ctrl &= ~CLKM_CLKIN_SEL; | |
165 *((volatile SYS_UWORD16 *) CLKM_ARM_CLK) = clkm_ctrl; | |
166 | |
167 // disable clk48mhz | |
168 AI_ResetBit(6); | |
169 } | |
170 } | |
171 | |
172 /* | |
173 * CLKM_EnableSharedMemClock | |
174 * | |
175 * Enable or disable shared mem clock | |
176 * | |
177 * Parameter : 1 or 0 | |
178 * | |
179 */ | |
180 void CLKM_EnableSharedMemClock(int enable) | |
181 { | |
182 if (enable) | |
183 { | |
184 // request shared mem clock and wait for MPU HW acknowledge | |
185 AI_ResetBit(4); | |
186 while(AI_ReadBit(5)!=1); | |
187 } | |
188 else | |
189 { | |
190 // disable shared mem clock | |
191 AI_SetBit(4); | |
192 } | |
193 } | |
194 | |
195 /* | |
196 * CLKM_InitLeadClock | |
197 * | |
198 * Parameter : onoff, mul, ndiv, div | |
199 * | |
200 * onoff -> (1:pll on) (0: pll off) | |
201 * if div = 0 -> x(plmul+1) | |
202 * if div = 1 -> x(plmul+1)/2 if plmul is even | |
203 * x(plmul/4) if plmul is odd | |
204 * ndiv | |
205 */ | |
206 | |
207 void CLKM_InitLeadClock(int onoff, int mul, int ndiv, int div) | |
208 { | |
209 int pldiv, pllndiv ; | |
210 SYS_UWORD16 value = 0; | |
211 | |
212 value |= onoff & CLKM_PLONOFF ; | |
213 value |= (mul << 1) & CLKM_PLMUL; | |
214 value |= (ndiv << 5)& CLKM_PLLNDIV; | |
215 value |= (div << 6) & CLKM_PLDIV; | |
216 | |
217 CLKM_INITLEADPLL(value); | |
218 } | |
219 | |
220 #elif ((CHIPSET == 4) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12)) | |
221 /*--------------------------------------------------------------*/ | |
222 /* CLKM_InitARMClock() */ | |
223 /*--------------------------------------------------------------*/ | |
224 /* Parameters : clk_src : 0x00 means DPLL selected */ | |
225 /* 0x01 means VTCX0 selected */ | |
226 /* 0x03 means CLKIN selected */ | |
227 /* clk_xp5 : Enable 1.5 or 2.5 division factor */ | |
228 /* (0 or 1) */ | |
229 /* clk_div : Division factor applied to clock */ | |
230 /* source */ | |
231 /* WARNING : reverse order in comparison to ULYSSE */ | |
232 /* */ | |
233 /* Return : none */ | |
234 /* Functionality :Initialize the ARM Clock frequency */ | |
235 /*--------------------------------------------------------------*/ | |
236 void CLKM_InitARMClock(SYS_UWORD16 clk_src, SYS_UWORD16 clk_div, SYS_UWORD16 clk_xp5) | |
237 { | |
238 SYS_UWORD16 cntl = * (volatile SYS_UWORD16 *) CLKM_ARM_CLK; | |
239 | |
240 cntl &= ~(CLKM_CLKIN0 | CLKM_CLKIN_SEL | CLKM_ARM_MCLK_XP5 | CLKM_MCLK_DIV); | |
241 | |
242 cntl |= ((clk_src << 1) | (clk_xp5 << 3) | (clk_div << 4)); | |
243 | |
244 * (volatile SYS_UWORD16 *) CLKM_ARM_CLK = cntl; | |
245 } | |
246 #else | |
247 /*-------------------------------------------------------------- | |
248 * CLKM_InitARMClock() | |
249 *-------------------------------------------------------------- | |
250 * Parameters : clk_src : 0x00 means CLKIN selected | |
251 * 0x01 means 32 K selected | |
252 * 0x02 means External clock selected | |
253 * | |
254 * Return : none | |
255 * Functionality :Initialize the ARM Clock frequency | |
256 *--------------------------------------------------------------*/ | |
257 void CLKM_InitARMClock(SYS_UWORD16 clk_src, SYS_UWORD16 clk_div) | |
258 { | |
259 SYS_UWORD16 cntl = * (volatile SYS_UWORD16 *) CLKM_ARM_CLK; | |
260 | |
261 cntl &= ~(CLKM_LOW_FRQ | CLKM_CLKIN_SEL | CLKM_MCLK_DIV); | |
262 | |
263 cntl |= ((clk_src << 1) | (clk_div << 4)); | |
264 | |
265 * (volatile SYS_UWORD16 *) CLKM_ARM_CLK = cntl; | |
266 } | |
267 | |
268 #endif | |
269 | |
270 | |
271 /*-------------------------------------------------------*/ | |
272 /* convert_nanosec_to_cycles() */ | |
273 /*-------------------------------------------------------*/ | |
274 /* parameter: time in 10E-9 seconds */ | |
275 /* return: Number of cycles for the wait_ARM_cycles() */ | |
276 /* function */ | |
277 /* */ | |
278 /* Description: */ | |
279 /* ------------ */ | |
280 /* convert x nanoseconds in y cycles used by the ASM loop*/ | |
281 /* function . Before calling this function, call the */ | |
282 /* initialize_wait_loop() function */ | |
283 /* Called when the HardWare needs time to wait */ | |
284 /*-------------------------------------------------------*/ | |
285 SYS_UWORD32 convert_nanosec_to_cycles(SYS_UWORD32 time) | |
286 { | |
287 return( time / ratio_wait_loop); | |
288 } | |
289 | |
290 | |
291 /*-------------------------------------------------------*/ | |
292 /* initialize_wait_loop() */ | |
293 /*-------------------------------------------------------*/ | |
294 /* */ | |
295 /* Description: */ | |
296 /* ------------ */ | |
297 /* Init the ratio used to convert time->Cycles according */ | |
298 /* to hardware parameters */ | |
299 /* measurement time for this function (ARM 39Mhz, 3 waits*/ | |
300 /* states) = 75 micoseconds */ | |
301 /*-------------------------------------------------------*/ | |
302 | |
303 void initialize_wait_loop(void) | |
304 { | |
305 #if (BOARD == 34) | |
306 unsigned long ulTimeSpent=0; | |
307 | |
308 // set up timer 2 for wait_ARM_cycles function calibration | |
309 TM_EnableTimer (2); | |
310 TM_ResetTimer (2, 0xFFFF, 0, 0); | |
311 | |
312 // run wait_ARM_cycles() for 10000 loops | |
313 wait_ARM_cycles(10000); | |
314 | |
315 // time spent expressed in timer cycles | |
316 // where 1 timer cycle = 2462 ns with prescale 0 | |
317 // 13 MHz divided by 16 = timer clkin | |
318 // prescale 0 -> divided by 2 | |
319 ulTimeSpent = TM_ReadTimer (2); | |
320 | |
321 TM_StopTimer (2); | |
322 | |
323 ulTimeSpent = 0xFFFF - ulTimeSpent; | |
324 ulTimeSpent *= 2462; | |
325 | |
326 // compute ratio_wait_loop | |
327 ratio_wait_loop = (unsigned long)(ulTimeSpent/10000.); | |
328 #else | |
329 #define NBR_CYCLES_IN_LOOP 5 // this value is got from an oscilloscope measurement | |
330 | |
331 double src_ratio; | |
332 double final_ratio; | |
333 | |
334 SYS_UWORD16 flash_access_size; | |
335 SYS_UWORD16 flash_wait_state; | |
336 SYS_UWORD32 nbr; | |
337 SYS_UWORD32 arm_clock; | |
338 | |
339 ////////////////////////////////// | |
340 // compute the ARM clock used // | |
341 ////////////////////////////////// | |
342 { | |
343 SYS_UWORD16 arm_mclk_xp5; | |
344 SYS_UWORD16 arm_ratio; | |
345 SYS_UWORD16 clk_src; | |
346 SYS_UWORD16 clkm_cntl_arm_clk_reg = * (volatile SYS_UWORD16 *) CLKM_CNTL_ARM_CLK; | |
347 | |
348 #if ((CHIPSET == 4) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12)) | |
349 clk_src = (clkm_cntl_arm_clk_reg & MASK_CLKIN) >> 1; | |
350 switch (clk_src) | |
351 { | |
352 case 0x00: //DPLL selected | |
353 // select the DPLL factor | |
354 #if (CHIPSET == 12) | |
355 if (((* (volatile SYS_UWORD16 *) C_MAP_DPLL_BASE) & DPLL_LOCK) != 0) | |
356 #else | |
357 if (((* (volatile SYS_UWORD16 *) MEM_DPLL_ADDR) & DPLL_LOCK) != 0) | |
358 #endif | |
359 { | |
360 SYS_UWORD16 dpll_div; | |
361 SYS_UWORD16 dpll_mul; | |
362 | |
363 dpll_div=DPLL_READ_DPLL_DIV; | |
364 dpll_mul=DPLL_READ_DPLL_MUL; | |
365 src_ratio = (double)(dpll_mul)/(double)(dpll_div+1); | |
366 } | |
367 else // DPLL in bypass mode | |
368 { | |
369 SYS_UWORD16 dpll_div = DPLL_BYPASS_DIV; | |
370 src_ratio= (double)(1)/(double)(dpll_div+1); | |
371 } | |
372 break; | |
373 case 0x01: //VTCX0 selected | |
374 src_ratio = 1; | |
375 break; | |
376 case 0x03: //CLKIN selected (external clock) | |
377 src_ratio = 1; | |
378 break; | |
379 } | |
380 // define the division factor applied to clock source (CLKIN or VTCXO or DPLL) | |
381 arm_ratio = (clkm_cntl_arm_clk_reg & CLKM_MCLK_DIV) >> 4; | |
382 | |
383 // check if the 1.5 or 2.5 division factor is enabled | |
384 arm_mclk_xp5 = clkm_cntl_arm_clk_reg & CLKM_ARM_MCLK_XP5; | |
385 | |
386 if (arm_mclk_xp5 == 0) // division factor enable for ARM clock ? | |
387 { | |
388 if (arm_ratio == 0) | |
389 arm_ratio =1; | |
390 } | |
391 else | |
392 arm_ratio = ((arm_ratio>>1) & 0x0001) == 0 ? 1.5 : 2.5; | |
393 | |
394 | |
395 #else | |
396 src_ratio = 1; | |
397 | |
398 // define the division factor applied to clock source (CLKIN or VTCXO or DPLL) | |
399 arm_ratio = (clkm_cntl_arm_clk_reg & CLKM_MCLK_DIV) >> 4; | |
400 | |
401 // check if the 1.5 or 2.5 division factor is enabled | |
402 arm_mclk_xp5 = clkm_cntl_arm_clk_reg & MASK_ARM_MCLK_1P5; | |
403 | |
404 if (arm_mclk_xp5 == 1) // division factor enable for ARM clock ? | |
405 arm_ratio = 1.5; | |
406 else | |
407 { | |
408 if (arm_ratio == 0) | |
409 arm_ratio = 4; | |
410 else | |
411 if (arm_ratio == 1 ) | |
412 arm_ratio = 2; | |
413 else | |
414 arm_ratio = 1; | |
415 } | |
416 | |
417 #endif | |
418 | |
419 final_ratio = (src_ratio / (double) arm_ratio); | |
420 | |
421 } | |
422 ////////////////////////////////////////// | |
423 // compute the Flash wait states used // | |
424 ////////////////////////////////////////// | |
425 | |
426 #if (CHIPSET == 12) | |
427 flash_access_size = 1; | |
428 #else | |
429 flash_access_size = *((volatile SYS_UWORD16 *) MEM_REG_nCS0); | |
430 #endif | |
431 flash_access_size = (flash_access_size >> 5) & 0x0003; // 0=>8bits, 1=>16 bits, 2 =>32 bits | |
432 | |
433 // the loop file is compiled in 16 bits it means | |
434 // flash 8 bits => 2 loads for 1 16 bits assembler instruction | |
435 // flash 16 bits => 1 loads for 1 16 bits assembler instruction | |
436 // flash/internal RAM 32 bits => 1 loads for 1 16 bits assembler instruction (ARM bus 16 bits !!) | |
437 | |
438 // !!!!!!!!! be careful: if this file is compile in 32 bits, change these 2 lines here after !!! | |
439 if (flash_access_size == 0) flash_access_size = 2; | |
440 else flash_access_size = 1; | |
441 | |
442 #if (CHIPSET == 12) | |
443 /* | |
444 * loop move to run in internal memory, due to page mode in external memory | |
445 */ | |
446 flash_wait_state = 0; | |
447 #else | |
448 flash_wait_state = *((volatile SYS_UWORD16 *) MEM_REG_nCS0); | |
449 flash_wait_state &= 0x001F; | |
450 #endif | |
451 | |
452 ////////////////////////////////////// | |
453 // compute the length of the loop // | |
454 ////////////////////////////////////// | |
455 | |
456 // Number of flash cycles for the assembler loop | |
457 nbr = NBR_CYCLES_IN_LOOP; | |
458 | |
459 // Number of ARM cycles for the assembler loop | |
460 nbr = nbr * (flash_wait_state + 1) * (flash_access_size); | |
461 | |
462 // time for the assembler loop (unit nanoseconds: 10E-9) | |
463 arm_clock = final_ratio * 13; // ARM clock in Mhz | |
464 ratio_wait_loop = (SYS_UWORD32)((nbr*1000) / arm_clock); | |
465 #endif | |
466 } | |
467 | |
468 #if (CHIPSET != 12) | |
469 | |
470 /*-------------------------------------------------------*/ | |
471 /* wait_ARM_cycles() */ | |
472 /*-------------------------------------------------------*/ | |
473 /* */ | |
474 /* Description: */ | |
475 /* ------------ */ | |
476 /* Called when the HardWare needs time to wait. */ | |
477 /* this function wait x cycles and is used with the */ | |
478 /* convert_nanosec_to_cycles() & initialize_wait_loop() */ | |
479 /* */ | |
480 /* Exemple: wait 10 micro seconds: */ | |
481 /* initialize_wait_loop(); */ | |
482 /* wait_ARM_cycles(convert_nanosec_to_cycles(10000)) */ | |
483 /* */ | |
484 /* minimum time value with cpt_loop = 0 (estimated) */ | |
485 /* and C-SAMPLE / flash 6,5Mhz ~ 1,5 micro seconds */ | |
486 /* */ | |
487 /* */ | |
488 /* Be careful : in order to respect the rule about the */ | |
489 /* conversion "time => number of cylcles in this loop" */ | |
490 /* (Cf the functions: convert_nanosec_to_cycles() and */ | |
491 /* initialize_wait_loop() ) respect the following rules: */ | |
492 /* This function must be placed in Flash Memory and */ | |
493 /* compiled in 16 bits instructions length */ | |
494 /*-------------------------------------------------------*/ | |
495 void wait_ARM_cycles(SYS_UWORD32 cpt_loop) | |
496 { | |
497 // C code: | |
498 // while (cpt_loop -- != 0); | |
499 | |
500 asm(" CMP A1, #0"); | |
501 asm(" BEQ END_FUNCTION"); | |
502 | |
503 asm("LOOP_LINE: "); | |
504 asm(" SUB A1, A1, #1"); | |
505 asm(" CMP A1, #0"); | |
506 asm(" BNE LOOP_LINE"); | |
507 | |
508 asm("END_FUNCTION: "); | |
509 } | |
510 | |
511 #endif /* (CHIPSET != 12)*/ |