mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
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 <bivvy.bi@rock-chips.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user