All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/8] Renesas R-Car Gen2 Common Clock Framework support
@ 2013-11-19 14:45 ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-sh; +Cc: linux-arm-kernel, Mike Turquette, devicetree

Hello,

This is the third version of the CCF clock drivers for the Renesas R-Car
R8A7790 (H2) and R8A7791 (M2) SoCs.

The patches are pretty self-explanatory and described in their respective
commit message. The R8A7790 and R8A7791 datasheets are unfortunately not
publicly available.

The code is available in my git tree at

        git://linuxtv.org/pinchartl/fbdev.git clocks/ccf/rcar-gen2

The branch is based on the clk-prepare patches I've posted earlier on the list
("[PATCH 00/12] Prepare various SH/R Mobile/Car drivers for CCF migration"),
themselves rebased on top of renesas-devel-v3.12-20131119.

Changes compared to v2:

- Fixed I2C MSTP clocks parents (hp -> p)
- Added Z and Z2 clocks
- Added r8a7791 clocks to DT

Changes compared to v1:

- The core CPG clocks driver now supports the r8a7791 SoC in addition to the
r8a7790. They are collectively refered to as 'R-Car Gen2'. The driver has thus
been renamed to clk-rcar-gen2.c. The DT bindings have been updated accordingly.
- Several MSTP clocks have been added to the r8a7790-clock.h header and a new
header has been added for the r8a7791
- The r8a7790 dtsi patches that add and reference clocks have been added to
this series.

Cc: devicetree@vger.kernel.org

Laurent Pinchart (8):
  clk: shmobile: Add R-Car Gen2 clocks support
  clk: shmobile: Add DIV6 clock support
  clk: shmobile: Add MSTP clock support
  ARM: shmobile: r8a7790: Add clock index macros for DT sources
  ARM: shmobile: r8a7791: Add clock index macros for DT sources
  ARM: shmobile: r8a7790: Add clocks
  ARM: shmobile: r8a7790: Reference clocks
  ARM: shmobile: r8a7791: Add clocks

 .../bindings/clock/renesas,cpg-div6-clocks.txt     |  28 ++
 .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++
 .../clock/renesas,rcar-gen2-cpg-clocks.txt         |  32 ++
 arch/arm/boot/dts/r8a7790.dtsi                     | 326 +++++++++++++++++++++
 arch/arm/boot/dts/r8a7791.dtsi                     | 312 ++++++++++++++++++++
 drivers/clk/shmobile/Makefile                      |   7 +-
 drivers/clk/shmobile/clk-div6.c                    | 185 ++++++++++++
 drivers/clk/shmobile/clk-mstp.c                    | 229 +++++++++++++++
 drivers/clk/shmobile/clk-rcar-gen2.c               | 298 +++++++++++++++++++
 include/dt-bindings/clock/r8a7790-clock.h          | 100 +++++++
 include/dt-bindings/clock/r8a7791-clock.h          | 105 +++++++
 include/linux/clk/shmobile.h                       |  19 ++
 12 files changed, 1688 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
 create mode 100644 drivers/clk/shmobile/clk-div6.c
 create mode 100644 drivers/clk/shmobile/clk-mstp.c
 create mode 100644 drivers/clk/shmobile/clk-rcar-gen2.c
 create mode 100644 include/dt-bindings/clock/r8a7790-clock.h
 create mode 100644 include/dt-bindings/clock/r8a7791-clock.h
 create mode 100644 include/linux/clk/shmobile.h

-- 
Regards,

Laurent Pinchart


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

* [PATCH v3 0/8] Renesas R-Car Gen2 Common Clock Framework support
@ 2013-11-19 14:45 ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

Hello,

This is the third version of the CCF clock drivers for the Renesas R-Car
R8A7790 (H2) and R8A7791 (M2) SoCs.

The patches are pretty self-explanatory and described in their respective
commit message. The R8A7790 and R8A7791 datasheets are unfortunately not
publicly available.

The code is available in my git tree at

        git://linuxtv.org/pinchartl/fbdev.git clocks/ccf/rcar-gen2

The branch is based on the clk-prepare patches I've posted earlier on the list
("[PATCH 00/12] Prepare various SH/R Mobile/Car drivers for CCF migration"),
themselves rebased on top of renesas-devel-v3.12-20131119.

Changes compared to v2:

- Fixed I2C MSTP clocks parents (hp -> p)
- Added Z and Z2 clocks
- Added r8a7791 clocks to DT

Changes compared to v1:

- The core CPG clocks driver now supports the r8a7791 SoC in addition to the
r8a7790. They are collectively refered to as 'R-Car Gen2'. The driver has thus
been renamed to clk-rcar-gen2.c. The DT bindings have been updated accordingly.
- Several MSTP clocks have been added to the r8a7790-clock.h header and a new
header has been added for the r8a7791
- The r8a7790 dtsi patches that add and reference clocks have been added to
this series.

Cc: devicetree at vger.kernel.org

Laurent Pinchart (8):
  clk: shmobile: Add R-Car Gen2 clocks support
  clk: shmobile: Add DIV6 clock support
  clk: shmobile: Add MSTP clock support
  ARM: shmobile: r8a7790: Add clock index macros for DT sources
  ARM: shmobile: r8a7791: Add clock index macros for DT sources
  ARM: shmobile: r8a7790: Add clocks
  ARM: shmobile: r8a7790: Reference clocks
  ARM: shmobile: r8a7791: Add clocks

 .../bindings/clock/renesas,cpg-div6-clocks.txt     |  28 ++
 .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++
 .../clock/renesas,rcar-gen2-cpg-clocks.txt         |  32 ++
 arch/arm/boot/dts/r8a7790.dtsi                     | 326 +++++++++++++++++++++
 arch/arm/boot/dts/r8a7791.dtsi                     | 312 ++++++++++++++++++++
 drivers/clk/shmobile/Makefile                      |   7 +-
 drivers/clk/shmobile/clk-div6.c                    | 185 ++++++++++++
 drivers/clk/shmobile/clk-mstp.c                    | 229 +++++++++++++++
 drivers/clk/shmobile/clk-rcar-gen2.c               | 298 +++++++++++++++++++
 include/dt-bindings/clock/r8a7790-clock.h          | 100 +++++++
 include/dt-bindings/clock/r8a7791-clock.h          | 105 +++++++
 include/linux/clk/shmobile.h                       |  19 ++
 12 files changed, 1688 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
 create mode 100644 drivers/clk/shmobile/clk-div6.c
 create mode 100644 drivers/clk/shmobile/clk-mstp.c
 create mode 100644 drivers/clk/shmobile/clk-rcar-gen2.c
 create mode 100644 include/dt-bindings/clock/r8a7790-clock.h
 create mode 100644 include/dt-bindings/clock/r8a7791-clock.h
 create mode 100644 include/linux/clk/shmobile.h

-- 
Regards,

Laurent Pinchart

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

* [PATCH v3 0/8] Renesas R-Car Gen2 Common Clock Framework support
@ 2013-11-19 14:45 ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

Hello,

This is the third version of the CCF clock drivers for the Renesas R-Car
R8A7790 (H2) and R8A7791 (M2) SoCs.

The patches are pretty self-explanatory and described in their respective
commit message. The R8A7790 and R8A7791 datasheets are unfortunately not
publicly available.

The code is available in my git tree at

        git://linuxtv.org/pinchartl/fbdev.git clocks/ccf/rcar-gen2

The branch is based on the clk-prepare patches I've posted earlier on the list
("[PATCH 00/12] Prepare various SH/R Mobile/Car drivers for CCF migration"),
themselves rebased on top of renesas-devel-v3.12-20131119.

Changes compared to v2:

- Fixed I2C MSTP clocks parents (hp -> p)
- Added Z and Z2 clocks
- Added r8a7791 clocks to DT

Changes compared to v1:

- The core CPG clocks driver now supports the r8a7791 SoC in addition to the
r8a7790. They are collectively refered to as 'R-Car Gen2'. The driver has thus
been renamed to clk-rcar-gen2.c. The DT bindings have been updated accordingly.
- Several MSTP clocks have been added to the r8a7790-clock.h header and a new
header has been added for the r8a7791
- The r8a7790 dtsi patches that add and reference clocks have been added to
this series.

Cc: devicetree@vger.kernel.org

Laurent Pinchart (8):
  clk: shmobile: Add R-Car Gen2 clocks support
  clk: shmobile: Add DIV6 clock support
  clk: shmobile: Add MSTP clock support
  ARM: shmobile: r8a7790: Add clock index macros for DT sources
  ARM: shmobile: r8a7791: Add clock index macros for DT sources
  ARM: shmobile: r8a7790: Add clocks
  ARM: shmobile: r8a7790: Reference clocks
  ARM: shmobile: r8a7791: Add clocks

 .../bindings/clock/renesas,cpg-div6-clocks.txt     |  28 ++
 .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++
 .../clock/renesas,rcar-gen2-cpg-clocks.txt         |  32 ++
 arch/arm/boot/dts/r8a7790.dtsi                     | 326 +++++++++++++++++++++
 arch/arm/boot/dts/r8a7791.dtsi                     | 312 ++++++++++++++++++++
 drivers/clk/shmobile/Makefile                      |   7 +-
 drivers/clk/shmobile/clk-div6.c                    | 185 ++++++++++++
 drivers/clk/shmobile/clk-mstp.c                    | 229 +++++++++++++++
 drivers/clk/shmobile/clk-rcar-gen2.c               | 298 +++++++++++++++++++
 include/dt-bindings/clock/r8a7790-clock.h          | 100 +++++++
 include/dt-bindings/clock/r8a7791-clock.h          | 105 +++++++
 include/linux/clk/shmobile.h                       |  19 ++
 12 files changed, 1688 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
 create mode 100644 drivers/clk/shmobile/clk-div6.c
 create mode 100644 drivers/clk/shmobile/clk-mstp.c
 create mode 100644 drivers/clk/shmobile/clk-rcar-gen2.c
 create mode 100644 include/dt-bindings/clock/r8a7790-clock.h
 create mode 100644 include/dt-bindings/clock/r8a7791-clock.h
 create mode 100644 include/linux/clk/shmobile.h

-- 
Regards,

Laurent Pinchart


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

* [PATCH v3 1/8] clk: shmobile: Add R-Car Gen2 clocks support
  2013-11-19 14:45 ` Laurent Pinchart
  (?)
@ 2013-11-19 14:45   ` Laurent Pinchart
  -1 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-sh; +Cc: linux-arm-kernel, Mike Turquette, devicetree

The R-Car Gen2 SoCs (R8A7790 and R8A7791) have several clocks that are
too custom to be supported in a generic driver. Those clocks can be
divided in two categories:

- Fixed rate clocks with multiplier and divisor set according to boot
  mode configuration

- Custom divider clocks with SoC-specific divider values

This driver supports both.

Cc: devicetree@vger.kernel.org
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Kumar Gala <galak@codeaurora.org>
---
 .../clock/renesas,rcar-gen2-cpg-clocks.txt         |  32 +++
 drivers/clk/shmobile/Makefile                      |   5 +-
 drivers/clk/shmobile/clk-rcar-gen2.c               | 298 +++++++++++++++++++++
 include/linux/clk/shmobile.h                       |  19 ++
 4 files changed, 353 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
 create mode 100644 drivers/clk/shmobile/clk-rcar-gen2.c
 create mode 100644 include/linux/clk/shmobile.h

diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
new file mode 100644
index 0000000..7b41c2f
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
@@ -0,0 +1,32 @@
+* Renesas R-Car Gen2 Clock Pulse Generator (CPG)
+
+The CPG generates core clocks for the R-Car Gen2 SoCs. It includes three PLLs
+and several fixed ratio dividers.
+
+Required Properties:
+
+  - compatible: Must be one of
+    - "renesas,r8a7790-cpg-clocks" for the r8a7790 CPG
+    - "renesas,r8a7791-cpg-clocks" for the r8a7791 CPG
+    - "renesas,rcar-gen2-cpg-clocks" for the generic R-Car Gen2 CPG
+
+  - reg: Base address and length of the memory resource used by the CPG
+
+  - clocks: Reference to the parent clock
+  - #clock-cells: Must be 1
+  - clock-output-names: The names of the clocks. Supported clocks are "main",
+    "pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1" and "z"
+
+
+Example
+-------
+
+	cpg_clocks: cpg_clocks@e6150000 {
+		compatible = "renesas,r8a7790-cpg-clocks",
+			     "renesas,rcar-gen2-cpg-clocks";
+		reg = <0 0xe6150000 0 0x1000>;
+		clocks = <&extal_clk>;
+		#clock-cells = <1>;
+		clock-output-names = "main", "pll0, "pll1", "pll3",
+				     "lb", "qspi", "sdh", "sd0", "sd1", "z";
+	};
diff --git a/drivers/clk/shmobile/Makefile b/drivers/clk/shmobile/Makefile
index 2240730..40d88e6 100644
--- a/drivers/clk/shmobile/Makefile
+++ b/drivers/clk/shmobile/Makefile
@@ -1,3 +1,6 @@
-obj-$(CONFIG_ARCH_EMEV2)	+= clk-emev2.o
+obj-$(CONFIG_ARCH_EMEV2)		+= clk-emev2.o
+obj-$(CONFIG_ARCH_R8A7790)		+= clk-rcar-gen2.o
+obj-$(CONFIG_ARCH_R8A7791)		+= clk-rcar-gen2.o
+
 # for emply built-in.o
 obj-n	:= dummy
diff --git a/drivers/clk/shmobile/clk-rcar-gen2.c b/drivers/clk/shmobile/clk-rcar-gen2.c
new file mode 100644
index 0000000..a59ec21
--- /dev/null
+++ b/drivers/clk/shmobile/clk-rcar-gen2.c
@@ -0,0 +1,298 @@
+/*
+ * rcar_gen2 Core CPG Clocks
+ *
+ * Copyright (C) 2013  Ideas On Board SPRL
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/shmobile.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/math64.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/spinlock.h>
+
+struct rcar_gen2_cpg {
+	struct clk_onecell_data data;
+	spinlock_t lock;
+	void __iomem *reg;
+};
+
+#define CPG_SDCKCR			0x00000074
+#define CPG_PLL0CR			0x000000d8
+#define CPG_FRQCRC			0x000000e0
+#define CPG_FRQCRC_ZFC_MASK		(0x1f << 8)
+#define CPG_FRQCRC_ZFC_SHIFT		8
+
+/* -----------------------------------------------------------------------------
+ * Z Clock
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is adjustable.  clk->rate = parent->rate * mult / 32
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+struct cpg_z_clk {
+	struct clk_hw hw;
+	void __iomem *reg;
+};
+
+#define to_z_clk(_hw)	container_of(_hw, struct cpg_z_clk, hw)
+
+static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw,
+					   unsigned long parent_rate)
+{
+	struct cpg_z_clk *zclk = to_z_clk(hw);
+	unsigned int mult;
+	unsigned int val;
+
+	val = (clk_readl(zclk->reg) & CPG_FRQCRC_ZFC_MASK)
+	    >> CPG_FRQCRC_ZFC_SHIFT;
+	mult = 32 - val;
+
+	return div_u64((u64)parent_rate * mult, 32);
+}
+
+static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+				 unsigned long *parent_rate)
+{
+	unsigned long prate  = *parent_rate;
+	unsigned int mult;
+
+	if (!prate)
+		prate = 1;
+
+	mult = div_u64((u64)rate * 32, prate);
+	mult = clamp(mult, 1U, 32U);
+
+	return *parent_rate / 32 * mult;
+}
+
+static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long parent_rate)
+{
+	struct cpg_z_clk *zclk = to_z_clk(hw);
+	unsigned int mult;
+	u32 val;
+
+	mult = div_u64((u64)rate * 32, parent_rate);
+	mult = clamp(mult, 1U, 32U);
+
+	val = clk_readl(zclk->reg);
+	val &= ~CPG_FRQCRC_ZFC_MASK;
+	val |= (32 - mult) << CPG_FRQCRC_ZFC_SHIFT;
+	clk_writel(val, zclk->reg);
+
+	return 0;
+}
+
+static const struct clk_ops cpg_z_clk_ops = {
+	.recalc_rate = cpg_z_clk_recalc_rate,
+	.round_rate = cpg_z_clk_round_rate,
+	.set_rate = cpg_z_clk_set_rate,
+};
+
+static struct clk * __init cpg_z_clk_register(struct rcar_gen2_cpg *cpg)
+{
+	static const char *parent_name = "pll0";
+	struct clk_init_data init;
+	struct cpg_z_clk *zclk;
+	struct clk *clk;
+
+	zclk = kzalloc(sizeof(*zclk), GFP_KERNEL);
+	if (!zclk)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = "z";
+	init.ops = &cpg_z_clk_ops;
+	init.flags = 0;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	zclk->reg = cpg->reg + CPG_FRQCRC;
+	zclk->hw.init = &init;
+
+	clk = clk_register(NULL, &zclk->hw);
+	if (IS_ERR(clk))
+		kfree(zclk);
+
+	return clk;
+}
+
+/* -----------------------------------------------------------------------------
+ * CPG Clock Data
+ */
+
+/*
+ *   MD		EXTAL		PLL0	PLL1	PLL3
+ * 14 13 19	(MHz)		*1	*1
+ *---------------------------------------------------
+ * 0  0  0	15 x 1		x172/2	x208/2	x106
+ * 0  0  1	15 x 1		x172/2	x208/2	x88
+ * 0  1  0	20 x 1		x130/2	x156/2	x80
+ * 0  1  1	20 x 1		x130/2	x156/2	x66
+ * 1  0  0	26 / 2		x200/2	x240/2	x122
+ * 1  0  1	26 / 2		x200/2	x240/2	x102
+ * 1  1  0	30 / 2		x172/2	x208/2	x106
+ * 1  1  1	30 / 2		x172/2	x208/2	x88
+ *
+ * *1 :	Table 7.6 indicates VCO ouput (PLLx = VCO/2)
+ */
+#define CPG_PLL_CONFIG_INDEX(md)	((((md) & BIT(14)) >> 12) | \
+					 (((md) & BIT(13)) >> 12) | \
+					 (((md) & BIT(19)) >> 19))
+struct cpg_pll_config {
+	unsigned int extal_div;
+	unsigned int pll1_mult;
+	unsigned int pll3_mult;
+};
+
+static const struct cpg_pll_config cpg_pll_configs[8] __initconst = {
+	{ 1, 208, 106 }, { 1, 208,  88 }, { 1, 156,  80 }, { 1, 156,  66 },
+	{ 2, 240, 122 }, { 2, 240, 102 }, { 2, 208, 106 }, { 2, 208,  88 },
+};
+
+/* SDHI divisors */
+static const struct clk_div_table cpg_sdh_div_table[] = {
+	{  0,  2 }, {  1,  3 }, {  2,  4 }, {  3,  6 },
+	{  4,  8 }, {  5, 12 }, {  6, 16 }, {  7, 18 },
+	{  8, 24 }, { 10, 36 }, { 11, 48 }, {  0,  0 },
+};
+
+static const struct clk_div_table cpg_sd01_div_table[] = {
+	{  5, 12 }, {  6, 16 }, {  7, 18 }, {  8, 24 },
+	{ 10, 36 }, { 11, 48 }, { 12, 10 }, {  0,  0 },
+};
+
+/* -----------------------------------------------------------------------------
+ * Initialization
+ */
+
+static u32 cpg_mode __initdata;
+
+static struct clk * __init
+rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg,
+			     const struct cpg_pll_config *config,
+			     const char *name)
+{
+	const struct clk_div_table *table = NULL;
+	const char *parent_name = "main";
+	unsigned int shift;
+	unsigned int mult = 1;
+	unsigned int div = 1;
+
+	if (!strcmp(name, "main")) {
+		parent_name = of_clk_get_parent_name(np, 0);
+		div = config->extal_div;
+	} else if (!strcmp(name, "pll0")) {
+		/* PLL0 is a configurable multiplier clock. Register it as a
+		 * fixed factor clock for now as there's no generic multiplier
+		 * clock implementation and we currently have no need to change
+		 * the multiplier value.
+		 */
+		u32 value = clk_readl(cpg->reg + CPG_PLL0CR);
+		mult = ((value >> 24) & ((1 << 7) - 1)) + 1;
+	} else if (!strcmp(name, "pll1")) {
+		mult = config->pll1_mult / 2;
+	} else if (!strcmp(name, "pll3")) {
+		mult = config->pll3_mult;
+	} else if (!strcmp(name, "lb")) {
+		div = cpg_mode & BIT(18) ? 36 : 24;
+	} else if (!strcmp(name, "qspi")) {
+		div = (cpg_mode & (BIT(3) | BIT(2) | BIT(1))) == BIT(2)
+		    ? 16 : 20;
+	} else if (!strcmp(name, "sdh")) {
+		table = cpg_sdh_div_table;
+		shift = 8;
+	} else if (!strcmp(name, "sd0")) {
+		table = cpg_sd01_div_table;
+		shift = 4;
+	} else if (!strcmp(name, "sd1")) {
+		table = cpg_sd01_div_table;
+		shift = 0;
+	} else if (!strcmp(name, "z")) {
+		return cpg_z_clk_register(cpg);
+	} else {
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (!table)
+		return clk_register_fixed_factor(NULL, name, parent_name, 0,
+						 mult, div);
+	else
+		return clk_register_divider_table(NULL, name, parent_name, 0,
+						 cpg->reg + CPG_SDCKCR, shift,
+						 4, 0, table, &cpg->lock);
+}
+
+static void __init rcar_gen2_cpg_clocks_init(struct device_node *np)
+{
+	const struct cpg_pll_config *config;
+	struct rcar_gen2_cpg *cpg;
+	struct clk **clks;
+	unsigned int i;
+	int num_clks;
+
+	num_clks = of_property_count_strings(np, "clock-output-names");
+	if (num_clks < 0) {
+		pr_err("%s: failed to count clocks\n", __func__);
+		return;
+	}
+
+	cpg = kzalloc(sizeof(*cpg), GFP_KERNEL);
+	clks = kzalloc(num_clks * sizeof(*clks), GFP_KERNEL);
+	if (cpg == NULL || clks == NULL) {
+		/* We're leaking memory on purpose, there's no point in cleaning
+		 * up as the system won't boot anyway.
+		 */
+		pr_err("%s: failed to allocate cpg\n", __func__);
+		return;
+	}
+
+	spin_lock_init(&cpg->lock);
+
+	cpg->data.clks = clks;
+	cpg->data.clk_num = num_clks;
+
+	cpg->reg = of_iomap(np, 0);
+	if (WARN_ON(cpg->reg == NULL))
+		return;
+
+	config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+
+	for (i = 0; i < num_clks; ++i) {
+		const char *name;
+		struct clk *clk;
+
+		of_property_read_string_index(np, "clock-output-names", i,
+					      &name);
+
+		clk = rcar_gen2_cpg_register_clock(np, cpg, config, name);
+		if (IS_ERR(clk))
+			pr_err("%s: failed to register %s %s clock (%ld)\n",
+			       __func__, np->name, name, PTR_ERR(clk));
+		else
+			cpg->data.clks[i] = clk;
+	}
+
+	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+}
+CLK_OF_DECLARE(rcar_gen2_cpg_clks, "renesas,rcar-gen2-cpg-clocks",
+	       rcar_gen2_cpg_clocks_init);
+
+void __init rcar_gen2_clocks_init(u32 mode)
+{
+	cpg_mode = mode;
+
+	of_clk_init(NULL);
+}
diff --git a/include/linux/clk/shmobile.h b/include/linux/clk/shmobile.h
new file mode 100644
index 0000000..f9bf080
--- /dev/null
+++ b/include/linux/clk/shmobile.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Ideas On Board SPRL
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __LINUX_CLK_SHMOBILE_H_
+#define __LINUX_CLK_SHMOBILE_H_
+
+#include <linux/types.h>
+
+void rcar_gen2_clocks_init(u32 mode);
+
+#endif
-- 
1.8.3.2


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

* [PATCH v3 1/8] clk: shmobile: Add R-Car Gen2 clocks support
@ 2013-11-19 14:45   ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

The R-Car Gen2 SoCs (R8A7790 and R8A7791) have several clocks that are
too custom to be supported in a generic driver. Those clocks can be
divided in two categories:

- Fixed rate clocks with multiplier and divisor set according to boot
  mode configuration

- Custom divider clocks with SoC-specific divider values

This driver supports both.

Cc: devicetree at vger.kernel.org
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Kumar Gala <galak@codeaurora.org>
---
 .../clock/renesas,rcar-gen2-cpg-clocks.txt         |  32 +++
 drivers/clk/shmobile/Makefile                      |   5 +-
 drivers/clk/shmobile/clk-rcar-gen2.c               | 298 +++++++++++++++++++++
 include/linux/clk/shmobile.h                       |  19 ++
 4 files changed, 353 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
 create mode 100644 drivers/clk/shmobile/clk-rcar-gen2.c
 create mode 100644 include/linux/clk/shmobile.h

diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
new file mode 100644
index 0000000..7b41c2f
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
@@ -0,0 +1,32 @@
+* Renesas R-Car Gen2 Clock Pulse Generator (CPG)
+
+The CPG generates core clocks for the R-Car Gen2 SoCs. It includes three PLLs
+and several fixed ratio dividers.
+
+Required Properties:
+
+  - compatible: Must be one of
+    - "renesas,r8a7790-cpg-clocks" for the r8a7790 CPG
+    - "renesas,r8a7791-cpg-clocks" for the r8a7791 CPG
+    - "renesas,rcar-gen2-cpg-clocks" for the generic R-Car Gen2 CPG
+
+  - reg: Base address and length of the memory resource used by the CPG
+
+  - clocks: Reference to the parent clock
+  - #clock-cells: Must be 1
+  - clock-output-names: The names of the clocks. Supported clocks are "main",
+    "pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1" and "z"
+
+
+Example
+-------
+
+	cpg_clocks: cpg_clocks at e6150000 {
+		compatible = "renesas,r8a7790-cpg-clocks",
+			     "renesas,rcar-gen2-cpg-clocks";
+		reg = <0 0xe6150000 0 0x1000>;
+		clocks = <&extal_clk>;
+		#clock-cells = <1>;
+		clock-output-names = "main", "pll0, "pll1", "pll3",
+				     "lb", "qspi", "sdh", "sd0", "sd1", "z";
+	};
diff --git a/drivers/clk/shmobile/Makefile b/drivers/clk/shmobile/Makefile
index 2240730..40d88e6 100644
--- a/drivers/clk/shmobile/Makefile
+++ b/drivers/clk/shmobile/Makefile
@@ -1,3 +1,6 @@
-obj-$(CONFIG_ARCH_EMEV2)	+= clk-emev2.o
+obj-$(CONFIG_ARCH_EMEV2)		+= clk-emev2.o
+obj-$(CONFIG_ARCH_R8A7790)		+= clk-rcar-gen2.o
+obj-$(CONFIG_ARCH_R8A7791)		+= clk-rcar-gen2.o
+
 # for emply built-in.o
 obj-n	:= dummy
diff --git a/drivers/clk/shmobile/clk-rcar-gen2.c b/drivers/clk/shmobile/clk-rcar-gen2.c
new file mode 100644
index 0000000..a59ec21
--- /dev/null
+++ b/drivers/clk/shmobile/clk-rcar-gen2.c
@@ -0,0 +1,298 @@
+/*
+ * rcar_gen2 Core CPG Clocks
+ *
+ * Copyright (C) 2013  Ideas On Board SPRL
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/shmobile.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/math64.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/spinlock.h>
+
+struct rcar_gen2_cpg {
+	struct clk_onecell_data data;
+	spinlock_t lock;
+	void __iomem *reg;
+};
+
+#define CPG_SDCKCR			0x00000074
+#define CPG_PLL0CR			0x000000d8
+#define CPG_FRQCRC			0x000000e0
+#define CPG_FRQCRC_ZFC_MASK		(0x1f << 8)
+#define CPG_FRQCRC_ZFC_SHIFT		8
+
+/* -----------------------------------------------------------------------------
+ * Z Clock
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is adjustable.  clk->rate = parent->rate * mult / 32
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+struct cpg_z_clk {
+	struct clk_hw hw;
+	void __iomem *reg;
+};
+
+#define to_z_clk(_hw)	container_of(_hw, struct cpg_z_clk, hw)
+
+static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw,
+					   unsigned long parent_rate)
+{
+	struct cpg_z_clk *zclk = to_z_clk(hw);
+	unsigned int mult;
+	unsigned int val;
+
+	val = (clk_readl(zclk->reg) & CPG_FRQCRC_ZFC_MASK)
+	    >> CPG_FRQCRC_ZFC_SHIFT;
+	mult = 32 - val;
+
+	return div_u64((u64)parent_rate * mult, 32);
+}
+
+static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+				 unsigned long *parent_rate)
+{
+	unsigned long prate  = *parent_rate;
+	unsigned int mult;
+
+	if (!prate)
+		prate = 1;
+
+	mult = div_u64((u64)rate * 32, prate);
+	mult = clamp(mult, 1U, 32U);
+
+	return *parent_rate / 32 * mult;
+}
+
+static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long parent_rate)
+{
+	struct cpg_z_clk *zclk = to_z_clk(hw);
+	unsigned int mult;
+	u32 val;
+
+	mult = div_u64((u64)rate * 32, parent_rate);
+	mult = clamp(mult, 1U, 32U);
+
+	val = clk_readl(zclk->reg);
+	val &= ~CPG_FRQCRC_ZFC_MASK;
+	val |= (32 - mult) << CPG_FRQCRC_ZFC_SHIFT;
+	clk_writel(val, zclk->reg);
+
+	return 0;
+}
+
+static const struct clk_ops cpg_z_clk_ops = {
+	.recalc_rate = cpg_z_clk_recalc_rate,
+	.round_rate = cpg_z_clk_round_rate,
+	.set_rate = cpg_z_clk_set_rate,
+};
+
+static struct clk * __init cpg_z_clk_register(struct rcar_gen2_cpg *cpg)
+{
+	static const char *parent_name = "pll0";
+	struct clk_init_data init;
+	struct cpg_z_clk *zclk;
+	struct clk *clk;
+
+	zclk = kzalloc(sizeof(*zclk), GFP_KERNEL);
+	if (!zclk)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = "z";
+	init.ops = &cpg_z_clk_ops;
+	init.flags = 0;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	zclk->reg = cpg->reg + CPG_FRQCRC;
+	zclk->hw.init = &init;
+
+	clk = clk_register(NULL, &zclk->hw);
+	if (IS_ERR(clk))
+		kfree(zclk);
+
+	return clk;
+}
+
+/* -----------------------------------------------------------------------------
+ * CPG Clock Data
+ */
+
+/*
+ *   MD		EXTAL		PLL0	PLL1	PLL3
+ * 14 13 19	(MHz)		*1	*1
+ *---------------------------------------------------
+ * 0  0  0	15 x 1		x172/2	x208/2	x106
+ * 0  0  1	15 x 1		x172/2	x208/2	x88
+ * 0  1  0	20 x 1		x130/2	x156/2	x80
+ * 0  1  1	20 x 1		x130/2	x156/2	x66
+ * 1  0  0	26 / 2		x200/2	x240/2	x122
+ * 1  0  1	26 / 2		x200/2	x240/2	x102
+ * 1  1  0	30 / 2		x172/2	x208/2	x106
+ * 1  1  1	30 / 2		x172/2	x208/2	x88
+ *
+ * *1 :	Table 7.6 indicates VCO ouput (PLLx = VCO/2)
+ */
+#define CPG_PLL_CONFIG_INDEX(md)	((((md) & BIT(14)) >> 12) | \
+					 (((md) & BIT(13)) >> 12) | \
+					 (((md) & BIT(19)) >> 19))
+struct cpg_pll_config {
+	unsigned int extal_div;
+	unsigned int pll1_mult;
+	unsigned int pll3_mult;
+};
+
+static const struct cpg_pll_config cpg_pll_configs[8] __initconst = {
+	{ 1, 208, 106 }, { 1, 208,  88 }, { 1, 156,  80 }, { 1, 156,  66 },
+	{ 2, 240, 122 }, { 2, 240, 102 }, { 2, 208, 106 }, { 2, 208,  88 },
+};
+
+/* SDHI divisors */
+static const struct clk_div_table cpg_sdh_div_table[] = {
+	{  0,  2 }, {  1,  3 }, {  2,  4 }, {  3,  6 },
+	{  4,  8 }, {  5, 12 }, {  6, 16 }, {  7, 18 },
+	{  8, 24 }, { 10, 36 }, { 11, 48 }, {  0,  0 },
+};
+
+static const struct clk_div_table cpg_sd01_div_table[] = {
+	{  5, 12 }, {  6, 16 }, {  7, 18 }, {  8, 24 },
+	{ 10, 36 }, { 11, 48 }, { 12, 10 }, {  0,  0 },
+};
+
+/* -----------------------------------------------------------------------------
+ * Initialization
+ */
+
+static u32 cpg_mode __initdata;
+
+static struct clk * __init
+rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg,
+			     const struct cpg_pll_config *config,
+			     const char *name)
+{
+	const struct clk_div_table *table = NULL;
+	const char *parent_name = "main";
+	unsigned int shift;
+	unsigned int mult = 1;
+	unsigned int div = 1;
+
+	if (!strcmp(name, "main")) {
+		parent_name = of_clk_get_parent_name(np, 0);
+		div = config->extal_div;
+	} else if (!strcmp(name, "pll0")) {
+		/* PLL0 is a configurable multiplier clock. Register it as a
+		 * fixed factor clock for now as there's no generic multiplier
+		 * clock implementation and we currently have no need to change
+		 * the multiplier value.
+		 */
+		u32 value = clk_readl(cpg->reg + CPG_PLL0CR);
+		mult = ((value >> 24) & ((1 << 7) - 1)) + 1;
+	} else if (!strcmp(name, "pll1")) {
+		mult = config->pll1_mult / 2;
+	} else if (!strcmp(name, "pll3")) {
+		mult = config->pll3_mult;
+	} else if (!strcmp(name, "lb")) {
+		div = cpg_mode & BIT(18) ? 36 : 24;
+	} else if (!strcmp(name, "qspi")) {
+		div = (cpg_mode & (BIT(3) | BIT(2) | BIT(1))) == BIT(2)
+		    ? 16 : 20;
+	} else if (!strcmp(name, "sdh")) {
+		table = cpg_sdh_div_table;
+		shift = 8;
+	} else if (!strcmp(name, "sd0")) {
+		table = cpg_sd01_div_table;
+		shift = 4;
+	} else if (!strcmp(name, "sd1")) {
+		table = cpg_sd01_div_table;
+		shift = 0;
+	} else if (!strcmp(name, "z")) {
+		return cpg_z_clk_register(cpg);
+	} else {
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (!table)
+		return clk_register_fixed_factor(NULL, name, parent_name, 0,
+						 mult, div);
+	else
+		return clk_register_divider_table(NULL, name, parent_name, 0,
+						 cpg->reg + CPG_SDCKCR, shift,
+						 4, 0, table, &cpg->lock);
+}
+
+static void __init rcar_gen2_cpg_clocks_init(struct device_node *np)
+{
+	const struct cpg_pll_config *config;
+	struct rcar_gen2_cpg *cpg;
+	struct clk **clks;
+	unsigned int i;
+	int num_clks;
+
+	num_clks = of_property_count_strings(np, "clock-output-names");
+	if (num_clks < 0) {
+		pr_err("%s: failed to count clocks\n", __func__);
+		return;
+	}
+
+	cpg = kzalloc(sizeof(*cpg), GFP_KERNEL);
+	clks = kzalloc(num_clks * sizeof(*clks), GFP_KERNEL);
+	if (cpg == NULL || clks == NULL) {
+		/* We're leaking memory on purpose, there's no point in cleaning
+		 * up as the system won't boot anyway.
+		 */
+		pr_err("%s: failed to allocate cpg\n", __func__);
+		return;
+	}
+
+	spin_lock_init(&cpg->lock);
+
+	cpg->data.clks = clks;
+	cpg->data.clk_num = num_clks;
+
+	cpg->reg = of_iomap(np, 0);
+	if (WARN_ON(cpg->reg == NULL))
+		return;
+
+	config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+
+	for (i = 0; i < num_clks; ++i) {
+		const char *name;
+		struct clk *clk;
+
+		of_property_read_string_index(np, "clock-output-names", i,
+					      &name);
+
+		clk = rcar_gen2_cpg_register_clock(np, cpg, config, name);
+		if (IS_ERR(clk))
+			pr_err("%s: failed to register %s %s clock (%ld)\n",
+			       __func__, np->name, name, PTR_ERR(clk));
+		else
+			cpg->data.clks[i] = clk;
+	}
+
+	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+}
+CLK_OF_DECLARE(rcar_gen2_cpg_clks, "renesas,rcar-gen2-cpg-clocks",
+	       rcar_gen2_cpg_clocks_init);
+
+void __init rcar_gen2_clocks_init(u32 mode)
+{
+	cpg_mode = mode;
+
+	of_clk_init(NULL);
+}
diff --git a/include/linux/clk/shmobile.h b/include/linux/clk/shmobile.h
new file mode 100644
index 0000000..f9bf080
--- /dev/null
+++ b/include/linux/clk/shmobile.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Ideas On Board SPRL
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __LINUX_CLK_SHMOBILE_H_
+#define __LINUX_CLK_SHMOBILE_H_
+
+#include <linux/types.h>
+
+void rcar_gen2_clocks_init(u32 mode);
+
+#endif
-- 
1.8.3.2

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

* [PATCH v3 1/8] clk: shmobile: Add R-Car Gen2 clocks support
@ 2013-11-19 14:45   ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

The R-Car Gen2 SoCs (R8A7790 and R8A7791) have several clocks that are
too custom to be supported in a generic driver. Those clocks can be
divided in two categories:

- Fixed rate clocks with multiplier and divisor set according to boot
  mode configuration

- Custom divider clocks with SoC-specific divider values

This driver supports both.

Cc: devicetree@vger.kernel.org
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Kumar Gala <galak@codeaurora.org>
---
 .../clock/renesas,rcar-gen2-cpg-clocks.txt         |  32 +++
 drivers/clk/shmobile/Makefile                      |   5 +-
 drivers/clk/shmobile/clk-rcar-gen2.c               | 298 +++++++++++++++++++++
 include/linux/clk/shmobile.h                       |  19 ++
 4 files changed, 353 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
 create mode 100644 drivers/clk/shmobile/clk-rcar-gen2.c
 create mode 100644 include/linux/clk/shmobile.h

diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
new file mode 100644
index 0000000..7b41c2f
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
@@ -0,0 +1,32 @@
+* Renesas R-Car Gen2 Clock Pulse Generator (CPG)
+
+The CPG generates core clocks for the R-Car Gen2 SoCs. It includes three PLLs
+and several fixed ratio dividers.
+
+Required Properties:
+
+  - compatible: Must be one of
+    - "renesas,r8a7790-cpg-clocks" for the r8a7790 CPG
+    - "renesas,r8a7791-cpg-clocks" for the r8a7791 CPG
+    - "renesas,rcar-gen2-cpg-clocks" for the generic R-Car Gen2 CPG
+
+  - reg: Base address and length of the memory resource used by the CPG
+
+  - clocks: Reference to the parent clock
+  - #clock-cells: Must be 1
+  - clock-output-names: The names of the clocks. Supported clocks are "main",
+    "pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1" and "z"
+
+
+Example
+-------
+
+	cpg_clocks: cpg_clocks@e6150000 {
+		compatible = "renesas,r8a7790-cpg-clocks",
+			     "renesas,rcar-gen2-cpg-clocks";
+		reg = <0 0xe6150000 0 0x1000>;
+		clocks = <&extal_clk>;
+		#clock-cells = <1>;
+		clock-output-names = "main", "pll0, "pll1", "pll3",
+				     "lb", "qspi", "sdh", "sd0", "sd1", "z";
+	};
diff --git a/drivers/clk/shmobile/Makefile b/drivers/clk/shmobile/Makefile
index 2240730..40d88e6 100644
--- a/drivers/clk/shmobile/Makefile
+++ b/drivers/clk/shmobile/Makefile
@@ -1,3 +1,6 @@
-obj-$(CONFIG_ARCH_EMEV2)	+= clk-emev2.o
+obj-$(CONFIG_ARCH_EMEV2)		+= clk-emev2.o
+obj-$(CONFIG_ARCH_R8A7790)		+= clk-rcar-gen2.o
+obj-$(CONFIG_ARCH_R8A7791)		+= clk-rcar-gen2.o
+
 # for emply built-in.o
 obj-n	:= dummy
diff --git a/drivers/clk/shmobile/clk-rcar-gen2.c b/drivers/clk/shmobile/clk-rcar-gen2.c
new file mode 100644
index 0000000..a59ec21
--- /dev/null
+++ b/drivers/clk/shmobile/clk-rcar-gen2.c
@@ -0,0 +1,298 @@
+/*
+ * rcar_gen2 Core CPG Clocks
+ *
+ * Copyright (C) 2013  Ideas On Board SPRL
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/shmobile.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/math64.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/spinlock.h>
+
+struct rcar_gen2_cpg {
+	struct clk_onecell_data data;
+	spinlock_t lock;
+	void __iomem *reg;
+};
+
+#define CPG_SDCKCR			0x00000074
+#define CPG_PLL0CR			0x000000d8
+#define CPG_FRQCRC			0x000000e0
+#define CPG_FRQCRC_ZFC_MASK		(0x1f << 8)
+#define CPG_FRQCRC_ZFC_SHIFT		8
+
+/* -----------------------------------------------------------------------------
+ * Z Clock
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is adjustable.  clk->rate = parent->rate * mult / 32
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+struct cpg_z_clk {
+	struct clk_hw hw;
+	void __iomem *reg;
+};
+
+#define to_z_clk(_hw)	container_of(_hw, struct cpg_z_clk, hw)
+
+static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw,
+					   unsigned long parent_rate)
+{
+	struct cpg_z_clk *zclk = to_z_clk(hw);
+	unsigned int mult;
+	unsigned int val;
+
+	val = (clk_readl(zclk->reg) & CPG_FRQCRC_ZFC_MASK)
+	    >> CPG_FRQCRC_ZFC_SHIFT;
+	mult = 32 - val;
+
+	return div_u64((u64)parent_rate * mult, 32);
+}
+
+static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+				 unsigned long *parent_rate)
+{
+	unsigned long prate  = *parent_rate;
+	unsigned int mult;
+
+	if (!prate)
+		prate = 1;
+
+	mult = div_u64((u64)rate * 32, prate);
+	mult = clamp(mult, 1U, 32U);
+
+	return *parent_rate / 32 * mult;
+}
+
+static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long parent_rate)
+{
+	struct cpg_z_clk *zclk = to_z_clk(hw);
+	unsigned int mult;
+	u32 val;
+
+	mult = div_u64((u64)rate * 32, parent_rate);
+	mult = clamp(mult, 1U, 32U);
+
+	val = clk_readl(zclk->reg);
+	val &= ~CPG_FRQCRC_ZFC_MASK;
+	val |= (32 - mult) << CPG_FRQCRC_ZFC_SHIFT;
+	clk_writel(val, zclk->reg);
+
+	return 0;
+}
+
+static const struct clk_ops cpg_z_clk_ops = {
+	.recalc_rate = cpg_z_clk_recalc_rate,
+	.round_rate = cpg_z_clk_round_rate,
+	.set_rate = cpg_z_clk_set_rate,
+};
+
+static struct clk * __init cpg_z_clk_register(struct rcar_gen2_cpg *cpg)
+{
+	static const char *parent_name = "pll0";
+	struct clk_init_data init;
+	struct cpg_z_clk *zclk;
+	struct clk *clk;
+
+	zclk = kzalloc(sizeof(*zclk), GFP_KERNEL);
+	if (!zclk)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = "z";
+	init.ops = &cpg_z_clk_ops;
+	init.flags = 0;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	zclk->reg = cpg->reg + CPG_FRQCRC;
+	zclk->hw.init = &init;
+
+	clk = clk_register(NULL, &zclk->hw);
+	if (IS_ERR(clk))
+		kfree(zclk);
+
+	return clk;
+}
+
+/* -----------------------------------------------------------------------------
+ * CPG Clock Data
+ */
+
+/*
+ *   MD		EXTAL		PLL0	PLL1	PLL3
+ * 14 13 19	(MHz)		*1	*1
+ *---------------------------------------------------
+ * 0  0  0	15 x 1		x172/2	x208/2	x106
+ * 0  0  1	15 x 1		x172/2	x208/2	x88
+ * 0  1  0	20 x 1		x130/2	x156/2	x80
+ * 0  1  1	20 x 1		x130/2	x156/2	x66
+ * 1  0  0	26 / 2		x200/2	x240/2	x122
+ * 1  0  1	26 / 2		x200/2	x240/2	x102
+ * 1  1  0	30 / 2		x172/2	x208/2	x106
+ * 1  1  1	30 / 2		x172/2	x208/2	x88
+ *
+ * *1 :	Table 7.6 indicates VCO ouput (PLLx = VCO/2)
+ */
+#define CPG_PLL_CONFIG_INDEX(md)	((((md) & BIT(14)) >> 12) | \
+					 (((md) & BIT(13)) >> 12) | \
+					 (((md) & BIT(19)) >> 19))
+struct cpg_pll_config {
+	unsigned int extal_div;
+	unsigned int pll1_mult;
+	unsigned int pll3_mult;
+};
+
+static const struct cpg_pll_config cpg_pll_configs[8] __initconst = {
+	{ 1, 208, 106 }, { 1, 208,  88 }, { 1, 156,  80 }, { 1, 156,  66 },
+	{ 2, 240, 122 }, { 2, 240, 102 }, { 2, 208, 106 }, { 2, 208,  88 },
+};
+
+/* SDHI divisors */
+static const struct clk_div_table cpg_sdh_div_table[] = {
+	{  0,  2 }, {  1,  3 }, {  2,  4 }, {  3,  6 },
+	{  4,  8 }, {  5, 12 }, {  6, 16 }, {  7, 18 },
+	{  8, 24 }, { 10, 36 }, { 11, 48 }, {  0,  0 },
+};
+
+static const struct clk_div_table cpg_sd01_div_table[] = {
+	{  5, 12 }, {  6, 16 }, {  7, 18 }, {  8, 24 },
+	{ 10, 36 }, { 11, 48 }, { 12, 10 }, {  0,  0 },
+};
+
+/* -----------------------------------------------------------------------------
+ * Initialization
+ */
+
+static u32 cpg_mode __initdata;
+
+static struct clk * __init
+rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg,
+			     const struct cpg_pll_config *config,
+			     const char *name)
+{
+	const struct clk_div_table *table = NULL;
+	const char *parent_name = "main";
+	unsigned int shift;
+	unsigned int mult = 1;
+	unsigned int div = 1;
+
+	if (!strcmp(name, "main")) {
+		parent_name = of_clk_get_parent_name(np, 0);
+		div = config->extal_div;
+	} else if (!strcmp(name, "pll0")) {
+		/* PLL0 is a configurable multiplier clock. Register it as a
+		 * fixed factor clock for now as there's no generic multiplier
+		 * clock implementation and we currently have no need to change
+		 * the multiplier value.
+		 */
+		u32 value = clk_readl(cpg->reg + CPG_PLL0CR);
+		mult = ((value >> 24) & ((1 << 7) - 1)) + 1;
+	} else if (!strcmp(name, "pll1")) {
+		mult = config->pll1_mult / 2;
+	} else if (!strcmp(name, "pll3")) {
+		mult = config->pll3_mult;
+	} else if (!strcmp(name, "lb")) {
+		div = cpg_mode & BIT(18) ? 36 : 24;
+	} else if (!strcmp(name, "qspi")) {
+		div = (cpg_mode & (BIT(3) | BIT(2) | BIT(1))) = BIT(2)
+		    ? 16 : 20;
+	} else if (!strcmp(name, "sdh")) {
+		table = cpg_sdh_div_table;
+		shift = 8;
+	} else if (!strcmp(name, "sd0")) {
+		table = cpg_sd01_div_table;
+		shift = 4;
+	} else if (!strcmp(name, "sd1")) {
+		table = cpg_sd01_div_table;
+		shift = 0;
+	} else if (!strcmp(name, "z")) {
+		return cpg_z_clk_register(cpg);
+	} else {
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (!table)
+		return clk_register_fixed_factor(NULL, name, parent_name, 0,
+						 mult, div);
+	else
+		return clk_register_divider_table(NULL, name, parent_name, 0,
+						 cpg->reg + CPG_SDCKCR, shift,
+						 4, 0, table, &cpg->lock);
+}
+
+static void __init rcar_gen2_cpg_clocks_init(struct device_node *np)
+{
+	const struct cpg_pll_config *config;
+	struct rcar_gen2_cpg *cpg;
+	struct clk **clks;
+	unsigned int i;
+	int num_clks;
+
+	num_clks = of_property_count_strings(np, "clock-output-names");
+	if (num_clks < 0) {
+		pr_err("%s: failed to count clocks\n", __func__);
+		return;
+	}
+
+	cpg = kzalloc(sizeof(*cpg), GFP_KERNEL);
+	clks = kzalloc(num_clks * sizeof(*clks), GFP_KERNEL);
+	if (cpg = NULL || clks = NULL) {
+		/* We're leaking memory on purpose, there's no point in cleaning
+		 * up as the system won't boot anyway.
+		 */
+		pr_err("%s: failed to allocate cpg\n", __func__);
+		return;
+	}
+
+	spin_lock_init(&cpg->lock);
+
+	cpg->data.clks = clks;
+	cpg->data.clk_num = num_clks;
+
+	cpg->reg = of_iomap(np, 0);
+	if (WARN_ON(cpg->reg = NULL))
+		return;
+
+	config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+
+	for (i = 0; i < num_clks; ++i) {
+		const char *name;
+		struct clk *clk;
+
+		of_property_read_string_index(np, "clock-output-names", i,
+					      &name);
+
+		clk = rcar_gen2_cpg_register_clock(np, cpg, config, name);
+		if (IS_ERR(clk))
+			pr_err("%s: failed to register %s %s clock (%ld)\n",
+			       __func__, np->name, name, PTR_ERR(clk));
+		else
+			cpg->data.clks[i] = clk;
+	}
+
+	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+}
+CLK_OF_DECLARE(rcar_gen2_cpg_clks, "renesas,rcar-gen2-cpg-clocks",
+	       rcar_gen2_cpg_clocks_init);
+
+void __init rcar_gen2_clocks_init(u32 mode)
+{
+	cpg_mode = mode;
+
+	of_clk_init(NULL);
+}
diff --git a/include/linux/clk/shmobile.h b/include/linux/clk/shmobile.h
new file mode 100644
index 0000000..f9bf080
--- /dev/null
+++ b/include/linux/clk/shmobile.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013 Ideas On Board SPRL
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __LINUX_CLK_SHMOBILE_H_
+#define __LINUX_CLK_SHMOBILE_H_
+
+#include <linux/types.h>
+
+void rcar_gen2_clocks_init(u32 mode);
+
+#endif
-- 
1.8.3.2


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

* [PATCH v3 2/8] clk: shmobile: Add DIV6 clock support
  2013-11-19 14:45 ` Laurent Pinchart
  (?)
@ 2013-11-19 14:45   ` Laurent Pinchart
  -1 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-sh; +Cc: linux-arm-kernel, Mike Turquette, devicetree

DIV6 clocks are divider gate clocks controlled through a single
register. The divider is expressed on 6 bits, hence the name, and can
take values from 1/1 to 1/64.

Those clocks are found on Renesas ARM SoCs.

Cc: devicetree@vger.kernel.org
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 .../bindings/clock/renesas,cpg-div6-clocks.txt     |  28 ++++
 drivers/clk/shmobile/Makefile                      |   1 +
 drivers/clk/shmobile/clk-div6.c                    | 185 +++++++++++++++++++++
 3 files changed, 214 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
 create mode 100644 drivers/clk/shmobile/clk-div6.c

diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
new file mode 100644
index 0000000..952e373
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
@@ -0,0 +1,28 @@
+* Renesas CPG DIV6 Clock
+
+The CPG DIV6 clocks are variable factor clocks provided by the Clock Pulse
+Generator (CPG). They clock input is divided by a configurable factor from 1
+to 64.
+
+Required Properties:
+
+  - compatible: Must be one of the following
+    - "renesas,r8a7790-div6-clock" for R8A7790 (R-Car H2) DIV6 clocks
+    - "renesas,r8a7791-div6-clock" for R8A7791 (R-Car M2) DIV6 clocks
+    - "renesas,cpg-div6-clock" for generic DIV6 clocks
+  - reg: Base address and length of the memory resource used by the DIV6 clock
+  - clocks: Reference to the parent clock
+  - #clock-cells: Must be 0
+  - clock-output-names: The name of the clock as a free-form string
+
+
+Example
+-------
+
+	sd2_clk: sd2_clk@e6150078 {
+		compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+		reg = <0 0xe6150078 0 4>;
+		clocks = <&pll1_div2_clk>;
+		#clock-cells = <0>;
+		clock-output-names = "sd2";
+	};
diff --git a/drivers/clk/shmobile/Makefile b/drivers/clk/shmobile/Makefile
index 40d88e6..eded163 100644
--- a/drivers/clk/shmobile/Makefile
+++ b/drivers/clk/shmobile/Makefile
@@ -1,6 +1,7 @@
 obj-$(CONFIG_ARCH_EMEV2)		+= clk-emev2.o
 obj-$(CONFIG_ARCH_R8A7790)		+= clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_R8A7791)		+= clk-rcar-gen2.o
