drm/rockchip: get connector in bridge mode
authorHuang Jiachai <hjc@rock-chips.com>
Mon, 31 Jul 2017 11:53:15 +0000 (19:53 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Thu, 3 Aug 2017 12:25:32 +0000 (20:25 +0800)
Change-Id: I08535f5c2d83783dc86ae641daeb530dedec36e6
Signed-off-by: Huang Jiachai <hjc@rock-chips.com>
drivers/gpu/drm/rockchip/rockchip_drm_drv.c
drivers/gpu/drm/rockchip/rockchip_lvds.c
include/drm/drm_crtc.h

index 76151586df6ef55d5386e66edead5336984435c3..bc42cbc77bdb63074f5dd1fa87be1f98f2a690b3 100644 (file)
@@ -106,6 +106,74 @@ static struct drm_connector *find_connector_by_node(struct drm_device *drm_dev,
        return NULL;
 }
 
+static
+struct drm_connector *find_connector_by_bridge(struct drm_device *drm_dev,
+                                              struct device_node *node)
+{
+       struct device_node *np_encoder, *np_connector;
+       struct drm_encoder *encoder;
+       struct drm_connector *connector = NULL;
+       struct device_node *port, *endpoint;
+       bool encoder_bridge = false;
+       bool found_connector = false;
+
+       np_encoder = of_graph_get_remote_port_parent(node);
+       if (!np_encoder || !of_device_is_available(np_encoder))
+               goto err_put_encoder;
+       drm_for_each_encoder(encoder, drm_dev) {
+               if (encoder->port == np_encoder && encoder->bridge) {
+                       encoder_bridge = true;
+                       break;
+               }
+       }
+       if (!encoder_bridge) {
+               dev_err(drm_dev->dev, "can't found encoder bridge!\n");
+               goto err_put_encoder;
+       }
+       port = of_graph_get_port_by_id(np_encoder, 1);
+       if (!port) {
+               dev_err(drm_dev->dev, "can't found port point!\n");
+               goto err_put_encoder;
+       }
+       for_each_child_of_node(port, endpoint) {
+               np_connector = of_graph_get_remote_port_parent(endpoint);
+               if (!np_connector) {
+                       dev_err(drm_dev->dev,
+                               "can't found connector node, please init!\n");
+                       goto err_put_port;
+               }
+               if (!of_device_is_available(np_connector)) {
+                       of_node_put(np_connector);
+                       np_connector = NULL;
+                       continue;
+               } else {
+                       break;
+               }
+       }
+       if (!np_connector) {
+               dev_err(drm_dev->dev, "can't found available connector node!\n");
+               goto err_put_port;
+       }
+
+       drm_for_each_connector(connector, drm_dev) {
+               if (connector->port == np_connector) {
+                       found_connector = true;
+                       break;
+               }
+       }
+
+       if (!found_connector)
+               connector = NULL;
+
+       of_node_put(np_connector);
+err_put_port:
+       of_node_put(port);
+err_put_encoder:
+       of_node_put(np_encoder);
+
+       return connector;
+}
+
 void rockchip_free_loader_memory(struct drm_device *drm)
 {
        struct rockchip_drm_private *private = drm->dev_private;
@@ -298,6 +366,8 @@ of_parse_display_resource(struct drm_device *drm_dev, struct device_node *route)
 
        crtc = find_crtc_by_node(drm_dev, connect);
        connector = find_connector_by_node(drm_dev, connect);
+       if (!connector)
+               connector = find_connector_by_bridge(drm_dev, connect);
        if (!crtc || !connector) {
                dev_warn(drm_dev->dev,
                         "No available crtc or connector for display");
index 4b424911447752b4175df7df4d521663143077f4..ad497552b5ea6f09f6bb14e6acdd487b82092125 100644 (file)
@@ -821,6 +821,7 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master,
        }
 
        drm_encoder_helper_add(encoder, &rockchip_lvds_encoder_helper_funcs);
+       encoder->port = dev->of_node;
 
        if (lvds->panel) {
                connector = &lvds->connector;
index 1b904d9d280868dfe729dd69f8eda1e217e73267..5d7b55c1b9111669f9dda52fe39fe9e7e4cbef25 100644 (file)
@@ -722,6 +722,7 @@ struct drm_encoder_funcs {
 /**
  * struct drm_encoder - central DRM encoder structure
  * @dev: parent DRM device
+ * @port: OF node used by find encoder by node
  * @head: list management
  * @base: base KMS object
  * @name: encoder name
@@ -738,6 +739,7 @@ struct drm_encoder_funcs {
  */
 struct drm_encoder {
        struct drm_device *dev;
+       struct device_node *port;
        struct list_head head;
 
        struct drm_mode_object base;