Devicetree
 help / color / mirror / Atom feed
* [PATCH 6/9] dt-bindings: clock: Convert i.MX27 clock to json-schema
From: Anson Huang @ 2020-05-28  7:27 UTC (permalink / raw)
  To: mturquette, sboyd, robh+dt, shawnguo, s.hauer, kernel, festevam,
	shc_work, s.trumtrar, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel
  Cc: Linux-imx
In-Reply-To: <1590650879-18288-1-git-send-email-Anson.Huang@nxp.com>

Convert the i.MX27 clock binding to DT schema format using json-schema.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
 .../devicetree/bindings/clock/imx27-clock.txt      | 27 -----------
 .../devicetree/bindings/clock/imx27-clock.yaml     | 53 ++++++++++++++++++++++
 2 files changed, 53 insertions(+), 27 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/imx27-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/imx27-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/imx27-clock.txt b/Documentation/devicetree/bindings/clock/imx27-clock.txt
deleted file mode 100644
index 4c95c04..0000000
--- a/Documentation/devicetree/bindings/clock/imx27-clock.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-* Clock bindings for Freescale i.MX27
-
-Required properties:
-- compatible: Should be "fsl,imx27-ccm"
-- reg: Address and length of the register set
-- interrupts: Should contain CCM interrupt
-- #clock-cells: Should be <1>
-
-The clock consumer should specify the desired clock by having the clock
-ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx27-clock.h
-for the full list of i.MX27 clock IDs.
-
-Examples:
-	clks: ccm@10027000{
-		compatible = "fsl,imx27-ccm";
-		reg = <0x10027000 0x1000>;
-		#clock-cells = <1>;
-	};
-
-	uart1: serial@1000a000 {
-		compatible = "fsl,imx27-uart", "fsl,imx21-uart";
-		reg = <0x1000a000 0x1000>;
-		interrupts = <20>;
-		clocks = <&clks IMX27_CLK_UART1_IPG_GATE>,
-			 <&clks IMX27_CLK_PER1_GATE>;
-		clock-names = "ipg", "per";
-	};
diff --git a/Documentation/devicetree/bindings/clock/imx27-clock.yaml b/Documentation/devicetree/bindings/clock/imx27-clock.yaml
new file mode 100644
index 0000000..2d69807
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx27-clock.yaml
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/imx27-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Clock bindings for Freescale i.MX27
+
+maintainers:
+  - Fabio Estevam <fabio.estevam@freescale.com>
+
+description: |
+  The clock consumer should specify the desired clock by having the clock
+  ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx27-clock.h
+  for the full list of i.MX27 clock IDs.
+
+properties:
+  compatible:
+    const: fsl,imx27-ccm
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx27-clock.h>
+
+    clock-controller@10027000 {
+        compatible = "fsl,imx27-ccm";
+        reg = <0x10027000 0x1000>;
+        interrupts = <31>;
+        #clock-cells = <1>;
+    };
+
+    serial@1000a000 {
+        compatible = "fsl,imx27-uart", "fsl,imx21-uart";
+        reg = <0x1000a000 0x1000>;
+        interrupts = <20>;
+        clocks = <&clks IMX27_CLK_UART1_IPG_GATE>,
+                 <&clks IMX27_CLK_PER1_GATE>;
+        clock-names = "ipg", "per";
+    };
-- 
2.7.4


^ permalink raw reply related

* [PATCH 8/9] dt-bindings: clock: Convert i.MX21 clock to json-schema
From: Anson Huang @ 2020-05-28  7:27 UTC (permalink / raw)
  To: mturquette, sboyd, robh+dt, shawnguo, s.hauer, kernel, festevam,
	shc_work, s.trumtrar, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel
  Cc: Linux-imx
In-Reply-To: <1590650879-18288-1-git-send-email-Anson.Huang@nxp.com>

Convert the i.MX21 clock binding to DT schema format using json-schema,
can NOT find any CCM interrupt info from reference manual and DT file,
so interrupts property is removed from original binding doc.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
 .../devicetree/bindings/clock/imx21-clock.txt      | 27 ------------
 .../devicetree/bindings/clock/imx21-clock.yaml     | 49 ++++++++++++++++++++++
 2 files changed, 49 insertions(+), 27 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/imx21-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/imx21-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/imx21-clock.txt b/Documentation/devicetree/bindings/clock/imx21-clock.txt
deleted file mode 100644
index 806f63d..0000000
--- a/Documentation/devicetree/bindings/clock/imx21-clock.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-* Clock bindings for Freescale i.MX21
-
-Required properties:
-- compatible  : Should be "fsl,imx21-ccm".
-- reg         : Address and length of the register set.
-- interrupts  : Should contain CCM interrupt.
-- #clock-cells: Should be <1>.
-
-The clock consumer should specify the desired clock by having the clock
-ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx21-clock.h
-for the full list of i.MX21 clock IDs.
-
-Examples:
-	clks: ccm@10027000{
-		compatible = "fsl,imx21-ccm";
-		reg = <0x10027000 0x800>;
-		#clock-cells = <1>;
-	};
-
-	uart1: serial@1000a000 {
-		compatible = "fsl,imx21-uart";
-		reg = <0x1000a000 0x1000>;
-		interrupts = <20>;
-		clocks = <&clks IMX21_CLK_UART1_IPG_GATE>,
-			 <&clks IMX21_CLK_PER1>;
-		clock-names = "ipg", "per";
-	};
diff --git a/Documentation/devicetree/bindings/clock/imx21-clock.yaml b/Documentation/devicetree/bindings/clock/imx21-clock.yaml
new file mode 100644
index 0000000..cee9b00
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx21-clock.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/imx21-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Clock bindings for Freescale i.MX21
+
+maintainers:
+  - Alexander Shiyan <shc_work@mail.ru>
+
+description: |
+  The clock consumer should specify the desired clock by having the clock
+  ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx21-clock.h
+  for the full list of i.MX21 clock IDs.
+
+properties:
+  compatible:
+    const: fsl,imx21-ccm
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx21-clock.h>
+
+    clock-controller@10027000 {
+        compatible = "fsl,imx21-ccm";
+        reg = <0x10027000 0x800>;
+        #clock-cells = <1>;
+    };
+
+    serial@1000a000 {
+        compatible = "fsl,imx21-uart";
+        reg = <0x1000a000 0x1000>;
+        interrupts = <20>;
+        clocks = <&clks IMX21_CLK_UART1_IPG_GATE>,
+                 <&clks IMX21_CLK_PER1>;
+        clock-names = "ipg", "per";
+    };
-- 
2.7.4


^ permalink raw reply related

* [PATCH 5/9] dt-bindings: clock: Convert i.MX23 clock to json-schema
From: Anson Huang @ 2020-05-28  7:27 UTC (permalink / raw)
  To: mturquette, sboyd, robh+dt, shawnguo, s.hauer, kernel, festevam,
	shc_work, s.trumtrar, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel
  Cc: Linux-imx
In-Reply-To: <1590650879-18288-1-git-send-email-Anson.Huang@nxp.com>

Convert the i.MX23 clock binding to DT schema format using json-schema.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
 .../devicetree/bindings/clock/imx23-clock.txt      | 70 -----------------
 .../devicetree/bindings/clock/imx23-clock.yaml     | 90 ++++++++++++++++++++++
 2 files changed, 90 insertions(+), 70 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/imx23-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/imx23-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/imx23-clock.txt b/Documentation/devicetree/bindings/clock/imx23-clock.txt
deleted file mode 100644
index 8385348..0000000
--- a/Documentation/devicetree/bindings/clock/imx23-clock.txt
+++ /dev/null
@@ -1,70 +0,0 @@
-* Clock bindings for Freescale i.MX23
-
-Required properties:
-- compatible: Should be "fsl,imx23-clkctrl"
-- reg: Address and length of the register set
-- #clock-cells: Should be <1>
-
-The clock consumer should specify the desired clock by having the clock
-ID in its "clocks" phandle cell.  The following is a full list of i.MX23
-clocks and IDs.
-
-	Clock		ID
-	------------------
-	ref_xtal	0
-	pll		1
-	ref_cpu		2
-	ref_emi		3
-	ref_pix		4
-	ref_io		5
-	saif_sel	6
-	lcdif_sel	7
-	gpmi_sel	8
-	ssp_sel		9
-	emi_sel		10
-	cpu		11
-	etm_sel		12
-	cpu_pll		13
-	cpu_xtal	14
-	hbus		15
-	xbus		16
-	lcdif_div	17
-	ssp_div		18
-	gpmi_div	19
-	emi_pll		20
-	emi_xtal	21
-	etm_div		22
-	saif_div	23
-	clk32k_div	24
-	rtc		25
-	adc		26
-	spdif_div	27
-	clk32k		28
-	dri		29
-	pwm		30
-	filt		31
-	uart		32
-	ssp		33
-	gpmi		34
-	spdif		35
-	emi		36
-	saif		37
-	lcdif		38
-	etm		39
-	usb		40
-	usb_phy		41
-
-Examples:
-
-clks: clkctrl@80040000 {
-	compatible = "fsl,imx23-clkctrl";
-	reg = <0x80040000 0x2000>;
-	#clock-cells = <1>;
-};
-
-auart0: serial@8006c000 {
-	compatible = "fsl,imx23-auart";
-	reg = <0x8006c000 0x2000>;
-	interrupts = <24 25 23>;
-	clocks = <&clks 32>;
-};
diff --git a/Documentation/devicetree/bindings/clock/imx23-clock.yaml b/Documentation/devicetree/bindings/clock/imx23-clock.yaml
new file mode 100644
index 0000000..0fd21f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx23-clock.yaml
@@ -0,0 +1,90 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/imx23-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Clock bindings for Freescale i.MX23
+
+maintainers:
+  - Shawn Guo <shawn.guo@linaro.org>
+
+description: |
+  The clock consumer should specify the desired clock by having the clock
+  ID in its "clocks" phandle cell. The following is a full list of i.MX23
+  clocks and IDs.
+
+        Clock		ID
+        ------------------
+        ref_xtal	0
+        pll		1
+        ref_cpu		2
+        ref_emi		3
+        ref_pix		4
+        ref_io		5
+        saif_sel	6
+        lcdif_sel	7
+        gpmi_sel	8
+        ssp_sel		9
+        emi_sel		10
+        cpu		11
+        etm_sel		12
+        cpu_pll		13
+        cpu_xtal	14
+        hbus		15
+        xbus		16
+        lcdif_div	17
+        ssp_div		18
+        gpmi_div	19
+        emi_pll		20
+        emi_xtal	21
+        etm_div		22
+        saif_div	23
+        clk32k_div	24
+        rtc		25
+        adc		26
+        spdif_div	27
+        clk32k		28
+        dri		29
+        pwm		30
+        filt		31
+        uart		32
+        ssp		33
+        gpmi		34
+        spdif		35
+        emi		36
+        saif		37
+        lcdif		38
+        etm		39
+        usb		40
+        usb_phy		41
+
+properties:
+  compatible:
+    const: fsl,imx23-clkctrl
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+
+examples:
+  - |
+    clock-controller@80040000 {
+        compatible = "fsl,imx23-clkctrl";
+        reg = <0x80040000 0x2000>;
+        #clock-cells = <1>;
+    };
+
+    serial@8006c000 {
+        compatible = "fsl,imx23-auart";
+        reg = <0x8006c000 0x2000>;
+        interrupts = <24 25 23>;
+        clocks = <&clks 32>;
+    };
-- 
2.7.4


^ permalink raw reply related

* [PATCH 4/9] dt-bindings: clock: Convert i.MX28 clock to json-schema
From: Anson Huang @ 2020-05-28  7:27 UTC (permalink / raw)
  To: mturquette, sboyd, robh+dt, shawnguo, s.hauer, kernel, festevam,
	shc_work, s.trumtrar, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel
  Cc: Linux-imx
In-Reply-To: <1590650879-18288-1-git-send-email-Anson.Huang@nxp.com>

Convert the i.MX28 clock binding to DT schema format using json-schema.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
 .../devicetree/bindings/clock/imx28-clock.txt      |  93 -----------------
 .../devicetree/bindings/clock/imx28-clock.yaml     | 113 +++++++++++++++++++++
 2 files changed, 113 insertions(+), 93 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/imx28-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/imx28-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/imx28-clock.txt b/Documentation/devicetree/bindings/clock/imx28-clock.txt
deleted file mode 100644
index d84a37d..0000000
--- a/Documentation/devicetree/bindings/clock/imx28-clock.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-* Clock bindings for Freescale i.MX28
-
-Required properties:
-- compatible: Should be "fsl,imx28-clkctrl"
-- reg: Address and length of the register set
-- #clock-cells: Should be <1>
-
-The clock consumer should specify the desired clock by having the clock
-ID in its "clocks" phandle cell.  The following is a full list of i.MX28
-clocks and IDs.
-
-	Clock		ID
-	------------------
-	ref_xtal	0
-	pll0		1
-	pll1		2
-	pll2		3
-	ref_cpu		4
-	ref_emi		5
-	ref_io0		6
-	ref_io1		7
-	ref_pix		8
-	ref_hsadc	9
-	ref_gpmi	10
-	saif0_sel	11
-	saif1_sel	12
-	gpmi_sel	13
-	ssp0_sel	14
-	ssp1_sel	15
-	ssp2_sel	16
-	ssp3_sel	17
-	emi_sel		18
-	etm_sel		19
-	lcdif_sel	20
-	cpu		21
-	ptp_sel		22
-	cpu_pll		23
-	cpu_xtal	24
-	hbus		25
-	xbus		26
-	ssp0_div	27
-	ssp1_div	28
-	ssp2_div	29
-	ssp3_div	30
-	gpmi_div	31
-	emi_pll		32
-	emi_xtal	33
-	lcdif_div	34
-	etm_div		35
-	ptp		36
-	saif0_div	37
-	saif1_div	38
-	clk32k_div	39
-	rtc		40
-	lradc		41
-	spdif_div	42
-	clk32k		43
-	pwm		44
-	uart		45
-	ssp0		46
-	ssp1		47
-	ssp2		48
-	ssp3		49
-	gpmi		50
-	spdif		51
-	emi		52
-	saif0		53
-	saif1		54
-	lcdif		55
-	etm		56
-	fec		57
-	can0		58
-	can1		59
-	usb0		60
-	usb1		61
-	usb0_phy	62
-	usb1_phy	63
-	enet_out	64
-
-Examples:
-
-clks: clkctrl@80040000 {
-	compatible = "fsl,imx28-clkctrl";
-	reg = <0x80040000 0x2000>;
-	#clock-cells = <1>;
-};
-
-auart0: serial@8006a000 {
-	compatible = "fsl,imx28-auart", "fsl,imx23-auart";
-	reg = <0x8006a000 0x2000>;
-	interrupts = <112 70 71>;
-	clocks = <&clks 45>;
-};
diff --git a/Documentation/devicetree/bindings/clock/imx28-clock.yaml b/Documentation/devicetree/bindings/clock/imx28-clock.yaml
new file mode 100644
index 0000000..e4a7038
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx28-clock.yaml
@@ -0,0 +1,113 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/imx28-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Clock bindings for Freescale i.MX28
+
+maintainers:
+  - Shawn Guo <shawn.guo@linaro.org>
+
+description: |
+  The clock consumer should specify the desired clock by having the clock
+  ID in its "clocks" phandle cell. The following is a full list of i.MX28
+  clocks and IDs.
+
+        Clock		ID
+        ------------------
+        ref_xtal	0
+        pll0		1
+        pll1		2
+        pll2		3
+        ref_cpu		4
+        ref_emi		5
+        ref_io0		6
+        ref_io1		7
+        ref_pix		8
+        ref_hsadc	9
+        ref_gpmi	10
+        saif0_sel	11
+        saif1_sel	12
+        gpmi_sel	13
+        ssp0_sel	14
+        ssp1_sel	15
+        ssp2_sel	16
+        ssp3_sel	17
+        emi_sel		18
+        etm_sel		19
+        lcdif_sel	20
+        cpu		21
+        ptp_sel		22
+        cpu_pll		23
+        cpu_xtal	24
+        hbus		25
+        xbus		26
+        ssp0_div	27
+        ssp1_div	28
+        ssp2_div	29
+        ssp3_div	30
+        gpmi_div	31
+        emi_pll		32
+        emi_xtal	33
+        lcdif_div	34
+        etm_div		35
+        ptp		36
+        saif0_div	37
+        saif1_div	38
+        clk32k_div	39
+        rtc		40
+        lradc		41
+        spdif_div	42
+        clk32k		43
+        pwm		44
+        uart		45
+        ssp0		46
+        ssp1		47
+        ssp2		48
+        ssp3		49
+        gpmi		50
+        spdif		51
+        emi		52
+        saif0		53
+        saif1		54
+        lcdif		55
+        etm		56
+        fec		57
+        can0		58
+        can1		59
+        usb0		60
+        usb1		61
+        usb0_phy	62
+        usb1_phy	63
+        enet_out	64
+
+properties:
+  compatible:
+    const: fsl,imx28-clkctrl
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+
+examples:
+  - |
+    clock-controller@80040000 {
+        compatible = "fsl,imx28-clkctrl";
+        reg = <0x80040000 0x2000>;
+        #clock-cells = <1>;
+    };
+
+    serial@8006a000 {
+        compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+        reg = <0x8006a000 0x2000>;
+        interrupts = <112 70 71>;
+        clocks = <&clks 45>;
+    };
-- 
2.7.4