+obj-$(CONFIG_ARCH_SHMOBILE_MULTI)	+= clk-div6.o
 
 # for emply built-in.o
 obj-n	:= dummy
diff --git a/drivers/clk/shmobile/clk-div6.c b/drivers/clk/shmobile/clk-div6.c
new file mode 100644
index 0000000..aac4756
--- /dev/null
+++ b/drivers/clk/shmobile/clk-div6.c
@@ -0,0 +1,185 @@
+/*
+ * r8a7790 Common Clock Framework support
+ *
+ * Copyright (C) 2013  Renesas Solutions Corp.
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#define CPG_DIV6_CKSTP		BIT(8)
+#define CPG_DIV6_DIV(d)		((d) & 0x3f)
+#define CPG_DIV6_DIV_MASK	0x3f
+
+/**
+ * struct div6_clock - MSTP gating clock
+ * @hw: handle between common and hardware-specific interfaces
+ * @reg: IO-remapped register
+ * @div: divisor value (1-64)
+ */
+struct div6_clock {
+	struct clk_hw hw;
+	void __iomem *reg;
+	unsigned int div;
+};
+
+#define to_div6_clock(_hw) container_of(_hw, struct div6_clock, hw)
+
+static int cpg_div6_clock_enable(struct clk_hw *hw)
+{
+	struct div6_clock *clock = to_div6_clock(hw);
+
+	clk_writel(CPG_DIV6_DIV(clock->div - 1), clock->reg);
+
+	return 0;
+}
+
+static void cpg_div6_clock_disable(struct clk_hw *hw)
+{
+	struct div6_clock *clock = to_div6_clock(hw);
+
+	/* DIV6 clocks require the divisor field to be non-zero when stopping
+	 * the clock.
+	 */
+	clk_writel(CPG_DIV6_CKSTP | CPG_DIV6_DIV(CPG_DIV6_DIV_MASK),
+		   clock->reg);
+}
+
+static int cpg_div6_clock_is_enabled(struct clk_hw *hw)
+{
+	struct div6_clock *clock = to_div6_clock(hw);
+
+	return !(clk_readl(clock->reg) & CPG_DIV6_CKSTP);
+}
+
+static unsigned long cpg_div6_clock_recalc_rate(struct clk_hw *hw,
+						unsigned long parent_rate)
+{
+	struct div6_clock *clock = to_div6_clock(hw);
+	unsigned int div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1;
+
+	return parent_rate / div;
+}
+
+static unsigned int cpg_div6_clock_calc_div(unsigned long rate,
+					    unsigned long parent_rate)
+{
+	unsigned int div;
+
+	div = DIV_ROUND_CLOSEST(parent_rate, rate);
+	return clamp_t(unsigned int, div, 1, 64);
+}
+
+static long cpg_div6_clock_round_rate(struct clk_hw *hw, unsigned long rate,
+				      unsigned long *parent_rate)
+{
+	unsigned int div = cpg_div6_clock_calc_div(rate, *parent_rate);
+
+	return *parent_rate / div;
+}
+
+static int cpg_div6_clock_set_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long parent_rate)
+{
+	struct div6_clock *clock = to_div6_clock(hw);
+	unsigned int div = cpg_div6_clock_calc_div(rate, parent_rate);
+
+	clock->div = div;
+
+	/* Only program the new divisor if the clock isn't stopped. */
+	if (!(clk_readl(clock->reg) & CPG_DIV6_CKSTP))
+		clk_writel(CPG_DIV6_DIV(clock->div - 1), clock->reg);
+
+	return 0;
+}
+
+static const struct clk_ops cpg_div6_clock_ops = {
+	.enable = cpg_div6_clock_enable,
+	.disable = cpg_div6_clock_disable,
+	.is_enabled = cpg_div6_clock_is_enabled,
+	.recalc_rate = cpg_div6_clock_recalc_rate,
+	.round_rate = cpg_div6_clock_round_rate,
+	.set_rate = cpg_div6_clock_set_rate,
+};
+
+static void __init cpg_div6_clock_init(struct device_node *np)
+{
+	struct clk_init_data init;
+	struct div6_clock *clock;
+	const char *parent_name;
+	const char *name;
+	struct clk *clk;
+	int ret;
+
+	clock = kzalloc(sizeof(*clock), GFP_KERNEL);
+	if (!clock) {
+		pr_err("%s: failed to allocate %s DIV6 clock\n",
+		       __func__, np->name);
+		return;
+	}
+
+	/* Remap the clock register and read the divisor. Disabling the
+	 * clock overwrites the divisor, so we need to cache its value for the
+	 * enable operation.
+	 */
+	clock->reg = of_iomap(np, 0);
+	if (clock->reg == NULL) {
+		pr_err("%s: failed to map %s DIV6 clock register\n",
+		       __func__, np->name);
+		goto error;
+	}
+
+	clock->div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1;
+
+	/* Parse the DT properties. */
+	ret = of_property_read_string(np, "clock-output-names", &name);
+	if (ret < 0) {
+		pr_err("%s: failed to get %s DIV6 clock output name\n",
+		       __func__, np->name);
+		goto error;
+	}
+
+	parent_name = of_clk_get_parent_name(np, 0);
+	if (parent_name == NULL) {
+		pr_err("%s: failed to get %s DIV6 clock parent name\n",
+		       __func__, np->name);
+		goto error;
+	}
+
+	/* Register the clock. */
+	init.name = name;
+	init.ops = &cpg_div6_clock_ops;
+	init.flags = CLK_IS_BASIC;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	clock->hw.init = &init;
+
+	clk = clk_register(NULL, &clock->hw);
+	if (IS_ERR(clk)) {
+		pr_err("%s: failed to register %s DIV6 clock (%ld)\n",
+		       __func__, np->name, PTR_ERR(clk));
+		goto error;
+	}
+
+	of_clk_add_provider(np, of_clk_src_simple_get, clk);
+
+	return;
+
+error:
+	if (clock->reg)
+		iounmap(clock->reg);
+	kfree(clock);
+}
+CLK_OF_DECLARE(cpg_div6_clk, "renesas,cpg-div6-clock", cpg_div6_clock_init);
-- 
1.8.3.2


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

* [PATCH v3 2/8] clk: shmobile: Add DIV6 clock support
@ 2013-11-19 14:45   ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

DIV6 clocks are divider gate clocks controlled through a single
register. The divider is expressed on 6 bits, hence the name, and can
take values from 1/1 to 1/64.

Those clocks are found on Renesas ARM SoCs.

Cc: devicetree at vger.kernel.org
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 .../bindings/clock/renesas,cpg-div6-clocks.txt     |  28 ++++
 drivers/clk/shmobile/Makefile                      |   1 +
 drivers/clk/shmobile/clk-div6.c                    | 185 +++++++++++++++++++++
 3 files changed, 214 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
 create mode 100644 drivers/clk/shmobile/clk-div6.c

diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
new file mode 100644
index 0000000..952e373
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
@@ -0,0 +1,28 @@
+* Renesas CPG DIV6 Clock
+
+The CPG DIV6 clocks are variable factor clocks provided by the Clock Pulse
+Generator (CPG). They clock input is divided by a configurable factor from 1
+to 64.
+
+Required Properties:
+
+  - compatible: Must be one of the following
+    - "renesas,r8a7790-div6-clock" for R8A7790 (R-Car H2) DIV6 clocks
+    - "renesas,r8a7791-div6-clock" for R8A7791 (R-Car M2) DIV6 clocks
+    - "renesas,cpg-div6-clock" for generic DIV6 clocks
+  - reg: Base address and length of the memory resource used by the DIV6 clock
+  - clocks: Reference to the parent clock
+  - #clock-cells: Must be 0
+  - clock-output-names: The name of the clock as a free-form string
+
+
+Example
+-------
+
+	sd2_clk: sd2_clk at e6150078 {
+		compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+		reg = <0 0xe6150078 0 4>;
+		clocks = <&pll1_div2_clk>;
+		#clock-cells = <0>;
+		clock-output-names = "sd2";
+	};
diff --git a/drivers/clk/shmobile/Makefile b/drivers/clk/shmobile/Makefile
index 40d88e6..eded163 100644
--- a/drivers/clk/shmobile/Makefile
+++ b/drivers/clk/shmobile/Makefile
@@ -1,6 +1,7 @@
 obj-$(CONFIG_ARCH_EMEV2)		+= clk-emev2.o
 obj-$(CONFIG_ARCH_R8A7790)		+= clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_R8A7791)		+= clk-rcar-gen2.o
+obj-$(CONFIG_ARCH_SHMOBILE_MULTI)	+= clk-div6.o
 
 # for emply built-in.o
 obj-n	:= dummy
diff --git a/drivers/clk/shmobile/clk-div6.c b/drivers/clk/shmobile/clk-div6.c
new file mode 100644
index 0000000..aac4756
--- /dev/null
+++ b/drivers/clk/shmobile/clk-div6.c
@@ -0,0 +1,185 @@
+/*
+ * r8a7790 Common Clock Framework support
+ *
+ * Copyright (C) 2013  Renesas Solutions Corp.
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#define CPG_DIV6_CKSTP		BIT(8)
+#define CPG_DIV6_DIV(d)		((d) & 0x3f)
+#define CPG_DIV6_DIV_MASK	0x3f
+
+/**
+ * struct div6_clock - MSTP gating clock
+ * @hw: handle between common and hardware-specific interfaces
+ * @reg: IO-remapped register
+ * @div: divisor value (1-64)
+ */
+struct div6_clock {
+	struct clk_hw hw;
+	void __iomem *reg;
+	unsigned int div;
+};
+
+#define to_div6_clock(_hw) container_of(_hw, struct div6_clock, hw)
+
+static int cpg_div6_clock_enable(struct clk_hw *hw)
+{
+	struct div6_clock *clock = to_div6_clock(hw);
+
+	clk_writel(CPG_DIV6_DIV(clock->div - 1), clock->reg);
+
+	return 0;
+}
+
+static void cpg_div6_clock_disable(struct clk_hw *hw)
+{
+	struct div6_clock *clock = to_div6_clock(hw);
+
+	/* DIV6 clocks require the divisor field to be non-zero when stopping
+	 * the clock.
+	 */
+	clk_writel(CPG_DIV6_CKSTP | CPG_DIV6_DIV(CPG_DIV6_DIV_MASK),
+		   clock->reg);
+}
+
+static int cpg_div6_clock_is_enabled(struct clk_hw *hw)
+{
+	struct div6_clock *clock = to_div6_clock(hw);
+
+	return !(clk_readl(clock->reg) & CPG_DIV6_CKSTP);
+}
+
+static unsigned long cpg_div6_clock_recalc_rate(struct clk_hw *hw,
+						unsigned long parent_rate)
+{
+	struct div6_clock *clock = to_div6_clock(hw);
+	unsigned int div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1;
+
+	return parent_rate / div;
+}
+
+static unsigned int cpg_div6_clock_calc_div(unsigned long rate,
+					    unsigned long parent_rate)
+{
+	unsigned int div;
+
+	div = DIV_ROUND_CLOSEST(parent_rate, rate);
+	return clamp_t(unsigned int, div, 1, 64);
+}
+
+static long cpg_div6_clock_round_rate(struct clk_hw *hw, unsigned long rate,
+				      unsigned long *parent_rate)
+{
+	unsigned int div = cpg_div6_clock_calc_div(rate, *parent_rate);
+
+	return *parent_rate / div;
+}
+
+static int cpg_div6_clock_set_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long parent_rate)
+{
+	struct div6_clock *clock = to_div6_clock(hw);
+	unsigned int div = cpg_div6_clock_calc_div(rate, parent_rate);
+
+	clock->div = div;
+
+	/* Only program the new divisor if the clock isn't stopped. */
+	if (!(clk_readl(clock->reg) & CPG_DIV6_CKSTP))
+		clk_writel(CPG_DIV6_DIV(clock->div - 1), clock->reg);
+
+	return 0;
+}
+
+static const struct clk_ops cpg_div6_clock_ops = {
+	.enable = cpg_div6_clock_enable,
+	.disable = cpg_div6_clock_disable,
+	.is_enabled = cpg_div6_clock_is_enabled,
+	.recalc_rate = cpg_div6_clock_recalc_rate,
+	.round_rate = cpg_div6_clock_round_rate,
+	.set_rate = cpg_div6_clock_set_rate,
+};
+
+static void __init cpg_div6_clock_init(struct device_node *np)
+{
+	struct clk_init_data init;
+	struct div6_clock *clock;
+	const char *parent_name;
+	const char *name;
+	struct clk *clk;
+	int ret;
+
+	clock = kzalloc(sizeof(*clock), GFP_KERNEL);
+	if (!clock) {
+		pr_err("%s: failed to allocate %s DIV6 clock\n",
+		       __func__, np->name);
+		return;
+	}
+
+	/* Remap the clock register and read the divisor. Disabling the
+	 * clock overwrites the divisor, so we need to cache its value for the
+	 * enable operation.
+	 */
+	clock->reg = of_iomap(np, 0);
+	if (clock->reg == NULL) {
+		pr_err("%s: failed to map %s DIV6 clock register\n",
+		       __func__, np->name);
+		goto error;
+	}
+
+	clock->div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1;
+
+	/* Parse the DT properties. */
+	ret = of_property_read_string(np, "clock-output-names", &name);
+	if (ret < 0) {
+		pr_err("%s: failed to get %s DIV6 clock output name\n",
+		       __func__, np->name);
+		goto error;
+	}
+
+	parent_name = of_clk_get_parent_name(np, 0);
+	if (parent_name == NULL) {
+		pr_err("%s: failed to get %s DIV6 clock parent name\n",
+		       __func__, np->name);
+		goto error;
+	}
+
+	/* Register the clock. */
+	init.name = name;
+	init.ops = &cpg_div6_clock_ops;
+	init.flags = CLK_IS_BASIC;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	clock->hw.init = &init;
+
+	clk = clk_register(NULL, &clock->hw);
+	if (IS_ERR(clk)) {
+		pr_err("%s: failed to register %s DIV6 clock (%ld)\n",
+		       __func__, np->name, PTR_ERR(clk));
+		goto error;
+	}
+
+	of_clk_add_provider(np, of_clk_src_simple_get, clk);
+
+	return;
+
+error:
+	if (clock->reg)
+		iounmap(clock->reg);
+	kfree(clock);
+}
+CLK_OF_DECLARE(cpg_div6_clk, "renesas,cpg-div6-clock", cpg_div6_clock_init);
-- 
1.8.3.2

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

* [PATCH v3 2/8] clk: shmobile: Add DIV6 clock support
@ 2013-11-19 14:45   ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

DIV6 clocks are divider gate clocks controlled through a single
register. The divider is expressed on 6 bits, hence the name, and can
take values from 1/1 to 1/64.

Those clocks are found on Renesas ARM SoCs.

Cc: devicetree@vger.kernel.org
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 .../bindings/clock/renesas,cpg-div6-clocks.txt     |  28 ++++
 drivers/clk/shmobile/Makefile                      |   1 +
 drivers/clk/shmobile/clk-div6.c                    | 185 +++++++++++++++++++++
 3 files changed, 214 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
 create mode 100644 drivers/clk/shmobile/clk-div6.c

diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
new file mode 100644
index 0000000..952e373
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
@@ -0,0 +1,28 @@
+* Renesas CPG DIV6 Clock
+
+The CPG DIV6 clocks are variable factor clocks provided by the Clock Pulse
+Generator (CPG). They clock input is divided by a configurable factor from 1
+to 64.
+
+Required Properties:
+
+  - compatible: Must be one of the following
+    - "renesas,r8a7790-div6-clock" for R8A7790 (R-Car H2) DIV6 clocks
+    - "renesas,r8a7791-div6-clock" for R8A7791 (R-Car M2) DIV6 clocks
+    - "renesas,cpg-div6-clock" for generic DIV6 clocks
+  - reg: Base address and length of the memory resource used by the DIV6 clock
+  - clocks: Reference to the parent clock
+  - #clock-cells: Must be 0
+  - clock-output-names: The name of the clock as a free-form string
+
+
+Example
+-------
+
+	sd2_clk: sd2_clk@e6150078 {
+		compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+		reg = <0 0xe6150078 0 4>;
+		clocks = <&pll1_div2_clk>;
+		#clock-cells = <0>;
+		clock-output-names = "sd2";
+	};
diff --git a/drivers/clk/shmobile/Makefile b/drivers/clk/shmobile/Makefile
index 40d88e6..eded163 100644
--- a/drivers/clk/shmobile/Makefile
+++ b/drivers/clk/shmobile/Makefile
@@ -1,6 +1,7 @@
 obj-$(CONFIG_ARCH_EMEV2)		+= clk-emev2.o
 obj-$(CONFIG_ARCH_R8A7790)		+= clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_R8A7791)		+= clk-rcar-gen2.o
