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 "reset.h" |
16 | #include <dt-bindings/clock/mediatek,mt7988-clk.h> |
17 | #include <dt-bindings/reset/mediatek,mt7988-resets.h> |
18 | |
19 | static const struct mtk_gate_regs ethdma_cg_regs = { |
20 | .set_ofs = 0x30, |
21 | .clr_ofs = 0x30, |
22 | .sta_ofs = 0x30, |
23 | }; |
24 | |
25 | #define GATE_ETHDMA(_id, _name, _parent, _shift) \ |
26 | { \ |
27 | .id = _id, \ |
28 | .name = _name, \ |
29 | .parent_name = _parent, \ |
30 | .regs = ðdma_cg_regs, \ |
31 | .shift = _shift, \ |
32 | .ops = &mtk_clk_gate_ops_no_setclr_inv, \ |
33 | } |
34 | |
35 | static const struct mtk_gate ethdma_clks[] = { |
36 | GATE_ETHDMA(CLK_ETHDMA_XGP1_EN, "ethdma_xgp1_en" , "top_xtal" , 0), |
37 | GATE_ETHDMA(CLK_ETHDMA_XGP2_EN, "ethdma_xgp2_en" , "top_xtal" , 1), |
38 | GATE_ETHDMA(CLK_ETHDMA_XGP3_EN, "ethdma_xgp3_en" , "top_xtal" , 2), |
39 | GATE_ETHDMA(CLK_ETHDMA_FE_EN, "ethdma_fe_en" , "netsys_2x_sel" , 6), |
40 | GATE_ETHDMA(CLK_ETHDMA_GP2_EN, "ethdma_gp2_en" , "top_xtal" , 7), |
41 | GATE_ETHDMA(CLK_ETHDMA_GP1_EN, "ethdma_gp1_en" , "top_xtal" , 8), |
42 | GATE_ETHDMA(CLK_ETHDMA_GP3_EN, "ethdma_gp3_en" , "top_xtal" , 10), |
43 | GATE_ETHDMA(CLK_ETHDMA_ESW_EN, "ethdma_esw_en" , "netsys_gsw_sel" , 16), |
44 | GATE_ETHDMA(CLK_ETHDMA_CRYPT0_EN, "ethdma_crypt0_en" , "eip197_sel" , 29), |
45 | }; |
46 | |
47 | static const struct mtk_clk_desc ethdma_desc = { |
48 | .clks = ethdma_clks, |
49 | .num_clks = ARRAY_SIZE(ethdma_clks), |
50 | }; |
51 | |
52 | static const struct mtk_gate_regs sgmii_cg_regs = { |
53 | .set_ofs = 0xe4, |
54 | .clr_ofs = 0xe4, |
55 | .sta_ofs = 0xe4, |
56 | }; |
57 | |
58 | #define GATE_SGMII(_id, _name, _parent, _shift) \ |
59 | { \ |
60 | .id = _id, \ |
61 | .name = _name, \ |
62 | .parent_name = _parent, \ |
63 | .regs = &sgmii_cg_regs, \ |
64 | .shift = _shift, \ |
65 | .ops = &mtk_clk_gate_ops_no_setclr_inv, \ |
66 | } |
67 | |
68 | static const struct mtk_gate sgmii0_clks[] = { |
69 | GATE_SGMII(CLK_SGM0_TX_EN, "sgm0_tx_en" , "top_xtal" , 2), |
70 | GATE_SGMII(CLK_SGM0_RX_EN, "sgm0_rx_en" , "top_xtal" , 3), |
71 | }; |
72 | |
73 | static const struct mtk_clk_desc sgmii0_desc = { |
74 | .clks = sgmii0_clks, |
75 | .num_clks = ARRAY_SIZE(sgmii0_clks), |
76 | }; |
77 | |
78 | static const struct mtk_gate sgmii1_clks[] = { |
79 | GATE_SGMII(CLK_SGM1_TX_EN, "sgm1_tx_en" , "top_xtal" , 2), |
80 | GATE_SGMII(CLK_SGM1_RX_EN, "sgm1_rx_en" , "top_xtal" , 3), |
81 | }; |
82 | |
83 | static const struct mtk_clk_desc sgmii1_desc = { |
84 | .clks = sgmii1_clks, |
85 | .num_clks = ARRAY_SIZE(sgmii1_clks), |
86 | }; |
87 | |
88 | static const struct mtk_gate_regs ethwarp_cg_regs = { |
89 | .set_ofs = 0x14, |
90 | .clr_ofs = 0x14, |
91 | .sta_ofs = 0x14, |
92 | }; |
93 | |
94 | #define GATE_ETHWARP(_id, _name, _parent, _shift) \ |
95 | { \ |
96 | .id = _id, \ |
97 | .name = _name, \ |
98 | .parent_name = _parent, \ |
99 | .regs = ðwarp_cg_regs, \ |
100 | .shift = _shift, \ |
101 | .ops = &mtk_clk_gate_ops_no_setclr_inv, \ |
102 | } |
103 | |
104 | static const struct mtk_gate ethwarp_clks[] = { |
105 | GATE_ETHWARP(CLK_ETHWARP_WOCPU2_EN, "ethwarp_wocpu2_en" , "netsys_mcu_sel" , 13), |
106 | GATE_ETHWARP(CLK_ETHWARP_WOCPU1_EN, "ethwarp_wocpu1_en" , "netsys_mcu_sel" , 14), |
107 | GATE_ETHWARP(CLK_ETHWARP_WOCPU0_EN, "ethwarp_wocpu0_en" , "netsys_mcu_sel" , 15), |
108 | }; |
109 | |
110 | static u16 ethwarp_rst_ofs[] = { 0x8 }; |
111 | |
112 | static u16 ethwarp_idx_map[] = { |
113 | [MT7988_ETHWARP_RST_SWITCH] = 9, |
114 | }; |
115 | |
116 | static const struct mtk_clk_rst_desc ethwarp_rst_desc = { |
117 | .version = MTK_RST_SIMPLE, |
118 | .rst_bank_ofs = ethwarp_rst_ofs, |
119 | .rst_bank_nr = ARRAY_SIZE(ethwarp_rst_ofs), |
120 | .rst_idx_map = ethwarp_idx_map, |
121 | .rst_idx_map_nr = ARRAY_SIZE(ethwarp_idx_map), |
122 | }; |
123 | |
124 | static const struct mtk_clk_desc ethwarp_desc = { |
125 | .clks = ethwarp_clks, |
126 | .num_clks = ARRAY_SIZE(ethwarp_clks), |
127 | .rst_desc = ðwarp_rst_desc, |
128 | }; |
129 | |
130 | static const struct of_device_id of_match_clk_mt7988_eth[] = { |
131 | { .compatible = "mediatek,mt7988-ethsys" , .data = ðdma_desc }, |
132 | { .compatible = "mediatek,mt7988-sgmiisys0" , .data = &sgmii0_desc }, |
133 | { .compatible = "mediatek,mt7988-sgmiisys1" , .data = &sgmii1_desc }, |
134 | { .compatible = "mediatek,mt7988-ethwarp" , .data = ðwarp_desc }, |
135 | { /* sentinel */ } |
136 | }; |
137 | MODULE_DEVICE_TABLE(of, of_match_clk_mt7988_eth); |
138 | |
139 | static struct platform_driver clk_mt7988_eth_drv = { |
140 | .driver = { |
141 | .name = "clk-mt7988-eth" , |
142 | .of_match_table = of_match_clk_mt7988_eth, |
143 | }, |
144 | .probe = mtk_clk_simple_probe, |
145 | .remove_new = mtk_clk_simple_remove, |
146 | }; |
147 | module_platform_driver(clk_mt7988_eth_drv); |
148 | |
149 | MODULE_DESCRIPTION("MediaTek MT7988 Ethernet clocks driver" ); |
150 | MODULE_LICENSE("GPL" ); |
151 | |