^ permalink raw reply related

* [PATCH 3/9] dt-bindings: clock: Convert i.MX31 clock to json-schema
From: Anson Huang @ 2020-05-28  7:27 UTC (permalink / raw)
  To: mturquette, sboyd, robh+dt, shawnguo, s.hauer, kernel, festevam,
	shc_work, s.trumtrar, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel
  Cc: Linux-imx
In-Reply-To: <1590650879-18288-1-git-send-email-Anson.Huang@nxp.com>

Convert the i.MX31 clock binding to DT schema format using json-schema.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
 .../devicetree/bindings/clock/imx31-clock.txt      |  90 ----------------
 .../devicetree/bindings/clock/imx31-clock.yaml     | 118 +++++++++++++++++++++
 2 files changed, 118 insertions(+), 90 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/imx31-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/imx31-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/imx31-clock.txt b/Documentation/devicetree/bindings/clock/imx31-clock.txt
deleted file mode 100644
index 0a29109..0000000
--- a/Documentation/devicetree/bindings/clock/imx31-clock.txt
+++ /dev/null
@@ -1,90 +0,0 @@
-* Clock bindings for Freescale i.MX31
-
-Required properties:
-- compatible: Should be "fsl,imx31-ccm"
-- reg: Address and length of the register set
-- interrupts: Should contain CCM interrupt
-- #clock-cells: Should be <1>
-
-The clock consumer should specify the desired clock by having the clock
-ID in its "clocks" phandle cell.  The following is a full list of i.MX31
-clocks and IDs.
-
-	Clock		    ID
-	-----------------------
-	dummy	             0
-	ckih                 1
-	ckil                 2
-	mpll                 3
-	spll                 4
-	upll                 5
-	mcu_main             6
-	hsp                  7
-	ahb                  8
-	nfc                  9
-	ipg                  10
-	per_div              11
-	per                  12
-	csi_sel              13
-	fir_sel              14
-	csi_div              15
-	usb_div_pre          16
-	usb_div_post         17
-	fir_div_pre          18
-	fir_div_post         19
-	sdhc1_gate           20
-	sdhc2_gate           21
-	gpt_gate             22
-	epit1_gate           23
-	epit2_gate           24
-	iim_gate             25
-	ata_gate             26
-	sdma_gate            27
-	cspi3_gate           28
-	rng_gate             29
-	uart1_gate           30
-	uart2_gate           31
-	ssi1_gate            32
-	i2c1_gate            33
-	i2c2_gate            34
-	i2c3_gate            35
-	hantro_gate          36
-	mstick1_gate         37
-	mstick2_gate         38
-	csi_gate             39
-	rtc_gate             40
-	wdog_gate            41
-	pwm_gate             42
-	sim_gate             43
-	ect_gate             44
-	usb_gate             45
-	kpp_gate             46
-	ipu_gate             47
-	uart3_gate           48
-	uart4_gate           49
-	uart5_gate           50
-	owire_gate           51
-	ssi2_gate            52
-	cspi1_gate           53
-	cspi2_gate           54
-	gacc_gate            55
-	emi_gate             56
-	rtic_gate            57
-	firi_gate            58
-
-Examples:
-
-clks: ccm@53f80000{
-	compatible = "fsl,imx31-ccm";
-	reg = <0x53f80000 0x4000>;
-	interrupts = <31>, <53>;
-	#clock-cells = <1>;
-};
-
-uart1: serial@43f90000 {
-	compatible = "fsl,imx31-uart", "fsl,imx21-uart";
-	reg = <0x43f90000 0x4000>;
-	interrupts = <45>;
-	clocks = <&clks 10>, <&clks 30>;
-	clock-names = "ipg", "per";
-};
diff --git a/Documentation/devicetree/bindings/clock/imx31-clock.yaml b/Documentation/devicetree/bindings/clock/imx31-clock.yaml
new file mode 100644
index 0000000..2d9220e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx31-clock.yaml
@@ -0,0 +1,118 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/imx31-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Clock bindings for Freescale i.MX31
+
+maintainers:
+  - Fabio Estevam <fabio.estevam@freescale.com>
+
+description: |
+  The clock consumer should specify the desired clock by having the clock
+  ID in its "clocks" phandle cell. The following is a full list of i.MX31
+  clocks and IDs.
+
+        Clock		    ID
+        -----------------------
+        dummy	             0
+        ckih                 1
+        ckil                 2
+        mpll                 3
+        spll                 4
+        upll                 5
+        mcu_main             6
+        hsp                  7
+        ahb                  8
+        nfc                  9
+        ipg                  10
+        per_div              11
+        per                  12
+        csi_sel              13
+        fir_sel              14
+        csi_div              15
+        usb_div_pre          16
+        usb_div_post         17
+        fir_div_pre          18
+        fir_div_post         19
+        sdhc1_gate           20
+        sdhc2_gate           21
+        gpt_gate             22
+        epit1_gate           23
+        epit2_gate           24
+        iim_gate             25
+        ata_gate             26
+        sdma_gate            27
+        cspi3_gate           28
+        rng_gate             29
+        uart1_gate           30
+        uart2_gate           31
+        ssi1_gate            32
+        i2c1_gate            33
+        i2c2_gate            34
+        i2c3_gate            35
+        hantro_gate          36
+        mstick1_gate         37
+        mstick2_gate         38
+        csi_gate             39
+        rtc_gate             40
+        wdog_gate            41
+        pwm_gate             42
+        sim_gate             43
+        ect_gate             44
+        usb_gate             45
+        kpp_gate             46
+        ipu_gate             47
+        uart3_gate           48
+        uart4_gate           49
+        uart5_gate           50
+        owire_gate           51
+        ssi2_gate            52
+        cspi1_gate           53
+        cspi2_gate           54
+        gacc_gate            55
+        emi_gate             56
+        rtic_gate            57
+        firi_gate            58
+
+properties:
+  compatible:
+    const: fsl,imx31-ccm
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    description: CCM provides 2 interrupt requests, request 1 is to generate
+      interrupt for DVFS when a frequency change is requested, request 2 is
+      to generate interrupt for DPTC when a voltage change is requested.
+    items:
+      - description: CCM DVFS interrupt request 1
+      - description: CCM DPTC interrupt request 2
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - '#clock-cells'
+
+examples:
+  - |
+    clock-controller@53f80000 {
+        compatible = "fsl,imx31-ccm";
+        reg = <0x53f80000 0x4000>;
+        interrupts = <31>, <53>;
+        #clock-cells = <1>;
+    };
+
+    serial@43f90000 {
+        compatible = "fsl,imx31-uart", "fsl,imx21-uart";
+        reg = <0x43f90000 0x4000>;
+        interrupts = <45>;
+        clocks = <&clks 10>, <&clks 30>;
+        clock-names = "ipg", "per";
+    };
-- 
2.7.4


^ permalink raw reply related

* [PATCH 1/9] dt-bindings: clock: Convert i.MX5 clock to json-schema
From: Anson Huang @ 2020-05-28  7:27 UTC (permalink / raw)
  To: mturquette, sboyd, robh+dt, shawnguo, s.hauer, kernel, festevam,
	shc_work, s.trumtrar, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel
  Cc: Linux-imx
In-Reply-To: <1590650879-18288-1-git-send-email-Anson.Huang@nxp.com>

Convert the i.MX5 clock binding to DT schema format using json-schema.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
 .../devicetree/bindings/clock/imx5-clock.txt       | 28 ----------
 .../devicetree/bindings/clock/imx5-clock.yaml      | 63 ++++++++++++++++++++++
 2 files changed, 63 insertions(+), 28 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/imx5-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/imx5-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/imx5-clock.txt b/Documentation/devicetree/bindings/clock/imx5-clock.txt
deleted file mode 100644
index a24ca9e..0000000
--- a/Documentation/devicetree/bindings/clock/imx5-clock.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-* Clock bindings for Freescale i.MX5
-
-Required properties:
-- compatible: Should be "fsl,<soc>-ccm" , where <soc> can be imx51 or imx53
-- reg: Address and length of the register set
-- interrupts: Should contain CCM interrupt
-- #clock-cells: Should be <1>
-
-The clock consumer should specify the desired clock by having the clock
-ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx5-clock.h
-for the full list of i.MX5 clock IDs.
-
-Examples (for mx53):
-
-clks: ccm@53fd4000{
-	compatible = "fsl,imx53-ccm";
-	reg = <0x53fd4000 0x4000>;
-	interrupts = <0 71 0x04 0 72 0x04>;
-	#clock-cells = <1>;
-};
-
-can1: can@53fc8000 {
-	compatible = "fsl,imx53-flexcan", "fsl,p1010-flexcan";
-	reg = <0x53fc8000 0x4000>;
-	interrupts = <82>;
-	clocks = <&clks IMX5_CLK_CAN1_IPG_GATE>, <&clks IMX5_CLK_CAN1_SERIAL_GATE>;
-	clock-names = "ipg", "per";
-};
diff --git a/Documentation/devicetree/bindings/clock/imx5-clock.yaml b/Documentation/devicetree/bindings/clock/imx5-clock.yaml
new file mode 100644
index 0000000..e4c405c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx5-clock.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/imx5-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Clock bindings for Freescale i.MX5
+
+maintainers:
+  - Fabio Estevam <fabio.estevam@freescale.com>
+
+description: |
+  The clock consumer should specify the desired clock by having the clock
+  ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx5-clock.h
+  for the full list of i.MX5 clock IDs.
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx53-ccm
+      - fsl,imx51-ccm
+      - fsl,imx50-ccm
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    description: CCM provides 2 interrupt requests, request 1 is to generate
+      interrupt for frequency or mux change, request 2 is to generate
+      interrupt for oscillator read or PLL lock.
+    items:
+      - description: CCM interrupt request 1
+      - description: CCM interrupt request 2
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - '#clock-cells'
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx5-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    clock-controller@53fd4000{
+        compatible = "fsl,imx53-ccm";
+        reg = <0x53fd4000 0x4000>;
+        interrupts = <0 71 IRQ_TYPE_LEVEL_HIGH>,
+                     <0 72 IRQ_TYPE_LEVEL_HIGH>;
+        #clock-cells = <1>;
+    };
+
+    can@53fc8000 {
+        compatible = "fsl,imx53-flexcan", "fsl,p1010-flexcan";
+        reg = <0x53fc8000 0x4000>;
+        interrupts = <82>;
+        clocks = <&clks IMX5_CLK_CAN1_IPG_GATE>, <&clks IMX5_CLK_CAN1_SERIAL_GATE>;
+        clock-names = "ipg", "per";
+    };
-- 
2.7.4


^ permalink raw reply related

* [PATCH 0/3] STM32 update uart4 pin configuration for low power
From: Erwan Le Ray @ 2020-05-28  7:38 UTC (permalink / raw)
  To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland
  Cc: linux-stm32, linux-arm-kernel, devicetree, linux-kernel,
	Erwan Le Ray, Fabrice Gasnier

Update uart4 pin configuration for low power in pinctrl, and for ed/ev
and dkx boards.

Erwan Le Ray (3):
  ARM: dts: stm32: update uart4 pin configuration for low power on
    stm32mp157
  ARM: dts: stm32: Update pin states for uart4 on stm32mp157c-ed1
  ARM: dts: stm32: Update UART4 pin states on stm32mp15xx-dkx

 arch/arm/boot/dts/stm32mp15-pinctrl.dtsi | 17 +++++++++++++++++
 arch/arm/boot/dts/stm32mp157c-ed1.dts    |  4 +++-
 arch/arm/boot/dts/stm32mp15xx-dkx.dtsi   |  4 +++-
 3 files changed, 23 insertions(+), 2 deletions(-)

-- 
2.17.1


^ permalink raw reply

* [PATCH 1/3] ARM: dts: stm32: update uart4 pin configuration for low power on stm32mp157
From: Erwan Le Ray @ 2020-05-28  7:38 UTC (permalink / raw)
  To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland
  Cc: linux-stm32, linux-arm-kernel, devicetree, linux-kernel,
	Erwan Le Ray, Fabrice Gasnier, Bich Hemon
In-Reply-To: <20200528073853.24759-1-erwan.leray@st.com>

Sleep pin configuration is refined for low power modes:
- "sleep" (no wakeup & console suspend enabled): put pins in analog state
  to optimize power
- "idle" (wakeup capability): keep Rx pin in alternate function

Signed-off-by: Bich Hemon <bich.hemon@st.com>
Signed-off-by: Erwan Le Ray <erwan.leray@st.com>

diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
index 7eb858732d6d..7cf535dc05f5 100644
--- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
@@ -1648,6 +1648,23 @@
 		};
 	};
 
+	uart4_idle_pins_a: uart4-idle-0 {
+		   pins1 {
+			 pinmux = <STM32_PINMUX('G', 11, ANALOG)>; /* UART4_TX */
+		   };
+		   pins2 {
+			 pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
+			 bias-disable;
+		   };
+	};
+
+	uart4_sleep_pins_a: uart4-sleep-0 {
+		   pins {
+			pinmux = <STM32_PINMUX('G', 11, ANALOG)>, /* UART4_TX */
+				 <STM32_PINMUX('B', 2, ANALOG)>; /* UART4_RX */
+		    };
+	};
+
 	uart4_pins_b: uart4-1 {
 		pins1 {
 			pinmux = <STM32_PINMUX('D', 1, AF8)>; /* UART4_TX */
-- 
2.17.1


^ permalink raw reply related

* [PATCH 2/3] ARM: dts: stm32: Update pin states for uart4 on stm32mp157c-ed1
From: Erwan Le Ray @ 2020-05-28  7:38 UTC (permalink / raw)
  To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland
  Cc: linux-stm32, linux-arm-kernel, devicetree, linux-kernel,
	Erwan Le Ray, Fabrice Gasnier
In-Reply-To: <20200528073853.24759-1-erwan.leray@st.com>

Add sleep and idle states to uart4 pin configuration.

Signed-off-by: Erwan Le Ray <erwan.leray@st.com>

diff --git a/arch/arm/boot/dts/stm32mp157c-ed1.dts b/arch/arm/boot/dts/stm32mp157c-ed1.dts
index 32ccd50b4144..ca109dc18238 100644
--- a/arch/arm/boot/dts/stm32mp157c-ed1.dts
+++ b/arch/arm/boot/dts/stm32mp157c-ed1.dts
@@ -353,8 +353,10 @@
 };
 
 &uart4 {
-	pinctrl-names = "default";
+	pinctrl-names = "default", "sleep", "idle";
 	pinctrl-0 = <&uart4_pins_a>;
+	pinctrl-1 = <&uart4_sleep_pins_a>;
+	pinctrl-2 = <&uart4_idle_pins_a>;
 	status = "okay";
 };
 
-- 
2.17.1


^ permalink raw reply related

* [PATCH 3/3] ARM: dts: stm32: Update UART4 pin states on stm32mp15xx-dkx
From: Erwan Le Ray @ 2020-05-28  7:38 UTC (permalink / raw)
  To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland
  Cc: linux-stm32, linux-arm-kernel, devicetree, linux-kernel,
	Erwan Le Ray, Fabrice Gasnier
In-Reply-To: <20200528073853.24759-1-erwan.leray@st.com>

Add sleep and idle states to uart4 pin configuration.

Signed-off-by: Erwan Le Ray <erwan.leray@st.com>

diff --git a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
index 70db923a45f7..e5fdbc149bf4 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
@@ -584,8 +584,10 @@
 };
 
 &uart4 {
-	pinctrl-names = "default";
+	pinctrl-names = "default", "sleep", "idle";
 	pinctrl-0 = <&uart4_pins_a>;
+	pinctrl-1 = <&uart4_sleep_pins_a>;
+	pinctrl-2 = <&uart4_idle_pins_a>;
 	status = "okay";
 };
 
