forked from Minki/linux
OMAPDSS: DISPC: zorder support for DSS overlays
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>
This commit is contained in:
parent
b8c095b4d6
commit
54128701ec
@ -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);
|
||||
@ -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);
|
||||
|
||||
@ -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 */
|
||||
|
@ -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 *);
|
||||
@ -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,
|
||||
@ -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
|
||||
};
|
||||
|
||||
@ -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;
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user