linux-clk.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] Renesas R8A77980 CPG/MSSR RPC clock support
@ 2018-12-04 19:43 Sergei Shtylyov
  2018-12-04 19:48 ` [PATCH v2 1/4] clk: renesas: rcar-gen3-cpg: factor out cpg_reg_modify() Sergei Shtylyov
                   ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: Sergei Shtylyov @ 2018-12-04 19:43 UTC (permalink / raw)
  To: linux-renesas-soc, Michael Turquette, Stephen Boyd,
	Geert Uytterhoeven, linux-clk

Hello!

Here's the set of 4 patches against the 'clk-renesas' branch of Geert Uytterhoeven's
'renesas-drivers.git' repo. We're adding support for the R8A77980 CPG/MSSR RPC clocks...

[1/4] clk: renesas: rcar-gen3-cpg: factor out cpg_reg_modify()
[2/4] clk: renesas: rcar-gen3-cpg: add spinlock
[3/4] clk: renesas: rcar-gen3-cpg: add RPC clocks
[4/4] clk: renesas: r8a77980-cpg-mssr: add RPC clocks

MBR, Sergei

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

* [PATCH v2 1/4] clk: renesas: rcar-gen3-cpg: factor out cpg_reg_modify()
  2018-12-04 19:43 [PATCH v2 0/4] Renesas R8A77980 CPG/MSSR RPC clock support Sergei Shtylyov
@ 2018-12-04 19:48 ` Sergei Shtylyov
  2018-12-14 15:32   ` Simon Horman
  2019-01-21 13:25   ` Geert Uytterhoeven
  2018-12-04 19:49 ` [PATCH v2 2/4] clk: renesas: rcar-gen3-cpg: add spinlock Sergei Shtylyov
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 13+ messages in thread
From: Sergei Shtylyov @ 2018-12-04 19:48 UTC (permalink / raw)
  To: linux-renesas-soc, Michael Turquette, Stephen Boyd,
	Geert Uytterhoeven, linux-clk

There's quite often repeated sequence of a CPG register read-modify-write,
so it seems worth factoring it out into a function -- this saves 68 bytes
of the object code (AArch64 gcc 4.8.5) and simplifies protecting all such
sequences with a spinlock in the next patch...

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

---
Changes in version 2:
- moved the readl() call from the initializer in cpg_reg_modify();
- adjusted the patch description.

 drivers/clk/renesas/rcar-gen3-cpg.c |   38 ++++++++++++++++++------------------
 1 file changed, 20 insertions(+), 18 deletions(-)

Index: renesas-drivers/drivers/clk/renesas/rcar-gen3-cpg.c
===================================================================
--- renesas-drivers.orig/drivers/clk/renesas/rcar-gen3-cpg.c
+++ renesas-drivers/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -30,6 +30,16 @@
 
 #define CPG_RCKCR_CKSEL	BIT(15)	/* RCLK Clock Source Select */
 
+static void cpg_reg_modify(void __iomem *reg, u32 clear, u32 set)
+{
+	u32 val;
+
+	val = readl(reg);
+	val &= ~clear;
+	val |= set;
+	writel(val, reg);
+};
+
 struct cpg_simple_notifier {
 	struct notifier_block nb;
 	void __iomem *reg;
@@ -118,7 +128,6 @@ static int cpg_z_clk_set_rate(struct clk
 	struct cpg_z_clk *zclk = to_z_clk(hw);
 	unsigned int mult;
 	unsigned int i;
-	u32 val, kick;
 
 	/* Factor of 2 is for fixed divider */
 	mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL * 2, parent_rate);
@@ -127,17 +136,14 @@ static int cpg_z_clk_set_rate(struct clk
 	if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK)
 		return -EBUSY;
 
-	val = readl(zclk->reg) & ~zclk->mask;
-	val |= ((32 - mult) << __ffs(zclk->mask)) & zclk->mask;
-	writel(val, zclk->reg);
+	cpg_reg_modify(zclk->reg, zclk->mask,
+		       ((32 - mult) << __ffs(zclk->mask)) & zclk->mask);
 
 	/*
 	 * Set KICK bit in FRQCRB to update hardware setting and wait for
 	 * clock change completion.
 	 */
-	kick = readl(zclk->kick_reg);
-	kick |= CPG_FRQCRB_KICK;
-	writel(kick, zclk->kick_reg);
+	cpg_reg_modify(zclk->kick_reg, 0, CPG_FRQCRB_KICK);
 
 	/*
 	 * Note: There is no HW information about the worst case latency.
@@ -262,12 +268,10 @@ static const struct sd_div_table cpg_sd_
 static int cpg_sd_clock_enable(struct clk_hw *hw)
 {
 	struct sd_clock *clock = to_sd_clock(hw);
-	u32 val = readl(clock->csn.reg);
-
-	val &= ~(CPG_SD_STP_MASK);
-	val |= clock->div_table[clock->cur_div_idx].val & CPG_SD_STP_MASK;
 
-	writel(val, clock->csn.reg);
+	cpg_reg_modify(clock->csn.reg, CPG_SD_STP_MASK,
+		       clock->div_table[clock->cur_div_idx].val &
+		       CPG_SD_STP_MASK);
 
 	return 0;
 }
@@ -276,7 +280,7 @@ static void cpg_sd_clock_disable(struct
 {
 	struct sd_clock *clock = to_sd_clock(hw);
 
-	writel(readl(clock->csn.reg) | CPG_SD_STP_MASK, clock->csn.reg);
+	cpg_reg_modify(clock->csn.reg, 0, CPG_SD_STP_MASK);
 }
 
 static int cpg_sd_clock_is_enabled(struct clk_hw *hw)
@@ -323,7 +327,6 @@ static int cpg_sd_clock_set_rate(struct
 {
 	struct sd_clock *clock = to_sd_clock(hw);
 	unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate);
-	u32 val;
 	unsigned int i;
 
 	for (i = 0; i < clock->div_num; i++)
@@ -335,10 +338,9 @@ static int cpg_sd_clock_set_rate(struct
 
 	clock->cur_div_idx = i;
 
-	val = readl(clock->csn.reg);
-	val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK);
-	val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK);
-	writel(val, clock->csn.reg);
+	cpg_reg_modify(clock->csn.reg, CPG_SD_STP_MASK | CPG_SD_FC_MASK,
+		       clock->div_table[i].val &
+		       (CPG_SD_STP_MASK | CPG_SD_FC_MASK));
 
 	return 0;
 }

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

* [PATCH v2 2/4] clk: renesas: rcar-gen3-cpg: add spinlock
  2018-12-04 19:43 [PATCH v2 0/4] Renesas R8A77980 CPG/MSSR RPC clock support Sergei Shtylyov
  2018-12-04 19:48 ` [PATCH v2 1/4] clk: renesas: rcar-gen3-cpg: factor out cpg_reg_modify() Sergei Shtylyov
