1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2016 Chen-Yu Tsai. All rights reserved.
6 #include <linux/clk-provider.h>
8 #include <linux/of_address.h>
9 #include <linux/platform_device.h>
11 #include "ccu_common.h"
12 #include "ccu_reset.h"
19 #include "ccu_phase.h"
21 #include "ccu-sun9i-a80.h"
23 #define CCU_SUN9I_LOCK_REG 0x09c
26 * The CPU PLLs are actually NP clocks, with P being /1 or /4. However
27 * P should only be used for output frequencies lower than 228 MHz.
28 * Neither mainline Linux, U-boot, nor the vendor BSPs use these.
30 * For now we can just model it as a multiplier clock, and force P to /1.
32 #define SUN9I_A80_PLL_C0CPUX_REG 0x000
33 #define SUN9I_A80_PLL_C1CPUX_REG 0x004
35 static struct ccu_mult pll_c0cpux_clk
= {
38 .mult
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
40 .reg
= SUN9I_A80_PLL_C0CPUX_REG
,
41 .lock_reg
= CCU_SUN9I_LOCK_REG
,
42 .features
= CCU_FEATURE_LOCK_REG
,
43 .hw
.init
= CLK_HW_INIT("pll-c0cpux", "osc24M",
49 static struct ccu_mult pll_c1cpux_clk
= {
52 .mult
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
54 .reg
= SUN9I_A80_PLL_C1CPUX_REG
,
55 .lock_reg
= CCU_SUN9I_LOCK_REG
,
56 .features
= CCU_FEATURE_LOCK_REG
,
57 .hw
.init
= CLK_HW_INIT("pll-c1cpux", "osc24M",
64 * The Audio PLL has d1, d2 dividers in addition to the usual N, M
65 * factors. Since we only need 2 frequencies from this PLL: 22.5792 MHz
66 * and 24.576 MHz, ignore them for now. Enforce d1 = 0 and d2 = 0.
68 #define SUN9I_A80_PLL_AUDIO_REG 0x008
70 static struct ccu_nm pll_audio_clk
= {
73 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
74 .m
= _SUNXI_CCU_DIV_OFFSET(0, 6, 0),
77 .lock_reg
= CCU_SUN9I_LOCK_REG
,
78 .features
= CCU_FEATURE_LOCK_REG
,
79 .hw
.init
= CLK_HW_INIT("pll-audio", "osc24M",
80 &ccu_nm_ops
, CLK_SET_RATE_UNGATE
),
84 /* Some PLLs are input * N / div1 / div2. Model them as NKMP with no K */
85 static struct ccu_nkmp pll_periph0_clk
= {
88 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
89 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
90 .p
= _SUNXI_CCU_DIV(18, 1), /* output divider */
93 .lock_reg
= CCU_SUN9I_LOCK_REG
,
94 .features
= CCU_FEATURE_LOCK_REG
,
95 .hw
.init
= CLK_HW_INIT("pll-periph0", "osc24M",
101 static struct ccu_nkmp pll_ve_clk
= {
104 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
105 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
106 .p
= _SUNXI_CCU_DIV(18, 1), /* output divider */
109 .lock_reg
= CCU_SUN9I_LOCK_REG
,
110 .features
= CCU_FEATURE_LOCK_REG
,
111 .hw
.init
= CLK_HW_INIT("pll-ve", "osc24M",
113 CLK_SET_RATE_UNGATE
),
117 static struct ccu_nkmp pll_ddr_clk
= {
120 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
121 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
122 .p
= _SUNXI_CCU_DIV(18, 1), /* output divider */
125 .lock_reg
= CCU_SUN9I_LOCK_REG
,
126 .features
= CCU_FEATURE_LOCK_REG
,
127 .hw
.init
= CLK_HW_INIT("pll-ddr", "osc24M",
129 CLK_SET_RATE_UNGATE
),
133 static struct ccu_nm pll_video0_clk
= {
136 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
137 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
140 .lock_reg
= CCU_SUN9I_LOCK_REG
,
141 .features
= CCU_FEATURE_LOCK_REG
,
142 .hw
.init
= CLK_HW_INIT("pll-video0", "osc24M",
144 CLK_SET_RATE_UNGATE
),
148 static struct ccu_nkmp pll_video1_clk
= {
151 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
152 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
153 .p
= _SUNXI_CCU_DIV(0, 2), /* external divider p */
156 .lock_reg
= CCU_SUN9I_LOCK_REG
,
157 .features
= CCU_FEATURE_LOCK_REG
,
158 .hw
.init
= CLK_HW_INIT("pll-video1", "osc24M",
160 CLK_SET_RATE_UNGATE
),
164 static struct ccu_nkmp pll_gpu_clk
= {
167 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
168 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
169 .p
= _SUNXI_CCU_DIV(18, 1), /* output divider */
172 .lock_reg
= CCU_SUN9I_LOCK_REG
,
173 .features
= CCU_FEATURE_LOCK_REG
,
174 .hw
.init
= CLK_HW_INIT("pll-gpu", "osc24M",
176 CLK_SET_RATE_UNGATE
),
180 static struct ccu_nkmp pll_de_clk
= {
183 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
184 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
185 .p
= _SUNXI_CCU_DIV(18, 1), /* output divider */
188 .lock_reg
= CCU_SUN9I_LOCK_REG
,
189 .features
= CCU_FEATURE_LOCK_REG
,
190 .hw
.init
= CLK_HW_INIT("pll-de", "osc24M",
192 CLK_SET_RATE_UNGATE
),
196 static struct ccu_nkmp pll_isp_clk
= {
199 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
200 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
201 .p
= _SUNXI_CCU_DIV(18, 1), /* output divider */
204 .lock_reg
= CCU_SUN9I_LOCK_REG
,
205 .features
= CCU_FEATURE_LOCK_REG
,
206 .hw
.init
= CLK_HW_INIT("pll-isp", "osc24M",
208 CLK_SET_RATE_UNGATE
),
212 static struct ccu_nkmp pll_periph1_clk
= {
215 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
216 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
217 .p
= _SUNXI_CCU_DIV(18, 1), /* output divider */
220 .lock_reg
= CCU_SUN9I_LOCK_REG
,
221 .features
= CCU_FEATURE_LOCK_REG
,
222 .hw
.init
= CLK_HW_INIT("pll-periph1", "osc24M",
224 CLK_SET_RATE_UNGATE
),
228 static const char * const c0cpux_parents
[] = { "osc24M", "pll-c0cpux" };
229 static SUNXI_CCU_MUX(c0cpux_clk
, "c0cpux", c0cpux_parents
,
230 0x50, 0, 1, CLK_SET_RATE_PARENT
| CLK_IS_CRITICAL
);
232 static const char * const c1cpux_parents
[] = { "osc24M", "pll-c1cpux" };
233 static SUNXI_CCU_MUX(c1cpux_clk
, "c1cpux", c1cpux_parents
,
234 0x50, 8, 1, CLK_SET_RATE_PARENT
| CLK_IS_CRITICAL
);
236 static struct clk_div_table axi_div_table
[] = {
237 { .val
= 0, .div
= 1 },
238 { .val
= 1, .div
= 2 },
239 { .val
= 2, .div
= 3 },
240 { .val
= 3, .div
= 4 },
241 { .val
= 4, .div
= 4 },
242 { .val
= 5, .div
= 4 },
243 { .val
= 6, .div
= 4 },
244 { .val
= 7, .div
= 4 },
248 static SUNXI_CCU_M(atb0_clk
, "atb0", "c0cpux", 0x054, 8, 2, 0);
250 static SUNXI_CCU_DIV_TABLE(axi0_clk
, "axi0", "c0cpux",
251 0x054, 0, 3, axi_div_table
, 0);
253 static SUNXI_CCU_M(atb1_clk
, "atb1", "c1cpux", 0x058, 8, 2, 0);
255 static SUNXI_CCU_DIV_TABLE(axi1_clk
, "axi1", "c1cpux",
256 0x058, 0, 3, axi_div_table
, 0);
258 static const char * const gtbus_parents
[] = { "osc24M", "pll-periph0",
259 "pll-periph1", "pll-periph1" };
260 static SUNXI_CCU_M_WITH_MUX(gtbus_clk
, "gtbus", gtbus_parents
,
261 0x05c, 0, 2, 24, 2, CLK_IS_CRITICAL
);
263 static const char * const ahb_parents
[] = { "gtbus", "pll-periph0",
264 "pll-periph1", "pll-periph1" };
265 static struct ccu_div ahb0_clk
= {
266 .div
= _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO
),
267 .mux
= _SUNXI_CCU_MUX(24, 2),
270 .hw
.init
= CLK_HW_INIT_PARENTS("ahb0",
277 static struct ccu_div ahb1_clk
= {
278 .div
= _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO
),
279 .mux
= _SUNXI_CCU_MUX(24, 2),
282 .hw
.init
= CLK_HW_INIT_PARENTS("ahb1",
289 static struct ccu_div ahb2_clk
= {
290 .div
= _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO
),
291 .mux
= _SUNXI_CCU_MUX(24, 2),
294 .hw
.init
= CLK_HW_INIT_PARENTS("ahb2",
301 static const char * const apb_parents
[] = { "osc24M", "pll-periph0" };
303 static struct ccu_div apb0_clk
= {
304 .div
= _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO
),
305 .mux
= _SUNXI_CCU_MUX(24, 1),
308 .hw
.init
= CLK_HW_INIT_PARENTS("apb0",
315 static struct ccu_div apb1_clk
= {
316 .div
= _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO
),
317 .mux
= _SUNXI_CCU_MUX(24, 1),
320 .hw
.init
= CLK_HW_INIT_PARENTS("apb1",
327 static struct ccu_div cci400_clk
= {
328 .div
= _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO
),
329 .mux
= _SUNXI_CCU_MUX(24, 2),
332 .hw
.init
= CLK_HW_INIT_PARENTS("cci400",
339 static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk
, "ats", apb_parents
,
340 0x080, 0, 3, 24, 2, BIT(31), 0);
342 static SUNXI_CCU_M_WITH_MUX_GATE(trace_clk
, "trace", apb_parents
,
343 0x084, 0, 3, 24, 2, BIT(31), 0);
345 static const char * const out_parents
[] = { "osc24M", "osc32k", "osc24M" };
346 static const struct ccu_mux_fixed_prediv out_prediv
= {
347 .index
= 0, .div
= 750
350 static struct ccu_mp out_a_clk
= {
352 .m
= _SUNXI_CCU_DIV(8, 5),
353 .p
= _SUNXI_CCU_DIV(20, 2),
357 .fixed_predivs
= &out_prediv
,
362 .features
= CCU_FEATURE_FIXED_PREDIV
,
363 .hw
.init
= CLK_HW_INIT_PARENTS("out-a",
370 static struct ccu_mp out_b_clk
= {
372 .m
= _SUNXI_CCU_DIV(8, 5),
373 .p
= _SUNXI_CCU_DIV(20, 2),
377 .fixed_predivs
= &out_prediv
,
382 .features
= CCU_FEATURE_FIXED_PREDIV
,
383 .hw
.init
= CLK_HW_INIT_PARENTS("out-b",
390 static const char * const mod0_default_parents
[] = { "osc24M", "pll-periph0" };
392 static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_0_clk
, "nand0-0", mod0_default_parents
,
400 static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_1_clk
, "nand0-1", mod0_default_parents
,
408 static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_0_clk
, "nand1-0", mod0_default_parents
,
416 static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_1_clk
, "nand1-1", mod0_default_parents
,
424 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk
, "mmc0", mod0_default_parents
,
432 static SUNXI_CCU_PHASE(mmc0_sample_clk
, "mmc0-sample", "mmc0",
434 static SUNXI_CCU_PHASE(mmc0_output_clk
, "mmc0-output", "mmc0",
437 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk
, "mmc1", mod0_default_parents
,
445 static SUNXI_CCU_PHASE(mmc1_sample_clk
, "mmc1-sample", "mmc1",
447 static SUNXI_CCU_PHASE(mmc1_output_clk
, "mmc1-output", "mmc1",
450 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk
, "mmc2", mod0_default_parents
,
458 static SUNXI_CCU_PHASE(mmc2_sample_clk
, "mmc2-sample", "mmc2",
460 static SUNXI_CCU_PHASE(mmc2_output_clk
, "mmc2-output", "mmc2",
463 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk
, "mmc3", mod0_default_parents
,
471 static SUNXI_CCU_PHASE(mmc3_sample_clk
, "mmc3-sample", "mmc3",
473 static SUNXI_CCU_PHASE(mmc3_output_clk
, "mmc3-output", "mmc3",
476 static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk
, "ts", mod0_default_parents
,
484 static const char * const ss_parents
[] = { "osc24M", "pll-periph",
486 static const u8 ss_table
[] = { 0, 1, 13 };
487 static struct ccu_mp ss_clk
= {
489 .m
= _SUNXI_CCU_DIV(0, 4),
490 .p
= _SUNXI_CCU_DIV(16, 2),
491 .mux
= _SUNXI_CCU_MUX_TABLE(24, 4, ss_table
),
494 .hw
.init
= CLK_HW_INIT_PARENTS("ss",
501 static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk
, "spi0", mod0_default_parents
,
509 static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk
, "spi1", mod0_default_parents
,
517 static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk
, "spi2", mod0_default_parents
,
525 static SUNXI_CCU_MP_WITH_MUX_GATE(spi3_clk
, "spi3", mod0_default_parents
,
533 static SUNXI_CCU_M_WITH_GATE(i2s0_clk
, "i2s0", "pll-audio",
534 0x440, 0, 4, BIT(31), CLK_SET_RATE_PARENT
);
535 static SUNXI_CCU_M_WITH_GATE(i2s1_clk
, "i2s1", "pll-audio",
536 0x444, 0, 4, BIT(31), CLK_SET_RATE_PARENT
);
537 static SUNXI_CCU_M_WITH_GATE(spdif_clk
, "spdif", "pll-audio",
538 0x44c, 0, 4, BIT(31), CLK_SET_RATE_PARENT
);
540 static const char * const sdram_parents
[] = { "pll-periph0", "pll-ddr" };
541 static const u8 sdram_table
[] = { 0, 3 };
543 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(sdram_clk
, "sdram",
544 sdram_parents
, sdram_table
,
551 static SUNXI_CCU_M_WITH_GATE(de_clk
, "de", "pll-de", 0x490,
552 0, 4, BIT(31), CLK_SET_RATE_PARENT
);
554 static SUNXI_CCU_GATE(edp_clk
, "edp", "osc24M", 0x494, BIT(31), 0);
556 static const char * const mp_parents
[] = { "pll-video1", "pll-gpu", "pll-de" };
557 static const u8 mp_table
[] = { 9, 10, 11 };
558 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mp_clk
, "mp", mp_parents
, mp_table
,
565 static const char * const display_parents
[] = { "pll-video0", "pll-video1" };
566 static const u8 display_table
[] = { 8, 9 };
568 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(lcd0_clk
, "lcd0",
569 display_parents
, display_table
,
574 CLK_SET_RATE_NO_REPARENT
|
575 CLK_SET_RATE_PARENT
);
577 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(lcd1_clk
, "lcd1",
578 display_parents
, display_table
,
583 CLK_SET_RATE_NO_REPARENT
|
584 CLK_SET_RATE_PARENT
);
586 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mipi_dsi0_clk
, "mipi-dsi0",
587 display_parents
, display_table
,
592 CLK_SET_RATE_PARENT
);
594 static const char * const mipi_dsi1_parents
[] = { "osc24M", "pll-video1" };
595 static const u8 mipi_dsi1_table
[] = { 0, 9 };
596 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mipi_dsi1_clk
, "mipi-dsi1",
597 mipi_dsi1_parents
, mipi_dsi1_table
,
602 CLK_SET_RATE_PARENT
);
604 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(hdmi_clk
, "hdmi",
605 display_parents
, display_table
,
610 CLK_SET_RATE_NO_REPARENT
|
611 CLK_SET_RATE_PARENT
);
613 static SUNXI_CCU_GATE(hdmi_slow_clk
, "hdmi-slow", "osc24M", 0x4b4, BIT(31), 0);
615 static SUNXI_CCU_M_WITH_GATE(mipi_csi_clk
, "mipi-csi", "osc24M", 0x4bc,
618 static SUNXI_CCU_M_WITH_GATE(csi_isp_clk
, "csi-isp", "pll-isp", 0x4c0,
619 0, 4, BIT(31), CLK_SET_RATE_PARENT
);
621 static SUNXI_CCU_GATE(csi_misc_clk
, "csi-misc", "osc24M", 0x4c0, BIT(16), 0);
623 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi0_mclk_clk
, "csi0-mclk",
624 mipi_dsi1_parents
, mipi_dsi1_table
,
629 CLK_SET_RATE_PARENT
);
631 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi1_mclk_clk
, "csi1-mclk",
632 mipi_dsi1_parents
, mipi_dsi1_table
,
637 CLK_SET_RATE_PARENT
);
639 static const char * const fd_parents
[] = { "pll-periph0", "pll-isp" };
640 static const u8 fd_table
[] = { 1, 12 };
641 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(fd_clk
, "fd", fd_parents
, fd_table
,
647 static SUNXI_CCU_M_WITH_GATE(ve_clk
, "ve", "pll-ve", 0x4d0,
648 16, 3, BIT(31), CLK_SET_RATE_PARENT
);
650 static SUNXI_CCU_GATE(avs_clk
, "avs", "osc24M", 0x4d4, BIT(31), 0);
652 static SUNXI_CCU_M_WITH_GATE(gpu_core_clk
, "gpu-core", "pll-gpu", 0x4f0,
653 0, 3, BIT(31), CLK_SET_RATE_PARENT
);
654 static SUNXI_CCU_M_WITH_GATE(gpu_memory_clk
, "gpu-memory", "pll-gpu", 0x4f4,
655 0, 3, BIT(31), CLK_SET_RATE_PARENT
);
657 static const char * const gpu_axi_parents
[] = { "pll-periph0", "pll-gpu" };
658 static const u8 gpu_axi_table
[] = { 1, 10 };
659 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(gpu_axi_clk
, "gpu-axi",
660 gpu_axi_parents
, gpu_axi_table
,
665 CLK_SET_RATE_PARENT
);
667 static SUNXI_CCU_M_WITH_GATE(sata_clk
, "sata", "pll-periph0", 0x500,
670 static SUNXI_CCU_M_WITH_GATE(ac97_clk
, "ac97", "pll-audio",
671 0x504, 0, 4, BIT(31), CLK_SET_RATE_PARENT
);
673 static SUNXI_CCU_M_WITH_MUX_GATE(mipi_hsi_clk
, "mipi-hsi",
674 mod0_default_parents
, 0x508,
680 static const char * const gpadc_parents
[] = { "osc24M", "pll-audio", "osc32k" };
681 static const u8 gpadc_table
[] = { 0, 4, 7 };
682 static struct ccu_mp gpadc_clk
= {
684 .m
= _SUNXI_CCU_DIV(0, 4),
685 .p
= _SUNXI_CCU_DIV(16, 2),
686 .mux
= _SUNXI_CCU_MUX_TABLE(24, 4, gpadc_table
),
689 .hw
.init
= CLK_HW_INIT_PARENTS("gpadc",
696 static const char * const cir_tx_parents
[] = { "osc24M", "osc32k" };
697 static const u8 cir_tx_table
[] = { 0, 7 };
698 static struct ccu_mp cir_tx_clk
= {
700 .m
= _SUNXI_CCU_DIV(0, 4),
701 .p
= _SUNXI_CCU_DIV(16, 2),
702 .mux
= _SUNXI_CCU_MUX_TABLE(24, 4, cir_tx_table
),
705 .hw
.init
= CLK_HW_INIT_PARENTS("cir-tx",
713 static SUNXI_CCU_GATE(bus_fd_clk
, "bus-fd", "ahb0",
715 static SUNXI_CCU_GATE(bus_ve_clk
, "bus-ve", "ahb0",
717 static SUNXI_CCU_GATE(bus_gpu_ctrl_clk
, "bus-gpu-ctrl", "ahb0",
719 static SUNXI_CCU_GATE(bus_ss_clk
, "bus-ss", "ahb0",
721 static SUNXI_CCU_GATE(bus_mmc_clk
, "bus-mmc", "ahb0",
723 static SUNXI_CCU_GATE(bus_nand0_clk
, "bus-nand0", "ahb0",
725 static SUNXI_CCU_GATE(bus_nand1_clk
, "bus-nand1", "ahb0",
727 static SUNXI_CCU_GATE(bus_sdram_clk
, "bus-sdram", "ahb0",
729 static SUNXI_CCU_GATE(bus_mipi_hsi_clk
, "bus-mipi-hsi", "ahb0",
731 static SUNXI_CCU_GATE(bus_sata_clk
, "bus-sata", "ahb0",
733 static SUNXI_CCU_GATE(bus_ts_clk
, "bus-ts", "ahb0",
735 static SUNXI_CCU_GATE(bus_spi0_clk
, "bus-spi0", "ahb0",
737 static SUNXI_CCU_GATE(bus_spi1_clk
, "bus-spi1", "ahb0",
739 static SUNXI_CCU_GATE(bus_spi2_clk
, "bus-spi2", "ahb0",
741 static SUNXI_CCU_GATE(bus_spi3_clk
, "bus-spi3", "ahb0",
745 static SUNXI_CCU_GATE(bus_otg_clk
, "bus-otg", "ahb1",
747 static SUNXI_CCU_GATE(bus_usb_clk
, "bus-usb", "ahb1",
749 static SUNXI_CCU_GATE(bus_gmac_clk
, "bus-gmac", "ahb1",
751 static SUNXI_CCU_GATE(bus_msgbox_clk
, "bus-msgbox", "ahb1",
753 static SUNXI_CCU_GATE(bus_spinlock_clk
, "bus-spinlock", "ahb1",
755 static SUNXI_CCU_GATE(bus_hstimer_clk
, "bus-hstimer", "ahb1",
757 static SUNXI_CCU_GATE(bus_dma_clk
, "bus-dma", "ahb1",
761 static SUNXI_CCU_GATE(bus_lcd0_clk
, "bus-lcd0", "ahb2",
763 static SUNXI_CCU_GATE(bus_lcd1_clk
, "bus-lcd1", "ahb2",
765 static SUNXI_CCU_GATE(bus_edp_clk
, "bus-edp", "ahb2",
767 static SUNXI_CCU_GATE(bus_csi_clk
, "bus-csi", "ahb2",
769 static SUNXI_CCU_GATE(bus_hdmi_clk
, "bus-hdmi", "ahb2",
771 static SUNXI_CCU_GATE(bus_de_clk
, "bus-de", "ahb2",
773 static SUNXI_CCU_GATE(bus_mp_clk
, "bus-mp", "ahb2",
775 static SUNXI_CCU_GATE(bus_mipi_dsi_clk
, "bus-mipi-dsi", "ahb2",
779 static SUNXI_CCU_GATE(bus_spdif_clk
, "bus-spdif", "apb0",
781 static SUNXI_CCU_GATE(bus_pio_clk
, "bus-pio", "apb0",
783 static SUNXI_CCU_GATE(bus_ac97_clk
, "bus-ac97", "apb0",
785 static SUNXI_CCU_GATE(bus_i2s0_clk
, "bus-i2s0", "apb0",
787 static SUNXI_CCU_GATE(bus_i2s1_clk
, "bus-i2s1", "apb0",
789 static SUNXI_CCU_GATE(bus_lradc_clk
, "bus-lradc", "apb0",
791 static SUNXI_CCU_GATE(bus_gpadc_clk
, "bus-gpadc", "apb0",
793 static SUNXI_CCU_GATE(bus_twd_clk
, "bus-twd", "apb0",
795 static SUNXI_CCU_GATE(bus_cir_tx_clk
, "bus-cir-tx", "apb0",
799 static SUNXI_CCU_GATE(bus_i2c0_clk
, "bus-i2c0", "apb1",
801 static SUNXI_CCU_GATE(bus_i2c1_clk
, "bus-i2c1", "apb1",
803 static SUNXI_CCU_GATE(bus_i2c2_clk
, "bus-i2c2", "apb1",
805 static SUNXI_CCU_GATE(bus_i2c3_clk
, "bus-i2c3", "apb1",
807 static SUNXI_CCU_GATE(bus_i2c4_clk
, "bus-i2c4", "apb1",
809 static SUNXI_CCU_GATE(bus_uart0_clk
, "bus-uart0", "apb1",
811 static SUNXI_CCU_GATE(bus_uart1_clk
, "bus-uart1", "apb1",
813 static SUNXI_CCU_GATE(bus_uart2_clk
, "bus-uart2", "apb1",
815 static SUNXI_CCU_GATE(bus_uart3_clk
, "bus-uart3", "apb1",
817 static SUNXI_CCU_GATE(bus_uart4_clk
, "bus-uart4", "apb1",
819 static SUNXI_CCU_GATE(bus_uart5_clk
, "bus-uart5", "apb1",
822 static struct ccu_common
*sun9i_a80_ccu_clks
[] = {
823 &pll_c0cpux_clk
.common
,
824 &pll_c1cpux_clk
.common
,
825 &pll_audio_clk
.common
,
826 &pll_periph0_clk
.common
,
829 &pll_video0_clk
.common
,
830 &pll_video1_clk
.common
,
834 &pll_periph1_clk
.common
,
860 &mmc0_sample_clk
.common
,
861 &mmc0_output_clk
.common
,
863 &mmc1_sample_clk
.common
,
864 &mmc1_output_clk
.common
,
866 &mmc2_sample_clk
.common
,
867 &mmc2_output_clk
.common
,
869 &mmc3_sample_clk
.common
,
870 &mmc3_output_clk
.common
,
886 &mipi_dsi0_clk
.common
,
887 &mipi_dsi1_clk
.common
,
889 &hdmi_slow_clk
.common
,
890 &mipi_csi_clk
.common
,
892 &csi_misc_clk
.common
,
893 &csi0_mclk_clk
.common
,
894 &csi1_mclk_clk
.common
,
898 &gpu_core_clk
.common
,
899 &gpu_memory_clk
.common
,
903 &mipi_hsi_clk
.common
,
910 &bus_gpu_ctrl_clk
.common
,
913 &bus_nand0_clk
.common
,
914 &bus_nand1_clk
.common
,
915 &bus_sdram_clk
.common
,
916 &bus_mipi_hsi_clk
.common
,
917 &bus_sata_clk
.common
,
919 &bus_spi0_clk
.common
,
920 &bus_spi1_clk
.common
,
921 &bus_spi2_clk
.common
,
922 &bus_spi3_clk
.common
,
927 &bus_gmac_clk
.common
,
928 &bus_msgbox_clk
.common
,
929 &bus_spinlock_clk
.common
,
930 &bus_hstimer_clk
.common
,
934 &bus_lcd0_clk
.common
,
935 &bus_lcd1_clk
.common
,
938 &bus_hdmi_clk
.common
,
941 &bus_mipi_dsi_clk
.common
,
944 &bus_spdif_clk
.common
,
946 &bus_ac97_clk
.common
,
947 &bus_i2s0_clk
.common
,
948 &bus_i2s1_clk
.common
,
949 &bus_lradc_clk
.common
,
950 &bus_gpadc_clk
.common
,
952 &bus_cir_tx_clk
.common
,
955 &bus_i2c0_clk
.common
,
956 &bus_i2c1_clk
.common
,
957 &bus_i2c2_clk
.common
,
958 &bus_i2c3_clk
.common
,
959 &bus_i2c4_clk
.common
,
960 &bus_uart0_clk
.common
,
961 &bus_uart1_clk
.common
,
962 &bus_uart2_clk
.common
,
963 &bus_uart3_clk
.common
,
964 &bus_uart4_clk
.common
,
965 &bus_uart5_clk
.common
,
968 static struct clk_hw_onecell_data sun9i_a80_hw_clks
= {
970 [CLK_PLL_C0CPUX
] = &pll_c0cpux_clk
.common
.hw
,
971 [CLK_PLL_C1CPUX
] = &pll_c1cpux_clk
.common
.hw
,
972 [CLK_PLL_AUDIO
] = &pll_audio_clk
.common
.hw
,
973 [CLK_PLL_PERIPH0
] = &pll_periph0_clk
.common
.hw
,
974 [CLK_PLL_VE
] = &pll_ve_clk
.common
.hw
,
975 [CLK_PLL_DDR
] = &pll_ddr_clk
.common
.hw
,
976 [CLK_PLL_VIDEO0
] = &pll_video0_clk
.common
.hw
,
977 [CLK_PLL_VIDEO1
] = &pll_video1_clk
.common
.hw
,
978 [CLK_PLL_GPU
] = &pll_gpu_clk
.common
.hw
,
979 [CLK_PLL_DE
] = &pll_de_clk
.common
.hw
,
980 [CLK_PLL_ISP
] = &pll_isp_clk
.common
.hw
,
981 [CLK_PLL_PERIPH1
] = &pll_periph1_clk
.common
.hw
,
982 [CLK_C0CPUX
] = &c0cpux_clk
.common
.hw
,
983 [CLK_C1CPUX
] = &c1cpux_clk
.common
.hw
,
984 [CLK_ATB0
] = &atb0_clk
.common
.hw
,
985 [CLK_AXI0
] = &axi0_clk
.common
.hw
,
986 [CLK_ATB1
] = &atb1_clk
.common
.hw
,
987 [CLK_AXI1
] = &axi1_clk
.common
.hw
,
988 [CLK_GTBUS
] = >bus_clk
.common
.hw
,
989 [CLK_AHB0
] = &ahb0_clk
.common
.hw
,
990 [CLK_AHB1
] = &ahb1_clk
.common
.hw
,
991 [CLK_AHB2
] = &ahb2_clk
.common
.hw
,
992 [CLK_APB0
] = &apb0_clk
.common
.hw
,
993 [CLK_APB1
] = &apb1_clk
.common
.hw
,
994 [CLK_CCI400
] = &cci400_clk
.common
.hw
,
995 [CLK_ATS
] = &ats_clk
.common
.hw
,
996 [CLK_TRACE
] = &trace_clk
.common
.hw
,
998 [CLK_OUT_A
] = &out_a_clk
.common
.hw
,
999 [CLK_OUT_B
] = &out_b_clk
.common
.hw
,
1001 [CLK_NAND0_0
] = &nand0_0_clk
.common
.hw
,
1002 [CLK_NAND0_1
] = &nand0_1_clk
.common
.hw
,
1003 [CLK_NAND1_0
] = &nand1_0_clk
.common
.hw
,
1004 [CLK_NAND1_1
] = &nand1_1_clk
.common
.hw
,
1005 [CLK_MMC0
] = &mmc0_clk
.common
.hw
,
1006 [CLK_MMC0_SAMPLE
] = &mmc0_sample_clk
.common
.hw
,
1007 [CLK_MMC0_OUTPUT
] = &mmc0_output_clk
.common
.hw
,
1008 [CLK_MMC1
] = &mmc1_clk
.common
.hw
,
1009 [CLK_MMC1_SAMPLE
] = &mmc1_sample_clk
.common
.hw
,
1010 [CLK_MMC1_OUTPUT
] = &mmc1_output_clk
.common
.hw
,
1011 [CLK_MMC2
] = &mmc2_clk
.common
.hw
,
1012 [CLK_MMC2_SAMPLE
] = &mmc2_sample_clk
.common
.hw
,
1013 [CLK_MMC2_OUTPUT
] = &mmc2_output_clk
.common
.hw
,
1014 [CLK_MMC3
] = &mmc3_clk
.common
.hw
,
1015 [CLK_MMC3_SAMPLE
] = &mmc3_sample_clk
.common
.hw
,
1016 [CLK_MMC3_OUTPUT
] = &mmc3_output_clk
.common
.hw
,
1017 [CLK_TS
] = &ts_clk
.common
.hw
,
1018 [CLK_SS
] = &ss_clk
.common
.hw
,
1019 [CLK_SPI0
] = &spi0_clk
.common
.hw
,
1020 [CLK_SPI1
] = &spi1_clk
.common
.hw
,
1021 [CLK_SPI2
] = &spi2_clk
.common
.hw
,
1022 [CLK_SPI3
] = &spi3_clk
.common
.hw
,
1023 [CLK_I2S0
] = &i2s0_clk
.common
.hw
,
1024 [CLK_I2S1
] = &i2s1_clk
.common
.hw
,
1025 [CLK_SPDIF
] = &spdif_clk
.common
.hw
,
1026 [CLK_SDRAM
] = &sdram_clk
.common
.hw
,
1027 [CLK_DE
] = &de_clk
.common
.hw
,
1028 [CLK_EDP
] = &edp_clk
.common
.hw
,
1029 [CLK_MP
] = &mp_clk
.common
.hw
,
1030 [CLK_LCD0
] = &lcd0_clk
.common
.hw
,
1031 [CLK_LCD1
] = &lcd1_clk
.common
.hw
,
1032 [CLK_MIPI_DSI0
] = &mipi_dsi0_clk
.common
.hw
,
1033 [CLK_MIPI_DSI1
] = &mipi_dsi1_clk
.common
.hw
,
1034 [CLK_HDMI
] = &hdmi_clk
.common
.hw
,
1035 [CLK_HDMI_SLOW
] = &hdmi_slow_clk
.common
.hw
,
1036 [CLK_MIPI_CSI
] = &mipi_csi_clk
.common
.hw
,
1037 [CLK_CSI_ISP
] = &csi_isp_clk
.common
.hw
,
1038 [CLK_CSI_MISC
] = &csi_misc_clk
.common
.hw
,
1039 [CLK_CSI0_MCLK
] = &csi0_mclk_clk
.common
.hw
,
1040 [CLK_CSI1_MCLK
] = &csi1_mclk_clk
.common
.hw
,
1041 [CLK_FD
] = &fd_clk
.common
.hw
,
1042 [CLK_VE
] = &ve_clk
.common
.hw
,
1043 [CLK_AVS
] = &avs_clk
.common
.hw
,
1044 [CLK_GPU_CORE
] = &gpu_core_clk
.common
.hw
,
1045 [CLK_GPU_MEMORY
] = &gpu_memory_clk
.common
.hw
,
1046 [CLK_GPU_AXI
] = &gpu_axi_clk
.common
.hw
,
1047 [CLK_SATA
] = &sata_clk
.common
.hw
,
1048 [CLK_AC97
] = &ac97_clk
.common
.hw
,
1049 [CLK_MIPI_HSI
] = &mipi_hsi_clk
.common
.hw
,
1050 [CLK_GPADC
] = &gpadc_clk
.common
.hw
,
1051 [CLK_CIR_TX
] = &cir_tx_clk
.common
.hw
,
1053 [CLK_BUS_FD
] = &bus_fd_clk
.common
.hw
,
1054 [CLK_BUS_VE
] = &bus_ve_clk
.common
.hw
,
1055 [CLK_BUS_GPU_CTRL
] = &bus_gpu_ctrl_clk
.common
.hw
,
1056 [CLK_BUS_SS
] = &bus_ss_clk
.common
.hw
,
1057 [CLK_BUS_MMC
] = &bus_mmc_clk
.common
.hw
,
1058 [CLK_BUS_NAND0
] = &bus_nand0_clk
.common
.hw
,
1059 [CLK_BUS_NAND1
] = &bus_nand1_clk
.common
.hw
,
1060 [CLK_BUS_SDRAM
] = &bus_sdram_clk
.common
.hw
,
1061 [CLK_BUS_MIPI_HSI
] = &bus_mipi_hsi_clk
.common
.hw
,
1062 [CLK_BUS_SATA
] = &bus_sata_clk
.common
.hw
,
1063 [CLK_BUS_TS
] = &bus_ts_clk
.common
.hw
,
1064 [CLK_BUS_SPI0
] = &bus_spi0_clk
.common
.hw
,
1065 [CLK_BUS_SPI1
] = &bus_spi1_clk
.common
.hw
,
1066 [CLK_BUS_SPI2
] = &bus_spi2_clk
.common
.hw
,
1067 [CLK_BUS_SPI3
] = &bus_spi3_clk
.common
.hw
,
1069 [CLK_BUS_OTG
] = &bus_otg_clk
.common
.hw
,
1070 [CLK_BUS_USB
] = &bus_usb_clk
.common
.hw
,
1071 [CLK_BUS_GMAC
] = &bus_gmac_clk
.common
.hw
,
1072 [CLK_BUS_MSGBOX
] = &bus_msgbox_clk
.common
.hw
,
1073 [CLK_BUS_SPINLOCK
] = &bus_spinlock_clk
.common
.hw
,
1074 [CLK_BUS_HSTIMER
] = &bus_hstimer_clk
.common
.hw
,
1075 [CLK_BUS_DMA
] = &bus_dma_clk
.common
.hw
,
1077 [CLK_BUS_LCD0
] = &bus_lcd0_clk
.common
.hw
,
1078 [CLK_BUS_LCD1
] = &bus_lcd1_clk
.common
.hw
,
1079 [CLK_BUS_EDP
] = &bus_edp_clk
.common
.hw
,
1080 [CLK_BUS_CSI
] = &bus_csi_clk
.common
.hw
,
1081 [CLK_BUS_HDMI
] = &bus_hdmi_clk
.common
.hw
,
1082 [CLK_BUS_DE
] = &bus_de_clk
.common
.hw
,
1083 [CLK_BUS_MP
] = &bus_mp_clk
.common
.hw
,
1084 [CLK_BUS_MIPI_DSI
] = &bus_mipi_dsi_clk
.common
.hw
,
1086 [CLK_BUS_SPDIF
] = &bus_spdif_clk
.common
.hw
,
1087 [CLK_BUS_PIO
] = &bus_pio_clk
.common
.hw
,
1088 [CLK_BUS_AC97
] = &bus_ac97_clk
.common
.hw
,
1089 [CLK_BUS_I2S0
] = &bus_i2s0_clk
.common
.hw
,
1090 [CLK_BUS_I2S1
] = &bus_i2s1_clk
.common
.hw
,
1091 [CLK_BUS_LRADC
] = &bus_lradc_clk
.common
.hw
,
1092 [CLK_BUS_GPADC
] = &bus_gpadc_clk
.common
.hw
,
1093 [CLK_BUS_TWD
] = &bus_twd_clk
.common
.hw
,
1094 [CLK_BUS_CIR_TX
] = &bus_cir_tx_clk
.common
.hw
,
1096 [CLK_BUS_I2C0
] = &bus_i2c0_clk
.common
.hw
,
1097 [CLK_BUS_I2C1
] = &bus_i2c1_clk
.common
.hw
,
1098 [CLK_BUS_I2C2
] = &bus_i2c2_clk
.common
.hw
,
1099 [CLK_BUS_I2C3
] = &bus_i2c3_clk
.common
.hw
,
1100 [CLK_BUS_I2C4
] = &bus_i2c4_clk
.common
.hw
,
1101 [CLK_BUS_UART0
] = &bus_uart0_clk
.common
.hw
,
1102 [CLK_BUS_UART1
] = &bus_uart1_clk
.common
.hw
,
1103 [CLK_BUS_UART2
] = &bus_uart2_clk
.common
.hw
,
1104 [CLK_BUS_UART3
] = &bus_uart3_clk
.common
.hw
,
1105 [CLK_BUS_UART4
] = &bus_uart4_clk
.common
.hw
,
1106 [CLK_BUS_UART5
] = &bus_uart5_clk
.common
.hw
,
1111 static struct ccu_reset_map sun9i_a80_ccu_resets
[] = {
1112 /* AHB0 reset controls */
1113 [RST_BUS_FD
] = { 0x5a0, BIT(0) },
1114 [RST_BUS_VE
] = { 0x5a0, BIT(1) },
1115 [RST_BUS_GPU_CTRL
] = { 0x5a0, BIT(3) },
1116 [RST_BUS_SS
] = { 0x5a0, BIT(5) },
1117 [RST_BUS_MMC
] = { 0x5a0, BIT(8) },
1118 [RST_BUS_NAND0
] = { 0x5a0, BIT(12) },
1119 [RST_BUS_NAND1
] = { 0x5a0, BIT(13) },
1120 [RST_BUS_SDRAM
] = { 0x5a0, BIT(14) },
1121 [RST_BUS_SATA
] = { 0x5a0, BIT(16) },
1122 [RST_BUS_TS
] = { 0x5a0, BIT(18) },
1123 [RST_BUS_SPI0
] = { 0x5a0, BIT(20) },
1124 [RST_BUS_SPI1
] = { 0x5a0, BIT(21) },
1125 [RST_BUS_SPI2
] = { 0x5a0, BIT(22) },
1126 [RST_BUS_SPI3
] = { 0x5a0, BIT(23) },
1128 /* AHB1 reset controls */
1129 [RST_BUS_OTG
] = { 0x5a4, BIT(0) },
1130 [RST_BUS_OTG_PHY
] = { 0x5a4, BIT(1) },
1131 [RST_BUS_MIPI_HSI
] = { 0x5a4, BIT(9) },
1132 [RST_BUS_GMAC
] = { 0x5a4, BIT(17) },
1133 [RST_BUS_MSGBOX
] = { 0x5a4, BIT(21) },
1134 [RST_BUS_SPINLOCK
] = { 0x5a4, BIT(22) },
1135 [RST_BUS_HSTIMER
] = { 0x5a4, BIT(23) },
1136 [RST_BUS_DMA
] = { 0x5a4, BIT(24) },
1138 /* AHB2 reset controls */
1139 [RST_BUS_LCD0
] = { 0x5a8, BIT(0) },
1140 [RST_BUS_LCD1
] = { 0x5a8, BIT(1) },
1141 [RST_BUS_EDP
] = { 0x5a8, BIT(2) },
1142 [RST_BUS_LVDS
] = { 0x5a8, BIT(3) },
1143 [RST_BUS_CSI
] = { 0x5a8, BIT(4) },
1144 [RST_BUS_HDMI0
] = { 0x5a8, BIT(5) },
1145 [RST_BUS_HDMI1
] = { 0x5a8, BIT(6) },
1146 [RST_BUS_DE
] = { 0x5a8, BIT(7) },
1147 [RST_BUS_MP
] = { 0x5a8, BIT(8) },
1148 [RST_BUS_GPU
] = { 0x5a8, BIT(9) },
1149 [RST_BUS_MIPI_DSI
] = { 0x5a8, BIT(11) },
1151 /* APB0 reset controls */
1152 [RST_BUS_SPDIF
] = { 0x5b0, BIT(1) },
1153 [RST_BUS_AC97
] = { 0x5b0, BIT(11) },
1154 [RST_BUS_I2S0
] = { 0x5b0, BIT(12) },
1155 [RST_BUS_I2S1
] = { 0x5b0, BIT(13) },
1156 [RST_BUS_LRADC
] = { 0x5b0, BIT(15) },
1157 [RST_BUS_GPADC
] = { 0x5b0, BIT(17) },
1158 [RST_BUS_CIR_TX
] = { 0x5b0, BIT(19) },
1160 /* APB1 reset controls */
1161 [RST_BUS_I2C0
] = { 0x5b4, BIT(0) },
1162 [RST_BUS_I2C1
] = { 0x5b4, BIT(1) },
1163 [RST_BUS_I2C2
] = { 0x5b4, BIT(2) },
1164 [RST_BUS_I2C3
] = { 0x5b4, BIT(3) },
1165 [RST_BUS_I2C4
] = { 0x5b4, BIT(4) },
1166 [RST_BUS_UART0
] = { 0x5b4, BIT(16) },
1167 [RST_BUS_UART1
] = { 0x5b4, BIT(17) },
1168 [RST_BUS_UART2
] = { 0x5b4, BIT(18) },
1169 [RST_BUS_UART3
] = { 0x5b4, BIT(19) },
1170 [RST_BUS_UART4
] = { 0x5b4, BIT(20) },
1171 [RST_BUS_UART5
] = { 0x5b4, BIT(21) },
1174 static const struct sunxi_ccu_desc sun9i_a80_ccu_desc
= {
1175 .ccu_clks
= sun9i_a80_ccu_clks
,
1176 .num_ccu_clks
= ARRAY_SIZE(sun9i_a80_ccu_clks
),
1178 .hw_clks
= &sun9i_a80_hw_clks
,
1180 .resets
= sun9i_a80_ccu_resets
,
1181 .num_resets
= ARRAY_SIZE(sun9i_a80_ccu_resets
),
1184 #define SUN9I_A80_PLL_P_SHIFT 16
1185 #define SUN9I_A80_PLL_N_SHIFT 8
1186 #define SUN9I_A80_PLL_N_WIDTH 8
1188 static void sun9i_a80_cpu_pll_fixup(void __iomem
*reg
)
1190 u32 val
= readl(reg
);
1192 /* bail out if P divider is not used */
1193 if (!(val
& BIT(SUN9I_A80_PLL_P_SHIFT
)))
1197 * If P is used, output should be less than 288 MHz. When we
1198 * set P to 1, we should also decrease the multiplier so the
1199 * output doesn't go out of range, but not too much such that
1200 * the multiplier stays above 12, the minimal operation value.
1202 * To keep it simple, set the multiplier to 17, the reset value.
1204 val
&= ~GENMASK(SUN9I_A80_PLL_N_SHIFT
+ SUN9I_A80_PLL_N_WIDTH
- 1,
1205 SUN9I_A80_PLL_N_SHIFT
);
1206 val
|= 17 << SUN9I_A80_PLL_N_SHIFT
;
1209 val
&= ~BIT(SUN9I_A80_PLL_P_SHIFT
);
1214 static int sun9i_a80_ccu_probe(struct platform_device
*pdev
)
1216 struct resource
*res
;
1220 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1221 reg
= devm_ioremap_resource(&pdev
->dev
, res
);
1223 return PTR_ERR(reg
);
1225 /* Enforce d1 = 0, d2 = 0 for Audio PLL */
1226 val
= readl(reg
+ SUN9I_A80_PLL_AUDIO_REG
);
1227 val
&= (BIT(16) & BIT(18));
1228 writel(val
, reg
+ SUN9I_A80_PLL_AUDIO_REG
);
1230 /* Enforce P = 1 for both CPU cluster PLLs */
1231 sun9i_a80_cpu_pll_fixup(reg
+ SUN9I_A80_PLL_C0CPUX_REG
);
1232 sun9i_a80_cpu_pll_fixup(reg
+ SUN9I_A80_PLL_C1CPUX_REG
);
1234 return sunxi_ccu_probe(pdev
->dev
.of_node
, reg
, &sun9i_a80_ccu_desc
);
1237 static const struct of_device_id sun9i_a80_ccu_ids
[] = {
1238 { .compatible
= "allwinner,sun9i-a80-ccu" },
1242 static struct platform_driver sun9i_a80_ccu_driver
= {
1243 .probe
= sun9i_a80_ccu_probe
,
1245 .name
= "sun9i-a80-ccu",
1246 .of_match_table
= sun9i_a80_ccu_ids
,
1249 builtin_platform_driver(sun9i_a80_ccu_driver
);