1
2
3
4
5#define LOG_CATEGORY UCLASS_CLK
6
7#include <common.h>
8#include <clk.h>
9#include <clk-uclass.h>
10#include <div64.h>
11#include <dm.h>
12#include <log.h>
13#include <mapmem.h>
14#include <serial.h>
15#include <dt-bindings/clock/k210-sysctl.h>
16#include <dt-bindings/mfd/k210-sysctl.h>
17#include <kendryte/pll.h>
18#include <linux/bitfield.h>
19
20DECLARE_GLOBAL_DATA_PTR;
21
22
23
24
25
26
27struct k210_clk_priv {
28 void __iomem *base;
29 struct clk in0;
30};
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51enum k210_clk_div_type {
52 K210_DIV_ONE,
53 K210_DIV_EVEN,
54 K210_DIV_POWER,
55 K210_DIV_FIXED,
56};
57
58
59
60
61
62
63
64
65
66struct k210_div_params {
67 u8 type;
68 union {
69 struct {
70 u8 off;
71 u8 shift;
72 u8 width;
73 };
74 u8 div;
75 };
76};
77
78#define DIV_LIST \
79 DIV(K210_CLK_ACLK, K210_SYSCTL_SEL0, 1, 2, K210_DIV_POWER) \
80 DIV(K210_CLK_APB0, K210_SYSCTL_SEL0, 3, 3, K210_DIV_ONE) \
81 DIV(K210_CLK_APB1, K210_SYSCTL_SEL0, 6, 3, K210_DIV_ONE) \
82 DIV(K210_CLK_APB2, K210_SYSCTL_SEL0, 9, 3, K210_DIV_ONE) \
83 DIV(K210_CLK_SRAM0, K210_SYSCTL_THR0, 0, 4, K210_DIV_ONE) \
84 DIV(K210_CLK_SRAM1, K210_SYSCTL_THR0, 4, 4, K210_DIV_ONE) \
85 DIV(K210_CLK_AI, K210_SYSCTL_THR0, 8, 4, K210_DIV_ONE) \
86 DIV(K210_CLK_DVP, K210_SYSCTL_THR0, 12, 4, K210_DIV_ONE) \
87 DIV(K210_CLK_ROM, K210_SYSCTL_THR0, 16, 4, K210_DIV_ONE) \
88 DIV(K210_CLK_SPI0, K210_SYSCTL_THR1, 0, 8, K210_DIV_EVEN) \
89 DIV(K210_CLK_SPI1, K210_SYSCTL_THR1, 8, 8, K210_DIV_EVEN) \
90 DIV(K210_CLK_SPI2, K210_SYSCTL_THR1, 16, 8, K210_DIV_EVEN) \
91 DIV(K210_CLK_SPI3, K210_SYSCTL_THR1, 24, 8, K210_DIV_EVEN) \
92 DIV(K210_CLK_TIMER0, K210_SYSCTL_THR2, 0, 8, K210_DIV_EVEN) \
93 DIV(K210_CLK_TIMER1, K210_SYSCTL_THR2, 8, 8, K210_DIV_EVEN) \
94 DIV(K210_CLK_TIMER2, K210_SYSCTL_THR2, 16, 8, K210_DIV_EVEN) \
95 DIV(K210_CLK_I2S0, K210_SYSCTL_THR3, 0, 16, K210_DIV_EVEN) \
96 DIV(K210_CLK_I2S1, K210_SYSCTL_THR3, 16, 16, K210_DIV_EVEN) \
97 DIV(K210_CLK_I2S2, K210_SYSCTL_THR4, 0, 16, K210_DIV_EVEN) \
98 DIV(K210_CLK_I2S0_M, K210_SYSCTL_THR4, 16, 8, K210_DIV_EVEN) \
99 DIV(K210_CLK_I2S1_M, K210_SYSCTL_THR4, 24, 8, K210_DIV_EVEN) \
100 DIV(K210_CLK_I2S2_M, K210_SYSCTL_THR4, 0, 8, K210_DIV_EVEN) \
101 DIV(K210_CLK_I2C0, K210_SYSCTL_THR5, 8, 8, K210_DIV_EVEN) \
102 DIV(K210_CLK_I2C1, K210_SYSCTL_THR5, 16, 8, K210_DIV_EVEN) \
103 DIV(K210_CLK_I2C2, K210_SYSCTL_THR5, 24, 8, K210_DIV_EVEN) \
104 DIV(K210_CLK_WDT0, K210_SYSCTL_THR6, 0, 8, K210_DIV_EVEN) \
105 DIV(K210_CLK_WDT1, K210_SYSCTL_THR6, 8, 8, K210_DIV_EVEN) \
106 DIV_FIXED(K210_CLK_CLINT, 50) \
107
108#define _DIVIFY(id) K210_CLK_DIV_##id
109#define DIVIFY(id) _DIVIFY(id)
110
111enum k210_div_id {
112#define DIV(id, ...) DIVIFY(id),
113#define DIV_FIXED DIV
114 DIV_LIST
115#undef DIV
116#undef DIV_FIXED
117 K210_CLK_DIV_NONE,
118};
119
120static const struct k210_div_params k210_divs[] = {
121#define DIV(id, _off, _shift, _width, _type) \
122 [DIVIFY(id)] = { \
123 .type = (_type), \
124 .off = (_off), \
125 .shift = (_shift), \
126 .width = (_width), \
127 },
128#define DIV_FIXED(id, _div) \
129 [DIVIFY(id)] = { \
130 .type = K210_DIV_FIXED, \
131 .div = (_div) \
132 },
133 DIV_LIST
134#undef DIV
135#undef DIV_FIXED
136};
137
138#undef DIV
139#undef DIV_LIST
140
141
142
143
144
145
146struct k210_gate_params {
147 u8 off;
148 u8 bit_idx;
149};
150
151#define GATE_LIST \
152 GATE(K210_CLK_CPU, K210_SYSCTL_EN_CENT, 0) \
153 GATE(K210_CLK_SRAM0, K210_SYSCTL_EN_CENT, 1) \
154 GATE(K210_CLK_SRAM1, K210_SYSCTL_EN_CENT, 2) \
155 GATE(K210_CLK_APB0, K210_SYSCTL_EN_CENT, 3) \
156 GATE(K210_CLK_APB1, K210_SYSCTL_EN_CENT, 4) \
157 GATE(K210_CLK_APB2, K210_SYSCTL_EN_CENT, 5) \
158 GATE(K210_CLK_ROM, K210_SYSCTL_EN_PERI, 0) \
159 GATE(K210_CLK_DMA, K210_SYSCTL_EN_PERI, 1) \
160 GATE(K210_CLK_AI, K210_SYSCTL_EN_PERI, 2) \
161 GATE(K210_CLK_DVP, K210_SYSCTL_EN_PERI, 3) \
162 GATE(K210_CLK_FFT, K210_SYSCTL_EN_PERI, 4) \
163 GATE(K210_CLK_GPIO, K210_SYSCTL_EN_PERI, 5) \
164 GATE(K210_CLK_SPI0, K210_SYSCTL_EN_PERI, 6) \
165 GATE(K210_CLK_SPI1, K210_SYSCTL_EN_PERI, 7) \
166 GATE(K210_CLK_SPI2, K210_SYSCTL_EN_PERI, 8) \
167 GATE(K210_CLK_SPI3, K210_SYSCTL_EN_PERI, 9) \
168 GATE(K210_CLK_I2S0, K210_SYSCTL_EN_PERI, 10) \
169 GATE(K210_CLK_I2S1, K210_SYSCTL_EN_PERI, 11) \
170 GATE(K210_CLK_I2S2, K210_SYSCTL_EN_PERI, 12) \
171 GATE(K210_CLK_I2C0, K210_SYSCTL_EN_PERI, 13) \
172 GATE(K210_CLK_I2C1, K210_SYSCTL_EN_PERI, 14) \
173 GATE(K210_CLK_I2C2, K210_SYSCTL_EN_PERI, 15) \
174 GATE(K210_CLK_UART1, K210_SYSCTL_EN_PERI, 16) \
175 GATE(K210_CLK_UART2, K210_SYSCTL_EN_PERI, 17) \
176 GATE(K210_CLK_UART3, K210_SYSCTL_EN_PERI, 18) \
177 GATE(K210_CLK_AES, K210_SYSCTL_EN_PERI, 19) \
178 GATE(K210_CLK_FPIOA, K210_SYSCTL_EN_PERI, 20) \
179 GATE(K210_CLK_TIMER0, K210_SYSCTL_EN_PERI, 21) \
180 GATE(K210_CLK_TIMER1, K210_SYSCTL_EN_PERI, 22) \
181 GATE(K210_CLK_TIMER2, K210_SYSCTL_EN_PERI, 23) \
182 GATE(K210_CLK_WDT0, K210_SYSCTL_EN_PERI, 24) \
183 GATE(K210_CLK_WDT1, K210_SYSCTL_EN_PERI, 25) \
184 GATE(K210_CLK_SHA, K210_SYSCTL_EN_PERI, 26) \
185 GATE(K210_CLK_OTP, K210_SYSCTL_EN_PERI, 27) \
186 GATE(K210_CLK_RTC, K210_SYSCTL_EN_PERI, 29)
187
188#define _GATEIFY(id) K210_CLK_GATE_##id
189#define GATEIFY(id) _GATEIFY(id)
190
191enum k210_gate_id {
192#define GATE(id, ...) GATEIFY(id),
193 GATE_LIST
194#undef GATE
195 K210_CLK_GATE_NONE,
196};
197
198static const struct k210_gate_params k210_gates[] = {
199#define GATE(id, _off, _idx) \
200 [GATEIFY(id)] = { \
201 .off = (_off), \
202 .bit_idx = (_idx), \
203 },
204 GATE_LIST
205#undef GATE
206};
207
208#undef GATE_LIST
209
210
211#define K210_CLK_MAX_PARENTS 3
212
213
214
215
216
217
218
219
220
221struct k210_mux_params {
222 u8 parents[K210_CLK_MAX_PARENTS];
223 u8 num_parents;
224 u8 off;
225 u8 shift;
226 u8 width;
227};
228
229#define MUX(id, reg, shift, width) \
230 MUX_PARENTS(id, reg, shift, width, K210_CLK_IN0, K210_CLK_PLL0)
231#define MUX_LIST \
232 MUX_PARENTS(K210_CLK_PLL2, K210_SYSCTL_PLL2, 26, 2, \
233 K210_CLK_IN0, K210_CLK_PLL0, K210_CLK_PLL1) \
234 MUX(K210_CLK_ACLK, K210_SYSCTL_SEL0, 0, 1) \
235 MUX(K210_CLK_SPI3, K210_SYSCTL_SEL0, 12, 1) \
236 MUX(K210_CLK_TIMER0, K210_SYSCTL_SEL0, 13, 1) \
237 MUX(K210_CLK_TIMER1, K210_SYSCTL_SEL0, 14, 1) \
238 MUX(K210_CLK_TIMER2, K210_SYSCTL_SEL0, 15, 1)
239
240#define _MUXIFY(id) K210_CLK_MUX_##id
241#define MUXIFY(id) _MUXIFY(id)
242
243enum k210_mux_id {
244#define MUX_PARENTS(id, ...) MUXIFY(id),
245 MUX_LIST
246#undef MUX_PARENTS
247 K210_CLK_MUX_NONE,
248};
249
250static const struct k210_mux_params k210_muxes[] = {
251#define MUX_PARENTS(id, _off, _shift, _width, ...) \
252 [MUXIFY(id)] = { \
253 .parents = { __VA_ARGS__ }, \
254 .num_parents = __count_args(__VA_ARGS__), \
255 .off = (_off), \
256 .shift = (_shift), \
257 .width = (_width), \
258 },
259 MUX_LIST
260#undef MUX_PARENTS
261};
262
263#undef MUX
264#undef MUX_LIST
265
266
267
268
269
270
271
272struct k210_pll_params {
273 u8 off;
274 u8 shift;
275 u8 width;
276};
277
278static const struct k210_pll_params k210_plls[] = {
279#define PLL(_off, _shift, _width) { \
280 .off = (_off), \
281 .shift = (_shift), \
282 .width = (_width), \
283}
284 [0] = PLL(K210_SYSCTL_PLL0, 0, 2),
285 [1] = PLL(K210_SYSCTL_PLL1, 8, 1),
286 [2] = PLL(K210_SYSCTL_PLL2, 16, 1),
287#undef PLL
288};
289
290
291
292
293
294
295enum k210_clk_flags {
296 K210_CLKF_MUX = BIT(0),
297 K210_CLKF_PLL = BIT(1),
298};
299
300
301
302
303
304
305
306
307
308
309
310struct k210_clk_params {
311#if CONFIG_IS_ENABLED(CMD_CLK)
312 const char *name;
313#endif
314 u8 flags;
315 union {
316 u8 parent;
317 u8 mux;
318 };
319 union {
320 u8 pll;
321 struct {
322 u8 div;
323 u8 gate;
324 };
325 };
326};
327
328static const struct k210_clk_params k210_clks[] = {
329#if CONFIG_IS_ENABLED(CMD_CLK)
330#define NAME(_name) .name = (_name),
331#else
332#define NAME(name)
333#endif
334#define CLK(id, _name, _parent, _div, _gate) \
335 [id] = { \
336 NAME(_name) \
337 .parent = (_parent), \
338 .div = (_div), \
339 .gate = (_gate), \
340 }
341#define CLK_MUX(id, _name, _mux, _div, _gate) \
342 [id] = { \
343 NAME(_name) \
344 .flags = K210_CLKF_MUX, \
345 .mux = (_mux), \
346 .div = (_div), \
347 .gate = (_gate), \
348 }
349#define CLK_PLL(id, _pll, _parent) \
350 [id] = { \
351 NAME("pll" #_pll) \
352 .flags = K210_CLKF_PLL, \
353 .parent = (_parent), \
354 .pll = (_pll), \
355 }
356#define CLK_FULL(id, name) \
357 CLK_MUX(id, name, MUXIFY(id), DIVIFY(id), GATEIFY(id))
358#define CLK_NOMUX(id, name, parent) \
359 CLK(id, name, parent, DIVIFY(id), GATEIFY(id))
360#define CLK_DIV(id, name, parent) \
361 CLK(id, name, parent, DIVIFY(id), K210_CLK_GATE_NONE)
362#define CLK_GATE(id, name, parent) \
363 CLK(id, name, parent, K210_CLK_DIV_NONE, GATEIFY(id))
364 CLK_PLL(K210_CLK_PLL0, 0, K210_CLK_IN0),
365 CLK_PLL(K210_CLK_PLL1, 1, K210_CLK_IN0),
366 [K210_CLK_PLL2] = {
367 NAME("pll2")
368 .flags = K210_CLKF_MUX | K210_CLKF_PLL,
369 .mux = MUXIFY(K210_CLK_PLL2),
370 .pll = 2,
371 },
372 CLK_MUX(K210_CLK_ACLK, "aclk", MUXIFY(K210_CLK_ACLK),
373 DIVIFY(K210_CLK_ACLK), K210_CLK_GATE_NONE),
374 CLK_FULL(K210_CLK_SPI3, "spi3"),
375 CLK_FULL(K210_CLK_TIMER0, "timer0"),
376 CLK_FULL(K210_CLK_TIMER1, "timer1"),
377 CLK_FULL(K210_CLK_TIMER2, "timer2"),
378 CLK_NOMUX(K210_CLK_SRAM0, "sram0", K210_CLK_ACLK),
379 CLK_NOMUX(K210_CLK_SRAM1, "sram1", K210_CLK_ACLK),
380 CLK_NOMUX(K210_CLK_ROM, "rom", K210_CLK_ACLK),
381 CLK_NOMUX(K210_CLK_DVP, "dvp", K210_CLK_ACLK),
382 CLK_NOMUX(K210_CLK_APB0, "apb0", K210_CLK_ACLK),
383 CLK_NOMUX(K210_CLK_APB1, "apb1", K210_CLK_ACLK),
384 CLK_NOMUX(K210_CLK_APB2, "apb2", K210_CLK_ACLK),
385 CLK_NOMUX(K210_CLK_AI, "ai", K210_CLK_PLL1),
386 CLK_NOMUX(K210_CLK_I2S0, "i2s0", K210_CLK_PLL2),
387 CLK_NOMUX(K210_CLK_I2S1, "i2s1", K210_CLK_PLL2),
388 CLK_NOMUX(K210_CLK_I2S2, "i2s2", K210_CLK_PLL2),
389 CLK_NOMUX(K210_CLK_WDT0, "wdt0", K210_CLK_IN0),
390 CLK_NOMUX(K210_CLK_WDT1, "wdt1", K210_CLK_IN0),
391 CLK_NOMUX(K210_CLK_SPI0, "spi0", K210_CLK_PLL0),
392 CLK_NOMUX(K210_CLK_SPI1, "spi1", K210_CLK_PLL0),
393 CLK_NOMUX(K210_CLK_SPI2, "spi2", K210_CLK_PLL0),
394 CLK_NOMUX(K210_CLK_I2C0, "i2c0", K210_CLK_PLL0),
395 CLK_NOMUX(K210_CLK_I2C1, "i2c1", K210_CLK_PLL0),
396 CLK_NOMUX(K210_CLK_I2C2, "i2c2", K210_CLK_PLL0),
397 CLK_DIV(K210_CLK_I2S0_M, "i2s0_m", K210_CLK_PLL2),
398 CLK_DIV(K210_CLK_I2S1_M, "i2s1_m", K210_CLK_PLL2),
399 CLK_DIV(K210_CLK_I2S2_M, "i2s2_m", K210_CLK_PLL2),
400 CLK_DIV(K210_CLK_CLINT, "clint", K210_CLK_ACLK),
401 CLK_GATE(K210_CLK_CPU, "cpu", K210_CLK_ACLK),
402 CLK_GATE(K210_CLK_DMA, "dma", K210_CLK_ACLK),
403 CLK_GATE(K210_CLK_FFT, "fft", K210_CLK_ACLK),
404 CLK_GATE(K210_CLK_GPIO, "gpio", K210_CLK_APB0),
405 CLK_GATE(K210_CLK_UART1, "uart1", K210_CLK_APB0),
406 CLK_GATE(K210_CLK_UART2, "uart2", K210_CLK_APB0),
407 CLK_GATE(K210_CLK_UART3, "uart3", K210_CLK_APB0),
408 CLK_GATE(K210_CLK_FPIOA, "fpioa", K210_CLK_APB0),
409 CLK_GATE(K210_CLK_SHA, "sha", K210_CLK_APB0),
410 CLK_GATE(K210_CLK_AES, "aes", K210_CLK_APB1),
411 CLK_GATE(K210_CLK_OTP, "otp", K210_CLK_APB1),
412 CLK_GATE(K210_CLK_RTC, "rtc", K210_CLK_IN0),
413#undef NAME
414#undef CLK_PLL
415#undef CLK
416#undef CLK_FULL
417#undef CLK_NOMUX
418#undef CLK_DIV
419#undef CLK_GATE
420#undef CLK_LIST
421};
422
423#define K210_PLL_CLKR GENMASK(3, 0)
424#define K210_PLL_CLKF GENMASK(9, 4)
425#define K210_PLL_CLKOD GENMASK(13, 10)
426#define K210_PLL_BWADJ GENMASK(19, 14)
427#define K210_PLL_RESET BIT(20)
428#define K210_PLL_PWRD BIT(21)
429#define K210_PLL_INTFB BIT(22)
430#define K210_PLL_BYPASS BIT(23)
431#define K210_PLL_TEST BIT(24)
432#define K210_PLL_EN BIT(25)
433#define K210_PLL_TEST_EN BIT(26)
434
435#define K210_PLL_LOCK 0
436#define K210_PLL_CLEAR_SLIP 2
437#define K210_PLL_TEST_OUT 3
438
439#ifdef CONFIG_CLK_K210_SET_RATE
440static int k210_pll_enable(struct k210_clk_priv *priv, int id);
441static int k210_pll_disable(struct k210_clk_priv *priv, int id);
442static ulong k210_pll_get_rate(struct k210_clk_priv *priv, int id, ulong rate_in);
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554#define PACK(r, od) (((((r) - 1) & 0xF) << 4) | (((od) - 1) & 0xF))
555#define UNPACK_R(val) ((((val) >> 4) & 0xF) + 1)
556#define UNPACK_OD(val) (((val) & 0xF) + 1)
557static const u8 factors[] = {
558 PACK(1, 1),
559 PACK(1, 2),
560 PACK(1, 3),
561 PACK(1, 4),
562 PACK(1, 5),
563 PACK(1, 6),
564 PACK(1, 7),
565 PACK(1, 8),
566 PACK(1, 9),
567 PACK(3, 3),
568 PACK(1, 10),
569 PACK(1, 11),
570 PACK(1, 12),
571 PACK(3, 4),
572 PACK(1, 13),
573 PACK(1, 14),
574 PACK(1, 15),
575 PACK(3, 5),
576 PACK(1, 16),
577 PACK(4, 4),
578 PACK(2, 9),
579 PACK(2, 10),
580 PACK(3, 7),
581 PACK(2, 11),
582 PACK(2, 12),
583 PACK(5, 5),
584 PACK(2, 13),
585 PACK(3, 9),
586 PACK(2, 14),
587 PACK(2, 15),
588 PACK(2, 16),
589 PACK(3, 11),
590 PACK(5, 7),
591 PACK(3, 12),
592 PACK(3, 13),
593 PACK(4, 10),
594 PACK(3, 14),
595 PACK(4, 11),
596 PACK(3, 15),
597 PACK(3, 16),
598 PACK(7, 7),
599 PACK(5, 10),
600 PACK(4, 13),
601 PACK(6, 9),
602 PACK(5, 11),
603 PACK(4, 14),
604 PACK(4, 15),
605 PACK(7, 9),
606 PACK(4, 16),
607 PACK(5, 13),
608 PACK(6, 11),
609 PACK(5, 14),
610 PACK(6, 12),
611 PACK(5, 15),
612 PACK(7, 11),
613 PACK(6, 13),
614 PACK(5, 16),
615 PACK(9, 9),
616 PACK(6, 14),
617 PACK(8, 11),
618 PACK(6, 15),
619 PACK(7, 13),
620 PACK(6, 16),
621 PACK(7, 14),
622 PACK(9, 11),
623 PACK(10, 10),
624 PACK(8, 13),
625 PACK(7, 15),
626 PACK(9, 12),
627 PACK(10, 11),
628 PACK(7, 16),
629 PACK(9, 13),
630 PACK(8, 15),
631 PACK(11, 11),
632 PACK(9, 14),
633 PACK(8, 16),
634 PACK(10, 13),
635 PACK(11, 12),
636 PACK(9, 15),
637 PACK(10, 14),
638 PACK(11, 13),
639 PACK(9, 16),
640 PACK(10, 15),
641 PACK(11, 14),
642 PACK(12, 13),
643 PACK(10, 16),
644 PACK(11, 15),
645 PACK(12, 14),
646 PACK(13, 13),
647 PACK(11, 16),
648 PACK(12, 15),
649 PACK(13, 14),
650 PACK(12, 16),
651 PACK(13, 15),
652 PACK(14, 14),
653 PACK(13, 16),
654 PACK(14, 15),
655 PACK(14, 16),
656 PACK(15, 15),
657 PACK(15, 16),
658 PACK(16, 16),
659};
660
661TEST_STATIC int k210_pll_calc_config(u32 rate, u32 rate_in,
662 struct k210_pll_config *best)
663{
664 int i;
665 s64 error, best_error;
666 u64 ratio, inv_ratio;
667 u64 max_r;
668 u64 r, f, od;
669
670
671
672
673
674
675 if (rate > 1750000000 || rate < 21250000)
676 return -EINVAL;
677
678
679 if (rate_in > 1750000000 || rate_in < 13300000)
680 return -EINVAL;
681
682 ratio = DIV_ROUND_CLOSEST_ULL((u64)rate << 32, rate_in);
683 inv_ratio = DIV_ROUND_CLOSEST_ULL((u64)rate_in << 32, rate);
684
685 if (rate > rate_in && ratio > (64ULL << 32))
686 return -EINVAL;
687 else if (rate <= rate_in && inv_ratio > (256ULL << 32))
688 return -EINVAL;
689
690
691
692
693
694
695
696
697 max_r = DIV_ROUND_DOWN_ULL(rate_in, 13300000);
698
699
700 i = -1;
701 f = 0;
702 r = 0;
703 od = 0;
704 best_error = S64_MAX;
705 error = best_error;
706
707 do {
708
709
710
711 bool swapped = false;
712
713
714
715 bool out_of_spec;
716 u64 last_od = od;
717 u64 last_r = r;
718
719
720
721
722
723 if (rate > rate_in) {
724
725
726
727
728 do {
729 i++;
730 r = UNPACK_R(factors[i]);
731 od = UNPACK_OD(factors[i]);
732 } while (i + 1 < ARRAY_SIZE(factors) &&
733 r * od == last_r * last_od);
734
735
736 f = (r * od * ratio + BIT(31)) >> 32;
737 if (f > 64)
738 f = 64;
739 } else {
740 u64 tmp = ++f * inv_ratio;
741 bool round_up = !!(tmp & BIT(31));
742 u32 goal = (tmp >> 32) + round_up;
743 u32 err, last_err;
744
745
746 while (r * od < goal && i + 1 < ARRAY_SIZE(factors)) {
747 i++;
748 r = UNPACK_R(factors[i]);
749 od = UNPACK_OD(factors[i]);
750 }
751
752
753
754
755
756
757
758
759
760 err = abs(r * od - goal);
761 last_err = abs(last_r * last_od - goal);
762 if (last_err < err || (round_up && last_err == err)) {
763 i--;
764 r = last_r;
765 od = last_od;
766 }
767 }
768
769
770
771
772
773
774again:
775 out_of_spec = false;
776 if (r > max_r) {
777 out_of_spec = true;
778 } else {
779
780
781
782
783
784 u64 vco = DIV_ROUND_CLOSEST_ULL(rate_in * f, r);
785
786 if (vco > 1750000000 || vco < 340000000)
787 out_of_spec = true;
788 }
789
790 if (out_of_spec) {
791 u64 new_r, new_od;
792
793 if (!swapped) {
794 u64 tmp = r;
795
796 r = od;
797 od = tmp;
798 swapped = true;
799 goto again;
800 }
801
802
803
804
805
806 if (i + 1 < ARRAY_SIZE(factors)) {
807 i++;
808 new_r = UNPACK_R(factors[i]);
809 new_od = UNPACK_OD(factors[i]);
810 if (r * od == new_r * new_od) {
811 r = new_r;
812 od = new_od;
813 swapped = false;
814 goto again;
815 }
816 i--;
817 }
818
819
820
821
822
823 while (i > 0) {
824 i--;
825 new_r = UNPACK_R(factors[i]);
826 new_od = UNPACK_OD(factors[i]);
827
828
829
830
831
832 if (r * od != new_r * new_od) {
833 if (new_r * new_od > last_r * last_od) {
834 r = new_r;
835 od = new_od;
836 swapped = false;
837 goto again;
838 }
839 break;
840 }
841 }
842
843
844 continue;
845 }
846
847 error = DIV_ROUND_CLOSEST_ULL(f * inv_ratio, r * od);
848
849 error = abs((error - BIT(32))) >> 16;
850
851 if (error < best_error) {
852 best->r = r;
853 best->f = f;
854 best->od = od;
855 best_error = error;
856 }
857 } while (f < 64 && i + 1 < ARRAY_SIZE(factors) && error != 0);
858
859 log_debug("best error %lld\n", best_error);
860 if (best_error == S64_MAX)
861 return -EINVAL;
862
863 return 0;
864}
865
866static ulong k210_pll_set_rate(struct k210_clk_priv *priv, int id, ulong rate,
867 ulong rate_in)
868{
869 int err;
870 const struct k210_pll_params *pll = &k210_plls[id];
871 struct k210_pll_config config = {};
872 u32 reg;
873 ulong calc_rate;
874
875 err = k210_pll_calc_config(rate, rate_in, &config);
876 if (err)
877 return err;
878 log_debug("Got r=%u f=%u od=%u\n", config.r, config.f, config.od);
879
880
881 calc_rate = DIV_ROUND_DOWN_ULL(((u64)rate_in) * config.f,
882 config.r * config.od);
883 if (calc_rate == k210_pll_get_rate(priv, id, rate))
884 return calc_rate;
885
886 k210_pll_disable(priv, id);
887
888 reg = readl(priv->base + pll->off);
889 reg &= ~K210_PLL_CLKR
890 & ~K210_PLL_CLKF
891 & ~K210_PLL_CLKOD
892 & ~K210_PLL_BWADJ;
893 reg |= FIELD_PREP(K210_PLL_CLKR, config.r - 1)
894 | FIELD_PREP(K210_PLL_CLKF, config.f - 1)
895 | FIELD_PREP(K210_PLL_CLKOD, config.od - 1)
896 | FIELD_PREP(K210_PLL_BWADJ, config.f - 1);
897 writel(reg, priv->base + pll->off);
898
899 k210_pll_enable(priv, id);
900
901 serial_setbrg();
902 return k210_pll_get_rate(priv, id, rate);
903}
904#else
905static ulong k210_pll_set_rate(struct k210_clk_priv *priv, int id, ulong rate,
906 ulong rate_in)
907{
908 return -ENOSYS;
909}
910#endif
911
912static ulong k210_pll_get_rate(struct k210_clk_priv *priv, int id,
913 ulong rate_in)
914{
915 u64 r, f, od;
916 u32 reg = readl(priv->base + k210_plls[id].off);
917
918 if (reg & K210_PLL_BYPASS)
919 return rate_in;
920
921 if (!(reg & K210_PLL_PWRD))
922 return 0;
923
924 r = FIELD_GET(K210_PLL_CLKR, reg) + 1;
925 f = FIELD_GET(K210_PLL_CLKF, reg) + 1;
926 od = FIELD_GET(K210_PLL_CLKOD, reg) + 1;
927
928 return DIV_ROUND_DOWN_ULL(((u64)rate_in) * f, r * od);
929}
930
931
932
933
934
935static void k210_pll_waitfor_lock(struct k210_clk_priv *priv, int id)
936{
937 const struct k210_pll_params *pll = &k210_plls[id];
938 u32 mask = (BIT(pll->width) - 1) << pll->shift;
939
940 while (true) {
941 u32 reg = readl(priv->base + K210_SYSCTL_PLL_LOCK);
942
943 if ((reg & mask) == mask)
944 break;
945
946 reg |= BIT(pll->shift + K210_PLL_CLEAR_SLIP);
947 writel(reg, priv->base + K210_SYSCTL_PLL_LOCK);
948 }
949}
950
951static bool k210_pll_enabled(u32 reg)
952{
953 return (reg & K210_PLL_PWRD) && (reg & K210_PLL_EN) &&
954 !(reg & K210_PLL_RESET);
955}
956
957
958static int k210_pll_enable(struct k210_clk_priv *priv, int id)
959{
960 const struct k210_pll_params *pll = &k210_plls[id];
961 u32 reg = readl(priv->base + pll->off);
962
963 if (k210_pll_enabled(reg))
964 return 0;
965
966 reg |= K210_PLL_PWRD;
967 writel(reg, priv->base + pll->off);
968
969
970 reg &= ~K210_PLL_RESET;
971 writel(reg, priv->base + pll->off);
972 reg |= K210_PLL_RESET;
973 writel(reg, priv->base + pll->off);
974 nop();
975 nop();
976 reg &= ~K210_PLL_RESET;
977 writel(reg, priv->base + pll->off);
978
979 k210_pll_waitfor_lock(priv, id);
980
981 reg &= ~K210_PLL_BYPASS;
982 reg |= K210_PLL_EN;
983 writel(reg, priv->base + pll->off);
984
985 return 0;
986}
987
988static int k210_pll_disable(struct k210_clk_priv *priv, int id)
989{
990 const struct k210_pll_params *pll = &k210_plls[id];
991 u32 reg = readl(priv->base + pll->off);
992
993
994
995
996
997
998 reg |= K210_PLL_BYPASS;
999 writel(reg, priv->base + pll->off);
1000
1001 reg &= ~K210_PLL_PWRD;
1002 reg &= ~K210_PLL_EN;
1003 writel(reg, priv->base + pll->off);
1004 return 0;
1005}
1006
1007static u32 k210_clk_readl(struct k210_clk_priv *priv, u8 off, u8 shift,
1008 u8 width)
1009{
1010 u32 reg = readl(priv->base + off);
1011
1012 return (reg >> shift) & (BIT(width) - 1);
1013}
1014
1015static void k210_clk_writel(struct k210_clk_priv *priv, u8 off, u8 shift,
1016 u8 width, u32 val)
1017{
1018 u32 reg = readl(priv->base + off);
1019 u32 mask = (BIT(width) - 1) << shift;
1020
1021 reg &= ~mask;
1022 reg |= mask & (val << shift);
1023 writel(reg, priv->base + off);
1024}
1025
1026static int k210_clk_get_parent(struct k210_clk_priv *priv, int id)
1027{
1028 u32 sel;
1029 const struct k210_mux_params *mux;
1030
1031 if (!(k210_clks[id].flags & K210_CLKF_MUX))
1032 return k210_clks[id].parent;
1033 mux = &k210_muxes[k210_clks[id].mux];
1034
1035 sel = k210_clk_readl(priv, mux->off, mux->shift, mux->width);
1036 assert(sel < mux->num_parents);
1037 return mux->parents[sel];
1038}
1039
1040static ulong do_k210_clk_get_rate(struct k210_clk_priv *priv, int id)
1041{
1042 int parent;
1043 u32 val;
1044 ulong parent_rate;
1045 const struct k210_div_params *div;
1046
1047 if (id == K210_CLK_IN0)
1048 return clk_get_rate(&priv->in0);
1049
1050 parent = k210_clk_get_parent(priv, id);
1051 parent_rate = do_k210_clk_get_rate(priv, parent);
1052 if (IS_ERR_VALUE(parent_rate))
1053 return parent_rate;
1054
1055 if (k210_clks[id].flags & K210_CLKF_PLL)
1056 return k210_pll_get_rate(priv, k210_clks[id].pll, parent_rate);
1057
1058 if (k210_clks[id].div == K210_CLK_DIV_NONE)
1059 return parent_rate;
1060 div = &k210_divs[k210_clks[id].div];
1061
1062 if (div->type == K210_DIV_FIXED)
1063 return parent_rate / div->div;
1064
1065 val = k210_clk_readl(priv, div->off, div->shift, div->width);
1066 switch (div->type) {
1067 case K210_DIV_ONE:
1068 return parent_rate / (val + 1);
1069 case K210_DIV_EVEN:
1070 return parent_rate / 2 / (val + 1);
1071 case K210_DIV_POWER:
1072
1073 if (parent == K210_CLK_IN0)
1074 return parent_rate;
1075 return parent_rate / (2 << val);
1076 default:
1077 assert(false);
1078 return -EINVAL;
1079 };
1080}
1081
1082static ulong k210_clk_get_rate(struct clk *clk)
1083{
1084 return do_k210_clk_get_rate(dev_get_priv(clk->dev), clk->id);
1085}
1086
1087static int do_k210_clk_set_parent(struct k210_clk_priv *priv, int id, int new)
1088{
1089 int i;
1090 const struct k210_mux_params *mux;
1091
1092 if (!(k210_clks[id].flags & K210_CLKF_MUX))
1093 return -ENOSYS;
1094 mux = &k210_muxes[k210_clks[id].mux];
1095
1096 for (i = 0; i < mux->num_parents; i++) {
1097 if (mux->parents[i] == new) {
1098 k210_clk_writel(priv, mux->off, mux->shift, mux->width,
1099 i);
1100 return 0;
1101 }
1102 }
1103 return -EINVAL;
1104}
1105
1106static int k210_clk_set_parent(struct clk *clk, struct clk *parent)
1107{
1108 return do_k210_clk_set_parent(dev_get_priv(clk->dev), clk->id,
1109 parent->id);
1110}
1111
1112static ulong k210_clk_set_rate(struct clk *clk, unsigned long rate)
1113{
1114 int parent, ret, err;
1115 ulong rate_in, val;
1116 const struct k210_div_params *div;
1117 struct k210_clk_priv *priv = dev_get_priv(clk->dev);
1118
1119 if (clk->id == K210_CLK_IN0)
1120 return clk_set_rate(&priv->in0, rate);
1121
1122 parent = k210_clk_get_parent(priv, clk->id);
1123 rate_in = do_k210_clk_get_rate(priv, parent);
1124 if (IS_ERR_VALUE(rate_in))
1125 return rate_in;
1126
1127 log_debug("id=%ld rate=%lu rate_in=%lu\n", clk->id, rate, rate_in);
1128
1129 if (clk->id == K210_CLK_PLL0) {
1130
1131 ret = do_k210_clk_set_parent(priv, K210_CLK_ACLK, K210_CLK_IN0);
1132 if (ret)
1133 return ret;
1134 } else if (clk->id == K210_CLK_PLL1 && gd->flags & GD_FLG_RELOC) {
1135
1136
1137
1138
1139 return -EPERM;
1140 }
1141
1142 if (k210_clks[clk->id].flags & K210_CLKF_PLL) {
1143 ret = k210_pll_set_rate(priv, k210_clks[clk->id].pll, rate,
1144 rate_in);
1145 if (!IS_ERR_VALUE(ret) && clk->id == K210_CLK_PLL0) {
1146
1147
1148
1149
1150
1151 err = do_k210_clk_set_parent(priv, K210_CLK_ACLK,
1152 K210_CLK_PLL0);
1153 if (err)
1154 return err;
1155 }
1156 return ret;
1157 }
1158
1159 if (k210_clks[clk->id].div == K210_CLK_DIV_NONE)
1160 return -ENOSYS;
1161 div = &k210_divs[k210_clks[clk->id].div];
1162
1163 switch (div->type) {
1164 case K210_DIV_ONE:
1165 val = DIV_ROUND_CLOSEST_ULL((u64)rate_in, rate);
1166 val = val ? val - 1 : 0;
1167 break;
1168 case K210_DIV_EVEN:
1169 val = DIV_ROUND_CLOSEST_ULL((u64)rate_in, 2 * rate);
1170 break;
1171 case K210_DIV_POWER:
1172
1173 if (parent == K210_CLK_IN0)
1174 return -ENOSYS;
1175
1176 val = DIV_ROUND_CLOSEST_ULL((u64)rate_in, rate);
1177 val = __ffs(val);
1178 break;
1179 default:
1180 assert(false);
1181 return -EINVAL;
1182 };
1183
1184 val = val ? val - 1 : 0;
1185 k210_clk_writel(priv, div->off, div->shift, div->width, val);
1186 return do_k210_clk_get_rate(priv, clk->id);
1187}
1188
1189static int k210_clk_endisable(struct k210_clk_priv *priv, int id, bool enable)
1190{
1191 int parent = k210_clk_get_parent(priv, id);
1192 const struct k210_gate_params *gate;
1193
1194 if (id == K210_CLK_IN0) {
1195 if (enable)
1196 return clk_enable(&priv->in0);
1197 else
1198 return clk_disable(&priv->in0);
1199 }
1200
1201
1202 if (enable) {
1203 int ret = k210_clk_endisable(priv, parent, true);
1204
1205 if (ret && ret != -ENOSYS)
1206 return ret;
1207 }
1208
1209 if (k210_clks[id].flags & K210_CLKF_PLL) {
1210 if (enable)
1211 return k210_pll_enable(priv, k210_clks[id].pll);
1212 else
1213 return k210_pll_disable(priv, k210_clks[id].pll);
1214 }
1215
1216 if (k210_clks[id].gate == K210_CLK_GATE_NONE)
1217 return -ENOSYS;
1218 gate = &k210_gates[k210_clks[id].gate];
1219
1220 k210_clk_writel(priv, gate->off, gate->bit_idx, 1, enable);
1221 return 0;
1222}
1223
1224static int k210_clk_enable(struct clk *clk)
1225{
1226 return k210_clk_endisable(dev_get_priv(clk->dev), clk->id, true);
1227}
1228
1229static int k210_clk_disable(struct clk *clk)
1230{
1231 return k210_clk_endisable(dev_get_priv(clk->dev), clk->id, false);
1232}
1233
1234static int k210_clk_request(struct clk *clk)
1235{
1236 if (clk->id >= ARRAY_SIZE(k210_clks))
1237 return -EINVAL;
1238 return 0;
1239}
1240
1241static const struct clk_ops k210_clk_ops = {
1242 .request = k210_clk_request,
1243 .set_rate = k210_clk_set_rate,
1244 .get_rate = k210_clk_get_rate,
1245 .set_parent = k210_clk_set_parent,
1246 .enable = k210_clk_enable,
1247 .disable = k210_clk_disable,
1248};
1249
1250static int k210_clk_probe(struct udevice *dev)
1251{
1252 int ret;
1253 struct k210_clk_priv *priv = dev_get_priv(dev);
1254
1255 priv->base = dev_read_addr_ptr(dev_get_parent(dev));
1256 if (!priv->base)
1257 return -EINVAL;
1258
1259 ret = clk_get_by_index(dev, 0, &priv->in0);
1260 if (ret)
1261 return ret;
1262
1263
1264
1265
1266
1267 if (!(gd->flags & GD_FLG_RELOC))
1268 clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE);
1269
1270 return 0;
1271}
1272
1273static const struct udevice_id k210_clk_ids[] = {
1274 { .compatible = "kendryte,k210-clk" },
1275 { },
1276};
1277
1278U_BOOT_DRIVER(k210_clk) = {
1279 .name = "k210_clk",
1280 .id = UCLASS_CLK,
1281 .of_match = k210_clk_ids,
1282 .ops = &k210_clk_ops,
1283 .probe = k210_clk_probe,
1284 .priv_auto = sizeof(struct k210_clk_priv),
1285};
1286
1287#if CONFIG_IS_ENABLED(CMD_CLK)
1288static char show_enabled(struct k210_clk_priv *priv, int id)
1289{
1290 bool enabled;
1291
1292 if (k210_clks[id].flags & K210_CLKF_PLL) {
1293 const struct k210_pll_params *pll =
1294 &k210_plls[k210_clks[id].pll];
1295
1296 enabled = k210_pll_enabled(readl(priv->base + pll->off));
1297 } else if (k210_clks[id].gate == K210_CLK_GATE_NONE) {
1298 return '-';
1299 } else {
1300 const struct k210_gate_params *gate =
1301 &k210_gates[k210_clks[id].gate];
1302
1303 enabled = k210_clk_readl(priv, gate->off, gate->bit_idx, 1);
1304 }
1305
1306 return enabled ? 'y' : 'n';
1307}
1308
1309static void show_clks(struct k210_clk_priv *priv, int id, int depth)
1310{
1311 int i;
1312
1313 for (i = 0; i < ARRAY_SIZE(k210_clks); i++) {
1314 if (k210_clk_get_parent(priv, i) != id)
1315 continue;
1316
1317 printf(" %-9lu %-7c %*s%s\n", do_k210_clk_get_rate(priv, i),
1318 show_enabled(priv, i), depth * 4, "",
1319 k210_clks[i].name);
1320
1321 show_clks(priv, i, depth + 1);
1322 }
1323}
1324
1325int soc_clk_dump(void)
1326{
1327 int ret;
1328 struct udevice *dev;
1329 struct k210_clk_priv *priv;
1330
1331 ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(k210_clk),
1332 &dev);
1333 if (ret)
1334 return ret;
1335 priv = dev_get_priv(dev);
1336
1337 puts(" Rate Enabled Name\n");
1338 puts("------------------------\n");
1339 printf(" %-9lu %-7c %*s%s\n", clk_get_rate(&priv->in0), 'y', 0, "",
1340 priv->in0.dev->name);
1341 show_clks(priv, K210_CLK_IN0, 1);
1342 return 0;
1343}
1344#endif
1345