devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/6] clk: Ingenic JZ4760(B) support
@ 2021-05-30 16:49 Paul Cercueil
  2021-05-30 16:49 ` [PATCH v2 1/6] dt-bindings: clock: ingenic: Add ingenic,jz4760{,b}-cgu compatibles Paul Cercueil
                   ` (6 more replies)
  0 siblings, 7 replies; 17+ messages in thread
From: Paul Cercueil @ 2021-05-30 16:49 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, devicetree, linux-kernel, linux-mips, list,
	周琰杰,
	Paul Cercueil

Hi,

Here is (finally) my v2 of the JZ4760(B) patchset.

Patches 1-5 are the exact same as in v1.

Patch 6's algorithm was updated with Zhou's feedback.

Cheers,
-Paul

Paul Cercueil (6):
  dt-bindings: clock: ingenic: Add ingenic,jz4760{,b}-cgu compatibles
  clk: Support bypassing dividers
  clk: ingenic: Read bypass register only when there is one
  clk: ingenic: Remove pll_info.no_bypass_bit
  clk: ingenic: Support overriding PLLs M/N/OD calc algorithm
  clk: ingenic: Add support for the JZ4760

 .../bindings/clock/ingenic,cgu.yaml           |   4 +
 drivers/clk/ingenic/Kconfig                   |  10 +
 drivers/clk/ingenic/Makefile                  |   1 +
 drivers/clk/ingenic/cgu.c                     |  92 ++--
 drivers/clk/ingenic/cgu.h                     |  12 +-
 drivers/clk/ingenic/jz4725b-cgu.c             |  12 +-
 drivers/clk/ingenic/jz4740-cgu.c              |  12 +-
 drivers/clk/ingenic/jz4760-cgu.c              | 428 ++++++++++++++++++
 drivers/clk/ingenic/jz4770-cgu.c              |  15 +-
 drivers/clk/ingenic/tcu.c                     |   2 +
 include/dt-bindings/clock/jz4760-cgu.h        |  54 +++
 11 files changed, 586 insertions(+), 56 deletions(-)
 create mode 100644 drivers/clk/ingenic/jz4760-cgu.c
 create mode 100644 include/dt-bindings/clock/jz4760-cgu.h

-- 
2.30.2


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 1/6] dt-bindings: clock: ingenic: Add ingenic,jz4760{,b}-cgu compatibles
  2021-05-30 16:49 [PATCH v2 0/6] clk: Ingenic JZ4760(B) support Paul Cercueil
@ 2021-05-30 16:49 ` Paul Cercueil
  2021-06-28  2:49   ` Stephen Boyd
  2021-05-30 16:49 ` [PATCH v2 2/6] clk: Support bypassing dividers Paul Cercueil
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: Paul Cercueil @ 2021-05-30 16:49 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, devicetree, linux-kernel, linux-mips, list,
	周琰杰,
	Paul Cercueil, Rob Herring

Add ingenic,jz4760-cgu and ingenic,jz4760b-cgu compatible strings for
the JZ4760 and JZ4760B SoCs respectively.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Acked-by: Rob Herring <robh@kernel.org>
---
 Documentation/devicetree/bindings/clock/ingenic,cgu.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml b/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml
index c65b9458c0b6..6d6236e02c22 100644
--- a/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml
+++ b/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml
@@ -22,6 +22,8 @@ select:
         enum:
           - ingenic,jz4740-cgu
           - ingenic,jz4725b-cgu
+          - ingenic,jz4760-cgu
+          - ingenic,jz4760b-cgu
           - ingenic,jz4770-cgu
           - ingenic,jz4780-cgu
           - ingenic,x1000-cgu
@@ -49,6 +51,8 @@ properties:
       - enum:
           - ingenic,jz4740-cgu
           - ingenic,jz4725b-cgu
+          - ingenic,jz4760-cgu
+          - ingenic,jz4760b-cgu
           - ingenic,jz4770-cgu
           - ingenic,jz4780-cgu
           - ingenic,x1000-cgu
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 2/6] clk: Support bypassing dividers
  2021-05-30 16:49 [PATCH v2 0/6] clk: Ingenic JZ4760(B) support Paul Cercueil
  2021-05-30 16:49 ` [PATCH v2 1/6] dt-bindings: clock: ingenic: Add ingenic,jz4760{,b}-cgu compatibles Paul Cercueil
