Discussion:
[PATCH v4 1/5] dt-bindings: update device tree binding for Allwinner PRCM CCUs
Icenowy Zheng
2017-04-04 09:50:56 UTC
Permalink
From: Icenowy Zheng <***@aosc.xyz>

Many Allwinner SoCs after A31 have a CCU in PRCM block.

Give the ones on H3 and A64 compatible strings.

Signed-off-by: Icenowy Zheng <***@aosc.xyz>
Acked-by: Rob Herring <***@kernel.org>
---
Changes in v4:
- Add Rob's ACK.
Changes in v3:
- Removed frequency info of iosc in this device tree binding document.
Changes in v2:
- Add iosc for R_CCU's on H3/A64.

Documentation/devicetree/bindings/clock/sunxi-ccu.txt | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
index 68512aa398a9..e9c5a1d9834a 100644
--- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
@@ -7,9 +7,11 @@ Required properties :
- "allwinner,sun8i-a23-ccu"
- "allwinner,sun8i-a33-ccu"
- "allwinner,sun8i-h3-ccu"
+ - "allwinner,sun8i-h3-r-ccu"
- "allwinner,sun8i-v3s-ccu"
- "allwinner,sun9i-a80-ccu"
- "allwinner,sun50i-a64-ccu"
+ - "allwinner,sun50i-a64-r-ccu"
- "allwinner,sun50i-h5-ccu"

- reg: Must contain the registers base address and length
@@ -20,7 +22,10 @@ Required properties :
- #clock-cells : must contain 1
- #reset-cells : must contain 1

-Example:
+For the PRCM CCUs on H3/A64, one more clock is needed:
+- "iosc": the SoC's internal frequency oscillator
+
+Example for generic CCU:
ccu: ***@01c20000 {
compatible = "allwinner,sun8i-h3-ccu";
reg = <0x01c20000 0x400>;
@@ -29,3 +34,13 @@ ccu: ***@01c20000 {
#clock-cells = <1>;
#reset-cells = <1>;
};
+
+Example for PRCM CCU:
+r_ccu: ***@01f01400 {
+ compatible = "allwinner,sun50i-a64-r-ccu";
+ reg = <0x01f01400 0x100>;
+ clocks = <&osc24M>, <&osc32k>, <&iosc>;
+ clock-names = "hosc", "losc", "iosc";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+};
--
2.12.2
Icenowy Zheng
2017-04-04 09:51:00 UTC
Permalink
From: Icenowy Zheng <***@aosc.xyz>

Allwinner A64 have a dedicated pin controller to manage the PL pin bank.
As the driver and the required clock support are added, add the device
node for it.

Signed-off-by: Icenowy Zheng <***@aosc.xyz>
---
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 1d4e5bcced0c..6bc606b4d74d 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -409,5 +409,17 @@
#clock-cells = <1>;
#reset-cells = <1>;
};
+
+ r_pio: ***@01f02c00 {
+ compatible = "allwinner,sun50i-a64-r-pinctrl";
+ reg = <0x01f02c00 0x400>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&r_ccu 3>, <&osc24M>, <&osc32k>;
+ clock-names = "apb", "hosc", "losc";
+ gpio-controller;
+ #gpio-cells = <3>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
};
};
--
2.12.2
Icenowy Zheng
2017-04-04 09:50:59 UTC
Permalink
From: Icenowy Zheng <***@aosc.xyz>

Now we have driver for the PRCM CCU, switch to use it instead of
old-style clock nodes for apb0-related clocks in sunxi-h3-h5.dtsi .

The mux 3 of R_CCU is still the internal oscillator, which is said to be
16MHz plus minus 30%, and get a measured value of 15MHz~16MHz on my two
H3 boards and one H5 board.

Signed-off-by: Icenowy Zheng <***@aosc.xyz>
---
Changes in v4:
- Temporarily dropped the CCU headers.
Changes in v3:
- Change osc32000 to iosc.

arch/arm/boot/dts/sunxi-h3-h5.dtsi | 45 ++++++++++++--------------------------
1 file changed, 14 insertions(+), 31 deletions(-)

diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 6640ebfa6419..1aeeacb3a884 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -68,31 +68,12 @@
clock-output-names = "osc32k";
};

- apb0: apb0_clk {
- compatible = "fixed-factor-clock";
+ iosc: internal-osc-clk {
#clock-cells = <0>;
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&osc24M>;
- clock-output-names = "apb0";
- };
-
- apb0_gates: ***@01f01428 {
- compatible = "allwinner,sun8i-h3-apb0-gates-clk",
- "allwinner,sun4i-a10-gates-clk";
- reg = <0x01f01428 0x4>;
- #clock-cells = <1>;
- clocks = <&apb0>;
- clock-indices = <0>, <1>;
- clock-output-names = "apb0_pio", "apb0_ir";
- };
-
- ir_clk: ***@01f01454 {
- compatible = "allwinner,sun4i-a10-mod0-clk";
- reg = <0x01f01454 0x4>;
- #clock-cells = <0>;
- clocks = <&osc32k>, <&osc24M>;
- clock-output-names = "ir";
+ compatible = "fixed-clock";
+ clock-frequency = <16000000>;
+ clock-accuracy = <300000000>;
+ clock-output-names = "iosc";
};
};

@@ -576,9 +557,12 @@
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
};

