diff --git a/src/soc/qualcomm/sc7180/clock.c b/src/soc/qualcomm/sc7180/clock.c index 8c9e117308..1683d70cbe 100644 --- a/src/soc/qualcomm/sc7180/clock.c +++ b/src/soc/qualcomm/sc7180/clock.c @@ -2,8 +2,10 @@ #include #include +#include #include #include +#include #include #define DIV(div) (2 * div - 1) @@ -273,6 +275,54 @@ void clock_enable_qup(int qup) clk_en_off); } +static int pll_init_and_set(struct sc7180_apss_clock *apss, u32 l_val) +{ + u32 gfmux_val; + + /* Configure and Enable PLL */ + write32(&apss->pll.config_ctl_lo, 0x0); + setbits32(&apss->pll.config_ctl_lo, 0x2 << CTUNE_SHFT | + 0x2 << K_I_SHFT | 0x5 << K_P_SHFT | + 0x2 << PFA_MSB_SHFT | 0x2 << REF_CONT_SHFT); + + write32(&apss->pll.config_ctl_hi, 0x0); + setbits32(&apss->pll.config_ctl_hi, 0x2 << CUR_ADJ_SHFT | + BIT(DMET_SHFT) | 0xF << RES_SHFT); + + write32(&apss->pll.config_ctl_u1, 0x0); + write32(&apss->pll.l_val, l_val); + + setbits32(&apss->pll.mode, BIT(BYPASSNL_SHFT)); + udelay(5); + setbits32(&apss->pll.mode, BIT(RESET_SHFT)); + + setbits32(&apss->pll.opmode, RUN_MODE); + + if (!wait_us(100, read32(&apss->pll.mode) & LOCK_DET_BMSK)) { + printk(BIOS_ERR, "ERROR: PLL did not lock!\n"); + return -1; + } + + setbits32(&apss->pll.mode, BIT(OUTCTRL_SHFT)); + + gfmux_val = read32(&apss->cfg_gfmux) & ~GFMUX_SRC_SEL_BMSK; + gfmux_val |= APCS_SRC_EARLY; + write32(&apss->cfg_gfmux, gfmux_val); + + return 0; +} + +static void speed_up_boot_cpu(void) +{ + /* 1516.8 MHz */ + if (!pll_init_and_set(apss_silver, L_VAL_1516P8MHz)) + printk(BIOS_DEBUG, "Silver Frequency bumped to 1.5168(GHz)\n"); + + /* 1209.6 MHz */ + if (!pll_init_and_set(apss_l3, L_VAL_1209P6MHz)) + printk(BIOS_DEBUG, "L3 Frequency bumped to 1.2096(GHz)\n"); +} + void clock_init(void) { clock_configure_gpll0(); @@ -302,4 +352,5 @@ void clock_init(void) clock_enable_vote(&gcc->qup_wrap1_s_ahb_cbcr, &gcc->apcs_clk_br_en1, QUPV3_WRAP_1_S_AHB_CLK_ENA); + speed_up_boot_cpu(); } diff --git a/src/soc/qualcomm/sc7180/include/soc/addressmap.h b/src/soc/qualcomm/sc7180/include/soc/addressmap.h index 72b6d1295e..c5b48bf44a 100644 --- a/src/soc/qualcomm/sc7180/include/soc/addressmap.h +++ b/src/soc/qualcomm/sc7180/include/soc/addressmap.h @@ -11,6 +11,8 @@ #define TLMM_NORTH_TILE_BASE 0x03900000 #define TLMM_SOUTH_TILE_BASE 0x03D00000 #define TLMM_WEST_TILE_BASE 0x03500000 +#define SILVER_PLL_BASE 0x18280000 +#define L3_PLL_BASE 0x18284000 /* * QUP SERIAL ENGINE BASE ADDRESSES diff --git a/src/soc/qualcomm/sc7180/include/soc/clock.h b/src/soc/qualcomm/sc7180/include/soc/clock.h index 79cf408b5c..d202605327 100644 --- a/src/soc/qualcomm/sc7180/include/soc/clock.h +++ b/src/soc/qualcomm/sc7180/include/soc/clock.h @@ -208,8 +208,63 @@ struct mdss_clock_config { uintptr_t cbcr; }; +/* CPU PLL */ +#define L_VAL_1516P8MHz 0x4F +#define L_VAL_1209P6MHz 0x3F + +struct sc7180_apss_pll { + u32 mode; + u32 l_val; + u32 alpha_val; + u32 user_ctl; + u32 config_ctl_lo; + u32 config_ctl_hi; + u32 config_ctl_u1; + u32 test_ctl_lo; + u32 test_ctl_hi; + u32 test_ctl_u1; + u32 opmode; + u8 _res0[0x38 - 0x2c]; + u32 status; +}; + +struct sc7180_apss_clock { + struct sc7180_apss_pll pll; + u8 _res0[0x88 - 0x40]; + u32 cfg_gfmux; +}; + +enum pll_config_ctl_lo { + CTUNE_SHFT = 2, + K_I_SHFT = 4, + K_P_SHFT = 7, + PFA_MSB_SHFT = 10, + REF_CONT_SHFT = 28, +}; + +enum pll_config_ctl_hi { + CUR_ADJ_SHFT = 0, + DMET_SHFT = 4, + RES_SHFT = 6, +}; + +enum pll_mode { + LOCK_DET_BMSK = 0x80000000, + RUN_MODE = 1, + OUTCTRL_SHFT = 0, + BYPASSNL_SHFT = 1, + RESET_SHFT = 2, +}; + +enum apss_gfmux { + GFMUX_SRC_SEL_BMSK = 0x3, + APCS_SRC_EARLY = 0x2, +}; + static struct sc7180_gcc *const gcc = (void *)GCC_BASE; static struct sc7180_aoss *const aoss = (void *)AOSS_CC_BASE; +static struct sc7180_apss_clock *const apss_silver = (void *)SILVER_PLL_BASE; +static struct sc7180_apss_clock *const apss_l3 = (void *)L3_PLL_BASE; void clock_init(void); void clock_reset_aop(void);