@ 2021-05-30 16:49 ` Paul Cercueil
  2021-06-28  2:49   ` Stephen Boyd
  2021-05-30 16:49 ` [PATCH v2 3/6] clk: ingenic: Read bypass register only when there is one Paul Cercueil
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: Paul Cercueil @ 2021-05-30 16:49 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, devicetree, linux-kernel, linux-mips, list,
	周琰杰,
	Paul Cercueil

When a clock is declared as both CGU_CLK_DIV and CGU_CLK_MUX, the CGU
code expects the mux to be applied first, the divider second.

On the JZ4760, and maybe on some other SoCs, some clocks also have a mux
setting and a divider, but the divider is not applied to all parents
selectable from the mux.

This could be solved by creating two clocks, one with CGU_CLK_DIV and
one with CGU_CLK_MUX, but that would increase the number of clocks.

Instead, add a 8-bit mask to CGU_CLK_DIV clocks. If the bit
corresponding to the parent clock's index is set, the divider is
bypassed.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 drivers/clk/ingenic/cgu.c         | 33 ++++++++++++++++++++-----------
 drivers/clk/ingenic/cgu.h         |  2 ++
 drivers/clk/ingenic/jz4725b-cgu.c | 12 +++++------
 drivers/clk/ingenic/jz4740-cgu.c  | 12 +++++------
 drivers/clk/ingenic/jz4770-cgu.c  | 12 +++++------
 5 files changed, 42 insertions(+), 29 deletions(-)

diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
index c8e9cb6c8e39..0619d45a950c 100644
--- a/drivers/clk/ingenic/cgu.c
+++ b/drivers/clk/ingenic/cgu.c
@@ -369,18 +369,23 @@ ingenic_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 	struct ingenic_cgu *cgu = ingenic_clk->cgu;
 	unsigned long rate = parent_rate;
 	u32 div_reg, div;
+	u8 parent;
 
 	if (clk_info->type & CGU_CLK_DIV) {
-		div_reg = readl(cgu->base + clk_info->div.reg);
-		div = (div_reg >> clk_info->div.shift) &
-		      GENMASK(clk_info->div.bits - 1, 0);
+		parent = ingenic_clk_get_parent(hw);
 
-		if (clk_info->div.div_table)
-			div = clk_info->div.div_table[div];
-		else
-			div = (div + 1) * clk_info->div.div;
+		if (!(clk_info->div.bypass_mask & BIT(parent))) {
+			div_reg = readl(cgu->base + clk_info->div.reg);
+			div = (div_reg >> clk_info->div.shift) &
+			      GENMASK(clk_info->div.bits - 1, 0);
+
+			if (clk_info->div.div_table)
+				div = clk_info->div.div_table[div];
+			else
+				div = (div + 1) * clk_info->div.div;
 
-		rate /= div;
+			rate /= div;
+		}
 	} else if (clk_info->type & CGU_CLK_FIXDIV) {
 		rate /= clk_info->fixdiv.div;
 	}
@@ -410,10 +415,16 @@ ingenic_clk_calc_hw_div(const struct ingenic_cgu_clk_info *clk_info,
 }
 
 static unsigned
-ingenic_clk_calc_div(const struct ingenic_cgu_clk_info *clk_info,
+ingenic_clk_calc_div(struct clk_hw *hw,
+		     const struct ingenic_cgu_clk_info *clk_info,
 		     unsigned long parent_rate, unsigned long req_rate)
 {
 	unsigned int div, hw_div;
+	u8 parent;
+
+	parent = ingenic_clk_get_parent(hw);
+	if (clk_info->div.bypass_mask & BIT(parent))
+		return 1;
 
 	/* calculate the divide */
 	div = DIV_ROUND_UP(parent_rate, req_rate);
@@ -448,7 +459,7 @@ ingenic_clk_round_rate(struct clk_hw *hw, unsigned long req_rate,
 	unsigned int div = 1;
 
 	if (clk_info->type & CGU_CLK_DIV)
-		div = ingenic_clk_calc_div(clk_info, *parent_rate, req_rate);
+		div = ingenic_clk_calc_div(hw, clk_info, *parent_rate, req_rate);
 	else if (clk_info->type & CGU_CLK_FIXDIV)
 		div = clk_info->fixdiv.div;
 	else if (clk_hw_can_set_rate_parent(hw))
@@ -480,7 +491,7 @@ ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate,
 	int ret = 0;
 
 	if (clk_info->type & CGU_CLK_DIV) {
-		div = ingenic_clk_calc_div(clk_info, parent_rate, req_rate);
+		div = ingenic_clk_calc_div(hw, clk_info, parent_rate, req_rate);
 		rate = DIV_ROUND_UP(parent_rate, div);
 
 		if (rate != req_rate)
diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h
index 2c75ef4a36f5..44d97a259692 100644
--- a/drivers/clk/ingenic/cgu.h
+++ b/drivers/clk/ingenic/cgu.h
@@ -84,6 +84,7 @@ struct ingenic_cgu_mux_info {
  *          isn't one
  * @busy_bit: the index of the busy bit within reg, or -1 if there isn't one
  * @stop_bit: the index of the stop bit within reg, or -1 if there isn't one
+ * @bypass_mask: mask of parent clocks for which the divider does not apply
  * @div_table: optional table to map the value read from the register to the
  *             actual divider value
  */
@@ -95,6 +96,7 @@ struct ingenic_cgu_div_info {
 	s8 ce_bit;
 	s8 busy_bit;
 	s8 stop_bit;
+	u8 bypass_mask;
 	const u8 *div_table;
 };
 
diff --git a/drivers/clk/ingenic/jz4725b-cgu.c b/drivers/clk/ingenic/jz4725b-cgu.c
index 8c38e72d14a7..5154b0cf8ad6 100644
--- a/drivers/clk/ingenic/jz4725b-cgu.c
+++ b/drivers/clk/ingenic/jz4725b-cgu.c
@@ -80,7 +80,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
 		"pll half", CGU_CLK_DIV,
 		.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
 		.div = {
-			CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1,
+			CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1, 0,
 			jz4725b_cgu_pll_half_div_table,
 		},
 	},
@@ -89,7 +89,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
 		"cclk", CGU_CLK_DIV,
 		.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
 		.div = {
-			CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1,
+			CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
 			jz4725b_cgu_cpccr_div_table,
 		},
 	},
@@ -98,7 +98,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
 		"hclk", CGU_CLK_DIV,
 		.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
 		.div = {
-			CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1,
+			CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0,
 			jz4725b_cgu_cpccr_div_table,
 		},
 	},
@@ -107,7 +107,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
 		"pclk", CGU_CLK_DIV,
 		.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
 		.div = {
-			CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1,
+			CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0,
 			jz4725b_cgu_cpccr_div_table,
 		},
 	},
@@ -116,7 +116,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
 		"mclk", CGU_CLK_DIV,
 		.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
 		.div = {
-			CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1,
+			CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
 			jz4725b_cgu_cpccr_div_table,
 		},
 	},
@@ -125,7 +125,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
 		"ipu", CGU_CLK_DIV | CGU_CLK_GATE,
 		.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
 		.div = {
-			CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1,
+			CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, 0,
 			jz4725b_cgu_cpccr_div_table,
 		},
 		.gate = { CGU_REG_CLKGR, 13 },
diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c
index c0ac9196a581..cd878f08aca3 100644
--- a/drivers/clk/ingenic/jz4740-cgu.c
+++ b/drivers/clk/ingenic/jz4740-cgu.c
@@ -95,7 +95,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
 		"pll half", CGU_CLK_DIV,
 		.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
 		.div = {
-			CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1,
+			CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1, 0,
 			jz4740_cgu_pll_half_div_table,
 		},
 	},
@@ -104,7 +104,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
 		"cclk", CGU_CLK_DIV,
 		.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
 		.div = {
-			CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1,
+			CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
 			jz4740_cgu_cpccr_div_table,
 		},
 	},
@@ -113,7 +113,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
 		"hclk", CGU_CLK_DIV,
 		.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
 		.div = {
-			CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1,
+			CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0,
 			jz4740_cgu_cpccr_div_table,
 		},
 	},
@@ -122,7 +122,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
 		"pclk", CGU_CLK_DIV,
 		.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
 		.div = {
-			CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1,
+			CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0,
 			jz4740_cgu_cpccr_div_table,
 		},
 	},
@@ -131,7 +131,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
 		"mclk", CGU_CLK_DIV,
 		.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
 		.div = {
-			CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1,
+			CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
 			jz4740_cgu_cpccr_div_table,
 		},
 	},
@@ -140,7 +140,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
 		"lcd", CGU_CLK_DIV | CGU_CLK_GATE,
 		.parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 },
 		.div = {
-			CGU_REG_CPCCR, 16, 1, 5, 22, -1, -1,
+			CGU_REG_CPCCR, 16, 1, 5, 22, -1, -1, 0,
 			jz4740_cgu_cpccr_div_table,
 		},
 		.gate = { CGU_REG_CLKGR, 10 },
diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c
index 9ea4490ecb7f..381a27f20b51 100644
--- a/drivers/clk/ingenic/jz4770-cgu.c
+++ b/drivers/clk/ingenic/jz4770-cgu.c
@@ -152,7 +152,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
 		"cclk", CGU_CLK_DIV,
 		.parents = { JZ4770_CLK_PLL0, },
 		.div = {
-			CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1,
+			CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
 			jz4770_cgu_cpccr_div_table,
 		},
 	},
@@ -160,7 +160,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
 		"h0clk", CGU_CLK_DIV,
 		.parents = { JZ4770_CLK_PLL0, },
 		.div = {
-			CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1,
+			CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0,
 			jz4770_cgu_cpccr_div_table,
 		},
 	},
@@ -168,7 +168,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
 		"h1clk", CGU_CLK_DIV | CGU_CLK_GATE,
 		.parents = { JZ4770_CLK_PLL0, },
 		.div = {
-			CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1,
+			CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1, 0,
 			jz4770_cgu_cpccr_div_table,
 		},
 		.gate = { CGU_REG_CLKGR1, 7 },
@@ -177,7 +177,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
 		"h2clk", CGU_CLK_DIV,
 		.parents = { JZ4770_CLK_PLL0, },
 		.div = {
-			CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1,
+			CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, 0,
 			jz4770_cgu_cpccr_div_table,
 		},
 	},
@@ -185,7 +185,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
 		"c1clk", CGU_CLK_DIV | CGU_CLK_GATE,
 		.parents = { JZ4770_CLK_PLL0, },
 		.div = {
-			CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1,
+			CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
 			jz4770_cgu_cpccr_div_table,
 		},
 		.gate = { CGU_REG_OPCR, 31, true }, // disable CCLK stop on idle
@@ -194,7 +194,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
 		"pclk", CGU_CLK_DIV,
 		.parents = { JZ4770_CLK_PLL0, },
 		.div = {
-			CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1,
+			CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0,
 			jz4770_cgu_cpccr_div_table,
 		},
 	},
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 3/6] clk: ingenic: Read bypass register only when there is one
  2021-05-30 16:49 [PATCH v2 0/6] clk: Ingenic JZ4760(B) support Paul Cercueil
  2021-05-30 16:49 ` [PATCH v2 1/6] dt-bindings: clock: ingenic: Add ingenic,jz4760{,b}-cgu compatibles Paul Cercueil
  2021-05-30 16:49 ` [PATCH v2 2/6] clk: Support bypassing dividers Paul Cercueil
@ 2021-05-30 16:49 ` Paul Cercueil
  2021-06-01 14:08   ` Zhou Yanjie
  2021-06-28  2:49   ` Stephen Boyd
  2021-05-30 16:49 ` [PATCH v2 4/6] clk: ingenic: Remove pll_info.no_bypass_bit Paul Cercueil
                   ` (3 subsequent siblings)
  6 siblings, 2 replies; 17+ messages in thread
From: Paul Cercueil @ 2021-05-30 16:49 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, devicetree, linux-kernel, linux-mips, list,
	周琰杰,
	Paul Cercueil

Rework the clock code so that the bypass register is only read when
there is actually a bypass functionality.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 drivers/clk/ingenic/cgu.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
index 0619d45a950c..7686072aff8f 100644
--- a/drivers/clk/ingenic/cgu.c
+++ b/drivers/clk/ingenic/cgu.c
@@ -99,13 +99,14 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 	od_enc = ctl >> pll_info->od_shift;
 	od_enc &= GENMASK(pll_info->od_bits - 1, 0);
 