-- 
2.17.1


^ permalink raw reply related

* [PATCH 0/2] STM32 Fix uart nodes in stm32mp15-pinctrl
From: Erwan Le Ray @ 2020-05-28  7:40 UTC (permalink / raw)
  To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland
  Cc: linux-stm32, linux-arm-kernel, devicetree, linux-kernel,
	Erwan Le Ray, Fabrice Gasnier

Fix uart nodes ordering and uart7_pins_a comments in stm32mp15-pinctrl.

Erwan Le Ray (2):
  ARM: dts: stm32: fix uart nodes ordering in stm32mp15-pinctrl
  ARM: dts: stm32: fix uart7_pins_a comments in stm32mp15-pinctrl

 arch/arm/boot/dts/stm32mp15-pinctrl.dtsi | 130 +++++++++++------------
 1 file changed, 65 insertions(+), 65 deletions(-)

-- 
2.17.1


^ permalink raw reply

* [PATCH 1/2] ARM: dts: stm32: fix uart nodes ordering in stm32mp15-pinctrl
From: Erwan Le Ray @ 2020-05-28  7:40 UTC (permalink / raw)
  To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland
  Cc: linux-stm32, linux-arm-kernel, devicetree, linux-kernel,
	Erwan Le Ray, Fabrice Gasnier
In-Reply-To: <20200528074003.24875-1-erwan.leray@st.com>

Fix usart and uart nodes ordering. Several usart nodes didn't respect
expecting ordering.

Fixes: 077e0638fc83 ("ARM: dts: stm32: Add alternate pinmux for USART2 pins on stm32mp15")

Signed-off-by: Erwan Le Ray <erwan.leray@st.com>

diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
index 7cf535dc05f5..5ff1323236e1 100644
--- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
@@ -1574,67 +1574,6 @@
 		};
 	};
 
-	usart2_pins_a: usart2-0 {
-		pins1 {
-			pinmux = <STM32_PINMUX('F', 5, AF7)>, /* USART2_TX */
-				 <STM32_PINMUX('D', 4, AF7)>; /* USART2_RTS */
-			bias-disable;
-			drive-push-pull;
-			slew-rate = <0>;
-		};
-		pins2 {
-			pinmux = <STM32_PINMUX('D', 6, AF7)>, /* USART2_RX */
-				 <STM32_PINMUX('D', 3, AF7)>; /* USART2_CTS_NSS */
-			bias-disable;
-		};
-	};
-
-	usart2_sleep_pins_a: usart2-sleep-0 {
-		pins {
-			pinmux = <STM32_PINMUX('F', 5, ANALOG)>, /* USART2_TX */
-				 <STM32_PINMUX('D', 4, ANALOG)>, /* USART2_RTS */
-				 <STM32_PINMUX('D', 6, ANALOG)>, /* USART2_RX */
-				 <STM32_PINMUX('D', 3, ANALOG)>; /* USART2_CTS_NSS */
-		};
-	};
-
-	usart2_pins_b: usart2-1 {
-		pins1 {
-			pinmux = <STM32_PINMUX('F', 5, AF7)>, /* USART2_TX */
-				 <STM32_PINMUX('A', 1, AF7)>; /* USART2_RTS */
-			bias-disable;
-			drive-push-pull;
-			slew-rate = <0>;
-		};
-		pins2 {
-			pinmux = <STM32_PINMUX('F', 4, AF7)>, /* USART2_RX */
-				 <STM32_PINMUX('E', 15, AF7)>; /* USART2_CTS_NSS */
-			bias-disable;
-		};
-	};
-
-	usart2_sleep_pins_b: usart2-sleep-1 {
-		pins {
-			pinmux = <STM32_PINMUX('F', 5, ANALOG)>, /* USART2_TX */
-				 <STM32_PINMUX('A', 1, ANALOG)>, /* USART2_RTS */
-				 <STM32_PINMUX('F', 4, ANALOG)>, /* USART2_RX */
-				 <STM32_PINMUX('E', 15, ANALOG)>; /* USART2_CTS_NSS */
-		};
-	};
-
-	usart3_pins_a: usart3-0 {
-		pins1 {
-			pinmux = <STM32_PINMUX('B', 10, AF7)>; /* USART3_TX */
-			bias-disable;
-			drive-push-pull;
-			slew-rate = <0>;
-		};
-		pins2 {
-			pinmux = <STM32_PINMUX('B', 12, AF8)>; /* USART3_RX */
-			bias-disable;
-		};
-	};
-
 	uart4_pins_a: uart4-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
@@ -1732,6 +1671,67 @@
 		};
 	};
 
+	usart2_pins_a: usart2-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('F', 5, AF7)>, /* USART2_TX */
+				 <STM32_PINMUX('D', 4, AF7)>; /* USART2_RTS */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('D', 6, AF7)>, /* USART2_RX */
+				 <STM32_PINMUX('D', 3, AF7)>; /* USART2_CTS_NSS */
+			bias-disable;
+		};
+	};
+
+	usart2_sleep_pins_a: usart2-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('F', 5, ANALOG)>, /* USART2_TX */
+				 <STM32_PINMUX('D', 4, ANALOG)>, /* USART2_RTS */
+				 <STM32_PINMUX('D', 6, ANALOG)>, /* USART2_RX */
+				 <STM32_PINMUX('D', 3, ANALOG)>; /* USART2_CTS_NSS */
+		};
+	};
+
+	usart2_pins_b: usart2-1 {
+		pins1 {
+			pinmux = <STM32_PINMUX('F', 5, AF7)>, /* USART2_TX */
+				 <STM32_PINMUX('A', 1, AF7)>; /* USART2_RTS */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('F', 4, AF7)>, /* USART2_RX */
+				 <STM32_PINMUX('E', 15, AF7)>; /* USART2_CTS_NSS */
+			bias-disable;
+		};
+	};
+
+	usart2_sleep_pins_b: usart2-sleep-1 {
+		pins {
+			pinmux = <STM32_PINMUX('F', 5, ANALOG)>, /* USART2_TX */
+				 <STM32_PINMUX('A', 1, ANALOG)>, /* USART2_RTS */
+				 <STM32_PINMUX('F', 4, ANALOG)>, /* USART2_RX */
+				 <STM32_PINMUX('E', 15, ANALOG)>; /* USART2_CTS_NSS */
+		};
+	};
+
+	usart3_pins_a: usart3-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('B', 10, AF7)>; /* USART3_TX */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('B', 12, AF8)>; /* USART3_RX */
+			bias-disable;
+		};
+	};
+
 	usbotg_hs_pins_a: usbotg-hs-0 {
 		pins {
 			pinmux = <STM32_PINMUX('A', 10, ANALOG)>; /* OTG_ID */
-- 
2.17.1


^ permalink raw reply related

* [PATCH 2/2] ARM: dts: stm32: fix uart7_pins_a comments in stm32mp15-pinctrl
From: Erwan Le Ray @ 2020-05-28  7:40 UTC (permalink / raw)
  To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland
  Cc: linux-stm32, linux-arm-kernel, devicetree, linux-kernel,
	Erwan Le Ray, Fabrice Gasnier
In-Reply-To: <20200528074003.24875-1-erwan.leray@st.com>

Fix uart7_pins_a comments to indicate UART7 pins instead of UART4 pins.

Fixes: bf4b5f379fed ("ARM: dts: stm32: Add missing pinctrl definitions for STM32MP157")

Signed-off-by: Erwan Le Ray <erwan.leray@st.com>

diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
index 5ff1323236e1..fb98a66977fe 100644
--- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
@@ -1632,15 +1632,15 @@
 
 	uart7_pins_a: uart7-0 {
 		pins1 {
-			pinmux = <STM32_PINMUX('E', 8, AF7)>; /* UART4_TX */
+			pinmux = <STM32_PINMUX('E', 8, AF7)>; /* UART7_TX */
 			bias-disable;
 			drive-push-pull;
 			slew-rate = <0>;
 		};
 		pins2 {
-			pinmux = <STM32_PINMUX('E', 7, AF7)>, /* UART4_RX */
-				 <STM32_PINMUX('E', 10, AF7)>, /* UART4_CTS */
-				 <STM32_PINMUX('E', 9, AF7)>; /* UART4_RTS */
+			pinmux = <STM32_PINMUX('E', 7, AF7)>, /* UART7_RX */
+				 <STM32_PINMUX('E', 10, AF7)>, /* UART7_CTS */
+				 <STM32_PINMUX('E', 9, AF7)>; /* UART7_RTS */
 			bias-disable;
 		};
 	};
-- 
2.17.1


^ permalink raw reply related

* [PATCH 0/5] STM32 add usart nodes support
From: Erwan Le Ray @ 2020-05-28  7:40 UTC (permalink / raw)
  To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland
  Cc: linux-stm32, linux-arm-kernel, devicetree, linux-kernel,
	Erwan Le Ray, Fabrice Gasnier

Add the support of uart instances available on STM32MP157 boards:
- usart3 on stm32mp157c-ev1, stm32mp157a-dk1, and stm32mp157c-dk2
- uart7 on stm32mp157a-dk1 and stm32mp157c-dk2
- usart2 on stm32mp157c-dk2

The aliases are following this order.

Erwan Le Ray (5):
  ARM: dts: stm32: add usart2, usart3 and uart7 pins in
    stm32mp15-pinctrl
  ARM: dts: stm32: add usart3 node to stm32mp15xx-dkx boards
  ARM: dts: stm32: add usart3 node to stm32mp157c-ev1
  ARM: dts: stm32: add uart7 support to stm32mp15xx-dkx boards
  ARM: dts: stm32: add usart2 node to stm32mp157c-dk2

 arch/arm/boot/dts/stm32mp15-pinctrl.dtsi | 138 +++++++++++++++++++++++
 arch/arm/boot/dts/stm32mp157a-dk1.dts    |   2 +
 arch/arm/boot/dts/stm32mp157c-dk2.dts    |  11 ++
 arch/arm/boot/dts/stm32mp157c-ev1.dts    |  10 ++
 arch/arm/boot/dts/stm32mp15xx-dkx.dtsi   |  17 +++
 5 files changed, 178 insertions(+)

-- 
2.17.1


^ permalink raw reply

* [PATCH 3/5] ARM: dts: stm32: add usart3 node to stm32mp157c-ev1
From: Erwan Le Ray @ 2020-05-28  7:40 UTC (permalink / raw)
  To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland
  Cc: linux-stm32, linux-arm-kernel, devicetree, linux-kernel,
	Erwan Le Ray, Fabrice Gasnier
In-Reply-To: <20200528074029.24962-1-erwan.leray@st.com>

Adds the usart3 node to stm32mp157c-ev1 board. usart3 pins are connected to
GPIO Expansion connector. usart3 is disabled by default.

Signed-off-by: Erwan Le Ray <erwan.leray@st.com>

diff --git a/arch/arm/boot/dts/stm32mp157c-ev1.dts b/arch/arm/boot/dts/stm32mp157c-ev1.dts
index b19056557ef0..e56dde8d20f8 100644
--- a/arch/arm/boot/dts/stm32mp157c-ev1.dts
+++ b/arch/arm/boot/dts/stm32mp157c-ev1.dts
@@ -19,6 +19,7 @@
 
 	aliases {
 		serial0 = &uart4;
+		serial1 = &usart3;
 		ethernet0 = &ethernet0;
 	};
 
@@ -341,6 +342,15 @@
 	};
 };
 
+&usart3 {
+	pinctrl-names = "default", "sleep", "idle";
+	pinctrl-0 = <&usart3_pins_b>;
+	pinctrl-1 = <&usart3_sleep_pins_b>;
+	pinctrl-2 = <&usart3_idle_pins_b>;
+	uart-has-rtscts;
+	status = "disabled";
+};
+
 &usbh_ehci {
 	phys = <&usbphyc_port0>;
 	status = "okay";
-- 
2.17.1


^ permalink raw reply related

* [PATCH 5/5] ARM: dts: stm32: add usart2 node to stm32mp157c-dk2
From: Erwan Le Ray @ 2020-05-28  7:40 UTC (permalink / raw)
  To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland
  Cc: linux-stm32, linux-arm-kernel, devicetree, linux-kernel,
	Erwan Le Ray, Fabrice Gasnier
In-Reply-To: <20200528074029.24962-1-erwan.leray@st.com>

Adds the usart2 node to stm32mp157c-dk2 board. usart2 pins are connected
to Bluetooth component. usart2 is disabled by default.

Signed-off-by: Erwan Le Ray <erwan.leray@st.com>

diff --git a/arch/arm/boot/dts/stm32mp157c-dk2.dts b/arch/arm/boot/dts/stm32mp157c-dk2.dts
index ffbae4a8753d..045636555ddd 100644
--- a/arch/arm/boot/dts/stm32mp157c-dk2.dts
+++ b/arch/arm/boot/dts/stm32mp157c-dk2.dts
@@ -21,6 +21,7 @@
 		serial0 = &uart4;
 		serial1 = &usart3;
 		serial2 = &uart7;
+		serial3 = &usart2;
 	};
 
 	chosen {
@@ -86,3 +87,11 @@
 		};
 	};
 };
+
+&usart2 {
+	pinctrl-names = "default", "sleep", "idle";
+	pinctrl-0 = <&usart2_pins_c>;
+	pinctrl-1 = <&usart2_sleep_pins_c>;
+	pinctrl-2 = <&usart2_idle_pins_c>;
+	status = "disabled";
+};
-- 
2.17.1


^ permalink raw reply related

* [PATCH 1/5] ARM: dts: stm32: add usart2, usart3 and uart7 pins in stm32mp15-pinctrl
From: Erwan Le Ray @ 2020-05-28  7:40 UTC (permalink / raw)
  To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland
  Cc: linux-stm32, linux-arm-kernel, devicetree, linux-kernel,
	Erwan Le Ray, Fabrice Gasnier
In-Reply-To: <20200528074029.24962-1-erwan.leray@st.com>

Adds usart2_pins_c, usart3_pins_b, usart3_pins_c and uart7_pins_c pins
configurations in stm32mp15-pinctrl.
- usart2_pins_c pins are connected to Bluetooth chip on dk2 board.
- usart3_pins_b pins are connected to GPIO expansion connector on evx board.
- usart3_pins_c pins are connected to GPIO expansion connector on dkx board.
- uart7_pins_c pins are connected to Arduino Uno connector on dkx board.

Signed-off-by: Erwan Le Ray <erwan.leray@st.com>

diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
index fb98a66977fe..99e399e4e4c3 100644
--- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
@@ -1658,6 +1658,36 @@
 		};
 	};
 
+	uart7_pins_c: uart7-1 {
+		pins1 {
+			pinmux = <STM32_PINMUX('E', 8, AF7)>; /* USART7_TX */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('E', 7, AF7)>; /* USART7_RX */
+			bias-disable;
+		};
+	};
+
+	uart7_idle_pins_c: uart7-idle-1 {
+		pins1 {
+			pinmux = <STM32_PINMUX('E', 8, ANALOG)>; /* USART7_TX */
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('E', 7, AF7)>; /* USART7_RX */
+			bias-disable;
+		};
+	};
+
+	uart7_sleep_pins_c: uart7-sleep-1 {
+		pins {
+			pinmux = <STM32_PINMUX('E', 8, ANALOG)>, /* USART7_TX */
+				 <STM32_PINMUX('E', 7, ANALOG)>; /* USART7_RX */
+		};
+	};
+
 	uart8_pins_a: uart8-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('E', 1, AF8)>; /* UART8_TX */
@@ -1719,6 +1749,42 @@
 		};
 	};
 
