]> git.sur5r.net Git - freertos/blob - Demo/TriCore_TC1782_TriBoard_GCC/RTOSDemo/ThirdPartyCode/cpufreq.c
Start to re-arrange files to include FreeRTOS+ in main download.
[freertos] / Demo / TriCore_TC1782_TriBoard_GCC / RTOSDemo / ThirdPartyCode / cpufreq.c
1 /*====================================================================
2 * Project:  Board Support Package (BSP)
3 * Developed using:
4 * Function: Determine the frequency the CPU is running at (TC1782)
5 *
6 * Copyright HighTec EDV-Systeme GmbH 1982-2010
7 *====================================================================*/
8
9 #include <machine/wdtcon.h>
10 #include <tc1782/scu.h>
11 #include <tc1782/cpu.h>
12
13
14 #ifndef DEF_FRQ
15 #define DEF_FRQ                 20000000U       /* TriBoard-TC1782 quartz frequency is 20 MHz */
16 #endif /* DEF_FRQ */
17
18 #define VCOBASE_FREQ    400000000U      /* ?? */
19
20 /* divider values for 150 MHz */
21 #define SYS_CFG_PDIV     2
22 #define SYS_CFG_NDIV    30
23 #define SYS_CFG_K1DIV    2
24 #define SYS_CFG_K2DIV    2
25
26
27 /* prototypes for global functions */
28 void set_cpu_frequency(void);
29 unsigned int get_cpu_frequency(void);
30
31 /* initialization flag: prevent multiple initialization of PLL_CLC */
32 static int freq_init = 0;
33
34
35 /* Set the frequency the CPU is running at */
36
37 void set_cpu_frequency(void)
38 {
39         SCU_PLLCON0_t_nonv pllcon0;
40         SCU_PLLCON1_t_nonv pllcon1;
41
42         if (freq_init)
43         {
44                 return;
45         }
46
47         freq_init = 1;
48
49         /* check whether we are already running at desired clockrate */
50         pllcon0 = SCU_PLLCON0;
51         pllcon1 = SCU_PLLCON1;
52         if (    ((SYS_CFG_NDIV - 1)  == pllcon0.bits.NDIV)
53                 &&      ((SYS_CFG_PDIV - 1)  == pllcon0.bits.PDIV)
54                 &&      ((SYS_CFG_K1DIV - 1) == pllcon1.bits.K1DIV)
55                 &&      ((SYS_CFG_K2DIV - 1) == pllcon1.bits.K2DIV)
56                 &&      SCU_PLLSTAT.bits.VCOLOCK)
57         {
58                 return;
59         }
60
61         if (!SCU_PLLSTAT.bits.PWDSTAT)
62         {
63                 /* set speed to 180 MHz with 20MHz Crystal */
64                 pllcon0.reg = 0;
65                 pllcon1.reg = 0;
66                 pllcon0.bits.NDIV  = SYS_CFG_NDIV - 1;
67                 pllcon0.bits.PDIV  = SYS_CFG_PDIV - 1;
68                 pllcon1.bits.K2DIV = SYS_CFG_K2DIV - 1;
69                 pllcon1.bits.K1DIV = SYS_CFG_K1DIV - 1;
70                 pllcon0.bits.VCOBYP = 1;
71                 pllcon0.bits.CLRFINDIS = 1;
72                 pllcon0.bits.PLLPWD = 1;
73                 pllcon0.bits.RESLD = 1;
74
75                 unlock_wdtcon();
76                 /* FPI at half CPU speed */
77                 SCU_CCUCON0.reg = 1;
78
79                 /* force prescaler mode */
80                 SCU_PLLCON0.bits.VCOBYP = 1;
81
82                 /* wait for prescaler mode */
83                 while (!SCU_PLLSTAT.bits.VCOBYST)
84                         ;
85
86                 /* write new control values */
87                 SCU_PLLCON1 = pllcon1;
88                 SCU_PLLCON0 = pllcon0;
89                 lock_wdtcon();
90
91                 /* wait for stable VCO frequency */
92                 while (!SCU_PLLSTAT.bits.VCOLOCK)
93                         ;
94
95                 unlock_wdtcon();
96                 /* leave prescaler mode */
97                 SCU_PLLCON0.bits.VCOBYP = 0;
98                 lock_wdtcon();
99         }
100 }
101
102 /* Determine the frequency the CPU is running at */
103
104 unsigned int get_cpu_frequency(void)
105 {
106         unsigned int frequency;
107         unsigned int fpidiv;
108         SCU_PLLCON0_t_nonv pllcon0;
109         SCU_PLLCON1_t_nonv pllcon1;
110         SCU_PLLSTAT_t_nonv pllstat;
111
112         if (!freq_init)
113         {
114                 set_cpu_frequency();
115
116 #ifdef ENABLE_ICACHE
117                 /* enable instruction cache (PMI_CON0) */
118                 unlock_wdtcon();
119                 PMI_CON0.bits.PCBYP = 0;
120                 lock_wdtcon();
121 #endif /* ENABLE_ICACHE */
122         }
123
124         pllcon0 = SCU_PLLCON0;
125         pllcon1 = SCU_PLLCON1;
126         pllstat = SCU_PLLSTAT;
127
128         /* read FPI divider value */
129         fpidiv = SCU_CCUCON0.bits.FPIDIV;
130
131         if (pllstat.bits.VCOBYST)
132         {
133                 /* prescaler mode */
134                 unsigned int k_div;
135
136                 k_div = pllcon1.bits.K1DIV + 1;
137                 frequency = DEF_FRQ / k_div;
138         }
139         else if (pllstat.bits.FINDIS)
140         {
141                 /* freerunning mode */
142                 unsigned int k_div;
143
144                 k_div = pllcon1.bits.K2DIV + 1;
145                 frequency = VCOBASE_FREQ / k_div;
146         }
147         else
148         {
149                 /* normal mode */
150                 unsigned int k_div, n_div, p_div;
151
152                 n_div = pllcon0.bits.NDIV + 1;
153                 p_div = pllcon0.bits.PDIV + 1;
154                 k_div = pllcon1.bits.K2DIV + 1;
155
156                 frequency = DEF_FRQ * n_div / (k_div * p_div);
157         }
158
159         frequency /= (fpidiv + 1);
160
161         return frequency;
162 }