linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v8 0/5] arm: Base support for Renesas RZN1D-DB Board
@ 2018-06-05  8:29 Michel Pollet
  2018-06-05  8:29 ` [PATCH v8 1/5] dt-bindings: Add the r9a06g032-sysctrl.h file Michel Pollet
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Michel Pollet @ 2018-06-05  8:29 UTC (permalink / raw)
  To: linux-renesas-soc, Simon Horman
  Cc: phil.edworthy, Michel Pollet, Michel Pollet, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	linux-clk, devicetree, linux-kernel

This series adds the plain basic support for booting a bare
kernel on the RZ/N1D-DB Board. It's been trimmed to the strict
minimum as a 'base', further patches that could add the
rest of the support.

Note on the clock driver: Current usage of the clocks on Linux
involves Linux 'claiming' all of them, disabling the one it doesn't
need and so on.
On *this* architecture it can't be done, there is at least one other
OS running on the CM3 core that claims it's own clock; Linux can claim
some others but definitely not start disabling stuff it isn't supposed to.

Thanks for the comments on the previous versions!

v8:
 + Added Reviewed mentions as appropriate.
 + Moved some of the clocks #defines into the driver
 + Tweaked the pointer arithmetics in the clock driver.
 + Removed clk_readl/writel
 + Use CLK_IS_CRITICAL instead of my own flag
 + Also added that critical section to the dualgate object.
 + Few other nitpicks fixed.
 + Rebased on next-20180604
v7:
 + Removed mention of 'rz[/]n1' from everywhere.
 + Removed unwanted documentation.
 + Renamed clock node back to sysctrl.
 + Renamed rzn1-clocks.h to r9a06g032-sysctrl.h to match
 + Made the clock driver claim the sysctrl node.
 + Fixed a couple of 'sparse' warning in the clock driver.
v6:
 + Fix for suggestion by Geert Uytterhoeven
 + Removed "renesas,rzn1" from the board bindings
 + Removed patches already merged.
 + Removed reboot driver
 + Added a whole clock infrastructure.
 + Rebased on next-20180517
v5:
 + Given the problems I have with getting in some structure around the
   sysctrl block, I've removed the MFD, I've now attached the reboot
   driver on it's  own pair of registers.
 + Rebased on next-20180417
v4:
 + Fixes for suggestions by Simon Horman
 + Fixes for suggestions by Jacopo Mondi
 + Fixes for suggestions by Geert Uytterhoeven
 + Renamed the r9a06g0xx.dtsi file, given up on trying to get a family
   common file in, so dropped potential RZ/N1S support and now only
   focus on RZ/N1D for this patchset.
 + Added 'always-on' to the architected timer node, because it is.
 + Added ARCH_R9A06G032, to match others patterns like RCAR
 + Sorted the .dts files, added empty lines as required.
 + Fixed patch prefixes to match git-log for bindings&dts
 + Merged board .dts & Makefile changes together
 + Rebased on next-20180410
v3:
 + Fixes for suggestions by Geert Uytterhoeven
 + Removed SoC Specific renesas,r9a06g032-xxx, as it's not needed for now.
 + Kept renesas,rzn1 as a family/generic for this family.
 + Fixed a couple of the commit messages.
 + Added Geert's Reviewed-By where appropriate.
v2:
 + Fixes for suggestions by Simon Horman
 + Fixes for suggestions by Rob Herring
 + Fixes for suggestions by Geert Uytterhoeven
 + Removed the mach file
 + Added a MFD base for the sysctrl block
 + Added a regmap based sub driver for the reboot handler
 + Renamed the files to match shmobile conventions
 + Adapted the compatible= strings to reflect 'family' vs 'part'
   distinction.
 + Removed the sysctrl.h file entirelly.
 + Fixed every warnings from the DTC compiler on W=12 mode.
 + Split the device-tree patches from the code.

Michel Pollet (5):
  dt-bindings: Add the r9a06g032-sysctrl.h file
  dt-bindings: clock: renesas,r9a06g032-sysctrl: documentation
  ARM: dts: Renesas R9A06G032 base device tree file
  ARM: dts: Renesas RZN1D-DB Board base file
  clk: renesas: Renesas R9A06G032 clock driver

 .../bindings/clock/renesas,r9a06g032-sysctrl.txt   |  32 +
 arch/arm/boot/dts/Makefile                         |   1 +
 arch/arm/boot/dts/r9a06g032-rzn1d400-db.dts        |  28 +
 arch/arm/boot/dts/r9a06g032.dtsi                   |  86 +++
 drivers/clk/renesas/Kconfig                        |   6 +
 drivers/clk/renesas/Makefile                       |   1 +
 drivers/clk/renesas/r9a06g032-clocks.c             | 853 +++++++++++++++++++++
 include/dt-bindings/clock/r9a06g032-sysctrl.h      | 148 ++++
 8 files changed, 1155 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.txt
 create mode 100644 arch/arm/boot/dts/r9a06g032-rzn1d400-db.dts
 create mode 100644 arch/arm/boot/dts/r9a06g032.dtsi
 create mode 100644 drivers/clk/renesas/r9a06g032-clocks.c
 create mode 100644 include/dt-bindings/clock/r9a06g032-sysctrl.h

-- 
2.7.4

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

* [PATCH v8 1/5] dt-bindings: Add the r9a06g032-sysctrl.h file
  2018-06-05  8:29 [PATCH v8 0/5] arm: Base support for Renesas RZN1D-DB Board Michel Pollet
@ 2018-06-05  8:29 ` Michel Pollet
  2018-06-05  8:29 ` [PATCH v8 2/5] dt-bindings: clock: renesas,r9a06g032-sysctrl: documentation Michel Pollet
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 13+ messages in thread
From: Michel Pollet @ 2018-06-05  8:29 UTC (permalink / raw)
  To: linux-renesas-soc, Simon Horman
  Cc: phil.edworthy, Michel Pollet, Michel Pollet, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	linux-clk, devicetree, linux-kernel

This adds the constants necessary to use the renesas,r9a06g032-sysctrl node.

Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 include/dt-bindings/clock/r9a06g032-sysctrl.h | 148 ++++++++++++++++++++++++++
 1 file changed, 148 insertions(+)
 create mode 100644 include/dt-bindings/clock/r9a06g032-sysctrl.h

diff --git a/include/dt-bindings/clock/r9a06g032-sysctrl.h b/include/dt-bindings/clock/r9a06g032-sysctrl.h
new file mode 100644
index 0000000..90c0f3d
--- /dev/null
+++ b/include/dt-bindings/clock/r9a06g032-sysctrl.h
@@ -0,0 +1,148 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * R9A06G032 sysctrl IDs
+ *
+ * Copyright (C) 2018 Renesas Electronics Europe Limited
+ *
+ * Michel Pollet <michel.pollet@bp.renesas.com>, <buserror@gmail.com>
+ */
+
+#ifndef __DT_BINDINGS_R9A06G032_SYSCTRL_H__
+#define __DT_BINDINGS_R9A06G032_SYSCTRL_H__
+
+#define R9A06G032_CLK_PLL_USB		1
+#define R9A06G032_CLK_48		1	/* AKA CLK_PLL_USB */
+#define R9A06G032_MSEBIS_CLK		3	/* AKA CLKOUT_D16 */
+#define R9A06G032_MSEBIM_CLK		3	/* AKA CLKOUT_D16 */
+#define R9A06G032_CLK_DDRPHY_PLLCLK	5	/* AKA CLKOUT_D1OR2 */
+#define R9A06G032_CLK50			6	/* AKA CLKOUT_D20 */
+#define R9A06G032_CLK25			7	/* AKA CLKOUT_D40 */
+#define R9A06G032_CLK125		9	/* AKA CLKOUT_D8 */
+#define R9A06G032_CLK_P5_PG1		17	/* AKA DIV_P5_PG */
+#define R9A06G032_CLK_REF_SYNC		21	/* AKA DIV_REF_SYNC */
+#define R9A06G032_CLK_25_PG4		26
+#define R9A06G032_CLK_25_PG5		27
+#define R9A06G032_CLK_25_PG6		28
+#define R9A06G032_CLK_25_PG7		29
+#define R9A06G032_CLK_25_PG8		30
+#define R9A06G032_CLK_ADC		31
+#define R9A06G032_CLK_ECAT100		32
+#define R9A06G032_CLK_HSR100		33
+#define R9A06G032_CLK_I2C0		34
+#define R9A06G032_CLK_I2C1		35
+#define R9A06G032_CLK_MII_REF		36
+#define R9A06G032_CLK_NAND		37
+#define R9A06G032_CLK_NOUSBP2_PG6	38
+#define R9A06G032_CLK_P1_PG2		39
+#define R9A06G032_CLK_P1_PG3		40
+#define R9A06G032_CLK_P1_PG4		41
+#define R9A06G032_CLK_P4_PG3		42
+#define R9A06G032_CLK_P4_PG4		43
+#define R9A06G032_CLK_P6_PG1		44
+#define R9A06G032_CLK_P6_PG2		45
+#define R9A06G032_CLK_P6_PG3		46
+#define R9A06G032_CLK_P6_PG4		47
+#define R9A06G032_CLK_PCI_USB		48
+#define R9A06G032_CLK_QSPI0		49
+#define R9A06G032_CLK_QSPI1		50
+#define R9A06G032_CLK_RGMII_REF		51
+#define R9A06G032_CLK_RMII_REF		52
+#define R9A06G032_CLK_SDIO0		53
+#define R9A06G032_CLK_SDIO1		54
+#define R9A06G032_CLK_SERCOS100		55
+#define R9A06G032_CLK_SLCD		56
+#define R9A06G032_CLK_SPI0		57
+#define R9A06G032_CLK_SPI1		58
+#define R9A06G032_CLK_SPI2		59
+#define R9A06G032_CLK_SPI3		60
+#define R9A06G032_CLK_SPI4		61
+#define R9A06G032_CLK_SPI5		62
+#define R9A06G032_CLK_SWITCH		63
+#define R9A06G032_HCLK_ECAT125		65
+#define R9A06G032_HCLK_PINCONFIG	66
+#define R9A06G032_HCLK_SERCOS		67
+#define R9A06G032_HCLK_SGPIO2		68
+#define R9A06G032_HCLK_SGPIO3		69
+#define R9A06G032_HCLK_SGPIO4		70
+#define R9A06G032_HCLK_TIMER0		71
+#define R9A06G032_HCLK_TIMER1		72
+#define R9A06G032_HCLK_USBF		73
+#define R9A06G032_HCLK_USBH		74
+#define R9A06G032_HCLK_USBPM		75
+#define R9A06G032_CLK_48_PG_F		76
+#define R9A06G032_CLK_48_PG4		77
+#define R9A06G032_CLK_DDRPHY_PCLK	81	/* AKA CLK_REF_SYNC_D4 */
+#define R9A06G032_CLK_FW		81	/* AKA CLK_REF_SYNC_D4 */
+#define R9A06G032_CLK_CRYPTO		81	/* AKA CLK_REF_SYNC_D4 */
+#define R9A06G032_CLK_A7MP		84	/* AKA DIV_CA7 */
+#define R9A06G032_HCLK_CAN0		85
+#define R9A06G032_HCLK_CAN1		86
+#define R9A06G032_HCLK_DELTASIGMA	87
+#define R9A06G032_HCLK_PWMPTO		88
+#define R9A06G032_HCLK_RSV		89
+#define R9A06G032_HCLK_SGPIO0		90
+#define R9A06G032_HCLK_SGPIO1		91
+#define R9A06G032_RTOS_MDC		92
+#define R9A06G032_CLK_CM3		93
+#define R9A06G032_CLK_DDRC		94
+#define R9A06G032_CLK_ECAT25		95
+#define R9A06G032_CLK_HSR50		96
+#define R9A06G032_CLK_HW_RTOS		97
+#define R9A06G032_CLK_SERCOS50		98
+#define R9A06G032_HCLK_ADC		99
+#define R9A06G032_HCLK_CM3		100
+#define R9A06G032_HCLK_CRYPTO_EIP150	101
+#define R9A06G032_HCLK_CRYPTO_EIP93	102
+#define R9A06G032_HCLK_DDRC		103
+#define R9A06G032_HCLK_DMA0		104
+#define R9A06G032_HCLK_DMA1		105
+#define R9A06G032_HCLK_GMAC0		106
+#define R9A06G032_HCLK_GMAC1		107
+#define R9A06G032_HCLK_GPIO0		108
+#define R9A06G032_HCLK_GPIO1		109
+#define R9A06G032_HCLK_GPIO2		110
+#define R9A06G032_HCLK_HSR		111
+#define R9A06G032_HCLK_I2C0		112
+#define R9A06G032_HCLK_I2C1		113
+#define R9A06G032_HCLK_LCD		114
+#define R9A06G032_HCLK_MSEBI_M		115
+#define R9A06G032_HCLK_MSEBI_S		116
+#define R9A06G032_HCLK_NAND		117
+#define R9A06G032_HCLK_PG_I		118
+#define R9A06G032_HCLK_PG19		119
+#define R9A06G032_HCLK_PG20		120
+#define R9A06G032_HCLK_PG3		121
+#define R9A06G032_HCLK_PG4		122
+#define R9A06G032_HCLK_QSPI0		123
+#define R9A06G032_HCLK_QSPI1		124
+#define R9A06G032_HCLK_ROM		125
+#define R9A06G032_HCLK_RTC		126
+#define R9A06G032_HCLK_SDIO0		127
+#define R9A06G032_HCLK_SDIO1		128
+#define R9A06G032_HCLK_SEMAP		129
+#define R9A06G032_HCLK_SPI0		130
+#define R9A06G032_HCLK_SPI1		131
+#define R9A06G032_HCLK_SPI2		132
+#define R9A06G032_HCLK_SPI3		133
+#define R9A06G032_HCLK_SPI4		134
+#define R9A06G032_HCLK_SPI5		135
+#define R9A06G032_HCLK_SWITCH		136
+#define R9A06G032_HCLK_SWITCH_RG	137
+#define R9A06G032_HCLK_UART0		138
+#define R9A06G032_HCLK_UART1		139
+#define R9A06G032_HCLK_UART2		140
+#define R9A06G032_HCLK_UART3		141
+#define R9A06G032_HCLK_UART4		142
+#define R9A06G032_HCLK_UART5		143
+#define R9A06G032_HCLK_UART6		144
+#define R9A06G032_HCLK_UART7		145
+#define R9A06G032_CLK_UART0		146
+#define R9A06G032_CLK_UART1		147
+#define R9A06G032_CLK_UART2		148
+#define R9A06G032_CLK_UART3		149
+#define R9A06G032_CLK_UART4		150
+#define R9A06G032_CLK_UART5		151
+#define R9A06G032_CLK_UART6		152
+#define R9A06G032_CLK_UART7		153
+
+#endif /* __DT_BINDINGS_R9A06G032_SYSCTRL_H__ */
-- 
2.7.4

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

* [PATCH v8 2/5] dt-bindings: clock: renesas,r9a06g032-sysctrl: documentation
  2018-06-05  8:29 [PATCH v8 0/5] arm: Base support for Renesas RZN1D-DB Board Michel Pollet
  2018-06-05  8:29 ` [PATCH v8 1/5] dt-bindings: Add the r9a06g032-sysctrl.h file Michel Pollet
