.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2014 MundoReader S.L. |
---|
3 | 4 | * 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. |
---|
14 | 5 | */ |
---|
15 | 6 | |
---|
16 | 7 | #include <linux/clk-provider.h> |
---|
| 8 | +#include <linux/io.h> |
---|
| 9 | +#include <linux/module.h> |
---|
17 | 10 | #include <linux/of.h> |
---|
18 | 11 | #include <linux/of_address.h> |
---|
| 12 | +#include <linux/of_device.h> |
---|
19 | 13 | #include <linux/syscore_ops.h> |
---|
20 | 14 | #include <dt-bindings/clock/rk3288-cru.h> |
---|
21 | 15 | #include "clk.h" |
---|
.. | .. |
---|
23 | 17 | |
---|
24 | 18 | #define RK3288_GRF_SOC_CON(x) (0x244 + x * 4) |
---|
25 | 19 | #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 | +}; |
---|
30 | 25 | |
---|
31 | 26 | enum rk3288_plls { |
---|
32 | 27 | apll, dpll, cpll, gpll, npll, |
---|
.. | .. |
---|
88 | 83 | RK3066_PLL_RATE( 768000000, 1, 64, 2), |
---|
89 | 84 | RK3066_PLL_RATE( 742500000, 4, 495, 4), |
---|
90 | 85 | RK3066_PLL_RATE( 696000000, 1, 58, 2), |
---|
| 86 | + RK3066_PLL_RATE_NB(621000000, 1, 207, 8, 1), |
---|
91 | 87 | RK3066_PLL_RATE( 600000000, 1, 50, 2), |
---|
92 | 88 | RK3066_PLL_RATE_NB(594000000, 1, 99, 4, 1), |
---|
93 | 89 | RK3066_PLL_RATE( 552000000, 1, 46, 2), |
---|
94 | 90 | RK3066_PLL_RATE( 504000000, 1, 84, 4), |
---|
95 | 91 | RK3066_PLL_RATE( 500000000, 1, 125, 6), |
---|
96 | 92 | RK3066_PLL_RATE( 456000000, 1, 76, 4), |
---|
97 | | - RK3066_PLL_RATE( 420000000, 1, 70, 4), |
---|
| 93 | + RK3066_PLL_RATE( 428000000, 1, 107, 6), |
---|
98 | 94 | RK3066_PLL_RATE( 408000000, 1, 68, 4), |
---|
99 | 95 | RK3066_PLL_RATE( 400000000, 1, 100, 6), |
---|
| 96 | + RK3066_PLL_RATE_NB( 394000000, 1, 197, 12, 1), |
---|
100 | 97 | RK3066_PLL_RATE( 384000000, 1, 64, 4), |
---|
101 | 98 | 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), |
---|
102 | 101 | 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), |
---|
104 | 106 | 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), |
---|
105 | 114 | 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), |
---|
107 | 124 | RK3066_PLL_RATE( 148500000, 1, 99, 16), |
---|
108 | 125 | RK3066_PLL_RATE( 126000000, 1, 84, 16), |
---|
109 | | - RK3066_PLL_RATE( 48000000, 1, 64, 32), |
---|
110 | 126 | { /* sentinel */ }, |
---|
111 | 127 | }; |
---|
112 | 128 | |
---|
.. | .. |
---|
179 | 195 | }; |
---|
180 | 196 | |
---|
181 | 197 | PNAME(mux_pll_p) = { "xin24m", "xin32k" }; |
---|
182 | | -PNAME(mux_armclk_p) = { "apll_core", "gpll_core" }; |
---|
183 | 198 | PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr" }; |
---|
184 | 199 | PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu" }; |
---|
185 | 200 | |
---|
186 | 201 | PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" }; |
---|
187 | 202 | PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" }; |
---|
188 | 203 | 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" }; |
---|
191 | 206 | |
---|
192 | 207 | PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "xin24m" }; |
---|
193 | 208 | PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" }; |
---|
.. | .. |
---|
223 | 238 | [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK3288_PLL_CON(4), |
---|
224 | 239 | RK3288_MODE_CON, 4, 5, 0, NULL), |
---|
225 | 240 | [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), |
---|
227 | 242 | [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), |
---|
229 | 244 | [npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16), |
---|
230 | 245 | RK3288_MODE_CON, 14, 9, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), |
---|
231 | 246 | }; |
---|
.. | .. |
---|
329 | 344 | RK3288_CLKSEL_CON(26), 2, 1, MFLAGS, 0, 2, |
---|
330 | 345 | DFLAGS | CLK_DIVIDER_POWER_OF_TWO), |
---|
331 | 346 | |
---|
332 | | - GATE(0, "gpll_aclk_cpu", "gpll", CLK_IGNORE_UNUSED, |
---|
| 347 | + GATE(0, "gpll_aclk_cpu", "gpll", CLK_IS_CRITICAL, |
---|
333 | 348 | 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, |
---|
335 | 350 | 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, |
---|
337 | 352 | RK3288_CLKSEL_CON(1), 15, 1, MFLAGS, 3, 5, DFLAGS), |
---|
338 | 353 | DIV(0, "aclk_cpu_pre", "aclk_cpu_src", CLK_SET_RATE_PARENT, |
---|
339 | 354 | 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, |
---|
341 | 356 | 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, |
---|
343 | 358 | RK3288_CLKSEL_CON(1), 12, 3, DFLAGS, |
---|
344 | 359 | 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, |
---|
346 | 361 | RK3288_CLKSEL_CON(1), 8, 2, DFLAGS, div_hclk_cpu_t, |
---|
347 | 362 | RK3288_CLKGATE_CON(0), 4, GFLAGS), |
---|
348 | 363 | GATE(0, "c2c_host", "aclk_cpu_src", 0, |
---|
.. | .. |
---|
361 | 376 | COMPOSITE_FRACMUX(0, "i2s_frac", "i2s_src", CLK_SET_RATE_PARENT, |
---|
362 | 377 | RK3288_CLKSEL_CON(8), 0, |
---|
363 | 378 | RK3288_CLKGATE_CON(4), 2, GFLAGS, |
---|
364 | | - &rk3288_i2s_fracmux, RK3288_I2S_FRAC_MAX_PRATE), |
---|
| 379 | + &rk3288_i2s_fracmux), |
---|
365 | 380 | COMPOSITE_NODIV(SCLK_I2S0_OUT, "i2s0_clkout", mux_i2s_clkout_p, 0, |
---|
366 | 381 | RK3288_CLKSEL_CON(4), 12, 1, MFLAGS, |
---|
367 | 382 | RK3288_CLKGATE_CON(4), 0, GFLAGS), |
---|
.. | .. |
---|
376 | 391 | COMPOSITE_FRACMUX(0, "spdif_frac", "spdif_src", CLK_SET_RATE_PARENT, |
---|
377 | 392 | RK3288_CLKSEL_CON(9), 0, |
---|
378 | 393 | RK3288_CLKGATE_CON(4), 5, GFLAGS, |
---|
379 | | - &rk3288_spdif_fracmux, RK3288_SPDIF_FRAC_MAX_PRATE), |
---|
| 394 | + &rk3288_spdif_fracmux), |
---|
380 | 395 | GATE(SCLK_SPDIF, "sclk_spdif", "spdif_mux", CLK_SET_RATE_PARENT, |
---|
381 | 396 | RK3288_CLKGATE_CON(4), 6, GFLAGS), |
---|
382 | 397 | COMPOSITE_NOMUX(0, "spdif_8ch_pre", "spdif_src", CLK_SET_RATE_PARENT, |
---|
.. | .. |
---|
385 | 400 | COMPOSITE_FRACMUX(0, "spdif_8ch_frac", "spdif_8ch_pre", CLK_SET_RATE_PARENT, |
---|
386 | 401 | RK3288_CLKSEL_CON(41), 0, |
---|
387 | 402 | RK3288_CLKGATE_CON(4), 8, GFLAGS, |
---|
388 | | - &rk3288_spdif_8ch_fracmux, RK3288_SPDIF_FRAC_MAX_PRATE), |
---|
| 403 | + &rk3288_spdif_8ch_fracmux), |
---|
389 | 404 | GATE(SCLK_SPDIF8CH, "sclk_spdif_8ch", "spdif_8ch_mux", CLK_SET_RATE_PARENT, |
---|
390 | 405 | RK3288_CLKGATE_CON(4), 9, GFLAGS), |
---|
391 | 406 | |
---|
.. | .. |
---|
443 | 458 | COMPOSITE(DCLK_VOP0, "dclk_vop0", mux_pll_src_cpll_gpll_npll_p, 0, |
---|
444 | 459 | RK3288_CLKSEL_CON(27), 0, 2, MFLAGS, 8, 8, DFLAGS, |
---|
445 | 460 | 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, |
---|
447 | 462 | 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), |
---|
449 | 464 | |
---|
450 | 465 | COMPOSITE_NODIV(SCLK_EDP_24M, "sclk_edp_24m", mux_edp_24m_p, 0, |
---|
451 | 466 | RK3288_CLKSEL_CON(28), 15, 1, MFLAGS, |
---|
.. | .. |
---|
485 | 500 | COMPOSITE_NOGATE(SCLK_VIP_OUT, "sclk_vip_out", mux_vip_out_p, 0, |
---|
486 | 501 | RK3288_CLKSEL_CON(26), 15, 1, MFLAGS, 9, 5, DFLAGS), |
---|
487 | 502 | |
---|
488 | | - DIV(PCLK_PD_ALIVE, "pclk_pd_alive", "gpll", 0, |
---|
| 503 | + DIV(PCLK_PD_ALIVE, "pclk_pd_alive", "gpll", CLK_IS_CRITICAL, |
---|
489 | 504 | 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, |
---|
491 | 506 | RK3288_CLKSEL_CON(33), 0, 5, DFLAGS, |
---|
492 | 507 | RK3288_CLKGATE_CON(5), 8, GFLAGS), |
---|
493 | 508 | |
---|
.. | .. |
---|
495 | 510 | RK3288_CLKSEL_CON(34), 6, 2, MFLAGS, 0, 5, DFLAGS, |
---|
496 | 511 | RK3288_CLKGATE_CON(5), 7, GFLAGS), |
---|
497 | 512 | |
---|
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, |
---|
499 | 514 | RK3288_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS, |
---|
500 | 515 | 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, |
---|
502 | 517 | RK3288_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, |
---|
503 | 518 | 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, |
---|
505 | 520 | RK3288_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, |
---|
506 | 521 | 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, |
---|
508 | 523 | RK3288_CLKGATE_CON(2), 1, GFLAGS), |
---|
509 | 524 | |
---|
510 | 525 | /* |
---|
.. | .. |
---|
592 | 607 | COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT, |
---|
593 | 608 | RK3288_CLKSEL_CON(17), 0, |
---|
594 | 609 | RK3288_CLKGATE_CON(1), 9, GFLAGS, |
---|
595 | | - &rk3288_uart0_fracmux, RK3288_UART_FRAC_MAX_PRATE), |
---|
| 610 | + &rk3288_uart0_fracmux), |
---|
596 | 611 | MUX(0, "uart_src", mux_pll_src_cpll_gpll_p, 0, |
---|
597 | 612 | RK3288_CLKSEL_CON(13), 15, 1, MFLAGS), |
---|
598 | 613 | COMPOSITE_NOMUX(0, "uart1_src", "uart_src", 0, |
---|
.. | .. |
---|
601 | 616 | COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT, |
---|
602 | 617 | RK3288_CLKSEL_CON(18), 0, |
---|
603 | 618 | RK3288_CLKGATE_CON(1), 11, GFLAGS, |
---|
604 | | - &rk3288_uart1_fracmux, RK3288_UART_FRAC_MAX_PRATE), |
---|
| 619 | + &rk3288_uart1_fracmux), |
---|
605 | 620 | COMPOSITE_NOMUX(0, "uart2_src", "uart_src", 0, |
---|
606 | 621 | RK3288_CLKSEL_CON(15), 0, 7, DFLAGS, |
---|
607 | 622 | RK3288_CLKGATE_CON(1), 12, GFLAGS), |
---|
608 | 623 | COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT, |
---|
609 | 624 | RK3288_CLKSEL_CON(19), 0, |
---|
610 | 625 | RK3288_CLKGATE_CON(1), 13, GFLAGS, |
---|
611 | | - &rk3288_uart2_fracmux, RK3288_UART_FRAC_MAX_PRATE), |
---|
| 626 | + &rk3288_uart2_fracmux), |
---|
612 | 627 | COMPOSITE_NOMUX(0, "uart3_src", "uart_src", 0, |
---|
613 | 628 | RK3288_CLKSEL_CON(16), 0, 7, DFLAGS, |
---|
614 | 629 | RK3288_CLKGATE_CON(1), 14, GFLAGS), |
---|
615 | 630 | COMPOSITE_FRACMUX(0, "uart3_frac", "uart3_src", CLK_SET_RATE_PARENT, |
---|
616 | 631 | RK3288_CLKSEL_CON(20), 0, |
---|
617 | 632 | RK3288_CLKGATE_CON(1), 15, GFLAGS, |
---|
618 | | - &rk3288_uart3_fracmux, RK3288_UART_FRAC_MAX_PRATE), |
---|
| 633 | + &rk3288_uart3_fracmux), |
---|
619 | 634 | COMPOSITE_NOMUX(0, "uart4_src", "uart_src", 0, |
---|
620 | 635 | RK3288_CLKSEL_CON(3), 0, 7, DFLAGS, |
---|
621 | 636 | RK3288_CLKGATE_CON(2), 12, GFLAGS), |
---|
622 | 637 | COMPOSITE_FRACMUX(0, "uart4_frac", "uart4_src", CLK_SET_RATE_PARENT, |
---|
623 | 638 | RK3288_CLKSEL_CON(7), 0, |
---|
624 | 639 | RK3288_CLKGATE_CON(2), 13, GFLAGS, |
---|
625 | | - &rk3288_uart4_fracmux, RK3288_UART_FRAC_MAX_PRATE), |
---|
| 640 | + &rk3288_uart4_fracmux), |
---|
626 | 641 | |
---|
627 | 642 | COMPOSITE(SCLK_MAC_PLL, "mac_pll_src", mux_pll_src_npll_cpll_gpll_p, 0, |
---|
628 | 643 | RK3288_CLKSEL_CON(21), 0, 2, MFLAGS, 8, 5, DFLAGS, |
---|
.. | .. |
---|
670 | 685 | GATE(0, "sclk_intmem0", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 5, GFLAGS), |
---|
671 | 686 | GATE(0, "sclk_intmem1", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 6, GFLAGS), |
---|
672 | 687 | 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), |
---|
674 | 689 | GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 13, GFLAGS), |
---|
675 | 690 | GATE(0, "aclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 4, GFLAGS), |
---|
676 | 691 | GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 6, GFLAGS), |
---|
.. | .. |
---|
696 | 711 | GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS), |
---|
697 | 712 | GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS), |
---|
698 | 713 | 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), |
---|
700 | 715 | |
---|
701 | 716 | /* ddrctrl [DDR Controller PHY clock] gates */ |
---|
702 | 717 | GATE(0, "nclk_ddrupctl0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 4, GFLAGS), |
---|
.. | .. |
---|
709 | 724 | /* aclk_peri gates */ |
---|
710 | 725 | GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 2, GFLAGS), |
---|
711 | 726 | 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), |
---|
713 | 728 | GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(8), 12, GFLAGS), |
---|
714 | 729 | GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 0, GFLAGS), |
---|
715 | 730 | GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 2, GFLAGS), |
---|
.. | .. |
---|
732 | 747 | GATE(HCLK_SDIO1, "hclk_sdio1", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 5, GFLAGS), |
---|
733 | 748 | GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 6, GFLAGS), |
---|
734 | 749 | 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), |
---|
736 | 751 | |
---|
737 | 752 | /* pclk_peri gates */ |
---|
738 | 753 | GATE(0, "pclk_peri_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 1, GFLAGS), |
---|
.. | .. |
---|
772 | 787 | GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 5, GFLAGS), |
---|
773 | 788 | GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 6, GFLAGS), |
---|
774 | 789 | 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"), |
---|
776 | 794 | |
---|
777 | 795 | /* pclk_pd_pmu gates */ |
---|
778 | 796 | GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 0, GFLAGS), |
---|
779 | 797 | 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), |
---|
781 | 799 | GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 3, GFLAGS), |
---|
782 | 800 | GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 4, GFLAGS), |
---|
783 | 801 | |
---|
.. | .. |
---|
786 | 804 | GATE(HCLK_VOP0, "hclk_vop0", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 6, GFLAGS), |
---|
787 | 805 | GATE(HCLK_VOP1, "hclk_vop1", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 8, GFLAGS), |
---|
788 | 806 | 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), |
---|
790 | 808 | GATE(HCLK_VIP, "hclk_vip", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 15, GFLAGS), |
---|
791 | 809 | GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 3, GFLAGS), |
---|
792 | 810 | GATE(HCLK_ISP, "hclk_isp", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 1, GFLAGS), |
---|
.. | .. |
---|
802 | 820 | /* aclk_vio0 gates */ |
---|
803 | 821 | GATE(ACLK_VOP0, "aclk_vop0", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 5, GFLAGS), |
---|
804 | 822 | 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), |
---|
806 | 824 | GATE(ACLK_VIP, "aclk_vip", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 14, GFLAGS), |
---|
807 | 825 | |
---|
808 | 826 | /* aclk_vio1 gates */ |
---|
809 | 827 | GATE(ACLK_VOP1, "aclk_vop1", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 7, GFLAGS), |
---|
810 | 828 | 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), |
---|
812 | 830 | |
---|
813 | 831 | /* aclk_rga_pre gates */ |
---|
814 | 832 | 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), |
---|
816 | 834 | |
---|
817 | 835 | /* |
---|
818 | 836 | * Other ungrouped clocks. |
---|
.. | .. |
---|
828 | 846 | GATE(SCLK_27M_TSP, "clk_27m_tsp", "ext_27m_tsp", 0, RK3288_CLKGATE_CON(8), 11, GFLAGS), |
---|
829 | 847 | }; |
---|
830 | 848 | |
---|
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), |
---|
848 | 857 | }; |
---|
849 | 858 | |
---|
850 | 859 | static void __iomem *rk3288_cru_base; |
---|
.. | .. |
---|
935 | 944 | } |
---|
936 | 945 | } |
---|
937 | 946 | |
---|
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) |
---|
939 | 949 | { |
---|
940 | 950 | struct rockchip_clk_provider *ctx; |
---|
941 | | - struct clk *clk; |
---|
| 951 | + struct clk **clks; |
---|
942 | 952 | |
---|
943 | 953 | rk3288_cru_base = of_iomap(np, 0); |
---|
944 | 954 | if (!rk3288_cru_base) { |
---|
.. | .. |
---|
952 | 962 | iounmap(rk3288_cru_base); |
---|
953 | 963 | return; |
---|
954 | 964 | } |
---|
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; |
---|
963 | 966 | |
---|
964 | 967 | rockchip_clk_register_plls(ctx, rk3288_pll_clks, |
---|
965 | 968 | ARRAY_SIZE(rk3288_pll_clks), |
---|
.. | .. |
---|
967 | 970 | rockchip_clk_register_branches(ctx, rk3288_clk_branches, |
---|
968 | 971 | ARRAY_SIZE(rk3288_clk_branches)); |
---|
969 | 972 | |
---|
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)); |
---|
982 | 976 | 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)); |
---|
987 | 979 | |
---|
988 | 980 | rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", |
---|
989 | | - mux_armclk_p, ARRAY_SIZE(mux_armclk_p), |
---|
| 981 | + 2, clks[PLL_APLL], clks[PLL_GPLL], |
---|
990 | 982 | &rk3288_cpuclk_data, rk3288_cpuclk_rates, |
---|
991 | 983 | ARRAY_SIZE(rk3288_cpuclk_rates)); |
---|
992 | 984 | |
---|
.. | .. |
---|
1005 | 997 | if (!rk_dump_cru) |
---|
1006 | 998 | rk_dump_cru = rk3288_dump_cru; |
---|
1007 | 999 | } |
---|
| 1000 | + |
---|
| 1001 | +static void __init rk3288_clk_init(struct device_node *np) |
---|
| 1002 | +{ |
---|
| 1003 | + rk3288_common_init(np, RK3288_CRU); |
---|
| 1004 | +} |
---|
1008 | 1005 | 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"); |
---|