diff options
author | Artem Rudenko <artemrudenko@ti.com> | 2012-09-12 16:10:58 +0300 |
---|---|---|
committer | Ziyann <jaraidaniel@gmail.com> | 2014-11-19 21:12:08 +0100 |
commit | 9436a61bec6339c0653501d627f21b10c08cb848 (patch) | |
tree | b20244e51a38d1f61bde7f86ba846fad00315925 /drivers/video/omap2 | |
parent | 3179c093b7704dc38636500203d7aa911c4571ef (diff) | |
download | kernel_samsung_tuna-9436a61bec6339c0653501d627f21b10c08cb848.zip kernel_samsung_tuna-9436a61bec6339c0653501d627f21b10c08cb848.tar.gz kernel_samsung_tuna-9436a61bec6339c0653501d627f21b10c08cb848.tar.bz2 |
OMAPDSS: implementation of MEM2MEM mode with blanked pannel.
This change implements MEM2MEM mode for pannels blanked case.
Change-Id: Ic030682e7aaa33dd596d5150da23ab9dc1fc20f7
Signed-off-by: Artem Rudenko <artemrudenko@ti.com>
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r-- | drivers/video/omap2/dss/manager.c | 115 |
1 files changed, 98 insertions, 17 deletions
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index f47e55b..a39aa34 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -590,6 +590,7 @@ struct manager_cache_data { bool cpr_enable; struct omap_dss_cpr_coefs cpr_coefs; bool skip_init; + bool m2m_only; }; static struct { @@ -1684,6 +1685,65 @@ end: spin_unlock(&dss_cache.lock); } +/* This function is needed for turning on/turning off DISPC clock for M2M mode + * with blanked panel. Essentially, this function increments/decrements counter + * of users of DISPC. */ +void dss_m2m_clock_handling(struct omap_overlay_manager *mgr) +{ + struct manager_cache_data *mc; + bool mc_m2m_only; + + mc = &dss_cache.manager_cache[mgr->id]; + mc_m2m_only = mc->m2m_only; + + if (mgr->m2m_only && !mc_m2m_only) + dispc_runtime_get(); + else if (!mgr->m2m_only && mc_m2m_only) + dispc_runtime_put(); +} + +static void dss_m2m_apply_handler(void) +{ + struct manager_cache_data *mc; + struct overlay_cache_data *oc; + const int num_ovls = dss_feat_get_num_ovls(); + const int num_mgrs = dss_feat_get_num_mgrs(); + int i; + bool mgr_busy[MAX_DSS_MANAGERS]; + + for (i = 0; i < MAX_DSS_MANAGERS; i++) { + if (i < num_mgrs) { + if (mgrs[i] && mgrs[i]->m2m_only) + mgr_busy[i] = false; + else + mgr_busy[i] = dispc_go_busy(i); + } else + mgr_busy[i] = false; + } + + for (i = 0; i < num_ovls; ++i) { + oc = &dss_cache.overlay_cache[i]; + if (!mgr_busy[oc->channel] && oc->shadow_dirty) { + dss_ovl_program_cb(&oc->cb, i); + oc->dispc_channel = oc->channel; + oc->shadow_dirty = false; + } + } + + for (i = 0; i < num_mgrs; ++i) { + mc = &dss_cache.manager_cache[i]; + if (!mgr_busy[i] && mc->shadow_dirty) { + if (mgrs[i] && mgrs[i]->device) + mgrs[i]->device->first_vsync = true; + + dss_ovl_program_cb(&mc->cb, i); + mc->shadow_dirty = false; + } + } + + configure_dispc(); +} + static int omap_dss_mgr_blank(struct omap_overlay_manager *mgr, bool wait_for_go) { @@ -1743,21 +1803,29 @@ static int omap_dss_mgr_blank(struct omap_overlay_manager *mgr, mgr->info.cb.fn = NULL; mc->dirty = true; mgr->info_dirty = false; + mc->m2m_only = mgr->m2m_only; /* * TRICKY: Enable apply irq even if not waiting for vsync, so that * DISPC programming takes place in case GO bit was on. */ - if (!dss_cache.irq_enabled) { - u32 mask; + if (mgr->m2m_only) { + configure_dispc(); + dss_m2m_apply_handler(); + } else { + if (!dss_cache.irq_enabled) { + u32 mask; - mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD | - DISPC_IRQ_EVSYNC_EVEN; - if (dss_has_feature(FEAT_MGR_LCD2)) - mask |= DISPC_IRQ_VSYNC2; + mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD | + DISPC_IRQ_EVSYNC_EVEN; - r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask); - dss_cache.irq_enabled = true; + if (dss_has_feature(FEAT_MGR_LCD2)) + mask |= DISPC_IRQ_VSYNC2; + + r = omap_dispc_register_isr(dss_apply_irq_handler, + NULL, mask); + dss_cache.irq_enabled = true; + } } if (!r_get) { @@ -2002,6 +2070,12 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) mc->skip_init = dssdev->skip_init; + /* WA: Do not set GO bit on manager */ + if (mgr->m2m_only) + mc->skip_init = true; + + mc->m2m_only = mgr->m2m_only; + skip_mgr: /* XXX TODO: Try to get fifomerge working. The problem is that it @@ -2065,18 +2139,25 @@ skip_mgr: } r = 0; - if (!dss_cache.irq_enabled) { - u32 mask; + if (mgr->m2m_only) { + configure_dispc(); + dss_m2m_apply_handler(); + } else { + if (!dss_cache.irq_enabled) { + u32 mask; - mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD | - DISPC_IRQ_EVSYNC_EVEN; - if (dss_has_feature(FEAT_MGR_LCD2)) - mask |= DISPC_IRQ_VSYNC2; + mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD | + DISPC_IRQ_EVSYNC_EVEN; - r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask); - dss_cache.irq_enabled = true; + if (dss_has_feature(FEAT_MGR_LCD2)) + mask |= DISPC_IRQ_VSYNC2; + + r = omap_dispc_register_isr(dss_apply_irq_handler, + NULL, mask); + dss_cache.irq_enabled = true; + } + configure_dispc(); } - configure_dispc(); done: spin_unlock_irqrestore(&dss_cache.lock, flags); |