2 * Copyright (c) 2016 Chen-Yu Tsai. All rights reserved.
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include <linux/clk-provider.h>
15 #include <linux/of_address.h>
16 #include <linux/platform_device.h>
18 #include "ccu_common.h"
19 #include "ccu_reset.h"
26 #include "ccu_phase.h"
28 #include "ccu-sun9i-a80.h"
30 #define CCU_SUN9I_LOCK_REG 0x09c
33 * The CPU PLLs are actually NP clocks, with P being /1 or /4. However
34 * P should only be used for output frequencies lower than 228 MHz.
35 * Neither mainline Linux, U-boot, nor the vendor BSPs use these.
37 * For now we can just model it as a multiplier clock, and force P to /1.
39 #define SUN9I_A80_PLL_C0CPUX_REG 0x000
40 #define SUN9I_A80_PLL_C1CPUX_REG 0x004
42 static struct ccu_mult pll_c0cpux_clk
= {
45 .mult
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
47 .reg
= SUN9I_A80_PLL_C0CPUX_REG
,
48 .lock_reg
= CCU_SUN9I_LOCK_REG
,
49 .features
= CCU_FEATURE_LOCK_REG
,
50 .hw
.init
= CLK_HW_INIT("pll-c0cpux", "osc24M",
56 static struct ccu_mult pll_c1cpux_clk
= {
59 .mult
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
61 .reg
= SUN9I_A80_PLL_C1CPUX_REG
,
62 .lock_reg
= CCU_SUN9I_LOCK_REG
,
63 .features
= CCU_FEATURE_LOCK_REG
,
64 .hw
.init
= CLK_HW_INIT("pll-c1cpux", "osc24M",
71 * The Audio PLL has d1, d2 dividers in addition to the usual N, M
72 * factors. Since we only need 2 frequencies from this PLL: 22.5792 MHz
73 * and 24.576 MHz, ignore them for now. Enforce d1 = 0 and d2 = 0.
75 #define SUN9I_A80_PLL_AUDIO_REG 0x008
77 static struct ccu_nm pll_audio_clk
= {
80 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
81 .m
= _SUNXI_CCU_DIV_OFFSET(0, 6, 0),
84 .lock_reg
= CCU_SUN9I_LOCK_REG
,
85 .features
= CCU_FEATURE_LOCK_REG
,
86 .hw
.init
= CLK_HW_INIT("pll-audio", "osc24M",
87 &ccu_nm_ops
, CLK_SET_RATE_UNGATE
),
91 /* Some PLLs are input * N / div1 / div2. Model them as NKMP with no K */
92 static struct ccu_nkmp pll_periph0_clk
= {
95 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
96 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
97 .p
= _SUNXI_CCU_DIV(18, 1), /* output divider */
100 .lock_reg
= CCU_SUN9I_LOCK_REG
,
101 .features
= CCU_FEATURE_LOCK_REG
,
102 .hw
.init
= CLK_HW_INIT("pll-periph0", "osc24M",
104 CLK_SET_RATE_UNGATE
),
108 static struct ccu_nkmp pll_ve_clk
= {
111 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
112 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
113 .p
= _SUNXI_CCU_DIV(18, 1), /* output divider */
116 .lock_reg
= CCU_SUN9I_LOCK_REG
,
117 .features
= CCU_FEATURE_LOCK_REG
,
118 .hw
.init
= CLK_HW_INIT("pll-ve", "osc24M",
120 CLK_SET_RATE_UNGATE
),
124 static struct ccu_nkmp pll_ddr_clk
= {
127 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
128 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
129 .p
= _SUNXI_CCU_DIV(18, 1), /* output divider */
132 .lock_reg
= CCU_SUN9I_LOCK_REG
,
133 .features
= CCU_FEATURE_LOCK_REG
,
134 .hw
.init
= CLK_HW_INIT("pll-ddr", "osc24M",
136 CLK_SET_RATE_UNGATE
),
140 static struct ccu_nm pll_video0_clk
= {
143 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
144 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
147 .lock_reg
= CCU_SUN9I_LOCK_REG
,
148 .features
= CCU_FEATURE_LOCK_REG
,
149 .hw
.init
= CLK_HW_INIT("pll-video0", "osc24M",
151 CLK_SET_RATE_UNGATE
),
155 static struct ccu_nkmp pll_video1_clk
= {
158 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
159 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
160 .p
= _SUNXI_CCU_DIV(0, 2), /* external divider p */
163 .lock_reg
= CCU_SUN9I_LOCK_REG
,
164 .features
= CCU_FEATURE_LOCK_REG
,
165 .hw
.init
= CLK_HW_INIT("pll-video1", "osc24M",
167 CLK_SET_RATE_UNGATE
),
171 static struct ccu_nkmp pll_gpu_clk
= {
174 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
175 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
176 .p
= _SUNXI_CCU_DIV(18, 1), /* output divider */
179 .lock_reg
= CCU_SUN9I_LOCK_REG
,
180 .features
= CCU_FEATURE_LOCK_REG
,
181 .hw
.init
= CLK_HW_INIT("pll-gpu", "osc24M",
183 CLK_SET_RATE_UNGATE
),
187 static struct ccu_nkmp pll_de_clk
= {
190 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
191 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
192 .p
= _SUNXI_CCU_DIV(18, 1), /* output divider */
195 .lock_reg
= CCU_SUN9I_LOCK_REG
,
196 .features
= CCU_FEATURE_LOCK_REG
,
197 .hw
.init
= CLK_HW_INIT("pll-de", "osc24M",
199 CLK_SET_RATE_UNGATE
),
203 static struct ccu_nkmp pll_isp_clk
= {
206 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
207 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
208 .p
= _SUNXI_CCU_DIV(18, 1), /* output divider */
211 .lock_reg
= CCU_SUN9I_LOCK_REG
,
212 .features
= CCU_FEATURE_LOCK_REG
,
213 .hw
.init
= CLK_HW_INIT("pll-isp", "osc24M",
215 CLK_SET_RATE_UNGATE
),
219 static struct ccu_nkmp pll_periph1_clk
= {
222 .n
= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
223 .m
= _SUNXI_CCU_DIV(16, 1), /* input divider */
224 .p
= _SUNXI_CCU_DIV(18, 1), /* output divider */
227 .lock_reg
= CCU_SUN9I_LOCK_REG
,
228 .features
= CCU_FEATURE_LOCK_REG
,
229 .hw
.init
= CLK_HW_INIT("pll-periph1", "osc24M",
231 CLK_SET_RATE_UNGATE
),
235 static const char * const c0cpux_parents
[] = { "osc24M", "pll-c0cpux" };
236 static SUNXI_CCU_MUX(c0cpux_clk
, "c0cpux", c0cpux_parents
,
237 0x50, 0, 1, CLK_SET_RATE_PARENT
| CLK_IS_CRITICAL
);
239 static const char * const c1cpux_parents
[] = { "osc24M", "pll-c1cpux" };
240 static SUNXI_CCU_MUX(c1cpux_clk
, "c1cpux", c1cpux_parents
,
241 0x50, 8, 1, CLK_SET_RATE_PARENT
| CLK_IS_CRITICAL
);
243 static struct clk_div_table axi_div_table
[] = {
244 { .val
= 0, .div
= 1 },
245 { .val
= 1, .div
= 2 },
246 { .val
= 2, .div
= 3 },
247 { .val
= 3, .div
= 4 },
248 { .val
= 4, .div
= 4 },
249 { .val
= 5, .div
= 4 },
250 { .val
= 6, .div
= 4 },
251 { .val
= 7, .div
= 4 },
255 static SUNXI_CCU_M(atb0_clk
, "atb0", "c0cpux", 0x054, 8, 2, 0);
257 static SUNXI_CCU_DIV_TABLE(axi0_clk
, "axi0", "c0cpux",
258 0x054, 0, 3, axi_div_table
, 0);
260 static SUNXI_CCU_M(atb1_clk
, "atb1", "c1cpux", 0x058, 8, 2, 0);
262 static SUNXI_CCU_DIV_TABLE(axi1_clk
, "axi1", "c1cpux",
263 0x058, 0, 3, axi_div_table
, 0);
265 static const char * const gtbus_parents
[] = { "osc24M", "pll-periph0",
266 "pll-periph1", "pll-periph1" };
267 static SUNXI_CCU_M_WITH_MUX(gtbus_clk
, "gtbus", gtbus_parents
,
268 0x05c, 0, 2, 24, 2, CLK_IS_CRITICAL
);
270 static const char * const ahb_parents
[] = { "gtbus", "pll-periph0",
271 "pll-periph1", "pll-periph1" };
272 static struct ccu_div ahb0_clk
= {
273 .div
= _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO
),
274 .mux
= _SUNXI_CCU_MUX(24, 2),
277 .hw
.init
= CLK_HW_INIT_PARENTS("ahb0",
284 static struct ccu_div ahb1_clk
= {
285 .div
= _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO
),
286 .mux
= _SUNXI_CCU_MUX(24, 2),
289 .hw
.init
= CLK_HW_INIT_PARENTS("ahb1",
296 static struct ccu_div ahb2_clk
= {
297 .div
= _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO
),
298 .mux
= _SUNXI_CCU_MUX(24, 2),
301 .hw
.init
= CLK_HW_INIT_PARENTS("ahb2",
308 static const char * const apb_parents
[] = { "osc24M", "pll-periph0" };
310 static struct ccu_div apb0_clk
= {
311 .div
= _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO
),
312 .mux
= _SUNXI_CCU_MUX(24, 1),
315 .hw
.init
= CLK_HW_INIT_PARENTS("apb0",
322 static struct ccu_div apb1_clk
= {
323 .div
= _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO
),
324 .mux
= _SUNXI_CCU_MUX(24, 1),
327 .hw
.init
= CLK_HW_INIT_PARENTS("apb1",
334 static struct ccu_div cci400_clk
= {
335 .div
= _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO
),
336 .mux
= _SUNXI_CCU_MUX(24, 2),
339 .hw
.init
= CLK_HW_INIT_PARENTS("cci400",
346 static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk
, "ats", apb_parents
,
347 0x080, 0, 3, 24, 2, BIT(31), 0);
349 static SUNXI_CCU_M_WITH_MUX_GATE(trace_clk
, "trace", apb_parents
,
350 0x084, 0, 3, 24, 2, BIT(31), 0);
352 static const char * const out_parents
[] = { "osc24M", "osc32k", "osc24M" };
353 static const struct ccu_mux_fixed_prediv out_prediv
= {
354 .index
= 0, .div
= 750
357 static struct ccu_mp out_a_clk
= {
359 .m
= _SUNXI_CCU_DIV(8, 5),
360 .p
= _SUNXI_CCU_DIV(20, 2),
364 .fixed_predivs
= &out_prediv
,
369 .features
= CCU_FEATURE_FIXED_PREDIV
,
370 .hw
.init
= CLK_HW_INIT_PARENTS("out-a",
377 static struct ccu_mp out_b_clk
= {
379 .m
= _SUNXI_CCU_DIV(8, 5),
380 .p
= _SUNXI_CCU_DIV(20, 2),
384 .fixed_predivs
= &out_prediv
,
389 .features
= CCU_FEATURE_FIXED_PREDIV
,
390 .hw
.init
= CLK_HW_INIT_PARENTS("out-b",
397 static const char * const mod0_default_parents
[] = { "osc24M", "pll-periph0" };
399 static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_0_clk
, "nand0-0", mod0_default_parents
,
407 static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_1_clk
, "nand0-1", mod0_default_parents
,
415 static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_0_clk
, "nand1-0", mod0_default_parents
,
423 static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_1_clk
, "nand1-1", mod0_default_parents
,
431 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk
, "mmc0", mod0_default_parents
,
439 static SUNXI_CCU_PHASE(mmc0_sample_clk
, "mmc0-sample", "mmc0",
441 static SUNXI_CCU_PHASE(mmc0_output_clk
, "mmc0-output", "mmc0",
444 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk
, "mmc1", mod0_default_parents
,
452 static SUNXI_CCU_PHASE(mmc1_sample_clk
, "mmc1-sample", "mmc1",
454 static SUNXI_CCU_PHASE(mmc1_output_clk
, "mmc1-output", "mmc1",
457 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk
, "mmc2", mod0_default_parents
,
465 static SUNXI_CCU_PHASE(mmc2_sample_clk
, "mmc2-sample", "mmc2",
467 static SUNXI_CCU_PHASE(mmc2_output_clk
, "mmc2-output", "mmc2",
470 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk
, "mmc3", mod0_default_parents
,
478 static SUNXI_CCU_PHASE(mmc3_sample_clk
, "mmc3-sample", "mmc3",
480 static SUNXI_CCU_PHASE(mmc3_output_clk
, "mmc3-output", "mmc3",
483 static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk
, "ts", mod0_default_parents
,
491 static const char * const ss_parents
[] = { "osc24M", "pll-periph",
493 static const u8 ss_table
[] = { 0, 1, 13 };
494 static struct ccu_mp ss_clk
= {
496 .m
= _SUNXI_CCU_DIV(0, 4),
497 .p
= _SUNXI_CCU_DIV(16, 2),
498 .mux
= _SUNXI_CCU_MUX_TABLE(24, 4, ss_table
),
501 .hw
.init
= CLK_HW_INIT_PARENTS("ss",
508 static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk
, "spi0", mod0_default_parents
,
516 static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk
, "spi1", mod0_default_parents
,
524 static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk
, "spi2", mod0_default_parents
,
532 static SUNXI_CCU_MP_WITH_MUX_GATE(spi3_clk
, "spi3", mod0_default_parents
,
540 static SUNXI_CCU_M_WITH_GATE(i2s0_clk
, "i2s0", "pll-audio",
541 0x440, 0, 4, BIT(31), CLK_SET_RATE_PARENT
);
542 static SUNXI_CCU_M_WITH_GATE(i2s1_clk
, "i2s1", "pll-audio",
543 0x444, 0, 4, BIT(31), CLK_SET_RATE_PARENT
);
544 static SUNXI_CCU_M_WITH_GATE(spdif_clk
, "spdif", "pll-audio",
545 0x44c, 0, 4, BIT(31), CLK_SET_RATE_PARENT
);
547 static const char * const sdram_parents
[] = { "pll-periph0", "pll-ddr" };
548 static const u8 sdram_table
[] = { 0, 3 };
550 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(sdram_clk
, "sdram",
551 sdram_parents
, sdram_table
,
558 static SUNXI_CCU_M_WITH_GATE(de_clk
, "de", "pll-de", 0x490,
559 0, 4, BIT(31), CLK_SET_RATE_PARENT
);
561 static SUNXI_CCU_GATE(edp_clk
, "edp", "osc24M", 0x494, BIT(31), 0);
563 static const char * const mp_parents
[] = { "pll-video1", "pll-gpu", "pll-de" };
564 static const u8 mp_table
[] = { 9, 10, 11 };
565 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mp_clk
, "mp", mp_parents
, mp_table
,
572 static const char * const display_parents
[] = { "pll-video0", "pll-video1" };
573 static const u8 display_table
[] = { 8, 9 };
575 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(lcd0_clk
, "lcd0",
576 display_parents
, display_table
,
581 CLK_SET_RATE_NO_REPARENT
|
582 CLK_SET_RATE_PARENT
);
584 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(lcd1_clk
, "lcd1",
585 display_parents
, display_table
,
590 CLK_SET_RATE_NO_REPARENT
|
591 CLK_SET_RATE_PARENT
);
593 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mipi_dsi0_clk
, "mipi-dsi0",
594 display_parents
, display_table
,
599 CLK_SET_RATE_PARENT
);
601 static const char * const mipi_dsi1_parents
[] = { "osc24M", "pll-video1" };
602 static const u8 mipi_dsi1_table
[] = { 0, 9 };
603 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mipi_dsi1_clk
, "mipi-dsi1",
604 mipi_dsi1_parents
, mipi_dsi1_table
,
609 CLK_SET_RATE_PARENT
);
611 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(hdmi_clk
, "hdmi",
612 display_parents
, display_table
,
617 CLK_SET_RATE_NO_REPARENT
|
618 CLK_SET_RATE_PARENT
);
620 static SUNXI_CCU_GATE(hdmi_slow_clk
, "hdmi-slow", "osc24M", 0x4b4, BIT(31), 0);
622 static SUNXI_CCU_M_WITH_GATE(mipi_csi_clk
, "mipi-csi", "osc24M", 0x4bc,
625 static SUNXI_CCU_M_WITH_GATE(csi_isp_clk
, "csi-isp", "pll-isp", 0x4c0,
626 0, 4, BIT(31), CLK_SET_RATE_PARENT
);
628 static SUNXI_CCU_GATE(csi_misc_clk
, "csi-misc", "osc24M", 0x4c0, BIT(16), 0);
630 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi0_mclk_clk
, "csi0-mclk",
631 mipi_dsi1_parents
, mipi_dsi1_table
,
636 CLK_SET_RATE_PARENT
);
638 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi1_mclk_clk
, "csi1-mclk",
639 mipi_dsi1_parents
, mipi_dsi1_table
,
644 CLK_SET_RATE_PARENT
);
646 static const char * const fd_parents
[] = { "pll-periph0", "pll-isp" };
647 static const u8 fd_table
[] = { 1, 12 };
648 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(fd_clk
, "fd", fd_parents
, fd_table
,
654 static SUNXI_CCU_M_WITH_GATE(ve_clk
, "ve", "pll-ve", 0x4d0,
655 16, 3, BIT(31), CLK_SET_RATE_PARENT
);
657 static SUNXI_CCU_GATE(avs_clk
, "avs", "osc24M", 0x4d4, BIT(31), 0);
659 static SUNXI_CCU_M_WITH_GATE(gpu_core_clk
, "gpu-core", "pll-gpu", 0x4f0,
660 0, 3, BIT(31), CLK_SET_RATE_PARENT
);
661 static SUNXI_CCU_M_WITH_GATE(gpu_memory_clk
, "gpu-memory", "pll-gpu", 0x4f4,
662 0, 3, BIT(31), CLK_SET_RATE_PARENT
);
664 static const char * const gpu_axi_parents
[] = { "pll-periph0", "pll-gpu" };
665 static const u8 gpu_axi_table
[] = { 1, 10 };
666 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(gpu_axi_clk
, "gpu-axi",
667 gpu_axi_parents
, gpu_axi_table
,
672 CLK_SET_RATE_PARENT
);
674 static SUNXI_CCU_M_WITH_GATE(sata_clk
, "sata", "pll-periph0", 0x500,
677 static SUNXI_CCU_M_WITH_GATE(ac97_clk
, "ac97", "pll-audio",
678 0x504, 0, 4, BIT(31), CLK_SET_RATE_PARENT
);
680 static SUNXI_CCU_M_WITH_MUX_GATE(mipi_hsi_clk
, "mipi-hsi",
681 mod0_default_parents
, 0x508,
687 static const char * const gpadc_parents
[] = { "osc24M", "pll-audio", "osc32k" };
688 static const u8 gpadc_table
[] = { 0, 4, 7 };
689 static struct ccu_mp gpadc_clk
= {
691 .m
= _SUNXI_CCU_DIV(0, 4),
692 .p
= _SUNXI_CCU_DIV(16, 2),
693 .mux
= _SUNXI_CCU_MUX_TABLE(24, 4, gpadc_table
),
696 .hw
.init
= CLK_HW_INIT_PARENTS("gpadc",
703 static const char * const cir_tx_parents
[] = { "osc24M", "osc32k" };
704 static const u8 cir_tx_table
[] = { 0, 7 };
705 static struct ccu_mp cir_tx_clk
= {
707 .m
= _SUNXI_CCU_DIV(0, 4),
708 .p
= _SUNXI_CCU_DIV(16, 2),
709 .mux
= _SUNXI_CCU_MUX_TABLE(24, 4, cir_tx_table
),
712 .hw
.init
= CLK_HW_INIT_PARENTS("cir-tx",
720 static SUNXI_CCU_GATE(bus_fd_clk
, "bus-fd", "ahb0",
722 static SUNXI_CCU_GATE(bus_ve_clk
, "bus-ve", "ahb0",
724 static SUNXI_CCU_GATE(bus_gpu_ctrl_clk
, "bus-gpu-ctrl", "ahb0",
726 static SUNXI_CCU_GATE(bus_ss_clk
, "bus-ss", "ahb0",
728 static SUNXI_CCU_GATE(bus_mmc_clk
, "bus-mmc", "ahb0",
730 static SUNXI_CCU_GATE(bus_nand0_clk
, "bus-nand0", "ahb0",
732 static SUNXI_CCU_GATE(bus_nand1_clk
, "bus-nand1", "ahb0",
734 static SUNXI_CCU_GATE(bus_sdram_clk
, "bus-sdram", "ahb0",
736 static SUNXI_CCU_GATE(bus_mipi_hsi_clk
, "bus-mipi-hsi", "ahb0",
738 static SUNXI_CCU_GATE(bus_sata_clk
, "bus-sata", "ahb0",
740 static SUNXI_CCU_GATE(bus_ts_clk
, "bus-ts", "ahb0",
742 static SUNXI_CCU_GATE(bus_spi0_clk
, "bus-spi0", "ahb0",
744 static SUNXI_CCU_GATE(bus_spi1_clk
, "bus-spi1", "ahb0",
746 static SUNXI_CCU_GATE(bus_spi2_clk
, "bus-spi2", "ahb0",
748 static SUNXI_CCU_GATE(bus_spi3_clk
, "bus-spi3", "ahb0",
752 static SUNXI_CCU_GATE(bus_otg_clk
, "bus-otg", "ahb1",
754 static SUNXI_CCU_GATE(bus_usb_clk
, "bus-usb", "ahb1",
756 static SUNXI_CCU_GATE(bus_gmac_clk
, "bus-gmac", "ahb1",
758 static SUNXI_CCU_GATE(bus_msgbox_clk
, "bus-msgbox", "ahb1",
760 static SUNXI_CCU_GATE(bus_spinlock_clk
, "bus-spinlock", "ahb1",
762 static SUNXI_CCU_GATE(bus_hstimer_clk
, "bus-hstimer", "ahb1",
764 static SUNXI_CCU_GATE(bus_dma_clk
, "bus-dma", "ahb1",
768 static SUNXI_CCU_GATE(bus_lcd0_clk
, "bus-lcd0", "ahb2",
770 static SUNXI_CCU_GATE(bus_lcd1_clk
, "bus-lcd1", "ahb2",
772 static SUNXI_CCU_GATE(bus_edp_clk
, "bus-edp", "ahb2",
774 static SUNXI_CCU_GATE(bus_csi_clk
, "bus-csi", "ahb2",
776 static SUNXI_CCU_GATE(bus_hdmi_clk
, "bus-hdmi", "ahb2",
778 static SUNXI_CCU_GATE(bus_de_clk
, "bus-de", "ahb2",
780 static SUNXI_CCU_GATE(bus_mp_clk
, "bus-mp", "ahb2",
782 static SUNXI_CCU_GATE(bus_mipi_dsi_clk
, "bus-mipi-dsi", "ahb2",
786 static SUNXI_CCU_GATE(bus_spdif_clk
, "bus-spdif", "apb0",
788 static SUNXI_CCU_GATE(bus_pio_clk
, "bus-pio", "apb0",
790 static SUNXI_CCU_GATE(bus_ac97_clk
, "bus-ac97", "apb0",
792 static SUNXI_CCU_GATE(bus_i2s0_clk
, "bus-i2s0", "apb0",
794 static SUNXI_CCU_GATE(bus_i2s1_clk
, "bus-i2s1", "apb0",
796 static SUNXI_CCU_GATE(bus_lradc_clk
, "bus-lradc", "apb0",
798 static SUNXI_CCU_GATE(bus_gpadc_clk
, "bus-gpadc", "apb0",
800 static SUNXI_CCU_GATE(bus_twd_clk
, "bus-twd", "apb0",
802 static SUNXI_CCU_GATE(bus_cir_tx_clk
, "bus-cir-tx", "apb0",
806 static SUNXI_CCU_GATE(bus_i2c0_clk
, "bus-i2c0", "apb1",
808 static SUNXI_CCU_GATE(bus_i2c1_clk
, "bus-i2c1", "apb1",
810 static SUNXI_CCU_GATE(bus_i2c2_clk
, "bus-i2c2", "apb1",
812 static SUNXI_CCU_GATE(bus_i2c3_clk
, "bus-i2c3", "apb1",
814 static SUNXI_CCU_GATE(bus_i2c4_clk
, "bus-i2c4", "apb1",
816 static SUNXI_CCU_GATE(bus_uart0_clk
, "bus-uart0", "apb1",
818 static SUNXI_CCU_GATE(bus_uart1_clk
, "bus-uart1", "apb1",
820 static SUNXI_CCU_GATE(bus_uart2_clk
, "bus-uart2", "apb1",
822 static SUNXI_CCU_GATE(bus_uart3_clk
, "bus-uart3", "apb1",
824 static SUNXI_CCU_GATE(bus_uart4_clk
, "bus-uart4", "apb1",
826 static SUNXI_CCU_GATE(bus_uart5_clk
, "bus-uart5", "apb1",
829 static struct ccu_common
*sun9i_a80_ccu_clks
[] = {
830 &pll_c0cpux_clk
.common
,
831 &pll_c1cpux_clk
.common
,
832 &pll_audio_clk
.common
,
833 &pll_periph0_clk
.common
,
836 &pll_video0_clk
.common
,
837 &pll_video1_clk
.common
,
841 &pll_periph1_clk
.common
,
867 &mmc0_sample_clk
.common
,
868 &mmc0_output_clk
.common
,
870 &mmc1_sample_clk
.common
,
871 &mmc1_output_clk
.common
,
873 &mmc2_sample_clk
.common
,
874 &mmc2_output_clk
.common
,
876 &mmc3_sample_clk
.common
,
877 &mmc3_output_clk
.common
,
893 &mipi_dsi0_clk
.common
,
894 &mipi_dsi1_clk
.common
,
896 &hdmi_slow_clk
.common
,
897 &mipi_csi_clk
.common
,
899 &csi_misc_clk
.common
,
900 &csi0_mclk_clk
.common
,
901 &csi1_mclk_clk
.common
,
905 &gpu_core_clk
.common
,
906 &gpu_memory_clk
.common
,
910 &mipi_hsi_clk
.common
,
917 &bus_gpu_ctrl_clk
.common
,
920 &bus_nand0_clk
.common
,
921 &bus_nand1_clk
.common
,
922 &bus_sdram_clk
.common
,
923 &bus_mipi_hsi_clk
.common
,
924 &bus_sata_clk
.common
,
926 &bus_spi0_clk
.common
,
927 &bus_spi1_clk
.common
,
928 &bus_spi2_clk
.common
,
929 &bus_spi3_clk
.common
,
934 &bus_gmac_clk
.common
,
935 &bus_msgbox_clk
.common
,
936 &bus_spinlock_clk
.common
,
937 &bus_hstimer_clk
.common
,
941 &bus_lcd0_clk
.common
,
942 &bus_lcd1_clk
.common
,
945 &bus_hdmi_clk
.common
,
948 &bus_mipi_dsi_clk
.common
,
951 &bus_spdif_clk
.common
,
953 &bus_ac97_clk
.common
,
954 &bus_i2s0_clk
.common
,
955 &bus_i2s1_clk
.common
,
956 &bus_lradc_clk
.common
,
957 &bus_gpadc_clk
.common
,
959 &bus_cir_tx_clk
.common
,
962 &bus_i2c0_clk
.common
,
963 &bus_i2c1_clk
.common
,
964 &bus_i2c2_clk
.common
,
965 &bus_i2c3_clk
.common
,
966 &bus_i2c4_clk
.common
,
967 &bus_uart0_clk
.common
,
968 &bus_uart1_clk
.common
,
969 &bus_uart2_clk
.common
,
970 &bus_uart3_clk
.common
,
971 &bus_uart4_clk
.common
,
972 &bus_uart5_clk
.common
,
975 static struct clk_hw_onecell_data sun9i_a80_hw_clks
= {
977 [CLK_PLL_C0CPUX
] = &pll_c0cpux_clk
.common
.hw
,
978 [CLK_PLL_C1CPUX
] = &pll_c1cpux_clk
.common
.hw
,
979 [CLK_PLL_AUDIO
] = &pll_audio_clk
.common
.hw
,
980 [CLK_PLL_PERIPH0
] = &pll_periph0_clk
.common
.hw
,
981 [CLK_PLL_VE
] = &pll_ve_clk
.common
.hw
,
982 [CLK_PLL_DDR
] = &pll_ddr_clk
.common
.hw
,
983 [CLK_PLL_VIDEO0
] = &pll_video0_clk
.common
.hw
,
984 [CLK_PLL_VIDEO1
] = &pll_video1_clk
.common
.hw
,
985 [CLK_PLL_GPU
] = &pll_gpu_clk
.common
.hw
,
986 [CLK_PLL_DE
] = &pll_de_clk
.common
.hw
,
987 [CLK_PLL_ISP
] = &pll_isp_clk
.common
.hw
,
988 [CLK_PLL_PERIPH1
] = &pll_periph1_clk
.common
.hw
,
989 [CLK_C0CPUX
] = &c0cpux_clk
.common
.hw
,
990 [CLK_C1CPUX
] = &c1cpux_clk
.common
.hw
,
991 [CLK_ATB0
] = &atb0_clk
.common
.hw
,
992 [CLK_AXI0
] = &axi0_clk
.common
.hw
,
993 [CLK_ATB1
] = &atb1_clk
.common
.hw
,
994 [CLK_AXI1
] = &axi1_clk
.common
.hw
,
995 [CLK_GTBUS
] = >bus_clk
.common
.hw
,
996 [CLK_AHB0
] = &ahb0_clk
.common
.hw
,
997 [CLK_AHB1
] = &ahb1_clk
.common
.hw
,
998 [CLK_AHB2
] = &ahb2_clk
.common
.hw
,
999 [CLK_APB0
] = &apb0_clk
.common
.hw
,
1000 [CLK_APB1
] = &apb1_clk
.common
.hw
,
1001 [CLK_CCI400
] = &cci400_clk
.common
.hw
,
1002 [CLK_ATS
] = &ats_clk
.common
.hw
,
1003 [CLK_TRACE
] = &trace_clk
.common
.hw
,
1005 [CLK_OUT_A
] = &out_a_clk
.common
.hw
,
1006 [CLK_OUT_B
] = &out_b_clk
.common
.hw
,
1008 [CLK_NAND0_0
] = &nand0_0_clk
.common
.hw
,
1009 [CLK_NAND0_1
] = &nand0_1_clk
.common
.hw
,
1010 [CLK_NAND1_0
] = &nand1_0_clk
.common
.hw
,
1011 [CLK_NAND1_1
] = &nand1_1_clk
.common
.hw
,
1012 [CLK_MMC0
] = &mmc0_clk
.common
.hw
,
1013 [CLK_MMC0_SAMPLE
] = &mmc0_sample_clk
.common
.hw
,
1014 [CLK_MMC0_OUTPUT
] = &mmc0_output_clk
.common
.hw
,
1015 [CLK_MMC1
] = &mmc1_clk
.common
.hw
,
1016 [CLK_MMC1_SAMPLE
] = &mmc1_sample_clk
.common
.hw
,
1017 [CLK_MMC1_OUTPUT
] = &mmc1_output_clk
.common
.hw
,
1018 [CLK_MMC2
] = &mmc2_clk
.common
.hw
,
1019 [CLK_MMC2_SAMPLE
] = &mmc2_sample_clk
.common
.hw
,
1020 [CLK_MMC2_OUTPUT
] = &mmc2_output_clk
.common
.hw
,
1021 [CLK_MMC3
] = &mmc3_clk
.common
.hw
,
1022 [CLK_MMC3_SAMPLE
] = &mmc3_sample_clk
.common
.hw
,
1023 [CLK_MMC3_OUTPUT
] = &mmc3_output_clk
.common
.hw
,
1024 [CLK_TS
] = &ts_clk
.common
.hw
,
1025 [CLK_SS
] = &ss_clk
.common
.hw
,
1026 [CLK_SPI0
] = &spi0_clk
.common
.hw
,
1027 [CLK_SPI1
] = &spi1_clk
.common
.hw
,
1028 [CLK_SPI2
] = &spi2_clk
.common
.hw
,
1029 [CLK_SPI3
] = &spi3_clk
.common
.hw
,
1030 [CLK_I2S0
] = &i2s0_clk
.common
.hw
,
1031 [CLK_I2S1
] = &i2s1_clk
.common
.hw
,
1032 [CLK_SPDIF
] = &spdif_clk
.common
.hw
,
1033 [CLK_SDRAM
] = &sdram_clk
.common
.hw
,
1034 [CLK_DE
] = &de_clk
.common
.hw
,
1035 [CLK_EDP
] = &edp_clk
.common
.hw
,
1036 [CLK_MP
] = &mp_clk
.common
.hw
,
1037 [CLK_LCD0
] = &lcd0_clk
.common
.hw
,
1038 [CLK_LCD1
] = &lcd1_clk
.common
.hw
,
1039 [CLK_MIPI_DSI0
] = &mipi_dsi0_clk
.common
.hw
,
1040 [CLK_MIPI_DSI1
] = &mipi_dsi1_clk
.common
.hw
,
1041 [CLK_HDMI
] = &hdmi_clk
.common
.hw
,
1042 [CLK_HDMI_SLOW
] = &hdmi_slow_clk
.common
.hw
,
1043 [CLK_MIPI_CSI
] = &mipi_csi_clk
.common
.hw
,
1044 [CLK_CSI_ISP
] = &csi_isp_clk
.common
.hw
,
1045 [CLK_CSI_MISC
] = &csi_misc_clk
.common
.hw
,
1046 [CLK_CSI0_MCLK
] = &csi0_mclk_clk
.common
.hw
,
1047 [CLK_CSI1_MCLK
] = &csi1_mclk_clk
.common
.hw
,
1048 [CLK_FD
] = &fd_clk
.common
.hw
,
1049 [CLK_VE
] = &ve_clk
.common
.hw
,
1050 [CLK_AVS
] = &avs_clk
.common
.hw
,
1051 [CLK_GPU_CORE
] = &gpu_core_clk
.common
.hw
,
1052 [CLK_GPU_MEMORY
] = &gpu_memory_clk
.common
.hw
,
1053 [CLK_GPU_AXI
] = &gpu_axi_clk
.common
.hw
,
1054 [CLK_SATA
] = &sata_clk
.common
.hw
,
1055 [CLK_AC97
] = &ac97_clk
.common
.hw
,
1056 [CLK_MIPI_HSI
] = &mipi_hsi_clk
.common
.hw
,
1057 [CLK_GPADC
] = &gpadc_clk
.common
.hw
,
1058 [CLK_CIR_TX
] = &cir_tx_clk
.common
.hw
,
1060 [CLK_BUS_FD
] = &bus_fd_clk
.common
.hw
,
1061 [CLK_BUS_VE
] = &bus_ve_clk
.common
.hw
,
1062 [CLK_BUS_GPU_CTRL
] = &bus_gpu_ctrl_clk
.common
.hw
,
1063 [CLK_BUS_SS
] = &bus_ss_clk
.common
.hw
,
1064 [CLK_BUS_MMC
] = &bus_mmc_clk
.common
.hw
,
1065 [CLK_BUS_NAND0
] = &bus_nand0_clk
.common
.hw
,
1066 [CLK_BUS_NAND1
] = &bus_nand1_clk
.common
.hw
,
1067 [CLK_BUS_SDRAM
] = &bus_sdram_clk
.common
.hw
,
1068 [CLK_BUS_MIPI_HSI
] = &bus_mipi_hsi_clk
.common
.hw
,
1069 [CLK_BUS_SATA
] = &bus_sata_clk
.common
.hw
,
1070 [CLK_BUS_TS
] = &bus_ts_clk
.common
.hw
,
1071 [CLK_BUS_SPI0
] = &bus_spi0_clk
.common
.hw
,
1072 [CLK_BUS_SPI1
] = &bus_spi1_clk
.common
.hw
,
1073 [CLK_BUS_SPI2
] = &bus_spi2_clk
.common
.hw
,
1074 [CLK_BUS_SPI3
] = &bus_spi3_clk
.common
.hw
,
1076 [CLK_BUS_OTG
] = &bus_otg_clk
.common
.hw
,
1077 [CLK_BUS_USB
] = &bus_usb_clk
.common
.hw
,
1078 [CLK_BUS_GMAC
] = &bus_gmac_clk
.common
.hw
,
1079 [CLK_BUS_MSGBOX
] = &bus_msgbox_clk
.common
.hw
,
1080 [CLK_BUS_SPINLOCK
] = &bus_spinlock_clk
.common
.hw
,
1081 [CLK_BUS_HSTIMER
] = &bus_hstimer_clk
.common
.hw
,
1082 [CLK_BUS_DMA
] = &bus_dma_clk
.common
.hw
,
1084 [CLK_BUS_LCD0
] = &bus_lcd0_clk
.common
.hw
,
1085 [CLK_BUS_LCD1
] = &bus_lcd1_clk
.common
.hw
,
1086 [CLK_BUS_EDP
] = &bus_edp_clk
.common
.hw
,
1087 [CLK_BUS_CSI
] = &bus_csi_clk
.common
.hw
,
1088 [CLK_BUS_HDMI
] = &bus_hdmi_clk
.common
.hw
,
1089 [CLK_BUS_DE
] = &bus_de_clk
.common
.hw
,
1090 [CLK_BUS_MP
] = &bus_mp_clk
.common
.hw
,
1091 [CLK_BUS_MIPI_DSI
] = &bus_mipi_dsi_clk
.common
.hw
,
1093 [CLK_BUS_SPDIF
] = &bus_spdif_clk
.common
.hw
,
1094 [CLK_BUS_PIO
] = &bus_pio_clk
.common
.hw
,
1095 [CLK_BUS_AC97
] = &bus_ac97_clk
.common
.hw
,
1096 [CLK_BUS_I2S0
] = &bus_i2s0_clk
.common
.hw
,
1097 [CLK_BUS_I2S1
] = &bus_i2s1_clk
.common
.hw
,
1098 [CLK_BUS_LRADC
] = &bus_lradc_clk
.common
.hw
,
1099 [CLK_BUS_GPADC
] = &bus_gpadc_clk
.common
.hw
,
1100 [CLK_BUS_TWD
] = &bus_twd_clk
.common
.hw
,
1101 [CLK_BUS_CIR_TX
] = &bus_cir_tx_clk
.common
.hw
,
1103 [CLK_BUS_I2C0
] = &bus_i2c0_clk
.common
.hw
,
1104 [CLK_BUS_I2C1
] = &bus_i2c1_clk
.common
.hw
,
1105 [CLK_BUS_I2C2
] = &bus_i2c2_clk
.common
.hw
,
1106 [CLK_BUS_I2C3
] = &bus_i2c3_clk
.common
.hw
,
1107 [CLK_BUS_I2C4
] = &bus_i2c4_clk
.common
.hw
,
1108 [CLK_BUS_UART0
] = &bus_uart0_clk
.common
.hw
,
1109 [CLK_BUS_UART1
] = &bus_uart1_clk
.common
.hw
,
1110 [CLK_BUS_UART2
] = &bus_uart2_clk
.common
.hw
,
1111 [CLK_BUS_UART3
] = &bus_uart3_clk
.common
.hw
,
1112 [CLK_BUS_UART4
] = &bus_uart4_clk
.common
.hw
,
1113 [CLK_BUS_UART5
] = &bus_uart5_clk
.common
.hw
,
1118 static struct ccu_reset_map sun9i_a80_ccu_resets
[] = {
1119 /* AHB0 reset controls */
1120 [RST_BUS_FD
] = { 0x5a0, BIT(0) },
1121 [RST_BUS_VE
] = { 0x5a0, BIT(1) },
1122 [RST_BUS_GPU_CTRL
] = { 0x5a0, BIT(3) },
1123 [RST_BUS_SS
] = { 0x5a0, BIT(5) },
1124 [RST_BUS_MMC
] = { 0x5a0, BIT(8) },
1125 [RST_BUS_NAND0
] = { 0x5a0, BIT(12) },
1126 [RST_BUS_NAND1
] = { 0x5a0, BIT(13) },
1127 [RST_BUS_SDRAM
] = { 0x5a0, BIT(14) },
1128 [RST_BUS_SATA
] = { 0x5a0, BIT(16) },
1129 [RST_BUS_TS
] = { 0x5a0, BIT(18) },
1130 [RST_BUS_SPI0
] = { 0x5a0, BIT(20) },
1131 [RST_BUS_SPI1
] = { 0x5a0, BIT(21) },
1132 [RST_BUS_SPI2
] = { 0x5a0, BIT(22) },
1133 [RST_BUS_SPI3
] = { 0x5a0, BIT(23) },
1135 /* AHB1 reset controls */
1136 [RST_BUS_OTG
] = { 0x5a4, BIT(0) },
1137 [RST_BUS_OTG_PHY
] = { 0x5a4, BIT(1) },
1138 [RST_BUS_MIPI_HSI
] = { 0x5a4, BIT(9) },
1139 [RST_BUS_GMAC
] = { 0x5a4, BIT(17) },
1140 [RST_BUS_MSGBOX
] = { 0x5a4, BIT(21) },
1141 [RST_BUS_SPINLOCK
] = { 0x5a4, BIT(22) },
1142 [RST_BUS_HSTIMER
] = { 0x5a4, BIT(23) },
1143 [RST_BUS_DMA
] = { 0x5a4, BIT(24) },
1145 /* AHB2 reset controls */
1146 [RST_BUS_LCD0
] = { 0x5a8, BIT(0) },
1147 [RST_BUS_LCD1
] = { 0x5a8, BIT(1) },
1148 [RST_BUS_EDP
] = { 0x5a8, BIT(2) },
1149 [RST_BUS_LVDS
] = { 0x5a8, BIT(3) },
1150 [RST_BUS_CSI
] = { 0x5a8, BIT(4) },
1151 [RST_BUS_HDMI0
] = { 0x5a8, BIT(5) },
1152 [RST_BUS_HDMI1
] = { 0x5a8, BIT(6) },
1153 [RST_BUS_DE
] = { 0x5a8, BIT(7) },
1154 [RST_BUS_MP
] = { 0x5a8, BIT(8) },
1155 [RST_BUS_GPU
] = { 0x5a8, BIT(9) },
1156 [RST_BUS_MIPI_DSI
] = { 0x5a8, BIT(11) },
1158 /* APB0 reset controls */
1159 [RST_BUS_SPDIF
] = { 0x5b0, BIT(1) },
1160 [RST_BUS_AC97
] = { 0x5b0, BIT(11) },
1161 [RST_BUS_I2S0
] = { 0x5b0, BIT(12) },
1162 [RST_BUS_I2S1
] = { 0x5b0, BIT(13) },
1163 [RST_BUS_LRADC
] = { 0x5b0, BIT(15) },
1164 [RST_BUS_GPADC
] = { 0x5b0, BIT(17) },
1165 [RST_BUS_CIR_TX
] = { 0x5b0, BIT(19) },
1167 /* APB1 reset controls */
1168 [RST_BUS_I2C0
] = { 0x5b4, BIT(0) },
1169 [RST_BUS_I2C1
] = { 0x5b4, BIT(1) },
1170 [RST_BUS_I2C2
] = { 0x5b4, BIT(2) },
1171 [RST_BUS_I2C3
] = { 0x5b4, BIT(3) },
1172 [RST_BUS_I2C4
] = { 0x5b4, BIT(4) },
1173 [RST_BUS_UART0
] = { 0x5b4, BIT(16) },
1174 [RST_BUS_UART1
] = { 0x5b4, BIT(17) },
1175 [RST_BUS_UART2
] = { 0x5b4, BIT(18) },
1176 [RST_BUS_UART3
] = { 0x5b4, BIT(19) },
1177 [RST_BUS_UART4
] = { 0x5b4, BIT(20) },
1178 [RST_BUS_UART5
] = { 0x5b4, BIT(21) },
1181 static const struct sunxi_ccu_desc sun9i_a80_ccu_desc
= {
1182 .ccu_clks
= sun9i_a80_ccu_clks
,
1183 .num_ccu_clks
= ARRAY_SIZE(sun9i_a80_ccu_clks
),
1185 .hw_clks
= &sun9i_a80_hw_clks
,
1187 .resets
= sun9i_a80_ccu_resets
,
1188 .num_resets
= ARRAY_SIZE(sun9i_a80_ccu_resets
),
1191 #define SUN9I_A80_PLL_P_SHIFT 16
1192 #define SUN9I_A80_PLL_N_SHIFT 8
1193 #define SUN9I_A80_PLL_N_WIDTH 8
1195 static void sun9i_a80_cpu_pll_fixup(void __iomem
*reg
)
1197 u32 val
= readl(reg
);
1199 /* bail out if P divider is not used */
1200 if (!(val
& BIT(SUN9I_A80_PLL_P_SHIFT
)))
1204 * If P is used, output should be less than 288 MHz. When we
1205 * set P to 1, we should also decrease the multiplier so the
1206 * output doesn't go out of range, but not too much such that
1207 * the multiplier stays above 12, the minimal operation value.
1209 * To keep it simple, set the multiplier to 17, the reset value.
1211 val
&= ~GENMASK(SUN9I_A80_PLL_N_SHIFT
+ SUN9I_A80_PLL_N_WIDTH
- 1,
1212 SUN9I_A80_PLL_N_SHIFT
);
1213 val
|= 17 << SUN9I_A80_PLL_N_SHIFT
;
1216 val
&= ~BIT(SUN9I_A80_PLL_P_SHIFT
);
1221 static int sun9i_a80_ccu_probe(struct platform_device
*pdev
)
1223 struct resource
*res
;
1227 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1228 reg
= devm_ioremap_resource(&pdev
->dev
, res
);
1230 return PTR_ERR(reg
);
1232 /* Enforce d1 = 0, d2 = 0 for Audio PLL */
1233 val
= readl(reg
+ SUN9I_A80_PLL_AUDIO_REG
);
1234 val
&= ~(BIT(16) | BIT(18));
1235 writel(val
, reg
+ SUN9I_A80_PLL_AUDIO_REG
);
1237 /* Enforce P = 1 for both CPU cluster PLLs */
1238 sun9i_a80_cpu_pll_fixup(reg
+ SUN9I_A80_PLL_C0CPUX_REG
);
1239 sun9i_a80_cpu_pll_fixup(reg
+ SUN9I_A80_PLL_C1CPUX_REG
);
1241 return sunxi_ccu_probe(pdev
->dev
.of_node
, reg
, &sun9i_a80_ccu_desc
);
1244 static const struct of_device_id sun9i_a80_ccu_ids
[] = {
1245 { .compatible
= "allwinner,sun9i-a80-ccu" },
1249 static struct platform_driver sun9i_a80_ccu_driver
= {
1250 .probe
= sun9i_a80_ccu_probe
,
1252 .name
= "sun9i-a80-ccu",
1253 .of_match_table
= sun9i_a80_ccu_ids
,
1256 builtin_platform_driver(sun9i_a80_ccu_driver
);