
On 26/02/2024 10:08, Varadarajan Narayanan wrote:
The BCR registers in IPQ9574 are different and have different fields. Add function to program these clocks accordingly.
Signed-off-by: Varadarajan Narayanan quic_varada@quicinc.com
drivers/clk/qcom/clock-qcom.c | 32 ++++++++++++++++++++++++++++++++ drivers/clk/qcom/clock-qcom.h | 8 ++++++++ 2 files changed, 40 insertions(+)
diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c index 7c683e5192..fe60490186 100644 --- a/drivers/clk/qcom/clock-qcom.c +++ b/drivers/clk/qcom/clock-qcom.c @@ -156,6 +156,38 @@ void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div, clk_bcr_update(base + regs->cmd_rcgr); }
+#define CFG_MASK 0x3FFF
Please define this in terms of the individual register fields.
+#define CFG_DIVIDER_MASK 0x1F
This is just CFG_SRC_DIV_MASK, please use that instead.
+/* root set rate for clocks without the MND divider */
Please adjust this comment to explain what's different about v2 and where it's relevant (is it just IPQ SoCs? Or "some IPQ SoCs"?).
+void clk_rcg_set_rate_v2(phys_addr_t base, const struct bcr_regs_v2 *regs,
int div, int cdiv, int source)
As far as I can tell, this is like the RCG clocks in that the cfg register is always cmd + 4 and div_cdivr is always cfg + 4.
In this case let's simplify this and save a whole lot of lines by just passing in the cmd register address and using offsets for the others. There's no need to specify all these manually. See https://lore.kernel.org/u-boot/20240131-b4-qcom-livetree-v1-4-4071c0787db0@l...
+{
- u32 cfg;
- /* setup src select and divider */
- cfg = readl(base + regs->cfg_rcgr);
- cfg &= ~CFG_MASK;
- cfg |= source & CFG_CLK_SRC_MASK; /* Select clock source */
- /*
* Set the divider; HW permits fraction dividers (+0.5), but
* for simplicity, we will support integers only
*/
- if (div)
cfg |= div & CFG_DIVIDER_MASK;
- writel(cfg, base + regs->cfg_rcgr); /* Write new clock configuration */
- /* Write the common divider clock configuration */
- if (regs->div_cdivr)
writel(cdiv, base + regs->div_cdivr);
- /* Inform h/w to start using the new config. */
- clk_bcr_update(base + regs->cmd_rcgr);
+}
const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate) { if (!f) diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h index 01088c1901..95f6162ea4 100644 --- a/drivers/clk/qcom/clock-qcom.h +++ b/drivers/clk/qcom/clock-qcom.h @@ -32,6 +32,12 @@ struct bcr_regs { uintptr_t D; };
+struct bcr_regs_v2 {
- uintptr_t cfg_rcgr;
- uintptr_t cmd_rcgr;
- uintptr_t div_cdivr;
+};> + struct freq_tbl { uint freq; uint src; @@ -86,6 +92,8 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs, int div, int m, int n, int source, u8 mnd_width); void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div, int source); +void clk_rcg_set_rate_v2(phys_addr_t base, const struct bcr_regs_v2 *regs,
int div, int cdiv, int source);
static inline void qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id) {