Devicetree
 help / color / mirror / Atom feed
* [PATCH 05/12] ARM: dts: imx6-sabresd: add OV5642 and OV5640 camera sensors
From: Steve Longerbeam @ 2016-12-08  0:57 UTC (permalink / raw)
  To: shawnguo-DgEjT+Ai2ygdnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	fabio.estevam-3arQi8VN3Tc, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
	tomi.valkeinen-l0cyMroinI0, p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Steve Longerbeam
In-Reply-To: <1481158673-15937-1-git-send-email-steve_longerbeam-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>

Enables the OV5642 parallel-bus sensor, and the OV5640 MIPI CSI-2 sensor.

The OV5642 connects to the parallel-bus mux input port on ipu1_csi0_mux.

The OV5640 connects to the input port on the MIPI CSI-2 receiver on
mipi_csi. It is set to transmit over MIPI virtual channel 1.

Until the OV5652 sensor module compatible with the SabreSD becomes
available for testing, the ov5642 node is currently disabled.

Signed-off-by: Steve Longerbeam <steve_longerbeam-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>
---
 arch/arm/boot/dts/imx6dl-sabresd.dts   |   5 ++
 arch/arm/boot/dts/imx6q-sabresd.dts    |   5 ++
 arch/arm/boot/dts/imx6qdl-sabresd.dtsi | 114 ++++++++++++++++++++++++++++++++-
 3 files changed, 123 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx6dl-sabresd.dts b/arch/arm/boot/dts/imx6dl-sabresd.dts
index 1e45f2f..6cf7a50 100644
--- a/arch/arm/boot/dts/imx6dl-sabresd.dts
+++ b/arch/arm/boot/dts/imx6dl-sabresd.dts
@@ -15,3 +15,8 @@
 	model = "Freescale i.MX6 DualLite SABRE Smart Device Board";
 	compatible = "fsl,imx6dl-sabresd", "fsl,imx6dl";
 };
+
+&ipu1_csi1_from_ipu1_csi1_mux {
+	data-lanes = <0 1>;
+	clock-lanes = <2>;
+};
diff --git a/arch/arm/boot/dts/imx6q-sabresd.dts b/arch/arm/boot/dts/imx6q-sabresd.dts
index 9cbdfe7..8c1d7ad 100644
--- a/arch/arm/boot/dts/imx6q-sabresd.dts
+++ b/arch/arm/boot/dts/imx6q-sabresd.dts
@@ -23,3 +23,8 @@
 &sata {
 	status = "okay";
 };
+
+&ipu1_csi1_from_mipi_vc1 {
+	data-lanes = <0 1>;
+	clock-lanes = <2>;
+};
diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
index 8e9e0d9..e36e1e7 100644
--- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
@@ -10,6 +10,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
+#include <dt-bindings/clock/imx6qdl-clock.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 
@@ -146,6 +147,33 @@
 	};
 };
 
+&ipu1_csi0_from_ipu1_csi0_mux {
+	bus-width = <8>;
+	data-shift = <12>; /* Lines 19:12 used */
+	hsync-active = <1>;
+	vsync-active = <1>;
+};
+
+&ipu1_csi0_mux_from_parallel_sensor {
+	remote-endpoint = <&ov5642_to_ipu1_csi0_mux>;
+};
+
+&ipu1_csi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ipu1_csi0>;
+};
+
+&mipi_csi {
+	status = "okay";
+};
+
+/* Incoming port from sensor */
+&mipi_csi_from_mipi_sensor {
+	remote-endpoint = <&ov5640_to_mipi_csi>;
+	data-lanes = <0 1>;
+	clock-lanes = <2>;
+};
+
 &audmux {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_audmux>;
@@ -214,7 +242,33 @@
 			0x8014 /* 4:FN_DMICCDAT */
 			0x0000 /* 5:Default */
 		>;
-       };
+	};
+
+	camera: ov5642@3c {
+		compatible = "ovti,ov5642";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ov5642>;
+		clocks = <&clks IMX6QDL_CLK_CKO>;
+		clock-names = "xclk";
+		reg = <0x3c>;
+		xclk = <24000000>;
+		DOVDD-supply = <&vgen4_reg>; /* 1.8v */
+		AVDD-supply = <&vgen5_reg>;  /* 2.8v, rev C board is VGEN3
+						rev B board is VGEN5 */
+		DVDD-supply = <&vgen2_reg>;  /* 1.5v*/
+		pwdn-gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>; /* SD1_DAT0 */
+		reset-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; /* SD1_DAT1 */
+		status = "disabled";
+
+		port {
+			ov5642_to_ipu1_csi0_mux: endpoint {
+				remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>;
+				bus-width = <8>;
+				hsync-active = <1>;
+				vsync-active = <1>;
+			};
+		};
+	};
 };
 
 &i2c2 {
@@ -322,6 +376,34 @@
 			};
 		};
 	};
+
+	mipi_camera: ov5640@3c {
+		compatible = "ovti,ov5640_mipi";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ov5640>;
+		reg = <0x3c>;
+		clocks = <&clks IMX6QDL_CLK_CKO>;
+		clock-names = "xclk";
+		xclk = <24000000>;
+		DOVDD-supply = <&vgen4_reg>; /* 1.8v */
+		AVDD-supply = <&vgen5_reg>;  /* 2.8v, rev C board is VGEN3
+						rev B board is VGEN5 */
+		DVDD-supply = <&vgen2_reg>;  /* 1.5v*/
+		pwdn-gpios = <&gpio1 19 GPIO_ACTIVE_HIGH>; /* SD1_DAT2 */
+		reset-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>; /* SD1_CLK */
+
+		port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			ov5640_to_mipi_csi: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&mipi_csi_from_mipi_sensor>;
+				data-lanes = <0 1>;
+				clock-lanes = <2>;
+			};
+		};
+	};
 };
 
 &i2c3 {
@@ -426,6 +508,36 @@
 			>;
 		};
 
+		pinctrl_ov5640: ov5640grp {
+			fsl,pins = <
+				MX6QDL_PAD_SD1_DAT2__GPIO1_IO19 0x80000000
+				MX6QDL_PAD_SD1_CLK__GPIO1_IO20  0x80000000
+			>;
+		};
+
+		pinctrl_ov5642: ov5642grp {
+			fsl,pins = <
+				MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x80000000
+				MX6QDL_PAD_SD1_DAT1__GPIO1_IO17 0x80000000
+			>;
+		};
+
+		pinctrl_ipu1_csi0: ipu1grp-csi0 {
+			fsl,pins = <
+				MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12    0x80000000
+				MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13    0x80000000
+				MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14    0x80000000
+				MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15    0x80000000
+				MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16    0x80000000
+				MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17    0x80000000
+				MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18    0x80000000
+				MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19    0x80000000
+				MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK   0x80000000
+				MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC      0x80000000
+				MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC     0x80000000
+			>;
+		};
+
 		pinctrl_pcie: pciegrp {
 			fsl,pins = <
 				MX6QDL_PAD_GPIO_17__GPIO7_IO12	0x1b0b0
-- 
2.7.4

--
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 04/12] ARM: dts: imx6-sabrelite: add OV5642 and OV5640 camera sensors
From: Steve Longerbeam @ 2016-12-08  0:57 UTC (permalink / raw)
  To: shawnguo, kernel, fabio.estevam, robh+dt, mark.rutland, linux,
	tomi.valkeinen, p.zabel
  Cc: devicetree, linux-fbdev, Steve Longerbeam, linux-kernel,
	dri-devel, linux-arm-kernel
In-Reply-To: <1481158673-15937-1-git-send-email-steve_longerbeam@mentor.com>

Enables the OV5642 parallel-bus sensor, and the OV5640 MIPI CSI-2 sensor.
Both hang off the same i2c2 bus, so they require different (and non-
default) i2c slave addresses.

The OV5642 connects to the parallel-bus mux input port on ipu1_csi0_mux.

The OV5640 connects to the input port on the MIPI CSI-2 receiver on
mipi_csi. It is set to transmit over MIPI virtual channel 1.

Note there is a pin conflict with GPIO6. This pin functions as a power
input pin to the OV5642, but ENET uses it as the h/w workaround for
erratum ERR006687, to wake-up the ARM cores on normal RX and TX packet
done events (see 6261c4c8). So workaround 6261c4c8 is reverted here to
support the OV5642, and the "fsl,err006687-workaround-present" boolean
also must be removed. The result is that the CPUidle driver will no longer
allow entering the deep idle states on the sabrelite.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
---
 arch/arm/boot/dts/imx6dl-sabrelite.dts   |   5 ++
 arch/arm/boot/dts/imx6q-sabrelite.dts    |   6 ++
 arch/arm/boot/dts/imx6qdl-sabrelite.dtsi | 122 ++++++++++++++++++++++++++++++-
 3 files changed, 129 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/imx6dl-sabrelite.dts b/arch/arm/boot/dts/imx6dl-sabrelite.dts
index 0f06ca5..fec2524 100644
--- a/arch/arm/boot/dts/imx6dl-sabrelite.dts
+++ b/arch/arm/boot/dts/imx6dl-sabrelite.dts
@@ -48,3 +48,8 @@
 	model = "Freescale i.MX6 DualLite SABRE Lite Board";
 	compatible = "fsl,imx6dl-sabrelite", "fsl,imx6dl";
 };
+
+&ipu1_csi1_from_ipu1_csi1_mux {
+	data-lanes = <0 1>;
+	clock-lanes = <2>;
+};
diff --git a/arch/arm/boot/dts/imx6q-sabrelite.dts b/arch/arm/boot/dts/imx6q-sabrelite.dts
index 66d10d8..9e2d26d 100644
--- a/arch/arm/boot/dts/imx6q-sabrelite.dts
+++ b/arch/arm/boot/dts/imx6q-sabrelite.dts
@@ -52,3 +52,9 @@
 &sata {
 	status = "okay";
 };
+
+&ipu1_csi1_from_mipi_vc1 {
+	data-lanes = <0 1>;
+	clock-lanes = <2>;
+};
+
diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
index 81dd6cd..d7fcb1a2 100644
--- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
@@ -39,6 +39,8 @@
  *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  *     OTHER DEALINGS IN THE SOFTWARE.
  */
+
+#include <dt-bindings/clock/imx6qdl-clock.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 
@@ -96,6 +98,15 @@
 		};
 	};
 
+	mipi_xclk: mipi_xclk {
+		compatible = "pwm-clock";
+		#clock-cells = <0>;
+		clock-frequency = <22000000>;
+		clock-output-names = "mipi_pwm3";
+		pwms = <&pwm3 0 45>; /* 1 / 45 ns = 22 MHz */
+		status = "okay";
+	};
+
 	gpio-keys {
 		compatible = "gpio-keys";
 		pinctrl-names = "default";
@@ -220,6 +231,22 @@
 	};
 };
 
+&ipu1_csi0_from_ipu1_csi0_mux {
+	bus-width = <8>;
+	data-shift = <12>; /* Lines 19:12 used */
+	hsync-active = <1>;
+	vync-active = <1>;
+};
+
+&ipu1_csi0_mux_from_parallel_sensor {
+	remote-endpoint = <&ov5642_to_ipu1_csi0_mux>;
+};
+
+&ipu1_csi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ipu1_csi0>;
+};
+
 &audmux {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_audmux>;
@@ -271,9 +298,6 @@
 	txd1-skew-ps = <0>;
 	txd2-skew-ps = <0>;
 	txd3-skew-ps = <0>;
-	interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
-			      <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
-	fsl,err006687-workaround-present;
 	status = "okay";
 };
 
@@ -302,6 +326,52 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_i2c2>;
 	status = "okay";
+
+	camera: ov5642@42 {
+		compatible = "ovti,ov5642";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ov5642>;
+		clocks = <&clks IMX6QDL_CLK_CKO2>;
+		clock-names = "xclk";
+		reg = <0x42>;
+		xclk = <24000000>;
+		reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
+		pwdn-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+		gp-gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
+
+		port {
+			ov5642_to_ipu1_csi0_mux: endpoint {
+				remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>;
+				bus-width = <8>;
+				hsync-active = <1>;
+				vsync-active = <1>;
+			};
+		};
+	};
+
+	mipi_camera: ov5640@40 {
+		compatible = "ovti,ov5640_mipi";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ov5640>;
+		clocks = <&mipi_xclk>;
+		clock-names = "xclk";
+		reg = <0x40>;
+		xclk = <22000000>;
+		reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; /* NANDF_D5 */
+		pwdn-gpios = <&gpio6 9 GPIO_ACTIVE_HIGH>; /* NANDF_WP_B */
+
+		port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			ov5640_to_mipi_csi: endpoint@1 {
+				reg = <1>;
+				remote-endpoint = <&mipi_csi_from_mipi_sensor>;
+				data-lanes = <0 1>;
+				clock-lanes = <2>;
+			};
+		};
+	};
 };
 
 &i2c3 {
@@ -374,7 +444,6 @@
 				MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	0x1b030
 				/* Phy reset */
 				MX6QDL_PAD_EIM_D23__GPIO3_IO23		0x000b0
-				MX6QDL_PAD_GPIO_6__ENET_IRQ		0x000b1
 			>;
 		};
 
@@ -449,6 +518,39 @@
 			>;
 		};
 
+		pinctrl_ov5642: ov5642grp {
+			fsl,pins = <
+				MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x80000000
+				MX6QDL_PAD_GPIO_6__GPIO1_IO06   0x80000000
+				MX6QDL_PAD_GPIO_8__GPIO1_IO08   0x80000000
+				MX6QDL_PAD_GPIO_3__CCM_CLKO2    0x80000000
+			>;
+		};
+
+		pinctrl_ipu1_csi0: ipu1grp-csi0 {
+			fsl,pins = <
+				MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12    0x80000000
+				MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13    0x80000000
+				MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14    0x80000000
+				MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15    0x80000000
+				MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16    0x80000000
+				MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17    0x80000000
+				MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18    0x80000000
+				MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19    0x80000000
+				MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK   0x80000000
+				MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC      0x80000000
+				MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC     0x80000000
+				MX6QDL_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN 0x80000000
+			>;
+		};
+
+                pinctrl_ov5640: ov5640grp {
+                        fsl,pins = <
+				MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x000b0
+				MX6QDL_PAD_NANDF_WP_B__GPIO6_IO09 0x0b0b0
+                        >;
+                };
+
 		pinctrl_pwm1: pwm1grp {
 			fsl,pins = <
 				MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
@@ -605,3 +707,15 @@
 	vmmc-supply = <&reg_3p3v>;
 	status = "okay";
 };
+
+&mipi_csi {
+        status = "okay";
+};
+
+/* Incoming port from sensor */
+&mipi_csi_from_mipi_sensor {
+        remote-endpoint = <&ov5640_to_mipi_csi>;
+        data-lanes = <0 1>;
+        clock-lanes = <2>;
+};
+
-- 
2.7.4

^ permalink raw reply related

* [PATCH 03/12] ARM: dts: imx6qdl: add video capture devices and connections
From: Steve Longerbeam @ 2016-12-08  0:57 UTC (permalink / raw)
  To: shawnguo, kernel, fabio.estevam, robh+dt, mark.rutland, linux,
	tomi.valkeinen, p.zabel
  Cc: linux-arm-kernel, devicetree, linux-kernel, linux-fbdev,
	dri-devel, Steve Longerbeam
In-Reply-To: <1481158673-15937-1-git-send-email-steve_longerbeam@mentor.com>

From: Philipp Zabel <p.zabel@pengutronix.de>

This patch adds the IPU subunit devices involved in video capture and
image conversion, and defines all the possible hardware connections
between them via OF graphs.

External to the IPU:

Video input multiplexers are defined that multiplex inputs from camera
sensors and the MIPI-CSI2 gasket, to the IPU CSIs.

On i.MX6Q/D two two-input multiplexers in front of IPU1 CSI0 and IPU2 CSI1
allow to select between CSI0/1 parallel input pads and the MIPI CSI-2 virtual
channels 0/3.

On i.MX6DL/S two five-input multiplexers in front of IPU1 CSI0 and IPU1 CSI1
allow to select between CSI0/1 parallel input pads and any of the four MIPI
CSI-2 virtual channels.

Internal to the IPU:

The IPU CSI, SMFC, IC-PRPENC, IC-PRPVF, and IC-PP subunits are added
as children of the IPUs, along with the hardware-supported connections
between them.

Finally, a media device node is defined. A video camera interface
and mem2mem device are defined as children of the media device.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 arch/arm/boot/dts/imx6dl.dtsi  | 190 ++++++++++++++++
 arch/arm/boot/dts/imx6q.dtsi   | 487 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/imx6qdl.dtsi | 368 +++++++++++++++++++++++++++++++
 3 files changed, 1045 insertions(+)

diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi
index 1ade195..4bab076 100644
--- a/arch/arm/boot/dts/imx6dl.dtsi
+++ b/arch/arm/boot/dts/imx6dl.dtsi
@@ -109,6 +109,120 @@
 		compatible = "fsl,imx-gpu-subsystem";
 		cores = <&gpu_2d>, <&gpu_3d>;
 	};
