From d6653db29af448e1c72a04729a3ca15db08a46e2 Mon Sep 17 00:00:00 2001 From: Wyon Bi Date: Thu, 18 Apr 2019 15:47:09 +0800 Subject: [PATCH] drm/bridge: analogix_dp: Add support for external bridge The current output code only supports connection to drm panels. Add code to support drm bridge, to support connections to external connectors. Change-Id: I6ea64b652d1f513fa9ccf25a66568c8932a60464 Signed-off-by: Wyon Bi --- .../drm/bridge/analogix/analogix_dp_core.c | 65 +++++++++++-------- .../gpu/drm/rockchip/analogix_dp-rockchip.c | 31 ++------- include/drm/bridge/analogix_dp.h | 1 + 3 files changed, 45 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 90cd6b1d6f59..1656824ab99d 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -938,37 +938,48 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge) return -ENODEV; } - connector->polled = DRM_CONNECTOR_POLL_HPD; - connector->port = dp->dev->of_node; + if (dp->plat_data->bridge) { + dp->plat_data->bridge->encoder = encoder; - ret = drm_connector_init(dp->drm_dev, connector, - &analogix_dp_connector_funcs, - DRM_MODE_CONNECTOR_eDP); - if (ret) { - DRM_ERROR("Failed to initialize connector with drm\n"); - return ret; - } + ret = drm_bridge_attach(bridge->dev, dp->plat_data->bridge); + if (ret) { + DRM_ERROR("failed to attach bridge: %d\n", ret); + return ret; + } - drm_connector_helper_add(connector, - &analogix_dp_connector_helper_funcs); - drm_mode_connector_attach_encoder(connector, encoder); + bridge->next = dp->plat_data->bridge; + } else { + connector->polled = DRM_CONNECTOR_POLL_HPD; + connector->port = dp->dev->of_node; - /* - * NOTE: the connector registration is implemented in analogix - * platform driver, that to say connector would be exist after - * plat_data->attch return, that's why we record the connector - * point after plat attached. - */ - if (dp->plat_data->attach) { - ret = dp->plat_data->attach(dp->plat_data, bridge, connector); - if (ret) { - DRM_ERROR("Failed at platform attch func\n"); - return ret; - } - } + ret = drm_connector_init(dp->drm_dev, connector, + &analogix_dp_connector_funcs, + DRM_MODE_CONNECTOR_eDP); + if (ret) { + DRM_ERROR("Failed to initialize connector with drm\n"); + return ret; + } - if (dp->plat_data->panel) { - ret = drm_panel_attach(dp->plat_data->panel, &dp->connector); + drm_connector_helper_add(connector, + &analogix_dp_connector_helper_funcs); + drm_mode_connector_attach_encoder(connector, encoder); + + /* + * NOTE: the connector registration is implemented in analogix + * platform driver, that to say connector would be exist after + * plat_data->attch return, that's why we record the connector + * point after plat attached. + */ + if (dp->plat_data->attach) { + ret = dp->plat_data->attach(dp->plat_data, bridge, + connector); + if (ret) { + DRM_ERROR("Failed at platform attch func\n"); + return ret; + } + } + + ret = drm_panel_attach(dp->plat_data->panel, connector); if (ret) { DRM_ERROR("Failed to attach panel\n"); return ret; diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 71d965d8bfe2..86a168a5c2c3 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -325,6 +325,7 @@ static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp) struct device *dev = dp->dev; int ret; + encoder->port = dev->of_node; encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, dev->of_node); DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs); @@ -346,37 +347,17 @@ static int rockchip_dp_bind(struct device *dev, struct device *master, { struct rockchip_dp_device *dp = dev_get_drvdata(dev); const struct rockchip_dp_chip_data *dp_data; - struct device_node *panel_node, *port, *endpoint; struct drm_panel *panel = NULL; + struct drm_bridge *bridge = NULL; struct drm_device *drm_dev = data; int ret; - port = of_graph_get_port_by_id(dev->of_node, 1); - if (port) { - endpoint = of_get_child_by_name(port, "endpoint"); - of_node_put(port); - if (!endpoint) { - dev_err(dev, "no output endpoint found\n"); - return -EINVAL; - } - - panel_node = of_graph_get_remote_port_parent(endpoint); - of_node_put(endpoint); - if (!panel_node) { - dev_err(dev, "no output node found\n"); - return -EINVAL; - } - - panel = of_drm_find_panel(panel_node); - if (!panel) { - DRM_ERROR("failed to find panel\n"); - of_node_put(panel_node); - return -EPROBE_DEFER; - } - of_node_put(panel_node); - } + ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, &bridge); + if (ret) + return ret; dp->plat_data.panel = panel; + dp->plat_data.bridge = bridge; dp_data = of_device_get_match_data(dev); if (!dp_data) diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h index 05c73743c6da..27d1f704e520 100644 --- a/include/drm/bridge/analogix_dp.h +++ b/include/drm/bridge/analogix_dp.h @@ -30,6 +30,7 @@ struct analogix_dp_plat_data { enum analogix_dp_devtype dev_type; enum analogix_dp_sub_devtype subdev_type; struct drm_panel *panel; + struct drm_bridge *bridge; struct drm_encoder *encoder; struct drm_connector *connector;