aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/dsi/dsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/dsi/dsi.c')
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi.c58
1 files changed, 35 insertions, 23 deletions
diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
index 1f2561e2ff71..6edcd6f57e70 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.c
+++ b/drivers/gpu/drm/msm/dsi/dsi.c
@@ -15,10 +15,10 @@
15 15
16struct drm_encoder *msm_dsi_get_encoder(struct msm_dsi *msm_dsi) 16struct drm_encoder *msm_dsi_get_encoder(struct msm_dsi *msm_dsi)
17{ 17{
18 if (!msm_dsi || !msm_dsi->panel) 18 if (!msm_dsi || !msm_dsi_device_connected(msm_dsi))
19 return NULL; 19 return NULL;
20 20
21 return (msm_dsi->panel_flags & MIPI_DSI_MODE_VIDEO) ? 21 return (msm_dsi->device_flags & MIPI_DSI_MODE_VIDEO) ?
22 msm_dsi->encoders[MSM_DSI_VIDEO_ENCODER_ID] : 22 msm_dsi->encoders[MSM_DSI_VIDEO_ENCODER_ID] :
23 msm_dsi->encoders[MSM_DSI_CMD_ENCODER_ID]; 23 msm_dsi->encoders[MSM_DSI_CMD_ENCODER_ID];
24} 24}
@@ -74,19 +74,15 @@ static void dsi_destroy(struct msm_dsi *msm_dsi)
74 74
75static struct msm_dsi *dsi_init(struct platform_device *pdev) 75static struct msm_dsi *dsi_init(struct platform_device *pdev)
76{ 76{
77 struct msm_dsi *msm_dsi = NULL; 77 struct msm_dsi *msm_dsi;
78 int ret; 78 int ret;
79 79
80 if (!pdev) { 80 if (!pdev)
81 ret = -ENXIO; 81 return ERR_PTR(-ENXIO);
82 goto fail;
83 }
84 82
85 msm_dsi = devm_kzalloc(&pdev->dev, sizeof(*msm_dsi), GFP_KERNEL); 83 msm_dsi = devm_kzalloc(&pdev->dev, sizeof(*msm_dsi), GFP_KERNEL);
86 if (!msm_dsi) { 84 if (!msm_dsi)
87 ret = -ENOMEM; 85 return ERR_PTR(-ENOMEM);
88 goto fail;
89 }
90 DBG("dsi probed=%p", msm_dsi); 86 DBG("dsi probed=%p", msm_dsi);
91 87
92 msm_dsi->pdev = pdev; 88 msm_dsi->pdev = pdev;
@@ -95,24 +91,22 @@ static struct msm_dsi *dsi_init(struct platform_device *pdev)
95 /* Init dsi host */ 91 /* Init dsi host */
96 ret = msm_dsi_host_init(msm_dsi); 92 ret = msm_dsi_host_init(msm_dsi);
97 if (ret) 93 if (ret)
98 goto fail; 94 goto destroy_dsi;
99 95
100 /* GET dsi PHY */ 96 /* GET dsi PHY */
101 ret = dsi_get_phy(msm_dsi); 97 ret = dsi_get_phy(msm_dsi);
102 if (ret) 98 if (ret)
103 goto fail; 99 goto destroy_dsi;
104 100
105 /* Register to dsi manager */ 101 /* Register to dsi manager */
106 ret = msm_dsi_manager_register(msm_dsi); 102 ret = msm_dsi_manager_register(msm_dsi);
107 if (ret) 103 if (ret)
108 goto fail; 104 goto destroy_dsi;
109 105
110 return msm_dsi; 106 return msm_dsi;
111 107
112fail: 108destroy_dsi:
113 if (msm_dsi) 109 dsi_destroy(msm_dsi);
114 dsi_destroy(msm_dsi);
115
116 return ERR_PTR(ret); 110 return ERR_PTR(ret);
117} 111}
118 112
@@ -196,6 +190,7 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
196 struct drm_encoder *encoders[MSM_DSI_ENCODER_NUM]) 190 struct drm_encoder *encoders[MSM_DSI_ENCODER_NUM])
197{ 191{
198 struct msm_drm_private *priv = dev->dev_private; 192 struct msm_drm_private *priv = dev->dev_private;
193 struct drm_bridge *ext_bridge;
199 int ret, i; 194 int ret, i;
200 195
201 if (WARN_ON(!encoders[MSM_DSI_VIDEO_ENCODER_ID] || 196 if (WARN_ON(!encoders[MSM_DSI_VIDEO_ENCODER_ID] ||
@@ -223,10 +218,25 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
223 msm_dsi->encoders[i] = encoders[i]; 218 msm_dsi->encoders[i] = encoders[i];
224 } 219 }
225 220
226 msm_dsi->connector = msm_dsi_manager_connector_init(msm_dsi->id); 221 /*
222 * check if the dsi encoder output is connected to a panel or an
223 * external bridge. We create a connector only if we're connected to a
224 * drm_panel device. When we're connected to an external bridge, we
225 * assume that the drm_bridge driver will create the connector itself.
226 */
227 ext_bridge = msm_dsi_host_get_bridge(msm_dsi->host);
228
229 if (ext_bridge)
230 msm_dsi->connector =
231 msm_dsi_manager_ext_bridge_init(msm_dsi->id);
232 else
233 msm_dsi->connector =
234 msm_dsi_manager_connector_init(msm_dsi->id);
235
227 if (IS_ERR(msm_dsi->connector)) { 236 if (IS_ERR(msm_dsi->connector)) {
228 ret = PTR_ERR(msm_dsi->connector); 237 ret = PTR_ERR(msm_dsi->connector);
229 dev_err(dev->dev, "failed to create dsi connector: %d\n", ret); 238 dev_err(dev->dev,
239 "failed to create dsi connector: %d\n", ret);
230 msm_dsi->connector = NULL; 240 msm_dsi->connector = NULL;
231 goto fail; 241 goto fail;
232 } 242 }
@@ -242,10 +252,12 @@ fail:
242 msm_dsi_manager_bridge_destroy(msm_dsi->bridge); 252 msm_dsi_manager_bridge_destroy(msm_dsi->bridge);
243 msm_dsi->bridge = NULL; 253 msm_dsi->bridge = NULL;
244 } 254 }
245 if (msm_dsi->connector) { 255
256 /* don't destroy connector if we didn't make it */
257 if (msm_dsi->connector && !msm_dsi->external_bridge)
246 msm_dsi->connector->funcs->destroy(msm_dsi->connector); 258 msm_dsi->connector->funcs->destroy(msm_dsi->connector);
247 msm_dsi->connector = NULL; 259
248 } 260 msm_dsi->connector = NULL;
249 } 261 }
250 262
251 return ret; 263 return ret;