All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chen-Yu Tsai <wens@csie.org>
To: Maxime Ripard <maxime.ripard@free-electrons.com>,
	David Airlie <airlied@linux.ie>, Rob Herring <robh+dt@kernel.org>,
	Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@codeaurora.org>
Cc: Chen-Yu Tsai <wens@csie.org>,
	dri-devel@lists.freedesktop.org,
	linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
	linux-clk@vger.kernel.org, linux-sunxi@googlegroups.com
Subject: [PATCH 02/19] drm/sun4i: add components in two passes with encoders added in second pass
Date: Fri,  2 Jun 2017 18:10:07 +0800	[thread overview]
Message-ID: <20170602101024.18940-3-wens@csie.org> (raw)
In-Reply-To: <20170602101024.18940-1-wens@csie.org>

The encoder drivers use drm_of_find_possible_crtcs to get upstream
crtcs from the device tree using of_graph. For the results to be
correct, encoders must be probed/bound after _all_ crtcs have been
created. The existing code uses a depth first recursive traversal
of the of_graph, which means the encoders downstream of the TCON
get add right after the first TCON. The second TCON or CRTC will
never be properly associated with encoders connected to it.

Other platforms, such as Rockchip, deal with this by probing all
crtcs first, then all subsequent components. This is easy to do
since the crtcs correspond to just one device node, and are the
first nodes in the pipeline.

However with Allwinner SoCs, the function of the CRTC is split between
the display backend (DE 1.0) or mixer (DE 2.0), which does scan-out
and compositing, and the TCON, which generating the display timing
signals. Further complicating the process, there may be a Dynamic Range
Controller between the backend and the TCON. Also, the backend is
preceded by the frontend, with a Display Enhancement Unit possibly
in between.

One solution would be, instead of a depth first traversal of the
component of_graph, we do a breadth first traversal, so that components
at the same depth are grouped together. This however requires us to
implement extra code for a queue structure that is only used here.

Instead, since we can identify TCON device nodes, and since the
component system can gracefully deal with duplicate entries, we can add
components in two passes, using the existing recursive depth code. The
first pass stops right after the TCON is added. The second pass will
re-add all components up to the TCON, but these will be skipped since
they will have already been bound with the entries from the first pass.
The encoders added in the second pass will be the last entries in the
list.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 drivers/gpu/drm/sun4i/sun4i_drv.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index ed75a779ae4b..bc13dcf06783 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -198,7 +198,8 @@ static int compare_of(struct device *dev, void *data)
 
 static int sun4i_drv_add_endpoints(struct device *dev,
 				   struct component_match **match,
-				   struct device_node *node)
+				   struct device_node *node,
+				   bool add_encoders)
 {
 	struct device_node *port, *ep, *remote;
 	int count = 0;
@@ -227,13 +228,16 @@ static int sun4i_drv_add_endpoints(struct device *dev,
 		count++;
 	}
 
+	/* Skip downstream encoders during the first pass */
+	if (sun4i_drv_node_is_tcon(node) && !add_encoders)
+		return 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) {
@@ -262,7 +266,8 @@ static int sun4i_drv_add_endpoints(struct device *dev,
 		}
 
 		/* Walk down our tree */
-		count += sun4i_drv_add_endpoints(dev, match, remote);
+		count += sun4i_drv_add_endpoints(dev, match, remote,
+						 add_encoders);
 
 		of_node_put(remote);
 	}
@@ -283,8 +288,19 @@ static int sun4i_drv_probe(struct platform_device *pdev)
 		if (!pipeline)
 			break;
 
+		sun4i_drv_add_endpoints(&pdev->dev, &match, pipeline, false);
+		of_node_put(pipeline);
+	}
+
+	for (i = 0;; i++) {
+		struct device_node *pipeline = of_parse_phandle(np,
+								"allwinner,pipelines",
+								i);
+		if (!pipeline)
+			break;
+
 		count += sun4i_drv_add_endpoints(&pdev->dev, &match,
-						pipeline);
+						 pipeline, true);
 		of_node_put(pipeline);
 
 		DRM_DEBUG_DRIVER("Queued %d outputs on pipeline %d\n",
-- 
2.11.0


WARNING: multiple messages have this Message-ID (diff)
From: wens@csie.org (Chen-Yu Tsai)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 02/19] drm/sun4i: add components in two passes with encoders added in second pass
Date: Fri,  2 Jun 2017 18:10:07 +0800	[thread overview]
Message-ID: <20170602101024.18940-3-wens@csie.org> (raw)
In-Reply-To: <20170602101024.18940-1-wens@csie.org>

The encoder drivers use drm_of_find_possible_crtcs to get upstream
crtcs from the device tree using of_graph. For the results to be
correct, encoders must be probed/bound after _all_ crtcs have been
created. The existing code uses a depth first recursive traversal
of the of_graph, which means the encoders downstream of the TCON
get add right after the first TCON. The second TCON or CRTC will
never be properly associated with encoders connected to it.

