1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com>
6 #include <linux/clk-provider.h>
7 #include <linux/module.h>
8 #include <linux/platform_device.h>
10 #include "ccu_common.h"
11 #include "ccu_reset.h"
18 #include "ccu-sun50i-a100-r.h"
20 static const char * const cpus_r_apb2_parents
[] = { "dcxo24M", "osc32k",
21 "iosc", "pll-periph0" };
22 static const struct ccu_mux_var_prediv cpus_r_apb2_predivs
[] = {
23 { .index
= 3, .shift
= 0, .width
= 5 },
26 static struct ccu_div r_cpus_clk
= {
27 .div
= _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO
),
33 .var_predivs
= cpus_r_apb2_predivs
,
34 .n_var_predivs
= ARRAY_SIZE(cpus_r_apb2_predivs
),
39 .features
= CCU_FEATURE_VARIABLE_PREDIV
,
40 .hw
.init
= CLK_HW_INIT_PARENTS("cpus",
47 static CLK_FIXED_FACTOR_HW(r_ahb_clk
, "r-ahb", &r_cpus_clk
.common
.hw
, 1, 1, 0);
49 static struct ccu_div r_apb1_clk
= {
50 .div
= _SUNXI_CCU_DIV(0, 2),
54 .hw
.init
= CLK_HW_INIT("r-apb1",
61 static struct ccu_div r_apb2_clk
= {
62 .div
= _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO
),
68 .var_predivs
= cpus_r_apb2_predivs
,
69 .n_var_predivs
= ARRAY_SIZE(cpus_r_apb2_predivs
),
74 .features
= CCU_FEATURE_VARIABLE_PREDIV
,
75 .hw
.init
= CLK_HW_INIT_PARENTS("r-apb2",
82 static const struct clk_parent_data clk_parent_r_apb1
[] = {
83 { .hw
= &r_apb1_clk
.common
.hw
},
86 static const struct clk_parent_data clk_parent_r_apb2
[] = {
87 { .hw
= &r_apb2_clk
.common
.hw
},
90 static SUNXI_CCU_GATE_DATA(r_apb1_timer_clk
, "r-apb1-timer", clk_parent_r_apb1
,
93 static SUNXI_CCU_GATE_DATA(r_apb1_twd_clk
, "r-apb1-twd", clk_parent_r_apb1
,
96 static const char * const r_apb1_pwm_clk_parents
[] = { "dcxo24M", "osc32k",
98 static SUNXI_CCU_MUX(r_apb1_pwm_clk
, "r-apb1-pwm", r_apb1_pwm_clk_parents
,
101 static SUNXI_CCU_GATE_DATA(r_apb1_bus_pwm_clk
, "r-apb1-bus-pwm",
102 clk_parent_r_apb1
, 0x13c, BIT(0), 0);
104 static SUNXI_CCU_GATE_DATA(r_apb1_ppu_clk
, "r-apb1-ppu", clk_parent_r_apb1
,
107 static SUNXI_CCU_GATE_DATA(r_apb2_uart_clk
, "r-apb2-uart", clk_parent_r_apb2
,
110 static SUNXI_CCU_GATE_DATA(r_apb2_i2c0_clk
, "r-apb2-i2c0", clk_parent_r_apb2
,
113 static SUNXI_CCU_GATE_DATA(r_apb2_i2c1_clk
, "r-apb2-i2c1", clk_parent_r_apb2
,
116 static const char * const r_apb1_ir_rx_parents
[] = { "osc32k", "dcxo24M" };
117 static SUNXI_CCU_MP_WITH_MUX_GATE(r_apb1_ir_rx_clk
, "r-apb1-ir-rx",
118 r_apb1_ir_rx_parents
, 0x1c0,
125 static SUNXI_CCU_GATE_DATA(r_apb1_bus_ir_rx_clk
, "r-apb1-bus-ir-rx",
126 clk_parent_r_apb1
, 0x1cc, BIT(0), 0);
128 static SUNXI_CCU_GATE(r_ahb_bus_rtc_clk
, "r-ahb-rtc", "r-ahb",
131 static struct ccu_common
*sun50i_a100_r_ccu_clks
[] = {
135 &r_apb1_timer_clk
.common
,
136 &r_apb1_twd_clk
.common
,
137 &r_apb1_pwm_clk
.common
,
138 &r_apb1_bus_pwm_clk
.common
,
139 &r_apb1_ppu_clk
.common
,
140 &r_apb2_uart_clk
.common
,
141 &r_apb2_i2c0_clk
.common
,
142 &r_apb2_i2c1_clk
.common
,
143 &r_apb1_ir_rx_clk
.common
,
144 &r_apb1_bus_ir_rx_clk
.common
,
145 &r_ahb_bus_rtc_clk
.common
,
148 static struct clk_hw_onecell_data sun50i_a100_r_hw_clks
= {
150 [CLK_R_CPUS
] = &r_cpus_clk
.common
.hw
,
151 [CLK_R_AHB
] = &r_ahb_clk
.hw
,
152 [CLK_R_APB1
] = &r_apb1_clk
.common
.hw
,
153 [CLK_R_APB2
] = &r_apb2_clk
.common
.hw
,
154 [CLK_R_APB1_TIMER
] = &r_apb1_timer_clk
.common
.hw
,
155 [CLK_R_APB1_TWD
] = &r_apb1_twd_clk
.common
.hw
,
156 [CLK_R_APB1_PWM
] = &r_apb1_pwm_clk
.common
.hw
,
157 [CLK_R_APB1_BUS_PWM
] = &r_apb1_bus_pwm_clk
.common
.hw
,
158 [CLK_R_APB1_PPU
] = &r_apb1_ppu_clk
.common
.hw
,
159 [CLK_R_APB2_UART
] = &r_apb2_uart_clk
.common
.hw
,
160 [CLK_R_APB2_I2C0
] = &r_apb2_i2c0_clk
.common
.hw
,
161 [CLK_R_APB2_I2C1
] = &r_apb2_i2c1_clk
.common
.hw
,
162 [CLK_R_APB1_IR
] = &r_apb1_ir_rx_clk
.common
.hw
,
163 [CLK_R_APB1_BUS_IR
] = &r_apb1_bus_ir_rx_clk
.common
.hw
,
164 [CLK_R_AHB_BUS_RTC
] = &r_ahb_bus_rtc_clk
.common
.hw
,
169 static const struct ccu_reset_map sun50i_a100_r_ccu_resets
[] = {
170 [RST_R_APB1_TIMER
] = { 0x11c, BIT(16) },
171 [RST_R_APB1_BUS_PWM
] = { 0x13c, BIT(16) },
172 [RST_R_APB1_PPU
] = { 0x17c, BIT(16) },
173 [RST_R_APB2_UART
] = { 0x18c, BIT(16) },
174 [RST_R_APB2_I2C0
] = { 0x19c, BIT(16) },
175 [RST_R_APB2_I2C1
] = { 0x19c, BIT(17) },
176 [RST_R_APB1_BUS_IR
] = { 0x1cc, BIT(16) },
177 [RST_R_AHB_BUS_RTC
] = { 0x20c, BIT(16) },
180 static const struct sunxi_ccu_desc sun50i_a100_r_ccu_desc
= {
181 .ccu_clks
= sun50i_a100_r_ccu_clks
,
182 .num_ccu_clks
= ARRAY_SIZE(sun50i_a100_r_ccu_clks
),
184 .hw_clks
= &sun50i_a100_r_hw_clks
,
186 .resets
= sun50i_a100_r_ccu_resets
,
187 .num_resets
= ARRAY_SIZE(sun50i_a100_r_ccu_resets
),
190 static int sun50i_a100_r_ccu_probe(struct platform_device
*pdev
)
194 reg
= devm_platform_ioremap_resource(pdev
, 0);
198 return devm_sunxi_ccu_probe(&pdev
->dev
, reg
, &sun50i_a100_r_ccu_desc
);
201 static const struct of_device_id sun50i_a100_r_ccu_ids
[] = {
202 { .compatible
= "allwinner,sun50i-a100-r-ccu" },
205 MODULE_DEVICE_TABLE(of
, sun50i_a100_r_ccu_ids
);
207 static struct platform_driver sun50i_a100_r_ccu_driver
= {
208 .probe
= sun50i_a100_r_ccu_probe
,
210 .name
= "sun50i-a100-r-ccu",
211 .suppress_bind_attrs
= true,
212 .of_match_table
= sun50i_a100_r_ccu_ids
,
215 module_platform_driver(sun50i_a100_r_ccu_driver
);
217 MODULE_IMPORT_NS("SUNXI_CCU");
218 MODULE_DESCRIPTION("Support for the Allwinner A100 PRCM CCU");
219 MODULE_LICENSE("GPL");