+	usart2_pins_c: usart2-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('D', 5, AF7)>, /* USART2_TX */
+				 <STM32_PINMUX('D', 4, AF7)>; /* USART2_RTS */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <3>;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('D', 6, AF7)>, /* USART2_RX */
+				 <STM32_PINMUX('D', 3, AF7)>; /* USART2_CTS_NSS */
+			bias-disable;
+		};
+	};
+
+	usart2_idle_pins_c: usart2-idle-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('D', 5, ANALOG)>, /* USART2_TX */
+				 <STM32_PINMUX('D', 4, ANALOG)>, /* USART2_RTS */
+				 <STM32_PINMUX('D', 3, ANALOG)>; /* USART2_CTS_NSS */
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('D', 6, AF7)>; /* USART2_RX */
+			bias-disable;
+		};
+	};
+
+	usart2_sleep_pins_c: usart2-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('D', 5, ANALOG)>, /* USART2_TX */
+				 <STM32_PINMUX('D', 4, ANALOG)>, /* USART2_RTS */
+				 <STM32_PINMUX('D', 6, ANALOG)>, /* USART2_RX */
+				 <STM32_PINMUX('D', 3, ANALOG)>; /* USART2_CTS_NSS */
+		};
+	};
+
 	usart3_pins_a: usart3-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('B', 10, AF7)>; /* USART3_TX */
@@ -1732,6 +1798,78 @@
 		};
 	};
 
