1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
6 #include <soc/addressmap.h>
7 #include <soc/infracfg.h>
54 #define MUX(_id, _reg, _mux_shift, _mux_width) \
56 .reg = &mtk_topckgen->_reg, \
57 .mux_shift = _mux_shift, \
58 .mux_width = _mux_width, \
63 static const struct mux muxes
[] = {
65 MUX(TOP_AXI_SEL
, clk_cfg_0
, 0, 3),
66 MUX(TOP_MEM_SEL
, clk_cfg_0
, 8, 1),
67 MUX(TOP_DDRPHYCFG_SEL
, clk_cfg_0
, 16, 1),
68 MUX(TOP_MM_SEL
, clk_cfg_0
, 24, 4),
70 MUX(TOP_PWM_SEL
, clk_cfg_1
, 0, 2),
71 MUX(TOP_VDEC_SEL
, clk_cfg_1
, 8, 4),
72 MUX(TOP_VENC_SEL
, clk_cfg_1
, 16, 4),
73 MUX(TOP_MFG_SEL
, clk_cfg_1
, 24, 4),
75 MUX(TOP_CAMTG_SEL
, clk_cfg_2
, 0, 3),
76 MUX(TOP_UART_SEL
, clk_cfg_2
, 8, 1),
77 MUX(TOP_SPI_SEL
, clk_cfg_2
, 16, 3),
78 MUX(TOP_USB20_SEL
, clk_cfg_2
, 24, 2),
80 MUX(TOP_USB30_SEL
, clk_cfg_3
, 0, 2),
81 MUX(TOP_MSDC50_0_H_SEL
, clk_cfg_3
, 8, 3),
82 MUX(TOP_MSDC50_0_SEL
, clk_cfg_3
, 16, 4),
83 MUX(TOP_MSDC30_1_SEL
, clk_cfg_3
, 24, 3),
85 MUX(TOP_MSDC30_2_SEL
, clk_cfg_4
, 0, 3),
86 MUX(TOP_MSDC30_3_SEL
, clk_cfg_4
, 8, 4),
87 MUX(TOP_AUDIO_SEL
, clk_cfg_4
, 16, 2),
88 MUX(TOP_AUD_INTBUS_SEL
, clk_cfg_4
, 24, 3),
90 MUX(TOP_PMICSPI_SEL
, clk_cfg_5
, 0, 3),
91 MUX(TOP_SCP_SEL
, clk_cfg_5
, 8, 3),
92 MUX(TOP_ATB_SEL
, clk_cfg_5
, 16, 2),
93 MUX(TOP_VENC_LT_SEL
, clk_cfg_5
, 24, 4),
95 MUX(TOP_DPI0_SEL
, clk_cfg_6
, 0, 3),
96 MUX(TOP_IRDA_SEL
, clk_cfg_6
, 8, 2),
97 MUX(TOP_CCI400_SEL
, clk_cfg_6
, 16, 3),
98 MUX(TOP_AUD_1_SEL
, clk_cfg_6
, 24, 2),
100 MUX(TOP_AUD_2_SEL
, clk_cfg_7
, 0, 2),
101 MUX(TOP_MEM_MFG_IN_SEL
, clk_cfg_7
, 8, 2),
102 MUX(TOP_AXI_MFG_IN_SEL
, clk_cfg_7
, 16, 2),
103 MUX(TOP_SCAM_SEL
, clk_cfg_7
, 24, 2),
105 MUX(TOP_SPINFI_IFR_SEL
, clk_cfg_12
, 0, 3),
106 MUX(TOP_HDMI_SEL
, clk_cfg_12
, 8, 2),
107 MUX(TOP_DPILVDS_SEL
, clk_cfg_12
, 24, 3),
109 MUX(TOP_MSDC50_2_H_SEL
, clk_cfg_13
, 0, 3),
110 MUX(TOP_HDCP_SEL
, clk_cfg_13
, 8, 2),
111 MUX(TOP_HDCP_24M_SEL
, clk_cfg_13
, 16, 2),
112 MUX(TOP_RTC_SEL
, clk_cfg_13
, 24, 2),
120 static const struct mux_sel mux_sels
[] = {
122 { .id
= TOP_AXI_SEL
, .sel
= 5 }, /* 5: univpll2_d2 */
123 { .id
= TOP_MEM_SEL
, .sel
= 0 }, /* 0: clk26m */
124 { .id
= TOP_DDRPHYCFG_SEL
, .sel
= 0 }, /* 0: clk26m */
125 { .id
= TOP_MM_SEL
, .sel
= 1 }, /* 1: vencpll_d2 */
127 { .id
= TOP_PWM_SEL
, .sel
= 0 }, /* 0: clk26m */
128 { .id
= TOP_VDEC_SEL
, .sel
= 1 }, /* 1: vcodecpll_ck */
129 { .id
= TOP_VENC_SEL
, .sel
= 1 }, /* 1: vcodecpll_ck */
130 { .id
= TOP_MFG_SEL
, .sel
= 1 }, /* 1: mmpll_ck */
132 { .id
= TOP_CAMTG_SEL
, .sel
= 0 }, /* 0: clk26m */
133 { .id
= TOP_UART_SEL
, .sel
= 0 }, /* 0: clk26m */
134 { .id
= TOP_SPI_SEL
, .sel
= 1 }, /* 1: syspll3_d2 */
135 { .id
= TOP_USB20_SEL
, .sel
= 1 }, /* 1: univpll1_d8 */
137 { .id
= TOP_MSDC30_2_SEL
, .sel
= 2 }, /* 2: msdcpll_d4 */
138 { .id
= TOP_MSDC30_3_SEL
, .sel
= 5 }, /* 5: msdcpll_d4 */
139 { .id
= TOP_AUDIO_SEL
, .sel
= 0 }, /* 0: clk26m */
140 { .id
= TOP_AUD_INTBUS_SEL
, .sel
= 1 }, /* 1: syspll1_d4 */
142 { .id
= TOP_PMICSPI_SEL
, .sel
= 0 }, /* 0: clk26m */
143 { .id
= TOP_SCP_SEL
, .sel
= 1 }, /* 1: syspll1_d2 */
144 { .id
= TOP_ATB_SEL
, .sel
= 0 }, /* 0: clk26m */
145 { .id
= TOP_VENC_LT_SEL
, .sel
= 6 }, /* 6: univpll1_d2 */
147 { .id
= TOP_DPI0_SEL
, .sel
= 1 }, /* 1: tvdpll_d2 */
148 { .id
= TOP_IRDA_SEL
, .sel
= 1 }, /* 1: univpll2_d4 */
149 { .id
= TOP_CCI400_SEL
, .sel
= 5 }, /* 5: syspll_d2 */
150 { .id
= TOP_AUD_1_SEL
, .sel
= 1 }, /* 1: apll1_ck */
152 { .id
= TOP_AUD_2_SEL
, .sel
= 1 }, /* 1: apll2_ck */
153 { .id
= TOP_MEM_MFG_IN_SEL
, .sel
= 1 }, /* 1: mmpll_ck */
154 { .id
= TOP_AXI_MFG_IN_SEL
, .sel
= 1 }, /* 1: hd_faxi_ck */
155 { .id
= TOP_SCAM_SEL
, .sel
= 1 }, /* 1: syspll3_d2 */
157 { .id
= TOP_SPINFI_IFR_SEL
, .sel
= 0 }, /* 0: clk26m */
158 { .id
= TOP_HDMI_SEL
, .sel
= 1 }, /* 1: AD_HDMITX_CLK */
159 { .id
= TOP_DPILVDS_SEL
, .sel
= 1 }, /* 1: AD_LVDSPLL_CK */
161 { .id
= TOP_MSDC50_2_H_SEL
, .sel
= 2 }, /* 2: syspll2_d2 */
162 { .id
= TOP_HDCP_SEL
, .sel
= 2 }, /* 2: syspll3_d4 */
163 { .id
= TOP_HDCP_24M_SEL
, .sel
= 2 }, /* 2: univpll_d52 */
164 { .id
= TOP_RTC_SEL
, .sel
= 1 }, /* 1: clkrtc_ext */
166 { .id
= TOP_USB30_SEL
, .sel
= 1 }, /* 1: univpll3_d2 */
167 { .id
= TOP_MSDC50_0_H_SEL
, .sel
= 2 }, /* 2: syspll2_d2 */
168 { .id
= TOP_MSDC50_0_SEL
, .sel
= 6 }, /* 6: msdcpll_d4 */
169 { .id
= TOP_MSDC30_1_SEL
, .sel
= 2 }, /* 2: msdcpll_d4 */
190 const u32 pll_div_rate
[] = {
199 const u32 univpll_div_rate
[] = {
208 const u32 mmpll_div_rate
[] = {
217 static const struct pll plls
[] = {
218 PLL(APMIXED_ARMCA15PLL
, armca15pll_con0
, armca15pll_pwr_con0
,
219 NO_RSTB_SHIFT
, 21, armca15pll_con1
, 24, armca15pll_con1
, 0,
221 PLL(APMIXED_ARMCA7PLL
, armca7pll_con0
, armca7pll_pwr_con0
,
222 PLL_RSTB_SHIFT
, 21, armca7pll_con1
, 24, armca7pll_con1
, 0,
224 PLL(APMIXED_MAINPLL
, mainpll_con0
, mainpll_pwr_con0
,
225 PLL_RSTB_SHIFT
, 21, mainpll_con0
, 4, mainpll_con1
, 0,
227 PLL(APMIXED_UNIVPLL
, univpll_con0
, univpll_pwr_con0
,
228 PLL_RSTB_SHIFT
, 7, univpll_con0
, 4, univpll_con1
, 14,
230 PLL(APMIXED_MMPLL
, mmpll_con0
, mmpll_pwr_con0
,
231 NO_RSTB_SHIFT
, 21, mmpll_con1
, 24, mmpll_con1
, 0,
233 PLL(APMIXED_MSDCPLL
, msdcpll_con0
, msdcpll_pwr_con0
,
234 NO_RSTB_SHIFT
, 21, msdcpll_con0
, 4, msdcpll_con1
, 0,
236 PLL(APMIXED_VENCPLL
, vencpll_con0
, vencpll_pwr_con0
,
237 NO_RSTB_SHIFT
, 21, vencpll_con0
, 4, vencpll_con1
, 0,
239 PLL(APMIXED_TVDPLL
, tvdpll_con0
, tvdpll_pwr_con0
,
240 NO_RSTB_SHIFT
, 21, tvdpll_con0
, 4, tvdpll_con1
, 0,
242 PLL(APMIXED_MPLL
, mpll_con0
, mpll_pwr_con0
,
243 NO_RSTB_SHIFT
, 21, mpll_con0
, 4, mpll_con1
, 0,
245 PLL(APMIXED_VCODECPLL
, vcodecpll_con0
, vcodecpll_pwr_con0
,
246 NO_RSTB_SHIFT
, 21, vcodecpll_con0
, 4, vcodecpll_con1
, 0,
248 PLL(APMIXED_APLL1
, apll1_con0
, apll1_pwr_con0
,
249 NO_RSTB_SHIFT
, 31, apll1_con0
, 4, apll1_con1
, 0,
251 PLL(APMIXED_APLL2
, apll2_con0
, apll2_pwr_con0
,
252 NO_RSTB_SHIFT
, 31, apll2_con0
, 4, apll2_con1
, 0,
254 PLL(APMIXED_LVDSPLL
, lvdspll_con0
, lvdspll_pwr_con0
,
255 NO_RSTB_SHIFT
, 21, lvdspll_con0
, 4, lvdspll_con1
, 0,
257 PLL(APMIXED_MSDCPLL2
, msdcpll2_con0
, msdcpll2_pwr_con0
,
258 NO_RSTB_SHIFT
, 21, msdcpll2_con0
, 4, msdcpll2_con1
, 0,
267 static const struct rate rates
[] = {
268 { .id
= APMIXED_ARMCA15PLL
, .rate
= ARMCA15PLL_HZ
},
269 { .id
= APMIXED_ARMCA7PLL
, .rate
= ARMCA7PLL_HZ
},
270 { .id
= APMIXED_MAINPLL
, .rate
= MAINPLL_HZ
},
271 { .id
= APMIXED_UNIVPLL
, .rate
= UNIVPLL_HZ
},
272 { .id
= APMIXED_MMPLL
, .rate
= MMPLL_HZ
},
273 { .id
= APMIXED_MSDCPLL
, .rate
= MSDCPLL_HZ
},
274 { .id
= APMIXED_VENCPLL
, .rate
= VENCPLL_HZ
},
275 { .id
= APMIXED_TVDPLL
, .rate
= TVDPLL_HZ
},
276 { .id
= APMIXED_MPLL
, .rate
= MPLL_HZ
},
277 { .id
= APMIXED_VCODECPLL
, .rate
= VCODECPLL_HZ
},
278 { .id
= APMIXED_LVDSPLL
, .rate
= LVDSPLL_HZ
},
279 { .id
= APMIXED_MSDCPLL2
, .rate
= MSDCPLL2_HZ
},
280 { .id
= APMIXED_APLL1
, .rate
= APLL1_HZ
},
281 { .id
= APMIXED_APLL2
, .rate
= APLL2_HZ
},
284 void pll_set_pcw_change(const struct pll
*pll
)
286 setbits32(pll
->pcw_reg
, PLL_PCW_CHG
);
289 void mt_pll_init(void)
293 /* reduce CLKSQ disable time */
294 write32(&mtk_apmixed
->clksq_stb_con0
, (0x05 << 8) | (0x01 << 0));
295 /* extend PWR/ISO control timing to 1us */
296 write32(&mtk_apmixed
->pll_iso_con0
, (0x8 << 16) | (0x8 << 0));
297 write32(&mtk_apmixed
->ap_pll_con6
, 0x00000000);
302 for (i
= 0; i
< APMIXED_NR_PLL
; i
++)
303 setbits32(plls
[i
].pwr_reg
, PLL_PWR_ON
);
305 /* wait for xPLL_PWR_ON ready (min delay is 1us) */
306 udelay(PLL_PWR_ON_DELAY
);
311 for (i
= 0; i
< APMIXED_NR_PLL
; i
++)
312 clrbits32(plls
[i
].pwr_reg
, PLL_ISO
);
314 /********************
316 *********************/
317 for (i
= 0; i
< ARRAY_SIZE(rates
); i
++)
318 pll_set_rate(&plls
[rates
[i
].id
], rates
[i
].rate
);
320 /***********************
321 * xPLL Frequency Enable
322 ************************/
323 for (i
= 0; i
< APMIXED_NR_PLL
; i
++)
324 setbits32(plls
[i
].reg
, PLL_EN
);
326 udelay(PLL_EN_DELAY
); /* wait for PLL stable (min delay is 20us) */
331 for (i
= 0; i
< APMIXED_NR_PLL
; i
++) {
332 if (plls
[i
].rstb_shift
!= NO_RSTB_SHIFT
)
333 setbits32(plls
[i
].reg
, 1 << plls
[i
].rstb_shift
);
340 /* enable infrasys DCM */
341 setbits32(&mt8173_infracfg
->top_dcmctl
, 0x1);
343 write32(&mtk_topckgen
->clk_mode
, 0x1);
344 write32(&mtk_topckgen
->clk_mode
, 0x0); /* enable TOPCKGEN */
347 * TOP CLKMUX -- DO NOT CHANGE WITHOUT ADJUSTING <soc/pll.h> CONSTANTS!
349 for (i
= 0; i
< ARRAY_SIZE(mux_sels
); i
++)
350 pll_mux_set_sel(&muxes
[mux_sels
[i
].id
], mux_sels
[i
].sel
);
352 /* enable scpsys clock off control */
353 write32(&mtk_topckgen
->clk_scp_cfg_0
,
354 (1 << 10) | (1 << 9) | (1 << 5) | (1 << 4) | (1 << 2) |
355 (1 << 1) | (1 << 0));
356 write32(&mtk_topckgen
->clk_scp_cfg_1
,
357 (1 << 4) | (1 << 2) | (1 << 0));
360 /* Turn on ADA_SSUSB_XTAL_CK 26MHz */
361 void mt_pll_enable_ssusb_clk(void)
363 /* set RG_LTECLKSQ_EN */
364 setbits32(&mtk_apmixed
->ap_pll_con0
, 0x1);
365 udelay(100); /* wait for PLL stable */
367 /* set RG_LTECLKSQ_LPF_EN & DA_REF2USB_TX_EN */
368 setbits32(&mtk_apmixed
->ap_pll_con0
, 0x1 << 1);
369 setbits32(&mtk_apmixed
->ap_pll_con2
, 0x1);
370 udelay(100); /* wait for PLL stable */
372 /* set DA_REF2USB_TX_LPF_EN & DA_REF2USB_TX_OUT_EN */
373 setbits32(&mtk_apmixed
->ap_pll_con2
, (0x1 << 2) | (0x1 << 1));
376 /* after pmic_init */
377 void mt_pll_post_init(void)
379 /* CPU clock divide by 1 */
380 clrbits32(&mt8173_infracfg
->top_ckdiv1
, 0x3ff);
383 write32(&mt8173_infracfg
->top_ckmuxsel
, (1 << 2) | 1);
386 void mt_pll_set_aud_div(u32 rate
)
389 u32 apll_clock
= APLL2_CK_HZ
;
392 if (rate
% 11025 == 0) {
393 /* use APLL1 instead */
395 apll_clock
= APLL1_CK_HZ
;
398 mclk_div
= (apll_clock
/ 256 / rate
) - 1;
399 assert(apll_clock
== rate
* 256 * (mclk_div
+ 1));
403 clrbits32(&mtk_topckgen
->clk_auddiv_0
, 1 << 5);
404 clrsetbits32(&mtk_topckgen
->clk_auddiv_1
, 0xff << 8,
407 clrsetbits32(&mtk_topckgen
->clk_auddiv_0
, 0xf << 24,
411 setbits32(&mtk_topckgen
->clk_auddiv_0
, 1 << 5);
412 clrsetbits32(&mtk_topckgen
->clk_auddiv_2
, 0xff << 8,
415 clrsetbits32(&mtk_topckgen
->clk_auddiv_0
, 0xf << 28,
420 void mt_pll_raise_little_cpu_freq(u32 freq
)
422 pll_set_rate(&plls
[APMIXED_ARMCA7PLL
], freq
); /* freq in Hz */
425 void mt_mem_pll_config_pre(const struct mt8173_sdram_params
*sdram_params
)
427 u32 mpll_sdm_pcw_20_0
= 0xF13B1;
429 /* disable MPLL for adjusting memory clk frequency */
430 clrbits32(&mtk_apmixed
->mpll_con0
, BIT(0));
431 /* MPLL configuration: mode selection */
432 setbits32(&mtk_apmixed
->mpll_con0
, BIT(16));
433 clrbits32(&mtk_apmixed
->mpll_con0
, 0x7 << 4);
434 clrbits32(&mtk_apmixed
->pll_test_con0
, 1 << 31);
435 /* set RG_MPLL_SDM_PCW for feedback divide ratio */
436 clrsetbits32(&mtk_apmixed
->mpll_con1
, 0x1fffff, mpll_sdm_pcw_20_0
);
439 void mt_mem_pll_config_post(void)
441 /* power up sequence starts: enable MPLL */
442 setbits32(&mtk_apmixed
->mpll_con0
, BIT(0));
445 void mt_mem_pll_mux(void)
448 pll_mux_set_sel(&muxes
[TOP_MEM_SEL
], 1); /* 1: dmpll_ck */