-	ctl = readl(cgu->base + pll_info->bypass_reg);
+	if (!pll_info->no_bypass_bit) {
+		ctl = readl(cgu->base + pll_info->bypass_reg);
 
-	bypass = !pll_info->no_bypass_bit &&
-		 !!(ctl & BIT(pll_info->bypass_bit));
+		bypass = !!(ctl & BIT(pll_info->bypass_bit));
 
-	if (bypass)
-		return parent_rate;
+		if (bypass)
+			return parent_rate;
+	}
 
 	for (od = 0; od < pll_info->od_max; od++) {
 		if (pll_info->od_encoding[od] == od_enc)
@@ -225,11 +226,13 @@ static int ingenic_pll_enable(struct clk_hw *hw)
 	u32 ctl;
 
 	spin_lock_irqsave(&cgu->lock, flags);
-	ctl = readl(cgu->base + pll_info->bypass_reg);
+	if (!pll_info->no_bypass_bit) {
+		ctl = readl(cgu->base + pll_info->bypass_reg);
 
-	ctl &= ~BIT(pll_info->bypass_bit);
+		ctl &= ~BIT(pll_info->bypass_bit);
 
-	writel(ctl, cgu->base + pll_info->bypass_reg);
+		writel(ctl, cgu->base + pll_info->bypass_reg);
+	}
 
 	ctl = readl(cgu->base + pll_info->reg);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 4/6] clk: ingenic: Remove pll_info.no_bypass_bit
  2021-05-30 16:49 [PATCH v2 0/6] clk: Ingenic JZ4760(B) support Paul Cercueil
                   ` (2 preceding siblings ...)
  2021-05-30 16:49 ` [PATCH v2 3/6] clk: ingenic: Read bypass register only when there is one Paul Cercueil
@ 2021-05-30 16:49 ` Paul Cercueil
  2021-06-01 14:07   ` Zhou Yanjie
  2021-06-28  2:49   ` Stephen Boyd
  2021-05-30 16:49 ` [PATCH v2 5/6] clk: ingenic: Support overriding PLLs M/N/OD calc algorithm Paul Cercueil
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 17+ messages in thread
From: Paul Cercueil @ 2021-05-30 16:49 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, devicetree, linux-kernel, linux-mips, list,
	周琰杰,
	Paul Cercueil

We can express that a PLL has no bypass bit by simply setting the
.bypass_bit field to a negative value.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 drivers/clk/ingenic/cgu.c        | 4 ++--
 drivers/clk/ingenic/cgu.h        | 7 +++----
 drivers/clk/ingenic/jz4770-cgu.c | 3 +--
 3 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
index 7686072aff8f..58f7ab5cf0fe 100644
--- a/drivers/clk/ingenic/cgu.c
+++ b/drivers/clk/ingenic/cgu.c
@@ -99,7 +99,7 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 	od_enc = ctl >> pll_info->od_shift;
 	od_enc &= GENMASK(pll_info->od_bits - 1, 0);
 