@ 2018-12-04 19:49 ` Sergei Shtylyov
  2018-12-14 15:33   ` Simon Horman
  2019-01-21 14:08   ` Geert Uytterhoeven
  2018-12-04 19:51 ` [PATCH v2 3/4] clk: renesas: rcar-gen3-cpg: add RPC clocks Sergei Shtylyov
  2018-12-04 19:52 ` [PATCH v2 4/4] clk: renesas: r8a77980-cpg-mssr: " Sergei Shtylyov
  3 siblings, 2 replies; 13+ messages in thread
From: Sergei Shtylyov @ 2018-12-04 19:49 UTC (permalink / raw)
  To: linux-renesas-soc, Michael Turquette, Stephen Boyd,
	Geert Uytterhoeven, linux-clk

Protect the CPG register read-modify-write sequence with a spinlock.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

---
Changes in version 2:
- new patch.

 drivers/clk/renesas/rcar-gen3-cpg.c |    8 ++++++++
 1 file changed, 8 insertions(+)

Index: renesas-drivers/drivers/clk/renesas/rcar-gen3-cpg.c
===================================================================
--- renesas-drivers.orig/drivers/clk/renesas/rcar-gen3-cpg.c
+++ renesas-drivers/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -30,14 +30,19 @@
 
 #define CPG_RCKCR_CKSEL	BIT(15)	/* RCLK Clock Source Select */
 
+static spinlock_t cpg_lock;
+
 static void cpg_reg_modify(void __iomem *reg, u32 clear, u32 set)
 {
+	unsigned long flags;
 	u32 val;
 
+	spin_lock_irqsave(&cpg_lock, flags);
 	val = readl(reg);
 	val &= ~clear;
 	val |= set;
 	writel(val, reg);
+	spin_unlock_irqrestore(&cpg_lock, flags);
 };
 
 struct cpg_simple_notifier {
@@ -604,5 +609,8 @@ int __init rcar_gen3_cpg_init(const stru
 	if (attr)
 		cpg_quirks = (uintptr_t)attr->data;
 	pr_debug("%s: mode = 0x%x quirks = 0x%x\n", __func__, mode, cpg_quirks);
+
+	spin_lock_init(&cpg_lock);
+
 	return 0;
 }

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

* [PATCH v2 3/4] clk: renesas: rcar-gen3-cpg: add RPC clocks
  2018-12-04 19:43 [PATCH v2 0/4] Renesas R8A77980 CPG/MSSR RPC clock support Sergei Shtylyov
  2018-12-04 19:48 ` [PATCH v2 1/4] clk: renesas: rcar-gen3-cpg: factor out cpg_reg_modify() Sergei Shtylyov
  2018-12-04 19:49 ` [PATCH v2 2/4] clk: renesas: rcar-gen3-cpg: add spinlock Sergei Shtylyov
@ 2018-12-04 19:51 ` Sergei Shtylyov
  2019-01-21 14:17   ` Geert Uytterhoeven
  2018-12-04 19:52 ` [PATCH v2 4/4] clk: renesas: r8a77980-cpg-mssr: " Sergei Shtylyov
  3 siblings, 1 reply; 13+ messages in thread