+	usart3_pins_b: usart3-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
+				 <STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('B', 12, AF8)>, /* USART3_RX */
+				 <STM32_PINMUX('I', 10, AF8)>; /* USART3_CTS_NSS */
+			bias-disable;
+		};
+	};
+
+	usart3_idle_pins_b: usart3-idle-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
+				 <STM32_PINMUX('G', 8, ANALOG)>, /* USART3_RTS */
+				 <STM32_PINMUX('I', 10, ANALOG)>; /* USART3_CTS_NSS */
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('B', 12, AF8)>; /* USART3_RX */
+			bias-disable;
+		};
+	};
+
+	usart3_sleep_pins_b: usart3-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
+				 <STM32_PINMUX('G', 8, ANALOG)>, /* USART3_RTS */
+				 <STM32_PINMUX('I', 10, ANALOG)>, /* USART3_CTS_NSS */
+				 <STM32_PINMUX('B', 12, ANALOG)>; /* USART3_RX */
+		};
+	};
+
+	usart3_pins_c: usart3-1 {
+		pins1 {
+			pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
+				 <STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <0>;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('B', 12, AF8)>, /* USART3_RX */
+				 <STM32_PINMUX('B', 13, AF7)>; /* USART3_CTS_NSS */
+			bias-disable;
+		};
+	};
+
+	usart3_idle_pins_c: usart3-idle-1 {
+		pins1 {
+			pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
+				 <STM32_PINMUX('G', 8, ANALOG)>, /* USART3_RTS */
+				 <STM32_PINMUX('B', 13, ANALOG)>; /* USART3_CTS_NSS */
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('B', 12, AF8)>; /* USART3_RX */
+			bias-disable;
+		};
+	};
+
+	usart3_sleep_pins_c: usart3-sleep-1 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 10, ANALOG)>, /* USART3_TX */
+				 <STM32_PINMUX('G', 8, ANALOG)>, /* USART3_RTS */
+				 <STM32_PINMUX('B', 13, ANALOG)>, /* USART3_CTS_NSS */
+				 <STM32_PINMUX('B', 12, ANALOG)>; /* USART3_RX */
+		};
+	};
+
 	usbotg_hs_pins_a: usbotg-hs-0 {
 		pins {
 			pinmux = <STM32_PINMUX('A', 10, ANALOG)>; /* OTG_ID */
-- 
2.17.1


^ permalink raw reply related

* [PATCH 4/5] ARM: dts: stm32: add uart7 support to stm32mp15xx-dkx boards
From: Erwan Le Ray @ 2020-05-28  7:40 UTC (permalink / raw)
  To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland
  Cc: linux-stm32, linux-arm-kernel, devicetree, linux-kernel,
	Erwan Le Ray, Fabrice Gasnier
In-Reply-To: <20200528074029.24962-1-erwan.leray@st.com>

Adds uart7 node to stm32mp15xx-dkx and uart7 alias to stm32mp157a-dk1 and
stm32mp157c-dk2 boards. uart7 pins are connected to Arduino connector.
uart7 is disabled by default.

Signed-off-by: Erwan Le Ray <erwan.leray@st.com>

diff --git a/arch/arm/boot/dts/stm32mp157a-dk1.dts b/arch/arm/boot/dts/stm32mp157a-dk1.dts
index 65ee61b7667a..4c8be9c8eb20 100644
--- a/arch/arm/boot/dts/stm32mp157a-dk1.dts
+++ b/arch/arm/boot/dts/stm32mp157a-dk1.dts
@@ -19,6 +19,7 @@
 		ethernet0 = &ethernet0;
 		serial0 = &uart4;
 		serial1 = &usart3;
+		serial2 = &uart7;
 	};
 
 	chosen {
diff --git a/arch/arm/boot/dts/stm32mp157c-dk2.dts b/arch/arm/boot/dts/stm32mp157c-dk2.dts
index fb690a817e28..ffbae4a8753d 100644
--- a/arch/arm/boot/dts/stm32mp157c-dk2.dts
+++ b/arch/arm/boot/dts/stm32mp157c-dk2.dts
@@ -20,6 +20,7 @@
 		ethernet0 = &ethernet0;
 		serial0 = &uart4;
 		serial1 = &usart3;
+		serial2 = &uart7;
 	};
 
 	chosen {
diff --git a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
index 243aa4b2063d..cfbe3e2afef2 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
@@ -591,6 +591,14 @@
 	status = "okay";
 };
 
+&uart7 {
+	pinctrl-names = "default", "sleep", "idle";
+	pinctrl-0 = <&uart7_pins_c>;
+	pinctrl-1 = <&uart7_sleep_pins_c>;
+	pinctrl-2 = <&uart7_idle_pins_c>;
+	status = "disabled";
+};
+
 &usart3 {
 	pinctrl-names = "default", "sleep", "idle";
 	pinctrl-0 = <&usart3_pins_c>;
-- 
2.17.1


^ permalink raw reply related

* [PATCH 2/5] ARM: dts: stm32: add usart3 node to stm32mp15xx-dkx boards
From: Erwan Le Ray @ 2020-05-28  7:40 UTC (permalink / raw)
  To: Maxime Coquelin, Alexandre Torgue, Rob Herring, Mark Rutland
  Cc: linux-stm32, linux-arm-kernel, devicetree, linux-kernel,
	Erwan Le Ray, Fabrice Gasnier
In-Reply-To: <20200528074029.24962-1-erwan.leray@st.com>

Adds usart3 node to stm32mp15xx-dkx and usart3 alias to stm32mp157a-dk1
and stm32mp157c-dk2 boards. usart3 pins are connected to GPIO Expansion
connector. usart3 is disabled by default.

Signed-off-by: Erwan Le Ray <erwan.leray@st.com>

diff --git a/arch/arm/boot/dts/stm32mp157a-dk1.dts b/arch/arm/boot/dts/stm32mp157a-dk1.dts
index d03d4cd2606a..65ee61b7667a 100644
--- a/arch/arm/boot/dts/stm32mp157a-dk1.dts
+++ b/arch/arm/boot/dts/stm32mp157a-dk1.dts
@@ -18,6 +18,7 @@
 	aliases {
 		ethernet0 = &ethernet0;
 		serial0 = &uart4;
+		serial1 = &usart3;
 	};
 
 	chosen {
diff --git a/arch/arm/boot/dts/stm32mp157c-dk2.dts b/arch/arm/boot/dts/stm32mp157c-dk2.dts
index 9a8a26710ac1..fb690a817e28 100644
--- a/arch/arm/boot/dts/stm32mp157c-dk2.dts
+++ b/arch/arm/boot/dts/stm32mp157c-dk2.dts
@@ -19,6 +19,7 @@
 	aliases {
 		ethernet0 = &ethernet0;
 		serial0 = &uart4;
+		serial1 = &usart3;
 	};
 
 	chosen {
diff --git a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
index e5fdbc149bf4..243aa4b2063d 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
@@ -591,6 +591,15 @@
 	status = "okay";
 };
 
+&usart3 {
+	pinctrl-names = "default", "sleep", "idle";
+	pinctrl-0 = <&usart3_pins_c>;
+	pinctrl-1 = <&usart3_sleep_pins_c>;
+	pinctrl-2 = <&usart3_idle_pins_c>;
+	uart-has-rtscts;
+	status = "disabled";
+};
+
 &usbh_ehci {
 	phys = <&usbphyc_port0>;
 	status = "okay";
-- 
2.17.1


^ permalink raw reply related

* Re: [PATCH 09/12] devfreq: add mediatek cci devfreq
From: Chanwoo Choi @ 2020-05-28  8:00 UTC (permalink / raw)
  To: Andrew-sh.Cheng, MyungJoo Ham, Kyungmin Park, Rob Herring,
	Mark Rutland, Matthias Brugger, Rafael J . Wysocki, Viresh Kumar,
	Nishanth Menon, Stephen Boyd, Liam Girdwood, Mark Brown
  Cc: linux-pm, devicetree, linux-arm-kernel, linux-mediatek,
	linux-kernel, srv_heupstream
In-Reply-To: <c39e4f30-805a-78c4-b1c4-e55a03e2408e@samsung.com>

Hi Andrew-sh.Cheng,

On 5/28/20 4:35 PM, Chanwoo Choi wrote:
> Hi Andrew-sh.Cheng,
> 
> On 5/20/20 12:43 PM, Andrew-sh.Cheng wrote:
>> This adds a devfreq driver for the Cache Coherent Interconnect (CCI)
>> of the Mediatek MT8183.
>>
>> On the MT8183 the CCI is supplied by the same regulator as the LITTLE
>> cores. The driver is notified when the regulator voltage changes
>> (driven by cpufreq) and adjusts the CCI frequency to the maximum
>> possible value.

I understood that the mt8183-cci.c and mt8183 cpufreq driver (ARM_MEDIATEK_CPUFREQ)
shared the same regulator. So, when mt8183 cpufreq driver
changes the CPU frequency and voltage, the mt8183-cci.c
changes the CCI frequency according to the new mt8183 frequency
with passive governor. 

I think that mt8183-cci.c don't need to change the voltage
because already mt8183 cpufreq changed the voltage of shared regulator.
Why do you change the voltage in this driver?

>>
>> Signed-off-by: Andrew-sh.Cheng <andrew-sh.cheng@mediatek.com>
>> ---
>>  drivers/devfreq/Kconfig              |  10 ++
>>  drivers/devfreq/Makefile             |   1 +
>>  drivers/devfreq/mt8183-cci-devfreq.c | 206 +++++++++++++++++++++++++++++++++++
> 
> The mt8183-cci.c is enough for driver name.
> 
>>  3 files changed, 217 insertions(+)
>>  create mode 100644 drivers/devfreq/mt8183-cci-devfreq.c
>>
>> diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
>> index d9067950af6a..4ed7116271ee 100644
>> --- a/drivers/devfreq/Kconfig
>> +++ b/drivers/devfreq/Kconfig
>> @@ -103,6 +103,16 @@ config ARM_IMX8M_DDRC_DEVFREQ
>>  	  This adds the DEVFREQ driver for the i.MX8M DDR Controller. It allows
>>  	  adjusting DRAM frequency.
>>  
>> +config ARM_MT8183_CCI_DEVFREQ
>> +	tristate "MT8183 CCI DEVFREQ Driver"
>> +	depends on ARM_MEDIATEK_CPUFREQ
>> +	help
>> +		This adds a devfreq driver for Cache Coherent Interconnect
>> +		of Mediatek MT8183, which is shared the same regulator
>> +		with cpu cluster.
>> +		It can track buck voltage and update a proper cci frequency.
> 
> s/cci/CCI
> 
>> +		Use notification to get regulator status.
>> +
>>  config ARM_TEGRA_DEVFREQ
>>  	tristate "NVIDIA Tegra30/114/124/210 DEVFREQ Driver"
>>  	depends on ARCH_TEGRA_3x_SOC || ARCH_TEGRA_114_SOC || \
>> diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
>> index 3eb4d5e6635c..5b1b670c954d 100644
>> --- a/drivers/devfreq/Makefile
>> +++ b/drivers/devfreq/Makefile
>> @@ -10,6 +10,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE)	+= governor_passive.o
>>  # DEVFREQ Drivers
>>  obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)	+= exynos-bus.o
>>  obj-$(CONFIG_ARM_IMX8M_DDRC_DEVFREQ)	+= imx8m-ddrc.o
>> +obj-$(CONFIG_ARM_MT8183_CCI_DEVFREQ)	+= mt8183-cci-devfreq.o
>>  obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ)	+= rk3399_dmc.o
>>  obj-$(CONFIG_ARM_TEGRA_DEVFREQ)		+= tegra30-devfreq.o
>>  obj-$(CONFIG_ARM_TEGRA20_DEVFREQ)	+= tegra20-devfreq.o
>> diff --git a/drivers/devfreq/mt8183-cci-devfreq.c b/drivers/devfreq/mt8183-cci-devfreq.c
>> new file mode 100644
>> index 000000000000..cd7929a83bf8
>> --- /dev/null
>> +++ b/drivers/devfreq/mt8183-cci-devfreq.c
>> @@ -0,0 +1,206 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (c) 2019 MediaTek Inc.
> 
> s/2019/2020
> 
>> +
>> + * Author: Andrew-sh.Cheng <andrew-sh.cheng@mediatek.com>
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/devfreq.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regulator/consumer.h>
>> +#include <linux/time.h>
>> +
>> +#include "governor.h"
> 
> It is not needed. Please remove it.
> 
>> +
>> +#define MAX_VOLT_LIMIT		(1150000)
>> +
>> +struct cci_devfreq {
>> +	struct devfreq *devfreq;
>> +	struct regulator *proc_reg;
> 
> 'proc' means the 'processor'?
> Instead of 'proc_reg', you better to use 'cpu_reg'.
> 
>> +	struct clk *cci_clk;
>> +	int old_vproc;
>> +	unsigned long old_freq;
>> +};
>> +
>> +static int mtk_cci_set_voltage(struct cci_devfreq *cci_df, int vproc)
>> +{
>> +	int ret;
>> +
>> +	ret = regulator_set_voltage(cci_df->proc_reg, vproc,
>> +				    MAX_VOLT_LIMIT);
>> +	if (!ret)
>> +		cci_df->old_vproc = vproc;
>> +	return ret;
>> +}
>> +
>> +static int mtk_cci_devfreq_target(struct device *dev, unsigned long *freq,
>> +				  u32 flags)
>> +{
>> +	int ret;
>> +	struct cci_devfreq *cci_df = dev_get_drvdata(dev);
>> +	struct dev_pm_opp *opp;
>> +	unsigned long opp_rate, opp_voltage, old_voltage;
>> +
>> +	if (!cci_df)
>> +		return -EINVAL;
>> +
>> +	if (cci_df->old_freq == *freq)
>> +		return 0;
>> +
>> +	opp_rate = *freq;
>> +	opp = dev_pm_opp_find_freq_floor(dev, &opp_rate);
>> +	opp_voltage = dev_pm_opp_get_voltage(opp);
>> +	dev_pm_opp_put(opp);
> 
> 
> You can use the helper function for getting the rate 
> with devfreq_recommended_opp(). You can refer the following code
> in drivers/devfreq/exynos-bus.c
> 
> 	opp = devfreq_recommended_opp(dev, freq, flags);
> 	if (IS_ERR(opp)) {
> 		dev_err(dev, "failed to get recommended opp instance\n");
> 		return PTR_ERR(opp);
> 	}
> 	dev_pm_opp_put(opp);
> 
>> +
>> +	old_voltage = cci_df->old_vproc;
>> +	if (old_voltage == 0)
>> +		old_voltage = regulator_get_voltage(cci_df->proc_reg);
>> +
>> +	// scale up: set voltage first then freq
>> +	if (opp_voltage > old_voltage) {
>> +		ret = mtk_cci_set_voltage(cci_df, opp_voltage);
>> +		if (ret) {
>> +			pr_err("cci: failed to scale up voltage\n");
>> +			return ret;
>> +		}
>> +	}
>> +
>> +	ret = clk_set_rate(cci_df->cci_clk, *freq);
>> +	if (ret) {
>> +		pr_err("%s: failed cci to set rate: %d\n", __func__,
>> +		       ret);
>> +		mtk_cci_set_voltage(cci_df, old_voltage);
>> +		return ret;
>> +	}
>> +
>> +	// scale down: set freq first then voltage
>> +	if (opp_voltage < old_voltage) {
>> +		ret = mtk_cci_set_voltage(cci_df, opp_voltage);
>> +		if (ret) {
>> +			pr_err("cci: failed to scale down voltage\n");
>> +			clk_set_rate(cci_df->cci_clk, cci_df->old_freq);
>> +			return ret;
>> +		}
>> +	}
> 
> 
> I recommend that dev_pm_opp_set_rate() and dev_pm_opp_set_regulator()
> instead of 'clk_set_rate' and 'regulator_set_voltage'.
> In the dev_pm_opp_set_rate(), handle the these sequence.
> You can refer the merged patch[1].
> 
> [1] commit 4294a779bd8dff6c65e7e85ffe7a1ea236e92a68
> - PM / devfreq: exynos-bus: Convert to use dev_pm_opp_set_rate()
> 
> 
>> +
>> +	cci_df->old_freq = *freq;
>> +
>> +	return 0;
>> +}
>> +
>> +static struct devfreq_dev_profile cci_devfreq_profile = {
>> +	.target = mtk_cci_devfreq_target,
> 
> Need to add '.exit' for calling dev_pm_opp_of_remove_table().
> You can refer the merged devfreq patches like exynos_bus.c, imx-bus.c.
> 
>> +};
>> +
>> +static int mtk_cci_devfreq_probe(struct platform_device *pdev)
>> +{
>> +	struct device *cci_dev = &pdev->dev;
>> +	struct cci_devfreq *cci_df;
>> +	struct devfreq_passive_data *passive_data;
>> +	int ret;
>> +
>> +	cci_df = devm_kzalloc(cci_dev, sizeof(*cci_df), GFP_KERNEL);
>> +	if (!cci_df)
>> +		return -ENOMEM;
>> +
>> +	cci_df->cci_clk = devm_clk_get(cci_dev, "cci_clock");
>> +	ret = PTR_ERR_OR_ZERO(cci_df->cci_clk);
>> +	if (ret) {
>> +		if (ret != -EPROBE_DEFER)
>> +			dev_err(cci_dev, "failed to get clock for CCI: %d\n",
>> +				ret);
>> +		return ret;
>> +	}
>> +	cci_df->proc_reg = devm_regulator_get_optional(cci_dev, "proc");
>> +	ret = PTR_ERR_OR_ZERO(cci_df->proc_reg);
>> +	if (ret) {
>> +		if (ret != -EPROBE_DEFER)
>> +			dev_err(cci_dev, "failed to get regulator for CCI: %d\n",
>> +				ret);
>> +		return ret;
>> +	}
> 
> I recommend that use dev_pm_opp_set_regulators.
> You can refer the merged patch[1].
> 
> [1] commit 4294a779bd8dff6c65e7e85ffe7a1ea236e92a68
> - PM / devfreq: exynos-bus: Convert to use dev_pm_opp_set_rate()
> 
> 
>> +	ret = regulator_enable(cci_df->proc_reg);
>> +	if (ret) {
>> +		pr_warn("enable buck for cci fail\n");
> 
> Use dev_err instead of 'pr_warn'.
> 
>> +		return ret;
>> +	}
>> +
>> +	ret = dev_pm_opp_of_add_table(cci_dev);
>> +	if (ret) {
>> +		dev_err(cci_dev, "Fail to init CCI OPP table: %d\n", ret);
> 
> How about changing the error log as following
> because in this driver, use the 'failed to' sentence for error handling?
> 
> 	failed to get OPP table for CCI:L %d
> 
>> +		return ret;
>> +	}
>> +
>> +	platform_set_drvdata(pdev, cci_df);
>> +
>> +	passive_data = devm_kzalloc(cci_dev, sizeof(*passive_data), GFP_KERNEL);
>> +	if (!passive_data)
>> +		return -ENOMEM;
> 
> On this error case, you have to call dev_pm_opp_of_remove_table().
> You better to make the 'err_opp' jump lable and then add 'goto err_opp'.
> 
>> +
>> +	passive_data->parent_type = CPUFREQ_PARENT_DEV;
>> +
>> +	cci_df->devfreq = devm_devfreq_add_device(cci_dev,
>> +						  &cci_devfreq_profile,
>> +						  DEVFREQ_GOV_PASSIVE,
>> +						  passive_data);
>> +	if (IS_ERR(cci_df->devfreq)) {
>> +		ret = PTR_ERR(cci_df->devfreq);
>> +		dev_err(cci_dev, "cannot create cci devfreq device:%d\n", ret);
>> +		dev_pm_opp_of_remove_table(cci_dev);
> 
> Instead of direct call, use 'goto err_opp'.
> 
>> +		return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int mtk_cci_devfreq_remove(struct platform_device *pdev)
>> +{
>> +	struct device *cci_dev = &pdev->dev;
>> +	struct cci_devfreq *cci_df;
>> +	struct notifier_block *opp_nb;
>> +
>> +	cci_df = platform_get_drvdata(pdev);
>> +	opp_nb = &cci_df->opp_nb;
>> +
>> +	dev_pm_opp_unregister_notifier(cci_dev, opp_nb);
> 
> This patch doesn't call the dev_pm_opp_register_notifier.
> Please remove it.
> 
>> +	devm_devfreq_remove_device(cci_dev, cci_df->devfreq);
> 
> Don't need to call this function because you used devm_devfreq_add_device().
> 
>> +	dev_pm_opp_of_remove_table(cci_dev)> +	regulator_disable(cci_df->proc_reg);
>> +
>> +	return 0;
>> +}
>> +
>> +static const __maybe_unused struct of_device_id
>> +	mediatek_cci_devfreq_of_match[] = {
> 
> Make it on one line and remove '__maybe_unused' keyword.
> - mediatek_cci_devfreq_of_match-> mediatek_cci_of_match
> 
>> +	{ .compatible = "mediatek,mt8183-cci" },
>> +	{ },
>> +};
>> +MODULE_DEVICE_TABLE(of, mediatek_cci_devfreq_of_match);
> 
> ditto.
> 
>> +
>> +static struct platform_driver cci_devfreq_driver = {
>> +	.probe	= mtk_cci_devfreq_probe,
>> +	.remove	= mtk_cci_devfreq_remove,
>> +	.driver = {
>> +		.name = "mediatek-cci-devfreq",
>> +		.of_match_table = of_match_ptr(mediatek_cci_devfreq_of_match),
> 
> ditto.
> 
>> +	},
>> +};
>> +
>> +static int __init mtk_cci_devfreq_init(void)
>> +{
>> +	return platform_driver_register(&cci_devfreq_driver);
>> +}
>> +module_init(mtk_cci_devfreq_init)
>> +
>> +static void __exit mtk_cci_devfreq_exit(void)
>> +{
>> +	platform_driver_unregister(&cci_devfreq_driver);
>> +}
>> +module_exit(mtk_cci_devfreq_exit)
> 
> Use 'module_platform_driver' instead of module_init and module_exit.
> 
>> +
>> +MODULE_DESCRIPTION("Mediatek CCI devfreq driver");
>> +MODULE_AUTHOR("Andrew-sh.Cheng <andrew-sh.cheng@mediatek.com>");
>> +MODULE_LICENSE("GPL v2");
>>
> 
> 


-- 
Best Regards,
Chanwoo Choi
Samsung Electronics

^ permalink raw reply

* Re: [V9, 1/2] media: dt-bindings: media: i2c: Document OV02A10 bindings
From: Dongchun Zhu @ 2020-05-28  8:04 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Rob Herring, Linus Walleij, Bartosz Golaszewski,
	Mauro Carvalho Chehab, Andy Shevchenko, Mark Rutland,
	Nicolas Boichat, Tomasz Figa, Matthias Brugger, Cao Bing Bu,
	srv_heupstream, moderated list:ARM/Mediatek SoC support,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, Sj Huang,
	Linux Media Mailing List, devicetree, Louis Kuo,
	Shengnan Wang (王圣男)
In-Reply-To: <20200528072332.GW7618@paasikivi.fi.intel.com>

Hi Sakari,

On Thu, 2020-05-28 at 10:23 +0300, Sakari Ailus wrote:
> Hi Dongchun,
> 
> On Thu, May 28, 2020 at 11:34:42AM +0800, Dongchun Zhu wrote:
> > Hi Sakari, Rob,
> > 
> > On Thu, 2020-05-28 at 00:16 +0300, Sakari Ailus wrote:
> > > Hi Rob, Dongchun,
> > > 
> > > On Wed, May 27, 2020 at 09:27:22AM -0600, Rob Herring wrote:
> > > > > > > +    properties:
> > > > > > > +      endpoint:
> > > > > > > +        type: object
> > > > > > > +        additionalProperties: false
> > > > > > > +
> > > > > > > +        properties:
> > > > >
> > > > > Actually I wonder whether we need to declare 'clock-lanes' here?
> > > > 
> > > > Yes, if you are using it.
> > > 
> > > Dongchun, can you confirm the chip has a single data and a single clock
> > > lane and that it does not support lane reordering?
> > > 
> > 
> > From the datasheet, 'MIPI inside the OV02A10 provides one single
> > uni-directional clock lane and one bi-directional data lane solution for
> > communication links between components inside a mobile device.
> > The data lane has full support for HS(uni-directional) and
> > LP(bi-directional) data transfer mode.'
> > 
> > The sensor doesn't support lane reordering, so 'clock-lanes' property
> > would not be added in next release.
> > 
> > > So if there's nothing to convey to the driver, also the data-lanes should
> > > be removed IMO.
> > > 
> > 
> > However, 'data-lanes' property may still be required.
> > It is known that either data-lanes or clock-lanes is an array of
> > physical data lane indexes. Position of an entry determines the logical
> > lane number, while the value of an entry indicates physical lane, e.g.,
> > for 1-lane MIPI CSI-2 bus we could have "data-lanes = <1>;", assuming
> > the clock lane is on hardware lane 0.
> > 
> > As mentioned earlier, the OV02A10 sensor supports only 1C1D and does not
> > support lane reordering, so here we shall use 'data-lanes = <1>' as
> > there is only a clock lane for OV02A10.
> > 
> > Reminder:
> > If 'data-lanes' property is not present, the driver would assume
> > four-lane operation. This means for one-lane or two-lane operation, this
> > property must be present and set to the right physical lane indexes.
> > If the hardware does not support lane reordering, monotonically
> > incremented values shall be used from 0 or 1 onwards, depending on
> > whether or not there is also a clock lane.
> 
> How can the driver use four lanes, considering the device only supports a
> single lane??
> 

I understood your meaning.
If we omit the property 'data-lanes', the sensor should work still.
But then what's the meaning of the existence of 'data-lanes'?
If this property 'data-lanes' is always optional, then why dt-bindings
provide the interface?

In the meantime, if omitting 'data-lanes' for one sensor(transmitter)
that has only one physical data lane, MIPI receiver(e.g., MIPI CSI-2)
shall enable four-lane configuration, which may increase consumption of
both power and resource in the process of IIC communication.

^ permalink raw reply

* Re: [Patch 2/2] media: ti-vpe: Add the VIP driver
From: Hans Verkuil @ 2020-05-28  8:09 UTC (permalink / raw)
  To: Benoit Parrot
  Cc: Rob Herring, linux-media, devicetree, linux-kernel,
	Nikhil Devshatwar
In-Reply-To: <20200526215708.3vp4z4qjzpj66t36@ti.com>

On 26/05/2020 23:57, Benoit Parrot wrote:
> Hans,
> 
> Thanks for the review.
> 
> Hans Verkuil <hverkuil@xs4all.nl> wrote on Tue [2020-May-26 13:48:35 +0200]:
>> On 23/05/2020 00:54, Benoit Parrot wrote:
>>> VIP stands for Video Input Port, it can be found on devices such as
>>> DRA7xx and provides a parallel interface to a video source such as
>>> a sensor or TV decoder.  Each VIP can support two inputs (slices) and
>>> a SoC can be configured with a variable number of VIP's.
>>> Each slice can supports two ports each connected to its own
>>> sub-device.
>>>
>>> Signed-off-by: Benoit Parrot <bparrot@ti.com>
>>> Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
>>> ---
>>>  drivers/media/platform/Kconfig         |   13 +
>>>  drivers/media/platform/ti-vpe/Makefile |    2 +
>>>  drivers/media/platform/ti-vpe/vip.c    | 4158 ++++++++++++++++++++++++
>>>  drivers/media/platform/ti-vpe/vip.h    |  724 +++++
>>>  4 files changed, 4897 insertions(+)
>>>  create mode 100644 drivers/media/platform/ti-vpe/vip.c
>>>  create mode 100644 drivers/media/platform/ti-vpe/vip.h
>>>

<snip>

>>> +static int vip_enum_fmt_vid_cap(struct file *file, void *priv,
>>> +				struct v4l2_fmtdesc *f)
>>> +{
>>> +	struct vip_stream *stream = file2stream(file);
>>> +	struct vip_port *port = stream->port;
>>> +	struct vip_fmt *fmt;
>>> +
>>> +	vip_dbg(3, stream, "enum_fmt index:%d\n", f->index);
>>> +	if (f->index >= port->num_active_fmt)
>>> +		return -EINVAL;
>>> +
>>> +	fmt = port->active_fmt[f->index];
>>> +
>>> +	f->pixelformat = fmt->fourcc;
>>> +	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
>>
>> No need to set the type field.
> 
> Ok.
> 
>>
>>> +	vip_dbg(3, stream, "enum_fmt fourcc:%s\n",
>>> +		fourcc_to_str(f->pixelformat));
>>
>> Excessive debugging.
> 
> Why excessive?

Two debug messages for a simple function like this seems overkill.

Besides, the v4l2 core already has debugging support for ioctl calls:

https://linuxtv.org/downloads/v4l-dvb-apis-new/driver-api/v4l2-dev.html#video-device-debugging

> 
>>
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int vip_enum_framesizes(struct file *file, void *priv,
>>> +			       struct v4l2_frmsizeenum *f)
>>> +{
>>> +	struct vip_stream *stream = file2stream(file);
>>> +	struct vip_port *port = stream->port;
>>> +	struct vip_fmt *fmt;
>>> +	struct v4l2_subdev_frame_size_enum fse;
>>> +	int ret;
>>> +
>>> +	fmt = find_port_format_by_pix(port, f->pixel_format);
>>> +	if (!fmt)
>>> +		return -EINVAL;
>>> +
>>> +	fse.index = f->index;
>>> +	fse.pad = port->source_pad;
>>> +	fse.code = fmt->code;
>>> +	fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
>>> +	ret = v4l2_subdev_call(port->subdev, pad, enum_frame_size, NULL, &fse);
>>> +	if (ret == -ENOIOCTLCMD && !f->index) {
>>> +		/*
>>> +		 * if subdev does not support enum_frame_size
>>> +		 * then use get_fmt
>>
>> I don't think that's right. If the subdev doesn't support this, then
>> this ioctl should be disabled altogether. Typically this ioctl is only
>> valid for sensor subdevs, not for video receivers.
>>
>> Use v4l2_subdev_has_op() and v4l2_disable_ioctl().
> 
> You mean to check if the subdev support this ioctl and if not disable it
> for the current video device only, correct?

Correct.

There are several other drivers that do this, just grep for them.

>>> +static int vip_calc_format_size(struct vip_port *port,
>>> +				struct vip_fmt *fmt,
>>> +				struct v4l2_format *f)
>>> +{
>>> +	enum v4l2_field *field;
>>> +	unsigned int stride;
>>> +
>>> +	if (!fmt) {
>>> +		vip_dbg(2, port,
>>> +			"no vip_fmt format provided!\n");
>>> +		return -EINVAL;
>>> +	}
>>> +
>>> +	field = &f->fmt.pix.field;
>>> +	if (*field == V4L2_FIELD_ANY)
>>> +		*field = V4L2_FIELD_NONE;
>>> +	else if (V4L2_FIELD_NONE != *field && V4L2_FIELD_ALTERNATE != *field)
>>> +		return -EINVAL;
>>> +
>>> +	v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W, W_ALIGN,
>>> +			      &f->fmt.pix.height, MIN_H, MAX_H, H_ALIGN,
>>> +			      S_ALIGN);
>>> +
>>> +	stride = f->fmt.pix.width * (fmt->vpdma_fmt[0]->depth >> 3);
>>> +	if (stride > f->fmt.pix.bytesperline)
>>> +		f->fmt.pix.bytesperline = stride;
>>> +
>>> +	f->fmt.pix.bytesperline = clamp_t(u32, f->fmt.pix.bytesperline,
>>> +					  stride, VPDMA_MAX_STRIDE);
>>> +	f->fmt.pix.bytesperline = ALIGN(f->fmt.pix.bytesperline,
>>> +					VPDMA_STRIDE_ALIGN);
>>> +
>>> +	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
>>> +	if (fmt->coplanar) {
>>> +		f->fmt.pix.sizeimage += f->fmt.pix.height *
>>> +					f->fmt.pix.bytesperline *
>>> +					fmt->vpdma_fmt[VIP_CHROMA]->depth >> 3;
>>> +	}
>>> +
>>> +	f->fmt.pix.colorspace = fmt->colorspace;
>>> +	f->fmt.pix.priv = 0;
>>
>> No need to set this.
> 
> You mean pix.priv? I thought I remember v4l2-compliance complaining about
> something like this?

Yes, pix.priv. It used to complain a long time ago, but the v4l2 core should
handle this. Basically drivers shouldn't touch pix.priv.

> 
>>
>>> +
>>> +	vip_dbg(3, port, "calc_format_size: fourcc:%s size: %dx%d bpl:%d img_size:%d\n",
>>> +		fourcc_to_str(f->fmt.pix.pixelformat),
>>> +		f->fmt.pix.width, f->fmt.pix.height,
>>> +		f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static inline bool vip_is_size_dma_aligned(u32 bpp, u32 width)
>>> +{
>>> +	return ((width * bpp) == ALIGN(width * bpp, VPDMA_STRIDE_ALIGN));
>>> +}
>>> +
>>> +static int vip_try_fmt_vid_cap(struct file *file, void *priv,
>>> +			       struct v4l2_format *f)
>>> +{
>>> +	struct vip_stream *stream = file2stream(file);
>>> +	struct vip_port *port = stream->port;
>>> +	struct v4l2_subdev_frame_size_enum fse;
>>> +	struct vip_fmt *fmt;
>>> +	u32 best_width, best_height, largest_width, largest_height;
>>> +	int ret, found;
>>> +	enum vip_csc_state csc_direction;
>>> +
>>> +	vip_dbg(3, stream, "try_fmt fourcc:%s size: %dx%d\n",
>>> +		fourcc_to_str(f->fmt.pix.pixelformat),
>>> +		f->fmt.pix.width, f->fmt.pix.height);
>>> +
>>> +	fmt = find_port_format_by_pix(port, f->fmt.pix.pixelformat);
>>> +	if (!fmt) {
>>> +		vip_dbg(2, stream,
>>> +			"Fourcc format (0x%08x) not found.\n",
>>> +			f->fmt.pix.pixelformat);
>>> +
>>> +		/* Just get the first one enumerated */
>>> +		fmt = port->active_fmt[0];
>>> +		f->fmt.pix.pixelformat = fmt->fourcc;
>>> +	}
>>> +
>>> +	csc_direction =  vip_csc_direction(fmt->code, fmt->finfo);
>>> +	if (csc_direction != VIP_CSC_NA) {
>>> +		if (!is_csc_available(port)) {
>>> +			vip_dbg(2, stream,
>>> +				"CSC not available for Fourcc format (0x%08x).\n",
>>> +				f->fmt.pix.pixelformat);
>>> +
>>> +			/* Just get the first one enumerated */
>>> +			fmt = port->active_fmt[0];
>>> +			f->fmt.pix.pixelformat = fmt->fourcc;
>>> +			/* re-evaluate the csc_direction here */
>>> +			csc_direction =  vip_csc_direction(fmt->code,
>>> +							   fmt->finfo);
>>> +		} else {
>>> +			vip_dbg(3, stream, "CSC active on Port %c: going %s\n",
>>> +				port->port_id == VIP_PORTA ? 'A' : 'B',
>>> +				(csc_direction == VIP_CSC_Y2R) ? "Y2R" : "R2Y");
>>> +		}
>>> +	}
>>> +
>>> +	/*
>>> +	 * Given that sensors might support multiple mbus code we need
>>> +	 * to use the one that matches the requested pixel format
>>> +	 */
>>> +	port->try_mbus_framefmt = port->mbus_framefmt;
>>> +	port->try_mbus_framefmt.code = fmt->code;
>>> +
>>> +	/* check for/find a valid width/height */
>>> +	ret = 0;
>>> +	found = false;
>>> +	best_width = 0;
>>> +	best_height = 0;
>>> +	largest_width = 0;
>>> +	largest_height = 0;
>>> +	fse.pad = port->source_pad;
>>> +	fse.code = fmt->code;
>>> +	fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
>>> +	for (fse.index = 0; ; fse.index++) {
>>> +		u32 bpp = fmt->vpdma_fmt[0]->depth >> 3;
>>> +
>>> +		ret = v4l2_subdev_call(port->subdev, pad,
>>> +				       enum_frame_size, NULL, &fse);
>>> +		if (ret == -ENOIOCTLCMD) {
>>> +			/*
>>> +			 * if subdev does not support enum_frame_size
>>> +			 * then just try to set_fmt directly
>>> +			 */
>>> +			struct v4l2_subdev_format format = {
>>> +				.which = V4L2_SUBDEV_FORMAT_TRY,
>>> +			};
>>> +			struct v4l2_subdev_pad_config *pad_cfg;
>>> +
>>> +			pad_cfg = v4l2_subdev_alloc_pad_config(port->subdev);
>>> +			if (!pad_cfg)
>>> +				return -ENOMEM;
>>> +
>>> +			v4l2_fill_mbus_format(&format.format, &f->fmt.pix,
>>> +					      fmt->code);
>>> +			ret = v4l2_subdev_call(port->subdev, pad, set_fmt,
>>> +					       pad_cfg, &format);
>>> +			if (ret)
>>> +				/* here regardless of the reason we give up */
>>> +				break;
>>> +
>>> +			if (f->fmt.pix.width == format.format.width &&
>>> +			    f->fmt.pix.height == format.format.height) {
>>> +				found = true;
>>> +				vip_dbg(3, stream, "try_fmt loop:%d found direct match: %dx%d\n",
>>> +					fse.index, format.format.width,
>>> +					format.format.height);
>>> +			}
>>> +			largest_width = format.format.width;
>>> +			largest_height = format.format.height;
>>> +			best_width = format.format.width;
>>> +			best_height = format.format.height;
>>> +
>>> +			v4l2_subdev_free_pad_config(pad_cfg);
>>> +			break;
>>> +
>>> +		} else if (ret) {
>>> +			break;
>>> +		}
>>> +
>>> +		vip_dbg(3, stream, "try_fmt loop:%d fourcc:%s size: %dx%d\n",
>>> +			fse.index, fourcc_to_str(f->fmt.pix.pixelformat),
>>> +			fse.max_width, fse.max_height);
>>> +
>>> +		if (!vip_is_size_dma_aligned(bpp, fse.max_width))
>>> +			continue;
>>> +
>>> +		if ((fse.max_width >= largest_width) &&
>>> +		    (fse.max_height >= largest_height)) {
>>> +			vip_dbg(3, stream, "try_fmt loop:%d found new larger: %dx%d\n",
>>> +				fse.index, fse.max_width, fse.max_height);
>>> +			largest_width = fse.max_width;
>>> +			largest_height = fse.max_height;
>>> +		}
>>> +
>>> +		if ((fse.max_width >= f->fmt.pix.width) &&
>>> +		    (fse.max_height >= f->fmt.pix.height)) {
>>> +			vip_dbg(3, stream, "try_fmt loop:%d found at least larger: %dx%d\n",
>>> +				fse.index, fse.max_width, fse.max_height);
>>> +
>>> +			if (!best_width ||
>>> +			    ((abs(best_width - f->fmt.pix.width) >=
>>> +			      abs(fse.max_width - f->fmt.pix.width)) &&
>>> +			     (abs(best_height - f->fmt.pix.height) >=
>>> +			      abs(fse.max_height - f->fmt.pix.height)))) {
>>> +				best_width = fse.max_width;
>>> +				best_height = fse.max_height;
>>> +				vip_dbg(3, stream, "try_fmt loop:%d found new best: %dx%d\n",
>>> +					fse.index, fse.max_width,
>>> +					fse.max_height);
>>> +			}
>>> +		}
>>> +
>>> +		if ((f->fmt.pix.width == fse.max_width) &&
>>> +		    (f->fmt.pix.height == fse.max_height)) {
>>> +			found = true;
>>> +			vip_dbg(3, stream, "try_fmt loop:%d found direct match: %dx%d\n",
>>> +				fse.index, fse.max_width,
>>> +				fse.max_height);
>>> +			break;
>>> +		}
>>> +
>>> +		if ((f->fmt.pix.width >= fse.min_width) &&
>>> +		    (f->fmt.pix.width <= fse.max_width) &&
>>> +		    (f->fmt.pix.height >= fse.min_height) &&
>>> +		    (f->fmt.pix.height <= fse.max_height)) {
>>> +			found = true;
>>> +			vip_dbg(3, stream, "try_fmt loop:%d found direct range match: %dx%d\n",
>>> +				fse.index, fse.max_width,
>>> +				fse.max_height);
>>> +			break;
>>> +		}
>>> +	}
>>> +
>>> +	if (found) {
>>> +		port->try_mbus_framefmt.width = f->fmt.pix.width;
>>> +		port->try_mbus_framefmt.height = f->fmt.pix.height;
>>> +		/* No need to check for scaling */
>>> +		goto calc_size;
>>> +	} else if (largest_width && f->fmt.pix.width > largest_width) {
>>> +		port->try_mbus_framefmt.width = largest_width;
>>> +		port->try_mbus_framefmt.height = largest_height;
>>> +	} else if (best_width) {
>>> +		port->try_mbus_framefmt.width = best_width;
>>> +		port->try_mbus_framefmt.height = best_height;
>>> +	} else {
>>> +		/* use existing values as default */
>>> +	}
>>> +
>>> +	vip_dbg(3, stream, "try_fmt best subdev size: %dx%d\n",
>>> +		port->try_mbus_framefmt.width,
>>> +		port->try_mbus_framefmt.height);
>>> +
>>> +	if (is_scaler_available(port) &&
>>> +	    csc_direction != VIP_CSC_Y2R &&
>>> +	    !vip_is_mbuscode_raw(fmt->code) &&
>>> +	    f->fmt.pix.height <= port->try_mbus_framefmt.height &&
>>> +	    port->try_mbus_framefmt.height <= SC_MAX_PIXEL_HEIGHT &&
>>> +	    port->try_mbus_framefmt.width <= SC_MAX_PIXEL_WIDTH) {
>>> +		/*
>>> +		 * Scaler is only accessible if the dst colorspace is YUV.
>>> +		 * As the input to the scaler must be in YUV mode only.
>>> +		 *
>>> +		 * Scaling up is allowed only horizontally.
>>> +		 */
>>> +		unsigned int hratio, vratio, width_align, height_align;
>>> +		u32 bpp = fmt->vpdma_fmt[0]->depth >> 3;
>>> +
>>> +		vip_dbg(3, stream, "Scaler active on Port %c: requesting %dx%d\n",
>>> +			port->port_id == VIP_PORTA ? 'A' : 'B',
>>> +			f->fmt.pix.width, f->fmt.pix.height);
>>> +
>>> +		/* Just make sure everything is properly aligned */
>>> +		width_align = ALIGN(f->fmt.pix.width * bpp, VPDMA_STRIDE_ALIGN);
>>> +		width_align /= bpp;
>>> +		height_align = ALIGN(f->fmt.pix.height, 2);
>>> +
>>> +		f->fmt.pix.width = width_align;
>>> +		f->fmt.pix.height = height_align;
>>> +
>>> +		hratio = f->fmt.pix.width * 1000 /
>>> +			 port->try_mbus_framefmt.width;
>>> +		vratio = f->fmt.pix.height * 1000 /
>>> +			 port->try_mbus_framefmt.height;
>>> +		if (hratio < 125) {
>>> +			f->fmt.pix.width = port->try_mbus_framefmt.width / 8;
>>> +			vip_dbg(3, stream, "Horizontal scaling ratio out of range adjusting -> %d\n",
>>> +				f->fmt.pix.width);
>>> +		}
>>> +
>>> +		if (vratio < 188) {
>>> +			f->fmt.pix.height = port->try_mbus_framefmt.height / 4;
>>> +			vip_dbg(3, stream, "Vertical scaling ratio out of range adjusting -> %d\n",
>>> +				f->fmt.pix.height);
>>> +		}
>>> +		vip_dbg(3, stream, "Scaler: got %dx%d\n",
>>> +			f->fmt.pix.width, f->fmt.pix.height);
>>> +	} else {
>>> +		/* use existing values as default */
>>> +		f->fmt.pix.width = port->try_mbus_framefmt.width;
>>> +		f->fmt.pix.height = port->try_mbus_framefmt.height;
>>> +	}
>>> +
>>> +calc_size:
>>> +	/* That we have a fmt calculate imagesize and bytesperline */
>>> +	return vip_calc_format_size(port, fmt, f);
>>> +}
>>> +
>>> +static int vip_g_fmt_vid_cap(struct file *file, void *priv,
>>> +			     struct v4l2_format *f)
>>> +{
>>> +	struct vip_stream *stream = file2stream(file);
>>> +	struct vip_port *port = stream->port;
>>> +	struct vip_fmt *fmt = port->fmt;
>>> +
>>> +	/* Use last known values or defaults */
>>> +	f->fmt.pix.width	= stream->width;
>>> +	f->fmt.pix.height	= stream->height;
>>> +	f->fmt.pix.pixelformat	= port->fmt->fourcc;
>>> +	f->fmt.pix.field	= stream->sup_field;
>>> +	f->fmt.pix.colorspace	= port->fmt->colorspace;
>>> +	f->fmt.pix.bytesperline	= stream->bytesperline;
>>> +	f->fmt.pix.sizeimage	= stream->sizeimage;
>>> +
>>> +	vip_dbg(3, stream,
>>> +		"g_fmt fourcc:%s code: %04x size: %dx%d bpl:%d img_size:%d\n",
>>> +		fourcc_to_str(f->fmt.pix.pixelformat),
>>> +		fmt->code,
>>> +		f->fmt.pix.width, f->fmt.pix.height,
>>> +		f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
>>> +	vip_dbg(3, stream, "g_fmt vpdma data type: 0x%02X\n",
>>> +		port->fmt->vpdma_fmt[0]->data_type);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int vip_s_fmt_vid_cap(struct file *file, void *priv,
>>> +			     struct v4l2_format *f)
>>> +{
>>> +	struct vip_stream *stream = file2stream(file);
>>> +	struct vip_port *port = stream->port;
>>> +	struct v4l2_subdev_format sfmt;
>>> +	struct v4l2_mbus_framefmt *mf;
>>> +	enum vip_csc_state csc_direction;
>>> +	int ret;
>>> +
>>> +	vip_dbg(3, stream, "s_fmt input fourcc:%s size: %dx%d bpl:%d img_size:%d\n",
>>> +		fourcc_to_str(f->fmt.pix.pixelformat),
>>> +		f->fmt.pix.width, f->fmt.pix.height,
>>> +		f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
>>> +
>>> +	ret = vip_try_fmt_vid_cap(file, priv, f);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	vip_dbg(3, stream, "s_fmt try_fmt fourcc:%s size: %dx%d bpl:%d img_size:%d\n",
>>> +		fourcc_to_str(f->fmt.pix.pixelformat),
>>> +		f->fmt.pix.width, f->fmt.pix.height,
>>> +		f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
>>> +
>>> +	if (vb2_is_busy(&stream->vb_vidq)) {
>>> +		vip_err(stream, "%s queue busy\n", __func__);
>>> +		return -EBUSY;
>>> +	}
>>> +
>>> +	/*
>>> +	 * Check if we need the scaler or not
>>> +	 *
>>> +	 * Since on previous S_FMT call the scaler might have been
>>> +	 * allocated if it is not needed in this instance we will
>>> +	 * attempt to free it just in case.
>>> +	 *
>>> +	 * free_scaler() is harmless unless the current port
>>> +	 * allocated it.
>>> +	 */
>>> +	if (f->fmt.pix.width == port->try_mbus_framefmt.width &&
>>> +	    f->fmt.pix.height == port->try_mbus_framefmt.height)
>>> +		free_scaler(port);
>>> +	else
>>> +		allocate_scaler(port);
>>> +
>>> +	port->fmt = find_port_format_by_pix(port,
>>> +					    f->fmt.pix.pixelformat);
>>> +	stream->width		= f->fmt.pix.width;
>>> +	stream->height		= f->fmt.pix.height;
>>> +	stream->bytesperline	= f->fmt.pix.bytesperline;
>>> +	stream->sizeimage	= f->fmt.pix.sizeimage;
>>> +	stream->sup_field	= f->fmt.pix.field;
>>> +	stream->field		= f->fmt.pix.field;
>>> +
>>> +	port->c_rect.left	= 0;
>>> +	port->c_rect.top	= 0;
>>> +	port->c_rect.width	= stream->width;
>>> +	port->c_rect.height	= stream->height;
>>> +
>>> +	/*
>>> +	 * Check if we need the csc unit or not
>>> +	 *
>>> +	 * Since on previous S_FMT call, the csc might have been
>>> +	 * allocated if it is not needed in this instance we will
>>> +	 * attempt to free it just in case.
>>> +	 *
>>> +	 * free_csc() is harmless unless the current port
>>> +	 * allocated it.
>>> +	 */
>>> +	csc_direction =  vip_csc_direction(port->fmt->code, port->fmt->finfo);
>>> +	if (csc_direction == VIP_CSC_NA)
>>> +		free_csc(port);
>>> +	else
>>> +		allocate_csc(port, csc_direction);
>>> +
>>> +	if (stream->sup_field == V4L2_FIELD_ALTERNATE)
>>> +		port->flags |= FLAG_INTERLACED;
>>> +	else
>>> +		port->flags &= ~FLAG_INTERLACED;
>>> +
>>> +	vip_dbg(3, stream, "s_fmt fourcc:%s size: %dx%d bpl:%d img_size:%d\n",
>>> +		fourcc_to_str(f->fmt.pix.pixelformat),
>>> +		f->fmt.pix.width, f->fmt.pix.height,
>>> +		f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
>>> +
>>> +	mf = &sfmt.format;
>>> +	v4l2_fill_mbus_format(mf, &f->fmt.pix, port->fmt->code);
>>> +	/* Make sure to use the subdev size found in the try_fmt */
>>> +	mf->width = port->try_mbus_framefmt.width;
>>> +	mf->height = port->try_mbus_framefmt.height;
>>> +
>>> +	vip_dbg(3, stream, "s_fmt pix_to_mbus mbus_code: %04X size: %dx%d\n",
>>> +		mf->code,
>>> +		mf->width, mf->height);
>>> +
>>> +	sfmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
>>> +	sfmt.pad = port->source_pad;
>>> +	ret = v4l2_subdev_call(port->subdev, pad, set_fmt, NULL, &sfmt);
>>> +	if (ret) {
>>> +		vip_dbg(1, stream, "set_fmt failed in subdev\n");
>>> +		return ret;
>>> +	}
>>> +
>>> +	/* Save it */
>>> +	port->mbus_framefmt = *mf;
>>> +
>>> +	vip_dbg(3, stream, "s_fmt subdev fmt mbus_code: %04X size: %dx%d\n",
>>> +		port->mbus_framefmt.code,
>>> +		port->mbus_framefmt.width, port->mbus_framefmt.height);
>>> +	vip_dbg(3, stream, "s_fmt vpdma data type: 0x%02X\n",
>>> +		port->fmt->vpdma_fmt[0]->data_type);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +/*
>>> + * Does the exact opposite of set_fmt_params
>>> + * It makes sure the DataPath register is sane after tear down
>>> + */
>>> +static void unset_fmt_params(struct vip_stream *stream)
>>> +{
>>> +	struct vip_dev *dev = stream->port->dev;
>>> +	struct vip_port *port = stream->port;
>>> +
>>> +	stream->sequence = 0;
>>> +	if (stream->port->flags & FLAG_INTERLACED)
>>> +		stream->field = V4L2_FIELD_TOP;
>>> +
>>> +	if (port->csc == VIP_CSC_Y2R) {
>>> +		if (port->port_id == VIP_PORTA) {
>>> +			vip_set_slice_path(dev, VIP_CSC_SRC_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev, VIP_RGB_SRC_DATA_SELECT, 0);
>>> +		} else {
>>> +			vip_set_slice_path(dev, VIP_CSC_SRC_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 0);
>>> +		}
>>> +		/* We are done */
>>> +		return;
>>> +	} else if (port->csc == VIP_CSC_R2Y) {
>>> +		if (port->scaler && port->fmt->coplanar) {
>>> +			if (port->port_id == VIP_PORTA) {
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CSC_SRC_DATA_SELECT, 0);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_SC_SRC_DATA_SELECT, 0);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CHR_DS_1_SRC_DATA_SELECT,
>>> +						   0);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CHR_DS_1_DATA_BYPASS, 0);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_RGB_OUT_HI_DATA_SELECT,
>>> +						   0);
>>> +			}
>>> +		} else if (port->scaler) {
>>> +			if (port->port_id == VIP_PORTA) {
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CSC_SRC_DATA_SELECT, 0);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_SC_SRC_DATA_SELECT, 0);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CHR_DS_1_SRC_DATA_SELECT,
>>> +						   0);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CHR_DS_1_DATA_BYPASS, 0);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_RGB_OUT_HI_DATA_SELECT,
>>> +						   0);
>>> +			}
>>> +		} else if (port->fmt->coplanar) {
>>> +			if (port->port_id == VIP_PORTA) {
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CSC_SRC_DATA_SELECT, 0);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CHR_DS_1_SRC_DATA_SELECT,
>>> +						   0);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CHR_DS_1_DATA_BYPASS, 0);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_RGB_OUT_HI_DATA_SELECT,
>>> +						   0);
>>> +			}
>>> +		} else {
>>> +			if (port->port_id == VIP_PORTA) {
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CSC_SRC_DATA_SELECT, 0);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CHR_DS_1_SRC_DATA_SELECT,
>>> +						   0);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CHR_DS_1_DATA_BYPASS, 0);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_RGB_OUT_HI_DATA_SELECT,
>>> +						   0);
>>> +			}
>>> +		}
>>> +		/* We are done */
>>> +		return;
>>> +	} else if (v4l2_is_format_rgb(port->fmt->finfo)) {
>>> +		if (port->port_id == VIP_PORTA) {
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 0);
>>> +		}
>>> +		/* We are done */
>>> +		return;
>>> +	}
>>> +
>>> +	if (port->scaler && port->fmt->coplanar) {
>>> +		if (port->port_id == VIP_PORTA) {
>>> +			vip_set_slice_path(dev, VIP_SC_SRC_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_CHR_DS_1_SRC_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 0);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
>>> +		} else {
>>> +			vip_set_slice_path(dev, VIP_SC_SRC_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_CHR_DS_2_SRC_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 0);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
>>> +		}
>>> +	} else if (port->scaler) {
>>> +		if (port->port_id == VIP_PORTA) {
>>> +			vip_set_slice_path(dev, VIP_SC_SRC_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_CHR_DS_1_SRC_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 0);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
>>> +		} else {
>>> +			vip_set_slice_path(dev, VIP_SC_SRC_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_CHR_DS_2_SRC_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 0);
>>> +			vip_set_slice_path(dev, VIP_CHR_DS_2_DATA_BYPASS, 0);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
>>> +		}
>>> +	} else if (port->fmt->coplanar) {
>>> +		if (port->port_id == VIP_PORTA) {
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_CHR_DS_1_SRC_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 0);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
>>> +		} else {
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_CHR_DS_2_SRC_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev, VIP_CHR_DS_2_DATA_BYPASS, 0);
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 0);
>>> +		}
>>> +	} else {
>>> +		/*
>>> +		 * We undo all data path setting except for the multi
>>> +		 * stream case.
>>> +		 * Because we cannot disrupt other on-going capture if only
>>> +		 * one stream is terminated the other might still be going
>>> +		 */
>>> +		vip_set_slice_path(dev, VIP_MULTI_CHANNEL_DATA_SELECT, 1);
>>> +		vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 0);
>>> +	}
>>> +}
>>> +
>>> +/*
>>> + * Set the registers that are modified when the video format changes.
>>> + */
>>> +static void set_fmt_params(struct vip_stream *stream)
>>> +{
>>
>> Hmm, this is a *very* long function. Perhaps this could be split up a bit,
>> or reorganized?
> 
> Yeah, I'll start by removing the extra comment lines and reformat it.
> 
>>
>>> +	struct vip_dev *dev = stream->port->dev;
>>> +	struct vip_port *port = stream->port;
>>> +
>>> +	stream->sequence = 0;
>>> +	if (stream->port->flags & FLAG_INTERLACED)
>>> +		stream->field = V4L2_FIELD_TOP;
>>> +
>>> +	if (port->csc == VIP_CSC_Y2R) {
>>> +		port->flags &= ~FLAG_MULT_PORT;
>>> +		/* Set alpha component in background color */
>>> +		vpdma_set_bg_color(dev->shared->vpdma,
>>> +				   (struct vpdma_data_format *)
>>> +				   port->fmt->vpdma_fmt[0],
>>> +				   0xff);
>>> +		if (port->port_id == VIP_PORTA) {
>>> +			/*
>>> +			 * Input A: YUV422
>>> +			 * Output: Y_UP/UV_UP: RGB
>>> +			 * CSC_SRC_SELECT       = 1
>>> +			 * RGB_OUT_HI_SELECT    = 1
>>> +			 * RGB_SRC_SELECT       = 1
>>> +			 * MULTI_CHANNEL_SELECT = 0
>>
>> It's a bit pointless to comment what the register values should be when you
>> set them in the code below. I'd drop that part, it will make the code
>> shorter.
> 
> Ok.
> 
>>
>>> +			 */
>>> +			vip_set_slice_path(dev, VIP_CSC_SRC_DATA_SELECT, 1);
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
>>
>> For readability purposes I think it is better to keep this on one line. Same for
>> the other vip_set_slice_path calls.
> 
> Ok.
> 
>>
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 1);
>>> +			vip_set_slice_path(dev, VIP_RGB_SRC_DATA_SELECT, 1);
>>> +		} else {
>>> +			/*
>>> +			 * Input B: YUV422
>>> +			 * Output: Y_UP/UV_UP: RGB
>>> +			 * CSC_SRC_SELECT       = 2
>>> +			 * RGB_OUT_LO_SELECT    = 1
>>> +			 * MULTI_CHANNEL_SELECT = 0
>>> +			 */
>>> +			vip_set_slice_path(dev, VIP_CSC_SRC_DATA_SELECT, 2);
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 1);
>>> +		}
>>> +		/* We are done */
>>> +		return;
>>> +	} else if (port->csc == VIP_CSC_R2Y) {
>>> +		port->flags &= ~FLAG_MULT_PORT;
>>> +		if (port->scaler && port->fmt->coplanar) {
>>> +			if (port->port_id == VIP_PORTA) {
>>> +				/*
>>> +				 * Input A: RGB
>>> +				 * Output: Y_UP/UV_UP: Scaled YUV420
>>> +				 * CSC_SRC_SELECT       = 4
>>> +				 * SC_SRC_SELECT        = 1
>>> +				 * CHR_DS_1_SRC_SELECT  = 1
>>> +				 * CHR_DS_1_BYPASS      = 0
>>> +				 * RGB_OUT_HI_SELECT    = 0
>>> +				 */
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CSC_SRC_DATA_SELECT, 4);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_SC_SRC_DATA_SELECT, 1);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CHR_DS_1_SRC_DATA_SELECT,
>>> +						   1);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CHR_DS_1_DATA_BYPASS, 0);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_RGB_OUT_HI_DATA_SELECT,
>>> +						   0);
>>> +			} else {
>>> +				vip_err(stream, "RGB sensor can only be on Port A\n");
>>> +			}
>>> +		} else if (port->scaler) {
>>> +			if (port->port_id == VIP_PORTA) {
>>> +				/*
>>> +				 * Input A: RGB
>>> +				 * Output: Y_UP: Scaled YUV422
>>> +				 * CSC_SRC_SELECT       = 4
>>> +				 * SC_SRC_SELECT        = 1
>>> +				 * CHR_DS_1_SRC_SELECT  = 1
>>> +				 * CHR_DS_1_BYPASS      = 1
>>> +				 * RGB_OUT_HI_SELECT    = 0
>>> +				 */
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CSC_SRC_DATA_SELECT, 4);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_SC_SRC_DATA_SELECT, 1);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CHR_DS_1_SRC_DATA_SELECT,
>>> +						   1);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CHR_DS_1_DATA_BYPASS, 1);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_RGB_OUT_HI_DATA_SELECT,
>>> +						   0);
>>> +			} else {
>>> +				vip_err(stream, "RGB sensor can only be on Port A\n");
>>> +			}
>>> +		} else if (port->fmt->coplanar) {
>>> +			if (port->port_id == VIP_PORTA) {
>>> +				/*
>>> +				 * Input A: RGB
>>> +				 * Output: Y_UP/UV_UP: YUV420
>>> +				 * CSC_SRC_SELECT       = 4
>>> +				 * CHR_DS_1_SRC_SELECT  = 2
>>> +				 * CHR_DS_1_BYPASS      = 0
>>> +				 * RGB_OUT_HI_SELECT    = 0
>>> +				 */
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CSC_SRC_DATA_SELECT, 4);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CHR_DS_1_SRC_DATA_SELECT,
>>> +						   2);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CHR_DS_1_DATA_BYPASS, 0);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_RGB_OUT_HI_DATA_SELECT,
>>> +						   0);
>>> +			} else {
>>> +				vip_err(stream, "RGB sensor can only be on Port A\n");
>>> +			}
>>> +		} else {
>>> +			if (port->port_id == VIP_PORTA) {
>>> +				/*
>>> +				 * Input A: RGB
>>> +				 * Output: Y_UP/UV_UP: YUV420
>>> +				 * CSC_SRC_SELECT       = 4
>>> +				 * CHR_DS_1_SRC_SELECT  = 2
>>> +				 * CHR_DS_1_BYPASS      = 1
>>> +				 * RGB_OUT_HI_SELECT    = 0
>>> +				 */
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CSC_SRC_DATA_SELECT, 4);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CHR_DS_1_SRC_DATA_SELECT,
>>> +						   2);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_CHR_DS_1_DATA_BYPASS, 1);
>>> +				vip_set_slice_path(dev,
>>> +						   VIP_RGB_OUT_HI_DATA_SELECT,
>>> +						   0);
>>> +			} else {
>>> +				vip_err(stream, "RGB sensor can only be on Port A\n");
>>> +			}
>>> +		}
>>> +		/* We are done */
>>> +		return;
>>> +	} else if (v4l2_is_format_rgb(port->fmt->finfo)) {
>>> +		port->flags &= ~FLAG_MULT_PORT;
>>> +		/* Set alpha component in background color */
>>> +		vpdma_set_bg_color(dev->shared->vpdma,
>>> +				   (struct vpdma_data_format *)
>>> +				   port->fmt->vpdma_fmt[0],
>>> +				   0xff);
>>> +		if (port->port_id == VIP_PORTA) {
>>> +			/*
>>> +			 * Input A: RGB
>>> +			 * Output: Y_LO/UV_LO: RGB
>>> +			 * RGB_OUT_LO_SELECT    = 1
>>> +			 * MULTI_CHANNEL_SELECT = 1
>>> +			 */
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_MULTI_CHANNEL_DATA_SELECT, 1);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 1);
>>> +		} else {
>>> +			vip_err(stream, "RGB sensor can only be on Port A\n");
>>> +		}
>>> +		/* We are done */
>>> +		return;
>>> +	}
>>> +
>>> +	if (port->scaler && port->fmt->coplanar) {
>>> +		port->flags &= ~FLAG_MULT_PORT;
>>> +		if (port->port_id == VIP_PORTA) {
>>> +			/*
>>> +			 * Input A: YUV422
>>> +			 * Output: Y_UP/UV_UP: Scaled YUV420
>>> +			 * SC_SRC_SELECT        = 2
>>> +			 * CHR_DS_1_SRC_SELECT  = 1
>>> +			 * CHR_DS_1_BYPASS      = 0
>>> +			 * RGB_OUT_HI_SELECT    = 0
>>> +			 */
>>> +			vip_set_slice_path(dev, VIP_SC_SRC_DATA_SELECT, 2);
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_CHR_DS_1_SRC_DATA_SELECT, 1);
>>> +			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 0);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
>>> +		} else {
>>> +			/*
>>> +			 * Input B: YUV422
>>> +			 * Output: Y_LO/UV_LO: Scaled YUV420
>>> +			 * SC_SRC_SELECT        = 3
>>> +			 * CHR_DS_2_SRC_SELECT  = 1
>>> +			 * RGB_OUT_LO_SELECT    = 0
>>> +			 * MULTI_CHANNEL_SELECT = 0
>>> +			 */
>>> +			vip_set_slice_path(dev, VIP_SC_SRC_DATA_SELECT, 3);
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_CHR_DS_2_SRC_DATA_SELECT, 1);
>>> +			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 0);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
>>> +		}
>>> +	} else if (port->scaler) {
>>> +		port->flags &= ~FLAG_MULT_PORT;
>>> +		if (port->port_id == VIP_PORTA) {
>>> +			/*
>>> +			 * Input A: YUV422
>>> +			 * Output: Y_UP: Scaled YUV422
>>> +			 * SC_SRC_SELECT        = 2
>>> +			 * CHR_DS_1_SRC_SELECT  = 1
>>> +			 * CHR_DS_1_BYPASS      = 1
>>> +			 * RGB_OUT_HI_SELECT    = 0
>>> +			 */
>>> +			vip_set_slice_path(dev, VIP_SC_SRC_DATA_SELECT, 2);
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_CHR_DS_1_SRC_DATA_SELECT, 1);
>>> +			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 1);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
>>> +		} else {
>>> +			/*
>>> +			 * Input B: YUV422
>>> +			 * Output: UV_UP: Scaled YUV422
>>> +			 * SC_SRC_SELECT        = 3
>>> +			 * CHR_DS_2_SRC_SELECT  = 1
>>> +			 * CHR_DS_1_BYPASS      = 1
>>> +			 * CHR_DS_2_BYPASS      = 1
>>> +			 * RGB_OUT_HI_SELECT    = 0
>>> +			 */
>>> +			vip_set_slice_path(dev, VIP_SC_SRC_DATA_SELECT, 3);
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_CHR_DS_2_SRC_DATA_SELECT, 1);
>>> +			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 1);
>>> +			vip_set_slice_path(dev, VIP_CHR_DS_2_DATA_BYPASS, 1);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
>>> +		}
>>> +	} else if (port->fmt->coplanar) {
>>> +		port->flags &= ~FLAG_MULT_PORT;
>>> +		if (port->port_id == VIP_PORTA) {
>>> +			/*
>>> +			 * Input A: YUV422
>>> +			 * Output: Y_UP/UV_UP: YUV420
>>> +			 * CHR_DS_1_SRC_SELECT  = 3
>>> +			 * CHR_DS_1_BYPASS      = 0
>>> +			 * RGB_OUT_HI_SELECT    = 0
>>> +			 */
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_CHR_DS_1_SRC_DATA_SELECT, 3);
>>> +			vip_set_slice_path(dev, VIP_CHR_DS_1_DATA_BYPASS, 0);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_HI_DATA_SELECT, 0);
>>> +		} else {
>>> +			/*
>>> +			 * Input B: YUV422
>>> +			 * Output: Y_LO/UV_LO: YUV420
>>> +			 * CHR_DS_2_SRC_SELECT  = 4
>>> +			 * CHR_DS_2_BYPASS      = 0
>>> +			 * RGB_OUT_LO_SELECT    = 0
>>> +			 * MULTI_CHANNEL_SELECT = 0
>>> +			 */
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_CHR_DS_2_SRC_DATA_SELECT, 4);
>>> +			vip_set_slice_path(dev, VIP_CHR_DS_2_DATA_BYPASS, 0);
>>> +			vip_set_slice_path(dev,
>>> +					   VIP_MULTI_CHANNEL_DATA_SELECT, 0);
>>> +			vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 0);
>>> +		}
>>> +	} else {
>>> +		port->flags |= FLAG_MULT_PORT;
>>> +		/*
>>> +		 * Input A/B: YUV422
>>> +		 * Output: Y_LO: YUV422 - UV_LO: YUV422
>>> +		 * MULTI_CHANNEL_SELECT = 1
>>> +		 * RGB_OUT_LO_SELECT    = 0
>>> +		 */
>>> +		vip_set_slice_path(dev, VIP_MULTI_CHANNEL_DATA_SELECT, 1);
>>> +		vip_set_slice_path(dev, VIP_RGB_OUT_LO_DATA_SELECT, 0);
>>> +	}
>>> +}
>>> +
>>> +static int vip_g_selection(struct file *file, void *fh,
>>> +			   struct v4l2_selection *s)
>>> +{
>>> +	struct vip_stream *stream = file2stream(file);
>>> +
>>> +	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
>>> +		return -EINVAL;
>>> +
>>> +	switch (s->target) {
>>> +	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
>>> +	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
>>> +	case V4L2_SEL_TGT_CROP_BOUNDS:
>>> +	case V4L2_SEL_TGT_CROP_DEFAULT:
>>> +		s->r.left = 0;
>>> +		s->r.top = 0;
>>> +		s->r.width = stream->width;
>>> +		s->r.height = stream->height;
>>> +		return 0;
>>> +
>>> +	case V4L2_SEL_TGT_COMPOSE:
>>> +	case V4L2_SEL_TGT_CROP:
>>> +		s->r = stream->port->c_rect;
>>> +		return 0;
>>> +	}
>>> +
>>> +	return -EINVAL;
>>> +}
>>> +
>>> +static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
>>> +{
>>> +	if (a->left < b->left || a->top < b->top)
>>> +		return 0;
>>> +	if (a->left + a->width > b->left + b->width)
>>> +		return 0;
>>> +	if (a->top + a->height > b->top + b->height)
>>> +		return 0;
>>> +
>>> +	return 1;
>>> +}
>>
>> There are helper functions in include/media/v4l2-rect.h, it would make
>> sense to add this one to that header.
> 
> I'll check that out.
> 
>>
>>> +
>>> +static int vip_s_selection(struct file *file, void *fh,
>>> +			   struct v4l2_selection *s)
>>> +{
>>> +	struct vip_stream *stream = file2stream(file);
>>> +	struct v4l2_rect r = s->r;
>>> +
>>> +	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
>>> +		return -EINVAL;
>>> +
>>> +	switch (s->target) {
>>> +	case V4L2_SEL_TGT_COMPOSE:
>>> +	case V4L2_SEL_TGT_CROP:
>>
>> Why both crop and compose when it is the same c_rect? That makes no sense.
> 
> Yeah, this is always puzzling to me. When to use which and what not.
> I'll catch you on IRC sometime to chat about this.

For video capture devices cropping occurs before the DMA step, usually
in the sensor. Composing affects the DMA engine: it composes the (possibly
cropped) video frame into a buffer. E.g. the buffer might be sized for
1920x1080, but the video is 1280x720 and you want to have it DMAed to the
center of the 1920x1080-sized buffer.

This requires that the DMA engine supports this, which is uncommon for video
capture drivers. So typically video capture drivers just support cropping.

> 
>>
>>> +		v4l_bound_align_image(&r.width, 0, stream->width, 0,
>>> +				      &r.height, 0, stream->height, 0, 0);
>>> +
>>> +		r.left = clamp_t(unsigned int, r.left, 0,
>>> +				 stream->width - r.width);
>>> +		r.top  = clamp_t(unsigned int, r.top, 0,
>>> +				 stream->height - r.height);
>>> +
>>> +		if (s->flags & V4L2_SEL_FLAG_LE &&
>>> +		    !enclosed_rectangle(&r, &s->r))
>>> +			return -ERANGE;
>>> +
>>> +		if (s->flags & V4L2_SEL_FLAG_GE &&
>>> +		    !enclosed_rectangle(&s->r, &r))
>>> +			return -ERANGE;
>>> +
>>> +		s->r = r;
>>> +		stream->port->c_rect = r;
>>> +
>>> +		vip_dbg(1, stream, "cropped (%d,%d)/%dx%d of %dx%d\n",
>>> +			r.left, r.top, r.width, r.height,
>>> +			stream->width, stream->height);
>>> +
>>> +			s->r = stream->port->c_rect;
>>> +		return 0;
>>> +	default:
>>> +		return -EINVAL;
>>> +	}
>>> +
>>> +	return 0;
>>> +}

