diff options
Diffstat (limited to 'arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c')
-rw-r--r-- | arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c new file mode 100644 index 000000000000..367df75d4bb3 --- /dev/null +++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c | |||
@@ -0,0 +1,293 @@ | |||
1 | /***************************************************************************** | ||
2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
3 | * | ||
4 | * Unless you and Broadcom execute a separate written software license | ||
5 | * agreement governing use of this software, this software is licensed to you | ||
6 | * under the terms of the GNU General Public License version 2, available at | ||
7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
8 | * | ||
9 | * Notwithstanding the above, under no circumstances may you combine this | ||
10 | * software in any way with any other Broadcom software provided under a | ||
11 | * license other than the GPL, without Broadcom's express prior written | ||
12 | * consent. | ||
13 | *****************************************************************************/ | ||
14 | |||
15 | /****************************************************************************/ | ||
16 | /** | ||
17 | * @file chipcHw_init.c | ||
18 | * | ||
19 | * @brief Low level CHIPC PLL configuration functions | ||
20 | * | ||
21 | * @note | ||
22 | * | ||
23 | * These routines provide basic PLL controlling functionality only. | ||
24 | */ | ||
25 | /****************************************************************************/ | ||
26 | |||
27 | /* ---- Include Files ---------------------------------------------------- */ | ||
28 | |||
29 | #include <csp/errno.h> | ||
30 | #include <csp/stdint.h> | ||
31 | #include <csp/module.h> | ||
32 | |||
33 | #include <mach/csp/chipcHw_def.h> | ||
34 | #include <mach/csp/chipcHw_inline.h> | ||
35 | |||
36 | #include <csp/reg.h> | ||
37 | #include <csp/delay.h> | ||
38 | /* ---- Private Constants and Types --------------------------------------- */ | ||
39 | |||
40 | /* | ||
41 | Calculation for NDIV_i to obtain VCO frequency | ||
42 | ----------------------------------------------- | ||
43 | |||
44 | Freq_vco = Freq_ref * (P2 / P1) * (PLL_NDIV_i + PLL_NDIV_f) | ||
45 | for Freq_vco = VCO_FREQ_MHz | ||
46 | Freq_ref = chipcHw_XTAL_FREQ_Hz | ||
47 | PLL_P1 = PLL_P2 = 1 | ||
48 | and | ||
49 | PLL_NDIV_f = 0 | ||
50 | |||
51 | We get: | ||
52 | PLL_NDIV_i = Freq_vco / Freq_ref = VCO_FREQ_MHz / chipcHw_XTAL_FREQ_Hz | ||
53 | |||
54 | Calculation for PLL MDIV to obtain frequency Freq_x for channel x | ||
55 | ----------------------------------------------------------------- | ||
56 | Freq_x = chipcHw_XTAL_FREQ_Hz * PLL_NDIV_i / PLL_MDIV_x = VCO_FREQ_MHz / PLL_MDIV_x | ||
57 | |||
58 | PLL_MDIV_x = VCO_FREQ_MHz / Freq_x | ||
59 | */ | ||
60 | |||
61 | /* ---- Private Variables ------------------------------------------------- */ | ||
62 | /****************************************************************************/ | ||
63 | /** | ||
64 | * @brief Initializes the PLL2 | ||
65 | * | ||
66 | * This function initializes the PLL2 | ||
67 | * | ||
68 | */ | ||
69 | /****************************************************************************/ | ||
70 | void chipcHw_pll2Enable(uint32_t vcoFreqHz) | ||
71 | { | ||
72 | uint32_t pllPreDivider2 = 0; | ||
73 | |||
74 | { | ||
75 | REG_LOCAL_IRQ_SAVE; | ||
76 | pChipcHw->PLLConfig2 = | ||
77 | chipcHw_REG_PLL_CONFIG_D_RESET | | ||
78 | chipcHw_REG_PLL_CONFIG_A_RESET; | ||
79 | |||
80 | pllPreDivider2 = chipcHw_REG_PLL_PREDIVIDER_POWER_DOWN | | ||
81 | chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER | | ||
82 | (chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) << | ||
83 | chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) | | ||
84 | (chipcHw_REG_PLL_PREDIVIDER_P1 << | ||
85 | chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) | | ||
86 | (chipcHw_REG_PLL_PREDIVIDER_P2 << | ||
87 | chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT); | ||
88 | |||
89 | /* Enable CHIPC registers to control the PLL */ | ||
90 | pChipcHw->PLLStatus |= chipcHw_REG_PLL_STATUS_CONTROL_ENABLE; | ||
91 | |||
92 | /* Set pre divider to get desired VCO frequency */ | ||
93 | pChipcHw->PLLPreDivider2 = pllPreDivider2; | ||
94 | /* Set NDIV Frac */ | ||
95 | pChipcHw->PLLDivider2 = chipcHw_REG_PLL_DIVIDER_NDIV_f; | ||
96 | |||
97 | /* This has to be removed once the default values are fixed for PLL2. */ | ||
98 | pChipcHw->PLLControl12 = 0x38000700; | ||
99 | pChipcHw->PLLControl22 = 0x00000015; | ||
100 | |||
101 | /* Reset PLL2 */ | ||
102 | if (vcoFreqHz > chipcHw_REG_PLL_CONFIG_VCO_SPLIT_FREQ) { | ||
103 | pChipcHw->PLLConfig2 = chipcHw_REG_PLL_CONFIG_D_RESET | | ||
104 | chipcHw_REG_PLL_CONFIG_A_RESET | | ||
105 | chipcHw_REG_PLL_CONFIG_VCO_1601_3200 | | ||
106 | chipcHw_REG_PLL_CONFIG_POWER_DOWN; | ||
107 | } else { | ||
108 | pChipcHw->PLLConfig2 = chipcHw_REG_PLL_CONFIG_D_RESET | | ||
109 | chipcHw_REG_PLL_CONFIG_A_RESET | | ||
110 | chipcHw_REG_PLL_CONFIG_VCO_800_1600 | | ||
111 | chipcHw_REG_PLL_CONFIG_POWER_DOWN; | ||
112 | } | ||
113 | REG_LOCAL_IRQ_RESTORE; | ||
114 | } | ||
115 | |||
116 | /* Insert certain amount of delay before deasserting ARESET. */ | ||
117 | udelay(1); | ||
118 | |||
119 | { | ||
120 | REG_LOCAL_IRQ_SAVE; | ||
121 | /* Remove analog reset and Power on the PLL */ | ||
122 | pChipcHw->PLLConfig2 &= | ||
123 | ~(chipcHw_REG_PLL_CONFIG_A_RESET | | ||
124 | chipcHw_REG_PLL_CONFIG_POWER_DOWN); | ||
125 | |||
126 | REG_LOCAL_IRQ_RESTORE; | ||
127 | |||
128 | } | ||
129 | |||
130 | /* Wait until PLL is locked */ | ||
131 | while (!(pChipcHw->PLLStatus2 & chipcHw_REG_PLL_STATUS_LOCKED)) | ||
132 | ; | ||
133 | |||
134 | { | ||
135 | REG_LOCAL_IRQ_SAVE; | ||
136 | /* Remove digital reset */ | ||
137 | pChipcHw->PLLConfig2 &= ~chipcHw_REG_PLL_CONFIG_D_RESET; | ||
138 | |||
139 | REG_LOCAL_IRQ_RESTORE; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | EXPORT_SYMBOL(chipcHw_pll2Enable); | ||
144 | |||
145 | /****************************************************************************/ | ||
146 | /** | ||
147 | * @brief Initializes the PLL1 | ||
148 | * | ||
149 | * This function initializes the PLL1 | ||
150 | * | ||
151 | */ | ||
152 | /****************************************************************************/ | ||
153 | void chipcHw_pll1Enable(uint32_t vcoFreqHz, chipcHw_SPREAD_SPECTRUM_e ssSupport) | ||
154 | { | ||
155 | uint32_t pllPreDivider = 0; | ||
156 | |||
157 | { | ||
158 | REG_LOCAL_IRQ_SAVE; | ||
159 | |||
160 | pChipcHw->PLLConfig = | ||
161 | chipcHw_REG_PLL_CONFIG_D_RESET | | ||
162 | chipcHw_REG_PLL_CONFIG_A_RESET; | ||
163 | /* Setting VCO frequency */ | ||
164 | if (ssSupport == chipcHw_SPREAD_SPECTRUM_ALLOW) { | ||
165 | pllPreDivider = | ||
166 | chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASH_1_8 | | ||
167 | ((chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) - | ||
168 | 1) << chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) | | ||
169 | (chipcHw_REG_PLL_PREDIVIDER_P1 << | ||
170 | chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) | | ||
171 | (chipcHw_REG_PLL_PREDIVIDER_P2 << | ||
172 | chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT); | ||
173 | } else { | ||
174 | pllPreDivider = chipcHw_REG_PLL_PREDIVIDER_POWER_DOWN | | ||
175 | chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER | | ||
176 | (chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) << | ||
177 | chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) | | ||
178 | (chipcHw_REG_PLL_PREDIVIDER_P1 << | ||
179 | chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) | | ||
180 | (chipcHw_REG_PLL_PREDIVIDER_P2 << | ||
181 | chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT); | ||
182 | } | ||
183 | |||
184 | /* Enable CHIPC registers to control the PLL */ | ||
185 | pChipcHw->PLLStatus |= chipcHw_REG_PLL_STATUS_CONTROL_ENABLE; | ||
186 | |||
187 | /* Set pre divider to get desired VCO frequency */ | ||
188 | pChipcHw->PLLPreDivider = pllPreDivider; | ||
189 | /* Set NDIV Frac */ | ||
190 | if (ssSupport == chipcHw_SPREAD_SPECTRUM_ALLOW) { | ||
191 | pChipcHw->PLLDivider = chipcHw_REG_PLL_DIVIDER_M1DIV | | ||
192 | chipcHw_REG_PLL_DIVIDER_NDIV_f_SS; | ||
193 | } else { | ||
194 | pChipcHw->PLLDivider = chipcHw_REG_PLL_DIVIDER_M1DIV | | ||
195 | chipcHw_REG_PLL_DIVIDER_NDIV_f; | ||
196 | } | ||
197 | |||
198 | /* Reset PLL1 */ | ||
199 | if (vcoFreqHz > chipcHw_REG_PLL_CONFIG_VCO_SPLIT_FREQ) { | ||
200 | pChipcHw->PLLConfig = chipcHw_REG_PLL_CONFIG_D_RESET | | ||
201 | chipcHw_REG_PLL_CONFIG_A_RESET | | ||
202 | chipcHw_REG_PLL_CONFIG_VCO_1601_3200 | | ||
203 | chipcHw_REG_PLL_CONFIG_POWER_DOWN; | ||
204 | } else { | ||
205 | pChipcHw->PLLConfig = chipcHw_REG_PLL_CONFIG_D_RESET | | ||
206 | chipcHw_REG_PLL_CONFIG_A_RESET | | ||
207 | chipcHw_REG_PLL_CONFIG_VCO_800_1600 | | ||
208 | chipcHw_REG_PLL_CONFIG_POWER_DOWN; | ||
209 | } | ||
210 | |||
211 | REG_LOCAL_IRQ_RESTORE; | ||
212 | |||
213 | /* Insert certain amount of delay before deasserting ARESET. */ | ||
214 | udelay(1); | ||
215 | |||
216 | { | ||
217 | REG_LOCAL_IRQ_SAVE; | ||
218 | /* Remove analog reset and Power on the PLL */ | ||
219 | pChipcHw->PLLConfig &= | ||
220 | ~(chipcHw_REG_PLL_CONFIG_A_RESET | | ||
221 | chipcHw_REG_PLL_CONFIG_POWER_DOWN); | ||
222 | REG_LOCAL_IRQ_RESTORE; | ||
223 | } | ||
224 | |||
225 | /* Wait until PLL is locked */ | ||
226 | while (!(pChipcHw->PLLStatus & chipcHw_REG_PLL_STATUS_LOCKED) | ||
227 | || !(pChipcHw-> | ||
228 | PLLStatus2 & chipcHw_REG_PLL_STATUS_LOCKED)) | ||
229 | ; | ||
230 | |||
231 | /* Remove digital reset */ | ||
232 | { | ||
233 | REG_LOCAL_IRQ_SAVE; | ||
234 | pChipcHw->PLLConfig &= ~chipcHw_REG_PLL_CONFIG_D_RESET; | ||
235 | REG_LOCAL_IRQ_RESTORE; | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | |||
240 | EXPORT_SYMBOL(chipcHw_pll1Enable); | ||
241 | |||
242 | /****************************************************************************/ | ||
243 | /** | ||
244 | * @brief Initializes the chipc module | ||
245 | * | ||
246 | * This function initializes the PLLs and core system clocks | ||
247 | * | ||
248 | */ | ||
249 | /****************************************************************************/ | ||
250 | |||
251 | void chipcHw_Init(chipcHw_INIT_PARAM_t *initParam /* [ IN ] Misc chip initialization parameter */ | ||
252 | ) { | ||
253 | #if !(defined(__KERNEL__) && !defined(STANDALONE)) | ||
254 | delay_init(); | ||
255 | #endif | ||
256 | |||
257 | /* Do not program PLL, when warm reset */ | ||
258 | if (!(chipcHw_getStickyBits() & chipcHw_REG_STICKY_CHIP_WARM_RESET)) { | ||
259 | chipcHw_pll1Enable(initParam->pllVcoFreqHz, | ||
260 | initParam->ssSupport); | ||
261 | chipcHw_pll2Enable(initParam->pll2VcoFreqHz); | ||
262 | } else { | ||
263 | /* Clear sticky bits */ | ||
264 | chipcHw_clearStickyBits(chipcHw_REG_STICKY_CHIP_WARM_RESET); | ||
265 | } | ||
266 | /* Clear sticky bits */ | ||
267 | chipcHw_clearStickyBits(chipcHw_REG_STICKY_CHIP_SOFT_RESET); | ||
268 | |||
269 | /* Before configuring the ARM clock, atleast we need to make sure BUS clock maintains the proper ratio with ARM clock */ | ||
270 | pChipcHw->ACLKClock = | ||
271 | (pChipcHw-> | ||
272 | ACLKClock & ~chipcHw_REG_ACLKClock_CLK_DIV_MASK) | (initParam-> | ||
273 | armBusRatio & | ||
274 | chipcHw_REG_ACLKClock_CLK_DIV_MASK); | ||
275 | |||
276 | /* Set various core component frequencies. The order in which this is done is important for some. */ | ||
277 | /* The RTBUS (DDR PHY) is derived from the BUS, and the BUS from the ARM, and VPM needs to know BUS */ | ||
278 | /* frequency to find its ratio with the BUS. Hence we must set the ARM first, followed by the BUS, */ | ||
279 | /* then VPM and RTBUS. */ | ||
280 | |||
281 | chipcHw_setClockFrequency(chipcHw_CLOCK_ARM, | ||
282 | initParam->busClockFreqHz * | ||
283 | initParam->armBusRatio); | ||
284 | chipcHw_setClockFrequency(chipcHw_CLOCK_BUS, initParam->busClockFreqHz); | ||
285 | chipcHw_setClockFrequency(chipcHw_CLOCK_VPM, | ||
286 | initParam->busClockFreqHz * | ||
287 | initParam->vpmBusRatio); | ||
288 | chipcHw_setClockFrequency(chipcHw_CLOCK_DDR, | ||
289 | initParam->busClockFreqHz * | ||
290 | initParam->ddrBusRatio); | ||
291 | chipcHw_setClockFrequency(chipcHw_CLOCK_RTBUS, | ||
292 | initParam->busClockFreqHz / 2); | ||
293 | } | ||