+obj-$(CONFIG_ARCH_SHMOBILE_MULTI)	+= clk-div6.o
 
 # for emply built-in.o
 obj-n	:= dummy
diff --git a/drivers/clk/shmobile/clk-div6.c b/drivers/clk/shmobile/clk-div6.c
new file mode 100644
index 0000000..aac4756
--- /dev/null
+++ b/drivers/clk/shmobile/clk-div6.c
@@ -0,0 +1,185 @@
+/*
+ * r8a7790 Common Clock Framework support
+ *
+ * Copyright (C) 2013  Renesas Solutions Corp.
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#define CPG_DIV6_CKSTP		BIT(8)
+#define CPG_DIV6_DIV(d)		((d) & 0x3f)
+#define CPG_DIV6_DIV_MASK	0x3f
+
+/**
+ * struct div6_clock - MSTP gating clock
+ * @hw: handle between common and hardware-specific interfaces
+ * @reg: IO-remapped register
+ * @div: divisor value (1-64)
+ */
+struct div6_clock {
+	struct clk_hw hw;
+	void __iomem *reg;
+	unsigned int div;
+};
+
+#define to_div6_clock(_hw) container_of(_hw, struct div6_clock, hw)
+
+static int cpg_div6_clock_enable(struct clk_hw *hw)
+{
+	struct div6_clock *clock = to_div6_clock(hw);
+
+	clk_writel(CPG_DIV6_DIV(clock->div - 1), clock->reg);
+
+	return 0;
+}
+
+static void cpg_div6_clock_disable(struct clk_hw *hw)
+{
+	struct div6_clock *clock = to_div6_clock(hw);
+
+	/* DIV6 clocks require the divisor field to be non-zero when stopping
+	 * the clock.
+	 */
+	clk_writel(CPG_DIV6_CKSTP | CPG_DIV6_DIV(CPG_DIV6_DIV_MASK),
+		   clock->reg);
+}
+
+static int cpg_div6_clock_is_enabled(struct clk_hw *hw)
+{
+	struct div6_clock *clock = to_div6_clock(hw);
+
+	return !(clk_readl(clock->reg) & CPG_DIV6_CKSTP);
+}
+
+static unsigned long cpg_div6_clock_recalc_rate(struct clk_hw *hw,
+						unsigned long parent_rate)
+{
+	struct div6_clock *clock = to_div6_clock(hw);
+	unsigned int div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1;
+
+	return parent_rate / div;
+}
+
+static unsigned int cpg_div6_clock_calc_div(unsigned long rate,
+					    unsigned long parent_rate)
+{
+	unsigned int div;
+
+	div = DIV_ROUND_CLOSEST(parent_rate, rate);
+	return clamp_t(unsigned int, div, 1, 64);
+}
+
+static long cpg_div6_clock_round_rate(struct clk_hw *hw, unsigned long rate,
+				      unsigned long *parent_rate)
+{
+	unsigned int div = cpg_div6_clock_calc_div(rate, *parent_rate);
+
+	return *parent_rate / div;
+}
+
+static int cpg_div6_clock_set_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long parent_rate)
+{
+	struct div6_clock *clock = to_div6_clock(hw);
+	unsigned int div = cpg_div6_clock_calc_div(rate, parent_rate);
+
+	clock->div = div;
+
+	/* Only program the new divisor if the clock isn't stopped. */
+	if (!(clk_readl(clock->reg) & CPG_DIV6_CKSTP))
+		clk_writel(CPG_DIV6_DIV(clock->div - 1), clock->reg);
+
+	return 0;
+}
+
+static const struct clk_ops cpg_div6_clock_ops = {
+	.enable = cpg_div6_clock_enable,
+	.disable = cpg_div6_clock_disable,
+	.is_enabled = cpg_div6_clock_is_enabled,
+	.recalc_rate = cpg_div6_clock_recalc_rate,
+	.round_rate = cpg_div6_clock_round_rate,
+	.set_rate = cpg_div6_clock_set_rate,
+};
+
+static void __init cpg_div6_clock_init(struct device_node *np)
+{
+	struct clk_init_data init;
+	struct div6_clock *clock;
+	const char *parent_name;
+	const char *name;
+	struct clk *clk;
+	int ret;
+
+	clock = kzalloc(sizeof(*clock), GFP_KERNEL);
+	if (!clock) {
+		pr_err("%s: failed to allocate %s DIV6 clock\n",
+		       __func__, np->name);
+		return;
+	}
+
+	/* Remap the clock register and read the divisor. Disabling the
+	 * clock overwrites the divisor, so we need to cache its value for the
+	 * enable operation.
+	 */
+	clock->reg = of_iomap(np, 0);
+	if (clock->reg = NULL) {
+		pr_err("%s: failed to map %s DIV6 clock register\n",
+		       __func__, np->name);
+		goto error;
+	}
+
+	clock->div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1;
+
+	/* Parse the DT properties. */
+	ret = of_property_read_string(np, "clock-output-names", &name);
+	if (ret < 0) {
+		pr_err("%s: failed to get %s DIV6 clock output name\n",
+		       __func__, np->name);
+		goto error;
+	}
+
+	parent_name = of_clk_get_parent_name(np, 0);
+	if (parent_name = NULL) {
+		pr_err("%s: failed to get %s DIV6 clock parent name\n",
+		       __func__, np->name);
+		goto error;
+	}
+
+	/* Register the clock. */
+	init.name = name;
+	init.ops = &cpg_div6_clock_ops;
+	init.flags = CLK_IS_BASIC;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	clock->hw.init = &init;
+
+	clk = clk_register(NULL, &clock->hw);
+	if (IS_ERR(clk)) {
+		pr_err("%s: failed to register %s DIV6 clock (%ld)\n",
+		       __func__, np->name, PTR_ERR(clk));
+		goto error;
+	}
+
+	of_clk_add_provider(np, of_clk_src_simple_get, clk);
+
+	return;
+
+error:
+	if (clock->reg)
+		iounmap(clock->reg);
+	kfree(clock);
+}
+CLK_OF_DECLARE(cpg_div6_clk, "renesas,cpg-div6-clock", cpg_div6_clock_init);
-- 
1.8.3.2


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

* [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
  2013-11-19 14:45 ` Laurent Pinchart
  (?)
@ 2013-11-19 14:45   ` Laurent Pinchart
  -1 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-sh; +Cc: linux-arm-kernel, Mike Turquette, devicetree

MSTP clocks are gate clocks controlled through a register that handles
up to 32 clocks. The register is often sparsely populated.

Those clocks are found on Renesas ARM SoCs.

Cc: devicetree@vger.kernel.org
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
 drivers/clk/shmobile/Makefile                      |   1 +
 drivers/clk/shmobile/clk-mstp.c                    | 229 +++++++++++++++++++++
 3 files changed, 278 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
 create mode 100644 drivers/clk/shmobile/clk-mstp.c

diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
new file mode 100644
index 0000000..126b17e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
@@ -0,0 +1,48 @@
+* Renesas CPG Module Stop (MSTP) Clocks
+
+The CPG can gate SoC device clocks. The gates are organized in groups of up to
+32 gates.
+
+This device tree binding describes a single 32 gate clocks group per node.
+Clocks are referenced by user nodes by the MSTP node phandle and the clock
+index in the group, from 0 to 31.
+
+Required Properties:
+
+  - compatible: Must be one of the following
+    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks
+    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate clocks
+    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
+  - reg: Base address and length of the memory resource used by the MSTP
+    clocks
+  - clocks: Reference to the parent clocks
+  - #clock-cells: Must be 1
+  - clock-output-names: The name of the clocks as free-form strings
+  - renesas,indices: Indices of the gate clocks into the group (0 to 31)
+
+The clocks, clock-output-names and renesas,indices properties contain one
+entry per gate clock. The MSTP groups are sparsely populated. Unimplemented
+gate clocks must not be declared.
+
+
+Example
+-------
+
+	#include <dt-bindings/clock/r8a7790-clock.h>
+
+	mstp3_clks: mstp3_clks@e615013c {
+		compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+		reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
+		clocks = <&cp_clk>, <&mmc1_clk>, <&sd3_clk>, <&sd2_clk>,
+			 <&cpg_clocks R8A7790_CLK_SD1>, <&cpg_clocks R8A7790_CLK_SD0>,
+			 <&mmc0_clk>;
+		#clock-cells = <1>;
+		clock-output-names =
+			"tpu0", "mmcif1", "sdhi3", "sdhi2",
+			 "sdhi1", "sdhi0", "mmcif0";
+		renesas,clock-indices = <
+			R8A7790_CLK_TPU0 R8A7790_CLK_MMCIF1 R8A7790_CLK_SDHI3
+			R8A7790_CLK_SDHI2 R8A7790_CLK_SDHI1 R8A7790_CLK_SDHI0
+			R8A7790_CLK_MMCIF0
+		>;
+	};
diff --git a/drivers/clk/shmobile/Makefile b/drivers/clk/shmobile/Makefile
index eded163..4df35a0 100644
--- a/drivers/clk/shmobile/Makefile
+++ b/drivers/clk/shmobile/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_ARCH_EMEV2)		+= clk-emev2.o
 obj-$(CONFIG_ARCH_R8A7790)		+= clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_R8A7791)		+= clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_SHMOBILE_MULTI)	+= clk-div6.o
+obj-$(CONFIG_ARCH_SHMOBILE_MULTI)	+= clk-mstp.o
 
 # for emply built-in.o
 obj-n	:= dummy
diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/shmobile/clk-mstp.c
new file mode 100644
index 0000000..e576b60
--- /dev/null
+++ b/drivers/clk/shmobile/clk-mstp.c
@@ -0,0 +1,229 @@
+/*
+ * R-Car MSTP clocks
+ *
+ * Copyright (C) 2013 Ideas On Board SPRL
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/spinlock.h>
+
+/*
+ * MSTP clocks. We can't use standard gate clocks as we need to poll on the
+ * status register when enabling the clock.
+ */
+
+#define MSTP_MAX_CLOCKS		32
+
+/**
+ * struct mstp_clock_group - MSTP gating clocks group
+ *
+ * @data: clocks in this group
+ * @smstpcr: module stop control register
+ * @mstpsr: module stop status register (optional)
+ * @lock: protects writes to SMSTPCR
+ */
+struct mstp_clock_group {
+	struct clk_onecell_data data;
+	void __iomem *smstpcr;
+	void __iomem *mstpsr;
+	spinlock_t lock;
+};
+
+/**
+ * struct mstp_clock - MSTP gating clock
+ * @hw: handle between common and hardware-specific interfaces
+ * @bit_index: control bit index
+ * @group: MSTP clocks group
+ */
+struct mstp_clock {
+	struct clk_hw hw;
+	u32 bit_index;
+	struct mstp_clock_group *group;
+};
+
+#define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw)
+
+static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
+{
+	struct mstp_clock *clock = to_mstp_clock(hw);
+	struct mstp_clock_group *group = clock->group;
+	u32 bitmask = BIT(clock->bit_index);
+	unsigned long flags;
+	unsigned int i;
+	u32 value;
+
+	spin_lock_irqsave(&group->lock, flags);
+
+	value = clk_readl(group->smstpcr);
+	if (enable)
+		value &= ~bitmask;
+	else
+		value |= bitmask;
+	clk_writel(value, group->smstpcr);
+
+	spin_unlock_irqrestore(&group->lock, flags);
+
+	if (!enable || !group->mstpsr)
+		return 0;
+
+	for (i = 1000; i > 0; --i) {
+		if (!(clk_readl(group->mstpsr) & bitmask))
+			break;
+		cpu_relax();
+	}
+
+	if (!i) {
+		pr_err("%s: failed to enable %p[%d]\n", __func__,
+		       group->smstpcr, clock->bit_index);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static int cpg_mstp_clock_enable(struct clk_hw *hw)
+{
+	return cpg_mstp_clock_endisable(hw, true);
+}
+
+static void cpg_mstp_clock_disable(struct clk_hw *hw)
+{
+	cpg_mstp_clock_endisable(hw, false);
+}
+
+static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
+{
+	struct mstp_clock *clock = to_mstp_clock(hw);
+	struct mstp_clock_group *group = clock->group;
+	u32 value;
+
+	if (group->mstpsr)
+		value = clk_readl(group->mstpsr);
+	else
+		value = clk_readl(group->smstpcr);
+
+	return !!(value & BIT(clock->bit_index));
+}
+
+static const struct clk_ops cpg_mstp_clock_ops = {
+	.enable = cpg_mstp_clock_enable,
+	.disable = cpg_mstp_clock_disable,
+	.is_enabled = cpg_mstp_clock_is_enabled,
+};
+
+static struct clk * __init
+cpg_mstp_clock_register(const char *name, const char *parent_name,
+			unsigned int index, struct mstp_clock_group *group)
+{
+	struct clk_init_data init;
+	struct mstp_clock *clock;
+	struct clk *clk;
+
+	clock = kzalloc(sizeof(*clock), GFP_KERNEL);
+	if (!clock) {
+		pr_err("%s: failed to allocate MSTP clock.\n", __func__);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	init.name = name;
+	init.ops = &cpg_mstp_clock_ops;
+	init.flags = CLK_IS_BASIC;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	clock->bit_index = index;
+	clock->group = group;
+	clock->hw.init = &init;
+
+	clk = clk_register(NULL, &clock->hw);
+
+	if (IS_ERR(clk))
+		kfree(clock);
+
+	return clk;
+}
+
+static void __init cpg_mstp_clocks_init(struct device_node *np)
+{
+	struct mstp_clock_group *group;
+	struct clk **clks;
+	unsigned int i;
+
+	group = kzalloc(sizeof(*group), GFP_KERNEL);
+	clks = kzalloc(MSTP_MAX_CLOCKS * sizeof(*clks), GFP_KERNEL);
+	if (group == NULL || clks == NULL) {
+		kfree(group);
+		kfree(clks);
+		pr_err("%s: failed to allocate group\n", __func__);
+		return;
+	}
+
+	spin_lock_init(&group->lock);
+	group->data.clks = clks;
+
+	group->smstpcr = of_iomap(np, 0);
+	group->mstpsr = of_iomap(np, 1);
+
+	if (group->smstpcr == NULL) {
+		pr_err("%s: failed to remap SMSTPCR\n", __func__);
+		kfree(group);
+		kfree(clks);
+		return;
+	}
+
+	for (i = 0; i < MSTP_MAX_CLOCKS; ++i) {
+		const char *parent_name;
+		const char *name;
+		u32 clkidx;
+		int ret;
+
+		/* Skip clocks with no name. */
+		ret = of_property_read_string_index(np, "clock-output-names",
+						    i, &name);
+		if (ret < 0 || strlen(name) == 0)
+			continue;
+
+		parent_name = of_clk_get_parent_name(np, i);
+		ret = of_property_read_u32_index(np, "renesas,clock-indices", i,
+						 &clkidx);
+		if (parent_name == NULL || ret < 0)
+			break;
+
+		if (clkidx >= MSTP_MAX_CLOCKS) {
+			pr_err("%s: invalid clock %s %s index %u)\n",
+			       __func__, np->name, name, clkidx);
+			continue;
+		}
+
+		clks[clkidx] = cpg_mstp_clock_register(name, parent_name, i,
+						       group);
+		if (!IS_ERR(clks[clkidx])) {
+			group->data.clk_num = max(group->data.clk_num, clkidx);
+			/*
+			 * Register a clkdev to let board code retrieve the
+			 * clock by name and register aliases for non-DT
+			 * devices.
+			 *
+			 * FIXME: Remove this when all devices that require a
+			 * clock will be instantiated from DT.
+			 */
+			clk_register_clkdev(clks[clkidx], name, NULL);
+		} else {
+			pr_err("%s: failed to register %s %s clock (%ld)\n",
+			       __func__, np->name, name, PTR_ERR(clks[clkidx]));
+		}
+	}
+
+	of_clk_add_provider(np, of_clk_src_onecell_get, &group->data);
+}
+CLK_OF_DECLARE(cpg_mstp_clks, "renesas,cpg-mstp-clocks", cpg_mstp_clocks_init);
-- 
1.8.3.2


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

* [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
@ 2013-11-19 14:45   ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

MSTP clocks are gate clocks controlled through a register that handles
up to 32 clocks. The register is often sparsely populated.

Those clocks are found on Renesas ARM SoCs.

Cc: devicetree at vger.kernel.org
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
 drivers/clk/shmobile/Makefile                      |   1 +
 drivers/clk/shmobile/clk-mstp.c                    | 229 +++++++++++++++++++++
 3 files changed, 278 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
 create mode 100644 drivers/clk/shmobile/clk-mstp.c

diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
new file mode 100644
index 0000000..126b17e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
@@ -0,0 +1,48 @@
+* Renesas CPG Module Stop (MSTP) Clocks
+
+The CPG can gate SoC device clocks. The gates are organized in groups of up to
+32 gates.
+
+This device tree binding describes a single 32 gate clocks group per node.
+Clocks are referenced by user nodes by the MSTP node phandle and the clock
+index in the group, from 0 to 31.
+
+Required Properties:
+
+  - compatible: Must be one of the following
+    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks
+    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate clocks
+    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
+  - reg: Base address and length of the memory resource used by the MSTP
+    clocks
+  - clocks: Reference to the parent clocks
+  - #clock-cells: Must be 1
+  - clock-output-names: The name of the clocks as free-form strings
+  - renesas,indices: Indices of the gate clocks into the group (0 to 31)
+
+The clocks, clock-output-names and renesas,indices properties contain one
+entry per gate clock. The MSTP groups are sparsely populated. Unimplemented
+gate clocks must not be declared.
+
+
+Example
+-------
+
+	#include <dt-bindings/clock/r8a7790-clock.h>
+
+	mstp3_clks: mstp3_clks at e615013c {
+		compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+		reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
+		clocks = <&cp_clk>, <&mmc1_clk>, <&sd3_clk>, <&sd2_clk>,
+			 <&cpg_clocks R8A7790_CLK_SD1>, <&cpg_clocks R8A7790_CLK_SD0>,
+			 <&mmc0_clk>;
+		#clock-cells = <1>;
+		clock-output-names =
+			"tpu0", "mmcif1", "sdhi3", "sdhi2",
+			 "sdhi1", "sdhi0", "mmcif0";
+		renesas,clock-indices = <
+			R8A7790_CLK_TPU0 R8A7790_CLK_MMCIF1 R8A7790_CLK_SDHI3
+			R8A7790_CLK_SDHI2 R8A7790_CLK_SDHI1 R8A7790_CLK_SDHI0
+			R8A7790_CLK_MMCIF0
+		>;
+	};
diff --git a/drivers/clk/shmobile/Makefile b/drivers/clk/shmobile/Makefile
index eded163..4df35a0 100644
--- a/drivers/clk/shmobile/Makefile
+++ b/drivers/clk/shmobile/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_ARCH_EMEV2)		+= clk-emev2.o
 obj-$(CONFIG_ARCH_R8A7790)		+= clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_R8A7791)		+= clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_SHMOBILE_MULTI)	+= clk-div6.o
+obj-$(CONFIG_ARCH_SHMOBILE_MULTI)	+= clk-mstp.o
 
 # for emply built-in.o
 obj-n	:= dummy
diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/shmobile/clk-mstp.c
new file mode 100644
index 0000000..e576b60
--- /dev/null
+++ b/drivers/clk/shmobile/clk-mstp.c
@@ -0,0 +1,229 @@
+/*
+ * R-Car MSTP clocks
+ *
+ * Copyright (C) 2013 Ideas On Board SPRL
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/spinlock.h>
+
+/*
+ * MSTP clocks. We can't use standard gate clocks as we need to poll on the
+ * status register when enabling the clock.
+ */
+
+#define MSTP_MAX_CLOCKS		32
+
+/**
+ * struct mstp_clock_group - MSTP gating clocks group
+ *
+ * @data: clocks in this group
+ * @smstpcr: module stop control register
+ * @mstpsr: module stop status register (optional)
+ * @lock: protects writes to SMSTPCR
+ */
+struct mstp_clock_group {
+	struct clk_onecell_data data;
+	void __iomem *smstpcr;
+	void __iomem *mstpsr;
+	spinlock_t lock;
+};
+
+/**
+ * struct mstp_clock - MSTP gating clock
+ * @hw: handle between common and hardware-specific interfaces
+ * @bit_index: control bit index
+ * @group: MSTP clocks group
+ */
+struct mstp_clock {
+	struct clk_hw hw;
+	u32 bit_index;
+	struct mstp_clock_group *group;
+};
+
+#define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw)
+
+static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
+{
+	struct mstp_clock *clock = to_mstp_clock(hw);
+	struct mstp_clock_group *group = clock->group;
+	u32 bitmask = BIT(clock->bit_index);
+	unsigned long flags;
+	unsigned int i;
+	u32 value;
+
+	spin_lock_irqsave(&group->lock, flags);
+
+	value = clk_readl(group->smstpcr);
+	if (enable)
+		value &= ~bitmask;
+	else
+		value |= bitmask;
+	clk_writel(value, group->smstpcr);
+
+	spin_unlock_irqrestore(&group->lock, flags);
+
+	if (!enable || !group->mstpsr)
+		return 0;
+
+	for (i = 1000; i > 0; --i) {
+		if (!(clk_readl(group->mstpsr) & bitmask))
+			break;
+		cpu_relax();
+	}
+
+	if (!i) {
+		pr_err("%s: failed to enable %p[%d]\n", __func__,
+		       group->smstpcr, clock->bit_index);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static int cpg_mstp_clock_enable(struct clk_hw *hw)
+{
+	return cpg_mstp_clock_endisable(hw, true);
+}
+
+static void cpg_mstp_clock_disable(struct clk_hw *hw)
+{
+	cpg_mstp_clock_endisable(hw, false);
+}
+
+static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
+{
+	struct mstp_clock *clock = to_mstp_clock(hw);
+	struct mstp_clock_group *group = clock->group;
+	u32 value;
+
+	if (group->mstpsr)
+		value = clk_readl(group->mstpsr);
+	else
+		value = clk_readl(group->smstpcr);
+
+	return !!(value & BIT(clock->bit_index));
+}
+
+static const struct clk_ops cpg_mstp_clock_ops = {
+	.enable = cpg_mstp_clock_enable,
+	.disable = cpg_mstp_clock_disable,
+	.is_enabled = cpg_mstp_clock_is_enabled,
+};
+
+static struct clk * __init
+cpg_mstp_clock_register(const char *name, const char *parent_name,
+			unsigned int index, struct mstp_clock_group *group)
+{
+	struct clk_init_data init;
+	struct mstp_clock *clock;
+	struct clk *clk;
+
+	clock = kzalloc(sizeof(*clock), GFP_KERNEL);
+	if (!clock) {
+		pr_err("%s: failed to allocate MSTP clock.\n", __func__);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	init.name = name;
+	init.ops = &cpg_mstp_clock_ops;
+	init.flags = CLK_IS_BASIC;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	clock->bit_index = index;
+	clock->group = group;
+	clock->hw.init = &init;
+
+	clk = clk_register(NULL, &clock->hw);
+
+	if (IS_ERR(clk))
+		kfree(clock);
+
+	return clk;
+}
+
+static void __init cpg_mstp_clocks_init(struct device_node *np)
+{
+	struct mstp_clock_group *group;
+	struct clk **clks;
+	unsigned int i;
+
+	group = kzalloc(sizeof(*group), GFP_KERNEL);
+	clks = kzalloc(MSTP_MAX_CLOCKS * sizeof(*clks), GFP_KERNEL);
+	if (group == NULL || clks == NULL) {
+		kfree(group);
+		kfree(clks);
+		pr_err("%s: failed to allocate group\n", __func__);
+		return;
+	}
+
+	spin_lock_init(&group->lock);
+	group->data.clks = clks;
+
+	group->smstpcr = of_iomap(np, 0);
+	group->mstpsr = of_iomap(np, 1);
+
+	if (group->smstpcr == NULL) {
+		pr_err("%s: failed to remap SMSTPCR\n", __func__);
+		kfree(group);
+		kfree(clks);
+		return;
+	}
+
+	for (i = 0; i < MSTP_MAX_CLOCKS; ++i) {
+		const char *parent_name;
+		const char *name;
+		u32 clkidx;
+		int ret;
+
+		/* Skip clocks with no name. */
+		ret = of_property_read_string_index(np, "clock-output-names",
+						    i, &name);
+		if (ret < 0 || strlen(name) == 0)
+			continue;
+
+		parent_name = of_clk_get_parent_name(np, i);
+		ret = of_property_read_u32_index(np, "renesas,clock-indices", i,
+						 &clkidx);
+		if (parent_name == NULL || ret < 0)
+			break;
+
+		if (clkidx >= MSTP_MAX_CLOCKS) {
+			pr_err("%s: invalid clock %s %s index %u)\n",
+			       __func__, np->name, name, clkidx);
+			continue;
+		}
+
+		clks[clkidx] = cpg_mstp_clock_register(name, parent_name, i,
+						       group);
+		if (!IS_ERR(clks[clkidx])) {
+			group->data.clk_num = max(group->data.clk_num, clkidx);
+			/*
+			 * Register a clkdev to let board code retrieve the
+			 * clock by name and register aliases for non-DT
+			 * devices.
+			 *
+			 * FIXME: Remove this when all devices that require a
+			 * clock will be instantiated from DT.
+			 */
+			clk_register_clkdev(clks[clkidx], name, NULL);
+		} else {
+			pr_err("%s: failed to register %s %s clock (%ld)\n",
+			       __func__, np->name, name, PTR_ERR(clks[clkidx]));
+		}
+	}
+
+	of_clk_add_provider(np, of_clk_src_onecell_get, &group->data);
+}
+CLK_OF_DECLARE(cpg_mstp_clks, "renesas,cpg-mstp-clocks", cpg_mstp_clocks_init);
-- 
1.8.3.2

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

* [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
@ 2013-11-19 14:45   ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

MSTP clocks are gate clocks controlled through a register that handles
up to 32 clocks. The register is often sparsely populated.

Those clocks are found on Renesas ARM SoCs.

Cc: devicetree@vger.kernel.org
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
 drivers/clk/shmobile/Makefile                      |   1 +
 drivers/clk/shmobile/clk-mstp.c                    | 229 +++++++++++++++++++++
 3 files changed, 278 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
 create mode 100644 drivers/clk/shmobile/clk-mstp.c

diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
new file mode 100644
index 0000000..126b17e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
@@ -0,0 +1,48 @@
+* Renesas CPG Module Stop (MSTP) Clocks
+
+The CPG can gate SoC device clocks. The gates are organized in groups of up to
+32 gates.
+
+This device tree binding describes a single 32 gate clocks group per node.
+Clocks are referenced by user nodes by the MSTP node phandle and the clock
+index in the group, from 0 to 31.
+
+Required Properties:
+
+  - compatible: Must be one of the following
+    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks
+    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate clocks
+    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
+  - reg: Base address and length of the memory resource used by the MSTP
+    clocks
+  - clocks: Reference to the parent clocks
+  - #clock-cells: Must be 1
+  - clock-output-names: The name of the clocks as free-form strings
+  - renesas,indices: Indices of the gate clocks into the group (0 to 31)
+
+The clocks, clock-output-names and renesas,indices properties contain one
+entry per gate clock. The MSTP groups are sparsely populated. Unimplemented
+gate clocks must not be declared.
+
+
+Example
+-------
+
+	#include <dt-bindings/clock/r8a7790-clock.h>
+
+	mstp3_clks: mstp3_clks@e615013c {
+		compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+		reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
+		clocks = <&cp_clk>, <&mmc1_clk>, <&sd3_clk>, <&sd2_clk>,
+			 <&cpg_clocks R8A7790_CLK_SD1>, <&cpg_clocks R8A7790_CLK_SD0>,
+			 <&mmc0_clk>;
+		#clock-cells = <1>;
+		clock-output-names +			"tpu0", "mmcif1", "sdhi3", "sdhi2",
+			 "sdhi1", "sdhi0", "mmcif0";
+		renesas,clock-indices = <
+			R8A7790_CLK_TPU0 R8A7790_CLK_MMCIF1 R8A7790_CLK_SDHI3
+			R8A7790_CLK_SDHI2 R8A7790_CLK_SDHI1 R8A7790_CLK_SDHI0
+			R8A7790_CLK_MMCIF0
+		>;
+	};
diff --git a/drivers/clk/shmobile/Makefile b/drivers/clk/shmobile/Makefile
index eded163..4df35a0 100644
--- a/drivers/clk/shmobile/Makefile
+++ b/drivers/clk/shmobile/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_ARCH_EMEV2)		+= clk-emev2.o
 obj-$(CONFIG_ARCH_R8A7790)		+= clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_R8A7791)		+= clk-rcar-gen2.o
 obj-$(CONFIG_ARCH_SHMOBILE_MULTI)	+= clk-div6.o
+obj-$(CONFIG_ARCH_SHMOBILE_MULTI)	+= clk-mstp.o
 
 # for emply built-in.o
 obj-n	:= dummy
diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/shmobile/clk-mstp.c
new file mode 100644
index 0000000..e576b60
--- /dev/null
+++ b/drivers/clk/shmobile/clk-mstp.c
@@ -0,0 +1,229 @@
+/*
+ * R-Car MSTP clocks
+ *
+ * Copyright (C) 2013 Ideas On Board SPRL
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/spinlock.h>
+
+/*
+ * MSTP clocks. We can't use standard gate clocks as we need to poll on the
+ * status register when enabling the clock.
+ */
+
+#define MSTP_MAX_CLOCKS		32
+
+/**
+ * struct mstp_clock_group - MSTP gating clocks group
+ *
+ * @data: clocks in this group
+ * @smstpcr: module stop control register
+ * @mstpsr: module stop status register (optional)
+ * @lock: protects writes to SMSTPCR
+ */
+struct mstp_clock_group {
+	struct clk_onecell_data data;
+	void __iomem *smstpcr;
+	void __iomem *mstpsr;
+	spinlock_t lock;
+};
+
+/**
+ * struct mstp_clock - MSTP gating clock
+ * @hw: handle between common and hardware-specific interfaces
+ * @bit_index: control bit index
+ * @group: MSTP clocks group
+ */
+struct mstp_clock {
+	struct clk_hw hw;
+	u32 bit_index;
+	struct mstp_clock_group *group;
+};
+
+#define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw)
+
+static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
+{
+	struct mstp_clock *clock = to_mstp_clock(hw);
+	struct mstp_clock_group *group = clock->group;
+	u32 bitmask = BIT(clock->bit_index);
+	unsigned long flags;
+	unsigned int i;
+	u32 value;
+
+	spin_lock_irqsave(&group->lock, flags);
+
+	value = clk_readl(group->smstpcr);
+	if (enable)
+		value &= ~bitmask;
+	else
+		value |= bitmask;
+	clk_writel(value, group->smstpcr);
+
+	spin_unlock_irqrestore(&group->lock, flags);
+
+	if (!enable || !group->mstpsr)
+		return 0;
+
+	for (i = 1000; i > 0; --i) {
+		if (!(clk_readl(group->mstpsr) & bitmask))
+			break;
+		cpu_relax();
+	}
+
+	if (!i) {
+		pr_err("%s: failed to enable %p[%d]\n", __func__,
+		       group->smstpcr, clock->bit_index);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static int cpg_mstp_clock_enable(struct clk_hw *hw)
+{
+	return cpg_mstp_clock_endisable(hw, true);
+}
+
+static void cpg_mstp_clock_disable(struct clk_hw *hw)
+{
+	cpg_mstp_clock_endisable(hw, false);
+}
+
+static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
+{
+	struct mstp_clock *clock = to_mstp_clock(hw);
+	struct mstp_clock_group *group = clock->group;
+	u32 value;
+
+	if (group->mstpsr)
+		value = clk_readl(group->mstpsr);
+	else
+		value = clk_readl(group->smstpcr);
+
+	return !!(value & BIT(clock->bit_index));
+}
+
+static const struct clk_ops cpg_mstp_clock_ops = {
+	.enable = cpg_mstp_clock_enable,
+	.disable = cpg_mstp_clock_disable,
+	.is_enabled = cpg_mstp_clock_is_enabled,
+};
+
+static struct clk * __init
+cpg_mstp_clock_register(const char *name, const char *parent_name,
+			unsigned int index, struct mstp_clock_group *group)
+{
+	struct clk_init_data init;
+	struct mstp_clock *clock;
+	struct clk *clk;
+
+	clock = kzalloc(sizeof(*clock), GFP_KERNEL);
+	if (!clock) {
+		pr_err("%s: failed to allocate MSTP clock.\n", __func__);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	init.name = name;
+	init.ops = &cpg_mstp_clock_ops;
+	init.flags = CLK_IS_BASIC;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	clock->bit_index = index;
+	clock->group = group;
+	clock->hw.init = &init;
+
+	clk = clk_register(NULL, &clock->hw);
+
+	if (IS_ERR(clk))
+		kfree(clock);
+
+	return clk;
+}
+
+static void __init cpg_mstp_clocks_init(struct device_node *np)
+{
+	struct mstp_clock_group *group;
+	struct clk **clks;
+	unsigned int i;
+
+	group = kzalloc(sizeof(*group), GFP_KERNEL);
+	clks = kzalloc(MSTP_MAX_CLOCKS * sizeof(*clks), GFP_KERNEL);
+	if (group = NULL || clks = NULL) {
+		kfree(group);
+		kfree(clks);
+		pr_err("%s: failed to allocate group\n", __func__);
+		return;
+	}
+
+	spin_lock_init(&group->lock);
+	group->data.clks = clks;
+
+	group->smstpcr = of_iomap(np, 0);
+	group->mstpsr = of_iomap(np, 1);
+
+	if (group->smstpcr = NULL) {
+		pr_err("%s: failed to remap SMSTPCR\n", __func__);
+		kfree(group);
+		kfree(clks);
+		return;
+	}
+
+	for (i = 0; i < MSTP_MAX_CLOCKS; ++i) {
+		const char *parent_name;
+		const char *name;
+		u32 clkidx;
+		int ret;
+
+		/* Skip clocks with no name. */
+		ret = of_property_read_string_index(np, "clock-output-names",
+						    i, &name);
+		if (ret < 0 || strlen(name) = 0)
+			continue;
+
+		parent_name = of_clk_get_parent_name(np, i);
+		ret = of_property_read_u32_index(np, "renesas,clock-indices", i,
+						 &clkidx);
+		if (parent_name = NULL || ret < 0)
+			break;
+
+		if (clkidx >= MSTP_MAX_CLOCKS) {
+			pr_err("%s: invalid clock %s %s index %u)\n",
+			       __func__, np->name, name, clkidx);
+			continue;
+		}
+
+		clks[clkidx] = cpg_mstp_clock_register(name, parent_name, i,
+						       group);
+		if (!IS_ERR(clks[clkidx])) {
+			group->data.clk_num = max(group->data.clk_num, clkidx);
+			/*
+			 * Register a clkdev to let board code retrieve the
+			 * clock by name and register aliases for non-DT
+			 * devices.
+			 *
+			 * FIXME: Remove this when all devices that require a
+			 * clock will be instantiated from DT.
+			 */
+			clk_register_clkdev(clks[clkidx], name, NULL);
+		} else {
+			pr_err("%s: failed to register %s %s clock (%ld)\n",
+			       __func__, np->name, name, PTR_ERR(clks[clkidx]));
+		}
+	}
+
+	of_clk_add_provider(np, of_clk_src_onecell_get, &group->data);
+}
+CLK_OF_DECLARE(cpg_mstp_clks, "renesas,cpg-mstp-clocks", cpg_mstp_clocks_init);
-- 
1.8.3.2


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

* [PATCH v3 4/8] ARM: shmobile: r8a7790: Add clock index macros for DT sources
  2013-11-19 14:45 ` Laurent Pinchart
@ 2013-11-19 14:45   ` Laurent Pinchart
  -1 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

Add macros usable by device tree sources to reference r8a7790 clocks by
index.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 include/dt-bindings/clock/r8a7790-clock.h | 100 ++++++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)
 create mode 100644 include/dt-bindings/clock/r8a7790-clock.h

diff --git a/include/dt-bindings/clock/r8a7790-clock.h b/include/dt-bindings/clock/r8a7790-clock.h
new file mode 100644
index 0000000..420f0b0
--- /dev/null
+++ b/include/dt-bindings/clock/r8a7790-clock.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2013 Ideas On Board SPRL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_R8A7790_H__
+#define __DT_BINDINGS_CLOCK_R8A7790_H__
+
+/* CPG */
+#define R8A7790_CLK_MAIN		0
+#define R8A7790_CLK_PLL0		1
+#define R8A7790_CLK_PLL1		2
+#define R8A7790_CLK_PLL3		3
+#define R8A7790_CLK_LB			4
+#define R8A7790_CLK_QSPI		5
+#define R8A7790_CLK_SDH			6
+#define R8A7790_CLK_SD0			7
+#define R8A7790_CLK_SD1			8
+#define R8A7790_CLK_Z			9
+
+/* MSTP1 */
+#define R8A7790_CLK_TMU1		11
+#define R8A7790_CLK_TMU3		21
+#define R8A7790_CLK_TMU2		22
+#define R8A7790_CLK_CMT0		24
+#define R8A7790_CLK_TMU0		25
+#define R8A7790_CLK_VSP1_DU1		27
+#define R8A7790_CLK_VSP1_DU0		28
+#define R8A7790_CLK_VSP1_RT		30
+#define R8A7790_CLK_VSP1_SY		31
+
+/* MSTP2 */
+#define R8A7790_CLK_SCIFA2		2
+#define R8A7790_CLK_SCIFA1		3
+#define R8A7790_CLK_SCIFA0		4
+#define R8A7790_CLK_SCIFB0		6
+#define R8A7790_CLK_SCIFB1		7
+#define R8A7790_CLK_SCIFB2		16
+#define R8A7790_CLK_SYS_DMAC0		18
+#define R8A7790_CLK_SYS_DMAC1		19
+
+/* MSTP3 */
+#define R8A7790_CLK_TPU0		4
+#define R8A7790_CLK_MMCIF1		5
+#define R8A7790_CLK_SDHI3		11
+#define R8A7790_CLK_SDHI2		12
+#define R8A7790_CLK_SDHI1		13
+#define R8A7790_CLK_SDHI0		14
+#define R8A7790_CLK_MMCIF0		15
+#define R8A7790_CLK_SSUSB		28
+#define R8A7790_CLK_CMT1		29
+#define R8A7790_CLK_USBDMAC0		30
+#define R8A7790_CLK_USBDMAC1		31
+
+/* MSTP5 */
+#define R8A7790_CLK_THERMAL		22
+#define R8A7790_CLK_PWM			23
+
+/* MSTP7 */
+#define R8A7790_CLK_EHCI		3
+#define R8A7790_CLK_HSUSB		4
+#define R8A7790_CLK_HSCIF1		16
+#define R8A7790_CLK_HSCIF0		17
+#define R8A7790_CLK_SCIF1		20
+#define R8A7790_CLK_SCIF0		21
+#define R8A7790_CLK_DU2			22
+#define R8A7790_CLK_DU1			23
+#define R8A7790_CLK_DU0			24
+#define R8A7790_CLK_LVDS1		25
+#define R8A7790_CLK_LVDS0		26
+
+/* MSTP8 */
+#define R8A7790_CLK_VIN3		8
+#define R8A7790_CLK_VIN2		9
+#define R8A7790_CLK_VIN1		10
+#define R8A7790_CLK_VIN0		11
+#define R8A7790_CLK_ETHER		13
+#define R8A7790_CLK_SATA1		14
+#define R8A7790_CLK_SATA0		15
+
+/* MSTP9 */
+#define R8A7790_CLK_GPIO5		7
+#define R8A7790_CLK_GPIO4		8
+#define R8A7790_CLK_GPIO3		9
+#define R8A7790_CLK_GPIO2		10
+#define R8A7790_CLK_GPIO1		11
+#define R8A7790_CLK_GPIO0		12
+#define R8A7790_CLK_RCAN1		15
+#define R8A7790_CLK_RCAN0		16
+#define R8A7790_CLK_IICDVFS		26
+#define R8A7790_CLK_I2C3		28
+#define R8A7790_CLK_I2C2		29
+#define R8A7790_CLK_I2C1		30
+#define R8A7790_CLK_I2C0		31
+
+#endif /* __DT_BINDINGS_CLOCK_R8A7790_H__ */
-- 
1.8.3.2

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

* [PATCH v3 4/8] ARM: shmobile: r8a7790: Add clock index macros for DT sources
@ 2013-11-19 14:45   ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

Add macros usable by device tree sources to reference r8a7790 clocks by
index.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 include/dt-bindings/clock/r8a7790-clock.h | 100 ++++++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)
 create mode 100644 include/dt-bindings/clock/r8a7790-clock.h

diff --git a/include/dt-bindings/clock/r8a7790-clock.h b/include/dt-bindings/clock/r8a7790-clock.h
new file mode 100644
index 0000000..420f0b0
--- /dev/null
+++ b/include/dt-bindings/clock/r8a7790-clock.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2013 Ideas On Board SPRL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_R8A7790_H__
+#define __DT_BINDINGS_CLOCK_R8A7790_H__
+
+/* CPG */
+#define R8A7790_CLK_MAIN		0
+#define R8A7790_CLK_PLL0		1
+#define R8A7790_CLK_PLL1		2
+#define R8A7790_CLK_PLL3		3
+#define R8A7790_CLK_LB			4
+#define R8A7790_CLK_QSPI		5
+#define R8A7790_CLK_SDH			6
+#define R8A7790_CLK_SD0			7
+#define R8A7790_CLK_SD1			8
+#define R8A7790_CLK_Z			9
+
+/* MSTP1 */
+#define R8A7790_CLK_TMU1		11
+#define R8A7790_CLK_TMU3		21
+#define R8A7790_CLK_TMU2		22
+#define R8A7790_CLK_CMT0		24
+#define R8A7790_CLK_TMU0		25
+#define R8A7790_CLK_VSP1_DU1		27
+#define R8A7790_CLK_VSP1_DU0		28
+#define R8A7790_CLK_VSP1_RT		30
+#define R8A7790_CLK_VSP1_SY		31
+
+/* MSTP2 */
+#define R8A7790_CLK_SCIFA2		2
+#define R8A7790_CLK_SCIFA1		3
+#define R8A7790_CLK_SCIFA0		4
+#define R8A7790_CLK_SCIFB0		6
+#define R8A7790_CLK_SCIFB1		7
+#define R8A7790_CLK_SCIFB2		16
+#define R8A7790_CLK_SYS_DMAC0		18
+#define R8A7790_CLK_SYS_DMAC1		19
+
+/* MSTP3 */
+#define R8A7790_CLK_TPU0		4
+#define R8A7790_CLK_MMCIF1		5
+#define R8A7790_CLK_SDHI3		11
+#define R8A7790_CLK_SDHI2		12
+#define R8A7790_CLK_SDHI1		13
+#define R8A7790_CLK_SDHI0		14
+#define R8A7790_CLK_MMCIF0		15
+#define R8A7790_CLK_SSUSB		28
+#define R8A7790_CLK_CMT1		29
+#define R8A7790_CLK_USBDMAC0		30
+#define R8A7790_CLK_USBDMAC1		31
+
+/* MSTP5 */
+#define R8A7790_CLK_THERMAL		22
+#define R8A7790_CLK_PWM			23
+
+/* MSTP7 */
+#define R8A7790_CLK_EHCI		3
+#define R8A7790_CLK_HSUSB		4
+#define R8A7790_CLK_HSCIF1		16
+#define R8A7790_CLK_HSCIF0		17
+#define R8A7790_CLK_SCIF1		20
+#define R8A7790_CLK_SCIF0		21
+#define R8A7790_CLK_DU2			22
+#define R8A7790_CLK_DU1			23
+#define R8A7790_CLK_DU0			24
+#define R8A7790_CLK_LVDS1		25
+#define R8A7790_CLK_LVDS0		26
+
+/* MSTP8 */
+#define R8A7790_CLK_VIN3		8
+#define R8A7790_CLK_VIN2		9
+#define R8A7790_CLK_VIN1		10
+#define R8A7790_CLK_VIN0		11
+#define R8A7790_CLK_ETHER		13
+#define R8A7790_CLK_SATA1		14
+#define R8A7790_CLK_SATA0		15
+
+/* MSTP9 */
+#define R8A7790_CLK_GPIO5		7
+#define R8A7790_CLK_GPIO4		8
+#define R8A7790_CLK_GPIO3		9
+#define R8A7790_CLK_GPIO2		10
+#define R8A7790_CLK_GPIO1		11
+#define R8A7790_CLK_GPIO0		12
+#define R8A7790_CLK_RCAN1		15
+#define R8A7790_CLK_RCAN0		16
+#define R8A7790_CLK_IICDVFS		26
+#define R8A7790_CLK_I2C3		28
+#define R8A7790_CLK_I2C2		29
+#define R8A7790_CLK_I2C1		30
+#define R8A7790_CLK_I2C0		31
+
+#endif /* __DT_BINDINGS_CLOCK_R8A7790_H__ */
-- 
1.8.3.2


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

* [PATCH v3 5/8] ARM: shmobile: r8a7791: Add clock index macros for DT sources
  2013-11-19 14:45 ` Laurent Pinchart
@ 2013-11-19 14:45   ` Laurent Pinchart
  -1 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

Add macros usable by device tree sources to reference r8a7791 clocks by
index.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 include/dt-bindings/clock/r8a7791-clock.h | 105 ++++++++++++++++++++++++++++++
 1 file changed, 105 insertions(+)
 create mode 100644 include/dt-bindings/clock/r8a7791-clock.h

diff --git a/include/dt-bindings/clock/r8a7791-clock.h b/include/dt-bindings/clock/r8a7791-clock.h
new file mode 100644
index 0000000..df1715b
--- /dev/null
+++ b/include/dt-bindings/clock/r8a7791-clock.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2013 Ideas On Board SPRL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_R8A7791_H__
+#define __DT_BINDINGS_CLOCK_R8A7791_H__
+
+/* CPG */
+#define R8A7791_CLK_MAIN		0
+#define R8A7791_CLK_PLL0		1
+#define R8A7791_CLK_PLL1		2
+#define R8A7791_CLK_PLL3		3
+#define R8A7791_CLK_LB			4
+#define R8A7791_CLK_QSPI		5
+#define R8A7791_CLK_SDH			6
+#define R8A7791_CLK_SD0			7
+#define R8A7791_CLK_Z			8
+
+/* MSTP1 */
+#define R8A7791_CLK_TMU1		11
+#define R8A7791_CLK_TMU3		21
+#define R8A7791_CLK_TMU2		22
+#define R8A7791_CLK_CMT0		24
+#define R8A7791_CLK_TMU0		25
+#define R8A7791_CLK_VSP1_DU1		27
+#define R8A7791_CLK_VSP1_DU0		28
+#define R8A7791_CLK_VSP1_SY		31
+
+/* MSTP2 */
+#define R8A7791_CLK_SCIFA2		2
+#define R8A7791_CLK_SCIFA1		3
+#define R8A7791_CLK_SCIFA0		4
+#define R8A7791_CLK_SCIFB0		6
+#define R8A7791_CLK_SCIFB1		7
+#define R8A7791_CLK_SCIFB2		16
+#define R8A7791_CLK_DMAC		18
+
+/* MSTP3 */
+#define R8A7791_CLK_TPU0		4
+#define R8A7791_CLK_SDHI2		11
+#define R8A7791_CLK_SDHI1		12
+#define R8A7791_CLK_SDHI0		14
+#define R8A7791_CLK_MMCIF0		15
+#define R8A7791_CLK_SSUSB		28
+#define R8A7791_CLK_CMT1		29
+#define R8A7791_CLK_USBDMAC0		30
+#define R8A7791_CLK_USBDMAC1		31
+
+/* MSTP5 */
+#define R8A7791_CLK_THERMAL		22
+#define R8A7791_CLK_PWM			23
+
+/* MSTP7 */
+#define R8A7791_CLK_HSUSB		4
+#define R8A7791_CLK_HSCIF2		13
+#define R8A7791_CLK_SCIF5		14
+#define R8A7791_CLK_SCIF4		15
+#define R8A7791_CLK_HSCIF1		16
+#define R8A7791_CLK_HSCIF0		17
+#define R8A7791_CLK_SCIF3		18
+#define R8A7791_CLK_SCIF2		19
+#define R8A7791_CLK_SCIF1		20
+#define R8A7791_CLK_SCIF0		21
+#define R8A7791_CLK_DU1			23
+#define R8A7791_CLK_DU0			24
+#define R8A7791_CLK_LVDS0		26
+
+/* MSTP8 */
+#define R8A7791_CLK_VIN2		9
+#define R8A7791_CLK_VIN1		10
+#define R8A7791_CLK_VIN0		11
+#define R8A7791_CLK_ETHER		13
+#define R8A7791_CLK_SATA1		14
+#define R8A7791_CLK_SATA0		15
+
+/* MSTP9 */
+#define R8A7791_CLK_GPIO7		4
+#define R8A7791_CLK_GPIO6		5
+#define R8A7791_CLK_GPIO5		7
+#define R8A7791_CLK_GPIO4		8
+#define R8A7791_CLK_GPIO3		9
+#define R8A7791_CLK_GPIO2		10
+#define R8A7791_CLK_GPIO1		11
+#define R8A7791_CLK_GPIO0		12
+#define R8A7791_CLK_RCAN1		15
+#define R8A7791_CLK_RCAN0		16
+#define R8A7791_CLK_I2C5		25
+#define R8A7791_CLK_IICDVFS		26
+#define R8A7791_CLK_I2C4		27
+#define R8A7791_CLK_I2C3		28
+#define R8A7791_CLK_I2C2		29
+#define R8A7791_CLK_I2C1		30
+#define R8A7791_CLK_I2C0		31
+
+/* MSTP11 */
+#define R8A7791_CLK_SCIFA3		6
+#define R8A7791_CLK_SCIFA4		7
+#define R8A7791_CLK_SCIFA5		8
+
+#endif /* __DT_BINDINGS_CLOCK_R8A7791_H__ */
-- 
1.8.3.2

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

* [PATCH v3 5/8] ARM: shmobile: r8a7791: Add clock index macros for DT sources
@ 2013-11-19 14:45   ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

Add macros usable by device tree sources to reference r8a7791 clocks by
index.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 include/dt-bindings/clock/r8a7791-clock.h | 105 ++++++++++++++++++++++++++++++
 1 file changed, 105 insertions(+)
 create mode 100644 include/dt-bindings/clock/r8a7791-clock.h

diff --git a/include/dt-bindings/clock/r8a7791-clock.h b/include/dt-bindings/clock/r8a7791-clock.h
new file mode 100644
index 0000000..df1715b
--- /dev/null
+++ b/include/dt-bindings/clock/r8a7791-clock.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2013 Ideas On Board SPRL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_R8A7791_H__
+#define __DT_BINDINGS_CLOCK_R8A7791_H__
+
+/* CPG */
+#define R8A7791_CLK_MAIN		0
+#define R8A7791_CLK_PLL0		1
+#define R8A7791_CLK_PLL1		2
+#define R8A7791_CLK_PLL3		3
+#define R8A7791_CLK_LB			4
+#define R8A7791_CLK_QSPI		5
+#define R8A7791_CLK_SDH			6
+#define R8A7791_CLK_SD0			7
+#define R8A7791_CLK_Z			8
+
+/* MSTP1 */
+#define R8A7791_CLK_TMU1		11
+#define R8A7791_CLK_TMU3		21
+#define R8A7791_CLK_TMU2		22
+#define R8A7791_CLK_CMT0		24
+#define R8A7791_CLK_TMU0		25
+#define R8A7791_CLK_VSP1_DU1		27
+#define R8A7791_CLK_VSP1_DU0		28
+#define R8A7791_CLK_VSP1_SY		31
+
+/* MSTP2 */
+#define R8A7791_CLK_SCIFA2		2
+#define R8A7791_CLK_SCIFA1		3
+#define R8A7791_CLK_SCIFA0		4
+#define R8A7791_CLK_SCIFB0		6
+#define R8A7791_CLK_SCIFB1		7
+#define R8A7791_CLK_SCIFB2		16
+#define R8A7791_CLK_DMAC		18
+
+/* MSTP3 */
+#define R8A7791_CLK_TPU0		4
+#define R8A7791_CLK_SDHI2		11
+#define R8A7791_CLK_SDHI1		12
+#define R8A7791_CLK_SDHI0		14
+#define R8A7791_CLK_MMCIF0		15
+#define R8A7791_CLK_SSUSB		28
+#define R8A7791_CLK_CMT1		29
+#define R8A7791_CLK_USBDMAC0		30
+#define R8A7791_CLK_USBDMAC1		31
+
+/* MSTP5 */
+#define R8A7791_CLK_THERMAL		22
+#define R8A7791_CLK_PWM			23
+
+/* MSTP7 */
+#define R8A7791_CLK_HSUSB		4
+#define R8A7791_CLK_HSCIF2		13
+#define R8A7791_CLK_SCIF5		14
+#define R8A7791_CLK_SCIF4		15
+#define R8A7791_CLK_HSCIF1		16
+#define R8A7791_CLK_HSCIF0		17
+#define R8A7791_CLK_SCIF3		18
+#define R8A7791_CLK_SCIF2		19
+#define R8A7791_CLK_SCIF1		20
+#define R8A7791_CLK_SCIF0		21
+#define R8A7791_CLK_DU1			23
+#define R8A7791_CLK_DU0			24
+#define R8A7791_CLK_LVDS0		26
+
+/* MSTP8 */
+#define R8A7791_CLK_VIN2		9
+#define R8A7791_CLK_VIN1		10
+#define R8A7791_CLK_VIN0		11
+#define R8A7791_CLK_ETHER		13
+#define R8A7791_CLK_SATA1		14
+#define R8A7791_CLK_SATA0		15
+
+/* MSTP9 */
+#define R8A7791_CLK_GPIO7		4
+#define R8A7791_CLK_GPIO6		5
+#define R8A7791_CLK_GPIO5		7
+#define R8A7791_CLK_GPIO4		8
+#define R8A7791_CLK_GPIO3		9
+#define R8A7791_CLK_GPIO2		10
+#define R8A7791_CLK_GPIO1		11
+#define R8A7791_CLK_GPIO0		12
+#define R8A7791_CLK_RCAN1		15
+#define R8A7791_CLK_RCAN0		16
+#define R8A7791_CLK_I2C5		25
+#define R8A7791_CLK_IICDVFS		26
+#define R8A7791_CLK_I2C4		27
+#define R8A7791_CLK_I2C3		28
+#define R8A7791_CLK_I2C2		29
+#define R8A7791_CLK_I2C1		30
+#define R8A7791_CLK_I2C0		31
+
+/* MSTP11 */
+#define R8A7791_CLK_SCIFA3		6
+#define R8A7791_CLK_SCIFA4		7
+#define R8A7791_CLK_SCIFA5		8
+
+#endif /* __DT_BINDINGS_CLOCK_R8A7791_H__ */
-- 
1.8.3.2


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

* [PATCH v3 6/8] ARM: shmobile: r8a7790: Add clocks
  2013-11-19 14:45 ` Laurent Pinchart
@ 2013-11-19 14:45   ` Laurent Pinchart
  -1 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

Declare all core clocks and DIV6 clocks, as well as all MSTP clocks
currently used by r8a7790 boards.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7790.dtsi | 316 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 316 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index 3800952..e3c6072 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -8,6 +8,7 @@
  * kind, whether express or implied.
  */
 
+#include <dt-bindings/clock/r8a7790-clock.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 
@@ -280,4 +281,319 @@
 		cap-sd-highspeed;
 		status = "disabled";
 	};
+
+	clocks {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* External root clock */
+		extal_clk: extal_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			/* This value must be overriden by the board. */
+			clock-frequency = <0>;
+			clock-output-names = "extal";
+		};
+
+		/* Special CPG clocks */
+		cpg_clocks: cpg_clocks at e6150000 {
+			compatible = "renesas,r8a7790-cpg-clocks",
+				     "renesas,rcar-gen2-cpg-clocks";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>;
+			#clock-cells = <1>;
+			clock-output-names = "main", "pll0", "pll1", "pll3",
+					     "lb", "qspi", "sdh", "sd0", "sd1",
+					     "z";
+		};
+
+		/* Variable factor clocks */
+		sd2_clk: sd2_clk at e6150078 {
+			compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe6150078 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "sd2";
+		};
+		sd3_clk: sd3_clk at e615007c {
+			compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe615007c 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "sd3";
+		};
+		mmc0_clk: mmc0_clk at e6150240 {
+			compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe6150240 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "mmc0";
+		};
+		mmc1_clk: mmc1_clk at e6150244 {
+			compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe6150244 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "mmc1";
+		};
+		ssp_clk: ssp_clk at e6150248 {
+			compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe6150248 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "ssp";
+		};
+		ssprs_clk: ssprs_clk at e615024c {
+			compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe615024c 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "ssprs";
+		};
+
+		/* Fixed factor clocks */
+		pll1_div2_clk: pll1_div2_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <2>;
+			clock-mult = <1>;
+			clock-output-names = "pll1_div2";
+		};
+		z2_clk: z2_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <2>;
+			clock-mult = <1>;
+			clock-output-names = "z2";
+		};
+		zg_clk: zg_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <3>;
+			clock-mult = <1>;
+			clock-output-names = "zg";
+		};
+		zx_clk: zx_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <3>;
+			clock-mult = <1>;
+			clock-output-names = "zx";
+		};
+		zs_clk: zs_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <6>;
+			clock-mult = <1>;
+			clock-output-names = "zs";
+		};
+		hp_clk: hp_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <12>;
+			clock-mult = <1>;
+			clock-output-names = "hp";
+		};
+		i_clk: i_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <2>;
+			clock-mult = <1>;
+			clock-output-names = "i";
+		};
+		b_clk: b_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <12>;
+			clock-mult = <1>;
+			clock-output-names = "b";
+		};
+		p_clk: p_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <24>;
+			clock-mult = <1>;
+			clock-output-names = "p";
+		};
+		cl_clk: cl_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <48>;
+			clock-mult = <1>;
+			clock-output-names = "cl";
+		};
+		m2_clk: m2_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <8>;
+			clock-mult = <1>;
+			clock-output-names = "m2";
+		};
+		imp_clk: imp_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <4>;
+			clock-mult = <1>;
+			clock-output-names = "imp";
+		};
+		rclk_clk: rclk_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <(48 * 1024)>;
+			clock-mult = <1>;
+			clock-output-names = "rclk";
+		};
+		oscclk_clk: oscclk_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <(12 * 1024)>;
+			clock-mult = <1>;
+			clock-output-names = "oscclk";
+		};
+		zb3_clk: zb3_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL3>;
+			#clock-cells = <0>;
+			clock-div = <4>;
+			clock-mult = <1>;
+			clock-output-names = "zb3";
+		};
+		zb3d2_clk: zb3d2_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL3>;
+			#clock-cells = <0>;
+			clock-div = <8>;
+			clock-mult = <1>;
+			clock-output-names = "zb3d2";
+		};
+		ddr_clk: ddr_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL3>;
+			#clock-cells = <0>;
+			clock-div = <8>;
+			clock-mult = <1>;
+			clock-output-names = "ddr";
+		};
+		mp_clk: mp_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-div = <15>;
+			clock-mult = <1>;
+			clock-output-names = "mp";
+		};
+		cp_clk: cp_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&extal_clk>;
+			#clock-cells = <0>;
+			clock-div = <2>;
+			clock-mult = <1>;
+			clock-output-names = "cp";
+		};
+
+		/* Gate clocks */
+		mstp1_clks: mstp1_clks at e6150134 {
+			compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>;
+			clocks = <&p_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>,
+				 <&cp_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>,
+				 <&zs_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7790_CLK_TMU1 R8A7790_CLK_TMU3 R8A7790_CLK_TMU2
+				R8A7790_CLK_CMT0 R8A7790_CLK_TMU0 R8A7790_CLK_VSP1_DU1
+				R8A7790_CLK_VSP1_DU0 R8A7790_CLK_VSP1_RT R8A7790_CLK_VSP1_SY
+			>;
+			clock-output-names =
+				"tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1",
+				"vsp1-du0", "vsp1-rt", "vsp1-sy";
+		};
+		mstp2_clks: mstp2_clks at e6150138 {
+			compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
+			clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>,
+				 <&mp_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7790_CLK_SCIFA2 R8A7790_CLK_SCIFA1 R8A7790_CLK_SCIFA0
+				R8A7790_CLK_SCIFB0 R8A7790_CLK_SCIFB1 R8A7790_CLK_SCIFB2
+			>;
+			clock-output-names =
+				"scifa2", "scifa1", "scifa0", "scifb0", "scifb1",
+				"scifb2";
+		};
+		mstp3_clks: mstp3_clks at e615013c {
+			compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
+			clocks = <&cp_clk>, <&mmc1_clk>, <&sd3_clk>, <&sd2_clk>,
+				 <&cpg_clocks R8A7790_CLK_SD1>, <&cpg_clocks R8A7790_CLK_SD0>,
+				 <&mmc0_clk>, <&rclk_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7790_CLK_TPU0 R8A7790_CLK_MMCIF1 R8A7790_CLK_SDHI3
+				R8A7790_CLK_SDHI2 R8A7790_CLK_SDHI1 R8A7790_CLK_SDHI0
+				R8A7790_CLK_MMCIF0 R8A7790_CLK_CMT1
+			>;
+			clock-output-names =
+				"tpu0", "mmcif1", "sdhi3", "sdhi2",
+				"sdhi1", "sdhi0", "mmcif0", "cmt1";
+		};
+		mstp5_clks: mstp5_clks at e6150144 {
+			compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>;
+			clocks = <&extal_clk>, <&p_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <R8A7790_CLK_THERMAL R8A7790_CLK_PWM>;
+			clock-output-names = "thermal", "pwm";
+		};
+		mstp7_clks: mstp7_clks at e615014c {
+			compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe615014c 0 4>, <0 0xe61501c4 0 4>;
+			clocks = <&zs_clk>, <&zs_clk>, <&p_clk>, <&p_clk>, <&zx_clk>,
+				 <&zx_clk>, <&zx_clk>, <&zx_clk>, <&zx_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7790_CLK_HSCIF1 R8A7790_CLK_HSCIF0 R8A7790_CLK_SCIF1
+				R8A7790_CLK_SCIF0 R8A7790_CLK_DU2 R8A7790_CLK_DU1
+				R8A7790_CLK_DU0 R8A7790_CLK_LVDS1 R8A7790_CLK_LVDS0
+			>;
+			clock-output-names =
+				"hscif1", "hscif0", "scif1", "scif0", "du2", "du1",
+				"du0", "lvds1", "lvds0";
+		};
+		mstp8_clks: mstp8_clks at e6150990 {
+			compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>;
+			clocks = <&p_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <R8A7790_CLK_ETHER>;
+			clock-output-names = "ether";
+		};
+		mstp9_clks: mstp9_clks at e6150994 {
+			compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>;
+			clocks = <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7790_CLK_RCAN1 R8A7790_CLK_RCAN0 R8A7790_CLK_I2C3
+				R8A7790_CLK_I2C2 R8A7790_CLK_I2C1 R8A7790_CLK_I2C0
+			>;
+			clock-output-names = "rcan1", "rcan0", "i2c3", "i2c2", "i2c1", "i2c0";
+		};
+	};
 };
-- 
1.8.3.2

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

* [PATCH v3 6/8] ARM: shmobile: r8a7790: Add clocks
@ 2013-11-19 14:45   ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

Declare all core clocks and DIV6 clocks, as well as all MSTP clocks
currently used by r8a7790 boards.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7790.dtsi | 316 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 316 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index 3800952..e3c6072 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -8,6 +8,7 @@
  * kind, whether express or implied.
  */
 
+#include <dt-bindings/clock/r8a7790-clock.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 
@@ -280,4 +281,319 @@
 		cap-sd-highspeed;
 		status = "disabled";
 	};
+
+	clocks {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* External root clock */
+		extal_clk: extal_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			/* This value must be overriden by the board. */
+			clock-frequency = <0>;
+			clock-output-names = "extal";
+		};
+
+		/* Special CPG clocks */
+		cpg_clocks: cpg_clocks@e6150000 {
+			compatible = "renesas,r8a7790-cpg-clocks",
+				     "renesas,rcar-gen2-cpg-clocks";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>;
+			#clock-cells = <1>;
+			clock-output-names = "main", "pll0", "pll1", "pll3",
+					     "lb", "qspi", "sdh", "sd0", "sd1",
+					     "z";
+		};
+
+		/* Variable factor clocks */
+		sd2_clk: sd2_clk@e6150078 {
+			compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe6150078 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "sd2";
+		};
+		sd3_clk: sd3_clk@e615007c {
+			compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe615007c 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "sd3";
+		};
+		mmc0_clk: mmc0_clk@e6150240 {
+			compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe6150240 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "mmc0";
+		};
+		mmc1_clk: mmc1_clk@e6150244 {
+			compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe6150244 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "mmc1";
+		};
+		ssp_clk: ssp_clk@e6150248 {
+			compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe6150248 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "ssp";
+		};
+		ssprs_clk: ssprs_clk@e615024c {
+			compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe615024c 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "ssprs";
+		};
+
+		/* Fixed factor clocks */
+		pll1_div2_clk: pll1_div2_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <2>;
+			clock-mult = <1>;
+			clock-output-names = "pll1_div2";
+		};
+		z2_clk: z2_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <2>;
+			clock-mult = <1>;
+			clock-output-names = "z2";
+		};
+		zg_clk: zg_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <3>;
+			clock-mult = <1>;
+			clock-output-names = "zg";
+		};
+		zx_clk: zx_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <3>;
+			clock-mult = <1>;
+			clock-output-names = "zx";
+		};
+		zs_clk: zs_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <6>;
+			clock-mult = <1>;
+			clock-output-names = "zs";
+		};
+		hp_clk: hp_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <12>;
+			clock-mult = <1>;
+			clock-output-names = "hp";
+		};
+		i_clk: i_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <2>;
+			clock-mult = <1>;
+			clock-output-names = "i";
+		};
+		b_clk: b_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <12>;
+			clock-mult = <1>;
+			clock-output-names = "b";
+		};
+		p_clk: p_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <24>;
+			clock-mult = <1>;
+			clock-output-names = "p";
+		};
+		cl_clk: cl_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <48>;
+			clock-mult = <1>;
+			clock-output-names = "cl";
+		};
+		m2_clk: m2_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <8>;
+			clock-mult = <1>;
+			clock-output-names = "m2";
+		};
+		imp_clk: imp_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <4>;
+			clock-mult = <1>;
+			clock-output-names = "imp";
+		};
+		rclk_clk: rclk_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <(48 * 1024)>;
+			clock-mult = <1>;
+			clock-output-names = "rclk";
+		};
+		oscclk_clk: oscclk_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <(12 * 1024)>;
+			clock-mult = <1>;
+			clock-output-names = "oscclk";
+		};
+		zb3_clk: zb3_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL3>;
+			#clock-cells = <0>;
+			clock-div = <4>;
+			clock-mult = <1>;
+			clock-output-names = "zb3";
+		};
+		zb3d2_clk: zb3d2_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL3>;
+			#clock-cells = <0>;
+			clock-div = <8>;
+			clock-mult = <1>;
+			clock-output-names = "zb3d2";
+		};
+		ddr_clk: ddr_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7790_CLK_PLL3>;
+			#clock-cells = <0>;
+			clock-div = <8>;
+			clock-mult = <1>;
+			clock-output-names = "ddr";
+		};
+		mp_clk: mp_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-div = <15>;
+			clock-mult = <1>;
+			clock-output-names = "mp";
+		};
+		cp_clk: cp_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&extal_clk>;
+			#clock-cells = <0>;
+			clock-div = <2>;
+			clock-mult = <1>;
+			clock-output-names = "cp";
+		};
+
+		/* Gate clocks */
+		mstp1_clks: mstp1_clks@e6150134 {
+			compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>;
+			clocks = <&p_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>,
+				 <&cp_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>,
+				 <&zs_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7790_CLK_TMU1 R8A7790_CLK_TMU3 R8A7790_CLK_TMU2
+				R8A7790_CLK_CMT0 R8A7790_CLK_TMU0 R8A7790_CLK_VSP1_DU1
+				R8A7790_CLK_VSP1_DU0 R8A7790_CLK_VSP1_RT R8A7790_CLK_VSP1_SY
+			>;
+			clock-output-names +				"tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1",
+				"vsp1-du0", "vsp1-rt", "vsp1-sy";
+		};
+		mstp2_clks: mstp2_clks@e6150138 {
+			compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
+			clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>,
+				 <&mp_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7790_CLK_SCIFA2 R8A7790_CLK_SCIFA1 R8A7790_CLK_SCIFA0
+				R8A7790_CLK_SCIFB0 R8A7790_CLK_SCIFB1 R8A7790_CLK_SCIFB2
+			>;
+			clock-output-names +				"scifa2", "scifa1", "scifa0", "scifb0", "scifb1",
+				"scifb2";
+		};
+		mstp3_clks: mstp3_clks@e615013c {
+			compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
+			clocks = <&cp_clk>, <&mmc1_clk>, <&sd3_clk>, <&sd2_clk>,
+				 <&cpg_clocks R8A7790_CLK_SD1>, <&cpg_clocks R8A7790_CLK_SD0>,
+				 <&mmc0_clk>, <&rclk_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7790_CLK_TPU0 R8A7790_CLK_MMCIF1 R8A7790_CLK_SDHI3
+				R8A7790_CLK_SDHI2 R8A7790_CLK_SDHI1 R8A7790_CLK_SDHI0
+				R8A7790_CLK_MMCIF0 R8A7790_CLK_CMT1
+			>;
+			clock-output-names +				"tpu0", "mmcif1", "sdhi3", "sdhi2",
+				"sdhi1", "sdhi0", "mmcif0", "cmt1";
+		};
+		mstp5_clks: mstp5_clks@e6150144 {
+			compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>;
+			clocks = <&extal_clk>, <&p_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <R8A7790_CLK_THERMAL R8A7790_CLK_PWM>;
+			clock-output-names = "thermal", "pwm";
+		};
+		mstp7_clks: mstp7_clks@e615014c {
+			compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe615014c 0 4>, <0 0xe61501c4 0 4>;
+			clocks = <&zs_clk>, <&zs_clk>, <&p_clk>, <&p_clk>, <&zx_clk>,
+				 <&zx_clk>, <&zx_clk>, <&zx_clk>, <&zx_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7790_CLK_HSCIF1 R8A7790_CLK_HSCIF0 R8A7790_CLK_SCIF1
+				R8A7790_CLK_SCIF0 R8A7790_CLK_DU2 R8A7790_CLK_DU1
+				R8A7790_CLK_DU0 R8A7790_CLK_LVDS1 R8A7790_CLK_LVDS0
+			>;
+			clock-output-names +				"hscif1", "hscif0", "scif1", "scif0", "du2", "du1",
+				"du0", "lvds1", "lvds0";
+		};
+		mstp8_clks: mstp8_clks@e6150990 {
+			compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>;
+			clocks = <&p_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <R8A7790_CLK_ETHER>;
+			clock-output-names = "ether";
+		};
+		mstp9_clks: mstp9_clks@e6150994 {
+			compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>;
+			clocks = <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7790_CLK_RCAN1 R8A7790_CLK_RCAN0 R8A7790_CLK_I2C3
+				R8A7790_CLK_I2C2 R8A7790_CLK_I2C1 R8A7790_CLK_I2C0
+			>;
+			clock-output-names = "rcan1", "rcan0", "i2c3", "i2c2", "i2c1", "i2c0";
+		};
+	};
 };