Regards,

	Hans

^ permalink raw reply

* Re: [PATCHv6 0/4] n_gsm serdev support and protocol driver for droid4 modem
From: Johan Hovold @ 2020-05-28  8:24 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Johan Hovold, Greg Kroah-Hartman, Rob Herring, Alan Cox,
	Lee Jones, Jiri Slaby, Merlijn Wajer, Pavel Machek, Peter Hurley,
	Sebastian Reichel, linux-serial, devicetree, linux-kernel,
	linux-omap
In-Reply-To: <20200423153756.GE37466@atomide.com>

Hi Tony,

Sorry about the late reply on this.

On Thu, Apr 23, 2020 at 08:37:56AM -0700, Tony Lindgren wrote:
> * Johan Hovold <johan@kernel.org> [200423 11:44]:

> > I know the location of this driver has been up for discussion already,
> > but drivers/tty/serdev/protocol still isn't right (e.g. we don't have an
> > drivers/i2c/protocol directory where we stuff random i2c client
> > drivers).
> 
> Argh, the location of driver again.. So we do have the custom motorola
> layer to deal with on top of TS 27.010, but the custom handling is
> contained within the driver. So maybe just drivers/serial for the
> custom driver then.

Yeah, that should do for now; n_gsm is a serial driver (exposing tty
devices) after all.

