Angel Pons | e67ab18 | 2020-04-04 18:51:11 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 2 | |
Kyösti Mälkki | 13f6650 | 2019-03-03 08:01:05 +0200 | [diff] [blame] | 3 | #include <device/mmio.h> |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 4 | #include <assert.h> |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 5 | #include <delay.h> |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 6 | #include <soc/addressmap.h> |
| 7 | #include <soc/infracfg.h> |
| 8 | #include <soc/pll.h> |
Elyes HAOUAS | 27d02d8 | 2019-05-15 21:11:39 +0200 | [diff] [blame] | 9 | #include <types.h> |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 10 | |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 11 | enum mux_id { |
| 12 | TOP_AXI_SEL, |
| 13 | TOP_MEM_SEL, |
| 14 | TOP_DDRPHYCFG_SEL, |
| 15 | TOP_MM_SEL, |
| 16 | TOP_PWM_SEL, |
| 17 | TOP_VDEC_SEL, |
| 18 | TOP_VENC_SEL, |
| 19 | TOP_MFG_SEL, |
| 20 | TOP_CAMTG_SEL, |
| 21 | TOP_UART_SEL, |
| 22 | TOP_SPI_SEL, |
| 23 | TOP_USB20_SEL, |
| 24 | TOP_USB30_SEL, |
| 25 | TOP_MSDC50_0_H_SEL, |
| 26 | TOP_MSDC50_0_SEL, |
| 27 | TOP_MSDC30_1_SEL, |
| 28 | TOP_MSDC30_2_SEL, |
| 29 | TOP_MSDC30_3_SEL, |
| 30 | TOP_AUDIO_SEL, |
| 31 | TOP_AUD_INTBUS_SEL, |
| 32 | TOP_PMICSPI_SEL, |
| 33 | TOP_SCP_SEL, |
| 34 | TOP_ATB_SEL, |
| 35 | TOP_VENC_LT_SEL, |
| 36 | TOP_DPI0_SEL, |
| 37 | TOP_IRDA_SEL, |
| 38 | TOP_CCI400_SEL, |
| 39 | TOP_AUD_1_SEL, |
| 40 | TOP_AUD_2_SEL, |
| 41 | TOP_MEM_MFG_IN_SEL, |
| 42 | TOP_AXI_MFG_IN_SEL, |
| 43 | TOP_SCAM_SEL, |
| 44 | TOP_SPINFI_IFR_SEL, |
| 45 | TOP_HDMI_SEL, |
| 46 | TOP_DPILVDS_SEL, |
| 47 | TOP_MSDC50_2_H_SEL, |
| 48 | TOP_HDCP_SEL, |
| 49 | TOP_HDCP_24M_SEL, |
| 50 | TOP_RTC_SEL, |
| 51 | TOP_NR_MUX |
| 52 | }; |
| 53 | |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 54 | #define MUX(_id, _reg, _mux_shift, _mux_width) \ |
| 55 | [_id] = { \ |
Tristan Shieh | 17180af | 2018-07-02 17:20:13 +0800 | [diff] [blame] | 56 | .reg = &mtk_topckgen->_reg, \ |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 57 | .mux_shift = _mux_shift, \ |
| 58 | .mux_width = _mux_width, \ |
Tristan Shieh | 17180af | 2018-07-02 17:20:13 +0800 | [diff] [blame] | 59 | .upd_reg = NULL, \ |
| 60 | .upd_shift = 0, \ |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 61 | } |
| 62 | |
| 63 | static const struct mux muxes[] = { |
| 64 | /* CLK_CFG_0 */ |
| 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), |
| 69 | /* CLK_CFG_1 */ |
| 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), |
| 74 | /* CLK_CFG_2 */ |
| 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), |
| 79 | /* CLK_CFG_3 */ |
| 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), |
| 84 | /* CLK_CFG_4 */ |
| 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), |
| 89 | /* CLK_CFG_5 */ |
| 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), |
| 94 | /* CLK_CFG_6 */ |
| 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), |
| 99 | /* CLK_CFG_7 */ |
| 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), |
| 104 | /* CLK_CFG_12 */ |
| 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), |
| 108 | /* CLK_CFG_13 */ |
| 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), |
| 113 | }; |
| 114 | |
Tristan Shieh | 17180af | 2018-07-02 17:20:13 +0800 | [diff] [blame] | 115 | struct mux_sel { |
| 116 | enum mux_id id; |
| 117 | u32 sel; |
| 118 | }; |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 119 | |
Tristan Shieh | 17180af | 2018-07-02 17:20:13 +0800 | [diff] [blame] | 120 | static const struct mux_sel mux_sels[] = { |
| 121 | /* CLK_CFG_0 */ |
| 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 */ |
| 126 | /* CLK_CFG_1 */ |
| 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 */ |
| 131 | /* CLK_CFG_2 */ |
| 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 */ |
| 136 | /* CLK_CFG_4 */ |
| 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 */ |
| 141 | /* CLK_CFG_5 */ |
| 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 */ |
| 146 | /* CLK_CFG_6 */ |
| 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 */ |
| 151 | /* CLK_CFG_7 */ |
| 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 */ |
| 156 | /* CLK_CFG_12 */ |
| 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 */ |
| 160 | /* CLK_CFG_13 */ |
| 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 */ |
| 165 | /* CLK_CFG_3 */ |
| 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 */ |
| 170 | }; |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 171 | |
| 172 | enum pll_id { |
| 173 | APMIXED_ARMCA15PLL, |
| 174 | APMIXED_ARMCA7PLL, |
| 175 | APMIXED_MAINPLL, |
| 176 | APMIXED_UNIVPLL, |
| 177 | APMIXED_MMPLL, |
| 178 | APMIXED_MSDCPLL, |
| 179 | APMIXED_VENCPLL, |
| 180 | APMIXED_TVDPLL, |
| 181 | APMIXED_MPLL, |
| 182 | APMIXED_VCODECPLL, |
| 183 | APMIXED_APLL1, |
| 184 | APMIXED_APLL2, |
| 185 | APMIXED_LVDSPLL, |
| 186 | APMIXED_MSDCPLL2, |
| 187 | APMIXED_NR_PLL |
| 188 | }; |
| 189 | |
| 190 | const u32 pll_div_rate[] = { |
| 191 | 3UL * GHz, |
| 192 | 1 * GHz, |
| 193 | 500 * MHz, |
| 194 | 250 * MHz, |
| 195 | 125 * MHz, |
| 196 | 0, |
| 197 | }; |
| 198 | |
| 199 | const u32 univpll_div_rate[] = { |
| 200 | 3UL * GHz, |
| 201 | 1500 * MHz, |
| 202 | 750 * MHz, |
| 203 | 375 * MHz, |
| 204 | 187500 * KHz, |
| 205 | 0, |
| 206 | }; |
| 207 | |
| 208 | const u32 mmpll_div_rate[] = { |
| 209 | 3UL * GHz, |
| 210 | 1 * GHz, |
| 211 | 702 * MHz, |
| 212 | 253500 * KHz, |
| 213 | 126750 * KHz, |
| 214 | 0, |
| 215 | }; |
| 216 | |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 217 | static const struct pll plls[] = { |
Tristan Shieh | 17180af | 2018-07-02 17:20:13 +0800 | [diff] [blame] | 218 | PLL(APMIXED_ARMCA15PLL, armca15pll_con0, armca15pll_pwr_con0, |
| 219 | NO_RSTB_SHIFT, 21, armca15pll_con1, 24, armca15pll_con1, 0, |
| 220 | pll_div_rate), |
| 221 | PLL(APMIXED_ARMCA7PLL, armca7pll_con0, armca7pll_pwr_con0, |
| 222 | PLL_RSTB_SHIFT, 21, armca7pll_con1, 24, armca7pll_con1, 0, |
| 223 | pll_div_rate), |
| 224 | PLL(APMIXED_MAINPLL, mainpll_con0, mainpll_pwr_con0, |
| 225 | PLL_RSTB_SHIFT, 21, mainpll_con0, 4, mainpll_con1, 0, |
| 226 | pll_div_rate), |
| 227 | PLL(APMIXED_UNIVPLL, univpll_con0, univpll_pwr_con0, |
| 228 | PLL_RSTB_SHIFT, 7, univpll_con0, 4, univpll_con1, 14, |
| 229 | univpll_div_rate), |
| 230 | PLL(APMIXED_MMPLL, mmpll_con0, mmpll_pwr_con0, |
| 231 | NO_RSTB_SHIFT, 21, mmpll_con1, 24, mmpll_con1, 0, |
| 232 | mmpll_div_rate), |
| 233 | PLL(APMIXED_MSDCPLL, msdcpll_con0, msdcpll_pwr_con0, |
| 234 | NO_RSTB_SHIFT, 21, msdcpll_con0, 4, msdcpll_con1, 0, |
| 235 | pll_div_rate), |
| 236 | PLL(APMIXED_VENCPLL, vencpll_con0, vencpll_pwr_con0, |
| 237 | NO_RSTB_SHIFT, 21, vencpll_con0, 4, vencpll_con1, 0, |
| 238 | pll_div_rate), |
| 239 | PLL(APMIXED_TVDPLL, tvdpll_con0, tvdpll_pwr_con0, |
| 240 | NO_RSTB_SHIFT, 21, tvdpll_con0, 4, tvdpll_con1, 0, |
| 241 | pll_div_rate), |
| 242 | PLL(APMIXED_MPLL, mpll_con0, mpll_pwr_con0, |
| 243 | NO_RSTB_SHIFT, 21, mpll_con0, 4, mpll_con1, 0, |
| 244 | pll_div_rate), |
| 245 | PLL(APMIXED_VCODECPLL, vcodecpll_con0, vcodecpll_pwr_con0, |
| 246 | NO_RSTB_SHIFT, 21, vcodecpll_con0, 4, vcodecpll_con1, 0, |
| 247 | pll_div_rate), |
| 248 | PLL(APMIXED_APLL1, apll1_con0, apll1_pwr_con0, |
| 249 | NO_RSTB_SHIFT, 31, apll1_con0, 4, apll1_con1, 0, |
| 250 | pll_div_rate), |
| 251 | PLL(APMIXED_APLL2, apll2_con0, apll2_pwr_con0, |
| 252 | NO_RSTB_SHIFT, 31, apll2_con0, 4, apll2_con1, 0, |
| 253 | pll_div_rate), |
| 254 | PLL(APMIXED_LVDSPLL, lvdspll_con0, lvdspll_pwr_con0, |
| 255 | NO_RSTB_SHIFT, 21, lvdspll_con0, 4, lvdspll_con1, 0, |
| 256 | pll_div_rate), |
| 257 | PLL(APMIXED_MSDCPLL2, msdcpll2_con0, msdcpll2_pwr_con0, |
| 258 | NO_RSTB_SHIFT, 21, msdcpll2_con0, 4, msdcpll2_con1, 0, |
| 259 | pll_div_rate), |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 260 | }; |
| 261 | |
Tristan Shieh | 17180af | 2018-07-02 17:20:13 +0800 | [diff] [blame] | 262 | struct rate { |
| 263 | enum pll_id id; |
| 264 | u32 rate; |
| 265 | }; |
| 266 | |
| 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 }, |
| 282 | }; |
| 283 | |
| 284 | void pll_set_pcw_change(const struct pll *pll) |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 285 | { |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 286 | setbits32(pll->pcw_reg, PLL_PCW_CHG); |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 287 | } |
| 288 | |
| 289 | void mt_pll_init(void) |
| 290 | { |
| 291 | int i; |
| 292 | |
| 293 | /* reduce CLKSQ disable time */ |
Tristan Shieh | 17180af | 2018-07-02 17:20:13 +0800 | [diff] [blame] | 294 | write32(&mtk_apmixed->clksq_stb_con0, (0x05 << 8) | (0x01 << 0)); |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 295 | /* extend PWR/ISO control timing to 1us */ |
Tristan Shieh | 17180af | 2018-07-02 17:20:13 +0800 | [diff] [blame] | 296 | write32(&mtk_apmixed->pll_iso_con0, (0x8 << 16) | (0x8 << 0)); |
| 297 | write32(&mtk_apmixed->ap_pll_con6, 0x00000000); |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 298 | |
| 299 | /************* |
| 300 | * xPLL PWR ON |
| 301 | **************/ |
| 302 | for (i = 0; i < APMIXED_NR_PLL; i++) |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 303 | setbits32(plls[i].pwr_reg, PLL_PWR_ON); |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 304 | |
Tristan Shieh | 17180af | 2018-07-02 17:20:13 +0800 | [diff] [blame] | 305 | /* wait for xPLL_PWR_ON ready (min delay is 1us) */ |
| 306 | udelay(PLL_PWR_ON_DELAY); |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 307 | |
| 308 | /****************** |
| 309 | * xPLL ISO Disable |
| 310 | *******************/ |
| 311 | for (i = 0; i < APMIXED_NR_PLL; i++) |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 312 | clrbits32(plls[i].pwr_reg, PLL_ISO); |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 313 | |
| 314 | /******************** |
| 315 | * xPLL Frequency Set |
| 316 | *********************/ |
Tristan Shieh | 17180af | 2018-07-02 17:20:13 +0800 | [diff] [blame] | 317 | for (i = 0; i < ARRAY_SIZE(rates); i++) |
| 318 | pll_set_rate(&plls[rates[i].id], rates[i].rate); |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 319 | |
| 320 | /*********************** |
| 321 | * xPLL Frequency Enable |
| 322 | ************************/ |
| 323 | for (i = 0; i < APMIXED_NR_PLL; i++) |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 324 | setbits32(plls[i].reg, PLL_EN); |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 325 | |
Tristan Shieh | 17180af | 2018-07-02 17:20:13 +0800 | [diff] [blame] | 326 | udelay(PLL_EN_DELAY); /* wait for PLL stable (min delay is 20us) */ |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 327 | |
| 328 | /*************** |
| 329 | * xPLL DIV RSTB |
| 330 | ****************/ |
| 331 | for (i = 0; i < APMIXED_NR_PLL; i++) { |
Tristan Shieh | 17180af | 2018-07-02 17:20:13 +0800 | [diff] [blame] | 332 | if (plls[i].rstb_shift != NO_RSTB_SHIFT) |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 333 | setbits32(plls[i].reg, 1 << plls[i].rstb_shift); |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 334 | } |
| 335 | |
| 336 | /************** |
| 337 | * INFRA CLKMUX |
| 338 | ***************/ |
| 339 | |
| 340 | /* enable infrasys DCM */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 341 | setbits32(&mt8173_infracfg->top_dcmctl, 0x1); |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 342 | |
Tristan Shieh | 17180af | 2018-07-02 17:20:13 +0800 | [diff] [blame] | 343 | write32(&mtk_topckgen->clk_mode, 0x1); |
| 344 | write32(&mtk_topckgen->clk_mode, 0x0); /* enable TOPCKGEN */ |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 345 | |
| 346 | /************ |
| 347 | * TOP CLKMUX -- DO NOT CHANGE WITHOUT ADJUSTING <soc/pll.h> CONSTANTS! |
| 348 | *************/ |
Tristan Shieh | 17180af | 2018-07-02 17:20:13 +0800 | [diff] [blame] | 349 | for (i = 0; i < ARRAY_SIZE(mux_sels); i++) |
| 350 | mux_set_sel(&muxes[mux_sels[i].id], mux_sels[i].sel); |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 351 | |
| 352 | /* enable scpsys clock off control */ |
Tristan Shieh | 17180af | 2018-07-02 17:20:13 +0800 | [diff] [blame] | 353 | write32(&mtk_topckgen->clk_scp_cfg_0, |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 354 | (1 << 10) | (1 << 9) | (1 << 5) | (1 << 4) | (1 << 2) | |
| 355 | (1 << 1) | (1 << 0)); |
Tristan Shieh | 17180af | 2018-07-02 17:20:13 +0800 | [diff] [blame] | 356 | write32(&mtk_topckgen->clk_scp_cfg_1, |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 357 | (1 << 4) | (1 << 2) | (1 << 0)); |
| 358 | } |
| 359 | |
Chunfeng Yun | cc248bc | 2015-09-06 16:01:33 +0800 | [diff] [blame] | 360 | /* Turn on ADA_SSUSB_XTAL_CK 26MHz */ |
| 361 | void mt_pll_enable_ssusb_clk(void) |
| 362 | { |
| 363 | /* set RG_LTECLKSQ_EN */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 364 | setbits32(&mtk_apmixed->ap_pll_con0, 0x1); |
Tristan Shieh | f42db11 | 2018-06-06 12:52:20 +0800 | [diff] [blame] | 365 | udelay(100); /* wait for PLL stable */ |
Chunfeng Yun | cc248bc | 2015-09-06 16:01:33 +0800 | [diff] [blame] | 366 | |
| 367 | /* set RG_LTECLKSQ_LPF_EN & DA_REF2USB_TX_EN */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 368 | setbits32(&mtk_apmixed->ap_pll_con0, 0x1 << 1); |
| 369 | setbits32(&mtk_apmixed->ap_pll_con2, 0x1); |
Tristan Shieh | f42db11 | 2018-06-06 12:52:20 +0800 | [diff] [blame] | 370 | udelay(100); /* wait for PLL stable */ |
Chunfeng Yun | cc248bc | 2015-09-06 16:01:33 +0800 | [diff] [blame] | 371 | |
| 372 | /* set DA_REF2USB_TX_LPF_EN & DA_REF2USB_TX_OUT_EN */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 373 | setbits32(&mtk_apmixed->ap_pll_con2, (0x1 << 2) | (0x1 << 1)); |
Chunfeng Yun | cc248bc | 2015-09-06 16:01:33 +0800 | [diff] [blame] | 374 | } |
| 375 | |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 376 | /* after pmic_init */ |
| 377 | void mt_pll_post_init(void) |
| 378 | { |
| 379 | /* CPU clock divide by 1 */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 380 | clrbits32(&mt8173_infracfg->top_ckdiv1, 0x3ff); |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 381 | |
| 382 | /* select ARMPLL */ |
James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 383 | write32(&mt8173_infracfg->top_ckmuxsel, (1 << 2) | 1); |
| 384 | } |
Koro Chen | 5d7c38f | 2015-08-04 16:16:46 +0800 | [diff] [blame] | 385 | |
| 386 | void mt_pll_set_aud_div(u32 rate) |
| 387 | { |
| 388 | u32 mclk_div; |
| 389 | u32 apll_clock = APLL2_CK_HZ; |
| 390 | int apll1 = 0; |
| 391 | |
| 392 | if (rate % 11025 == 0) { |
| 393 | /* use APLL1 instead */ |
| 394 | apll1 = 1; |
| 395 | apll_clock = APLL1_CK_HZ; |
| 396 | } |
| 397 | /* I2S1 clock */ |
| 398 | mclk_div = (apll_clock / 256 / rate) - 1; |
| 399 | assert(apll_clock == rate * 256 * (mclk_div + 1)); |
| 400 | |
| 401 | if (apll1) { |
| 402 | /* mclk */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 403 | clrbits32(&mtk_topckgen->clk_auddiv_0, 1 << 5); |
| 404 | clrsetbits32(&mtk_topckgen->clk_auddiv_1, 0xff << 8, |
| 405 | mclk_div << 8); |
Koro Chen | 5d7c38f | 2015-08-04 16:16:46 +0800 | [diff] [blame] | 406 | /* bclk */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 407 | clrsetbits32(&mtk_topckgen->clk_auddiv_0, 0xf << 24, |
| 408 | 7 << 24); |
Koro Chen | 5d7c38f | 2015-08-04 16:16:46 +0800 | [diff] [blame] | 409 | } else { |
| 410 | /* mclk */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 411 | setbits32(&mtk_topckgen->clk_auddiv_0, 1 << 5); |
| 412 | clrsetbits32(&mtk_topckgen->clk_auddiv_2, 0xff << 8, |
| 413 | mclk_div << 8); |
Koro Chen | 5d7c38f | 2015-08-04 16:16:46 +0800 | [diff] [blame] | 414 | /* bclk */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 415 | clrsetbits32(&mtk_topckgen->clk_auddiv_0, 0xf << 28, |
| 416 | 7 << 28); |
Koro Chen | 5d7c38f | 2015-08-04 16:16:46 +0800 | [diff] [blame] | 417 | } |
| 418 | } |
Peter Kao | da1e02a | 2015-07-31 17:11:14 +0800 | [diff] [blame] | 419 | |
Weiyi Lu | 86b3bf1 | 2020-06-19 15:28:55 +0800 | [diff] [blame] | 420 | void mt_pll_raise_little_cpu_freq(u32 freq) |
Tristan Shieh | 3d96f60 | 2019-04-26 11:58:30 +0800 | [diff] [blame] | 421 | { |
Yidi Lin | a622f28 | 2016-01-29 17:25:03 +0800 | [diff] [blame] | 422 | pll_set_rate(&plls[APMIXED_ARMCA7PLL], freq); /* freq in Hz */ |
| 423 | } |
| 424 | |
Peter Kao | da1e02a | 2015-07-31 17:11:14 +0800 | [diff] [blame] | 425 | void mt_mem_pll_config_pre(const struct mt8173_sdram_params *sdram_params) |
| 426 | { |
| 427 | u32 mpll_sdm_pcw_20_0 = 0xF13B1; |
| 428 | |
| 429 | /* disable MPLL for adjusting memory clk frequency */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 430 | clrbits32(&mtk_apmixed->mpll_con0, BIT(0)); |
Peter Kao | da1e02a | 2015-07-31 17:11:14 +0800 | [diff] [blame] | 431 | /* MPLL configuration: mode selection */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 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); |
Peter Kao | da1e02a | 2015-07-31 17:11:14 +0800 | [diff] [blame] | 435 | /* set RG_MPLL_SDM_PCW for feedback divide ratio */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 436 | clrsetbits32(&mtk_apmixed->mpll_con1, 0x1fffff, mpll_sdm_pcw_20_0); |
Peter Kao | da1e02a | 2015-07-31 17:11:14 +0800 | [diff] [blame] | 437 | } |
| 438 | |
| 439 | void mt_mem_pll_config_post(void) |
| 440 | { |
| 441 | /* power up sequence starts: enable MPLL */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 442 | setbits32(&mtk_apmixed->mpll_con0, BIT(0)); |
Peter Kao | da1e02a | 2015-07-31 17:11:14 +0800 | [diff] [blame] | 443 | } |
| 444 | |
| 445 | void mt_mem_pll_mux(void) |
| 446 | { |
| 447 | /* CLK_CFG_0 */ |
| 448 | mux_set_sel(&muxes[TOP_MEM_SEL], 1); /* 1: dmpll_ck */ |
| 449 | } |