|
@@ -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;
|
|
|
}
|
|
|
|