diff options
author | Mykhailo Denysiuk <x0172934@ti.com> | 2012-06-24 15:05:47 +0300 |
---|---|---|
committer | Ziyann <jaraidaniel@gmail.com> | 2014-11-19 21:10:34 +0100 |
commit | 5ca8a84a20463793775eb84cb2da8c3871824eb3 (patch) | |
tree | 00df50ff070366ccbf110cf8d86ca664ef05eb50 | |
parent | 66b3a6593ad9e397ef6518509f96306a253067d6 (diff) | |
download | kernel_samsung_tuna-5ca8a84a20463793775eb84cb2da8c3871824eb3.zip kernel_samsung_tuna-5ca8a84a20463793775eb84cb2da8c3871824eb3.tar.gz kernel_samsung_tuna-5ca8a84a20463793775eb84cb2da8c3871824eb3.tar.bz2 |
OMAPDSS: DSSCOMP: Add MEM2MEM with manager mode
This change adds code for maintain MEM2MEM with manager mode
at DSSCOMP level.
Change-Id: Id14bc0c4884310250b6709436d815c9102a9d72e
Signed-off-by: Mykhailo Denysiuk <x0172934@ti.com>
-rw-r--r-- | drivers/video/omap2/dsscomp/base.c | 22 | ||||
-rw-r--r-- | drivers/video/omap2/dsscomp/dsscomp.h | 3 | ||||
-rw-r--r-- | drivers/video/omap2/dsscomp/queue.c | 105 |
3 files changed, 99 insertions, 31 deletions
diff --git a/drivers/video/omap2/dsscomp/base.c b/drivers/video/omap2/dsscomp/base.c index c1f5b56..72a2199 100644 --- a/drivers/video/omap2/dsscomp/base.c +++ b/drivers/video/omap2/dsscomp/base.c @@ -178,6 +178,8 @@ int crop_to_rect(union rect *crop, union rect *win, union rect *vis, int set_dss_ovl_info(struct dss2_ovl_info *oi) { struct omap_overlay_info info; + struct omap_writeback_info wb_info; + struct omap_writeback *wb; struct omap_overlay *ovl; struct dss2_ovl_cfg *cfg; union rect crop, win, vis; @@ -212,9 +214,21 @@ int set_dss_ovl_info(struct dss2_ovl_info *oi) /* crop to screen */ crop.r = cfg->crop; win.r = cfg->win; + vis.x = vis.y = 0; - vis.w = ovl->manager->device->panel.timings.x_res; - vis.h = ovl->manager->device->panel.timings.y_res; + + wb = omap_dss_get_wb(0); + + wb->get_wb_info(wb, &wb_info); + + if (wb && wb_info.enabled && wb_info.mode == OMAP_WB_MEM2MEM_MODE && + ovl->manager->id == wb_info.source) { + vis.w = wb_info.width; + vis.h = wb_info.height; + } else { + vis.w = ovl->manager->device->panel.timings.x_res; + vis.h = ovl->manager->device->panel.timings.y_res; + } if (!info.wb_source) { if (crop_to_rect(&crop, &win, &vis, cfg->rotation, @@ -444,7 +458,8 @@ struct omap_overlay_manager *find_dss_mgr(int display_ix) return NULL; } -int set_dss_mgr_info(struct dss2_mgr_info *mi, struct omapdss_ovl_cb *cb) +int set_dss_mgr_info(struct dss2_mgr_info *mi, struct omapdss_ovl_cb *cb, + bool m2m_mode) { struct omap_overlay_manager_info info; struct omap_overlay_manager *mgr; @@ -467,6 +482,7 @@ int set_dss_mgr_info(struct dss2_mgr_info *mi, struct omapdss_ovl_cb *cb) info.cpr_coefs = mi->cpr_coefs; info.cpr_enable = mi->cpr_enabled; info.cb = *cb; + info.wb_only = m2m_mode; return mgr->set_manager_info(mgr, &info); } diff --git a/drivers/video/omap2/dsscomp/dsscomp.h b/drivers/video/omap2/dsscomp/dsscomp.h index e6625be..ae7f7b1 100644 --- a/drivers/video/omap2/dsscomp/dsscomp.h +++ b/drivers/video/omap2/dsscomp/dsscomp.h @@ -145,7 +145,8 @@ int dsscomp_state_notifier(struct notifier_block *nb, /* basic operation - if not using queues */ int set_dss_ovl_info(struct dss2_ovl_info *oi); int set_dss_wb_info(struct dss2_ovl_info *oi); -int set_dss_mgr_info(struct dss2_mgr_info *mi, struct omapdss_ovl_cb *cb); +int set_dss_mgr_info(struct dss2_mgr_info *mi, struct omapdss_ovl_cb *cb, + bool m2m_mode); struct omap_overlay_manager *find_dss_mgr(int display_ix); void swap_rb_in_ovl_info(struct dss2_ovl_info *oi); void swap_rb_in_mgr_info(struct dss2_mgr_info *mi); diff --git a/drivers/video/omap2/dsscomp/queue.c b/drivers/video/omap2/dsscomp/queue.c index 6f5f790..6b74078 100644 --- a/drivers/video/omap2/dsscomp/queue.c +++ b/drivers/video/omap2/dsscomp/queue.c @@ -506,9 +506,12 @@ static int dsscomp_apply(dsscomp_t comp) struct omap_overlay_manager *mgr; struct omap_overlay *ovl; struct dsscomp_setup_mgr_data *d; + struct omap_writeback_info wb_info; + struct omap_writeback *wb; u32 oix; bool cb_programmed = false; bool wb_apply = false; + bool m2m_mgr_mode = false; struct omapdss_ovl_cb cb = { .fn = dsscomp_mgr_callback, @@ -536,29 +539,25 @@ static int dsscomp_apply(dsscomp_t comp) dump_comp_info(cdev, d, "apply"); + wb = omap_dss_get_wb(0); + wb->get_wb_info(wb, &wb_info); + r = 0; dmask = 0; + + /* In some cases overlay cropping is based on WB resolution. + * Because of that we need to apply WB settings before configuring + * the rest of overlays. */ for (oix = 0; oix < comp->frm.num_ovls; oix++) { struct dss2_ovl_info *oi = comp->ovls + oix; - /* keep track of disabled overlays */ - if (!oi->cfg.enabled) - dmask |= 1 << oi->cfg.ix; - - if (r && !comp->must_apply) + if (!comp->must_apply) continue; - dump_ovl_info(cdev, oi); - - if (oi->cfg.ix >= cdev->num_ovls && oi->cfg.ix != OMAP_DSS_WB) { - r = -EINVAL; - continue; - } - if (oi->cfg.ix == OMAP_DSS_WB) { /* update status of WB */ - struct omap_writeback_info wb_info; - struct omap_writeback *wb; + if (!oi->cfg.enabled) + dmask |= 1 << oi->cfg.ix; wb_apply = true; @@ -566,13 +565,49 @@ static int dsscomp_apply(dsscomp_t comp) wb->get_wb_info(wb, &wb_info); /* if prev comp was with M2M WB */ if (wb_info.mode == OMAP_WB_MEM2MEM_MODE && - wb_info.enabled) { - if (wb->wait_framedone(wb)) - dev_warn(DEV(cdev), - "WB Framedone expired\n"); + wb_info.enabled) { + if (wb->wait_framedone(wb)) + dev_warn(DEV(cdev), + "WB Framedone expired\n"); } + + /* if wb is disabled and wb was enabled in prev + * comp - set m2m flag. */ + if (!oi->cfg.enabled && wb_info.enabled && + wb_info.source == mgr->id && + wb_info.mode == OMAP_WB_MEM2MEM_MODE) + m2m_mgr_mode = true; + + /* set m2m_mgr_mode if we will capture in m2m mode + * from the manager */ + if (oi->cfg.enabled && + oi->cfg.wb_mode == OMAP_WB_MEM2MEM_MODE && + oi->cfg.wb_source == mgr->id) + m2m_mgr_mode = true; + r = set_dss_wb_info(oi); - } else { + break; + } + } + + for (oix = 0; oix < comp->frm.num_ovls; oix++) { + struct dss2_ovl_info *oi = comp->ovls + oix; + + if (oi->cfg.ix != OMAP_DSS_WB) { + /* keep track of disabled overlays */ + if (!oi->cfg.enabled) + dmask |= 1 << oi->cfg.ix; + + if (r && !comp->must_apply) + continue; + + dump_ovl_info(cdev, oi); + + if (oi->cfg.ix >= cdev->num_ovls) { + r = -EINVAL; + continue; + } + ovl = cdev->ovls[oi->cfg.ix]; /* set overlays' manager & info */ @@ -580,9 +615,10 @@ static int dsscomp_apply(dsscomp_t comp) r = -EBUSY; goto skip_ovl_set; } + if (ovl->manager != mgr) { mutex_lock(&mtx); - if (!mgrq[comp->ix].blanking) { + if (!mgrq[comp->ix].blanking || m2m_mgr_mode) { /* * Ideally, we should call * ovl->unset_manager(ovl), @@ -627,7 +663,7 @@ skip_ovl_set: * composition. Otherwise, we can skip the composition now. */ if (!r || comp->must_apply) { - r = set_dss_mgr_info(&d->mgr, &cb); + r = set_dss_mgr_info(&d->mgr, &cb, m2m_mgr_mode); cb_programmed = r == 0; } @@ -699,9 +735,9 @@ skip_ovl_set: } mutex_lock(&mtx); - if (mgrq[comp->ix].blanking) { + if (mgrq[comp->ix].blanking && !m2m_mgr_mode) { pr_info_ratelimited("ignoring apply mgr(%s) while blanking\n", - mgr->name); + mgr->name); r = -ENODEV; } else { if (wb_apply) { @@ -712,7 +748,9 @@ skip_ovl_set: } r = mgr->apply(mgr); if (r) - dev_err(DEV(cdev), "failed while applying %d", r); + dev_err(DEV(cdev), + "failed while applying mgr[%d] r:%d\n", + mgr->id, r); /* keep error if set_mgr_info failed */ if (!r && !cb_programmed) r = -EINVAL; @@ -732,11 +770,25 @@ skip_ovl_set: if (omap_dss_manager_unregister_callback(mgr, &cb)) r = 0; } + + /* This blanking is needed, when we received composition without WB for + * disabling pipes, which are sources for manager, which is source for + * WB. In this case manager apply operation is skipped and we need to + * update caches and to invoke callback functions to free the buffers. + */ + if (!m2m_mgr_mode && wb_info.mode == OMAP_WB_MEM2MEM_MODE && + wb_info.source == mgr->id && mgr->device && + mgr->device->state != OMAP_DSS_DISPLAY_ACTIVE && + comp->must_apply) { + mgr->blank(mgr, true); + goto done; + } + /* if failed to apply, kick out prior composition */ if (comp->must_apply && r) mgr->blank(mgr, true); - if (!r && (d->mode & DSSCOMP_SETUP_MODE_DISPLAY)) { + if (!r && (d->mode & DSSCOMP_SETUP_MODE_DISPLAY) && !m2m_mgr_mode) { if (dssdev_manually_updated(dssdev) && drv->update) { r = drv->update(dssdev, d->win.x, d->win.y, d->win.w, d->win.h); @@ -750,8 +802,7 @@ skip_ovl_set: */ r = 0; } - } - else + } else /* wait for sync to do smooth animations */ mgr->wait_for_vsync(mgr); } |