aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r--drivers/video/omap2/dsscomp/base.c6
-rw-r--r--drivers/video/omap2/dsscomp/gralloc.c159
-rw-r--r--drivers/video/omap2/dsscomp/queue.c1
3 files changed, 114 insertions, 52 deletions
diff --git a/drivers/video/omap2/dsscomp/base.c b/drivers/video/omap2/dsscomp/base.c
index b54fc50..7d208e1 100644
--- a/drivers/video/omap2/dsscomp/base.c
+++ b/drivers/video/omap2/dsscomp/base.c
@@ -478,6 +478,8 @@ void dump_total_comp_info(struct dsscomp_dev *cdev,
struct dsscomp_setup_dispc_data *d,
const char *phase)
{
+ int i;
+
if (!(debug & DEBUG_COMPOSITIONS))
return;
@@ -486,6 +488,8 @@ void dump_total_comp_info(struct dsscomp_dev *cdev,
(d->mode & DSSCOMP_SETUP_MODE_APPLY) ? 'A' : '-',
(d->mode & DSSCOMP_SETUP_MODE_DISPLAY) ? 'D' : '-',
(d->mode & DSSCOMP_SETUP_MODE_CAPTURE) ? 'C' : '-');
- print_mgr_info(cdev, &d->mgr);
+
+ for (i = 0; i < d->num_mgrs && i < ARRAY_SIZE(d->mgrs); i++)
+ print_mgr_info(cdev, d->mgrs + i);
printk("n=%d\n", d->num_ovls);
}
diff --git a/drivers/video/omap2/dsscomp/gralloc.c b/drivers/video/omap2/dsscomp/gralloc.c
index fe3e2a2..e2a9515 100644
--- a/drivers/video/omap2/dsscomp/gralloc.c
+++ b/drivers/video/omap2/dsscomp/gralloc.c
@@ -37,7 +37,7 @@ struct dsscomp_gralloc_t {
/* queued gralloc compositions */
static LIST_HEAD(flip_queue);
-static u32 ovl_set_mask;
+static u32 ovl_use_mask[MAX_MANAGERS];
static void unpin_tiler_blocks(struct list_head *slots)
{
@@ -127,10 +127,15 @@ int dsscomp_gralloc_queue(struct dsscomp_setup_dispc_data *d,
int r = 0;
struct omap_dss_device *dev;
struct omap_overlay_manager *mgr;
- dsscomp_t comp;
- u32 ovl_new_set_mask = 0;
+ dsscomp_t comp[MAX_MANAGERS];
+ u32 ovl_new_use_mask[MAX_MANAGERS];
+ u32 mgr_set_mask = 0;
+ u32 ovl_set_mask = 0;
+
+ u32 channels[ARRAY_SIZE(d->mgrs)], ch;
int skip;
struct dsscomp_gralloc_t *gsync;
+ struct dss2_rect_t win = { .w = 0 };
/* reserve tiler areas if not already done so */
dsscomp_gralloc_init(cdev);
@@ -162,47 +167,100 @@ int dsscomp_gralloc_queue(struct dsscomp_setup_dispc_data *d,
mutex_unlock(&mtx);
+ d->num_mgrs = min(d->num_mgrs, (u16) ARRAY_SIZE(d->mgrs));
+ d->num_ovls = min(d->num_ovls, (u16) ARRAY_SIZE(d->ovls));
+
+ memset(comp, 0, sizeof(comp));
+ memset(ovl_new_use_mask, 0, sizeof(ovl_new_use_mask));
+
if (skip)
- goto skip_mgr;
+ goto skip_comp;
+
+ d->mode = DSSCOMP_SETUP_DISPLAY;
+
+ /* mark managers we are using */
+ for (i = 0; i < d->num_mgrs; i++) {
+ /* verify display is valid & connected, ignore if not */
+ if (d->mgrs[i].ix >= cdev->num_displays)
+ continue;
+ dev = cdev->displays[d->mgrs[i].ix];
+ if (!dev) {
+ dev_warn(DEV(cdev), "failed to get display%d\n",
+ d->mgrs[i].ix);
+ continue;
+ }
+ mgr = dev->manager;
+ if (!mgr) {
+ dev_warn(DEV(cdev), "no manager for display%d\n",
+ d->mgrs[i].ix);
+ continue;
+ }
+ channels[i] = ch = mgr->id;
+ mgr_set_mask |= 1 << ch;
- /* verify display is valid and connected */
- if (d->mgr.ix >= cdev->num_displays) {
- r = -EINVAL;
- goto skip_mgr;
- }
- dev = cdev->displays[d->mgr.ix];
- if (!dev) {
- r = -EINVAL;
- goto skip_mgr;
- }
- mgr = dev->manager;
- if (!mgr) {
- r = -ENODEV;
- goto skip_mgr;
+ /* swap red & blue if requested */
+ if (d->mgrs[i].swap_rb)
+ swap_rb_in_mgr_info(d->mgrs + i);
}
- comp = dsscomp_new(mgr);
- if (IS_ERR(comp)) {
- r = PTR_ERR(comp);
- goto skip_mgr;
- }
+ /* create dsscomp objects for set managers (including active ones) */
+ for (ch = 0; ch < MAX_MANAGERS; ch++) {
+ if (!(mgr_set_mask & (1 << ch)) && !ovl_use_mask[ch])
+ continue;
- comp->frm.mode = DSSCOMP_SETUP_DISPLAY;
- comp->must_apply = true;
+ mgr = cdev->mgrs[ch];
- /* swap red & blue if requested */
- if (d->mgr.swap_rb) {
- swap_rb_in_mgr_info(&d->mgr);
- for (i = 0; i < d->num_ovls; i++)
- swap_rb_in_ovl_info(d->ovls + i);
+ comp[ch] = dsscomp_new(mgr);
+ if (IS_ERR(comp[ch])) {
+ comp[ch] = NULL;
+ dev_warn(DEV(cdev), "failed to get composition on %s\n",
+ mgr->name);
+ continue;
+ }
+
+ /* set basic manager information for blanked managers */
+ if (!(mgr_set_mask & (1 << ch))) {
+ struct dss2_mgr_info mi = {
+ .alpha_blending = true,
+ .ix = comp[ch]->frm.mgr.ix,
+ };
+ dsscomp_set_mgr(comp[ch], &mi);
+ }
+
+ comp[ch]->must_apply = true;
+ r = dsscomp_setup(comp[ch], d->mode, win);
+ if (r)
+ dev_err(DEV(cdev), "failed to setup comp (%d)\n", r);
+ }
+
+ /* configure manager data from gralloc composition */
+ for (i = 0; i < d->num_mgrs; i++) {
+ ch = channels[i];
+ r = dsscomp_set_mgr(comp[ch], d->mgrs + i);
+ if (r)
+ dev_err(DEV(cdev), "failed to set mgr%d (%d)\n", ch, r);
}
/* NOTE: none of the dsscomp sets should fail as composition is new */
- r = dsscomp_set_mgr(comp, &d->mgr);
- if (r)
- dev_err(DEV(cdev), "failed to set mgr (%d)\n", r);
for (i = 0; i < d->num_ovls; i++) {
struct dss2_ovl_info *oi = d->ovls + i;
+ u32 mgr_ix = oi->cfg.mgr_ix;
+
+ /* verify manager index */
+ if (mgr_ix >= d->num_mgrs) {
+ dev_err(DEV(cdev), "invalid manager for ovl%d\n",
+ oi->cfg.ix);
+ continue;
+ }
+ ch = channels[mgr_ix];
+
+ /* skip overlays on compositions we could not create */
+ if (!comp[ch])
+ continue;
+
+ /* swap red & blue if requested */
+ if (d->mgrs[mgr_ix].swap_rb)
+ swap_rb_in_ovl_info(d->ovls + i);
/* map non-TILER buffers to 1D */
if (pas[i] && oi->cfg.enabled) {
@@ -228,43 +286,44 @@ int dsscomp_gralloc_queue(struct dsscomp_setup_dispc_data *d,
}
if (oi->cfg.enabled)
- ovl_new_set_mask |= 1 << oi->cfg.ix;
+ ovl_new_use_mask[ch] |= 1 << oi->cfg.ix;
- r = dsscomp_set_ovl(comp, oi);
+ r = dsscomp_set_ovl(comp[ch], oi);
if (r)
dev_err(DEV(cdev), "failed to set ovl%d (%d)\n",
oi->cfg.ix, r);
+ else
+ ovl_set_mask |= 1 << oi->cfg.ix;
}
- r = dsscomp_setup(comp, d->mode, d->win);
- if (r)
- dev_err(DEV(cdev), "failed to setup comp (%d)\n", r);
-
- if (r) {
- dsscomp_drop(comp);
- } else {
+ for (ch = 0; ch < MAX_MANAGERS; ch++) {
/* disable all overlays not specifically set from prior frame */
- u32 mask = ovl_set_mask & ~ovl_new_set_mask;
+ u32 mask = ovl_use_mask[ch] & ~ovl_set_mask;
+
+ if (!comp[ch])
+ continue;
+
while (mask) {
struct dss2_ovl_info oi = {
.cfg.zonly = true,
.cfg.enabled = false,
.cfg.ix = fls(mask) - 1,
};
- dsscomp_set_ovl(comp, &oi);
+ dsscomp_set_ovl(comp[ch], &oi);
mask &= ~(1 << oi.cfg.ix);
}
- comp->extra_cb = dsscomp_gralloc_cb;
- comp->extra_cb_data = gsync;
+ /* associate dsscomp objects with this gralloc composition */
+ comp[ch]->extra_cb = dsscomp_gralloc_cb;
+ comp[ch]->extra_cb_data = gsync;
atomic_inc(&gsync->refs);
- r = dsscomp_delayed_apply(comp);
+ r = dsscomp_delayed_apply(comp[ch]);
if (r)
dev_err(DEV(cdev), "failed to apply comp (%d)\n", r);
else
- ovl_set_mask = ovl_new_set_mask;
+ ovl_use_mask[ch] = ovl_new_use_mask[ch];
}
-skip_mgr:
+skip_comp:
/* release sync object ref - this completes unapplied compositions */
dsscomp_gralloc_cb(gsync, DSS_COMPLETION_RELEASED);
@@ -284,7 +343,7 @@ static void dsscomp_early_suspend_cb(void *data, int status)
static void dsscomp_early_suspend(struct early_suspend *h)
{
struct dsscomp_setup_dispc_data d = {
- .mgr.alpha_blending = 1,
+ .num_mgrs = 0,
};
int err;
diff --git a/drivers/video/omap2/dsscomp/queue.c b/drivers/video/omap2/dsscomp/queue.c
index 0f8c8a6..b6f625b 100644
--- a/drivers/video/omap2/dsscomp/queue.c
+++ b/drivers/video/omap2/dsscomp/queue.c
@@ -579,7 +579,6 @@ skip_ovl_set:
done:
return r;
}
-EXPORT_SYMBOL(dsscomp_apply);
struct dsscomp_apply_work {
struct work_struct work;