dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/6] Support DRM bridges on NVIDIA Tegra
@ 2020-04-18 17:06 Dmitry Osipenko
  2020-04-18 17:06 ` [PATCH v5 1/6] of_graph: add of_graph_get_local_port() Dmitry Osipenko
                   ` (6 more replies)
  0 siblings, 7 replies; 18+ messages in thread
From: Dmitry Osipenko @ 2020-04-18 17:06 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, Laurent Pinchart, Rob Herring,
	Frank Rowand
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel

Hello,

This series adds initial support for the DRM bridges to NVIDIA Tegra DRM
driver. This is required by newer device-trees where we model the LVDS
encoder bridge properly.

Changelog:

v5: - Added new patches that make drm_of_find_panel_or_bridge() more usable
      if graph isn't defined in a device-tree:

        of_graph: add of_graph_get_local_port()
        drm/of: Make drm_of_find_panel_or_bridge() to check graph's presence

    - Updated "Support DRM bridges" patch to use drm_of_find_panel_or_bridge()
      directly and added WARN_ON(output->panel || output->bridge) sanity-check.

    - Added new "Wrap directly-connected panel into DRM bridge" patch, as
      was suggested by Laurent Pinchart.

v4: - Following review comments that were made by Laurent Pinchart to the v3,
      we now create and use the "bridge connector".

v3: - Following recommendation from Sam Ravnborg, the new bridge attachment
      model is now being used, i.e. we ask bridge to *not* create a connector
      using the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag.

    - The bridge is now created only for the RGB (LVDS) output, and only
      when necessary. For now we don't need bridges for HDMI or DSI outputs.

    - I noticed that we're leaking OF node in the panel's error code path,
      this is fixed now by the new patch "Don't leak OF node on error".

v2: - Added the new "rgb: Don't register connector if bridge is used"
      patch, which hides the unused connector provided by the Tegra DRM
      driver when bridge is used, since bridge provides its own connector
      to us.

    - Please notice that the first "Support DRM bridges" patch was previously
      sent out as a standalone v1 change.

Dmitry Osipenko (6):
  of_graph: add of_graph_get_local_port()
  drm/of: Make drm_of_find_panel_or_bridge() to check graph's presence
  drm/tegra: output: Don't leak OF node on error
  drm/tegra: output: Support DRM bridges
  drm/tegra: output: rgb: Support LVDS encoder bridge
  drm/tegra: output: rgb: Wrap directly-connected panel into DRM bridge

 drivers/gpu/drm/drm_of.c       | 13 +++++-
 drivers/gpu/drm/tegra/drm.h    |  2 +
 drivers/gpu/drm/tegra/output.c | 21 +++++++--
 drivers/gpu/drm/tegra/rgb.c    | 85 +++++++++++++++++++++-------------
 drivers/of/property.c          | 32 +++++++++----
 include/linux/of_graph.h       |  7 +++
 6 files changed, 114 insertions(+), 46 deletions(-)

-- 
2.26.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v5 1/6] of_graph: add of_graph_get_local_port()
  2020-04-18 17:06 [PATCH v5 0/6] Support DRM bridges on NVIDIA Tegra Dmitry Osipenko
@ 2020-04-18 17:06 ` Dmitry Osipenko
  2020-04-30 14:10   ` Rob Herring
  2020-05-06 16:32   ` Sam Ravnborg
  2020-04-18 17:06 ` [PATCH v5 2/6] drm/of: Make drm_of_find_panel_or_bridge() to check graph's presence Dmitry Osipenko
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 18+ messages in thread
From: Dmitry Osipenko @ 2020-04-18 17:06 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, Laurent Pinchart, Rob Herring,
	Frank Rowand
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel

In some case, like a DRM display code for example, it's useful to silently
check whether port node exists at all in a device-tree before proceeding
with parsing the graph.