- apb0_reset: ***@01f014b0 {
- reg = <0x01f014b0 0x4>;
- compatible = "allwinner,sun6i-a31-clock-reset";
+ r_ccu: ***@1f01400 {
+ compatible = "allwinner,sun50i-a64-r-ccu";
+ reg = <0x01f01400 0x100>;
+ clocks = <&osc24M>, <&osc32k>, <&iosc>;
+ clock-names = "hosc", "losc", "iosc";
+ #clock-cells = <1>;
#reset-cells = <1>;
};

@@ -589,9 +573,9 @@

ir: ***@01f02000 {
compatible = "allwinner,sun5i-a13-ir";
- clocks = <&apb0_gates 1>, <&ir_clk>;
+ clocks = <&r_ccu 4>, <&r_ccu 11>;
clock-names = "apb", "ir";
- resets = <&apb0_reset 1>;
+ resets = <&r_ccu 0>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x01f02000 0x40>;
status = "disabled";
@@ -601,9 +585,8 @@
compatible = "allwinner,sun8i-h3-r-pinctrl";
reg = <0x01f02c00 0x400>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>;
+ clocks = <&r_ccu 3>, <&osc24M>, <&osc32k>;
clock-names = "apb", "hosc", "losc";
- resets = <&apb0_reset 0>;
gpio-controller;
#gpio-cells = <3>;
interrupt-controller;
--
2.12.2
Ondřej Jirman
2017-07-19 22:59:33 UTC
Permalink
Hi,
Post by Icenowy Zheng
Now we have driver for the PRCM CCU, switch to use it instead of
old-style clock nodes for apb0-related clocks in sunxi-h3-h5.dtsi .
The mux 3 of R_CCU is still the internal oscillator, which is said to be
16MHz plus minus 30%, and get a measured value of 15MHz~16MHz on my two
H3 boards and one H5 board.
There's issue with the new r_ccu that breaks r_i2c. (no devices can be
found on the bus). Reverting this patch fixes the issue with the I2C
controller. (everything else being the same)

Here's the code I'm using: https://github.com/megous/linux/commits/oran
ge-pi-4.12

The last commit is the revert.

The issue manifests itself by non-working DVFS, because kernel lacks
access to SY8106A regulator, because r_i2c doesn't work with sunxi-ng
clock driver (sun8i-r).

Relevant difference in registers between working/non-working state is
just this (diff -u):

0x01f02400 = 0x00000000
0x01f02404 = 0x00000000
-0x01f02408 = 0x00000091
+0x01f02408 = 0x00000095 DATA register inisde the I2C controller
0x01f0240c = 0x00000044
0x01f02410 = 0x000000f8
-0x01f02414 = 0x00000059
+0x01f02414 = 0x00000000 CLOCK setup register inside the I2C controller
0x01f02418 = 0x00000000
0x01f0241c = 0x00000000
0x01f02420 = 0x0000003a

It looks like the new sunxi-ng clock driver causes the I2C driver to
not correctly configure the CLOCK register. I don't know why and I'm
not sure how to deal with this. Any ideas what can I do next?

thank you and regards,
o.
Post by Icenowy Zheng
---
- Temporarily dropped the CCU headers.
- Change osc32000 to iosc.
arch/arm/boot/dts/sunxi-h3-h5.dtsi | 45 ++++++++++++--------------------------
1 file changed, 14 insertions(+), 31 deletions(-)
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 6640ebfa6419..1aeeacb3a884 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -68,31 +68,12 @@
clock-output-names = "osc32k";
};
- apb0: apb0_clk {
- compatible = "fixed-factor-clock";
+ iosc: internal-osc-clk {
#clock-cells = <0>;
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&osc24M>;
- clock-output-names = "apb0";
- };
-
- compatible = "allwinner,sun8i-h3-apb0-gates-clk",
- "allwinner,sun4i-a10-gates-clk";
- reg = <0x01f01428 0x4>;
- #clock-cells = <1>;
- clocks = <&apb0>;
- clock-indices = <0>, <1>;
- clock-output-names = "apb0_pio", "apb0_ir";
- };
-
- compatible = "allwinner,sun4i-a10-mod0-clk";
- reg = <0x01f01454 0x4>;
- #clock-cells = <0>;
- clocks = <&osc32k>, <&osc24M>;
- clock-output-names = "ir";
+ compatible = "fixed-clock";
+ clock-frequency = <16000000>;
+ clock-accuracy = <300000000>;
+ clock-output-names = "iosc";
};
};
@@ -576,9 +557,12 @@
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
};
- reg = <0x01f014b0 0x4>;
- compatible = "allwinner,sun6i-a31-clock-reset";
+ compatible = "allwinner,sun50i-a64-r-ccu";
+ reg = <0x01f01400 0x100>;
+ clocks = <&osc24M>, <&osc32k>, <&iosc>;
+ clock-names = "hosc", "losc", "iosc";
+ #clock-cells = <1>;
#reset-cells = <1>;
};
@@ -589,9 +573,9 @@
compatible = "allwinner,sun5i-a13-ir";
- clocks = <&apb0_gates 1>, <&ir_clk>;
+ clocks = <&r_ccu 4>, <&r_ccu 11>;
clock-names = "apb", "ir";
- resets = <&apb0_reset 1>;
+ resets = <&r_ccu 0>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x01f02000 0x40>;
status = "disabled";
@@ -601,9 +585,8 @@
compatible = "allwinner,sun8i-h3-r-pinctrl";
reg = <0x01f02c00 0x400>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>;
+ clocks = <&r_ccu 3>, <&osc24M>, <&osc32k>;
clock-names = "apb", "hosc", "losc";
- resets = <&apb0_reset 0>;
gpio-controller;
#gpio-cells = <3>;
interrupt-controller;
--
2.12.2
i***@aosc.io
2017-07-20 02:03:57 UTC
Permalink
在 2017-07-20 06:59,Ondřej Jirman 写道:
Post by Ondřej Jirman
Hi,
Post by Icenowy Zheng
Now we have driver for the PRCM CCU, switch to use it instead of
old-style clock nodes for apb0-related clocks in sunxi-h3-h5.dtsi .
The mux 3 of R_CCU is still the internal oscillator, which is said to be
16MHz plus minus 30%, and get a measured value of 15MHz~16MHz on my two
H3 boards and one H5 board.
There's issue with the new r_ccu that breaks r_i2c. (no devices can be
found on the bus). Reverting this patch fixes the issue with the I2C
controller. (everything else being the same)
Here's the code I'm using: https://github.com/megous/linux/commits/oran
ge-pi-4.12
The last commit is the revert.
The issue manifests itself by non-working DVFS, because kernel lacks
access to SY8106A regulator, because r_i2c doesn't work with sunxi-ng
clock driver (sun8i-r).
Relevant difference in registers between working/non-working state is
0x01f02400 = 0x00000000
0x01f02404 = 0x00000000
-0x01f02408 = 0x00000091
+0x01f02408 = 0x00000095 DATA register inisde the I2C controller
0x01f0240c = 0x00000044
0x01f02410 = 0x000000f8
-0x01f02414 = 0x00000059
+0x01f02414 = 0x00000000 CLOCK setup register inside the I2C controller
0x01f02418 = 0x00000000
0x01f0241c = 0x00000000
0x01f02420 = 0x0000003a
It looks like the new sunxi-ng clock driver causes the I2C driver to
not correctly configure the CLOCK register. I don't know why and I'm
not sure how to deal with this. Any ideas what can I do next?
thank you and regards,
o.
It seems to be a very very very weird problem -- the CPUS_CFG register
seems to be not accessible in non-secure mode on H3, and if the r_ccu
driver reads it a value of 0x0 is read out (which means that the parent
of ar100 is osc32k), but the real initial value of the register is
0x00010000 (which means the parent is osc24M).

