Skip to contentSkip to conversation

clk: Add APM X-Gene SoC clock driver

PATCH Superseded Loc Ho 2 participants 6 messages Jun 24, 2013

Subsystems (2)

v3 of 5 Superseded Latest is v5 →

lore
Share & tools
lore

Loc Ho

author
#0 lore raw

v3 cover clk: Add APM X-Gene SoC clock driver

This patch adds APM X-Gene SoC clock driver support. Reference, PCP PLL, SoC PCP, and Ethernet clocks are defined via the DTS.

-v3:
* Make DTS compatible type for SoC PLL and PCP PLL
* Make use of of_iomap instead direct ioremap call
* Make kzalloc with variable instead structure
* Remove DTS binding for fixed-clock and fixed_factor_clock
* Remove unnecessary arch_initcall

-v2:
* Make depends on ARM64
* Fix duplicate registration

-v1 - Initial post

Loc Ho (3):
clk: Add APM X-Gene SoC clock driver for reference, PLL, and device
clocks.
clk: arm64: Add DTS clock entry for APM X-Gene Storm SoC with
reference to
Documentation: Add documentation for APM X-Gene clock binding with
PLL and

 Documentation/devicetree/bindings/clock/xgene.txt |   90 ++++
 arch/arm64/boot/dts/apm-storm.dtsi                |   75 +++
 drivers/clk/Kconfig                               |    7 +
 drivers/clk/Makefile                              |    1 +
 drivers/clk/clk-xgene.c                           |  538 +++++++++++++++++++++
 5 files changed, 711 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/xgene.txt
 create mode 100644 drivers/clk/clk-xgene.c
author
#1 lore raw

PATCH v3 1/3 clk: Add APM X-Gene SoC clock driver for reference, PLL, and device clocks.

clk: Add APM X-Gene SoC clock driver for reference, PLL, and device clocks.

---
 drivers/clk/Kconfig     |    7 +
 drivers/clk/Makefile    |    1 +
 drivers/clk/clk-xgene.c |  538 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 546 insertions(+), 0 deletions(-)
 create mode 100644 drivers/clk/clk-xgene.c
drivers/clk/Kconfig +7 -0
index 0357ac4..534a722 100644
@@ -81,6 +81,13 @@ config COMMON_CLK_AXI_CLKGEN
 	  Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx
 	  FPGAs. It is commonly used in Analog Devices' reference designs.
 
+config COMMON_CLK_XGENE
+	bool "Clock driver for APM XGene SoC"
+	default y
+	depends on ARM64
+	---help---
+	  Sypport for the APM X-Gene SoC reference, PLL, and device clocks.
+
 endmenu
 
 source "drivers/clk/mvebu/Kconfig"
drivers/clk/Makefile +1 -0
index 137d3e7..4c96337 100644
@@ -39,3 +39,4 @@ obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
 obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
 obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
 obj-$(CONFIG_CLK_TWL6040)	+= clk-twl6040.o
+obj-$(CONFIG_COMMON_CLK_XGENE)  += clk-xgene.o
drivers/clk/clk-xgene.c new file +538 -0

538 lines not on this page · raw message

Signature · 1 line
1.5.5
author
#2 lore raw

PATCH v3 2/3 clk: arm64: Add DTS clock entry for APM X-Gene Storm SoC

clk: arm64: Add DTS clock entry for APM X-Gene Storm SoC with reference to reference, PCP PLL, SoC PLL, and Ethernet clocks.

---
 arch/arm64/boot/dts/apm-storm.dtsi |   75 ++++++++++++++++++++++++++++++++++++
 1 files changed, 75 insertions(+), 0 deletions(-)
arch/arm64/boot/dts/apm-storm.dtsi +75 -0
index bfdc578..3f2ef74 100644
@@ -103,6 +103,81 @@
 		#size-cells = <2>;
 		ranges;
 
