mediatek: add mt7988 clock drivers support
[openwrt/openwrt.git] / target / linux / mediatek / files-5.15 / drivers / clk / mediatek / clk-mt7988-eth.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2023 MediaTek Inc.
4 * Author: Sam Shih <sam.shih@mediatek.com>
5 * Author: Xiufeng Li <Xiufeng.Li@mediatek.com>
6 */
7
8 #include <linux/clk-provider.h>
9 #include <linux/of.h>
10 #include <linux/of_address.h>
11 #include <linux/of_device.h>
12 #include <linux/platform_device.h>
13 #include "clk-mtk.h"
14 #include "clk-gate.h"
15 #include <dt-bindings/clock/mediatek,mt7988-clk.h>
16
17 static const struct mtk_gate_regs ethdma_cg_regs = {
18 .set_ofs = 0x30,
19 .clr_ofs = 0x30,
20 .sta_ofs = 0x30,
21 };
22
23 #define GATE_ETHDMA(_id, _name, _parent, _shift) \
24 { \
25 .id = _id, .name = _name, .parent_name = _parent, \
26 .regs = &ethdma_cg_regs, .shift = _shift, \
27 .ops = &mtk_clk_gate_ops_no_setclr_inv, \
28 }
29
30 static const struct mtk_gate ethdma_clks[] = {
31 GATE_ETHDMA(CLK_ETHDMA_XGP1_EN, "ethdma_xgp1_en", "top_xtal", 0),
32 GATE_ETHDMA(CLK_ETHDMA_XGP2_EN, "ethdma_xgp2_en", "top_xtal", 1),
33 GATE_ETHDMA(CLK_ETHDMA_XGP3_EN, "ethdma_xgp3_en", "top_xtal", 2),
34 GATE_ETHDMA(CLK_ETHDMA_FE_EN, "ethdma_fe_en", "netsys_2x_sel", 6),
35 GATE_ETHDMA(CLK_ETHDMA_GP2_EN, "ethdma_gp2_en", "top_xtal", 7),
36 GATE_ETHDMA(CLK_ETHDMA_GP1_EN, "ethdma_gp1_en", "top_xtal", 8),
37 GATE_ETHDMA(CLK_ETHDMA_GP3_EN, "ethdma_gp3_en", "top_xtal", 10),
38 GATE_ETHDMA(CLK_ETHDMA_ESW_EN, "ethdma_esw_en", "netsys_gsw_sel", 16),
39 GATE_ETHDMA(CLK_ETHDMA_CRYPT0_EN, "ethdma_crypt0_en", "eip197_sel",
40 29),
41 };
42
43 static int clk_mt7988_ethsys_probe(struct platform_device *pdev)
44 {
45 struct clk_onecell_data *clk_data;
46 struct device_node *node = pdev->dev.of_node;
47 int r;
48 void __iomem *base;
49
50 base = of_iomap(node, 0);
51 if (!base) {
52 pr_err("%s(): ioremap failed\n", __func__);
53 return -ENOMEM;
54 }
55
56 clk_data = mtk_alloc_clk_data(ARRAY_SIZE(ethdma_clks));
57
58 if (!clk_data)
59 return -ENOMEM;
60
61 mtk_clk_register_gates(node, ethdma_clks, ARRAY_SIZE(ethdma_clks),
62 clk_data);
63
64 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
65 if (r) {
66 pr_err("%s(): could not register clock provider: %d\n",
67 __func__, r);
68 goto free_data;
69 }
70 return r;
71
72 free_data:
73 mtk_free_clk_data(clk_data);
74 return r;
75 }
76
77 static const struct mtk_gate_regs sgmii0_cg_regs = {
78 .set_ofs = 0xe4,
79 .clr_ofs = 0xe4,
80 .sta_ofs = 0xe4,
81 };
82
83 #define GATE_SGMII0(_id, _name, _parent, _shift) \
84 { \
85 .id = _id, .name = _name, .parent_name = _parent, \
86 .regs = &sgmii0_cg_regs, .shift = _shift, \
87 .ops = &mtk_clk_gate_ops_no_setclr_inv, \
88 }
89
90 static const struct mtk_gate sgmii0_clks[] = {
91 GATE_SGMII0(CLK_SGM0_TX_EN, "sgm0_tx_en", "top_xtal", 2),
92 GATE_SGMII0(CLK_SGM0_RX_EN, "sgm0_rx_en", "top_xtal", 3),
93 };
94
95 static int clk_mt7988_sgmii0_probe(struct platform_device *pdev)
96 {
97 struct clk_onecell_data *clk_data;
98 struct device_node *node = pdev->dev.of_node;
99 int r;
100 void __iomem *base;
101
102 base = of_iomap(node, 0);
103 if (!base) {
104 pr_err("%s(): ioremap failed\n", __func__);
105 return -ENOMEM;
106 }
107
108 clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii0_clks));
109
110 if (!clk_data)
111 return -ENOMEM;
112
113 mtk_clk_register_gates(node, sgmii0_clks, ARRAY_SIZE(sgmii0_clks),
114 clk_data);
115
116 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
117 if (r) {
118 pr_err("%s(): could not register clock provider: %d\n",
119 __func__, r);
120 goto free_data;
121 }
122 return r;
123
124 free_data:
125 mtk_free_clk_data(clk_data);
126 return r;
127 }
128
129 static const struct mtk_gate_regs sgmii1_cg_regs = {
130 .set_ofs = 0xe4,
131 .clr_ofs = 0xe4,
132 .sta_ofs = 0xe4,
133 };
134
135 #define GATE_SGMII1(_id, _name, _parent, _shift) \
136 { \
137 .id = _id, .name = _name, .parent_name = _parent, \
138 .regs = &sgmii1_cg_regs, .shift = _shift, \
139 .ops = &mtk_clk_gate_ops_no_setclr_inv, \
140 }
141
142 static const struct mtk_gate sgmii1_clks[] = {
143 GATE_SGMII1(CLK_SGM1_TX_EN, "sgm1_tx_en", "top_xtal", 2),
144 GATE_SGMII1(CLK_SGM1_RX_EN, "sgm1_rx_en", "top_xtal", 3),
145 };
146
147 static int clk_mt7988_sgmii1_probe(struct platform_device *pdev)
148 {
149 struct clk_onecell_data *clk_data;
150 struct device_node *node = pdev->dev.of_node;
151 int r;
152 void __iomem *base;
153
154 base = of_iomap(node, 0);
155 if (!base) {
156 pr_err("%s(): ioremap failed\n", __func__);
157 return -ENOMEM;
158 }
159
160 clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii1_clks));
161
162 if (!clk_data)
163 return -ENOMEM;
164
165 mtk_clk_register_gates(node, sgmii1_clks, ARRAY_SIZE(sgmii1_clks),
166 clk_data);
167
168 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
169 if (r) {
170 pr_err("%s(): could not register clock provider: %d\n",
171 __func__, r);
172 goto free_data;
173 }
174 return r;
175
176 free_data:
177 mtk_free_clk_data(clk_data);
178 return r;
179 }
180
181 static const struct mtk_gate_regs ethwarp_cg_regs = {
182 .set_ofs = 0x14,
183 .clr_ofs = 0x14,
184 .sta_ofs = 0x14,
185 };
186
187 #define GATE_ETHWARP(_id, _name, _parent, _shift) \
188 { \
189 .id = _id, .name = _name, .parent_name = _parent, \
190 .regs = &ethwarp_cg_regs, .shift = _shift, \
191 .ops = &mtk_clk_gate_ops_no_setclr_inv, \
192 }
193
194 static const struct mtk_gate ethwarp_clks[] = {
195 GATE_ETHWARP(CLK_ETHWARP_WOCPU2_EN, "ethwarp_wocpu2_en",
196 "netsys_mcu_sel", 13),
197 GATE_ETHWARP(CLK_ETHWARP_WOCPU1_EN, "ethwarp_wocpu1_en",
198 "netsys_mcu_sel", 14),
199 GATE_ETHWARP(CLK_ETHWARP_WOCPU0_EN, "ethwarp_wocpu0_en",
200 "netsys_mcu_sel", 15),
201 };
202
203 static int clk_mt7988_ethwarp_probe(struct platform_device *pdev)
204 {
205 struct clk_onecell_data *clk_data;
206 struct device_node *node = pdev->dev.of_node;
207 int r;
208 void __iomem *base;
209
210 base = of_iomap(node, 0);
211 if (!base) {
212 pr_err("%s(): ioremap failed\n", __func__);
213 return -ENOMEM;
214 }
215
216 clk_data = mtk_alloc_clk_data(ARRAY_SIZE(ethwarp_clks));
217
218 if (!clk_data)
219 return -ENOMEM;
220
221 mtk_clk_register_gates(node, ethwarp_clks, ARRAY_SIZE(ethwarp_clks),
222 clk_data);
223
224 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
225 if (r) {
226 pr_err("%s(): could not register clock provider: %d\n",
227 __func__, r);
228 goto free_data;
229 }
230 return r;
231
232 free_data:
233 mtk_free_clk_data(clk_data);
234 return r;
235 }
236
237 static const struct of_device_id of_match_clk_mt7988_ethsys[] = {
238 {
239 .compatible = "mediatek,mt7988-ethsys",
240 },
241 {}
242 };
243
244 static struct platform_driver clk_mt7988_ethsys_drv = {
245 .probe = clk_mt7988_ethsys_probe,
246 .driver = {
247 .name = "clk-mt7988-ethsys",
248 .of_match_table = of_match_clk_mt7988_ethsys,
249 },
250 };
251 builtin_platform_driver(clk_mt7988_ethsys_drv);
252
253 static const struct of_device_id of_match_clk_mt7988_sgmii0[] = {
254 {
255 .compatible = "mediatek,mt7988-sgmiisys_0",
256 },
257 {}
258 };
259
260 static struct platform_driver clk_mt7988_sgmii0_drv = {
261 .probe = clk_mt7988_sgmii0_probe,
262 .driver = {
263 .name = "clk-mt7988-sgmiisys_0",
264 .of_match_table = of_match_clk_mt7988_sgmii0,
265 },
266 };
267 builtin_platform_driver(clk_mt7988_sgmii0_drv);
268
269 static const struct of_device_id of_match_clk_mt7988_sgmii1[] = {
270 {
271 .compatible = "mediatek,mt7988-sgmiisys_1",
272 },
273 {}
274 };
275
276 static struct platform_driver clk_mt7988_sgmii1_drv = {
277 .probe = clk_mt7988_sgmii1_probe,
278 .driver = {
279 .name = "clk-mt7988-sgmiisys_1",
280 .of_match_table = of_match_clk_mt7988_sgmii1,
281 },
282 };
283 builtin_platform_driver(clk_mt7988_sgmii1_drv);
284
285 static const struct of_device_id of_match_clk_mt7988_ethwarp[] = {
286 {
287 .compatible = "mediatek,mt7988-ethwarp",
288 },
289 {}
290 };
291
292 static struct platform_driver clk_mt7988_ethwarp_drv = {
293 .probe = clk_mt7988_ethwarp_probe,
294 .driver = {
295 .name = "clk-mt7988-ethwarp",
296 .of_match_table = of_match_clk_mt7988_ethwarp,
297 },
298 };
299 builtin_platform_driver(clk_mt7988_ethwarp_drv);