Ravi kumar would like Taniya Das to review this change.

View Change

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__

To view, visit change 39612. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ida222890252b80db738fa1f685b212b3f7c6e689
Gerrit-Change-Number: 39612
Gerrit-PatchSet: 1
Gerrit-Owner: Ravi kumar <rbokka@codeaurora.org>
Gerrit-Reviewer: Taniya Das <tdas@codeaurora.org>
Gerrit-MessageType: newchange