drm: rcar-du: lvds: Improve identification of panels
authorFabrizio Castro <fabrizio.castro@bp.renesas.com>
Tue, 17 Dec 2019 13:45:57 +0000 (13:45 +0000)
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Wed, 18 Dec 2019 00:40:19 +0000 (02:40 +0200)
Dual-LVDS panels are mistakenly identified as bridges, this
commit replaces the current logic with a call to
drm_of_find_panel_or_bridge to sort that out.

Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
drivers/gpu/drm/rcar-du/rcar_lvds.c

index 284f10d..ec63546 100644 (file)
@@ -21,6 +21,7 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_bridge.h>
+#include <drm/drm_of.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_probe_helper.h>
 
@@ -712,79 +713,23 @@ done:
 
 static int rcar_lvds_parse_dt(struct rcar_lvds *lvds)
 {
-       struct device_node *local_output = NULL;
-       struct device_node *remote_input = NULL;
-       struct device_node *remote = NULL;
-       struct device_node *node;
-       bool is_bridge = false;
-       int ret = 0;
-
-       local_output = of_graph_get_endpoint_by_regs(lvds->dev->of_node, 1, 0);
-       if (!local_output) {
-               dev_dbg(lvds->dev, "unconnected port@1\n");
-               ret = -ENODEV;
-               goto done;
-       }
-
-       /*
-        * Locate the connected entity and infer its type from the number of
-        * endpoints.
-        */
-       remote = of_graph_get_remote_port_parent(local_output);
-       if (!remote) {
-               dev_dbg(lvds->dev, "unconnected endpoint %pOF\n", local_output);
-               ret = -ENODEV;
-               goto done;
-       }
+       int ret;
 
-       if (!of_device_is_available(remote)) {
-               dev_dbg(lvds->dev, "connected entity %pOF is disabled\n",
-                       remote);
-               ret = -ENODEV;
+       ret = drm_of_find_panel_or_bridge(lvds->dev->of_node, 1, 0,
+                                         &lvds->panel, &lvds->next_bridge);
+       if (ret)
                goto done;
-       }
 
-       remote_input = of_graph_get_remote_endpoint(local_output);
-
-       for_each_endpoint_of_node(remote, node) {
-               if (node != remote_input) {
-                       /*
-                        * We've found one endpoint other than the input, this
-                        * must be a bridge.
-                        */
-                       is_bridge = true;
-                       of_node_put(node);
-                       break;
-               }
-       }
-
-       if (is_bridge) {
-               lvds->next_bridge = of_drm_find_bridge(remote);
-               if (!lvds->next_bridge) {
-                       ret = -EPROBE_DEFER;
-                       goto done;
-               }
-
-               if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK)
-                       lvds->dual_link = lvds->next_bridge->timings
-                                       ? lvds->next_bridge->timings->dual_link
-                                       : false;
-       } else {
-               lvds->panel = of_drm_find_panel(remote);
-               if (IS_ERR(lvds->panel)) {
-                       ret = PTR_ERR(lvds->panel);
-                       goto done;
-               }
-       }
+       if ((lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK) &&
+           lvds->next_bridge)
+               lvds->dual_link = lvds->next_bridge->timings
+                               ? lvds->next_bridge->timings->dual_link
+                               : false;
 
        if (lvds->dual_link)
                ret = rcar_lvds_parse_dt_companion(lvds);
 
 done:
-       of_node_put(local_output);
-       of_node_put(remote_input);
-       of_node_put(remote);
-
        /*
         * On D3/E3 the LVDS encoder provides a clock to the DU, which can be
         * used for the DPAD output even when the LVDS output is not connected.