diff options
author | Craig Stout <craig.stout@ti.com> | 2012-06-22 12:38:58 -0700 |
---|---|---|
committer | Ziyann <jaraidaniel@gmail.com> | 2014-10-01 13:00:51 +0200 |
commit | f3b9815dbd5e35de15d24901f32307521ed0d8f5 (patch) | |
tree | ee99e34272349d113584b7322679367eafbdc403 /drivers/misc/gcx | |
parent | 0bb7be3adc380a0ef8559f129d686356f3ee20d1 (diff) | |
download | kernel_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/gcx')
-rw-r--r-- | drivers/misc/gcx/gcbv/gcbv.c | 70 |
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", |