summaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/dispc.c
diff options
context:
space:
mode:
authorChandrabhanu Mahapatra <cmahapatra@ti.com>2012-05-11 15:49:55 +0200
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-05-22 09:59:15 +0200
commit65e006ff4bb06d42b532f866a846db6e4e637723 (patch)
tree8b791304b33ea7888d7e43504865d899b5d1a096 /drivers/video/omap2/dss/dispc.c
parentOMAPDSS: VRFB: remove compiler warnings when CONFIG_BUG=n (diff)
downloadlinux-65e006ff4bb06d42b532f866a846db6e4e637723.tar.xz
linux-65e006ff4bb06d42b532f866a846db6e4e637723.zip
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>
Diffstat (limited to 'drivers/video/omap2/dss/dispc.c')
-rw-r--r--drivers/video/omap2/dss/dispc.c60
1 files changed, 59 insertions, 1 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,
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1);
}
+static void dispc_ovl_configure_burst_type(enum omap_plane plane,
+ enum omap_dss_rotation_type rotation_type)
+{
+ if (dss_has_feature(FEAT_BURST_2D) == 0)
+ return;
+
+ if (rotation_type == OMAP_DSS_ROT_TILER)
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), 1, 29, 29);
+ else
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), 0, 29, 29);
+}
+
void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel)
{
int shift;
@@ -1731,6 +1743,45 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
}
}
+static void calc_tiler_rotation_offset(u16 screen_width, u16 width,
+ enum omap_color_mode color_mode, bool fieldmode,
+ unsigned int field_offset, unsigned *offset0, unsigned *offset1,
+ s32 *row_inc, s32 *pix_inc, int x_predecim, int y_predecim)
+{
+ u8 ps;
+
+ switch (color_mode) {
+ case OMAP_DSS_COLOR_CLUT1:
+ case OMAP_DSS_COLOR_CLUT2:
+ case OMAP_DSS_COLOR_CLUT4:
+ case OMAP_DSS_COLOR_CLUT8:
+ BUG();
+ return;
+ default:
+ ps = color_mode_to_bpp(color_mode) / 8;
+ break;
+ }
+
+ DSSDBG("scrw %d, width %d\n", screen_width, width);
+
+ /*
+ * field 0 = even field = bottom field
+ * field 1 = odd field = top field
+ */
+ *offset1 = 0;
+ if (field_offset)
+ *offset0 = *offset1 + field_offset * screen_width * ps;
+ else
+ *offset0 = *offset1;
+ *row_inc = pixinc(1 + (y_predecim * screen_width - width * x_predecim) +
+ (fieldmode ? screen_width : 0), ps);
+ if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+ color_mode == OMAP_DSS_COLOR_UYVY)
+ *pix_inc = pixinc(x_predecim, 2 * ps);
+ else
+ *pix_inc = pixinc(x_predecim, ps);
+}
+
/*
* This function is used to avoid synclosts in OMAP3, because of some
* undocumented horizontal position and timing related limitations.
@@ -2122,7 +2173,12 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
row_inc = 0;
pix_inc = 0;
- if (oi->rotation_type == OMAP_DSS_ROT_DMA)
+ if (oi->rotation_type == OMAP_DSS_ROT_TILER)
+ calc_tiler_rotation_offset(oi->screen_width, in_width,
+ oi->color_mode, fieldmode, field_offset,
+ &offset0, &offset1, &row_inc, &pix_inc,
+ x_predecim, y_predecim);
+ else if (oi->rotation_type == OMAP_DSS_ROT_DMA)
calc_dma_rotation_offset(oi->rotation, oi->mirror,
oi->screen_width, in_width, frame_height,
oi->color_mode, fieldmode, field_offset,
@@ -2140,6 +2196,8 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
dispc_ovl_set_color_mode(plane, oi->color_mode);
+ dispc_ovl_configure_burst_type(plane, oi->rotation_type);
+
dispc_ovl_set_ba0(plane, oi->paddr + offset0);
dispc_ovl_set_ba1(plane, oi->paddr + offset1);