clk: Add APM X-Gene SoC clock driver
Subsystems (2)
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
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
@@ -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
@@ -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
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
@@ -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 = <ðclk 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
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
@@ -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
PATCH v3 1/3 clk: Add APM X-Gene SoC clock driver for reference, PLL, and device clocks.
In reply to Loc HoQuoted 12 lines · Loc Ho
clk: Add APM X-Gene SoC clock driver for reference, PLL, and device clocks.
Signed-off-by Loc Ho <[email protected]>Signed-off-by Kumar Sankaran <[email protected]>Signed-off-by Vinayak Kale <[email protected]>Signed-off-by Feng Kan <[email protected]>--- 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" , ¶meters.flags)) + parameters.flags =0 ;
As mentioned previously, I believe you could use the standard status property instead of flags.
Thanks,
Mark.
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" , ¶meters.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