aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMykhailo Denysiuk <x0172934@ti.com>2012-06-24 15:05:47 +0300
committerZiyann <jaraidaniel@gmail.com>2014-11-19 21:10:34 +0100
commit5ca8a84a20463793775eb84cb2da8c3871824eb3 (patch)
tree00df50ff070366ccbf110cf8d86ca664ef05eb50
parent66b3a6593ad9e397ef6518509f96306a253067d6 (diff)
downloadkernel_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.c22
-rw-r--r--drivers/video/omap2/dsscomp/dsscomp.h3
-rw-r--r--drivers/video/omap2/dsscomp/queue.c105
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);
}