From ece88ab765859b728c2ba17d1224455807a5fda6 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 5 Nov 2019 21:37:32 +0530 Subject: [PATCH] sc7180: clock: Add support for QUP DFSR configuration Support configuring the qup dfsr registers. Tested: validated DFSR clock configuration and M/N/D values. Change-Id: I146ac7c2197606965265f2a770769312af76041e Signed-off-by: Taniya Das Reviewed-on: https://review.coreboot.org/c/coreboot/+/37305 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/soc/qualcomm/sc7180/clock.c | 89 +++++++++++++++++++++ src/soc/qualcomm/sc7180/include/soc/clock.h | 21 ++++- 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/src/soc/qualcomm/sc7180/clock.c b/src/soc/qualcomm/sc7180/clock.c index 9092a4e185..b447a54487 100644 --- a/src/soc/qualcomm/sc7180/clock.c +++ b/src/soc/qualcomm/sc7180/clock.c @@ -60,6 +60,61 @@ struct clock_config qspi_core_cfg[] = { } }; +struct clock_config qup_wrap_cfg[] = { + { + .hz = SRC_XO_HZ, /* 19.2KHz */ + .src = SRC_XO_19_2MHZ, + .div = DIV(1), + }, + { + .hz = 32 * MHz, + .src = SRC_GPLL0_EVEN_300MHZ, + .div = DIV(1), + .m = 8, + .n = 75, + .d_2 = 150, + }, + { + .hz = 48 * MHz, + .src = SRC_GPLL0_EVEN_300MHZ, + .div = DIV(1), + .m = 4, + .n = 25, + .d_2 = 50, + }, + { + .hz = 64 * MHz, + .src = SRC_GPLL0_EVEN_300MHZ, + .div = DIV(1), + .m = 16, + .n = 75, + .d_2 = 150, + }, + { + .hz = 96 * MHz, + .src = SRC_GPLL0_EVEN_300MHZ, + .div = DIV(1), + .m = 8, + .n = 25, + .d_2 = 50, + }, + { + .hz = 100 * MHz, + .src = SRC_GPLL0_EVEN_300MHZ, + .div = DIV(3), + }, + { + .hz = SRC_XO_HZ, /* 19.2KHz */ + .src = SRC_XO_19_2MHZ, + .div = DIV(1), + }, + { + .hz = SRC_XO_HZ, /* 19.2KHz */ + .src = SRC_XO_19_2MHZ, + .div = DIV(1), + }, +}; + static int clock_configure_gpll0(void) { setbits32(&gcc->gpll0.user_ctl_u, 1 << SCALE_FREQ_SHFT); @@ -173,6 +228,40 @@ int clock_reset_bcr(void *bcr_addr, bool reset) return 0; } +void clock_configure_dfsr(int qup) +{ + int idx; + int s = qup % QUP_WRAP1_S0; + uint32_t reg_val; + struct sc7180_qupv3_clock *qup_clk = qup < QUP_WRAP1_S0 ? + &gcc->qup_wrap0_s[s] : &gcc->qup_wrap1_s[s]; + + setbits32(&qup_clk->dfsr_clk.cmd_dfsr, 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); + + write32(&qup_clk->dfsr_clk.perf_dfsr[idx], reg_val); + + if (qup_wrap_cfg[idx].m == 0) + continue; + + setbits32(&qup_clk->dfsr_clk.cmd_dfsr, + RCG_MODE_DUAL_EDGE << CLK_CTL_CFG_MODE_SHFT); + + reg_val = qup_wrap_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) + & 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; + write32(&qup_clk->dfsr_clk.perf_d_dfsr[idx], reg_val); + } +} + void clock_configure_qup(int qup, uint32_t hz) { int s = qup % QUP_WRAP1_S0; diff --git a/src/soc/qualcomm/sc7180/include/soc/clock.h b/src/soc/qualcomm/sc7180/include/soc/clock.h index 39cde8c1bc..2e44b60623 100644 --- a/src/soc/qualcomm/sc7180/include/soc/clock.h +++ b/src/soc/qualcomm/sc7180/include/soc/clock.h @@ -56,9 +56,22 @@ struct sc7180_mnd_clock { u32 d_2; }; +struct sc7180_dfsr_clock { + u32 cmd_dfsr; + u8 _res0[0x20 - 0x1c]; + u32 perf_dfsr[8]; + u8 _res1[0x60 - 0x40]; + u32 perf_m_dfsr[8]; + u8 _res2[0xa0 - 0x80]; + u32 perf_n_dfsr[8]; + u8 _res3[0xe0 - 0xc0]; + u32 perf_d_dfsr[8]; + u8 _res4[0x130 - 0x100]; +}; + struct sc7180_qupv3_clock { struct sc7180_mnd_clock mnd_clk; - u8 _res[0x130 - 0x18]; + struct sc7180_dfsr_clock dfsr_clk; }; struct sc7180_gpll { @@ -171,6 +184,11 @@ enum clk_ctl_bcr { CLK_CTL_BCR_BLK_ARES_SHFT = 0, }; +enum clk_ctl_dfsr { + CLK_CTL_CMD_DFSR_BMSK = 0x1, + CLK_CTL_CMD_DFSR_SHFT = 0, +}; + enum clk_qup { QUP_WRAP0_S0, QUP_WRAP0_S1, @@ -210,5 +228,6 @@ void clock_configure_qspi(uint32_t hz); 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); #endif // __SOC_QUALCOMM_SC7180_CLOCK_H__