This patch adds of_graph_get_local_port() which returns pointer to a local
port node, or NULL if graph isn't specified in a device-tree for a given
device node.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/of/property.c    | 32 +++++++++++++++++++++++---------
 include/linux/of_graph.h |  7 +++++++
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/drivers/of/property.c b/drivers/of/property.c
index 252e4f600155..5dbeccaabb86 100644
--- a/drivers/of/property.c
+++ b/drivers/of/property.c
@@ -608,15 +608,7 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
 	 * parent port node.
 	 */
 	if (!prev) {
-		struct device_node *node;
-
-		node = of_get_child_by_name(parent, "ports");
-		if (node)
-			parent = node;
-
-		port = of_get_child_by_name(parent, "port");
-		of_node_put(node);
-
+		port = of_graph_get_local_port(parent);
 		if (!port) {
 			pr_err("graph: no port node found in %pOF\n", parent);
 			return NULL;
@@ -765,6 +757,28 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
 }
 EXPORT_SYMBOL(of_graph_get_remote_port);
 
+/**
+ * of_graph_get_local_port() - get local port node
+ * @node: pointer to a local endpoint device_node
+ *
+ * Return: First local port node associated with local endpoint node linked
+ *	   to @node. Use of_node_put() on it when done.
+ */
+struct device_node *of_graph_get_local_port(const struct device_node *node)
+{
+	struct device_node *ports, *port;
+
+	ports = of_get_child_by_name(node, "ports");
+	if (ports)
+		node = ports;
+
+	port = of_get_child_by_name(node, "port");
+	of_node_put(ports);
+
+	return port;
+}
+EXPORT_SYMBOL(of_graph_get_local_port);
+
 int of_graph_get_endpoint_count(const struct device_node *np)
 {
 	struct device_node *endpoint;
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index 01038a6aade0..1fdeb72c7765 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -54,6 +54,7 @@ struct device_node *of_graph_get_remote_port_parent(
 struct device_node *of_graph_get_remote_port(const struct device_node *node);
 struct device_node *of_graph_get_remote_node(const struct device_node *node,
 					     u32 port, u32 endpoint);
+struct device_node *of_graph_get_local_port(const struct device_node *node);
 #else
 
 static inline int of_graph_parse_endpoint(const struct device_node *node,
@@ -116,6 +117,12 @@ static inline struct device_node *of_graph_get_remote_node(
 	return NULL;
 }
 
+static inline struct device_node *of_graph_get_local_port(
+					const struct device_node *node)
+{
+	return NULL;
+}
+
 #endif /* CONFIG_OF */
 
 #endif /* __LINUX_OF_GRAPH_H */
-- 
2.26.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v5 2/6] drm/of: Make drm_of_find_panel_or_bridge() to check graph's presence
  2020-04-18 17:06 [PATCH v5 0/6] Support DRM bridges on NVIDIA Tegra Dmitry Osipenko
  2020-04-18 17:06 ` [PATCH v5 1/6] of_graph: add of_graph_get_local_port() Dmitry Osipenko
@ 2020-04-18 17:06 ` Dmitry Osipenko
  2020-05-06 16:41   ` Sam Ravnborg
  2020-04-18 17:07 ` [PATCH v5 3/6] drm/tegra: output: Don't leak OF node on error Dmitry Osipenko
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Dmitry Osipenko @ 2020-04-18 17:06 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, Laurent Pinchart, Rob Herring,
	Frank Rowand
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel

When graph isn't defined in a device-tree, the of_graph_get_remote_node()
prints a noisy error message, telling that port node is not found. This is
undesirable behaviour in our case because absence of a panel/bridge graph
is a valid case. Let's check presence of the local port in a device-tree
before proceeding with parsing the graph.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/drm_of.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index b50b44e76279..e0652c38f357 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -239,13 +239,24 @@ int drm_of_find_panel_or_bridge(const struct device_node *np,
 				struct drm_bridge **bridge)
 {
 	int ret = -EPROBE_DEFER;
-	struct device_node *remote;
+	struct device_node *local, *remote;
 
 	if (!panel && !bridge)
 		return -EINVAL;
 	if (panel)
 		*panel = NULL;
 
+	/*
+	 * of_graph_get_remote_node() produces a noisy error message if port
+	 * node isn't found and the absence of the port is a legit case here,
+	 * so at first we silently check presence of the local port.
+	 */
+	local = of_graph_get_local_port(np);
+	if (!local)
+		return -ENODEV;
+
+	of_node_put(local);
+
 	remote = of_graph_get_remote_node(np, port, endpoint);
 	if (!remote)
 		return -ENODEV;
-- 
2.26.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v5 3/6] drm/tegra: output: Don't leak OF node on error
  2020-04-18 17:06 [PATCH v5 0/6] Support DRM bridges on NVIDIA Tegra Dmitry Osipenko
  2020-04-18 17:06 ` [PATCH v5 1/6] of_graph: add of_graph_get_local_port() Dmitry Osipenko
  2020-04-18 17:06 ` [PATCH v5 2/6] drm/of: Make drm_of_find_panel_or_bridge() to check graph's presence Dmitry Osipenko
@ 2020-04-18 17:07 ` Dmitry Osipenko
  2020-05-06 16:42   ` Sam Ravnborg
  2020-04-18 17:07 ` [PATCH v5 4/6] drm/tegra: output: Support DRM bridges Dmitry Osipenko
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Dmitry Osipenko @ 2020-04-18 17:07 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, Laurent Pinchart, Rob Herring,
	Frank Rowand
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel

The OF node should be put before returning error in tegra_output_probe(),
otherwise node's refcount will be leaked.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/tegra/output.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
index e36e5e7c2f69..a6a711d54e88 100644
--- a/drivers/gpu/drm/tegra/output.c
+++ b/drivers/gpu/drm/tegra/output.c
@@ -102,10 +102,10 @@ int tegra_output_probe(struct tegra_output *output)
 	panel = of_parse_phandle(output->of_node, "nvidia,panel", 0);
 	if (panel) {
 		output->panel = of_drm_find_panel(panel);
+		of_node_put(panel);
+
 		if (IS_ERR(output->panel))
 			return PTR_ERR(output->panel);
-
-		of_node_put(panel);
 	}
 
 	output->edid = of_get_property(output->of_node, "nvidia,edid", &size);
@@ -113,13 +113,12 @@ int tegra_output_probe(struct tegra_output *output)
 	ddc = of_parse_phandle(output->of_node, "nvidia,ddc-i2c-bus", 0);
 	if (ddc) {
 		output->ddc = of_find_i2c_adapter_by_node(ddc);
+		of_node_put(ddc);
+
 		if (!output->ddc) {
 			err = -EPROBE_DEFER;
-			of_node_put(ddc);
 			return err;
 		}
-
-		of_node_put(ddc);
 	}
 
 	output->hpd_gpio = devm_gpiod_get_from_of_node(output->dev,
-- 
2.26.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v5 4/6] drm/tegra: output: Support DRM bridges
  2020-04-18 17:06 [PATCH v5 0/6] Support DRM bridges on NVIDIA Tegra Dmitry Osipenko
                   ` (2 preceding siblings ...)
  2020-04-18 17:07 ` [PATCH v5 3/6] drm/tegra: output: Don't leak OF node on error Dmitry Osipenko
@ 2020-04-18 17:07 ` Dmitry Osipenko
  2020-05-06 16:43   ` Sam Ravnborg
  2020-04-18 17:07 ` [PATCH v5 5/6] drm/tegra: output: rgb: Support LVDS encoder bridge Dmitry Osipenko
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Dmitry Osipenko @ 2020-04-18 17:07 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, Laurent Pinchart, Rob Herring,
	Frank Rowand
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel

Newer Tegra device-trees will specify a video output graph which involves
a bridge. This patch adds initial support for the DRM bridges to the Tegra
DRM output.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/tegra/drm.h    |  2 ++
 drivers/gpu/drm/tegra/output.c | 12 ++++++++++++
 2 files changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index 804869799305..cccd368b6752 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -12,6 +12,7 @@
 #include <linux/of_gpio.h>
 
 #include <drm/drm_atomic.h>
+#include <drm/drm_bridge.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder.h>
 #include <drm/drm_fb_helper.h>
@@ -116,6 +117,7 @@ struct tegra_output {
 	struct device_node *of_node;
 	struct device *dev;
 
+	struct drm_bridge *bridge;
 	struct drm_panel *panel;
 	struct i2c_adapter *ddc;
 	const struct edid *edid;
diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
index a6a711d54e88..ccd1421f1b24 100644
--- a/drivers/gpu/drm/tegra/output.c
+++ b/drivers/gpu/drm/tegra/output.c
@@ -5,6 +5,7 @@
  */
 
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_of.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_simple_kms_helper.h>
 
@@ -99,8 +100,19 @@ int tegra_output_probe(struct tegra_output *output)
 	if (!output->of_node)
 		output->of_node = output->dev->of_node;
 
+	err = drm_of_find_panel_or_bridge(output->of_node, -1, -1,
+					  &output->panel, &output->bridge);
+	if (err && err != -ENODEV)
+		return err;
+
 	panel = of_parse_phandle(output->of_node, "nvidia,panel", 0);
 	if (panel) {
+		/*
+		 * Don't mix nvidia,panel phandle with the graph in a
+		 * device-tree.
+		 */
+		WARN_ON(output->panel || output->bridge);
+
 		output->panel = of_drm_find_panel(panel);
 		of_node_put(panel);
 
-- 
2.26.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v5 5/6] drm/tegra: output: rgb: Support LVDS encoder bridge
  2020-04-18 17:06 [PATCH v5 0/6] Support DRM bridges on NVIDIA Tegra Dmitry Osipenko
                   ` (3 preceding siblings ...)
  2020-04-18 17:07 ` [PATCH v5 4/6] drm/tegra: output: Support DRM bridges Dmitry Osipenko
@ 2020-04-18 17:07 ` Dmitry Osipenko
  2020-05-06 16:45   ` Sam Ravnborg
  2020-04-18 17:07 ` [PATCH v5 6/6] drm/tegra: output: rgb: Wrap directly-connected panel into DRM bridge Dmitry Osipenko
  2020-05-24 18:41 ` [PATCH v5 0/6] Support DRM bridges on NVIDIA Tegra Dmitry Osipenko
  6 siblings, 1 reply; 18+ messages in thread
From: Dmitry Osipenko @ 2020-04-18 17:07 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, Laurent Pinchart, Rob Herring,
	Frank Rowand
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel

Newer Tegra device-trees will specify a video output graph, which involves
LVDS encoder bridge. This patch adds support for the LVDS encoder bridge
to the RGB output, allowing us to model the display hardware properly.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/tegra/rgb.c | 58 +++++++++++++++++++++++++++++++------
 1 file changed, 49 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
index 0562a7eb793f..9a7024ec96bc 100644
--- a/drivers/gpu/drm/tegra/rgb.c
+++ b/drivers/gpu/drm/tegra/rgb.c
@@ -7,6 +7,7 @@
 #include <linux/clk.h>
 
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge_connector.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_simple_kms_helper.h>
 
@@ -267,24 +268,63 @@ int tegra_dc_rgb_remove(struct tegra_dc *dc)
 int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc)
 {
 	struct tegra_output *output = dc->rgb;
+	struct drm_connector *connector;
 	int err;
 
 	if (!dc->rgb)
 		return -ENODEV;
 
-	drm_connector_init(drm, &output->connector, &tegra_rgb_connector_funcs,
-			   DRM_MODE_CONNECTOR_LVDS);
-	drm_connector_helper_add(&output->connector,
-				 &tegra_rgb_connector_helper_funcs);
-	output->connector.dpms = DRM_MODE_DPMS_OFF;
-
 	drm_simple_encoder_init(drm, &output->encoder, DRM_MODE_ENCODER_LVDS);
 	drm_encoder_helper_add(&output->encoder,
 			       &tegra_rgb_encoder_helper_funcs);
 
-	drm_connector_attach_encoder(&output->connector,
-					  &output->encoder);
-	drm_connector_register(&output->connector);
+	/*
+	 * Tegra devices that have LVDS panel utilize LVDS encoder bridge
+	 * for converting up to 28 LCD LVTTL lanes into 5/4 LVDS lanes that
+	 * go to display panel's receiver.
+	 *
+	 * Encoder usually have a power-down control which needs to be enabled
+	 * in order to transmit data to the panel.  Historically devices that
+	 * use an older device-tree version didn't model the bridge, assuming
+	 * that encoder is turned ON by default, while today's DRM allows us
+	 * to model LVDS encoder properly.
+	 *
+	 * Newer device-trees utilize LVDS encoder bridge, which provides
+	 * us with a connector and handles the display panel.
+	 *
+	 * For older device-trees we fall back to our own connector and use
+	 * nvidia,panel phandle.
+	 */
+	if (output->bridge) {
+		err = drm_bridge_attach(&output->encoder, output->bridge,
+					NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+		if (err) {
+			dev_err(output->dev, "failed to attach bridge: %d\n",
+				err);
+			return err;
+		}
+
+		connector = drm_bridge_connector_init(drm, &output->encoder);
+		if (IS_ERR(connector)) {
+			dev_err(output->dev,
+				"failed to initialize bridge connector: %pe\n",
+				connector);
+			return PTR_ERR(connector);
+		}
+
+		drm_connector_attach_encoder(connector, &output->encoder);
+	} else {
+		drm_connector_init(drm, &output->connector,
+				   &tegra_rgb_connector_funcs,
+				   DRM_MODE_CONNECTOR_LVDS);
+		drm_connector_helper_add(&output->connector,
+					 &tegra_rgb_connector_helper_funcs);
+		output->connector.dpms = DRM_MODE_DPMS_OFF;
+
+		drm_connector_attach_encoder(&output->connector,
+					     &output->encoder);
+		drm_connector_register(&output->connector);
+	}
 
 	err = tegra_output_init(drm, output);
 	if (err < 0) {
-- 
2.26.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH v5 6/6] drm/tegra: output: rgb: Wrap directly-connected panel into DRM bridge
  2020-04-18 17:06 [PATCH v5 0/6] Support DRM bridges on NVIDIA Tegra Dmitry Osipenko
                   ` (4 preceding siblings ...)
  2020-04-18 17:07 ` [PATCH v5 5/6] drm/tegra: output: rgb: Support LVDS encoder bridge Dmitry Osipenko
@ 2020-04-18 17:07 ` Dmitry Osipenko
  2020-04-25 17:02   ` Sam Ravnborg
  2020-05-24 18:41 ` [PATCH v5 0/6] Support DRM bridges on NVIDIA Tegra Dmitry Osipenko
  6 siblings, 1 reply; 18+ messages in thread
From: Dmitry Osipenko @ 2020-04-18 17:07 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, Laurent Pinchart, Rob Herring,
	Frank Rowand
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel

Currently Tegra DRM driver manually manages display panel, but this
management could be moved out into DRM core if we'll wrap panel into
DRM bridge. This patch wraps RGB panel into a DRM bridge and removes
manual handling of the panel from the RGB output code.

Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/tegra/rgb.c | 53 +++++++++++++------------------------
 1 file changed, 18 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
index 9a7024ec96bc..a4c5a6066c54 100644
--- a/drivers/gpu/drm/tegra/rgb.c
+++ b/drivers/gpu/drm/tegra/rgb.c
@@ -8,7 +8,6 @@
 
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_bridge_connector.h>
-#include <drm/drm_panel.h>
 #include <drm/drm_simple_kms_helper.h>
 
 #include "drm.h"
@@ -86,15 +85,6 @@ static void tegra_dc_write_regs(struct tegra_dc *dc,
 		tegra_dc_writel(dc, table[i].value, table[i].offset);
 }
 
-static const struct drm_connector_funcs tegra_rgb_connector_funcs = {
-	.reset = drm_atomic_helper_connector_reset,
-	.detect = tegra_output_connector_detect,
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.destroy = tegra_output_connector_destroy,
-	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
 static enum drm_mode_status
 tegra_rgb_connector_mode_valid(struct drm_connector *connector,
 			       struct drm_display_mode *mode)
@@ -117,14 +107,8 @@ static void tegra_rgb_encoder_disable(struct drm_encoder *encoder)
 	struct tegra_output *output = encoder_to_output(encoder);
 	struct tegra_rgb *rgb = to_rgb(output);
 
-	if (output->panel)
-		drm_panel_disable(output->panel);
-
 	tegra_dc_write_regs(rgb->dc, rgb_disable, ARRAY_SIZE(rgb_disable));
 	tegra_dc_commit(rgb->dc);
-
-	if (output->panel)
-		drm_panel_unprepare(output->panel);
 }
 
 static void tegra_rgb_encoder_enable(struct drm_encoder *encoder)
@@ -133,9 +117,6 @@ static void tegra_rgb_encoder_enable(struct drm_encoder *encoder)
 	struct tegra_rgb *rgb = to_rgb(output);
 	u32 value;
 
-	if (output->panel)
-		drm_panel_prepare(output->panel);
-
 	tegra_dc_write_regs(rgb->dc, rgb_enable, ARRAY_SIZE(rgb_enable));
 
 	value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL;
@@ -157,9 +138,6 @@ static void tegra_rgb_encoder_enable(struct drm_encoder *encoder)
 	tegra_dc_writel(rgb->dc, value, DC_DISP_SHIFT_CLOCK_OPTIONS);
 
 	tegra_dc_commit(rgb->dc);
-
-	if (output->panel)
-		drm_panel_enable(output->panel);
 }
 
 static int
@@ -278,6 +256,23 @@ int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc)
 	drm_encoder_helper_add(&output->encoder,
 			       &tegra_rgb_encoder_helper_funcs);
 
+	/*
+	 * Wrap directly-connected panel into DRM bridge in order to let
+	 * DRM core to handle panel for us.
+	 */
+	if (output->panel) {
+		output->bridge = devm_drm_panel_bridge_add(output->dev,
+							   output->panel);
+		if (IS_ERR(output->bridge)) {
+			dev_err(output->dev,
+				"failed to wrap panel into bridge: %pe\n",
+				output->bridge);
+			return PTR_ERR(output->bridge);
+		}
+
+		output->panel = NULL;
+	}
+
 	/*
 	 * Tegra devices that have LVDS panel utilize LVDS encoder bridge
 	 * for converting up to 28 LCD LVTTL lanes into 5/4 LVDS lanes that
@@ -292,8 +287,7 @@ int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc)
 	 * Newer device-trees utilize LVDS encoder bridge, which provides
 	 * us with a connector and handles the display panel.
 	 *
-	 * For older device-trees we fall back to our own connector and use
-	 * nvidia,panel phandle.
+	 * For older device-trees we wrapped panel into the panel-bridge.
 	 */
 	if (output->bridge) {
 		err = drm_bridge_attach(&output->encoder, output->bridge,
@@ -313,17 +307,6 @@ int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc)
 		}
 
 		drm_connector_attach_encoder(connector, &output->encoder);
-	} else {
-		drm_connector_init(drm, &output->connector,
-				   &tegra_rgb_connector_funcs,
-				   DRM_MODE_CONNECTOR_LVDS);
-		drm_connector_helper_add(&output->connector,
-					 &tegra_rgb_connector_helper_funcs);
-		output->connector.dpms = DRM_MODE_DPMS_OFF;
-
-		drm_connector_attach_encoder(&output->connector,
-					     &output->encoder);
-		drm_connector_register(&output->connector);
 	}
 
 	err = tegra_output_init(drm, output);
-- 
2.26.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v5 6/6] drm/tegra: output: rgb: Wrap directly-connected panel into DRM bridge
  2020-04-18 17:07 ` [PATCH v5 6/6] drm/tegra: output: rgb: Wrap directly-connected panel into DRM bridge Dmitry Osipenko
@ 2020-04-25 17:02   ` Sam Ravnborg
  2020-04-25 21:51     ` Dmitry Osipenko
  0 siblings, 1 reply; 18+ messages in thread
From: Sam Ravnborg @ 2020-04-25 17:02 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, dri-devel, linux-kernel, Rob Herring, Thierry Reding,
	Laurent Pinchart, linux-tegra, Frank Rowand

Hi Dmitry

On Sat, Apr 18, 2020 at 08:07:03PM +0300, Dmitry Osipenko wrote:
> Currently Tegra DRM driver manually manages display panel, but this
> management could be moved out into DRM core if we'll wrap panel into
> DRM bridge. This patch wraps RGB panel into a DRM bridge and removes
> manual handling of the panel from the RGB output code.
> 
> Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>

This resulted in the expected simplifications - good.
Acked-by: Sam Ravnborg <sam@ravnborg.org>

> ---
>  drivers/gpu/drm/tegra/rgb.c | 53 +++++++++++++------------------------
>  1 file changed, 18 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
> index 9a7024ec96bc..a4c5a6066c54 100644
> --- a/drivers/gpu/drm/tegra/rgb.c
> +++ b/drivers/gpu/drm/tegra/rgb.c
> @@ -8,7 +8,6 @@
>  
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_bridge_connector.h>
> -#include <drm/drm_panel.h>
>  #include <drm/drm_simple_kms_helper.h>
>  
>  #include "drm.h"
> @@ -86,15 +85,6 @@ static void tegra_dc_write_regs(struct tegra_dc *dc,
>  		tegra_dc_writel(dc, table[i].value, table[i].offset);
>  }
>  
> -static const struct drm_connector_funcs tegra_rgb_connector_funcs = {
> -	.reset = drm_atomic_helper_connector_reset,
> -	.detect = tegra_output_connector_detect,
> -	.fill_modes = drm_helper_probe_single_connector_modes,
> -	.destroy = tegra_output_connector_destroy,
> -	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> -	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> -};
> -
>  static enum drm_mode_status
>  tegra_rgb_connector_mode_valid(struct drm_connector *connector,
>  			       struct drm_display_mode *mode)
> @@ -117,14 +107,8 @@ static void tegra_rgb_encoder_disable(struct drm_encoder *encoder)
>  	struct tegra_output *output = encoder_to_output(encoder);
>  	struct tegra_rgb *rgb = to_rgb(output);
>  
> -	if (output->panel)
> -		drm_panel_disable(output->panel);
> -
>  	tegra_dc_write_regs(rgb->dc, rgb_disable, ARRAY_SIZE(rgb_disable));
>  	tegra_dc_commit(rgb->dc);
> -
> -	if (output->panel)
> -		drm_panel_unprepare(output->panel);
>  }
>  
>  static void tegra_rgb_encoder_enable(struct drm_encoder *encoder)
> @@ -133,9 +117,6 @@ static void tegra_rgb_encoder_enable(struct drm_encoder *encoder)
>  	struct tegra_rgb *rgb = to_rgb(output);
>  	u32 value;
>  
> -	if (output->panel)
> -		drm_panel_prepare(output->panel);
> -
>  	tegra_dc_write_regs(rgb->dc, rgb_enable, ARRAY_SIZE(rgb_enable));
>  
>  	value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL;
> @@ -157,9 +138,6 @@ static void tegra_rgb_encoder_enable(struct drm_encoder *encoder)
>  	tegra_dc_writel(rgb->dc, value, DC_DISP_SHIFT_CLOCK_OPTIONS);
>  
>  	tegra_dc_commit(rgb->dc);
> -
> -	if (output->panel)
> -		drm_panel_enable(output->panel);
>  }
>  
>  static int
> @@ -278,6 +256,23 @@ int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc)
>  	drm_encoder_helper_add(&output->encoder,
>  			       &tegra_rgb_encoder_helper_funcs);
>  
> +	/*
> +	 * Wrap directly-connected panel into DRM bridge in order to let
> +	 * DRM core to handle panel for us.
> +	 */
> +	if (output->panel) {
> +		output->bridge = devm_drm_panel_bridge_add(output->dev,
> +							   output->panel);
> +		if (IS_ERR(output->bridge)) {
> +			dev_err(output->dev,
> +				"failed to wrap panel into bridge: %pe\n",
> +				output->bridge);
> +			return PTR_ERR(output->bridge);
> +		}
> +
> +		output->panel = NULL;
> +	}
> +
>  	/*
>  	 * Tegra devices that have LVDS panel utilize LVDS encoder bridge
>  	 * for converting up to 28 LCD LVTTL lanes into 5/4 LVDS lanes that
> @@ -292,8 +287,7 @@ int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc)
>  	 * Newer device-trees utilize LVDS encoder bridge, which provides
>  	 * us with a connector and handles the display panel.
>  	 *
> -	 * For older device-trees we fall back to our own connector and use
> -	 * nvidia,panel phandle.
> +	 * For older device-trees we wrapped panel into the panel-bridge.
>  	 */
>  	if (output->bridge) {
>  		err = drm_bridge_attach(&output->encoder, output->bridge,
> @@ -313,17 +307,6 @@ int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc)
>  		}
>  
>  		drm_connector_attach_encoder(connector, &output->encoder);
> -	} else {
> -		drm_connector_init(drm, &output->connector,
> -				   &tegra_rgb_connector_funcs,
> -				   DRM_MODE_CONNECTOR_LVDS);
> -		drm_connector_helper_add(&output->connector,
> -					 &tegra_rgb_connector_helper_funcs);
> -		output->connector.dpms = DRM_MODE_DPMS_OFF;
> -
> -		drm_connector_attach_encoder(&output->connector,
> -					     &output->encoder);
> -		drm_connector_register(&output->connector);
>  	}
>  
>  	err = tegra_output_init(drm, output);
> -- 
> 2.26.0
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v5 6/6] drm/tegra: output: rgb: Wrap directly-connected panel into DRM bridge
  2020-04-25 17:02   ` Sam Ravnborg
@ 2020-04-25 21:51     ` Dmitry Osipenko
  0 siblings, 0 replies; 18+ messages in thread
