Devicetree
 help / color / mirror / Atom feed
* [v2, 04/10] powerpc/mpc85xx: move ptp timer out of fman in dts
From: Yangbo Lu @ 2018-06-07  3:22 UTC (permalink / raw)
  To: netdev, madalin.bucur, Richard Cochran, Rob Herring, Shawn Guo,
	David S . Miller
  Cc: devicetree, linuxppc-dev, linux-arm-kernel, linux-kernel,
	Yangbo Lu
In-Reply-To: <20180607032256.39802-1-yangbo.lu@nxp.com>

This patch is to move ptp timer node out of fman.
Because ptp timer will be probed by ptp_qoriq driver,
it should be an independent device in case of conflict
memory mapping.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- None.
---
 arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi   |   14 ++++++++------
 arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi   |   14 ++++++++------
 arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi  |   14 ++++++++------
 arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi  |   14 ++++++++------
 arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi |   14 ++++++++------
 5 files changed, 40 insertions(+), 30 deletions(-)

diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi
index abd01d4..6b124f7 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi
@@ -37,12 +37,13 @@ fman0: fman@400000 {
 	#size-cells = <1>;
 	cell-index = <0>;
 	compatible = "fsl,fman";
-	ranges = <0 0x400000 0x100000>;
-	reg = <0x400000 0x100000>;
+	ranges = <0 0x400000 0xfe000>;
+	reg = <0x400000 0xfe000>;
 	interrupts = <96 2 0 0>, <16 2 1 1>;
 	clocks = <&clockgen 3 0>;
 	clock-names = "fmanclk";
 	fsl,qman-channel-range = <0x40 0xc>;
+	ptimer-handle = <&ptp_timer0>;
 
 	muram@0 {
 		compatible = "fsl,fman-muram";
@@ -93,9 +94,10 @@ fman0: fman@400000 {
 		reg = <0x87000 0x1000>;
 		status = "disabled";
 	};
+};
 
-	ptp_timer0: ptp-timer@fe000 {
-		compatible = "fsl,fman-ptp-timer";
-		reg = <0xfe000 0x1000>;
-	};
+ptp_timer0: ptp-timer@4fe000 {
+	compatible = "fsl,fman-ptp-timer";
+	reg = <0x4fe000 0x1000>;
+	interrupts = <96 2 0 0>;
 };
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi
index debea75..b80aaf5 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi
@@ -37,12 +37,13 @@ fman1: fman@500000 {
 	#size-cells = <1>;
 	cell-index = <1>;
 	compatible = "fsl,fman";
-	ranges = <0 0x500000 0x100000>;
-	reg = <0x500000 0x100000>;
+	ranges = <0 0x500000 0xfe000>;
+	reg = <0x500000 0xfe000>;
 	interrupts = <97 2 0 0>, <16 2 1 0>;
 	clocks = <&clockgen 3 1>;
 	clock-names = "fmanclk";
 	fsl,qman-channel-range = <0x60 0xc>;
+	ptimer-handle = <&ptp_timer1>;
 
 	muram@0 {
 		compatible = "fsl,fman-muram";
@@ -93,9 +94,10 @@ fman1: fman@500000 {
 		reg = <0x87000 0x1000>;
 		status = "disabled";
 	};
+};
 
-	ptp_timer1: ptp-timer@fe000 {
-		compatible = "fsl,fman-ptp-timer";
-		reg = <0xfe000 0x1000>;
-	};
+ptp_timer1: ptp-timer@5fe000 {
+	compatible = "fsl,fman-ptp-timer";
+	reg = <0x5fe000 0x1000>;
+	interrupts = <97 2 0 0>;
 };
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi
index 3a20e0d..d3720fd 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi
@@ -37,12 +37,13 @@ fman0: fman@400000 {
 	#size-cells = <1>;
 	cell-index = <0>;
 	compatible = "fsl,fman";
-	ranges = <0 0x400000 0x100000>;
-	reg = <0x400000 0x100000>;
+	ranges = <0 0x400000 0xfe000>;
+	reg = <0x400000 0xfe000>;
 	interrupts = <96 2 0 0>, <16 2 1 1>;
 	clocks = <&clockgen 3 0>;
 	clock-names = "fmanclk";
 	fsl,qman-channel-range = <0x800 0x10>;
+	ptimer-handle = <&ptp_timer0>;
 
 	muram@0 {
 		compatible = "fsl,fman-muram";
@@ -98,9 +99,10 @@ fman0: fman@400000 {
 		compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
 		reg = <0xfd000 0x1000>;
 	};
+};
 
-	ptp_timer0: ptp-timer@fe000 {
-		compatible = "fsl,fman-ptp-timer";
-		reg = <0xfe000 0x1000>;
-	};
+ptp_timer0: ptp-timer@4fe000 {
+	compatible = "fsl,fman-ptp-timer";
+	reg = <0x4fe000 0x1000>;
+	interrupts = <96 2 0 0>;
 };
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi
index 82750ac..ae34c20 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi
@@ -37,12 +37,13 @@ fman1: fman@500000 {
 	#size-cells = <1>;
 	cell-index = <1>;
 	compatible = "fsl,fman";
-	ranges = <0 0x500000 0x100000>;
-	reg = <0x500000 0x100000>;
+	ranges = <0 0x500000 0xfe000>;
+	reg = <0x500000 0xfe000>;
 	interrupts = <97 2 0 0>, <16 2 1 0>;
 	clocks = <&clockgen 3 1>;
 	clock-names = "fmanclk";
 	fsl,qman-channel-range = <0x820 0x10>;
+	ptimer-handle = <&ptp_timer1>;
 
 	muram@0 {
 		compatible = "fsl,fman-muram";
@@ -98,9 +99,10 @@ fman1: fman@500000 {
 		compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
 		reg = <0xfd000 0x1000>;
 	};
+};
 
-	ptp_timer1: ptp-timer@fe000 {
-		compatible = "fsl,fman-ptp-timer";
-		reg = <0xfe000 0x1000>;
-	};
+ptp_timer1: ptp-timer@5fe000 {
+	compatible = "fsl,fman-ptp-timer";
+	reg = <0x5fe000 0x1000>;
+	interrupts = <97 2 0 0>;
 };
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi
index 7f60b60..02f2755 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi
@@ -37,12 +37,13 @@ fman0: fman@400000 {
 	#size-cells = <1>;
 	cell-index = <0>;
 	compatible = "fsl,fman";
-	ranges = <0 0x400000 0x100000>;
-	reg = <0x400000 0x100000>;
+	ranges = <0 0x400000 0xfe000>;
+	reg = <0x400000 0xfe000>;
 	interrupts = <96 2 0 0>, <16 2 1 1>;
 	clocks = <&clockgen 3 0>;
 	clock-names = "fmanclk";
 	fsl,qman-channel-range = <0x800 0x10>;
+	ptimer-handle = <&ptp_timer0>;
 
 	muram@0 {
 		compatible = "fsl,fman-muram";
@@ -86,9 +87,10 @@ fman0: fman@400000 {
 		compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio";
 		reg = <0xfd000 0x1000>;
 	};
+};
 
-	ptp_timer0: ptp-timer@fe000 {
-		compatible = "fsl,fman-ptp-timer";
-		reg = <0xfe000 0x1000>;
-	};
+ptp_timer0: ptp-timer@4fe000 {
+	compatible = "fsl,fman-ptp-timer";
+	reg = <0x4fe000 0x1000>;
+	interrupts = <96 2 0 0>;
 };
-- 
1.7.1

^ permalink raw reply related

* [v2, 03/10] dt-binding: ptp_qoriq: add DPAA FMan support
From: Yangbo Lu @ 2018-06-07  3:22 UTC (permalink / raw)
  To: netdev, madalin.bucur, Richard Cochran, Rob Herring, Shawn Guo,
	David S . Miller
  Cc: devicetree, linuxppc-dev, linux-arm-kernel, linux-kernel,
	Yangbo Lu
In-Reply-To: <20180607032256.39802-1-yangbo.lu@nxp.com>

This patch is to add bindings description for DPAA
FMan 1588 timer, and also remove its description in
fsl-fman dt-bindings document.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- None.
---
 Documentation/devicetree/bindings/net/fsl-fman.txt |   25 +-------------------
 .../devicetree/bindings/ptp/ptp-qoriq.txt          |   15 +++++++++--
 2 files changed, 13 insertions(+), 27 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/fsl-fman.txt b/Documentation/devicetree/bindings/net/fsl-fman.txt
index df873d1..74603dd 100644
--- a/Documentation/devicetree/bindings/net/fsl-fman.txt
+++ b/Documentation/devicetree/bindings/net/fsl-fman.txt
@@ -356,30 +356,7 @@ ethernet@e0000 {
 ============================================================================
 FMan IEEE 1588 Node
 
-DESCRIPTION
-
-The FMan interface to support IEEE 1588
-
-
-PROPERTIES
-
-- compatible
-		Usage: required
-		Value type: <stringlist>
-		Definition: A standard property.
-		Must include "fsl,fman-ptp-timer".
-
-- reg
-		Usage: required
-		Value type: <prop-encoded-array>
-		Definition: A standard property.
-
-EXAMPLE
-
-ptp-timer@fe000 {
-	compatible = "fsl,fman-ptp-timer";
-	reg = <0xfe000 0x1000>;
-};
+Refer to Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
 
 =============================================================================
 FMan MDIO Node
diff --git a/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt b/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
index 0f569d8..c5d0e79 100644
--- a/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
+++ b/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
@@ -2,7 +2,8 @@
 
 General Properties:
 
-  - compatible   Should be "fsl,etsec-ptp"
+  - compatible   Should be "fsl,etsec-ptp" for eTSEC
+                 Should be "fsl,fman-ptp-timer" for DPAA FMan
   - reg          Offset and length of the register set for the device
   - interrupts   There should be at least two interrupts. Some devices
                  have as many as four PTP related interrupts.
@@ -43,14 +44,22 @@ Clock Properties:
   value, which will be directly written in those bits, that is why,
   according to reference manual, the next clock sources can be used:
 
+  For eTSEC,
   <0> - external high precision timer reference clock (TSEC_TMR_CLK
         input is used for this purpose);
   <1> - eTSEC system clock;
   <2> - eTSEC1 transmit clock;
   <3> - RTC clock input.
 
-  When this attribute is not used, eTSEC system clock will serve as
-  IEEE 1588 timer reference clock.
+  For DPAA FMan,
+  <0> - external high precision timer reference clock (TMR_1588_CLK)
+  <1> - MAC system clock (1/2 FMan clock)
+  <2> - reserved
+  <3> - RTC clock oscillator
+
+  When this attribute is not used, the IEEE 1588 timer reference clock
+  will use the eTSEC system clock (for Gianfar) or the MAC system
+  clock (for DPAA).
 
 Example:
 
-- 
1.7.1

^ permalink raw reply related

* [v2, 02/10] ptp: support DPAA FMan 1588 timer in ptp_qoriq
From: Yangbo Lu @ 2018-06-07  3:22 UTC (permalink / raw)
  To: netdev, madalin.bucur, Richard Cochran, Rob Herring, Shawn Guo,
	David S . Miller
  Cc: devicetree, linuxppc-dev, linux-arm-kernel, linux-kernel,
	Yangbo Lu
In-Reply-To: <20180607032256.39802-1-yangbo.lu@nxp.com>

This patch is to support DPAA (Data Path Acceleration Architecture)
1588 timer by adding "fsl,fman-ptp-timer" compatible, sharing
interrupt with FMan, adding FSL_DPAA_ETH dependency, and fixing
up register offset.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- None.
---
 drivers/ptp/Kconfig           |    2 +-
 drivers/ptp/ptp_qoriq.c       |  104 ++++++++++++++++++++++++++---------------
 include/linux/fsl/ptp_qoriq.h |   38 ++++++++++++---
 3 files changed, 98 insertions(+), 46 deletions(-)

diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
index 474c988..d137c48 100644
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -43,7 +43,7 @@ config PTP_1588_CLOCK_DTE
 
 config PTP_1588_CLOCK_QORIQ
 	tristate "Freescale QorIQ 1588 timer as PTP clock"
-	depends on GIANFAR
+	depends on GIANFAR || FSL_DPAA_ETH
 	depends on PTP_1588_CLOCK
 	default y
 	help
diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 1468a16..c4e3545 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -39,11 +39,12 @@
 /* Caller must hold qoriq_ptp->lock. */
 static u64 tmr_cnt_read(struct qoriq_ptp *qoriq_ptp)
 {
+	struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
 	u64 ns;
 	u32 lo, hi;
 
-	lo = qoriq_read(&qoriq_ptp->regs->tmr_cnt_l);
-	hi = qoriq_read(&qoriq_ptp->regs->tmr_cnt_h);
+	lo = qoriq_read(&regs->ctrl_regs->tmr_cnt_l);
+	hi = qoriq_read(&regs->ctrl_regs->tmr_cnt_h);
 	ns = ((u64) hi) << 32;
 	ns |= lo;
 	return ns;
@@ -52,16 +53,18 @@ static u64 tmr_cnt_read(struct qoriq_ptp *qoriq_ptp)
 /* Caller must hold qoriq_ptp->lock. */
 static void tmr_cnt_write(struct qoriq_ptp *qoriq_ptp, u64 ns)
 {
+	struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
 	u32 hi = ns >> 32;
 	u32 lo = ns & 0xffffffff;
 
-	qoriq_write(&qoriq_ptp->regs->tmr_cnt_l, lo);
-	qoriq_write(&qoriq_ptp->regs->tmr_cnt_h, hi);
+	qoriq_write(&regs->ctrl_regs->tmr_cnt_l, lo);
+	qoriq_write(&regs->ctrl_regs->tmr_cnt_h, hi);
 }
 
 /* Caller must hold qoriq_ptp->lock. */
 static void set_alarm(struct qoriq_ptp *qoriq_ptp)
 {
+	struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
 	u64 ns;
 	u32 lo, hi;
 
@@ -70,16 +73,18 @@ static void set_alarm(struct qoriq_ptp *qoriq_ptp)
 	ns -= qoriq_ptp->tclk_period;
 	hi = ns >> 32;
 	lo = ns & 0xffffffff;
-	qoriq_write(&qoriq_ptp->regs->tmr_alarm1_l, lo);
-	qoriq_write(&qoriq_ptp->regs->tmr_alarm1_h, hi);
+	qoriq_write(&regs->alarm_regs->tmr_alarm1_l, lo);
+	qoriq_write(&regs->alarm_regs->tmr_alarm1_h, hi);
 }
 
 /* Caller must hold qoriq_ptp->lock. */
 static void set_fipers(struct qoriq_ptp *qoriq_ptp)
 {
+	struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+
 	set_alarm(qoriq_ptp);
-	qoriq_write(&qoriq_ptp->regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
-	qoriq_write(&qoriq_ptp->regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
+	qoriq_write(&regs->fiper_regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
+	qoriq_write(&regs->fiper_regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
 }
 
 /*
@@ -89,16 +94,17 @@ static void set_fipers(struct qoriq_ptp *qoriq_ptp)
 static irqreturn_t isr(int irq, void *priv)
 {
 	struct qoriq_ptp *qoriq_ptp = priv;
+	struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
 	struct ptp_clock_event event;
 	u64 ns;
 	u32 ack = 0, lo, hi, mask, val;
 
-	val = qoriq_read(&qoriq_ptp->regs->tmr_tevent);
+	val = qoriq_read(&regs->ctrl_regs->tmr_tevent);
 
 	if (val & ETS1) {
 		ack |= ETS1;
-		hi = qoriq_read(&qoriq_ptp->regs->tmr_etts1_h);
-		lo = qoriq_read(&qoriq_ptp->regs->tmr_etts1_l);
+		hi = qoriq_read(&regs->etts_regs->tmr_etts1_h);
+		lo = qoriq_read(&regs->etts_regs->tmr_etts1_l);
 		event.type = PTP_CLOCK_EXTTS;
 		event.index = 0;
 		event.timestamp = ((u64) hi) << 32;
@@ -108,8 +114,8 @@ static irqreturn_t isr(int irq, void *priv)
 
 	if (val & ETS2) {
 		ack |= ETS2;
-		hi = qoriq_read(&qoriq_ptp->regs->tmr_etts2_h);
-		lo = qoriq_read(&qoriq_ptp->regs->tmr_etts2_l);
+		hi = qoriq_read(&regs->etts_regs->tmr_etts2_h);
+		lo = qoriq_read(&regs->etts_regs->tmr_etts2_l);
 		event.type = PTP_CLOCK_EXTTS;
 		event.index = 1;
 		event.timestamp = ((u64) hi) << 32;
@@ -130,16 +136,16 @@ static irqreturn_t isr(int irq, void *priv)
 			hi = ns >> 32;
 			lo = ns & 0xffffffff;
 			spin_lock(&qoriq_ptp->lock);
-			qoriq_write(&qoriq_ptp->regs->tmr_alarm2_l, lo);
-			qoriq_write(&qoriq_ptp->regs->tmr_alarm2_h, hi);
+			qoriq_write(&regs->alarm_regs->tmr_alarm2_l, lo);
+			qoriq_write(&regs->alarm_regs->tmr_alarm2_h, hi);
 			spin_unlock(&qoriq_ptp->lock);
 			qoriq_ptp->alarm_value = ns;
 		} else {
-			qoriq_write(&qoriq_ptp->regs->tmr_tevent, ALM2);
+			qoriq_write(&regs->ctrl_regs->tmr_tevent, ALM2);
 			spin_lock(&qoriq_ptp->lock);
-			mask = qoriq_read(&qoriq_ptp->regs->tmr_temask);
+			mask = qoriq_read(&regs->ctrl_regs->tmr_temask);
 			mask &= ~ALM2EN;
-			qoriq_write(&qoriq_ptp->regs->tmr_temask, mask);
+			qoriq_write(&regs->ctrl_regs->tmr_temask, mask);
 			spin_unlock(&qoriq_ptp->lock);
 			qoriq_ptp->alarm_value = 0;
 			qoriq_ptp->alarm_interval = 0;
@@ -153,7 +159,7 @@ static irqreturn_t isr(int irq, void *priv)
 	}
 
 	if (ack) {
-		qoriq_write(&qoriq_ptp->regs->tmr_tevent, ack);
+		qoriq_write(&regs->ctrl_regs->tmr_tevent, ack);
 		return IRQ_HANDLED;
 	} else
 		return IRQ_NONE;
@@ -169,6 +175,7 @@ static int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
 	u32 tmr_add;
 	int neg_adj = 0;
 	struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
+	struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
 
 	if (scaled_ppm < 0) {
 		neg_adj = 1;
@@ -186,7 +193,7 @@ static int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
 
 	tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;
 
-	qoriq_write(&qoriq_ptp->regs->tmr_add, tmr_add);
+	qoriq_write(&regs->ctrl_regs->tmr_add, tmr_add);
 
 	return 0;
 }
@@ -250,6 +257,7 @@ static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
 			      struct ptp_clock_request *rq, int on)
 {
 	struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
+	struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
 	unsigned long flags;
 	u32 bit, mask;
 
@@ -266,23 +274,23 @@ static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
 			return -EINVAL;
 		}
 		spin_lock_irqsave(&qoriq_ptp->lock, flags);
-		mask = qoriq_read(&qoriq_ptp->regs->tmr_temask);
+		mask = qoriq_read(&regs->ctrl_regs->tmr_temask);
 		if (on)
 			mask |= bit;
 		else
 			mask &= ~bit;
-		qoriq_write(&qoriq_ptp->regs->tmr_temask, mask);
+		qoriq_write(&regs->ctrl_regs->tmr_temask, mask);
 		spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
 		return 0;
 
 	case PTP_CLK_REQ_PPS:
 		spin_lock_irqsave(&qoriq_ptp->lock, flags);
-		mask = qoriq_read(&qoriq_ptp->regs->tmr_temask);
+		mask = qoriq_read(&regs->ctrl_regs->tmr_temask);
 		if (on)
 			mask |= PP1EN;
 		else
 			mask &= ~PP1EN;
-		qoriq_write(&qoriq_ptp->regs->tmr_temask, mask);
+		qoriq_write(&regs->ctrl_regs->tmr_temask, mask);
 		spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
 		return 0;
 
@@ -313,10 +321,12 @@ static int qoriq_ptp_probe(struct platform_device *dev)
 {
 	struct device_node *node = dev->dev.of_node;
 	struct qoriq_ptp *qoriq_ptp;
+	struct qoriq_ptp_registers *regs;
 	struct timespec64 now;
 	int err = -ENOMEM;
 	u32 tmr_ctrl;
 	unsigned long flags;
+	void __iomem *base;
 
 	qoriq_ptp = kzalloc(sizeof(*qoriq_ptp), GFP_KERNEL);
 	if (!qoriq_ptp)
@@ -351,7 +361,7 @@ static int qoriq_ptp_probe(struct platform_device *dev)
 		pr_err("irq not in device tree\n");
 		goto no_node;
 	}
-	if (request_irq(qoriq_ptp->irq, isr, 0, DRIVER, qoriq_ptp)) {
+	if (request_irq(qoriq_ptp->irq, isr, IRQF_SHARED, DRIVER, qoriq_ptp)) {
 		pr_err("request_irq failed\n");
 		goto no_node;
 	}
@@ -368,12 +378,27 @@ static int qoriq_ptp_probe(struct platform_device *dev)
 
 	spin_lock_init(&qoriq_ptp->lock);
 
-	qoriq_ptp->regs = ioremap(qoriq_ptp->rsrc->start,
-				resource_size(qoriq_ptp->rsrc));
-	if (!qoriq_ptp->regs) {
+	base = ioremap(qoriq_ptp->rsrc->start,
+		       resource_size(qoriq_ptp->rsrc));
+	if (!base) {
 		pr_err("ioremap ptp registers failed\n");
 		goto no_ioremap;
 	}
+
+	qoriq_ptp->base = base;
+
+	if (of_device_is_compatible(node, "fsl,fman-ptp-timer")) {
+		qoriq_ptp->regs.ctrl_regs = base + FMAN_CTRL_REGS_OFFSET;
+		qoriq_ptp->regs.alarm_regs = base + FMAN_ALARM_REGS_OFFSET;
+		qoriq_ptp->regs.fiper_regs = base + FMAN_FIPER_REGS_OFFSET;
+		qoriq_ptp->regs.etts_regs = base + FMAN_ETTS_REGS_OFFSET;
+	} else {
+		qoriq_ptp->regs.ctrl_regs = base + CTRL_REGS_OFFSET;
+		qoriq_ptp->regs.alarm_regs = base + ALARM_REGS_OFFSET;
+		qoriq_ptp->regs.fiper_regs = base + FIPER_REGS_OFFSET;
+		qoriq_ptp->regs.etts_regs = base + ETTS_REGS_OFFSET;
+	}
+
 	getnstimeofday64(&now);
 	ptp_qoriq_settime(&qoriq_ptp->caps, &now);
 
@@ -383,13 +408,14 @@ static int qoriq_ptp_probe(struct platform_device *dev)
 
 	spin_lock_irqsave(&qoriq_ptp->lock, flags);
 
-	qoriq_write(&qoriq_ptp->regs->tmr_ctrl,   tmr_ctrl);
-	qoriq_write(&qoriq_ptp->regs->tmr_add,    qoriq_ptp->tmr_add);
-	qoriq_write(&qoriq_ptp->regs->tmr_prsc,   qoriq_ptp->tmr_prsc);
-	qoriq_write(&qoriq_ptp->regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
-	qoriq_write(&qoriq_ptp->regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
+	regs = &qoriq_ptp->regs;
+	qoriq_write(&regs->ctrl_regs->tmr_ctrl,   tmr_ctrl);
+	qoriq_write(&regs->ctrl_regs->tmr_add,    qoriq_ptp->tmr_add);
+	qoriq_write(&regs->ctrl_regs->tmr_prsc,   qoriq_ptp->tmr_prsc);
+	qoriq_write(&regs->fiper_regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
+	qoriq_write(&regs->fiper_regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
 	set_alarm(qoriq_ptp);
-	qoriq_write(&qoriq_ptp->regs->tmr_ctrl,   tmr_ctrl|FIPERST|RTPE|TE|FRD);
+	qoriq_write(&regs->ctrl_regs->tmr_ctrl,   tmr_ctrl|FIPERST|RTPE|TE|FRD);
 
 	spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
 
@@ -405,7 +431,7 @@ static int qoriq_ptp_probe(struct platform_device *dev)
 	return 0;
 
 no_clock:
-	iounmap(qoriq_ptp->regs);
+	iounmap(qoriq_ptp->base);
 no_ioremap:
 	release_resource(qoriq_ptp->rsrc);
 no_resource:
@@ -419,12 +445,13 @@ static int qoriq_ptp_probe(struct platform_device *dev)
 static int qoriq_ptp_remove(struct platform_device *dev)
 {
 	struct qoriq_ptp *qoriq_ptp = platform_get_drvdata(dev);
+	struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
 
-	qoriq_write(&qoriq_ptp->regs->tmr_temask, 0);
-	qoriq_write(&qoriq_ptp->regs->tmr_ctrl,   0);
+	qoriq_write(&regs->ctrl_regs->tmr_temask, 0);
+	qoriq_write(&regs->ctrl_regs->tmr_ctrl,   0);
 
 	ptp_clock_unregister(qoriq_ptp->clock);
-	iounmap(qoriq_ptp->regs);
+	iounmap(qoriq_ptp->base);
 	release_resource(qoriq_ptp->rsrc);
 	free_irq(qoriq_ptp->irq, qoriq_ptp);
 	kfree(qoriq_ptp);
@@ -434,6 +461,7 @@ static int qoriq_ptp_remove(struct platform_device *dev)
 
 static const struct of_device_id match_table[] = {
 	{ .compatible = "fsl,etsec-ptp" },
+	{ .compatible = "fsl,fman-ptp-timer" },
 	{},
 };
 MODULE_DEVICE_TABLE(of, match_table);
diff --git a/include/linux/fsl/ptp_qoriq.h b/include/linux/fsl/ptp_qoriq.h
index b462d9e..dc3dac4 100644
--- a/include/linux/fsl/ptp_qoriq.h
+++ b/include/linux/fsl/ptp_qoriq.h
@@ -11,9 +11,8 @@
 
 /*
  * qoriq ptp registers
- * Generated by regen.tcl on Thu May 13 01:38:57 PM CEST 2010
  */
-struct qoriq_ptp_registers {
+struct ctrl_regs {
 	u32 tmr_ctrl;     /* Timer control register */
 	u32 tmr_tevent;   /* Timestamp event register */
 	u32 tmr_temask;   /* Timer event mask register */
@@ -28,22 +27,47 @@ struct qoriq_ptp_registers {
 	u8  res1[4];
 	u32 tmroff_h;     /* Timer offset high */
 	u32 tmroff_l;     /* Timer offset low */
-	u8  res2[8];
+};
+
+struct alarm_regs {
 	u32 tmr_alarm1_h; /* Timer alarm 1 high register */
 	u32 tmr_alarm1_l; /* Timer alarm 1 high register */
 	u32 tmr_alarm2_h; /* Timer alarm 2 high register */
 	u32 tmr_alarm2_l; /* Timer alarm 2 high register */
-	u8  res3[48];
+};
+
+struct fiper_regs {
 	u32 tmr_fiper1;   /* Timer fixed period interval */
 	u32 tmr_fiper2;   /* Timer fixed period interval */
 	u32 tmr_fiper3;   /* Timer fixed period interval */
-	u8  res4[20];
+};
+
+struct etts_regs {
 	u32 tmr_etts1_h;  /* Timestamp of general purpose external trigger */
 	u32 tmr_etts1_l;  /* Timestamp of general purpose external trigger */
 	u32 tmr_etts2_h;  /* Timestamp of general purpose external trigger */
 	u32 tmr_etts2_l;  /* Timestamp of general purpose external trigger */
 };
 
+struct qoriq_ptp_registers {
+	struct ctrl_regs __iomem *ctrl_regs;
+	struct alarm_regs __iomem *alarm_regs;
+	struct fiper_regs __iomem *fiper_regs;
+	struct etts_regs __iomem *etts_regs;
+};
+
+/* Offset definitions for the four register groups */
+#define CTRL_REGS_OFFSET	0x0
+#define ALARM_REGS_OFFSET	0x40
+#define FIPER_REGS_OFFSET	0x80
+#define ETTS_REGS_OFFSET	0xa0
+
+#define FMAN_CTRL_REGS_OFFSET	0x80
+#define FMAN_ALARM_REGS_OFFSET	0xb8
+#define FMAN_FIPER_REGS_OFFSET	0xd0
+#define FMAN_ETTS_REGS_OFFSET	0xe0
+
+
 /* Bit definitions for the TMR_CTRL register */
 #define ALM1P                 (1<<31) /* Alarm1 output polarity */
 #define ALM2P                 (1<<30) /* Alarm2 output polarity */
@@ -105,10 +129,10 @@ struct qoriq_ptp_registers {
 #define DRIVER		"ptp_qoriq"
 #define DEFAULT_CKSEL	1
 #define N_EXT_TS	2
-#define REG_SIZE	sizeof(struct qoriq_ptp_registers)
 
 struct qoriq_ptp {
-	struct qoriq_ptp_registers __iomem *regs;
+	void __iomem *base;
+	struct qoriq_ptp_registers regs;
 	spinlock_t lock; /* protects regs */
 	struct ptp_clock *clock;
 	struct ptp_clock_info caps;
-- 
1.7.1

^ permalink raw reply related

* [v2, 01/10] fsl/fman: share the event interrupt
From: Yangbo Lu @ 2018-06-07  3:22 UTC (permalink / raw)
  To: netdev, madalin.bucur, Richard Cochran, Rob Herring, Shawn Guo,
	David S . Miller
  Cc: devicetree, linuxppc-dev, linux-arm-kernel, linux-kernel,
	Yangbo Lu
In-Reply-To: <20180607032256.39802-1-yangbo.lu@nxp.com>

This patch is to share fman event interrupt because
the 1588 timer driver will also use this interrupt.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- None.
---
 drivers/net/ethernet/freescale/fman/fman.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman.c b/drivers/net/ethernet/freescale/fman/fman.c
index 9530405..c415ac6 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -2801,7 +2801,8 @@ static irqreturn_t fman_irq(int irq, void *handle)
 	of_node_put(muram_node);
 	of_node_put(fm_node);
 
-	err = devm_request_irq(&of_dev->dev, irq, fman_irq, 0, "fman", fman);
+	err = devm_request_irq(&of_dev->dev, irq, fman_irq, IRQF_SHARED,
+			       "fman", fman);
 	if (err < 0) {
 		dev_err(&of_dev->dev, "%s: irq %d allocation failed (error = %d)\n",
 			__func__, irq, err);
-- 
1.7.1

^ permalink raw reply related

* [v2, 00/10] Support DPAA PTP clock and timestamping
From: Yangbo Lu @ 2018-06-07  3:22 UTC (permalink / raw)
  To: netdev, madalin.bucur, Richard Cochran, Rob Herring, Shawn Guo,
	David S . Miller
  Cc: devicetree, linuxppc-dev, linux-arm-kernel, linux-kernel,
	Yangbo Lu

This patchset is to support DPAA FMAN PTP clock and HW timestamping.
- The patch #1 to patch #5 are to support DPAA FMAN 1588 timer in
  ptp_qoriq driver.
- The patch #6 to patch #10 are to add HW timestamping support in
  DPAA ethernet driver.

Yangbo Lu (10):
  fsl/fman: share the event interrupt
  ptp: support DPAA FMan 1588 timer in ptp_qoriq
  dt-binding: ptp_qoriq: add DPAA FMan support
  powerpc/mpc85xx: move ptp timer out of fman in dts
  arm64: dts: fsl: move ptp timer out of fman
  fsl/fman: add set_tstamp interface
  fsl/fman_port: support getting timestamp field
  fsl/fman: define frame description command UPD
  dpaa_eth: add support for hardware timestamping
  dpaa_eth: add the get_ts_info interface for ethtool

 Documentation/devicetree/bindings/net/fsl-fman.txt |   25 +-----
 .../devicetree/bindings/ptp/ptp-qoriq.txt          |   15 +++-
 arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi   |   14 ++-
 arch/powerpc/boot/dts/fsl/qoriq-fman-0.dtsi        |   14 ++-
 arch/powerpc/boot/dts/fsl/qoriq-fman-1.dtsi        |   14 ++-
 arch/powerpc/boot/dts/fsl/qoriq-fman3-0.dtsi       |   14 ++-
 arch/powerpc/boot/dts/fsl/qoriq-fman3-1.dtsi       |   14 ++-
 arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi      |   14 ++-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c     |  101 ++++++++++++++++++-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h     |    3 +
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c |   39 ++++++++
 drivers/net/ethernet/freescale/fman/fman.c         |    3 +-
 drivers/net/ethernet/freescale/fman/fman.h         |    1 +
 drivers/net/ethernet/freescale/fman/fman_dtsec.c   |   27 +++++
 drivers/net/ethernet/freescale/fman/fman_dtsec.h   |    1 +
 drivers/net/ethernet/freescale/fman/fman_memac.c   |    5 +
 drivers/net/ethernet/freescale/fman/fman_memac.h   |    1 +
 drivers/net/ethernet/freescale/fman/fman_port.c    |   12 +++
 drivers/net/ethernet/freescale/fman/fman_port.h    |    3 +
 drivers/net/ethernet/freescale/fman/fman_tgec.c    |   21 ++++
 drivers/net/ethernet/freescale/fman/fman_tgec.h    |    1 +
 drivers/net/ethernet/freescale/fman/mac.c          |    3 +
 drivers/net/ethernet/freescale/fman/mac.h          |    1 +
 drivers/ptp/Kconfig                                |    2 +-
 drivers/ptp/ptp_qoriq.c                            |  104 ++++++++++++-------
 include/linux/fsl/ptp_qoriq.h                      |   38 ++++++--
 26 files changed, 375 insertions(+), 115 deletions(-)

^ permalink raw reply

* [PATCH v1 4/4] clk: rockchip: add clock controller for px30
From: Elaine Zhang @ 2018-06-07  3:06 UTC (permalink / raw)
  To: heiko
  Cc: sboyd, robh+dt, mark.rutland, mturquette, linux-clk, devicetree,
	linux-arm-kernel, linux-rockchip, linux-kernel, cl, xxx, xf,
	huangtao, Elaine Zhang
In-Reply-To: <1528340786-462-1-git-send-email-zhangqing@rock-chips.com>

Add the clock tree definition for the new px30 SoC.

Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
---
 drivers/clk/rockchip/Makefile   |    1 +
 drivers/clk/rockchip/clk-px30.c | 1080 +++++++++++++++++++++++++++++++++++++++
 drivers/clk/rockchip/clk.h      |   41 +-
 3 files changed, 1121 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/rockchip/clk-px30.c

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 023f83ad3429..82ab6f515179 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -14,6 +14,7 @@ obj-y	+= clk-muxgrf.o
 obj-y	+= clk-ddr.o
 obj-$(CONFIG_RESET_CONTROLLER)	+= softrst.o
 
+obj-y   += clk-px30.o
 obj-y	+= clk-rv1108.o
 obj-y	+= clk-rk3036.o
 obj-y	+= clk-rk3128.o
diff --git a/drivers/clk/rockchip/clk-px30.c b/drivers/clk/rockchip/clk-px30.c
new file mode 100644
index 000000000000..07105fe1ff6c
--- /dev/null
+++ b/drivers/clk/rockchip/clk-px30.c
@@ -0,0 +1,1080 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author: Elaine <zhangqing@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.h>
+#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
+#include <dt-bindings/clock/px30-cru.h>
+#include "clk.h"
+
+#define PX30_GRF_SOC_STATUS0		0x480
+
+enum px30_plls {
+	apll, dpll, cpll, npll, apll_b_h, apll_b_l,
+};
+
+enum px30_pmu_plls {
+	gpll,
+};
+
+static struct rockchip_pll_rate_table px30_pll_rates[] = {
+	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
+	RK3036_PLL_RATE(984000000, 1, 82, 2, 1, 1, 0),
+	RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0),
+	RK3036_PLL_RATE(936000000, 1, 78, 2, 1, 1, 0),
+	RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
+	RK3036_PLL_RATE(900000000, 4, 300, 2, 1, 1, 0),
+	RK3036_PLL_RATE(888000000, 1, 74, 2, 1, 1, 0),
+	RK3036_PLL_RATE(864000000, 1, 72, 2, 1, 1, 0),
+	RK3036_PLL_RATE(840000000, 1, 70, 2, 1, 1, 0),
+	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+	RK3036_PLL_RATE(800000000, 6, 400, 2, 1, 1, 0),
+	RK3036_PLL_RATE(700000000, 6, 350, 2, 1, 1, 0),
+	RK3036_PLL_RATE(696000000, 1, 58, 2, 1, 1, 0),
+	RK3036_PLL_RATE(624000000, 1, 52, 2, 1, 1, 0),
+	RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0),
+	RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0),
+	RK3036_PLL_RATE(504000000, 1, 63, 3, 1, 1, 0),
+	RK3036_PLL_RATE(500000000, 6, 250, 2, 1, 1, 0),
+	RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
+	RK3036_PLL_RATE(312000000, 1, 52, 2, 2, 1, 0),
+	RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
+	RK3036_PLL_RATE(96000000, 1, 64, 4, 4, 1, 0),
+	{ /* sentinel */ },
+};
+
+#define PX30_DIV_ACLKM_MASK		0x7
+#define PX30_DIV_ACLKM_SHIFT		12
+#define PX30_DIV_PCLK_DBG_MASK	0xf
+#define PX30_DIV_PCLK_DBG_SHIFT	8
+
+#define PX30_CLKSEL0(_aclk_core, _pclk_dbg)				\
+{									\
+	.reg = PX30_CLKSEL_CON(0),					\
+	.val = HIWORD_UPDATE(_aclk_core, PX30_DIV_ACLKM_MASK,		\
+			     PX30_DIV_ACLKM_SHIFT) |			\
+	       HIWORD_UPDATE(_pclk_dbg, PX30_DIV_PCLK_DBG_MASK,	\
+			     PX30_DIV_PCLK_DBG_SHIFT),		\
+}
+
+#define PX30_CPUCLK_RATE(_prate, _aclk_core, _pclk_dbg)		\
+{									\
+	.prate = _prate,						\
+	.divs = {							\
+		PX30_CLKSEL0(_aclk_core, _pclk_dbg),			\
+	},								\
+}
+
+static struct rockchip_cpuclk_rate_table px30_cpuclk_rates[] __initdata = {
+	PX30_CPUCLK_RATE(1608000000, 1, 7),
+	PX30_CPUCLK_RATE(1584000000, 1, 7),
+	PX30_CPUCLK_RATE(1560000000, 1, 7),
+	PX30_CPUCLK_RATE(1536000000, 1, 7),
+	PX30_CPUCLK_RATE(1512000000, 1, 7),
+	PX30_CPUCLK_RATE(1488000000, 1, 5),
+	PX30_CPUCLK_RATE(1464000000, 1, 5),
+	PX30_CPUCLK_RATE(1440000000, 1, 5),
+	PX30_CPUCLK_RATE(1416000000, 1, 5),
+	PX30_CPUCLK_RATE(1392000000, 1, 5),
+	PX30_CPUCLK_RATE(1368000000, 1, 5),
+	PX30_CPUCLK_RATE(1344000000, 1, 5),
+	PX30_CPUCLK_RATE(1320000000, 1, 5),
+	PX30_CPUCLK_RATE(1296000000, 1, 5),
+	PX30_CPUCLK_RATE(1272000000, 1, 5),
+	PX30_CPUCLK_RATE(1248000000, 1, 5),
+	PX30_CPUCLK_RATE(1224000000, 1, 5),
+	PX30_CPUCLK_RATE(1200000000, 1, 5),
+	PX30_CPUCLK_RATE(1104000000, 1, 5),
+	PX30_CPUCLK_RATE(1008000000, 1, 5),
+	PX30_CPUCLK_RATE(912000000, 1, 5),
+	PX30_CPUCLK_RATE(816000000, 1, 3),
+	PX30_CPUCLK_RATE(696000000, 1, 3),
+	PX30_CPUCLK_RATE(600000000, 1, 3),
+	PX30_CPUCLK_RATE(408000000, 1, 1),
+	PX30_CPUCLK_RATE(312000000, 1, 1),
+	PX30_CPUCLK_RATE(216000000,  1, 1),
+	PX30_CPUCLK_RATE(96000000, 1, 1),
+};
+
+static const struct rockchip_cpuclk_reg_data px30_cpuclk_data = {
+	.core_reg = PX30_CLKSEL_CON(0),
+	.div_core_shift = 0,
+	.div_core_mask = 0xf,
+	.mux_core_alt = 1,
+	.mux_core_main = 0,
+	.mux_core_shift = 7,
+	.mux_core_mask = 0x1,
+};
+
+PNAME(mux_pll_p)		= { "xin24m"};
+PNAME(mux_usb480m_p)		= { "xin24m", "usb480m_phy", "clk_rtc32k_pmu" };
+PNAME(mux_armclk_p)		= { "apll_core", "gpll_core" };
+PNAME(mux_ddrphy_p)		= { "dpll_ddr", "gpll_ddr" };
+PNAME(mux_ddrstdby_p)		= { "clk_ddrphy1x", "clk_stdby_2wrap" };
+PNAME(mux_4plls_p)		= { "gpll", "dummy_cpll", "usb480m", "npll" };
+PNAME(mux_cpll_npll_p)		= { "cpll", "npll" };
+PNAME(mux_npll_cpll_p)		= { "npll", "cpll" };
+PNAME(mux_gpll_cpll_p)		= { "gpll", "dummy_cpll" };
+PNAME(mux_gpll_npll_p)		= { "gpll", "npll" };
+PNAME(mux_gpll_xin24m_p)		= { "gpll", "xin24m"};
+PNAME(mux_gpll_cpll_npll_p)		= { "gpll", "dummy_cpll", "npll" };
+PNAME(mux_gpll_cpll_npll_xin24m_p)	= { "gpll", "dummy_cpll", "npll", "xin24m" };
+PNAME(mux_gpll_xin24m_npll_p)		= { "gpll", "xin24m", "npll"};
+PNAME(mux_pdm_p)		= { "clk_pdm_src", "clk_pdm_frac" };
+PNAME(mux_i2s0_tx_p)		= { "clk_i2s0_tx_src", "clk_i2s0_tx_frac", "mclk_i2s0_tx_in", "xin12m"};
+PNAME(mux_i2s0_rx_p)		= { "clk_i2s0_rx_src", "clk_i2s0_rx_frac", "mclk_i2s0_rx_in", "xin12m"};
+PNAME(mux_i2s1_p)		= { "clk_i2s1_src", "clk_i2s1_frac", "i2s1_clkin", "xin12m"};
+PNAME(mux_i2s2_p)		= { "clk_i2s2_src", "clk_i2s2_frac", "i2s2_clkin", "xin12m"};
+PNAME(mux_i2s0_tx_out_p)	= { "clk_i2s0_tx", "xin12m", "clk_i2s0_rx"};
+PNAME(mux_i2s0_rx_out_p)	= { "clk_i2s0_rx", "xin12m", "clk_i2s0_tx"};
+PNAME(mux_i2s1_out_p)		= { "clk_i2s1", "xin12m"};
+PNAME(mux_i2s2_out_p)		= { "clk_i2s2", "xin12m"};
+PNAME(mux_i2s0_tx_rx_p)		= { "clk_i2s0_tx_mux", "clk_i2s0_rx_mux"};
+PNAME(mux_i2s0_rx_tx_p)		= { "clk_i2s0_rx_mux", "clk_i2s0_tx_mux"};
+PNAME(mux_uart_src_p)		= { "gpll", "xin24m", "usb480m", "npll" };
+PNAME(mux_uart1_p)		= { "clk_uart1_src", "clk_uart1_np5", "clk_uart1_frac" };
+PNAME(mux_uart2_p)		= { "clk_uart2_src", "clk_uart2_np5", "clk_uart2_frac" };
+PNAME(mux_uart3_p)		= { "clk_uart3_src", "clk_uart3_np5", "clk_uart3_frac" };
+PNAME(mux_uart4_p)		= { "clk_uart4_src", "clk_uart4_np5", "clk_uart4_frac" };
+PNAME(mux_uart5_p)		= { "clk_uart5_src", "clk_uart5_np5", "clk_uart5_frac" };
+PNAME(mux_cif_out_p)		= { "xin24m", "dummy_cpll", "npll", "usb480m" };
+PNAME(mux_dclk_vopb_p)		= { "dclk_vopb_src", "dclk_vopb_frac", "xin24m" };
+PNAME(mux_dclk_vopl_p)		= { "dclk_vopl_src", "dclk_vopl_frac", "xin24m" };
+PNAME(mux_gmac_p)		= { "clk_gmac_src", "gmac_clkin" };
+PNAME(mux_gmac_rmii_sel_p)	= { "clk_gmac_rx_tx_div20", "clk_gmac_rx_tx_div2" };
+PNAME(mux_rtc32k_pmu_p)		= { "xin32k", "pmu_pvtm_32k", "clk_rtc32k_frac", };
+PNAME(mux_wifi_pmu_p)		= { "xin24m", "clk_wifi_pmu_src" };
+PNAME(mux_uart0_pmu_p)		= { "clk_uart0_pmu_src", "clk_uart0_np5", "clk_uart0_frac" };
+PNAME(mux_usbphy_ref_p)		= { "xin24m", "clk_ref24m_pmu" };
+PNAME(mux_mipidsiphy_ref_p)	= { "xin24m", "clk_ref24m_pmu" };
+PNAME(mux_gpu_p)	= { "clk_gpu_div", "clk_gpu_np5" };
+
+static struct rockchip_pll_clock px30_pll_clks[] __initdata = {
+	[apll] = PLL(pll_rk3328, PLL_APLL, "apll", mux_pll_p,
+		     0, PX30_PLL_CON(0),
+		     PX30_MODE_CON, 0, 0, 0, px30_pll_rates),
+	[dpll] = PLL(pll_rk3328, PLL_DPLL, "dpll", mux_pll_p,
+		     0, PX30_PLL_CON(8),
+		     PX30_MODE_CON, 4, 1, 0, NULL),
+	[cpll] = PLL(pll_rk3328, PLL_CPLL, "cpll", mux_pll_p,
+		     0, PX30_PLL_CON(16),
+		     PX30_MODE_CON, 2, 2, 0, px30_pll_rates),
+	[npll] = PLL(pll_rk3328, PLL_NPLL, "npll", mux_pll_p,
+		     0, PX30_PLL_CON(24),
+		     PX30_MODE_CON, 6, 4, 0, px30_pll_rates),
+};
+
+static struct rockchip_pll_clock px30_pmu_pll_clks[] __initdata = {
+	[gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll",  mux_pll_p, 0, PX30_PMU_PLL_CON(0),
+		     PX30_PMU_MODE, 0, 3, 0, px30_pll_rates),
+};
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_clk_branch px30_pdm_fracmux __initdata =
+	MUX(0, "clk_pdm_mux", mux_pdm_p, CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(26), 15, 1, MFLAGS);
+
+static struct rockchip_clk_branch px30_i2s0_tx_fracmux __initdata =
+	MUX(0, "clk_i2s0_tx_mux", mux_i2s0_tx_p, CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(28), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch px30_i2s0_rx_fracmux __initdata =
+	MUX(0, "clk_i2s0_rx_mux", mux_i2s0_rx_p, CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(58), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch px30_i2s1_fracmux __initdata =
+	MUX(0, "clk_i2s1_mux", mux_i2s1_p, CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(30), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch px30_i2s2_fracmux __initdata =
+	MUX(0, "clk_i2s2_mux", mux_i2s2_p, CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(32), 10, 2, MFLAGS);
+
+static struct rockchip_clk_branch px30_uart1_fracmux __initdata =
+	MUX(0, "clk_uart1_mux", mux_uart1_p, CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(35), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch px30_uart2_fracmux __initdata =
+	MUX(0, "clk_uart2_mux", mux_uart2_p, CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(38), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch px30_uart3_fracmux __initdata =
+	MUX(0, "clk_uart3_mux", mux_uart3_p, CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(41), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch px30_uart4_fracmux __initdata =
+	MUX(0, "clk_uart4_mux", mux_uart4_p, CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(44), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch px30_uart5_fracmux __initdata =
+	MUX(0, "clk_uart5_mux", mux_uart5_p, CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(47), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch px30_dclk_vopb_fracmux __initdata =
+	MUX(0, "dclk_vopb_mux", mux_dclk_vopb_p, CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(5), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch px30_dclk_vopl_fracmux __initdata =
+	MUX(0, "dclk_vopl_mux", mux_dclk_vopl_p, CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(8), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch px30_rtc32k_pmu_fracmux __initdata =
+	MUX(SCLK_RTC32K_PMU, "clk_rtc32k_pmu", mux_rtc32k_pmu_p, CLK_SET_RATE_PARENT,
+			PX30_PMU_CLKSEL_CON(0), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch px30_uart0_pmu_fracmux __initdata =
+	MUX(0, "clk_uart0_pmu_mux", mux_uart0_pmu_p, CLK_SET_RATE_PARENT,
+			PX30_PMU_CLKSEL_CON(4), 14, 2, MFLAGS);
+
+static struct rockchip_clk_branch px30_clk_branches[] __initdata = {
+	/*
+	 * Clock-Architecture Diagram 1
+	 */
+
+	MUX(USB480M, "usb480m", mux_usb480m_p, CLK_SET_RATE_PARENT,
+			PX30_MODE_CON, 8, 2, MFLAGS),
+	FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
+
+	/*
+	 * Clock-Architecture Diagram 3
+	 */
+
+	/* PD_CORE */
+	GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(0), 0, GFLAGS),
+	GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(0), 0, GFLAGS),
+	COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED,
+			PX30_CLKSEL_CON(0), 8, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			PX30_CLKGATE_CON(0), 2, GFLAGS),
+	COMPOSITE_NOMUX(0, "aclk_core", "armclk", CLK_IGNORE_UNUSED,
+			PX30_CLKSEL_CON(0), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			PX30_CLKGATE_CON(0), 1, GFLAGS),
+	GATE(0, "aclk_core_niu", "aclk_core", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(0), 4, GFLAGS),
+	GATE(0, "aclk_core_prf", "aclk_core", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(17), 5, GFLAGS),
+	GATE(0, "pclk_dbg_niu", "pclk_dbg", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(0), 5, GFLAGS),
+	GATE(0, "pclk_core_dbg", "pclk_dbg", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(0), 6, GFLAGS),
+	GATE(0, "pclk_core_grf", "pclk_dbg", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(17), 6, GFLAGS),
+
+	GATE(0, "clk_jtag", "jtag_clkin", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(0), 3, GFLAGS),
+	GATE(SCLK_PVTM, "clk_pvtm", "xin24m", 0,
+			PX30_CLKGATE_CON(17), 4, GFLAGS),
+
+	/* PD_GPU */
+	COMPOSITE_NODIV(0, "clk_gpu_src", mux_4plls_p, 0,
+			PX30_CLKSEL_CON(1), 6, 2, MFLAGS,
+			PX30_CLKGATE_CON(0), 8, GFLAGS),
+	COMPOSITE_NOMUX(0, "clk_gpu_div", "clk_gpu_src", 0,
+			PX30_CLKSEL_CON(1), 0, 4, DFLAGS,
+			PX30_CLKGATE_CON(0), 12, GFLAGS),
+	COMPOSITE_NOMUX_HALFDIV(0, "clk_gpu_np5", "clk_gpu_src", 0,
+			PX30_CLKSEL_CON(1), 8, 4, DFLAGS,
+			PX30_CLKGATE_CON(0), 9, GFLAGS),
+	COMPOSITE_NODIV(SCLK_GPU, "clk_gpu", mux_gpu_p, CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(1), 15, 1, MFLAGS,
+			PX30_CLKGATE_CON(0), 10, GFLAGS),
+	COMPOSITE_NOMUX(0, "aclk_gpu", "clk_gpu", CLK_IGNORE_UNUSED,
+			PX30_CLKSEL_CON(1), 13, 2, DFLAGS,
+			PX30_CLKGATE_CON(17), 10, GFLAGS),
+	GATE(0, "aclk_gpu_niu", "aclk_gpu", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(0), 11, GFLAGS),
+	GATE(0, "aclk_gpu_prf", "aclk_gpu", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(17), 8, GFLAGS),
+	GATE(0, "pclk_gpu_grf", "aclk_gpu", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(17), 9, GFLAGS),
+
+	/*
+	 * Clock-Architecture Diagram 4
+	 */
+
+	/* PD_DDR */
+	GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(0), 7, GFLAGS),
+	GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(0), 13, GFLAGS),
+	COMPOSITE_NOGATE(SCLK_DDRCLK, "sclk_ddrc", mux_ddrphy_p, CLK_IGNORE_UNUSED,
+			PX30_CLKSEL_CON(2), 7, 1, MFLAGS, 0, 3, DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
+	COMPOSITE_NOGATE(0, "clk_ddrphy4x", mux_ddrphy_p, CLK_IGNORE_UNUSED,
+			PX30_CLKSEL_CON(2), 7, 1, MFLAGS, 0, 3, DFLAGS),
+	FACTOR_GATE(0, "clk_ddrphy1x", "clk_ddrphy4x", CLK_IGNORE_UNUSED, 1, 4,
+			PX30_CLKGATE_CON(0), 14, GFLAGS),
+	FACTOR_GATE(0, "clk_stdby_2wrap", "clk_ddrphy4x", CLK_IGNORE_UNUSED, 1, 4,
+			PX30_CLKGATE_CON(1), 0, GFLAGS),
+	COMPOSITE_NODIV(0, "clk_ddrstdby", mux_ddrstdby_p, CLK_IGNORE_UNUSED,
+			PX30_CLKSEL_CON(2), 4, 1, MFLAGS,
+			PX30_CLKGATE_CON(1), 13, GFLAGS),
+	GATE(0, "aclk_split", "clk_ddrphy1x", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(1), 15, GFLAGS),
+	GATE(0, "clk_msch", "clk_ddrphy1x", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(1), 8, GFLAGS),
+	GATE(0, "aclk_ddrc", "clk_ddrphy1x", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(1), 5, GFLAGS),
+	GATE(0, "clk_core_ddrc", "clk_ddrphy1x", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(1), 6, GFLAGS),
+	GATE(0, "aclk_cmd_buff", "clk_ddrphy1x", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(1), 6, GFLAGS),
+	GATE(0, "clk_ddrmon", "clk_ddrphy1x", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(1), 11, GFLAGS),
+
+	GATE(0, "clk_ddrmon_timer", "xin24m", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(0), 15, GFLAGS),
+
+	COMPOSITE_NOMUX(PCLK_DDR, "pclk_ddr", "gpll", CLK_IGNORE_UNUSED,
+			PX30_CLKSEL_CON(2), 8, 5, DFLAGS,
+			PX30_CLKGATE_CON(1), 1, GFLAGS),
+	GATE(0, "pclk_ddrmon", "pclk_ddr", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(1), 10, GFLAGS),
+	GATE(0, "pclk_ddrc", "pclk_ddr", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(1), 7, GFLAGS),
+	GATE(0, "pclk_msch", "pclk_ddr", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(1), 9, GFLAGS),
+	GATE(0, "pclk_stdby", "pclk_ddr", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(1), 12, GFLAGS),
+	GATE(0, "pclk_ddr_grf", "pclk_ddr", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(1), 14, GFLAGS),
+	GATE(0, "pclk_cmdbuff", "pclk_ddr", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(1), 3, GFLAGS),
+
+	/*
+	 * Clock-Architecture Diagram 5
+	 */
+
+	/* PD_VI */
+	COMPOSITE(ACLK_VI_PRE, "aclk_vi_pre", mux_gpll_cpll_npll_p, 0,
+			PX30_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(4), 8, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_VI_PRE, "hclk_vi_pre", "aclk_vi_pre", 0,
+			PX30_CLKSEL_CON(11), 8, 4, DFLAGS,
+			PX30_CLKGATE_CON(4), 12, GFLAGS),
+	COMPOSITE(SCLK_ISP, "clk_isp", mux_gpll_cpll_npll_p, 0,
+			PX30_CLKSEL_CON(12), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(4), 9, GFLAGS),
+	COMPOSITE(SCLK_CIF_OUT, "clk_cif_out", mux_cif_out_p, 0,
+			PX30_CLKSEL_CON(13), 6, 2, MFLAGS, 0, 6, DFLAGS,
+			PX30_CLKGATE_CON(4), 11, GFLAGS),
+	GATE(PCLK_ISP, "pclkin_isp", "ext_pclkin", 0,
+			PX30_CLKGATE_CON(4), 13, GFLAGS),
+	GATE(PCLK_CIF, "pclkin_cif", "ext_pclkin", 0,
+			PX30_CLKGATE_CON(4), 14, GFLAGS),
+
+	/*
+	 * Clock-Architecture Diagram 6
+	 */
+
+	/* PD_VO */
+	COMPOSITE(ACLK_VO_PRE, "aclk_vo_pre", mux_gpll_cpll_npll_p, 0,
+			PX30_CLKSEL_CON(3), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(2), 0, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_VO_PRE, "hclk_vo_pre", "aclk_vo_pre", 0,
+			PX30_CLKSEL_CON(3), 8, 4, DFLAGS,
+			PX30_CLKGATE_CON(2), 12, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_VO_PRE, "pclk_vo_pre", "aclk_vo_pre", 0,
+			PX30_CLKSEL_CON(3), 12, 4, DFLAGS,
+			PX30_CLKGATE_CON(2), 13, GFLAGS),
+	COMPOSITE(SCLK_RGA_CORE, "clk_rga_core", mux_gpll_cpll_npll_p, 0,
+			PX30_CLKSEL_CON(4), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(2), 1, GFLAGS),
+
+	COMPOSITE(SCLK_VOPB_PWM, "clk_vopb_pwm", mux_gpll_xin24m_p, 0,
+			PX30_CLKSEL_CON(7), 7, 1, MFLAGS, 0, 7, DFLAGS,
+			PX30_CLKGATE_CON(2), 5, GFLAGS),
+	COMPOSITE(0, "dclk_vopb_src", mux_cpll_npll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+			PX30_CLKSEL_CON(5), 11, 1, MFLAGS, 0, 8, DFLAGS,
+			PX30_CLKGATE_CON(2), 2, GFLAGS),
+	COMPOSITE_FRACMUX(0, "dclk_vopb_frac", "dclk_vopb_src", CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(6), 0,
+			PX30_CLKGATE_CON(2), 3, GFLAGS,
+			&px30_dclk_vopb_fracmux),
+	GATE(DCLK_VOPB, "dclk_vopb", "dclk_vopb_mux", CLK_SET_RATE_PARENT,
+			PX30_CLKGATE_CON(2), 4, GFLAGS),
+	COMPOSITE(0, "dclk_vopl_src", mux_npll_cpll_p, 0,
+			PX30_CLKSEL_CON(8), 11, 1, MFLAGS, 0, 8, DFLAGS,
+			PX30_CLKGATE_CON(2), 6, GFLAGS),
+	COMPOSITE_FRACMUX(0, "dclk_vopl_frac", "dclk_vopl_src", CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(9), 0,
+			PX30_CLKGATE_CON(2), 7, GFLAGS,
+			&px30_dclk_vopl_fracmux),
+	GATE(DCLK_VOPL, "dclk_vopl", "dclk_vopl_mux", CLK_SET_RATE_PARENT,
+			PX30_CLKGATE_CON(2), 8, GFLAGS),
+
+	/* PD_VPU */
+	COMPOSITE(0, "aclk_vpu_pre", mux_gpll_cpll_npll_p, 0,
+			PX30_CLKSEL_CON(10), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(4), 0, GFLAGS),
+	COMPOSITE_NOMUX(0, "hclk_vpu_pre", "aclk_vpu_pre", 0,
+			PX30_CLKSEL_CON(10), 8, 4, DFLAGS,
+			PX30_CLKGATE_CON(4), 2, GFLAGS),
+	COMPOSITE(SCLK_CORE_VPU, "sclk_core_vpu", mux_gpll_cpll_npll_p, 0,
+			PX30_CLKSEL_CON(13), 14, 2, MFLAGS, 8, 5, DFLAGS,
+			PX30_CLKGATE_CON(4), 1, GFLAGS),
+
+	/*
+	 * Clock-Architecture Diagram 7
+	 */
+
+	COMPOSITE_NODIV(ACLK_PERI_SRC, "aclk_peri_src", mux_gpll_cpll_p, 0,
+			PX30_CLKSEL_CON(14), 15, 1, MFLAGS,
+			PX30_CLKGATE_CON(5), 7, GFLAGS),
+	COMPOSITE_NOMUX(ACLK_PERI_PRE, "aclk_peri_pre", "aclk_peri_src", CLK_IGNORE_UNUSED,
+			PX30_CLKSEL_CON(14), 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(5), 8, GFLAGS),
+	DIV(HCLK_PERI_PRE, "hclk_peri_pre", "aclk_peri_src", CLK_IGNORE_UNUSED,
+			PX30_CLKSEL_CON(14), 8, 5, DFLAGS),
+
+	/* PD_MMC_NAND */
+	GATE(HCLK_MMC_NAND, "hclk_mmc_nand", "hclk_peri_pre", 0,
+			PX30_CLKGATE_CON(6), 0, GFLAGS),
+	COMPOSITE(SCLK_NANDC, "clk_nandc", mux_gpll_cpll_npll_p, 0,
+			PX30_CLKSEL_CON(15), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(5), 13, GFLAGS),
+
+	COMPOSITE(SCLK_SDIO, "clk_sdio", mux_gpll_cpll_npll_xin24m_p, 0,
+			PX30_CLKSEL_CON(18), 14, 2, MFLAGS, 0, 8, DFLAGS,
+			PX30_CLKGATE_CON(6), 3, GFLAGS),
+
+	COMPOSITE(SCLK_EMMC, "clk_emmc", mux_gpll_cpll_npll_xin24m_p, 0,
+			PX30_CLKSEL_CON(20), 14, 2, MFLAGS, 0, 8, DFLAGS,
+			PX30_CLKGATE_CON(6), 6, GFLAGS),
+
+	COMPOSITE(SCLK_SFC, "clk_sfc", mux_gpll_cpll_p, 0,
+			PX30_CLKSEL_CON(22), 7, 1, MFLAGS, 0, 7, DFLAGS,
+			PX30_CLKGATE_CON(6), 7, GFLAGS),
+
+	MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "clk_sdmmc",
+	    PX30_SDMMC_CON0, 1),
+	MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "clk_sdmmc",
+	    PX30_SDMMC_CON1, 1),
+
+	MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio",
+	    PX30_SDIO_CON0, 1),
+	MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio",
+	    PX30_SDIO_CON1, 1),
+
+	MMC(SCLK_EMMC_DRV, "emmc_drv", "clk_emmc",
+	    PX30_EMMC_CON0, 1),
+	MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "clk_emmc",
+	    PX30_EMMC_CON1, 1),
+
+	/* PD_SDCARD */
+	GATE(0, "hclk_sdmmc_pre", "hclk_peri_pre", 0,
+			PX30_CLKGATE_CON(6), 12, GFLAGS),
+	COMPOSITE(SCLK_SDMMC, "clk_sdmmc", mux_gpll_cpll_npll_xin24m_p, 0,
+			PX30_CLKSEL_CON(16), 14, 2, MFLAGS, 0, 8, DFLAGS,
+			PX30_CLKGATE_CON(6), 15, GFLAGS),
+
+	/* PD_USB */
+	GATE(HCLK_USB, "hclk_usb", "hclk_peri_pre", 0,
+			PX30_CLKGATE_CON(7), 2, GFLAGS),
+	GATE(SCLK_OTG_ADP, "clk_otg_adp", "clk_rtc32k_pmu", 0,
+			PX30_CLKGATE_CON(7), 3, GFLAGS),
+
+	/* PD_GMAC */
+	COMPOSITE(SCLK_GMAC_SRC, "clk_gmac_src", mux_gpll_cpll_npll_p, 0,
+			PX30_CLKSEL_CON(22), 14, 2, MFLAGS, 8, 5, DFLAGS,
+			PX30_CLKGATE_CON(7), 11, GFLAGS),
+	MUX(SCLK_GMAC, "clk_gmac", mux_gmac_p,  CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(23), 6, 1, MFLAGS),
+	GATE(SCLK_MAC_REF, "clk_mac_ref", "clk_gmac", 0,
+			PX30_CLKGATE_CON(7), 15, GFLAGS),
+	GATE(SCLK_GMAC_RX_TX, "clk_gmac_rx_tx", "clk_gmac", 0,
+			PX30_CLKGATE_CON(7), 13, GFLAGS),
+	FACTOR(0, "clk_gmac_rx_tx_div2", "clk_gmac_rx_tx", 0, 1, 2),
+	FACTOR(0, "clk_gmac_rx_tx_div20", "clk_gmac_rx_tx", 0, 1, 20),
+	MUX(SCLK_GMAC_RMII, "clk_gmac_rmii_sel", mux_gmac_rmii_sel_p,  CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(23), 7, 1, MFLAGS),
+
+	GATE(0, "aclk_gmac_pre", "aclk_peri_pre", 0,
+			PX30_CLKGATE_CON(7), 10, GFLAGS),
+	COMPOSITE_NOMUX(0, "pclk_gmac_pre", "aclk_gmac_pre", 0,
+			PX30_CLKSEL_CON(23), 0, 4, DFLAGS,
+			PX30_CLKGATE_CON(7), 12, GFLAGS),
+
+	COMPOSITE(SCLK_MAC_OUT, "clk_mac_out", mux_gpll_cpll_npll_p, 0,
+			PX30_CLKSEL_CON(12), 14, 2, MFLAGS, 8, 5, DFLAGS,
+			PX30_CLKGATE_CON(8), 5, GFLAGS),
+
+	/*
+	 * Clock-Architecture Diagram 8
+	 */
+
+	/* PD_BUS */
+	COMPOSITE_NODIV(ACLK_BUS_SRC, "aclk_bus_src", mux_gpll_cpll_p, CLK_IGNORE_UNUSED,
+			PX30_CLKSEL_CON(23), 15, 1, MFLAGS,
+			PX30_CLKGATE_CON(8), 6, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_BUS_PRE, "hclk_bus_pre", "aclk_bus_src", CLK_IGNORE_UNUSED,
+			PX30_CLKSEL_CON(24), 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(8), 8, GFLAGS),
+	COMPOSITE_NOMUX(ACLK_BUS_PRE, "aclk_bus_pre", "aclk_bus_src", CLK_IGNORE_UNUSED,
+			PX30_CLKSEL_CON(23), 8, 5, DFLAGS,
+			PX30_CLKGATE_CON(8), 7, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_BUS_PRE, "pclk_bus_pre", "aclk_bus_pre", CLK_IGNORE_UNUSED,
+			PX30_CLKSEL_CON(24), 8, 2, DFLAGS,
+			PX30_CLKGATE_CON(8), 9, GFLAGS),
+	GATE(0, "pclk_top_pre", "pclk_bus_pre", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(8), 10, GFLAGS),
+
+	COMPOSITE(0, "clk_pdm_src", mux_gpll_xin24m_npll_p, 0,
+			PX30_CLKSEL_CON(26), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			PX30_CLKGATE_CON(9), 9, GFLAGS),
+	COMPOSITE_FRACMUX(0, "clk_pdm_frac", "clk_pdm_src", CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(27), 0,
+			PX30_CLKGATE_CON(9), 10, GFLAGS,
+			&px30_pdm_fracmux),
+	GATE(SCLK_PDM, "clk_pdm", "clk_pdm_mux", CLK_SET_RATE_PARENT,
+			PX30_CLKGATE_CON(9), 11, GFLAGS),
+
+	COMPOSITE(0, "clk_i2s0_tx_src", mux_gpll_npll_p, 0,
+			PX30_CLKSEL_CON(28), 8, 1, MFLAGS, 0, 7, DFLAGS,
+			PX30_CLKGATE_CON(9), 12, GFLAGS),
+	COMPOSITE_FRACMUX(0, "clk_i2s0_tx_frac", "clk_i2s0_tx_src", CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(29), 0,
+			PX30_CLKGATE_CON(9), 13, GFLAGS,
+			&px30_i2s0_tx_fracmux),
+	COMPOSITE_NODIV(SCLK_I2S0_TX, "clk_i2s0_tx", mux_i2s0_tx_rx_p, CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(28), 12, 1, MFLAGS,
+			PX30_CLKGATE_CON(9), 14, GFLAGS),
+	COMPOSITE_NODIV(0, "clk_i2s0_tx_out_pre", mux_i2s0_tx_out_p, 0,
+			PX30_CLKSEL_CON(28), 14, 2, MFLAGS,
+			PX30_CLKGATE_CON(9), 15, GFLAGS),
+	GATE(SCLK_I2S0_TX_OUT, "clk_i2s0_tx_out", "clk_i2s0_tx_out_pre", CLK_SET_RATE_PARENT,
+			PX30_CLKGATE_CON(10), 8, CLK_GATE_HIWORD_MASK),
+
+	COMPOSITE(0, "clk_i2s0_rx_src", mux_gpll_npll_p, 0,
+			PX30_CLKSEL_CON(58), 8, 1, MFLAGS, 0, 7, DFLAGS,
+			PX30_CLKGATE_CON(17), 0, GFLAGS),
+	COMPOSITE_FRACMUX(0, "clk_i2s0_rx_frac", "clk_i2s0_rx_src", CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(59), 0,
+			PX30_CLKGATE_CON(17), 1, GFLAGS,
+			&px30_i2s0_rx_fracmux),
+	COMPOSITE_NODIV(SCLK_I2S0_RX, "clk_i2s0_rx", mux_i2s0_rx_tx_p, CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(58), 12, 1, MFLAGS,
+			PX30_CLKGATE_CON(17), 2, GFLAGS),
+	COMPOSITE_NODIV(0, "clk_i2s0_rx_out_pre", mux_i2s0_rx_out_p, 0,
+			PX30_CLKSEL_CON(58), 14, 2, MFLAGS,
+			PX30_CLKGATE_CON(17), 3, GFLAGS),
+	GATE(SCLK_I2S0_RX_OUT, "clk_i2s0_rx_out", "clk_i2s0_rx_out_pre", CLK_SET_RATE_PARENT,
+			PX30_CLKGATE_CON(10), 11, CLK_GATE_HIWORD_MASK),
+
+	COMPOSITE(0, "clk_i2s1_src", mux_gpll_npll_p, 0,
+			PX30_CLKSEL_CON(30), 8, 1, MFLAGS, 0, 7, DFLAGS,
+			PX30_CLKGATE_CON(10), 0, GFLAGS),
+	COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_src", CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(31), 0,
+			PX30_CLKGATE_CON(10), 1, GFLAGS,
+			&px30_i2s1_fracmux),
+	GATE(SCLK_I2S1, "clk_i2s1", "clk_i2s1_mux", CLK_SET_RATE_PARENT,
+			PX30_CLKGATE_CON(10), 2, GFLAGS),
+	COMPOSITE_NODIV(0, "clk_i2s1_out_pre", mux_i2s1_out_p, 0,
+			PX30_CLKSEL_CON(30), 15, 1, MFLAGS,
+			PX30_CLKGATE_CON(10), 3, GFLAGS),
+	GATE(SCLK_I2S1_OUT, "clk_i2s1_out", "clk_i2s1_out_pre", CLK_SET_RATE_PARENT,
+			PX30_CLKGATE_CON(10), 9, CLK_GATE_HIWORD_MASK),
+
+	COMPOSITE(0, "clk_i2s2_src", mux_gpll_npll_p, 0,
+			PX30_CLKSEL_CON(32), 8, 1, MFLAGS, 0, 7, DFLAGS,
+			PX30_CLKGATE_CON(10), 4, GFLAGS),
+	COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_src", CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(33), 0,
+			PX30_CLKGATE_CON(10), 5, GFLAGS,
+			&px30_i2s2_fracmux),
+	GATE(SCLK_I2S2, "clk_i2s2", "clk_i2s2_mux", CLK_SET_RATE_PARENT,
+			PX30_CLKGATE_CON(10), 6, GFLAGS),
+	COMPOSITE_NODIV(0, "clk_i2s2_out_pre", mux_i2s2_out_p, 0,
+			PX30_CLKSEL_CON(32), 15, 1, MFLAGS,
+			PX30_CLKGATE_CON(10), 7, GFLAGS),
+	GATE(SCLK_I2S2_OUT, "clk_i2s2_out", "clk_i2s2_out_pre", CLK_SET_RATE_PARENT,
+			PX30_CLKGATE_CON(10), 10, CLK_GATE_HIWORD_MASK),
+
+	COMPOSITE(SCLK_UART1_SRC, "clk_uart1_src", mux_uart_src_p, CLK_SET_RATE_NO_REPARENT,
+			PX30_CLKSEL_CON(34), 14, 2, MFLAGS, 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(10), 12, GFLAGS),
+	COMPOSITE_NOMUX_HALFDIV(0, "clk_uart1_np5", "clk_uart1_src", 0,
+			PX30_CLKSEL_CON(35), 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(10), 13, GFLAGS),
+	COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_src", CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(36), 0,
+			PX30_CLKGATE_CON(10), 14, GFLAGS,
+			&px30_uart1_fracmux),
+	GATE(SCLK_UART1, "clk_uart1", "clk_uart1_mux", CLK_SET_RATE_PARENT,
+			PX30_CLKGATE_CON(10), 15, GFLAGS),
+
+	COMPOSITE(SCLK_UART2_SRC, "clk_uart2_src", mux_uart_src_p, 0,
+			PX30_CLKSEL_CON(37), 14, 2, MFLAGS, 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(11), 0, GFLAGS),
+	COMPOSITE_NOMUX_HALFDIV(0, "clk_uart2_np5", "clk_uart2_src", 0,
+			PX30_CLKSEL_CON(38), 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(11), 1, GFLAGS),
+	COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_src", CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(39), 0,
+			PX30_CLKGATE_CON(11), 2, GFLAGS,
+			&px30_uart2_fracmux),
+	GATE(SCLK_UART2, "clk_uart2", "clk_uart2_mux", CLK_SET_RATE_PARENT,
+			PX30_CLKGATE_CON(11), 3, GFLAGS),
+
+	COMPOSITE(0, "clk_uart3_src", mux_uart_src_p, 0,
+			PX30_CLKSEL_CON(40), 14, 2, MFLAGS, 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(11), 4, GFLAGS),
+	COMPOSITE_NOMUX_HALFDIV(0, "clk_uart3_np5", "clk_uart3_src", 0,
+			PX30_CLKSEL_CON(41), 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(11), 5, GFLAGS),
+	COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_src", CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(42), 0,
+			PX30_CLKGATE_CON(11), 6, GFLAGS,
+			&px30_uart3_fracmux),
+	GATE(SCLK_UART3, "clk_uart3", "clk_uart3_mux", CLK_SET_RATE_PARENT,
+			PX30_CLKGATE_CON(11), 7, GFLAGS),
+
+	COMPOSITE(0, "clk_uart4_src", mux_uart_src_p, 0,
+			PX30_CLKSEL_CON(43), 14, 2, MFLAGS, 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(11), 8, GFLAGS),
+	COMPOSITE_NOMUX_HALFDIV(0, "clk_uart4_np5", "clk_uart4_src", 0,
+			PX30_CLKSEL_CON(44), 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(11), 9, GFLAGS),
+	COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_src", CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(45), 0,
+			PX30_CLKGATE_CON(11), 10, GFLAGS,
+			&px30_uart4_fracmux),
+	GATE(SCLK_UART4, "clk_uart4", "clk_uart4_mux", CLK_SET_RATE_PARENT,
+			PX30_CLKGATE_CON(11), 11, GFLAGS),
+
+	COMPOSITE(0, "clk_uart5_src", mux_uart_src_p, 0,
+			PX30_CLKSEL_CON(46), 14, 2, MFLAGS, 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(11), 12, GFLAGS),
+	COMPOSITE_NOMUX_HALFDIV(0, "clk_uart5_np5", "clk_uart5_src", 0,
+			PX30_CLKSEL_CON(47), 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(11), 13, GFLAGS),
+	COMPOSITE_FRACMUX(0, "clk_uart5_frac", "clk_uart5_src", CLK_SET_RATE_PARENT,
+			PX30_CLKSEL_CON(48), 0,
+			PX30_CLKGATE_CON(11), 14, GFLAGS,
+			&px30_uart5_fracmux),
+	GATE(SCLK_UART5, "clk_uart5", "clk_uart5_mux", CLK_SET_RATE_PARENT,
+			PX30_CLKGATE_CON(11), 15, GFLAGS),
+
+	COMPOSITE(SCLK_I2C0, "clk_i2c0", mux_gpll_xin24m_p, 0,
+			PX30_CLKSEL_CON(49), 7, 1, MFLAGS, 0, 7, DFLAGS,
+			PX30_CLKGATE_CON(12), 0, GFLAGS),
+	COMPOSITE(SCLK_I2C1, "clk_i2c1", mux_gpll_xin24m_p, 0,
+			PX30_CLKSEL_CON(49), 15, 1, MFLAGS, 8, 7, DFLAGS,
+			PX30_CLKGATE_CON(12), 1, GFLAGS),
+	COMPOSITE(SCLK_I2C2, "clk_i2c2", mux_gpll_xin24m_p, 0,
+			PX30_CLKSEL_CON(50), 7, 1, MFLAGS, 0, 7, DFLAGS,
+			PX30_CLKGATE_CON(12), 2, GFLAGS),
+	COMPOSITE(SCLK_I2C3, "clk_i2c3", mux_gpll_xin24m_p, 0,
+			PX30_CLKSEL_CON(50), 15, 1, MFLAGS, 8, 7, DFLAGS,
+			PX30_CLKGATE_CON(12), 3, GFLAGS),
+	COMPOSITE(SCLK_PWM0, "clk_pwm0", mux_gpll_xin24m_p, 0,
+			PX30_CLKSEL_CON(52), 7, 1, MFLAGS, 0, 7, DFLAGS,
+			PX30_CLKGATE_CON(12), 5, GFLAGS),
+	COMPOSITE(SCLK_PWM1, "clk_pwm1", mux_gpll_xin24m_p, 0,
+			PX30_CLKSEL_CON(52), 15, 1, MFLAGS, 8, 7, DFLAGS,
+			PX30_CLKGATE_CON(12), 6, GFLAGS),
+	COMPOSITE(SCLK_SPI0, "clk_spi0", mux_gpll_xin24m_p, 0,
+			PX30_CLKSEL_CON(53), 7, 1, MFLAGS, 0, 7, DFLAGS,
+			PX30_CLKGATE_CON(12), 7, GFLAGS),
+	COMPOSITE(SCLK_SPI1, "clk_spi1", mux_gpll_xin24m_p, 0,
+			PX30_CLKSEL_CON(53), 15, 1, MFLAGS, 8, 7, DFLAGS,
+			PX30_CLKGATE_CON(12), 8, GFLAGS),
+
+	GATE(SCLK_TIMER0, "sclk_timer0", "xin24m", 0,
+			PX30_CLKGATE_CON(13), 0, GFLAGS),
+	GATE(SCLK_TIMER1, "sclk_timer1", "xin24m", 0,
+			PX30_CLKGATE_CON(13), 1, GFLAGS),
+	GATE(SCLK_TIMER2, "sclk_timer2", "xin24m", 0,
+			PX30_CLKGATE_CON(13), 2, GFLAGS),
+	GATE(SCLK_TIMER3, "sclk_timer3", "xin24m", 0,
+			PX30_CLKGATE_CON(13), 3, GFLAGS),
+	GATE(SCLK_TIMER4, "sclk_timer4", "xin24m", 0,
+			PX30_CLKGATE_CON(13), 4, GFLAGS),
+	GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0,
+			PX30_CLKGATE_CON(13), 5, GFLAGS),
+
+	COMPOSITE_NOMUX(SCLK_TSADC, "clk_tsadc", "xin24m", 0,
+			PX30_CLKSEL_CON(54), 0, 11, DFLAGS,
+			PX30_CLKGATE_CON(12), 9, GFLAGS),
+	COMPOSITE_NOMUX(SCLK_SARADC, "clk_saradc", "xin24m", 0,
+			PX30_CLKSEL_CON(55), 0, 11, DFLAGS,
+			PX30_CLKGATE_CON(12), 10, GFLAGS),
+	COMPOSITE_NOMUX(SCLK_OTP, "clk_otp", "xin24m", 0,
+			PX30_CLKSEL_CON(56), 0, 3, DFLAGS,
+			PX30_CLKGATE_CON(12), 11, GFLAGS),
+	COMPOSITE_NOMUX(SCLK_OTP_USR, "clk_otp_usr", "clk_otp", 0,
+			PX30_CLKSEL_CON(56), 4, 2, DFLAGS,
+			PX30_CLKGATE_CON(13), 6, GFLAGS),
+
+	GATE(0, "clk_cpu_boost", "xin24m", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(12), 12, GFLAGS),
+
+	/* PD_CRYPTO */
+	GATE(0, "aclk_crypto_pre", "aclk_bus_pre", 0,
+			PX30_CLKGATE_CON(8), 12, GFLAGS),
+	GATE(0, "hclk_crypto_pre", "hclk_bus_pre", 0,
+			PX30_CLKGATE_CON(8), 13, GFLAGS),
+	COMPOSITE(SCLK_CRYPTO, "clk_crypto", mux_gpll_cpll_npll_p, 0,
+			PX30_CLKSEL_CON(25), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			PX30_CLKGATE_CON(8), 14, GFLAGS),
+	COMPOSITE(SCLK_CRYPTO_APK, "clk_crypto_apk", mux_gpll_cpll_npll_p, 0,
+			PX30_CLKSEL_CON(25), 14, 2, MFLAGS, 8, 5, DFLAGS,
+			PX30_CLKGATE_CON(8), 15, GFLAGS),
+
+	/*
+	 * Clock-Architecture Diagram 9
+	 */
+
+	/* PD_BUS_TOP */
+	GATE(0, "pclk_top_niu", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 0, GFLAGS),
+	GATE(0, "pclk_top_cru", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 1, GFLAGS),
+	GATE(PCLK_OTP_PHY, "pclk_otp_phy", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 2, GFLAGS),
+	GATE(0, "pclk_ddrphy", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 3, GFLAGS),
+	GATE(PCLK_MIPIDSIPHY, "pclk_mipidsiphy", "pclk_top_pre", 0, PX30_CLKGATE_CON(16), 4, GFLAGS),
+	GATE(PCLK_MIPICSIPHY, "pclk_mipicsiphy", "pclk_top_pre", 0, PX30_CLKGATE_CON(16), 5, GFLAGS),
+	GATE(PCLK_USB_GRF, "pclk_usb_grf", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 6, GFLAGS),
+	GATE(0, "pclk_cpu_hoost", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 7, GFLAGS),
+
+	/* PD_VI */
+	GATE(0, "aclk_vi_niu", "aclk_vi_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(4), 15, GFLAGS),
+	GATE(ACLK_CIF, "aclk_cif", "aclk_vi_pre", 0, PX30_CLKGATE_CON(5), 1, GFLAGS),
+	GATE(ACLK_ISP, "aclk_isp", "aclk_vi_pre", 0, PX30_CLKGATE_CON(5), 3, GFLAGS),
+	GATE(0, "hclk_vi_niu", "hclk_vi_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(5), 0, GFLAGS),
+	GATE(HCLK_CIF, "hclk_cif", "hclk_vi_pre", 0, PX30_CLKGATE_CON(5), 2, GFLAGS),
+	GATE(HCLK_ISP, "hclk_isp", "hclk_vi_pre", 0, PX30_CLKGATE_CON(5), 4, GFLAGS),
+
+	/* PD_VO */
+	GATE(0, "aclk_vo_niu", "aclk_vo_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(3), 0, GFLAGS),
+	GATE(ACLK_VOPB, "aclk_vopb", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 3, GFLAGS),
+	GATE(ACLK_RGA, "aclk_rga", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 7, GFLAGS),
+	GATE(ACLK_VOPL, "aclk_vopl", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 5, GFLAGS),
+
+	GATE(0, "hclk_vo_niu", "hclk_vo_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(3), 1, GFLAGS),
+	GATE(HCLK_VOPB, "hclk_vopb", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 4, GFLAGS),
+	GATE(HCLK_RGA, "hclk_rga", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 8, GFLAGS),
+	GATE(HCLK_VOPL, "hclk_vopl", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 6, GFLAGS),
+
+	GATE(0, "pclk_vo_niu", "pclk_vo_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(3), 2, GFLAGS),
+	GATE(PCLK_MIPI_DSI, "pclk_mipi_dsi", "pclk_vo_pre", 0, PX30_CLKGATE_CON(3), 9, GFLAGS),
+
+	/* PD_BUS */
+	GATE(0, "aclk_bus_niu", "aclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 8, GFLAGS),
+	GATE(0, "aclk_intmem", "aclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 11, GFLAGS),
+	GATE(ACLK_GIC, "aclk_gic", "aclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 12, GFLAGS),
+	GATE(ACLK_DCF, "aclk_dcf", "aclk_bus_pre", 0, PX30_CLKGATE_CON(13), 15, GFLAGS),
+
+	GATE(0, "hclk_bus_niu", "hclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 9, GFLAGS),
+	GATE(0, "hclk_rom", "hclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 14, GFLAGS),
+	GATE(HCLK_PDM, "hclk_pdm", "hclk_bus_pre", 0, PX30_CLKGATE_CON(14), 1, GFLAGS),
+	GATE(HCLK_I2S0, "hclk_i2s0", "hclk_bus_pre", 0, PX30_CLKGATE_CON(14), 2, GFLAGS),
+	GATE(HCLK_I2S1, "hclk_i2s1", "hclk_bus_pre", 0, PX30_CLKGATE_CON(14), 3, GFLAGS),
+	GATE(HCLK_I2S2, "hclk_i2s2", "hclk_bus_pre", 0, PX30_CLKGATE_CON(14), 4, GFLAGS),
+
+	GATE(0, "pclk_bus_niu", "pclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 10, GFLAGS),
+	GATE(PCLK_DCF, "pclk_dcf", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 0, GFLAGS),
+	GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 5, GFLAGS),
+	GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 6, GFLAGS),
+	GATE(PCLK_UART3, "pclk_uart3", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 7, GFLAGS),
+	GATE(PCLK_UART4, "pclk_uart4", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 8, GFLAGS),
+	GATE(PCLK_UART5, "pclk_uart5", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 9, GFLAGS),
+	GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 10, GFLAGS),
+	GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 11, GFLAGS),
+	GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 12, GFLAGS),
+	GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 13, GFLAGS),
+	GATE(PCLK_I2C4, "pclk_i2c4", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 14, GFLAGS),
+	GATE(PCLK_PWM0, "pclk_pwm0", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 15, GFLAGS),
+	GATE(PCLK_PWM1, "pclk_pwm1", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 0, GFLAGS),
+	GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 1, GFLAGS),
+	GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 2, GFLAGS),
+	GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 3, GFLAGS),
+	GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 4, GFLAGS),
+	GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 5, GFLAGS),
+	GATE(PCLK_OTP_NS, "pclk_otp_ns", "pclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(15), 6, GFLAGS),
+	GATE(PCLK_WDT_NS, "pclk_wdt_ns", "pclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(15), 7, GFLAGS),
+	GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 8, GFLAGS),
+	GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 9, GFLAGS),
+	GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 10, GFLAGS),
+	GATE(0, "pclk_grf", "pclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(15), 11, GFLAGS),
+	GATE(0, "pclk_sgrf", "pclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(15), 12, GFLAGS),
+
+	/* PD_VPU */
+	GATE(0, "hclk_vpu_niu", "hclk_vpu_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(4), 7, GFLAGS),
+	GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", 0, PX30_CLKGATE_CON(4), 6, GFLAGS),
+	GATE(0, "aclk_vpu_niu", "aclk_vpu_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(4), 5, GFLAGS),
+	GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", 0, PX30_CLKGATE_CON(4), 4, GFLAGS),
+
+	/* PD_CRYPTO */
+	GATE(0, "hclk_crypto_niu", "hclk_crypto_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(9), 3, GFLAGS),
+	GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_crypto_pre", 0, PX30_CLKGATE_CON(9), 5, GFLAGS),
+	GATE(0, "aclk_crypto_niu", "aclk_crypto_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(9), 2, GFLAGS),
+	GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_crypto_pre", 0, PX30_CLKGATE_CON(9), 4, GFLAGS),
+
+	/* PD_SDCARD */
+	GATE(0, "hclk_sdmmc_niu", "hclk_sdmmc_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(7), 0, GFLAGS),
+	GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_sdmmc_pre", 0, PX30_CLKGATE_CON(7), 1, GFLAGS),
+
+	/* PD_PERI */
+	GATE(0, "aclk_peri_niu", "aclk_peri_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(5), 9, GFLAGS),
+
+	/* PD_MMC_NAND */
+	GATE(HCLK_NANDC, "hclk_nandc", "hclk_mmc_nand", 0, PX30_CLKGATE_CON(5), 15, GFLAGS),
+	GATE(0, "hclk_mmc_nand_niu", "hclk_mmc_nand", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(6), 8, GFLAGS),
+	GATE(HCLK_SDIO, "hclk_sdio", "hclk_mmc_nand", 0, PX30_CLKGATE_CON(6), 9, GFLAGS),
+	GATE(HCLK_EMMC, "hclk_emmc", "hclk_mmc_nand", 0, PX30_CLKGATE_CON(6), 10, GFLAGS),
+	GATE(HCLK_SFC, "hclk_sfc", "hclk_mmc_nand", 0, PX30_CLKGATE_CON(6), 11, GFLAGS),
+
+	/* PD_USB */
+	GATE(0, "hclk_usb_niu", "hclk_usb", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(7), 4, GFLAGS),
+	GATE(HCLK_OTG, "hclk_otg", "hclk_usb", 0, PX30_CLKGATE_CON(7), 5, GFLAGS),
+	GATE(HCLK_HOST, "hclk_host", "hclk_usb", 0, PX30_CLKGATE_CON(7), 6, GFLAGS),
+	GATE(HCLK_HOST_ARB, "hclk_host_arb", "hclk_usb", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(7), 8, GFLAGS),
+
+	/* PD_GMAC */
+	GATE(0, "aclk_gmac_niu", "aclk_gmac_pre", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(8), 0, GFLAGS),
+	GATE(ACLK_GMAC, "aclk_gmac", "aclk_gmac_pre", 0,
+			PX30_CLKGATE_CON(8), 2, GFLAGS),
+	GATE(0, "pclk_gmac_niu", "pclk_gmac_pre", CLK_IGNORE_UNUSED,
+			PX30_CLKGATE_CON(8), 1, GFLAGS),
+	GATE(PCLK_GMAC, "pclk_gmac", "pclk_gmac_pre", 0,
+			PX30_CLKGATE_CON(8), 3, GFLAGS),
+};
+
+static struct rockchip_clk_branch px30_clk_pmu_branches[] __initdata = {
+	/*
+	 * Clock-Architecture Diagram 2
+	 */
+
+	COMPOSITE_FRACMUX(0, "clk_rtc32k_frac", "xin24m", CLK_IGNORE_UNUSED,
+			PX30_PMU_CLKSEL_CON(1), 0,
+			PX30_PMU_CLKGATE_CON(0), 13, GFLAGS,
+			&px30_rtc32k_pmu_fracmux),
+
+	COMPOSITE_NOMUX(XIN24M_DIV, "xin24m_div", "xin24m", CLK_IGNORE_UNUSED,
+			PX30_PMU_CLKSEL_CON(0), 8, 5, DFLAGS,
+			PX30_PMU_CLKGATE_CON(0), 12, GFLAGS),
+
+	COMPOSITE_NOMUX(0, "clk_wifi_pmu_src", "gpll", 0,
+			PX30_PMU_CLKSEL_CON(2), 8, 6, DFLAGS,
+			PX30_PMU_CLKGATE_CON(0), 14, GFLAGS),
+	COMPOSITE_NODIV(SCLK_WIFI_PMU, "clk_wifi_pmu", mux_wifi_pmu_p, CLK_SET_RATE_PARENT,
+			PX30_PMU_CLKSEL_CON(2), 15, 1, MFLAGS,
+			PX30_PMU_CLKGATE_CON(0), 15, GFLAGS),
+
+	COMPOSITE(0, "clk_uart0_pmu_src", mux_uart_src_p, 0,
+			PX30_PMU_CLKSEL_CON(3), 14, 2, MFLAGS, 0, 5, DFLAGS,
+			PX30_PMU_CLKGATE_CON(1), 0, GFLAGS),
+	COMPOSITE_NOMUX_HALFDIV(0, "clk_uart0_np5", "clk_uart0_pmu_src", 0,
+			PX30_PMU_CLKSEL_CON(4), 0, 5, DFLAGS,
+			PX30_PMU_CLKGATE_CON(1), 1, GFLAGS),
+	COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_pmu_src", CLK_SET_RATE_PARENT,
+			PX30_PMU_CLKSEL_CON(5), 0,
+			PX30_PMU_CLKGATE_CON(1), 2, GFLAGS,
+			&px30_uart0_pmu_fracmux),
+	GATE(SCLK_UART0_PMU, "clk_uart0_pmu", "clk_uart0_pmu_mux", CLK_SET_RATE_PARENT,
+			PX30_PMU_CLKGATE_CON(1), 3, GFLAGS),
+
+	GATE(SCLK_PVTM_PMU, "clk_pvtm_pmu", "xin24m", 0,
+			PX30_PMU_CLKGATE_CON(1), 4, GFLAGS),
+
+	COMPOSITE_NOMUX(PCLK_PMU_PRE, "pclk_pmu_pre", "gpll", 0,
+			PX30_PMU_CLKSEL_CON(0), 0, 5, DFLAGS,
+			PX30_PMU_CLKGATE_CON(0), 0, GFLAGS),
+
+	COMPOSITE_NOMUX(SCLK_REF24M_PMU, "clk_ref24m_pmu", "gpll", 0,
+			PX30_PMU_CLKSEL_CON(2), 0, 6, DFLAGS,
+			PX30_PMU_CLKGATE_CON(1), 8, GFLAGS),
+	COMPOSITE_NODIV(SCLK_USBPHY_REF, "clk_usbphy_ref", mux_usbphy_ref_p, CLK_SET_RATE_PARENT,
+			PX30_PMU_CLKSEL_CON(2), 6, 1, MFLAGS,
+			PX30_PMU_CLKGATE_CON(1), 9, GFLAGS),
+	COMPOSITE_NODIV(SCLK_MIPIDSIPHY_REF, "clk_mipidsiphy_ref", mux_mipidsiphy_ref_p, CLK_SET_RATE_PARENT,
+			PX30_PMU_CLKSEL_CON(2), 7, 1, MFLAGS,
+			PX30_PMU_CLKGATE_CON(1), 10, GFLAGS),
+
+	/*
+	 * Clock-Architecture Diagram 9
+	 */
+
+	/* PD_PMU */
+	GATE(0, "pclk_pmu_niu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 1, GFLAGS),
+	GATE(0, "pclk_pmu_sgrf", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 2, GFLAGS),
+	GATE(0, "pclk_pmu_grf", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 3, GFLAGS),
+	GATE(0, "pclk_pmu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 4, GFLAGS),
+	GATE(0, "pclk_pmu_mem", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 5, GFLAGS),
+	GATE(PCLK_GPIO0_PMU, "pclk_gpio0_pmu", "pclk_pmu_pre", 0, PX30_PMU_CLKGATE_CON(0), 6, GFLAGS),
+	GATE(PCLK_UART0_PMU, "pclk_uart0_pmu", "pclk_pmu_pre", 0, PX30_PMU_CLKGATE_CON(0), 7, GFLAGS),
+	GATE(0, "pclk_cru_pmu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 8, GFLAGS),
+};
+
+static const char *const px30_pmucru_critical_clocks[] __initconst = {
+	"aclk_bus_pre",
+	"pclk_bus_pre",
+	"hclk_bus_pre",
+	"aclk_peri_pre",
+	"hclk_peri_pre",
+	"aclk_gpu_niu",
+	"pclk_top_pre",
+	"pclk_pmu_pre",
+	"hclk_usb_niu",
+	"pll_npll",
+	"usb480m",
+	"clk_uart2",
+	"pclk_uart2",
+};
+
+static void __iomem *px30_cru_base;
+static void __iomem *px30_pmucru_base;
+
+void px30_dump_cru(void)
+{
+	if (px30_cru_base) {
+		pr_warn("CRU:\n");
+		print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET,
+			       32, 4, px30_cru_base,
+			       0x400, false);
+	}
+	if (px30_pmucru_base) {
+		pr_warn("PMU CRU:\n");
+		print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET,
+			       32, 4, px30_pmucru_base,
+			       0x90, false);
+	}
+}
+EXPORT_SYMBOL_GPL(px30_dump_cru);
+
+static int px30_clk_panic(struct notifier_block *this,
+			  unsigned long ev, void *ptr)
+{
+	px30_dump_cru();
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block px30_clk_panic_block = {
+	.notifier_call = px30_clk_panic,
+};
+
+static void __init px30_clk_init(struct device_node *np)
+{
+	struct rockchip_clk_provider *ctx;
+	void __iomem *reg_base;
+	struct clk *clk;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base) {
+		pr_err("%s: could not map cru region\n", __func__);
+		return;
+	}
+
+	px30_cru_base = reg_base;
+
+	ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+	if (IS_ERR(ctx)) {
+		pr_err("%s: rockchip clk init failed\n", __func__);
+		iounmap(reg_base);
+		return;
+	}
+
+	/* aclk_dmac is controlled by sgrf_soc_con1[11]. */
+	clk = clk_register_fixed_factor(NULL, "aclk_dmac", "aclk_bus_pre", 0, 1, 1);
+	if (IS_ERR(clk))
+		pr_warn("%s: could not register clock aclk_dmac: %ld\n",
+			__func__, PTR_ERR(clk));
+	else
+		rockchip_clk_add_lookup(ctx, clk, ACLK_DMAC);
+
+	rockchip_clk_register_plls(ctx, px30_pll_clks,
+				   ARRAY_SIZE(px30_pll_clks),
+				   PX30_GRF_SOC_STATUS0);
+	rockchip_clk_register_branches(ctx, px30_clk_branches,
+				       ARRAY_SIZE(px30_clk_branches));
+
+	rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
+				     mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
+				     &px30_cpuclk_data, px30_cpuclk_rates,
+				     ARRAY_SIZE(px30_cpuclk_rates));
+
+	rockchip_register_softrst(np, 12, reg_base + PX30_SOFTRST_CON(0),
+				  ROCKCHIP_SOFTRST_HIWORD_MASK);
+
+	rockchip_register_restart_notifier(ctx, PX30_GLB_SRST_FST, NULL);
+
+	rockchip_clk_of_add_provider(np, ctx);
+
+	atomic_notifier_chain_register(&panic_notifier_list,
+				       &px30_clk_panic_block);
+}
+
+CLK_OF_DECLARE(px30_cru, "rockchip,px30-cru", px30_clk_init);
+
+static void __init px30_pmu_clk_init(struct device_node *np)
+{
+	struct rockchip_clk_provider *ctx;
+	void __iomem *reg_base;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base) {
+		pr_err("%s: could not map cru pmu region\n", __func__);
+		return;
+	}
+
+	px30_pmucru_base = reg_base;
+
+	ctx = rockchip_clk_init(np, reg_base, CLKPMU_NR_CLKS);
+	if (IS_ERR(ctx)) {
+		pr_err("%s: rockchip pmu clk init failed\n", __func__);
+		return;
+	}
+
+	rockchip_clk_register_plls(ctx, px30_pmu_pll_clks,
+				   ARRAY_SIZE(px30_pmu_pll_clks), PX30_GRF_SOC_STATUS0);
+
+	rockchip_clk_register_branches(ctx, px30_clk_pmu_branches,
+				       ARRAY_SIZE(px30_clk_pmu_branches));
+
+	rockchip_clk_protect_critical(px30_pmucru_critical_clocks,
+				      ARRAY_SIZE(px30_pmucru_critical_clocks));
+
+	rockchip_clk_of_add_provider(np, ctx);
+}
+
+CLK_OF_DECLARE(px30_cru_pmu, "rockchip,px30-pmucru", px30_pmu_clk_init);
+
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 7a3660c2bbb5..6b480b9921e3 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -34,7 +34,46 @@
 #define HIWORD_UPDATE(val, mask, shift) \
 		((val) << (shift) | (mask) << ((shift) + 16))
 
-/* register positions shared by RV1108, RK2928, RK3036, RK3066, RK3188 and RK3228 */
+/* register positions shared by PX30, RV1108, RK2928, RK3036, RK3066, RK3188 and RK3228 */
+#define BOOST_PLL_H_CON(x)		((x) * 0x4)
+#define BOOST_CLK_CON			0x0008
+#define BOOST_BOOST_CON			0x000c
+#define BOOST_SWITCH_CNT		0x0010
+#define BOOST_HIGH_PERF_CNT0		0x0014
+#define BOOST_HIGH_PERF_CNT1		0x0018
+#define BOOST_STATIS_THRESHOLD		0x001c
+#define BOOST_SHORT_SWITCH_CNT		0x0020
+#define BOOST_SWITCH_THRESHOLD		0x0024
+#define BOOST_FSM_STATUS		0x0028
+#define BOOST_PLL_L_CON(x)		((x) * 0x4 + 0x2c)
+#define BOOST_RECOVERY_MASK		0x1
+#define BOOST_RECOVERY_SHIFT		1
+#define BOOST_SW_CTRL_MASK		0x1
+#define BOOST_SW_CTRL_SHIFT		2
+#define BOOST_LOW_FREQ_EN_MASK		0x1
+#define BOOST_LOW_FREQ_EN_SHIFT		3
+#define BOOST_BUSY_STATE		BIT(8)
+
+#define PX30_PLL_CON(x)			((x) * 0x4)
+#define PX30_CLKSEL_CON(x)		((x) * 0x4 + 0x100)
+#define PX30_CLKGATE_CON(x)		((x) * 0x4 + 0x200)
+#define PX30_GLB_SRST_FST		0xb8
+#define PX30_GLB_SRST_SND		0xbc
+#define PX30_SOFTRST_CON(x)		((x) * 0x4 + 0x300)
+#define PX30_MODE_CON			0xa0
+#define PX30_MISC_CON			0xa4
+#define PX30_SDMMC_CON0			0x380
+#define PX30_SDMMC_CON1			0x384
+#define PX30_SDIO_CON0			0x388
+#define PX30_SDIO_CON1			0x38c
+#define PX30_EMMC_CON0			0x390
+#define PX30_EMMC_CON1			0x394
+
+#define PX30_PMU_PLL_CON(x)		((x) * 0x4)
+#define PX30_PMU_CLKSEL_CON(x)		((x) * 0x4 + 0x40)
+#define PX30_PMU_CLKGATE_CON(x)		((x) * 0x4 + 0x80)
+#define PX30_PMU_MODE			0x0020
+
 #define RV1108_PLL_CON(x)		((x) * 0x4)
 #define RV1108_CLKSEL_CON(x)		((x) * 0x4 + 0x60)
 #define RV1108_CLKGATE_CON(x)		((x) * 0x4 + 0x120)
-- 
1.9.1

^ permalink raw reply related

* [PATCH v1 3/4] clk: rockchip: add support for half divider
From: Elaine Zhang @ 2018-06-07  3:06 UTC (permalink / raw)
  To: heiko
  Cc: sboyd, robh+dt, mark.rutland, mturquette, linux-clk, devicetree,
	linux-arm-kernel, linux-rockchip, linux-kernel, cl, xxx, xf,
	huangtao, Elaine Zhang
In-Reply-To: <1528340786-462-1-git-send-email-zhangqing@rock-chips.com>

The new Rockchip socs have optional half divider,
so we use "branch_half_divider" + "COMPOSITE_NOMUX_HALFDIV \ DIV_HALF"
to hook that special divider clock-type into our clock-tree.

Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
---
 drivers/clk/rockchip/Makefile           |   1 +
 drivers/clk/rockchip/clk-half-divider.c | 235 ++++++++++++++++++++++++++++++++
 drivers/clk/rockchip/clk.c              |  10 ++
 drivers/clk/rockchip/clk.h              |  45 ++++++
 4 files changed, 291 insertions(+)
 create mode 100644 drivers/clk/rockchip/clk-half-divider.c

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 59b8d320960a..023f83ad3429 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -7,6 +7,7 @@ obj-y	+= clk-rockchip.o
 obj-y	+= clk.o
 obj-y	+= clk-pll.o
 obj-y	+= clk-cpu.o
+obj-y   += clk-half-divider.o
 obj-y	+= clk-inverter.o
 obj-y	+= clk-mmc-phase.o
 obj-y	+= clk-muxgrf.o
diff --git a/drivers/clk/rockchip/clk-half-divider.c b/drivers/clk/rockchip/clk-half-divider.c
new file mode 100644
index 000000000000..23830de254ec
--- /dev/null
+++ b/drivers/clk/rockchip/clk-half-divider.c
@@ -0,0 +1,235 @@
+/*
+ *
+ * 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/slab.h>
+#include <linux/bitops.h>
+#include <linux/regmap.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include "clk.h"
+
+#define div_mask(width)	((1 << (width)) - 1)
+
+static bool _is_best_half_div(unsigned long rate, unsigned long now,
+			      unsigned long best, unsigned long flags)
+{
+	if (flags & CLK_DIVIDER_ROUND_CLOSEST)
+		return abs(rate - now) < abs(rate - best);
+
+	return now <= rate && now > best;
+}
+
+static unsigned long clk_half_divider_recalc_rate(struct clk_hw *hw,
+						  unsigned long parent_rate)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+	unsigned int val;
+
+	val = clk_readl(divider->reg) >> divider->shift;
+	val &= div_mask(divider->width);
+	val = val * 2 + 3;
+
+	return DIV_ROUND_UP_ULL((u64)(parent_rate * 2), val);
+}
+
+static int clk_half_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
+				    unsigned long *best_parent_rate, u8 width,
+				    unsigned long flags)
+{
+	int i, bestdiv = 0;
+	unsigned long parent_rate, best = 0, now, maxdiv;
+	unsigned long parent_rate_saved = *best_parent_rate;
+
+	if (!rate)
+		rate = 1;
+
+	maxdiv = div_mask(width);
+
+	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
+		parent_rate = *best_parent_rate;
+		bestdiv = DIV_ROUND_UP_ULL((u64)(parent_rate * 2), rate);
+		if (bestdiv < 3)
+			bestdiv = 0;
+		else
+			bestdiv = (bestdiv - 3) / 2;
+		bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
+		return bestdiv;
+	}
+
+	/*
+	 * The maximum divider we can use without overflowing
+	 * unsigned long in rate * i below
+	 */
+	maxdiv = min(ULONG_MAX / rate, maxdiv);
+
+	for (i = 0; i <= maxdiv; i++) {
+		if ((rate * (i * 2 + 3)) == (parent_rate_saved * 2)) {
+			/*
+			 * It's the most ideal case if the requested rate can be
+			 * divided from parent clock without needing to change
+			 * parent rate, so return the divider immediately.
+			 */
+			*best_parent_rate = parent_rate_saved;
+			return i;
+		}
+		parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
+						(rate * (i * 2 + 3)) / 2);
+		now = DIV_ROUND_UP_ULL((u64)(parent_rate * 2), (i * 2 + 3));
+		if (_is_best_half_div(rate, now, best, flags)) {
+			bestdiv = i;
+			best = now;
+			*best_parent_rate = parent_rate;
+		}
+	}
+
+	if (!bestdiv) {
+		bestdiv = div_mask(width);
+		*best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 1);
+	}
+
+	return bestdiv;
+}
+
+static long clk_half_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+					unsigned long *prate)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+	int div;
+
+	div = clk_half_divider_bestdiv(hw, rate, prate,
+				       divider->width,
+				       divider->flags);
+
+	return DIV_ROUND_UP_ULL((u64)(*prate * 2), div * 2 + 3);
+}
+
+static int clk_half_divider_set_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long parent_rate)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+	unsigned int value;
+	unsigned long flags = 0;
+	u32 val;
+
+	value = DIV_ROUND_UP_ULL((u64)(2 * parent_rate), rate);
+	value = (value - 3) / 2;
+	value =  min_t(unsigned int, value, div_mask(divider->width));
+
+	if (divider->lock)
+		spin_lock_irqsave(divider->lock, flags);
+	else
+		__acquire(divider->lock);
+
+	if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
+		val = div_mask(divider->width) << (divider->shift + 16);
+	} else {
+		val = clk_readl(divider->reg);
+		val &= ~(div_mask(divider->width) << divider->shift);
+	}
+	val |= value << divider->shift;
+	clk_writel(val, divider->reg);
+
+	if (divider->lock)
+		spin_unlock_irqrestore(divider->lock, flags);
+	else
+		__release(divider->lock);
+
+	return 0;
+}
+
+const struct clk_ops clk_half_divider_ops = {
+	.recalc_rate = clk_half_divider_recalc_rate,
+	.round_rate = clk_half_divider_round_rate,
+	.set_rate = clk_half_divider_set_rate,
+};
+EXPORT_SYMBOL_GPL(clk_half_divider_ops);
+
+/**
+ * Register a clock branch.
+ * Most clock branches have a form like
+ *
+ * src1 --|--\
+ *        |M |--[GATE]-[DIV]-
+ * src2 --|--/
+ *
+ * sometimes without one of those components.
+ */
+struct clk *rockchip_clk_register_halfdiv(const char *name,
+					  const char *const *parent_names,
+					  u8 num_parents, void __iomem *base,
+					  int muxdiv_offset, u8 mux_shift,
+					  u8 mux_width, u8 mux_flags,
+					  u8 div_shift, u8 div_width,
+					  u8 div_flags, int gate_offset,
+					  u8 gate_shift, u8 gate_flags,
+					  unsigned long flags,
+					  spinlock_t *lock)
+{
+	struct clk *clk;
+	struct clk_mux *mux = NULL;
+	struct clk_gate *gate = NULL;
+	struct clk_divider *div = NULL;
+	const struct clk_ops *mux_ops = NULL, *div_ops = NULL,
+			     *gate_ops = NULL;
+
+	if (num_parents > 1) {
+		mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+		if (!mux)
+			return ERR_PTR(-ENOMEM);
+
+		mux->reg = base + muxdiv_offset;
+		mux->shift = mux_shift;
+		mux->mask = BIT(mux_width) - 1;
+		mux->flags = mux_flags;
+		mux->lock = lock;
+		mux_ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops
+							: &clk_mux_ops;
+	}
+
+	if (gate_offset >= 0) {
+		gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+		if (!gate)
+			goto err_gate;
+
+		gate->flags = gate_flags;
+		gate->reg = base + gate_offset;
+		gate->bit_idx = gate_shift;
+		gate->lock = lock;
+		gate_ops = &clk_gate_ops;
+	}
+
+	if (div_width > 0) {
+		div = kzalloc(sizeof(*div), GFP_KERNEL);
+		if (!div)
+			goto err_div;
+
+		div->flags = div_flags;
+		div->reg = base + muxdiv_offset;
+		div->shift = div_shift;
+		div->width = div_width;
+		div->lock = lock;
+		div_ops = &clk_half_divider_ops;
+	}
+
+	clk = clk_register_composite(NULL, name, parent_names, num_parents,
+				     mux ? &mux->hw : NULL, mux_ops,
+				     div ? &div->hw : NULL, div_ops,
+				     gate ? &gate->hw : NULL, gate_ops,
+				     flags);
+
+	return clk;
+err_div:
+	kfree(gate);
+err_gate:
+	kfree(mux);
+	return ERR_PTR(-ENOMEM);
+}
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 3cd8ad59e0b7..cd1474c05c91 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -498,6 +498,16 @@ void __init rockchip_clk_register_branches(
 				list->gate_flags, flags, list->child,
 				&ctx->lock);
 			break;
+		case branch_half_divider:
+			clk = rockchip_clk_register_halfdiv(list->name,
+				list->parent_names, list->num_parents,
+				ctx->reg_base, list->muxdiv_offset,
+				list->mux_shift, list->mux_width,
+				list->mux_flags, list->div_shift,
+				list->div_width, list->div_flags,
+				list->gate_offset, list->gate_shift,
+				list->gate_flags, flags, &ctx->lock);
+			break;
 		case branch_gate:
 			flags |= CLK_SET_RATE_PARENT;
 
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index ef601dded32c..7a3660c2bbb5 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -354,6 +354,7 @@ enum rockchip_clk_branch_type {
 	branch_inverter,
 	branch_factor,
 	branch_ddrclk,
+	branch_half_divider,
 };
 
 struct rockchip_clk_branch {
@@ -684,6 +685,39 @@ struct rockchip_clk_branch {
 		.gate_flags	= gf,				\
 	}
 
+#define COMPOSITE_NOMUX_HALFDIV(_id, cname, pname, f, mo, ds, dw, df,	\
+			go, gs, gf)				\
+	{							\
+		.id		= _id,				\
+		.branch_type	= branch_half_divider,		\
+		.name		= cname,			\
+		.parent_names	= (const char *[]){ pname },	\
+		.num_parents	= 1,				\
+		.flags		= f,				\
+		.muxdiv_offset	= mo,				\
+		.div_shift	= ds,				\
+		.div_width	= dw,				\
+		.div_flags	= df,				\
+		.gate_offset	= go,				\
+		.gate_shift	= gs,				\
+		.gate_flags	= gf,				\
+	}
+
+#define DIV_HALF(_id, cname, pname, f, o, s, w, df)			\
+	{							\
+		.id		= _id,				\
+		.branch_type	= branch_half_divider,		\
+		.name		= cname,			\
+		.parent_names	= (const char *[]){ pname },	\
+		.num_parents	= 1,				\
+		.flags		= f,				\
+		.muxdiv_offset	= o,				\
+		.div_shift	= s,				\
+		.div_width	= w,				\
+		.div_flags	= df,				\
+		.gate_offset	= -1,				\
+	}
+
 struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
 			void __iomem *base, unsigned long nr_clks);
 void rockchip_clk_of_add_provider(struct device_node *np,
@@ -708,6 +742,17 @@ void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
 
 #define ROCKCHIP_SOFTRST_HIWORD_MASK	BIT(0)
 
+struct clk *rockchip_clk_register_halfdiv(const char *name,
+					  const char *const *parent_names,
+					  u8 num_parents, void __iomem *base,
+					  int muxdiv_offset, u8 mux_shift,
+					  u8 mux_width, u8 mux_flags,
+					  u8 div_shift, u8 div_width,
+					  u8 div_flags, int gate_offset,
+					  u8 gate_shift, u8 gate_flags,
+					  unsigned long flags,
+					  spinlock_t *lock);
+
 #ifdef CONFIG_RESET_CONTROLLER
 void rockchip_register_softrst(struct device_node *np,
 			       unsigned int num_regs,
-- 
1.9.1

^ permalink raw reply related

* [PATCH v1 2/4] clk: rockchip: add dt-binding header for px30
From: Elaine Zhang @ 2018-06-07  3:06 UTC (permalink / raw)
  To: heiko
  Cc: sboyd, robh+dt, mark.rutland, mturquette, linux-clk, devicetree,
	linux-arm-kernel, linux-rockchip, linux-kernel, cl, xxx, xf,
	huangtao, Elaine Zhang
In-Reply-To: <1528340786-462-1-git-send-email-zhangqing@rock-chips.com>

Add the dt-bindings header for the px30, that gets shared between
the clock controller and the clock references in the dts.
Add softreset ID for px30.

Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
---
 include/dt-bindings/clock/px30-cru.h | 402 +++++++++++++++++++++++++++++++++++
 1 file changed, 402 insertions(+)
 create mode 100644 include/dt-bindings/clock/px30-cru.h

diff --git a/include/dt-bindings/clock/px30-cru.h b/include/dt-bindings/clock/px30-cru.h
new file mode 100644
index 000000000000..db9fc2a0bb21
--- /dev/null
+++ b/include/dt-bindings/clock/px30-cru.h
@@ -0,0 +1,402 @@
+/*
+ * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
+ * Author: Elaine <zhangqing@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 _DT_BINDINGS_CLK_ROCKCHIP_PX30_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_PX30_H
+
+/* core clocks */
+#define PLL_APLL		1
+#define PLL_DPLL		2
+#define PLL_CPLL		3
+#define PLL_NPLL		4
+#define APLL_BOOST_H		5
+#define APLL_BOOST_L		6
+#define ARMCLK			7
+
+/* sclk gates (special clocks) */
+#define USB480M			14
+#define SCLK_PDM		15
+#define SCLK_I2S0_TX		16
+#define SCLK_I2S0_TX_OUT	17
+#define SCLK_I2S0_RX		18
+#define SCLK_I2S0_RX_OUT	19
+#define SCLK_I2S1		20
+#define SCLK_I2S1_OUT		21
+#define SCLK_I2S2		22
+#define SCLK_I2S2_OUT		23
+#define SCLK_UART1		24
+#define SCLK_UART2		25
+#define SCLK_UART3		26
+#define SCLK_UART4		27
+#define SCLK_UART5		28
+#define SCLK_I2C0		29
+#define SCLK_I2C1		30
+#define SCLK_I2C2		31
+#define SCLK_I2C3		32
+#define SCLK_I2C4		33
+#define SCLK_PWM0		34
+#define SCLK_PWM1		35
+#define SCLK_SPI0		36
+#define SCLK_SPI1		37
+#define SCLK_TIMER0		38
+#define SCLK_TIMER1		39
+#define SCLK_TIMER2		40
+#define SCLK_TIMER3		41
+#define SCLK_TIMER4		42
+#define SCLK_TIMER5		43
+#define SCLK_TSADC		44
+#define SCLK_SARADC		45
+#define SCLK_OTP		46
+#define SCLK_OTP_USR		47
+#define SCLK_CRYPTO		48
+#define SCLK_CRYPTO_APK		49
+#define SCLK_DDRC		50
+#define SCLK_ISP		51
+#define SCLK_CIF_OUT		52
+#define SCLK_RGA_CORE		53
+#define SCLK_VOPB_PWM		54
+#define SCLK_NANDC		55
+#define SCLK_SDIO		56
+#define SCLK_EMMC		57
+#define SCLK_SFC		58
+#define SCLK_SDMMC		59
+#define SCLK_OTG_ADP		60
+#define SCLK_GMAC_SRC		61
+#define SCLK_GMAC		62
+#define SCLK_GMAC_RX_TX		63
+#define SCLK_MAC_REF		64
+#define SCLK_MAC_REFOUT		65
+#define SCLK_MAC_OUT		66
+#define SCLK_SDMMC_DRV		67
+#define SCLK_SDMMC_SAMPLE	68
+#define SCLK_SDIO_DRV		69
+#define SCLK_SDIO_SAMPLE	70
+#define SCLK_EMMC_DRV		71
+#define SCLK_EMMC_SAMPLE	72
+#define SCLK_GPU		73
+#define SCLK_PVTM		74
+#define SCLK_CORE_VPU		75
+#define SCLK_GMAC_RMII		76
+#define SCLK_UART2_SRC		77
+#define SCLK_NANDC_DIV		78
+#define SCLK_NANDC_DIV50	79
+#define SCLK_SDIO_DIV		80
+#define SCLK_SDIO_DIV50		81
+#define SCLK_EMMC_DIV		82
+#define SCLK_EMMC_DIV50		83
+#define SCLK_DDRCLK		84
+#define SCLK_UART1_SRC		85
+
+/* dclk gates */
+#define DCLK_VOPB		150
+#define DCLK_VOPL		151
+
+/* aclk gates */
+#define ACLK_GPU		170
+#define ACLK_BUS_PRE		171
+#define ACLK_CRYPTO		172
+#define ACLK_VI_PRE		173
+#define ACLK_VO_PRE		174
+#define ACLK_VPU		175
+#define ACLK_PERI_PRE		176
+#define ACLK_GMAC		178
+#define ACLK_CIF		179
+#define ACLK_ISP		180
+#define ACLK_VOPB		181
+#define ACLK_VOPL		182
+#define ACLK_RGA		183
+#define ACLK_GIC		184
+#define ACLK_DCF		186
+#define ACLK_DMAC		187
+#define ACLK_BUS_SRC		188
+#define ACLK_PERI_SRC		189
+
+/* hclk gates */
+#define HCLK_BUS_PRE		240
+#define HCLK_CRYPTO		241
+#define HCLK_VI_PRE		242
+#define HCLK_VO_PRE		243
+#define HCLK_VPU		244
+#define HCLK_PERI_PRE		245
+#define HCLK_MMC_NAND		246
+#define HCLK_SDMMC		247
+#define HCLK_USB		248
+#define HCLK_CIF		249
+#define HCLK_ISP		250
+#define HCLK_VOPB		251
+#define HCLK_VOPL		252
+#define HCLK_RGA		253
+#define HCLK_NANDC		254
+#define HCLK_SDIO		255
+#define HCLK_EMMC		256
+#define HCLK_SFC		257
+#define HCLK_OTG		258
+#define HCLK_HOST		259
+#define HCLK_HOST_ARB		260
+#define HCLK_PDM		261
+#define HCLK_I2S0		262
+#define HCLK_I2S1		263
+#define HCLK_I2S2		264
+
+/* pclk gates */
+#define PCLK_BUS_PRE		320
+#define PCLK_DDR		321
+#define PCLK_VO_PRE		322
+#define PCLK_GMAC		323
+#define PCLK_MIPI_DSI		324
+#define PCLK_MIPIDSIPHY		325
+#define PCLK_MIPICSIPHY		326
+#define PCLK_USB_GRF		327
+#define PCLK_DCF		328
+#define PCLK_UART1		329
+#define PCLK_UART2		330
+#define PCLK_UART3		331
+#define PCLK_UART4		332
+#define PCLK_UART5		333
+#define PCLK_I2C0		334
+#define PCLK_I2C1		335
+#define PCLK_I2C2		336
+#define PCLK_I2C3		337
+#define PCLK_I2C4		338
+#define PCLK_PWM0		339
+#define PCLK_PWM1		340
+#define PCLK_SPI0		341
+#define PCLK_SPI1		342
+#define PCLK_SARADC		343
+#define PCLK_TSADC		344
+#define PCLK_TIMER		345
+#define PCLK_OTP_NS		346
+#define PCLK_WDT_NS		347
+#define PCLK_GPIO1		348
+#define PCLK_GPIO2		349
+#define PCLK_GPIO3		350
+#define PCLK_ISP		351
+#define PCLK_CIF		352
+#define PCLK_OTP_PHY		353
+
+#define CLK_NR_CLKS		(PCLK_OTP_PHY + 1)
+
+/* pmu-clocks indices */
+
+#define PLL_GPLL		1
+
+#define SCLK_RTC32K_PMU		4
+#define SCLK_WIFI_PMU		5
+#define SCLK_UART0_PMU		6
+#define SCLK_PVTM_PMU		7
+#define PCLK_PMU_PRE		8
+#define SCLK_REF24M_PMU		9
+#define SCLK_USBPHY_REF		10
+#define SCLK_MIPIDSIPHY_REF	11
+
+#define XIN24M_DIV		12
+
+#define PCLK_GPIO0_PMU		20
+#define PCLK_UART0_PMU		21
+
+#define CLKPMU_NR_CLKS		(PCLK_UART0_PMU + 1)
+
+/* soft-reset indices */
+#define SRST_CORE0_PO		0
+#define SRST_CORE1_PO		1
+#define SRST_CORE2_PO		2
+#define SRST_CORE3_PO		3
+#define SRST_CORE0		4
+#define SRST_CORE1		5
+#define SRST_CORE2		6
+#define SRST_CORE3		7
+#define SRST_CORE0_DBG		8
+#define SRST_CORE1_DBG		9
+#define SRST_CORE2_DBG		10
+#define SRST_CORE3_DBG		11
+#define SRST_TOPDBG		12
+#define SRST_CORE_NOC		13
+#define SRST_STRC_A		14
+#define SRST_L2C		15
+
+#define SRST_DAP		16
+#define SRST_CORE_PVTM		17
+#define SRST_GPU		18
+#define SRST_GPU_NIU		19
+#define SRST_UPCTL2		20
+#define SRST_UPCTL2_A		21
+#define SRST_UPCTL2_P		22
+#define SRST_MSCH		23
+#define SRST_MSCH_P		24
+#define SRST_DDRMON_P		25
+#define SRST_DDRSTDBY_P		26
+#define SRST_DDRSTDBY		27
+#define SRST_DDRGRF_p		28
+#define SRST_AXI_SPLIT_A	29
+#define SRST_AXI_CMD_A		30
+#define SRST_AXI_CMD_P		31
+
+#define SRST_DDRPHY		32
+#define SRST_DDRPHYDIV		33
+#define SRST_DDRPHY_P		34
+#define SRST_VPU_A		36
+#define SRST_VPU_NIU_A		37
+#define SRST_VPU_H		38
+#define SRST_VPU_NIU_H		39
+#define SRST_VI_NIU_A		40
+#define SRST_VI_NIU_H		41
+#define SRST_ISP_H		42
+#define SRST_ISP		43
+#define SRST_CIF_A		44
+#define SRST_CIF_H		45
+#define SRST_CIF_PCLKIN		46
+#define SRST_MIPICSIPHY_P	47
+
+#define SRST_VO_NIU_A		48
+#define SRST_VO_NIU_H		49
+#define SRST_VO_NIU_P		50
+#define SRST_VOPB_A		51
+#define SRST_VOPB_H		52
+#define SRST_VOPB		53
+#define SRST_PWM_VOPB		54
+#define SRST_VOPL_A		55
+#define SRST_VOPL_H		56
+#define SRST_VOPL		57
+#define SRST_RGA_A		58
+#define SRST_RGA_H		59
+#define SRST_RGA		60
+#define SRST_MIPIDSI_HOST_P	61
+#define SRST_MIPIDSIPHY_P	62
+#define SRST_VPU_CORE		63
+
+#define SRST_PERI_NIU_A		64
+#define SRST_USB_NIU_H		65
+#define SRST_USB2OTG_H		66
+#define SRST_USB2OTG		67
+#define SRST_USB2OTG_ADP	68
+#define SRST_USB2HOST_H		69
+#define SRST_USB2HOST_ARB_H	70
+#define SRST_USB2HOST_AUX_H	71
+#define SRST_USB2HOST_EHCI	72
+#define SRST_USB2HOST		73
+#define SRST_USBPHYPOR		74
+#define SRST_USBPHY_OTG_PORT	75
+#define SRST_USBPHY_HOST_PORT	76
+#define SRST_USBPHY_GRF		77
+#define SRST_CPU_BOOST_P	78
+#define SRST_CPU_BOOST		79
+
+#define SRST_MMC_NAND_NIU_H	80
+#define SRST_SDIO_H		81
+#define SRST_EMMC_H		82
+#define SRST_SFC_H		83
+#define SRST_SFC		84
+#define SRST_SDCARD_NIU_H	85
+#define SRST_SDMMC_H		86
+#define SRST_NANDC_H		89
+#define SRST_NANDC		90
+#define SRST_GMAC_NIU_A		92
+#define SRST_GMAC_NIU_P		93
+#define SRST_GMAC_A		94
+
+#define SRST_PMU_NIU_P		96
+#define SRST_PMU_SGRF_P		97
+#define SRST_PMU_GRF_P		98
+#define SRST_PMU		99
+#define SRST_PMU_MEM_P		100
+#define SRST_PMU_GPIO0_P	101
+#define SRST_PMU_UART0_P	102
+#define SRST_PMU_CRU_P		103
+#define SRST_PMU_PVTM		104
+#define SRST_PMU_UART		105
+#define SRST_PMU_NIU_H		106
+#define SRST_PMU_DDR_FAIL_SAVE	107
+#define SRST_PMU_CORE_PERF_A	108
+#define SRST_PMU_CORE_GRF_P	109
+#define SRST_PMU_GPU_PERF_A	110
+#define SRST_PMU_GPU_GRF_P	111
+
+#define SRST_CRYPTO_NIU_A	112
+#define SRST_CRYPTO_NIU_H	113
+#define SRST_CRYPTO_A		114
+#define SRST_CRYPTO_H		115
+#define SRST_CRYPTO		116
+#define SRST_CRYPTO_APK		117
+#define SRST_BUS_NIU_H		120
+#define SRST_USB_NIU_P		121
+#define SRST_BUS_TOP_NIU_P	122
+#define SRST_INTMEM_A		123
+#define SRST_GIC_A		124
+#define SRST_ROM_H		126
+#define SRST_DCF_A		127
+
+#define SRST_DCF_P		128
+#define SRST_PDM_H		129
+#define SRST_PDM		130
+#define SRST_I2S0_H		131
+#define SRST_I2S0_TX		132
+#define SRST_I2S1_H		133
+#define SRST_I2S1		134
+#define SRST_I2S2_H		135
+#define SRST_I2S2		136
+#define SRST_UART1_P		137
+#define SRST_UART1		138
+#define SRST_UART2_P		139
+#define SRST_UART2		140
+#define SRST_UART3_P		141
+#define SRST_UART3		142
+#define SRST_UART4_P		143
+
+#define SRST_UART4		144
+#define SRST_UART5_P		145
+#define SRST_UART5		146
+#define SRST_I2C0_P		147
+#define SRST_I2C0		148
+#define SRST_I2C1_P		149
+#define SRST_I2C1		150
+#define SRST_I2C2_P		151
+#define SRST_I2C2		152
+#define SRST_I2C3_P		153
+#define SRST_I2C3		154
+#define SRST_PWM0_P		157
+#define SRST_PWM0		158
+#define SRST_PWM1_P		159
+
+#define SRST_PWM1		160
+#define SRST_SPI0_P		161
+#define SRST_SPI0		162
+#define SRST_SPI1_P		163
+#define SRST_SPI1		164
+#define SRST_SARADC_P		165
+#define SRST_SARADC		166
+#define SRST_TSADC_P		167
+#define SRST_TSADC		168
+#define SRST_TIMER_P		169
+#define SRST_TIMER0		170
+#define SRST_TIMER1		171
+#define SRST_TIMER2		172
+#define SRST_TIMER3		173
+#define SRST_TIMER4		174
+#define SRST_TIMER5		175
+
+#define SRST_OTP_NS_P		176
+#define SRST_OTP_NS_SBPI	177
+#define SRST_OTP_NS_USR		178
+#define SRST_OTP_PHY_P		179
+#define SRST_OTP_PHY		180
+#define SRST_WDT_NS_P		181
+#define SRST_GPIO1_P		182
+#define SRST_GPIO2_P		183
+#define SRST_GPIO3_P		184
+#define SRST_SGRF_P		185
+#define SRST_GRF_P		186
+#define SRST_I2S0_RX		191
+
+#endif
-- 
1.9.1

^ permalink raw reply related

* [PATCH v1 1/4] dt-bindings: add bindings for px30 clock controller
From: Elaine Zhang @ 2018-06-07  3:06 UTC (permalink / raw)
  To: heiko
  Cc: sboyd, robh+dt, mark.rutland, mturquette, linux-clk, devicetree,
	linux-arm-kernel, linux-rockchip, linux-kernel, cl, xxx, xf,
	huangtao, Elaine Zhang
In-Reply-To: <1528340786-462-1-git-send-email-zhangqing@rock-chips.com>

Add devicetree bindings for Rockchip cru which found on
Rockchip SoCs.

Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
---
 .../bindings/clock/rockchip,px30-cru.txt           | 67 ++++++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,px30-cru.txt

diff --git a/Documentation/devicetree/bindings/clock/rockchip,px30-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,px30-cru.txt
new file mode 100644
index 000000000000..af5a45b680d0
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rockchip,px30-cru.txt
@@ -0,0 +1,67 @@
+* Rockchip PX30 Clock and Reset Unit
+
+The PX30 clock controller generates and supplies clock to various
+controllers within the SoC and also implements a reset controller for SoC
+peripherals.
+
+Required Properties:
+
+- compatible: PMU for CRU should be "rockchip,px30-pmu-cru"
+- compatible: CRU should be "rockchip,px30-cru"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- #clock-cells: should be 1.
+- #reset-cells: should be 1.
+
+Optional Properties:
+
+- rockchip,grf: phandle to the syscon managing the "general register files"
+  If missing, pll rates are not changeable, due to the missing pll lock status.
+
+Each clock is assigned an identifier and client nodes can use this identifier
+to specify the clock which they consume. All available clocks are defined as
+preprocessor macros in the dt-bindings/clock/px30-cru.h headers and can be
+used in device tree sources. Similar macros exist for the reset sources in
+these files.
+
+External clocks:
+
+There are several clocks that are generated outside the SoC. It is expected
+that they are defined using standard clock bindings with following
+clock-output-names:
+ - "xin24m" - crystal input - required,
+ - "xin32k" - rtc clock - optional,
+ - "i2sx_clkin" - external I2S clock - optional,
+ - "gmac_clkin" - external GMAC clock - optional
+
+Example: Clock controller node:
+
+	pmucru: pmu-clock-controller@ff2bc000 {
+		compatible = "rockchip,px30-pmucru";
+		reg = <0x0 0xff2bc000 0x0 0x1000>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	cru: clock-controller@ff2b0000 {
+		compatible = "rockchip,px30-cru";
+		reg = <0x0 0xff2b0000 0x0 0x1000>;
+		rockchip,grf = <&grf>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+Example: UART controller node that consumes the clock generated by the clock
+  controller:
+
+	uart0: serial@ff030000 {
+		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff030000 0x0 0x100>;
+		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&pmucru SCLK_UART0_PMU>, <&pmucru PCLK_UART0_PMU>;
+		clock-names = "baudclk", "apb_pclk";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		status = "disabled";
+	};
+
-- 
1.9.1

^ permalink raw reply related

* [PATCH v1 0/4] clk: rockchip: support clock controller for px30 SoC
From: Elaine Zhang @ 2018-06-07  3:06 UTC (permalink / raw)
  To: heiko
  Cc: sboyd, robh+dt, mark.rutland, mturquette, linux-clk, devicetree,
	linux-arm-kernel, linux-rockchip, linux-kernel, cl, xxx, xf,
	huangtao, Elaine Zhang

Elaine Zhang (4):
  dt-bindings: add bindings for px30 clock controller
  clk: rockchip: add dt-binding header for px30
  clk: rockchip: add support for half divider
  clk: rockchip: add clock controller for px30

 .../bindings/clock/rockchip,px30-cru.txt           |   67 ++
 drivers/clk/rockchip/Makefile                      |    2 +
 drivers/clk/rockchip/clk-half-divider.c            |  235 +++++
 drivers/clk/rockchip/clk-px30.c                    | 1080 ++++++++++++++++++++
 drivers/clk/rockchip/clk.c                         |   10 +
 drivers/clk/rockchip/clk.h                         |   86 +-
 include/dt-bindings/clock/px30-cru.h               |  402 ++++++++
 7 files changed, 1881 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,px30-cru.txt
 create mode 100644 drivers/clk/rockchip/clk-half-divider.c
 create mode 100644 drivers/clk/rockchip/clk-px30.c
 create mode 100644 include/dt-bindings/clock/px30-cru.h

-- 
1.9.1

^ permalink raw reply

* [GIT PULL] DeviceTree updates for 4.18
From: Rob Herring @ 2018-06-07  2:40 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Frank Rowand, Mark Rutland, devicetree,
	linux-kernel@vger.kernel.org

Hi Linus,

Please pull DT updates for 4.18. Details below.

Rob

The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:

  Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git
tags/devicetree-for-4.18

for you to fetch changes up to 44acf10587907ff77c28fd97906220b2d8eb4f05:

  dt-bindings: submitting-patches: add guidance on patch content and
subject (2018-06-05 16:37:47 -0600)

----------------------------------------------------------------
DeviceTree updates for v4.18:

- Sync dtc with upstream version v1.4.6-21-g84e414b0b5bc. This adds new
  warnings which are either fixed or disabled by default (enabled with
  W=1).

- Validate an untrusted offset in DT overlay function
  update_usages_of_a_phandle_reference

- Fix a use after free error of_platform_device_destroy

- Fix an off by 1 string errors in unittest

- Avoid creating a struct device for OPP nodes

- Update DT specific submitting-patches.txt with patch content and
  subject requirements.

- Move some bindings to their proper subsystem locations

- Add vendor prefixes for Kaohsiung, SiFive, Avnet, Wi2Wi, Logic PD, and
  ArcherMind

- Add documentation for "no-gpio-delays" property in FSI bus GPIO master

- Add compatible for r8a77990 SoC ravb ethernet block

- More wack-a-mole removal of 'status' property in examples

----------------------------------------------------------------
Benjamin Herrenschmidt (1):
      dt-bindings: fsi-master-gpio: Document "no-gpio-delays" property

Frank Rowand (2):
      MAINTAINERS: add keyword for devicetree overlay notifiers
      of: overlay: validate offset from property fixups

Geert Uytterhoeven (3):
      dt-bindings: meson-uart: DT fix s/clocks-names/clock-names/
      dt-bindings: mvebu-uart: DT fix s/interrupts-names/interrupt-names/
      dt-bindings: panel: lvds: Fix path to display timing bindings

H. Nikolaus Schaller (1):
      dt-bindings: define vendor prefix for Wi2Wi, Inc.

Jacopo Mondi (3):
      dt-bindings: net: ravb: Add support for r8a77965 SoC
      dt-bindings: serial: sh-sci: Add support for r8a77965 (H)SCIF
      dt-bindings: dmaengine: rcar-dmac: document R8A77965 support

Jan Kiszka (1):
      of: overlay: Stop leaking resources on overlay removal

Lukasz Majewski (2):
      doc: Add vendor prefix for Kieback & Peter GmbH
      doc: Add vendor prefix for Kaohsiung

Manivannan Sadhasivam (1):
      dt-bindings: Add vendor prefix for ArcherMind

Matheus Castello (1):
      dt-bindings: pinctrl: sunxi: Fix reference to driver

Michal Simek (1):
      dt-bindings: Add vendor prefix for Avnet, Inc.

Niklas Söderlund (1):
      dt-bindings: thermal: rcar-gen3-thermal: update register size in example

Rob Herring (12):
      of/numa: drop export of of_node_to_nid
      dt-bindings: more status property removal from examples
      dtc: checks: drop warning for missing PCI bridge bus-range
      dt-bindings: move various timer bindings to timer/ directory
      dt-bindings: move various RNG bindings to rng/ directory
      dt-bindings: powerpc/4xx: move 4xx NDFC and EMAC bindings to
subsystem directories
      dt-bindings: exynos: move ADC binding to iio/adc/ directory
      Merge tag 'devicetree-fixes-for-4.17' into dt/next to pick-up fixes
      scripts/dtc: Update to upstream version v1.4.6-21-g84e414b0b5bc
      kbuild: disable new dtc graph and unit-address warnings
      drm: rcar-du: disable dtc graph-endpoint warnings on DT overlays
      dt-bindings: submitting-patches: add guidance on patch content and subject

Srinivas Kandagatla (1):
      of: platform: stop accessing invalid dev in of_platform_device_destroy

Stefan M Schaeckeler (1):
      of: unittest: for strings, account for trailing \0 in property
length field

Thierry Reding (1):
      dt-bindings: Relocate Tegra20 memory controller bindings

Viresh Kumar (1):
      of: Don't create device for OPP tables

Vladimir Zapolskiy (1):
      dt-bindings: Add vendor prefix for Logic PD

Wesley W. Terpstra (1):
      dt-bindings: Add "sifive" vendor prefix

Yoshihiro Shimoda (1):
      dt-bindings: net: ravb: Add support for r8a77990 SoC

 .../devicetree/bindings/arm/ux500/boards.txt       |   2 +-
 .../bindings/display/panel/panel-common.txt        |   2 +-
 Documentation/devicetree/bindings/dma/k3dma.txt    |   1 -
 .../devicetree/bindings/dma/renesas,rcar-dmac.txt  |   1 +
 Documentation/devicetree/bindings/dma/ti-edma.txt  |   1 -
 .../devicetree/bindings/fsi/fsi-master-gpio.txt    |   4 +
 .../adc/samsung,exynos-adc.txt}                    |   0
 .../nvidia,tegra20-mc.txt                          |   0
 .../devicetree/bindings/mips/lantiq/rcu.txt        |   2 -
 Documentation/devicetree/bindings/mmc/tmio_mmc.txt |   4 -
 .../{powerpc/4xx/ndfc.txt => mtd/ibm,ndfc.txt}     |   0
 Documentation/devicetree/bindings/mtd/mtk-nand.txt |   4 -
 .../{powerpc/4xx/emac.txt => net/ibm,emac.txt}     |   0
 .../devicetree/bindings/net/renesas,ravb.txt       |   2 +
 .../devicetree/bindings/pci/xgene-pci.txt          |   7 -
 .../bindings/pinctrl/allwinner,sunxi-pinctrl.txt   |   6 +-
 Documentation/devicetree/bindings/pps/pps-gpio.txt |   1 -
 .../devicetree/bindings/pwm/pwm-omap-dmtimer.txt   |   2 +-
 .../samsung,exynos4-rng.txt}                       |   0
 .../bindings/{ => rng}/sparc_sun_oracle_rng.txt    |   0
 .../bindings/serial/amlogic,meson-uart.txt         |   2 +-
 .../devicetree/bindings/serial/mvebu-uart.txt      |   2 +-
 .../bindings/serial/renesas,sci-serial.txt         |   2 +
 .../devicetree/bindings/submitting-patches.txt     |   9 +-
 .../bindings/thermal/rcar-gen3-thermal.txt         |   6 +-
 .../{nios2/timer.txt => timer/altr,timer-1.0.txt}  |   0
 .../arch_timer.txt => timer/arm,arch_timer.txt}    |   0
 .../arm,armv7m-systick.txt}                        |   0
 .../arm,global_timer.txt}                          |   0
 .../bindings/{arm/twd.txt => timer/arm,twd.txt}    |   0
 .../{powerpc/fsl/gtm.txt => timer/fsl,gtm.txt}     |   0
 .../mrvl/timer.txt => timer/mrvl,mmp-timer.txt}    |   0
 .../msm/timer.txt => timer/qcom,msm-timer.txt}     |   0
 .../spear-timer.txt => timer/st,spear-timer.txt}   |   0
 .../{c6x/timer64.txt => timer/ti,c64x+timer64.txt} |   0
 .../{arm/omap/timer.txt => timer/ti,timer.txt}     |   0
 .../{arm/vt8500 => timer}/via,vt8500-timer.txt     |   0
 .../devicetree/bindings/vendor-prefixes.txt        |   7 +
 Documentation/devicetree/overlay-notes.txt         |   8 +
 MAINTAINERS                                        |   2 +
 drivers/gpu/drm/rcar-du/Makefile                   |   7 +
 drivers/of/of_numa.c                               |   1 -
 drivers/of/overlay.c                               |  30 ++-
 drivers/of/platform.c                              |  16 +-
 drivers/of/resolver.c                              |   5 +
 drivers/of/unittest.c                              |   8 +-
 scripts/Makefile.lib                               |   3 +
 scripts/dtc/checks.c                               | 204 ++++++++++++++++++++-
 scripts/dtc/dtc-lexer.l                            |   7 +
 scripts/dtc/dtc-parser.y                           |  39 ++--
 scripts/dtc/dtc.h                                  |   4 +
 scripts/dtc/livetree.c                             |  26 ++-
 scripts/dtc/version_gen.h                          |   2 +-
 53 files changed, 362 insertions(+), 67 deletions(-)
 rename Documentation/devicetree/bindings/{arm/samsung/exynos-adc.txt
=> iio/adc/samsung,exynos-adc.txt} (100%)
 rename Documentation/devicetree/bindings/{arm/tegra =>
memory-controllers}/nvidia,tegra20-mc.txt (100%)
 rename Documentation/devicetree/bindings/{powerpc/4xx/ndfc.txt =>
mtd/ibm,ndfc.txt} (100%)
 rename Documentation/devicetree/bindings/{powerpc/4xx/emac.txt =>
net/ibm,emac.txt} (100%)
 rename Documentation/devicetree/bindings/{crypto/samsung,exynos-rng4.txt
=> rng/samsung,exynos4-rng.txt} (100%)
 rename Documentation/devicetree/bindings/{ =>
rng}/sparc_sun_oracle_rng.txt (100%)
 rename Documentation/devicetree/bindings/{nios2/timer.txt =>
timer/altr,timer-1.0.txt} (100%)
 rename Documentation/devicetree/bindings/{arm/arch_timer.txt =>
timer/arm,arch_timer.txt} (100%)
 rename Documentation/devicetree/bindings/{arm/armv7m_systick.txt =>
timer/arm,armv7m-systick.txt} (100%)
 rename Documentation/devicetree/bindings/{arm/global_timer.txt =>
timer/arm,global_timer.txt} (100%)
 rename Documentation/devicetree/bindings/{arm/twd.txt =>
timer/arm,twd.txt} (100%)
 rename Documentation/devicetree/bindings/{powerpc/fsl/gtm.txt =>
timer/fsl,gtm.txt} (100%)
 rename Documentation/devicetree/bindings/{arm/mrvl/timer.txt =>
timer/mrvl,mmp-timer.txt} (100%)
 rename Documentation/devicetree/bindings/{arm/msm/timer.txt =>
timer/qcom,msm-timer.txt} (100%)
 rename Documentation/devicetree/bindings/{arm/spear-timer.txt =>
timer/st,spear-timer.txt} (100%)
 rename Documentation/devicetree/bindings/{c6x/timer64.txt =>
timer/ti,c64x+timer64.txt} (100%)
 rename Documentation/devicetree/bindings/{arm/omap/timer.txt =>
timer/ti,timer.txt} (100%)
 rename Documentation/devicetree/bindings/{arm/vt8500 =>
timer}/via,vt8500-timer.txt (100%)

