hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/clk/meson/axg-aoclk.c
....@@ -12,9 +12,25 @@
1212 #include <linux/platform_device.h>
1313 #include <linux/reset-controller.h>
1414 #include <linux/mfd/syscon.h>
15
-#include "clk-regmap.h"
15
+#include <linux/module.h>
1616 #include "meson-aoclk.h"
1717 #include "axg-aoclk.h"
18
+
19
+#include "clk-regmap.h"
20
+#include "clk-dualdiv.h"
21
+
22
+/*
23
+ * AO Configuration Clock registers offsets
24
+ * Register offsets from the data sheet must be multiplied by 4.
25
+ */
26
+#define AO_RTI_PWR_CNTL_REG1 0x0C
27
+#define AO_RTI_PWR_CNTL_REG0 0x10
28
+#define AO_RTI_GEN_CNTL_REG0 0x40
29
+#define AO_OSCIN_CNTL 0x58
30
+#define AO_CRT_CLK_CNTL1 0x68
31
+#define AO_SAR_CLK 0x90
32
+#define AO_RTC_ALT_CLK_CNTL0 0x94
33
+#define AO_RTC_ALT_CLK_CNTL1 0x98
1834
1935 #define AXG_AO_GATE(_name, _bit) \
2036 static struct clk_regmap axg_aoclk_##_name = { \
....@@ -25,7 +41,9 @@
2541 .hw.init = &(struct clk_init_data) { \
2642 .name = "axg_ao_" #_name, \
2743 .ops = &clk_regmap_gate_ops, \
28
- .parent_names = (const char *[]){ "clk81" }, \
44
+ .parent_data = &(const struct clk_parent_data) { \
45
+ .fw_name = "mpeg-clk", \
46
+ }, \
2947 .num_parents = 1, \
3048 .flags = CLK_IGNORE_UNUSED, \
3149 }, \
....@@ -39,17 +57,155 @@
3957 AXG_AO_GATE(ir_blaster, 6);
4058 AXG_AO_GATE(saradc, 7);
4159
60
+static struct clk_regmap axg_aoclk_cts_oscin = {
61
+ .data = &(struct clk_regmap_gate_data){
62
+ .offset = AO_RTI_PWR_CNTL_REG0,
63
+ .bit_idx = 14,
64
+ },
65
+ .hw.init = &(struct clk_init_data){
66
+ .name = "cts_oscin",
67
+ .ops = &clk_regmap_gate_ro_ops,
68
+ .parent_data = &(const struct clk_parent_data) {
69
+ .fw_name = "xtal",
70
+ },
71
+ .num_parents = 1,
72
+ },
73
+};
74
+
75
+static struct clk_regmap axg_aoclk_32k_pre = {
76
+ .data = &(struct clk_regmap_gate_data){
77
+ .offset = AO_RTC_ALT_CLK_CNTL0,
78
+ .bit_idx = 31,
79
+ },
80
+ .hw.init = &(struct clk_init_data){
81
+ .name = "axg_ao_32k_pre",
82
+ .ops = &clk_regmap_gate_ops,
83
+ .parent_hws = (const struct clk_hw *[]) {
84
+ &axg_aoclk_cts_oscin.hw
85
+ },
86
+ .num_parents = 1,
87
+ },
88
+};
89
+
90
+static const struct meson_clk_dualdiv_param axg_32k_div_table[] = {
91
+ {
92
+ .dual = 1,
93
+ .n1 = 733,
94
+ .m1 = 8,
95
+ .n2 = 732,
96
+ .m2 = 11,
97
+ }, {}
98
+};
99
+
100
+static struct clk_regmap axg_aoclk_32k_div = {
101
+ .data = &(struct meson_clk_dualdiv_data){
102
+ .n1 = {
103
+ .reg_off = AO_RTC_ALT_CLK_CNTL0,
104
+ .shift = 0,
105
+ .width = 12,
106
+ },
107
+ .n2 = {
108
+ .reg_off = AO_RTC_ALT_CLK_CNTL0,
109
+ .shift = 12,
110
+ .width = 12,
111
+ },
112
+ .m1 = {
113
+ .reg_off = AO_RTC_ALT_CLK_CNTL1,
114
+ .shift = 0,
115
+ .width = 12,
116
+ },
117
+ .m2 = {
118
+ .reg_off = AO_RTC_ALT_CLK_CNTL1,
119
+ .shift = 12,
120
+ .width = 12,
121
+ },
122
+ .dual = {
123
+ .reg_off = AO_RTC_ALT_CLK_CNTL0,
124
+ .shift = 28,
125
+ .width = 1,
126
+ },
127
+ .table = axg_32k_div_table,
128
+ },
129
+ .hw.init = &(struct clk_init_data){
130
+ .name = "axg_ao_32k_div",
131
+ .ops = &meson_clk_dualdiv_ops,
132
+ .parent_hws = (const struct clk_hw *[]) {
133
+ &axg_aoclk_32k_pre.hw
134
+ },
135
+ .num_parents = 1,
136
+ },
137
+};
138
+
139
+static struct clk_regmap axg_aoclk_32k_sel = {
140
+ .data = &(struct clk_regmap_mux_data) {
141
+ .offset = AO_RTC_ALT_CLK_CNTL1,
142
+ .mask = 0x1,
143
+ .shift = 24,
144
+ .flags = CLK_MUX_ROUND_CLOSEST,
145
+ },
146
+ .hw.init = &(struct clk_init_data){
147
+ .name = "axg_ao_32k_sel",
148
+ .ops = &clk_regmap_mux_ops,
149
+ .parent_hws = (const struct clk_hw *[]) {
150
+ &axg_aoclk_32k_div.hw,
151
+ &axg_aoclk_32k_pre.hw,
152
+ },
153
+ .num_parents = 2,
154
+ .flags = CLK_SET_RATE_PARENT,
155
+ },
156
+};
157
+
158
+static struct clk_regmap axg_aoclk_32k = {
159
+ .data = &(struct clk_regmap_gate_data){
160
+ .offset = AO_RTC_ALT_CLK_CNTL0,
161
+ .bit_idx = 30,
162
+ },
163
+ .hw.init = &(struct clk_init_data){
164
+ .name = "axg_ao_32k",
165
+ .ops = &clk_regmap_gate_ops,
166
+ .parent_hws = (const struct clk_hw *[]) {
167
+ &axg_aoclk_32k_sel.hw
168
+ },
169
+ .num_parents = 1,
170
+ .flags = CLK_SET_RATE_PARENT,
171
+ },
172
+};
173
+
174
+static struct clk_regmap axg_aoclk_cts_rtc_oscin = {
175
+ .data = &(struct clk_regmap_mux_data) {
176
+ .offset = AO_RTI_PWR_CNTL_REG0,
177
+ .mask = 0x1,
178
+ .shift = 10,
179
+ .flags = CLK_MUX_ROUND_CLOSEST,
180
+ },
181
+ .hw.init = &(struct clk_init_data){
182
+ .name = "axg_ao_cts_rtc_oscin",
183
+ .ops = &clk_regmap_mux_ops,
184
+ .parent_data = (const struct clk_parent_data []) {
185
+ { .hw = &axg_aoclk_32k.hw },
186
+ { .fw_name = "ext_32k-0", },
187
+ },
188
+ .num_parents = 2,
189
+ .flags = CLK_SET_RATE_PARENT,
190
+ },
191
+};
192
+
42193 static struct clk_regmap axg_aoclk_clk81 = {
43194 .data = &(struct clk_regmap_mux_data) {
44195 .offset = AO_RTI_PWR_CNTL_REG0,
45196 .mask = 0x1,
46197 .shift = 8,
198
+ .flags = CLK_MUX_ROUND_CLOSEST,
47199 },
48200 .hw.init = &(struct clk_init_data){
49201 .name = "axg_ao_clk81",
50202 .ops = &clk_regmap_mux_ro_ops,
51
- .parent_names = (const char *[]){ "clk81", "ao_alt_xtal"},
203
+ .parent_data = (const struct clk_parent_data []) {
204
+ { .fw_name = "mpeg-clk", },
205
+ { .hw = &axg_aoclk_cts_rtc_oscin.hw },
206
+ },
52207 .num_parents = 2,
208
+ .flags = CLK_SET_RATE_PARENT,
53209 },
54210 };
55211
....@@ -62,7 +218,10 @@
62218 .hw.init = &(struct clk_init_data){
63219 .name = "axg_ao_saradc_mux",
64220 .ops = &clk_regmap_mux_ops,
65
- .parent_names = (const char *[]){ "xtal", "axg_ao_clk81" },
221
+ .parent_data = (const struct clk_parent_data []) {
222
+ { .fw_name = "xtal", },
223
+ { .hw = &axg_aoclk_clk81.hw },
224
+ },
66225 .num_parents = 2,
67226 },
68227 };
....@@ -76,7 +235,9 @@
76235 .hw.init = &(struct clk_init_data){
77236 .name = "axg_ao_saradc_div",
78237 .ops = &clk_regmap_divider_ops,
79
- .parent_names = (const char *[]){ "axg_ao_saradc_mux" },
238
+ .parent_hws = (const struct clk_hw *[]) {
239
+ &axg_aoclk_saradc_mux.hw
240
+ },
80241 .num_parents = 1,
81242 .flags = CLK_SET_RATE_PARENT,
82243 },
....@@ -90,7 +251,9 @@
90251 .hw.init = &(struct clk_init_data){
91252 .name = "axg_ao_saradc_gate",
92253 .ops = &clk_regmap_gate_ops,
93
- .parent_names = (const char *[]){ "axg_ao_saradc_div" },
254
+ .parent_hws = (const struct clk_hw *[]) {
255
+ &axg_aoclk_saradc_div.hw
256
+ },
94257 .num_parents = 1,
95258 .flags = CLK_SET_RATE_PARENT,
96259 },
....@@ -106,17 +269,23 @@
106269 };
107270
108271 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,
272
+ &axg_aoclk_remote,
273
+ &axg_aoclk_i2c_master,
274
+ &axg_aoclk_i2c_slave,
275
+ &axg_aoclk_uart1,
276
+ &axg_aoclk_uart2,
277
+ &axg_aoclk_ir_blaster,
278
+ &axg_aoclk_saradc,
279
+ &axg_aoclk_cts_oscin,
280
+ &axg_aoclk_32k_pre,
281
+ &axg_aoclk_32k_div,
282
+ &axg_aoclk_32k_sel,
283
+ &axg_aoclk_32k,
284
+ &axg_aoclk_cts_rtc_oscin,
285
+ &axg_aoclk_clk81,
286
+ &axg_aoclk_saradc_mux,
287
+ &axg_aoclk_saradc_div,
288
+ &axg_aoclk_saradc_gate,
120289 };
121290
122291 static const struct clk_hw_onecell_data axg_aoclk_onecell_data = {
....@@ -132,6 +301,12 @@
132301 [CLKID_AO_SAR_ADC_SEL] = &axg_aoclk_saradc_mux.hw,
133302 [CLKID_AO_SAR_ADC_DIV] = &axg_aoclk_saradc_div.hw,
134303 [CLKID_AO_SAR_ADC_CLK] = &axg_aoclk_saradc_gate.hw,
304
+ [CLKID_AO_CTS_OSCIN] = &axg_aoclk_cts_oscin.hw,
305
+ [CLKID_AO_32K_PRE] = &axg_aoclk_32k_pre.hw,
306
+ [CLKID_AO_32K_DIV] = &axg_aoclk_32k_div.hw,
307
+ [CLKID_AO_32K_SEL] = &axg_aoclk_32k_sel.hw,
308
+ [CLKID_AO_32K] = &axg_aoclk_32k.hw,
309
+ [CLKID_AO_CTS_RTC_OSCIN] = &axg_aoclk_cts_rtc_oscin.hw,
135310 },
136311 .num = NR_CLKS,
137312 };
....@@ -152,6 +327,7 @@
152327 },
153328 { }
154329 };
330
+MODULE_DEVICE_TABLE(of, axg_aoclkc_match_table);
155331
156332 static struct platform_driver axg_aoclkc_driver = {
157333 .probe = meson_aoclkc_probe,
....@@ -161,4 +337,5 @@
161337 },
162338 };
163339
164
-builtin_platform_driver(axg_aoclkc_driver);
340
+module_platform_driver(axg_aoclkc_driver);
341
+MODULE_LICENSE("GPL v2");