aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2011-09-08 01:59:17 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2011-10-03 09:51:55 -0400
commit54128701ecccbeb6f740030e0cc5f8e5701fe8ee (patch)
treed0c7e5fee25d9458f105acc20b5f4accc2d82bcd /drivers/video/omap2/dss
parentb8c095b4d62f90ed8da0cca7116125863b1d8bef (diff)
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>
Diffstat (limited to 'drivers/video/omap2/dss')
-rw-r--r--drivers/video/omap2/dss/dispc.c24
-rw-r--r--drivers/video/omap2/dss/overlay.c72
2 files changed, 96 insertions, 0 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index fa7aadfec7b8..6892cfd2e3b7 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -739,6 +739,27 @@ static void dispc_ovl_set_vid_size(enum omap_plane plane, int width, int height)
739 dispc_write_reg(DISPC_OVL_SIZE(plane), val); 739 dispc_write_reg(DISPC_OVL_SIZE(plane), val);
740} 740}
741 741
742static void dispc_ovl_set_zorder(enum omap_plane plane, u8 zorder)
743{
744 struct omap_overlay *ovl = omap_dss_get_overlay(plane);
745
746 if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
747 return;
748
749 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26);
750}
751
752static void dispc_ovl_enable_zorder_planes(void)
753{
754 int i;
755
756 if (!dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
757 return;
758
759 for (i = 0; i < dss_feat_get_num_ovls(); i++)
760 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25);
761}
762
742static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, bool enable) 763static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, bool enable)
743{ 764{
744 struct omap_overlay *ovl = omap_dss_get_overlay(plane); 765 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,
1866 dispc_ovl_set_rotation_attrs(plane, oi->rotation, oi->mirror, 1887 dispc_ovl_set_rotation_attrs(plane, oi->rotation, oi->mirror,
1867 oi->color_mode); 1888 oi->color_mode);
1868 1889
1890 dispc_ovl_set_zorder(plane, oi->zorder);
1869 dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha); 1891 dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha);
1870 dispc_ovl_setup_global_alpha(plane, oi->global_alpha); 1892 dispc_ovl_setup_global_alpha(plane, oi->global_alpha);
1871 1893
@@ -3317,6 +3339,8 @@ static void _omap_dispc_initial_config(void)
3317 dispc_read_plane_fifo_sizes(); 3339 dispc_read_plane_fifo_sizes();
3318 3340
3319 dispc_configure_burst_sizes(); 3341 dispc_configure_burst_sizes();
3342
3343 dispc_ovl_enable_zorder_planes();
3320} 3344}
3321 3345
3322/* DISPC HW IP initialisation */ 3346/* DISPC HW IP initialisation */
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 11d21e3347ad..ab8e40e48759 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -311,6 +311,42 @@ static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
311 return size; 311 return size;
312} 312}
313 313
314static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
315{
316 return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.zorder);
317}
318
319static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
320 const char *buf, size_t size)
321{
322 int r;
323 u8 zorder;
324 struct omap_overlay_info info;
325
326 if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
327 return -ENODEV;
328
329 r = kstrtou8(buf, 0, &zorder);
330 if (r)
331 return r;
332
333 ovl->get_overlay_info(ovl, &info);
334
335 info.zorder = zorder;
336
337 r = ovl->set_overlay_info(ovl, &info);
338 if (r)
339 return r;
340
341 if (ovl->manager) {
342 r = ovl->manager->apply(ovl->manager);
343 if (r)
344 return r;
345 }
346
347 return size;
348}
349
314struct overlay_attribute { 350struct overlay_attribute {
315 struct attribute attr; 351 struct attribute attr;
316 ssize_t (*show)(struct omap_overlay *, char *); 352 ssize_t (*show)(struct omap_overlay *, char *);
@@ -337,6 +373,8 @@ static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
337static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR, 373static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
338 overlay_pre_mult_alpha_show, 374 overlay_pre_mult_alpha_show,
339 overlay_pre_mult_alpha_store); 375 overlay_pre_mult_alpha_store);
376static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
377 overlay_zorder_show, overlay_zorder_store);
340 378
341static struct attribute *overlay_sysfs_attrs[] = { 379static struct attribute *overlay_sysfs_attrs[] = {
342 &overlay_attr_name.attr, 380 &overlay_attr_name.attr,
@@ -348,6 +386,7 @@ static struct attribute *overlay_sysfs_attrs[] = {
348 &overlay_attr_enabled.attr, 386 &overlay_attr_enabled.attr,
349 &overlay_attr_global_alpha.attr, 387 &overlay_attr_global_alpha.attr,
350 &overlay_attr_pre_mult_alpha.attr, 388 &overlay_attr_pre_mult_alpha.attr,
389 &overlay_attr_zorder.attr,
351 NULL 390 NULL
352}; 391};
353 392
@@ -397,6 +436,7 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
397 struct omap_overlay_info *info; 436 struct omap_overlay_info *info;
398 u16 outw, outh; 437 u16 outw, outh;
399 u16 dw, dh; 438 u16 dw, dh;
439 int i;
400 440
401 if (!dssdev) 441 if (!dssdev)
402 return 0; 442 return 0;
@@ -452,6 +492,31 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
452 return -EINVAL; 492 return -EINVAL;
453 } 493 }
454 494
495 if (ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) {
496 if (info->zorder < 0 || info->zorder > 3) {
497 DSSERR("zorder out of range: %d\n",
498 info->zorder);
499 return -EINVAL;
500 }
501 /*
502 * Check that zorder doesn't match with zorder of any other
503 * overlay which is enabled and is also connected to the same
504 * manager
505 */
506 for (i = 0; i < omap_dss_get_num_overlays(); i++) {
507 struct omap_overlay *tmp_ovl = omap_dss_get_overlay(i);
508
509 if (tmp_ovl->id != ovl->id &&
510 tmp_ovl->manager == ovl->manager &&
511 tmp_ovl->info.enabled == true &&
512 tmp_ovl->info.zorder == info->zorder) {
513 DSSERR("%s and %s have same zorder: %d\n",
514 ovl->name, tmp_ovl->name, info->zorder);
515 return -EINVAL;
516 }
517 }
518 }
519
455 return 0; 520 return 0;
456} 521}
457 522
@@ -604,21 +669,28 @@ void dss_init_overlays(struct platform_device *pdev)
604 ovl->name = "gfx"; 669 ovl->name = "gfx";
605 ovl->id = OMAP_DSS_GFX; 670 ovl->id = OMAP_DSS_GFX;
606 ovl->info.global_alpha = 255; 671 ovl->info.global_alpha = 255;
672 ovl->info.zorder = 0;
607 break; 673 break;
608 case 1: 674 case 1:
609 ovl->name = "vid1"; 675 ovl->name = "vid1";
610 ovl->id = OMAP_DSS_VIDEO1; 676 ovl->id = OMAP_DSS_VIDEO1;
611 ovl->info.global_alpha = 255; 677 ovl->info.global_alpha = 255;
678 ovl->info.zorder =
679 dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0;
612 break; 680 break;
613 case 2: 681 case 2:
614 ovl->name = "vid2"; 682 ovl->name = "vid2";
615 ovl->id = OMAP_DSS_VIDEO2; 683 ovl->id = OMAP_DSS_VIDEO2;
616 ovl->info.global_alpha = 255; 684 ovl->info.global_alpha = 255;
685 ovl->info.zorder =
686 dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0;
617 break; 687 break;
618 case 3: 688 case 3:
619 ovl->name = "vid3"; 689 ovl->name = "vid3";
620 ovl->id = OMAP_DSS_VIDEO3; 690 ovl->id = OMAP_DSS_VIDEO3;
621 ovl->info.global_alpha = 255; 691 ovl->info.global_alpha = 255;
692 ovl->info.zorder =
693 dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0;
622 break; 694 break;
623 } 695 }
624 696