^ permalink raw reply

* Re: [PATCH v3 2/5] gpio: syscon: rockchip: add GPIO_MUTE support for rk3328
From: Levin @ 2018-06-07  1:32 UTC (permalink / raw)
  To: Rob Herring
  Cc: open list:ARM/Rockchip SoC..., Wayne Chou, Heiko Stuebner,
	devicetree, Linus Walleij, linux-kernel@vger.kernel.org,
	open list:GPIO SUBSYSTEM, Mark Rutland,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20180605195854.GA16394@rob-hp-laptop>

Rob Herring <robh@kernel.org> writes:

> On Sat, Jun 02, 2018 at 04:40:09PM +0800, Levin Du wrote:
>> 
>> Rob Herring <robh+dt@kernel.org> writes:
>> 
>> > On Thu, May 31, 2018 at 9:05 PM, Levin <djw@t-chip.com.cn> wrote:
>> > > Hi Rob,
>> > > 
>> > > 
>> > > On 2018-05-31 10:45 PM, Rob Herring wrote:
>> > > > 
>> > > > On Wed, May 30, 2018 at 10:27 PM,  <djw@t-chip.com.cn> wrote:
>> > > > > 
>> > > > > From: Levin Du <djw@t-chip.com.cn>
>> > > > > 
>> > > > > In Rockchip RK3328, the output only GPIO_MUTE pin,
>> > > > > originally for codec
>> > > > > mute control, can also be used for general purpose. It is
>> > > > > manipulated by
>> > > > > the GRF_SOC_CON10 register.
>> > > > > 
>> > > > > Signed-off-by: Levin Du <djw@t-chip.com.cn>
>> > > > > 
>> > > > > ---
>> > > > > 
>> > > > > Changes in v3:
>> > > > > - Change from general gpio-syscon to specific
>> > > > > rk3328-gpio-mute
>> > > > > 
>> > > > > Changes in v2:
>> > > > > - Rename gpio_syscon10 to gpio_mute in doc
>> > > > > 
>> > > > > Changes in v1:
>> > > > > - Refactured for general gpio-syscon usage for Rockchip SoCs.
>> > > > > - Add doc rockchip,gpio-syscon.txt
>> > > > > 
>> > > > >   .../bindings/gpio/rockchip,rk3328-gpio-mute.txt    | 28
>> > > > > +++++++++++++++++++
>> > > > >   drivers/gpio/gpio-syscon.c                         | 31
>> > > > > ++++++++++++++++++++++
>> > > > >   2 files changed, 59 insertions(+)
>> > > > >   create mode 100644
>> > > > > Documentation/devicetree/bindings/gpio/rockchip,rk3328-gpio-mute.txt
>> > > > > 
>> > > > > diff --git
>> > > > > a/Documentation/devicetree/bindings/gpio/rockchip,rk3328-gpio-mute.txt
>> > > > > b/Documentation/devicetree/bindings/gpio/rockchip,rk3328-gpio-mute.txt
>> > > > > new file mode 100644
>> > > > > index 0000000..10bc632
>> > > > > --- /dev/null
>> > > > > +++
>> > > > > b/Documentation/devicetree/bindings/gpio/rockchip,rk3328-gpio-mute.txt
>> > > > > @@ -0,0 +1,28 @@
>> > > > > +Rockchip RK3328 GPIO controller dedicated for the GPIO_MUTE
>> > > > > pin.
>> > > > > +
>> > > > > +In Rockchip RK3328, the output only GPIO_MUTE pin,
>> > > > > originally for codec
>> > > > > mute
>> > > > > +control, can also be used for general purpose. It is
>> > > > > manipulated by the
>> > > > > +GRF_SOC_CON10 register.
>> > > > > +
>> > > > > +Required properties:
>> > > > > +- compatible: Should contain "rockchip,rk3328-gpio-mute".
>> > > > > +- gpio-controller: Marks the device node as a gpio
>> > > > > controller.
>> > > > > +- #gpio-cells: Should be 2. The first cell is the pin
>> > > > > number and
>> > > > > +  the second cell is used to specify the gpio polarity:
>> > > > > +    0 = Active high,
>> > > > > +    1 = Active low.
>> > > > > +
>> > > > > +Example:
>> > > > > +
>> > > > > +       grf: syscon@ff100000 {
>> > > > > +               compatible = "rockchip,rk3328-grf", "syscon",
>> > > > > "simple-mfd";
>> > > > > +
>> > > > > +               gpio_mute: gpio-mute {
>> > > > 
>> > > > Node names should be generic:
>> > > > 
>> > > > gpio {
>> > > > 
>> > > > This also means you can't add another GPIO node in the future
>> > > > and
>> > > > you'll have to live with "rockchip,rk3328-gpio-mute" covering
>> > > > more
>> > > > than 1 GPIO if you do need to add more GPIOs.
>> > > 
>> > > 
>> > > As the first line describes, this GPIO controller is dedicated for
>> > > the
>> > > GPIO_MUTE pin.
>> > > There's only one GPIO pin in the GRF_SOC_CON10 register. Therefore
>> > > the
>> > > gpio_mute
>> > > name is proper IMHO.
>> > 
>> > It's how many GPIOs in the GRF, not this register. What I'm saying is
>> > when you come along later to add another GPIO in the GRF, you had
>> > better just add it to this same node. I'm not going to accept another
>> > GPIO controller node within the GRF. You have the cells to support
>> > more than 1, so it would only be a driver change. The compatible
>> > string would then not be ideally named at that point. But compatible
>> > strings are just unique identifiers, so it doesn't really matter what
>> > the string is.
>> > 
>> 
>> I'll try my best to introduce the situation here. The GRF, GPIO0~GPIO3
>> are register blocks in the RK3328 Soc. The GPIO0~GPIO3 contain registers
>> for GPIO operations like reading/writing data, setting direction,
>> interruption etc, which corresponds to the GPIO banks (gpio0~gpio3)
>> defined in rk3328.dtsi:
>
> I'm only talking about GRF functions, not "regular" GPIOs.
>
>> 	pinctrl: pinctrl {
>> 		compatible = "rockchip,rk3328-pinctrl";
>> 		rockchip,grf = <&grf>;
>> 		#address-cells = <2>;
>> 		#size-cells = <2>;
>> 		ranges;
>> 
>> 		gpio0: gpio0@ff210000 {
>> 			compatible = "rockchip,gpio-bank";
>> 			reg = <0x0 0xff210000 0x0 0x100>;
>> 			interrupts = <GIC_SPI 51 			IRQ_TYPE_LEVEL_HIGH>;
>> 			clocks = <&cru PCLK_GPIO0>;
>> 
>> 			gpio-controller;
>> 			#gpio-cells = <2>;
>> 
>> 			interrupt-controller;
>> 			#interrupt-cells = <2>;
>> 		};
>> 
>> 		gpio1: gpio1@ff220000 {
>>                //...
>> 		};
>> 
>> 		gpio2: gpio2@ff230000 {
>>                //...
>> 		};
>> 
>> 		gpio3: gpio3@ff240000 {
>>                //...
>> 		};
>>         }
>> 
>> However, these general GPIO pins has multiplexed functions and their
>> pull up/down and driving strength can also be configured. These settings
>> are manipulated by the GRF registers in pinctrl driver. Quoted from the
>> TRM, the GRF has the following function:
>> 
>> - IOMUX control
>> - Control the state of GPIO in power-down mode
>> - GPIO PAD pull down and pull up control
>> - Used for common system control
>> - Used to record the system state
>> 
>> Therefore the functions of the GRF are messy and scattered in different
>> nodes. The so-called GPIO_MUTE does not belong to GPIO0~GPIO3. It is
>> manipulated by the GRF_SOC_CON10 register in the GRF block.
>> 
>> > I'm being told both "this is the only GPIO" and "the GRF has too many
>> > different functions for us to tell you what they all are". So which is
>> > it?
>> > 
>> > Rob
>> 
>> They are both true, but lack of context. See the above description.
>
> What I meant was "only GPIO in GRF registers"...
>
> Rob

I check the TRM and schematic once again. In GRF resters, there are also
HDMI GPIOs, which are already covered by the HDMI driver. Aside from
those, MUTE_GPIO is the only GPIO.

Levin

^ permalink raw reply

* Re: [PATCH v3 1/2] power: supply: sbs-battery: don't assume MANUFACTURER_DATA formats
From: Brian Norris @ 2018-06-07  1:09 UTC (permalink / raw)
  To: Phil Reid
  Cc: Sebastian Reichel, linux-kernel, Rob Herring, linux-pm,
	devicetree, Rhyland Klein, Alexandru Stan, Guenter Roeck,
	Doug Anderson
In-Reply-To: <7cbe27cf-2917-a17b-07bf-e5fdeb5fef15@electromag.com.au>

Hi Phil,

On Wed, Jun 06, 2018 at 10:03:59AM +0800, Phil Reid wrote:
> On 2/06/2018 09:28, Brian Norris wrote:
> >   drivers/power/supply/sbs-battery.c | 54 +++++++++++++++++++++++++-----
> >   1 file changed, 46 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c
> > index 83d7b4115857..a9691ea42f44 100644
> > --- a/drivers/power/supply/sbs-battery.c
> > +++ b/drivers/power/supply/sbs-battery.c

...

> > @@ -806,6 +837,7 @@ static int sbs_probe(struct i2c_client *client,
> >   	if (!chip)
> >   		return -ENOMEM;
> > +	chip->flags = (u32)(uintptr_t)of_device_get_match_data(&client->dev);
> >   	chip->client = client;
> >   	chip->enable_detection = false;
> >   	psy_cfg.of_node = client->dev.of_node;
> > @@ -915,12 +947,15 @@ static int sbs_suspend(struct device *dev)
> >   	if (chip->poll_time > 0)
> >   		cancel_delayed_work_sync(&chip->work);
> > -	/*
> > -	 * Write to manufacturer access with sleep command.
> > -	 * Support is manufacturer dependend, so ignore errors.
> > -	 */
> > -	sbs_write_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr,
> > -		MANUFACTURER_ACCESS_SLEEP);
> > +	if (chip->flags & SBS_FLAGS_TI_BQ20Z75) {
> > +		/*
> > +		 * Write to manufacturer access with sleep command.
> > +		 * Support is manufacturer dependent, so ignore errors.
> > +		 */
> > +		sbs_write_word_data(client,
> > +				    sbs_data[REG_MANUFACTURER_DATA].addr,
> > +				    MANUFACTURER_ACCESS_SLEEP);
> > +	}
> 
> Now that this is only being done for only TI devices that support this I would think the comment
> about ignoring errors needs to go, and errors checks added.
> Ditto in the new sbs_get_ti_battery_presence_and_health()

Seems reasonable. I'll look at doing that and respinning.

> >   	return 0;
> >   }

Thanks,
Brian

^ permalink raw reply

* RE: [PATCH v6 00/15] staging: typec: tcpci: move out of staging
From: Jun Li @ 2018-06-07  0:47 UTC (permalink / raw)
  To: Mats Karrman, robh+dt@kernel.org, gregkh@linuxfoundation.org,
	heikki.krogerus@linux.intel.com, linux@roeck-us.net
  Cc: cw00.choi@samsung.com, a.hajda@samsung.com,
	shufan_lee@richtek.com, Peter Chen, garsilva@embeddedor.com,
	gsomlo@gmail.com, linux-usb@vger.kernel.org,
	devicetree@vger.kernel.org, dl-linux-imx
In-Reply-To: <1ce9509d-8b41-0b66-40d8-2d7badc972eb@gmail.com>

Hi Mats,
> -----Original Message-----
> From: Mats Karrman [mailto:mats.dev.list@gmail.com]
> Sent: 2018年6月7日 5:45
> To: Jun Li <jun.li@nxp.com>; robh+dt@kernel.org; gregkh@linuxfoundation.org;
> heikki.krogerus@linux.intel.com; linux@roeck-us.net
> Cc: cw00.choi@samsung.com; a.hajda@samsung.com; shufan_lee@richtek.com;
> Peter Chen <peter.chen@nxp.com>; garsilva@embeddedor.com;
> gsomlo@gmail.com; linux-usb@vger.kernel.org; devicetree@vger.kernel.org;
> dl-linux-imx <linux-imx@nxp.com>
> Subject: Re: [PATCH v6 00/15] staging: typec: tcpci: move out of staging
> 
> Hello Li Jun,
> 
> I have been testing these patches on top of usb-next using an i.MX6, a nxp
> ptn5110 evaluation board and a bunch of usbc devices. So far everything seem to
> work fine! :-) However, I have only tested host mode and I have some test cases
> left I want to cover.
> 
> Just to let you know your patches are not forgotten :-)