From: Dmitry Osipenko @ 2020-04-25 21:51 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: devicetree, dri-devel, linux-kernel, Rob Herring, Thierry Reding,
	Laurent Pinchart, linux-tegra, Frank Rowand

25.04.2020 20:02, Sam Ravnborg пишет:
> Hi Dmitry
> 
> On Sat, Apr 18, 2020 at 08:07:03PM +0300, Dmitry Osipenko wrote:
>> Currently Tegra DRM driver manually manages display panel, but this
>> management could be moved out into DRM core if we'll wrap panel into
>> DRM bridge. This patch wraps RGB panel into a DRM bridge and removes
>> manual handling of the panel from the RGB output code.
>>
>> Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> 
> This resulted in the expected simplifications - good.
> Acked-by: Sam Ravnborg <sam@ravnborg.org>

Hello Sam,

Thank you for taking a look at this patch! :)
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v5 1/6] of_graph: add of_graph_get_local_port()
  2020-04-18 17:06 ` [PATCH v5 1/6] of_graph: add of_graph_get_local_port() Dmitry Osipenko
@ 2020-04-30 14:10   ` Rob Herring
  2020-05-06 16:32   ` Sam Ravnborg
  1 sibling, 0 replies; 18+ messages in thread
From: Rob Herring @ 2020-04-30 14:10 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Sam Ravnborg, linux-kernel, dri-devel,
	Thierry Reding, Laurent Pinchart, linux-tegra, Frank Rowand

On Sat, 18 Apr 2020 20:06:58 +0300, Dmitry Osipenko wrote:
> In some case, like a DRM display code for example, it's useful to silently
> check whether port node exists at all in a device-tree before proceeding
> with parsing the graph.
> 
> This patch adds of_graph_get_local_port() which returns pointer to a local
> port node, or NULL if graph isn't specified in a device-tree for a given
> device node.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/of/property.c    | 32 +++++++++++++++++++++++---------
>  include/linux/of_graph.h |  7 +++++++
>  2 files changed, 30 insertions(+), 9 deletions(-)
> 

Reviewed-by: Rob Herring <robh@kernel.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v5 1/6] of_graph: add of_graph_get_local_port()
  2020-04-18 17:06 ` [PATCH v5 1/6] of_graph: add of_graph_get_local_port() Dmitry Osipenko
  2020-04-30 14:10   ` Rob Herring
@ 2020-05-06 16:32   ` Sam Ravnborg
  2020-05-11 20:27     ` Rob Herring
  1 sibling, 1 reply; 18+ messages in thread
From: Sam Ravnborg @ 2020-05-06 16:32 UTC (permalink / raw)
  To: Dmitry Osipenko, Rob Herring
  Cc: devicetree, dri-devel, linux-kernel, Rob Herring, Thierry Reding,
	Laurent Pinchart, linux-tegra, Frank Rowand

Hi Dmitry

On Sat, Apr 18, 2020 at 08:06:58PM +0300, Dmitry Osipenko wrote:
> In some case, like a DRM display code for example, it's useful to silently
> check whether port node exists at all in a device-tree before proceeding
> with parsing the graph.
> 
> This patch adds of_graph_get_local_port() which returns pointer to a local
> port node, or NULL if graph isn't specified in a device-tree for a given
> device node.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Nice little helper function.
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>

Rob - OK to commit to drm-misc-next?

	Sam

> ---
>  drivers/of/property.c    | 32 +++++++++++++++++++++++---------
>  include/linux/of_graph.h |  7 +++++++
>  2 files changed, 30 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/of/property.c b/drivers/of/property.c
> index 252e4f600155..5dbeccaabb86 100644
> --- a/drivers/of/property.c
> +++ b/drivers/of/property.c
> @@ -608,15 +608,7 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
>  	 * parent port node.
>  	 */
>  	if (!prev) {
> -		struct device_node *node;
> -
> -		node = of_get_child_by_name(parent, "ports");
> -		if (node)
> -			parent = node;
> -
> -		port = of_get_child_by_name(parent, "port");
> -		of_node_put(node);
> -
> +		port = of_graph_get_local_port(parent);
>  		if (!port) {
>  			pr_err("graph: no port node found in %pOF\n", parent);
>  			return NULL;
> @@ -765,6 +757,28 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
>  }
>  EXPORT_SYMBOL(of_graph_get_remote_port);
>  
> +/**
> + * of_graph_get_local_port() - get local port node
> + * @node: pointer to a local endpoint device_node
> + *
> + * Return: First local port node associated with local endpoint node linked
> + *	   to @node. Use of_node_put() on it when done.
> + */
> +struct device_node *of_graph_get_local_port(const struct device_node *node)
> +{
> +	struct device_node *ports, *port;
> +
> +	ports = of_get_child_by_name(node, "ports");
> +	if (ports)
> +		node = ports;
> +
> +	port = of_get_child_by_name(node, "port");
> +	of_node_put(ports);
> +
> +	return port;
> +}
> +EXPORT_SYMBOL(of_graph_get_local_port);
> +
>  int of_graph_get_endpoint_count(const struct device_node *np)
>  {
>  	struct device_node *endpoint;
> diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
> index 01038a6aade0..1fdeb72c7765 100644
> --- a/include/linux/of_graph.h
> +++ b/include/linux/of_graph.h
> @@ -54,6 +54,7 @@ struct device_node *of_graph_get_remote_port_parent(
>  struct device_node *of_graph_get_remote_port(const struct device_node *node);
>  struct device_node *of_graph_get_remote_node(const struct device_node *node,
>  					     u32 port, u32 endpoint);
> +struct device_node *of_graph_get_local_port(const struct device_node *node);
>  #else
>  
>  static inline int of_graph_parse_endpoint(const struct device_node *node,
> @@ -116,6 +117,12 @@ static inline struct device_node *of_graph_get_remote_node(
>  	return NULL;
>  }
>  
> +static inline struct device_node *of_graph_get_local_port(
> +					const struct device_node *node)
> +{
> +	return NULL;
> +}
> +
>  #endif /* CONFIG_OF */
>  
>  #endif /* __LINUX_OF_GRAPH_H */
> -- 
> 2.26.0
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v5 2/6] drm/of: Make drm_of_find_panel_or_bridge() to check graph's presence
  2020-04-18 17:06 ` [PATCH v5 2/6] drm/of: Make drm_of_find_panel_or_bridge() to check graph's presence Dmitry Osipenko
