diff options
-rw-r--r-- | drivers/video/omap2/dss/apply.c | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 5bde08f19920..107a4ae6e5ac 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c | |||
@@ -87,6 +87,10 @@ struct mgr_priv_data { | |||
87 | bool manual_update; | 87 | bool manual_update; |
88 | bool do_manual_update; | 88 | bool do_manual_update; |
89 | 89 | ||
90 | /* If true, GO bit is up and shadow registers cannot be written. | ||
91 | * Never true for manual update displays */ | ||
92 | bool busy; | ||
93 | |||
90 | /* If true, a display is enabled using this manager */ | 94 | /* If true, a display is enabled using this manager */ |
91 | bool enabled; | 95 | bool enabled; |
92 | }; | 96 | }; |
@@ -319,18 +323,12 @@ static int dss_write_regs(void) | |||
319 | const int num_mgrs = dss_feat_get_num_mgrs(); | 323 | const int num_mgrs = dss_feat_get_num_mgrs(); |
320 | int i; | 324 | int i; |
321 | int r; | 325 | int r; |
322 | bool mgr_busy[MAX_DSS_MANAGERS]; | 326 | bool mgr_go[MAX_DSS_MANAGERS] = { false }; |
323 | bool mgr_go[MAX_DSS_MANAGERS]; | ||
324 | bool busy; | 327 | bool busy; |
325 | 328 | ||
326 | r = 0; | 329 | r = 0; |
327 | busy = false; | 330 | busy = false; |
328 | 331 | ||
329 | for (i = 0; i < num_mgrs; i++) { | ||
330 | mgr_busy[i] = dispc_mgr_go_busy(i); | ||
331 | mgr_go[i] = false; | ||
332 | } | ||
333 | |||
334 | /* Commit overlay settings */ | 332 | /* Commit overlay settings */ |
335 | for (i = 0; i < num_ovls; ++i) { | 333 | for (i = 0; i < num_ovls; ++i) { |
336 | ovl = omap_dss_get_overlay(i); | 334 | ovl = omap_dss_get_overlay(i); |
@@ -344,7 +342,7 @@ static int dss_write_regs(void) | |||
344 | if (mp->manual_update && !mp->do_manual_update) | 342 | if (mp->manual_update && !mp->do_manual_update) |
345 | continue; | 343 | continue; |
346 | 344 | ||
347 | if (mgr_busy[op->channel]) { | 345 | if (mp->busy) { |
348 | busy = true; | 346 | busy = true; |
349 | continue; | 347 | continue; |
350 | } | 348 | } |
@@ -369,7 +367,7 @@ static int dss_write_regs(void) | |||
369 | if (mp->manual_update && !mp->do_manual_update) | 367 | if (mp->manual_update && !mp->do_manual_update) |
370 | continue; | 368 | continue; |
371 | 369 | ||
372 | if (mgr_busy[i]) { | 370 | if (mp->busy) { |
373 | busy = true; | 371 | busy = true; |
374 | continue; | 372 | continue; |
375 | } | 373 | } |
@@ -391,8 +389,10 @@ static int dss_write_regs(void) | |||
391 | /* We don't need GO with manual update display. LCD iface will | 389 | /* We don't need GO with manual update display. LCD iface will |
392 | * always be turned off after frame, and new settings will be | 390 | * always be turned off after frame, and new settings will be |
393 | * taken in to use at next update */ | 391 | * taken in to use at next update */ |
394 | if (!mp->manual_update) | 392 | if (!mp->manual_update) { |
393 | mp->busy = true; | ||
395 | dispc_mgr_go(i); | 394 | dispc_mgr_go(i); |
395 | } | ||
396 | } | 396 | } |
397 | 397 | ||
398 | if (busy) | 398 | if (busy) |
@@ -471,24 +471,34 @@ static void dss_apply_irq_handler(void *data, u32 mask) | |||
471 | const int num_ovls = dss_feat_get_num_ovls(); | 471 | const int num_ovls = dss_feat_get_num_ovls(); |
472 | const int num_mgrs = dss_feat_get_num_mgrs(); | 472 | const int num_mgrs = dss_feat_get_num_mgrs(); |
473 | int i, r; | 473 | int i, r; |
474 | bool mgr_busy[MAX_DSS_MANAGERS]; | ||
475 | |||
476 | for (i = 0; i < num_mgrs; i++) | ||
477 | mgr_busy[i] = dispc_mgr_go_busy(i); | ||
478 | 474 | ||
479 | spin_lock(&data_lock); | 475 | spin_lock(&data_lock); |
480 | 476 | ||
477 | for (i = 0; i < num_mgrs; i++) { | ||
478 | mgr = omap_dss_get_overlay_manager(i); | ||
479 | mp = get_mgr_priv(mgr); | ||
480 | |||
481 | mp->busy = dispc_mgr_go_busy(i); | ||
482 | } | ||
483 | |||
481 | for (i = 0; i < num_ovls; ++i) { | 484 | for (i = 0; i < num_ovls; ++i) { |
482 | ovl = omap_dss_get_overlay(i); | 485 | ovl = omap_dss_get_overlay(i); |
483 | op = get_ovl_priv(ovl); | 486 | op = get_ovl_priv(ovl); |
484 | if (!mgr_busy[op->channel]) | 487 | |
488 | if (!op->enabled) | ||
489 | continue; | ||
490 | |||
491 | mp = get_mgr_priv(ovl->manager); | ||
492 | |||
493 | if (!mp->busy) | ||
485 | op->shadow_dirty = false; | 494 | op->shadow_dirty = false; |
486 | } | 495 | } |
487 | 496 | ||
488 | for (i = 0; i < num_mgrs; ++i) { | 497 | for (i = 0; i < num_mgrs; ++i) { |
489 | mgr = omap_dss_get_overlay_manager(i); | 498 | mgr = omap_dss_get_overlay_manager(i); |
490 | mp = get_mgr_priv(mgr); | 499 | mp = get_mgr_priv(mgr); |
491 | if (!mgr_busy[i]) | 500 | |
501 | if (!mp->busy) | ||
492 | mp->shadow_dirty = false; | 502 | mp->shadow_dirty = false; |
493 | } | 503 | } |
494 | 504 | ||
@@ -497,13 +507,20 @@ static void dss_apply_irq_handler(void *data, u32 mask) | |||
497 | goto end; | 507 | goto end; |
498 | 508 | ||
499 | /* re-read busy flags */ | 509 | /* re-read busy flags */ |
500 | for (i = 0; i < num_mgrs; i++) | 510 | for (i = 0; i < num_mgrs; i++) { |
501 | mgr_busy[i] = dispc_mgr_go_busy(i); | 511 | mgr = omap_dss_get_overlay_manager(i); |
512 | mp = get_mgr_priv(mgr); | ||
513 | |||
514 | mp->busy = dispc_mgr_go_busy(i); | ||
515 | } | ||
502 | 516 | ||
503 | /* keep running as long as there are busy managers, so that | 517 | /* keep running as long as there are busy managers, so that |
504 | * we can collect overlay-applied information */ | 518 | * we can collect overlay-applied information */ |
505 | for (i = 0; i < num_mgrs; ++i) { | 519 | for (i = 0; i < num_mgrs; ++i) { |
506 | if (mgr_busy[i]) | 520 | mgr = omap_dss_get_overlay_manager(i); |
521 | mp = get_mgr_priv(mgr); | ||
522 | |||
523 | if (mp->busy) | ||
507 | goto end; | 524 | goto end; |
508 | } | 525 | } |
509 | 526 | ||