-- 
1.8.3.2


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

* [PATCH v3 7/8] ARM: shmobile: r8a7790: Reference clocks
  2013-11-19 14:45 ` Laurent Pinchart
@ 2013-11-19 14:45   ` Laurent Pinchart
  -1 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

Reference clocks using a "clocks" property in all nodes corresponding to
devices that require a clock.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7790.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index e3c6072..fe65a68 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -190,6 +190,7 @@
 		reg = <0 0xe6508000 0 0x40>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_I2C0>;
 		status = "disabled";
 	};
 
@@ -200,6 +201,7 @@
 		reg = <0 0xe6518000 0 0x40>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_I2C1>;
 		status = "disabled";
 	};
 
@@ -210,6 +212,7 @@
 		reg = <0 0xe6530000 0 0x40>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_I2C2>;
 		status = "disabled";
 	};
 
@@ -220,6 +223,7 @@
 		reg = <0 0xe6540000 0 0x40>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_I2C3>;
 		status = "disabled";
 	};
 
@@ -228,6 +232,7 @@
 		reg = <0 0xee200000 0 0x80>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_MMCIF0>;
 		reg-io-width = <4>;
 		status = "disabled";
 	};
@@ -237,6 +242,7 @@
 		reg = <0 0xee220000 0 0x80>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_MMCIF1>;
 		reg-io-width = <4>;
 		status = "disabled";
 	};
@@ -251,6 +257,7 @@
 		reg = <0 0xee100000 0 0x100>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_SDHI0>;
 		cap-sd-highspeed;
 		status = "disabled";
 	};
@@ -260,6 +267,7 @@
 		reg = <0 0xee120000 0 0x100>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_SDHI1>;
 		cap-sd-highspeed;
 		status = "disabled";
 	};
@@ -269,6 +277,7 @@
 		reg = <0 0xee140000 0 0x100>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_SDHI2>;
 		cap-sd-highspeed;
 		status = "disabled";
 	};
@@ -278,6 +287,7 @@
 		reg = <0 0xee160000 0 0x100>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_SDHI3>;
 		cap-sd-highspeed;
 		status = "disabled";
 	};
-- 
1.8.3.2

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

* [PATCH v3 7/8] ARM: shmobile: r8a7790: Reference clocks
@ 2013-11-19 14:45   ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

Reference clocks using a "clocks" property in all nodes corresponding to
devices that require a clock.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7790.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index e3c6072..fe65a68 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -190,6 +190,7 @@
 		reg = <0 0xe6508000 0 0x40>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_I2C0>;
 		status = "disabled";
 	};
 
@@ -200,6 +201,7 @@
 		reg = <0 0xe6518000 0 0x40>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_I2C1>;
 		status = "disabled";
 	};
 
@@ -210,6 +212,7 @@
 		reg = <0 0xe6530000 0 0x40>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_I2C2>;
 		status = "disabled";
 	};
 
@@ -220,6 +223,7 @@
 		reg = <0 0xe6540000 0 0x40>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_I2C3>;
 		status = "disabled";
 	};
 
@@ -228,6 +232,7 @@
 		reg = <0 0xee200000 0 0x80>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_MMCIF0>;
 		reg-io-width = <4>;
 		status = "disabled";
 	};
@@ -237,6 +242,7 @@
 		reg = <0 0xee220000 0 0x80>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_MMCIF1>;
 		reg-io-width = <4>;
 		status = "disabled";
 	};
@@ -251,6 +257,7 @@
 		reg = <0 0xee100000 0 0x100>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_SDHI0>;
 		cap-sd-highspeed;
 		status = "disabled";
 	};
@@ -260,6 +267,7 @@
 		reg = <0 0xee120000 0 0x100>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_SDHI1>;
 		cap-sd-highspeed;
 		status = "disabled";
 	};
@@ -269,6 +277,7 @@
 		reg = <0 0xee140000 0 0x100>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_SDHI2>;
 		cap-sd-highspeed;
 		status = "disabled";
 	};
@@ -278,6 +287,7 @@
 		reg = <0 0xee160000 0 0x100>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7790_CLK_SDHI3>;
 		cap-sd-highspeed;
 		status = "disabled";
 	};
-- 
1.8.3.2


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

* [PATCH v3 8/8] ARM: shmobile: r8a7791: Add clocks
  2013-11-19 14:45 ` Laurent Pinchart
@ 2013-11-19 14:45   ` Laurent Pinchart
  -1 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

Declare all core clocks and DIV6 clocks, as well as all MSTP clocks
currently used by r8a7791 boards.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7791.dtsi | 312 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 312 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index 86d5d3a..5c8933e 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -9,6 +9,7 @@
  * kind, whether express or implied.
  */
 
+#include <dt-bindings/clock/r8a7791-clock.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 
@@ -176,4 +177,315 @@
 		reg = <0 0xe6060000 0 0x250>;
 		#gpio-range-cells = <3>;
 	};
+
+	clocks {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* External root clock */
+		extal_clk: extal_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			/* This value must be overriden by the board. */
+			clock-frequency = <0>;
+			clock-output-names = "extal";
+		};
+
+		/* Special CPG clocks */
+		cpg_clocks: cpg_clocks at e6150000 {
+			compatible = "renesas,r8a7791-cpg-clocks",
+				     "renesas,rcar-gen2-cpg-clocks";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>;
+			#clock-cells = <1>;
+			clock-output-names = "main", "pll0", "pll1", "pll3",
+					     "lb", "qspi", "sdh", "sd0", "z";
+		};
+
+		/* Variable factor clocks */
+		sd1_clk: sd2_clk at e6150078 {
+			compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe6150078 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "sd1";
+		};
+		sd2_clk: sd3_clk at e615007c {
+			compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe615007c 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "sd2";
+		};
+		mmc0_clk: mmc0_clk at e6150240 {
+			compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe6150240 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "mmc0";
+		};
+		ssp_clk: ssp_clk at e6150248 {
+			compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe6150248 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "ssp";
+		};
+		ssprs_clk: ssprs_clk at e615024c {
+			compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe615024c 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "ssprs";
+		};
+
+		/* Fixed factor clocks */
+		pll1_div2_clk: pll1_div2_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <2>;
+			clock-mult = <1>;
+			clock-output-names = "pll1_div2";
+		};
+		zg_clk: zg_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <3>;
+			clock-mult = <1>;
+			clock-output-names = "zg";
+		};
+		zx_clk: zx_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <3>;
+			clock-mult = <1>;
+			clock-output-names = "zx";
+		};
+		zs_clk: zs_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <6>;
+			clock-mult = <1>;
+			clock-output-names = "zs";
+		};
+		hp_clk: hp_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <12>;
+			clock-mult = <1>;
+			clock-output-names = "hp";
+		};
+		i_clk: i_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <2>;
+			clock-mult = <1>;
+			clock-output-names = "i";
+		};
+		b_clk: b_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <12>;
+			clock-mult = <1>;
+			clock-output-names = "b";
+		};
+		p_clk: p_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <24>;
+			clock-mult = <1>;
+			clock-output-names = "p";
+		};
+		cl_clk: cl_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <48>;
+			clock-mult = <1>;
+			clock-output-names = "cl";
+		};
+		m2_clk: m2_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <8>;
+			clock-mult = <1>;
+			clock-output-names = "m2";
+		};
+		imp_clk: imp_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <4>;
+			clock-mult = <1>;
+			clock-output-names = "imp";
+		};
+		rclk_clk: rclk_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <(48 * 1024)>;
+			clock-mult = <1>;
+			clock-output-names = "rclk";
+		};
+		oscclk_clk: oscclk_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <(12 * 1024)>;
+			clock-mult = <1>;
+			clock-output-names = "oscclk";
+		};
+		zb3_clk: zb3_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL3>;
+			#clock-cells = <0>;
+			clock-div = <4>;
+			clock-mult = <1>;
+			clock-output-names = "zb3";
+		};
+		zb3d2_clk: zb3d2_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL3>;
+			#clock-cells = <0>;
+			clock-div = <8>;
+			clock-mult = <1>;
+			clock-output-names = "zb3d2";
+		};
+		ddr_clk: ddr_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL3>;
+			#clock-cells = <0>;
+			clock-div = <8>;
+			clock-mult = <1>;
+			clock-output-names = "ddr";
+		};
+		mp_clk: mp_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-div = <15>;
+			clock-mult = <1>;
+			clock-output-names = "mp";
+		};
+		cp_clk: cp_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&extal_clk>;
+			#clock-cells = <0>;
+			clock-div = <2>;
+			clock-mult = <1>;
+			clock-output-names = "cp";
+		};
+
+		/* Gate clocks */
+		mstp1_clks: mstp1_clks at e6150134 {
+			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>;
+			clocks = <&p_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>,
+				 <&cp_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7791_CLK_TMU1 R8A7791_CLK_TMU3 R8A7791_CLK_TMU2
+				R8A7791_CLK_CMT0 R8A7791_CLK_TMU0 R8A7791_CLK_VSP1_DU1
+				R8A7791_CLK_VSP1_DU0 R8A7791_CLK_VSP1_SY
+			>;
+			clock-output-names =
+				"tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1",
+				"vsp1-du0", "vsp1-sy";
+		};
+		mstp2_clks: mstp2_clks at e6150138 {
+			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
+			clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>,
+				 <&mp_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7791_CLK_SCIFA2 R8A7791_CLK_SCIFA1 R8A7791_CLK_SCIFA0
+				R8A7791_CLK_SCIFB0 R8A7791_CLK_SCIFB1 R8A7791_CLK_SCIFB2
+			>;
+			clock-output-names =
+				"scifa2", "scifa1", "scifa0", "scifb0", "scifb1",
+				"scifb2";
+		};
+		mstp3_clks: mstp3_clks at e615013c {
+			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
+			clocks = <&cp_clk>, <&sd2_clk>, <&sd1_clk>,
+				<&cpg_clocks R8A7791_CLK_SD0>, <&mmc0_clk>, <&rclk_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7791_CLK_TPU0 R8A7791_CLK_SDHI2 R8A7791_CLK_SDHI1
+				R8A7791_CLK_SDHI0 R8A7791_CLK_MMCIF0 R8A7791_CLK_CMT1
+			>;
+			clock-output-names =
+				"tpu0", "sdhi2", "sdhi1", "sdhi0", "mmcif0", "cmt1";
+		};
+		mstp5_clks: mstp5_clks at e6150144 {
+			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>;
+			clocks = <&extal_clk>, <&p_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <R8A7791_CLK_THERMAL R8A7791_CLK_PWM>;
+			clock-output-names = "thermal", "pwm";
+		};
+		mstp7_clks: mstp7_clks at e615014c {
+			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe615014c 0 4>, <0 0xe61501c4 0 4>;
+			clocks = <&zs_clk>, <&p_clk>, <&p_clk>, <&zs_clk>, <&zs_clk>,
+				 <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&zx_clk>,
+				 <&zx_clk>, <&zx_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7791_CLK_HSCIF2 R8A7791_CLK_SCIF5 R8A7791_CLK_SCIF4
+				R8A7791_CLK_HSCIF1 R8A7791_CLK_HSCIF0 R8A7791_CLK_SCIF3
+				R8A7791_CLK_SCIF2 R8A7791_CLK_SCIF1 R8A7791_CLK_SCIF0
+				R8A7791_CLK_DU1 R8A7791_CLK_DU0 R8A7791_CLK_LVDS0
+			>;
+			clock-output-names =
+				"hscif2", "scif5", "scif4", "hscif1", "hscif0", "scif3",
+				"scif2", "scif1", "scif0", "du1", "du0", "lvds0";
+		};
+		mstp8_clks: mstp8_clks at e6150990 {
+			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>;
+			clocks = <&p_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <R8A7791_CLK_ETHER>;
+			clock-output-names = "ether";
+		};
+		mstp9_clks: mstp9_clks at e6150994 {
+			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>;
+			clocks = <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
+				 <&p_clk>, <&p_clk>, <&p_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7791_CLK_RCAN1 R8A7791_CLK_RCAN0 R8A7791_CLK_I2C4
+				R8A7791_CLK_I2C4 R8A7791_CLK_I2C3 R8A7791_CLK_I2C2
+				R8A7791_CLK_I2C1 R8A7791_CLK_I2C0
+			>;
+			clock-output-names =
+				"rcan1", "rcan0", "i2c5", "i2c4", "i2c3", "i2c2", "i2c1",
+				"i2c0";
+		};
+		mstp11_clks: mstp11_clks at e615099c {
+			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe615099c 0 4>, <0 0xe61509ac 0 4>;
+			clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7791_CLK_SCIFA3 R8A7791_CLK_SCIFA4 R8A7791_CLK_SCIFA5
+			>;
+			clock-output-names = "scifa3", "scifa4", "scifa5";
+		};
+	};
 };
-- 
1.8.3.2

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

* [PATCH v3 8/8] ARM: shmobile: r8a7791: Add clocks
@ 2013-11-19 14:45   ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 14:45 UTC (permalink / raw
  To: linux-arm-kernel

Declare all core clocks and DIV6 clocks, as well as all MSTP clocks
currently used by r8a7791 boards.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/r8a7791.dtsi | 312 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 312 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index 86d5d3a..5c8933e 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -9,6 +9,7 @@
  * kind, whether express or implied.
  */
 
+#include <dt-bindings/clock/r8a7791-clock.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 
@@ -176,4 +177,315 @@
 		reg = <0 0xe6060000 0 0x250>;
 		#gpio-range-cells = <3>;
 	};
+
+	clocks {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* External root clock */
+		extal_clk: extal_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			/* This value must be overriden by the board. */
+			clock-frequency = <0>;
+			clock-output-names = "extal";
+		};
+
+		/* Special CPG clocks */
+		cpg_clocks: cpg_clocks@e6150000 {
+			compatible = "renesas,r8a7791-cpg-clocks",
+				     "renesas,rcar-gen2-cpg-clocks";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>;
+			#clock-cells = <1>;
+			clock-output-names = "main", "pll0", "pll1", "pll3",
+					     "lb", "qspi", "sdh", "sd0", "z";
+		};
+
+		/* Variable factor clocks */
+		sd1_clk: sd2_clk@e6150078 {
+			compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe6150078 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "sd1";
+		};
+		sd2_clk: sd3_clk@e615007c {
+			compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe615007c 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "sd2";
+		};
+		mmc0_clk: mmc0_clk@e6150240 {
+			compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe6150240 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "mmc0";
+		};
+		ssp_clk: ssp_clk@e6150248 {
+			compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe6150248 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "ssp";
+		};
+		ssprs_clk: ssprs_clk@e615024c {
+			compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock";
+			reg = <0 0xe615024c 0 4>;
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-output-names = "ssprs";
+		};
+
+		/* Fixed factor clocks */
+		pll1_div2_clk: pll1_div2_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <2>;
+			clock-mult = <1>;
+			clock-output-names = "pll1_div2";
+		};
+		zg_clk: zg_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <3>;
+			clock-mult = <1>;
+			clock-output-names = "zg";
+		};
+		zx_clk: zx_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <3>;
+			clock-mult = <1>;
+			clock-output-names = "zx";
+		};
+		zs_clk: zs_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <6>;
+			clock-mult = <1>;
+			clock-output-names = "zs";
+		};
+		hp_clk: hp_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <12>;
+			clock-mult = <1>;
+			clock-output-names = "hp";
+		};
+		i_clk: i_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <2>;
+			clock-mult = <1>;
+			clock-output-names = "i";
+		};
+		b_clk: b_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <12>;
+			clock-mult = <1>;
+			clock-output-names = "b";
+		};
+		p_clk: p_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <24>;
+			clock-mult = <1>;
+			clock-output-names = "p";
+		};
+		cl_clk: cl_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <48>;
+			clock-mult = <1>;
+			clock-output-names = "cl";
+		};
+		m2_clk: m2_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <8>;
+			clock-mult = <1>;
+			clock-output-names = "m2";
+		};
+		imp_clk: imp_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <4>;
+			clock-mult = <1>;
+			clock-output-names = "imp";
+		};
+		rclk_clk: rclk_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <(48 * 1024)>;
+			clock-mult = <1>;
+			clock-output-names = "rclk";
+		};
+		oscclk_clk: oscclk_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL1>;
+			#clock-cells = <0>;
+			clock-div = <(12 * 1024)>;
+			clock-mult = <1>;
+			clock-output-names = "oscclk";
+		};
+		zb3_clk: zb3_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL3>;
+			#clock-cells = <0>;
+			clock-div = <4>;
+			clock-mult = <1>;
+			clock-output-names = "zb3";
+		};
+		zb3d2_clk: zb3d2_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL3>;
+			#clock-cells = <0>;
+			clock-div = <8>;
+			clock-mult = <1>;
+			clock-output-names = "zb3d2";
+		};
+		ddr_clk: ddr_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&cpg_clocks R8A7791_CLK_PLL3>;
+			#clock-cells = <0>;
+			clock-div = <8>;
+			clock-mult = <1>;
+			clock-output-names = "ddr";
+		};
+		mp_clk: mp_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&pll1_div2_clk>;
+			#clock-cells = <0>;
+			clock-div = <15>;
+			clock-mult = <1>;
+			clock-output-names = "mp";
+		};
+		cp_clk: cp_clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&extal_clk>;
+			#clock-cells = <0>;
+			clock-div = <2>;
+			clock-mult = <1>;
+			clock-output-names = "cp";
+		};
+
+		/* Gate clocks */
+		mstp1_clks: mstp1_clks@e6150134 {
+			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>;
+			clocks = <&p_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>,
+				 <&cp_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7791_CLK_TMU1 R8A7791_CLK_TMU3 R8A7791_CLK_TMU2
+				R8A7791_CLK_CMT0 R8A7791_CLK_TMU0 R8A7791_CLK_VSP1_DU1
+				R8A7791_CLK_VSP1_DU0 R8A7791_CLK_VSP1_SY
+			>;
+			clock-output-names +				"tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1",
+				"vsp1-du0", "vsp1-sy";
+		};
+		mstp2_clks: mstp2_clks@e6150138 {
+			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
+			clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>,
+				 <&mp_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7791_CLK_SCIFA2 R8A7791_CLK_SCIFA1 R8A7791_CLK_SCIFA0
+				R8A7791_CLK_SCIFB0 R8A7791_CLK_SCIFB1 R8A7791_CLK_SCIFB2
+			>;
+			clock-output-names +				"scifa2", "scifa1", "scifa0", "scifb0", "scifb1",
+				"scifb2";
+		};
+		mstp3_clks: mstp3_clks@e615013c {
+			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>;
+			clocks = <&cp_clk>, <&sd2_clk>, <&sd1_clk>,
+				<&cpg_clocks R8A7791_CLK_SD0>, <&mmc0_clk>, <&rclk_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7791_CLK_TPU0 R8A7791_CLK_SDHI2 R8A7791_CLK_SDHI1
+				R8A7791_CLK_SDHI0 R8A7791_CLK_MMCIF0 R8A7791_CLK_CMT1
+			>;
+			clock-output-names +				"tpu0", "sdhi2", "sdhi1", "sdhi0", "mmcif0", "cmt1";
+		};
+		mstp5_clks: mstp5_clks@e6150144 {
+			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>;
+			clocks = <&extal_clk>, <&p_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <R8A7791_CLK_THERMAL R8A7791_CLK_PWM>;
+			clock-output-names = "thermal", "pwm";
+		};
+		mstp7_clks: mstp7_clks@e615014c {
+			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe615014c 0 4>, <0 0xe61501c4 0 4>;
+			clocks = <&zs_clk>, <&p_clk>, <&p_clk>, <&zs_clk>, <&zs_clk>,
+				 <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&zx_clk>,
+				 <&zx_clk>, <&zx_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7791_CLK_HSCIF2 R8A7791_CLK_SCIF5 R8A7791_CLK_SCIF4
+				R8A7791_CLK_HSCIF1 R8A7791_CLK_HSCIF0 R8A7791_CLK_SCIF3
+				R8A7791_CLK_SCIF2 R8A7791_CLK_SCIF1 R8A7791_CLK_SCIF0
+				R8A7791_CLK_DU1 R8A7791_CLK_DU0 R8A7791_CLK_LVDS0
+			>;
+			clock-output-names +				"hscif2", "scif5", "scif4", "hscif1", "hscif0", "scif3",
+				"scif2", "scif1", "scif0", "du1", "du0", "lvds0";
+		};
+		mstp8_clks: mstp8_clks@e6150990 {
+			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>;
+			clocks = <&p_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <R8A7791_CLK_ETHER>;
+			clock-output-names = "ether";
+		};
+		mstp9_clks: mstp9_clks@e6150994 {
+			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>;
+			clocks = <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>,
+				 <&p_clk>, <&p_clk>, <&p_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7791_CLK_RCAN1 R8A7791_CLK_RCAN0 R8A7791_CLK_I2C4
+				R8A7791_CLK_I2C4 R8A7791_CLK_I2C3 R8A7791_CLK_I2C2
+				R8A7791_CLK_I2C1 R8A7791_CLK_I2C0
+			>;
+			clock-output-names +				"rcan1", "rcan0", "i2c5", "i2c4", "i2c3", "i2c2", "i2c1",
+				"i2c0";
+		};
+		mstp11_clks: mstp11_clks@e615099c {
+			compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks";
+			reg = <0 0xe615099c 0 4>, <0 0xe61509ac 0 4>;
+			clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>;
+			#clock-cells = <1>;
+			renesas,clock-indices = <
+				R8A7791_CLK_SCIFA3 R8A7791_CLK_SCIFA4 R8A7791_CLK_SCIFA5
+			>;
+			clock-output-names = "scifa3", "scifa4", "scifa5";
+		};
+	};
 };
-- 
1.8.3.2


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