-	if (!pll_info->no_bypass_bit) {
+	if (pll_info->bypass_bit >= 0) {
 		ctl = readl(cgu->base + pll_info->bypass_reg);
 
 		bypass = !!(ctl & BIT(pll_info->bypass_bit));
@@ -226,7 +226,7 @@ static int ingenic_pll_enable(struct clk_hw *hw)
 	u32 ctl;
 
 	spin_lock_irqsave(&cgu->lock, flags);
-	if (!pll_info->no_bypass_bit) {
+	if (pll_info->bypass_bit >= 0) {
 		ctl = readl(cgu->base + pll_info->bypass_reg);
 
 		ctl &= ~BIT(pll_info->bypass_bit);
diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h
index 44d97a259692..10521d1b7b12 100644
--- a/drivers/clk/ingenic/cgu.h
+++ b/drivers/clk/ingenic/cgu.h
@@ -39,10 +39,10 @@
  *               their encoded values in the PLL control register, or -1 for
  *               unsupported values
  * @bypass_reg: the offset of the bypass control register within the CGU
- * @bypass_bit: the index of the bypass bit in the PLL control register
+ * @bypass_bit: the index of the bypass bit in the PLL control register, or
+ *              -1 if there is no bypass bit
  * @enable_bit: the index of the enable bit in the PLL control register
  * @stable_bit: the index of the stable bit in the PLL control register
- * @no_bypass_bit: if set, the PLL has no bypass functionality
  */
 struct ingenic_cgu_pll_info {
 	unsigned reg;
@@ -52,10 +52,9 @@ struct ingenic_cgu_pll_info {
 	u8 n_shift, n_bits, n_offset;
 	u8 od_shift, od_bits, od_max;
 	unsigned bypass_reg;
-	u8 bypass_bit;
+	s8 bypass_bit;
 	u8 enable_bit;
 	u8 stable_bit;
-	bool no_bypass_bit;
 };
 
 /**
diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c
index 381a27f20b51..2321742b3471 100644
--- a/drivers/clk/ingenic/jz4770-cgu.c
+++ b/drivers/clk/ingenic/jz4770-cgu.c
@@ -139,8 +139,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
 			.od_bits = 2,
 			.od_max = 8,
 			.od_encoding = pll_od_encoding,
-			.bypass_reg = CGU_REG_CPPCR1,
-			.no_bypass_bit = true,
+			.bypass_bit = -1,
 			.enable_bit = 7,
 			.stable_bit = 6,
 		},
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 5/6] clk: ingenic: Support overriding PLLs M/N/OD calc algorithm
  2021-05-30 16:49 [PATCH v2 0/6] clk: Ingenic JZ4760(B) support Paul Cercueil
                   ` (3 preceding siblings ...)
  2021-05-30 16:49 ` [PATCH v2 4/6] clk: ingenic: Remove pll_info.no_bypass_bit Paul Cercueil
@ 2021-05-30 16:49 ` Paul Cercueil
  2021-06-28  2:49   ` Stephen Boyd
  2021-05-30 16:49 ` [PATCH v2 6/6] clk: ingenic: Add support for the JZ4760 Paul Cercueil
  2021-06-22 14:48 ` [PATCH v2 0/6] clk: Ingenic JZ4760(B) support 周琰杰
  6 siblings, 1 reply; 17+ messages in thread
From: Paul Cercueil @ 2021-05-30 16:49 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, devicetree, linux-kernel, linux-mips, list,
	周琰杰,
	Paul Cercueil

SoC-specific code can now provide a callback if they need to compute the
M/N/OD values in a specific way.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Tested-by: 周琰杰 (Zhou Yanjie)<zhouyanjie@wanyeetech.com>   # on CU1000-neo/X1000E
---
 drivers/clk/ingenic/cgu.c | 40 ++++++++++++++++++++++++++-------------
 drivers/clk/ingenic/cgu.h |  3 +++
 2 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
index 58f7ab5cf0fe..266c7595d330 100644
--- a/drivers/clk/ingenic/cgu.c
+++ b/drivers/clk/ingenic/cgu.c
@@ -119,28 +119,42 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 		n * od);
 }
 
-static unsigned long
-ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
-		 unsigned long rate, unsigned long parent_rate,
-		 unsigned *pm, unsigned *pn, unsigned *pod)
+static void
+ingenic_pll_calc_m_n_od(const struct ingenic_cgu_pll_info *pll_info,
+			unsigned long rate, unsigned long parent_rate,
+			unsigned int *pm, unsigned int *pn, unsigned int *pod)
 {
-	const struct ingenic_cgu_pll_info *pll_info;
-	unsigned m, n, od;
-
-	pll_info = &clk_info->pll;
-	od = 1;
+	unsigned int m, n, od = 1;
 
 	/*
 	 * The frequency after the input divider must be between 10 and 50 MHz.
 	 * The highest divider yields the best resolution.
 	 */
 	n = parent_rate / (10 * MHZ);
-	n = min_t(unsigned, n, 1 << clk_info->pll.n_bits);
-	n = max_t(unsigned, n, pll_info->n_offset);
+	n = min_t(unsigned int, n, 1 << pll_info->n_bits);
+	n = max_t(unsigned int, n, pll_info->n_offset);
 
 	m = (rate / MHZ) * od * n / (parent_rate / MHZ);
-	m = min_t(unsigned, m, 1 << clk_info->pll.m_bits);
-	m = max_t(unsigned, m, pll_info->m_offset);
+	m = min_t(unsigned int, m, 1 << pll_info->m_bits);
+	m = max_t(unsigned int, m, pll_info->m_offset);
+
+	*pm = m;
+	*pn = n;
+	*pod = od;
+}
+
+static unsigned long
+ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
+		 unsigned long rate, unsigned long parent_rate,
+		 unsigned int *pm, unsigned int *pn, unsigned int *pod)
+{
+	const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
+	unsigned int m, n, od;
+
+	if (pll_info->calc_m_n_od)
+		(*pll_info->calc_m_n_od)(pll_info, rate, parent_rate, &m, &n, &od);
+	else
+		ingenic_pll_calc_m_n_od(pll_info, rate, parent_rate, &m, &n, &od);
 
 	if (pm)
 		*pm = m;
diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h
index 10521d1b7b12..bfc2b9c38a41 100644
--- a/drivers/clk/ingenic/cgu.h
+++ b/drivers/clk/ingenic/cgu.h
@@ -55,6 +55,9 @@ struct ingenic_cgu_pll_info {
 	s8 bypass_bit;
 	u8 enable_bit;
 	u8 stable_bit;
+	void (*calc_m_n_od)(const struct ingenic_cgu_pll_info *pll_info,
+			    unsigned long rate, unsigned long parent_rate,
+			    unsigned int *m, unsigned int *n, unsigned int *od);
 };
 
 /**
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 6/6] clk: ingenic: Add support for the JZ4760
  2021-05-30 16:49 [PATCH v2 0/6] clk: Ingenic JZ4760(B) support Paul Cercueil
                   ` (4 preceding siblings ...)
  2021-05-30 16:49 ` [PATCH v2 5/6] clk: ingenic: Support overriding PLLs M/N/OD calc algorithm Paul Cercueil
@ 2021-05-30 16:49 ` Paul Cercueil
  2021-06-28  2:50   ` Stephen Boyd
  2021-06-22 14:48 ` [PATCH v2 0/6] clk: Ingenic JZ4760(B) support 周琰杰
  6 siblings, 1 reply; 17+ messages in thread
From: Paul Cercueil @ 2021-05-30 16:49 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-clk, devicetree, linux-kernel, linux-mips, list,
	周琰杰,
	Paul Cercueil

Add the CGU code and the compatible string to the TCU driver to support
the JZ4760 SoC.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---

Notes:
    v2: Fix algorithm

 drivers/clk/ingenic/Kconfig            |  10 +
 drivers/clk/ingenic/Makefile           |   1 +
 drivers/clk/ingenic/jz4760-cgu.c       | 428 +++++++++++++++++++++++++
 drivers/clk/ingenic/tcu.c              |   2 +
 include/dt-bindings/clock/jz4760-cgu.h |  54 ++++
 5 files changed, 495 insertions(+)
 create mode 100644 drivers/clk/ingenic/jz4760-cgu.c
 create mode 100644 include/dt-bindings/clock/jz4760-cgu.h

diff --git a/drivers/clk/ingenic/Kconfig b/drivers/clk/ingenic/Kconfig
index 580b0cf69ed5..898f1bc478c9 100644
--- a/drivers/clk/ingenic/Kconfig
+++ b/drivers/clk/ingenic/Kconfig
@@ -25,6 +25,16 @@ config INGENIC_CGU_JZ4725B
 
 	  If building for a JZ4725B SoC, you want to say Y here.
 
+config INGENIC_CGU_JZ4760
+	bool "Ingenic JZ4760 CGU driver"
+	default MACH_JZ4760
+	select INGENIC_CGU_COMMON
+	help
+	  Support the clocks provided by the CGU hardware on Ingenic JZ4760
+	  and compatible SoCs.
+
+	  If building for a JZ4760 SoC, you want to say Y here.
+
 config INGENIC_CGU_JZ4770
 	bool "Ingenic JZ4770 CGU driver"
 	default MACH_JZ4770
diff --git a/drivers/clk/ingenic/Makefile b/drivers/clk/ingenic/Makefile
index aaa4bffe03c6..9edfaf4610b9 100644
--- a/drivers/clk/ingenic/Makefile
+++ b/drivers/clk/ingenic/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_INGENIC_CGU_COMMON)	+= cgu.o pm.o
 obj-$(CONFIG_INGENIC_CGU_JZ4740)	+= jz4740-cgu.o
 obj-$(CONFIG_INGENIC_CGU_JZ4725B)	+= jz4725b-cgu.o
+obj-$(CONFIG_INGENIC_CGU_JZ4760)	+= jz4760-cgu.o
 obj-$(CONFIG_INGENIC_CGU_JZ4770)	+= jz4770-cgu.o
 obj-$(CONFIG_INGENIC_CGU_JZ4780)	+= jz4780-cgu.o
 obj-$(CONFIG_INGENIC_CGU_X1000)		+= x1000-cgu.o
diff --git a/drivers/clk/ingenic/jz4760-cgu.c b/drivers/clk/ingenic/jz4760-cgu.c
new file mode 100644
index 000000000000..14483797a4db
--- /dev/null
+++ b/drivers/clk/ingenic/jz4760-cgu.c
@@ -0,0 +1,428 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * JZ4760 SoC CGU driver
+ * Copyright 2018, Paul Cercueil <paul@crapouillou.net>
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include <linux/clk.h>
+
+#include <dt-bindings/clock/jz4760-cgu.h>
+
+#include "cgu.h"
+#include "pm.h"
+
+#define MHZ (1000 * 1000)
+
+/*
+ * CPM registers offset address definition
+ */
+#define CGU_REG_CPCCR		0x00
+#define CGU_REG_LCR		0x04
+#define CGU_REG_CPPCR0		0x10
+#define CGU_REG_CLKGR0		0x20
+#define CGU_REG_OPCR		0x24
+#define CGU_REG_CLKGR1		0x28
+#define CGU_REG_CPPCR1		0x30
+#define CGU_REG_USBPCR		0x3c
+#define CGU_REG_USBCDR		0x50
+#define CGU_REG_I2SCDR		0x60
+#define CGU_REG_LPCDR		0x64
+#define CGU_REG_MSCCDR		0x68
+#define CGU_REG_UHCCDR		0x6c
+#define CGU_REG_SSICDR		0x74
+#define CGU_REG_CIMCDR		0x7c
+#define CGU_REG_GPSCDR		0x80
+#define CGU_REG_PCMCDR		0x84
+#define CGU_REG_GPUCDR		0x88
+
+static const s8 pll_od_encoding[8] = {
+	0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3,
+};
+
+static const u8 jz4760_cgu_cpccr_div_table[] = {
+	1, 2, 3, 4, 6, 8,
+};
+
+static const u8 jz4760_cgu_pll_half_div_table[] = {
+	2, 1,
+};
+
+static void
+jz4760_cgu_calc_m_n_od(const struct ingenic_cgu_pll_info *pll_info,
+		       unsigned long rate, unsigned long parent_rate,
+		       unsigned int *pm, unsigned int *pn, unsigned int *pod)
+{
+	unsigned int m, n, od, m_max = (1 << pll_info->m_bits) - 2;
+
+	/* The frequency after the N divider must be between 1 and 50 MHz. */
+	n = parent_rate / (1 * MHZ);
+
+	/* The N divider must be >= 2. */
+	n = clamp_val(n, 2, 1 << pll_info->n_bits);
+
+	for (;; n >>= 1) {
+		od = (unsigned int)-1;
+
+		do {
+			m = (rate / MHZ) * (1 << ++od) * n / (parent_rate / MHZ);
+		} while ((m > m_max || m & 1) && (od < 4));
+
+		if (od < 4 && m >= 4 && m <= m_max)
+			break;
+	}
+
+	*pm = m;
+	*pn = n;
+	*pod = 1 << od;
+}
+
+static const struct ingenic_cgu_clk_info jz4760_cgu_clocks[] = {
+
+	/* External clocks */
+
+	[JZ4760_CLK_EXT] = { "ext", CGU_CLK_EXT },
+	[JZ4760_CLK_OSC32K] = { "osc32k", CGU_CLK_EXT },
+
+	/* PLLs */
+
+	[JZ4760_CLK_PLL0] = {
+		"pll0", CGU_CLK_PLL,
+		.parents = { JZ4760_CLK_EXT },
+		.pll = {
+			.reg = CGU_REG_CPPCR0,
+			.rate_multiplier = 1,
+			.m_shift = 23,
+			.m_bits = 8,
+			.m_offset = 0,
+			.n_shift = 18,
+			.n_bits = 4,
+			.n_offset = 0,
+			.od_shift = 16,
+			.od_bits = 2,
+			.od_max = 8,
+			.od_encoding = pll_od_encoding,
+			.bypass_reg = CGU_REG_CPPCR0,
+			.bypass_bit = 9,
+			.enable_bit = 8,
+			.stable_bit = 10,
+			.calc_m_n_od = jz4760_cgu_calc_m_n_od,
+		},
+	},
+
+	[JZ4760_CLK_PLL1] = {
+		/* TODO: PLL1 can depend on PLL0 */
+		"pll1", CGU_CLK_PLL,
+		.parents = { JZ4760_CLK_EXT },
+		.pll = {
+			.reg = CGU_REG_CPPCR1,
+			.rate_multiplier = 1,
+			.m_shift = 23,
+			.m_bits = 8,
+			.m_offset = 0,
+			.n_shift = 18,
+			.n_bits = 4,
+			.n_offset = 0,
+			.od_shift = 16,
+			.od_bits = 2,
+			.od_max = 8,
+			.od_encoding = pll_od_encoding,
+			.bypass_bit = -1,
+			.enable_bit = 7,
+			.stable_bit = 6,
+			.calc_m_n_od = jz4760_cgu_calc_m_n_od,
+		},
+	},
+
+	/* Main clocks */
+
+	[JZ4760_CLK_CCLK] = {
+		"cclk", CGU_CLK_DIV,
+		.parents = { JZ4760_CLK_PLL0, },
+		.div = {
+			CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
+			jz4760_cgu_cpccr_div_table,
+		},
+	},
+	[JZ4760_CLK_HCLK] = {
+		"hclk", CGU_CLK_DIV,
+		.parents = { JZ4760_CLK_PLL0, },
+		.div = {
+			CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0,
+			jz4760_cgu_cpccr_div_table,
+		},
+	},
+	[JZ4760_CLK_SCLK] = {
+		"sclk", CGU_CLK_DIV,
+		.parents = { JZ4760_CLK_PLL0, },
+		.div = {
+			CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1, 0,
+			jz4760_cgu_cpccr_div_table,
+		},
+	},
+	[JZ4760_CLK_H2CLK] = {
+		"h2clk", CGU_CLK_DIV,
+		.parents = { JZ4760_CLK_PLL0, },
+		.div = {
+			CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, 0,
+			jz4760_cgu_cpccr_div_table,
+		},
+	},
+	[JZ4760_CLK_MCLK] = {
+		"mclk", CGU_CLK_DIV,
+		.parents = { JZ4760_CLK_PLL0, },
+		.div = {
+			CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
+			jz4760_cgu_cpccr_div_table,
+		},
+	},
+	[JZ4760_CLK_PCLK] = {
+		"pclk", CGU_CLK_DIV,
+		.parents = { JZ4760_CLK_PLL0, },
+		.div = {
+			CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0,
+			jz4760_cgu_cpccr_div_table,
+		},
+	},
+
+	/* Divided clocks */
+
+	[JZ4760_CLK_PLL0_HALF] = {
+		"pll0_half", CGU_CLK_DIV,
+		.parents = { JZ4760_CLK_PLL0 },
+		.div = {
+			CGU_REG_CPCCR, 21, 1, 1, 22, -1, -1, 0,
+			jz4760_cgu_pll_half_div_table,
+		},
+	},
+
+	/* Those divided clocks can connect to PLL0 or PLL1 */
+
+	[JZ4760_CLK_UHC] = {
+		"uhc", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1, },
+		.mux = { CGU_REG_UHCCDR, 31, 1 },
+		.div = { CGU_REG_UHCCDR, 0, 1, 4, -1, -1, -1 },
+		.gate = { CGU_REG_CLKGR0, 24 },
+	},
+	[JZ4760_CLK_GPU] = {
+		"gpu", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1, },
+		.mux = { CGU_REG_GPUCDR, 31, 1 },
+		.div = { CGU_REG_GPUCDR, 0, 1, 3, -1, -1, -1 },
+		.gate = { CGU_REG_CLKGR1, 9 },
+	},
+	[JZ4760_CLK_LPCLK_DIV] = {
+		"lpclk_div", CGU_CLK_DIV | CGU_CLK_MUX,
+		.parents = { JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1, },
+		.mux = { CGU_REG_LPCDR, 29, 1 },
+		.div = { CGU_REG_LPCDR, 0, 1, 11, -1, -1, -1 },
+	},
+	[JZ4760_CLK_TVE] = {
+		"tve", CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4760_CLK_LPCLK_DIV, JZ4760_CLK_EXT, },
+		.mux = { CGU_REG_LPCDR, 31, 1 },
+		.gate = { CGU_REG_CLKGR0, 27 },
+	},
+	[JZ4760_CLK_LPCLK] = {
+		"lpclk", CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4760_CLK_LPCLK_DIV, JZ4760_CLK_TVE, },
+		.mux = { CGU_REG_LPCDR, 30, 1 },
+		.gate = { CGU_REG_CLKGR0, 28 },
+	},
+	[JZ4760_CLK_GPS] = {
+		"gps", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1, },
+		.mux = { CGU_REG_GPSCDR, 31, 1 },
+		.div = { CGU_REG_GPSCDR, 0, 1, 4, -1, -1, -1 },
+		.gate = { CGU_REG_CLKGR0, 22 },
+	},
+
+	/* Those divided clocks can connect to EXT, PLL0 or PLL1 */
+
+	[JZ4760_CLK_PCM] = {
+		"pcm", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4760_CLK_EXT, -1,
+			JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1 },
+		.mux = { CGU_REG_PCMCDR, 30, 2 },
+		.div = { CGU_REG_PCMCDR, 0, 1, 9, -1, -1, -1, BIT(0) },
+		.gate = { CGU_REG_CLKGR1, 8 },
+	},
+	[JZ4760_CLK_I2S] = {
+		"i2s", CGU_CLK_DIV | CGU_CLK_MUX,
+		.parents = { JZ4760_CLK_EXT, -1,
+			JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1 },
+		.mux = { CGU_REG_I2SCDR, 30, 2 },
+		.div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1, BIT(0) },
+	},
+	[JZ4760_CLK_OTG] = {
+		"usb", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4760_CLK_EXT, -1,
+			JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1 },
+		.mux = { CGU_REG_USBCDR, 30, 2 },
+		.div = { CGU_REG_USBCDR, 0, 1, 8, -1, -1, -1 },
+		.gate = { CGU_REG_CLKGR0, 2 },
+	},
+
+	/* Those divided clocks can connect to EXT or PLL0 */
+	[JZ4760_CLK_MMC_MUX] = {
+		"mmc_mux", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { JZ4760_CLK_EXT, JZ4760_CLK_PLL0_HALF, },
+		.mux = { CGU_REG_MSCCDR, 31, 1 },
+		.div = { CGU_REG_MSCCDR, 0, 1, 6, -1, -1, -1, BIT(0) },
+	},
+	[JZ4760_CLK_SSI_MUX] = {
+		"ssi_mux", CGU_CLK_DIV | CGU_CLK_MUX,
+		.parents = { JZ4760_CLK_EXT, JZ4760_CLK_PLL0_HALF, },
+		.mux = { CGU_REG_SSICDR, 31, 1 },
+		.div = { CGU_REG_SSICDR, 0, 1, 6, -1, -1, -1, BIT(0) },
+	},
+
+	/* These divided clock can connect to PLL0 only */
+	[JZ4760_CLK_CIM] = {
+		"cim", CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_PLL0_HALF },
+		.div = { CGU_REG_CIMCDR, 0, 1, 8, -1, -1, -1 },
+		.gate = { CGU_REG_CLKGR0, 26 },
+	},
+
+	/* Gate-only clocks */
+
+	[JZ4760_CLK_SSI0] = {
+		"ssi0", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_SSI_MUX, },
+		.gate = { CGU_REG_CLKGR0, 4 },
+	},
+	[JZ4760_CLK_SSI1] = {
+		"ssi1", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_SSI_MUX, },
+		.gate = { CGU_REG_CLKGR0, 19 },
+	},
+	[JZ4760_CLK_SSI2] = {
+		"ssi2", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_SSI_MUX, },
+		.gate = { CGU_REG_CLKGR0, 20 },
+	},
+	[JZ4760_CLK_DMA] = {
+		"dma", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_H2CLK, },
+		.gate = { CGU_REG_CLKGR0, 21 },
+	},
+	[JZ4760_CLK_I2C0] = {
+		"i2c0", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR0, 5 },
+	},
+	[JZ4760_CLK_I2C1] = {
+		"i2c1", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR0, 6 },
+	},
+	[JZ4760_CLK_UART0] = {
+		"uart0", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR0, 15 },
+	},
+	[JZ4760_CLK_UART1] = {
+		"uart1", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR0, 16 },
+	},
+	[JZ4760_CLK_UART2] = {
+		"uart2", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR0, 17 },
+	},
+	[JZ4760_CLK_UART3] = {
+		"uart3", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR0, 18 },
+	},
+	[JZ4760_CLK_IPU] = {
+		"ipu", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_HCLK, },
+		.gate = { CGU_REG_CLKGR0, 29 },
+	},
+	[JZ4760_CLK_ADC] = {
+		"adc", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR0, 14 },
+	},
+	[JZ4760_CLK_AIC] = {
+		"aic", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR0, 8 },
+	},
+	[JZ4760_CLK_VPU] = {
+		"vpu", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_HCLK, },
+		.gate = { CGU_REG_LCR, 30, false, 150 },
+	},
+	[JZ4760_CLK_MMC0] = {
+		"mmc0", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_MMC_MUX, },
+		.gate = { CGU_REG_CLKGR0, 3 },
+	},
+	[JZ4760_CLK_MMC1] = {
+		"mmc1", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_MMC_MUX, },
+		.gate = { CGU_REG_CLKGR0, 11 },
+	},
+	[JZ4760_CLK_MMC2] = {
+		"mmc2", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_MMC_MUX, },
+		.gate = { CGU_REG_CLKGR0, 12 },
+	},
+	[JZ4760_CLK_UHC_PHY] = {
+		"uhc_phy", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_UHC, },
+		.gate = { CGU_REG_OPCR, 5 },
+	},
+	[JZ4760_CLK_OTG_PHY] = {
+		"usb_phy", CGU_CLK_GATE,
+		.parents = { JZ4760_CLK_OTG },
+		.gate = { CGU_REG_OPCR, 7, true, 50 },
+	},
+
+	/* Custom clocks */
+	[JZ4760_CLK_EXT512] = {
+		"ext/512", CGU_CLK_FIXDIV,
+		.parents = { JZ4760_CLK_EXT },
+		.fixdiv = { 512 },
+	},
+	[JZ4760_CLK_RTC] = {
+		"rtc", CGU_CLK_MUX,
+		.parents = { JZ4760_CLK_EXT512, JZ4760_CLK_OSC32K, },
+		.mux = { CGU_REG_OPCR, 2, 1},
+	},
+};
+
+static void __init jz4760_cgu_init(struct device_node *np)
+{
+	struct ingenic_cgu *cgu;
+	int retval;
+
+	cgu = ingenic_cgu_new(jz4760_cgu_clocks,
+			      ARRAY_SIZE(jz4760_cgu_clocks), np);
+	if (!cgu) {
+		pr_err("%s: failed to initialise CGU\n", __func__);
+		return;
+	}
+
+	retval = ingenic_cgu_register_clocks(cgu);
+	if (retval)
+		pr_err("%s: failed to register CGU Clocks\n", __func__);
+
+	ingenic_cgu_register_syscore_ops(cgu);
+}
+
+/* We only probe via devicetree, no need for a platform driver */
+CLK_OF_DECLARE_DRIVER(jz4760_cgu, "ingenic,jz4760-cgu", jz4760_cgu_init);
+
+/* JZ4760B has some small differences, but we don't implement them. */
+CLK_OF_DECLARE_DRIVER(jz4760b_cgu, "ingenic,jz4760b-cgu", jz4760_cgu_init);
diff --git a/drivers/clk/ingenic/tcu.c b/drivers/clk/ingenic/tcu.c
index 9382dc3aa27e..77acfbeb4830 100644
--- a/drivers/clk/ingenic/tcu.c
+++ b/drivers/clk/ingenic/tcu.c
@@ -326,6 +326,7 @@ static const struct ingenic_soc_info x1000_soc_info = {
 static const struct of_device_id __maybe_unused ingenic_tcu_of_match[] __initconst = {
 	{ .compatible = "ingenic,jz4740-tcu", .data = &jz4740_soc_info, },
 	{ .compatible = "ingenic,jz4725b-tcu", .data = &jz4725b_soc_info, },
+	{ .compatible = "ingenic,jz4760-tcu", .data = &jz4770_soc_info, },
 	{ .compatible = "ingenic,jz4770-tcu", .data = &jz4770_soc_info, },
 	{ .compatible = "ingenic,x1000-tcu", .data = &x1000_soc_info, },
 	{ /* sentinel */ }
@@ -477,5 +478,6 @@ static void __init ingenic_tcu_init(struct device_node *np)
 
 CLK_OF_DECLARE_DRIVER(jz4740_cgu, "ingenic,jz4740-tcu", ingenic_tcu_init);
 CLK_OF_DECLARE_DRIVER(jz4725b_cgu, "ingenic,jz4725b-tcu", ingenic_tcu_init);
+CLK_OF_DECLARE_DRIVER(jz4760_cgu, "ingenic,jz4760-tcu", ingenic_tcu_init);
 CLK_OF_DECLARE_DRIVER(jz4770_cgu, "ingenic,jz4770-tcu", ingenic_tcu_init);
 CLK_OF_DECLARE_DRIVER(x1000_cgu, "ingenic,x1000-tcu", ingenic_tcu_init);
diff --git a/include/dt-bindings/clock/jz4760-cgu.h b/include/dt-bindings/clock/jz4760-cgu.h
new file mode 100644
index 000000000000..4bb2e19c4743
--- /dev/null
+++ b/include/dt-bindings/clock/jz4760-cgu.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This header provides clock numbers for the ingenic,jz4760-cgu DT binding.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_JZ4760_CGU_H__
+#define __DT_BINDINGS_CLOCK_JZ4760_CGU_H__
+
+#define JZ4760_CLK_EXT		0
+#define JZ4760_CLK_OSC32K	1
+#define JZ4760_CLK_PLL0		2
+#define JZ4760_CLK_PLL0_HALF	3
+#define JZ4760_CLK_PLL1		4
+#define JZ4760_CLK_CCLK		5
+#define JZ4760_CLK_HCLK		6
+#define JZ4760_CLK_SCLK		7
+#define JZ4760_CLK_H2CLK	8
+#define JZ4760_CLK_MCLK		9
+#define JZ4760_CLK_PCLK		10
+#define JZ4760_CLK_MMC_MUX	11
+#define JZ4760_CLK_MMC0		12
+#define JZ4760_CLK_MMC1		13
+#define JZ4760_CLK_MMC2		14
+#define JZ4760_CLK_CIM		15
+#define JZ4760_CLK_UHC		16
+#define JZ4760_CLK_GPU		17
+#define JZ4760_CLK_GPS		18
+#define JZ4760_CLK_SSI_MUX	19
+#define JZ4760_CLK_PCM		20
+#define JZ4760_CLK_I2S		21
+#define JZ4760_CLK_OTG		22
+#define JZ4760_CLK_SSI0		23
+#define JZ4760_CLK_SSI1		24
+#define JZ4760_CLK_SSI2		25
+#define JZ4760_CLK_DMA		26
+#define JZ4760_CLK_I2C0		27
+#define JZ4760_CLK_I2C1		28
+#define JZ4760_CLK_UART0	29
+#define JZ4760_CLK_UART1	30
+#define JZ4760_CLK_UART2	31
+#define JZ4760_CLK_UART3	32
+#define JZ4760_CLK_IPU		33
+#define JZ4760_CLK_ADC		34
+#define JZ4760_CLK_AIC		35
+#define JZ4760_CLK_VPU		36
+#define JZ4760_CLK_UHC_PHY	37
+#define JZ4760_CLK_OTG_PHY	38
+#define JZ4760_CLK_EXT512	39
+#define JZ4760_CLK_RTC		40
+#define JZ4760_CLK_LPCLK_DIV	41
+#define JZ4760_CLK_TVE		42
+#define JZ4760_CLK_LPCLK	43
+
+#endif /* __DT_BINDINGS_CLOCK_JZ4760_CGU_H__ */
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 4/6] clk: ingenic: Remove pll_info.no_bypass_bit
  2021-05-30 16:49 ` [PATCH v2 4/6] clk: ingenic: Remove pll_info.no_bypass_bit Paul Cercueil
@ 2021-06-01 14:07   ` Zhou Yanjie
  2021-06-28  2:49   ` Stephen Boyd
  1 sibling, 0 replies; 17+ messages in thread
From: Zhou Yanjie @ 2021-06-01 14:07 UTC (permalink / raw)
  To: Paul Cercueil, Michael Turquette, Stephen Boyd
  Cc: linux-clk, devicetree, linux-kernel, linux-mips, list


On 2021/5/31 上午12:49, Paul Cercueil wrote:
> We can express that a PLL has no bypass bit by simply setting the
> .bypass_bit field to a negative value.
>
> Signed-off-by: Paul Cercueil <paul@crapouillou.net>
> ---
>   drivers/clk/ingenic/cgu.c        | 4 ++--
>   drivers/clk/ingenic/cgu.h        | 7 +++----
>   drivers/clk/ingenic/jz4770-cgu.c | 3 +--
>   3 files changed, 6 insertions(+), 8 deletions(-)


Tested-by: 周琰杰 (Zhou Yanjie)<zhouyanjie@wanyeetech.com>    # on CU1830-neo/X1830


>
> diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
> index 7686072aff8f..58f7ab5cf0fe 100644
> --- a/drivers/clk/ingenic/cgu.c
> +++ b/drivers/clk/ingenic/cgu.c
> @@ -99,7 +99,7 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
>   	od_enc = ctl >> pll_info->od_shift;
>   	od_enc &= GENMASK(pll_info->od_bits - 1, 0);
>   
> -	if (!pll_info->no_bypass_bit) {
> +	if (pll_info->bypass_bit >= 0) {
>   		ctl = readl(cgu->base + pll_info->bypass_reg);
>   
>   		bypass = !!(ctl & BIT(pll_info->bypass_bit));
> @@ -226,7 +226,7 @@ static int ingenic_pll_enable(struct clk_hw *hw)
>   	u32 ctl;
>   
>   	spin_lock_irqsave(&cgu->lock, flags);
> -	if (!pll_info->no_bypass_bit) {
> +	if (pll_info->bypass_bit >= 0) {
>   		ctl = readl(cgu->base + pll_info->bypass_reg);
>   
>   		ctl &= ~BIT(pll_info->bypass_bit);
> diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h
> index 44d97a259692..10521d1b7b12 100644
> --- a/drivers/clk/ingenic/cgu.h
> +++ b/drivers/clk/ingenic/cgu.h
> @@ -39,10 +39,10 @@
>    *               their encoded values in the PLL control register, or -1 for
>    *               unsupported values
>    * @bypass_reg: the offset of the bypass control register within the CGU
> - * @bypass_bit: the index of the bypass bit in the PLL control register
> + * @bypass_bit: the index of the bypass bit in the PLL control register, or
> + *              -1 if there is no bypass bit
>    * @enable_bit: the index of the enable bit in the PLL control register
>    * @stable_bit: the index of the stable bit in the PLL control register
> - * @no_bypass_bit: if set, the PLL has no bypass functionality
>    */
>   struct ingenic_cgu_pll_info {
>   	unsigned reg;
> @@ -52,10 +52,9 @@ struct ingenic_cgu_pll_info {
>   	u8 n_shift, n_bits, n_offset;
>   	u8 od_shift, od_bits, od_max;
>   	unsigned bypass_reg;
> -	u8 bypass_bit;
> +	s8 bypass_bit;
>   	u8 enable_bit;
>   	u8 stable_bit;
> -	bool no_bypass_bit;
>   };
>   
>   /**
> diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c
> index 381a27f20b51..2321742b3471 100644
> --- a/drivers/clk/ingenic/jz4770-cgu.c
> +++ b/drivers/clk/ingenic/jz4770-cgu.c
> @@ -139,8 +139,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
>   			.od_bits = 2,
>   			.od_max = 8,
>   			.od_encoding = pll_od_encoding,
> -			.bypass_reg = CGU_REG_CPPCR1,
> -			.no_bypass_bit = true,
> +			.bypass_bit = -1,
>   			.enable_bit = 7,
>   			.stable_bit = 6,
>   		},

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 3/6] clk: ingenic: Read bypass register only when there is one
  2021-05-30 16:49 ` [PATCH v2 3/6] clk: ingenic: Read bypass register only when there is one Paul Cercueil
@ 2021-06-01 14:08   ` Zhou Yanjie
  2021-06-28  2:49   ` Stephen Boyd
  1 sibling, 0 replies; 17+ messages in thread
From: Zhou Yanjie @ 2021-06-01 14:08 UTC (permalink / raw)
  To: Paul Cercueil, Michael Turquette, Stephen Boyd
  Cc: linux-clk, devicetree, linux-kernel, linux-mips, list


On 2021/5/31 上午12:49, Paul Cercueil wrote:
> Rework the clock code so that the bypass register is only read when
> there is actually a bypass functionality.
>
> Signed-off-by: Paul Cercueil <paul@crapouillou.net>
> ---
>   drivers/clk/ingenic/cgu.c | 19 +++++++++++--------
>   1 file changed, 11 insertions(+), 8 deletions(-)


Tested-by: 周琰杰 (Zhou Yanjie)<zhouyanjie@wanyeetech.com>    # on CU1830-neo/X1830


>
> diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
> index 0619d45a950c..7686072aff8f 100644
> --- a/drivers/clk/ingenic/cgu.c
> +++ b/drivers/clk/ingenic/cgu.c
> @@ -99,13 +99,14 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
>   	od_enc = ctl >> pll_info->od_shift;
>   	od_enc &= GENMASK(pll_info->od_bits - 1, 0);
>   
> -	ctl = readl(cgu->base + pll_info->bypass_reg);
> +	if (!pll_info->no_bypass_bit) {
> +		ctl = readl(cgu->base + pll_info->bypass_reg);
>   
> -	bypass = !pll_info->no_bypass_bit &&
> -		 !!(ctl & BIT(pll_info->bypass_bit));
> +		bypass = !!(ctl & BIT(pll_info->bypass_bit));
>   
> -	if (bypass)
> -		return parent_rate;
> +		if (bypass)
> +			return parent_rate;
> +	}
>   
>   	for (od = 0; od < pll_info->od_max; od++) {
>   		if (pll_info->od_encoding[od] == od_enc)
> @@ -225,11 +226,13 @@ static int ingenic_pll_enable(struct clk_hw *hw)
>   	u32 ctl;
>   
>   	spin_lock_irqsave(&cgu->lock, flags);
> -	ctl = readl(cgu->base + pll_info->bypass_reg);
> +	if (!pll_info->no_bypass_bit) {
> +		ctl = readl(cgu->base + pll_info->bypass_reg);
>   
> -	ctl &= ~BIT(pll_info->bypass_bit);
> +		ctl &= ~BIT(pll_info->bypass_bit);
>   
> -	writel(ctl, cgu->base + pll_info->bypass_reg);
> +		writel(ctl, cgu->base + pll_info->bypass_reg);
> +	}
>   
>   	ctl = readl(cgu->base + pll_info->reg);
>   

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/6] clk: Ingenic JZ4760(B) support
  2021-05-30 16:49 [PATCH v2 0/6] clk: Ingenic JZ4760(B) support Paul Cercueil
                   ` (5 preceding siblings ...)
  2021-05-30 16:49 ` [PATCH v2 6/6] clk: ingenic: Add support for the JZ4760 Paul Cercueil
@ 2021-06-22 14:48 ` 周琰杰
  6 siblings, 0 replies; 17+ messages in thread
From: 周琰杰 @ 2021-06-22 14:48 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: Michael Turquette, Stephen Boyd, linux-clk, devicetree,
	linux-kernel, linux-mips, list

Hi,

A gentle ping :)

Here are some new patches that need to be based on this series.

Thanks and best regards!

于 Sun, 30 May 2021 17:49:17 +0100
Paul Cercueil <paul@crapouillou.net> 写道:

> Hi,
> 
> Here is (finally) my v2 of the JZ4760(B) patchset.
> 
> Patches 1-5 are the exact same as in v1.
> 
> Patch 6's algorithm was updated with Zhou's feedback.
> 
> Cheers,
> -Paul
> 
> Paul Cercueil (6):
>   dt-bindings: clock: ingenic: Add ingenic,jz4760{,b}-cgu compatibles
>   clk: Support bypassing dividers
>   clk: ingenic: Read bypass register only when there is one
>   clk: ingenic: Remove pll_info.no_bypass_bit
>   clk: ingenic: Support overriding PLLs M/N/OD calc algorithm
>   clk: ingenic: Add support for the JZ4760
> 
>  .../bindings/clock/ingenic,cgu.yaml           |   4 +
>  drivers/clk/ingenic/Kconfig                   |  10 +
>  drivers/clk/ingenic/Makefile                  |   1 +
>  drivers/clk/ingenic/cgu.c                     |  92 ++--
>  drivers/clk/ingenic/cgu.h                     |  12 +-
>  drivers/clk/ingenic/jz4725b-cgu.c             |  12 +-
>  drivers/clk/ingenic/jz4740-cgu.c              |  12 +-
>  drivers/clk/ingenic/jz4760-cgu.c              | 428
> ++++++++++++++++++ drivers/clk/ingenic/jz4770-cgu.c              |
> 15 +- drivers/clk/ingenic/tcu.c                     |   2 +
>  include/dt-bindings/clock/jz4760-cgu.h        |  54 +++
>  11 files changed, 586 insertions(+), 56 deletions(-)
>  create mode 100644 drivers/clk/ingenic/jz4760-cgu.c
>  create mode 100644 include/dt-bindings/clock/jz4760-cgu.h
> 


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 1/6] dt-bindings: clock: ingenic: Add ingenic,jz4760{,b}-cgu compatibles
  2021-05-30 16:49 ` [PATCH v2 1/6] dt-bindings: clock: ingenic: Add ingenic,jz4760{,b}-cgu compatibles Paul Cercueil
@ 2021-06-28  2:49   ` Stephen Boyd
  0 siblings, 0 replies; 17+ messages in thread
From: Stephen Boyd @ 2021-06-28  2:49 UTC (permalink / raw)
  To: Michael Turquette, Paul Cercueil
  Cc: linux-clk, devicetree, linux-kernel, linux-mips, list,
	周琰杰,
	Paul Cercueil, Rob Herring

Quoting Paul Cercueil (2021-05-30 09:49:18)
> Add ingenic,jz4760-cgu and ingenic,jz4760b-cgu compatible strings for
> the JZ4760 and JZ4760B SoCs respectively.
> 
> Signed-off-by: Paul Cercueil <paul@crapouillou.net>
> Acked-by: Rob Herring <robh@kernel.org>
> ---

Applied to clk-next

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 2/6] clk: Support bypassing dividers
  2021-05-30 16:49 ` [PATCH v2 2/6] clk: Support bypassing dividers Paul Cercueil
@ 2021-06-28  2:49   ` Stephen Boyd
  0 siblings, 0 replies; 17+ messages in thread
From: Stephen Boyd @ 2021-06-28  2:49 UTC (permalink / raw)
  To: Michael Turquette, Paul Cercueil
  Cc: linux-clk, devicetree, linux-kernel, linux-mips, list,
	周琰杰,
	Paul Cercueil

Quoting Paul Cercueil (2021-05-30 09:49:19)
> When a clock is declared as both CGU_CLK_DIV and CGU_CLK_MUX, the CGU
> code expects the mux to be applied first, the divider second.
> 
> On the JZ4760, and maybe on some other SoCs, some clocks also have a mux
> setting and a divider, but the divider is not applied to all parents
> selectable from the mux.
> 
> This could be solved by creating two clocks, one with CGU_CLK_DIV and
> one with CGU_CLK_MUX, but that would increase the number of clocks.
> 
> Instead, add a 8-bit mask to CGU_CLK_DIV clocks. If the bit
> corresponding to the parent clock's index is set, the divider is
> bypassed.
> 
> Signed-off-by: Paul Cercueil <paul@crapouillou.net>
> ---

Applied to clk-next

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 3/6] clk: ingenic: Read bypass register only when there is one
  2021-05-30 16:49 ` [PATCH v2 3/6] clk: ingenic: Read bypass register only when there is one Paul Cercueil
  2021-06-01 14:08   ` Zhou Yanjie
@ 2021-06-28  2:49   ` Stephen Boyd
  1 sibling, 0 replies; 17+ messages in thread
From: Stephen Boyd @ 2021-06-28  2:49 UTC (permalink / raw)
  To: Michael Turquette, Paul Cercueil
  Cc: linux-clk, devicetree, linux-kernel, linux-mips, list,
	周琰杰,
	Paul Cercueil

Quoting Paul Cercueil (2021-05-30 09:49:20)
> Rework the clock code so that the bypass register is only read when
> there is actually a bypass functionality.
> 
> Signed-off-by: Paul Cercueil <paul@crapouillou.net>
> ---

Applied to clk-next

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 4/6] clk: ingenic: Remove pll_info.no_bypass_bit
  2021-05-30 16:49 ` [PATCH v2 4/6] clk: ingenic: Remove pll_info.no_bypass_bit Paul Cercueil
  2021-06-01 14:07   ` Zhou Yanjie
