aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2
diff options
context:
space:
mode:
authorArtem Rudenko <artemrudenko@ti.com>2012-09-12 16:10:58 +0300
committerZiyann <jaraidaniel@gmail.com>2014-11-19 21:12:08 +0100
commit9436a61bec6339c0653501d627f21b10c08cb848 (patch)
treeb20244e51a38d1f61bde7f86ba846fad00315925 /drivers/video/omap2
parent3179c093b7704dc38636500203d7aa911c4571ef (diff)
downloadkernel_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.c115
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);