Good to know that, thanks, Mats, those patches was tested on my i.MX8M
HW with PTN5110 for both source and sink mode, hope you can test your
device mode as well soon.

Li Jun

^ permalink raw reply

* Re: [PATCH v4 0/6] Enhance support for the SP805 WDT
From: Ray Jui @ 2018-06-06 23:40 UTC (permalink / raw)
  To: Florian Fainelli, Wim Van Sebroeck, Guenter Roeck, Rob Herring,
	Mark Rutland, Frank Rowand, Catalin Marinas, Will Deacon,
	Robin Murphy
  Cc: linux-watchdog, devicetree, linux-arm-kernel, linux-kernel,
	bcm-kernel-feedback-list
In-Reply-To: <e3f657f1-bd7e-cadb-9cfe-dee6cf8c1668@gmail.com>

Hi Florian,

On 6/6/2018 12:29 PM, Florian Fainelli wrote:
> On 05/28/2018 11:01 AM, Ray Jui wrote:
>> This patch series enhances the support for the SP805 watchdog timer.
>> First of all, 'timeout-sec' devicetree property is added. In addition,
>> support is also added to allow the driver to reset the watchdog if it
>> has been detected that watchdot has been started in the bootloader. In
>> this case, the driver will initiate the ping service from the kernel
>> watchdog subsystem, before a user mode daemon takes over. This series
>> also enables SP805 in the default ARM64 defconfig
>>
>> This patch series is based off v4.17-rc5 and is available on GIHUB:
>> repo: https://github.com/Broadcom/arm64-linux.git
>> branch: sp805-wdt-v4
>>
>> Changes since v3:
>>   - Improve description of 'timeout-sec' in the binding document, per
>> recommendation from Guenter Roeck
>>
>> Changes since v2:
>>   - Fix indent and format to make them consistent within arm,sp805.txt
>>
>> Changes since v1:
>>   - Consolidate two duplicated SP805 binding documents into one
>>   - Slight change of the wdt_is_running implementation per discussion
>>
>> Ray Jui (6):
>>    Documentation: DT: Consolidate SP805 binding docs
>>    Documentation: DT: Add optional 'timeout-sec' property for sp805
>>    watchdog: sp805: add 'timeout-sec' DT property support
>>    watchdog: sp805: set WDOG_HW_RUNNING when appropriate
>>    arm64: dt: set initial SR watchdog timeout to 60 seconds
>>    arm64: defconfig: add CONFIG_ARM_SP805_WATCHDOG
> 
> I can take the last two patches and Guenter would take the first 4 or
> would you want to proceed differently?
> 

