linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: linus.walleij@linaro.org (Linus Walleij)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 4/4] drm/pl111: Support multiple endpoints on the CLCD
Date: Fri, 26 Jan 2018 14:20:33 +0100	[thread overview]
Message-ID: <20180126132033.19744-4-linus.walleij@linaro.org> (raw)
In-Reply-To: <20180126132033.19744-1-linus.walleij@linaro.org>

The Versatile PL110 implementations use multiple endpoints:
from the PL111 port, the lines are routed through a PLD,
and from there forked so the same lines go to a VGA DAC and
an external TFT panel connector. This is discrete wireing
so there is no way to turn of one output, i.e. this is
really two endpoints, not two ports.

We model this with multiple endpoints, so we need to loop
over the available endpoints, check for panel or bridge on
each and accumulate the result before continuing.

The code already will give the panel preference over the
bridge, if present, so the output will be sent to the panel
if both a panel and a bridge is present on two endpoints
of the same port.

If they all return -EPROBE_DEFER we return -EPROBE_DEFER
as well.

If just one endpoint is present on the port, the behaviour
is the same as before.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpu/drm/pl111/pl111_drv.c | 62 +++++++++++++++++++++++++++++++++++----
 1 file changed, 56 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
index f1f1b87b0e44..7e9f5efe3274 100644
--- a/drivers/gpu/drm/pl111/pl111_drv.c
+++ b/drivers/gpu/drm/pl111/pl111_drv.c
@@ -58,6 +58,8 @@
 #include <linux/dma-buf.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
 
 #include <drm/drmP.h>
 #include <drm/drm_atomic_helper.h>
@@ -84,9 +86,13 @@ static int pl111_modeset_init(struct drm_device *dev)
 {
 	struct drm_mode_config *mode_config;
 	struct pl111_drm_dev_private *priv = dev->dev_private;
-	struct drm_panel *panel;
-	struct drm_bridge *bridge;
+	struct device_node *np = dev->dev->of_node;
+	struct device_node *remote;
+	struct drm_panel *panel = NULL;
+	struct drm_bridge *bridge = NULL;
+	bool defer = false;
 	int ret = 0;
+	int i;
 
 	drm_mode_config_init(dev);
 	mode_config = &dev->mode_config;
@@ -96,10 +102,54 @@ static int pl111_modeset_init(struct drm_device *dev)
 	mode_config->min_height = 1;
 	mode_config->max_height = 768;
 
-	ret = drm_of_find_panel_or_bridge(dev->dev->of_node,
-					  0, 0, &panel, &bridge);
-	if (ret && ret != -ENODEV)
-		return ret;
+	i = 0;
+	for_each_endpoint_of_node(np, remote) {
+		struct drm_panel *tmp_panel;
+		struct drm_bridge *tmp_bridge;
+
+		dev_dbg(dev->dev, "checking endpoint %d\n", i);
+
+		ret = drm_of_find_panel_or_bridge(dev->dev->of_node,
+						  0, i,
+						  &tmp_panel,
+						  &tmp_bridge);
+		if (ret) {
+			if (ret == -EPROBE_DEFER) {
+				/*
+				 * Something deferred, but that is often just
+				 * another way of saying -ENODEV, but let's
+				 * cast a vote for later deferral.
+				 */
+				defer = true;
+			} else if (ret != -ENODEV) {
+				/* Continue, maybe something else is working */
+				dev_err(dev->dev,
+					"endpoint %d returns %d\n", i, ret);
+			}
+		}
+
+		if (tmp_panel) {
+			dev_info(dev->dev,
+				 "found panel on endpoint %d\n", i);
+			panel = tmp_panel;
+		}
+		if (tmp_bridge) {
+			dev_info(dev->dev,
+				 "found bridge on endpoint %d\n", i);
+			bridge = tmp_bridge;
+		}
+
+		i++;
+	}
+
+	/*
+	 * If we can't find neither panel nor bridge on any of the
+	 * endpoints, and any of them retured -EPROBE_DEFER, then
+	 * let's defer this driver too.
+	 */
+	if ((!panel && !bridge) && defer)
+		return -EPROBE_DEFER;
+
 	if (panel) {
 		bridge = drm_panel_bridge_add(panel,
 					      DRM_MODE_CONNECTOR_Unknown);
-- 
2.14.3

  parent reply	other threads:[~2018-01-26 13:20 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-26 13:20 [PATCH 1/4] drm/pl111: Error handling for CMA framebuffer Linus Walleij
2018-01-26 13:20 ` [PATCH 2/4] drm/pl111: Properly detect the PL110+ variant Linus Walleij
2018-01-29 23:45   ` Eric Anholt
2018-01-30 15:39     ` Linus Walleij
2018-01-26 13:20 ` [PATCH 3/4] drm/pl111: Handle the Versatile RGB/BGR565 mode Linus Walleij
2018-01-26 13:20 ` Linus Walleij [this message]
2018-01-29 23:55   ` [PATCH 4/4] drm/pl111: Support multiple endpoints on the CLCD Eric Anholt
2018-02-01 12:49     ` Linus Walleij
2018-01-29 23:39 ` [PATCH 1/4] drm/pl111: Error handling for CMA framebuffer Eric Anholt

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=20180126132033.19744-4-linus.walleij@linaro.org \
    --to=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.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 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).