So the bus clock of r_i2c is wrongly claimed as 32kHz, not 24MHz, then
the r_i2c fails to work.

This clock problem doesn't exist for A64.
Post by Ondřej Jirman
Post by Icenowy Zheng
---
- Temporarily dropped the CCU headers.
- Change osc32000 to iosc.
arch/arm/boot/dts/sunxi-h3-h5.dtsi | 45
++++++++++++--------------------------
1 file changed, 14 insertions(+), 31 deletions(-)
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 6640ebfa6419..1aeeacb3a884 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -68,31 +68,12 @@
clock-output-names = "osc32k";
};
- apb0: apb0_clk {
- compatible = "fixed-factor-clock";
+ iosc: internal-osc-clk {
#clock-cells = <0>;
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&osc24M>;
- clock-output-names = "apb0";
- };
-
- compatible = "allwinner,sun8i-h3-apb0-gates-clk",
- "allwinner,sun4i-a10-gates-clk";
- reg = <0x01f01428 0x4>;
- #clock-cells = <1>;
- clocks = <&apb0>;
- clock-indices = <0>, <1>;
- clock-output-names = "apb0_pio", "apb0_ir";
- };
-
- compatible = "allwinner,sun4i-a10-mod0-clk";
- reg = <0x01f01454 0x4>;
- #clock-cells = <0>;
- clocks = <&osc32k>, <&osc24M>;
- clock-output-names = "ir";
+ compatible = "fixed-clock";
+ clock-frequency = <16000000>;
+ clock-accuracy = <300000000>;
+ clock-output-names = "iosc";
};
};
@@ -576,9 +557,12 @@
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
};
- reg = <0x01f014b0 0x4>;
- compatible = "allwinner,sun6i-a31-clock-reset";
+ compatible = "allwinner,sun50i-a64-r-ccu";
+ reg = <0x01f01400 0x100>;
+ clocks = <&osc24M>, <&osc32k>, <&iosc>;
+ clock-names = "hosc", "losc", "iosc";
+ #clock-cells = <1>;
#reset-cells = <1>;
};
@@ -589,9 +573,9 @@
compatible = "allwinner,sun5i-a13-ir";
- clocks = <&apb0_gates 1>, <&ir_clk>;
+ clocks = <&r_ccu 4>, <&r_ccu 11>;
clock-names = "apb", "ir";
- resets = <&apb0_reset 1>;
+ resets = <&r_ccu 0>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x01f02000 0x40>;
status = "disabled";
@@ -601,9 +585,8 @@
compatible = "allwinner,sun8i-h3-r-pinctrl";
reg = <0x01f02c00 0x400>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>;
+ clocks = <&r_ccu 3>, <&osc24M>, <&osc32k>;
clock-names = "apb", "hosc", "losc";
- resets = <&apb0_reset 0>;
gpio-controller;
#gpio-cells = <3>;
interrupt-controller;
--
2.12.2
_______________________________________________
linux-arm-kernel mailing list
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
i***@aosc.io
2017-07-20 02:19:11 UTC
Permalink
Post by i***@aosc.io
在 2017-07-20 06:59,Ondřej Jirman 写道:
Post by Ondřej Jirman
Hi,
Post by Icenowy Zheng
Now we have driver for the PRCM CCU, switch to use it instead of
old-style clock nodes for apb0-related clocks in sunxi-h3-h5.dtsi .
The mux 3 of R_CCU is still the internal oscillator, which is said to be
16MHz plus minus 30%, and get a measured value of 15MHz~16MHz on my two
H3 boards and one H5 board.
There's issue with the new r_ccu that breaks r_i2c. (no devices can be
found on the bus). Reverting this patch fixes the issue with the I2C
controller. (everything else being the same)
https://github.com/megous/linux/commits/oran
ge-pi-4.12
The last commit is the revert.
The issue manifests itself by non-working DVFS, because kernel lacks
access to SY8106A regulator, because r_i2c doesn't work with sunxi-ng
clock driver (sun8i-r).
Relevant difference in registers between working/non-working state is
0x01f02400 = 0x00000000
0x01f02404 = 0x00000000
-0x01f02408 = 0x00000091
+0x01f02408 = 0x00000095 DATA register inisde the I2C controller
0x01f0240c = 0x00000044
0x01f02410 = 0x000000f8
-0x01f02414 = 0x00000059
+0x01f02414 = 0x00000000 CLOCK setup register inside the I2C
controller
0x01f02418 = 0x00000000
0x01f0241c = 0x00000000
0x01f02420 = 0x0000003a
It looks like the new sunxi-ng clock driver causes the I2C driver to
not correctly configure the CLOCK register. I don't know why and I'm
not sure how to deal with this. Any ideas what can I do next?
thank you and regards,
o.
It seems to be a very very very weird problem -- the CPUS_CFG register
seems to be not accessible in non-secure mode on H3, and if the r_ccu
driver reads it a value of 0x0 is read out (which means that the parent
of ar100 is osc32k), but the real initial value of the register is
0x00010000 (which means the parent is osc24M).
So the bus clock of r_i2c is wrongly claimed as 32kHz, not 24MHz, then
the r_i2c fails to work.
This clock problem doesn't exist for A64.
H5 doesn't have this issue either.
Post by i***@aosc.io
Post by Ondřej Jirman
Post by Icenowy Zheng
---
- Temporarily dropped the CCU headers.
- Change osc32000 to iosc.
arch/arm/boot/dts/sunxi-h3-h5.dtsi | 45
++++++++++++--------------------------
1 file changed, 14 insertions(+), 31 deletions(-)
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 6640ebfa6419..1aeeacb3a884 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -68,31 +68,12 @@
clock-output-names = "osc32k";
};
- apb0: apb0_clk {
- compatible = "fixed-factor-clock";
+ iosc: internal-osc-clk {
#clock-cells = <0>;
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&osc24M>;
- clock-output-names = "apb0";
- };
-
- compatible = "allwinner,sun8i-h3-apb0-gates-clk",
- "allwinner,sun4i-a10-gates-clk";
- reg = <0x01f01428 0x4>;
- #clock-cells = <1>;
- clocks = <&apb0>;
- clock-indices = <0>, <1>;
- clock-output-names = "apb0_pio", "apb0_ir";
- };
-
- compatible = "allwinner,sun4i-a10-mod0-clk";
- reg = <0x01f01454 0x4>;
- #clock-cells = <0>;
- clocks = <&osc32k>, <&osc24M>;
- clock-output-names = "ir";
+ compatible = "fixed-clock";
+ clock-frequency = <16000000>;
+ clock-accuracy = <300000000>;
+ clock-output-names = "iosc";
};
};
@@ -576,9 +557,12 @@
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
};
- reg = <0x01f014b0 0x4>;
- compatible = "allwinner,sun6i-a31-clock-reset";
+ compatible = "allwinner,sun50i-a64-r-ccu";
+ reg = <0x01f01400 0x100>;
+ clocks = <&osc24M>, <&osc32k>, <&iosc>;
+ clock-names = "hosc", "losc", "iosc";
+ #clock-cells = <1>;
#reset-cells = <1>;
};
@@ -589,9 +573,9 @@
compatible = "allwinner,sun5i-a13-ir";
- clocks = <&apb0_gates 1>, <&ir_clk>;
+ clocks = <&r_ccu 4>, <&r_ccu 11>;
clock-names = "apb", "ir";
- resets = <&apb0_reset 1>;
+ resets = <&r_ccu 0>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x01f02000 0x40>;
status = "disabled";
@@ -601,9 +585,8 @@
compatible = "allwinner,sun8i-h3-r-pinctrl";
reg = <0x01f02c00 0x400>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>;
+ clocks = <&r_ccu 3>, <&osc24M>, <&osc32k>;
clock-names = "apb", "hosc", "losc";
- resets = <&apb0_reset 0>;
gpio-controller;
#gpio-cells = <3>;
interrupt-controller;
--
2.12.2
_______________________________________________
linux-arm-kernel mailing list
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
_______________________________________________
linux-arm-kernel mailing list
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
i***@aosc.io
2017-07-20 05:15:15 UTC
Permalink
Post by i***@aosc.io
在 2017-07-20 06:59,Ondřej Jirman 写道:
Post by Ondřej Jirman
Hi,
Post by Icenowy Zheng
Now we have driver for the PRCM CCU, switch to use it instead of
old-style clock nodes for apb0-related clocks in sunxi-h3-h5.dtsi .
The mux 3 of R_CCU is still the internal oscillator, which is said to be
16MHz plus minus 30%, and get a measured value of 15MHz~16MHz on my two
H3 boards and one H5 board.
There's issue with the new r_ccu that breaks r_i2c. (no devices can be
found on the bus). Reverting this patch fixes the issue with the I2C
controller. (everything else being the same)
https://github.com/megous/linux/commits/oran
ge-pi-4.12
The last commit is the revert.
The issue manifests itself by non-working DVFS, because kernel lacks
access to SY8106A regulator, because r_i2c doesn't work with sunxi-ng
clock driver (sun8i-r).
Relevant difference in registers between working/non-working state is
0x01f02400 = 0x00000000
0x01f02404 = 0x00000000
-0x01f02408 = 0x00000091
+0x01f02408 = 0x00000095 DATA register inisde the I2C controller
0x01f0240c = 0x00000044
0x01f02410 = 0x000000f8
-0x01f02414 = 0x00000059
+0x01f02414 = 0x00000000 CLOCK setup register inside the I2C
controller
0x01f02418 = 0x00000000
0x01f0241c = 0x00000000
0x01f02420 = 0x0000003a
It looks like the new sunxi-ng clock driver causes the I2C driver to
not correctly configure the CLOCK register. I don't know why and I'm
not sure how to deal with this. Any ideas what can I do next?
thank you and regards,
o.
It seems to be a very very very weird problem -- the CPUS_CFG register
seems to be not accessible in non-secure mode on H3, and if the r_ccu
driver reads it a value of 0x0 is read out (which means that the parent
of ar100 is osc32k), but the real initial value of the register is
0x00010000 (which means the parent is osc24M).
So the bus clock of r_i2c is wrongly claimed as 32kHz, not 24MHz, then
the r_i2c fails to work.
The protection to AR100 registers can be removed by writing 1 to
0x01f015d0
(0x1d0 at PRCM memory region).

