1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (c) 2021 MediaTek Inc. |
4 | * Author: Sam Shih <sam.shih@mediatek.com> |
5 | * Author: Wenzhen Yu <wenzhen.yu@mediatek.com> |
6 | * Author: Jianhui Zhao <zhaojh329@gmail.com> |
7 | * Author: Daniel Golle <daniel@makrotopia.org> |
8 | */ |
9 | |
10 | #include <linux/clk-provider.h> |
11 | #include <linux/mod_devicetable.h> |
12 | #include <linux/platform_device.h> |
13 | #include "clk-mtk.h" |
14 | #include "clk-gate.h" |
15 | #include "clk-mux.h" |
16 | |
17 | #include <dt-bindings/clock/mediatek,mt7981-clk.h> |
18 | #include <linux/clk.h> |
19 | |
20 | static DEFINE_SPINLOCK(mt7981_clk_lock); |
21 | |
22 | static const struct mtk_fixed_factor infra_divs[] = { |
23 | FACTOR(CLK_INFRA_66M_MCK, "infra_66m_mck" , "sysaxi_sel" , 1, 2), |
24 | }; |
25 | |
26 | static const char *const infra_uart_parent[] __initconst = { "csw_f26m_sel" , |
27 | "uart_sel" }; |
28 | |
29 | static const char *const infra_spi0_parents[] __initconst = { "i2c_sel" , |
30 | "spi_sel" }; |
31 | |
32 | static const char *const infra_spi1_parents[] __initconst = { "i2c_sel" , |
33 | "spim_mst_sel" }; |
34 | |
35 | static const char *const infra_pwm1_parents[] __initconst = { "pwm_sel" }; |
36 | |
37 | static const char *const infra_pwm_bsel_parents[] __initconst = { |
38 | "cb_rtc_32p7k" , "csw_f26m_sel" , "infra_66m_mck" , "pwm_sel" |
39 | }; |
40 | |
41 | static const char *const infra_pcie_parents[] __initconst = { |
42 | "cb_rtc_32p7k" , "csw_f26m_sel" , "cb_cksq_40m" , "pextp_tl_ck_sel" |
43 | }; |
44 | |
45 | static const struct mtk_mux infra_muxes[] = { |
46 | /* MODULE_CLK_SEL_0 */ |
47 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART0_SEL, "infra_uart0_sel" , |
48 | infra_uart_parent, 0x0018, 0x0010, 0x0014, 0, 1, |
49 | -1, -1, -1), |
50 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART1_SEL, "infra_uart1_sel" , |
51 | infra_uart_parent, 0x0018, 0x0010, 0x0014, 1, 1, |
52 | -1, -1, -1), |
53 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART2_SEL, "infra_uart2_sel" , |
54 | infra_uart_parent, 0x0018, 0x0010, 0x0014, 2, 1, |
55 | -1, -1, -1), |
56 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI0_SEL, "infra_spi0_sel" , |
57 | infra_spi0_parents, 0x0018, 0x0010, 0x0014, 4, 1, |
58 | -1, -1, -1), |
59 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI1_SEL, "infra_spi1_sel" , |
60 | infra_spi1_parents, 0x0018, 0x0010, 0x0014, 5, 1, |
61 | -1, -1, -1), |
62 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI2_SEL, "infra_spi2_sel" , |
63 | infra_spi0_parents, 0x0018, 0x0010, 0x0014, 6, 1, |
64 | -1, -1, -1), |
65 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM1_SEL, "infra_pwm1_sel" , |
66 | infra_pwm1_parents, 0x0018, 0x0010, 0x0014, 9, 1, |
67 | -1, -1, -1), |
68 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM2_SEL, "infra_pwm2_sel" , |
69 | infra_pwm1_parents, 0x0018, 0x0010, 0x0014, 11, 1, |
70 | -1, -1, -1), |
71 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM3_SEL, "infra_pwm3_sel" , |
72 | infra_pwm1_parents, 0x0018, 0x0010, 0x0014, 15, 1, |
73 | -1, -1, -1), |
74 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_BSEL, "infra_pwm_bsel" , |
75 | infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 13, |
76 | 2, -1, -1, -1), |
77 | /* MODULE_CLK_SEL_1 */ |
78 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_SEL, "infra_pcie_sel" , |
79 | infra_pcie_parents, 0x0028, 0x0020, 0x0024, 0, 2, |
80 | -1, -1, -1), |
81 | }; |
82 | |
83 | static const struct mtk_gate_regs infra0_cg_regs = { |
84 | .set_ofs = 0x40, |
85 | .clr_ofs = 0x44, |
86 | .sta_ofs = 0x48, |
87 | }; |
88 | |
89 | static const struct mtk_gate_regs infra1_cg_regs = { |
90 | .set_ofs = 0x50, |
91 | .clr_ofs = 0x54, |
92 | .sta_ofs = 0x58, |
93 | }; |
94 | |
95 | static const struct mtk_gate_regs infra2_cg_regs = { |
96 | .set_ofs = 0x60, |
97 | .clr_ofs = 0x64, |
98 | .sta_ofs = 0x68, |
99 | }; |
100 | |
101 | #define GATE_INFRA0(_id, _name, _parent, _shift) \ |
102 | { \ |
103 | .id = _id, .name = _name, .parent_name = _parent, \ |
104 | .regs = &infra0_cg_regs, .shift = _shift, \ |
105 | .ops = &mtk_clk_gate_ops_setclr, \ |
106 | } |
107 | |
108 | #define GATE_INFRA1(_id, _name, _parent, _shift) \ |
109 | { \ |
110 | .id = _id, .name = _name, .parent_name = _parent, \ |
111 | .regs = &infra1_cg_regs, .shift = _shift, \ |
112 | .ops = &mtk_clk_gate_ops_setclr, \ |
113 | } |
114 | |
115 | #define GATE_INFRA2(_id, _name, _parent, _shift) \ |
116 | { \ |
117 | .id = _id, .name = _name, .parent_name = _parent, \ |
118 | .regs = &infra2_cg_regs, .shift = _shift, \ |
119 | .ops = &mtk_clk_gate_ops_setclr, \ |
120 | } |
121 | |
122 | static const struct mtk_gate infra_clks[] = { |
123 | /* INFRA0 */ |
124 | GATE_INFRA0(CLK_INFRA_GPT_STA, "infra_gpt_sta" , "infra_66m_mck" , 0), |
125 | GATE_INFRA0(CLK_INFRA_PWM_HCK, "infra_pwm_hck" , "infra_66m_mck" , 1), |
126 | GATE_INFRA0(CLK_INFRA_PWM_STA, "infra_pwm_sta" , "infra_pwm_bsel" , 2), |
127 | GATE_INFRA0(CLK_INFRA_PWM1_CK, "infra_pwm1" , "infra_pwm1_sel" , 3), |
128 | GATE_INFRA0(CLK_INFRA_PWM2_CK, "infra_pwm2" , "infra_pwm2_sel" , 4), |
129 | GATE_INFRA0(CLK_INFRA_CQ_DMA_CK, "infra_cq_dma" , "sysaxi" , 6), |
130 | |
131 | GATE_INFRA0(CLK_INFRA_AUD_BUS_CK, "infra_aud_bus" , "sysaxi" , 8), |
132 | GATE_INFRA0(CLK_INFRA_AUD_26M_CK, "infra_aud_26m" , "csw_f26m_sel" , 9), |
133 | GATE_INFRA0(CLK_INFRA_AUD_L_CK, "infra_aud_l" , "aud_l" , 10), |
134 | GATE_INFRA0(CLK_INFRA_AUD_AUD_CK, "infra_aud_aud" , "a1sys" , 11), |
135 | GATE_INFRA0(CLK_INFRA_AUD_EG2_CK, "infra_aud_eg2" , "a_tuner" , 13), |
136 | GATE_INFRA0(CLK_INFRA_DRAMC_26M_CK, "infra_dramc_26m" , "csw_f26m_sel" , |
137 | 14), |
138 | GATE_INFRA0(CLK_INFRA_DBG_CK, "infra_dbg" , "infra_66m_mck" , 15), |
139 | GATE_INFRA0(CLK_INFRA_AP_DMA_CK, "infra_ap_dma" , "infra_66m_mck" , 16), |
140 | GATE_INFRA0(CLK_INFRA_SEJ_CK, "infra_sej" , "infra_66m_mck" , 24), |
141 | GATE_INFRA0(CLK_INFRA_SEJ_13M_CK, "infra_sej_13m" , "csw_f26m_sel" , 25), |
142 | GATE_INFRA0(CLK_INFRA_PWM3_CK, "infra_pwm3" , "infra_pwm3_sel" , 27), |
143 | /* INFRA1 */ |
144 | GATE_INFRA1(CLK_INFRA_THERM_CK, "infra_therm" , "csw_f26m_sel" , 0), |
145 | GATE_INFRA1(CLK_INFRA_I2C0_CK, "infra_i2c0" , "i2c_bck" , 1), |
146 | GATE_INFRA1(CLK_INFRA_UART0_CK, "infra_uart0" , "infra_uart0_sel" , 2), |
147 | GATE_INFRA1(CLK_INFRA_UART1_CK, "infra_uart1" , "infra_uart1_sel" , 3), |
148 | GATE_INFRA1(CLK_INFRA_UART2_CK, "infra_uart2" , "infra_uart2_sel" , 4), |
149 | GATE_INFRA1(CLK_INFRA_SPI2_CK, "infra_spi2" , "infra_spi2_sel" , 6), |
150 | GATE_INFRA1(CLK_INFRA_SPI2_HCK_CK, "infra_spi2_hck" , "infra_66m_mck" , 7), |
151 | GATE_INFRA1(CLK_INFRA_NFI1_CK, "infra_nfi1" , "nfi1x" , 8), |
152 | GATE_INFRA1(CLK_INFRA_SPINFI1_CK, "infra_spinfi1" , "spinfi_bck" , 9), |
153 | GATE_INFRA1(CLK_INFRA_NFI_HCK_CK, "infra_nfi_hck" , "infra_66m_mck" , 10), |
154 | GATE_INFRA1(CLK_INFRA_SPI0_CK, "infra_spi0" , "infra_spi0_sel" , 11), |
155 | GATE_INFRA1(CLK_INFRA_SPI1_CK, "infra_spi1" , "infra_spi1_sel" , 12), |
156 | GATE_INFRA1(CLK_INFRA_SPI0_HCK_CK, "infra_spi0_hck" , "infra_66m_mck" , |
157 | 13), |
158 | GATE_INFRA1(CLK_INFRA_SPI1_HCK_CK, "infra_spi1_hck" , "infra_66m_mck" , |
159 | 14), |
160 | GATE_INFRA1(CLK_INFRA_FRTC_CK, "infra_frtc" , "cb_rtc_32k" , 15), |
161 | GATE_INFRA1(CLK_INFRA_MSDC_CK, "infra_msdc" , "emmc_400m" , 16), |
162 | GATE_INFRA1(CLK_INFRA_MSDC_HCK_CK, "infra_msdc_hck" , "emmc_208m" , 17), |
163 | GATE_INFRA1(CLK_INFRA_MSDC_133M_CK, "infra_msdc_133m" , "sysaxi" , 18), |
164 | GATE_INFRA1(CLK_INFRA_MSDC_66M_CK, "infra_msdc_66m" , "sysaxi" , 19), |
165 | GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m" , "infra_adc_frc" , 20), |
166 | GATE_INFRA1(CLK_INFRA_ADC_FRC_CK, "infra_adc_frc" , "csw_f26m" , 21), |
167 | GATE_INFRA1(CLK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc" , "nfi1x" , 23), |
168 | GATE_INFRA1(CLK_INFRA_I2C_MCK_CK, "infra_i2c_mck" , "sysaxi" , 25), |
169 | GATE_INFRA1(CLK_INFRA_I2C_PCK_CK, "infra_i2c_pck" , "infra_66m_mck" , 26), |
170 | /* INFRA2 */ |
171 | GATE_INFRA2(CLK_INFRA_IUSB_133_CK, "infra_iusb_133" , "sysaxi" , 0), |
172 | GATE_INFRA2(CLK_INFRA_IUSB_66M_CK, "infra_iusb_66m" , "sysaxi" , 1), |
173 | GATE_INFRA2(CLK_INFRA_IUSB_SYS_CK, "infra_iusb_sys" , "u2u3_sys" , 2), |
174 | GATE_INFRA2(CLK_INFRA_IUSB_CK, "infra_iusb" , "u2u3_ref" , 3), |
175 | GATE_INFRA2(CLK_INFRA_IPCIE_CK, "infra_ipcie" , "pextp_tl" , 12), |
176 | GATE_INFRA2(CLK_INFRA_IPCIE_PIPE_CK, "infra_ipcie_pipe" , "cb_cksq_40m" , |
177 | 13), |
178 | GATE_INFRA2(CLK_INFRA_IPCIER_CK, "infra_ipcier" , "csw_f26m" , 14), |
179 | GATE_INFRA2(CLK_INFRA_IPCIEB_CK, "infra_ipcieb" , "sysaxi" , 15), |
180 | }; |
181 | |
182 | static const struct mtk_clk_desc infracfg_desc = { |
183 | .factor_clks = infra_divs, |
184 | .num_factor_clks = ARRAY_SIZE(infra_divs), |
185 | .mux_clks = infra_muxes, |
186 | .num_mux_clks = ARRAY_SIZE(infra_muxes), |
187 | .clks = infra_clks, |
188 | .num_clks = ARRAY_SIZE(infra_clks), |
189 | .clk_lock = &mt7981_clk_lock, |
190 | }; |
191 | |
192 | static const struct of_device_id of_match_clk_mt7981_infracfg[] = { |
193 | { .compatible = "mediatek,mt7981-infracfg" , .data = &infracfg_desc }, |
194 | { /* sentinel */ } |
195 | }; |
196 | MODULE_DEVICE_TABLE(of, of_match_clk_mt7981_infracfg); |
197 | |
198 | static struct platform_driver clk_mt7981_infracfg_drv = { |
199 | .probe = mtk_clk_simple_probe, |
200 | .remove_new = mtk_clk_simple_remove, |
201 | .driver = { |
202 | .name = "clk-mt7981-infracfg" , |
203 | .of_match_table = of_match_clk_mt7981_infracfg, |
204 | }, |
205 | }; |
206 | module_platform_driver(clk_mt7981_infracfg_drv); |
207 | MODULE_LICENSE("GPL" ); |
208 | |