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
next prev parent 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: linkBe 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.