Interestingly this controlling register can be written in non-secure
world,
so it's still broken secure/non-secure division ;-)
Post by i***@aosc.io
This clock problem doesn't exist for A64.
Post by Ondřej Jirman
Post by Icenowy Zheng
---
- Temporarily dropped the CCU headers.
- Change osc32000 to iosc.
arch/arm/boot/dts/sunxi-h3-h5.dtsi | 45
++++++++++++--------------------------
1 file changed, 14 insertions(+), 31 deletions(-)
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 6640ebfa6419..1aeeacb3a884 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -68,31 +68,12 @@
clock-output-names = "osc32k";
};
- apb0: apb0_clk {
- compatible = "fixed-factor-clock";
+ iosc: internal-osc-clk {
#clock-cells = <0>;
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&osc24M>;
- clock-output-names = "apb0";
- };
-
- compatible = "allwinner,sun8i-h3-apb0-gates-clk",
- "allwinner,sun4i-a10-gates-clk";
- reg = <0x01f01428 0x4>;
- #clock-cells = <1>;
- clocks = <&apb0>;
- clock-indices = <0>, <1>;
- clock-output-names = "apb0_pio", "apb0_ir";
- };
-
- compatible = "allwinner,sun4i-a10-mod0-clk";
- reg = <0x01f01454 0x4>;
- #clock-cells = <0>;
- clocks = <&osc32k>, <&osc24M>;
- clock-output-names = "ir";
+ compatible = "fixed-clock";
+ clock-frequency = <16000000>;
+ clock-accuracy = <300000000>;
+ clock-output-names = "iosc";
};
};
@@ -576,9 +557,12 @@
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
};
- reg = <0x01f014b0 0x4>;
- compatible = "allwinner,sun6i-a31-clock-reset";
+ compatible = "allwinner,sun50i-a64-r-ccu";
+ reg = <0x01f01400 0x100>;
+ clocks = <&osc24M>, <&osc32k>, <&iosc>;
+ clock-names = "hosc", "losc", "iosc";
+ #clock-cells = <1>;
#reset-cells = <1>;
};
@@ -589,9 +573,9 @@
compatible = "allwinner,sun5i-a13-ir";
- clocks = <&apb0_gates 1>, <&ir_clk>;
+ clocks = <&r_ccu 4>, <&r_ccu 11>;
clock-names = "apb", "ir";
- resets = <&apb0_reset 1>;
+ resets = <&r_ccu 0>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x01f02000 0x40>;
status = "disabled";
@@ -601,9 +585,8 @@
compatible = "allwinner,sun8i-h3-r-pinctrl";
reg = <0x01f02c00 0x400>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>;
+ clocks = <&r_ccu 3>, <&osc24M>, <&osc32k>;
clock-names = "apb", "hosc", "losc";
- resets = <&apb0_reset 0>;
gpio-controller;
#gpio-cells = <3>;
interrupt-controller;
--
2.12.2
_______________________________________________
linux-arm-kernel mailing list
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
_______________________________________________
linux-arm-kernel mailing list
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
i***@aosc.io
2017-07-20 08:21:11 UTC
Permalink
在 2017-07-20 06:59,Ondřej Jirman 写道:
Post by Ondřej Jirman
Hi,
Post by Icenowy Zheng
Now we have driver for the PRCM CCU, switch to use it instead of
old-style clock nodes for apb0-related clocks in sunxi-h3-h5.dtsi .
The mux 3 of R_CCU is still the internal oscillator, which is said to be
16MHz plus minus 30%, and get a measured value of 15MHz~16MHz on my two
H3 boards and one H5 board.
There's issue with the new r_ccu that breaks r_i2c. (no devices can be
found on the bus). Reverting this patch fixes the issue with the I2C
controller. (everything else being the same)
Here's the code I'm using: https://github.com/megous/linux/commits/oran
ge-pi-4.12
The last commit is the revert.
The issue manifests itself by non-working DVFS, because kernel lacks
access to SY8106A regulator, because r_i2c doesn't work with sunxi-ng
clock driver (sun8i-r).
Relevant difference in registers between working/non-working state is
0x01f02400 = 0x00000000
0x01f02404 = 0x00000000
-0x01f02408 = 0x00000091
+0x01f02408 = 0x00000095 DATA register inisde the I2C controller
0x01f0240c = 0x00000044
0x01f02410 = 0x000000f8
-0x01f02414 = 0x00000059
+0x01f02414 = 0x00000000 CLOCK setup register inside the I2C controller
0x01f02418 = 0x00000000
0x01f0241c = 0x00000000
0x01f02420 = 0x0000003a
It looks like the new sunxi-ng clock driver causes the I2C driver to
not correctly configure the CLOCK register. I don't know why and I'm
not sure how to deal with this. Any ideas what can I do next?
Could you apply the patches at [1] and [2] to U-Boot and re-try with
r_ccu? They switched the CPUs clock of r_ccu to non-secure mode, which
makes it possible to be accessed from the kernel running in non-secure.

