aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorAlexei Shlychkov <x0177296@ti.com>2012-09-13 04:03:12 -0700
committerDmytro Kedrovskyi <x0169235@ti.com>2012-09-27 14:44:42 +0300
commitd4f9fe208c519081cbf114c8292b03167aee4b08 (patch)
tree24728780d0eb152dc23099e010377a0faf052ee6 /drivers/misc
parent60bab566a363654e97ea92c727e564dcc227ed95 (diff)
downloadkernel_samsung_espresso10-d4f9fe208c519081cbf114c8292b03167aee4b08.zip
kernel_samsung_espresso10-d4f9fe208c519081cbf114c8292b03167aee4b08.tar.gz
kernel_samsung_espresso10-d4f9fe208c519081cbf114c8292b03167aee4b08.tar.bz2
gcx: error handling improvements and fixes.
Change-Id: I3d19564422501dd76772760e5c2fdb152d031825 Signed-off-by: Alexei Shlychkov <x0177296@ti.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/gcx/gcbv/gcbv.c37
-rw-r--r--drivers/misc/gcx/gcbv/gcfilter.c17
-rw-r--r--drivers/misc/gcx/gcbv/gcparser.c126
3 files changed, 106 insertions, 74 deletions
diff --git a/drivers/misc/gcx/gcbv/gcbv.c b/drivers/misc/gcx/gcbv/gcbv.c
index 5e3d80e..a91cbab 100644
--- a/drivers/misc/gcx/gcbv/gcbv.c
+++ b/drivers/misc/gcx/gcbv/gcbv.c
@@ -547,15 +547,6 @@ exit:
* Surface compare and validation.
*/
-static inline bool valid_rect(struct bvsurfgeom *bvsurfgeom,
- struct gcrect *gcrect)
-{
- return (((gcrect->right - gcrect->left) > 0) &&
- ((gcrect->bottom - gcrect->top) > 0) &&
- (gcrect->right <= (int) bvsurfgeom->width) &&
- (gcrect->bottom <= (int) bvsurfgeom->height));
-}
-
static inline bool equal_rects(struct bvrect *rect1, struct bvrect *rect2)
{
if (rect1->left != rect2->left)
@@ -1123,22 +1114,6 @@ enum bverror bv_blt(struct bvbltparams *bvbltparams)
if (bverror != BVERR_NONE)
goto exit;
- /* Validate destination rectangles. */
- if (!valid_rect(bvbltparams->dstgeom,
- &gcbatch->dstclipped)) {
- GCDBG(GCZONE_DEST,
- "invalid destination rectangle.\n");
- goto exit;
- }
-
- if (((bvbltparams->flags & BVFLAG_SRC2_AUXDSTRECT) != 0) &&
- !valid_rect(bvbltparams->dstgeom,
- &gcbatch->dstclippedaux)) {
- GCDBG(GCZONE_DEST,
- "invalid aux destination rectangle.\n");
- goto exit;
- }
-
/* Reset the number of sources. */
srccount = 0;
@@ -1305,18 +1280,6 @@ enum bverror bv_blt(struct bvbltparams *bvbltparams)
&srcinfo[i]);
} else {
GCDBG(GCZONE_BLIT, " op: filter.\n");
-
- /* Finish previous batch if any. */
- bverror = gcbatch->batchend(
- bvbltparams, gcbatch);
- if (bverror != BVERR_NONE)
- goto exit;
-
- bverror = parse_scalemode(bvbltparams,
- gcbatch);
- if (bverror != BVERR_NONE)
- goto exit;
-
bverror = do_filter(bvbltparams,
gcbatch,
&srcinfo[i]);
diff --git a/drivers/misc/gcx/gcbv/gcfilter.c b/drivers/misc/gcx/gcbv/gcfilter.c
index a436186..99d9f9a 100644
--- a/drivers/misc/gcx/gcbv/gcfilter.c
+++ b/drivers/misc/gcx/gcbv/gcfilter.c
@@ -974,6 +974,23 @@ enum bverror do_filter(struct bvbltparams *bvbltparams,
GCENTER(GCZONE_FILTER);
+ /* Finish previous batch if any. */
+ bverror = batch->batchend(bvbltparams, batch);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
+ /* ROP is not supported by the filters. */
+ if ((srcinfo->rop & 0xFF) != 0xCC) {
+ BVSETBLTERROR(BVERR_ROP,
+ "only copy ROP is supported in scaling mode");
+ goto exit;
+ }
+
+ /* Parse the scale mode. */
+ bverror = parse_scalemode(bvbltparams, batch);
+ if (bverror != BVERR_NONE)
+ goto exit;
+
/* Additional stride requirements. */
if (srcinfo->format.format == GCREG_DE_FORMAT_NV12) {
/* Nv12 may be shifted up to 32 bytes for alignment.
diff --git a/drivers/misc/gcx/gcbv/gcparser.c b/drivers/misc/gcx/gcbv/gcparser.c
index 8ef92ca..b0a64c3 100644
--- a/drivers/misc/gcx/gcbv/gcparser.c
+++ b/drivers/misc/gcx/gcbv/gcparser.c
@@ -1256,6 +1256,17 @@ static inline int get_angle(int orientation)
* Surface compare and validation.
*/
+static inline bool valid_rect(struct bvsurfgeom *bvsurfgeom,
+ struct gcrect *gcrect)
+{
+ return ((gcrect->left >= 0) &&
+ (gcrect->top >= 0) &&
+ ((gcrect->right - gcrect->left) > 0) &&
+ ((gcrect->bottom - gcrect->top) > 0) &&
+ (gcrect->right <= (int) bvsurfgeom->width) &&
+ (gcrect->bottom <= (int) bvsurfgeom->height));
+}
+
static bool valid_geom(struct surfaceinfo *surfaceinfo)
{
unsigned int size;
@@ -1353,17 +1364,6 @@ enum bverror parse_destination(struct bvbltparams *bvbltparams,
dstinfo->rop = 0;
dstinfo->gca = NULL;
- /* Check for unsupported dest formats. */
- switch (dstinfo->geom->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(bvbltparams, dstinfo) != BVERR_NONE) {
@@ -1371,6 +1371,14 @@ enum bverror parse_destination(struct bvbltparams *bvbltparams,
goto exit;
}
+ /* Check for unsupported dest formats. */
+ if ((dstinfo->format.type == BVFMT_YUV) &&
+ (dstinfo->format.cs.yuv.planecount > 1)) {
+ BVSETBLTERROR(BVERR_DSTGEOM_FORMAT,
+ "destination format unsupported");
+ goto exit;
+ }
+
/* Validate geometry. */
if (!valid_geom(dstinfo)) {
BVSETBLTERROR(BVERR_DSTGEOM,
@@ -1393,6 +1401,7 @@ enum bverror parse_destination(struct bvbltparams *bvbltparams,
BVSETBLTERROR(BVERR_DSTGEOM,
"unsupported destination orientation %d.",
dstinfo->geom->orientation);
+ goto exit;
}
/* Compute the destination alignments needed to compensate
@@ -1518,6 +1527,7 @@ enum bverror parse_destination(struct bvbltparams *bvbltparams,
/* Determine whether aux destination is specified. */
haveaux = ((bvbltparams->flags & BVFLAG_SRC2_AUXDSTRECT) != 0);
+ GCDBG(GCZONE_DEST, "aux dest = %d\n", haveaux);
/* Is clipping rectangle specified? */
if ((bvbltparams->flags & BVFLAG_CLIP) == BVFLAG_CLIP) {
@@ -1582,25 +1592,33 @@ enum bverror parse_destination(struct bvbltparams *bvbltparams,
&bvbltparams->src2auxdstrect,
&dstrectaux);
- batch->dstclippedaux.left
- = (cliprect.left <= dstrectaux.left)
- ? dstrectaux.left
- : cliprect.left;
-
- batch->dstclippedaux.top
- = (cliprect.top <= dstrectaux.top)
- ? dstrectaux.top
- : cliprect.top;
-
- batch->dstclippedaux.right
- = (cliprect.right >= dstrectaux.right)
- ? dstrectaux.right
- : cliprect.right;
-
- batch->dstclippedaux.bottom
- = (cliprect.bottom >= dstrectaux.bottom)
- ? dstrectaux.bottom
- : cliprect.bottom;
+ if (cliprect.left <= dstrectaux.left)
+ batch->dstclippedaux.left
+ = dstrectaux.left;
+ else
+ batch->dstclippedaux.left
+ = cliprect.left;
+
+ if (cliprect.top <= dstrectaux.top)
+ batch->dstclippedaux.top
+ = dstrectaux.top;
+ else
+ batch->dstclippedaux.top
+ = cliprect.top;
+
+ if (cliprect.right >= dstrectaux.right)
+ batch->dstclippedaux.right
+ = dstrectaux.right;
+ else
+ batch->dstclippedaux.right
+ = cliprect.right;
+
+ if (cliprect.bottom >= dstrectaux.bottom)
+ batch->dstclippedaux.bottom
+ = dstrectaux.bottom;
+ else
+ batch->dstclippedaux.bottom
+ = cliprect.bottom;
}
} else {
batch->clipdelta.left =
@@ -1620,20 +1638,28 @@ enum bverror parse_destination(struct bvbltparams *bvbltparams,
GCPRINT_RECT(GCZONE_DEST, "clipped dest",
&batch->dstclipped);
- /* Check for valid dest rect after clipping. */
- if (batch->dstclipped.left < 0 ||
- batch->dstclipped.top < 0 ||
- batch->dstclipped.right > dstinfo->geom->width ||
- batch->dstclipped.bottom > dstinfo->geom->height) {
+ /* Validate the destination rectangle. */
+ if (!valid_rect(bvbltparams->dstgeom,
+ &batch->dstclipped)) {
BVSETBLTERROR(BVERR_DSTRECT,
- "destination rect invalid");
+ "invalid destination rectangle.");
goto exit;
}
- if (haveaux)
+ if (haveaux) {
GCPRINT_RECT(GCZONE_DEST, "clipped aux dest",
&batch->dstclippedaux);
+ /* Validate the aux destination rectangle. */
+ if (!valid_rect(bvbltparams->dstgeom,
+ &batch->dstclippedaux)) {
+ BVSETBLTERROR(BVERR_DSTRECT,
+ "invalid aux destination "
+ "rectangle.");
+ goto exit;
+ }
+ }
+
GCDBG(GCZONE_DEST,
"clipping delta = (%d,%d)-(%d,%d)\n",
batch->clipdelta.left,
@@ -1689,6 +1715,21 @@ enum bverror parse_source(struct bvbltparams *bvbltparams,
goto exit;
}
+ /* Check base address alignment for planar YUV. */
+ if ((srcinfo->format.type == BVFMT_YUV) &&
+ (srcinfo->format.cs.yuv.planecount > 1)) {
+ int pixalign;
+ pixalign = get_pixel_offset(srcinfo, 0);
+ if (pixalign != 0) {
+ BVSETBLTERROR((srcinfo->index == 0)
+ ? BVERR_SRC1DESC_ALIGNMENT
+ : BVERR_SRC2DESC_ALIGNMENT,
+ "planar YUV base address must be "
+ "64 byte aligned.");
+ goto exit;
+ }
+ }
+
/* Parse orientation. */
srcinfo->angle = get_angle(srcinfo->geom->orientation);
if (srcinfo->angle == ROT_ANGLE_INVALID) {
@@ -1698,6 +1739,17 @@ enum bverror parse_source(struct bvbltparams *bvbltparams,
"unsupported source%d orientation %d.",
srcinfo->index + 1,
srcinfo->geom->orientation);
+ goto exit;
+ }
+
+ /* Rotated YUV (packed and planar) source is not supported. */
+ if ((srcinfo->angle != ROT_ANGLE_0) &&
+ (srcinfo->format.type == BVFMT_YUV)) {
+ BVSETBLTERROR((srcinfo->index == 0)
+ ? BVERR_SRC1_ROT
+ : BVERR_SRC2_ROT,
+ "rotation of YUV is not supported");
+ goto exit;
}
/* Determine source mirror. */