diff options
author | Archit Taneja <architt@codeaurora.org> | 2015-10-19 02:50:52 -0400 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2015-12-14 10:39:30 -0500 |
commit | ec141af624bbd3932aab90b85e1fabe7fa1ca70b (patch) | |
tree | c5054a036af8ac2d5b6bd412fbb4466a9cca86d7 /drivers/gpu/drm/msm | |
parent | 66a42f8586897c3a95ac2fef5e2ee1e69da695c8 (diff) |
drm/msm/mdp4: Clean up modeset_init
modeset_init() for mdp4 isn't very flexible. That makes it hard to add
more interfaces.
Split out the encoder/connector creation code in modeset_init into a
separate function. This is similar to what's done in modeset_init for
mdp5.
Signed-off-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm')
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 192 |
1 files changed, 109 insertions, 83 deletions
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c index 76984a8d038c..379b43521853 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | |||
@@ -270,117 +270,143 @@ static struct drm_panel *detect_panel(struct drm_device *dev) | |||
270 | return panel; | 270 | return panel; |
271 | } | 271 | } |
272 | 272 | ||
273 | static int modeset_init(struct mdp4_kms *mdp4_kms) | 273 | static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms, |
274 | int intf_type) | ||
274 | { | 275 | { |
275 | struct drm_device *dev = mdp4_kms->dev; | 276 | struct drm_device *dev = mdp4_kms->dev; |
276 | struct msm_drm_private *priv = dev->dev_private; | 277 | struct msm_drm_private *priv = dev->dev_private; |
277 | struct drm_plane *plane; | ||
278 | struct drm_crtc *crtc; | ||
279 | struct drm_encoder *encoder; | 278 | struct drm_encoder *encoder; |
280 | struct drm_connector *connector; | 279 | struct drm_connector *connector; |
281 | struct drm_panel *panel; | 280 | struct drm_panel *panel; |
282 | int ret; | 281 | int ret; |
283 | 282 | ||
284 | /* construct non-private planes: */ | 283 | switch (intf_type) { |
285 | plane = mdp4_plane_init(dev, VG1, false); | 284 | case DRM_MODE_ENCODER_LVDS: |
286 | if (IS_ERR(plane)) { | 285 | panel = detect_panel(dev); |
287 | dev_err(dev->dev, "failed to construct plane for VG1\n"); | 286 | if (IS_ERR(panel)) { |
288 | ret = PTR_ERR(plane); | 287 | dev_err(dev->dev, "failed to detect LVDS panel\n"); |
289 | goto fail; | 288 | return PTR_ERR(panel); |
290 | } | 289 | } |
291 | priv->planes[priv->num_planes++] = plane; | ||
292 | 290 | ||
293 | plane = mdp4_plane_init(dev, VG2, false); | 291 | encoder = mdp4_lcdc_encoder_init(dev, panel); |
294 | if (IS_ERR(plane)) { | 292 | if (IS_ERR(encoder)) { |
295 | dev_err(dev->dev, "failed to construct plane for VG2\n"); | 293 | dev_err(dev->dev, "failed to construct LCDC encoder\n"); |
296 | ret = PTR_ERR(plane); | 294 | return PTR_ERR(encoder); |
297 | goto fail; | 295 | } |
298 | } | ||
299 | priv->planes[priv->num_planes++] = plane; | ||
300 | 296 | ||
301 | /* | 297 | /* LCDC can be hooked to DMA_P (TODO: Add DMA_S later?) */ |
302 | * Setup the LCDC/LVDS path: RGB2 -> DMA_P -> LCDC -> LVDS: | 298 | encoder->possible_crtcs = 1 << DMA_P; |
303 | */ | ||
304 | 299 | ||
305 | panel = detect_panel(dev); | 300 | connector = mdp4_lvds_connector_init(dev, panel, encoder); |
306 | if (IS_ERR(panel)) { | 301 | if (IS_ERR(connector)) { |
307 | ret = PTR_ERR(panel); | 302 | dev_err(dev->dev, "failed to initialize LVDS connector\n"); |
308 | dev_err(dev->dev, "failed to detect LVDS panel: %d\n", ret); | 303 | return PTR_ERR(connector); |
309 | goto fail; | 304 | } |
310 | } | ||
311 | 305 | ||
312 | plane = mdp4_plane_init(dev, RGB2, true); | 306 | priv->encoders[priv->num_encoders++] = encoder; |
313 | if (IS_ERR(plane)) { | 307 | priv->connectors[priv->num_connectors++] = connector; |
314 | dev_err(dev->dev, "failed to construct plane for RGB2\n"); | ||
315 | ret = PTR_ERR(plane); | ||
316 | goto fail; | ||
317 | } | ||
318 | 308 | ||
319 | crtc = mdp4_crtc_init(dev, plane, priv->num_crtcs, 0, DMA_P); | 309 | break; |
320 | if (IS_ERR(crtc)) { | 310 | case DRM_MODE_ENCODER_TMDS: |
321 | dev_err(dev->dev, "failed to construct crtc for DMA_P\n"); | 311 | encoder = mdp4_dtv_encoder_init(dev); |
322 | ret = PTR_ERR(crtc); | 312 | if (IS_ERR(encoder)) { |
323 | goto fail; | 313 | dev_err(dev->dev, "failed to construct DTV encoder\n"); |
324 | } | 314 | return PTR_ERR(encoder); |
315 | } | ||
325 | 316 | ||
326 | encoder = mdp4_lcdc_encoder_init(dev, panel); | 317 | /* DTV can be hooked to DMA_E: */ |
327 | if (IS_ERR(encoder)) { | 318 | encoder->possible_crtcs = 1 << 1; |
328 | dev_err(dev->dev, "failed to construct LCDC encoder\n"); | ||
329 | ret = PTR_ERR(encoder); | ||
330 | goto fail; | ||
331 | } | ||
332 | 319 | ||
333 | /* LCDC can be hooked to DMA_P: */ | 320 | if (priv->hdmi) { |
334 | encoder->possible_crtcs = 1 << priv->num_crtcs; | 321 | /* Construct bridge/connector for HDMI: */ |
322 | ret = hdmi_modeset_init(priv->hdmi, dev, encoder); | ||
323 | if (ret) { | ||
324 | dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret); | ||
325 | return ret; | ||
326 | } | ||
327 | } | ||
335 | 328 | ||
336 | priv->crtcs[priv->num_crtcs++] = crtc; | 329 | priv->encoders[priv->num_encoders++] = encoder; |
337 | priv->encoders[priv->num_encoders++] = encoder; | ||
338 | 330 | ||
339 | connector = mdp4_lvds_connector_init(dev, panel, encoder); | 331 | break; |
340 | if (IS_ERR(connector)) { | 332 | default: |
341 | ret = PTR_ERR(connector); | 333 | dev_err(dev->dev, "Invalid or unsupported interface\n"); |
342 | dev_err(dev->dev, "failed to initialize LVDS connector: %d\n", ret); | 334 | return -EINVAL; |
343 | goto fail; | ||
344 | } | 335 | } |
345 | 336 | ||
346 | priv->connectors[priv->num_connectors++] = connector; | ||
347 | 337 | ||
348 | /* | 338 | return 0; |
349 | * Setup DTV/HDMI path: RGB1 -> DMA_E -> DTV -> HDMI: | 339 | } |
350 | */ | ||
351 | 340 | ||
352 | plane = mdp4_plane_init(dev, RGB1, true); | 341 | static int modeset_init(struct mdp4_kms *mdp4_kms) |
353 | if (IS_ERR(plane)) { | 342 | { |
354 | dev_err(dev->dev, "failed to construct plane for RGB1\n"); | 343 | struct drm_device *dev = mdp4_kms->dev; |
355 | ret = PTR_ERR(plane); | 344 | struct msm_drm_private *priv = dev->dev_private; |
356 | goto fail; | 345 | struct drm_plane *plane; |
357 | } | 346 | struct drm_crtc *crtc; |
347 | int i, ret; | ||
348 | static const enum mdp4_pipe rgb_planes[] = { | ||
349 | RGB1, RGB2, | ||
350 | }; | ||
351 | static const enum mdp4_pipe vg_planes[] = { | ||
352 | VG1, VG2, | ||
353 | }; | ||
354 | static const enum mdp4_dma mdp4_crtcs[] = { | ||
355 | DMA_P, DMA_E, | ||
356 | }; | ||
357 | static const char * const mdp4_crtc_names[] = { | ||
358 | "DMA_P", "DMA_E", | ||
359 | }; | ||
360 | static const int mdp4_intfs[] = { | ||
361 | DRM_MODE_ENCODER_LVDS, | ||
362 | DRM_MODE_ENCODER_TMDS, | ||
363 | }; | ||
358 | 364 | ||
359 | crtc = mdp4_crtc_init(dev, plane, priv->num_crtcs, 1, DMA_E); | 365 | /* construct non-private planes: */ |
360 | if (IS_ERR(crtc)) { | 366 | for (i = 0; i < ARRAY_SIZE(vg_planes); i++) { |
361 | dev_err(dev->dev, "failed to construct crtc for DMA_E\n"); | 367 | plane = mdp4_plane_init(dev, vg_planes[i], false); |
362 | ret = PTR_ERR(crtc); | 368 | if (IS_ERR(plane)) { |
363 | goto fail; | 369 | dev_err(dev->dev, |
370 | "failed to construct plane for VG%d\n", i + 1); | ||
371 | ret = PTR_ERR(plane); | ||
372 | goto fail; | ||
373 | } | ||
374 | priv->planes[priv->num_planes++] = plane; | ||
364 | } | 375 | } |
365 | 376 | ||
366 | encoder = mdp4_dtv_encoder_init(dev); | 377 | for (i = 0; i < ARRAY_SIZE(mdp4_crtcs); i++) { |
367 | if (IS_ERR(encoder)) { | 378 | plane = mdp4_plane_init(dev, rgb_planes[i], true); |
368 | dev_err(dev->dev, "failed to construct DTV encoder\n"); | 379 | if (IS_ERR(plane)) { |
369 | ret = PTR_ERR(encoder); | 380 | dev_err(dev->dev, |
370 | goto fail; | 381 | "failed to construct plane for RGB%d\n", i + 1); |
371 | } | 382 | ret = PTR_ERR(plane); |
383 | goto fail; | ||
384 | } | ||
372 | 385 | ||
373 | /* DTV can be hooked to DMA_E: */ | 386 | crtc = mdp4_crtc_init(dev, plane, priv->num_crtcs, i, |
374 | encoder->possible_crtcs = 1 << priv->num_crtcs; | 387 | mdp4_crtcs[i]); |
388 | if (IS_ERR(crtc)) { | ||
389 | dev_err(dev->dev, "failed to construct crtc for %s\n", | ||
390 | mdp4_crtc_names[i]); | ||
391 | ret = PTR_ERR(crtc); | ||
392 | goto fail; | ||
393 | } | ||
394 | |||
395 | priv->crtcs[priv->num_crtcs++] = crtc; | ||
396 | } | ||
375 | 397 | ||
376 | priv->crtcs[priv->num_crtcs++] = crtc; | 398 | /* |
377 | priv->encoders[priv->num_encoders++] = encoder; | 399 | * we currently set up two relatively fixed paths: |
400 | * | ||
401 | * LCDC/LVDS path: RGB1 -> DMA_P -> LCDC -> LVDS | ||
402 | * DTV/HDMI path: RGB2 -> DMA_E -> DTV -> HDMI | ||
403 | */ | ||
378 | 404 | ||
379 | if (priv->hdmi) { | 405 | for (i = 0; i < ARRAY_SIZE(mdp4_intfs); i++) { |
380 | /* Construct bridge/connector for HDMI: */ | 406 | ret = mdp4_modeset_init_intf(mdp4_kms, mdp4_intfs[i]); |
381 | ret = hdmi_modeset_init(priv->hdmi, dev, encoder); | ||
382 | if (ret) { | 407 | if (ret) { |
383 | dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret); | 408 | dev_err(dev->dev, "failed to initialize intf: %d, %d\n", |
409 | i, ret); | ||
384 | goto fail; | 410 | goto fail; |
385 | } | 411 | } |
386 | } | 412 | } |