Skip to content

Commit

Permalink
OMAPDSS: DISPC: zorder support for DSS overlays
Browse files Browse the repository at this point in the history
Add zorder support on OMAP4, this feature allows deciding the visibility order
of the overlays based on the zorder value provided as an overlay info parameter
or a sysfs attribute of the overlay object.

Use the overlay cap OMAP_DSS_OVL_CAP_ZORDER to determine whether zorder is
supported for the overlay or not. Use dss feature FEAT_ALPHA_FREE_ZORDER
if the caps are not available.

Ensure that all overlays that are enabled and connected to the same manager
have different zorders. Swapping zorders of 2 enabled overlays currently
requires disabling one of the overlays.

Signed-off-by: Archit Taneja <archit@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
  • Loading branch information
Archit Taneja authored and Tomi Valkeinen committed Oct 3, 2011
1 parent b8c095b commit 5412870
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 0 deletions.
24 changes: 24 additions & 0 deletions drivers/video/omap2/dss/dispc.c
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,27 @@ static void dispc_ovl_set_vid_size(enum omap_plane plane, int width, int height)
dispc_write_reg(DISPC_OVL_SIZE(plane), val);
}

static void dispc_ovl_set_zorder(enum omap_plane plane, u8 zorder)
{
struct omap_overlay *ovl = omap_dss_get_overlay(plane);

if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
return;

REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26);
}

static void dispc_ovl_enable_zorder_planes(void)
{
int i;

if (!dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
return;

for (i = 0; i < dss_feat_get_num_ovls(); i++)
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25);
}

static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, bool enable)
{
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
Expand Down Expand Up @@ -1866,6 +1887,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
dispc_ovl_set_rotation_attrs(plane, oi->rotation, oi->mirror,
oi->color_mode);

dispc_ovl_set_zorder(plane, oi->zorder);
dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha);
dispc_ovl_setup_global_alpha(plane, oi->global_alpha);

Expand Down Expand Up @@ -3317,6 +3339,8 @@ static void _omap_dispc_initial_config(void)
dispc_read_plane_fifo_sizes();

dispc_configure_burst_sizes();

dispc_ovl_enable_zorder_planes();
}

/* DISPC HW IP initialisation */
Expand Down
72 changes: 72 additions & 0 deletions drivers/video/omap2/dss/overlay.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,42 @@ static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
return size;
}

static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.zorder);
}

static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
const char *buf, size_t size)
{
int r;
u8 zorder;
struct omap_overlay_info info;

if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
return -ENODEV;

r = kstrtou8(buf, 0, &zorder);
if (r)
return r;

ovl->get_overlay_info(ovl, &info);

info.zorder = zorder;

r = ovl->set_overlay_info(ovl, &info);
if (r)
return r;

if (ovl->manager) {
r = ovl->manager->apply(ovl->manager);
if (r)
return r;
}

return size;
}

struct overlay_attribute {
struct attribute attr;
ssize_t (*show)(struct omap_overlay *, char *);
Expand All @@ -337,6 +373,8 @@ static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
overlay_pre_mult_alpha_show,
overlay_pre_mult_alpha_store);
static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
overlay_zorder_show, overlay_zorder_store);

static struct attribute *overlay_sysfs_attrs[] = {
&overlay_attr_name.attr,
Expand All @@ -348,6 +386,7 @@ static struct attribute *overlay_sysfs_attrs[] = {
&overlay_attr_enabled.attr,
&overlay_attr_global_alpha.attr,
&overlay_attr_pre_mult_alpha.attr,
&overlay_attr_zorder.attr,
NULL
};

Expand Down Expand Up @@ -397,6 +436,7 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
struct omap_overlay_info *info;
u16 outw, outh;
u16 dw, dh;
int i;

if (!dssdev)
return 0;
Expand Down Expand Up @@ -452,6 +492,31 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
return -EINVAL;
}

if (ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) {
if (info->zorder < 0 || info->zorder > 3) {
DSSERR("zorder out of range: %d\n",
info->zorder);
return -EINVAL;
}
/*
* Check that zorder doesn't match with zorder of any other
* overlay which is enabled and is also connected to the same
* manager
*/
for (i = 0; i < omap_dss_get_num_overlays(); i++) {
struct omap_overlay *tmp_ovl = omap_dss_get_overlay(i);

if (tmp_ovl->id != ovl->id &&
tmp_ovl->manager == ovl->manager &&
tmp_ovl->info.enabled == true &&
tmp_ovl->info.zorder == info->zorder) {
DSSERR("%s and %s have same zorder: %d\n",
ovl->name, tmp_ovl->name, info->zorder);
return -EINVAL;
}
}
}

return 0;
}

Expand Down Expand Up @@ -604,21 +669,28 @@ void dss_init_overlays(struct platform_device *pdev)
ovl->name = "gfx";
ovl->id = OMAP_DSS_GFX;
ovl->info.global_alpha = 255;
ovl->info.zorder = 0;
break;
case 1:
ovl->name = "vid1";
ovl->id = OMAP_DSS_VIDEO1;
ovl->info.global_alpha = 255;
ovl->info.zorder =
dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0;
break;
case 2:
ovl->name = "vid2";
ovl->id = OMAP_DSS_VIDEO2;
ovl->info.global_alpha = 255;
ovl->info.zorder =
dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0;
break;
case 3:
ovl->name = "vid3";
ovl->id = OMAP_DSS_VIDEO3;
ovl->info.global_alpha = 255;
ovl->info.zorder =
dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0;
break;
}

Expand Down
1 change: 1 addition & 0 deletions include/video/omapdss.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ struct omap_overlay_info {
u16 out_height; /* if 0, out_height == height */
u8 global_alpha;
u8 pre_mult_alpha;
u8 zorder;
};

struct omap_overlay {
Expand Down

0 comments on commit 5412870

Please sign in to comment.