* [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
* 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
* [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
* 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
* [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
* 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 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
* [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
* 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 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
* [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 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
* 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