aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorCraig Stout <craig.stout@ti.com>2012-06-22 12:38:58 -0700
committerZiyann <jaraidaniel@gmail.com>2014-10-01 13:00:51 +0200
commitf3b9815dbd5e35de15d24901f32307521ed0d8f5 (patch)
treeee99e34272349d113584b7322679367eafbdc403 /drivers/misc
parent0bb7be3adc380a0ef8559f129d686356f3ee20d1 (diff)
downloadkernel_samsung_tuna-f3b9815dbd5e35de15d24901f32307521ed0d8f5.zip
kernel_samsung_tuna-f3b9815dbd5e35de15d24901f32307521ed0d8f5.tar.gz
kernel_samsung_tuna-f3b9815dbd5e35de15d24901f32307521ed0d8f5.tar.bz2
gcx: yuv support improvements.
Added UYVY and YUY2 formats for input and output. Also fixes some issues with alignment for NV12. Also adds destination stride check for all surfaces. Change-Id: I7a3c99f5fba1c95474039300d1cc11ee19f01398 Signed-off-by: Craig Stout <craig.stout@ti.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/gcx/gcbv/gcbv.c70
1 files changed, 62 insertions, 8 deletions
diff --git a/drivers/misc/gcx/gcbv/gcbv.c b/drivers/misc/gcx/gcbv/gcbv.c
index d8ef08b..f08f67b 100644
--- a/drivers/misc/gcx/gcbv/gcbv.c
+++ b/drivers/misc/gcx/gcbv/gcbv.c
@@ -1264,6 +1264,16 @@ static struct bvformatxlate g_format_nv12 = {
.bitspp = 8,
.format = GCREG_DE_FORMAT_NV12,
};
+static struct bvformatxlate g_format_uyvy = {
+ .type = BVFMT_YUV,
+ .bitspp = 16,
+ .format = GCREG_DE_FORMAT_UYVY
+};
+static struct bvformatxlate g_format_yuy2 = {
+ .type = BVFMT_YUV,
+ .bitspp = 16,
+ .format = GCREG_DE_FORMAT_YUY2
+};
static struct bvformatxlate formatxlate[] = {
/* #0: OCDFMT_xRGB12
@@ -1453,6 +1463,16 @@ static int parse_format(enum ocdformat ocdformat, struct bvformatxlate **format)
*format = &g_format_nv12;
return 1;
+ case OCDFMT_UYVY:
+ GCDBG(GCZONE_FORMAT, "OCDFMT_UYVY\n");
+ *format = &g_format_uyvy;
+ return 1;
+
+ case OCDFMT_YUY2:
+ GCDBG(GCZONE_FORMAT, "OCDFMT_YUY2\n");
+ *format = &g_format_yuy2;
+ return 1;
+
default:
break;
}
@@ -2659,6 +2679,17 @@ static enum bverror parse_destination(struct bvbltparams *bltparams,
dstdesc = bltparams->dstdesc;
dstgeom = bltparams->dstgeom;
+ /* Check for unsupported dest formats. */
+ switch (dstgeom->format) {
+ case OCDFMT_NV12:
+ BVSETBLTERROR(BVERR_DSTGEOM_FORMAT,
+ "destination format unsupported");
+ goto exit;
+
+ default:
+ break;
+ }
+
/* Parse the destination format. */
GCDBG(GCZONE_FORMAT, "parsing destination format.\n");
if (!parse_format(dstgeom->format, &batch->dstformat)) {
@@ -2675,6 +2706,13 @@ static enum bverror parse_destination(struct bvbltparams *bltparams,
goto exit;
}
+ /* Destination must be 16 byte aligned */
+ if (dstgeom->virtstride & 15) {
+ BVSETBLTERROR(BVERR_DSTGEOM_STRIDE,
+ "destination stride must be 16 byte aligned");
+ goto exit;
+ }
+
/* Parse orientation. */
batch->dstangle = get_angle(dstgeom->orientation);
if (batch->dstangle == ROT_ANGLE_INVALID) {
@@ -2816,6 +2854,22 @@ static enum bverror parse_source(struct bvbltparams *bltparams,
goto exit;
}
+ /* Format specific stride check */
+ switch (srcgeom->format) {
+ case OCDFMT_NV12:
+ case OCDFMT_UYVY:
+ case OCDFMT_YUY2:
+ if (srcgeom->virtstride & 15) {
+ BVSETBLTERROR(BVERR_SRC1GEOM_STRIDE,
+ "stride must be 16 byte aligned for yuv");
+ goto exit;
+ }
+ break;
+
+ default:
+ break;
+ }
+
/* Parse orientation. */
srcinfo->angle = get_angle(srcgeom->orientation);
if (srcinfo->angle == ROT_ANGLE_INVALID) {
@@ -3296,8 +3350,9 @@ static enum bverror do_blit(struct bvbltparams *bltparams,
GCDBG(GCZONE_SURF, " realignment = %d\n",
dstalign);
- if ((srcformat->type == BVFMT_YUV) || (dstalign != 0) ||
- ((srcalign != 0) && (srcinfo->angle == batch->dstangle))) {
+ if ((srcformat->format == GCREG_DE_FORMAT_NV12) ||
+ (dstalign != 0) ||
+ ((srcalign != 0) && (srcinfo->angle == batch->dstangle))) {
/* Compute the source offset in pixels needed to compensate
* for the surface base address misalignment if any. */
srcalign = get_pixeloffset(srcdesc, srcformat, 0);
@@ -3594,11 +3649,12 @@ static enum bverror do_blit(struct bvbltparams *bltparams,
= GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_DISABLE;
}
- if (srcformat->type == BVFMT_YUV) {
+ if (srcformat->format == GCREG_DE_FORMAT_NV12) {
struct gcmosrcplanaryuv *yuv;
- int uvshift;
+ int uvshift = srcbyteshift;
#if 0
+ /* TODO: needs rework */
if (multisrc && (srcsurftop % 2)) {
/* We can't shift the uv plane by an odd number
* of rows. */
@@ -3623,8 +3679,9 @@ static enum bverror do_blit(struct bvbltparams *bltparams,
gcmosrc_vplaneaddress_ldst[index];
yuv->vplanestride_ldst =
gcmosrc_vplanestride_ldst[index];
-#if 0
+#if 0
+ /* TODO: needs rework */
if (multisrc) {
/* UV plane is half height. */
uvshift = (srcsurftop / 2)
@@ -3635,9 +3692,6 @@ static enum bverror do_blit(struct bvbltparams *bltparams,
/* No shift needed for single source walker. */
uvshift = 0;
}
-#else
- /* No shift needed for single source walker. */
- uvshift = 0;
#endif
GCDBG(GCZONE_SURF, " uvshift = 0x%08X (%d)\n",