It looks like we still need to figure out how to proceed based on 
discussions with Rob and Guenter on 1/6?

Thanks,

Ray

^ permalink raw reply

* Re: [PATCH v4 1/6] Documentation: DT: Consolidate SP805 binding docs
From: Ray Jui @ 2018-06-06 23:39 UTC (permalink / raw)
  To: Rob Herring, Guenter Roeck
  Cc: Wim Van Sebroeck, Mark Rutland, Frank Rowand, Catalin Marinas,
	Will Deacon, Robin Murphy, linux-watchdog, devicetree,
	linux-arm-kernel, Linux Kernel Mailing List, BCM Kernel Feedback
In-Reply-To: <CABGGisxEvWDy16SKE2RG-vhUHBZHSCCHyfwJsPY16B1fQS-=cA@mail.gmail.com>



On 6/6/2018 9:33 AM, Rob Herring wrote:
> On Wed, Jun 6, 2018 at 11:19 AM, Guenter Roeck <linux@roeck-us.net> wrote:
>> On 06/05/2018 12:41 PM, Rob Herring wrote:
>>>
>>> On Mon, May 28, 2018 at 11:01:32AM -0700, Ray Jui wrote:
>>>>
>>>> Consolidate two SP805 binding documents "arm,sp805.txt" and
>>>> "sp805-wdt.txt" into "arm,sp805.txt" that matches the naming of the
>>>> desired compatible string to be used
>>>>
>>>> Signed-off-by: Ray Jui <ray.jui@broadcom.com>
>>>> ---
>>>>    .../devicetree/bindings/watchdog/arm,sp805.txt     | 27
>>>> ++++++++++++++-----
>>>>    .../devicetree/bindings/watchdog/sp805-wdt.txt     | 31
>>>> ----------------------
>>>>    2 files changed, 20 insertions(+), 38 deletions(-)
>>>>    delete mode 100644
>>>> Documentation/devicetree/bindings/watchdog/sp805-wdt.txt
>>>
>>>
>>> Would be good to get a ACK from FSL/NXP person on this. It looks to me
>>> like the driver fetches the wrong clock as it gets the first one and the
>>> driver really wants 'wdog_clk'. In any case, their dts files should be
>>> updated.
>>>
>>
>> This is really confusing, since he deleted file lists apb_pclk first.
>> Does the watchdog driver need apb_pclk or wdog_clk ? That isn't clear to me.
>> arch/arm64/boot/dts/hisilicon/hi3660.dtsi only provides apb_pclk, or at
>> least
>> it says so.
> 
> Note that that clock source is 32KHz. That is obviously a mistake
> because no one clocks their bus/register interface at 32KHz. Someone
> just filled in something that happened to work.
> 
>> The fsl dts files all have apb_pclk first.
> 
> It's all kind of a mess, but fortunately one we should be able to clean-up.
> 

