Hello Taniya Das,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/39612
to review the following change.
Change subject: sc7180: clock: Add display external clock in coreboot ......................................................................
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 tdas@codeaurora.org --- M src/soc/qualcomm/sc7180/clock.c M src/soc/qualcomm/sc7180/include/soc/addressmap.h M src/soc/qualcomm/sc7180/include/soc/clock.h 3 files changed, 145 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/12/39612/1
diff --git a/src/soc/qualcomm/sc7180/clock.c b/src/soc/qualcomm/sc7180/clock.c index 2eb5830..f9ddeee 100644 --- a/src/soc/qualcomm/sc7180/clock.c +++ b/src/soc/qualcomm/sc7180/clock.c @@ -18,10 +18,12 @@ #include <delay.h> #include <device/mmio.h> #include <soc/clock.h> +#include <string.h> #include <timer.h> #include <types.h>
#define DIV(div) (2 * div - 1) +#define HALF_DIVIDER(div2x) (div2x ? (div2x - 1) : 0)
struct clock_config qup_cfg[] = { { @@ -117,6 +119,30 @@ }, };
+struct mdss_clock_config mdss_extclk_config[] = { + { + "disp_cc_mdss_esc0_clk", + mdss_reg_ptr(struct sc7180_disp_cc, esc0_rcgr, DISP_CC_BASE), + mdss_reg_ptr(struct sc7180_disp_cc, esc0_cbcr, DISP_CC_BASE), + }, + { + "disp_cc_mdss_pclk0_clk", + mdss_reg_ptr(struct sc7180_disp_cc, pclk0_rcgr, DISP_CC_BASE), + mdss_reg_ptr(struct sc7180_disp_cc, pclk0_cbcr, DISP_CC_BASE), + }, + { + "disp_cc_mdss_byte0_clk", + mdss_reg_ptr(struct sc7180_disp_cc, byte0_rcgr, DISP_CC_BASE), + mdss_reg_ptr(struct sc7180_disp_cc, byte0_cbcr, DISP_CC_BASE), + }, + { + "disp_cc_mdss_byte0_intf_clk", + mdss_reg_ptr(struct sc7180_disp_cc, byte0_rcgr, DISP_CC_BASE), + mdss_reg_ptr(struct sc7180_disp_cc, byte0_intf_cbcr, + DISP_CC_BASE), + }, +}; + static int clock_configure_gpll0(void) { setbits32(&gcc->gpll0.user_ctl_u, 1 << SCALE_FREQ_SHFT); @@ -336,6 +362,90 @@ printk(BIOS_INFO, "L3 Frequency bumped to 1.2096(GHz)\n"); }
+static void * mdss_clock_get_reg_addr(const char *clk_name, + uint32_t mdss_clk_type) +{ + void *reg_addr = NULL; + int i; + int num_clks; + + num_clks = sizeof(mdss_extclk_config) / + sizeof(struct mdss_clock_config); + + for (i = 0; i < num_clks; i++) { + if (strcmp(mdss_extclk_config[i].clk_name, clk_name) != 0) + continue; + + if (mdss_clk_type == 0) + reg_addr = (void *)mdss_extclk_config[i].rcgr; + else if(mdss_clk_type == 1) + reg_addr = (void *)mdss_extclk_config[i].cbcr; + } + return reg_addr; +} + +int mdss_clock_configure(const char *clk_name, uint32_t source, + uint32_t divider, uint32_t m, uint32_t n, uint32_t d_2) +{ + struct clock_config mdss_clk_cfg; + struct sc7180_mdss_rcg *mdss_clk; + uint32_t reg_val; + + /* Find out the RCGR address corresponding to the given clock */ + mdss_clk = mdss_clock_get_reg_addr(clk_name, 0); + + /* clk_name not found in the available clock list */ + if (mdss_clk == NULL) + return -1; + + /* Initialize it with received arguments */ + mdss_clk_cfg.hz = 0; + mdss_clk_cfg.src = source; + mdss_clk_cfg.div = HALF_DIVIDER(divider); + 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_clk->cfg, reg_val); + + /* Set m/n/d values for a specific clock */ + if (mdss_clk_cfg.m != 0) { + setbits32(&mdss_clk->cfg, + RCG_MODE_DUAL_EDGE << CLK_CTL_CFG_MODE_SHFT); + write32(&mdss->pclk0_m, mdss_clk_cfg.m & CLK_CTL_RCG_MND_BMSK); + write32(&mdss->pclk0_n, ~(mdss_clk_cfg.n-mdss_clk_cfg.m) & + CLK_CTL_RCG_MND_BMSK); + write32(&mdss->pclk0_d, ~(mdss_clk_cfg.d_2) & + CLK_CTL_RCG_MND_BMSK); + } + + /* Commit config to RCG */ + setbits32(&mdss_clk->cmd, BIT(CLK_CTL_CMD_UPDATE_SHFT)); + + return 0; +} + +int mdss_clock_enable(const char *clk_name, uint32_t clk_on) +{ + void *cbcr; + + /* Find out the RCGR address corresponding to the given clock */ + cbcr = mdss_clock_get_reg_addr(clk_name, 1); + + /* clk_name not found in the available clock list */ + if ((cbcr == NULL) || (clk_on == 0)) + return -1; + + /* Enable clock*/ + clock_enable(cbcr); + + return 0; +} + void clock_init(void) { clock_configure_gpll0(); diff --git a/src/soc/qualcomm/sc7180/include/soc/addressmap.h b/src/soc/qualcomm/sc7180/include/soc/addressmap.h index ee640a2..ff05616 100644 --- a/src/soc/qualcomm/sc7180/include/soc/addressmap.h +++ b/src/soc/qualcomm/sc7180/include/soc/addressmap.h @@ -26,6 +26,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 26e3d09..e42f9b3 100644 --- a/src/soc/qualcomm/sc7180/include/soc/clock.h +++ b/src/soc/qualcomm/sc7180/include/soc/clock.h @@ -43,6 +43,9 @@
#define SCALE_FREQ_SHFT 11
+#define mdss_reg_ptr(type, mem, base) \ + ((offsetof(type, mem)) + base) + struct sc7180_clock { u32 cbcr; u32 rcg_cmd; @@ -140,6 +143,33 @@ u32 aoss_cc_apcs_misc; };
+struct sc7180_mdss_rcg { + u32 cmd; + u32 cfg; +}; + +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_mdss_rcg pclk0_rcgr; + u32 pclk0_m; + u32 pclk0_n; + u32 pclk0_d; + u8 _res4[0x2110 - 0x20AC]; + struct sc7180_mdss_rcg byte0_rcgr; + u8 _res5[0x2148 - 0x2118]; + struct sc7180_mdss_rcg esc0_rcgr; + u8 _res6[0x10000 - 0x2050]; +}; +check_member(sc7180_disp_cc, byte0_cbcr, 0x2028); +check_member(sc7180_disp_cc, esc0_cbcr, 0x2038); + enum clk_ctl_gpll_user_ctl { CLK_CTL_GPLL_PLLOUT_EVEN_BMSK = 0x2, CLK_CTL_GPLL_PLLOUT_MAIN_SHFT = 0, @@ -280,6 +310,7 @@ 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); @@ -288,5 +319,8 @@ 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(const char *clk_name, uint32_t source, + uint32_t divider, uint32_t m, uint32_t n, uint32_t d); +int mdss_clock_enable(const char *sName, uint32_t clk_on);
#endif // __SOC_QUALCOMM_SC7180_CLOCK_H__