diff options
-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__ |