1 /*====================================================================
2 * Project: Board Support Package (BSP)
4 * Function: Determine the frequency the CPU is running at (TC1782)
6 * Copyright HighTec EDV-Systeme GmbH 1982-2010
7 *====================================================================*/
9 #include <machine/wdtcon.h>
10 #include <tc1782/scu.h>
11 #include <tc1782/cpu.h>
15 #define DEF_FRQ 20000000U /* TriBoard-TC1782 quartz frequency is 20 MHz */
18 #define VCOBASE_FREQ 400000000U /* ?? */
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
27 /* prototypes for global functions */
28 void set_cpu_frequency(void);
29 unsigned int get_cpu_frequency(void);
31 /* initialization flag: prevent multiple initialization of PLL_CLC */
32 static int freq_init = 0;
35 /* Set the frequency the CPU is running at */
37 void set_cpu_frequency(void)
39 SCU_PLLCON0_t_nonv pllcon0;
40 SCU_PLLCON1_t_nonv pllcon1;
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)
61 if (!SCU_PLLSTAT.bits.PWDSTAT)
63 /* set speed to 180 MHz with 20MHz Crystal */
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;
76 /* FPI at half CPU speed */
79 /* force prescaler mode */
80 SCU_PLLCON0.bits.VCOBYP = 1;
82 /* wait for prescaler mode */
83 while (!SCU_PLLSTAT.bits.VCOBYST)
86 /* write new control values */
87 SCU_PLLCON1 = pllcon1;
88 SCU_PLLCON0 = pllcon0;
91 /* wait for stable VCO frequency */
92 while (!SCU_PLLSTAT.bits.VCOLOCK)
96 /* leave prescaler mode */
97 SCU_PLLCON0.bits.VCOBYP = 0;
102 /* Determine the frequency the CPU is running at */
104 unsigned int get_cpu_frequency(void)
106 unsigned int frequency;
108 SCU_PLLCON0_t_nonv pllcon0;
109 SCU_PLLCON1_t_nonv pllcon1;
110 SCU_PLLSTAT_t_nonv pllstat;
117 /* enable instruction cache (PMI_CON0) */
119 PMI_CON0.bits.PCBYP = 0;
121 #endif /* ENABLE_ICACHE */
124 pllcon0 = SCU_PLLCON0;
125 pllcon1 = SCU_PLLCON1;
126 pllstat = SCU_PLLSTAT;
128 /* read FPI divider value */
129 fpidiv = SCU_CCUCON0.bits.FPIDIV;
131 if (pllstat.bits.VCOBYST)
136 k_div = pllcon1.bits.K1DIV + 1;
137 frequency = DEF_FRQ / k_div;
139 else if (pllstat.bits.FINDIS)
141 /* freerunning mode */
144 k_div = pllcon1.bits.K2DIV + 1;
145 frequency = VCOBASE_FREQ / k_div;
150 unsigned int k_div, n_div, p_div;
152 n_div = pllcon0.bits.NDIV + 1;
153 p_div = pllcon0.bits.PDIV + 1;
154 k_div = pllcon1.bits.K2DIV + 1;
156 frequency = DEF_FRQ * n_div / (k_div * p_div);
159 frequency /= (fpidiv + 1);