diff options
author | Taniya Das <tdas@codeaurora.org> | 2021-02-11 15:58:29 +0530 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2021-09-03 16:45:37 +0000 |
commit | 3fe6c03a393453ba9670f1055279c89c78d01e49 (patch) | |
tree | 4261df1525aa94e2fcdbf3d814058ac7aa63972e /src | |
parent | 6239e1b2520c4083813c041500c109bf46bdd110 (diff) |
qualcomm/sc7280: Move to use common clock driver for sc7280
It supports the clock consumers for QUP, SDCC, PCIE, Display to be able
to configure & enable the desired clocks.
The clock driver also supports reset of subsystems like AOP and SHRM.
Also add support for Zonda PLL enable for CPU in common clock driver.
Refactor the SC7280 clock driver to use the common clock driver APIs.
BUG=b:182963902
TEST=Validated on qualcomm sc7280 development board
Change-Id: I590a93cda0d6eccb51b54692b620d43ccacede77
Signed-off-by: Taniya Das <tdas@codeaurora.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/50580
Reviewed-by: Martin Roth <martinroth@google.com>
Reviewed-by: Shelley Chen <shchen@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/soc/qualcomm/common/clock.c | 23 | ||||
-rw-r--r-- | src/soc/qualcomm/common/include/soc/clock_common.h | 2 | ||||
-rw-r--r-- | src/soc/qualcomm/sc7280/Makefile.inc | 2 | ||||
-rw-r--r-- | src/soc/qualcomm/sc7280/clock.c | 490 | ||||
-rw-r--r-- | src/soc/qualcomm/sc7280/include/soc/addressmap.h | 7 | ||||
-rw-r--r-- | src/soc/qualcomm/sc7280/include/soc/clock.h | 390 |
6 files changed, 914 insertions, 0 deletions
diff --git a/src/soc/qualcomm/common/clock.c b/src/soc/qualcomm/common/clock.c index e83f979e81..09cd95c88a 100644 --- a/src/soc/qualcomm/common/clock.c +++ b/src/soc/qualcomm/common/clock.c @@ -236,6 +236,29 @@ enum cb_err agera_pll_enable(struct alpha_pll_reg_val_config *cfg) return CB_SUCCESS; } +enum cb_err zonda_pll_enable(struct alpha_pll_reg_val_config *cfg) +{ + setbits32(cfg->reg_mode, BIT(PLL_BYPASSNL_SHFT)); + + /* + * H/W requires a 1us delay between disabling the bypass and + * de-asserting the reset. + */ + udelay(1); + setbits32(cfg->reg_mode, BIT(PLL_RESET_SHFT)); + setbits32(cfg->reg_opmode, PLL_RUN_MODE); + + if (!wait_us(100, read32(cfg->reg_mode) & PLL_LOCK_DET_BMSK)) { + printk(BIOS_ERR, "ERROR: CPU PLL did not lock!\n"); + return CB_ERR; + } + + setbits32(cfg->reg_user_ctl, PLL_USERCTL_BMSK); + setbits32(cfg->reg_mode, BIT(PLL_OUTCTRL_SHFT)); + + return CB_SUCCESS; +} + /* Bring subsystem out of RESET */ void clock_reset_subsystem(u32 *misc, u32 shft) { diff --git a/src/soc/qualcomm/common/include/soc/clock_common.h b/src/soc/qualcomm/common/include/soc/clock_common.h index b9241944c2..0911827149 100644 --- a/src/soc/qualcomm/common/include/soc/clock_common.h +++ b/src/soc/qualcomm/common/include/soc/clock_common.h @@ -155,6 +155,8 @@ enum cb_err clock_configure_enable_gpll(struct alpha_pll_reg_val_config *cfg, bool enable, int br_enable); enum cb_err agera_pll_enable(struct alpha_pll_reg_val_config *cfg); +enum cb_err zonda_pll_enable(struct alpha_pll_reg_val_config *cfg); + struct aoss { u8 _res0[0x50020]; u32 aoss_cc_reset_status; diff --git a/src/soc/qualcomm/sc7280/Makefile.inc b/src/soc/qualcomm/sc7280/Makefile.inc index 3c34be010c..b44c754c16 100644 --- a/src/soc/qualcomm/sc7280/Makefile.inc +++ b/src/soc/qualcomm/sc7280/Makefile.inc @@ -3,6 +3,8 @@ ifeq ($(CONFIG_SOC_QUALCOMM_SC7280),y) all-y += ../common/timer.c all-y += spi.c all-y += ../common/gpio.c +all-y += ../common/clock.c +all-y += clock.c ################################################################################ bootblock-y += bootblock.c diff --git a/src/soc/qualcomm/sc7280/clock.c b/src/soc/qualcomm/sc7280/clock.c new file mode 100644 index 0000000000..871fb9bbd8 --- /dev/null +++ b/src/soc/qualcomm/sc7280/clock.c @@ -0,0 +1,490 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <assert.h> +#include <commonlib/helpers.h> +#include <delay.h> +#include <device/mmio.h> +#include <soc/clock.h> +#include <timer.h> +#include <types.h> + +static struct clock_freq_config qspi_core_cfg[] = { + { + .hz = SRC_XO_HZ, /* 19.2KHz */ + .src = SRC_XO_19_2MHZ, + .div = QCOM_CLOCK_DIV(1), + }, + { + .hz = 100 * MHz, + .src = SRC_GPLL0_MAIN_600MHZ, + .div = QCOM_CLOCK_DIV(6), + }, + { + .hz = 150 * MHz, + .src = SRC_GPLL0_MAIN_600MHZ, + .div = QCOM_CLOCK_DIV(4), + }, + { + .hz = 200 * MHz, + .src = SRC_GPLL0_MAIN_600MHZ, + .div = QCOM_CLOCK_DIV(3), + }, + { + .hz = 400 * MHz, + .src = SRC_GPLL0_MAIN_600MHZ, + .div = QCOM_CLOCK_DIV(1.5), + }, +}; + +static struct clock_freq_config qupv3_wrap_cfg[] = { + { + .hz = SRC_XO_HZ, /* 19.2KHz */ + .src = SRC_XO_19_2MHZ, + .div = QCOM_CLOCK_DIV(1), + }, + { + .hz = 32 * MHz, + .src = SRC_GPLL0_EVEN_300MHZ, + .div = QCOM_CLOCK_DIV(1), + .m = 8, + .n = 75, + .d_2 = 75, + }, + { + .hz = 48 * MHz, + .src = SRC_GPLL0_EVEN_300MHZ, + .div = QCOM_CLOCK_DIV(1), + .m = 4, + .n = 25, + .d_2 = 25, + }, + { + .hz = 64 * MHz, + .src = SRC_GPLL0_EVEN_300MHZ, + .div = QCOM_CLOCK_DIV(1), + .m = 16, + .n = 75, + .d_2 = 75, + }, + { + .hz = 96 * MHz, + .src = SRC_GPLL0_EVEN_300MHZ, + .div = QCOM_CLOCK_DIV(1), + .m = 8, + .n = 25, + .d_2 = 25, + }, + { + .hz = 100 * MHz, + .src = SRC_GPLL0_MAIN_600MHZ, + .div = QCOM_CLOCK_DIV(6), + }, + { + .hz = SRC_XO_HZ, /* 19.2KHz */ + .src = SRC_XO_19_2MHZ, + .div = QCOM_CLOCK_DIV(1), + }, + { + .hz = SRC_XO_HZ, /* 19.2KHz */ + .src = SRC_XO_19_2MHZ, + .div = QCOM_CLOCK_DIV(1), + }, +}; + +static struct clock_freq_config sdcc1_core_cfg[] = { + { + .hz = 100 * MHz, + .src = SRC_GPLL0_EVEN_300MHZ, + .div = QCOM_CLOCK_DIV(3), + }, + { + .hz = 192 * MHz, + .src = SRC_GPLL10_MAIN_384MHZ, + .div = QCOM_CLOCK_DIV(2), + }, + { + .hz = 384 * MHz, + .src = SRC_GPLL10_MAIN_384MHZ, + .div = QCOM_CLOCK_DIV(1), + }, +}; + +static struct clock_freq_config sdcc2_core_cfg[] = { + { + .hz = 50 * MHz, + .src = SRC_GPLL0_EVEN_300MHZ, + .div = QCOM_CLOCK_DIV(6), + }, + { + .hz = 202 * MHz, + .src = SRC_GPLL9_MAIN_808MHZ, + .div = QCOM_CLOCK_DIV(4), + }, +}; + +static struct pcie pcie_cfg[] = { + [PCIE_1_GDSC] = { + .gdscr = &gcc->pcie_1.gdscr, + }, + [PCIE_1_SLV_Q2A_AXI_CLK] = { + .clk = &gcc->pcie_1.slv_q2a_axi_cbcr, + .clk_br_en = &gcc->apcs_clk_br_en, + .vote_bit = PCIE_1_SLV_Q2A_AXI_CLK_ENA, + }, + [PCIE_1_SLV_AXI_CLK] = { + .clk = &gcc->pcie_1.slv_axi_cbcr, + .clk_br_en = &gcc->apcs_clk_br_en, + .vote_bit = PCIE_1_SLV_AXI_CLK_ENA, + }, + [PCIE_1_MSTR_AXI_CLK] = { + .clk = &gcc->pcie_1.mstr_axi_cbcr, + .clk_br_en = &gcc->apcs_clk_br_en, + .vote_bit = PCIE_1_MSTR_AXI_CLK_ENA, + }, + [PCIE_1_CFG_AHB_CLK] = { + .clk = &gcc->pcie_1.cfg_ahb_cbcr, + .clk_br_en = &gcc->apcs_clk_br_en, + .vote_bit = PCIE_1_CFG_AHB_CLK_ENA, + }, + [PCIE_1_AUX_CLK] = { + .clk = &gcc->pcie_1.aux_cbcr, + .clk_br_en = &gcc->apcs_clk_br_en, + .vote_bit = PCIE_1_AUX_CLK_ENA, + }, + [AGGRE_NOC_PCIE_TBU_CLK] = { + .clk = &gcc->aggre_noc_pcie_tbu_cbcr, + .clk_br_en = &gcc->apcs_clk_br_en, + .vote_bit = AGGRE_NOC_PCIE_TBU_CLK_ENA, + }, + [AGGRE_NOC_PCIE_1_AXI_CLK] = { + .clk = &gcc->pcie_1.aggre_noc_pcie_axi_cbcr, + .clk_br_en = &gcc->apcs_clk_br_en, + .vote_bit = AGGRE_NOC_PCIE_1_AXI_CLK_ENA, + }, + [DDRSS_PCIE_SF_CLK] = { + .clk = &gcc->pcie_1.ddrss_pcie_sf_cbcr, + .clk_br_en = &gcc->apcs_clk_br_en, + .vote_bit = DDRSS_PCIE_SF_CLK_ENA, + }, + [PCIE1_PHY_RCHNG_CLK] = { + .clk = &gcc->pcie_1.phy_rchng_cbcr, + .clk_br_en = &gcc->apcs_clk_br_en, + .vote_bit = PCIE1_PHY_RCHNG_CLK_ENA, + }, + [AGGRE_NOC_PCIE_CENTER_SF_AXI_CLK] = { + .clk = &gcc->pcie_1.aggre_noc_pcie_center_sf_axi_cbcr, + .clk_br_en = &gcc->apcs_clk_br_en1, + .vote_bit = AGGRE_NOC_PCIE_CENTER_SF_AXI_CLK_ENA, + }, + [PCIE_1_PIPE_CLK] = { + .clk = &gcc->pcie_1.pipe_cbcr, + .clk_br_en = &gcc->apcs_clk_br_en, + .vote_bit = PCIE_1_PIPE_CLK_ENA, + }, + [PCIE_CLKREF_EN] = { + .clk = &gcc->pcie_clkref_en, + .vote_bit = NO_VOTE_BIT, + }, + [GCC_PCIE_1_PIPE_MUXR] = { + .clk = &gcc->pcie_1.pipe_muxr, + .vote_bit = NO_VOTE_BIT, + }, +}; + +static struct clock_freq_config mdss_mdp_cfg[] = { + { + .hz = 200 * MHz, + .src = SRC_GCC_DISP_GPLL0_CLK, + .div = QCOM_CLOCK_DIV(3), + }, + { + .hz = 300 * MHz, + .src = SRC_GCC_DISP_GPLL0_CLK, + .div = QCOM_CLOCK_DIV(2), + }, +}; + +static struct clock_rcg_mnd *mdss_clock[MDSS_CLK_COUNT] = { + [MDSS_CLK_PCLK0] = &mdss->pclk0, + [MDSS_CLK_MDP] = &mdss->mdp, + [MDSS_CLK_VSYNC] = &mdss->vsync, + [MDSS_CLK_ESC0] = &mdss->esc0, + [MDSS_CLK_BYTE0] = &mdss->byte0, + [MDSS_CLK_BYTE0_INTF] = &mdss->byte0, + [MDSS_CLK_AHB] = &mdss->ahb, +}; + +static u32 *mdss_cbcr[MDSS_CLK_COUNT] = { + [GCC_DISP_AHB] = &gcc->disp_ahb_cbcr, + [GCC_DISP_HF_AXI] = &gcc->disp_hf_axi_cbcr, + [GCC_DISP_SF_AXI] = &gcc->disp_sf_axi_cbcr, + [MDSS_CLK_PCLK0] = &mdss->pclk0_cbcr, + [MDSS_CLK_MDP] = &mdss->mdp_cbcr, + [MDSS_CLK_VSYNC] = &mdss->vsync_cbcr, + [MDSS_CLK_BYTE0] = &mdss->byte0_cbcr, + [MDSS_CLK_BYTE0_INTF] = &mdss->byte0_intf_cbcr, + [MDSS_CLK_ESC0] = &mdss->esc0_cbcr, + [MDSS_CLK_AHB] = &mdss->ahb_cbcr, +}; + +static u32 *gdsc[MAX_GDSC] = { + [PCIE_1_GDSC] = &gcc->pcie_1.gdscr, + [MDSS_CORE_GDSC] = &mdss->core_gdsc, +}; + +static enum cb_err clock_configure_gpll0(void) +{ + struct alpha_pll_reg_val_config gpll0_cfg = {0}; + + gpll0_cfg.reg_user_ctl = &gcc->gpll0.user_ctl; + gpll0_cfg.user_ctl_val = (1 << PLL_POST_DIV_EVEN_SHFT | + 3 << PLL_POST_DIV_ODD_SHFT | + 1 << PLL_PLLOUT_EVEN_SHFT | + 1 << PLL_PLLOUT_MAIN_SHFT | + 1 << PLL_PLLOUT_ODD_SHFT); + + return clock_configure_enable_gpll(&gpll0_cfg, false, 0); +} + +void clock_configure_qspi(uint32_t hz) +{ + clock_configure(&gcc->qspi_core, + qspi_core_cfg, hz, + ARRAY_SIZE(qspi_core_cfg)); + clock_enable(&gcc->qspi_cnoc_ahb_cbcr); + clock_enable(&gcc->qspi_core_cbcr); +} + + +void clock_enable_qup(int qup) +{ + struct qupv3_clock *qup_clk; + int s = qup % QUP_WRAP1_S0, clk_en_off; + + qup_clk = qup < QUP_WRAP1_S0 ? + &gcc->qup_wrap0_s[s] : &gcc->qup_wrap1_s[s]; + + if (qup < QUP_WRAP1_S6) { + clk_en_off = qup < QUP_WRAP1_S0 ? + QUPV3_WRAP0_CLK_ENA_S(s) : QUPV3_WRAP1_CLK_ENA_S(s); + clock_enable_vote(&qup_clk->cbcr, &gcc->apcs_clk_br_en1, + clk_en_off); + } else { + clk_en_off = QUPV3_WRAP1_CLK_ENA_1_S(s); + clock_enable_vote(&qup_clk->cbcr, &gcc->apcs_clk_br_en, + clk_en_off); + } +} + +void clock_configure_sdcc(enum clk_sdcc sdcc, uint32_t hz) +{ + if (sdcc == SDCC1_CLK) { + if (hz > CLK_100MHZ) { + struct alpha_pll_reg_val_config gpll10_cfg = {0}; + gpll10_cfg.reg_mode = &gcc->gpll10.mode; + gpll10_cfg.reg_opmode = &gcc->gpll10.opmode; + gpll10_cfg.reg_l = &gcc->gpll10.l; + gpll10_cfg.l_val = 0x14; + gpll10_cfg.reg_cal_l = &gcc->gpll10.cal_l; + gpll10_cfg.cal_l_val = 0x44; + gpll10_cfg.fsm_enable = true; + gpll10_cfg.reg_apcs_pll_br_en = &gcc->apcs_pll_br_en; + clock_configure_enable_gpll(&gpll10_cfg, true, 9); + } + clock_configure((struct clock_rcg *)&gcc->sdcc1, sdcc1_core_cfg, + hz, ARRAY_SIZE(sdcc1_core_cfg)); + clock_enable(&gcc->sdcc1_ahb_cbcr); + clock_enable(&gcc->sdcc1_apps_cbcr); + } else if (sdcc == SDCC2_CLK) { + if (hz > CLK_100MHZ) { + struct alpha_pll_reg_val_config gpll9_cfg = {0}; + gpll9_cfg.reg_mode = &gcc->gpll9.mode; + gpll9_cfg.reg_opmode = &gcc->gpll9.opmode; + gpll9_cfg.reg_alpha = &gcc->gpll9.alpha; + gpll9_cfg.alpha_val = 0x1555; + gpll9_cfg.reg_l = &gcc->gpll9.l; + gpll9_cfg.l_val = 0x2A; + gpll9_cfg.reg_cal_l = &gcc->gpll9.cal_l; + gpll9_cfg.cal_l_val = 0x44; + gpll9_cfg.fsm_enable = true; + gpll9_cfg.reg_apcs_pll_br_en = &gcc->apcs_pll_br_en; + clock_configure_enable_gpll(&gpll9_cfg, true, 8); + } + clock_configure((struct clock_rcg *)&gcc->sdcc2, sdcc2_core_cfg, + hz, ARRAY_SIZE(sdcc2_core_cfg)); + clock_enable(&gcc->sdcc2_ahb_cbcr); + clock_enable(&gcc->sdcc2_apps_cbcr); + } +} + +void clock_configure_dfsr(int qup) +{ + clock_configure_dfsr_table(qup, qupv3_wrap_cfg, + ARRAY_SIZE(qupv3_wrap_cfg)); +} + +static enum cb_err pll_init_and_set(struct sc7280_apss_clock *apss, u32 l_val) +{ + struct alpha_pll_reg_val_config pll_cfg = {0}; + int ret; + u32 gfmux_val, regval; + + pll_cfg.reg_l = &apss->pll.l; + pll_cfg.l_val = l_val; + + pll_cfg.reg_config_ctl = &apss->pll.config_ctl_lo; + pll_cfg.reg_config_ctl_hi = &apss->pll.config_ctl_hi; + pll_cfg.reg_config_ctl_hi1 = &apss->pll.config_ctl_u1; + + regval = read32(&apss->pll.config_ctl_lo); + pll_cfg.config_ctl_val = regval & + (~(0x2 << K_P_SHFT | 0x2 << K_I_SHFT)); + + regval = read32(&apss->pll.config_ctl_hi); + pll_cfg.config_ctl_hi_val = (regval | (BIT(KLSB_SHFT) | + BIT(RON_MODE_SHFT))) & (~(0x4 << KLSB_SHFT)); + + regval = read32(&apss->pll.config_ctl_u1); + pll_cfg.config_ctl_hi1_val = (regval | BIT(FAST_LOCK_LOW_L_SHFT)) & + ~BIT(DCO_BIAS_ADJ_SHFT); + + ret = clock_configure_enable_gpll(&pll_cfg, false, 0); + if (ret != CB_SUCCESS) + return CB_ERR; + + pll_cfg.reg_mode = &apss->pll.mode; + pll_cfg.reg_opmode = &apss->pll.opmode; + pll_cfg.reg_user_ctl = &apss->pll.user_ctl; + + ret = zonda_pll_enable(&pll_cfg); + if (ret != CB_SUCCESS) + return CB_ERR; + + gfmux_val = read32(&apss->cfg_gfmux) & ~GFMUX_SRC_SEL_BMSK; + gfmux_val |= APCS_SRC_EARLY; + write32(&apss->cfg_gfmux, gfmux_val); + + return CB_SUCCESS; +} + +enum cb_err clock_enable_gdsc(enum clk_gdsc gdsc_type) +{ + if (gdsc_type > MAX_GDSC) + return CB_ERR; + + return enable_and_poll_gdsc_status(gdsc[gdsc_type]); +} + +enum cb_err mdss_clock_configure(enum clk_mdss clk_type, uint32_t hz, + uint32_t source, uint32_t divider, uint32_t m, + uint32_t n, uint32_t d_2) +{ + struct clock_freq_config mdss_clk_cfg; + uint32_t idx; + + if (clk_type >= MDSS_CLK_COUNT) + return CB_ERR; + + /* Initialize it with received arguments */ + mdss_clk_cfg.div = divider ? QCOM_CLOCK_DIV(divider) : 0; + + if (clk_type == MDSS_CLK_MDP) { + for (idx = 0; idx < ARRAY_SIZE(mdss_mdp_cfg); idx++) { + if (hz <= mdss_mdp_cfg[idx].hz) { + source = mdss_mdp_cfg[idx].src; + mdss_clk_cfg.div = mdss_mdp_cfg[idx].div; + m = 0; + break; + } + } + } + mdss_clk_cfg.src = source; + mdss_clk_cfg.m = m; + mdss_clk_cfg.n = n; + mdss_clk_cfg.d_2 = d_2; + + return clock_configure((struct clock_rcg *)mdss_clock[clk_type], + &mdss_clk_cfg, hz, 0); +} + +enum cb_err mdss_clock_enable(enum clk_mdss clk_type) +{ + if (clk_type >= MDSS_CLK_COUNT) + return CB_ERR; + + /* Enable clock*/ + return clock_enable(mdss_cbcr[clk_type]); +} + +enum cb_err clock_enable_pcie(enum clk_pcie clk_type) +{ + int clk_vote_bit; + + if (clk_type >= PCIE_CLK_COUNT) + return CB_ERR; + + clk_vote_bit = pcie_cfg[clk_type].vote_bit; + if (clk_vote_bit < 0) + return clock_enable(pcie_cfg[clk_type].clk); + + clock_enable_vote(pcie_cfg[clk_type].clk, + pcie_cfg[clk_type].clk_br_en, + pcie_cfg[clk_type].vote_bit); + + return CB_SUCCESS; +} + +enum cb_err clock_configure_mux(enum clk_pcie clk_type, u32 src_type) +{ + if (clk_type >= PCIE_CLK_COUNT) + return CB_ERR; + + /* Set clock src */ + write32(pcie_cfg[clk_type].clk, src_type); + + return CB_SUCCESS; +} + +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"); + + /* 1190.4 MHz */ + if (!pll_init_and_set(apss_l3, L_VAL_1190P4MHz)) + printk(BIOS_DEBUG, "L3 Frequency bumped to 1.1904(GHz)\n"); +} + +void clock_init(void) +{ + clock_configure_gpll0(); + + clock_enable_vote(&gcc->qup_wrap0_core_2x_cbcr, + &gcc->apcs_clk_br_en1, + QUPV3_WRAP0_CORE_2X_CLK_ENA); + clock_enable_vote(&gcc->qup_wrap0_core_cbcr, + &gcc->apcs_clk_br_en1, + QUPV3_WRAP0_CORE_CLK_ENA); + clock_enable_vote(&gcc->qup_wrap0_m_ahb_cbcr, + &gcc->apcs_clk_br_en1, + QUPV3_WRAP_0_M_AHB_CLK_ENA); + clock_enable_vote(&gcc->qup_wrap0_s_ahb_cbcr, + &gcc->apcs_clk_br_en1, + QUPV3_WRAP_0_S_AHB_CLK_ENA); + + clock_enable_vote(&gcc->qup_wrap1_core_2x_cbcr, + &gcc->apcs_clk_br_en1, + QUPV3_WRAP1_CORE_2X_CLK_ENA); + clock_enable_vote(&gcc->qup_wrap1_core_cbcr, + &gcc->apcs_clk_br_en1, + QUPV3_WRAP1_CORE_CLK_ENA); + clock_enable_vote(&gcc->qup_wrap1_m_ahb_cbcr, + &gcc->apcs_clk_br_en1, + QUPV3_WRAP_1_M_AHB_CLK_ENA); + 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/sc7280/include/soc/addressmap.h b/src/soc/qualcomm/sc7280/include/soc/addressmap.h index 5b515bd2d1..82c84ae2f8 100644 --- a/src/soc/qualcomm/sc7280/include/soc/addressmap.h +++ b/src/soc/qualcomm/sc7280/include/soc/addressmap.h @@ -5,6 +5,13 @@ #include <stdint.h> +#define AOSS_CC_BASE 0x0C2A0000 +#define DISP_CC_BASE 0x0AF00000 +#define GCC_BASE 0x00100000 +#define L3_PLL_BASE 0x18284000 +#define QSPI_BASE 0x088DC000 +#define SHRM_SPROC_BASE 0x09051000 +#define SILVER_PLL_BASE 0x18280000 #define TLMM_TILE_BASE 0x0F100000 #endif /* __SOC_QUALCOMM_SC7280_ADDRESS_MAP_H__ */ diff --git a/src/soc/qualcomm/sc7280/include/soc/clock.h b/src/soc/qualcomm/sc7280/include/soc/clock.h new file mode 100644 index 0000000000..a0694ba6bc --- /dev/null +++ b/src/soc/qualcomm/sc7280/include/soc/clock.h @@ -0,0 +1,390 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <soc/addressmap.h> +#include <types.h> +#include <soc/clock_common.h> + +#ifndef __SOC_QUALCOMM_SC7280_CLOCK_H__ +#define __SOC_QUALCOMM_SC7280_CLOCK_H__ + +#define SRC_XO_HZ (19200 * KHz) +#define GPLL0_EVEN_HZ (300 * MHz) +#define GPLL0_MAIN_HZ (600 * MHz) +#define CLK_100MHZ (100 * MHz) + +/* CPU PLL */ +#define L_VAL_1516P8MHz 0x4F +#define L_VAL_1190P4MHz 0x3E + +#define QUPV3_WRAP0_CLK_ENA_S(idx) (10 + idx) +#define QUPV3_WRAP1_CLK_ENA_S(idx) (22 + idx) +#define QUPV3_WRAP1_CLK_ENA_1_S(idx) (7 + idx) + +enum clk_pll_src { + SRC_XO_19_2MHZ = 0, + SRC_GPLL0_MAIN_600MHZ = 1, + SRC_GPLL9_MAIN_808MHZ = 2, + SRC_GCC_DISP_GPLL0_CLK = 4, + SRC_GPLL10_MAIN_384MHZ = 5, + SRC_GPLL0_EVEN_300MHZ = 6, +}; + +enum clk_pcie_src_sel { + PCIE_1_PIPE_SRC_SEL = 0, + PCIE_1_XO_SRC_SEL = 2, +}; + +enum apcs_branch_en_vote { + QUPV3_WRAP_0_M_AHB_CLK_ENA = 6, + QUPV3_WRAP_0_S_AHB_CLK_ENA = 7, + QUPV3_WRAP0_CORE_CLK_ENA = 8, + QUPV3_WRAP0_CORE_2X_CLK_ENA = 9, + AGGRE_NOC_PCIE_1_AXI_CLK_ENA = 11, + QUPV3_WRAP1_CORE_2X_CLK_ENA = 18, + AGGRE_NOC_PCIE_TBU_CLK_ENA = 18, + QUPV3_WRAP1_CORE_CLK_ENA = 19, + DDRSS_PCIE_SF_CLK_ENA = 19, + QUPV3_WRAP_1_M_AHB_CLK_ENA = 20, + QUPV3_WRAP_1_S_AHB_CLK_ENA = 21, + PCIE1_PHY_RCHNG_CLK_ENA = 23, + PCIE_1_SLV_Q2A_AXI_CLK_ENA = 25, + PCIE_1_SLV_AXI_CLK_ENA = 26, + PCIE_1_MSTR_AXI_CLK_ENA = 27, + PCIE_1_CFG_AHB_CLK_ENA = 28, + AGGRE_NOC_PCIE_CENTER_SF_AXI_CLK_ENA = 28, + PCIE_1_AUX_CLK_ENA = 29, + PCIE_1_PIPE_CLK_ENA = 30, + NO_VOTE_BIT = -1, +}; + +struct sc7280_gpll { + u32 mode; + u32 l; + u32 cal_l; + u32 user_ctl; + u32 user_ctl_u; + u32 user_ctl_u1; + u32 config_ctl; + u32 config_ctl_u; + u32 config_ctl_u1; + u32 test_ctl; + u32 test_ctl_u; + u32 test_ctl_u1; + u8 _res0[0x38 - 0x30]; + u32 opmode; + u8 _res1[0x40 - 0x3c]; + u32 alpha; +}; + +struct sc7280_disp_cc { + u8 _res0[0x1004]; + u32 core_gdsc; + u8 _res1[0x1010 - 0x1008]; + u32 pclk0_cbcr; + u32 mdp_cbcr; + u8 _res2[0x102c - 0x1018]; + u32 vsync_cbcr; + u32 byte0_cbcr; + u32 byte0_intf_cbcr; + u32 esc0_cbcr; + u8 _res3[0x1050 - 0x103c]; + u32 ahb_cbcr; + u8 _res4[0x1078 - 0x1054]; + struct clock_rcg_mnd pclk0; + u8 _res5[0x1090 - 0x108c]; + struct clock_rcg_mnd mdp; + u8 _res6[0x10c0 - 0x1098]; + struct clock_rcg_mnd vsync; + u8 _res7[0x10d8 - 0x10c8]; + struct clock_rcg_mnd byte0; + u8 _res8[0x10f4 - 0x10ec]; + struct clock_rcg_mnd esc0; + u8 _res9[0x1170 - 0x1108]; + struct clock_rcg_mnd ahb; + u8 _res10[0x20000 - 0x1178]; +}; +check_member(sc7280_disp_cc, pclk0_cbcr, 0x1010); +check_member(sc7280_disp_cc, vsync_cbcr, 0x102c); +check_member(sc7280_disp_cc, ahb_cbcr, 0x1050); + +struct sc7280_pcie { + u32 pcie_1_bcr; + u32 gdscr; + u8 _res1[0x18d010 - 0x18d008]; + u32 slv_q2a_axi_cbcr; + u32 slv_axi_cbcr; + u8 _res2[0x18d01c - 0x18d018]; + u32 mstr_axi_cbcr; + u8 _res3[0x18d024 - 0x18d020]; + u32 cfg_ahb_cbcr; + u32 aux_cbcr; + u8 _res4[0x18d030 - 0x18d02c]; + u32 pipe_cbcr; + u8 _res5[0x18d038 - 0x18d034]; + u32 phy_rchng_cbcr; + u8 _res6[0x18d054 - 0x18d03c]; + u32 pipe_muxr; + u8 _res7[0x18d080 - 0x18d058]; + u32 ddrss_pcie_sf_cbcr; + u32 aggre_noc_pcie_axi_cbcr; + u32 aggre_noc_pcie_center_sf_axi_cbcr; + u8 _res8[0x18e01c - 0x18d08c]; + u32 phy_bcr; +}; +check_member(sc7280_pcie, slv_q2a_axi_cbcr, 0x10); +check_member(sc7280_pcie, mstr_axi_cbcr, 0x1c); +check_member(sc7280_pcie, pipe_cbcr, 0x30); +check_member(sc7280_pcie, ddrss_pcie_sf_cbcr, 0x80); +check_member(sc7280_pcie, phy_bcr, 0x101c); + +struct sc7280_gcc { + struct sc7280_gpll gpll0; + u8 _res0[0xf000 - 0x44]; + u32 usb30_prim_bcr; + u8 _res1[0x12000 - 0xf004]; + u32 qusb2phy_prim_bcr; + u32 qusb2phy_sec_bcr; + u8 _res2[0x14004 - 0x12008]; + u32 sdcc2_apps_cbcr; + u32 sdcc2_ahb_cbcr; + struct clock_rcg_mnd sdcc2; + u8 _res3[0x16004 - 0x14020]; + u32 sdcc4_apps_cbcr; + u32 sdcc4_ahb_cbcr; + struct clock_rcg_mnd sdcc4; + u8 _res4[0x17000 - 0x16020]; + u32 qup_wrap0_bcr; + u32 qup_wrap0_m_ahb_cbcr; + u32 qup_wrap0_s_ahb_cbcr; + struct qupv3_clock qup_wrap0_s[8]; + u8 _res5[0x18000 - 0x1798c]; + u32 qup_wrap1_bcr; + u32 qup_wrap1_m_ahb_cbcr; + u32 qup_wrap1_s_ahb_cbcr; + struct qupv3_clock qup_wrap1_s[8]; + u8 _res6[0x1c000 - 0x1898c]; + struct sc7280_gpll gpll9; + u8 _res7[0x1e000 - 0x1c044]; + struct sc7280_gpll gpll10; + u8 _res8[0x23000 - 0x1e044]; + u32 qup_wrap0_core_cbcr; + u32 qup_wrap0_core_cdivr; + u32 qup_wrap0_core_2x_cbcr; + struct clock_rcg qup_wrap0_core_2x; + u8 _res9[0x23138 - 0x23014]; + u32 qup_wrap1_core_cbcr; + u32 qup_wrap1_core_cdivr; + u32 qup_wrap1_core_2x_cbcr; + struct clock_rcg qup_wrap1_core_2x; + u8 _res10[0x27004 - 0x2314c]; + u32 disp_ahb_cbcr; + u8 _res11[0x2700c - 0x27008]; + u32 disp_hf_axi_cbcr; + u8 _res12[0x27014 - 0x27010]; + u32 disp_sf_axi_cbcr; + u8 _res13[0x4b000 - 0x27018]; + u32 qspi_bcr; + u32 qspi_cnoc_ahb_cbcr; + u32 qspi_core_cbcr; + struct clock_rcg qspi_core; + u8 _res14[0x50000 - 0x4b014]; + u32 usb3_phy_prim_bcr; + u32 usb3phy_phy_prim_bcr; + u32 usb3_dp_phy_prim_bcr; + u8 _res15[0x52000 - 0x5000c]; + u32 apcs_clk_br_en; + u8 _res16[0x52008 - 0x52004]; + u32 apcs_clk_br_en1; + u8 _res17[0x52010 - 0x5200c]; + u32 apcs_pll_br_en; + u8 _res18[0x6a000 - 0x52014]; + u32 usb_phy_cfg_ahb2phy_bcr; + u8 _res19[0x75004 - 0x6a004]; + u32 sdcc1_ahb_cbcr; + u32 sdcc1_apps_cbcr; + struct clock_rcg_mnd sdcc1; + u8 _res20[0x8c004 - 0x75020]; + u32 pcie_clkref_en; + u8 _res21[0x8d000 - 0x8c008]; + struct sc7280_pcie pcie_1; + u8 _res22[0x90010 - 0x8e020]; + u32 aggre_noc_pcie_tbu_cbcr; + u8 _res23[0x9e000 - 0x90014]; + u32 usb30_sec_bcr; + u8 _res24[0x1000000 - 0x90014]; +}; +check_member(sc7280_gcc, qusb2phy_prim_bcr, 0x12000); +check_member(sc7280_gcc, sdcc2_apps_cbcr, 0x14004); +check_member(sc7280_gcc, sdcc4_apps_cbcr, 0x16004); +check_member(sc7280_gcc, qup_wrap0_bcr, 0x17000); +check_member(sc7280_gcc, qup_wrap1_bcr, 0x18000); +check_member(sc7280_gcc, qup_wrap1_core_cbcr, 0x23138); +check_member(sc7280_gcc, qspi_bcr, 0x4b000); +check_member(sc7280_gcc, usb3_phy_prim_bcr, 0x50000); +check_member(sc7280_gcc, apcs_clk_br_en1, 0x52008); +check_member(sc7280_gcc, apcs_pll_br_en, 0x52010); +check_member(sc7280_gcc, usb_phy_cfg_ahb2phy_bcr, 0x6a000); +check_member(sc7280_gcc, sdcc1_ahb_cbcr, 0x75004); +check_member(sc7280_gcc, pcie_clkref_en, 0x8c004); +check_member(sc7280_gcc, aggre_noc_pcie_tbu_cbcr, 0x90010); +check_member(sc7280_gcc, usb30_sec_bcr, 0x9e000); + + +struct sc7280_apss_pll { + u32 mode; + u32 l; + u32 alpha; + 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 sc7280_apss_clock { + struct sc7280_apss_pll pll; + u8 _res0[0x84 - 0x3c]; + u32 cfg_gfmux; +}; + +struct pcie { + uint32_t *gdscr; + uint32_t *clk; + uint32_t *clk_br_en; + int vote_bit; +}; + +enum clk_sdcc { + SDCC1_CLK, + SDCC2_CLK, +}; + +enum clk_qup { + QUP_WRAP0_S0, + QUP_WRAP0_S1, + QUP_WRAP0_S2, + QUP_WRAP0_S3, + QUP_WRAP0_S4, + QUP_WRAP0_S5, + QUP_WRAP0_S6, + QUP_WRAP0_S7, + QUP_WRAP1_S0, + QUP_WRAP1_S1, + QUP_WRAP1_S2, + QUP_WRAP1_S3, + QUP_WRAP1_S4, + QUP_WRAP1_S5, + QUP_WRAP1_S6, + QUP_WRAP1_S7, +}; + +enum clk_gdsc { + MDSS_CORE_GDSC, + PCIE_1_GDSC, + MAX_GDSC +}; + +enum clk_mdss { + GCC_DISP_AHB, + GCC_DISP_HF_AXI, + GCC_DISP_SF_AXI, + MDSS_CLK_PCLK0, + MDSS_CLK_MDP, + MDSS_CLK_VSYNC, + MDSS_CLK_BYTE0, + MDSS_CLK_BYTE0_INTF, + MDSS_CLK_ESC0, + MDSS_CLK_AHB, + MDSS_CLK_COUNT +}; + +enum clk_pcie { + PCIE_1_SLV_Q2A_AXI_CLK, + PCIE_1_SLV_AXI_CLK, + PCIE_1_MSTR_AXI_CLK, + PCIE_1_CFG_AHB_CLK, + PCIE_1_AUX_CLK, + AGGRE_NOC_PCIE_TBU_CLK, + AGGRE_NOC_PCIE_1_AXI_CLK, + DDRSS_PCIE_SF_CLK, + PCIE1_PHY_RCHNG_CLK, + AGGRE_NOC_PCIE_CENTER_SF_AXI_CLK, + PCIE_1_PIPE_CLK, + PCIE_CLKREF_EN, + GCC_PCIE_1_PIPE_MUXR, + PCIE_CLK_COUNT, +}; + +enum subsystem_reset { + AOP_RESET_SHFT = 0, + SHRM_RUN_STALL = 0, +}; + +enum pll_config_ctl_lo { + CTUNE_SHFT = 2, + K_I_SHFT = 4, + K_P_SHFT = 7, + PFA_MSB_SHFT = 10, + RES_BIT_SHFT = 14, + RON_DEGEN_MUL_SHFT = 18, + ALPHA_CAL_SHFT = 20, + DCO_ADDER_EN_SHFT = 22, + PLL_COUNTER_EN = 27, +}; + +enum pll_config_ctl_hi { + CUR_TRIM_SHFT = 0, + FREQ_DOUBLE_SHFT = 4, + ADJ_ENABLE_SHFT = 5, + ADJ_VALUE_SHFT = 6, + KLSB_SHFT = 13, + RON_MODE_SHFT = 17, + CHP_REF_SHFT = 19, + CHP_STARTUP = 21, + ADC_KMSB_VAL = 23, +}; + +enum pll_config_ctl_u1 { + FAST_LOCK_LOW_L_SHFT = 4, + DCO_BIAS_ADJ_SHFT = 26, +}; + +enum apss_gfmux { + GFMUX_SRC_SEL_BMSK = 0x3, + APCS_SRC_EARLY = 0x2, +}; + +static struct sc7280_gcc *const gcc = (void *)GCC_BASE; +static struct sc7280_apss_clock *const apss_silver = (void *)SILVER_PLL_BASE; +static struct sc7280_apss_clock *const apss_l3 = (void *)L3_PLL_BASE; +static struct sc7280_disp_cc *const mdss = (void *)DISP_CC_BASE; + +void clock_init(void); +void clock_configure_qspi(uint32_t hz); +void clock_enable_qup(int qup); +void clock_configure_sdcc(enum clk_sdcc, uint32_t hz); +void clock_configure_dfsr(int qup); +int clock_enable_gdsc(enum clk_gdsc gdsc_type); + +int mdss_clock_configure(enum clk_mdss clk_type, uint32_t hz, + uint32_t source, uint32_t divider, + uint32_t m, uint32_t n, uint32_t d); +int mdss_clock_enable(enum clk_mdss clk_type); +int clock_enable_pcie(enum clk_pcie clk_type); +int clock_configure_mux(enum clk_pcie clk_type, u32 src_type); + +/* Subsystem Reset */ +static struct aoss *const aoss = (void *)AOSS_CC_BASE; +static struct shrm *const shrm = (void *)SHRM_SPROC_BASE; + +#define clock_reset_aop() \ + clock_reset_subsystem(&aoss->aoss_cc_apcs_misc, AOP_RESET_SHFT) +#define clock_reset_shrm() \ + clock_reset_subsystem(&shrm->shrm_sproc_ctrl, SHRM_RUN_STALL) + +#endif // __SOC_QUALCOMM_SC7280_CLOCK_H__ |