* Never true for manual update displays */
bool busy;
+ /* If true, dispc output is enabled */
+ bool updating;
+
/* If true, a display is enabled using this manager */
bool enabled;
};
if (!mp->enabled)
continue;
- if (mgr_manual_update(mgr))
- continue;
-
- /* to catch GO bit going down */
- if (mp->busy)
- return true;
+ if (mgr_manual_update(mgr)) {
+ /* to catch FRAMEDONE */
+ if (mp->updating)
+ return true;
+ } else {
+ /* to catch GO bit going down */
+ if (mp->busy)
+ return true;
- /* to write new values to registers */
- if (mp->dirty)
- return true;
+ /* to write new values to registers */
+ if (mp->dirty)
+ return true;
- list_for_each_entry(ovl, &mgr->overlays, list) {
- struct ovl_priv_data *op;
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ struct ovl_priv_data *op;
- op = get_ovl_priv(ovl);
+ op = get_ovl_priv(ovl);
- if (!op->enabled)
- continue;
+ if (!op->enabled)
+ continue;
- /* to write new values to registers */
- if (op->dirty || op->extra_info_dirty)
- return true;
+ /* to write new values to registers */
+ if (op->dirty || op->extra_info_dirty)
+ return true;
+ }
}
}
struct ovl_priv_data *op = get_ovl_priv(ovl);
struct omap_overlay_info *oi;
bool ilace, replication;
+ struct mgr_priv_data *mp;
int r;
DSSDBGF("%d", ovl->id);
dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
+ mp = get_mgr_priv(ovl->manager);
+
op->dirty = false;
- op->shadow_dirty = true;
+ if (mp->updating)
+ op->shadow_dirty = true;
}
static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
{
struct ovl_priv_data *op = get_ovl_priv(ovl);
+ struct mgr_priv_data *mp;
DSSDBGF("%d", ovl->id);
dispc_ovl_enable(ovl->id, op->enabled);
+ mp = get_mgr_priv(ovl->manager);
+
op->extra_info_dirty = false;
- op->shadow_extra_info_dirty = true;
+ if (mp->updating)
+ op->shadow_extra_info_dirty = true;
}
static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
dispc_mgr_setup(mgr->id, &mp->info);
mp->dirty = false;
- mp->shadow_dirty = true;
+ if (mp->updating)
+ mp->shadow_dirty = true;
}
}
void dss_mgr_start_update(struct omap_overlay_manager *mgr)
{
struct mgr_priv_data *mp = get_mgr_priv(mgr);
- struct ovl_priv_data *op;
- struct omap_overlay *ovl;
unsigned long flags;
spin_lock_irqsave(&data_lock, flags);
+ WARN_ON(mp->updating);
+
dss_mgr_write_regs(mgr);
- list_for_each_entry(ovl, &mgr->overlays, list) {
- op = get_ovl_priv(ovl);
- op->shadow_dirty = false;
- op->shadow_extra_info_dirty = false;
- }
+ mp->updating = true;
- mp->shadow_dirty = false;
+ if (!dss_data.irq_enabled && need_isr())
+ dss_register_vsync_isr();
dispc_mgr_enable(mgr->id, true);
for (i = 0; i < num_mgrs; ++i)
mask |= dispc_mgr_get_vsync_irq(i);
+ for (i = 0; i < num_mgrs; ++i)
+ mask |= dispc_mgr_get_framedone_irq(i);
+
r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
WARN_ON(r);
for (i = 0; i < num_mgrs; ++i)
mask |= dispc_mgr_get_vsync_irq(i);
+ for (i = 0; i < num_mgrs; ++i)
+ mask |= dispc_mgr_get_framedone_irq(i);
+
r = omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, mask);
WARN_ON(r);
mp = get_mgr_priv(mgr);
mp->busy = dispc_mgr_go_busy(i);
+ mp->updating = dispc_mgr_is_enabled(i);
}
for (i = 0; i < num_ovls; ++i) {
dss_write_regs();
+ if (!mgr_manual_update(mgr))
+ mp->updating = true;
+
spin_unlock_irqrestore(&data_lock, flags);
if (!mgr_manual_update(mgr))
spin_lock_irqsave(&data_lock, flags);
+ mp->updating = false;
mp->enabled = false;
spin_unlock_irqrestore(&data_lock, flags);