@ 2021-06-28  2:49   ` Stephen Boyd
  1 sibling, 0 replies; 17+ messages in thread
From: Stephen Boyd @ 2021-06-28  2:49 UTC (permalink / raw)
  To: Michael Turquette, Paul Cercueil
  Cc: linux-clk, devicetree, linux-kernel, linux-mips, list,
	周琰杰,
	Paul Cercueil

Quoting Paul Cercueil (2021-05-30 09:49:21)
> We can express that a PLL has no bypass bit by simply setting the
> .bypass_bit field to a negative value.
> 
> Signed-off-by: Paul Cercueil <paul@crapouillou.net>
> ---

Applied to clk-next

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 5/6] clk: ingenic: Support overriding PLLs M/N/OD calc algorithm
  2021-05-30 16:49 ` [PATCH v2 5/6] clk: ingenic: Support overriding PLLs M/N/OD calc algorithm Paul Cercueil
@ 2021-06-28  2:49   ` Stephen Boyd
  0 siblings, 0 replies; 17+ messages in thread
From: Stephen Boyd @ 2021-06-28  2:49 UTC (permalink / raw)
  To: Michael Turquette, Paul Cercueil
  Cc: linux-clk, devicetree, linux-kernel, linux-mips, list,
	周琰杰,
	Paul Cercueil

Quoting Paul Cercueil (2021-05-30 09:49:22)
> SoC-specific code can now provide a callback if they need to compute the
> M/N/OD values in a specific way.
> 
> Signed-off-by: Paul Cercueil <paul@crapouillou.net>
> Tested-by: 周琰杰 (Zhou Yanjie)<zhouyanjie@wanyeetech.com>   # on CU1000-neo/X1000E
> ---

Applied to clk-next

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 6/6] clk: ingenic: Add support for the JZ4760
  2021-05-30 16:49 ` [PATCH v2 6/6] clk: ingenic: Add support for the JZ4760 Paul Cercueil
