Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH 13/15] Documentation: devicetree: dwc2: Add host DMA binding
From: John Youn @ 2016-10-27 21:33 UTC (permalink / raw)
  To: Rob Herring, John Youn
  Cc: Felipe Balbi, linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Mark Rutland
In-Reply-To: <20161026220718.2vqcpts6mw2vf7jh@rob-hp-laptop>

On 10/26/2016 3:07 PM, Rob Herring wrote:
> On Wed, Oct 19, 2016 at 06:22:52PM -0700, John Youn wrote:
>> Add the host-dma property to devicetree. This controls whether to use
>> DMA in host mode.
>>
>> Signed-off-by: John Youn <johnyoun-HKixBCOQz3hWk0Htik3J/w@public.gmane.org>
>> ---
>>  Documentation/devicetree/bindings/usb/dwc2.txt | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt
>> index 2c30a54..17f7624 100644
>> --- a/Documentation/devicetree/bindings/usb/dwc2.txt
>> +++ b/Documentation/devicetree/bindings/usb/dwc2.txt
>> @@ -25,6 +25,7 @@ Optional properties:
>>  Refer to phy/phy-bindings.txt for generic phy consumer properties
>>  - dr_mode: shall be one of "host", "peripheral" and "otg"
>>    Refer to usb/generic.txt
>> +- host-dma: turn on or off host buffer DMA (1 or 0).
> 
> Why not boolean? Seems like disabling would be rare, so name the 
> property something like host-dma-disable.

Ok.

> Also, it needs a vendor 
> prefix.
> 

The dwc2 driver doesn't have vendor prefixes on existing DT
bindings. Is this required? If so I guess we'd have to deprecate the
old ones and add new ones with the vendor prefix?

Regards,
John
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v5 0/7] Add R8A7743/SK-RZG1M board support
From: Sergei Shtylyov @ 2016-10-27 21:33 UTC (permalink / raw)
  To: horms, linux-renesas-soc, robh+dt, mark.rutland, devicetree
  Cc: linux, magnus.damm, linux-arm-kernel

Hello.

   Here's the set of 7 patches against Simon Horman's 'renesas.git' repo's
'renesas-devel-20161024-v4.9-rc2' tag. I'm adding the device tree support for
the R8A7743-based SK-RZG1M board. The SoC is close to R8A7791 and the board
seems identical to the R8A7791/Porter board. The device tree patches depend on
the R8A7743 CPG/MSSR driver series just re-posted in order to compile and work.
Already merged patches from this series won't be re-posted.

[1/7] ARM: dts: r8a7743: initial SoC device tree
[2/7] ARM: dts: r8a7743: add SYS-DMAC support
[3/7] ARM: dts: r8a7743: add [H]SCIF{A|B} support
[4/7] ARM: dts: r8a7743: add Ether support
[5/7] ARM: dts: r8a7743: add IRQC support
[6/7] ARM: dts: sk-rzg1m: initial device tree
[7/7] ARM: dts: sk-rzg1m: add Ether support

WBR, Sergei

^ permalink raw reply

* [PATCH v5 1/7] ARM: dts: r8a7743: initial SoC device tree
From: Sergei Shtylyov @ 2016-10-27 21:36 UTC (permalink / raw)
  To: horms, linux-renesas-soc, robh+dt, mark.rutland, devicetree
  Cc: magnus.damm, linux, linux-arm-kernel
In-Reply-To: <1580369.yToZzJza1l@wasted.cogentembedded.com>

The  initial R8A7743 SoC device tree including CPU0, GIC, timer, SYSC, RST,
CPG, and the required clock descriptions.

Based on the original (and large) patch by Dmitry Shifrin
<dmitry.shifrin@cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

---
Changes in version 5:
- added the RST device node, updated the patch description accordingly.

Changes in version 4:
- removed the CPU1 node, updated the patch description accordingly;
- reformatted the "interrupts" props of the GIC/timer device nodes;
- added Geert's tag.

Changes in version 3:
- changed  the R8A7743 clock header #include;
- replaced the multiple clock nodes with the single CPG node, updated the
  "clocks" property in the CPU0 node, updated the patch description.

Changes in version 2:
- added the IRQC and Ether clocks.

 arch/arm/boot/dts/r8a7743.dtsi |  120 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 120 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7743.dtsi
===================================================================
--- /dev/null
+++ renesas/arch/arm/boot/dts/r8a7743.dtsi
@@ -0,0 +1,120 @@
+/*
+ * Device Tree Source for the r8a7743 SoC
+ *
+ * Copyright (C) 2016 Cogent Embedded Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/r8a7743-cpg-mssr.h>
+#include <dt-bindings/power/r8a7743-sysc.h>
+
+/ {
+	compatible = "renesas,r8a7743";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0>;
+			clock-frequency = <1500000000>;
+			clocks = <&cpg CPG_CORE R8A7743_CLK_Z>;
+			power-domains = <&sysc R8A7743_PD_CA15_CPU0>;
+			next-level-cache = <&L2_CA15>;
+		};
+
+		L2_CA15: cache-controller@0 {
+			compatible = "cache";
+			reg = <0>;
+			cache-unified;
+			cache-level = <2>;
+			power-domains = <&sysc R8A7743_PD_CA15_SCU>;
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		interrupt-parent = <&gic>;
+
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gic: interrupt-controller@f1001000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0 0xf1001000 0 0x1000>,
+			      <0 0xf1002000 0 0x1000>,
+			      <0 0xf1004000 0 0x2000>,
+			      <0 0xf1006000 0 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) |
+						 IRQ_TYPE_LEVEL_HIGH)>;
+		};
+
+		timer {
+			compatible = "arm,armv7-timer";
+			interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
+						  IRQ_TYPE_LEVEL_LOW)>,
+				     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) |
+						  IRQ_TYPE_LEVEL_LOW)>,
+				     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) |
+						  IRQ_TYPE_LEVEL_LOW)>,
+				     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) |
+						  IRQ_TYPE_LEVEL_LOW)>;
+		};
+
+		cpg: clock-controller@e6150000 {
+			compatible = "renesas,r8a7743-cpg-mssr";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>, <&usb_extal_clk>;
+			clock-names = "extal", "usb_extal";
+			#clock-cells = <2>;
+			#power-domain-cells = <0>;
+		};
+
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a7743-sysc";
+			reg = <0 0xe6180000 0 0x0200>;
+			#power-domain-cells = <1>;
+		};
+
+		rst: reset-controller@e6160000 {
+			compatible = "renesas,r8a7743-rst";
+			reg = <0 0xe6160000 0 0x0200>;
+		};
+	};
+
+	/* External root clock */
+	extal_clk: extal {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		/* This value must be overriden by the board. */
+		clock-frequency = <0>;
+	};
+
+	/* External USB clock - can be overridden by the board */
+	usb_extal_clk: usb_extal {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <48000000>;
+	};
+
+	/* External SCIF clock */
+	scif_clk: scif {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		/* This value must be overridden by the board. */
+		clock-frequency = <0>;
+	};
+};

^ permalink raw reply

* [PATCH v5 2/7] ARM: dts: r8a7743: add SYS-DMAC support
From: Sergei Shtylyov @ 2016-10-27 21:37 UTC (permalink / raw)
  To: horms, linux-renesas-soc, robh+dt, mark.rutland, devicetree
  Cc: magnus.damm, linux, linux-arm-kernel
In-Reply-To: <1580369.yToZzJza1l@wasted.cogentembedded.com>

Describe SYS-DMAC0/1 in the R8A7743 device tree.

Based on the original (and large) patch by Dmitry Shifrin
<dmitry.shifrin@cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

---
Changes in version 5:
- refreshed the patch.

Changes in version 4:
- refreshed the patch.

Changes in version 3:
- resolved a reject;
- updated the "clocks" properties for the CPG/MSSR driver.

Changes in version 2:
- added Geert's tag.

 arch/arm/boot/dts/r8a7743.dtsi |   64 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7743.dtsi
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7743.dtsi
+++ renesas/arch/arm/boot/dts/r8a7743.dtsi
@@ -93,6 +93,70 @@
 			compatible = "renesas,r8a7743-rst";
 			reg = <0 0xe6160000 0 0x0200>;
 		};
+
+		dmac0: dma-controller@e6700000 {
+			compatible = "renesas,dmac-r8a7743",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6700000 0 0x20000>;
+			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5", "ch6", "ch7",
+					"ch8", "ch9", "ch10", "ch11",
+					"ch12", "ch13", "ch14";
+			clocks = <&cpg CPG_MOD 219>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			#dma-cells = <1>;
+			dma-channels = <15>;
+		};
+
+		dmac1: dma-controller@e6720000 {
+			compatible = "renesas,dmac-r8a7743",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6720000 0 0x20000>;
+			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5", "ch6", "ch7",
+					"ch8", "ch9", "ch10", "ch11",
+					"ch12", "ch13", "ch14";
+			clocks = <&cpg CPG_MOD 218>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			#dma-cells = <1>;
+			dma-channels = <15>;
+		};
 	};
 
 	/* External root clock */

^ permalink raw reply

* [PATCH v5 3/7] ARM: dts: r8a7743: add [H]SCIF{A|B} support
From: Sergei Shtylyov @ 2016-10-27 21:37 UTC (permalink / raw)
  To: horms, linux-renesas-soc, robh+dt, mark.rutland, devicetree
  Cc: magnus.damm, linux, linux-arm-kernel
In-Reply-To: <1580369.yToZzJza1l@wasted.cogentembedded.com>

Describe [H]SCIF{|A|B} ports in the R8A7743 device tree.

Based on the original (and large) patch by Dmitry Shifrin
<dmitry.shifrin@cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

---
Changes in version 5:
- refreshed the patch.

Changes in version 4:
- corrected RBNF in the patch description/subject;
- used the R-Car gen2 bindings instead of the RZ/G family ones;
- refreshed the patch;
- added Geert's tag.

Changes in version 3:
- resolved  a reject;
- updated the "clocks" properties for the CPG/MSSR driver;
- renamed the patch.

Changes in version 2:
- used  the new RZ/G family "compatible" prop values, reformatting where needed;
- fixed the size cells of the SCIFB device nodes' "reg" properties;
- changed the size cells of the "reg" properties to hexadecimal;
- indented the SCIFA1 device node's closing brace correctly
- adjusted the patch description, renamed the patch.

 arch/arm/boot/dts/r8a7743.dtsi |  261 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 261 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7743.dtsi
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7743.dtsi
+++ renesas/arch/arm/boot/dts/r8a7743.dtsi
@@ -157,6 +157,267 @@
 			#dma-cells = <1>;
 			dma-channels = <15>;
 		};