+
+	ipu1_csi0_mux: ipu1_csi0_mux@34 {
+		compatible = "imx-video-mux";
+		reg = <0x34 0x07>;
+		gpr = <&gpr>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "okay";
+		sink-ports = <5>;
+
+		port@0 {
+			reg = <0>;
+
+			ipu1_csi0_mux_from_mipi_vc0: endpoint {
+				remote-endpoint = <&mipi_vc0_to_ipu1_csi0_mux>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+
+			ipu1_csi0_mux_from_mipi_vc1: endpoint {
+				remote-endpoint = <&mipi_vc1_to_ipu1_csi0_mux>;
+			};
+		};
+
+		port@2 {
+			reg = <2>;
+
+			ipu1_csi0_mux_from_mipi_vc2: endpoint {
+				remote-endpoint = <&mipi_vc2_to_ipu1_csi0_mux>;
+			};
+		};
+
+		port@3 {
+			reg = <3>;
+
+			ipu1_csi0_mux_from_mipi_vc3: endpoint {
+				remote-endpoint = <&mipi_vc3_to_ipu1_csi0_mux>;
+			};
+		};
+
+		port@4 {
+			reg = <4>;
+
+			ipu1_csi0_mux_from_parallel_sensor: endpoint {
+			};
+		};
+
+		port@5 {
+			reg = <5>;
+
+			ipu1_csi0_mux_to_ipu1_csi0: endpoint {
+				remote-endpoint = <&ipu1_csi0_from_ipu1_csi0_mux>;
+			};
+		};
+	};
+
+	ipu1_csi1_mux: ipu1_csi1_mux@34 {
+		compatible = "imx-video-mux";
+		reg = <0x34 0x38>;
+		gpr = <&gpr>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "okay";
+		sink-ports = <5>;
+
+		port@0 {
+			reg = <0>;
+
+			ipu1_csi1_mux_from_mipi_vc0: endpoint {
+				remote-endpoint = <&mipi_vc0_to_ipu1_csi1_mux>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+
+			ipu1_csi1_mux_from_mipi_vc1: endpoint {
+				remote-endpoint = <&mipi_vc1_to_ipu1_csi1_mux>;
+			};
+		};
+
+		port@2 {
+			reg = <2>;
+
+			ipu1_csi1_mux_from_mipi_vc2: endpoint {
+				remote-endpoint = <&mipi_vc2_to_ipu1_csi1_mux>;
+			};
+		};
+
+		port@3 {
+			reg = <3>;
+
+			ipu1_csi1_mux_from_mipi_vc3: endpoint {
+				remote-endpoint = <&mipi_vc3_to_ipu1_csi1_mux>;
+			};
+		};
+
+		port@4 {
+			reg = <4>;
+
+			ipu1_csi1_mux_from_parallel_sensor: endpoint {
+			};
+		};
+
+		port@5 {
+			reg = <5>;
+
+			ipu1_csi1_mux_to_ipu1_csi1: endpoint {
+				remote-endpoint = <&ipu1_csi1_from_ipu1_csi1_mux>;
+			};
+		};
+	};
 };
 
 &gpio1 {
@@ -184,3 +298,79 @@
 &vpu {
 	compatible = "fsl,imx6dl-vpu", "cnm,coda960";
 };
+
+&ipu1_csi1 {
+	port@0 {
+		reg = <0>;
+		ipu1_csi1_from_ipu1_csi1_mux: endpoint {
+			remote-endpoint = <&ipu1_csi1_mux_to_ipu1_csi1>;
+		};
+	};
+};
+
+&mipi_csi {
+	sink-ports = <1>;
+
+	port@0 {
+		reg = <0>;
+
+		mipi_csi_from_mipi_sensor: endpoint {
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		mipi_vc0_to_ipu1_csi0_mux: endpoint@0 {
+			remote-endpoint = <&ipu1_csi0_mux_from_mipi_vc0>;
+		};
+
+		mipi_vc0_to_ipu1_csi1_mux: endpoint@1 {
+			remote-endpoint = <&ipu1_csi1_mux_from_mipi_vc0>;
+		};
+	};
+
+	port@2 {
+		reg = <2>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		mipi_vc1_to_ipu1_csi0_mux: endpoint@0 {
+			remote-endpoint = <&ipu1_csi0_mux_from_mipi_vc1>;
+		};
+
+		mipi_vc1_to_ipu1_csi1_mux: endpoint@1 {
+			remote-endpoint = <&ipu1_csi1_mux_from_mipi_vc1>;
+		};
+	};
+
+	port@3 {
+		reg = <3>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		mipi_vc2_to_ipu1_csi0_mux: endpoint@0 {
+			remote-endpoint = <&ipu1_csi0_mux_from_mipi_vc2>;
+		};
+
+		mipi_vc2_to_ipu1_csi1_mux: endpoint@1 {
+			remote-endpoint = <&ipu1_csi1_mux_from_mipi_vc2>;
+		};
+	};
+
+	port@4 {
+		reg = <4>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		mipi_vc3_to_ipu1_csi0_mux: endpoint@0 {
+			remote-endpoint = <&ipu1_csi0_mux_from_mipi_vc3>;
+		};
+
+		mipi_vc3_to_ipu1_csi1_mux: endpoint@1 {
+			remote-endpoint = <&ipu1_csi1_mux_from_mipi_vc3>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 2b261ba..a0602c5 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -142,11 +142,270 @@
 			resets = <&src 4>;
 
 			ipu2_csi0: ipu2_csi@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
 				reg = <0>;
+
+				port@0 {
+					reg = <0>;
+					ipu2_csi0_from_mipi_vc2: endpoint {
+						remote-endpoint = <&mipi_vc2_to_ipu2_csi0>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu2_csi0_to_smfc0: smfc0-endpoint {
+						remote-endpoint = <&ipu2_smfc0_from_csi0>;
+					};
+					ipu2_csi0_to_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu2_ic_prpvf_from_csi0>;
+					};
+					ipu2_csi0_to_ic_prpenc: prpenc-endpoint {
+						remote-endpoint = <&ipu2_ic_prpenc_from_csi0>;
+					};
+				};
 			};
 
 			ipu2_csi1: ipu2_csi@1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
 				reg = <1>;
+
+				port@0 {
+					reg = <0>;
+					ipu2_csi1_from_ipu2_csi1_mux: endpoint {
+						remote-endpoint = <&ipu2_csi1_mux_to_ipu2_csi1>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu2_csi1_to_smfc1: smfc1-endpoint {
+						remote-endpoint = <&ipu2_smfc1_from_csi1>;
+					};
+					ipu2_csi1_to_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu2_ic_prpvf_from_csi1>;
+					};
+					ipu2_csi1_to_ic_prpenc: prpenc-endpoint {
+						remote-endpoint = <&ipu2_ic_prpenc_from_csi1>;
+					};
+				};
+			};
+
+			ipu2_smfc0: ipu2_smfc@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
+				reg = <0>;
+
+				port@0 {
+					reg = <0>;
+					ipu2_smfc0_from_csi0: endpoint {
+						remote-endpoint = <&ipu2_csi0_to_smfc0>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu2_smfc0_to_ic_pp1: pp-endpoint {
+						remote-endpoint = <&ipu2_ic_pp1_from_smfc0>;
+					};
+					ipu2_smfc0_to_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu2_ic_prpvf_from_smfc0>;
+					};
+					ipu2_smfc0_to_camif2: camif2-endpoint {
+						remote-endpoint = <&camif2_from_smfc0>;
+					};
+					ipu2_smfc0_to_camif3: camif3-endpoint {
+						remote-endpoint = <&camif3_from_smfc0>;
+					};
+				};
+			};
+
+			ipu2_smfc1: ipu2_smfc@1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
+				reg = <1>;
+
+				port@0 {
+					reg = <0>;
+					ipu2_smfc1_from_csi1: endpoint {
+						remote-endpoint = <&ipu2_csi1_to_smfc1>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu2_smfc1_to_ic_pp2: pp-endpoint {
+						remote-endpoint = <&ipu2_ic_pp2_from_smfc1>;
+					};
+					ipu2_smfc1_to_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu2_ic_prpvf_from_smfc1>;
+					};
+					ipu2_smfc1_to_camif2: camif2-endpoint {
+						remote-endpoint = <&camif2_from_smfc1>;
+					};
+					ipu2_smfc1_to_camif3: camif3-endpoint {
+						remote-endpoint = <&camif3_from_smfc1>;
+					};
+				};
+			};
+
+			ipu2_ic_prpenc: ipu2_ic_prpenc@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
+				reg = <0>;
+
+				port@0 {
+					reg = <0>;
+					ipu2_ic_prpenc_from_csi0: csi0-endpoint {
+						remote-endpoint = <&ipu2_csi0_to_ic_prpenc>;
+					};
+					ipu2_ic_prpenc_from_csi1: csi1-endpoint {
+						remote-endpoint = <&ipu2_csi1_to_ic_prpenc>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu2_ic_prpenc_to_camif2: camif2-endpoint {
+						remote-endpoint = <&camif2_from_ic_prpenc>;
+					};
+					ipu2_ic_prpenc_to_camif3: camif3-endpoint {
+						remote-endpoint = <&camif3_from_ic_prpenc>;
+					};
+				};
+			};
+
+			ipu2_ic_prpvf: ipu2_ic_prpvf@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
+				reg = <0>;
+
+				port@0 {
+					reg = <0>;
+					ipu2_ic_prpvf_from_csi0: csi0-endpoint {
+						remote-endpoint = <&ipu2_csi0_to_ic_prpvf>;
+					};
+					ipu2_ic_prpvf_from_csi1: csi1-endpoint {
+						remote-endpoint = <&ipu2_csi1_to_ic_prpvf>;
+					};
+					ipu2_ic_prpvf_from_smfc0: smfc0-endpoint {
+						remote-endpoint = <&ipu2_smfc0_to_ic_prpvf>;
+					};
+					ipu2_ic_prpvf_from_smfc1: smfc1-endpoint {
+						remote-endpoint = <&ipu2_smfc1_to_ic_prpvf>;
+					};
+					ipu2_ic_prpvf_from_m2m1: m2m1-endpoint {
+						remote-endpoint = <&m2m1_to_ic_prpvf>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu2_ic_prpvf_to_camif2: camif2-endpoint {
+						remote-endpoint = <&camif2_from_ic_prpvf>;
+					};
+					ipu2_ic_prpvf_to_camif3: camif3-endpoint {
+						remote-endpoint = <&camif3_from_ic_prpvf>;
+					};
+					ipu2_ic_prpvf_to_ic_pp0: pp0-endpoint {
+						remote-endpoint = <&ipu2_ic_pp0_from_ic_prpvf>;
+					};
+					ipu2_ic_prpvf_to_ic_pp1: pp1-endpoint {
+						remote-endpoint = <&ipu2_ic_pp1_from_ic_prpvf>;
+					};
+					ipu2_ic_prpvf_to_ic_pp2: pp2-endpoint {
+						remote-endpoint = <&ipu2_ic_pp2_from_ic_prpvf>;
+					};
+					ipu2_ic_prpvf_to_m2m1: m2m1-endpoint {
+						remote-endpoint = <&m2m1_from_ic_prpvf>;
+					};
+				};
+			};
+
+			ipu2_ic_pp0: ipu2_ic_pp@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
+				reg = <0>;
+
+				port@0 {
+					reg = <0>;
+					ipu2_ic_pp0_from_m2m1: m2m1-endpoint {
+						remote-endpoint = <&m2m1_to_ic_pp0>;
+					};
+					ipu2_ic_pp0_from_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu2_ic_prpvf_to_ic_pp0>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu2_ic_pp0_to_m2m1: endpoint {
+						remote-endpoint = <&m2m1_from_ic_pp0>;
+					};
+				};
+			};
+
+			ipu2_ic_pp1: ipu2_ic_pp@1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
+				reg = <1>;
+
+				port@0 {
+					reg = <0>;
+					ipu2_ic_pp1_from_smfc0: smfc0-endpoint {
+						remote-endpoint = <&ipu2_smfc0_to_ic_pp1>;
+					};
+					ipu2_ic_pp1_from_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu2_ic_prpvf_to_ic_pp1>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu2_ic_pp1_to_camif2: camif2-endpoint {
+						remote-endpoint = <&camif2_from_ic_pp1>;
+					};
+					ipu2_ic_pp1_to_camif3: camif3-endpoint {
+						remote-endpoint = <&camif3_from_ic_pp1>;
+					};
+				};
+			};
+
+			ipu2_ic_pp2: ipu2_ic_pp@2 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
+				reg = <2>;
+
+				port@0 {
+					reg = <0>;
+					ipu2_ic_pp2_from_smfc1: smfc1-endpoint {
+						remote-endpoint = <&ipu2_smfc1_to_ic_pp2>;
+					};
+					ipu2_ic_pp2_from_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu2_ic_prpvf_to_ic_pp2>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu2_ic_pp2_to_camif2: camif2-endpoint {
+						remote-endpoint = <&camif2_from_ic_pp2>;
+					};
+					ipu2_ic_pp2_to_camif3: camif3-endpoint {
+						remote-endpoint = <&camif3_from_ic_pp2>;
+					};
+				};
 			};
 
 			ipu2_di0: ipu2_di@0 {
@@ -207,6 +466,73 @@
 		compatible = "fsl,imx-gpu-subsystem";
 		cores = <&gpu_2d>, <&gpu_3d>, <&gpu_vg>;
 	};
+
+
+	ipu1_csi0_mux: ipu1_csi0_mux@4 {
+		compatible = "imx-video-mux";
+		reg = <0x04 0x80000>;
+		gpr = <&gpr>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "okay";
+		sink-ports = <2>;
+
+		port@0 {
+			reg = <0>;
+
+			ipu1_csi0_mux_from_mipi_vc0: endpoint {
+				remote-endpoint = <&mipi_vc0_to_ipu1_csi0_mux>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+
+			ipu1_csi0_mux_from_parallel_sensor: endpoint {
+			};
+		};
+
+		port@2 {
+			reg = <2>;
+
+			ipu1_csi0_mux_to_ipu1_csi0: endpoint {
+				remote-endpoint = <&ipu1_csi0_from_ipu1_csi0_mux>;
+			};
+		};
+	};
+
+	ipu2_csi1_mux: ipu2_csi1_mux@4 {
+		compatible = "imx-video-mux";
+		reg = <0x04 0x100000>;
+		gpr = <&gpr>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "okay";
+		sink-ports = <2>;
+
+		port@0 {
+			reg = <0>;
+
+			ipu2_csi1_mux_from_mipi_vc3: endpoint {
+				remote-endpoint = <&mipi_vc3_to_ipu2_csi1_mux>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+
+			ipu2_csi1_mux_from_parallel_sensor: endpoint {
+			};
+		};
+
+		port@2 {
+			reg = <2>;
+
+			ipu2_csi1_mux_to_ipu2_csi1: endpoint {
+				remote-endpoint = <&ipu2_csi1_from_ipu2_csi1_mux>;
+			};
+		};
+	};
 };
 
 &gpio1 {
@@ -266,6 +592,15 @@
 	};
 };
 
+&ipu1_csi1 {
+	port@0 {
+		reg = <0>;
+		ipu1_csi1_from_mipi_vc1: endpoint {
+			remote-endpoint = <&mipi_vc1_to_ipu1_csi1>;
+		};
+	};
+};
+
 &ldb {
 	clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_SEL>,
 		 <&clks IMX6QDL_CLK_IPU1_DI0_SEL>, <&clks IMX6QDL_CLK_IPU1_DI1_SEL>,
@@ -312,6 +647,49 @@
 	};
 };
 