From: Sergei Shtylyov @ 2018-12-04 19:51 UTC (permalink / raw)
  To: linux-renesas-soc, Michael Turquette, Stephen Boyd,
	Geert Uytterhoeven, linux-clk

The RPCSRC internal clock is controlled by the RPCCKCR.DIV[4:3] on all
the R-Car gen3 SoCs except V3M (R8A77970) but the encoding of this field
is different between SoCs; it makes sense to support the most common case
of this encoding in the R-Car gen3 CPG driver...

After adding the RPCSRC clock, we can add the RPC[D2] clocks derived from
it and controlled by the RPCCKCR register on all the R-Car gen3 SoCs except
V3M (R8A77970); the composite clock driver seems handy for this task, using
the spinlock added in the previous patch...

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

---
Changes in version 2:
- merged in the RPCD2 clock support from the next patch;
- moved in the RPCSRC clock support from the R8A77980 CPG/MSSR driver patch;
- switched the RPC and RPCSD2 clock support to the composite clock driver;
- changed the 1st parameter of cpg_rpc[d2]_clk_register();
- rewrote the patch description, renamed the patch.

 drivers/clk/renesas/rcar-gen3-cpg.c |   99 ++++++++++++++++++++++++++++++++++++
 drivers/clk/renesas/rcar-gen3-cpg.h |    4 +
 2 files changed, 103 insertions(+)

Index: renesas-drivers/drivers/clk/renesas/rcar-gen3-cpg.c
===================================================================
--- renesas-drivers.orig/drivers/clk/renesas/rcar-gen3-cpg.c
+++ renesas-drivers/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -415,6 +415,90 @@ free_clock:
 	return clk;
 }
 
+struct rpc_clock {
+	struct clk_divider div;
+	struct clk_gate gate;
+	struct cpg_simple_notifier csn;
+};
+
+static const struct clk_div_table cpg_rpcsrc_div_table[] = {
+	{ 2, 5 }, { 3, 6 }, { 0, 0 },
+};
+
+static const struct clk_div_table cpg_rpc_div_table[] = {
+	{ 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 }, { 0, 0 },
+};
+
+static struct clk * __init cpg_rpc_clk_register(const char *name,
+	void __iomem *base, const char *parent_name,
+	struct raw_notifier_head *notifiers)
+{
+	struct rpc_clock *rpc;
+	struct clk *clk;
+
+	rpc = kzalloc(sizeof(*rpc), GFP_KERNEL);
+	if (!rpc)
+		return ERR_PTR(-ENOMEM);
+
+	rpc->div.reg = base + CPG_RPCCKCR;
+	rpc->div.width = 3;
+	rpc->div.table = cpg_rpc_div_table;
+	rpc->div.lock = &cpg_lock;
+
+	rpc->gate.reg = base + CPG_RPCCKCR;
+	rpc->gate.bit_idx = 8;
+	rpc->gate.flags = CLK_GATE_SET_TO_DISABLE;
+	rpc->gate.lock = &cpg_lock;
+
+	rpc->csn.reg = base + CPG_RPCCKCR;
+
+	clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
+				     &rpc->div.hw,  &clk_divider_ops,
+				     &rpc->gate.hw, &clk_gate_ops, 0);
+	if (IS_ERR(clk))
+		kfree(rpc);
+
+	cpg_simple_notifier_register(notifiers, &rpc->csn);
+	return clk;
+}
+
+static struct clk * __init cpg_rpcd2_clk_register(const char *name,
+						  void __iomem *base,
+						  const char *parent_name)
+{
+	struct clk_fixed_factor *fixed;
+	struct clk_gate *gate;
+	struct clk *clk;
+
+	fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
+	if (!fixed)
+		return ERR_PTR(-ENOMEM);
+
+	fixed->mult = 1;
+	fixed->div = 2;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate) {
+		kfree(fixed);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	gate->reg = base + CPG_RPCCKCR;
+	gate->bit_idx = 9;
+	gate->flags = CLK_GATE_SET_TO_DISABLE;
+	gate->lock = &cpg_lock;
+
+	clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
+				     &fixed->hw, &clk_fixed_factor_ops,
+				     &gate->hw,  &clk_gate_ops, 0);
+	if (IS_ERR(clk)) {
+		kfree(fixed);
+		kfree(gate);
+	}
+
+	return clk;
+}
+
 
 static const struct rcar_gen3_cpg_pll_config *cpg_pll_config __initdata;
 static unsigned int cpg_clk_extalr __initdata;
