aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c')
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c123
1 files changed, 80 insertions, 43 deletions
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index c396d459a9d0..3eb0749223d9 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -148,7 +148,15 @@ static int mdp5_set_split_display(struct msm_kms *kms,
148 return mdp5_cmd_encoder_set_split_display(encoder, 148 return mdp5_cmd_encoder_set_split_display(encoder,
149 slave_encoder); 149 slave_encoder);
150 else 150 else
151 return mdp5_encoder_set_split_display(encoder, slave_encoder); 151 return mdp5_vid_encoder_set_split_display(encoder,
152 slave_encoder);
153}
154
155static void mdp5_set_encoder_mode(struct msm_kms *kms,
156 struct drm_encoder *encoder,
157 bool cmd_mode)
158{
159 mdp5_encoder_set_intf_mode(encoder, cmd_mode);
152} 160}
153 161
154static void mdp5_kms_destroy(struct msm_kms *kms) 162static void mdp5_kms_destroy(struct msm_kms *kms)
@@ -230,6 +238,7 @@ static const struct mdp_kms_funcs kms_funcs = {
230 .get_format = mdp_get_format, 238 .get_format = mdp_get_format,
231 .round_pixclk = mdp5_round_pixclk, 239 .round_pixclk = mdp5_round_pixclk,
232 .set_split_display = mdp5_set_split_display, 240 .set_split_display = mdp5_set_split_display,
241 .set_encoder_mode = mdp5_set_encoder_mode,
233 .destroy = mdp5_kms_destroy, 242 .destroy = mdp5_kms_destroy,
234#ifdef CONFIG_DEBUG_FS 243#ifdef CONFIG_DEBUG_FS
235 .debugfs_init = mdp5_kms_debugfs_init, 244 .debugfs_init = mdp5_kms_debugfs_init,
@@ -267,7 +276,7 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms)
267 276
268static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms, 277static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms,
269 enum mdp5_intf_type intf_type, int intf_num, 278 enum mdp5_intf_type intf_type, int intf_num,
270 enum mdp5_intf_mode intf_mode, struct mdp5_ctl *ctl) 279 struct mdp5_ctl *ctl)
271{ 280{
272 struct drm_device *dev = mdp5_kms->dev; 281 struct drm_device *dev = mdp5_kms->dev;
273 struct msm_drm_private *priv = dev->dev_private; 282 struct msm_drm_private *priv = dev->dev_private;
@@ -275,21 +284,15 @@ static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms,
275 struct mdp5_interface intf = { 284 struct mdp5_interface intf = {
276 .num = intf_num, 285 .num = intf_num,
277 .type = intf_type, 286 .type = intf_type,
278 .mode = intf_mode, 287 .mode = MDP5_INTF_MODE_NONE,
279 }; 288 };
280 289
281 if ((intf_type == INTF_DSI) && 290 encoder = mdp5_encoder_init(dev, &intf, ctl);
282 (intf_mode == MDP5_INTF_DSI_MODE_COMMAND))
283 encoder = mdp5_cmd_encoder_init(dev, &intf, ctl);
284 else
285 encoder = mdp5_encoder_init(dev, &intf, ctl);
286
287 if (IS_ERR(encoder)) { 291 if (IS_ERR(encoder)) {
288 dev_err(dev->dev, "failed to construct encoder\n"); 292 dev_err(dev->dev, "failed to construct encoder\n");
289 return encoder; 293 return encoder;
290 } 294 }
291 295
292 encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
293 priv->encoders[priv->num_encoders++] = encoder; 296 priv->encoders[priv->num_encoders++] = encoder;
294 297
295 return encoder; 298 return encoder;
@@ -338,8 +341,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
338 break; 341 break;
339 } 342 }
340 343
341 encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num, 344 encoder = construct_encoder(mdp5_kms, INTF_eDP, intf_num, ctl);
342 MDP5_INTF_MODE_NONE, ctl);
343 if (IS_ERR(encoder)) { 345 if (IS_ERR(encoder)) {
344 ret = PTR_ERR(encoder); 346 ret = PTR_ERR(encoder);
345 break; 347 break;
@@ -357,8 +359,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
357 break; 359 break;
358 } 360 }
359 361
360 encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num, 362 encoder = construct_encoder(mdp5_kms, INTF_HDMI, intf_num, ctl);
361 MDP5_INTF_MODE_NONE, ctl);
362 if (IS_ERR(encoder)) { 363 if (IS_ERR(encoder)) {
363 ret = PTR_ERR(encoder); 364 ret = PTR_ERR(encoder);
364 break; 365 break;
@@ -369,9 +370,6 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
369 case INTF_DSI: 370 case INTF_DSI:
370 { 371 {
371 int dsi_id = get_dsi_id_from_intf(hw_cfg, intf_num); 372 int dsi_id = get_dsi_id_from_intf(hw_cfg, intf_num);
372 struct drm_encoder *dsi_encs[MSM_DSI_ENCODER_NUM];
373 enum mdp5_intf_mode mode;
374 int i;
375 373
376 if ((dsi_id >= ARRAY_SIZE(priv->dsi)) || (dsi_id < 0)) { 374 if ((dsi_id >= ARRAY_SIZE(priv->dsi)) || (dsi_id < 0)) {
377 dev_err(dev->dev, "failed to find dsi from intf %d\n", 375 dev_err(dev->dev, "failed to find dsi from intf %d\n",
@@ -389,19 +387,13 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int intf_num)
389 break; 387 break;
390 } 388 }
391 389
392 for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) { 390 encoder = construct_encoder(mdp5_kms, INTF_DSI, intf_num, ctl);
393 mode = (i == MSM_DSI_CMD_ENCODER_ID) ? 391 if (IS_ERR(encoder)) {
394 MDP5_INTF_DSI_MODE_COMMAND : 392 ret = PTR_ERR(encoder);
395 MDP5_INTF_DSI_MODE_VIDEO; 393 break;
396 dsi_encs[i] = construct_encoder(mdp5_kms, INTF_DSI,
397 intf_num, mode, ctl);
398 if (IS_ERR(dsi_encs[i])) {
399 ret = PTR_ERR(dsi_encs[i]);
400 break;
401 }
402 } 394 }
403 395
404 ret = msm_dsi_modeset_init(priv->dsi[dsi_id], dev, dsi_encs); 396 ret = msm_dsi_modeset_init(priv->dsi[dsi_id], dev, encoder);
405 break; 397 break;
406 } 398 }
407 default: 399 default:
@@ -418,20 +410,48 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
418 struct drm_device *dev = mdp5_kms->dev; 410 struct drm_device *dev = mdp5_kms->dev;
419 struct msm_drm_private *priv = dev->dev_private; 411 struct msm_drm_private *priv = dev->dev_private;
420 const struct mdp5_cfg_hw *hw_cfg; 412 const struct mdp5_cfg_hw *hw_cfg;
421 int i, ret; 413 unsigned int num_crtcs;
414 int i, ret, pi = 0, ci = 0;
415 struct drm_plane *primary[MAX_BASES] = { NULL };
416 struct drm_plane *cursor[MAX_BASES] = { NULL };
422 417
423 hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg); 418 hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
424 419
425 /* Construct planes equaling the number of hw pipes, and CRTCs 420 /*
426 * for the N layer-mixers (LM). The first N planes become primary 421 * Construct encoders and modeset initialize connector devices
422 * for each external display interface.
423 */
424 for (i = 0; i < ARRAY_SIZE(hw_cfg->intf.connect); i++) {
425 ret = modeset_init_intf(mdp5_kms, i);
426 if (ret)
427 goto fail;
428 }
429
430 /*
431 * We should ideally have less number of encoders (set up by parsing
432 * the MDP5 interfaces) than the number of layer mixers present in HW,
433 * but let's be safe here anyway
434 */
435 num_crtcs = min(priv->num_encoders, mdp5_cfg->lm.count);
436
437 /*
438 * Construct planes equaling the number of hw pipes, and CRTCs for the
439 * N encoders set up by the driver. The first N planes become primary
427 * planes for the CRTCs, with the remainder as overlay planes: 440 * planes for the CRTCs, with the remainder as overlay planes:
428 */ 441 */
429 for (i = 0; i < mdp5_kms->num_hwpipes; i++) { 442 for (i = 0; i < mdp5_kms->num_hwpipes; i++) {
430 bool primary = i < mdp5_cfg->lm.count; 443 struct mdp5_hw_pipe *hwpipe = mdp5_kms->hwpipes[i];
431 struct drm_plane *plane; 444 struct drm_plane *plane;
432 struct drm_crtc *crtc; 445 enum drm_plane_type type;
433 446
434 plane = mdp5_plane_init(dev, primary); 447 if (i < num_crtcs)
448 type = DRM_PLANE_TYPE_PRIMARY;
449 else if (hwpipe->caps & MDP_PIPE_CAP_CURSOR)
450 type = DRM_PLANE_TYPE_CURSOR;
451 else
452 type = DRM_PLANE_TYPE_OVERLAY;
453
454 plane = mdp5_plane_init(dev, type);
435 if (IS_ERR(plane)) { 455 if (IS_ERR(plane)) {
436 ret = PTR_ERR(plane); 456 ret = PTR_ERR(plane);
437 dev_err(dev->dev, "failed to construct plane %d (%d)\n", i, ret); 457 dev_err(dev->dev, "failed to construct plane %d (%d)\n", i, ret);
@@ -439,10 +459,16 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
439 } 459 }
440 priv->planes[priv->num_planes++] = plane; 460 priv->planes[priv->num_planes++] = plane;
441 461
442 if (!primary) 462 if (type == DRM_PLANE_TYPE_PRIMARY)
443 continue; 463 primary[pi++] = plane;
464 if (type == DRM_PLANE_TYPE_CURSOR)
465 cursor[ci++] = plane;
466 }
467
468 for (i = 0; i < num_crtcs; i++) {
469 struct drm_crtc *crtc;
444 470
445 crtc = mdp5_crtc_init(dev, plane, i); 471 crtc = mdp5_crtc_init(dev, primary[i], cursor[i], i);
446 if (IS_ERR(crtc)) { 472 if (IS_ERR(crtc)) {
447 ret = PTR_ERR(crtc); 473 ret = PTR_ERR(crtc);
448 dev_err(dev->dev, "failed to construct crtc %d (%d)\n", i, ret); 474 dev_err(dev->dev, "failed to construct crtc %d (%d)\n", i, ret);
@@ -451,13 +477,14 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
451 priv->crtcs[priv->num_crtcs++] = crtc; 477 priv->crtcs[priv->num_crtcs++] = crtc;
452 } 478 }
453 479
454 /* Construct encoders and modeset initialize connector devices 480 /*
455 * for each external display interface. 481 * Now that we know the number of crtcs we've created, set the possible
482 * crtcs for the encoders
456 */ 483 */
457 for (i = 0; i < ARRAY_SIZE(hw_cfg->intf.connect); i++) { 484 for (i = 0; i < priv->num_encoders; i++) {
458 ret = modeset_init_intf(mdp5_kms, i); 485 struct drm_encoder *encoder = priv->encoders[i];
459 if (ret) 486
460 goto fail; 487 encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
461 } 488 }
462 489
463 return 0; 490 return 0;
@@ -773,6 +800,9 @@ static int hwpipe_init(struct mdp5_kms *mdp5_kms)
773 static const enum mdp5_pipe dma_planes[] = { 800 static const enum mdp5_pipe dma_planes[] = {
774 SSPP_DMA0, SSPP_DMA1, 801 SSPP_DMA0, SSPP_DMA1,
775 }; 802 };
803 static const enum mdp5_pipe cursor_planes[] = {
804 SSPP_CURSOR0, SSPP_CURSOR1,
805 };
776 const struct mdp5_cfg_hw *hw_cfg; 806 const struct mdp5_cfg_hw *hw_cfg;
777 int ret; 807 int ret;
778 808
@@ -796,6 +826,13 @@ static int hwpipe_init(struct mdp5_kms *mdp5_kms)
796 if (ret) 826 if (ret)
797 return ret; 827 return ret;
798 828
829 /* Construct cursor pipes: */
830 ret = construct_pipes(mdp5_kms, hw_cfg->pipe_cursor.count,
831 cursor_planes, hw_cfg->pipe_cursor.base,
832 hw_cfg->pipe_cursor.caps);
833 if (ret)
834 return ret;
835
799 return 0; 836 return 0;
800} 837}
801 838