+&mipi_csi {
+	sink-ports = <1>;
+
+	port@0 {
+		reg = <0>;
+
+		mipi_csi_from_mipi_sensor: endpoint {
+		};
+	};
+
+	port@1 {
+		reg = <1>;
+
+		mipi_vc0_to_ipu1_csi0_mux: endpoint {
+			remote-endpoint = <&ipu1_csi0_mux_from_mipi_vc0>;
+		};
+	};
+
+	port@2 {
+		reg = <2>;
+
+		mipi_vc1_to_ipu1_csi1: endpoint {
+			remote-endpoint = <&ipu1_csi1_from_mipi_vc1>;
+		};
+	};
+
+	port@3 {
+		reg = <3>;
+
+		mipi_vc2_to_ipu2_csi0: endpoint {
+			remote-endpoint = <&ipu2_csi0_from_mipi_vc2>;
+		};
+	};
+
+	port@4 {
+		reg = <4>;
+
+		mipi_vc3_to_ipu2_csi1_mux: endpoint {
+			remote-endpoint = <&ipu2_csi1_mux_from_mipi_vc3>;
+		};
+	};
+};
+
 &mipi_dsi {
 	ports {
 		port@2 {
@@ -335,3 +713,112 @@
 &vpu {
 	compatible = "fsl,imx6q-vpu", "cnm,coda960";
 };
+
+&media0 {
+	m2m1: m2m@1 {
+		compatible = "fsl,imx-media-mem2mem";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "okay";
+		sink-ports = <2>;
+		reg = <1>;
+
+		port@0 {
+			reg = <0>;
+		};
+
+		port@1 {
+			reg = <1>;
+			m2m1_from_ic_pp0: endpoint {
+				remote-endpoint = <&ipu2_ic_pp0_to_m2m1>;
+			};
+			m2m1_from_ic_prpvf: prpvf-endpoint {
+				remote-endpoint = <&ipu2_ic_prpvf_to_m2m1>;
+			};
+		};
+
+		port@2 {
+			reg = <2>;
+			m2m1_to_ic_prpvf: prpvf-endpoint {
+				remote-endpoint = <&ipu2_ic_prpvf_from_m2m1>;
+			};
+			m2m1_to_ic_pp0: pp0-endpoint {
+				remote-endpoint = <&ipu2_ic_pp0_from_m2m1>;
+			};
+		};
+
+		port@3 {
+			reg = <3>;
+		};
+	};
+
+	camif2: camif@2 {
+		compatible = "fsl,imx-media-camif";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "okay";
+		sink-ports = <1>;
+		reg = <2>;
+
+		port@0 {
+			reg = <0>;
+			camif2_from_smfc0: smfc0-endpoint {
+				remote-endpoint = <&ipu2_smfc0_to_camif2>;
+			};
+			camif2_from_smfc1: smfc1-endpoint {
+				remote-endpoint = <&ipu2_smfc1_to_camif2>;
+			};
+			camif2_from_ic_prpenc: prpenc-endpoint {
+				remote-endpoint = <&ipu2_ic_prpenc_to_camif2>;
+			};
+			camif2_from_ic_prpvf: prpvf-endpoint {
+				remote-endpoint = <&ipu2_ic_prpvf_to_camif2>;
+			};
+			camif2_from_ic_pp1: pp1-endpoint {
+				remote-endpoint = <&ipu2_ic_pp1_to_camif2>;
+			};
+			camif2_from_ic_pp2: pp2-endpoint {
+				remote-endpoint = <&ipu2_ic_pp2_to_camif2>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+		};
+	};
+
+	camif3: camif@3 {
+		compatible = "fsl,imx-media-camif";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "okay";
+		sink-ports = <1>;
+		reg = <3>;
+
+		port@0 {
+			reg = <0>;
+			camif3_from_smfc0: smfc0-endpoint {
+				remote-endpoint = <&ipu2_smfc0_to_camif3>;
+			};
+			camif3_from_smfc1: smfc1-endpoint {
+				remote-endpoint = <&ipu2_smfc1_to_camif3>;
+			};
+			camif3_from_ic_prpenc: prpenc-endpoint {
+				remote-endpoint = <&ipu2_ic_prpenc_to_camif3>;
+			};
+			camif3_from_ic_prpvf: prpvf-endpoint {
+				remote-endpoint = <&ipu2_ic_prpvf_to_camif3>;
+			};
+			camif3_from_ic_pp1: pp1-endpoint {
+				remote-endpoint = <&ipu2_ic_pp1_to_camif3>;
+			};
+			camif3_from_ic_pp2: pp2-endpoint {
+				remote-endpoint = <&ipu2_ic_pp2_to_camif3>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 2465187..ea1e2f3 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -1123,6 +1123,8 @@
 			mipi_csi: mipi@021dc000 {
 				compatible = "fsl,imx-mipi-csi2";
 				reg = <0x021dc000 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
 				interrupts = <0 100 0x04>, <0 101 0x04>;
 				clocks = <&clks IMX6QDL_CLK_HSI_TX>,
 					 <&clks IMX6QDL_CLK_VIDEO_27M>,
@@ -1227,11 +1229,263 @@
 			resets = <&src 2>;
 
 			ipu1_csi0: ipu1_csi@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
 				reg = <0>;
+
+				port@0 {
+					reg = <0>;
+					ipu1_csi0_from_ipu1_csi0_mux: endpoint {
+						remote-endpoint = <&ipu1_csi0_mux_to_ipu1_csi0>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu1_csi0_to_smfc0: smfc0-endpoint {
+						remote-endpoint = <&ipu1_smfc0_from_csi0>;
+					};
+					ipu1_csi0_to_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu1_ic_prpvf_from_csi0>;
+					};
+					ipu1_csi0_to_ic_prpenc: prpenc-endpoint {
+						remote-endpoint = <&ipu1_ic_prpenc_from_csi0>;
+					};
+				};
 			};
 
 			ipu1_csi1: ipu1_csi@1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
+				reg = <1>;
+
+				port@1 {
+					reg = <1>;
+					ipu1_csi1_to_smfc1: smfc1-endpoint {
+						remote-endpoint = <&ipu1_smfc1_from_csi1>;
+					};
+					ipu1_csi1_to_ic_prpvf: prendpoint {
+						remote-endpoint = <&ipu1_ic_prpvf_from_csi1>;
+					};
+					ipu1_csi1_to_ic_prpenc: prpenc-endpoint {
+						remote-endpoint = <&ipu1_ic_prpenc_from_csi1>;
+					};
+				};
+			};
+
+			ipu1_smfc0: ipu1_smfc@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
+				reg = <0>;
+
+				port@0 {
+					reg = <0>;
+					ipu1_smfc0_from_csi0: endpoint {
+						remote-endpoint = <&ipu1_csi0_to_smfc0>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu1_smfc0_to_ic_pp1: pp-endpoint {
+						remote-endpoint = <&ipu1_ic_pp1_from_smfc0>;
+					};
+					ipu1_smfc0_to_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu1_ic_prpvf_from_smfc0>;
+					};
+					ipu1_smfc0_to_camif0: camif0-endpoint {
+						remote-endpoint = <&camif0_from_smfc0>;
+					};
+					ipu1_smfc0_to_camif1: camif1-endpoint {
+						remote-endpoint = <&camif1_from_smfc0>;
+					};
+				};
+			};
+
+			ipu1_smfc1: ipu1_smfc@1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
 				reg = <1>;
+
+				port@0 {
+					reg = <0>;
+					ipu1_smfc1_from_csi1: endpoint {
+						remote-endpoint = <&ipu1_csi1_to_smfc1>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu1_smfc1_to_ic_pp2: pp-endpoint {
+						remote-endpoint = <&ipu1_ic_pp2_from_smfc1>;
+					};
+					ipu1_smfc1_to_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu1_ic_prpvf_from_smfc1>;
+					};
+					ipu1_smfc1_to_camif0: camif0-endpoint {
+						remote-endpoint = <&camif0_from_smfc1>;
+					};
+					ipu1_smfc1_to_camif1: camif1-endpoint {
+						remote-endpoint = <&camif1_from_smfc1>;
+					};
+				};
+			};
+
+			ipu1_ic_prpenc: ipu1_ic_prpenc@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
+				reg = <0>;
+
+				port@0 {
+					reg = <0>;
+					ipu1_ic_prpenc_from_csi0: csi0-endpoint {
+						remote-endpoint = <&ipu1_csi0_to_ic_prpenc>;
+					};
+					ipu1_ic_prpenc_from_csi1: csi1-endpoint {
+						remote-endpoint = <&ipu1_csi1_to_ic_prpenc>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu1_ic_prpenc_to_camif0: camif0-endpoint {
+						remote-endpoint = <&camif0_from_ic_prpenc>;
+					};
+					ipu1_ic_prpenc_to_camif1: camif1-endpoint {
+						remote-endpoint = <&camif1_from_ic_prpenc>;
+					};
+				};
+			};
+
+			ipu1_ic_prpvf: ipu1_ic_prpvf@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
+				reg = <0>;
+
+				port@0 {
+					reg = <0>;
+					ipu1_ic_prpvf_from_csi0: csi0-endpoint {
+						remote-endpoint = <&ipu1_csi0_to_ic_prpvf>;
+					};
+					ipu1_ic_prpvf_from_csi1: csi1-endpoint {
+						remote-endpoint = <&ipu1_csi1_to_ic_prpvf>;
+					};
+					ipu1_ic_prpvf_from_smfc0: smfc0-endpoint {
+						remote-endpoint = <&ipu1_smfc0_to_ic_prpvf>;
+					};
+					ipu1_ic_prpvf_from_smfc1: smfc1-endpoint {
+						remote-endpoint = <&ipu1_smfc1_to_ic_prpvf>;
+					};
+					ipu1_ic_prpvf_from_m2m0: m2m0-endpoint {
+						remote-endpoint = <&m2m0_to_ic_prpvf>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu1_ic_prpvf_to_camif0: camif0-endpoint {
+						remote-endpoint = <&camif0_from_ic_prpvf>;
+					};
+					ipu1_ic_prpvf_to_camif1: camif1-endpoint {
+						remote-endpoint = <&camif1_from_ic_prpvf>;
+					};
+					ipu1_ic_prpvf_to_ic_pp0: pp0-endpoint {
+						remote-endpoint = <&ipu1_ic_pp0_from_ic_prpvf>;
+					};
+					ipu1_ic_prpvf_to_ic_pp1: pp1-endpoint {
+						remote-endpoint = <&ipu1_ic_pp1_from_ic_prpvf>;
+					};
+					ipu1_ic_prpvf_to_ic_pp2: pp2-endpoint {
+						remote-endpoint = <&ipu1_ic_pp2_from_ic_prpvf>;
+					};
+					ipu1_ic_prpvf_to_m2m0: m2m0-endpoint {
+						remote-endpoint = <&m2m0_from_ic_prpvf>;
+					};
+				};
+			};
+
+			ipu1_ic_pp0: ipu1_ic_pp@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
+				reg = <0>;
+
+				port@0 {
+					reg = <0>;
+					ipu1_ic_pp0_from_m2m0: m2m0-endpoint {
+						remote-endpoint = <&m2m0_to_ic_pp0>;
+					};
+					ipu1_ic_pp0_from_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu1_ic_prpvf_to_ic_pp0>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu1_ic_pp0_to_m2m0: endpoint {
+						remote-endpoint = <&m2m0_from_ic_pp0>;
+					};
+				};
+			};
+
+			ipu1_ic_pp1: ipu1_ic_pp@1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
+				reg = <1>;
+
+				port@0 {
+					reg = <0>;
+					ipu1_ic_pp1_from_smfc0: smfc0-endpoint {
+						remote-endpoint = <&ipu1_smfc0_to_ic_pp1>;
+					};
+					ipu1_ic_pp1_from_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu1_ic_prpvf_to_ic_pp1>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu1_ic_pp1_to_camif0: camif0-endpoint {
+						remote-endpoint = <&camif0_from_ic_pp1>;
+					};
+					ipu1_ic_pp1_to_camif1: camif1-endpoint {
+						remote-endpoint = <&camif1_from_ic_pp1>;
+					};
+				};
+			};
+
+			ipu1_ic_pp2: ipu1_ic_pp@2 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sink-ports = <1>;
+				reg = <2>;
+
+				port@0 {
+					reg = <0>;
+					ipu1_ic_pp2_from_smfc1: smfc1-endpoint {
+						remote-endpoint = <&ipu1_smfc1_to_ic_pp2>;
+					};
+					ipu1_ic_pp2_from_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu1_ic_prpvf_to_ic_pp2>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ipu1_ic_pp2_to_camif0: camif0-endpoint {
+						remote-endpoint = <&camif0_from_ic_pp2>;
+					};
+					ipu1_ic_pp2_to_camif1: camif1-endpoint {
+						remote-endpoint = <&camif1_from_ic_pp2>;
+					};
+				};
 			};
 
 			ipu1_di0: ipu1_di@0 {
@@ -1284,5 +1538,119 @@
 				};
 			};
 		};
+
+		media0: media@0 {
+			compatible = "fsl,imx-media", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "okay";
+
+			m2m0: m2m@0 {
+				compatible = "fsl,imx-media-mem2mem";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "okay";
+				sink-ports = <2>;
+				reg = <0>;
+
+				port@0 {
+					reg = <0>;
+				};
+
+				port@1 {
+					reg = <1>;
+					m2m0_from_ic_pp0: endpoint {
+						remote-endpoint = <&ipu1_ic_pp0_to_m2m0>;
+					};
+					m2m0_from_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu1_ic_prpvf_to_m2m0>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+					m2m0_to_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu1_ic_prpvf_from_m2m0>;
+					};
+					m2m0_to_ic_pp0: pp0-endpoint {
+						remote-endpoint = <&ipu1_ic_pp0_from_m2m0>;
+					};
+				};
+
+				port@3 {
+					reg = <3>;
+				};
+			};
+
+			camif0: camif@0 {
+				compatible = "fsl,imx-media-camif";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "okay";
+				sink-ports = <1>;
+				reg = <0>;
+
+				port@0 {
+					reg = <0>;
+					camif0_from_smfc0: smfc0-endpoint {
+						remote-endpoint = <&ipu1_smfc0_to_camif0>;
+					};
+					camif0_from_smfc1: smfc1-endpoint {
+						remote-endpoint = <&ipu1_smfc1_to_camif0>;
+					};
+					camif0_from_ic_prpenc: prpenc-endpoint {
+						remote-endpoint = <&ipu1_ic_prpenc_to_camif0>;
+					};
+					camif0_from_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu1_ic_prpvf_to_camif0>;
+					};
+					camif0_from_ic_pp1: pp1-endpoint {
+						remote-endpoint = <&ipu1_ic_pp1_to_camif0>;
+					};
+					camif0_from_ic_pp2: pp2-endpoint {
+						remote-endpoint = <&ipu1_ic_pp2_to_camif0>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+				};
+			};
+
+			camif1: camif@1 {
+				compatible = "fsl,imx-media-camif";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "okay";
+				sink-ports = <1>;
+				reg = <1>;
+
+				port@0 {
+					reg = <0>;
+					camif1_from_smfc0: smfc0-endpoint {
+						remote-endpoint = <&ipu1_smfc0_to_camif1>;
+					};
+					camif1_from_smfc1: smfc1-endpoint {
+						remote-endpoint = <&ipu1_smfc1_to_camif1>;
+					};
+					camif1_from_ic_prpenc: prpenc-endpoint {
+						remote-endpoint = <&ipu1_ic_prpenc_to_camif1>;
+					};
+					camif1_from_ic_prpvf: prpvf-endpoint {
+						remote-endpoint = <&ipu1_ic_prpvf_to_camif1>;
+					};
+					camif1_from_ic_pp1: pp1-endpoint {
+						remote-endpoint = <&ipu1_ic_pp1_to_camif1>;
+					};
+					camif1_from_ic_pp2: pp2-endpoint {
+						remote-endpoint = <&ipu1_ic_pp2_to_camif1>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+				};
+			};
+		};
 	};
 };
-- 
2.7.4

^ permalink raw reply related

* [PATCH 02/12] ARM: dts: imx6qdl: rename ipu client nodes
From: Steve Longerbeam @ 2016-12-08  0:57 UTC (permalink / raw)
  To: shawnguo, kernel, fabio.estevam, robh+dt, mark.rutland, linux,
	tomi.valkeinen, p.zabel
  Cc: linux-arm-kernel, devicetree, linux-kernel, linux-fbdev,
	dri-devel, Steve Longerbeam
In-Reply-To: <1481158673-15937-1-git-send-email-steve_longerbeam@mentor.com>

To allow for IPU client devices that are composed of more than one
port for input and output (SMFC and IC), change the nodes from being
a single port node to nodes that can contain multiple ports. Rename
the nodes to use the following format: "ipu<id>_<subunit>".

The IPUv3 driver will then need to lookup the client nodes by name
rather than by port id.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
---
 arch/arm/boot/dts/imx6q.dtsi   | 12 ++++++------
 arch/arm/boot/dts/imx6qdl.dtsi | 12 ++++++------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index e9a5d0b..2b261ba 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -141,18 +141,18 @@
 			clock-names = "bus", "di0", "di1";
 			resets = <&src 4>;
 