@@ -589,6 +673,21 @@ struct clk * __init rcar_gen3_cpg_clk_re
 		}
 		break;
 
+	case CLK_TYPE_GEN3_RPCSRC:
+		return clk_register_divider_table(NULL, core->name,
+						  __clk_get_name(parent), 0,
+						  base + CPG_RPCCKCR, 3, 2, 0,
+						  cpg_rpcsrc_div_table,
+						  &cpg_lock);
+
+	case CLK_TYPE_GEN3_RPC:
+		return cpg_rpc_clk_register(core->name, base,
+					    __clk_get_name(parent), notifiers);
+
+	case CLK_TYPE_GEN3_RPCD2:
+		return cpg_rpcd2_clk_register(core->name, base,
+					      __clk_get_name(parent));
+
 	default:
 		return ERR_PTR(-EINVAL);
 	}
Index: renesas-drivers/drivers/clk/renesas/rcar-gen3-cpg.h
===================================================================
--- renesas-drivers.orig/drivers/clk/renesas/rcar-gen3-cpg.h
+++ renesas-drivers/drivers/clk/renesas/rcar-gen3-cpg.h
@@ -23,6 +23,9 @@ enum rcar_gen3_clk_types {
 	CLK_TYPE_GEN3_Z2,
 	CLK_TYPE_GEN3_OSC,	/* OSC EXTAL predivider and fixed divider */
 	CLK_TYPE_GEN3_RCKSEL,	/* Select parent/divider using RCKCR.CKSEL */
+	CLK_TYPE_GEN3_RPCSRC,
+	CLK_TYPE_GEN3_RPC,
+	CLK_TYPE_GEN3_RPCD2,
 
 	/* SoC specific definitions start here */
 	CLK_TYPE_GEN3_SOC_BASE,
@@ -57,6 +60,7 @@ struct rcar_gen3_cpg_pll_config {
 	u8 osc_prediv;
 };
 
+#define CPG_RPCCKCR	0x238
 #define CPG_RCKCR	0x240
 
 struct clk *rcar_gen3_cpg_clk_register(struct device *dev,

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

* [PATCH v2 4/4] clk: renesas: r8a77980-cpg-mssr: add RPC clocks
  2018-12-04 19:43 [PATCH v2 0/4] Renesas R8A77980 CPG/MSSR RPC clock support Sergei Shtylyov
                   ` (2 preceding siblings ...)
  2018-12-04 19:51 ` [PATCH v2 3/4] clk: renesas: rcar-gen3-cpg: add RPC clocks Sergei Shtylyov
@ 2018-12-04 19:52 ` Sergei Shtylyov
  2019-01-21 14:18   ` Geert Uytterhoeven
  3 siblings, 1 reply; 13+ messages in thread
From: Sergei Shtylyov @ 2018-12-04 19:52 UTC (permalink / raw)
  To: linux-renesas-soc, Michael Turquette, Stephen Boyd,
	Geert Uytterhoeven, linux-clk

Describe the RPCSRC internal clock and the RPC[D2] clocks derived from it,
as well as the RPC-IF module clock, in the R-Car V3H (R8A77980) CPG/MSSR
driver.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

---
Changes in version 2:
- moved the RPCSRC clock support to the R-Car gen3 CPG patch adding the RPC
  clocks;
- rewrote the patch description.

 drivers/clk/renesas/r8a77980-cpg-mssr.c |    8 ++++++++
 1 file changed, 8 insertions(+)

Index: renesas-drivers/drivers/clk/renesas/r8a77980-cpg-mssr.c
===================================================================
--- renesas-drivers.orig/drivers/clk/renesas/r8a77980-cpg-mssr.c
+++ renesas-drivers/drivers/clk/renesas/r8a77980-cpg-mssr.c
@@ -41,6 +41,7 @@ enum clk_ids {
 	CLK_S2,
 	CLK_S3,
 	CLK_SDSRC,
+	CLK_RPCSRC,
 	CLK_OCO,
 
 	/* Module Clocks */
@@ -65,8 +66,14 @@ static const struct cpg_core_clk r8a7798
 	DEF_FIXED(".s2",	CLK_S2,		   CLK_PLL1_DIV2,  4, 1),
 	DEF_FIXED(".s3",	CLK_S3,		   CLK_PLL1_DIV2,  6, 1),
 	DEF_FIXED(".sdsrc",	CLK_SDSRC,	   CLK_PLL1_DIV2,  2, 1),
+	DEF_BASE(".rpcsrc",	CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1),
 	DEF_RATE(".oco",	CLK_OCO,           32768),
 
+	DEF_BASE("rpc",		R8A77980_CLK_RPC, CLK_TYPE_GEN3_RPC,
+		 CLK_RPCSRC),
+	DEF_BASE("rpcd2",	R8A77980_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2,
+		 R8A77980_CLK_RPC),
+
 	/* Core Clock Outputs */
 	DEF_FIXED("ztr",	R8A77980_CLK_ZTR,   CLK_PLL1_DIV2,  6, 1),
 	DEF_FIXED("ztrd2",	R8A77980_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
@@ -164,6 +171,7 @@ static const struct mssr_mod_clk r8a7798
 	DEF_MOD("gpio1",		 911,	R8A77980_CLK_CP),
 	DEF_MOD("gpio0",		 912,	R8A77980_CLK_CP),
 	DEF_MOD("can-fd",		 914,	R8A77980_CLK_S3D2),
+	DEF_MOD("rpc-if",		 917,	R8A77980_CLK_RPC),
 	DEF_MOD("i2c4",			 927,	R8A77980_CLK_S0D6),
 	DEF_MOD("i2c3",			 928,	R8A77980_CLK_S0D6),
 	DEF_MOD("i2c2",			 929,	R8A77980_CLK_S3D2),


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

* Re: [PATCH v2 1/4] clk: renesas: rcar-gen3-cpg: factor out cpg_reg_modify()
  2018-12-04 19:48 ` [PATCH v2 1/4] clk: renesas: rcar-gen3-cpg: factor out cpg_reg_modify() Sergei Shtylyov
@ 2018-12-14 15:32   ` Simon Horman
  2019-01-21 13:25   ` Geert Uytterhoeven
  1 sibling, 0 replies; 13+ messages in thread
From: Simon Horman @ 2018-12-14 15:32 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: linux-renesas-soc, Michael Turquette, Stephen Boyd,
	Geert Uytterhoeven, linux-clk

On Tue, Dec 04, 2018 at 10:48:21PM +0300, Sergei Shtylyov wrote:
> There's quite often repeated sequence of a CPG register read-modify-write,
> so it seems worth factoring it out into a function -- this saves 68 bytes
> of the object code (AArch64 gcc 4.8.5) and simplifies protecting all such
> sequences with a spinlock in the next patch...
> 
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

Reviewed-by: Simon Horman <horms+renesas@verge.net.au>

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

* Re: [PATCH v2 2/4] clk: renesas: rcar-gen3-cpg: add spinlock
  2018-12-04 19:49 ` [PATCH v2 2/4] clk: renesas: rcar-gen3-cpg: add spinlock Sergei Shtylyov
@ 2018-12-14 15:33   ` Simon Horman
  2019-01-21 13:40     ` Geert Uytterhoeven
  2019-01-21 18:49     ` Sergei Shtylyov
  2019-01-21 14:08   ` Geert Uytterhoeven
  1 sibling, 2 replies; 13+ messages in thread
From: Simon Horman @ 2018-12-14 15:33 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: linux-renesas-soc, Michael Turquette, Stephen Boyd,
	Geert Uytterhoeven, linux-clk

On Tue, Dec 04, 2018 at 10:49:44PM +0300, Sergei Shtylyov wrote:
> Protect the CPG register read-modify-write sequence with a spinlock.

Spinlocks are expensive, I think an explanation of why this is
necessary would be worthwhile.

> 
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> 
> ---
> Changes in version 2:
> - new patch.
> 
>  drivers/clk/renesas/rcar-gen3-cpg.c |    8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> Index: renesas-drivers/drivers/clk/renesas/rcar-gen3-cpg.c
> ===================================================================
> --- renesas-drivers.orig/drivers/clk/renesas/rcar-gen3-cpg.c
> +++ renesas-drivers/drivers/clk/renesas/rcar-gen3-cpg.c
> @@ -30,14 +30,19 @@
>  
>  #define CPG_RCKCR_CKSEL	BIT(15)	/* RCLK Clock Source Select */
>  
> +static spinlock_t cpg_lock;
> +
>  static void cpg_reg_modify(void __iomem *reg, u32 clear, u32 set)
>  {
> +	unsigned long flags;
>  	u32 val;
>  
> +	spin_lock_irqsave(&cpg_lock, flags);
>  	val = readl(reg);
>  	val &= ~clear;
>  	val |= set;
>  	writel(val, reg);
> +	spin_unlock_irqrestore(&cpg_lock, flags);
>  };
>  
>  struct cpg_simple_notifier {
> @@ -604,5 +609,8 @@ int __init rcar_gen3_cpg_init(const stru
>  	if (attr)
>  		cpg_quirks = (uintptr_t)attr->data;
>  	pr_debug("%s: mode = 0x%x quirks = 0x%x\n", __func__, mode, cpg_quirks);
> +
> +	spin_lock_init(&cpg_lock);
> +
>  	return 0;
>  }
> 

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

* Re: [PATCH v2 1/4] clk: renesas: rcar-gen3-cpg: factor out cpg_reg_modify()
  2018-12-04 19:48 ` [PATCH v2 1/4] clk: renesas: rcar-gen3-cpg: factor out cpg_reg_modify() Sergei Shtylyov
  2018-12-14 15:32   ` Simon Horman
@ 2019-01-21 13:25   ` Geert Uytterhoeven
  1 sibling, 0 replies; 13+ messages in thread
From: Geert Uytterhoeven @ 2019-01-21 13:25 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Linux-Renesas, Michael Turquette, Stephen Boyd,
	Geert Uytterhoeven, linux-clk

Hi Sergei,

On Tue, Dec 4, 2018 at 8:48 PM Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> There's quite often repeated sequence of a CPG register read-modify-write,
> so it seems worth factoring it out into a function -- this saves 68 bytes
> of the object code (AArch64 gcc 4.8.5) and simplifies protecting all such
> sequences with a spinlock in the next patch...
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

I believe my
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
for v1 is still valid.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v2 2/4] clk: renesas: rcar-gen3-cpg: add spinlock
  2018-12-14 15:33   ` Simon Horman
@ 2019-01-21 13:40     ` Geert Uytterhoeven
  2019-01-21 18:49     ` Sergei Shtylyov
  1 sibling, 0 replies; 13+ messages in thread
From: Geert Uytterhoeven @ 2019-01-21 13:40 UTC (permalink / raw)
  To: Simon Horman
  Cc: Sergei Shtylyov, Linux-Renesas, Michael Turquette, Stephen Boyd,
	Geert Uytterhoeven, linux-clk

Hi Simon,

On Fri, Dec 14, 2018 at 4:33 PM Simon Horman <horms@verge.net.au> wrote:
> On Tue, Dec 04, 2018 at 10:49:44PM +0300, Sergei Shtylyov wrote:
> > Protect the CPG register read-modify-write sequence with a spinlock.
>
> Spinlocks are expensive, I think an explanation of why this is
> necessary would be worthwhile.

Some clock registers contain bits for multiple clocks.
Hence read-modify-write cycles on these registers should be protected
against concurrent accesses for multiple clocks.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v2 2/4] clk: renesas: rcar-gen3-cpg: add spinlock
  2018-12-04 19:49 ` [PATCH v2 2/4] clk: renesas: rcar-gen3-cpg: add spinlock Sergei Shtylyov
  2018-12-14 15:33   ` Simon Horman
@ 2019-01-21 14:08   ` Geert Uytterhoeven
  1 sibling, 0 replies; 13+ messages in thread
From: Geert Uytterhoeven @ 2019-01-21 14:08 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Linux-Renesas, Michael Turquette, Stephen Boyd,
	Geert Uytterhoeven, linux-clk

On Tue, Dec 4, 2018 at 8:49 PM Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> Protect the CPG register read-modify-write sequence with a spinlock.
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v2 3/4] clk: renesas: rcar-gen3-cpg: add RPC clocks
  2018-12-04 19:51 ` [PATCH v2 3/4] clk: renesas: rcar-gen3-cpg: add RPC clocks Sergei Shtylyov
@ 2019-01-21 14:17   ` Geert Uytterhoeven
  0 siblings, 0 replies; 13+ messages in thread
From: Geert Uytterhoeven @ 2019-01-21 14:17 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Linux-Renesas, Michael Turquette, Stephen Boyd,
	Geert Uytterhoeven, linux-clk

Hi Sergei,

On Tue, Dec 4, 2018 at 8:51 PM Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> The RPCSRC internal clock is controlled by the RPCCKCR.DIV[4:3] on all
> the R-Car gen3 SoCs except V3M (R8A77970) but the encoding of this field
> is different between SoCs; it makes sense to support the most common case
> of this encoding in the R-Car gen3 CPG driver...
>
> After adding the RPCSRC clock, we can add the RPC[D2] clocks derived from
> it and controlled by the RPCCKCR register on all the R-Car gen3 SoCs except
> V3M (R8A77970); the composite clock driver seems handy for this task, using
> the spinlock added in the previous patch...
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>
> ---
> Changes in version 2:
> - merged in the RPCD2 clock support from the next patch;
> - moved in the RPCSRC clock support from the R8A77980 CPG/MSSR driver patch;
> - switched the RPC and RPCSD2 clock support to the composite clock driver;
> - changed the 1st parameter of cpg_rpc[d2]_clk_register();
> - rewrote the patch description, renamed the patch.

Thanks for the update!

> --- renesas-drivers.orig/drivers/clk/renesas/rcar-gen3-cpg.c
> +++ renesas-drivers/drivers/clk/renesas/rcar-gen3-cpg.c
> @@ -415,6 +415,90 @@ free_clock:
>         return clk;
>  }
>
> +struct rpc_clock {
> +       struct clk_divider div;
> +       struct clk_gate gate;
> +       struct cpg_simple_notifier csn;
> +};
> +
> +static const struct clk_div_table cpg_rpcsrc_div_table[] = {
> +       { 2, 5 }, { 3, 6 }, { 0, 0 },
> +};
> +
> +static const struct clk_div_table cpg_rpc_div_table[] = {
> +       { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 }, { 0, 0 },
> +};
> +
> +static struct clk * __init cpg_rpc_clk_register(const char *name,
> +       void __iomem *base, const char *parent_name,
> +       struct raw_notifier_head *notifiers)
> +{
> +       struct rpc_clock *rpc;
> +       struct clk *clk;
> +
> +       rpc = kzalloc(sizeof(*rpc), GFP_KERNEL);
> +       if (!rpc)
> +               return ERR_PTR(-ENOMEM);
> +
> +       rpc->div.reg = base + CPG_RPCCKCR;
> +       rpc->div.width = 3;
> +       rpc->div.table = cpg_rpc_div_table;
> +       rpc->div.lock = &cpg_lock;
> +
> +       rpc->gate.reg = base + CPG_RPCCKCR;
> +       rpc->gate.bit_idx = 8;
> +       rpc->gate.flags = CLK_GATE_SET_TO_DISABLE;
> +       rpc->gate.lock = &cpg_lock;
> +
> +       rpc->csn.reg = base + CPG_RPCCKCR;
> +
> +       clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
> +                                    &rpc->div.hw,  &clk_divider_ops,
> +                                    &rpc->gate.hw, &clk_gate_ops, 0);
> +       if (IS_ERR(clk))
> +               kfree(rpc);
> +
> +       cpg_simple_notifier_register(notifiers, &rpc->csn);
> +       return clk;
> +}
> +
> +static struct clk * __init cpg_rpcd2_clk_register(const char *name,
> +                                                 void __iomem *base,
> +                                                 const char *parent_name)
> +{
> +       struct clk_fixed_factor *fixed;
> +       struct clk_gate *gate;
> +       struct clk *clk;
> +
> +       fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
> +       if (!fixed)
> +               return ERR_PTR(-ENOMEM);
> +
> +       fixed->mult = 1;
> +       fixed->div = 2;
> +
> +       gate = kzalloc(sizeof(*gate), GFP_KERNEL);
> +       if (!gate) {
> +               kfree(fixed);
> +               return ERR_PTR(-ENOMEM);
> +       }

Why allocate two separate structures here, instead of grouping them in a
single struct rpcd2_clock structure, like for the RPC clock?

> +
> +       gate->reg = base + CPG_RPCCKCR;
> +       gate->bit_idx = 9;
> +       gate->flags = CLK_GATE_SET_TO_DISABLE;
> +       gate->lock = &cpg_lock;
> +
> +       clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
> +                                    &fixed->hw, &clk_fixed_factor_ops,
> +                                    &gate->hw,  &clk_gate_ops, 0);
> +       if (IS_ERR(clk)) {
> +               kfree(fixed);
> +               kfree(gate);
> +       }

I first wondered why there's no notifier to save/restore the clock during system
PSCI suspend/resume, until I realized the RPC and RPCD2 clocks share the
same hardware register, so saving/restoring the register once is sufficient.
A comment (in struct rpc_clock?) explaining that would be appreciated.

The rest looks good to me.
Using the composite clock seems to have reduced LoC by ca. 60%, nice!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v2 4/4] clk: renesas: r8a77980-cpg-mssr: add RPC clocks
  2018-12-04 19:52 ` [PATCH v2 4/4] clk: renesas: r8a77980-cpg-mssr: " Sergei Shtylyov
@ 2019-01-21 14:18   ` Geert Uytterhoeven
  0 siblings, 0 replies; 13+ messages in thread
From: Geert Uytterhoeven @ 2019-01-21 14:18 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Linux-Renesas, Michael Turquette, Stephen Boyd,
	Geert Uytterhoeven, linux-clk

On Tue, Dec 4, 2018 at 8:52 PM Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> Describe the RPCSRC internal clock and the RPC[D2] clocks derived from it,
> as well as the RPC-IF module clock, in the R-Car V3H (R8A77980) CPG/MSSR
> driver.
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>
> ---
> Changes in version 2:
> - moved the RPCSRC clock support to the R-Car gen3 CPG patch adding the RPC
>   clocks;
> - rewrote the patch description.

Thanks for the update!

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v2 2/4] clk: renesas: rcar-gen3-cpg: add spinlock
  2018-12-14 15:33   ` Simon Horman
  2019-01-21 13:40     ` Geert Uytterhoeven
@ 2019-01-21 18:49     ` Sergei Shtylyov
  1 sibling, 0 replies; 13+ messages in thread
From: Sergei Shtylyov @ 2019-01-21 18:49 UTC (permalink / raw)
  To: Simon Horman
  Cc: linux-renesas-soc, Michael Turquette, Stephen Boyd,
	Geert Uytterhoeven, linux-clk

On 12/14/2018 06:33 PM, Simon Horman wrote:
> On Tue, Dec 04, 2018 at 10:49:44PM +0300, Sergei Shtylyov wrote:
>> Protect the CPG register read-modify-write sequence with a spinlock.
> 
> Spinlocks are expensive, I think an explanation of why this is
> necessary would be worthwhile.

   The driver using a spinlock to protect the hardware registers is such a 
common scenario, I didn't think it was worth a special explanation. :-)

> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
[...]

MBR, Sergei

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

end of thread, other threads:[~2019-01-21 18:49 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-04 19:43 [PATCH v2 0/4] Renesas R8A77980 CPG/MSSR RPC clock support Sergei Shtylyov
2018-12-04 19:48 ` [PATCH v2 1/4] clk: renesas: rcar-gen3-cpg: factor out cpg_reg_modify() Sergei Shtylyov
2018-12-14 15:32   ` Simon Horman
2019-01-21 13:25   ` Geert Uytterhoeven
2018-12-04 19:49 ` [PATCH v2 2/4] clk: renesas: rcar-gen3-cpg: add spinlock Sergei Shtylyov
2018-12-14 15:33   ` Simon Horman
2019-01-21 13:40     ` Geert Uytterhoeven
2019-01-21 18:49     ` Sergei Shtylyov
2019-01-21 14:08   ` Geert Uytterhoeven
2018-12-04 19:51 ` [PATCH v2 3/4] clk: renesas: rcar-gen3-cpg: add RPC clocks Sergei Shtylyov
2019-01-21 14:17   ` Geert Uytterhoeven
2018-12-04 19:52 ` [PATCH v2 4/4] clk: renesas: r8a77980-cpg-mssr: " Sergei Shtylyov
2019-01-21 14:18   ` Geert Uytterhoeven

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).