@ 2018-06-05  8:29 ` Michel Pollet
  2018-06-11 10:00   ` Geert Uytterhoeven
  2018-06-05  8:29 ` [PATCH v8 3/5] ARM: dts: Renesas R9A06G032 base device tree file Michel Pollet
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Michel Pollet @ 2018-06-05  8:29 UTC (permalink / raw)
  To: linux-renesas-soc, Simon Horman
  Cc: phil.edworthy, Michel Pollet, Michel Pollet, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	linux-clk, devicetree, linux-kernel

The Renesas R9A06G032 SYSCTRL node description.

Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>
---
 .../bindings/clock/renesas,r9a06g032-sysctrl.txt   | 32 ++++++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.txt

diff --git a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.txt b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.txt
new file mode 100644
index 0000000..6aee360
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.txt
@@ -0,0 +1,32 @@
+* Renesas R9A06G032 SYSCTRL
+
+Required Properties:
+
+  - compatible: Must be:
+    - "renesas,r9a06g032-sysctrl"
+  - reg: Base address and length of the SYSCTRL IO block.
+  - #clock-cells: Must be 1
+
+Examples
+--------
+
+  - SYSCTRL node:
+
+	sysctrl: system-controller@4000c000 {
+		compatible = "renesas,r9a06g032-sysctrl";
+		reg = <0x4000c000 0x1000>;
+		#clock-cells = <1>;
+	};
+
+  - Other nodes can use the clocks provided by SYSCTRL as in:
+
+	#include <dt-bindings/clock/r9a06g032-sysctrl.h>
+	uart0: serial@40060000 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0x40060000 0x400>;
+		interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clocks = <&sysctrl R9A06G032_CLK_UART0>;
+		clock-names = "baudclk";
+	};
-- 
2.7.4

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

* [PATCH v8 3/5] ARM: dts: Renesas R9A06G032 base device tree file
  2018-06-05  8:29 [PATCH v8 0/5] arm: Base support for Renesas RZN1D-DB Board Michel Pollet
  2018-06-05  8:29 ` [PATCH v8 1/5] dt-bindings: Add the r9a06g032-sysctrl.h file Michel Pollet
  2018-06-05  8:29 ` [PATCH v8 2/5] dt-bindings: clock: renesas,r9a06g032-sysctrl: documentation Michel Pollet
@ 2018-06-05  8:29 ` Michel Pollet
  2018-06-06  8:44   ` Simon Horman
  2018-06-05  8:30 ` [PATCH v8 4/5] ARM: dts: Renesas RZN1D-DB Board base file Michel Pollet
  2018-06-05  8:30 ` [PATCH v8 5/5] clk: renesas: Renesas R9A06G032 clock driver Michel Pollet
  4 siblings, 1 reply; 13+ messages in thread
From: Michel Pollet @ 2018-06-05  8:29 UTC (permalink / raw)
  To: linux-renesas-soc, Simon Horman
  Cc: phil.edworthy, Michel Pollet, Michel Pollet, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	linux-clk, devicetree, linux-kernel

This adds the Renesas R9A06G032 bare bone support.

This currently only handles the SYSCTRL block node,
generic parts (gic, architected timer) and a UART.

Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 arch/arm/boot/dts/r9a06g032.dtsi | 86 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)
 create mode 100644 arch/arm/boot/dts/r9a06g032.dtsi

diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi
new file mode 100644
index 0000000..40827bb
--- /dev/null
+++ b/arch/arm/boot/dts/r9a06g032.dtsi
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Base Device Tree Source for the Renesas RZ/N1D (R9A06G032)
+ *
+ * Copyright (C) 2018 Renesas Electronics Europe Limited
+ *
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/r9a06g032-sysctrl.h>
+
+/ {
+	compatible = "renesas,r9a06g032";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0>;
+			clocks = <&sysctrl R9A06G032_CLK_A7MP>;
+		};
+
+		cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <1>;
+			clocks = <&sysctrl R9A06G032_CLK_A7MP>;
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-parent = <&gic>;
+		ranges;
+
+		sysctrl: system-controller@4000c000 {
+			compatible = "renesas,r9a06g032-sysctrl";
+			reg = <0x4000c000 0x1000>;
+			status = "okay";
+			#clock-cells = <1>;
+		};
+
+		uart0: serial@40060000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x40060000 0x400>;
+			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&sysctrl R9A06G032_CLK_UART0>;
+			clock-names = "baudclk";
+			status = "disabled";
+		};
+
+		gic: gic@44101000 {
+			compatible = "arm,cortex-a7-gic", "arm,gic-400";
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			reg = <0x44101000 0x1000>, /* Distributer */
+			      <0x44102000 0x2000>, /* CPU interface */
+			      <0x44104000 0x2000>, /* Virt interface control */
+			      <0x44106000 0x2000>; /* Virt CPU interface */
+			interrupts =
+				<GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+		};
+	};
+
+	timer {
+		compatible = "arm,cortex-a7-timer",
+			     "arm,armv7-timer";
+		interrupt-parent = <&gic>;
+		arm,cpu-registers-not-fw-configured;
+		always-on;
+		interrupts =
+			<GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+			<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+			<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+			<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+};
-- 
2.7.4

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

* [PATCH v8 4/5] ARM: dts: Renesas RZN1D-DB Board base file
  2018-06-05  8:29 [PATCH v8 0/5] arm: Base support for Renesas RZN1D-DB Board Michel Pollet
                   ` (2 preceding siblings ...)
  2018-06-05  8:29 ` [PATCH v8 3/5] ARM: dts: Renesas R9A06G032 base device tree file Michel Pollet
@ 2018-06-05  8:30 ` Michel Pollet
  2018-06-06  8:45   ` Simon Horman
  2018-06-05  8:30 ` [PATCH v8 5/5] clk: renesas: Renesas R9A06G032 clock driver Michel Pollet
  4 siblings, 1 reply; 13+ messages in thread
From: Michel Pollet @ 2018-06-05  8:30 UTC (permalink / raw)
  To: linux-renesas-soc, Simon Horman
  Cc: phil.edworthy, Michel Pollet, Michel Pollet, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	linux-clk, devicetree, linux-kernel

This adds a base device tree file for the RZN1-DB board, with only the
basic support allowing the system to boot to a prompt. Only one UART is
used, with only a single CPU running.

Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 arch/arm/boot/dts/Makefile                  |  1 +
 arch/arm/boot/dts/r9a06g032-rzn1d400-db.dts | 28 ++++++++++++++++++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 arch/arm/boot/dts/r9a06g032-rzn1d400-db.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 37a3de7..c07f077 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -819,6 +819,7 @@ dtb-$(CONFIG_ARCH_RENESAS) += \
 	r8a7793-gose.dtb \
 	r8a7794-alt.dtb \
 	r8a7794-silk.dtb \
+	r9a06g032-rzn1d400-db.dtb \
 	sh73a0-kzm9g.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += \
 	rv1108-evb.dtb \