Other platforms, such as Rockchip, deal with this by probing all
crtcs first, then all subsequent components. This is easy to do
since the crtcs correspond to just one device node, and are the
first nodes in the pipeline.

However with Allwinner SoCs, the function of the CRTC is split between
the display backend (DE 1.0) or mixer (DE 2.0), which does scan-out
and compositing, and the TCON, which generating the display timing
signals. Further complicating the process, there may be a Dynamic Range
Controller between the backend and the TCON. Also, the backend is
preceded by the frontend, with a Display Enhancement Unit possibly
in between.

One solution would be, instead of a depth first traversal of the
component of_graph, we do a breadth first traversal, so that components
at the same depth are grouped together. This however requires us to
implement extra code for a queue structure that is only used here.

Instead, since we can identify TCON device nodes, and since the
component system can gracefully deal with duplicate entries, we can add
components in two passes, using the existing recursive depth code. The
first pass stops right after the TCON is added. The second pass will
re-add all components up to the TCON, but these will be skipped since
they will have already been bound with the entries from the first pass.
The encoders added in the second pass will be the last entries in the
list.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 drivers/gpu/drm/sun4i/sun4i_drv.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index ed75a779ae4b..bc13dcf06783 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -198,7 +198,8 @@ static int compare_of(struct device *dev, void *data)
 
 static int sun4i_drv_add_endpoints(struct device *dev,
 				   struct component_match **match,
-				   struct device_node *node)
+				   struct device_node *node,
+				   bool add_encoders)
 {
 	struct device_node *port, *ep, *remote;
 	int count = 0;
@@ -227,13 +228,16 @@ static int sun4i_drv_add_endpoints(struct device *dev,
 		count++;
 	}
 
+	/* Skip downstream encoders during the first pass */
+	if (sun4i_drv_node_is_tcon(node) && !add_encoders)
+		return 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) {
@@ -262,7 +266,8 @@ static int sun4i_drv_add_endpoints(struct device *dev,
 		}
 
 		/* Walk down our tree */
-		count += sun4i_drv_add_endpoints(dev, match, remote);
+		count += sun4i_drv_add_endpoints(dev, match, remote,
+						 add_encoders);
 
 		of_node_put(remote);
 	}
@@ -283,8 +288,19 @@ static int sun4i_drv_probe(struct platform_device *pdev)
 		if (!pipeline)
 			break;
 
+		sun4i_drv_add_endpoints(&pdev->dev, &match, pipeline, false);
+		of_node_put(pipeline);
+	}
+
+	for (i = 0;; i++) {
+		struct device_node *pipeline = of_parse_phandle(np,
+								"allwinner,pipelines",
+								i);
+		if (!pipeline)
+			break;
+
 		count += sun4i_drv_add_endpoints(&pdev->dev, &match,
-						pipeline);
+						 pipeline, true);
 		of_node_put(pipeline);
 
 		DRM_DEBUG_DRIVER("Queued %d outputs on pipeline %d\n",
-- 
2.11.0

  reply	other threads:[~2017-06-02 10:10 UTC|newest]

Thread overview: 105+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-02 10:10 [PATCH 00/19] drm/sun4i: hdmi: Support HDMI controller on A31 Chen-Yu Tsai
2017-06-02 10:10 ` Chen-Yu Tsai
2017-06-02 10:10 ` Chen-Yu Tsai
2017-06-02 10:10 ` Chen-Yu Tsai [this message]
2017-06-02 10:10   ` [PATCH 02/19] drm/sun4i: add components in two passes with encoders added in second pass Chen-Yu Tsai
2017-06-02 19:18   ` Maxime Ripard
2017-06-02 19:18     ` Maxime Ripard
2017-06-02 10:10 ` [PATCH 07/19] drm/sun4i: hdmi: Support different variants of the TMDS clock Chen-Yu Tsai
2017-06-02 10:10   ` Chen-Yu Tsai
     [not found] ` <20170602101024.18940-1-wens-jdAy2FN1RRM@public.gmane.org>
2017-06-02 10:10   ` [PATCH 01/19] drm/sun4i: call drm_vblank_init with correct number of crtcs Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 03/19] drm/sun4i: tcon: Add support for demuxing TCON output on A31 Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 04/19] drm/sun4i: hdmi: Disable clks in bind function error path and unbind function Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 05/19] drm/sun4i: hdmi: Allow using second PLL as TMDS clk parent Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 06/19] dt-bindings: display: sun4i: Add binding for A31 HDMI controller Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
     [not found]     ` <20170602101024.18940-7-wens-jdAy2FN1RRM@public.gmane.org>
2017-06-07 22:37       ` Rob Herring
2017-06-07 22:37         ` Rob Herring
2017-06-07 22:37         ` Rob Herring
2017-06-02 10:10   ` [PATCH 08/19] drm/sun4i: hdmi: Support the TMDS clock in the A31's " Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 09/19] drm/sun4i: hdmi: Support different variants of the DDC clock Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 10/19] drm/sun4i: hdmi: Rename internal DDC clock to avoid name collision Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 19:30     ` Maxime Ripard
2017-06-02 19:30       ` Maxime Ripard
2017-06-03 14:33       ` Chen-Yu Tsai
2017-06-03 14:33         ` Chen-Yu Tsai
     [not found]         ` <CAGb2v64Vgdjm1MAwn+L0PVc0CA0QOCn=0RONKoGDWLpzVBzvmQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-06-05 14:00           ` Maxime Ripard
2017-06-05 14:00             ` Maxime Ripard
2017-06-05 14:00             ` Maxime Ripard
     [not found]             ` <20170605140012.rlx7rm7xhriwqaza-ZC1Zs529Oq4@public.gmane.org>