> > Last, it seems you've based the serdev-ngsm-motmdm.c chardev
> > implementation on a more or less verbatim copy of drivers/gnss/core.c.
> > I'd appreciate if you could mention that in the file header and
> > reproduce the copyright notice if you end up keeping that interface.
> 
> Oh yes indeed, thanks for pointing that out. I'll add it to the next
> version. The chardev code is for sure based on drivers/gnss.
> 
> To explain my ignorance, I added the chardev support initially as an
> experiment to see if I can handle the motorola packet layer better
> that way compared to the n_gsm ttys and userspace handling. It ended
> up working quite nicely, so I kept it but then I accidentally left
> out references to the source. Sorry about that.

No worries.

Johan

^ permalink raw reply

* Re: [PATCH RESEND v3 0/2] syscon: Alter syscon and reboot drivers
From: Serge Semin @ 2020-05-28  8:31 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Serge Semin, Alexey Malahov, Maxim Kaurkin, Pavel Parkhomenko,
	Ramil Zaripov, Ekaterina Skachko, Vadim Vlasov, Alexey Kolotnikov,
	Thomas Bogendoerfer, Arnd Bergmann, Rob Herring, linux-mips,
	devicetree, linux-pm, linux-kernel
In-Reply-To: <20200528070311.uj6bxlplxe2bths5@earth.universe>