@ 2020-05-06 16:41   ` Sam Ravnborg
  2020-05-06 17:05     ` Dmitry Osipenko
  0 siblings, 1 reply; 18+ messages in thread
From: Sam Ravnborg @ 2020-05-06 16:41 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, dri-devel, linux-kernel, Rob Herring, Thierry Reding,
	Laurent Pinchart, linux-tegra, Frank Rowand

On Sat, Apr 18, 2020 at 08:06:59PM +0300, Dmitry Osipenko wrote:
> When graph isn't defined in a device-tree, the of_graph_get_remote_node()
> prints a noisy error message, telling that port node is not found. This is
> undesirable behaviour in our case because absence of a panel/bridge graph
> is a valid case. Let's check presence of the local port in a device-tree
> before proceeding with parsing the graph.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
> ---
>  drivers/gpu/drm/drm_of.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
> index b50b44e76279..e0652c38f357 100644
> --- a/drivers/gpu/drm/drm_of.c
> +++ b/drivers/gpu/drm/drm_of.c
> @@ -239,13 +239,24 @@ int drm_of_find_panel_or_bridge(const struct device_node *np,
>  				struct drm_bridge **bridge)
>  {
>  	int ret = -EPROBE_DEFER;
> -	struct device_node *remote;
> +	struct device_node *local, *remote;
>  
>  	if (!panel && !bridge)
>  		return -EINVAL;
>  	if (panel)
>  		*panel = NULL;
>  
> +	/*
> +	 * of_graph_get_remote_node() produces a noisy error message if port
> +	 * node isn't found and the absence of the port is a legit case here,
> +	 * so at first we silently check presence of the local port.
> +	 */
> +	local = of_graph_get_local_port(np);
> +	if (!local)
> +		return -ENODEV;
> +
> +	of_node_put(local);
> +
>  	remote = of_graph_get_remote_node(np, port, endpoint);
>  	if (!remote)
>  		return -ENODEV;
> -- 
> 2.26.0
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v5 3/6] drm/tegra: output: Don't leak OF node on error
  2020-04-18 17:07 ` [PATCH v5 3/6] drm/tegra: output: Don't leak OF node on error Dmitry Osipenko
@ 2020-05-06 16:42   ` Sam Ravnborg
  0 siblings, 0 replies; 18+ messages in thread