@ 2021-06-28  2:50   ` Stephen Boyd
  2021-06-30 12:18     ` Paul Cercueil
  0 siblings, 1 reply; 17+ messages in thread
From: Stephen Boyd @ 2021-06-28  2:50 UTC (permalink / raw)
  To: Michael Turquette, Paul Cercueil
  Cc: linux-clk, devicetree, linux-kernel, linux-mips, list,
	周琰杰,
	Paul Cercueil

Quoting Paul Cercueil (2021-05-30 09:49:23)
> Add the CGU code and the compatible string to the TCU driver to support
> the JZ4760 SoC.
> 
> Signed-off-by: Paul Cercueil <paul@crapouillou.net>
> ---

Applied to clk-next

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 6/6] clk: ingenic: Add support for the JZ4760
  2021-06-28  2:50   ` Stephen Boyd
@ 2021-06-30 12:18     ` Paul Cercueil
  0 siblings, 0 replies; 17+ messages in thread
From: Paul Cercueil @ 2021-06-30 12:18 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Michael Turquette, linux-clk, devicetree, linux-kernel,
	linux-mips, list, 周琰杰

Thank you Stephen.

-Paul


Le dim., juin 27 2021 at 19:50:03 -0700, Stephen Boyd 
<sboyd@kernel.org> a écrit :
> Quoting Paul Cercueil (2021-05-30 09:49:23)
>>  Add the CGU code and the compatible string to the TCU driver to 
>> support
>>  the JZ4760 SoC.
>> 
>>  Signed-off-by: Paul Cercueil <paul@crapouillou.net>
>>  ---
> 
> Applied to clk-next



