James Liao | f9fad12 | 2015-07-31 17:10:53 +0800 | [diff] [blame] | 1 | /* |
| 2 | * This file is part of the coreboot project. |
| 3 | * |
| 4 | * Copyright 2015 MediaTek Inc. |
| 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by |
| 8 | * the Free Software Foundation; version 2 of the License. |
| 9 | * |
| 10 | * This program is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | * GNU General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with this program; if not, write to the Free Software |
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 18 | */ |
| 19 | |
| 20 | #include <arch/io.h> |
| 21 | #include <assert.h> |
| 22 | #include <console/console.h> |
| 23 | #include <delay.h> |
| 24 | #include <stddef.h> |
| 25 | |
| 26 | #include <soc/addressmap.h> |
| 27 | #include <soc/infracfg.h> |
| 28 | #include <soc/pll.h> |
| 29 | |
| 30 | #define GENMASK(h, l) (((1U << ((h) - (l) + 1)) - 1) << (l)) |
| 31 | |
| 32 | enum mux_id { |
| 33 | TOP_AXI_SEL, |
| 34 | TOP_MEM_SEL, |
| 35 | TOP_DDRPHYCFG_SEL, |
| 36 | TOP_MM_SEL, |
| 37 | TOP_PWM_SEL, |
| 38 | TOP_VDEC_SEL, |
| 39 | TOP_VENC_SEL, |
| 40 | TOP_MFG_SEL, |
| 41 | TOP_CAMTG_SEL, |
| 42 | TOP_UART_SEL, |
| 43 | TOP_SPI_SEL, |
| 44 | TOP_USB20_SEL, |
| 45 | TOP_USB30_SEL, |
| 46 | TOP_MSDC50_0_H_SEL, |
| 47 | TOP_MSDC50_0_SEL, |
| 48 | TOP_MSDC30_1_SEL, |
| 49 | TOP_MSDC30_2_SEL, |
| 50 | TOP_MSDC30_3_SEL, |
| 51 | TOP_AUDIO_SEL, |
| 52 | TOP_AUD_INTBUS_SEL, |
| 53 | TOP_PMICSPI_SEL, |
| 54 | TOP_SCP_SEL, |
| 55 | TOP_ATB_SEL, |
| 56 | TOP_VENC_LT_SEL, |
| 57 | TOP_DPI0_SEL, |
| 58 | TOP_IRDA_SEL, |
| 59 | TOP_CCI400_SEL, |
| 60 | TOP_AUD_1_SEL, |
| 61 | TOP_AUD_2_SEL, |
| 62 | TOP_MEM_MFG_IN_SEL, |
| 63 | TOP_AXI_MFG_IN_SEL, |
| 64 | TOP_SCAM_SEL, |
| 65 | TOP_SPINFI_IFR_SEL, |
| 66 | TOP_HDMI_SEL, |
| 67 | TOP_DPILVDS_SEL, |
| 68 | TOP_MSDC50_2_H_SEL, |
| 69 | TOP_HDCP_SEL, |
| 70 | TOP_HDCP_24M_SEL, |
| 71 | TOP_RTC_SEL, |
| 72 | TOP_NR_MUX |
| 73 | }; |
| 74 | |
| 75 | #define TOPCKGEN_REG(x) (CKSYS_BASE + offsetof(struct mt8173_topckgen_regs, x)) |
| 76 | #define APMIXED_REG(x) (APMIXED_BASE + offsetof(struct mt8173_apmixed_regs, x)) |
| 77 | |
| 78 | struct mux { |
| 79 | void *reg; |
| 80 | u8 mux_shift; |
| 81 | u8 mux_width; |
| 82 | }; |
| 83 | |
| 84 | #define MUX(_id, _reg, _mux_shift, _mux_width) \ |
| 85 | [_id] = { \ |
| 86 | .reg = (void *)TOPCKGEN_REG(_reg), \ |
| 87 | .mux_shift = _mux_shift, \ |
| 88 | .mux_width = _mux_width, \ |
| 89 | } |
| 90 | |
| 91 | static const struct mux muxes[] = { |
| 92 | /* CLK_CFG_0 */ |
| 93 | MUX(TOP_AXI_SEL, clk_cfg_0, 0, 3), |
| 94 | MUX(TOP_MEM_SEL, clk_cfg_0, 8, 1), |
| 95 | MUX(TOP_DDRPHYCFG_SEL, clk_cfg_0, 16, 1), |
| 96 | MUX(TOP_MM_SEL, clk_cfg_0, 24, 4), |
| 97 | /* CLK_CFG_1 */ |
| 98 | MUX(TOP_PWM_SEL, clk_cfg_1, 0, 2), |
| 99 | MUX(TOP_VDEC_SEL, clk_cfg_1, 8, 4), |
| 100 | MUX(TOP_VENC_SEL, clk_cfg_1, 16, 4), |
| 101 | MUX(TOP_MFG_SEL, clk_cfg_1, 24, 4), |
| 102 | /* CLK_CFG_2 */ |
| 103 | MUX(TOP_CAMTG_SEL, clk_cfg_2, 0, 3), |
| 104 | MUX(TOP_UART_SEL, clk_cfg_2, 8, 1), |
| 105 | MUX(TOP_SPI_SEL, clk_cfg_2, 16, 3), |
| 106 | MUX(TOP_USB20_SEL, clk_cfg_2, 24, 2), |
| 107 | /* CLK_CFG_3 */ |
| 108 | MUX(TOP_USB30_SEL, clk_cfg_3, 0, 2), |
| 109 | MUX(TOP_MSDC50_0_H_SEL, clk_cfg_3, 8, 3), |
| 110 | MUX(TOP_MSDC50_0_SEL, clk_cfg_3, 16, 4), |
| 111 | MUX(TOP_MSDC30_1_SEL, clk_cfg_3, 24, 3), |
| 112 | /* CLK_CFG_4 */ |
| 113 | MUX(TOP_MSDC30_2_SEL, clk_cfg_4, 0, 3), |
| 114 | MUX(TOP_MSDC30_3_SEL, clk_cfg_4, 8, 4), |
| 115 | MUX(TOP_AUDIO_SEL, clk_cfg_4, 16, 2), |
| 116 | MUX(TOP_AUD_INTBUS_SEL, clk_cfg_4, 24, 3), |
| 117 | /* CLK_CFG_5 */ |
| 118 | MUX(TOP_PMICSPI_SEL, clk_cfg_5, 0, 3), |
| 119 | MUX(TOP_SCP_SEL, clk_cfg_5, 8, 3), |
| 120 | MUX(TOP_ATB_SEL, clk_cfg_5, 16, 2), |
| 121 | MUX(TOP_VENC_LT_SEL, clk_cfg_5, 24, 4), |
| 122 | /* CLK_CFG_6 */ |
| 123 | MUX(TOP_DPI0_SEL, clk_cfg_6, 0, 3), |
| 124 | MUX(TOP_IRDA_SEL, clk_cfg_6, 8, 2), |
| 125 | MUX(TOP_CCI400_SEL, clk_cfg_6, 16, 3), |
| 126 | MUX(TOP_AUD_1_SEL, clk_cfg_6, 24, 2), |
| 127 | /* CLK_CFG_7 */ |
| 128 | MUX(TOP_AUD_2_SEL, clk_cfg_7, 0, 2), |
| 129 | MUX(TOP_MEM_MFG_IN_SEL, clk_cfg_7, 8, 2), |
| 130 | MUX(TOP_AXI_MFG_IN_SEL, clk_cfg_7, 16, 2), |
| 131 | MUX(TOP_SCAM_SEL, clk_cfg_7, 24, 2), |
| 132 | /* CLK_CFG_12 */ |
| 133 | MUX(TOP_SPINFI_IFR_SEL, clk_cfg_12, 0, 3), |
| 134 | MUX(TOP_HDMI_SEL, clk_cfg_12, 8, 2), |
| 135 | MUX(TOP_DPILVDS_SEL, clk_cfg_12, 24, 3), |
| 136 | /* CLK_CFG_13 */ |
| 137 | MUX(TOP_MSDC50_2_H_SEL, clk_cfg_13, 0, 3), |
| 138 | MUX(TOP_HDCP_SEL, clk_cfg_13, 8, 2), |
| 139 | MUX(TOP_HDCP_24M_SEL, clk_cfg_13, 16, 2), |
| 140 | MUX(TOP_RTC_SEL, clk_cfg_13, 24, 2), |
| 141 | }; |
| 142 | |
| 143 | static void mux_set_sel(const struct mux *mux, u32 sel) |
| 144 | { |
| 145 | u32 mask = GENMASK(mux->mux_width - 1, 0); |
| 146 | u32 val = read32(mux->reg); |
| 147 | |
| 148 | val &= ~(mask << mux->mux_shift); |
| 149 | val |= (sel & mask) << mux->mux_shift; |
| 150 | write32(mux->reg, val); |
| 151 | } |
| 152 | |
| 153 | #define PLL_PWR_ON (1 << 0) |
| 154 | #define PLL_EN (1 << 0) |
| 155 | #define PLL_ISO (1 << 1) |
| 156 | #define PLL_RSTB (1 << 24) |
| 157 | #define PLL_PCW_CHG (1 << 31) |
| 158 | #define PLL_POSTDIV_MASK 0x7 |
| 159 | #define PCW_INTEGER_BITS 7 |
| 160 | |
| 161 | enum pll_id { |
| 162 | APMIXED_ARMCA15PLL, |
| 163 | APMIXED_ARMCA7PLL, |
| 164 | APMIXED_MAINPLL, |
| 165 | APMIXED_UNIVPLL, |
| 166 | APMIXED_MMPLL, |
| 167 | APMIXED_MSDCPLL, |
| 168 | APMIXED_VENCPLL, |
| 169 | APMIXED_TVDPLL, |
| 170 | APMIXED_MPLL, |
| 171 | APMIXED_VCODECPLL, |
| 172 | APMIXED_APLL1, |
| 173 | APMIXED_APLL2, |
| 174 | APMIXED_LVDSPLL, |
| 175 | APMIXED_MSDCPLL2, |
| 176 | APMIXED_NR_PLL |
| 177 | }; |
| 178 | |
| 179 | const u32 pll_div_rate[] = { |
| 180 | 3UL * GHz, |
| 181 | 1 * GHz, |
| 182 | 500 * MHz, |
| 183 | 250 * MHz, |
| 184 | 125 * MHz, |
| 185 | 0, |
| 186 | }; |
| 187 | |
| 188 | const u32 univpll_div_rate[] = { |
| 189 | 3UL * GHz, |
| 190 | 1500 * MHz, |
| 191 | 750 * MHz, |
| 192 | 375 * MHz, |
| 193 | 187500 * KHz, |
| 194 | 0, |
| 195 | }; |
| 196 | |
| 197 | const u32 mmpll_div_rate[] = { |
| 198 | 3UL * GHz, |
| 199 | 1 * GHz, |
| 200 | 702 * MHz, |
| 201 | 253500 * KHz, |
| 202 | 126750 * KHz, |
| 203 | 0, |
| 204 | }; |
| 205 | |
| 206 | struct pll { |
| 207 | void *reg; |
| 208 | void *pwr_reg; |
| 209 | u32 rstb; |
| 210 | u8 pcwbits; |
| 211 | void *div_reg; |
| 212 | u8 div_shift; |
| 213 | void *pcw_reg; |
| 214 | u8 pcw_shift; |
| 215 | const u32 *div_rate; |
| 216 | }; |
| 217 | |
| 218 | #define PLL(_id, _reg, _pwr_reg, _rstb, _pcwbits, _div_reg, _div_shift, \ |
| 219 | _pcw_reg, _pcw_shift, _div_rate) \ |
| 220 | [_id] = { \ |
| 221 | .reg = (void *)APMIXED_REG(_reg), \ |
| 222 | .pwr_reg = (void *)APMIXED_REG(_pwr_reg), \ |
| 223 | .rstb = _rstb, \ |
| 224 | .pcwbits = _pcwbits, \ |
| 225 | .div_reg = (void *)APMIXED_REG(_div_reg), \ |
| 226 | .div_shift = _div_shift, \ |
| 227 | .pcw_reg = (void *)APMIXED_REG(_pcw_reg), \ |
| 228 | .pcw_shift = _pcw_shift, \ |
| 229 | .div_rate = _div_rate, \ |
| 230 | } |
| 231 | |
| 232 | static const struct pll plls[] = { |
| 233 | PLL(APMIXED_ARMCA15PLL, armca15pll_con0, armca15pll_pwr_con0, 0, 21, |
| 234 | armca15pll_con1, 24, armca15pll_con1, 0, pll_div_rate), |
| 235 | PLL(APMIXED_ARMCA7PLL, armca7pll_con0, armca7pll_pwr_con0, PLL_RSTB, 21, |
| 236 | armca7pll_con1, 24, armca7pll_con1, 0, pll_div_rate), |
| 237 | PLL(APMIXED_MAINPLL, mainpll_con0, mainpll_pwr_con0, PLL_RSTB, 21, |
| 238 | mainpll_con0, 4, mainpll_con1, 0, pll_div_rate), |
| 239 | PLL(APMIXED_UNIVPLL, univpll_con0, univpll_pwr_con0, PLL_RSTB, 7, |
| 240 | univpll_con0, 4, univpll_con1, 14, univpll_div_rate), |
| 241 | PLL(APMIXED_MMPLL, mmpll_con0, mmpll_pwr_con0, 0, 21, |
| 242 | mmpll_con1, 24, mmpll_con1, 0, mmpll_div_rate), |
| 243 | PLL(APMIXED_MSDCPLL, msdcpll_con0, msdcpll_pwr_con0, 0, 21, |
| 244 | msdcpll_con0, 4, msdcpll_con1, 0, pll_div_rate), |
| 245 | PLL(APMIXED_VENCPLL, vencpll_con0, vencpll_pwr_con0, 0, 21, |
| 246 | vencpll_con0, 4, vencpll_con1, 0, pll_div_rate), |
| 247 | PLL(APMIXED_TVDPLL, tvdpll_con0, tvdpll_pwr_con0, 0, 21, |
| 248 | tvdpll_con0, 4, tvdpll_con1, 0, pll_div_rate), |
| 249 | PLL(APMIXED_MPLL, mpll_con0, mpll_pwr_con0, 0, 21, |
| 250 | mpll_con0, 4, mpll_con1, 0, pll_div_rate), |
| 251 | PLL(APMIXED_VCODECPLL, vcodecpll_con0, vcodecpll_pwr_con0, 0, 21, |
| 252 | vcodecpll_con0, 4, vcodecpll_con1, 0, pll_div_rate), |
| 253 | PLL(APMIXED_APLL1, apll1_con0, apll1_pwr_con0, 0, 31, |
| 254 | apll1_con0, 4, apll1_con1, 0, pll_div_rate), |
| 255 | PLL(APMIXED_APLL2, apll2_con0, apll2_pwr_con0, 0, 31, |
| 256 | apll2_con0, 4, apll2_con1, 0, pll_div_rate), |
| 257 | PLL(APMIXED_LVDSPLL, lvdspll_con0, lvdspll_pwr_con0, 0, 21, |
| 258 | lvdspll_con0, 4, lvdspll_con1, 0, pll_div_rate), |
| 259 | PLL(APMIXED_MSDCPLL2, msdcpll2_con0, msdcpll2_pwr_con0, 0, 21, |
| 260 | msdcpll2_con0, 4, msdcpll2_con1, 0, pll_div_rate), |
| 261 | }; |
| 262 | |
| 263 | static void pll_set_rate_regs(const struct pll *pll, u32 pcw, u32 postdiv) |
| 264 | { |
| 265 | u32 val; |
| 266 | |
| 267 | /* set postdiv */ |
| 268 | val = read32(pll->div_reg); |
| 269 | val &= ~(PLL_POSTDIV_MASK << pll->div_shift); |
| 270 | val |= postdiv << pll->div_shift; |
| 271 | |
| 272 | /* postdiv and pcw need to set at the same time if on same register */ |
| 273 | if (pll->div_reg != pll->pcw_reg) { |
| 274 | write32(pll->div_reg, val); |
| 275 | val = read32(pll->pcw_reg); |
| 276 | } |
| 277 | |
| 278 | /* set pcw */ |
| 279 | val &= ~GENMASK(pll->pcw_shift + pll->pcwbits - 1, pll->pcw_shift); |
| 280 | val |= pcw << pll->pcw_shift; |
| 281 | val |= PLL_PCW_CHG; |
| 282 | write32(pll->pcw_reg, val); |
| 283 | } |
| 284 | |
| 285 | static void pll_calc_values(const struct pll *pll, u32 *pcw, u32 *postdiv, |
| 286 | u32 freq) |
| 287 | { |
| 288 | const u32 fin_hz = CLK26M_HZ; |
| 289 | const u32 *div_rate = pll->div_rate; |
| 290 | u32 val; |
| 291 | |
| 292 | assert(freq <= div_rate[0]); |
| 293 | assert(freq >= 1 * GHz / 16); |
| 294 | |
| 295 | for (val = 1; div_rate[val] != 0; val++) { |
| 296 | if (freq > div_rate[val]) |
| 297 | break; |
| 298 | } |
| 299 | val--; |
| 300 | *postdiv = val; |
| 301 | |
| 302 | /* _pcw = freq * 2^postdiv / fin * 2^pcwbits_fractional */ |
| 303 | val += pll->pcwbits - PCW_INTEGER_BITS; |
| 304 | |
| 305 | *pcw = ((u64)freq << val) / fin_hz; |
| 306 | } |
| 307 | |
| 308 | static int pll_set_rate(const struct pll *pll, u32 rate) |
| 309 | { |
| 310 | u32 pcw = 0; |
| 311 | u32 postdiv; |
| 312 | |
| 313 | pll_calc_values(pll, &pcw, &postdiv, rate); |
| 314 | pll_set_rate_regs(pll, pcw, postdiv); |
| 315 | |
| 316 | return 0; |
| 317 | } |
| 318 | |
| 319 | void mt_pll_init(void) |
| 320 | { |
| 321 | int i; |
| 322 | |
| 323 | /* reduce CLKSQ disable time */ |
| 324 | write32(&mt8173_apmixed->clksq_stb_con0, (0x05 << 8) | (0x01 << 0)); |
| 325 | /* extend PWR/ISO control timing to 1us */ |
| 326 | write32(&mt8173_apmixed->pll_iso_con0, (0x8 << 16) | (0x8 << 0)); |
| 327 | write32(&mt8173_apmixed->ap_pll_con6, 0x00000000); |
| 328 | |
| 329 | /************* |
| 330 | * xPLL PWR ON |
| 331 | **************/ |
| 332 | for (i = 0; i < APMIXED_NR_PLL; i++) |
| 333 | setbits_le32(plls[i].pwr_reg, PLL_PWR_ON); |
| 334 | |
| 335 | udelay(5); /* wait for xPLL_PWR_ON ready (min delay is 1us) */ |
| 336 | |
| 337 | /****************** |
| 338 | * xPLL ISO Disable |
| 339 | *******************/ |
| 340 | for (i = 0; i < APMIXED_NR_PLL; i++) |
| 341 | clrbits_le32(plls[i].pwr_reg, PLL_ISO); |
| 342 | |
| 343 | /******************** |
| 344 | * xPLL Frequency Set |
| 345 | *********************/ |
| 346 | |
| 347 | pll_set_rate(&plls[APMIXED_ARMCA15PLL], ARMCA15PLL_HZ); |
| 348 | pll_set_rate(&plls[APMIXED_ARMCA7PLL], ARMCA7PLL_HZ); |
| 349 | pll_set_rate(&plls[APMIXED_MAINPLL], MAINPLL_HZ); |
| 350 | pll_set_rate(&plls[APMIXED_UNIVPLL], UNIVPLL_HZ); |
| 351 | pll_set_rate(&plls[APMIXED_MMPLL], MMPLL_HZ); |
| 352 | pll_set_rate(&plls[APMIXED_MSDCPLL], MSDCPLL_HZ); |
| 353 | pll_set_rate(&plls[APMIXED_VENCPLL], VENCPLL_HZ); |
| 354 | pll_set_rate(&plls[APMIXED_TVDPLL], TVDPLL_HZ); |
| 355 | pll_set_rate(&plls[APMIXED_MPLL], MPLL_HZ); |
| 356 | pll_set_rate(&plls[APMIXED_VCODECPLL], VCODECPLL_HZ); |
| 357 | pll_set_rate(&plls[APMIXED_LVDSPLL], LVDSPLL_HZ); |
| 358 | pll_set_rate(&plls[APMIXED_MSDCPLL2], MSDCPLL2_HZ); |
| 359 | pll_set_rate(&plls[APMIXED_APLL1], APLL1_HZ); |
| 360 | pll_set_rate(&plls[APMIXED_APLL2], APLL2_HZ); |
| 361 | |
| 362 | /*********************** |
| 363 | * xPLL Frequency Enable |
| 364 | ************************/ |
| 365 | for (i = 0; i < APMIXED_NR_PLL; i++) |
| 366 | setbits_le32(plls[i].reg, PLL_EN); |
| 367 | |
| 368 | udelay(40); /* wait for PLL stable (min delay is 20us) */ |
| 369 | |
| 370 | /*************** |
| 371 | * xPLL DIV RSTB |
| 372 | ****************/ |
| 373 | for (i = 0; i < APMIXED_NR_PLL; i++) { |
| 374 | if (plls[i].rstb) |
| 375 | setbits_le32(plls[i].reg, plls[i].rstb); |
| 376 | } |
| 377 | |
| 378 | /************** |
| 379 | * INFRA CLKMUX |
| 380 | ***************/ |
| 381 | |
| 382 | /* enable infrasys DCM */ |
| 383 | setbits_le32(&mt8173_infracfg->top_dcmctl, 0x1); |
| 384 | |
| 385 | write32(&mt8173_topckgen->clk_mode, 0x1); |
| 386 | write32(&mt8173_topckgen->clk_mode, 0x0); /* enable TOPCKGEN */ |
| 387 | |
| 388 | /************ |
| 389 | * TOP CLKMUX -- DO NOT CHANGE WITHOUT ADJUSTING <soc/pll.h> CONSTANTS! |
| 390 | *************/ |
| 391 | |
| 392 | /* CLK_CFG_0 */ |
| 393 | mux_set_sel(&muxes[TOP_AXI_SEL], 5); /* 5: univpll2_d2 */ |
| 394 | mux_set_sel(&muxes[TOP_MEM_SEL], 0); /* 0: clk26m */ |
| 395 | mux_set_sel(&muxes[TOP_DDRPHYCFG_SEL], 0); /* 0: clk26m */ |
| 396 | mux_set_sel(&muxes[TOP_MM_SEL], 1); /* 1: vencpll_d2 */ |
| 397 | /* CLK_CFG_1 */ |
| 398 | mux_set_sel(&muxes[TOP_PWM_SEL], 0); /* 0: clk26m */ |
| 399 | mux_set_sel(&muxes[TOP_VDEC_SEL], 1); /* 1: vcodecpll_ck */ |
| 400 | mux_set_sel(&muxes[TOP_VENC_SEL], 1); /* 1: vcodecpll_ck */ |
| 401 | mux_set_sel(&muxes[TOP_MFG_SEL], 1); /* 1: mmpll_ck */ |
| 402 | /* CLK_CFG_2 */ |
| 403 | mux_set_sel(&muxes[TOP_CAMTG_SEL], 0); /* 0: clk26m */ |
| 404 | mux_set_sel(&muxes[TOP_UART_SEL], 0); /* 0: clk26m */ |
| 405 | mux_set_sel(&muxes[TOP_SPI_SEL], 1); /* 1: syspll3_d2 */ |
| 406 | mux_set_sel(&muxes[TOP_USB20_SEL], 1); /* 1: univpll1_d8 */ |
| 407 | /* CLK_CFG_4 */ |
| 408 | mux_set_sel(&muxes[TOP_MSDC30_2_SEL], 2); /* 2: msdcpll_d4 */ |
| 409 | mux_set_sel(&muxes[TOP_MSDC30_3_SEL], 5); /* 5: msdcpll_d4 */ |
| 410 | mux_set_sel(&muxes[TOP_AUDIO_SEL], 0); /* 0: clk26m */ |
| 411 | mux_set_sel(&muxes[TOP_AUD_INTBUS_SEL], 1); /* 1: syspll1_d4 */ |
| 412 | /* CLK_CFG_5 */ |
| 413 | mux_set_sel(&muxes[TOP_PMICSPI_SEL], 0); /* 0: clk26m */ |
| 414 | mux_set_sel(&muxes[TOP_SCP_SEL], 1); /* 1: syspll1_d2 */ |
| 415 | mux_set_sel(&muxes[TOP_ATB_SEL], 0); /* 0: clk26m */ |
| 416 | mux_set_sel(&muxes[TOP_VENC_LT_SEL], 6); /* 6: univpll1_d2 */ |
| 417 | /* CLK_CFG_6 */ |
| 418 | mux_set_sel(&muxes[TOP_DPI0_SEL], 1); /* 1: tvdpll_d2 */ |
| 419 | mux_set_sel(&muxes[TOP_IRDA_SEL], 1); /* 1: univpll2_d4 */ |
| 420 | mux_set_sel(&muxes[TOP_CCI400_SEL], 5); /* 5: syspll_d2 */ |
| 421 | mux_set_sel(&muxes[TOP_AUD_1_SEL], 1); /* 1: apll1_ck */ |
| 422 | /* CLK_CFG_7 */ |
| 423 | mux_set_sel(&muxes[TOP_AUD_2_SEL], 1); /* 1: apll2_ck */ |
| 424 | mux_set_sel(&muxes[TOP_MEM_MFG_IN_SEL], 1); /* 1: mmpll_ck */ |
| 425 | mux_set_sel(&muxes[TOP_AXI_MFG_IN_SEL], 1); /* 1: hd_faxi_ck */ |
| 426 | mux_set_sel(&muxes[TOP_SCAM_SEL], 1); /* 1: syspll3_d2 */ |
| 427 | /* CLK_CFG_12 */ |
| 428 | mux_set_sel(&muxes[TOP_SPINFI_IFR_SEL], 0); /* 0: clk26m */ |
| 429 | mux_set_sel(&muxes[TOP_HDMI_SEL], 1); /* 1: AD_HDMITX_CLK */ |
| 430 | mux_set_sel(&muxes[TOP_DPILVDS_SEL], 1); /* 1: AD_LVDSPLL_CK */ |
| 431 | /* CLK_CFG_13 */ |
| 432 | mux_set_sel(&muxes[TOP_MSDC50_2_H_SEL], 2); /* 2: syspll2_d2 */ |
| 433 | mux_set_sel(&muxes[TOP_HDCP_SEL], 2); /* 2: syspll3_d4 */ |
| 434 | mux_set_sel(&muxes[TOP_HDCP_24M_SEL], 2); /* 2: univpll_d52 */ |
| 435 | mux_set_sel(&muxes[TOP_RTC_SEL], 1); /* 1: clkrtc_ext */ |
| 436 | /* CLK_CFG_3 */ |
| 437 | mux_set_sel(&muxes[TOP_USB30_SEL], 1); /* 1: univpll3_d2 */ |
| 438 | mux_set_sel(&muxes[TOP_MSDC50_0_H_SEL], 2); /* 2: syspll2_d2 */ |
| 439 | mux_set_sel(&muxes[TOP_MSDC50_0_SEL], 6); /* 6: msdcpll_d4 */ |
| 440 | mux_set_sel(&muxes[TOP_MSDC30_1_SEL], 2); /* 2: msdcpll_d4 */ |
| 441 | |
| 442 | /* enable scpsys clock off control */ |
| 443 | write32(&mt8173_topckgen->clk_scp_cfg_0, |
| 444 | (1 << 10) | (1 << 9) | (1 << 5) | (1 << 4) | (1 << 2) | |
| 445 | (1 << 1) | (1 << 0)); |
| 446 | write32(&mt8173_topckgen->clk_scp_cfg_1, |
| 447 | (1 << 4) | (1 << 2) | (1 << 0)); |
| 448 | } |
| 449 | |
| 450 | /* after pmic_init */ |
| 451 | void mt_pll_post_init(void) |
| 452 | { |
| 453 | /* CPU clock divide by 1 */ |
| 454 | clrbits_le32(&mt8173_infracfg->top_ckdiv1, 0x3ff); |
| 455 | |
| 456 | /* select ARMPLL */ |
| 457 | /* TODO: possibly raise ARMPLL frequency here */ |
| 458 | /* NOTICE: raise Vproc voltage before raise ARMPLL frequency */ |
| 459 | write32(&mt8173_infracfg->top_ckmuxsel, (1 << 2) | 1); |
| 460 | } |