1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2023 MediaTek Inc.
4 * Author: Sam Shih <sam.shih@mediatek.com>
5 * Author: Xiufeng Li <Xiufeng.Li@mediatek.com>
8 #include <linux/clk-provider.h>
10 #include <linux/of_address.h>
11 #include <linux/of_device.h>
12 #include <linux/platform_device.h>
16 #include <dt-bindings/clock/mediatek,mt7988-clk.h>
18 static DEFINE_SPINLOCK(mt7988_clk_lock
);
20 static const char *const infra_mux_uart0_parents
[] __initconst
= {
21 "csw_infra_f26m_sel", "uart_sel"
24 static const char *const infra_mux_uart1_parents
[] __initconst
= {
25 "csw_infra_f26m_sel", "uart_sel"
28 static const char *const infra_mux_uart2_parents
[] __initconst
= {
29 "csw_infra_f26m_sel", "uart_sel"
32 static const char *const infra_mux_spi0_parents
[] __initconst
= { "i2c_sel",
35 static const char *const infra_mux_spi1_parents
[] __initconst
= {
36 "i2c_sel", "spim_mst_sel"
39 static const char *const infra_pwm_bck_parents
[] __initconst
= {
40 "top_rtc_32p7k", "csw_infra_f26m_sel", "sysaxi_sel", "pwm_sel"
43 static const char *const infra_pcie_gfmux_tl_ck_o_p0_parents
[] __initconst
= {
44 "top_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel",
48 static const char *const infra_pcie_gfmux_tl_ck_o_p1_parents
[] __initconst
= {
49 "top_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel",
53 static const char *const infra_pcie_gfmux_tl_ck_o_p2_parents
[] __initconst
= {
54 "top_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel",
58 static const char *const infra_pcie_gfmux_tl_ck_o_p3_parents
[] __initconst
= {
59 "top_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel",
63 static const struct mtk_mux infra_muxes
[] = {
64 /* MODULE_CLK_SEL_0 */
65 MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_UART0_SEL
, "infra_mux_uart0_sel",
66 infra_mux_uart0_parents
, 0x0018, 0x0010, 0x0014,
68 MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_UART1_SEL
, "infra_mux_uart1_sel",
69 infra_mux_uart1_parents
, 0x0018, 0x0010, 0x0014,
71 MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_UART2_SEL
, "infra_mux_uart2_sel",
72 infra_mux_uart2_parents
, 0x0018, 0x0010, 0x0014,
74 MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_SPI0_SEL
, "infra_mux_spi0_sel",
75 infra_mux_spi0_parents
, 0x0018, 0x0010, 0x0014, 4,
77 MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_SPI1_SEL
, "infra_mux_spi1_sel",
78 infra_mux_spi1_parents
, 0x0018, 0x0010, 0x0014, 5,
80 MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_SPI2_SEL
, "infra_mux_spi2_sel",
81 infra_mux_spi0_parents
, 0x0018, 0x0010, 0x0014, 6,
83 MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_SEL
, "infra_pwm_sel",
84 infra_pwm_bck_parents
, 0x0018, 0x0010, 0x0014, 14,
86 MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK1_SEL
, "infra_pwm_ck1_sel",
87 infra_pwm_bck_parents
, 0x0018, 0x0010, 0x0014, 16,
89 MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK2_SEL
, "infra_pwm_ck2_sel",
90 infra_pwm_bck_parents
, 0x0018, 0x0010, 0x0014, 18,
92 MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK3_SEL
, "infra_pwm_ck3_sel",
93 infra_pwm_bck_parents
, 0x0018, 0x0010, 0x0014, 20,
95 MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK4_SEL
, "infra_pwm_ck4_sel",
96 infra_pwm_bck_parents
, 0x0018, 0x0010, 0x0014, 22,
98 MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK5_SEL
, "infra_pwm_ck5_sel",
99 infra_pwm_bck_parents
, 0x0018, 0x0010, 0x0014, 24,
101 MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK6_SEL
, "infra_pwm_ck6_sel",
102 infra_pwm_bck_parents
, 0x0018, 0x0010, 0x0014, 26,
104 MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK7_SEL
, "infra_pwm_ck7_sel",
105 infra_pwm_bck_parents
, 0x0018, 0x0010, 0x0014, 28,
107 MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK8_SEL
, "infra_pwm_ck8_sel",
108 infra_pwm_bck_parents
, 0x0018, 0x0010, 0x0014, 30,
110 /* MODULE_CLK_SEL_1 */
111 MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P0_SEL
,
112 "infra_pcie_gfmux_tl_o_p0_sel",
113 infra_pcie_gfmux_tl_ck_o_p0_parents
, 0x0028,
114 0x0020, 0x0024, 0, 2, -1, -1, -1),
115 MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P1_SEL
,
116 "infra_pcie_gfmux_tl_o_p1_sel",
117 infra_pcie_gfmux_tl_ck_o_p1_parents
, 0x0028,
118 0x0020, 0x0024, 2, 2, -1, -1, -1),
119 MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P2_SEL
,
120 "infra_pcie_gfmux_tl_o_p2_sel",
121 infra_pcie_gfmux_tl_ck_o_p2_parents
, 0x0028,
122 0x0020, 0x0024, 4, 2, -1, -1, -1),
123 MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P3_SEL
,
124 "infra_pcie_gfmux_tl_o_p3_sel",
125 infra_pcie_gfmux_tl_ck_o_p3_parents
, 0x0028,
126 0x0020, 0x0024, 6, 2, -1, -1, -1),
129 static const struct mtk_gate_regs infra0_cg_regs
= {
135 static const struct mtk_gate_regs infra1_cg_regs
= {
141 static const struct mtk_gate_regs infra2_cg_regs
= {
147 static const struct mtk_gate_regs infra3_cg_regs
= {
153 #define GATE_INFRA0_FLAGS(_id, _name, _parent, _shift, _flags) \
155 .id = _id, .name = _name, .parent_name = _parent, \
156 .regs = &infra0_cg_regs, .shift = _shift, \
157 .ops = &mtk_clk_gate_ops_setclr, .flags = _flags, \
160 #define GATE_INFRA1_FLAGS(_id, _name, _parent, _shift, _flags) \
162 .id = _id, .name = _name, .parent_name = _parent, \
163 .regs = &infra1_cg_regs, .shift = _shift, \
164 .ops = &mtk_clk_gate_ops_setclr, .flags = _flags, \
167 #define GATE_INFRA2_FLAGS(_id, _name, _parent, _shift, _flags) \
169 .id = _id, .name = _name, .parent_name = _parent, \
170 .regs = &infra2_cg_regs, .shift = _shift, \
171 .ops = &mtk_clk_gate_ops_setclr, .flags = _flags, \
174 #define GATE_INFRA3_FLAGS(_id, _name, _parent, _shift, _flags) \
176 .id = _id, .name = _name, .parent_name = _parent, \
177 .regs = &infra3_cg_regs, .shift = _shift, \
178 .ops = &mtk_clk_gate_ops_setclr, .flags = _flags, \
181 #define GATE_INFRA0(_id, _name, _parent, _shift) \
182 GATE_INFRA0_FLAGS(_id, _name, _parent, _shift, 0)
184 #define GATE_INFRA1(_id, _name, _parent, _shift) \
185 GATE_INFRA1_FLAGS(_id, _name, _parent, _shift, 0)
187 #define GATE_INFRA2(_id, _name, _parent, _shift) \
188 GATE_INFRA2_FLAGS(_id, _name, _parent, _shift, 0)
190 #define GATE_INFRA3(_id, _name, _parent, _shift) \
191 GATE_INFRA3_FLAGS(_id, _name, _parent, _shift, 0)
193 static const struct mtk_gate infra_clks
[] = {
195 GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P0
,
196 "infra_pcie_peri_ck_26m_ck_p0", "csw_infra_f26m_sel", 7),
197 GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P1
,
198 "infra_pcie_peri_ck_26m_ck_p1", "csw_infra_f26m_sel", 8),
199 GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P2
,
200 "infra_pcie_peri_ck_26m_ck_p2", "csw_infra_f26m_sel", 9),
201 GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P3
,
202 "infra_pcie_peri_ck_26m_ck_p3", "csw_infra_f26m_sel", 10),
204 GATE_INFRA1(CLK_INFRA_66M_GPT_BCK
, "infra_hf_66m_gpt_bck",
206 GATE_INFRA1(CLK_INFRA_66M_PWM_HCK
, "infra_hf_66m_pwm_hck",
208 GATE_INFRA1(CLK_INFRA_66M_PWM_BCK
, "infra_hf_66m_pwm_bck",
210 GATE_INFRA1(CLK_INFRA_66M_PWM_CK1
, "infra_hf_66m_pwm_ck1",
211 "infra_pwm_ck1_sel", 3),
212 GATE_INFRA1(CLK_INFRA_66M_PWM_CK2
, "infra_hf_66m_pwm_ck2",
213 "infra_pwm_ck2_sel", 4),
214 GATE_INFRA1(CLK_INFRA_66M_PWM_CK3
, "infra_hf_66m_pwm_ck3",
215 "infra_pwm_ck3_sel", 5),
216 GATE_INFRA1(CLK_INFRA_66M_PWM_CK4
, "infra_hf_66m_pwm_ck4",
217 "infra_pwm_ck4_sel", 6),
218 GATE_INFRA1(CLK_INFRA_66M_PWM_CK5
, "infra_hf_66m_pwm_ck5",
219 "infra_pwm_ck5_sel", 7),
220 GATE_INFRA1(CLK_INFRA_66M_PWM_CK6
, "infra_hf_66m_pwm_ck6",
221 "infra_pwm_ck6_sel", 8),
222 GATE_INFRA1(CLK_INFRA_66M_PWM_CK7
, "infra_hf_66m_pwm_ck7",
223 "infra_pwm_ck7_sel", 9),
224 GATE_INFRA1(CLK_INFRA_66M_PWM_CK8
, "infra_hf_66m_pwm_ck8",
225 "infra_pwm_ck8_sel", 10),
226 GATE_INFRA1(CLK_INFRA_133M_CQDMA_BCK
, "infra_hf_133m_cqdma_bck",
228 GATE_INFRA1(CLK_INFRA_66M_AUD_SLV_BCK
, "infra_66m_aud_slv_bck",
230 GATE_INFRA1(CLK_INFRA_AUD_26M
, "infra_f_faud_26m",
231 "csw_infra_f26m_sel", 14),
232 GATE_INFRA1(CLK_INFRA_AUD_L
, "infra_f_faud_l", "aud_l_sel", 15),
233 GATE_INFRA1(CLK_INFRA_AUD_AUD
, "infra_f_aud_aud", "a1sys_sel", 16),
234 GATE_INFRA1(CLK_INFRA_AUD_EG2
, "infra_f_faud_eg2", "a_tuner_sel", 18),
235 GATE_INFRA1_FLAGS(CLK_INFRA_DRAMC_F26M
, "infra_dramc_f26m",
236 "csw_infra_f26m_sel", 19, CLK_IS_CRITICAL
),
238 GATE_INFRA1_FLAGS(CLK_INFRA_133M_DBG_ACKM
, "infra_hf_133m_dbg_ackm",
239 "sysaxi_sel", 20, CLK_IS_CRITICAL
),
240 GATE_INFRA1(CLK_INFRA_66M_AP_DMA_BCK
, "infra_66m_ap_dma_bck",
242 GATE_INFRA1(CLK_INFRA_66M_SEJ_BCK
, "infra_hf_66m_sej_bck",
244 GATE_INFRA1(CLK_INFRA_PRE_CK_SEJ_F13M
, "infra_pre_ck_sej_f13m",
245 "csw_infra_f26m_sel", 30),
247 GATE_INFRA2(CLK_INFRA_26M_THERM_SYSTEM
, "infra_hf_26m_therm_system",
248 "csw_infra_f26m_sel", 0),
249 GATE_INFRA2(CLK_INFRA_I2C_BCK
, "infra_i2c_bck", "i2c_sel", 1),
250 GATE_INFRA2(CLK_INFRA_52M_UART0_CK
, "infra_f_52m_uart0",
251 "infra_mux_uart0_sel", 3),
252 GATE_INFRA2(CLK_INFRA_52M_UART1_CK
, "infra_f_52m_uart1",
253 "infra_mux_uart1_sel", 4),
254 GATE_INFRA2(CLK_INFRA_52M_UART2_CK
, "infra_f_52m_uart2",
255 "infra_mux_uart2_sel", 5),
256 GATE_INFRA2(CLK_INFRA_NFI
, "infra_f_fnfi", "nfi1x_sel", 9),
257 GATE_INFRA2(CLK_INFRA_SPINFI
, "infra_f_fspinfi", "spinfi_sel", 10),
258 GATE_INFRA2_FLAGS(CLK_INFRA_66M_NFI_HCK
, "infra_hf_66m_nfi_hck",
259 "sysaxi_sel", 11, CLK_IS_CRITICAL
),
260 GATE_INFRA2_FLAGS(CLK_INFRA_104M_SPI0
, "infra_hf_104m_spi0",
261 "infra_mux_spi0_sel", 12, CLK_IS_CRITICAL
),
262 GATE_INFRA2(CLK_INFRA_104M_SPI1
, "infra_hf_104m_spi1",
263 "infra_mux_spi1_sel", 13),
264 GATE_INFRA2(CLK_INFRA_104M_SPI2_BCK
, "infra_hf_104m_spi2_bck",
265 "infra_mux_spi2_sel", 14),
266 GATE_INFRA2_FLAGS(CLK_INFRA_66M_SPI0_HCK
, "infra_hf_66m_spi0_hck",
267 "sysaxi_sel", 15, CLK_IS_CRITICAL
),
268 GATE_INFRA2(CLK_INFRA_66M_SPI1_HCK
, "infra_hf_66m_spi1_hck",
270 GATE_INFRA2(CLK_INFRA_66M_SPI2_HCK
, "infra_hf_66m_spi2_hck",
272 GATE_INFRA2(CLK_INFRA_66M_FLASHIF_AXI
, "infra_hf_66m_flashif_axi",
274 GATE_INFRA2(CLK_INFRA_RTC
, "infra_f_frtc", "top_rtc_32k", 19),
275 GATE_INFRA2(CLK_INFRA_26M_ADC_BCK
, "infra_f_26m_adc_bck",
276 "csw_infra_f26m_sel", 20),
277 GATE_INFRA2(CLK_INFRA_RC_ADC
, "infra_f_frc_adc", "infra_f_26m_adc_bck",
279 GATE_INFRA2(CLK_INFRA_MSDC400
, "infra_f_fmsdc400", "emmc_400m_sel",
281 GATE_INFRA2(CLK_INFRA_MSDC2_HCK
, "infra_f_fmsdc2_hck", "emmc_250m_sel",
283 GATE_INFRA2(CLK_INFRA_133M_MSDC_0_HCK
, "infra_hf_133m_msdc_0_hck",
285 GATE_INFRA2(CLK_INFRA_66M_MSDC_0_HCK
, "infra_66m_msdc_0_hck",
287 GATE_INFRA2(CLK_INFRA_133M_CPUM_BCK
, "infra_hf_133m_cpum_bck",
289 GATE_INFRA2(CLK_INFRA_BIST2FPC
, "infra_hf_fbist2fpc", "nfi1x_sel", 27),
290 GATE_INFRA2(CLK_INFRA_I2C_X16W_MCK_CK_P1
,
291 "infra_hf_i2c_x16w_mck_ck_p1", "sysaxi_sel", 29),
292 GATE_INFRA2(CLK_INFRA_I2C_X16W_PCK_CK_P1
,
293 "infra_hf_i2c_x16w_pck_ck_p1", "sysaxi_sel", 31),
295 GATE_INFRA3(CLK_INFRA_133M_USB_HCK
, "infra_133m_usb_hck", "sysaxi_sel",
297 GATE_INFRA3(CLK_INFRA_133M_USB_HCK_CK_P1
, "infra_133m_usb_hck_ck_p1",
299 GATE_INFRA3(CLK_INFRA_66M_USB_HCK
, "infra_66m_usb_hck", "sysaxi_sel",
301 GATE_INFRA3(CLK_INFRA_66M_USB_HCK_CK_P1
, "infra_66m_usb_hck_ck_p1",
303 GATE_INFRA3(CLK_INFRA_USB_SYS
, "infra_usb_sys", "usb_sys_sel", 4),
304 GATE_INFRA3(CLK_INFRA_USB_SYS_CK_P1
, "infra_usb_sys_ck_p1",
305 "usb_sys_p1_sel", 5),
306 GATE_INFRA3(CLK_INFRA_USB_REF
, "infra_usb_ref", "top_xtal", 6),
307 GATE_INFRA3(CLK_INFRA_USB_CK_P1
, "infra_usb_ck_p1", "top_xtal", 7),
308 GATE_INFRA3_FLAGS(CLK_INFRA_USB_FRMCNT
, "infra_usb_frmcnt",
309 "usb_frmcnt_sel", 8, CLK_IS_CRITICAL
),
310 GATE_INFRA3_FLAGS(CLK_INFRA_USB_FRMCNT_CK_P1
, "infra_usb_frmcnt_ck_p1",
311 "usb_frmcnt_p1_sel", 9, CLK_IS_CRITICAL
),
312 GATE_INFRA3(CLK_INFRA_USB_PIPE
, "infra_usb_pipe", "sspxtp_sel", 10),
313 GATE_INFRA3(CLK_INFRA_USB_PIPE_CK_P1
, "infra_usb_pipe_ck_p1",
315 GATE_INFRA3(CLK_INFRA_USB_UTMI
, "infra_usb_utmi", "top_xtal", 12),
316 GATE_INFRA3(CLK_INFRA_USB_UTMI_CK_P1
, "infra_usb_utmi_ck_p1",
318 GATE_INFRA3(CLK_INFRA_USB_XHCI
, "infra_usb_xhci", "usb_xhci_sel", 14),
319 GATE_INFRA3(CLK_INFRA_USB_XHCI_CK_P1
, "infra_usb_xhci_ck_p1",
320 "usb_xhci_p1_sel", 15),
321 GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P0
, "infra_pcie_gfmux_tl_ck_p0",
322 "infra_pcie_gfmux_tl_o_p0_sel", 20),
323 GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P1
, "infra_pcie_gfmux_tl_ck_p1",
324 "infra_pcie_gfmux_tl_o_p1_sel", 21),
325 GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P2
, "infra_pcie_gfmux_tl_ck_p2",
326 "infra_pcie_gfmux_tl_o_p2_sel", 22),
327 GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P3
, "infra_pcie_gfmux_tl_ck_p3",
328 "infra_pcie_gfmux_tl_o_p3_sel", 23),
329 GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P0
, "infra_pcie_pipe_ck_p0",
331 GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P1
, "infra_pcie_pipe_ck_p1",
333 GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P2
, "infra_pcie_pipe_ck_p2",
335 GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P3
, "infra_pcie_pipe_ck_p3",
337 GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P0
, "infra_133m_pcie_ck_p0",
339 GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P1
, "infra_133m_pcie_ck_p1",
341 GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P2
, "infra_133m_pcie_ck_p2",
343 GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P3
, "infra_133m_pcie_ck_p3",
347 static int clk_mt7988_infracfg_probe(struct platform_device
*pdev
)
349 struct clk_onecell_data
*clk_data
;
350 struct device_node
*node
= pdev
->dev
.of_node
;
353 int nr
= ARRAY_SIZE(infra_muxes
) + ARRAY_SIZE(infra_clks
);
355 base
= of_iomap(node
, 0);
357 pr_err("%s(): ioremap failed\n", __func__
);
361 clk_data
= mtk_alloc_clk_data(nr
);
366 mtk_clk_register_muxes(infra_muxes
, ARRAY_SIZE(infra_muxes
), node
,
367 &mt7988_clk_lock
, clk_data
);
369 mtk_clk_register_gates(node
, infra_clks
, ARRAY_SIZE(infra_clks
),
372 r
= of_clk_add_provider(node
, of_clk_src_onecell_get
, clk_data
);
374 pr_err("%s(): could not register clock provider: %d\n",
376 goto free_infracfg_data
;
381 mtk_free_clk_data(clk_data
);
385 static const struct of_device_id of_match_clk_mt7988_infracfg
[] = {
387 .compatible
= "mediatek,mt7988-infracfg",
392 static struct platform_driver clk_mt7988_infracfg_drv
= {
393 .probe
= clk_mt7988_infracfg_probe
,
395 .name
= "clk-mt7988-infracfg",
396 .of_match_table
= of_match_clk_mt7988_infracfg
,
399 builtin_platform_driver(clk_mt7988_infracfg_drv
);