^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2021-06-30 12:18 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-30 16:49 [PATCH v2 0/6] clk: Ingenic JZ4760(B) support Paul Cercueil
2021-05-30 16:49 ` [PATCH v2 1/6] dt-bindings: clock: ingenic: Add ingenic,jz4760{,b}-cgu compatibles Paul Cercueil
2021-06-28  2:49   ` Stephen Boyd
2021-05-30 16:49 ` [PATCH v2 2/6] clk: Support bypassing dividers Paul Cercueil
2021-06-28  2:49   ` Stephen Boyd
2021-05-30 16:49 ` [PATCH v2 3/6] clk: ingenic: Read bypass register only when there is one Paul Cercueil
2021-06-01 14:08   ` Zhou Yanjie
2021-06-28  2:49   ` Stephen Boyd
2021-05-30 16:49 ` [PATCH v2 4/6] clk: ingenic: Remove pll_info.no_bypass_bit Paul Cercueil
2021-06-01 14:07   ` Zhou Yanjie
2021-06-28  2:49   ` Stephen Boyd
2021-05-30 16:49 ` [PATCH v2 5/6] clk: ingenic: Support overriding PLLs M/N/OD calc algorithm Paul Cercueil
2021-06-28  2:49   ` Stephen Boyd
2021-05-30 16:49 ` [PATCH v2 6/6] clk: ingenic: Add support for the JZ4760 Paul Cercueil
2021-06-28  2:50   ` Stephen Boyd
2021-06-30 12:18     ` Paul Cercueil
2021-06-22 14:48 ` [PATCH v2 0/6] clk: Ingenic JZ4760(B) support 周琰杰

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).