On Thu, May 28, 2020 at 09:03:11AM +0200, Sebastian Reichel wrote:
> Hi,
> 
> On Tue, May 26, 2020 at 04:50:59PM +0300, Serge Semin wrote:
> > This is a small patchset about tuning the syscon infrastructure a bit.
> > As it's going to be general in the framework of the Baikal-T1 SoC support
> > integration into the kernel, we suggest to replace the legacy text-based
> > syscon-reboot-mode dts-bindings file with yaml-based one. Then seeing a
> > syscon reboot block is normally expected to be a part of a system
> > controller and based on the discussion
> > https://lore.kernel.org/linux-pm/20200306130402.1F4F0803079F@mail.baikalelectronics.ru/
> > we decided to alter the syscon reboot driver so one would also try to fetch
> > the syscon registers map from a parental DT node. regmap property is left
> > supported although it's marked as deprecated from now.
> > 
> > This patchset is rebased and tested on the mainline Linux kernel 5.7-rc4:
> > 0e698dfa2822 ("Linux 5.7-rc4")
> > tag: v5.7-rc4
> > 
> > Changelog v2:
> > - Add Sebastian' Acked-by tag to patch 1.
> > - Use a shorter summary describing the bindings modification patches.
> > - Our corporate email server doesn't change Message-Id anymore, so the patchset
> >   is resubmitted being in the cover-letter-threaded format.
> > - Discard patch with syscon "-endian" property support. As Rob said It shall be
> >   in the common dt-schema.
> > - Replace patches of adding a regmap property support to the syscon-reboot-mode
> >   with patches making syscon-reboot a sub-node of a system controller node.
> > - Mark regmap property as deprecated from now.
> > 
> > Link: https://lore.kernel.org/linux-pm/20200507233846.11548-1-Sergey.Semin@baikalelectronics.ru/
> > Changelog v3:
> > - Discard the commit 6acd3ecd88ff ("dt-bindings: power: reset: Convert
> >   syscon-reboot-mode to DT schema") since it has been merged in by Sebatian.
> > - Add Rob's Reviewed-by tag to the patch "dt-bindings: power: reset: Unrequire
> >   regmap property in syscon-reboot node"
> > 
> > Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> > Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
> > Cc: Maxim Kaurkin <Maxim.Kaurkin@baikalelectronics.ru>
> > Cc: Pavel Parkhomenko <Pavel.Parkhomenko@baikalelectronics.ru>
> > Cc: Ramil Zaripov <Ramil.Zaripov@baikalelectronics.ru>
> > Cc: Ekaterina Skachko <Ekaterina.Skachko@baikalelectronics.ru>
> > Cc: Vadim Vlasov <V.Vlasov@baikalelectronics.ru>
> > Cc: Alexey Kolotnikov <Alexey.Kolotnikov@baikalelectronics.ru>
> > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: linux-mips@vger.kernel.org
> > Cc: devicetree@vger.kernel.org
> > Cc: linux-pm@vger.kernel.org
> > Cc: linux-kernel@vger.kernel.org
> > 
> > Serge Semin (2):
> >   dt-bindings: power: reset: Unrequire regmap property in syscon-reboot
> >     node
> >   power: reset: syscon-reboot: Add parental syscon support
> > 
> >  .../bindings/power/reset/syscon-reboot.yaml       | 15 ++++++++++-----
> >  drivers/power/reset/syscon-reboot.c               |  7 +++++--
> >  2 files changed, 15 insertions(+), 7 deletions(-)
> 
> Thanks, I queued both patches to power-supply's for-next branch.
> 
> -- Sebastian

Great! Thanks.

-Sergey

^ permalink raw reply

* [v1] drm/msm/dpu: allow initialization of encoder locks during encoder init
From: Krishna Manikandan @ 2020-05-28  8:34 UTC (permalink / raw)
  To: dri-devel, linux-arm-msm, freedreno, devicetree
  Cc: Krishna Manikandan, linux-kernel, robdclark, seanpaul, hoegsberg,
	kalyan_t, nganji, mka

In the current implementation, mutex initialization
for encoder mutex locks are done during encoder
setup. This can lead to scenarios where the lock
is used before it is initialized. Move mutex_init
to dpu_encoder_init to avoid this.

Signed-off-by: Krishna Manikandan <mkrishn@codeaurora.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index f8ac3bf..21730a5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2145,7 +2145,6 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc,
 
 	dpu_enc = to_dpu_encoder_virt(enc);
 
-	mutex_init(&dpu_enc->enc_lock);
 	ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info);
 	if (ret)
 		goto fail;
@@ -2160,7 +2159,6 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc,
 				0);
 
 
-	mutex_init(&dpu_enc->rc_lock);
 	INIT_DELAYED_WORK(&dpu_enc->delayed_off_work,
 			dpu_encoder_off_work);
 	dpu_enc->idle_timeout = IDLE_TIMEOUT;
@@ -2205,6 +2203,8 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev,
 
 	spin_lock_init(&dpu_enc->enc_spinlock);
 	dpu_enc->enabled = false;
+	mutex_init(&dpu_enc->enc_lock);
+	mutex_init(&dpu_enc->rc_lock);
 
 	return &dpu_enc->base;
 }
-- 
1.9.1


^ 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