-			ipu2_csi0: port@0 {
+			ipu2_csi0: ipu2_csi@0 {
 				reg = <0>;
 			};
 
-			ipu2_csi1: port@1 {
+			ipu2_csi1: ipu2_csi@1 {
 				reg = <1>;
 			};
 
-			ipu2_di0: port@2 {
+			ipu2_di0: ipu2_di@0 {
 				#address-cells = <1>;
 				#size-cells = <0>;
-				reg = <2>;
+				reg = <0>;
 
 				ipu2_di0_disp0: disp0-endpoint {
 				};
@@ -174,10 +174,10 @@
 				};
 			};
 
-			ipu2_di1: port@3 {
+			ipu2_di1: ipu2_di@1 {
 				#address-cells = <1>;
 				#size-cells = <0>;
-				reg = <3>;
+				reg = <1>;
 
 				ipu2_di1_hdmi: hdmi-endpoint {
 					remote-endpoint = <&hdmi_mux_3>;
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index e01e5d5..2465187 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -1226,18 +1226,18 @@
 			clock-names = "bus", "di0", "di1";
 			resets = <&src 2>;
 
-			ipu1_csi0: port@0 {
+			ipu1_csi0: ipu1_csi@0 {
 				reg = <0>;
 			};
 
-			ipu1_csi1: port@1 {
+			ipu1_csi1: ipu1_csi@1 {
 				reg = <1>;
 			};
 
-			ipu1_di0: port@2 {
+			ipu1_di0: ipu1_di@0 {
 				#address-cells = <1>;
 				#size-cells = <0>;
-				reg = <2>;
+				reg = <0>;
 
 				ipu1_di0_disp0: disp0-endpoint {
 				};
@@ -1259,10 +1259,10 @@
 				};
 			};
 
-			ipu1_di1: port@3 {
+			ipu1_di1: ipu1_di@1 {
 				#address-cells = <1>;
 				#size-cells = <0>;
-				reg = <3>;
+				reg = <1>;
 
 				ipu1_di1_disp1: disp1-endpoint {
 				};
-- 
2.7.4

^ permalink raw reply related

* [PATCH 01/12] ARM: dts: imx6qdl: Add compatible, clocks, irqs to MIPI CSI-2 node
From: Steve Longerbeam @ 2016-12-08  0:57 UTC (permalink / raw)
  To: shawnguo, kernel, fabio.estevam, robh+dt, mark.rutland, linux,
	tomi.valkeinen, p.zabel
  Cc: devicetree, linux-fbdev, Steve Longerbeam, linux-kernel,
	dri-devel, linux-arm-kernel
In-Reply-To: <1481158673-15937-1-git-send-email-steve_longerbeam@mentor.com>

Add to the MIPI CSI2 receiver node: compatible string, interrupt sources,
clocks.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
---
 arch/arm/boot/dts/imx6qdl.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index b13b0b2..e01e5d5 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -1121,7 +1121,14 @@
 			};
 
 			mipi_csi: mipi@021dc000 {
+				compatible = "fsl,imx-mipi-csi2";
 				reg = <0x021dc000 0x4000>;
+				interrupts = <0 100 0x04>, <0 101 0x04>;
+				clocks = <&clks IMX6QDL_CLK_HSI_TX>,
+					 <&clks IMX6QDL_CLK_VIDEO_27M>,
+					 <&clks IMX6QDL_CLK_EIM_SEL>;
+				clock-names = "dphy_clk", "cfg_clk", "pix_clk";
+				status = "disabled";
 			};
 
 			mipi_dsi: mipi@021e0000 {
-- 
2.7.4

^ permalink raw reply related

* [PATCH 00/12] i.MX media devices and connections
From: Steve Longerbeam @ 2016-12-08  0:57 UTC (permalink / raw)
  To: shawnguo, kernel, fabio.estevam, robh+dt, mark.rutland, linux,
	tomi.valkeinen, p.zabel
  Cc: linux-arm-kernel, devicetree, linux-kernel, linux-fbdev,
	dri-devel, Steve Longerbeam

Hi Philipp, Sascha, Shawn, et al,

I've been working for the past few months on a media driver for i.MX.
In addition to the media entities for the IPU-external units involved
with video capture (video mux and MIPI CSI-2 receiver), I've created
media entities for the IPU CSI, SMFC, and IC subunits. The IC entities
carry out scaling, CSC, horizontal/vertical flip, and rotation. In
addition, the IC-PRPVF entity carries out motion compensated
de-interlace.

The following series adds the OF device nodes and graphs that define
all the possible hardware connections supported by the i.MX involved
in video capture and image conversion.

Here are some of the pipelines defined by the OF graphs:

CSI -> IC-PRPENC
CSI -> IC-PRPVF
CSI -> IC-PRPVF -> IC-PP
CSI -> SMFC
CSI -> SMFC -> IC-PRPVF
CSI -> SMFC -> IC-PP
CSI -> SMFC -> IC-PRPVF -> IC-PP

You will notice that three IC-PP nodes are defined (ipu1_ic_pp0,
ipu1_ic_pp1, ipu1_ic_pp2, and same for ipu2). The reason for that
is that the IC-PP media entity uses the new ipu-image-conversion
API, which allows for multiple conversion contexts to be created.
Each IC-PP entity thus creates its own conversion context, and there
can be any number of IC-PP entities instantiated as needed by the OF
graph.

Camera sensor nodes are also added for the SabreAuto, SabreSD, and
SabreLite reference platforms.

The media driver is now in fairly good shape. It parses the OF graphs
to create the media pads and links. All the pipelines defined by the
OF graphs have been tested and are working. My media driver work is
at:

git@github.com:slongerbeam/mediatree.git, branch imx-media-staging-md-v2.

For an overview of the pipelines supported and usage notes for the
reference boards, you can refer to Documentation/media/v4l-drivers/imx.rst.

I realize there is collision here with the recent patch series posted by
Philipp, particularly around the video multiplexer and mipi csi-2 receiver
subdevs and OF graphs, as well as v4l2 capture drivers.



Philipp Zabel (1):
  ARM: dts: imx6qdl: add video capture devices and connections

Steve Longerbeam (11):
  ARM: dts: imx6qdl: Add compatible, clocks, irqs to MIPI CSI-2 node
  ARM: dts: imx6qdl: rename ipu client nodes
  ARM: dts: imx6-sabrelite: add OV5642 and OV5640 camera sensors
  ARM: dts: imx6-sabresd: add OV5642 and OV5640 camera sensors
  ARM: dts: imx6-sabreauto: create i2cmux for i2c3
  ARM: dts: imx6-sabreauto: add reset-gpios property for max7310_b
  ARM: dts: imx6-sabreauto: add pinctrl for gpt input capture
  ARM: dts: imx6-sabreauto: add the ADV7180 video decoder
  gpu: ipu-v3: Add ipu_unit_type enumeration
  gpu: ipu-v3: lookup ipu client nodes by name
  gpu: ipu-v3: Add smfc and ic client devices

 arch/arm/boot/dts/imx6dl-sabrelite.dts   |   5 +
 arch/arm/boot/dts/imx6dl-sabresd.dts     |   5 +
 arch/arm/boot/dts/imx6dl.dtsi            | 190 ++++++++++++
 arch/arm/boot/dts/imx6q-sabrelite.dts    |   6 +
 arch/arm/boot/dts/imx6q-sabresd.dts      |   5 +
 arch/arm/boot/dts/imx6q.dtsi             | 497 ++++++++++++++++++++++++++++++-
 arch/arm/boot/dts/imx6qdl-sabreauto.dtsi | 148 +++++++--
 arch/arm/boot/dts/imx6qdl-sabrelite.dtsi | 122 +++++++-
 arch/arm/boot/dts/imx6qdl-sabresd.dtsi   | 114 ++++++-
 arch/arm/boot/dts/imx6qdl.dtsi           | 385 +++++++++++++++++++++++-
 drivers/gpu/ipu-v3/ipu-common.c          | 142 ++++++++-
 include/video/imx-ipu-v3.h               |  21 ++
 12 files changed, 1593 insertions(+), 47 deletions(-)

-- 
2.7.4

^ permalink raw reply

* Re: [PATCH] ARM: dts: imx7d: fix LCDIF clock assignment
From: Shawn Guo @ 2016-12-08  0:54 UTC (permalink / raw)
  To: Olof Johansson
  Cc: Arnd Bergmann, Sascha Hauer, Stefan Agner, Mark Rutland,
	devicetree, linux-kernel, robh+dt, Peter Chen, Fabio Estevam,
	Liu Ying, linux-arm-kernel, Fabio Estevam
In-Reply-To: <20161207205314.GA20203@localhost>

On Wed, Dec 07, 2016 at 12:53:14PM -0800, Olof Johansson wrote:
> Applied, with the fixes line. In the future, please email arm@kernel.org too,
> it's easier to make sure we don't miss it that way.

Noted.  Thanks, Olof.

Shawn

^ permalink raw reply

* Re: [PATCH 3/3] clk: keystone: Add sci-clk driver support
From: Stephen Boyd @ 2016-12-08  0:13 UTC (permalink / raw)
  To: Tero Kristo
  Cc: linux-clk, mturquette, ssantosh, nm, linux-arm-kernel, devicetree
In-Reply-To: <1477053961-27128-4-git-send-email-t-kristo@ti.com>

On 10/21, Tero Kristo wrote:
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index 6a8ac04..dce08a7 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -169,6 +169,15 @@ config COMMON_CLK_NXP
>  	---help---
>  	  Support for clock providers on NXP platforms.
>  
> +config TI_SCI_CLK
> +	tristate "TI System Control Interface clock drivers"
> +	depends on (TI_SCI_PROTOCOL && COMMON_CLK_KEYSTONE) || COMPILE_TEST

Given that we depend on COMMON_CLK_KEYSTONE (just for the
Makefile dependency?) this should be moved to right below the
COMMON_CLK_KEYSTONE config. And we should consider making a
Kconfig file in drivers/clk/keystone/ to hold both those configs
instead of having them at the toplevel.

> +	default TI_SCI_PROTOCOL
> +	---help---
> +	  This adds the clock driver support over TI System Control Interface.
> +	  If you wish to use clock resources from the PMMC firmware, say Y.
> +	  Otherwise, say N.
> +
>  config COMMON_CLK_PALMAS
>  	tristate "Clock driver for TI Palmas devices"
>  	depends on MFD_PALMAS
> diff --git a/drivers/clk/keystone/Makefile b/drivers/clk/keystone/Makefile
> index 0477cf6..0e7993d 100644
> --- a/drivers/clk/keystone/Makefile
> +++ b/drivers/clk/keystone/Makefile
> @@ -1 +1,2 @@
>  obj-y			+= pll.o gate.o
> +obj-$(CONFIG_TI_SCI_CLK)	+= sci-clk.o
> diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
> new file mode 100644
> index 0000000..f6af5bd
> --- /dev/null
> +++ b/drivers/clk/keystone/sci-clk.c
> @@ -0,0 +1,589 @@
[...]
> +
> +/**
> + * sci_clk_recalc_rate - Get clock rate for a TI SCI clock
> + * @hw: clock to get rate for
> + * @parent_rate: parent rate provided by common clock framework, not used
> + *
> + * Gets the current clock rate of a TI SCI clock. Returns the current
> + * clock rate, or zero in failure.
> + */
> +static unsigned long sci_clk_recalc_rate(struct clk_hw *hw,
> +					 unsigned long parent_rate)
> +{
> +	struct sci_clk *clk = to_sci_clk(hw);
> +	u64 freq;
> +	int ret;
> +
> +	ret = clk->provider->ops->get_freq(clk->provider->sci, clk->dev_id,
> +					   clk->clk_id, &freq);
> +	if (ret) {
> +		dev_err(clk->provider->dev,
> +			"recalc-rate failed for dev=%d, clk=%d, ret=%d\n",
> +			clk->dev_id, clk->clk_id, ret);
> +		return 0;
> +	}
> +
> +	return (u32)freq;

Do we need the cast? sizeof(u32) doesn't always equal
sizeof(unsigned long).

> +
> +/**
> + * _sci_clk_get - Gets a handle for an SCI clock
> + * @provider: Handle to SCI clock provider
> + * @dev_id: device ID for the clock to register
> + * @clk_id: clock ID for the clock to register
> + *
> + * Gets a handle to an existing TI SCI hw clock, or builds a new clock
> + * entry and registers it with the common clock framework. Called from
> + * the common clock framework, when a corresponding of_clk_get call is
> + * executed, or recursively from itself when parsing parent clocks.
> + * Returns a pointer to the hw clock struct, or ERR_PTR value in failure.
> + */
> +static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider,
> +				     u16 dev_id, u8 clk_id)
> +{
> +	struct clk_init_data init = { NULL };
> +	struct sci_clk *sci_clk = NULL;
> +	char *name = NULL;
> +	char **parent_names = NULL;
> +	int i;
> +	int ret;
> +
> +	sci_clk = devm_kzalloc(provider->dev, sizeof(*sci_clk), GFP_KERNEL);
> +	if (!sci_clk)
> +		return ERR_PTR(-ENOMEM);
> +
> +	sci_clk->dev_id = dev_id;
> +	sci_clk->clk_id = clk_id;
> +	sci_clk->provider = provider;
> +
> +	ret = provider->ops->get_num_parents(provider->sci, dev_id,
> +					     clk_id,
> +					     &init.num_parents);
> +	if (ret)
> +		goto err;
> +
> +	name = kasprintf(GFP_KERNEL, "%s:%d:%d", dev_name(provider->dev),
> +			 sci_clk->dev_id, sci_clk->clk_id);
> +
> +	init.name = name;
> +
> +	if (init.num_parents < 2)
> +		init.num_parents = 0;

This deserves a comment. Why is num_parents == 1 the same as
num_parents == 0?

> +
> +	if (init.num_parents) {
> +		parent_names = devm_kcalloc(provider->dev, init.num_parents,
> +					    sizeof(char *), GFP_KERNEL);
> +
> +		if (!parent_names) {
> +			ret = -ENOMEM;
> +			goto err;
> +		}
> +
> +		for (i = 0; i < init.num_parents; i++) {
> +			char *parent_name;
> +
> +			parent_name = kasprintf(GFP_KERNEL, "%s:%d:%d",
> +						dev_name(provider->dev),
> +						sci_clk->dev_id,
> +						sci_clk->clk_id + 1 + i);
> +			if (!parent_name) {
> +				ret = -ENOMEM;
> +				goto err;
> +			}
> +			parent_names[i] = parent_name;
> +		}
> +		init.parent_names = (const char * const *)parent_names;

Does that really need a cast?

> +	}
> +
> +	init.ops = &sci_clk_ops;
> +	sci_clk->hw.init = &init;
> +
> +	ret = devm_clk_hw_register(provider->dev, &sci_clk->hw);
> +	if (ret) {
> +		dev_err(provider->dev, "failed clk register with %d\n", ret);
> +		goto err;
> +	}
> +	kfree(name);
> +
> +	return &sci_clk->hw;
> +
> +err:
> +	if (parent_names) {
> +		for (i = 0; i < init.num_parents; i++)
> +			devm_kfree(provider->dev, parent_names[i]);
> +
> +		devm_kfree(provider->dev, parent_names);

Shouldn't we be freeing the parent names all the time? It should
be deep copied in the framework.

> +	}
> +
> +	devm_kfree(provider->dev, sci_clk);
> +
> +	kfree(name);
> +
> +	return ERR_PTR(ret);
> +}
[..]
> +
> +static int ti_sci_init_clocks(struct sci_clk_provider *p)
> +{
> +	struct sci_clk_data *data = p->clocks;
> +	struct clk_hw *hw;
> +	int i;
> +
> +	while (data->num_clks) {
> +		data->clocks = devm_kcalloc(p->dev, data->num_clks,
> +					    sizeof(struct sci_clk),
> +					    GFP_KERNEL);
> +		if (!data->clocks)
> +			return -ENOMEM;
> +
> +		for (i = 0; i < data->num_clks; i++) {
> +			hw = _sci_clk_build(p, data->dev, i);
> +			if (!IS_ERR(hw)) {
> +				data->clocks[i] = hw;
> +				continue;
> +			}
> +
> +			/* Skip any holes in the clock lists */
> +			if (PTR_ERR(hw) == -ENODEV)

Does this happen? I don't see where _sci_clk_build() returns
-ENODEV.

> +				continue;
> +
> +			return PTR_ERR(hw);
> +		}
> +		data++;
> +	}
> +
> +	return 0;
> +}
> +

> +
> +/**
> + * ti_sci_clk_probe - Probe function for the TI SCI clock driver
> + * @pdev: platform device pointer to be probed
> + *
> + * Probes the TI SCI clock device. Allocates a new clock provider
> + * and registers this to the common clock framework. Also applies
> + * any required flags to the identified clocks via clock lists
> + * supplied from DT. Returns 0 for success, negative error value
> + * for failure.
> + */
> +static int ti_sci_clk_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	struct sci_clk_provider *provider;
> +	const struct ti_sci_handle *handle;
> +	struct sci_clk_data *data;
> +	int ret;
> +
> +	data = (struct sci_clk_data *)
> +		of_match_node(ti_sci_clk_of_match, np)->data;

Just use of_device_get_match_data() instead.

> +
> +	handle = devm_ti_sci_get_handle(dev);
> +	if (IS_ERR(handle))
> +		return PTR_ERR(handle);
> +
> +	provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL);
> +	if (!provider)
> +		return -ENOMEM;
> +
> +	provider->clocks = data;
> +
> +	provider->sci = handle;
> +	provider->ops = &handle->ops.clk_ops;
> +	provider->dev = dev;
> +
> +	ti_sci_init_clocks(provider);

And if this fails?

> +
> +	ret = of_clk_add_hw_provider(np, sci_clk_get, provider);
> +	if (ret)
> +		return ret;
> +
> +	return 0;

Just "return of_clk_add_hw_provider()" please.

> +}

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* Re: [PATCH] PM / Domains: Fix compatible for domain idle state
From: Rafael J. Wysocki @ 2016-12-08  0:13 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Lina Iyer
  Cc: Kevin Hilman, linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	Andy Gross, Stephen Boyd,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Brendan Jackman, Lorenzo Pieralisi, Sudeep Holla, Juri Lelli,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <1616414.c1s7NxTqJS-yvgW3jdyMHm1GS7QM15AGw@public.gmane.org>

On Thursday, December 01, 2016 10:21:59 PM Rafael J. Wysocki wrote:
> On Tuesday, November 29, 2016 09:47:03 AM Ulf Hansson wrote:
> > On 10 November 2016 at 20:58, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> > > On Mon, Nov 07, 2016 at 12:14:28PM +0100, Ulf Hansson wrote:
> > >> On 3 November 2016 at 22:54, Lina Iyer <lina.iyer-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> > >> > Re-using idle state definition provided by arm,idle-state for domain
> > >> > idle states creates a lot of confusion and limits further evolution of
> > >> > the domain idle definition. To keep things clear and simple, define a
> > >> > idle states for domain using a new compatible "domain-idle-state".
> > >> >
> > >> > Fix existing PM domains code to look for the newly defined compatible.
> > >> >
> > >> > Cc: <devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
> > >> > Cc: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > >> > Signed-off-by: Lina Iyer <lina.iyer-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> > >> > ---
> > >> >  .../bindings/power/domain-idle-state.txt           | 33 ++++++++++++++++++++++
> > >> >  .../devicetree/bindings/power/power_domain.txt     |  8 +++---
> > >> >  drivers/base/power/domain.c                        |  2 +-
> > >> >  3 files changed, 38 insertions(+), 5 deletions(-)
> > >> >  create mode 100644 Documentation/devicetree/bindings/power/domain-idle-state.txt
> > >> >
> > >> > diff --git a/Documentation/devicetree/bindings/power/domain-idle-state.txt b/Documentation/devicetree/bindings/power/domain-idle-state.txt
> > >> > new file mode 100644
> > >> > index 0000000..eefc7ed
> > >> > --- /dev/null
> > >> > +++ b/Documentation/devicetree/bindings/power/domain-idle-state.txt
> > >> > @@ -0,0 +1,33 @@
> > >> > +PM Domain Idle State Node:
> > >> > +
> > >> > +A domain idle state node represents the state parameters that will be used to
> > >> > +select the state when there are no active components in the domain.
> > >> > +
> > >> > +The state node has the following parameters -
> > >> > +
> > >> > +- compatible:
> > >> > +       Usage: Required
> > >> > +       Value type: <string>
> > >> > +       Definition: Must be "domain-idle-state".
> > >> > +
> > >> > +- entry-latency-us
> > >> > +       Usage: Required
> > >> > +       Value type: <prop-encoded-array>
> > >> > +       Definition: u32 value representing worst case latency in
> > >> > +                   microseconds required to enter the idle state.
> > >> > +                   The exit-latency-us duration may be guaranteed
> > >> > +                   only after entry-latency-us has passed.
> > >>
> > >> As we anyway are going to change this, why not use an u64 and have the
> > >> value in ns instead of us?
> > >
> > > I can't imagine that you would need more resolution or range. For times
> > > less than 1us, s/w and register access times are going to dominate the
> > > time.
> > >
> > > Unless there is a real need, I'd keep alignment with the existing
> > > binding.
> > 
> > Rob, are you fine with this? I thought it would be great to get this
> > in for 4.10 rc1.
> 
> Rob, any objections here?

Well, no objections, so applied.

Thanks,
Rafael

--
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 08/16] drivers/fsi: Add crc4 helpers
From: Jeremy Kerr @ 2016-12-07 23:33 UTC (permalink / raw)
  To: Greg KH, Chris Bostic
  Cc: robh+dt, mark.rutland, linux, sre, mturquette, geert+renesas,
	devicetree, linux-arm-kernel, joel, linux-kernel, andrew,
	alistair, benh, Chris Bostic
In-Reply-To: <20161207090219.GA14742@kroah.com>

Hi Greg,

> Why not just create lib/crc4.c with these functions, like the other crc
> functions in the kernel?

Two (bad) reasons:

 - The crc4 implementation here is pretty specific to the FSI
   usage (only supporting 4-bit-sized chunks), to keep the math & lookup
   table simple

 - I'm lazy

So yes, we should spend the effort now to make this generic enough for
a lib/crc4.c. Would we want to support different values for the
polynomial?

Chris: do you want me to to that, or will you?

Cheers,


Jeremy

^ permalink raw reply

* Re: [PATCH 05/16] drivers/fsi: Add fake master driver
From: Jeremy Kerr @ 2016-12-07 23:27 UTC (permalink / raw)
  To: Mark Rutland, Chris Bostic
  Cc: devicetree, linux-kernel, geert+renesas, andrew, gregkh,
	mturquette, linux, Chris Bostic, sre, robh+dt, benh, joel,
	alistair, linux-arm-kernel
In-Reply-To: <20161207120905.GD7054@leverpostej>

Hi Mark & Chris,

> On Tue, Dec 06, 2016 at 06:14:26PM -0600, Chris Bostic wrote:
>> From: Jeremy Kerr <jk@ozlabs.org>
>>
>> For debugging, add a fake master driver, that only supports reads,
>> returning a fixed set of data.
> 
>> +config FSI_MASTER_FAKE
>> +	tristate "Fake FSI master"
>> +	depends on FSI
>> +	---help---
>> +	This option enables a fake FSI master driver for debugging.
>> +endif
> 
>> +static const struct of_device_id fsi_master_fake_match[] = {
>> +	{ .compatible = "ibm,fsi-master-fake" },
>> +	{ },
>> +};
> 
> NAK.
> 
> DT should be treated as an ABI, and should describe the HW explicitly.
> This makes no sense. This is also missing a binding document.
> 
> Have your module take a module parameter allowing you to bind it to
> arbitrary devices, or do something like what PCI does where you can
> bind/unbind arbitrary drivers to devices using sysfs.

This driver is purely for testing the FSI engine scan code; we could
probably just drop this patch since I suspect that it's no longer useful
(now that we have an actual master driver).

If we do want to keep it though, I'd say we remove the device tree
dependency; all this is doing at the moment is triggering the ->probe,
and there are better ways to do that.

Cheers,


Jeremy

^ permalink raw reply

* Re: [PATCH v5 2/2] Add support for OV5647 sensor
From: Sakari Ailus @ 2016-12-07 23:01 UTC (permalink / raw)
  To: Ramiro Oliveira
  Cc: mchehab, linux-kernel, linux-media, robh+dt, devicetree, davem,
	gregkh, geert+renesas, akpm, linux, hverkuil, dheitmueller,
	slongerbeam, lars, robert.jarzmik, pavel, pali.rohar,
	sakari.ailus, mark.rutland, CARLOS.PALMINHA
In-Reply-To: <3e6262362f9961d2cf861353f32dbcd5bcc5a879.1480958609.git.roliveir@synopsys.com>

Hi Ramiro,

On Mon, Dec 05, 2016 at 05:36:34PM +0000, Ramiro Oliveira wrote:
> Add support for OV5647 sensor.
> 
> Modes supported:
>  - 640x480 RAW 8
> 
> Signed-off-by: Ramiro Oliveira <roliveir@synopsys.com>
> ---
>  MAINTAINERS                |   7 +
>  drivers/media/i2c/Kconfig  |  12 +
>  drivers/media/i2c/Makefile |   1 +
>  drivers/media/i2c/ov5647.c | 866 +++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 886 insertions(+)
>  create mode 100644 drivers/media/i2c/ov5647.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 52cc077..72e828a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -8923,6 +8923,13 @@ M:	Harald Welte <laforge@gnumonks.org>
>  S:	Maintained
>  F:	drivers/char/pcmcia/cm4040_cs.*
>  
> +OMNIVISION OV5647 SENSOR DRIVER
> +M:	Ramiro Oliveira <roliveir@synopsys.com>
> +L:	linux-media@vger.kernel.org
> +T:	git git://linuxtv.org/media_tree.git
> +S:	Maintained
> +F:	drivers/media/i2c/ov5647.c
> +
>  OMNIVISION OV7670 SENSOR DRIVER
>  M:	Jonathan Corbet <corbet@lwn.net>
>  L:	linux-media@vger.kernel.org
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index b31fa6f..c1b78e5 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -531,6 +531,18 @@ config VIDEO_OV2659
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called ov2659.
>  
> +config VIDEO_OV5647
> +	tristate "OmniVision OV5647 sensor support"
> +	depends on OF

How does this driver depend on OF, other than matching the compatible
string?

> +	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
> +	depends on MEDIA_CAMERA_SUPPORT
> +	---help---
> +	  This is a Video4Linux2 sensor-level driver for the OmniVision
> +	  OV5647 camera.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called ov5647.
> +
>  config VIDEO_OV7640
>  	tristate "OmniVision OV7640 sensor support"
>  	depends on I2C && VIDEO_V4L2
> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> index 92773b2..0d9014c 100644
> --- a/drivers/media/i2c/Makefile
> +++ b/drivers/media/i2c/Makefile
> @@ -82,3 +82,4 @@ obj-$(CONFIG_VIDEO_IR_I2C)  += ir-kbd-i2c.o
>  obj-$(CONFIG_VIDEO_ML86V7667)	+= ml86v7667.o
>  obj-$(CONFIG_VIDEO_OV2659)	+= ov2659.o
>  obj-$(CONFIG_VIDEO_TC358743)	+= tc358743.o
> +obj-$(CONFIG_VIDEO_OV5647)	+= ov5647.o
> diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
> new file mode 100644
> index 0000000..2aae806
> --- /dev/null
> +++ b/drivers/media/i2c/ov5647.c
> @@ -0,0 +1,866 @@
> +/*
> + * A V4L2 driver for OmniVision OV5647 cameras.
> + *
> + * Based on Samsung S5K6AAFX SXGA 1/6" 1.3M CMOS Image Sensor driver
> + * Copyright (C) 2011 Sylwester Nawrocki <s.nawrocki@samsung.com>
> + *
> + * Based on Omnivision OV7670 Camera Driver
> + * Copyright (C) 2006-7 Jonathan Corbet <corbet@lwn.net>
> + *
> + * Copyright (C) 2016, Synopsys, Inc.
> + *
> + * 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 version 2.
> + *
> + * 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/init.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/i2c.h>
> +#include <linux/delay.h>
> +#include <linux/videodev2.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-mediabus.h>
> +#include <media/v4l2-image-sizes.h>
> +#include <media/v4l2-of.h>
> +#include <linux/io.h>

Alphabetical order, please.

> +
> +#define SENSOR_NAME "ov5647"
> +
> +#define OV5647_SW_RESET		0x1003
> +#define OV5647_REG_CHIPID_H	0x300A
> +#define OV5647_REG_CHIPID_L	0x300B
> +
> +#define REG_TERM 0xfffe
> +#define VAL_TERM 0xfe
> +#define REG_DLY  0xffff
> +
> +#define OV5647_ROW_START		0x01
> +#define OV5647_ROW_START_MIN		0
> +#define OV5647_ROW_START_MAX		2004
> +#define OV5647_ROW_START_DEF		54
> +
> +#define OV5647_COLUMN_START		0x02
> +#define OV5647_COLUMN_START_MIN		0
> +#define OV5647_COLUMN_START_MAX		2750
> +#define OV5647_COLUMN_START_DEF		16
> +
> +#define OV5647_WINDOW_HEIGHT		0x03
> +#define OV5647_WINDOW_HEIGHT_MIN	2
> +#define OV5647_WINDOW_HEIGHT_MAX	2006
> +#define OV5647_WINDOW_HEIGHT_DEF	1944
> +
> +#define OV5647_WINDOW_WIDTH		0x04
> +#define OV5647_WINDOW_WIDTH_MIN		2
> +#define OV5647_WINDOW_WIDTH_MAX		2752
> +#define OV5647_WINDOW_WIDTH_DEF		2592
> +
> +struct regval_list {
> +	u16 addr;
> +	u8 data;
> +};
> +
> +struct cfg_array {
> +	struct regval_list *regs;
> +	int size;
> +};
> +
> +struct sensor_win_size {
> +	int width;
> +	int height;
> +	unsigned int hoffset;
> +	unsigned int voffset;
> +	unsigned int hts;
> +	unsigned int vts;
> +	unsigned int pclk;
> +	unsigned int mipi_bps;
> +	unsigned int fps_fixed;
> +	unsigned int bin_factor;
> +	unsigned int intg_min;
> +	unsigned int intg_max;
> +	void *regs;
> +	int regs_size;
> +	int (*set_size)(struct v4l2_subdev *sd);
> +};
> +
> +
> +struct ov5647 {
> +	struct device			*dev;
> +	struct v4l2_subdev		sd;
> +	struct media_pad		pad;
> +	struct mutex			lock;
> +	struct v4l2_mbus_framefmt	format;
> +	struct sensor_format_struct	*fmt;
> +	unsigned int			width;
> +	unsigned int			height;
> +	unsigned int			capture_mode;
> +	int				hue;

At least capture_mode and hue are unused. Please remove unused fields.

> +	struct v4l2_fract		tpf;
> +	struct sensor_win_size		*current_wins;
> +};
> +
> +static inline struct ov5647 *to_state(struct v4l2_subdev *sd)
> +{
> +	return container_of(sd, struct ov5647, sd);
> +}
> +
> +static struct regval_list sensor_oe_disable_regs[] = {
> +	{0x3000, 0x00},
> +	{0x3001, 0x00},
> +	{0x3002, 0x00},
> +};
> +
> +static struct regval_list sensor_oe_enable_regs[] = {
> +	{0x3000, 0x0f},
> +	{0x3001, 0xff},
> +	{0x3002, 0xe4},
> +};
> +
> +static struct regval_list ov5647_640x480[] = {

Does this list expect a certain external clock frequency? If it does, should
you check that the actual frequency matches with the expectation?

> +	{0x0100, 0x00},
> +	{0x0103, 0x01},
> +	{0x3034, 0x08},
> +	{0x3035, 0x21},
> +	{0x3036, 0x46},
> +	{0x303c, 0x11},
> +	{0x3106, 0xf5},
> +	{0x3821, 0x07},
> +	{0x3820, 0x41},
> +	{0x3827, 0xec},
> +	{0x370c, 0x0f},
> +	{0x3612, 0x59},
> +	{0x3618, 0x00},
> +	{0x5000, 0x06},
> +	{0x5001, 0x01},
> +	{0x5002, 0x41},
> +	{0x5003, 0x08},
> +	{0x5a00, 0x08},
> +	{0x3000, 0x00},
> +	{0x3001, 0x00},
> +	{0x3002, 0x00},
> +	{0x3016, 0x08},
> +	{0x3017, 0xe0},
> +	{0x3018, 0x44},
> +	{0x301c, 0xf8},
> +	{0x301d, 0xf0},
> +	{0x3a18, 0x00},
> +	{0x3a19, 0xf8},
> +	{0x3c01, 0x80},
> +	{0x3b07, 0x0c},
> +	{0x380c, 0x07},
> +	{0x380d, 0x68},
> +	{0x380e, 0x03},
> +	{0x380f, 0xd8},
> +	{0x3814, 0x31},
> +	{0x3815, 0x31},
> +	{0x3708, 0x64},
> +	{0x3709, 0x52},
> +	{0x3808, 0x02},
> +	{0x3809, 0x80},
> +	{0x380a, 0x01},
> +	{0x380b, 0xE0},
> +	{0x3801, 0x00},
> +	{0x3802, 0x00},
> +	{0x3803, 0x00},
> +	{0x3804, 0x0a},
> +	{0x3805, 0x3f},
> +	{0x3806, 0x07},
> +	{0x3807, 0xa1},
> +	{0x3811, 0x08},
> +	{0x3813, 0x02},
> +	{0x3630, 0x2e},
> +	{0x3632, 0xe2},
> +	{0x3633, 0x23},
> +	{0x3634, 0x44},
> +	{0x3636, 0x06},
> +	{0x3620, 0x64},
> +	{0x3621, 0xe0},
> +	{0x3600, 0x37},
> +	{0x3704, 0xa0},
> +	{0x3703, 0x5a},
> +	{0x3715, 0x78},
> +	{0x3717, 0x01},
> +	{0x3731, 0x02},
> +	{0x370b, 0x60},
> +	{0x3705, 0x1a},
> +	{0x3f05, 0x02},
> +	{0x3f06, 0x10},
> +	{0x3f01, 0x0a},
> +	{0x3a08, 0x01},
> +	{0x3a09, 0x27},
> +	{0x3a0a, 0x00},
> +	{0x3a0b, 0xf6},
> +	{0x3a0d, 0x04},
> +	{0x3a0e, 0x03},
> +	{0x3a0f, 0x58},
> +	{0x3a10, 0x50},
> +	{0x3a1b, 0x58},
> +	{0x3a1e, 0x50},
> +	{0x3a11, 0x60},
> +	{0x3a1f, 0x28},
> +	{0x4001, 0x02},
> +	{0x4004, 0x02},
> +	{0x4000, 0x09},
> +	{0x4837, 0x24},
> +	{0x4050, 0x6e},
> +	{0x4051, 0x8f},
> +	{0x0100, 0x01},
> +};
> +
> +struct sensor_format_struct;
> +
> +/**
> + * @short I2C Write operation
> + * @param[in] i2c_client I2C client
> + * @param[in] reg register address
> + * @param[in] val value to write
> + * @return Error code
> + */
> +static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val)
> +{
> +	int ret;
> +	unsigned char data[3] = { reg >> 8, reg & 0xff, val};
> +	struct i2c_client *client = v4l2_get_subdevdata(sd);
> +
> +	ret = i2c_master_send(client, data, 3);
> +	if (ret != 3) {
> +		dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n",
> +				__func__, reg);
> +		return ret < 0 ? ret : -EIO;
> +	}
> +	return 0;
> +}
> +
> +/**
> + * @short I2C Read operation
> + * @param[in] i2c_client I2C client
> + * @param[in] reg register address
> + * @param[out] val value read
> + * @return Error code
> + */
> +static int ov5647_read(struct v4l2_subdev *sd, u16 reg, u8 *val)
> +{
> +	int ret;
> +	unsigned char data_w[2] = { reg >> 8, reg & 0xff };
> +	struct i2c_client *client = v4l2_get_subdevdata(sd);
> +
> +
> +	ret = i2c_master_send(client, data_w, 2);
> +
> +	if (ret < 2) {
> +		dev_dbg(&client->dev, "%s: i2c read error, reg: %x\n",
> +			__func__, reg);
> +		return ret < 0 ? ret : -EIO;
> +	}
> +
> +
> +	ret = i2c_master_recv(client, val, 1);
> +
> +	if (ret < 1) {
> +		dev_dbg(&client->dev, "%s: i2c read error, reg: %x\n",
> +				__func__, reg);
> +		return ret < 0 ? ret : -EIO;
> +	}
> +	return 0;
> +}
> +
> +static int ov5647_write_array(struct v4l2_subdev *sd,
> +				struct regval_list *regs, int array_size)
> +{
> +	int i = 0;
> +	int ret = 0;
> +
> +	if (!regs)
> +		return -EINVAL;
> +
> +	while (i < array_size) {
> +		ret = ov5647_write(sd, regs->addr, regs->data);
> +		if (ret < 0)
> +			return ret;
> +		i++;
> +		regs++;
> +	}
> +	return 0;
> +}
> +
> +static void ov5647_set_virtual_channel(struct v4l2_subdev *sd, int channel)
> +{
> +	u8 channel_id;
> +
> +	ov5647_read(sd, 0x4814, &channel_id);
> +	channel_id &= ~(3 << 6);
> +	ov5647_write(sd, 0x4814, channel_id | (channel << 6));
> +}
> +
> +void ov5647_stream_on(struct v4l2_subdev *sd)
> +{
> +	struct i2c_client *client = v4l2_get_subdevdata(sd);
> +
> +	ov5647_write(sd, 0x4202, 0x00);
> +	dev_dbg(&client->dev, "Stream on");
> +	ov5647_write(sd, 0x300D, 0x00);
> +}
> +
> +void ov5647_stream_off(struct v4l2_subdev *sd)
> +{
> +	struct i2c_client *client = v4l2_get_subdevdata(sd);
> +
> +	ov5647_write(sd, 0x4202, 0x0f);
> +	dev_dbg(&client->dev, "Stream off");
> +	ov5647_write(sd, 0x300D, 0x01);
> +}
> +
> +/****************************************************************************/
> +
> +/**
> + * @short Set SW standby
> + * @param[in] sd v4l2 sd
> + * @param[in] stanby standby mode status (on or off)
> + * @return Error code
> + */
> +static int set_sw_standby(struct v4l2_subdev *sd, bool standby)
> +{
> +	int ret;
> +	unsigned char rdval;
> +
> +	ret = ov5647_read(sd, 0x0100, &rdval);
> +	if (ret != 0)
> +		return ret;
> +
> +	if (standby)
> +		rdval &= 0xfe;
> +	else
> +		rdval |= 0x01;
> +
> +	ret = ov5647_write(sd, 0x0100, rdval);
> +
> +	return ret;
> +}
> +
> +/**
> + * @short Store information about the video data format.
> + */
> +static struct sensor_format_struct {
> +	u8 *desc;
> +	u32 mbus_code;
> +	struct regval_list *regs;
> +	int regs_size;
> +	int bpp;

At least desc and bpp are unused.

> +} sensor_formats[] = {
> +	{
> +		.desc		= "Raw RGB Bayer",
> +		.mbus_code	= MEDIA_BUS_FMT_SBGGR8_1X8,
> +		.regs		= ov5647_640x480,
> +		.regs_size	= ARRAY_SIZE(ov5647_640x480),
> +		.bpp		= 1
> +	},
> +};
> +#define N_FMTS ARRAY_SIZE(sensor_formats)
> +
> +/* ----------------------------------------------------------------------- */
> +
> +/**
> + * @short Initialize sensor
> + * @param[in] sd v4l2 subdev
> + * @param[in] val not used
> + * @return Error code
> + */
> +static int __sensor_init(struct v4l2_subdev *sd)
> +{
> +	int ret;
> +	u8 resetval;
> +	u8 rdval;
> +	struct i2c_client *client = v4l2_get_subdevdata(sd);
> +
> +	dev_dbg(&client->dev, "sensor init\n");
> +
> +	ret = ov5647_read(sd, 0x0100, &rdval);
> +	if (ret != 0)
> +		return ret;
> +
> +	ov5647_write(sd, 0x4800, 0x25);
> +	ov5647_stream_off(sd);
> +
> +	ret = ov5647_write_array(sd, ov5647_640x480,
> +					ARRAY_SIZE(ov5647_640x480));
> +	if (ret < 0) {
> +		dev_err(&client->dev, "write sensor_default_regs error\n");
> +		return ret;
> +	}
> +
> +	ov5647_set_virtual_channel(sd, 0);
> +
> +	ov5647_read(sd, 0x0100, &resetval);
> +	if (!(resetval & 0x01)) {
> +		dev_err(&client->dev, "Device was in SW standby");
> +		ov5647_write(sd, 0x0100, 0x01);
> +	}
> +
> +	ov5647_write(sd, 0x4800, 0x04);
> +	ov5647_stream_on(sd);
> +
> +	return 0;
> +}
> +
> +/**
> + * @short Control sensor power state
> + * @param[in] sd v4l2 subdev
> + * @param[in] on Sensor power
> + * @return Error code
> + */
> +static int sensor_power(struct v4l2_subdev *sd, int on)
> +{
> +	int ret;
> +	struct ov5647 *ov5647 = to_state(sd);
> +	struct i2c_client *client = v4l2_get_subdevdata(sd);
> +
> +	ret = 0;
> +	mutex_lock(&ov5647->lock);
> +
> +	if (on)	{
> +		dev_dbg(&client->dev, "OV5647 power on\n");
> +
> +		ret = ov5647_write_array(sd, sensor_oe_enable_regs,
> +				ARRAY_SIZE(sensor_oe_enable_regs));
> +
> +		ret = __sensor_init(sd);
> +
> +		if (ret < 0)
> +			dev_err(&client->dev,
> +				"Camera not available, check Power\n");
> +	} else {
> +		dev_dbg(&client->dev, "OV5647 power off\n");
> +
> +		dev_dbg(&client->dev, "disable oe\n");
> +		ret = ov5647_write_array(sd, sensor_oe_disable_regs,
> +				ARRAY_SIZE(sensor_oe_disable_regs));
> +
> +		if (ret < 0)
> +			dev_dbg(&client->dev, "disable oe failed\n");
> +
> +		ret = set_sw_standby(sd, true);
> +
> +		if (ret < 0)
> +			dev_dbg(&client->dev, "soft stby failed\n");
> +
> +	}
> +
> +	mutex_unlock(&ov5647->lock);
> +
> +	return ret;
> +}
> +
> +#ifdef CONFIG_VIDEO_ADV_DEBUG
> +/**
> + * @short Get register value
> + * @param[in] sd v4l2 subdev
> + * @param[in] reg register struct
> + * @return Error code
> + */
> +static int sensor_get_register(struct v4l2_subdev *sd,
> +				struct v4l2_dbg_register *reg)
> +{
> +	unsigned char val = 0;
> +	int ret;
> +
> +	ret = ov5647_read(sd, reg->reg & 0xff, &val);
> +	if (ret != 0)
> +		return ret;
> +
> +	reg->val = val;
> +	reg->size = 1;
> +
> +	return ret;
> +}
> +
> +/**
> + * @short Set register value
> + * @param[in] sd v4l2 subdev
> + * @param[in] reg register struct
> + * @return Error code
> + */
> +static int sensor_set_register(struct v4l2_subdev *sd,
> +				const struct v4l2_dbg_register *reg)
> +{
> +	return ov5647_write(sd, reg->reg & 0xff, reg->val & 0xff);
> +}
> +#endif
> +
> +/* ----------------------------------------------------------------------- */
> +
> +/**
> + * @short Subdev core operations registration
> + */
> +static const struct v4l2_subdev_core_ops sensor_core_ops = {
> +	.s_power		= sensor_power,

The s_power() op will be called by the bridge (ISP) driver as well. You
should expect that it may be enabled more than once before being disabled
equal number of times.

> +#ifdef CONFIG_VIDEO_ADV_DEBUG
> +	.g_register		= sensor_get_register,
> +	.s_register		= sensor_set_register,
> +#endif
> +};
> +
> +/* ----------------------------------------------------------------------- */
> +
> +
> +
> +/**
> + * @short Enumerate available image formats
> + * @param[in] sd v4l2 subdev
> + * @param[in] index index
> + * @param[in] code MBUS Pixel code
> + * @return Error code
> + */
> +static int sensor_enum_fmt(struct v4l2_subdev *sd,
> +		struct v4l2_subdev_pad_config *cfg,
> +		struct v4l2_subdev_mbus_code_enum *code)
> +{
> +	if (code->pad || code->index >= N_FMTS)
> +		return -EINVAL;
> +
> +	code->code = sensor_formats[code->index].mbus_code;
> +	return 0;
> +}
> +
> +/**
> + * @short Try frame format internal function
> + * @param[in] sd v4l2 subdev
> + * @param[in] fmt frame format
> + * @return Error code
> + */
> +static int sensor_try_fmt_internal(struct v4l2_subdev *sd,
> +	struct v4l2_mbus_framefmt *fmt, struct sensor_format_struct **ret_fmt,
> +	struct sensor_win_size **ret_wsize)
> +{
> +	int index;
> +
> +	for (index = 0; index < N_FMTS; index++)
> +		if (sensor_formats[index].mbus_code == fmt->code)
> +			break;
> +
> +	if (index >= N_FMTS)
> +		return -EINVAL;
> +
> +	if (ret_fmt != NULL)
> +		*ret_fmt = sensor_formats + index;
> +
> +	fmt->field = V4L2_FIELD_NONE;
> +
> +	return 0;
> +}
> +
> +/**
> + * @short Set frame format
> + * @param[in] sd v4l2 subdev
> + * @param[in] fmt frame format
> + * @return Error code
> + */
> +static int sensor_s_fmt(struct v4l2_subdev *sd,
> +		struct v4l2_subdev_pad_config *cfg,
> +		struct v4l2_subdev_format *fmt)
> +{
> +	int ret;
> +	struct sensor_format_struct *sensor_fmt;
> +	struct sensor_win_size *wsize;
> +	struct ov5647 *info = to_state(sd);
> +
> +	ov5647_write_array(sd, sensor_oe_disable_regs,
> +					ARRAY_SIZE(sensor_oe_disable_regs));

Should you check the error code here?

> +
> +	ret = sensor_try_fmt_internal(sd, &fmt->format,
> +					&sensor_fmt, &wsize);

Do you set wsize somewhere?

> +	if (ret)
> +		return ret;
> +
> +	ov5647_write_array(sd, sensor_fmt->regs, sensor_fmt->regs_size);

And here.

> +
> +	ret = 0;

ret was already zero.

> +
> +	if (wsize->regs)
> +		ov5647_write_array(sd, wsize->regs, wsize->regs_size);
> +
> +	if (wsize->set_size)
> +		wsize->set_size(sd);
> +
> +	info->fmt = sensor_fmt;
> +	info->width = wsize->width;
> +	info->height = wsize->height;
> +
> +	ov5647_write_array(sd, sensor_oe_enable_regs,
> +				ARRAY_SIZE(sensor_oe_enable_regs));
> +
> +	return 0;
> +}
> +
> +/**
> + * @short Set stream parameters
> + * @param[in] sd v4l2 subdev
> + * @param[in] parms stream parameters
> + * @return Error code
> + */
> +static int sensor_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
> +{
> +	struct v4l2_captureparm *cp = &parms->parm.capture;
> +	struct ov5647 *info = to_state(sd);
> +
> +	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
> +		return -EINVAL;
> +
> +	if (info->tpf.numerator == 0)
> +		return -EINVAL;
> +
> +	info->capture_mode = cp->capturemode;
> +
> +	return 0;
> +}
> +
> +/**
> + * @short Get stream parameters
> + * @param[in] sd v4l2 subdev
> + * @param[in] parms stream parameters
> + * @return Error code
> + */
> +static int sensor_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
> +{
> +	struct v4l2_captureparm *cp = &parms->parm.capture;
> +	struct ov5647 *info = to_state(sd);
> +
> +	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
> +		return -EINVAL;
> +
> +	memset(cp, 0, sizeof(struct v4l2_captureparm));
> +	cp->capability = V4L2_CAP_TIMEPERFRAME;
> +	cp->capturemode = info->capture_mode;
> +
> +	return 0;
> +}
> +
> +/**
> + * @short Subdev video operations registration
> + *
> + */
> +static const struct v4l2_subdev_video_ops sensor_video_ops = {
> +	.s_parm		= sensor_s_parm,
> +	.g_parm		= sensor_g_parm,

Please use the g/s_frame_interval() instead. That's what sub-device drivers
generally use for the purpose.

> +};
> +
> +/* ----------------------------------------------------------------------- */
> +
> +/**
> + * @short Subdev operations registration
> + *
> + */
> +static const struct v4l2_subdev_ops subdev_ops = {
> +	.core			= &sensor_core_ops,
> +	.video			= &sensor_video_ops,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * V4L2 subdev internal operations
> + */
> +
> +/**
> + * @short Detect camera version and model
> + * @param[in] sd v4l2 subdev
> + * @return Error code
> + */
> +int ov5647_detect(struct v4l2_subdev *sd)
> +{
> +	unsigned char v;
> +	int ret;
> +	struct i2c_client *client = v4l2_get_subdevdata(sd);
> +
> +	ret = ov5647_write(sd, OV5647_SW_RESET, 0x01);
> +	if (ret < 0)
> +		return ret;
> +	ret = ov5647_read(sd, OV5647_REG_CHIPID_H, &v);
> +	if (ret < 0)
> +		return ret;
> +	if (v != 0x56) {
> +		dev_err(&client->dev, "Wrong model version detected");
> +		return -ENODEV;
> +	}
> +	ret = ov5647_read(sd, OV5647_REG_CHIPID_L, &v);
> +	if (ret < 0)
> +		return ret;
> +	if (v != 0x47) {
> +		dev_err(&client->dev, "Wrong model version detected");
> +		return -ENODEV;
> +	}
> +
> +	ret = ov5647_write(sd, OV5647_SW_RESET, 0x00);
> +	if (ret < 0)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +/**
> + * @short Detect if camera is registered
> + * @param[in] sd v4l2 subdev
> + * @return Error code
> + */
> +static int ov5647_registered(struct v4l2_subdev *sd)
> +{
> +	struct i2c_client *client = v4l2_get_subdevdata(sd);
> +
> +	dev_info(&client->dev, "OV5647 detected at address 0x%02x\n",
> +				client->addr);

I might omit this. If there's a need to debug this then the information
should be printed by the framework instead using debug level messages.

> +
> +	return 0;
> +}
> +
> +/**
> + * @short Open device
> + * @param[in] sd v4l2 subdev
> + * @param[in] fh v4l2 file handler
> + * @return Error code
> + */
> +static int ov5647_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
> +{
> +	struct v4l2_mbus_framefmt *format =
> +				v4l2_subdev_get_try_format(sd, fh->pad, 0);
> +	struct v4l2_rect *crop =
> +				v4l2_subdev_get_try_crop(sd, fh->pad, 0);
> +
> +	crop->left = OV5647_COLUMN_START_DEF;
> +	crop->top = OV5647_ROW_START_DEF;
> +	crop->width = OV5647_WINDOW_WIDTH_DEF;
> +	crop->height = OV5647_WINDOW_HEIGHT_DEF;
> +
> +	format->code = MEDIA_BUS_FMT_SBGGR8_1X8;
> +
> +	format->width = OV5647_WINDOW_WIDTH_DEF;
> +	format->height = OV5647_WINDOW_HEIGHT_DEF;
> +	format->field = V4L2_FIELD_NONE;
> +	format->colorspace = V4L2_COLORSPACE_SRGB;
> +
> +	return sensor_power(sd, true);
> +}
> +
> +/**
> + * @short Open device
> + * @param[in] sd v4l2 subdev
> + * @param[in] fh v4l2 file handler
> + * @return Error code
> + */
> +static int ov5647_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
> +{
> +	return sensor_power(sd, false);
> +}
> +
> +/**
> + * @short Subdev internal operations registration
> + *
> + */
> +static const struct v4l2_subdev_internal_ops ov5647_subdev_internal_ops = {
> +	.registered = ov5647_registered,
> +	.open = ov5647_open,
> +	.close = ov5647_close,
> +};
> +
> +/**
> + * @short Initialization routine - Entry point of the driver
> + * @param[in] client pointer to the i2c client structure
> + * @param[in] id pointer to the i2c device id structure
> + * @return 0 on success and a negative number on failure
> + */
> +static int ov5647_probe(struct i2c_client *client,
> +			const struct i2c_device_id *id)
> +{
> +	struct device *dev = &client->dev;
> +	struct ov5647 *sensor;
> +	int ret = 0;

No need to initialise ret here.

> +	struct v4l2_subdev *sd;
> +
> +	dev_info(&client->dev, "Installing OmniVision OV5647 camera driver\n");
> +
> +	sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
> +	if (sensor == NULL)
> +		return -ENOMEM;
> +
> +	mutex_init(&sensor->lock);
> +	sensor->dev = dev;
> +
> +	sd = &sensor->sd;
> +	v4l2_i2c_subdev_init(sd, client, &subdev_ops);
> +	sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> +
> +	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
> +	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
> +	ret = media_entity_pads_init(&sd->entity, 1, &sensor->pad);
> +	if (ret < 0)
> +		goto mutex_remove;
> +
> +	ret = ov5647_detect(sd);
> +	if (ret < 0)
> +		goto error;
> +
> +	ret = v4l2_async_register_subdev(sd);
> +	if (ret < 0)
> +		goto error;
> +
> +	return 0;
> +error:
> +	media_entity_cleanup(&sd->entity);
> +mutex_remove:
> +	mutex_destroy(&sensor->lock);
> +	return ret;
> +}
> +
> +/**
> + * @short Exit routine - Exit point of the driver
> + * @param[in] client pointer to the i2c client structure
> + * @return 0 on success and a negative number on failure
> + */
> +static int ov5647_remove(struct i2c_client *client)
> +{
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> +	struct ov5647 *ov5647 = to_state(sd);
> +
> +	v4l2_async_unregister_subdev(&ov5647->sd);
> +	media_entity_cleanup(&ov5647->sd.entity);
> +	v4l2_device_unregister_subdev(sd);
> +	mutex_destroy(&ov5647->lock);
> +
> +	return 0;
> +}
> +
> +static const struct i2c_device_id ov5647_id[] = {
> +	{ "ov5647", 0 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(i2c, ov5647_id);
> +
> +#if IS_ENABLED(CONFIG_OF)
> +static const struct of_device_id ov5647_of_match[] = {
> +	{ .compatible = "ovti,ov5647" },
> +	{ /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, ov5647_of_match);
> +#endif
> +
> +/**
> + * @short i2c driver structure
> + */
> +static struct i2c_driver ov5647_driver = {
> +	.driver = {
> +		.of_match_table = of_match_ptr(ov5647_of_match),
> +		.owner	= THIS_MODULE,
> +		.name	= "ov5647",
> +	},
> +	.probe		= ov5647_probe,
> +	.remove		= ov5647_remove,
> +	.id_table	= ov5647_id,
> +};
> +
> +module_i2c_driver(ov5647_driver);
> +
> +MODULE_AUTHOR("Ramiro Oliveira <roliveir@synopsys.com>");
> +MODULE_DESCRIPTION("A low-level driver for OmniVision ov5647 sensors");
> +MODULE_LICENSE("GPL v2");

-- 
Kind regards,

Sakari Ailus
e-mail: sakari.ailus@iki.fi	XMPP: sailus@retiisi.org.uk

^ permalink raw reply

* Re: [PATCH pci/next v3 0/3] PCI: rcar, rcar-gen2: Bindings cleanups
From: Bjorn Helgaas @ 2016-12-07 22:57 UTC (permalink / raw)
  To: Simon Horman
  Cc: Bjorn Helgaas, Phil Edworthy, Magnus Damm, linux-pci,
	linux-renesas-soc, Rob Herring, devicetree
In-Reply-To: <1481039491-30364-1-git-send-email-horms+renesas@verge.net.au>

On Tue, Dec 06, 2016 at 04:51:28PM +0100, Simon Horman wrote:
> Hi,
> 
> this short series makes some bindings cleanups to the Renesas PCI drivers.
> 
> Changes v2->v3:
> * Reworded changelogs to indicate that re-ordering struct of_device_id
>   entries does not effect run-time behaviour
> * Corrected compile error due to typo in symbol name
> Changes v1->v2:
> * re-order struct of_device_id entries
> 
> Simon Horman (3):
>   PCI: rcar-gen2: Use gen2 fallback compatibility last
>   PCI: rcar: Use gen2 fallback compatibility last
>   PCI: rcar: Add gen3 fallback compatibility string for pcie-rcar
> 
>  Documentation/devicetree/bindings/pci/rcar-pci.txt | 1 +
>  drivers/pci/host/pci-rcar-gen2.c                   | 2 +-
>  drivers/pci/host/pcie-rcar.c                       | 5 +++--
>  3 files changed, 5 insertions(+), 3 deletions(-)

Applied to pci/host-rcar for v4.10, thanks!

^ permalink raw reply

* Re: [PATCH v2] ARM: dts: lpc32xx: add pwm-cells to base dts file
From: Vladimir Zapolskiy @ 2016-12-07 22:50 UTC (permalink / raw)
  To: Sylvain Lemieux, robh+dt; +Cc: devicetree, linux-arm-kernel
In-Reply-To: <1481139047-13166-1-git-send-email-slemieux.tyco@gmail.com>

Hi Sylvain,

On 12/07/2016 09:30 PM, Sylvain Lemieux wrote:
> From: Sylvain Lemieux <slemieux@tycoint.com>
> 
> There is no need to define the "pwm-cells" in the board
> specific dts file; move the entry to the base dts file.
> 
> Signed-off-by: Sylvain Lemieux <slemieux@tycoint.com>
> ---

thank you for the change,

Acked-by: Vladimir Zapolskiy <vz@mleia.com>

--
With best wishes,
Vladimir

^ permalink raw reply

* Re: [PATCH v5 1/2] Add OV5647 device tree documentation
From: Sakari Ailus @ 2016-12-07 22:33 UTC (permalink / raw)
  To: Ramiro Oliveira
  Cc: mchehab-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-media-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, devicetree-u79uwXL29TY76Z2rM5mHXA,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	linux-0h96xk9xTtrk1uMJSBkQmQ, hverkuil-qWit8jRvyhVmR6Xm/wNWPw,
	dheitmueller-eb9eJ82Ua7k9XoPSrs7Ehg,
	slongerbeam-Re5JQEeQqe8AvxtiuMwx3w, lars-Qo5EllUWu/uELgA04lAiVw,
	robert.jarzmik-GANU6spQydw, pavel-+ZI9xUNit7I,
	pali.rohar-Re5JQEeQqe8AvxtiuMwx3w,
	sakari.ailus-VuQAYsv1563Yd54FQh9/CA, mark.rutland-5wv7dgnIgG8,
	CARLOS.PALMINHA-HKixBCOQz3hWk0Htik3J/w
In-Reply-To: <bb5a2ae3078a977eb52aec0ffa3a0a0de558e6ad.1480958609.git.roliveir-HKixBCOQz3hWk0Htik3J/w@public.gmane.org>

Hi Ramiro,

Thank you for the patch.

On Mon, Dec 05, 2016 at 05:36:33PM +0000, Ramiro Oliveira wrote:
> Add device tree documentation.
> 
> Signed-off-by: Ramiro Oliveira <roliveir-HKixBCOQz3hWk0Htik3J/w@public.gmane.org>
> ---
>  .../devicetree/bindings/media/i2c/ov5647.txt          | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/i2c/ov5647.txt
> 
> diff --git a/Documentation/devicetree/bindings/media/i2c/ov5647.txt b/Documentation/devicetree/bindings/media/i2c/ov5647.txt
> new file mode 100644
> index 0000000..4c91b3b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/i2c/ov5647.txt
> @@ -0,0 +1,19 @@
> +Omnivision OV5647 raw image sensor
> +---------------------------------
> +
> +OV5647 is a raw image sensor with MIPI CSI-2 and CCP2 image data interfaces
> +and CCI (I2C compatible) control bus.
> +
> +Required properties:
> +
> +- compatible	: "ovti,ov5647";
> +- reg		: I2C slave address of the sensor;
> +
> +The common video interfaces bindings (see video-interfaces.txt) should be
> +used to specify link to the image data receiver. The OV5647 device
> +node should contain one 'port' child node with an 'endpoint' subnode.
> +
> +Following properties are valid for the endpoint node:
> +
> +- data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in
> +  video-interfaces.txt.  The sensor supports only two data lanes.

Doesn't this sensor require a external clock, a reset GPIO and / or a
regulator or a few? Do you need data-lanes, unless you can change the order
or the number?

An example DT snippet wouldn't hurt.

-- 
Kind regards,

Sakari Ailus
e-mail: sakari.ailus-X3B1VOXEql0@public.gmane.org	XMPP: sailus-PCDdDYkjdNMDXYZnReoRVg@public.gmane.org
--
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 v5 3/3] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs
From: Anatolij Gustschin @ 2016-12-07 21:33 UTC (permalink / raw)
  To: Joshua Clayton
  Cc: Alan Tull, Moritz Fischer, Mark Rutland, Russell King,
	Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <6e33619c-e8a4-e372-04ab-d03c379cbfa0-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On Wed, 7 Dec 2016 13:29:29 -0800
Joshua Clayton stillcompiling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:

>Anatolij,
>Thanks for the quick look and response.
>I guess I should have rebased before submitting.

yes, Makefile and Kconfig changes need rebasing, I think.

>I just realized I also forgot to send this patch series to
>the newly minted FPGA Manager mailing list. V6 coming soon :)

okay, thanks.

--
Anatolij
--
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 v5 3/3] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs
From: Joshua Clayton @ 2016-12-07 21:29 UTC (permalink / raw)
  To: Anatolij Gustschin
  Cc: Alan Tull, Moritz Fischer, Mark Rutland, Russell King,
	Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20161207222127.23f6b8b4@crub>

Anatolij,
Thanks for the quick look and response.
I guess I should have rebased before submitting.
I just realized I also forgot to send this patch series to
the newly minted FPGA Manager mailing list. V6 coming soon :)

On 12/07/2016 01:21 PM, Anatolij Gustschin wrote:
> On Wed,  7 Dec 2016 13:04:40 -0800
> Joshua Clayton stillcompiling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:
> ...
>> +static int cyclonespi_write_init(struct fpga_manager *mgr, u32 flags,
>> +				 const char *buf, size_t count)
> there is a minor API change in linux-next [1]. struct fpga_image_info *
> is passed instead of u32 flags. I assume this will be merged soon, so
> please prepare this driver accordingly.
>
> ...
Ah. Thanks.

>> +static int cyclonespi_write_complete(struct fpga_manager *mgr, u32 flags)
> same here.
OK.
>
> [1] http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/drivers/fpga?id=1df2865f8dd9d56cb76aa7aa1298921e7bece2af
>
> --
> Anatolij
Joshua
--
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 v5 3/3] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs
From: Anatolij Gustschin @ 2016-12-07 21:21 UTC (permalink / raw)
  To: Joshua Clayton
  Cc: Mark Rutland, Moritz Fischer, devicetree, Alan Tull, Russell King,
	linux-kernel, Rob Herring, linux-arm-kernel
In-Reply-To: <1778a82d1989d13919b24e47fa09eeb56b2cb8e5.1481139171.git.stillcompiling@gmail.com>

On Wed,  7 Dec 2016 13:04:40 -0800
Joshua Clayton stillcompiling@gmail.com wrote:
...
>+static int cyclonespi_write_init(struct fpga_manager *mgr, u32 flags,
>+				 const char *buf, size_t count)

there is a minor API change in linux-next [1]. struct fpga_image_info *
is passed instead of u32 flags. I assume this will be merged soon, so
please prepare this driver accordingly.

...
>+static int cyclonespi_write_complete(struct fpga_manager *mgr, u32 flags)

same here.

[1] http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/drivers/fpga?id=1df2865f8dd9d56cb76aa7aa1298921e7bece2af

--
Anatolij

^ permalink raw reply

* [PATCH v5 3/3] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs
From: Joshua Clayton @ 2016-12-07 21:04 UTC (permalink / raw)
  To: Alan Tull, Moritz Fischer, Mark Rutland, Russell King
  Cc: Rob Herring, Anatolij Gustschin, Joshua Clayton,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <cover.1481139171.git.stillcompiling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

cyclone-ps-spi loads FPGA firmware over spi, using the "passive serial"
interface on Altera Cyclone FPGAS.

This is one of the simpler ways to set up an FPGA at runtime.
The signal interface is close to unidirectional spi with lsb first.

Signed-off-by: Joshua Clayton <stillcompiling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/fpga/Kconfig          |   7 ++
 drivers/fpga/Makefile         |   1 +
 drivers/fpga/cyclone-ps-spi.c | 181 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 189 insertions(+)
 create mode 100644 drivers/fpga/cyclone-ps-spi.c

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index cd84934..2462707 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -13,6 +13,13 @@ config FPGA
 
 if FPGA
 
+config FPGA_MGR_CYCLONE_PS_SPI
+	tristate "Altera Cyclone FPGA Passive Serial over SPI"
+	depends on SPI
+	help
+	  FPGA manager driver support for Altera Cyclone using the
+	  passive serial interface over SPI
+
 config FPGA_MGR_SOCFPGA
 	tristate "Altera SOCFPGA FPGA Manager"
 	depends on ARCH_SOCFPGA
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 8d83fc6..8f93930 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -6,5 +6,6 @@
 obj-$(CONFIG_FPGA)			+= fpga-mgr.o
 
 # FPGA Manager Drivers
+obj-$(CONFIG_FPGA_MGR_CYCLONE_PS_SPI)	+= cyclone-ps-spi.o
 obj-$(CONFIG_FPGA_MGR_SOCFPGA)		+= socfpga.o
 obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
diff --git a/drivers/fpga/cyclone-ps-spi.c b/drivers/fpga/cyclone-ps-spi.c
new file mode 100644
index 0000000..82a754a
--- /dev/null
+++ b/drivers/fpga/cyclone-ps-spi.c
@@ -0,0 +1,181 @@
+/**
+ * Copyright (c) 2015 United Western Technologies, Corporation
+ *
+ * Joshua Clayton <stillcompiling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ *
+ * Manage Altera fpga firmware that is loaded over spi.
+ * Firmware must be in binary "rbf" format.
+ * Works on Cyclone V. Should work on cyclone series.
+ * May work on other Altera fpgas.
+ *
+ */
+
+#include <linux/bitrev.h>
+#include <linux/delay.h>
+#include <linux/fpga/fpga-mgr.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/sizes.h>
+
+#define FPGA_RESET_TIME		50   /* time in usecs to trigger FPGA config */
+#define FPGA_MIN_DELAY		50   /* min usecs to wait for config status */
+#define FPGA_MAX_DELAY		1000 /* max usecs to wait for config status */
+
+struct cyclonespi_conf {
+	struct gpio_desc *config;
+	struct gpio_desc *status;
+	struct spi_device *spi;
+};
+
+static const struct of_device_id of_ef_match[] = {
+	{ .compatible = "altr,cyclone-ps-spi-fpga-mgr", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, of_ef_match);
+
+static enum fpga_mgr_states cyclonespi_state(struct fpga_manager *mgr)
+{
+	struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv;
+
+	if (gpiod_get_value(conf->status))
+		return FPGA_MGR_STATE_RESET;
+
+	return FPGA_MGR_STATE_UNKNOWN;
+}
+
+static int cyclonespi_write_init(struct fpga_manager *mgr, u32 flags,
+				 const char *buf, size_t count)
+{
+	struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv;
+	int i;
+
+	if (flags & FPGA_MGR_PARTIAL_RECONFIG) {
+		dev_err(&mgr->dev, "Partial reconfiguration not supported.\n");
+		return -EINVAL;
+	}
+
+	gpiod_set_value(conf->config, 1);
+	usleep_range(FPGA_RESET_TIME, FPGA_RESET_TIME + 20);
+	if (!gpiod_get_value(conf->status)) {
+		dev_err(&mgr->dev, "Status pin should be low.\n");
+		return -EIO;
+	}
+
+	gpiod_set_value(conf->config, 0);
+	for (i = 0; i < (FPGA_MAX_DELAY / FPGA_MIN_DELAY); i++) {
+		usleep_range(FPGA_MIN_DELAY, FPGA_MIN_DELAY + 20);
+		if (!gpiod_get_value(conf->status))
+			return 0;
+	}
+
+	dev_err(&mgr->dev, "Status pin not ready.\n");
+	return -EIO;
+}
+
+static void rev_buf(void *buf, size_t len)
+{
+	u32 *fw32 = (u32 *)buf;
+	const u32 *fw_end = (u32 *)(buf + len);
+
+	/* set buffer to lsb first */
+	while (fw32 < fw_end) {
+		*fw32 = bitrev8x4(*fw32);
+		fw32++;
+	}
+}
+
+static int cyclonespi_write(struct fpga_manager *mgr, const char *buf,
+			    size_t count)
+{
+	struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv;
+	const char *fw_data = buf;
+	const char *fw_data_end = fw_data + count;
+
+	while (fw_data < fw_data_end) {
+		int ret;
+		size_t stride = min(fw_data_end - fw_data, SZ_4K);
+
+		rev_buf((void *)fw_data, stride);
+		ret = spi_write(conf->spi, fw_data, stride);
+		if (ret) {
+			dev_err(&mgr->dev, "spi error in firmware write: %d\n",
+				ret);
+			return ret;
+		}
+		fw_data += stride;
+	}
+
+	return 0;
+}
+
+static int cyclonespi_write_complete(struct fpga_manager *mgr, u32 flags)
+{
+	struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv;
+
+	if (gpiod_get_value(conf->status)) {
+		dev_err(&mgr->dev, "Error during configuration.\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static const struct fpga_manager_ops cyclonespi_ops = {
+	.state = cyclonespi_state,
+	.write_init = cyclonespi_write_init,
+	.write = cyclonespi_write,
+	.write_complete = cyclonespi_write_complete,
+};
+
+static int cyclonespi_probe(struct spi_device *spi)
+{
+	struct cyclonespi_conf *conf = devm_kzalloc(&spi->dev, sizeof(*conf),
+						GFP_KERNEL);
+
+	if (!conf)
+		return -ENOMEM;
+
+	conf->spi = spi;
+	conf->config = devm_gpiod_get(&spi->dev, "config", GPIOD_OUT_HIGH);
+	if (IS_ERR(conf->config)) {
+		dev_err(&spi->dev, "Failed to get config gpio: %ld\n",
+			PTR_ERR(conf->config));
+		return PTR_ERR(conf->config);
+	}
+
+	conf->status = devm_gpiod_get(&spi->dev, "status", GPIOD_IN);
+	if (IS_ERR(conf->status)) {
+		dev_err(&spi->dev, "Failed to get status gpio: %ld\n",
+			PTR_ERR(conf->status));
+		return PTR_ERR(conf->status);
+	}
+
+	return fpga_mgr_register(&spi->dev,
+				 "Altera Cyclone PS SPI FPGA Manager",
+				 &cyclonespi_ops, conf);
+}
+
+static int cyclonespi_remove(struct spi_device *spi)
+{
+	fpga_mgr_unregister(&spi->dev);
+
+	return 0;
+}
+
+static struct spi_driver cyclonespi_driver = {
+	.driver = {
+		.name   = "cyclone-ps-spi",
+		.owner  = THIS_MODULE,
+		.of_match_table = of_match_ptr(of_ef_match),
+	},
+	.probe  = cyclonespi_probe,
+	.remove = cyclonespi_remove,
+};
+
+module_spi_driver(cyclonespi_driver)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Joshua Clayton <stillcompiling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
+MODULE_DESCRIPTION("Module to load Altera FPGA firmware over spi");
-- 
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 v5 2/3] doc: dt: add cyclone-ps-spi binding document
From: Joshua Clayton @ 2016-12-07 21:04 UTC (permalink / raw)
  To: Alan Tull, Moritz Fischer, Mark Rutland, Russell King
  Cc: devicetree, Joshua Clayton, linux-kernel, Rob Herring,
	Anatolij Gustschin, linux-arm-kernel
In-Reply-To: <cover.1481139171.git.stillcompiling@gmail.com>

Describe a cyclone-ps-spi devicetree entry, required features

Signed-off-by: Joshua Clayton <stillcompiling@gmail.com>
Acked-by: Rob Herring <robh@kernel.org>
---
 .../bindings/fpga/cyclone-ps-spi-fpga-mgr.txt      | 25 ++++++++++++++++++++++
 1 file changed, 25 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt

diff --git a/Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt b/Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt
new file mode 100644
index 0000000..3f515c7
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt
@@ -0,0 +1,25 @@
+Altera Cyclone Passive Serial SPI FPGA Manager
+
+Altera Cyclone FPGAs support a method of loading the bitstream over what is
+referred to as "passive serial".
+The passive serial link is not technically spi, and might require extra
+circuits in order to play nicely with other spi slaves on the same bus.
+
+See https://www.altera.com/literature/hb/cyc/cyc_c51013.pdf
+
+Required properties:
+- compatible  : should contain "altr,cyclone-ps-spi-fpga-mgr"
+- reg         : spi slave id of the fpga
+- config-gpios : config pin (referred to as nCONFIG in the cyclone manual)
+- status-gpios : status pin (referred to as nSTATUS in the cyclone manual)
+
+both gpios pins are normally active low open drain.
+
+Example:
+	fpga_spi: evi-fpga-spi@0 {
+		compatible = "altr,cyclone-ps-spi-fpga-mgr";
+		spi-max-frequency = <20000000>;
+		reg = <0>;
+		config-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>;
+		status-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>;
+	};
-- 
2.9.3

^ permalink raw reply related

* [PATCH v5 1/3] lib: add bitrev8x4()
From: Joshua Clayton @ 2016-12-07 21:04 UTC (permalink / raw)
  To: Alan Tull, Moritz Fischer, Mark Rutland, Russell King
  Cc: devicetree, Joshua Clayton, linux-kernel, Rob Herring,
	Anatolij Gustschin, linux-arm-kernel
In-Reply-To: <cover.1481139171.git.stillcompiling@gmail.com>

Add a function to reverse bytes within a 32 bit word.
This function is more efficient than using the 8 bit version when
iterating over an array

Signed-off-by: Joshua Clayton <stillcompiling@gmail.com>
---
 arch/arm/include/asm/bitrev.h |  6 ++++++
 include/linux/bitrev.h        | 26 ++++++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/arch/arm/include/asm/bitrev.h b/arch/arm/include/asm/bitrev.h
index ec291c3..9482f78 100644
--- a/arch/arm/include/asm/bitrev.h
+++ b/arch/arm/include/asm/bitrev.h
@@ -17,4 +17,10 @@ static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x)
 	return __arch_bitrev32((u32)x) >> 24;
 }
 
+static __always_inline __attribute_const__ u32 __arch_bitrev8x4(u32 x)
+{
+	__asm__ ("rbit %0, %1; rev %0, %0" : "=r" (x) : "r" (x));
+	return x;
+}
+
 #endif
diff --git a/include/linux/bitrev.h b/include/linux/bitrev.h
index fb790b8..b1cfa1a 100644
--- a/include/linux/bitrev.h
+++ b/include/linux/bitrev.h
@@ -9,6 +9,7 @@
 #define __bitrev32 __arch_bitrev32
 #define __bitrev16 __arch_bitrev16
 #define __bitrev8 __arch_bitrev8
+#define __bitrev8x4 __arch_bitrev8x4
 
 #else
 extern u8 const byte_rev_table[256];
@@ -27,6 +28,14 @@ static inline u32 __bitrev32(u32 x)
 	return (__bitrev16(x & 0xffff) << 16) | __bitrev16(x >> 16);
 }
 
+static inline u32 __bitrev8x4(u32 x)
+{
+	return(__bitrev8(x & 0xff) |
+	       (__bitrev8((x >> 8)  & 0xff) << 8) |
+	       (__bitrev8((x >> 16)  & 0xff) << 16) |
+	       (__bitrev8((x >> 24)  & 0xff) << 24));
+}
+
 #endif /* CONFIG_HAVE_ARCH_BITREVERSE */
 
 #define __constant_bitrev32(x)	\
@@ -50,6 +59,15 @@ static inline u32 __bitrev32(u32 x)
 	__x;								\
 })
 
+#define __constant_bitrev8x4(x) \
+({			\
+	u32 __x = x;	\
+	__x = ((__x & (u32)0xF0F0F0F0UL) >> 4) | ((__x & (u32)0x0F0F0F0FUL) << 4);	\
+	__x = ((__x & (u32)0xCCCCCCCCUL) >> 2) | ((__x & (u32)0x33333333UL) << 2);	\
+	__x = ((__x & (u32)0xAAAAAAAAUL) >> 1) | ((__x & (u32)0x55555555UL) << 1);	\
+	__x;								\
+})
+
 #define __constant_bitrev8(x)	\
 ({					\
 	u8 __x = x;			\
@@ -75,6 +93,14 @@ static inline u32 __bitrev32(u32 x)
 	__bitrev16(__x);				\
  })
 
+#define bitrev8x4(x) \
+({			\
+	u32 __x = x;	\
+	__builtin_constant_p(__x) ?	\
+	__constant_bitrev8x4(__x) :			\
+	__bitrev8x4(__x);				\
+})
+
 #define bitrev8(x) \
 ({			\
 	u8 __x = x;	\
-- 
2.9.3

^ permalink raw reply related

* [PATCH v5 0/3] Altera Cyclone Passive Serial SPI FPGA Manager
From: Joshua Clayton @ 2016-12-07 21:04 UTC (permalink / raw)
  To: Alan Tull, Moritz Fischer, Mark Rutland, Russell King
  Cc: devicetree, Joshua Clayton, linux-kernel, Rob Herring,
	Anatolij Gustschin, linux-arm-kernel

This series adds an FPGA manager for Altera cyclone FPGAs
that can program them using an spi port and a couple of gpios, using
Alteras passive serial protocol.

Still need an ACK from Russell King on the ARM specific portion of 
patch 1. Any comment/criticism on the addition of bitrev8x4() to bitrev.h
would be welcome as well.

Changes from v4:
- Added the needed return statement to __arch_bitrev8x4()
- Added Rob Herrings ACK for and fix a typo in the commit log of patch 2

Changes from v3:
- Fixed up the state() function to return the state of the status pin
  reqested by Alan Tull
- Switched the pin to ACTIVE_LOW and coresponding logic level, and updated
  the corresponding documentation. Thanks Rob Herring for pointing out my
  mistake.
- Per Rob Herring, switched from "gpio" to "gpios" in dts

Changes from v2:
- Merged patch 3 and 4 as suggested in review by Moritz Fischer
- Changed FPGA_MIN_DELAY from 250 to 50 ms is the time advertized by
  Altera. This now works, as we don't assume it is done

Changes from v1:
- Changed the name from cyclone-spi-fpga-mgr to cyclone-ps-spi-fpga-mgr
  This name change was requested by Alan Tull, to be specific about which
  programming method is being employed on the fpga.
- Changed the name of the reset-gpio to config-gpio to closer match the
  way the pins are described in the Altera manual
- Moved MODULE_LICENCE, _AUTHOR, and _DESCRIPTION to the bottom

- Added a bitrev8x4() function to the bitrev headers and implemented ARM
 const, runtime, and ARM specific faster versions (This may end up
 needing to be a standalone patch)

- Moved the bitswapping into cyclonespi_write(), as requested.
  This falls short of my desired generic lsb first spi support, but is a step
  in that direction.

- Fixed whitespace problems introduced during refactoring

- Replaced magic number for initial delay with a descriptive macro
- Poll the fpga to see when it is ready rather than a fixed 1 ms sleep

Joshua Clayton (3):
  lib: add bitrev8x4()
  doc: dt: add cyclone-ps-spi binding document
  fpga manager: Add cyclone-ps-spi driver for Altera FPGAs

 .../bindings/fpga/cyclone-ps-spi-fpga-mgr.txt      |  25 +++
 arch/arm/include/asm/bitrev.h                      |   6 +
 drivers/fpga/Kconfig                               |   7 +
 drivers/fpga/Makefile                              |   1 +
 drivers/fpga/cyclone-ps-spi.c                      | 181 +++++++++++++++++++++
 include/linux/bitrev.h                             |  26 +++
 6 files changed, 246 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt
 create mode 100644 drivers/fpga/cyclone-ps-spi.c

-- 
2.9.3

^ permalink raw reply

* Re: [PATCH] ARM: dts: imx7d: fix LCDIF clock assignment
From: Olof Johansson @ 2016-12-07 20:53 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Arnd Bergmann, Sascha Hauer, Stefan Agner, Mark Rutland,
	devicetree, linux-kernel, robh+dt, Peter Chen, Fabio Estevam,
	Liu Ying, linux-arm-kernel, Fabio Estevam
In-Reply-To: <20161205020123.GA2066@dragon>

On Mon, Dec 05, 2016 at 10:01:24AM +0800, Shawn Guo wrote:
> Hi Arnd, Olof,
> 
> On Sun, Dec 04, 2016 at 05:26:58PM -0800, Stefan Agner wrote:
> > Hi Shawn
> > 
> > On 2016-11-23 15:02, Fabio Estevam wrote:
> > > On Tue, Nov 22, 2016 at 10:42 PM, Stefan Agner <stefan@agner.ch> wrote:
> > >> The eLCDIF IP of the i.MX 7 SoC knows multiple clocks and lists them
> > >> separately:
> > >>
> > >> Clock      Clock Root              Description
> > >> apb_clk    MAIN_AXI_CLK_ROOT       AXI clock
> > >> pix_clk    LCDIF_PIXEL_CLK_ROOT    Pixel clock
> > >> ipg_clk_s  MAIN_AXI_CLK_ROOT       Peripheral access clock
> > >>
> > >> All of them are switched by a single gate, which is part of the
> > >> IMX7D_LCDIF_PIXEL_ROOT_CLK clock. Hence using that clock also for
> > >> the AXI bus clock (clock-name "axi") makes sure the gate gets
> > >> enabled when accessing registers.
> > >>
> > >> There seem to be no separate AXI display clock, and the clock is
> > >> optional. Hence remove the dummy clock.
> > >>
> > >> This fixes kernel freezes when starting the X-Server (which
> > >> disables/re-enables the display controller).
> > >>
> > >> Signed-off-by: Stefan Agner <stefan@agner.ch>
> > > 
> > > Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
> > 
> > Since this fixes a kernel freeze, is there a chance to get this still in
> > 4.9?
> 
> Since we get one more week to the final 4.9, is it possible for you to
> send this fix for 4.9 inclusion?  Thanks.
> 
> For the patch,
> 
> Acked-by: Shawn Guo <shawnguo@kernel.org>

Applied, with the fixes line. In the future, please email arm@kernel.org too,
it's easier to make sure we don't miss it that way.


-Olof

^ permalink raw reply

* Re: [PATCH] dts: sun8i-h3: correct UART3 pin definitions
From: Olof Johansson @ 2016-12-07 20:40 UTC (permalink / raw)
  To: jorik-U9/BOH3cVv3CLqq/8VZgpA
  Cc: arm-DgEjT+Ai2ygdnm+yROfE0A,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-I+IVW8TIWO2tmTQ+vhA3Yw, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20161206142710.6450-1-jorik-U9/BOH3cVv3CLqq/8VZgpA@public.gmane.org>

On Tue, Dec 06, 2016 at 03:27:10PM +0100, jorik-U9/BOH3cVv3CLqq/8VZgpA@public.gmane.org wrote:
> From: Jorik Jonker <jorik-U9/BOH3cVv3CLqq/8VZgpA@public.gmane.org>
> 
> In a previous commit, I made a copy/paste error in the pinmux
> definitions of UART3: PG{13,14} instead of PA{13,14}. This commit takes
> care of that. I have tested this commit on Orange Pi PC and Orange Pi
> Plus, and it works for these boards.
> 
> Fixes: e3d11d3c45c5 ("dts: sun8i-h3: add pinmux definitions for
> UART2-3")
> 
> Signed-off-by: Jorik Jonker <jorik-U9/BOH3cVv3CLqq/8VZgpA@public.gmane.org>

Applied to fixes. Thanks.


-Olof
--
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 2/2] ASoC: cs43130: Add devicetree bindings for CS43130
From: Li Xu @ 2016-12-07 20:17 UTC (permalink / raw)
  To: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	perex-/Fr2/VpizcU, tiwai-IBi9RG/b67k,
	brian.austin-jGc1dHjMKG3QT0dZR+AlfA,
	Paul.Handrigan-jGc1dHjMKG3QT0dZR+AlfA, Li Xu
In-Reply-To: <1481141848-6695-1-git-send-email-li.xu-jGc1dHjMKG3QT0dZR+AlfA@public.gmane.org>

Add devicetree bindings documentation file for Cirrus
Logic CS43130 codec.

Signed-off-by: Li Xu <li.xu-jGc1dHjMKG3QT0dZR+AlfA@public.gmane.org>
---
 .../devicetree/bindings/sound/cs43130.txt          | 41 ++++++++++++++++++++++
 1 file changed, 41 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/cs43130.txt

diff --git a/Documentation/devicetree/bindings/sound/cs43130.txt b/Documentation/devicetree/bindings/sound/cs43130.txt
new file mode 100644
index 0000000..9a2a22a
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/cs43130.txt
@@ -0,0 +1,41 @@
+CS43130 DAC
+
+Required properties:
+
+  - compatible : "cirrus,cs43130"
+
+  - reg : the I2C address of the device for I2C
+
+  - VA-supply, VP-supply, VL-supply, VCP-supply, VD-supply:
+	power supplies for the device, as covered in
+	Documentation/devicetree/bindings/regulator/regulator.txt.
+
+
+Optional properties:
+
+  - reset-gpios : gpio used to reset the Device
+
+  - cirrus,xtal-ibias:
+   When external MCLK is generated by external crystal
+   oscillator, CS43130 can be used to provide bias current
+   for external crystal.  Amount of bias current sent is
+   set as:
+   1 = 7.5uA
+   2 = 12.5uA
+   3 = 15uA
+
+Example:
+
+cs43130: cs43130@30 {
+	compatible = "cirrus,cs43130";
+	reg = <0x30>;
+	reset-gpios = <&axi_gpio 54 0>;
+   VA-supply = <&dummy_vreg>;
+   VP-supply = <&dummy_vreg>;
+   VL-supply = <&dummy_vreg>;
+   VCP-supply = <&dummy_vreg>;
+   VD-supply = <&dummy_vreg>;
+   cirrus,xtal-ibias = <2>;
+   interrupt-parent = <&gpio0>;
+   interrupts = <55 8>;
+};
-- 
1.9.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


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