summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/dsi/dsi_manager.c
diff options
context:
space:
mode:
authorArchit Taneja <architt@codeaurora.org>2015-07-31 08:36:10 (GMT)
committerRob Clark <robdclark@gmail.com>2015-08-15 22:27:25 (GMT)
commitc118e29033aa5b38b593ebd0e02f8b1224c20ed3 (patch)
tree0e5fc90b41d59377dfb0928f45cda2f32f78ee06 /drivers/gpu/drm/msm/dsi/dsi_manager.c
parent6f054ec5b9ced3041f29541ae79402198678fc06 (diff)
downloadlinux-c118e29033aa5b38b593ebd0e02f8b1224c20ed3.tar.xz
drm/msm/dsi: Allow dsi to connect to an external bridge
There are platforms where the DSI output can be connected to another encoder bridge chip (DSI to HDMI, DSI to LVDS etc). Add support for external bridge support to the dsi driver. We assume that the external bridge chip would be of the type drm_bridge. The dsi driver's internal drm_bridge (msm_dsi->bridge) is linked to the external bridge's drm_bridge struct. In the case we're connected to an external bridge, we don't need to create and manage a connector within our driver, it's the bridge driver's responsibility to create one. v2: - Move the external bridge attaching stuff to dsi manager to make things cleaner. - Force the bridge to connect to a video mode encoder for now (the dsi mode flags may have not been populated by modeset_init) Signed-off-by: Archit Taneja <architt@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/dsi/dsi_manager.c')
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_manager.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index 60dbd82..dc3d322 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -517,7 +517,7 @@ static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = {
.mode_set = dsi_mgr_bridge_mode_set,
};
-/* initialize connector */
+/* initialize connector when we're connected to a drm_panel */
struct drm_connector *msm_dsi_manager_connector_init(u8 id)
{
struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
@@ -602,6 +602,53 @@ fail:
return ERR_PTR(ret);
}
+struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id)
+{
+ struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+ struct drm_device *dev = msm_dsi->dev;
+ struct drm_encoder *encoder;
+ struct drm_bridge *int_bridge, *ext_bridge;
+ struct drm_connector *connector;
+ struct list_head *connector_list;
+
+ int_bridge = msm_dsi->bridge;
+ ext_bridge = msm_dsi->external_bridge =
+ msm_dsi_host_get_bridge(msm_dsi->host);
+
+ /*
+ * HACK: we may not know the external DSI bridge device's mode
+ * flags here. We'll get to know them only when the device
+ * attaches to the dsi host. For now, assume the bridge supports
+ * DSI video mode
+ */
+ encoder = msm_dsi->encoders[MSM_DSI_VIDEO_ENCODER_ID];
+
+ /* link the internal dsi bridge to the external bridge */
+ int_bridge->next = ext_bridge;
+ /* set the external bridge's encoder as dsi's encoder */
+ ext_bridge->encoder = encoder;
+
+ drm_bridge_attach(dev, ext_bridge);
+
+ /*
+ * we need the drm_connector created by the external bridge
+ * driver (or someone else) to feed it to our driver's
+ * priv->connector[] list, mainly for msm_fbdev_init()
+ */
+ connector_list = &dev->mode_config.connector_list;
+
+ list_for_each_entry(connector, connector_list, head) {
+ int i;
+
+ for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+ if (connector->encoder_ids[i] == encoder->base.id)
+ return connector;
+ }
+ }
+
+ return ERR_PTR(-ENODEV);
+}
+
void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge)
{
}