hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/clk/rockchip/clk-rk3288.c
....@@ -1,21 +1,15 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (c) 2014 MundoReader S.L.
34 * Author: Heiko Stuebner <heiko@sntech.de>
4
- *
5
- * This program is free software; you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation; either version 2 of the License, or
8
- * (at your option) any later version.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
145 */
156
167 #include <linux/clk-provider.h>
8
+#include <linux/io.h>
9
+#include <linux/module.h>
1710 #include <linux/of.h>
1811 #include <linux/of_address.h>
12
+#include <linux/of_device.h>
1913 #include <linux/syscore_ops.h>
2014 #include <dt-bindings/clock/rk3288-cru.h>
2115 #include "clk.h"
....@@ -23,10 +17,11 @@
2317
2418 #define RK3288_GRF_SOC_CON(x) (0x244 + x * 4)
2519 #define RK3288_GRF_SOC_STATUS1 0x284
26
-#define RK3288_UART_FRAC_MAX_PRATE 600000000
27
-#define RK3288_I2S_FRAC_MAX_PRATE 600000000
28
-#define RK3288_SPDIF_FRAC_MAX_PRATE 600000000
29
-#define RK3288_DCLK_PARENT_MAX_PRATE 600000000
20
+
21
+enum rk3288_variant {
22
+ RK3288_CRU,
23
+ RK3288W_CRU,
24
+};
3025
3126 enum rk3288_plls {
3227 apll, dpll, cpll, gpll, npll,
....@@ -88,25 +83,46 @@
8883 RK3066_PLL_RATE( 768000000, 1, 64, 2),
8984 RK3066_PLL_RATE( 742500000, 4, 495, 4),
9085 RK3066_PLL_RATE( 696000000, 1, 58, 2),
86
+ RK3066_PLL_RATE_NB(621000000, 1, 207, 8, 1),
9187 RK3066_PLL_RATE( 600000000, 1, 50, 2),
9288 RK3066_PLL_RATE_NB(594000000, 1, 99, 4, 1),
9389 RK3066_PLL_RATE( 552000000, 1, 46, 2),
9490 RK3066_PLL_RATE( 504000000, 1, 84, 4),
9591 RK3066_PLL_RATE( 500000000, 1, 125, 6),
9692 RK3066_PLL_RATE( 456000000, 1, 76, 4),
97
- RK3066_PLL_RATE( 420000000, 1, 70, 4),
93
+ RK3066_PLL_RATE( 428000000, 1, 107, 6),
9894 RK3066_PLL_RATE( 408000000, 1, 68, 4),
9995 RK3066_PLL_RATE( 400000000, 1, 100, 6),
96
+ RK3066_PLL_RATE_NB( 394000000, 1, 197, 12, 1),
10097 RK3066_PLL_RATE( 384000000, 1, 64, 4),
10198 RK3066_PLL_RATE( 360000000, 1, 60, 4),
99
+ RK3066_PLL_RATE_NB( 356000000, 1, 178, 12, 1),
100
+ RK3066_PLL_RATE_NB( 324000000, 1, 189, 14, 1),
102101 RK3066_PLL_RATE( 312000000, 1, 52, 4),
103
- RK3066_PLL_RATE( 300000000, 1, 50, 4),
102
+ RK3066_PLL_RATE_NB( 308000000, 1, 154, 12, 1),
103
+ RK3066_PLL_RATE_NB( 303000000, 1, 202, 16, 1),
104
+ RK3066_PLL_RATE( 300000000, 1, 75, 6),
105
+ RK3066_PLL_RATE_NB( 297750000, 2, 397, 16, 1),
104106 RK3066_PLL_RATE( 297000000, 1, 99, 8),
107
+ RK3066_PLL_RATE_NB( 293250000, 2, 391, 16, 1),
108
+ RK3066_PLL_RATE_NB( 292500000, 1, 195, 16, 1),
109
+ RK3066_PLL_RATE( 273600000, 1, 114, 10),
110
+ RK3066_PLL_RATE_NB( 273000000, 1, 182, 16, 1),
111
+ RK3066_PLL_RATE_NB( 270000000, 1, 180, 16, 1),
112
+ RK3066_PLL_RATE_NB( 266250000, 2, 355, 16, 1),
113
+ RK3066_PLL_RATE_NB( 256500000, 1, 171, 16, 1),
105114 RK3066_PLL_RATE( 252000000, 1, 84, 8),
106
- RK3066_PLL_RATE( 216000000, 1, 72, 8),
115
+ RK3066_PLL_RATE_NB( 250500000, 1, 167, 16, 1),
116
+ RK3066_PLL_RATE_NB( 243428571, 1, 142, 14, 1),
117
+ RK3066_PLL_RATE( 238000000, 1, 119, 12),
118
+ RK3066_PLL_RATE_NB( 219750000, 2, 293, 16, 1),
119
+ RK3066_PLL_RATE_NB( 216000000, 1, 144, 16, 1),
120
+ RK3066_PLL_RATE_NB( 213000000, 1, 142, 16, 1),
121
+ RK3066_PLL_RATE( 195428571, 1, 114, 14),
122
+ RK3066_PLL_RATE( 160000000, 1, 80, 12),
123
+ RK3066_PLL_RATE( 157500000, 1, 105, 16),
107124 RK3066_PLL_RATE( 148500000, 1, 99, 16),
108125 RK3066_PLL_RATE( 126000000, 1, 84, 16),
109
- RK3066_PLL_RATE( 48000000, 1, 64, 32),
110126 { /* sentinel */ },
111127 };
112128
....@@ -179,15 +195,14 @@
179195 };
180196
181197 PNAME(mux_pll_p) = { "xin24m", "xin32k" };
182
-PNAME(mux_armclk_p) = { "apll_core", "gpll_core" };
183198 PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr" };
184199 PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu" };
185200
186201 PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" };
187202 PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" };
188203 PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" };
189
-PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usbphy480m_src" };
190
-PNAME(mux_pll_src_cpll_gll_usb_npll_p) = { "cpll", "gpll", "usbphy480m_src", "npll" };
204
+PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "unstable:usbphy480m_src" };
205
+PNAME(mux_pll_src_cpll_gll_usb_npll_p) = { "cpll", "gpll", "unstable:usbphy480m_src", "npll" };
191206
192207 PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "xin24m" };
193208 PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
....@@ -223,9 +238,9 @@
223238 [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK3288_PLL_CON(4),
224239 RK3288_MODE_CON, 4, 5, 0, NULL),
225240 [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK3288_PLL_CON(8),
226
- RK3288_MODE_CON, 8, 7, 0, rk3288_pll_rates),
241
+ RK3288_MODE_CON, 8, 7, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates),
227242 [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK3288_PLL_CON(12),
228
- RK3288_MODE_CON, 12, 8, 0, rk3288_pll_rates),
243
+ RK3288_MODE_CON, 12, 8, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates),
229244 [npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16),
230245 RK3288_MODE_CON, 14, 9, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates),
231246 };
....@@ -329,20 +344,20 @@
329344 RK3288_CLKSEL_CON(26), 2, 1, MFLAGS, 0, 2,
330345 DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
331346
332
- GATE(0, "gpll_aclk_cpu", "gpll", CLK_IGNORE_UNUSED,
347
+ GATE(0, "gpll_aclk_cpu", "gpll", CLK_IS_CRITICAL,
333348 RK3288_CLKGATE_CON(0), 10, GFLAGS),
334
- GATE(0, "cpll_aclk_cpu", "cpll", CLK_IGNORE_UNUSED,
349
+ GATE(0, "cpll_aclk_cpu", "cpll", CLK_IS_CRITICAL,
335350 RK3288_CLKGATE_CON(0), 11, GFLAGS),
336
- COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, CLK_IGNORE_UNUSED,
351
+ COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, CLK_IS_CRITICAL,
337352 RK3288_CLKSEL_CON(1), 15, 1, MFLAGS, 3, 5, DFLAGS),
338353 DIV(0, "aclk_cpu_pre", "aclk_cpu_src", CLK_SET_RATE_PARENT,
339354 RK3288_CLKSEL_CON(1), 0, 3, DFLAGS),
340
- GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED,
355
+ GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", CLK_IS_CRITICAL,
341356 RK3288_CLKGATE_CON(0), 3, GFLAGS),
342
- COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED,
357
+ COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_pre", CLK_IS_CRITICAL,
343358 RK3288_CLKSEL_CON(1), 12, 3, DFLAGS,
344359 RK3288_CLKGATE_CON(0), 5, GFLAGS),
345
- COMPOSITE_NOMUX_DIVTBL(HCLK_CPU, "hclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED,
360
+ COMPOSITE_NOMUX_DIVTBL(HCLK_CPU, "hclk_cpu", "aclk_cpu_pre", CLK_IS_CRITICAL,
346361 RK3288_CLKSEL_CON(1), 8, 2, DFLAGS, div_hclk_cpu_t,
347362 RK3288_CLKGATE_CON(0), 4, GFLAGS),
348363 GATE(0, "c2c_host", "aclk_cpu_src", 0,
....@@ -361,7 +376,7 @@
361376 COMPOSITE_FRACMUX(0, "i2s_frac", "i2s_src", CLK_SET_RATE_PARENT,
362377 RK3288_CLKSEL_CON(8), 0,
363378 RK3288_CLKGATE_CON(4), 2, GFLAGS,
364
- &rk3288_i2s_fracmux, RK3288_I2S_FRAC_MAX_PRATE),
379
+ &rk3288_i2s_fracmux),
365380 COMPOSITE_NODIV(SCLK_I2S0_OUT, "i2s0_clkout", mux_i2s_clkout_p, 0,
366381 RK3288_CLKSEL_CON(4), 12, 1, MFLAGS,
367382 RK3288_CLKGATE_CON(4), 0, GFLAGS),
....@@ -376,7 +391,7 @@
376391 COMPOSITE_FRACMUX(0, "spdif_frac", "spdif_src", CLK_SET_RATE_PARENT,
377392 RK3288_CLKSEL_CON(9), 0,
378393 RK3288_CLKGATE_CON(4), 5, GFLAGS,
379
- &rk3288_spdif_fracmux, RK3288_SPDIF_FRAC_MAX_PRATE),
394
+ &rk3288_spdif_fracmux),
380395 GATE(SCLK_SPDIF, "sclk_spdif", "spdif_mux", CLK_SET_RATE_PARENT,
381396 RK3288_CLKGATE_CON(4), 6, GFLAGS),
382397 COMPOSITE_NOMUX(0, "spdif_8ch_pre", "spdif_src", CLK_SET_RATE_PARENT,
....@@ -385,7 +400,7 @@
385400 COMPOSITE_FRACMUX(0, "spdif_8ch_frac", "spdif_8ch_pre", CLK_SET_RATE_PARENT,
386401 RK3288_CLKSEL_CON(41), 0,
387402 RK3288_CLKGATE_CON(4), 8, GFLAGS,
388
- &rk3288_spdif_8ch_fracmux, RK3288_SPDIF_FRAC_MAX_PRATE),
403
+ &rk3288_spdif_8ch_fracmux),
389404 GATE(SCLK_SPDIF8CH, "sclk_spdif_8ch", "spdif_8ch_mux", CLK_SET_RATE_PARENT,
390405 RK3288_CLKGATE_CON(4), 9, GFLAGS),
391406
....@@ -443,9 +458,9 @@
443458 COMPOSITE(DCLK_VOP0, "dclk_vop0", mux_pll_src_cpll_gpll_npll_p, 0,
444459 RK3288_CLKSEL_CON(27), 0, 2, MFLAGS, 8, 8, DFLAGS,
445460 RK3288_CLKGATE_CON(3), 1, GFLAGS),
446
- COMPOSITE_DCLK(DCLK_VOP1, "dclk_vop1", mux_pll_src_cpll_gpll_npll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
461
+ COMPOSITE(DCLK_VOP1, "dclk_vop1", mux_pll_src_cpll_gpll_npll_p, 0,
447462 RK3288_CLKSEL_CON(29), 6, 2, MFLAGS, 8, 8, DFLAGS,
448
- RK3288_CLKGATE_CON(3), 3, GFLAGS, RK3288_DCLK_PARENT_MAX_PRATE),
463
+ RK3288_CLKGATE_CON(3), 3, GFLAGS),
449464
450465 COMPOSITE_NODIV(SCLK_EDP_24M, "sclk_edp_24m", mux_edp_24m_p, 0,
451466 RK3288_CLKSEL_CON(28), 15, 1, MFLAGS,
....@@ -485,9 +500,9 @@
485500 COMPOSITE_NOGATE(SCLK_VIP_OUT, "sclk_vip_out", mux_vip_out_p, 0,
486501 RK3288_CLKSEL_CON(26), 15, 1, MFLAGS, 9, 5, DFLAGS),
487502
488
- DIV(PCLK_PD_ALIVE, "pclk_pd_alive", "gpll", 0,
503
+ DIV(PCLK_PD_ALIVE, "pclk_pd_alive", "gpll", CLK_IS_CRITICAL,
489504 RK3288_CLKSEL_CON(33), 8, 5, DFLAGS),
490
- COMPOSITE_NOMUX(PCLK_PD_PMU, "pclk_pd_pmu", "gpll", CLK_IGNORE_UNUSED,
505
+ COMPOSITE_NOMUX(PCLK_PD_PMU, "pclk_pd_pmu", "gpll", CLK_IS_CRITICAL,
491506 RK3288_CLKSEL_CON(33), 0, 5, DFLAGS,
492507 RK3288_CLKGATE_CON(5), 8, GFLAGS),
493508
....@@ -495,16 +510,16 @@
495510 RK3288_CLKSEL_CON(34), 6, 2, MFLAGS, 0, 5, DFLAGS,
496511 RK3288_CLKGATE_CON(5), 7, GFLAGS),
497512
498
- COMPOSITE(0, "aclk_peri_src", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED,
513
+ COMPOSITE(0, "aclk_peri_src", mux_pll_src_cpll_gpll_p, CLK_IS_CRITICAL,
499514 RK3288_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS,
500515 RK3288_CLKGATE_CON(2), 0, GFLAGS),
501
- COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0,
516
+ COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", CLK_IS_CRITICAL,
502517 RK3288_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
503518 RK3288_CLKGATE_CON(2), 3, GFLAGS),
504
- COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", CLK_IGNORE_UNUSED,
519
+ COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", CLK_IS_CRITICAL,
505520 RK3288_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
506521 RK3288_CLKGATE_CON(2), 2, GFLAGS),
507
- GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", CLK_IGNORE_UNUSED,
522
+ GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", CLK_IS_CRITICAL,
508523 RK3288_CLKGATE_CON(2), 1, GFLAGS),
509524
510525 /*
....@@ -592,7 +607,7 @@
592607 COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
593608 RK3288_CLKSEL_CON(17), 0,
594609 RK3288_CLKGATE_CON(1), 9, GFLAGS,
595
- &rk3288_uart0_fracmux, RK3288_UART_FRAC_MAX_PRATE),
610
+ &rk3288_uart0_fracmux),
596611 MUX(0, "uart_src", mux_pll_src_cpll_gpll_p, 0,
597612 RK3288_CLKSEL_CON(13), 15, 1, MFLAGS),
598613 COMPOSITE_NOMUX(0, "uart1_src", "uart_src", 0,
....@@ -601,28 +616,28 @@
601616 COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
602617 RK3288_CLKSEL_CON(18), 0,
603618 RK3288_CLKGATE_CON(1), 11, GFLAGS,
604
- &rk3288_uart1_fracmux, RK3288_UART_FRAC_MAX_PRATE),
619
+ &rk3288_uart1_fracmux),
605620 COMPOSITE_NOMUX(0, "uart2_src", "uart_src", 0,
606621 RK3288_CLKSEL_CON(15), 0, 7, DFLAGS,
607622 RK3288_CLKGATE_CON(1), 12, GFLAGS),
608623 COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
609624 RK3288_CLKSEL_CON(19), 0,
610625 RK3288_CLKGATE_CON(1), 13, GFLAGS,
611
- &rk3288_uart2_fracmux, RK3288_UART_FRAC_MAX_PRATE),
626
+ &rk3288_uart2_fracmux),
612627 COMPOSITE_NOMUX(0, "uart3_src", "uart_src", 0,
613628 RK3288_CLKSEL_CON(16), 0, 7, DFLAGS,
614629 RK3288_CLKGATE_CON(1), 14, GFLAGS),
615630 COMPOSITE_FRACMUX(0, "uart3_frac", "uart3_src", CLK_SET_RATE_PARENT,
616631 RK3288_CLKSEL_CON(20), 0,
617632 RK3288_CLKGATE_CON(1), 15, GFLAGS,
618
- &rk3288_uart3_fracmux, RK3288_UART_FRAC_MAX_PRATE),
633
+ &rk3288_uart3_fracmux),
619634 COMPOSITE_NOMUX(0, "uart4_src", "uart_src", 0,
620635 RK3288_CLKSEL_CON(3), 0, 7, DFLAGS,
621636 RK3288_CLKGATE_CON(2), 12, GFLAGS),
622637 COMPOSITE_FRACMUX(0, "uart4_frac", "uart4_src", CLK_SET_RATE_PARENT,
623638 RK3288_CLKSEL_CON(7), 0,
624639 RK3288_CLKGATE_CON(2), 13, GFLAGS,
625
- &rk3288_uart4_fracmux, RK3288_UART_FRAC_MAX_PRATE),
640
+ &rk3288_uart4_fracmux),
626641
627642 COMPOSITE(SCLK_MAC_PLL, "mac_pll_src", mux_pll_src_npll_cpll_gpll_p, 0,
628643 RK3288_CLKSEL_CON(21), 0, 2, MFLAGS, 8, 5, DFLAGS,
....@@ -670,7 +685,7 @@
670685 GATE(0, "sclk_intmem0", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 5, GFLAGS),
671686 GATE(0, "sclk_intmem1", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 6, GFLAGS),
672687 GATE(0, "sclk_intmem2", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 7, GFLAGS),
673
- GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 12, GFLAGS),
688
+ GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_cpu", CLK_IS_CRITICAL, RK3288_CLKGATE_CON(10), 12, GFLAGS),
674689 GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 13, GFLAGS),
675690 GATE(0, "aclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 4, GFLAGS),
676691 GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 6, GFLAGS),
....@@ -696,7 +711,7 @@
696711 GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS),
697712 GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS),
698713 GATE(PCLK_EFUSE256, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS),
699
- GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 11, GFLAGS),
714
+ GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", CLK_IS_CRITICAL, RK3288_CLKGATE_CON(11), 11, GFLAGS),
700715
701716 /* ddrctrl [DDR Controller PHY clock] gates */
702717 GATE(0, "nclk_ddrupctl0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 4, GFLAGS),
....@@ -709,7 +724,7 @@
709724 /* aclk_peri gates */
710725 GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 2, GFLAGS),
711726 GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 3, GFLAGS),
712
- GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK3288_CLKGATE_CON(7), 11, GFLAGS),
727
+ GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IS_CRITICAL, RK3288_CLKGATE_CON(7), 11, GFLAGS),
713728 GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(8), 12, GFLAGS),
714729 GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 0, GFLAGS),
715730 GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 2, GFLAGS),
....@@ -732,7 +747,7 @@
732747 GATE(HCLK_SDIO1, "hclk_sdio1", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 5, GFLAGS),
733748 GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 6, GFLAGS),
734749 GATE(HCLK_HSADC, "hclk_hsadc", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 7, GFLAGS),
735
- GATE(0, "pmu_hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 5, GFLAGS),
750
+ GATE(0, "pmu_hclk_otg0", "hclk_peri", CLK_IS_CRITICAL, RK3288_CLKGATE_CON(7), 5, GFLAGS),
736751
737752 /* pclk_peri gates */
738753 GATE(0, "pclk_peri_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 1, GFLAGS),
....@@ -772,12 +787,15 @@
772787 GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 5, GFLAGS),
773788 GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 6, GFLAGS),
774789 GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 11, GFLAGS),
775
- GATE(0, "pclk_alive_niu", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 12, GFLAGS),
790
+ GATE(0, "pclk_alive_niu", "pclk_pd_alive", CLK_IS_CRITICAL, RK3288_CLKGATE_CON(14), 12, GFLAGS),
791
+
792
+ /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */
793
+ SGRF_GATE(PCLK_WDT, "pclk_wdt", "pclk_pd_alive"),
776794
777795 /* pclk_pd_pmu gates */
778796 GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 0, GFLAGS),
779797 GATE(0, "pclk_intmem1", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 1, GFLAGS),
780
- GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 2, GFLAGS),
798
+ GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", CLK_IS_CRITICAL, RK3288_CLKGATE_CON(17), 2, GFLAGS),
781799 GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 3, GFLAGS),
782800 GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 4, GFLAGS),
783801
....@@ -786,7 +804,7 @@
786804 GATE(HCLK_VOP0, "hclk_vop0", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 6, GFLAGS),
787805 GATE(HCLK_VOP1, "hclk_vop1", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 8, GFLAGS),
788806 GATE(HCLK_VIO_AHB_ARBI, "hclk_vio_ahb_arbi", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 9, GFLAGS),
789
- GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 10, GFLAGS),
807
+ GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", CLK_IS_CRITICAL, RK3288_CLKGATE_CON(15), 10, GFLAGS),
790808 GATE(HCLK_VIP, "hclk_vip", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 15, GFLAGS),
791809 GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 3, GFLAGS),
792810 GATE(HCLK_ISP, "hclk_isp", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 1, GFLAGS),
....@@ -802,17 +820,17 @@
802820 /* aclk_vio0 gates */
803821 GATE(ACLK_VOP0, "aclk_vop0", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 5, GFLAGS),
804822 GATE(ACLK_IEP, "aclk_iep", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 2, GFLAGS),
805
- GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 11, GFLAGS),
823
+ GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", CLK_IS_CRITICAL, RK3288_CLKGATE_CON(15), 11, GFLAGS),
806824 GATE(ACLK_VIP, "aclk_vip", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 14, GFLAGS),
807825
808826 /* aclk_vio1 gates */
809827 GATE(ACLK_VOP1, "aclk_vop1", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 7, GFLAGS),
810828 GATE(ACLK_ISP, "aclk_isp", "aclk_vio1", 0, RK3288_CLKGATE_CON(16), 2, GFLAGS),
811
- GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 12, GFLAGS),
829
+ GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", CLK_IS_CRITICAL, RK3288_CLKGATE_CON(15), 12, GFLAGS),
812830
813831 /* aclk_rga_pre gates */
814832 GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 0, GFLAGS),
815
- GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 13, GFLAGS),
833
+ GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", CLK_IS_CRITICAL, RK3288_CLKGATE_CON(15), 13, GFLAGS),
816834
817835 /*
818836 * Other ungrouped clocks.
....@@ -828,23 +846,14 @@
828846 GATE(SCLK_27M_TSP, "clk_27m_tsp", "ext_27m_tsp", 0, RK3288_CLKGATE_CON(8), 11, GFLAGS),
829847 };
830848
831
-static const char *const rk3288_critical_clocks[] __initconst = {
832
- "aclk_cpu",
833
- "aclk_peri",
834
- "aclk_peri_niu",
835
- "aclk_vio0_niu",
836
- "aclk_vio1_niu",
837
- "aclk_rga_niu",
838
- "hclk_peri",
839
- "hclk_vio_niu",
840
- "pclk_peri",
841
- "pclk_alive_niu",
842
- "pclk_pd_pmu",
843
- "pclk_pmu_niu",
844
- "pmu_hclk_otg0",
845
- "aclk_dmac1",
846
- /* pwm-regulators on some boards, so handoff-critical later */
847
- "pclk_rkpwm",
849
+static struct rockchip_clk_branch rk3288w_hclkvio_branch[] __initdata = {
850
+ DIV(0, "hclk_vio", "aclk_vio1", 0,
851
+ RK3288_CLKSEL_CON(28), 8, 5, DFLAGS),
852
+};
853
+
854
+static struct rockchip_clk_branch rk3288_hclkvio_branch[] __initdata = {
855
+ DIV(0, "hclk_vio", "aclk_vio0", 0,
856
+ RK3288_CLKSEL_CON(28), 8, 5, DFLAGS),
848857 };
849858
850859 static void __iomem *rk3288_cru_base;
....@@ -935,10 +944,11 @@
935944 }
936945 }
937946
938
-static void __init rk3288_clk_init(struct device_node *np)
947
+static void __init rk3288_common_init(struct device_node *np,
948
+ enum rk3288_variant soc)
939949 {
940950 struct rockchip_clk_provider *ctx;
941
- struct clk *clk;
951
+ struct clk **clks;
942952
943953 rk3288_cru_base = of_iomap(np, 0);
944954 if (!rk3288_cru_base) {
....@@ -952,14 +962,7 @@
952962 iounmap(rk3288_cru_base);
953963 return;
954964 }
955
-
956
- /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */
957
- clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1);
958
- if (IS_ERR(clk))
959
- pr_warn("%s: could not register clock pclk_wdt: %ld\n",
960
- __func__, PTR_ERR(clk));
961
- else
962
- rockchip_clk_add_lookup(ctx, clk, PCLK_WDT);
965
+ clks = ctx->clk_data.clks;
963966
964967 rockchip_clk_register_plls(ctx, rk3288_pll_clks,
965968 ARRAY_SIZE(rk3288_pll_clks),
....@@ -967,26 +970,15 @@
967970 rockchip_clk_register_branches(ctx, rk3288_clk_branches,
968971 ARRAY_SIZE(rk3288_clk_branches));
969972
970
- if (of_machine_is_compatible("rockchip,rk3288w")) {
971
- clk = clk_register_divider(NULL, "hclk_vio", "aclk_vio1", 0,
972
- ctx->reg_base + RK3288_CLKSEL_CON(28), 8, 5,
973
- DFLAGS, &ctx->lock);
974
- } else {
975
- clk = clk_register_divider(NULL, "hclk_vio", "aclk_vio0", 0,
976
- ctx->reg_base + RK3288_CLKSEL_CON(28), 8, 5,
977
- DFLAGS, &ctx->lock);
978
- }
979
- if (IS_ERR(clk))
980
- pr_warn("%s: could not register clock hclk_vio: %ld\n",
981
- __func__, PTR_ERR(clk));
973
+ if (soc == RK3288W_CRU)
974
+ rockchip_clk_register_branches(ctx, rk3288w_hclkvio_branch,
975
+ ARRAY_SIZE(rk3288w_hclkvio_branch));
982976 else
983
- rockchip_clk_add_lookup(ctx, clk, HCLK_VIO);
984
-
985
- rockchip_clk_protect_critical(rk3288_critical_clocks,
986
- ARRAY_SIZE(rk3288_critical_clocks));
977
+ rockchip_clk_register_branches(ctx, rk3288_hclkvio_branch,
978
+ ARRAY_SIZE(rk3288_hclkvio_branch));
987979
988980 rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
989
- mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
981
+ 2, clks[PLL_APLL], clks[PLL_GPLL],
990982 &rk3288_cpuclk_data, rk3288_cpuclk_rates,
991983 ARRAY_SIZE(rk3288_cpuclk_rates));
992984
....@@ -1005,4 +997,67 @@
1005997 if (!rk_dump_cru)
1006998 rk_dump_cru = rk3288_dump_cru;
1007999 }
1000
+
1001
+static void __init rk3288_clk_init(struct device_node *np)
1002
+{
1003
+ rk3288_common_init(np, RK3288_CRU);
1004
+}
10081005 CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
1006
+
1007
+static void __init rk3288w_clk_init(struct device_node *np)
1008
+{
1009
+ rk3288_common_init(np, RK3288W_CRU);
1010
+}
1011
+CLK_OF_DECLARE(rk3288w_cru, "rockchip,rk3288w-cru", rk3288w_clk_init);
1012
+
1013
+struct clk_rk3288_inits {
1014
+ void (*inits)(struct device_node *np);
1015
+};
1016
+
1017
+static const struct clk_rk3288_inits clk_rk3288_init = {
1018
+ .inits = rk3288_clk_init,
1019
+};
1020
+
1021
+static const struct clk_rk3288_inits clk_rk3288w_init = {
1022
+ .inits = rk3288w_clk_init,
1023
+};
1024
+
1025
+static const struct of_device_id clk_rk3288_match_table[] = {
1026
+ {
1027
+ .compatible = "rockchip,rk3288-cru",
1028
+ .data = &clk_rk3288_init,
1029
+ }, {
1030
+ .compatible = "rockchip,rk3288w-cru",
1031
+ .data = &clk_rk3288w_init,
1032
+ },
1033
+ { }
1034
+};
1035
+MODULE_DEVICE_TABLE(of, clk_rk3288_match_table);
1036
+
1037
+static int __init clk_rk3288_probe(struct platform_device *pdev)
1038
+{
1039
+ struct device_node *np = pdev->dev.of_node;
1040
+ const struct of_device_id *match;
1041
+ const struct clk_rk3288_inits *init_data;
1042
+
1043
+ match = of_match_device(clk_rk3288_match_table, &pdev->dev);
1044
+ if (!match || !match->data)
1045
+ return -EINVAL;
1046
+
1047
+ init_data = match->data;
1048
+ if (init_data->inits)
1049
+ init_data->inits(np);
1050
+
1051
+ return 0;
1052
+}
1053
+
1054
+static struct platform_driver clk_rk3288_driver = {
1055
+ .driver = {
1056
+ .name = "clk-rk3288",
1057
+ .of_match_table = clk_rk3288_match_table,
1058
+ },
1059
+};
1060
+builtin_platform_driver_probe(clk_rk3288_driver, clk_rk3288_probe);
1061
+
1062
+MODULE_DESCRIPTION("Rockchip RK3288 Clock Driver");
1063
+MODULE_LICENSE("GPL");