I think these patches can solve this problem.

[1] https://patchwork.ozlabs.org/patch/791414/
[2] https://patchwork.ozlabs.org/patch/791415/
Post by Ondřej Jirman
thank you and regards,
o.
Post by Icenowy Zheng
---
- Temporarily dropped the CCU headers.
- Change osc32000 to iosc.
arch/arm/boot/dts/sunxi-h3-h5.dtsi | 45
++++++++++++--------------------------
1 file changed, 14 insertions(+), 31 deletions(-)
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 6640ebfa6419..1aeeacb3a884 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -68,31 +68,12 @@
clock-output-names = "osc32k";
};
- apb0: apb0_clk {
- compatible = "fixed-factor-clock";
+ iosc: internal-osc-clk {
#clock-cells = <0>;
- clock-div = <1>;
- clock-mult = <1>;
- clocks = <&osc24M>;
- clock-output-names = "apb0";
- };
-
- compatible = "allwinner,sun8i-h3-apb0-gates-clk",
- "allwinner,sun4i-a10-gates-clk";
- reg = <0x01f01428 0x4>;
- #clock-cells = <1>;
- clocks = <&apb0>;
- clock-indices = <0>, <1>;
- clock-output-names = "apb0_pio", "apb0_ir";
- };
-
- compatible = "allwinner,sun4i-a10-mod0-clk";
- reg = <0x01f01454 0x4>;
- #clock-cells = <0>;
- clocks = <&osc32k>, <&osc24M>;
- clock-output-names = "ir";
+ compatible = "fixed-clock";
+ clock-frequency = <16000000>;
+ clock-accuracy = <300000000>;
+ clock-output-names = "iosc";
};
};
@@ -576,9 +557,12 @@
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
};
- reg = <0x01f014b0 0x4>;
- compatible = "allwinner,sun6i-a31-clock-reset";
+ compatible = "allwinner,sun50i-a64-r-ccu";
+ reg = <0x01f01400 0x100>;
+ clocks = <&osc24M>, <&osc32k>, <&iosc>;
+ clock-names = "hosc", "losc", "iosc";
+ #clock-cells = <1>;
#reset-cells = <1>;
};
@@ -589,9 +573,9 @@
compatible = "allwinner,sun5i-a13-ir";
- clocks = <&apb0_gates 1>, <&ir_clk>;
+ clocks = <&r_ccu 4>, <&r_ccu 11>;
clock-names = "apb", "ir";
- resets = <&apb0_reset 1>;
+ resets = <&r_ccu 0>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x01f02000 0x40>;
status = "disabled";
@@ -601,9 +585,8 @@
compatible = "allwinner,sun8i-h3-r-pinctrl";
reg = <0x01f02c00 0x400>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>;
+ clocks = <&r_ccu 3>, <&osc24M>, <&osc32k>;
clock-names = "apb", "hosc", "losc";
- resets = <&apb0_reset 0>;
gpio-controller;
#gpio-cells = <3>;
interrupt-controller;
--
2.12.2
_______________________________________________
linux-arm-kernel mailing list
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Ondřej Jirman
2017-07-20 12:12:09 UTC
Permalink
Hi Icenowy,
Post by i***@aosc.io
在 2017-07-20 06:59,Ondřej Jirman 写道:
Post by Ondřej Jirman
Hi,
Post by Icenowy Zheng
Now we have driver for the PRCM CCU, switch to use it instead of
old-style clock nodes for apb0-related clocks in sunxi-h3-h5.dtsi .
The mux 3 of R_CCU is still the internal oscillator, which is said to be
16MHz plus minus 30%, and get a measured value of 15MHz~16MHz on my two
H3 boards and one H5 board.
There's issue with the new r_ccu that breaks r_i2c. (no devices can be
found on the bus). Reverting this patch fixes the issue with the I2C
controller. (everything else being the same)
Here's the code I'm using: https://github.com/megous/linux/commits/oran
ge-pi-4.12
The last commit is the revert.
The issue manifests itself by non-working DVFS, because kernel lacks
access to SY8106A regulator, because r_i2c doesn't work with sunxi-ng
clock driver (sun8i-r).
Relevant difference in registers between working/non-working state is
0x01f02400 = 0x00000000
0x01f02404 = 0x00000000
-0x01f02408 = 0x00000091
+0x01f02408 = 0x00000095 DATA register inisde the I2C controller
0x01f0240c = 0x00000044
0x01f02410 = 0x000000f8
-0x01f02414 = 0x00000059
+0x01f02414 = 0x00000000 CLOCK setup register inside the I2C controller
0x01f02418 = 0x00000000
0x01f0241c = 0x00000000
0x01f02420 = 0x0000003a
It looks like the new sunxi-ng clock driver causes the I2C driver to
not correctly configure the CLOCK register. I don't know why and I'm
not sure how to deal with this. Any ideas what can I do next?
Could you apply the patches at [1] and [2] to U-Boot and re-try with
r_ccu? They switched the CPUs clock of r_ccu to non-secure mode, which
makes it possible to be accessed from the kernel running in non-secure.
I have verified that r_ccu works correctly with the u-boot patches on
H3 and H5.

