]>
Commit | Line | Data |
---|---|---|
52ef43b0 | 1 | /* |
722e000c | 2 | * (C) Copyright 2013-2015 |
52ef43b0 TW |
3 | * NVIDIA Corporation <www.nvidia.com> |
4 | * | |
5 | * SPDX-License-Identifier: GPL-2.0+ | |
6 | */ | |
7 | ||
8 | /* Tegra124 Clock control functions */ | |
9 | ||
10 | #include <common.h> | |
11 | #include <asm/io.h> | |
12 | #include <asm/arch/clock.h> | |
13 | #include <asm/arch/sysctr.h> | |
14 | #include <asm/arch/tegra.h> | |
15 | #include <asm/arch-tegra/clk_rst.h> | |
16 | #include <asm/arch-tegra/timer.h> | |
17 | #include <div64.h> | |
18 | #include <fdtdec.h> | |
19 | ||
20 | /* | |
21 | * Clock types that we can use as a source. The Tegra124 has muxes for the | |
22 | * peripheral clocks, and in most cases there are four options for the clock | |
23 | * source. This gives us a clock 'type' and exploits what commonality exists | |
24 | * in the device. | |
25 | * | |
26 | * Letters are obvious, except for T which means CLK_M, and S which means the | |
27 | * clock derived from 32KHz. Beware that CLK_M (also called OSC in the | |
28 | * datasheet) and PLL_M are different things. The former is the basic | |
29 | * clock supplied to the SOC from an external oscillator. The latter is the | |
30 | * memory clock PLL. | |
31 | * | |
32 | * See definitions in clock_id in the header file. | |
33 | */ | |
34 | enum clock_type_id { | |
35 | CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */ | |
36 | CLOCK_TYPE_MCPA, /* and so on */ | |
37 | CLOCK_TYPE_MCPT, | |
38 | CLOCK_TYPE_PCM, | |
39 | CLOCK_TYPE_PCMT, | |
40 | CLOCK_TYPE_PDCT, | |
41 | CLOCK_TYPE_ACPT, | |
42 | CLOCK_TYPE_ASPTE, | |
43 | CLOCK_TYPE_PMDACD2T, | |
44 | CLOCK_TYPE_PCST, | |
96e82a25 | 45 | CLOCK_TYPE_DP, |
52ef43b0 TW |
46 | |
47 | CLOCK_TYPE_PC2CC3M, | |
48 | CLOCK_TYPE_PC2CC3S_T, | |
49 | CLOCK_TYPE_PC2CC3M_T, | |
50 | CLOCK_TYPE_PC2CC3M_T16, /* PC2CC3M_T, but w/16-bit divisor (I2C) */ | |
51 | CLOCK_TYPE_MC2CC3P_A, | |
52 | CLOCK_TYPE_M, | |
53 | CLOCK_TYPE_MCPTM2C2C3, | |
54 | CLOCK_TYPE_PC2CC3T_S, | |
55 | CLOCK_TYPE_AC2CC3P_TS2, | |
56 | ||
57 | CLOCK_TYPE_COUNT, | |
58 | CLOCK_TYPE_NONE = -1, /* invalid clock type */ | |
59 | }; | |
60 | ||
61 | enum { | |
62 | CLOCK_MAX_MUX = 8 /* number of source options for each clock */ | |
63 | }; | |
64 | ||
65 | /* | |
66 | * Clock source mux for each clock type. This just converts our enum into | |
67 | * a list of mux sources for use by the code. | |
68 | * | |
69 | * Note: | |
70 | * The extra column in each clock source array is used to store the mask | |
71 | * bits in its register for the source. | |
72 | */ | |
73 | #define CLK(x) CLOCK_ID_ ## x | |
74 | static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = { | |
75 | { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC), | |
76 | CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), | |
77 | MASK_BITS_31_30}, | |
78 | { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO), | |
79 | CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), | |
80 | MASK_BITS_31_30}, | |
81 | { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), | |
82 | CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), | |
83 | MASK_BITS_31_30}, | |
84 | { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE), | |
85 | CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), | |
86 | MASK_BITS_31_30}, | |
87 | { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), | |
88 | CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), | |
89 | MASK_BITS_31_30}, | |
90 | { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC), | |
91 | CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), | |
92 | MASK_BITS_31_30}, | |
93 | { CLK(AUDIO), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), | |
94 | CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), | |
95 | MASK_BITS_31_30}, | |
96 | { CLK(AUDIO), CLK(SFROM32KHZ), CLK(PERIPH), CLK(OSC), | |
97 | CLK(EPCI), CLK(NONE), CLK(NONE), CLK(NONE), | |
98 | MASK_BITS_31_29}, | |
99 | { CLK(PERIPH), CLK(MEMORY), CLK(DISPLAY), CLK(AUDIO), | |
100 | CLK(CGENERAL), CLK(DISPLAY2), CLK(OSC), CLK(NONE), | |
101 | MASK_BITS_31_29}, | |
102 | { CLK(PERIPH), CLK(CGENERAL), CLK(SFROM32KHZ), CLK(OSC), | |
103 | CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), | |
104 | MASK_BITS_31_28}, | |
96e82a25 SG |
105 | /* CLOCK_TYPE_DP */ |
106 | { CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), | |
107 | CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), | |
108 | MASK_BITS_31_28}, | |
52ef43b0 TW |
109 | |
110 | /* Additional clock types on Tegra114+ */ | |
111 | /* CLOCK_TYPE_PC2CC3M */ | |
112 | { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), | |
113 | CLK(MEMORY), CLK(NONE), CLK(NONE), CLK(NONE), | |
114 | MASK_BITS_31_29}, | |
115 | /* CLOCK_TYPE_PC2CC3S_T */ | |
116 | { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), | |
117 | CLK(SFROM32KHZ), CLK(NONE), CLK(OSC), CLK(NONE), | |
118 | MASK_BITS_31_29}, | |
119 | /* CLOCK_TYPE_PC2CC3M_T */ | |
120 | { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), | |
121 | CLK(MEMORY), CLK(NONE), CLK(OSC), CLK(NONE), | |
122 | MASK_BITS_31_29}, | |
123 | /* CLOCK_TYPE_PC2CC3M_T, w/16-bit divisor (I2C) */ | |
124 | { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), | |
125 | CLK(MEMORY), CLK(NONE), CLK(OSC), CLK(NONE), | |
126 | MASK_BITS_31_29}, | |
127 | /* CLOCK_TYPE_MC2CC3P_A */ | |
128 | { CLK(MEMORY), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), | |
129 | CLK(PERIPH), CLK(NONE), CLK(AUDIO), CLK(NONE), | |
130 | MASK_BITS_31_29}, | |
131 | /* CLOCK_TYPE_M */ | |
132 | { CLK(MEMORY), CLK(NONE), CLK(NONE), CLK(NONE), | |
133 | CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), | |
134 | MASK_BITS_31_30}, | |
135 | /* CLOCK_TYPE_MCPTM2C2C3 */ | |
136 | { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), | |
137 | CLK(MEMORY2), CLK(CGENERAL2), CLK(CGENERAL3), CLK(NONE), | |
138 | MASK_BITS_31_29}, | |
139 | /* CLOCK_TYPE_PC2CC3T_S */ | |
140 | { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), | |
141 | CLK(OSC), CLK(NONE), CLK(SFROM32KHZ), CLK(NONE), | |
142 | MASK_BITS_31_29}, | |
143 | /* CLOCK_TYPE_AC2CC3P_TS2 */ | |
144 | { CLK(AUDIO), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), | |
145 | CLK(PERIPH), CLK(NONE), CLK(OSC), CLK(SRC2), | |
146 | MASK_BITS_31_29}, | |
147 | }; | |
148 | ||
149 | /* | |
150 | * Clock type for each peripheral clock source. We put the name in each | |
151 | * record just so it is easy to match things up | |
152 | */ | |
153 | #define TYPE(name, type) type | |
154 | static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { | |
155 | /* 0x00 */ | |
156 | TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT), | |
157 | TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT), | |
158 | TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT), | |
159 | TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PC2CC3M), | |
160 | TYPE(PERIPHC_PWM, CLOCK_TYPE_PC2CC3S_T), | |
161 | TYPE(PERIPHC_05h, CLOCK_TYPE_NONE), | |
162 | TYPE(PERIPHC_SBC2, CLOCK_TYPE_PC2CC3M_T), | |
163 | TYPE(PERIPHC_SBC3, CLOCK_TYPE_PC2CC3M_T), | |
164 | ||
165 | /* 0x08 */ | |
166 | TYPE(PERIPHC_08h, CLOCK_TYPE_NONE), | |
167 | TYPE(PERIPHC_I2C1, CLOCK_TYPE_PC2CC3M_T16), | |
168 | TYPE(PERIPHC_I2C5, CLOCK_TYPE_PC2CC3M_T16), | |
169 | TYPE(PERIPHC_0bh, CLOCK_TYPE_NONE), | |
170 | TYPE(PERIPHC_0ch, CLOCK_TYPE_NONE), | |
171 | TYPE(PERIPHC_SBC1, CLOCK_TYPE_PC2CC3M_T), | |
172 | TYPE(PERIPHC_DISP1, CLOCK_TYPE_PMDACD2T), | |
173 | TYPE(PERIPHC_DISP2, CLOCK_TYPE_PMDACD2T), | |
174 | ||
175 | /* 0x10 */ | |
176 | TYPE(PERIPHC_10h, CLOCK_TYPE_NONE), | |
177 | TYPE(PERIPHC_11h, CLOCK_TYPE_NONE), | |
178 | TYPE(PERIPHC_VI, CLOCK_TYPE_MC2CC3P_A), | |
179 | TYPE(PERIPHC_13h, CLOCK_TYPE_NONE), | |
180 | TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PC2CC3M_T), | |
181 | TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PC2CC3M_T), | |
182 | TYPE(PERIPHC_16h, CLOCK_TYPE_NONE), | |
183 | TYPE(PERIPHC_17h, CLOCK_TYPE_NONE), | |
184 | ||
185 | /* 0x18 */ | |
186 | TYPE(PERIPHC_18h, CLOCK_TYPE_NONE), | |
187 | TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PC2CC3M_T), | |
188 | TYPE(PERIPHC_VFIR, CLOCK_TYPE_PC2CC3M_T), | |
189 | TYPE(PERIPHC_1Bh, CLOCK_TYPE_NONE), | |
190 | TYPE(PERIPHC_1Ch, CLOCK_TYPE_NONE), | |
191 | TYPE(PERIPHC_HSI, CLOCK_TYPE_PC2CC3M_T), | |
192 | TYPE(PERIPHC_UART1, CLOCK_TYPE_PC2CC3M_T), | |
193 | TYPE(PERIPHC_UART2, CLOCK_TYPE_PC2CC3M_T), | |
194 | ||
195 | /* 0x20 */ | |
196 | TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MC2CC3P_A), | |
197 | TYPE(PERIPHC_21h, CLOCK_TYPE_NONE), | |
198 | TYPE(PERIPHC_22h, CLOCK_TYPE_NONE), | |
199 | TYPE(PERIPHC_HDMI, CLOCK_TYPE_PMDACD2T), | |
200 | TYPE(PERIPHC_24h, CLOCK_TYPE_NONE), | |
201 | TYPE(PERIPHC_25h, CLOCK_TYPE_NONE), | |
202 | TYPE(PERIPHC_I2C2, CLOCK_TYPE_PC2CC3M_T16), | |
203 | TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPTM2C2C3), | |
204 | ||
205 | /* 0x28 */ | |
206 | TYPE(PERIPHC_UART3, CLOCK_TYPE_PC2CC3M_T), | |
207 | TYPE(PERIPHC_29h, CLOCK_TYPE_NONE), | |
208 | TYPE(PERIPHC_VI_SENSOR, CLOCK_TYPE_MC2CC3P_A), | |
209 | TYPE(PERIPHC_2bh, CLOCK_TYPE_NONE), | |
210 | TYPE(PERIPHC_2ch, CLOCK_TYPE_NONE), | |
211 | TYPE(PERIPHC_SBC4, CLOCK_TYPE_PC2CC3M_T), | |
212 | TYPE(PERIPHC_I2C3, CLOCK_TYPE_PC2CC3M_T16), | |
213 | TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PC2CC3M_T), | |
214 | ||
215 | /* 0x30 */ | |
216 | TYPE(PERIPHC_UART4, CLOCK_TYPE_PC2CC3M_T), | |
217 | TYPE(PERIPHC_UART5, CLOCK_TYPE_PC2CC3M_T), | |
218 | TYPE(PERIPHC_VDE, CLOCK_TYPE_PC2CC3M_T), | |
219 | TYPE(PERIPHC_OWR, CLOCK_TYPE_PC2CC3M_T), | |
220 | TYPE(PERIPHC_NOR, CLOCK_TYPE_PC2CC3M_T), | |
221 | TYPE(PERIPHC_CSITE, CLOCK_TYPE_PC2CC3M_T), | |
222 | TYPE(PERIPHC_I2S0, CLOCK_TYPE_AXPT), | |
223 | TYPE(PERIPHC_DTV, CLOCK_TYPE_NONE), | |
224 | ||
225 | /* 0x38 */ | |
226 | TYPE(PERIPHC_38h, CLOCK_TYPE_NONE), | |
227 | TYPE(PERIPHC_39h, CLOCK_TYPE_NONE), | |
228 | TYPE(PERIPHC_3ah, CLOCK_TYPE_NONE), | |
229 | TYPE(PERIPHC_3bh, CLOCK_TYPE_NONE), | |
230 | TYPE(PERIPHC_MSENC, CLOCK_TYPE_MC2CC3P_A), | |
231 | TYPE(PERIPHC_TSEC, CLOCK_TYPE_PC2CC3M_T), | |
232 | TYPE(PERIPHC_3eh, CLOCK_TYPE_NONE), | |
233 | TYPE(PERIPHC_OSC, CLOCK_TYPE_NONE), | |
234 | ||
235 | /* 0x40 */ | |
236 | TYPE(PERIPHC_40h, CLOCK_TYPE_NONE), /* start with 0x3b0 */ | |
237 | TYPE(PERIPHC_MSELECT, CLOCK_TYPE_PC2CC3M_T), | |
238 | TYPE(PERIPHC_TSENSOR, CLOCK_TYPE_PC2CC3T_S), | |
239 | TYPE(PERIPHC_I2S3, CLOCK_TYPE_AXPT), | |
240 | TYPE(PERIPHC_I2S4, CLOCK_TYPE_AXPT), | |
241 | TYPE(PERIPHC_I2C4, CLOCK_TYPE_PC2CC3M_T16), | |
242 | TYPE(PERIPHC_SBC5, CLOCK_TYPE_PC2CC3M_T), | |
243 | TYPE(PERIPHC_SBC6, CLOCK_TYPE_PC2CC3M_T), | |
244 | ||
245 | /* 0x48 */ | |
246 | TYPE(PERIPHC_AUDIO, CLOCK_TYPE_AC2CC3P_TS2), | |
247 | TYPE(PERIPHC_49h, CLOCK_TYPE_NONE), | |
248 | TYPE(PERIPHC_DAM0, CLOCK_TYPE_AC2CC3P_TS2), | |
249 | TYPE(PERIPHC_DAM1, CLOCK_TYPE_AC2CC3P_TS2), | |
250 | TYPE(PERIPHC_DAM2, CLOCK_TYPE_AC2CC3P_TS2), | |
251 | TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PC2CC3M_T), | |
252 | TYPE(PERIPHC_ACTMON, CLOCK_TYPE_PC2CC3S_T), | |
253 | TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE), | |
254 | ||
255 | /* 0x50 */ | |
256 | TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE), | |
257 | TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE), | |
258 | TYPE(PERIPHC_52h, CLOCK_TYPE_NONE), | |
259 | TYPE(PERIPHC_I2CSLOW, CLOCK_TYPE_PC2CC3S_T), | |
260 | TYPE(PERIPHC_SYS, CLOCK_TYPE_NONE), | |
261 | TYPE(PERIPHC_55h, CLOCK_TYPE_NONE), | |
262 | TYPE(PERIPHC_56h, CLOCK_TYPE_NONE), | |
263 | TYPE(PERIPHC_57h, CLOCK_TYPE_NONE), | |
264 | ||
265 | /* 0x58 */ | |
266 | TYPE(PERIPHC_58h, CLOCK_TYPE_NONE), | |
96e82a25 | 267 | TYPE(PERIPHC_SOR, CLOCK_TYPE_NONE), |
52ef43b0 TW |
268 | TYPE(PERIPHC_5ah, CLOCK_TYPE_NONE), |
269 | TYPE(PERIPHC_5bh, CLOCK_TYPE_NONE), | |
270 | TYPE(PERIPHC_SATAOOB, CLOCK_TYPE_PCMT), | |
271 | TYPE(PERIPHC_SATA, CLOCK_TYPE_PCMT), | |
272 | TYPE(PERIPHC_HDA, CLOCK_TYPE_PC2CC3M_T), | |
273 | TYPE(PERIPHC_5fh, CLOCK_TYPE_NONE), | |
274 | ||
275 | /* 0x60 */ | |
276 | TYPE(PERIPHC_XUSB_CORE_HOST, CLOCK_TYPE_NONE), | |
277 | TYPE(PERIPHC_XUSB_FALCON, CLOCK_TYPE_NONE), | |
278 | TYPE(PERIPHC_XUSB_FS, CLOCK_TYPE_NONE), | |
279 | TYPE(PERIPHC_XUSB_CORE_DEV, CLOCK_TYPE_NONE), | |
280 | TYPE(PERIPHC_XUSB_SS, CLOCK_TYPE_NONE), | |
281 | TYPE(PERIPHC_CILAB, CLOCK_TYPE_NONE), | |
282 | TYPE(PERIPHC_CILCD, CLOCK_TYPE_NONE), | |
283 | TYPE(PERIPHC_CILE, CLOCK_TYPE_NONE), | |
284 | ||
285 | /* 0x68 */ | |
286 | TYPE(PERIPHC_DSIA_LP, CLOCK_TYPE_NONE), | |
287 | TYPE(PERIPHC_DSIB_LP, CLOCK_TYPE_NONE), | |
288 | TYPE(PERIPHC_ENTROPY, CLOCK_TYPE_NONE), | |
289 | TYPE(PERIPHC_DVFS_REF, CLOCK_TYPE_NONE), | |
290 | TYPE(PERIPHC_DVFS_SOC, CLOCK_TYPE_NONE), | |
291 | TYPE(PERIPHC_TRACECLKIN, CLOCK_TYPE_NONE), | |
292 | TYPE(PERIPHC_ADX0, CLOCK_TYPE_NONE), | |
293 | TYPE(PERIPHC_AMX0, CLOCK_TYPE_NONE), | |
294 | ||
295 | /* 0x70 */ | |
296 | TYPE(PERIPHC_EMC_LATENCY, CLOCK_TYPE_NONE), | |
297 | TYPE(PERIPHC_SOC_THERM, CLOCK_TYPE_NONE), | |
298 | TYPE(PERIPHC_72h, CLOCK_TYPE_NONE), | |
299 | TYPE(PERIPHC_73h, CLOCK_TYPE_NONE), | |
300 | TYPE(PERIPHC_74h, CLOCK_TYPE_NONE), | |
301 | TYPE(PERIPHC_75h, CLOCK_TYPE_NONE), | |
302 | TYPE(PERIPHC_VI_SENSOR2, CLOCK_TYPE_NONE), | |
303 | TYPE(PERIPHC_I2C6, CLOCK_TYPE_PC2CC3M_T16), | |
304 | ||
305 | /* 0x78 */ | |
306 | TYPE(PERIPHC_78h, CLOCK_TYPE_NONE), | |
307 | TYPE(PERIPHC_EMC_DLL, CLOCK_TYPE_MCPTM2C2C3), | |
308 | TYPE(PERIPHC_HDMI_AUDIO, CLOCK_TYPE_NONE), | |
309 | TYPE(PERIPHC_CLK72MHZ, CLOCK_TYPE_NONE), | |
310 | TYPE(PERIPHC_ADX1, CLOCK_TYPE_AC2CC3P_TS2), | |
311 | TYPE(PERIPHC_AMX1, CLOCK_TYPE_AC2CC3P_TS2), | |
312 | TYPE(PERIPHC_VIC, CLOCK_TYPE_NONE), | |
313 | TYPE(PERIPHC_7Fh, CLOCK_TYPE_NONE), | |
314 | }; | |
315 | ||
316 | /* | |
317 | * This array translates a periph_id to a periphc_internal_id | |
318 | * | |
319 | * Not present/matched up: | |
320 | * uint vi_sensor; _VI_SENSOR_0, 0x1A8 | |
321 | * SPDIF - which is both 0x08 and 0x0c | |
322 | * | |
323 | */ | |
324 | #define NONE(name) (-1) | |
325 | #define OFFSET(name, value) PERIPHC_ ## name | |
326 | static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { | |
327 | /* Low word: 31:0 */ | |
328 | NONE(CPU), | |
329 | NONE(COP), | |
330 | NONE(TRIGSYS), | |
331 | NONE(ISPB), | |
332 | NONE(RESERVED4), | |
333 | NONE(TMR), | |
334 | PERIPHC_UART1, | |
335 | PERIPHC_UART2, /* and vfir 0x68 */ | |
336 | ||
337 | /* 8 */ | |
338 | NONE(GPIO), | |
339 | PERIPHC_SDMMC2, | |
340 | PERIPHC_SPDIF_IN, | |
341 | PERIPHC_I2S1, | |
342 | PERIPHC_I2C1, | |
343 | NONE(RESERVED13), | |
344 | PERIPHC_SDMMC1, | |
345 | PERIPHC_SDMMC4, | |
346 | ||
347 | /* 16 */ | |
348 | NONE(TCW), | |
349 | PERIPHC_PWM, | |
350 | PERIPHC_I2S2, | |
351 | NONE(RESERVED19), | |
352 | PERIPHC_VI, | |
353 | NONE(RESERVED21), | |
354 | NONE(USBD), | |
355 | NONE(ISP), | |
356 | ||
357 | /* 24 */ | |
358 | NONE(RESERVED24), | |
359 | NONE(RESERVED25), | |
360 | PERIPHC_DISP2, | |
361 | PERIPHC_DISP1, | |
362 | PERIPHC_HOST1X, | |
363 | NONE(VCP), | |
364 | PERIPHC_I2S0, | |
365 | NONE(CACHE2), | |
366 | ||
367 | /* Middle word: 63:32 */ | |
368 | NONE(MEM), | |
369 | NONE(AHBDMA), | |
370 | NONE(APBDMA), | |
371 | NONE(RESERVED35), | |
372 | NONE(RESERVED36), | |
373 | NONE(STAT_MON), | |
374 | NONE(RESERVED38), | |
375 | NONE(FUSE), | |
376 | ||
377 | /* 40 */ | |
378 | NONE(KFUSE), | |
379 | PERIPHC_SBC1, /* SBCx = SPIx */ | |
380 | PERIPHC_NOR, | |
381 | NONE(RESERVED43), | |
382 | PERIPHC_SBC2, | |
383 | NONE(XIO), | |
384 | PERIPHC_SBC3, | |
385 | PERIPHC_I2C5, | |
386 | ||
387 | /* 48 */ | |
388 | NONE(DSI), | |
389 | NONE(RESERVED49), | |
390 | PERIPHC_HSI, | |
391 | PERIPHC_HDMI, | |
392 | NONE(CSI), | |
393 | NONE(RESERVED53), | |
394 | PERIPHC_I2C2, | |
395 | PERIPHC_UART3, | |
396 | ||
397 | /* 56 */ | |
398 | NONE(MIPI_CAL), | |
399 | PERIPHC_EMC, | |
400 | NONE(USB2), | |
401 | NONE(USB3), | |
402 | NONE(RESERVED60), | |
403 | PERIPHC_VDE, | |
404 | NONE(BSEA), | |
405 | NONE(BSEV), | |
406 | ||
407 | /* Upper word 95:64 */ | |
408 | NONE(RESERVED64), | |
409 | PERIPHC_UART4, | |
410 | PERIPHC_UART5, | |
411 | PERIPHC_I2C3, | |
412 | PERIPHC_SBC4, | |
413 | PERIPHC_SDMMC3, | |
414 | NONE(PCIE), | |
415 | PERIPHC_OWR, | |
416 | ||
417 | /* 72 */ | |
418 | NONE(AFI), | |
419 | PERIPHC_CSITE, | |
420 | NONE(PCIEXCLK), | |
421 | NONE(AVPUCQ), | |
422 | NONE(LA), | |
423 | NONE(TRACECLKIN), | |
424 | NONE(SOC_THERM), | |
425 | NONE(DTV), | |
426 | ||
427 | /* 80 */ | |
428 | NONE(RESERVED80), | |
429 | PERIPHC_I2CSLOW, | |
430 | NONE(DSIB), | |
431 | PERIPHC_TSEC, | |
432 | NONE(RESERVED84), | |
433 | NONE(RESERVED85), | |
434 | NONE(RESERVED86), | |
435 | NONE(EMUCIF), | |
436 | ||
437 | /* 88 */ | |
438 | NONE(RESERVED88), | |
439 | NONE(XUSB_HOST), | |
440 | NONE(RESERVED90), | |
441 | PERIPHC_MSENC, | |
442 | NONE(RESERVED92), | |
443 | NONE(RESERVED93), | |
444 | NONE(RESERVED94), | |
445 | NONE(XUSB_DEV), | |
446 | ||
447 | /* V word: 31:0 */ | |
448 | NONE(CPUG), | |
449 | NONE(CPULP), | |
450 | NONE(V_RESERVED2), | |
451 | PERIPHC_MSELECT, | |
452 | NONE(V_RESERVED4), | |
453 | PERIPHC_I2S3, | |
454 | PERIPHC_I2S4, | |
455 | PERIPHC_I2C4, | |
456 | ||
457 | /* 104 */ | |
458 | PERIPHC_SBC5, | |
459 | PERIPHC_SBC6, | |
460 | PERIPHC_AUDIO, | |
461 | NONE(APBIF), | |
462 | PERIPHC_DAM0, | |
463 | PERIPHC_DAM1, | |
464 | PERIPHC_DAM2, | |
465 | PERIPHC_HDA2CODEC2X, | |
466 | ||
467 | /* 112 */ | |
468 | NONE(ATOMICS), | |
469 | NONE(V_RESERVED17), | |
470 | NONE(V_RESERVED18), | |
471 | NONE(V_RESERVED19), | |
472 | NONE(V_RESERVED20), | |
473 | NONE(V_RESERVED21), | |
474 | NONE(V_RESERVED22), | |
475 | PERIPHC_ACTMON, | |
476 | ||
477 | /* 120 */ | |
057772b7 | 478 | PERIPHC_EXTPERIPH1, |
52ef43b0 TW |
479 | NONE(EXTPERIPH2), |
480 | NONE(EXTPERIPH3), | |
481 | NONE(OOB), | |
482 | PERIPHC_SATA, | |
483 | PERIPHC_HDA, | |
484 | NONE(TZRAM), | |
485 | NONE(SE), | |
486 | ||
487 | /* W word: 31:0 */ | |
488 | NONE(HDA2HDMICODEC), | |
489 | NONE(SATACOLD), | |
490 | NONE(W_RESERVED2), | |
491 | NONE(W_RESERVED3), | |
492 | NONE(W_RESERVED4), | |
493 | NONE(W_RESERVED5), | |
494 | NONE(W_RESERVED6), | |
495 | NONE(W_RESERVED7), | |
496 | ||
497 | /* 136 */ | |
498 | NONE(CEC), | |
499 | NONE(W_RESERVED9), | |
500 | NONE(W_RESERVED10), | |
501 | NONE(W_RESERVED11), | |
502 | NONE(W_RESERVED12), | |
503 | NONE(W_RESERVED13), | |
504 | NONE(XUSB_PADCTL), | |
505 | NONE(W_RESERVED15), | |
506 | ||
507 | /* 144 */ | |
508 | NONE(W_RESERVED16), | |
509 | NONE(W_RESERVED17), | |
510 | NONE(W_RESERVED18), | |
511 | NONE(W_RESERVED19), | |
512 | NONE(W_RESERVED20), | |
513 | NONE(ENTROPY), | |
514 | NONE(DDS), | |
515 | NONE(W_RESERVED23), | |
516 | ||
517 | /* 152 */ | |
518 | NONE(DP2), | |
519 | NONE(AMX0), | |
520 | NONE(ADX0), | |
521 | NONE(DVFS), | |
522 | NONE(XUSB_SS), | |
523 | NONE(W_RESERVED29), | |
524 | NONE(W_RESERVED30), | |
525 | NONE(W_RESERVED31), | |
526 | ||
527 | /* X word: 31:0 */ | |
528 | NONE(SPARE), | |
529 | NONE(X_RESERVED1), | |
530 | NONE(X_RESERVED2), | |
531 | NONE(X_RESERVED3), | |
532 | NONE(CAM_MCLK), | |
533 | NONE(CAM_MCLK2), | |
534 | PERIPHC_I2C6, | |
535 | NONE(X_RESERVED7), | |
536 | ||
537 | /* 168 */ | |
538 | NONE(X_RESERVED8), | |
539 | NONE(X_RESERVED9), | |
540 | NONE(X_RESERVED10), | |
541 | NONE(VIM2_CLK), | |
542 | NONE(X_RESERVED12), | |
543 | NONE(X_RESERVED13), | |
544 | NONE(EMC_DLL), | |
545 | NONE(X_RESERVED15), | |
546 | ||
547 | /* 176 */ | |
548 | NONE(HDMI_AUDIO), | |
549 | NONE(CLK72MHZ), | |
550 | NONE(VIC), | |
551 | NONE(X_RESERVED19), | |
552 | NONE(ADX1), | |
553 | NONE(DPAUX), | |
96e82a25 | 554 | PERIPHC_SOR, |
52ef43b0 TW |
555 | NONE(X_RESERVED23), |
556 | ||
557 | /* 184 */ | |
558 | NONE(GPU), | |
559 | NONE(AMX1), | |
560 | NONE(X_RESERVED26), | |
561 | NONE(X_RESERVED27), | |
562 | NONE(X_RESERVED28), | |
563 | NONE(X_RESERVED29), | |
564 | NONE(X_RESERVED30), | |
565 | NONE(X_RESERVED31), | |
566 | }; | |
567 | ||
722e000c TW |
568 | /* |
569 | * PLL divider shift/mask tables for all PLL IDs. | |
570 | */ | |
571 | struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = { | |
572 | /* | |
5a30cee5 | 573 | * T124: same as T114, some deviations from T2x/T30. Adds PLLDP. |
722e000c TW |
574 | * NOTE: If kcp_mask/kvco_mask == 0, they're not used in that PLL (PLLX, etc.) |
575 | * If lock_ena or lock_det are >31, they're not used in that PLL. | |
576 | */ | |
577 | ||
578 | { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF, .p_shift = 20, .p_mask = 0x0F, | |
579 | .lock_ena = 24, .lock_det = 27, .kcp_shift = 28, .kcp_mask = 3, .kvco_shift = 27, .kvco_mask = 1 }, /* PLLC */ | |
580 | { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF, .p_shift = 0, .p_mask = 0, | |
581 | .lock_ena = 0, .lock_det = 27, .kcp_shift = 1, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 }, /* PLLM */ | |
582 | { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | |
583 | .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF }, /* PLLP */ | |
584 | { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | |
585 | .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF }, /* PLLA */ | |
586 | { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x01, | |
587 | .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF }, /* PLLU */ | |
588 | { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | |
589 | .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF }, /* PLLD */ | |
590 | { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF, .p_shift = 20, .p_mask = 0x0F, | |
591 | .lock_ena = 18, .lock_det = 27, .kcp_shift = 0, .kcp_mask = 0, .kvco_shift = 0, .kvco_mask = 0 }, /* PLLX */ | |
592 | { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF, .p_shift = 0, .p_mask = 0, | |
593 | .lock_ena = 9, .lock_det = 11, .kcp_shift = 6, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 }, /* PLLE */ | |
594 | { .m_shift = 0, .m_mask = 0x0F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, | |
595 | .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF }, /* PLLS (RESERVED) */ | |
5a30cee5 SG |
596 | { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF, .p_shift = 20, .p_mask = 0xF, |
597 | .lock_ena = 30, .lock_det = 27, .kcp_shift = 25, .kcp_mask = 3, .kvco_shift = 24, .kvco_mask = 1 }, /* PLLDP */ | |
722e000c TW |
598 | }; |
599 | ||
52ef43b0 TW |
600 | /* |
601 | * Get the oscillator frequency, from the corresponding hardware configuration | |
602 | * field. Note that Tegra30+ support 3 new higher freqs, but we map back | |
603 | * to the old T20 freqs. Support for the higher oscillators is TBD. | |
604 | */ | |
605 | enum clock_osc_freq clock_get_osc_freq(void) | |
606 | { | |
607 | struct clk_rst_ctlr *clkrst = | |
608 | (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | |
609 | u32 reg; | |
610 | ||
611 | reg = readl(&clkrst->crc_osc_ctrl); | |
612 | reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; | |
613 | ||
614 | if (reg & 1) /* one of the newer freqs */ | |
615 | printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg); | |
616 | ||
617 | return reg >> 2; /* Map to most common (T20) freqs */ | |
618 | } | |
619 | ||
620 | /* Returns a pointer to the clock source register for a peripheral */ | |
621 | u32 *get_periph_source_reg(enum periph_id periph_id) | |
622 | { | |
623 | struct clk_rst_ctlr *clkrst = | |
624 | (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | |
625 | enum periphc_internal_id internal_id; | |
626 | ||
627 | /* Coresight is a special case */ | |
628 | if (periph_id == PERIPH_ID_CSI) | |
629 | return &clkrst->crc_clk_src[PERIPH_ID_CSI+1]; | |
630 | ||
631 | assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT); | |
632 | internal_id = periph_id_to_internal_id[periph_id]; | |
633 | assert(internal_id != -1); | |
96e82a25 SG |
634 | if (internal_id >= PERIPHC_X_FIRST) { |
635 | internal_id -= PERIPHC_X_FIRST; | |
636 | return &clkrst->crc_clk_src_x[internal_id]; | |
637 | } else if (internal_id >= PERIPHC_VW_FIRST) { | |
52ef43b0 TW |
638 | internal_id -= PERIPHC_VW_FIRST; |
639 | return &clkrst->crc_clk_src_vw[internal_id]; | |
640 | } else { | |
641 | return &clkrst->crc_clk_src[internal_id]; | |
642 | } | |
643 | } | |
644 | ||
645 | /** | |
646 | * Given a peripheral ID and the required source clock, this returns which | |
647 | * value should be programmed into the source mux for that peripheral. | |
648 | * | |
649 | * There is special code here to handle the one source type with 5 sources. | |
650 | * | |
651 | * @param periph_id peripheral to start | |
652 | * @param source PLL id of required parent clock | |
653 | * @param mux_bits Set to number of bits in mux register: 2 or 4 | |
654 | * @param divider_bits Set to number of divider bits (8 or 16) | |
655 | * @return mux value (0-4, or -1 if not found) | |
656 | */ | |
657 | int get_periph_clock_source(enum periph_id periph_id, | |
658 | enum clock_id parent, int *mux_bits, int *divider_bits) | |
659 | { | |
660 | enum clock_type_id type; | |
661 | enum periphc_internal_id internal_id; | |
662 | int mux; | |
663 | ||
664 | assert(clock_periph_id_isvalid(periph_id)); | |
665 | ||
666 | internal_id = periph_id_to_internal_id[periph_id]; | |
667 | assert(periphc_internal_id_isvalid(internal_id)); | |
668 | ||
669 | type = clock_periph_type[internal_id]; | |
670 | assert(clock_type_id_isvalid(type)); | |
671 | ||
672 | *mux_bits = clock_source[type][CLOCK_MAX_MUX]; | |
673 | ||
674 | if (type == CLOCK_TYPE_PC2CC3M_T16) | |
675 | *divider_bits = 16; | |
676 | else | |
677 | *divider_bits = 8; | |
678 | ||
679 | for (mux = 0; mux < CLOCK_MAX_MUX; mux++) | |
680 | if (clock_source[type][mux] == parent) | |
681 | return mux; | |
682 | ||
683 | /* if we get here, either us or the caller has made a mistake */ | |
684 | printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id, | |
685 | parent); | |
686 | return -1; | |
687 | } | |
688 | ||
689 | void clock_set_enable(enum periph_id periph_id, int enable) | |
690 | { | |
691 | struct clk_rst_ctlr *clkrst = | |
692 | (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | |
693 | u32 *clk; | |
694 | u32 reg; | |
695 | ||
696 | /* Enable/disable the clock to this peripheral */ | |
697 | assert(clock_periph_id_isvalid(periph_id)); | |
698 | if ((int)periph_id < (int)PERIPH_ID_VW_FIRST) | |
699 | clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)]; | |
96e82a25 | 700 | else if ((int)periph_id < PERIPH_ID_X_FIRST) |
52ef43b0 | 701 | clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)]; |
96e82a25 SG |
702 | else |
703 | clk = &clkrst->crc_clk_out_enb_x; | |
52ef43b0 TW |
704 | reg = readl(clk); |
705 | if (enable) | |
706 | reg |= PERIPH_MASK(periph_id); | |
707 | else | |
708 | reg &= ~PERIPH_MASK(periph_id); | |
709 | writel(reg, clk); | |
710 | } | |
711 | ||
712 | void reset_set_enable(enum periph_id periph_id, int enable) | |
713 | { | |
714 | struct clk_rst_ctlr *clkrst = | |
715 | (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | |
716 | u32 *reset; | |
717 | u32 reg; | |
718 | ||
719 | /* Enable/disable reset to the peripheral */ | |
720 | assert(clock_periph_id_isvalid(periph_id)); | |
721 | if (periph_id < PERIPH_ID_VW_FIRST) | |
722 | reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)]; | |
96e82a25 | 723 | else if ((int)periph_id < PERIPH_ID_X_FIRST) |
52ef43b0 | 724 | reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)]; |
96e82a25 SG |
725 | else |
726 | reset = &clkrst->crc_rst_devices_x; | |
52ef43b0 TW |
727 | reg = readl(reset); |
728 | if (enable) | |
729 | reg |= PERIPH_MASK(periph_id); | |
730 | else | |
731 | reg &= ~PERIPH_MASK(periph_id); | |
732 | writel(reg, reset); | |
733 | } | |
734 | ||
0f925822 | 735 | #if CONFIG_IS_ENABLED(OF_CONTROL) |
52ef43b0 TW |
736 | /* |
737 | * Convert a device tree clock ID to our peripheral ID. They are mostly | |
738 | * the same but we are very cautious so we check that a valid clock ID is | |
739 | * provided. | |
740 | * | |
741 | * @param clk_id Clock ID according to tegra124 device tree binding | |
742 | * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid | |
743 | */ | |
744 | enum periph_id clk_id_to_periph_id(int clk_id) | |
745 | { | |
746 | if (clk_id > PERIPH_ID_COUNT) | |
747 | return PERIPH_ID_NONE; | |
748 | ||
749 | switch (clk_id) { | |
750 | case PERIPH_ID_RESERVED4: | |
751 | case PERIPH_ID_RESERVED25: | |
752 | case PERIPH_ID_RESERVED35: | |
753 | case PERIPH_ID_RESERVED36: | |
754 | case PERIPH_ID_RESERVED38: | |
755 | case PERIPH_ID_RESERVED43: | |
756 | case PERIPH_ID_RESERVED49: | |
757 | case PERIPH_ID_RESERVED53: | |
758 | case PERIPH_ID_RESERVED64: | |
759 | case PERIPH_ID_RESERVED84: | |
760 | case PERIPH_ID_RESERVED85: | |
761 | case PERIPH_ID_RESERVED86: | |
762 | case PERIPH_ID_RESERVED88: | |
763 | case PERIPH_ID_RESERVED90: | |
764 | case PERIPH_ID_RESERVED92: | |
765 | case PERIPH_ID_RESERVED93: | |
766 | case PERIPH_ID_RESERVED94: | |
767 | case PERIPH_ID_V_RESERVED2: | |
768 | case PERIPH_ID_V_RESERVED4: | |
769 | case PERIPH_ID_V_RESERVED17: | |
770 | case PERIPH_ID_V_RESERVED18: | |
771 | case PERIPH_ID_V_RESERVED19: | |
772 | case PERIPH_ID_V_RESERVED20: | |
773 | case PERIPH_ID_V_RESERVED21: | |
774 | case PERIPH_ID_V_RESERVED22: | |
775 | case PERIPH_ID_W_RESERVED2: | |
776 | case PERIPH_ID_W_RESERVED3: | |
777 | case PERIPH_ID_W_RESERVED4: | |
778 | case PERIPH_ID_W_RESERVED5: | |
779 | case PERIPH_ID_W_RESERVED6: | |
780 | case PERIPH_ID_W_RESERVED7: | |
781 | case PERIPH_ID_W_RESERVED9: | |
782 | case PERIPH_ID_W_RESERVED10: | |
783 | case PERIPH_ID_W_RESERVED11: | |
784 | case PERIPH_ID_W_RESERVED12: | |
785 | case PERIPH_ID_W_RESERVED13: | |
786 | case PERIPH_ID_W_RESERVED15: | |
787 | case PERIPH_ID_W_RESERVED16: | |
788 | case PERIPH_ID_W_RESERVED17: | |
789 | case PERIPH_ID_W_RESERVED18: | |
790 | case PERIPH_ID_W_RESERVED19: | |
791 | case PERIPH_ID_W_RESERVED20: | |
792 | case PERIPH_ID_W_RESERVED23: | |
793 | case PERIPH_ID_W_RESERVED29: | |
794 | case PERIPH_ID_W_RESERVED30: | |
795 | case PERIPH_ID_W_RESERVED31: | |
796 | return PERIPH_ID_NONE; | |
797 | default: | |
798 | return clk_id; | |
799 | } | |
800 | } | |
0f925822 | 801 | #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ |
52ef43b0 TW |
802 | |
803 | void clock_early_init(void) | |
804 | { | |
805 | struct clk_rst_ctlr *clkrst = | |
806 | (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | |
722e000c TW |
807 | struct clk_pll_info *pllinfo; |
808 | u32 data; | |
52ef43b0 TW |
809 | |
810 | tegra30_set_up_pllp(); | |
811 | ||
aba11d44 TR |
812 | /* clear IDDQ before accessing any other PLLC registers */ |
813 | pllinfo = &tegra_pll_info_table[CLOCK_ID_CGENERAL]; | |
814 | clrbits_le32(&clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc, PLLC_IDDQ); | |
815 | udelay(2); | |
816 | ||
52ef43b0 TW |
817 | /* |
818 | * PLLC output frequency set to 600Mhz | |
819 | * PLLD output frequency set to 925Mhz | |
820 | */ | |
821 | switch (clock_get_osc_freq()) { | |
822 | case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ | |
823 | clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8); | |
824 | clock_set_rate(CLOCK_ID_DISPLAY, 925, 12, 0, 12); | |
825 | break; | |
826 | ||
827 | case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ | |
828 | clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8); | |
829 | clock_set_rate(CLOCK_ID_DISPLAY, 925, 26, 0, 12); | |
830 | break; | |
831 | ||
832 | case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ | |
833 | clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); | |
834 | clock_set_rate(CLOCK_ID_DISPLAY, 925, 13, 0, 12); | |
835 | break; | |
836 | case CLOCK_OSC_FREQ_19_2: | |
837 | default: | |
838 | /* | |
839 | * These are not supported. It is too early to print a | |
840 | * message and the UART likely won't work anyway due to the | |
841 | * oscillator being wrong. | |
842 | */ | |
843 | break; | |
844 | } | |
845 | ||
846 | /* PLLC_MISC2: Set dynramp_stepA/B. MISC2 maps to pll_out[1] */ | |
847 | writel(0x00561600, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_out[1]); | |
848 | ||
849 | /* PLLC_MISC: Set LOCK_ENABLE */ | |
722e000c TW |
850 | pllinfo = &tegra_pll_info_table[CLOCK_ID_CGENERAL]; |
851 | setbits_le32(&clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc, (1 << pllinfo->lock_ena)); | |
52ef43b0 TW |
852 | udelay(2); |
853 | ||
722e000c TW |
854 | /* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1, and enable lock */ |
855 | pllinfo = &tegra_pll_info_table[CLOCK_ID_DISPLAY]; | |
856 | data = (12 << pllinfo->kcp_shift) | (1 << pllinfo->kvco_shift); | |
857 | data |= (1 << PLLD_CLKENABLE) | (1 << pllinfo->lock_ena); | |
858 | writel(data, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc); | |
52ef43b0 TW |
859 | udelay(2); |
860 | } | |
861 | ||
862 | void arch_timer_init(void) | |
863 | { | |
864 | struct sysctr_ctlr *sysctr = (struct sysctr_ctlr *)NV_PA_TSC_BASE; | |
865 | u32 freq, val; | |
866 | ||
97c02d87 TR |
867 | freq = clock_get_rate(CLOCK_ID_CLK_M); |
868 | debug("%s: clk_m freq is %dHz [0x%08X]\n", __func__, freq, freq); | |
52ef43b0 TW |
869 | |
870 | /* ARM CNTFRQ */ | |
871 | asm("mcr p15, 0, %0, c14, c0, 0\n" : : "r" (freq)); | |
872 | ||
873 | /* Only Tegra114+ has the System Counter regs */ | |
874 | debug("%s: setting CNTFID0 to 0x%08X\n", __func__, freq); | |
875 | writel(freq, &sysctr->cntfid0); | |
876 | ||
877 | val = readl(&sysctr->cntcr); | |
878 | val |= TSC_CNTCR_ENABLE | TSC_CNTCR_HDBG; | |
879 | writel(val, &sysctr->cntcr); | |
880 | debug("%s: TSC CNTCR = 0x%08X\n", __func__, val); | |
881 | } | |
a7230745 TR |
882 | |
883 | #define PLLE_SS_CNTL 0x68 | |
884 | #define PLLE_SS_CNTL_SSCINCINTR(x) (((x) & 0x3f) << 24) | |
885 | #define PLLE_SS_CNTL_SSCINC(x) (((x) & 0xff) << 16) | |
886 | #define PLLE_SS_CNTL_SSCINVERT (1 << 15) | |
887 | #define PLLE_SS_CNTL_SSCCENTER (1 << 14) | |
888 | #define PLLE_SS_CNTL_SSCBYP (1 << 12) | |
889 | #define PLLE_SS_CNTL_INTERP_RESET (1 << 11) | |
890 | #define PLLE_SS_CNTL_BYPASS_SS (1 << 10) | |
891 | #define PLLE_SS_CNTL_SSCMAX(x) (((x) & 0x1ff) << 0) | |
892 | ||
893 | #define PLLE_BASE 0x0e8 | |
894 | #define PLLE_BASE_ENABLE (1 << 30) | |
895 | #define PLLE_BASE_LOCK_OVERRIDE (1 << 29) | |
896 | #define PLLE_BASE_PLDIV_CML(x) (((x) & 0xf) << 24) | |
897 | #define PLLE_BASE_NDIV(x) (((x) & 0xff) << 8) | |
898 | #define PLLE_BASE_MDIV(x) (((x) & 0xff) << 0) | |
899 | ||
900 | #define PLLE_MISC 0x0ec | |
901 | #define PLLE_MISC_IDDQ_SWCTL (1 << 14) | |
902 | #define PLLE_MISC_IDDQ_OVERRIDE (1 << 13) | |
903 | #define PLLE_MISC_LOCK_ENABLE (1 << 9) | |
904 | #define PLLE_MISC_PTS (1 << 8) | |
905 | #define PLLE_MISC_VREG_BG_CTRL(x) (((x) & 0x3) << 4) | |
906 | #define PLLE_MISC_VREG_CTRL(x) (((x) & 0x3) << 2) | |
907 | ||
908 | #define PLLE_AUX 0x48c | |
909 | #define PLLE_AUX_SEQ_ENABLE (1 << 24) | |
910 | #define PLLE_AUX_ENABLE_SWCTL (1 << 4) | |
911 | ||
912 | int tegra_plle_enable(void) | |
913 | { | |
914 | unsigned int m = 1, n = 200, cpcon = 13; | |
915 | u32 value; | |
916 | ||
917 | value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); | |
918 | value &= ~PLLE_BASE_LOCK_OVERRIDE; | |
919 | writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); | |
920 | ||
921 | value = readl(NV_PA_CLK_RST_BASE + PLLE_AUX); | |
922 | value |= PLLE_AUX_ENABLE_SWCTL; | |
923 | value &= ~PLLE_AUX_SEQ_ENABLE; | |
924 | writel(value, NV_PA_CLK_RST_BASE + PLLE_AUX); | |
925 | ||
926 | udelay(1); | |
927 | ||
928 | value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); | |
929 | value |= PLLE_MISC_IDDQ_SWCTL; | |
930 | value &= ~PLLE_MISC_IDDQ_OVERRIDE; | |
931 | value |= PLLE_MISC_LOCK_ENABLE; | |
932 | value |= PLLE_MISC_PTS; | |
933 | value |= PLLE_MISC_VREG_BG_CTRL(3); | |
934 | value |= PLLE_MISC_VREG_CTRL(2); | |
935 | writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); | |
936 | ||
937 | udelay(5); | |
938 | ||
939 | value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); | |
940 | value |= PLLE_SS_CNTL_SSCBYP | PLLE_SS_CNTL_INTERP_RESET | | |
941 | PLLE_SS_CNTL_BYPASS_SS; | |
942 | writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); | |
943 | ||
944 | value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); | |
945 | value &= ~PLLE_BASE_PLDIV_CML(0xf); | |
946 | value &= ~PLLE_BASE_NDIV(0xff); | |
947 | value &= ~PLLE_BASE_MDIV(0xff); | |
948 | value |= PLLE_BASE_PLDIV_CML(cpcon); | |
949 | value |= PLLE_BASE_NDIV(n); | |
950 | value |= PLLE_BASE_MDIV(m); | |
951 | writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); | |
952 | ||
953 | udelay(1); | |
954 | ||
955 | value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); | |
956 | value |= PLLE_BASE_ENABLE; | |
957 | writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); | |
958 | ||
959 | /* wait for lock */ | |
960 | udelay(300); | |
961 | ||
962 | value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); | |
963 | value &= ~PLLE_SS_CNTL_SSCINVERT; | |
964 | value &= ~PLLE_SS_CNTL_SSCCENTER; | |
965 | ||
966 | value &= ~PLLE_SS_CNTL_SSCINCINTR(0x3f); | |
967 | value &= ~PLLE_SS_CNTL_SSCINC(0xff); | |
968 | value &= ~PLLE_SS_CNTL_SSCMAX(0x1ff); | |
969 | ||
970 | value |= PLLE_SS_CNTL_SSCINCINTR(0x20); | |
971 | value |= PLLE_SS_CNTL_SSCINC(0x01); | |
972 | value |= PLLE_SS_CNTL_SSCMAX(0x25); | |
973 | ||
974 | writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); | |
975 | ||
976 | value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); | |
977 | value &= ~PLLE_SS_CNTL_SSCBYP; | |
978 | value &= ~PLLE_SS_CNTL_BYPASS_SS; | |
979 | writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); | |
980 | ||
981 | udelay(1); | |
982 | ||
983 | value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); | |
984 | value &= ~PLLE_SS_CNTL_INTERP_RESET; | |
985 | writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); | |
986 | ||
987 | udelay(1); | |
988 | ||
989 | return 0; | |
990 | } | |
96e82a25 SG |
991 | |
992 | void clock_sor_enable_edp_clock(void) | |
993 | { | |
994 | u32 *reg; | |
995 | ||
996 | /* uses PLLP, has a non-standard bit layout. */ | |
997 | reg = get_periph_source_reg(PERIPH_ID_SOR0); | |
998 | setbits_le32(reg, SOR0_CLK_SEL0); | |
999 | } | |
1000 | ||
1001 | u32 clock_set_display_rate(u32 frequency) | |
1002 | { | |
1003 | /** | |
1004 | * plld (fo) = vco >> p, where 500MHz < vco < 1000MHz | |
1005 | * = (cf * n) >> p, where 1MHz < cf < 6MHz | |
1006 | * = ((ref / m) * n) >> p | |
1007 | * | |
1008 | * Iterate the possible values of p (3 bits, 2^7) to find out a minimum | |
1009 | * safe vco, then find best (m, n). since m has only 5 bits, we can | |
1010 | * iterate all possible values. Note Tegra 124 supports 11 bits for n, | |
1011 | * but our pll_fields has only 10 bits for n. | |
1012 | * | |
1013 | * Note values undershoot or overshoot target output frequency may not | |
1014 | * work if the values are not in "safe" range by panel specification. | |
1015 | */ | |
1016 | u32 ref = clock_get_rate(CLOCK_ID_OSC); | |
1017 | u32 divm, divn, divp, cpcon; | |
1018 | u32 cf, vco, rounded_rate = frequency; | |
1019 | u32 diff, best_diff, best_m = 0, best_n = 0, best_p; | |
1020 | const u32 max_m = 1 << 5, max_n = 1 << 10, max_p = 1 << 3, | |
1021 | mhz = 1000 * 1000, min_vco = 500 * mhz, max_vco = 1000 * mhz, | |
1022 | min_cf = 1 * mhz, max_cf = 6 * mhz; | |
1023 | int mux_bits, divider_bits, source; | |
1024 | ||
1025 | for (divp = 0, vco = frequency; vco < min_vco && divp < max_p; divp++) | |
1026 | vco <<= 1; | |
1027 | ||
1028 | if (vco < min_vco || vco > max_vco) { | |
1029 | printf("%s: Cannot find out a supported VCO for Frequency (%u)\n", | |
1030 | __func__, frequency); | |
1031 | return 0; | |
1032 | } | |
1033 | ||
1034 | best_p = divp; | |
1035 | best_diff = vco; | |
1036 | ||
1037 | for (divm = 1; divm < max_m && best_diff; divm++) { | |
1038 | cf = ref / divm; | |
1039 | if (cf < min_cf) | |
1040 | break; | |
1041 | if (cf > max_cf) | |
1042 | continue; | |
1043 | ||
1044 | divn = vco / cf; | |
1045 | if (divn >= max_n) | |
1046 | continue; | |
1047 | ||
1048 | diff = vco - divn * cf; | |
1049 | if (divn + 1 < max_n && diff > cf / 2) { | |
1050 | divn++; | |
1051 | diff = cf - diff; | |
1052 | } | |
1053 | ||
1054 | if (diff >= best_diff) | |
1055 | continue; | |
1056 | ||
1057 | best_diff = diff; | |
1058 | best_m = divm; | |
1059 | best_n = divn; | |
1060 | } | |
1061 | ||
1062 | if (best_n < 50) | |
1063 | cpcon = 2; | |
1064 | else if (best_n < 300) | |
1065 | cpcon = 3; | |
1066 | else if (best_n < 600) | |
1067 | cpcon = 8; | |
1068 | else | |
1069 | cpcon = 12; | |
1070 | ||
1071 | if (best_diff) { | |
1072 | printf("%s: Failed to match output frequency %u, best difference is %u\n", | |
1073 | __func__, frequency, best_diff); | |
1074 | rounded_rate = (ref / best_m * best_n) >> best_p; | |
1075 | } | |
1076 | ||
1077 | debug("%s: PLLD=%u ref=%u, m/n/p/cpcon=%u/%u/%u/%u\n", | |
1078 | __func__, rounded_rate, ref, best_m, best_n, best_p, cpcon); | |
1079 | ||
1080 | source = get_periph_clock_source(PERIPH_ID_DISP1, CLOCK_ID_DISPLAY, | |
1081 | &mux_bits, ÷r_bits); | |
1082 | clock_ll_set_source_bits(PERIPH_ID_DISP1, mux_bits, source); | |
1083 | clock_set_rate(CLOCK_ID_DISPLAY, best_n, best_m, best_p, cpcon); | |
1084 | ||
1085 | return rounded_rate; | |
1086 | } | |
1087 | ||
1088 | void clock_set_up_plldp(void) | |
1089 | { | |
1090 | struct clk_rst_ctlr *clkrst = | |
1091 | (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | |
1092 | u32 value; | |
1093 | ||
1094 | value = PLLDP_SS_CFG_UNDOCUMENTED | PLLDP_SS_CFG_DITHER; | |
1095 | writel(value | PLLDP_SS_CFG_CLAMP, &clkrst->crc_plldp_ss_cfg); | |
1096 | clock_start_pll(CLOCK_ID_DP, 1, 90, 3, 0, 0); | |
1097 | writel(value, &clkrst->crc_plldp_ss_cfg); | |
1098 | } | |
1099 | ||
1100 | struct clk_pll_simple *clock_get_simple_pll(enum clock_id clkid) | |
1101 | { | |
1102 | struct clk_rst_ctlr *clkrst = | |
1103 | (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | |
1104 | ||
1105 | if (clkid == CLOCK_ID_DP) | |
1106 | return &clkrst->plldp; | |
1107 | ||
1108 | return NULL; | |
1109 | } |