2017-06-23  9:37               ` Chen-Yu Tsai
2017-06-23  9:37                 ` Chen-Yu Tsai
2017-06-23  9:37                 ` Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 11/19] drm/sun4i: hdmi: Add A31 specific DDC register definitions Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 12/19] drm/sun4i: hdmi: Support the DDC clock in the A31's HDMI controller Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
     [not found]     ` <20170602101024.18940-13-wens-jdAy2FN1RRM@public.gmane.org>
2017-06-02 19:31       ` Maxime Ripard
2017-06-02 19:31         ` Maxime Ripard
2017-06-02 19:31         ` Maxime Ripard
2017-06-02 10:10   ` [PATCH 13/19] drm/sun4i: hdmi: Add support for controller hardware variants Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 19:38     ` Maxime Ripard
2017-06-02 19:38       ` Maxime Ripard
     [not found]       ` <20170602193827.rnjum6x5ra4x5wef-ZC1Zs529Oq4@public.gmane.org>
2017-06-03 14:58         ` Chen-Yu Tsai
2017-06-03 14:58           ` Chen-Yu Tsai
2017-06-03 14:58           ` Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 14/19] drm/sun4i: hdmi: Add support for A31's HDMI controller Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 19:41     ` Maxime Ripard
2017-06-02 19:41       ` Maxime Ripard
2017-06-03 15:19       ` Chen-Yu Tsai
2017-06-03 15:19         ` Chen-Yu Tsai
     [not found]         ` <CAGb2v65eFAmAybmHkQcKjF+ZKxh+_G6q9i2GPzMs5854X8bQug-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-06-06 19:27           ` Maxime Ripard
2017-06-06 19:27             ` Maxime Ripard
2017-06-06 19:27             ` Maxime Ripard
2017-06-02 10:10   ` [PATCH 15/19] clk: sunxi-ng: sun6i: Export video PLLs Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 16/19] ARM: sun6i: a31: Add device node for HDMI controller Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 17/19] ARM: sun6i: a31: Enable HDMI support on the A31 Hummingbird Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 18/19] ARM: sun6i: a31s: Enable HDMI display output on the Sinlinx SinA31s Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10   ` [PATCH 19/19] ARM: sun6i: a31s: Enable HDMI display output on the MSI Primo81 tablet Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
2017-06-02 10:10     ` Chen-Yu Tsai
     [not found]     ` <20170602101024.18940-20-wens-jdAy2FN1RRM@public.gmane.org>
2017-06-02 19:42       ` Maxime Ripard
2017-06-02 19:42         ` Maxime Ripard
2017-06-02 19:42         ` Maxime Ripard
     [not found]         ` <20170602194219.hiajr7dt2oikm52q-ZC1Zs529Oq4@public.gmane.org>
2017-06-03 15:31           ` Chen-Yu Tsai
2017-06-03 15:31             ` Chen-Yu Tsai
2017-06-03 15:31             ` Chen-Yu Tsai
2017-06-07 22:36           ` Rob Herring
2017-06-07 22:36             ` Rob Herring
2017-06-07 22:36             ` Rob Herring
2017-06-07 22:47             ` Ilia Mirkin
2017-06-07 22:47               ` Ilia Mirkin
     [not found]               ` <CAKb7UvgKhgCpeNzUX1ecFPuF6j+KvAWW3vprZ9nnVMBBJFi_zQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-06-09 16:08                 ` Chen-Yu Tsai
2017-06-09 16:08                   ` Chen-Yu Tsai
2017-06-09 16:08                   ` Chen-Yu Tsai
2017-06-09 16:49                   ` Rob Herring
2017-06-09 16:49                     ` Rob Herring
2017-06-09 16:49                     ` Rob Herring

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170602101024.18940-3-wens@csie.org \
    --to=wens@csie.org \
    --cc=airlied@linux.ie \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-sunxi@googlegroups.com \
    --cc=maxime.ripard@free-electrons.com \
    --cc=mturquette@baylibre.com \
    --cc=robh+dt@kernel.org \
    --cc=sboyd@codeaurora.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.