1 // SPDX-License-Identifier: GPL-2.0+
3 * Amlogic Meson-AXG Clock Controller Driver
5 * Copyright (c) 2016 Baylibre SAS.
6 * Author: Michael Turquette <mturquette@baylibre.com>
8 * Copyright (c) 2018 Amlogic, inc.
9 * Author: Qiufang Dai <qiufang.dai@amlogic.com>
11 #include <linux/clk-provider.h>
12 #include <linux/platform_device.h>
13 #include <linux/reset-controller.h>
14 #include <linux/mfd/syscon.h>
15 #include "clk-regmap.h"
16 #include "meson-aoclk.h"
17 #include "axg-aoclk.h"
19 #define AXG_AO_GATE(_name, _bit) \
20 static struct clk_regmap axg_aoclk_##_name = { \
21 .data = &(struct clk_regmap_gate_data) { \
22 .offset = (AO_RTI_GEN_CNTL_REG0), \
25 .hw.init = &(struct clk_init_data) { \
26 .name = "axg_ao_" #_name, \
27 .ops = &clk_regmap_gate_ops, \
28 .parent_names = (const char *[]){ "clk81" }, \
30 .flags = CLK_IGNORE_UNUSED, \
34 AXG_AO_GATE(remote
, 0);
35 AXG_AO_GATE(i2c_master
, 1);
36 AXG_AO_GATE(i2c_slave
, 2);
37 AXG_AO_GATE(uart1
, 3);
38 AXG_AO_GATE(uart2
, 5);
39 AXG_AO_GATE(ir_blaster
, 6);
40 AXG_AO_GATE(saradc
, 7);
42 static struct clk_regmap axg_aoclk_clk81
= {
43 .data
= &(struct clk_regmap_mux_data
) {
44 .offset
= AO_RTI_PWR_CNTL_REG0
,
48 .hw
.init
= &(struct clk_init_data
){
49 .name
= "axg_ao_clk81",
50 .ops
= &clk_regmap_mux_ro_ops
,
51 .parent_names
= (const char *[]){ "clk81", "ao_alt_xtal"},
56 static struct clk_regmap axg_aoclk_saradc_mux
= {
57 .data
= &(struct clk_regmap_mux_data
) {
62 .hw
.init
= &(struct clk_init_data
){
63 .name
= "axg_ao_saradc_mux",
64 .ops
= &clk_regmap_mux_ops
,
65 .parent_names
= (const char *[]){ "xtal", "axg_ao_clk81" },
70 static struct clk_regmap axg_aoclk_saradc_div
= {
71 .data
= &(struct clk_regmap_div_data
) {
76 .hw
.init
= &(struct clk_init_data
){
77 .name
= "axg_ao_saradc_div",
78 .ops
= &clk_regmap_divider_ops
,
79 .parent_names
= (const char *[]){ "axg_ao_saradc_mux" },
81 .flags
= CLK_SET_RATE_PARENT
,
85 static struct clk_regmap axg_aoclk_saradc_gate
= {
86 .data
= &(struct clk_regmap_gate_data
) {
90 .hw
.init
= &(struct clk_init_data
){
91 .name
= "axg_ao_saradc_gate",
92 .ops
= &clk_regmap_gate_ops
,
93 .parent_names
= (const char *[]){ "axg_ao_saradc_div" },
95 .flags
= CLK_SET_RATE_PARENT
,
99 static const unsigned int axg_aoclk_reset
[] = {
100 [RESET_AO_REMOTE
] = 16,
101 [RESET_AO_I2C_MASTER
] = 18,
102 [RESET_AO_I2C_SLAVE
] = 19,
103 [RESET_AO_UART1
] = 17,
104 [RESET_AO_UART2
] = 22,
105 [RESET_AO_IR_BLASTER
] = 23,
108 static struct clk_regmap
*axg_aoclk_regmap
[] = {
109 [CLKID_AO_REMOTE
] = &axg_aoclk_remote
,
110 [CLKID_AO_I2C_MASTER
] = &axg_aoclk_i2c_master
,
111 [CLKID_AO_I2C_SLAVE
] = &axg_aoclk_i2c_slave
,
112 [CLKID_AO_UART1
] = &axg_aoclk_uart1
,
113 [CLKID_AO_UART2
] = &axg_aoclk_uart2
,
114 [CLKID_AO_IR_BLASTER
] = &axg_aoclk_ir_blaster
,
115 [CLKID_AO_SAR_ADC
] = &axg_aoclk_saradc
,
116 [CLKID_AO_CLK81
] = &axg_aoclk_clk81
,
117 [CLKID_AO_SAR_ADC_SEL
] = &axg_aoclk_saradc_mux
,
118 [CLKID_AO_SAR_ADC_DIV
] = &axg_aoclk_saradc_div
,
119 [CLKID_AO_SAR_ADC_CLK
] = &axg_aoclk_saradc_gate
,
122 static const struct clk_hw_onecell_data axg_aoclk_onecell_data
= {
124 [CLKID_AO_REMOTE
] = &axg_aoclk_remote
.hw
,
125 [CLKID_AO_I2C_MASTER
] = &axg_aoclk_i2c_master
.hw
,
126 [CLKID_AO_I2C_SLAVE
] = &axg_aoclk_i2c_slave
.hw
,
127 [CLKID_AO_UART1
] = &axg_aoclk_uart1
.hw
,
128 [CLKID_AO_UART2
] = &axg_aoclk_uart2
.hw
,
129 [CLKID_AO_IR_BLASTER
] = &axg_aoclk_ir_blaster
.hw
,
130 [CLKID_AO_SAR_ADC
] = &axg_aoclk_saradc
.hw
,
131 [CLKID_AO_CLK81
] = &axg_aoclk_clk81
.hw
,
132 [CLKID_AO_SAR_ADC_SEL
] = &axg_aoclk_saradc_mux
.hw
,
133 [CLKID_AO_SAR_ADC_DIV
] = &axg_aoclk_saradc_div
.hw
,
134 [CLKID_AO_SAR_ADC_CLK
] = &axg_aoclk_saradc_gate
.hw
,
139 static const struct meson_aoclk_data axg_aoclkc_data
= {
140 .reset_reg
= AO_RTI_GEN_CNTL_REG0
,
141 .num_reset
= ARRAY_SIZE(axg_aoclk_reset
),
142 .reset
= axg_aoclk_reset
,
143 .num_clks
= ARRAY_SIZE(axg_aoclk_regmap
),
144 .clks
= axg_aoclk_regmap
,
145 .hw_data
= &axg_aoclk_onecell_data
,
148 static const struct of_device_id axg_aoclkc_match_table
[] = {
150 .compatible
= "amlogic,meson-axg-aoclkc",
151 .data
= &axg_aoclkc_data
,
156 static struct platform_driver axg_aoclkc_driver
= {
157 .probe
= meson_aoclkc_probe
,
159 .name
= "axg-aoclkc",
160 .of_match_table
= axg_aoclkc_match_table
,
164 builtin_platform_driver(axg_aoclkc_driver
);