xref: /openbmc/linux/drivers/clk/meson/axg-aoclk.c (revision ba61bb17)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Amlogic Meson-AXG Clock Controller Driver
4  *
5  * Copyright (c) 2016 Baylibre SAS.
6  * Author: Michael Turquette <mturquette@baylibre.com>
7  *
8  * Copyright (c) 2018 Amlogic, inc.
9  * Author: Qiufang Dai <qiufang.dai@amlogic.com>
10  */
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"
18 
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),			\
23 		.bit_idx = (_bit),					\
24 	},								\
25 	.hw.init = &(struct clk_init_data) {				\
26 		.name =  "axg_ao_" #_name,				\
27 		.ops = &clk_regmap_gate_ops,				\
28 		.parent_names = (const char *[]){ "clk81" },		\
29 		.num_parents = 1,					\
30 		.flags = CLK_IGNORE_UNUSED,				\
31 	},								\
32 }
33 
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);
41 
42 static struct clk_regmap axg_aoclk_clk81 = {
43 	.data = &(struct clk_regmap_mux_data) {
44 		.offset = AO_RTI_PWR_CNTL_REG0,
45 		.mask = 0x1,
46 		.shift = 8,
47 	},
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"},
52 		.num_parents = 2,
53 	},
54 };
55 
56 static struct clk_regmap axg_aoclk_saradc_mux = {
57 	.data = &(struct clk_regmap_mux_data) {
58 		.offset = AO_SAR_CLK,
59 		.mask = 0x3,
60 		.shift = 9,
61 	},
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" },
66 		.num_parents = 2,
67 	},
68 };
69 
70 static struct clk_regmap axg_aoclk_saradc_div = {
71 	.data = &(struct clk_regmap_div_data) {
72 		.offset = AO_SAR_CLK,
73 		.shift = 0,
74 		.width = 8,
75 	},
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" },
80 		.num_parents = 1,
81 		.flags = CLK_SET_RATE_PARENT,
82 	},
83 };
84 
85 static struct clk_regmap axg_aoclk_saradc_gate = {
86 	.data = &(struct clk_regmap_gate_data) {
87 		.offset = AO_SAR_CLK,
88 		.bit_idx = 8,
89 	},
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" },
94 		.num_parents = 1,
95 		.flags = CLK_SET_RATE_PARENT,
96 	},
97 };
98 
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,
106 };
107 
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,
120 };
121 
122 static const struct clk_hw_onecell_data axg_aoclk_onecell_data = {
123 	.hws = {
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,
135 	},
136 	.num = NR_CLKS,
137 };
138 
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,
146 };
147 
148 static const struct of_device_id axg_aoclkc_match_table[] = {
149 	{
150 		.compatible	= "amlogic,meson-axg-aoclkc",
151 		.data		= &axg_aoclkc_data,
152 	},
153 	{ }
154 };
155 
156 static struct platform_driver axg_aoclkc_driver = {
157 	.probe		= meson_aoclkc_probe,
158 	.driver		= {
159 		.name	= "axg-aoclkc",
160 		.of_match_table = axg_aoclkc_match_table,
161 	},
162 };
163 
164 builtin_platform_driver(axg_aoclkc_driver);
165