Re: [PATCH 03/10] clk/qcom: Add support for clock registers in IPQ9574

2024-02-26 Thread Caleb Connolly



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 
> ---
> 
>  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-4071c0787...@linaro.org/
> +{
> + 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)
>  {

-- 
// Caleb (they/them)


[PATCH 03/10] clk/qcom: Add support for clock registers in IPQ9574

2024-02-26 Thread Varadarajan Narayanan
The BCR registers in IPQ9574 are different and have
different fields. Add function to program these
clocks accordingly.

Signed-off-by: Varadarajan Narayanan 
---

 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
+
+#define CFG_DIVIDER_MASK 0x1F
+
+/* root set rate for clocks without the MND divider */
+void clk_rcg_set_rate_v2(phys_addr_t base, const struct bcr_regs_v2 *regs,
+int div, int cdiv, int source)
+{
+   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)
 {
-- 
2.34.1