It is indeed a mess. Note the SP805 driver only derive one clock from 
DT, and that's not done based on name. As a result, the first clock 
defined in DT will be fetched and the rate calculation will be carried 
out based on that clock rate.

I assumed the clock entries and their names defined in the binding 
document are just placeholders, at least for the 2nd clock.

Based on how the current driver is, the first clock needs to be the 
WDOGCLK for things to work properly.

According to the SP805 TRM, APB clock is the PCLK, that drives the bus 
for register access.

The relationship between WDOGCLK and PCLK is defined as:

- the rising edges of WDOGCLK must be synchronous and
balanced with a rising edge of PCLK

- the WDOGCLK frequency cannot be greater than the PCLK
frequency

> The compatible string changes too, but AMBA bus devices don't actually
> use the compatible string as they use the ID registers to match. I
> suppose some other OS could do things differently. Worth the risk to
> clean-up IMO.
> 
>>
>> Either case, why are two clocks asked for in the first place ? Are there
>> situations where the second clock is actually used/useful ?
> 
> For clocks, the bus needs "apb_pclk" and the driver just gets the
> first clock. The driver is obviously going to want the functional
> clock that determines the counter rate. That should
> 
> Primecell peripherals are about the only ones that have clear specs
> WRT clock inputs. Yet we've still managed to screw them up. There are
> 2 clocks in the spec, so the DT has (or should have) 2 clocks.
> 
> Rob
> 