Thank you very much for looking into the issue. :)

regards,
o.
Post by i***@aosc.io
I think these patches can solve this problem.
[1] https://patchwork.ozlabs.org/patch/791414/
[2] https://patchwork.ozlabs.org/patch/791415/
Icenowy Zheng
2017-04-04 09:50:57 UTC
Permalink
From: Icenowy Zheng <***@aosc.xyz>

SoCs after A31 has a clock controller module in the PRCM part.

Support the clock controller module on H3/5 and A64 now.

Signed-off-by: Icenowy Zheng <***@aosc.xyz>
---
Changes in v4:
- Add missing twd items in *_ccu_clks.
Changes in v3:
- Change osc32000 mux to iosc, as its frequency varies between SoCs. (And
none of them is really 32000Hz)
Changes in v2:
- Replace all sun6i to sun8i, as this driver currently doesn't really
support sun6i(A31).
- Add osc32000 mux for ar100 clk. (Note: the frequency is proven to be wrong
during the development of PATCH v3).
- Rename some clocks.
- Add gate of TWD (Trusted Watchdog). There's no reset for TWD.
- Removed reset of PIO, which doesn't exist really.

drivers/clk/sunxi-ng/Kconfig | 6 +
drivers/clk/sunxi-ng/Makefile | 1 +
drivers/clk/sunxi-ng/ccu-sun8i-r.c | 213 ++++++++++++++++++++++++++++++++
drivers/clk/sunxi-ng/ccu-sun8i-r.h | 27 ++++
include/dt-bindings/clock/sun8i-r-ccu.h | 59 +++++++++
include/dt-bindings/reset/sun8i-r-ccu.h | 53 ++++++++
6 files changed, 359 insertions(+)
create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-r.c
create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-r.h
create mode 100644 include/dt-bindings/clock/sun8i-r-ccu.h
create mode 100644 include/dt-bindings/reset/sun8i-r-ccu.h

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 8af8f4be8e3b..fbd3f8cd5c22 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -151,4 +151,10 @@ config SUN9I_A80_CCU
default MACH_SUN9I
depends on MACH_SUN9I || COMPILE_TEST

