aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2015-02-22 18:39:13 -0500
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2015-03-03 09:16:28 -0500
commit52055bafa1ffcd24525f72f5bc35bc14eae1c449 (patch)
treed5d8663c4e5dd7eda32653d915f0aab2b348271b
parent5bfcbce0eaeb884e258648e5ceb74a61cfb80f3c (diff)
drm: rcar-du: Move plane commit code from CRTC start to CRTC resume
As the DRM core will commit plane states when performing atomic updates, those don't need to be committed manually when the CRTC is started except in the system resume code path. However, the atomic plane commit step is currently performed between mode set disable and mode set enable to mimick the legacy mode setting operations order. This causes the device clocks to be disabled after applying plane settings and reenabled when enabling the CRTC, potentially losing hardware in between. Reorder the operations to enable the CRTC first and only then apply plane settings, removing the need to manage clocks in the atomic begin and flush handlers. We can then move the plane state commit code out of the CRTC start handler to the system resume handler. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.c54
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_kms.c2
2 files changed, 21 insertions, 35 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 98f770622b2d..29bbb44eecc9 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -204,9 +204,8 @@ plane_format(struct rcar_du_plane *plane)
204 return to_rcar_du_plane_state(plane->plane.state)->format; 204 return to_rcar_du_plane_state(plane->plane.state)->format;
205} 205}
206 206
207static void rcar_du_crtc_update_planes(struct drm_crtc *crtc) 207static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
208{ 208{
209 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
210 struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES]; 209 struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES];
211 unsigned int num_planes = 0; 210 unsigned int num_planes = 0;
212 unsigned int prio = 0; 211 unsigned int prio = 0;
@@ -354,7 +353,6 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
354{ 353{
355 struct drm_crtc *crtc = &rcrtc->crtc; 354 struct drm_crtc *crtc = &rcrtc->crtc;
356 bool interlaced; 355 bool interlaced;
357 unsigned int i;
358 356
359 if (rcrtc->started) 357 if (rcrtc->started)
360 return; 358 return;
@@ -367,26 +365,8 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
367 rcar_du_crtc_set_display_timing(rcrtc); 365 rcar_du_crtc_set_display_timing(rcrtc);
368 rcar_du_group_set_routing(rcrtc->group); 366 rcar_du_group_set_routing(rcrtc->group);
369 367
370 /* FIXME: Commit the planes state. This is required here as the CRTC can 368 /* Start with all planes disabled. */
371 * be started from the system resume handler, which don't go 369 rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
372 * through .atomic_plane_update() and .atomic_flush() to commit plane
373 * state. Additionally, given that the plane state atomic commit occurs
374 * between CRTC disable and enable, the hardware state could also be
375 * lost due to runtime PM, requiring a full commit here. This will be
376 * fixed later after switching to atomic updates completely.
377 */
378 mutex_lock(&rcrtc->group->planes.lock);
379 rcar_du_crtc_update_planes(crtc);
380 mutex_unlock(&rcrtc->group->planes.lock);
381
382 for (i = 0; i < ARRAY_SIZE(rcrtc->group->planes.planes); ++i) {
383 struct rcar_du_plane *plane = &rcrtc->group->planes.planes[i];
384
385 if (plane->plane.state->crtc != crtc)
386 continue;
387
388 rcar_du_plane_setup(plane);
389 }
390 370
391 /* Select master sync mode. This enables display operation in master 371 /* Select master sync mode. This enables display operation in master
392 * sync mode (with the HSYNC and VSYNC signals configured as outputs and 372 * sync mode (with the HSYNC and VSYNC signals configured as outputs and
@@ -437,11 +417,27 @@ void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc)
437 417
438void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc) 418void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc)
439{ 419{
420 unsigned int i;
421
440 if (!rcrtc->enabled) 422 if (!rcrtc->enabled)
441 return; 423 return;
442 424
443 rcar_du_crtc_get(rcrtc); 425 rcar_du_crtc_get(rcrtc);
444 rcar_du_crtc_start(rcrtc); 426 rcar_du_crtc_start(rcrtc);
427
428 /* Commit the planes state. */
429 for (i = 0; i < ARRAY_SIZE(rcrtc->group->planes.planes); ++i) {
430 struct rcar_du_plane *plane = &rcrtc->group->planes.planes[i];
431
432 if (plane->plane.state->crtc != &rcrtc->crtc)
433 continue;
434
435 rcar_du_plane_setup(plane);
436 }
437
438 mutex_lock(&rcrtc->group->planes.lock);
439 rcar_du_crtc_update_planes(rcrtc);
440 mutex_unlock(&rcrtc->group->planes.lock);
445} 441}
446 442
447/* ----------------------------------------------------------------------------- 443/* -----------------------------------------------------------------------------
@@ -490,11 +486,6 @@ static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc)
490 struct drm_device *dev = rcrtc->crtc.dev; 486 struct drm_device *dev = rcrtc->crtc.dev;
491 unsigned long flags; 487 unsigned long flags;
492 488
493 /* We need to access the hardware during atomic update, acquire a
494 * reference to the CRTC.
495 */
496 rcar_du_crtc_get(rcrtc);
497
498 if (event) { 489 if (event) {
499 event->pipe = rcrtc->index; 490 event->pipe = rcrtc->index;
500 491
@@ -510,14 +501,9 @@ static void rcar_du_crtc_atomic_flush(struct drm_crtc *crtc)
510{ 501{
511 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); 502 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
512 503
513 /* We're done, apply the configuration and drop the reference acquired
514 * in .atomic_begin().
515 */
516 mutex_lock(&rcrtc->group->planes.lock); 504 mutex_lock(&rcrtc->group->planes.lock);
517 rcar_du_crtc_update_planes(crtc); 505 rcar_du_crtc_update_planes(rcrtc);
518 mutex_unlock(&rcrtc->group->planes.lock); 506 mutex_unlock(&rcrtc->group->planes.lock);
519
520 rcar_du_crtc_put(rcrtc);
521} 507}
522 508
523static const struct drm_crtc_helper_funcs crtc_helper_funcs = { 509static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index cec35e405248..8bc7242ba979 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -207,8 +207,8 @@ static void rcar_du_atomic_complete(struct rcar_du_commit *commit)
207 207
208 /* Apply the atomic update. */ 208 /* Apply the atomic update. */
209 drm_atomic_helper_commit_modeset_disables(dev, old_state); 209 drm_atomic_helper_commit_modeset_disables(dev, old_state);
210 drm_atomic_helper_commit_planes(dev, old_state);
211 drm_atomic_helper_commit_modeset_enables(dev, old_state); 210 drm_atomic_helper_commit_modeset_enables(dev, old_state);
211 drm_atomic_helper_commit_planes(dev, old_state);
212 212
213 drm_atomic_helper_wait_for_vblanks(dev, old_state); 213 drm_atomic_helper_wait_for_vblanks(dev, old_state);
214 214