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 | */ |
7 | |
8 | #include <linux/clk-provider.h> |
9 | #include <linux/mod_devicetable.h> |
10 | #include <linux/platform_device.h> |
11 | #include "clk-mtk.h" |
12 | #include "clk-gate.h" |
13 | #include "clk-mux.h" |
14 | |
15 | #include <dt-bindings/clock/mt7986-clk.h> |
16 | #include <linux/clk.h> |
17 | |
18 | static DEFINE_SPINLOCK(mt7986_clk_lock); |
19 | |
20 | static const struct mtk_fixed_factor infra_divs[] = { |
21 | FACTOR(CLK_INFRA_SYSAXI_D2, "infra_sysaxi_d2" , "sysaxi_sel" , 1, 2), |
22 | }; |
23 | |
24 | static const char *const infra_uart_parent[] __initconst = { "csw_f26m_sel" , |
25 | "uart_sel" }; |
26 | |
27 | static const char *const infra_spi_parents[] __initconst = { "i2c_sel" , |
28 | "spi_sel" }; |
29 | |
30 | static const char *const infra_pwm_bsel_parents[] __initconst = { |
31 | "top_rtc_32p7k" , "csw_f26m_sel" , "infra_sysaxi_d2" , "pwm_sel" |
32 | }; |
33 | |
34 | static const char *const infra_pcie_parents[] __initconst = { |
35 | "top_rtc_32p7k" , "csw_f26m_sel" , "top_xtal" , "pextp_tl_ck_sel" |
36 | }; |
37 | |
38 | static const struct mtk_mux infra_muxes[] = { |
39 | /* MODULE_CLK_SEL_0 */ |
40 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART0_SEL, "infra_uart0_sel" , |
41 | infra_uart_parent, 0x0018, 0x0010, 0x0014, 0, 1, |
42 | -1, -1, -1), |
43 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART1_SEL, "infra_uart1_sel" , |
44 | infra_uart_parent, 0x0018, 0x0010, 0x0014, 1, 1, |
45 | -1, -1, -1), |
46 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART2_SEL, "infra_uart2_sel" , |
47 | infra_uart_parent, 0x0018, 0x0010, 0x0014, 2, 1, |
48 | -1, -1, -1), |
49 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI0_SEL, "infra_spi0_sel" , |
50 | infra_spi_parents, 0x0018, 0x0010, 0x0014, 4, 1, |
51 | -1, -1, -1), |
52 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI1_SEL, "infra_spi1_sel" , |
53 | infra_spi_parents, 0x0018, 0x0010, 0x0014, 5, 1, |
54 | -1, -1, -1), |
55 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM1_SEL, "infra_pwm1_sel" , |
56 | infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 9, |
57 | 2, -1, -1, -1), |
58 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM2_SEL, "infra_pwm2_sel" , |
59 | infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 11, |
60 | 2, -1, -1, -1), |
61 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_BSEL, "infra_pwm_bsel" , |
62 | infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 13, |
63 | 2, -1, -1, -1), |
64 | /* MODULE_CLK_SEL_1 */ |
65 | MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_SEL, "infra_pcie_sel" , |
66 | infra_pcie_parents, 0x0028, 0x0020, 0x0024, 0, 2, |
67 | -1, -1, -1), |
68 | }; |
69 | |
70 | static const struct mtk_gate_regs infra0_cg_regs = { |
71 | .set_ofs = 0x40, |
72 | .clr_ofs = 0x44, |
73 | .sta_ofs = 0x48, |
74 | }; |
75 | |
76 | static const struct mtk_gate_regs infra1_cg_regs = { |
77 | .set_ofs = 0x50, |
78 | .clr_ofs = 0x54, |
79 | .sta_ofs = 0x58, |
80 | }; |
81 | |
82 | static const struct mtk_gate_regs infra2_cg_regs = { |
83 | .set_ofs = 0x60, |
84 | .clr_ofs = 0x64, |
85 | .sta_ofs = 0x68, |
86 | }; |
87 | |
88 | #define GATE_INFRA0(_id, _name, _parent, _shift) \ |
89 | GATE_MTK(_id, _name, _parent, &infra0_cg_regs, _shift, &mtk_clk_gate_ops_setclr) |
90 | |
91 | #define GATE_INFRA1(_id, _name, _parent, _shift) \ |
92 | GATE_MTK(_id, _name, _parent, &infra1_cg_regs, _shift, &mtk_clk_gate_ops_setclr) |
93 | |
94 | #define GATE_INFRA2(_id, _name, _parent, _shift) \ |
95 | GATE_MTK(_id, _name, _parent, &infra2_cg_regs, _shift, &mtk_clk_gate_ops_setclr) |
96 | |
97 | static const struct mtk_gate infra_clks[] = { |
98 | /* INFRA0 */ |
99 | GATE_INFRA0(CLK_INFRA_GPT_STA, "infra_gpt_sta" , "infra_sysaxi_d2" , 0), |
100 | GATE_INFRA0(CLK_INFRA_PWM_HCK, "infra_pwm_hck" , "infra_sysaxi_d2" , 1), |
101 | GATE_INFRA0(CLK_INFRA_PWM_STA, "infra_pwm_sta" , "infra_pwm_bsel" , 2), |
102 | GATE_INFRA0(CLK_INFRA_PWM1_CK, "infra_pwm1" , "infra_pwm1_sel" , 3), |
103 | GATE_INFRA0(CLK_INFRA_PWM2_CK, "infra_pwm2" , "infra_pwm2_sel" , 4), |
104 | GATE_INFRA0(CLK_INFRA_CQ_DMA_CK, "infra_cq_dma" , "sysaxi_sel" , 6), |
105 | GATE_INFRA0(CLK_INFRA_EIP97_CK, "infra_eip97" , "eip_b_sel" , 7), |
106 | GATE_INFRA0(CLK_INFRA_AUD_BUS_CK, "infra_aud_bus" , "sysaxi_sel" , 8), |
107 | GATE_INFRA0(CLK_INFRA_AUD_26M_CK, "infra_aud_26m" , "csw_f26m_sel" , 9), |
108 | GATE_INFRA0(CLK_INFRA_AUD_L_CK, "infra_aud_l" , "aud_l_sel" , 10), |
109 | GATE_INFRA0(CLK_INFRA_AUD_AUD_CK, "infra_aud_aud" , "a1sys_sel" , 11), |
110 | GATE_INFRA0(CLK_INFRA_AUD_EG2_CK, "infra_aud_eg2" , "a_tuner_sel" , 13), |
111 | GATE_INFRA0(CLK_INFRA_DRAMC_26M_CK, "infra_dramc_26m" , "csw_f26m_sel" , |
112 | 14), |
113 | GATE_INFRA0(CLK_INFRA_DBG_CK, "infra_dbg" , "infra_sysaxi_d2" , 15), |
114 | GATE_INFRA0(CLK_INFRA_AP_DMA_CK, "infra_ap_dma" , "infra_sysaxi_d2" , 16), |
115 | GATE_INFRA0(CLK_INFRA_SEJ_CK, "infra_sej" , "infra_sysaxi_d2" , 24), |
116 | GATE_INFRA0(CLK_INFRA_SEJ_13M_CK, "infra_sej_13m" , "csw_f26m_sel" , 25), |
117 | GATE_INFRA0(CLK_INFRA_TRNG_CK, "infra_trng" , "sysaxi_sel" , 26), |
118 | /* INFRA1 */ |
119 | GATE_INFRA1(CLK_INFRA_THERM_CK, "infra_therm" , "csw_f26m_sel" , 0), |
120 | GATE_INFRA1(CLK_INFRA_I2C0_CK, "infra_i2c0" , "i2c_sel" , 1), |
121 | GATE_INFRA1(CLK_INFRA_UART0_CK, "infra_uart0" , "infra_uart0_sel" , 2), |
122 | GATE_INFRA1(CLK_INFRA_UART1_CK, "infra_uart1" , "infra_uart1_sel" , 3), |
123 | GATE_INFRA1(CLK_INFRA_UART2_CK, "infra_uart2" , "infra_uart2_sel" , 4), |
124 | GATE_INFRA1(CLK_INFRA_NFI1_CK, "infra_nfi1" , "nfi1x_sel" , 8), |
125 | GATE_INFRA1(CLK_INFRA_SPINFI1_CK, "infra_spinfi1" , "spinfi_sel" , 9), |
126 | GATE_INFRA1(CLK_INFRA_NFI_HCK_CK, "infra_nfi_hck" , "infra_sysaxi_d2" , |
127 | 10), |
128 | GATE_INFRA1(CLK_INFRA_SPI0_CK, "infra_spi0" , "infra_spi0_sel" , 11), |
129 | GATE_INFRA1(CLK_INFRA_SPI1_CK, "infra_spi1" , "infra_spi1_sel" , 12), |
130 | GATE_INFRA1(CLK_INFRA_SPI0_HCK_CK, "infra_spi0_hck" , "infra_sysaxi_d2" , |
131 | 13), |
132 | GATE_INFRA1(CLK_INFRA_SPI1_HCK_CK, "infra_spi1_hck" , "infra_sysaxi_d2" , |
133 | 14), |
134 | GATE_INFRA1(CLK_INFRA_FRTC_CK, "infra_frtc" , "top_rtc_32k" , 15), |
135 | GATE_INFRA1(CLK_INFRA_MSDC_CK, "infra_msdc" , "emmc_416m_sel" , 16), |
136 | GATE_INFRA1(CLK_INFRA_MSDC_HCK_CK, "infra_msdc_hck" , "emmc_250m_sel" , |
137 | 17), |
138 | GATE_INFRA1(CLK_INFRA_MSDC_133M_CK, "infra_msdc_133m" , "sysaxi_sel" , |
139 | 18), |
140 | GATE_INFRA1(CLK_INFRA_MSDC_66M_CK, "infra_msdc_66m" , "infra_sysaxi_d2" , |
141 | 19), |
142 | GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m" , "infra_adc_frc" , 20), |
143 | GATE_INFRA1(CLK_INFRA_ADC_FRC_CK, "infra_adc_frc" , "csw_f26m_sel" , 21), |
144 | GATE_INFRA1(CLK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc" , "nfi1x_sel" , 23), |
145 | /* INFRA2 */ |
146 | GATE_INFRA2(CLK_INFRA_IUSB_133_CK, "infra_iusb_133" , "sysaxi_sel" , 0), |
147 | GATE_INFRA2(CLK_INFRA_IUSB_66M_CK, "infra_iusb_66m" , "infra_sysaxi_d2" , |
148 | 1), |
149 | GATE_INFRA2(CLK_INFRA_IUSB_SYS_CK, "infra_iusb_sys" , "u2u3_sys_sel" , 2), |
150 | GATE_INFRA2(CLK_INFRA_IUSB_CK, "infra_iusb" , "u2u3_sel" , 3), |
151 | GATE_INFRA2(CLK_INFRA_IPCIE_CK, "infra_ipcie" , "pextp_tl_ck_sel" , 12), |
152 | GATE_INFRA2(CLK_INFRA_IPCIE_PIPE_CK, "infra_ipcie_pipe" , "top_xtal" , |
153 | 13), |
154 | GATE_INFRA2(CLK_INFRA_IPCIER_CK, "infra_ipcier" , "csw_f26m_sel" , 14), |
155 | GATE_INFRA2(CLK_INFRA_IPCIEB_CK, "infra_ipcieb" , "sysaxi_sel" , 15), |
156 | }; |
157 | |
158 | static const struct mtk_clk_desc infra_desc = { |
159 | .clks = infra_clks, |
160 | .num_clks = ARRAY_SIZE(infra_clks), |
161 | .factor_clks = infra_divs, |
162 | .num_factor_clks = ARRAY_SIZE(infra_divs), |
163 | .mux_clks = infra_muxes, |
164 | .num_mux_clks = ARRAY_SIZE(infra_muxes), |
165 | .clk_lock = &mt7986_clk_lock, |
166 | }; |
167 | |
168 | static const struct of_device_id of_match_clk_mt7986_infracfg[] = { |
169 | { .compatible = "mediatek,mt7986-infracfg" , .data = &infra_desc }, |
170 | { /* sentinel */ } |
171 | }; |
172 | MODULE_DEVICE_TABLE(of, of_match_clk_mt7986_infracfg); |
173 | |
174 | static struct platform_driver clk_mt7986_infracfg_drv = { |
175 | .driver = { |
176 | .name = "clk-mt7986-infracfg" , |
177 | .of_match_table = of_match_clk_mt7986_infracfg, |
178 | }, |
179 | .probe = mtk_clk_simple_probe, |
180 | .remove_new = mtk_clk_simple_remove, |
181 | }; |
182 | module_platform_driver(clk_mt7986_infracfg_drv); |
183 | |
184 | MODULE_DESCRIPTION("MediaTek MT7986 infracfg clocks driver" ); |
185 | MODULE_LICENSE("GPL" ); |
186 | |