| 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* |
| 3 | * Copyright (c) 2017 MediaTek Inc. |
| 4 | * Author: Chen Zhong <chen.zhong@mediatek.com> |
| 5 | * Sean Wang <sean.wang@mediatek.com> |
| 6 | */ |
| 7 | |
| 8 | #include <linux/clk-provider.h> |
| 9 | #include <linux/mod_devicetable.h> |
| 10 | #include <linux/platform_device.h> |
| 11 | |
| 12 | #include "clk-cpumux.h" |
| 13 | #include "clk-gate.h" |
| 14 | #include "clk-mtk.h" |
| 15 | |
| 16 | #include <dt-bindings/clock/mt7622-clk.h> |
| 17 | #include <linux/clk.h> /* for consumer */ |
| 18 | |
| 19 | #define GATE_TOP0(_id, _name, _parent, _shift) \ |
| 20 | GATE_MTK(_id, _name, _parent, &top0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) |
| 21 | |
| 22 | #define GATE_TOP1(_id, _name, _parent, _shift) \ |
| 23 | GATE_MTK(_id, _name, _parent, &top1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) |
| 24 | |
| 25 | #define GATE_PERI0(_id, _name, _parent, _shift) \ |
| 26 | GATE_MTK(_id, _name, _parent, &peri0_cg_regs, _shift, &mtk_clk_gate_ops_setclr) |
| 27 | |
| 28 | #define GATE_PERI0_AO(_id, _name, _parent, _shift) \ |
| 29 | GATE_MTK_FLAGS(_id, _name, _parent, &peri0_cg_regs, _shift, \ |
| 30 | &mtk_clk_gate_ops_setclr, CLK_IS_CRITICAL) |
| 31 | |
| 32 | #define GATE_PERI1(_id, _name, _parent, _shift) \ |
| 33 | GATE_MTK(_id, _name, _parent, &peri1_cg_regs, _shift, &mtk_clk_gate_ops_setclr) |
| 34 | |
| 35 | static DEFINE_SPINLOCK(mt7622_clk_lock); |
| 36 | |
| 37 | static const char * const axi_parents[] = { |
| 38 | "clkxtal" , |
| 39 | "syspll1_d2" , |
| 40 | "syspll_d5" , |
| 41 | "syspll1_d4" , |
| 42 | "univpll_d5" , |
| 43 | "univpll2_d2" , |
| 44 | "univpll_d7" |
| 45 | }; |
| 46 | |
| 47 | static const char * const mem_parents[] = { |
| 48 | "clkxtal" , |
| 49 | "dmpll_ck" |
| 50 | }; |
| 51 | |
| 52 | static const char * const ddrphycfg_parents[] = { |
| 53 | "clkxtal" , |
| 54 | "syspll1_d8" |
| 55 | }; |
| 56 | |
| 57 | static const char * const eth_parents[] = { |
| 58 | "clkxtal" , |
| 59 | "syspll1_d2" , |
| 60 | "univpll1_d2" , |
| 61 | "syspll1_d4" , |
| 62 | "univpll_d5" , |
| 63 | "clk_null" , |
| 64 | "univpll_d7" |
| 65 | }; |
| 66 | |
| 67 | static const char * const pwm_parents[] = { |
| 68 | "clkxtal" , |
| 69 | "univpll2_d4" |
| 70 | }; |
| 71 | |
| 72 | static const char * const f10m_ref_parents[] = { |
| 73 | "clkxtal" , |
| 74 | "syspll4_d16" |
| 75 | }; |
| 76 | |
| 77 | static const char * const nfi_infra_parents[] = { |
| 78 | "clkxtal" , |
| 79 | "clkxtal" , |
| 80 | "clkxtal" , |
| 81 | "clkxtal" , |
| 82 | "clkxtal" , |
| 83 | "clkxtal" , |
| 84 | "clkxtal" , |
| 85 | "clkxtal" , |
| 86 | "univpll2_d8" , |
| 87 | "syspll1_d8" , |
| 88 | "univpll1_d8" , |
| 89 | "syspll4_d2" , |
| 90 | "univpll2_d4" , |
| 91 | "univpll3_d2" , |
| 92 | "syspll1_d4" |
| 93 | }; |
| 94 | |
| 95 | static const char * const flash_parents[] = { |
| 96 | "clkxtal" , |
| 97 | "univpll_d80_d4" , |
| 98 | "syspll2_d8" , |
| 99 | "syspll3_d4" , |
| 100 | "univpll3_d4" , |
| 101 | "univpll1_d8" , |
| 102 | "syspll2_d4" , |
| 103 | "univpll2_d4" |
| 104 | }; |
| 105 | |
| 106 | static const char * const uart_parents[] = { |
| 107 | "clkxtal" , |
| 108 | "univpll2_d8" |
| 109 | }; |
| 110 | |
| 111 | static const char * const spi0_parents[] = { |
| 112 | "clkxtal" , |
| 113 | "syspll3_d2" , |
| 114 | "clkxtal" , |
| 115 | "syspll2_d4" , |
| 116 | "syspll4_d2" , |
| 117 | "univpll2_d4" , |
| 118 | "univpll1_d8" , |
| 119 | "clkxtal" |
| 120 | }; |
| 121 | |
| 122 | static const char * const spi1_parents[] = { |
| 123 | "clkxtal" , |
| 124 | "syspll3_d2" , |
| 125 | "clkxtal" , |
| 126 | "syspll4_d4" , |
| 127 | "syspll4_d2" , |
| 128 | "univpll2_d4" , |
| 129 | "univpll1_d8" , |
| 130 | "clkxtal" |
| 131 | }; |
| 132 | |
| 133 | static const char * const msdc30_0_parents[] = { |
| 134 | "clkxtal" , |
| 135 | "univpll2_d16" , |
| 136 | "univ48m" |
| 137 | }; |
| 138 | |
| 139 | static const char * const a1sys_hp_parents[] = { |
| 140 | "clkxtal" , |
| 141 | "aud1pll_ck" , |
| 142 | "aud2pll_ck" , |
| 143 | "clkxtal" |
| 144 | }; |
| 145 | |
| 146 | static const char * const intdir_parents[] = { |
| 147 | "clkxtal" , |
| 148 | "syspll_d2" , |
| 149 | "univpll_d2" , |
| 150 | "sgmiipll_ck" |
| 151 | }; |
| 152 | |
| 153 | static const char * const aud_intbus_parents[] = { |
| 154 | "clkxtal" , |
| 155 | "syspll1_d4" , |
| 156 | "syspll4_d2" , |
| 157 | "syspll3_d2" |
| 158 | }; |
| 159 | |
| 160 | static const char * const pmicspi_parents[] = { |
| 161 | "clkxtal" , |
| 162 | "clk_null" , |
| 163 | "clk_null" , |
| 164 | "clk_null" , |
| 165 | "clk_null" , |
| 166 | "univpll2_d16" |
| 167 | }; |
| 168 | |
| 169 | static const char * const atb_parents[] = { |
| 170 | "clkxtal" , |
| 171 | "syspll1_d2" , |
| 172 | "syspll_d5" |
| 173 | }; |
| 174 | |
| 175 | static const char * const audio_parents[] = { |
| 176 | "clkxtal" , |
| 177 | "syspll3_d4" , |
| 178 | "syspll4_d4" , |
| 179 | "univpll1_d16" |
| 180 | }; |
| 181 | |
| 182 | static const char * const usb20_parents[] = { |
| 183 | "clkxtal" , |
| 184 | "univpll3_d4" , |
| 185 | "syspll1_d8" , |
| 186 | "clkxtal" |
| 187 | }; |
| 188 | |
| 189 | static const char * const aud1_parents[] = { |
| 190 | "clkxtal" , |
| 191 | "aud1pll_ck" |
| 192 | }; |
| 193 | |
| 194 | static const char * const aud2_parents[] = { |
| 195 | "clkxtal" , |
| 196 | "aud2pll_ck" |
| 197 | }; |
| 198 | |
| 199 | static const char * const asm_l_parents[] = { |
| 200 | "clkxtal" , |
| 201 | "syspll_d5" , |
| 202 | "univpll2_d2" , |
| 203 | "univpll2_d4" |
| 204 | }; |
| 205 | |
| 206 | static const char * const apll1_ck_parents[] = { |
| 207 | "aud1_sel" , |
| 208 | "aud2_sel" |
| 209 | }; |
| 210 | |
| 211 | static const char * const peribus_ck_parents[] = { |
| 212 | "syspll1_d8" , |
| 213 | "syspll1_d4" |
| 214 | }; |
| 215 | |
| 216 | static const struct mtk_gate_regs top0_cg_regs = { |
| 217 | .set_ofs = 0x120, |
| 218 | .clr_ofs = 0x120, |
| 219 | .sta_ofs = 0x120, |
| 220 | }; |
| 221 | |
| 222 | static const struct mtk_gate_regs top1_cg_regs = { |
| 223 | .set_ofs = 0x128, |
| 224 | .clr_ofs = 0x128, |
| 225 | .sta_ofs = 0x128, |
| 226 | }; |
| 227 | |
| 228 | static const struct mtk_gate_regs peri0_cg_regs = { |
| 229 | .set_ofs = 0x8, |
| 230 | .clr_ofs = 0x10, |
| 231 | .sta_ofs = 0x18, |
| 232 | }; |
| 233 | |
| 234 | static const struct mtk_gate_regs peri1_cg_regs = { |
| 235 | .set_ofs = 0xC, |
| 236 | .clr_ofs = 0x14, |
| 237 | .sta_ofs = 0x1C, |
| 238 | }; |
| 239 | |
| 240 | static const struct mtk_fixed_clk top_fixed_clks[] = { |
| 241 | FIXED_CLK(CLK_TOP_TO_U2_PHY, "to_u2_phy" , "clkxtal" , |
| 242 | 31250000), |
| 243 | FIXED_CLK(CLK_TOP_TO_U2_PHY_1P, "to_u2_phy_1p" , "clkxtal" , |
| 244 | 31250000), |
| 245 | FIXED_CLK(CLK_TOP_PCIE0_PIPE_EN, "pcie0_pipe_en" , "clkxtal" , |
| 246 | 125000000), |
| 247 | FIXED_CLK(CLK_TOP_PCIE1_PIPE_EN, "pcie1_pipe_en" , "clkxtal" , |
| 248 | 125000000), |
| 249 | FIXED_CLK(CLK_TOP_SSUSB_TX250M, "ssusb_tx250m" , "clkxtal" , |
| 250 | 250000000), |
| 251 | FIXED_CLK(CLK_TOP_SSUSB_EQ_RX250M, "ssusb_eq_rx250m" , "clkxtal" , |
| 252 | 250000000), |
| 253 | FIXED_CLK(CLK_TOP_SSUSB_CDR_REF, "ssusb_cdr_ref" , "clkxtal" , |
| 254 | 33333333), |
| 255 | FIXED_CLK(CLK_TOP_SSUSB_CDR_FB, "ssusb_cdr_fb" , "clkxtal" , |
| 256 | 50000000), |
| 257 | FIXED_CLK(CLK_TOP_SATA_ASIC, "sata_asic" , "clkxtal" , |
| 258 | 50000000), |
| 259 | FIXED_CLK(CLK_TOP_SATA_RBC, "sata_rbc" , "clkxtal" , |
| 260 | 50000000), |
| 261 | }; |
| 262 | |
| 263 | static const struct mtk_fixed_factor top_divs[] = { |
| 264 | FACTOR(CLK_TOP_TO_USB3_SYS, "to_usb3_sys" , "eth1pll" , 1, 4), |
| 265 | FACTOR(CLK_TOP_P1_1MHZ, "p1_1mhz" , "eth1pll" , 1, 500), |
| 266 | FACTOR(CLK_TOP_4MHZ, "free_run_4mhz" , "eth1pll" , 1, 125), |
| 267 | FACTOR(CLK_TOP_P0_1MHZ, "p0_1mhz" , "eth1pll" , 1, 500), |
| 268 | FACTOR(CLK_TOP_TXCLK_SRC_PRE, "txclk_src_pre" , "sgmiipll_d2" , 1, 1), |
| 269 | FACTOR(CLK_TOP_RTC, "rtc" , "clkxtal" , 1, 1024), |
| 270 | FACTOR(CLK_TOP_MEMPLL, "mempll" , "clkxtal" , 32, 1), |
| 271 | FACTOR(CLK_TOP_DMPLL, "dmpll_ck" , "mempll" , 1, 1), |
| 272 | FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2" , "mainpll" , 1, 2), |
| 273 | FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2" , "mainpll" , 1, 4), |
| 274 | FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4" , "mainpll" , 1, 8), |
| 275 | FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8" , "mainpll" , 1, 16), |
| 276 | FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4" , "mainpll" , 1, 12), |
| 277 | FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8" , "mainpll" , 1, 24), |
| 278 | FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5" , "mainpll" , 1, 5), |
| 279 | FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2" , "mainpll" , 1, 10), |
| 280 | FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4" , "mainpll" , 1, 20), |
| 281 | FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2" , "mainpll" , 1, 14), |
| 282 | FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4" , "mainpll" , 1, 28), |
| 283 | FACTOR(CLK_TOP_SYSPLL4_D16, "syspll4_d16" , "mainpll" , 1, 112), |
| 284 | FACTOR(CLK_TOP_UNIVPLL, "univpll" , "univ2pll" , 1, 2), |
| 285 | FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2" , "univpll" , 1, 2), |
| 286 | FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2" , "univpll" , 1, 4), |
| 287 | FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4" , "univpll" , 1, 8), |
| 288 | FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8" , "univpll" , 1, 16), |
| 289 | FACTOR(CLK_TOP_UNIVPLL1_D16, "univpll1_d16" , "univpll" , 1, 32), |
| 290 | FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2" , "univpll" , 1, 6), |
| 291 | FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4" , "univpll" , 1, 12), |
| 292 | FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8" , "univpll" , 1, 24), |
| 293 | FACTOR(CLK_TOP_UNIVPLL2_D16, "univpll2_d16" , "univpll" , 1, 48), |
| 294 | FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5" , "univpll" , 1, 5), |
| 295 | FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2" , "univpll" , 1, 10), |
| 296 | FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4" , "univpll" , 1, 20), |
| 297 | FACTOR(CLK_TOP_UNIVPLL3_D16, "univpll3_d16" , "univpll" , 1, 80), |
| 298 | FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7" , "univpll" , 1, 7), |
| 299 | FACTOR(CLK_TOP_UNIVPLL_D80_D4, "univpll_d80_d4" , "univpll" , 1, 320), |
| 300 | FACTOR(CLK_TOP_UNIV48M, "univ48m" , "univpll" , 1, 25), |
| 301 | FACTOR(CLK_TOP_SGMIIPLL, "sgmiipll_ck" , "sgmipll" , 1, 1), |
| 302 | FACTOR(CLK_TOP_SGMIIPLL_D2, "sgmiipll_d2" , "sgmipll" , 1, 2), |
| 303 | FACTOR(CLK_TOP_AUD1PLL, "aud1pll_ck" , "aud1pll" , 1, 1), |
| 304 | FACTOR(CLK_TOP_AUD2PLL, "aud2pll_ck" , "aud2pll" , 1, 1), |
| 305 | FACTOR(CLK_TOP_AUD_I2S2_MCK, "aud_i2s2_mck" , "i2s2_mck_sel" , 1, 2), |
| 306 | FACTOR(CLK_TOP_TO_USB3_REF, "to_usb3_ref" , "univpll2_d4" , 1, 4), |
| 307 | FACTOR(CLK_TOP_PCIE1_MAC_EN, "pcie1_mac_en" , "univpll1_d4" , 1, 1), |
| 308 | FACTOR(CLK_TOP_PCIE0_MAC_EN, "pcie0_mac_en" , "univpll1_d4" , 1, 1), |
| 309 | FACTOR(CLK_TOP_ETH_500M, "eth_500m" , "eth1pll" , 1, 1), |
| 310 | }; |
| 311 | |
| 312 | static const struct mtk_gate top_clks[] = { |
| 313 | /* TOP0 */ |
| 314 | GATE_TOP0(CLK_TOP_APLL1_DIV_PD, "apll1_ck_div_pd" , "apll1_ck_div" , 0), |
| 315 | GATE_TOP0(CLK_TOP_APLL2_DIV_PD, "apll2_ck_div_pd" , "apll2_ck_div" , 1), |
| 316 | GATE_TOP0(CLK_TOP_I2S0_MCK_DIV_PD, "i2s0_mck_div_pd" , "i2s0_mck_div" , |
| 317 | 2), |
| 318 | GATE_TOP0(CLK_TOP_I2S1_MCK_DIV_PD, "i2s1_mck_div_pd" , "i2s1_mck_div" , |
| 319 | 3), |
| 320 | GATE_TOP0(CLK_TOP_I2S2_MCK_DIV_PD, "i2s2_mck_div_pd" , "i2s2_mck_div" , |
| 321 | 4), |
| 322 | GATE_TOP0(CLK_TOP_I2S3_MCK_DIV_PD, "i2s3_mck_div_pd" , "i2s3_mck_div" , |
| 323 | 5), |
| 324 | |
| 325 | /* TOP1 */ |
| 326 | GATE_TOP1(CLK_TOP_A1SYS_HP_DIV_PD, "a1sys_div_pd" , "a1sys_div" , 0), |
| 327 | GATE_TOP1(CLK_TOP_A2SYS_HP_DIV_PD, "a2sys_div_pd" , "a2sys_div" , 16), |
| 328 | }; |
| 329 | |
| 330 | static const struct mtk_clk_divider top_adj_divs[] = { |
| 331 | DIV_ADJ(CLK_TOP_APLL1_DIV, "apll1_ck_div" , "apll1_ck_sel" , |
| 332 | 0x120, 24, 3), |
| 333 | DIV_ADJ(CLK_TOP_APLL2_DIV, "apll2_ck_div" , "apll2_ck_sel" , |
| 334 | 0x120, 28, 3), |
| 335 | DIV_ADJ(CLK_TOP_I2S0_MCK_DIV, "i2s0_mck_div" , "i2s0_mck_sel" , |
| 336 | 0x124, 0, 7), |
| 337 | DIV_ADJ(CLK_TOP_I2S1_MCK_DIV, "i2s1_mck_div" , "i2s1_mck_sel" , |
| 338 | 0x124, 8, 7), |
| 339 | DIV_ADJ(CLK_TOP_I2S2_MCK_DIV, "i2s2_mck_div" , "aud_i2s2_mck" , |
| 340 | 0x124, 16, 7), |
| 341 | DIV_ADJ(CLK_TOP_I2S3_MCK_DIV, "i2s3_mck_div" , "i2s3_mck_sel" , |
| 342 | 0x124, 24, 7), |
| 343 | DIV_ADJ(CLK_TOP_A1SYS_HP_DIV, "a1sys_div" , "a1sys_hp_sel" , |
| 344 | 0x128, 8, 7), |
| 345 | DIV_ADJ(CLK_TOP_A2SYS_HP_DIV, "a2sys_div" , "a2sys_hp_sel" , |
| 346 | 0x128, 24, 7), |
| 347 | }; |
| 348 | |
| 349 | static const struct mtk_gate peri_clks[] = { |
| 350 | /* PERI0 */ |
| 351 | GATE_PERI0(CLK_PERI_THERM_PD, "peri_therm_pd" , "axi_sel" , 1), |
| 352 | GATE_PERI0(CLK_PERI_PWM1_PD, "peri_pwm1_pd" , "clkxtal" , 2), |
| 353 | GATE_PERI0(CLK_PERI_PWM2_PD, "peri_pwm2_pd" , "clkxtal" , 3), |
| 354 | GATE_PERI0(CLK_PERI_PWM3_PD, "peri_pwm3_pd" , "clkxtal" , 4), |
| 355 | GATE_PERI0(CLK_PERI_PWM4_PD, "peri_pwm4_pd" , "clkxtal" , 5), |
| 356 | GATE_PERI0(CLK_PERI_PWM5_PD, "peri_pwm5_pd" , "clkxtal" , 6), |
| 357 | GATE_PERI0(CLK_PERI_PWM6_PD, "peri_pwm6_pd" , "clkxtal" , 7), |
| 358 | GATE_PERI0(CLK_PERI_PWM7_PD, "peri_pwm7_pd" , "clkxtal" , 8), |
| 359 | GATE_PERI0(CLK_PERI_PWM_PD, "peri_pwm_pd" , "clkxtal" , 9), |
| 360 | GATE_PERI0(CLK_PERI_AP_DMA_PD, "peri_ap_dma_pd" , "axi_sel" , 12), |
| 361 | GATE_PERI0(CLK_PERI_MSDC30_0_PD, "peri_msdc30_0" , "msdc30_0_sel" , 13), |
| 362 | GATE_PERI0(CLK_PERI_MSDC30_1_PD, "peri_msdc30_1" , "msdc30_1_sel" , 14), |
| 363 | GATE_PERI0_AO(CLK_PERI_UART0_PD, "peri_uart0_pd" , "axi_sel" , 17), |
| 364 | GATE_PERI0(CLK_PERI_UART1_PD, "peri_uart1_pd" , "axi_sel" , 18), |
| 365 | GATE_PERI0(CLK_PERI_UART2_PD, "peri_uart2_pd" , "axi_sel" , 19), |
| 366 | GATE_PERI0(CLK_PERI_UART3_PD, "peri_uart3_pd" , "axi_sel" , 20), |
| 367 | GATE_PERI0(CLK_PERI_UART4_PD, "peri_uart4_pd" , "axi_sel" , 21), |
| 368 | GATE_PERI0(CLK_PERI_BTIF_PD, "peri_btif_pd" , "axi_sel" , 22), |
| 369 | GATE_PERI0(CLK_PERI_I2C0_PD, "peri_i2c0_pd" , "axi_sel" , 23), |
| 370 | GATE_PERI0(CLK_PERI_I2C1_PD, "peri_i2c1_pd" , "axi_sel" , 24), |
| 371 | GATE_PERI0(CLK_PERI_I2C2_PD, "peri_i2c2_pd" , "axi_sel" , 25), |
| 372 | GATE_PERI0(CLK_PERI_SPI1_PD, "peri_spi1_pd" , "spi1_sel" , 26), |
| 373 | GATE_PERI0(CLK_PERI_AUXADC_PD, "peri_auxadc_pd" , "clkxtal" , 27), |
| 374 | GATE_PERI0(CLK_PERI_SPI0_PD, "peri_spi0_pd" , "spi0_sel" , 28), |
| 375 | GATE_PERI0(CLK_PERI_SNFI_PD, "peri_snfi_pd" , "nfi_infra_sel" , 29), |
| 376 | GATE_PERI0(CLK_PERI_NFI_PD, "peri_nfi_pd" , "axi_sel" , 30), |
| 377 | GATE_PERI0(CLK_PERI_NFIECC_PD, "peri_nfiecc_pd" , "axi_sel" , 31), |
| 378 | |
| 379 | /* PERI1 */ |
| 380 | GATE_PERI1(CLK_PERI_FLASH_PD, "peri_flash_pd" , "flash_sel" , 1), |
| 381 | GATE_PERI1(CLK_PERI_IRTX_PD, "peri_irtx_pd" , "irtx_sel" , 2), |
| 382 | }; |
| 383 | |
| 384 | static struct mtk_composite top_muxes[] = { |
| 385 | /* CLK_CFG_0 */ |
| 386 | MUX_GATE_FLAGS(CLK_TOP_AXI_SEL, "axi_sel" , axi_parents, |
| 387 | 0x040, 0, 3, 7, CLK_IS_CRITICAL), |
| 388 | MUX_GATE_FLAGS(CLK_TOP_MEM_SEL, "mem_sel" , mem_parents, |
| 389 | 0x040, 8, 1, 15, CLK_IS_CRITICAL), |
| 390 | MUX_GATE_FLAGS(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel" , ddrphycfg_parents, |
| 391 | 0x040, 16, 1, 23, CLK_IS_CRITICAL), |
| 392 | MUX_GATE(CLK_TOP_ETH_SEL, "eth_sel" , eth_parents, |
| 393 | 0x040, 24, 3, 31), |
| 394 | |
| 395 | /* CLK_CFG_1 */ |
| 396 | MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel" , pwm_parents, |
| 397 | 0x050, 0, 2, 7), |
| 398 | MUX_GATE(CLK_TOP_F10M_REF_SEL, "f10m_ref_sel" , f10m_ref_parents, |
| 399 | 0x050, 8, 1, 15), |
| 400 | MUX_GATE(CLK_TOP_NFI_INFRA_SEL, "nfi_infra_sel" , nfi_infra_parents, |
| 401 | 0x050, 16, 4, 23), |
| 402 | MUX_GATE(CLK_TOP_FLASH_SEL, "flash_sel" , flash_parents, |
| 403 | 0x050, 24, 3, 31), |
| 404 | |
| 405 | /* CLK_CFG_2 */ |
| 406 | MUX_GATE(CLK_TOP_UART_SEL, "uart_sel" , uart_parents, |
| 407 | 0x060, 0, 1, 7), |
| 408 | MUX_GATE(CLK_TOP_SPI0_SEL, "spi0_sel" , spi0_parents, |
| 409 | 0x060, 8, 3, 15), |
| 410 | MUX_GATE(CLK_TOP_SPI1_SEL, "spi1_sel" , spi1_parents, |
| 411 | 0x060, 16, 3, 23), |
| 412 | MUX_GATE(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel" , uart_parents, |
| 413 | 0x060, 24, 3, 31), |
| 414 | |
| 415 | /* CLK_CFG_3 */ |
| 416 | MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel" , msdc30_0_parents, |
| 417 | 0x070, 0, 3, 7), |
| 418 | MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel" , msdc30_0_parents, |
| 419 | 0x070, 8, 3, 15), |
| 420 | MUX_GATE(CLK_TOP_A1SYS_HP_SEL, "a1sys_hp_sel" , a1sys_hp_parents, |
| 421 | 0x070, 16, 2, 23), |
| 422 | MUX_GATE(CLK_TOP_A2SYS_HP_SEL, "a2sys_hp_sel" , a1sys_hp_parents, |
| 423 | 0x070, 24, 2, 31), |
| 424 | |
| 425 | /* CLK_CFG_4 */ |
| 426 | MUX_GATE(CLK_TOP_INTDIR_SEL, "intdir_sel" , intdir_parents, |
| 427 | 0x080, 0, 2, 7), |
| 428 | MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel" , aud_intbus_parents, |
| 429 | 0x080, 8, 2, 15), |
| 430 | MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel" , pmicspi_parents, |
| 431 | 0x080, 16, 3, 23), |
| 432 | MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel" , ddrphycfg_parents, |
| 433 | 0x080, 24, 2, 31), |
| 434 | |
| 435 | /* CLK_CFG_5 */ |
| 436 | MUX_GATE(CLK_TOP_ATB_SEL, "atb_sel" , atb_parents, |
| 437 | 0x090, 0, 2, 7), |
| 438 | MUX_GATE(CLK_TOP_HIF_SEL, "hif_sel" , eth_parents, |
| 439 | 0x090, 8, 3, 15), |
| 440 | MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel" , audio_parents, |
| 441 | 0x090, 16, 2, 23), |
| 442 | MUX_GATE(CLK_TOP_U2_SEL, "usb20_sel" , usb20_parents, |
| 443 | 0x090, 24, 2, 31), |
| 444 | |
| 445 | /* CLK_CFG_6 */ |
| 446 | MUX_GATE(CLK_TOP_AUD1_SEL, "aud1_sel" , aud1_parents, |
| 447 | 0x0A0, 0, 1, 7), |
| 448 | MUX_GATE(CLK_TOP_AUD2_SEL, "aud2_sel" , aud2_parents, |
| 449 | 0x0A0, 8, 1, 15), |
| 450 | MUX_GATE(CLK_TOP_IRRX_SEL, "irrx_sel" , f10m_ref_parents, |
| 451 | 0x0A0, 16, 1, 23), |
| 452 | MUX_GATE(CLK_TOP_IRTX_SEL, "irtx_sel" , f10m_ref_parents, |
| 453 | 0x0A0, 24, 1, 31), |
| 454 | |
| 455 | /* CLK_CFG_7 */ |
| 456 | MUX_GATE(CLK_TOP_ASM_L_SEL, "asm_l_sel" , asm_l_parents, |
| 457 | 0x0B0, 0, 2, 7), |
| 458 | MUX_GATE(CLK_TOP_ASM_M_SEL, "asm_m_sel" , asm_l_parents, |
| 459 | 0x0B0, 8, 2, 15), |
| 460 | MUX_GATE(CLK_TOP_ASM_H_SEL, "asm_h_sel" , asm_l_parents, |
| 461 | 0x0B0, 16, 2, 23), |
| 462 | |
| 463 | /* CLK_AUDDIV_0 */ |
| 464 | MUX(CLK_TOP_APLL1_SEL, "apll1_ck_sel" , apll1_ck_parents, |
| 465 | 0x120, 6, 1), |
| 466 | MUX(CLK_TOP_APLL2_SEL, "apll2_ck_sel" , apll1_ck_parents, |
| 467 | 0x120, 7, 1), |
| 468 | MUX(CLK_TOP_I2S0_MCK_SEL, "i2s0_mck_sel" , apll1_ck_parents, |
| 469 | 0x120, 8, 1), |
| 470 | MUX(CLK_TOP_I2S1_MCK_SEL, "i2s1_mck_sel" , apll1_ck_parents, |
| 471 | 0x120, 9, 1), |
| 472 | MUX(CLK_TOP_I2S2_MCK_SEL, "i2s2_mck_sel" , apll1_ck_parents, |
| 473 | 0x120, 10, 1), |
| 474 | MUX(CLK_TOP_I2S3_MCK_SEL, "i2s3_mck_sel" , apll1_ck_parents, |
| 475 | 0x120, 11, 1), |
| 476 | }; |
| 477 | |
| 478 | static struct mtk_composite peri_muxes[] = { |
| 479 | /* PERI_GLOBALCON_CKSEL */ |
| 480 | MUX(CLK_PERIBUS_SEL, "peribus_ck_sel" , peribus_ck_parents, 0x05C, 0, 1), |
| 481 | }; |
| 482 | |
| 483 | static u16 pericfg_rst_ofs[] = { 0x0, 0x4, }; |
| 484 | |
| 485 | static const struct mtk_clk_rst_desc clk_rst_desc = { |
| 486 | .version = MTK_RST_SIMPLE, |
| 487 | .rst_bank_ofs = pericfg_rst_ofs, |
| 488 | .rst_bank_nr = ARRAY_SIZE(pericfg_rst_ofs), |
| 489 | }; |
| 490 | |
| 491 | static const struct mtk_clk_desc topck_desc = { |
| 492 | .clks = top_clks, |
| 493 | .num_clks = ARRAY_SIZE(top_clks), |
| 494 | .fixed_clks = top_fixed_clks, |
| 495 | .num_fixed_clks = ARRAY_SIZE(top_fixed_clks), |
| 496 | .factor_clks = top_divs, |
| 497 | .num_factor_clks = ARRAY_SIZE(top_divs), |
| 498 | .composite_clks = top_muxes, |
| 499 | .num_composite_clks = ARRAY_SIZE(top_muxes), |
| 500 | .divider_clks = top_adj_divs, |
| 501 | .num_divider_clks = ARRAY_SIZE(top_adj_divs), |
| 502 | .clk_lock = &mt7622_clk_lock, |
| 503 | }; |
| 504 | |
| 505 | static const struct mtk_clk_desc peri_desc = { |
| 506 | .clks = peri_clks, |
| 507 | .num_clks = ARRAY_SIZE(peri_clks), |
| 508 | .composite_clks = peri_muxes, |
| 509 | .num_composite_clks = ARRAY_SIZE(peri_muxes), |
| 510 | .rst_desc = &clk_rst_desc, |
| 511 | .clk_lock = &mt7622_clk_lock, |
| 512 | }; |
| 513 | |
| 514 | static const struct of_device_id of_match_clk_mt7622[] = { |
| 515 | { .compatible = "mediatek,mt7622-topckgen" , .data = &topck_desc }, |
| 516 | { .compatible = "mediatek,mt7622-pericfg" , .data = &peri_desc }, |
| 517 | { /* sentinel */ } |
| 518 | }; |
| 519 | MODULE_DEVICE_TABLE(of, of_match_clk_mt7622); |
| 520 | |
| 521 | static struct platform_driver clk_mt7622_drv = { |
| 522 | .driver = { |
| 523 | .name = "clk-mt7622" , |
| 524 | .of_match_table = of_match_clk_mt7622, |
| 525 | }, |
| 526 | .probe = mtk_clk_simple_probe, |
| 527 | .remove = mtk_clk_simple_remove, |
| 528 | }; |
| 529 | module_platform_driver(clk_mt7622_drv) |
| 530 | |
| 531 | MODULE_DESCRIPTION("MediaTek MT7622 clocks driver" ); |
| 532 | MODULE_LICENSE("GPL" ); |
| 533 | |