diff options
Diffstat (limited to 'drivers/video/omap2/dss')
-rw-r--r-- | drivers/video/omap2/dss/apply.c | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 8d9521609150..ecac6b6e5a8d 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -70,7 +70,6 @@ struct ovl_priv_data { bool shadow_extra_info_dirty; bool enabled; - enum omap_channel channel; u32 fifo_low, fifo_high; /* @@ -615,7 +614,6 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl) * disabled */ dispc_ovl_enable(ovl->id, op->enabled); - dispc_ovl_set_channel_out(ovl->id, op->channel); dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high); mp = get_mgr_priv(ovl->manager); @@ -1276,39 +1274,34 @@ int dss_ovl_set_manager(struct omap_overlay *ovl, goto err; } + r = dispc_runtime_get(); + if (r) + goto err; + spin_lock_irqsave(&data_lock, flags); if (op->enabled) { spin_unlock_irqrestore(&data_lock, flags); DSSERR("overlay has to be disabled to change the manager\n"); r = -EINVAL; - goto err; + goto err1; } - op->channel = mgr->id; - op->extra_info_dirty = true; + dispc_ovl_set_channel_out(ovl->id, mgr->id); ovl->manager = mgr; list_add_tail(&ovl->list, &mgr->overlays); spin_unlock_irqrestore(&data_lock, flags); - /* XXX: When there is an overlay on a DSI manual update display, and - * the overlay is first disabled, then moved to tv, and enabled, we - * seem to get SYNC_LOST_DIGIT error. - * - * Waiting doesn't seem to help, but updating the manual update display - * after disabling the overlay seems to fix this. This hints that the - * overlay is perhaps somehow tied to the LCD output until the output - * is updated. - * - * Userspace workaround for this is to update the LCD after disabling - * the overlay, but before moving the overlay to TV. - */ + dispc_runtime_put(); mutex_unlock(&apply_lock); return 0; + +err1: + dispc_runtime_put(); err: mutex_unlock(&apply_lock); return r; @@ -1342,9 +1335,24 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl) /* wait for pending extra_info updates to ensure the ovl is disabled */ wait_pending_extra_info_updates(); + /* + * For a manual update display, there is no guarantee that the overlay + * is really disabled in HW, we may need an extra update from this + * manager before the configurations can go in. Return an error if the + * overlay needed an update from the manager. + * + * TODO: Instead of returning an error, try to do a dummy manager update + * here to disable the overlay in hardware. Use the *GATED fields in + * the DISPC_CONFIG registers to do a dummy update. + */ spin_lock_irqsave(&data_lock, flags); - op->channel = -1; + if (ovl_manual_update(ovl) && op->extra_info_dirty) { + spin_unlock_irqrestore(&data_lock, flags); + DSSERR("need an update to change the manager\n"); + r = -EINVAL; + goto err; + } ovl->manager = NULL; list_del(&ovl->list); |