blob: ae53cd61efd8d67ea7aca2c45d82bed6b872bbfe [file] [log] [blame]
Nathan Barrett-Morrisona215cfc2024-04-24 20:04:00 -04001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * (C) Copyright 2022 - Analog Devices, Inc.
4 *
5 * Written and/or maintained by Timesys Corporation
6 *
7 * Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
8 * Contact: Greg Malysa <greg.malysa@timesys.com>
9 */
10
11#include <asm/arch-adi/sc5xx/sc5xx.h>
12#include <asm/io.h>
13#include <linux/types.h>
14#include "clkinit.h"
15#include "dmcinit.h"
16
17#ifdef CONFIG_CGU0_SCLK0_DIV
18 #define VAL_CGU0_SCLK0_DIV CONFIG_CGU0_SCLK0_DIV
19#else
20 #define VAL_CGU0_SCLK0_DIV 1
21#endif
22#ifdef CONFIG_CGU0_SCLK1_DIV
23 #define VAL_CGU0_SCLK1_DIV CONFIG_CGU0_SCLK1_DIV
24#else
25 #define VAL_CGU0_SCLK1_DIV 1
26#endif
27#ifdef CONFIG_CGU0_DIV_S0SELEX
28 #define VAL_CGU0_DIV_S0SELEX CONFIG_CGU0_DIV_S0SELEX
29#else
30 #define VAL_CGU0_DIV_S0SELEX -1
31#endif
32#ifdef CONFIG_CGU0_DIV_S1SELEX
33 #define VAL_CGU0_DIV_S1SELEX CONFIG_CGU0_DIV_S1SELEX
34#else
35 #define VAL_CGU0_DIV_S1SELEX -1
36#endif
37#ifdef CONFIG_CGU0_CLKOUTSEL
38 #define VAL_CGU0_CLKOUTSEL CONFIG_CGU0_CLKOUTSEL
39#else
40 #define VAL_CGU0_CLKOUTSEL -1
41#endif
42#ifdef CONFIG_CGU1_SCLK0_DIV
43 #define VAL_CGU1_SCLK0_DIV CONFIG_CGU1_SCLK0_DIV
44#else
45 #define VAL_CGU1_SCLK0_DIV 1
46#endif
47#ifdef CONFIG_CGU1_SCLK1_DIV
48 #define VAL_CGU1_SCLK1_DIV CONFIG_CGU1_SCLK1_DIV
49#else
50 #define VAL_CGU1_SCLK1_DIV 1
51#endif
52#ifdef CONFIG_CGU1_DIV_S0SELEX
53 #define VAL_CGU1_DIV_S0SELEX CONFIG_CGU1_DIV_S0SELEX
54#else
55 #define VAL_CGU1_DIV_S0SELEX -1
56#endif
57#ifdef CONFIG_CGU1_DIV_S1SELEX
58 #define VAL_CGU1_DIV_S1SELEX CONFIG_CGU1_DIV_S1SELEX
59#else
60 #define VAL_CGU1_DIV_S1SELEX -1
61#endif
62#ifdef CONFIG_CGU1_CLKOUTSEL
63 #define VAL_CGU1_CLKOUTSEL CONFIG_CGU1_CLKOUTSEL
64#else
65 #define VAL_CGU1_CLKOUTSEL -1
66#endif
67
68#define REG_MISC_REG10_tst_addr 0x310A902C
69
70#define CGU0_REGBASE 0x3108D000
71#define CGU1_REGBASE 0x3108E000
72
73#define CGU_CTL 0x00 // CGU0 Control Register
74#define CGU_PLLCTL 0x04 // CGU0 PLL Control Register
75#define CGU_STAT 0x08 // CGU0 Status Register
76#define CGU_DIV 0x0C // CGU0 Clocks Divisor Register
77#define CGU_CLKOUTSEL 0x10 // CGU0 CLKOUT Select Register
78#define CGU_DIVEX 0x40 // CGU0 DIV Register Extension
79
80#define BITP_CGU_DIV_OSEL 22 // OUTCLK Divisor
81#define BITP_CGU_DIV_DSEL 16 // DCLK Divisor
82#define BITP_CGU_DIV_S1SEL 13 // SCLK 1 Divisor
83#define BITP_CGU_DIV_SYSSEL 8 // SYSCLK Divisor
84#define BITP_CGU_DIV_S0SEL 5 // SCLK 0 Divisor
85#define BITP_CGU_DIV_CSEL 0 // CCLK Divisor
86
87#define BITP_CGU_CTL_MSEL 8 // Multiplier Select
88#define BITP_CGU_CTL_DF 0 // Divide Frequency
89
90#define BITM_CGU_STAT_CLKSALGN 0x00000008
91#define BITM_CGU_STAT_PLOCK 0x00000004
92#define BITM_CGU_STAT_PLLBP 0x00000002
93#define BITM_CGU_STAT_PLLEN 0x00000001
94
95/* PLL Multiplier and Divisor Selections (Required Value, Bit Position) */
96/* PLL Multiplier Select */
97#define MSEL(X) (((X) << BITP_CGU_CTL_MSEL) & \
98 BITM_CGU_CTL_MSEL)
99/* Divide frequency[true or false] */
100#define DF(X) (((X) << BITP_CGU_CTL_DF) & \
101 BITM_CGU_CTL_DF)
102/* Core Clock Divisor Select */
103#define CSEL(X) (((X) << BITP_CGU_DIV_CSEL) & \
104 BITM_CGU_DIV_CSEL)
105/* System Clock Divisor Select */
106#define SYSSEL(X) (((X) << BITP_CGU_DIV_SYSSEL) & \
107 BITM_CGU_DIV_SYSSEL)
108/* SCLK0 Divisor Select */
109#define S0SEL(X) (((X) << BITP_CGU_DIV_S0SEL) & \
110 BITM_CGU_DIV_S0SEL)
111/* SCLK1 Divisor Select */
112#define S1SEL(X) (((X) << BITP_CGU_DIV_S1SEL) & \
113 BITM_CGU_DIV_S1SEL)
114/* DDR Clock Divisor Select */
115#define DSEL(X) (((X) << BITP_CGU_DIV_DSEL) & \
116 BITM_CGU_DIV_DSEL)
117/* OUTCLK Divisor Select */
118#define OSEL(X) (((X) << BITP_CGU_DIV_OSEL) & \
119 BITM_CGU_DIV_OSEL)
120/* CLKOUT select */
121#define CLKOUTSEL(X) (((X) << BITP_CGU_CLKOUTSEL_CLKOUTSEL) & \
122 BITM_CGU_CLKOUTSEL_CLKOUTSEL)
123#define S0SELEX(X) (((X) << BITP_CGU_DIVEX_S0SELEX) & \
124 BITM_CGU_DIVEX_S0SELEX)
125#define S1SELEX(X) (((X) << BITP_CGU_DIVEX_S1SELEX) & \
126 BITM_CGU_DIVEX_S1SELEX)
127
128struct CGU_Settings {
129 phys_addr_t rbase;
130 u32 ctl_MSEL:7;
131 u32 ctl_DF:1;
132 u32 div_CSEL:5;
133 u32 div_SYSSEL:5;
134 u32 div_S0SEL:3;
135 u32 div_S1SEL:3;
136 u32 div_DSEL:5;
137 u32 div_OSEL:7;
138 s16 divex_S0SELEX;
139 s16 divex_S1SELEX;
140 s8 clkoutsel;
141};
142
143/* CGU Registers */
144#define BITM_CGU_CTL_LOCK 0x80000000 /* Lock */
145
146#define BITM_CGU_CTL_MSEL 0x00007F00 /* Multiplier Select */
147#define BITM_CGU_CTL_DF 0x00000001 /* Divide Frequency */
148#define BITM_CGU_CTL_S1SELEXEN 0x00020000 /* SCLK1 Extension Divider Enable */
149#define BITM_CGU_CTL_S0SELEXEN 0x00010000 /* SCLK0 Extension Divider Enable */
150
151#define BITM_CGU_DIV_LOCK 0x80000000 /* Lock */
152#define BITM_CGU_DIV_UPDT 0x40000000 /* Update Clock Divisors */
153#define BITM_CGU_DIV_ALGN 0x20000000 /* Align */
154#define BITM_CGU_DIV_OSEL 0x1FC00000 /* OUTCLK Divisor */
155#define BITM_CGU_DIV_DSEL 0x001F0000 /* DCLK Divisor */
156#define BITM_CGU_DIV_S1SEL 0x0000E000 /* SCLK 1 Divisor */
157#define BITM_CGU_DIV_SYSSEL 0x00001F00 /* SYSCLK Divisor */
158#define BITM_CGU_DIV_S0SEL 0x000000E0 /* SCLK 0 Divisor */
159#define BITM_CGU_DIV_CSEL 0x0000001F /* CCLK Divisor */
160
161#define BITP_CGU_DIVEX_S0SELEX 0
162#define BITM_CGU_DIVEX_S0SELEX 0x000000FF /* SCLK 0 Extension Divisor */
163
164#define BITP_CGU_DIVEX_S1SELEX 16
165#define BITM_CGU_DIVEX_S1SELEX 0x00FF0000 /* SCLK 1 Extension Divisor */
166
167#define BITM_CGU_PLLCTL_PLLEN 0x00000008 /* PLL Enable */
168#define BITM_CGU_PLLCTL_PLLBPCL 0x00000002 /* PLL Bypass Clear */
169#define BITM_CGU_PLLCTL_PLLBPST 0x00000001 /* PLL Bypass Set */
170
171#define BITP_CGU_CLKOUTSEL_CLKOUTSEL 0 /* CLKOUT Select */
172#define BITM_CGU_CLKOUTSEL_CLKOUTSEL 0x0000001F /* CLKOUT Select */
173
174#define CGU_STAT_MASK (BITM_CGU_STAT_PLLEN | BITM_CGU_STAT_PLOCK | \
175 BITM_CGU_STAT_CLKSALGN)
176#define CGU_STAT_ALGN_LOCK (BITM_CGU_STAT_PLLEN | BITM_CGU_STAT_PLOCK)
177
178/* Clock Distribution Unit Registers */
179#define REG_CDU0_CFG0 0x3108F000
180#define REG_CDU0_CFG1 0x3108F004
181#define REG_CDU0_CFG2 0x3108F008
182#define REG_CDU0_CFG3 0x3108F00C
183#define REG_CDU0_CFG4 0x3108F010
184#define REG_CDU0_CFG5 0x3108F014
185#define REG_CDU0_CFG6 0x3108F018
186#define REG_CDU0_CFG7 0x3108F01C
187#define REG_CDU0_CFG8 0x3108F020
188#define REG_CDU0_CFG9 0x3108F024
189#define REG_CDU0_CFG10 0x3108F028
190#define REG_CDU0_CFG11 0x3108F02C
191#define REG_CDU0_CFG12 0x3108F030
192#define REG_CDU0_CFG13 0x3108F034
193#define REG_CDU0_CFG14 0x3108F038
194#define REG_CDU0_STAT 0x3108F040
195#define REG_CDU0_CLKINSEL 0x3108F044
196#define REG_CDU0_REVID 0x3108F048
197
198#define BITM_REG10_MSEL3 0x000007F0
199#define BITP_REG10_MSEL3 4
200
201#define BITM_REG10_DSEL3 0x0001F000
202#define BITP_REG10_DSEL3 12
203
204/* Selected clock macros */
205#define CGUn_MULT(cgu) ((CONFIG_CGU##cgu##_VCO_MULT == 0) ? \
206 128 : CONFIG_CGU##cgu##_VCO_MULT)
207#define CGUn_DIV(clkname, cgu) ((CONFIG_CGU##cgu##_##clkname##_DIV == 0) ? \
208 32 : CONFIG_CGU##cgu##_##clkname##_DIV)
209#define CCLK1_n_RATIO(cgu) (((CGUn_MULT(cgu)) / \
210 (1 + CONFIG_CGU##cgu##_DF_DIV)) / \
211 CGUn_DIV(CCLK, cgu))
212#define CCLK2_n_RATIO(cgu) (((CGUn_MULT(cgu) * 2) / 3) / \
213 (1 + CONFIG_CGU##cgu##_DF_DIV))
214#define DCLK_n_RATIO(cgu) (((CGUn_MULT(cgu)) / \
215 (1 + CONFIG_CGU##cgu##_DF_DIV)) / \
216 CGUn_DIV(DCLK, cgu))
217#define SYSCLK_n_RATIO(cgu) (((CGUn_MULT(cgu)) / \
218 (1 + CONFIG_CGU##cgu##_DF_DIV)) / \
219 CGUn_DIV(SCLK, cgu))
220#define PLL3_RATIO ((CONFIG_CGU1_PLL3_VCO_MSEL) / \
221 (CONFIG_CGU1_PLL3_DCLK_DIV))
222
223#if (1 == CONFIG_CDU0_CLKO2)
224 #define ARMCLK_IN 0
225 #define ARMCLK_RATIO CCLK1_n_RATIO(0)
226#elif (3 == CONFIG_CDU0_CLKO2) && \
227 (defined(CONFIG_SC57X) || defined(CONFIG_SC58X))
228 #define ARMCLK_IN 0
229 #define ARMCLK_RATIO SYSCLK_n_RATIO(0)
230#elif (5 == CONFIG_CDU0_CLKO2) && defined(CONFIG_SC59X_64)
231 #define ARMCLK_IN 0
232 #define ARMCLK_RATIO CCLK2_n_RATIO(0)
233#elif (7 == CONFIG_CDU0_CLKO2) && defined(CONFIG_SC59X_64)
234 #define ARMCLK_IN CDU0_CGU1_CLKIN
235 #define ARMCLK_RATIO CCLK2_n_RATIO(1)
236#endif
237
238#ifdef CONFIG_CGU1_PLL3_DDRCLK
239 #define DDRCLK_IN CDU0_CGU1_CLKIN
240 #define DDRCLK_RATIO PLL3_RATIO
241#elif (1 == CONFIG_CDU0_CLKO3)
242 #define DDRCLK_IN 0
243 #define DDRCLK_RATIO DCLK_n_RATIO(0)
244#elif (3 == CONFIG_CDU0_CLKO3)
245 #define DDRCLK_IN CDU0_CGU1_CLKIN
246 #define DDRCLK_RATIO DCLK_n_RATIO(1)
247#endif
248
249#ifndef ARMCLK_RATIO
250 #error Invalid/unknown ARMCLK selection!
251#endif
252#ifndef DDRCLK_RATIO
253 #error Invalid/unknown DDRCLK selection!
254#endif
255
256#define ARMDDR_CLK_RATIO_FPERCISION 1000
257
258#if ARMCLK_IN != DDRCLK_IN
259 #ifndef CUSTOM_ARMDDR_CLK_RATIO
260 /**
261 * SYS_CLKINx are defined within the device tree, not configs.
262 * Thus, we can only determine cross-CGU clock ratios if they
263 * use the same SYS_CLKINx.
264 */
265 #error Define CUSTOM_ARMDDR_CLK_RATIO for different SYS_CLKINs
266 #else
267 #define ARMDDR_CLK_RATIO CUSTOM_ARMDDR_CLK_RATIO
268 #endif
269#else
270 #define ARMDDR_CLK_RATIO (ARMDDR_CLK_RATIO_FPERCISION *\
271 ARMCLK_RATIO / DDRCLK_RATIO)
272#endif
273
274void dmcdelay(uint32_t delay)
275{
276 /* There is no zero-overhead loop on ARM, so assume each iteration
277 * takes 4 processor cycles (based on examination of -O3 and -Ofast
278 * output).
279 */
280 u32 i, remainder;
281
282 /* Convert DDR cycles to core clock cycles */
283 u32 f = delay * ARMDDR_CLK_RATIO;
284
285 delay = f + 500;
286 delay /= ARMDDR_CLK_RATIO_FPERCISION;
287
288 /* Round up to multiple of 4 */
289 remainder = delay % 4;
290 if (remainder != 0u)
291 delay += (4u - remainder);
292
293 for (i = 0; i < delay; i += 4)
294 asm("nop");
295}
296
297static void program_cgu(const struct CGU_Settings *cgu)
298{
299 const uintptr_t b = cgu->rbase;
300 const bool use_extension0 = cgu->divex_S0SELEX >= 0;
301 const bool use_extension1 = cgu->divex_S1SELEX >= 0;
302 u32 temp;
303
304 temp = OSEL(cgu->div_OSEL);
305 temp |= SYSSEL(cgu->div_SYSSEL);
306 temp |= CSEL(cgu->div_CSEL);
307 temp |= DSEL(cgu->div_DSEL);
308 temp |= (S0SEL(cgu->div_S0SEL));
309 temp |= (S1SEL(cgu->div_S1SEL));
310 temp &= ~BITM_CGU_DIV_LOCK;
311
312 //Put PLL in to Bypass Mode
313 writel(BITM_CGU_PLLCTL_PLLEN | BITM_CGU_PLLCTL_PLLBPST,
314 b + CGU_PLLCTL);
315 while (!(readl(b + CGU_STAT) & BITM_CGU_STAT_PLLBP))
316 ;
317
318 while (!((readl(b + CGU_STAT) & CGU_STAT_MASK) == CGU_STAT_ALGN_LOCK))
319 ;
320
321 dmcdelay(1000);
322
323 writel(temp & (~BITM_CGU_DIV_ALGN) & (~BITM_CGU_DIV_UPDT),
324 b + CGU_DIV);
325
326 dmcdelay(1000);
327
328 temp = MSEL(cgu->ctl_MSEL) | DF(cgu->ctl_DF);
329 if (use_extension0)
330 temp |= BITM_CGU_CTL_S0SELEXEN;
331 if (use_extension1)
332 temp |= BITM_CGU_CTL_S1SELEXEN;
333
334 writel(temp & (~BITM_CGU_CTL_LOCK), b + CGU_CTL);
335
336 if (use_extension0 || use_extension1) {
337 u32 mask = BITM_CGU_CTL_S1SELEXEN | BITM_CGU_CTL_S0SELEXEN;
338
339 while (!(readl(b + CGU_CTL) & mask))
340 ;
341
342 temp = readl(b + CGU_DIVEX);
343
344 if (use_extension0) {
345 temp &= ~BITM_CGU_DIVEX_S0SELEX;
346 temp |= S0SELEX(cgu->divex_S0SELEX);
347 }
348
349 if (use_extension1) {
350 temp &= ~BITM_CGU_DIVEX_S1SELEX;
351 temp |= S1SELEX(cgu->divex_S1SELEX);
352 }
353
354 writel(temp, b + CGU_DIVEX);
355 }
356
357 dmcdelay(1000);
358
359 //Take PLL out of Bypass Mode
360 writel(BITM_CGU_PLLCTL_PLLEN | BITM_CGU_PLLCTL_PLLBPCL,
361 b + CGU_PLLCTL);
362 while ((readl(b + CGU_STAT) &
363 (BITM_CGU_STAT_PLLBP | BITM_CGU_STAT_CLKSALGN)))
364 ;
365
366 dmcdelay(1000);
367
368 if (cgu->clkoutsel >= 0) {
369 temp = readl(b + CGU_CLKOUTSEL);
370 temp &= ~BITM_CGU_CLKOUTSEL_CLKOUTSEL;
371 temp |= CLKOUTSEL(cgu->clkoutsel);
372 writel(temp, b + CGU_CLKOUTSEL);
373 }
374}
375
376void adi_config_third_pll(void)
377{
378#if defined(CONFIG_CGU1_PLL3_VCO_MSEL) && defined(CONFIG_CGU1_PLL3_DCLK_DIV)
379 u32 temp;
380
381 u32 msel = CONFIG_CGU1_PLL3_VCO_MSEL - 1;
382 u32 dsel = CONFIG_CGU1_PLL3_DCLK_DIV - 1;
383
384 temp = readl(REG_MISC_REG10_tst_addr);
385 temp &= 0xFFFE0000;
386 writel(temp, REG_MISC_REG10_tst_addr);
387
388 dmcdelay(4000u);
389
390 //update MSEL [10:4]
391 temp = readl(REG_MISC_REG10_tst_addr);
392 temp |= ((msel << BITP_REG10_MSEL3) & BITM_REG10_MSEL3);
393 writel(temp, REG_MISC_REG10_tst_addr);
394
395 temp = readl(REG_MISC_REG10_tst_addr);
396 temp |= 0x2;
397 writel(temp, REG_MISC_REG10_tst_addr);
398
399 dmcdelay(100000u);
400
401 temp = readl(REG_MISC_REG10_tst_addr);
402 temp |= 0x1;
403 writel(temp, REG_MISC_REG10_tst_addr);
404
405 temp = readl(REG_MISC_REG10_tst_addr);
406 temp |= 0x800;
407 writel(temp, REG_MISC_REG10_tst_addr);
408
409 temp = readl(REG_MISC_REG10_tst_addr);
410 temp &= 0xFFFFF7F8;
411 writel(temp, REG_MISC_REG10_tst_addr);
412
413 dmcdelay(4000u);
414
415 temp = readl(REG_MISC_REG10_tst_addr);
416 temp |= ((dsel << BITP_REG10_DSEL3) & BITM_REG10_DSEL3);
417 writel(temp, REG_MISC_REG10_tst_addr);
418
419 temp = readl(REG_MISC_REG10_tst_addr);
420 temp |= 0x4;
421 writel(temp, REG_MISC_REG10_tst_addr);
422
423 dmcdelay(100000u);
424
425 temp = readl(REG_MISC_REG10_tst_addr);
426 temp |= 0x1;
427 writel(temp, REG_MISC_REG10_tst_addr);
428
429 temp = readl(REG_MISC_REG10_tst_addr);
430 temp |= 0x800;
431 writel(temp, REG_MISC_REG10_tst_addr);
432#endif
433}
434
435static void Active_To_Fullon(const struct CGU_Settings *pCGU)
436{
437 u32 tmp;
438
439 while (1) {
440 tmp = readl(pCGU->rbase + CGU_STAT);
441 if ((tmp & BITM_CGU_STAT_PLLEN) &&
442 (tmp & BITM_CGU_STAT_PLLBP))
443 break;
444 }
445
446 writel(BITM_CGU_PLLCTL_PLLBPCL, pCGU->rbase + CGU_PLLCTL);
447
448 while (1) {
449 tmp = readl(pCGU->rbase + CGU_STAT);
450 if ((tmp & BITM_CGU_STAT_PLLEN) &&
451 ~(tmp & BITM_CGU_STAT_PLLBP) &&
452 ~(tmp & BITM_CGU_STAT_CLKSALGN))
453 break;
454 }
455}
456
457static void CGU_Init(const struct CGU_Settings *pCGU)
458{
459 const uintptr_t b = pCGU->rbase;
460
461#if defined(CONFIG_SC59X) || defined(CONFIG_SC59X_64)
462 if (readl(b + CGU_STAT) & BITM_CGU_STAT_PLLEN)
463 writel(BITM_CGU_PLLCTL_PLLEN, b + CGU_PLLCTL);
464
465 dmcdelay(1000);
466#endif
467
468 /* Check if processor is in Active mode */
469 if (readl(b + CGU_STAT) & BITM_CGU_STAT_PLLBP)
470 Active_To_Fullon(pCGU);
471
472#if defined(CONFIG_SC59X) || defined(CONFIG_SC59X_64)
473 dmcdelay(1000);
474#endif
475
476 program_cgu(pCGU);
477}
478
479void cgu_init(void)
480{
481 const struct CGU_Settings dividers0 = {
482 .rbase = CGU0_REGBASE,
483 .ctl_MSEL = CONFIG_CGU0_VCO_MULT,
484 .ctl_DF = CONFIG_CGU0_DF_DIV,
485 .div_CSEL = CONFIG_CGU0_CCLK_DIV,
486 .div_SYSSEL = CONFIG_CGU0_SCLK_DIV,
487 .div_S0SEL = VAL_CGU0_SCLK0_DIV,
488 .div_S1SEL = VAL_CGU0_SCLK1_DIV,
489 .div_DSEL = CONFIG_CGU0_DCLK_DIV,
490 .div_OSEL = CONFIG_CGU0_OCLK_DIV,
491 .divex_S0SELEX = VAL_CGU0_DIV_S0SELEX,
492 .divex_S1SELEX = VAL_CGU0_DIV_S1SELEX,
493 .clkoutsel = VAL_CGU0_CLKOUTSEL,
494 };
495 const struct CGU_Settings dividers1 = {
496 .rbase = CGU1_REGBASE,
497 .ctl_MSEL = CONFIG_CGU1_VCO_MULT,
498 .ctl_DF = CONFIG_CGU1_DF_DIV,
499 .div_CSEL = CONFIG_CGU1_CCLK_DIV,
500 .div_SYSSEL = CONFIG_CGU1_SCLK_DIV,
501 .div_S0SEL = VAL_CGU1_SCLK0_DIV,
502 .div_S1SEL = VAL_CGU1_SCLK1_DIV,
503 .div_DSEL = CONFIG_CGU1_DCLK_DIV,
504 .div_OSEL = CONFIG_CGU1_OCLK_DIV,
505 .divex_S0SELEX = VAL_CGU1_DIV_S0SELEX,
506 .divex_S1SELEX = VAL_CGU1_DIV_S1SELEX,
507 .clkoutsel = VAL_CGU1_CLKOUTSEL,
508 };
509
510 CGU_Init(&dividers0);
511 CGU_Init(&dividers1);
512}
513
514#define CONFIGURE_CDU0(a, b, c) \
515 writel(a, b); \
516 while (readl(REG_CDU0_STAT) & (1 << (c)))
517
518void cdu_init(void)
519{
520 while (readl(REG_CDU0_STAT) & 0xffff)
521 ;
522 writel((CONFIG_CDU0_CGU1_CLKIN & 0x1), REG_CDU0_CLKINSEL);
523
524 CONFIGURE_CDU0(CONFIG_CDU0_CLKO0, REG_CDU0_CFG0, 0);
525 CONFIGURE_CDU0(CONFIG_CDU0_CLKO1, REG_CDU0_CFG1, 1);
526 CONFIGURE_CDU0(CONFIG_CDU0_CLKO2, REG_CDU0_CFG2, 2);
527 CONFIGURE_CDU0(CONFIG_CDU0_CLKO3, REG_CDU0_CFG3, 3);
528 CONFIGURE_CDU0(CONFIG_CDU0_CLKO4, REG_CDU0_CFG4, 4);
529 CONFIGURE_CDU0(CONFIG_CDU0_CLKO5, REG_CDU0_CFG5, 5);
530 CONFIGURE_CDU0(CONFIG_CDU0_CLKO6, REG_CDU0_CFG6, 6);
531 CONFIGURE_CDU0(CONFIG_CDU0_CLKO7, REG_CDU0_CFG7, 7);
532 CONFIGURE_CDU0(CONFIG_CDU0_CLKO8, REG_CDU0_CFG8, 8);
533 CONFIGURE_CDU0(CONFIG_CDU0_CLKO9, REG_CDU0_CFG9, 9);
534#ifdef CONFIG_CDU0_CLKO10
535 CONFIGURE_CDU0(CONFIG_CDU0_CLKO10, REG_CDU0_CFG10, 10);
536#endif
537#ifdef CONFIG_CDU0_CLKO12
538 CONFIGURE_CDU0(CONFIG_CDU0_CLKO12, REG_CDU0_CFG12, 12);
539#endif
540#ifdef CONFIG_CDU0_CLKO13
541 CONFIGURE_CDU0(CONFIG_CDU0_CLKO13, REG_CDU0_CFG13, 13);
542#endif
543#ifdef CONFIG_CDU0_CLKO14
544 CONFIGURE_CDU0(CONFIG_CDU0_CLKO14, REG_CDU0_CFG14, 14);
545#endif
546}
547
548void clks_init(void)
549{
550 adi_dmc_reset_lanes(true);
551
552 cdu_init();
553 cgu_init();
554
555 adi_config_third_pll();
556
557 adi_dmc_reset_lanes(false);
558}