diff options
author | Taniya Das <tdas@codeaurora.org> | 2021-06-23 08:53:39 +0530 |
---|---|---|
committer | Shelley Chen <shchen@google.com> | 2021-09-03 06:03:08 +0000 |
commit | 310edec6177445a69968a7b8c7a9a89252f58008 (patch) | |
tree | d4c0e79f86a65725f2b31765a9c96e3adb867cbe /src | |
parent | a74eb4f6e8ccf5a181563273b156e02633fa08b6 (diff) |
qualcomm/sc7180: Clean up drivers with common clock
As we move to use the common clock driver, the sc7180 clock driver,
watchdog and display drivers requires few cleanups, thus update the
impacted drivers.
Earlier the display 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;
The older convention in the upcoming patches would be replaced with
the common macro of QCOM_CLOCK_DIV, thus need the divider needs to
be updated.
mdss_clk_cfg.div = half_divider ? QCOM_CLOCK_DIV(half_divider) : 0;
To accommodate impacting the functionality, the half_divider is taken
care in the clock driver.
BUG=b:182963902
TEST=Validated on qualcomm sc7180 development board
Change-Id: Ic334fd0d43e5b4b1e43a27d5db7665f0bc151d66
Signed-off-by: Taniya Das <tdas@codeaurora.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/56587
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Shelley Chen <shchen@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/soc/qualcomm/sc7180/clock.c | 126 | ||||
-rw-r--r-- | src/soc/qualcomm/sc7180/display/dsi_phy.c | 2 | ||||
-rw-r--r-- | src/soc/qualcomm/sc7180/include/soc/clock.h | 6 | ||||
-rw-r--r-- | src/soc/qualcomm/sc7180/watchdog.c | 4 |
4 files changed, 70 insertions, 68 deletions
diff --git a/src/soc/qualcomm/sc7180/clock.c b/src/soc/qualcomm/sc7180/clock.c index 8763a9d71f..8bf450ab08 100644 --- a/src/soc/qualcomm/sc7180/clock.c +++ b/src/soc/qualcomm/sc7180/clock.c @@ -11,14 +11,6 @@ #define DIV(div) (2 * div - 1) -struct clock_config qup_cfg[] = { - { - .hz = SRC_XO_HZ, /* 19.2KHz */ - .src = SRC_XO_19_2MHZ, - .div = DIV(1), - } -}; - struct clock_config qspi_core_cfg[] = { { .hz = SRC_XO_HZ, /* 19.2KHz */ @@ -42,7 +34,7 @@ struct clock_config qspi_core_cfg[] = { } }; -struct clock_config qup_wrap_cfg[] = { +struct clock_config qupv3_wrap_cfg[] = { { .hz = SRC_XO_HZ, /* 19.2KHz */ .src = SRC_XO_19_2MHZ, @@ -124,8 +116,8 @@ static int clock_configure_gpll0(void) return 0; } -static int clock_configure_mnd(struct sc7180_clock *clk, uint32_t m, uint32_t n, - uint32_t d_2) +static void clock_configure_mnd(struct sc7180_clock *clk, uint32_t m, + uint32_t n, uint32_t d_2) { struct sc7180_mnd_clock *mnd = (struct sc7180_mnd_clock *)clk; setbits32(&clk->rcg_cfg, @@ -134,11 +126,9 @@ static int clock_configure_mnd(struct sc7180_clock *clk, uint32_t m, uint32_t n, write32(&mnd->m, m & CLK_CTL_RCG_MND_BMSK); write32(&mnd->n, ~(n-m) & CLK_CTL_RCG_MND_BMSK); write32(&mnd->d_2, ~(d_2) & CLK_CTL_RCG_MND_BMSK); - - return 0; } -static int clock_configure(struct sc7180_clock *clk, +static enum cb_err clock_configure(struct sc7180_clock *clk, struct clock_config *clk_cfg, uint32_t hz, uint32_t num_perfs) { @@ -164,7 +154,7 @@ static int clock_configure(struct sc7180_clock *clk, /* Commit config to RCG*/ setbits32(&clk->rcg_cmd, BIT(CLK_CTL_CMD_UPDATE_SHFT)); - return 0; + return CB_SUCCESS; } static bool clock_is_off(u32 *cbcr_addr) @@ -172,35 +162,39 @@ static bool clock_is_off(u32 *cbcr_addr) return (read32(cbcr_addr) & CLK_CTL_CBC_CLK_OFF_BMSK); } -static int clock_enable_vote(void *cbcr_addr, void *vote_addr, +static enum cb_err clock_enable_vote(void *cbcr_addr, void *vote_addr, uint32_t vote_bit) { /* Set clock vote bit */ setbits32(vote_addr, BIT(vote_bit)); /* Ensure clock is enabled */ - while (clock_is_off(cbcr_addr)) - ; + if (!wait_us(100, clock_is_off(cbcr_addr))) + return CB_ERR; - return 0; + return CB_SUCCESS; } -static int clock_enable(void *cbcr_addr) +static enum cb_err clock_enable(void *cbcr_addr) { /* Set clock enable bit */ setbits32(cbcr_addr, BIT(CLK_CTL_CBC_CLK_EN_SHFT)); - /* Ensure clock is enabled */ - while (clock_is_off(cbcr_addr)) - ; + if (!wait_us(100, clock_is_off(cbcr_addr))) + return CB_ERR; - return 0; + return CB_SUCCESS; +} + +static void clock_reset_subsystem(u32 *misc, u32 shft) +{ + clrbits32(misc, BIT(shft)); } void clock_reset_aop(void) { /* Bring AOP out of RESET */ - clrbits32(&aoss->aoss_cc_apcs_misc, BIT(AOP_RESET_SHFT)); + clock_reset_subsystem(&aoss->aoss_cc_apcs_misc, AOP_RESET_SHFT); } void clock_configure_qspi(uint32_t hz) @@ -212,7 +206,7 @@ void clock_configure_qspi(uint32_t hz) clock_enable(&gcc->qspi_core_cbcr); } -int clock_reset_bcr(void *bcr_addr, bool reset) +void clock_reset_bcr(void *bcr_addr, bool reset) { struct sc7180_bcr *bcr = bcr_addr; @@ -220,11 +214,10 @@ int clock_reset_bcr(void *bcr_addr, bool reset) setbits32(bcr, BIT(CLK_CTL_BCR_BLK_ARES_SHFT)); else clrbits32(bcr, BIT(CLK_CTL_BCR_BLK_ARES_SHFT)); - - return 0; } -void clock_configure_dfsr(int qup) +static void clock_configure_dfsr_table(int qup, struct clock_config *clk_cfg, + uint32_t num_perfs) { int idx; int s = qup % QUP_WRAP1_S0; @@ -236,38 +229,34 @@ void clock_configure_dfsr(int qup) BIT(CLK_CTL_CMD_RCG_SW_CTL_SHFT), BIT(CLK_CTL_CMD_DFSR_SHFT)); - for (idx = 0; idx < ARRAY_SIZE(qup_wrap_cfg); idx++) { - reg_val = (qup_wrap_cfg[idx].src << CLK_CTL_CFG_SRC_SEL_SHFT) | - (qup_wrap_cfg[idx].div << CLK_CTL_CFG_SRC_DIV_SHFT); + for (idx = 0; idx < num_perfs; idx++) { + reg_val = (clk_cfg[idx].src << CLK_CTL_CFG_SRC_SEL_SHFT) | + (clk_cfg[idx].div << CLK_CTL_CFG_SRC_DIV_SHFT); write32(&qup_clk->dfsr_clk.perf_dfsr[idx], reg_val); - if (qup_wrap_cfg[idx].m == 0) + if (clk_cfg[idx].m == 0) continue; setbits32(&qup_clk->dfsr_clk.perf_dfsr[idx], RCG_MODE_DUAL_EDGE << CLK_CTL_CFG_MODE_SHFT); - reg_val = qup_wrap_cfg[idx].m & CLK_CTL_RCG_MND_BMSK; + reg_val = clk_cfg[idx].m & CLK_CTL_RCG_MND_BMSK; write32(&qup_clk->dfsr_clk.perf_m_dfsr[idx], reg_val); - reg_val = ~(qup_wrap_cfg[idx].n - qup_wrap_cfg[idx].m) + reg_val = ~(clk_cfg[idx].n - clk_cfg[idx].m) & CLK_CTL_RCG_MND_BMSK; write32(&qup_clk->dfsr_clk.perf_n_dfsr[idx], reg_val); - reg_val = ~(qup_wrap_cfg[idx].d_2) & CLK_CTL_RCG_MND_BMSK; + reg_val = ~(clk_cfg[idx].d_2) & CLK_CTL_RCG_MND_BMSK; write32(&qup_clk->dfsr_clk.perf_d_dfsr[idx], reg_val); } } -void clock_configure_qup(int qup, uint32_t hz) +void clock_configure_dfsr(int qup) { - int s = qup % QUP_WRAP1_S0; - struct sc7180_qupv3_clock *qup_clk = qup < QUP_WRAP1_S0 ? - &gcc->qup_wrap0_s[s] : &gcc->qup_wrap1_s[s]; - - clock_configure(&qup_clk->mnd_clk.clock, qup_cfg, hz, - ARRAY_SIZE(qup_cfg)); + clock_configure_dfsr_table(qup, qupv3_wrap_cfg, + ARRAY_SIZE(qupv3_wrap_cfg)); } void clock_enable_qup(int qup) @@ -282,8 +271,27 @@ void clock_enable_qup(int qup) clk_en_off); } -static int pll_init_and_set(struct sc7180_apss_clock *apss, u32 l_val) +static enum cb_err agera_pll_enable(u32 *mode, u32 *opmode) { + setbits32(mode, BIT(BYPASSNL_SHFT)); + udelay(5); + setbits32(mode, BIT(RESET_SHFT)); + + setbits32(opmode, RUN_MODE); + + if (!wait_us(100, read32(mode) & LOCK_DET_BMSK)) { + printk(BIOS_ERR, "ERROR: PLL did not lock!\n"); + return CB_ERR; + } + + setbits32(mode, BIT(OUTCTRL_SHFT)); + + return CB_SUCCESS; +} + +static enum cb_err pll_init_and_set(struct sc7180_apss_clock *apss, u32 l_val) +{ + int ret; u32 gfmux_val; /* Configure and Enable PLL */ @@ -299,24 +307,15 @@ static int pll_init_and_set(struct sc7180_apss_clock *apss, u32 l_val) write32(&apss->pll.config_ctl_u1, 0x0); write32(&apss->pll.l_val, l_val); - setbits32(&apss->pll.mode, BIT(BYPASSNL_SHFT)); - udelay(5); - setbits32(&apss->pll.mode, BIT(RESET_SHFT)); - - setbits32(&apss->pll.opmode, RUN_MODE); - - if (!wait_us(100, read32(&apss->pll.mode) & LOCK_DET_BMSK)) { - printk(BIOS_ERR, "ERROR: PLL did not lock!\n"); - return -1; - } - - setbits32(&apss->pll.mode, BIT(OUTCTRL_SHFT)); + ret = agera_pll_enable(&apss->pll.mode, &apss->pll.opmode); + 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 0; + return CB_SUCCESS; } static void speed_up_boot_cpu(void) @@ -330,25 +329,28 @@ 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, +enum cb_err mdss_clock_configure(enum mdss_clock clk_type, uint32_t source, + uint32_t 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; + return CB_ERR; /* Initialize it with received arguments */ mdss_clk_cfg.hz = 0; mdss_clk_cfg.src = source; /* + * Update half_divider passed from display, this is to accommodate + * the transition to common clock driver. + * * 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.div = divider ? ((divider * 2) - 1) : 0; mdss_clk_cfg.m = m; mdss_clk_cfg.n = n; mdss_clk_cfg.d_2 = d_2; @@ -368,7 +370,7 @@ int mdss_clock_configure(enum mdss_clock clk_type, uint32_t source, setbits32(&mdss_clock[clk_type]->clock.rcg_cmd, BIT(CLK_CTL_CMD_UPDATE_SHFT)); - return 0; + return CB_SUCCESS; } int mdss_clock_enable(enum mdss_clock clk_type) diff --git a/src/soc/qualcomm/sc7180/display/dsi_phy.c b/src/soc/qualcomm/sc7180/display/dsi_phy.c index db4b67cfe7..a7b04a87e1 100644 --- a/src/soc/qualcomm/sc7180/display/dsi_phy.c +++ b/src/soc/qualcomm/sc7180/display/dsi_phy.c @@ -722,7 +722,7 @@ static enum cb_err enable_dsi_clk(void) {.clk_type = MDSS_CLK_PCLK0, .clk_source = 1}, {.clk_type = MDSS_CLK_BYTE0, .clk_source = 1}, {.clk_type = MDSS_CLK_BYTE0_INTF, .clk_source = 1, - .clk_div = 2, .source_div = 2}, + .clk_div = 1, .source_div = 2}, }; for (i = 0; i < ARRAY_SIZE(clks); i++) { diff --git a/src/soc/qualcomm/sc7180/include/soc/clock.h b/src/soc/qualcomm/sc7180/include/soc/clock.h index b303efefc1..bb46062e11 100644 --- a/src/soc/qualcomm/sc7180/include/soc/clock.h +++ b/src/soc/qualcomm/sc7180/include/soc/clock.h @@ -28,8 +28,6 @@ #define AOP_RESET_SHFT 0 #define RCG_MODE_DUAL_EDGE 2 -#define WDOG_RESET_BIT_MASK 1 - #define SCALE_FREQ_SHFT 11 struct sc7180_clock { @@ -298,12 +296,12 @@ static struct sc7180_disp_cc *const mdss = (void *)DISP_CC_BASE; void clock_init(void); void clock_reset_aop(void); void clock_configure_qspi(uint32_t hz); -int clock_reset_bcr(void *bcr_addr, bool reset); +void 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); + uint32_t 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__ diff --git a/src/soc/qualcomm/sc7180/watchdog.c b/src/soc/qualcomm/sc7180/watchdog.c index 0b7dd6dff8..680d70b2d3 100644 --- a/src/soc/qualcomm/sc7180/watchdog.c +++ b/src/soc/qualcomm/sc7180/watchdog.c @@ -1,10 +1,12 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include <soc/watchdog.h> #include <soc/clock.h> +#include <soc/watchdog.h> #include <device/mmio.h> #include <vendorcode/google/chromeos/chromeos.h> +#define WDOG_RESET_BIT_MASK 1 + void check_wdog(void) { uint32_t wdog_sta = read32(&aoss->aoss_cc_reset_status); |