aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChandrabhanu Mahapatra <cmahapatra@ti.com>2012-05-11 09:49:55 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-05-22 03:59:15 -0400
commit65e006ff4bb06d42b532f866a846db6e4e637723 (patch)
tree8b791304b33ea7888d7e43504865d899b5d1a096
parent3cb6a1b9672a2e0937a1475e3d68e6c236133156 (diff)
OMAPDSS: DISPC: Support rotation through TILER
TILER is a block in OMAP4's DMM which lets DSS fetch frames in a rotated manner. Physical memory can be mapped to a portion of OMAP's system address space called TILER address space. The TILER address space is split into 8 views. Each view represents a rotated or mirrored form of the mapped physical memory. When a DISPC overlay's base address is programmed to one of these views, the TILER fetches the pixels according to the orientation of the view. A view is further split into 4 containers, each container holds elements of a particular size. Rotation can be achieved at the granularity of elements in the container. For more information on TILER, refer to the Memory Subsytem section in OMAP4 TRM. Rotation type TILER has been added which is used to exploit the capabilities of these 8 views for performing various rotations. When fetching from addresses mapped to TILER space, the DISPC DMA can fetch pixels in either 1D or 2D bursts. The fetch depends on which TILER container we are accessing. Accessing 8, 16 and 32 bit sized containers requires 2D bursts, and page mode sized containers require 1D bursts. The DSS2 user is expected to provide the Tiler address of the view that it is interested in. This is passed to the paddr and p_uv_addr parameters in omap_overlay_info. It is also expected to provide the stride value based on the view's orientation and container type, this should be passed to the screen_width parameter of omap_overlay_info. In calc_tiler_rotation_offset screen_width is used to calculate the required row_inc for DISPC. x_predecim and y_predecim are also used to calculate row_inc and pix_inc thereby adding predecimation support for TILER. Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
-rw-r--r--drivers/video/omap2/dss/dispc.c60
-rw-r--r--drivers/video/omap2/dss/dss_features.c16
-rw-r--r--drivers/video/omap2/dss/dss_features.h3
-rw-r--r--drivers/video/omap2/dss/overlay.c6
-rw-r--r--include/video/omapdss.h5
5 files changed, 87 insertions, 3 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 3d0576d1983c..9626b2c0c9e1 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -785,6 +785,18 @@ static void dispc_ovl_set_color_mode(enum omap_plane plane,
785 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1); 785 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1);
786} 786}
787 787
788static void dispc_ovl_configure_burst_type(enum omap_plane plane,
789 enum omap_dss_rotation_type rotation_type)
790{
791 if (dss_has_feature(FEAT_BURST_2D) == 0)
792 return;
793
794 if (rotation_type == OMAP_DSS_ROT_TILER)
795 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), 1, 29, 29);
796 else
797 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), 0, 29, 29);
798}
799
788void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel) 800void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel)
789{ 801{
790 int shift; 802 int shift;
@@ -1731,6 +1743,45 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
1731 } 1743 }
1732} 1744}
1733 1745
1746static void calc_tiler_rotation_offset(u16 screen_width, u16 width,
1747 enum omap_color_mode color_mode, bool fieldmode,
1748 unsigned int field_offset, unsigned *offset0, unsigned *offset1,
1749 s32 *row_inc, s32 *pix_inc, int x_predecim, int y_predecim)
1750{
1751 u8 ps;
1752
1753 switch (color_mode) {
1754 case OMAP_DSS_COLOR_CLUT1:
1755 case OMAP_DSS_COLOR_CLUT2:
1756 case OMAP_DSS_COLOR_CLUT4:
1757 case OMAP_DSS_COLOR_CLUT8:
1758 BUG();
1759 return;
1760 default:
1761 ps = color_mode_to_bpp(color_mode) / 8;
1762 break;
1763 }
1764
1765 DSSDBG("scrw %d, width %d\n", screen_width, width);
1766
1767 /*
1768 * field 0 = even field = bottom field
1769 * field 1 = odd field = top field
1770 */
1771 *offset1 = 0;
1772 if (field_offset)
1773 *offset0 = *offset1 + field_offset * screen_width * ps;
1774 else
1775 *offset0 = *offset1;
1776 *row_inc = pixinc(1 + (y_predecim * screen_width - width * x_predecim) +
1777 (fieldmode ? screen_width : 0), ps);
1778 if (color_mode == OMAP_DSS_COLOR_YUV2 ||
1779 color_mode == OMAP_DSS_COLOR_UYVY)
1780 *pix_inc = pixinc(x_predecim, 2 * ps);
1781 else
1782 *pix_inc = pixinc(x_predecim, ps);
1783}
1784
1734/* 1785/*
1735 * This function is used to avoid synclosts in OMAP3, because of some 1786 * This function is used to avoid synclosts in OMAP3, because of some
1736 * undocumented horizontal position and timing related limitations. 1787 * undocumented horizontal position and timing related limitations.
@@ -2122,7 +2173,12 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
2122 row_inc = 0; 2173 row_inc = 0;
2123 pix_inc = 0; 2174 pix_inc = 0;
2124 2175
2125 if (oi->rotation_type == OMAP_DSS_ROT_DMA) 2176 if (oi->rotation_type == OMAP_DSS_ROT_TILER)
2177 calc_tiler_rotation_offset(oi->screen_width, in_width,
2178 oi->color_mode, fieldmode, field_offset,
2179 &offset0, &offset1, &row_inc, &pix_inc,
2180 x_predecim, y_predecim);
2181 else if (oi->rotation_type == OMAP_DSS_ROT_DMA)
2126 calc_dma_rotation_offset(oi->rotation, oi->mirror, 2182 calc_dma_rotation_offset(oi->rotation, oi->mirror,
2127 oi->screen_width, in_width, frame_height, 2183 oi->screen_width, in_width, frame_height,
2128 oi->color_mode, fieldmode, field_offset, 2184 oi->color_mode, fieldmode, field_offset,
@@ -2140,6 +2196,8 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
2140 2196
2141 dispc_ovl_set_color_mode(plane, oi->color_mode); 2197 dispc_ovl_set_color_mode(plane, oi->color_mode);
2142 2198
2199 dispc_ovl_configure_burst_type(plane, oi->rotation_type);
2200
2143 dispc_ovl_set_ba0(plane, oi->paddr + offset0); 2201 dispc_ovl_set_ba0(plane, oi->paddr + offset0);
2144 dispc_ovl_set_ba1(plane, oi->paddr + offset1); 2202 dispc_ovl_set_ba1(plane, oi->paddr + offset1);
2145 2203
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 2627441731b1..938709724f0c 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -52,6 +52,8 @@ struct omap_dss_features {
52 const char * const *clksrc_names; 52 const char * const *clksrc_names;
53 const struct dss_param_range *dss_params; 53 const struct dss_param_range *dss_params;
54 54
55 const enum omap_dss_rotation_type supported_rotation_types;
56
55 const u32 buffer_size_unit; 57 const u32 buffer_size_unit;
56 const u32 burst_size_unit; 58 const u32 burst_size_unit;
57}; 59};
@@ -405,6 +407,7 @@ static const enum dss_feat_id omap4430_es1_0_dss_feat_list[] = {
405 FEAT_FIR_COEF_V, 407 FEAT_FIR_COEF_V,
406 FEAT_ALPHA_FREE_ZORDER, 408 FEAT_ALPHA_FREE_ZORDER,
407 FEAT_FIFO_MERGE, 409 FEAT_FIFO_MERGE,
410 FEAT_BURST_2D,
408}; 411};
409 412
410static const enum dss_feat_id omap4430_es2_0_1_2_dss_feat_list[] = { 413static const enum dss_feat_id omap4430_es2_0_1_2_dss_feat_list[] = {
@@ -422,6 +425,7 @@ static const enum dss_feat_id omap4430_es2_0_1_2_dss_feat_list[] = {
422 FEAT_FIR_COEF_V, 425 FEAT_FIR_COEF_V,
423 FEAT_ALPHA_FREE_ZORDER, 426 FEAT_ALPHA_FREE_ZORDER,
424 FEAT_FIFO_MERGE, 427 FEAT_FIFO_MERGE,
428 FEAT_BURST_2D,
425}; 429};
426 430
427static const enum dss_feat_id omap4_dss_feat_list[] = { 431static const enum dss_feat_id omap4_dss_feat_list[] = {
@@ -440,6 +444,7 @@ static const enum dss_feat_id omap4_dss_feat_list[] = {
440 FEAT_FIR_COEF_V, 444 FEAT_FIR_COEF_V,
441 FEAT_ALPHA_FREE_ZORDER, 445 FEAT_ALPHA_FREE_ZORDER,
442 FEAT_FIFO_MERGE, 446 FEAT_FIFO_MERGE,
447 FEAT_BURST_2D,
443}; 448};
444 449
445/* OMAP2 DSS Features */ 450/* OMAP2 DSS Features */
@@ -457,6 +462,7 @@ static const struct omap_dss_features omap2_dss_features = {
457 .overlay_caps = omap2_dss_overlay_caps, 462 .overlay_caps = omap2_dss_overlay_caps,
458 .clksrc_names = omap2_dss_clk_source_names, 463 .clksrc_names = omap2_dss_clk_source_names,
459 .dss_params = omap2_dss_param_range, 464 .dss_params = omap2_dss_param_range,
465 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
460 .buffer_size_unit = 1, 466 .buffer_size_unit = 1,
461 .burst_size_unit = 8, 467 .burst_size_unit = 8,
462}; 468};
@@ -476,6 +482,7 @@ static const struct omap_dss_features omap3430_dss_features = {
476 .overlay_caps = omap3430_dss_overlay_caps, 482 .overlay_caps = omap3430_dss_overlay_caps,
477 .clksrc_names = omap3_dss_clk_source_names, 483 .clksrc_names = omap3_dss_clk_source_names,
478 .dss_params = omap3_dss_param_range, 484 .dss_params = omap3_dss_param_range,
485 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
479 .buffer_size_unit = 1, 486 .buffer_size_unit = 1,
480 .burst_size_unit = 8, 487 .burst_size_unit = 8,
481}; 488};
@@ -494,6 +501,7 @@ static const struct omap_dss_features omap3630_dss_features = {
494 .overlay_caps = omap3630_dss_overlay_caps, 501 .overlay_caps = omap3630_dss_overlay_caps,
495 .clksrc_names = omap3_dss_clk_source_names, 502 .clksrc_names = omap3_dss_clk_source_names,
496 .dss_params = omap3_dss_param_range, 503 .dss_params = omap3_dss_param_range,
504 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
497 .buffer_size_unit = 1, 505 .buffer_size_unit = 1,
498 .burst_size_unit = 8, 506 .burst_size_unit = 8,
499}; 507};
@@ -514,6 +522,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
514 .overlay_caps = omap4_dss_overlay_caps, 522 .overlay_caps = omap4_dss_overlay_caps,
515 .clksrc_names = omap4_dss_clk_source_names, 523 .clksrc_names = omap4_dss_clk_source_names,
516 .dss_params = omap4_dss_param_range, 524 .dss_params = omap4_dss_param_range,
525 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
517 .buffer_size_unit = 16, 526 .buffer_size_unit = 16,
518 .burst_size_unit = 16, 527 .burst_size_unit = 16,
519}; 528};
@@ -533,6 +542,7 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
533 .overlay_caps = omap4_dss_overlay_caps, 542 .overlay_caps = omap4_dss_overlay_caps,
534 .clksrc_names = omap4_dss_clk_source_names, 543 .clksrc_names = omap4_dss_clk_source_names,
535 .dss_params = omap4_dss_param_range, 544 .dss_params = omap4_dss_param_range,
545 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
536 .buffer_size_unit = 16, 546 .buffer_size_unit = 16,
537 .burst_size_unit = 16, 547 .burst_size_unit = 16,
538}; 548};
@@ -552,6 +562,7 @@ static const struct omap_dss_features omap4_dss_features = {
552 .overlay_caps = omap4_dss_overlay_caps, 562 .overlay_caps = omap4_dss_overlay_caps,
553 .clksrc_names = omap4_dss_clk_source_names, 563 .clksrc_names = omap4_dss_clk_source_names,
554 .dss_params = omap4_dss_param_range, 564 .dss_params = omap4_dss_param_range,
565 .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
555 .buffer_size_unit = 16, 566 .buffer_size_unit = 16,
556 .burst_size_unit = 16, 567 .burst_size_unit = 16,
557}; 568};
@@ -672,6 +683,11 @@ void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end)
672 *end = omap_current_dss_features->reg_fields[id].end; 683 *end = omap_current_dss_features->reg_fields[id].end;
673} 684}
674 685
686bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type)
687{
688 return omap_current_dss_features->supported_rotation_types & rot_type;
689}
690
675void dss_features_init(void) 691void dss_features_init(void)
676{ 692{
677 if (cpu_is_omap24xx()) 693 if (cpu_is_omap24xx())
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 3736367089a1..bdf469f080e7 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -62,6 +62,7 @@ enum dss_feat_id {
62 FEAT_FIFO_MERGE, 62 FEAT_FIFO_MERGE,
63 /* An unknown HW bug causing the normal FIFO thresholds not to work */ 63 /* An unknown HW bug causing the normal FIFO thresholds not to work */
64 FEAT_OMAP3_DSI_FIFO_BUG, 64 FEAT_OMAP3_DSI_FIFO_BUG,
65 FEAT_BURST_2D,
65}; 66};
66 67
67/* DSS register field id */ 68/* DSS register field id */
@@ -110,6 +111,8 @@ const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id);
110u32 dss_feat_get_buffer_size_unit(void); /* in bytes */ 111u32 dss_feat_get_buffer_size_unit(void); /* in bytes */
111u32 dss_feat_get_burst_size_unit(void); /* in bytes */ 112u32 dss_feat_get_burst_size_unit(void); /* in bytes */
112 113
114bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type);
115
113bool dss_has_feature(enum dss_feat_id id); 116bool dss_has_feature(enum dss_feat_id id);
114void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); 117void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
115void dss_features_init(void); 118void dss_features_init(void);
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 0da5eb654ae9..b0ba60f88dd2 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -628,6 +628,12 @@ int dss_ovl_simple_check(struct omap_overlay *ovl,
628 return -EINVAL; 628 return -EINVAL;
629 } 629 }
630 630
631 if (dss_feat_rotation_type_supported(info->rotation_type) == 0) {
632 DSSERR("check_overlay: rotation type %d not supported\n",
633 info->rotation_type);
634 return -EINVAL;
635 }
636
631 return 0; 637 return 0;
632} 638}
633 639
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index bb30242eeea1..c8e59b4a3364 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -175,8 +175,9 @@ enum omap_dss_overlay_managers {
175}; 175};
176 176
177enum omap_dss_rotation_type { 177enum omap_dss_rotation_type {
178 OMAP_DSS_ROT_DMA = 0, 178 OMAP_DSS_ROT_DMA = 1 << 0,
179 OMAP_DSS_ROT_VRFB = 1, 179 OMAP_DSS_ROT_VRFB = 1 << 1,
180 OMAP_DSS_ROT_TILER = 1 << 2,
180}; 181};
181 182
182/* clockwise rotation angle */ 183/* clockwise rotation angle */