linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/24] Add support for R40 HDMI pipeline
@ 2018-06-25 12:02 Jernej Skrabec
  2018-06-25 12:02 ` [PATCH v3 01/24] clk: sunxi-ng: r40: Add minimal rate for video PLLs Jernej Skrabec
                   ` (26 more replies)
  0 siblings, 27 replies; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

This series adds support for R40 HDMI pipeline. It is a bit special
than other already supported pipelines because it has additional unit
called TCON TOP responsible for relationship configuration between
mixers, TCONs and HDMI. Additionally, it has additional gates for DSI
and TV TCONs, TV encoder clock settings and pin muxing between LCD
and TV encoders.

However, it seems that TCON TOP will become a norm, since newer
Allwinner SoCs like H6 also have this unit.

I tested different possible configurations:
- mixer0 <> TCON-TV0 <> HDMI
- mixer0 <> TCON-TV1 <> HDMI
- mixer1 <> TCON-TV0 <> HDMI
- mixer1 <> TCON-TV1 <> HDMI

Please review.

Best regards,
Jernej

Changes from v2:
- Collected tags
- Exported drm_crtc_port_mask() symbol
- Removed TCON TOP reset name
- TCON TOP gates have now right parents
- updated TCON TOP bindings
- dropped new TCON quirk due TCON TOP rework

Changes from v1:
- Split DT bindings patch and updated description
- Split HDMI PHY patch
- Move header file from TCON TOP patch to dt bindings patch
- Added Rob reviewed-by tag
- Used clk_hw_register_gate() instead of custom gate registration code
- Reworked TCON TOP to be part of of-graph. Because of that, a lot of
  new patches were added.
- Droped mixer index quirk patch
- Reworked TCON support for TCON TOP
- Updated commit messages

Jernej Skrabec (24):
  clk: sunxi-ng: r40: Add minimal rate for video PLLs
  clk: sunxi-ng: r40: Allow setting parent rate to display related
    clocks
  clk: sunxi-ng: r40: Export video PLLs
  dt-bindings: display: sunxi-drm: Add TCON TOP description
  drm/sun4i: Add TCON TOP driver
  drm/sun4i: Fix releasing node when enumerating enpoints
  drm/sun4i: Split out code for enumerating endpoints in output port
  drm/sun4i: Add support for traversing graph with TCON TOP
  drm/sun4i: Don't skip TCONs if they don't have channel 0
  drm/sun4i: tcon: Generalize engine search algorithm
  drm/sun4i: Don't check for LVDS and RGB when TCON has only ch1
  drm/sun4i: Don't check for panel or bridge on TV TCONs
  dt-bindings: display: sun4i-drm: Add R40 mixer compatibles
  drm/sun4i: Add support for R40 mixers
  dt-bindings: display: sun4i-drm: Add description of A64 HDMI PHY
  drm/sun4i: Enable DW HDMI PHY clock
  drm/sun4i: Don't change clock bits in DW HDMI PHY driver
  drm/sun4i: DW HDMI PHY: Add support for second PLL
  drm/sun4i: Add support for second clock parent to DW HDMI PHY clk
    driver
  drm/sun4i: Add support for A64 HDMI PHY
  drm: of: Export drm_crtc_port_mask()
  drm/sun4i: DW HDMI: Expand algorithm for possible crtcs
  ARM: dts: sun8i: r40: Add HDMI pipeline
  ARM: dts: sun8i: r40: Enable HDMI output on BananaPi M2 Ultra

 .../bindings/display/sunxi/sun4i-drm.txt      |  62 +++-
 .../boot/dts/sun8i-r40-bananapi-m2-ultra.dts  |  45 +++
 arch/arm/boot/dts/sun8i-r40.dtsi              | 269 ++++++++++++++++
 drivers/clk/sunxi-ng/ccu-sun8i-r40.c          |  58 ++--
 drivers/clk/sunxi-ng/ccu-sun8i-r40.h          |   8 +-
 drivers/gpu/drm/drm_of.c                      |   5 +-
 drivers/gpu/drm/sun4i/Makefile                |   3 +-
 drivers/gpu/drm/sun4i/sun4i_drv.c             | 121 +++++--
 drivers/gpu/drm/sun4i/sun4i_tcon.c            |  66 ++--
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c         |  46 ++-
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h         |   8 +-
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c        |  54 +++-
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c    |  90 ++++--
 drivers/gpu/drm/sun4i/sun8i_mixer.c           |  24 ++
 drivers/gpu/drm/sun4i/sun8i_tcon_top.c        | 300 ++++++++++++++++++
 drivers/gpu/drm/sun4i/sun8i_tcon_top.h        |  40 +++
 include/drm/drm_of.h                          |   8 +
 include/dt-bindings/clock/sun8i-r40-ccu.h     |   4 +
 include/dt-bindings/clock/sun8i-tcon-top.h    |  11 +
 19 files changed, 1100 insertions(+), 122 deletions(-)
 create mode 100644 drivers/gpu/drm/sun4i/sun8i_tcon_top.c
 create mode 100644 drivers/gpu/drm/sun4i/sun8i_tcon_top.h
 create mode 100644 include/dt-bindings/clock/sun8i-tcon-top.h

-- 
2.18.0


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

* [PATCH v3 01/24] clk: sunxi-ng: r40: Add minimal rate for video PLLs
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-25 12:02 ` [PATCH v3 02/24] clk: sunxi-ng: r40: Allow setting parent rate to display related clocks Jernej Skrabec
                   ` (25 subsequent siblings)
  26 siblings, 0 replies; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

According to documentation and experience with other similar SoCs, video
PLLs don't work stable if their output frequency is set below 192 MHz.

Because of that, set minimal rate to both R40 video PLLs to 192 MHz.

Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/clk/sunxi-ng/ccu-sun8i-r40.c | 46 +++++++++++++++-------------
 1 file changed, 24 insertions(+), 22 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
index 933f2e68f42a..c16a62a7bdbd 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
@@ -65,17 +65,18 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
 				   CLK_SET_RATE_UNGATE);
 
 /* TODO: The result of N/M is required to be in [8, 25] range. */
-static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0",
-					"osc24M", 0x0010,
-					8, 7,		/* N */
-					0, 4,		/* M */
-					BIT(24),	/* frac enable */
-					BIT(25),	/* frac select */
-					270000000,	/* frac rate 0 */
-					297000000,	/* frac rate 1 */
-					BIT(31),	/* gate */
-					BIT(28),	/* lock */
-					CLK_SET_RATE_UNGATE);
+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video0_clk, "pll-video0",
+					    "osc24M", 0x0010,
+					    192000000,	/* Minimum rate */
+					    8, 7,	/* N */
+					    0, 4,	/* M */
+					    BIT(24),	/* frac enable */
+					    BIT(25),	/* frac select */
+					    270000000,	/* frac rate 0 */
+					    297000000,	/* frac rate 1 */
+					    BIT(31),	/* gate */
+					    BIT(28),	/* lock */
+					    CLK_SET_RATE_UNGATE);
 
 /* TODO: The result of N/M is required to be in [8, 25] range. */
 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
@@ -151,17 +152,18 @@ static struct ccu_nk pll_periph1_clk = {
 };
 
 /* TODO: The result of N/M is required to be in [8, 25] range. */
-static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1",
-					"osc24M", 0x030,
-					8, 7,		/* N */
-					0, 4,		/* M */
-					BIT(24),	/* frac enable */
-					BIT(25),	/* frac select */
-					270000000,	/* frac rate 0 */
-					297000000,	/* frac rate 1 */
-					BIT(31),	/* gate */
-					BIT(28),	/* lock */
-					CLK_SET_RATE_UNGATE);
+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video1_clk, "pll-video1",
+					    "osc24M", 0x030,
+					    192000000,	/* Minimum rate */
+					    8, 7,	/* N */
+					    0, 4,	/* M */
+					    BIT(24),	/* frac enable */
+					    BIT(25),	/* frac select */
+					    270000000,	/* frac rate 0 */
+					    297000000,	/* frac rate 1 */
+					    BIT(31),	/* gate */
+					    BIT(28),	/* lock */
+					    CLK_SET_RATE_UNGATE);
 
 static struct ccu_nkm pll_sata_clk = {
 	.enable		= BIT(31),
-- 
2.18.0


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

* [PATCH v3 02/24] clk: sunxi-ng: r40: Allow setting parent rate to display related clocks
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
  2018-06-25 12:02 ` [PATCH v3 01/24] clk: sunxi-ng: r40: Add minimal rate for video PLLs Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-25 12:02 ` [PATCH v3 03/24] clk: sunxi-ng: r40: Export video PLLs Jernej Skrabec
                   ` (24 subsequent siblings)
  26 siblings, 0 replies; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Display related peripherals need precise clocks to operate correctly.

Allow DE2, TCONs and HDMI to set parent clock.

Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/clk/sunxi-ng/ccu-sun8i-r40.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
index c16a62a7bdbd..fa5317719684 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
@@ -655,7 +655,8 @@ static SUNXI_CCU_GATE(dram_deinterlace_clk,	"dram-deinterlace",	"dram",
 
 static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" };
 static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
-				 0x104, 0, 4, 24, 3, BIT(31), 0);
+				 0x104, 0, 4, 24, 3, BIT(31),
+				 CLK_SET_RATE_PARENT);
 static SUNXI_CCU_M_WITH_MUX_GATE(mp_clk, "mp", de_parents,
 				 0x108, 0, 4, 24, 3, BIT(31), 0);
 
@@ -667,9 +668,11 @@ static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd0_clk, "tcon-lcd0", tcon_parents,
 static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd1_clk, "tcon-lcd1", tcon_parents,
 			       0x114, 24, 3, BIT(31), CLK_SET_RATE_PARENT);
 static SUNXI_CCU_M_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0", tcon_parents,
-				 0x118, 0, 4, 24, 3, BIT(31), 0);
+				 0x118, 0, 4, 24, 3, BIT(31),
+				 CLK_SET_RATE_PARENT);
 static SUNXI_CCU_M_WITH_MUX_GATE(tcon_tv1_clk, "tcon-tv1", tcon_parents,
-				 0x11c, 0, 4, 24, 3, BIT(31), 0);
+				 0x11c, 0, 4, 24, 3, BIT(31),
+				 CLK_SET_RATE_PARENT);
 
 static const char * const deinterlace_parents[] = { "pll-periph0",
 						    "pll-periph1" };
@@ -699,7 +702,8 @@ static SUNXI_CCU_GATE(avs_clk,		"avs",		"osc24M",
 
 static const char * const hdmi_parents[] = { "pll-video0", "pll-video1" };
 static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents,
-				 0x150, 0, 4, 24, 2, BIT(31), 0);
+				 0x150, 0, 4, 24, 2, BIT(31),
+				 CLK_SET_RATE_PARENT);
 
 static SUNXI_CCU_GATE(hdmi_slow_clk,	"hdmi-slow",	"osc24M",
 		      0x154, BIT(31), 0);
-- 
2.18.0


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

* [PATCH v3 03/24] clk: sunxi-ng: r40: Export video PLLs
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
  2018-06-25 12:02 ` [PATCH v3 01/24] clk: sunxi-ng: r40: Add minimal rate for video PLLs Jernej Skrabec
  2018-06-25 12:02 ` [PATCH v3 02/24] clk: sunxi-ng: r40: Allow setting parent rate to display related clocks Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-25 12:30   ` Chen-Yu Tsai
  2018-06-25 12:02 ` [PATCH v3 04/24] dt-bindings: display: sunxi-drm: Add TCON TOP description Jernej Skrabec
                   ` (23 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Video PLLs need to be referenced in R40 DT as possible HDMI PHY parent.

Export them.

Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/clk/sunxi-ng/ccu-sun8i-r40.h      | 8 ++++++--
 include/dt-bindings/clock/sun8i-r40-ccu.h | 4 ++++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.h b/drivers/clk/sunxi-ng/ccu-sun8i-r40.h
index 0db8e1e97af8..db2a1243f9ff 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.h
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.h
@@ -25,7 +25,9 @@
 #define CLK_PLL_AUDIO_2X	4
 #define CLK_PLL_AUDIO_4X	5
 #define CLK_PLL_AUDIO_8X	6
-#define CLK_PLL_VIDEO0		7
+
+/* PLL_VIDEO0 is exported */
+
 #define CLK_PLL_VIDEO0_2X	8
 #define CLK_PLL_VE		9
 #define CLK_PLL_DDR0		10
@@ -34,7 +36,9 @@
 #define CLK_PLL_PERIPH0_2X	13
 #define CLK_PLL_PERIPH1		14
 #define CLK_PLL_PERIPH1_2X	15
-#define CLK_PLL_VIDEO1		16
+
+/* PLL_VIDEO1 is exported */
+
 #define CLK_PLL_VIDEO1_2X	17
 #define CLK_PLL_SATA		18
 #define CLK_PLL_SATA_OUT	19
diff --git a/include/dt-bindings/clock/sun8i-r40-ccu.h b/include/dt-bindings/clock/sun8i-r40-ccu.h
index 4fa5f69fc297..f9e15a235626 100644
--- a/include/dt-bindings/clock/sun8i-r40-ccu.h
+++ b/include/dt-bindings/clock/sun8i-r40-ccu.h
@@ -43,6 +43,10 @@
 #ifndef _DT_BINDINGS_CLK_SUN8I_R40_H_
 #define _DT_BINDINGS_CLK_SUN8I_R40_H_
 
+#define CLK_PLL_VIDEO0		7
+
+#define CLK_PLL_VIDEO1		16
+
 #define CLK_CPU			24
 
 #define CLK_BUS_MIPI_DSI	29
-- 
2.18.0


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

* [PATCH v3 04/24] dt-bindings: display: sunxi-drm: Add TCON TOP description
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (2 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 03/24] clk: sunxi-ng: r40: Export video PLLs Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-25 17:33   ` Rob Herring
  2018-06-25 12:02 ` [PATCH v3 05/24] drm/sun4i: Add TCON TOP driver Jernej Skrabec
                   ` (22 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

TCON TOP main purpose is to configure whole display pipeline. It
determines relationships between mixers and TCONs, selects source TCON
for HDMI, muxes LCD and TV encoder GPIO output, selects TV encoder
clock source and contains additional TV TCON and DSI gates.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 .../bindings/display/sunxi/sun4i-drm.txt      | 56 +++++++++++++++++++
 include/dt-bindings/clock/sun8i-tcon-top.h    | 11 ++++
 2 files changed, 67 insertions(+)
 create mode 100644 include/dt-bindings/clock/sun8i-tcon-top.h

diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index 3346c1e2a7a0..fe31b1510717 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -187,6 +187,62 @@ And on the A23, A31, A31s and A33, you need one more clock line:
    - 'lvds-alt': An alternative clock source, separate from the TCON channel 0
                  clock, that can be used to drive the LVDS clock
 
+TCON TOP
+--------
+
+TCON TOPs main purpose is to configure whole display pipeline. It determines
+relationships between mixers and TCONs, selects source TCON for HDMI, muxes
+LCD and TV encoder GPIO output, selects TV encoder clock source and contains
+additional TV TCON and DSI gates.
+
+It allows display pipeline to be configured in very different ways:
+
+                                / LCD0/LVDS0
+                 / [0] TCON-LCD0
+                 |              \ MIPI DSI
+ mixer0          |
+        \        / [1] TCON-LCD1 - LCD1/LVDS1
+         TCON-TOP
+        /        \ [2] TCON-TV0 [0] - TVE0/RGB
+ mixer1          |                  \
+                 |                   TCON-TOP - HDMI
+                 |                  /
+                 \ [3] TCON-TV1 [1] - TVE1/RGB
+
+Note that both TCON TOP references same physical unit. Both mixers can be
+connected to any TCON.
+
+Required properties:
+  - compatible: value must be one of:
+    * allwinner,sun8i-r40-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
+  - 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.
+
+- ports: A ports node with endpoint definitions as defined in
+    Documentation/devicetree/bindings/media/video-interfaces.txt. 6 ports should
+    be defined:
+    * port 0 is input for mixer0 mux
+    * port 1 is output for mixer0 mux
+    * port 2 is input for mixer1 mux
+    * port 3 is output for mixer1 mux
+    * port 4 is input for HDMI mux
+    * port 5 is output for HDMI mux
+    All output endpoints for mixer muxes and input endpoints for HDMI mux should
+    have reg property with the id of the target TCON, as shown in above graph
+    (0-3 for mixer muxes and 0-1 for HDMI mux). All ports should have only one
+    endpoint connected to remote endpoint.
+
 DRC
 ---
 
diff --git a/include/dt-bindings/clock/sun8i-tcon-top.h b/include/dt-bindings/clock/sun8i-tcon-top.h
new file mode 100644
index 000000000000..25164d767835
--- /dev/null
+++ b/include/dt-bindings/clock/sun8i-tcon-top.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/* Copyright (C) 2018 Jernej Skrabec <jernej.skrabec@siol.net> */
+
+#ifndef _DT_BINDINGS_CLOCK_SUN8I_TCON_TOP_H_
+#define _DT_BINDINGS_CLOCK_SUN8I_TCON_TOP_H_
+
+#define CLK_TCON_TOP_TV0	0
+#define CLK_TCON_TOP_TV1	1
+#define CLK_TCON_TOP_DSI	2
+
+#endif /* _DT_BINDINGS_CLOCK_SUN8I_TCON_TOP_H_ */
-- 
2.18.0


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

* [PATCH v3 05/24] drm/sun4i: Add TCON TOP driver
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (3 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 04/24] dt-bindings: display: sunxi-drm: Add TCON TOP description Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-28  1:47   ` Chen-Yu Tsai
  2018-06-25 12:02 ` [PATCH v3 06/24] drm/sun4i: Fix releasing node when enumerating enpoints Jernej Skrabec
                   ` (21 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

As already described in DT binding, TCON TOP is responsible for
configuring display pipeline. In this initial driver focus is on HDMI
pipeline, so TVE and LCD configuration is not implemented.

Implemented features:
- HDMI source selection
- clock driver (TCON and DSI gating)
- connecting mixers and TCONS

Something similar also existed in previous SoCs, except that it was part
of first TCON.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/Makefile         |   3 +-
 drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 300 +++++++++++++++++++++++++
 drivers/gpu/drm/sun4i/sun8i_tcon_top.h |  40 ++++
 3 files changed, 342 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/sun4i/sun8i_tcon_top.c
 create mode 100644 drivers/gpu/drm/sun4i/sun8i_tcon_top.h

diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile
index 2589f4acd5ae..09fbfd6304ba 100644
--- a/drivers/gpu/drm/sun4i/Makefile
+++ b/drivers/gpu/drm/sun4i/Makefile
@@ -16,7 +16,8 @@ sun8i-drm-hdmi-y		+= sun8i_hdmi_phy_clk.o
 
 sun8i-mixer-y			+= sun8i_mixer.o sun8i_ui_layer.o \
 				   sun8i_vi_layer.o sun8i_ui_scaler.o \
-				   sun8i_vi_scaler.o sun8i_csc.o
+				   sun8i_vi_scaler.o sun8i_csc.o \
+				   sun8i_tcon_top.o
 
 sun4i-tcon-y			+= sun4i_crtc.o
 sun4i-tcon-y			+= sun4i_dotclock.o
diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
new file mode 100644
index 000000000000..8da0460e0028
--- /dev/null
+++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright (c) 2018 Jernej Skrabec <jernej.skrabec@siol.net> */
+
+#include <drm/drmP.h>
+
+#include <dt-bindings/clock/sun8i-tcon-top.h>
+
+#include <linux/bitfield.h>
+#include <linux/component.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+
+#include "sun8i_tcon_top.h"
+
+static int sun8i_tcon_top_get_connected_ep_id(struct device_node *node,
+					      int port_id)
+{
+	struct device_node *ep, *remote, *port;
+	struct of_endpoint endpoint;
+
+	port = of_graph_get_port_by_id(node, port_id);
+	if (!port)
+		return -ENOENT;
+
+	for_each_available_child_of_node(port, ep) {
+		remote = of_graph_get_remote_port_parent(ep);
+		if (!remote)
+			continue;
+
+		if (of_device_is_available(remote)) {
+			of_graph_parse_endpoint(ep, &endpoint);
+
+			of_node_put(remote);
+
+			return endpoint.id;
+		}
+
+		of_node_put(remote);
+	}
+
+	return -ENOENT;
+}
+
+static struct clk_hw *sun8i_tcon_top_register_gate(struct device *dev,
+						   struct clk *parent,
+						   void __iomem *regs,
+						   spinlock_t *lock,
+						   u8 bit, int name_index)
+{
+	const char *clk_name, *parent_name;
+	int ret;
+
+	parent_name = __clk_get_name(parent);
+	ret = of_property_read_string_index(dev->of_node,
+					    "clock-output-names", name_index,
+					    &clk_name);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return clk_hw_register_gate(dev, clk_name, parent_name,
+				    CLK_SET_RATE_PARENT,
+				    regs + TCON_TOP_GATE_SRC_REG,
+				    bit, 0, lock);
+};
+
+static int sun8i_tcon_top_bind(struct device *dev, struct device *master,
+			       void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct clk *dsi, *tcon_tv0, *tcon_tv1, *tve0, *tve1;
+	struct clk_hw_onecell_data *clk_data;
+	struct sun8i_tcon_top *tcon_top;
+	bool mixer0_unused = false;
+	struct resource *res;
+	void __iomem *regs;
+	int ret, i, id;
+	u32 val;
+
+	tcon_top = devm_kzalloc(dev, sizeof(*tcon_top), GFP_KERNEL);
+	if (!tcon_top)
+		return -ENOMEM;
+
+	clk_data = devm_kzalloc(dev, sizeof(*clk_data) +
+				sizeof(*clk_data->hws) * CLK_NUM,
+				GFP_KERNEL);
+	if (!clk_data)
+		return -ENOMEM;
+	tcon_top->clk_data = clk_data;
+
+	spin_lock_init(&tcon_top->reg_lock);
+
+	tcon_top->rst = devm_reset_control_get(dev, NULL);
+	if (IS_ERR(tcon_top->rst)) {
+		dev_err(dev, "Couldn't get our reset line\n");
+		return PTR_ERR(tcon_top->rst);
+	}
+
+	tcon_top->bus = devm_clk_get(dev, "bus");
+	if (IS_ERR(tcon_top->bus)) {
+		dev_err(dev, "Couldn't get the bus clock\n");
+		return PTR_ERR(tcon_top->bus);
+	}
+
+	dsi = devm_clk_get(dev, "dsi");
+	if (IS_ERR(dsi)) {
+		dev_err(dev, "Couldn't get the dsi clock\n");
+		return PTR_ERR(dsi);
+	}
+
+	tcon_tv0 = devm_clk_get(dev, "tcon-tv0");
+	if (IS_ERR(tcon_tv0)) {
+		dev_err(dev, "Couldn't get the tcon-tv0 clock\n");
+		return PTR_ERR(tcon_tv0);
+	}
+
+	tcon_tv1 = devm_clk_get(dev, "tcon-tv1");
+	if (IS_ERR(tcon_tv1)) {
+		dev_err(dev, "Couldn't get the tcon-tv1 clock\n");
+		return PTR_ERR(tcon_tv1);
+	}
+
+	tve0 = devm_clk_get(dev, "tve0");
+	if (IS_ERR(tve0)) {
+		dev_err(dev, "Couldn't get the tve0 clock\n");
+		return PTR_ERR(tve0);
+	}
+
+	tve1 = devm_clk_get(dev, "tve1");
+	if (IS_ERR(tve1)) {
+		dev_err(dev, "Couldn't get the tve1 clock\n");
+		return PTR_ERR(tve1);
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	ret = reset_control_deassert(tcon_top->rst);
+	if (ret) {
+		dev_err(dev, "Could not deassert ctrl reset control\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(tcon_top->bus);
+	if (ret) {
+		dev_err(dev, "Could not enable bus clock\n");
+		goto err_assert_reset;
+	}
+
+	val = 0;
+
+	/* check if HDMI mux output is connected */
+	if (sun8i_tcon_top_get_connected_ep_id(dev->of_node, 5) >= 0) {
+		/* find HDMI input endpoint id, if it is connected at all*/
+		id = sun8i_tcon_top_get_connected_ep_id(dev->of_node, 4);
+		if (id >= 0)
+			val = FIELD_PREP(TCON_TOP_HDMI_SRC_MSK, id + 1);
+		else
+			DRM_DEBUG_DRIVER("TCON TOP HDMI input is not connected\n");
+	} else {
+		DRM_DEBUG_DRIVER("TCON TOP HDMI output is not connected\n");
+	}
+
+	writel(val, regs + TCON_TOP_GATE_SRC_REG);
+
+	val = 0;
+
+	/* process mixer0 mux output */
+	id = sun8i_tcon_top_get_connected_ep_id(dev->of_node, 1);
+	if (id >= 0) {
+		val = FIELD_PREP(TCON_TOP_PORT_DE0_MSK, id);
+	} else {
+		DRM_DEBUG_DRIVER("TCON TOP mixer0 output is not connected\n");
+		mixer0_unused = true;
+	}
+
+	/* process mixer1 mux output */
+	id = sun8i_tcon_top_get_connected_ep_id(dev->of_node, 3);
+	if (id >= 0) {
+		val |= FIELD_PREP(TCON_TOP_PORT_DE1_MSK, id);
+
+		/*
+		 * mixer0 mux has priority over mixer1 mux. We have to
+		 * make sure mixer0 doesn't overtake TCON from mixer1.
+		 */
+		if (mixer0_unused && id == 0)
+			val |= FIELD_PREP(TCON_TOP_PORT_DE0_MSK, 1);
+	} else {
+		DRM_DEBUG_DRIVER("TCON TOP mixer1 output is not connected\n");
+	}
+
+	writel(val, regs + TCON_TOP_PORT_SEL_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
+	 * we leave this fixed to TCON TV, since TVE driver for R40 is not yet
+	 * implemented. Once it is, graph needs to be traversed to determine
+	 * if TVE is active on each TCON TV. If it is, mux should be switched
+	 * to TVE clock parent.
+	 */
+	clk_data->hws[CLK_TCON_TOP_TV0] =
+		sun8i_tcon_top_register_gate(dev, tcon_tv0, regs,
+					     &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);
+
+	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);
+
+	for (i = 0; i < CLK_NUM; i++)
+		if (IS_ERR(clk_data->hws[i])) {
+			ret = PTR_ERR(clk_data->hws[i]);
+			goto err_unregister_gates;
+		}
+
+	clk_data->num = CLK_NUM;
+
+	ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
+				     clk_data);
+	if (ret)
+		goto err_unregister_gates;
+
+	dev_set_drvdata(dev, tcon_top);
+
+	return 0;
+
+err_unregister_gates:
+	for (i = 0; i < CLK_NUM; i++)
+		if (clk_data->hws[i])
+			clk_hw_unregister_gate(clk_data->hws[i]);
+	clk_disable_unprepare(tcon_top->bus);
+err_assert_reset:
+	reset_control_assert(tcon_top->rst);
+
+	return ret;
+}
+
+static void sun8i_tcon_top_unbind(struct device *dev, struct device *master,
+				  void *data)
+{
+	struct sun8i_tcon_top *tcon_top = dev_get_drvdata(dev);
+	struct clk_hw_onecell_data *clk_data = tcon_top->clk_data;
+	int i;
+
+	of_clk_del_provider(dev->of_node);
+	for (i = 0; i < CLK_NUM; i++)
+		clk_hw_unregister_gate(clk_data->hws[i]);
+
+	clk_disable_unprepare(tcon_top->bus);
+	reset_control_assert(tcon_top->rst);
+}
+
+static const struct component_ops sun8i_tcon_top_ops = {
+	.bind	= sun8i_tcon_top_bind,
+	.unbind	= sun8i_tcon_top_unbind,
+};
+
+static int sun8i_tcon_top_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &sun8i_tcon_top_ops);
+}
+
+static int sun8i_tcon_top_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &sun8i_tcon_top_ops);
+
+	return 0;
+}
+
+/* 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" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sun8i_tcon_top_of_table);
+EXPORT_SYMBOL(sun8i_tcon_top_of_table);
+
+static struct platform_driver sun8i_tcon_top_platform_driver = {
+	.probe		= sun8i_tcon_top_probe,
+	.remove		= sun8i_tcon_top_remove,
+	.driver		= {
+		.name		= "sun8i-tcon-top",
+		.of_match_table	= sun8i_tcon_top_of_table,
+	},
+};
+module_platform_driver(sun8i_tcon_top_platform_driver);
+
+MODULE_AUTHOR("Jernej Skrabec <jernej.skrabec@siol.net>");
+MODULE_DESCRIPTION("Allwinner R40 TCON TOP driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.h b/drivers/gpu/drm/sun4i/sun8i_tcon_top.h
new file mode 100644
index 000000000000..39838bbfeaee
--- /dev/null
+++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* Copyright (c) 2018 Jernej Skrabec <jernej.skrabec@siol.net> */
+
+#ifndef _SUN8I_TCON_TOP_H_
+#define _SUN8I_TCON_TOP_H_
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/reset.h>
+#include <linux/spinlock.h>
+
+#define TCON_TOP_TCON_TV_SETUP_REG	0x00
+
+#define TCON_TOP_PORT_SEL_REG		0x1C
+#define TCON_TOP_PORT_DE0_MSK			GENMASK(1, 0)
+#define TCON_TOP_PORT_DE1_MSK			GENMASK(5, 4)
+
+#define TCON_TOP_GATE_SRC_REG		0x20
+#define TCON_TOP_HDMI_SRC_MSK			GENMASK(29, 28)
+#define TCON_TOP_TCON_TV1_GATE			24
+#define TCON_TOP_TCON_TV0_GATE			20
+#define TCON_TOP_TCON_DSI_GATE			16
+
+#define CLK_NUM					3
+
+struct sun8i_tcon_top {
+	struct clk			*bus;
+	struct clk_hw_onecell_data	*clk_data;
+	struct reset_control		*rst;
+
+	/*
+	 * spinlock is used to synchronize access to same
+	 * register where multiple clock gates can be set.
+	 */
+	spinlock_t			reg_lock;
+};
+
+extern const struct of_device_id sun8i_tcon_top_of_table[];
+
+#endif /* _SUN8I_TCON_TOP_H_ */
-- 
2.18.0


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

* [PATCH v3 06/24] drm/sun4i: Fix releasing node when enumerating enpoints
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (4 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 05/24] drm/sun4i: Add TCON TOP driver Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-28  1:53   ` [linux-sunxi] " Chen-Yu Tsai
  2018-06-25 12:02 ` [PATCH v3 07/24] drm/sun4i: Split out code for enumerating endpoints in output port Jernej Skrabec
                   ` (20 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

sun4i_drv_add_endpoints() has a memory leak since it uses of_node_put()
when remote is equal to NULL and does nothing when remote has a valid
pointer.

Invert the logic to fix memory leak.

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

diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index 50d19605c38f..e15fa2389e3f 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -283,7 +283,6 @@ static int sun4i_drv_add_endpoints(struct device *dev,
 		remote = of_graph_get_remote_port_parent(ep);
 		if (!remote) {
 			DRM_DEBUG_DRIVER("Error retrieving the output node\n");
-			of_node_put(remote);
 			continue;
 		}
 
@@ -297,11 +296,13 @@ static int sun4i_drv_add_endpoints(struct device *dev,
 
 			if (of_graph_parse_endpoint(ep, &endpoint)) {
 				DRM_DEBUG_DRIVER("Couldn't parse endpoint\n");
+				of_node_put(remote);
 				continue;
 			}
 
 			if (!endpoint.id) {
 				DRM_DEBUG_DRIVER("Endpoint is our panel... skipping\n");
+				of_node_put(remote);
 				continue;
 			}
 		}
-- 
2.18.0


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

* [PATCH v3 07/24] drm/sun4i: Split out code for enumerating endpoints in output port
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (5 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 06/24] drm/sun4i: Fix releasing node when enumerating enpoints Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-28  1:57   ` [linux-sunxi] " Chen-Yu Tsai
  2018-06-25 12:02 ` [PATCH v3 08/24] drm/sun4i: Add support for traversing graph with TCON TOP Jernej Skrabec
                   ` (19 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Until now, each node has one input port and one output port. However,
with TCON TOP this is no longer true. It has 3 input and 3 output ports.

In order to prepare to this situation, split out the code which checks
all endpoints in input port and adds available components to fifo.

This patch doesn't do any functional change.

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

diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index e15fa2389e3f..20193d6f33ba 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -231,12 +231,55 @@ struct endpoint_list {
 	DECLARE_KFIFO(fifo, struct device_node *, 16);
 };
 
+static void sun4i_drv_traverse_endpoints(struct endpoint_list *list,
+					 struct device_node *node,
+					 int port_id)
+{
+	struct device_node *ep, *remote, *port;
+
+	port = of_graph_get_port_by_id(node, port_id);
+	if (!port) {
+		DRM_DEBUG_DRIVER("No output to bind on port %d\n", port_id);
+		return;
+	}
+
+	for_each_available_child_of_node(port, ep) {
+		remote = of_graph_get_remote_port_parent(ep);
+		if (!remote) {
+			DRM_DEBUG_DRIVER("Error retrieving the output node\n");
+			continue;
+		}
+
+		/*
+		 * If the node is our TCON, the first port is used for
+		 * panel or bridges, and will not be part of the
+		 * component framework.
+		 */
+		if (sun4i_drv_node_is_tcon(node)) {
+			struct of_endpoint endpoint;
+
+			if (of_graph_parse_endpoint(ep, &endpoint)) {
+				DRM_DEBUG_DRIVER("Couldn't parse endpoint\n");
+				of_node_put(remote);
+				continue;
+			}
+
+			if (!endpoint.id) {
+				DRM_DEBUG_DRIVER("Endpoint is our panel... skipping\n");
+				of_node_put(remote);
+				continue;
+			}
+		}
+
+		kfifo_put(&list->fifo, remote);
+	}
+}
+
 static int sun4i_drv_add_endpoints(struct device *dev,
 				   struct endpoint_list *list,
 				   struct component_match **match,
 				   struct device_node *node)
 {
-	struct device_node *port, *ep, *remote;
 	int count = 0;
 
 	/*
@@ -272,43 +315,8 @@ static int sun4i_drv_add_endpoints(struct device *dev,
 		count++;
 	}
 
-	/* Inputs are listed first, then outputs */
-	port = of_graph_get_port_by_id(node, 1);
-	if (!port) {
-		DRM_DEBUG_DRIVER("No output to bind\n");
-		return count;
-	}
-
-	for_each_available_child_of_node(port, ep) {
-		remote = of_graph_get_remote_port_parent(ep);
-		if (!remote) {
-			DRM_DEBUG_DRIVER("Error retrieving the output node\n");
-			continue;
-		}
-
-		/*
-		 * If the node is our TCON, the first port is used for
-		 * panel or bridges, and will not be part of the
-		 * component framework.
-		 */
-		if (sun4i_drv_node_is_tcon(node)) {
-			struct of_endpoint endpoint;
-
-			if (of_graph_parse_endpoint(ep, &endpoint)) {
-				DRM_DEBUG_DRIVER("Couldn't parse endpoint\n");
-				of_node_put(remote);
-				continue;
-			}
-
-			if (!endpoint.id) {
-				DRM_DEBUG_DRIVER("Endpoint is our panel... skipping\n");
-				of_node_put(remote);
-				continue;
-			}
-		}
-
-		kfifo_put(&list->fifo, remote);
-	}
+	/* each node has at least one output */
+	sun4i_drv_traverse_endpoints(list, node, 1);
 
 	return count;
 }
-- 
2.18.0


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

* [PATCH v3 08/24] drm/sun4i: Add support for traversing graph with TCON TOP
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (6 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 07/24] drm/sun4i: Split out code for enumerating endpoints in output port Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-28  1:57   ` Chen-Yu Tsai
  2018-06-25 12:02 ` [PATCH v3 09/24] drm/sun4i: Don't skip TCONs if they don't have channel 0 Jernej Skrabec
                   ` (18 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

TCON TOP is different from other nodes in graph by having 3 input and 3
output ports. Additionally, connection to TV TCON might lead back to
HDMI mux input port, creating loops.

Add support for traversing such graph.

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

diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index 20193d6f33ba..e6c62c079146 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -26,6 +26,7 @@
 #include "sun4i_frontend.h"
 #include "sun4i_framebuffer.h"
 #include "sun4i_tcon.h"
+#include "sun8i_tcon_top.h"
 
 DEFINE_DRM_GEM_CMA_FOPS(sun4i_drv_fops);
 
@@ -197,6 +198,11 @@ static bool sun4i_drv_node_is_tcon(struct device_node *node)
 	return !!of_match_node(sun4i_tcon_of_table, node);
 }
 
+static bool sun4i_drv_node_is_tcon_top(struct device_node *node)
+{
+	return !!of_match_node(sun8i_tcon_top_of_table, node);
+}
+
 static int compare_of(struct device *dev, void *data)
 {
 	DRM_DEBUG_DRIVER("Comparing of node %pOF with %pOF\n",
@@ -258,6 +264,18 @@ static void sun4i_drv_traverse_endpoints(struct endpoint_list *list,
 		if (sun4i_drv_node_is_tcon(node)) {
 			struct of_endpoint endpoint;
 
+			/*
+			 * TCON TOP is always probed before TCON. However, TCON
+			 * points back to TCON TOP when it is source for HDMI.
+			 * We have to skip it here to prevent infinite looping
+			 * between TCON TOP and TCON.
+			 */
+			if (sun4i_drv_node_is_tcon_top(remote)) {
+				DRM_DEBUG_DRIVER("TCON output endpoint is TCON TOP... skipping\n");
+				of_node_put(remote);
+				continue;
+			}
+
 			if (of_graph_parse_endpoint(ep, &endpoint)) {
 				DRM_DEBUG_DRIVER("Couldn't parse endpoint\n");
 				of_node_put(remote);
@@ -318,6 +336,12 @@ static int sun4i_drv_add_endpoints(struct device *dev,
 	/* each node has at least one output */
 	sun4i_drv_traverse_endpoints(list, node, 1);
 
+	/* TCON TOP has second and third output */
+	if (sun4i_drv_node_is_tcon_top(node)) {
+		sun4i_drv_traverse_endpoints(list, node, 3);
+		sun4i_drv_traverse_endpoints(list, node, 5);
+	}
+
 	return count;
 }
 
-- 
2.18.0


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

* [PATCH v3 09/24] drm/sun4i: Don't skip TCONs if they don't have channel 0
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (7 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 08/24] drm/sun4i: Add support for traversing graph with TCON TOP Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-28  1:51   ` Chen-Yu Tsai
  2018-06-25 12:02 ` [PATCH v3 10/24] drm/sun4i: tcon: Generalize engine search algorithm Jernej Skrabec
                   ` (17 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

TV TCONs (channel 1 only) are always connected to TV or HDMI encoder.
Because of that, all output endpoints on such TCON node will point to a
encoder which is part of component framework.

Correct current graph traversing algorithm in such way that it doesn't
skip output enpoints with id 0 on TV TCONs.

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

diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index e6c62c079146..6ddf4eaccb40 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -198,6 +198,22 @@ static bool sun4i_drv_node_is_tcon(struct device_node *node)
 	return !!of_match_node(sun4i_tcon_of_table, node);
 }
 
+static bool sun4i_drv_node_is_tcon_with_ch0(struct device_node *node)
+{
+	const struct of_device_id *match;
+
+	match = of_match_node(sun4i_tcon_of_table, node);
+	if (match) {
+		struct sun4i_tcon_quirks *quirks;
+
+		quirks = (struct sun4i_tcon_quirks *)match->data;
+
+		return quirks->has_channel_0;
+	}
+
+	return false;
+}
+
 static bool sun4i_drv_node_is_tcon_top(struct device_node *node)
 {
 	return !!of_match_node(sun8i_tcon_top_of_table, node);
@@ -256,14 +272,7 @@ static void sun4i_drv_traverse_endpoints(struct endpoint_list *list,
 			continue;
 		}
 
-		/*
-		 * If the node is our TCON, the first port is used for
-		 * panel or bridges, and will not be part of the
-		 * component framework.
-		 */
 		if (sun4i_drv_node_is_tcon(node)) {
-			struct of_endpoint endpoint;
-
 			/*
 			 * TCON TOP is always probed before TCON. However, TCON
 			 * points back to TCON TOP when it is source for HDMI.
@@ -276,16 +285,25 @@ static void sun4i_drv_traverse_endpoints(struct endpoint_list *list,
 				continue;
 			}
 
-			if (of_graph_parse_endpoint(ep, &endpoint)) {
-				DRM_DEBUG_DRIVER("Couldn't parse endpoint\n");
-				of_node_put(remote);
-				continue;
-			}
-
-			if (!endpoint.id) {
-				DRM_DEBUG_DRIVER("Endpoint is our panel... skipping\n");
-				of_node_put(remote);
-				continue;
+			/*
+			 * If the node is our TCON with channel 0, the first
+			 * port is used for panel or bridges, and will not be
+			 * part of the component framework.
+			 */
+			if (sun4i_drv_node_is_tcon_with_ch0(node)) {
+				struct of_endpoint endpoint;
+
+				if (of_graph_parse_endpoint(ep, &endpoint)) {
+					DRM_DEBUG_DRIVER("Couldn't parse endpoint\n");
+					of_node_put(remote);
+					continue;
+				}
+
+				if (!endpoint.id) {
+					DRM_DEBUG_DRIVER("Endpoint is our panel... skipping\n");
+					of_node_put(remote);
+					continue;
+				}
 			}
 		}
 
-- 
2.18.0


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

* [PATCH v3 10/24] drm/sun4i: tcon: Generalize engine search algorithm
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (8 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 09/24] drm/sun4i: Don't skip TCONs if they don't have channel 0 Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-28  2:06   ` Chen-Yu Tsai
  2018-06-25 12:02 ` [PATCH v3 11/24] drm/sun4i: Don't check for LVDS and RGB when TCON has only ch1 Jernej Skrabec
                   ` (16 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Current "old" method to find engine worked pretty well for DE2. However,
it doesn't work when TCON TOP is between  mixer (engine) and TCON. TCON
TOP has multiple input ports, but current engine search algorithm
expects only one.

This can be fixed by first looking for output port id and selecting
matching input by subtracting 1 for the next round. This work even if
there is only one input and output.

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

diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 08747fc3ee71..264bcc43da11 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -791,12 +791,14 @@ static int sun4i_tcon_init_regmap(struct device *dev,
  */
 static struct sunxi_engine *
 sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv,
-				struct device_node *node)
+				struct device_node *node,
+				u32 port_id)
 {
 	struct device_node *port, *ep, *remote;
 	struct sunxi_engine *engine = ERR_PTR(-EINVAL);
+	u32 reg = 0;
 
-	port = of_graph_get_port_by_id(node, 0);
+	port = of_graph_get_port_by_id(node, port_id);
 	if (!port)
 		return ERR_PTR(-EINVAL);
 
@@ -826,8 +828,20 @@ sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv,
 		if (remote == engine->node)
 			goto out_put_remote;
 
+	/*
+	 * According to device tree binding input ports have even id
+	 * number and output ports have odd id. Since component with
+	 * more than one input and one output (TCON TOP) exits, correct
+	 * remote input id has to be calculated by subtracting 1 from
+	 * remote output id. If this for some reason can't be done, 0
+	 * is used as input port id.
+	 */
+	port = of_graph_get_remote_port(ep);
+	if (!of_property_read_u32(port, "reg", &reg) && reg > 0)
+		reg -= 1;
+
 	/* keep looking through upstream ports */
-	engine = sun4i_tcon_find_engine_traverse(drv, remote);
+	engine = sun4i_tcon_find_engine_traverse(drv, remote, reg);
 
 out_put_remote:
 	of_node_put(remote);
@@ -950,7 +964,7 @@ static struct sunxi_engine *sun4i_tcon_find_engine(struct sun4i_drv *drv,
 
 	/* Fallback to old method by traversing input endpoints */
 	of_node_put(port);
-	return sun4i_tcon_find_engine_traverse(drv, node);
+	return sun4i_tcon_find_engine_traverse(drv, node, 0);
 }
 
 static int sun4i_tcon_bind(struct device *dev, struct device *master,
-- 
2.18.0


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

* [PATCH v3 11/24] drm/sun4i: Don't check for LVDS and RGB when TCON has only ch1
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (9 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 10/24] drm/sun4i: tcon: Generalize engine search algorithm Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-28  2:08   ` Chen-Yu Tsai
  2018-06-25 12:02 ` [PATCH v3 12/24] drm/sun4i: Don't check for panel or bridge on TV TCONs Jernej Skrabec
                   ` (15 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

LVDS and RGB interfaces are always connected to TCONs which have channel
0. It doesn't make sense to try to init them on TV TCONs.

Add a check if TCON has channel 0 before trying to init LVDS or RGB
interface.

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

diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 264bcc43da11..761687ebacba 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -1106,23 +1106,25 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
 		goto err_free_dotclock;
 	}
 
-	/*
-	 * If we have an LVDS panel connected to the TCON, we should
-	 * just probe the LVDS connector. Otherwise, just probe RGB as
-	 * we used to.
-	 */
-	remote = of_graph_get_remote_node(dev->of_node, 1, 0);
-	if (of_device_is_compatible(remote, "panel-lvds"))
-		if (can_lvds)
-			ret = sun4i_lvds_init(drm, tcon);
+	if (tcon->quirks->has_channel_0) {
+		/*
+		 * If we have an LVDS panel connected to the TCON, we should
+		 * just probe the LVDS connector. Otherwise, just probe RGB as
+		 * we used to.
+		 */
+		remote = of_graph_get_remote_node(dev->of_node, 1, 0);
+		if (of_device_is_compatible(remote, "panel-lvds"))
+			if (can_lvds)
+				ret = sun4i_lvds_init(drm, tcon);
+			else
+				ret = -EINVAL;
 		else
-			ret = -EINVAL;
-	else
-		ret = sun4i_rgb_init(drm, tcon);
-	of_node_put(remote);
+			ret = sun4i_rgb_init(drm, tcon);
+		of_node_put(remote);
 
-	if (ret < 0)
-		goto err_free_dotclock;
+		if (ret < 0)
+			goto err_free_dotclock;
+	}
 
 	if (tcon->quirks->needs_de_be_mux) {
 		/*
-- 
2.18.0


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

* [PATCH v3 12/24] drm/sun4i: Don't check for panel or bridge on TV TCONs
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (10 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 11/24] drm/sun4i: Don't check for LVDS and RGB when TCON has only ch1 Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-28  2:17   ` Chen-Yu Tsai
  2018-06-25 12:02 ` [PATCH v3 13/24] dt-bindings: display: sun4i-drm: Add R40 mixer compatibles Jernej Skrabec
                   ` (14 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

TV TCONs are always connected to TV or HDMI encoder, so it doesn't make
sense to check if panel or bridge is connected to them.

Check if TCON has channel 0 and only then check for connected panel or
bridges.

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

diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 761687ebacba..a41c7bb0d557 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -1178,13 +1178,19 @@ static const struct component_ops sun4i_tcon_ops = {
 static int sun4i_tcon_probe(struct platform_device *pdev)
 {
 	struct device_node *node = pdev->dev.of_node;
+	const struct sun4i_tcon_quirks *quirks;
 	struct drm_bridge *bridge;
 	struct drm_panel *panel;
 	int ret;
 
-	ret = drm_of_find_panel_or_bridge(node, 1, 0, &panel, &bridge);
-	if (ret == -EPROBE_DEFER)
-		return ret;
+	quirks = of_device_get_match_data(&pdev->dev);
+
+	/* panels and bridges are present only on TCONs with channel 0 */
+	if (quirks->has_channel_0) {
+		ret = drm_of_find_panel_or_bridge(node, 1, 0, &panel, &bridge);
+		if (ret == -EPROBE_DEFER)
+			return ret;
+	}
 
 	return component_add(&pdev->dev, &sun4i_tcon_ops);
 }
-- 
2.18.0


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

* [PATCH v3 13/24] dt-bindings: display: sun4i-drm: Add R40 mixer compatibles
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (11 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 12/24] drm/sun4i: Don't check for panel or bridge on TV TCONs Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-28  2:17   ` Chen-Yu Tsai
  2018-06-25 12:02 ` [PATCH v3 14/24] drm/sun4i: Add support for R40 mixers Jernej Skrabec
                   ` (13 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

R40 DE2 mixers are similar to those found in A83T, except it needs
different clock settings.

Add a compatibles for them.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index fe31b1510717..84fe38dbb900 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -366,6 +366,8 @@ Required properties:
     * allwinner,sun8i-a83t-de2-mixer-0
     * allwinner,sun8i-a83t-de2-mixer-1
     * allwinner,sun8i-h3-de2-mixer-0
+    * allwinner,sun8i-r40-de2-mixer-0
+    * allwinner,sun8i-r40-de2-mixer-1
     * allwinner,sun8i-v3s-de2-mixer
   - reg: base address and size of the memory-mapped region.
   - clocks: phandles to the clocks feeding the mixer
-- 
2.18.0


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

* [PATCH v3 14/24] drm/sun4i: Add support for R40 mixers
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (12 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 13/24] dt-bindings: display: sun4i-drm: Add R40 mixer compatibles Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-28  2:18   ` Chen-Yu Tsai
  2018-06-25 12:02 ` [PATCH v3 15/24] dt-bindings: display: sun4i-drm: Add description of A64 HDMI PHY Jernej Skrabec
                   ` (12 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Both mixers have similar capabilities as others SoCs with DE2.

First mixer has 1 VI and 3 UI planes and supports HW scaling on all
planes.

Second mixer has 1 VI and 1 UI planes and also supports HW scaling on
all planes.

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

diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 126899d6f0d3..ee8febb25903 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -500,6 +500,22 @@ static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg = {
 	.vi_num		= 1,
 };
 
+static const struct sun8i_mixer_cfg sun8i_r40_mixer0_cfg = {
+	.ccsc		= 0,
+	.mod_rate	= 297000000,
+	.scaler_mask	= 0xf,
+	.ui_num		= 3,
+	.vi_num		= 1,
+};
+
+static const struct sun8i_mixer_cfg sun8i_r40_mixer1_cfg = {
+	.ccsc		= 1,
+	.mod_rate	= 297000000,
+	.scaler_mask	= 0x3,
+	.ui_num		= 1,
+	.vi_num		= 1,
+};
+
 static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
 	.vi_num = 2,
 	.ui_num = 1,
@@ -521,6 +537,14 @@ static const struct of_device_id sun8i_mixer_of_table[] = {
 		.compatible = "allwinner,sun8i-h3-de2-mixer-0",
 		.data = &sun8i_h3_mixer0_cfg,
 	},
+	{
+		.compatible = "allwinner,sun8i-r40-de2-mixer-0",
+		.data = &sun8i_r40_mixer0_cfg,
+	},
+	{
+		.compatible = "allwinner,sun8i-r40-de2-mixer-1",
+		.data = &sun8i_r40_mixer1_cfg,
+	},
 	{
 		.compatible = "allwinner,sun8i-v3s-de2-mixer",
 		.data = &sun8i_v3s_mixer_cfg,
-- 
2.18.0


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

* [PATCH v3 15/24] dt-bindings: display: sun4i-drm: Add description of A64 HDMI PHY
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (13 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 14/24] drm/sun4i: Add support for R40 mixers Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-28  2:19   ` Chen-Yu Tsai
  2018-06-25 12:02 ` [PATCH v3 16/24] drm/sun4i: Enable DW HDMI PHY clock Jernej Skrabec
                   ` (11 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

A64 HDMI PHY is similar to H3 HDMI PHY except it has two possible PLL
clock parents. It is compatible to other HDMI PHYs, like that found in
R40.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index 84fe38dbb900..dc83f21ef188 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -101,6 +101,7 @@ DWC HDMI PHY
 
 Required properties:
   - compatible: value must be one of:
+    * allwinner,sun50i-a64-hdmi-phy
     * allwinner,sun8i-a83t-hdmi-phy
     * allwinner,sun8i-h3-hdmi-phy
   - reg: base address and size of memory-mapped region
@@ -111,8 +112,9 @@ Required properties:
   - resets: phandle to the reset controller driving the PHY
   - reset-names: must be "phy"
 
-H3 HDMI PHY requires additional clock:
+H3 and A64 HDMI PHY require additional clocks:
   - pll-0: parent of phy clock
+  - pll-1: second possible phy clock parent (A64 only)
 
 TV Encoder
 ----------
-- 
2.18.0


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

* [PATCH v3 16/24] drm/sun4i: Enable DW HDMI PHY clock
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (14 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 15/24] dt-bindings: display: sun4i-drm: Add description of A64 HDMI PHY Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-28  2:22   ` Chen-Yu Tsai
  2018-06-25 12:02 ` [PATCH v3 17/24] drm/sun4i: Don't change clock bits in DW HDMI PHY driver Jernej Skrabec
                   ` (10 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Current DW HDMI PHY code never prepares and enables PHY clock after it is
created. It's just used as it is. This may work in some cases, but it's
clearly wrong. Fix it by adding proper calls to enable/disable PHY
clock.

Fixes: 4f86e81748fe ("drm/sun4i: Add support for H3 HDMI PHY variant")

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

diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index 5a52fc489a9d..966688f04741 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -477,13 +477,15 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
 			dev_err(dev, "Couldn't create the PHY clock\n");
 			goto err_put_clk_pll0;
 		}
+
+		clk_prepare_enable(phy->clk_phy);
 	}
 
 	phy->rst_phy = of_reset_control_get_shared(node, "phy");
 	if (IS_ERR(phy->rst_phy)) {
 		dev_err(dev, "Could not get phy reset control\n");
 		ret = PTR_ERR(phy->rst_phy);
-		goto err_put_clk_pll0;
+		goto err_disable_clk_phy;
 	}
 
 	ret = reset_control_deassert(phy->rst_phy);
@@ -514,6 +516,8 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
 	reset_control_assert(phy->rst_phy);
 err_put_rst_phy:
 	reset_control_put(phy->rst_phy);
+err_disable_clk_phy:
+	clk_disable_unprepare(phy->clk_phy);
 err_put_clk_pll0:
 	if (phy->variant->has_phy_clk)
 		clk_put(phy->clk_pll0);
@@ -531,6 +535,7 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi)
 
 	clk_disable_unprepare(phy->clk_mod);
 	clk_disable_unprepare(phy->clk_bus);
+	clk_disable_unprepare(phy->clk_phy);
 
 	reset_control_assert(phy->rst_phy);
 
-- 
2.18.0


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

* [PATCH v3 17/24] drm/sun4i: Don't change clock bits in DW HDMI PHY driver
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (15 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 16/24] drm/sun4i: Enable DW HDMI PHY clock Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-28  2:24   ` Chen-Yu Tsai
  2018-06-25 12:02 ` [PATCH v3 18/24] drm/sun4i: DW HDMI PHY: Add support for second PLL Jernej Skrabec
                   ` (9 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

DW HDMI PHY driver and PHY clock driver share same registers. Make sure
that DW HDMI PHY setup code doesn't change any clock related bits.
During initialization, set PHY PLL parent bit to 0.

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

diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
index 79154f0f674a..3ba71aff92fc 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -98,7 +98,7 @@
 #define SUN8I_HDMI_PHY_PLL_CFG1_LDO2_EN		BIT(29)
 #define SUN8I_HDMI_PHY_PLL_CFG1_LDO1_EN		BIT(28)
 #define SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33	BIT(27)
-#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL	BIT(26)
+#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK	BIT(26)
 #define SUN8I_HDMI_PHY_PLL_CFG1_PLLEN		BIT(25)
 #define SUN8I_HDMI_PHY_PLL_CFG1_LDO_VSET(x)	((x) << 22)
 #define SUN8I_HDMI_PHY_PLL_CFG1_UNKNOWN(x)	((x) << 20)
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index 966688f04741..e56b9e5b1c42 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -183,7 +183,13 @@ static int sun8i_hdmi_phy_config_h3(struct dw_hdmi *hdmi,
 	regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
 			   SUN8I_HDMI_PHY_ANA_CFG1_TXEN_MASK, 0);
 
-	regmap_write(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, pll_cfg1_init);
+	/*
+	 * NOTE: We have to be careful not to overwrite PHY parent
+	 * clock selection bit and clock divider.
+	 */
+	regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
+			   (u32)~SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK,
+			   pll_cfg1_init);
 	regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG2_REG,
 			   (u32)~SUN8I_HDMI_PHY_PLL_CFG2_PREDIV_MSK,
 			   pll_cfg2_init);
@@ -352,6 +358,10 @@ static void sun8i_hdmi_phy_init_h3(struct sun8i_hdmi_phy *phy)
 			   SUN8I_HDMI_PHY_ANA_CFG3_SCLEN |
 			   SUN8I_HDMI_PHY_ANA_CFG3_SDAEN);
 
+	/* reset PHY PLL clock parent */
+	regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
+			   SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK, 0);
+
 	/* set HW control of CEC pins */
 	regmap_write(phy->regs, SUN8I_HDMI_PHY_CEC_REG, 0);
 
-- 
2.18.0


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

* [PATCH v3 18/24] drm/sun4i: DW HDMI PHY: Add support for second PLL
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (16 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 17/24] drm/sun4i: Don't change clock bits in DW HDMI PHY driver Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-28  2:25   ` Chen-Yu Tsai
  2018-06-25 12:02 ` [PATCH v3 19/24] drm/sun4i: Add support for second clock parent to DW HDMI PHY clk driver Jernej Skrabec
                   ` (8 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Some DW HDMI PHYs, like those found in A64 and R40 SoCs, can select
between two clock parents.

Add code which reads second PLL from DT.

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

diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
index 3ba71aff92fc..46a3aa6a53a9 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -147,6 +147,7 @@ struct sun8i_hdmi_phy;
 
 struct sun8i_hdmi_phy_variant {
 	bool has_phy_clk;
+	bool has_second_pll;
 	void (*phy_init)(struct sun8i_hdmi_phy *phy);
 	void (*phy_disable)(struct dw_hdmi *hdmi,
 			    struct sun8i_hdmi_phy *phy);
@@ -160,6 +161,7 @@ struct sun8i_hdmi_phy {
 	struct clk			*clk_mod;
 	struct clk			*clk_phy;
 	struct clk			*clk_pll0;
+	struct clk			*clk_pll1;
 	unsigned int			rcal;
 	struct regmap			*regs;
 	struct reset_control		*rst_phy;
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index e56b9e5b1c42..f0877b3f67e7 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -482,10 +482,19 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
 			goto err_put_clk_mod;
 		}
 
+		if (phy->variant->has_second_pll) {
+			phy->clk_pll1 = of_clk_get_by_name(node, "pll-1");
+			if (IS_ERR(phy->clk_pll1)) {
+				dev_err(dev, "Could not get pll-1 clock\n");
+				ret = PTR_ERR(phy->clk_pll1);
+				goto err_put_clk_pll0;
+			}
+		}
+
 		ret = sun8i_phy_clk_create(phy, dev);
 		if (ret) {
 			dev_err(dev, "Couldn't create the PHY clock\n");
-			goto err_put_clk_pll0;
+			goto err_put_clk_pll1;
 		}
 
 		clk_prepare_enable(phy->clk_phy);
@@ -528,9 +537,10 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
 	reset_control_put(phy->rst_phy);
 err_disable_clk_phy:
 	clk_disable_unprepare(phy->clk_phy);
+err_put_clk_pll1:
+	clk_put(phy->clk_pll1);
 err_put_clk_pll0:
-	if (phy->variant->has_phy_clk)
-		clk_put(phy->clk_pll0);
+	clk_put(phy->clk_pll0);
 err_put_clk_mod:
 	clk_put(phy->clk_mod);
 err_put_clk_bus:
@@ -551,8 +561,8 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi)
 
 	reset_control_put(phy->rst_phy);
 
-	if (phy->variant->has_phy_clk)
-		clk_put(phy->clk_pll0);
+	clk_put(phy->clk_pll0);
+	clk_put(phy->clk_pll1);
 	clk_put(phy->clk_mod);
 	clk_put(phy->clk_bus);
 }
-- 
2.18.0


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

* [PATCH v3 19/24] drm/sun4i: Add support for second clock parent to DW HDMI PHY clk driver
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (17 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 18/24] drm/sun4i: DW HDMI PHY: Add support for second PLL Jernej Skrabec
@ 2018-06-25 12:02 ` Jernej Skrabec
  2018-06-28  2:30   ` [linux-sunxi] " Chen-Yu Tsai
  2018-06-25 12:03 ` [PATCH v3 20/24] drm/sun4i: Add support for A64 HDMI PHY Jernej Skrabec
                   ` (7 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:02 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Expand HDMI PHY clock driver to support second clock parent.

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

diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
index 46a3aa6a53a9..aadbe0a10b0c 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -99,6 +99,7 @@
 #define SUN8I_HDMI_PHY_PLL_CFG1_LDO1_EN		BIT(28)
 #define SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33	BIT(27)
 #define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK	BIT(26)
+#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT	26
 #define SUN8I_HDMI_PHY_PLL_CFG1_PLLEN		BIT(25)
 #define SUN8I_HDMI_PHY_PLL_CFG1_LDO_VSET(x)	((x) << 22)
 #define SUN8I_HDMI_PHY_PLL_CFG1_UNKNOWN(x)	((x) << 20)
@@ -190,6 +191,7 @@ 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);
 
-int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev);
+int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev,
+			 bool second_parent);
 
 #endif /* _SUN8I_DW_HDMI_H_ */
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index f0877b3f67e7..aea46b08f127 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -491,7 +491,8 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
 			}
 		}
 
-		ret = sun8i_phy_clk_create(phy, dev);
+		ret = sun8i_phy_clk_create(phy, dev,
+					   phy->variant->has_second_pll);
 		if (ret) {
 			dev_err(dev, "Couldn't create the PHY clock\n");
 			goto err_put_clk_pll1;
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
index faea449812f8..a4d31fe3abff 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
@@ -22,35 +22,45 @@ static int sun8i_phy_clk_determine_rate(struct clk_hw *hw,
 {
 	unsigned long rate = req->rate;
 	unsigned long best_rate = 0;
+	struct clk_hw *best_parent = NULL;
 	struct clk_hw *parent;
 	int best_div = 1;
-	int i;
+	int i, p;
 
-	parent = clk_hw_get_parent(hw);
-
-	for (i = 1; i <= 16; i++) {
-		unsigned long ideal = rate * i;
-		unsigned long rounded;
-
-		rounded = clk_hw_round_rate(parent, ideal);
+	for (p = 0; p < clk_hw_get_num_parents(hw); p++) {
+		parent = clk_hw_get_parent_by_index(hw, p);
+		if (!parent)
+			continue;
 
-		if (rounded == ideal) {
-			best_rate = rounded;
-			best_div = i;
-			break;
+		for (i = 1; i <= 16; i++) {
+			unsigned long ideal = rate * i;
+			unsigned long rounded;
+
+			rounded = clk_hw_round_rate(parent, ideal);
+
+			if (rounded == ideal) {
+				best_rate = rounded;
+				best_div = i;
+				best_parent = parent;
+				break;
+			}
+
+			if (!best_rate ||
+			    abs(rate - rounded / i) <
+			    abs(rate - best_rate / best_div)) {
+				best_rate = rounded;
+				best_div = i;
+				best_parent = parent;
+			}
 		}
 
-		if (!best_rate ||
-		    abs(rate - rounded / i) <
-		    abs(rate - best_rate / best_div)) {
-			best_rate = rounded;
-			best_div = i;
-		}
+		if (best_rate / best_div == rate)
+			break;
 	}
 
 	req->rate = best_rate / best_div;
 	req->best_parent_rate = best_rate;
-	req->best_parent_hw = parent;
+	req->best_parent_hw = best_parent;
 
 	return 0;
 }
@@ -95,22 +105,58 @@ static int sun8i_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 	return 0;
 }
 
+static u8 sun8i_phy_clk_get_parent(struct clk_hw *hw)
+{
+	struct sun8i_phy_clk *priv = hw_to_phy_clk(hw);
+	u32 reg;
+
+	regmap_read(priv->phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, &reg);
+	reg = (reg & SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK) >>
+	      SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT;
+
+	return reg;
+}
+
+static int sun8i_phy_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct sun8i_phy_clk *priv = hw_to_phy_clk(hw);
+
+	if (index > 1)
+		return -EINVAL;
+
+	regmap_update_bits(priv->phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
+			   SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK,
+			   index << SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT);
+
+	return 0;
+}
+
 static const struct clk_ops sun8i_phy_clk_ops = {
 	.determine_rate	= sun8i_phy_clk_determine_rate,
 	.recalc_rate	= sun8i_phy_clk_recalc_rate,
 	.set_rate	= sun8i_phy_clk_set_rate,
+
+	.get_parent	= sun8i_phy_clk_get_parent,
+	.set_parent	= sun8i_phy_clk_set_parent,
 };
 
-int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev)
+int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev,
+			 bool second_parent)
 {
 	struct clk_init_data init;
 	struct sun8i_phy_clk *priv;
-	const char *parents[1];
+	const char *parents[2];
 
 	parents[0] = __clk_get_name(phy->clk_pll0);
 	if (!parents[0])
 		return -ENODEV;
 
+	if (second_parent) {
+		parents[1] = __clk_get_name(phy->clk_pll1);
+		if (!parents[1])
+			return -ENODEV;
+	}
+
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
@@ -118,7 +164,7 @@ int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev)
 	init.name = "hdmi-phy-clk";
 	init.ops = &sun8i_phy_clk_ops;
 	init.parent_names = parents;
-	init.num_parents = 1;
+	init.num_parents = second_parent ? 2 : 1;
 	init.flags = CLK_SET_RATE_PARENT;
 
 	priv->phy = phy;
-- 
2.18.0


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

* [PATCH v3 20/24] drm/sun4i: Add support for A64 HDMI PHY
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (18 preceding siblings ...)
  2018-06-25 12:02 ` [PATCH v3 19/24] drm/sun4i: Add support for second clock parent to DW HDMI PHY clk driver Jernej Skrabec
@ 2018-06-25 12:03 ` Jernej Skrabec
  2018-06-28  2:30   ` Chen-Yu Tsai
  2018-06-25 12:03 ` [PATCH v3 21/24] drm: of: Export drm_crtc_port_mask() Jernej Skrabec
                   ` (6 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:03 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

PHY is the same as in H3, except it can switch between two clock
parents.

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

diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index aea46b08f127..82502b351aec 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -396,6 +396,14 @@ static struct regmap_config sun8i_hdmi_phy_regmap_config = {
 	.name		= "phy"
 };
 
+static const struct sun8i_hdmi_phy_variant sun50i_a64_hdmi_phy = {
+	.has_phy_clk = true,
+	.has_second_pll = true,
+	.phy_init = &sun8i_hdmi_phy_init_h3,
+	.phy_disable = &sun8i_hdmi_phy_disable_h3,
+	.phy_config = &sun8i_hdmi_phy_config_h3,
+};
+
 static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = {
 	.phy_init = &sun8i_hdmi_phy_init_a83t,
 	.phy_disable = &sun8i_hdmi_phy_disable_a83t,
@@ -410,6 +418,10 @@ static const struct sun8i_hdmi_phy_variant sun8i_h3_hdmi_phy = {
 };
 
 static const struct of_device_id sun8i_hdmi_phy_of_table[] = {
+	{
+		.compatible = "allwinner,sun50i-a64-hdmi-phy",
+		.data = &sun50i_a64_hdmi_phy,
+	},
 	{
 		.compatible = "allwinner,sun8i-a83t-hdmi-phy",
 		.data = &sun8i_a83t_hdmi_phy,
-- 
2.18.0


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

* [PATCH v3 21/24] drm: of: Export drm_crtc_port_mask()
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (19 preceding siblings ...)
  2018-06-25 12:03 ` [PATCH v3 20/24] drm/sun4i: Add support for A64 HDMI PHY Jernej Skrabec
@ 2018-06-25 12:03 ` Jernej Skrabec
  2018-06-28  2:32   ` Chen-Yu Tsai
  2018-06-25 12:03 ` [PATCH v3 22/24] drm/sun4i: DW HDMI: Expand algorithm for possible crtcs Jernej Skrabec
                   ` (5 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:03 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Function is useful when drm_of_find_possible_crtcs() can't be used and
custom parsing is needed. This can happen for example when there is a
node with multiple muxes between crtc and encoder.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/drm_of.c | 5 +++--
 include/drm/drm_of.h     | 8 ++++++++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 1fe122461298..50e738857258 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -22,8 +22,8 @@ static void drm_release_of(struct device *dev, void *data)
  * Given a port OF node, return the possible mask of the corresponding
  * CRTC within a device's list of CRTCs.  Returns zero if not found.
  */
-static uint32_t drm_crtc_port_mask(struct drm_device *dev,
-				   struct device_node *port)
+uint32_t drm_crtc_port_mask(struct drm_device *dev,
+			    struct device_node *port)
 {
 	unsigned int index = 0;
 	struct drm_crtc *tmp;
@@ -37,6 +37,7 @@ static uint32_t drm_crtc_port_mask(struct drm_device *dev,
 
 	return 0;
 }
+EXPORT_SYMBOL(drm_crtc_port_mask);
 
 /**
  * drm_of_find_possible_crtcs - find the possible CRTCs for an encoder port
diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h
index b93c239afb60..a61fd77e46ba 100644
--- a/include/drm/drm_of.h
+++ b/include/drm/drm_of.h
@@ -17,6 +17,8 @@ struct drm_bridge;
 struct device_node;
 
 #ifdef CONFIG_OF
+uint32_t drm_crtc_port_mask(struct drm_device *dev,
+			    struct device_node *port);
 uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
 				    struct device_node *port);
 void drm_of_component_match_add(struct device *master,
@@ -34,6 +36,12 @@ int drm_of_find_panel_or_bridge(const struct device_node *np,
 				struct drm_panel **panel,
 				struct drm_bridge **bridge);
 #else
+static inline uint32_t drm_crtc_port_mask(struct drm_device *dev,
+					  struct device_node *port)
+{
+	return 0;
+}
+
 static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
 						  struct device_node *port)
 {
-- 
2.18.0


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

* [PATCH v3 22/24] drm/sun4i: DW HDMI: Expand algorithm for possible crtcs
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (20 preceding siblings ...)
  2018-06-25 12:03 ` [PATCH v3 21/24] drm: of: Export drm_crtc_port_mask() Jernej Skrabec
@ 2018-06-25 12:03 ` Jernej Skrabec
  2018-06-28  2:42   ` Chen-Yu Tsai
  2018-06-25 12:03 ` [PATCH v3 23/24] ARM: dts: sun8i: r40: Add HDMI pipeline Jernej Skrabec
                   ` (4 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:03 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

drm_of_find_possible_crtcs() doesn't work when DW HDMI encoder is
connected to TCON (crtc) through mux in TCON TOP.

In that case TCON TOP HDMI mux input port has to be manually traversed
and checked if it matches any known crtc.

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

diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
index 9f40a44b456b..d443886e055b 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
@@ -12,6 +12,7 @@
 #include <drm/drm_crtc_helper.h>
 
 #include "sun8i_dw_hdmi.h"
+#include "sun8i_tcon_top.h"
 
 static void sun8i_dw_hdmi_encoder_mode_set(struct drm_encoder *encoder,
 					   struct drm_display_mode *mode,
@@ -41,6 +42,48 @@ sun8i_dw_hdmi_mode_valid(struct drm_connector *connector,
 	return MODE_OK;
 }
 
+static bool sun8i_dw_hdmi_node_is_tcon_top(struct device_node *node)
+{
+	return !!of_match_node(sun8i_tcon_top_of_table, node);
+}
+
+static u32 sun8i_dw_hdmi_find_possible_crtcs(struct drm_device *drm,
+					     struct device_node *node)
+{
+	struct device_node *port, *ep, *remote, *remote_port;
+	u32 crtcs = 0;
+
+	port = of_graph_get_port_by_id(node, 0);
+	if (!port)
+		return 0;
+
+	ep = of_get_next_available_child(port, NULL);
+	if (!ep)
+		return 0;
+
+	remote = of_graph_get_remote_port_parent(ep);
+	if (!remote)
+		return 0;
+
+	if (sun8i_dw_hdmi_node_is_tcon_top(remote)) {
+		port = of_graph_get_port_by_id(remote, 4);
+		if (!port)
+			return 0;
+
+		for_each_child_of_node(port, ep) {
+			remote_port = of_graph_get_remote_port(ep);
+			if (remote_port) {
+				crtcs |= drm_crtc_port_mask(drm, remote_port);
+				of_node_put(remote_port);
+			}
+		}
+	} else {
+		crtcs = drm_of_find_possible_crtcs(drm, node);
+	}
+
+	return crtcs;
+}
+
 static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
 			      void *data)
 {
@@ -63,7 +106,8 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
 	hdmi->dev = &pdev->dev;
 	encoder = &hdmi->encoder;
 
-	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
+	encoder->possible_crtcs =
+		sun8i_dw_hdmi_find_possible_crtcs(drm, dev->of_node);
 	/*
 	 * If we failed to find the CRTC(s) which this encoder is
 	 * supposed to be connected to, it's because the CRTC has
-- 
2.18.0


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

* [PATCH v3 23/24] ARM: dts: sun8i: r40: Add HDMI pipeline
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (21 preceding siblings ...)
  2018-06-25 12:03 ` [PATCH v3 22/24] drm/sun4i: DW HDMI: Expand algorithm for possible crtcs Jernej Skrabec
@ 2018-06-25 12:03 ` Jernej Skrabec
  2018-06-28  2:50   ` Chen-Yu Tsai
  2018-06-25 12:03 ` [PATCH v3 24/24] ARM: dts: sun8i: r40: Enable HDMI output on BananaPi M2 Ultra Jernej Skrabec
                   ` (3 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:03 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Add all entries needed for HDMI to function properly.

Since R40 has highly configurable pipeline, both mixers and both TCON
TVs are added. Board specific DT should then connect them together
trough TCON TOP muxers to best fit the purpose of the board.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 arch/arm/boot/dts/sun8i-r40.dtsi | 269 +++++++++++++++++++++++++++++++
 1 file changed, 269 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi
index 173dcc1652d2..a2a75fb04caf 100644
--- a/arch/arm/boot/dts/sun8i-r40.dtsi
+++ b/arch/arm/boot/dts/sun8i-r40.dtsi
@@ -42,8 +42,11 @@
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/sun8i-de2.h>
 #include <dt-bindings/clock/sun8i-r40-ccu.h>
+#include <dt-bindings/clock/sun8i-tcon-top.h>
 #include <dt-bindings/reset/sun8i-r40-ccu.h>
+#include <dt-bindings/reset/sun8i-de2.h>
 
 / {
 	#address-cells = <1>;
@@ -99,12 +102,76 @@
 		};
 	};
 
+	de: display-engine {
+		compatible = "allwinner,sun8i-r40-display-engine",
+			     "allwinner,sun8i-h3-display-engine";
+		allwinner,pipelines = <&mixer0>, <&mixer1>;
+		status = "disabled";
+	};
+
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
 
+		display_clocks: clock@1000000 {
+			compatible = "allwinner,sun8i-r40-de2-clk",
+				     "allwinner,sun8i-h3-de2-clk";
+			reg = <0x01000000 0x100000>;
+			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@1100000 {
+			compatible = "allwinner,sun8i-r40-de2-mixer-0";
+			reg = <0x01100000 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: endpoint {
+						remote-endpoint = <&tcon_top_mixer0_in_mixer0>;
+					};
+				};
+			};
+		};
+
+		mixer1: mixer@1200000 {
+			compatible = "allwinner,sun8i-r40-de2-mixer-1";
+			reg = <0x01200000 0x100000>;
+			clocks = <&display_clocks CLK_BUS_MIXER1>,
+				 <&display_clocks CLK_MIXER1>;
+			clock-names = "bus",
+				      "mod";
+			resets = <&display_clocks RST_WB>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				mixer1_out: port@1 {
+					reg = <1>;
+					mixer1_out_tcon_top: endpoint {
+						remote-endpoint = <&tcon_top_mixer1_in_mixer1>;
+					};
+				};
+			};
+		};
+
 		nmi_intc: interrupt-controller@1c00030 {
 			compatible = "allwinner,sun7i-a20-sc-nmi";
 			interrupt-controller;
@@ -451,6 +518,163 @@
 			#size-cells = <0>;
 		};
 
+		tcon_top: tcon-top@1c70000 {
+			compatible = "allwinner,sun8i-r40-tcon-top";
+			reg = <0x01c70000 0x1000>;
+			clocks = <&ccu CLK_BUS_TCON_TOP>,
+				 <&ccu CLK_TCON_TV0>,
+				 <&ccu CLK_TVE0>,
+				 <&ccu CLK_TCON_TV1>,
+				 <&ccu CLK_TVE1>,
+				 <&ccu CLK_DSI_DPHY>;
+			clock-names = "bus",
+				      "tcon-tv0",
+				      "tve0",
+				      "tcon-tv1",
+				      "tve1",
+				      "dsi";
+			clock-output-names = "tcon-top-tv0",
+					     "tcon-top-tv1",
+					     "tcon-top-dsi";
+			resets = <&ccu RST_BUS_TCON_TOP>;
+			#clock-cells = <1>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon_top_mixer0_in: port@0 {
+					reg = <0>;
+
+					tcon_top_mixer0_in_mixer0: endpoint {
+						remote-endpoint = <&mixer0_out_tcon_top>;
+					};
+				};
+
+				tcon_top_mixer0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					tcon_top_mixer0_out_tcon_lcd0: endpoint@0 {
+						reg = <0>;
+					};
+
+					tcon_top_mixer0_out_tcon_lcd1: endpoint@1 {
+						reg = <1>;
+					};
+
+					tcon_top_mixer0_out_tcon_tv0: endpoint@2 {
+						reg = <2>;
+					};
+
+					tcon_top_mixer0_out_tcon_tv1: endpoint@3 {
+						reg = <3>;
+					};
+				};
+
+				tcon_top_mixer1_in: port@2 {
+					reg = <2>;
+
+					tcon_top_mixer1_in_mixer1: endpoint {
+						remote-endpoint = <&mixer1_out_tcon_top>;
+					};
+				};
+
+				tcon_top_mixer1_out: port@3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+
+					tcon_top_mixer1_out_tcon_lcd0: endpoint@0 {
+						reg = <0>;
+					};
+
+					tcon_top_mixer1_out_tcon_lcd1: endpoint@1 {
+						reg = <1>;
+					};
+
+					tcon_top_mixer1_out_tcon_tv0: endpoint@2 {
+						reg = <2>;
+					};
+
+					tcon_top_mixer1_out_tcon_tv1: endpoint@3 {
+						reg = <3>;
+					};
+				};
+
+				tcon_top_hdmi_in: port@4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+
+					tcon_top_hdmi_in_tcon_tv0: endpoint@0 {
+						reg = <0>;
+					};
+
+					tcon_top_hdmi_in_tcon_tv1: endpoint@1 {
+						reg = <1>;
+					};
+				};
+
+				tcon_top_hdmi_out: port@5 {
+					reg = <5>;
+
+					tcon_top_hdmi_out_hdmi: endpoint {
+						remote-endpoint = <&hdmi_in_tcon_top>;
+					};
+				};
+			};
+		};
+
+		tcon_tv0: lcd-controller@1c73000 {
+			compatible = "allwinner,sun8i-r40-tcon-tv",
+				     "allwinner,sun8i-a83t-tcon-tv";
+			reg = <0x01c73000 0x1000>;
+			interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_TCON_TV0>, <&tcon_top 0>;
+			clock-names = "ahb", "tcon-ch1";
+			resets = <&ccu RST_BUS_TCON_TV0>;
+			reset-names = "lcd";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon_tv0_in: port@0 {
+					reg = <0>;
+				};
+
+				tcon_tv0_out: port@1 {
+					reg = <1>;
+				};
+			};
+		};
+
+		tcon_tv1: lcd-controller@1c74000 {
+			compatible = "allwinner,sun8i-r40-tcon-tv",
+				     "allwinner,sun8i-a83t-tcon-tv";
+			reg = <0x01c74000 0x1000>;
+			interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_TCON_TV1>, <&tcon_top 1>;
+			clock-names = "ahb", "tcon-ch1";
+			resets = <&ccu RST_BUS_TCON_TV1>;
+			reset-names = "lcd";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon_tv1_in: port@0 {
+					reg = <0>;
+				};
+
+				tcon_tv1_out: port@1 {
+					reg = <1>;
+				};
+			};
+		};
+
 		gic: interrupt-controller@1c81000 {
 			compatible = "arm,gic-400";
 			reg = <0x01c81000 0x1000>,
@@ -461,6 +685,51 @@
 			#interrupt-cells = <3>;
 			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
 		};
+
+		hdmi: hdmi@1ee0000 {
+			compatible = "allwinner,sun8i-r40-dw-hdmi",
+				     "allwinner,sun8i-a83t-dw-hdmi";
+			reg = <0x01ee0000 0x10000>;
+			reg-io-width = <1>;
+			interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_HDMI0>, <&ccu CLK_HDMI_SLOW>,
+				 <&ccu CLK_HDMI>;
+			clock-names = "iahb", "isfr", "tmds";
+			resets = <&ccu RST_BUS_HDMI1>;
+			reset-names = "ctrl";
+			phys = <&hdmi_phy>;
+			phy-names = "hdmi-phy";
+			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@1ef0000 {
+			compatible = "allwinner,sun8i-r40-hdmi-phy",
+				     "allwinner,sun50i-a64-hdmi-phy";
+			reg = <0x01ef0000 0x10000>;
+			clocks = <&ccu CLK_BUS_HDMI1>, <&ccu CLK_HDMI_SLOW>,
+				 <&ccu 7>, <&ccu 16>;
+			clock-names = "bus", "mod", "pll-0", "pll-1";
+			resets = <&ccu RST_BUS_HDMI0>;
+			reset-names = "phy";
+			#phy-cells = <0>;
+		};
 	};
 
 	timer {
-- 
2.18.0


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

* [PATCH v3 24/24] ARM: dts: sun8i: r40: Enable HDMI output on BananaPi M2 Ultra
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (22 preceding siblings ...)
  2018-06-25 12:03 ` [PATCH v3 23/24] ARM: dts: sun8i: r40: Add HDMI pipeline Jernej Skrabec
@ 2018-06-25 12:03 ` Jernej Skrabec
  2018-06-28  2:51   ` [linux-sunxi] " Chen-Yu Tsai
  2018-06-25 12:07 ` [linux-sunxi] [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Škrabec
                   ` (2 subsequent siblings)
  26 siblings, 1 reply; 87+ messages in thread
From: Jernej Skrabec @ 2018-06-25 12:03 UTC (permalink / raw)
  To: maxime.ripard, wens, robh+dt
  Cc: airlied, gustavo, maarten.lankhorst, seanpaul, mark.rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Since HDMI can be considered as main output, most capable mixer is
connected to it (mixer0).

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 .../boot/dts/sun8i-r40-bananapi-m2-ultra.dts  | 45 +++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
index 27d9ccd0ef2f..0ebc2f9a980e 100644
--- a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
+++ b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
@@ -58,6 +58,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";
 
@@ -93,6 +104,10 @@
 	};
 };
 
+&de {
+	status = "okay";
+};
+
 &ehci1 {
 	status = "okay";
 };
@@ -101,6 +116,16 @@
 	status = "okay";
 };
 
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &i2c0 {
 	status = "okay";
 
@@ -195,6 +220,26 @@
 	status = "okay";
 };
 
+&tcon_top_hdmi_in_tcon_tv0 {
+	remote-endpoint = <&tcon_tv0_out_tcon_top>;
+};
+
+&tcon_top_mixer0_out_tcon_tv0 {
+	remote-endpoint = <&tcon_tv0_in_tcon_top>;
+};
+
+&tcon_tv0_in {
+	tcon_tv0_in_tcon_top: endpoint {
+		remote-endpoint = <&tcon_top_mixer0_out_tcon_tv0>;
+	};
+};
+
+&tcon_tv0_out {
+	tcon_tv0_out_tcon_top: endpoint {
+		remote-endpoint = <&tcon_top_hdmi_in_tcon_tv0>;
+	};
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pb_pins>;
-- 
2.18.0


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

* Re: [linux-sunxi] [PATCH v3 00/24] Add support for R40 HDMI pipeline
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (23 preceding siblings ...)
  2018-06-25 12:03 ` [PATCH v3 24/24] ARM: dts: sun8i: r40: Enable HDMI output on BananaPi M2 Ultra Jernej Skrabec
@ 2018-06-25 12:07 ` Jernej Škrabec
  2018-06-25 16:43 ` Maxime Ripard
  2018-06-27 18:02 ` Maxime Ripard
  26 siblings, 0 replies; 87+ messages in thread
From: Jernej Škrabec @ 2018-06-25 12:07 UTC (permalink / raw)
  To: linux-sunxi
  Cc: maxime.ripard, wens, robh+dt, airlied, gustavo,
	maarten.lankhorst, seanpaul, mark.rutland, dri-devel, devicetree,
	linux-arm-kernel, linux-kernel, linux-clk

Dne ponedeljek, 25. junij 2018 ob 14:02:40 CEST je Jernej Skrabec napisal(a):
> This series adds support for R40 HDMI pipeline. It is a bit special
> than other already supported pipelines because it has additional unit
> called TCON TOP responsible for relationship configuration between
> mixers, TCONs and HDMI. Additionally, it has additional gates for DSI
> and TV TCONs, TV encoder clock settings and pin muxing between LCD
> and TV encoders.
> 
> However, it seems that TCON TOP will become a norm, since newer
> Allwinner SoCs like H6 also have this unit.
> 
> I tested different possible configurations:
> - mixer0 <> TCON-TV0 <> HDMI
> - mixer0 <> TCON-TV1 <> HDMI
> - mixer1 <> TCON-TV0 <> HDMI
> - mixer1 <> TCON-TV1 <> HDMI
> 
> Please review.
> 
> Best regards,
> Jernej
> 
> Changes from v2:
> - Collected tags
> - Exported drm_crtc_port_mask() symbol
> - Removed TCON TOP reset name
> - TCON TOP gates have now right parents
> - updated TCON TOP bindings
> - dropped new TCON quirk due TCON TOP rework

Forgot to add:
- in "drm/sun4i: Don't change clock bits in DW HDMI PHY driver" patch, only 
parent selection bit is reset to 0. Previously whole register was set to 0. 
Previous version broke H3 HDMI.

> 
> Changes from v1:
> - Split DT bindings patch and updated description
> - Split HDMI PHY patch
> - Move header file from TCON TOP patch to dt bindings patch
> - Added Rob reviewed-by tag
> - Used clk_hw_register_gate() instead of custom gate registration code
> - Reworked TCON TOP to be part of of-graph. Because of that, a lot of
>   new patches were added.
> - Droped mixer index quirk patch
> - Reworked TCON support for TCON TOP
> - Updated commit messages
> 
> Jernej Skrabec (24):
>   clk: sunxi-ng: r40: Add minimal rate for video PLLs
>   clk: sunxi-ng: r40: Allow setting parent rate to display related
>     clocks
>   clk: sunxi-ng: r40: Export video PLLs
>   dt-bindings: display: sunxi-drm: Add TCON TOP description
>   drm/sun4i: Add TCON TOP driver
>   drm/sun4i: Fix releasing node when enumerating enpoints
>   drm/sun4i: Split out code for enumerating endpoints in output port
>   drm/sun4i: Add support for traversing graph with TCON TOP
>   drm/sun4i: Don't skip TCONs if they don't have channel 0
>   drm/sun4i: tcon: Generalize engine search algorithm
>   drm/sun4i: Don't check for LVDS and RGB when TCON has only ch1
>   drm/sun4i: Don't check for panel or bridge on TV TCONs
>   dt-bindings: display: sun4i-drm: Add R40 mixer compatibles
>   drm/sun4i: Add support for R40 mixers
>   dt-bindings: display: sun4i-drm: Add description of A64 HDMI PHY
>   drm/sun4i: Enable DW HDMI PHY clock
>   drm/sun4i: Don't change clock bits in DW HDMI PHY driver
>   drm/sun4i: DW HDMI PHY: Add support for second PLL
>   drm/sun4i: Add support for second clock parent to DW HDMI PHY clk
>     driver
>   drm/sun4i: Add support for A64 HDMI PHY
>   drm: of: Export drm_crtc_port_mask()
>   drm/sun4i: DW HDMI: Expand algorithm for possible crtcs
>   ARM: dts: sun8i: r40: Add HDMI pipeline
>   ARM: dts: sun8i: r40: Enable HDMI output on BananaPi M2 Ultra
> 
>  .../bindings/display/sunxi/sun4i-drm.txt      |  62 +++-
>  .../boot/dts/sun8i-r40-bananapi-m2-ultra.dts  |  45 +++
>  arch/arm/boot/dts/sun8i-r40.dtsi              | 269 ++++++++++++++++
>  drivers/clk/sunxi-ng/ccu-sun8i-r40.c          |  58 ++--
>  drivers/clk/sunxi-ng/ccu-sun8i-r40.h          |   8 +-
>  drivers/gpu/drm/drm_of.c                      |   5 +-
>  drivers/gpu/drm/sun4i/Makefile                |   3 +-
>  drivers/gpu/drm/sun4i/sun4i_drv.c             | 121 +++++--
>  drivers/gpu/drm/sun4i/sun4i_tcon.c            |  66 ++--
>  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c         |  46 ++-
>  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h         |   8 +-
>  drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c        |  54 +++-
>  drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c    |  90 ++++--
>  drivers/gpu/drm/sun4i/sun8i_mixer.c           |  24 ++
>  drivers/gpu/drm/sun4i/sun8i_tcon_top.c        | 300 ++++++++++++++++++
>  drivers/gpu/drm/sun4i/sun8i_tcon_top.h        |  40 +++
>  include/drm/drm_of.h                          |   8 +
>  include/dt-bindings/clock/sun8i-r40-ccu.h     |   4 +
>  include/dt-bindings/clock/sun8i-tcon-top.h    |  11 +
>  19 files changed, 1100 insertions(+), 122 deletions(-)
>  create mode 100644 drivers/gpu/drm/sun4i/sun8i_tcon_top.c
>  create mode 100644 drivers/gpu/drm/sun4i/sun8i_tcon_top.h
>  create mode 100644 include/dt-bindings/clock/sun8i-tcon-top.h





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

* Re: [PATCH v3 03/24] clk: sunxi-ng: r40: Export video PLLs
  2018-06-25 12:02 ` [PATCH v3 03/24] clk: sunxi-ng: r40: Export video PLLs Jernej Skrabec
@ 2018-06-25 12:30   ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-25 12:30 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> Video PLLs need to be referenced in R40 DT as possible HDMI PHY parent.
>
> Export them.
>
> Reviewed-by: Rob Herring <robh@kernel.org>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

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

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

* Re: [PATCH v3 00/24] Add support for R40 HDMI pipeline
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (24 preceding siblings ...)
  2018-06-25 12:07 ` [linux-sunxi] [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Škrabec
@ 2018-06-25 16:43 ` Maxime Ripard
  2018-06-27 18:02 ` Maxime Ripard
  26 siblings, 0 replies; 87+ messages in thread
From: Maxime Ripard @ 2018-06-25 16:43 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: wens, robh+dt, airlied, gustavo, maarten.lankhorst, seanpaul,
	mark.rutland, dri-devel, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, linux-sunxi

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

On Mon, Jun 25, 2018 at 02:02:40PM +0200, Jernej Skrabec wrote:
> This series adds support for R40 HDMI pipeline. It is a bit special
> than other already supported pipelines because it has additional unit
> called TCON TOP responsible for relationship configuration between
> mixers, TCONs and HDMI. Additionally, it has additional gates for DSI
> and TV TCONs, TV encoder clock settings and pin muxing between LCD
> and TV encoders.
> 
> However, it seems that TCON TOP will become a norm, since newer
> Allwinner SoCs like H6 also have this unit.
> 
> I tested different possible configurations:
> - mixer0 <> TCON-TV0 <> HDMI
> - mixer0 <> TCON-TV1 <> HDMI
> - mixer1 <> TCON-TV0 <> HDMI
> - mixer1 <> TCON-TV1 <> HDMI
> 
> Please review.

This looks all fine by me, thanks!

I'd still like some more review (by Chen-Yu and Rob) before applying
it, but you can add my Acked-by for the next round if needed.

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

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

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

* Re: [PATCH v3 04/24] dt-bindings: display: sunxi-drm: Add TCON TOP description
  2018-06-25 12:02 ` [PATCH v3 04/24] dt-bindings: display: sunxi-drm: Add TCON TOP description Jernej Skrabec
@ 2018-06-25 17:33   ` Rob Herring
  0 siblings, 0 replies; 87+ messages in thread
From: Rob Herring @ 2018-06-25 17:33 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: maxime.ripard, wens, airlied, gustavo, maarten.lankhorst,
	seanpaul, mark.rutland, dri-devel, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, linux-sunxi

On Mon, Jun 25, 2018 at 02:02:44PM +0200, Jernej Skrabec wrote:
> TCON TOP main purpose is to configure whole display pipeline. It
> determines relationships between mixers and TCONs, selects source TCON
> for HDMI, muxes LCD and TV encoder GPIO output, selects TV encoder
> clock source and contains additional TV TCON and DSI gates.
> 
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  .../bindings/display/sunxi/sun4i-drm.txt      | 56 +++++++++++++++++++
>  include/dt-bindings/clock/sun8i-tcon-top.h    | 11 ++++
>  2 files changed, 67 insertions(+)
>  create mode 100644 include/dt-bindings/clock/sun8i-tcon-top.h

Reviewed-by: Rob Herring <robh@kernel.org>


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

* Re: [PATCH v3 00/24] Add support for R40 HDMI pipeline
  2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
                   ` (25 preceding siblings ...)
  2018-06-25 16:43 ` Maxime Ripard
@ 2018-06-27 18:02 ` Maxime Ripard
  2018-06-27 19:50   ` Maxime Ripard
  26 siblings, 1 reply; 87+ messages in thread
From: Maxime Ripard @ 2018-06-27 18:02 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: wens, robh+dt, airlied, gustavo, maarten.lankhorst, seanpaul,
	mark.rutland, dri-devel, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, linux-sunxi

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

On Mon, Jun 25, 2018 at 02:02:40PM +0200, Jernej Skrabec wrote:
> This series adds support for R40 HDMI pipeline. It is a bit special
> than other already supported pipelines because it has additional unit
> called TCON TOP responsible for relationship configuration between
> mixers, TCONs and HDMI. Additionally, it has additional gates for DSI
> and TV TCONs, TV encoder clock settings and pin muxing between LCD
> and TV encoders.
> 
> However, it seems that TCON TOP will become a norm, since newer
> Allwinner SoCs like H6 also have this unit.
> 
> I tested different possible configurations:
> - mixer0 <> TCON-TV0 <> HDMI
> - mixer0 <> TCON-TV1 <> HDMI
> - mixer1 <> TCON-TV0 <> HDMI
> - mixer1 <> TCON-TV1 <> HDMI
> 
> Please review.

I just applied it. It didn't apply cleanly, so please make sure it
does next time, or at least state what the dependencies are.

Thanks!
Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

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

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

* Re: [PATCH v3 00/24] Add support for R40 HDMI pipeline
  2018-06-27 18:02 ` Maxime Ripard
@ 2018-06-27 19:50   ` Maxime Ripard
  2018-06-27 20:25     ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Maxime Ripard @ 2018-06-27 19:50 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: wens, robh+dt, airlied, gustavo, maarten.lankhorst, seanpaul,
	mark.rutland, dri-devel, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, linux-sunxi

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

1;5202;0c
On Wed, Jun 27, 2018 at 08:02:15PM +0200, Maxime Ripard wrote:
> On Mon, Jun 25, 2018 at 02:02:40PM +0200, Jernej Skrabec wrote:
> > This series adds support for R40 HDMI pipeline. It is a bit special
> > than other already supported pipelines because it has additional unit
> > called TCON TOP responsible for relationship configuration between
> > mixers, TCONs and HDMI. Additionally, it has additional gates for DSI
> > and TV TCONs, TV encoder clock settings and pin muxing between LCD
> > and TV encoders.
> > 
> > However, it seems that TCON TOP will become a norm, since newer
> > Allwinner SoCs like H6 also have this unit.
> > 
> > I tested different possible configurations:
> > - mixer0 <> TCON-TV0 <> HDMI
> > - mixer0 <> TCON-TV1 <> HDMI
> > - mixer1 <> TCON-TV0 <> HDMI
> > - mixer1 <> TCON-TV1 <> HDMI
> > 
> > Please review.
> 
> I just applied it. It didn't apply cleanly, so please make sure it
> does next time, or at least state what the dependencies are.

And it didn't compile either, because of the compile error that was
reported to the previous version by kbuild... Those shouldn't be
ignored and simply fixed.

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

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

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

* Re: [PATCH v3 00/24] Add support for R40 HDMI pipeline
  2018-06-27 19:50   ` Maxime Ripard
@ 2018-06-27 20:25     ` Jernej Škrabec
  2018-06-28  8:41       ` Maxime Ripard
  0 siblings, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-06-27 20:25 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: wens, robh+dt, airlied, gustavo, maarten.lankhorst, seanpaul,
	mark.rutland, dri-devel, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, linux-sunxi

Dne sreda, 27. junij 2018 ob 21:50:43 CEST je Maxime Ripard napisal(a):
> 1;5202;0c
> 
> On Wed, Jun 27, 2018 at 08:02:15PM +0200, Maxime Ripard wrote:
> > On Mon, Jun 25, 2018 at 02:02:40PM +0200, Jernej Skrabec wrote:
> > > This series adds support for R40 HDMI pipeline. It is a bit special
> > > than other already supported pipelines because it has additional unit
> > > called TCON TOP responsible for relationship configuration between
> > > mixers, TCONs and HDMI. Additionally, it has additional gates for DSI
> > > and TV TCONs, TV encoder clock settings and pin muxing between LCD
> > > and TV encoders.
> > > 
> > > However, it seems that TCON TOP will become a norm, since newer
> > > Allwinner SoCs like H6 also have this unit.
> > > 
> > > I tested different possible configurations:
> > > - mixer0 <> TCON-TV0 <> HDMI
> > > - mixer0 <> TCON-TV1 <> HDMI
> > > - mixer1 <> TCON-TV0 <> HDMI
> > > - mixer1 <> TCON-TV1 <> HDMI
> > > 
> > > Please review.
> > 
> > I just applied it. It didn't apply cleanly, so please make sure it
> > does next time, or at least state what the dependencies are.
> 
> And it didn't compile either, because of the compile error that was
> reported to the previous version by kbuild... Those shouldn't be
> ignored and simply fixed.

Sorry about that. I forgot to rebase and had same linux-next base for all 3 
versions.

I actually take a look at that kbuild message, but it just didn't make much 
sense and it worked for me without issues. Merge conflicts would explain that.

Best regards,
Jernej





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

* Re: [PATCH v3 05/24] drm/sun4i: Add TCON TOP driver
  2018-06-25 12:02 ` [PATCH v3 05/24] drm/sun4i: Add TCON TOP driver Jernej Skrabec
@ 2018-06-28  1:47   ` Chen-Yu Tsai
  2018-06-29 19:09     ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  1:47 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Hi,

So I'm late to the party, but...

On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> As already described in DT binding, TCON TOP is responsible for
> configuring display pipeline. In this initial driver focus is on HDMI
> pipeline, so TVE and LCD configuration is not implemented.
>
> Implemented features:
> - HDMI source selection
> - clock driver (TCON and DSI gating)
> - connecting mixers and TCONS
>
> Something similar also existed in previous SoCs, except that it was part
> of first TCON.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  drivers/gpu/drm/sun4i/Makefile         |   3 +-
>  drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 300 +++++++++++++++++++++++++
>  drivers/gpu/drm/sun4i/sun8i_tcon_top.h |  40 ++++
>  3 files changed, 342 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/sun4i/sun8i_tcon_top.c
>  create mode 100644 drivers/gpu/drm/sun4i/sun8i_tcon_top.h
>
> diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile
> index 2589f4acd5ae..09fbfd6304ba 100644
> --- a/drivers/gpu/drm/sun4i/Makefile
> +++ b/drivers/gpu/drm/sun4i/Makefile
> @@ -16,7 +16,8 @@ sun8i-drm-hdmi-y              += sun8i_hdmi_phy_clk.o
>
>  sun8i-mixer-y                  += sun8i_mixer.o sun8i_ui_layer.o \
>                                    sun8i_vi_layer.o sun8i_ui_scaler.o \
> -                                  sun8i_vi_scaler.o sun8i_csc.o
> +                                  sun8i_vi_scaler.o sun8i_csc.o \
> +                                  sun8i_tcon_top.o
>
>  sun4i-tcon-y                   += sun4i_crtc.o
>  sun4i-tcon-y                   += sun4i_dotclock.o
> diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
> new file mode 100644
> index 000000000000..8da0460e0028
> --- /dev/null
> +++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
> @@ -0,0 +1,300 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/* Copyright (c) 2018 Jernej Skrabec <jernej.skrabec@siol.net> */
> +
> +#include <drm/drmP.h>
> +
> +#include <dt-bindings/clock/sun8i-tcon-top.h>
> +
> +#include <linux/bitfield.h>
> +#include <linux/component.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/of_graph.h>
> +#include <linux/platform_device.h>
> +
> +#include "sun8i_tcon_top.h"
> +
> +static int sun8i_tcon_top_get_connected_ep_id(struct device_node *node,
> +                                             int port_id)
> +{
> +       struct device_node *ep, *remote, *port;
> +       struct of_endpoint endpoint;
> +
> +       port = of_graph_get_port_by_id(node, port_id);
> +       if (!port)
> +               return -ENOENT;
> +
> +       for_each_available_child_of_node(port, ep) {
> +               remote = of_graph_get_remote_port_parent(ep);
> +               if (!remote)
> +                       continue;
> +
> +               if (of_device_is_available(remote)) {
> +                       of_graph_parse_endpoint(ep, &endpoint);
> +
> +                       of_node_put(remote);
> +
> +                       return endpoint.id;
> +               }
> +
> +               of_node_put(remote);
> +       }
> +
> +       return -ENOENT;
> +}
> +
> +static struct clk_hw *sun8i_tcon_top_register_gate(struct device *dev,
> +                                                  struct clk *parent,
> +                                                  void __iomem *regs,
> +                                                  spinlock_t *lock,
> +                                                  u8 bit, int name_index)
> +{
> +       const char *clk_name, *parent_name;
> +       int ret;
> +
> +       parent_name = __clk_get_name(parent);

You can simply pass in the binding clock name, and have

    index = of_property_match_string(np, "clock-names", name);
    parent_name = of_clk_get_parent_name(dev->of_node, index);

> +       ret = of_property_read_string_index(dev->of_node,
> +                                           "clock-output-names", name_index,
> +                                           &clk_name);
> +       if (ret)
> +               return ERR_PTR(ret);
> +
> +       return clk_hw_register_gate(dev, clk_name, parent_name,
> +                                   CLK_SET_RATE_PARENT,
> +                                   regs + TCON_TOP_GATE_SRC_REG,
> +                                   bit, 0, lock);
> +};
> +
> +static int sun8i_tcon_top_bind(struct device *dev, struct device *master,
> +                              void *data)
> +{
> +       struct platform_device *pdev = to_platform_device(dev);
> +       struct clk *dsi, *tcon_tv0, *tcon_tv1, *tve0, *tve1;
> +       struct clk_hw_onecell_data *clk_data;
> +       struct sun8i_tcon_top *tcon_top;
> +       bool mixer0_unused = false;
> +       struct resource *res;
> +       void __iomem *regs;
> +       int ret, i, id;
> +       u32 val;
> +
> +       tcon_top = devm_kzalloc(dev, sizeof(*tcon_top), GFP_KERNEL);
> +       if (!tcon_top)
> +               return -ENOMEM;
> +
> +       clk_data = devm_kzalloc(dev, sizeof(*clk_data) +
> +                               sizeof(*clk_data->hws) * CLK_NUM,
> +                               GFP_KERNEL);
> +       if (!clk_data)
> +               return -ENOMEM;
> +       tcon_top->clk_data = clk_data;
> +
> +       spin_lock_init(&tcon_top->reg_lock);
> +
> +       tcon_top->rst = devm_reset_control_get(dev, NULL);
> +       if (IS_ERR(tcon_top->rst)) {
> +               dev_err(dev, "Couldn't get our reset line\n");
> +               return PTR_ERR(tcon_top->rst);
> +       }
> +
> +       tcon_top->bus = devm_clk_get(dev, "bus");
> +       if (IS_ERR(tcon_top->bus)) {
> +               dev_err(dev, "Couldn't get the bus clock\n");
> +               return PTR_ERR(tcon_top->bus);
> +       }
> +
> +       dsi = devm_clk_get(dev, "dsi");
> +       if (IS_ERR(dsi)) {
> +               dev_err(dev, "Couldn't get the dsi clock\n");
> +               return PTR_ERR(dsi);
> +       }
> +
> +       tcon_tv0 = devm_clk_get(dev, "tcon-tv0");
> +       if (IS_ERR(tcon_tv0)) {
> +               dev_err(dev, "Couldn't get the tcon-tv0 clock\n");
> +               return PTR_ERR(tcon_tv0);
> +       }
> +
> +       tcon_tv1 = devm_clk_get(dev, "tcon-tv1");
> +       if (IS_ERR(tcon_tv1)) {
> +               dev_err(dev, "Couldn't get the tcon-tv1 clock\n");
> +               return PTR_ERR(tcon_tv1);
> +       }
> +
> +       tve0 = devm_clk_get(dev, "tve0");
> +       if (IS_ERR(tve0)) {
> +               dev_err(dev, "Couldn't get the tve0 clock\n");
> +               return PTR_ERR(tve0);
> +       }
> +
> +       tve1 = devm_clk_get(dev, "tve1");
> +       if (IS_ERR(tve1)) {
> +               dev_err(dev, "Couldn't get the tve1 clock\n");
> +               return PTR_ERR(tve1);
> +       }

So you don't actually have to hold references to the parent clocks.

ChenYu

> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       regs = devm_ioremap_resource(dev, res);
> +       if (IS_ERR(regs))
> +               return PTR_ERR(regs);
> +
> +       ret = reset_control_deassert(tcon_top->rst);
> +       if (ret) {
> +               dev_err(dev, "Could not deassert ctrl reset control\n");
> +               return ret;
> +       }
> +
> +       ret = clk_prepare_enable(tcon_top->bus);
> +       if (ret) {
> +               dev_err(dev, "Could not enable bus clock\n");
> +               goto err_assert_reset;
> +       }
> +
> +       val = 0;
> +
> +       /* check if HDMI mux output is connected */
> +       if (sun8i_tcon_top_get_connected_ep_id(dev->of_node, 5) >= 0) {
> +               /* find HDMI input endpoint id, if it is connected at all*/
> +               id = sun8i_tcon_top_get_connected_ep_id(dev->of_node, 4);
> +               if (id >= 0)
> +                       val = FIELD_PREP(TCON_TOP_HDMI_SRC_MSK, id + 1);
> +               else
> +                       DRM_DEBUG_DRIVER("TCON TOP HDMI input is not connected\n");
> +       } else {
> +               DRM_DEBUG_DRIVER("TCON TOP HDMI output is not connected\n");
> +       }
> +
> +       writel(val, regs + TCON_TOP_GATE_SRC_REG);
> +
> +       val = 0;
> +
> +       /* process mixer0 mux output */
> +       id = sun8i_tcon_top_get_connected_ep_id(dev->of_node, 1);
> +       if (id >= 0) {
> +               val = FIELD_PREP(TCON_TOP_PORT_DE0_MSK, id);
> +       } else {
> +               DRM_DEBUG_DRIVER("TCON TOP mixer0 output is not connected\n");
> +               mixer0_unused = true;
> +       }
> +
> +       /* process mixer1 mux output */
> +       id = sun8i_tcon_top_get_connected_ep_id(dev->of_node, 3);
> +       if (id >= 0) {
> +               val |= FIELD_PREP(TCON_TOP_PORT_DE1_MSK, id);
> +
> +               /*
> +                * mixer0 mux has priority over mixer1 mux. We have to
> +                * make sure mixer0 doesn't overtake TCON from mixer1.
> +                */
> +               if (mixer0_unused && id == 0)
> +                       val |= FIELD_PREP(TCON_TOP_PORT_DE0_MSK, 1);
> +       } else {
> +               DRM_DEBUG_DRIVER("TCON TOP mixer1 output is not connected\n");
> +       }
> +
> +       writel(val, regs + TCON_TOP_PORT_SEL_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
> +        * we leave this fixed to TCON TV, since TVE driver for R40 is not yet
> +        * implemented. Once it is, graph needs to be traversed to determine
> +        * if TVE is active on each TCON TV. If it is, mux should be switched
> +        * to TVE clock parent.
> +        */
> +       clk_data->hws[CLK_TCON_TOP_TV0] =
> +               sun8i_tcon_top_register_gate(dev, tcon_tv0, regs,
> +                                            &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);
> +
> +       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);
> +
> +       for (i = 0; i < CLK_NUM; i++)
> +               if (IS_ERR(clk_data->hws[i])) {
> +                       ret = PTR_ERR(clk_data->hws[i]);
> +                       goto err_unregister_gates;
> +               }
> +
> +       clk_data->num = CLK_NUM;
> +
> +       ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
> +                                    clk_data);
> +       if (ret)
> +               goto err_unregister_gates;
> +
> +       dev_set_drvdata(dev, tcon_top);
> +
> +       return 0;
> +
> +err_unregister_gates:
> +       for (i = 0; i < CLK_NUM; i++)
> +               if (clk_data->hws[i])
> +                       clk_hw_unregister_gate(clk_data->hws[i]);
> +       clk_disable_unprepare(tcon_top->bus);
> +err_assert_reset:
> +       reset_control_assert(tcon_top->rst);
> +
> +       return ret;
> +}
> +
> +static void sun8i_tcon_top_unbind(struct device *dev, struct device *master,
> +                                 void *data)
> +{
> +       struct sun8i_tcon_top *tcon_top = dev_get_drvdata(dev);
> +       struct clk_hw_onecell_data *clk_data = tcon_top->clk_data;
> +       int i;
> +
> +       of_clk_del_provider(dev->of_node);
> +       for (i = 0; i < CLK_NUM; i++)
> +               clk_hw_unregister_gate(clk_data->hws[i]);
> +
> +       clk_disable_unprepare(tcon_top->bus);
> +       reset_control_assert(tcon_top->rst);
> +}
> +
> +static const struct component_ops sun8i_tcon_top_ops = {
> +       .bind   = sun8i_tcon_top_bind,
> +       .unbind = sun8i_tcon_top_unbind,
> +};
> +
> +static int sun8i_tcon_top_probe(struct platform_device *pdev)
> +{
> +       return component_add(&pdev->dev, &sun8i_tcon_top_ops);
> +}
> +
> +static int sun8i_tcon_top_remove(struct platform_device *pdev)
> +{
> +       component_del(&pdev->dev, &sun8i_tcon_top_ops);
> +
> +       return 0;
> +}
> +
> +/* 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" },
> +       { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, sun8i_tcon_top_of_table);
> +EXPORT_SYMBOL(sun8i_tcon_top_of_table);
> +
> +static struct platform_driver sun8i_tcon_top_platform_driver = {
> +       .probe          = sun8i_tcon_top_probe,
> +       .remove         = sun8i_tcon_top_remove,
> +       .driver         = {
> +               .name           = "sun8i-tcon-top",
> +               .of_match_table = sun8i_tcon_top_of_table,
> +       },
> +};
> +module_platform_driver(sun8i_tcon_top_platform_driver);
> +
> +MODULE_AUTHOR("Jernej Skrabec <jernej.skrabec@siol.net>");
> +MODULE_DESCRIPTION("Allwinner R40 TCON TOP driver");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.h b/drivers/gpu/drm/sun4i/sun8i_tcon_top.h
> new file mode 100644
> index 000000000000..39838bbfeaee
> --- /dev/null
> +++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.h
> @@ -0,0 +1,40 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/* Copyright (c) 2018 Jernej Skrabec <jernej.skrabec@siol.net> */
> +
> +#ifndef _SUN8I_TCON_TOP_H_
> +#define _SUN8I_TCON_TOP_H_
> +
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/reset.h>
> +#include <linux/spinlock.h>
> +
> +#define TCON_TOP_TCON_TV_SETUP_REG     0x00
> +
> +#define TCON_TOP_PORT_SEL_REG          0x1C
> +#define TCON_TOP_PORT_DE0_MSK                  GENMASK(1, 0)
> +#define TCON_TOP_PORT_DE1_MSK                  GENMASK(5, 4)
> +
> +#define TCON_TOP_GATE_SRC_REG          0x20
> +#define TCON_TOP_HDMI_SRC_MSK                  GENMASK(29, 28)
> +#define TCON_TOP_TCON_TV1_GATE                 24
> +#define TCON_TOP_TCON_TV0_GATE                 20
> +#define TCON_TOP_TCON_DSI_GATE                 16
> +
> +#define CLK_NUM                                        3
> +
> +struct sun8i_tcon_top {
> +       struct clk                      *bus;
> +       struct clk_hw_onecell_data      *clk_data;
> +       struct reset_control            *rst;
> +
> +       /*
> +        * spinlock is used to synchronize access to same
> +        * register where multiple clock gates can be set.
> +        */
> +       spinlock_t                      reg_lock;
> +};
> +
> +extern const struct of_device_id sun8i_tcon_top_of_table[];
> +
> +#endif /* _SUN8I_TCON_TOP_H_ */
> --
> 2.18.0
>

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

* Re: [PATCH v3 09/24] drm/sun4i: Don't skip TCONs if they don't have channel 0
  2018-06-25 12:02 ` [PATCH v3 09/24] drm/sun4i: Don't skip TCONs if they don't have channel 0 Jernej Skrabec
@ 2018-06-28  1:51   ` Chen-Yu Tsai
  2018-06-28  4:45     ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  1:51 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> TV TCONs (channel 1 only) are always connected to TV or HDMI encoder.
> Because of that, all output endpoints on such TCON node will point to a
> encoder which is part of component framework.
>
> Correct current graph traversing algorithm in such way that it doesn't
> skip output enpoints with id 0 on TV TCONs.

No. Our bindings say that endpoint 0 _is_ channel 0. For TCONs that don't
have channel 0, it must be skipped.

ChenYu

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

* Re: [linux-sunxi] [PATCH v3 06/24] drm/sun4i: Fix releasing node when enumerating enpoints
  2018-06-25 12:02 ` [PATCH v3 06/24] drm/sun4i: Fix releasing node when enumerating enpoints Jernej Skrabec
@ 2018-06-28  1:53   ` Chen-Yu Tsai
  2018-06-29 19:15     ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  1:53 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> sun4i_drv_add_endpoints() has a memory leak since it uses of_node_put()
> when remote is equal to NULL and does nothing when remote has a valid
> pointer.
>
> Invert the logic to fix memory leak.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

Given this is a fix, it should have Fixes and stable tags.

ChenYu

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

* Re: [PATCH v3 08/24] drm/sun4i: Add support for traversing graph with TCON TOP
  2018-06-25 12:02 ` [PATCH v3 08/24] drm/sun4i: Add support for traversing graph with TCON TOP Jernej Skrabec
@ 2018-06-28  1:57   ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  1:57 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> TCON TOP is different from other nodes in graph by having 3 input and 3
> output ports. Additionally, connection to TV TCON might lead back to
> HDMI mux input port, creating loops.
>
> Add support for traversing such graph.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

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

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

* Re: [linux-sunxi] [PATCH v3 07/24] drm/sun4i: Split out code for enumerating endpoints in output port
  2018-06-25 12:02 ` [PATCH v3 07/24] drm/sun4i: Split out code for enumerating endpoints in output port Jernej Skrabec
@ 2018-06-28  1:57   ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  1:57 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> Until now, each node has one input port and one output port. However,
> with TCON TOP this is no longer true. It has 3 input and 3 output ports.
>
> In order to prepare to this situation, split out the code which checks
> all endpoints in input port and adds available components to fifo.
>
> This patch doesn't do any functional change.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

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

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

* Re: [PATCH v3 10/24] drm/sun4i: tcon: Generalize engine search algorithm
  2018-06-25 12:02 ` [PATCH v3 10/24] drm/sun4i: tcon: Generalize engine search algorithm Jernej Skrabec
@ 2018-06-28  2:06   ` Chen-Yu Tsai
  2018-06-28  4:48     ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  2:06 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> Current "old" method to find engine worked pretty well for DE2. However,
> it doesn't work when TCON TOP is between  mixer (engine) and TCON. TCON
> TOP has multiple input ports, but current engine search algorithm
> expects only one.
>
> This can be fixed by first looking for output port id and selecting
> matching input by subtracting 1 for the next round. This work even if
> there is only one input and output.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  drivers/gpu/drm/sun4i/sun4i_tcon.c | 22 ++++++++++++++++++----
>  1 file changed, 18 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> index 08747fc3ee71..264bcc43da11 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> @@ -791,12 +791,14 @@ static int sun4i_tcon_init_regmap(struct device *dev,
>   */
>  static struct sunxi_engine *
>  sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv,
> -                               struct device_node *node)
> +                               struct device_node *node,
> +                               u32 port_id)
>  {
>         struct device_node *port, *ep, *remote;
>         struct sunxi_engine *engine = ERR_PTR(-EINVAL);
> +       u32 reg = 0;
>
> -       port = of_graph_get_port_by_id(node, 0);
> +       port = of_graph_get_port_by_id(node, port_id);
>         if (!port)
>                 return ERR_PTR(-EINVAL);
>
> @@ -826,8 +828,20 @@ sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv,
>                 if (remote == engine->node)
>                         goto out_put_remote;
>
> +       /*
> +        * According to device tree binding input ports have even id
> +        * number and output ports have odd id. Since component with
> +        * more than one input and one output (TCON TOP) exits, correct
> +        * remote input id has to be calculated by subtracting 1 from
> +        * remote output id. If this for some reason can't be done, 0
> +        * is used as input port id.
> +        */

You need to call

    of_node_put(port);

to drop the reference to the original port.

Otherwise,

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

> +       port = of_graph_get_remote_port(ep);
> +       if (!of_property_read_u32(port, "reg", &reg) && reg > 0)
> +               reg -= 1;
> +
>         /* keep looking through upstream ports */
> -       engine = sun4i_tcon_find_engine_traverse(drv, remote);
> +       engine = sun4i_tcon_find_engine_traverse(drv, remote, reg);
>
>  out_put_remote:
>         of_node_put(remote);
> @@ -950,7 +964,7 @@ static struct sunxi_engine *sun4i_tcon_find_engine(struct sun4i_drv *drv,
>
>         /* Fallback to old method by traversing input endpoints */
>         of_node_put(port);
> -       return sun4i_tcon_find_engine_traverse(drv, node);
> +       return sun4i_tcon_find_engine_traverse(drv, node, 0);
>  }
>
>  static int sun4i_tcon_bind(struct device *dev, struct device *master,
> --
> 2.18.0
>

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

* Re: [PATCH v3 11/24] drm/sun4i: Don't check for LVDS and RGB when TCON has only ch1
  2018-06-25 12:02 ` [PATCH v3 11/24] drm/sun4i: Don't check for LVDS and RGB when TCON has only ch1 Jernej Skrabec
@ 2018-06-28  2:08   ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  2:08 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> LVDS and RGB interfaces are always connected to TCONs which have channel
> 0. It doesn't make sense to try to init them on TV TCONs.
>
> Add a check if TCON has channel 0 before trying to init LVDS or RGB
> interface.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

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

Though I think at some point we could just have separate functions
to handle channel 0 and channel 1.

ChenYu

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

* Re: [PATCH v3 12/24] drm/sun4i: Don't check for panel or bridge on TV TCONs
  2018-06-25 12:02 ` [PATCH v3 12/24] drm/sun4i: Don't check for panel or bridge on TV TCONs Jernej Skrabec
@ 2018-06-28  2:17   ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  2:17 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> TV TCONs are always connected to TV or HDMI encoder, so it doesn't make
> sense to check if panel or bridge is connected to them.
>
> Check if TCON has channel 0 and only then check for connected panel or
> bridges.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  drivers/gpu/drm/sun4i/sun4i_tcon.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> index 761687ebacba..a41c7bb0d557 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> @@ -1178,13 +1178,19 @@ static const struct component_ops sun4i_tcon_ops = {
>  static int sun4i_tcon_probe(struct platform_device *pdev)
>  {
>         struct device_node *node = pdev->dev.of_node;
> +       const struct sun4i_tcon_quirks *quirks;
>         struct drm_bridge *bridge;
>         struct drm_panel *panel;
>         int ret;
>
> -       ret = drm_of_find_panel_or_bridge(node, 1, 0, &panel, &bridge);
> -       if (ret == -EPROBE_DEFER)
> -               return ret;
> +       quirks = of_device_get_match_data(&pdev->dev);
> +
> +       /* panels and bridges are present only on TCONs with channel 0 */
> +       if (quirks->has_channel_0) {

This is implied by the device tree binding. TCONs that don't have panels
or bridges will have endpoint 0 unconnected, and drm_of_find_panel_or_bridge
will return -ENODEV.

It doesn't hurt to skip the check though.

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

> +               ret = drm_of_find_panel_or_bridge(node, 1, 0, &panel, &bridge);
> +               if (ret == -EPROBE_DEFER)
> +                       return ret;
> +       }
>
>         return component_add(&pdev->dev, &sun4i_tcon_ops);
>  }
> --
> 2.18.0
>

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

* Re: [PATCH v3 13/24] dt-bindings: display: sun4i-drm: Add R40 mixer compatibles
  2018-06-25 12:02 ` [PATCH v3 13/24] dt-bindings: display: sun4i-drm: Add R40 mixer compatibles Jernej Skrabec
@ 2018-06-28  2:17   ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  2:17 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> R40 DE2 mixers are similar to those found in A83T, except it needs
> different clock settings.
>
> Add a compatibles for them.
>
> Acked-by: Rob Herring <robh@kernel.org>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

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

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

* Re: [PATCH v3 14/24] drm/sun4i: Add support for R40 mixers
  2018-06-25 12:02 ` [PATCH v3 14/24] drm/sun4i: Add support for R40 mixers Jernej Skrabec
@ 2018-06-28  2:18   ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  2:18 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> Both mixers have similar capabilities as others SoCs with DE2.
>
> First mixer has 1 VI and 3 UI planes and supports HW scaling on all
> planes.
>
> Second mixer has 1 VI and 1 UI planes and also supports HW scaling on
> all planes.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

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

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

* Re: [PATCH v3 15/24] dt-bindings: display: sun4i-drm: Add description of A64 HDMI PHY
  2018-06-25 12:02 ` [PATCH v3 15/24] dt-bindings: display: sun4i-drm: Add description of A64 HDMI PHY Jernej Skrabec
@ 2018-06-28  2:19   ` Chen-Yu Tsai
  2018-06-28  4:51     ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  2:19 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> A64 HDMI PHY is similar to H3 HDMI PHY except it has two possible PLL
> clock parents. It is compatible to other HDMI PHYs, like that found in
> R40.
>
> Acked-by: Rob Herring <robh@kernel.org>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> index 84fe38dbb900..dc83f21ef188 100644
> --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> @@ -101,6 +101,7 @@ DWC HDMI PHY
>
>  Required properties:
>    - compatible: value must be one of:
> +    * allwinner,sun50i-a64-hdmi-phy
>      * allwinner,sun8i-a83t-hdmi-phy
>      * allwinner,sun8i-h3-hdmi-phy

Nit: the list is sorted by family first, then SoC name, so it should
be the last on the list.

Otherwise,

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

>    - reg: base address and size of memory-mapped region
> @@ -111,8 +112,9 @@ Required properties:
>    - resets: phandle to the reset controller driving the PHY
>    - reset-names: must be "phy"
>
> -H3 HDMI PHY requires additional clock:
> +H3 and A64 HDMI PHY require additional clocks:
>    - pll-0: parent of phy clock
> +  - pll-1: second possible phy clock parent (A64 only)
>
>  TV Encoder
>  ----------
> --
> 2.18.0
>

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

* Re: [PATCH v3 16/24] drm/sun4i: Enable DW HDMI PHY clock
  2018-06-25 12:02 ` [PATCH v3 16/24] drm/sun4i: Enable DW HDMI PHY clock Jernej Skrabec
@ 2018-06-28  2:22   ` Chen-Yu Tsai
  2018-06-28  4:52     ` Jernej Škrabec
  2018-06-29 19:19     ` Jernej Škrabec
  0 siblings, 2 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  2:22 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> Current DW HDMI PHY code never prepares and enables PHY clock after it is
> created. It's just used as it is. This may work in some cases, but it's
> clearly wrong. Fix it by adding proper calls to enable/disable PHY
> clock.
>
> Fixes: 4f86e81748fe ("drm/sun4i: Add support for H3 HDMI PHY variant")
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

So why does it work on the H3? Because there's only one PLL that the whole
display pipeline uses?

We should probably tag this for stable. So,

Cc: <stable@vger.kernel.org>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>

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

* Re: [PATCH v3 17/24] drm/sun4i: Don't change clock bits in DW HDMI PHY driver
  2018-06-25 12:02 ` [PATCH v3 17/24] drm/sun4i: Don't change clock bits in DW HDMI PHY driver Jernej Skrabec
@ 2018-06-28  2:24   ` Chen-Yu Tsai
  2018-06-29 19:23     ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  2:24 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> DW HDMI PHY driver and PHY clock driver share same registers. Make sure
> that DW HDMI PHY setup code doesn't change any clock related bits.
> During initialization, set PHY PLL parent bit to 0.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

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

and maybe a fixes tag?

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

* Re: [PATCH v3 18/24] drm/sun4i: DW HDMI PHY: Add support for second PLL
  2018-06-25 12:02 ` [PATCH v3 18/24] drm/sun4i: DW HDMI PHY: Add support for second PLL Jernej Skrabec
@ 2018-06-28  2:25   ` Chen-Yu Tsai
  2018-06-28  4:56     ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  2:25 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> Some DW HDMI PHYs, like those found in A64 and R40 SoCs, can select
> between two clock parents.
>
> Add code which reads second PLL from DT.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

This patch by itself does not do anything. It should be merged with the
next one.

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

* Re: [linux-sunxi] [PATCH v3 19/24] drm/sun4i: Add support for second clock parent to DW HDMI PHY clk driver
  2018-06-25 12:02 ` [PATCH v3 19/24] drm/sun4i: Add support for second clock parent to DW HDMI PHY clk driver Jernej Skrabec
@ 2018-06-28  2:30   ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  2:30 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> Expand HDMI PHY clock driver to support second clock parent.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

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

> ---
>  drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h      |  4 +-
>  drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c     |  3 +-
>  drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c | 90 ++++++++++++++++------
>  3 files changed, 73 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
> index 46a3aa6a53a9..aadbe0a10b0c 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
> +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
> @@ -99,6 +99,7 @@
>  #define SUN8I_HDMI_PHY_PLL_CFG1_LDO1_EN                BIT(28)
>  #define SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33       BIT(27)
>  #define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK   BIT(26)
> +#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT 26
>  #define SUN8I_HDMI_PHY_PLL_CFG1_PLLEN          BIT(25)
>  #define SUN8I_HDMI_PHY_PLL_CFG1_LDO_VSET(x)    ((x) << 22)
>  #define SUN8I_HDMI_PHY_PLL_CFG1_UNKNOWN(x)     ((x) << 20)
> @@ -190,6 +191,7 @@ 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);
>
> -int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev);
> +int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev,
> +                        bool second_parent);
>
>  #endif /* _SUN8I_DW_HDMI_H_ */
> diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> index f0877b3f67e7..aea46b08f127 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
> @@ -491,7 +491,8 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
>                         }
>                 }
>
> -               ret = sun8i_phy_clk_create(phy, dev);
> +               ret = sun8i_phy_clk_create(phy, dev,
> +                                          phy->variant->has_second_pll);
>                 if (ret) {
>                         dev_err(dev, "Couldn't create the PHY clock\n");
>                         goto err_put_clk_pll1;
> diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
> index faea449812f8..a4d31fe3abff 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
> @@ -22,35 +22,45 @@ static int sun8i_phy_clk_determine_rate(struct clk_hw *hw,
>  {
>         unsigned long rate = req->rate;
>         unsigned long best_rate = 0;
> +       struct clk_hw *best_parent = NULL;
>         struct clk_hw *parent;
>         int best_div = 1;
> -       int i;
> +       int i, p;
>
> -       parent = clk_hw_get_parent(hw);
> -
> -       for (i = 1; i <= 16; i++) {
> -               unsigned long ideal = rate * i;
> -               unsigned long rounded;
> -
> -               rounded = clk_hw_round_rate(parent, ideal);
> +       for (p = 0; p < clk_hw_get_num_parents(hw); p++) {
> +               parent = clk_hw_get_parent_by_index(hw, p);
> +               if (!parent)
> +                       continue;
>
> -               if (rounded == ideal) {
> -                       best_rate = rounded;
> -                       best_div = i;
> -                       break;
> +               for (i = 1; i <= 16; i++) {
> +                       unsigned long ideal = rate * i;
> +                       unsigned long rounded;
> +
> +                       rounded = clk_hw_round_rate(parent, ideal);
> +
> +                       if (rounded == ideal) {
> +                               best_rate = rounded;
> +                               best_div = i;
> +                               best_parent = parent;
> +                               break;
> +                       }
> +
> +                       if (!best_rate ||
> +                           abs(rate - rounded / i) <
> +                           abs(rate - best_rate / best_div)) {
> +                               best_rate = rounded;
> +                               best_div = i;
> +                               best_parent = parent;
> +                       }
>                 }
>
> -               if (!best_rate ||
> -                   abs(rate - rounded / i) <
> -                   abs(rate - best_rate / best_div)) {
> -                       best_rate = rounded;
> -                       best_div = i;
> -               }
> +               if (best_rate / best_div == rate)
> +                       break;
>         }
>
>         req->rate = best_rate / best_div;
>         req->best_parent_rate = best_rate;
> -       req->best_parent_hw = parent;
> +       req->best_parent_hw = best_parent;
>
>         return 0;
>  }
> @@ -95,22 +105,58 @@ static int sun8i_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
>         return 0;
>  }
>
> +static u8 sun8i_phy_clk_get_parent(struct clk_hw *hw)
> +{
> +       struct sun8i_phy_clk *priv = hw_to_phy_clk(hw);
> +       u32 reg;
> +
> +       regmap_read(priv->phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, &reg);
> +       reg = (reg & SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK) >>
> +             SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT;
> +
> +       return reg;
> +}
> +
> +static int sun8i_phy_clk_set_parent(struct clk_hw *hw, u8 index)
> +{
> +       struct sun8i_phy_clk *priv = hw_to_phy_clk(hw);
> +
> +       if (index > 1)
> +               return -EINVAL;
> +
> +       regmap_update_bits(priv->phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
> +                          SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK,
> +                          index << SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT);
> +
> +       return 0;
> +}
> +
>  static const struct clk_ops sun8i_phy_clk_ops = {
>         .determine_rate = sun8i_phy_clk_determine_rate,
>         .recalc_rate    = sun8i_phy_clk_recalc_rate,
>         .set_rate       = sun8i_phy_clk_set_rate,
> +
> +       .get_parent     = sun8i_phy_clk_get_parent,
> +       .set_parent     = sun8i_phy_clk_set_parent,
>  };
>
> -int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev)
> +int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev,
> +                        bool second_parent)
>  {
>         struct clk_init_data init;
>         struct sun8i_phy_clk *priv;
> -       const char *parents[1];
> +       const char *parents[2];
>
>         parents[0] = __clk_get_name(phy->clk_pll0);
>         if (!parents[0])
>                 return -ENODEV;
>
> +       if (second_parent) {
> +               parents[1] = __clk_get_name(phy->clk_pll1);

Like I mentioned in the TCON TOP patch, you don't actually need a reference
if all you want is just the clock name.

ChenYu

> +               if (!parents[1])
> +                       return -ENODEV;
> +       }
> +
>         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>         if (!priv)
>                 return -ENOMEM;
> @@ -118,7 +164,7 @@ int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev)
>         init.name = "hdmi-phy-clk";
>         init.ops = &sun8i_phy_clk_ops;
>         init.parent_names = parents;
> -       init.num_parents = 1;
> +       init.num_parents = second_parent ? 2 : 1;
>         init.flags = CLK_SET_RATE_PARENT;
>
>         priv->phy = phy;
> --
> 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] 87+ messages in thread

* Re: [PATCH v3 20/24] drm/sun4i: Add support for A64 HDMI PHY
  2018-06-25 12:03 ` [PATCH v3 20/24] drm/sun4i: Add support for A64 HDMI PHY Jernej Skrabec
@ 2018-06-28  2:30   ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  2:30 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:03 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> PHY is the same as in H3, except it can switch between two clock
> parents.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

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

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

* Re: [PATCH v3 21/24] drm: of: Export drm_crtc_port_mask()
  2018-06-25 12:03 ` [PATCH v3 21/24] drm: of: Export drm_crtc_port_mask() Jernej Skrabec
@ 2018-06-28  2:32   ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  2:32 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:03 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> Function is useful when drm_of_find_possible_crtcs() can't be used and
> custom parsing is needed. This can happen for example when there is a
> node with multiple muxes between crtc and encoder.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

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

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

* Re: [PATCH v3 22/24] drm/sun4i: DW HDMI: Expand algorithm for possible crtcs
  2018-06-25 12:03 ` [PATCH v3 22/24] drm/sun4i: DW HDMI: Expand algorithm for possible crtcs Jernej Skrabec
@ 2018-06-28  2:42   ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  2:42 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:03 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> drm_of_find_possible_crtcs() doesn't work when DW HDMI encoder is
> connected to TCON (crtc) through mux in TCON TOP.
>
> In that case TCON TOP HDMI mux input port has to be manually traversed
> and checked if it matches any known crtc.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>

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

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

* Re: [PATCH v3 23/24] ARM: dts: sun8i: r40: Add HDMI pipeline
  2018-06-25 12:03 ` [PATCH v3 23/24] ARM: dts: sun8i: r40: Add HDMI pipeline Jernej Skrabec
@ 2018-06-28  2:50   ` Chen-Yu Tsai
  2018-06-28  5:15     ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  2:50 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:03 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> Add all entries needed for HDMI to function properly.
>
> Since R40 has highly configurable pipeline, both mixers and both TCON
> TVs are added. Board specific DT should then connect them together
> trough TCON TOP muxers to best fit the purpose of the board.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  arch/arm/boot/dts/sun8i-r40.dtsi | 269 +++++++++++++++++++++++++++++++
>  1 file changed, 269 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi
> index 173dcc1652d2..a2a75fb04caf 100644
> --- a/arch/arm/boot/dts/sun8i-r40.dtsi
> +++ b/arch/arm/boot/dts/sun8i-r40.dtsi
> @@ -42,8 +42,11 @@
>   */
>
>  #include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/clock/sun8i-de2.h>
>  #include <dt-bindings/clock/sun8i-r40-ccu.h>
> +#include <dt-bindings/clock/sun8i-tcon-top.h>
>  #include <dt-bindings/reset/sun8i-r40-ccu.h>
> +#include <dt-bindings/reset/sun8i-de2.h>
>
>  / {
>         #address-cells = <1>;
> @@ -99,12 +102,76 @@
>                 };
>         };
>
> +       de: display-engine {
> +               compatible = "allwinner,sun8i-r40-display-engine",
> +                            "allwinner,sun8i-h3-display-engine";

Given that the display pipeline looks different, they should not be
compatible.

> +               allwinner,pipelines = <&mixer0>, <&mixer1>;
> +               status = "disabled";
> +       };
> +
>         soc {
>                 compatible = "simple-bus";
>                 #address-cells = <1>;
>                 #size-cells = <1>;
>                 ranges;
>
> +               display_clocks: clock@1000000 {
> +                       compatible = "allwinner,sun8i-r40-de2-clk",
> +                                    "allwinner,sun8i-h3-de2-clk";
> +                       reg = <0x01000000 0x100000>;
> +                       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@1100000 {
> +                       compatible = "allwinner,sun8i-r40-de2-mixer-0";
> +                       reg = <0x01100000 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: endpoint {
> +                                               remote-endpoint = <&tcon_top_mixer0_in_mixer0>;
> +                                       };
> +                               };
> +                       };
> +               };
> +
> +               mixer1: mixer@1200000 {
> +                       compatible = "allwinner,sun8i-r40-de2-mixer-1";
> +                       reg = <0x01200000 0x100000>;
> +                       clocks = <&display_clocks CLK_BUS_MIXER1>,
> +                                <&display_clocks CLK_MIXER1>;
> +                       clock-names = "bus",
> +                                     "mod";
> +                       resets = <&display_clocks RST_WB>;
> +
> +                       ports {
> +                               #address-cells = <1>;
> +                               #size-cells = <0>;
> +
> +                               mixer1_out: port@1 {
> +                                       reg = <1>;
> +                                       mixer1_out_tcon_top: endpoint {
> +                                               remote-endpoint = <&tcon_top_mixer1_in_mixer1>;
> +                                       };
> +                               };
> +                       };
> +               };
> +
>                 nmi_intc: interrupt-controller@1c00030 {
>                         compatible = "allwinner,sun7i-a20-sc-nmi";
>                         interrupt-controller;
> @@ -451,6 +518,163 @@
>                         #size-cells = <0>;
>                 };
>
> +               tcon_top: tcon-top@1c70000 {
> +                       compatible = "allwinner,sun8i-r40-tcon-top";
> +                       reg = <0x01c70000 0x1000>;
> +                       clocks = <&ccu CLK_BUS_TCON_TOP>,
> +                                <&ccu CLK_TCON_TV0>,
> +                                <&ccu CLK_TVE0>,
> +                                <&ccu CLK_TCON_TV1>,
> +                                <&ccu CLK_TVE1>,
> +                                <&ccu CLK_DSI_DPHY>;
> +                       clock-names = "bus",
> +                                     "tcon-tv0",
> +                                     "tve0",
> +                                     "tcon-tv1",
> +                                     "tve1",
> +                                     "dsi";
> +                       clock-output-names = "tcon-top-tv0",
> +                                            "tcon-top-tv1",
> +                                            "tcon-top-dsi";
> +                       resets = <&ccu RST_BUS_TCON_TOP>;
> +                       #clock-cells = <1>;
> +
> +                       ports {
> +                               #address-cells = <1>;
> +                               #size-cells = <0>;
> +
> +                               tcon_top_mixer0_in: port@0 {
> +                                       reg = <0>;
> +
> +                                       tcon_top_mixer0_in_mixer0: endpoint {
> +                                               remote-endpoint = <&mixer0_out_tcon_top>;
> +                                       };
> +                               };
> +
> +                               tcon_top_mixer0_out: port@1 {
> +                                       #address-cells = <1>;
> +                                       #size-cells = <0>;
> +                                       reg = <1>;
> +
> +                                       tcon_top_mixer0_out_tcon_lcd0: endpoint@0 {
> +                                               reg = <0>;
> +                                       };
> +
> +                                       tcon_top_mixer0_out_tcon_lcd1: endpoint@1 {
> +                                               reg = <1>;
> +                                       };
> +
> +                                       tcon_top_mixer0_out_tcon_tv0: endpoint@2 {
> +                                               reg = <2>;
> +                                       };
> +
> +                                       tcon_top_mixer0_out_tcon_tv1: endpoint@3 {
> +                                               reg = <3>;
> +                                       };
> +                               };
> +
> +                               tcon_top_mixer1_in: port@2 {
> +                                       reg = <2>;
> +
> +                                       tcon_top_mixer1_in_mixer1: endpoint {
> +                                               remote-endpoint = <&mixer1_out_tcon_top>;
> +                                       };
> +                               };
> +
> +                               tcon_top_mixer1_out: port@3 {
> +                                       #address-cells = <1>;
> +                                       #size-cells = <0>;
> +                                       reg = <3>;
> +
> +                                       tcon_top_mixer1_out_tcon_lcd0: endpoint@0 {
> +                                               reg = <0>;
> +                                       };
> +
> +                                       tcon_top_mixer1_out_tcon_lcd1: endpoint@1 {
> +                                               reg = <1>;
> +                                       };
> +
> +                                       tcon_top_mixer1_out_tcon_tv0: endpoint@2 {
> +                                               reg = <2>;
> +                                       };
> +
> +                                       tcon_top_mixer1_out_tcon_tv1: endpoint@3 {
> +                                               reg = <3>;
> +                                       };
> +                               };
> +
> +                               tcon_top_hdmi_in: port@4 {
> +                                       #address-cells = <1>;
> +                                       #size-cells = <0>;
> +                                       reg = <4>;
> +
> +                                       tcon_top_hdmi_in_tcon_tv0: endpoint@0 {
> +                                               reg = <0>;
> +                                       };
> +
> +                                       tcon_top_hdmi_in_tcon_tv1: endpoint@1 {
> +                                               reg = <1>;
> +                                       };
> +                               };
> +
> +                               tcon_top_hdmi_out: port@5 {
> +                                       reg = <5>;
> +
> +                                       tcon_top_hdmi_out_hdmi: endpoint {
> +                                               remote-endpoint = <&hdmi_in_tcon_top>;
> +                                       };
> +                               };
> +                       };
> +               };
> +
> +               tcon_tv0: lcd-controller@1c73000 {
> +                       compatible = "allwinner,sun8i-r40-tcon-tv",
> +                                    "allwinner,sun8i-a83t-tcon-tv";
> +                       reg = <0x01c73000 0x1000>;
> +                       interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
> +                       clocks = <&ccu CLK_BUS_TCON_TV0>, <&tcon_top 0>;
> +                       clock-names = "ahb", "tcon-ch1";
> +                       resets = <&ccu RST_BUS_TCON_TV0>;
> +                       reset-names = "lcd";
> +
> +                       ports {
> +                               #address-cells = <1>;
> +                               #size-cells = <0>;
> +
> +                               tcon_tv0_in: port@0 {
> +                                       reg = <0>;
> +                               };
> +
> +                               tcon_tv0_out: port@1 {
> +                                       reg = <1>;
> +                               };
> +                       };
> +               };
> +
> +               tcon_tv1: lcd-controller@1c74000 {
> +                       compatible = "allwinner,sun8i-r40-tcon-tv",
> +                                    "allwinner,sun8i-a83t-tcon-tv";
> +                       reg = <0x01c74000 0x1000>;
> +                       interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
> +                       clocks = <&ccu CLK_BUS_TCON_TV1>, <&tcon_top 1>;
> +                       clock-names = "ahb", "tcon-ch1";
> +                       resets = <&ccu RST_BUS_TCON_TV1>;
> +                       reset-names = "lcd";
> +
> +                       ports {
> +                               #address-cells = <1>;
> +                               #size-cells = <0>;
> +
> +                               tcon_tv1_in: port@0 {
> +                                       reg = <0>;
> +                               };
> +
> +                               tcon_tv1_out: port@1 {
> +                                       reg = <1>;

You are missing the remote-endpoints for all the TCON-TOP <-> TCON connections.
Also, on the driver side, there's no code to handle dynamically mapping mixers
to the TCONs that are being used. In the past we had simple 1:1 mappings. This
is no longer the case, and it needs to be dealt with.

ChenYu

> +                               };
> +                       };
> +               };
> +
>                 gic: interrupt-controller@1c81000 {
>                         compatible = "arm,gic-400";
>                         reg = <0x01c81000 0x1000>,
> @@ -461,6 +685,51 @@
>                         #interrupt-cells = <3>;
>                         interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
>                 };
> +
> +               hdmi: hdmi@1ee0000 {
> +                       compatible = "allwinner,sun8i-r40-dw-hdmi",
> +                                    "allwinner,sun8i-a83t-dw-hdmi";
> +                       reg = <0x01ee0000 0x10000>;
> +                       reg-io-width = <1>;
> +                       interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
> +                       clocks = <&ccu CLK_BUS_HDMI0>, <&ccu CLK_HDMI_SLOW>,
> +                                <&ccu CLK_HDMI>;
> +                       clock-names = "iahb", "isfr", "tmds";
> +                       resets = <&ccu RST_BUS_HDMI1>;
> +                       reset-names = "ctrl";
> +                       phys = <&hdmi_phy>;
> +                       phy-names = "hdmi-phy";
> +                       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@1ef0000 {
> +                       compatible = "allwinner,sun8i-r40-hdmi-phy",
> +                                    "allwinner,sun50i-a64-hdmi-phy";
> +                       reg = <0x01ef0000 0x10000>;
> +                       clocks = <&ccu CLK_BUS_HDMI1>, <&ccu CLK_HDMI_SLOW>,
> +                                <&ccu 7>, <&ccu 16>;
> +                       clock-names = "bus", "mod", "pll-0", "pll-1";
> +                       resets = <&ccu RST_BUS_HDMI0>;
> +                       reset-names = "phy";
> +                       #phy-cells = <0>;
> +               };
>         };
>
>         timer {
> --
> 2.18.0
>

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

* Re: [linux-sunxi] [PATCH v3 24/24] ARM: dts: sun8i: r40: Enable HDMI output on BananaPi M2 Ultra
  2018-06-25 12:03 ` [PATCH v3 24/24] ARM: dts: sun8i: r40: Enable HDMI output on BananaPi M2 Ultra Jernej Skrabec
@ 2018-06-28  2:51   ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  2:51 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Mon, Jun 25, 2018 at 8:03 PM, Jernej Skrabec <jernej.skrabec@siol.net> wrote:
> Since HDMI can be considered as main output, most capable mixer is
> connected to it (mixer0).
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  .../boot/dts/sun8i-r40-bananapi-m2-ultra.dts  | 45 +++++++++++++++++++
>  1 file changed, 45 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
> index 27d9ccd0ef2f..0ebc2f9a980e 100644
> --- a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
> +++ b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
> @@ -58,6 +58,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";
>
> @@ -93,6 +104,10 @@
>         };
>  };
>
> +&de {
> +       status = "okay";
> +};
> +
>  &ehci1 {
>         status = "okay";
>  };
> @@ -101,6 +116,16 @@
>         status = "okay";
>  };
>
> +&hdmi {
> +       status = "okay";
> +};
> +
> +&hdmi_out {
> +       hdmi_out_con: endpoint {
> +               remote-endpoint = <&hdmi_con_in>;
> +       };
> +};
> +
>  &i2c0 {
>         status = "okay";
>
> @@ -195,6 +220,26 @@
>         status = "okay";
>  };
>
> +&tcon_top_hdmi_in_tcon_tv0 {
> +       remote-endpoint = <&tcon_tv0_out_tcon_top>;
> +};
> +
> +&tcon_top_mixer0_out_tcon_tv0 {
> +       remote-endpoint = <&tcon_tv0_in_tcon_top>;
> +};
> +
> +&tcon_tv0_in {
> +       tcon_tv0_in_tcon_top: endpoint {
> +               remote-endpoint = <&tcon_top_mixer0_out_tcon_tv0>;
> +       };
> +};
> +
> +&tcon_tv0_out {
> +       tcon_tv0_out_tcon_top: endpoint {
> +               remote-endpoint = <&tcon_top_hdmi_in_tcon_tv0>;
> +       };
> +};
> +

This is the wrong place for this. Once removed,

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

>  &uart0 {
>         pinctrl-names = "default";
>         pinctrl-0 = <&uart0_pb_pins>;
> --
> 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] 87+ messages in thread

* Re: [PATCH v3 09/24] drm/sun4i: Don't skip TCONs if they don't have channel 0
  2018-06-28  1:51   ` Chen-Yu Tsai
@ 2018-06-28  4:45     ` Jernej Škrabec
  2018-06-28  6:24       ` [linux-sunxi] " Chen-Yu Tsai
  0 siblings, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-06-28  4:45 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne četrtek, 28. junij 2018 ob 03:51:31 CEST je Chen-Yu Tsai napisal(a):
> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > TV TCONs (channel 1 only) are always connected to TV or HDMI encoder.
> > Because of that, all output endpoints on such TCON node will point to a
> > encoder which is part of component framework.
> > 
> > Correct current graph traversing algorithm in such way that it doesn't
> > skip output enpoints with id 0 on TV TCONs.
> 
> No. Our bindings say that endpoint 0 _is_ channel 0. For TCONs that don't
> have channel 0, it must be skipped.

I'm not sure where this is stated. I read TCON binding again. Can you please 
point me to it?

So on TV TCONs on R40 (without channel 0) TVE would be endpoint 1 and HDMI 
endpoint 2 (or the other way around)?

Best regards,
Jernej




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

* Re: [PATCH v3 10/24] drm/sun4i: tcon: Generalize engine search algorithm
  2018-06-28  2:06   ` Chen-Yu Tsai
@ 2018-06-28  4:48     ` Jernej Škrabec
  2018-06-28 18:25       ` Maxime Ripard
  0 siblings, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-06-28  4:48 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne četrtek, 28. junij 2018 ob 04:06:52 CEST je Chen-Yu Tsai napisal(a):
> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > Current "old" method to find engine worked pretty well for DE2. However,
> > it doesn't work when TCON TOP is between  mixer (engine) and TCON. TCON
> > TOP has multiple input ports, but current engine search algorithm
> > expects only one.
> > 
> > This can be fixed by first looking for output port id and selecting
> > matching input by subtracting 1 for the next round. This work even if
> > there is only one input and output.
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> > 
> >  drivers/gpu/drm/sun4i/sun4i_tcon.c | 22 ++++++++++++++++++----
> >  1 file changed, 18 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 08747fc3ee71..264bcc43da11
> > 100644
> > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > @@ -791,12 +791,14 @@ static int sun4i_tcon_init_regmap(struct device
> > *dev,
> > 
> >   */
> >  
> >  static struct sunxi_engine *
> >  sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv,
> > 
> > -                               struct device_node *node)
> > +                               struct device_node *node,
> > +                               u32 port_id)
> > 
> >  {
> >  
> >         struct device_node *port, *ep, *remote;
> >         struct sunxi_engine *engine = ERR_PTR(-EINVAL);
> > 
> > +       u32 reg = 0;
> > 
> > -       port = of_graph_get_port_by_id(node, 0);
> > +       port = of_graph_get_port_by_id(node, port_id);
> > 
> >         if (!port)
> >         
> >                 return ERR_PTR(-EINVAL);
> > 
> > @@ -826,8 +828,20 @@ sun4i_tcon_find_engine_traverse(struct sun4i_drv
> > *drv,
> > 
> >                 if (remote == engine->node)
> >                 
> >                         goto out_put_remote;
> > 
> > +       /*
> > +        * According to device tree binding input ports have even id
> > +        * number and output ports have odd id. Since component with
> > +        * more than one input and one output (TCON TOP) exits, correct
> > +        * remote input id has to be calculated by subtracting 1 from
> > +        * remote output id. If this for some reason can't be done, 0
> > +        * is used as input port id.
> > +        */
> 
> You need to call
> 
>     of_node_put(port);
> 
> to drop the reference to the original port.

Thanks for noticing it. I guess I should send fix patch, since patches from 
drm-misc-next can't be dropped.

Best regards,
Jernej

> Otherwise,
> 
> Reviewed-by: Chen-Yu Tsai <wens@csie.org>
> 
> > +       port = of_graph_get_remote_port(ep);
> > +       if (!of_property_read_u32(port, "reg", &reg) && reg > 0)
> > +               reg -= 1;
> > +
> > 
> >         /* keep looking through upstream ports */
> > 
> > -       engine = sun4i_tcon_find_engine_traverse(drv, remote);
> > +       engine = sun4i_tcon_find_engine_traverse(drv, remote, reg);
> > 
> >  out_put_remote:
> >         of_node_put(remote);
> > 
> > @@ -950,7 +964,7 @@ static struct sunxi_engine
> > *sun4i_tcon_find_engine(struct sun4i_drv *drv,> 
> >         /* Fallback to old method by traversing input endpoints */
> >         of_node_put(port);
> > 
> > -       return sun4i_tcon_find_engine_traverse(drv, node);
> > +       return sun4i_tcon_find_engine_traverse(drv, node, 0);
> > 
> >  }
> >  
> >  static int sun4i_tcon_bind(struct device *dev, struct device *master,
> > 
> > --
> > 2.18.0





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

* Re: [PATCH v3 15/24] dt-bindings: display: sun4i-drm: Add description of A64 HDMI PHY
  2018-06-28  2:19   ` Chen-Yu Tsai
@ 2018-06-28  4:51     ` Jernej Škrabec
  2018-06-28  7:00       ` [linux-sunxi] " Chen-Yu Tsai
  0 siblings, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-06-28  4:51 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne četrtek, 28. junij 2018 ob 04:19:55 CEST je Chen-Yu Tsai napisal(a):
> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > A64 HDMI PHY is similar to H3 HDMI PHY except it has two possible PLL
> > clock parents. It is compatible to other HDMI PHYs, like that found in
> > R40.
> > 
> > Acked-by: Rob Herring <robh@kernel.org>
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> > 
> >  Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> > b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt index
> > 84fe38dbb900..dc83f21ef188 100644
> > --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> > +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> > @@ -101,6 +101,7 @@ DWC HDMI PHY
> > 
> >  Required properties:
> >    - compatible: value must be one of:
> > +    * allwinner,sun50i-a64-hdmi-phy
> > 
> >      * allwinner,sun8i-a83t-hdmi-phy
> >      * allwinner,sun8i-h3-hdmi-phy
> 
> Nit: the list is sorted by family first, then SoC name, so it should
> be the last on the list.

I went alphabetically, since "5" is before "8"...

Best regards,
Jernej

> 
> Otherwise,
> 
> Reviewed-by: Chen-Yu Tsai <wens@csie.org>
> 
> >    - reg: base address and size of memory-mapped region
> > 
> > @@ -111,8 +112,9 @@ Required properties:
> >    - resets: phandle to the reset controller driving the PHY
> >    - reset-names: must be "phy"
> > 
> > -H3 HDMI PHY requires additional clock:
> > 
> > +H3 and A64 HDMI PHY require additional clocks:
> >    - pll-0: parent of phy clock
> > 
> > +  - pll-1: second possible phy clock parent (A64 only)
> > 
> >  TV Encoder
> >  ----------
> > 
> > --
> > 2.18.0





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

* Re: [PATCH v3 16/24] drm/sun4i: Enable DW HDMI PHY clock
  2018-06-28  2:22   ` Chen-Yu Tsai
@ 2018-06-28  4:52     ` Jernej Škrabec
  2018-06-29 19:19     ` Jernej Škrabec
  1 sibling, 0 replies; 87+ messages in thread
From: Jernej Škrabec @ 2018-06-28  4:52 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne četrtek, 28. junij 2018 ob 04:22:36 CEST je Chen-Yu Tsai napisal(a):
> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > Current DW HDMI PHY code never prepares and enables PHY clock after it is
> > created. It's just used as it is. This may work in some cases, but it's
> > clearly wrong. Fix it by adding proper calls to enable/disable PHY
> > clock.
> > 
> > Fixes: 4f86e81748fe ("drm/sun4i: Add support for H3 HDMI PHY variant")
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> 
> So why does it work on the H3? Because there's only one PLL that the whole
> display pipeline uses?

Yes, there is only one PLL_VIDEO and TCON and HDMI controller already enabled 
it.

Best regards,
Jernej

> 
> We should probably tag this for stable. So,
> 
> Cc: <stable@vger.kernel.org>
> Reviewed-by: Chen-Yu Tsai <wens@csie.org>





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

* Re: [PATCH v3 18/24] drm/sun4i: DW HDMI PHY: Add support for second PLL
  2018-06-28  2:25   ` Chen-Yu Tsai
@ 2018-06-28  4:56     ` Jernej Škrabec
  2018-06-28  6:59       ` [linux-sunxi] " Chen-Yu Tsai
  0 siblings, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-06-28  4:56 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne četrtek, 28. junij 2018 ob 04:25:54 CEST je Chen-Yu Tsai napisal(a):
> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > Some DW HDMI PHYs, like those found in A64 and R40 SoCs, can select
> > between two clock parents.
> > 
> > Add code which reads second PLL from DT.
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> 
> This patch by itself does not do anything. It should be merged with the
> next one.

Maxime said clock changes should be separated from DT changes.
http://lists.infradead.org/pipermail/linux-arm-kernel/2018-May/578775.html

Best regards,
Jernej




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

* Re: [PATCH v3 23/24] ARM: dts: sun8i: r40: Add HDMI pipeline
  2018-06-28  2:50   ` Chen-Yu Tsai
@ 2018-06-28  5:15     ` Jernej Škrabec
  2018-06-28  6:51       ` [linux-sunxi] " Chen-Yu Tsai
  0 siblings, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-06-28  5:15 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne četrtek, 28. junij 2018 ob 04:50:09 CEST je Chen-Yu Tsai napisal(a):
> On Mon, Jun 25, 2018 at 8:03 PM, Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > Add all entries needed for HDMI to function properly.
> > 
> > Since R40 has highly configurable pipeline, both mixers and both TCON
> > TVs are added. Board specific DT should then connect them together
> > trough TCON TOP muxers to best fit the purpose of the board.
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> > 
> >  arch/arm/boot/dts/sun8i-r40.dtsi | 269 +++++++++++++++++++++++++++++++
> >  1 file changed, 269 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi
> > b/arch/arm/boot/dts/sun8i-r40.dtsi index 173dcc1652d2..a2a75fb04caf
> > 100644
> > --- a/arch/arm/boot/dts/sun8i-r40.dtsi
> > +++ b/arch/arm/boot/dts/sun8i-r40.dtsi
> > @@ -42,8 +42,11 @@
> > 
> >   */
> >  
> >  #include <dt-bindings/interrupt-controller/arm-gic.h>
> > 
> > +#include <dt-bindings/clock/sun8i-de2.h>
> > 
> >  #include <dt-bindings/clock/sun8i-r40-ccu.h>
> > 
> > +#include <dt-bindings/clock/sun8i-tcon-top.h>

Maxime, above line breaks compilation for build robot, sorry.

> > 
> >  #include <dt-bindings/reset/sun8i-r40-ccu.h>
> > 
> > +#include <dt-bindings/reset/sun8i-de2.h>
> > 
> >  / {
> >  
> >         #address-cells = <1>;
> > 
> > @@ -99,12 +102,76 @@
> > 
> >                 };
> >         
> >         };
> > 
> > +       de: display-engine {
> > +               compatible = "allwinner,sun8i-r40-display-engine",
> > +                            "allwinner,sun8i-h3-display-engine";
> 
> Given that the display pipeline looks different, they should not be
> compatible.

Ok.

> 
> > +               allwinner,pipelines = <&mixer0>, <&mixer1>;
> > +               status = "disabled";
> > +       };
> > +
> > 
> >         soc {
> >         
> >                 compatible = "simple-bus";
> >                 #address-cells = <1>;
> >                 #size-cells = <1>;
> >                 ranges;
> > 
> > +               display_clocks: clock@1000000 {
> > +                       compatible = "allwinner,sun8i-r40-de2-clk",
> > +                                    "allwinner,sun8i-h3-de2-clk";
> > +                       reg = <0x01000000 0x100000>;
> > +                       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@1100000 {
> > +                       compatible = "allwinner,sun8i-r40-de2-mixer-0";
> > +                       reg = <0x01100000 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: endpoint {
> > +                                               remote-endpoint =
> > <&tcon_top_mixer0_in_mixer0>; +                                       };
> > +                               };
> > +                       };
> > +               };
> > +
> > +               mixer1: mixer@1200000 {
> > +                       compatible = "allwinner,sun8i-r40-de2-mixer-1";
> > +                       reg = <0x01200000 0x100000>;
> > +                       clocks = <&display_clocks CLK_BUS_MIXER1>,
> > +                                <&display_clocks CLK_MIXER1>;
> > +                       clock-names = "bus",
> > +                                     "mod";
> > +                       resets = <&display_clocks RST_WB>;
> > +
> > +                       ports {
> > +                               #address-cells = <1>;
> > +                               #size-cells = <0>;
> > +
> > +                               mixer1_out: port@1 {
> > +                                       reg = <1>;
> > +                                       mixer1_out_tcon_top: endpoint {
> > +                                               remote-endpoint =
> > <&tcon_top_mixer1_in_mixer1>; +                                       };
> > +                               };
> > +                       };
> > +               };
> > +
> > 
> >                 nmi_intc: interrupt-controller@1c00030 {
> >                 
> >                         compatible = "allwinner,sun7i-a20-sc-nmi";
> >                         interrupt-controller;
> > 
> > @@ -451,6 +518,163 @@
> > 
> >                         #size-cells = <0>;
> >                 
> >                 };
> > 
> > +               tcon_top: tcon-top@1c70000 {
> > +                       compatible = "allwinner,sun8i-r40-tcon-top";
> > +                       reg = <0x01c70000 0x1000>;
> > +                       clocks = <&ccu CLK_BUS_TCON_TOP>,
> > +                                <&ccu CLK_TCON_TV0>,
> > +                                <&ccu CLK_TVE0>,
> > +                                <&ccu CLK_TCON_TV1>,
> > +                                <&ccu CLK_TVE1>,
> > +                                <&ccu CLK_DSI_DPHY>;
> > +                       clock-names = "bus",
> > +                                     "tcon-tv0",
> > +                                     "tve0",
> > +                                     "tcon-tv1",
> > +                                     "tve1",
> > +                                     "dsi";
> > +                       clock-output-names = "tcon-top-tv0",
> > +                                            "tcon-top-tv1",
> > +                                            "tcon-top-dsi";
> > +                       resets = <&ccu RST_BUS_TCON_TOP>;
> > +                       #clock-cells = <1>;
> > +
> > +                       ports {
> > +                               #address-cells = <1>;
> > +                               #size-cells = <0>;
> > +
> > +                               tcon_top_mixer0_in: port@0 {
> > +                                       reg = <0>;
> > +
> > +                                       tcon_top_mixer0_in_mixer0:
> > endpoint { +                                              
> > remote-endpoint = <&mixer0_out_tcon_top>; +                              
> >         };
> > +                               };
> > +
> > +                               tcon_top_mixer0_out: port@1 {
> > +                                       #address-cells = <1>;
> > +                                       #size-cells = <0>;
> > +                                       reg = <1>;
> > +
> > +                                       tcon_top_mixer0_out_tcon_lcd0:
> > endpoint@0 { +                                               reg = <0>;
> > +                                       };
> > +
> > +                                       tcon_top_mixer0_out_tcon_lcd1:
> > endpoint@1 { +                                               reg = <1>;
> > +                                       };
> > +
> > +                                       tcon_top_mixer0_out_tcon_tv0:
> > endpoint@2 { +                                               reg = <2>;
> > +                                       };
> > +
> > +                                       tcon_top_mixer0_out_tcon_tv1:
> > endpoint@3 { +                                               reg = <3>;
> > +                                       };
> > +                               };
> > +
> > +                               tcon_top_mixer1_in: port@2 {
> > +                                       reg = <2>;
> > +
> > +                                       tcon_top_mixer1_in_mixer1:
> > endpoint { +                                              
> > remote-endpoint = <&mixer1_out_tcon_top>; +                              
> >         };
> > +                               };
> > +
> > +                               tcon_top_mixer1_out: port@3 {
> > +                                       #address-cells = <1>;
> > +                                       #size-cells = <0>;
> > +                                       reg = <3>;
> > +
> > +                                       tcon_top_mixer1_out_tcon_lcd0:
> > endpoint@0 { +                                               reg = <0>;
> > +                                       };
> > +
> > +                                       tcon_top_mixer1_out_tcon_lcd1:
> > endpoint@1 { +                                               reg = <1>;
> > +                                       };
> > +
> > +                                       tcon_top_mixer1_out_tcon_tv0:
> > endpoint@2 { +                                               reg = <2>;
> > +                                       };
> > +
> > +                                       tcon_top_mixer1_out_tcon_tv1:
> > endpoint@3 { +                                               reg = <3>;
> > +                                       };
> > +                               };
> > +
> > +                               tcon_top_hdmi_in: port@4 {
> > +                                       #address-cells = <1>;
> > +                                       #size-cells = <0>;
> > +                                       reg = <4>;
> > +
> > +                                       tcon_top_hdmi_in_tcon_tv0:
> > endpoint@0 { +                                               reg = <0>;
> > +                                       };
> > +
> > +                                       tcon_top_hdmi_in_tcon_tv1:
> > endpoint@1 { +                                               reg = <1>;
> > +                                       };
> > +                               };
> > +
> > +                               tcon_top_hdmi_out: port@5 {
> > +                                       reg = <5>;
> > +
> > +                                       tcon_top_hdmi_out_hdmi: endpoint {
> > +                                               remote-endpoint =
> > <&hdmi_in_tcon_top>; +                                       };
> > +                               };
> > +                       };
> > +               };
> > +
> > +               tcon_tv0: lcd-controller@1c73000 {
> > +                       compatible = "allwinner,sun8i-r40-tcon-tv",
> > +                                    "allwinner,sun8i-a83t-tcon-tv";
> > +                       reg = <0x01c73000 0x1000>;
> > +                       interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
> > +                       clocks = <&ccu CLK_BUS_TCON_TV0>, <&tcon_top 0>;
> > +                       clock-names = "ahb", "tcon-ch1";
> > +                       resets = <&ccu RST_BUS_TCON_TV0>;
> > +                       reset-names = "lcd";
> > +
> > +                       ports {
> > +                               #address-cells = <1>;
> > +                               #size-cells = <0>;
> > +
> > +                               tcon_tv0_in: port@0 {
> > +                                       reg = <0>;
> > +                               };
> > +
> > +                               tcon_tv0_out: port@1 {
> > +                                       reg = <1>;
> > +                               };
> > +                       };
> > +               };
> > +
> > +               tcon_tv1: lcd-controller@1c74000 {
> > +                       compatible = "allwinner,sun8i-r40-tcon-tv",
> > +                                    "allwinner,sun8i-a83t-tcon-tv";
> > +                       reg = <0x01c74000 0x1000>;
> > +                       interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
> > +                       clocks = <&ccu CLK_BUS_TCON_TV1>, <&tcon_top 1>;
> > +                       clock-names = "ahb", "tcon-ch1";
> > +                       resets = <&ccu RST_BUS_TCON_TV1>;
> > +                       reset-names = "lcd";
> > +
> > +                       ports {
> > +                               #address-cells = <1>;
> > +                               #size-cells = <0>;
> > +
> > +                               tcon_tv1_in: port@0 {
> > +                                       reg = <0>;
> > +                               };
> > +
> > +                               tcon_tv1_out: port@1 {
> > +                                       reg = <1>;
> 
> You are missing the remote-endpoints for all the TCON-TOP <-> TCON
> connections. Also, on the driver side, there's no code to handle
> dynamically mapping mixers to the TCONs that are being used. In the past we
> had simple 1:1 mappings. This is no longer the case, and it needs to be
> dealt with.

How would TCON TOP driver know how to set muxes? There are no appropriate 
bingings for muxes, except for V4L2 subsystem, which doesn't really work here.

Additionaly, how would HDMI know which TCON belongs to it to appropriately set 
possible_crtcs?

Currently, my idea is that board DT creates wanted connections. Since there is 
only one valid connection for each mux, driver knows eactly what to write into 
mux register. HDMI driver can simply check which TCON connection is valid in 
HDMI input mux and select it in possible_crtcs.

Please also note that mixer0 and mixer1 don't have same capabilities and you 
generally want mixer0 to be connected to main output. This is in contrast to 
DE1 SoCs, where both backends and both frontends have same capability.

Best regards,
Jernej

> 
> ChenYu
> 
> > +                               };
> > +                       };
> > +               };
> > +
> > 
> >                 gic: interrupt-controller@1c81000 {
> >                 
> >                         compatible = "arm,gic-400";
> >                         reg = <0x01c81000 0x1000>,
> > 
> > @@ -461,6 +685,51 @@
> > 
> >                         #interrupt-cells = <3>;
> >                         interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
> >                         IRQ_TYPE_LEVEL_HIGH)>;
> >                 
> >                 };
> > 
> > +
> > +               hdmi: hdmi@1ee0000 {
> > +                       compatible = "allwinner,sun8i-r40-dw-hdmi",
> > +                                    "allwinner,sun8i-a83t-dw-hdmi";
> > +                       reg = <0x01ee0000 0x10000>;
> > +                       reg-io-width = <1>;
> > +                       interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
> > +                       clocks = <&ccu CLK_BUS_HDMI0>, <&ccu
> > CLK_HDMI_SLOW>, +                                <&ccu CLK_HDMI>;
> > +                       clock-names = "iahb", "isfr", "tmds";
> > +                       resets = <&ccu RST_BUS_HDMI1>;
> > +                       reset-names = "ctrl";
> > +                       phys = <&hdmi_phy>;
> > +                       phy-names = "hdmi-phy";
> > +                       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@1ef0000 {
> > +                       compatible = "allwinner,sun8i-r40-hdmi-phy",
> > +                                    "allwinner,sun50i-a64-hdmi-phy";
> > +                       reg = <0x01ef0000 0x10000>;
> > +                       clocks = <&ccu CLK_BUS_HDMI1>, <&ccu
> > CLK_HDMI_SLOW>, +                                <&ccu 7>, <&ccu 16>;
> > +                       clock-names = "bus", "mod", "pll-0", "pll-1";
> > +                       resets = <&ccu RST_BUS_HDMI0>;
> > +                       reset-names = "phy";
> > +                       #phy-cells = <0>;
> > +               };
> > 
> >         };
> >         
> >         timer {
> > 
> > --
> > 2.18.0





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

* Re: [linux-sunxi] Re: [PATCH v3 09/24] drm/sun4i: Don't skip TCONs if they don't have channel 0
  2018-06-28  4:45     ` Jernej Škrabec
@ 2018-06-28  6:24       ` Chen-Yu Tsai
  2018-07-01  8:27         ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  6:24 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Thu, Jun 28, 2018 at 12:45 PM, Jernej Škrabec
<jernej.skrabec@siol.net> wrote:
> Dne četrtek, 28. junij 2018 ob 03:51:31 CEST je Chen-Yu Tsai napisal(a):
>> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net>
> wrote:
>> > TV TCONs (channel 1 only) are always connected to TV or HDMI encoder.
>> > Because of that, all output endpoints on such TCON node will point to a
>> > encoder which is part of component framework.
>> >
>> > Correct current graph traversing algorithm in such way that it doesn't
>> > skip output enpoints with id 0 on TV TCONs.
>>
>> No. Our bindings say that endpoint 0 _is_ channel 0. For TCONs that don't
>> have channel 0, it must be skipped.
>
> I'm not sure where this is stated. I read TCON binding again. Can you please
> point me to it?

https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt#L169

Our TCON driver still expects RGB or LVDS panel / bridges on endpoint 0.
So I guess this was sort of implied historically. It's no longer true.
This is something we should probably fix.

In practice our drivers don't look at it (yet), but rely on the downstream
encoder type to determine which channel to use.

But please add the "allwinner,tcon-channel" property as specified in
the binding.

> So on TV TCONs on R40 (without channel 0) TVE would be endpoint 1 and HDMI
> endpoint 2 (or the other way around)?

Which one goes first doesn't quite matter. IIRC there's also a mux for TVE?

ChenYu

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

* Re: [linux-sunxi] Re: [PATCH v3 23/24] ARM: dts: sun8i: r40: Add HDMI pipeline
  2018-06-28  5:15     ` Jernej Škrabec
@ 2018-06-28  6:51       ` Chen-Yu Tsai
  2018-07-01 10:41         ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  6:51 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Thu, Jun 28, 2018 at 1:15 PM, Jernej Škrabec <jernej.skrabec@siol.net> wrote:
> Dne četrtek, 28. junij 2018 ob 04:50:09 CEST je Chen-Yu Tsai napisal(a):
>> On Mon, Jun 25, 2018 at 8:03 PM, Jernej Skrabec <jernej.skrabec@siol.net>
> wrote:
>> > Add all entries needed for HDMI to function properly.
>> >
>> > Since R40 has highly configurable pipeline, both mixers and both TCON
>> > TVs are added. Board specific DT should then connect them together
>> > trough TCON TOP muxers to best fit the purpose of the board.
>> >
>> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>> > ---
>> >
>> >  arch/arm/boot/dts/sun8i-r40.dtsi | 269 +++++++++++++++++++++++++++++++
>> >  1 file changed, 269 insertions(+)
>> >
>> > diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi
>> > b/arch/arm/boot/dts/sun8i-r40.dtsi index 173dcc1652d2..a2a75fb04caf
>> > 100644
>> > --- a/arch/arm/boot/dts/sun8i-r40.dtsi
>> > +++ b/arch/arm/boot/dts/sun8i-r40.dtsi
>> > @@ -42,8 +42,11 @@
>> >
>> >   */
>> >
>> >  #include <dt-bindings/interrupt-controller/arm-gic.h>
>> >
>> > +#include <dt-bindings/clock/sun8i-de2.h>
>> >
>> >  #include <dt-bindings/clock/sun8i-r40-ccu.h>
>> >
>> > +#include <dt-bindings/clock/sun8i-tcon-top.h>
>
> Maxime, above line breaks compilation for build robot, sorry.
>
>> >
>> >  #include <dt-bindings/reset/sun8i-r40-ccu.h>
>> >
>> > +#include <dt-bindings/reset/sun8i-de2.h>
>> >
>> >  / {
>> >
>> >         #address-cells = <1>;
>> >
>> > @@ -99,12 +102,76 @@
>> >
>> >                 };
>> >
>> >         };
>> >
>> > +       de: display-engine {
>> > +               compatible = "allwinner,sun8i-r40-display-engine",
>> > +                            "allwinner,sun8i-h3-display-engine";
>>
>> Given that the display pipeline looks different, they should not be
>> compatible.
>
> Ok.
>
>>
>> > +               allwinner,pipelines = <&mixer0>, <&mixer1>;
>> > +               status = "disabled";
>> > +       };
>> > +
>> >
>> >         soc {
>> >
>> >                 compatible = "simple-bus";
>> >                 #address-cells = <1>;
>> >                 #size-cells = <1>;
>> >                 ranges;
>> >
>> > +               display_clocks: clock@1000000 {
>> > +                       compatible = "allwinner,sun8i-r40-de2-clk",
>> > +                                    "allwinner,sun8i-h3-de2-clk";
>> > +                       reg = <0x01000000 0x100000>;
>> > +                       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@1100000 {
>> > +                       compatible = "allwinner,sun8i-r40-de2-mixer-0";
>> > +                       reg = <0x01100000 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: endpoint {
>> > +                                               remote-endpoint =
>> > <&tcon_top_mixer0_in_mixer0>; +                                       };
>> > +                               };
>> > +                       };
>> > +               };
>> > +
>> > +               mixer1: mixer@1200000 {
>> > +                       compatible = "allwinner,sun8i-r40-de2-mixer-1";
>> > +                       reg = <0x01200000 0x100000>;
>> > +                       clocks = <&display_clocks CLK_BUS_MIXER1>,
>> > +                                <&display_clocks CLK_MIXER1>;
>> > +                       clock-names = "bus",
>> > +                                     "mod";
>> > +                       resets = <&display_clocks RST_WB>;
>> > +
>> > +                       ports {
>> > +                               #address-cells = <1>;
>> > +                               #size-cells = <0>;
>> > +
>> > +                               mixer1_out: port@1 {
>> > +                                       reg = <1>;
>> > +                                       mixer1_out_tcon_top: endpoint {
>> > +                                               remote-endpoint =
>> > <&tcon_top_mixer1_in_mixer1>; +                                       };
>> > +                               };
>> > +                       };
>> > +               };
>> > +
>> >
>> >                 nmi_intc: interrupt-controller@1c00030 {
>> >
>> >                         compatible = "allwinner,sun7i-a20-sc-nmi";
>> >                         interrupt-controller;
>> >
>> > @@ -451,6 +518,163 @@
>> >
>> >                         #size-cells = <0>;
>> >
>> >                 };
>> >
>> > +               tcon_top: tcon-top@1c70000 {
>> > +                       compatible = "allwinner,sun8i-r40-tcon-top";
>> > +                       reg = <0x01c70000 0x1000>;
>> > +                       clocks = <&ccu CLK_BUS_TCON_TOP>,
>> > +                                <&ccu CLK_TCON_TV0>,
>> > +                                <&ccu CLK_TVE0>,
>> > +                                <&ccu CLK_TCON_TV1>,
>> > +                                <&ccu CLK_TVE1>,
>> > +                                <&ccu CLK_DSI_DPHY>;
>> > +                       clock-names = "bus",
>> > +                                     "tcon-tv0",
>> > +                                     "tve0",
>> > +                                     "tcon-tv1",
>> > +                                     "tve1",
>> > +                                     "dsi";
>> > +                       clock-output-names = "tcon-top-tv0",
>> > +                                            "tcon-top-tv1",
>> > +                                            "tcon-top-dsi";
>> > +                       resets = <&ccu RST_BUS_TCON_TOP>;
>> > +                       #clock-cells = <1>;
>> > +
>> > +                       ports {
>> > +                               #address-cells = <1>;
>> > +                               #size-cells = <0>;
>> > +
>> > +                               tcon_top_mixer0_in: port@0 {
>> > +                                       reg = <0>;
>> > +
>> > +                                       tcon_top_mixer0_in_mixer0:
>> > endpoint { +
>> > remote-endpoint = <&mixer0_out_tcon_top>; +
>> >         };
>> > +                               };
>> > +
>> > +                               tcon_top_mixer0_out: port@1 {
>> > +                                       #address-cells = <1>;
>> > +                                       #size-cells = <0>;
>> > +                                       reg = <1>;
>> > +
>> > +                                       tcon_top_mixer0_out_tcon_lcd0:
>> > endpoint@0 { +                                               reg = <0>;
>> > +                                       };
>> > +
>> > +                                       tcon_top_mixer0_out_tcon_lcd1:
>> > endpoint@1 { +                                               reg = <1>;
>> > +                                       };
>> > +
>> > +                                       tcon_top_mixer0_out_tcon_tv0:
>> > endpoint@2 { +                                               reg = <2>;
>> > +                                       };
>> > +
>> > +                                       tcon_top_mixer0_out_tcon_tv1:
>> > endpoint@3 { +                                               reg = <3>;
>> > +                                       };
>> > +                               };
>> > +
>> > +                               tcon_top_mixer1_in: port@2 {
>> > +                                       reg = <2>;
>> > +
>> > +                                       tcon_top_mixer1_in_mixer1:
>> > endpoint { +
>> > remote-endpoint = <&mixer1_out_tcon_top>; +
>> >         };
>> > +                               };
>> > +
>> > +                               tcon_top_mixer1_out: port@3 {
>> > +                                       #address-cells = <1>;
>> > +                                       #size-cells = <0>;
>> > +                                       reg = <3>;
>> > +
>> > +                                       tcon_top_mixer1_out_tcon_lcd0:
>> > endpoint@0 { +                                               reg = <0>;
>> > +                                       };
>> > +
>> > +                                       tcon_top_mixer1_out_tcon_lcd1:
>> > endpoint@1 { +                                               reg = <1>;
>> > +                                       };
>> > +
>> > +                                       tcon_top_mixer1_out_tcon_tv0:
>> > endpoint@2 { +                                               reg = <2>;
>> > +                                       };
>> > +
>> > +                                       tcon_top_mixer1_out_tcon_tv1:
>> > endpoint@3 { +                                               reg = <3>;
>> > +                                       };
>> > +                               };
>> > +
>> > +                               tcon_top_hdmi_in: port@4 {
>> > +                                       #address-cells = <1>;
>> > +                                       #size-cells = <0>;
>> > +                                       reg = <4>;
>> > +
>> > +                                       tcon_top_hdmi_in_tcon_tv0:
>> > endpoint@0 { +                                               reg = <0>;
>> > +                                       };
>> > +
>> > +                                       tcon_top_hdmi_in_tcon_tv1:
>> > endpoint@1 { +                                               reg = <1>;
>> > +                                       };
>> > +                               };
>> > +
>> > +                               tcon_top_hdmi_out: port@5 {
>> > +                                       reg = <5>;
>> > +
>> > +                                       tcon_top_hdmi_out_hdmi: endpoint {
>> > +                                               remote-endpoint =
>> > <&hdmi_in_tcon_top>; +                                       };
>> > +                               };
>> > +                       };
>> > +               };
>> > +
>> > +               tcon_tv0: lcd-controller@1c73000 {
>> > +                       compatible = "allwinner,sun8i-r40-tcon-tv",
>> > +                                    "allwinner,sun8i-a83t-tcon-tv";
>> > +                       reg = <0x01c73000 0x1000>;
>> > +                       interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
>> > +                       clocks = <&ccu CLK_BUS_TCON_TV0>, <&tcon_top 0>;
>> > +                       clock-names = "ahb", "tcon-ch1";
>> > +                       resets = <&ccu RST_BUS_TCON_TV0>;
>> > +                       reset-names = "lcd";
>> > +
>> > +                       ports {
>> > +                               #address-cells = <1>;
>> > +                               #size-cells = <0>;
>> > +
>> > +                               tcon_tv0_in: port@0 {
>> > +                                       reg = <0>;
>> > +                               };
>> > +
>> > +                               tcon_tv0_out: port@1 {
>> > +                                       reg = <1>;
>> > +                               };
>> > +                       };
>> > +               };
>> > +
>> > +               tcon_tv1: lcd-controller@1c74000 {
>> > +                       compatible = "allwinner,sun8i-r40-tcon-tv",
>> > +                                    "allwinner,sun8i-a83t-tcon-tv";
>> > +                       reg = <0x01c74000 0x1000>;
>> > +                       interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
>> > +                       clocks = <&ccu CLK_BUS_TCON_TV1>, <&tcon_top 1>;
>> > +                       clock-names = "ahb", "tcon-ch1";
>> > +                       resets = <&ccu RST_BUS_TCON_TV1>;
>> > +                       reset-names = "lcd";
>> > +
>> > +                       ports {
>> > +                               #address-cells = <1>;
>> > +                               #size-cells = <0>;
>> > +
>> > +                               tcon_tv1_in: port@0 {
>> > +                                       reg = <0>;
>> > +                               };
>> > +
>> > +                               tcon_tv1_out: port@1 {
>> > +                                       reg = <1>;
>>
>> You are missing the remote-endpoints for all the TCON-TOP <-> TCON
>> connections. Also, on the driver side, there's no code to handle
>> dynamically mapping mixers to the TCONs that are being used. In the past we
>> had simple 1:1 mappings. This is no longer the case, and it needs to be
>> dealt with.
>
> How would TCON TOP driver know how to set muxes? There are no appropriate
> bingings for muxes, except for V4L2 subsystem, which doesn't really work here.

This will end up being a bunch of custom functions exported from the TCON
TOP driver to the TCON driver. As for bindings, the stuff you already have
is mostly enough. You do have to specify the endpoint ID vs component
mapping, so you can find the correct one.

For example, you would specify that the IDs for TCON LCDs be 0 and 1, and TCON
TVs be 2 and 3. Matching the actual register values is a nice convenience.
These would be used by the driver as the TCON ID.

Also, we might want to consider them as two pairs of two TCONs (LCD + TV).
The CRTC in DRM land is actually the mixer + TCON on our platform. This means
we only have two CRTCs. So we could have CRTC 0 = mixer 0 + TCON LCD 0 + TCON
TV 0. The "TCON_TVx_OUTSEL" and "DE_PORTx PERH Select" muxes would be set at
run time in the mode set function, selecting either LCD or TV based on what
encoder is attached.

This limitation is a software one, and should not bleed over into the hardware
representation.

> Additionaly, how would HDMI know which TCON belongs to it to appropriately set
> possible_crtcs?

HDMI is connected to the two TCON TVs through the TCON TOP mux. We handle TCON
output muxing in the TCON driver, using the set_mux callback in the quirks.
For R40, this callback would probably call into the TCON TOP driver asking it
to set the mux to some value.

> Currently, my idea is that board DT creates wanted connections. Since there is
> only one valid connection for each mux, driver knows eactly what to write into
> mux register. HDMI driver can simply check which TCON connection is valid in
> HDMI input mux and select it in possible_crtcs.

But that is not how the actual hardware looks like. The device tree should model
the hardware, not a subset of it just because one thinks the implementation is
difficult or won't be used at all.

Furthermore, I think you have it backwards. possible_crtcs is generated based
on (in our case) the connections between TCON and HDMI based on the device tree
graph. So if you have both hooked up, both will show up in possible_crtcs, but
only one crtc will actually be selected to feed the HDMI encoder. If you really
need to access the current crtc, the drm_encoder struct contains a pointer to
it.

In DE 1.0 driver, we leave all the muxing to the TCON driver. See

    https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/sun4i/sun4i_tcon.c#L537

So in a sense, the HDMI encoder should be and is hooked up to both TCONs,
but only one is active at any given time.

> Please also note that mixer0 and mixer1 don't have same capabilities and you
> generally want mixer0 to be connected to main output. This is in contrast to
> DE1 SoCs, where both backends and both frontends have same capability.

Yes. But who's to say the two display outputs can't be reversed or swapped
around? With fixed singular connections, you also rule out mirrored output.

ChenYu

>>
>> ChenYu
>>
>> > +                               };
>> > +                       };
>> > +               };
>> > +
>> >
>> >                 gic: interrupt-controller@1c81000 {
>> >
>> >                         compatible = "arm,gic-400";
>> >                         reg = <0x01c81000 0x1000>,
>> >
>> > @@ -461,6 +685,51 @@
>> >
>> >                         #interrupt-cells = <3>;
>> >                         interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
>> >                         IRQ_TYPE_LEVEL_HIGH)>;
>> >
>> >                 };
>> >
>> > +
>> > +               hdmi: hdmi@1ee0000 {
>> > +                       compatible = "allwinner,sun8i-r40-dw-hdmi",
>> > +                                    "allwinner,sun8i-a83t-dw-hdmi";
>> > +                       reg = <0x01ee0000 0x10000>;
>> > +                       reg-io-width = <1>;
>> > +                       interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
>> > +                       clocks = <&ccu CLK_BUS_HDMI0>, <&ccu
>> > CLK_HDMI_SLOW>, +                                <&ccu CLK_HDMI>;
>> > +                       clock-names = "iahb", "isfr", "tmds";
>> > +                       resets = <&ccu RST_BUS_HDMI1>;
>> > +                       reset-names = "ctrl";
>> > +                       phys = <&hdmi_phy>;
>> > +                       phy-names = "hdmi-phy";
>> > +                       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@1ef0000 {
>> > +                       compatible = "allwinner,sun8i-r40-hdmi-phy",
>> > +                                    "allwinner,sun50i-a64-hdmi-phy";
>> > +                       reg = <0x01ef0000 0x10000>;
>> > +                       clocks = <&ccu CLK_BUS_HDMI1>, <&ccu
>> > CLK_HDMI_SLOW>, +                                <&ccu 7>, <&ccu 16>;
>> > +                       clock-names = "bus", "mod", "pll-0", "pll-1";
>> > +                       resets = <&ccu RST_BUS_HDMI0>;
>> > +                       reset-names = "phy";
>> > +                       #phy-cells = <0>;
>> > +               };
>> >
>> >         };
>> >
>> >         timer {
>> >
>> > --
>> > 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] 87+ messages in thread

* Re: [linux-sunxi] Re: [PATCH v3 18/24] drm/sun4i: DW HDMI PHY: Add support for second PLL
  2018-06-28  4:56     ` Jernej Škrabec
@ 2018-06-28  6:59       ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  6:59 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Thu, Jun 28, 2018 at 12:56 PM, Jernej Škrabec
<jernej.skrabec@siol.net> wrote:
> Dne četrtek, 28. junij 2018 ob 04:25:54 CEST je Chen-Yu Tsai napisal(a):
>> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net>
> wrote:
>> > Some DW HDMI PHYs, like those found in A64 and R40 SoCs, can select
>> > between two clock parents.
>> >
>> > Add code which reads second PLL from DT.
>> >
>> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>>
>> This patch by itself does not do anything. It should be merged with the
>> next one.
>
> Maxime said clock changes should be separated from DT changes.
> http://lists.infradead.org/pipermail/linux-arm-kernel/2018-May/578775.html

OK. I think the boundary between these two is bit blurred in this case.
And I think implementing support for two or more parents, then actually
adding the second parent makes more sense.

ChenYu

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

* Re: [linux-sunxi] Re: [PATCH v3 15/24] dt-bindings: display: sun4i-drm: Add description of A64 HDMI PHY
  2018-06-28  4:51     ` Jernej Škrabec
@ 2018-06-28  7:00       ` Chen-Yu Tsai
  2018-06-29 19:32         ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-28  7:00 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Thu, Jun 28, 2018 at 12:51 PM, Jernej Škrabec
<jernej.skrabec@siol.net> wrote:
> Dne četrtek, 28. junij 2018 ob 04:19:55 CEST je Chen-Yu Tsai napisal(a):
>> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net>
> wrote:
>> > A64 HDMI PHY is similar to H3 HDMI PHY except it has two possible PLL
>> > clock parents. It is compatible to other HDMI PHYs, like that found in
>> > R40.
>> >
>> > Acked-by: Rob Herring <robh@kernel.org>
>> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>> > ---
>> >
>> >  Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 4 +++-
>> >  1 file changed, 3 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
>> > b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt index
>> > 84fe38dbb900..dc83f21ef188 100644
>> > --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
>> > +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
>> > @@ -101,6 +101,7 @@ DWC HDMI PHY
>> >
>> >  Required properties:
>> >    - compatible: value must be one of:
>> > +    * allwinner,sun50i-a64-hdmi-phy
>> >
>> >      * allwinner,sun8i-a83t-hdmi-phy
>> >      * allwinner,sun8i-h3-hdmi-phy
>>
>> Nit: the list is sorted by family first, then SoC name, so it should
>> be the last on the list.
>
> I went alphabetically, since "5" is before "8"...

I see. I think version sort applies here, given that sun50i is newer
than sun8i.

ChenYu

> Best regards,
> Jernej
>
>>
>> Otherwise,
>>
>> Reviewed-by: Chen-Yu Tsai <wens@csie.org>
>>
>> >    - reg: base address and size of memory-mapped region
>> >
>> > @@ -111,8 +112,9 @@ Required properties:
>> >    - resets: phandle to the reset controller driving the PHY
>> >    - reset-names: must be "phy"
>> >
>> > -H3 HDMI PHY requires additional clock:
>> >
>> > +H3 and A64 HDMI PHY require additional clocks:
>> >    - pll-0: parent of phy clock
>> >
>> > +  - pll-1: second possible phy clock parent (A64 only)
>> >
>> >  TV Encoder
>> >  ----------
>> >
>> > --
>> > 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] 87+ messages in thread

* Re: [PATCH v3 00/24] Add support for R40 HDMI pipeline
  2018-06-27 20:25     ` Jernej Škrabec
@ 2018-06-28  8:41       ` Maxime Ripard
  0 siblings, 0 replies; 87+ messages in thread
From: Maxime Ripard @ 2018-06-28  8:41 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: wens, robh+dt, airlied, gustavo, maarten.lankhorst, seanpaul,
	mark.rutland, dri-devel, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, linux-sunxi

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

On Wed, Jun 27, 2018 at 10:25:37PM +0200, Jernej Škrabec wrote:
> Dne sreda, 27. junij 2018 ob 21:50:43 CEST je Maxime Ripard napisal(a):
> > 
> > On Wed, Jun 27, 2018 at 08:02:15PM +0200, Maxime Ripard wrote:
> > > On Mon, Jun 25, 2018 at 02:02:40PM +0200, Jernej Skrabec wrote:
> > > > This series adds support for R40 HDMI pipeline. It is a bit special
> > > > than other already supported pipelines because it has additional unit
> > > > called TCON TOP responsible for relationship configuration between
> > > > mixers, TCONs and HDMI. Additionally, it has additional gates for DSI
> > > > and TV TCONs, TV encoder clock settings and pin muxing between LCD
> > > > and TV encoders.
> > > > 
> > > > However, it seems that TCON TOP will become a norm, since newer
> > > > Allwinner SoCs like H6 also have this unit.
> > > > 
> > > > I tested different possible configurations:
> > > > - mixer0 <> TCON-TV0 <> HDMI
> > > > - mixer0 <> TCON-TV1 <> HDMI
> > > > - mixer1 <> TCON-TV0 <> HDMI
> > > > - mixer1 <> TCON-TV1 <> HDMI
> > > > 
> > > > Please review.
> > > 
> > > I just applied it. It didn't apply cleanly, so please make sure it
> > > does next time, or at least state what the dependencies are.
> > 
> > And it didn't compile either, because of the compile error that was
> > reported to the previous version by kbuild... Those shouldn't be
> > ignored and simply fixed.
> 
> Sorry about that. I forgot to rebase and had same linux-next base for all 3 
> versions.
> 
> I actually take a look at that kbuild message, but it just didn't make much 
> sense and it worked for me without issues. Merge conflicts would explain that.

This was happening when the driver is compiled as a module, which is
pointed by the config attached to the kbuild mail. And asking is
definitely encouraged when you're confused about such things, ignoring
it on the other hand, not so much.

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

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

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

* Re: [PATCH v3 10/24] drm/sun4i: tcon: Generalize engine search algorithm
  2018-06-28  4:48     ` Jernej Škrabec
@ 2018-06-28 18:25       ` Maxime Ripard
  2018-06-29 19:06         ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Maxime Ripard @ 2018-06-28 18:25 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: Chen-Yu Tsai, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Thu, Jun 28, 2018 at 06:48:50AM +0200, Jernej Škrabec wrote:
> Dne četrtek, 28. junij 2018 ob 04:06:52 CEST je Chen-Yu Tsai napisal(a):
> > On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> 
> wrote:
> > > Current "old" method to find engine worked pretty well for DE2. However,
> > > it doesn't work when TCON TOP is between  mixer (engine) and TCON. TCON
> > > TOP has multiple input ports, but current engine search algorithm
> > > expects only one.
> > > 
> > > This can be fixed by first looking for output port id and selecting
> > > matching input by subtracting 1 for the next round. This work even if
> > > there is only one input and output.
> > > 
> > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > ---
> > > 
> > >  drivers/gpu/drm/sun4i/sun4i_tcon.c | 22 ++++++++++++++++++----
> > >  1 file changed, 18 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 08747fc3ee71..264bcc43da11
> > > 100644
> > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > @@ -791,12 +791,14 @@ static int sun4i_tcon_init_regmap(struct device
> > > *dev,
> > > 
> > >   */
> > >  
> > >  static struct sunxi_engine *
> > >  sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv,
> > > 
> > > -                               struct device_node *node)
> > > +                               struct device_node *node,
> > > +                               u32 port_id)
> > > 
> > >  {
> > >  
> > >         struct device_node *port, *ep, *remote;
> > >         struct sunxi_engine *engine = ERR_PTR(-EINVAL);
> > > 
> > > +       u32 reg = 0;
> > > 
> > > -       port = of_graph_get_port_by_id(node, 0);
> > > +       port = of_graph_get_port_by_id(node, port_id);
> > > 
> > >         if (!port)
> > >         
> > >                 return ERR_PTR(-EINVAL);
> > > 
> > > @@ -826,8 +828,20 @@ sun4i_tcon_find_engine_traverse(struct sun4i_drv
> > > *drv,
> > > 
> > >                 if (remote == engine->node)
> > >                 
> > >                         goto out_put_remote;
> > > 
> > > +       /*
> > > +        * According to device tree binding input ports have even id
> > > +        * number and output ports have odd id. Since component with
> > > +        * more than one input and one output (TCON TOP) exits, correct
> > > +        * remote input id has to be calculated by subtracting 1 from
> > > +        * remote output id. If this for some reason can't be done, 0
> > > +        * is used as input port id.
> > > +        */
> > 
> > You need to call
> > 
> >     of_node_put(port);
> > 
> > to drop the reference to the original port.
> 
> Thanks for noticing it. I guess I should send fix patch, since patches from 
> drm-misc-next can't be dropped.

Yeah, please send additional patches for all the issues pointed out by
Chen-Yu.

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

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

* Re: [PATCH v3 10/24] drm/sun4i: tcon: Generalize engine search algorithm
  2018-06-28 18:25       ` Maxime Ripard
@ 2018-06-29 19:06         ` Jernej Škrabec
  2018-07-01 19:09           ` [linux-sunxi] " Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-06-29 19:06 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne četrtek, 28. junij 2018 ob 20:25:43 CEST je Maxime Ripard napisal(a):
> On Thu, Jun 28, 2018 at 06:48:50AM +0200, Jernej Škrabec wrote:
> > Dne četrtek, 28. junij 2018 ob 04:06:52 CEST je Chen-Yu Tsai napisal(a):
> > > On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec
> > > <jernej.skrabec@siol.net>
> > 
> > wrote:
> > > > Current "old" method to find engine worked pretty well for DE2.
> > > > However,
> > > > it doesn't work when TCON TOP is between  mixer (engine) and TCON.
> > > > TCON
> > > > TOP has multiple input ports, but current engine search algorithm
> > > > expects only one.
> > > > 
> > > > This can be fixed by first looking for output port id and selecting
> > > > matching input by subtracting 1 for the next round. This work even if
> > > > there is only one input and output.
> > > > 
> > > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > > ---
> > > > 
> > > >  drivers/gpu/drm/sun4i/sun4i_tcon.c | 22 ++++++++++++++++++----
> > > >  1 file changed, 18 insertions(+), 4 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 08747fc3ee71..264bcc43da11
> > > > 100644
> > > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > @@ -791,12 +791,14 @@ static int sun4i_tcon_init_regmap(struct device
> > > > *dev,
> > > > 
> > > >   */
> > > >  
> > > >  static struct sunxi_engine *
> > > >  sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv,
> > > > 
> > > > -                               struct device_node *node)
> > > > +                               struct device_node *node,
> > > > +                               u32 port_id)
> > > > 
> > > >  {
> > > >  
> > > >         struct device_node *port, *ep, *remote;
> > > >         struct sunxi_engine *engine = ERR_PTR(-EINVAL);
> > > > 
> > > > +       u32 reg = 0;
> > > > 
> > > > -       port = of_graph_get_port_by_id(node, 0);
> > > > +       port = of_graph_get_port_by_id(node, port_id);
> > > > 
> > > >         if (!port)
> > > >         
> > > >                 return ERR_PTR(-EINVAL);
> > > > 
> > > > @@ -826,8 +828,20 @@ sun4i_tcon_find_engine_traverse(struct sun4i_drv
> > > > *drv,
> > > > 
> > > >                 if (remote == engine->node)
> > > >                 
> > > >                         goto out_put_remote;
> > > > 
> > > > +       /*
> > > > +        * According to device tree binding input ports have even id
> > > > +        * number and output ports have odd id. Since component with
> > > > +        * more than one input and one output (TCON TOP) exits,
> > > > correct
> > > > +        * remote input id has to be calculated by subtracting 1 from
> > > > +        * remote output id. If this for some reason can't be done, 0
> > > > +        * is used as input port id.
> > > > +        */
> > > 
> > > You need to call
> > > 
> > >     of_node_put(port);
> > > 
> > > to drop the reference to the original port.
> > 
> > Thanks for noticing it. I guess I should send fix patch, since patches
> > from
> > drm-misc-next can't be dropped.
> 
> Yeah, please send additional patches for all the issues pointed out by
> Chen-Yu.

Of course. I hope this can be resolved till the end of the next week. After 
that, I will be away from PC for 2 weeks. Feel free to drop DT patches if you 
think that it will come too close to merge window.

Best regards,
Jernej




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

* Re: [PATCH v3 05/24] drm/sun4i: Add TCON TOP driver
  2018-06-28  1:47   ` Chen-Yu Tsai
@ 2018-06-29 19:09     ` Jernej Škrabec
  2018-06-30  1:13       ` [linux-sunxi] " Chen-Yu Tsai
  0 siblings, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-06-29 19:09 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne četrtek, 28. junij 2018 ob 03:47:20 CEST je Chen-Yu Tsai napisal(a):
> Hi,
> 
> So I'm late to the party, but...
> 
> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > As already described in DT binding, TCON TOP is responsible for
> > configuring display pipeline. In this initial driver focus is on HDMI
> > pipeline, so TVE and LCD configuration is not implemented.
> > 
> > Implemented features:
> > - HDMI source selection
> > - clock driver (TCON and DSI gating)
> > - connecting mixers and TCONS
> > 
> > Something similar also existed in previous SoCs, except that it was part
> > of first TCON.
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> > 
> >  drivers/gpu/drm/sun4i/Makefile         |   3 +-
> >  drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 300 +++++++++++++++++++++++++
> >  drivers/gpu/drm/sun4i/sun8i_tcon_top.h |  40 ++++
> >  3 files changed, 342 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/gpu/drm/sun4i/sun8i_tcon_top.c
> >  create mode 100644 drivers/gpu/drm/sun4i/sun8i_tcon_top.h
> > 
> > diff --git a/drivers/gpu/drm/sun4i/Makefile
> > b/drivers/gpu/drm/sun4i/Makefile index 2589f4acd5ae..09fbfd6304ba 100644
> > --- a/drivers/gpu/drm/sun4i/Makefile
> > +++ b/drivers/gpu/drm/sun4i/Makefile
> > @@ -16,7 +16,8 @@ sun8i-drm-hdmi-y              += sun8i_hdmi_phy_clk.o
> > 
> >  sun8i-mixer-y                  += sun8i_mixer.o sun8i_ui_layer.o \
> >  
> >                                    sun8i_vi_layer.o sun8i_ui_scaler.o \
> > 
> > -                                  sun8i_vi_scaler.o sun8i_csc.o
> > +                                  sun8i_vi_scaler.o sun8i_csc.o \
> > +                                  sun8i_tcon_top.o
> > 
> >  sun4i-tcon-y                   += sun4i_crtc.o
> >  sun4i-tcon-y                   += sun4i_dotclock.o
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
> > b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c new file mode 100644
> > index 000000000000..8da0460e0028
> > --- /dev/null
> > +++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
> > @@ -0,0 +1,300 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/* Copyright (c) 2018 Jernej Skrabec <jernej.skrabec@siol.net> */
> > +
> > +#include <drm/drmP.h>
> > +
> > +#include <dt-bindings/clock/sun8i-tcon-top.h>
> > +
> > +#include <linux/bitfield.h>
> > +#include <linux/component.h>
> > +#include <linux/device.h>
> > +#include <linux/module.h>
> > +#include <linux/of_graph.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include "sun8i_tcon_top.h"
> > +
> > +static int sun8i_tcon_top_get_connected_ep_id(struct device_node *node,
> > +                                             int port_id)
> > +{
> > +       struct device_node *ep, *remote, *port;
> > +       struct of_endpoint endpoint;
> > +
> > +       port = of_graph_get_port_by_id(node, port_id);
> > +       if (!port)
> > +               return -ENOENT;
> > +
> > +       for_each_available_child_of_node(port, ep) {
> > +               remote = of_graph_get_remote_port_parent(ep);
> > +               if (!remote)
> > +                       continue;
> > +
> > +               if (of_device_is_available(remote)) {
> > +                       of_graph_parse_endpoint(ep, &endpoint);
> > +
> > +                       of_node_put(remote);
> > +
> > +                       return endpoint.id;
> > +               }
> > +
> > +               of_node_put(remote);
> > +       }
> > +
> > +       return -ENOENT;
> > +}
> > +
> > +static struct clk_hw *sun8i_tcon_top_register_gate(struct device *dev,
> > +                                                  struct clk *parent,
> > +                                                  void __iomem *regs,
> > +                                                  spinlock_t *lock,
> > +                                                  u8 bit, int name_index)
> > +{
> > +       const char *clk_name, *parent_name;
> > +       int ret;
> > +
> > +       parent_name = __clk_get_name(parent);
> 
> You can simply pass in the binding clock name, and have
> 
>     index = of_property_match_string(np, "clock-names", name);
>     parent_name = of_clk_get_parent_name(dev->of_node, index);

That is elegant solution. Should I include that in follow up series?

Best regards,
Jernej

> 
> > +       ret = of_property_read_string_index(dev->of_node,
> > +                                           "clock-output-names",
> > name_index, +                                           &clk_name);
> > +       if (ret)
> > +               return ERR_PTR(ret);
> > +
> > +       return clk_hw_register_gate(dev, clk_name, parent_name,
> > +                                   CLK_SET_RATE_PARENT,
> > +                                   regs + TCON_TOP_GATE_SRC_REG,
> > +                                   bit, 0, lock);
> > +};
> > +
> > +static int sun8i_tcon_top_bind(struct device *dev, struct device *master,
> > +                              void *data)
> > +{
> > +       struct platform_device *pdev = to_platform_device(dev);
> > +       struct clk *dsi, *tcon_tv0, *tcon_tv1, *tve0, *tve1;
> > +       struct clk_hw_onecell_data *clk_data;
> > +       struct sun8i_tcon_top *tcon_top;
> > +       bool mixer0_unused = false;
> > +       struct resource *res;
> > +       void __iomem *regs;
> > +       int ret, i, id;
> > +       u32 val;
> > +
> > +       tcon_top = devm_kzalloc(dev, sizeof(*tcon_top), GFP_KERNEL);
> > +       if (!tcon_top)
> > +               return -ENOMEM;
> > +
> > +       clk_data = devm_kzalloc(dev, sizeof(*clk_data) +
> > +                               sizeof(*clk_data->hws) * CLK_NUM,
> > +                               GFP_KERNEL);
> > +       if (!clk_data)
> > +               return -ENOMEM;
> > +       tcon_top->clk_data = clk_data;
> > +
> > +       spin_lock_init(&tcon_top->reg_lock);
> > +
> > +       tcon_top->rst = devm_reset_control_get(dev, NULL);
> > +       if (IS_ERR(tcon_top->rst)) {
> > +               dev_err(dev, "Couldn't get our reset line\n");
> > +               return PTR_ERR(tcon_top->rst);
> > +       }
> > +
> > +       tcon_top->bus = devm_clk_get(dev, "bus");
> > +       if (IS_ERR(tcon_top->bus)) {
> > +               dev_err(dev, "Couldn't get the bus clock\n");
> > +               return PTR_ERR(tcon_top->bus);
> > +       }
> > +
> > +       dsi = devm_clk_get(dev, "dsi");
> > +       if (IS_ERR(dsi)) {
> > +               dev_err(dev, "Couldn't get the dsi clock\n");
> > +               return PTR_ERR(dsi);
> > +       }
> > +
> > +       tcon_tv0 = devm_clk_get(dev, "tcon-tv0");
> > +       if (IS_ERR(tcon_tv0)) {
> > +               dev_err(dev, "Couldn't get the tcon-tv0 clock\n");
> > +               return PTR_ERR(tcon_tv0);
> > +       }
> > +
> > +       tcon_tv1 = devm_clk_get(dev, "tcon-tv1");
> > +       if (IS_ERR(tcon_tv1)) {
> > +               dev_err(dev, "Couldn't get the tcon-tv1 clock\n");
> > +               return PTR_ERR(tcon_tv1);
> > +       }
> > +
> > +       tve0 = devm_clk_get(dev, "tve0");
> > +       if (IS_ERR(tve0)) {
> > +               dev_err(dev, "Couldn't get the tve0 clock\n");
> > +               return PTR_ERR(tve0);
> > +       }
> > +
> > +       tve1 = devm_clk_get(dev, "tve1");
> > +       if (IS_ERR(tve1)) {
> > +               dev_err(dev, "Couldn't get the tve1 clock\n");
> > +               return PTR_ERR(tve1);
> > +       }
> 
> So you don't actually have to hold references to the parent clocks.
> 
> ChenYu
> 
> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +       regs = devm_ioremap_resource(dev, res);
> > +       if (IS_ERR(regs))
> > +               return PTR_ERR(regs);
> > +
> > +       ret = reset_control_deassert(tcon_top->rst);
> > +       if (ret) {
> > +               dev_err(dev, "Could not deassert ctrl reset control\n");
> > +               return ret;
> > +       }
> > +
> > +       ret = clk_prepare_enable(tcon_top->bus);
> > +       if (ret) {
> > +               dev_err(dev, "Could not enable bus clock\n");
> > +               goto err_assert_reset;
> > +       }
> > +
> > +       val = 0;
> > +
> > +       /* check if HDMI mux output is connected */
> > +       if (sun8i_tcon_top_get_connected_ep_id(dev->of_node, 5) >= 0) {
> > +               /* find HDMI input endpoint id, if it is connected at
> > all*/
> > +               id = sun8i_tcon_top_get_connected_ep_id(dev->of_node, 4);
> > +               if (id >= 0)
> > +                       val = FIELD_PREP(TCON_TOP_HDMI_SRC_MSK, id + 1);
> > +               else
> > +                       DRM_DEBUG_DRIVER("TCON TOP HDMI input is not
> > connected\n"); +       } else {
> > +               DRM_DEBUG_DRIVER("TCON TOP HDMI output is not
> > connected\n"); +       }
> > +
> > +       writel(val, regs + TCON_TOP_GATE_SRC_REG);
> > +
> > +       val = 0;
> > +
> > +       /* process mixer0 mux output */
> > +       id = sun8i_tcon_top_get_connected_ep_id(dev->of_node, 1);
> > +       if (id >= 0) {
> > +               val = FIELD_PREP(TCON_TOP_PORT_DE0_MSK, id);
> > +       } else {
> > +               DRM_DEBUG_DRIVER("TCON TOP mixer0 output is not
> > connected\n"); +               mixer0_unused = true;
> > +       }
> > +
> > +       /* process mixer1 mux output */
> > +       id = sun8i_tcon_top_get_connected_ep_id(dev->of_node, 3);
> > +       if (id >= 0) {
> > +               val |= FIELD_PREP(TCON_TOP_PORT_DE1_MSK, id);
> > +
> > +               /*
> > +                * mixer0 mux has priority over mixer1 mux. We have to
> > +                * make sure mixer0 doesn't overtake TCON from mixer1.
> > +                */
> > +               if (mixer0_unused && id == 0)
> > +                       val |= FIELD_PREP(TCON_TOP_PORT_DE0_MSK, 1);
> > +       } else {
> > +               DRM_DEBUG_DRIVER("TCON TOP mixer1 output is not
> > connected\n"); +       }
> > +
> > +       writel(val, regs + TCON_TOP_PORT_SEL_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 +        * we leave this fixed to TCON TV, since TVE driver for
> > R40 is not yet +        * implemented. Once it is, graph needs to be
> > traversed to determine +        * if TVE is active on each TCON TV. If it
> > is, mux should be switched +        * to TVE clock parent.
> > +        */
> > +       clk_data->hws[CLK_TCON_TOP_TV0] =
> > +               sun8i_tcon_top_register_gate(dev, tcon_tv0, regs,
> > +                                            &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);
> > +
> > +       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);
> > +
> > +       for (i = 0; i < CLK_NUM; i++)
> > +               if (IS_ERR(clk_data->hws[i])) {
> > +                       ret = PTR_ERR(clk_data->hws[i]);
> > +                       goto err_unregister_gates;
> > +               }
> > +
> > +       clk_data->num = CLK_NUM;
> > +
> > +       ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
> > +                                    clk_data);
> > +       if (ret)
> > +               goto err_unregister_gates;
> > +
> > +       dev_set_drvdata(dev, tcon_top);
> > +
> > +       return 0;
> > +
> > +err_unregister_gates:
> > +       for (i = 0; i < CLK_NUM; i++)
> > +               if (clk_data->hws[i])
> > +                       clk_hw_unregister_gate(clk_data->hws[i]);
> > +       clk_disable_unprepare(tcon_top->bus);
> > +err_assert_reset:
> > +       reset_control_assert(tcon_top->rst);
> > +
> > +       return ret;
> > +}
> > +
> > +static void sun8i_tcon_top_unbind(struct device *dev, struct device
> > *master, +                                 void *data)
> > +{
> > +       struct sun8i_tcon_top *tcon_top = dev_get_drvdata(dev);
> > +       struct clk_hw_onecell_data *clk_data = tcon_top->clk_data;
> > +       int i;
> > +
> > +       of_clk_del_provider(dev->of_node);
> > +       for (i = 0; i < CLK_NUM; i++)
> > +               clk_hw_unregister_gate(clk_data->hws[i]);
> > +
> > +       clk_disable_unprepare(tcon_top->bus);
> > +       reset_control_assert(tcon_top->rst);
> > +}
> > +
> > +static const struct component_ops sun8i_tcon_top_ops = {
> > +       .bind   = sun8i_tcon_top_bind,
> > +       .unbind = sun8i_tcon_top_unbind,
> > +};
> > +
> > +static int sun8i_tcon_top_probe(struct platform_device *pdev)
> > +{
> > +       return component_add(&pdev->dev, &sun8i_tcon_top_ops);
> > +}
> > +
> > +static int sun8i_tcon_top_remove(struct platform_device *pdev)
> > +{
> > +       component_del(&pdev->dev, &sun8i_tcon_top_ops);
> > +
> > +       return 0;
> > +}
> > +
> > +/* 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" },
> > +       { /* sentinel */ }
> > +};
> > +MODULE_DEVICE_TABLE(of, sun8i_tcon_top_of_table);
> > +EXPORT_SYMBOL(sun8i_tcon_top_of_table);
> > +
> > +static struct platform_driver sun8i_tcon_top_platform_driver = {
> > +       .probe          = sun8i_tcon_top_probe,
> > +       .remove         = sun8i_tcon_top_remove,
> > +       .driver         = {
> > +               .name           = "sun8i-tcon-top",
> > +               .of_match_table = sun8i_tcon_top_of_table,
> > +       },
> > +};
> > +module_platform_driver(sun8i_tcon_top_platform_driver);
> > +
> > +MODULE_AUTHOR("Jernej Skrabec <jernej.skrabec@siol.net>");
> > +MODULE_DESCRIPTION("Allwinner R40 TCON TOP driver");
> > +MODULE_LICENSE("GPL");
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.h
> > b/drivers/gpu/drm/sun4i/sun8i_tcon_top.h new file mode 100644
> > index 000000000000..39838bbfeaee
> > --- /dev/null
> > +++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.h
> > @@ -0,0 +1,40 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/* Copyright (c) 2018 Jernej Skrabec <jernej.skrabec@siol.net> */
> > +
> > +#ifndef _SUN8I_TCON_TOP_H_
> > +#define _SUN8I_TCON_TOP_H_
> > +
> > +#include <linux/clk.h>
> > +#include <linux/clk-provider.h>
> > +#include <linux/reset.h>
> > +#include <linux/spinlock.h>
> > +
> > +#define TCON_TOP_TCON_TV_SETUP_REG     0x00
> > +
> > +#define TCON_TOP_PORT_SEL_REG          0x1C
> > +#define TCON_TOP_PORT_DE0_MSK                  GENMASK(1, 0)
> > +#define TCON_TOP_PORT_DE1_MSK                  GENMASK(5, 4)
> > +
> > +#define TCON_TOP_GATE_SRC_REG          0x20
> > +#define TCON_TOP_HDMI_SRC_MSK                  GENMASK(29, 28)
> > +#define TCON_TOP_TCON_TV1_GATE                 24
> > +#define TCON_TOP_TCON_TV0_GATE                 20
> > +#define TCON_TOP_TCON_DSI_GATE                 16
> > +
> > +#define CLK_NUM                                        3
> > +
> > +struct sun8i_tcon_top {
> > +       struct clk                      *bus;
> > +       struct clk_hw_onecell_data      *clk_data;
> > +       struct reset_control            *rst;
> > +
> > +       /*
> > +        * spinlock is used to synchronize access to same
> > +        * register where multiple clock gates can be set.
> > +        */
> > +       spinlock_t                      reg_lock;
> > +};
> > +
> > +extern const struct of_device_id sun8i_tcon_top_of_table[];
> > +
> > +#endif /* _SUN8I_TCON_TOP_H_ */
> > --
> > 2.18.0





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

* Re: [linux-sunxi] [PATCH v3 06/24] drm/sun4i: Fix releasing node when enumerating enpoints
  2018-06-28  1:53   ` [linux-sunxi] " Chen-Yu Tsai
@ 2018-06-29 19:15     ` Jernej Škrabec
  2018-06-30  1:09       ` Chen-Yu Tsai
  0 siblings, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-06-29 19:15 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne četrtek, 28. junij 2018 ob 03:53:36 CEST je Chen-Yu Tsai napisal(a):
> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > sun4i_drv_add_endpoints() has a memory leak since it uses of_node_put()
> > when remote is equal to NULL and does nothing when remote has a valid
> > pointer.
> > 
> > Invert the logic to fix memory leak.
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> 
> Given this is a fix, it should have Fixes and stable tags.

How should be this handled given that the patch is already merged and cannot 
be dropped?

Best regards,
Jernej




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

* Re: [PATCH v3 16/24] drm/sun4i: Enable DW HDMI PHY clock
  2018-06-28  2:22   ` Chen-Yu Tsai
  2018-06-28  4:52     ` Jernej Škrabec
@ 2018-06-29 19:19     ` Jernej Škrabec
  2018-06-30  1:11       ` Chen-Yu Tsai
  1 sibling, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-06-29 19:19 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne četrtek, 28. junij 2018 ob 04:22:36 CEST je Chen-Yu Tsai napisal(a):
> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > Current DW HDMI PHY code never prepares and enables PHY clock after it is
> > created. It's just used as it is. This may work in some cases, but it's
> > clearly wrong. Fix it by adding proper calls to enable/disable PHY
> > clock.
> > 
> > Fixes: 4f86e81748fe ("drm/sun4i: Add support for H3 HDMI PHY variant")
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> 
> So why does it work on the H3? Because there's only one PLL that the whole
> display pipeline uses?
> 
> We should probably tag this for stable. So,
> 
> Cc: <stable@vger.kernel.org>
> Reviewed-by: Chen-Yu Tsai <wens@csie.org>

Same question as before, how this should be handled? Can I send separate patch 
with same content to stable ML only?

Best regards,
Jernej




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

* Re: [PATCH v3 17/24] drm/sun4i: Don't change clock bits in DW HDMI PHY driver
  2018-06-28  2:24   ` Chen-Yu Tsai
@ 2018-06-29 19:23     ` Jernej Škrabec
  0 siblings, 0 replies; 87+ messages in thread
From: Jernej Škrabec @ 2018-06-29 19:23 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne četrtek, 28. junij 2018 ob 04:24:02 CEST je Chen-Yu Tsai napisal(a):
> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net> 
wrote:
> > DW HDMI PHY driver and PHY clock driver share same registers. Make sure
> > that DW HDMI PHY setup code doesn't change any clock related bits.
> > During initialization, set PHY PLL parent bit to 0.
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> 
> Reviewed-by: Chen-Yu Tsai <wens@csie.org>
> 
> and maybe a fixes tag?

No need for fixes tag here. H3 and H5 HDMI PHYs have only one possible parent 
clock. Without this patch, 0 is always written in parent clock bit, which 
correctly selects first parent.

This is preparation patch for 2 clock parents support.

Best regards,
Jernej




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

* Re: [linux-sunxi] Re: [PATCH v3 15/24] dt-bindings: display: sun4i-drm: Add description of A64 HDMI PHY
  2018-06-28  7:00       ` [linux-sunxi] " Chen-Yu Tsai
@ 2018-06-29 19:32         ` Jernej Škrabec
  2018-07-04  4:05           ` Chen-Yu Tsai
  0 siblings, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-06-29 19:32 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne četrtek, 28. junij 2018 ob 09:00:32 CEST je Chen-Yu Tsai napisal(a):
> On Thu, Jun 28, 2018 at 12:51 PM, Jernej Škrabec
> 
> <jernej.skrabec@siol.net> wrote:
> > Dne četrtek, 28. junij 2018 ob 04:19:55 CEST je Chen-Yu Tsai napisal(a):
> >> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net>
> > 
> > wrote:
> >> > A64 HDMI PHY is similar to H3 HDMI PHY except it has two possible PLL
> >> > clock parents. It is compatible to other HDMI PHYs, like that found in
> >> > R40.
> >> > 
> >> > Acked-by: Rob Herring <robh@kernel.org>
> >> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> >> > ---
> >> > 
> >> >  Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 4 +++-
> >> >  1 file changed, 3 insertions(+), 1 deletion(-)
> >> > 
> >> > diff --git
> >> > a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> >> > b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt index
> >> > 84fe38dbb900..dc83f21ef188 100644
> >> > --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> >> > +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> >> > @@ -101,6 +101,7 @@ DWC HDMI PHY
> >> > 
> >> >  Required properties:
> >> >    - compatible: value must be one of:
> >> > +    * allwinner,sun50i-a64-hdmi-phy
> >> > 
> >> >      * allwinner,sun8i-a83t-hdmi-phy
> >> >      * allwinner,sun8i-h3-hdmi-phy
> >> 
> >> Nit: the list is sorted by family first, then SoC name, so it should
> >> be the last on the list.
> > 
> > I went alphabetically, since "5" is before "8"...
> 
> I see. I think version sort applies here, given that sun50i is newer
> than sun8i.

Should I make a patch for that?

Best regards,
Jernej

> 
> ChenYu
> 
> > Best regards,
> > Jernej
> > 
> >> Otherwise,
> >> 
> >> Reviewed-by: Chen-Yu Tsai <wens@csie.org>
> >> 
> >> >    - reg: base address and size of memory-mapped region
> >> > 
> >> > @@ -111,8 +112,9 @@ Required properties:
> >> >    - resets: phandle to the reset controller driving the PHY
> >> >    - reset-names: must be "phy"
> >> > 
> >> > -H3 HDMI PHY requires additional clock:
> >> > 
> >> > +H3 and A64 HDMI PHY require additional clocks:
> >> >    - pll-0: parent of phy clock
> >> > 
> >> > +  - pll-1: second possible phy clock parent (A64 only)
> >> > 
> >> >  TV Encoder
> >> >  ----------
> >> > 
> >> > --
> >> > 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] 87+ messages in thread

* Re: [linux-sunxi] [PATCH v3 06/24] drm/sun4i: Fix releasing node when enumerating enpoints
  2018-06-29 19:15     ` Jernej Škrabec
@ 2018-06-30  1:09       ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-30  1:09 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Sat, Jun 30, 2018 at 3:15 AM, Jernej Škrabec <jernej.skrabec@siol.net> wrote:
> Dne četrtek, 28. junij 2018 ob 03:53:36 CEST je Chen-Yu Tsai napisal(a):
>> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net>
> wrote:
>> > sun4i_drv_add_endpoints() has a memory leak since it uses of_node_put()
>> > when remote is equal to NULL and does nothing when remote has a valid
>> > pointer.
>> >
>> > Invert the logic to fix memory leak.
>> >
>> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>>
>> Given this is a fix, it should have Fixes and stable tags.
>
> How should be this handled given that the patch is already merged and cannot
> be dropped?

We can't. We'll have to manually submit it for stable once this lands
in Linus' tree.

ChenYu

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

* Re: [PATCH v3 16/24] drm/sun4i: Enable DW HDMI PHY clock
  2018-06-29 19:19     ` Jernej Škrabec
@ 2018-06-30  1:11       ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-30  1:11 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Sat, Jun 30, 2018 at 3:19 AM, Jernej Škrabec <jernej.skrabec@siol.net> wrote:
> Dne četrtek, 28. junij 2018 ob 04:22:36 CEST je Chen-Yu Tsai napisal(a):
>> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net>
> wrote:
>> > Current DW HDMI PHY code never prepares and enables PHY clock after it is
>> > created. It's just used as it is. This may work in some cases, but it's
>> > clearly wrong. Fix it by adding proper calls to enable/disable PHY
>> > clock.
>> >
>> > Fixes: 4f86e81748fe ("drm/sun4i: Add support for H3 HDMI PHY variant")
>> >
>> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>>
>> So why does it work on the H3? Because there's only one PLL that the whole
>> display pipeline uses?
>>
>> We should probably tag this for stable. So,
>>
>> Cc: <stable@vger.kernel.org>
>> Reviewed-by: Chen-Yu Tsai <wens@csie.org>
>
> Same question as before, how this should be handled? Can I send separate patch
> with same content to stable ML only?

Yes, including the hash of the commit which is already in Linus' tree. So
you have to send it after the next -rc1.

ChenYu

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

* Re: [linux-sunxi] Re: [PATCH v3 05/24] drm/sun4i: Add TCON TOP driver
  2018-06-29 19:09     ` Jernej Škrabec
@ 2018-06-30  1:13       ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-06-30  1:13 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Sat, Jun 30, 2018 at 3:09 AM, Jernej Škrabec <jernej.skrabec@siol.net> wrote:
> Dne četrtek, 28. junij 2018 ob 03:47:20 CEST je Chen-Yu Tsai napisal(a):
>> Hi,
>>
>> So I'm late to the party, but...
>>
>> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net>
> wrote:
>> > As already described in DT binding, TCON TOP is responsible for
>> > configuring display pipeline. In this initial driver focus is on HDMI
>> > pipeline, so TVE and LCD configuration is not implemented.
>> >
>> > Implemented features:
>> > - HDMI source selection
>> > - clock driver (TCON and DSI gating)
>> > - connecting mixers and TCONS
>> >
>> > Something similar also existed in previous SoCs, except that it was part
>> > of first TCON.
>> >
>> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>> > ---
>> >
>> >  drivers/gpu/drm/sun4i/Makefile         |   3 +-
>> >  drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 300 +++++++++++++++++++++++++
>> >  drivers/gpu/drm/sun4i/sun8i_tcon_top.h |  40 ++++
>> >  3 files changed, 342 insertions(+), 1 deletion(-)
>> >  create mode 100644 drivers/gpu/drm/sun4i/sun8i_tcon_top.c
>> >  create mode 100644 drivers/gpu/drm/sun4i/sun8i_tcon_top.h
>> >
>> > diff --git a/drivers/gpu/drm/sun4i/Makefile
>> > b/drivers/gpu/drm/sun4i/Makefile index 2589f4acd5ae..09fbfd6304ba 100644
>> > --- a/drivers/gpu/drm/sun4i/Makefile
>> > +++ b/drivers/gpu/drm/sun4i/Makefile
>> > @@ -16,7 +16,8 @@ sun8i-drm-hdmi-y              += sun8i_hdmi_phy_clk.o
>> >
>> >  sun8i-mixer-y                  += sun8i_mixer.o sun8i_ui_layer.o \
>> >
>> >                                    sun8i_vi_layer.o sun8i_ui_scaler.o \
>> >
>> > -                                  sun8i_vi_scaler.o sun8i_csc.o
>> > +                                  sun8i_vi_scaler.o sun8i_csc.o \
>> > +                                  sun8i_tcon_top.o
>> >
>> >  sun4i-tcon-y                   += sun4i_crtc.o
>> >  sun4i-tcon-y                   += sun4i_dotclock.o
>> >
>> > diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
>> > b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c new file mode 100644
>> > index 000000000000..8da0460e0028
>> > --- /dev/null
>> > +++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
>> > @@ -0,0 +1,300 @@
>> > +// SPDX-License-Identifier: GPL-2.0+
>> > +/* Copyright (c) 2018 Jernej Skrabec <jernej.skrabec@siol.net> */
>> > +
>> > +#include <drm/drmP.h>
>> > +
>> > +#include <dt-bindings/clock/sun8i-tcon-top.h>
>> > +
>> > +#include <linux/bitfield.h>
>> > +#include <linux/component.h>
>> > +#include <linux/device.h>
>> > +#include <linux/module.h>
>> > +#include <linux/of_graph.h>
>> > +#include <linux/platform_device.h>
>> > +
>> > +#include "sun8i_tcon_top.h"
>> > +
>> > +static int sun8i_tcon_top_get_connected_ep_id(struct device_node *node,
>> > +                                             int port_id)
>> > +{
>> > +       struct device_node *ep, *remote, *port;
>> > +       struct of_endpoint endpoint;
>> > +
>> > +       port = of_graph_get_port_by_id(node, port_id);
>> > +       if (!port)
>> > +               return -ENOENT;
>> > +
>> > +       for_each_available_child_of_node(port, ep) {
>> > +               remote = of_graph_get_remote_port_parent(ep);
>> > +               if (!remote)
>> > +                       continue;
>> > +
>> > +               if (of_device_is_available(remote)) {
>> > +                       of_graph_parse_endpoint(ep, &endpoint);
>> > +
>> > +                       of_node_put(remote);
>> > +
>> > +                       return endpoint.id;
>> > +               }
>> > +
>> > +               of_node_put(remote);
>> > +       }
>> > +
>> > +       return -ENOENT;
>> > +}
>> > +
>> > +static struct clk_hw *sun8i_tcon_top_register_gate(struct device *dev,
>> > +                                                  struct clk *parent,
>> > +                                                  void __iomem *regs,
>> > +                                                  spinlock_t *lock,
>> > +                                                  u8 bit, int name_index)
>> > +{
>> > +       const char *clk_name, *parent_name;
>> > +       int ret;
>> > +
>> > +       parent_name = __clk_get_name(parent);
>>
>> You can simply pass in the binding clock name, and have
>>
>>     index = of_property_match_string(np, "clock-names", name);
>>     parent_name = of_clk_get_parent_name(dev->of_node, index);
>
> That is elegant solution. Should I include that in follow up series?

If you have time for it, go ahead. This is just cleanup, so there's
no urgency. If not, I suppose I could do it later on.

ChenYu

> Best regards,
> Jernej
>
>>
>> > +       ret = of_property_read_string_index(dev->of_node,
>> > +                                           "clock-output-names",
>> > name_index, +                                           &clk_name);
>> > +       if (ret)
>> > +               return ERR_PTR(ret);
>> > +
>> > +       return clk_hw_register_gate(dev, clk_name, parent_name,
>> > +                                   CLK_SET_RATE_PARENT,
>> > +                                   regs + TCON_TOP_GATE_SRC_REG,
>> > +                                   bit, 0, lock);
>> > +};
>> > +
>> > +static int sun8i_tcon_top_bind(struct device *dev, struct device *master,
>> > +                              void *data)
>> > +{
>> > +       struct platform_device *pdev = to_platform_device(dev);
>> > +       struct clk *dsi, *tcon_tv0, *tcon_tv1, *tve0, *tve1;
>> > +       struct clk_hw_onecell_data *clk_data;
>> > +       struct sun8i_tcon_top *tcon_top;
>> > +       bool mixer0_unused = false;
>> > +       struct resource *res;
>> > +       void __iomem *regs;
>> > +       int ret, i, id;
>> > +       u32 val;
>> > +
>> > +       tcon_top = devm_kzalloc(dev, sizeof(*tcon_top), GFP_KERNEL);
>> > +       if (!tcon_top)
>> > +               return -ENOMEM;
>> > +
>> > +       clk_data = devm_kzalloc(dev, sizeof(*clk_data) +
>> > +                               sizeof(*clk_data->hws) * CLK_NUM,
>> > +                               GFP_KERNEL);
>> > +       if (!clk_data)
>> > +               return -ENOMEM;
>> > +       tcon_top->clk_data = clk_data;
>> > +
>> > +       spin_lock_init(&tcon_top->reg_lock);
>> > +
>> > +       tcon_top->rst = devm_reset_control_get(dev, NULL);
>> > +       if (IS_ERR(tcon_top->rst)) {
>> > +               dev_err(dev, "Couldn't get our reset line\n");
>> > +               return PTR_ERR(tcon_top->rst);
>> > +       }
>> > +
>> > +       tcon_top->bus = devm_clk_get(dev, "bus");
>> > +       if (IS_ERR(tcon_top->bus)) {
>> > +               dev_err(dev, "Couldn't get the bus clock\n");
>> > +               return PTR_ERR(tcon_top->bus);
>> > +       }
>> > +
>> > +       dsi = devm_clk_get(dev, "dsi");
>> > +       if (IS_ERR(dsi)) {
>> > +               dev_err(dev, "Couldn't get the dsi clock\n");
>> > +               return PTR_ERR(dsi);
>> > +       }
>> > +
>> > +       tcon_tv0 = devm_clk_get(dev, "tcon-tv0");
>> > +       if (IS_ERR(tcon_tv0)) {
>> > +               dev_err(dev, "Couldn't get the tcon-tv0 clock\n");
>> > +               return PTR_ERR(tcon_tv0);
>> > +       }
>> > +
>> > +       tcon_tv1 = devm_clk_get(dev, "tcon-tv1");
>> > +       if (IS_ERR(tcon_tv1)) {
>> > +               dev_err(dev, "Couldn't get the tcon-tv1 clock\n");
>> > +               return PTR_ERR(tcon_tv1);
>> > +       }
>> > +
>> > +       tve0 = devm_clk_get(dev, "tve0");
>> > +       if (IS_ERR(tve0)) {
>> > +               dev_err(dev, "Couldn't get the tve0 clock\n");
>> > +               return PTR_ERR(tve0);
>> > +       }
>> > +
>> > +       tve1 = devm_clk_get(dev, "tve1");
>> > +       if (IS_ERR(tve1)) {
>> > +               dev_err(dev, "Couldn't get the tve1 clock\n");
>> > +               return PTR_ERR(tve1);
>> > +       }
>>
>> So you don't actually have to hold references to the parent clocks.
>>
>> ChenYu
>>
>> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> > +       regs = devm_ioremap_resource(dev, res);
>> > +       if (IS_ERR(regs))
>> > +               return PTR_ERR(regs);
>> > +
>> > +       ret = reset_control_deassert(tcon_top->rst);
>> > +       if (ret) {
>> > +               dev_err(dev, "Could not deassert ctrl reset control\n");
>> > +               return ret;
>> > +       }
>> > +
>> > +       ret = clk_prepare_enable(tcon_top->bus);
>> > +       if (ret) {
>> > +               dev_err(dev, "Could not enable bus clock\n");
>> > +               goto err_assert_reset;
>> > +       }
>> > +
>> > +       val = 0;
>> > +
>> > +       /* check if HDMI mux output is connected */
>> > +       if (sun8i_tcon_top_get_connected_ep_id(dev->of_node, 5) >= 0) {
>> > +               /* find HDMI input endpoint id, if it is connected at
>> > all*/
>> > +               id = sun8i_tcon_top_get_connected_ep_id(dev->of_node, 4);
>> > +               if (id >= 0)
>> > +                       val = FIELD_PREP(TCON_TOP_HDMI_SRC_MSK, id + 1);
>> > +               else
>> > +                       DRM_DEBUG_DRIVER("TCON TOP HDMI input is not
>> > connected\n"); +       } else {
>> > +               DRM_DEBUG_DRIVER("TCON TOP HDMI output is not
>> > connected\n"); +       }
>> > +
>> > +       writel(val, regs + TCON_TOP_GATE_SRC_REG);
>> > +
>> > +       val = 0;
>> > +
>> > +       /* process mixer0 mux output */
>> > +       id = sun8i_tcon_top_get_connected_ep_id(dev->of_node, 1);
>> > +       if (id >= 0) {
>> > +               val = FIELD_PREP(TCON_TOP_PORT_DE0_MSK, id);
>> > +       } else {
>> > +               DRM_DEBUG_DRIVER("TCON TOP mixer0 output is not
>> > connected\n"); +               mixer0_unused = true;
>> > +       }
>> > +
>> > +       /* process mixer1 mux output */
>> > +       id = sun8i_tcon_top_get_connected_ep_id(dev->of_node, 3);
>> > +       if (id >= 0) {
>> > +               val |= FIELD_PREP(TCON_TOP_PORT_DE1_MSK, id);
>> > +
>> > +               /*
>> > +                * mixer0 mux has priority over mixer1 mux. We have to
>> > +                * make sure mixer0 doesn't overtake TCON from mixer1.
>> > +                */
>> > +               if (mixer0_unused && id == 0)
>> > +                       val |= FIELD_PREP(TCON_TOP_PORT_DE0_MSK, 1);
>> > +       } else {
>> > +               DRM_DEBUG_DRIVER("TCON TOP mixer1 output is not
>> > connected\n"); +       }
>> > +
>> > +       writel(val, regs + TCON_TOP_PORT_SEL_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 +        * we leave this fixed to TCON TV, since TVE driver for
>> > R40 is not yet +        * implemented. Once it is, graph needs to be
>> > traversed to determine +        * if TVE is active on each TCON TV. If it
>> > is, mux should be switched +        * to TVE clock parent.
>> > +        */
>> > +       clk_data->hws[CLK_TCON_TOP_TV0] =
>> > +               sun8i_tcon_top_register_gate(dev, tcon_tv0, regs,
>> > +                                            &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);
>> > +
>> > +       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);
>> > +
>> > +       for (i = 0; i < CLK_NUM; i++)
>> > +               if (IS_ERR(clk_data->hws[i])) {
>> > +                       ret = PTR_ERR(clk_data->hws[i]);
>> > +                       goto err_unregister_gates;
>> > +               }
>> > +
>> > +       clk_data->num = CLK_NUM;
>> > +
>> > +       ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
>> > +                                    clk_data);
>> > +       if (ret)
>> > +               goto err_unregister_gates;
>> > +
>> > +       dev_set_drvdata(dev, tcon_top);
>> > +
>> > +       return 0;
>> > +
>> > +err_unregister_gates:
>> > +       for (i = 0; i < CLK_NUM; i++)
>> > +               if (clk_data->hws[i])
>> > +                       clk_hw_unregister_gate(clk_data->hws[i]);
>> > +       clk_disable_unprepare(tcon_top->bus);
>> > +err_assert_reset:
>> > +       reset_control_assert(tcon_top->rst);
>> > +
>> > +       return ret;
>> > +}
>> > +
>> > +static void sun8i_tcon_top_unbind(struct device *dev, struct device
>> > *master, +                                 void *data)
>> > +{
>> > +       struct sun8i_tcon_top *tcon_top = dev_get_drvdata(dev);
>> > +       struct clk_hw_onecell_data *clk_data = tcon_top->clk_data;
>> > +       int i;
>> > +
>> > +       of_clk_del_provider(dev->of_node);
>> > +       for (i = 0; i < CLK_NUM; i++)
>> > +               clk_hw_unregister_gate(clk_data->hws[i]);
>> > +
>> > +       clk_disable_unprepare(tcon_top->bus);
>> > +       reset_control_assert(tcon_top->rst);
>> > +}
>> > +
>> > +static const struct component_ops sun8i_tcon_top_ops = {
>> > +       .bind   = sun8i_tcon_top_bind,
>> > +       .unbind = sun8i_tcon_top_unbind,
>> > +};
>> > +
>> > +static int sun8i_tcon_top_probe(struct platform_device *pdev)
>> > +{
>> > +       return component_add(&pdev->dev, &sun8i_tcon_top_ops);
>> > +}
>> > +
>> > +static int sun8i_tcon_top_remove(struct platform_device *pdev)
>> > +{
>> > +       component_del(&pdev->dev, &sun8i_tcon_top_ops);
>> > +
>> > +       return 0;
>> > +}
>> > +
>> > +/* 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" },
>> > +       { /* sentinel */ }
>> > +};
>> > +MODULE_DEVICE_TABLE(of, sun8i_tcon_top_of_table);
>> > +EXPORT_SYMBOL(sun8i_tcon_top_of_table);
>> > +
>> > +static struct platform_driver sun8i_tcon_top_platform_driver = {
>> > +       .probe          = sun8i_tcon_top_probe,
>> > +       .remove         = sun8i_tcon_top_remove,
>> > +       .driver         = {
>> > +               .name           = "sun8i-tcon-top",
>> > +               .of_match_table = sun8i_tcon_top_of_table,
>> > +       },
>> > +};
>> > +module_platform_driver(sun8i_tcon_top_platform_driver);
>> > +
>> > +MODULE_AUTHOR("Jernej Skrabec <jernej.skrabec@siol.net>");
>> > +MODULE_DESCRIPTION("Allwinner R40 TCON TOP driver");
>> > +MODULE_LICENSE("GPL");
>> > diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.h
>> > b/drivers/gpu/drm/sun4i/sun8i_tcon_top.h new file mode 100644
>> > index 000000000000..39838bbfeaee
>> > --- /dev/null
>> > +++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.h
>> > @@ -0,0 +1,40 @@
>> > +/* SPDX-License-Identifier: GPL-2.0+ */
>> > +/* Copyright (c) 2018 Jernej Skrabec <jernej.skrabec@siol.net> */
>> > +
>> > +#ifndef _SUN8I_TCON_TOP_H_
>> > +#define _SUN8I_TCON_TOP_H_
>> > +
>> > +#include <linux/clk.h>
>> > +#include <linux/clk-provider.h>
>> > +#include <linux/reset.h>
>> > +#include <linux/spinlock.h>
>> > +
>> > +#define TCON_TOP_TCON_TV_SETUP_REG     0x00
>> > +
>> > +#define TCON_TOP_PORT_SEL_REG          0x1C
>> > +#define TCON_TOP_PORT_DE0_MSK                  GENMASK(1, 0)
>> > +#define TCON_TOP_PORT_DE1_MSK                  GENMASK(5, 4)
>> > +
>> > +#define TCON_TOP_GATE_SRC_REG          0x20
>> > +#define TCON_TOP_HDMI_SRC_MSK                  GENMASK(29, 28)
>> > +#define TCON_TOP_TCON_TV1_GATE                 24
>> > +#define TCON_TOP_TCON_TV0_GATE                 20
>> > +#define TCON_TOP_TCON_DSI_GATE                 16
>> > +
>> > +#define CLK_NUM                                        3
>> > +
>> > +struct sun8i_tcon_top {
>> > +       struct clk                      *bus;
>> > +       struct clk_hw_onecell_data      *clk_data;
>> > +       struct reset_control            *rst;
>> > +
>> > +       /*
>> > +        * spinlock is used to synchronize access to same
>> > +        * register where multiple clock gates can be set.
>> > +        */
>> > +       spinlock_t                      reg_lock;
>> > +};
>> > +
>> > +extern const struct of_device_id sun8i_tcon_top_of_table[];
>> > +
>> > +#endif /* _SUN8I_TCON_TOP_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] 87+ messages in thread

* Re: [linux-sunxi] Re: [PATCH v3 09/24] drm/sun4i: Don't skip TCONs if they don't have channel 0
  2018-06-28  6:24       ` [linux-sunxi] " Chen-Yu Tsai
@ 2018-07-01  8:27         ` Jernej Škrabec
  2018-07-01 15:11           ` Chen-Yu Tsai
  0 siblings, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-07-01  8:27 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne četrtek, 28. junij 2018 ob 08:24:34 CEST je Chen-Yu Tsai napisal(a):
> On Thu, Jun 28, 2018 at 12:45 PM, Jernej Škrabec
> 
> <jernej.skrabec@siol.net> wrote:
> > Dne četrtek, 28. junij 2018 ob 03:51:31 CEST je Chen-Yu Tsai napisal(a):
> >> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net>
> > 
> > wrote:
> >> > TV TCONs (channel 1 only) are always connected to TV or HDMI encoder.
> >> > Because of that, all output endpoints on such TCON node will point to a
> >> > encoder which is part of component framework.
> >> > 
> >> > Correct current graph traversing algorithm in such way that it doesn't
> >> > skip output enpoints with id 0 on TV TCONs.
> >> 
> >> No. Our bindings say that endpoint 0 _is_ channel 0. For TCONs that don't
> >> have channel 0, it must be skipped.
> > 
> > I'm not sure where this is stated. I read TCON binding again. Can you
> > please point me to it?
> 
> https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bind
> ings/display/sunxi/sun4i-drm.txt#L169
> 
> Our TCON driver still expects RGB or LVDS panel / bridges on endpoint 0.

Yes, but that can only happen on TCON which has channel 0. TV TCONs (those 
with channel 1 only) can't have panels or bridges connected to them, because 
they are internally always connected to either HDMI or TV encoder or both. 
Actually, R40 is the only SoC, where same TV TCON can be connected to TV 
encoder or HDMI. Others have specialized TV TCONs, which are connect to only 
one encoder.

IMO TV TCONs are really just stripped down LCD TCONs to support one (or max 
two) specific encoder.

> So I guess this was sort of implied historically. It's no longer true.
> This is something we should probably fix.

Fixed in what way? You mean update bindings to mention that TCON output 
endpoint 0 is reserved for panels or bridges?

> 
> In practice our drivers don't look at it (yet), but rely on the downstream
> encoder type to determine which channel to use.
> 
> But please add the "allwinner,tcon-channel" property as specified in
> the binding.

It's my understanding of TCON binding documentation that property 
"allwinner,tcon-channel" is needed only if TCON supports both channels. TV 
TCON clearly supports only channel 1. In that case, there is no doubt to which 
channel output endpoint belongs.

If that's not true, dt bindings documentation should be reworded to contain 
word "needed" or something similar. Currently, no DT for newer SoC contains 
that property (for example, A83T, H3, H5 or even A33). On A33 this is even 
more interesting, since tcon0 has only channel 0 and has DSI output endpoint 
with number 1. According to TCON binding docs, if "allwinner,tcon-channel" is 
not preset, endpoint number represent channel. So, that would mean DSI needs 
channel 1 on tcon which supports clearly only channel 0. So either there TCON 
bindings documentation needs updates or DT for A33 has to be updated.

BTW, "allwinner,tcon-channel" property is not used at all in the code.

> 
> > So on TV TCONs on R40 (without channel 0) TVE would be endpoint 1 and HDMI
> > endpoint 2 (or the other way around)?
> 
> Which one goes first doesn't quite matter. IIRC there's also a mux for TVE?

AFAIK, TV TCON is by default connected to TV encoder unless HDMI mux in TCON 
TOP points to it. I think it's best put TVE with lower number since it's 
default and HDMI with higher number.

Best regards,
Jernej




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

* Re: [linux-sunxi] Re: [PATCH v3 23/24] ARM: dts: sun8i: r40: Add HDMI pipeline
  2018-06-28  6:51       ` [linux-sunxi] " Chen-Yu Tsai
@ 2018-07-01 10:41         ` Jernej Škrabec
  2018-07-01 13:52           ` Chen-Yu Tsai
  0 siblings, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-07-01 10:41 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne četrtek, 28. junij 2018 ob 08:51:07 CEST je Chen-Yu Tsai napisal(a):
> On Thu, Jun 28, 2018 at 1:15 PM, Jernej Škrabec <jernej.skrabec@siol.net> 
wrote:
> > Dne četrtek, 28. junij 2018 ob 04:50:09 CEST je Chen-Yu Tsai napisal(a):
> >> On Mon, Jun 25, 2018 at 8:03 PM, Jernej Skrabec <jernej.skrabec@siol.net>
> > 
> > wrote:
> >> > Add all entries needed for HDMI to function properly.
> >> > 
> >> > Since R40 has highly configurable pipeline, both mixers and both TCON
> >> > TVs are added. Board specific DT should then connect them together
> >> > trough TCON TOP muxers to best fit the purpose of the board.
> >> > 
> >> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> >> > ---
> >> > 
> >> >  arch/arm/boot/dts/sun8i-r40.dtsi | 269 +++++++++++++++++++++++++++++++
> >> >  1 file changed, 269 insertions(+)
> >> > 
> >> > diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi
> >> > b/arch/arm/boot/dts/sun8i-r40.dtsi index 173dcc1652d2..a2a75fb04caf
> >> > 100644
> >> > --- a/arch/arm/boot/dts/sun8i-r40.dtsi
> >> > +++ b/arch/arm/boot/dts/sun8i-r40.dtsi
> >> > @@ -42,8 +42,11 @@
> >> > 
> >> >   */
> >> >  
> >> >  #include <dt-bindings/interrupt-controller/arm-gic.h>
> >> > 
> >> > +#include <dt-bindings/clock/sun8i-de2.h>
> >> > 
> >> >  #include <dt-bindings/clock/sun8i-r40-ccu.h>
> >> > 
> >> > +#include <dt-bindings/clock/sun8i-tcon-top.h>
> > 
> > Maxime, above line breaks compilation for build robot, sorry.
> > 
> >> >  #include <dt-bindings/reset/sun8i-r40-ccu.h>
> >> > 
> >> > +#include <dt-bindings/reset/sun8i-de2.h>
> >> > 
> >> >  / {
> >> >  
> >> >         #address-cells = <1>;
> >> > 
> >> > @@ -99,12 +102,76 @@
> >> > 
> >> >                 };
> >> >         
> >> >         };
> >> > 
> >> > +       de: display-engine {
> >> > +               compatible = "allwinner,sun8i-r40-display-engine",
> >> > +                            "allwinner,sun8i-h3-display-engine";
> >> 
> >> Given that the display pipeline looks different, they should not be
> >> compatible.
> > 
> > Ok.
> > 
> >> > +               allwinner,pipelines = <&mixer0>, <&mixer1>;
> >> > +               status = "disabled";
> >> > +       };
> >> > +
> >> > 
> >> >         soc {
> >> >         
> >> >                 compatible = "simple-bus";
> >> >                 #address-cells = <1>;
> >> >                 #size-cells = <1>;
> >> >                 ranges;
> >> > 
> >> > +               display_clocks: clock@1000000 {
> >> > +                       compatible = "allwinner,sun8i-r40-de2-clk",
> >> > +                                    "allwinner,sun8i-h3-de2-clk";
> >> > +                       reg = <0x01000000 0x100000>;
> >> > +                       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@1100000 {
> >> > +                       compatible = "allwinner,sun8i-r40-de2-mixer-0";
> >> > +                       reg = <0x01100000 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: endpoint {
> >> > +                                               remote-endpoint =
> >> > <&tcon_top_mixer0_in_mixer0>; +                                      
> >> > };
> >> > +                               };
> >> > +                       };
> >> > +               };
> >> > +
> >> > +               mixer1: mixer@1200000 {
> >> > +                       compatible = "allwinner,sun8i-r40-de2-mixer-1";
> >> > +                       reg = <0x01200000 0x100000>;
> >> > +                       clocks = <&display_clocks CLK_BUS_MIXER1>,
> >> > +                                <&display_clocks CLK_MIXER1>;
> >> > +                       clock-names = "bus",
> >> > +                                     "mod";
> >> > +                       resets = <&display_clocks RST_WB>;
> >> > +
> >> > +                       ports {
> >> > +                               #address-cells = <1>;
> >> > +                               #size-cells = <0>;
> >> > +
> >> > +                               mixer1_out: port@1 {
> >> > +                                       reg = <1>;
> >> > +                                       mixer1_out_tcon_top: endpoint {
> >> > +                                               remote-endpoint =
> >> > <&tcon_top_mixer1_in_mixer1>; +                                      
> >> > };
> >> > +                               };
> >> > +                       };
> >> > +               };
> >> > +
> >> > 
> >> >                 nmi_intc: interrupt-controller@1c00030 {
> >> >                 
> >> >                         compatible = "allwinner,sun7i-a20-sc-nmi";
> >> >                         interrupt-controller;
> >> > 
> >> > @@ -451,6 +518,163 @@
> >> > 
> >> >                         #size-cells = <0>;
> >> >                 
> >> >                 };
> >> > 
> >> > +               tcon_top: tcon-top@1c70000 {
> >> > +                       compatible = "allwinner,sun8i-r40-tcon-top";
> >> > +                       reg = <0x01c70000 0x1000>;
> >> > +                       clocks = <&ccu CLK_BUS_TCON_TOP>,
> >> > +                                <&ccu CLK_TCON_TV0>,
> >> > +                                <&ccu CLK_TVE0>,
> >> > +                                <&ccu CLK_TCON_TV1>,
> >> > +                                <&ccu CLK_TVE1>,
> >> > +                                <&ccu CLK_DSI_DPHY>;
> >> > +                       clock-names = "bus",
> >> > +                                     "tcon-tv0",
> >> > +                                     "tve0",
> >> > +                                     "tcon-tv1",
> >> > +                                     "tve1",
> >> > +                                     "dsi";
> >> > +                       clock-output-names = "tcon-top-tv0",
> >> > +                                            "tcon-top-tv1",
> >> > +                                            "tcon-top-dsi";
> >> > +                       resets = <&ccu RST_BUS_TCON_TOP>;
> >> > +                       #clock-cells = <1>;
> >> > +
> >> > +                       ports {
> >> > +                               #address-cells = <1>;
> >> > +                               #size-cells = <0>;
> >> > +
> >> > +                               tcon_top_mixer0_in: port@0 {
> >> > +                                       reg = <0>;
> >> > +
> >> > +                                       tcon_top_mixer0_in_mixer0:
> >> > endpoint { +
> >> > remote-endpoint = <&mixer0_out_tcon_top>; +
> >> > 
> >> >         };
> >> > 
> >> > +                               };
> >> > +
> >> > +                               tcon_top_mixer0_out: port@1 {
> >> > +                                       #address-cells = <1>;
> >> > +                                       #size-cells = <0>;
> >> > +                                       reg = <1>;
> >> > +
> >> > +                                       tcon_top_mixer0_out_tcon_lcd0:
> >> > endpoint@0 { +                                               reg = <0>;
> >> > +                                       };
> >> > +
> >> > +                                       tcon_top_mixer0_out_tcon_lcd1:
> >> > endpoint@1 { +                                               reg = <1>;
> >> > +                                       };
> >> > +
> >> > +                                       tcon_top_mixer0_out_tcon_tv0:
> >> > endpoint@2 { +                                               reg = <2>;
> >> > +                                       };
> >> > +
> >> > +                                       tcon_top_mixer0_out_tcon_tv1:
> >> > endpoint@3 { +                                               reg = <3>;
> >> > +                                       };
> >> > +                               };
> >> > +
> >> > +                               tcon_top_mixer1_in: port@2 {
> >> > +                                       reg = <2>;
> >> > +
> >> > +                                       tcon_top_mixer1_in_mixer1:
> >> > endpoint { +
> >> > remote-endpoint = <&mixer1_out_tcon_top>; +
> >> > 
> >> >         };
> >> > 
> >> > +                               };
> >> > +
> >> > +                               tcon_top_mixer1_out: port@3 {
> >> > +                                       #address-cells = <1>;
> >> > +                                       #size-cells = <0>;
> >> > +                                       reg = <3>;
> >> > +
> >> > +                                       tcon_top_mixer1_out_tcon_lcd0:
> >> > endpoint@0 { +                                               reg = <0>;
> >> > +                                       };
> >> > +
> >> > +                                       tcon_top_mixer1_out_tcon_lcd1:
> >> > endpoint@1 { +                                               reg = <1>;
> >> > +                                       };
> >> > +
> >> > +                                       tcon_top_mixer1_out_tcon_tv0:
> >> > endpoint@2 { +                                               reg = <2>;
> >> > +                                       };
> >> > +
> >> > +                                       tcon_top_mixer1_out_tcon_tv1:
> >> > endpoint@3 { +                                               reg = <3>;
> >> > +                                       };
> >> > +                               };
> >> > +
> >> > +                               tcon_top_hdmi_in: port@4 {
> >> > +                                       #address-cells = <1>;
> >> > +                                       #size-cells = <0>;
> >> > +                                       reg = <4>;
> >> > +
> >> > +                                       tcon_top_hdmi_in_tcon_tv0:
> >> > endpoint@0 { +                                               reg = <0>;
> >> > +                                       };
> >> > +
> >> > +                                       tcon_top_hdmi_in_tcon_tv1:
> >> > endpoint@1 { +                                               reg = <1>;
> >> > +                                       };
> >> > +                               };
> >> > +
> >> > +                               tcon_top_hdmi_out: port@5 {
> >> > +                                       reg = <5>;
> >> > +
> >> > +                                       tcon_top_hdmi_out_hdmi:
> >> > endpoint {
> >> > +                                               remote-endpoint =
> >> > <&hdmi_in_tcon_top>; +                                       };
> >> > +                               };
> >> > +                       };
> >> > +               };
> >> > +
> >> > +               tcon_tv0: lcd-controller@1c73000 {
> >> > +                       compatible = "allwinner,sun8i-r40-tcon-tv",
> >> > +                                    "allwinner,sun8i-a83t-tcon-tv";
> >> > +                       reg = <0x01c73000 0x1000>;
> >> > +                       interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
> >> > +                       clocks = <&ccu CLK_BUS_TCON_TV0>, <&tcon_top
> >> > 0>;
> >> > +                       clock-names = "ahb", "tcon-ch1";
> >> > +                       resets = <&ccu RST_BUS_TCON_TV0>;
> >> > +                       reset-names = "lcd";
> >> > +
> >> > +                       ports {
> >> > +                               #address-cells = <1>;
> >> > +                               #size-cells = <0>;
> >> > +
> >> > +                               tcon_tv0_in: port@0 {
> >> > +                                       reg = <0>;
> >> > +                               };
> >> > +
> >> > +                               tcon_tv0_out: port@1 {
> >> > +                                       reg = <1>;
> >> > +                               };
> >> > +                       };
> >> > +               };
> >> > +
> >> > +               tcon_tv1: lcd-controller@1c74000 {
> >> > +                       compatible = "allwinner,sun8i-r40-tcon-tv",
> >> > +                                    "allwinner,sun8i-a83t-tcon-tv";
> >> > +                       reg = <0x01c74000 0x1000>;
> >> > +                       interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
> >> > +                       clocks = <&ccu CLK_BUS_TCON_TV1>, <&tcon_top
> >> > 1>;
> >> > +                       clock-names = "ahb", "tcon-ch1";
> >> > +                       resets = <&ccu RST_BUS_TCON_TV1>;
> >> > +                       reset-names = "lcd";
> >> > +
> >> > +                       ports {
> >> > +                               #address-cells = <1>;
> >> > +                               #size-cells = <0>;
> >> > +
> >> > +                               tcon_tv1_in: port@0 {
> >> > +                                       reg = <0>;
> >> > +                               };
> >> > +
> >> > +                               tcon_tv1_out: port@1 {
> >> > +                                       reg = <1>;
> >> 
> >> You are missing the remote-endpoints for all the TCON-TOP <-> TCON
> >> connections. Also, on the driver side, there's no code to handle
> >> dynamically mapping mixers to the TCONs that are being used. In the past
> >> we
> >> had simple 1:1 mappings. This is no longer the case, and it needs to be
> >> dealt with.
> > 
> > How would TCON TOP driver know how to set muxes? There are no appropriate
> > bingings for muxes, except for V4L2 subsystem, which doesn't really work
> > here.
> This will end up being a bunch of custom functions exported from the TCON
> TOP driver to the TCON driver. As for bindings, the stuff you already have
> is mostly enough. You do have to specify the endpoint ID vs component
> mapping, so you can find the correct one.
> 
> For example, you would specify that the IDs for TCON LCDs be 0 and 1, and
> TCON TVs be 2 and 3. Matching the actual register values is a nice
> convenience. These would be used by the driver as the TCON ID.

So something that's already done (minus full connections).

> 
> Also, we might want to consider them as two pairs of two TCONs (LCD + TV).
> The CRTC in DRM land is actually the mixer + TCON on our platform. This
> means we only have two CRTCs. So we could have CRTC 0 = mixer 0 + TCON LCD
> 0 + TCON TV 0. The "TCON_TVx_OUTSEL" and "DE_PORTx PERH Select" muxes would
> be set at run time in the mode set function, selecting either LCD or TV
> based on what encoder is attached.

That proposal would still limit some combinations. For example, that would put 
DSI always on mixer1, since it can be connected to only LCD TCON 1. It can 
also cause undesired combination in laptop solutions. Consider that PCB 
designer connected LCD1 pins to panel for some reason. Panel is definetly main 
screen and should definetly be connected to mixer0, but in that case, it would 
be to mixer1.

Additionaly, since HDMI would became floating between TV TCON 0 and 1, whoever 
would write board DT would need to know this and enable only TV TCON1 if LCD 
is desired to be connected to mixer0 (or vice versa).

If we really want universal solution with full connections, addtional property 
has to be defined and used for that.

> 
> This limitation is a software one, and should not bleed over into the
> hardware representation.
> 
> > Additionaly, how would HDMI know which TCON belongs to it to appropriately
> > set possible_crtcs?
> 
> HDMI is connected to the two TCON TVs through the TCON TOP mux. We handle
> TCON output muxing in the TCON driver, using the set_mux callback in the
> quirks. For R40, this callback would probably call into the TCON TOP driver
> asking it to set the mux to some value.
> 
> > Currently, my idea is that board DT creates wanted connections. Since
> > there is only one valid connection for each mux, driver knows eactly what
> > to write into mux register. HDMI driver can simply check which TCON
> > connection is valid in HDMI input mux and select it in possible_crtcs.
> 
> But that is not how the actual hardware looks like. The device tree should
> model the hardware, not a subset of it just because one thinks the
> implementation is difficult or won't be used at all.
> 
> Furthermore, I think you have it backwards. possible_crtcs is generated
> based on (in our case) the connections between TCON and HDMI based on the
> device tree graph. So if you have both hooked up, both will show up in
> possible_crtcs, but only one crtc will actually be selected to feed the
> HDMI encoder. If you really need to access the current crtc, the
> drm_encoder struct contains a pointer to it.
> 
> In DE 1.0 driver, we leave all the muxing to the TCON driver. See
> 
>    
> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/sun4i/sun4i_
> tcon.c#L537
> 
> So in a sense, the HDMI encoder should be and is hooked up to both TCONs,
> but only one is active at any given time.

So something like that I had in v1 series. I'll implement something similar. 
That would also mean we need R40 specific TV TCON compatible. I'll restore 
that.

Just a question on future situation when TVE driver will be implemented. 
Suppose that R40 board has TVE0 and HDMI as outputs. This would mean that TVE0 
has possible crtcs set as 0b01 and HDMI 0b11. Will be DRM framework smart 
enough that it will put HDMI on second crtc because TVE0 can be connected to 
only to first crtc?

> 
> > Please also note that mixer0 and mixer1 don't have same capabilities and
> > you generally want mixer0 to be connected to main output. This is in
> > contrast to DE1 SoCs, where both backends and both frontends have same
> > capability.
> Yes. But who's to say the two display outputs can't be reversed or swapped
> around? With fixed singular connections, you also rule out mirrored output.

I don't think there is standard way to swap around mixers at runtime, 
expecially if crtcs are represented as mixer + TCON pair.

I'm not sure what do you mean with mirrored output or at least why singular 
connections would prevent mirroring. HW mirroring needs DRM writeback support 
which is currently in RFC phase if I'm not mistaken. Once implemented in DRM 
framework and in sun4i-drm, it would be possible only to mirror mixer0 -> 
mixer1, because mixer1 doesn't support writeback (at least on existing SoCs).

Best regards,
Jernej

> 
> ChenYu
> 
> >> ChenYu
> >> 
> >> > +                               };
> >> > +                       };
> >> > +               };
> >> > +
> >> > 
> >> >                 gic: interrupt-controller@1c81000 {
> >> >                 
> >> >                         compatible = "arm,gic-400";
> >> >                         reg = <0x01c81000 0x1000>,
> >> > 
> >> > @@ -461,6 +685,51 @@
> >> > 
> >> >                         #interrupt-cells = <3>;
> >> >                         interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4)
> >> >                         |
> >> >                         IRQ_TYPE_LEVEL_HIGH)>;
> >> >                 
> >> >                 };
> >> > 
> >> > +
> >> > +               hdmi: hdmi@1ee0000 {
> >> > +                       compatible = "allwinner,sun8i-r40-dw-hdmi",
> >> > +                                    "allwinner,sun8i-a83t-dw-hdmi";
> >> > +                       reg = <0x01ee0000 0x10000>;
> >> > +                       reg-io-width = <1>;
> >> > +                       interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
> >> > +                       clocks = <&ccu CLK_BUS_HDMI0>, <&ccu
> >> > CLK_HDMI_SLOW>, +                                <&ccu CLK_HDMI>;
> >> > +                       clock-names = "iahb", "isfr", "tmds";
> >> > +                       resets = <&ccu RST_BUS_HDMI1>;
> >> > +                       reset-names = "ctrl";
> >> > +                       phys = <&hdmi_phy>;
> >> > +                       phy-names = "hdmi-phy";
> >> > +                       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@1ef0000 {
> >> > +                       compatible = "allwinner,sun8i-r40-hdmi-phy",
> >> > +                                    "allwinner,sun50i-a64-hdmi-phy";
> >> > +                       reg = <0x01ef0000 0x10000>;
> >> > +                       clocks = <&ccu CLK_BUS_HDMI1>, <&ccu
> >> > CLK_HDMI_SLOW>, +                                <&ccu 7>, <&ccu 16>;
> >> > +                       clock-names = "bus", "mod", "pll-0", "pll-1";
> >> > +                       resets = <&ccu RST_BUS_HDMI0>;
> >> > +                       reset-names = "phy";
> >> > +                       #phy-cells = <0>;
> >> > +               };
> >> > 
> >> >         };
> >> >         
> >> >         timer {
> >> > 
> >> > --
> >> > 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] 87+ messages in thread

* Re: [linux-sunxi] Re: [PATCH v3 23/24] ARM: dts: sun8i: r40: Add HDMI pipeline
  2018-07-01 10:41         ` Jernej Škrabec
@ 2018-07-01 13:52           ` Chen-Yu Tsai
  2018-07-01 15:13             ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-07-01 13:52 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Sun, Jul 1, 2018 at 6:41 PM, Jernej Škrabec <jernej.skrabec@siol.net> wrote:
> Dne četrtek, 28. junij 2018 ob 08:51:07 CEST je Chen-Yu Tsai napisal(a):
>> On Thu, Jun 28, 2018 at 1:15 PM, Jernej Škrabec <jernej.skrabec@siol.net>
> wrote:
>> > Dne četrtek, 28. junij 2018 ob 04:50:09 CEST je Chen-Yu Tsai napisal(a):
>> >> On Mon, Jun 25, 2018 at 8:03 PM, Jernej Skrabec <jernej.skrabec@siol.net>
>> >
>> > wrote:
>> >> > Add all entries needed for HDMI to function properly.
>> >> >
>> >> > Since R40 has highly configurable pipeline, both mixers and both TCON
>> >> > TVs are added. Board specific DT should then connect them together
>> >> > trough TCON TOP muxers to best fit the purpose of the board.
>> >> >
>> >> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>> >> > ---
>> >> >
>> >> >  arch/arm/boot/dts/sun8i-r40.dtsi | 269 +++++++++++++++++++++++++++++++
>> >> >  1 file changed, 269 insertions(+)
>> >> >
>> >> > diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi
>> >> > b/arch/arm/boot/dts/sun8i-r40.dtsi index 173dcc1652d2..a2a75fb04caf
>> >> > 100644
>> >> > --- a/arch/arm/boot/dts/sun8i-r40.dtsi
>> >> > +++ b/arch/arm/boot/dts/sun8i-r40.dtsi
>> >> > @@ -42,8 +42,11 @@
>> >> >
>> >> >   */
>> >> >
>> >> >  #include <dt-bindings/interrupt-controller/arm-gic.h>
>> >> >
>> >> > +#include <dt-bindings/clock/sun8i-de2.h>
>> >> >
>> >> >  #include <dt-bindings/clock/sun8i-r40-ccu.h>
>> >> >
>> >> > +#include <dt-bindings/clock/sun8i-tcon-top.h>
>> >
>> > Maxime, above line breaks compilation for build robot, sorry.
>> >
>> >> >  #include <dt-bindings/reset/sun8i-r40-ccu.h>
>> >> >
>> >> > +#include <dt-bindings/reset/sun8i-de2.h>
>> >> >
>> >> >  / {
>> >> >
>> >> >         #address-cells = <1>;
>> >> >
>> >> > @@ -99,12 +102,76 @@
>> >> >
>> >> >                 };
>> >> >
>> >> >         };
>> >> >
>> >> > +       de: display-engine {
>> >> > +               compatible = "allwinner,sun8i-r40-display-engine",
>> >> > +                            "allwinner,sun8i-h3-display-engine";
>> >>
>> >> Given that the display pipeline looks different, they should not be
>> >> compatible.
>> >
>> > Ok.
>> >
>> >> > +               allwinner,pipelines = <&mixer0>, <&mixer1>;
>> >> > +               status = "disabled";
>> >> > +       };
>> >> > +
>> >> >
>> >> >         soc {
>> >> >
>> >> >                 compatible = "simple-bus";
>> >> >                 #address-cells = <1>;
>> >> >                 #size-cells = <1>;
>> >> >                 ranges;
>> >> >
>> >> > +               display_clocks: clock@1000000 {
>> >> > +                       compatible = "allwinner,sun8i-r40-de2-clk",
>> >> > +                                    "allwinner,sun8i-h3-de2-clk";
>> >> > +                       reg = <0x01000000 0x100000>;
>> >> > +                       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@1100000 {
>> >> > +                       compatible = "allwinner,sun8i-r40-de2-mixer-0";
>> >> > +                       reg = <0x01100000 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: endpoint {
>> >> > +                                               remote-endpoint =
>> >> > <&tcon_top_mixer0_in_mixer0>; +
>> >> > };
>> >> > +                               };
>> >> > +                       };
>> >> > +               };
>> >> > +
>> >> > +               mixer1: mixer@1200000 {
>> >> > +                       compatible = "allwinner,sun8i-r40-de2-mixer-1";
>> >> > +                       reg = <0x01200000 0x100000>;
>> >> > +                       clocks = <&display_clocks CLK_BUS_MIXER1>,
>> >> > +                                <&display_clocks CLK_MIXER1>;
>> >> > +                       clock-names = "bus",
>> >> > +                                     "mod";
>> >> > +                       resets = <&display_clocks RST_WB>;
>> >> > +
>> >> > +                       ports {
>> >> > +                               #address-cells = <1>;
>> >> > +                               #size-cells = <0>;
>> >> > +
>> >> > +                               mixer1_out: port@1 {
>> >> > +                                       reg = <1>;
>> >> > +                                       mixer1_out_tcon_top: endpoint {
>> >> > +                                               remote-endpoint =
>> >> > <&tcon_top_mixer1_in_mixer1>; +
>> >> > };
>> >> > +                               };
>> >> > +                       };
>> >> > +               };
>> >> > +
>> >> >
>> >> >                 nmi_intc: interrupt-controller@1c00030 {
>> >> >
>> >> >                         compatible = "allwinner,sun7i-a20-sc-nmi";
>> >> >                         interrupt-controller;
>> >> >
>> >> > @@ -451,6 +518,163 @@
>> >> >
>> >> >                         #size-cells = <0>;
>> >> >
>> >> >                 };
>> >> >
>> >> > +               tcon_top: tcon-top@1c70000 {
>> >> > +                       compatible = "allwinner,sun8i-r40-tcon-top";
>> >> > +                       reg = <0x01c70000 0x1000>;
>> >> > +                       clocks = <&ccu CLK_BUS_TCON_TOP>,
>> >> > +                                <&ccu CLK_TCON_TV0>,
>> >> > +                                <&ccu CLK_TVE0>,
>> >> > +                                <&ccu CLK_TCON_TV1>,
>> >> > +                                <&ccu CLK_TVE1>,
>> >> > +                                <&ccu CLK_DSI_DPHY>;
>> >> > +                       clock-names = "bus",
>> >> > +                                     "tcon-tv0",
>> >> > +                                     "tve0",
>> >> > +                                     "tcon-tv1",
>> >> > +                                     "tve1",
>> >> > +                                     "dsi";
>> >> > +                       clock-output-names = "tcon-top-tv0",
>> >> > +                                            "tcon-top-tv1",
>> >> > +                                            "tcon-top-dsi";
>> >> > +                       resets = <&ccu RST_BUS_TCON_TOP>;
>> >> > +                       #clock-cells = <1>;
>> >> > +
>> >> > +                       ports {
>> >> > +                               #address-cells = <1>;
>> >> > +                               #size-cells = <0>;
>> >> > +
>> >> > +                               tcon_top_mixer0_in: port@0 {
>> >> > +                                       reg = <0>;
>> >> > +
>> >> > +                                       tcon_top_mixer0_in_mixer0:
>> >> > endpoint { +
>> >> > remote-endpoint = <&mixer0_out_tcon_top>; +
>> >> >
>> >> >         };
>> >> >
>> >> > +                               };
>> >> > +
>> >> > +                               tcon_top_mixer0_out: port@1 {
>> >> > +                                       #address-cells = <1>;
>> >> > +                                       #size-cells = <0>;
>> >> > +                                       reg = <1>;
>> >> > +
>> >> > +                                       tcon_top_mixer0_out_tcon_lcd0:
>> >> > endpoint@0 { +                                               reg = <0>;
>> >> > +                                       };
>> >> > +
>> >> > +                                       tcon_top_mixer0_out_tcon_lcd1:
>> >> > endpoint@1 { +                                               reg = <1>;
>> >> > +                                       };
>> >> > +
>> >> > +                                       tcon_top_mixer0_out_tcon_tv0:
>> >> > endpoint@2 { +                                               reg = <2>;
>> >> > +                                       };
>> >> > +
>> >> > +                                       tcon_top_mixer0_out_tcon_tv1:
>> >> > endpoint@3 { +                                               reg = <3>;
>> >> > +                                       };
>> >> > +                               };
>> >> > +
>> >> > +                               tcon_top_mixer1_in: port@2 {
>> >> > +                                       reg = <2>;
>> >> > +
>> >> > +                                       tcon_top_mixer1_in_mixer1:
>> >> > endpoint { +
>> >> > remote-endpoint = <&mixer1_out_tcon_top>; +
>> >> >
>> >> >         };
>> >> >
>> >> > +                               };
>> >> > +
>> >> > +                               tcon_top_mixer1_out: port@3 {
>> >> > +                                       #address-cells = <1>;
>> >> > +                                       #size-cells = <0>;
>> >> > +                                       reg = <3>;
>> >> > +
>> >> > +                                       tcon_top_mixer1_out_tcon_lcd0:
>> >> > endpoint@0 { +                                               reg = <0>;
>> >> > +                                       };
>> >> > +
>> >> > +                                       tcon_top_mixer1_out_tcon_lcd1:
>> >> > endpoint@1 { +                                               reg = <1>;
>> >> > +                                       };
>> >> > +
>> >> > +                                       tcon_top_mixer1_out_tcon_tv0:
>> >> > endpoint@2 { +                                               reg = <2>;
>> >> > +                                       };
>> >> > +
>> >> > +                                       tcon_top_mixer1_out_tcon_tv1:
>> >> > endpoint@3 { +                                               reg = <3>;
>> >> > +                                       };
>> >> > +                               };
>> >> > +
>> >> > +                               tcon_top_hdmi_in: port@4 {
>> >> > +                                       #address-cells = <1>;
>> >> > +                                       #size-cells = <0>;
>> >> > +                                       reg = <4>;
>> >> > +
>> >> > +                                       tcon_top_hdmi_in_tcon_tv0:
>> >> > endpoint@0 { +                                               reg = <0>;
>> >> > +                                       };
>> >> > +
>> >> > +                                       tcon_top_hdmi_in_tcon_tv1:
>> >> > endpoint@1 { +                                               reg = <1>;
>> >> > +                                       };
>> >> > +                               };
>> >> > +
>> >> > +                               tcon_top_hdmi_out: port@5 {
>> >> > +                                       reg = <5>;
>> >> > +
>> >> > +                                       tcon_top_hdmi_out_hdmi:
>> >> > endpoint {
>> >> > +                                               remote-endpoint =
>> >> > <&hdmi_in_tcon_top>; +                                       };
>> >> > +                               };
>> >> > +                       };
>> >> > +               };
>> >> > +
>> >> > +               tcon_tv0: lcd-controller@1c73000 {
>> >> > +                       compatible = "allwinner,sun8i-r40-tcon-tv",
>> >> > +                                    "allwinner,sun8i-a83t-tcon-tv";
>> >> > +                       reg = <0x01c73000 0x1000>;
>> >> > +                       interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
>> >> > +                       clocks = <&ccu CLK_BUS_TCON_TV0>, <&tcon_top
>> >> > 0>;
>> >> > +                       clock-names = "ahb", "tcon-ch1";
>> >> > +                       resets = <&ccu RST_BUS_TCON_TV0>;
>> >> > +                       reset-names = "lcd";
>> >> > +
>> >> > +                       ports {
>> >> > +                               #address-cells = <1>;
>> >> > +                               #size-cells = <0>;
>> >> > +
>> >> > +                               tcon_tv0_in: port@0 {
>> >> > +                                       reg = <0>;
>> >> > +                               };
>> >> > +
>> >> > +                               tcon_tv0_out: port@1 {
>> >> > +                                       reg = <1>;
>> >> > +                               };
>> >> > +                       };
>> >> > +               };
>> >> > +
>> >> > +               tcon_tv1: lcd-controller@1c74000 {
>> >> > +                       compatible = "allwinner,sun8i-r40-tcon-tv",
>> >> > +                                    "allwinner,sun8i-a83t-tcon-tv";
>> >> > +                       reg = <0x01c74000 0x1000>;
>> >> > +                       interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
>> >> > +                       clocks = <&ccu CLK_BUS_TCON_TV1>, <&tcon_top
>> >> > 1>;
>> >> > +                       clock-names = "ahb", "tcon-ch1";
>> >> > +                       resets = <&ccu RST_BUS_TCON_TV1>;
>> >> > +                       reset-names = "lcd";
>> >> > +
>> >> > +                       ports {
>> >> > +                               #address-cells = <1>;
>> >> > +                               #size-cells = <0>;
>> >> > +
>> >> > +                               tcon_tv1_in: port@0 {
>> >> > +                                       reg = <0>;
>> >> > +                               };
>> >> > +
>> >> > +                               tcon_tv1_out: port@1 {
>> >> > +                                       reg = <1>;
>> >>
>> >> You are missing the remote-endpoints for all the TCON-TOP <-> TCON
>> >> connections. Also, on the driver side, there's no code to handle
>> >> dynamically mapping mixers to the TCONs that are being used. In the past
>> >> we
>> >> had simple 1:1 mappings. This is no longer the case, and it needs to be
>> >> dealt with.
>> >
>> > How would TCON TOP driver know how to set muxes? There are no appropriate
>> > bingings for muxes, except for V4L2 subsystem, which doesn't really work
>> > here.
>> This will end up being a bunch of custom functions exported from the TCON
>> TOP driver to the TCON driver. As for bindings, the stuff you already have
>> is mostly enough. You do have to specify the endpoint ID vs component
>> mapping, so you can find the correct one.
>>
>> For example, you would specify that the IDs for TCON LCDs be 0 and 1, and
>> TCON TVs be 2 and 3. Matching the actual register values is a nice
>> convenience. These would be used by the driver as the TCON ID.
>
> So something that's already done (minus full connections).
>
>>
>> Also, we might want to consider them as two pairs of two TCONs (LCD + TV).
>> The CRTC in DRM land is actually the mixer + TCON on our platform. This
>> means we only have two CRTCs. So we could have CRTC 0 = mixer 0 + TCON LCD
>> 0 + TCON TV 0. The "TCON_TVx_OUTSEL" and "DE_PORTx PERH Select" muxes would
>> be set at run time in the mode set function, selecting either LCD or TV
>> based on what encoder is attached.
>
> That proposal would still limit some combinations. For example, that would put
> DSI always on mixer1, since it can be connected to only LCD TCON 1. It can
> also cause undesired combination in laptop solutions. Consider that PCB
> designer connected LCD1 pins to panel for some reason. Panel is definetly main
> screen and should definetly be connected to mixer0, but in that case, it would
> be to mixer1.

There's no reason we can't have dynamically assigned mixer+tcon pairs, but
that would mean implementing additional scheduling code that we don't have
yet. The current sunxi-drm and CRTC code assume static mappings.

We could do this as a second step if you're up to it.

> Additionaly, since HDMI would became floating between TV TCON 0 and 1, whoever
> would write board DT would need to know this and enable only TV TCON1 if LCD
> is desired to be connected to mixer0 (or vice versa).

There's no reason not to have all TCONs enabled by default. We would consider
the display-engine node controlling whether everything actually gets used.

> If we really want universal solution with full connections, addtional property
> has to be defined and used for that.
>
>>
>> This limitation is a software one, and should not bleed over into the
>> hardware representation.
>>
>> > Additionaly, how would HDMI know which TCON belongs to it to appropriately
>> > set possible_crtcs?
>>
>> HDMI is connected to the two TCON TVs through the TCON TOP mux. We handle
>> TCON output muxing in the TCON driver, using the set_mux callback in the
>> quirks. For R40, this callback would probably call into the TCON TOP driver
>> asking it to set the mux to some value.
>>
>> > Currently, my idea is that board DT creates wanted connections. Since
>> > there is only one valid connection for each mux, driver knows eactly what
>> > to write into mux register. HDMI driver can simply check which TCON
>> > connection is valid in HDMI input mux and select it in possible_crtcs.
>>
>> But that is not how the actual hardware looks like. The device tree should
>> model the hardware, not a subset of it just because one thinks the
>> implementation is difficult or won't be used at all.
>>
>> Furthermore, I think you have it backwards. possible_crtcs is generated
>> based on (in our case) the connections between TCON and HDMI based on the
>> device tree graph. So if you have both hooked up, both will show up in
>> possible_crtcs, but only one crtc will actually be selected to feed the
>> HDMI encoder. If you really need to access the current crtc, the
>> drm_encoder struct contains a pointer to it.
>>
>> In DE 1.0 driver, we leave all the muxing to the TCON driver. See
>>
>>
>> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/sun4i/sun4i_
>> tcon.c#L537
>>
>> So in a sense, the HDMI encoder should be and is hooked up to both TCONs,
>> but only one is active at any given time.
>
> So something like that I had in v1 series. I'll implement something similar.
> That would also mean we need R40 specific TV TCON compatible. I'll restore
> that.
>
> Just a question on future situation when TVE driver will be implemented.
> Suppose that R40 board has TVE0 and HDMI as outputs. This would mean that TVE0
> has possible crtcs set as 0b01 and HDMI 0b11. Will be DRM framework smart
> enough that it will put HDMI on second crtc because TVE0 can be connected to
> only to first crtc?

Yes. If the possible_clones setting for the encoder is not set, the DRM
framework will not do mirroring, and will keep each active encoder on a
separate crtc.

>
>>
>> > Please also note that mixer0 and mixer1 don't have same capabilities and
>> > you generally want mixer0 to be connected to main output. This is in
>> > contrast to DE1 SoCs, where both backends and both frontends have same
>> > capability.
>> Yes. But who's to say the two display outputs can't be reversed or swapped
>> around? With fixed singular connections, you also rule out mirrored output.
>
> I don't think there is standard way to swap around mixers at runtime,
> expecially if crtcs are represented as mixer + TCON pair.

As I mentioned above, we will have to do this on our own.

> I'm not sure what do you mean with mirrored output or at least why singular
> connections would prevent mirroring. HW mirroring needs DRM writeback support
> which is currently in RFC phase if I'm not mistaken. Once implemented in DRM
> framework and in sun4i-drm, it would be possible only to mirror mixer0 ->
> mixer1, because mixer1 doesn't support writeback (at least on existing SoCs).

What I meant was it might be possible to drive two TCONs with one mixer, or
two encoders with one TCON. I guess the latter is not possible since each
TCON only has one channel. Not sure about the former.

Regards
ChenYu

> Best regards,
> Jernej
>
>>
>> ChenYu
>>
>> >> ChenYu
>> >>
>> >> > +                               };
>> >> > +                       };
>> >> > +               };
>> >> > +
>> >> >
>> >> >                 gic: interrupt-controller@1c81000 {
>> >> >
>> >> >                         compatible = "arm,gic-400";
>> >> >                         reg = <0x01c81000 0x1000>,
>> >> >
>> >> > @@ -461,6 +685,51 @@
>> >> >
>> >> >                         #interrupt-cells = <3>;
>> >> >                         interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4)
>> >> >                         |
>> >> >                         IRQ_TYPE_LEVEL_HIGH)>;
>> >> >
>> >> >                 };
>> >> >
>> >> > +
>> >> > +               hdmi: hdmi@1ee0000 {
>> >> > +                       compatible = "allwinner,sun8i-r40-dw-hdmi",
>> >> > +                                    "allwinner,sun8i-a83t-dw-hdmi";
>> >> > +                       reg = <0x01ee0000 0x10000>;
>> >> > +                       reg-io-width = <1>;
>> >> > +                       interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
>> >> > +                       clocks = <&ccu CLK_BUS_HDMI0>, <&ccu
>> >> > CLK_HDMI_SLOW>, +                                <&ccu CLK_HDMI>;
>> >> > +                       clock-names = "iahb", "isfr", "tmds";
>> >> > +                       resets = <&ccu RST_BUS_HDMI1>;
>> >> > +                       reset-names = "ctrl";
>> >> > +                       phys = <&hdmi_phy>;
>> >> > +                       phy-names = "hdmi-phy";
>> >> > +                       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@1ef0000 {
>> >> > +                       compatible = "allwinner,sun8i-r40-hdmi-phy",
>> >> > +                                    "allwinner,sun50i-a64-hdmi-phy";
>> >> > +                       reg = <0x01ef0000 0x10000>;
>> >> > +                       clocks = <&ccu CLK_BUS_HDMI1>, <&ccu
>> >> > CLK_HDMI_SLOW>, +                                <&ccu 7>, <&ccu 16>;
>> >> > +                       clock-names = "bus", "mod", "pll-0", "pll-1";
>> >> > +                       resets = <&ccu RST_BUS_HDMI0>;
>> >> > +                       reset-names = "phy";
>> >> > +                       #phy-cells = <0>;
>> >> > +               };
>> >> >
>> >> >         };
>> >> >
>> >> >         timer {
>> >> >
>> >> > --
>> >> > 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] 87+ messages in thread

* Re: [linux-sunxi] Re: [PATCH v3 09/24] drm/sun4i: Don't skip TCONs if they don't have channel 0
  2018-07-01  8:27         ` Jernej Škrabec
@ 2018-07-01 15:11           ` Chen-Yu Tsai
  2018-07-05  7:03             ` Maxime Ripard
  0 siblings, 1 reply; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-07-01 15:11 UTC (permalink / raw)
  To: Jernej Škrabec, Maxime Ripard
  Cc: Rob Herring, David Airlie, Gustavo Padovan, Maarten Lankhorst,
	Sean Paul, Mark Rutland, dri-devel, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, linux-sunxi

On Sun, Jul 1, 2018 at 4:27 PM, Jernej Škrabec <jernej.skrabec@siol.net> wrote:
> Dne četrtek, 28. junij 2018 ob 08:24:34 CEST je Chen-Yu Tsai napisal(a):
>> On Thu, Jun 28, 2018 at 12:45 PM, Jernej Škrabec
>>
>> <jernej.skrabec@siol.net> wrote:
>> > Dne četrtek, 28. junij 2018 ob 03:51:31 CEST je Chen-Yu Tsai napisal(a):
>> >> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net>
>> >
>> > wrote:
>> >> > TV TCONs (channel 1 only) are always connected to TV or HDMI encoder.
>> >> > Because of that, all output endpoints on such TCON node will point to a
>> >> > encoder which is part of component framework.
>> >> >
>> >> > Correct current graph traversing algorithm in such way that it doesn't
>> >> > skip output enpoints with id 0 on TV TCONs.
>> >>
>> >> No. Our bindings say that endpoint 0 _is_ channel 0. For TCONs that don't
>> >> have channel 0, it must be skipped.
>> >
>> > I'm not sure where this is stated. I read TCON binding again. Can you
>> > please point me to it?
>>
>> https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bind
>> ings/display/sunxi/sun4i-drm.txt#L169
>>
>> Our TCON driver still expects RGB or LVDS panel / bridges on endpoint 0.
>
> Yes, but that can only happen on TCON which has channel 0. TV TCONs (those
> with channel 1 only) can't have panels or bridges connected to them, because
> they are internally always connected to either HDMI or TV encoder or both.
> Actually, R40 is the only SoC, where same TV TCON can be connected to TV
> encoder or HDMI. Others have specialized TV TCONs, which are connect to only
> one encoder.
>
> IMO TV TCONs are really just stripped down LCD TCONs to support one (or max
> two) specific encoder.

I agree. We've seen these first in the H3, and the reverse, TCONs only with
LCD, on the A23/A33.

>> So I guess this was sort of implied historically. It's no longer true.
>> This is something we should probably fix.
>
> Fixed in what way? You mean update bindings to mention that TCON output
> endpoint 0 is reserved for panels or bridges?

Either that, or have the drm driver look at other endpoints. I guess we
should ask Maxime if this is already done or not, since the DSI driver
isn't endpoint 0 in the A33 dtsi.

>>
>> In practice our drivers don't look at it (yet), but rely on the downstream
>> encoder type to determine which channel to use.
>>
>> But please add the "allwinner,tcon-channel" property as specified in
>> the binding.
>
> It's my understanding of TCON binding documentation that property
> "allwinner,tcon-channel" is needed only if TCON supports both channels. TV
> TCON clearly supports only channel 1. In that case, there is no doubt to which
> channel output endpoint belongs.
>
> If that's not true, dt bindings documentation should be reworded to contain
> word "needed" or something similar. Currently, no DT for newer SoC contains
> that property (for example, A83T, H3, H5 or even A33). On A33 this is even
> more interesting, since tcon0 has only channel 0 and has DSI output endpoint
> with number 1. According to TCON binding docs, if "allwinner,tcon-channel" is
> not preset, endpoint number represent channel. So, that would mean DSI needs
> channel 1 on tcon which supports clearly only channel 0. So either there TCON
> bindings documentation needs updates or DT for A33 has to be updated.

Maxime? You did the A33 DSI stuff.

> BTW, "allwinner,tcon-channel" property is not used at all in the code.

Yes I'm aware. We just base the channel selection on the encoder type instead.
TV-like ones use channel 1, LCD ones use channel 0.

>>
>> > So on TV TCONs on R40 (without channel 0) TVE would be endpoint 1 and HDMI
>> > endpoint 2 (or the other way around)?
>>
>> Which one goes first doesn't quite matter. IIRC there's also a mux for TVE?
>
> AFAIK, TV TCON is by default connected to TV encoder unless HDMI mux in TCON
> TOP points to it. I think it's best put TVE with lower number since it's
> default and HDMI with higher number.

Ok. As long as its specified in the binding, as a contract between the dts
and the graph parsing code.

Regards
ChenYu

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

* Re: [linux-sunxi] Re: [PATCH v3 23/24] ARM: dts: sun8i: r40: Add HDMI pipeline
  2018-07-01 13:52           ` Chen-Yu Tsai
@ 2018-07-01 15:13             ` Jernej Škrabec
  2018-07-01 15:35               ` Chen-Yu Tsai
  0 siblings, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-07-01 15:13 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne nedelja, 01. julij 2018 ob 15:52:55 CEST je Chen-Yu Tsai napisal(a):
> On Sun, Jul 1, 2018 at 6:41 PM, Jernej Škrabec <jernej.skrabec@siol.net> 
wrote:
> > Dne četrtek, 28. junij 2018 ob 08:51:07 CEST je Chen-Yu Tsai napisal(a):
> >> On Thu, Jun 28, 2018 at 1:15 PM, Jernej Škrabec <jernej.skrabec@siol.net>
> > 
> > wrote:
> >> > Dne četrtek, 28. junij 2018 ob 04:50:09 CEST je Chen-Yu Tsai 
napisal(a):
> >> >> On Mon, Jun 25, 2018 at 8:03 PM, Jernej Skrabec
> >> >> <jernej.skrabec@siol.net>
> >> > 
> >> > wrote:
> >> >> > Add all entries needed for HDMI to function properly.
> >> >> > 
> >> >> > Since R40 has highly configurable pipeline, both mixers and both
> >> >> > TCON
> >> >> > TVs are added. Board specific DT should then connect them together
> >> >> > trough TCON TOP muxers to best fit the purpose of the board.
> >> >> > 
> >> >> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> >> >> > ---
> >> >> > 
> >> >> >  arch/arm/boot/dts/sun8i-r40.dtsi | 269
> >> >> >  +++++++++++++++++++++++++++++++
> >> >> >  1 file changed, 269 insertions(+)
> >> >> > 
> >> >> > diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi
> >> >> > b/arch/arm/boot/dts/sun8i-r40.dtsi index 173dcc1652d2..a2a75fb04caf
> >> >> > 100644
> >> >> > --- a/arch/arm/boot/dts/sun8i-r40.dtsi
> >> >> > +++ b/arch/arm/boot/dts/sun8i-r40.dtsi
> >> >> > @@ -42,8 +42,11 @@
> >> >> > 
> >> >> >   */
> >> >> >  
> >> >> >  #include <dt-bindings/interrupt-controller/arm-gic.h>
> >> >> > 
> >> >> > +#include <dt-bindings/clock/sun8i-de2.h>
> >> >> > 
> >> >> >  #include <dt-bindings/clock/sun8i-r40-ccu.h>
> >> >> > 
> >> >> > +#include <dt-bindings/clock/sun8i-tcon-top.h>
> >> > 
> >> > Maxime, above line breaks compilation for build robot, sorry.
> >> > 
> >> >> >  #include <dt-bindings/reset/sun8i-r40-ccu.h>
> >> >> > 
> >> >> > +#include <dt-bindings/reset/sun8i-de2.h>
> >> >> > 
> >> >> >  / {
> >> >> >  
> >> >> >         #address-cells = <1>;
> >> >> > 
> >> >> > @@ -99,12 +102,76 @@
> >> >> > 
> >> >> >                 };
> >> >> >         
> >> >> >         };
> >> >> > 
> >> >> > +       de: display-engine {
> >> >> > +               compatible = "allwinner,sun8i-r40-display-engine",
> >> >> > +                            "allwinner,sun8i-h3-display-engine";
> >> >> 
> >> >> Given that the display pipeline looks different, they should not be
> >> >> compatible.
> >> > 
> >> > Ok.
> >> > 
> >> >> > +               allwinner,pipelines = <&mixer0>, <&mixer1>;
> >> >> > +               status = "disabled";
> >> >> > +       };
> >> >> > +
> >> >> > 
> >> >> >         soc {
> >> >> >         
> >> >> >                 compatible = "simple-bus";
> >> >> >                 #address-cells = <1>;
> >> >> >                 #size-cells = <1>;
> >> >> >                 ranges;
> >> >> > 
> >> >> > +               display_clocks: clock@1000000 {
> >> >> > +                       compatible = "allwinner,sun8i-r40-de2-clk",
> >> >> > +                                    "allwinner,sun8i-h3-de2-clk";
> >> >> > +                       reg = <0x01000000 0x100000>;
> >> >> > +                       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@1100000 {
> >> >> > +                       compatible =
> >> >> > "allwinner,sun8i-r40-de2-mixer-0";
> >> >> > +                       reg = <0x01100000 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:
> >> >> > endpoint {
> >> >> > +                                               remote-endpoint =
> >> >> > <&tcon_top_mixer0_in_mixer0>; +
> >> >> > };
> >> >> > +                               };
> >> >> > +                       };
> >> >> > +               };
> >> >> > +
> >> >> > +               mixer1: mixer@1200000 {
> >> >> > +                       compatible =
> >> >> > "allwinner,sun8i-r40-de2-mixer-1";
> >> >> > +                       reg = <0x01200000 0x100000>;
> >> >> > +                       clocks = <&display_clocks CLK_BUS_MIXER1>,
> >> >> > +                                <&display_clocks CLK_MIXER1>;
> >> >> > +                       clock-names = "bus",
> >> >> > +                                     "mod";
> >> >> > +                       resets = <&display_clocks RST_WB>;
> >> >> > +
> >> >> > +                       ports {
> >> >> > +                               #address-cells = <1>;
> >> >> > +                               #size-cells = <0>;
> >> >> > +
> >> >> > +                               mixer1_out: port@1 {
> >> >> > +                                       reg = <1>;
> >> >> > +                                       mixer1_out_tcon_top:
> >> >> > endpoint {
> >> >> > +                                               remote-endpoint =
> >> >> > <&tcon_top_mixer1_in_mixer1>; +
> >> >> > };
> >> >> > +                               };
> >> >> > +                       };
> >> >> > +               };
> >> >> > +
> >> >> > 
> >> >> >                 nmi_intc: interrupt-controller@1c00030 {
> >> >> >                 
> >> >> >                         compatible = "allwinner,sun7i-a20-sc-nmi";
> >> >> >                         interrupt-controller;
> >> >> > 
> >> >> > @@ -451,6 +518,163 @@
> >> >> > 
> >> >> >                         #size-cells = <0>;
> >> >> >                 
> >> >> >                 };
> >> >> > 
> >> >> > +               tcon_top: tcon-top@1c70000 {
> >> >> > +                       compatible = "allwinner,sun8i-r40-tcon-top";
> >> >> > +                       reg = <0x01c70000 0x1000>;
> >> >> > +                       clocks = <&ccu CLK_BUS_TCON_TOP>,
> >> >> > +                                <&ccu CLK_TCON_TV0>,
> >> >> > +                                <&ccu CLK_TVE0>,
> >> >> > +                                <&ccu CLK_TCON_TV1>,
> >> >> > +                                <&ccu CLK_TVE1>,
> >> >> > +                                <&ccu CLK_DSI_DPHY>;
> >> >> > +                       clock-names = "bus",
> >> >> > +                                     "tcon-tv0",
> >> >> > +                                     "tve0",
> >> >> > +                                     "tcon-tv1",
> >> >> > +                                     "tve1",
> >> >> > +                                     "dsi";
> >> >> > +                       clock-output-names = "tcon-top-tv0",
> >> >> > +                                            "tcon-top-tv1",
> >> >> > +                                            "tcon-top-dsi";
> >> >> > +                       resets = <&ccu RST_BUS_TCON_TOP>;
> >> >> > +                       #clock-cells = <1>;
> >> >> > +
> >> >> > +                       ports {
> >> >> > +                               #address-cells = <1>;
> >> >> > +                               #size-cells = <0>;
> >> >> > +
> >> >> > +                               tcon_top_mixer0_in: port@0 {
> >> >> > +                                       reg = <0>;
> >> >> > +
> >> >> > +                                       tcon_top_mixer0_in_mixer0:
> >> >> > endpoint { +
> >> >> > remote-endpoint = <&mixer0_out_tcon_top>; +
> >> >> > 
> >> >> >         };
> >> >> > 
> >> >> > +                               };
> >> >> > +
> >> >> > +                               tcon_top_mixer0_out: port@1 {
> >> >> > +                                       #address-cells = <1>;
> >> >> > +                                       #size-cells = <0>;
> >> >> > +                                       reg = <1>;
> >> >> > +
> >> >> > +                                      
> >> >> > tcon_top_mixer0_out_tcon_lcd0:
> >> >> > endpoint@0 { +                                               reg =
> >> >> > <0>;
> >> >> > +                                       };
> >> >> > +
> >> >> > +                                      
> >> >> > tcon_top_mixer0_out_tcon_lcd1:
> >> >> > endpoint@1 { +                                               reg =
> >> >> > <1>;
> >> >> > +                                       };
> >> >> > +
> >> >> > +                                      
> >> >> > tcon_top_mixer0_out_tcon_tv0:
> >> >> > endpoint@2 { +                                               reg =
> >> >> > <2>;
> >> >> > +                                       };
> >> >> > +
> >> >> > +                                      
> >> >> > tcon_top_mixer0_out_tcon_tv1:
> >> >> > endpoint@3 { +                                               reg =
> >> >> > <3>;
> >> >> > +                                       };
> >> >> > +                               };
> >> >> > +
> >> >> > +                               tcon_top_mixer1_in: port@2 {
> >> >> > +                                       reg = <2>;
> >> >> > +
> >> >> > +                                       tcon_top_mixer1_in_mixer1:
> >> >> > endpoint { +
> >> >> > remote-endpoint = <&mixer1_out_tcon_top>; +
> >> >> > 
> >> >> >         };
> >> >> > 
> >> >> > +                               };
> >> >> > +
> >> >> > +                               tcon_top_mixer1_out: port@3 {
> >> >> > +                                       #address-cells = <1>;
> >> >> > +                                       #size-cells = <0>;
> >> >> > +                                       reg = <3>;
> >> >> > +
> >> >> > +                                      
> >> >> > tcon_top_mixer1_out_tcon_lcd0:
> >> >> > endpoint@0 { +                                               reg =
> >> >> > <0>;
> >> >> > +                                       };
> >> >> > +
> >> >> > +                                      
> >> >> > tcon_top_mixer1_out_tcon_lcd1:
> >> >> > endpoint@1 { +                                               reg =
> >> >> > <1>;
> >> >> > +                                       };
> >> >> > +
> >> >> > +                                      
> >> >> > tcon_top_mixer1_out_tcon_tv0:
> >> >> > endpoint@2 { +                                               reg =
> >> >> > <2>;
> >> >> > +                                       };
> >> >> > +
> >> >> > +                                      
> >> >> > tcon_top_mixer1_out_tcon_tv1:
> >> >> > endpoint@3 { +                                               reg =
> >> >> > <3>;
> >> >> > +                                       };
> >> >> > +                               };
> >> >> > +
> >> >> > +                               tcon_top_hdmi_in: port@4 {
> >> >> > +                                       #address-cells = <1>;
> >> >> > +                                       #size-cells = <0>;
> >> >> > +                                       reg = <4>;
> >> >> > +
> >> >> > +                                       tcon_top_hdmi_in_tcon_tv0:
> >> >> > endpoint@0 { +                                               reg =
> >> >> > <0>;
> >> >> > +                                       };
> >> >> > +
> >> >> > +                                       tcon_top_hdmi_in_tcon_tv1:
> >> >> > endpoint@1 { +                                               reg =
> >> >> > <1>;
> >> >> > +                                       };
> >> >> > +                               };
> >> >> > +
> >> >> > +                               tcon_top_hdmi_out: port@5 {
> >> >> > +                                       reg = <5>;
> >> >> > +
> >> >> > +                                       tcon_top_hdmi_out_hdmi:
> >> >> > endpoint {
> >> >> > +                                               remote-endpoint =
> >> >> > <&hdmi_in_tcon_top>; +                                       };
> >> >> > +                               };
> >> >> > +                       };
> >> >> > +               };
> >> >> > +
> >> >> > +               tcon_tv0: lcd-controller@1c73000 {
> >> >> > +                       compatible = "allwinner,sun8i-r40-tcon-tv",
> >> >> > +                                    "allwinner,sun8i-a83t-tcon-tv";
> >> >> > +                       reg = <0x01c73000 0x1000>;
> >> >> > +                       interrupts = <GIC_SPI 51
> >> >> > IRQ_TYPE_LEVEL_HIGH>;
> >> >> > +                       clocks = <&ccu CLK_BUS_TCON_TV0>, <&tcon_top
> >> >> > 0>;
> >> >> > +                       clock-names = "ahb", "tcon-ch1";
> >> >> > +                       resets = <&ccu RST_BUS_TCON_TV0>;
> >> >> > +                       reset-names = "lcd";
> >> >> > +
> >> >> > +                       ports {
> >> >> > +                               #address-cells = <1>;
> >> >> > +                               #size-cells = <0>;
> >> >> > +
> >> >> > +                               tcon_tv0_in: port@0 {
> >> >> > +                                       reg = <0>;
> >> >> > +                               };
> >> >> > +
> >> >> > +                               tcon_tv0_out: port@1 {
> >> >> > +                                       reg = <1>;
> >> >> > +                               };
> >> >> > +                       };
> >> >> > +               };
> >> >> > +
> >> >> > +               tcon_tv1: lcd-controller@1c74000 {
> >> >> > +                       compatible = "allwinner,sun8i-r40-tcon-tv",
> >> >> > +                                    "allwinner,sun8i-a83t-tcon-tv";
> >> >> > +                       reg = <0x01c74000 0x1000>;
> >> >> > +                       interrupts = <GIC_SPI 52
> >> >> > IRQ_TYPE_LEVEL_HIGH>;
> >> >> > +                       clocks = <&ccu CLK_BUS_TCON_TV1>, <&tcon_top
> >> >> > 1>;
> >> >> > +                       clock-names = "ahb", "tcon-ch1";
> >> >> > +                       resets = <&ccu RST_BUS_TCON_TV1>;
> >> >> > +                       reset-names = "lcd";
> >> >> > +
> >> >> > +                       ports {
> >> >> > +                               #address-cells = <1>;
> >> >> > +                               #size-cells = <0>;
> >> >> > +
> >> >> > +                               tcon_tv1_in: port@0 {
> >> >> > +                                       reg = <0>;
> >> >> > +                               };
> >> >> > +
> >> >> > +                               tcon_tv1_out: port@1 {
> >> >> > +                                       reg = <1>;
> >> >> 
> >> >> You are missing the remote-endpoints for all the TCON-TOP <-> TCON
> >> >> connections. Also, on the driver side, there's no code to handle
> >> >> dynamically mapping mixers to the TCONs that are being used. In the
> >> >> past
> >> >> we
> >> >> had simple 1:1 mappings. This is no longer the case, and it needs to
> >> >> be
> >> >> dealt with.
> >> > 
> >> > How would TCON TOP driver know how to set muxes? There are no
> >> > appropriate
> >> > bingings for muxes, except for V4L2 subsystem, which doesn't really
> >> > work
> >> > here.
> >> 
> >> This will end up being a bunch of custom functions exported from the TCON
> >> TOP driver to the TCON driver. As for bindings, the stuff you already
> >> have
> >> is mostly enough. You do have to specify the endpoint ID vs component
> >> mapping, so you can find the correct one.
> >> 
> >> For example, you would specify that the IDs for TCON LCDs be 0 and 1, and
> >> TCON TVs be 2 and 3. Matching the actual register values is a nice
> >> convenience. These would be used by the driver as the TCON ID.
> > 
> > So something that's already done (minus full connections).
> > 
> >> Also, we might want to consider them as two pairs of two TCONs (LCD +
> >> TV).
> >> The CRTC in DRM land is actually the mixer + TCON on our platform. This
> >> means we only have two CRTCs. So we could have CRTC 0 = mixer 0 + TCON
> >> LCD
> >> 0 + TCON TV 0. The "TCON_TVx_OUTSEL" and "DE_PORTx PERH Select" muxes
> >> would
> >> be set at run time in the mode set function, selecting either LCD or TV
> >> based on what encoder is attached.
> > 
> > That proposal would still limit some combinations. For example, that would
> > put DSI always on mixer1, since it can be connected to only LCD TCON 1.
> > It can also cause undesired combination in laptop solutions. Consider
> > that PCB designer connected LCD1 pins to panel for some reason. Panel is
> > definetly main screen and should definetly be connected to mixer0, but in
> > that case, it would be to mixer1.
> 
> There's no reason we can't have dynamically assigned mixer+tcon pairs, but
> that would mean implementing additional scheduling code that we don't have
> yet. The current sunxi-drm and CRTC code assume static mappings.

I just remembered that your proposed solution while should work on R40, 
doesn't really fit in H6 case (which is the main reason for this series).

There are only LCD TCON 0 and TV TCON 0. Their HW IDs are the same as on R40 
(1 and 3). Additionaly, there is also HDMI mux as on R40, although there is 
only one TV TCON, which can be used only for HDMI (TV output is connected to 
LCD TCON through AC200 bridge, put on same die or glued in same package, not 
really sure and doesn't really matter).

I would like to write something which is also going to work for H6 out of the 
box. For H6, following combination would work well:
mixer0 = LCD TCON 1 + TV TCON 0
mixer1 = LCD TCON 0 + TV TCON 1

Or alternatively, we can leave that to mux callback in TCON which would take 
care for best variant for given SoC.

Once we concur on that, I'll try to implement something.

> 
> We could do this as a second step if you're up to it.

For my ultimate goal, which is 1st class Kodi experience on mainline, current 
proposal works in any case (mixer1 is enough). I just don't like solutions 
which are not universal.

> 
> > Additionaly, since HDMI would became floating between TV TCON 0 and 1,
> > whoever would write board DT would need to know this and enable only TV
> > TCON1 if LCD is desired to be connected to mixer0 (or vice versa).
> 
> There's no reason not to have all TCONs enabled by default. We would
> consider the display-engine node controlling whether everything actually
> gets used.
> > If we really want universal solution with full connections, addtional
> > property has to be defined and used for that.
> > 
> >> This limitation is a software one, and should not bleed over into the
> >> hardware representation.
> >> 
> >> > Additionaly, how would HDMI know which TCON belongs to it to
> >> > appropriately
> >> > set possible_crtcs?
> >> 
> >> HDMI is connected to the two TCON TVs through the TCON TOP mux. We handle
> >> TCON output muxing in the TCON driver, using the set_mux callback in the
> >> quirks. For R40, this callback would probably call into the TCON TOP
> >> driver
> >> asking it to set the mux to some value.
> >> 
> >> > Currently, my idea is that board DT creates wanted connections. Since
> >> > there is only one valid connection for each mux, driver knows eactly
> >> > what
> >> > to write into mux register. HDMI driver can simply check which TCON
> >> > connection is valid in HDMI input mux and select it in possible_crtcs.
> >> 
> >> But that is not how the actual hardware looks like. The device tree
> >> should
> >> model the hardware, not a subset of it just because one thinks the
> >> implementation is difficult or won't be used at all.
> >> 
> >> Furthermore, I think you have it backwards. possible_crtcs is generated
> >> based on (in our case) the connections between TCON and HDMI based on the
> >> device tree graph. So if you have both hooked up, both will show up in
> >> possible_crtcs, but only one crtc will actually be selected to feed the
> >> HDMI encoder. If you really need to access the current crtc, the
> >> drm_encoder struct contains a pointer to it.
> >> 
> >> In DE 1.0 driver, we leave all the muxing to the TCON driver. See
> >> 
> >> 
> >> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/sun4i/sun4
> >> i_
> >> tcon.c#L537
> >> 
> >> So in a sense, the HDMI encoder should be and is hooked up to both TCONs,
> >> but only one is active at any given time.
> > 
> > So something like that I had in v1 series. I'll implement something
> > similar. That would also mean we need R40 specific TV TCON compatible.
> > I'll restore that.
> > 
> > Just a question on future situation when TVE driver will be implemented.
> > Suppose that R40 board has TVE0 and HDMI as outputs. This would mean that
> > TVE0 has possible crtcs set as 0b01 and HDMI 0b11. Will be DRM framework
> > smart enough that it will put HDMI on second crtc because TVE0 can be
> > connected to only to first crtc?
> 
> Yes. If the possible_clones setting for the encoder is not set, the DRM
> framework will not do mirroring, and will keep each active encoder on a
> separate crtc.
> 
> >> > Please also note that mixer0 and mixer1 don't have same capabilities
> >> > and
> >> > you generally want mixer0 to be connected to main output. This is in
> >> > contrast to DE1 SoCs, where both backends and both frontends have same
> >> > capability.
> >> 
> >> Yes. But who's to say the two display outputs can't be reversed or
> >> swapped
> >> around? With fixed singular connections, you also rule out mirrored
> >> output.
> > 
> > I don't think there is standard way to swap around mixers at runtime,
> > expecially if crtcs are represented as mixer + TCON pair.
> 
> As I mentioned above, we will have to do this on our own.
> 
> > I'm not sure what do you mean with mirrored output or at least why
> > singular
> > connections would prevent mirroring. HW mirroring needs DRM writeback
> > support which is currently in RFC phase if I'm not mistaken. Once
> > implemented in DRM framework and in sun4i-drm, it would be possible only
> > to mirror mixer0 -> mixer1, because mixer1 doesn't support writeback (at
> > least on existing SoCs).
> What I meant was it might be possible to drive two TCONs with one mixer, or
> two encoders with one TCON. I guess the latter is not possible since each
> TCON only has one channel. Not sure about the former.
 
I think neither of this two variants are possible, because outputs would have 
to have exactly the same resolution and in second case even the same pixel 
clock, which is very unlikely.

Best regards,
Jernej

> Regards
> ChenYu
> 
> > Best regards,
> > Jernej
> > 
> >> ChenYu
> >> 
> >> >> ChenYu
> >> >> 
> >> >> > +                               };
> >> >> > +                       };
> >> >> > +               };
> >> >> > +
> >> >> > 
> >> >> >                 gic: interrupt-controller@1c81000 {
> >> >> >                 
> >> >> >                         compatible = "arm,gic-400";
> >> >> >                         reg = <0x01c81000 0x1000>,
> >> >> > 
> >> >> > @@ -461,6 +685,51 @@
> >> >> > 
> >> >> >                         #interrupt-cells = <3>;
> >> >> >                         interrupts = <GIC_PPI 9
> >> >> >                         (GIC_CPU_MASK_SIMPLE(4)
> >> >> >                         
> >> >> >                         IRQ_TYPE_LEVEL_HIGH)>;
> >> >> >                 
> >> >> >                 };
> >> >> > 
> >> >> > +
> >> >> > +               hdmi: hdmi@1ee0000 {
> >> >> > +                       compatible = "allwinner,sun8i-r40-dw-hdmi",
> >> >> > +                                    "allwinner,sun8i-a83t-dw-hdmi";
> >> >> > +                       reg = <0x01ee0000 0x10000>;
> >> >> > +                       reg-io-width = <1>;
> >> >> > +                       interrupts = <GIC_SPI 58
> >> >> > IRQ_TYPE_LEVEL_HIGH>;
> >> >> > +                       clocks = <&ccu CLK_BUS_HDMI0>, <&ccu
> >> >> > CLK_HDMI_SLOW>, +                                <&ccu CLK_HDMI>;
> >> >> > +                       clock-names = "iahb", "isfr", "tmds";
> >> >> > +                       resets = <&ccu RST_BUS_HDMI1>;
> >> >> > +                       reset-names = "ctrl";
> >> >> > +                       phys = <&hdmi_phy>;
> >> >> > +                       phy-names = "hdmi-phy";
> >> >> > +                       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@1ef0000 {
> >> >> > +                       compatible = "allwinner,sun8i-r40-hdmi-phy",
> >> >> > +                                   
> >> >> > "allwinner,sun50i-a64-hdmi-phy";
> >> >> > +                       reg = <0x01ef0000 0x10000>;
> >> >> > +                       clocks = <&ccu CLK_BUS_HDMI1>, <&ccu
> >> >> > CLK_HDMI_SLOW>, +                                <&ccu 7>, <&ccu
> >> >> > 16>;
> >> >> > +                       clock-names = "bus", "mod", "pll-0",
> >> >> > "pll-1";
> >> >> > +                       resets = <&ccu RST_BUS_HDMI0>;
> >> >> > +                       reset-names = "phy";
> >> >> > +                       #phy-cells = <0>;
> >> >> > +               };
> >> >> > 
> >> >> >         };
> >> >> >         
> >> >> >         timer {
> >> >> > 
> >> >> > --
> >> >> > 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] 87+ messages in thread

* Re: [linux-sunxi] Re: [PATCH v3 23/24] ARM: dts: sun8i: r40: Add HDMI pipeline
  2018-07-01 15:13             ` Jernej Škrabec
@ 2018-07-01 15:35               ` Chen-Yu Tsai
  2018-07-01 19:25                 ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-07-01 15:35 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Sun, Jul 1, 2018 at 11:13 PM, Jernej Škrabec <jernej.skrabec@siol.net> wrote:
> Dne nedelja, 01. julij 2018 ob 15:52:55 CEST je Chen-Yu Tsai napisal(a):
>> On Sun, Jul 1, 2018 at 6:41 PM, Jernej Škrabec <jernej.skrabec@siol.net>
> wrote:
>> > Dne četrtek, 28. junij 2018 ob 08:51:07 CEST je Chen-Yu Tsai napisal(a):
>> >> On Thu, Jun 28, 2018 at 1:15 PM, Jernej Škrabec <jernej.skrabec@siol.net>
>> >
>> > wrote:
>> >> > Dne četrtek, 28. junij 2018 ob 04:50:09 CEST je Chen-Yu Tsai
> napisal(a):
>> >> >> On Mon, Jun 25, 2018 at 8:03 PM, Jernej Skrabec
>> >> >> <jernej.skrabec@siol.net>
>> >> >
>> >> > wrote:
>> >> >> > Add all entries needed for HDMI to function properly.
>> >> >> >
>> >> >> > Since R40 has highly configurable pipeline, both mixers and both
>> >> >> > TCON
>> >> >> > TVs are added. Board specific DT should then connect them together
>> >> >> > trough TCON TOP muxers to best fit the purpose of the board.
>> >> >> >
>> >> >> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>> >> >> > ---
>> >> >> >
>> >> >> >  arch/arm/boot/dts/sun8i-r40.dtsi | 269
>> >> >> >  +++++++++++++++++++++++++++++++
>> >> >> >  1 file changed, 269 insertions(+)
>> >> >> >
>> >> >> > diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi
>> >> >> > b/arch/arm/boot/dts/sun8i-r40.dtsi index 173dcc1652d2..a2a75fb04caf
>> >> >> > 100644
>> >> >> > --- a/arch/arm/boot/dts/sun8i-r40.dtsi
>> >> >> > +++ b/arch/arm/boot/dts/sun8i-r40.dtsi
>> >> >> > @@ -42,8 +42,11 @@
>> >> >> >
>> >> >> >   */
>> >> >> >
>> >> >> >  #include <dt-bindings/interrupt-controller/arm-gic.h>
>> >> >> >
>> >> >> > +#include <dt-bindings/clock/sun8i-de2.h>
>> >> >> >
>> >> >> >  #include <dt-bindings/clock/sun8i-r40-ccu.h>
>> >> >> >
>> >> >> > +#include <dt-bindings/clock/sun8i-tcon-top.h>
>> >> >
>> >> > Maxime, above line breaks compilation for build robot, sorry.
>> >> >
>> >> >> >  #include <dt-bindings/reset/sun8i-r40-ccu.h>
>> >> >> >
>> >> >> > +#include <dt-bindings/reset/sun8i-de2.h>
>> >> >> >
>> >> >> >  / {
>> >> >> >
>> >> >> >         #address-cells = <1>;
>> >> >> >
>> >> >> > @@ -99,12 +102,76 @@
>> >> >> >
>> >> >> >                 };
>> >> >> >
>> >> >> >         };
>> >> >> >
>> >> >> > +       de: display-engine {
>> >> >> > +               compatible = "allwinner,sun8i-r40-display-engine",
>> >> >> > +                            "allwinner,sun8i-h3-display-engine";
>> >> >>
>> >> >> Given that the display pipeline looks different, they should not be
>> >> >> compatible.
>> >> >
>> >> > Ok.
>> >> >
>> >> >> > +               allwinner,pipelines = <&mixer0>, <&mixer1>;
>> >> >> > +               status = "disabled";
>> >> >> > +       };
>> >> >> > +
>> >> >> >
>> >> >> >         soc {
>> >> >> >
>> >> >> >                 compatible = "simple-bus";
>> >> >> >                 #address-cells = <1>;
>> >> >> >                 #size-cells = <1>;
>> >> >> >                 ranges;
>> >> >> >
>> >> >> > +               display_clocks: clock@1000000 {
>> >> >> > +                       compatible = "allwinner,sun8i-r40-de2-clk",
>> >> >> > +                                    "allwinner,sun8i-h3-de2-clk";
>> >> >> > +                       reg = <0x01000000 0x100000>;
>> >> >> > +                       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@1100000 {
>> >> >> > +                       compatible =
>> >> >> > "allwinner,sun8i-r40-de2-mixer-0";
>> >> >> > +                       reg = <0x01100000 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:
>> >> >> > endpoint {
>> >> >> > +                                               remote-endpoint =
>> >> >> > <&tcon_top_mixer0_in_mixer0>; +
>> >> >> > };
>> >> >> > +                               };
>> >> >> > +                       };
>> >> >> > +               };
>> >> >> > +
>> >> >> > +               mixer1: mixer@1200000 {
>> >> >> > +                       compatible =
>> >> >> > "allwinner,sun8i-r40-de2-mixer-1";
>> >> >> > +                       reg = <0x01200000 0x100000>;
>> >> >> > +                       clocks = <&display_clocks CLK_BUS_MIXER1>,
>> >> >> > +                                <&display_clocks CLK_MIXER1>;
>> >> >> > +                       clock-names = "bus",
>> >> >> > +                                     "mod";
>> >> >> > +                       resets = <&display_clocks RST_WB>;
>> >> >> > +
>> >> >> > +                       ports {
>> >> >> > +                               #address-cells = <1>;
>> >> >> > +                               #size-cells = <0>;
>> >> >> > +
>> >> >> > +                               mixer1_out: port@1 {
>> >> >> > +                                       reg = <1>;
>> >> >> > +                                       mixer1_out_tcon_top:
>> >> >> > endpoint {
>> >> >> > +                                               remote-endpoint =
>> >> >> > <&tcon_top_mixer1_in_mixer1>; +
>> >> >> > };
>> >> >> > +                               };
>> >> >> > +                       };
>> >> >> > +               };
>> >> >> > +
>> >> >> >
>> >> >> >                 nmi_intc: interrupt-controller@1c00030 {
>> >> >> >
>> >> >> >                         compatible = "allwinner,sun7i-a20-sc-nmi";
>> >> >> >                         interrupt-controller;
>> >> >> >
>> >> >> > @@ -451,6 +518,163 @@
>> >> >> >
>> >> >> >                         #size-cells = <0>;
>> >> >> >
>> >> >> >                 };
>> >> >> >
>> >> >> > +               tcon_top: tcon-top@1c70000 {
>> >> >> > +                       compatible = "allwinner,sun8i-r40-tcon-top";
>> >> >> > +                       reg = <0x01c70000 0x1000>;
>> >> >> > +                       clocks = <&ccu CLK_BUS_TCON_TOP>,
>> >> >> > +                                <&ccu CLK_TCON_TV0>,
>> >> >> > +                                <&ccu CLK_TVE0>,
>> >> >> > +                                <&ccu CLK_TCON_TV1>,
>> >> >> > +                                <&ccu CLK_TVE1>,
>> >> >> > +                                <&ccu CLK_DSI_DPHY>;
>> >> >> > +                       clock-names = "bus",
>> >> >> > +                                     "tcon-tv0",
>> >> >> > +                                     "tve0",
>> >> >> > +                                     "tcon-tv1",
>> >> >> > +                                     "tve1",
>> >> >> > +                                     "dsi";
>> >> >> > +                       clock-output-names = "tcon-top-tv0",
>> >> >> > +                                            "tcon-top-tv1",
>> >> >> > +                                            "tcon-top-dsi";
>> >> >> > +                       resets = <&ccu RST_BUS_TCON_TOP>;
>> >> >> > +                       #clock-cells = <1>;
>> >> >> > +
>> >> >> > +                       ports {
>> >> >> > +                               #address-cells = <1>;
>> >> >> > +                               #size-cells = <0>;
>> >> >> > +
>> >> >> > +                               tcon_top_mixer0_in: port@0 {
>> >> >> > +                                       reg = <0>;
>> >> >> > +
>> >> >> > +                                       tcon_top_mixer0_in_mixer0:
>> >> >> > endpoint { +
>> >> >> > remote-endpoint = <&mixer0_out_tcon_top>; +
>> >> >> >
>> >> >> >         };
>> >> >> >
>> >> >> > +                               };
>> >> >> > +
>> >> >> > +                               tcon_top_mixer0_out: port@1 {
>> >> >> > +                                       #address-cells = <1>;
>> >> >> > +                                       #size-cells = <0>;
>> >> >> > +                                       reg = <1>;
>> >> >> > +
>> >> >> > +
>> >> >> > tcon_top_mixer0_out_tcon_lcd0:
>> >> >> > endpoint@0 { +                                               reg =
>> >> >> > <0>;
>> >> >> > +                                       };
>> >> >> > +
>> >> >> > +
>> >> >> > tcon_top_mixer0_out_tcon_lcd1:
>> >> >> > endpoint@1 { +                                               reg =
>> >> >> > <1>;
>> >> >> > +                                       };
>> >> >> > +
>> >> >> > +
>> >> >> > tcon_top_mixer0_out_tcon_tv0:
>> >> >> > endpoint@2 { +                                               reg =
>> >> >> > <2>;
>> >> >> > +                                       };
>> >> >> > +
>> >> >> > +
>> >> >> > tcon_top_mixer0_out_tcon_tv1:
>> >> >> > endpoint@3 { +                                               reg =
>> >> >> > <3>;
>> >> >> > +                                       };
>> >> >> > +                               };
>> >> >> > +
>> >> >> > +                               tcon_top_mixer1_in: port@2 {
>> >> >> > +                                       reg = <2>;
>> >> >> > +
>> >> >> > +                                       tcon_top_mixer1_in_mixer1:
>> >> >> > endpoint { +
>> >> >> > remote-endpoint = <&mixer1_out_tcon_top>; +
>> >> >> >
>> >> >> >         };
>> >> >> >
>> >> >> > +                               };
>> >> >> > +
>> >> >> > +                               tcon_top_mixer1_out: port@3 {
>> >> >> > +                                       #address-cells = <1>;
>> >> >> > +                                       #size-cells = <0>;
>> >> >> > +                                       reg = <3>;
>> >> >> > +
>> >> >> > +
>> >> >> > tcon_top_mixer1_out_tcon_lcd0:
>> >> >> > endpoint@0 { +                                               reg =
>> >> >> > <0>;
>> >> >> > +                                       };
>> >> >> > +
>> >> >> > +
>> >> >> > tcon_top_mixer1_out_tcon_lcd1:
>> >> >> > endpoint@1 { +                                               reg =
>> >> >> > <1>;
>> >> >> > +                                       };
>> >> >> > +
>> >> >> > +
>> >> >> > tcon_top_mixer1_out_tcon_tv0:
>> >> >> > endpoint@2 { +                                               reg =
>> >> >> > <2>;
>> >> >> > +                                       };
>> >> >> > +
>> >> >> > +
>> >> >> > tcon_top_mixer1_out_tcon_tv1:
>> >> >> > endpoint@3 { +                                               reg =
>> >> >> > <3>;
>> >> >> > +                                       };
>> >> >> > +                               };
>> >> >> > +
>> >> >> > +                               tcon_top_hdmi_in: port@4 {
>> >> >> > +                                       #address-cells = <1>;
>> >> >> > +                                       #size-cells = <0>;
>> >> >> > +                                       reg = <4>;
>> >> >> > +
>> >> >> > +                                       tcon_top_hdmi_in_tcon_tv0:
>> >> >> > endpoint@0 { +                                               reg =
>> >> >> > <0>;
>> >> >> > +                                       };
>> >> >> > +
>> >> >> > +                                       tcon_top_hdmi_in_tcon_tv1:
>> >> >> > endpoint@1 { +                                               reg =
>> >> >> > <1>;
>> >> >> > +                                       };
>> >> >> > +                               };
>> >> >> > +
>> >> >> > +                               tcon_top_hdmi_out: port@5 {
>> >> >> > +                                       reg = <5>;
>> >> >> > +
>> >> >> > +                                       tcon_top_hdmi_out_hdmi:
>> >> >> > endpoint {
>> >> >> > +                                               remote-endpoint =
>> >> >> > <&hdmi_in_tcon_top>; +                                       };
>> >> >> > +                               };
>> >> >> > +                       };
>> >> >> > +               };
>> >> >> > +
>> >> >> > +               tcon_tv0: lcd-controller@1c73000 {
>> >> >> > +                       compatible = "allwinner,sun8i-r40-tcon-tv",
>> >> >> > +                                    "allwinner,sun8i-a83t-tcon-tv";
>> >> >> > +                       reg = <0x01c73000 0x1000>;
>> >> >> > +                       interrupts = <GIC_SPI 51
>> >> >> > IRQ_TYPE_LEVEL_HIGH>;
>> >> >> > +                       clocks = <&ccu CLK_BUS_TCON_TV0>, <&tcon_top
>> >> >> > 0>;
>> >> >> > +                       clock-names = "ahb", "tcon-ch1";
>> >> >> > +                       resets = <&ccu RST_BUS_TCON_TV0>;
>> >> >> > +                       reset-names = "lcd";
>> >> >> > +
>> >> >> > +                       ports {
>> >> >> > +                               #address-cells = <1>;
>> >> >> > +                               #size-cells = <0>;
>> >> >> > +
>> >> >> > +                               tcon_tv0_in: port@0 {
>> >> >> > +                                       reg = <0>;
>> >> >> > +                               };
>> >> >> > +
>> >> >> > +                               tcon_tv0_out: port@1 {
>> >> >> > +                                       reg = <1>;
>> >> >> > +                               };
>> >> >> > +                       };
>> >> >> > +               };
>> >> >> > +
>> >> >> > +               tcon_tv1: lcd-controller@1c74000 {
>> >> >> > +                       compatible = "allwinner,sun8i-r40-tcon-tv",
>> >> >> > +                                    "allwinner,sun8i-a83t-tcon-tv";
>> >> >> > +                       reg = <0x01c74000 0x1000>;
>> >> >> > +                       interrupts = <GIC_SPI 52
>> >> >> > IRQ_TYPE_LEVEL_HIGH>;
>> >> >> > +                       clocks = <&ccu CLK_BUS_TCON_TV1>, <&tcon_top
>> >> >> > 1>;
>> >> >> > +                       clock-names = "ahb", "tcon-ch1";
>> >> >> > +                       resets = <&ccu RST_BUS_TCON_TV1>;
>> >> >> > +                       reset-names = "lcd";
>> >> >> > +
>> >> >> > +                       ports {
>> >> >> > +                               #address-cells = <1>;
>> >> >> > +                               #size-cells = <0>;
>> >> >> > +
>> >> >> > +                               tcon_tv1_in: port@0 {
>> >> >> > +                                       reg = <0>;
>> >> >> > +                               };
>> >> >> > +
>> >> >> > +                               tcon_tv1_out: port@1 {
>> >> >> > +                                       reg = <1>;
>> >> >>
>> >> >> You are missing the remote-endpoints for all the TCON-TOP <-> TCON
>> >> >> connections. Also, on the driver side, there's no code to handle
>> >> >> dynamically mapping mixers to the TCONs that are being used. In the
>> >> >> past
>> >> >> we
>> >> >> had simple 1:1 mappings. This is no longer the case, and it needs to
>> >> >> be
>> >> >> dealt with.
>> >> >
>> >> > How would TCON TOP driver know how to set muxes? There are no
>> >> > appropriate
>> >> > bingings for muxes, except for V4L2 subsystem, which doesn't really
>> >> > work
>> >> > here.
>> >>
>> >> This will end up being a bunch of custom functions exported from the TCON
>> >> TOP driver to the TCON driver. As for bindings, the stuff you already
>> >> have
>> >> is mostly enough. You do have to specify the endpoint ID vs component
>> >> mapping, so you can find the correct one.
>> >>
>> >> For example, you would specify that the IDs for TCON LCDs be 0 and 1, and
>> >> TCON TVs be 2 and 3. Matching the actual register values is a nice
>> >> convenience. These would be used by the driver as the TCON ID.
>> >
>> > So something that's already done (minus full connections).
>> >
>> >> Also, we might want to consider them as two pairs of two TCONs (LCD +
>> >> TV).
>> >> The CRTC in DRM land is actually the mixer + TCON on our platform. This
>> >> means we only have two CRTCs. So we could have CRTC 0 = mixer 0 + TCON
>> >> LCD
>> >> 0 + TCON TV 0. The "TCON_TVx_OUTSEL" and "DE_PORTx PERH Select" muxes
>> >> would
>> >> be set at run time in the mode set function, selecting either LCD or TV
>> >> based on what encoder is attached.
>> >
>> > That proposal would still limit some combinations. For example, that would
>> > put DSI always on mixer1, since it can be connected to only LCD TCON 1.
>> > It can also cause undesired combination in laptop solutions. Consider
>> > that PCB designer connected LCD1 pins to panel for some reason. Panel is
>> > definetly main screen and should definetly be connected to mixer0, but in
>> > that case, it would be to mixer1.
>>
>> There's no reason we can't have dynamically assigned mixer+tcon pairs, but
>> that would mean implementing additional scheduling code that we don't have
>> yet. The current sunxi-drm and CRTC code assume static mappings.
>
> I just remembered that your proposed solution while should work on R40,
> doesn't really fit in H6 case (which is the main reason for this series).
>
> There are only LCD TCON 0 and TV TCON 0. Their HW IDs are the same as on R40
> (1 and 3). Additionaly, there is also HDMI mux as on R40, although there is
> only one TV TCON, which can be used only for HDMI (TV output is connected to
> LCD TCON through AC200 bridge, put on same die or glued in same package, not
> really sure and doesn't really matter).

OK. So even there's only one TV TCON, you still have to program all muxes with
the correct value, to prevent a) a bad value left by the bootloader and b) bad
reset default values.

> I would like to write something which is also going to work for H6 out of the
> box. For H6, following combination would work well:
> mixer0 = LCD TCON 1 + TV TCON 0
> mixer1 = LCD TCON 0 + TV TCON 1
>
> Or alternatively, we can leave that to mux callback in TCON which would take
> care for best variant for given SoC.

I think that is the ultimate goal. However, the muxing would be a bit
complicated. For all the past SoCs, we were dealing with muxing the
downstream encoder. Now we will be muxing mixer and tcon connections
as well. You would also have to dynamically switch around the mixer
and/or tcon pointers in sun4i_crtc so existing code can still work.

> Once we concur on that, I'll try to implement something.
>
>>
>> We could do this as a second step if you're up to it.
>
> For my ultimate goal, which is 1st class Kodi experience on mainline, current
> proposal works in any case (mixer1 is enough). I just don't like solutions
> which are not universal.
>
>>
>> > Additionaly, since HDMI would became floating between TV TCON 0 and 1,
>> > whoever would write board DT would need to know this and enable only TV
>> > TCON1 if LCD is desired to be connected to mixer0 (or vice versa).
>>
>> There's no reason not to have all TCONs enabled by default. We would
>> consider the display-engine node controlling whether everything actually
>> gets used.
>> > If we really want universal solution with full connections, addtional
>> > property has to be defined and used for that.
>> >
>> >> This limitation is a software one, and should not bleed over into the
>> >> hardware representation.
>> >>
>> >> > Additionaly, how would HDMI know which TCON belongs to it to
>> >> > appropriately
>> >> > set possible_crtcs?
>> >>
>> >> HDMI is connected to the two TCON TVs through the TCON TOP mux. We handle
>> >> TCON output muxing in the TCON driver, using the set_mux callback in the
>> >> quirks. For R40, this callback would probably call into the TCON TOP
>> >> driver
>> >> asking it to set the mux to some value.
>> >>
>> >> > Currently, my idea is that board DT creates wanted connections. Since
>> >> > there is only one valid connection for each mux, driver knows eactly
>> >> > what
>> >> > to write into mux register. HDMI driver can simply check which TCON
>> >> > connection is valid in HDMI input mux and select it in possible_crtcs.
>> >>
>> >> But that is not how the actual hardware looks like. The device tree
>> >> should
>> >> model the hardware, not a subset of it just because one thinks the
>> >> implementation is difficult or won't be used at all.
>> >>
>> >> Furthermore, I think you have it backwards. possible_crtcs is generated
>> >> based on (in our case) the connections between TCON and HDMI based on the
>> >> device tree graph. So if you have both hooked up, both will show up in
>> >> possible_crtcs, but only one crtc will actually be selected to feed the
>> >> HDMI encoder. If you really need to access the current crtc, the
>> >> drm_encoder struct contains a pointer to it.
>> >>
>> >> In DE 1.0 driver, we leave all the muxing to the TCON driver. See
>> >>
>> >>
>> >> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/sun4i/sun4
>> >> i_
>> >> tcon.c#L537
>> >>
>> >> So in a sense, the HDMI encoder should be and is hooked up to both TCONs,
>> >> but only one is active at any given time.
>> >
>> > So something like that I had in v1 series. I'll implement something
>> > similar. That would also mean we need R40 specific TV TCON compatible.
>> > I'll restore that.
>> >
>> > Just a question on future situation when TVE driver will be implemented.
>> > Suppose that R40 board has TVE0 and HDMI as outputs. This would mean that
>> > TVE0 has possible crtcs set as 0b01 and HDMI 0b11. Will be DRM framework
>> > smart enough that it will put HDMI on second crtc because TVE0 can be
>> > connected to only to first crtc?
>>
>> Yes. If the possible_clones setting for the encoder is not set, the DRM
>> framework will not do mirroring, and will keep each active encoder on a
>> separate crtc.
>>
>> >> > Please also note that mixer0 and mixer1 don't have same capabilities
>> >> > and
>> >> > you generally want mixer0 to be connected to main output. This is in
>> >> > contrast to DE1 SoCs, where both backends and both frontends have same
>> >> > capability.
>> >>
>> >> Yes. But who's to say the two display outputs can't be reversed or
>> >> swapped
>> >> around? With fixed singular connections, you also rule out mirrored
>> >> output.
>> >
>> > I don't think there is standard way to swap around mixers at runtime,
>> > expecially if crtcs are represented as mixer + TCON pair.
>>
>> As I mentioned above, we will have to do this on our own.
>>
>> > I'm not sure what do you mean with mirrored output or at least why
>> > singular
>> > connections would prevent mirroring. HW mirroring needs DRM writeback
>> > support which is currently in RFC phase if I'm not mistaken. Once
>> > implemented in DRM framework and in sun4i-drm, it would be possible only
>> > to mirror mixer0 -> mixer1, because mixer1 doesn't support writeback (at
>> > least on existing SoCs).
>> What I meant was it might be possible to drive two TCONs with one mixer, or
>> two encoders with one TCON. I guess the latter is not possible since each
>> TCON only has one channel. Not sure about the former.
>
> I think neither of this two variants are possible, because outputs would have
> to have exactly the same resolution and in second case even the same pixel
> clock, which is very unlikely.

That is what mirroring is supposed to mean, right? For instance you could
have VGA on one and HDMI on the other, at the same resolution and dotclock.

As far as I'm concerned, the software doesn't need to have all features
covered. But that doesn't mean the hardware representation can lack
features as well. We already did that once, and now we have some legacy
graph parsing code to handle that.

Regards
ChenYu

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

* Re: [linux-sunxi] Re: [PATCH v3 10/24] drm/sun4i: tcon: Generalize engine search algorithm
  2018-06-29 19:06         ` Jernej Škrabec
@ 2018-07-01 19:09           ` Jernej Škrabec
  2018-07-02  8:56             ` Maxime Ripard
  0 siblings, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-07-01 19:09 UTC (permalink / raw)
  To: linux-sunxi
  Cc: Maxime Ripard, Chen-Yu Tsai, Rob Herring, David Airlie,
	Gustavo Padovan, Maarten Lankhorst, Sean Paul, Mark Rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk

Dne petek, 29. junij 2018 ob 21:06:09 CEST je Jernej Škrabec napisal(a):
> Dne četrtek, 28. junij 2018 ob 20:25:43 CEST je Maxime Ripard napisal(a):
> > On Thu, Jun 28, 2018 at 06:48:50AM +0200, Jernej Škrabec wrote:
> > > Dne četrtek, 28. junij 2018 ob 04:06:52 CEST je Chen-Yu Tsai napisal(a):
> > > > On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec
> > > > <jernej.skrabec@siol.net>
> > > 
> > > wrote:
> > > > > Current "old" method to find engine worked pretty well for DE2.
> > > > > However,
> > > > > it doesn't work when TCON TOP is between  mixer (engine) and TCON.
> > > > > TCON
> > > > > TOP has multiple input ports, but current engine search algorithm
> > > > > expects only one.
> > > > > 
> > > > > This can be fixed by first looking for output port id and selecting
> > > > > matching input by subtracting 1 for the next round. This work even
> > > > > if
> > > > > there is only one input and output.
> > > > > 
> > > > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > > > ---
> > > > > 
> > > > >  drivers/gpu/drm/sun4i/sun4i_tcon.c | 22 ++++++++++++++++++----
> > > > >  1 file changed, 18 insertions(+), 4 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c index
> > > > > 08747fc3ee71..264bcc43da11
> > > > > 100644
> > > > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > @@ -791,12 +791,14 @@ static int sun4i_tcon_init_regmap(struct
> > > > > device
> > > > > *dev,
> > > > > 
> > > > >   */
> > > > >  
> > > > >  static struct sunxi_engine *
> > > > >  sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv,
> > > > > 
> > > > > -                               struct device_node *node)
> > > > > +                               struct device_node *node,
> > > > > +                               u32 port_id)
> > > > > 
> > > > >  {
> > > > >  
> > > > >         struct device_node *port, *ep, *remote;
> > > > >         struct sunxi_engine *engine = ERR_PTR(-EINVAL);
> > > > > 
> > > > > +       u32 reg = 0;
> > > > > 
> > > > > -       port = of_graph_get_port_by_id(node, 0);
> > > > > +       port = of_graph_get_port_by_id(node, port_id);
> > > > > 
> > > > >         if (!port)
> > > > >         
> > > > >                 return ERR_PTR(-EINVAL);
> > > > > 
> > > > > @@ -826,8 +828,20 @@ sun4i_tcon_find_engine_traverse(struct
> > > > > sun4i_drv
> > > > > *drv,
> > > > > 
> > > > >                 if (remote == engine->node)
> > > > >                 
> > > > >                         goto out_put_remote;
> > > > > 
> > > > > +       /*
> > > > > +        * According to device tree binding input ports have even id
> > > > > +        * number and output ports have odd id. Since component with
> > > > > +        * more than one input and one output (TCON TOP) exits,
> > > > > correct
> > > > > +        * remote input id has to be calculated by subtracting 1
> > > > > from
> > > > > +        * remote output id. If this for some reason can't be done,
> > > > > 0
> > > > > +        * is used as input port id.
> > > > > +        */
> > > > 
> > > > You need to call
> > > > 
> > > >     of_node_put(port);
> > > > 
> > > > to drop the reference to the original port.
> > > 
> > > Thanks for noticing it. I guess I should send fix patch, since patches
> > > from
> > > drm-misc-next can't be dropped.
> > 
> > Yeah, please send additional patches for all the issues pointed out by
> > Chen-Yu.
> 
> Of course. I hope this can be resolved till the end of the next week. After
> that, I will be away from PC for 2 weeks. Feel free to drop DT patches if
> you think that it will come too close to merge window.

Actually, can you drop it anyway? It needs a lot of changes and keeping HDMI 
working would need some effort.

Best regards,
Jernej





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

* Re: [linux-sunxi] Re: [PATCH v3 23/24] ARM: dts: sun8i: r40: Add HDMI pipeline
  2018-07-01 15:35               ` Chen-Yu Tsai
@ 2018-07-01 19:25                 ` Jernej Škrabec
  2018-07-02 21:39                   ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-07-01 19:25 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne nedelja, 01. julij 2018 ob 17:35:28 CEST je Chen-Yu Tsai napisal(a):
> On Sun, Jul 1, 2018 at 11:13 PM, Jernej Škrabec <jernej.skrabec@siol.net> 
wrote:
> > Dne nedelja, 01. julij 2018 ob 15:52:55 CEST je Chen-Yu Tsai napisal(a):
> >> On Sun, Jul 1, 2018 at 6:41 PM, Jernej Škrabec <jernej.skrabec@siol.net>
> > 
> > wrote:
> >> > Dne četrtek, 28. junij 2018 ob 08:51:07 CEST je Chen-Yu Tsai 
napisal(a):
> >> >> On Thu, Jun 28, 2018 at 1:15 PM, Jernej Škrabec
> >> >> <jernej.skrabec@siol.net>
> >> > 
> >> > wrote:
> >> >> > Dne četrtek, 28. junij 2018 ob 04:50:09 CEST je Chen-Yu Tsai
> > 
> > napisal(a):
> >> >> >> On Mon, Jun 25, 2018 at 8:03 PM, Jernej Skrabec
> >> >> >> <jernej.skrabec@siol.net>
> >> >> > 
> >> >> > wrote:
> >> >> >> > Add all entries needed for HDMI to function properly.
> >> >> >> > 
> >> >> >> > Since R40 has highly configurable pipeline, both mixers and both
> >> >> >> > TCON
> >> >> >> > TVs are added. Board specific DT should then connect them
> >> >> >> > together
> >> >> >> > trough TCON TOP muxers to best fit the purpose of the board.
> >> >> >> > 
> >> >> >> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> >> >> >> > ---
> >> >> >> > 
> >> >> >> >  arch/arm/boot/dts/sun8i-r40.dtsi | 269
> >> >> >> >  +++++++++++++++++++++++++++++++
> >> >> >> >  1 file changed, 269 insertions(+)
> >> >> >> > 
> >> >> >> > diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi
> >> >> >> > b/arch/arm/boot/dts/sun8i-r40.dtsi index
> >> >> >> > 173dcc1652d2..a2a75fb04caf
> >> >> >> > 100644
> >> >> >> > --- a/arch/arm/boot/dts/sun8i-r40.dtsi
> >> >> >> > +++ b/arch/arm/boot/dts/sun8i-r40.dtsi
> >> >> >> > @@ -42,8 +42,11 @@
> >> >> >> > 
> >> >> >> >   */
> >> >> >> >  
> >> >> >> >  #include <dt-bindings/interrupt-controller/arm-gic.h>
> >> >> >> > 
> >> >> >> > +#include <dt-bindings/clock/sun8i-de2.h>
> >> >> >> > 
> >> >> >> >  #include <dt-bindings/clock/sun8i-r40-ccu.h>
> >> >> >> > 
> >> >> >> > +#include <dt-bindings/clock/sun8i-tcon-top.h>
> >> >> > 
> >> >> > Maxime, above line breaks compilation for build robot, sorry.
> >> >> > 
> >> >> >> >  #include <dt-bindings/reset/sun8i-r40-ccu.h>
> >> >> >> > 
> >> >> >> > +#include <dt-bindings/reset/sun8i-de2.h>
> >> >> >> > 
> >> >> >> >  / {
> >> >> >> >  
> >> >> >> >         #address-cells = <1>;
> >> >> >> > 
> >> >> >> > @@ -99,12 +102,76 @@
> >> >> >> > 
> >> >> >> >                 };
> >> >> >> >         
> >> >> >> >         };
> >> >> >> > 
> >> >> >> > +       de: display-engine {
> >> >> >> > +               compatible =
> >> >> >> > "allwinner,sun8i-r40-display-engine",
> >> >> >> > +                            "allwinner,sun8i-h3-display-engine";
> >> >> >> 
> >> >> >> Given that the display pipeline looks different, they should not be
> >> >> >> compatible.
> >> >> > 
> >> >> > Ok.
> >> >> > 
> >> >> >> > +               allwinner,pipelines = <&mixer0>, <&mixer1>;
> >> >> >> > +               status = "disabled";
> >> >> >> > +       };
> >> >> >> > +
> >> >> >> > 
> >> >> >> >         soc {
> >> >> >> >         
> >> >> >> >                 compatible = "simple-bus";
> >> >> >> >                 #address-cells = <1>;
> >> >> >> >                 #size-cells = <1>;
> >> >> >> >                 ranges;
> >> >> >> > 
> >> >> >> > +               display_clocks: clock@1000000 {
> >> >> >> > +                       compatible =
> >> >> >> > "allwinner,sun8i-r40-de2-clk",
> >> >> >> > +                                   
> >> >> >> > "allwinner,sun8i-h3-de2-clk";
> >> >> >> > +                       reg = <0x01000000 0x100000>;
> >> >> >> > +                       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@1100000 {
> >> >> >> > +                       compatible =
> >> >> >> > "allwinner,sun8i-r40-de2-mixer-0";
> >> >> >> > +                       reg = <0x01100000 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:
> >> >> >> > endpoint {
> >> >> >> > +                                               remote-endpoint =
> >> >> >> > <&tcon_top_mixer0_in_mixer0>; +
> >> >> >> > };
> >> >> >> > +                               };
> >> >> >> > +                       };
> >> >> >> > +               };
> >> >> >> > +
> >> >> >> > +               mixer1: mixer@1200000 {
> >> >> >> > +                       compatible =
> >> >> >> > "allwinner,sun8i-r40-de2-mixer-1";
> >> >> >> > +                       reg = <0x01200000 0x100000>;
> >> >> >> > +                       clocks = <&display_clocks
> >> >> >> > CLK_BUS_MIXER1>,
> >> >> >> > +                                <&display_clocks CLK_MIXER1>;
> >> >> >> > +                       clock-names = "bus",
> >> >> >> > +                                     "mod";
> >> >> >> > +                       resets = <&display_clocks RST_WB>;
> >> >> >> > +
> >> >> >> > +                       ports {
> >> >> >> > +                               #address-cells = <1>;
> >> >> >> > +                               #size-cells = <0>;
> >> >> >> > +
> >> >> >> > +                               mixer1_out: port@1 {
> >> >> >> > +                                       reg = <1>;
> >> >> >> > +                                       mixer1_out_tcon_top:
> >> >> >> > endpoint {
> >> >> >> > +                                               remote-endpoint =
> >> >> >> > <&tcon_top_mixer1_in_mixer1>; +
> >> >> >> > };
> >> >> >> > +                               };
> >> >> >> > +                       };
> >> >> >> > +               };
> >> >> >> > +
> >> >> >> > 
> >> >> >> >                 nmi_intc: interrupt-controller@1c00030 {
> >> >> >> >                 
> >> >> >> >                         compatible =
> >> >> >> >                         "allwinner,sun7i-a20-sc-nmi";
> >> >> >> >                         interrupt-controller;
> >> >> >> > 
> >> >> >> > @@ -451,6 +518,163 @@
> >> >> >> > 
> >> >> >> >                         #size-cells = <0>;
> >> >> >> >                 
> >> >> >> >                 };
> >> >> >> > 
> >> >> >> > +               tcon_top: tcon-top@1c70000 {
> >> >> >> > +                       compatible =
> >> >> >> > "allwinner,sun8i-r40-tcon-top";
> >> >> >> > +                       reg = <0x01c70000 0x1000>;
> >> >> >> > +                       clocks = <&ccu CLK_BUS_TCON_TOP>,
> >> >> >> > +                                <&ccu CLK_TCON_TV0>,
> >> >> >> > +                                <&ccu CLK_TVE0>,
> >> >> >> > +                                <&ccu CLK_TCON_TV1>,
> >> >> >> > +                                <&ccu CLK_TVE1>,
> >> >> >> > +                                <&ccu CLK_DSI_DPHY>;
> >> >> >> > +                       clock-names = "bus",
> >> >> >> > +                                     "tcon-tv0",
> >> >> >> > +                                     "tve0",
> >> >> >> > +                                     "tcon-tv1",
> >> >> >> > +                                     "tve1",
> >> >> >> > +                                     "dsi";
> >> >> >> > +                       clock-output-names = "tcon-top-tv0",
> >> >> >> > +                                            "tcon-top-tv1",
> >> >> >> > +                                            "tcon-top-dsi";
> >> >> >> > +                       resets = <&ccu RST_BUS_TCON_TOP>;
> >> >> >> > +                       #clock-cells = <1>;
> >> >> >> > +
> >> >> >> > +                       ports {
> >> >> >> > +                               #address-cells = <1>;
> >> >> >> > +                               #size-cells = <0>;
> >> >> >> > +
> >> >> >> > +                               tcon_top_mixer0_in: port@0 {
> >> >> >> > +                                       reg = <0>;
> >> >> >> > +
> >> >> >> > +                                      
> >> >> >> > tcon_top_mixer0_in_mixer0:
> >> >> >> > endpoint { +
> >> >> >> > remote-endpoint = <&mixer0_out_tcon_top>; +
> >> >> >> > 
> >> >> >> >         };
> >> >> >> > 
> >> >> >> > +                               };
> >> >> >> > +
> >> >> >> > +                               tcon_top_mixer0_out: port@1 {
> >> >> >> > +                                       #address-cells = <1>;
> >> >> >> > +                                       #size-cells = <0>;
> >> >> >> > +                                       reg = <1>;
> >> >> >> > +
> >> >> >> > +
> >> >> >> > tcon_top_mixer0_out_tcon_lcd0:
> >> >> >> > endpoint@0 { +                                               reg
> >> >> >> > =
> >> >> >> > <0>;
> >> >> >> > +                                       };
> >> >> >> > +
> >> >> >> > +
> >> >> >> > tcon_top_mixer0_out_tcon_lcd1:
> >> >> >> > endpoint@1 { +                                               reg
> >> >> >> > =
> >> >> >> > <1>;
> >> >> >> > +                                       };
> >> >> >> > +
> >> >> >> > +
> >> >> >> > tcon_top_mixer0_out_tcon_tv0:
> >> >> >> > endpoint@2 { +                                               reg
> >> >> >> > =
> >> >> >> > <2>;
> >> >> >> > +                                       };
> >> >> >> > +
> >> >> >> > +
> >> >> >> > tcon_top_mixer0_out_tcon_tv1:
> >> >> >> > endpoint@3 { +                                               reg
> >> >> >> > =
> >> >> >> > <3>;
> >> >> >> > +                                       };
> >> >> >> > +                               };
> >> >> >> > +
> >> >> >> > +                               tcon_top_mixer1_in: port@2 {
> >> >> >> > +                                       reg = <2>;
> >> >> >> > +
> >> >> >> > +                                      
> >> >> >> > tcon_top_mixer1_in_mixer1:
> >> >> >> > endpoint { +
> >> >> >> > remote-endpoint = <&mixer1_out_tcon_top>; +
> >> >> >> > 
> >> >> >> >         };
> >> >> >> > 
> >> >> >> > +                               };
> >> >> >> > +
> >> >> >> > +                               tcon_top_mixer1_out: port@3 {
> >> >> >> > +                                       #address-cells = <1>;
> >> >> >> > +                                       #size-cells = <0>;
> >> >> >> > +                                       reg = <3>;
> >> >> >> > +
> >> >> >> > +
> >> >> >> > tcon_top_mixer1_out_tcon_lcd0:
> >> >> >> > endpoint@0 { +                                               reg
> >> >> >> > =
> >> >> >> > <0>;
> >> >> >> > +                                       };
> >> >> >> > +
> >> >> >> > +
> >> >> >> > tcon_top_mixer1_out_tcon_lcd1:
> >> >> >> > endpoint@1 { +                                               reg
> >> >> >> > =
> >> >> >> > <1>;
> >> >> >> > +                                       };
> >> >> >> > +
> >> >> >> > +
> >> >> >> > tcon_top_mixer1_out_tcon_tv0:
> >> >> >> > endpoint@2 { +                                               reg
> >> >> >> > =
> >> >> >> > <2>;
> >> >> >> > +                                       };
> >> >> >> > +
> >> >> >> > +
> >> >> >> > tcon_top_mixer1_out_tcon_tv1:
> >> >> >> > endpoint@3 { +                                               reg
> >> >> >> > =
> >> >> >> > <3>;
> >> >> >> > +                                       };
> >> >> >> > +                               };
> >> >> >> > +
> >> >> >> > +                               tcon_top_hdmi_in: port@4 {
> >> >> >> > +                                       #address-cells = <1>;
> >> >> >> > +                                       #size-cells = <0>;
> >> >> >> > +                                       reg = <4>;
> >> >> >> > +
> >> >> >> > +                                      
> >> >> >> > tcon_top_hdmi_in_tcon_tv0:
> >> >> >> > endpoint@0 { +                                               reg
> >> >> >> > =
> >> >> >> > <0>;
> >> >> >> > +                                       };
> >> >> >> > +
> >> >> >> > +                                      
> >> >> >> > tcon_top_hdmi_in_tcon_tv1:
> >> >> >> > endpoint@1 { +                                               reg
> >> >> >> > =
> >> >> >> > <1>;
> >> >> >> > +                                       };
> >> >> >> > +                               };
> >> >> >> > +
> >> >> >> > +                               tcon_top_hdmi_out: port@5 {
> >> >> >> > +                                       reg = <5>;
> >> >> >> > +
> >> >> >> > +                                       tcon_top_hdmi_out_hdmi:
> >> >> >> > endpoint {
> >> >> >> > +                                               remote-endpoint =
> >> >> >> > <&hdmi_in_tcon_top>; +                                       };
> >> >> >> > +                               };
> >> >> >> > +                       };
> >> >> >> > +               };
> >> >> >> > +
> >> >> >> > +               tcon_tv0: lcd-controller@1c73000 {
> >> >> >> > +                       compatible =
> >> >> >> > "allwinner,sun8i-r40-tcon-tv",
> >> >> >> > +                                   
> >> >> >> > "allwinner,sun8i-a83t-tcon-tv";
> >> >> >> > +                       reg = <0x01c73000 0x1000>;
> >> >> >> > +                       interrupts = <GIC_SPI 51
> >> >> >> > IRQ_TYPE_LEVEL_HIGH>;
> >> >> >> > +                       clocks = <&ccu CLK_BUS_TCON_TV0>,
> >> >> >> > <&tcon_top
> >> >> >> > 0>;
> >> >> >> > +                       clock-names = "ahb", "tcon-ch1";
> >> >> >> > +                       resets = <&ccu RST_BUS_TCON_TV0>;
> >> >> >> > +                       reset-names = "lcd";
> >> >> >> > +
> >> >> >> > +                       ports {
> >> >> >> > +                               #address-cells = <1>;
> >> >> >> > +                               #size-cells = <0>;
> >> >> >> > +
> >> >> >> > +                               tcon_tv0_in: port@0 {
> >> >> >> > +                                       reg = <0>;
> >> >> >> > +                               };
> >> >> >> > +
> >> >> >> > +                               tcon_tv0_out: port@1 {
> >> >> >> > +                                       reg = <1>;
> >> >> >> > +                               };
> >> >> >> > +                       };
> >> >> >> > +               };
> >> >> >> > +
> >> >> >> > +               tcon_tv1: lcd-controller@1c74000 {
> >> >> >> > +                       compatible =
> >> >> >> > "allwinner,sun8i-r40-tcon-tv",
> >> >> >> > +                                   
> >> >> >> > "allwinner,sun8i-a83t-tcon-tv";
> >> >> >> > +                       reg = <0x01c74000 0x1000>;
> >> >> >> > +                       interrupts = <GIC_SPI 52
> >> >> >> > IRQ_TYPE_LEVEL_HIGH>;
> >> >> >> > +                       clocks = <&ccu CLK_BUS_TCON_TV1>,
> >> >> >> > <&tcon_top
> >> >> >> > 1>;
> >> >> >> > +                       clock-names = "ahb", "tcon-ch1";
> >> >> >> > +                       resets = <&ccu RST_BUS_TCON_TV1>;
> >> >> >> > +                       reset-names = "lcd";
> >> >> >> > +
> >> >> >> > +                       ports {
> >> >> >> > +                               #address-cells = <1>;
> >> >> >> > +                               #size-cells = <0>;
> >> >> >> > +
> >> >> >> > +                               tcon_tv1_in: port@0 {
> >> >> >> > +                                       reg = <0>;
> >> >> >> > +                               };
> >> >> >> > +
> >> >> >> > +                               tcon_tv1_out: port@1 {
> >> >> >> > +                                       reg = <1>;
> >> >> >> 
> >> >> >> You are missing the remote-endpoints for all the TCON-TOP <-> TCON
> >> >> >> connections. Also, on the driver side, there's no code to handle
> >> >> >> dynamically mapping mixers to the TCONs that are being used. In the
> >> >> >> past
> >> >> >> we
> >> >> >> had simple 1:1 mappings. This is no longer the case, and it needs
> >> >> >> to
> >> >> >> be
> >> >> >> dealt with.
> >> >> > 
> >> >> > How would TCON TOP driver know how to set muxes? There are no
> >> >> > appropriate
> >> >> > bingings for muxes, except for V4L2 subsystem, which doesn't really
> >> >> > work
> >> >> > here.
> >> >> 
> >> >> This will end up being a bunch of custom functions exported from the
> >> >> TCON
> >> >> TOP driver to the TCON driver. As for bindings, the stuff you already
> >> >> have
> >> >> is mostly enough. You do have to specify the endpoint ID vs component
> >> >> mapping, so you can find the correct one.
> >> >> 
> >> >> For example, you would specify that the IDs for TCON LCDs be 0 and 1,
> >> >> and
> >> >> TCON TVs be 2 and 3. Matching the actual register values is a nice
> >> >> convenience. These would be used by the driver as the TCON ID.
> >> > 
> >> > So something that's already done (minus full connections).
> >> > 
> >> >> Also, we might want to consider them as two pairs of two TCONs (LCD +
> >> >> TV).
> >> >> The CRTC in DRM land is actually the mixer + TCON on our platform.
> >> >> This
> >> >> means we only have two CRTCs. So we could have CRTC 0 = mixer 0 + TCON
> >> >> LCD
> >> >> 0 + TCON TV 0. The "TCON_TVx_OUTSEL" and "DE_PORTx PERH Select" muxes
> >> >> would
> >> >> be set at run time in the mode set function, selecting either LCD or
> >> >> TV
> >> >> based on what encoder is attached.
> >> > 
> >> > That proposal would still limit some combinations. For example, that
> >> > would
> >> > put DSI always on mixer1, since it can be connected to only LCD TCON 1.
> >> > It can also cause undesired combination in laptop solutions. Consider
> >> > that PCB designer connected LCD1 pins to panel for some reason. Panel
> >> > is
> >> > definetly main screen and should definetly be connected to mixer0, but
> >> > in
> >> > that case, it would be to mixer1.
> >> 
> >> There's no reason we can't have dynamically assigned mixer+tcon pairs,
> >> but
> >> that would mean implementing additional scheduling code that we don't
> >> have
> >> yet. The current sunxi-drm and CRTC code assume static mappings.
> > 
> > I just remembered that your proposed solution while should work on R40,
> > doesn't really fit in H6 case (which is the main reason for this series).
> > 
> > There are only LCD TCON 0 and TV TCON 0. Their HW IDs are the same as on
> > R40 (1 and 3). Additionaly, there is also HDMI mux as on R40, although
> > there is only one TV TCON, which can be used only for HDMI (TV output is
> > connected to LCD TCON through AC200 bridge, put on same die or glued in
> > same package, not really sure and doesn't really matter).
> 
> OK. So even there's only one TV TCON, you still have to program all muxes
> with the correct value, to prevent a) a bad value left by the bootloader
> and b) bad reset default values.
> 
> > I would like to write something which is also going to work for H6 out of
> > the box. For H6, following combination would work well:
> > mixer0 = LCD TCON 1 + TV TCON 0
> > mixer1 = LCD TCON 0 + TV TCON 1
> > 
> > Or alternatively, we can leave that to mux callback in TCON which would
> > take care for best variant for given SoC.
> 
> I think that is the ultimate goal. However, the muxing would be a bit
> complicated. For all the past SoCs, we were dealing with muxing the
> downstream encoder. Now we will be muxing mixer and tcon connections
> as well. You would also have to dynamically switch around the mixer
> and/or tcon pointers in sun4i_crtc so existing code can still work.
> 
> > Once we concur on that, I'll try to implement something.
> > 
> >> We could do this as a second step if you're up to it.
> > 
> > For my ultimate goal, which is 1st class Kodi experience on mainline,
> > current proposal works in any case (mixer1 is enough). I just don't like
> > solutions which are not universal.
> > 
> >> > Additionaly, since HDMI would became floating between TV TCON 0 and 1,
> >> > whoever would write board DT would need to know this and enable only TV
> >> > TCON1 if LCD is desired to be connected to mixer0 (or vice versa).
> >> 
> >> There's no reason not to have all TCONs enabled by default. We would
> >> consider the display-engine node controlling whether everything actually
> >> gets used.
> >> 
> >> > If we really want universal solution with full connections, addtional
> >> > property has to be defined and used for that.
> >> > 
> >> >> This limitation is a software one, and should not bleed over into the
> >> >> hardware representation.
> >> >> 
> >> >> > Additionaly, how would HDMI know which TCON belongs to it to
> >> >> > appropriately
> >> >> > set possible_crtcs?
> >> >> 
> >> >> HDMI is connected to the two TCON TVs through the TCON TOP mux. We
> >> >> handle
> >> >> TCON output muxing in the TCON driver, using the set_mux callback in
> >> >> the
> >> >> quirks. For R40, this callback would probably call into the TCON TOP
> >> >> driver
> >> >> asking it to set the mux to some value.
> >> >> 
> >> >> > Currently, my idea is that board DT creates wanted connections.
> >> >> > Since
> >> >> > there is only one valid connection for each mux, driver knows eactly
> >> >> > what
> >> >> > to write into mux register. HDMI driver can simply check which TCON
> >> >> > connection is valid in HDMI input mux and select it in
> >> >> > possible_crtcs.
> >> >> 
> >> >> But that is not how the actual hardware looks like. The device tree
> >> >> should
> >> >> model the hardware, not a subset of it just because one thinks the
> >> >> implementation is difficult or won't be used at all.
> >> >> 
> >> >> Furthermore, I think you have it backwards. possible_crtcs is
> >> >> generated
> >> >> based on (in our case) the connections between TCON and HDMI based on
> >> >> the
> >> >> device tree graph. So if you have both hooked up, both will show up in
> >> >> possible_crtcs, but only one crtc will actually be selected to feed
> >> >> the
> >> >> HDMI encoder. If you really need to access the current crtc, the
> >> >> drm_encoder struct contains a pointer to it.
> >> >> 
> >> >> In DE 1.0 driver, we leave all the muxing to the TCON driver. See
> >> >> 
> >> >> 
> >> >> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/sun4i/s
> >> >> un4
> >> >> i_
> >> >> tcon.c#L537
> >> >> 
> >> >> So in a sense, the HDMI encoder should be and is hooked up to both
> >> >> TCONs,
> >> >> but only one is active at any given time.
> >> > 
> >> > So something like that I had in v1 series. I'll implement something
> >> > similar. That would also mean we need R40 specific TV TCON compatible.
> >> > I'll restore that.
> >> > 
> >> > Just a question on future situation when TVE driver will be
> >> > implemented.
> >> > Suppose that R40 board has TVE0 and HDMI as outputs. This would mean
> >> > that
> >> > TVE0 has possible crtcs set as 0b01 and HDMI 0b11. Will be DRM
> >> > framework
> >> > smart enough that it will put HDMI on second crtc because TVE0 can be
> >> > connected to only to first crtc?
> >> 
> >> Yes. If the possible_clones setting for the encoder is not set, the DRM
> >> framework will not do mirroring, and will keep each active encoder on a
> >> separate crtc.
> >> 
> >> >> > Please also note that mixer0 and mixer1 don't have same capabilities
> >> >> > and
> >> >> > you generally want mixer0 to be connected to main output. This is in
> >> >> > contrast to DE1 SoCs, where both backends and both frontends have
> >> >> > same
> >> >> > capability.
> >> >> 
> >> >> Yes. But who's to say the two display outputs can't be reversed or
> >> >> swapped
> >> >> around? With fixed singular connections, you also rule out mirrored
> >> >> output.
> >> > 
> >> > I don't think there is standard way to swap around mixers at runtime,
> >> > expecially if crtcs are represented as mixer + TCON pair.
> >> 
> >> As I mentioned above, we will have to do this on our own.
> >> 
> >> > I'm not sure what do you mean with mirrored output or at least why
> >> > singular
> >> > connections would prevent mirroring. HW mirroring needs DRM writeback
> >> > support which is currently in RFC phase if I'm not mistaken. Once
> >> > implemented in DRM framework and in sun4i-drm, it would be possible
> >> > only
> >> > to mirror mixer0 -> mixer1, because mixer1 doesn't support writeback
> >> > (at
> >> > least on existing SoCs).
> >> 
> >> What I meant was it might be possible to drive two TCONs with one mixer,
> >> or
> >> two encoders with one TCON. I guess the latter is not possible since each
> >> TCON only has one channel. Not sure about the former.
> > 
> > I think neither of this two variants are possible, because outputs would
> > have to have exactly the same resolution and in second case even the same
> > pixel clock, which is very unlikely.
> 
> That is what mirroring is supposed to mean, right? For instance you could
> have VGA on one and HDMI on the other, at the same resolution and dotclock.

Actually, R40 is the first SoC with DE2 where is theoretically possible to 
connect one mixer to multiple TCONs. I didn't try it yet because BPI M2U has 
apart from HDMI only DSI connector and TV out on test points and neither have 
support in mainline.

Best regards,
Jernej

> 
> As far as I'm concerned, the software doesn't need to have all features
> covered. But that doesn't mean the hardware representation can lack
> features as well. We already did that once, and now we have some legacy
> graph parsing code to handle that.
> 
> Regards
> ChenYu





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

* Re: [linux-sunxi] Re: [PATCH v3 10/24] drm/sun4i: tcon: Generalize engine search algorithm
  2018-07-01 19:09           ` [linux-sunxi] " Jernej Škrabec
@ 2018-07-02  8:56             ` Maxime Ripard
  0 siblings, 0 replies; 87+ messages in thread
From: Maxime Ripard @ 2018-07-02  8:56 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: linux-sunxi, Chen-Yu Tsai, Rob Herring, David Airlie,
	Gustavo Padovan, Maarten Lankhorst, Sean Paul, Mark Rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk

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

On Sun, Jul 01, 2018 at 09:09:47PM +0200, Jernej Škrabec wrote:
> Dne petek, 29. junij 2018 ob 21:06:09 CEST je Jernej Škrabec napisal(a):
> > Dne četrtek, 28. junij 2018 ob 20:25:43 CEST je Maxime Ripard napisal(a):
> > > On Thu, Jun 28, 2018 at 06:48:50AM +0200, Jernej Škrabec wrote:
> > > > Dne četrtek, 28. junij 2018 ob 04:06:52 CEST je Chen-Yu Tsai napisal(a):
> > > > > On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec
> > > > > <jernej.skrabec@siol.net>
> > > > 
> > > > wrote:
> > > > > > Current "old" method to find engine worked pretty well for DE2.
> > > > > > However,
> > > > > > it doesn't work when TCON TOP is between  mixer (engine) and TCON.
> > > > > > TCON
> > > > > > TOP has multiple input ports, but current engine search algorithm
> > > > > > expects only one.
> > > > > > 
> > > > > > This can be fixed by first looking for output port id and selecting
> > > > > > matching input by subtracting 1 for the next round. This work even
> > > > > > if
> > > > > > there is only one input and output.
> > > > > > 
> > > > > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > > > > ---
> > > > > > 
> > > > > >  drivers/gpu/drm/sun4i/sun4i_tcon.c | 22 ++++++++++++++++++----
> > > > > >  1 file changed, 18 insertions(+), 4 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c index
> > > > > > 08747fc3ee71..264bcc43da11
> > > > > > 100644
> > > > > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > @@ -791,12 +791,14 @@ static int sun4i_tcon_init_regmap(struct
> > > > > > device
> > > > > > *dev,
> > > > > > 
> > > > > >   */
> > > > > >  
> > > > > >  static struct sunxi_engine *
> > > > > >  sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv,
> > > > > > 
> > > > > > -                               struct device_node *node)
> > > > > > +                               struct device_node *node,
> > > > > > +                               u32 port_id)
> > > > > > 
> > > > > >  {
> > > > > >  
> > > > > >         struct device_node *port, *ep, *remote;
> > > > > >         struct sunxi_engine *engine = ERR_PTR(-EINVAL);
> > > > > > 
> > > > > > +       u32 reg = 0;
> > > > > > 
> > > > > > -       port = of_graph_get_port_by_id(node, 0);
> > > > > > +       port = of_graph_get_port_by_id(node, port_id);
> > > > > > 
> > > > > >         if (!port)
> > > > > >         
> > > > > >                 return ERR_PTR(-EINVAL);
> > > > > > 
> > > > > > @@ -826,8 +828,20 @@ sun4i_tcon_find_engine_traverse(struct
> > > > > > sun4i_drv
> > > > > > *drv,
> > > > > > 
> > > > > >                 if (remote == engine->node)
> > > > > >                 
> > > > > >                         goto out_put_remote;
> > > > > > 
> > > > > > +       /*
> > > > > > +        * According to device tree binding input ports have even id
> > > > > > +        * number and output ports have odd id. Since component with
> > > > > > +        * more than one input and one output (TCON TOP) exits,
> > > > > > correct
> > > > > > +        * remote input id has to be calculated by subtracting 1
> > > > > > from
> > > > > > +        * remote output id. If this for some reason can't be done,
> > > > > > 0
> > > > > > +        * is used as input port id.
> > > > > > +        */
> > > > > 
> > > > > You need to call
> > > > > 
> > > > >     of_node_put(port);
> > > > > 
> > > > > to drop the reference to the original port.
> > > > 
> > > > Thanks for noticing it. I guess I should send fix patch, since patches
> > > > from
> > > > drm-misc-next can't be dropped.
> > > 
> > > Yeah, please send additional patches for all the issues pointed out by
> > > Chen-Yu.
> > 
> > Of course. I hope this can be resolved till the end of the next week. After
> > that, I will be away from PC for 2 weeks. Feel free to drop DT patches if
> > you think that it will come too close to merge window.
> 
> Actually, can you drop it anyway? It needs a lot of changes and keeping HDMI 
> working would need some effort.

No, we can't drop it, unfortunately.

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

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

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

* Re: [linux-sunxi] Re: [PATCH v3 23/24] ARM: dts: sun8i: r40: Add HDMI pipeline
  2018-07-01 19:25                 ` Jernej Škrabec
@ 2018-07-02 21:39                   ` Jernej Škrabec
  0 siblings, 0 replies; 87+ messages in thread
From: Jernej Škrabec @ 2018-07-02 21:39 UTC (permalink / raw)
  To: linux-sunxi
  Cc: Chen-Yu Tsai, Maxime Ripard, Rob Herring, David Airlie,
	Gustavo Padovan, Maarten Lankhorst, Sean Paul, Mark Rutland,
	dri-devel, devicetree, linux-arm-kernel, linux-kernel, linux-clk

Dne nedelja, 01. julij 2018 ob 21:25:57 CEST je Jernej Škrabec napisal(a):
> Dne nedelja, 01. julij 2018 ob 17:35:28 CEST je Chen-Yu Tsai napisal(a):
> > On Sun, Jul 1, 2018 at 11:13 PM, Jernej Škrabec <jernej.skrabec@siol.net>
> 
> wrote:
> > > Dne nedelja, 01. julij 2018 ob 15:52:55 CEST je Chen-Yu Tsai napisal(a):
> > >> On Sun, Jul 1, 2018 at 6:41 PM, Jernej Škrabec
> > >> <jernej.skrabec@siol.net>
> > > 
> > > wrote:
> > >> > Dne četrtek, 28. junij 2018 ob 08:51:07 CEST je Chen-Yu Tsai
> 
> napisal(a):
> > >> >> On Thu, Jun 28, 2018 at 1:15 PM, Jernej Škrabec
> > >> >> <jernej.skrabec@siol.net>
> > >> > 
> > >> > wrote:
> > >> >> > Dne četrtek, 28. junij 2018 ob 04:50:09 CEST je Chen-Yu Tsai
> > > 
> > > napisal(a):
> > >> >> >> On Mon, Jun 25, 2018 at 8:03 PM, Jernej Skrabec
> > >> >> >> <jernej.skrabec@siol.net>
> > >> >> > 
> > >> >> > wrote:
> > >> >> >> > Add all entries needed for HDMI to function properly.
> > >> >> >> > 
> > >> >> >> > Since R40 has highly configurable pipeline, both mixers and
> > >> >> >> > both
> > >> >> >> > TCON
> > >> >> >> > TVs are added. Board specific DT should then connect them
> > >> >> >> > together
> > >> >> >> > trough TCON TOP muxers to best fit the purpose of the board.
> > >> >> >> > 
> > >> >> >> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > >> >> >> > ---
> > >> >> >> > 
> > >> >> >> >  arch/arm/boot/dts/sun8i-r40.dtsi | 269
> > >> >> >> >  +++++++++++++++++++++++++++++++
> > >> >> >> >  1 file changed, 269 insertions(+)
> > >> >> >> > 
> > >> >> >> > diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi
> > >> >> >> > b/arch/arm/boot/dts/sun8i-r40.dtsi index
> > >> >> >> > 173dcc1652d2..a2a75fb04caf
> > >> >> >> > 100644
> > >> >> >> > --- a/arch/arm/boot/dts/sun8i-r40.dtsi
> > >> >> >> > +++ b/arch/arm/boot/dts/sun8i-r40.dtsi
> > >> >> >> > @@ -42,8 +42,11 @@
> > >> >> >> > 
> > >> >> >> >   */
> > >> >> >> >  
> > >> >> >> >  #include <dt-bindings/interrupt-controller/arm-gic.h>
> > >> >> >> > 
> > >> >> >> > +#include <dt-bindings/clock/sun8i-de2.h>
> > >> >> >> > 
> > >> >> >> >  #include <dt-bindings/clock/sun8i-r40-ccu.h>
> > >> >> >> > 
> > >> >> >> > +#include <dt-bindings/clock/sun8i-tcon-top.h>
> > >> >> > 
> > >> >> > Maxime, above line breaks compilation for build robot, sorry.
> > >> >> > 
> > >> >> >> >  #include <dt-bindings/reset/sun8i-r40-ccu.h>
> > >> >> >> > 
> > >> >> >> > +#include <dt-bindings/reset/sun8i-de2.h>
> > >> >> >> > 
> > >> >> >> >  / {
> > >> >> >> >  
> > >> >> >> >         #address-cells = <1>;
> > >> >> >> > 
> > >> >> >> > @@ -99,12 +102,76 @@
> > >> >> >> > 
> > >> >> >> >                 };
> > >> >> >> >         
> > >> >> >> >         };
> > >> >> >> > 
> > >> >> >> > +       de: display-engine {
> > >> >> >> > +               compatible =
> > >> >> >> > "allwinner,sun8i-r40-display-engine",
> > >> >> >> > +                           
> > >> >> >> > "allwinner,sun8i-h3-display-engine";
> > >> >> >> 
> > >> >> >> Given that the display pipeline looks different, they should not
> > >> >> >> be
> > >> >> >> compatible.
> > >> >> > 
> > >> >> > Ok.
> > >> >> > 
> > >> >> >> > +               allwinner,pipelines = <&mixer0>, <&mixer1>;
> > >> >> >> > +               status = "disabled";
> > >> >> >> > +       };
> > >> >> >> > +
> > >> >> >> > 
> > >> >> >> >         soc {
> > >> >> >> >         
> > >> >> >> >                 compatible = "simple-bus";
> > >> >> >> >                 #address-cells = <1>;
> > >> >> >> >                 #size-cells = <1>;
> > >> >> >> >                 ranges;
> > >> >> >> > 
> > >> >> >> > +               display_clocks: clock@1000000 {
> > >> >> >> > +                       compatible =
> > >> >> >> > "allwinner,sun8i-r40-de2-clk",
> > >> >> >> > +
> > >> >> >> > "allwinner,sun8i-h3-de2-clk";
> > >> >> >> > +                       reg = <0x01000000 0x100000>;
> > >> >> >> > +                       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@1100000 {
> > >> >> >> > +                       compatible =
> > >> >> >> > "allwinner,sun8i-r40-de2-mixer-0";
> > >> >> >> > +                       reg = <0x01100000 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:
> > >> >> >> > endpoint {
> > >> >> >> > +                                               remote-endpoint
> > >> >> >> > =
> > >> >> >> > <&tcon_top_mixer0_in_mixer0>; +
> > >> >> >> > };
> > >> >> >> > +                               };
> > >> >> >> > +                       };
> > >> >> >> > +               };
> > >> >> >> > +
> > >> >> >> > +               mixer1: mixer@1200000 {
> > >> >> >> > +                       compatible =
> > >> >> >> > "allwinner,sun8i-r40-de2-mixer-1";
> > >> >> >> > +                       reg = <0x01200000 0x100000>;
> > >> >> >> > +                       clocks = <&display_clocks
> > >> >> >> > CLK_BUS_MIXER1>,
> > >> >> >> > +                                <&display_clocks CLK_MIXER1>;
> > >> >> >> > +                       clock-names = "bus",
> > >> >> >> > +                                     "mod";
> > >> >> >> > +                       resets = <&display_clocks RST_WB>;
> > >> >> >> > +
> > >> >> >> > +                       ports {
> > >> >> >> > +                               #address-cells = <1>;
> > >> >> >> > +                               #size-cells = <0>;
> > >> >> >> > +
> > >> >> >> > +                               mixer1_out: port@1 {
> > >> >> >> > +                                       reg = <1>;
> > >> >> >> > +                                       mixer1_out_tcon_top:
> > >> >> >> > endpoint {
> > >> >> >> > +                                               remote-endpoint
> > >> >> >> > =
> > >> >> >> > <&tcon_top_mixer1_in_mixer1>; +
> > >> >> >> > };
> > >> >> >> > +                               };
> > >> >> >> > +                       };
> > >> >> >> > +               };
> > >> >> >> > +
> > >> >> >> > 
> > >> >> >> >                 nmi_intc: interrupt-controller@1c00030 {
> > >> >> >> >                 
> > >> >> >> >                         compatible =
> > >> >> >> >                         "allwinner,sun7i-a20-sc-nmi";
> > >> >> >> >                         interrupt-controller;
> > >> >> >> > 
> > >> >> >> > @@ -451,6 +518,163 @@
> > >> >> >> > 
> > >> >> >> >                         #size-cells = <0>;
> > >> >> >> >                 
> > >> >> >> >                 };
> > >> >> >> > 
> > >> >> >> > +               tcon_top: tcon-top@1c70000 {
> > >> >> >> > +                       compatible =
> > >> >> >> > "allwinner,sun8i-r40-tcon-top";
> > >> >> >> > +                       reg = <0x01c70000 0x1000>;
> > >> >> >> > +                       clocks = <&ccu CLK_BUS_TCON_TOP>,
> > >> >> >> > +                                <&ccu CLK_TCON_TV0>,
> > >> >> >> > +                                <&ccu CLK_TVE0>,
> > >> >> >> > +                                <&ccu CLK_TCON_TV1>,
> > >> >> >> > +                                <&ccu CLK_TVE1>,
> > >> >> >> > +                                <&ccu CLK_DSI_DPHY>;
> > >> >> >> > +                       clock-names = "bus",
> > >> >> >> > +                                     "tcon-tv0",
> > >> >> >> > +                                     "tve0",
> > >> >> >> > +                                     "tcon-tv1",
> > >> >> >> > +                                     "tve1",
> > >> >> >> > +                                     "dsi";
> > >> >> >> > +                       clock-output-names = "tcon-top-tv0",
> > >> >> >> > +                                            "tcon-top-tv1",
> > >> >> >> > +                                            "tcon-top-dsi";
> > >> >> >> > +                       resets = <&ccu RST_BUS_TCON_TOP>;
> > >> >> >> > +                       #clock-cells = <1>;
> > >> >> >> > +
> > >> >> >> > +                       ports {
> > >> >> >> > +                               #address-cells = <1>;
> > >> >> >> > +                               #size-cells = <0>;
> > >> >> >> > +
> > >> >> >> > +                               tcon_top_mixer0_in: port@0 {
> > >> >> >> > +                                       reg = <0>;
> > >> >> >> > +
> > >> >> >> > +
> > >> >> >> > tcon_top_mixer0_in_mixer0:
> > >> >> >> > endpoint { +
> > >> >> >> > remote-endpoint = <&mixer0_out_tcon_top>; +
> > >> >> >> > 
> > >> >> >> >         };
> > >> >> >> > 
> > >> >> >> > +                               };
> > >> >> >> > +
> > >> >> >> > +                               tcon_top_mixer0_out: port@1 {
> > >> >> >> > +                                       #address-cells = <1>;
> > >> >> >> > +                                       #size-cells = <0>;
> > >> >> >> > +                                       reg = <1>;
> > >> >> >> > +
> > >> >> >> > +
> > >> >> >> > tcon_top_mixer0_out_tcon_lcd0:
> > >> >> >> > endpoint@0 { +                                              
> > >> >> >> > reg
> > >> >> >> > =
> > >> >> >> > <0>;
> > >> >> >> > +                                       };
> > >> >> >> > +
> > >> >> >> > +
> > >> >> >> > tcon_top_mixer0_out_tcon_lcd1:
> > >> >> >> > endpoint@1 { +                                              
> > >> >> >> > reg
> > >> >> >> > =
> > >> >> >> > <1>;
> > >> >> >> > +                                       };
> > >> >> >> > +
> > >> >> >> > +
> > >> >> >> > tcon_top_mixer0_out_tcon_tv0:
> > >> >> >> > endpoint@2 { +                                              
> > >> >> >> > reg
> > >> >> >> > =
> > >> >> >> > <2>;
> > >> >> >> > +                                       };
> > >> >> >> > +
> > >> >> >> > +
> > >> >> >> > tcon_top_mixer0_out_tcon_tv1:
> > >> >> >> > endpoint@3 { +                                              
> > >> >> >> > reg
> > >> >> >> > =
> > >> >> >> > <3>;
> > >> >> >> > +                                       };
> > >> >> >> > +                               };
> > >> >> >> > +
> > >> >> >> > +                               tcon_top_mixer1_in: port@2 {
> > >> >> >> > +                                       reg = <2>;
> > >> >> >> > +
> > >> >> >> > +
> > >> >> >> > tcon_top_mixer1_in_mixer1:
> > >> >> >> > endpoint { +
> > >> >> >> > remote-endpoint = <&mixer1_out_tcon_top>; +
> > >> >> >> > 
> > >> >> >> >         };
> > >> >> >> > 
> > >> >> >> > +                               };
> > >> >> >> > +
> > >> >> >> > +                               tcon_top_mixer1_out: port@3 {
> > >> >> >> > +                                       #address-cells = <1>;
> > >> >> >> > +                                       #size-cells = <0>;
> > >> >> >> > +                                       reg = <3>;
> > >> >> >> > +
> > >> >> >> > +
> > >> >> >> > tcon_top_mixer1_out_tcon_lcd0:
> > >> >> >> > endpoint@0 { +                                              
> > >> >> >> > reg
> > >> >> >> > =
> > >> >> >> > <0>;
> > >> >> >> > +                                       };
> > >> >> >> > +
> > >> >> >> > +
> > >> >> >> > tcon_top_mixer1_out_tcon_lcd1:
> > >> >> >> > endpoint@1 { +                                              
> > >> >> >> > reg
> > >> >> >> > =
> > >> >> >> > <1>;
> > >> >> >> > +                                       };
> > >> >> >> > +
> > >> >> >> > +
> > >> >> >> > tcon_top_mixer1_out_tcon_tv0:
> > >> >> >> > endpoint@2 { +                                              
> > >> >> >> > reg
> > >> >> >> > =
> > >> >> >> > <2>;
> > >> >> >> > +                                       };
> > >> >> >> > +
> > >> >> >> > +
> > >> >> >> > tcon_top_mixer1_out_tcon_tv1:
> > >> >> >> > endpoint@3 { +                                              
> > >> >> >> > reg
> > >> >> >> > =
> > >> >> >> > <3>;
> > >> >> >> > +                                       };
> > >> >> >> > +                               };
> > >> >> >> > +
> > >> >> >> > +                               tcon_top_hdmi_in: port@4 {
> > >> >> >> > +                                       #address-cells = <1>;
> > >> >> >> > +                                       #size-cells = <0>;
> > >> >> >> > +                                       reg = <4>;
> > >> >> >> > +
> > >> >> >> > +
> > >> >> >> > tcon_top_hdmi_in_tcon_tv0:
> > >> >> >> > endpoint@0 { +                                              
> > >> >> >> > reg
> > >> >> >> > =
> > >> >> >> > <0>;
> > >> >> >> > +                                       };
> > >> >> >> > +
> > >> >> >> > +
> > >> >> >> > tcon_top_hdmi_in_tcon_tv1:
> > >> >> >> > endpoint@1 { +                                              
> > >> >> >> > reg
> > >> >> >> > =
> > >> >> >> > <1>;
> > >> >> >> > +                                       };
> > >> >> >> > +                               };
> > >> >> >> > +
> > >> >> >> > +                               tcon_top_hdmi_out: port@5 {
> > >> >> >> > +                                       reg = <5>;
> > >> >> >> > +
> > >> >> >> > +                                       tcon_top_hdmi_out_hdmi:
> > >> >> >> > endpoint {
> > >> >> >> > +                                               remote-endpoint
> > >> >> >> > =
> > >> >> >> > <&hdmi_in_tcon_top>; +                                       };
> > >> >> >> > +                               };
> > >> >> >> > +                       };
> > >> >> >> > +               };
> > >> >> >> > +
> > >> >> >> > +               tcon_tv0: lcd-controller@1c73000 {
> > >> >> >> > +                       compatible =
> > >> >> >> > "allwinner,sun8i-r40-tcon-tv",
> > >> >> >> > +
> > >> >> >> > "allwinner,sun8i-a83t-tcon-tv";
> > >> >> >> > +                       reg = <0x01c73000 0x1000>;
> > >> >> >> > +                       interrupts = <GIC_SPI 51
> > >> >> >> > IRQ_TYPE_LEVEL_HIGH>;
> > >> >> >> > +                       clocks = <&ccu CLK_BUS_TCON_TV0>,
> > >> >> >> > <&tcon_top
> > >> >> >> > 0>;
> > >> >> >> > +                       clock-names = "ahb", "tcon-ch1";
> > >> >> >> > +                       resets = <&ccu RST_BUS_TCON_TV0>;
> > >> >> >> > +                       reset-names = "lcd";
> > >> >> >> > +
> > >> >> >> > +                       ports {
> > >> >> >> > +                               #address-cells = <1>;
> > >> >> >> > +                               #size-cells = <0>;
> > >> >> >> > +
> > >> >> >> > +                               tcon_tv0_in: port@0 {
> > >> >> >> > +                                       reg = <0>;
> > >> >> >> > +                               };
> > >> >> >> > +
> > >> >> >> > +                               tcon_tv0_out: port@1 {
> > >> >> >> > +                                       reg = <1>;
> > >> >> >> > +                               };
> > >> >> >> > +                       };
> > >> >> >> > +               };
> > >> >> >> > +
> > >> >> >> > +               tcon_tv1: lcd-controller@1c74000 {
> > >> >> >> > +                       compatible =
> > >> >> >> > "allwinner,sun8i-r40-tcon-tv",
> > >> >> >> > +
> > >> >> >> > "allwinner,sun8i-a83t-tcon-tv";
> > >> >> >> > +                       reg = <0x01c74000 0x1000>;
> > >> >> >> > +                       interrupts = <GIC_SPI 52
> > >> >> >> > IRQ_TYPE_LEVEL_HIGH>;
> > >> >> >> > +                       clocks = <&ccu CLK_BUS_TCON_TV1>,
> > >> >> >> > <&tcon_top
> > >> >> >> > 1>;
> > >> >> >> > +                       clock-names = "ahb", "tcon-ch1";
> > >> >> >> > +                       resets = <&ccu RST_BUS_TCON_TV1>;
> > >> >> >> > +                       reset-names = "lcd";
> > >> >> >> > +
> > >> >> >> > +                       ports {
> > >> >> >> > +                               #address-cells = <1>;
> > >> >> >> > +                               #size-cells = <0>;
> > >> >> >> > +
> > >> >> >> > +                               tcon_tv1_in: port@0 {
> > >> >> >> > +                                       reg = <0>;
> > >> >> >> > +                               };
> > >> >> >> > +
> > >> >> >> > +                               tcon_tv1_out: port@1 {
> > >> >> >> > +                                       reg = <1>;
> > >> >> >> 
> > >> >> >> You are missing the remote-endpoints for all the TCON-TOP <->
> > >> >> >> TCON
> > >> >> >> connections. Also, on the driver side, there's no code to handle
> > >> >> >> dynamically mapping mixers to the TCONs that are being used. In
> > >> >> >> the
> > >> >> >> past
> > >> >> >> we
> > >> >> >> had simple 1:1 mappings. This is no longer the case, and it needs
> > >> >> >> to
> > >> >> >> be
> > >> >> >> dealt with.
> > >> >> > 
> > >> >> > How would TCON TOP driver know how to set muxes? There are no
> > >> >> > appropriate
> > >> >> > bingings for muxes, except for V4L2 subsystem, which doesn't
> > >> >> > really
> > >> >> > work
> > >> >> > here.
> > >> >> 
> > >> >> This will end up being a bunch of custom functions exported from the
> > >> >> TCON
> > >> >> TOP driver to the TCON driver. As for bindings, the stuff you
> > >> >> already
> > >> >> have
> > >> >> is mostly enough. You do have to specify the endpoint ID vs
> > >> >> component
> > >> >> mapping, so you can find the correct one.
> > >> >> 
> > >> >> For example, you would specify that the IDs for TCON LCDs be 0 and
> > >> >> 1,
> > >> >> and
> > >> >> TCON TVs be 2 and 3. Matching the actual register values is a nice
> > >> >> convenience. These would be used by the driver as the TCON ID.
> > >> > 
> > >> > So something that's already done (minus full connections).
> > >> > 
> > >> >> Also, we might want to consider them as two pairs of two TCONs (LCD
> > >> >> +
> > >> >> TV).
> > >> >> The CRTC in DRM land is actually the mixer + TCON on our platform.
> > >> >> This
> > >> >> means we only have two CRTCs. So we could have CRTC 0 = mixer 0 +
> > >> >> TCON
> > >> >> LCD
> > >> >> 0 + TCON TV 0. The "TCON_TVx_OUTSEL" and "DE_PORTx PERH Select"
> > >> >> muxes
> > >> >> would
> > >> >> be set at run time in the mode set function, selecting either LCD or
> > >> >> TV
> > >> >> based on what encoder is attached.

Any suggestion how to expand sun4i_tcon_find_engine() to match TCON with 
mixer? Now we have mixer 0 and 1, with TCONs 2 and 3. This means that simple 
id matching like this:

https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/sun4i/
sun4i_tcon.c#L865

doesn't work anymore. As we discussed already, this is also a bit SoC 
specific. Should I add new quirk, which would match mixer id with TCON id with 
the SoC specific helper?

This has to be done at probe time, which means it can't be done in mux 
callback as though earlier.

> > >> > 
> > >> > That proposal would still limit some combinations. For example, that
> > >> > would
> > >> > put DSI always on mixer1, since it can be connected to only LCD TCON
> > >> > 1.
> > >> > It can also cause undesired combination in laptop solutions. Consider
> > >> > that PCB designer connected LCD1 pins to panel for some reason. Panel
> > >> > is
> > >> > definetly main screen and should definetly be connected to mixer0,
> > >> > but
> > >> > in
> > >> > that case, it would be to mixer1.
> > >> 
> > >> There's no reason we can't have dynamically assigned mixer+tcon pairs,
> > >> but
> > >> that would mean implementing additional scheduling code that we don't
> > >> have
> > >> yet. The current sunxi-drm and CRTC code assume static mappings.
> > > 
> > > I just remembered that your proposed solution while should work on R40,
> > > doesn't really fit in H6 case (which is the main reason for this
> > > series).
> > > 
> > > There are only LCD TCON 0 and TV TCON 0. Their HW IDs are the same as on
> > > R40 (1 and 3). Additionaly, there is also HDMI mux as on R40, although
> > > there is only one TV TCON, which can be used only for HDMI (TV output is
> > > connected to LCD TCON through AC200 bridge, put on same die or glued in
> > > same package, not really sure and doesn't really matter).
> > 
> > OK. So even there's only one TV TCON, you still have to program all muxes
> > with the correct value, to prevent a) a bad value left by the bootloader
> > and b) bad reset default values.
> > 
> > > I would like to write something which is also going to work for H6 out
> > > of
> > > the box. For H6, following combination would work well:
> > > mixer0 = LCD TCON 1 + TV TCON 0
> > > mixer1 = LCD TCON 0 + TV TCON 1
> > > 
> > > Or alternatively, we can leave that to mux callback in TCON which would
> > > take care for best variant for given SoC.
> > 
> > I think that is the ultimate goal. However, the muxing would be a bit
> > complicated. For all the past SoCs, we were dealing with muxing the
> > downstream encoder. Now we will be muxing mixer and tcon connections
> > as well. You would also have to dynamically switch around the mixer
> > and/or tcon pointers in sun4i_crtc so existing code can still work.
> > 
> > > Once we concur on that, I'll try to implement something.
> > > 
> > >> We could do this as a second step if you're up to it.
> > > 
> > > For my ultimate goal, which is 1st class Kodi experience on mainline,
> > > current proposal works in any case (mixer1 is enough). I just don't like
> > > solutions which are not universal.
> > > 
> > >> > Additionaly, since HDMI would became floating between TV TCON 0 and
> > >> > 1,
> > >> > whoever would write board DT would need to know this and enable only
> > >> > TV
> > >> > TCON1 if LCD is desired to be connected to mixer0 (or vice versa).
> > >> 
> > >> There's no reason not to have all TCONs enabled by default. We would
> > >> consider the display-engine node controlling whether everything
> > >> actually
> > >> gets used.
> > >> 
> > >> > If we really want universal solution with full connections, addtional
> > >> > property has to be defined and used for that.
> > >> > 
> > >> >> This limitation is a software one, and should not bleed over into
> > >> >> the
> > >> >> hardware representation.
> > >> >> 
> > >> >> > Additionaly, how would HDMI know which TCON belongs to it to
> > >> >> > appropriately
> > >> >> > set possible_crtcs?
> > >> >> 
> > >> >> HDMI is connected to the two TCON TVs through the TCON TOP mux. We
> > >> >> handle
> > >> >> TCON output muxing in the TCON driver, using the set_mux callback in
> > >> >> the
> > >> >> quirks. For R40, this callback would probably call into the TCON TOP
> > >> >> driver
> > >> >> asking it to set the mux to some value.
> > >> >> 
> > >> >> > Currently, my idea is that board DT creates wanted connections.
> > >> >> > Since
> > >> >> > there is only one valid connection for each mux, driver knows
> > >> >> > eactly
> > >> >> > what
> > >> >> > to write into mux register. HDMI driver can simply check which
> > >> >> > TCON
> > >> >> > connection is valid in HDMI input mux and select it in
> > >> >> > possible_crtcs.
> > >> >> 
> > >> >> But that is not how the actual hardware looks like. The device tree
> > >> >> should
> > >> >> model the hardware, not a subset of it just because one thinks the
> > >> >> implementation is difficult or won't be used at all.
> > >> >> 
> > >> >> Furthermore, I think you have it backwards. possible_crtcs is
> > >> >> generated
> > >> >> based on (in our case) the connections between TCON and HDMI based
> > >> >> on
> > >> >> the
> > >> >> device tree graph. So if you have both hooked up, both will show up
> > >> >> in
> > >> >> possible_crtcs, but only one crtc will actually be selected to feed
> > >> >> the
> > >> >> HDMI encoder. If you really need to access the current crtc, the
> > >> >> drm_encoder struct contains a pointer to it.
> > >> >> 
> > >> >> In DE 1.0 driver, we leave all the muxing to the TCON driver. See
> > >> >> 
> > >> >> 
> > >> >> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/sun4i
> > >> >> /s
> > >> >> un4
> > >> >> i_
> > >> >> tcon.c#L537
> > >> >> 
> > >> >> So in a sense, the HDMI encoder should be and is hooked up to both
> > >> >> TCONs,
> > >> >> but only one is active at any given time.
> > >> > 
> > >> > So something like that I had in v1 series. I'll implement something
> > >> > similar. That would also mean we need R40 specific TV TCON
> > >> > compatible.
> > >> > I'll restore that.
> > >> > 
> > >> > Just a question on future situation when TVE driver will be
> > >> > implemented.
> > >> > Suppose that R40 board has TVE0 and HDMI as outputs. This would mean
> > >> > that
> > >> > TVE0 has possible crtcs set as 0b01 and HDMI 0b11. Will be DRM
> > >> > framework
> > >> > smart enough that it will put HDMI on second crtc because TVE0 can be
> > >> > connected to only to first crtc?
> > >> 
> > >> Yes. If the possible_clones setting for the encoder is not set, the DRM
> > >> framework will not do mirroring, and will keep each active encoder on a
> > >> separate crtc.
> > >> 
> > >> >> > Please also note that mixer0 and mixer1 don't have same
> > >> >> > capabilities
> > >> >> > and
> > >> >> > you generally want mixer0 to be connected to main output. This is
> > >> >> > in
> > >> >> > contrast to DE1 SoCs, where both backends and both frontends have
> > >> >> > same
> > >> >> > capability.
> > >> >> 
> > >> >> Yes. But who's to say the two display outputs can't be reversed or
> > >> >> swapped
> > >> >> around? With fixed singular connections, you also rule out mirrored
> > >> >> output.
> > >> > 
> > >> > I don't think there is standard way to swap around mixers at runtime,
> > >> > expecially if crtcs are represented as mixer + TCON pair.
> > >> 
> > >> As I mentioned above, we will have to do this on our own.
> > >> 
> > >> > I'm not sure what do you mean with mirrored output or at least why
> > >> > singular
> > >> > connections would prevent mirroring. HW mirroring needs DRM writeback
> > >> > support which is currently in RFC phase if I'm not mistaken. Once
> > >> > implemented in DRM framework and in sun4i-drm, it would be possible
> > >> > only
> > >> > to mirror mixer0 -> mixer1, because mixer1 doesn't support writeback
> > >> > (at
> > >> > least on existing SoCs).
> > >> 
> > >> What I meant was it might be possible to drive two TCONs with one
> > >> mixer,
> > >> or
> > >> two encoders with one TCON. I guess the latter is not possible since
> > >> each
> > >> TCON only has one channel. Not sure about the former.
> > > 
> > > I think neither of this two variants are possible, because outputs would
> > > have to have exactly the same resolution and in second case even the
> > > same
> > > pixel clock, which is very unlikely.
> > 
> > That is what mirroring is supposed to mean, right? For instance you could
> > have VGA on one and HDMI on the other, at the same resolution and
> > dotclock.
> 
> Actually, R40 is the first SoC with DE2 where is theoretically possible to
> connect one mixer to multiple TCONs. I didn't try it yet because BPI M2U has
> apart from HDMI only DSI connector and TV out on test points and neither
> have support in mainline.

Sorry, I spoke too soon. Actually it's not possible to do that even on R40. So 
both variants are not possible with current DE2/DE3 SoCs, unless there is 
something undocumented. 
 
Best regards,
Jernej
> 
> > As far as I'm concerned, the software doesn't need to have all features
> > covered. But that doesn't mean the hardware representation can lack
> > features as well. We already did that once, and now we have some legacy
> > graph parsing code to handle that.
> > 
> > Regards
> > ChenYu





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

* Re: [linux-sunxi] Re: [PATCH v3 15/24] dt-bindings: display: sun4i-drm: Add description of A64 HDMI PHY
  2018-06-29 19:32         ` Jernej Škrabec
@ 2018-07-04  4:05           ` Chen-Yu Tsai
  0 siblings, 0 replies; 87+ messages in thread
From: Chen-Yu Tsai @ 2018-07-04  4:05 UTC (permalink / raw)
  To: Jernej Skrabec
  Cc: Maxime Ripard, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

On Sat, Jun 30, 2018 at 3:32 AM, Jernej Škrabec <jernej.skrabec@siol.net> wrote:
> Dne četrtek, 28. junij 2018 ob 09:00:32 CEST je Chen-Yu Tsai napisal(a):
>> On Thu, Jun 28, 2018 at 12:51 PM, Jernej Škrabec
>>
>> <jernej.skrabec@siol.net> wrote:
>> > Dne četrtek, 28. junij 2018 ob 04:19:55 CEST je Chen-Yu Tsai napisal(a):
>> >> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net>
>> >
>> > wrote:
>> >> > A64 HDMI PHY is similar to H3 HDMI PHY except it has two possible PLL
>> >> > clock parents. It is compatible to other HDMI PHYs, like that found in
>> >> > R40.
>> >> >
>> >> > Acked-by: Rob Herring <robh@kernel.org>
>> >> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>> >> > ---
>> >> >
>> >> >  Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 4 +++-
>> >> >  1 file changed, 3 insertions(+), 1 deletion(-)
>> >> >
>> >> > diff --git
>> >> > a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
>> >> > b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt index
>> >> > 84fe38dbb900..dc83f21ef188 100644
>> >> > --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
>> >> > +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
>> >> > @@ -101,6 +101,7 @@ DWC HDMI PHY
>> >> >
>> >> >  Required properties:
>> >> >    - compatible: value must be one of:
>> >> > +    * allwinner,sun50i-a64-hdmi-phy
>> >> >
>> >> >      * allwinner,sun8i-a83t-hdmi-phy
>> >> >      * allwinner,sun8i-h3-hdmi-phy
>> >>
>> >> Nit: the list is sorted by family first, then SoC name, so it should
>> >> be the last on the list.
>> >
>> > I went alphabetically, since "5" is before "8"...
>>
>> I see. I think version sort applies here, given that sun50i is newer
>> than sun8i.
>
> Should I make a patch for that?

Yes, please.

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

* Re: [linux-sunxi] Re: [PATCH v3 09/24] drm/sun4i: Don't skip TCONs if they don't have channel 0
  2018-07-01 15:11           ` Chen-Yu Tsai
@ 2018-07-05  7:03             ` Maxime Ripard
  2018-07-05 20:03               ` Jernej Škrabec
  0 siblings, 1 reply; 87+ messages in thread
From: Maxime Ripard @ 2018-07-05  7:03 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Jernej Škrabec, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

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

On Sun, Jul 01, 2018 at 11:11:06PM +0800, Chen-Yu Tsai wrote:
> On Sun, Jul 1, 2018 at 4:27 PM, Jernej Škrabec <jernej.skrabec@siol.net> wrote:
> > Dne četrtek, 28. junij 2018 ob 08:24:34 CEST je Chen-Yu Tsai napisal(a):
> >> On Thu, Jun 28, 2018 at 12:45 PM, Jernej Škrabec
> >>
> >> <jernej.skrabec@siol.net> wrote:
> >> > Dne četrtek, 28. junij 2018 ob 03:51:31 CEST je Chen-Yu Tsai napisal(a):
> >> >> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec <jernej.skrabec@siol.net>
> >> >
> >> > wrote:
> >> >> > TV TCONs (channel 1 only) are always connected to TV or HDMI encoder.
> >> >> > Because of that, all output endpoints on such TCON node will point to a
> >> >> > encoder which is part of component framework.
> >> >> >
> >> >> > Correct current graph traversing algorithm in such way that it doesn't
> >> >> > skip output enpoints with id 0 on TV TCONs.
> >> >>
> >> >> No. Our bindings say that endpoint 0 _is_ channel 0. For TCONs that don't
> >> >> have channel 0, it must be skipped.
> >> >
> >> > I'm not sure where this is stated. I read TCON binding again. Can you
> >> > please point me to it?
> >>
> >> https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bind
> >> ings/display/sunxi/sun4i-drm.txt#L169
> >>
> >> Our TCON driver still expects RGB or LVDS panel / bridges on endpoint 0.
> >
> > Yes, but that can only happen on TCON which has channel 0. TV TCONs (those
> > with channel 1 only) can't have panels or bridges connected to them, because
> > they are internally always connected to either HDMI or TV encoder or both.
> > Actually, R40 is the only SoC, where same TV TCON can be connected to TV
> > encoder or HDMI. Others have specialized TV TCONs, which are connect to only
> > one encoder.
> >
> > IMO TV TCONs are really just stripped down LCD TCONs to support one (or max
> > two) specific encoder.
> 
> I agree. We've seen these first in the H3, and the reverse, TCONs only with
> LCD, on the A23/A33.
> 
> >> So I guess this was sort of implied historically. It's no longer true.
> >> This is something we should probably fix.
> >
> > Fixed in what way? You mean update bindings to mention that TCON output
> > endpoint 0 is reserved for panels or bridges?
> 
> Either that, or have the drm driver look at other endpoints. I guess we
> should ask Maxime if this is already done or not, since the DSI driver
> isn't endpoint 0 in the A33 dtsi.

The DSI driver isn't really a good example for this, since the panel
isn't described as part of the OF graph, but DSI binding require that
it's a child of the DSI controller node.

> >>
> >> In practice our drivers don't look at it (yet), but rely on the downstream
> >> encoder type to determine which channel to use.
> >>
> >> But please add the "allwinner,tcon-channel" property as specified in
> >> the binding.
> >
> > It's my understanding of TCON binding documentation that property
> > "allwinner,tcon-channel" is needed only if TCON supports both channels. TV
> > TCON clearly supports only channel 1. In that case, there is no doubt to which
> > channel output endpoint belongs.
> >
> > If that's not true, dt bindings documentation should be reworded to contain
> > word "needed" or something similar. Currently, no DT for newer SoC contains
> > that property (for example, A83T, H3, H5 or even A33).

Yeah, but that's mainly because we have a single output enabled for
each channel on those newer SoCs. When / if we enable the RGB and LVDS
output for example, we will have to set this.

> > On A33 this is even more interesting, since tcon0 has only channel
> > 0 and has DSI output endpoint with number 1. According to TCON
> > binding docs, if "allwinner,tcon-channel" is not preset, endpoint
> > number represent channel. So, that would mean DSI needs channel 1
> > on tcon which supports clearly only channel 0. So either there
> > TCON bindings documentation needs updates or DT for A33 has to be
> > updated.
> 
> Maxime? You did the A33 DSI stuff.

I guess it's missing on the A33 DSI endpoint.

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

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

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

* Re: [linux-sunxi] Re: [PATCH v3 09/24] drm/sun4i: Don't skip TCONs if they don't have channel 0
  2018-07-05  7:03             ` Maxime Ripard
@ 2018-07-05 20:03               ` Jernej Škrabec
  2018-07-09  8:59                 ` Maxime Ripard
  0 siblings, 1 reply; 87+ messages in thread
From: Jernej Škrabec @ 2018-07-05 20:03 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

Dne četrtek, 05. julij 2018 ob 09:03:58 CEST je Maxime Ripard napisal(a):
> On Sun, Jul 01, 2018 at 11:11:06PM +0800, Chen-Yu Tsai wrote:
> > On Sun, Jul 1, 2018 at 4:27 PM, Jernej Škrabec <jernej.skrabec@siol.net> 
wrote:
> > > Dne četrtek, 28. junij 2018 ob 08:24:34 CEST je Chen-Yu Tsai napisal(a):
> > >> On Thu, Jun 28, 2018 at 12:45 PM, Jernej Škrabec
> > >> 
> > >> <jernej.skrabec@siol.net> wrote:
> > >> > Dne četrtek, 28. junij 2018 ob 03:51:31 CEST je Chen-Yu Tsai 
napisal(a):
> > >> >> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec
> > >> >> <jernej.skrabec@siol.net>
> > >> > 
> > >> > wrote:
> > >> >> > TV TCONs (channel 1 only) are always connected to TV or HDMI
> > >> >> > encoder.
> > >> >> > Because of that, all output endpoints on such TCON node will point
> > >> >> > to a
> > >> >> > encoder which is part of component framework.
> > >> >> > 
> > >> >> > Correct current graph traversing algorithm in such way that it
> > >> >> > doesn't
> > >> >> > skip output enpoints with id 0 on TV TCONs.
> > >> >> 
> > >> >> No. Our bindings say that endpoint 0 _is_ channel 0. For TCONs that
> > >> >> don't
> > >> >> have channel 0, it must be skipped.
> > >> > 
> > >> > I'm not sure where this is stated. I read TCON binding again. Can you
> > >> > please point me to it?
> > >> 
> > >> https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree
> > >> /bind ings/display/sunxi/sun4i-drm.txt#L169
> > >> 
> > >> Our TCON driver still expects RGB or LVDS panel / bridges on endpoint
> > >> 0.
> > > 
> > > Yes, but that can only happen on TCON which has channel 0. TV TCONs
> > > (those
> > > with channel 1 only) can't have panels or bridges connected to them,
> > > because they are internally always connected to either HDMI or TV
> > > encoder or both. Actually, R40 is the only SoC, where same TV TCON can
> > > be connected to TV encoder or HDMI. Others have specialized TV TCONs,
> > > which are connect to only one encoder.
> > > 
> > > IMO TV TCONs are really just stripped down LCD TCONs to support one (or
> > > max
> > > two) specific encoder.
> > 
> > I agree. We've seen these first in the H3, and the reverse, TCONs only
> > with
> > LCD, on the A23/A33.
> > 
> > >> So I guess this was sort of implied historically. It's no longer true.
> > >> This is something we should probably fix.
> > > 
> > > Fixed in what way? You mean update bindings to mention that TCON output
> > > endpoint 0 is reserved for panels or bridges?
> > 
> > Either that, or have the drm driver look at other endpoints. I guess we
> > should ask Maxime if this is already done or not, since the DSI driver
> > isn't endpoint 0 in the A33 dtsi.
> 
> The DSI driver isn't really a good example for this, since the panel
> isn't described as part of the OF graph, but DSI binding require that
> it's a child of the DSI controller node.

So should be new behaviour reverted? I mean ignoring endpoint 0 on TV TCONs.

For me, it doesn't make sense to check for panel or bridges on TV TCONs, 
because they are never exposed on physical pins. They are always connected to 
TVE or HDMI encoder internally.

> 
> > >> In practice our drivers don't look at it (yet), but rely on the
> > >> downstream
> > >> encoder type to determine which channel to use.
> > >> 
> > >> But please add the "allwinner,tcon-channel" property as specified in
> > >> the binding.
> > > 
> > > It's my understanding of TCON binding documentation that property
> > > "allwinner,tcon-channel" is needed only if TCON supports both channels.
> > > TV
> > > TCON clearly supports only channel 1. In that case, there is no doubt to
> > > which channel output endpoint belongs.
> > > 
> > > If that's not true, dt bindings documentation should be reworded to
> > > contain
> > > word "needed" or something similar. Currently, no DT for newer SoC
> > > contains
> > > that property (for example, A83T, H3, H5 or even A33).
> 
> Yeah, but that's mainly because we have a single output enabled for
> each channel on those newer SoCs. When / if we enable the RGB and LVDS
> output for example, we will have to set this.

So just to be clear, before I send follow up series, I have to add 
"allwinner,tcon-channel" property to DT, because both TV TCONs can be 
connected to either TVE or HDMI (trough TCON TOP)?

BTW, since this property is not used at all in the code, why not just simply 
deprecate it and remove it from existing DTs? I noticed this is standard 
practice for obsolete properties.

Best regards,
Jernej

> 
> > > On A33 this is even more interesting, since tcon0 has only channel
> > > 0 and has DSI output endpoint with number 1. According to TCON
> > > binding docs, if "allwinner,tcon-channel" is not preset, endpoint
> > > number represent channel. So, that would mean DSI needs channel 1
> > > on tcon which supports clearly only channel 0. So either there
> > > TCON bindings documentation needs updates or DT for A33 has to be
> > > updated.
> > 
> > Maxime? You did the A33 DSI stuff.
> 
> I guess it's missing on the A33 DSI endpoint.
> 
> Maxime




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

* Re: [linux-sunxi] Re: [PATCH v3 09/24] drm/sun4i: Don't skip TCONs if they don't have channel 0
  2018-07-05 20:03               ` Jernej Škrabec
@ 2018-07-09  8:59                 ` Maxime Ripard
  0 siblings, 0 replies; 87+ messages in thread
From: Maxime Ripard @ 2018-07-09  8:59 UTC (permalink / raw)
  To: Jernej Škrabec
  Cc: Chen-Yu Tsai, Rob Herring, David Airlie, Gustavo Padovan,
	Maarten Lankhorst, Sean Paul, Mark Rutland, dri-devel,
	devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	linux-sunxi

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

On Thu, Jul 05, 2018 at 10:03:35PM +0200, Jernej Škrabec wrote:
> Dne četrtek, 05. julij 2018 ob 09:03:58 CEST je Maxime Ripard napisal(a):
> > On Sun, Jul 01, 2018 at 11:11:06PM +0800, Chen-Yu Tsai wrote:
> > > On Sun, Jul 1, 2018 at 4:27 PM, Jernej Škrabec <jernej.skrabec@siol.net> 
> wrote:
> > > > Dne četrtek, 28. junij 2018 ob 08:24:34 CEST je Chen-Yu Tsai napisal(a):
> > > >> On Thu, Jun 28, 2018 at 12:45 PM, Jernej Škrabec
> > > >> 
> > > >> <jernej.skrabec@siol.net> wrote:
> > > >> > Dne četrtek, 28. junij 2018 ob 03:51:31 CEST je Chen-Yu Tsai 
> napisal(a):
> > > >> >> On Mon, Jun 25, 2018 at 8:02 PM, Jernej Skrabec
> > > >> >> <jernej.skrabec@siol.net>
> > > >> > 
> > > >> > wrote:
> > > >> >> > TV TCONs (channel 1 only) are always connected to TV or HDMI
> > > >> >> > encoder.
> > > >> >> > Because of that, all output endpoints on such TCON node will point
> > > >> >> > to a
> > > >> >> > encoder which is part of component framework.
> > > >> >> > 
> > > >> >> > Correct current graph traversing algorithm in such way that it
> > > >> >> > doesn't
> > > >> >> > skip output enpoints with id 0 on TV TCONs.
> > > >> >> 
> > > >> >> No. Our bindings say that endpoint 0 _is_ channel 0. For TCONs that
> > > >> >> don't
> > > >> >> have channel 0, it must be skipped.
> > > >> > 
> > > >> > I'm not sure where this is stated. I read TCON binding again. Can you
> > > >> > please point me to it?
> > > >> 
> > > >> https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree
> > > >> /bind ings/display/sunxi/sun4i-drm.txt#L169
> > > >> 
> > > >> Our TCON driver still expects RGB or LVDS panel / bridges on endpoint
> > > >> 0.
> > > > 
> > > > Yes, but that can only happen on TCON which has channel 0. TV TCONs
> > > > (those
> > > > with channel 1 only) can't have panels or bridges connected to them,
> > > > because they are internally always connected to either HDMI or TV
> > > > encoder or both. Actually, R40 is the only SoC, where same TV TCON can
> > > > be connected to TV encoder or HDMI. Others have specialized TV TCONs,
> > > > which are connect to only one encoder.
> > > > 
> > > > IMO TV TCONs are really just stripped down LCD TCONs to support one (or
> > > > max
> > > > two) specific encoder.
> > > 
> > > I agree. We've seen these first in the H3, and the reverse, TCONs only
> > > with
> > > LCD, on the A23/A33.
> > > 
> > > >> So I guess this was sort of implied historically. It's no longer true.
> > > >> This is something we should probably fix.
> > > > 
> > > > Fixed in what way? You mean update bindings to mention that TCON output
> > > > endpoint 0 is reserved for panels or bridges?
> > > 
> > > Either that, or have the drm driver look at other endpoints. I guess we
> > > should ask Maxime if this is already done or not, since the DSI driver
> > > isn't endpoint 0 in the A33 dtsi.
> > 
> > The DSI driver isn't really a good example for this, since the panel
> > isn't described as part of the OF graph, but DSI binding require that
> > it's a child of the DSI controller node.
> 
> So should be new behaviour reverted? I mean ignoring endpoint 0 on TV TCONs.
> 
> For me, it doesn't make sense to check for panel or bridges on TV TCONs, 
> because they are never exposed on physical pins. They are always connected to 
> TVE or HDMI encoder internally.

It doesn't make sense to check for panels, yes, but it also makes sens
to have a child node at the endpoint 0 for TV TCONs.

> > > >> In practice our drivers don't look at it (yet), but rely on the
> > > >> downstream
> > > >> encoder type to determine which channel to use.
> > > >> 
> > > >> But please add the "allwinner,tcon-channel" property as specified in
> > > >> the binding.
> > > > 
> > > > It's my understanding of TCON binding documentation that property
> > > > "allwinner,tcon-channel" is needed only if TCON supports both channels.
> > > > TV
> > > > TCON clearly supports only channel 1. In that case, there is no doubt to
> > > > which channel output endpoint belongs.
> > > > 
> > > > If that's not true, dt bindings documentation should be reworded to
> > > > contain
> > > > word "needed" or something similar. Currently, no DT for newer SoC
> > > > contains
> > > > that property (for example, A83T, H3, H5 or even A33).
> > 
> > Yeah, but that's mainly because we have a single output enabled for
> > each channel on those newer SoCs. When / if we enable the RGB and LVDS
> > output for example, we will have to set this.
> 
> So just to be clear, before I send follow up series, I have to add 
> "allwinner,tcon-channel" property to DT, because both TV TCONs can be 
> connected to either TVE or HDMI (trough TCON TOP)?
> 
> BTW, since this property is not used at all in the code, why not just simply 
> deprecate it and remove it from existing DTs? I noticed this is standard 
> practice for obsolete properties.

It's not deprecated or obsolete, it's future-proofing.

Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

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

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

end of thread, other threads:[~2018-07-09  8:59 UTC | newest]

Thread overview: 87+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
2018-06-25 12:02 ` [PATCH v3 01/24] clk: sunxi-ng: r40: Add minimal rate for video PLLs Jernej Skrabec
2018-06-25 12:02 ` [PATCH v3 02/24] clk: sunxi-ng: r40: Allow setting parent rate to display related clocks Jernej Skrabec
2018-06-25 12:02 ` [PATCH v3 03/24] clk: sunxi-ng: r40: Export video PLLs Jernej Skrabec
2018-06-25 12:30   ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 04/24] dt-bindings: display: sunxi-drm: Add TCON TOP description Jernej Skrabec
2018-06-25 17:33   ` Rob Herring
2018-06-25 12:02 ` [PATCH v3 05/24] drm/sun4i: Add TCON TOP driver Jernej Skrabec
2018-06-28  1:47   ` Chen-Yu Tsai
2018-06-29 19:09     ` Jernej Škrabec
2018-06-30  1:13       ` [linux-sunxi] " Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 06/24] drm/sun4i: Fix releasing node when enumerating enpoints Jernej Skrabec
2018-06-28  1:53   ` [linux-sunxi] " Chen-Yu Tsai
2018-06-29 19:15     ` Jernej Škrabec
2018-06-30  1:09       ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 07/24] drm/sun4i: Split out code for enumerating endpoints in output port Jernej Skrabec
2018-06-28  1:57   ` [linux-sunxi] " Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 08/24] drm/sun4i: Add support for traversing graph with TCON TOP Jernej Skrabec
2018-06-28  1:57   ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 09/24] drm/sun4i: Don't skip TCONs if they don't have channel 0 Jernej Skrabec
2018-06-28  1:51   ` Chen-Yu Tsai
2018-06-28  4:45     ` Jernej Škrabec
2018-06-28  6:24       ` [linux-sunxi] " Chen-Yu Tsai
2018-07-01  8:27         ` Jernej Škrabec
2018-07-01 15:11           ` Chen-Yu Tsai
2018-07-05  7:03             ` Maxime Ripard
2018-07-05 20:03               ` Jernej Škrabec
2018-07-09  8:59                 ` Maxime Ripard
2018-06-25 12:02 ` [PATCH v3 10/24] drm/sun4i: tcon: Generalize engine search algorithm Jernej Skrabec
2018-06-28  2:06   ` Chen-Yu Tsai
2018-06-28  4:48     ` Jernej Škrabec
2018-06-28 18:25       ` Maxime Ripard
2018-06-29 19:06         ` Jernej Škrabec
2018-07-01 19:09           ` [linux-sunxi] " Jernej Škrabec
2018-07-02  8:56             ` Maxime Ripard
2018-06-25 12:02 ` [PATCH v3 11/24] drm/sun4i: Don't check for LVDS and RGB when TCON has only ch1 Jernej Skrabec
2018-06-28  2:08   ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 12/24] drm/sun4i: Don't check for panel or bridge on TV TCONs Jernej Skrabec
2018-06-28  2:17   ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 13/24] dt-bindings: display: sun4i-drm: Add R40 mixer compatibles Jernej Skrabec
2018-06-28  2:17   ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 14/24] drm/sun4i: Add support for R40 mixers Jernej Skrabec
2018-06-28  2:18   ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 15/24] dt-bindings: display: sun4i-drm: Add description of A64 HDMI PHY Jernej Skrabec
2018-06-28  2:19   ` Chen-Yu Tsai
2018-06-28  4:51     ` Jernej Škrabec
2018-06-28  7:00       ` [linux-sunxi] " Chen-Yu Tsai
2018-06-29 19:32         ` Jernej Škrabec
2018-07-04  4:05           ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 16/24] drm/sun4i: Enable DW HDMI PHY clock Jernej Skrabec
2018-06-28  2:22   ` Chen-Yu Tsai
2018-06-28  4:52     ` Jernej Škrabec
2018-06-29 19:19     ` Jernej Škrabec
2018-06-30  1:11       ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 17/24] drm/sun4i: Don't change clock bits in DW HDMI PHY driver Jernej Skrabec
2018-06-28  2:24   ` Chen-Yu Tsai
2018-06-29 19:23     ` Jernej Škrabec
2018-06-25 12:02 ` [PATCH v3 18/24] drm/sun4i: DW HDMI PHY: Add support for second PLL Jernej Skrabec
2018-06-28  2:25   ` Chen-Yu Tsai
2018-06-28  4:56     ` Jernej Škrabec
2018-06-28  6:59       ` [linux-sunxi] " Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 19/24] drm/sun4i: Add support for second clock parent to DW HDMI PHY clk driver Jernej Skrabec
2018-06-28  2:30   ` [linux-sunxi] " Chen-Yu Tsai
2018-06-25 12:03 ` [PATCH v3 20/24] drm/sun4i: Add support for A64 HDMI PHY Jernej Skrabec
2018-06-28  2:30   ` Chen-Yu Tsai
2018-06-25 12:03 ` [PATCH v3 21/24] drm: of: Export drm_crtc_port_mask() Jernej Skrabec
2018-06-28  2:32   ` Chen-Yu Tsai
2018-06-25 12:03 ` [PATCH v3 22/24] drm/sun4i: DW HDMI: Expand algorithm for possible crtcs Jernej Skrabec
2018-06-28  2:42   ` Chen-Yu Tsai
2018-06-25 12:03 ` [PATCH v3 23/24] ARM: dts: sun8i: r40: Add HDMI pipeline Jernej Skrabec
2018-06-28  2:50   ` Chen-Yu Tsai
2018-06-28  5:15     ` Jernej Škrabec
2018-06-28  6:51       ` [linux-sunxi] " Chen-Yu Tsai
2018-07-01 10:41         ` Jernej Škrabec
2018-07-01 13:52           ` Chen-Yu Tsai
2018-07-01 15:13             ` Jernej Škrabec
2018-07-01 15:35               ` Chen-Yu Tsai
2018-07-01 19:25                 ` Jernej Škrabec
2018-07-02 21:39                   ` Jernej Škrabec
2018-06-25 12:03 ` [PATCH v3 24/24] ARM: dts: sun8i: r40: Enable HDMI output on BananaPi M2 Ultra Jernej Skrabec
2018-06-28  2:51   ` [linux-sunxi] " Chen-Yu Tsai
2018-06-25 12:07 ` [linux-sunxi] [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Škrabec
2018-06-25 16:43 ` Maxime Ripard
2018-06-27 18:02 ` Maxime Ripard
2018-06-27 19:50   ` Maxime Ripard
2018-06-27 20:25     ` Jernej Škrabec
2018-06-28  8:41       ` Maxime Ripard

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