From: Sam Ravnborg @ 2020-05-06 16:42 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, dri-devel, linux-kernel, Rob Herring, Thierry Reding,
	Laurent Pinchart, linux-tegra, Frank Rowand

On Sat, Apr 18, 2020 at 08:07:00PM +0300, Dmitry Osipenko wrote:
> The OF node should be put before returning error in tegra_output_probe(),
> otherwise node's refcount will be leaked.
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
> ---
>  drivers/gpu/drm/tegra/output.c | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
> index e36e5e7c2f69..a6a711d54e88 100644
> --- a/drivers/gpu/drm/tegra/output.c
> +++ b/drivers/gpu/drm/tegra/output.c
> @@ -102,10 +102,10 @@ int tegra_output_probe(struct tegra_output *output)
>  	panel = of_parse_phandle(output->of_node, "nvidia,panel", 0);
>  	if (panel) {
>  		output->panel = of_drm_find_panel(panel);
> +		of_node_put(panel);
> +
>  		if (IS_ERR(output->panel))
>  			return PTR_ERR(output->panel);
> -
> -		of_node_put(panel);
>  	}
>  
>  	output->edid = of_get_property(output->of_node, "nvidia,edid", &size);
> @@ -113,13 +113,12 @@ int tegra_output_probe(struct tegra_output *output)
>  	ddc = of_parse_phandle(output->of_node, "nvidia,ddc-i2c-bus", 0);
>  	if (ddc) {
>  		output->ddc = of_find_i2c_adapter_by_node(ddc);
> +		of_node_put(ddc);
> +
>  		if (!output->ddc) {
>  			err = -EPROBE_DEFER;
> -			of_node_put(ddc);
>  			return err;
>  		}
> -
> -		of_node_put(ddc);
>  	}
>  
>  	output->hpd_gpio = devm_gpiod_get_from_of_node(output->dev,
> -- 
> 2.26.0
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v5 4/6] drm/tegra: output: Support DRM bridges
  2020-04-18 17:07 ` [PATCH v5 4/6] drm/tegra: output: Support DRM bridges Dmitry Osipenko
@ 2020-05-06 16:43   ` Sam Ravnborg
  0 siblings, 0 replies; 18+ messages in thread