+config SUN8I_R_CCU
+ bool "Support for Allwinner SoCs' PRCM CCUs"
+ select SUNXI_CCU_DIV
+ select SUNXI_CCU_GATE
+ default MACH_SUN8I || (ARCH_SUNXI && ARM64)
+
endif
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 6feaac0c5600..0ec02fe14c50 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o
obj-$(CONFIG_SUN8I_A33_CCU) += ccu-sun8i-a33.o
obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o
obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o
+obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
new file mode 100644
index 000000000000..0d027d53dbdf
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2016 Icenowy Zheng <***@aosc.xyz>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_nm.h"
+
+#include "ccu-sun8i-r.h"
+
+static const char * const ar100_parents[] = { "osc32k", "osc24M",
+ "pll-periph0", "iosc" };
+
+static struct ccu_div ar100_clk = {
+ .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
+
+ .mux = {
+ .shift = 16,
+ .width = 2,
+
+ .variable_prediv = {
+ .index = 2,
+ .shift = 8,
+ .width = 5,
+ },
+ },
+
+ .common = {
+ .reg = 0x00,
+ .features = CCU_FEATURE_VARIABLE_PREDIV,
+ .hw.init = CLK_HW_INIT_PARENTS("ar100",
+ ar100_parents,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static CLK_FIXED_FACTOR(ahb0_clk, "ahb0", "ar100", 1, 1, 0);
+
+static struct ccu_div apb0_clk = {
+ .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
+
+ .common = {
+ .reg = 0x0c,
+ .hw.init = CLK_HW_INIT("apb0",
+ "ahb0",
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static SUNXI_CCU_GATE(apb0_pio_clk, "apb0-pio", "apb0",
+ 0x28, BIT(0), 0);
+static SUNXI_CCU_GATE(apb0_ir_clk, "apb0-ir", "apb0",
+ 0x28, BIT(1), 0);
+static SUNXI_CCU_GATE(apb0_timer_clk, "apb0-timer", "apb0",
+ 0x28, BIT(2), 0);
+static SUNXI_CCU_GATE(apb0_rsb_clk, "apb0-rsb", "apb0",
+ 0x28, BIT(3), 0);
+static SUNXI_CCU_GATE(apb0_uart_clk, "apb0-uart", "apb0",
+ 0x28, BIT(4), 0);
+static SUNXI_CCU_GATE(apb0_i2c_clk, "apb0-i2c", "apb0",
+ 0x28, BIT(6), 0);
+static SUNXI_CCU_GATE(apb0_twd_clk, "apb0-twd", "apb0",
+ 0x28, BIT(7), 0);
+
+static const char * const r_mod0_default_parents[] = { "osc32K", "osc24M" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir",
+ r_mod0_default_parents, 0x54,
+ 0, 4, /* M */
+ 16, 2, /* P */
+ 24, 2, /* mux */
+ BIT(31), /* gate */
+ 0);
+
+static struct ccu_common *sun8i_h3_r_ccu_clks[] = {
+ &ar100_clk.common,
+ &apb0_clk.common,
+ &apb0_pio_clk.common,
+ &apb0_ir_clk.common,
+ &apb0_timer_clk.common,
+ &apb0_uart_clk.common,
+ &apb0_i2c_clk.common,
+ &apb0_twd_clk.common,
+ &ir_clk.common,
+};
+
+static struct ccu_common *sun50i_a64_r_ccu_clks[] = {
+ &ar100_clk.common,
+ &apb0_clk.common,
+ &apb0_pio_clk.common,
+ &apb0_ir_clk.common,
+ &apb0_timer_clk.common,
+ &apb0_rsb_clk.common,
+ &apb0_uart_clk.common,
+ &apb0_i2c_clk.common,
+ &apb0_twd_clk.common,
+ &ir_clk.common,
+};
+
+static struct clk_hw_onecell_data sun8i_h3_r_hw_clks = {
+ .hws = {
+ [CLK_AR100] = &ar100_clk.common.hw,
+ [CLK_AHB0] = &ahb0_clk.hw,
+ [CLK_APB0] = &apb0_clk.common.hw,
+ [CLK_APB0_PIO] = &apb0_pio_clk.common.hw,
+ [CLK_APB0_IR] = &apb0_ir_clk.common.hw,
+ [CLK_APB0_TIMER] = &apb0_timer_clk.common.hw,
+ [CLK_APB0_UART] = &apb0_uart_clk.common.hw,
+ [CLK_APB0_I2C] = &apb0_i2c_clk.common.hw,
+ [CLK_APB0_TWD] = &apb0_twd_clk.common.hw,
+ [CLK_IR] = &ir_clk.common.hw,
+ },
+ .num = CLK_NUMBER,
+};
+
+static struct clk_hw_onecell_data sun50i_a64_r_hw_clks = {
+ .hws = {
+ [CLK_AR100] = &ar100_clk.common.hw,
+ [CLK_AHB0] = &ahb0_clk.hw,
+ [CLK_APB0] = &apb0_clk.common.hw,
+ [CLK_APB0_PIO] = &apb0_pio_clk.common.hw,
+ [CLK_APB0_IR] = &apb0_ir_clk.common.hw,
+ [CLK_APB0_TIMER] = &apb0_timer_clk.common.hw,
+ [CLK_APB0_RSB] = &apb0_rsb_clk.common.hw,
+ [CLK_APB0_UART] = &apb0_uart_clk.common.hw,
+ [CLK_APB0_I2C] = &apb0_i2c_clk.common.hw,
+ [CLK_APB0_TWD] = &apb0_twd_clk.common.hw,
+ [CLK_IR] = &ir_clk.common.hw,
+ },
+ .num = CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun8i_h3_r_ccu_resets[] = {
+ [RST_APB0_IR] = { 0xb0, BIT(1) },
+ [RST_APB0_TIMER] = { 0xb0, BIT(2) },
+ [RST_APB0_UART] = { 0xb0, BIT(4) },
+ [RST_APB0_I2C] = { 0xb0, BIT(6) },
+};
+
+static struct ccu_reset_map sun50i_a64_r_ccu_resets[] = {
+ [RST_APB0_IR] = { 0xb0, BIT(1) },
+ [RST_APB0_TIMER] = { 0xb0, BIT(2) },
+ [RST_APB0_RSB] = { 0xb0, BIT(3) },
+ [RST_APB0_UART] = { 0xb0, BIT(4) },
+ [RST_APB0_I2C] = { 0xb0, BIT(6) },
+};
+
+static const struct sunxi_ccu_desc sun8i_h3_r_ccu_desc = {
+ .ccu_clks = sun8i_h3_r_ccu_clks,
+ .num_ccu_clks = ARRAY_SIZE(sun8i_h3_r_ccu_clks),
+
+ .hw_clks = &sun8i_h3_r_hw_clks,
+
+ .resets = sun8i_h3_r_ccu_resets,
+ .num_resets = ARRAY_SIZE(sun8i_h3_r_ccu_resets),
+};
+
+static const struct sunxi_ccu_desc sun50i_a64_r_ccu_desc = {
+ .ccu_clks = sun50i_a64_r_ccu_clks,
+ .num_ccu_clks = ARRAY_SIZE(sun50i_a64_r_ccu_clks),
+
+ .hw_clks = &sun50i_a64_r_hw_clks,
+
+ .resets = sun50i_a64_r_ccu_resets,
+ .num_resets = ARRAY_SIZE(sun50i_a64_r_ccu_resets),
+};
+
+static void __init sunxi_r_ccu_init(struct device_node *node,
+ const struct sunxi_ccu_desc *desc)
+{
+ void __iomem *reg;
+
+ reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+ if (IS_ERR(reg)) {
+ pr_err("%s: Could not map the clock registers\n",
+ of_node_full_name(node));
+ return;
+ }
+
+ sunxi_ccu_probe(node, reg, desc);
+}
+
+static void __init sun8i_h3_r_ccu_setup(struct device_node *node)
+{
+ sunxi_r_ccu_init(node, &sun8i_h3_r_ccu_desc);
+}
+CLK_OF_DECLARE(sun8i_h3_r_ccu, "allwinner,sun8i-h3-r-ccu",
+ sun8i_h3_r_ccu_setup);
+
+static void __init sun50i_a64_r_ccu_setup(struct device_node *node)
+{
+ sunxi_r_ccu_init(node, &sun50i_a64_r_ccu_desc);
+}
+CLK_OF_DECLARE(sun50i_a64_r_ccu, "allwinner,sun50i-a64-r-ccu",
+ sun50i_a64_r_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.h b/drivers/clk/sunxi-ng/ccu-sun8i-r.h
new file mode 100644
index 000000000000..eaa431fd1d8f
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2016 Icenowy <***@aosc.xyz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CCU_SUN8I_R_H
+#define _CCU_SUN8I_R_H_
+
+#include <dt-bindings/clock/sun8i-r-ccu.h>
+#include <dt-bindings/reset/sun8i-r-ccu.h>
+
+/* AHB/APB bus clocks are not exported */
+#define CLK_AHB0 1
+#define CLK_APB0 2
+
+#define CLK_NUMBER (CLK_APB0_TWD + 1)
+
+#endif /* _CCU_SUN8I_R_H */
diff --git a/include/dt-bindings/clock/sun8i-r-ccu.h b/include/dt-bindings/clock/sun8i-r-ccu.h
new file mode 100644
index 000000000000..779d20aa0d05
--- /dev/null
+++ b/include/dt-bindings/clock/sun8i-r-ccu.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 Icenowy Zheng <***@aosc.xyz>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN8I_R_CCU_H_
+#define _DT_BINDINGS_CLK_SUN8I_R_CCU_H_
+
+#define CLK_AR100 0
+
+#define CLK_APB0_PIO 3
+#define CLK_APB0_IR 4
+#define CLK_APB0_TIMER 5
+#define CLK_APB0_RSB 6
+#define CLK_APB0_UART 7
+/* 8 is reserved for CLK_APB0_W1 on A31 */
+#define CLK_APB0_I2C 9
+#define CLK_APB0_TWD 10
+
+#define CLK_IR 11
+
+#endif /* _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ */
diff --git a/include/dt-bindings/reset/sun8i-r-ccu.h b/include/dt-bindings/reset/sun8i-r-ccu.h
new file mode 100644
index 000000000000..4ba64f3d6fc9
--- /dev/null
+++ b/include/dt-bindings/reset/sun8i-r-ccu.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 Icenowy Zheng <***@aosc.xyz>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _DT_BINDINGS_RST_SUN8I_R_CCU_H_
+#define _DT_BINDINGS_RST_SUN8I_R_CCU_H_
+
+#define RST_APB0_IR 0
+#define RST_APB0_TIMER 1
+#define RST_APB0_RSB 2
+#define RST_APB0_UART 3
+/* 4 is reserved for RST_APB0_W1 on A31 */
+#define RST_APB0_I2C 5
+
+#endif /* _DT_BINDINGS_RST_SUN8I_R_CCU_H_ */
--
2.12.2
Icenowy Zheng
2017-04-04 09:50:58 UTC
Permalink
From: Icenowy Zheng <***@aosc.xyz>

A64 SoC have a CCU (r_ccu) in PRCM block.

Add the device node for it.

The mux 3 of R_CCU is an internal oscillator, which is 16MHz according
to the user manual, and has only 30% accuracy based on our experience
on older SoCs. The real mesaured value of it on two Pine64 boards is
around 11MHz, which is around 70% of 16MHz.

Signed-off-by: Icenowy Zheng <***@aosc.xyz>
---
Changes in v4:
- Temporarily dropped the CCU headers.
Changes in v3:
- Change osc32000 to iosc, which is 16MHz plus minus 30%, according to the
RTC chapter of the user manual and our experiences on A33.
Changes in v2:
- Add osc32000.

arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 17 +++++++++++++++++
1 file changed, 17 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 1c64ea2d23f9..1d4e5bcced0c 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -98,6 +98,14 @@
clock-output-names = "osc32k";
};

+ iosc: internal-osc-clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <16000000>;
+ clock-accuracy = <300000000>;
+ clock-output-names = "iosc";
+ };
+
psci {
compatible = "arm,psci-0.2";
method = "smc";
@@ -392,5 +400,14 @@
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
};
+
+ r_ccu: ***@1f01400 {
+ compatible = "allwinner,sun50i-a64-r-ccu";
+ reg = <0x01f01400 0x100>;
+ clocks = <&osc24M>, <&osc32k>, <&iosc>;
+ clock-names = "hosc", "losc", "iosc";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
};
};
--
2.12.2
Maxime Ripard
2017-04-04 15:45:44 UTC
Permalink
Allwinner SoCs after sun6i-a31 nearly all have a R_CCU in PRCM part.
(V3s and R40 do not have it, as they have even no PRCM)
This patch adds support for the ones on H3/A64.
Some clock/reset values are reserved for easier extending the support to
A31/A23, but for this I think some changes to the PRCM MFD should be made,
see [1] (Although this is only a sketch).
The r_pio device node is also added for A64, as the driver is already
merged, and its depends (r_ccu) is now met.
Applied all, thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
Loading...