+		clocks {
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			refclk: refclk {
+				compatible = "fixed-clock";
+				#clock-cells = <1>;
+				clock-frequency = <100000000>;
+				clock-output-names = "refclk";
+			};
+
+			pcppll: pcppll at 17000100 {
+				compatible = "apm,xgene-pcppll-clock";
+				#clock-cells = <1>;
+				clocks = <&refclk 0>;
+				clock-names = "pcppll";
+				reg = <0x0 0x17000100 0x0 0x1000>;
+				clock-output-names = "pcppll";
+				type = <0>;
+			};
+
+			socpll: socpll at 17000120 {
+				compatible = "apm,xgene-socpll-clock";
+				#clock-cells = <1>;
+				clocks = <&refclk 0>;
+				clock-names = "socpll";
+				reg = <0x0 0x17000120 0x0 0x1000>;
+				clock-output-names = "socpll";
+				type = <1>;
+			};
+
+			socplldiv2: socplldiv2  {
+				compatible = "fixed-factor-clock";
+				#clock-cells = <1>;
+				clocks = <&socpll 0>;
+				clock-names = "socplldiv2";
+				clock-mult = <1>;
+				clock-div = <2>;
+				clock-output-names = "socplldiv2";
+			};
+
+			qmlclk: qmlclk {
+				compatible = "apm,xgene-device-clock";
+				#clock-cells = <1>;
+				clocks = <&socplldiv2 0>;
+				clock-names = "qmlclk";
+				reg = <0x0 0x1703C000 0x0 0x1000
+				       0x0 0x00000000 0x0 0x0000>;
+				clock-output-names = "qmlclk";
+			};
+
+			ethclk: ethclk {
+				compatible = "apm,xgene-device-clock";
+				#clock-cells = <1>;
+				clocks = <&socplldiv2 0>;
+				clock-names = "ethclk";
+				reg = <0x0 0x00000000 0x0 0x0000
+				       0x0 0x17000000 0x0 0x1000>;
+				divider-offset = <0x238>;
+				divider-width = <0x9>;
+				divider-shift = <0x0>;
+				clock-output-names = "ethclk";
+			};
+
+			eth8clk: eth8clk {
+				compatible = "apm,xgene-device-clock";
+				#clock-cells = <1>;
+				clocks = <&ethclk 0>;
+				clock-names = "eth8clk";
+				reg = <0x0 0x1702C000 0x0 0x1000
+				       0x0 0x00000000 0x0 0x0000>;
+				clock-output-names = "eth8clk";
+			};
+		};
+
 		serial0: serial at 1c020000 {
 			device_type = "serial";
 			compatible = "ns16550";
Signature · 1 line
1.5.5
author
#3 lore raw

PATCH v3 3/3 Documentation: Add documentation for APM X-Gene clock binding

Documentation: Add documentation for APM X-Gene clock binding with PLL and device clocks.

---
 Documentation/devicetree/bindings/clock/xgene.txt |   90 +++++++++++++++++++++
 1 files changed, 90 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/xgene.txt
Documentation/devicetree/bindings/clock/xgene.txt new file +90 -0
new file mode 100644
index 0000000..4f864bd
@@ -0,0 +1,90 @@
+Device Tree Clock bindings for APM X-Gene
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : shall be one of the following:
+	"apm,xgene-socpll-clock" - for a X-Gene SoC PLL clock
+	"apm,xgene-pcppll-clock" - for a X-Gene PCP PLL clock
+	"apm,xgene-device-clock" - for a X-Gene device clock
+
+Required properties for SoC or PCP PLL clocks:
+- reg : shall be the physical PLL register address for the pll clock.
+- clocks : shall be the input parent clock phandle for the clock. This should
+	be the reference clock.
+- #clock-cells : shall be set to 1.
+- clock-output-names : shall be the name of the PLL referenced by derive
+  clock.
+Optional properties for PLL clocks:
+- clock-names : shall be the name of the PLL. If missing, use the device name.
+
+Required properties for device clocks:
+- reg : shall be the physical CSR reset address base and physical CSR divider
+        address base. If one does not exist, specify 0 for address and 0 for 
+        size.
+- clocks : shall be the input parent clock phandle for the clock.
+- #clock-cells : shall be set to 1.
+- clock-output-names : shall be the name of the device referenced.
+Optional properties for device clocks:
+- clock-names : shall be the name of the device clock. If missing, use the
+                device name.
+- flags : Any clock flags. ie. use 0x8 to leave clock un-touch if not
+          referenced. Default is 0.
+- csr-offset : Offset to the CSR reset register from the reset address base.
+               Default is 0.
+- csr-mask : CSR reset mask bit. Default is 0xF.
+- enable-offset : Offset to the enable register from the reset address base.
+                  Default is 0x8.
+- enable-mask : CSR enable mask bit. Default is 0xF.
+- divider-offset : Offset to the divider CSR register from the divider base.
+                   Default is 0x0.
+- divider-width : Width of the divider register. Default is 0.
+- divider-shift : Bit shift of the divider register. Default is 0.
+
+For example:
+
+	pcppll: pcppll at 17000100 {
+		compatible = "apm,xgene-pcppll-clock";
+		#clock-cells = <1>;
+		clocks = <&refclk 0>;
+		clock-names = "pcppll";
+		reg = <0x0 0x17000100 0x0 0x1000>;
+		clock-output-names = "pcppll";
+		type = <0>;
+	};
+
+	socpll: socpll at 17000120 {
+		compatible = "apm,xgene-socpll-clock";
+		#clock-cells = <1>;
+		clocks = <&refclk 0>;
+		clock-names = "socpll";
+		reg = <0x0 0x17000120 0x0 0x1000>;
+		clock-output-names = "socpll";
+		type = <1>;
+	};
+
+	qmlclk: qmlclk {
+		compatible = "apm,xgene-device-clock";
+		#clock-cells = <1>;
+		clocks = <&socplldiv2 0>;
+		clock-names = "qmlclk";
+		reg = <0x0 0x1703C000 0x0 0x1000
+			0x0 0x00000000 0x0 0x0000>;
+		clock-output-names = "qmlclk";
+	};
+
+	ethclk: ethclk {
+		compatible = "apm,xgene-device-clock";
+		#clock-cells = <1>;
+		clocks = <&socplldiv2 0>;
+		clock-names = "ethclk";
+		reg = <0x0 0x00000000 0x0 0x0000
+			0x0 0x17000000 0x0 0x1000>;
+			divider-offset = <0x238>;
+		divider-width = <0x9>;
+		divider-shift = <0x0>;
+		clock-output-names = "ethclk";
+	};
+
Signature · 1 line
1.5.5
#4 lore raw

PATCH v3 1/3 clk: Add APM X-Gene SoC clock driver for reference, PLL, and device clocks.

In reply to Loc Ho
Quoted 12 lines · Loc Ho

clk: Add APM X-Gene SoC clock driver for reference, PLL, and device clocks.

---
 drivers/clk/Kconfig     |    7 +
 drivers/clk/Makefile    |    1 +
 drivers/clk/clk-xgene.c |  538 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 546 insertions(+), 0 deletions(-)
 create mode 100644 drivers/clk/clk-xgene.c

[...]

Quoted 10 lines
drivers/clk/clk-xgene.c new file +10 -0
+static void __init xgene_devclk_init(struct device_node *np)
+{
+       const char *clk_name = np->full_name;
+       struct clk *clk;
+       struct resource res;
+       int rc;
+       struct xgene_dev_parameters parameters;
+
+       rc = of_address_to_resource(np, 0, &res);
+       if (rc != 0) {

drivers/clk/clk-xgene.c line 474

Quoted 10 lines
drivers/clk/clk-xgene.c new file +10 -0
+               pr_err("no DTS CSR register for %s\n", np->full_name);
+               return;
+       }
+       if (resource_size(&res)) {
+               parameters.csr_reg = of_iomap(np, 0);
+               if (parameters.csr_reg == NULL) {
+                       pr_err("Unable to map CSR register for %s\n",
+                               np->full_name);
+                       return;
+               }

In my earlier post, I'd failed to understand what you were doing here -- testing that a reg represents a window of non-zero size. I don't think you need to describe the registers that aren't present at all, and I believe you can use the more standard reg-names property to describe this case. e.g. When you only have the "div" register bank, and not the "csr" bank, you could describe this as:

some-clock {
	compatible = "apm,xgene-device-clock";
	reg = <0 0x12340000 0 0x1000>;
	reg-names = "div-reg";

	...
}

... and when you had both, you could describe this as:

some-clock {
	compatible = "apm,xgene-device-clock";
	reg = <0 0x12340000 0 0x1000>,
	      <0 0x23450000 0 0x1000>;
	reg-names = "div", "csr";

	...
}

This way, you don't describe registers that aren't actually present, and it's clearer which register's which.

It looks like of_address_to_resource reads the reg-names property, so you could test against the resource's name to figure out which reg you have (if you only have one). My earlier comment to use of_iomap was misplaced, as there doesn't seem to be anything like of_iomap_by_name, and you have to use the resource anyway to get the name.

Quoted 13 lines
drivers/clk/clk-xgene.c new file +13 -0
+       } else {
+               parameters.csr_reg = NULL;
+       }
+
+       rc = of_address_to_resource(np, 1, &res);
+       if (rc != 0) {
+               pr_err("no DTS DIV register for %s\n", np->full_name);
+               return;
+       }
+       if (resource_size(&res)) {
+               parameters.divider_reg = of_iomap(np, 1);
+               if (parameters.divider_reg == NULL) {
+                       pr_err("Unable to map DIV register for %s\n",

drivers/clk/clk-xgene.c line 497

Quoted 10 lines
drivers/clk/clk-xgene.c new file +10 -0
+                               np->full_name);
+                       if (parameters.csr_reg)
+                               iounmap(parameters.csr_reg);
+                       return;
+               }
+       } else {
+               parameters.divider_reg = NULL;
+       }
+       if (of_property_read_u32(np, "flags", &parameters.flags))
+               parameters.flags = 0;

As mentioned previously, I believe you could use the standard status property instead of flags.

Thanks,
Mark.

author
#5 lore raw

PATCH v3 1/3 clk: Add APM X-Gene SoC clock driver for reference, PLL, and device clocks.

Hi Mar,

Quoted 5 lines

drivers/clk/clk-xgene.c line 497

Quoted 2 lines
drivers/clk/clk-xgene.c new file +2 -0
+       if (of_property_read_u32(np, "flags", &parameters.flags))
+               parameters.flags = 0;

As mentioned previously, I believe you could use the standard status property instead of flags.

[Loc Ho]
Okay... As mentioned, this will enforce multiple DTS file or patching the DTS entry for clock as well as the driver DTS entry.

-Loc