From: Sam Ravnborg @ 2020-05-06 16:43 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, dri-devel, linux-kernel, Rob Herring, Thierry Reding,
	Laurent Pinchart, linux-tegra, Frank Rowand

On Sat, Apr 18, 2020 at 08:07:01PM +0300, Dmitry Osipenko wrote:
> Newer Tegra device-trees will specify a video output graph which involves
> a bridge. This patch adds initial support for the DRM bridges to the Tegra
> DRM output.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
> ---
>  drivers/gpu/drm/tegra/drm.h    |  2 ++
>  drivers/gpu/drm/tegra/output.c | 12 ++++++++++++
>  2 files changed, 14 insertions(+)
> 
> diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
> index 804869799305..cccd368b6752 100644
> --- a/drivers/gpu/drm/tegra/drm.h
> +++ b/drivers/gpu/drm/tegra/drm.h
> @@ -12,6 +12,7 @@
>  #include <linux/of_gpio.h>
>  
>  #include <drm/drm_atomic.h>
> +#include <drm/drm_bridge.h>
>  #include <drm/drm_edid.h>
>  #include <drm/drm_encoder.h>
>  #include <drm/drm_fb_helper.h>
> @@ -116,6 +117,7 @@ struct tegra_output {
>  	struct device_node *of_node;
>  	struct device *dev;
>  
> +	struct drm_bridge *bridge;
>  	struct drm_panel *panel;
>  	struct i2c_adapter *ddc;
>  	const struct edid *edid;
> diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
> index a6a711d54e88..ccd1421f1b24 100644
> --- a/drivers/gpu/drm/tegra/output.c
> +++ b/drivers/gpu/drm/tegra/output.c
> @@ -5,6 +5,7 @@
>   */
>  
>  #include <drm/drm_atomic_helper.h>
> +#include <drm/drm_of.h>
>  #include <drm/drm_panel.h>
>  #include <drm/drm_simple_kms_helper.h>
>  
> @@ -99,8 +100,19 @@ int tegra_output_probe(struct tegra_output *output)
>  	if (!output->of_node)
>  		output->of_node = output->dev->of_node;
>  
> +	err = drm_of_find_panel_or_bridge(output->of_node, -1, -1,
> +					  &output->panel, &output->bridge);
> +	if (err && err != -ENODEV)
> +		return err;
> +
>  	panel = of_parse_phandle(output->of_node, "nvidia,panel", 0);
>  	if (panel) {
> +		/*
> +		 * Don't mix nvidia,panel phandle with the graph in a
> +		 * device-tree.
> +		 */
> +		WARN_ON(output->panel || output->bridge);
> +
>  		output->panel = of_drm_find_panel(panel);
>  		of_node_put(panel);
>  
> -- 
> 2.26.0
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v5 5/6] drm/tegra: output: rgb: Support LVDS encoder bridge
  2020-04-18 17:07 ` [PATCH v5 5/6] drm/tegra: output: rgb: Support LVDS encoder bridge Dmitry Osipenko
@ 2020-05-06 16:45   ` Sam Ravnborg
  0 siblings, 0 replies; 18+ messages in thread
From: Sam Ravnborg @ 2020-05-06 16:45 UTC (permalink / raw)
  To: Dmitry Osipenko, g
  Cc: devicetree, dri-devel, linux-kernel, Rob Herring, Thierry Reding,
	Laurent Pinchart, linux-tegra, Frank Rowand

On Sat, Apr 18, 2020 at 08:07:02PM +0300, Dmitry Osipenko wrote:
> Newer Tegra device-trees will specify a video output graph, which involves
> LVDS encoder bridge. This patch adds support for the LVDS encoder bridge
> to the RGB output, allowing us to model the display hardware properly.
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
> ---
>  drivers/gpu/drm/tegra/rgb.c | 58 +++++++++++++++++++++++++++++++------
>  1 file changed, 49 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
> index 0562a7eb793f..9a7024ec96bc 100644
> --- a/drivers/gpu/drm/tegra/rgb.c
> +++ b/drivers/gpu/drm/tegra/rgb.c
> @@ -7,6 +7,7 @@
>  #include <linux/clk.h>
>  
>  #include <drm/drm_atomic_helper.h>
> +#include <drm/drm_bridge_connector.h>
>  #include <drm/drm_panel.h>
>  #include <drm/drm_simple_kms_helper.h>
>  
> @@ -267,24 +268,63 @@ int tegra_dc_rgb_remove(struct tegra_dc *dc)
>  int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc)
>  {
>  	struct tegra_output *output = dc->rgb;
> +	struct drm_connector *connector;
>  	int err;
>  
>  	if (!dc->rgb)
>  		return -ENODEV;
>  
> -	drm_connector_init(drm, &output->connector, &tegra_rgb_connector_funcs,
> -			   DRM_MODE_CONNECTOR_LVDS);
> -	drm_connector_helper_add(&output->connector,
> -				 &tegra_rgb_connector_helper_funcs);
> -	output->connector.dpms = DRM_MODE_DPMS_OFF;
> -
>  	drm_simple_encoder_init(drm, &output->encoder, DRM_MODE_ENCODER_LVDS);
>  	drm_encoder_helper_add(&output->encoder,
>  			       &tegra_rgb_encoder_helper_funcs);
>  
> -	drm_connector_attach_encoder(&output->connector,
> -					  &output->encoder);
> -	drm_connector_register(&output->connector);
> +	/*
> +	 * Tegra devices that have LVDS panel utilize LVDS encoder bridge
> +	 * for converting up to 28 LCD LVTTL lanes into 5/4 LVDS lanes that
> +	 * go to display panel's receiver.
> +	 *
> +	 * Encoder usually have a power-down control which needs to be enabled
> +	 * in order to transmit data to the panel.  Historically devices that
> +	 * use an older device-tree version didn't model the bridge, assuming
> +	 * that encoder is turned ON by default, while today's DRM allows us
> +	 * to model LVDS encoder properly.
> +	 *
> +	 * Newer device-trees utilize LVDS encoder bridge, which provides
> +	 * us with a connector and handles the display panel.
> +	 *
> +	 * For older device-trees we fall back to our own connector and use
> +	 * nvidia,panel phandle.
> +	 */
> +	if (output->bridge) {
> +		err = drm_bridge_attach(&output->encoder, output->bridge,
> +					NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +		if (err) {
> +			dev_err(output->dev, "failed to attach bridge: %d\n",
> +				err);
> +			return err;
> +		}
> +
> +		connector = drm_bridge_connector_init(drm, &output->encoder);
> +		if (IS_ERR(connector)) {
> +			dev_err(output->dev,
> +				"failed to initialize bridge connector: %pe\n",
> +				connector);
> +			return PTR_ERR(connector);
> +		}
> +
> +		drm_connector_attach_encoder(connector, &output->encoder);
> +	} else {
> +		drm_connector_init(drm, &output->connector,
> +				   &tegra_rgb_connector_funcs,
> +				   DRM_MODE_CONNECTOR_LVDS);
> +		drm_connector_helper_add(&output->connector,
> +					 &tegra_rgb_connector_helper_funcs);
> +		output->connector.dpms = DRM_MODE_DPMS_OFF;
> +
> +		drm_connector_attach_encoder(&output->connector,
> +					     &output->encoder);
> +		drm_connector_register(&output->connector);
> +	}
>  
>  	err = tegra_output_init(drm, output);
>  	if (err < 0) {
> -- 
> 2.26.0
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v5 2/6] drm/of: Make drm_of_find_panel_or_bridge() to check graph's presence
  2020-05-06 16:41   ` Sam Ravnborg
@ 2020-05-06 17:05     ` Dmitry Osipenko
  0 siblings, 0 replies; 18+ messages in thread
From: Dmitry Osipenko @ 2020-05-06 17:05 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: devicetree, dri-devel, linux-kernel, Rob Herring, Thierry Reding,
	Laurent Pinchart, linux-tegra, Frank Rowand

06.05.2020 19:41, Sam Ravnborg пишет:
> On Sat, Apr 18, 2020 at 08:06:59PM +0300, Dmitry Osipenko wrote:
>> When graph isn't defined in a device-tree, the of_graph_get_remote_node()
>> prints a noisy error message, telling that port node is not found. This is
>> undesirable behaviour in our case because absence of a panel/bridge graph
>> is a valid case. Let's check presence of the local port in a device-tree
>> before proceeding with parsing the graph.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Reviewed-by: Sam Ravnborg <sam@ravnborg.org>

Thank you again for taking a look at these patches!
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v5 1/6] of_graph: add of_graph_get_local_port()
  2020-05-06 16:32   ` Sam Ravnborg
@ 2020-05-11 20:27     ` Rob Herring
  0 siblings, 0 replies; 18+ messages in thread
From: Rob Herring @ 2020-05-11 20:27 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: devicetree, linux-kernel, dri-devel, Thierry Reding,
	Laurent Pinchart, linux-tegra, Dmitry Osipenko, Frank Rowand

On Wed, May 6, 2020 at 11:32 AM Sam Ravnborg <sam@ravnborg.org> wrote:
>
> Hi Dmitry
>
> On Sat, Apr 18, 2020 at 08:06:58PM +0300, Dmitry Osipenko wrote:
> > In some case, like a DRM display code for example, it's useful to silently
> > check whether port node exists at all in a device-tree before proceeding
> > with parsing the graph.
> >
> > This patch adds of_graph_get_local_port() which returns pointer to a local
> > port node, or NULL if graph isn't specified in a device-tree for a given
> > device node.
> >
> > Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Nice little helper function.
> Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
>
> Rob - OK to commit to drm-misc-next?

Yes, that's why I gave my R-by.

Rob
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v5 0/6] Support DRM bridges on NVIDIA Tegra
  2020-04-18 17:06 [PATCH v5 0/6] Support DRM bridges on NVIDIA Tegra Dmitry Osipenko
                   ` (5 preceding siblings ...)
  2020-04-18 17:07 ` [PATCH v5 6/6] drm/tegra: output: rgb: Wrap directly-connected panel into DRM bridge Dmitry Osipenko
