linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/27] Allwinner H6 DE3 and HDMI support
@ 2018-09-02  7:26 Jernej Skrabec
  2018-09-02  7:26 ` [PATCH 01/27] dt-bindings: sunxi-sram: add binding for Allwinner H6 SRAM C Jernej Skrabec
                   ` (27 more replies)
  0 siblings, 28 replies; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

This series adds support for Display Engine 3.0 and HDMI 2.0a, which
can be found on H6 SoC.

Display Engine 3.0 in comparison to 2.0 mostly adds features needed for
displaying and processing 10-bit and AFBC formats, which are not yet
supported by this series.

This series is based on linux-next at next-20180828, which has working
R40 display pipeline support. I'll rebase series on later linux-next, if
needed, once R40 display pipeline support is reintroduced.

I suggest all patches go through allwinner tree, except DRM patches,
which should go through drm-misc tree.

Last detail, PineH64 model A schematic has DDC_EN signal, which enables
DDC voltage level shifter. TL Lim, PINE64 founder, said that this
signal is not actually present on PineH64 model A board. It is, however
present on PineH64 model B engineering samples, but it will be removed
in production version. Because of that, I didn't include any code for
it.

Please take a look.

Best regards,
Jernej

Icenowy Zheng (7):
  dt-bindings: sunxi-sram: add binding for Allwinner H6 SRAM C
  arm64: allwinner: h6: add system controller device tree node
  dt-bindings: bus: add H6 DE3 bus binding
  dt-bindings: display: sunxi: add DT binding for Allwinner H6 DW HDMI
  drm: sun4i: add quirks for TCON TOP
  dt-bindings: display: sun4i-drm: document H6 TCON TOP
  drm: sun4i: add support for H6 TCON TOP

Jernej Skrabec (20):
  clk: sunxi-ng: Adjust MP clock parent rate when allowed
  clk: sunxi-ng: Use u64 for calculation of NM rate
  clk: sunxi-ng: h6: Set video PLLs limits
  dt-bindings: clock: sun8i-de2: Add H6 DE3 clock description
  clk: sunxi-ng: Add support for H6 DE3 clocks
  dt-bindings: display: sun4i-drm: Add H6 display engine compatibles
  drm/sun4i: Add compatible for H6 display engine
  drm/sun4i: Rework DE2 register defines
  drm/sun4i: Add basic support for DE3
  drm/sun4i: Add support for H6 DE3 mixer 0
  drm/bridge/synopsys: dw-hdmi: Enable workaround for v2.12a
  drm/sun4i: Not all DW HDMI controllers has scrambled addresses
  drm/sun4i: dw-hdmi: Make mode_valid function configurable
  drm/sun4i: dw-hdmi: Add quirk for setting TMDS clock
  drm/sun4i: Add support for H6 DW HDMI controller
  drm/sun4i: Add support for Synopsys HDMI PHY
  drm/sun4i: Add support for H6 HDMI PHY
  drm/sun4i: Initialize registers in tcon-top driver
  arm64: dts: sun50i: h6: Add HDMI pipeline
  arm64: dts: sun50i: h6: Enable HDMI output on Pine H64 board

 .../bindings/bus/sun50i-de2-bus.txt           |   9 +-
 .../devicetree/bindings/clock/sun8i-de2.txt   |   5 +-
 .../bindings/display/sunxi/sun4i-drm.txt      |  30 ++-
 .../devicetree/bindings/sram/sunxi-sram.txt   |   4 +
 .../boot/dts/allwinner/sun50i-h6-pine-h64.dts |  25 ++
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  | 224 ++++++++++++++++++
 drivers/clk/sunxi-ng/ccu-sun50i-h6.c          |   4 +
 drivers/clk/sunxi-ng/ccu-sun8i-de2.c          |  65 +++++
 drivers/clk/sunxi-ng/ccu-sun8i-de2.h          |   1 +
 drivers/clk/sunxi-ng/ccu_mp.c                 |  64 ++++-
 drivers/clk/sunxi-ng/ccu_nm.c                 |  18 +-
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |   1 +
 drivers/gpu/drm/sun4i/sun4i_drv.c             |   1 +
 drivers/gpu/drm/sun4i/sun8i_csc.c             |  96 +++++++-
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c         |  45 +++-
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h         |  14 +-
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c        | 178 +++++++++++++-
 drivers/gpu/drm/sun4i/sun8i_mixer.c           |  44 +++-
 drivers/gpu/drm/sun4i/sun8i_mixer.h           |  61 +++--
 drivers/gpu/drm/sun4i/sun8i_tcon_top.c        |  58 ++++-
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c        |  47 ++--
 drivers/gpu/drm/sun4i/sun8i_ui_layer.h        |  37 +--
 drivers/gpu/drm/sun4i/sun8i_ui_scaler.c       |  45 ++--
 drivers/gpu/drm/sun4i/sun8i_ui_scaler.h       |  28 +--
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c        |  55 +++--
 drivers/gpu/drm/sun4i/sun8i_vi_layer.h        |  25 +-
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.c       |  85 +++++--
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.h       |  68 ++++--
 include/dt-bindings/clock/sun8i-de2.h         |   3 +
 include/dt-bindings/reset/sun8i-de2.h         |   1 +
 30 files changed, 1127 insertions(+), 214 deletions(-)

-- 
2.18.0


^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH 01/27] dt-bindings: sunxi-sram: add binding for Allwinner H6 SRAM C
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-04  8:39   ` Chen-Yu Tsai
  2018-09-02  7:26 ` [PATCH 02/27] arm64: allwinner: h6: add system controller device tree node Jernej Skrabec
                   ` (26 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, Icenowy Zheng

From: Icenowy Zheng <icenowy@aosc.io>

The Allwinner H6 SoC's DE3 needs the SRAM C section being claimed in the
system controller to work, like A64 DE2.

As H6 and A64 system controller are quite similar, code is reused now,
and the A64 fallback compatible string is added after the H6 compatible
string.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
[fixed typo in compatible string]
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 Documentation/devicetree/bindings/sram/sunxi-sram.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/sram/sunxi-sram.txt b/Documentation/devicetree/bindings/sram/sunxi-sram.txt
index c51ade86578c..62dd0748f0ef 100644
--- a/Documentation/devicetree/bindings/sram/sunxi-sram.txt
+++ b/Documentation/devicetree/bindings/sram/sunxi-sram.txt
@@ -18,6 +18,7 @@ Required properties:
     - "allwinner,sun8i-h3-system-control"
     - "allwinner,sun50i-a64-sram-controller" (deprecated)
     - "allwinner,sun50i-a64-system-control"
+    - "allwinner,sun50i-h6-system-control", "allwinner,sun50i-a64-system-control"
 - reg : sram controller register offset + length
 
 SRAM nodes
@@ -54,6 +55,9 @@ The valid sections compatible for H3 are:
 The valid sections compatible for A64 are:
     - allwinner,sun50i-a64-sram-c
 
+The valid sections compatible for H6 are:
+    - allwinner,sun50i-h6-sram-c, allwinner,sun50i-a64-sram-c
+
 Devices using SRAM sections
 ---------------------------
 
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 02/27] arm64: allwinner: h6: add system controller device tree node
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
  2018-09-02  7:26 ` [PATCH 01/27] dt-bindings: sunxi-sram: add binding for Allwinner H6 SRAM C Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-04  8:40   ` Chen-Yu Tsai
  2018-09-02  7:26 ` [PATCH 03/27] dt-bindings: bus: add H6 DE3 bus binding Jernej Skrabec
                   ` (25 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, Icenowy Zheng

From: Icenowy Zheng <icenowy@aosc.io>

As we have already binding for the H6 system controller, add its node
to the device tree.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
[fixed compatible string]
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 23 ++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index cfa5fffcf62b..040828d2e2c0 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -92,6 +92,29 @@
 		#size-cells = <1>;
 		ranges;
 
+		syscon: syscon@3000000 {
+			compatible = "allwinner,sun50i-h6-system-control",
+				     "allwinner,sun50i-a64-system-control";
+			reg = <0x03000000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			sram_c: sram@28000 {
+				compatible = "mmio-sram";
+				reg = <0x00028000 0x1e000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x00028000 0x1e000>;
+
+				de2_sram: sram-section@0 {
+					compatible = "allwinner,sun50i-h6-sram-c",
+						     "allwinner,sun50i-a64-sram-c";
+					reg = <0x0000 0x1e000>;
+				};
+			};
+		};
+
 		ccu: clock@3001000 {
 			compatible = "allwinner,sun50i-h6-ccu";
 			reg = <0x03001000 0x1000>;
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 03/27] dt-bindings: bus: add H6 DE3 bus binding
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
  2018-09-02  7:26 ` [PATCH 01/27] dt-bindings: sunxi-sram: add binding for Allwinner H6 SRAM C Jernej Skrabec
  2018-09-02  7:26 ` [PATCH 02/27] arm64: allwinner: h6: add system controller device tree node Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-02  7:26 ` [PATCH 04/27] clk: sunxi-ng: Adjust MP clock parent rate when allowed Jernej Skrabec
                   ` (24 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, Icenowy Zheng

From: Icenowy Zheng <icenowy@aosc.io>

The Allwinner H6 DE3 bus is similar to the A64 DE2 one.

Add its compatible string with the A64 string as fallback to the
binding.

Some description of the binding is modified to make it more generic.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt b/Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt
index 87dfb33fb3be..ac1445b95f41 100644
--- a/Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt
+++ b/Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt
@@ -1,11 +1,14 @@
-Device tree bindings for Allwinner A64 DE2 bus
+Device tree bindings for Allwinner DE2/3 bus
 
 The Allwinner A64 DE2 is on a special bus, which needs a SRAM region (SRAM C)
-to be claimed for enabling the access.
+to be claimed for enabling the access. The DE3 on Allwinner H6 is at the same
+situation, and the binding also applies.
 
 Required properties:
 
- - compatible:		Should contain "allwinner,sun50i-a64-de2"
+ - compatible:		Should be one of:
+				- "allwinner,sun50i-a64-de2"
+				- "allwinner,sun50i-a6-de3", "allwinner,sun50i-a64-de2"
  - reg:			A resource specifier for the register space
  - #address-cells:	Must be set to 1
  - #size-cells:		Must be set to 1
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 04/27] clk: sunxi-ng: Adjust MP clock parent rate when allowed
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (2 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 03/27] dt-bindings: bus: add H6 DE3 bus binding Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-02  7:26 ` [PATCH 05/27] clk: sunxi-ng: Use u64 for calculation of NM rate Jernej Skrabec
                   ` (23 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

Currently MP clocks don't consider adjusting parent rate even if they
are allowed to do so. Such behaviour considerably lowers amount of
possible rates, which is very inconvenient when such clock is used for
pixel clock, for example.

In order to improve the situation, adjusting parent rate is considered
when allowed.

This code is inspired by clk_divider_bestdiv() function, which does
basically the same thing for different clock type.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/clk/sunxi-ng/ccu_mp.c | 64 +++++++++++++++++++++++++++++++++--
 1 file changed, 62 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
index 5d0af4051737..0357349eb767 100644
--- a/drivers/clk/sunxi-ng/ccu_mp.c
+++ b/drivers/clk/sunxi-ng/ccu_mp.c
@@ -40,6 +40,61 @@ static void ccu_mp_find_best(unsigned long parent, unsigned long rate,
 	*p = best_p;
 }
 
+static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw,
+						      unsigned long *parent,
+						      unsigned long rate,
+						      unsigned int max_m,
+						      unsigned int max_p)
+{
+	unsigned long parent_rate_saved;
+	unsigned long parent_rate, now;
+	unsigned long best_rate = 0;
+	unsigned int _m, _p, div;
+	unsigned long maxdiv;
+
+	parent_rate_saved = *parent;
+
+	/*
+	 * The maximum divider we can use without overflowing
+	 * unsigned long in rate * m * p below
+	 */
+	maxdiv = max_m * max_p;
+	maxdiv = min(ULONG_MAX / rate, maxdiv);
+
+	for (_p = 1; _p <= max_p; _p <<= 1) {
+		for (_m = 1; _m <= max_m; _m++) {
+			div = _m * _p;
+
+			if (div > maxdiv)
+				break;
+
+			if (rate * div == parent_rate_saved) {
+				/*
+				 * It's the most ideal case if the requested
+				 * rate can be divided from parent clock without
+				 * needing to change parent rate, so return the
+				 * divider immediately.
+				 */
+				*parent = parent_rate_saved;
+				return rate;
+			}
+
+			parent_rate = clk_hw_round_rate(hw, rate * div);
+			now = parent_rate / div;
+
+			if (now <= rate && now > best_rate) {
+				best_rate = now;
+				*parent = parent_rate;
+
+				if (now == rate)
+					return rate;
+			}
+		}
+	}
+
+	return best_rate;
+}
+
 static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
 				       struct clk_hw *hw,
 				       unsigned long *parent_rate,
@@ -56,8 +111,13 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
 	max_m = cmp->m.max ?: 1 << cmp->m.width;
 	max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
 
-	ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
-	rate = *parent_rate / p / m;
+	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
+		ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
+		rate = *parent_rate / p / m;
+	} else {
+		rate = ccu_mp_find_best_with_parent_adj(hw, parent_rate, rate,
+							max_m, max_p);
+	}
 
 	if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
 		rate /= cmp->fixed_post_div;
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 05/27] clk: sunxi-ng: Use u64 for calculation of NM rate
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (3 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 04/27] clk: sunxi-ng: Adjust MP clock parent rate when allowed Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-04  9:18   ` Chen-Yu Tsai
  2018-09-02  7:26 ` [PATCH 06/27] clk: sunxi-ng: h6: Set video PLLs limits Jernej Skrabec
                   ` (22 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

Allwinner H6 SoC has multiplier N range between 1 and 254. Since parent
rate is 24MHz, intermediate result when calculating final rate easily
overflows 32 bit variable.

Because of that, introduce function for calculating clock rate which
uses 64 bit variable for intermediate result.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/clk/sunxi-ng/ccu_nm.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c
index 6fe3c14f7b2d..424d8635b053 100644
--- a/drivers/clk/sunxi-ng/ccu_nm.c
+++ b/drivers/clk/sunxi-ng/ccu_nm.c
@@ -19,6 +19,17 @@ struct _ccu_nm {
 	unsigned long	m, min_m, max_m;
 };
 
+static unsigned long ccu_nm_calc_rate(unsigned long parent,
+				      unsigned long n, unsigned long m)
+{
+	u64 rate = parent;
+
+	rate *= n;
+	do_div(rate, m);
+
+	return rate;
+}
+
 static void ccu_nm_find_best(unsigned long parent, unsigned long rate,
 			     struct _ccu_nm *nm)
 {
@@ -28,7 +39,8 @@ static void ccu_nm_find_best(unsigned long parent, unsigned long rate,
 
 	for (_n = nm->min_n; _n <= nm->max_n; _n++) {
 		for (_m = nm->min_m; _m <= nm->max_m; _m++) {
-			unsigned long tmp_rate = parent * _n  / _m;
+			unsigned long tmp_rate = ccu_nm_calc_rate(parent,
+								  _n, _m);
 
 			if (tmp_rate > rate)
 				continue;
@@ -100,7 +112,7 @@ static unsigned long ccu_nm_recalc_rate(struct clk_hw *hw,
 	if (ccu_sdm_helper_is_enabled(&nm->common, &nm->sdm))
 		rate = ccu_sdm_helper_read_rate(&nm->common, &nm->sdm, m, n);
 	else
-		rate = parent_rate * n / m;
+		rate = ccu_nm_calc_rate(parent_rate, n, m);
 
 	if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
 		rate /= nm->fixed_post_div;
@@ -149,7 +161,7 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
 	_nm.max_m = nm->m.max ?: 1 << nm->m.width;
 
 	ccu_nm_find_best(*parent_rate, rate, &_nm);
-	rate = *parent_rate * _nm.n / _nm.m;
+	rate = ccu_nm_calc_rate(*parent_rate, _nm.n, _nm.m);
 
 	if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
 		rate /= nm->fixed_post_div;
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 06/27] clk: sunxi-ng: h6: Set video PLLs limits
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (4 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 05/27] clk: sunxi-ng: Use u64 for calculation of NM rate Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-04 15:49   ` kbuild test robot
  2018-09-04 15:49   ` kbuild test robot
  2018-09-02  7:26 ` [PATCH 07/27] dt-bindings: clock: sun8i-de2: Add H6 DE3 clock description Jernej Skrabec
                   ` (21 subsequent siblings)
  27 siblings, 2 replies; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

Video PLL factors can be set in a way that final PLL rate is outside
stable range. H6 user manual specifically says that N factor should not
be below 12. While it doesn't says anything about maximum stable rate, it
is clear that PLL doesn't work at 6.096 GHz (254 * 24 MHz).

Set minimum allowed PLL video rate to 288 MHz (12 * 24 MHz) and maximum
to 2.4 GHz, which is maximum in BSP driver.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
index 2193e1495086..f44d314b2285 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
@@ -120,6 +120,8 @@ static struct ccu_nm pll_video0_clk = {
 	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
 	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
 	.fixed_post_div	= 4,
+	.min_rate	= 288000000,
+	.max_rate	= 2400000000,
 	.common		= {
 		.reg		= 0x040,
 		.features	= CCU_FEATURE_FIXED_POSTDIV,
@@ -136,6 +138,8 @@ static struct ccu_nm pll_video1_clk = {
 	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
 	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
 	.fixed_post_div	= 4,
+	.min_rate	= 288000000,
+	.max_rate	= 2400000000,
 	.common		= {
 		.reg		= 0x048,
 		.features	= CCU_FEATURE_FIXED_POSTDIV,
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 07/27] dt-bindings: clock: sun8i-de2: Add H6 DE3 clock description
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (5 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 06/27] clk: sunxi-ng: h6: Set video PLLs limits Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-04  8:59   ` Chen-Yu Tsai
  2018-09-02  7:26 ` [PATCH 08/27] clk: sunxi-ng: Add support for H6 DE3 clocks Jernej Skrabec
                   ` (20 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

This commit adds necessary description and dt includes for H6 DE3 clock.
It is very similar to others, but memory region has some additional
registers not found in DE2.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 Documentation/devicetree/bindings/clock/sun8i-de2.txt | 5 +++--
 include/dt-bindings/clock/sun8i-de2.h                 | 3 +++
 include/dt-bindings/reset/sun8i-de2.h                 | 1 +
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/sun8i-de2.txt b/Documentation/devicetree/bindings/clock/sun8i-de2.txt
index e94582e8b8a9..41a52c2acffd 100644
--- a/Documentation/devicetree/bindings/clock/sun8i-de2.txt
+++ b/Documentation/devicetree/bindings/clock/sun8i-de2.txt
@@ -1,5 +1,5 @@
-Allwinner Display Engine 2.0 Clock Control Binding
---------------------------------------------------
+Allwinner Display Engine 2.0/3.0 Clock Control Binding
+------------------------------------------------------
 
 Required properties :
 - compatible: must contain one of the following compatibles:
@@ -8,6 +8,7 @@ Required properties :
 		- "allwinner,sun8i-v3s-de2-clk"
 		- "allwinner,sun50i-a64-de2-clk"
 		- "allwinner,sun50i-h5-de2-clk"
+		- "allwinner,sun50i-h6-de3-clk"
 
 - reg: Must contain the registers base address and length
 - clocks: phandle to the clocks feeding the display engine subsystem.
diff --git a/include/dt-bindings/clock/sun8i-de2.h b/include/dt-bindings/clock/sun8i-de2.h
index 3bed63b524aa..7768f73b051e 100644
--- a/include/dt-bindings/clock/sun8i-de2.h
+++ b/include/dt-bindings/clock/sun8i-de2.h
@@ -15,4 +15,7 @@
 #define CLK_MIXER1		7
 #define CLK_WB			8
 
+#define CLK_BUS_ROT		9
+#define CLK_ROT			10
+
 #endif /* _DT_BINDINGS_CLOCK_SUN8I_DE2_H_ */
diff --git a/include/dt-bindings/reset/sun8i-de2.h b/include/dt-bindings/reset/sun8i-de2.h
index 9526017432f0..1c36a6ac86d6 100644
--- a/include/dt-bindings/reset/sun8i-de2.h
+++ b/include/dt-bindings/reset/sun8i-de2.h
@@ -10,5 +10,6 @@
 #define RST_MIXER0	0
 #define RST_MIXER1	1
 #define RST_WB		2
+#define RST_ROT		3
 
 #endif /* _DT_BINDINGS_RESET_SUN8I_DE2_H_ */
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 08/27] clk: sunxi-ng: Add support for H6 DE3 clocks
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (6 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 07/27] dt-bindings: clock: sun8i-de2: Add H6 DE3 clock description Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-04  9:04   ` Chen-Yu Tsai
  2018-09-02  7:26 ` [PATCH 09/27] dt-bindings: display: sun4i-drm: Add H6 display engine compatibles Jernej Skrabec
                   ` (19 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, Icenowy Zheng

Support for mixer0, mixer1, writeback and rotation units is added.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 65 ++++++++++++++++++++++++++++
 drivers/clk/sunxi-ng/ccu-sun8i-de2.h |  1 +
 2 files changed, 66 insertions(+)

diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
index bae5ee67a797..4535c1c27d27 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
@@ -31,6 +31,8 @@ static SUNXI_CCU_GATE(bus_mixer1_clk,	"bus-mixer1",	"bus-de",
 		      0x04, BIT(1), 0);
 static SUNXI_CCU_GATE(bus_wb_clk,	"bus-wb",	"bus-de",
 		      0x04, BIT(2), 0);
+static SUNXI_CCU_GATE(bus_rot_clk,	"bus-rot",	"bus-de",
+		      0x04, BIT(3), 0);
 
 static SUNXI_CCU_GATE(mixer0_clk,	"mixer0",	"mixer0-div",
 		      0x00, BIT(0), CLK_SET_RATE_PARENT);
@@ -38,6 +40,8 @@ static SUNXI_CCU_GATE(mixer1_clk,	"mixer1",	"mixer1-div",
 		      0x00, BIT(1), CLK_SET_RATE_PARENT);
 static SUNXI_CCU_GATE(wb_clk,		"wb",		"wb-div",
 		      0x00, BIT(2), CLK_SET_RATE_PARENT);
+static SUNXI_CCU_GATE(rot_clk,		"rot",		"rot-div",
+		      0x00, BIT(3), CLK_SET_RATE_PARENT);
 
 static SUNXI_CCU_M(mixer0_div_clk, "mixer0-div", "de", 0x0c, 0, 4,
 		   CLK_SET_RATE_PARENT);
@@ -45,6 +49,8 @@ static SUNXI_CCU_M(mixer1_div_clk, "mixer1-div", "de", 0x0c, 4, 4,
 		   CLK_SET_RATE_PARENT);
 static SUNXI_CCU_M(wb_div_clk, "wb-div", "de", 0x0c, 8, 4,
 		   CLK_SET_RATE_PARENT);
+static SUNXI_CCU_M(rot_div_clk, "rot-div", "de", 0x0c, 0x0c, 4,
+		   CLK_SET_RATE_PARENT);
 
 static SUNXI_CCU_M(mixer0_div_a83_clk, "mixer0-div", "pll-de", 0x0c, 0, 4,
 		   CLK_SET_RATE_PARENT);
@@ -53,6 +59,24 @@ static SUNXI_CCU_M(mixer1_div_a83_clk, "mixer1-div", "pll-de", 0x0c, 4, 4,
 static SUNXI_CCU_M(wb_div_a83_clk, "wb-div", "pll-de", 0x0c, 8, 4,
 		   CLK_SET_RATE_PARENT);
 
+static struct ccu_common *sun50i_h6_de3_clks[] = {
+	&mixer0_clk.common,
+	&mixer1_clk.common,
+	&wb_clk.common,
+
+	&bus_mixer0_clk.common,
+	&bus_mixer1_clk.common,
+	&bus_wb_clk.common,
+
+	&mixer0_div_clk.common,
+	&mixer1_div_clk.common,
+	&wb_div_clk.common,
+
+	&bus_rot_clk.common,
+	&rot_clk.common,
+	&rot_div_clk.common,
+};
+
 static struct ccu_common *sun8i_a83t_de2_clks[] = {
 	&mixer0_clk.common,
 	&mixer1_clk.common,
@@ -92,6 +116,26 @@ static struct ccu_common *sun8i_v3s_de2_clks[] = {
 	&wb_div_clk.common,
 };
 
+static struct clk_hw_onecell_data sun50i_h6_de3_hw_clks = {
+	.hws	= {
+		[CLK_MIXER0]		= &mixer0_clk.common.hw,
+		[CLK_MIXER1]		= &mixer1_clk.common.hw,
+		[CLK_WB]		= &wb_clk.common.hw,
+		[CLK_ROT]		= &rot_clk.common.hw,
+
+		[CLK_BUS_MIXER0]	= &bus_mixer0_clk.common.hw,
+		[CLK_BUS_MIXER1]	= &bus_mixer1_clk.common.hw,
+		[CLK_BUS_WB]		= &bus_wb_clk.common.hw,
+		[CLK_BUS_ROT]		= &bus_rot_clk.common.hw,
+
+		[CLK_MIXER0_DIV]	= &mixer0_div_clk.common.hw,
+		[CLK_MIXER1_DIV]	= &mixer1_div_clk.common.hw,
+		[CLK_WB_DIV]		= &wb_div_clk.common.hw,
+		[CLK_ROT_DIV]		= &rot_div_clk.common.hw,
+	},
+	.num	= 12,
+};
+
 static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = {
 	.hws	= {
 		[CLK_MIXER0]		= &mixer0_clk.common.hw,
@@ -156,6 +200,13 @@ static struct ccu_reset_map sun50i_a64_de2_resets[] = {
 	[RST_WB]	= { 0x08, BIT(2) },
 };
 
+static struct ccu_reset_map sun50i_h6_de3_resets[] = {
+	[RST_MIXER0]	= { 0x08, BIT(0) },
+	[RST_MIXER1]	= { 0x08, BIT(1) },
+	[RST_WB]	= { 0x08, BIT(2) },
+	[RST_ROT]	= { 0x08, BIT(3) },
+};
+
 static const struct sunxi_ccu_desc sun8i_a83t_de2_clk_desc = {
 	.ccu_clks	= sun8i_a83t_de2_clks,
 	.num_ccu_clks	= ARRAY_SIZE(sun8i_a83t_de2_clks),
@@ -186,6 +237,16 @@ static const struct sunxi_ccu_desc sun50i_a64_de2_clk_desc = {
 	.num_resets	= ARRAY_SIZE(sun50i_a64_de2_resets),
 };
 
+static const struct sunxi_ccu_desc sun50i_h6_de3_clk_desc = {
+	.ccu_clks	= sun50i_h6_de3_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun50i_h6_de3_clks),
+
+	.hw_clks	= &sun50i_h6_de3_hw_clks,
+
+	.resets		= sun50i_h6_de3_resets,
+	.num_resets	= ARRAY_SIZE(sun50i_h6_de3_resets),
+};
+
 static const struct sunxi_ccu_desc sun8i_v3s_de2_clk_desc = {
 	.ccu_clks	= sun8i_v3s_de2_clks,
 	.num_ccu_clks	= ARRAY_SIZE(sun8i_v3s_de2_clks),
@@ -296,6 +357,10 @@ static const struct of_device_id sunxi_de2_clk_ids[] = {
 		.compatible = "allwinner,sun50i-h5-de2-clk",
 		.data = &sun50i_a64_de2_clk_desc,
 	},
+	{
+		.compatible = "allwinner,sun50i-h6-de3-clk",
+		.data = &sun50i_h6_de3_clk_desc,
+	},
 	{ }
 };
 
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.h b/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
index 530c006e0ae9..27bd88539f42 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
@@ -22,6 +22,7 @@
 #define CLK_MIXER0_DIV	3
 #define CLK_MIXER1_DIV	4
 #define CLK_WB_DIV	5
+#define CLK_ROT_DIV	11
 
 #define CLK_NUMBER	(CLK_WB + 1)
 
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 09/27] dt-bindings: display: sun4i-drm: Add H6 display engine compatibles
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (7 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 08/27] clk: sunxi-ng: Add support for H6 DE3 clocks Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
       [not found]   ` <5b9f3f4d.1c69fb81.c776b.ee42@mx.google.com>
  2018-09-02  7:26 ` [PATCH 10/27] drm/sun4i: Add compatible for H6 display engine Jernej Skrabec
                   ` (18 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

This commit adds compatibles used in H6 display pipeline, namely for
display engine, mixer and TV TCON.

H6 display engine is somewhat similar to R40, just less TCONs and
mixer support more features.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 .../devicetree/bindings/display/sunxi/sun4i-drm.txt          | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index f8773ecb7525..dec2f8a6da9c 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -151,6 +151,7 @@ Required properties:
    * allwinner,sun8i-v3s-tcon
    * allwinner,sun9i-a80-tcon-lcd
    * allwinner,sun9i-a80-tcon-tv
+   * allwinner,sun50i-h6-tcon-tv, allwinner,sun8i-r40-tcon-tv
  - reg: base address and size of memory-mapped region
  - interrupts: interrupt associated to this IP
  - clocks: phandles to the clocks feeding the TCON.
@@ -370,6 +371,7 @@ Required properties:
     * allwinner,sun8i-a83t-de2-mixer-1
     * allwinner,sun8i-h3-de2-mixer-0
     * allwinner,sun8i-v3s-de2-mixer
+    * allwinner,sun50i-h6-de3-mixer-0
   - reg: base address and size of the memory-mapped region.
   - clocks: phandles to the clocks feeding the mixer
     * bus: the mixer interface clock
@@ -403,9 +405,10 @@ Required properties:
     * allwinner,sun8i-r40-display-engine
     * allwinner,sun8i-v3s-display-engine
     * allwinner,sun9i-a80-display-engine
+    * allwinner,sun50i-h6-display-engine
 
   - allwinner,pipelines: list of phandle to the display engine
-    frontends (DE 1.0) or mixers (DE 2.0) available.
+    frontends (DE 1.0) or mixers (DE 2.0/3.0) available.
 
 Example:
 
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 10/27] drm/sun4i: Add compatible for H6 display engine
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (8 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 09/27] dt-bindings: display: sun4i-drm: Add H6 display engine compatibles Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-03 12:18   ` Maxime Ripard
  2018-09-02  7:26 ` [PATCH 11/27] drm/sun4i: Rework DE2 register defines Jernej Skrabec
                   ` (17 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

H6 is first Allwinner SoC which supports 10 bit colors, HDR and AFBC.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun4i_drv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index dd19d674055c..e5731d092e1a 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -410,6 +410,7 @@ static int sun4i_drv_remove(struct platform_device *pdev)
 
 static const struct of_device_id sun4i_drv_of_table[] = {
 	{ .compatible = "allwinner,sun4i-a10-display-engine" },
+	{ .compatible = "allwinner,sun50i-h6-display-engine" },
 	{ .compatible = "allwinner,sun5i-a10s-display-engine" },
 	{ .compatible = "allwinner,sun5i-a13-display-engine" },
 	{ .compatible = "allwinner,sun6i-a31-display-engine" },
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 11/27] drm/sun4i: Rework DE2 register defines
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (9 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 10/27] drm/sun4i: Add compatible for H6 display engine Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-22 12:32   ` [linux-sunxi] " Chen-Yu Tsai
  2018-09-02  7:26 ` [PATCH 12/27] drm/sun4i: Add basic support for DE3 Jernej Skrabec
                   ` (16 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, Icenowy Zheng

Most, if not all, registers found in DE2 still exists in DE3. However,
units are on different base addresses.

To prepare for addition of DE3 support, registers macros are reworked so
they take base address as parameter.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
[rebased]
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 drivers/gpu/drm/sun4i/sun8i_mixer.c     | 14 ++++---
 drivers/gpu/drm/sun4i/sun8i_mixer.h     | 44 +++++++++++++-------
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c  | 47 ++++++++++++++--------
 drivers/gpu/drm/sun4i/sun8i_ui_layer.h  | 37 +++++++++--------
 drivers/gpu/drm/sun4i/sun8i_ui_scaler.c | 41 +++++++++++--------
 drivers/gpu/drm/sun4i/sun8i_ui_scaler.h | 27 +++++--------
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c  | 47 ++++++++++++++--------
 drivers/gpu/drm/sun4i/sun8i_vi_layer.h  | 23 ++++++-----
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 53 +++++++++++++++----------
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.h | 45 ++++++++++-----------
 10 files changed, 219 insertions(+), 159 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index fc3713608f78..743941a33d88 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -368,6 +368,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 	struct sun8i_mixer *mixer;
 	struct resource *res;
 	void __iomem *regs;
+	unsigned int base;
 	int plane_cnt;
 	int i, ret;
 
@@ -456,6 +457,8 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 
 	list_add_tail(&mixer->engine.list, &drv->engine_list);
 
+	base = sun8i_blender_base(mixer);
+
 	/* Reset the registers */
 	for (i = 0x0; i < 0x20000; i += 4)
 		regmap_write(mixer->engine.regs, i, 0);
@@ -465,24 +468,25 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 		     SUN8I_MIXER_GLOBAL_CTL_RT_EN);
 
 	/* Set background color to black */
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR,
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR(base),
 		     SUN8I_MIXER_BLEND_COLOR_BLACK);
 
 	/*
 	 * Set fill color of bottom plane to black. Generally not needed
 	 * except when VI plane is at bottom (zpos = 0) and enabled.
 	 */
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL,
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
 		     SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
-	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(0),
+	regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0),
 		     SUN8I_MIXER_BLEND_COLOR_BLACK);
 
 	plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num;
 	for (i = 0; i < plane_cnt; i++)
-		regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_MODE(i),
+		regmap_write(mixer->engine.regs,
+			     SUN8I_MIXER_BLEND_MODE(base, i),
 			     SUN8I_MIXER_BLEND_MODE_DEF);
 
-	regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL,
+	regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base),
 			   SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0);
 
 	return 0;
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index 406c42e752d7..020b0a097c84 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -29,20 +29,24 @@
 
 #define SUN8I_MIXER_GLOBAL_DBUFF_ENABLE		BIT(0)
 
-#define SUN8I_MIXER_BLEND_PIPE_CTL		0x1000
-#define SUN8I_MIXER_BLEND_ATTR_FCOLOR(x)	(0x1004 + 0x10 * (x) + 0x0)
-#define SUN8I_MIXER_BLEND_ATTR_INSIZE(x)	(0x1004 + 0x10 * (x) + 0x4)
-#define SUN8I_MIXER_BLEND_ATTR_COORD(x)		(0x1004 + 0x10 * (x) + 0x8)
-#define SUN8I_MIXER_BLEND_ROUTE			0x1080
-#define SUN8I_MIXER_BLEND_PREMULTIPLY		0x1084
-#define SUN8I_MIXER_BLEND_BKCOLOR		0x1088
-#define SUN8I_MIXER_BLEND_OUTSIZE		0x108c
-#define SUN8I_MIXER_BLEND_MODE(x)		(0x1090 + 0x04 * (x))
-#define SUN8I_MIXER_BLEND_CK_CTL		0x10b0
-#define SUN8I_MIXER_BLEND_CK_CFG		0x10b4
-#define SUN8I_MIXER_BLEND_CK_MAX(x)		(0x10c0 + 0x04 * (x))
-#define SUN8I_MIXER_BLEND_CK_MIN(x)		(0x10e0 + 0x04 * (x))
-#define SUN8I_MIXER_BLEND_OUTCTL		0x10fc
+#define DE2_BLD_BASE				0x1000
+#define DE2_CH_BASE				0x2000
+#define DE2_CH_SIZE				0x1000
+
+#define SUN8I_MIXER_BLEND_PIPE_CTL(base)	((base) + 0)
+#define SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, x)	((base) + 0x4 + 0x10 * (x))
+#define SUN8I_MIXER_BLEND_ATTR_INSIZE(base, x)	((base) + 0x8 + 0x10 * (x))
+#define SUN8I_MIXER_BLEND_ATTR_COORD(base, x)	((base) + 0xC + 0x10 * (x))
+#define SUN8I_MIXER_BLEND_ROUTE(base)		((base) + 0x80)
+#define SUN8I_MIXER_BLEND_PREMULTIPLY(base)	((base) + 0x84)
+#define SUN8I_MIXER_BLEND_BKCOLOR(base)		((base) + 0x88)
+#define SUN8I_MIXER_BLEND_OUTSIZE(base)		((base) + 0x8c)
+#define SUN8I_MIXER_BLEND_MODE(base, x)		((base) + 0x90 + 0x04 * (x))
+#define SUN8I_MIXER_BLEND_CK_CTL(base)		((base) + 0xb0)
+#define SUN8I_MIXER_BLEND_CK_CFG(base)		((base) + 0xb4)
+#define SUN8I_MIXER_BLEND_CK_MAX(base, x)	((base) + 0xc0 + 0x04 * (x))
+#define SUN8I_MIXER_BLEND_CK_MIN(base, x)	((base) + 0xe0 + 0x04 * (x))
+#define SUN8I_MIXER_BLEND_OUTCTL(base)		((base) + 0xfc)
 
 #define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK	GENMASK(12, 8)
 #define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe)	BIT(8 + pipe)
@@ -153,5 +157,17 @@ engine_to_sun8i_mixer(struct sunxi_engine *engine)
 	return container_of(engine, struct sun8i_mixer, engine);
 }
 
+static inline u32
+sun8i_blender_base(struct sun8i_mixer *mixer)
+{
+	return DE2_BLD_BASE;
+}
+
+static inline u32
+sun8i_channel_base(struct sun8i_mixer *mixer, int channel)
+{
+	return DE2_CH_BASE + channel * DE2_CH_SIZE;
+}
+
 const struct de2_fmt_info *sun8i_mixer_format_info(u32 format);
 #endif /* _SUN8I_MIXER_H_ */
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
index 28c15c6ef1ef..e3fc8fa920fb 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
@@ -30,7 +30,10 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
 				  int overlay, bool enable, unsigned int zpos,
 				  unsigned int old_zpos)
 {
-	u32 val;
+	u32 val, bld_base, ch_base;
+
+	bld_base = sun8i_blender_base(mixer);
+	ch_base = sun8i_channel_base(mixer, channel);
 
 	DRM_DEBUG_DRIVER("%sabling channel %d overlay %d\n",
 			 enable ? "En" : "Dis", channel, overlay);
@@ -41,17 +44,17 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
 		val = 0;
 
 	regmap_update_bits(mixer->engine.regs,
-			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(channel, overlay),
+			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay),
 			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val);
 
 	if (!enable || zpos != old_zpos) {
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_PIPE_CTL,
+				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
 				   SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
 				   0);
 
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_ROUTE,
+				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
 				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
 				   0);
 	}
@@ -60,12 +63,13 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
 		val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
 
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_PIPE_CTL, val, val);
+				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
+				   val, val);
 
 		val = channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos);
 
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_ROUTE,
+				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
 				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos),
 				   val);
 	}
@@ -77,12 +81,16 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 {
 	struct drm_plane_state *state = plane->state;
 	u32 src_w, src_h, dst_w, dst_h;
+	u32 bld_base, ch_base;
 	u32 outsize, insize;
 	u32 hphase, vphase;
 
 	DRM_DEBUG_DRIVER("Updating UI channel %d overlay %d\n",
 			 channel, overlay);
 
+	bld_base = sun8i_blender_base(mixer);
+	ch_base = sun8i_channel_base(mixer, channel);
+
 	src_w = drm_rect_width(&state->src) >> 16;
 	src_h = drm_rect_height(&state->src) >> 16;
 	dst_w = drm_rect_width(&state->dst);
@@ -103,8 +111,8 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 		regmap_write(mixer->engine.regs,
 			     SUN8I_MIXER_GLOBAL_SIZE,
 			     outsize);
-		regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_OUTSIZE,
-			     outsize);
+		regmap_write(mixer->engine.regs,
+			     SUN8I_MIXER_BLEND_OUTSIZE(bld_base), outsize);
 
 		if (state->crtc)
 			interlaced = state->crtc->state->adjusted_mode.flags
@@ -116,7 +124,7 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 			val = 0;
 
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_OUTCTL,
+				   SUN8I_MIXER_BLEND_OUTCTL(bld_base),
 				   SUN8I_MIXER_BLEND_OUTCTL_INTERLACED,
 				   val);
 
@@ -129,10 +137,10 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 			 state->src.x1 >> 16, state->src.y1 >> 16);
 	DRM_DEBUG_DRIVER("Layer source size W: %d H: %d\n", src_w, src_h);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_CHAN_UI_LAYER_SIZE(channel, overlay),
+		     SUN8I_MIXER_CHAN_UI_LAYER_SIZE(ch_base, overlay),
 		     insize);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_CHAN_UI_OVL_SIZE(channel),
+		     SUN8I_MIXER_CHAN_UI_OVL_SIZE(ch_base),
 		     insize);
 
 	if (insize != outsize || hphase || vphase) {
@@ -156,10 +164,10 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 			 state->dst.x1, state->dst.y1);
 	DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_BLEND_ATTR_COORD(zpos),
+		     SUN8I_MIXER_BLEND_ATTR_COORD(bld_base, zpos),
 		     SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1));
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_BLEND_ATTR_INSIZE(zpos),
+		     SUN8I_MIXER_BLEND_ATTR_INSIZE(bld_base, zpos),
 		     outsize);
 
 	return 0;
@@ -170,7 +178,9 @@ static int sun8i_ui_layer_update_formats(struct sun8i_mixer *mixer, int channel,
 {
 	struct drm_plane_state *state = plane->state;
 	const struct de2_fmt_info *fmt_info;
-	u32 val;
+	u32 val, ch_base;
+
+	ch_base = sun8i_channel_base(mixer, channel);
 
 	fmt_info = sun8i_mixer_format_info(state->fb->format->format);
 	if (!fmt_info || !fmt_info->rgb) {
@@ -180,7 +190,7 @@ static int sun8i_ui_layer_update_formats(struct sun8i_mixer *mixer, int channel,
 
 	val = fmt_info->de2_fmt << SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_OFFSET;
 	regmap_update_bits(mixer->engine.regs,
-			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(channel, overlay),
+			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay),
 			   SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_MASK, val);
 
 	return 0;
@@ -193,8 +203,11 @@ static int sun8i_ui_layer_update_buffer(struct sun8i_mixer *mixer, int channel,
 	struct drm_framebuffer *fb = state->fb;
 	struct drm_gem_cma_object *gem;
 	dma_addr_t paddr;
+	u32 ch_base;
 	int bpp;
 
+	ch_base = sun8i_channel_base(mixer, channel);
+
 	/* Get the physical address of the buffer in memory */
 	gem = drm_fb_cma_get_gem_obj(fb, 0);
 
@@ -211,13 +224,13 @@ static int sun8i_ui_layer_update_buffer(struct sun8i_mixer *mixer, int channel,
 	/* Set the line width */
 	DRM_DEBUG_DRIVER("Layer line width: %d bytes\n", fb->pitches[0]);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_CHAN_UI_LAYER_PITCH(channel, overlay),
+		     SUN8I_MIXER_CHAN_UI_LAYER_PITCH(ch_base, overlay),
 		     fb->pitches[0]);
 
 	DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr);
 
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(channel, overlay),
+		     SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(ch_base, overlay),
 		     lower_32_bits(paddr));
 
 	return 0;
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.h b/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
index 123b15ea9918..f4389cf0ba20 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
@@ -18,23 +18,26 @@
 
 #include <drm/drm_plane.h>
 
-#define SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch, layer) \
-			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x0)
-#define SUN8I_MIXER_CHAN_UI_LAYER_SIZE(ch, layer) \
-			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x4)
-#define SUN8I_MIXER_CHAN_UI_LAYER_COORD(ch, layer) \
-			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x8)
-#define SUN8I_MIXER_CHAN_UI_LAYER_PITCH(ch, layer) \
-			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0xc)
-#define SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(ch, layer) \
-			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x10)
-#define SUN8I_MIXER_CHAN_UI_LAYER_BOT_LADDR(ch, layer) \
-			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x14)
-#define SUN8I_MIXER_CHAN_UI_LAYER_FCOLOR(ch, layer) \
-			(0x2000 + 0x1000 * (ch) + 0x20 * (layer) + 0x18)
-#define SUN8I_MIXER_CHAN_UI_TOP_HADDR(ch)	(0x2000 + 0x1000 * (ch) + 0x80)
-#define SUN8I_MIXER_CHAN_UI_BOT_HADDR(ch)	(0x2000 + 0x1000 * (ch) + 0x84)
-#define SUN8I_MIXER_CHAN_UI_OVL_SIZE(ch)	(0x2000 + 0x1000 * (ch) + 0x88)
+#define SUN8I_MIXER_CHAN_UI_LAYER_ATTR(base, layer) \
+			((base) + 0x20 * (layer) + 0x0)
+#define SUN8I_MIXER_CHAN_UI_LAYER_SIZE(base, layer) \
+			((base) + 0x20 * (layer) + 0x4)
+#define SUN8I_MIXER_CHAN_UI_LAYER_COORD(base, layer) \
+			((base) + 0x20 * (layer) + 0x8)
+#define SUN8I_MIXER_CHAN_UI_LAYER_PITCH(base, layer) \
+			((base) + 0x20 * (layer) + 0xc)
+#define SUN8I_MIXER_CHAN_UI_LAYER_TOP_LADDR(base, layer) \
+			((base) + 0x20 * (layer) + 0x10)
+#define SUN8I_MIXER_CHAN_UI_LAYER_BOT_LADDR(base, layer) \
+			((base) + 0x20 * (layer) + 0x14)
+#define SUN8I_MIXER_CHAN_UI_LAYER_FCOLOR(base, layer) \
+			((base) + 0x20 * (layer) + 0x18)
+#define SUN8I_MIXER_CHAN_UI_TOP_HADDR(base) \
+			((base) + 0x80)
+#define SUN8I_MIXER_CHAN_UI_BOT_HADDR(base) \
+			((base) + 0x84)
+#define SUN8I_MIXER_CHAN_UI_OVL_SIZE(base) \
+			((base) + 0x88)
 
 #define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN		BIT(0)
 #define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_MASK	GENMASK(2, 1)
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
index 6bb2aa164c8e..c68eab8a748f 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
@@ -10,6 +10,7 @@
  */
 
 #include "sun8i_ui_scaler.h"
+#include "sun8i_vi_scaler.h"
 
 static const u32 lan2coefftab16[240] = {
 	0x00004000, 0x00033ffe, 0x00063efc, 0x000a3bfb,
@@ -88,6 +89,14 @@ static const u32 lan2coefftab16[240] = {
 	0x0b1c1603, 0x0d1c1502, 0x0e1d1401, 0x0f1d1301,
 };
 
+static inline u32 sun8i_ui_scaler_base(struct sun8i_mixer *mixer, int channel)
+{
+	int vi_num = mixer->cfg->vi_num;
+
+	return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * vi_num +
+	       DE2_UI_SCALER_SIZE * (channel - vi_num);
+}
+
 static int sun8i_ui_scaler_coef_index(unsigned int step)
 {
 	unsigned int scale, int_part, float_part;
@@ -114,33 +123,35 @@ static int sun8i_ui_scaler_coef_index(unsigned int step)
 
 void sun8i_ui_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable)
 {
-	int vi_cnt = mixer->cfg->vi_num;
-	u32 val;
+	u32 val, base;
 
-	if (WARN_ON(layer < vi_cnt))
+	if (WARN_ON(layer < mixer->cfg->vi_num))
 		return;
 
+	base = sun8i_ui_scaler_base(mixer, layer);
+
 	if (enable)
 		val = SUN8I_SCALER_GSU_CTRL_EN |
 		      SUN8I_SCALER_GSU_CTRL_COEFF_RDY;
 	else
 		val = 0;
 
-	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_GSU_CTRL(vi_cnt, layer - vi_cnt), val);
+	regmap_write(mixer->engine.regs, SUN8I_SCALER_GSU_CTRL(base), val);
 }
 
 void sun8i_ui_scaler_setup(struct sun8i_mixer *mixer, int layer,
 			   u32 src_w, u32 src_h, u32 dst_w, u32 dst_h,
 			   u32 hscale, u32 vscale, u32 hphase, u32 vphase)
 {
-	int vi_cnt = mixer->cfg->vi_num;
 	u32 insize, outsize;
 	int i, offset;
+	u32 base;
 
-	if (WARN_ON(layer < vi_cnt))
+	if (WARN_ON(layer < mixer->cfg->vi_num))
 		return;
 
+	base = sun8i_ui_scaler_base(mixer, layer);
+
 	hphase <<= SUN8I_UI_SCALER_PHASE_FRAC - 16;
 	vphase <<= SUN8I_UI_SCALER_PHASE_FRAC - 16;
 	hscale <<= SUN8I_UI_SCALER_SCALE_FRAC - 16;
@@ -149,24 +160,22 @@ void sun8i_ui_scaler_setup(struct sun8i_mixer *mixer, int layer,
 	insize = SUN8I_UI_SCALER_SIZE(src_w, src_h);
 	outsize = SUN8I_UI_SCALER_SIZE(dst_w, dst_h);
 
-	layer -= vi_cnt;
-
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_GSU_OUTSIZE(vi_cnt, layer), outsize);
+		     SUN8I_SCALER_GSU_OUTSIZE(base), outsize);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_GSU_INSIZE(vi_cnt, layer), insize);
+		     SUN8I_SCALER_GSU_INSIZE(base), insize);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_GSU_HSTEP(vi_cnt, layer), hscale);
+		     SUN8I_SCALER_GSU_HSTEP(base), hscale);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_GSU_VSTEP(vi_cnt, layer), vscale);
+		     SUN8I_SCALER_GSU_VSTEP(base), vscale);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_GSU_HPHASE(vi_cnt, layer), hphase);
+		     SUN8I_SCALER_GSU_HPHASE(base), hphase);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_GSU_VPHASE(vi_cnt, layer), vphase);
+		     SUN8I_SCALER_GSU_VPHASE(base), vphase);
 	offset = sun8i_ui_scaler_coef_index(hscale) *
 			SUN8I_UI_SCALER_COEFF_COUNT;
 	for (i = 0; i < SUN8I_UI_SCALER_COEFF_COUNT; i++)
 		regmap_write(mixer->engine.regs,
-			     SUN8I_SCALER_GSU_HCOEFF(vi_cnt, layer, i),
+			     SUN8I_SCALER_GSU_HCOEFF(base, i),
 			     lan2coefftab16[offset + i]);
 }
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.h b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.h
index 86295be8be78..6c3516b75341 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.h
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.h
@@ -11,6 +11,8 @@
 
 #include "sun8i_mixer.h"
 
+#define DE2_UI_SCALER_SIZE 0x10000
+
 /* this two macros assumes 16 fractional bits which is standard in DRM */
 #define SUN8I_UI_SCALER_SCALE_MIN		1
 #define SUN8I_UI_SCALER_SCALE_MAX		((1UL << 20) - 1)
@@ -20,23 +22,14 @@
 #define SUN8I_UI_SCALER_COEFF_COUNT		16
 #define SUN8I_UI_SCALER_SIZE(w, h)		(((h) - 1) << 16 | ((w) - 1))
 
-#define SUN8I_SCALER_GSU_CTRL(vi_cnt, ui_idx) \
-	(0x20000 + 0x20000 * (vi_cnt) + 0x10000 * (ui_idx) + 0x0)
-#define SUN8I_SCALER_GSU_OUTSIZE(vi_cnt, ui_idx) \
-	(0x20000 + 0x20000 * (vi_cnt) + 0x10000 * (ui_idx) + 0x40)
-#define SUN8I_SCALER_GSU_INSIZE(vi_cnt, ui_idx) \
-	(0x20000 + 0x20000 * (vi_cnt) + 0x10000 * (ui_idx) + 0x80)
-#define SUN8I_SCALER_GSU_HSTEP(vi_cnt, ui_idx) \
-	(0x20000 + 0x20000 * (vi_cnt) + 0x10000 * (ui_idx) + 0x88)
-#define SUN8I_SCALER_GSU_VSTEP(vi_cnt, ui_idx) \
-	(0x20000 + 0x20000 * (vi_cnt) + 0x10000 * (ui_idx) + 0x8c)
-#define SUN8I_SCALER_GSU_HPHASE(vi_cnt, ui_idx) \
-	(0x20000 + 0x20000 * (vi_cnt) + 0x10000 * (ui_idx) + 0x90)
-#define SUN8I_SCALER_GSU_VPHASE(vi_cnt, ui_idx) \
-	(0x20000 + 0x20000 * (vi_cnt) + 0x10000 * (ui_idx) + 0x98)
-#define SUN8I_SCALER_GSU_HCOEFF(vi_cnt, ui_idx, index) \
-	(0x20000 + 0x20000 * (vi_cnt) + 0x10000 * (ui_idx) + 0x200 + \
-	0x4 * (index))
+#define SUN8I_SCALER_GSU_CTRL(base)		((base) + 0x0)
+#define SUN8I_SCALER_GSU_OUTSIZE(base)		((base) + 0x40)
+#define SUN8I_SCALER_GSU_INSIZE(base)		((base) + 0x80)
+#define SUN8I_SCALER_GSU_HSTEP(base)		((base) + 0x88)
+#define SUN8I_SCALER_GSU_VSTEP(base)		((base) + 0x8c)
+#define SUN8I_SCALER_GSU_HPHASE(base)		((base) + 0x90)
+#define SUN8I_SCALER_GSU_VPHASE(base)		((base) + 0x98)
+#define SUN8I_SCALER_GSU_HCOEFF(base, index)	((base) + 0x200 + 0x4 * (index))
 
 #define SUN8I_SCALER_GSU_CTRL_EN		BIT(0)
 #define SUN8I_SCALER_GSU_CTRL_COEFF_RDY		BIT(4)
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
index f4fe97813f94..79811eae3735 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
@@ -24,7 +24,10 @@ static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel,
 				  int overlay, bool enable, unsigned int zpos,
 				  unsigned int old_zpos)
 {
-	u32 val;
+	u32 val, bld_base, ch_base;
+
+	bld_base = sun8i_blender_base(mixer);
+	ch_base = sun8i_channel_base(mixer, channel);
 
 	DRM_DEBUG_DRIVER("%sabling VI channel %d overlay %d\n",
 			 enable ? "En" : "Dis", channel, overlay);
@@ -35,17 +38,17 @@ static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel,
 		val = 0;
 
 	regmap_update_bits(mixer->engine.regs,
-			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(channel, overlay),
+			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay),
 			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN, val);
 
 	if (!enable || zpos != old_zpos) {
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_PIPE_CTL,
+				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
 				   SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
 				   0);
 
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_ROUTE,
+				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
 				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
 				   0);
 	}
@@ -54,12 +57,13 @@ static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel,
 		val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
 
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_PIPE_CTL, val, val);
+				   SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
+				   val, val);
 
 		val = channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos);
 
 		regmap_update_bits(mixer->engine.regs,
-				   SUN8I_MIXER_BLEND_ROUTE,
+				   SUN8I_MIXER_BLEND_ROUTE(bld_base),
 				   SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos),
 				   val);
 	}
@@ -72,6 +76,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 	struct drm_plane_state *state = plane->state;
 	const struct drm_format_info *format = state->fb->format;
 	u32 src_w, src_h, dst_w, dst_h;
+	u32 bld_base, ch_base;
 	u32 outsize, insize;
 	u32 hphase, vphase;
 	bool subsampled;
@@ -79,6 +84,9 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 	DRM_DEBUG_DRIVER("Updating VI channel %d overlay %d\n",
 			 channel, overlay);
 
+	bld_base = sun8i_blender_base(mixer);
+	ch_base = sun8i_channel_base(mixer, channel);
+
 	src_w = drm_rect_width(&state->src) >> 16;
 	src_h = drm_rect_height(&state->src) >> 16;
 	dst_w = drm_rect_width(&state->dst);
@@ -115,10 +123,10 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 			 (state->src.y1 >> 16) & ~(format->vsub - 1));
 	DRM_DEBUG_DRIVER("Layer source size W: %d H: %d\n", src_w, src_h);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_CHAN_VI_LAYER_SIZE(channel, overlay),
+		     SUN8I_MIXER_CHAN_VI_LAYER_SIZE(ch_base, overlay),
 		     insize);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_CHAN_VI_OVL_SIZE(channel),
+		     SUN8I_MIXER_CHAN_VI_OVL_SIZE(ch_base),
 		     insize);
 
 	/*
@@ -149,10 +157,10 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 			 state->dst.x1, state->dst.y1);
 	DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_BLEND_ATTR_COORD(zpos),
+		     SUN8I_MIXER_BLEND_ATTR_COORD(bld_base, zpos),
 		     SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1));
 	regmap_write(mixer->engine.regs,
-		     SUN8I_MIXER_BLEND_ATTR_INSIZE(zpos),
+		     SUN8I_MIXER_BLEND_ATTR_INSIZE(bld_base, zpos),
 		     outsize);
 
 	return 0;
@@ -163,7 +171,9 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel,
 {
 	struct drm_plane_state *state = plane->state;
 	const struct de2_fmt_info *fmt_info;
-	u32 val;
+	u32 val, ch_base;
+
+	ch_base = sun8i_channel_base(mixer, channel);
 
 	fmt_info = sun8i_mixer_format_info(state->fb->format->format);
 	if (!fmt_info) {
@@ -173,7 +183,7 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel,
 
 	val = fmt_info->de2_fmt << SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_OFFSET;
 	regmap_update_bits(mixer->engine.regs,
-			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(channel, overlay),
+			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay),
 			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK, val);
 
 	if (fmt_info->csc != SUN8I_CSC_MODE_OFF) {
@@ -189,7 +199,7 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel,
 		val = 0;
 
 	regmap_update_bits(mixer->engine.regs,
-			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(channel, overlay),
+			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay),
 			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE, val);
 
 	return 0;
@@ -204,8 +214,11 @@ static int sun8i_vi_layer_update_buffer(struct sun8i_mixer *mixer, int channel,
 	struct drm_gem_cma_object *gem;
 	u32 dx, dy, src_x, src_y;
 	dma_addr_t paddr;
+	u32 ch_base;
 	int i;
 
+	ch_base = sun8i_channel_base(mixer, channel);
+
 	/* Adjust x and y to be dividable by subsampling factor */
 	src_x = (state->src.x1 >> 16) & ~(format->hsub - 1);
 	src_y = (state->src.y1 >> 16) & ~(format->vsub - 1);
@@ -235,17 +248,17 @@ static int sun8i_vi_layer_update_buffer(struct sun8i_mixer *mixer, int channel,
 		DRM_DEBUG_DRIVER("Layer %d. line width: %d bytes\n",
 				 i + 1, fb->pitches[i]);
 		regmap_write(mixer->engine.regs,
-			     SUN8I_MIXER_CHAN_VI_LAYER_PITCH(channel,
+			     SUN8I_MIXER_CHAN_VI_LAYER_PITCH(ch_base,
 							     overlay, i),
-	       fb->pitches[i]);
+			     fb->pitches[i]);
 
 		DRM_DEBUG_DRIVER("Setting %d. buffer address to %pad\n",
 				 i + 1, &paddr);
 
 		regmap_write(mixer->engine.regs,
-			     SUN8I_MIXER_CHAN_VI_LAYER_TOP_LADDR(channel,
+			     SUN8I_MIXER_CHAN_VI_LAYER_TOP_LADDR(ch_base,
 								 overlay, i),
-	       lower_32_bits(paddr));
+			     lower_32_bits(paddr));
 	}
 
 	return 0;
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
index 6996627a0a76..46f0237c17bb 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
@@ -12,17 +12,18 @@
 
 #include <drm/drm_plane.h>
 
-#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch, layer) \
-		(0x2000 + 0x1000 * (ch) + 0x30 * (layer) + 0x0)
-#define SUN8I_MIXER_CHAN_VI_LAYER_SIZE(ch, layer) \
-		(0x2000 + 0x1000 * (ch) + 0x30 * (layer) + 0x4)
-#define SUN8I_MIXER_CHAN_VI_LAYER_COORD(ch, layer) \
-		(0x2000 + 0x1000 * (ch) + 0x30 * (layer) + 0x8)
-#define SUN8I_MIXER_CHAN_VI_LAYER_PITCH(ch, layer, plane) \
-		(0x2000 + 0x1000 * (ch) + 0x30 * (layer) + 0xc + 4 * (plane))
-#define SUN8I_MIXER_CHAN_VI_LAYER_TOP_LADDR(ch, layer, plane) \
-		(0x2000 + 0x1000 * (ch) + 0x30 * (layer) + 0x18 + 4 * (plane))
-#define SUN8I_MIXER_CHAN_VI_OVL_SIZE(ch)	(0x2000 + 0x1000 * (ch) + 0xe8)
+#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR(base, layer) \
+		((base) + 0x30 * (layer) + 0x0)
+#define SUN8I_MIXER_CHAN_VI_LAYER_SIZE(base, layer) \
+		((base) + 0x30 * (layer) + 0x4)
+#define SUN8I_MIXER_CHAN_VI_LAYER_COORD(base, layer) \
+		((base) + 0x30 * (layer) + 0x8)
+#define SUN8I_MIXER_CHAN_VI_LAYER_PITCH(base, layer, plane) \
+		((base) + 0x30 * (layer) + 0xc + 4 * (plane))
+#define SUN8I_MIXER_CHAN_VI_LAYER_TOP_LADDR(base, layer, plane) \
+		((base) + 0x30 * (layer) + 0x18 + 4 * (plane))
+#define SUN8I_MIXER_CHAN_VI_OVL_SIZE(base) \
+		((base) + 0xe8)
 
 #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN		BIT(0)
 /* RGB mode should be set for RGB formats and cleared for YCbCr */
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
index d3f1acb234b7..8697afc36023 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
@@ -833,6 +833,11 @@ static const u32 bicubic4coefftab32[480] = {
 	0x1012110d, 0x1012110d, 0x1013110c, 0x1013110c,
 };
 
+static inline u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel)
+{
+	return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * channel;
+}
+
 static int sun8i_vi_scaler_coef_index(unsigned int step)
 {
 	unsigned int scale, int_part, float_part;
@@ -857,7 +862,7 @@ static int sun8i_vi_scaler_coef_index(unsigned int step)
 	}
 }
 
-static void sun8i_vi_scaler_set_coeff(struct regmap *map, int layer,
+static void sun8i_vi_scaler_set_coeff(struct regmap *map, u32 base,
 				      u32 hstep, u32 vstep,
 				      const struct drm_format_info *format)
 {
@@ -877,29 +882,31 @@ static void sun8i_vi_scaler_set_coeff(struct regmap *map, int layer,
 	offset = sun8i_vi_scaler_coef_index(hstep) *
 			SUN8I_VI_SCALER_COEFF_COUNT;
 	for (i = 0; i < SUN8I_VI_SCALER_COEFF_COUNT; i++) {
-		regmap_write(map, SUN8I_SCALER_VSU_YHCOEFF0(layer, i),
+		regmap_write(map, SUN8I_SCALER_VSU_YHCOEFF0(base, i),
 			     lan3coefftab32_left[offset + i]);
-		regmap_write(map, SUN8I_SCALER_VSU_YHCOEFF1(layer, i),
+		regmap_write(map, SUN8I_SCALER_VSU_YHCOEFF1(base, i),
 			     lan3coefftab32_right[offset + i]);
-		regmap_write(map, SUN8I_SCALER_VSU_CHCOEFF0(layer, i),
+		regmap_write(map, SUN8I_SCALER_VSU_CHCOEFF0(base, i),
 			     ch_left[offset + i]);
-		regmap_write(map, SUN8I_SCALER_VSU_CHCOEFF1(layer, i),
+		regmap_write(map, SUN8I_SCALER_VSU_CHCOEFF1(base, i),
 			     ch_right[offset + i]);
 	}
 
 	offset = sun8i_vi_scaler_coef_index(hstep) *
 			SUN8I_VI_SCALER_COEFF_COUNT;
 	for (i = 0; i < SUN8I_VI_SCALER_COEFF_COUNT; i++) {
-		regmap_write(map, SUN8I_SCALER_VSU_YVCOEFF(layer, i),
+		regmap_write(map, SUN8I_SCALER_VSU_YVCOEFF(base, i),
 			     lan2coefftab32[offset + i]);
-		regmap_write(map, SUN8I_SCALER_VSU_CVCOEFF(layer, i),
+		regmap_write(map, SUN8I_SCALER_VSU_CVCOEFF(base, i),
 			     cy[offset + i]);
 	}
 }
 
 void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable)
 {
-	u32 val;
+	u32 val, base;
+
+	base = sun8i_vi_scaler_base(mixer, layer);
 
 	if (enable)
 		val = SUN8I_SCALER_VSU_CTRL_EN |
@@ -907,7 +914,8 @@ void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable)
 	else
 		val = 0;
 
-	regmap_write(mixer->engine.regs, SUN8I_SCALER_VSU_CTRL(layer), val);
+	regmap_write(mixer->engine.regs,
+		     SUN8I_SCALER_VSU_CTRL(base), val);
 }
 
 void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
@@ -917,6 +925,9 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
 {
 	u32 chphase, cvphase;
 	u32 insize, outsize;
+	u32 base;
+
+	base = sun8i_vi_scaler_base(mixer, layer);
 
 	hphase <<= SUN8I_VI_SCALER_PHASE_FRAC - 16;
 	vphase <<= SUN8I_VI_SCALER_PHASE_FRAC - 16;
@@ -941,31 +952,31 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
 	}
 
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_OUTSIZE(layer), outsize);
+		     SUN8I_SCALER_VSU_OUTSIZE(base), outsize);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_YINSIZE(layer), insize);
+		     SUN8I_SCALER_VSU_YINSIZE(base), insize);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_YHSTEP(layer), hscale);
+		     SUN8I_SCALER_VSU_YHSTEP(base), hscale);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_YVSTEP(layer), vscale);
+		     SUN8I_SCALER_VSU_YVSTEP(base), vscale);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_YHPHASE(layer), hphase);
+		     SUN8I_SCALER_VSU_YHPHASE(base), hphase);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_YVPHASE(layer), vphase);
+		     SUN8I_SCALER_VSU_YVPHASE(base), vphase);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_CINSIZE(layer),
+		     SUN8I_SCALER_VSU_CINSIZE(base),
 		     SUN8I_VI_SCALER_SIZE(src_w / format->hsub,
 					  src_h / format->vsub));
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_CHSTEP(layer),
+		     SUN8I_SCALER_VSU_CHSTEP(base),
 		     hscale / format->hsub);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_CVSTEP(layer),
+		     SUN8I_SCALER_VSU_CVSTEP(base),
 		     vscale / format->vsub);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_CHPHASE(layer), chphase);
+		     SUN8I_SCALER_VSU_CHPHASE(base), chphase);
 	regmap_write(mixer->engine.regs,
-		     SUN8I_SCALER_VSU_CVPHASE(layer), cvphase);
-	sun8i_vi_scaler_set_coeff(mixer->engine.regs, layer,
+		     SUN8I_SCALER_VSU_CVPHASE(base), cvphase);
+	sun8i_vi_scaler_set_coeff(mixer->engine.regs, base,
 				  hscale, vscale, format);
 }
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
index a595ab643a5a..cd015405f66d 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
@@ -12,6 +12,9 @@
 #include <drm/drm_fourcc.h>
 #include "sun8i_mixer.h"
 
+#define DE2_VI_SCALER_BASE 0x20000
+#define DE2_VI_SCALER_SIZE 0x20000
+
 /* this two macros assumes 16 fractional bits which is standard in DRM */
 #define SUN8I_VI_SCALER_SCALE_MIN		1
 #define SUN8I_VI_SCALER_SCALE_MAX		((1UL << 20) - 1)
@@ -21,30 +24,24 @@
 #define SUN8I_VI_SCALER_COEFF_COUNT		32
 #define SUN8I_VI_SCALER_SIZE(w, h)		(((h) - 1) << 16 | ((w) - 1))
 
-#define SUN8I_SCALER_VSU_CTRL(ch)	(0x20000 + 0x20000 * (ch) + 0x0)
-#define SUN8I_SCALER_VSU_OUTSIZE(ch)	(0x20000 + 0x20000 * (ch) + 0x40)
-#define SUN8I_SCALER_VSU_YINSIZE(ch)	(0x20000 + 0x20000 * (ch) + 0x80)
-#define SUN8I_SCALER_VSU_YHSTEP(ch)	(0x20000 + 0x20000 * (ch) + 0x88)
-#define SUN8I_SCALER_VSU_YVSTEP(ch)	(0x20000 + 0x20000 * (ch) + 0x8c)
-#define SUN8I_SCALER_VSU_YHPHASE(ch)	(0x20000 + 0x20000 * (ch) + 0x90)
-#define SUN8I_SCALER_VSU_YVPHASE(ch)	(0x20000 + 0x20000 * (ch) + 0x98)
-#define SUN8I_SCALER_VSU_CINSIZE(ch)	(0x20000 + 0x20000 * (ch) + 0xc0)
-#define SUN8I_SCALER_VSU_CHSTEP(ch)	(0x20000 + 0x20000 * (ch) + 0xc8)
-#define SUN8I_SCALER_VSU_CVSTEP(ch)	(0x20000 + 0x20000 * (ch) + 0xcc)
-#define SUN8I_SCALER_VSU_CHPHASE(ch)	(0x20000 + 0x20000 * (ch) + 0xd0)
-#define SUN8I_SCALER_VSU_CVPHASE(ch)	(0x20000 + 0x20000 * (ch) + 0xd8)
-#define SUN8I_SCALER_VSU_YHCOEFF0(ch, i) \
-	(0x20000 + 0x20000 * (ch) + 0x200 + 0x4 * (i))
-#define SUN8I_SCALER_VSU_YHCOEFF1(ch, i) \
-	(0x20000 + 0x20000 * (ch) + 0x300 + 0x4 * (i))
-#define SUN8I_SCALER_VSU_YVCOEFF(ch, i) \
-	(0x20000 + 0x20000 * (ch) + 0x400 + 0x4 * (i))
-#define SUN8I_SCALER_VSU_CHCOEFF0(ch, i) \
-	(0x20000 + 0x20000 * (ch) + 0x600 + 0x4 * (i))
-#define SUN8I_SCALER_VSU_CHCOEFF1(ch, i) \
-	(0x20000 + 0x20000 * (ch) + 0x700 + 0x4 * (i))
-#define SUN8I_SCALER_VSU_CVCOEFF(ch, i) \
-	(0x20000 + 0x20000 * (ch) + 0x800 + 0x4 * (i))
+#define SUN8I_SCALER_VSU_CTRL(base)		((base) + 0x0)
+#define SUN8I_SCALER_VSU_OUTSIZE(base)		((base) + 0x40)
+#define SUN8I_SCALER_VSU_YINSIZE(base)		((base) + 0x80)
+#define SUN8I_SCALER_VSU_YHSTEP(base)		((base) + 0x88)
+#define SUN8I_SCALER_VSU_YVSTEP(base)		((base) + 0x8c)
+#define SUN8I_SCALER_VSU_YHPHASE(base)		((base) + 0x90)
+#define SUN8I_SCALER_VSU_YVPHASE(base)		((base) + 0x98)
+#define SUN8I_SCALER_VSU_CINSIZE(base)		((base) + 0xc0)
+#define SUN8I_SCALER_VSU_CHSTEP(base)		((base) + 0xc8)
+#define SUN8I_SCALER_VSU_CVSTEP(base)		((base) + 0xcc)
+#define SUN8I_SCALER_VSU_CHPHASE(base)		((base) + 0xd0)
+#define SUN8I_SCALER_VSU_CVPHASE(base)		((base) + 0xd8)
+#define SUN8I_SCALER_VSU_YHCOEFF0(base, i)	((base) + 0x200 + 0x4 * (i))
+#define SUN8I_SCALER_VSU_YHCOEFF1(base, i)	((base) + 0x300 + 0x4 * (i))
+#define SUN8I_SCALER_VSU_YVCOEFF(base, i)	((base) + 0x400 + 0x4 * (i))
+#define SUN8I_SCALER_VSU_CHCOEFF0(base, i)	((base) + 0x600 + 0x4 * (i))
+#define SUN8I_SCALER_VSU_CHCOEFF1(base, i)	((base) + 0x700 + 0x4 * (i))
+#define SUN8I_SCALER_VSU_CVCOEFF(base, i)	((base) + 0x800 + 0x4 * (i))
 
 #define SUN8I_SCALER_VSU_CTRL_EN		BIT(0)
 #define SUN8I_SCALER_VSU_CTRL_COEFF_RDY		BIT(4)
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 12/27] drm/sun4i: Add basic support for DE3
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (10 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 11/27] drm/sun4i: Rework DE2 register defines Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-22 13:19   ` Chen-Yu Tsai
  2018-09-02  7:26 ` [PATCH 13/27] drm/sun4i: Add support for H6 DE3 mixer 0 Jernej Skrabec
                   ` (15 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

Display Engine 3 is an upgrade of DE2 with new features like support for
10 bit color formats and support for AFBC.

Most of DE2 code works with DE3, except some small details.

Add support for it.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_csc.c       | 96 +++++++++++++++++++++++--
 drivers/gpu/drm/sun4i/sun8i_mixer.c     | 17 ++++-
 drivers/gpu/drm/sun4i/sun8i_mixer.h     | 21 +++++-
 drivers/gpu/drm/sun4i/sun8i_ui_scaler.c |  8 ++-
 drivers/gpu/drm/sun4i/sun8i_ui_scaler.h |  1 +
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c  |  8 +++
 drivers/gpu/drm/sun4i/sun8i_vi_layer.h  |  2 +
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 34 ++++++++-
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.h | 23 ++++++
 9 files changed, 197 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c
index b14925b40ccf..101901ccf2dc 100644
--- a/drivers/gpu/drm/sun4i/sun8i_csc.c
+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
@@ -34,6 +34,34 @@ static const u32 yvu2rgb[] = {
 	0x000004A8, 0x00000000, 0x00000813, 0xFFFBAC4A,
 };
 
+/*
+ * DE3 has a bit different CSC units. Factors are in two's complement format.
+ * First three have 17 bits for fractinal part and last two 2 bits. First
+ * three values in each line are multiplication factor, 4th is difference,
+ * which is subtracted from the input value before the multiplication and
+ * last value is constant, which is added at the end.
+ *
+ * x' = c00 * (x + d0) + c01 * (y + d1) + c02 * (z + d2) + const0
+ * y' = c10 * (x + d0) + c11 * (y + d1) + c12 * (z + d2) + const1
+ * z' = c20 * (x + d0) + c21 * (y + d1) + c22 * (z + d2) + const2
+ *
+ * Please note that above formula is true only for Blender CSC. Other DE3 CSC
+ * units takes only positive value for difference. From what can be deducted
+ * from BSP driver code, those units probably automatically assume that
+ * difference has to be subtracted.
+ */
+static const u32 yuv2rgb_de3[] = {
+	0x0002542a, 0x00000000, 0x0003312a, 0xffffffc0, 0x00000000,
+	0x0002542a, 0xffff376b, 0xfffe5fc3, 0xfffffe00, 0x00000000,
+	0x0002542a, 0x000408d3, 0x00000000, 0xfffffe00, 0x00000000,
+};
+
+static const u32 yvu2rgb_de3[] = {
+	0x0002542a, 0x0003312a, 0x00000000, 0xffffffc0, 0x00000000,
+	0x0002542a, 0xfffe5fc3, 0xffff376b, 0xfffffe00, 0x00000000,
+	0x0002542a, 0x00000000, 0x000408d3, 0xfffffe00, 0x00000000,
+};
+
 static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
 				       enum sun8i_csc_mode mode)
 {
@@ -61,6 +89,38 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
 	}
 }
 
+static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer,
+					    enum sun8i_csc_mode mode)
+{
+	const u32 *table;
+	int i, j;
+
+	switch (mode) {
+	case SUN8I_CSC_MODE_YUV2RGB:
+		table = yuv2rgb_de3;
+		break;
+	case SUN8I_CSC_MODE_YVU2RGB:
+		table = yvu2rgb_de3;
+		break;
+	default:
+		DRM_WARN("Wrong CSC mode specified.\n");
+		return;
+	}
+
+	for (i = 0; i < 3; i++) {
+		for (j = 0; j < 3; j++)
+			regmap_write(map,
+				     SUN8I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE,
+								 layer, i, j),
+				     table[i * 5 + j]);
+		regmap_write(map,
+			     SUN8I_MIXER_BLEND_CSC_CONST(DE3_BLD_BASE,
+							 layer, i),
+			     SUN8I_MIXER_BLEND_CSC_CONST_VAL(table[i * 5 + 3],
+							     table[i * 5 + 4]));
+	}
+}
+
 static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable)
 {
 	u32 val;
@@ -73,21 +133,45 @@ static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable)
 	regmap_update_bits(map, SUN8I_CSC_CTRL(base), SUN8I_CSC_CTRL_EN, val);
 }
 
+static void sun8i_de3_ccsc_enable(struct regmap *map, int layer, bool enable)
+{
+	u32 val, mask;
+
+	mask = SUN8I_MIXER_BLEND_CSC_CTL_EN(layer);
+
+	if (enable)
+		val = mask;
+	else
+		val = 0;
+
+	regmap_update_bits(map, SUN8I_MIXER_BLEND_CSC_CTL(DE3_BLD_BASE),
+			   mask, val);
+}
+
 void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer,
 				     enum sun8i_csc_mode mode)
 {
-	u32 base;
+	if (!mixer->cfg->is_de3) {
+		u32 base;
 
-	base = ccsc_base[mixer->cfg->ccsc][layer];
+		base = ccsc_base[mixer->cfg->ccsc][layer];
 
-	sun8i_csc_set_coefficients(mixer->engine.regs, base, mode);
+		sun8i_csc_set_coefficients(mixer->engine.regs, base, mode);
+	} else {
+		sun8i_de3_ccsc_set_coefficients(mixer->engine.regs,
+						layer, mode);
+	}
 }
 
 void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable)
 {
-	u32 base;
+	if (!mixer->cfg->is_de3) {
+		u32 base;
 
-	base = ccsc_base[mixer->cfg->ccsc][layer];
+		base = ccsc_base[mixer->cfg->ccsc][layer];
 
-	sun8i_csc_enable(mixer->engine.regs, base, enable);
+		sun8i_csc_enable(mixer->engine.regs, base, enable);
+	} else {
+		sun8i_de3_ccsc_enable(mixer->engine.regs, layer, enable);
+	}
 }
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 743941a33d88..a9218abf0935 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -460,8 +460,21 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 	base = sun8i_blender_base(mixer);
 
 	/* Reset the registers */
-	for (i = 0x0; i < 0x20000; i += 4)
-		regmap_write(mixer->engine.regs, i, 0);
+	if (mixer->cfg->is_de3) {
+		for (i = 0x0; i < 0x3000; i += 4)
+			regmap_write(mixer->engine.regs, i, 0);
+		for (i = 0x20000; i < 0x40000; i += 4)
+			regmap_write(mixer->engine.regs, i, 0);
+		for (i = 0x70000; i < 0x88000; i += 4)
+			regmap_write(mixer->engine.regs, i, 0);
+		for (i = 0xa0000; i < 0xb0000; i += 4)
+			regmap_write(mixer->engine.regs, i, 0);
+		for (i = 0xd0000; i < 0xe0000; i += 4)
+			regmap_write(mixer->engine.regs, i, 0);
+	} else {
+		for (i = 0x0; i < 0x20000; i += 4)
+			regmap_write(mixer->engine.regs, i, 0);
+	}
 
 	/* Enable the mixer */
 	regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL,
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index 020b0a097c84..4c9a442bbb44 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -33,6 +33,10 @@
 #define DE2_CH_BASE				0x2000
 #define DE2_CH_SIZE				0x1000
 
+#define DE3_BLD_BASE				0x0800
+#define DE3_CH_BASE				0x1000
+#define DE3_CH_SIZE				0x0800
+
 #define SUN8I_MIXER_BLEND_PIPE_CTL(base)	((base) + 0)
 #define SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, x)	((base) + 0x4 + 0x10 * (x))
 #define SUN8I_MIXER_BLEND_ATTR_INSIZE(base, x)	((base) + 0x8 + 0x10 * (x))
@@ -47,6 +51,11 @@
 #define SUN8I_MIXER_BLEND_CK_MAX(base, x)	((base) + 0xc0 + 0x04 * (x))
 #define SUN8I_MIXER_BLEND_CK_MIN(base, x)	((base) + 0xe0 + 0x04 * (x))
 #define SUN8I_MIXER_BLEND_OUTCTL(base)		((base) + 0xfc)
+#define SUN8I_MIXER_BLEND_CSC_CTL(base)		((base) + 0x100)
+#define SUN8I_MIXER_BLEND_CSC_COEFF(base, layer, x, y) \
+	((base) + 0x110 + (layer) * 0x30 +  (x) * 0x10 + 4 * (y))
+#define SUN8I_MIXER_BLEND_CSC_CONST(base, layer, i) \
+	((base) + 0x110 + (layer) * 0x30 +  (i) * 0x10 + 0x0c)
 
 #define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK	GENMASK(12, 8)
 #define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe)	BIT(8 + pipe)
@@ -61,6 +70,9 @@
 
 #define SUN8I_MIXER_BLEND_OUTCTL_INTERLACED	BIT(1)
 
+#define SUN8I_MIXER_BLEND_CSC_CTL_EN(ch)	BIT(ch)
+#define SUN8I_MIXER_BLEND_CSC_CONST_VAL(d, c)	(((d) << 16) | ((c) & 0xffff))
+
 #define SUN8I_MIXER_FBFMT_ARGB8888	0
 #define SUN8I_MIXER_FBFMT_ABGR8888	1
 #define SUN8I_MIXER_FBFMT_RGBA8888	2
@@ -131,6 +143,7 @@ struct de2_fmt_info {
  *	are invalid.
  * @mod_rate: module clock rate that needs to be set in order to have
  *	a functional block.
+ * @is_de3: true, if this is next gen display engine 3.0, false otherwise.
  */
 struct sun8i_mixer_cfg {
 	int		vi_num;
@@ -138,6 +151,7 @@ struct sun8i_mixer_cfg {
 	int		scaler_mask;
 	int		ccsc;
 	unsigned long	mod_rate;
+	bool		is_de3;
 };
 
 struct sun8i_mixer {
@@ -160,13 +174,16 @@ engine_to_sun8i_mixer(struct sunxi_engine *engine)
 static inline u32
 sun8i_blender_base(struct sun8i_mixer *mixer)
 {
-	return DE2_BLD_BASE;
+	return mixer->cfg->is_de3 ? DE3_BLD_BASE : DE2_BLD_BASE;
 }
 
 static inline u32
 sun8i_channel_base(struct sun8i_mixer *mixer, int channel)
 {
-	return DE2_CH_BASE + channel * DE2_CH_SIZE;
+	if (mixer->cfg->is_de3)
+		return DE3_CH_BASE + channel * DE3_CH_SIZE;
+	else
+		return DE2_CH_BASE + channel * DE2_CH_SIZE;
 }
 
 const struct de2_fmt_info *sun8i_mixer_format_info(u32 format);
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
index c68eab8a748f..2bbeab4b8114 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
@@ -93,8 +93,12 @@ static inline u32 sun8i_ui_scaler_base(struct sun8i_mixer *mixer, int channel)
 {
 	int vi_num = mixer->cfg->vi_num;
 
-	return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * vi_num +
-	       DE2_UI_SCALER_SIZE * (channel - vi_num);
+	if (mixer->cfg->is_de3)
+		return DE3_VI_SCALER_BASE + DE3_VI_SCALER_SIZE * vi_num +
+		       DE3_UI_SCALER_SIZE * (channel - vi_num);
+	else
+		return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * vi_num +
+		       DE2_UI_SCALER_SIZE * (channel - vi_num);
 }
 
 static int sun8i_ui_scaler_coef_index(unsigned int step)
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.h b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.h
index 6c3516b75341..3d9b9e3ab9b6 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.h
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.h
@@ -12,6 +12,7 @@
 #include "sun8i_mixer.h"
 
 #define DE2_UI_SCALER_SIZE 0x10000
+#define DE3_UI_SCALER_SIZE 0x08000
 
 /* this two macros assumes 16 fractional bits which is standard in DRM */
 #define SUN8I_UI_SCALER_SCALE_MIN		1
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
index 79811eae3735..476cf67d6975 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
@@ -202,6 +202,14 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel,
 			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay),
 			   SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE, val);
 
+	/* It seems that YUV formats use global alpha setting. */
+	if (mixer->cfg->is_de3)
+		regmap_update_bits(mixer->engine.regs,
+				   SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base,
+								  overlay),
+				   SUN8I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK,
+				   SUN8I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA(0xff));
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
index 46f0237c17bb..3d0ad64178ea 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
@@ -30,6 +30,8 @@
 #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE		BIT(15)
 #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_OFFSET	8
 #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK	GENMASK(12, 8)
+#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK	GENMASK(31, 24)
+#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA(x)		((x) << 24)
 
 struct sun8i_mixer;
 
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
index 8697afc36023..22e1ed5cd7a4 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
@@ -835,7 +835,10 @@ static const u32 bicubic4coefftab32[480] = {
 
 static inline u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel)
 {
-	return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * channel;
+	if (mixer->cfg->is_de3)
+		return DE3_VI_SCALER_BASE + DE3_VI_SCALER_SIZE * channel;
+	else
+		return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * channel;
 }
 
 static int sun8i_vi_scaler_coef_index(unsigned int step)
@@ -951,6 +954,35 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
 		cvphase = vphase;
 	}
 
+	if (mixer->cfg->is_de3) {
+		u32 val;
+
+		if (format->hsub == 1 && format->vsub == 1)
+			val = SUN8I_SCALER_VSU_SCALE_MODE_UI;
+		else
+			val = SUN8I_SCALER_VSU_SCALE_MODE_NORMAL;
+
+		regmap_write(mixer->engine.regs,
+			     SUN8I_SCALER_VSU_SCALE_MODE(base), val);
+
+		regmap_write(mixer->engine.regs,
+			     SUN8I_SCALER_VSU_DIR_THR(base),
+			     SUN8I_SCALER_VSU_SUB_ZERO_DIR_THR(0) |
+			     SUN8I_SCALER_VSU_ZERO_DIR_THR(0) |
+			     SUN8I_SCALER_VSU_HORZ_DIR_THR(0xff) |
+			     SUN8I_SCALER_VSU_VERT_DIR_THR(1));
+		regmap_write(mixer->engine.regs,
+			     SUN8I_SCALER_VSU_EDGE_THR(base),
+			     SUN8I_SCALER_VSU_EDGE_SHIFT(8) |
+			     SUN8I_SCALER_VSU_EDGE_OFFSET(0));
+		regmap_write(mixer->engine.regs,
+			     SUN8I_SCALER_VSU_EDSCL_CTRL(base), 0);
+		regmap_write(mixer->engine.regs,
+			     SUN8I_SCALER_VSU_ANGLE_THR(base),
+			     SUN8I_SCALER_VSU_ANGLE_SHIFT(2) |
+			     SUN8I_SCALER_VSU_ANGLE_OFFSET(0));
+	}
+
 	regmap_write(mixer->engine.regs,
 		     SUN8I_SCALER_VSU_OUTSIZE(base), outsize);
 	regmap_write(mixer->engine.regs,
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
index cd015405f66d..c322f5652481 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
@@ -15,6 +15,9 @@
 #define DE2_VI_SCALER_BASE 0x20000
 #define DE2_VI_SCALER_SIZE 0x20000
 
+#define DE3_VI_SCALER_BASE 0x20000
+#define DE3_VI_SCALER_SIZE 0x08000
+
 /* this two macros assumes 16 fractional bits which is standard in DRM */
 #define SUN8I_VI_SCALER_SCALE_MIN		1
 #define SUN8I_VI_SCALER_SCALE_MAX		((1UL << 20) - 1)
@@ -25,6 +28,11 @@
 #define SUN8I_VI_SCALER_SIZE(w, h)		(((h) - 1) << 16 | ((w) - 1))
 
 #define SUN8I_SCALER_VSU_CTRL(base)		((base) + 0x0)
+#define SUN8I_SCALER_VSU_SCALE_MODE(base)	((base) + 0x10)
+#define SUN8I_SCALER_VSU_DIR_THR(base)		((base) + 0x20)
+#define SUN8I_SCALER_VSU_EDGE_THR(base)		((base) + 0x24)
+#define SUN8I_SCALER_VSU_EDSCL_CTRL(base)	((base) + 0x28)
+#define SUN8I_SCALER_VSU_ANGLE_THR(base)	((base) + 0x2c)
 #define SUN8I_SCALER_VSU_OUTSIZE(base)		((base) + 0x40)
 #define SUN8I_SCALER_VSU_YINSIZE(base)		((base) + 0x80)
 #define SUN8I_SCALER_VSU_YHSTEP(base)		((base) + 0x88)
@@ -46,6 +54,21 @@
 #define SUN8I_SCALER_VSU_CTRL_EN		BIT(0)
 #define SUN8I_SCALER_VSU_CTRL_COEFF_RDY		BIT(4)
 
+#define SUN8I_SCALER_VSU_SUB_ZERO_DIR_THR(x)	(((x) << 24) & 0xFF)
+#define SUN8I_SCALER_VSU_ZERO_DIR_THR(x)	(((x) << 16) & 0xFF)
+#define SUN8I_SCALER_VSU_HORZ_DIR_THR(x)	(((x) << 8) & 0xFF)
+#define SUN8I_SCALER_VSU_VERT_DIR_THR(x)	((x) & 0xFF)
+
+#define SUN8I_SCALER_VSU_SCALE_MODE_UI		0
+#define SUN8I_SCALER_VSU_SCALE_MODE_NORMAL	1
+#define SUN8I_SCALER_VSU_SCALE_MODE_ED_SCALE	2
+
+#define SUN8I_SCALER_VSU_EDGE_SHIFT(x)		(((x) << 16) & 0xF)
+#define SUN8I_SCALER_VSU_EDGE_OFFSET(x)		((x) & 0xFF)
+
+#define SUN8I_SCALER_VSU_ANGLE_SHIFT(x)		(((x) << 16) & 0xF)
+#define SUN8I_SCALER_VSU_ANGLE_OFFSET(x)	((x) & 0xFF)
+
 void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable);
 void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
 			   u32 src_w, u32 src_h, u32 dst_w, u32 dst_h,
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 13/27] drm/sun4i: Add support for H6 DE3 mixer 0
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (11 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 12/27] drm/sun4i: Add basic support for DE3 Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-22 13:23   ` Chen-Yu Tsai
  2018-09-02  7:26 ` [PATCH 14/27] drm/bridge/synopsys: dw-hdmi: Enable workaround for v2.12a Jernej Skrabec
                   ` (14 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

Mixer 0 has 1 VI and 3 UI planes, scaler on all planes and can output
4K image @60Hz. It also support 10 bit colors.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_mixer.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index a9218abf0935..54eca2dd4b33 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -540,6 +540,15 @@ static int sun8i_mixer_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = {
+	.ccsc		= 0,
+	.is_de3		= true,
+	.mod_rate	= 600000000,
+	.scaler_mask	= 0xf,
+	.ui_num		= 3,
+	.vi_num		= 1,
+};
+
 static const struct sun8i_mixer_cfg sun8i_a83t_mixer0_cfg = {
 	.ccsc		= 0,
 	.scaler_mask	= 0xf,
@@ -587,6 +596,10 @@ static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
 };
 
 static const struct of_device_id sun8i_mixer_of_table[] = {
+	{
+		.compatible = "allwinner,sun50i-h6-de3-mixer-0",
+		.data = &sun50i_h6_mixer0_cfg,
+	},
 	{
 		.compatible = "allwinner,sun8i-a83t-de2-mixer-0",
 		.data = &sun8i_a83t_mixer0_cfg,
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 14/27] drm/bridge/synopsys: dw-hdmi: Enable workaround for v2.12a
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (12 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 13/27] drm/sun4i: Add support for H6 DE3 mixer 0 Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-22 13:54   ` Chen-Yu Tsai
  2018-09-02  7:26 ` [PATCH 15/27] drm/sun4i: Not all DW HDMI controllers has scrambled addresses Jernej Skrabec
                   ` (13 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

It turns out that even new DW HDMI controllers exhibits same mangenta
line issues as older versions.

Enable workaround for v2.12a.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 5971976284bf..df1c7a2d6961 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1664,6 +1664,7 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
 	case 0x131a:
 	case 0x132a:
 	case 0x201a:
+	case 0x212a:
 		count = 1;
 		break;
 	default:
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 15/27] drm/sun4i: Not all DW HDMI controllers has scrambled addresses
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (13 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 14/27] drm/bridge/synopsys: dw-hdmi: Enable workaround for v2.12a Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-12 12:25   ` Chen-Yu Tsai
  2018-09-02  7:26 ` [PATCH 16/27] drm/sun4i: dw-hdmi: Make mode_valid function configurable Jernej Skrabec
                   ` (12 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

Currently supported Allwinner SoCs with DW HDMI controller have
scrambled addresses and read lock. However, that is not true in general.
For example, A80 and H6 have normal addresses and normal read access.

Move code for unscrambling addresses and unlocking read access to it's
own function and call it from init function.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index 82502b351aec..ad4ba1cc83b4 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -279,8 +279,21 @@ static const struct dw_hdmi_phy_ops sun8i_hdmi_phy_ops = {
 	.setup_hpd = &dw_hdmi_phy_setup_hpd,
 };
 
+static void sun8i_hdmi_phy_unlock(struct sun8i_hdmi_phy *phy)
+{
+	/* enable read access to HDMI controller */
+	regmap_write(phy->regs, SUN8I_HDMI_PHY_READ_EN_REG,
+		     SUN8I_HDMI_PHY_READ_EN_MAGIC);
+
+	/* unscramble register offsets */
+	regmap_write(phy->regs, SUN8I_HDMI_PHY_UNSCRAMBLE_REG,
+		     SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC);
+}
+
 static void sun8i_hdmi_phy_init_a83t(struct sun8i_hdmi_phy *phy)
 {
+	sun8i_hdmi_phy_unlock(phy);
+
 	regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_DBG_CTRL_REG,
 			   SUN8I_HDMI_PHY_DBG_CTRL_PX_LOCK,
 			   SUN8I_HDMI_PHY_DBG_CTRL_PX_LOCK);
@@ -298,6 +311,8 @@ static void sun8i_hdmi_phy_init_h3(struct sun8i_hdmi_phy *phy)
 {
 	unsigned int val;
 
+	sun8i_hdmi_phy_unlock(phy);
+
 	regmap_write(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, 0);
 	regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
 			   SUN8I_HDMI_PHY_ANA_CFG1_ENBI,
@@ -372,14 +387,6 @@ static void sun8i_hdmi_phy_init_h3(struct sun8i_hdmi_phy *phy)
 
 void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy)
 {
-	/* enable read access to HDMI controller */
-	regmap_write(phy->regs, SUN8I_HDMI_PHY_READ_EN_REG,
-		     SUN8I_HDMI_PHY_READ_EN_MAGIC);
-
-	/* unscramble register offsets */
-	regmap_write(phy->regs, SUN8I_HDMI_PHY_UNSCRAMBLE_REG,
-		     SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC);
-
 	phy->variant->phy_init(phy);
 }
 
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 16/27] drm/sun4i: dw-hdmi: Make mode_valid function configurable
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (14 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 15/27] drm/sun4i: Not all DW HDMI controllers has scrambled addresses Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-22 13:29   ` Chen-Yu Tsai
  2018-09-02  7:26 ` [PATCH 17/27] drm/sun4i: dw-hdmi: Add quirk for setting TMDS clock Jernej Skrabec
                   ` (11 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

Since it is not possible to access sun8i-dw-hdmi driver private data
inside mode_valid function, make it configurable. That way different
versions of HDMI controllers can set different function, depending on
it's limitations.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 18 ++++++++++++++----
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h |  6 ++++++
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
index 31875b636434..a5020fe8bd69 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
@@ -5,6 +5,7 @@
 
 #include <linux/component.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 
 #include <drm/drm_of.h>
@@ -33,8 +34,8 @@ static const struct drm_encoder_funcs sun8i_dw_hdmi_encoder_funcs = {
 };
 
 static enum drm_mode_status
-sun8i_dw_hdmi_mode_valid(struct drm_connector *connector,
-			 const struct drm_display_mode *mode)
+sun8i_dw_hdmi_mode_valid_a83t(struct drm_connector *connector,
+			      const struct drm_display_mode *mode)
 {
 	if (mode->clock > 297000)
 		return MODE_CLOCK_HIGH;
@@ -102,6 +103,8 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
 	hdmi->dev = &pdev->dev;
 	encoder = &hdmi->encoder;
 
+	hdmi->quirks = of_device_get_match_data(dev);
+
 	encoder->possible_crtcs =
 		sun8i_dw_hdmi_find_possible_crtcs(drm, dev->of_node);
 	/*
@@ -156,7 +159,7 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
 
 	sun8i_hdmi_phy_init(hdmi->phy);
 
-	plat_data->mode_valid = &sun8i_dw_hdmi_mode_valid;
+	plat_data->mode_valid = hdmi->quirks->mode_valid;
 	plat_data->phy_ops = sun8i_hdmi_phy_get_ops();
 	plat_data->phy_name = "sun8i_dw_hdmi_phy";
 	plat_data->phy_data = hdmi->phy;
@@ -215,8 +218,15 @@ static int sun8i_dw_hdmi_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct sun8i_dw_hdmi_quirks sun8i_a83t_quirks = {
+	.mode_valid = sun8i_dw_hdmi_mode_valid_a83t,
+};
+
 static const struct of_device_id sun8i_dw_hdmi_dt_ids[] = {
-	{ .compatible = "allwinner,sun8i-a83t-dw-hdmi" },
+	{
+		.compatible = "allwinner,sun8i-a83t-dw-hdmi",
+		.data = &sun8i_a83t_quirks,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, sun8i_dw_hdmi_dt_ids);
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
index aadbe0a10b0c..b718c47e00be 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -169,6 +169,11 @@ struct sun8i_hdmi_phy {
 	struct sun8i_hdmi_phy_variant	*variant;
 };
 
+struct sun8i_dw_hdmi_quirks {
+	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
+					   const struct drm_display_mode *mode);
+};
+
 struct sun8i_dw_hdmi {
 	struct clk			*clk_tmds;
 	struct device			*dev;
@@ -176,6 +181,7 @@ struct sun8i_dw_hdmi {
 	struct drm_encoder		encoder;
 	struct sun8i_hdmi_phy		*phy;
 	struct dw_hdmi_plat_data	plat_data;
+	const struct sun8i_dw_hdmi_quirks *quirks;
 	struct reset_control		*rst_ctrl;
 };
 
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 17/27] drm/sun4i: dw-hdmi: Add quirk for setting TMDS clock
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (15 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 16/27] drm/sun4i: dw-hdmi: Make mode_valid function configurable Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-22 13:30   ` Chen-Yu Tsai
  2018-09-02  7:26 ` [PATCH 18/27] dt-bindings: display: sunxi: add DT binding for Allwinner H6 DW HDMI Jernej Skrabec
                   ` (10 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

It turns out that H6 HDMI BSP kernel driver doesn't change TMDS rate at
all. At this point it is not clear whether it is just not necessary or
it would cause some kind of issues.

Add a quirk for it.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 5 ++++-
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 1 +
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
index a5020fe8bd69..16a0c7a88ea8 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
@@ -153,7 +153,9 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
 		goto err_disable_clk_tmds;
 	}
 
-	drm_encoder_helper_add(encoder, &sun8i_dw_hdmi_encoder_helper_funcs);
+	if (hdmi->quirks->set_rate)
+		drm_encoder_helper_add(encoder,
+				       &sun8i_dw_hdmi_encoder_helper_funcs);
 	drm_encoder_init(drm, encoder, &sun8i_dw_hdmi_encoder_funcs,
 			 DRM_MODE_ENCODER_TMDS, NULL);
 
@@ -220,6 +222,7 @@ static int sun8i_dw_hdmi_remove(struct platform_device *pdev)
 
 static const struct sun8i_dw_hdmi_quirks sun8i_a83t_quirks = {
 	.mode_valid = sun8i_dw_hdmi_mode_valid_a83t,
+	.set_rate = true,
 };
 
 static const struct of_device_id sun8i_dw_hdmi_dt_ids[] = {
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
index b718c47e00be..94cf13d09abe 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -172,6 +172,7 @@ struct sun8i_hdmi_phy {
 struct sun8i_dw_hdmi_quirks {
 	enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
 					   const struct drm_display_mode *mode);
+	bool set_rate;
 };
 
 struct sun8i_dw_hdmi {
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 18/27] dt-bindings: display: sunxi: add DT binding for Allwinner H6 DW HDMI
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (16 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 17/27] drm/sun4i: dw-hdmi: Add quirk for setting TMDS clock Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-02  7:26 ` [PATCH 19/27] drm/sun4i: Add support for H6 DW HDMI controller Jernej Skrabec
                   ` (9 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, Icenowy Zheng

From: Icenowy Zheng <icenowy@aosc.io>

The Allwinner H6 SoC uses a v2.12a DesignWare HDMI controller, with
dedicated CEC and HDCP clocks added; the PHY connected is a standard
DesignWare HDMI PHY.

Add binding for it.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
[added HDCP clock and reset]
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 .../devicetree/bindings/display/sunxi/sun4i-drm.txt   | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index dec2f8a6da9c..278410e43940 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -78,6 +78,7 @@ Required properties:
 
   - compatible: value must be one of:
     * "allwinner,sun8i-a83t-dw-hdmi"
+    * "allwinner,sun50i-h6-dw-hdmi"
   - reg: base address and size of memory-mapped region
   - reg-io-width: See dw_hdmi.txt. Shall be 1.
   - interrupts: HDMI interrupt number
@@ -85,9 +86,14 @@ Required properties:
     * iahb: the HDMI bus clock
     * isfr: the HDMI register clock
     * tmds: TMDS clock
+    * cec: HDMI CEC clock (H6 only)
+    * hdcp: HDCP clock (H6 only)
+    * hdcp-bus: HDCP bus clock (H6 only)
   - clock-names: the clock names mentioned above
-  - resets: phandle to the reset controller
-  - reset-names: must be "ctrl"
+  - resets:
+    * ctrl: HDMI controller reset
+    * hdcp: HDCP reset (H6 only)
+  - reset-names: reset names mentioned above
   - phys: phandle to the DWC HDMI PHY
   - phy-names: must be "phy"
 
@@ -104,6 +110,7 @@ Required properties:
     * allwinner,sun8i-a83t-hdmi-phy
     * allwinner,sun8i-h3-hdmi-phy
     * allwinner,sun50i-a64-hdmi-phy
+    * allwinner,sun50i-h6-hdmi-phy
   - reg: base address and size of memory-mapped region
   - clocks: phandles to the clocks feeding the HDMI PHY
     * bus: the HDMI PHY interface clock
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 19/27] drm/sun4i: Add support for H6 DW HDMI controller
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (17 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 18/27] dt-bindings: display: sunxi: add DT binding for Allwinner H6 DW HDMI Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-12 12:29   ` Chen-Yu Tsai
  2018-09-02  7:26 ` [PATCH 20/27] drm/sun4i: Add support for Synopsys HDMI PHY Jernej Skrabec
                   ` (8 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

H6 has DW HDMI 2.0 controller v2.12a.

It supports 4K at 60 Hz and HDCP 2.2.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
index 16a0c7a88ea8..44143c9f20d0 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
@@ -43,6 +43,16 @@ sun8i_dw_hdmi_mode_valid_a83t(struct drm_connector *connector,
 	return MODE_OK;
 }
 
+static enum drm_mode_status
+sun8i_dw_hdmi_mode_valid_h6(struct drm_connector *connector,
+			    const struct drm_display_mode *mode)
+{
+	if (mode->clock > 600000)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
 static bool sun8i_dw_hdmi_node_is_tcon_top(struct device_node *node)
 {
 	return IS_ENABLED(CONFIG_DRM_SUN8I_TCON_TOP) &&
@@ -220,12 +230,20 @@ static int sun8i_dw_hdmi_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct sun8i_dw_hdmi_quirks sun50i_h6_quirks = {
+	.mode_valid = sun8i_dw_hdmi_mode_valid_h6,
+};
+
 static const struct sun8i_dw_hdmi_quirks sun8i_a83t_quirks = {
 	.mode_valid = sun8i_dw_hdmi_mode_valid_a83t,
 	.set_rate = true,
 };
 
 static const struct of_device_id sun8i_dw_hdmi_dt_ids[] = {
+	{
+		.compatible = "allwinner,sun50i-h6-dw-hdmi",
+		.data = &sun50i_h6_quirks,
+	},
 	{
 		.compatible = "allwinner,sun8i-a83t-dw-hdmi",
 		.data = &sun8i_a83t_quirks,
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 20/27] drm/sun4i: Add support for Synopsys HDMI PHY
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (18 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 19/27] drm/sun4i: Add support for H6 DW HDMI controller Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-02  7:26 ` [PATCH 21/27] drm/sun4i: Add support for H6 " Jernej Skrabec
                   ` (7 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

Currently sun8i-hdmi-phy driver supports only custom PHYs connected to
DW HDMI controller. Since newest Allwinner SoCs have unmodified Synopsys
PHY, driver has to be reorganized to support them.

Variant structure is expanded to allow differentiation between custom
and Sysnopsys PHYs and to hold Synopsys PHY settings.

Since DW HDMI bridge platform data has different fields for custom and
Sysnopsys PHY, function sun8i_hdmi_phy_get_ops() is replaced with
sun8i_hdmi_phy_set_ops().

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c  |  4 +---
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h  |  7 ++++++-
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 18 ++++++++++++++++--
 3 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
index 44143c9f20d0..bf35975dd100 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
@@ -172,9 +172,7 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
 	sun8i_hdmi_phy_init(hdmi->phy);
 
 	plat_data->mode_valid = hdmi->quirks->mode_valid;
-	plat_data->phy_ops = sun8i_hdmi_phy_get_ops();
-	plat_data->phy_name = "sun8i_dw_hdmi_phy";
-	plat_data->phy_data = hdmi->phy;
+	sun8i_hdmi_phy_set_ops(hdmi->phy, plat_data);
 
 	platform_set_drvdata(pdev, hdmi);
 
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
index 94cf13d09abe..e48cd9b3cce3 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -149,6 +149,10 @@ struct sun8i_hdmi_phy;
 struct sun8i_hdmi_phy_variant {
 	bool has_phy_clk;
 	bool has_second_pll;
+	bool is_custom_phy;
+	const struct dw_hdmi_curr_ctrl *cur_ctr;
+	const struct dw_hdmi_mpll_config *mpll_cfg;
+	const struct dw_hdmi_phy_config *phy_cfg;
 	void (*phy_init)(struct sun8i_hdmi_phy *phy);
 	void (*phy_disable)(struct dw_hdmi *hdmi,
 			    struct sun8i_hdmi_phy *phy);
@@ -196,7 +200,8 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node);
 void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi);
 
 void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy);
-const struct dw_hdmi_phy_ops *sun8i_hdmi_phy_get_ops(void);
+void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy,
+			    struct dw_hdmi_plat_data *plat_data);
 
 int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev,
 			 bool second_parent);
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index ad4ba1cc83b4..ee2bf61cd4d2 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -390,9 +390,20 @@ void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy)
 	phy->variant->phy_init(phy);
 }
 
-const struct dw_hdmi_phy_ops *sun8i_hdmi_phy_get_ops(void)
+void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy,
+			    struct dw_hdmi_plat_data *plat_data)
 {
-	return &sun8i_hdmi_phy_ops;
+	struct sun8i_hdmi_phy_variant *variant = phy->variant;
+
+	if (variant->is_custom_phy) {
+		plat_data->phy_ops = &sun8i_hdmi_phy_ops;
+		plat_data->phy_name = "sun8i_dw_hdmi_phy";
+		plat_data->phy_data = phy;
+	} else {
+		plat_data->mpll_cfg = variant->mpll_cfg;
+		plat_data->cur_ctr = variant->cur_ctr;
+		plat_data->phy_config = variant->phy_cfg;
+	}
 }
 
 static struct regmap_config sun8i_hdmi_phy_regmap_config = {
@@ -405,6 +416,7 @@ static struct regmap_config sun8i_hdmi_phy_regmap_config = {
 
 static const struct sun8i_hdmi_phy_variant sun50i_a64_hdmi_phy = {
 	.has_phy_clk = true,
+	.is_custom_phy = true,
 	.has_second_pll = true,
 	.phy_init = &sun8i_hdmi_phy_init_h3,
 	.phy_disable = &sun8i_hdmi_phy_disable_h3,
@@ -412,6 +424,7 @@ static const struct sun8i_hdmi_phy_variant sun50i_a64_hdmi_phy = {
 };
 
 static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = {
+	.is_custom_phy = true,
 	.phy_init = &sun8i_hdmi_phy_init_a83t,
 	.phy_disable = &sun8i_hdmi_phy_disable_a83t,
 	.phy_config = &sun8i_hdmi_phy_config_a83t,
@@ -419,6 +432,7 @@ static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = {
 
 static const struct sun8i_hdmi_phy_variant sun8i_h3_hdmi_phy = {
 	.has_phy_clk = true,
+	.is_custom_phy = true,
 	.phy_init = &sun8i_hdmi_phy_init_h3,
 	.phy_disable = &sun8i_hdmi_phy_disable_h3,
 	.phy_config = &sun8i_hdmi_phy_config_h3,
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 21/27] drm/sun4i: Add support for H6 HDMI PHY
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (19 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 20/27] drm/sun4i: Add support for Synopsys HDMI PHY Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-22 15:55   ` Chen-Yu Tsai
  2018-09-02  7:26 ` [PATCH 22/27] drm/sun4i: Initialize registers in tcon-top driver Jernej Skrabec
                   ` (6 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

H6 has Synopsys DWC HDMI 2.0 TX PHY.

mpll settings were calculated from specifications of similar Synopsys
HDMI PHY found in i.MX6. Other PHY settings were derived from BSP PHY
driver code.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 137 +++++++++++++++++++++++++
 1 file changed, 137 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index ee2bf61cd4d2..2f5499bd35ec 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -14,6 +14,122 @@
  */
 #define I2C_ADDR	0x69
 
+static const struct dw_hdmi_mpll_config sun50i_h6_mpll_cfg[] = {
+	{
+		30666000, {
+			{ 0x00b3, 0x0000 },
+			{ 0x2153, 0x0000 },
+			{ 0x40f3, 0x0000 },
+		},
+	},  {
+		36800000, {
+			{ 0x00b3, 0x0000 },
+			{ 0x2153, 0x0000 },
+			{ 0x40a2, 0x0001 },
+		},
+	},  {
+		46000000, {
+			{ 0x00b3, 0x0000 },
+			{ 0x2142, 0x0001 },
+			{ 0x40a2, 0x0001 },
+		},
+	},  {
+		61333000, {
+			{ 0x0072, 0x0001 },
+			{ 0x2142, 0x0001 },
+			{ 0x40a2, 0x0001 },
+		},
+	},  {
+		73600000, {
+			{ 0x0072, 0x0001 },
+			{ 0x2142, 0x0001 },
+			{ 0x4061, 0x0002 },
+		},
+	},  {
+		92000000, {
+			{ 0x0072, 0x0001 },
+			{ 0x2145, 0x0002 },
+			{ 0x4061, 0x0002 },
+		},
+	},  {
+		122666000, {
+			{ 0x0051, 0x0002 },
+			{ 0x2145, 0x0002 },
+			{ 0x4061, 0x0002 },
+		},
+	},  {
+		147200000, {
+			{ 0x0051, 0x0002 },
+			{ 0x2145, 0x0002 },
+			{ 0x4064, 0x0003 },
+		},
+	},  {
+		184000000, {
+			{ 0x0051, 0x0002 },
+			{ 0x214c, 0x0003 },
+			{ 0x4064, 0x0003 },
+		},
+	},  {
+		226666000, {
+			{ 0x0040, 0x0003 },
+			{ 0x214c, 0x0003 },
+			{ 0x4064, 0x0003 },
+		},
+	},  {
+		272000000, {
+			{ 0x0040, 0x0003 },
+			{ 0x214c, 0x0003 },
+			{ 0x5a64, 0x0003 },
+		},
+	},  {
+		340000000, {
+			{ 0x0040, 0x0003 },
+			{ 0x3b4c, 0x0003 },
+			{ 0x5a64, 0x0003 },
+		},
+	},  {
+		600000000, {
+			{ 0x1a40, 0x0003 },
+			{ 0x3b4c, 0x0003 },
+			{ 0x5a64, 0x0003 },
+		},
+	}, {
+		~0UL, {
+			{ 0x0000, 0x0000 },
+			{ 0x0000, 0x0000 },
+			{ 0x0000, 0x0000 },
+		},
+	}
+};
+
+static const struct dw_hdmi_curr_ctrl sun50i_h6_cur_ctr[] = {
+	/* pixelclk    bpp8    bpp10   bpp12 */
+	{ 25175000,  { 0x0000, 0x0000, 0x0000 }, },
+	{ 27000000,  { 0x0012, 0x0000, 0x0000 }, },
+	{ 59400000,  { 0x0008, 0x0008, 0x0008 }, },
+	{ 72000000,  { 0x0008, 0x0008, 0x001b }, },
+	{ 74250000,  { 0x0013, 0x0013, 0x0013 }, },
+	{ 90000000,  { 0x0008, 0x001a, 0x001b }, },
+	{ 118800000, { 0x001b, 0x001a, 0x001b }, },
+	{ 144000000, { 0x001b, 0x001a, 0x0034 }, },
+	{ 180000000, { 0x001b, 0x0033, 0x0034 }, },
+	{ 216000000, { 0x0036, 0x0033, 0x0034 }, },
+	{ 237600000, { 0x0036, 0x0033, 0x001b }, },
+	{ 288000000, { 0x0036, 0x001b, 0x001b }, },
+	{ 297000000, { 0x0019, 0x001b, 0x0019 }, },
+	{ 330000000, { 0x0036, 0x001b, 0x001b }, },
+	{ 600000000, { 0x003f, 0x001b, 0x001b }, },
+	{ ~0UL,      { 0x0000, 0x0000, 0x0000 }, }
+};
+
+static const struct dw_hdmi_phy_config sun50i_h6_phy_config[] = {
+	/*pixelclk   symbol   term   vlev*/
+	{ 74250000,  0x8009, 0x0004, 0x0232},
+	{ 148500000, 0x8029, 0x0004, 0x0273},
+	{ 600000000, 0x8039, 0x0004, 0x014a},
+	{ ~0UL,	     0x0000, 0x0000, 0x0000}
+};
+
 static int sun8i_hdmi_phy_config_a83t(struct dw_hdmi *hdmi,
 				      struct sun8i_hdmi_phy *phy,
 				      unsigned int clk_rate)
@@ -290,6 +406,16 @@ static void sun8i_hdmi_phy_unlock(struct sun8i_hdmi_phy *phy)
 		     SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC);
 }
 
+static void sun50i_hdmi_phy_init_h6(struct sun8i_hdmi_phy *phy)
+{
+	regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG,
+			   SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN,
+			   SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN);
+
+	regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG,
+			   0xffff0000, 0x80c00000);
+}
+
 static void sun8i_hdmi_phy_init_a83t(struct sun8i_hdmi_phy *phy)
 {
 	sun8i_hdmi_phy_unlock(phy);
@@ -423,6 +549,13 @@ static const struct sun8i_hdmi_phy_variant sun50i_a64_hdmi_phy = {
 	.phy_config = &sun8i_hdmi_phy_config_h3,
 };
 
+static const struct sun8i_hdmi_phy_variant sun50i_h6_hdmi_phy = {
+	.cur_ctr  = sun50i_h6_cur_ctr,
+	.mpll_cfg = sun50i_h6_mpll_cfg,
+	.phy_cfg  = sun50i_h6_phy_config,
+	.phy_init = &sun50i_hdmi_phy_init_h6,
+};
+
 static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = {
 	.is_custom_phy = true,
 	.phy_init = &sun8i_hdmi_phy_init_a83t,
@@ -443,6 +576,10 @@ static const struct of_device_id sun8i_hdmi_phy_of_table[] = {
 		.compatible = "allwinner,sun50i-a64-hdmi-phy",
 		.data = &sun50i_a64_hdmi_phy,
 	},
+	{
+		.compatible = "allwinner,sun50i-h6-hdmi-phy",
+		.data = &sun50i_h6_hdmi_phy,
+	},
 	{
 		.compatible = "allwinner,sun8i-a83t-hdmi-phy",
 		.data = &sun8i_a83t_hdmi_phy,
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 22/27] drm/sun4i: Initialize registers in tcon-top driver
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (20 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 21/27] drm/sun4i: Add support for H6 " Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-02  7:26 ` [PATCH 23/27] drm: sun4i: add quirks for TCON TOP Jernej Skrabec
                   ` (5 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

It turns out that TCON TOP registers in H6 SoC have non-zero reset
value. This may cause issues if bits are not changed during
configuration.

To prevent that, initialize registers to 0.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
index 3040a79f298f..37158548b447 100644
--- a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
+++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
@@ -167,6 +167,13 @@ static int sun8i_tcon_top_bind(struct device *dev, struct device *master,
 		goto err_assert_reset;
 	}
 
+	/*
+	 * At least on H6, some registers have some bits set by default
+	 * which may cause issues. Clear them here.
+	 */
+	writel(0, regs + TCON_TOP_PORT_SEL_REG);
+	writel(0, regs + TCON_TOP_GATE_SRC_REG);
+
 	/*
 	 * TCON TOP has two muxes, which select parent clock for each TCON TV
 	 * channel clock. Parent could be either TCON TV or TVE clock. For now
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 23/27] drm: sun4i: add quirks for TCON TOP
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (21 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 22/27] drm/sun4i: Initialize registers in tcon-top driver Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-02  7:26 ` [PATCH 24/27] dt-bindings: display: sun4i-drm: document H6 " Jernej Skrabec
                   ` (4 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, Icenowy Zheng

From: Icenowy Zheng <icenowy@aosc.io>

Some SoCs, such as H6, doesn't have a full-featured TCON TOP.

Add quirks support for TCON TOP.

Currently the presence of TCON_TV1 and DSI is controlled via the quirks
structure.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 43 ++++++++++++++++++++------
 1 file changed, 34 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
index 37158548b447..ed13233cad88 100644
--- a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
+++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
@@ -9,11 +9,17 @@
 #include <linux/component.h>
 #include <linux/device.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/of_graph.h>
 #include <linux/platform_device.h>
 
 #include "sun8i_tcon_top.h"
 
+struct sun8i_tcon_top_quirks {
+	bool has_tcon_tv1;
+	bool has_dsi;
+};
+
 static bool sun8i_tcon_top_node_is_tcon_top(struct device_node *node)
 {
 	return !!of_match_node(sun8i_tcon_top_of_table, node);
@@ -121,10 +127,13 @@ static int sun8i_tcon_top_bind(struct device *dev, struct device *master,
 	struct platform_device *pdev = to_platform_device(dev);
 	struct clk_hw_onecell_data *clk_data;
 	struct sun8i_tcon_top *tcon_top;
+	const struct sun8i_tcon_top_quirks *quirks;
 	struct resource *res;
 	void __iomem *regs;
 	int ret, i;
 
+	quirks = of_device_get_match_data(&pdev->dev);
+
 	tcon_top = devm_kzalloc(dev, sizeof(*tcon_top), GFP_KERNEL);
 	if (!tcon_top)
 		return -ENOMEM;
@@ -187,15 +196,23 @@ static int sun8i_tcon_top_bind(struct device *dev, struct device *master,
 					     &tcon_top->reg_lock,
 					     TCON_TOP_TCON_TV0_GATE, 0);
 
-	clk_data->hws[CLK_TCON_TOP_TV1] =
-		sun8i_tcon_top_register_gate(dev, "tcon-tv1", regs,
-					     &tcon_top->reg_lock,
-					     TCON_TOP_TCON_TV1_GATE, 1);
+	if (quirks->has_tcon_tv1) {
+		clk_data->hws[CLK_TCON_TOP_TV1] =
+			sun8i_tcon_top_register_gate(dev, "tcon-tv1", regs,
+						     &tcon_top->reg_lock,
+						     TCON_TOP_TCON_TV1_GATE, 1);
+	} else {
+		clk_data->hws[CLK_TCON_TOP_TV1] = NULL;
+	}
 
-	clk_data->hws[CLK_TCON_TOP_DSI] =
-		sun8i_tcon_top_register_gate(dev, "dsi", regs,
-					     &tcon_top->reg_lock,
-					     TCON_TOP_TCON_DSI_GATE, 2);
+	if (quirks->has_dsi) {
+		clk_data->hws[CLK_TCON_TOP_DSI] =
+			sun8i_tcon_top_register_gate(dev, "dsi", regs,
+						     &tcon_top->reg_lock,
+						     TCON_TOP_TCON_DSI_GATE, 2);
+	} else {
+		clk_data->hws[CLK_TCON_TOP_DSI] = NULL;
+	}
 
 	for (i = 0; i < CLK_NUM; i++)
 		if (IS_ERR(clk_data->hws[i])) {
@@ -257,9 +274,17 @@ static int sun8i_tcon_top_remove(struct platform_device *pdev)
 	return 0;
 }
 
+const struct sun8i_tcon_top_quirks sun8i_r40_tcon_top_quirks = {
+	.has_tcon_tv1	= true,
+	.has_dsi	= true,
+};
+
 /* sun4i_drv uses this list to check if a device node is a TCON TOP */
 const struct of_device_id sun8i_tcon_top_of_table[] = {
-	{ .compatible = "allwinner,sun8i-r40-tcon-top" },
+	{
+		.compatible = "allwinner,sun8i-r40-tcon-top",
+		.data = &sun8i_r40_tcon_top_quirks
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sun8i_tcon_top_of_table);
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 24/27] dt-bindings: display: sun4i-drm: document H6 TCON TOP
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (22 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 23/27] drm: sun4i: add quirks for TCON TOP Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-02  7:26 ` [PATCH 25/27] drm: sun4i: add support for " Jernej Skrabec
                   ` (3 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, Icenowy Zheng

From: Icenowy Zheng <icenowy@aosc.io>

Allwinner H6 SoC has a cut down version of TCON TOP.

Add binding documentation for it.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
[expanded description]
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 .../bindings/display/sunxi/sun4i-drm.txt           | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index 278410e43940..a14eb9313e70 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -221,24 +221,26 @@ It allows display pipeline to be configured in very different ways:
                  \ [3] TCON-TV1 [1] - TVE1/RGB
 
 Note that both TCON TOP references same physical unit. Both mixers can be
-connected to any TCON.
+connected to any TCON. Not all TCON TOP variants support all features.
 
 Required properties:
   - compatible: value must be one of:
     * allwinner,sun8i-r40-tcon-top
+    * allwinner,sun50i-h6-tcon-top
   - reg: base address and size of the memory-mapped region.
   - clocks: phandle to the clocks feeding the TCON TOP
     * bus: TCON TOP interface clock
     * tcon-tv0: TCON TV0 clock
-    * tve0: TVE0 clock
-    * tcon-tv1: TCON TV1 clock
-    * tve1: TVE0 clock
-    * dsi: MIPI DSI clock
+    * tve0: TVE0 clock (R40 only)
+    * tcon-tv1: TCON TV1 clock (R40 only)
+    * tve1: TVE0 clock (R40 only)
+    * dsi: MIPI DSI clock (R40 only)
   - clock-names: clock name mentioned above
   - resets: phandle to the reset line driving the TCON TOP
   - #clock-cells : must contain 1
   - clock-output-names: Names of clocks created for TCON TV0 channel clock,
-    TCON TV1 channel clock and DSI channel clock, in that order.
+    TCON TV1 channel clock (R40 only) and DSI channel clock (R40 only), in
+    that order.
 
 - ports: A ports node with endpoint definitions as defined in
     Documentation/devicetree/bindings/media/video-interfaces.txt. 6 ports should
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 25/27] drm: sun4i: add support for H6 TCON TOP
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (23 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 24/27] dt-bindings: display: sun4i-drm: document H6 " Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-02  7:26 ` [PATCH 26/27] arm64: dts: sun50i: h6: Add HDMI pipeline Jernej Skrabec
                   ` (2 subsequent siblings)
  27 siblings, 0 replies; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, Icenowy Zheng

From: Icenowy Zheng <icenowy@aosc.io>

The TCON TOP on Allwinner H6 SoC is a cut down version of the R40 TCON
TOP, which dropped TCON_TV1 and DSI (which do not exist on H6).

Add support for it.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
index ed13233cad88..d0f1767ec6fc 100644
--- a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
+++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
@@ -279,12 +279,20 @@ const struct sun8i_tcon_top_quirks sun8i_r40_tcon_top_quirks = {
 	.has_dsi	= true,
 };
 
+const struct sun8i_tcon_top_quirks sun50i_h6_tcon_top_quirks = {
+	/* Nothing special */
+};
+
 /* sun4i_drv uses this list to check if a device node is a TCON TOP */
 const struct of_device_id sun8i_tcon_top_of_table[] = {
 	{
 		.compatible = "allwinner,sun8i-r40-tcon-top",
 		.data = &sun8i_r40_tcon_top_quirks
 	},
+	{
+		.compatible = "allwinner,sun50i-h6-tcon-top",
+		.data = &sun50i_h6_tcon_top_quirks
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sun8i_tcon_top_of_table);
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 26/27] arm64: dts: sun50i: h6: Add HDMI pipeline
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (24 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 25/27] drm: sun4i: add support for " Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-02  7:26 ` [PATCH 27/27] arm64: dts: sun50i: h6: Enable HDMI output on Pine H64 board Jernej Skrabec
  2018-09-02  9:31 ` [PATCH 00/27] Allwinner H6 DE3 and HDMI support Chen-Yu Tsai
  27 siblings, 0 replies; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi, Icenowy Zheng

This commit adds all entries needed for HDMI to function properly.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
[added DE3 bus]
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 201 +++++++++++++++++++
 1 file changed, 201 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 040828d2e2c0..59dda8f89d23 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -6,8 +6,11 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/sun50i-h6-ccu.h>
 #include <dt-bindings/clock/sun50i-h6-r-ccu.h>
+#include <dt-bindings/clock/sun8i-de2.h>
+#include <dt-bindings/clock/sun8i-tcon-top.h>
 #include <dt-bindings/reset/sun50i-h6-ccu.h>
 #include <dt-bindings/reset/sun50i-h6-r-ccu.h>
+#include <dt-bindings/reset/sun8i-de2.h>
 
 / {
 	interrupt-parent = <&gic>;
@@ -86,12 +89,63 @@
 			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
 	};
 
+	de: display-engine {
+		compatible = "allwinner,sun50i-h6-display-engine";
+		allwinner,pipelines = <&mixer0>;
+		status = "disabled";
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
 
+		de3@1000000 {
+			compatible = "allwinner,sun50i-h6-de3",
+				     "allwinner,sun50i-a64-de2";
+			reg = <0x1000000 0x400000>;
+			allwinner,sram = <&de2_sram 1>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0x1000000 0x400000>;
+
+			display_clocks: clock@0 {
+				compatible = "allwinner,sun50i-h6-de3-clk";
+				reg = <0x0 0x10000>;
+				clocks = <&ccu CLK_DE>,
+					 <&ccu CLK_BUS_DE>;
+				clock-names = "mod",
+					      "bus";
+				resets = <&ccu RST_BUS_DE>;
+				#clock-cells = <1>;
+				#reset-cells = <1>;
+			};
+
+			mixer0: mixer@100000 {
+				compatible = "allwinner,sun50i-h6-de3-mixer-0";
+				reg = <0x100000 0x100000>;
+				clocks = <&display_clocks CLK_BUS_MIXER0>,
+					 <&display_clocks CLK_MIXER0>;
+				clock-names = "bus",
+					      "mod";
+				resets = <&display_clocks RST_MIXER0>;
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					mixer0_out: port@1 {
+						reg = <1>;
+
+						mixer0_out_tcon_top_mixer0: endpoint {
+							remote-endpoint = <&tcon_top_mixer0_in_mixer0>;
+						};
+					};
+				};
+			};
+		};
+
 		syscon: syscon@3000000 {
 			compatible = "allwinner,sun50i-h6-system-control",
 				     "allwinner,sun50i-a64-system-control";
@@ -149,6 +203,11 @@
 			interrupt-controller;
 			#interrupt-cells = <3>;
 
+			hdmi_pins: hdmi-pins {
+				pins = "PH8", "PH9", "PH10";
+				function = "hdmi";
+			};
+
 			mmc0_pins: mmc0-pins {
 				pins = "PF0", "PF1", "PF2", "PF3",
 				       "PF4", "PF5";
@@ -258,6 +317,148 @@
 			status = "disabled";
 		};
 
+		hdmi: hdmi@6000000 {
+			compatible = "allwinner,sun50i-h6-dw-hdmi";
+			reg = <0x06000000 0x10000>;
+			reg-io-width = <1>;
+			interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_SLOW>,
+				 <&ccu CLK_HDMI>, <&ccu CLK_HDMI_CEC>,
+				 <&ccu CLK_HDCP>, <&ccu CLK_BUS_HDCP>;
+			clock-names = "iahb", "isfr", "tmds", "cec", "hdcp",
+				      "hdcp-bus";
+			resets = <&ccu RST_BUS_HDMI_SUB>, <&ccu RST_BUS_HDCP>;
+			reset-names = "ctrl", "hdcp";
+			phys = <&hdmi_phy>;
+			phy-names = "hdmi-phy";
+			pinctrl-names = "default";
+			pinctrl-0 = <&hdmi_pins>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				hdmi_in: port@0 {
+					reg = <0>;
+
+					hdmi_in_tcon_top: endpoint {
+						remote-endpoint = <&tcon_top_hdmi_out_hdmi>;
+					};
+				};
+
+				hdmi_out: port@1 {
+					reg = <1>;
+				};
+			};
+		};
+
+		hdmi_phy: hdmi-phy@6010000 {
+			compatible = "allwinner,sun50i-h6-hdmi-phy";
+			reg = <0x06010000 0x10000>;
+			clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_SLOW>;
+			clock-names = "bus", "mod";
+			resets = <&ccu RST_BUS_HDMI>;
+			reset-names = "phy";
+			#phy-cells = <0>;
+		};
+
+		tcon_top: tcon-top@6510000 {
+			compatible = "allwinner,sun50i-h6-tcon-top";
+			reg = <0x06510000 0x1000>;
+			clocks = <&ccu CLK_BUS_TCON_TOP>,
+				 <&ccu CLK_TCON_TV0>;
+			clock-names = "bus",
+				      "tcon-tv0";
+			clock-output-names = "tcon-top-tv0";
+			resets = <&ccu RST_BUS_TCON_TOP>;
+			reset-names = "rst";
+			#clock-cells = <1>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon_top_mixer0_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					tcon_top_mixer0_in_mixer0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&mixer0_out_tcon_top_mixer0>;
+					};
+				};
+
+				tcon_top_mixer0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					tcon_top_mixer0_out_tcon_tv: endpoint@2 {
+						reg = <2>;
+						remote-endpoint = <&tcon_tv_in_tcon_top_mixer0>;
+					};
+				};
+
+				tcon_top_hdmi_in: port@4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+
+					tcon_top_hdmi_in_tcon_tv: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&tcon_tv_out_tcon_top>;
+					};
+				};
+
+				tcon_top_hdmi_out: port@5 {
+					reg = <5>;
+
+					tcon_top_hdmi_out_hdmi: endpoint {
+						remote-endpoint = <&hdmi_in_tcon_top>;
+					};
+				};
+			};
+		};
+
+		tcon_tv: lcd-controller@6515000 {
+			compatible = "allwinner,sun50i-h6-tcon-tv",
+				     "allwinner,sun8i-r40-tcon-tv";
+			reg = <0x06515000 0x1000>;
+			interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_TCON_TV0>,
+				 <&tcon_top CLK_TCON_TOP_TV0>;
+			clock-names = "ahb",
+				      "tcon-ch1";
+			resets = <&ccu RST_BUS_TCON_TV0>;
+			reset-names = "lcd";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon_tv_in: port@0 {
+					reg = <0>;
+
+					tcon_tv_in_tcon_top_mixer0: endpoint {
+						remote-endpoint = <&tcon_top_mixer0_out_tcon_tv>;
+					};
+				};
+
+				tcon_tv_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					tcon_tv_out_tcon_top: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&tcon_top_hdmi_in_tcon_tv>;
+					};
+				};
+			};
+		};
+
 		r_ccu: clock@7010000 {
 			compatible = "allwinner,sun50i-h6-r-ccu";
 			reg = <0x07010000 0x400>;
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH 27/27] arm64: dts: sun50i: h6: Enable HDMI output on Pine H64 board
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (25 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 26/27] arm64: dts: sun50i: h6: Add HDMI pipeline Jernej Skrabec
@ 2018-09-02  7:26 ` Jernej Skrabec
  2018-09-02  9:31 ` [PATCH 00/27] Allwinner H6 DE3 and HDMI support Chen-Yu Tsai
  27 siblings, 0 replies; 66+ messages in thread
From: Jernej Skrabec @ 2018-09-02  7:26 UTC (permalink / raw)
  To: robh+dt, maxime.ripard, wens
  Cc: mark.rutland, mturquette, sboyd, airlied, architt, a.hajda,
	jernej.skrabec, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

Pine H64 board has HDMI type A connector.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 .../boot/dts/allwinner/sun50i-h6-pine-h64.dts | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
index 48daec7f78ba..36db21314996 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
@@ -21,6 +21,17 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 
@@ -41,6 +52,20 @@
 	};
 };
 
+&de {
+	status = "okay";
+};
+
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &mmc0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc0_pins>;
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 66+ messages in thread

* Re: [PATCH 00/27] Allwinner H6 DE3 and HDMI support
  2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
                   ` (26 preceding siblings ...)
  2018-09-02  7:26 ` [PATCH 27/27] arm64: dts: sun50i: h6: Enable HDMI output on Pine H64 board Jernej Skrabec
@ 2018-09-02  9:31 ` Chen-Yu Tsai
  27 siblings, 0 replies; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-02  9:31 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
>
> This series adds support for Display Engine 3.0 and HDMI 2.0a, which
> can be found on H6 SoC.
>
> Display Engine 3.0 in comparison to 2.0 mostly adds features needed for
> displaying and processing 10-bit and AFBC formats, which are not yet
> supported by this series.
>
> This series is based on linux-next at next-20180828, which has working
> R40 display pipeline support. I'll rebase series on later linux-next, if
> needed, once R40 display pipeline support is reintroduced.
>
> I suggest all patches go through allwinner tree, except DRM patches,
> which should go through drm-misc tree.
>
> Last detail, PineH64 model A schematic has DDC_EN signal, which enables
> DDC voltage level shifter. TL Lim, PINE64 founder, said that this
> signal is not actually present on PineH64 model A board. It is, however
> present on PineH64 model B engineering samples, but it will be removed
> in production version. Because of that, I didn't include any code for
> it.
>
> Please take a look.
>
> Best regards,
> Jernej
>
> Icenowy Zheng (7):
>   dt-bindings: sunxi-sram: add binding for Allwinner H6 SRAM C
>   arm64: allwinner: h6: add system controller device tree node

Prefix should be "arm64: dts: allwinner: h6: ".

>   dt-bindings: bus: add H6 DE3 bus binding
>   dt-bindings: display: sunxi: add DT binding for Allwinner H6 DW HDMI
>   drm: sun4i: add quirks for TCON TOP
>   dt-bindings: display: sun4i-drm: document H6 TCON TOP
>   drm: sun4i: add support for H6 TCON TOP
>
> Jernej Skrabec (20):
>   clk: sunxi-ng: Adjust MP clock parent rate when allowed
>   clk: sunxi-ng: Use u64 for calculation of NM rate
>   clk: sunxi-ng: h6: Set video PLLs limits
>   dt-bindings: clock: sun8i-de2: Add H6 DE3 clock description
>   clk: sunxi-ng: Add support for H6 DE3 clocks
>   dt-bindings: display: sun4i-drm: Add H6 display engine compatibles
>   drm/sun4i: Add compatible for H6 display engine
>   drm/sun4i: Rework DE2 register defines
>   drm/sun4i: Add basic support for DE3
>   drm/sun4i: Add support for H6 DE3 mixer 0
>   drm/bridge/synopsys: dw-hdmi: Enable workaround for v2.12a
>   drm/sun4i: Not all DW HDMI controllers has scrambled addresses
>   drm/sun4i: dw-hdmi: Make mode_valid function configurable
>   drm/sun4i: dw-hdmi: Add quirk for setting TMDS clock
>   drm/sun4i: Add support for H6 DW HDMI controller
>   drm/sun4i: Add support for Synopsys HDMI PHY
>   drm/sun4i: Add support for H6 HDMI PHY
>   drm/sun4i: Initialize registers in tcon-top driver
>   arm64: dts: sun50i: h6: Add HDMI pipeline
>   arm64: dts: sun50i: h6: Enable HDMI output on Pine H64 board

Same here.

ChenYu

>
>  .../bindings/bus/sun50i-de2-bus.txt           |   9 +-
>  .../devicetree/bindings/clock/sun8i-de2.txt   |   5 +-
>  .../bindings/display/sunxi/sun4i-drm.txt      |  30 ++-
>  .../devicetree/bindings/sram/sunxi-sram.txt   |   4 +
>  .../boot/dts/allwinner/sun50i-h6-pine-h64.dts |  25 ++
>  arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  | 224 ++++++++++++++++++
>  drivers/clk/sunxi-ng/ccu-sun50i-h6.c          |   4 +
>  drivers/clk/sunxi-ng/ccu-sun8i-de2.c          |  65 +++++
>  drivers/clk/sunxi-ng/ccu-sun8i-de2.h          |   1 +
>  drivers/clk/sunxi-ng/ccu_mp.c                 |  64 ++++-
>  drivers/clk/sunxi-ng/ccu_nm.c                 |  18 +-
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |   1 +
>  drivers/gpu/drm/sun4i/sun4i_drv.c             |   1 +
>  drivers/gpu/drm/sun4i/sun8i_csc.c             |  96 +++++++-
>  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c         |  45 +++-
>  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h         |  14 +-
>  drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c        | 178 +++++++++++++-
>  drivers/gpu/drm/sun4i/sun8i_mixer.c           |  44 +++-
>  drivers/gpu/drm/sun4i/sun8i_mixer.h           |  61 +++--
>  drivers/gpu/drm/sun4i/sun8i_tcon_top.c        |  58 ++++-
>  drivers/gpu/drm/sun4i/sun8i_ui_layer.c        |  47 ++--
>  drivers/gpu/drm/sun4i/sun8i_ui_layer.h        |  37 +--
>  drivers/gpu/drm/sun4i/sun8i_ui_scaler.c       |  45 ++--
>  drivers/gpu/drm/sun4i/sun8i_ui_scaler.h       |  28 +--
>  drivers/gpu/drm/sun4i/sun8i_vi_layer.c        |  55 +++--
>  drivers/gpu/drm/sun4i/sun8i_vi_layer.h        |  25 +-
>  drivers/gpu/drm/sun4i/sun8i_vi_scaler.c       |  85 +++++--
>  drivers/gpu/drm/sun4i/sun8i_vi_scaler.h       |  68 ++++--
>  include/dt-bindings/clock/sun8i-de2.h         |   3 +
>  include/dt-bindings/reset/sun8i-de2.h         |   1 +
>  30 files changed, 1127 insertions(+), 214 deletions(-)
>
> --
> 2.18.0
>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 10/27] drm/sun4i: Add compatible for H6 display engine
  2018-09-02  7:26 ` [PATCH 10/27] drm/sun4i: Add compatible for H6 display engine Jernej Skrabec
@ 2018-09-03 12:18   ` Maxime Ripard
  0 siblings, 0 replies; 66+ messages in thread
From: Maxime Ripard @ 2018-09-03 12:18 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: robh+dt, wens, mark.rutland, mturquette, sboyd, airlied, architt,
	a.hajda, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	dri-devel, linux-sunxi

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

hi,

On Sun, Sep 02, 2018 at 09:26:26AM +0200, Jernej Skrabec wrote:
> H6 is first Allwinner SoC which supports 10 bit colors, HDR and AFBC.
> 
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  drivers/gpu/drm/sun4i/sun4i_drv.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
> index dd19d674055c..e5731d092e1a 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_drv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
> @@ -410,6 +410,7 @@ static int sun4i_drv_remove(struct platform_device *pdev)
>  
>  static const struct of_device_id sun4i_drv_of_table[] = {
>  	{ .compatible = "allwinner,sun4i-a10-display-engine" },
> +	{ .compatible = "allwinner,sun50i-h6-display-engine" },
>  	{ .compatible = "allwinner,sun5i-a10s-display-engine" },
>  	{ .compatible = "allwinner,sun5i-a13-display-engine" },
>  	{ .compatible = "allwinner,sun6i-a31-display-engine" },

While it makes sens from an alphabetical point of view, we usually
follow the number order here (so after sun9i).

Maxime

-- 
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 01/27] dt-bindings: sunxi-sram: add binding for Allwinner H6 SRAM C
  2018-09-02  7:26 ` [PATCH 01/27] dt-bindings: sunxi-sram: add binding for Allwinner H6 SRAM C Jernej Skrabec
@ 2018-09-04  8:39   ` Chen-Yu Tsai
  0 siblings, 0 replies; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-04  8:39 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi, Icenowy Zheng

On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
>
> From: Icenowy Zheng <icenowy@aosc.io>
>
> The Allwinner H6 SoC's DE3 needs the SRAM C section being claimed in the
> system controller to work, like A64 DE2.
>
> As H6 and A64 system controller are quite similar, code is reused now,
> and the A64 fallback compatible string is added after the H6 compatible
> string.
>
> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> [fixed typo in compatible string]
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

Reviewed-by: Chen-Yu Tsai <wens@csie.org>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 02/27] arm64: allwinner: h6: add system controller device tree node
  2018-09-02  7:26 ` [PATCH 02/27] arm64: allwinner: h6: add system controller device tree node Jernej Skrabec
@ 2018-09-04  8:40   ` Chen-Yu Tsai
  2018-09-04  8:44     ` [linux-sunxi] " Icenowy Zheng
  0 siblings, 1 reply; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-04  8:40 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi, Icenowy Zheng

On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
>
> From: Icenowy Zheng <icenowy@aosc.io>
>
> As we have already binding for the H6 system controller, add its node
> to the device tree.
>
> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> [fixed compatible string]
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

Reviewed-by: Chen-Yu Tsai <wens@csie.org>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [linux-sunxi] Re: [PATCH 02/27] arm64: allwinner: h6: add system controller device tree node
  2018-09-04  8:40   ` Chen-Yu Tsai
@ 2018-09-04  8:44     ` Icenowy Zheng
  2018-09-12 14:49       ` Chen-Yu Tsai
  0 siblings, 1 reply; 66+ messages in thread
From: Icenowy Zheng @ 2018-09-04  8:44 UTC (permalink / raw)
  To: wens, Chen-Yu Tsai, Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi



于 2018年9月4日 GMT+08:00 下午4:40:56, Chen-Yu Tsai <wens@csie.org> 写到:
>On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net>
>wrote:
>>
>> From: Icenowy Zheng <icenowy@aosc.io>
>>
>> As we have already binding for the H6 system controller, add its node
>> to the device tree.
>>
>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
>> [fixed compatible string]
>> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>
>Reviewed-by: Chen-Yu Tsai <wens@csie.org>

By the way can these patches be applied first? (patches
related to syscon).

They're also needed for EMAC.


^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 07/27] dt-bindings: clock: sun8i-de2: Add H6 DE3 clock description
  2018-09-02  7:26 ` [PATCH 07/27] dt-bindings: clock: sun8i-de2: Add H6 DE3 clock description Jernej Skrabec
@ 2018-09-04  8:59   ` Chen-Yu Tsai
  2018-09-04  9:05     ` Chen-Yu Tsai
  0 siblings, 1 reply; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-04  8:59 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

Hi,

On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
>
> This commit adds necessary description and dt includes for H6 DE3 clock.
> It is very similar to others, but memory region has some additional
> registers not found in DE2.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  Documentation/devicetree/bindings/clock/sun8i-de2.txt | 5 +++--
>  include/dt-bindings/clock/sun8i-de2.h                 | 3 +++
>  include/dt-bindings/reset/sun8i-de2.h                 | 1 +
>  3 files changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/clock/sun8i-de2.txt b/Documentation/devicetree/bindings/clock/sun8i-de2.txt
> index e94582e8b8a9..41a52c2acffd 100644
> --- a/Documentation/devicetree/bindings/clock/sun8i-de2.txt
> +++ b/Documentation/devicetree/bindings/clock/sun8i-de2.txt
> @@ -1,5 +1,5 @@
> -Allwinner Display Engine 2.0 Clock Control Binding
> ---------------------------------------------------
> +Allwinner Display Engine 2.0/3.0 Clock Control Binding
> +------------------------------------------------------
>
>  Required properties :
>  - compatible: must contain one of the following compatibles:
> @@ -8,6 +8,7 @@ Required properties :
>                 - "allwinner,sun8i-v3s-de2-clk"
>                 - "allwinner,sun50i-a64-de2-clk"
>                 - "allwinner,sun50i-h5-de2-clk"
> +               - "allwinner,sun50i-h6-de3-clk"
>
>  - reg: Must contain the registers base address and length
>  - clocks: phandle to the clocks feeding the display engine subsystem.
> diff --git a/include/dt-bindings/clock/sun8i-de2.h b/include/dt-bindings/clock/sun8i-de2.h
> index 3bed63b524aa..7768f73b051e 100644
> --- a/include/dt-bindings/clock/sun8i-de2.h
> +++ b/include/dt-bindings/clock/sun8i-de2.h
> @@ -15,4 +15,7 @@
>  #define CLK_MIXER1             7
>  #define CLK_WB                 8
>
> +#define CLK_BUS_ROT            9
> +#define CLK_ROT                        10
> +
>  #endif /* _DT_BINDINGS_CLOCK_SUN8I_DE2_H_ */
> diff --git a/include/dt-bindings/reset/sun8i-de2.h b/include/dt-bindings/reset/sun8i-de2.h
> index 9526017432f0..1c36a6ac86d6 100644
> --- a/include/dt-bindings/reset/sun8i-de2.h
> +++ b/include/dt-bindings/reset/sun8i-de2.h
> @@ -10,5 +10,6 @@
>  #define RST_MIXER0     0
>  #define RST_MIXER1     1
>  #define RST_WB         2
> +#define RST_ROT                3

Looking at the DE 2.0 register guide, the "Rotate" related fields are also
found on the A83T. So this is not DE 3.0 specific. And you could also have
the H6 DE3 compatible fall back to the A83T for the common parts.

ChenYu

>
>  #endif /* _DT_BINDINGS_RESET_SUN8I_DE2_H_ */
> --
> 2.18.0
>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 08/27] clk: sunxi-ng: Add support for H6 DE3 clocks
  2018-09-02  7:26 ` [PATCH 08/27] clk: sunxi-ng: Add support for H6 DE3 clocks Jernej Skrabec
@ 2018-09-04  9:04   ` Chen-Yu Tsai
  2018-09-04 17:45     ` Jernej Škrabec
  0 siblings, 1 reply; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-04  9:04 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi, Icenowy Zheng

On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
>
> Support for mixer0, mixer1, writeback and rotation units is added.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> ---
>  drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 65 ++++++++++++++++++++++++++++
>  drivers/clk/sunxi-ng/ccu-sun8i-de2.h |  1 +
>  2 files changed, 66 insertions(+)
>
> diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
> index bae5ee67a797..4535c1c27d27 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
> +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
> @@ -31,6 +31,8 @@ static SUNXI_CCU_GATE(bus_mixer1_clk, "bus-mixer1",   "bus-de",
>                       0x04, BIT(1), 0);
>  static SUNXI_CCU_GATE(bus_wb_clk,      "bus-wb",       "bus-de",
>                       0x04, BIT(2), 0);
> +static SUNXI_CCU_GATE(bus_rot_clk,     "bus-rot",      "bus-de",
> +                     0x04, BIT(3), 0);
>
>  static SUNXI_CCU_GATE(mixer0_clk,      "mixer0",       "mixer0-div",
>                       0x00, BIT(0), CLK_SET_RATE_PARENT);
> @@ -38,6 +40,8 @@ static SUNXI_CCU_GATE(mixer1_clk,     "mixer1",       "mixer1-div",
>                       0x00, BIT(1), CLK_SET_RATE_PARENT);
>  static SUNXI_CCU_GATE(wb_clk,          "wb",           "wb-div",
>                       0x00, BIT(2), CLK_SET_RATE_PARENT);
> +static SUNXI_CCU_GATE(rot_clk,         "rot",          "rot-div",
> +                     0x00, BIT(3), CLK_SET_RATE_PARENT);
>
>  static SUNXI_CCU_M(mixer0_div_clk, "mixer0-div", "de", 0x0c, 0, 4,
>                    CLK_SET_RATE_PARENT);
> @@ -45,6 +49,8 @@ static SUNXI_CCU_M(mixer1_div_clk, "mixer1-div", "de", 0x0c, 4, 4,
>                    CLK_SET_RATE_PARENT);
>  static SUNXI_CCU_M(wb_div_clk, "wb-div", "de", 0x0c, 8, 4,
>                    CLK_SET_RATE_PARENT);
> +static SUNXI_CCU_M(rot_div_clk, "rot-div", "de", 0x0c, 0x0c, 4,
> +                  CLK_SET_RATE_PARENT);
>
>  static SUNXI_CCU_M(mixer0_div_a83_clk, "mixer0-div", "pll-de", 0x0c, 0, 4,
>                    CLK_SET_RATE_PARENT);
> @@ -53,6 +59,24 @@ static SUNXI_CCU_M(mixer1_div_a83_clk, "mixer1-div", "pll-de", 0x0c, 4, 4,
>  static SUNXI_CCU_M(wb_div_a83_clk, "wb-div", "pll-de", 0x0c, 8, 4,
>                    CLK_SET_RATE_PARENT);
>
> +static struct ccu_common *sun50i_h6_de3_clks[] = {
> +       &mixer0_clk.common,
> +       &mixer1_clk.common,
> +       &wb_clk.common,
> +
> +       &bus_mixer0_clk.common,
> +       &bus_mixer1_clk.common,
> +       &bus_wb_clk.common,
> +
> +       &mixer0_div_clk.common,
> +       &mixer1_div_clk.common,
> +       &wb_div_clk.common,
> +
> +       &bus_rot_clk.common,
> +       &rot_clk.common,
> +       &rot_div_clk.common,
> +};
> +
>  static struct ccu_common *sun8i_a83t_de2_clks[] = {
>         &mixer0_clk.common,
>         &mixer1_clk.common,
> @@ -92,6 +116,26 @@ static struct ccu_common *sun8i_v3s_de2_clks[] = {
>         &wb_div_clk.common,
>  };
>
> +static struct clk_hw_onecell_data sun50i_h6_de3_hw_clks = {
> +       .hws    = {
> +               [CLK_MIXER0]            = &mixer0_clk.common.hw,
> +               [CLK_MIXER1]            = &mixer1_clk.common.hw,
> +               [CLK_WB]                = &wb_clk.common.hw,
> +               [CLK_ROT]               = &rot_clk.common.hw,
> +
> +               [CLK_BUS_MIXER0]        = &bus_mixer0_clk.common.hw,
> +               [CLK_BUS_MIXER1]        = &bus_mixer1_clk.common.hw,
> +               [CLK_BUS_WB]            = &bus_wb_clk.common.hw,
> +               [CLK_BUS_ROT]           = &bus_rot_clk.common.hw,
> +
> +               [CLK_MIXER0_DIV]        = &mixer0_div_clk.common.hw,
> +               [CLK_MIXER1_DIV]        = &mixer1_div_clk.common.hw,
> +               [CLK_WB_DIV]            = &wb_div_clk.common.hw,
> +               [CLK_ROT_DIV]           = &rot_div_clk.common.hw,
> +       },
> +       .num    = 12,

It's best not to openly code these. It is error prone, like having
an index beyond .num, which then never gets registered.

Instead, please update CLK_NUMBERS and use that instead. sunxi_ccu_probe()
can handle holes in .hws.

On the other hand, it can't handle holes in the ccu_reset_map. Hope we
never have to deal with such an instance.

ChenYu

> +};
> +
>  static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = {
>         .hws    = {
>                 [CLK_MIXER0]            = &mixer0_clk.common.hw,
> @@ -156,6 +200,13 @@ static struct ccu_reset_map sun50i_a64_de2_resets[] = {
>         [RST_WB]        = { 0x08, BIT(2) },
>  };
>
> +static struct ccu_reset_map sun50i_h6_de3_resets[] = {
> +       [RST_MIXER0]    = { 0x08, BIT(0) },
> +       [RST_MIXER1]    = { 0x08, BIT(1) },
> +       [RST_WB]        = { 0x08, BIT(2) },
> +       [RST_ROT]       = { 0x08, BIT(3) },
> +};
> +
>  static const struct sunxi_ccu_desc sun8i_a83t_de2_clk_desc = {
>         .ccu_clks       = sun8i_a83t_de2_clks,
>         .num_ccu_clks   = ARRAY_SIZE(sun8i_a83t_de2_clks),
> @@ -186,6 +237,16 @@ static const struct sunxi_ccu_desc sun50i_a64_de2_clk_desc = {
>         .num_resets     = ARRAY_SIZE(sun50i_a64_de2_resets),
>  };
>
> +static const struct sunxi_ccu_desc sun50i_h6_de3_clk_desc = {
> +       .ccu_clks       = sun50i_h6_de3_clks,
> +       .num_ccu_clks   = ARRAY_SIZE(sun50i_h6_de3_clks),
> +
> +       .hw_clks        = &sun50i_h6_de3_hw_clks,
> +
> +       .resets         = sun50i_h6_de3_resets,
> +       .num_resets     = ARRAY_SIZE(sun50i_h6_de3_resets),
> +};
> +
>  static const struct sunxi_ccu_desc sun8i_v3s_de2_clk_desc = {
>         .ccu_clks       = sun8i_v3s_de2_clks,
>         .num_ccu_clks   = ARRAY_SIZE(sun8i_v3s_de2_clks),
> @@ -296,6 +357,10 @@ static const struct of_device_id sunxi_de2_clk_ids[] = {
>                 .compatible = "allwinner,sun50i-h5-de2-clk",
>                 .data = &sun50i_a64_de2_clk_desc,
>         },
> +       {
> +               .compatible = "allwinner,sun50i-h6-de3-clk",
> +               .data = &sun50i_h6_de3_clk_desc,
> +       },
>         { }
>  };
>
> diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.h b/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
> index 530c006e0ae9..27bd88539f42 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
> +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
> @@ -22,6 +22,7 @@
>  #define CLK_MIXER0_DIV 3
>  #define CLK_MIXER1_DIV 4
>  #define CLK_WB_DIV     5
> +#define CLK_ROT_DIV    11
>
>  #define CLK_NUMBER     (CLK_WB + 1)
>
> --
> 2.18.0
>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 07/27] dt-bindings: clock: sun8i-de2: Add H6 DE3 clock description
  2018-09-04  8:59   ` Chen-Yu Tsai
@ 2018-09-04  9:05     ` Chen-Yu Tsai
  0 siblings, 0 replies; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-04  9:05 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

On Tue, Sep 4, 2018 at 4:59 PM Chen-Yu Tsai <wens@csie.org> wrote:
>
> Hi,
>
> On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> >
> > This commit adds necessary description and dt includes for H6 DE3 clock.
> > It is very similar to others, but memory region has some additional
> > registers not found in DE2.
> >
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> >  Documentation/devicetree/bindings/clock/sun8i-de2.txt | 5 +++--
> >  include/dt-bindings/clock/sun8i-de2.h                 | 3 +++
> >  include/dt-bindings/reset/sun8i-de2.h                 | 1 +
> >  3 files changed, 7 insertions(+), 2 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/clock/sun8i-de2.txt b/Documentation/devicetree/bindings/clock/sun8i-de2.txt
> > index e94582e8b8a9..41a52c2acffd 100644
> > --- a/Documentation/devicetree/bindings/clock/sun8i-de2.txt
> > +++ b/Documentation/devicetree/bindings/clock/sun8i-de2.txt
> > @@ -1,5 +1,5 @@
> > -Allwinner Display Engine 2.0 Clock Control Binding
> > ---------------------------------------------------
> > +Allwinner Display Engine 2.0/3.0 Clock Control Binding
> > +------------------------------------------------------
> >
> >  Required properties :
> >  - compatible: must contain one of the following compatibles:
> > @@ -8,6 +8,7 @@ Required properties :
> >                 - "allwinner,sun8i-v3s-de2-clk"
> >                 - "allwinner,sun50i-a64-de2-clk"
> >                 - "allwinner,sun50i-h5-de2-clk"
> > +               - "allwinner,sun50i-h6-de3-clk"
> >
> >  - reg: Must contain the registers base address and length
> >  - clocks: phandle to the clocks feeding the display engine subsystem.
> > diff --git a/include/dt-bindings/clock/sun8i-de2.h b/include/dt-bindings/clock/sun8i-de2.h
> > index 3bed63b524aa..7768f73b051e 100644
> > --- a/include/dt-bindings/clock/sun8i-de2.h
> > +++ b/include/dt-bindings/clock/sun8i-de2.h
> > @@ -15,4 +15,7 @@
> >  #define CLK_MIXER1             7
> >  #define CLK_WB                 8
> >
> > +#define CLK_BUS_ROT            9
> > +#define CLK_ROT                        10
> > +
> >  #endif /* _DT_BINDINGS_CLOCK_SUN8I_DE2_H_ */
> > diff --git a/include/dt-bindings/reset/sun8i-de2.h b/include/dt-bindings/reset/sun8i-de2.h
> > index 9526017432f0..1c36a6ac86d6 100644
> > --- a/include/dt-bindings/reset/sun8i-de2.h
> > +++ b/include/dt-bindings/reset/sun8i-de2.h
> > @@ -10,5 +10,6 @@
> >  #define RST_MIXER0     0
> >  #define RST_MIXER1     1
> >  #define RST_WB         2
> > +#define RST_ROT                3
>
> Looking at the DE 2.0 register guide, the "Rotate" related fields are also
> found on the A83T. So this is not DE 3.0 specific. And you could also have
> the H6 DE3 compatible fall back to the A83T for the common parts.

I take that back. The A83T has a different clock tree structure because it
lacks the DE mod clock, so it's not compatible.

> ChenYu
>
> >
> >  #endif /* _DT_BINDINGS_RESET_SUN8I_DE2_H_ */
> > --
> > 2.18.0
> >

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 05/27] clk: sunxi-ng: Use u64 for calculation of NM rate
  2018-09-02  7:26 ` [PATCH 05/27] clk: sunxi-ng: Use u64 for calculation of NM rate Jernej Skrabec
@ 2018-09-04  9:18   ` Chen-Yu Tsai
  2018-09-04 18:06     ` Jernej Škrabec
  0 siblings, 1 reply; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-04  9:18 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
>
> Allwinner H6 SoC has multiplier N range between 1 and 254. Since parent
> rate is 24MHz, intermediate result when calculating final rate easily
> overflows 32 bit variable.
>
> Because of that, introduce function for calculating clock rate which
> uses 64 bit variable for intermediate result.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

The code looks good. The A80's Video PLLs are also affected by this.
The range for N on the A80 is 12 ~ 255.

Can you add fixes and stable tags?

ChenYu

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 06/27] clk: sunxi-ng: h6: Set video PLLs limits
  2018-09-02  7:26 ` [PATCH 06/27] clk: sunxi-ng: h6: Set video PLLs limits Jernej Skrabec
@ 2018-09-04 15:49   ` kbuild test robot
  2018-09-04 15:49   ` kbuild test robot
  1 sibling, 0 replies; 66+ messages in thread
From: kbuild test robot @ 2018-09-04 15:49 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: kbuild-all, robh+dt, maxime.ripard, wens, mark.rutland,
	mturquette, sboyd, airlied, architt, a.hajda, jernej.skrabec,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

Hi Jernej,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on sunxi/sunxi/for-next]
[also build test WARNING on v4.19-rc2 next-20180831]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Jernej-Skrabec/Allwinner-H6-DE3-and-HDMI-support/20180903-082543
base:   https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git sunxi/for-next
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__
:::::: branch date: 6 hours ago
:::::: commit date: 6 hours ago

>> drivers/clk/sunxi-ng/ccu-sun50i-h6.c:124:27: sparse: constant 2400000000 is so big it is long
   drivers/clk/sunxi-ng/ccu-sun50i-h6.c:142:27: sparse: constant 2400000000 is so big it is long

# https://github.com/0day-ci/linux/commit/752a88510f0bcada69753fccb31adb187f80f29a
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout 752a88510f0bcada69753fccb31adb187f80f29a
vim +124 drivers/clk/sunxi-ng/ccu-sun50i-h6.c

524353ea4 Icenowy Zheng  2018-03-16  111  
524353ea4 Icenowy Zheng  2018-03-16  112  /*
524353ea4 Icenowy Zheng  2018-03-16  113   * For Video PLLs, the output divider is described as "used for testing"
524353ea4 Icenowy Zheng  2018-03-16  114   * in the user manual. So it's not modelled and forced to 0.
524353ea4 Icenowy Zheng  2018-03-16  115   */
524353ea4 Icenowy Zheng  2018-03-16  116  #define SUN50I_H6_PLL_VIDEO0_REG	0x040
524353ea4 Icenowy Zheng  2018-03-16  117  static struct ccu_nm pll_video0_clk = {
524353ea4 Icenowy Zheng  2018-03-16  118  	.enable		= BIT(31),
524353ea4 Icenowy Zheng  2018-03-16  119  	.lock		= BIT(28),
524353ea4 Icenowy Zheng  2018-03-16  120  	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
524353ea4 Icenowy Zheng  2018-03-16  121  	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
524353ea4 Icenowy Zheng  2018-03-16  122  	.fixed_post_div	= 4,
752a88510 Jernej Skrabec 2018-09-02  123  	.min_rate	= 288000000,
752a88510 Jernej Skrabec 2018-09-02 @124  	.max_rate	= 2400000000,
524353ea4 Icenowy Zheng  2018-03-16  125  	.common		= {
524353ea4 Icenowy Zheng  2018-03-16  126  		.reg		= 0x040,
524353ea4 Icenowy Zheng  2018-03-16  127  		.features	= CCU_FEATURE_FIXED_POSTDIV,
524353ea4 Icenowy Zheng  2018-03-16  128  		.hw.init	= CLK_HW_INIT("pll-video0", "osc24M",
524353ea4 Icenowy Zheng  2018-03-16  129  					      &ccu_nm_ops,
524353ea4 Icenowy Zheng  2018-03-16  130  					      CLK_SET_RATE_UNGATE),
524353ea4 Icenowy Zheng  2018-03-16  131  	},
524353ea4 Icenowy Zheng  2018-03-16  132  };
524353ea4 Icenowy Zheng  2018-03-16  133  

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

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 06/27] clk: sunxi-ng: h6: Set video PLLs limits
  2018-09-02  7:26 ` [PATCH 06/27] clk: sunxi-ng: h6: Set video PLLs limits Jernej Skrabec
  2018-09-04 15:49   ` kbuild test robot
@ 2018-09-04 15:49   ` kbuild test robot
  1 sibling, 0 replies; 66+ messages in thread
From: kbuild test robot @ 2018-09-04 15:49 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: kbuild-all, robh+dt, maxime.ripard, wens, mark.rutland,
	mturquette, sboyd, airlied, architt, a.hajda, jernej.skrabec,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

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

Hi Jernej,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on sunxi/sunxi/for-next]
[also build test WARNING on v4.19-rc2 next-20180831]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Jernej-Skrabec/Allwinner-H6-DE3-and-HDMI-support/20180903-082543
base:   https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git sunxi/for-next
config: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.2.0 make.cross ARCH=arm 
:::::: branch date: 2 hours ago
:::::: commit date: 2 hours ago

All warnings (new ones prefixed by >>):

>> drivers/clk/sunxi-ng/ccu-sun50i-h6.c:124:2: warning: this decimal constant is unsigned only in ISO C90
     .max_rate = 2400000000,
     ^
   drivers/clk/sunxi-ng/ccu-sun50i-h6.c:142:2: warning: this decimal constant is unsigned only in ISO C90
     .max_rate = 2400000000,
     ^

# https://github.com/0day-ci/linux/commit/752a88510f0bcada69753fccb31adb187f80f29a
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout 752a88510f0bcada69753fccb31adb187f80f29a
vim +124 drivers/clk/sunxi-ng/ccu-sun50i-h6.c

524353ea4 Icenowy Zheng  2018-03-16  111  
524353ea4 Icenowy Zheng  2018-03-16  112  /*
524353ea4 Icenowy Zheng  2018-03-16  113   * For Video PLLs, the output divider is described as "used for testing"
524353ea4 Icenowy Zheng  2018-03-16  114   * in the user manual. So it's not modelled and forced to 0.
524353ea4 Icenowy Zheng  2018-03-16  115   */
524353ea4 Icenowy Zheng  2018-03-16  116  #define SUN50I_H6_PLL_VIDEO0_REG	0x040
524353ea4 Icenowy Zheng  2018-03-16  117  static struct ccu_nm pll_video0_clk = {
524353ea4 Icenowy Zheng  2018-03-16  118  	.enable		= BIT(31),
524353ea4 Icenowy Zheng  2018-03-16  119  	.lock		= BIT(28),
524353ea4 Icenowy Zheng  2018-03-16  120  	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
524353ea4 Icenowy Zheng  2018-03-16  121  	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
524353ea4 Icenowy Zheng  2018-03-16  122  	.fixed_post_div	= 4,
752a88510 Jernej Skrabec 2018-09-02  123  	.min_rate	= 288000000,
752a88510 Jernej Skrabec 2018-09-02 @124  	.max_rate	= 2400000000,
524353ea4 Icenowy Zheng  2018-03-16  125  	.common		= {
524353ea4 Icenowy Zheng  2018-03-16  126  		.reg		= 0x040,
524353ea4 Icenowy Zheng  2018-03-16  127  		.features	= CCU_FEATURE_FIXED_POSTDIV,
524353ea4 Icenowy Zheng  2018-03-16  128  		.hw.init	= CLK_HW_INIT("pll-video0", "osc24M",
524353ea4 Icenowy Zheng  2018-03-16  129  					      &ccu_nm_ops,
524353ea4 Icenowy Zheng  2018-03-16  130  					      CLK_SET_RATE_UNGATE),
524353ea4 Icenowy Zheng  2018-03-16  131  	},
524353ea4 Icenowy Zheng  2018-03-16  132  };
524353ea4 Icenowy Zheng  2018-03-16  133  

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

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

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 08/27] clk: sunxi-ng: Add support for H6 DE3 clocks
  2018-09-04  9:04   ` Chen-Yu Tsai
@ 2018-09-04 17:45     ` Jernej Škrabec
  2018-09-12 12:20       ` Chen-Yu Tsai
  0 siblings, 1 reply; 66+ messages in thread
From: Jernej Škrabec @ 2018-09-04 17:45 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi, Icenowy Zheng

Dne torek, 04. september 2018 ob 11:04:21 CEST je Chen-Yu Tsai napisal(a):
> On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > Support for mixer0, mixer1, writeback and rotation units is added.
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> > ---
> > 
> >  drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 65 ++++++++++++++++++++++++++++
> >  drivers/clk/sunxi-ng/ccu-sun8i-de2.h |  1 +
> >  2 files changed, 66 insertions(+)
> > 
> > diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
> > b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c index bae5ee67a797..4535c1c27d27
> > 100644
> > --- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
> > +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
> > @@ -31,6 +31,8 @@ static SUNXI_CCU_GATE(bus_mixer1_clk, "bus-mixer1",  
> > "bus-de",> 
> >                       0x04, BIT(1), 0);
> >  
> >  static SUNXI_CCU_GATE(bus_wb_clk,      "bus-wb",       "bus-de",
> >  
> >                       0x04, BIT(2), 0);
> > 
> > +static SUNXI_CCU_GATE(bus_rot_clk,     "bus-rot",      "bus-de",
> > +                     0x04, BIT(3), 0);
> > 
> >  static SUNXI_CCU_GATE(mixer0_clk,      "mixer0",       "mixer0-div",
> >  
> >                       0x00, BIT(0), CLK_SET_RATE_PARENT);
> > 
> > @@ -38,6 +40,8 @@ static SUNXI_CCU_GATE(mixer1_clk,     "mixer1",      
> > "mixer1-div",> 
> >                       0x00, BIT(1), CLK_SET_RATE_PARENT);
> >  
> >  static SUNXI_CCU_GATE(wb_clk,          "wb",           "wb-div",
> >  
> >                       0x00, BIT(2), CLK_SET_RATE_PARENT);
> > 
> > +static SUNXI_CCU_GATE(rot_clk,         "rot",          "rot-div",
> > +                     0x00, BIT(3), CLK_SET_RATE_PARENT);
> > 
> >  static SUNXI_CCU_M(mixer0_div_clk, "mixer0-div", "de", 0x0c, 0, 4,
> >  
> >                    CLK_SET_RATE_PARENT);
> > 
> > @@ -45,6 +49,8 @@ static SUNXI_CCU_M(mixer1_div_clk, "mixer1-div", "de",
> > 0x0c, 4, 4,> 
> >                    CLK_SET_RATE_PARENT);
> >  
> >  static SUNXI_CCU_M(wb_div_clk, "wb-div", "de", 0x0c, 8, 4,
> >  
> >                    CLK_SET_RATE_PARENT);
> > 
> > +static SUNXI_CCU_M(rot_div_clk, "rot-div", "de", 0x0c, 0x0c, 4,
> > +                  CLK_SET_RATE_PARENT);
> > 
> >  static SUNXI_CCU_M(mixer0_div_a83_clk, "mixer0-div", "pll-de", 0x0c, 0,
> >  4,
> >  
> >                    CLK_SET_RATE_PARENT);
> > 
> > @@ -53,6 +59,24 @@ static SUNXI_CCU_M(mixer1_div_a83_clk, "mixer1-div",
> > "pll-de", 0x0c, 4, 4,> 
> >  static SUNXI_CCU_M(wb_div_a83_clk, "wb-div", "pll-de", 0x0c, 8, 4,
> >  
> >                    CLK_SET_RATE_PARENT);
> > 
> > +static struct ccu_common *sun50i_h6_de3_clks[] = {
> > +       &mixer0_clk.common,
> > +       &mixer1_clk.common,
> > +       &wb_clk.common,
> > +
> > +       &bus_mixer0_clk.common,
> > +       &bus_mixer1_clk.common,
> > +       &bus_wb_clk.common,
> > +
> > +       &mixer0_div_clk.common,
> > +       &mixer1_div_clk.common,
> > +       &wb_div_clk.common,
> > +
> > +       &bus_rot_clk.common,
> > +       &rot_clk.common,
> > +       &rot_div_clk.common,
> > +};
> > +
> > 
> >  static struct ccu_common *sun8i_a83t_de2_clks[] = {
> >  
> >         &mixer0_clk.common,
> >         &mixer1_clk.common,
> > 
> > @@ -92,6 +116,26 @@ static struct ccu_common *sun8i_v3s_de2_clks[] = {
> > 
> >         &wb_div_clk.common,
> >  
> >  };
> > 
> > +static struct clk_hw_onecell_data sun50i_h6_de3_hw_clks = {
> > +       .hws    = {
> > +               [CLK_MIXER0]            = &mixer0_clk.common.hw,
> > +               [CLK_MIXER1]            = &mixer1_clk.common.hw,
> > +               [CLK_WB]                = &wb_clk.common.hw,
> > +               [CLK_ROT]               = &rot_clk.common.hw,
> > +
> > +               [CLK_BUS_MIXER0]        = &bus_mixer0_clk.common.hw,
> > +               [CLK_BUS_MIXER1]        = &bus_mixer1_clk.common.hw,
> > +               [CLK_BUS_WB]            = &bus_wb_clk.common.hw,
> > +               [CLK_BUS_ROT]           = &bus_rot_clk.common.hw,
> > +
> > +               [CLK_MIXER0_DIV]        = &mixer0_div_clk.common.hw,
> > +               [CLK_MIXER1_DIV]        = &mixer1_div_clk.common.hw,
> > +               [CLK_WB_DIV]            = &wb_div_clk.common.hw,
> > +               [CLK_ROT_DIV]           = &rot_div_clk.common.hw,
> > +       },
> > +       .num    = 12,
> 
> It's best not to openly code these. It is error prone, like having
> an index beyond .num, which then never gets registered.
> 
> Instead, please update CLK_NUMBERS and use that instead. sunxi_ccu_probe()
> can handle holes in .hws.

I'm not sure this will work. All newly introduced indices are at the end, so 
other arrays will still have same length (hole at the end). You will just 
claim that arrays are larger than they really are, which means bad things.

But I take any other suggestion. I really can't think of better solution.

Best regards,
Jernej

> 
> On the other hand, it can't handle holes in the ccu_reset_map. Hope we
> never have to deal with such an instance.
> 
> ChenYu
> 
> > +};
> > +
> > 
> >  static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = {
> >  
> >         .hws    = {
> >         
> >                 [CLK_MIXER0]            = &mixer0_clk.common.hw,
> > 
> > @@ -156,6 +200,13 @@ static struct ccu_reset_map sun50i_a64_de2_resets[] =
> > {> 
> >         [RST_WB]        = { 0x08, BIT(2) },
> >  
> >  };
> > 
> > +static struct ccu_reset_map sun50i_h6_de3_resets[] = {
> > +       [RST_MIXER0]    = { 0x08, BIT(0) },
> > +       [RST_MIXER1]    = { 0x08, BIT(1) },
> > +       [RST_WB]        = { 0x08, BIT(2) },
> > +       [RST_ROT]       = { 0x08, BIT(3) },
> > +};
> > +
> > 
> >  static const struct sunxi_ccu_desc sun8i_a83t_de2_clk_desc = {
> >  
> >         .ccu_clks       = sun8i_a83t_de2_clks,
> >         .num_ccu_clks   = ARRAY_SIZE(sun8i_a83t_de2_clks),
> > 
> > @@ -186,6 +237,16 @@ static const struct sunxi_ccu_desc
> > sun50i_a64_de2_clk_desc = {> 
> >         .num_resets     = ARRAY_SIZE(sun50i_a64_de2_resets),
> >  
> >  };
> > 
> > +static const struct sunxi_ccu_desc sun50i_h6_de3_clk_desc = {
> > +       .ccu_clks       = sun50i_h6_de3_clks,
> > +       .num_ccu_clks   = ARRAY_SIZE(sun50i_h6_de3_clks),
> > +
> > +       .hw_clks        = &sun50i_h6_de3_hw_clks,
> > +
> > +       .resets         = sun50i_h6_de3_resets,
> > +       .num_resets     = ARRAY_SIZE(sun50i_h6_de3_resets),
> > +};
> > +
> > 
> >  static const struct sunxi_ccu_desc sun8i_v3s_de2_clk_desc = {
> >  
> >         .ccu_clks       = sun8i_v3s_de2_clks,
> >         .num_ccu_clks   = ARRAY_SIZE(sun8i_v3s_de2_clks),
> > 
> > @@ -296,6 +357,10 @@ static const struct of_device_id sunxi_de2_clk_ids[]
> > = {> 
> >                 .compatible = "allwinner,sun50i-h5-de2-clk",
> >                 .data = &sun50i_a64_de2_clk_desc,
> >         
> >         },
> > 
> > +       {
> > +               .compatible = "allwinner,sun50i-h6-de3-clk",
> > +               .data = &sun50i_h6_de3_clk_desc,
> > +       },
> > 
> >         { }
> >  
> >  };
> > 
> > diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
> > b/drivers/clk/sunxi-ng/ccu-sun8i-de2.h index 530c006e0ae9..27bd88539f42
> > 100644
> > --- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
> > +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
> > @@ -22,6 +22,7 @@
> > 
> >  #define CLK_MIXER0_DIV 3
> >  #define CLK_MIXER1_DIV 4
> >  #define CLK_WB_DIV     5
> > 
> > +#define CLK_ROT_DIV    11
> > 
> >  #define CLK_NUMBER     (CLK_WB + 1)
> > 
> > --
> > 2.18.0





^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 05/27] clk: sunxi-ng: Use u64 for calculation of NM rate
  2018-09-04  9:18   ` Chen-Yu Tsai
@ 2018-09-04 18:06     ` Jernej Škrabec
  0 siblings, 0 replies; 66+ messages in thread
From: Jernej Škrabec @ 2018-09-04 18:06 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

Dne torek, 04. september 2018 ob 11:18:47 CEST je Chen-Yu Tsai napisal(a):
> On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > Allwinner H6 SoC has multiplier N range between 1 and 254. Since parent
> > rate is 24MHz, intermediate result when calculating final rate easily
> > overflows 32 bit variable.
> > 
> > Because of that, introduce function for calculating clock rate which
> > uses 64 bit variable for intermediate result.
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> 
> The code looks good. The A80's Video PLLs are also affected by this.
> The range for N on the A80 is 12 ~ 255.
> 
> Can you add fixes and stable tags?

Sure.

> 
> ChenYu





^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 08/27] clk: sunxi-ng: Add support for H6 DE3 clocks
  2018-09-04 17:45     ` Jernej Škrabec
@ 2018-09-12 12:20       ` Chen-Yu Tsai
  2018-09-12 14:55         ` Jernej Škrabec
  0 siblings, 1 reply; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-12 12:20 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi, Icenowy Zheng

On Wed, Sep 5, 2018 at 1:46 AM Jernej Škrabec <jernej.skrabec@siol.net> wrote:
>
> Dne torek, 04. september 2018 ob 11:04:21 CEST je Chen-Yu Tsai napisal(a):
> > On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net>
> wrote:
> > > Support for mixer0, mixer1, writeback and rotation units is added.
> > >
> > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> > > ---
> > >
> > >  drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 65 ++++++++++++++++++++++++++++
> > >  drivers/clk/sunxi-ng/ccu-sun8i-de2.h |  1 +
> > >  2 files changed, 66 insertions(+)
> > >
> > > diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
> > > b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c index bae5ee67a797..4535c1c27d27
> > > 100644
> > > --- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
> > > +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
> > > @@ -31,6 +31,8 @@ static SUNXI_CCU_GATE(bus_mixer1_clk, "bus-mixer1",
> > > "bus-de",>
> > >                       0x04, BIT(1), 0);
> > >
> > >  static SUNXI_CCU_GATE(bus_wb_clk,      "bus-wb",       "bus-de",
> > >
> > >                       0x04, BIT(2), 0);
> > >
> > > +static SUNXI_CCU_GATE(bus_rot_clk,     "bus-rot",      "bus-de",
> > > +                     0x04, BIT(3), 0);
> > >
> > >  static SUNXI_CCU_GATE(mixer0_clk,      "mixer0",       "mixer0-div",
> > >
> > >                       0x00, BIT(0), CLK_SET_RATE_PARENT);
> > >
> > > @@ -38,6 +40,8 @@ static SUNXI_CCU_GATE(mixer1_clk,     "mixer1",
> > > "mixer1-div",>
> > >                       0x00, BIT(1), CLK_SET_RATE_PARENT);
> > >
> > >  static SUNXI_CCU_GATE(wb_clk,          "wb",           "wb-div",
> > >
> > >                       0x00, BIT(2), CLK_SET_RATE_PARENT);
> > >
> > > +static SUNXI_CCU_GATE(rot_clk,         "rot",          "rot-div",
> > > +                     0x00, BIT(3), CLK_SET_RATE_PARENT);
> > >
> > >  static SUNXI_CCU_M(mixer0_div_clk, "mixer0-div", "de", 0x0c, 0, 4,
> > >
> > >                    CLK_SET_RATE_PARENT);
> > >
> > > @@ -45,6 +49,8 @@ static SUNXI_CCU_M(mixer1_div_clk, "mixer1-div", "de",
> > > 0x0c, 4, 4,>
> > >                    CLK_SET_RATE_PARENT);
> > >
> > >  static SUNXI_CCU_M(wb_div_clk, "wb-div", "de", 0x0c, 8, 4,
> > >
> > >                    CLK_SET_RATE_PARENT);
> > >
> > > +static SUNXI_CCU_M(rot_div_clk, "rot-div", "de", 0x0c, 0x0c, 4,
> > > +                  CLK_SET_RATE_PARENT);
> > >
> > >  static SUNXI_CCU_M(mixer0_div_a83_clk, "mixer0-div", "pll-de", 0x0c, 0,
> > >  4,
> > >
> > >                    CLK_SET_RATE_PARENT);
> > >
> > > @@ -53,6 +59,24 @@ static SUNXI_CCU_M(mixer1_div_a83_clk, "mixer1-div",
> > > "pll-de", 0x0c, 4, 4,>
> > >  static SUNXI_CCU_M(wb_div_a83_clk, "wb-div", "pll-de", 0x0c, 8, 4,
> > >
> > >                    CLK_SET_RATE_PARENT);
> > >
> > > +static struct ccu_common *sun50i_h6_de3_clks[] = {
> > > +       &mixer0_clk.common,
> > > +       &mixer1_clk.common,
> > > +       &wb_clk.common,
> > > +
> > > +       &bus_mixer0_clk.common,
> > > +       &bus_mixer1_clk.common,
> > > +       &bus_wb_clk.common,
> > > +
> > > +       &mixer0_div_clk.common,
> > > +       &mixer1_div_clk.common,
> > > +       &wb_div_clk.common,
> > > +
> > > +       &bus_rot_clk.common,
> > > +       &rot_clk.common,
> > > +       &rot_div_clk.common,
> > > +};
> > > +
> > >
> > >  static struct ccu_common *sun8i_a83t_de2_clks[] = {
> > >
> > >         &mixer0_clk.common,
> > >         &mixer1_clk.common,
> > >
> > > @@ -92,6 +116,26 @@ static struct ccu_common *sun8i_v3s_de2_clks[] = {
> > >
> > >         &wb_div_clk.common,
> > >
> > >  };
> > >
> > > +static struct clk_hw_onecell_data sun50i_h6_de3_hw_clks = {
> > > +       .hws    = {
> > > +               [CLK_MIXER0]            = &mixer0_clk.common.hw,
> > > +               [CLK_MIXER1]            = &mixer1_clk.common.hw,
> > > +               [CLK_WB]                = &wb_clk.common.hw,
> > > +               [CLK_ROT]               = &rot_clk.common.hw,
> > > +
> > > +               [CLK_BUS_MIXER0]        = &bus_mixer0_clk.common.hw,
> > > +               [CLK_BUS_MIXER1]        = &bus_mixer1_clk.common.hw,
> > > +               [CLK_BUS_WB]            = &bus_wb_clk.common.hw,
> > > +               [CLK_BUS_ROT]           = &bus_rot_clk.common.hw,
> > > +
> > > +               [CLK_MIXER0_DIV]        = &mixer0_div_clk.common.hw,
> > > +               [CLK_MIXER1_DIV]        = &mixer1_div_clk.common.hw,
> > > +               [CLK_WB_DIV]            = &wb_div_clk.common.hw,
> > > +               [CLK_ROT_DIV]           = &rot_div_clk.common.hw,
> > > +       },
> > > +       .num    = 12,
> >
> > It's best not to openly code these. It is error prone, like having
> > an index beyond .num, which then never gets registered.
> >
> > Instead, please update CLK_NUMBERS and use that instead. sunxi_ccu_probe()
> > can handle holes in .hws.
>
> I'm not sure this will work. All newly introduced indices are at the end, so
> other arrays will still have same length (hole at the end). You will just
> claim that arrays are larger than they really are, which means bad things.
>
> But I take any other suggestion. I really can't think of better solution.

Then maybe have macros for both cases instead?
CLK_NUMBER_WITH_ROT / CLK_NUMBER_WITHOUT_ROT?

ChenYu

> Best regards,
> Jernej
>
> >
> > On the other hand, it can't handle holes in the ccu_reset_map. Hope we
> > never have to deal with such an instance.
> >
> > ChenYu
> >
> > > +};
> > > +
> > >
> > >  static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = {
> > >
> > >         .hws    = {
> > >
> > >                 [CLK_MIXER0]            = &mixer0_clk.common.hw,
> > >
> > > @@ -156,6 +200,13 @@ static struct ccu_reset_map sun50i_a64_de2_resets[] =
> > > {>
> > >         [RST_WB]        = { 0x08, BIT(2) },
> > >
> > >  };
> > >
> > > +static struct ccu_reset_map sun50i_h6_de3_resets[] = {
> > > +       [RST_MIXER0]    = { 0x08, BIT(0) },
> > > +       [RST_MIXER1]    = { 0x08, BIT(1) },
> > > +       [RST_WB]        = { 0x08, BIT(2) },
> > > +       [RST_ROT]       = { 0x08, BIT(3) },
> > > +};
> > > +
> > >
> > >  static const struct sunxi_ccu_desc sun8i_a83t_de2_clk_desc = {
> > >
> > >         .ccu_clks       = sun8i_a83t_de2_clks,
> > >         .num_ccu_clks   = ARRAY_SIZE(sun8i_a83t_de2_clks),
> > >
> > > @@ -186,6 +237,16 @@ static const struct sunxi_ccu_desc
> > > sun50i_a64_de2_clk_desc = {>
> > >         .num_resets     = ARRAY_SIZE(sun50i_a64_de2_resets),
> > >
> > >  };
> > >
> > > +static const struct sunxi_ccu_desc sun50i_h6_de3_clk_desc = {
> > > +       .ccu_clks       = sun50i_h6_de3_clks,
> > > +       .num_ccu_clks   = ARRAY_SIZE(sun50i_h6_de3_clks),
> > > +
> > > +       .hw_clks        = &sun50i_h6_de3_hw_clks,
> > > +
> > > +       .resets         = sun50i_h6_de3_resets,
> > > +       .num_resets     = ARRAY_SIZE(sun50i_h6_de3_resets),
> > > +};
> > > +
> > >
> > >  static const struct sunxi_ccu_desc sun8i_v3s_de2_clk_desc = {
> > >
> > >         .ccu_clks       = sun8i_v3s_de2_clks,
> > >         .num_ccu_clks   = ARRAY_SIZE(sun8i_v3s_de2_clks),
> > >
> > > @@ -296,6 +357,10 @@ static const struct of_device_id sunxi_de2_clk_ids[]
> > > = {>
> > >                 .compatible = "allwinner,sun50i-h5-de2-clk",
> > >                 .data = &sun50i_a64_de2_clk_desc,
> > >
> > >         },
> > >
> > > +       {
> > > +               .compatible = "allwinner,sun50i-h6-de3-clk",
> > > +               .data = &sun50i_h6_de3_clk_desc,
> > > +       },
> > >
> > >         { }
> > >
> > >  };
> > >
> > > diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
> > > b/drivers/clk/sunxi-ng/ccu-sun8i-de2.h index 530c006e0ae9..27bd88539f42
> > > 100644
> > > --- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
> > > +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
> > > @@ -22,6 +22,7 @@
> > >
> > >  #define CLK_MIXER0_DIV 3
> > >  #define CLK_MIXER1_DIV 4
> > >  #define CLK_WB_DIV     5
> > >
> > > +#define CLK_ROT_DIV    11
> > >
> > >  #define CLK_NUMBER     (CLK_WB + 1)
> > >
> > > --
> > > 2.18.0
>
>
>
>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 15/27] drm/sun4i: Not all DW HDMI controllers has scrambled addresses
  2018-09-02  7:26 ` [PATCH 15/27] drm/sun4i: Not all DW HDMI controllers has scrambled addresses Jernej Skrabec
@ 2018-09-12 12:25   ` Chen-Yu Tsai
  0 siblings, 0 replies; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-12 12:25 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
>
> Currently supported Allwinner SoCs with DW HDMI controller have
> scrambled addresses and read lock. However, that is not true in general.
> For example, A80 and H6 have normal addresses and normal read access.
>
> Move code for unscrambling addresses and unlocking read access to it's
> own function and call it from init function.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

Reviewed-by: Chen-Yu Tsai <wens@csie.org>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 19/27] drm/sun4i: Add support for H6 DW HDMI controller
  2018-09-02  7:26 ` [PATCH 19/27] drm/sun4i: Add support for H6 DW HDMI controller Jernej Skrabec
@ 2018-09-12 12:29   ` Chen-Yu Tsai
  0 siblings, 0 replies; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-12 12:29 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
>
> H6 has DW HDMI 2.0 controller v2.12a.
>
> It supports 4K at 60 Hz and HDCP 2.2.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>
> diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> index 16a0c7a88ea8..44143c9f20d0 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> @@ -43,6 +43,16 @@ sun8i_dw_hdmi_mode_valid_a83t(struct drm_connector *connector,
>         return MODE_OK;
>  }
>
> +static enum drm_mode_status
> +sun8i_dw_hdmi_mode_valid_h6(struct drm_connector *connector,
> +                           const struct drm_display_mode *mode)
> +{
> +       if (mode->clock > 600000)

600 MHz seems slightly arbitrary. AFAIK the dot clock for 4K 60Hz is 594 MHz?
A comment on this limit would be nice.

> +               return MODE_CLOCK_HIGH;
> +
> +       return MODE_OK;
> +}
> +
>  static bool sun8i_dw_hdmi_node_is_tcon_top(struct device_node *node)
>  {
>         return IS_ENABLED(CONFIG_DRM_SUN8I_TCON_TOP) &&
> @@ -220,12 +230,20 @@ static int sun8i_dw_hdmi_remove(struct platform_device *pdev)
>         return 0;
>  }
>
> +static const struct sun8i_dw_hdmi_quirks sun50i_h6_quirks = {
> +       .mode_valid = sun8i_dw_hdmi_mode_valid_h6,
> +};
> +

Please "version" sort the SoC families and models.

>  static const struct sun8i_dw_hdmi_quirks sun8i_a83t_quirks = {
>         .mode_valid = sun8i_dw_hdmi_mode_valid_a83t,
>         .set_rate = true,
>  };
>
>  static const struct of_device_id sun8i_dw_hdmi_dt_ids[] = {
> +       {
> +               .compatible = "allwinner,sun50i-h6-dw-hdmi",
> +               .data = &sun50i_h6_quirks,
> +       },

Here also.

Once fixed,

Reviewed-by: Chen-Yu Tsai <wens@csie.org>

>         {
>                 .compatible = "allwinner,sun8i-a83t-dw-hdmi",
>                 .data = &sun8i_a83t_quirks,
> --
> 2.18.0
>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [linux-sunxi] Re: [PATCH 02/27] arm64: allwinner: h6: add system controller device tree node
  2018-09-04  8:44     ` [linux-sunxi] " Icenowy Zheng
@ 2018-09-12 14:49       ` Chen-Yu Tsai
  2018-09-12 15:37         ` Icenowy Zheng
  0 siblings, 1 reply; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-12 14:49 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Jernej Skrabec, Rob Herring, Maxime Ripard, Mark Rutland,
	Mike Turquette, Stephen Boyd, David Airlie, Archit Taneja,
	Andrzej Hajda, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel, linux-sunxi

On Tue, Sep 4, 2018 at 4:44 PM Icenowy Zheng <icenowy@aosc.io> wrote:
>
>
>
> 于 2018年9月4日 GMT+08:00 下午4:40:56, Chen-Yu Tsai <wens@csie.org> 写到:
> >On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net>
> >wrote:
> >>
> >> From: Icenowy Zheng <icenowy@aosc.io>
> >>
> >> As we have already binding for the H6 system controller, add its node
> >> to the device tree.
> >>
> >> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> >> [fixed compatible string]
> >> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> >
> >Reviewed-by: Chen-Yu Tsai <wens@csie.org>
>
> By the way can these patches be applied first? (patches
> related to syscon).
>
> They're also needed for EMAC.

Applied.

BTW, the H6 system control EMAC register also has the internal PHY
related controls seen on H3/H5. IIRC you previously mentioned that
they have no effect?

ChenYu

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 08/27] clk: sunxi-ng: Add support for H6 DE3 clocks
  2018-09-12 12:20       ` Chen-Yu Tsai
@ 2018-09-12 14:55         ` Jernej Škrabec
  2018-09-12 16:16           ` [linux-sunxi] " Chen-Yu Tsai
  0 siblings, 1 reply; 66+ messages in thread
From: Jernej Škrabec @ 2018-09-12 14:55 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi, Icenowy Zheng

Dne sreda, 12. september 2018 ob 14:20:08 CEST je Chen-Yu Tsai napisal(a):
> On Wed, Sep 5, 2018 at 1:46 AM Jernej Škrabec <jernej.skrabec@siol.net> 
wrote:
> > Dne torek, 04. september 2018 ob 11:04:21 CEST je Chen-Yu Tsai napisal(a):
> > > On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net>
> > 
> > wrote:
> > > > Support for mixer0, mixer1, writeback and rotation units is added.
> > > > 
> > > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > > Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> > > > ---
> > > > 
> > > >  drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 65
> > > >  ++++++++++++++++++++++++++++
> > > >  drivers/clk/sunxi-ng/ccu-sun8i-de2.h |  1 +
> > > >  2 files changed, 66 insertions(+)
> > > > 
> > > > diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
> > > > b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c index
> > > > bae5ee67a797..4535c1c27d27
> > > > 100644
> > > > --- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
> > > > +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
> > > > @@ -31,6 +31,8 @@ static SUNXI_CCU_GATE(bus_mixer1_clk, "bus-mixer1",
> > > > "bus-de",>
> > > > 
> > > >                       0x04, BIT(1), 0);
> > > >  
> > > >  static SUNXI_CCU_GATE(bus_wb_clk,      "bus-wb",       "bus-de",
> > > >  
> > > >                       0x04, BIT(2), 0);
> > > > 
> > > > +static SUNXI_CCU_GATE(bus_rot_clk,     "bus-rot",      "bus-de",
> > > > +                     0x04, BIT(3), 0);
> > > > 
> > > >  static SUNXI_CCU_GATE(mixer0_clk,      "mixer0",       "mixer0-div",
> > > >  
> > > >                       0x00, BIT(0), CLK_SET_RATE_PARENT);
> > > > 
> > > > @@ -38,6 +40,8 @@ static SUNXI_CCU_GATE(mixer1_clk,     "mixer1",
> > > > "mixer1-div",>
> > > > 
> > > >                       0x00, BIT(1), CLK_SET_RATE_PARENT);
> > > >  
> > > >  static SUNXI_CCU_GATE(wb_clk,          "wb",           "wb-div",
> > > >  
> > > >                       0x00, BIT(2), CLK_SET_RATE_PARENT);
> > > > 
> > > > +static SUNXI_CCU_GATE(rot_clk,         "rot",          "rot-div",
> > > > +                     0x00, BIT(3), CLK_SET_RATE_PARENT);
> > > > 
> > > >  static SUNXI_CCU_M(mixer0_div_clk, "mixer0-div", "de", 0x0c, 0, 4,
> > > >  
> > > >                    CLK_SET_RATE_PARENT);
> > > > 
> > > > @@ -45,6 +49,8 @@ static SUNXI_CCU_M(mixer1_div_clk, "mixer1-div",
> > > > "de",
> > > > 0x0c, 4, 4,>
> > > > 
> > > >                    CLK_SET_RATE_PARENT);
> > > >  
> > > >  static SUNXI_CCU_M(wb_div_clk, "wb-div", "de", 0x0c, 8, 4,
> > > >  
> > > >                    CLK_SET_RATE_PARENT);
> > > > 
> > > > +static SUNXI_CCU_M(rot_div_clk, "rot-div", "de", 0x0c, 0x0c, 4,
> > > > +                  CLK_SET_RATE_PARENT);
> > > > 
> > > >  static SUNXI_CCU_M(mixer0_div_a83_clk, "mixer0-div", "pll-de", 0x0c,
> > > >  0,
> > > >  4,
> > > >  
> > > >                    CLK_SET_RATE_PARENT);
> > > > 
> > > > @@ -53,6 +59,24 @@ static SUNXI_CCU_M(mixer1_div_a83_clk,
> > > > "mixer1-div",
> > > > "pll-de", 0x0c, 4, 4,>
> > > > 
> > > >  static SUNXI_CCU_M(wb_div_a83_clk, "wb-div", "pll-de", 0x0c, 8, 4,
> > > >  
> > > >                    CLK_SET_RATE_PARENT);
> > > > 
> > > > +static struct ccu_common *sun50i_h6_de3_clks[] = {
> > > > +       &mixer0_clk.common,
> > > > +       &mixer1_clk.common,
> > > > +       &wb_clk.common,
> > > > +
> > > > +       &bus_mixer0_clk.common,
> > > > +       &bus_mixer1_clk.common,
> > > > +       &bus_wb_clk.common,
> > > > +
> > > > +       &mixer0_div_clk.common,
> > > > +       &mixer1_div_clk.common,
> > > > +       &wb_div_clk.common,
> > > > +
> > > > +       &bus_rot_clk.common,
> > > > +       &rot_clk.common,
> > > > +       &rot_div_clk.common,
> > > > +};
> > > > +
> > > > 
> > > >  static struct ccu_common *sun8i_a83t_de2_clks[] = {
> > > >  
> > > >         &mixer0_clk.common,
> > > >         &mixer1_clk.common,
> > > > 
> > > > @@ -92,6 +116,26 @@ static struct ccu_common *sun8i_v3s_de2_clks[] = {
> > > > 
> > > >         &wb_div_clk.common,
> > > >  
> > > >  };
> > > > 
> > > > +static struct clk_hw_onecell_data sun50i_h6_de3_hw_clks = {
> > > > +       .hws    = {
> > > > +               [CLK_MIXER0]            = &mixer0_clk.common.hw,
> > > > +               [CLK_MIXER1]            = &mixer1_clk.common.hw,
> > > > +               [CLK_WB]                = &wb_clk.common.hw,
> > > > +               [CLK_ROT]               = &rot_clk.common.hw,
> > > > +
> > > > +               [CLK_BUS_MIXER0]        = &bus_mixer0_clk.common.hw,
> > > > +               [CLK_BUS_MIXER1]        = &bus_mixer1_clk.common.hw,
> > > > +               [CLK_BUS_WB]            = &bus_wb_clk.common.hw,
> > > > +               [CLK_BUS_ROT]           = &bus_rot_clk.common.hw,
> > > > +
> > > > +               [CLK_MIXER0_DIV]        = &mixer0_div_clk.common.hw,
> > > > +               [CLK_MIXER1_DIV]        = &mixer1_div_clk.common.hw,
> > > > +               [CLK_WB_DIV]            = &wb_div_clk.common.hw,
> > > > +               [CLK_ROT_DIV]           = &rot_div_clk.common.hw,
> > > > +       },
> > > > +       .num    = 12,
> > > 
> > > It's best not to openly code these. It is error prone, like having
> > > an index beyond .num, which then never gets registered.
> > > 
> > > Instead, please update CLK_NUMBERS and use that instead.
> > > sunxi_ccu_probe()
> > > can handle holes in .hws.
> > 
> > I'm not sure this will work. All newly introduced indices are at the end,
> > so other arrays will still have same length (hole at the end). You will
> > just claim that arrays are larger than they really are, which means bad
> > things.
> > 
> > But I take any other suggestion. I really can't think of better solution.
> 
> Then maybe have macros for both cases instead?
> CLK_NUMBER_WITH_ROT / CLK_NUMBER_WITHOUT_ROT?

That sounds reasonable. Do you want separate patch which renames original 
macro CLK_NUMBER to CLK_NUMBER_WITHOUT_ROT?

Best regards,
Jernej

> 
> ChenYu
> 
> > Best regards,
> > Jernej
> > 
> > > On the other hand, it can't handle holes in the ccu_reset_map. Hope we
> > > never have to deal with such an instance.
> > > 
> > > ChenYu
> > > 
> > > > +};
> > > > +
> > > > 
> > > >  static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = {
> > > >  
> > > >         .hws    = {
> > > >         
> > > >                 [CLK_MIXER0]            = &mixer0_clk.common.hw,
> > > > 
> > > > @@ -156,6 +200,13 @@ static struct ccu_reset_map
> > > > sun50i_a64_de2_resets[] =
> > > > {>
> > > > 
> > > >         [RST_WB]        = { 0x08, BIT(2) },
> > > >  
> > > >  };
> > > > 
> > > > +static struct ccu_reset_map sun50i_h6_de3_resets[] = {
> > > > +       [RST_MIXER0]    = { 0x08, BIT(0) },
> > > > +       [RST_MIXER1]    = { 0x08, BIT(1) },
> > > > +       [RST_WB]        = { 0x08, BIT(2) },
> > > > +       [RST_ROT]       = { 0x08, BIT(3) },
> > > > +};
> > > > +
> > > > 
> > > >  static const struct sunxi_ccu_desc sun8i_a83t_de2_clk_desc = {
> > > >  
> > > >         .ccu_clks       = sun8i_a83t_de2_clks,
> > > >         .num_ccu_clks   = ARRAY_SIZE(sun8i_a83t_de2_clks),
> > > > 
> > > > @@ -186,6 +237,16 @@ static const struct sunxi_ccu_desc
> > > > sun50i_a64_de2_clk_desc = {>
> > > > 
> > > >         .num_resets     = ARRAY_SIZE(sun50i_a64_de2_resets),
> > > >  
> > > >  };
> > > > 
> > > > +static const struct sunxi_ccu_desc sun50i_h6_de3_clk_desc = {
> > > > +       .ccu_clks       = sun50i_h6_de3_clks,
> > > > +       .num_ccu_clks   = ARRAY_SIZE(sun50i_h6_de3_clks),
> > > > +
> > > > +       .hw_clks        = &sun50i_h6_de3_hw_clks,
> > > > +
> > > > +       .resets         = sun50i_h6_de3_resets,
> > > > +       .num_resets     = ARRAY_SIZE(sun50i_h6_de3_resets),
> > > > +};
> > > > +
> > > > 
> > > >  static const struct sunxi_ccu_desc sun8i_v3s_de2_clk_desc = {
> > > >  
> > > >         .ccu_clks       = sun8i_v3s_de2_clks,
> > > >         .num_ccu_clks   = ARRAY_SIZE(sun8i_v3s_de2_clks),
> > > > 
> > > > @@ -296,6 +357,10 @@ static const struct of_device_id
> > > > sunxi_de2_clk_ids[]
> > > > = {>
> > > > 
> > > >                 .compatible = "allwinner,sun50i-h5-de2-clk",
> > > >                 .data = &sun50i_a64_de2_clk_desc,
> > > >         
> > > >         },
> > > > 
> > > > +       {
> > > > +               .compatible = "allwinner,sun50i-h6-de3-clk",
> > > > +               .data = &sun50i_h6_de3_clk_desc,
> > > > +       },
> > > > 
> > > >         { }
> > > >  
> > > >  };
> > > > 
> > > > diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
> > > > b/drivers/clk/sunxi-ng/ccu-sun8i-de2.h index
> > > > 530c006e0ae9..27bd88539f42
> > > > 100644
> > > > --- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
> > > > +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
> > > > @@ -22,6 +22,7 @@
> > > > 
> > > >  #define CLK_MIXER0_DIV 3
> > > >  #define CLK_MIXER1_DIV 4
> > > >  #define CLK_WB_DIV     5
> > > > 
> > > > +#define CLK_ROT_DIV    11
> > > > 
> > > >  #define CLK_NUMBER     (CLK_WB + 1)
> > > > 
> > > > --
> > > > 2.18.0





^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [linux-sunxi] Re: [PATCH 02/27] arm64: allwinner: h6: add system controller device tree node
  2018-09-12 14:49       ` Chen-Yu Tsai
@ 2018-09-12 15:37         ` Icenowy Zheng
  0 siblings, 0 replies; 66+ messages in thread
From: Icenowy Zheng @ 2018-09-12 15:37 UTC (permalink / raw)
  To: linux-arm-kernel, Chen-Yu Tsai
  Cc: Mark Rutland, David Airlie, Jernej Skrabec, Andrzej Hajda,
	Maxime Ripard, Mike Turquette, linux-sunxi, Archit Taneja,
	dri-devel, linux-kernel, Stephen Boyd, devicetree, Rob Herring,
	linux-clk, linux-arm-kernel



于 2018年9月12日 GMT+08:00 下午10:49:12, Chen-Yu Tsai <wens@csie.org> 写到:
>On Tue, Sep 4, 2018 at 4:44 PM Icenowy Zheng <icenowy@aosc.io> wrote:
>>
>>
>>
>> 于 2018年9月4日 GMT+08:00 下午4:40:56, Chen-Yu Tsai <wens@csie.org> 写到:
>> >On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec
><jernej.skrabec@siol.net>
>> >wrote:
>> >>
>> >> From: Icenowy Zheng <icenowy@aosc.io>
>> >>
>> >> As we have already binding for the H6 system controller, add its
>node
>> >> to the device tree.
>> >>
>> >> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
>> >> [fixed compatible string]
>> >> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>> >
>> >Reviewed-by: Chen-Yu Tsai <wens@csie.org>
>>
>> By the way can these patches be applied first? (patches
>> related to syscon).
>>
>> They're also needed for EMAC.
>
>Applied.
>
>BTW, the H6 system control EMAC register also has the internal PHY
>related controls seen on H3/H5. IIRC you previously mentioned that
>they have no effect?

Yes, because the "internal PHY" on H6 is on AC200.

The internal/external mux bit has effect (although it will mux
to a non-existent PHY when switching to "internal", render
EMAC not usable), but it also has effect on A64 (same effect
with H6), on which it's not documented.

>
>ChenYu
>
>_______________________________________________
>linux-arm-kernel mailing list
>linux-arm-kernel@lists.infradead.org
>http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [linux-sunxi] Re: [PATCH 08/27] clk: sunxi-ng: Add support for H6 DE3 clocks
  2018-09-12 14:55         ` Jernej Škrabec
@ 2018-09-12 16:16           ` Chen-Yu Tsai
  0 siblings, 0 replies; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-12 16:16 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi, Icenowy Zheng

On Wed, Sep 12, 2018 at 10:55 PM Jernej Škrabec <jernej.skrabec@siol.net> wrote:
>
> Dne sreda, 12. september 2018 ob 14:20:08 CEST je Chen-Yu Tsai napisal(a):
> > On Wed, Sep 5, 2018 at 1:46 AM Jernej Škrabec <jernej.skrabec@siol.net>
> wrote:
> > > Dne torek, 04. september 2018 ob 11:04:21 CEST je Chen-Yu Tsai napisal(a):
> > > > On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net>
> > >
> > > wrote:
> > > > > Support for mixer0, mixer1, writeback and rotation units is added.
> > > > >
> > > > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > > > Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> > > > > ---
> > > > >
> > > > >  drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 65
> > > > >  ++++++++++++++++++++++++++++
> > > > >  drivers/clk/sunxi-ng/ccu-sun8i-de2.h |  1 +
> > > > >  2 files changed, 66 insertions(+)
> > > > >
> > > > > diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
> > > > > b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c index
> > > > > bae5ee67a797..4535c1c27d27
> > > > > 100644
> > > > > --- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
> > > > > +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
> > > > > @@ -31,6 +31,8 @@ static SUNXI_CCU_GATE(bus_mixer1_clk, "bus-mixer1",
> > > > > "bus-de",>
> > > > >
> > > > >                       0x04, BIT(1), 0);
> > > > >
> > > > >  static SUNXI_CCU_GATE(bus_wb_clk,      "bus-wb",       "bus-de",
> > > > >
> > > > >                       0x04, BIT(2), 0);
> > > > >
> > > > > +static SUNXI_CCU_GATE(bus_rot_clk,     "bus-rot",      "bus-de",
> > > > > +                     0x04, BIT(3), 0);
> > > > >
> > > > >  static SUNXI_CCU_GATE(mixer0_clk,      "mixer0",       "mixer0-div",
> > > > >
> > > > >                       0x00, BIT(0), CLK_SET_RATE_PARENT);
> > > > >
> > > > > @@ -38,6 +40,8 @@ static SUNXI_CCU_GATE(mixer1_clk,     "mixer1",
> > > > > "mixer1-div",>
> > > > >
> > > > >                       0x00, BIT(1), CLK_SET_RATE_PARENT);
> > > > >
> > > > >  static SUNXI_CCU_GATE(wb_clk,          "wb",           "wb-div",
> > > > >
> > > > >                       0x00, BIT(2), CLK_SET_RATE_PARENT);
> > > > >
> > > > > +static SUNXI_CCU_GATE(rot_clk,         "rot",          "rot-div",
> > > > > +                     0x00, BIT(3), CLK_SET_RATE_PARENT);
> > > > >
> > > > >  static SUNXI_CCU_M(mixer0_div_clk, "mixer0-div", "de", 0x0c, 0, 4,
> > > > >
> > > > >                    CLK_SET_RATE_PARENT);
> > > > >
> > > > > @@ -45,6 +49,8 @@ static SUNXI_CCU_M(mixer1_div_clk, "mixer1-div",
> > > > > "de",
> > > > > 0x0c, 4, 4,>
> > > > >
> > > > >                    CLK_SET_RATE_PARENT);
> > > > >
> > > > >  static SUNXI_CCU_M(wb_div_clk, "wb-div", "de", 0x0c, 8, 4,
> > > > >
> > > > >                    CLK_SET_RATE_PARENT);
> > > > >
> > > > > +static SUNXI_CCU_M(rot_div_clk, "rot-div", "de", 0x0c, 0x0c, 4,
> > > > > +                  CLK_SET_RATE_PARENT);
> > > > >
> > > > >  static SUNXI_CCU_M(mixer0_div_a83_clk, "mixer0-div", "pll-de", 0x0c,
> > > > >  0,
> > > > >  4,
> > > > >
> > > > >                    CLK_SET_RATE_PARENT);
> > > > >
> > > > > @@ -53,6 +59,24 @@ static SUNXI_CCU_M(mixer1_div_a83_clk,
> > > > > "mixer1-div",
> > > > > "pll-de", 0x0c, 4, 4,>
> > > > >
> > > > >  static SUNXI_CCU_M(wb_div_a83_clk, "wb-div", "pll-de", 0x0c, 8, 4,
> > > > >
> > > > >                    CLK_SET_RATE_PARENT);
> > > > >
> > > > > +static struct ccu_common *sun50i_h6_de3_clks[] = {
> > > > > +       &mixer0_clk.common,
> > > > > +       &mixer1_clk.common,
> > > > > +       &wb_clk.common,
> > > > > +
> > > > > +       &bus_mixer0_clk.common,
> > > > > +       &bus_mixer1_clk.common,
> > > > > +       &bus_wb_clk.common,
> > > > > +
> > > > > +       &mixer0_div_clk.common,
> > > > > +       &mixer1_div_clk.common,
> > > > > +       &wb_div_clk.common,
> > > > > +
> > > > > +       &bus_rot_clk.common,
> > > > > +       &rot_clk.common,
> > > > > +       &rot_div_clk.common,
> > > > > +};
> > > > > +
> > > > >
> > > > >  static struct ccu_common *sun8i_a83t_de2_clks[] = {
> > > > >
> > > > >         &mixer0_clk.common,
> > > > >         &mixer1_clk.common,
> > > > >
> > > > > @@ -92,6 +116,26 @@ static struct ccu_common *sun8i_v3s_de2_clks[] = {
> > > > >
> > > > >         &wb_div_clk.common,
> > > > >
> > > > >  };
> > > > >
> > > > > +static struct clk_hw_onecell_data sun50i_h6_de3_hw_clks = {
> > > > > +       .hws    = {
> > > > > +               [CLK_MIXER0]            = &mixer0_clk.common.hw,
> > > > > +               [CLK_MIXER1]            = &mixer1_clk.common.hw,
> > > > > +               [CLK_WB]                = &wb_clk.common.hw,
> > > > > +               [CLK_ROT]               = &rot_clk.common.hw,
> > > > > +
> > > > > +               [CLK_BUS_MIXER0]        = &bus_mixer0_clk.common.hw,
> > > > > +               [CLK_BUS_MIXER1]        = &bus_mixer1_clk.common.hw,
> > > > > +               [CLK_BUS_WB]            = &bus_wb_clk.common.hw,
> > > > > +               [CLK_BUS_ROT]           = &bus_rot_clk.common.hw,
> > > > > +
> > > > > +               [CLK_MIXER0_DIV]        = &mixer0_div_clk.common.hw,
> > > > > +               [CLK_MIXER1_DIV]        = &mixer1_div_clk.common.hw,
> > > > > +               [CLK_WB_DIV]            = &wb_div_clk.common.hw,
> > > > > +               [CLK_ROT_DIV]           = &rot_div_clk.common.hw,
> > > > > +       },
> > > > > +       .num    = 12,
> > > >
> > > > It's best not to openly code these. It is error prone, like having
> > > > an index beyond .num, which then never gets registered.
> > > >
> > > > Instead, please update CLK_NUMBERS and use that instead.
> > > > sunxi_ccu_probe()
> > > > can handle holes in .hws.
> > >
> > > I'm not sure this will work. All newly introduced indices are at the end,
> > > so other arrays will still have same length (hole at the end). You will
> > > just claim that arrays are larger than they really are, which means bad
> > > things.
> > >
> > > But I take any other suggestion. I really can't think of better solution.
> >
> > Then maybe have macros for both cases instead?
> > CLK_NUMBER_WITH_ROT / CLK_NUMBER_WITHOUT_ROT?
>
> That sounds reasonable. Do you want separate patch which renames original
> macro CLK_NUMBER to CLK_NUMBER_WITHOUT_ROT?

I don't think that's necessary. Just mention the name change in the changelog,
and justifying it by the addition of the ROT clocks.

Thanks

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [linux-sunxi] [PATCH 11/27] drm/sun4i: Rework DE2 register defines
  2018-09-02  7:26 ` [PATCH 11/27] drm/sun4i: Rework DE2 register defines Jernej Skrabec
@ 2018-09-22 12:32   ` Chen-Yu Tsai
  2018-09-23 20:02     ` Jernej Škrabec
  0 siblings, 1 reply; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-22 12:32 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi, Icenowy Zheng

Hi,

On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
>
> Most, if not all, registers found in DE2 still exists in DE3. However,
> units are on different base addresses.
>
> To prepare for addition of DE3 support, registers macros are reworked so
> they take base address as parameter.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> [rebased]
> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>

This patch mostly checks out. But see below.


> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> index 406c42e752d7..020b0a097c84 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> @@ -29,20 +29,24 @@
>
>  #define SUN8I_MIXER_GLOBAL_DBUFF_ENABLE                BIT(0)
>
> -#define SUN8I_MIXER_BLEND_PIPE_CTL             0x1000
> -#define SUN8I_MIXER_BLEND_ATTR_FCOLOR(x)       (0x1004 + 0x10 * (x) + 0x0)
> -#define SUN8I_MIXER_BLEND_ATTR_INSIZE(x)       (0x1004 + 0x10 * (x) + 0x4)
> -#define SUN8I_MIXER_BLEND_ATTR_COORD(x)                (0x1004 + 0x10 * (x) + 0x8)
> -#define SUN8I_MIXER_BLEND_ROUTE                        0x1080
> -#define SUN8I_MIXER_BLEND_PREMULTIPLY          0x1084
> -#define SUN8I_MIXER_BLEND_BKCOLOR              0x1088
> -#define SUN8I_MIXER_BLEND_OUTSIZE              0x108c
> -#define SUN8I_MIXER_BLEND_MODE(x)              (0x1090 + 0x04 * (x))
> -#define SUN8I_MIXER_BLEND_CK_CTL               0x10b0
> -#define SUN8I_MIXER_BLEND_CK_CFG               0x10b4
> -#define SUN8I_MIXER_BLEND_CK_MAX(x)            (0x10c0 + 0x04 * (x))
> -#define SUN8I_MIXER_BLEND_CK_MIN(x)            (0x10e0 + 0x04 * (x))
> -#define SUN8I_MIXER_BLEND_OUTCTL               0x10fc
> +#define DE2_BLD_BASE                           0x1000
> +#define DE2_CH_BASE                            0x2000
> +#define DE2_CH_SIZE                            0x1000
> +
> +#define SUN8I_MIXER_BLEND_PIPE_CTL(base)       ((base) + 0)
> +#define SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, x) ((base) + 0x4 + 0x10 * (x))
> +#define SUN8I_MIXER_BLEND_ATTR_INSIZE(base, x) ((base) + 0x8 + 0x10 * (x))
> +#define SUN8I_MIXER_BLEND_ATTR_COORD(base, x)  ((base) + 0xC + 0x10 * (x))

Nit: Use lowercase for '0xC' to be consistent.

> +#define SUN8I_MIXER_BLEND_ROUTE(base)          ((base) + 0x80)
> +#define SUN8I_MIXER_BLEND_PREMULTIPLY(base)    ((base) + 0x84)
> +#define SUN8I_MIXER_BLEND_BKCOLOR(base)                ((base) + 0x88)
> +#define SUN8I_MIXER_BLEND_OUTSIZE(base)                ((base) + 0x8c)
> +#define SUN8I_MIXER_BLEND_MODE(base, x)                ((base) + 0x90 + 0x04 * (x))
> +#define SUN8I_MIXER_BLEND_CK_CTL(base)         ((base) + 0xb0)
> +#define SUN8I_MIXER_BLEND_CK_CFG(base)         ((base) + 0xb4)
> +#define SUN8I_MIXER_BLEND_CK_MAX(base, x)      ((base) + 0xc0 + 0x04 * (x))
> +#define SUN8I_MIXER_BLEND_CK_MIN(base, x)      ((base) + 0xe0 + 0x04 * (x))
> +#define SUN8I_MIXER_BLEND_OUTCTL(base)         ((base) + 0xfc)
>
>  #define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK      GENMASK(12, 8)
>  #define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe)    BIT(8 + pipe)

[...]

> diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
> index 6bb2aa164c8e..c68eab8a748f 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
> @@ -10,6 +10,7 @@
>   */
>
>  #include "sun8i_ui_scaler.h"
> +#include "sun8i_vi_scaler.h"
>
>  static const u32 lan2coefftab16[240] = {
>         0x00004000, 0x00033ffe, 0x00063efc, 0x000a3bfb,
> @@ -88,6 +89,14 @@ static const u32 lan2coefftab16[240] = {
>         0x0b1c1603, 0x0d1c1502, 0x0e1d1401, 0x0f1d1301,
>  };
>
> +static inline u32 sun8i_ui_scaler_base(struct sun8i_mixer *mixer, int channel)

I recently saw a review comment stating one should not inline functions
unless they are defined in header files. Otherwise the decision should
be left up to the compiler.

> +{
> +       int vi_num = mixer->cfg->vi_num;
> +
> +       return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * vi_num +
> +              DE2_UI_SCALER_SIZE * (channel - vi_num);
> +}
> +
>  static int sun8i_ui_scaler_coef_index(unsigned int step)
>  {
>         unsigned int scale, int_part, float_part;

[...]

> diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> index d3f1acb234b7..8697afc36023 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> @@ -833,6 +833,11 @@ static const u32 bicubic4coefftab32[480] = {
>         0x1012110d, 0x1012110d, 0x1013110c, 0x1013110c,
>  };
>
> +static inline u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel)
> +{
> +       return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * channel;
> +}
> +

This one as well.

>  static int sun8i_vi_scaler_coef_index(unsigned int step)
>  {
>         unsigned int scale, int_part, float_part;
> @@ -857,7 +862,7 @@ static int sun8i_vi_scaler_coef_index(unsigned int step)
>         }
>  }
>
> -static void sun8i_vi_scaler_set_coeff(struct regmap *map, int layer,
> +static void sun8i_vi_scaler_set_coeff(struct regmap *map, u32 base,
>                                       u32 hstep, u32 vstep,
>                                       const struct drm_format_info *format)

This is the only instance where a function's "layer" parameter was changed
to "base". It would be nice if it were consistent.

ChenYu

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 12/27] drm/sun4i: Add basic support for DE3
  2018-09-02  7:26 ` [PATCH 12/27] drm/sun4i: Add basic support for DE3 Jernej Skrabec
@ 2018-09-22 13:19   ` Chen-Yu Tsai
  2018-09-23 19:51     ` Jernej Škrabec
  2018-10-05 17:51     ` Jernej Škrabec
  0 siblings, 2 replies; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-22 13:19 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
>
> Display Engine 3 is an upgrade of DE2 with new features like support for
> 10 bit color formats and support for AFBC.
>
> Most of DE2 code works with DE3, except some small details.
>
> Add support for it.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  drivers/gpu/drm/sun4i/sun8i_csc.c       | 96 +++++++++++++++++++++++--
>  drivers/gpu/drm/sun4i/sun8i_mixer.c     | 17 ++++-
>  drivers/gpu/drm/sun4i/sun8i_mixer.h     | 21 +++++-
>  drivers/gpu/drm/sun4i/sun8i_ui_scaler.c |  8 ++-
>  drivers/gpu/drm/sun4i/sun8i_ui_scaler.h |  1 +
>  drivers/gpu/drm/sun4i/sun8i_vi_layer.c  |  8 +++
>  drivers/gpu/drm/sun4i/sun8i_vi_layer.h  |  2 +
>  drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 34 ++++++++-
>  drivers/gpu/drm/sun4i/sun8i_vi_scaler.h | 23 ++++++
>  9 files changed, 197 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c
> index b14925b40ccf..101901ccf2dc 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_csc.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
> @@ -34,6 +34,34 @@ static const u32 yvu2rgb[] = {
>         0x000004A8, 0x00000000, 0x00000813, 0xFFFBAC4A,
>  };
>
> +/*
> + * DE3 has a bit different CSC units. Factors are in two's complement format.
> + * First three have 17 bits for fractinal part and last two 2 bits. First
> + * three values in each line are multiplication factor, 4th is difference,
> + * which is subtracted from the input value before the multiplication and
> + * last value is constant, which is added at the end.
> + *
> + * x' = c00 * (x + d0) + c01 * (y + d1) + c02 * (z + d2) + const0
> + * y' = c10 * (x + d0) + c11 * (y + d1) + c12 * (z + d2) + const1
> + * z' = c20 * (x + d0) + c21 * (y + d1) + c22 * (z + d2) + const2
> + *
> + * Please note that above formula is true only for Blender CSC. Other DE3 CSC
> + * units takes only positive value for difference. From what can be deducted
> + * from BSP driver code, those units probably automatically assume that
> + * difference has to be subtracted.
> + */
> +static const u32 yuv2rgb_de3[] = {
> +       0x0002542a, 0x00000000, 0x0003312a, 0xffffffc0, 0x00000000,
> +       0x0002542a, 0xffff376b, 0xfffe5fc3, 0xfffffe00, 0x00000000,
> +       0x0002542a, 0x000408d3, 0x00000000, 0xfffffe00, 0x00000000,
> +};
> +
> +static const u32 yvu2rgb_de3[] = {
> +       0x0002542a, 0x0003312a, 0x00000000, 0xffffffc0, 0x00000000,
> +       0x0002542a, 0xfffe5fc3, 0xffff376b, 0xfffffe00, 0x00000000,
> +       0x0002542a, 0x00000000, 0x000408d3, 0xfffffe00, 0x00000000,
> +};
> +
>  static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
>                                        enum sun8i_csc_mode mode)
>  {
> @@ -61,6 +89,38 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
>         }
>  }
>
> +static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer,
> +                                           enum sun8i_csc_mode mode)
> +{
> +       const u32 *table;
> +       int i, j;
> +
> +       switch (mode) {
> +       case SUN8I_CSC_MODE_YUV2RGB:
> +               table = yuv2rgb_de3;
> +               break;
> +       case SUN8I_CSC_MODE_YVU2RGB:
> +               table = yvu2rgb_de3;
> +               break;
> +       default:
> +               DRM_WARN("Wrong CSC mode specified.\n");
> +               return;
> +       }
> +
> +       for (i = 0; i < 3; i++) {
> +               for (j = 0; j < 3; j++)
> +                       regmap_write(map,
> +                                    SUN8I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE,
> +                                                                layer, i, j),
> +                                    table[i * 5 + j]);

Given that the first three values occupy contiguous addresses,
you can use regmap_bulk_write() here.

> +               regmap_write(map,
> +                            SUN8I_MIXER_BLEND_CSC_CONST(DE3_BLD_BASE,
> +                                                        layer, i),
> +                            SUN8I_MIXER_BLEND_CSC_CONST_VAL(table[i * 5 + 3],
> +                                                            table[i * 5 + 4]));

Nit: Using a two-dimension array might make it easier to read.

> +       }
> +}
> +
>  static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable)
>  {
>         u32 val;
> @@ -73,21 +133,45 @@ static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable)
>         regmap_update_bits(map, SUN8I_CSC_CTRL(base), SUN8I_CSC_CTRL_EN, val);
>  }
>
> +static void sun8i_de3_ccsc_enable(struct regmap *map, int layer, bool enable)
> +{
> +       u32 val, mask;
> +
> +       mask = SUN8I_MIXER_BLEND_CSC_CTL_EN(layer);
> +
> +       if (enable)
> +               val = mask;
> +       else
> +               val = 0;
> +
> +       regmap_update_bits(map, SUN8I_MIXER_BLEND_CSC_CTL(DE3_BLD_BASE),
> +                          mask, val);
> +}
> +
>  void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer,
>                                      enum sun8i_csc_mode mode)
>  {
> -       u32 base;
> +       if (!mixer->cfg->is_de3) {
> +               u32 base;

You could rewrite this as

    if (mixer->cfg->is_de3) {
               sun8i_de3_ccsc_set_coefficients(mixer->engine.regs,
                                               layer, mode);
               return;
    }

That way you don't need to change the indentation on the existing lines.
I suppose this is more of a personal preference. The downside is the control
flow is slightly more complicated.

> -       base = ccsc_base[mixer->cfg->ccsc][layer];
> +               base = ccsc_base[mixer->cfg->ccsc][layer];
>
> -       sun8i_csc_set_coefficients(mixer->engine.regs, base, mode);
> +               sun8i_csc_set_coefficients(mixer->engine.regs, base, mode);
> +       } else {
> +               sun8i_de3_ccsc_set_coefficients(mixer->engine.regs,
> +                                               layer, mode);
> +       }
>  }
>
>  void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable)
>  {
> -       u32 base;
> +       if (!mixer->cfg->is_de3) {
> +               u32 base;
>
> -       base = ccsc_base[mixer->cfg->ccsc][layer];
> +               base = ccsc_base[mixer->cfg->ccsc][layer];
>
> -       sun8i_csc_enable(mixer->engine.regs, base, enable);
> +               sun8i_csc_enable(mixer->engine.regs, base, enable);
> +       } else {
> +               sun8i_de3_ccsc_enable(mixer->engine.regs, layer, enable);
> +       }
>  }
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> index 743941a33d88..a9218abf0935 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> @@ -460,8 +460,21 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
>         base = sun8i_blender_base(mixer);
>
>         /* Reset the registers */
> -       for (i = 0x0; i < 0x20000; i += 4)
> -               regmap_write(mixer->engine.regs, i, 0);
> +       if (mixer->cfg->is_de3) {
> +               for (i = 0x0; i < 0x3000; i += 4)
> +                       regmap_write(mixer->engine.regs, i, 0);
> +               for (i = 0x20000; i < 0x40000; i += 4)
> +                       regmap_write(mixer->engine.regs, i, 0);
> +               for (i = 0x70000; i < 0x88000; i += 4)
> +                       regmap_write(mixer->engine.regs, i, 0);
> +               for (i = 0xa0000; i < 0xb0000; i += 4)
> +                       regmap_write(mixer->engine.regs, i, 0);
> +               for (i = 0xd0000; i < 0xe0000; i += 4)
> +                       regmap_write(mixer->engine.regs, i, 0);

Could you use the macros *_BASE and *_SIZE here? That would make
it more obviously what parts you're clearing.

The last offset, 0xd0000, isn't even defined in the DE3 spec.

> +       } else {
> +               for (i = 0x0; i < 0x20000; i += 4)
> +                       regmap_write(mixer->engine.regs, i, 0);
> +       }
>
>         /* Enable the mixer */
>         regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL,
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> index 020b0a097c84..4c9a442bbb44 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> @@ -33,6 +33,10 @@
>  #define DE2_CH_BASE                            0x2000
>  #define DE2_CH_SIZE                            0x1000
>
> +#define DE3_BLD_BASE                           0x0800
> +#define DE3_CH_BASE                            0x1000
> +#define DE3_CH_SIZE                            0x0800
> +
>  #define SUN8I_MIXER_BLEND_PIPE_CTL(base)       ((base) + 0)
>  #define SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, x) ((base) + 0x4 + 0x10 * (x))
>  #define SUN8I_MIXER_BLEND_ATTR_INSIZE(base, x) ((base) + 0x8 + 0x10 * (x))
> @@ -47,6 +51,11 @@
>  #define SUN8I_MIXER_BLEND_CK_MAX(base, x)      ((base) + 0xc0 + 0x04 * (x))
>  #define SUN8I_MIXER_BLEND_CK_MIN(base, x)      ((base) + 0xe0 + 0x04 * (x))
>  #define SUN8I_MIXER_BLEND_OUTCTL(base)         ((base) + 0xfc)
> +#define SUN8I_MIXER_BLEND_CSC_CTL(base)                ((base) + 0x100)
> +#define SUN8I_MIXER_BLEND_CSC_COEFF(base, layer, x, y) \
> +       ((base) + 0x110 + (layer) * 0x30 +  (x) * 0x10 + 4 * (y))
> +#define SUN8I_MIXER_BLEND_CSC_CONST(base, layer, i) \
> +       ((base) + 0x110 + (layer) * 0x30 +  (i) * 0x10 + 0x0c)

Should these have a DE3 prefix?

>
>  #define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK      GENMASK(12, 8)
>  #define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe)    BIT(8 + pipe)
> @@ -61,6 +70,9 @@
>
>  #define SUN8I_MIXER_BLEND_OUTCTL_INTERLACED    BIT(1)
>
> +#define SUN8I_MIXER_BLEND_CSC_CTL_EN(ch)       BIT(ch)
> +#define SUN8I_MIXER_BLEND_CSC_CONST_VAL(d, c)  (((d) << 16) | ((c) & 0xffff))
> +

Same here.

>  #define SUN8I_MIXER_FBFMT_ARGB8888     0
>  #define SUN8I_MIXER_FBFMT_ABGR8888     1
>  #define SUN8I_MIXER_FBFMT_RGBA8888     2

[...]

> diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> index 46f0237c17bb..3d0ad64178ea 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> @@ -30,6 +30,8 @@
>  #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE                BIT(15)
>  #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_OFFSET    8
>  #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK      GENMASK(12, 8)
> +#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK      GENMASK(31, 24)
> +#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA(x)                ((x) << 24)

DE3 prefix?

>
>  struct sun8i_mixer;
>
> diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> index 8697afc36023..22e1ed5cd7a4 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> @@ -835,7 +835,10 @@ static const u32 bicubic4coefftab32[480] = {
>
>  static inline u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel)
>  {
> -       return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * channel;
> +       if (mixer->cfg->is_de3)
> +               return DE3_VI_SCALER_BASE + DE3_VI_SCALER_SIZE * channel;
> +       else
> +               return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * channel;
>  }
>
>  static int sun8i_vi_scaler_coef_index(unsigned int step)
> @@ -951,6 +954,35 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
>                 cvphase = vphase;
>         }
>
> +       if (mixer->cfg->is_de3) {
> +               u32 val;
> +
> +               if (format->hsub == 1 && format->vsub == 1)
> +                       val = SUN8I_SCALER_VSU_SCALE_MODE_UI;
> +               else
> +                       val = SUN8I_SCALER_VSU_SCALE_MODE_NORMAL;
> +
> +               regmap_write(mixer->engine.regs,
> +                            SUN8I_SCALER_VSU_SCALE_MODE(base), val);

The remaining settings seem to be related to the edge detection scaling
method. Since you aren't supporting it, are they necessary?

> +               regmap_write(mixer->engine.regs,
> +                            SUN8I_SCALER_VSU_DIR_THR(base),
> +                            SUN8I_SCALER_VSU_SUB_ZERO_DIR_THR(0) |
> +                            SUN8I_SCALER_VSU_ZERO_DIR_THR(0) |
> +                            SUN8I_SCALER_VSU_HORZ_DIR_THR(0xff) |
> +                            SUN8I_SCALER_VSU_VERT_DIR_THR(1));
> +               regmap_write(mixer->engine.regs,
> +                            SUN8I_SCALER_VSU_EDGE_THR(base),
> +                            SUN8I_SCALER_VSU_EDGE_SHIFT(8) |
> +                            SUN8I_SCALER_VSU_EDGE_OFFSET(0));
> +               regmap_write(mixer->engine.regs,
> +                            SUN8I_SCALER_VSU_EDSCL_CTRL(base), 0);
> +               regmap_write(mixer->engine.regs,
> +                            SUN8I_SCALER_VSU_ANGLE_THR(base),
> +                            SUN8I_SCALER_VSU_ANGLE_SHIFT(2) |
> +                            SUN8I_SCALER_VSU_ANGLE_OFFSET(0));
> +       }
> +
>         regmap_write(mixer->engine.regs,
>                      SUN8I_SCALER_VSU_OUTSIZE(base), outsize);
>         regmap_write(mixer->engine.regs,
> diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
> index cd015405f66d..c322f5652481 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
> +++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
> @@ -15,6 +15,9 @@
>  #define DE2_VI_SCALER_BASE 0x20000
>  #define DE2_VI_SCALER_SIZE 0x20000
>
> +#define DE3_VI_SCALER_BASE 0x20000
> +#define DE3_VI_SCALER_SIZE 0x08000
> +
>  /* this two macros assumes 16 fractional bits which is standard in DRM */
>  #define SUN8I_VI_SCALER_SCALE_MIN              1
>  #define SUN8I_VI_SCALER_SCALE_MAX              ((1UL << 20) - 1)
> @@ -25,6 +28,11 @@
>  #define SUN8I_VI_SCALER_SIZE(w, h)             (((h) - 1) << 16 | ((w) - 1))
>
>  #define SUN8I_SCALER_VSU_CTRL(base)            ((base) + 0x0)
> +#define SUN8I_SCALER_VSU_SCALE_MODE(base)      ((base) + 0x10)
> +#define SUN8I_SCALER_VSU_DIR_THR(base)         ((base) + 0x20)
> +#define SUN8I_SCALER_VSU_EDGE_THR(base)                ((base) + 0x24)
> +#define SUN8I_SCALER_VSU_EDSCL_CTRL(base)      ((base) + 0x28)
> +#define SUN8I_SCALER_VSU_ANGLE_THR(base)       ((base) + 0x2c)

DE3 prefix for the new ones please.

>  #define SUN8I_SCALER_VSU_OUTSIZE(base)         ((base) + 0x40)
>  #define SUN8I_SCALER_VSU_YINSIZE(base)         ((base) + 0x80)
>  #define SUN8I_SCALER_VSU_YHSTEP(base)          ((base) + 0x88)
> @@ -46,6 +54,21 @@
>  #define SUN8I_SCALER_VSU_CTRL_EN               BIT(0)
>  #define SUN8I_SCALER_VSU_CTRL_COEFF_RDY                BIT(4)
>
> +#define SUN8I_SCALER_VSU_SUB_ZERO_DIR_THR(x)   (((x) << 24) & 0xFF)
> +#define SUN8I_SCALER_VSU_ZERO_DIR_THR(x)       (((x) << 16) & 0xFF)
> +#define SUN8I_SCALER_VSU_HORZ_DIR_THR(x)       (((x) << 8) & 0xFF)
> +#define SUN8I_SCALER_VSU_VERT_DIR_THR(x)       ((x) & 0xFF)
> +
> +#define SUN8I_SCALER_VSU_SCALE_MODE_UI         0
> +#define SUN8I_SCALER_VSU_SCALE_MODE_NORMAL     1
> +#define SUN8I_SCALER_VSU_SCALE_MODE_ED_SCALE   2
> +
> +#define SUN8I_SCALER_VSU_EDGE_SHIFT(x)         (((x) << 16) & 0xF)
> +#define SUN8I_SCALER_VSU_EDGE_OFFSET(x)                ((x) & 0xFF)
> +
> +#define SUN8I_SCALER_VSU_ANGLE_SHIFT(x)                (((x) << 16) & 0xF)
> +#define SUN8I_SCALER_VSU_ANGLE_OFFSET(x)       ((x) & 0xFF)
> +

Same here.

Regards
ChenYu

>  void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable);
>  void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
>                            u32 src_w, u32 src_h, u32 dst_w, u32 dst_h,
> --
> 2.18.0
>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 13/27] drm/sun4i: Add support for H6 DE3 mixer 0
  2018-09-02  7:26 ` [PATCH 13/27] drm/sun4i: Add support for H6 DE3 mixer 0 Jernej Skrabec
@ 2018-09-22 13:23   ` Chen-Yu Tsai
  2018-09-22 13:47     ` Chen-Yu Tsai
  0 siblings, 1 reply; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-22 13:23 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
>
> Mixer 0 has 1 VI and 3 UI planes, scaler on all planes and can output
> 4K image @60Hz. It also support 10 bit colors.

AFAICT 10 bit color support is not implemented? Please mention this.

>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  drivers/gpu/drm/sun4i/sun8i_mixer.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
>
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> index a9218abf0935..54eca2dd4b33 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> @@ -540,6 +540,15 @@ static int sun8i_mixer_remove(struct platform_device *pdev)
>         return 0;
>  }
>
> +static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = {

Please sort the per-compatible structures according to "version sort" rules.

> +       .ccsc           = 0,
> +       .is_de3         = true,
> +       .mod_rate       = 600000000,
> +       .scaler_mask    = 0xf,
> +       .ui_num         = 3,
> +       .vi_num         = 1,
> +};
> +
>  static const struct sun8i_mixer_cfg sun8i_a83t_mixer0_cfg = {
>         .ccsc           = 0,
>         .scaler_mask    = 0xf,
> @@ -587,6 +596,10 @@ static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
>  };
>
>  static const struct of_device_id sun8i_mixer_of_table[] = {
> +       {
> +               .compatible = "allwinner,sun50i-h6-de3-mixer-0",
> +               .data = &sun50i_h6_mixer0_cfg,
> +       },

Same here.

ChenYu

>         {
>                 .compatible = "allwinner,sun8i-a83t-de2-mixer-0",
>                 .data = &sun8i_a83t_mixer0_cfg,
> --
> 2.18.0
>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 16/27] drm/sun4i: dw-hdmi: Make mode_valid function configurable
  2018-09-02  7:26 ` [PATCH 16/27] drm/sun4i: dw-hdmi: Make mode_valid function configurable Jernej Skrabec
@ 2018-09-22 13:29   ` Chen-Yu Tsai
  0 siblings, 0 replies; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-22 13:29 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
>
> Since it is not possible to access sun8i-dw-hdmi driver private data
> inside mode_valid function, make it configurable. That way different
> versions of HDMI controllers can set different function, depending on
> it's limitations.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

Reviewed-by: Chen-Yu Tsai <wens@csie.org>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 17/27] drm/sun4i: dw-hdmi: Add quirk for setting TMDS clock
  2018-09-02  7:26 ` [PATCH 17/27] drm/sun4i: dw-hdmi: Add quirk for setting TMDS clock Jernej Skrabec
@ 2018-09-22 13:30   ` Chen-Yu Tsai
  0 siblings, 0 replies; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-22 13:30 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
>
> It turns out that H6 HDMI BSP kernel driver doesn't change TMDS rate at
> all. At this point it is not clear whether it is just not necessary or
> it would cause some kind of issues.
>
> Add a quirk for it.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

Reviewed-by: Chen-Yu Tsai <wens@csie.org>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 09/27] dt-bindings: display: sun4i-drm: Add H6 display engine compatibles
       [not found]   ` <5b9f3f4d.1c69fb81.c776b.ee42@mx.google.com>
@ 2018-09-22 13:32     ` Chen-Yu Tsai
  0 siblings, 0 replies; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-22 13:32 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, David Airlie,
	Archit Taneja, devicetree, Stephen Boyd, Mike Turquette,
	dri-devel, linux-kernel, Andrzej Hajda, linux-sunxi, linux-clk,
	linux-arm-kernel

On Mon, Sep 17, 2018 at 1:44 PM Rob Herring <robh@kernel.org> wrote:
>
> On Sun,  2 Sep 2018 09:26:25 +0200, Jernej Skrabec wrote:
> > This commit adds compatibles used in H6 display pipeline, namely for
> > display engine, mixer and TV TCON.
> >
> > H6 display engine is somewhat similar to R40, just less TCONs and
> > mixer support more features.
> >
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> >  .../devicetree/bindings/display/sunxi/sun4i-drm.txt          | 5 ++++-
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> >
>
> Reviewed-by: Rob Herring <robh@kernel.org>

Reviewed-by: Chen-Yu Tsai <wens@csie.org>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 13/27] drm/sun4i: Add support for H6 DE3 mixer 0
  2018-09-22 13:23   ` Chen-Yu Tsai
@ 2018-09-22 13:47     ` Chen-Yu Tsai
  2018-09-23 19:40       ` [linux-sunxi] " Jernej Škrabec
  0 siblings, 1 reply; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-22 13:47 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

On Sat, Sep 22, 2018 at 9:23 PM Chen-Yu Tsai <wens@csie.org> wrote:
>
> On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> >
> > Mixer 0 has 1 VI and 3 UI planes, scaler on all planes and can output
> > 4K image @60Hz. It also support 10 bit colors.
>
> AFAICT 10 bit color support is not implemented? Please mention this.
>
> >
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> >  drivers/gpu/drm/sun4i/sun8i_mixer.c | 13 +++++++++++++
> >  1 file changed, 13 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > index a9218abf0935..54eca2dd4b33 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > @@ -540,6 +540,15 @@ static int sun8i_mixer_remove(struct platform_device *pdev)
> >         return 0;
> >  }
> >
> > +static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = {
>
> Please sort the per-compatible structures according to "version sort" rules.
>
> > +       .ccsc           = 0,
> > +       .is_de3         = true,
> > +       .mod_rate       = 600000000,
> > +       .scaler_mask    = 0xf,
> > +       .ui_num         = 3,
> > +       .vi_num         = 1,
> > +};
> > +
> >  static const struct sun8i_mixer_cfg sun8i_a83t_mixer0_cfg = {
> >         .ccsc           = 0,
> >         .scaler_mask    = 0xf,
> > @@ -587,6 +596,10 @@ static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
> >  };
> >
> >  static const struct of_device_id sun8i_mixer_of_table[] = {
> > +       {
> > +               .compatible = "allwinner,sun50i-h6-de3-mixer-0",
> > +               .data = &sun50i_h6_mixer0_cfg,
> > +       },
>
> Same here.
>
> ChenYu

BTW, DE 3.0 includes a register in DE TOP called "DE IP configure register",
which gives the number of IP blocks per class, per mixer. If we retrieve the
configuration from this register, then we shouldn't need to differentiate
between mixer-0 and mixer-1 with compatible strings.

What do you think?

ChenYu

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 14/27] drm/bridge/synopsys: dw-hdmi: Enable workaround for v2.12a
  2018-09-02  7:26 ` [PATCH 14/27] drm/bridge/synopsys: dw-hdmi: Enable workaround for v2.12a Jernej Skrabec
@ 2018-09-22 13:54   ` Chen-Yu Tsai
  0 siblings, 0 replies; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-22 13:54 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
>
> It turns out that even new DW HDMI controllers exhibits same mangenta

magenta?

Otherwise, FWIW,

Reviewed-by: Chen-Yu Tsai <wens@csie.org>

> line issues as older versions.
>
> Enable workaround for v2.12a.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 5971976284bf..df1c7a2d6961 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -1664,6 +1664,7 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
>         case 0x131a:
>         case 0x132a:
>         case 0x201a:
> +       case 0x212a:
>                 count = 1;
>                 break;
>         default:
> --
> 2.18.0
>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 21/27] drm/sun4i: Add support for H6 HDMI PHY
  2018-09-02  7:26 ` [PATCH 21/27] drm/sun4i: Add support for H6 " Jernej Skrabec
@ 2018-09-22 15:55   ` Chen-Yu Tsai
  2018-09-23 19:29     ` Jernej Škrabec
  0 siblings, 1 reply; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-22 15:55 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

On Sun, Sep 2, 2018 at 3:28 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
>
> H6 has Synopsys DWC HDMI 2.0 TX PHY.
>
> mpll settings were calculated from specifications of similar Synopsys
> HDMI PHY found in i.MX6. Other PHY settings were derived from BSP PHY
> driver code.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 137 +++++++++++++++++++++++++
>  1 file changed, 137 insertions(+)
>
> diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> index ee2bf61cd4d2..2f5499bd35ec 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> @@ -14,6 +14,122 @@
>   */
>  #define I2C_ADDR       0x69
>
> +static const struct dw_hdmi_mpll_config sun50i_h6_mpll_cfg[] = {

How did you choose the pixel clock points for this table? The values
sort of match up with the BSP.

> +       {
> +               30666000, {
> +                       { 0x00b3, 0x0000 },
> +                       { 0x2153, 0x0000 },
> +                       { 0x40f3, 0x0000 },
> +               },
> +       },  {
> +               36800000, {
> +                       { 0x00b3, 0x0000 },
> +                       { 0x2153, 0x0000 },
> +                       { 0x40a2, 0x0001 },
> +               },
> +       },  {
> +               46000000, {
> +                       { 0x00b3, 0x0000 },
> +                       { 0x2142, 0x0001 },
> +                       { 0x40a2, 0x0001 },
> +               },
> +       },  {
> +               61333000, {
> +                       { 0x0072, 0x0001 },
> +                       { 0x2142, 0x0001 },
> +                       { 0x40a2, 0x0001 },
> +               },
> +       },  {
> +               73600000, {
> +                       { 0x0072, 0x0001 },
> +                       { 0x2142, 0x0001 },
> +                       { 0x4061, 0x0002 },
> +               },
> +       },  {
> +               92000000, {
> +                       { 0x0072, 0x0001 },
> +                       { 0x2145, 0x0002 },
> +                       { 0x4061, 0x0002 },
> +               },
> +       },  {
> +               122666000, {
> +                       { 0x0051, 0x0002 },
> +                       { 0x2145, 0x0002 },
> +                       { 0x4061, 0x0002 },
> +               },
> +       },  {
> +               147200000, {
> +                       { 0x0051, 0x0002 },
> +                       { 0x2145, 0x0002 },
> +                       { 0x4064, 0x0003 },
> +               },
> +       },  {
> +               184000000, {
> +                       { 0x0051, 0x0002 },
> +                       { 0x214c, 0x0003 },
> +                       { 0x4064, 0x0003 },
> +               },
> +       },  {
> +               226666000, {
> +                       { 0x0040, 0x0003 },
> +                       { 0x214c, 0x0003 },
> +                       { 0x4064, 0x0003 },
> +               },
> +       },  {
> +               272000000, {
> +                       { 0x0040, 0x0003 },
> +                       { 0x214c, 0x0003 },
> +                       { 0x5a64, 0x0003 },
> +               },
> +       },  {
> +               340000000, {
> +                       { 0x0040, 0x0003 },
> +                       { 0x3b4c, 0x0003 },
> +                       { 0x5a64, 0x0003 },
> +               },
> +       },  {
> +               600000000, {

594000000 is the proper clock rate.

> +                       { 0x1a40, 0x0003 },
> +                       { 0x3b4c, 0x0003 },
> +                       { 0x5a64, 0x0003 },
> +               },
> +       }, {
> +               ~0UL, {
> +                       { 0x0000, 0x0000 },
> +                       { 0x0000, 0x0000 },
> +                       { 0x0000, 0x0000 },
> +               },
> +       }
> +};
> +
> +static const struct dw_hdmi_curr_ctrl sun50i_h6_cur_ctr[] = {

The BSP sometimes uses different settings depending on the pixel repetition.
Any ideas about this? I assume it's because the TMDS clock changes as a
result of pixel repetition, as is the same with different bit depths.

> +       /* pixelclk    bpp8    bpp10   bpp12 */
> +       { 25175000,  { 0x0000, 0x0000, 0x0000 }, },
> +       { 27000000,  { 0x0012, 0x0000, 0x0000 }, },
> +       { 59400000,  { 0x0008, 0x0008, 0x0008 }, },
> +       { 72000000,  { 0x0008, 0x0008, 0x001b }, },
> +       { 74250000,  { 0x0013, 0x0013, 0x0013 }, },
> +       { 90000000,  { 0x0008, 0x001a, 0x001b }, },
> +       { 118800000, { 0x001b, 0x001a, 0x001b }, },
> +       { 144000000, { 0x001b, 0x001a, 0x0034 }, },
> +       { 180000000, { 0x001b, 0x0033, 0x0034 }, },
> +       { 216000000, { 0x0036, 0x0033, 0x0034 }, },
> +       { 237600000, { 0x0036, 0x0033, 0x001b }, },
> +       { 288000000, { 0x0036, 0x001b, 0x001b }, },
> +       { 297000000, { 0x0019, 0x001b, 0x0019 }, },
> +       { 330000000, { 0x0036, 0x001b, 0x001b }, },
> +       { 600000000, { 0x003f, 0x001b, 0x001b }, },
> +       { ~0UL,      { 0x0000, 0x0000, 0x0000 }, }
> +};
> +
> +static const struct dw_hdmi_phy_config sun50i_h6_phy_config[] = {
> +       /*pixelclk   symbol   term   vlev*/

I see a slightly different setting for 27000000, and this frequency
below 74250000
only, and even different for all three bit depths (not listed here). So:

    { 25175000,  0x8009, 0x0004, 0x0232 },
    { 27000000,  0x8009, 0x0007, 0x02b0 },

And,

> +       { 74250000,  0x8009, 0x0004, 0x0232},
> +       { 148500000, 0x8029, 0x0004, 0x0273},

These two don't match what I see in the BSP. BTW, which table did you use?
phy301 or phy303? The code seems to indicate that model 301 is the one.

> +       { 600000000, 0x8039, 0x0004, 0x014a},

594000000 is the proper pixel clock you're after.

> +       { ~0UL,      0x0000, 0x0000, 0x0000}
> +};
> +
>  static int sun8i_hdmi_phy_config_a83t(struct dw_hdmi *hdmi,
>                                       struct sun8i_hdmi_phy *phy,
>                                       unsigned int clk_rate)
> @@ -290,6 +406,16 @@ static void sun8i_hdmi_phy_unlock(struct sun8i_hdmi_phy *phy)
>                      SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC);
>  }
>
> +static void sun50i_hdmi_phy_init_h6(struct sun8i_hdmi_phy *phy)
> +{
> +       regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG,
> +                          SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN,
> +                          SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN);
> +
> +       regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG,
> +                          0xffff0000, 0x80c00000);
> +}
> +
>  static void sun8i_hdmi_phy_init_a83t(struct sun8i_hdmi_phy *phy)
>  {
>         sun8i_hdmi_phy_unlock(phy);
> @@ -423,6 +549,13 @@ static const struct sun8i_hdmi_phy_variant sun50i_a64_hdmi_phy = {
>         .phy_config = &sun8i_hdmi_phy_config_h3,
>  };
>
> +static const struct sun8i_hdmi_phy_variant sun50i_h6_hdmi_phy = {
> +       .cur_ctr  = sun50i_h6_cur_ctr,
> +       .mpll_cfg = sun50i_h6_mpll_cfg,
> +       .phy_cfg  = sun50i_h6_phy_config,
> +       .phy_init = &sun50i_hdmi_phy_init_h6,
> +};
> +
>  static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = {
>         .is_custom_phy = true,
>         .phy_init = &sun8i_hdmi_phy_init_a83t,
> @@ -443,6 +576,10 @@ static const struct of_device_id sun8i_hdmi_phy_of_table[] = {
>                 .compatible = "allwinner,sun50i-a64-hdmi-phy",
>                 .data = &sun50i_a64_hdmi_phy,
>         },
> +       {
> +               .compatible = "allwinner,sun50i-h6-hdmi-phy",
> +               .data = &sun50i_h6_hdmi_phy,
> +       },

Version sort please.

Regards
ChenYu

>         {
>                 .compatible = "allwinner,sun8i-a83t-hdmi-phy",
>                 .data = &sun8i_a83t_hdmi_phy,
> --
> 2.18.0
>
On Sun, Sep 2, 2018 at 3:28 PM Jernej Skrabec <jernej.skrabec@siol.net> wrote:
>
> H6 has Synopsys DWC HDMI 2.0 TX PHY.
>
> mpll settings were calculated from specifications of similar Synopsys
> HDMI PHY found in i.MX6. Other PHY settings were derived from BSP PHY
> driver code.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 137 +++++++++++++++++++++++++
>  1 file changed, 137 insertions(+)
>
> diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> index ee2bf61cd4d2..2f5499bd35ec 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> @@ -14,6 +14,122 @@
>   */
>  #define I2C_ADDR       0x69
>
> +static const struct dw_hdmi_mpll_config sun50i_h6_mpll_cfg[] = {
> +       {
> +               30666000, {
> +                       { 0x00b3, 0x0000 },
> +                       { 0x2153, 0x0000 },
> +                       { 0x40f3, 0x0000 },
> +               },
> +       },  {
> +               36800000, {
> +                       { 0x00b3, 0x0000 },
> +                       { 0x2153, 0x0000 },
> +                       { 0x40a2, 0x0001 },
> +               },
> +       },  {
> +               46000000, {
> +                       { 0x00b3, 0x0000 },
> +                       { 0x2142, 0x0001 },
> +                       { 0x40a2, 0x0001 },
> +               },
> +       },  {
> +               61333000, {
> +                       { 0x0072, 0x0001 },
> +                       { 0x2142, 0x0001 },
> +                       { 0x40a2, 0x0001 },
> +               },
> +       },  {
> +               73600000, {
> +                       { 0x0072, 0x0001 },
> +                       { 0x2142, 0x0001 },
> +                       { 0x4061, 0x0002 },
> +               },
> +       },  {
> +               92000000, {
> +                       { 0x0072, 0x0001 },
> +                       { 0x2145, 0x0002 },
> +                       { 0x4061, 0x0002 },
> +               },
> +       },  {
> +               122666000, {
> +                       { 0x0051, 0x0002 },
> +                       { 0x2145, 0x0002 },
> +                       { 0x4061, 0x0002 },
> +               },
> +       },  {
> +               147200000, {
> +                       { 0x0051, 0x0002 },
> +                       { 0x2145, 0x0002 },
> +                       { 0x4064, 0x0003 },
> +               },
> +       },  {
> +               184000000, {
> +                       { 0x0051, 0x0002 },
> +                       { 0x214c, 0x0003 },
> +                       { 0x4064, 0x0003 },
> +               },
> +       },  {
> +               226666000, {
> +                       { 0x0040, 0x0003 },
> +                       { 0x214c, 0x0003 },
> +                       { 0x4064, 0x0003 },
> +               },
> +       },  {
> +               272000000, {
> +                       { 0x0040, 0x0003 },
> +                       { 0x214c, 0x0003 },
> +                       { 0x5a64, 0x0003 },
> +               },
> +       },  {
> +               340000000, {
> +                       { 0x0040, 0x0003 },
> +                       { 0x3b4c, 0x0003 },
> +                       { 0x5a64, 0x0003 },
> +               },
> +       },  {
> +               600000000, {
> +                       { 0x1a40, 0x0003 },
> +                       { 0x3b4c, 0x0003 },
> +                       { 0x5a64, 0x0003 },
> +               },
> +       }, {
> +               ~0UL, {
> +                       { 0x0000, 0x0000 },
> +                       { 0x0000, 0x0000 },
> +                       { 0x0000, 0x0000 },
> +               },
> +       }
> +};
> +
> +static const struct dw_hdmi_curr_ctrl sun50i_h6_cur_ctr[] = {
> +       /* pixelclk    bpp8    bpp10   bpp12 */
> +       { 25175000,  { 0x0000, 0x0000, 0x0000 }, },
> +       { 27000000,  { 0x0012, 0x0000, 0x0000 }, },
> +       { 59400000,  { 0x0008, 0x0008, 0x0008 }, },
> +       { 72000000,  { 0x0008, 0x0008, 0x001b }, },
> +       { 74250000,  { 0x0013, 0x0013, 0x0013 }, },
> +       { 90000000,  { 0x0008, 0x001a, 0x001b }, },
> +       { 118800000, { 0x001b, 0x001a, 0x001b }, },
> +       { 144000000, { 0x001b, 0x001a, 0x0034 }, },
> +       { 180000000, { 0x001b, 0x0033, 0x0034 }, },
> +       { 216000000, { 0x0036, 0x0033, 0x0034 }, },
> +       { 237600000, { 0x0036, 0x0033, 0x001b }, },
> +       { 288000000, { 0x0036, 0x001b, 0x001b }, },
> +       { 297000000, { 0x0019, 0x001b, 0x0019 }, },
> +       { 330000000, { 0x0036, 0x001b, 0x001b }, },
> +       { 600000000, { 0x003f, 0x001b, 0x001b }, },
> +       { ~0UL,      { 0x0000, 0x0000, 0x0000 }, }
> +};
> +
> +static const struct dw_hdmi_phy_config sun50i_h6_phy_config[] = {
> +       /*pixelclk   symbol   term   vlev*/
> +       { 74250000,  0x8009, 0x0004, 0x0232},
> +       { 148500000, 0x8029, 0x0004, 0x0273},
> +       { 600000000, 0x8039, 0x0004, 0x014a},
> +       { ~0UL,      0x0000, 0x0000, 0x0000}
> +};
> +
>  static int sun8i_hdmi_phy_config_a83t(struct dw_hdmi *hdmi,
>                                       struct sun8i_hdmi_phy *phy,
>                                       unsigned int clk_rate)
> @@ -290,6 +406,16 @@ static void sun8i_hdmi_phy_unlock(struct sun8i_hdmi_phy *phy)
>                      SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC);
>  }
>
> +static void sun50i_hdmi_phy_init_h6(struct sun8i_hdmi_phy *phy)
> +{
> +       regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG,
> +                          SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN,
> +                          SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN);
> +
> +       regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG,
> +                          0xffff0000, 0x80c00000);
> +}
> +
>  static void sun8i_hdmi_phy_init_a83t(struct sun8i_hdmi_phy *phy)
>  {
>         sun8i_hdmi_phy_unlock(phy);
> @@ -423,6 +549,13 @@ static const struct sun8i_hdmi_phy_variant sun50i_a64_hdmi_phy = {
>         .phy_config = &sun8i_hdmi_phy_config_h3,
>  };
>
> +static const struct sun8i_hdmi_phy_variant sun50i_h6_hdmi_phy = {
> +       .cur_ctr  = sun50i_h6_cur_ctr,
> +       .mpll_cfg = sun50i_h6_mpll_cfg,
> +       .phy_cfg  = sun50i_h6_phy_config,
> +       .phy_init = &sun50i_hdmi_phy_init_h6,
> +};
> +
>  static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = {
>         .is_custom_phy = true,
>         .phy_init = &sun8i_hdmi_phy_init_a83t,
> @@ -443,6 +576,10 @@ static const struct of_device_id sun8i_hdmi_phy_of_table[] = {
>                 .compatible = "allwinner,sun50i-a64-hdmi-phy",
>                 .data = &sun50i_a64_hdmi_phy,
>         },
> +       {
> +               .compatible = "allwinner,sun50i-h6-hdmi-phy",
> +               .data = &sun50i_h6_hdmi_phy,
> +       },
>         {
>                 .compatible = "allwinner,sun8i-a83t-hdmi-phy",
>                 .data = &sun8i_a83t_hdmi_phy,
> --
> 2.18.0
>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 21/27] drm/sun4i: Add support for H6 HDMI PHY
  2018-09-22 15:55   ` Chen-Yu Tsai
@ 2018-09-23 19:29     ` Jernej Škrabec
  0 siblings, 0 replies; 66+ messages in thread
From: Jernej Škrabec @ 2018-09-23 19:29 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

Dne sobota, 22. september 2018 ob 17:55:35 CEST je Chen-Yu Tsai napisal(a):
> On Sun, Sep 2, 2018 at 3:28 PM Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > H6 has Synopsys DWC HDMI 2.0 TX PHY.
> > 
> > mpll settings were calculated from specifications of similar Synopsys
> > HDMI PHY found in i.MX6. Other PHY settings were derived from BSP PHY
> > driver code.
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> > 
> >  drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 137 +++++++++++++++++++++++++
> >  1 file changed, 137 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> > b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c index ee2bf61cd4d2..2f5499bd35ec
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> > @@ -14,6 +14,122 @@
> > 
> >   */
> >  
> >  #define I2C_ADDR       0x69
> > 
> > +static const struct dw_hdmi_mpll_config sun50i_h6_mpll_cfg[] = {
> 
> How did you choose the pixel clock points for this table? The values
> sort of match up with the BSP.

I used this script:
https://chromium.googlesource.com/chromiumos/platform/drm-tests/+/master/
rk3288_hdmitables.py

I forgot already how I came to conclusion that there are identical register 
settings. After all, imx6 manual describes DWC HDMI PHY and it seems that 
settings are identical for DWC HDMI PHY contained in imx6, rk3288 and h6.

Check out that script, it has some explanation how values are calculated.

Part of the reason why I didn't use original settings is that it is pain to 
convert BSP PHY settings table to this form. Not all frequencies have settings 
for 8, 10 and 12 bit depth.

> 
> > +       {
> > +               30666000, {
> > +                       { 0x00b3, 0x0000 },
> > +                       { 0x2153, 0x0000 },
> > +                       { 0x40f3, 0x0000 },
> > +               },
> > +       },  {
> > +               36800000, {
> > +                       { 0x00b3, 0x0000 },
> > +                       { 0x2153, 0x0000 },
> > +                       { 0x40a2, 0x0001 },
> > +               },
> > +       },  {
> > +               46000000, {
> > +                       { 0x00b3, 0x0000 },
> > +                       { 0x2142, 0x0001 },
> > +                       { 0x40a2, 0x0001 },
> > +               },
> > +       },  {
> > +               61333000, {
> > +                       { 0x0072, 0x0001 },
> > +                       { 0x2142, 0x0001 },
> > +                       { 0x40a2, 0x0001 },
> > +               },
> > +       },  {
> > +               73600000, {
> > +                       { 0x0072, 0x0001 },
> > +                       { 0x2142, 0x0001 },
> > +                       { 0x4061, 0x0002 },
> > +               },
> > +       },  {
> > +               92000000, {
> > +                       { 0x0072, 0x0001 },
> > +                       { 0x2145, 0x0002 },
> > +                       { 0x4061, 0x0002 },
> > +               },
> > +       },  {
> > +               122666000, {
> > +                       { 0x0051, 0x0002 },
> > +                       { 0x2145, 0x0002 },
> > +                       { 0x4061, 0x0002 },
> > +               },
> > +       },  {
> > +               147200000, {
> > +                       { 0x0051, 0x0002 },
> > +                       { 0x2145, 0x0002 },
> > +                       { 0x4064, 0x0003 },
> > +               },
> > +       },  {
> > +               184000000, {
> > +                       { 0x0051, 0x0002 },
> > +                       { 0x214c, 0x0003 },
> > +                       { 0x4064, 0x0003 },
> > +               },
> > +       },  {
> > +               226666000, {
> > +                       { 0x0040, 0x0003 },
> > +                       { 0x214c, 0x0003 },
> > +                       { 0x4064, 0x0003 },
> > +               },
> > +       },  {
> > +               272000000, {
> > +                       { 0x0040, 0x0003 },
> > +                       { 0x214c, 0x0003 },
> > +                       { 0x5a64, 0x0003 },
> > +               },
> > +       },  {
> > +               340000000, {
> > +                       { 0x0040, 0x0003 },
> > +                       { 0x3b4c, 0x0003 },
> > +                       { 0x5a64, 0x0003 },
> > +               },
> > +       },  {
> > +               600000000, {
> 
> 594000000 is the proper clock rate.
> 
> > +                       { 0x1a40, 0x0003 },
> > +                       { 0x3b4c, 0x0003 },
> > +                       { 0x5a64, 0x0003 },
> > +               },
> > +       }, {
> > +               ~0UL, {
> > +                       { 0x0000, 0x0000 },
> > +                       { 0x0000, 0x0000 },
> > +                       { 0x0000, 0x0000 },
> > +               },
> > +       }
> > +};
> > +
> > +static const struct dw_hdmi_curr_ctrl sun50i_h6_cur_ctr[] = {
> 
> The BSP sometimes uses different settings depending on the pixel repetition.
> Any ideas about this? I assume it's because the TMDS clock changes as a
> result of pixel repetition, as is the same with different bit depths.

No, no idea. As I said before, I went easy way out using script mentioned 
before.

> > +       /* pixelclk    bpp8    bpp10   bpp12 */
> > +       { 25175000,  { 0x0000, 0x0000, 0x0000 }, },
> > +       { 27000000,  { 0x0012, 0x0000, 0x0000 }, },
> > +       { 59400000,  { 0x0008, 0x0008, 0x0008 }, },
> > +       { 72000000,  { 0x0008, 0x0008, 0x001b }, },
> > +       { 74250000,  { 0x0013, 0x0013, 0x0013 }, },
> > +       { 90000000,  { 0x0008, 0x001a, 0x001b }, },
> > +       { 118800000, { 0x001b, 0x001a, 0x001b }, },
> > +       { 144000000, { 0x001b, 0x001a, 0x0034 }, },
> > +       { 180000000, { 0x001b, 0x0033, 0x0034 }, },
> > +       { 216000000, { 0x0036, 0x0033, 0x0034 }, },
> > +       { 237600000, { 0x0036, 0x0033, 0x001b }, },
> > +       { 288000000, { 0x0036, 0x001b, 0x001b }, },
> > +       { 297000000, { 0x0019, 0x001b, 0x0019 }, },
> > +       { 330000000, { 0x0036, 0x001b, 0x001b }, },
> > +       { 600000000, { 0x003f, 0x001b, 0x001b }, },
> > +       { ~0UL,      { 0x0000, 0x0000, 0x0000 }, }
> > +};
> > +
> > +static const struct dw_hdmi_phy_config sun50i_h6_phy_config[] = {
> > +       /*pixelclk   symbol   term   vlev*/
> 
> I see a slightly different setting for 27000000, and this frequency
> below 74250000
> only, and even different for all three bit depths (not listed here). So:
> 
>     { 25175000,  0x8009, 0x0004, 0x0232 },
>     { 27000000,  0x8009, 0x0007, 0x02b0 },
> 
> And,
> 
> > +       { 74250000,  0x8009, 0x0004, 0x0232},
> > +       { 148500000, 0x8029, 0x0004, 0x0273},
> 
> These two don't match what I see in the BSP. BTW, which table did you use?
> phy301 or phy303? The code seems to indicate that model 301 is the one.
> 

yes, BSP uses 301.

Best regards,
Jernej

> > +       { 600000000, 0x8039, 0x0004, 0x014a},
> 
> 594000000 is the proper pixel clock you're after.
> 
> > +       { ~0UL,      0x0000, 0x0000, 0x0000}
> > +};
> > +
> > 
> >  static int sun8i_hdmi_phy_config_a83t(struct dw_hdmi *hdmi,
> >  
> >                                       struct sun8i_hdmi_phy *phy,
> >                                       unsigned int clk_rate)
> > 
> > @@ -290,6 +406,16 @@ static void sun8i_hdmi_phy_unlock(struct
> > sun8i_hdmi_phy *phy)> 
> >                      SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC);
> >  
> >  }
> > 
> > +static void sun50i_hdmi_phy_init_h6(struct sun8i_hdmi_phy *phy)
> > +{
> > +       regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG,
> > +                          SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN,
> > +                          SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN);
> > +
> > +       regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG,
> > +                          0xffff0000, 0x80c00000);
> > +}
> > +
> > 
> >  static void sun8i_hdmi_phy_init_a83t(struct sun8i_hdmi_phy *phy)
> >  {
> >  
> >         sun8i_hdmi_phy_unlock(phy);
> > 
> > @@ -423,6 +549,13 @@ static const struct sun8i_hdmi_phy_variant
> > sun50i_a64_hdmi_phy = {> 
> >         .phy_config = &sun8i_hdmi_phy_config_h3,
> >  
> >  };
> > 
> > +static const struct sun8i_hdmi_phy_variant sun50i_h6_hdmi_phy = {
> > +       .cur_ctr  = sun50i_h6_cur_ctr,
> > +       .mpll_cfg = sun50i_h6_mpll_cfg,
> > +       .phy_cfg  = sun50i_h6_phy_config,
> > +       .phy_init = &sun50i_hdmi_phy_init_h6,
> > +};
> > +
> > 
> >  static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = {
> >  
> >         .is_custom_phy = true,
> >         .phy_init = &sun8i_hdmi_phy_init_a83t,
> > 
> > @@ -443,6 +576,10 @@ static const struct of_device_id
> > sun8i_hdmi_phy_of_table[] = {> 
> >                 .compatible = "allwinner,sun50i-a64-hdmi-phy",
> >                 .data = &sun50i_a64_hdmi_phy,
> >         
> >         },
> > 
> > +       {
> > +               .compatible = "allwinner,sun50i-h6-hdmi-phy",
> > +               .data = &sun50i_h6_hdmi_phy,
> > +       },
> 
> Version sort please.
> 
> Regards
> ChenYu
> 
> >         {
> >         
> >                 .compatible = "allwinner,sun8i-a83t-hdmi-phy",
> >                 .data = &sun8i_a83t_hdmi_phy,
> > 
> > --
> > 2.18.0
> 
> On Sun, Sep 2, 2018 at 3:28 PM Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > H6 has Synopsys DWC HDMI 2.0 TX PHY.
> > 
> > mpll settings were calculated from specifications of similar Synopsys
> > HDMI PHY found in i.MX6. Other PHY settings were derived from BSP PHY
> > driver code.
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> > 
> >  drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 137 +++++++++++++++++++++++++
> >  1 file changed, 137 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> > b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c index ee2bf61cd4d2..2f5499bd35ec
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> > @@ -14,6 +14,122 @@
> > 
> >   */
> >  
> >  #define I2C_ADDR       0x69
> > 
> > +static const struct dw_hdmi_mpll_config sun50i_h6_mpll_cfg[] = {
> > +       {
> > +               30666000, {
> > +                       { 0x00b3, 0x0000 },
> > +                       { 0x2153, 0x0000 },
> > +                       { 0x40f3, 0x0000 },
> > +               },
> > +       },  {
> > +               36800000, {
> > +                       { 0x00b3, 0x0000 },
> > +                       { 0x2153, 0x0000 },
> > +                       { 0x40a2, 0x0001 },
> > +               },
> > +       },  {
> > +               46000000, {
> > +                       { 0x00b3, 0x0000 },
> > +                       { 0x2142, 0x0001 },
> > +                       { 0x40a2, 0x0001 },
> > +               },
> > +       },  {
> > +               61333000, {
> > +                       { 0x0072, 0x0001 },
> > +                       { 0x2142, 0x0001 },
> > +                       { 0x40a2, 0x0001 },
> > +               },
> > +       },  {
> > +               73600000, {
> > +                       { 0x0072, 0x0001 },
> > +                       { 0x2142, 0x0001 },
> > +                       { 0x4061, 0x0002 },
> > +               },
> > +       },  {
> > +               92000000, {
> > +                       { 0x0072, 0x0001 },
> > +                       { 0x2145, 0x0002 },
> > +                       { 0x4061, 0x0002 },
> > +               },
> > +       },  {
> > +               122666000, {
> > +                       { 0x0051, 0x0002 },
> > +                       { 0x2145, 0x0002 },
> > +                       { 0x4061, 0x0002 },
> > +               },
> > +       },  {
> > +               147200000, {
> > +                       { 0x0051, 0x0002 },
> > +                       { 0x2145, 0x0002 },
> > +                       { 0x4064, 0x0003 },
> > +               },
> > +       },  {
> > +               184000000, {
> > +                       { 0x0051, 0x0002 },
> > +                       { 0x214c, 0x0003 },
> > +                       { 0x4064, 0x0003 },
> > +               },
> > +       },  {
> > +               226666000, {
> > +                       { 0x0040, 0x0003 },
> > +                       { 0x214c, 0x0003 },
> > +                       { 0x4064, 0x0003 },
> > +               },
> > +       },  {
> > +               272000000, {
> > +                       { 0x0040, 0x0003 },
> > +                       { 0x214c, 0x0003 },
> > +                       { 0x5a64, 0x0003 },
> > +               },
> > +       },  {
> > +               340000000, {
> > +                       { 0x0040, 0x0003 },
> > +                       { 0x3b4c, 0x0003 },
> > +                       { 0x5a64, 0x0003 },
> > +               },
> > +       },  {
> > +               600000000, {
> > +                       { 0x1a40, 0x0003 },
> > +                       { 0x3b4c, 0x0003 },
> > +                       { 0x5a64, 0x0003 },
> > +               },
> > +       }, {
> > +               ~0UL, {
> > +                       { 0x0000, 0x0000 },
> > +                       { 0x0000, 0x0000 },
> > +                       { 0x0000, 0x0000 },
> > +               },
> > +       }
> > +};
> > +
> > +static const struct dw_hdmi_curr_ctrl sun50i_h6_cur_ctr[] = {
> > +       /* pixelclk    bpp8    bpp10   bpp12 */
> > +       { 25175000,  { 0x0000, 0x0000, 0x0000 }, },
> > +       { 27000000,  { 0x0012, 0x0000, 0x0000 }, },
> > +       { 59400000,  { 0x0008, 0x0008, 0x0008 }, },
> > +       { 72000000,  { 0x0008, 0x0008, 0x001b }, },
> > +       { 74250000,  { 0x0013, 0x0013, 0x0013 }, },
> > +       { 90000000,  { 0x0008, 0x001a, 0x001b }, },
> > +       { 118800000, { 0x001b, 0x001a, 0x001b }, },
> > +       { 144000000, { 0x001b, 0x001a, 0x0034 }, },
> > +       { 180000000, { 0x001b, 0x0033, 0x0034 }, },
> > +       { 216000000, { 0x0036, 0x0033, 0x0034 }, },
> > +       { 237600000, { 0x0036, 0x0033, 0x001b }, },
> > +       { 288000000, { 0x0036, 0x001b, 0x001b }, },
> > +       { 297000000, { 0x0019, 0x001b, 0x0019 }, },
> > +       { 330000000, { 0x0036, 0x001b, 0x001b }, },
> > +       { 600000000, { 0x003f, 0x001b, 0x001b }, },
> > +       { ~0UL,      { 0x0000, 0x0000, 0x0000 }, }
> > +};
> > +
> > +static const struct dw_hdmi_phy_config sun50i_h6_phy_config[] = {
> > +       /*pixelclk   symbol   term   vlev*/
> > +       { 74250000,  0x8009, 0x0004, 0x0232},
> > +       { 148500000, 0x8029, 0x0004, 0x0273},
> > +       { 600000000, 0x8039, 0x0004, 0x014a},
> > +       { ~0UL,      0x0000, 0x0000, 0x0000}
> > +};
> > +
> > 
> >  static int sun8i_hdmi_phy_config_a83t(struct dw_hdmi *hdmi,
> >  
> >                                       struct sun8i_hdmi_phy *phy,
> >                                       unsigned int clk_rate)
> > 
> > @@ -290,6 +406,16 @@ static void sun8i_hdmi_phy_unlock(struct
> > sun8i_hdmi_phy *phy)> 
> >                      SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC);
> >  
> >  }
> > 
> > +static void sun50i_hdmi_phy_init_h6(struct sun8i_hdmi_phy *phy)
> > +{
> > +       regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG,
> > +                          SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN,
> > +                          SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN);
> > +
> > +       regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG,
> > +                          0xffff0000, 0x80c00000);
> > +}
> > +
> > 
> >  static void sun8i_hdmi_phy_init_a83t(struct sun8i_hdmi_phy *phy)
> >  {
> >  
> >         sun8i_hdmi_phy_unlock(phy);
> > 
> > @@ -423,6 +549,13 @@ static const struct sun8i_hdmi_phy_variant
> > sun50i_a64_hdmi_phy = {> 
> >         .phy_config = &sun8i_hdmi_phy_config_h3,
> >  
> >  };
> > 
> > +static const struct sun8i_hdmi_phy_variant sun50i_h6_hdmi_phy = {
> > +       .cur_ctr  = sun50i_h6_cur_ctr,
> > +       .mpll_cfg = sun50i_h6_mpll_cfg,
> > +       .phy_cfg  = sun50i_h6_phy_config,
> > +       .phy_init = &sun50i_hdmi_phy_init_h6,
> > +};
> > +
> > 
> >  static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = {
> >  
> >         .is_custom_phy = true,
> >         .phy_init = &sun8i_hdmi_phy_init_a83t,
> > 
> > @@ -443,6 +576,10 @@ static const struct of_device_id
> > sun8i_hdmi_phy_of_table[] = {> 
> >                 .compatible = "allwinner,sun50i-a64-hdmi-phy",
> >                 .data = &sun50i_a64_hdmi_phy,
> >         
> >         },
> > 
> > +       {
> > +               .compatible = "allwinner,sun50i-h6-hdmi-phy",
> > +               .data = &sun50i_h6_hdmi_phy,
> > +       },
> > 
> >         {
> >         
> >                 .compatible = "allwinner,sun8i-a83t-hdmi-phy",
> >                 .data = &sun8i_a83t_hdmi_phy,
> > 
> > --
> > 2.18.0





^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [linux-sunxi] Re: [PATCH 13/27] drm/sun4i: Add support for H6 DE3 mixer 0
  2018-09-22 13:47     ` Chen-Yu Tsai
@ 2018-09-23 19:40       ` Jernej Škrabec
  2018-09-24  1:59         ` Chen-Yu Tsai
  0 siblings, 1 reply; 66+ messages in thread
From: Jernej Škrabec @ 2018-09-23 19:40 UTC (permalink / raw)
  To: linux-sunxi, wens
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel

Dne sobota, 22. september 2018 ob 15:47:03 CEST je Chen-Yu Tsai napisal(a):
> On Sat, Sep 22, 2018 at 9:23 PM Chen-Yu Tsai <wens@csie.org> wrote:
> > On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > > Mixer 0 has 1 VI and 3 UI planes, scaler on all planes and can output
> > > 4K image @60Hz. It also support 10 bit colors.
> > 
> > AFAICT 10 bit color support is not implemented? Please mention this.

ok.

> > 
> > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > ---
> > > 
> > >  drivers/gpu/drm/sun4i/sun8i_mixer.c | 13 +++++++++++++
> > >  1 file changed, 13 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > b/drivers/gpu/drm/sun4i/sun8i_mixer.c index a9218abf0935..54eca2dd4b33
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > @@ -540,6 +540,15 @@ static int sun8i_mixer_remove(struct
> > > platform_device *pdev)> > 
> > >         return 0;
> > >  
> > >  }
> > > 
> > > +static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = {
> > 
> > Please sort the per-compatible structures according to "version sort"
> > rules.> 
> > > +       .ccsc           = 0,
> > > +       .is_de3         = true,
> > > +       .mod_rate       = 600000000,
> > > +       .scaler_mask    = 0xf,
> > > +       .ui_num         = 3,
> > > +       .vi_num         = 1,
> > > +};
> > > +
> > > 
> > >  static const struct sun8i_mixer_cfg sun8i_a83t_mixer0_cfg = {
> > >  
> > >         .ccsc           = 0,
> > >         .scaler_mask    = 0xf,
> > > 
> > > @@ -587,6 +596,10 @@ static const struct sun8i_mixer_cfg
> > > sun8i_v3s_mixer_cfg = {> > 
> > >  };
> > >  
> > >  static const struct of_device_id sun8i_mixer_of_table[] = {
> > > 
> > > +       {
> > > +               .compatible = "allwinner,sun50i-h6-de3-mixer-0",
> > > +               .data = &sun50i_h6_mixer0_cfg,
> > > +       },
> > 
> > Same here.
> > 
> > ChenYu
> 
> BTW, DE 3.0 includes a register in DE TOP called "DE IP configure register",
> which gives the number of IP blocks per class, per mixer. If we retrieve
> the configuration from this register, then we shouldn't need to
> differentiate between mixer-0 and mixer-1 with compatible strings.
> 
> What do you think?

IIRC, not all setting were correct when read from registers, but I would need 
to check again. I'm also not sure if register holds all possible settings, so 
it is safer to have separate list. We would also have to devise mechanism to 
get this data from DE2/3 CCU driver (it occupies the same memory space).

Perhaps the strongest argument is that some SoCs with DE3 have HW bug in 
mixer1 block, including that in H6. In order to work, mod clock has to be 
enabled for mixer0 and mixer1 at the same time. I would associate that quirk 
with mixer1 compatible.

Best regards,
Jernej




^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 12/27] drm/sun4i: Add basic support for DE3
  2018-09-22 13:19   ` Chen-Yu Tsai
@ 2018-09-23 19:51     ` Jernej Škrabec
  2018-09-24  2:04       ` Chen-Yu Tsai
  2018-10-05 17:51     ` Jernej Škrabec
  1 sibling, 1 reply; 66+ messages in thread
From: Jernej Škrabec @ 2018-09-23 19:51 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

Dne sobota, 22. september 2018 ob 15:19:12 CEST je Chen-Yu Tsai napisal(a):
> On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > Display Engine 3 is an upgrade of DE2 with new features like support for
> > 10 bit color formats and support for AFBC.
> > 
> > Most of DE2 code works with DE3, except some small details.
> > 
> > Add support for it.
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> > 
> >  drivers/gpu/drm/sun4i/sun8i_csc.c       | 96 +++++++++++++++++++++++--
> >  drivers/gpu/drm/sun4i/sun8i_mixer.c     | 17 ++++-
> >  drivers/gpu/drm/sun4i/sun8i_mixer.h     | 21 +++++-
> >  drivers/gpu/drm/sun4i/sun8i_ui_scaler.c |  8 ++-
> >  drivers/gpu/drm/sun4i/sun8i_ui_scaler.h |  1 +
> >  drivers/gpu/drm/sun4i/sun8i_vi_layer.c  |  8 +++
> >  drivers/gpu/drm/sun4i/sun8i_vi_layer.h  |  2 +
> >  drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 34 ++++++++-
> >  drivers/gpu/drm/sun4i/sun8i_vi_scaler.h | 23 ++++++
> >  9 files changed, 197 insertions(+), 13 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c
> > b/drivers/gpu/drm/sun4i/sun8i_csc.c index b14925b40ccf..101901ccf2dc
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_csc.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
> > @@ -34,6 +34,34 @@ static const u32 yvu2rgb[] = {
> > 
> >         0x000004A8, 0x00000000, 0x00000813, 0xFFFBAC4A,
> >  
> >  };
> > 
> > +/*
> > + * DE3 has a bit different CSC units. Factors are in two's complement
> > format. + * First three have 17 bits for fractinal part and last two 2
> > bits. First + * three values in each line are multiplication factor, 4th
> > is difference, + * which is subtracted from the input value before the
> > multiplication and + * last value is constant, which is added at the end.
> > + *
> > + * x' = c00 * (x + d0) + c01 * (y + d1) + c02 * (z + d2) + const0
> > + * y' = c10 * (x + d0) + c11 * (y + d1) + c12 * (z + d2) + const1
> > + * z' = c20 * (x + d0) + c21 * (y + d1) + c22 * (z + d2) + const2
> > + *
> > + * Please note that above formula is true only for Blender CSC. Other DE3
> > CSC + * units takes only positive value for difference. From what can be
> > deducted + * from BSP driver code, those units probably automatically
> > assume that + * difference has to be subtracted.
> > + */
> > +static const u32 yuv2rgb_de3[] = {
> > +       0x0002542a, 0x00000000, 0x0003312a, 0xffffffc0, 0x00000000,
> > +       0x0002542a, 0xffff376b, 0xfffe5fc3, 0xfffffe00, 0x00000000,
> > +       0x0002542a, 0x000408d3, 0x00000000, 0xfffffe00, 0x00000000,
> > +};
> > +
> > +static const u32 yvu2rgb_de3[] = {
> > +       0x0002542a, 0x0003312a, 0x00000000, 0xffffffc0, 0x00000000,
> > +       0x0002542a, 0xfffe5fc3, 0xffff376b, 0xfffffe00, 0x00000000,
> > +       0x0002542a, 0x00000000, 0x000408d3, 0xfffffe00, 0x00000000,
> > +};
> > +
> > 
> >  static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
> >  
> >                                        enum sun8i_csc_mode mode)
> >  
> >  {
> > 
> > @@ -61,6 +89,38 @@ static void sun8i_csc_set_coefficients(struct regmap
> > *map, u32 base,> 
> >         }
> >  
> >  }
> > 
> > +static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int
> > layer,
> > +                                           enum sun8i_csc_mode mode)
> > +{
> > +       const u32 *table;
> > +       int i, j;
> > +
> > +       switch (mode) {
> > +       case SUN8I_CSC_MODE_YUV2RGB:
> > +               table = yuv2rgb_de3;
> > +               break;
> > +       case SUN8I_CSC_MODE_YVU2RGB:
> > +               table = yvu2rgb_de3;
> > +               break;
> > +       default:
> > +               DRM_WARN("Wrong CSC mode specified.\n");
> > +               return;
> > +       }
> > +
> > +       for (i = 0; i < 3; i++) {
> > +               for (j = 0; j < 3; j++)
> > +                       regmap_write(map,
> > +                                   
> > SUN8I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, +                              
> >                                  layer, i, j), +                         
> >           table[i * 5 + j]);
> 
> Given that the first three values occupy contiguous addresses,
> you can use regmap_bulk_write() here.
> 
> > +               regmap_write(map,
> > +                            SUN8I_MIXER_BLEND_CSC_CONST(DE3_BLD_BASE,
> > +                                                        layer, i),
> > +                            SUN8I_MIXER_BLEND_CSC_CONST_VAL(table[i * 5 +
> > 3], +                                                            table[i
> > * 5 + 4]));
> Nit: Using a two-dimension array might make it easier to read.
> 
> > +       }
> > +}
> > +
> > 
> >  static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable)
> >  {
> >  
> >         u32 val;
> > 
> > @@ -73,21 +133,45 @@ static void sun8i_csc_enable(struct regmap *map, u32
> > base, bool enable)> 
> >         regmap_update_bits(map, SUN8I_CSC_CTRL(base), SUN8I_CSC_CTRL_EN,
> >         val);
> >  
> >  }
> > 
> > +static void sun8i_de3_ccsc_enable(struct regmap *map, int layer, bool
> > enable) +{
> > +       u32 val, mask;
> > +
> > +       mask = SUN8I_MIXER_BLEND_CSC_CTL_EN(layer);
> > +
> > +       if (enable)
> > +               val = mask;
> > +       else
> > +               val = 0;
> > +
> > +       regmap_update_bits(map, SUN8I_MIXER_BLEND_CSC_CTL(DE3_BLD_BASE),
> > +                          mask, val);
> > +}
> > +
> > 
> >  void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int
> >  layer,
> >  
> >                                      enum sun8i_csc_mode mode)
> >  
> >  {
> > 
> > -       u32 base;
> > +       if (!mixer->cfg->is_de3) {
> > +               u32 base;
> 
> You could rewrite this as
> 
>     if (mixer->cfg->is_de3) {
>                sun8i_de3_ccsc_set_coefficients(mixer->engine.regs,
>                                                layer, mode);
>                return;
>     }
> 
> That way you don't need to change the indentation on the existing lines.
> I suppose this is more of a personal preference. The downside is the control
> flow is slightly more complicated.
> 
> > -       base = ccsc_base[mixer->cfg->ccsc][layer];
> > +               base = ccsc_base[mixer->cfg->ccsc][layer];
> > 
> > -       sun8i_csc_set_coefficients(mixer->engine.regs, base, mode);
> > +               sun8i_csc_set_coefficients(mixer->engine.regs, base,
> > mode);
> > +       } else {
> > +               sun8i_de3_ccsc_set_coefficients(mixer->engine.regs,
> > +                                               layer, mode);
> > +       }
> > 
> >  }
> >  
> >  void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool
> >  enable) {
> > 
> > -       u32 base;
> > +       if (!mixer->cfg->is_de3) {
> > +               u32 base;
> > 
> > -       base = ccsc_base[mixer->cfg->ccsc][layer];
> > +               base = ccsc_base[mixer->cfg->ccsc][layer];
> > 
> > -       sun8i_csc_enable(mixer->engine.regs, base, enable);
> > +               sun8i_csc_enable(mixer->engine.regs, base, enable);
> > +       } else {
> > +               sun8i_de3_ccsc_enable(mixer->engine.regs, layer, enable);
> > +       }
> > 
> >  }
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 743941a33d88..a9218abf0935
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > @@ -460,8 +460,21 @@ static int sun8i_mixer_bind(struct device *dev,
> > struct device *master,> 
> >         base = sun8i_blender_base(mixer);
> >         
> >         /* Reset the registers */
> > 
> > -       for (i = 0x0; i < 0x20000; i += 4)
> > -               regmap_write(mixer->engine.regs, i, 0);
> > +       if (mixer->cfg->is_de3) {
> > +               for (i = 0x0; i < 0x3000; i += 4)
> > +                       regmap_write(mixer->engine.regs, i, 0);
> > +               for (i = 0x20000; i < 0x40000; i += 4)
> > +                       regmap_write(mixer->engine.regs, i, 0);
> > +               for (i = 0x70000; i < 0x88000; i += 4)
> > +                       regmap_write(mixer->engine.regs, i, 0);
> > +               for (i = 0xa0000; i < 0xb0000; i += 4)
> > +                       regmap_write(mixer->engine.regs, i, 0);
> > +               for (i = 0xd0000; i < 0xe0000; i += 4)
> > +                       regmap_write(mixer->engine.regs, i, 0);
> 
> Could you use the macros *_BASE and *_SIZE here? That would make
> it more obviously what parts you're clearing.

Ok, but where should I define them? In sun8i-mixer.h?

> 
> The last offset, 0xd0000, isn't even defined in the DE3 spec.

It is, check chapter 2.3.2, table 2-3.

> 
> > +       } else {
> > +               for (i = 0x0; i < 0x20000; i += 4)
> > +                       regmap_write(mixer->engine.regs, i, 0);
> > +       }
> > 
> >         /* Enable the mixer */
> >         regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL,
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > b/drivers/gpu/drm/sun4i/sun8i_mixer.h index 020b0a097c84..4c9a442bbb44
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > @@ -33,6 +33,10 @@
> > 
> >  #define DE2_CH_BASE                            0x2000
> >  #define DE2_CH_SIZE                            0x1000
> > 
> > +#define DE3_BLD_BASE                           0x0800
> > +#define DE3_CH_BASE                            0x1000
> > +#define DE3_CH_SIZE                            0x0800
> > +
> > 
> >  #define SUN8I_MIXER_BLEND_PIPE_CTL(base)       ((base) + 0)
> >  #define SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, x) ((base) + 0x4 + 0x10 *
> >  (x))
> >  #define SUN8I_MIXER_BLEND_ATTR_INSIZE(base, x) ((base) + 0x8 + 0x10 *
> >  (x))
> > 
> > @@ -47,6 +51,11 @@
> > 
> >  #define SUN8I_MIXER_BLEND_CK_MAX(base, x)      ((base) + 0xc0 + 0x04 *
> >  (x))
> >  #define SUN8I_MIXER_BLEND_CK_MIN(base, x)      ((base) + 0xe0 + 0x04 *
> >  (x))
> >  #define SUN8I_MIXER_BLEND_OUTCTL(base)         ((base) + 0xfc)
> > 
> > +#define SUN8I_MIXER_BLEND_CSC_CTL(base)                ((base) + 0x100)
> > +#define SUN8I_MIXER_BLEND_CSC_COEFF(base, layer, x, y) \
> > +       ((base) + 0x110 + (layer) * 0x30 +  (x) * 0x10 + 4 * (y))
> > +#define SUN8I_MIXER_BLEND_CSC_CONST(base, layer, i) \
> > +       ((base) + 0x110 + (layer) * 0x30 +  (i) * 0x10 + 0x0c)
> 
> Should these have a DE3 prefix?

Ok for all prefix comments.

> 
> >  #define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK      GENMASK(12, 8)
> >  #define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe)    BIT(8 + pipe)
> > 
> > @@ -61,6 +70,9 @@
> > 
> >  #define SUN8I_MIXER_BLEND_OUTCTL_INTERLACED    BIT(1)
> > 
> > +#define SUN8I_MIXER_BLEND_CSC_CTL_EN(ch)       BIT(ch)
> > +#define SUN8I_MIXER_BLEND_CSC_CONST_VAL(d, c)  (((d) << 16) | ((c) &
> > 0xffff)) +
> 
> Same here.
> 
> >  #define SUN8I_MIXER_FBFMT_ARGB8888     0
> >  #define SUN8I_MIXER_FBFMT_ABGR8888     1
> >  #define SUN8I_MIXER_FBFMT_RGBA8888     2
> 
> [...]
> 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> > b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h index 46f0237c17bb..3d0ad64178ea
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> > @@ -30,6 +30,8 @@
> > 
> >  #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE                BIT(15)
> >  #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_OFFSET    8
> >  #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK      GENMASK(12, 8)
> > 
> > +#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK      GENMASK(31, 24)
> > +#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA(x)                ((x) <<
> > 24)
> 
> DE3 prefix?
> 
> >  struct sun8i_mixer;
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c index
> > 8697afc36023..22e1ed5cd7a4 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > @@ -835,7 +835,10 @@ static const u32 bicubic4coefftab32[480] = {
> > 
> >  static inline u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int
> >  channel) {
> > 
> > -       return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * channel;
> > +       if (mixer->cfg->is_de3)
> > +               return DE3_VI_SCALER_BASE + DE3_VI_SCALER_SIZE * channel;
> > +       else
> > +               return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * channel;
> > 
> >  }
> >  
> >  static int sun8i_vi_scaler_coef_index(unsigned int step)
> > 
> > @@ -951,6 +954,35 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer,
> > int layer,> 
> >                 cvphase = vphase;
> >         
> >         }
> > 
> > +       if (mixer->cfg->is_de3) {
> > +               u32 val;
> > +
> > +               if (format->hsub == 1 && format->vsub == 1)
> > +                       val = SUN8I_SCALER_VSU_SCALE_MODE_UI;
> > +               else
> > +                       val = SUN8I_SCALER_VSU_SCALE_MODE_NORMAL;
> > +
> > +               regmap_write(mixer->engine.regs,
> > +                            SUN8I_SCALER_VSU_SCALE_MODE(base), val);
> 
> The remaining settings seem to be related to the edge detection scaling
> method. Since you aren't supporting it, are they necessary?

Didn't really tried without them IIRC. I will for next revision.

Best regards,
Jernej

> 
> > +               regmap_write(mixer->engine.regs,
> > +                            SUN8I_SCALER_VSU_DIR_THR(base),
> > +                            SUN8I_SCALER_VSU_SUB_ZERO_DIR_THR(0) |
> > +                            SUN8I_SCALER_VSU_ZERO_DIR_THR(0) |
> > +                            SUN8I_SCALER_VSU_HORZ_DIR_THR(0xff) |
> > +                            SUN8I_SCALER_VSU_VERT_DIR_THR(1));
> > +               regmap_write(mixer->engine.regs,
> > +                            SUN8I_SCALER_VSU_EDGE_THR(base),
> > +                            SUN8I_SCALER_VSU_EDGE_SHIFT(8) |
> > +                            SUN8I_SCALER_VSU_EDGE_OFFSET(0));
> > +               regmap_write(mixer->engine.regs,
> > +                            SUN8I_SCALER_VSU_EDSCL_CTRL(base), 0);
> > +               regmap_write(mixer->engine.regs,
> > +                            SUN8I_SCALER_VSU_ANGLE_THR(base),
> > +                            SUN8I_SCALER_VSU_ANGLE_SHIFT(2) |
> > +                            SUN8I_SCALER_VSU_ANGLE_OFFSET(0));
> > +       }
> > +
> > 
> >         regmap_write(mixer->engine.regs,
> >         
> >                      SUN8I_SCALER_VSU_OUTSIZE(base), outsize);
> >         
> >         regmap_write(mixer->engine.regs,
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
> > b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h index
> > cd015405f66d..c322f5652481 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
> > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
> > @@ -15,6 +15,9 @@
> > 
> >  #define DE2_VI_SCALER_BASE 0x20000
> >  #define DE2_VI_SCALER_SIZE 0x20000
> > 
> > +#define DE3_VI_SCALER_BASE 0x20000
> > +#define DE3_VI_SCALER_SIZE 0x08000
> > +
> > 
> >  /* this two macros assumes 16 fractional bits which is standard in DRM */
> >  #define SUN8I_VI_SCALER_SCALE_MIN              1
> >  #define SUN8I_VI_SCALER_SCALE_MAX              ((1UL << 20) - 1)
> > 
> > @@ -25,6 +28,11 @@
> > 
> >  #define SUN8I_VI_SCALER_SIZE(w, h)             (((h) - 1) << 16 | ((w) -
> >  1))
> >  
> >  #define SUN8I_SCALER_VSU_CTRL(base)            ((base) + 0x0)
> > 
> > +#define SUN8I_SCALER_VSU_SCALE_MODE(base)      ((base) + 0x10)
> > +#define SUN8I_SCALER_VSU_DIR_THR(base)         ((base) + 0x20)
> > +#define SUN8I_SCALER_VSU_EDGE_THR(base)                ((base) + 0x24)
> > +#define SUN8I_SCALER_VSU_EDSCL_CTRL(base)      ((base) + 0x28)
> > +#define SUN8I_SCALER_VSU_ANGLE_THR(base)       ((base) + 0x2c)
> 
> DE3 prefix for the new ones please.
> 
> >  #define SUN8I_SCALER_VSU_OUTSIZE(base)         ((base) + 0x40)
> >  #define SUN8I_SCALER_VSU_YINSIZE(base)         ((base) + 0x80)
> >  #define SUN8I_SCALER_VSU_YHSTEP(base)          ((base) + 0x88)
> > 
> > @@ -46,6 +54,21 @@
> > 
> >  #define SUN8I_SCALER_VSU_CTRL_EN               BIT(0)
> >  #define SUN8I_SCALER_VSU_CTRL_COEFF_RDY                BIT(4)
> > 
> > +#define SUN8I_SCALER_VSU_SUB_ZERO_DIR_THR(x)   (((x) << 24) & 0xFF)
> > +#define SUN8I_SCALER_VSU_ZERO_DIR_THR(x)       (((x) << 16) & 0xFF)
> > +#define SUN8I_SCALER_VSU_HORZ_DIR_THR(x)       (((x) << 8) & 0xFF)
> > +#define SUN8I_SCALER_VSU_VERT_DIR_THR(x)       ((x) & 0xFF)
> > +
> > +#define SUN8I_SCALER_VSU_SCALE_MODE_UI         0
> > +#define SUN8I_SCALER_VSU_SCALE_MODE_NORMAL     1
> > +#define SUN8I_SCALER_VSU_SCALE_MODE_ED_SCALE   2
> > +
> > +#define SUN8I_SCALER_VSU_EDGE_SHIFT(x)         (((x) << 16) & 0xF)
> > +#define SUN8I_SCALER_VSU_EDGE_OFFSET(x)                ((x) & 0xFF)
> > +
> > +#define SUN8I_SCALER_VSU_ANGLE_SHIFT(x)                (((x) << 16) &
> > 0xF)
> > +#define SUN8I_SCALER_VSU_ANGLE_OFFSET(x)       ((x) & 0xFF)
> > +
> 
> Same here.
> 
> Regards
> ChenYu
> 
> >  void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool
> >  enable); void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int
> >  layer,
> >  
> >                            u32 src_w, u32 src_h, u32 dst_w, u32 dst_h,
> > 
> > --
> > 2.18.0





^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [linux-sunxi] [PATCH 11/27] drm/sun4i: Rework DE2 register defines
  2018-09-22 12:32   ` [linux-sunxi] " Chen-Yu Tsai
@ 2018-09-23 20:02     ` Jernej Škrabec
  2018-09-24  2:01       ` Chen-Yu Tsai
  0 siblings, 1 reply; 66+ messages in thread
From: Jernej Škrabec @ 2018-09-23 20:02 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi, Icenowy Zheng

Dne sobota, 22. september 2018 ob 14:32:30 CEST je Chen-Yu Tsai napisal(a):
> Hi,
> 
> On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > Most, if not all, registers found in DE2 still exists in DE3. However,
> > units are on different base addresses.
> > 
> > To prepare for addition of DE3 support, registers macros are reworked so
> > they take base address as parameter.
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > [rebased]
> > Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> 
> This patch mostly checks out. But see below.
> 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > b/drivers/gpu/drm/sun4i/sun8i_mixer.h index 406c42e752d7..020b0a097c84
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > @@ -29,20 +29,24 @@
> > 
> >  #define SUN8I_MIXER_GLOBAL_DBUFF_ENABLE                BIT(0)
> > 
> > -#define SUN8I_MIXER_BLEND_PIPE_CTL             0x1000
> > -#define SUN8I_MIXER_BLEND_ATTR_FCOLOR(x)       (0x1004 + 0x10 * (x) +
> > 0x0)
> > -#define SUN8I_MIXER_BLEND_ATTR_INSIZE(x)       (0x1004 + 0x10 * (x) +
> > 0x4)
> > -#define SUN8I_MIXER_BLEND_ATTR_COORD(x)                (0x1004 + 0x10 *
> > (x) + 0x8) -#define SUN8I_MIXER_BLEND_ROUTE                        0x1080
> > -#define SUN8I_MIXER_BLEND_PREMULTIPLY          0x1084
> > -#define SUN8I_MIXER_BLEND_BKCOLOR              0x1088
> > -#define SUN8I_MIXER_BLEND_OUTSIZE              0x108c
> > -#define SUN8I_MIXER_BLEND_MODE(x)              (0x1090 + 0x04 * (x))
> > -#define SUN8I_MIXER_BLEND_CK_CTL               0x10b0
> > -#define SUN8I_MIXER_BLEND_CK_CFG               0x10b4
> > -#define SUN8I_MIXER_BLEND_CK_MAX(x)            (0x10c0 + 0x04 * (x))
> > -#define SUN8I_MIXER_BLEND_CK_MIN(x)            (0x10e0 + 0x04 * (x))
> > -#define SUN8I_MIXER_BLEND_OUTCTL               0x10fc
> > +#define DE2_BLD_BASE                           0x1000
> > +#define DE2_CH_BASE                            0x2000
> > +#define DE2_CH_SIZE                            0x1000
> > +
> > +#define SUN8I_MIXER_BLEND_PIPE_CTL(base)       ((base) + 0)
> > +#define SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, x) ((base) + 0x4 + 0x10 *
> > (x))
> > +#define SUN8I_MIXER_BLEND_ATTR_INSIZE(base, x) ((base) + 0x8 + 0x10 *
> > (x))
> > +#define SUN8I_MIXER_BLEND_ATTR_COORD(base, x)  ((base) + 0xC + 0x10 *
> > (x))
> 
> Nit: Use lowercase for '0xC' to be consistent.
> 
> > +#define SUN8I_MIXER_BLEND_ROUTE(base)          ((base) + 0x80)
> > +#define SUN8I_MIXER_BLEND_PREMULTIPLY(base)    ((base) + 0x84)
> > +#define SUN8I_MIXER_BLEND_BKCOLOR(base)                ((base) + 0x88)
> > +#define SUN8I_MIXER_BLEND_OUTSIZE(base)                ((base) + 0x8c)
> > +#define SUN8I_MIXER_BLEND_MODE(base, x)                ((base) + 0x90 +
> > 0x04 * (x)) +#define SUN8I_MIXER_BLEND_CK_CTL(base)         ((base) +
> > 0xb0)
> > +#define SUN8I_MIXER_BLEND_CK_CFG(base)         ((base) + 0xb4)
> > +#define SUN8I_MIXER_BLEND_CK_MAX(base, x)      ((base) + 0xc0 + 0x04 *
> > (x)) +#define SUN8I_MIXER_BLEND_CK_MIN(base, x)      ((base) + 0xe0 +
> > 0x04 * (x)) +#define SUN8I_MIXER_BLEND_OUTCTL(base)         ((base) +
> > 0xfc)
> > 
> >  #define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK      GENMASK(12, 8)
> >  #define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe)    BIT(8 + pipe)
> 
> [...]
> 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
> > b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c index
> > 6bb2aa164c8e..c68eab8a748f 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
> > @@ -10,6 +10,7 @@
> > 
> >   */
> >  
> >  #include "sun8i_ui_scaler.h"
> > 
> > +#include "sun8i_vi_scaler.h"
> > 
> >  static const u32 lan2coefftab16[240] = {
> >  
> >         0x00004000, 0x00033ffe, 0x00063efc, 0x000a3bfb,
> > 
> > @@ -88,6 +89,14 @@ static const u32 lan2coefftab16[240] = {
> > 
> >         0x0b1c1603, 0x0d1c1502, 0x0e1d1401, 0x0f1d1301,
> >  
> >  };
> > 
> > +static inline u32 sun8i_ui_scaler_base(struct sun8i_mixer *mixer, int
> > channel)
> I recently saw a review comment stating one should not inline functions
> unless they are defined in header files. Otherwise the decision should
> be left up to the compiler.
> 
> > +{
> > +       int vi_num = mixer->cfg->vi_num;
> > +
> > +       return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * vi_num +
> > +              DE2_UI_SCALER_SIZE * (channel - vi_num);
> > +}
> > +
> > 
> >  static int sun8i_ui_scaler_coef_index(unsigned int step)
> >  {
> >  
> >         unsigned int scale, int_part, float_part;
> 
> [...]
> 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c index
> > d3f1acb234b7..8697afc36023 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > @@ -833,6 +833,11 @@ static const u32 bicubic4coefftab32[480] = {
> > 
> >         0x1012110d, 0x1012110d, 0x1013110c, 0x1013110c,
> >  
> >  };
> > 
> > +static inline u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int
> > channel) +{
> > +       return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * channel;
> > +}
> > +
> 
> This one as well.
> 
> >  static int sun8i_vi_scaler_coef_index(unsigned int step)
> >  {
> >  
> >         unsigned int scale, int_part, float_part;
> > 
> > @@ -857,7 +862,7 @@ static int sun8i_vi_scaler_coef_index(unsigned int
> > step)> 
> >         }
> >  
> >  }
> > 
> > -static void sun8i_vi_scaler_set_coeff(struct regmap *map, int layer,
> > +static void sun8i_vi_scaler_set_coeff(struct regmap *map, u32 base,
> > 
> >                                       u32 hstep, u32 vstep,
> >                                       const struct drm_format_info
> >                                       *format)
> 
> This is the only instance where a function's "layer" parameter was changed
> to "base". It would be nice if it were consistent.

Why not? Caller already have base address calculated, so it poses no overhead. 
Additionally, sun8i_vi_scaler_set_coeff() doesn't have struct sun8i_mixer 
*mixer parameter, which would allow calculating base address based on layer 
id. So, you can chose between existing variant or adding additional parameter 
for no real reason.

Best regards,
Jernej




^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [linux-sunxi] Re: [PATCH 13/27] drm/sun4i: Add support for H6 DE3 mixer 0
  2018-09-23 19:40       ` [linux-sunxi] " Jernej Škrabec
@ 2018-09-24  1:59         ` Chen-Yu Tsai
  0 siblings, 0 replies; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-24  1:59 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: linux-sunxi, Rob Herring, Maxime Ripard, Mark Rutland,
	Mike Turquette, Stephen Boyd, David Airlie, Archit Taneja,
	Andrzej Hajda, devicetree, linux-arm-kernel, linux-kernel,
	linux-clk, dri-devel

On Mon, Sep 24, 2018 at 3:40 AM Jernej Škrabec <jernej.skrabec@siol.net> wrote:
>
> Dne sobota, 22. september 2018 ob 15:47:03 CEST je Chen-Yu Tsai napisal(a):
> > On Sat, Sep 22, 2018 at 9:23 PM Chen-Yu Tsai <wens@csie.org> wrote:
> > > On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net>
> wrote:
> > > > Mixer 0 has 1 VI and 3 UI planes, scaler on all planes and can output
> > > > 4K image @60Hz. It also support 10 bit colors.
> > >
> > > AFAICT 10 bit color support is not implemented? Please mention this.
>
> ok.
>
> > >
> > > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > > ---
> > > >
> > > >  drivers/gpu/drm/sun4i/sun8i_mixer.c | 13 +++++++++++++
> > > >  1 file changed, 13 insertions(+)
> > > >
> > > > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > > b/drivers/gpu/drm/sun4i/sun8i_mixer.c index a9218abf0935..54eca2dd4b33
> > > > 100644
> > > > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > > @@ -540,6 +540,15 @@ static int sun8i_mixer_remove(struct
> > > > platform_device *pdev)> >
> > > >         return 0;
> > > >
> > > >  }
> > > >
> > > > +static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = {
> > >
> > > Please sort the per-compatible structures according to "version sort"
> > > rules.>
> > > > +       .ccsc           = 0,
> > > > +       .is_de3         = true,
> > > > +       .mod_rate       = 600000000,
> > > > +       .scaler_mask    = 0xf,
> > > > +       .ui_num         = 3,
> > > > +       .vi_num         = 1,
> > > > +};
> > > > +
> > > >
> > > >  static const struct sun8i_mixer_cfg sun8i_a83t_mixer0_cfg = {
> > > >
> > > >         .ccsc           = 0,
> > > >         .scaler_mask    = 0xf,
> > > >
> > > > @@ -587,6 +596,10 @@ static const struct sun8i_mixer_cfg
> > > > sun8i_v3s_mixer_cfg = {> >
> > > >  };
> > > >
> > > >  static const struct of_device_id sun8i_mixer_of_table[] = {
> > > >
> > > > +       {
> > > > +               .compatible = "allwinner,sun50i-h6-de3-mixer-0",
> > > > +               .data = &sun50i_h6_mixer0_cfg,
> > > > +       },
> > >
> > > Same here.
> > >
> > > ChenYu
> >
> > BTW, DE 3.0 includes a register in DE TOP called "DE IP configure register",
> > which gives the number of IP blocks per class, per mixer. If we retrieve
> > the configuration from this register, then we shouldn't need to
> > differentiate between mixer-0 and mixer-1 with compatible strings.
> >
> > What do you think?
>
> IIRC, not all setting were correct when read from registers, but I would need
> to check again. I'm also not sure if register holds all possible settings, so
> it is safer to have separate list. We would also have to devise mechanism to
> get this data from DE2/3 CCU driver (it occupies the same memory space).
>
> Perhaps the strongest argument is that some SoCs with DE3 have HW bug in
> mixer1 block, including that in H6. In order to work, mod clock has to be
> enabled for mixer0 and mixer1 at the same time. I would associate that quirk
> with mixer1 compatible.

OK. That makes sense. So apart from the mentioning 10 bit support status
in the commit log,

Reviewed-by: Chen-Yu Tsai <wens@csie.org>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [linux-sunxi] [PATCH 11/27] drm/sun4i: Rework DE2 register defines
  2018-09-23 20:02     ` Jernej Škrabec
@ 2018-09-24  2:01       ` Chen-Yu Tsai
  0 siblings, 0 replies; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-24  2:01 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi, Icenowy Zheng

On Mon, Sep 24, 2018 at 4:02 AM Jernej Škrabec <jernej.skrabec@siol.net> wrote:
>
> Dne sobota, 22. september 2018 ob 14:32:30 CEST je Chen-Yu Tsai napisal(a):
> > Hi,
> >
> > On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net>
> wrote:
> > > Most, if not all, registers found in DE2 still exists in DE3. However,
> > > units are on different base addresses.
> > >
> > > To prepare for addition of DE3 support, registers macros are reworked so
> > > they take base address as parameter.
> > >
> > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > [rebased]
> > > Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> >
> > This patch mostly checks out. But see below.
> >
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > > b/drivers/gpu/drm/sun4i/sun8i_mixer.h index 406c42e752d7..020b0a097c84
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > > @@ -29,20 +29,24 @@
> > >
> > >  #define SUN8I_MIXER_GLOBAL_DBUFF_ENABLE                BIT(0)
> > >
> > > -#define SUN8I_MIXER_BLEND_PIPE_CTL             0x1000
> > > -#define SUN8I_MIXER_BLEND_ATTR_FCOLOR(x)       (0x1004 + 0x10 * (x) +
> > > 0x0)
> > > -#define SUN8I_MIXER_BLEND_ATTR_INSIZE(x)       (0x1004 + 0x10 * (x) +
> > > 0x4)
> > > -#define SUN8I_MIXER_BLEND_ATTR_COORD(x)                (0x1004 + 0x10 *
> > > (x) + 0x8) -#define SUN8I_MIXER_BLEND_ROUTE                        0x1080
> > > -#define SUN8I_MIXER_BLEND_PREMULTIPLY          0x1084
> > > -#define SUN8I_MIXER_BLEND_BKCOLOR              0x1088
> > > -#define SUN8I_MIXER_BLEND_OUTSIZE              0x108c
> > > -#define SUN8I_MIXER_BLEND_MODE(x)              (0x1090 + 0x04 * (x))
> > > -#define SUN8I_MIXER_BLEND_CK_CTL               0x10b0
> > > -#define SUN8I_MIXER_BLEND_CK_CFG               0x10b4
> > > -#define SUN8I_MIXER_BLEND_CK_MAX(x)            (0x10c0 + 0x04 * (x))
> > > -#define SUN8I_MIXER_BLEND_CK_MIN(x)            (0x10e0 + 0x04 * (x))
> > > -#define SUN8I_MIXER_BLEND_OUTCTL               0x10fc
> > > +#define DE2_BLD_BASE                           0x1000
> > > +#define DE2_CH_BASE                            0x2000
> > > +#define DE2_CH_SIZE                            0x1000
> > > +
> > > +#define SUN8I_MIXER_BLEND_PIPE_CTL(base)       ((base) + 0)
> > > +#define SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, x) ((base) + 0x4 + 0x10 *
> > > (x))
> > > +#define SUN8I_MIXER_BLEND_ATTR_INSIZE(base, x) ((base) + 0x8 + 0x10 *
> > > (x))
> > > +#define SUN8I_MIXER_BLEND_ATTR_COORD(base, x)  ((base) + 0xC + 0x10 *
> > > (x))
> >
> > Nit: Use lowercase for '0xC' to be consistent.
> >
> > > +#define SUN8I_MIXER_BLEND_ROUTE(base)          ((base) + 0x80)
> > > +#define SUN8I_MIXER_BLEND_PREMULTIPLY(base)    ((base) + 0x84)
> > > +#define SUN8I_MIXER_BLEND_BKCOLOR(base)                ((base) + 0x88)
> > > +#define SUN8I_MIXER_BLEND_OUTSIZE(base)                ((base) + 0x8c)
> > > +#define SUN8I_MIXER_BLEND_MODE(base, x)                ((base) + 0x90 +
> > > 0x04 * (x)) +#define SUN8I_MIXER_BLEND_CK_CTL(base)         ((base) +
> > > 0xb0)
> > > +#define SUN8I_MIXER_BLEND_CK_CFG(base)         ((base) + 0xb4)
> > > +#define SUN8I_MIXER_BLEND_CK_MAX(base, x)      ((base) + 0xc0 + 0x04 *
> > > (x)) +#define SUN8I_MIXER_BLEND_CK_MIN(base, x)      ((base) + 0xe0 +
> > > 0x04 * (x)) +#define SUN8I_MIXER_BLEND_OUTCTL(base)         ((base) +
> > > 0xfc)
> > >
> > >  #define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK      GENMASK(12, 8)
> > >  #define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe)    BIT(8 + pipe)
> >
> > [...]
> >
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
> > > b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c index
> > > 6bb2aa164c8e..c68eab8a748f 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
> > > @@ -10,6 +10,7 @@
> > >
> > >   */
> > >
> > >  #include "sun8i_ui_scaler.h"
> > >
> > > +#include "sun8i_vi_scaler.h"
> > >
> > >  static const u32 lan2coefftab16[240] = {
> > >
> > >         0x00004000, 0x00033ffe, 0x00063efc, 0x000a3bfb,
> > >
> > > @@ -88,6 +89,14 @@ static const u32 lan2coefftab16[240] = {
> > >
> > >         0x0b1c1603, 0x0d1c1502, 0x0e1d1401, 0x0f1d1301,
> > >
> > >  };
> > >
> > > +static inline u32 sun8i_ui_scaler_base(struct sun8i_mixer *mixer, int
> > > channel)
> > I recently saw a review comment stating one should not inline functions
> > unless they are defined in header files. Otherwise the decision should
> > be left up to the compiler.
> >
> > > +{
> > > +       int vi_num = mixer->cfg->vi_num;
> > > +
> > > +       return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * vi_num +
> > > +              DE2_UI_SCALER_SIZE * (channel - vi_num);
> > > +}
> > > +
> > >
> > >  static int sun8i_ui_scaler_coef_index(unsigned int step)
> > >  {
> > >
> > >         unsigned int scale, int_part, float_part;
> >
> > [...]
> >
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > > b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c index
> > > d3f1acb234b7..8697afc36023 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > > @@ -833,6 +833,11 @@ static const u32 bicubic4coefftab32[480] = {
> > >
> > >         0x1012110d, 0x1012110d, 0x1013110c, 0x1013110c,
> > >
> > >  };
> > >
> > > +static inline u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int
> > > channel) +{
> > > +       return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * channel;
> > > +}
> > > +
> >
> > This one as well.
> >
> > >  static int sun8i_vi_scaler_coef_index(unsigned int step)
> > >  {
> > >
> > >         unsigned int scale, int_part, float_part;
> > >
> > > @@ -857,7 +862,7 @@ static int sun8i_vi_scaler_coef_index(unsigned int
> > > step)>
> > >         }
> > >
> > >  }
> > >
> > > -static void sun8i_vi_scaler_set_coeff(struct regmap *map, int layer,
> > > +static void sun8i_vi_scaler_set_coeff(struct regmap *map, u32 base,
> > >
> > >                                       u32 hstep, u32 vstep,
> > >                                       const struct drm_format_info
> > >                                       *format)
> >
> > This is the only instance where a function's "layer" parameter was changed
> > to "base". It would be nice if it were consistent.
>
> Why not? Caller already have base address calculated, so it poses no overhead.
> Additionally, sun8i_vi_scaler_set_coeff() doesn't have struct sun8i_mixer
> *mixer parameter, which would allow calculating base address based on layer
> id. So, you can chose between existing variant or adding additional parameter
> for no real reason.

Thanks for the explanation. Yeah, then the current patch makes sense.

ChenYu

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 12/27] drm/sun4i: Add basic support for DE3
  2018-09-23 19:51     ` Jernej Škrabec
@ 2018-09-24  2:04       ` Chen-Yu Tsai
  0 siblings, 0 replies; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-09-24  2:04 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

On Mon, Sep 24, 2018 at 3:51 AM Jernej Škrabec <jernej.skrabec@siol.net> wrote:
>
> Dne sobota, 22. september 2018 ob 15:19:12 CEST je Chen-Yu Tsai napisal(a):
> > On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net>
> wrote:
> > > Display Engine 3 is an upgrade of DE2 with new features like support for
> > > 10 bit color formats and support for AFBC.
> > >
> > > Most of DE2 code works with DE3, except some small details.
> > >
> > > Add support for it.
> > >
> > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > ---
> > >
> > >  drivers/gpu/drm/sun4i/sun8i_csc.c       | 96 +++++++++++++++++++++++--
> > >  drivers/gpu/drm/sun4i/sun8i_mixer.c     | 17 ++++-
> > >  drivers/gpu/drm/sun4i/sun8i_mixer.h     | 21 +++++-
> > >  drivers/gpu/drm/sun4i/sun8i_ui_scaler.c |  8 ++-
> > >  drivers/gpu/drm/sun4i/sun8i_ui_scaler.h |  1 +
> > >  drivers/gpu/drm/sun4i/sun8i_vi_layer.c  |  8 +++
> > >  drivers/gpu/drm/sun4i/sun8i_vi_layer.h  |  2 +
> > >  drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 34 ++++++++-
> > >  drivers/gpu/drm/sun4i/sun8i_vi_scaler.h | 23 ++++++
> > >  9 files changed, 197 insertions(+), 13 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c
> > > b/drivers/gpu/drm/sun4i/sun8i_csc.c index b14925b40ccf..101901ccf2dc
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_csc.c
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
> > > @@ -34,6 +34,34 @@ static const u32 yvu2rgb[] = {
> > >
> > >         0x000004A8, 0x00000000, 0x00000813, 0xFFFBAC4A,
> > >
> > >  };
> > >
> > > +/*
> > > + * DE3 has a bit different CSC units. Factors are in two's complement
> > > format. + * First three have 17 bits for fractinal part and last two 2
> > > bits. First + * three values in each line are multiplication factor, 4th
> > > is difference, + * which is subtracted from the input value before the
> > > multiplication and + * last value is constant, which is added at the end.
> > > + *
> > > + * x' = c00 * (x + d0) + c01 * (y + d1) + c02 * (z + d2) + const0
> > > + * y' = c10 * (x + d0) + c11 * (y + d1) + c12 * (z + d2) + const1
> > > + * z' = c20 * (x + d0) + c21 * (y + d1) + c22 * (z + d2) + const2
> > > + *
> > > + * Please note that above formula is true only for Blender CSC. Other DE3
> > > CSC + * units takes only positive value for difference. From what can be
> > > deducted + * from BSP driver code, those units probably automatically
> > > assume that + * difference has to be subtracted.
> > > + */
> > > +static const u32 yuv2rgb_de3[] = {
> > > +       0x0002542a, 0x00000000, 0x0003312a, 0xffffffc0, 0x00000000,
> > > +       0x0002542a, 0xffff376b, 0xfffe5fc3, 0xfffffe00, 0x00000000,
> > > +       0x0002542a, 0x000408d3, 0x00000000, 0xfffffe00, 0x00000000,
> > > +};
> > > +
> > > +static const u32 yvu2rgb_de3[] = {
> > > +       0x0002542a, 0x0003312a, 0x00000000, 0xffffffc0, 0x00000000,
> > > +       0x0002542a, 0xfffe5fc3, 0xffff376b, 0xfffffe00, 0x00000000,
> > > +       0x0002542a, 0x00000000, 0x000408d3, 0xfffffe00, 0x00000000,
> > > +};
> > > +
> > >
> > >  static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
> > >
> > >                                        enum sun8i_csc_mode mode)
> > >
> > >  {
> > >
> > > @@ -61,6 +89,38 @@ static void sun8i_csc_set_coefficients(struct regmap
> > > *map, u32 base,>
> > >         }
> > >
> > >  }
> > >
> > > +static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int
> > > layer,
> > > +                                           enum sun8i_csc_mode mode)
> > > +{
> > > +       const u32 *table;
> > > +       int i, j;
> > > +
> > > +       switch (mode) {
> > > +       case SUN8I_CSC_MODE_YUV2RGB:
> > > +               table = yuv2rgb_de3;
> > > +               break;
> > > +       case SUN8I_CSC_MODE_YVU2RGB:
> > > +               table = yvu2rgb_de3;
> > > +               break;
> > > +       default:
> > > +               DRM_WARN("Wrong CSC mode specified.\n");
> > > +               return;
> > > +       }
> > > +
> > > +       for (i = 0; i < 3; i++) {
> > > +               for (j = 0; j < 3; j++)
> > > +                       regmap_write(map,
> > > +
> > > SUN8I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, +
> > >                                  layer, i, j), +
> > >           table[i * 5 + j]);
> >
> > Given that the first three values occupy contiguous addresses,
> > you can use regmap_bulk_write() here.
> >
> > > +               regmap_write(map,
> > > +                            SUN8I_MIXER_BLEND_CSC_CONST(DE3_BLD_BASE,
> > > +                                                        layer, i),
> > > +                            SUN8I_MIXER_BLEND_CSC_CONST_VAL(table[i * 5 +
> > > 3], +                                                            table[i
> > > * 5 + 4]));
> > Nit: Using a two-dimension array might make it easier to read.
> >
> > > +       }
> > > +}
> > > +
> > >
> > >  static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable)
> > >  {
> > >
> > >         u32 val;
> > >
> > > @@ -73,21 +133,45 @@ static void sun8i_csc_enable(struct regmap *map, u32
> > > base, bool enable)>
> > >         regmap_update_bits(map, SUN8I_CSC_CTRL(base), SUN8I_CSC_CTRL_EN,
> > >         val);
> > >
> > >  }
> > >
> > > +static void sun8i_de3_ccsc_enable(struct regmap *map, int layer, bool
> > > enable) +{
> > > +       u32 val, mask;
> > > +
> > > +       mask = SUN8I_MIXER_BLEND_CSC_CTL_EN(layer);
> > > +
> > > +       if (enable)
> > > +               val = mask;
> > > +       else
> > > +               val = 0;
> > > +
> > > +       regmap_update_bits(map, SUN8I_MIXER_BLEND_CSC_CTL(DE3_BLD_BASE),
> > > +                          mask, val);
> > > +}
> > > +
> > >
> > >  void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int
> > >  layer,
> > >
> > >                                      enum sun8i_csc_mode mode)
> > >
> > >  {
> > >
> > > -       u32 base;
> > > +       if (!mixer->cfg->is_de3) {
> > > +               u32 base;
> >
> > You could rewrite this as
> >
> >     if (mixer->cfg->is_de3) {
> >                sun8i_de3_ccsc_set_coefficients(mixer->engine.regs,
> >                                                layer, mode);
> >                return;
> >     }
> >
> > That way you don't need to change the indentation on the existing lines.
> > I suppose this is more of a personal preference. The downside is the control
> > flow is slightly more complicated.
> >
> > > -       base = ccsc_base[mixer->cfg->ccsc][layer];
> > > +               base = ccsc_base[mixer->cfg->ccsc][layer];
> > >
> > > -       sun8i_csc_set_coefficients(mixer->engine.regs, base, mode);
> > > +               sun8i_csc_set_coefficients(mixer->engine.regs, base,
> > > mode);
> > > +       } else {
> > > +               sun8i_de3_ccsc_set_coefficients(mixer->engine.regs,
> > > +                                               layer, mode);
> > > +       }
> > >
> > >  }
> > >
> > >  void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool
> > >  enable) {
> > >
> > > -       u32 base;
> > > +       if (!mixer->cfg->is_de3) {
> > > +               u32 base;
> > >
> > > -       base = ccsc_base[mixer->cfg->ccsc][layer];
> > > +               base = ccsc_base[mixer->cfg->ccsc][layer];
> > >
> > > -       sun8i_csc_enable(mixer->engine.regs, base, enable);
> > > +               sun8i_csc_enable(mixer->engine.regs, base, enable);
> > > +       } else {
> > > +               sun8i_de3_ccsc_enable(mixer->engine.regs, layer, enable);
> > > +       }
> > >
> > >  }
> > >
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 743941a33d88..a9218abf0935
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > @@ -460,8 +460,21 @@ static int sun8i_mixer_bind(struct device *dev,
> > > struct device *master,>
> > >         base = sun8i_blender_base(mixer);
> > >
> > >         /* Reset the registers */
> > >
> > > -       for (i = 0x0; i < 0x20000; i += 4)
> > > -               regmap_write(mixer->engine.regs, i, 0);
> > > +       if (mixer->cfg->is_de3) {
> > > +               for (i = 0x0; i < 0x3000; i += 4)
> > > +                       regmap_write(mixer->engine.regs, i, 0);
> > > +               for (i = 0x20000; i < 0x40000; i += 4)
> > > +                       regmap_write(mixer->engine.regs, i, 0);
> > > +               for (i = 0x70000; i < 0x88000; i += 4)
> > > +                       regmap_write(mixer->engine.regs, i, 0);
> > > +               for (i = 0xa0000; i < 0xb0000; i += 4)
> > > +                       regmap_write(mixer->engine.regs, i, 0);
> > > +               for (i = 0xd0000; i < 0xe0000; i += 4)
> > > +                       regmap_write(mixer->engine.regs, i, 0);
> >
> > Could you use the macros *_BASE and *_SIZE here? That would make
> > it more obviously what parts you're clearing.
>
> Ok, but where should I define them? In sun8i-mixer.h?

If it's only used here you could put them just above this function.

> >
> > The last offset, 0xd0000, isn't even defined in the DE3 spec.
>
> It is, check chapter 2.3.2, table 2-3.

I must have read something incorrectly. I see it now. Thanks.

ChenYu

> >
> > > +       } else {
> > > +               for (i = 0x0; i < 0x20000; i += 4)
> > > +                       regmap_write(mixer->engine.regs, i, 0);
> > > +       }
> > >
> > >         /* Enable the mixer */
> > >         regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL,
> > >
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > > b/drivers/gpu/drm/sun4i/sun8i_mixer.h index 020b0a097c84..4c9a442bbb44
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > > @@ -33,6 +33,10 @@
> > >
> > >  #define DE2_CH_BASE                            0x2000
> > >  #define DE2_CH_SIZE                            0x1000
> > >
> > > +#define DE3_BLD_BASE                           0x0800
> > > +#define DE3_CH_BASE                            0x1000
> > > +#define DE3_CH_SIZE                            0x0800
> > > +
> > >
> > >  #define SUN8I_MIXER_BLEND_PIPE_CTL(base)       ((base) + 0)
> > >  #define SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, x) ((base) + 0x4 + 0x10 *
> > >  (x))
> > >  #define SUN8I_MIXER_BLEND_ATTR_INSIZE(base, x) ((base) + 0x8 + 0x10 *
> > >  (x))
> > >
> > > @@ -47,6 +51,11 @@
> > >
> > >  #define SUN8I_MIXER_BLEND_CK_MAX(base, x)      ((base) + 0xc0 + 0x04 *
> > >  (x))
> > >  #define SUN8I_MIXER_BLEND_CK_MIN(base, x)      ((base) + 0xe0 + 0x04 *
> > >  (x))
> > >  #define SUN8I_MIXER_BLEND_OUTCTL(base)         ((base) + 0xfc)
> > >
> > > +#define SUN8I_MIXER_BLEND_CSC_CTL(base)                ((base) + 0x100)
> > > +#define SUN8I_MIXER_BLEND_CSC_COEFF(base, layer, x, y) \
> > > +       ((base) + 0x110 + (layer) * 0x30 +  (x) * 0x10 + 4 * (y))
> > > +#define SUN8I_MIXER_BLEND_CSC_CONST(base, layer, i) \
> > > +       ((base) + 0x110 + (layer) * 0x30 +  (i) * 0x10 + 0x0c)
> >
> > Should these have a DE3 prefix?
>
> Ok for all prefix comments.
>
> >
> > >  #define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK      GENMASK(12, 8)
> > >  #define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe)    BIT(8 + pipe)
> > >
> > > @@ -61,6 +70,9 @@
> > >
> > >  #define SUN8I_MIXER_BLEND_OUTCTL_INTERLACED    BIT(1)
> > >
> > > +#define SUN8I_MIXER_BLEND_CSC_CTL_EN(ch)       BIT(ch)
> > > +#define SUN8I_MIXER_BLEND_CSC_CONST_VAL(d, c)  (((d) << 16) | ((c) &
> > > 0xffff)) +
> >
> > Same here.
> >
> > >  #define SUN8I_MIXER_FBFMT_ARGB8888     0
> > >  #define SUN8I_MIXER_FBFMT_ABGR8888     1
> > >  #define SUN8I_MIXER_FBFMT_RGBA8888     2
> >
> > [...]
> >
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> > > b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h index 46f0237c17bb..3d0ad64178ea
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> > > @@ -30,6 +30,8 @@
> > >
> > >  #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE                BIT(15)
> > >  #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_OFFSET    8
> > >  #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK      GENMASK(12, 8)
> > >
> > > +#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK      GENMASK(31, 24)
> > > +#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA(x)                ((x) <<
> > > 24)
> >
> > DE3 prefix?
> >
> > >  struct sun8i_mixer;
> > >
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > > b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c index
> > > 8697afc36023..22e1ed5cd7a4 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > > @@ -835,7 +835,10 @@ static const u32 bicubic4coefftab32[480] = {
> > >
> > >  static inline u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int
> > >  channel) {
> > >
> > > -       return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * channel;
> > > +       if (mixer->cfg->is_de3)
> > > +               return DE3_VI_SCALER_BASE + DE3_VI_SCALER_SIZE * channel;
> > > +       else
> > > +               return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * channel;
> > >
> > >  }
> > >
> > >  static int sun8i_vi_scaler_coef_index(unsigned int step)
> > >
> > > @@ -951,6 +954,35 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer,
> > > int layer,>
> > >                 cvphase = vphase;
> > >
> > >         }
> > >
> > > +       if (mixer->cfg->is_de3) {
> > > +               u32 val;
> > > +
> > > +               if (format->hsub == 1 && format->vsub == 1)
> > > +                       val = SUN8I_SCALER_VSU_SCALE_MODE_UI;
> > > +               else
> > > +                       val = SUN8I_SCALER_VSU_SCALE_MODE_NORMAL;
> > > +
> > > +               regmap_write(mixer->engine.regs,
> > > +                            SUN8I_SCALER_VSU_SCALE_MODE(base), val);
> >
> > The remaining settings seem to be related to the edge detection scaling
> > method. Since you aren't supporting it, are they necessary?
>
> Didn't really tried without them IIRC. I will for next revision.
>
> Best regards,
> Jernej
>
> >
> > > +               regmap_write(mixer->engine.regs,
> > > +                            SUN8I_SCALER_VSU_DIR_THR(base),
> > > +                            SUN8I_SCALER_VSU_SUB_ZERO_DIR_THR(0) |
> > > +                            SUN8I_SCALER_VSU_ZERO_DIR_THR(0) |
> > > +                            SUN8I_SCALER_VSU_HORZ_DIR_THR(0xff) |
> > > +                            SUN8I_SCALER_VSU_VERT_DIR_THR(1));
> > > +               regmap_write(mixer->engine.regs,
> > > +                            SUN8I_SCALER_VSU_EDGE_THR(base),
> > > +                            SUN8I_SCALER_VSU_EDGE_SHIFT(8) |
> > > +                            SUN8I_SCALER_VSU_EDGE_OFFSET(0));
> > > +               regmap_write(mixer->engine.regs,
> > > +                            SUN8I_SCALER_VSU_EDSCL_CTRL(base), 0);
> > > +               regmap_write(mixer->engine.regs,
> > > +                            SUN8I_SCALER_VSU_ANGLE_THR(base),
> > > +                            SUN8I_SCALER_VSU_ANGLE_SHIFT(2) |
> > > +                            SUN8I_SCALER_VSU_ANGLE_OFFSET(0));
> > > +       }
> > > +
> > >
> > >         regmap_write(mixer->engine.regs,
> > >
> > >                      SUN8I_SCALER_VSU_OUTSIZE(base), outsize);
> > >
> > >         regmap_write(mixer->engine.regs,
> > >
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
> > > b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h index
> > > cd015405f66d..c322f5652481 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
> > > @@ -15,6 +15,9 @@
> > >
> > >  #define DE2_VI_SCALER_BASE 0x20000
> > >  #define DE2_VI_SCALER_SIZE 0x20000
> > >
> > > +#define DE3_VI_SCALER_BASE 0x20000
> > > +#define DE3_VI_SCALER_SIZE 0x08000
> > > +
> > >
> > >  /* this two macros assumes 16 fractional bits which is standard in DRM */
> > >  #define SUN8I_VI_SCALER_SCALE_MIN              1
> > >  #define SUN8I_VI_SCALER_SCALE_MAX              ((1UL << 20) - 1)
> > >
> > > @@ -25,6 +28,11 @@
> > >
> > >  #define SUN8I_VI_SCALER_SIZE(w, h)             (((h) - 1) << 16 | ((w) -
> > >  1))
> > >
> > >  #define SUN8I_SCALER_VSU_CTRL(base)            ((base) + 0x0)
> > >
> > > +#define SUN8I_SCALER_VSU_SCALE_MODE(base)      ((base) + 0x10)
> > > +#define SUN8I_SCALER_VSU_DIR_THR(base)         ((base) + 0x20)
> > > +#define SUN8I_SCALER_VSU_EDGE_THR(base)                ((base) + 0x24)
> > > +#define SUN8I_SCALER_VSU_EDSCL_CTRL(base)      ((base) + 0x28)
> > > +#define SUN8I_SCALER_VSU_ANGLE_THR(base)       ((base) + 0x2c)
> >
> > DE3 prefix for the new ones please.
> >
> > >  #define SUN8I_SCALER_VSU_OUTSIZE(base)         ((base) + 0x40)
> > >  #define SUN8I_SCALER_VSU_YINSIZE(base)         ((base) + 0x80)
> > >  #define SUN8I_SCALER_VSU_YHSTEP(base)          ((base) + 0x88)
> > >
> > > @@ -46,6 +54,21 @@
> > >
> > >  #define SUN8I_SCALER_VSU_CTRL_EN               BIT(0)
> > >  #define SUN8I_SCALER_VSU_CTRL_COEFF_RDY                BIT(4)
> > >
> > > +#define SUN8I_SCALER_VSU_SUB_ZERO_DIR_THR(x)   (((x) << 24) & 0xFF)
> > > +#define SUN8I_SCALER_VSU_ZERO_DIR_THR(x)       (((x) << 16) & 0xFF)
> > > +#define SUN8I_SCALER_VSU_HORZ_DIR_THR(x)       (((x) << 8) & 0xFF)
> > > +#define SUN8I_SCALER_VSU_VERT_DIR_THR(x)       ((x) & 0xFF)
> > > +
> > > +#define SUN8I_SCALER_VSU_SCALE_MODE_UI         0
> > > +#define SUN8I_SCALER_VSU_SCALE_MODE_NORMAL     1
> > > +#define SUN8I_SCALER_VSU_SCALE_MODE_ED_SCALE   2
> > > +
> > > +#define SUN8I_SCALER_VSU_EDGE_SHIFT(x)         (((x) << 16) & 0xF)
> > > +#define SUN8I_SCALER_VSU_EDGE_OFFSET(x)                ((x) & 0xFF)
> > > +
> > > +#define SUN8I_SCALER_VSU_ANGLE_SHIFT(x)                (((x) << 16) &
> > > 0xF)
> > > +#define SUN8I_SCALER_VSU_ANGLE_OFFSET(x)       ((x) & 0xFF)
> > > +
> >
> > Same here.
> >
> > Regards
> > ChenYu
> >
> > >  void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool
> > >  enable); void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int
> > >  layer,
> > >
> > >                            u32 src_w, u32 src_h, u32 dst_w, u32 dst_h,
> > >
> > > --
> > > 2.18.0
>
>
>
>

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH 12/27] drm/sun4i: Add basic support for DE3
  2018-09-22 13:19   ` Chen-Yu Tsai
  2018-09-23 19:51     ` Jernej Škrabec
@ 2018-10-05 17:51     ` Jernej Škrabec
  2018-10-06 15:34       ` [linux-sunxi] " Chen-Yu Tsai
  1 sibling, 1 reply; 66+ messages in thread
From: Jernej Škrabec @ 2018-10-05 17:51 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

Dne sobota, 22. september 2018 ob 15:19:12 CEST je Chen-Yu Tsai napisal(a):
> On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > Display Engine 3 is an upgrade of DE2 with new features like support for
> > 10 bit color formats and support for AFBC.
> > 
> > Most of DE2 code works with DE3, except some small details.
> > 
> > Add support for it.
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> > 
> >  drivers/gpu/drm/sun4i/sun8i_csc.c       | 96 +++++++++++++++++++++++--
> >  drivers/gpu/drm/sun4i/sun8i_mixer.c     | 17 ++++-
> >  drivers/gpu/drm/sun4i/sun8i_mixer.h     | 21 +++++-
> >  drivers/gpu/drm/sun4i/sun8i_ui_scaler.c |  8 ++-
> >  drivers/gpu/drm/sun4i/sun8i_ui_scaler.h |  1 +
> >  drivers/gpu/drm/sun4i/sun8i_vi_layer.c  |  8 +++
> >  drivers/gpu/drm/sun4i/sun8i_vi_layer.h  |  2 +
> >  drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 34 ++++++++-
> >  drivers/gpu/drm/sun4i/sun8i_vi_scaler.h | 23 ++++++
> >  9 files changed, 197 insertions(+), 13 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c
> > b/drivers/gpu/drm/sun4i/sun8i_csc.c index b14925b40ccf..101901ccf2dc
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_csc.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
> > @@ -34,6 +34,34 @@ static const u32 yvu2rgb[] = {
> > 
> >         0x000004A8, 0x00000000, 0x00000813, 0xFFFBAC4A,
> >  
> >  };
> > 
> > +/*
> > + * DE3 has a bit different CSC units. Factors are in two's complement
> > format. + * First three have 17 bits for fractinal part and last two 2
> > bits. First + * three values in each line are multiplication factor, 4th
> > is difference, + * which is subtracted from the input value before the
> > multiplication and + * last value is constant, which is added at the end.
> > + *
> > + * x' = c00 * (x + d0) + c01 * (y + d1) + c02 * (z + d2) + const0
> > + * y' = c10 * (x + d0) + c11 * (y + d1) + c12 * (z + d2) + const1
> > + * z' = c20 * (x + d0) + c21 * (y + d1) + c22 * (z + d2) + const2
> > + *
> > + * Please note that above formula is true only for Blender CSC. Other DE3
> > CSC + * units takes only positive value for difference. From what can be
> > deducted + * from BSP driver code, those units probably automatically
> > assume that + * difference has to be subtracted.
> > + */
> > +static const u32 yuv2rgb_de3[] = {
> > +       0x0002542a, 0x00000000, 0x0003312a, 0xffffffc0, 0x00000000,
> > +       0x0002542a, 0xffff376b, 0xfffe5fc3, 0xfffffe00, 0x00000000,
> > +       0x0002542a, 0x000408d3, 0x00000000, 0xfffffe00, 0x00000000,
> > +};
> > +
> > +static const u32 yvu2rgb_de3[] = {
> > +       0x0002542a, 0x0003312a, 0x00000000, 0xffffffc0, 0x00000000,
> > +       0x0002542a, 0xfffe5fc3, 0xffff376b, 0xfffffe00, 0x00000000,
> > +       0x0002542a, 0x00000000, 0x000408d3, 0xfffffe00, 0x00000000,
> > +};
> > +
> > 
> >  static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
> >  
> >                                        enum sun8i_csc_mode mode)
> >  
> >  {
> > 
> > @@ -61,6 +89,38 @@ static void sun8i_csc_set_coefficients(struct regmap
> > *map, u32 base,> 
> >         }
> >  
> >  }
> > 
> > +static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int
> > layer,
> > +                                           enum sun8i_csc_mode mode)
> > +{
> > +       const u32 *table;
> > +       int i, j;
> > +
> > +       switch (mode) {
> > +       case SUN8I_CSC_MODE_YUV2RGB:
> > +               table = yuv2rgb_de3;
> > +               break;
> > +       case SUN8I_CSC_MODE_YVU2RGB:
> > +               table = yvu2rgb_de3;
> > +               break;
> > +       default:
> > +               DRM_WARN("Wrong CSC mode specified.\n");
> > +               return;
> > +       }
> > +
> > +       for (i = 0; i < 3; i++) {
> > +               for (j = 0; j < 3; j++)
> > +                       regmap_write(map,
> > +                                   
> > SUN8I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, +                              
> >                                  layer, i, j), +                         
> >           table[i * 5 + j]);
> 
> Given that the first three values occupy contiguous addresses,
> you can use regmap_bulk_write() here.

Do you mind if I rework table in a way that directly fits in registers and use 
regmap_bulk_write() on whole table? This means I must combine two values into 
one for "const" register, but I would explain it better in a comment. It would 
be most elegant solution, one call to regmap_bulk_write() instead of two for 
loops and some arithmetics.

I guess macro for "const" part can stay as documentation.

> 
> > +               regmap_write(map,
> > +                            SUN8I_MIXER_BLEND_CSC_CONST(DE3_BLD_BASE,
> > +                                                        layer, i),
> > +                            SUN8I_MIXER_BLEND_CSC_CONST_VAL(table[i * 5 +
> > 3], +                                                            table[i
> > * 5 + 4]));
> Nit: Using a two-dimension array might make it easier to read.
> 
> > +       }
> > +}
> > +
> > 
> >  static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable)
> >  {
> >  
> >         u32 val;
> > 
> > @@ -73,21 +133,45 @@ static void sun8i_csc_enable(struct regmap *map, u32
> > base, bool enable)> 
> >         regmap_update_bits(map, SUN8I_CSC_CTRL(base), SUN8I_CSC_CTRL_EN,
> >         val);
> >  
> >  }
> > 
> > +static void sun8i_de3_ccsc_enable(struct regmap *map, int layer, bool
> > enable) +{
> > +       u32 val, mask;
> > +
> > +       mask = SUN8I_MIXER_BLEND_CSC_CTL_EN(layer);
> > +
> > +       if (enable)
> > +               val = mask;
> > +       else
> > +               val = 0;
> > +
> > +       regmap_update_bits(map, SUN8I_MIXER_BLEND_CSC_CTL(DE3_BLD_BASE),
> > +                          mask, val);
> > +}
> > +
> > 
> >  void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int
> >  layer,
> >  
> >                                      enum sun8i_csc_mode mode)
> >  
> >  {
> > 
> > -       u32 base;
> > +       if (!mixer->cfg->is_de3) {
> > +               u32 base;
> 
> You could rewrite this as
> 
>     if (mixer->cfg->is_de3) {
>                sun8i_de3_ccsc_set_coefficients(mixer->engine.regs,
>                                                layer, mode);
>                return;
>     }
> 
> That way you don't need to change the indentation on the existing lines.
> I suppose this is more of a personal preference. The downside is the control
> flow is slightly more complicated.
> 
> > -       base = ccsc_base[mixer->cfg->ccsc][layer];
> > +               base = ccsc_base[mixer->cfg->ccsc][layer];
> > 
> > -       sun8i_csc_set_coefficients(mixer->engine.regs, base, mode);
> > +               sun8i_csc_set_coefficients(mixer->engine.regs, base,
> > mode);
> > +       } else {
> > +               sun8i_de3_ccsc_set_coefficients(mixer->engine.regs,
> > +                                               layer, mode);
> > +       }
> > 
> >  }
> >  
> >  void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool
> >  enable) {
> > 
> > -       u32 base;
> > +       if (!mixer->cfg->is_de3) {
> > +               u32 base;
> > 
> > -       base = ccsc_base[mixer->cfg->ccsc][layer];
> > +               base = ccsc_base[mixer->cfg->ccsc][layer];
> > 
> > -       sun8i_csc_enable(mixer->engine.regs, base, enable);
> > +               sun8i_csc_enable(mixer->engine.regs, base, enable);
> > +       } else {
> > +               sun8i_de3_ccsc_enable(mixer->engine.regs, layer, enable);
> > +       }
> > 
> >  }
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 743941a33d88..a9218abf0935
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > @@ -460,8 +460,21 @@ static int sun8i_mixer_bind(struct device *dev,
> > struct device *master,> 
> >         base = sun8i_blender_base(mixer);
> >         
> >         /* Reset the registers */
> > 
> > -       for (i = 0x0; i < 0x20000; i += 4)
> > -               regmap_write(mixer->engine.regs, i, 0);
> > +       if (mixer->cfg->is_de3) {
> > +               for (i = 0x0; i < 0x3000; i += 4)
> > +                       regmap_write(mixer->engine.regs, i, 0);
> > +               for (i = 0x20000; i < 0x40000; i += 4)
> > +                       regmap_write(mixer->engine.regs, i, 0);
> > +               for (i = 0x70000; i < 0x88000; i += 4)
> > +                       regmap_write(mixer->engine.regs, i, 0);
> > +               for (i = 0xa0000; i < 0xb0000; i += 4)
> > +                       regmap_write(mixer->engine.regs, i, 0);
> > +               for (i = 0xd0000; i < 0xe0000; i += 4)
> > +                       regmap_write(mixer->engine.regs, i, 0);
> 
> Could you use the macros *_BASE and *_SIZE here? That would make
> it more obviously what parts you're clearing.
> 
> The last offset, 0xd0000, isn't even defined in the DE3 spec.
> 
> > +       } else {
> > +               for (i = 0x0; i < 0x20000; i += 4)
> > +                       regmap_write(mixer->engine.regs, i, 0);
> > +       }
> > 
> >         /* Enable the mixer */
> >         regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL,
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > b/drivers/gpu/drm/sun4i/sun8i_mixer.h index 020b0a097c84..4c9a442bbb44
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > @@ -33,6 +33,10 @@
> > 
> >  #define DE2_CH_BASE                            0x2000
> >  #define DE2_CH_SIZE                            0x1000
> > 
> > +#define DE3_BLD_BASE                           0x0800
> > +#define DE3_CH_BASE                            0x1000
> > +#define DE3_CH_SIZE                            0x0800
> > +
> > 
> >  #define SUN8I_MIXER_BLEND_PIPE_CTL(base)       ((base) + 0)
> >  #define SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, x) ((base) + 0x4 + 0x10 *
> >  (x))
> >  #define SUN8I_MIXER_BLEND_ATTR_INSIZE(base, x) ((base) + 0x8 + 0x10 *
> >  (x))
> > 
> > @@ -47,6 +51,11 @@
> > 
> >  #define SUN8I_MIXER_BLEND_CK_MAX(base, x)      ((base) + 0xc0 + 0x04 *
> >  (x))
> >  #define SUN8I_MIXER_BLEND_CK_MIN(base, x)      ((base) + 0xe0 + 0x04 *
> >  (x))
> >  #define SUN8I_MIXER_BLEND_OUTCTL(base)         ((base) + 0xfc)
> > 
> > +#define SUN8I_MIXER_BLEND_CSC_CTL(base)                ((base) + 0x100)
> > +#define SUN8I_MIXER_BLEND_CSC_COEFF(base, layer, x, y) \
> > +       ((base) + 0x110 + (layer) * 0x30 +  (x) * 0x10 + 4 * (y))
> > +#define SUN8I_MIXER_BLEND_CSC_CONST(base, layer, i) \
> > +       ((base) + 0x110 + (layer) * 0x30 +  (i) * 0x10 + 0x0c)
> 
> Should these have a DE3 prefix?

How do you want this to look like?

SUN50I_DE3_MIXER_BLEND_CSC_CONST?

SUN8I prefix doesn't fit for DE3, but as usual, there is a chance that AW 
releases 32 bit SoC with DE3.

At the end, it would be better to rename everything to have just DE2 or DE3 
prefix without mentioning any SoC family. After all, DE2 is also supported on 
sun50i family, which makes any family name in DE2/3 macros confusing...

Do you think I can squeeze dropping SUN8I prefix to a previous patch, where 
macros are reworked anyway?

Best regards,
Jernej

> 
> >  #define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK      GENMASK(12, 8)
> >  #define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe)    BIT(8 + pipe)
> > 
> > @@ -61,6 +70,9 @@
> > 
> >  #define SUN8I_MIXER_BLEND_OUTCTL_INTERLACED    BIT(1)
> > 
> > +#define SUN8I_MIXER_BLEND_CSC_CTL_EN(ch)       BIT(ch)
> > +#define SUN8I_MIXER_BLEND_CSC_CONST_VAL(d, c)  (((d) << 16) | ((c) &
> > 0xffff)) +
> 
> Same here.
> 
> >  #define SUN8I_MIXER_FBFMT_ARGB8888     0
> >  #define SUN8I_MIXER_FBFMT_ABGR8888     1
> >  #define SUN8I_MIXER_FBFMT_RGBA8888     2
> 
> [...]
> 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> > b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h index 46f0237c17bb..3d0ad64178ea
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> > @@ -30,6 +30,8 @@
> > 
> >  #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE                BIT(15)
> >  #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_OFFSET    8
> >  #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK      GENMASK(12, 8)
> > 
> > +#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK      GENMASK(31, 24)
> > +#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA(x)                ((x) <<
> > 24)
> 
> DE3 prefix?
> 
> >  struct sun8i_mixer;
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c index
> > 8697afc36023..22e1ed5cd7a4 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > @@ -835,7 +835,10 @@ static const u32 bicubic4coefftab32[480] = {
> > 
> >  static inline u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int
> >  channel) {
> > 
> > -       return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * channel;
> > +       if (mixer->cfg->is_de3)
> > +               return DE3_VI_SCALER_BASE + DE3_VI_SCALER_SIZE * channel;
> > +       else
> > +               return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * channel;
> > 
> >  }
> >  
> >  static int sun8i_vi_scaler_coef_index(unsigned int step)
> > 
> > @@ -951,6 +954,35 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer,
> > int layer,> 
> >                 cvphase = vphase;
> >         
> >         }
> > 
> > +       if (mixer->cfg->is_de3) {
> > +               u32 val;
> > +
> > +               if (format->hsub == 1 && format->vsub == 1)
> > +                       val = SUN8I_SCALER_VSU_SCALE_MODE_UI;
> > +               else
> > +                       val = SUN8I_SCALER_VSU_SCALE_MODE_NORMAL;
> > +
> > +               regmap_write(mixer->engine.regs,
> > +                            SUN8I_SCALER_VSU_SCALE_MODE(base), val);
> 
> The remaining settings seem to be related to the edge detection scaling
> method. Since you aren't supporting it, are they necessary?
> 
> > +               regmap_write(mixer->engine.regs,
> > +                            SUN8I_SCALER_VSU_DIR_THR(base),
> > +                            SUN8I_SCALER_VSU_SUB_ZERO_DIR_THR(0) |
> > +                            SUN8I_SCALER_VSU_ZERO_DIR_THR(0) |
> > +                            SUN8I_SCALER_VSU_HORZ_DIR_THR(0xff) |
> > +                            SUN8I_SCALER_VSU_VERT_DIR_THR(1));
> > +               regmap_write(mixer->engine.regs,
> > +                            SUN8I_SCALER_VSU_EDGE_THR(base),
> > +                            SUN8I_SCALER_VSU_EDGE_SHIFT(8) |
> > +                            SUN8I_SCALER_VSU_EDGE_OFFSET(0));
> > +               regmap_write(mixer->engine.regs,
> > +                            SUN8I_SCALER_VSU_EDSCL_CTRL(base), 0);
> > +               regmap_write(mixer->engine.regs,
> > +                            SUN8I_SCALER_VSU_ANGLE_THR(base),
> > +                            SUN8I_SCALER_VSU_ANGLE_SHIFT(2) |
> > +                            SUN8I_SCALER_VSU_ANGLE_OFFSET(0));
> > +       }
> > +
> > 
> >         regmap_write(mixer->engine.regs,
> >         
> >                      SUN8I_SCALER_VSU_OUTSIZE(base), outsize);
> >         
> >         regmap_write(mixer->engine.regs,
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
> > b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h index
> > cd015405f66d..c322f5652481 100644
> > --- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
> > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
> > @@ -15,6 +15,9 @@
> > 
> >  #define DE2_VI_SCALER_BASE 0x20000
> >  #define DE2_VI_SCALER_SIZE 0x20000
> > 
> > +#define DE3_VI_SCALER_BASE 0x20000
> > +#define DE3_VI_SCALER_SIZE 0x08000
> > +
> > 
> >  /* this two macros assumes 16 fractional bits which is standard in DRM */
> >  #define SUN8I_VI_SCALER_SCALE_MIN              1
> >  #define SUN8I_VI_SCALER_SCALE_MAX              ((1UL << 20) - 1)
> > 
> > @@ -25,6 +28,11 @@
> > 
> >  #define SUN8I_VI_SCALER_SIZE(w, h)             (((h) - 1) << 16 | ((w) -
> >  1))
> >  
> >  #define SUN8I_SCALER_VSU_CTRL(base)            ((base) + 0x0)
> > 
> > +#define SUN8I_SCALER_VSU_SCALE_MODE(base)      ((base) + 0x10)
> > +#define SUN8I_SCALER_VSU_DIR_THR(base)         ((base) + 0x20)
> > +#define SUN8I_SCALER_VSU_EDGE_THR(base)                ((base) + 0x24)
> > +#define SUN8I_SCALER_VSU_EDSCL_CTRL(base)      ((base) + 0x28)
> > +#define SUN8I_SCALER_VSU_ANGLE_THR(base)       ((base) + 0x2c)
> 
> DE3 prefix for the new ones please.
> 
> >  #define SUN8I_SCALER_VSU_OUTSIZE(base)         ((base) + 0x40)
> >  #define SUN8I_SCALER_VSU_YINSIZE(base)         ((base) + 0x80)
> >  #define SUN8I_SCALER_VSU_YHSTEP(base)          ((base) + 0x88)
> > 
> > @@ -46,6 +54,21 @@
> > 
> >  #define SUN8I_SCALER_VSU_CTRL_EN               BIT(0)
> >  #define SUN8I_SCALER_VSU_CTRL_COEFF_RDY                BIT(4)
> > 
> > +#define SUN8I_SCALER_VSU_SUB_ZERO_DIR_THR(x)   (((x) << 24) & 0xFF)
> > +#define SUN8I_SCALER_VSU_ZERO_DIR_THR(x)       (((x) << 16) & 0xFF)
> > +#define SUN8I_SCALER_VSU_HORZ_DIR_THR(x)       (((x) << 8) & 0xFF)
> > +#define SUN8I_SCALER_VSU_VERT_DIR_THR(x)       ((x) & 0xFF)
> > +
> > +#define SUN8I_SCALER_VSU_SCALE_MODE_UI         0
> > +#define SUN8I_SCALER_VSU_SCALE_MODE_NORMAL     1
> > +#define SUN8I_SCALER_VSU_SCALE_MODE_ED_SCALE   2
> > +
> > +#define SUN8I_SCALER_VSU_EDGE_SHIFT(x)         (((x) << 16) & 0xF)
> > +#define SUN8I_SCALER_VSU_EDGE_OFFSET(x)                ((x) & 0xFF)
> > +
> > +#define SUN8I_SCALER_VSU_ANGLE_SHIFT(x)                (((x) << 16) &
> > 0xF)
> > +#define SUN8I_SCALER_VSU_ANGLE_OFFSET(x)       ((x) & 0xFF)
> > +
> 
> Same here.
> 
> Regards
> ChenYu
> 
> >  void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool
> >  enable); void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int
> >  layer,
> >  
> >                            u32 src_w, u32 src_h, u32 dst_w, u32 dst_h,
> > 
> > --
> > 2.18.0





^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [linux-sunxi] Re: [PATCH 12/27] drm/sun4i: Add basic support for DE3
  2018-10-05 17:51     ` Jernej Škrabec
@ 2018-10-06 15:34       ` Chen-Yu Tsai
  0 siblings, 0 replies; 66+ messages in thread
From: Chen-Yu Tsai @ 2018-10-06 15:34 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Rob Herring, Maxime Ripard, Mark Rutland, Mike Turquette,
	Stephen Boyd, David Airlie, Archit Taneja, Andrzej Hajda,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk, dri-devel,
	linux-sunxi

On Sat, Oct 6, 2018 at 1:51 AM Jernej Škrabec <jernej.skrabec@siol.net> wrote:
>
> Dne sobota, 22. september 2018 ob 15:19:12 CEST je Chen-Yu Tsai napisal(a):
> > On Sun, Sep 2, 2018 at 3:27 PM Jernej Skrabec <jernej.skrabec@siol.net>
> wrote:
> > > Display Engine 3 is an upgrade of DE2 with new features like support for
> > > 10 bit color formats and support for AFBC.
> > >
> > > Most of DE2 code works with DE3, except some small details.
> > >
> > > Add support for it.
> > >
> > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > ---
> > >
> > >  drivers/gpu/drm/sun4i/sun8i_csc.c       | 96 +++++++++++++++++++++++--
> > >  drivers/gpu/drm/sun4i/sun8i_mixer.c     | 17 ++++-
> > >  drivers/gpu/drm/sun4i/sun8i_mixer.h     | 21 +++++-
> > >  drivers/gpu/drm/sun4i/sun8i_ui_scaler.c |  8 ++-
> > >  drivers/gpu/drm/sun4i/sun8i_ui_scaler.h |  1 +
> > >  drivers/gpu/drm/sun4i/sun8i_vi_layer.c  |  8 +++
> > >  drivers/gpu/drm/sun4i/sun8i_vi_layer.h  |  2 +
> > >  drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 34 ++++++++-
> > >  drivers/gpu/drm/sun4i/sun8i_vi_scaler.h | 23 ++++++
> > >  9 files changed, 197 insertions(+), 13 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c
> > > b/drivers/gpu/drm/sun4i/sun8i_csc.c index b14925b40ccf..101901ccf2dc
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_csc.c
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
> > > @@ -34,6 +34,34 @@ static const u32 yvu2rgb[] = {
> > >
> > >         0x000004A8, 0x00000000, 0x00000813, 0xFFFBAC4A,
> > >
> > >  };
> > >
> > > +/*
> > > + * DE3 has a bit different CSC units. Factors are in two's complement
> > > format. + * First three have 17 bits for fractinal part and last two 2
> > > bits. First + * three values in each line are multiplication factor, 4th
> > > is difference, + * which is subtracted from the input value before the
> > > multiplication and + * last value is constant, which is added at the end.
> > > + *
> > > + * x' = c00 * (x + d0) + c01 * (y + d1) + c02 * (z + d2) + const0
> > > + * y' = c10 * (x + d0) + c11 * (y + d1) + c12 * (z + d2) + const1
> > > + * z' = c20 * (x + d0) + c21 * (y + d1) + c22 * (z + d2) + const2
> > > + *
> > > + * Please note that above formula is true only for Blender CSC. Other DE3
> > > CSC + * units takes only positive value for difference. From what can be
> > > deducted + * from BSP driver code, those units probably automatically
> > > assume that + * difference has to be subtracted.
> > > + */
> > > +static const u32 yuv2rgb_de3[] = {
> > > +       0x0002542a, 0x00000000, 0x0003312a, 0xffffffc0, 0x00000000,
> > > +       0x0002542a, 0xffff376b, 0xfffe5fc3, 0xfffffe00, 0x00000000,
> > > +       0x0002542a, 0x000408d3, 0x00000000, 0xfffffe00, 0x00000000,
> > > +};
> > > +
> > > +static const u32 yvu2rgb_de3[] = {
> > > +       0x0002542a, 0x0003312a, 0x00000000, 0xffffffc0, 0x00000000,
> > > +       0x0002542a, 0xfffe5fc3, 0xffff376b, 0xfffffe00, 0x00000000,
> > > +       0x0002542a, 0x00000000, 0x000408d3, 0xfffffe00, 0x00000000,
> > > +};
> > > +
> > >
> > >  static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
> > >
> > >                                        enum sun8i_csc_mode mode)
> > >
> > >  {
> > >
> > > @@ -61,6 +89,38 @@ static void sun8i_csc_set_coefficients(struct regmap
> > > *map, u32 base,>
> > >         }
> > >
> > >  }
> > >
> > > +static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int
> > > layer,
> > > +                                           enum sun8i_csc_mode mode)
> > > +{
> > > +       const u32 *table;
> > > +       int i, j;
> > > +
> > > +       switch (mode) {
> > > +       case SUN8I_CSC_MODE_YUV2RGB:
> > > +               table = yuv2rgb_de3;
> > > +               break;
> > > +       case SUN8I_CSC_MODE_YVU2RGB:
> > > +               table = yvu2rgb_de3;
> > > +               break;
> > > +       default:
> > > +               DRM_WARN("Wrong CSC mode specified.\n");
> > > +               return;
> > > +       }
> > > +
> > > +       for (i = 0; i < 3; i++) {
> > > +               for (j = 0; j < 3; j++)
> > > +                       regmap_write(map,
> > > +
> > > SUN8I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, +
> > >                                  layer, i, j), +
> > >           table[i * 5 + j]);
> >
> > Given that the first three values occupy contiguous addresses,
> > you can use regmap_bulk_write() here.
>
> Do you mind if I rework table in a way that directly fits in registers and use
> regmap_bulk_write() on whole table? This means I must combine two values into
> one for "const" register, but I would explain it better in a comment. It would
> be most elegant solution, one call to regmap_bulk_write() instead of two for
> loops and some arithmetics.

With proper comments I see no problem with it. The constants are hexidecimal
and only loaded once. It's unlikely others would use it any other way.

> I guess macro for "const" part can stay as documentation.

I agree.

>
> >
> > > +               regmap_write(map,
> > > +                            SUN8I_MIXER_BLEND_CSC_CONST(DE3_BLD_BASE,
> > > +                                                        layer, i),
> > > +                            SUN8I_MIXER_BLEND_CSC_CONST_VAL(table[i * 5 +
> > > 3], +                                                            table[i
> > > * 5 + 4]));
> > Nit: Using a two-dimension array might make it easier to read.
> >
> > > +       }
> > > +}
> > > +
> > >
> > >  static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable)
> > >  {
> > >
> > >         u32 val;
> > >
> > > @@ -73,21 +133,45 @@ static void sun8i_csc_enable(struct regmap *map, u32
> > > base, bool enable)>
> > >         regmap_update_bits(map, SUN8I_CSC_CTRL(base), SUN8I_CSC_CTRL_EN,
> > >         val);
> > >
> > >  }
> > >
> > > +static void sun8i_de3_ccsc_enable(struct regmap *map, int layer, bool
> > > enable) +{
> > > +       u32 val, mask;
> > > +
> > > +       mask = SUN8I_MIXER_BLEND_CSC_CTL_EN(layer);
> > > +
> > > +       if (enable)
> > > +               val = mask;
> > > +       else
> > > +               val = 0;
> > > +
> > > +       regmap_update_bits(map, SUN8I_MIXER_BLEND_CSC_CTL(DE3_BLD_BASE),
> > > +                          mask, val);
> > > +}
> > > +
> > >
> > >  void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int
> > >  layer,
> > >
> > >                                      enum sun8i_csc_mode mode)
> > >
> > >  {
> > >
> > > -       u32 base;
> > > +       if (!mixer->cfg->is_de3) {
> > > +               u32 base;
> >
> > You could rewrite this as
> >
> >     if (mixer->cfg->is_de3) {
> >                sun8i_de3_ccsc_set_coefficients(mixer->engine.regs,
> >                                                layer, mode);
> >                return;
> >     }
> >
> > That way you don't need to change the indentation on the existing lines.
> > I suppose this is more of a personal preference. The downside is the control
> > flow is slightly more complicated.
> >
> > > -       base = ccsc_base[mixer->cfg->ccsc][layer];
> > > +               base = ccsc_base[mixer->cfg->ccsc][layer];
> > >
> > > -       sun8i_csc_set_coefficients(mixer->engine.regs, base, mode);
> > > +               sun8i_csc_set_coefficients(mixer->engine.regs, base,
> > > mode);
> > > +       } else {
> > > +               sun8i_de3_ccsc_set_coefficients(mixer->engine.regs,
> > > +                                               layer, mode);
> > > +       }
> > >
> > >  }
> > >
> > >  void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool
> > >  enable) {
> > >
> > > -       u32 base;
> > > +       if (!mixer->cfg->is_de3) {
> > > +               u32 base;
> > >
> > > -       base = ccsc_base[mixer->cfg->ccsc][layer];
> > > +               base = ccsc_base[mixer->cfg->ccsc][layer];
> > >
> > > -       sun8i_csc_enable(mixer->engine.regs, base, enable);
> > > +               sun8i_csc_enable(mixer->engine.regs, base, enable);
> > > +       } else {
> > > +               sun8i_de3_ccsc_enable(mixer->engine.regs, layer, enable);
> > > +       }
> > >
> > >  }
> > >
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 743941a33d88..a9218abf0935
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> > > @@ -460,8 +460,21 @@ static int sun8i_mixer_bind(struct device *dev,
> > > struct device *master,>
> > >         base = sun8i_blender_base(mixer);
> > >
> > >         /* Reset the registers */
> > >
> > > -       for (i = 0x0; i < 0x20000; i += 4)
> > > -               regmap_write(mixer->engine.regs, i, 0);
> > > +       if (mixer->cfg->is_de3) {
> > > +               for (i = 0x0; i < 0x3000; i += 4)
> > > +                       regmap_write(mixer->engine.regs, i, 0);
> > > +               for (i = 0x20000; i < 0x40000; i += 4)
> > > +                       regmap_write(mixer->engine.regs, i, 0);
> > > +               for (i = 0x70000; i < 0x88000; i += 4)
> > > +                       regmap_write(mixer->engine.regs, i, 0);
> > > +               for (i = 0xa0000; i < 0xb0000; i += 4)
> > > +                       regmap_write(mixer->engine.regs, i, 0);
> > > +               for (i = 0xd0000; i < 0xe0000; i += 4)
> > > +                       regmap_write(mixer->engine.regs, i, 0);
> >
> > Could you use the macros *_BASE and *_SIZE here? That would make
> > it more obviously what parts you're clearing.
> >
> > The last offset, 0xd0000, isn't even defined in the DE3 spec.
> >
> > > +       } else {
> > > +               for (i = 0x0; i < 0x20000; i += 4)
> > > +                       regmap_write(mixer->engine.regs, i, 0);
> > > +       }
> > >
> > >         /* Enable the mixer */
> > >         regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL,
> > >
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > > b/drivers/gpu/drm/sun4i/sun8i_mixer.h index 020b0a097c84..4c9a442bbb44
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> > > @@ -33,6 +33,10 @@
> > >
> > >  #define DE2_CH_BASE                            0x2000
> > >  #define DE2_CH_SIZE                            0x1000
> > >
> > > +#define DE3_BLD_BASE                           0x0800
> > > +#define DE3_CH_BASE                            0x1000
> > > +#define DE3_CH_SIZE                            0x0800
> > > +
> > >
> > >  #define SUN8I_MIXER_BLEND_PIPE_CTL(base)       ((base) + 0)
> > >  #define SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, x) ((base) + 0x4 + 0x10 *
> > >  (x))
> > >  #define SUN8I_MIXER_BLEND_ATTR_INSIZE(base, x) ((base) + 0x8 + 0x10 *
> > >  (x))
> > >
> > > @@ -47,6 +51,11 @@
> > >
> > >  #define SUN8I_MIXER_BLEND_CK_MAX(base, x)      ((base) + 0xc0 + 0x04 *
> > >  (x))
> > >  #define SUN8I_MIXER_BLEND_CK_MIN(base, x)      ((base) + 0xe0 + 0x04 *
> > >  (x))
> > >  #define SUN8I_MIXER_BLEND_OUTCTL(base)         ((base) + 0xfc)
> > >
> > > +#define SUN8I_MIXER_BLEND_CSC_CTL(base)                ((base) + 0x100)
> > > +#define SUN8I_MIXER_BLEND_CSC_COEFF(base, layer, x, y) \
> > > +       ((base) + 0x110 + (layer) * 0x30 +  (x) * 0x10 + 4 * (y))
> > > +#define SUN8I_MIXER_BLEND_CSC_CONST(base, layer, i) \
> > > +       ((base) + 0x110 + (layer) * 0x30 +  (i) * 0x10 + 0x0c)
> >
> > Should these have a DE3 prefix?
>
> How do you want this to look like?
>
> SUN50I_DE3_MIXER_BLEND_CSC_CONST?
>
> SUN8I prefix doesn't fit for DE3, but as usual, there is a chance that AW
> releases 32 bit SoC with DE3.
>
> At the end, it would be better to rename everything to have just DE2 or DE3
> prefix without mentioning any SoC family. After all, DE2 is also supported on
> sun50i family, which makes any family name in DE2/3 macros confusing...

Probably SUNXI_DEx_MIXER_foo or just DEx_MIXER_foo ...
Since it's contained in the driver I think the latter would suffice.

> Do you think I can squeeze dropping SUN8I prefix to a previous patch, where
> macros are reworked anyway?

Given there's a lot of them, and you're only changing about half of them
in that patch, I suggest you have a separate patch to do all the renaming.

ChenYu

> Best regards,
> Jernej
>
> >
> > >  #define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK      GENMASK(12, 8)
> > >  #define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe)    BIT(8 + pipe)
> > >
> > > @@ -61,6 +70,9 @@
> > >
> > >  #define SUN8I_MIXER_BLEND_OUTCTL_INTERLACED    BIT(1)
> > >
> > > +#define SUN8I_MIXER_BLEND_CSC_CTL_EN(ch)       BIT(ch)
> > > +#define SUN8I_MIXER_BLEND_CSC_CONST_VAL(d, c)  (((d) << 16) | ((c) &
> > > 0xffff)) +
> >
> > Same here.
> >
> > >  #define SUN8I_MIXER_FBFMT_ARGB8888     0
> > >  #define SUN8I_MIXER_FBFMT_ABGR8888     1
> > >  #define SUN8I_MIXER_FBFMT_RGBA8888     2
> >
> > [...]
> >
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> > > b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h index 46f0237c17bb..3d0ad64178ea
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
> > > @@ -30,6 +30,8 @@
> > >
> > >  #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE                BIT(15)
> > >  #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_OFFSET    8
> > >  #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK      GENMASK(12, 8)
> > >
> > > +#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK      GENMASK(31, 24)
> > > +#define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA(x)                ((x) <<
> > > 24)
> >
> > DE3 prefix?
> >
> > >  struct sun8i_mixer;
> > >
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > > b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c index
> > > 8697afc36023..22e1ed5cd7a4 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
> > > @@ -835,7 +835,10 @@ static const u32 bicubic4coefftab32[480] = {
> > >
> > >  static inline u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int
> > >  channel) {
> > >
> > > -       return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * channel;
> > > +       if (mixer->cfg->is_de3)
> > > +               return DE3_VI_SCALER_BASE + DE3_VI_SCALER_SIZE * channel;
> > > +       else
> > > +               return DE2_VI_SCALER_BASE + DE2_VI_SCALER_SIZE * channel;
> > >
> > >  }
> > >
> > >  static int sun8i_vi_scaler_coef_index(unsigned int step)
> > >
> > > @@ -951,6 +954,35 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer,
> > > int layer,>
> > >                 cvphase = vphase;
> > >
> > >         }
> > >
> > > +       if (mixer->cfg->is_de3) {
> > > +               u32 val;
> > > +
> > > +               if (format->hsub == 1 && format->vsub == 1)
> > > +                       val = SUN8I_SCALER_VSU_SCALE_MODE_UI;
> > > +               else
> > > +                       val = SUN8I_SCALER_VSU_SCALE_MODE_NORMAL;
> > > +
> > > +               regmap_write(mixer->engine.regs,
> > > +                            SUN8I_SCALER_VSU_SCALE_MODE(base), val);
> >
> > The remaining settings seem to be related to the edge detection scaling
> > method. Since you aren't supporting it, are they necessary?
> >
> > > +               regmap_write(mixer->engine.regs,
> > > +                            SUN8I_SCALER_VSU_DIR_THR(base),
> > > +                            SUN8I_SCALER_VSU_SUB_ZERO_DIR_THR(0) |
> > > +                            SUN8I_SCALER_VSU_ZERO_DIR_THR(0) |
> > > +                            SUN8I_SCALER_VSU_HORZ_DIR_THR(0xff) |
> > > +                            SUN8I_SCALER_VSU_VERT_DIR_THR(1));
> > > +               regmap_write(mixer->engine.regs,
> > > +                            SUN8I_SCALER_VSU_EDGE_THR(base),
> > > +                            SUN8I_SCALER_VSU_EDGE_SHIFT(8) |
> > > +                            SUN8I_SCALER_VSU_EDGE_OFFSET(0));
> > > +               regmap_write(mixer->engine.regs,
> > > +                            SUN8I_SCALER_VSU_EDSCL_CTRL(base), 0);
> > > +               regmap_write(mixer->engine.regs,
> > > +                            SUN8I_SCALER_VSU_ANGLE_THR(base),
> > > +                            SUN8I_SCALER_VSU_ANGLE_SHIFT(2) |
> > > +                            SUN8I_SCALER_VSU_ANGLE_OFFSET(0));
> > > +       }
> > > +
> > >
> > >         regmap_write(mixer->engine.regs,
> > >
> > >                      SUN8I_SCALER_VSU_OUTSIZE(base), outsize);
> > >
> > >         regmap_write(mixer->engine.regs,
> > >
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
> > > b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h index
> > > cd015405f66d..c322f5652481 100644
> > > --- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
> > > @@ -15,6 +15,9 @@
> > >
> > >  #define DE2_VI_SCALER_BASE 0x20000
> > >  #define DE2_VI_SCALER_SIZE 0x20000
> > >
> > > +#define DE3_VI_SCALER_BASE 0x20000
> > > +#define DE3_VI_SCALER_SIZE 0x08000
> > > +
> > >
> > >  /* this two macros assumes 16 fractional bits which is standard in DRM */
> > >  #define SUN8I_VI_SCALER_SCALE_MIN              1
> > >  #define SUN8I_VI_SCALER_SCALE_MAX              ((1UL << 20) - 1)
> > >
> > > @@ -25,6 +28,11 @@
> > >
> > >  #define SUN8I_VI_SCALER_SIZE(w, h)             (((h) - 1) << 16 | ((w) -
> > >  1))
> > >
> > >  #define SUN8I_SCALER_VSU_CTRL(base)            ((base) + 0x0)
> > >
> > > +#define SUN8I_SCALER_VSU_SCALE_MODE(base)      ((base) + 0x10)
> > > +#define SUN8I_SCALER_VSU_DIR_THR(base)         ((base) + 0x20)
> > > +#define SUN8I_SCALER_VSU_EDGE_THR(base)                ((base) + 0x24)
> > > +#define SUN8I_SCALER_VSU_EDSCL_CTRL(base)      ((base) + 0x28)
> > > +#define SUN8I_SCALER_VSU_ANGLE_THR(base)       ((base) + 0x2c)
> >
> > DE3 prefix for the new ones please.
> >
> > >  #define SUN8I_SCALER_VSU_OUTSIZE(base)         ((base) + 0x40)
> > >  #define SUN8I_SCALER_VSU_YINSIZE(base)         ((base) + 0x80)
> > >  #define SUN8I_SCALER_VSU_YHSTEP(base)          ((base) + 0x88)
> > >
> > > @@ -46,6 +54,21 @@
> > >
> > >  #define SUN8I_SCALER_VSU_CTRL_EN               BIT(0)
> > >  #define SUN8I_SCALER_VSU_CTRL_COEFF_RDY                BIT(4)
> > >
> > > +#define SUN8I_SCALER_VSU_SUB_ZERO_DIR_THR(x)   (((x) << 24) & 0xFF)
> > > +#define SUN8I_SCALER_VSU_ZERO_DIR_THR(x)       (((x) << 16) & 0xFF)
> > > +#define SUN8I_SCALER_VSU_HORZ_DIR_THR(x)       (((x) << 8) & 0xFF)
> > > +#define SUN8I_SCALER_VSU_VERT_DIR_THR(x)       ((x) & 0xFF)
> > > +
> > > +#define SUN8I_SCALER_VSU_SCALE_MODE_UI         0
> > > +#define SUN8I_SCALER_VSU_SCALE_MODE_NORMAL     1
> > > +#define SUN8I_SCALER_VSU_SCALE_MODE_ED_SCALE   2
> > > +
> > > +#define SUN8I_SCALER_VSU_EDGE_SHIFT(x)         (((x) << 16) & 0xF)
> > > +#define SUN8I_SCALER_VSU_EDGE_OFFSET(x)                ((x) & 0xFF)
> > > +
> > > +#define SUN8I_SCALER_VSU_ANGLE_SHIFT(x)                (((x) << 16) &
> > > 0xF)
> > > +#define SUN8I_SCALER_VSU_ANGLE_OFFSET(x)       ((x) & 0xFF)
> > > +
> >
> > Same here.
> >
> > Regards
> > ChenYu
> >
> > >  void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool
> > >  enable); void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int
> > >  layer,
> > >
> > >                            u32 src_w, u32 src_h, u32 dst_w, u32 dst_h,
> > >
> > > --
> > > 2.18.0
>
>
>
>
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply	[flat|nested] 66+ messages in thread

end of thread, other threads:[~2018-10-06 15:35 UTC | newest]

Thread overview: 66+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-02  7:26 [PATCH 00/27] Allwinner H6 DE3 and HDMI support Jernej Skrabec
2018-09-02  7:26 ` [PATCH 01/27] dt-bindings: sunxi-sram: add binding for Allwinner H6 SRAM C Jernej Skrabec
2018-09-04  8:39   ` Chen-Yu Tsai
2018-09-02  7:26 ` [PATCH 02/27] arm64: allwinner: h6: add system controller device tree node Jernej Skrabec
2018-09-04  8:40   ` Chen-Yu Tsai
2018-09-04  8:44     ` [linux-sunxi] " Icenowy Zheng
2018-09-12 14:49       ` Chen-Yu Tsai
2018-09-12 15:37         ` Icenowy Zheng
2018-09-02  7:26 ` [PATCH 03/27] dt-bindings: bus: add H6 DE3 bus binding Jernej Skrabec
2018-09-02  7:26 ` [PATCH 04/27] clk: sunxi-ng: Adjust MP clock parent rate when allowed Jernej Skrabec
2018-09-02  7:26 ` [PATCH 05/27] clk: sunxi-ng: Use u64 for calculation of NM rate Jernej Skrabec
2018-09-04  9:18   ` Chen-Yu Tsai
2018-09-04 18:06     ` Jernej Škrabec
2018-09-02  7:26 ` [PATCH 06/27] clk: sunxi-ng: h6: Set video PLLs limits Jernej Skrabec
2018-09-04 15:49   ` kbuild test robot
2018-09-04 15:49   ` kbuild test robot
2018-09-02  7:26 ` [PATCH 07/27] dt-bindings: clock: sun8i-de2: Add H6 DE3 clock description Jernej Skrabec
2018-09-04  8:59   ` Chen-Yu Tsai
2018-09-04  9:05     ` Chen-Yu Tsai
2018-09-02  7:26 ` [PATCH 08/27] clk: sunxi-ng: Add support for H6 DE3 clocks Jernej Skrabec
2018-09-04  9:04   ` Chen-Yu Tsai
2018-09-04 17:45     ` Jernej Škrabec
2018-09-12 12:20       ` Chen-Yu Tsai
2018-09-12 14:55         ` Jernej Škrabec
2018-09-12 16:16           ` [linux-sunxi] " Chen-Yu Tsai
2018-09-02  7:26 ` [PATCH 09/27] dt-bindings: display: sun4i-drm: Add H6 display engine compatibles Jernej Skrabec
     [not found]   ` <5b9f3f4d.1c69fb81.c776b.ee42@mx.google.com>
2018-09-22 13:32     ` Chen-Yu Tsai
2018-09-02  7:26 ` [PATCH 10/27] drm/sun4i: Add compatible for H6 display engine Jernej Skrabec
2018-09-03 12:18   ` Maxime Ripard
2018-09-02  7:26 ` [PATCH 11/27] drm/sun4i: Rework DE2 register defines Jernej Skrabec
2018-09-22 12:32   ` [linux-sunxi] " Chen-Yu Tsai
2018-09-23 20:02     ` Jernej Škrabec
2018-09-24  2:01       ` Chen-Yu Tsai
2018-09-02  7:26 ` [PATCH 12/27] drm/sun4i: Add basic support for DE3 Jernej Skrabec
2018-09-22 13:19   ` Chen-Yu Tsai
2018-09-23 19:51     ` Jernej Škrabec
2018-09-24  2:04       ` Chen-Yu Tsai
2018-10-05 17:51     ` Jernej Škrabec
2018-10-06 15:34       ` [linux-sunxi] " Chen-Yu Tsai
2018-09-02  7:26 ` [PATCH 13/27] drm/sun4i: Add support for H6 DE3 mixer 0 Jernej Skrabec
2018-09-22 13:23   ` Chen-Yu Tsai
2018-09-22 13:47     ` Chen-Yu Tsai
2018-09-23 19:40       ` [linux-sunxi] " Jernej Škrabec
2018-09-24  1:59         ` Chen-Yu Tsai
2018-09-02  7:26 ` [PATCH 14/27] drm/bridge/synopsys: dw-hdmi: Enable workaround for v2.12a Jernej Skrabec
2018-09-22 13:54   ` Chen-Yu Tsai
2018-09-02  7:26 ` [PATCH 15/27] drm/sun4i: Not all DW HDMI controllers has scrambled addresses Jernej Skrabec
2018-09-12 12:25   ` Chen-Yu Tsai
2018-09-02  7:26 ` [PATCH 16/27] drm/sun4i: dw-hdmi: Make mode_valid function configurable Jernej Skrabec
2018-09-22 13:29   ` Chen-Yu Tsai
2018-09-02  7:26 ` [PATCH 17/27] drm/sun4i: dw-hdmi: Add quirk for setting TMDS clock Jernej Skrabec
2018-09-22 13:30   ` Chen-Yu Tsai
2018-09-02  7:26 ` [PATCH 18/27] dt-bindings: display: sunxi: add DT binding for Allwinner H6 DW HDMI Jernej Skrabec
2018-09-02  7:26 ` [PATCH 19/27] drm/sun4i: Add support for H6 DW HDMI controller Jernej Skrabec
2018-09-12 12:29   ` Chen-Yu Tsai
2018-09-02  7:26 ` [PATCH 20/27] drm/sun4i: Add support for Synopsys HDMI PHY Jernej Skrabec
2018-09-02  7:26 ` [PATCH 21/27] drm/sun4i: Add support for H6 " Jernej Skrabec
2018-09-22 15:55   ` Chen-Yu Tsai
2018-09-23 19:29     ` Jernej Škrabec
2018-09-02  7:26 ` [PATCH 22/27] drm/sun4i: Initialize registers in tcon-top driver Jernej Skrabec
2018-09-02  7:26 ` [PATCH 23/27] drm: sun4i: add quirks for TCON TOP Jernej Skrabec
2018-09-02  7:26 ` [PATCH 24/27] dt-bindings: display: sun4i-drm: document H6 " Jernej Skrabec
2018-09-02  7:26 ` [PATCH 25/27] drm: sun4i: add support for " Jernej Skrabec
2018-09-02  7:26 ` [PATCH 26/27] arm64: dts: sun50i: h6: Add HDMI pipeline Jernej Skrabec
2018-09-02  7:26 ` [PATCH 27/27] arm64: dts: sun50i: h6: Enable HDMI output on Pine H64 board Jernej Skrabec
2018-09-02  9:31 ` [PATCH 00/27] Allwinner H6 DE3 and HDMI support Chen-Yu Tsai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).