aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/dsi/dsi_manager.c
diff options
context:
space:
mode:
authorArchit Taneja <architt@codeaurora.org>2015-07-31 04:36:10 -0400
committerRob Clark <robdclark@gmail.com>2015-08-15 18:27:25 -0400
commitc118e29033aa5b38b593ebd0e02f8b1224c20ed3 (patch)
tree0e5fc90b41d59377dfb0928f45cda2f32f78ee06 /drivers/gpu/drm/msm/dsi/dsi_manager.c
parent6f054ec5b9ced3041f29541ae79402198678fc06 (diff)
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 60dbd829d7a9..dc3d322375e9 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 = {
517 .mode_set = dsi_mgr_bridge_mode_set, 517 .mode_set = dsi_mgr_bridge_mode_set,
518}; 518};
519 519
520/* initialize connector */ 520/* initialize connector when we're connected to a drm_panel */
521struct drm_connector *msm_dsi_manager_connector_init(u8 id) 521struct drm_connector *msm_dsi_manager_connector_init(u8 id)
522{ 522{
523 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 523 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
@@ -602,6 +602,53 @@ fail:
602 return ERR_PTR(ret); 602 return ERR_PTR(ret);
603} 603}
604 604
605struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id)
606{
607 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
608 struct drm_device *dev = msm_dsi->dev;
609 struct drm_encoder *encoder;
610 struct drm_bridge *int_bridge, *ext_bridge;
611 struct drm_connector *connector;
612 struct list_head *connector_list;
613
614 int_bridge = msm_dsi->bridge;
615 ext_bridge = msm_dsi->external_bridge =
616 msm_dsi_host_get_bridge(msm_dsi->host);
617
618 /*
619 * HACK: we may not know the external DSI bridge device's mode
620 * flags here. We'll get to know them only when the device
621 * attaches to the dsi host. For now, assume the bridge supports
622 * DSI video mode
623 */
624 encoder = msm_dsi->encoders[MSM_DSI_VIDEO_ENCODER_ID];
625
626 /* link the internal dsi bridge to the external bridge */
627 int_bridge->next = ext_bridge;
628 /* set the external bridge's encoder as dsi's encoder */
629 ext_bridge->encoder = encoder;
630
631 drm_bridge_attach(dev, ext_bridge);
632
633 /*
634 * we need the drm_connector created by the external bridge
635 * driver (or someone else) to feed it to our driver's
636 * priv->connector[] list, mainly for msm_fbdev_init()
637 */
638 connector_list = &dev->mode_config.connector_list;
639
640 list_for_each_entry(connector, connector_list, head) {
641 int i;
642
643 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
644 if (connector->encoder_ids[i] == encoder->base.id)
645 return connector;
646 }
647 }
648
649 return ERR_PTR(-ENODEV);
650}
651
605void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge) 652void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge)
606{ 653{
607} 654}