coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
pll.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 /*
4  * This file is created based on MT8186 Functional Specification
5  * Chapter number: 3.2
6  */
7 
8 #include <console/console.h>
9 #include <device/mmio.h>
10 #include <delay.h>
11 #include <stddef.h>
12 #include <timer.h>
13 
14 #include <soc/addressmap.h>
15 #include <soc/infracfg.h>
16 #include <soc/mcucfg.h>
17 #include <soc/pll.h>
18 
19 enum mux_id {
85 };
86 
87 #define MUX(_id, _reg, _mux_shift, _mux_width) \
88  [_id] = { \
89  .reg = &mtk_topckgen->_reg, \
90  .mux_shift = _mux_shift, \
91  .mux_width = _mux_width, \
92  }
93 
94 #define MUX_UPD(_id, _reg, _mux_shift, _mux_width, _upd_reg, _upd_shift)\
95  [_id] = { \
96  .reg = &mtk_topckgen->_reg, \
97  .set_reg = &mtk_topckgen->_reg##_set, \
98  .clr_reg = &mtk_topckgen->_reg##_clr, \
99  .mux_shift = _mux_shift, \
100  .mux_width = _mux_width, \
101  .upd_reg = &mtk_topckgen->_upd_reg, \
102  .upd_shift = _upd_shift, \
103  }
104 
105 static const struct mux muxes[] = {
106  /* CLK_CFG_0 */
107  MUX_UPD(TOP_AXI_SEL, clk_cfg_0, 0, 2, clk_cfg_update, 0),
108  MUX_UPD(TOP_SCP_SEL, clk_cfg_0, 8, 3, clk_cfg_update, 1),
109  MUX_UPD(TOP_MFG_SEL, clk_cfg_0, 16, 2, clk_cfg_update, 2),
110  MUX_UPD(TOP_CAMTG_SEL, clk_cfg_0, 24, 3, clk_cfg_update, 3),
111  /* CLK_CFG_1 */
112  MUX_UPD(TOP_CAMTG1_SEL, clk_cfg_1, 0, 3, clk_cfg_update, 4),
113  MUX_UPD(TOP_CAMTG2_SEL, clk_cfg_1, 8, 3, clk_cfg_update, 5),
114  MUX_UPD(TOP_CAMTG3_SEL, clk_cfg_1, 16, 3, clk_cfg_update, 6),
115  MUX_UPD(TOP_CAMTG4_SEL, clk_cfg_1, 24, 3, clk_cfg_update, 7),
116  /* CLK_CFG_2 */
117  MUX_UPD(TOP_CAMTG5_SEL, clk_cfg_2, 0, 3, clk_cfg_update, 8),
118  MUX_UPD(TOP_CAMTG6_SEL, clk_cfg_2, 8, 3, clk_cfg_update, 9),
119  MUX_UPD(TOP_UART_SEL, clk_cfg_2, 16, 1, clk_cfg_update, 10),
120  MUX_UPD(TOP_SPI_SEL, clk_cfg_2, 24, 3, clk_cfg_update, 11),
121  /* CLK_CFG_3 */
122  MUX_UPD(TOP_MSDC50_0_HCLK_SEL, clk_cfg_3, 0, 2, clk_cfg_update, 12),
123  MUX_UPD(TOP_MSDC50_0_SEL, clk_cfg_3, 8, 3, clk_cfg_update, 13),
124  MUX_UPD(TOP_MSDC30_1_SEL, clk_cfg_3, 16, 3, clk_cfg_update, 14),
125  MUX_UPD(TOP_AUDIO_SEL, clk_cfg_3, 24, 2, clk_cfg_update, 15),
126  /* CLK_CFG_4 */
127  MUX_UPD(TOP_AUD_INTBUS_SEL, clk_cfg_4, 0, 2, clk_cfg_update, 16),
128  MUX_UPD(TOP_AUD_1_SEL, clk_cfg_4, 8, 1, clk_cfg_update, 17),
129  MUX_UPD(TOP_AUD_2_SEL, clk_cfg_4, 16, 1, clk_cfg_update, 18),
130  MUX_UPD(TOP_AUD_ENGEN1_SEL, clk_cfg_4, 24, 2, clk_cfg_update, 19),
131  /* CLK_CFG_5 */
132  MUX_UPD(TOP_AUD_ENGEN2_SEL, clk_cfg_5, 0, 2, clk_cfg_update, 20),
133  MUX_UPD(TOP_DISP_PWM_SEL, clk_cfg_5, 8, 3, clk_cfg_update, 21),
134  MUX_UPD(TOP_SSPM_SEL, clk_cfg_5, 16, 3, clk_cfg_update, 22),
135  MUX_UPD(TOP_DXCC_SEL, clk_cfg_5, 24, 2, clk_cfg_update, 23),
136  /* CLK_CFG_6 */
137  MUX_UPD(TOP_USB_TOP_SEL, clk_cfg_6, 0, 2, clk_cfg_update, 24),
138  MUX_UPD(TOP_SRCK_SEL, clk_cfg_6, 8, 2, clk_cfg_update, 25),
139  MUX_UPD(TOP_SPM_SEL, clk_cfg_6, 16, 2, clk_cfg_update, 26),
140  MUX_UPD(TOP_I2C_SEL, clk_cfg_6, 24, 2, clk_cfg_update, 27),
141  /* CLK_CFG_7 */
142  MUX_UPD(TOP_PWM_SEL, clk_cfg_7, 0, 2, clk_cfg_update, 28),
143  MUX_UPD(TOP_SENINF_SEL, clk_cfg_7, 8, 2, clk_cfg_update, 29),
144  MUX_UPD(TOP_SENINF1_SEL, clk_cfg_7, 16, 2, clk_cfg_update, 30),
145  MUX_UPD(TOP_SENINF2_SEL, clk_cfg_7, 24, 2, clk_cfg_update1, 0),
146  /* CLK_CFG_8 */
147  MUX_UPD(TOP_SENINF3_SEL, clk_cfg_8, 0, 2, clk_cfg_update1, 1),
148  MUX_UPD(TOP_AES_MSDCFDE_SEL, clk_cfg_8, 8, 3, clk_cfg_update1, 2),
149  MUX_UPD(TOP_PWRAP_ULPOSC_SEL, clk_cfg_8, 16, 3, clk_cfg_update1, 3),
150  MUX_UPD(TOP_CAMTM_SEL, clk_cfg_8, 24, 2, clk_cfg_update1, 4),
151  /* CLK_CFG_9 */
152  MUX_UPD(TOP_VENC_SEL, clk_cfg_9, 0, 3, clk_cfg_update1, 5),
153  MUX_UPD(TOP_CAM_SEL, clk_cfg_9, 8, 4, clk_cfg_update1, 6),
154  MUX_UPD(TOP_IMG1_SEL, clk_cfg_9, 16, 4, clk_cfg_update1, 7),
155  MUX_UPD(TOP_IPE_SEL, clk_cfg_9, 24, 4, clk_cfg_update1, 8),
156  /* CLK_CFG_10 */
157  MUX_UPD(TOP_DPMAIF_SEL, clk_cfg_10, 0, 3, clk_cfg_update1, 9),
158  MUX_UPD(TOP_VDEC_SEL, clk_cfg_10, 8, 3, clk_cfg_update1, 10),
159  MUX_UPD(TOP_DISP_SEL, clk_cfg_10, 16, 4, clk_cfg_update1, 11),
160  MUX_UPD(TOP_MDP_SEL, clk_cfg_10, 24, 4, clk_cfg_update1, 12),
161  /* CLK_CFG_11 */
162  MUX_UPD(TOP_AUDIO_H_SEL, clk_cfg_11, 0, 2, clk_cfg_update1, 13),
163  MUX_UPD(TOP_UFS_SEL, clk_cfg_11, 8, 2, clk_cfg_update1, 14),
164  MUX_UPD(TOP_AES_FDE_SEL, clk_cfg_11, 16, 2, clk_cfg_update1, 15),
165  MUX_UPD(TOP_AUDIODSP_SEL, clk_cfg_11, 24, 3, clk_cfg_update1, 16),
166  /* CLK_CFG_12 */
167  MUX_UPD(TOP_DSI_OCC_SEL, clk_cfg_12, 8, 2, clk_cfg_update1, 18),
168  MUX_UPD(TOP_SPMI_MST_SEL, clk_cfg_12, 16, 3, clk_cfg_update1, 19),
169  /* CLK_CFG_13 */
170  MUX_UPD(TOP_SPINOR_SEL, clk_cfg_13, 0, 3, clk_cfg_update1, 20),
171  MUX_UPD(TOP_NNA_SEL, clk_cfg_13, 7, 4, clk_cfg_update1, 21),
172  MUX_UPD(TOP_NNA1_SEL, clk_cfg_13, 15, 4, clk_cfg_update1, 22),
173  MUX_UPD(TOP_NNA2_SEL, clk_cfg_13, 23, 4, clk_cfg_update1, 23),
174  /* CLK_CFG_14 */
175  MUX_UPD(TOP_SSUSB_XHCI_SEL, clk_cfg_14, 0, 2, clk_cfg_update1, 24),
176  MUX_UPD(TOP_SSUSB_TOP_1P_SEL, clk_cfg_14, 6, 2, clk_cfg_update1, 25),
177  MUX_UPD(TOP_SSUSB_XHCI_1P_SEL, clk_cfg_14, 12, 2, clk_cfg_update1, 26),
178  MUX_UPD(TOP_WPE_SEL, clk_cfg_14, 18, 4, clk_cfg_update1, 27),
179  /* CLK_CFG_15 */
180  MUX_UPD(TOP_DPI_SEL, clk_cfg_15, 0, 3, clk_cfg_update1, 28),
181  MUX_UPD(TOP_U3_OCC_250M_SEL, clk_cfg_15, 7, 1, clk_cfg_update1, 29),
182  MUX_UPD(TOP_U3_OCC_500M_SEL, clk_cfg_15, 12, 1, clk_cfg_update1, 30),
183  MUX_UPD(TOP_ADSP_BUS_SEL, clk_cfg_15, 17, 3, clk_cfg_update1, 31),
184 };
185 
186 struct mux_sel {
187  enum mux_id id;
188  u32 sel;
189 };
190 
191 static const struct mux_sel mux_sels[] = {
192  /* CLK_CFG_0 */
193  { .id = TOP_AXI_SEL, .sel = 1 }, /* 1: mainpll_d7 */
194  { .id = TOP_SCP_SEL, .sel = 3 }, /* 3: mainpll_d2_d2 */
195  { .id = TOP_MFG_SEL, .sel = 1 }, /* 1: mfgpll_ck */
196  { .id = TOP_CAMTG_SEL, .sel = 2 }, /* 2: univpll_d3_d8 */
197  /* CLK_CFG_1 */
198  { .id = TOP_CAMTG1_SEL, .sel = 2 }, /* 2: univpll_d3_d8 */
199  { .id = TOP_CAMTG2_SEL, .sel = 2 }, /* 2: univpll_d3_d8 */
200  { .id = TOP_CAMTG3_SEL, .sel = 2 }, /* 2: univpll_d3_d8 */
201  { .id = TOP_CAMTG4_SEL, .sel = 2 }, /* 2: univpll_d3_d8 */
202  /* CLK_CFG_2 */
203  { .id = TOP_CAMTG5_SEL, .sel = 2 }, /* 2: univpll_d3_d8 */
204  { .id = TOP_CAMTG6_SEL, .sel = 2 }, /* 2: univpll_d3_d8 */
205  { .id = TOP_UART_SEL, .sel = 0 }, /* 0: clk26m */
206  { .id = TOP_SPI_SEL, .sel = 7 }, /* 7: mainpll_d5 */
207  /* CLK_CFG_3 */
208  { .id = TOP_MSDC50_0_HCLK_SEL, .sel = 1 }, /* 1: mainpll_d2_d2 */
209  { .id = TOP_MSDC50_0_SEL, .sel = 1 }, /* 1: msdcpll_ck */
210  { .id = TOP_MSDC30_1_SEL, .sel = 1 }, /* 1: msdcpll_d2 */
211  { .id = TOP_AUDIO_SEL, .sel = 1 }, /* 1: mainpll_d5_d4 */
212  /* CLK_CFG_4 */
213  { .id = TOP_AUD_INTBUS_SEL, .sel = 1 }, /* 1: mainpll_d2_d4 */
214  { .id = TOP_AUD_1_SEL, .sel = 1 }, /* 1: apll1_ck */
215  { .id = TOP_AUD_2_SEL, .sel = 1 }, /* 1: apll2_ck */
216  { .id = TOP_AUD_ENGEN1_SEL, .sel = 3 }, /* 3: apll1_d8 */
217  /* CLK_CFG_5 */
218  { .id = TOP_AUD_ENGEN2_SEL, .sel = 3 }, /* 3: apll2_d8 */
219  { .id = TOP_DISP_PWM_SEL, .sel = 1 }, /* 1: univpll_d5_d2 */
220  { .id = TOP_SSPM_SEL, .sel = 1 }, /* 1: mainpll_d2_d2 */
221  { .id = TOP_DXCC_SEL, .sel = 1 }, /* 1: mainpll_d2_d2 */
222  /* CLK_CFG_6 */
223  { .id = TOP_USB_TOP_SEL, .sel = 2 }, /* 2: univpll_d5_d2 */
224  { .id = TOP_SRCK_SEL, .sel = 2 }, /* 2: ulposc1_d10 */
225  { .id = TOP_SPM_SEL, .sel = 3 }, /* 3: mainpll_d7_d2 */
226  { .id = TOP_I2C_SEL, .sel = 3 }, /* 3: univpll_d5_d2 */
227  /* CLK_CFG_7 */
228  { .id = TOP_PWM_SEL, .sel = 3 }, /* 3: univpll_d2_d4 */
229  { .id = TOP_SENINF_SEL, .sel = 3 }, /* 3: univpll_d3_d2 */
230  { .id = TOP_SENINF1_SEL, .sel = 3 }, /* 3: univpll_d3_d2 */
231  { .id = TOP_SENINF2_SEL, .sel = 3 }, /* 3: univpll_d3_d2 */
232  /* CLK_CFG_8 */
233  { .id = TOP_SENINF3_SEL, .sel = 3 }, /* 3: univpll_d3_d2 */
234  { .id = TOP_AES_MSDCFDE_SEL, .sel = 1 }, /* 1: univpll_d3 */
235  { .id = TOP_PWRAP_ULPOSC_SEL, .sel = 0 }, /* 0: clk26m */
236  { .id = TOP_CAMTM_SEL, .sel = 2 }, /* 2: univpll_d3_d2 */
237  /* CLK_CFG_9 */
238  { .id = TOP_VENC_SEL, .sel = 6 }, /* 6: mainpll_d3 */
239  { .id = TOP_CAM_SEL, .sel = 7 }, /* 7: univpll_d2_d2 */
240  { .id = TOP_IMG1_SEL, .sel = 7 }, /* 7: univpll_d2_d2 */
241  { .id = TOP_IPE_SEL, .sel = 7 }, /* 7: univpll_d2_d2 */
242  /* CLK_CFG_10 */
243  { .id = TOP_DPMAIF_SEL, .sel = 1 }, /* 1: univpll_d2_d2 */
244  { .id = TOP_VDEC_SEL, .sel = 6 }, /* 6: univpll_d2_d2 */
245  { .id = TOP_DISP_SEL, .sel = 8 }, /* 8: mmpll_ck */
246  { .id = TOP_MDP_SEL, .sel = 8 }, /* 8: mmpll_ck */
247  /* CLK_CFG_11 */
248  { .id = TOP_AUDIO_H_SEL, .sel = 3 }, /* 3: apll2_ck */
249  { .id = TOP_UFS_SEL, .sel = 1 }, /* 1: mainpll_d7 */
250  { .id = TOP_AES_FDE_SEL, .sel = 1 }, /* 1: univpll_d3 */
251  { .id = TOP_AUDIODSP_SEL, .sel = 0 }, /* 0: clk26m */
252  /* CLK_CFG_12 */
253  { .id = TOP_DSI_OCC_SEL, .sel = 1 }, /* 1: univpll_d3_d2 */
254  { .id = TOP_SPMI_MST_SEL, .sel = 2 }, /* 2: ulposc1_d4 */
255  /* CLK_CFG_13 */
256  { .id = TOP_SPINOR_SEL, .sel = 3 }, /* 3: univpll_d3_d8 */
257  { .id = TOP_NNA_SEL, .sel = 14 }, /* 14: nnapll_ck */
258  { .id = TOP_NNA1_SEL, .sel = 14 }, /* 14: nnapll_ck */
259  { .id = TOP_NNA2_SEL, .sel = 15 }, /* 15: nna2pll_ck */
260  /* CLK_CFG_14 */
261  { .id = TOP_SSUSB_XHCI_SEL, .sel = 2 }, /* 2: univpll_d5_d2 */
262  { .id = TOP_SSUSB_TOP_1P_SEL, .sel = 2 }, /* 2: univpll_d5_d2 */
263  { .id = TOP_SSUSB_XHCI_1P_SEL, .sel = 2 }, /* 2: univpll_d5_d2 */
264  { .id = TOP_WPE_SEL, .sel = 8 }, /* 8: mmpll_ck */
265  /* CLK_CFG_15 */
266  { .id = TOP_DPI_SEL, .sel = 1 }, /* 1: tvdpll_ck */
267  { .id = TOP_U3_OCC_250M_SEL, .sel = 1 }, /* 1: univpll_d5 */
268  { .id = TOP_U3_OCC_500M_SEL, .sel = 1 }, /* 1: nna2pll_d2 */
269  { .id = TOP_ADSP_BUS_SEL, .sel = 3 }, /* 3: mainpll_d2_d2 */
270 };
271 
272 enum pll_id {
288 };
289 
290 static const u32 pll_div_rate[] = {
291  3800UL * MHz,
292  1900 * MHz,
293  950 * MHz,
294  475 * MHz,
295  237500 * KHz,
296  0,
297 };
298 
299 static const struct pll plls[] = {
300  PLL(APMIXED_ARMPLL_LL, armpll_ll_con0, armpll_ll_con3,
301  NO_RSTB_SHIFT, 22, armpll_ll_con1, 24, armpll_ll_con1, 0,
302  pll_div_rate),
303  PLL(APMIXED_ARMPLL_BL, armpll_bl_con0, armpll_bl_con3,
304  NO_RSTB_SHIFT, 22, armpll_bl_con1, 24, armpll_bl_con1, 0,
305  pll_div_rate),
306  PLL(APMIXED_CCIPLL, ccipll_con0, ccipll_con3,
307  NO_RSTB_SHIFT, 22, ccipll_con1, 24, ccipll_con1, 0,
308  pll_div_rate),
309  PLL(APMIXED_MAINPLL, mainpll_con0, mainpll_con3,
310  23, 22, mainpll_con1, 24, mainpll_con1, 0,
311  pll_div_rate),
312  PLL(APMIXED_UNIV2PLL, univpll_con0, univpll_con3,
313  23, 22, univpll_con1, 24, univpll_con1, 0,
314  pll_div_rate),
315  PLL(APMIXED_MSDCPLL, msdcpll_con0, msdcpll_con3,
316  NO_RSTB_SHIFT, 22, msdcpll_con1, 24, msdcpll_con1, 0,
317  pll_div_rate),
318  PLL(APMIXED_MMPLL, mmpll_con0, mmpll_con3,
319  NO_RSTB_SHIFT, 22, mmpll_con1, 24, mmpll_con1, 0,
320  pll_div_rate),
321  PLL(APMIXED_NNAPLL, nnapll_con0, nnapll_con3,
322  NO_RSTB_SHIFT, 22, nnapll_con1, 24, nnapll_con1, 0,
323  pll_div_rate),
324  PLL(APMIXED_NNA2PLL, nna2pll_con0, nna2pll_con3,
325  NO_RSTB_SHIFT, 22, nna2pll_con1, 24, nna2pll_con1, 0,
326  pll_div_rate),
327  PLL(APMIXED_ADSPPLL, adsppll_con0, adsppll_con3,
328  NO_RSTB_SHIFT, 22, adsppll_con1, 24, adsppll_con1, 0,
329  pll_div_rate),
330  PLL(APMIXED_MFGPLL, mfgpll_con0, mfgpll_con3,
331  NO_RSTB_SHIFT, 22, mfgpll_con1, 24, mfgpll_con1, 0,
332  pll_div_rate),
333  PLL(APMIXED_TVDPLL, tvdpll_con0, tvdpll_con3,
334  NO_RSTB_SHIFT, 22, tvdpll_con1, 24, tvdpll_con1, 0,
335  pll_div_rate),
336  PLL(APMIXED_APLL1, apll1_con0, apll1_con4,
337  NO_RSTB_SHIFT, 32, apll1_con1, 24, apll1_con2, 0,
338  pll_div_rate),
339  PLL(APMIXED_APLL2, apll2_con0, apll2_con4,
340  NO_RSTB_SHIFT, 32, apll2_con1, 24, apll2_con2, 0,
341  pll_div_rate),
342 };
343 
344 struct rate {
345  enum pll_id id;
346  u32 rate;
347 };
348 
349 static const struct rate rates[] = {
350  { .id = APMIXED_ARMPLL_LL, .rate = ARMPLL_LL_HZ },
351  { .id = APMIXED_ARMPLL_BL, .rate = ARMPLL_BL_HZ },
352  { .id = APMIXED_CCIPLL, .rate = CCIPLL_HZ },
353  { .id = APMIXED_MAINPLL, .rate = MAINPLL_HZ },
354  { .id = APMIXED_UNIV2PLL, .rate = UNIV2PLL_HZ },
355  { .id = APMIXED_MSDCPLL, .rate = MSDCPLL_HZ },
356  { .id = APMIXED_MMPLL, .rate = MMPLL_HZ },
357  { .id = APMIXED_NNAPLL, .rate = NNAPLL_HZ },
358  { .id = APMIXED_NNA2PLL, .rate = NNA2PLL_HZ },
359  { .id = APMIXED_ADSPPLL, .rate = ADSPPLL_HZ },
360  { .id = APMIXED_MFGPLL, .rate = MFGPLL_HZ },
361  { .id = APMIXED_TVDPLL, .rate = TVDPLL_HZ },
362  { .id = APMIXED_APLL1, .rate = APLL1_HZ },
363  { .id = APMIXED_APLL2, .rate = APLL2_HZ },
364 };
365 
366 void pll_set_pcw_change(const struct pll *pll)
367 {
369 }
370 
371 void mt_pll_init(void)
372 {
373  int i;
374 
375  /* enable clock square */
376  setbits32(&mtk_apmixed->ap_pll_con0, BIT(0));
377 
379 
380  /* enable clock square1 low-pass filter */
381  setbits32(&mtk_apmixed->ap_pll_con0, BIT(1));
382 
383  /* xPLL PWR ON */
384  for (i = 0; i < APMIXED_PLL_MAX; i++)
385  setbits32(plls[i].pwr_reg, PLL_PWR_ON);
386 
388 
389  /* xPLL ISO Disable */
390  for (i = 0; i < APMIXED_PLL_MAX; i++)
391  clrbits32(plls[i].pwr_reg, PLL_ISO);
392 
394 
395  /* disable glitch free if rate < 374MHz */
396  for (i = 0; i < ARRAY_SIZE(rates); i++) {
397  if (rates[i].rate < 374 * MHz)
398  clrbits32(plls[rates[i].id].reg, GLITCH_FREE_EN);
399  }
400 
401  /* xPLL Frequency Set */
402  for (i = 0; i < ARRAY_SIZE(rates); i++)
403  pll_set_rate(&plls[rates[i].id], rates[i].rate);
404 
405  /* AUDPLL Tuner Frequency Set */
406  write32(&mtk_apmixed->apll1_tuner_con0, read32(&mtk_apmixed->apll1_con2) + 1);
407  write32(&mtk_apmixed->apll2_tuner_con0, read32(&mtk_apmixed->apll2_con2) + 1);
408 
409  /* xPLL Frequency Enable */
410  for (i = 0; i < APMIXED_PLL_MAX; i++)
411  setbits32(plls[i].reg, MT8186_PLL_EN);
412 
413  /* wait for PLL stable */
415 
416  /* xPLL DIV Enable & RSTB */
417  for (i = 0; i < APMIXED_PLL_MAX; i++) {
418  if (plls[i].rstb_shift != NO_RSTB_SHIFT) {
419  setbits32(plls[i].reg, PLL_DIV_EN);
420  setbits32(plls[i].reg, 1 << plls[i].rstb_shift);
421  }
422  }
423 
424  /* MCUCFG CLKMUX */
425  setbits32(&mtk_topckgen->clk_misc_cfg_0, ARMPLL_DIVIDER_PLL1_EN);
426  setbits32(&mtk_topckgen->clk_misc_cfg_0, ARMPLL_DIVIDER_PLL2_EN);
427 
431 
435 
438 
439  /* dcm_infracfg_ao_audio_bus and dcm_infracfg_ao_icusb_bus */
441  INFRACFG_AO_AUDIO_BUS_REG0, 0,
442  INFRACFG_AO_ICUSB_BUS_REG0, 0,
443  INFRACFG_AO_AUDIO_BUS_REG0, 1,
444  INFRACFG_AO_ICUSB_BUS_REG0, 1);
445 
446  /* dcm_infracfg_ao_infra_bus */
448  INFRACFG_AO_INFRA_BUS_REG0_0, 0,
449  INFRACFG_AO_INFRA_BUS_REG0_1, 0,
450  INFRACFG_AO_INFRA_BUS_REG0_2, 0,
451  INFRACFG_AO_INFRA_BUS_REG0_0, 0x603,
452  INFRACFG_AO_INFRA_BUS_REG0_1, 0xF,
453  INFRACFG_AO_INFRA_BUS_REG0_2, 1);
454 
455  /* dcm_infracfg_ao_p2p_rx_clk */
457  INFRACFG_AO_P2P_RX_CLK_REG0_MASK_0, 0,
458  INFRACFG_AO_P2P_RX_CLK_REG0_MASK_1, 0,
459  INFRACFG_AO_P2P_RX_CLK_REG0_MASK_1, 1);
460 
461  /* dcm_infracfg_ao_peri_bus */
463  INFRACFG_AO_PERI_BUS_REG0_0, 0,
464  INFRACFG_AO_PERI_BUS_REG0_1, 0,
465  INFRACFG_AO_PERI_BUS_REG0_2, 0,
466  INFRACFG_AO_PERI_BUS_REG0_0, 3,
467  INFRACFG_AO_PERI_BUS_REG0_1, 0xFF07C,
468  INFRACFG_AO_PERI_BUS_REG0_2, 1);
469 
470  for (i = 0; i < ARRAY_SIZE(mux_sels); i++)
471  mux_set_sel(&muxes[mux_sels[i].id], mux_sels[i].sel);
472 
473  /* [4] SCP_CORE_CK_CG, [5] SEJ_CG */
475  /* [7] DVFSRC_CG, [20] DEVICE_APC_CG */
477  /* [15] SEJ_F13M_CK_CG, [16] AES_TOP0_BCLK_CK_CG */
479 }
480 
482 {
483  /* switch clock source to intermediate clock */
485 
486  /* disable armpll_ll frequency output */
488 
489  /* raise armpll_ll frequency */
491 
492  /* enable armpll_ll frequency output */
495 
496  /* switch clock source back to armpll_ll */
498 }
499 
501 {
502  /* switch clock source to intermediate clock */
504 
505  /* disable ccipll frequency output */
507 
508  /* raise ccipll frequency */
510 
511  /* enable ccipll frequency output */
514 
515  /* switch clock source back to ccipll */
517 }
518 
520 {
521  u32 output, count, clk_dbg_cfg, clk_misc_cfg_0, clk26cali_0, clk26cali_1;
522 
523  /* backup */
524  clk_dbg_cfg = read32(&mtk_topckgen->clk_dbg_cfg);
525  clk_misc_cfg_0 = read32(&mtk_topckgen->clk_misc_cfg_0);
526  clk26cali_0 = read32(&mtk_topckgen->clk26cali_0);
527  clk26cali_1 = read32(&mtk_topckgen->clk26cali_1);
528 
529  /* set up frequency meter */
530  if (type == FMETER_ABIST) {
531  SET32_BITFIELDS(&mtk_topckgen->clk_dbg_cfg,
532  CLK_DBG_CFG_ABIST_CK_SEL, id,
533  CLK_DBG_CFG_CKGEN_CK_SEL, 0,
534  CLK_DBG_CFG_METER_CK_SEL, 0);
535  SET32_BITFIELDS(&mtk_topckgen->clk_misc_cfg_0,
536  CLK_MISC_CFG_0_METER_DIV, 1);
537  } else if (type == FMETER_CKGEN) {
538  SET32_BITFIELDS(&mtk_topckgen->clk_dbg_cfg,
539  CLK_DBG_CFG_ABIST_CK_SEL, 0,
540  CLK_DBG_CFG_CKGEN_CK_SEL, id,
541  CLK_DBG_CFG_METER_CK_SEL, 1);
542  SET32_BITFIELDS(&mtk_topckgen->clk_misc_cfg_0,
543  CLK_MISC_CFG_0_METER_DIV, 0);
544  } else {
545  die("unsupport fmeter type\n");
546  }
547 
548  /* enable frequency meter */
549  SET32_BITFIELDS(&mtk_topckgen->clk26cali_0, CLK26CALI_0_ENABLE, 1);
550 
551  /* trigger frequency meter */
552  SET32_BITFIELDS(&mtk_topckgen->clk26cali_0, CLK26CALI_0_TRIGGER, 1);
553 
554  /* wait frequency meter until finished */
555  if (wait_us(200, !READ32_BITFIELD(&mtk_topckgen->clk26cali_0, CLK26CALI_0_TRIGGER))) {
556  count = read32(&mtk_topckgen->clk26cali_1) & 0xffff;
557  output = (count * 26000) / 1024; /* KHz */
558  } else {
559  output = 0;
560  }
561 
562  /* restore */
563  write32(&mtk_topckgen->clk_dbg_cfg, clk_dbg_cfg);
564  write32(&mtk_topckgen->clk_misc_cfg_0, clk_misc_cfg_0);
565  write32(&mtk_topckgen->clk26cali_0, clk26cali_0);
566  write32(&mtk_topckgen->clk26cali_1, clk26cali_1);
567 
568  if (type == FMETER_ABIST)
569  return output * 2;
570  else if (type == FMETER_CKGEN)
571  return output;
572 
573  return 0;
574 }
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define MHz
Definition: helpers.h:80
#define KHz
Definition: helpers.h:79
void mux_set_sel(const struct mux *mux, u32 sel)
Definition: pll.c:8
int pll_set_rate(const struct pll *pll, u32 rate)
Definition: pll.c:72
void __noreturn die(const char *fmt,...)
Definition: die.c:17
#define BIT(nr)
Definition: ec_commands.h:45
#define setbits32(addr, set)
Definition: mmio.h:21
#define SET32_BITFIELDS(addr,...)
Definition: mmio.h:201
#define READ32_BITFIELD(addr, name)
Definition: mmio.h:207
#define clrsetbits32(addr, clear, set)
Definition: mmio.h:16
#define clrbits32(addr, clear)
Definition: mmio.h:26
#define wait_us(timeout_us, condition)
Definition: timer.h:198
unsigned int type
Definition: edid.c:57
@ MSDCPLL_HZ
Definition: pll.h:198
@ MAINPLL_HZ
Definition: pll.h:195
@ MMPLL_HZ
Definition: pll.h:197
@ APLL1_HZ
Definition: pll.h:205
@ APLL2_HZ
Definition: pll.h:206
@ TVDPLL_HZ
Definition: pll.h:200
@ PLL_ISO_DELAY
Definition: pll.h:183
@ PLL_EN_DELAY
Definition: pll.h:184
@ PLL_PWR_ON_DELAY
Definition: pll.h:182
void mt_pll_init(void)
Definition: pll.c:289
pll_id
Definition: pll.c:172
@ APMIXED_MMPLL
Definition: pll.c:177
@ APMIXED_APLL1
Definition: pll.c:183
@ APMIXED_APLL2
Definition: pll.c:184
@ APMIXED_MSDCPLL
Definition: pll.c:178
@ APMIXED_MAINPLL
Definition: pll.c:175
@ APMIXED_TVDPLL
Definition: pll.c:180
const u32 pll_div_rate[]
Definition: pll.c:190
void mt_pll_raise_little_cpu_freq(u32 freq)
Definition: pll.c:420
void pll_set_pcw_change(const struct pll *pll)
Definition: pll.c:284
mux_id
Definition: pll.c:11
@ TOP_VENC_SEL
Definition: pll.c:18
@ TOP_AUD_1_SEL
Definition: pll.c:39
@ TOP_MSDC50_0_SEL
Definition: pll.c:26
@ TOP_AUD_INTBUS_SEL
Definition: pll.c:31
@ TOP_UART_SEL
Definition: pll.c:21
@ TOP_MFG_SEL
Definition: pll.c:19
@ TOP_MSDC30_1_SEL
Definition: pll.c:27
@ TOP_SCP_SEL
Definition: pll.c:33
@ TOP_MEM_SEL
Definition: pll.c:13
@ TOP_AUDIO_SEL
Definition: pll.c:30
@ TOP_CAMTG_SEL
Definition: pll.c:20
@ TOP_SPI_SEL
Definition: pll.c:22
@ TOP_AUD_2_SEL
Definition: pll.c:40
@ TOP_PWM_SEL
Definition: pll.c:16
@ TOP_NR_MUX
Definition: pll.c:51
@ TOP_VDEC_SEL
Definition: pll.c:17
@ TOP_AXI_SEL
Definition: pll.c:12
@ CCIPLL_HZ
Definition: pll.h:237
@ MFGPLL_HZ
Definition: pll.h:242
@ ARMPLL_LL_HZ
Definition: pll.h:235
@ APMIXED_PLL_MAX
Definition: pll.c:198
@ APMIXED_ARMPLL_LL
Definition: pll.c:186
@ APMIXED_CCIPLL
Definition: pll.c:188
@ APMIXED_MFGPLL
Definition: pll.c:193
@ TOP_SENINF_SEL
Definition: pll.c:46
@ TOP_AUD_ENGEN2_SEL
Definition: pll.c:49
@ TOP_CAMTG2_SEL
Definition: pll.c:23
@ TOP_UFS_SEL
Definition: pll.c:51
@ TOP_I2C_SEL
Definition: pll.c:44
@ TOP_MSDC50_0_HCLK_SEL
Definition: pll.c:28
@ TOP_SSUSB_XHCI_SEL
Definition: pll.c:42
@ TOP_USB_TOP_SEL
Definition: pll.c:41
@ TOP_CAMTG4_SEL
Definition: pll.c:25
@ TOP_DISP_PWM_SEL
Definition: pll.c:40
@ TOP_CAMTG3_SEL
Definition: pll.c:24
@ TOP_AUD_ENGEN1_SEL
Definition: pll.c:48
@ TOP_SPM_SEL
Definition: pll.c:43
@ TOP_PWRAP_ULPOSC_SEL
Definition: pll.c:35
@ TOP_DXCC_SEL
Definition: pll.c:47
@ TOP_CAM_SEL
Definition: pll.c:15
static struct mt8186_infracfg_ao_regs *const mt8186_infracfg_ao
Definition: infracfg.h:544
static struct mt8186_mcucfg_regs *const mtk_mcucfg
Definition: mcucfg.h:945
@ ARMPLL_DIVIDER_PLL1_EN
Definition: pll.h:461
@ ARMPLL_DIVIDER_PLL2_EN
Definition: pll.h:462
@ NNAPLL_HZ
Definition: pll.h:483
@ ARMPLL_BL_HZ
Definition: pll.h:477
@ UNIV2PLL_HZ
Definition: pll.h:480
@ ADSPPLL_HZ
Definition: pll.h:485
@ NNA2PLL_HZ
Definition: pll.h:484
@ PLL_CKSQ_ON_DELAY
Definition: pll.h:444
@ GLITCH_FREE_EN
Definition: pll.h:456
@ MT8186_PLL_EN
Definition: pll.h:455
@ PLL_DIV_EN
Definition: pll.h:457
@ MCU_MUX_MASK
Definition: pll.h:469
@ MCU_DIV_MASK
Definition: pll.h:466
@ MCU_DIV_1
Definition: pll.h:467
@ MCU_MUX_SRC_PLL
Definition: pll.h:470
@ MCU_MUX_SRC_26M
Definition: pll.h:471
static const struct mux muxes[]
Definition: pll.c:105
@ APMIXED_NNAPLL
Definition: pll.c:280
@ APMIXED_ARMPLL_BL
Definition: pll.c:274
@ APMIXED_UNIV2PLL
Definition: pll.c:277
@ APMIXED_ADSPPLL
Definition: pll.c:282
@ APMIXED_NNA2PLL
Definition: pll.c:281
static const struct rate rates[]
Definition: pll.c:349
#define MUX_UPD(_id, _reg, _mux_shift, _mux_width, _upd_reg, _upd_shift)
Definition: pll.c:94
static const struct mux_sel mux_sels[]
Definition: pll.c:191
u32 mt_fmeter_get_freq_khz(enum fmeter_type type, u32 id)
Definition: pll.c:519
void mt_pll_raise_cci_freq(u32 freq)
Definition: pll.c:500
static const struct pll plls[]
Definition: pll.c:299
@ TOP_DVFSRC_SEL
Definition: pll.c:68
@ TOP_SENINF1_SEL
Definition: pll.c:50
@ TOP_SSPM_SEL
Definition: pll.c:42
@ TOP_CAMTM_SEL
Definition: pll.c:55
@ TOP_SENINF3_SEL
Definition: pll.c:52
@ TOP_WPE_SEL
Definition: pll.c:78
@ TOP_SPINOR_SEL
Definition: pll.c:71
@ TOP_DSI_OCC_SEL
Definition: pll.c:69
@ TOP_DISP_SEL
Definition: pll.c:62
@ TOP_IPE_SEL
Definition: pll.c:59
@ TOP_SRCK_SEL
Definition: pll.c:45
@ TOP_IMG1_SEL
Definition: pll.c:58
@ TOP_AES_MSDCFDE_SEL
Definition: pll.c:53
@ TOP_NNA2_SEL
Definition: pll.c:74
@ TOP_AES_FDE_SEL
Definition: pll.c:66
@ TOP_U3_OCC_500M_SEL
Definition: pll.c:82
@ TOP_DPI_SEL
Definition: pll.c:80
@ TOP_CAMTG6_SEL
Definition: pll.c:29
@ TOP_SPMI_MST_SEL
Definition: pll.c:70
@ TOP_MDP_SEL
Definition: pll.c:63
@ TOP_DPMAIF_SEL
Definition: pll.c:60
@ TOP_SSUSB_TOP_1P_SEL
Definition: pll.c:76
@ TOP_SENINF2_SEL
Definition: pll.c:51
@ TOP_NNA_SEL
Definition: pll.c:72
@ TOP_CAMTG1_SEL
Definition: pll.c:24
@ TOP_NNA1_SEL
Definition: pll.c:73
@ TOP_U3_OCC_250M_SEL
Definition: pll.c:81
@ TOP_AUDIODSP_SEL
Definition: pll.c:67
@ TOP_ADSP_BUS_SEL
Definition: pll.c:83
@ TOP_SSUSB_XHCI_1P_SEL
Definition: pll.c:77
@ TOP_CAMTG5_SEL
Definition: pll.c:28
@ TOP_AUDIO_H_SEL
Definition: pll.c:64
#define PLL_PCW_CHG
Definition: pll_common.h:19
#define NO_RSTB_SHIFT
Definition: pll_common.h:18
#define PLL_PWR_ON
Definition: pll_common.h:14
#define mtk_topckgen
Definition: pll_common.h:11
#define PLL(_id, _reg, _pwr_reg, _rstb, _pcwbits, _div_reg, _div_shift, _pcw_reg, _pcw_shift, _div_rate)
Definition: pll_common.h:44
#define PLL_ISO
Definition: pll_common.h:16
#define mtk_apmixed
Definition: pll_common.h:12
fmeter_type
Definition: pll_common.h:76
@ FMETER_CKGEN
Definition: pll_common.h:78
@ FMETER_ABIST
Definition: pll_common.h:77
uint32_t u32
Definition: stdint.h:51
Definition: dw_i2c.c:39
Definition: pll.c:115
u32 sel
Definition: pll.c:117
enum mux_id id
Definition: pll.c:116
Definition: pll_common.h:22
Definition: pll_common.h:32
void * div_reg
Definition: pll_common.h:35
Definition: pll.c:262
u32 rate
Definition: pll.c:264
enum pll_id id
Definition: pll.c:263
void udelay(uint32_t us)
Definition: udelay.c:15
#define count