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)*/