* Re: [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
  2013-11-19 14:45   ` Laurent Pinchart
  (?)
@ 2013-11-19 16:28     ` Mark Rutland
  -1 siblings, 0 replies; 41+ messages in thread
From: Mark Rutland @ 2013-11-19 16:28 UTC (permalink / raw
  To: Laurent Pinchart
  Cc: linux-sh@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	Mike Turquette, devicetree@vger.kernel.org

On Tue, Nov 19, 2013 at 02:45:42PM +0000, Laurent Pinchart wrote:
> MSTP clocks are gate clocks controlled through a register that handles
> up to 32 clocks. The register is often sparsely populated.

Does that mean some clocks aren't wired up, or that some clocks don't
exist at all?

What is the behaviour of the unpopulated bits?

> 
> Those clocks are found on Renesas ARM SoCs.
> 
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
>  drivers/clk/shmobile/Makefile                      |   1 +
>  drivers/clk/shmobile/clk-mstp.c                    | 229 +++++++++++++++++++++
>  3 files changed, 278 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
>  create mode 100644 drivers/clk/shmobile/clk-mstp.c
> 
> diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> new file mode 100644
> index 0000000..126b17e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> @@ -0,0 +1,48 @@
> +* Renesas CPG Module Stop (MSTP) Clocks
> +
> +The CPG can gate SoC device clocks. The gates are organized in groups of up to
> +32 gates.
> +
> +This device tree binding describes a single 32 gate clocks group per node.
> +Clocks are referenced by user nodes by the MSTP node phandle and the clock
> +index in the group, from 0 to 31.
> +
> +Required Properties:
> +
> +  - compatible: Must be one of the following
> +    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks
> +    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate clocks
> +    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
> +  - reg: Base address and length of the memory resource used by the MSTP
> +    clocks

There are two entries in the example, the code seems to assume they are
particular registers, but this implies one.

Are these not part of a larger bank of registers?

> +  - clocks: Reference to the parent clocks

How many, and what do they correspond to?

> +  - #clock-cells: Must be 1
> +  - clock-output-names: The name of the clocks as free-form strings
> +  - renesas,indices: Indices of the gate clocks into the group (0 to 31)

The description of this property doesn't describe half of what it means.
I believe something like the below does:

- renesas,indices: A list of clock IDs (single cells), one for each
  clock present. Each entry may correspond to a clock-output-names entry
  at the same index, and its location in the list defines the
  corresponding clock-specifier for the entry.

I'd imagine we have a few sparse clocks by now, and we might be able to
make this more uniform. But I may be mistaken.

[...]

> +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> +{
> +	struct mstp_clock *clock = to_mstp_clock(hw);
> +	struct mstp_clock_group *group = clock->group;
> +	u32 bitmask = BIT(clock->bit_index);
> +	unsigned long flags;
> +	unsigned int i;
> +	u32 value;
> +
> +	spin_lock_irqsave(&group->lock, flags);
> +
> +	value = clk_readl(group->smstpcr);
> +	if (enable)
> +		value &= ~bitmask;
> +	else
> +		value |= bitmask;
> +	clk_writel(value, group->smstpcr);
> +
> +	spin_unlock_irqrestore(&group->lock, flags);
> +
> +	if (!enable || !group->mstpsr)
> +		return 0;
> +
> +	for (i = 1000; i > 0; --i) {
> +		if (!(clk_readl(group->mstpsr) & bitmask))
> +			break;
> +		cpu_relax();
> +	}

Any particular reason for 1000 times? Is there a known minimum time to
switch a clock between disabled and enabled? A comment would be nice.

Cheers,
Mark.

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

* [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
@ 2013-11-19 16:28     ` Mark Rutland
  0 siblings, 0 replies; 41+ messages in thread
From: Mark Rutland @ 2013-11-19 16:28 UTC (permalink / raw
  To: linux-arm-kernel

On Tue, Nov 19, 2013 at 02:45:42PM +0000, Laurent Pinchart wrote:
> MSTP clocks are gate clocks controlled through a register that handles
> up to 32 clocks. The register is often sparsely populated.

Does that mean some clocks aren't wired up, or that some clocks don't
exist at all?

What is the behaviour of the unpopulated bits?

> 
> Those clocks are found on Renesas ARM SoCs.
> 
> Cc: devicetree at vger.kernel.org
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
>  drivers/clk/shmobile/Makefile                      |   1 +
>  drivers/clk/shmobile/clk-mstp.c                    | 229 +++++++++++++++++++++
>  3 files changed, 278 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
>  create mode 100644 drivers/clk/shmobile/clk-mstp.c
> 
> diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> new file mode 100644
> index 0000000..126b17e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> @@ -0,0 +1,48 @@
> +* Renesas CPG Module Stop (MSTP) Clocks
> +
> +The CPG can gate SoC device clocks. The gates are organized in groups of up to
> +32 gates.
> +
> +This device tree binding describes a single 32 gate clocks group per node.
> +Clocks are referenced by user nodes by the MSTP node phandle and the clock
> +index in the group, from 0 to 31.
> +
> +Required Properties:
> +
> +  - compatible: Must be one of the following
> +    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks
> +    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate clocks
> +    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
> +  - reg: Base address and length of the memory resource used by the MSTP
> +    clocks

There are two entries in the example, the code seems to assume they are
particular registers, but this implies one.

Are these not part of a larger bank of registers?

> +  - clocks: Reference to the parent clocks

How many, and what do they correspond to?

> +  - #clock-cells: Must be 1
> +  - clock-output-names: The name of the clocks as free-form strings
> +  - renesas,indices: Indices of the gate clocks into the group (0 to 31)

The description of this property doesn't describe half of what it means.
I believe something like the below does:

- renesas,indices: A list of clock IDs (single cells), one for each
  clock present. Each entry may correspond to a clock-output-names entry
  at the same index, and its location in the list defines the
  corresponding clock-specifier for the entry.

I'd imagine we have a few sparse clocks by now, and we might be able to
make this more uniform. But I may be mistaken.

[...]

> +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> +{
> +	struct mstp_clock *clock = to_mstp_clock(hw);
> +	struct mstp_clock_group *group = clock->group;
> +	u32 bitmask = BIT(clock->bit_index);
> +	unsigned long flags;
> +	unsigned int i;
> +	u32 value;
> +
> +	spin_lock_irqsave(&group->lock, flags);
> +
> +	value = clk_readl(group->smstpcr);
> +	if (enable)
> +		value &= ~bitmask;
> +	else
> +		value |= bitmask;
> +	clk_writel(value, group->smstpcr);
> +
> +	spin_unlock_irqrestore(&group->lock, flags);
> +
> +	if (!enable || !group->mstpsr)
> +		return 0;
> +
> +	for (i = 1000; i > 0; --i) {
> +		if (!(clk_readl(group->mstpsr) & bitmask))
> +			break;
> +		cpu_relax();
> +	}

Any particular reason for 1000 times? Is there a known minimum time to
switch a clock between disabled and enabled? A comment would be nice.

Cheers,
Mark.

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

* Re: [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
@ 2013-11-19 16:28     ` Mark Rutland
  0 siblings, 0 replies; 41+ messages in thread
From: Mark Rutland @ 2013-11-19 16:28 UTC (permalink / raw
  To: linux-arm-kernel

On Tue, Nov 19, 2013 at 02:45:42PM +0000, Laurent Pinchart wrote:
> MSTP clocks are gate clocks controlled through a register that handles
> up to 32 clocks. The register is often sparsely populated.

Does that mean some clocks aren't wired up, or that some clocks don't
exist at all?

What is the behaviour of the unpopulated bits?

> 
> Those clocks are found on Renesas ARM SoCs.
> 
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
>  drivers/clk/shmobile/Makefile                      |   1 +
>  drivers/clk/shmobile/clk-mstp.c                    | 229 +++++++++++++++++++++
>  3 files changed, 278 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
>  create mode 100644 drivers/clk/shmobile/clk-mstp.c
> 
> diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> new file mode 100644
> index 0000000..126b17e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> @@ -0,0 +1,48 @@
> +* Renesas CPG Module Stop (MSTP) Clocks
> +
> +The CPG can gate SoC device clocks. The gates are organized in groups of up to
> +32 gates.
> +
> +This device tree binding describes a single 32 gate clocks group per node.
> +Clocks are referenced by user nodes by the MSTP node phandle and the clock
> +index in the group, from 0 to 31.
> +
> +Required Properties:
> +
> +  - compatible: Must be one of the following
> +    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks
> +    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate clocks
> +    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
> +  - reg: Base address and length of the memory resource used by the MSTP
> +    clocks

There are two entries in the example, the code seems to assume they are
particular registers, but this implies one.

Are these not part of a larger bank of registers?

> +  - clocks: Reference to the parent clocks

How many, and what do they correspond to?

> +  - #clock-cells: Must be 1
> +  - clock-output-names: The name of the clocks as free-form strings
> +  - renesas,indices: Indices of the gate clocks into the group (0 to 31)

The description of this property doesn't describe half of what it means.
I believe something like the below does:

- renesas,indices: A list of clock IDs (single cells), one for each
  clock present. Each entry may correspond to a clock-output-names entry
  at the same index, and its location in the list defines the
  corresponding clock-specifier for the entry.

I'd imagine we have a few sparse clocks by now, and we might be able to
make this more uniform. But I may be mistaken.

[...]

> +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> +{
> +	struct mstp_clock *clock = to_mstp_clock(hw);
> +	struct mstp_clock_group *group = clock->group;
> +	u32 bitmask = BIT(clock->bit_index);
> +	unsigned long flags;
> +	unsigned int i;
> +	u32 value;
> +
> +	spin_lock_irqsave(&group->lock, flags);
> +
> +	value = clk_readl(group->smstpcr);
> +	if (enable)
> +		value &= ~bitmask;
> +	else
> +		value |= bitmask;
> +	clk_writel(value, group->smstpcr);
> +
> +	spin_unlock_irqrestore(&group->lock, flags);
> +
> +	if (!enable || !group->mstpsr)
> +		return 0;
> +
> +	for (i = 1000; i > 0; --i) {
> +		if (!(clk_readl(group->mstpsr) & bitmask))
> +			break;
> +		cpu_relax();
> +	}

Any particular reason for 1000 times? Is there a known minimum time to
switch a clock between disabled and enabled? A comment would be nice.

Cheers,
Mark.

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

* Re: [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
  2013-11-19 16:28     ` Mark Rutland
  (?)
@ 2013-11-19 17:00       ` Laurent Pinchart
  -1 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 17:00 UTC (permalink / raw
  To: Mark Rutland
  Cc: Laurent Pinchart, linux-sh@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, Mike Turquette,
	devicetree@vger.kernel.org

Hi Mark,

Thank you for the quick review, much appreciated.

On Tuesday 19 November 2013 16:28:21 Mark Rutland wrote:
> On Tue, Nov 19, 2013 at 02:45:42PM +0000, Laurent Pinchart wrote:
> > MSTP clocks are gate clocks controlled through a register that handles
> > up to 32 clocks. The register is often sparsely populated.
> 
> Does that mean some clocks aren't wired up, or that some clocks don't
> exist at all?

It means that some of the bits don't control anything.

> What is the behaviour of the unpopulated bits?

According to the datasheet they're reserved, read-only, and read an 
unspecified value that is to be written back without modification when writing 
the register.

> > Those clocks are found on Renesas ARM SoCs.
> > 
> > Cc: devicetree@vger.kernel.org
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
> >  drivers/clk/shmobile/Makefile                      |   1 +
> >  drivers/clk/shmobile/clk-mstp.c                    | 229 ++++++++++++++++
> >  3 files changed, 278 insertions(+)
> >  create mode 100644
> >  Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> >  create mode 100644 drivers/clk/shmobile/clk-mstp.c
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt new
> > file mode 100644
> > index 0000000..126b17e
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > @@ -0,0 +1,48 @@
> > +* Renesas CPG Module Stop (MSTP) Clocks
> > +
> > +The CPG can gate SoC device clocks. The gates are organized in groups of
> > up to
> > +32 gates.
> > +
> > +This device tree binding describes a single 32 gate clocks group per
> > node.
> > +Clocks are referenced by user nodes by the MSTP node phandle and the
> > clock
> > +index in the group, from 0 to 31.
> > +
> > +Required Properties:
> > +
> > +  - compatible: Must be one of the following
> > +    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate
> > clocks
> > +    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate
> > clocks
> > +    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
> > +  - reg: Base address and length of the memory resource used by the MSTP
> > +    clocks
> 
> There are two entries in the example, the code seems to assume they are
> particular registers, but this implies one.

There can be one or two registers, depending on the hardware. The first 
register is always required and controls the clocks, the second register is 
optional (in the sense that it's not implemented for some of the MSTP 
instances) and reports the clock status.

> Are these not part of a larger bank of registers?

They are. Here's the memory map for the r8a7791 for instance.

MSTPSR0		H'E615 0030
MSTPSR1		H'E615 0038
MSTPSR2		H'E615 0040
MSTPSR3		H'E615 0048
MSTPSR4		H'E615 004C
MSTPSR5		H'E615 003C
MSTPSR6		H'E615 01C0
MSTPSR7		H'E615 01C4
MSTPSR8		H'E615 09A0
MSTPSR9		H'E615 09A4
MSTPSR10		H'E615 09A8
MSTPSR11		H'E615 09AC

SMSTPCR0		H'E615 0130
SMSTPCR1		H'E615 0134
SMSTPCR2		H'E615 0138
SMSTPCR3		H'E615 013C
SMSTPCR4		H'E615 0140
SMSTPCR5		H'E615 0144
SMSTPCR6		H'E615 0148
SMSTPCR7		H'E615 014C
SMSTPCR8		H'E615 0990
SMSTPCR9		H'E615 0994
SMSTPCR10		H'E615 0998
SMSTPCR11		H'E615 099C

I've pondered whether we should use a single device node for all the MSTP 
clocks, but I don't think it would be very practical. Not only would we need 
to encode all bit positions, we also would have to encode register offsets in 
DT. This would become pretty messy in a single node.

> > +  - clocks: Reference to the parent clocks
> 
> How many, and what do they correspond to?

What about

- clocks: Reference to the parent clocks, one per output clock. The parents 
must appear in the same order as the output clocks.

> > +  - #clock-cells: Must be 1
> > +  - clock-output-names: The name of the clocks as free-form strings
> > +  - renesas,indices: Indices of the gate clocks into the group (0 to 31)
> 
> The description of this property doesn't describe half of what it means.
> I believe something like the below does:
> 
> - renesas,indices: A list of clock IDs (single cells), one for each
>   clock present. Each entry may correspond to a clock-output-names entry
>   at the same index, and its location in the list defines the
>   corresponding clock-specifier for the entry.

I might be mistaken, but doesn't "its location in the list defines the 
corresponding clock-specifier for the entry" imply that clock specifiers use 
the location in the list as the clock ID instead of the numerical value of the 
indices entry ? Each entry in the renesas,indices list corresponds to one 
clocks entry and one clock-output-names entry, and clock users reference an 
MSTP clock using the value of its indices entry, not the position of the 
entry.

> I'd imagine we have a few sparse clocks by now, and we might be able to
> make this more uniform. But I may be mistaken.
> 
> [...]
> 
> > +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> > +{
> > +	struct mstp_clock *clock = to_mstp_clock(hw);
> > +	struct mstp_clock_group *group = clock->group;
> > +	u32 bitmask = BIT(clock->bit_index);
> > +	unsigned long flags;
> > +	unsigned int i;
> > +	u32 value;
> > +
> > +	spin_lock_irqsave(&group->lock, flags);
> > +
> > +	value = clk_readl(group->smstpcr);
> > +	if (enable)
> > +		value &= ~bitmask;
> > +	else
> > +		value |= bitmask;
> > +	clk_writel(value, group->smstpcr);
> > +
> > +	spin_unlock_irqrestore(&group->lock, flags);
> > +
> > +	if (!enable || !group->mstpsr)
> > +		return 0;
> > +
> > +	for (i = 1000; i > 0; --i) {
> > +		if (!(clk_readl(group->mstpsr) & bitmask))
> > +			break;
> > +		cpu_relax();
> > +	}
> 
> Any particular reason for 1000 times? Is there a known minimum time to
> switch a clock between disabled and enabled? A comment would be nice.

There's no particular reason, the datasheet doesn't provide any useful 
information. I've just copied that value from existing C code.

-- 
Regards,

Laurent Pinchart


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

* [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
@ 2013-11-19 17:00       ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 17:00 UTC (permalink / raw
  To: linux-arm-kernel

Hi Mark,

Thank you for the quick review, much appreciated.

On Tuesday 19 November 2013 16:28:21 Mark Rutland wrote:
> On Tue, Nov 19, 2013 at 02:45:42PM +0000, Laurent Pinchart wrote:
> > MSTP clocks are gate clocks controlled through a register that handles
> > up to 32 clocks. The register is often sparsely populated.
> 
> Does that mean some clocks aren't wired up, or that some clocks don't
> exist at all?

It means that some of the bits don't control anything.

> What is the behaviour of the unpopulated bits?

According to the datasheet they're reserved, read-only, and read an 
unspecified value that is to be written back without modification when writing 
the register.

> > Those clocks are found on Renesas ARM SoCs.
> > 
> > Cc: devicetree at vger.kernel.org
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
> >  drivers/clk/shmobile/Makefile                      |   1 +
> >  drivers/clk/shmobile/clk-mstp.c                    | 229 ++++++++++++++++
> >  3 files changed, 278 insertions(+)
> >  create mode 100644
> >  Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> >  create mode 100644 drivers/clk/shmobile/clk-mstp.c
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt new
> > file mode 100644
> > index 0000000..126b17e
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > @@ -0,0 +1,48 @@
> > +* Renesas CPG Module Stop (MSTP) Clocks
> > +
> > +The CPG can gate SoC device clocks. The gates are organized in groups of
> > up to
> > +32 gates.
> > +
> > +This device tree binding describes a single 32 gate clocks group per
> > node.
> > +Clocks are referenced by user nodes by the MSTP node phandle and the
> > clock
> > +index in the group, from 0 to 31.
> > +
> > +Required Properties:
> > +
> > +  - compatible: Must be one of the following
> > +    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate
> > clocks
> > +    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate
> > clocks
> > +    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
> > +  - reg: Base address and length of the memory resource used by the MSTP
> > +    clocks
> 
> There are two entries in the example, the code seems to assume they are
> particular registers, but this implies one.

There can be one or two registers, depending on the hardware. The first 
register is always required and controls the clocks, the second register is 
optional (in the sense that it's not implemented for some of the MSTP 
instances) and reports the clock status.

> Are these not part of a larger bank of registers?

They are. Here's the memory map for the r8a7791 for instance.

MSTPSR0		H'E615 0030
MSTPSR1		H'E615 0038
MSTPSR2		H'E615 0040
MSTPSR3		H'E615 0048
MSTPSR4		H'E615 004C
MSTPSR5		H'E615 003C
MSTPSR6		H'E615 01C0
MSTPSR7		H'E615 01C4
MSTPSR8		H'E615 09A0
MSTPSR9		H'E615 09A4
MSTPSR10		H'E615 09A8
MSTPSR11		H'E615 09AC

SMSTPCR0		H'E615 0130
SMSTPCR1		H'E615 0134
SMSTPCR2		H'E615 0138
SMSTPCR3		H'E615 013C
SMSTPCR4		H'E615 0140
SMSTPCR5		H'E615 0144
SMSTPCR6		H'E615 0148
SMSTPCR7		H'E615 014C
SMSTPCR8		H'E615 0990
SMSTPCR9		H'E615 0994
SMSTPCR10		H'E615 0998
SMSTPCR11		H'E615 099C

I've pondered whether we should use a single device node for all the MSTP 
clocks, but I don't think it would be very practical. Not only would we need 
to encode all bit positions, we also would have to encode register offsets in 
DT. This would become pretty messy in a single node.

> > +  - clocks: Reference to the parent clocks
> 
> How many, and what do they correspond to?

What about

- clocks: Reference to the parent clocks, one per output clock. The parents 
must appear in the same order as the output clocks.

> > +  - #clock-cells: Must be 1
> > +  - clock-output-names: The name of the clocks as free-form strings
> > +  - renesas,indices: Indices of the gate clocks into the group (0 to 31)
> 
> The description of this property doesn't describe half of what it means.
> I believe something like the below does:
> 
> - renesas,indices: A list of clock IDs (single cells), one for each
>   clock present. Each entry may correspond to a clock-output-names entry
>   at the same index, and its location in the list defines the
>   corresponding clock-specifier for the entry.

I might be mistaken, but doesn't "its location in the list defines the 
corresponding clock-specifier for the entry" imply that clock specifiers use 
the location in the list as the clock ID instead of the numerical value of the 
indices entry ? Each entry in the renesas,indices list corresponds to one 
clocks entry and one clock-output-names entry, and clock users reference an 
MSTP clock using the value of its indices entry, not the position of the 
entry.

> I'd imagine we have a few sparse clocks by now, and we might be able to
> make this more uniform. But I may be mistaken.
> 
> [...]
> 
> > +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> > +{
> > +	struct mstp_clock *clock = to_mstp_clock(hw);
> > +	struct mstp_clock_group *group = clock->group;
> > +	u32 bitmask = BIT(clock->bit_index);
> > +	unsigned long flags;
> > +	unsigned int i;
> > +	u32 value;
> > +
> > +	spin_lock_irqsave(&group->lock, flags);
> > +
> > +	value = clk_readl(group->smstpcr);
> > +	if (enable)
> > +		value &= ~bitmask;
> > +	else
> > +		value |= bitmask;
> > +	clk_writel(value, group->smstpcr);
> > +
> > +	spin_unlock_irqrestore(&group->lock, flags);
> > +
> > +	if (!enable || !group->mstpsr)
> > +		return 0;
> > +
> > +	for (i = 1000; i > 0; --i) {
> > +		if (!(clk_readl(group->mstpsr) & bitmask))
> > +			break;
> > +		cpu_relax();
> > +	}
> 
> Any particular reason for 1000 times? Is there a known minimum time to
> switch a clock between disabled and enabled? A comment would be nice.

There's no particular reason, the datasheet doesn't provide any useful 
information. I've just copied that value from existing C code.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
@ 2013-11-19 17:00       ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-19 17:00 UTC (permalink / raw
  To: linux-arm-kernel

Hi Mark,

Thank you for the quick review, much appreciated.

On Tuesday 19 November 2013 16:28:21 Mark Rutland wrote:
> On Tue, Nov 19, 2013 at 02:45:42PM +0000, Laurent Pinchart wrote:
> > MSTP clocks are gate clocks controlled through a register that handles
> > up to 32 clocks. The register is often sparsely populated.
> 
> Does that mean some clocks aren't wired up, or that some clocks don't
> exist at all?

It means that some of the bits don't control anything.

> What is the behaviour of the unpopulated bits?

According to the datasheet they're reserved, read-only, and read an 
unspecified value that is to be written back without modification when writing 
the register.

> > Those clocks are found on Renesas ARM SoCs.
> > 
> > Cc: devicetree@vger.kernel.org
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> > 
> >  .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
> >  drivers/clk/shmobile/Makefile                      |   1 +
> >  drivers/clk/shmobile/clk-mstp.c                    | 229 ++++++++++++++++
> >  3 files changed, 278 insertions(+)
> >  create mode 100644
> >  Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> >  create mode 100644 drivers/clk/shmobile/clk-mstp.c
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt new
> > file mode 100644
> > index 0000000..126b17e
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > @@ -0,0 +1,48 @@
> > +* Renesas CPG Module Stop (MSTP) Clocks
> > +
> > +The CPG can gate SoC device clocks. The gates are organized in groups of
> > up to
> > +32 gates.
> > +
> > +This device tree binding describes a single 32 gate clocks group per
> > node.
> > +Clocks are referenced by user nodes by the MSTP node phandle and the
> > clock
> > +index in the group, from 0 to 31.
> > +
> > +Required Properties:
> > +
> > +  - compatible: Must be one of the following
> > +    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate
> > clocks
> > +    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate
> > clocks
> > +    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
> > +  - reg: Base address and length of the memory resource used by the MSTP
> > +    clocks
> 
> There are two entries in the example, the code seems to assume they are
> particular registers, but this implies one.

There can be one or two registers, depending on the hardware. The first 
register is always required and controls the clocks, the second register is 
optional (in the sense that it's not implemented for some of the MSTP 
instances) and reports the clock status.

> Are these not part of a larger bank of registers?

They are. Here's the memory map for the r8a7791 for instance.

MSTPSR0		H'E615 0030
MSTPSR1		H'E615 0038
MSTPSR2		H'E615 0040
MSTPSR3		H'E615 0048
MSTPSR4		H'E615 004C
MSTPSR5		H'E615 003C
MSTPSR6		H'E615 01C0
MSTPSR7		H'E615 01C4
MSTPSR8		H'E615 09A0
MSTPSR9		H'E615 09A4
MSTPSR10		H'E615 09A8
MSTPSR11		H'E615 09AC

SMSTPCR0		H'E615 0130
SMSTPCR1		H'E615 0134
SMSTPCR2		H'E615 0138
SMSTPCR3		H'E615 013C
SMSTPCR4		H'E615 0140
SMSTPCR5		H'E615 0144
SMSTPCR6		H'E615 0148
SMSTPCR7		H'E615 014C
SMSTPCR8		H'E615 0990
SMSTPCR9		H'E615 0994
SMSTPCR10		H'E615 0998
SMSTPCR11		H'E615 099C

I've pondered whether we should use a single device node for all the MSTP 
clocks, but I don't think it would be very practical. Not only would we need 
to encode all bit positions, we also would have to encode register offsets in 
DT. This would become pretty messy in a single node.

> > +  - clocks: Reference to the parent clocks
> 
> How many, and what do they correspond to?

What about

- clocks: Reference to the parent clocks, one per output clock. The parents 
must appear in the same order as the output clocks.

> > +  - #clock-cells: Must be 1
> > +  - clock-output-names: The name of the clocks as free-form strings
> > +  - renesas,indices: Indices of the gate clocks into the group (0 to 31)
> 
> The description of this property doesn't describe half of what it means.
> I believe something like the below does:
> 
> - renesas,indices: A list of clock IDs (single cells), one for each
>   clock present. Each entry may correspond to a clock-output-names entry
>   at the same index, and its location in the list defines the
>   corresponding clock-specifier for the entry.

I might be mistaken, but doesn't "its location in the list defines the 
corresponding clock-specifier for the entry" imply that clock specifiers use 
the location in the list as the clock ID instead of the numerical value of the 
indices entry ? Each entry in the renesas,indices list corresponds to one 
clocks entry and one clock-output-names entry, and clock users reference an 
MSTP clock using the value of its indices entry, not the position of the 
entry.

> I'd imagine we have a few sparse clocks by now, and we might be able to
> make this more uniform. But I may be mistaken.
> 
> [...]
> 
> > +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> > +{
> > +	struct mstp_clock *clock = to_mstp_clock(hw);
> > +	struct mstp_clock_group *group = clock->group;
> > +	u32 bitmask = BIT(clock->bit_index);
> > +	unsigned long flags;
> > +	unsigned int i;
> > +	u32 value;
> > +
> > +	spin_lock_irqsave(&group->lock, flags);
> > +
> > +	value = clk_readl(group->smstpcr);
> > +	if (enable)
> > +		value &= ~bitmask;
> > +	else
> > +		value |= bitmask;
> > +	clk_writel(value, group->smstpcr);
> > +
> > +	spin_unlock_irqrestore(&group->lock, flags);
> > +
> > +	if (!enable || !group->mstpsr)
> > +		return 0;
> > +
> > +	for (i = 1000; i > 0; --i) {
> > +		if (!(clk_readl(group->mstpsr) & bitmask))
> > +			break;
> > +		cpu_relax();
> > +	}
> 
> Any particular reason for 1000 times? Is there a known minimum time to
> switch a clock between disabled and enabled? A comment would be nice.

There's no particular reason, the datasheet doesn't provide any useful 
information. I've just copied that value from existing C code.

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
  2013-11-19 17:00       ` Laurent Pinchart
  (?)
@ 2013-11-19 18:19         ` Mark Rutland
  -1 siblings, 0 replies; 41+ messages in thread
From: Mark Rutland @ 2013-11-19 18:19 UTC (permalink / raw
  To: Laurent Pinchart
  Cc: devicetree@vger.kernel.org, Laurent Pinchart, Mike Turquette,
	linux-arm-kernel@lists.infradead.org, linux-sh@vger.kernel.org

On Tue, Nov 19, 2013 at 05:00:40PM +0000, Laurent Pinchart wrote:
> Hi Mark,
> 
> Thank you for the quick review, much appreciated.
> 
> On Tuesday 19 November 2013 16:28:21 Mark Rutland wrote:
> > On Tue, Nov 19, 2013 at 02:45:42PM +0000, Laurent Pinchart wrote:
> > > MSTP clocks are gate clocks controlled through a register that handles
> > > up to 32 clocks. The register is often sparsely populated.
> > 
> > Does that mean some clocks aren't wired up, or that some clocks don't
> > exist at all?
> 
> It means that some of the bits don't control anything.
> 
> > What is the behaviour of the unpopulated bits?
> 
> According to the datasheet they're reserved, read-only, and read an 
> unspecified value that is to be written back without modification when writing 
> the register.

Ok.

> 
> > > Those clocks are found on Renesas ARM SoCs.
> > > 
> > > Cc: devicetree@vger.kernel.org
> > > Signed-off-by: Laurent Pinchart
> > > <laurent.pinchart+renesas@ideasonboard.com>
> > > ---
> > > 
> > >  .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
> > >  drivers/clk/shmobile/Makefile                      |   1 +
> > >  drivers/clk/shmobile/clk-mstp.c                    | 229 ++++++++++++++++
> > >  3 files changed, 278 insertions(+)
> > >  create mode 100644
> > >  Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > >  create mode 100644 drivers/clk/shmobile/clk-mstp.c
> > > 
> > > diff --git
> > > a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt new
> > > file mode 100644
> > > index 0000000..126b17e
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > @@ -0,0 +1,48 @@
> > > +* Renesas CPG Module Stop (MSTP) Clocks
> > > +
> > > +The CPG can gate SoC device clocks. The gates are organized in groups of
> > > up to
> > > +32 gates.
> > > +
> > > +This device tree binding describes a single 32 gate clocks group per
> > > node.
> > > +Clocks are referenced by user nodes by the MSTP node phandle and the
> > > clock
> > > +index in the group, from 0 to 31.
> > > +
> > > +Required Properties:
> > > +
> > > +  - compatible: Must be one of the following
> > > +    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate
> > > clocks
> > > +    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate
> > > clocks
> > > +    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
> > > +  - reg: Base address and length of the memory resource used by the MSTP
> > > +    clocks
> > 
> > There are two entries in the example, the code seems to assume they are
> > particular registers, but this implies one.
> 
> There can be one or two registers, depending on the hardware. The first 
> register is always required and controls the clocks, the second register is 
> optional (in the sense that it's not implemented for some of the MSTP 
> instances) and reports the clock status.

Ok. The documentation should note this.

> 
> > Are these not part of a larger bank of registers?
> 
> They are. Here's the memory map for the r8a7791 for instance.
> 
> MSTPSR0		H'E615 0030
> MSTPSR1		H'E615 0038
> MSTPSR2		H'E615 0040
> MSTPSR3		H'E615 0048
> MSTPSR4		H'E615 004C
> MSTPSR5		H'E615 003C
> MSTPSR6		H'E615 01C0
> MSTPSR7		H'E615 01C4
> MSTPSR8		H'E615 09A0
> MSTPSR9		H'E615 09A4
> MSTPSR10		H'E615 09A8
> MSTPSR11		H'E615 09AC
> 
> SMSTPCR0		H'E615 0130
> SMSTPCR1		H'E615 0134
> SMSTPCR2		H'E615 0138
> SMSTPCR3		H'E615 013C
> SMSTPCR4		H'E615 0140
> SMSTPCR5		H'E615 0144
> SMSTPCR6		H'E615 0148
> SMSTPCR7		H'E615 014C
> SMSTPCR8		H'E615 0990
> SMSTPCR9		H'E615 0994
> SMSTPCR10		H'E615 0998
> SMSTPCR11		H'E615 099C
> 
> I've pondered whether we should use a single device node for all the MSTP 
> clocks, but I don't think it would be very practical. Not only would we need 
> to encode all bit positions, we also would have to encode register offsets in 
> DT. This would become pretty messy in a single node.
> 
> > > +  - clocks: Reference to the parent clocks
> > 
> > How many, and what do they correspond to?
> 
> What about
> 
> - clocks: Reference to the parent clocks, one per output clock. The parents 
> must appear in the same order as the output clocks.

That sounds reasonable.

> 
> > > +  - #clock-cells: Must be 1
> > > +  - clock-output-names: The name of the clocks as free-form strings
> > > +  - renesas,indices: Indices of the gate clocks into the group (0 to 31)
> > 
> > The description of this property doesn't describe half of what it means.
> > I believe something like the below does:
> > 
> > - renesas,indices: A list of clock IDs (single cells), one for each
> >   clock present. Each entry may correspond to a clock-output-names entry
> >   at the same index, and its location in the list defines the
> >   corresponding clock-specifier for the entry.
> 
> I might be mistaken, but doesn't "its location in the list defines the 
> corresponding clock-specifier for the entry" imply that clock specifiers use 
> the location in the list as the clock ID instead of the numerical value of the 
> indices entry ? Each entry in the renesas,indices list corresponds to one 
> clocks entry and one clock-output-names entry, and clock users reference an 
> MSTP clock using the value of its indices entry, not the position of the 
> entry.

Sorry, the code confused me. Having read over it again, I'm even more
confused.

You said the registers were sparesly populated, but the code assumes
that the bits start at 0 and the set of populated bits are contiguous,
which is not what I would describe that as sparse. Are the bits always
contiguous?

I thought the bits in the register were truly sparse (i.e. you could
have two bits which were at either end of the register), and the indices
property allowed you to define the set of bits which were valid.

As far as I can see from cpg_mstp_clocks_init and
cpg_mstp_clock_register, the indices property assings the set of IDs for
consumers to use, and I don't see what the point of that is if we
already have a well-defined linear index (the bit position in the
register) which we could use instead, which also makes the binding and
code simpler.

> 
> > I'd imagine we have a few sparse clocks by now, and we might be able to
> > make this more uniform. But I may be mistaken.
> > 
> > [...]
> > 
> > > +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> > > +{
> > > +	struct mstp_clock *clock = to_mstp_clock(hw);
> > > +	struct mstp_clock_group *group = clock->group;
> > > +	u32 bitmask = BIT(clock->bit_index);
> > > +	unsigned long flags;
> > > +	unsigned int i;
> > > +	u32 value;
> > > +
> > > +	spin_lock_irqsave(&group->lock, flags);
> > > +
> > > +	value = clk_readl(group->smstpcr);
> > > +	if (enable)
> > > +		value &= ~bitmask;
> > > +	else
> > > +		value |= bitmask;
> > > +	clk_writel(value, group->smstpcr);
> > > +
> > > +	spin_unlock_irqrestore(&group->lock, flags);
> > > +
> > > +	if (!enable || !group->mstpsr)
> > > +		return 0;
> > > +
> > > +	for (i = 1000; i > 0; --i) {
> > > +		if (!(clk_readl(group->mstpsr) & bitmask))
> > > +			break;
> > > +		cpu_relax();
> > > +	}
> > 
> > Any particular reason for 1000 times? Is there a known minimum time to
> > switch a clock between disabled and enabled? A comment would be nice.
> 
> There's no particular reason, the datasheet doesn't provide any useful 
> information. I've just copied that value from existing C code.

Any chance it might work without?

Thanks,
Mark.

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

* [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
@ 2013-11-19 18:19         ` Mark Rutland
  0 siblings, 0 replies; 41+ messages in thread
From: Mark Rutland @ 2013-11-19 18:19 UTC (permalink / raw
  To: linux-arm-kernel

On Tue, Nov 19, 2013 at 05:00:40PM +0000, Laurent Pinchart wrote:
> Hi Mark,
> 
> Thank you for the quick review, much appreciated.
> 
> On Tuesday 19 November 2013 16:28:21 Mark Rutland wrote:
> > On Tue, Nov 19, 2013 at 02:45:42PM +0000, Laurent Pinchart wrote:
> > > MSTP clocks are gate clocks controlled through a register that handles
> > > up to 32 clocks. The register is often sparsely populated.
> > 
> > Does that mean some clocks aren't wired up, or that some clocks don't
> > exist at all?
> 
> It means that some of the bits don't control anything.
> 
> > What is the behaviour of the unpopulated bits?
> 
> According to the datasheet they're reserved, read-only, and read an 
> unspecified value that is to be written back without modification when writing 
> the register.

Ok.

> 
> > > Those clocks are found on Renesas ARM SoCs.
> > > 
> > > Cc: devicetree at vger.kernel.org
> > > Signed-off-by: Laurent Pinchart
> > > <laurent.pinchart+renesas@ideasonboard.com>
> > > ---
> > > 
> > >  .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
> > >  drivers/clk/shmobile/Makefile                      |   1 +
> > >  drivers/clk/shmobile/clk-mstp.c                    | 229 ++++++++++++++++
> > >  3 files changed, 278 insertions(+)
> > >  create mode 100644
> > >  Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > >  create mode 100644 drivers/clk/shmobile/clk-mstp.c
> > > 
> > > diff --git
> > > a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt new
> > > file mode 100644
> > > index 0000000..126b17e
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > @@ -0,0 +1,48 @@
> > > +* Renesas CPG Module Stop (MSTP) Clocks
> > > +
> > > +The CPG can gate SoC device clocks. The gates are organized in groups of
> > > up to
> > > +32 gates.
> > > +
> > > +This device tree binding describes a single 32 gate clocks group per
> > > node.
> > > +Clocks are referenced by user nodes by the MSTP node phandle and the
> > > clock
> > > +index in the group, from 0 to 31.
> > > +
> > > +Required Properties:
> > > +
> > > +  - compatible: Must be one of the following
> > > +    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate
> > > clocks
> > > +    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate
> > > clocks
> > > +    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
> > > +  - reg: Base address and length of the memory resource used by the MSTP
> > > +    clocks
> > 
> > There are two entries in the example, the code seems to assume they are
> > particular registers, but this implies one.
> 
> There can be one or two registers, depending on the hardware. The first 
> register is always required and controls the clocks, the second register is 
> optional (in the sense that it's not implemented for some of the MSTP 
> instances) and reports the clock status.

Ok. The documentation should note this.

> 
> > Are these not part of a larger bank of registers?
> 
> They are. Here's the memory map for the r8a7791 for instance.
> 
> MSTPSR0		H'E615 0030
> MSTPSR1		H'E615 0038
> MSTPSR2		H'E615 0040
> MSTPSR3		H'E615 0048
> MSTPSR4		H'E615 004C
> MSTPSR5		H'E615 003C
> MSTPSR6		H'E615 01C0
> MSTPSR7		H'E615 01C4
> MSTPSR8		H'E615 09A0
> MSTPSR9		H'E615 09A4
> MSTPSR10		H'E615 09A8
> MSTPSR11		H'E615 09AC
> 
> SMSTPCR0		H'E615 0130
> SMSTPCR1		H'E615 0134
> SMSTPCR2		H'E615 0138
> SMSTPCR3		H'E615 013C
> SMSTPCR4		H'E615 0140
> SMSTPCR5		H'E615 0144
> SMSTPCR6		H'E615 0148
> SMSTPCR7		H'E615 014C
> SMSTPCR8		H'E615 0990
> SMSTPCR9		H'E615 0994
> SMSTPCR10		H'E615 0998
> SMSTPCR11		H'E615 099C
> 
> I've pondered whether we should use a single device node for all the MSTP 
> clocks, but I don't think it would be very practical. Not only would we need 
> to encode all bit positions, we also would have to encode register offsets in 
> DT. This would become pretty messy in a single node.
> 
> > > +  - clocks: Reference to the parent clocks
> > 
> > How many, and what do they correspond to?
> 
> What about
> 
> - clocks: Reference to the parent clocks, one per output clock. The parents 
> must appear in the same order as the output clocks.

That sounds reasonable.

> 
> > > +  - #clock-cells: Must be 1
> > > +  - clock-output-names: The name of the clocks as free-form strings
> > > +  - renesas,indices: Indices of the gate clocks into the group (0 to 31)
> > 
> > The description of this property doesn't describe half of what it means.
> > I believe something like the below does:
> > 
> > - renesas,indices: A list of clock IDs (single cells), one for each
> >   clock present. Each entry may correspond to a clock-output-names entry
> >   at the same index, and its location in the list defines the
> >   corresponding clock-specifier for the entry.
> 
> I might be mistaken, but doesn't "its location in the list defines the 
> corresponding clock-specifier for the entry" imply that clock specifiers use 
> the location in the list as the clock ID instead of the numerical value of the 
> indices entry ? Each entry in the renesas,indices list corresponds to one 
> clocks entry and one clock-output-names entry, and clock users reference an 
> MSTP clock using the value of its indices entry, not the position of the 
> entry.

Sorry, the code confused me. Having read over it again, I'm even more
confused.

You said the registers were sparesly populated, but the code assumes
that the bits start at 0 and the set of populated bits are contiguous,
which is not what I would describe that as sparse. Are the bits always
contiguous?

I thought the bits in the register were truly sparse (i.e. you could
have two bits which were at either end of the register), and the indices
property allowed you to define the set of bits which were valid.

As far as I can see from cpg_mstp_clocks_init and
cpg_mstp_clock_register, the indices property assings the set of IDs for
consumers to use, and I don't see what the point of that is if we
already have a well-defined linear index (the bit position in the
register) which we could use instead, which also makes the binding and
code simpler.

> 
> > I'd imagine we have a few sparse clocks by now, and we might be able to
> > make this more uniform. But I may be mistaken.
> > 
> > [...]
> > 
> > > +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> > > +{
> > > +	struct mstp_clock *clock = to_mstp_clock(hw);
> > > +	struct mstp_clock_group *group = clock->group;
> > > +	u32 bitmask = BIT(clock->bit_index);
> > > +	unsigned long flags;
> > > +	unsigned int i;
> > > +	u32 value;
> > > +
> > > +	spin_lock_irqsave(&group->lock, flags);
> > > +
> > > +	value = clk_readl(group->smstpcr);
> > > +	if (enable)
> > > +		value &= ~bitmask;
> > > +	else
> > > +		value |= bitmask;
> > > +	clk_writel(value, group->smstpcr);
> > > +
> > > +	spin_unlock_irqrestore(&group->lock, flags);
> > > +
> > > +	if (!enable || !group->mstpsr)
> > > +		return 0;
> > > +
> > > +	for (i = 1000; i > 0; --i) {
> > > +		if (!(clk_readl(group->mstpsr) & bitmask))
> > > +			break;
> > > +		cpu_relax();
> > > +	}
> > 
> > Any particular reason for 1000 times? Is there a known minimum time to
> > switch a clock between disabled and enabled? A comment would be nice.
> 
> There's no particular reason, the datasheet doesn't provide any useful 
> information. I've just copied that value from existing C code.

Any chance it might work without?

Thanks,
Mark.

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

* Re: [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
@ 2013-11-19 18:19         ` Mark Rutland
  0 siblings, 0 replies; 41+ messages in thread
From: Mark Rutland @ 2013-11-19 18:19 UTC (permalink / raw
  To: linux-arm-kernel

On Tue, Nov 19, 2013 at 05:00:40PM +0000, Laurent Pinchart wrote:
> Hi Mark,
> 
> Thank you for the quick review, much appreciated.
> 
> On Tuesday 19 November 2013 16:28:21 Mark Rutland wrote:
> > On Tue, Nov 19, 2013 at 02:45:42PM +0000, Laurent Pinchart wrote:
> > > MSTP clocks are gate clocks controlled through a register that handles
> > > up to 32 clocks. The register is often sparsely populated.
> > 
> > Does that mean some clocks aren't wired up, or that some clocks don't
> > exist at all?
> 
> It means that some of the bits don't control anything.
> 
> > What is the behaviour of the unpopulated bits?
> 
> According to the datasheet they're reserved, read-only, and read an 
> unspecified value that is to be written back without modification when writing 
> the register.

Ok.

> 
> > > Those clocks are found on Renesas ARM SoCs.
> > > 
> > > Cc: devicetree@vger.kernel.org
> > > Signed-off-by: Laurent Pinchart
> > > <laurent.pinchart+renesas@ideasonboard.com>
> > > ---
> > > 
> > >  .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
> > >  drivers/clk/shmobile/Makefile                      |   1 +
> > >  drivers/clk/shmobile/clk-mstp.c                    | 229 ++++++++++++++++
> > >  3 files changed, 278 insertions(+)
> > >  create mode 100644
> > >  Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > >  create mode 100644 drivers/clk/shmobile/clk-mstp.c
> > > 
> > > diff --git
> > > a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt new
> > > file mode 100644
> > > index 0000000..126b17e
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > @@ -0,0 +1,48 @@
> > > +* Renesas CPG Module Stop (MSTP) Clocks
> > > +
> > > +The CPG can gate SoC device clocks. The gates are organized in groups of
> > > up to
> > > +32 gates.
> > > +
> > > +This device tree binding describes a single 32 gate clocks group per
> > > node.
> > > +Clocks are referenced by user nodes by the MSTP node phandle and the
> > > clock
> > > +index in the group, from 0 to 31.
> > > +
> > > +Required Properties:
> > > +
> > > +  - compatible: Must be one of the following
> > > +    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate
> > > clocks
> > > +    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate
> > > clocks
> > > +    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
> > > +  - reg: Base address and length of the memory resource used by the MSTP
> > > +    clocks
> > 
> > There are two entries in the example, the code seems to assume they are
> > particular registers, but this implies one.
> 
> There can be one or two registers, depending on the hardware. The first 
> register is always required and controls the clocks, the second register is 
> optional (in the sense that it's not implemented for some of the MSTP 
> instances) and reports the clock status.

Ok. The documentation should note this.

> 
> > Are these not part of a larger bank of registers?
> 
> They are. Here's the memory map for the r8a7791 for instance.
> 
> MSTPSR0		H'E615 0030
> MSTPSR1		H'E615 0038
> MSTPSR2		H'E615 0040
> MSTPSR3		H'E615 0048
> MSTPSR4		H'E615 004C
> MSTPSR5		H'E615 003C
> MSTPSR6		H'E615 01C0
> MSTPSR7		H'E615 01C4
> MSTPSR8		H'E615 09A0
> MSTPSR9		H'E615 09A4
> MSTPSR10		H'E615 09A8
> MSTPSR11		H'E615 09AC
> 
> SMSTPCR0		H'E615 0130
> SMSTPCR1		H'E615 0134
> SMSTPCR2		H'E615 0138
> SMSTPCR3		H'E615 013C
> SMSTPCR4		H'E615 0140
> SMSTPCR5		H'E615 0144
> SMSTPCR6		H'E615 0148
> SMSTPCR7		H'E615 014C
> SMSTPCR8		H'E615 0990
> SMSTPCR9		H'E615 0994
> SMSTPCR10		H'E615 0998
> SMSTPCR11		H'E615 099C
> 
> I've pondered whether we should use a single device node for all the MSTP 
> clocks, but I don't think it would be very practical. Not only would we need 
> to encode all bit positions, we also would have to encode register offsets in 
> DT. This would become pretty messy in a single node.
> 
> > > +  - clocks: Reference to the parent clocks
> > 
> > How many, and what do they correspond to?
> 
> What about
> 
> - clocks: Reference to the parent clocks, one per output clock. The parents 
> must appear in the same order as the output clocks.

That sounds reasonable.

> 
> > > +  - #clock-cells: Must be 1
> > > +  - clock-output-names: The name of the clocks as free-form strings
> > > +  - renesas,indices: Indices of the gate clocks into the group (0 to 31)
> > 
> > The description of this property doesn't describe half of what it means.
> > I believe something like the below does:
> > 
> > - renesas,indices: A list of clock IDs (single cells), one for each
> >   clock present. Each entry may correspond to a clock-output-names entry
> >   at the same index, and its location in the list defines the
> >   corresponding clock-specifier for the entry.
> 
> I might be mistaken, but doesn't "its location in the list defines the 
> corresponding clock-specifier for the entry" imply that clock specifiers use 
> the location in the list as the clock ID instead of the numerical value of the 
> indices entry ? Each entry in the renesas,indices list corresponds to one 
> clocks entry and one clock-output-names entry, and clock users reference an 
> MSTP clock using the value of its indices entry, not the position of the 
> entry.

Sorry, the code confused me. Having read over it again, I'm even more
confused.

You said the registers were sparesly populated, but the code assumes
that the bits start at 0 and the set of populated bits are contiguous,
which is not what I would describe that as sparse. Are the bits always
contiguous?

I thought the bits in the register were truly sparse (i.e. you could
have two bits which were at either end of the register), and the indices
property allowed you to define the set of bits which were valid.

As far as I can see from cpg_mstp_clocks_init and
cpg_mstp_clock_register, the indices property assings the set of IDs for
consumers to use, and I don't see what the point of that is if we
already have a well-defined linear index (the bit position in the
register) which we could use instead, which also makes the binding and
code simpler.

> 
> > I'd imagine we have a few sparse clocks by now, and we might be able to
> > make this more uniform. But I may be mistaken.
> > 
> > [...]
> > 
> > > +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> > > +{
> > > +	struct mstp_clock *clock = to_mstp_clock(hw);
> > > +	struct mstp_clock_group *group = clock->group;
> > > +	u32 bitmask = BIT(clock->bit_index);
> > > +	unsigned long flags;
> > > +	unsigned int i;
> > > +	u32 value;
> > > +
> > > +	spin_lock_irqsave(&group->lock, flags);
> > > +
> > > +	value = clk_readl(group->smstpcr);
> > > +	if (enable)
> > > +		value &= ~bitmask;
> > > +	else
> > > +		value |= bitmask;
> > > +	clk_writel(value, group->smstpcr);
> > > +
> > > +	spin_unlock_irqrestore(&group->lock, flags);
> > > +
> > > +	if (!enable || !group->mstpsr)
> > > +		return 0;
> > > +
> > > +	for (i = 1000; i > 0; --i) {
> > > +		if (!(clk_readl(group->mstpsr) & bitmask))
> > > +			break;
> > > +		cpu_relax();
> > > +	}
> > 
> > Any particular reason for 1000 times? Is there a known minimum time to
> > switch a clock between disabled and enabled? A comment would be nice.
> 
> There's no particular reason, the datasheet doesn't provide any useful 
> information. I've just copied that value from existing C code.

Any chance it might work without?

Thanks,
Mark.

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

* Re: [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
  2013-11-19 18:19         ` Mark Rutland
  (?)
@ 2013-11-20 21:54           ` Laurent Pinchart
  -1 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-20 21:54 UTC (permalink / raw
  To: Mark Rutland
  Cc: Laurent Pinchart, linux-sh@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, Mike Turquette,
	devicetree@vger.kernel.org

Hi Mark,

On Tuesday 19 November 2013 18:19:36 Mark Rutland wrote:
> On Tue, Nov 19, 2013 at 05:00:40PM +0000, Laurent Pinchart wrote:
> > On Tuesday 19 November 2013 16:28:21 Mark Rutland wrote:
> > > On Tue, Nov 19, 2013 at 02:45:42PM +0000, Laurent Pinchart wrote:
> > > > MSTP clocks are gate clocks controlled through a register that handles
> > > > up to 32 clocks. The register is often sparsely populated.
> > > 
> > > Does that mean some clocks aren't wired up, or that some clocks don't
> > > exist at all?
> > 
> > It means that some of the bits don't control anything.
> > 
> > > What is the behaviour of the unpopulated bits?
> > 
> > According to the datasheet they're reserved, read-only, and read an
> > unspecified value that is to be written back without modification when
> > writing the register.
> 
> Ok.
> 
> > > > Those clocks are found on Renesas ARM SoCs.
> > > > 
> > > > Cc: devicetree@vger.kernel.org
> > > > Signed-off-by: Laurent Pinchart
> > > > <laurent.pinchart+renesas@ideasonboard.com>
> > > > ---
> > > > 
> > > >  .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
> > > >  drivers/clk/shmobile/Makefile                      |   1 +
> > > >  drivers/clk/shmobile/clk-mstp.c                    | 229 ++++++++++++
> > > >  3 files changed, 278 insertions(+)
> > > >  create mode 100644
> > > >  Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > >  create mode 100644 drivers/clk/shmobile/clk-mstp.c
> > > > 
> > > > diff --git
> > > > a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > > new file mode 100644
> > > > index 0000000..126b17e
> > > > --- /dev/null
> > > > +++
> > > > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > > @@ -0,0 +1,48 @@
> > > > +* Renesas CPG Module Stop (MSTP) Clocks
> > > > +
> > > > +The CPG can gate SoC device clocks. The gates are organized in groups
> > > > of up to
> > > > +32 gates.
> > > > +
> > > > +This device tree binding describes a single 32 gate clocks group per
> > > > node.
> > > > +Clocks are referenced by user nodes by the MSTP node phandle and the
> > > > clock
> > > > +index in the group, from 0 to 31.
> > > > +
> > > > +Required Properties:
> > > > +
> > > > +  - compatible: Must be one of the following
> > > > +    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate
> > > > clocks
> > > > +    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate
> > > > clocks
> > > > +    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
> > > > +  - reg: Base address and length of the memory resource used by the
> > > > MSTP
> > > > +    clocks
> > > 
> > > There are two entries in the example, the code seems to assume they are
> > > particular registers, but this implies one.
> > 
> > There can be one or two registers, depending on the hardware. The first
> > register is always required and controls the clocks, the second register
> > is optional (in the sense that it's not implemented for some of the MSTP
> > instances) and reports the clock status.
> 
> Ok. The documentation should note this.

What about

  - reg: Base address and length of the I/O mapped registers used by the MSTP
    clocks. The first register is the clock control register and is mandatory.
    The second register is the clock status register and is optional when not
    implemented in hardware.

> > > Are these not part of a larger bank of registers?
> > 
> > They are. Here's the memory map for the r8a7791 for instance.
> > 
> > MSTPSR0		H'E615 0030
> > MSTPSR1		H'E615 0038
> > MSTPSR2		H'E615 0040
> > MSTPSR3		H'E615 0048
> > MSTPSR4		H'E615 004C
> > MSTPSR5		H'E615 003C
> > MSTPSR6		H'E615 01C0
> > MSTPSR7		H'E615 01C4
> > MSTPSR8		H'E615 09A0
> > MSTPSR9		H'E615 09A4
> > MSTPSR10		H'E615 09A8
> > MSTPSR11		H'E615 09AC
> > 
> > SMSTPCR0		H'E615 0130
> > SMSTPCR1		H'E615 0134
> > SMSTPCR2		H'E615 0138
> > SMSTPCR3		H'E615 013C
> > SMSTPCR4		H'E615 0140
> > SMSTPCR5		H'E615 0144
> > SMSTPCR6		H'E615 0148
> > SMSTPCR7		H'E615 014C
> > SMSTPCR8		H'E615 0990
> > SMSTPCR9		H'E615 0994
> > SMSTPCR10		H'E615 0998
> > SMSTPCR11		H'E615 099C
> > 
> > I've pondered whether we should use a single device node for all the MSTP
> > clocks, but I don't think it would be very practical. Not only would we
> > need to encode all bit positions, we also would have to encode register
> > offsets in DT. This would become pretty messy in a single node.
> > 
> > > > +  - clocks: Reference to the parent clocks
> > > 
> > > How many, and what do they correspond to?
> > 
> > What about
> > 
> > - clocks: Reference to the parent clocks, one per output clock. The
> > parents must appear in the same order as the output clocks.
> 
> That sounds reasonable.
> 
> > > > +  - #clock-cells: Must be 1
> > > > +  - clock-output-names: The name of the clocks as free-form strings
> > > > +  - renesas,indices: Indices of the gate clocks into the group (0 to
> > > > 31)
> > > 
> > > The description of this property doesn't describe half of what it means.
> > > I believe something like the below does:
> > > 
> > > - renesas,indices: A list of clock IDs (single cells), one for each
> > > 
> > >   clock present. Each entry may correspond to a clock-output-names entry
> > >   at the same index, and its location in the list defines the
> > >   corresponding clock-specifier for the entry.
> > 
> > I might be mistaken, but doesn't "its location in the list defines the
> > corresponding clock-specifier for the entry" imply that clock specifiers
> > use the location in the list as the clock ID instead of the numerical
> > value of the indices entry ? Each entry in the renesas,indices list
> > corresponds to one clocks entry and one clock-output-names entry, and
> > clock users reference an MSTP clock using the value of its indices entry,
> > not the position of the entry.
> 
> Sorry, the code confused me. Having read over it again, I'm even more
> confused.
> 
> You said the registers were sparesly populated, but the code assumes
> that the bits start at 0 and the set of populated bits are contiguous,
> which is not what I would describe that as sparse. Are the bits always
> contiguous?

They're not, and the code doesn't assume so. The driver loops over all the 
clocks using the position in the renesas,indices array as the loop counter i. 
It then retrieves the output name, the parent and the index and registers the 
clock. When registration succeeds, the clock is stored in the clks array at 
the index corresponding to the renesas,indices value. The clks array is thus 
sparsely populated, exactly as the MSTP register.

> I thought the bits in the register were truly sparse (i.e. you could
> have two bits which were at either end of the register), and the indices
> property allowed you to define the set of bits which were valid.
> 
> As far as I can see from cpg_mstp_clocks_init and
> cpg_mstp_clock_register, the indices property assings the set of IDs for
> consumers to use, and I don't see what the point of that is if we
> already have a well-defined linear index (the bit position in the
> register) which we could use instead, which also makes the binding and
> code simpler.
> 
> > > I'd imagine we have a few sparse clocks by now, and we might be able to
> > > make this more uniform. But I may be mistaken.
> > > 
> > > [...]
> > > 
> > > > +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> > > > +{
> > > > +	struct mstp_clock *clock = to_mstp_clock(hw);
> > > > +	struct mstp_clock_group *group = clock->group;
> > > > +	u32 bitmask = BIT(clock->bit_index);
> > > > +	unsigned long flags;
> > > > +	unsigned int i;
> > > > +	u32 value;
> > > > +
> > > > +	spin_lock_irqsave(&group->lock, flags);
> > > > +
> > > > +	value = clk_readl(group->smstpcr);
> > > > +	if (enable)
> > > > +		value &= ~bitmask;
> > > > +	else
> > > > +		value |= bitmask;
> > > > +	clk_writel(value, group->smstpcr);
> > > > +
> > > > +	spin_unlock_irqrestore(&group->lock, flags);
> > > > +
> > > > +	if (!enable || !group->mstpsr)
> > > > +		return 0;
> > > > +
> > > > +	for (i = 1000; i > 0; --i) {
> > > > +		if (!(clk_readl(group->mstpsr) & bitmask))
> > > > +			break;
> > > > +		cpu_relax();
> > > > +	}
> > > 
> > > Any particular reason for 1000 times? Is there a known minimum time to
> > > switch a clock between disabled and enabled? A comment would be nice.
> > 
> > There's no particular reason, the datasheet doesn't provide any useful
> > information. I've just copied that value from existing C code.
> 
> Any chance it might work without?

Yes, with roughly a 75% chance :-) Without this look I get a crash around once 
every four times with the video processing devices. Other devices are affected 
as well, but delays in their respective drivers hide the problem.

-- 
Regards,

Laurent Pinchart

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

* [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
@ 2013-11-20 21:54           ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-20 21:54 UTC (permalink / raw
  To: linux-arm-kernel

Hi Mark,

On Tuesday 19 November 2013 18:19:36 Mark Rutland wrote:
> On Tue, Nov 19, 2013 at 05:00:40PM +0000, Laurent Pinchart wrote:
> > On Tuesday 19 November 2013 16:28:21 Mark Rutland wrote:
> > > On Tue, Nov 19, 2013 at 02:45:42PM +0000, Laurent Pinchart wrote:
> > > > MSTP clocks are gate clocks controlled through a register that handles
> > > > up to 32 clocks. The register is often sparsely populated.
> > > 
> > > Does that mean some clocks aren't wired up, or that some clocks don't
> > > exist at all?
> > 
> > It means that some of the bits don't control anything.
> > 
> > > What is the behaviour of the unpopulated bits?
> > 
> > According to the datasheet they're reserved, read-only, and read an
> > unspecified value that is to be written back without modification when
> > writing the register.
> 
> Ok.
> 
> > > > Those clocks are found on Renesas ARM SoCs.
> > > > 
> > > > Cc: devicetree at vger.kernel.org
> > > > Signed-off-by: Laurent Pinchart
> > > > <laurent.pinchart+renesas@ideasonboard.com>
> > > > ---
> > > > 
> > > >  .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
> > > >  drivers/clk/shmobile/Makefile                      |   1 +
> > > >  drivers/clk/shmobile/clk-mstp.c                    | 229 ++++++++++++
> > > >  3 files changed, 278 insertions(+)
> > > >  create mode 100644
> > > >  Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > >  create mode 100644 drivers/clk/shmobile/clk-mstp.c
> > > > 
> > > > diff --git
> > > > a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > > new file mode 100644
> > > > index 0000000..126b17e
> > > > --- /dev/null
> > > > +++
> > > > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > > @@ -0,0 +1,48 @@
> > > > +* Renesas CPG Module Stop (MSTP) Clocks
> > > > +
> > > > +The CPG can gate SoC device clocks. The gates are organized in groups
> > > > of up to
> > > > +32 gates.
> > > > +
> > > > +This device tree binding describes a single 32 gate clocks group per
> > > > node.
> > > > +Clocks are referenced by user nodes by the MSTP node phandle and the
> > > > clock
> > > > +index in the group, from 0 to 31.
> > > > +
> > > > +Required Properties:
> > > > +
> > > > +  - compatible: Must be one of the following
> > > > +    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate
> > > > clocks
> > > > +    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate
> > > > clocks
> > > > +    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
> > > > +  - reg: Base address and length of the memory resource used by the
> > > > MSTP
> > > > +    clocks
> > > 
> > > There are two entries in the example, the code seems to assume they are
> > > particular registers, but this implies one.
> > 
> > There can be one or two registers, depending on the hardware. The first
> > register is always required and controls the clocks, the second register
> > is optional (in the sense that it's not implemented for some of the MSTP
> > instances) and reports the clock status.
> 
> Ok. The documentation should note this.

What about

  - reg: Base address and length of the I/O mapped registers used by the MSTP
    clocks. The first register is the clock control register and is mandatory.
    The second register is the clock status register and is optional when not
    implemented in hardware.

> > > Are these not part of a larger bank of registers?
> > 
> > They are. Here's the memory map for the r8a7791 for instance.
> > 
> > MSTPSR0		H'E615 0030
> > MSTPSR1		H'E615 0038
> > MSTPSR2		H'E615 0040
> > MSTPSR3		H'E615 0048
> > MSTPSR4		H'E615 004C
> > MSTPSR5		H'E615 003C
> > MSTPSR6		H'E615 01C0
> > MSTPSR7		H'E615 01C4
> > MSTPSR8		H'E615 09A0
> > MSTPSR9		H'E615 09A4
> > MSTPSR10		H'E615 09A8
> > MSTPSR11		H'E615 09AC
> > 
> > SMSTPCR0		H'E615 0130
> > SMSTPCR1		H'E615 0134
> > SMSTPCR2		H'E615 0138
> > SMSTPCR3		H'E615 013C
> > SMSTPCR4		H'E615 0140
> > SMSTPCR5		H'E615 0144
> > SMSTPCR6		H'E615 0148
> > SMSTPCR7		H'E615 014C
> > SMSTPCR8		H'E615 0990
> > SMSTPCR9		H'E615 0994
> > SMSTPCR10		H'E615 0998
> > SMSTPCR11		H'E615 099C
> > 
> > I've pondered whether we should use a single device node for all the MSTP
> > clocks, but I don't think it would be very practical. Not only would we
> > need to encode all bit positions, we also would have to encode register
> > offsets in DT. This would become pretty messy in a single node.
> > 
> > > > +  - clocks: Reference to the parent clocks
> > > 
> > > How many, and what do they correspond to?
> > 
> > What about
> > 
> > - clocks: Reference to the parent clocks, one per output clock. The
> > parents must appear in the same order as the output clocks.
> 
> That sounds reasonable.
> 
> > > > +  - #clock-cells: Must be 1
> > > > +  - clock-output-names: The name of the clocks as free-form strings
> > > > +  - renesas,indices: Indices of the gate clocks into the group (0 to
> > > > 31)
> > > 
> > > The description of this property doesn't describe half of what it means.
> > > I believe something like the below does:
> > > 
> > > - renesas,indices: A list of clock IDs (single cells), one for each
> > > 
> > >   clock present. Each entry may correspond to a clock-output-names entry
> > >   at the same index, and its location in the list defines the
> > >   corresponding clock-specifier for the entry.
> > 
> > I might be mistaken, but doesn't "its location in the list defines the
> > corresponding clock-specifier for the entry" imply that clock specifiers
> > use the location in the list as the clock ID instead of the numerical
> > value of the indices entry ? Each entry in the renesas,indices list
> > corresponds to one clocks entry and one clock-output-names entry, and
> > clock users reference an MSTP clock using the value of its indices entry,
> > not the position of the entry.
> 
> Sorry, the code confused me. Having read over it again, I'm even more
> confused.
> 
> You said the registers were sparesly populated, but the code assumes
> that the bits start at 0 and the set of populated bits are contiguous,
> which is not what I would describe that as sparse. Are the bits always
> contiguous?

They're not, and the code doesn't assume so. The driver loops over all the 
clocks using the position in the renesas,indices array as the loop counter i. 
It then retrieves the output name, the parent and the index and registers the 
clock. When registration succeeds, the clock is stored in the clks array at 
the index corresponding to the renesas,indices value. The clks array is thus 
sparsely populated, exactly as the MSTP register.

> I thought the bits in the register were truly sparse (i.e. you could
> have two bits which were at either end of the register), and the indices
> property allowed you to define the set of bits which were valid.
> 
> As far as I can see from cpg_mstp_clocks_init and
> cpg_mstp_clock_register, the indices property assings the set of IDs for
> consumers to use, and I don't see what the point of that is if we
> already have a well-defined linear index (the bit position in the
> register) which we could use instead, which also makes the binding and
> code simpler.
> 
> > > I'd imagine we have a few sparse clocks by now, and we might be able to
> > > make this more uniform. But I may be mistaken.
> > > 
> > > [...]
> > > 
> > > > +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> > > > +{
> > > > +	struct mstp_clock *clock = to_mstp_clock(hw);
> > > > +	struct mstp_clock_group *group = clock->group;
> > > > +	u32 bitmask = BIT(clock->bit_index);
> > > > +	unsigned long flags;
> > > > +	unsigned int i;
> > > > +	u32 value;
> > > > +
> > > > +	spin_lock_irqsave(&group->lock, flags);
> > > > +
> > > > +	value = clk_readl(group->smstpcr);
> > > > +	if (enable)
> > > > +		value &= ~bitmask;
> > > > +	else
> > > > +		value |= bitmask;
> > > > +	clk_writel(value, group->smstpcr);
> > > > +
> > > > +	spin_unlock_irqrestore(&group->lock, flags);
> > > > +
> > > > +	if (!enable || !group->mstpsr)
> > > > +		return 0;
> > > > +
> > > > +	for (i = 1000; i > 0; --i) {
> > > > +		if (!(clk_readl(group->mstpsr) & bitmask))
> > > > +			break;
> > > > +		cpu_relax();
> > > > +	}
> > > 
> > > Any particular reason for 1000 times? Is there a known minimum time to
> > > switch a clock between disabled and enabled? A comment would be nice.
> > 
> > There's no particular reason, the datasheet doesn't provide any useful
> > information. I've just copied that value from existing C code.
> 
> Any chance it might work without?

Yes, with roughly a 75% chance :-) Without this look I get a crash around once 
every four times with the video processing devices. Other devices are affected 
as well, but delays in their respective drivers hide the problem.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
@ 2013-11-20 21:54           ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-20 21:54 UTC (permalink / raw
  To: linux-arm-kernel

Hi Mark,

On Tuesday 19 November 2013 18:19:36 Mark Rutland wrote:
> On Tue, Nov 19, 2013 at 05:00:40PM +0000, Laurent Pinchart wrote:
> > On Tuesday 19 November 2013 16:28:21 Mark Rutland wrote:
> > > On Tue, Nov 19, 2013 at 02:45:42PM +0000, Laurent Pinchart wrote:
> > > > MSTP clocks are gate clocks controlled through a register that handles
> > > > up to 32 clocks. The register is often sparsely populated.
> > > 
> > > Does that mean some clocks aren't wired up, or that some clocks don't
> > > exist at all?
> > 
> > It means that some of the bits don't control anything.
> > 
> > > What is the behaviour of the unpopulated bits?
> > 
> > According to the datasheet they're reserved, read-only, and read an
> > unspecified value that is to be written back without modification when
> > writing the register.
> 
> Ok.
> 
> > > > Those clocks are found on Renesas ARM SoCs.
> > > > 
> > > > Cc: devicetree@vger.kernel.org
> > > > Signed-off-by: Laurent Pinchart
> > > > <laurent.pinchart+renesas@ideasonboard.com>
> > > > ---
> > > > 
> > > >  .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
> > > >  drivers/clk/shmobile/Makefile                      |   1 +
> > > >  drivers/clk/shmobile/clk-mstp.c                    | 229 ++++++++++++
> > > >  3 files changed, 278 insertions(+)
> > > >  create mode 100644
> > > >  Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > >  create mode 100644 drivers/clk/shmobile/clk-mstp.c
> > > > 
> > > > diff --git
> > > > a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > > new file mode 100644
> > > > index 0000000..126b17e
> > > > --- /dev/null
> > > > +++
> > > > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > > @@ -0,0 +1,48 @@
> > > > +* Renesas CPG Module Stop (MSTP) Clocks
> > > > +
> > > > +The CPG can gate SoC device clocks. The gates are organized in groups
> > > > of up to
> > > > +32 gates.
> > > > +
> > > > +This device tree binding describes a single 32 gate clocks group per
> > > > node.
> > > > +Clocks are referenced by user nodes by the MSTP node phandle and the
> > > > clock
> > > > +index in the group, from 0 to 31.
> > > > +
> > > > +Required Properties:
> > > > +
> > > > +  - compatible: Must be one of the following
> > > > +    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate
> > > > clocks
> > > > +    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate
> > > > clocks
> > > > +    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
> > > > +  - reg: Base address and length of the memory resource used by the
> > > > MSTP
> > > > +    clocks
> > > 
> > > There are two entries in the example, the code seems to assume they are
> > > particular registers, but this implies one.
> > 
> > There can be one or two registers, depending on the hardware. The first
> > register is always required and controls the clocks, the second register
> > is optional (in the sense that it's not implemented for some of the MSTP
> > instances) and reports the clock status.
> 
> Ok. The documentation should note this.

What about

  - reg: Base address and length of the I/O mapped registers used by the MSTP
    clocks. The first register is the clock control register and is mandatory.
    The second register is the clock status register and is optional when not
    implemented in hardware.

> > > Are these not part of a larger bank of registers?
> > 
> > They are. Here's the memory map for the r8a7791 for instance.
> > 
> > MSTPSR0		H'E615 0030
> > MSTPSR1		H'E615 0038
> > MSTPSR2		H'E615 0040
> > MSTPSR3		H'E615 0048
> > MSTPSR4		H'E615 004C
> > MSTPSR5		H'E615 003C
> > MSTPSR6		H'E615 01C0
> > MSTPSR7		H'E615 01C4
> > MSTPSR8		H'E615 09A0
> > MSTPSR9		H'E615 09A4
> > MSTPSR10		H'E615 09A8
> > MSTPSR11		H'E615 09AC
> > 
> > SMSTPCR0		H'E615 0130
> > SMSTPCR1		H'E615 0134
> > SMSTPCR2		H'E615 0138
> > SMSTPCR3		H'E615 013C
> > SMSTPCR4		H'E615 0140
> > SMSTPCR5		H'E615 0144
> > SMSTPCR6		H'E615 0148
> > SMSTPCR7		H'E615 014C
> > SMSTPCR8		H'E615 0990
> > SMSTPCR9		H'E615 0994
> > SMSTPCR10		H'E615 0998
> > SMSTPCR11		H'E615 099C
> > 
> > I've pondered whether we should use a single device node for all the MSTP
> > clocks, but I don't think it would be very practical. Not only would we
> > need to encode all bit positions, we also would have to encode register
> > offsets in DT. This would become pretty messy in a single node.
> > 
> > > > +  - clocks: Reference to the parent clocks
> > > 
> > > How many, and what do they correspond to?
> > 
> > What about
> > 
> > - clocks: Reference to the parent clocks, one per output clock. The
> > parents must appear in the same order as the output clocks.
> 
> That sounds reasonable.
> 
> > > > +  - #clock-cells: Must be 1
> > > > +  - clock-output-names: The name of the clocks as free-form strings
> > > > +  - renesas,indices: Indices of the gate clocks into the group (0 to
> > > > 31)
> > > 
> > > The description of this property doesn't describe half of what it means.
> > > I believe something like the below does:
> > > 
> > > - renesas,indices: A list of clock IDs (single cells), one for each
> > > 
> > >   clock present. Each entry may correspond to a clock-output-names entry
> > >   at the same index, and its location in the list defines the
> > >   corresponding clock-specifier for the entry.
> > 
> > I might be mistaken, but doesn't "its location in the list defines the
> > corresponding clock-specifier for the entry" imply that clock specifiers
> > use the location in the list as the clock ID instead of the numerical
> > value of the indices entry ? Each entry in the renesas,indices list
> > corresponds to one clocks entry and one clock-output-names entry, and
> > clock users reference an MSTP clock using the value of its indices entry,
> > not the position of the entry.
> 
> Sorry, the code confused me. Having read over it again, I'm even more
> confused.
> 
> You said the registers were sparesly populated, but the code assumes
> that the bits start at 0 and the set of populated bits are contiguous,
> which is not what I would describe that as sparse. Are the bits always
> contiguous?

They're not, and the code doesn't assume so. The driver loops over all the 
clocks using the position in the renesas,indices array as the loop counter i. 
It then retrieves the output name, the parent and the index and registers the 
clock. When registration succeeds, the clock is stored in the clks array at 
the index corresponding to the renesas,indices value. The clks array is thus 
sparsely populated, exactly as the MSTP register.

> I thought the bits in the register were truly sparse (i.e. you could
> have two bits which were at either end of the register), and the indices
> property allowed you to define the set of bits which were valid.
> 
> As far as I can see from cpg_mstp_clocks_init and
> cpg_mstp_clock_register, the indices property assings the set of IDs for
> consumers to use, and I don't see what the point of that is if we
> already have a well-defined linear index (the bit position in the
> register) which we could use instead, which also makes the binding and
> code simpler.
> 
> > > I'd imagine we have a few sparse clocks by now, and we might be able to
> > > make this more uniform. But I may be mistaken.
> > > 
> > > [...]
> > > 
> > > > +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> > > > +{
> > > > +	struct mstp_clock *clock = to_mstp_clock(hw);
> > > > +	struct mstp_clock_group *group = clock->group;
> > > > +	u32 bitmask = BIT(clock->bit_index);
> > > > +	unsigned long flags;
> > > > +	unsigned int i;
> > > > +	u32 value;
> > > > +
> > > > +	spin_lock_irqsave(&group->lock, flags);
> > > > +
> > > > +	value = clk_readl(group->smstpcr);
> > > > +	if (enable)
> > > > +		value &= ~bitmask;
> > > > +	else
> > > > +		value |= bitmask;
> > > > +	clk_writel(value, group->smstpcr);
> > > > +
> > > > +	spin_unlock_irqrestore(&group->lock, flags);
> > > > +
> > > > +	if (!enable || !group->mstpsr)
> > > > +		return 0;
> > > > +
> > > > +	for (i = 1000; i > 0; --i) {
> > > > +		if (!(clk_readl(group->mstpsr) & bitmask))
> > > > +			break;
> > > > +		cpu_relax();
> > > > +	}
> > > 
> > > Any particular reason for 1000 times? Is there a known minimum time to
> > > switch a clock between disabled and enabled? A comment would be nice.
> > 
> > There's no particular reason, the datasheet doesn't provide any useful
> > information. I've just copied that value from existing C code.
> 
> Any chance it might work without?

Yes, with roughly a 75% chance :-) Without this look I get a crash around once 
every four times with the video processing devices. Other devices are affected 
as well, but delays in their respective drivers hide the problem.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
  2013-11-20 21:54           ` Laurent Pinchart
  (?)
@ 2013-11-27  1:30             ` Laurent Pinchart
  -1 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-27  1:30 UTC (permalink / raw
  To: Mark Rutland
  Cc: devicetree@vger.kernel.org, Laurent Pinchart, Mike Turquette,
	linux-arm-kernel@lists.infradead.org, linux-sh@vger.kernel.org

Hi Mark,

I'd like to send v4 of this series soon, hopefully for the last time. Would 
you be able to reply to the two issues that are still left and discussed below 
? That would be really appreciated.

On Wednesday 20 November 2013 22:54:58 Laurent Pinchart wrote:
> On Tuesday 19 November 2013 18:19:36 Mark Rutland wrote:
> > On Tue, Nov 19, 2013 at 05:00:40PM +0000, Laurent Pinchart wrote:
> > > On Tuesday 19 November 2013 16:28:21 Mark Rutland wrote:
> > > > On Tue, Nov 19, 2013 at 02:45:42PM +0000, Laurent Pinchart wrote:
> > > > > MSTP clocks are gate clocks controlled through a register that
> > > > > handles up to 32 clocks. The register is often sparsely populated.
> > > > 
> > > > Does that mean some clocks aren't wired up, or that some clocks don't
> > > > exist at all?
> > > 
> > > It means that some of the bits don't control anything.
> > > 
> > > > What is the behaviour of the unpopulated bits?
> > > 
> > > According to the datasheet they're reserved, read-only, and read an
> > > unspecified value that is to be written back without modification when
> > > writing the register.
> > 
> > Ok.
> > 
> > > > > Those clocks are found on Renesas ARM SoCs.
> > > > > 
> > > > > Cc: devicetree@vger.kernel.org
> > > > > Signed-off-by: Laurent Pinchart
> > > > > <laurent.pinchart+renesas@ideasonboard.com>
> > > > > ---
> > > > > 
> > > > >  .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
> > > > >  drivers/clk/shmobile/Makefile                      |   1 +
> > > > >  drivers/clk/shmobile/clk-mstp.c                    | 229 ++++++++++
> > > > >  3 files changed, 278 insertions(+)
> > > > >  create mode 100644
> > > > >  Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > > >  create mode 100644 drivers/clk/shmobile/clk-mstp.c
> > > > > 
> > > > > diff --git
> > > > > a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-
> > > > > clocks.txt
> > > > > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-
> > > > > clocks.txt
> > > > > new file mode 100644
> > > > > index 0000000..126b17e
> > > > > --- /dev/null
> > > > > +++
> > > > > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-
> > > > > clocks.txt
> > > > > @@ -0,0 +1,48 @@
> > > > > +* Renesas CPG Module Stop (MSTP) Clocks
> > > > > +
> > > > > +The CPG can gate SoC device clocks. The gates are organized in
> > > > > groups of up to
> > > > > +32 gates.
> > > > > +
> > > > > +This device tree binding describes a single 32 gate clocks group
> > > > > per node.
> > > > > +Clocks are referenced by user nodes by the MSTP node phandle and
> > > > > the clock
> > > > > +index in the group, from 0 to 31.
> > > > > +
> > > > > +Required Properties:
> > > > > +
> > > > > +  - compatible: Must be one of the following
> > > > > +    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP
> > > > > gate clocks
> > > > > +    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP
> > > > > gate clocks
> > > > > +    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
> > > > > +  - reg: Base address and length of the memory resource used by the
> > > > > MSTP
> > > > > +    clocks
> > > > 
> > > > There are two entries in the example, the code seems to assume they
> > > > are particular registers, but this implies one.
> > > 
> > > There can be one or two registers, depending on the hardware. The first
> > > register is always required and controls the clocks, the second register
> > > is optional (in the sense that it's not implemented for some of the MSTP
> > > instances) and reports the clock status.
> > 
> > Ok. The documentation should note this.
> 
> What about
> 
>   - reg: Base address and length of the I/O mapped registers used by the
> MSTP clocks. The first register is the clock control register and is
> mandatory. The second register is the clock status register and is optional
> when not implemented in hardware.
> 
> > > > Are these not part of a larger bank of registers?
> > > 
> > > They are. Here's the memory map for the r8a7791 for instance.
> > > 
> > > MSTPSR0		H'E615 0030
> > > MSTPSR1		H'E615 0038
> > > MSTPSR2		H'E615 0040
> > > MSTPSR3		H'E615 0048
> > > MSTPSR4		H'E615 004C
> > > MSTPSR5		H'E615 003C
> > > MSTPSR6		H'E615 01C0
> > > MSTPSR7		H'E615 01C4
> > > MSTPSR8		H'E615 09A0
> > > MSTPSR9		H'E615 09A4
> > > MSTPSR10		H'E615 09A8
> > > MSTPSR11		H'E615 09AC
> > > 
> > > SMSTPCR0		H'E615 0130
> > > SMSTPCR1		H'E615 0134
> > > SMSTPCR2		H'E615 0138
> > > SMSTPCR3		H'E615 013C
> > > SMSTPCR4		H'E615 0140
> > > SMSTPCR5		H'E615 0144
> > > SMSTPCR6		H'E615 0148
> > > SMSTPCR7		H'E615 014C
> > > SMSTPCR8		H'E615 0990
> > > SMSTPCR9		H'E615 0994
> > > SMSTPCR10		H'E615 0998
> > > SMSTPCR11		H'E615 099C
> > > 
> > > I've pondered whether we should use a single device node for all the
> > > MSTP clocks, but I don't think it would be very practical. Not only
> > > would we need to encode all bit positions, we also would have to encode
> > > register offsets in DT. This would become pretty messy in a single node.
> > > 
> > > > > +  - clocks: Reference to the parent clocks
> > > > 
> > > > How many, and what do they correspond to?
> > > 
> > > What about
> > > 
> > > - clocks: Reference to the parent clocks, one per output clock. The
> > > parents must appear in the same order as the output clocks.
> > 
> > That sounds reasonable.
> > 
> > > > > +  - #clock-cells: Must be 1
> > > > > +  - clock-output-names: The name of the clocks as free-form strings
> > > > > +  - renesas,indices: Indices of the gate clocks into the group (0
> > > > > to 31)
> > > > 
> > > > The description of this property doesn't describe half of what it
> > > > means. I believe something like the below does:
> > > > 
> > > > - renesas,indices: A list of clock IDs (single cells), one for each
> > > >   clock present. Each entry may correspond to a clock-output-names
> > > >   entry at the same index, and its location in the list defines the
> > > >   corresponding clock-specifier for the entry.
> > > 
> > > I might be mistaken, but doesn't "its location in the list defines the
> > > corresponding clock-specifier for the entry" imply that clock specifiers
> > > use the location in the list as the clock ID instead of the numerical
> > > value of the indices entry ? Each entry in the renesas,indices list
> > > corresponds to one clocks entry and one clock-output-names entry, and
> > > clock users reference an MSTP clock using the value of its indices
> > > entry, not the position of the entry.
> > 
> > Sorry, the code confused me. Having read over it again, I'm even more
> > confused.
> > 
> > You said the registers were sparesly populated, but the code assumes
> > that the bits start at 0 and the set of populated bits are contiguous,
> > which is not what I would describe that as sparse. Are the bits always
> > contiguous?
> 
> They're not, and the code doesn't assume so. The driver loops over all the
> clocks using the position in the renesas,indices array as the loop counter
> i. It then retrieves the output name, the parent and the index and
> registers the clock. When registration succeeds, the clock is stored in the
> clks array at the index corresponding to the renesas,indices value. The
> clks array is thus sparsely populated, exactly as the MSTP register.
> 
> > I thought the bits in the register were truly sparse (i.e. you could
> > have two bits which were at either end of the register), and the indices
> > property allowed you to define the set of bits which were valid.
> > 
> > As far as I can see from cpg_mstp_clocks_init and
> > cpg_mstp_clock_register, the indices property assings the set of IDs for
> > consumers to use, and I don't see what the point of that is if we
> > already have a well-defined linear index (the bit position in the
> > register) which we could use instead, which also makes the binding and
> > code simpler.
> > 
> > > > I'd imagine we have a few sparse clocks by now, and we might be able
> > > > to make this more uniform. But I may be mistaken.
> > > > 
> > > > [...]
> > > > 
> > > > > +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> > > > > +{
> > > > > +	struct mstp_clock *clock = to_mstp_clock(hw);
> > > > > +	struct mstp_clock_group *group = clock->group;
> > > > > +	u32 bitmask = BIT(clock->bit_index);
> > > > > +	unsigned long flags;
> > > > > +	unsigned int i;
> > > > > +	u32 value;
> > > > > +
> > > > > +	spin_lock_irqsave(&group->lock, flags);
> > > > > +
> > > > > +	value = clk_readl(group->smstpcr);
> > > > > +	if (enable)
> > > > > +		value &= ~bitmask;
> > > > > +	else
> > > > > +		value |= bitmask;
> > > > > +	clk_writel(value, group->smstpcr);
> > > > > +
> > > > > +	spin_unlock_irqrestore(&group->lock, flags);
> > > > > +
> > > > > +	if (!enable || !group->mstpsr)
> > > > > +		return 0;
> > > > > +
> > > > > +	for (i = 1000; i > 0; --i) {
> > > > > +		if (!(clk_readl(group->mstpsr) & bitmask))
> > > > > +			break;
> > > > > +		cpu_relax();
> > > > > +	}
> > > > 
> > > > Any particular reason for 1000 times? Is there a known minimum time to
> > > > switch a clock between disabled and enabled? A comment would be nice.
> > > 
> > > There's no particular reason, the datasheet doesn't provide any useful
> > > information. I've just copied that value from existing C code.
> > 
> > Any chance it might work without?
> 
> Yes, with roughly a 75% chance :-) Without this look I get a crash around
> once every four times with the video processing devices. Other devices are
> affected as well, but delays in their respective drivers hide the problem.

-- 
Regards,

Laurent Pinchart

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

* [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
@ 2013-11-27  1:30             ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-27  1:30 UTC (permalink / raw
  To: linux-arm-kernel

Hi Mark,

I'd like to send v4 of this series soon, hopefully for the last time. Would 
you be able to reply to the two issues that are still left and discussed below 
? That would be really appreciated.

On Wednesday 20 November 2013 22:54:58 Laurent Pinchart wrote:
> On Tuesday 19 November 2013 18:19:36 Mark Rutland wrote:
> > On Tue, Nov 19, 2013 at 05:00:40PM +0000, Laurent Pinchart wrote:
> > > On Tuesday 19 November 2013 16:28:21 Mark Rutland wrote:
> > > > On Tue, Nov 19, 2013 at 02:45:42PM +0000, Laurent Pinchart wrote:
> > > > > MSTP clocks are gate clocks controlled through a register that
> > > > > handles up to 32 clocks. The register is often sparsely populated.
> > > > 
> > > > Does that mean some clocks aren't wired up, or that some clocks don't
> > > > exist at all?
> > > 
> > > It means that some of the bits don't control anything.
> > > 
> > > > What is the behaviour of the unpopulated bits?
> > > 
> > > According to the datasheet they're reserved, read-only, and read an
> > > unspecified value that is to be written back without modification when
> > > writing the register.
> > 
> > Ok.
> > 
> > > > > Those clocks are found on Renesas ARM SoCs.
> > > > > 
> > > > > Cc: devicetree at vger.kernel.org
> > > > > Signed-off-by: Laurent Pinchart
> > > > > <laurent.pinchart+renesas@ideasonboard.com>
> > > > > ---
> > > > > 
> > > > >  .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
> > > > >  drivers/clk/shmobile/Makefile                      |   1 +
> > > > >  drivers/clk/shmobile/clk-mstp.c                    | 229 ++++++++++
> > > > >  3 files changed, 278 insertions(+)
> > > > >  create mode 100644
> > > > >  Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > > >  create mode 100644 drivers/clk/shmobile/clk-mstp.c
> > > > > 
> > > > > diff --git
> > > > > a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-
> > > > > clocks.txt
> > > > > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-
> > > > > clocks.txt
> > > > > new file mode 100644
> > > > > index 0000000..126b17e
> > > > > --- /dev/null
> > > > > +++
> > > > > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-
> > > > > clocks.txt
> > > > > @@ -0,0 +1,48 @@
> > > > > +* Renesas CPG Module Stop (MSTP) Clocks
> > > > > +
> > > > > +The CPG can gate SoC device clocks. The gates are organized in
> > > > > groups of up to
> > > > > +32 gates.
> > > > > +
> > > > > +This device tree binding describes a single 32 gate clocks group
> > > > > per node.
> > > > > +Clocks are referenced by user nodes by the MSTP node phandle and
> > > > > the clock
> > > > > +index in the group, from 0 to 31.
> > > > > +
> > > > > +Required Properties:
> > > > > +
> > > > > +  - compatible: Must be one of the following
> > > > > +    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP
> > > > > gate clocks
> > > > > +    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP
> > > > > gate clocks
> > > > > +    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
> > > > > +  - reg: Base address and length of the memory resource used by the
> > > > > MSTP
> > > > > +    clocks
> > > > 
> > > > There are two entries in the example, the code seems to assume they
> > > > are particular registers, but this implies one.
> > > 
> > > There can be one or two registers, depending on the hardware. The first
> > > register is always required and controls the clocks, the second register
> > > is optional (in the sense that it's not implemented for some of the MSTP
> > > instances) and reports the clock status.
> > 
> > Ok. The documentation should note this.
> 
> What about
> 
>   - reg: Base address and length of the I/O mapped registers used by the
> MSTP clocks. The first register is the clock control register and is
> mandatory. The second register is the clock status register and is optional
> when not implemented in hardware.
> 
> > > > Are these not part of a larger bank of registers?
> > > 
> > > They are. Here's the memory map for the r8a7791 for instance.
> > > 
> > > MSTPSR0		H'E615 0030
> > > MSTPSR1		H'E615 0038
> > > MSTPSR2		H'E615 0040
> > > MSTPSR3		H'E615 0048
> > > MSTPSR4		H'E615 004C
> > > MSTPSR5		H'E615 003C
> > > MSTPSR6		H'E615 01C0
> > > MSTPSR7		H'E615 01C4
> > > MSTPSR8		H'E615 09A0
> > > MSTPSR9		H'E615 09A4
> > > MSTPSR10		H'E615 09A8
> > > MSTPSR11		H'E615 09AC
> > > 
> > > SMSTPCR0		H'E615 0130
> > > SMSTPCR1		H'E615 0134
> > > SMSTPCR2		H'E615 0138
> > > SMSTPCR3		H'E615 013C
> > > SMSTPCR4		H'E615 0140
> > > SMSTPCR5		H'E615 0144
> > > SMSTPCR6		H'E615 0148
> > > SMSTPCR7		H'E615 014C
> > > SMSTPCR8		H'E615 0990
> > > SMSTPCR9		H'E615 0994
> > > SMSTPCR10		H'E615 0998
> > > SMSTPCR11		H'E615 099C
> > > 
> > > I've pondered whether we should use a single device node for all the
> > > MSTP clocks, but I don't think it would be very practical. Not only
> > > would we need to encode all bit positions, we also would have to encode
> > > register offsets in DT. This would become pretty messy in a single node.
> > > 
> > > > > +  - clocks: Reference to the parent clocks
> > > > 
> > > > How many, and what do they correspond to?
> > > 
> > > What about
> > > 
> > > - clocks: Reference to the parent clocks, one per output clock. The
> > > parents must appear in the same order as the output clocks.
> > 
> > That sounds reasonable.
> > 
> > > > > +  - #clock-cells: Must be 1
> > > > > +  - clock-output-names: The name of the clocks as free-form strings
> > > > > +  - renesas,indices: Indices of the gate clocks into the group (0
> > > > > to 31)
> > > > 
> > > > The description of this property doesn't describe half of what it
> > > > means. I believe something like the below does:
> > > > 
> > > > - renesas,indices: A list of clock IDs (single cells), one for each
> > > >   clock present. Each entry may correspond to a clock-output-names
> > > >   entry at the same index, and its location in the list defines the
> > > >   corresponding clock-specifier for the entry.
> > > 
> > > I might be mistaken, but doesn't "its location in the list defines the
> > > corresponding clock-specifier for the entry" imply that clock specifiers
> > > use the location in the list as the clock ID instead of the numerical
> > > value of the indices entry ? Each entry in the renesas,indices list
> > > corresponds to one clocks entry and one clock-output-names entry, and
> > > clock users reference an MSTP clock using the value of its indices
> > > entry, not the position of the entry.
> > 
> > Sorry, the code confused me. Having read over it again, I'm even more
> > confused.
> > 
> > You said the registers were sparesly populated, but the code assumes
> > that the bits start at 0 and the set of populated bits are contiguous,
> > which is not what I would describe that as sparse. Are the bits always
> > contiguous?
> 
> They're not, and the code doesn't assume so. The driver loops over all the
> clocks using the position in the renesas,indices array as the loop counter
> i. It then retrieves the output name, the parent and the index and
> registers the clock. When registration succeeds, the clock is stored in the
> clks array at the index corresponding to the renesas,indices value. The
> clks array is thus sparsely populated, exactly as the MSTP register.
> 
> > I thought the bits in the register were truly sparse (i.e. you could
> > have two bits which were at either end of the register), and the indices
> > property allowed you to define the set of bits which were valid.
> > 
> > As far as I can see from cpg_mstp_clocks_init and
> > cpg_mstp_clock_register, the indices property assings the set of IDs for
> > consumers to use, and I don't see what the point of that is if we
> > already have a well-defined linear index (the bit position in the
> > register) which we could use instead, which also makes the binding and
> > code simpler.
> > 
> > > > I'd imagine we have a few sparse clocks by now, and we might be able
> > > > to make this more uniform. But I may be mistaken.
> > > > 
> > > > [...]
> > > > 
> > > > > +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> > > > > +{
> > > > > +	struct mstp_clock *clock = to_mstp_clock(hw);
> > > > > +	struct mstp_clock_group *group = clock->group;
> > > > > +	u32 bitmask = BIT(clock->bit_index);
> > > > > +	unsigned long flags;
> > > > > +	unsigned int i;
> > > > > +	u32 value;
> > > > > +
> > > > > +	spin_lock_irqsave(&group->lock, flags);
> > > > > +
> > > > > +	value = clk_readl(group->smstpcr);
> > > > > +	if (enable)
> > > > > +		value &= ~bitmask;
> > > > > +	else
> > > > > +		value |= bitmask;
> > > > > +	clk_writel(value, group->smstpcr);
> > > > > +
> > > > > +	spin_unlock_irqrestore(&group->lock, flags);
> > > > > +
> > > > > +	if (!enable || !group->mstpsr)
> > > > > +		return 0;
> > > > > +
> > > > > +	for (i = 1000; i > 0; --i) {
> > > > > +		if (!(clk_readl(group->mstpsr) & bitmask))
> > > > > +			break;
> > > > > +		cpu_relax();
> > > > > +	}
> > > > 
> > > > Any particular reason for 1000 times? Is there a known minimum time to
> > > > switch a clock between disabled and enabled? A comment would be nice.
> > > 
> > > There's no particular reason, the datasheet doesn't provide any useful
> > > information. I've just copied that value from existing C code.
> > 
> > Any chance it might work without?
> 
> Yes, with roughly a 75% chance :-) Without this look I get a crash around
> once every four times with the video processing devices. Other devices are
> affected as well, but delays in their respective drivers hide the problem.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v3 3/8] clk: shmobile: Add MSTP clock support
@ 2013-11-27  1:30             ` Laurent Pinchart
  0 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2013-11-27  1:30 UTC (permalink / raw
  To: linux-arm-kernel

Hi Mark,

I'd like to send v4 of this series soon, hopefully for the last time. Would 
you be able to reply to the two issues that are still left and discussed below 
? That would be really appreciated.

On Wednesday 20 November 2013 22:54:58 Laurent Pinchart wrote:
> On Tuesday 19 November 2013 18:19:36 Mark Rutland wrote:
> > On Tue, Nov 19, 2013 at 05:00:40PM +0000, Laurent Pinchart wrote:
> > > On Tuesday 19 November 2013 16:28:21 Mark Rutland wrote:
> > > > On Tue, Nov 19, 2013 at 02:45:42PM +0000, Laurent Pinchart wrote:
> > > > > MSTP clocks are gate clocks controlled through a register that
> > > > > handles up to 32 clocks. The register is often sparsely populated.
> > > > 
> > > > Does that mean some clocks aren't wired up, or that some clocks don't
> > > > exist at all?
> > > 
> > > It means that some of the bits don't control anything.
> > > 
> > > > What is the behaviour of the unpopulated bits?
> > > 
> > > According to the datasheet they're reserved, read-only, and read an
> > > unspecified value that is to be written back without modification when
> > > writing the register.
> > 
> > Ok.
> > 
> > > > > Those clocks are found on Renesas ARM SoCs.
> > > > > 
> > > > > Cc: devicetree@vger.kernel.org
> > > > > Signed-off-by: Laurent Pinchart
> > > > > <laurent.pinchart+renesas@ideasonboard.com>
> > > > > ---
> > > > > 
> > > > >  .../bindings/clock/renesas,cpg-mstp-clocks.txt     |  48 +++++
> > > > >  drivers/clk/shmobile/Makefile                      |   1 +
> > > > >  drivers/clk/shmobile/clk-mstp.c                    | 229 ++++++++++
> > > > >  3 files changed, 278 insertions(+)
> > > > >  create mode 100644
> > > > >  Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt
> > > > >  create mode 100644 drivers/clk/shmobile/clk-mstp.c
> > > > > 
> > > > > diff --git
> > > > > a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-
> > > > > clocks.txt
> > > > > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-
> > > > > clocks.txt
> > > > > new file mode 100644
> > > > > index 0000000..126b17e
> > > > > --- /dev/null
> > > > > +++
> > > > > b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-
> > > > > clocks.txt
> > > > > @@ -0,0 +1,48 @@
> > > > > +* Renesas CPG Module Stop (MSTP) Clocks
> > > > > +
> > > > > +The CPG can gate SoC device clocks. The gates are organized in
> > > > > groups of up to
> > > > > +32 gates.
> > > > > +
> > > > > +This device tree binding describes a single 32 gate clocks group
> > > > > per node.
> > > > > +Clocks are referenced by user nodes by the MSTP node phandle and
> > > > > the clock
> > > > > +index in the group, from 0 to 31.
> > > > > +
> > > > > +Required Properties:
> > > > > +
> > > > > +  - compatible: Must be one of the following
> > > > > +    - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP
> > > > > gate clocks
> > > > > +    - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP
> > > > > gate clocks
> > > > > +    - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
> > > > > +  - reg: Base address and length of the memory resource used by the
> > > > > MSTP
> > > > > +    clocks
> > > > 
> > > > There are two entries in the example, the code seems to assume they
> > > > are particular registers, but this implies one.
> > > 
> > > There can be one or two registers, depending on the hardware. The first
> > > register is always required and controls the clocks, the second register
> > > is optional (in the sense that it's not implemented for some of the MSTP
> > > instances) and reports the clock status.
> > 
> > Ok. The documentation should note this.
> 
> What about
> 
>   - reg: Base address and length of the I/O mapped registers used by the
> MSTP clocks. The first register is the clock control register and is
> mandatory. The second register is the clock status register and is optional
> when not implemented in hardware.
> 
> > > > Are these not part of a larger bank of registers?
> > > 
> > > They are. Here's the memory map for the r8a7791 for instance.
> > > 
> > > MSTPSR0		H'E615 0030
> > > MSTPSR1		H'E615 0038
> > > MSTPSR2		H'E615 0040
> > > MSTPSR3		H'E615 0048
> > > MSTPSR4		H'E615 004C
> > > MSTPSR5		H'E615 003C
> > > MSTPSR6		H'E615 01C0
> > > MSTPSR7		H'E615 01C4
> > > MSTPSR8		H'E615 09A0
> > > MSTPSR9		H'E615 09A4
> > > MSTPSR10		H'E615 09A8
> > > MSTPSR11		H'E615 09AC
> > > 
> > > SMSTPCR0		H'E615 0130
> > > SMSTPCR1		H'E615 0134
> > > SMSTPCR2		H'E615 0138
> > > SMSTPCR3		H'E615 013C
> > > SMSTPCR4		H'E615 0140
> > > SMSTPCR5		H'E615 0144
> > > SMSTPCR6		H'E615 0148
> > > SMSTPCR7		H'E615 014C
> > > SMSTPCR8		H'E615 0990
> > > SMSTPCR9		H'E615 0994
> > > SMSTPCR10		H'E615 0998
> > > SMSTPCR11		H'E615 099C
> > > 
> > > I've pondered whether we should use a single device node for all the
> > > MSTP clocks, but I don't think it would be very practical. Not only
> > > would we need to encode all bit positions, we also would have to encode
> > > register offsets in DT. This would become pretty messy in a single node.
> > > 
> > > > > +  - clocks: Reference to the parent clocks
> > > > 
> > > > How many, and what do they correspond to?
> > > 
> > > What about
> > > 
> > > - clocks: Reference to the parent clocks, one per output clock. The
> > > parents must appear in the same order as the output clocks.
> > 
> > That sounds reasonable.
> > 
> > > > > +  - #clock-cells: Must be 1
> > > > > +  - clock-output-names: The name of the clocks as free-form strings
> > > > > +  - renesas,indices: Indices of the gate clocks into the group (0
> > > > > to 31)
> > > > 
> > > > The description of this property doesn't describe half of what it
> > > > means. I believe something like the below does:
> > > > 
> > > > - renesas,indices: A list of clock IDs (single cells), one for each
> > > >   clock present. Each entry may correspond to a clock-output-names
> > > >   entry at the same index, and its location in the list defines the
> > > >   corresponding clock-specifier for the entry.
> > > 
> > > I might be mistaken, but doesn't "its location in the list defines the
> > > corresponding clock-specifier for the entry" imply that clock specifiers
> > > use the location in the list as the clock ID instead of the numerical
> > > value of the indices entry ? Each entry in the renesas,indices list
> > > corresponds to one clocks entry and one clock-output-names entry, and
> > > clock users reference an MSTP clock using the value of its indices
> > > entry, not the position of the entry.
> > 
> > Sorry, the code confused me. Having read over it again, I'm even more
> > confused.
> > 
> > You said the registers were sparesly populated, but the code assumes
> > that the bits start at 0 and the set of populated bits are contiguous,
> > which is not what I would describe that as sparse. Are the bits always
> > contiguous?
> 
> They're not, and the code doesn't assume so. The driver loops over all the
> clocks using the position in the renesas,indices array as the loop counter
> i. It then retrieves the output name, the parent and the index and
> registers the clock. When registration succeeds, the clock is stored in the
> clks array at the index corresponding to the renesas,indices value. The
> clks array is thus sparsely populated, exactly as the MSTP register.
> 
> > I thought the bits in the register were truly sparse (i.e. you could
> > have two bits which were at either end of the register), and the indices
> > property allowed you to define the set of bits which were valid.
> > 
> > As far as I can see from cpg_mstp_clocks_init and
> > cpg_mstp_clock_register, the indices property assings the set of IDs for
> > consumers to use, and I don't see what the point of that is if we
> > already have a well-defined linear index (the bit position in the
> > register) which we could use instead, which also makes the binding and
> > code simpler.
> > 
> > > > I'd imagine we have a few sparse clocks by now, and we might be able
> > > > to make this more uniform. But I may be mistaken.
> > > > 
> > > > [...]
> > > > 
> > > > > +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
> > > > > +{
> > > > > +	struct mstp_clock *clock = to_mstp_clock(hw);
> > > > > +	struct mstp_clock_group *group = clock->group;
> > > > > +	u32 bitmask = BIT(clock->bit_index);
> > > > > +	unsigned long flags;
> > > > > +	unsigned int i;
> > > > > +	u32 value;
> > > > > +
> > > > > +	spin_lock_irqsave(&group->lock, flags);
> > > > > +
> > > > > +	value = clk_readl(group->smstpcr);
> > > > > +	if (enable)
> > > > > +		value &= ~bitmask;
> > > > > +	else
> > > > > +		value |= bitmask;
> > > > > +	clk_writel(value, group->smstpcr);
> > > > > +
> > > > > +	spin_unlock_irqrestore(&group->lock, flags);
> > > > > +
> > > > > +	if (!enable || !group->mstpsr)
> > > > > +		return 0;
> > > > > +
> > > > > +	for (i = 1000; i > 0; --i) {
> > > > > +		if (!(clk_readl(group->mstpsr) & bitmask))
> > > > > +			break;
> > > > > +		cpu_relax();
> > > > > +	}
> > > > 
> > > > Any particular reason for 1000 times? Is there a known minimum time to
> > > > switch a clock between disabled and enabled? A comment would be nice.
> > > 
> > > There's no particular reason, the datasheet doesn't provide any useful
> > > information. I've just copied that value from existing C code.
> > 
> > Any chance it might work without?
> 
> Yes, with roughly a 75% chance :-) Without this look I get a crash around
> once every four times with the video processing devices. Other devices are
> affected as well, but delays in their respective drivers hide the problem.

-- 
Regards,

Laurent Pinchart


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

* [PATCH v3 5/8] ARM: shmobile: r8a7791: Add default PCIe bus clock
  2013-11-19 14:45   ` Laurent Pinchart
  (?)
@ 2014-06-13  9:37   ` Phil Edworthy
  -1 siblings, 0 replies; 41+ messages in thread
From: Phil Edworthy @ 2014-06-13  9:37 UTC (permalink / raw
  To: linux-sh

This patch adds a default PCIe bus clock node.

Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com>
---
v3:
 - By default, disable the PCIe bus clock

v2:
 - Use a default PCIe bus clock in the device's dtsi

 arch/arm/boot/dts/r8a7791.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index 1e644eb..7c4f7c7 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -532,6 +532,15 @@
 			clock-output-names = "extal";
 		};
 
+		/* External PCIe clock - can be overridden by the board */
+		pcie_bus_clk: pcie_bus_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <100000000>;
+			clock-output-names = "pcie_bus";
+			status = "disabled";
+		};
+
 		/* Special CPG clocks */
 		cpg_clocks: cpg_clocks@e6150000 {
 			compatible = "renesas,r8a7791-cpg-clocks",
-- 
2.0.0


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

* Re: [PATCH v3 5/8] ARM: shmobile: r8a7791: Add default PCIe bus clock
  2013-11-19 14:45   ` Laurent Pinchart
  (?)
  (?)
@ 2014-06-13 10:46   ` Laurent Pinchart
  -1 siblings, 0 replies; 41+ messages in thread
From: Laurent Pinchart @ 2014-06-13 10:46 UTC (permalink / raw
  To: linux-sh

Hi Phil,

Thank you for the patch.

On Friday 13 June 2014 10:37:19 Phil Edworthy wrote:
> This patch adds a default PCIe bus clock node.
> 
> Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com>

Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
> v3:
>  - By default, disable the PCIe bus clock
> 
> v2:
>  - Use a default PCIe bus clock in the device's dtsi
> 
>  arch/arm/boot/dts/r8a7791.dtsi | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
> index 1e644eb..7c4f7c7 100644
> --- a/arch/arm/boot/dts/r8a7791.dtsi
> +++ b/arch/arm/boot/dts/r8a7791.dtsi
> @@ -532,6 +532,15 @@
>  			clock-output-names = "extal";
>  		};
> 
> +		/* External PCIe clock - can be overridden by the board */
> +		pcie_bus_clk: pcie_bus_clk {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <100000000>;
> +			clock-output-names = "pcie_bus";
> +			status = "disabled";
> +		};
> +
>  		/* Special CPG clocks */
>  		cpg_clocks: cpg_clocks@e6150000 {
>  			compatible = "renesas,r8a7791-cpg-clocks",

-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH v3 5/8] ARM: shmobile: r8a7791: Add default PCIe bus clock
  2013-11-19 14:45   ` Laurent Pinchart
                     ` (2 preceding siblings ...)
  (?)
@ 2014-06-16  0:56   ` Simon Horman
  -1 siblings, 0 replies; 41+ messages in thread
From: Simon Horman @ 2014-06-16  0:56 UTC (permalink / raw
  To: linux-sh

On Fri, Jun 13, 2014 at 10:37:19AM +0100, Phil Edworthy wrote:
> This patch adds a default PCIe bus clock node.
> 
> Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com>
> ---
> v3:
>  - By default, disable the PCIe bus clock
> 
> v2:
>  - Use a default PCIe bus clock in the device's dtsi
> 
>  arch/arm/boot/dts/r8a7791.dtsi | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
> index 1e644eb..7c4f7c7 100644
> --- a/arch/arm/boot/dts/r8a7791.dtsi
> +++ b/arch/arm/boot/dts/r8a7791.dtsi
> @@ -532,6 +532,15 @@
>  			clock-output-names = "extal";
>  		};
>  
> +		/* External PCIe clock - can be overridden by the board */
> +		pcie_bus_clk: pcie_bus_clk {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <100000000>;
> +			clock-output-names = "pcie_bus";
> +			status = "disabled";
> +		};
> +
>  		/* Special CPG clocks */
>  		cpg_clocks: cpg_clocks@e6150000 {
>  			compatible = "renesas,r8a7791-cpg-clocks",
> -- 
> 2.0.0
> 


Hi Phil,

I encountered a minor conflict when applying this patch.
The version that I have queued-up is below, please check that it is correct.

From: Phil Edworthy <phil.edworthy@renesas.com>

[PATCH] ARM: shmobile: r8a7791: Add default PCIe bus clock

This patch adds a default PCIe bus clock node.

Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
[horms+renesas@verge.net.au: resolved conflict]
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 arch/arm/boot/dts/r8a7791.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index a15bf7a..7f7eda7 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -555,6 +555,15 @@
 			clock-output-names = "audio_clk_c";
 		};
 
+		/* External PCIe clock - can be overridden by the board */
+		pcie_bus_clk: pcie_bus_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <100000000>;
+			clock-output-names = "pcie_bus";
+			status = "disabled";
+		};
+
 		/* Special CPG clocks */
 		cpg_clocks: cpg_clocks@e6150000 {
 			compatible = "renesas,r8a7791-cpg-clocks",
-- 
2.0.0.rc2


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

* RE: [PATCH v3 5/8] ARM: shmobile: r8a7791: Add default PCIe bus clock
  2013-11-19 14:45   ` Laurent Pinchart
                     ` (3 preceding siblings ...)
  (?)
@ 2014-06-16  8:03   ` Phil Edworthy
  -1 siblings, 0 replies; 41+ messages in thread
From: Phil Edworthy @ 2014-06-16  8:03 UTC (permalink / raw
  To: linux-sh

Hi Simon,

On 16 June 2014 01:56, Simon wrote:
> On Fri, Jun 13, 2014 at 10:37:19AM +0100, Phil Edworthy wrote:
> > This patch adds a default PCIe bus clock node.
> >
> > Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com>
> > ---
> > v3:
> >  - By default, disable the PCIe bus clock
> >
> > v2:
> >  - Use a default PCIe bus clock in the device's dtsi
> >
> >  arch/arm/boot/dts/r8a7791.dtsi | 9 +++++++++
> >  1 file changed, 9 insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/r8a7791.dtsi
> b/arch/arm/boot/dts/r8a7791.dtsi
> > index 1e644eb..7c4f7c7 100644
> > --- a/arch/arm/boot/dts/r8a7791.dtsi
> > +++ b/arch/arm/boot/dts/r8a7791.dtsi
> > @@ -532,6 +532,15 @@
> >  			clock-output-names = "extal";
> >  		};
> >
> > +		/* External PCIe clock - can be overridden by the board */
> > +		pcie_bus_clk: pcie_bus_clk {
> > +			compatible = "fixed-clock";
> > +			#clock-cells = <0>;
> > +			clock-frequency = <100000000>;
> > +			clock-output-names = "pcie_bus";
> > +			status = "disabled";
> > +		};
> > +
> >  		/* Special CPG clocks */
> >  		cpg_clocks: cpg_clocks@e6150000 {
> >  			compatible = "renesas,r8a7791-cpg-clocks",
> > --
> > 2.0.0
> >
> 
> 
> Hi Phil,
> 
> I encountered a minor conflict when applying this patch.
> The version that I have queued-up is below, please check that it is correct.
Yes, that's fine.

Thanks
Phil

> From: Phil Edworthy <phil.edworthy@renesas.com>
> 
> [PATCH] ARM: shmobile: r8a7791: Add default PCIe bus clock
> 
> This patch adds a default PCIe bus clock node.
> 
> Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com>
> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> [horms+renesas@verge.net.au: resolved conflict]
> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
> ---
>  arch/arm/boot/dts/r8a7791.dtsi | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/r8a7791.dtsi
> b/arch/arm/boot/dts/r8a7791.dtsi
> index a15bf7a..7f7eda7 100644
> --- a/arch/arm/boot/dts/r8a7791.dtsi
> +++ b/arch/arm/boot/dts/r8a7791.dtsi
> @@ -555,6 +555,15 @@
>  			clock-output-names = "audio_clk_c";
>  		};
> 
> +		/* External PCIe clock - can be overridden by the board */
> +		pcie_bus_clk: pcie_bus_clk {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <100000000>;
> +			clock-output-names = "pcie_bus";
> +			status = "disabled";
> +		};
> +
>  		/* Special CPG clocks */
>  		cpg_clocks: cpg_clocks@e6150000 {
>  			compatible = "renesas,r8a7791-cpg-clocks",
> --
> 2.0.0.rc2


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

end of thread, other threads:[~2014-06-16  8:03 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-19 14:45 [PATCH v3 0/8] Renesas R-Car Gen2 Common Clock Framework support Laurent Pinchart
2013-11-19 14:45 ` Laurent Pinchart
2013-11-19 14:45 ` Laurent Pinchart
2013-11-19 14:45 ` [PATCH v3 1/8] clk: shmobile: Add R-Car Gen2 clocks support Laurent Pinchart
2013-11-19 14:45   ` Laurent Pinchart
2013-11-19 14:45   ` Laurent Pinchart
2013-11-19 14:45 ` [PATCH v3 2/8] clk: shmobile: Add DIV6 clock support Laurent Pinchart
2013-11-19 14:45   ` Laurent Pinchart
2013-11-19 14:45   ` Laurent Pinchart
2013-11-19 14:45 ` [PATCH v3 3/8] clk: shmobile: Add MSTP " Laurent Pinchart
2013-11-19 14:45   ` Laurent Pinchart
2013-11-19 14:45   ` Laurent Pinchart
2013-11-19 16:28   ` Mark Rutland
2013-11-19 16:28     ` Mark Rutland
2013-11-19 16:28     ` Mark Rutland
2013-11-19 17:00     ` Laurent Pinchart
2013-11-19 17:00       ` Laurent Pinchart
2013-11-19 17:00       ` Laurent Pinchart
2013-11-19 18:19       ` Mark Rutland
2013-11-19 18:19         ` Mark Rutland
2013-11-19 18:19         ` Mark Rutland
2013-11-20 21:54         ` Laurent Pinchart
2013-11-20 21:54           ` Laurent Pinchart
2013-11-20 21:54           ` Laurent Pinchart
2013-11-27  1:30           ` Laurent Pinchart
2013-11-27  1:30             ` Laurent Pinchart
2013-11-27  1:30             ` Laurent Pinchart
2013-11-19 14:45 ` [PATCH v3 4/8] ARM: shmobile: r8a7790: Add clock index macros for DT sources Laurent Pinchart
2013-11-19 14:45   ` Laurent Pinchart
2013-11-19 14:45 ` [PATCH v3 5/8] ARM: shmobile: r8a7791: " Laurent Pinchart
2013-11-19 14:45   ` Laurent Pinchart
2014-06-13  9:37   ` [PATCH v3 5/8] ARM: shmobile: r8a7791: Add default PCIe bus clock Phil Edworthy
2014-06-13 10:46   ` Laurent Pinchart
2014-06-16  0:56   ` Simon Horman
2014-06-16  8:03   ` Phil Edworthy
2013-11-19 14:45 ` [PATCH v3 6/8] ARM: shmobile: r8a7790: Add clocks Laurent Pinchart
2013-11-19 14:45   ` Laurent Pinchart
2013-11-19 14:45 ` [PATCH v3 7/8] ARM: shmobile: r8a7790: Reference clocks Laurent Pinchart
2013-11-19 14:45   ` Laurent Pinchart
2013-11-19 14:45 ` [PATCH v3 8/8] ARM: shmobile: r8a7791: Add clocks Laurent Pinchart
2013-11-19 14:45   ` Laurent Pinchart

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.