Let me know how you guys want to proceed with this?

Thanks,

Ray

^ permalink raw reply

* Re: [RFC v2 2/2] dt-bindings: mipi-dsi: Add dual-channel DSI related info
From: Heiko Stuebner @ 2018-06-06 23:08 UTC (permalink / raw)
  To: Archit Taneja
  Cc: devicetree, boris.brezillon, linux-arm-msm, tomi.valkeinen,
	briannorris, philippe.cornu, dri-devel, nickey.yang, robh+dt,
	thierry.reding, laurent.pinchart, maxime.ripard
In-Reply-To: <54f4e580-3337-58d6-9458-2f4045c22fd7@codeaurora.org>

Am Mittwoch, 6. Juni 2018, 18:07:46 CEST schrieb Archit Taneja:
> 
> On Wednesday 06 June 2018 04:16 PM, Heiko Stübner wrote:
> > Hi Archit,
> > 
> > Am Mittwoch, 6. Juni 2018, 12:21:16 CEST schrieb Archit Taneja:
> >> On Wednesday 06 June 2018 02:00 PM, Heiko Stübner wrote:
> >>> Am Mittwoch, 6. Juni 2018, 07:59:29 CEST schrieb Archit Taneja:
> >>>> On Monday 04 June 2018 05:47 PM, Heiko Stuebner wrote:
> >>>>> Am Donnerstag, 18. Januar 2018, 05:53:55 CEST schrieb Archit Taneja:
> >>>>>> Add binding info for peripherals that support dual-channel DSI. Add
> >>>>>> corresponding optional bindings for DSI host controllers that may
> >>>>>> be configured in this mode. Add an example of an I2C controlled
> >>>>>> device operating in dual-channel DSI mode.
> >>>>>>
> >>>>>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> >>>>>
> >>>>> Looks like a great solution for that problem, so
> >>>>> Reviewed-by: Heiko Stuebner <heiko@sntech.de>
> >>>>>
> >>>>> As I'm looking into that for my rk3399-scarlet device right now and
> >>>>> couldn't find this patchset in the kernel yet, is it planned to
> >>>>> merge or refresh these binding changes or were problems encountered.
> >>>>>
> >>>>> At least an Ack/Review from Rob seems to be missing.
> >>>>
> >>>> I forgot about these patches. Rob had reviewed the first one in
> >>>> the set the second one still needed an Ack. I'll post a v3
> >>>> that adds the Reviewed-bys and fixes a small typo.
> >>>
> >>> very nice ... because it looks like yesterday I managed to make the
> >>> Rockchip dsi work in dual mode following this.
> >>>
> >>> But one question came up, do you really want two input ports on the panel
> >>> side? I.e. hardware-wise, I guess the panel will have one 8-lane or so
> >>> input thatonly gets split up on the soc side onto 2 dsi controllers?
> >>
> >> I think all dual DSI panels actually have 2 DSI controllers/parsers
> >> within them, one on each port. The MIPI DSI spec doesn't support 8
> >> lanes. Also, the pixels coming out of the host are distributed among
> >> the lanes differently than what would have been the case with a
> >> 'theoretical' 8 lane receiver.
> >>
> >> Other than that, some dual DSI panels only accept DSI commands on the
> >> 'master' port, where as others expect the same command to be sent across
> >> both the ports.
> >>
> >> Therefore, I think it's better to represent dual DSI panels having 2
> >> DSI input ports.
> >>
> >> Your DT looks good to me.
> > 
> > Hmm, that doesn't match up then ;-) ... as my dt uses 2 endpoints
> > in one port for the dsi-links.
> > 
> 
> Sorry, I didn't notice you'd created two endpoints within a single port.
> 
> I don't think I'm particular about 2 ports vs 1 port with 2 endpoints.
> They both seem okay to me as long as we follow it consistently. I'm
> myself not 100% sure of how to figure where one should prefer endpoints
> over ports. Maybe someone more familiar with the of graph bindings
> could comment here.
> 
> 
> > The issue I see with using ports and not endpoints for dual-dsi links
> > is with distinguishing between input and output ports.
> > 
> > For a panel that's easy, as you every port will be an input port and if
> > you have 2, it's supposed dual-dsi. But for example I guess there might
> > exist some dual-dsi-to-something bridges, where you would end up
> > with say 3 (or even more) ports ... two dual-dsi inputs and 1 or more
> > outputs.
> 
> Okay, I get your point here. Although, even if the remote device had
> exactly 2 ports. Is it safe to assume that port #0 is an input port and
> port #1 is an output port? Is that the norm?

I don't think that anything like that is specified anywhere, so you cannot
assume anything about what a port contains.


> I've at least seen one device (toshiba,tc358767 bridge) that can 
> actually take either DPI as input or DSI based on how you configure it.
> There are 2 input ports here, port #0 for DSI and port #1 for DPI. Would
> it have made sense here to have a single port and 2 endpoints here too?

Nope, I guess having a port for DPI input, one port for DSI input makes
quite a lot of sense. And then you can have the input-specifics living in
the endpoints like dual links or so.


> > While the following argument might not be 100% valid from a dt-purity
> > standpoint implementing this might get hairy for _any_ operating system,
> > as you will need each panel/bridge to tell what the ports are used for.
> 
> Yeah.
> 
> > 
> > I.e. in my endpoint based mapping, right now I have this nice and generic
> > WIP function to parse the of_graph and get the master+slave nodes:
> > 
> > https://github.com/mmind/linux-rockchip/blob/tmp/rk3399-gru-bob-scarlet/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c#L697
> > [0]
> 
> I'd tried out something locally before posting this patch, I don't have
> the code for it, but I can describe the steps I took. This code expects
> the panel/bridge to have 2 input ports.

Which again would be very much panel-specific as you cannot assume
to much about the ports.


> 1. DSI0 host driver looks up its output port, gets the remote endpoint,
> and get this endpoint's parent (using
> of_graph_get_remote_port_parent()). Keeps the parent device node in a
> temp variable.
> 
> 2. DSI1 host driver does the same thing.
> 
> 3. DSI0 and DSI1 check whether their outputs are connected to the
> same device. If so, they're in dual DSI mode. If not, they are
> operating independently.
> 
> The positive of this approach is that we don't need to make any
> assumptions about the panel/bridge's port numbers, which is great.
> The negative is that our DSI controller instances now need to query
> each other, which can be messy, but not too hard to implement.
> 
> I think the choice finally boils down to what makes more sense w.r.t
> representing the HW correctly. We'd need Rob's comment on that.

Taking your DPI+DSI example from above actually shows quite nicely
how ports+endpoints could play together.

panel-or-bridge@0 {
	compatible = "something,something";
	reg = <0>;

	ports {
		/* DPI input */
		port@0 {
			endpoint {
				remote-endpoint = <&dpi_out>;
			};
		};

		/* DSI input */
		port@1 {
			/* from first dsi controller */
			endpoint@0 {
				remote-endpoint = <&dsi0_out>;
			};

			/* from second dsi controller */
			endpoint@1 {
				remote-endpoint = <&dsi1_out>;
			};
		};

		/* another input, or an output for a bridge */
		port@2 {
			endpoint {
				remote-endpoint = <&somewhere>;
			}
		};
	};
};

But yeah, hopefully we can entice Rob for comments :-) .

