From dc92cea680328c64865fc973500ec440d4795c2f Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Mon, 8 Jul 2019 12:00:51 +0530 Subject: sc7180: clock: Add display external clock in coreboot Add support for display external clock in coreboot for SC7180. Tested: Display clocks are configured. Change-Id: Ida222890252b80db738fa1f685b212b3f7c6e689 Signed-off-by: Taniya Das Reviewed-on: https://review.coreboot.org/c/coreboot/+/39612 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/soc/qualcomm/sc7180/clock.c | 70 +++++++++++++++++++++++- src/soc/qualcomm/sc7180/include/soc/addressmap.h | 1 + src/soc/qualcomm/sc7180/include/soc/clock.h | 41 +++++++++++--- 3 files changed, 103 insertions(+), 9 deletions(-) diff --git a/src/soc/qualcomm/sc7180/clock.c b/src/soc/qualcomm/sc7180/clock.c index 1683d70cbe..3702fa6ed4 100644 --- a/src/soc/qualcomm/sc7180/clock.c +++ b/src/soc/qualcomm/sc7180/clock.c @@ -104,6 +104,20 @@ struct clock_config qup_wrap_cfg[] = { }, }; +static struct sc7180_mnd_clock *mdss_clock[MDSS_CLK_COUNT] = { + [MDSS_CLK_ESC0] = &mdss->esc0, + [MDSS_CLK_PCLK0] = &mdss->pclk0, + [MDSS_CLK_BYTE0] = &mdss->byte0, + [MDSS_CLK_BYTE0_INTF] = &mdss->byte0, +}; + +static u32 *mdss_cbcr[MDSS_CLK_COUNT] = { + [MDSS_CLK_ESC0] = &mdss->esc0_cbcr, + [MDSS_CLK_PCLK0] = &mdss->pclk0_cbcr, + [MDSS_CLK_BYTE0] = &mdss->byte0_cbcr, + [MDSS_CLK_BYTE0_INTF] = &mdss->byte0_intf_cbcr, +}; + static int clock_configure_gpll0(void) { setbits32(&gcc->gpll0.user_ctl_u, 1 << SCALE_FREQ_SHFT); @@ -202,7 +216,7 @@ void clock_configure_qspi(uint32_t hz) qspi_core_cfg, hz, ARRAY_SIZE(qspi_core_cfg)); clock_enable(&gcc->qspi_cnoc_ahb_cbcr); - clock_enable(&gcc->qspi_core.cbcr); + clock_enable(&gcc->qspi_core_cbcr); } int clock_reset_bcr(void *bcr_addr, bool reset) @@ -323,11 +337,63 @@ static void speed_up_boot_cpu(void) printk(BIOS_DEBUG, "L3 Frequency bumped to 1.2096(GHz)\n"); } +int mdss_clock_configure(enum mdss_clock clk_type, uint32_t source, + uint32_t half_divider, uint32_t m, + uint32_t n, uint32_t d_2) +{ + struct clock_config mdss_clk_cfg; + uint32_t reg_val; + + if (clk_type >= MDSS_CLK_COUNT) + return -1; + + /* Initialize it with received arguments */ + mdss_clk_cfg.hz = 0; + mdss_clk_cfg.src = source; + + /* + * client is expected to provide 2n divider value, + * as the divider value in register is in form "2n-1" + */ + mdss_clk_cfg.div = half_divider ? (half_divider - 1) : 0; + mdss_clk_cfg.m = m; + mdss_clk_cfg.n = n; + mdss_clk_cfg.d_2 = d_2; + + /* configure and set the clock */ + reg_val = (mdss_clk_cfg.src << CLK_CTL_CFG_SRC_SEL_SHFT) | + (mdss_clk_cfg.div << CLK_CTL_CFG_SRC_DIV_SHFT); + + write32(&mdss_clock[clk_type]->clock.rcg_cfg, reg_val); + + /* Set m/n/d values for a specific clock */ + if (mdss_clk_cfg.m != 0) + clock_configure_mnd((struct sc7180_clock *)mdss_clock[clk_type], + mdss_clk_cfg.m, mdss_clk_cfg.n, mdss_clk_cfg.d_2); + + /* Commit config to RCG */ + setbits32(&mdss_clock[clk_type]->clock.rcg_cmd, + BIT(CLK_CTL_CMD_UPDATE_SHFT)); + + return 0; +} + +int mdss_clock_enable(enum mdss_clock clk_type) +{ + if (clk_type >= MDSS_CLK_COUNT) + return -1; + + /* Enable clock*/ + clock_enable(mdss_cbcr[clk_type]); + + return 0; +} + void clock_init(void) { clock_configure_gpll0(); - clock_enable_vote(&gcc->qup_wrap0_core_2x.cbcr, + 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, diff --git a/src/soc/qualcomm/sc7180/include/soc/addressmap.h b/src/soc/qualcomm/sc7180/include/soc/addressmap.h index 2b65e99396..29c60db56a 100644 --- a/src/soc/qualcomm/sc7180/include/soc/addressmap.h +++ b/src/soc/qualcomm/sc7180/include/soc/addressmap.h @@ -12,6 +12,7 @@ #define TLMM_WEST_TILE_BASE 0x03500000 #define SILVER_PLL_BASE 0x18280000 #define L3_PLL_BASE 0x18284000 +#define DISP_CC_BASE 0x0AF00000 /* * 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 d202605327..c9ecfb2a1f 100644 --- a/src/soc/qualcomm/sc7180/include/soc/clock.h +++ b/src/soc/qualcomm/sc7180/include/soc/clock.h @@ -32,7 +32,6 @@ #define SCALE_FREQ_SHFT 11 struct sc7180_clock { - u32 cbcr; u32 rcg_cmd; u32 rcg_cfg; }; @@ -58,6 +57,7 @@ struct sc7180_dfsr_clock { }; struct sc7180_qupv3_clock { + u32 cbcr; struct sc7180_mnd_clock mnd_clk; struct sc7180_dfsr_clock dfsr_clk; }; @@ -85,6 +85,7 @@ struct sc7180_gcc { u32 qup_wrap0_s_ahb_cbcr; u32 qup_wrap0_core_cbcr; u32 qup_wrap0_core_cdivr; + u32 qup_wrap0_core_2x_cbcr; struct sc7180_clock qup_wrap0_core_2x; u8 _res2[0x17030 - 0x17020]; struct sc7180_qupv3_clock qup_wrap0_s[6]; @@ -102,6 +103,7 @@ struct sc7180_gcc { u8 _res6[0x4b000 - 0x26004]; u32 qspi_bcr; u32 qspi_cnoc_ahb_cbcr; + u32 qspi_core_cbcr; struct sc7180_clock qspi_core; u8 _res7[0x50000 - 0x4b014]; u32 usb3_phy_prim_bcr; @@ -128,6 +130,33 @@ struct sc7180_aoss { u32 aoss_cc_apcs_misc; }; +struct sc7180_disp_cc { + u8 _res0[0x2004]; + u32 pclk0_cbcr; + u8 _res1[0x2028 - 0x2008]; + u32 byte0_cbcr; + u32 byte0_intf_cbcr; + u8 _res2[0x2038 - 0x2030]; + u32 esc0_cbcr; + u8 _res3[0x2098 - 0x203C]; + struct sc7180_mnd_clock pclk0; + u8 _res4[0x2110 - 0x20AC]; + struct sc7180_mnd_clock byte0; + u8 _res5[0x2148 - 0x2124]; + struct sc7180_mnd_clock esc0; + u8 _res6[0x10000 - 0x215C]; +}; +check_member(sc7180_disp_cc, byte0_cbcr, 0x2028); +check_member(sc7180_disp_cc, esc0_cbcr, 0x2038); + +enum mdss_clock { + MDSS_CLK_ESC0 = 0, + MDSS_CLK_PCLK0, + MDSS_CLK_BYTE0, + MDSS_CLK_BYTE0_INTF, + MDSS_CLK_COUNT +}; + enum clk_ctl_gpll_user_ctl { CLK_CTL_GPLL_PLLOUT_EVEN_BMSK = 0x2, CLK_CTL_GPLL_PLLOUT_MAIN_SHFT = 0, @@ -202,12 +231,6 @@ struct clock_config { uint16_t d_2; }; -struct mdss_clock_config { - const char *clk_name; - uintptr_t rcgr; - uintptr_t cbcr; -}; - /* CPU PLL */ #define L_VAL_1516P8MHz 0x4F #define L_VAL_1209P6MHz 0x3F @@ -265,6 +288,7 @@ 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; +static struct sc7180_disp_cc *const mdss = (void *)DISP_CC_BASE; void clock_init(void); void clock_reset_aop(void); @@ -273,5 +297,8 @@ int clock_reset_bcr(void *bcr_addr, bool reset); void clock_configure_qup(int qup, uint32_t hz); void clock_enable_qup(int qup); void clock_configure_dfsr(int qup); +int mdss_clock_configure(enum mdss_clock clk_type, uint32_t source, + uint32_t half_divider, uint32_t m, uint32_t n, uint32_t d); +int mdss_clock_enable(enum mdss_clock clk_type); #endif // __SOC_QUALCOMM_SC7180_CLOCK_H__ -- cgit v1.2.3