diff --git a/arch/arm/boot/dts/r9a06g032-rzn1d400-db.dts b/arch/arm/boot/dts/r9a06g032-rzn1d400-db.dts
new file mode 100644
index 0000000..4e57ae2
--- /dev/null
+++ b/arch/arm/boot/dts/r9a06g032-rzn1d400-db.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the RZN1D-DB Board
+ *
+ * Copyright (C) 2018 Renesas Electronics Europe Limited
+ *
+ */
+
+/dts-v1/;
+
+#include "r9a06g032.dtsi"
+
+/ {
+	model = "RZN1D-DB Board";
+	compatible = "renesas,rzn1d400-db", "renesas,r9a06g032";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	aliases {
+		serial0 = &uart0;
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
-- 
2.7.4

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

* [PATCH v8 5/5] clk: renesas: Renesas R9A06G032 clock driver
  2018-06-05  8:29 [PATCH v8 0/5] arm: Base support for Renesas RZN1D-DB Board Michel Pollet
                   ` (3 preceding siblings ...)
  2018-06-05  8:30 ` [PATCH v8 4/5] ARM: dts: Renesas RZN1D-DB Board base file Michel Pollet
@ 2018-06-05  8:30 ` Michel Pollet
  4 siblings, 0 replies; 13+ messages in thread
From: Michel Pollet @ 2018-06-05  8:30 UTC (permalink / raw)
  To: linux-renesas-soc, Simon Horman
  Cc: phil.edworthy, Michel Pollet, Michel Pollet, Michael Turquette,
	Stephen Boyd, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	linux-clk, devicetree, linux-kernel

This provides a clock driver for the Renesas R09A06G032.
This uses a structure derived from both the RCAR gen2 driver as well as
the renesas-cpg-mssr driver.

Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>
---
 drivers/clk/renesas/Kconfig            |   6 +
 drivers/clk/renesas/Makefile           |   1 +
 drivers/clk/renesas/r9a06g032-clocks.c | 853 +++++++++++++++++++++++++++++++++
 3 files changed, 860 insertions(+)
 create mode 100644 drivers/clk/renesas/r9a06g032-clocks.c

diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index f9ba71311..9022bbe 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -21,6 +21,7 @@ config CLK_RENESAS
 	select CLK_R8A77980 if ARCH_R8A77980
 	select CLK_R8A77990 if ARCH_R8A77990
 	select CLK_R8A77995 if ARCH_R8A77995
+	select CLK_R9A06G032 if ARCH_R9A06G032
 	select CLK_SH73A0 if ARCH_SH73A0
 
 if CLK_RENESAS
@@ -125,6 +126,11 @@ config CLK_R8A77995
 	bool "R-Car D3 clock support" if COMPILE_TEST
 	select CLK_RCAR_GEN3_CPG
 
+config CLK_R9A06G032
+	bool "Renesas R9A06G032 clock driver"
+	help
+	  This is a driver for R9A06G032 clocks
+
 config CLK_SH73A0
 	bool "SH-Mobile AG5 clock support" if COMPILE_TEST
 	select CLK_RENESAS_CPG_MSTP
diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile
index fe5bac9..e4aa3d6 100644
--- a/drivers/clk/renesas/Makefile
+++ b/drivers/clk/renesas/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_CLK_R8A77970)		+= r8a77970-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A77980)		+= r8a77980-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A77990)		+= r8a77990-cpg-mssr.o
 obj-$(CONFIG_CLK_R8A77995)		+= r8a77995-cpg-mssr.o
+obj-$(CONFIG_CLK_R9A06G032)		+= r9a06g032-clocks.o
 obj-$(CONFIG_CLK_SH73A0)		+= clk-sh73a0.o
 
 # Family
diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c
new file mode 100644
index 0000000..cc772dc
--- /dev/null
+++ b/drivers/clk/renesas/r9a06g032-clocks.c
@@ -0,0 +1,853 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * R9A09G032 clock driver
+ *
+ * Copyright (C) 2018 Renesas Electronics Europe Limited
+ *
+ * Michel Pollet <michel.pollet@bp.renesas.com>, <buserror@gmail.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/math64.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <dt-bindings/clock/r9a06g032-sysctrl.h>
+
+struct r9a06g032_gate {
+	uint16_t gate, reset, ready, midle,
+		scon, mirack, mistat;
+};
+
+/* This is used to describe a clock for instantiation */
+struct r9a06g032_clkdesc {
+	const char *name;
+	uint32_t type: 3;
+	uint32_t index: 8;
+	uint32_t source : 8; /* source index + 1 (0 == none) */
+	/* these are used to populate the bitsel struct */
+	union {
+		struct r9a06g032_gate gate;
+		/* for dividers */
+		struct {
+			unsigned int div_min : 10, div_max : 10, reg: 10;
+			uint16_t div_table[4];
+		};
+		/* For fixed-factor ones */
+		uint16_t div;
+		unsigned int factor;
+		unsigned int frequency;
+		/* for dual gate */
+		struct {
+			uint16_t group : 1, index: 3;
+			uint16_t sel, g1, r1, g2, r2;
+		} dual;
+	};
+} __packed;
+
+#define I_GATE(_clk, _rst, _rdy, _midle, _scon, _mirack, _mistat) \
+	{ .gate = _clk, .reset = _rst, \
+		.ready = _rdy, .midle = _midle, \
+		.scon = _scon, .mirack = _mirack, .mistat = _mistat }
+#define D_GATE(_idx, _n, _src, ...) \
+	{ .type = K_GATE, .index = R9A06G032_##_idx, \
+		.source = 1 + R9A06G032_##_src, .name = _n, \
+		.gate = I_GATE(__VA_ARGS__), }
+#define D_FC(_idx, _n, _freq) \
+	{ .type = K_FC, .index = R9A06G032_##_idx, .name = _n, .frequency = _freq, }
+#define D_FFC(_idx, _n, _src, _div) \
+	{ .type = K_FFC, .index = R9A06G032_##_idx, \
+		.source = 1 + R9A06G032_##_src, .name = _n, \
+		.div = _div, }
+#define D_DIV(_idx, _n, _src, _reg, _min, _max, ...) \
+	{ .type = K_DIV, .index = R9A06G032_##_idx, \
+		.source = 1 + R9A06G032_##_src, .name = _n, \
+		.reg = _reg, .div_min = _min, .div_max = _max, \
+		.div_table = { __VA_ARGS__ } }
+#define D_UGATE(_idx, _n, _src, _g, _gi, _g1, _r1, _g2, _r2) \
+	{ .type = K_DUALGATE, .index = R9A06G032_##_idx, \
+		.source = 1 + R9A06G032_##_src, .name = _n, \
+		.dual = { .group = _g, .index = _gi, \
+			.g1 = _g1, .r1 = _r1, .g2 = _g2, .r2 = _r2 }, }
+
+enum { K_GATE = 0, K_FFC, K_FC, K_DIV, K_BITSEL, K_DUALGATE };
+
+/* Internal clock IDs */
+#define R9A06G032_CLKOUT		0
+#define R9A06G032_CLKOUT_D10		2
+#define R9A06G032_CLKOUT_D16		3
+#define R9A06G032_CLKOUT_D160		4
+#define R9A06G032_CLKOUT_D1OR2		5
+#define R9A06G032_CLKOUT_D20		6
+#define R9A06G032_CLKOUT_D40		7
+#define R9A06G032_CLKOUT_D5		8
+#define R9A06G032_CLKOUT_D8		9
+#define R9A06G032_DIV_ADC		10
+#define R9A06G032_DIV_I2C		11
+#define R9A06G032_DIV_NAND		12
+#define R9A06G032_DIV_P1_PG		13
+#define R9A06G032_DIV_P2_PG		14
+#define R9A06G032_DIV_P3_PG		15
+#define R9A06G032_DIV_P4_PG		16
+#define R9A06G032_DIV_P5_PG		17
+#define R9A06G032_DIV_P6_PG		18
+#define R9A06G032_DIV_QSPI0		19
+#define R9A06G032_DIV_QSPI1		20
+#define R9A06G032_DIV_REF_SYNC		21
+#define R9A06G032_DIV_SDIO0		22
+#define R9A06G032_DIV_SDIO1		23
+#define R9A06G032_DIV_SWITCH		24
+#define R9A06G032_DIV_UART		25
+#define R9A06G032_DIV_MOTOR		64
+#define R9A06G032_CLK_DDRPHY_PLLCLK_D4	78
+#define R9A06G032_CLK_ECAT100_D4	79
+#define R9A06G032_CLK_HSR100_D2		80
+#define R9A06G032_CLK_REF_SYNC_D4	81
+#define R9A06G032_CLK_REF_SYNC_D8	82
+#define R9A06G032_CLK_SERCOS100_D2	83
+#define R9A06G032_DIV_CA7		84
+
+#define R9A06G032_UART_GROUP_012	154
+#define R9A06G032_UART_GROUP_34567	155
+
+#define R9A06G032_CLOCK_COUNT		(R9A06G032_UART_GROUP_34567 + 1)
+
+static const struct r9a06g032_clkdesc r9a06g032_clocks[] __initconst = {
+	D_FC(CLKOUT, "clkout", 1000000000),
+	D_FC(CLK_PLL_USB, "clk_pll_usb", 48000000),
+	D_FFC(CLKOUT_D10, "clkout_d10", CLKOUT, 10),
+	D_FFC(CLKOUT_D16, "clkout_d16", CLKOUT, 16),
+	D_FFC(CLKOUT_D160, "clkout_d160", CLKOUT, 160),
+	D_DIV(CLKOUT_D1OR2, "clkout_d1or2", CLKOUT, 0, 1, 2),
+	D_FFC(CLKOUT_D20, "clkout_d20", CLKOUT, 20),
+	D_FFC(CLKOUT_D40, "clkout_d40", CLKOUT, 40),
+	D_FFC(CLKOUT_D5, "clkout_d5", CLKOUT, 5),
+	D_FFC(CLKOUT_D8, "clkout_d8", CLKOUT, 8),
+	D_DIV(DIV_ADC, "div_adc", CLKOUT, 77, 50, 250),
+	D_DIV(DIV_I2C, "div_i2c", CLKOUT, 78, 12, 16),
+	D_DIV(DIV_NAND, "div_nand", CLKOUT, 82, 12, 32),
+	D_DIV(DIV_P1_PG, "div_p1_pg", CLKOUT, 68, 12, 200),
+	D_DIV(DIV_P2_PG, "div_p2_pg", CLKOUT, 62, 12, 128),
+	D_DIV(DIV_P3_PG, "div_p3_pg", CLKOUT, 64, 8, 128),
+	D_DIV(DIV_P4_PG, "div_p4_pg", CLKOUT, 66, 8, 128),
+	D_DIV(DIV_P5_PG, "div_p5_pg", CLKOUT, 71, 10, 40),
+	D_DIV(DIV_P6_PG, "div_p6_pg", CLKOUT, 18, 12, 64),
+	D_DIV(DIV_QSPI0, "div_qspi0", CLKOUT, 73, 3, 7),
+	D_DIV(DIV_QSPI1, "div_qspi1", CLKOUT, 25, 3, 7),
+	D_DIV(DIV_REF_SYNC, "div_ref_sync", CLKOUT, 56, 2, 16, 2, 4, 8, 16),
+	D_DIV(DIV_SDIO0, "div_sdio0", CLKOUT, 74, 20, 128),
+	D_DIV(DIV_SDIO1, "div_sdio1", CLKOUT, 75, 20, 128),
+	D_DIV(DIV_SWITCH, "div_switch", CLKOUT, 37, 5, 40),
+	D_DIV(DIV_UART, "div_uart", CLKOUT, 79, 12, 128),
+	D_GATE(CLK_25_PG4, "clk_25_pg4", CLKOUT_D40, 0x749, 0x74a, 0x74b, 0, 0xae3, 0, 0),
+	D_GATE(CLK_25_PG5, "clk_25_pg5", CLKOUT_D40, 0x74c, 0x74d, 0x74e, 0, 0xae4, 0, 0),
+	D_GATE(CLK_25_PG6, "clk_25_pg6", CLKOUT_D40, 0x74f, 0x750, 0x751, 0, 0xae5, 0, 0),
+	D_GATE(CLK_25_PG7, "clk_25_pg7", CLKOUT_D40, 0x752, 0x753, 0x754, 0, 0xae6, 0, 0),
+	D_GATE(CLK_25_PG8, "clk_25_pg8", CLKOUT_D40, 0x755, 0x756, 0x757, 0, 0xae7, 0, 0),
+	D_GATE(CLK_ADC, "clk_adc", DIV_ADC, 0x1ea, 0x1eb, 0, 0, 0, 0, 0),
+	D_GATE(CLK_ECAT100, "clk_ecat100", CLKOUT_D10, 0x405, 0, 0, 0, 0, 0, 0),
+	D_GATE(CLK_HSR100, "clk_hsr100", CLKOUT_D10, 0x483, 0, 0, 0, 0, 0, 0),
+	D_GATE(CLK_I2C0, "clk_i2c0", DIV_I2C, 0x1e6, 0x1e7, 0, 0, 0, 0, 0),
+	D_GATE(CLK_I2C1, "clk_i2c1", DIV_I2C, 0x1e8, 0x1e9, 0, 0, 0, 0, 0),
+	D_GATE(CLK_MII_REF, "clk_mii_ref", CLKOUT_D40, 0x342, 0, 0, 0, 0, 0, 0),
+	D_GATE(CLK_NAND, "clk_nand", DIV_NAND, 0x284, 0x285, 0, 0, 0, 0, 0),
+	D_GATE(CLK_NOUSBP2_PG6, "clk_nousbp2_pg6", DIV_P2_PG, 0x774, 0x775, 0, 0, 0, 0, 0),
+	D_GATE(CLK_P1_PG2, "clk_p1_pg2", DIV_P1_PG, 0x862, 0x863, 0, 0, 0, 0, 0),
+	D_GATE(CLK_P1_PG3, "clk_p1_pg3", DIV_P1_PG, 0x864, 0x865, 0, 0, 0, 0, 0),
+	D_GATE(CLK_P1_PG4, "clk_p1_pg4", DIV_P1_PG, 0x866, 0x867, 0, 0, 0, 0, 0),
+	D_GATE(CLK_P4_PG3, "clk_p4_pg3", DIV_P4_PG, 0x824, 0x825, 0, 0, 0, 0, 0),
+	D_GATE(CLK_P4_PG4, "clk_p4_pg4", DIV_P4_PG, 0x826, 0x827, 0, 0, 0, 0, 0),
+	D_GATE(CLK_P6_PG1, "clk_p6_pg1", DIV_P6_PG, 0x8a0, 0x8a1, 0x8a2, 0, 0xb60, 0, 0),
+	D_GATE(CLK_P6_PG2, "clk_p6_pg2", DIV_P6_PG, 0x8a3, 0x8a4, 0x8a5, 0, 0xb61, 0, 0),
+	D_GATE(CLK_P6_PG3, "clk_p6_pg3", DIV_P6_PG, 0x8a6, 0x8a7, 0x8a8, 0, 0xb62, 0, 0),
+	D_GATE(CLK_P6_PG4, "clk_p6_pg4", DIV_P6_PG, 0x8a9, 0x8aa, 0x8ab, 0, 0xb63, 0, 0),
+	D_GATE(CLK_QSPI0, "clk_qspi0", DIV_QSPI0, 0x2a4, 0x2a5, 0, 0, 0, 0, 0),
+	D_GATE(CLK_QSPI1, "clk_qspi1", DIV_QSPI1, 0x484, 0x485, 0, 0, 0, 0, 0),
+	D_GATE(CLK_RGMII_REF, "clk_rgmii_ref", CLKOUT_D8, 0x340, 0, 0, 0, 0, 0, 0),
+	D_GATE(CLK_RMII_REF, "clk_rmii_ref", CLKOUT_D20, 0x341, 0, 0, 0, 0, 0, 0),
+	D_GATE(CLK_SDIO0, "clk_sdio0", DIV_SDIO0, 0x64, 0, 0, 0, 0, 0, 0),
+	D_GATE(CLK_SDIO1, "clk_sdio1", DIV_SDIO1, 0x644, 0, 0, 0, 0, 0, 0),
+	D_GATE(CLK_SERCOS100, "clk_sercos100", CLKOUT_D10, 0x425, 0, 0, 0, 0, 0, 0),
+	D_GATE(CLK_SLCD, "clk_slcd", DIV_P1_PG, 0x860, 0x861, 0, 0, 0, 0, 0),
+	D_GATE(CLK_SPI0, "clk_spi0", DIV_P3_PG, 0x7e0, 0x7e1, 0, 0, 0, 0, 0),
+	D_GATE(CLK_SPI1, "clk_spi1", DIV_P3_PG, 0x7e2, 0x7e3, 0, 0, 0, 0, 0),
+	D_GATE(CLK_SPI2, "clk_spi2", DIV_P3_PG, 0x7e4, 0x7e5, 0, 0, 0, 0, 0),
+	D_GATE(CLK_SPI3, "clk_spi3", DIV_P3_PG, 0x7e6, 0x7e7, 0, 0, 0, 0, 0),
+	D_GATE(CLK_SPI4, "clk_spi4", DIV_P4_PG, 0x820, 0x821, 0, 0, 0, 0, 0),
+	D_GATE(CLK_SPI5, "clk_spi5", DIV_P4_PG, 0x822, 0x823, 0, 0, 0, 0, 0),
+	D_GATE(CLK_SWITCH, "clk_switch", DIV_SWITCH, 0x982, 0x983, 0, 0, 0, 0, 0),
+	D_DIV(DIV_MOTOR, "div_motor", CLKOUT_D5, 84, 2, 8),
+	D_GATE(HCLK_ECAT125, "hclk_ecat125", CLKOUT_D8, 0x400, 0x401, 0, 0x402, 0, 0x440, 0x441),
+	D_GATE(HCLK_PINCONFIG, "hclk_pinconfig", CLKOUT_D40, 0x740, 0x741, 0x742, 0, 0xae0, 0, 0),
+	D_GATE(HCLK_SERCOS, "hclk_sercos", CLKOUT_D10, 0x420, 0x422, 0, 0x421, 0, 0x460, 0x461),
+	D_GATE(HCLK_SGPIO2, "hclk_sgpio2", DIV_P5_PG, 0x8c3, 0x8c4, 0x8c5, 0, 0xb41, 0, 0),
+	D_GATE(HCLK_SGPIO3, "hclk_sgpio3", DIV_P5_PG, 0x8c6, 0x8c7, 0x8c8, 0, 0xb42, 0, 0),
+	D_GATE(HCLK_SGPIO4, "hclk_sgpio4", DIV_P5_PG, 0x8c9, 0x8ca, 0x8cb, 0, 0xb43, 0, 0),
+	D_GATE(HCLK_TIMER0, "hclk_timer0", CLKOUT_D40, 0x743, 0x744, 0x745, 0, 0xae1, 0, 0),
+	D_GATE(HCLK_TIMER1, "hclk_timer1", CLKOUT_D40, 0x746, 0x747, 0x748, 0, 0xae2, 0, 0),
+	D_GATE(HCLK_USBF, "hclk_usbf", CLKOUT_D8, 0xe3, 0, 0, 0xe4, 0, 0x102, 0x103),
+	D_GATE(HCLK_USBH, "hclk_usbh", CLKOUT_D8, 0xe0, 0xe1, 0, 0xe2, 0, 0x100, 0x101),
+	D_GATE(HCLK_USBPM, "hclk_usbpm", CLKOUT_D8, 0xe5, 0, 0, 0, 0, 0, 0),
+	D_GATE(CLK_48_PG_F, "clk_48_pg_f", CLK_48, 0x78c, 0x78d, 0, 0x78e, 0, 0xb04, 0xb05),
+	D_GATE(CLK_48_PG4, "clk_48_pg4", CLK_48, 0x789, 0x78a, 0x78b, 0, 0xb03, 0, 0),
+	D_FFC(CLK_DDRPHY_PLLCLK_D4, "clk_ddrphy_pllclk_d4", CLK_DDRPHY_PLLCLK, 4),
+	D_FFC(CLK_ECAT100_D4, "clk_ecat100_d4", CLK_ECAT100, 4),
+	D_FFC(CLK_HSR100_D2, "clk_hsr100_d2", CLK_HSR100, 2),
+	D_FFC(CLK_REF_SYNC_D4, "clk_ref_sync_d4", CLK_REF_SYNC, 4),
+	D_FFC(CLK_REF_SYNC_D8, "clk_ref_sync_d8", CLK_REF_SYNC, 8),
+	D_FFC(CLK_SERCOS100_D2, "clk_sercos100_d2", CLK_SERCOS100, 2),
+	D_DIV(DIV_CA7, "div_ca7", CLK_REF_SYNC, 57, 1, 4, 1, 2, 4),
+	D_GATE(HCLK_CAN0, "hclk_can0", CLK_48, 0x783, 0x784, 0x785, 0, 0xb01, 0, 0),
+	D_GATE(HCLK_CAN1, "hclk_can1", CLK_48, 0x786, 0x787, 0x788, 0, 0xb02, 0, 0),
+	D_GATE(HCLK_DELTASIGMA, "hclk_deltasigma", DIV_MOTOR, 0x1ef, 0x1f0, 0x1f1, 0, 0, 0, 0),
+	D_GATE(HCLK_PWMPTO, "hclk_pwmpto", DIV_MOTOR, 0x1ec, 0x1ed, 0x1ee, 0, 0, 0, 0),
+	D_GATE(HCLK_RSV, "hclk_rsv", CLK_48, 0x780, 0x781, 0x782, 0, 0xb00, 0, 0),
+	D_GATE(HCLK_SGPIO0, "hclk_sgpio0", DIV_MOTOR, 0x1e0, 0x1e1, 0x1e2, 0, 0, 0, 0),
+	D_GATE(HCLK_SGPIO1, "hclk_sgpio1", DIV_MOTOR, 0x1e3, 0x1e4, 0x1e5, 0, 0, 0, 0),
+	D_DIV(RTOS_MDC, "rtos_mdc", CLK_REF_SYNC, 100, 80, 640, 80, 160, 320, 640),
+	D_GATE(CLK_CM3, "clk_cm3", CLK_REF_SYNC_D4, 0xba0, 0xba1, 0, 0xba2, 0, 0xbc0, 0xbc1),
+	D_GATE(CLK_DDRC, "clk_ddrc", CLK_DDRPHY_PLLCLK_D4, 0x323, 0x324, 0, 0, 0, 0, 0),
+	D_GATE(CLK_ECAT25, "clk_ecat25", CLK_ECAT100_D4, 0x403, 0x404, 0, 0, 0, 0, 0),
+	D_GATE(CLK_HSR50, "clk_hsr50", CLK_HSR100_D2, 0x484, 0x485, 0, 0, 0, 0, 0),
+	D_GATE(CLK_HW_RTOS, "clk_hw_rtos", CLK_REF_SYNC_D4, 0xc60, 0xc61, 0, 0, 0, 0, 0),
+	D_GATE(CLK_SERCOS50, "clk_sercos50", CLK_SERCOS100_D2, 0x424, 0x423, 0, 0, 0, 0, 0),
+	D_GATE(HCLK_ADC, "hclk_adc", CLK_REF_SYNC_D8, 0x1af, 0x1b0, 0x1b1, 0, 0, 0, 0),
+	D_GATE(HCLK_CM3, "hclk_cm3", CLK_REF_SYNC_D4, 0xc20, 0xc21, 0xc22, 0, 0, 0, 0),
+	D_GATE(HCLK_CRYPTO_EIP150, "hclk_crypto_eip150", CLK_REF_SYNC_D4, 0x123, 0x124, 0x125, 0, 0x142, 0, 0),
+	D_GATE(HCLK_CRYPTO_EIP93, "hclk_crypto_eip93", CLK_REF_SYNC_D4, 0x120, 0x121, 0, 0x122, 0, 0x140, 0x141),
+	D_GATE(HCLK_DDRC, "hclk_ddrc", CLK_REF_SYNC_D4, 0x320, 0x322, 0, 0x321, 0, 0x3a0, 0x3a1),
+	D_GATE(HCLK_DMA0, "hclk_dma0", CLK_REF_SYNC_D4, 0x260, 0x261, 0x262, 0x263, 0x2c0, 0x2c1, 0x2c2),
+	D_GATE(HCLK_DMA1, "hclk_dma1", CLK_REF_SYNC_D4, 0x264, 0x265, 0x266, 0x267, 0x2c3, 0x2c4, 0x2c5),
+	D_GATE(HCLK_GMAC0, "hclk_gmac0", CLK_REF_SYNC_D4, 0x360, 0x361, 0x362, 0x363, 0x3c0, 0x3c1, 0x3c2),
+	D_GATE(HCLK_GMAC1, "hclk_gmac1", CLK_REF_SYNC_D4, 0x380, 0x381, 0x382, 0x383, 0x3e0, 0x3e1, 0x3e2),
+	D_GATE(HCLK_GPIO0, "hclk_gpio0", CLK_REF_SYNC_D4, 0x212, 0x213, 0x214, 0, 0, 0, 0),
+	D_GATE(HCLK_GPIO1, "hclk_gpio1", CLK_REF_SYNC_D4, 0x215, 0x216, 0x217, 0, 0, 0, 0),
+	D_GATE(HCLK_GPIO2, "hclk_gpio2", CLK_REF_SYNC_D4, 0x229, 0x22a, 0x22b, 0, 0, 0, 0),
+	D_GATE(HCLK_HSR, "hclk_hsr", CLK_HSR100_D2, 0x480, 0x482, 0, 0x481, 0, 0x4c0, 0x4c1),
+	D_GATE(HCLK_I2C0, "hclk_i2c0", CLK_REF_SYNC_D8, 0x1a9, 0x1aa, 0x1ab, 0, 0, 0, 0),
+	D_GATE(HCLK_I2C1, "hclk_i2c1", CLK_REF_SYNC_D8, 0x1ac, 0x1ad, 0x1ae, 0, 0, 0, 0),
+	D_GATE(HCLK_LCD, "hclk_lcd", CLK_REF_SYNC_D4, 0x7a0, 0x7a1, 0x7a2, 0, 0xb20, 0, 0),
+	D_GATE(HCLK_MSEBI_M, "hclk_msebi_m", CLK_REF_SYNC_D4, 0x164, 0x165, 0x166, 0, 0x183, 0, 0),
+	D_GATE(HCLK_MSEBI_S, "hclk_msebi_s", CLK_REF_SYNC_D4, 0x160, 0x161, 0x162, 0x163, 0x180, 0x181, 0x182),
+	D_GATE(HCLK_NAND, "hclk_nand", CLK_REF_SYNC_D4, 0x280, 0x281, 0x282, 0x283, 0x2e0, 0x2e1, 0x2e2),
+	D_GATE(HCLK_PG_I, "hclk_pg_i", CLK_REF_SYNC_D4, 0x7ac, 0x7ad, 0, 0x7ae, 0, 0xb24, 0xb25),
+	D_GATE(HCLK_PG19, "hclk_pg19", CLK_REF_SYNC_D4, 0x22c, 0x22d, 0x22e, 0, 0, 0, 0),
+	D_GATE(HCLK_PG20, "hclk_pg20", CLK_REF_SYNC_D4, 0x22f, 0x230, 0x231, 0, 0, 0, 0),
+	D_GATE(HCLK_PG3, "hclk_pg3", CLK_REF_SYNC_D4, 0x7a6, 0x7a7, 0x7a8, 0, 0xb22, 0, 0),
+	D_GATE(HCLK_PG4, "hclk_pg4", CLK_REF_SYNC_D4, 0x7a9, 0x7aa, 0x7ab, 0, 0xb23, 0, 0),
+	D_GATE(HCLK_QSPI0, "hclk_qspi0", CLK_REF_SYNC_D4, 0x2a0, 0x2a1, 0x2a2, 0x2a3, 0x300, 0x301, 0x302),
+	D_GATE(HCLK_QSPI1, "hclk_qspi1", CLK_REF_SYNC_D4, 0x480, 0x481, 0x482, 0x483, 0x4c0, 0x4c1, 0x4c2),
+	D_GATE(HCLK_ROM, "hclk_rom", CLK_REF_SYNC_D4, 0xaa0, 0xaa1, 0xaa2, 0, 0xb80, 0, 0),
+	D_GATE(HCLK_RTC, "hclk_rtc", CLK_REF_SYNC_D8, 0xa00, 0, 0, 0, 0, 0, 0),
+	D_GATE(HCLK_SDIO0, "hclk_sdio0", CLK_REF_SYNC_D4, 0x60, 0x61, 0x62, 0x63, 0x80, 0x81, 0x82),
+	D_GATE(HCLK_SDIO1, "hclk_sdio1", CLK_REF_SYNC_D4, 0x640, 0x641, 0x642, 0x643, 0x660, 0x661, 0x662),
+	D_GATE(HCLK_SEMAP, "hclk_semap", CLK_REF_SYNC_D4, 0x7a3, 0x7a4, 0x7a5, 0, 0xb21, 0, 0),
+	D_GATE(HCLK_SPI0, "hclk_spi0", CLK_REF_SYNC_D4, 0x200, 0x201, 0x202, 0, 0, 0, 0),
+	D_GATE(HCLK_SPI1, "hclk_spi1", CLK_REF_SYNC_D4, 0x203, 0x204, 0x205, 0, 0, 0, 0),
+	D_GATE(HCLK_SPI2, "hclk_spi2", CLK_REF_SYNC_D4, 0x206, 0x207, 0x208, 0, 0, 0, 0),
+	D_GATE(HCLK_SPI3, "hclk_spi3", CLK_REF_SYNC_D4, 0x209, 0x20a, 0x20b, 0, 0, 0, 0),
+	D_GATE(HCLK_SPI4, "hclk_spi4", CLK_REF_SYNC_D4, 0x20c, 0x20d, 0x20e, 0, 0, 0, 0),
+	D_GATE(HCLK_SPI5, "hclk_spi5", CLK_REF_SYNC_D4, 0x20f, 0x210, 0x211, 0, 0, 0, 0),
+	D_GATE(HCLK_SWITCH, "hclk_switch", CLK_REF_SYNC_D4, 0x980, 0, 0x981, 0, 0, 0, 0),
+	D_GATE(HCLK_SWITCH_RG, "hclk_switch_rg", CLK_REF_SYNC_D4, 0xc40, 0xc41, 0xc42, 0, 0, 0, 0),
+	D_GATE(HCLK_UART0, "hclk_uart0", CLK_REF_SYNC_D8, 0x1a0, 0x1a1, 0x1a2, 0, 0, 0, 0),
+	D_GATE(HCLK_UART1, "hclk_uart1", CLK_REF_SYNC_D8, 0x1a3, 0x1a4, 0x1a5, 0, 0, 0, 0),
+	D_GATE(HCLK_UART2, "hclk_uart2", CLK_REF_SYNC_D8, 0x1a6, 0x1a7, 0x1a8, 0, 0, 0, 0),
+	D_GATE(HCLK_UART3, "hclk_uart3", CLK_REF_SYNC_D4, 0x218, 0x219, 0x21a, 0, 0, 0, 0),
+	D_GATE(HCLK_UART4, "hclk_uart4", CLK_REF_SYNC_D4, 0x21b, 0x21c, 0x21d, 0, 0, 0, 0),
+	D_GATE(HCLK_UART5, "hclk_uart5", CLK_REF_SYNC_D4, 0x220, 0x221, 0x222, 0, 0, 0, 0),
+	D_GATE(HCLK_UART6, "hclk_uart6", CLK_REF_SYNC_D4, 0x223, 0x224, 0x225, 0, 0, 0, 0),
+	D_GATE(HCLK_UART7, "hclk_uart7", CLK_REF_SYNC_D4, 0x226, 0x227, 0x228, 0, 0, 0, 0),
+	/*
+	 * These are not hardware clocks, but are needed to handle the special
+	 * case where we have a 'selector bit' that doesn't just change the
+	 * parent for a clock, but also the gate it's suposed to use.
+	 */
+	{
+		.index = R9A06G032_UART_GROUP_012,
+		.name = "uart_group_012",
+		.type = K_BITSEL,
+		.source = 1 + R9A06G032_DIV_UART,
+		/* R9A06G032_SYSCTRL_REG_PWRCTRL_PG1_PR2 */
+		.dual.sel = ((0xec / 4) << 5) | 24,
+		.dual.group = 0,
+	},
+	{
+		.index = R9A06G032_UART_GROUP_34567,
+		.name = "uart_group_34567",
+		.type = K_BITSEL,
+		.source = 1 + R9A06G032_DIV_P2_PG,
+		/* R9A06G032_SYSCTRL_REG_PWRCTRL_PG0_0 */
+		.dual.sel = ((0x34 / 4) << 5) | 30,
+		.dual.group = 1,
+	},
+	D_UGATE(CLK_UART0, "clk_uart0", UART_GROUP_012, 0, 0, 0x1b2, 0x1b3, 0x1b4, 0x1b5),
+	D_UGATE(CLK_UART1, "clk_uart1", UART_GROUP_012, 0, 1, 0x1b6, 0x1b7, 0x1b8, 0x1b9),
+	D_UGATE(CLK_UART2, "clk_uart2", UART_GROUP_012, 0, 2, 0x1ba, 0x1bb, 0x1bc, 0x1bd),
+	D_UGATE(CLK_UART3, "clk_uart3", UART_GROUP_34567, 1, 0, 0x760, 0x761, 0x762, 0x763),
+	D_UGATE(CLK_UART4, "clk_uart4", UART_GROUP_34567, 1, 1, 0x764, 0x765, 0x766, 0x767),
+	D_UGATE(CLK_UART5, "clk_uart5", UART_GROUP_34567, 1, 2, 0x768, 0x769, 0x76a, 0x76b),
+	D_UGATE(CLK_UART6, "clk_uart6", UART_GROUP_34567, 1, 3, 0x76c, 0x76d, 0x76e, 0x76f),
+	D_UGATE(CLK_UART7, "clk_uart7", UART_GROUP_34567, 1, 4, 0x770, 0x771, 0x772, 0x773),
+};
+
+struct r9a06g032_priv {
+	struct clk_onecell_data data;
+	spinlock_t lock;
+	void __iomem *reg;
+};
+
+/* register/bit pairs are encoded as an uint16_t */
+static void clk_rdesc_set(
+	struct r9a06g032_priv *clocks,
+	uint16_t one, unsigned int on)
+{
+	u32 __iomem *reg = clocks->reg + (4 * (one >> 5));
+	u32 val = readl(reg);
+
+	val = (val & ~(1U << (one & 0x1f))) | ((!!on) << (one & 0x1f));
+	writel(val, reg);
+}
+
+static int clk_rdesc_get(
+	struct r9a06g032_priv *clocks,
+	uint16_t one)
+{
+	u32 __iomem *reg = clocks->reg + (4 * (one >> 5));
+	u32 val = readl(reg);
+
+	return !!(val & (1U << (one & 0x1f)));
+}
+
+/*
+ * This implements the R9A09G032 clock gate 'driver'. We cannot use the system's
+ * clock gate framework as the gates on the R9A09G032 have a special enabling
+ * sequence, therefore we use this little proxy.
+ */
+struct r9a06g032_clk_gate {
+	struct clk_hw hw;
+	struct r9a06g032_priv *clocks;
+	u16 index;
+
+	struct r9a06g032_gate gate;
+};
+
+#define to_r9a06g032_gate(_hw) container_of(_hw, struct r9a06g032_clk_gate, hw)
+
+static void r9a06g032_clk_gate_set(
+	struct r9a06g032_priv *clocks,
+	struct r9a06g032_gate *g, int on)
+{
+	unsigned long flags;
+
+	WARN_ON(!g->gate);
+
+	spin_lock_irqsave(&clocks->lock, flags);
+	clk_rdesc_set(clocks, g->gate, on);
+	/* De-assert reset */
+	if (g->reset)
+		clk_rdesc_set(clocks, g->reset, 1);
+	spin_unlock_irqrestore(&clocks->lock, flags);
+
+	/* Hardware manual recommends 5us delay after enabling clock & reset */
+	udelay(5);
+
+	/* If the peripheral is memory mapped (i.e. an AXI slave), there is an
+	 * associated SLVRDY bit in the System Controller that needs to be set
+	 * so that the FlexWAY bus fabric passes on the read/write requests.
+	 */
+	if (g->ready || g->midle) {
+		spin_lock_irqsave(&clocks->lock, flags);
+		if (g->ready)
+			clk_rdesc_set(clocks, g->ready, on);
+		/* Clear 'Master Idle Request' bit */
+		if (g->midle)
+			clk_rdesc_set(clocks, g->midle, !on);
+		spin_unlock_irqrestore(&clocks->lock, flags);
+	}
+	/* Note: We don't wait for FlexWAY Socket Connection signal */
+}
+
+static int r9a06g032_clk_gate_enable(struct clk_hw *hw)
+{
+	struct r9a06g032_clk_gate *g = to_r9a06g032_gate(hw);
+
+	r9a06g032_clk_gate_set(g->clocks, &g->gate, 1);
+	return 0;
+}
+
+static void r9a06g032_clk_gate_disable(struct clk_hw *hw)
+{
+	struct r9a06g032_clk_gate *g = to_r9a06g032_gate(hw);
+
+	r9a06g032_clk_gate_set(g->clocks, &g->gate, 0);
+}
+
+static int r9a06g032_clk_gate_is_enabled(struct clk_hw *hw)
+{
+	struct r9a06g032_clk_gate *g = to_r9a06g032_gate(hw);
+
+	return clk_rdesc_get(g->clocks, g->gate.gate);
+}
+
+static const struct clk_ops r9a06g032_clk_gate_ops = {
+	.enable = r9a06g032_clk_gate_enable,
+	.disable = r9a06g032_clk_gate_disable,
+	.is_enabled = r9a06g032_clk_gate_is_enabled,
+};
+
+static struct clk *r9a06g032_register_gate(
+	struct r9a06g032_priv *clocks,
+	const char *parent_name,
+	const struct r9a06g032_clkdesc *desc)
+{
+	struct clk *clk;
+	struct r9a06g032_clk_gate *g;
+	struct clk_init_data init;
+
+	g = kzalloc(sizeof(struct r9a06g032_clk_gate), GFP_KERNEL);
+	if (!g)
+		return NULL;
+
+	init.name = desc->name;
+	init.ops = &r9a06g032_clk_gate_ops;
+	init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT;
+	/*
+	 * important here, some clocks are already in use by the CM3, we
+	 * have to assume they are not Linux's to play with and try to disable
+	 * at the end of the boot!
+	 */
+	if (clk_rdesc_get(clocks, desc->gate.gate)) {
+		init.flags |= CLK_IS_CRITICAL;
+		pr_debug("%s was enabled, making read-only\n", desc->name);
+	}
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+
+	g->clocks = clocks;
+	g->index = desc->index;
+	g->gate = desc->gate;
+	g->hw.init = &init;
+
+	clk = clk_register(NULL, &g->hw);
+	if (IS_ERR(clk)) {
+		kfree(g);
+		return NULL;
+	}
+	return clk;
+}
+
+struct r9a06g032_clk_div {
+	struct clk_hw hw;
+	struct r9a06g032_priv *clocks;
+	u16 index;
+	u16 reg;
+	u16 min, max;
+	uint8_t table_size;
+	u16 table[8];	/* we know there are no more than 8 */
+};
+
+#define to_r9a06g032_divider(_hw) \
+		container_of(_hw, struct r9a06g032_clk_div, hw)
+
+static unsigned long r9a06g032_divider_recalc_rate(
+	struct clk_hw *hw,
+	unsigned long parent_rate)
+{
+	struct r9a06g032_clk_div *clk = to_r9a06g032_divider(hw);
+	u32 __iomem *reg = clk->clocks->reg + (4 * clk->reg);
+	u32 div = readl(reg);
+
+	if (div < clk->min)
+		div = clk->min;
+	else if (div > clk->max)
+		div = clk->max;
+	return DIV_ROUND_UP(parent_rate, div);
+}
+
+/*
+ * Attempts to find a value that is in range of min,max,
+ * and if a table of set dividers was specified for this
+ * register, try to find the fixed divider that is the closest
+ * to the target frequency
+ */
+static long r9a06g032_divider_clamp_div(
+	struct r9a06g032_clk_div *clk,
+	unsigned long rate, unsigned long prate)
+{
+	/* + 1 to cope with rates that have the remainder dropped */
+	u32 div = DIV_ROUND_UP(prate, rate + 1);
+	int i;
+
+	if (div <= clk->min)
+		return clk->min;
+	if (div >= clk->max)
+		return clk->max;
+
+	for (i = 0; clk->table_size && i < clk->table_size - 1; i++) {
+		if (div >= clk->table[i] && div <= clk->table[i+1]) {
+			unsigned long m = rate -
+				DIV_ROUND_UP(prate, clk->table[i]);
+			unsigned long p =
+				DIV_ROUND_UP(prate, clk->table[i + 1]) -
+				rate;
+			/*
+			 * select the divider that generates
+			 * the value closest to the ideal frequency
+			 */
+			div = p >= m ? clk->table[i] : clk->table[i + 1];
+			return div;
+		}
+	}
+	return div;
+}
+
+static long r9a06g032_divider_round_rate(
+	struct clk_hw *hw, unsigned long rate,
+	unsigned long *prate)
+{
+	struct r9a06g032_clk_div *clk = to_r9a06g032_divider(hw);
+	u32 div = DIV_ROUND_UP(*prate, rate);
+
+	pr_devel("%s %pC %ld (prate %ld) (wanted div %u)\n", __func__,
+		hw->clk, rate, *prate, div);
+	pr_devel("   min %d (%ld) max %d (%ld)\n",
+		clk->min, DIV_ROUND_UP(*prate, clk->min),
+		clk->max, DIV_ROUND_UP(*prate, clk->max));
+
+	div = r9a06g032_divider_clamp_div(clk, rate, *prate);
+	/*
+	 * this is a hack. Currently the serial driver asks for a clock rate
+	 * that is 16 times the baud rate -- and that is wildly outside the
+	 * range of the UART divider, somehow there is no provision for that
+	 * case of 'let the divider as is if outside range'.
+	 * The serial driver *shouldn't* play with these clocks anyway, there's
+	 * several uarts attached to this divider, and changing this impacts
+	 * everyone.
+	 */
+	if (clk->index == R9A06G032_DIV_UART) {
+		pr_devel("%s div uart hack!\n", __func__);
+		return clk_get_rate(hw->clk);
+	}
+	pr_devel("%s %pC %ld / %u = %ld\n", __func__, hw->clk,
+		*prate, div, DIV_ROUND_UP(*prate, div));
+	return DIV_ROUND_UP(*prate, div);
+}
+
+static int r9a06g032_divider_set_rate(
+	struct clk_hw *hw, unsigned long rate,
+	unsigned long parent_rate)
+{
+	struct r9a06g032_clk_div *clk = to_r9a06g032_divider(hw);
+	/* + 1 to cope with rates that have the remainder dropped */
+	u32 div = DIV_ROUND_UP(parent_rate, rate + 1);
+	u32 __iomem *reg = clk->clocks->reg + (4 * clk->reg);
+
+	pr_devel("%s %pC rate %ld parent %ld div %d\n", __func__, hw->clk,
+		rate, parent_rate, div);
+
+	/*
+	 * Need to write the bit 31 with the divider value to
+	 * latch it. Technically we should wait until it has been
+	 * cleared too.
+	 * TODO: Find whether this callback is sleepable, in case
+	 * the hardware /does/ require some sort of spinloop here.
+	 */
+	writel(div | BIT(31), reg);
+
+	return 0;
+}
+
+static const struct clk_ops r9a06g032_clk_div_ops = {
+	.recalc_rate = r9a06g032_divider_recalc_rate,
+	.round_rate = r9a06g032_divider_round_rate,
+	.set_rate = r9a06g032_divider_set_rate,
+};
+
+static struct clk *r9a06g032_register_divider(
+	struct r9a06g032_priv *clocks,
+	const char *parent_name,
+	const struct r9a06g032_clkdesc *desc)
+{
+	struct r9a06g032_clk_div *div;
+	struct clk *clk;
+	struct clk_init_data init;
+	unsigned int i;
+
+	div = kzalloc(sizeof(struct r9a06g032_clk_div), GFP_KERNEL);
+	if (!div)
+		return NULL;
+
+	init.name = desc->name;
+	init.ops = &r9a06g032_clk_div_ops;
+	init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT;
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+
+	div->clocks = clocks;
+	div->index = desc->index;
+	div->reg = desc->reg;
+	div->hw.init = &init;
+	div->min = desc->div_min;
+	div->max = desc->div_max;
+	/* populate (optional) divider table fixed values */
+	for (i = 0; i < ARRAY_SIZE(div->table) &&
+			i < ARRAY_SIZE(desc->div_table) &&
+			desc->div_table[i]; i++) {
+		div->table[div->table_size++] = desc->div_table[i];
+	}
+
+	clk = clk_register(NULL, &div->hw);
+	if (IS_ERR(clk)) {
+		kfree(div);
+		return NULL;
+	}
+	return clk;
+}
+
+/*
+ * This clock provider handles the case of the R9A06G032 where you have
+ * peripherals that have two potential clock source and two gates, one for
+ * each of the clock source - the used clock source (for all sub clocks)
+ * is selected by a single bit.
+ * That single bit affects all sub-clocks, and therefore needs to change the
+ * active gate (and turn the others off) and force a recalculation of the rates.
+ *
+ * This implements two clock providers, one 'bitselect' that
+ * handles the switch between both parents, and another 'dualgate'
+ * that knows which gate to poke at, depending on the parent's bit position.
+ */
+struct r9a06g032_clk_bitsel {
+	struct clk_hw	hw;
+	struct r9a06g032_priv *clocks;
+	u16 index;
+	u16 selector;		/* selector register + bit */
+};
+
+#define to_clk_bitselect(_hw) \
+		container_of(_hw, struct r9a06g032_clk_bitsel, hw)
+
+static u8 r9a06g032_clk_mux_get_parent(struct clk_hw *hw)
+{
+	struct r9a06g032_clk_bitsel *set = to_clk_bitselect(hw);
+
+	return clk_rdesc_get(set->clocks, set->selector);
+}
+
+static int r9a06g032_clk_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct r9a06g032_clk_bitsel *set = to_clk_bitselect(hw);
+
+	/* a single bit in the register selects one of two parent clocks */
+	clk_rdesc_set(set->clocks, set->selector, !!index);
+
+	return 0;
+}
+
+static const struct clk_ops clk_bitselect_ops = {
+	.get_parent = r9a06g032_clk_mux_get_parent,
+	.set_parent = r9a06g032_clk_mux_set_parent,
+};
+
+static struct clk *r9a06g032_register_bitsel(
+	struct r9a06g032_priv *clocks,
+	const char *parent_name,
+	const struct r9a06g032_clkdesc *desc)
+{
+	struct clk *clk;
+	struct r9a06g032_clk_bitsel *g;
+	struct clk_init_data init;
+	const char *names[2];
+
+	/* allocate the gate */
+	g = kzalloc(sizeof(struct r9a06g032_clk_bitsel), GFP_KERNEL);
+	if (!g)
+		return NULL;
+
+	names[0] = parent_name;
+	names[1] = "clk_pll_usb";
+
+	init.name = desc->name;
+	init.ops = &clk_bitselect_ops;
+	init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT;
+	init.parent_names = names;
+	init.num_parents = 2;
+
+	g->clocks = clocks;
+	g->index = desc->index;
+	g->selector = desc->dual.sel;
+	g->hw.init = &init;
+
+	clk = clk_register(NULL, &g->hw);
+	if (IS_ERR(clk)) {
+		kfree(g);
+		return NULL;
+	}
+	return clk;
+}
+
+struct r9a06g032_clk_dualgate {
+	struct clk_hw	hw;
+	struct r9a06g032_priv *clocks;
+	u16 index;
+	u16 selector;		/* selector register + bit */
+	struct r9a06g032_gate gate[2];
+};
+#define to_clk_dualgate(_hw) \
+		container_of(_hw, struct r9a06g032_clk_dualgate, hw)
+
+static int r9a06g032_clk_dualgate_setenable(
+	struct r9a06g032_clk_dualgate *g, int enable)
+{
+	uint8_t sel_bit = clk_rdesc_get(g->clocks, g->selector);
+
+	/* we always turn off the 'other' gate, regardless */
+	r9a06g032_clk_gate_set(g->clocks, &g->gate[!sel_bit], 0);
+	r9a06g032_clk_gate_set(g->clocks, &g->gate[sel_bit], enable);
+
+	return 0;
+}
+
+static int r9a06g032_clk_dualgate_enable(struct clk_hw *hw)
+{
+	struct r9a06g032_clk_dualgate *gate = to_clk_dualgate(hw);
+
+	r9a06g032_clk_dualgate_setenable(gate, 1);
+
+	return 0;
+}
+
+static void r9a06g032_clk_dualgate_disable(struct clk_hw *hw)
+{
+	struct r9a06g032_clk_dualgate *gate = to_clk_dualgate(hw);
+
+	r9a06g032_clk_dualgate_setenable(gate, 0);
+}
+
+static int r9a06g032_clk_dualgate_is_enabled(struct clk_hw *hw)
+{
+	struct r9a06g032_clk_dualgate *g = to_clk_dualgate(hw);
+	uint8_t sel_bit = clk_rdesc_get(g->clocks, g->selector);
+
+	return clk_rdesc_get(g->clocks, g->gate[sel_bit].gate);
+}
+
+static const struct clk_ops r9a06g032_clk_dualgate_ops = {
+	.enable = r9a06g032_clk_dualgate_enable,
+	.disable = r9a06g032_clk_dualgate_disable,
+	.is_enabled = r9a06g032_clk_dualgate_is_enabled,
+};
+
+static struct clk *r9a06g032_register_dualgate(
+	struct r9a06g032_priv *clocks,
+	const char *parent_name,
+	const struct r9a06g032_clkdesc *desc,
+	uint16_t sel)
+{
+	struct r9a06g032_clk_dualgate *g;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	/* allocate the gate */
+	g = kzalloc(sizeof(struct r9a06g032_clk_dualgate), GFP_KERNEL);
+	if (!g)
+		return NULL;
+	g->clocks = clocks;
+	g->index = desc->index;
+	g->selector = sel;
+	g->gate[0].gate = desc->dual.g1;
+	g->gate[0].reset = desc->dual.r1;
+	g->gate[1].gate = desc->dual.g2;
+	g->gate[1].reset = desc->dual.r2;
+
+	init.name = desc->name;
+	init.ops = &r9a06g032_clk_dualgate_ops;
+	init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+	g->hw.init = &init;
+	/*
+	 * important here, some clocks are already in use by the CM3, we
+	 * have to assume they are not Linux's to play with and try to disable
+	 * at the end of the boot!
+	 */
+	if (r9a06g032_clk_dualgate_is_enabled(&g->hw)) {
+		init.flags |= CLK_IS_CRITICAL;
+		pr_debug("%s was enabled, making read-only\n", desc->name);
+	}
+
+	clk = clk_register(NULL, &g->hw);
+	if (IS_ERR(clk)) {
+		kfree(g);
+		return NULL;
+	}
+	return clk;
+}
+
+static void __init r9a06g032_clocks_init(struct device_node *np)
+{
+	struct r9a06g032_priv *clocks;
+	struct clk **clks;
+	unsigned int i;
+	uint16_t uart_group_sel[2];
+
+	clocks = kzalloc(sizeof(*clocks), GFP_KERNEL);
+	clks = kcalloc(sizeof(struct clk *), R9A06G032_CLOCK_COUNT,
+			GFP_KERNEL);
+	if (clocks == NULL || clks == NULL) {
+		/* We're leaking memory on purpose, there's no point in cleaning
+		 * up as the system won't boot anyway.
+		 */
+		return;
+	}
+	spin_lock_init(&clocks->lock);
+
+	clocks->data.clks = clks;
+	clocks->data.clk_num = R9A06G032_CLOCK_COUNT;
+
+	clocks->reg = of_iomap(np, 0);
+	if (WARN_ON(clocks->reg == NULL))
+		return;
+	for (i = 0; i < ARRAY_SIZE(r9a06g032_clocks); ++i) {
+		const struct r9a06g032_clkdesc *d = &r9a06g032_clocks[i];
+		const char *parent_name = d->source ?
+			__clk_get_name(clocks->data.clks[d->source - 1]) : NULL;
+		struct clk *clk = NULL;
+
+		switch (d->type) {
+		case K_FC:
+			clk = clk_register_fixed_rate(NULL, d->name,
+						parent_name, 0, d->frequency);
+			break;
+		case K_FFC:
+			clk = clk_register_fixed_factor(NULL, d->name,
+						parent_name, 0, 1, d->div);
+			break;
+		case K_GATE:
+			clk = r9a06g032_register_gate(clocks, parent_name, d);
+			break;
+		case K_DIV:
+			clk = r9a06g032_register_divider(clocks,
+					parent_name, d);
+			break;
+		case K_BITSEL:
+			/* keep that selector register around */
+			uart_group_sel[d->dual.group] = d->dual.sel;
+			clk = r9a06g032_register_bitsel(clocks, parent_name, d);
+			break;
+		case K_DUALGATE:
+			clk = r9a06g032_register_dualgate(clocks, parent_name,
+					d, uart_group_sel[d->dual.group]);
+			break;
+		}
+		clocks->data.clks[d->index] = clk;
+	}
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clocks->data);
+}
+CLK_OF_DECLARE(r9a06g032_clks, "renesas,r9a06g032-sysctrl",
+	       r9a06g032_clocks_init);
-- 
2.7.4

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

* Re: [PATCH v8 3/5] ARM: dts: Renesas R9A06G032 base device tree file
  2018-06-05  8:29 ` [PATCH v8 3/5] ARM: dts: Renesas R9A06G032 base device tree file Michel Pollet
@ 2018-06-06  8:44   ` Simon Horman
  0 siblings, 0 replies; 13+ messages in thread
From: Simon Horman @ 2018-06-06  8:44 UTC (permalink / raw)
  To: Michel Pollet
  Cc: linux-renesas-soc, phil.edworthy, Michel Pollet,
	Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, linux-clk, devicetree, linux-kernel

On Tue, Jun 05, 2018 at 09:29:59AM +0100, Michel Pollet wrote:
> This adds the Renesas R9A06G032 bare bone support.
> 
> This currently only handles the SYSCTRL block node,
> generic parts (gic, architected timer) and a UART.
> 
> Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Hi,

This looks fine to me but I will wait to see if there are other reviews
before applying.

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

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

* Re: [PATCH v8 4/5] ARM: dts: Renesas RZN1D-DB Board base file
  2018-06-05  8:30 ` [PATCH v8 4/5] ARM: dts: Renesas RZN1D-DB Board base file Michel Pollet
@ 2018-06-06  8:45   ` Simon Horman
  0 siblings, 0 replies; 13+ messages in thread
From: Simon Horman @ 2018-06-06  8:45 UTC (permalink / raw)
  To: Michel Pollet
  Cc: linux-renesas-soc, phil.edworthy, Michel Pollet,
	Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, linux-clk, devicetree, linux-kernel

On Tue, Jun 05, 2018 at 09:30:00AM +0100, Michel Pollet wrote:
> This adds a base device tree file for the RZN1-DB board, with only the
> basic support allowing the system to boot to a prompt. Only one UART is
> used, with only a single CPU running.
> 
> Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Hi,

This looks fine to me but I will wait to see if there are other reviews
before applying.

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

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

* Re: [PATCH v8 2/5] dt-bindings: clock: renesas,r9a06g032-sysctrl: documentation
  2018-06-05  8:29 ` [PATCH v8 2/5] dt-bindings: clock: renesas,r9a06g032-sysctrl: documentation Michel Pollet
@ 2018-06-11 10:00   ` Geert Uytterhoeven
  2018-06-13  6:38     ` Michel Pollet
  0 siblings, 1 reply; 13+ messages in thread
From: Geert Uytterhoeven @ 2018-06-11 10:00 UTC (permalink / raw)
  To: Michel Pollet
  Cc: Linux-Renesas, Simon Horman, Phil Edworthy, Michel Pollet,
	Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, linux-clk,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux Kernel Mailing List

Hi Michel,

On Tue, Jun 5, 2018 at 10:36 AM Michel Pollet
<michel.pollet@bp.renesas.com> wrote:
> The Renesas R9A06G032 SYSCTRL node description.
>
> Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>

> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.txt
> @@ -0,0 +1,32 @@
> +* Renesas R9A06G032 SYSCTRL
> +
> +Required Properties:
> +
> +  - compatible: Must be:
> +    - "renesas,r9a06g032-sysctrl"
> +  - reg: Base address and length of the SYSCTRL IO block.
> +  - #clock-cells: Must be 1

(repeating myself) No clocks/clock-names for the external clock inputs?

"RZ/N1 has 3 clock sources, 1 reference clock inputs for RGMII, and 2
 reference clock outputs for RMII/MII."

The rest looks fine to me.
Thanks!

Gr{oetje,eeting}s,

                        Geert

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

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

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

* RE: [PATCH v8 2/5] dt-bindings: clock: renesas,r9a06g032-sysctrl: documentation
  2018-06-11 10:00   ` Geert Uytterhoeven
@ 2018-06-13  6:38     ` Michel Pollet
  2018-06-13  7:17       ` Geert Uytterhoeven
  0 siblings, 1 reply; 13+ messages in thread
From: Michel Pollet @ 2018-06-13  6:38 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Linux-Renesas, Simon Horman, Phil Edworthy, Michel Pollet,
	Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, linux-clk,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux Kernel Mailing List

Hi Geert,

On 11 June 2018 11:01, Geert wrote:
> Hi Michel,
>
> On Tue, Jun 5, 2018 at 10:36 AM Michel Pollet
> <michel.pollet@bp.renesas.com> wrote:
> > The Renesas R9A06G032 SYSCTRL node description.
> >
> > Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>
>
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-
> sysctr
> > +++ l.txt
> > @@ -0,0 +1,32 @@
> > +* Renesas R9A06G032 SYSCTRL
> > +
> > +Required Properties:
> > +
> > +  - compatible: Must be:
> > +    - "renesas,r9a06g032-sysctrl"
> > +  - reg: Base address and length of the SYSCTRL IO block.
> > +  - #clock-cells: Must be 1
>
> (repeating myself) No clocks/clock-names for the external clock inputs?
>
> "RZ/N1 has 3 clock sources, 1 reference clock inputs for RGMII, and 2
> reference clock outputs for RMII/MII."

Well, I'm trying to keep the binding as simple as possible, to dodge any
further discussion. Adding these will be possible later, I don't need them
for the moment anyway.

>
> The rest looks fine to me.
> Thanks!

Did you have a chance to review the clock driver proper? I'm pondering
sending a v9 since it's been a week (with very minor changes) -- but I
don't want to interrupt if you were in the process of reviewing...

Cheers,
Michel

>
> Gr{oetje,eeting}s,
>
>                         Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-
> m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds



Renesas Electronics Europe Ltd, Dukes Meadow, Millboard Road, Bourne End, Buckinghamshire, SL8 5FH, UK. Registered in England & Wales under Registered No. 04586709.

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

* Re: [PATCH v8 2/5] dt-bindings: clock: renesas,r9a06g032-sysctrl: documentation
  2018-06-13  6:38     ` Michel Pollet
@ 2018-06-13  7:17       ` Geert Uytterhoeven
  2018-06-13  8:53         ` M P
  0 siblings, 1 reply; 13+ messages in thread
From: Geert Uytterhoeven @ 2018-06-13  7:17 UTC (permalink / raw)
  To: Michel Pollet
  Cc: Linux-Renesas, Simon Horman, Phil Edworthy, Michel Pollet,
	Michael Turquette, Stephen Boyd, Rob Herring, Mark Rutland,
	Geert Uytterhoeven, linux-clk,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux Kernel Mailing List

Hi Michel,

On Wed, Jun 13, 2018 at 8:38 AM Michel Pollet
<michel.pollet@bp.renesas.com> wrote:
> On 11 June 2018 11:01, Geert wrote:
> > On Tue, Jun 5, 2018 at 10:36 AM Michel Pollet
> > <michel.pollet@bp.renesas.com> wrote:
> > > The Renesas R9A06G032 SYSCTRL node description.
> > >
> > > Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>
> >
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-
> > sysctr
> > > +++ l.txt
> > > @@ -0,0 +1,32 @@
> > > +* Renesas R9A06G032 SYSCTRL
> > > +
> > > +Required Properties:
> > > +
> > > +  - compatible: Must be:
> > > +    - "renesas,r9a06g032-sysctrl"
> > > +  - reg: Base address and length of the SYSCTRL IO block.
> > > +  - #clock-cells: Must be 1
> >
> > (repeating myself) No clocks/clock-names for the external clock inputs?
> >
> > "RZ/N1 has 3 clock sources, 1 reference clock inputs for RGMII, and 2
> > reference clock outputs for RMII/MII."
>
> Well, I'm trying to keep the binding as simple as possible, to dodge any
> further discussion. Adding these will be possible later, I don't need them
> for the moment anyway.

Don't you? The external clock inputs are at the root of the clock tree, so I'd
say you need them. Bolting them on later may become complicated, especially
if you care about DTB backwards compatibility.

The reset controller subsystem is optional anyway, and used only by a small
number of drivers, so support for resets can definitely be postponed.

> Did you have a chance to review the clock driver proper? I'm pondering
> sending a v9 since it's been a week (with very minor changes) -- but I
> don't want to interrupt if you were in the process of reviewing...

I had a quick glance. Looks OK mostly, so it's definitely heading for the right
direction!
One remaining question: do you need CLK_OF_DECLARE()?
Is there any reason your clock driver cannot be a platform driver, which is
the recommended way?

Thanks!

Gr{oetje,eeting}s,

                        Geert

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

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

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

* Re: [PATCH v8 2/5] dt-bindings: clock: renesas,r9a06g032-sysctrl: documentation
  2018-06-13  7:17       ` Geert Uytterhoeven
@ 2018-06-13  8:53         ` M P
  2018-06-13 11:48           ` Geert Uytterhoeven
  0 siblings, 1 reply; 13+ messages in thread
From: M P @ 2018-06-13  8:53 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: michel.pollet, linux-renesas-soc, Simon Horman, Phil Edworthy,
	buserror+upstream, Michael Turquette, sboyd, robh+dt,
	mark.rutland, geert+renesas, linux-clk, devicetree, linux-kernel

hi Geert,

On Wed, 13 Jun 2018 at 08:17, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>
> Hi Michel,
>
> On Wed, Jun 13, 2018 at 8:38 AM Michel Pollet
> <michel.pollet@bp.renesas.com> wrote:
> > On 11 June 2018 11:01, Geert wrote:
> > > On Tue, Jun 5, 2018 at 10:36 AM Michel Pollet
> > > <michel.pollet@bp.renesas.com> wrote:
> > > > The Renesas R9A06G032 SYSCTRL node description.
> > > >
> > > > Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>
> > >
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-
> > > sysctr
> > > > +++ l.txt
> > > > @@ -0,0 +1,32 @@
> > > > +* Renesas R9A06G032 SYSCTRL
> > > > +
> > > > +Required Properties:
> > > > +
> > > > +  - compatible: Must be:
> > > > +    - "renesas,r9a06g032-sysctrl"
> > > > +  - reg: Base address and length of the SYSCTRL IO block.
> > > > +  - #clock-cells: Must be 1
> > >
> > > (repeating myself) No clocks/clock-names for the external clock inputs?
> > >
> > > "RZ/N1 has 3 clock sources, 1 reference clock inputs for RGMII, and 2
> > > reference clock outputs for RMII/MII."
> >
> > Well, I'm trying to keep the binding as simple as possible, to dodge any
> > further discussion. Adding these will be possible later, I don't need them
> > for the moment anyway.
>
> Don't you? The external clock inputs are at the root of the clock tree, so I'd
> say you need them. Bolting them on later may become complicated, especially
> if you care about DTB backwards compatibility.

Well the input is fixed frequency -- and there is a clock (gate)
created for it in the driver
(CLK_RGMII_REF) so you can turn it on/off if you like...

The only configurable bit is a *nightmare* as the selection bit for
whether it is coming
from CLKOUT_D8 or from an external input is in a *completely different
IP block*. I'd
need another iomap() and all that stuff, and a custom driver for it.

If I were to implement it, I'd have to add a custom driver for that
clock, use the current
gate as a parent, iomap the selection bit register etc -- basically.
All of that for a use
case of *none ever* as most people would probably tweak that bit in
the bootloader
anyway -- also, I'd have zero capability for testing it.

As far as the output, they also have their own gates (already
created). They are also fixed
frequency and the only thing that matters to them is the pinmux
settings. So (soon) with the
pinmux driver, you can enable that clock properly without a special
driver, just by adding
that gate to your ethernet, and add the pinmux config for it.

So what do I go with that?

>
> The reset controller subsystem is optional anyway, and used only by a small
> number of drivers, so support for resets can definitely be postponed.
>
> > Did you have a chance to review the clock driver proper? I'm pondering
> > sending a v9 since it's been a week (with very minor changes) -- but I
> > don't want to interrupt if you were in the process of reviewing...
>
> I had a quick glance. Looks OK mostly, so it's definitely heading for the right
> direction!
> One remaining question: do you need CLK_OF_DECLARE()?
> Is there any reason your clock driver cannot be a platform driver, which is
> the recommended way?

I copied it straight out of clk-rcar-gen2.c -- I don't 'need' anything more than
instantiating my driver; does it make a difference? ie a one liner macro vs
adding an extra struct, 2 functions to do the same thing?
Just curious, sometime I lose track of that the goalpost is -- for
years I understood
that having OF was simpler and better all around?

Thanks!
Michel

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

* Re: [PATCH v8 2/5] dt-bindings: clock: renesas,r9a06g032-sysctrl: documentation
  2018-06-13  8:53         ` M P
@ 2018-06-13 11:48           ` Geert Uytterhoeven
  0 siblings, 0 replies; 13+ messages in thread
From: Geert Uytterhoeven @ 2018-06-13 11:48 UTC (permalink / raw)
  To: M P
  Cc: Michel Pollet, Linux-Renesas, Simon Horman, Phil Edworthy,
	Michel Pollet, Michael Turquette, Stephen Boyd, Rob Herring,
	Mark Rutland, Geert Uytterhoeven, linux-clk,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux Kernel Mailing List

Hi Michel,

On Wed, Jun 13, 2018 at 10:53 AM M P <buserror@gmail.com> wrote:
> On Wed, 13 Jun 2018 at 08:17, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> > On Wed, Jun 13, 2018 at 8:38 AM Michel Pollet
> > <michel.pollet@bp.renesas.com> wrote:
> > > On 11 June 2018 11:01, Geert wrote:
> > > > On Tue, Jun 5, 2018 at 10:36 AM Michel Pollet
> > > > <michel.pollet@bp.renesas.com> wrote:
> > > > > The Renesas R9A06G032 SYSCTRL node description.
> > > > >
> > > > > Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>
> > > >
> > > > > --- /dev/null
> > > > > +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-
> > > > sysctr
> > > > > +++ l.txt
> > > > > @@ -0,0 +1,32 @@
> > > > > +* Renesas R9A06G032 SYSCTRL
> > > > > +
> > > > > +Required Properties:
> > > > > +
> > > > > +  - compatible: Must be:
> > > > > +    - "renesas,r9a06g032-sysctrl"
> > > > > +  - reg: Base address and length of the SYSCTRL IO block.
> > > > > +  - #clock-cells: Must be 1
> > > >
> > > > (repeating myself) No clocks/clock-names for the external clock inputs?
> > > >
> > > > "RZ/N1 has 3 clock sources, 1 reference clock inputs for RGMII, and 2
> > > > reference clock outputs for RMII/MII."
> > >
> > > Well, I'm trying to keep the binding as simple as possible, to dodge any
> > > further discussion. Adding these will be possible later, I don't need them
> > > for the moment anyway.
> >
> > Don't you? The external clock inputs are at the root of the clock tree, so I'd
> > say you need them. Bolting them on later may become complicated, especially
> > if you care about DTB backwards compatibility.
>
> Well the input is fixed frequency -- and there is a clock (gate)
> created for it in the driver
> (CLK_RGMII_REF) so you can turn it on/off if you like...
>
> The only configurable bit is a *nightmare* as the selection bit for
> whether it is coming
> from CLKOUT_D8 or from an external input is in a *completely different
> IP block*. I'd
> need another iomap() and all that stuff, and a custom driver for it.
>
> If I were to implement it, I'd have to add a custom driver for that
> clock, use the current
> gate as a parent, iomap the selection bit register etc -- basically.
> All of that for a use
> case of *none ever* as most people would probably tweak that bit in
> the bootloader
> anyway -- also, I'd have zero capability for testing it.
>
> As far as the output, they also have their own gates (already
> created). They are also fixed
> frequency and the only thing that matters to them is the pinmux
> settings. So (soon) with the
> pinmux driver, you can enable that clock properly without a special
> driver, just by adding
> that gate to your ethernet, and add the pinmux config for it.
>
> So what do I go with that?

IC.

Still, DT describes the hardware, not (the limitations of) the software
implementation.  So you can have the external clock inputs in the DT
bindings and in the DTS, but ignore complicated routing and source
selection in the driver.

> > > Did you have a chance to review the clock driver proper? I'm pondering
> > > sending a v9 since it's been a week (with very minor changes) -- but I
> > > don't want to interrupt if you were in the process of reviewing...
> >
> > I had a quick glance. Looks OK mostly, so it's definitely heading for the right
> > direction!
> > One remaining question: do you need CLK_OF_DECLARE()?
> > Is there any reason your clock driver cannot be a platform driver, which is
> > the recommended way?
>
> I copied it straight out of clk-rcar-gen2.c -- I don't 'need' anything more than
> instantiating my driver; does it make a difference? ie a one liner macro vs
> adding an extra struct, 2 functions to do the same thing?

clk-rcar-gen2.c is an old (early DT CCF) driver.
Please check out renesas-cpg-mssr.c for something newer.
Having a platform_driver means you're also having a struct device,
and can do power management, if needed.

> Just curious, sometime I lose track of that the goalpost is -- for
> years I understood
> that having OF was simpler and better all around?

"having OF" does not mean CLK_OF_DECLARE().
Those *_OF_DECLARE() macros impose a very strict initialization
order, which is not always suitable. Hence the trend to move to plain
platform drivers.

Gr{oetje,eeting}s,

                        Geert

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

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

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

end of thread, other threads:[~2018-06-13 11:48 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-05  8:29 [PATCH v8 0/5] arm: Base support for Renesas RZN1D-DB Board Michel Pollet
2018-06-05  8:29 ` [PATCH v8 1/5] dt-bindings: Add the r9a06g032-sysctrl.h file Michel Pollet
2018-06-05  8:29 ` [PATCH v8 2/5] dt-bindings: clock: renesas,r9a06g032-sysctrl: documentation Michel Pollet
2018-06-11 10:00   ` Geert Uytterhoeven
2018-06-13  6:38     ` Michel Pollet
2018-06-13  7:17       ` Geert Uytterhoeven
2018-06-13  8:53         ` M P
2018-06-13 11:48           ` Geert Uytterhoeven
2018-06-05  8:29 ` [PATCH v8 3/5] ARM: dts: Renesas R9A06G032 base device tree file Michel Pollet
2018-06-06  8:44   ` Simon Horman
2018-06-05  8:30 ` [PATCH v8 4/5] ARM: dts: Renesas RZN1D-DB Board base file Michel Pollet
2018-06-06  8:45   ` Simon Horman
2018-06-05  8:30 ` [PATCH v8 5/5] clk: renesas: Renesas R9A06G032 clock driver Michel Pollet

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