@ 2020-05-24 18:41 ` Dmitry Osipenko
  6 siblings, 0 replies; 18+ messages in thread
From: Dmitry Osipenko @ 2020-05-24 18:41 UTC (permalink / raw)
  To: Thierry Reding
  Cc: devicetree, Sam Ravnborg, linux-kernel, dri-devel, Rob Herring,
	Laurent Pinchart, linux-tegra, Frank Rowand

18.04.2020 20:06, Dmitry Osipenko пишет:
> Hello,
> 
> This series adds initial support for the DRM bridges to NVIDIA Tegra DRM
> driver. This is required by newer device-trees where we model the LVDS
> encoder bridge properly.
> 
> Changelog:
> 
> v5: - Added new patches that make drm_of_find_panel_or_bridge() more usable
>       if graph isn't defined in a device-tree:
> 
>         of_graph: add of_graph_get_local_port()
>         drm/of: Make drm_of_find_panel_or_bridge() to check graph's presence
> 
>     - Updated "Support DRM bridges" patch to use drm_of_find_panel_or_bridge()
>       directly and added WARN_ON(output->panel || output->bridge) sanity-check.
> 
>     - Added new "Wrap directly-connected panel into DRM bridge" patch, as
>       was suggested by Laurent Pinchart.
> 
> v4: - Following review comments that were made by Laurent Pinchart to the v3,
>       we now create and use the "bridge connector".
> 
> v3: - Following recommendation from Sam Ravnborg, the new bridge attachment
>       model is now being used, i.e. we ask bridge to *not* create a connector
>       using the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag.
> 
>     - The bridge is now created only for the RGB (LVDS) output, and only
>       when necessary. For now we don't need bridges for HDMI or DSI outputs.
> 
>     - I noticed that we're leaking OF node in the panel's error code path,
>       this is fixed now by the new patch "Don't leak OF node on error".
> 
> v2: - Added the new "rgb: Don't register connector if bridge is used"
>       patch, which hides the unused connector provided by the Tegra DRM
>       driver when bridge is used, since bridge provides its own connector
>       to us.
> 
>     - Please notice that the first "Support DRM bridges" patch was previously
>       sent out as a standalone v1 change.
> 
> Dmitry Osipenko (6):
>   of_graph: add of_graph_get_local_port()
>   drm/of: Make drm_of_find_panel_or_bridge() to check graph's presence
>   drm/tegra: output: Don't leak OF node on error
>   drm/tegra: output: Support DRM bridges
>   drm/tegra: output: rgb: Support LVDS encoder bridge
>   drm/tegra: output: rgb: Wrap directly-connected panel into DRM bridge
> 
>  drivers/gpu/drm/drm_of.c       | 13 +++++-
>  drivers/gpu/drm/tegra/drm.h    |  2 +
>  drivers/gpu/drm/tegra/output.c | 21 +++++++--
>  drivers/gpu/drm/tegra/rgb.c    | 85 +++++++++++++++++++++-------------
>  drivers/of/property.c          | 32 +++++++++----
>  include/linux/of_graph.h       |  7 +++
>  6 files changed, 114 insertions(+), 46 deletions(-)
> 

Hello Thierry,

Do you you have any objections to this series?
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

end of thread, other threads:[~2020-05-25  7:22 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-18 17:06 [PATCH v5 0/6] Support DRM bridges on NVIDIA Tegra Dmitry Osipenko
2020-04-18 17:06 ` [PATCH v5 1/6] of_graph: add of_graph_get_local_port() Dmitry Osipenko
2020-04-30 14:10   ` Rob Herring
2020-05-06 16:32   ` Sam Ravnborg
2020-05-11 20:27     ` Rob Herring
2020-04-18 17:06 ` [PATCH v5 2/6] drm/of: Make drm_of_find_panel_or_bridge() to check graph's presence Dmitry Osipenko
2020-05-06 16:41   ` Sam Ravnborg
2020-05-06 17:05     ` Dmitry Osipenko
2020-04-18 17:07 ` [PATCH v5 3/6] drm/tegra: output: Don't leak OF node on error Dmitry Osipenko
2020-05-06 16:42   ` Sam Ravnborg
2020-04-18 17:07 ` [PATCH v5 4/6] drm/tegra: output: Support DRM bridges Dmitry Osipenko
2020-05-06 16:43   ` Sam Ravnborg
2020-04-18 17:07 ` [PATCH v5 5/6] drm/tegra: output: rgb: Support LVDS encoder bridge Dmitry Osipenko
2020-05-06 16:45   ` Sam Ravnborg
2020-04-18 17:07 ` [PATCH v5 6/6] drm/tegra: output: rgb: Wrap directly-connected panel into DRM bridge Dmitry Osipenko
2020-04-25 17:02   ` Sam Ravnborg
2020-04-25 21:51     ` Dmitry Osipenko
2020-05-24 18:41 ` [PATCH v5 0/6] Support DRM bridges on NVIDIA Tegra Dmitry Osipenko

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