Heiko

> Thanks,
> Archit
> 
> > 
> > So I guess my proposal would be to have one port for inputs
> > and one port for outputs for dsi peripherals, with possibly
> > multiple endpoints in each.
> > 
> > 
> > Heiko
> > 
> > 
> > [0] github seems to have reliability problems, so for reference my
> > parsing function:
> > 
> > static int dw_mipi_dsi_is_dual(struct dw_mipi_dsi_rockchip *dsi,
> > 			struct device_node **master, struct device_node **slave)
> > {
> > 	struct device_node *local_ep, *remote_port, *ep;
> > 	struct device_node *ctrls[2] = { NULL, NULL };
> > 	int num = 0, ret = 0, idx;
> > 
> > 	/* get local panel endpoint of the dsi controller */
> > 	local_ep = of_graph_get_endpoint_by_regs(dsi->dev->of_node, 1, 0);
> > 	if (!local_ep) {
> > 		DRM_DEV_ERROR(dsi->dev, "couldn't find local panel endpoint\n");
> > 		return -ENXIO;
> > 	}
> > 
> > 	/* get panel port */
> > 	remote_port = of_graph_get_remote_port_parent(local_ep);
> > 	of_node_put(local_ep);
> > 	if (!remote_port) {
> > 		DRM_DEV_ERROR(dsi->dev, "couldn't find panel port\n");
> > 		return -ENXIO;
> > 	}
> > 
> > 	/* check other endpoints */
> > 	for_each_endpoint_of_node(remote_port, ep) {
> > 		struct device_node *np = of_graph_get_remote_port_parent(ep);
> > 
> > 		if (!np)
> > 			continue;
> > 
> > 		idx = of_property_read_bool(np, "clock-master");
> > 
> > 		/*
> > 		 * Either master or slave already defined, drop refcnt
> > 		 * but catch errors only after the full loop.
> > 		 */
> > 		if (ctrls[idx])
> > 			of_node_put(np);
> > 		else
> > 			ctrls[idx] = np;
> > 
> > 		num++;
> > 	}
> > 	of_node_put(remote_port);
> > 
> > 	if (num > 2) {
> > 		DRM_DEV_ERROR(dsi->dev, "too many dsi devices linked\n");
> > 		ret = -EINVAL;
> > 		goto cleanup;
> > 	}
> > 
> > 	/* nothing to do */
> > 	if (num < 1) {
> > 		ret = 0;
> > 		goto cleanup;
> > 	}
> > 
> > 	if (!ctrls[1]) {
> > 		DRM_DEV_ERROR(dsi->dev, "no master defined in dual-dsi\n");
> > 		ret = -ENODEV;
> > 		goto cleanup;
> > 	}
> > 
> > 	if (!ctrls[0]) {
> > 		DRM_DEV_ERROR(dsi->dev, "no slave defined in dual-dsi\n");
> > 		ret = -ENODEV;
> > 		goto cleanup;
> > 	}
> > 
> > 	*master = ctrls[1];
> > 	*slave = ctrls[0];
> > 
> > 	return 1;
> > 
> > cleanup:
> > 	for (idx = 0; idx < 2; idx++)
> > 		if (ctrls[idx])
> > 			of_node_put(ctrls[idx]);
> > 	return ret;
> > }
> > 
> >>> So right now I'm operating with a devicetree like
> >>>
> >>> &mipi_dsi {
> >>>
> >>>           status = "okay";
> >>>           clock-master;
> >>>           
> >>>           ports {
> >>>           
> >>>                   mipi_out: port@1 {
> >>>                   
> >>>                           reg = <1>;
> >>>                           
> >>>                           mipi_out_panel: endpoint {
> >>>                           
> >>>                                   remote-endpoint = <&mipi_in_panel>;
> >>>                           
> >>>                           };
> >>>                   
> >>>                   };
> >>>           
> >>>           };
> >>>           
> >>>           mipi_panel: panel@0 {
> >>> 		
> >>> 		  compatible = "innolux,p097pfg";
> >>> 		
> >>>                   reg = <0>;
> >>>                   backlight = <&backlight>;
> >>>                   enable-gpios = <&gpio4 25 GPIO_ACTIVE_HIGH>;
> >>>                   pinctrl-names = "default";
> >>>                   pinctrl-0 = <&display_rst_l>;
> >>>                   
> >>>                   port {
> >>>                   
> >>>                           #address-cells = <1>;
> >>>                           #size-cells = <0>;
> >>>                           
> >>>                           mipi_in_panel: endpoint@0 {
> >>>                           
> >>>                                   reg = <0>;
> >>>                                   remote-endpoint = <&mipi_out_panel>;
> >>>                           
> >>>                           };
> >>>                           
> >>>                           mipi1_in_panel: endpoint@1 {
> >>>                           
> >>>                                   reg = <1>;
> >>>                                   remote-endpoint = <&mipi1_out_panel>;
> >>>                           
> >>>                           };
> >>>                   
> >>>                   };
> >>>           
> >>>           };
> >>>
> >>> };
> >>>
> >>> &mipi_dsi1 {
> >>>
> >>>           status = "okay";
> >>>           
> >>>           ports {
> >>>           
> >>>                   mipi1_out: port@1 {
> >>>                   
> >>>                           reg = <1>;
> >>>                           
> >>>                           mipi1_out_panel: endpoint {
> >>>                           
> >>>                                   remote-endpoint = <&mipi1_in_panel>;
> >>>                           
> >>>                           };
> >>>                   
> >>>                   };
> >>>           
> >>>           };
> >>>
> >>> };
> >>>
> >>>
> >>> I guess it is a matter of preference on what reflects the hardware
> >>> best, so maybe that's Robs call?
> >>>
> >>>
> >>> Heiko
> >>>
> >>>>>> ---
> >>>>>> v2:
> >>>>>> - Specify that clock-master is a boolean property.
> >>>>>> - Drop/add unit-address and #*-cells where applicable.
> >>>>>>
> >>>>>>     .../devicetree/bindings/display/mipi-dsi-bus.txt   | 80
> >>>>>>     ++++++++++++++++++++++ 1 file changed, 80 insertions(+)
> >>>>>>
> >>>>>> diff --git a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> >>>>>> b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt index
> >>>>>> 94fb72cb916f..7a3abbedb3fa 100644
> >>>>>> --- a/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> >>>>>> +++ b/Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
> >>>>>>
> >>>>>> @@ -29,6 +29,13 @@ Required properties:
> >>>>>>     - #size-cells: Should be 0. There are cases where it makes sense to
> >>>>>>     use
> >>>>>>     a
> >>>>>>     
> >>>>>>       different value here. See below.
> >>>>>>
> >>>>>> +Optional properties:
> >>>>>> +- clock-master: boolean. Should be enabled if the host is being used
> >>>>>> in
> >>>>>> +  conjunction with another DSI host to drive the same peripheral.
> >>>>>> Hardware
> >>>>>> +  supporting such a configuration generally requires the data on both
> >>>>>> the busses +  to be driven by the same clock. Only the DSI host
> >>>>>> instance
> >>>>>> controlling this +  clock should contain this property.
> >>>>>> +
> >>>>>>
> >>>>>>     DSI peripheral
> >>>>>>     ==============
> >>>>>>
> >>>>>> @@ -62,6 +69,16 @@ primary control bus, but are also connected to a DSI
> >>>>>> bus (mostly for the data>>
> >>>>>>
> >>>>>>     path). Connections between such peripherals and a DSI host can be
> >>>>>>     represented using the graph bindings [1], [2].
> >>>>>>
> >>>>>> +Peripherals that support dual channel DSI
> >>>>>> +-----------------------------------------
> >>>>>> +
> >>>>>> +Peripherals with higher bandwidth requirements can be connected to 2
> >>>>>> DSI
> >>>>>> +busses. Each DSI bus/channel drives some portion of the pixel data
> >>>>>> (generally +left/right half of each line of the display, or even/odd
> >>>>>> lines of the display). +The graph bindings should be used to represent
> >>>>>> the multiple DSI busses that are +connected to this peripheral. Each
> >>>>>> DSI
> >>>>>> host's output endpoint can be linked to +an input endpoint of the DSI
> >>>>>> peripheral.
> >>>>>> +
> >>>>>>
> >>>>>>     [1] Documentation/devicetree/bindings/graph.txt
> >>>>>>     [2] Documentation/devicetree/bindings/media/video-interfaces.txt
> >>>>>>
> >>>>>> @@ -71,6 +88,8 @@ Examples
> >>>>>>
> >>>>>>       with different virtual channel configurations.
> >>>>>>     
> >>>>>>     - (4) is an example of a peripheral on a I2C control bus connected
> >>>>>>     with
> >>>>>>     to
> >>>>>>     
> >>>>>>       a DSI host using of-graph bindings.
> >>>>>>
> >>>>>> +- (5) is an example of 2 DSI hosts driving a dual-channel DSI
> >>>>>> peripheral,
> >>>>>> +  which uses I2C as its primary control bus.
> >>>>>>
> >>>>>>     1)
> >>>>>>     
> >>>>>>     	dsi-host {
> >>>>>>
> >>>>>> @@ -153,3 +172,64 @@ Examples
> >>>>>>
> >>>>>>     			};
> >>>>>>     		
> >>>>>>     		};
> >>>>>>     	
> >>>>>>     	};
> >>>>>>
> >>>>>> +
> >>>>>> +5)
> >>>>>> +	i2c-host {
> >>>>>> +		dsi-bridge@35 {
> >>>>>> +			compatible = "...";
> >>>>>> +			reg = <0x35>;
> >>>>>> +
> >>>>>> +			ports {
> >>>>>> +				#address-cells = <1>;
> >>>>>> +				#size-cells = <0>;
> >>>>>> +
> >>>>>> +				port@0 {
> >>>>>> +					reg = <0>;
> >>>>>> +					dsi0_in: endpoint {
> >>>>>> +						remote-endpoint = <&dsi0_out>;
> >>>>>> +					};
> >>>>>> +				};
> >>>>>> +
> >>>>>> +				port@1 {
> >>>>>> +					reg = <1>;
> >>>>>> +					dsi1_in: endpoint {
> >>>>>> +						remote-endpoint = <&dsi1_out>;
> >>>>>> +					};
> >>>>>> +				};
> >>>>>> +			};
> >>>>>> +		};
> >>>>>> +	};
> >>>>>> +
> >>>>>> +	dsi0-host {
> >>>>>> +		...
> >>>>>> +
> >>>>>> +		/*
> >>>>>> +		 * this DSI instance drives the clock for both the host
> >>>>>> +		 * controllers
> >>>>>> +		 */
> >>>>>> +		clock-master;
> >>>>>> +
> >>>>>> +		ports {
> >>>>>> +			...
> >>>>>> +
> >>>>>> +			port {
> >>>>>> +				dsi0_out: endpoint {
> >>>>>> +					remote-endpoint = <&dsi0_in>;
> >>>>>> +				};
> >>>>>> +			};
> >>>>>> +		};
> >>>>>> +	};
> >>>>>> +
> >>>>>> +	dsi1-host {
> >>>>>> +		...
> >>>>>> +
> >>>>>> +		ports {
> >>>>>> +			...
> >>>>>> +
> >>>>>> +			port {
> >>>>>> +				dsi1_out: endpoint {
> >>>>>> +					remote-endpoint = <&dsi1_in>;
> >>>>>> +				};
> >>>>>> +			};
> >>>>>> +		};
> >>>>>> +	};
> >>>>>
> >>>>> --
> >>>>> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm"
> >>>>> in
> >>>>> the body of a message to majordomo@vger.kernel.org
> >>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > 
> > 
> > 
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > 
> 
> 




_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: [PATCH v6 1/2] regulator: dt-bindings: add QCOM RPMh regulator bindings
From: Doug Anderson @ 2018-06-06 22:59 UTC (permalink / raw)
  To: David Collins
  Cc: Mark Brown, Liam Girdwood, Rob Herring, Mark Rutland,
	linux-arm-msm, Linux ARM, devicetree, LKML, Rajendra Nayak,
	Stephen Boyd
In-Reply-To: <38cb1906c96504f74517018ca4e0aed63bb77356.1528138319.git.collinsd@codeaurora.org>

Hi,

On Mon, Jun 4, 2018 at 12:15 PM, David Collins <collinsd@codeaurora.org> wrote:
> Introduce bindings for RPMh regulator devices found on some
> Qualcomm Technlogies, Inc. SoCs.  These devices allow a given
> processor within the SoC to make PMIC regulator requests which
> are aggregated within the RPMh hardware block along with requests
> from other processors in the SoC to determine the final PMIC
> regulator hardware state.
>
> Signed-off-by: David Collins <collinsd@codeaurora.org>
> Reviewed-by: Rob Herring <robh@kernel.org>
> ---
>  .../bindings/regulator/qcom,rpmh-regulator.txt     | 160 +++++++++++++++++++++
>  .../dt-bindings/regulator/qcom,rpmh-regulator.h    |  36 +++++
>  2 files changed, 196 insertions(+)

Reviewed-by: Douglas Anderson <dianders@chromium.org>

^ permalink raw reply

* Re: [PATCH v6 2/2] regulator: add QCOM RPMh regulator driver
From: Doug Anderson @ 2018-06-06 22:58 UTC (permalink / raw)
  To: David Collins
  Cc: Mark Brown, Liam Girdwood, Rob Herring, Mark Rutland,
	linux-arm-msm, Linux ARM, devicetree, LKML, Rajendra Nayak,
	Stephen Boyd, Andy Gross, Bjorn Andersson
In-Reply-To: <6d7abf248493cf81d62eb17ecb5030783aa85f72.1528138319.git.collinsd@codeaurora.org>

Hi,

On Mon, Jun 4, 2018 at 12:15 PM, David Collins <collinsd@codeaurora.org> wrote:
> Add the QCOM RPMh regulator driver to manage PMIC regulators
> which are controlled via RPMh on some Qualcomm Technologies, Inc.
> SoCs.  RPMh is a hardware block which contains several
> accelerators which are used to manage various hardware resources
> that are shared between the processors of the SoC.  The final
> hardware state of a regulator is determined within RPMh by
> performing max aggregation of the requests made by all of the
> processors.
>
> Add support for PMIC regulator control via the voltage regulator
> manager (VRM) and oscillator buffer (XOB) RPMh accelerators.
> VRM supports manipulation of enable state, voltage, and mode.
> XOB supports manipulation of enable state.
>
> Signed-off-by: David Collins <collinsd@codeaurora.org>
> ---
>  drivers/regulator/Kconfig               |   9 +
>  drivers/regulator/Makefile              |   1 +
>  drivers/regulator/qcom-rpmh-regulator.c | 767 ++++++++++++++++++++++++++++++++
>  3 files changed, 777 insertions(+)

Assuming Mark is OK with this, it looks good to me now.  My previous
feedback is resolved and I'm OK with the hardcoded current loads in
the driver for now until we come up with something better.

Reviewed-by: Douglas Anderson <dianders@chromium.org>

NOTE: Presumably this can't actually land anywhere :( until the RPMh
patchset lands somewhere and that's still sitting in limbo waiting for
Qualcomm to spin the patches.  Presumably once RPMh lands someone will
need to put it somewhere that can be pulled into the relevant trees so
we don't need to wait for a whole merge window...


-Doug

^ permalink raw reply

* Re: [PATCH 06/15] drm/sun4i: tcon: Add support for tcon-top
From: Jernej Škrabec @ 2018-06-06 22:30 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, Rob Herring, Mark Rutland, dri-devel, devicetree,
	linux-arm-kernel, linux-kernel, linux-clk, linux-sunxi
In-Reply-To: <20180604162357.rige4rcsiowdl725@flea>

Dne ponedeljek, 04. junij 2018 ob 18:23:57 CEST je Maxime Ripard napisal(a):
> On Mon, Jun 04, 2018 at 05:09:56PM +0200, Jernej Škrabec wrote:
> > Dne ponedeljek, 04. junij 2018 ob 13:50:34 CEST je Maxime Ripard 
napisal(a):
> > > On Fri, Jun 01, 2018 at 09:19:43AM -0700, Chen-Yu Tsai wrote:
> > > > On Fri, Jun 1, 2018 at 8:29 AM, Maxime Ripard
> > > > <maxime.ripard-LDxbnhwyfcJBDgjK7y7TUQ@public.gmane.org>
> > 
> > wrote:
> > > > > On Thu, May 31, 2018 at 07:54:08PM +0200, Jernej Škrabec wrote:
> > > > >> Dne četrtek, 31. maj 2018 ob 11:21:33 CEST je Maxime Ripard 
napisal(a):
> > > > >> > On Thu, May 24, 2018 at 03:01:09PM -0700, Chen-Yu Tsai wrote:
> > > > >> > > >> > > + if (tcon->quirks->needs_tcon_top) {
> > > > >> > > >> > > +         struct device_node *np;
> > > > >> > > >> > > +
> > > > >> > > >> > > +         np = of_parse_phandle(dev->of_node,
> > > > >> > > >> > > "allwinner,tcon-top",
> > > > >> > > >> > > 0);
> > > > >> > > >> > > +         if (np) {
> > > > >> > > >> > > +                 struct platform_device *pdev;
> > > > >> > > >> > > +
> > > > >> > > >> > > +                 pdev = of_find_device_by_node(np);
> > > > >> > > >> > > +                 if (pdev)
> > > > >> > > >> > > +                         tcon->tcon_top =
> > > > >> > > >> > > platform_get_drvdata(pdev);
> > > > >> > > >> > > +                 of_node_put(np);
> > > > >> > > >> > > +
> > > > >> > > >> > > +                 if (!tcon->tcon_top)
> > > > >> > > >> > > +                         return -EPROBE_DEFER;
> > > > >> > > >> > > +         }
> > > > >> > > >> > > + }
> > > > >> > > >> > > +
> > > > >> > > >> > 
> > > > >> > > >> > I might have missed it, but I've not seen the bindings
> > > > >> > > >> > additions for
> > > > >> > > >> > that property. This shouldn't really be done that way
> > > > >> > > >> > anyway,
> > > > >> > > >> > instead
> > > > >> > > >> > of using a direct phandle, you should be using the
> > > > >> > > >> > of-graph,
> > > > >> > > >> > with the
> > > > >> > > >> > TCON-top sitting where it belongs in the flow of data.
> > > > >> > > >> 
> > > > >> > > >> Just to answer to the first question, it did describe it in
> > > > >> > > >> "[PATCH
> > > > >> > > >> 07/15] dt- bindings: display: sun4i-drm: Add R40 HDMI
> > > > >> > > >> pipeline".
> > > > >> > > >> 
> > > > >> > > >> As why I designed it that way - HW representation could be
> > > > >> > > >> described
> > > > >> > > >> that way> >>
> > > > >> > > >> 
> > > > >> > > >> (ASCII art makes sense when fixed width font is used to view
> > 
> > it):
> > > > >> > > >>                             / LCD0/LVDS0
> > > > >> > > >>                 
> > > > >> > > >>                 / TCON-LCD0
> > > > >> > > >>                 
> > > > >> > > >>                 |           \ MIPI DSI
> > > > >> > > >> 
> > > > >> > > >> mixer0          |
> > > > >> > > >> 
> > > > >> > > >>        \        / TCON-LCD1 - LCD1/LVDS1
> > > > >> > > >>        
> > > > >> > > >>         TCON-TOP
> > > > >> > > >>        
> > > > >> > > >>        /        \ TCON-TV0 - TVE0/RGB
> > > > >> > > >> 
> > > > >> > > >> mixer1          |          \
> > > > >> > > >> 
> > > > >> > > >>                 |           TCON-TOP - HDMI
> > > > >> > > >>                 |          
> > > > >> > > >>                 |          /
> > > > >> > > >>                 
> > > > >> > > >>                 \ TCON-TV1 - TVE1/RGB
> > > > >> > > >> 
> > > > >> > > >> This is a bit simplified, since there is also TVE-TOP, which
> > > > >> > > >> is
> > > > >> > > >> responsible
> > > > >> > > >> for sharing 4 DACs between both TVE encoders. You can have
> > > > >> > > >> two
> > > > >> > > >> TV outs
> > > > >> > > >> (PAL/ NTSC) or TVE0 as TV out and TVE1 as RGB or vice versa.
> > > > >> > > >> It
> > > > >> > > >> even
> > > > >> > > >> seems that you can arbitrarly choose which DAC is
> > > > >> > > >> responsible
> > > > >> > > >> for
> > > > >> > > >> which signal, so there is a ton of possible end
> > > > >> > > >> combinations,
> > > > >> > > >> but I'm
> > > > >> > > >> not 100% sure.
> > > > >> > > >> 
> > > > >> > > >> Even though I wrote TCON-TOP twice, this is same unit in HW.
> > > > >> > > >> R40
> > > > >> > > >> manual
> > > > >> > > >> suggest more possibilities, although some of them seem
> > > > >> > > >> wrong,
> > > > >> > > >> like RGB
> > > > >> > > >> feeding from LCD TCON. That is confirmed to be wrong when
> > > > >> > > >> checking BSP
> > > > >> > > >> code.
> > > > >> > > >> 
> > > > >> > > >> Additionally, TCON-TOP comes in the middle of TVE0 and LCD0,
> > > > >> > > >> TVE1 and
> > > > >> > > >> LCD1 for pin muxing, although I'm not sure why is that
> > > > >> > > >> needed at
> > > > >> > > >> all,
> > > > >> > > >> since according to R40 datasheet, TVE0 and TVE1 pins are
> > > > >> > > >> dedicated and
> > > > >> > > >> not on PORT D and PORT H, respectively, as TCON-TOP
> > > > >> > > >> documentation
> > > > >> > > >> suggest. However, HSYNC and PSYNC lines might be shared
> > > > >> > > >> between
> > > > >> > > >> TVE
> > > > >> > > >> (when it works in RGB mode) and LCD. But that is just my
> > > > >> > > >> guess
> > > > >> > > >> since
> > > > >> > > >> I'm not really familiar with RGB and LCD interfaces.
> > > > >> > > >> 
> > > > >> > > >> I'm really not sure what would be the best representation in
> > > > >> > > >> OF-graph.
> > > > >> > > >> Can you suggest one?
> > > > >> > > > 
> > > > >> > > > Rob might disagree on this one, but I don't see anything
> > > > >> > > > wrong
> > > > >> > > > with
> > > > >> > > > having loops in the graph. If the TCON-TOP can be both the
> > > > >> > > > input
> > > > >> > > > and
> > > > >> > > > output of the TCONs, then so be it, and have it described
> > > > >> > > > that
> > > > >> > > > way in
> > > > >> > > > the graph.
> > > > >> > > > 
> > > > >> > > > The code is already able to filter out nodes that have
> > > > >> > > > already
> > > > >> > > > been
> > > > >> > > > added to the list of devices we need to wait for in the
> > > > >> > > > component
> > > > >> > > > framework, so that should work as well.
> > > > >> > > > 
> > > > >> > > > And we'd need to describe TVE-TOP as well, even though we
> > > > >> > > > don't
> > > > >> > > > have a
> > > > >> > > > driver for it yet. That will simplify the backward
> > > > >> > > > compatibility
> > > > >> > > > later
> > > > >> > > > on.
> > > > >> > > 
> > > > >> > > I'm getting the feeling that TCON-TOP / TVE-TOP is the glue
> > > > >> > > layer
> > > > >> > > that
> > > > >> > > binds everything together, and provides signal routing, kind of
> > > > >> > > like
> > > > >> > > DE-TOP on A64. So the signal mux controls that were originally
> > > > >> > > found
> > > > >> > > in TCON0 and TVE0 were moved out.
> > > > >> > > 
> > > > >> > > The driver needs to know about that, but the graph about
> > > > >> > > doesn't
> > > > >> > > make
> > > > >> > > much sense directly. Without looking at the manual, I
> > > > >> > > understand it
> > > > >> > > to
> > > > >> > > likely be one mux between the mixers and TCONs, and one between
> > > > >> > > the
> > > > >> > > TCON-TVs and HDMI. Would it make more sense to just have the
> > > > >> > > graph
> > > > >> > > connections between the muxed components, and remove TCON-TOP
> > > > >> > > from
> > > > >> > > it, like we had in the past? A phandle could be used to
> > > > >> > > reference
> > > > >> > > the TCON-TOP for mux controls, in addition to the clocks and
> > > > >> > > resets.
> > > > >> > > 
> > > > >> > > For TVE, we would need something to represent each of the
> > > > >> > > output
> > > > >> > > pins,
> > > > >> > > so the device tree can actually describe what kind of signal,
> > > > >> > > be it
> > > > >> > > each component of RGB/YUV or composite video, is wanted on each
> > > > >> > > pin,
> > > > >> > > if any. This is also needed on the A20 for the Cubietruck, so
> > > > >> > > we
> > > > >> > > can
> > > > >> > > describe which pins are tied to the VGA connector, and which
> > > > >> > > one
> > > > >> > > does
> > > > >> > > R, G, or B.
> > > > >> > 
> > > > >> > I guess we'll see how the DT maintainers feel about this, but my
> > > > >> > impression is that the OF graph should model the flow of data
> > > > >> > between
> > > > >> > the devices. If there's a mux somewhere, then the data is
> > > > >> > definitely
> > > > >> > going through it, and as such it should be part of the graph.
> > > > >> 
> > > > >> I concur, but I spent few days thinking how to represent this
> > > > >> sanely in
> > > > >> graph, but I didn't find any good solution. I'll represent here my
> > > > >> idea and please tell your opinion before I start implementing it.
> > > > >> 
> > > > >> First, let me be clear that mixer0 and mixer1 don't have same
> > > > >> capabilities
> > > > >> (different number of planes, mixer0 supports writeback, mixer1 does
> > > > >> not,
> > > > >> etc.). Thus, it does matter which mixer is connected to which
> > > > >> TCON/encoder.
> > > > >> mixer0 is meant to be connected to main display and mixer1 to
> > > > >> auxiliary. That obviously depends on end system.
> > > > >> 
> > > > >> So, TCON TOP has 3 muxes, which have to be represented in graph.
> > > > >> Two of
> > > > >> them are for mixer/TCON relationship (each of them 1 input and 4
> > > > >> possible outputs) and one for TV TCON/HDMI pair selection (2
> > > > >> possible
> > > > >> inputs, 1 output).
> > > > >> 
> > > > >> According to current practice in sun4i-drm driver, graph has to
> > > > >> have
> > > > >> port 0, representing input and port 1, representing output. This
> > > > >> would
> > > > >> mean that graph looks something like that:
> > > > >> 
> > > > >> tcon_top: tcon-top@1c70000 {
> > > > >> 
> > > > >>       compatible = "allwinner,sun8i-r40-tcon-top";
> > > > >>       ...
> > > > >>       ports {
> > > > >>       
> > > > >>               #address-cells = <1>;
> > > > >>               #size-cells = <0>;
> > > > >>               
> > > > >>               tcon_top_in: port@0 {
> > > > >>               
> > > > >>                       #address-cells = <1>;
> > > > >>                       #size-cells = <0>;
> > > > >>                       reg = <0>;
> > > > >>                       
> > > > >>                       tcon_top_in_mixer0: endpoint@0 {
> > > > >>                       
> > > > >>                               reg = <0>;
> > > > >>                               remote-endpoint =
> > > > >>                               <&mixer0_out_tcon_top>;
> > > > >>                       
> > > > >>                       };
> > > > >>                       
> > > > >>                       tcon_top_in_mixer1: endpoint@1 {
> > > > >>                       
> > > > >>                               reg = <1>;
> > > > >>                               remote-endpoint =
> > > > >>                               <&mixer1_out_tcon_top>;
> > > > >>                       
> > > > >>                       };
> > > > >>                       
> > > > >>                       tcon_top_in_tcon_tv: endpoint@2 {
> > > > >>                       
> > > > >>                               reg = <2>;
> > > > >>                               // here is HDMI input connection,
> > > > >>                               part of
> > > > >>                               board DTS
> > > > >>                               remote-endpoint = <board specific
> > > > >>                               phandle
> > > > >>                               to TV TCON output>;
> > > > >>                       
> > > > >>                       };
> > > > >>               
> > > > >>               };
> > > > >>               
> > > > >>               tcon_top_out: port@1 {
> > > > >>               
> > > > >>                       #address-cells = <1>;
> > > > >>                       #size-cells = <0>;
> > > > >>                       reg = <1>;
> > > > >>                       
> > > > >>                       tcon_top_out_tcon0: endpoint@0 {
> > > > >>                       
> > > > >>                               reg = <0>;
> > > > >>                               // here is mixer0 output connection,
> > > > >>                               part
> > > > >>                               of board DTS
> > > > >>                               remote-endpoint = <board specific
> > > > >>                               phandle
> > > > >>                               to TCON>;
> > > > >>                       
> > > > >>                       };
> > > > >>                       
> > > > >>                       tcon_top_out_tcon1: endpoint@1 {
> > > > >>                       
> > > > >>                               reg = <1>;
> > > > >>                               // here is mixer1 output connection,
> > > > >>                               part
> > > > >>                               of board DTS
> > > > >>                               remote-endpoint = <board specific
> > > > >>                               phandle
> > > > >>                               to TCON>;
> > > > >>                       
> > > > >>                       };
> > > > >>                       
> > > > >>                       tcon_top_out_hdmi: endpoint@2 {
> > > > >>                       
> > > > >>                               reg = <2>;
> > > > >>                               remote-endpoint =
> > > > >>                               <&hdmi_in_tcon_top>;
> > > > >>                       
> > > > >>                       };
> > > > >>               
> > > > >>               };
> > > > >>       
> > > > >>       };
> > > > >> 
> > > > >> };
> > > > > 
> > > > > IIRC, each port is supposed to be one route for the data, so we
> > > > > would
> > > > > have multiple ports, one for the mixers in input and for the tcon in
> > > > > output, and one for the TCON in input and for the HDMI/TV in
> > > > > output. Rob might correct me here.
> > 
> > Ok, that seems more clean approach. I'll have to extend graph traversing
> > algorithm in sun4i_drv.c, but that's no problem.
> > 
> > Just to be clear, you have in mind 3 pairs of ports (0/1 for mixer0 mux,
> > 2/3 for mixer1 and 4/5 for HDMI input), right? That way each mux is
> > represented with one pair of ports, even numbered for input and odd
> > numbered for output.
> Yep, unless Rob feels otherwise.