+
+		scifa0: serial@e6c40000 {
+			compatible = "renesas,scifa-r8a7743",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c40000 0 0x40>;
+			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 204>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x21>, <&dmac0 0x22>,
+			       <&dmac1 0x21>, <&dmac1 0x22>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scifa1: serial@e6c50000 {
+			compatible = "renesas,scifa-r8a7743",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c50000 0 0x40>;
+			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 203>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x25>, <&dmac0 0x26>,
+			       <&dmac1 0x25>, <&dmac1 0x26>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scifa2: serial@e6c60000 {
+			compatible = "renesas,scifa-r8a7743",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c60000 0 0x40>;
+			interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 202>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x27>, <&dmac0 0x28>,
+			       <&dmac1 0x27>, <&dmac1 0x28>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scifa3: serial@e6c70000 {
+			compatible = "renesas,scifa-r8a7743",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c70000 0 0x40>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1106>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x1b>, <&dmac0 0x1c>,
+			       <&dmac1 0x1b>, <&dmac1 0x1c>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scifa4: serial@e6c78000 {
+			compatible = "renesas,scifa-r8a7743",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c78000 0 0x40>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1107>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x1f>, <&dmac0 0x20>,
+			       <&dmac1 0x1f>, <&dmac1 0x20>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scifa5: serial@e6c80000 {
+			compatible = "renesas,scifa-r8a7743",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c80000 0 0x40>;
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1108>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x23>, <&dmac0 0x24>,
+			       <&dmac1 0x23>, <&dmac1 0x24>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scifb0: serial@e6c20000 {
+			compatible = "renesas,scifb-r8a7743",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6c20000 0 0x100>;
+			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 206>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x3d>, <&dmac0 0x3e>,
+		       <&dmac1 0x3d>, <&dmac1 0x3e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scifb1: serial@e6c30000 {
+			compatible = "renesas,scifb-r8a7743",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6c30000 0 0x100>;
+			interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 207>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x19>, <&dmac0 0x1a>,
+			       <&dmac1 0x19>, <&dmac1 0x1a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scifb2: serial@e6ce0000 {
+			compatible = "renesas,scifb-r8a7743",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6ce0000 0 0x100>;
+			interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 216>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x1d>, <&dmac0 0x1e>,
+			       <&dmac1 0x1d>, <&dmac1 0x1e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scif0: serial@e6e60000 {
+			compatible = "renesas,scif-r8a7743",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6e60000 0 0x40>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 721>,
+			         <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x29>, <&dmac0 0x2a>,
+			       <&dmac1 0x29>, <&dmac1 0x2a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scif1: serial@e6e68000 {
+			compatible = "renesas,scif-r8a7743",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6e68000 0 0x40>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 720>,
+			         <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2d>, <&dmac0 0x2e>,
+			       <&dmac1 0x2d>, <&dmac1 0x2e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scif2: serial@e6e58000 {
+			compatible = "renesas,scif-r8a7743",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6e58000 0 0x40>;
+			interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 719>,
+			         <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2b>, <&dmac0 0x2c>,
+			       <&dmac1 0x2b>, <&dmac1 0x2c>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scif3: serial@e6ea8000 {
+			compatible = "renesas,scif-r8a7743",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6ea8000 0 0x40>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 718>,
+			         <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2f>, <&dmac0 0x30>,
+			       <&dmac1 0x2f>, <&dmac1 0x30>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scif4: serial@e6ee0000 {
+			compatible = "renesas,scif-r8a7743",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6ee0000 0 0x40>;
+			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 715>,
+			         <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0xfb>, <&dmac0 0xfc>,
+			       <&dmac1 0xfb>, <&dmac1 0xfc>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scif5: serial@e6ee8000 {
+			compatible = "renesas,scif-r8a7743",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6ee8000 0 0x40>;
+			interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 714>,
+			         <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0xfd>, <&dmac0 0xfe>,
+			       <&dmac1 0xfd>, <&dmac1 0xfe>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		hscif0: serial@e62c0000 {
+			compatible = "renesas,hscif-r8a7743",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62c0000 0 0x60>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 717>,
+			         <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x39>, <&dmac0 0x3a>,
+			       <&dmac1 0x39>, <&dmac1 0x3a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		hscif1: serial@e62c8000 {
+			compatible = "renesas,hscif-r8a7743",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62c8000 0 0x60>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 716>,
+			         <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x4d>, <&dmac0 0x4e>,
+			       <&dmac1 0x4d>, <&dmac1 0x4e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		hscif2: serial@e62d0000 {
+			compatible = "renesas,hscif-r8a7743",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62d0000 0 0x60>;
+			interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 713>,
+			         <&cpg CPG_CORE R8A7743_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x3b>, <&dmac0 0x3c>,
+			       <&dmac1 0x3b>, <&dmac1 0x3c>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
 	};
 
 	/* External root clock */

^ permalink raw reply

* [PATCH v5 4/7] ARM: dts: r8a7743: add Ether support
From: Sergei Shtylyov @ 2016-10-27 21:38 UTC (permalink / raw)
  To: horms-/R6kz+dDXgpPR4JQBCEnsQ,
	linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: magnus.damm-Re5JQEeQqe8AvxtiuMwx3w, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1580369.yToZzJza1l-gHKXc3Y1Z8zGSmamagVegGFoWSdPRAKMAL8bYrjMMd8@public.gmane.org>

Define the generic R8A7743 part of the Ether device node.

Based on the original (and large) patch by Dmitry Shifrin
<dmitry.shifrin-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
Reviewed-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>

---
Changes in version 5:
- refreshed the patch.

Changes in version 4:
- refreshed the patch;
- added Geert's tag.

Changes in version 3:
- resolved a reject;
- updated the "clocks" property for the CPG/MSSR driver.

Changes in version 2:
- new patch.

 arch/arm/boot/dts/r8a7743.dtsi |   12 ++++++++++++
 1 file changed, 12 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7743.dtsi
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7743.dtsi
+++ renesas/arch/arm/boot/dts/r8a7743.dtsi
@@ -418,6 +418,18 @@
 			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
 			status = "disabled";
 		};
+
+		ether: ethernet@ee700000 {
+			compatible = "renesas,ether-r8a7743";
+			reg = <0 0xee700000 0 0x400>;
+			interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 813>;
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+			phy-mode = "rmii";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
 	};
 
 	/* External root clock */

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v5 5/7] ARM: dts: r8a7743: add IRQC support
From: Sergei Shtylyov @ 2016-10-27 21:39 UTC (permalink / raw)
  To: horms, linux-renesas-soc, robh+dt, mark.rutland, devicetree
  Cc: magnus.damm, linux, linux-arm-kernel
In-Reply-To: <1580369.yToZzJza1l@wasted.cogentembedded.com>

Describe the IRQC interrupt controller in the R8A7743 device tree.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

---
Changes in version 4:
- refreshed the patch;
- added Geert's tag.

Changes in version 3:
- updated the "clocks" property for the CPG/MSSR driver.

Changes in version 2:
- new patch.

 arch/arm/boot/dts/r8a7743.dtsi |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7743.dtsi
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7743.dtsi
+++ renesas/arch/arm/boot/dts/r8a7743.dtsi
@@ -62,6 +62,25 @@
 						 IRQ_TYPE_LEVEL_HIGH)>;
 		};
 
+		irqc: interrupt-controller@e61c0000 {
+			compatible = "renesas,irqc-r8a7743", "renesas,irqc";
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			reg = <0 0xe61c0000 0 0x200>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 407>;
+			power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+		};
+
 		timer {
 			compatible = "arm,armv7-timer";
 			interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |

^ permalink raw reply

* [PATCH v5 6/7] ARM: dts: sk-rzg1m: initial device tree
From: Sergei Shtylyov @ 2016-10-27 21:40 UTC (permalink / raw)
  To: horms, linux-renesas-soc, robh+dt, mark.rutland, devicetree
  Cc: magnus.damm, linux, linux-arm-kernel
In-Reply-To: <1580369.yToZzJza1l@wasted.cogentembedded.com>

Add the initial device  tree for the R8A7743 SoC based SK-RZG1M board.
The board has one debug serial port (SCIF0); include support for it, so
that  the serial  console  can work.

Based on the original (and large) patch by Dmitry Shifrin
<dmitry.shifrin@cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

---
Changes in version 4:
- refreshed the patch.

Changes in version 3:
- added Geert's tag.

 arch/arm/boot/dts/Makefile             |    1 
 arch/arm/boot/dts/r8a7743-sk-rzg1m.dts |   44 +++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)

Index: renesas/arch/arm/boot/dts/Makefile
===================================================================
--- renesas.orig/arch/arm/boot/dts/Makefile
+++ renesas/arch/arm/boot/dts/Makefile
@@ -677,6 +677,7 @@ dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
 	r7s72100-rskrza1.dtb \
 	r8a73a4-ape6evm.dtb \
 	r8a7740-armadillo800eva.dtb \
+	r8a7743-sk-rzg1m.dtb \
 	r8a7778-bockw.dtb \
 	r8a7779-marzen.dtb \
 	r8a7790-lager.dtb \
Index: renesas/arch/arm/boot/dts/r8a7743-sk-rzg1m.dts
===================================================================
--- /dev/null
+++ renesas/arch/arm/boot/dts/r8a7743-sk-rzg1m.dts
@@ -0,0 +1,44 @@
+/*
+ * Device Tree Source for the SK-RZG1M board
+ *
+ * Copyright (C) 2016 Cogent Embedded, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "r8a7743.dtsi"
+
+/ {
+	model = "SK-RZG1M";
+	compatible = "renesas,sk-rzg1m", "renesas,r8a7743";
+
+	aliases {
+		serial0 = &scif0;
+	};
+
+	chosen {
+		bootargs = "ignore_loglevel";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0 0x40000000>;
+	};
+
+	memory@200000000 {
+		device_type = "memory";
+		reg = <2 0x00000000 0 0x40000000>;
+	};
+};
+
+&extal_clk {
+	clock-frequency = <20000000>;
+};
+
+&scif0 {
+	status = "okay";
+};

^ permalink raw reply

* [PATCH v5 7/7] ARM: dts: sk-rzg1m: add Ether support
From: Sergei Shtylyov @ 2016-10-27 21:41 UTC (permalink / raw)
  To: horms, linux-renesas-soc, robh+dt, mark.rutland, devicetree
  Cc: magnus.damm, linux, linux-arm-kernel
In-Reply-To: <1580369.yToZzJza1l@wasted.cogentembedded.com>

Define the SK-RZG1M board dependent part of the Ether device node.
Enable DHCP and NFS root  for the kernel booting.

Based on the original (and large) patch by Dmitry Shifrin
<dmitry.shifrin@cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

---
Changes in version 4:
- added Geert's tag.

Changes in version 2:
- new patch.

 arch/arm/boot/dts/r8a7743-sk-rzg1m.dts |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

Index: renesas/arch/arm/boot/dts/r8a7743-sk-rzg1m.dts
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7743-sk-rzg1m.dts
+++ renesas/arch/arm/boot/dts/r8a7743-sk-rzg1m.dts
@@ -20,7 +20,7 @@
 	};
 
 	chosen {
-		bootargs = "ignore_loglevel";
+		bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
 		stdout-path = "serial0:115200n8";
 	};
 
@@ -42,3 +42,16 @@
 &scif0 {
 	status = "okay";
 };
+
+&ether {
+	phy-handle = <&phy1>;
+	renesas,ether-link-active-low;
+	status = "okay";
+
+	phy1: ethernet-phy@1 {
+		reg = <1>;
+		interrupt-parent = <&irqc>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		micrel,led-mode = <1>;
+	};
+};

^ permalink raw reply

* [PATCH v3 0/3] cpufreq: Introduce TI CPUFreq/OPP Driver
From: Dave Gerlach @ 2016-10-27 21:41 UTC (permalink / raw)
  To: Viresh Kumar, Rob Herring
  Cc: linux-arm-kernel, linux-omap, linux-pm, devicetree,
	Rafael J . Wysocki, Tony Lindgren, Nishanth Menon, Dave Gerlach

Hi,
This series is v3 of the series to introduce the ti-cpufreq driver
which parses SoC data and provides opp-supported-hw data to the
OPP core in order to enable the proper OPPs for the silicon in use.
v2 of this series can be found here [1].

Several changes to the dt-binding and ti-cpufreq driver are
present in v3, which are described in detail under scissors line
in patches but mostly focused on moving properties that were added
in cpu node previously to the operating-points node and updating
driver to reflect these changes, along with using a common compatible
for all ti platforms. Also, a new patch was added to expose an internal
OPP core API to allow a common way to get a reference to the OPP table
from a platform driver.

I have just sent the driver and binding here but have held off on the
updated DT nodes, I will send these out once we can agree on the binding
and driver changes but have pushed them if anyone is curious here [2].

Regards,
Dave

[1] http://www.spinics.net/lists/linux-omap/msg131601.html
[2] https://github.com/dgerlach/linux-pm/tree/upstream/v4.9/ti-cpufreq-driver-v3

Dave Gerlach (3):
  PM / OPP: Expose _of_get_opp_desc_node as dev_pm_opp API
  Documentation: dt: add bindings for ti-cpufreq
  cpufreq: ti: Add cpufreq driver to determine available OPPs at runtime

 .../devicetree/bindings/cpufreq/ti-cpufreq.txt     | 132 ++++++++++
 drivers/base/power/opp/of.c                        |   8 +-
 drivers/base/power/opp/opp.h                       |   1 -
 drivers/cpufreq/Kconfig.arm                        |  11 +
 drivers/cpufreq/Makefile                           |   1 +
 drivers/cpufreq/ti-cpufreq.c                       | 288 +++++++++++++++++++++
 include/linux/pm_opp.h                             |   6 +
 7 files changed, 442 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt
 create mode 100644 drivers/cpufreq/ti-cpufreq.c

-- 
2.9.3


^ permalink raw reply

* [PATCH v3 1/3] PM / OPP: Expose _of_get_opp_desc_node as dev_pm_opp API
From: Dave Gerlach @ 2016-10-27 21:41 UTC (permalink / raw)
  To: Viresh Kumar, Rob Herring
  Cc: linux-arm-kernel, linux-omap, linux-pm, devicetree,
	Rafael J . Wysocki, Tony Lindgren, Nishanth Menon, Dave Gerlach
In-Reply-To: <20161027214131.1725-1-d-gerlach@ti.com>

Move _of_get_opp_desc_node into include/linux/pm_opp.h and rename it
dev_pm_opp_of_get_opp_desc_node to allow other drivers, such as platform
OPP and cpufreq drivers, to make use of it.

Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
---
 drivers/base/power/opp/of.c  | 8 ++++----
 drivers/base/power/opp/opp.h | 1 -
 include/linux/pm_opp.h       | 6 ++++++
 3 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/base/power/opp/of.c b/drivers/base/power/opp/of.c
index 5552211e6fcd..215f5a538c78 100644
--- a/drivers/base/power/opp/of.c
+++ b/drivers/base/power/opp/of.c
@@ -198,7 +198,7 @@ void dev_pm_opp_of_remove_table(struct device *dev)
 EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table);
 
 /* Returns opp descriptor node for a device, caller must do of_node_put() */
-struct device_node *_of_get_opp_desc_node(struct device *dev)
+struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev)
 {
 	/*
 	 * TODO: Support for multiple OPP tables.
@@ -450,7 +450,7 @@ int dev_pm_opp_of_add_table(struct device *dev)
 	 * OPPs have two version of bindings now. The older one is deprecated,
 	 * try for the new binding first.
 	 */
-	opp_np = _of_get_opp_desc_node(dev);
+	opp_np = dev_pm_opp_of_get_opp_desc_node(dev);
 	if (!opp_np) {
 		/*
 		 * Try old-deprecated bindings for backward compatibility with
@@ -560,7 +560,7 @@ int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev,
 	int cpu, ret = 0;
 
 	/* Get OPP descriptor node */
-	np = _of_get_opp_desc_node(cpu_dev);
+	np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
 	if (!np) {
 		dev_dbg(cpu_dev, "%s: Couldn't find cpu_dev node.\n", __func__);
 		return -ENOENT;
@@ -585,7 +585,7 @@ int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev,
 		}
 
 		/* Get OPP descriptor node */
-		tmp_np = _of_get_opp_desc_node(tcpu_dev);
+		tmp_np = dev_pm_opp_of_get_opp_desc_node(tcpu_dev);
 		if (!tmp_np) {
 			dev_err(tcpu_dev, "%s: Couldn't find tcpu_dev node.\n",
 				__func__);
diff --git a/drivers/base/power/opp/opp.h b/drivers/base/power/opp/opp.h
index fabd5ca1a083..96cd30ac6c1d 100644
--- a/drivers/base/power/opp/opp.h
+++ b/drivers/base/power/opp/opp.h
@@ -190,7 +190,6 @@ struct opp_table {
 /* Routines internal to opp core */
 struct opp_table *_find_opp_table(struct device *dev);
 struct opp_device *_add_opp_dev(const struct device *dev, struct opp_table *opp_table);
-struct device_node *_of_get_opp_desc_node(struct device *dev);
 void _dev_pm_opp_remove_table(struct device *dev, bool remove_all);
 struct dev_pm_opp *_allocate_opp(struct device *dev, struct opp_table **opp_table);
 int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, struct opp_table *opp_table);
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index bca26157f5b6..9e8c138f55b7 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -208,6 +208,7 @@ void dev_pm_opp_of_remove_table(struct device *dev);
 int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask);
 void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask);
 int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask);
+struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev);
 #else
 static inline int dev_pm_opp_of_add_table(struct device *dev)
 {
@@ -231,6 +232,11 @@ static inline int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, struct
 {
 	return -ENOTSUPP;
 }
+
+static inline struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev)
+{
+	return NULL;
+}
 #endif
 
 #endif		/* __LINUX_OPP_H__ */
-- 
2.9.3


^ permalink raw reply related

* [PATCH v3 2/3] Documentation: dt: add bindings for ti-cpufreq
From: Dave Gerlach @ 2016-10-27 21:41 UTC (permalink / raw)
  To: Viresh Kumar, Rob Herring
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rafael J . Wysocki,
	Tony Lindgren, Nishanth Menon, Dave Gerlach
In-Reply-To: <20161027214131.1725-1-d-gerlach-l0cyMroinI0@public.gmane.org>

Add the device tree bindings document for the TI CPUFreq/OPP driver
on AM33xx and AM43xx SoCs. The operating-points-v2 binding allows us
to provide an opp-supported-hw property for each OPP to define when
it is available. This driver is responsible for reading and parsing
registers to determine which OPPs can be selectively enabled based
on the specific SoC in use by matching against the opp-supported-hw
data.

Signed-off-by: Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org>
---
v2->v3:
- Move ti,syscon-* properties under opp table instead of cpu node, as
  that is a better location for them.
- For the opp table do not use platform specific compatible strings
  but instead a operating-points-v2-ti-cpu

 .../devicetree/bindings/cpufreq/ti-cpufreq.txt     | 132 +++++++++++++++++++++
 1 file changed, 132 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt

diff --git a/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt b/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt
new file mode 100644
index 000000000000..467ad29c75c9
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt
@@ -0,0 +1,132 @@
+TI CPUFreq and OPP bindings
+================================
+
+Certain TI SoCs, like those in the am335x, am437x, am57xx, and dra7xx
+families support different OPPs depending on the silicon variant in use.
+The ti_cpufreq driver can use revision and an efuse value from the SoC to
+provide the OPP framework with supported hardware information. This is
+used to determine which OPPs from the operating-points-v2 table get enabled
+when it is parsed by the OPP framework.
+
+Required properties:
+--------------------
+In 'cpus' nodes:
+- operating-points-v2: Phandle to the operating-points-v2 table to use.
+
+In 'operating-points-v2' table:
+- compatible: Should be 'operating-points-v2-ti-cpu' for am335x, am43xx,
+	      and dra7xx/am57xx SoCs
+- ti,syscon-efuse: Syscon phandle, offset to efuse register, efuse register
+		   mask, and efuse register shift to get the relevant bits
+		   that describe OPP availability.
+- ti,syscon-rev: Syscon and offset used to look up revision value on SoC.
+
+Optional properties:
+--------------------
+For each opp entry in 'operating-points-v2' table:
+- opp-supported-hw: Two bitfields indicating:
+	1. Which revision of the SoC the OPP is supported by
+	2. Which eFuse bits indicate this OPP is available
+
+	A bitwise AND is performed against these values and if any bit
+	matches, the OPP gets enabled. Not providing the property for an
+	entry indicates that an OPP is always supported.
+
+Example:
+--------
+
+/* From arch/arm/boot/dts/am33xx.dtsi */
+cpus {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	cpu@0 {
+		compatible = "arm,cortex-a8";
+		device_type = "cpu";
+		reg = <0>;
+
+		operating-points-v2 = <&cpu0_opp_table>;
+
+		clocks = <&dpll_mpu_ck>;
+		clock-names = "cpu";
+
+		clock-latency = <300000>; /* From omap-cpufreq driver */
+	};
+};
+
+/*
+ * cpu0 has different OPPs depending on SoC revision and some on revisions
+ * 0x2 and 0x4 have eFuse bits that indicate if they are available or not
+ */
+cpu0_opp_table: opp_table0 {
+	compatible = "operating-points-v2-ti-am3352-cpu";
+	ti,syscon-efuse = <&scm_conf 0x7fc 0x1fff 0>;
+	ti,syscon-rev = <&scm_conf 0x600>;
+
+	/*
+	 * The three following nodes are marked with opp-suspend
+	 * because they can not be enabled simultaneously on a
+	 * single SoC.
+	 */
+	opp50@300000000 {
+		opp-hz = /bits/ 64 <300000000>;
+		opp-microvolt = <950000 931000 969000>;
+		opp-supported-hw = <0x06 0x0010>;
+		opp-suspend;
+	};
+
+	opp100@275000000 {
+		opp-hz = /bits/ 64 <275000000>;
+		opp-microvolt = <1100000 1078000 1122000>;
+		opp-supported-hw = <0x01 0x00FF>;
+		opp-suspend;
+	};
+
+	opp100@300000000 {
+		opp-hz = /bits/ 64 <300000000>;
+		opp-microvolt = <1100000 1078000 1122000>;
+		opp-supported-hw = <0x06 0x0020>;
+		opp-suspend;
+	};
+
+	opp100@500000000 {
+		opp-hz = /bits/ 64 <500000000>;
+		opp-microvolt = <1100000 1078000 1122000>;
+		opp-supported-hw = <0x01 0xFFFF>;
+	};
+
+	opp100@600000000 {
+		opp-hz = /bits/ 64 <600000000>;
+		opp-microvolt = <1100000 1078000 1122000>;
+		opp-supported-hw = <0x06 0x0040>;
+	};
+
+	opp120@600000000 {
+		opp-hz = /bits/ 64 <600000000>;
+		opp-microvolt = <1200000 1176000 1224000>;
+		opp-supported-hw = <0x01 0xFFFF>;
+	};
+
+	opp120@720000000 {
+		opp-hz = /bits/ 64 <720000000>;
+		opp-microvolt = <1200000 1176000 1224000>;
+		opp-supported-hw = <0x06 0x0080>;
+	};
+
+	oppturbo@720000000 {
+		opp-hz = /bits/ 64 <720000000>;
+		opp-microvolt = <1260000 1234800 1285200>;
+		opp-supported-hw = <0x01 0xFFFF>;
+	};
+
+	oppturbo@800000000 {
+		opp-hz = /bits/ 64 <800000000>;
+		opp-microvolt = <1260000 1234800 1285200>;
+		opp-supported-hw = <0x06 0x0100>;
+	};
+
+	oppnitro@1000000000 {
+		opp-hz = /bits/ 64 <1000000000>;
+		opp-microvolt = <1325000 1298500 1351500>;
+		opp-supported-hw = <0x04 0x0200>;
+	};
+};
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v3 3/3] cpufreq: ti: Add cpufreq driver to determine available OPPs at runtime
From: Dave Gerlach @ 2016-10-27 21:41 UTC (permalink / raw)
  To: Viresh Kumar, Rob Herring
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-pm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rafael J . Wysocki,
	Tony Lindgren, Nishanth Menon, Dave Gerlach
In-Reply-To: <20161027214131.1725-1-d-gerlach-l0cyMroinI0@public.gmane.org>

Some TI SoCs, like those in the AM335x, AM437x, DRA7x, and AM57x families,
have different OPPs available for the MPU depending on which specific
variant of the SoC is in use. This can be determined through use of the
revision and an eFuse register present in the silicon. Introduce a
ti-cpufreq driver that can read the aformentioned values and provide
them as version matching data to the opp framework. Through this the
opp-supported-hw dt binding that is part of the operating-points-v2
table can be used to indicate availability of OPPs for each device.

This driver also creates the "cpufreq-dt" platform_device after passing
the version matching data to the OPP framework so that the cpufreq-dt
handles the actual cpufreq implementation. Even without the necessary
data to pass the version matching data the driver will still create this
device to maintain backwards compatibility with operating-points v1
tables.

Signed-off-by: Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org>
---
v2-v3:
 - Use common ti compatible as described in binding and then match
   against machine type for platform data.
 - Use newly exposed dev_pm_opp_of_get_opp_desc_node to get
   operating-points-v2 table now that properties needed by driver are
   there.
 - Parse syscon properties from operating-points-v2 node rather
   than cpu node.
 - Do not make ti-cpufreq a module-platform-driver and do not allow
   building as module.

 drivers/cpufreq/Kconfig.arm  |  11 ++
 drivers/cpufreq/Makefile     |   1 +
 drivers/cpufreq/ti-cpufreq.c | 288 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 300 insertions(+)
 create mode 100644 drivers/cpufreq/ti-cpufreq.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index d89b8afe23b6..665f11dbdaef 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -234,6 +234,17 @@ config ARM_TEGRA124_CPUFREQ
 	help
 	  This adds the CPUFreq driver support for Tegra124 SOCs.
 
+config ARM_TI_CPUFREQ
+	bool "Texas Instruments CPUFreq support"
+	depends on ARCH_OMAP2PLUS
+	help
+	  This driver enables valid OPPs on the running platform based on
+	  values contained within the SoC in use. Enable this in order to
+	  use the cpufreq-dt driver on all Texas Instruments platforms that
+	  provide dt based operating-points-v2 tables with opp-supported-hw
+	  data provided. Required for cpufreq support on AM335x, AM437x,
+	  DRA7x, and AM57x platforms.
+
 config ARM_PXA2xx_CPUFREQ
 	tristate "Intel PXA2xx CPUfreq driver"
 	depends on PXA27x || PXA25x
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 0a9b6a093646..5b1b6ec0a9f0 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -77,6 +77,7 @@ obj-$(CONFIG_ARM_SPEAR_CPUFREQ)		+= spear-cpufreq.o
 obj-$(CONFIG_ARM_STI_CPUFREQ)		+= sti-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA20_CPUFREQ)	+= tegra20-cpufreq.o
 obj-$(CONFIG_ARM_TEGRA124_CPUFREQ)	+= tegra124-cpufreq.o
+obj-$(CONFIG_ARM_TI_CPUFREQ)		+= ti-cpufreq.o
 obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ)	+= vexpress-spc-cpufreq.o
 obj-$(CONFIG_ACPI_CPPC_CPUFREQ) += cppc_cpufreq.o
 obj-$(CONFIG_MACH_MVEBU_V7)		+= mvebu-cpufreq.o
diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c
new file mode 100644
index 000000000000..afbaef967b65
--- /dev/null
+++ b/drivers/cpufreq/ti-cpufreq.c
@@ -0,0 +1,288 @@
+/*
+ * TI CPUFreq/OPP hw-supported driver
+ *
+ * Copyright (C) 2016 Texas Instruments, Inc.
+ *	 Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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/cpu.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/pm_opp.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define REVISION_MASK				0xF
+#define REVISION_SHIFT				28
+
+#define AM33XX_800M_ARM_MPU_MAX_FREQ		0x1E2F
+#define AM43XX_600M_ARM_MPU_MAX_FREQ		0xFFA
+
+#define DRA7_EFUSE_HAS_OD_MPU_OPP		11
+#define DRA7_EFUSE_HAS_HIGH_MPU_OPP		15
+#define DRA7_EFUSE_HAS_ALL_MPU_OPP		23
+
+#define DRA7_EFUSE_NOM_MPU_OPP			BIT(0)
+#define DRA7_EFUSE_OD_MPU_OPP			BIT(1)
+#define DRA7_EFUSE_HIGH_MPU_OPP			BIT(2)
+
+#define VERSION_COUNT				2
+
+struct ti_cpufreq_data;
+
+struct ti_cpufreq_soc_data {
+	unsigned long (*efuse_xlate)(struct ti_cpufreq_data *opp_data,
+				     unsigned long efuse);
+	unsigned long efuse_fallback;
+};
+
+struct ti_cpufreq_data {
+	struct device *cpu_dev;
+	struct device_node *opp_node;
+	struct regmap *opp_efuse;
+	struct regmap *revision;
+	const struct ti_cpufreq_soc_data *soc_data;
+};
+
+static unsigned long amx3_efuse_xlate(struct ti_cpufreq_data *opp_data,
+				      unsigned long efuse)
+{
+	if (!efuse)
+		efuse = opp_data->soc_data->efuse_fallback;
+	/* AM335x and AM437x use "OPP disable" bits, so invert */
+	return ~efuse;
+}
+
+static unsigned long dra7_efuse_xlate(struct ti_cpufreq_data *opp_data,
+				      unsigned long efuse)
+{
+	unsigned long calculated_efuse = DRA7_EFUSE_NOM_MPU_OPP;
+
+	/*
+	 * The efuse on dra7 and am57 parts contains a specific
+	 * value indicating the highest available OPP.
+	 */
+
+	switch (efuse) {
+	case DRA7_EFUSE_HAS_ALL_MPU_OPP:
+	case DRA7_EFUSE_HAS_HIGH_MPU_OPP:
+		calculated_efuse |= DRA7_EFUSE_HIGH_MPU_OPP;
+	case DRA7_EFUSE_HAS_OD_MPU_OPP:
+		calculated_efuse |= DRA7_EFUSE_OD_MPU_OPP;
+	}
+
+	return calculated_efuse;
+}
+
+static struct ti_cpufreq_soc_data am3x_soc_data = {
+	.efuse_xlate = amx3_efuse_xlate,
+	.efuse_fallback = AM33XX_800M_ARM_MPU_MAX_FREQ,
+};
+
+static struct ti_cpufreq_soc_data am4x_soc_data = {
+	.efuse_xlate = amx3_efuse_xlate,
+	.efuse_fallback = AM43XX_600M_ARM_MPU_MAX_FREQ,
+};
+
+static struct ti_cpufreq_soc_data dra7_soc_data = {
+	.efuse_xlate = dra7_efuse_xlate,
+};
+
+/**
+ * ti_cpufreq_get_efuse() - Parse and return efuse value present on SoC
+ * @opp_data: pointer to ti_cpufreq_data context
+ * @efuse_value: Set to the value parsed from efuse
+ *
+ * Returns error code if efuse not read properly.
+ */
+static int ti_cpufreq_get_efuse(struct ti_cpufreq_data *opp_data,
+				u32 *efuse_value)
+{
+	struct device *dev = opp_data->cpu_dev;
+	struct device_node *np = opp_data->opp_node;
+	unsigned int efuse_offset;
+	u32 efuse, efuse_mask, efuse_shift, vals[4];
+	int ret;
+
+	ret = of_property_read_u32_array(np, "ti,syscon-efuse", vals, 4);
+	if (ret) {
+		dev_err(dev, "ti,syscon-efuse cannot be read %s: %d\n",
+			np->full_name, ret);
+		return ret;
+	}
+
+	efuse_offset = vals[1];
+	efuse_mask = vals[2];
+	efuse_shift = vals[3];
+
+	ret = regmap_read(opp_data->opp_efuse, efuse_offset, &efuse);
+	if (ret) {
+		dev_err(dev,
+			"Failed to read the efuse value from syscon: %d\n",
+			ret);
+		return ret;
+	}
+
+	efuse = (efuse & efuse_mask) >> efuse_shift;
+
+	*efuse_value = opp_data->soc_data->efuse_xlate(opp_data, efuse);
+
+	return 0;
+}
+
+/**
+ * ti_cpufreq_get_rev() - Parse and return rev value present on SoC
+ * @opp_data: pointer to ti_cpufreq_data context
+ * @revision_value: Set to the value parsed from revision register
+ *
+ * Returns error code if revision not read properly.
+ */
+static int ti_cpufreq_get_rev(struct ti_cpufreq_data *opp_data,
+			      u32 *revision_value)
+{
+	struct device *dev = opp_data->cpu_dev;
+	struct device_node *np = opp_data->opp_node;
+	unsigned int revision_offset;
+	u32 revision;
+	int ret;
+
+	ret = of_property_read_u32_index(np, "ti,syscon-rev",
+					 1, &revision_offset);
+	if (ret) {
+		dev_err(dev,
+			"No revision offset provided %s [%d]\n",
+			np->full_name, ret);
+		return ret;
+	}
+
+	ret = regmap_read(opp_data->revision, revision_offset, &revision);
+	if (ret) {
+		dev_err(dev,
+			"Failed to read the revision number from syscon: %d\n",
+			ret);
+		return ret;
+	}
+
+	*revision_value = BIT((revision >> REVISION_SHIFT) & REVISION_MASK);
+
+	return 0;
+}
+
+static int ti_cpufreq_setup_syscon_registers(struct ti_cpufreq_data *opp_data)
+{
+	struct device *dev = opp_data->cpu_dev;
+	struct device_node *np = opp_data->opp_node;
+
+	opp_data->opp_efuse = syscon_regmap_lookup_by_phandle(np,
+							"ti,syscon-efuse");
+	if (IS_ERR(opp_data->opp_efuse)) {
+		dev_err(dev,
+			"\"ti,syscon-efuse\" is missing, cannot use OPPv2 table.\n");
+		return PTR_ERR(opp_data->opp_efuse);
+	}
+
+	opp_data->revision = syscon_regmap_lookup_by_phandle(np,
+							"ti,syscon-rev");
+	if (IS_ERR(opp_data->revision)) {
+		dev_err(dev,
+			"\"ti,syscon-rev\" is missing, cannot use OPPv2 table.\n");
+		return PTR_ERR(opp_data->revision);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id ti_cpufreq_of_match[] = {
+	{ .compatible = "ti,am33xx", .data = &am3x_soc_data, },
+	{ .compatible = "ti,am4372", .data = &am4x_soc_data, },
+	{ .compatible = "ti,dra7", .data = &dra7_soc_data },
+	{},
+};
+
+static int ti_cpufreq_init(void)
+{
+	u32 version[VERSION_COUNT];
+	struct device_node *np;
+	const struct of_device_id *match;
+	struct ti_cpufreq_data *opp_data;
+	int ret;
+
+	np = of_find_node_by_path("/");
+	match = of_match_node(ti_cpufreq_of_match, np);
+	if (!match)
+		return -ENODEV;
+
+	opp_data = kzalloc(sizeof(*opp_data), GFP_KERNEL);
+	if (!opp_data)
+		return -ENOMEM;
+
+	opp_data->soc_data = match->data;
+
+	opp_data->cpu_dev = get_cpu_device(0);
+	if (!opp_data->cpu_dev) {
+		pr_err("%s: Failed to get device for CPU0\n", __func__);
+		return -ENODEV;
+	}
+
+	opp_data->opp_node = dev_pm_opp_of_get_opp_desc_node(opp_data->cpu_dev);
+	if (!opp_data->opp_node) {
+		dev_info(opp_data->cpu_dev,
+			 "OPP-v2 not supported, cpufreq-dt will attempt to use legacy tables.\n");
+		goto register_cpufreq_dt;
+	}
+
+	ret = ti_cpufreq_setup_syscon_registers(opp_data);
+	if (ret)
+		goto fail_put_node;
+
+	/*
+	 * OPPs determine whether or not they are supported based on
+	 * two metrics:
+	 *	0 - SoC Revision
+	 *	1 - eFuse value
+	 */
+	ret = ti_cpufreq_get_rev(opp_data, &version[0]);
+	if (ret)
+		goto fail_put_node;
+
+	ret = ti_cpufreq_get_efuse(opp_data, &version[1]);
+	if (ret)
+		goto fail_put_node;
+
+	of_node_put(opp_data->opp_node);
+
+	ret = dev_pm_opp_set_supported_hw(opp_data->cpu_dev, version,
+					  VERSION_COUNT);
+	if (ret) {
+		dev_err(opp_data->cpu_dev,
+			"Failed to set supported hardware\n");
+		goto fail_put_node;
+	}
+
+register_cpufreq_dt:
+	platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+
+	return 0;
+
+fail_put_node:
+	of_node_put(opp_data->opp_node);
+
+	return ret;
+}
+module_init(ti_cpufreq_init);
+
+MODULE_DESCRIPTION("TI CPUFreq/OPP hw-supported driver");
+MODULE_AUTHOR("Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org>");
+MODULE_LICENSE("GPL v2");
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v2 0/3] Add TI SCI Reset Driver
From: Andrew F. Davis @ 2016-10-27 21:49 UTC (permalink / raw)
  To: Nishanth Menon, Tero Kristo, Santosh Shilimkar, Philipp Zabel,
	Rob Herring, Mark Rutland, Suman Anna
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Andrew F . Davis

Hello all,

This series adds a reset controller driver that uses the TI SCI
protocol to manage resets.

The TI SCI protocol is used to communicate with power management
controllers used by some SoCs. These controllers manage the various
power domains, clocks, and resets available on a SoC.

This series is based on drivers for TI SCI and the first two controlled
elements above, these series can be found here:

TI-SCI: http://www.spinics.net/lists/arm-kernel/msg536851.html
PM Domains: http://www.spinics.net/lists/devicetree/msg146621.html
Clocks: https://www.spinics.net/lists/linux-clk/msg12785.html

Thanks,
Andrew

Changes from v1:
 - Revised dt binding
 - CC Linux ARM list

Andrew F. Davis (3):
  Documentation: dt: reset: Add TI SCI reset binding
  dt-bindings: reset: Add K2G reset definitions
  reset: Add the TI SCI reset driver

 .../devicetree/bindings/reset/ti,sci-reset.txt     |  65 +++++
 MAINTAINERS                                        |   3 +
 drivers/reset/Kconfig                              |   9 +
 drivers/reset/Makefile                             |   1 +
 drivers/reset/reset-ti-sci.c                       | 262 +++++++++++++++++++++
 include/dt-bindings/reset/k2g.h                    |  22 ++
 6 files changed, 362 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reset/ti,sci-reset.txt
 create mode 100644 drivers/reset/reset-ti-sci.c
 create mode 100644 include/dt-bindings/reset/k2g.h

-- 
2.10.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v2 1/3] Documentation: dt: reset: Add TI SCI reset binding
From: Andrew F. Davis @ 2016-10-27 21:49 UTC (permalink / raw)
  To: Nishanth Menon, Tero Kristo, Santosh Shilimkar, Philipp Zabel,
	Rob Herring, Mark Rutland, Suman Anna
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Andrew F . Davis
In-Reply-To: <20161027214941.24641-1-afd-l0cyMroinI0@public.gmane.org>

Add TI SCI reset controller binding. This describes the DT binding
details for a reset controller node providing reset management services
to hardware blocks (reset consumers) using the Texas Instrument's System
Control Interface (TI SCI) protocol to communicate to a system controller
block present on the SoC.

Signed-off-by: Andrew F. Davis <afd-l0cyMroinI0@public.gmane.org>
[s-anna-l0cyMroinI0@public.gmane.org: revise the binding format]
Signed-off-by: Suman Anna <s-anna-l0cyMroinI0@public.gmane.org>
Signed-off-by: Nishanth Menon <nm-l0cyMroinI0@public.gmane.org>
---
 .../devicetree/bindings/reset/ti,sci-reset.txt     | 65 ++++++++++++++++++++++
 MAINTAINERS                                        |  1 +
 2 files changed, 66 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reset/ti,sci-reset.txt

diff --git a/Documentation/devicetree/bindings/reset/ti,sci-reset.txt b/Documentation/devicetree/bindings/reset/ti,sci-reset.txt
new file mode 100644
index 0000000..cb00679
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/ti,sci-reset.txt
@@ -0,0 +1,65 @@
+Texas Instruments System Control Interface (TI-SCI) Reset Controller
+=====================================================================
+
+Some TI SoCs contain a system controller (like the Power Management Micro
+Controller (PMMC) on Keystone K2G SoC) that are responsible for controlling
+the state of the various hardware modules present on the SoC. Communication
+between the host processor running an OS and the system controller happens
+through a protocol called TI System Control Interface (TI-SCI protocol).
+For TI SCI details, please refer to the document,
+Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
+
+TI-SCI Reset Controller Node
+============================
+This reset controller node uses the TI SCI protocol to perform the reset
+management of various hardware modules present on the SoC.
+
+Required properties:
+--------------------
+ - compatible	: Should be "ti,sci-reset"
+ - #reset-cells	: Should be 2. Please see the reset consumer node below for
+		  usage details.
+
+TI-SCI Reset Consumer Nodes
+===========================
+Each of the reset consumer nodes should have the following properties,
+in addition to their own properties.
+
+Required properties:
+--------------------
+ - resets	: A phandle and reset specifier pair, one pair for each reset
+		  signal that affects the device, or that the device manages.
+		  The phandle should point to the TI-SCI reset controller node,
+		  and the reset specifier should have 2 cell-values. The first
+		  cell should contain the device ID, the values of which are
+		  specified in the <dt-bindings/genpd/<soc>.h> include file.
+		  The second cell should contain the reset mask value used by
+		  system controller, the values of which are specified in the
+		  include file <dt-bindings/reset/<soc>.h>, where <soc> is the
+		  name of the SoC involved, for example 'k2g'.
+
+Please also refer to Documentation/devicetree/bindings/reset/reset.txt for
+common reset controller usage by consumers.
+
+Example:
+--------
+The following example demonstrates both a TI-SCI reset controller node and a
+consumer (a DSP device) on the K2G SoC.
+
+#include <dt-bindings/genpd/k2g.h>
+#include <dt-bindings/reset/k2g.h>
+
+pmmc: pmmc {
+	compatible = "ti,k2g-sci";
+
+	k2g_reset: k2g_reset {
+		compatible = "ti,sci-reset";
+		#reset-cells = <2>;
+	};
+};
+
+dsp0: dsp0 {
+	...
+	resets = <&k2g_reset K2G_DEV_CGEM0 K2G_DEV_CGEM0_DSP0_RESET>;
+	...
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 6e93976..d8068df 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11899,6 +11899,7 @@ F:	drivers/soc/ti/ti_sci_pm_domains.c
 F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
 F:	include/dt-bindings/clock/k2g.h
 F:	drivers/clk/keystone/sci-clk.c
+F:	Documentation/devicetree/bindings/reset/ti,sci-reset.txt
 
 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
 M:	Hans Verkuil <hverkuil-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org>
-- 
2.10.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v2 2/3] dt-bindings: reset: Add K2G reset definitions
From: Andrew F. Davis @ 2016-10-27 21:49 UTC (permalink / raw)
  To: Nishanth Menon, Tero Kristo, Santosh Shilimkar, Philipp Zabel,
	Rob Herring, Mark Rutland, Suman Anna
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Andrew F . Davis
In-Reply-To: <20161027214941.24641-1-afd-l0cyMroinI0@public.gmane.org>

Add identifiers for the K2G resets managed by the PMMC.

Signed-off-by: Andrew F. Davis <afd-l0cyMroinI0@public.gmane.org>
---
 MAINTAINERS                     |  1 +
 include/dt-bindings/reset/k2g.h | 22 ++++++++++++++++++++++
 2 files changed, 23 insertions(+)
 create mode 100644 include/dt-bindings/reset/k2g.h

diff --git a/MAINTAINERS b/MAINTAINERS
index d8068df..accf991 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11900,6 +11900,7 @@ F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
 F:	include/dt-bindings/clock/k2g.h
 F:	drivers/clk/keystone/sci-clk.c
 F:	Documentation/devicetree/bindings/reset/ti,sci-reset.txt
+F:	include/dt-bindings/reset/k2g.h
 
 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
 M:	Hans Verkuil <hverkuil-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org>
diff --git a/include/dt-bindings/reset/k2g.h b/include/dt-bindings/reset/k2g.h
new file mode 100644
index 0000000..00e2a9b
--- /dev/null
+++ b/include/dt-bindings/reset/k2g.h
@@ -0,0 +1,22 @@
+/*
+ * TI K2G SoC reset definitions
+ *
+ * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.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_RESET_K2G_H__
+#define __DT_BINDINGS_RESET_K2G_H__
+
+#define K2G_DEV_CGEM0_DSP0_RESET	0x1
+
+#endif
-- 
2.10.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v2 3/3] reset: Add the TI SCI reset driver
From: Andrew F. Davis @ 2016-10-27 21:49 UTC (permalink / raw)
  To: Nishanth Menon, Tero Kristo, Santosh Shilimkar, Philipp Zabel,
	Rob Herring, Mark Rutland, Suman Anna
  Cc: linux-arm-kernel, devicetree, linux-kernel, Andrew F . Davis
In-Reply-To: <20161027214941.24641-1-afd@ti.com>

Some TI Keystone family of SoCs contain a system controller (like the
Power Management Micro Controller (PMMC) on K2G SoCs) that manage the
low-level device control (like clocks, resets etc) for the various
hardware modules present on the SoC. These device control operations
are provided to the host processor OS through a communication protocol
called the TI System Control Interface (TI SCI) protocol.

This patch adds a reset driver that communicates to the system
controller over the TI SCI protocol for performing reset management
of various devices present on the SoC. Various reset functionalities
are achieved by the means of different TI SCI device operations
provided by the TI SCI framework.

Signed-off-by: Andrew F. Davis <afd@ti.com>
[s-anna@ti.com: documentation changes, revised commit message]
Signed-off-by: Suman Anna <s-anna@ti.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
---
 MAINTAINERS                  |   1 +
 drivers/reset/Kconfig        |   9 ++
 drivers/reset/Makefile       |   1 +
 drivers/reset/reset-ti-sci.c | 262 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 273 insertions(+)
 create mode 100644 drivers/reset/reset-ti-sci.c

diff --git a/MAINTAINERS b/MAINTAINERS
index accf991..b93d91a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11901,6 +11901,7 @@ F:	include/dt-bindings/clock/k2g.h
 F:	drivers/clk/keystone/sci-clk.c
 F:	Documentation/devicetree/bindings/reset/ti,sci-reset.txt
 F:	include/dt-bindings/reset/k2g.h
+F:	drivers/reset/reset-ti-sci.c
 
 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
 M:	Hans Verkuil <hverkuil@xs4all.nl>
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 06d9fa2..4c21c9d 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -66,6 +66,15 @@ config RESET_SUNXI
 	help
 	  This enables the reset driver for Allwinner SoCs.
 
+config RESET_TI_SCI
+	tristate "TI System Control Interface (TI-SCI) reset driver"
+	depends on RESET_CONTROLLER
+	depends on TI_SCI_PROTOCOL
+	help
+	  This enables the reset driver support over TI System Control Interface
+	  available on some new TI SoCs. If you wish to use reset resources
+	  managed by the TI System Controller, say Y here. Otherwise, say N.
+
 config TI_SYSCON_RESET
 	tristate "TI SYSCON Reset Driver"
 	depends on HAS_IOMEM
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index bbe7026..36321f2 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o
 obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
 obj-$(CONFIG_RESET_STM32) += reset-stm32.o
 obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
+obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
 obj-$(CONFIG_TI_SYSCON_RESET) += reset-ti-syscon.o
 obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
 obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o
diff --git a/drivers/reset/reset-ti-sci.c b/drivers/reset/reset-ti-sci.c
new file mode 100644
index 0000000..42ccf12
--- /dev/null
+++ b/drivers/reset/reset-ti-sci.c
@@ -0,0 +1,262 @@
+/*
+ * Texas Instrument's System Control Interface (TI-SCI) reset driver
+ *
+ * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
+ *	Andrew F. Davis <afd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/idr.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+
+/**
+ * struct ti_sci_reset_control - reset control structure
+ * @dev_id: SoC-specific device identifier
+ * @reset_mask: reset mask to use for toggling reset
+ */
+struct ti_sci_reset_control {
+	u32 dev_id;
+	u32 reset_mask;
+};
+
+/**
+ * struct ti_sci_reset_data - reset controller information structure
+ * @rcdev: reset controller entity
+ * @dev: reset controller device pointer
+ * @sci: TI SCI handle used for communication with system controller
+ * @idr: idr structure for mapping ids to reset control structures
+ */
+struct ti_sci_reset_data {
+	struct reset_controller_dev rcdev;
+	struct device *dev;
+	const struct ti_sci_handle *sci;
+	struct idr idr;
+};
+
+#define to_ti_sci_reset_data(p)	\
+	container_of((p), struct ti_sci_reset_data, rcdev)
+
+/**
+ * ti_sci_reset_set() - program a device's reset
+ * @rcdev: reset controller entity
+ * @id: ID of the reset to toggle
+ * @assert: boolean flag to indicate assert or deassert
+ *
+ * This is a common internal function used to assert or deassert a device's
+ * reset using the TI SCI protocol. The device's reset is asserted if the
+ * @assert argument is true, or deasserted if @assert argument is false.
+ * The mechanism itself is a read-modify-write procedure, the current device
+ * reset register is read using a TI SCI device operation, the new value is
+ * set or un-set using the reset's mask, and the new reset value written by
+ * using another TI SCI device operation.
+ *
+ * Return: 0 for successful request, else a corresponding error value
+ */
+static int ti_sci_reset_set(struct reset_controller_dev *rcdev,
+			    unsigned long id, bool assert)
+{
+	struct ti_sci_reset_data *data = to_ti_sci_reset_data(rcdev);
+	const struct ti_sci_handle *sci = data->sci;
+	const struct ti_sci_dev_ops *dev_ops = &sci->ops.dev_ops;
+	struct ti_sci_reset_control *control;
+	u32 reset_state;
+	int ret;
+
+	control = idr_find(&data->idr, id);
+	if (!control)
+		return -EINVAL;
+
+	ret = dev_ops->get_device_resets(sci, control->dev_id,
+					 &reset_state);
+	if (ret)
+		return ret;
+
+	if (assert)
+		reset_state |= control->reset_mask;
+	else
+		reset_state &= ~control->reset_mask;
+
+	return dev_ops->set_device_resets(sci, control->dev_id,
+					  reset_state);
+}
+
+/**
+ * ti_sci_reset_assert() - assert device reset
+ * @rcdev: reset controller entity
+ * @id: ID of the reset to be asserted
+ *
+ * This function implements the reset driver op to assert a device's reset
+ * using the TI SCI protocol. This invokes the function ti_sci_reset_set()
+ * with the corresponding parameters as passed in, but with the @assert
+ * argument set to true for asserting the reset.
+ *
+ * Return: 0 for successful request, else a corresponding error value
+ */
+static int ti_sci_reset_assert(struct reset_controller_dev *rcdev,
+			       unsigned long id)
+{
+	return ti_sci_reset_set(rcdev, id, true);
+}
+
+/**
+ * ti_sci_reset_deassert() - deassert device reset
+ * @rcdev: reset controller entity
+ * @id: ID of the reset to be deasserted
+ *
+ * This function implements the reset driver op to deassert a device's reset
+ * using the TI SCI protocol. This invokes the function ti_sci_reset_set()
+ * with the corresponding parameters as passed in, but with the @assert
+ * argument set to false for deasserting the reset.
+ *
+ * Return: 0 for successful request, else a corresponding error value
+ */
+static int ti_sci_reset_deassert(struct reset_controller_dev *rcdev,
+				 unsigned long id)
+{
+	return ti_sci_reset_set(rcdev, id, false);
+}
+
+/**
+ * ti_sci_reset_status() - check device reset status
+ * @rcdev: reset controller entity
+ * @id: ID of reset to be checked
+ *
+ * This function implements the reset driver op to return the status of a
+ * device's reset using the TI SCI protocol. The reset register value is read
+ * by invoking the TI SCI device opertation .get_device_resets(), and the
+ * status of the specific reset is extracted and returned using this reset's
+ * reset mask.
+ *
+ * Return: 0 if reset is deasserted, or a non-zero value if reset is asserted
+ */
+static int ti_sci_reset_status(struct reset_controller_dev *rcdev,
+			       unsigned long id)
+{
+	struct ti_sci_reset_data *data = to_ti_sci_reset_data(rcdev);
+	const struct ti_sci_handle *sci = data->sci;
+	const struct ti_sci_dev_ops *dev_ops = &sci->ops.dev_ops;
+	struct ti_sci_reset_control *control;
+	u32 reset_state;
+	int ret;
+
+	control = idr_find(&data->idr, id);
+	if (!control)
+		return -EINVAL;
+
+	ret = dev_ops->get_device_resets(sci, control->dev_id,
+					 &reset_state);
+	if (ret)
+		return ret;
+
+	return reset_state & control->reset_mask;
+}
+
+static struct reset_control_ops ti_sci_reset_ops = {
+	.assert		= ti_sci_reset_assert,
+	.deassert	= ti_sci_reset_deassert,
+	.status		= ti_sci_reset_status,
+};
+
+/**
+ * ti_sci_reset_of_xlate() - translate a set of OF arguments to a reset ID
+ * @rcdev: reset controller entity
+ * @reset_spec: OF reset argument specifier
+ *
+ * This function performs the translation of the reset argument specifier
+ * values defined in a reset consumer device node. The function allocates a
+ * reset control structure for that device reset, and will be used by the
+ * driver for performing any reset functions on that reset. An idr structure
+ * is allocated and used to map to the reset control structure. This idr
+ * is used by the driver to do reset lookups.
+ *
+ * Return: 0 for successful request, else a corresponding error value
+ */
+static int ti_sci_reset_of_xlate(struct reset_controller_dev *rcdev,
+				 const struct of_phandle_args *reset_spec)
+{
+	struct ti_sci_reset_data *data = to_ti_sci_reset_data(rcdev);
+	struct ti_sci_reset_control *control;
+
+	if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells))
+		return -EINVAL;
+
+	control = devm_kzalloc(data->dev, sizeof(*control), GFP_KERNEL);
+	if (!control)
+		return -ENOMEM;
+
+	control->dev_id = reset_spec->args[0];
+	control->reset_mask = reset_spec->args[1];
+
+	return idr_alloc(&data->idr, control, 0, 0, GFP_KERNEL);
+}
+
+static const struct of_device_id ti_sci_reset_of_match[] = {
+	{ .compatible = "ti,sci-reset", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, ti_sci_reset_of_match);
+
+static int ti_sci_reset_probe(struct platform_device *pdev)
+{
+	struct ti_sci_reset_data *data;
+
+	if (!pdev->dev.of_node)
+		return -ENODEV;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->sci = devm_ti_sci_get_handle(&pdev->dev);
+	if (IS_ERR(data->sci))
+		return PTR_ERR(data->sci);
+
+	data->rcdev.ops = &ti_sci_reset_ops;
+	data->rcdev.owner = THIS_MODULE;
+	data->rcdev.of_node = pdev->dev.of_node;
+	data->rcdev.of_reset_n_cells = 2;
+	data->rcdev.of_xlate = ti_sci_reset_of_xlate;
+	data->dev = &pdev->dev;
+	idr_init(&data->idr);
+
+	platform_set_drvdata(pdev, data);
+
+	return reset_controller_register(&data->rcdev);
+}
+
+static int ti_sci_reset_remove(struct platform_device *pdev)
+{
+	struct ti_sci_reset_data *data = platform_get_drvdata(pdev);
+
+	reset_controller_unregister(&data->rcdev);
+
+	idr_destroy(&data->idr);
+
+	return 0;
+}
+
+static struct platform_driver ti_sci_reset_driver = {
+	.probe = ti_sci_reset_probe,
+	.remove = ti_sci_reset_remove,
+	.driver = {
+		.name = "ti-sci-reset",
+		.of_match_table = ti_sci_reset_of_match,
+	},
+};
+module_platform_driver(ti_sci_reset_driver);
+
+MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
+MODULE_DESCRIPTION("TI System Control Interface (TI SCI) Reset driver");
+MODULE_LICENSE("GPL v2");
-- 
2.10.1

^ permalink raw reply related

* Re: [PATCH v5 1/7] drm: sunxi: Add a basic DRM driver for Allwinner DE2
From: Maxime Ripard @ 2016-10-27 22:03 UTC (permalink / raw)
  To: Jean-Francois Moine
  Cc: Dave Airlie, Liam Girdwood, Mark Brown, Rob Herring,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <20161025161441.6b248efe9229bd80e3f7a33c-GANU6spQydw@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 19567 bytes --]

On Tue, Oct 25, 2016 at 04:14:41PM +0200, Jean-Francois Moine wrote:
> > > +Display controller
> > > +==================
> > > +
> > > +Required properties:
> > > +
> > > +- compatible: value should be one of the following
> > > +		"allwinner,sun8i-a83t-display-engine"
> > > +		"allwinner,sun8i-h3-display-engine"
> > > +
> > > +- clocks: must include clock specifiers corresponding to entries in the
> > > +		clock-names property.
> > > +
> > > +- clock-names: must contain
> > > +		"gate": for DE activation
> > > +		"clock": DE clock
> > 
> > We've been calling them bus and mod.
> 
> I can understand "bus" (which is better than "apb"), but why "mod"?

Allwinner has been calling the clocks that are supposed to generate
the external signals (depending on where you were looking) module or
mod clocks (which is also why we have mod in the clock
compatibles). The module 1 clocks being used for the audio and the
module 0 for the rest (SPI, MMC, NAND, display, etc.)

> > > +
> > > +- resets: phandle to the reset of the device
> > > +
> > > +- ports: phandle's to the LCD ports
> > 
> > Please use the OF graph.
> 
> These ports are references to the graph of nodes. See
> 	http://www.kernelhub.org/?msg=911825&p=2

In an OF-graph, your phandle to the LCD controller would be replaced
by an output endpoint.

> 
> 	[snip]
> > > +struct tcon {
> > > +	u32 gctl;
> > > +#define		TCON_GCTL_TCON_En BIT(31)
> > > +	u32 gint0;
> > > +#define		TCON_GINT0_TCON1_Vb_Int_En BIT(30)
> > > +#define		TCON_GINT0_TCON1_Vb_Int_Flag BIT(14)
> > > +	u32 gint1;
> > > +	u32 dum0[13];
> > > +	u32 tcon0_ctl;				/* 0x40 */
> > > +#define		TCON0_CTL_TCON_En BIT(31)
> > > +	u32 dum1[19];
> > > +	u32 tcon1_ctl;				/* 0x90 */
> > > +#define		TCON1_CTL_TCON_En BIT(31)
> > > +#define		TCON1_CTL_Interlace_En BIT(20)
> > > +#define		TCON1_CTL_Start_Delay_SHIFT 4
> > > +#define		TCON1_CTL_Start_Delay_MASK GENMASK(8, 4)
> > > +	u32 basic0;			/* XI/YI */
> > > +	u32 basic1;			/* LS_XO/LS_YO */
> > > +	u32 basic2;			/* XO/YO */
> > > +	u32 basic3;			/* HT/HBP */
> > > +	u32 basic4;			/* VT/VBP */
> > > +	u32 basic5;			/* HSPW/VSPW */
> > > +	u32 dum2;
> > > +	u32 ps_sync;				/* 0xb0 */
> > > +	u32 dum3[15];
> > > +	u32 io_pol;				/* 0xf0 */
> > > +#define		TCON1_IO_POL_IO0_inv BIT(24)
> > > +#define		TCON1_IO_POL_IO1_inv BIT(25)
> > > +#define		TCON1_IO_POL_IO2_inv BIT(26)
> > > +	u32 io_tri;
> > > +	u32 dum4[2];
> > > +
> > > +	u32 ceu_ctl;				/* 0x100 */
> > > +#define     TCON_CEU_CTL_ceu_en BIT(31)
> > > +	u32 dum5[3];
> > > +	u32 ceu_rr;
> > > +	u32 ceu_rg;
> > > +	u32 ceu_rb;
> > > +	u32 ceu_rc;
> > > +	u32 ceu_gr;
> > > +	u32 ceu_gg;
> > > +	u32 ceu_gb;
> > > +	u32 ceu_gc;
> > > +	u32 ceu_br;
> > > +	u32 ceu_bg;
> > > +	u32 ceu_bb;
> > > +	u32 ceu_bc;
> > > +	u32 ceu_rv;
> > > +	u32 ceu_gv;
> > > +	u32 ceu_bv;
> > > +	u32 dum6[45];
> > > +
> > > +	u32 mux_ctl;				/* 0x200 */
> > > +	u32 dum7[63];
> > > +
> > > +	u32 fill_ctl;				/* 0x300 */
> > > +	u32 fill_start0;
> > > +	u32 fill_end0;
> > > +	u32 fill_data0;
> > > +};
> > 
> > Please use defines instead of the structures.
> 
> I think that structures are more readable.

That's not really the point. No one in the kernel uses it (and even
you use defines for registers offset in some places of that
patch). And then you have André arguments.

> > > +void de2_disable_vblank(struct drm_device *drm, unsigned crtc)
> > > +{
> > > +	struct priv *priv = drm->dev_private;
> > > +	struct lcd *lcd = priv->lcds[crtc];
> > > +
> > > +	tcon_write(lcd->mmio, gint0,
> > > +			 tcon_read(lcd->mmio, gint0) &
> > > +					~TCON_GINT0_TCON1_Vb_Int_En);
> > > +}
> > > +
> > > +/* panel functions */
> > 
> > Panel functions? In the CRTC driver?
> 
> Yes, dumb panel.

What do you mean by that? Using a Parallel/RGB interface?

> 
> > > +static void de2_set_frame_timings(struct lcd *lcd)
> > > +{
> > > +	struct drm_crtc *crtc = &lcd->crtc;
> > > +	const struct drm_display_mode *mode = &crtc->mode;
> > > +	int interlace = mode->flags & DRM_MODE_FLAG_INTERLACE ? 2 : 1;
> > > +	int start_delay;
> > > +	u32 data;
> > > +
> > > +	data = XY(mode->hdisplay - 1, mode->vdisplay / interlace - 1);
> > > +	tcon_write(lcd->mmio, basic0, data);
> > > +	tcon_write(lcd->mmio, basic1, data);
> > > +	tcon_write(lcd->mmio, basic2, data);
> > > +	tcon_write(lcd->mmio, basic3,
> > > +			XY(mode->htotal - 1,
> > > +				mode->htotal - mode->hsync_start - 1));
> > > +	tcon_write(lcd->mmio, basic4,
> > > +			XY(mode->vtotal * (3 - interlace),
> > > +				mode->vtotal - mode->vsync_start - 1));
> > > +	tcon_write(lcd->mmio, basic5,
> > > +			 XY(mode->hsync_end - mode->hsync_start - 1,
> > > +				mode->vsync_end - mode->vsync_start - 1));
> > > +
> > > +	tcon_write(lcd->mmio, ps_sync, XY(1, 1));
> > > +
> > > +	data = TCON1_IO_POL_IO2_inv;
> > > +	if (mode->flags & DRM_MODE_FLAG_PVSYNC)
> > > +		data |= TCON1_IO_POL_IO0_inv;
> > > +	if (mode->flags & DRM_MODE_FLAG_PHSYNC)
> > > +		data |= TCON1_IO_POL_IO1_inv;
> > > +	tcon_write(lcd->mmio, io_pol, data);
> > > +
> > > +	tcon_write(lcd->mmio, ceu_ctl,
> > > +		tcon_read(lcd->mmio, ceu_ctl) & ~TCON_CEU_CTL_ceu_en);
> > > +
> > > +	data = tcon_read(lcd->mmio, tcon1_ctl);
> > > +	if (interlace == 2)
> > > +		data |= TCON1_CTL_Interlace_En;
> > > +	else
> > > +		data &= ~TCON1_CTL_Interlace_En;
> > > +	tcon_write(lcd->mmio, tcon1_ctl, data);
> > > +
> > > +	tcon_write(lcd->mmio, fill_ctl, 0);
> > > +	tcon_write(lcd->mmio, fill_start0, mode->vtotal + 1);
> > > +	tcon_write(lcd->mmio, fill_end0, mode->vtotal);
> > > +	tcon_write(lcd->mmio, fill_data0, 0);
> > > +
> > > +	start_delay = (mode->vtotal - mode->vdisplay) / interlace - 5;
> > > +	if (start_delay > 31)
> > > +		start_delay = 31;
> > > +	data = tcon_read(lcd->mmio, tcon1_ctl);
> > > +	data &= ~TCON1_CTL_Start_Delay_MASK;
> > > +	data |= start_delay << TCON1_CTL_Start_Delay_SHIFT;
> > > +	tcon_write(lcd->mmio, tcon1_ctl, data);
> > > +
> > > +	tcon_write(lcd->mmio, io_tri, 0x0fffffff);
> > > +}
> > 
> > Some comments here would be nice, there's a lot of non trivial things.
> 
> ... and no documentation. I just set the values I saw in the I/O memory
> when running the legacy driver.

That's bad (but definitely not your fault) :/

> > > +	lcd->gate = devm_clk_get(dev, "gate");		/* optional */
> > 
> > Having some kind of error checking would still be nice.
> 
> And cancel the device creation?

Well, yes. If it cannot enable it, it will at best not work properly,
at worst be reset, so it won't be very useful anyway.

> > > +	if (!IS_ERR(lcd->rstc)) {
> > > +		ret = reset_control_deassert(lcd->rstc);
> > > +		if (ret) {
> > > +			dev_err(dev, "reset deassert err %d\n", ret);
> > > +			goto err;
> > > +		}
> > > +	}
> > > +
> > > +	if (!IS_ERR(lcd->gate)) {
> > > +		ret = clk_prepare_enable(lcd->gate);
> > > +		if (ret)
> > > +			goto err2;
> > > +	}
> > > +
> > > +	ret = clk_prepare_enable(lcd->clk);
> > > +	if (ret)
> > > +		goto err2;
> > 
> > Is there any reason not to do that in the enable / disable? Leaving
> > clocks running while the device has no guarantee that it's going to be
> > used seems like a waste of resources.
> 
> If the machine does not need video (network server, router..), it is simpler
> to prevent the video driver to be loaded (DT, module black list...).

You might not have control on any of it, or you might just have no
monitor attached for example. Recompiling the kernel or updating the
DT when you want to plug an HDMI monitor seems like a poor UX :)

> > > +static const struct {
> > > +	char chan;
> > > +	char layer;
> > > +	char pipe;
> > > +} plane2layer[DE2_N_PLANES] = {
> > > +	[DE2_PRIMARY_PLANE] =	{0, 0, 0},
> > > +	[DE2_CURSOR_PLANE] =	{1, 0, 1},
> > > +	[DE2_VI_PLANE] =	{0, 1, 0},
> > > +};
> > 
> > Comments?
> 
> This
> 	primary plane is channel 0 (VI), layer 0, pipe 0
> 	cursor plane is channel 1 (UI), layer 0, pipe 1
> 	overlay plane is channel 0 (VI), layer 1, pipe 0
> or the full explanation:
>     Constraints:
> 	The VI channels can do RGB or YUV, while UI channels can do RGB
> 	only.
> 	The LCD 0 has 1 VI channel and 4 UI channels, while
> 	LCD 1 has only 1 VI channel and 1 UI channel.
> 	The cursor must go to a channel bigger than the primary channel,
> 	otherwise it is not transparent.
>     First try:
> 	Letting the primary plane (usually RGB) in the 2nd channel (UI),
> 	as this is done in the legacy driver, asks for the cursor to go
> 	to the next channel (UI), but this one does not exist in LCD1.
>     Retained layout:
> 	So, we must use only 2 channels for the same behaviour on LCD0
> 	(H3) and LCD1 (A83T)
> 	The retained combination is:
> 		- primary plane in the first channel (VI),
> 		- cursor plane inthe 2nd channel (UI), and
> 		- overlay plane in the 1st channel (VI).
> 
> 	Note that there could be 3 overlay planes (a channel has 4
> 	layers), but I am not sure that the A83T or the H3 could
> 	support 3 simultaneous video streams...

Do you know if the pipe works in the old display engine?

Especially about the two-steps composition that wouldn't allow you to
have alpha on all the planes?

If it is similar, I think hardcoding the pipe number is pretty bad,
because that would restrict the combination of planes and formats,
while some other might have worked.

> > > +static inline void de_write(struct priv *priv, int reg, u32 data)
> > > +{
> > > +	writel_relaxed(data, priv->mmio + reg);
> > > +}
> > > +
> > > +static inline u32 de_read(struct priv *priv, int reg)
> > > +{
> > > +	return readl_relaxed(priv->mmio + reg);
> > > +}
> > > +
> > > +static void de_lcd_select(struct priv *priv,
> > > +			int lcd_num,
> > > +			void __iomem *mux_o)
> > > +{
> > > +	u32 data;
> > > +
> > > +	/* select the LCD */
> > > +	data = de_read(priv, DE_SEL_REG);
> > > +	data &= ~1;
> > > +	de_write(priv, DE_SEL_REG, data);
> > > +
> > > +	/* double register switch */
> > > +	glb_write(mux_o + DE_MUX_GLB_REGS, dbuff, 1);
> > > +}
> > > +
> > > +void de2_de_plane_update(struct priv *priv,
> > > +			int lcd_num, int plane_ix,
> > > +			struct drm_plane_state *state,
> > > +			struct drm_plane_state *old_state)
> > > +{
> > > +	struct drm_framebuffer *fb = state->fb;
> > > +	struct drm_gem_cma_object *gem;
> > > +	void __iomem *mux_o = priv->mmio;
> > > +	void __iomem *chan_o;
> > > +	u32 size = WH(state->crtc_w, state->crtc_h);
> > > +	u32 coord;
> > > +	u32 screen_size;
> > > +	u32 data, fcolor;
> > > +	u32 ui_sel, alpha_glob;
> > > +	int chan, layer, x, y;
> > > +	unsigned fmt;
> > > +	unsigned long flags;
> > > +
> > > +	chan = plane2layer[plane_ix].chan;
> > > +	layer = plane2layer[plane_ix].layer;
> > > +
> > > +	mux_o += (lcd_num == 0) ? DE_MUX0_BASE : DE_MUX1_BASE;
> > > +	chan_o = mux_o;
> > > +	chan_o += DE_MUX_CHAN_REGS + DE_MUX_CHAN_SZ * chan;
> > > +
> > > +	x = state->crtc_x >= 0 ? state->crtc_x : 0;
> > > +	y = state->crtc_y >= 0 ? state->crtc_y : 0;
> > > +	coord = XY(x, y);
> > > +
> > > +	/* handle the cursor move */
> > > +	if (plane_ix == DE2_CURSOR_PLANE
> > > +	 && fb == old_state->fb) {
> > > +		spin_lock_irqsave(&de_lock, flags);
> > > +		de_lcd_select(priv, lcd_num, mux_o);
> > > +		if (chan == 0)
> > > +			vi_write(chan_o, cfg[layer].coord, coord);
> > > +		else
> > > +			ui_write(chan_o, cfg[layer].coord, coord);
> > > +		spin_unlock_irqrestore(&de_lock, flags);
> > > +		return;
> > > +	}
> > > +
> > > +	gem = drm_fb_cma_get_gem_obj(fb, 0);
> > > +
> > > +	ui_sel = alpha_glob = 0;
> > > +	switch (fb->pixel_format) {
> > > +	case DRM_FORMAT_ARGB8888:
> > > +		fmt = DE2_FORMAT_ARGB_8888;
> > > +		ui_sel = VI_CFG_ATTR_ui_sel;
> > > +		break;
> > > +	case DRM_FORMAT_BGRA8888:
> > > +		fmt = DE2_FORMAT_BGRA_8888;
> > > +		ui_sel = VI_CFG_ATTR_ui_sel;
> > > +		break;
> > > +	case DRM_FORMAT_XRGB8888:
> > > +		fmt = DE2_FORMAT_XRGB_8888;
> > > +		ui_sel = VI_CFG_ATTR_ui_sel;
> > > +		alpha_glob = (1 << UI_CFG_ATTR_alpmod_SHIFT) |
> > > +				(0xff << UI_CFG_ATTR_alpha_SHIFT);
> > > +		break;
> > > +	case DRM_FORMAT_RGB888:
> > > +		fmt = DE2_FORMAT_RGB_888;
> > > +		ui_sel = VI_CFG_ATTR_ui_sel;
> > > +		break;
> > > +	case DRM_FORMAT_BGR888:
> > > +		fmt = DE2_FORMAT_BGR_888;
> > > +		ui_sel = VI_CFG_ATTR_ui_sel;
> > > +		break;
> > > +	case DRM_FORMAT_YUYV:
> > > +		fmt = DE2_FORMAT_YUV422_I_YUYV;
> > > +		break;
> > > +	case DRM_FORMAT_YVYU:
> > > +		fmt = DE2_FORMAT_YUV422_I_YVYU;
> > > +		break;
> > > +	case DRM_FORMAT_YUV422:
> > > +		fmt = DE2_FORMAT_YUV422_P;
> > > +		break;
> > > +	case DRM_FORMAT_YUV420:
> > > +		fmt = DE2_FORMAT_YUV420_P;
> > > +		break;
> > > +	case DRM_FORMAT_UYVY:
> > > +		fmt = DE2_FORMAT_YUV422_I_UYVY;
> > > +		break;
> > > +	default:
> > > +		pr_err("format %.4s not yet treated\n",
> > > +			(char *) &fb->pixel_format);
> > > +		return;
> > > +	}
> > > +
> > > +	spin_lock_irqsave(&de_lock, flags);
> > > +
> > > +	screen_size = plane_ix == DE2_PRIMARY_PLANE ?
> > > +			size :
> > > +			glb_read(mux_o + DE_MUX_GLB_REGS, size);
> > > +
> > > +	/* prepare the activation of alpha blending (1 bit per plane) */
> > > +	fcolor = bld_read(mux_o + DE_MUX_BLD_REGS, fcolor_ctl)
> > > +			| (0x100 << plane2layer[plane_ix].pipe);
> > > +
> > > +	de_lcd_select(priv, lcd_num, mux_o);
> > > +
> > > +	if (chan == 0) {	/* VI channel */
> > > +		int i;
> > > +
> > > +		data = VI_CFG_ATTR_en | (fmt << VI_CFG_ATTR_fmt_SHIFT) |
> > > +					ui_sel;
> > > +		vi_write(chan_o, cfg[layer].attr, data);
> > > +		vi_write(chan_o, cfg[layer].size, size);
> > > +		vi_write(chan_o, cfg[layer].coord, coord);
> > > +		for (i = 0; i < VI_N_PLANES; i++) {
> > > +			vi_write(chan_o, cfg[layer].pitch[i],
> > > +					fb->pitches[i] ? fb->pitches[i] :
> > > +							fb->pitches[0]);
> > > +			vi_write(chan_o, cfg[layer].top_laddr[i],
> > > +				gem->paddr + fb->offsets[i]);
> > > +			vi_write(chan_o, fcolor[layer], 0xff000000);
> > > +		}
> > > +		if (layer == 0)
> > > +			vi_write(chan_o, ovl_size[0], screen_size);
> > > +
> > > +	} else {		/* UI channel */
> > > +		data = UI_CFG_ATTR_en | (fmt << UI_CFG_ATTR_fmt_SHIFT) |
> > > +			alpha_glob;
> > > +		ui_write(chan_o, cfg[layer].attr, data);
> > > +		ui_write(chan_o, cfg[layer].size, size);
> > > +		ui_write(chan_o, cfg[layer].coord, coord);
> > > +		ui_write(chan_o, cfg[layer].pitch, fb->pitches[0]);
> > > +		ui_write(chan_o, cfg[layer].top_laddr,
> > > +				gem->paddr + fb->offsets[0]);
> > > +		if (layer == 0)
> > > +			ui_write(chan_o, ovl_size, screen_size);
> > > +	}
> > > +	bld_write(mux_o + DE_MUX_BLD_REGS, fcolor_ctl, fcolor);
> > > +
> > > +	spin_unlock_irqrestore(&de_lock, flags);
> > > +}
> > 
> > Splitting that into functions would make it a bit more trivial and
> > readable.
> 
> Not sure: there is a lot of common data and different I/O accesses.

You could still have different ones to set the buffers, formats and
coordinates for example.

> > > +void de2_de_plane_disable(struct priv *priv,
> > > +			int lcd_num, int plane_ix)
> > > +{
> > > +	void __iomem *mux_o = priv->mmio;
> > > +	void __iomem *chan_o;
> > > +	u32 fcolor;
> > > +	int chan, layer, chan_disable = 0;
> > > +	unsigned long flags;
> > > +
> > > +	chan = plane2layer[plane_ix].chan;
> > > +	layer = plane2layer[plane_ix].layer;
> > > +
> > > +	mux_o += (lcd_num == 0) ? DE_MUX0_BASE : DE_MUX1_BASE;
> > > +	chan_o = mux_o;
> > > +	chan_o += DE_MUX_CHAN_REGS + DE_MUX_CHAN_SZ * chan;
> > > +
> > > +	/* (only 2 layers) */
> > > +	if (chan == 0) {
> > > +		if (vi_read(chan_o, cfg[1 - layer].attr) == 0)
> > > +			chan_disable = 1;
> > > +	} else {
> > > +		if (ui_read(chan_o, cfg[1 - layer].attr) == 0)
> > > +			chan_disable = 1;
> > > +	}
> > > +
> > > +	spin_lock_irqsave(&de_lock, flags);
> > > +
> > > +	fcolor = bld_read(mux_o + DE_MUX_BLD_REGS, fcolor_ctl);
> > > +
> > > +	de_lcd_select(priv, lcd_num, mux_o);
> > > +
> > > +	if (chan == 0)
> > > +		vi_write(chan_o, cfg[layer].attr, 0);
> > > +	else
> > > +		ui_write(chan_o, cfg[layer].attr, 0);
> > > +
> > > +	if (chan_disable)
> > > +		bld_write(mux_o + DE_MUX_BLD_REGS, fcolor_ctl,
> > > +			fcolor & ~(0x100 << plane2layer[plane_ix].pipe));
> > > +
> > > +	spin_unlock_irqrestore(&de_lock, flags);
> > > +}
> > 
> > Can't you just disable it?
> 
> Which 'it'? A layer must be disabled and it is not useful to let the
> DE2 processor to scan a pipe (channel) without any layer.

Oh, so that's what it does.

I really think that you should put as much comments as possible on
what you found out working on this, especially because of the lack of
documentation.

> > > +static int __init de2_drm_init(void)
> > > +{
> > > +	int ret;
> > > +
> > > +/* uncomment to activate the drm traces at startup time */
> > > +/*	drm_debug = DRM_UT_CORE | DRM_UT_DRIVER | DRM_UT_KMS |
> > > +			DRM_UT_PRIME | DRM_UT_ATOMIC; */
> > 
> > That's useless.
> 
> Right, but it seems that some people don't know how to debug a DRM
> driver. This is only a reminder.
> 
> > > +	DRM_DEBUG_DRIVER("\n");
> > > +
> > > +	ret = platform_driver_register(&de2_lcd_platform_driver);
> > > +	if (ret < 0)
> > > +		return ret;
> > > +
> > > +	ret = platform_driver_register(&de2_drm_platform_driver);
> > > +	if (ret < 0)
> > > +		platform_driver_unregister(&de2_lcd_platform_driver);
> > > +
> > > +	return ret;
> > > +}
> > 
> > And that really shouldn't be done that way.
> 
> May you explain?

This goes against the whole idea of the device and driver
model. Drivers should only register themselves, device should be
created by buses (or by using some external components if the bus
can't: DT, ACPI, etc.). If there's a match, you get probed.

A driver that creates its own device just to probe itself violates
that.

> > > +int de2_plane_init(struct drm_device *drm, struct lcd *lcd)
> > > +{
> > > +	int ret, possible_crtcs = 1 << lcd->crtc_idx;
> > > +
> > > +	ret = de2_one_plane_init(drm, &lcd->planes[DE2_PRIMARY_PLANE],
> > > +				DRM_PLANE_TYPE_PRIMARY, possible_crtcs,
> > > +				ui_formats, ARRAY_SIZE(ui_formats));
> > > +	if (ret >= 0)
> > > +		ret = de2_one_plane_init(drm, &lcd->planes[DE2_CURSOR_PLANE],
> > > +				DRM_PLANE_TYPE_CURSOR, possible_crtcs,
> > > +				ui_formats, ARRAY_SIZE(ui_formats));
> > 
> > Nothing looks really special about that cursor plane. Any reasion not
> > to make it an overlay?
> 
> As explained above (channel/layer/pipe plane definitions), the cursor
> cannot go in a channel lower or equal to the one of the primary plane.
> Then, it must be known and, so, have an explicit plane.

If you were to make it a plane, you could use atomic_check to check
this and make sure this doesn't happen. And you would gain a generic
plane that can be used for other purposes if needed.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

-- 
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.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: [PATCH 4/5] net: ethernet: bgmac: add NS2 support
From: Ray Jui @ 2016-10-27 22:21 UTC (permalink / raw)
  To: Jon Mason, Florian Fainelli
  Cc: David Miller, Rob Herring, Mark Rutland,
	rafal-g1n6cQUeyibVItvQsEIGlw,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20161027205117.GA24397-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>



On 10/27/2016 1:51 PM, Jon Mason wrote:
> On Wed, Oct 26, 2016 at 02:50:39PM -0700, Florian Fainelli wrote:
>> On 10/26/2016 12:36 PM, Jon Mason wrote:
>>> Add support for the variant of amac hardware present in the Broadcom
>>> Northstar2 based SoCs.  Northstar2 requires an additional register to be
>>> configured with the port speed/duplexity (NICPM).  This can be added to
>>> the link callback to hide it from the instances that do not use this.
>>> Also, the bgmac_chip_reset() was intentionally removed to prevent the
>>> resetting of the chip to the default values on open.  Finally, clearing
>>> of the pending interrupts on init is required due to observed issues on
>>> some platforms.
>>>
>>> Signed-off-by: Jon Mason <jon.mason-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
>>> ---
>>
>>> +static void bgmac_nicpm_speed_set(struct net_device *net_dev)
>>> +{
>>> +	struct bgmac *bgmac = netdev_priv(net_dev);
>>> +	u32 val;
>>> +
>>> +	if (!bgmac->plat.nicpm_base)
>>> +		return;
>>> +
>>> +	val = NICPM_IOMUX_CTRL_INIT_VAL;
>>> +	switch (bgmac->net_dev->phydev->speed) {
>>> +	default:
>>> +		pr_err("Unsupported speed.  Defaulting to 1000Mb\n");
>>> +	case SPEED_1000:
>>> +		val |= NICPM_IOMUX_CTRL_SPD_1000M << NICPM_IOMUX_CTRL_SPD_SHIFT;
>>> +		break;
>>> +	case SPEED_100:
>>> +		val |= NICPM_IOMUX_CTRL_SPD_100M << NICPM_IOMUX_CTRL_SPD_SHIFT;
>>> +		break;
>>> +	case SPEED_10:
>>> +		val |= NICPM_IOMUX_CTRL_SPD_10M << NICPM_IOMUX_CTRL_SPD_SHIFT;
>>> +		break;
>>> +	}
>>> +
>>> +	writel(val, bgmac->plat.nicpm_base + NICPM_IOMUX_CTRL);
>>> +
>>> +	usleep_range(10, 100);
>>
>> Does not seem like a good idea, do you need that sleep?
> 
> Oops, that's not supposed to be there.  Removed.
> 
> 
>>> +
>>> +	bgmac_adjust_link(bgmac->net_dev);
>>> +}
>>> +
>>>  static int platform_phy_connect(struct bgmac *bgmac)
>>>  {
>>>  	struct phy_device *phy_dev;
>>>  
>>> -	phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node,
>>> -					 bgmac_adjust_link);
>>> +	if (bgmac->plat.nicpm_base)
>>> +		phy_dev = of_phy_get_and_connect(bgmac->net_dev,
>>> +						 bgmac->dev->of_node,
>>> +						 bgmac_nicpm_speed_set);
>>> +	else
>>> +		phy_dev = of_phy_get_and_connect(bgmac->net_dev,
>>> +						 bgmac->dev->of_node,
>>> +						 bgmac_adjust_link);
>>>  	if (!phy_dev) {
>>>  		dev_err(bgmac->dev, "Phy connect failed\n");
>>>  		return -ENODEV;
>>>  	}
>>>  
>>> +	if (bgmac->feature_flags & BGMAC_FEAT_LANE_SWAP)
>>> +		phy_dev->dev_flags |= PHY_BRCM_EXP_LANE_SWAP;
>>> +
>>>  	return 0;
>>>  }
>>>  
>>> @@ -140,6 +188,9 @@ static int bgmac_probe(struct platform_device *pdev)
>>>  
>>>  	platform_set_drvdata(pdev, bgmac);
>>>  
>>> +	if (of_property_read_bool(np, "brcm,enet-phy-lane-swap"))
>>> +		bgmac->feature_flags |= BGMAC_FEAT_LANE_SWAP;
>>> +
>>>  	/* Set the features of the 4707 family */
>>>  	bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
>>>  	bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
>>> @@ -182,6 +233,14 @@ static int bgmac_probe(struct platform_device *pdev)
>>>  	if (IS_ERR(bgmac->plat.idm_base))
>>>  		return PTR_ERR(bgmac->plat.idm_base);
>>>  
>>> +	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base");
>>> +	if (regs) {
>>> +		bgmac->plat.nicpm_base = devm_ioremap_resource(&pdev->dev,
>>> +							       regs);
>>> +		if (IS_ERR(bgmac->plat.nicpm_base))
>>> +			return PTR_ERR(bgmac->plat.nicpm_base);
>>> +	}
>>> +
>>>  	bgmac->read = platform_bgmac_read;
>>>  	bgmac->write = platform_bgmac_write;
>>>  	bgmac->idm_read = platform_bgmac_idm_read;
>>> @@ -213,6 +272,7 @@ static int bgmac_remove(struct platform_device *pdev)
>>>  static const struct of_device_id bgmac_of_enet_match[] = {
>>>  	{.compatible = "brcm,amac",},
>>>  	{.compatible = "brcm,nsp-amac",},
>>> +	{.compatible = "brcm,ns2-amac",},
>>>  	{},
>>>  };
>>>  
>>> diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
>>> index 38876ec..1796208 100644
>>> --- a/drivers/net/ethernet/broadcom/bgmac.c
>>> +++ b/drivers/net/ethernet/broadcom/bgmac.c
>>> @@ -1082,6 +1082,9 @@ static void bgmac_enable(struct bgmac *bgmac)
>>>  /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */
>>>  static void bgmac_chip_init(struct bgmac *bgmac)
>>>  {
>>> +	/* Clear any erroneously pending interrupts */
>>> +	bgmac_write(bgmac, BGMAC_INT_STATUS, ~0);
>>> +
>>>  	/* 1 interrupt per received frame */
>>>  	bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
>>>  
>>> @@ -1158,8 +1161,6 @@ static int bgmac_open(struct net_device *net_dev)
>>>  	struct bgmac *bgmac = netdev_priv(net_dev);
>>>  	int err = 0;
>>>  
>>> -	bgmac_chip_reset(bgmac);
>>> -
>>
>> Is this removal intentional? Maybe it should be special cased with
>> checking for a NS2 BGMAC instance and not do it in that case?
> 
> The reset seems completely unnecessary.  There is already 2 resets in
> the probe routine, another reset serves no purpose.  I can add it
> back, as it does not seem to have the negative effect I was seeing
> before.

After repeated ifconfig down/up, does Ethernet still work with this
reset removed?

Thanks.

> 
> Of course, if I remove this one I should remove the reset in the close
> too (which seems even more unnecessary, but I didn't remove it).
> 
> Thanks,
> Jon
> 
>> -- 
>> Florian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 4/5] net: ethernet: bgmac: add NS2 support
From: Ray Jui @ 2016-10-27 22:32 UTC (permalink / raw)
  To: Jon Mason, Florian Fainelli
  Cc: David Miller, Rob Herring, Mark Rutland,
	rafal-g1n6cQUeyibVItvQsEIGlw,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <ccbaf726-b1fc-975a-215c-17e2870328a6-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>



On 10/27/2016 3:21 PM, Ray Jui wrote:
> 
> 
> On 10/27/2016 1:51 PM, Jon Mason wrote:
>> On Wed, Oct 26, 2016 at 02:50:39PM -0700, Florian Fainelli wrote:
>>> On 10/26/2016 12:36 PM, Jon Mason wrote:
>>>> Add support for the variant of amac hardware present in the Broadcom
>>>> Northstar2 based SoCs.  Northstar2 requires an additional register to be
>>>> configured with the port speed/duplexity (NICPM).  This can be added to
>>>> the link callback to hide it from the instances that do not use this.
>>>> Also, the bgmac_chip_reset() was intentionally removed to prevent the
>>>> resetting of the chip to the default values on open.  Finally, clearing
>>>> of the pending interrupts on init is required due to observed issues on
>>>> some platforms.
>>>>
>>>> Signed-off-by: Jon Mason <jon.mason-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
>>>> ---
>>>
>>>> +static void bgmac_nicpm_speed_set(struct net_device *net_dev)
>>>> +{
>>>> +	struct bgmac *bgmac = netdev_priv(net_dev);
>>>> +	u32 val;
>>>> +
>>>> +	if (!bgmac->plat.nicpm_base)
>>>> +		return;
>>>> +
>>>> +	val = NICPM_IOMUX_CTRL_INIT_VAL;
>>>> +	switch (bgmac->net_dev->phydev->speed) {
>>>> +	default:
>>>> +		pr_err("Unsupported speed.  Defaulting to 1000Mb\n");
>>>> +	case SPEED_1000:
>>>> +		val |= NICPM_IOMUX_CTRL_SPD_1000M << NICPM_IOMUX_CTRL_SPD_SHIFT;
>>>> +		break;
>>>> +	case SPEED_100:
>>>> +		val |= NICPM_IOMUX_CTRL_SPD_100M << NICPM_IOMUX_CTRL_SPD_SHIFT;
>>>> +		break;
>>>> +	case SPEED_10:
>>>> +		val |= NICPM_IOMUX_CTRL_SPD_10M << NICPM_IOMUX_CTRL_SPD_SHIFT;
>>>> +		break;
>>>> +	}
>>>> +
>>>> +	writel(val, bgmac->plat.nicpm_base + NICPM_IOMUX_CTRL);
>>>> +
>>>> +	usleep_range(10, 100);
>>>
>>> Does not seem like a good idea, do you need that sleep?
>>
>> Oops, that's not supposed to be there.  Removed.
>>
>>
>>>> +
>>>> +	bgmac_adjust_link(bgmac->net_dev);
>>>> +}
>>>> +
>>>>  static int platform_phy_connect(struct bgmac *bgmac)
>>>>  {
>>>>  	struct phy_device *phy_dev;
>>>>  
>>>> -	phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node,
>>>> -					 bgmac_adjust_link);
>>>> +	if (bgmac->plat.nicpm_base)
>>>> +		phy_dev = of_phy_get_and_connect(bgmac->net_dev,
>>>> +						 bgmac->dev->of_node,
>>>> +						 bgmac_nicpm_speed_set);
>>>> +	else
>>>> +		phy_dev = of_phy_get_and_connect(bgmac->net_dev,
>>>> +						 bgmac->dev->of_node,
>>>> +						 bgmac_adjust_link);
>>>>  	if (!phy_dev) {
>>>>  		dev_err(bgmac->dev, "Phy connect failed\n");
>>>>  		return -ENODEV;
>>>>  	}
>>>>  
>>>> +	if (bgmac->feature_flags & BGMAC_FEAT_LANE_SWAP)
>>>> +		phy_dev->dev_flags |= PHY_BRCM_EXP_LANE_SWAP;
>>>> +
>>>>  	return 0;
>>>>  }
>>>>  
>>>> @@ -140,6 +188,9 @@ static int bgmac_probe(struct platform_device *pdev)
>>>>  
>>>>  	platform_set_drvdata(pdev, bgmac);
>>>>  
>>>> +	if (of_property_read_bool(np, "brcm,enet-phy-lane-swap"))
>>>> +		bgmac->feature_flags |= BGMAC_FEAT_LANE_SWAP;
>>>> +
>>>>  	/* Set the features of the 4707 family */
>>>>  	bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
>>>>  	bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
>>>> @@ -182,6 +233,14 @@ static int bgmac_probe(struct platform_device *pdev)
>>>>  	if (IS_ERR(bgmac->plat.idm_base))
>>>>  		return PTR_ERR(bgmac->plat.idm_base);
>>>>  
>>>> +	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base");
>>>> +	if (regs) {
>>>> +		bgmac->plat.nicpm_base = devm_ioremap_resource(&pdev->dev,
>>>> +							       regs);
>>>> +		if (IS_ERR(bgmac->plat.nicpm_base))
>>>> +			return PTR_ERR(bgmac->plat.nicpm_base);
>>>> +	}
>>>> +
>>>>  	bgmac->read = platform_bgmac_read;
>>>>  	bgmac->write = platform_bgmac_write;
>>>>  	bgmac->idm_read = platform_bgmac_idm_read;
>>>> @@ -213,6 +272,7 @@ static int bgmac_remove(struct platform_device *pdev)
>>>>  static const struct of_device_id bgmac_of_enet_match[] = {
>>>>  	{.compatible = "brcm,amac",},
>>>>  	{.compatible = "brcm,nsp-amac",},
>>>> +	{.compatible = "brcm,ns2-amac",},
>>>>  	{},
>>>>  };
>>>>  
>>>> diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
>>>> index 38876ec..1796208 100644
>>>> --- a/drivers/net/ethernet/broadcom/bgmac.c
>>>> +++ b/drivers/net/ethernet/broadcom/bgmac.c
>>>> @@ -1082,6 +1082,9 @@ static void bgmac_enable(struct bgmac *bgmac)
>>>>  /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */
>>>>  static void bgmac_chip_init(struct bgmac *bgmac)
>>>>  {
>>>> +	/* Clear any erroneously pending interrupts */
>>>> +	bgmac_write(bgmac, BGMAC_INT_STATUS, ~0);
>>>> +
>>>>  	/* 1 interrupt per received frame */
>>>>  	bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
>>>>  
>>>> @@ -1158,8 +1161,6 @@ static int bgmac_open(struct net_device *net_dev)
>>>>  	struct bgmac *bgmac = netdev_priv(net_dev);
>>>>  	int err = 0;
>>>>  
>>>> -	bgmac_chip_reset(bgmac);
>>>> -
>>>
>>> Is this removal intentional? Maybe it should be special cased with
>>> checking for a NS2 BGMAC instance and not do it in that case?
>>
>> The reset seems completely unnecessary.  There is already 2 resets in
>> the probe routine, another reset serves no purpose.  I can add it
>> back, as it does not seem to have the negative effect I was seeing
>> before.
> 
> After repeated ifconfig down/up, does Ethernet still work with this
> reset removed?
> 
> Thanks.
> 

Sorry, I meant to say, after removing both reset calls in the open and
close functions, does Ethernet still work after repeated ifconfig
down/up with data traffic in the background?

I would guess this reset is required, to flush out and clean up the
internal memories and state machine of the AMAC core each time before
you bring up the interface. It might also be required in the close
function, such that after the interface bring down, there's no staled
data coming out of the AMAC core. But I cannot say for sure since I do
not try this out myself.

Thanks.

>>
>> Of course, if I remove this one I should remove the reset in the close
>> too (which seems even more unnecessary, but I didn't remove it).
>>
>> Thanks,
>> Jon
>>
>>> -- 
>>> Florian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v2 1/3] hwmon: (mcp3021) rework for DT support
From: Clemens Gruber @ 2016-10-27 22:33 UTC (permalink / raw)
  To: linux-hwmon
  Cc: Guenter Roeck, Rob Herring, Jean Delvare, devicetree, linux-doc,
	linux-kernel, Clemens Gruber

Support setting the reference voltage from the device tree.
Rework of driver structure, put chip specific data in a separate
structure and assign it depending on device id from platform data or
DT match.

Signed-off-by: Clemens Gruber <clemens.gruber@pqgruber.com>
---
 Documentation/hwmon/mcp3021 |   6 ++
 drivers/hwmon/mcp3021.c     | 145 ++++++++++++++++++++++++++++++++------------
 2 files changed, 111 insertions(+), 40 deletions(-)

diff --git a/Documentation/hwmon/mcp3021 b/Documentation/hwmon/mcp3021
index 74a6b72..be252b7 100644
--- a/Documentation/hwmon/mcp3021
+++ b/Documentation/hwmon/mcp3021
@@ -12,6 +12,7 @@ Supported chips:
 Authors:
    Mingkai Hu
    Sven Schuchmann <schuchmann@schleissheimer.de>
+   Clemens Gruber <clemens.gruber@pqgruber.com>
 
 Description
 -----------
@@ -27,3 +28,8 @@ Communication to the MCP3021/MCP3221  is performed using a 2-wire I2C
 compatible interface. Standard (100 kHz) and Fast (400 kHz) I2C modes are
 available. The default I2C device address is 0x4d (contact the Microchip
 factory for additional address options).
+
+The reference voltage used in the conversion can be set through platform data
+in millivolt (for backwards compatibility) or via device tree in microvolt.
+Please refer to Documentation/devicetree/bindings/i2c/mcp3021.txt for details
+about the device tree bindings.
diff --git a/drivers/hwmon/mcp3021.c b/drivers/hwmon/mcp3021.c
index 972444a..a8cf97f 100644
--- a/drivers/hwmon/mcp3021.c
+++ b/drivers/hwmon/mcp3021.c
@@ -4,6 +4,7 @@
  * Copyright (C) 2008-2009, 2012 Freescale Semiconductor, Inc.
  * Author: Mingkai Hu <Mingkai.hu@freescale.com>
  * Reworked by Sven Schuchmann <schuchmann@schleissheimer.de>
+ * Copyright (C) 2016 Clemens Gruber <clemens.gruber@pqgruber.com>
  *
  * This driver export the value of analog input voltage to sysfs, the
  * voltage unit is mV. Through the sysfs interface, lm-sensors tool
@@ -22,37 +23,56 @@
 #include <linux/i2c.h>
 #include <linux/err.h>
 #include <linux/device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
-/* Vdd info */
+/* Vdd / reference voltage in millivolt */
 #define MCP3021_VDD_MAX		5500
 #define MCP3021_VDD_MIN		2700
-#define MCP3021_VDD_REF		3300
-
-/* output format */
-#define MCP3021_SAR_SHIFT	2
-#define MCP3021_SAR_MASK	0x3ff
-#define MCP3021_OUTPUT_RES	10	/* 10-bit resolution */
-
-#define MCP3221_SAR_SHIFT	0
-#define MCP3221_SAR_MASK	0xfff
-#define MCP3221_OUTPUT_RES	12	/* 12-bit resolution */
+#define MCP3021_VDD_DEFAULT	3300
 
 enum chips {
 	mcp3021,
 	mcp3221
 };
 
+struct mcp3021_chip_info {
+	u16 sar_shift;
+	u16 sar_mask;
+	u8 output_res;
+};
+
 /*
  * Client data (each client gets its own)
  */
 struct mcp3021_data {
 	struct device *hwmon_dev;
-	u32 vdd;	/* device power supply */
-	u16 sar_shift;
-	u16 sar_mask;
-	u8 output_res;
+	const struct mcp3021_chip_info *chip_info;
+	u32 vdd; /* device power supply and reference voltage in millivolt */
 };
 
+static const struct mcp3021_chip_info mcp3021_chip_info_tbl[] = {
+	[mcp3021] = {
+		.sar_shift = 2,
+		.sar_mask = 0x3ff,
+		.output_res = 10,	/* 10-bit resolution */
+	},
+	[mcp3221] = {
+		.sar_shift = 0,
+		.sar_mask = 0xfff,
+		.output_res = 12,	/* 12-bit resolution */
+	},
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id of_mcp3021_match[] = {
+	{ .compatible = "microchip,mcp3021", .data = (void *)mcp3021 },
+	{ .compatible = "microchip,mcp3221", .data = (void *)mcp3221 },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, of_mcp3021_match);
+#endif
+
 static int mcp3021_read16(struct i2c_client *client)
 {
 	struct mcp3021_data *data = i2c_get_clientdata(client);
@@ -73,14 +93,15 @@ static int mcp3021_read16(struct i2c_client *client)
 	 * The ten-bit output code is composed of the lower 4-bit of the
 	 * first byte and the upper 6-bit of the second byte.
 	 */
-	reg = (reg >> data->sar_shift) & data->sar_mask;
+	reg = (reg >> data->chip_info->sar_shift) & data->chip_info->sar_mask;
 
 	return reg;
 }
 
 static inline u16 volts_from_reg(struct mcp3021_data *data, u16 val)
 {
-	return DIV_ROUND_CLOSEST(data->vdd * val, 1 << data->output_res);
+	return DIV_ROUND_CLOSEST(data->vdd * val,
+				 1 << data->chip_info->output_res);
 }
 
 static ssize_t show_in_input(struct device *dev, struct device_attribute *attr,
@@ -101,44 +122,85 @@ static ssize_t show_in_input(struct device *dev, struct device_attribute *attr,
 
 static DEVICE_ATTR(in0_input, S_IRUGO, show_in_input, NULL);
 
-static int mcp3021_probe(struct i2c_client *client,
+#ifdef CONFIG_OF
+static int mcp3021_probe_dt(struct i2c_client *client,
 				const struct i2c_device_id *id)
 {
-	int err;
-	struct mcp3021_data *data = NULL;
+	struct mcp3021_data *data = i2c_get_clientdata(client);
+	struct device_node *np = client->dev.of_node;
+	const struct of_device_id *match;
+	int devid, ret;
 
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+	match = of_match_device(of_mcp3021_match, &client->dev);
+	if (!match)
 		return -ENODEV;
 
-	data = devm_kzalloc(&client->dev, sizeof(struct mcp3021_data),
-			    GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	i2c_set_clientdata(client, data);
+	devid = (int)(uintptr_t)match->data;
+	data->chip_info = &mcp3021_chip_info_tbl[devid];
 
-	switch (id->driver_data) {
-	case mcp3021:
-		data->sar_shift = MCP3021_SAR_SHIFT;
-		data->sar_mask = MCP3021_SAR_MASK;
-		data->output_res = MCP3021_OUTPUT_RES;
-		break;
-
-	case mcp3221:
-		data->sar_shift = MCP3221_SAR_SHIFT;
-		data->sar_mask = MCP3221_SAR_MASK;
-		data->output_res = MCP3221_OUTPUT_RES;
-		break;
+	ret = of_property_read_u32(np, "reference-voltage-microvolt",
+				   &data->vdd);
+	if (ret) {
+		/* fallback */
+		data->vdd = MCP3021_VDD_DEFAULT;
+		return 0;
 	}
 
+	/* Convert microvolt from DT to millivolt used in the formula */
+	data->vdd /= 1000;
+
+	if (data->vdd > MCP3021_VDD_MAX || data->vdd < MCP3021_VDD_MIN)
+		return -EINVAL;
+
+	return 0;
+}
+#else
+static int mcp3021_probe_dt(struct i2c_client *client,
+				const struct i2c_device_id *id)
+{
+	return 1;
+}
+#endif
+
+static int mcp3021_probe_pdata(struct i2c_client *client,
+				const struct i2c_device_id *id)
+{
+	struct mcp3021_data *data = i2c_get_clientdata(client);
+
+	data->chip_info = &mcp3021_chip_info_tbl[id->driver_data];
+
 	if (dev_get_platdata(&client->dev)) {
 		data->vdd = *(u32 *)dev_get_platdata(&client->dev);
 		if (data->vdd > MCP3021_VDD_MAX || data->vdd < MCP3021_VDD_MIN)
 			return -EINVAL;
 	} else {
-		data->vdd = MCP3021_VDD_REF;
+		data->vdd = MCP3021_VDD_DEFAULT;
 	}
 
+	return 0;
+}
+
+static int mcp3021_probe(struct i2c_client *client,
+				const struct i2c_device_id *id)
+{
+	struct mcp3021_data *data = NULL;
+	int err;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+		return -ENODEV;
+
+	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, data);
+
+	err = mcp3021_probe_dt(client, id);
+	if (err > 0)
+		mcp3021_probe_pdata(client, id);
+	else if (err < 0)
+		return err;
+
 	err = sysfs_create_file(&client->dev.kobj, &dev_attr_in0_input.attr);
 	if (err)
 		return err;
@@ -176,6 +238,9 @@ MODULE_DEVICE_TABLE(i2c, mcp3021_id);
 static struct i2c_driver mcp3021_driver = {
 	.driver = {
 		.name = "mcp3021",
+#ifdef CONFIG_OF
+		.of_match_table = of_match_ptr(of_mcp3021_match),
+#endif
 	},
 	.probe = mcp3021_probe,
 	.remove = mcp3021_remove,
-- 
2.10.1

^ permalink raw reply related

* [PATCH v2 2/3] hwmon: (mcp3021) add devicetree bindings documentation
From: Clemens Gruber @ 2016-10-27 22:33 UTC (permalink / raw)
  To: linux-hwmon-u79uwXL29TY76Z2rM5mHXA
  Cc: Guenter Roeck, Rob Herring, Jean Delvare,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Clemens Gruber
In-Reply-To: <20161027223345.16733-1-clemens.gruber-lZxf/j91sTNWk0Htik3J/w@public.gmane.org>

Document the devicetree bindings for the Microchip MCP3021/3221.

Signed-off-by: Clemens Gruber <clemens.gruber-lZxf/j91sTNWk0Htik3J/w@public.gmane.org>
---
 Documentation/devicetree/bindings/hwmon/mcp3021.txt | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwmon/mcp3021.txt

diff --git a/Documentation/devicetree/bindings/hwmon/mcp3021.txt b/Documentation/devicetree/bindings/hwmon/mcp3021.txt
new file mode 100644
index 0000000..294318b
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/mcp3021.txt
@@ -0,0 +1,21 @@
+mcp3021 properties
+
+Required properties:
+- compatible: Must be one of the following:
+	- "microchip,mcp3021" for mcp3021
+	- "microchip,mcp3221" for mcp3221
+- reg: I2C address
+
+Optional properties:
+
+- reference-voltage-microvolt
+	Reference voltage in microvolt (uV)
+
+Example:
+
+mcp3021@4d {
+	compatible = "microchip,mcp3021";
+	reg = <0x4d>;
+
+	reference-voltage-microvolt = <4500000>; /* 4.5 V */
+};
-- 
2.10.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v2 3/3] hwmon: (mcp3021) replace S_IRUGO with 0444
From: Clemens Gruber @ 2016-10-27 22:33 UTC (permalink / raw)
  To: linux-hwmon
  Cc: Guenter Roeck, Rob Herring, Jean Delvare, devicetree, linux-doc,
	linux-kernel, Clemens Gruber
In-Reply-To: <20161027223345.16733-1-clemens.gruber@pqgruber.com>

Replace S_IRUGO with the better readable 0444.
This fixes a checkpatch warning.

Signed-off-by: Clemens Gruber <clemens.gruber@pqgruber.com>
---
 drivers/hwmon/mcp3021.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwmon/mcp3021.c b/drivers/hwmon/mcp3021.c
index a8cf97f..97c832d 100644
--- a/drivers/hwmon/mcp3021.c
+++ b/drivers/hwmon/mcp3021.c
@@ -120,7 +120,7 @@ static ssize_t show_in_input(struct device *dev, struct device_attribute *attr,
 	return sprintf(buf, "%d\n", in_input);
 }
 
-static DEVICE_ATTR(in0_input, S_IRUGO, show_in_input, NULL);
+static DEVICE_ATTR(in0_input, 0444, show_in_input, NULL);
 
 #ifdef CONFIG_OF
 static int mcp3021_probe_dt(struct i2c_client *client,
-- 
2.10.1


^ permalink raw reply related

* Re: [PATCH 1/5] net: phy: broadcom: Add BCM54810 phy entry
From: Jon Mason @ 2016-10-27 22:43 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: David Miller, Rob Herring, Mark Rutland, Florian Fainelli,
	devicetree, netdev, linux-kernel, bcm-kernel-feedback-list, rafal,
	Vikas Soni, linux-arm-kernel
In-Reply-To: <20161027091505.GB12841@lunn.ch>

On Thu, Oct 27, 2016 at 11:15:05AM +0200, Andrew Lunn wrote:
> On Wed, Oct 26, 2016 at 03:35:57PM -0400, Jon Mason wrote:
> > From: Vikas Soni <vsoni@broadcom.com>
> > 
> > Add BCM54810 phy entry
> 
> Hi Jon, Vikis
> 
> The subject line is a bit misleading. It does more than add a PHY ID
> entry.

All of the parts are related to adding the BCM54810 Phy, but I agree it
could be more verbose about what is happening.

> > Signed-off-by: Vikas Soni <vsoni@broadcom.com>
> > Signed-off-by: Jon Mason <jon.mason@broadcom.com>
> > ---
> >  drivers/net/phy/Kconfig    |  2 +-
> >  drivers/net/phy/broadcom.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/brcmphy.h    |  7 +++++
> >  3 files changed, 73 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
> > index 45f68ea..31967ca 100644
> > --- a/drivers/net/phy/Kconfig
> > +++ b/drivers/net/phy/Kconfig
> > @@ -217,7 +217,7 @@ config BROADCOM_PHY
> >  	select BCM_NET_PHYLIB
> >  	---help---
> >  	  Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464,
> > -	  BCM5481 and BCM5482 PHYs.
> > +	  BCM5481, BCM54810 and BCM5482 PHYs.
> >  
> >  config CICADA_PHY
> >  	tristate "Cicada PHYs"
> > diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
> > index 870327e..cdce761 100644
> > --- a/drivers/net/phy/broadcom.c
> > +++ b/drivers/net/phy/broadcom.c
> > @@ -35,6 +35,35 @@ static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
> >  	return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
> >  }
> >  
> > +static int bcm54810_config(struct phy_device *phydev)
> > +{
> > +	int rc;
> > +
> > +	/* Disable BroadR-Reach */
> > +	rc = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL, 0);
> > +	if (rc < 0)
> > +		return rc;
> > +
> > +	/* SKEW DISABLE */
> > +	rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
> > +				  0xF0E0);
> > +	if (rc < 0)
> > +		return rc;
> > +
> > +	/* DELAY DISABLE */
> > +	rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
> > +				  0x7000);
> 
> This driver mostly uses symbolic names, not #defines. Please can you
> use #defines here and else were in this patch.

Will do.  After looking at this, this appears to be setup for a read
that doesn't follow.  I'll audit this, clean it up and resend.

 
> > +	if (rc < 0)
> > +		return rc;
> > +
> > +	/* DELAY DISABLE */
> > +	rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, 0);
> > +	if (rc < 0)
> > +		return rc;
> 
> Twice the same comment?
>
> > +
> > +	return 0;
> > +}
> > +
> >  /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */
> >  static int bcm50610_a0_workaround(struct phy_device *phydev)
> >  {
> > @@ -207,6 +236,20 @@ static int bcm54xx_config_init(struct phy_device *phydev)
> >  	    (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
> >  		bcm54xx_adjust_rxrefclk(phydev);
> >  
> > +	if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) {
> > +		err = bcm54810_config(phydev);
> > +		if (err)
> > +			return err;
> > +
> > +		reg = phy_read(phydev, MII_BMCR);
> > +		if (reg < 0)
> > +			return reg;
> > +
> > +		err = phy_write(phydev, MII_BMCR, reg & ~BMCR_PDOWN);
> > +		if (err)
> > +			return err;
> 
> This seems a bit odd. I would expect the PHY core correctly handles
> the PHY being powered down. Can you explain this a bit more, why it is
> needed.

I believe it was needed in earlier versions of the code, but doesn't
seem to be needed anymore.  Removing.

> 
> 	Thanks
> 		Andrew

^ permalink raw reply

* Re: [PATCH v3 1/3] PM / OPP: Expose _of_get_opp_desc_node as dev_pm_opp API
From: kbuild test robot @ 2016-10-27 23:34 UTC (permalink / raw)
  Cc: kbuild-all, Viresh Kumar, Rob Herring, linux-arm-kernel,
	linux-omap, linux-pm, devicetree, Rafael J . Wysocki,
	Tony Lindgren, Nishanth Menon, Dave Gerlach
In-Reply-To: <20161027214131.1725-2-d-gerlach@ti.com>

[-- Attachment #1: Type: text/plain, Size: 5105 bytes --]

Hi Dave,

[auto build test ERROR on robh/for-next]
[also build test ERROR on v4.9-rc2]
[cannot apply to pm/linux-next next-20161027]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
[Suggest to use git(>=2.9.0) format-patch --base=<commit> (or --base=auto for convenience) to record what (public, well-known) commit your patch series was built on]
[Check https://git-scm.com/docs/git-format-patch for more information]

url:    https://github.com/0day-ci/linux/commits/Dave-Gerlach/cpufreq-Introduce-TI-CPUFreq-OPP-Driver/20161028-054633
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: xtensa-allmodconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 4.9.0
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=xtensa 

All errors (new ones prefixed by >>):

   drivers/base/power/opp/of.c:184:6: error: redefinition of 'dev_pm_opp_of_remove_table'
    void dev_pm_opp_of_remove_table(struct device *dev)
         ^
   In file included from drivers/base/power/opp/opp.h:21:0,
                    from drivers/base/power/opp/of.c:22:
   include/linux/pm_opp.h:218:20: note: previous definition of 'dev_pm_opp_of_remove_table' was here
    static inline void dev_pm_opp_of_remove_table(struct device *dev)
                       ^
>> drivers/base/power/opp/of.c:191:21: error: redefinition of 'dev_pm_opp_of_get_opp_desc_node'
    struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev)
                        ^
   In file included from drivers/base/power/opp/opp.h:21:0,
                    from drivers/base/power/opp/of.c:22:
   include/linux/pm_opp.h:236:35: note: previous definition of 'dev_pm_opp_of_get_opp_desc_node' was here
    static inline struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev)
                                      ^
   drivers/base/power/opp/of.c:434:5: error: redefinition of 'dev_pm_opp_of_add_table'
    int dev_pm_opp_of_add_table(struct device *dev)
        ^
   In file included from drivers/base/power/opp/opp.h:21:0,
                    from drivers/base/power/opp/of.c:22:
   include/linux/pm_opp.h:213:19: note: previous definition of 'dev_pm_opp_of_add_table' was here
    static inline int dev_pm_opp_of_add_table(struct device *dev)
                      ^
   drivers/base/power/opp/of.c:474:6: error: redefinition of 'dev_pm_opp_of_cpumask_remove_table'
    void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask)
         ^
   In file included from drivers/base/power/opp/opp.h:21:0,
                    from drivers/base/power/opp/of.c:22:
   include/linux/pm_opp.h:227:20: note: previous definition of 'dev_pm_opp_of_cpumask_remove_table' was here
    static inline void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask)
                       ^
   drivers/base/power/opp/of.c:492:5: error: redefinition of 'dev_pm_opp_of_cpumask_add_table'
    int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask)
        ^
   In file included from drivers/base/power/opp/opp.h:21:0,
                    from drivers/base/power/opp/of.c:22:
   include/linux/pm_opp.h:222:19: note: previous definition of 'dev_pm_opp_of_cpumask_add_table' was here
    static inline int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask)
                      ^
   drivers/base/power/opp/of.c:545:5: error: redefinition of 'dev_pm_opp_of_get_sharing_cpus'
    int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev,
        ^
   In file included from drivers/base/power/opp/opp.h:21:0,
                    from drivers/base/power/opp/of.c:22:
   include/linux/pm_opp.h:231:19: note: previous definition of 'dev_pm_opp_of_get_sharing_cpus' was here
    static inline int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
                      ^

vim +/dev_pm_opp_of_get_opp_desc_node +191 drivers/base/power/opp/of.c

   178	 * Locking: The internal opp_table and opp structures are RCU protected.
   179	 * Hence this function indirectly uses RCU updater strategy with mutex locks
   180	 * to keep the integrity of the internal data structures. Callers should ensure
   181	 * that this function is *NOT* called under RCU protection or in contexts where
   182	 * mutex cannot be locked.
   183	 */
 > 184	void dev_pm_opp_of_remove_table(struct device *dev)
   185	{
   186		_dev_pm_opp_remove_table(dev, false);
   187	}
   188	EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table);
   189	
   190	/* Returns opp descriptor node for a device, caller must do of_node_put() */
 > 191	struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev)
   192	{
   193		/*
   194		 * TODO: Support for multiple OPP tables.

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 46043 bytes --]

^ 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