I found an issue with this concept.

HDMI driver (sun8i_dw_hdmi.c) uses drm_of_find_possible_crtcs() to find 
connected crtcs (TCONs) to HDMI. This function assumes that crtc and encoder 
are directly connected through of_graph, but that is not the case with TCON 
TOP HDMI mux anymore. 
I could give TCON TOP node as an input to this function, but that won't work, 
since TCON TOP can have connections to other crtcs, not only that of HDMI and 
they will also be picked up by drm_of_find_possible_crtcs().

Any suggestion how to solve this nicely? I think creating my own version of 
drm_of_find_possible_crtcs() which considers that case is one way, but not 
very nice solution. Alternatively, we can fix possible_crtcs to BIT(0), since 
it always has only one input. This is done in meson_dw_hdmi.c for example. 

Best regards,
Jernej



-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply

* Re: [PATCH v2] dt-bindings: clock: imx6ul: Do not change the clock definition order
From: Fabio Estevam @ 2018-06-06 21:56 UTC (permalink / raw)
  To: Stefan Agner
  Cc: Stephen Boyd, Michael Trimarchi, Stefan Wahren, Rob Herring,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-clk, Yongcai Huang, Fabio Estevam
In-Reply-To: <3be11aeea9cd0399837acb201f6226d9@agner.ch>

Hi Stefan,

On Wed, Jun 6, 2018 at 1:27 PM, Stefan Agner <stefan@agner.ch> wrote:

>> +#define IMX6ULL_CLK_ESAI_SEL         236
>
> Nit: Add an empty line here?

The lack of an empty line is on purpose because I wanted to avoid
someone thinking:
"Oh, there is hole here, let me fill it with new clocks here" :-)

> Reviewed-by: Stefan Agner <stefan@agner.ch>

Thanks for reviewing!

^ permalink raw reply

* Re: [PATCH v4 2/3] arm: shmobile: Add the R9A06G032 SMP enabler driver
From: Frank Rowand @ 2018-06-06 21:52 UTC (permalink / raw)
  To: Michel Pollet, linux-renesas-soc@vger.kernel.org, Simon Horman
  Cc: Michel Pollet, Mark Rutland, Phil Edworthy, Florian Fainelli,
	Rajendra Nayak, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, Stefan Wahren, Magnus Damm,
	Russell King, Douglas Anderson, Chen-Yu Tsai, Rob Herring,
	Carlo Caione, Andreas Färber, Frank Rowand,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <9cef7124-3020-5741-f3a2-6925a6c8f0f3@gmail.com>

On 06/06/18 14:48, Frank Rowand wrote:
> On 06/05/18 23:36, Michel Pollet wrote:
>> Hi Frank,
>>
>> On 05 June 2018 18:34, Frank wrote:
>>> On 06/05/18 04:28, Michel Pollet wrote:
>>>> The Renesas R9A06G032 second CA7 is parked in a ROM pen at boot time,
>>>> it requires a special enable method to get it started.
>>>>
>>>> Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>
>>>> ---
>>>>  arch/arm/mach-shmobile/Makefile        |  1 +
>>>>  arch/arm/mach-shmobile/smp-r9a06g032.c | 79
>>>> ++++++++++++++++++++++++++++++++++
>>>>  2 files changed, 80 insertions(+)
>>>>  create mode 100644 arch/arm/mach-shmobile/smp-r9a06g032.c
>>>>
>>>> diff --git a/arch/arm/mach-shmobile/Makefile
>>>> b/arch/arm/mach-shmobile/Makefile index 1939f52..d7fc98f 100644
>>>> --- a/arch/arm/mach-shmobile/Makefile
>>>> +++ b/arch/arm/mach-shmobile/Makefile
>>>> @@ -34,6 +34,7 @@ smp-$(CONFIG_ARCH_SH73A0)+= smp-sh73a0.o
>>> headsmp-scu.o platsmp-scu.o
>>>>  smp-$(CONFIG_ARCH_R8A7779)+= smp-r8a7779.o headsmp-scu.o
>>> platsmp-scu.o
>>>>  smp-$(CONFIG_ARCH_R8A7790)+= smp-r8a7790.o
>>>>  smp-$(CONFIG_ARCH_R8A7791)+= smp-r8a7791.o
>>>> +smp-$(CONFIG_ARCH_R9A06G032)+= smp-r9a06g032.o
>>>>  smp-$(CONFIG_ARCH_EMEV2)+= smp-emev2.o headsmp-scu.o
>>> platsmp-scu.o
>>>>
>>>>  # PM objects
>>>> diff --git a/arch/arm/mach-shmobile/smp-r9a06g032.c
>>>> b/arch/arm/mach-shmobile/smp-r9a06g032.c
>>>> new file mode 100644
>>>> index 0000000..cd40e6e
>>>> --- /dev/null
>>>> +++ b/arch/arm/mach-shmobile/smp-r9a06g032.c
>>>> @@ -0,0 +1,79 @@
>>>> +// SPDX-License-Identifier: GPL-2.0
>>>> +/*
>>>> + * R9A06G032 Second CA7 enabler.
>>>> + *
>>>> + * Copyright (C) 2018 Renesas Electronics Europe Limited
>>>> + *
>>>> + * Michel Pollet <michel.pollet@bp.renesas.com>,
>>> <buserror@gmail.com>
>>>> + * Derived from action,s500-smp
>>>> + */
>>>> +
>>>> +#include <linux/io.h>
>>>> +#include <linux/of.h>
>>>> +#include <linux/of_address.h>
>>>> +#include <linux/smp.h>
>>>> +
>>>> +/*
>>>> + * The second CPU is parked in ROM at boot time. It requires waking
>>>> +it after
>>>> + * writing an address into the BOOTADDR register of sysctrl.
>>>> + *
>>>> + * So the default value of the "cpu-release-addr" corresponds to
>>> BOOTADDR...
>>>> + *
>>>> + * *However* the BOOTADDR register is not available when the kernel
>>>> + * starts in NONSEC mode.
>>>> + *
>>>> + * So for NONSEC mode, the bootloader re-parks the second CPU into a
>>>> +pen
>>>> + * in SRAM, and changes the "cpu-release-addr" of linux's DT to a
>>>> +SRAM address,
>>>> + * which is not restricted.
>>>
>>> The binding document for cpu-release-addr does not have a definition for 32
>>> bit arm.  The existing definition is only 64 bit arm.  Please add the definition
>>> for 32 bit arm to patch 1.
>>
>> Hmmm I do find a definition in
>> Documentation/devicetree/bindings/arm/cpus.txt -- just under where I
>> added my 'enable-method' -- And it is already used as 32 bits in at least
>> arch/arm/boot/dts/stih407-family.dtsi.
> 
> If the correct answer is for cpu-release-addr to be 64 bits in certain
> cases (that discussion is ongoing further downthread) then one approach
> to maintain compatibility _and_ to fix the devicetree source files is
> to change the source code that currently gets cpu-release-addr as a
> 32 bit object to check the size of the property and get it as either
> a 32 bit or 64 bit object, based on the actual size of the property
> in the device tree and then change the value in the devicetree source
> files to be two cells.  BUT this does not consider the bootloader
> complication.  arch/arm/boot/dts/axm5516-cpus.dtsi has a note
> "// Fixed by the boot loader", so the boot loader also has to be
> modified to be able to handle the possibility that the property
> could be either 32 bits or 64 bits.  I don't know how to maintain
> compatibility with the boot loader since we can't force it to
> change synchronously with changes in the kernel.
> 
> You can consider this comment to be a drive-by observation.  I think
> Rob and Geert and people like that are likely to be more helpful with
> what to actually do, and you can treat my comment more as pointing out
> the issue than as providing the perfect solution.

Darn it, hit <send> too quickly.

I meant to mention that there are several devicetree source files that
have a single cell value for cpu-release-addr, and thus potentially
face the same situation, depending on what the final decision is on
the proper size for cpu-release-addr. As of v4.17, a git grep shows
one cell values in:

  arch/arm/boot/dts/axm5516-cpus.dtsi
  arch/arm/boot/dts/stih407-family.dtsi
  arch/arm/boot/dts/stih418.dtsi

-Frank

> -Frnak
> 
> 
>>
>> What do you want me to add to this exactly? Do you want me to just
>> change "required for systems that have an "enable-method" property
>> value of "spin-table" to also specify renesas,r9a06g032 ?
>>
>> Thanks!
>> Michel
>>
>>>
>>> -Frank
>>>
>>>
>>>> + */
>>>> +
>>>> +static void __iomem *cpu_bootaddr;
>>>> +
>>>> +static DEFINE_SPINLOCK(cpu_lock);
>>>> +
>>>> +static int r9a06g032_smp_boot_secondary(unsigned int cpu, struct
>>>> +task_struct *idle) {
>>>> +if (!cpu_bootaddr)
>>>> +return -ENODEV;
>>>> +
>>>> +spin_lock(&cpu_lock);
>>>> +
>>>> +writel(__pa_symbol(secondary_startup), cpu_bootaddr);
>>>> +arch_send_wakeup_ipi_mask(cpumask_of(cpu));
>>>> +
>>>> +spin_unlock(&cpu_lock);
>>>> +
>>>> +return 0;
>>>> +}
>>>> +
>>>> +static void __init r9a06g032_smp_prepare_cpus(unsigned int max_cpus)
>>>> +{
>>>> +struct device_node *dn;
>>>> +int ret;
>>>> +u32 bootaddr;
>>>> +
>>>> +dn = of_get_cpu_node(1, NULL);
>>>> +if (!dn) {
>>>> +pr_err("CPU#1: missing device tree node\n");
>>>> +return;
>>>> +}
>>>> +/*
>>>> + * Determine the address from which the CPU is polling.
>>>> + * The bootloader *does* change this property
>>>> + */
>>>> +ret = of_property_read_u32(dn, "cpu-release-addr", &bootaddr);
>>>> +of_node_put(dn);
>>>> +if (ret) {
>>>> +pr_err("CPU#1: invalid cpu-release-addr property\n");
>>>> +return;
>>>> +}
>>>> +pr_info("CPU#1: cpu-release-addr %08x\n", bootaddr);
>>>> +
>>>> +cpu_bootaddr = ioremap(bootaddr, sizeof(bootaddr)); }
>>>> +
>>>> +static const struct smp_operations r9a06g032_smp_ops __initconst = {
>>>> +.smp_prepare_cpus = r9a06g032_smp_prepare_cpus,
>>>> +.smp_boot_secondary = r9a06g032_smp_boot_secondary, };
>>>> +CPU_METHOD_OF_DECLARE(r9a06g032_smp, "renesas,r9a06g032-smp",
>>>> +&r9a06g032_smp_ops);
>>>>
>>
>>
>>
>>
>> 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

* Re: [PATCH v4 2/3] arm: shmobile: Add the R9A06G032 SMP enabler driver
From: Frank Rowand @ 2018-06-06 21:48 UTC (permalink / raw)
  To: Michel Pollet, linux-renesas-soc@vger.kernel.org, Simon Horman
  Cc: Michel Pollet, Mark Rutland, Phil Edworthy, Florian Fainelli,
	Rajendra Nayak, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, Stefan Wahren, Magnus Damm,
	Russell King, Douglas Anderson, Chen-Yu Tsai, Rob Herring,
	Carlo Caione, Andreas Färber, Frank Rowand,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <OSBPR01MB2054E3A1E383495F3534B551D2650@OSBPR01MB2054.jpnprd01.prod.outlook.com>

On 06/05/18 23:36, Michel Pollet wrote:
> Hi Frank,
> 
> On 05 June 2018 18:34, Frank wrote:
>> On 06/05/18 04:28, Michel Pollet wrote:
>>> The Renesas R9A06G032 second CA7 is parked in a ROM pen at boot time,
>>> it requires a special enable method to get it started.
>>>
>>> Signed-off-by: Michel Pollet <michel.pollet@bp.renesas.com>
>>> ---
>>>  arch/arm/mach-shmobile/Makefile        |  1 +
>>>  arch/arm/mach-shmobile/smp-r9a06g032.c | 79
>>> ++++++++++++++++++++++++++++++++++
>>>  2 files changed, 80 insertions(+)
>>>  create mode 100644 arch/arm/mach-shmobile/smp-r9a06g032.c
>>>
>>> diff --git a/arch/arm/mach-shmobile/Makefile
>>> b/arch/arm/mach-shmobile/Makefile index 1939f52..d7fc98f 100644
>>> --- a/arch/arm/mach-shmobile/Makefile
>>> +++ b/arch/arm/mach-shmobile/Makefile
>>> @@ -34,6 +34,7 @@ smp-$(CONFIG_ARCH_SH73A0)+= smp-sh73a0.o
>> headsmp-scu.o platsmp-scu.o
>>>  smp-$(CONFIG_ARCH_R8A7779)+= smp-r8a7779.o headsmp-scu.o
>> platsmp-scu.o
>>>  smp-$(CONFIG_ARCH_R8A7790)+= smp-r8a7790.o
>>>  smp-$(CONFIG_ARCH_R8A7791)+= smp-r8a7791.o
>>> +smp-$(CONFIG_ARCH_R9A06G032)+= smp-r9a06g032.o
>>>  smp-$(CONFIG_ARCH_EMEV2)+= smp-emev2.o headsmp-scu.o
>> platsmp-scu.o
>>>
>>>  # PM objects
>>> diff --git a/arch/arm/mach-shmobile/smp-r9a06g032.c
>>> b/arch/arm/mach-shmobile/smp-r9a06g032.c
>>> new file mode 100644
>>> index 0000000..cd40e6e
>>> --- /dev/null
>>> +++ b/arch/arm/mach-shmobile/smp-r9a06g032.c
>>> @@ -0,0 +1,79 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * R9A06G032 Second CA7 enabler.
>>> + *
>>> + * Copyright (C) 2018 Renesas Electronics Europe Limited
>>> + *
>>> + * Michel Pollet <michel.pollet@bp.renesas.com>,
>> <buserror@gmail.com>
>>> + * Derived from action,s500-smp
>>> + */
>>> +
>>> +#include <linux/io.h>
>>> +#include <linux/of.h>
>>> +#include <linux/of_address.h>
>>> +#include <linux/smp.h>
>>> +
>>> +/*
>>> + * The second CPU is parked in ROM at boot time. It requires waking
>>> +it after
>>> + * writing an address into the BOOTADDR register of sysctrl.
>>> + *
>>> + * So the default value of the "cpu-release-addr" corresponds to
>> BOOTADDR...
>>> + *
>>> + * *However* the BOOTADDR register is not available when the kernel
>>> + * starts in NONSEC mode.
>>> + *
>>> + * So for NONSEC mode, the bootloader re-parks the second CPU into a
>>> +pen
>>> + * in SRAM, and changes the "cpu-release-addr" of linux's DT to a
>>> +SRAM address,
>>> + * which is not restricted.
>>
>> The binding document for cpu-release-addr does not have a definition for 32
>> bit arm.  The existing definition is only 64 bit arm.  Please add the definition
>> for 32 bit arm to patch 1.
> 
> Hmmm I do find a definition in
> Documentation/devicetree/bindings/arm/cpus.txt -- just under where I
> added my 'enable-method' -- And it is already used as 32 bits in at least
> arch/arm/boot/dts/stih407-family.dtsi.

If the correct answer is for cpu-release-addr to be 64 bits in certain
cases (that discussion is ongoing further downthread) then one approach
to maintain compatibility _and_ to fix the devicetree source files is
to change the source code that currently gets cpu-release-addr as a
32 bit object to check the size of the property and get it as either
a 32 bit or 64 bit object, based on the actual size of the property
in the device tree and then change the value in the devicetree source
files to be two cells.  BUT this does not consider the bootloader
complication.  arch/arm/boot/dts/axm5516-cpus.dtsi has a note
"// Fixed by the boot loader", so the boot loader also has to be
modified to be able to handle the possibility that the property
could be either 32 bits or 64 bits.  I don't know how to maintain
compatibility with the boot loader since we can't force it to
change synchronously with changes in the kernel.

You can consider this comment to be a drive-by observation.  I think
Rob and Geert and people like that are likely to be more helpful with
what to actually do, and you can treat my comment more as pointing out
the issue than as providing the perfect solution.

-Frnak


> 
> What do you want me to add to this exactly? Do you want me to just
> change "required for systems that have an "enable-method" property
> value of "spin-table" to also specify renesas,r9a06g032 ?
> 
> Thanks!
> Michel
> 
>>
>> -Frank
>>
>>
>>> + */
>>> +
>>> +static void __iomem *cpu_bootaddr;
>>> +
>>> +static DEFINE_SPINLOCK(cpu_lock);
>>> +
>>> +static int r9a06g032_smp_boot_secondary(unsigned int cpu, struct
>>> +task_struct *idle) {
>>> +if (!cpu_bootaddr)
>>> +return -ENODEV;
>>> +
>>> +spin_lock(&cpu_lock);
>>> +
>>> +writel(__pa_symbol(secondary_startup), cpu_bootaddr);
>>> +arch_send_wakeup_ipi_mask(cpumask_of(cpu));
>>> +
>>> +spin_unlock(&cpu_lock);
>>> +
>>> +return 0;
>>> +}
>>> +
>>> +static void __init r9a06g032_smp_prepare_cpus(unsigned int max_cpus)
>>> +{
>>> +struct device_node *dn;
>>> +int ret;
>>> +u32 bootaddr;
>>> +
>>> +dn = of_get_cpu_node(1, NULL);
>>> +if (!dn) {
>>> +pr_err("CPU#1: missing device tree node\n");
>>> +return;
>>> +}
>>> +/*
>>> + * Determine the address from which the CPU is polling.
>>> + * The bootloader *does* change this property
>>> + */
>>> +ret = of_property_read_u32(dn, "cpu-release-addr", &bootaddr);
>>> +of_node_put(dn);
>>> +if (ret) {
>>> +pr_err("CPU#1: invalid cpu-release-addr property\n");
>>> +return;
>>> +}
>>> +pr_info("CPU#1: cpu-release-addr %08x\n", bootaddr);
>>> +
>>> +cpu_bootaddr = ioremap(bootaddr, sizeof(bootaddr)); }
>>> +
>>> +static const struct smp_operations r9a06g032_smp_ops __initconst = {
>>> +.smp_prepare_cpus = r9a06g032_smp_prepare_cpus,
>>> +.smp_boot_secondary = r9a06g032_smp_boot_secondary, };
>>> +CPU_METHOD_OF_DECLARE(r9a06g032_smp, "renesas,r9a06g032-smp",
>>> +&r9a06g032_smp_ops);
>>>
> 
> 
> 
> 
> 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

* Re: [PATCH v6 00/15] staging: typec: tcpci: move out of staging
From: Mats Karrman @ 2018-06-06 21:44 UTC (permalink / raw)
  To: Li Jun, robh+dt, gregkh, heikki.krogerus, linux
  Cc: cw00.choi, a.hajda, shufan_lee, peter.chen, garsilva, gsomlo,
	linux-usb, devicetree, linux-imx
In-Reply-To: <1527475967-15201-1-git-send-email-jun.li@nxp.com>

Hello Li Jun,

I have been testing these patches on top of usb-next using an i.MX6,
a nxp ptn5110 evaluation board and a bunch of usbc devices. So far
everything seem to work fine! :-)
However, I have only tested host mode and I have some test cases
left I want to cover.

Just to let you know your patches are not forgotten :-)

BR // Mats

On 2018-05-28 04:52, Li Jun wrote:
> This patch set attempts to move the tcpci drivers out of staging by fix
> some tcpci driver issues and define typec and power delivery device
> properties, the changes are verified on NXP PTN5110, which is a standard
> tcpci typec port controller device with power delivery support, tested
> power source and sink with drp config.
>
> Changes for v6:
> - Change function name to be typec_find_port_power/data_role for find
>    capability, and typec_find_power_role for find one specific power role.
> - Fix rt1711h driver move missing.
> - Add one patch to improve the error checking in tcpci driver, use IS_ERR()
>    instead of PTR_ERR_OR_ZERO().
> - Add Rob's Reviewed-by for patch [2/15].
> - Misc typos fix.
>   
> Changes for v5:
> - Use "power-role" and "data-role" for typec port power and data capability
>    property name.
> - Use macro defintion instead of cryptic numbers for readability of
>    power delivery properties(PDO).
> - Add one tcpci driver binding string to be "nxp,ptn5110" to follow binding
>    name rule "<vendor prefix>,<device>".
> - Change operating power property name to be op-sink-microwatt.
> - Add one patch(remove unused tcpci_tcpc_config) to resolve bisectablitity
>    issue of patch usb: typec: add fwnode to tcpc.
> - A minor error handling change to keep the error path and success path
>    separate in patch: register port before request irq
> - Rebase to latest Greg's tree with max_snk_* removed.
>
> Changes for v4:
> - Remove max-sink-* properties as we will purge max_snk_* in tcpm,
>    see patch set[4].
> - Get typec power and data type value via name string(patch 5).
> - Move finding typec and pd properties code from tcpci to tcpm(patch 6)
> - Add a compatible string for nxp ptn5110 typec controller in tcpci driver.
>    (patch 3)
> - Add set cc for drp toggling without try.src/snk in tcpm(patch 10), then
>    patch 11 can only update CCx bits for keep disconnect cc line open.
> - Update op-sink-microwatt-hours example value to be the right value in
>    micorwatts, and accordingly divide 1000 to get its miliwatts value
>    in patch 6.
> - Add Guenter's Reviewed-by for patch(8/9/12)
>
> [4] https://www.spinics.net/lists/linux-usb/msg167261.html
>
> Changes for v3:
> - Use 2 properties to separate power and data capability of typec port:
>    "power-type" and "data-type", this is based on Heikki's typec class code
>    change[2]. use "try-power-role" to present if the typec port can support
>    Try.SNK or Try.SRC.
> - 4 sink properties(max_sink_mv/ma/mw and op_sink_mw) are kept because the
>    counterpart code is back, see revert patch[3], meanwhile I post a patch
>    to fix the reported problem of current source pdo select machinism(which
>    completely ignored those 4 sink settings), to see if we can keep current
>    code, once it was discussed and have conclusion I can update this
>    accordingly.
> - Use fwnode to get the connector node for dt setting parse.
>
> Main changes for v2:
> - Typec properties are based on general usb connector bindings[1] proposed
>    by Andrzej Hajda, use the standard unit suffixes as defined in
>    property-units.txt.
> - Add 2 infra APIs to get power sink and source config from dt.
> - Don't change the set_cc api, to keep the uncontacted cc line open,
>    set cc1/cc2 to be open in tcpci driver when set polarity.
> - Directly enable vbus detect in tcpci driver rather than add a API.
> - Details added in each patch.
>
> [1] https://patchwork.kernel.org/patch/10231447/
> [2] https://patchwork.kernel.org/patch/10276483/
> [3] https://www.spinics.net/lists/linux-usb/msg166366.html
>
> Li Jun (14):
>    dt-bindings: connector: add properties for typec
>    dt-bindings: usb: add documentation for typec port controller(TCPCI)
>    staging: typec: tcpci: add compatible string for nxp ptn5110
>    usb: typec: add fwnode to tcpc
>    usb: typec: add API to get typec basic port power and data config
>    usb: typec: tcpm: support get typec and pd config from device
>      properties
>    staging: typec: tcpci: remove unused tcpci_tcpc_config
>    staging: typec: tcpci: use IS_ERR() instead of PTR_ERR_OR_ZERO()
>    staging: typec: tcpci: enable vbus detection
>    typec: tcpm: add starting value for drp toggling
>    usb: typec: tcpm: set cc for drp toggling attach
>    staging: typec: tcpci: keep the disconnected cc line open
>    staging: typec: tcpci: Only touch target bit when enable vconn
>    staging: typec: tcpci: move tcpci drivers out of staging
>
> Peter Chen (1):
>    staging: typec: tcpci: register port before request irq
>
>   .../bindings/connector/usb-connector.txt           |  44 ++++++
>   .../devicetree/bindings/usb/typec-tcpci.txt        |  49 +++++++
>   drivers/staging/Kconfig                            |   2 -
>   drivers/staging/Makefile                           |   1 -
>   drivers/staging/typec/Kconfig                      |  22 ---
>   drivers/staging/typec/Makefile                     |   2 -
>   drivers/staging/typec/TODO                         |   5 -
>   drivers/usb/typec/Kconfig                          |  15 +++
>   drivers/usb/typec/Makefile                         |   2 +
>   drivers/usb/typec/class.c                          |  50 +++++++
>   drivers/{staging => usb}/typec/tcpci.c             |  66 +++++----
>   drivers/{staging => usb}/typec/tcpci.h             |   0
>   drivers/{staging => usb}/typec/tcpci_rt1711h.c     |   0
>   drivers/usb/typec/tcpm.c                           | 148 +++++++++++++++++----
>   include/dt-bindings/usb/pd.h                       |  62 +++++++++
>   include/linux/usb/tcpm.h                           |   2 +
>   include/linux/usb/typec.h                          |   3 +
>   17 files changed, 389 insertions(+), 84 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/usb/typec-tcpci.txt
>   delete mode 100644 drivers/staging/typec/Kconfig
>   delete mode 100644 drivers/staging/typec/Makefile
>   delete mode 100644 drivers/staging/typec/TODO
>   rename drivers/{staging => usb}/typec/tcpci.c (92%)
>   rename drivers/{staging => usb}/typec/tcpci.h (100%)
>   rename drivers/{staging => usb}/typec/tcpci_rt1711h.c (100%)
>   create mode 100644 include/dt-bindings/usb/pd.h
>

^ permalink raw reply

* USB role switches, usb-connector, typec and device trees
From: Mats Karrman @ 2018-06-06 21:36 UTC (permalink / raw)
  To: Heikki Krogerus, Hans de Goede, Andrzej Hajda
  Cc: Greg Kroah-Hartman, linux-usb, devicetree

Hello Gentlemen,

I'm trying to get my head around USB role switches in connection with Type-C ports
and device-trees. So far I have not found much documentation, e.g. there are no
device-tree bindings documented and really no good examples in existing device
trees, although there has been some attempts, e.g. [1] and [2]. Anyway, so I send
you a couple of questions instead:

1) tcpm uses the port device struct to find a single usb_role_switch but there is
room for three USB busses in the Type-C connector; one high speed and two (?) super-
speed. These would not all come from the same controller (there might even be
separate controllers for host and device mode for each bus).
The case I am working on now only have a single USB2 otg controller so it should
be possible to make that driver register a role switch but for other cases?
I imagine it would be possible to create a composite driver as a proxy for all role
switches but that would probably be different for every platform/product - not
very elegant. Could the role switch infrastructure be extended to handle arbitrary
sets of coordinated switches?

2) How should the connection between the Type-C port and the switches best be
expressed in a device tree? Using graph I presume, but should it be mixed into the
existing "usb-connector" or should this be a separate block?
I think it is unfortunate that the graph use numeric addresses that need to be
fixed by documentation and already I see problems with the current assignment
(0=HS, 1=SS, 2=SBU), e.g. if the host and device mode are handled by different
controllers. Graph do support multiple endpoints for one port but then we have
another level of magic numbers which does not exactly make things easier
(e.g. 0=dual or host controller, 1=device controller, 2=mode switch).

What are your thoughts on this? Please tell me I missed something and that there is
a simple solution :-)

BR // Mats

[1] https://www.spinics.net/lists/linux-usb/msg168071.html
[2] https://www.spinics.net/lists/linux-usb/msg168072.html


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox