예제 #1
0
static int fimg2d_import_bufs(struct fimg2d_control *info,
		struct fimg2d_bltcmd *cmd)
{
	int ret = 0;
	int i;
	size_t j;

	for (i = 0; i < MAX_IMAGES; i++) {
		struct fimg2d_image *img = &cmd->image[i];
		size_t num_planes = fimg2d_num_planes(img);

		for (j = 0; j < num_planes; j++) {
			int stride;
			unsigned int buf_size = fimg2d_map_dma_buf(info,
					&cmd->dma[i][j], img->addr.fd[j],
					fimg2d_dma_direction(i));
			if (!buf_size) {
				ret = -ENOMEM;
				goto err;
			}

			if (is_yuvfmt(img->fmt)) {
				stride = yuv_stride(img->width, img->fmt,
						img->order, j);
			} else {
				stride = img->stride;
			}

			if (buf_size < stride * img->height) {
				dev_err(info->dev,
						"%s plane %u too small (height = %d, stride = %d, buf_size = %u)\n",
						imagename(i), j,
						img->height, stride, buf_size);
				ret = -EINVAL;
				goto err;
			}
		}
	}

err:
	if (ret)
		for (i = 0; i < MAX_IMAGES; i++)
			for (j = 0; j < FIMG2D_MAX_PLANES; j++)
				fimg2d_unmap_dma_buf(info, &cmd->dma[i][j]);

	return ret;
}
void fimg2d_debug_command(struct fimg2d_bltcmd *cmd)
{
    int i;
    struct fimg2d_param *p = &cmd->blt.param;
    struct fimg2d_image *img;
    struct fimg2d_rect *r;
    struct fimg2d_dma *c;

    if (WARN_ON(!cmd->ctx))
        return;

    pr_info("\n[%s] ctx: %p seq_no(%u)\n", __func__, cmd->ctx, cmd->blt.seq_no);
    pr_info(" op: %s(%d)\n", opname(cmd->blt.op), cmd->blt.op);
    pr_info(" solid color: 0x%lx\n", p->solid_color);
    pr_info(" g_alpha: 0x%x\n", p->g_alpha);
    pr_info(" premultiplied: %d\n", p->premult);
    if (p->dither)
        pr_info(" dither: %d\n", p->dither);
    if (p->rotate)
        pr_info(" rotate: %d\n", p->rotate);
    if (p->repeat.mode) {
        pr_info(" repeat: %d, pad color: 0x%lx\n",
                p->repeat.mode, p->repeat.pad_color);
    }
    if (p->bluscr.mode) {
        pr_info(" bluescreen mode: %d, bs_color: 0x%lx " \
                "bg_color: 0x%lx\n",
                p->bluscr.mode, p->bluscr.bs_color,
                p->bluscr.bg_color);
    }
    if (p->scaling.mode) {
        pr_info(" scaling %d, s:%d,%d d:%d,%d\n",
                p->scaling.mode,
                p->scaling.src_w, p->scaling.src_h,
                p->scaling.dst_w, p->scaling.dst_h);
    }
    if (p->clipping.enable) {
        pr_info(" clipping LT(%d,%d) RB(%d,%d) WH(%d,%d)\n",
                p->clipping.x1, p->clipping.y1,
                p->clipping.x2, p->clipping.y2,
                rect_w(&p->clipping), rect_h(&p->clipping));
    }

    for (i = 0; i < MAX_IMAGES; i++) {
        img = &cmd->image[i];
        r = &img->rect;

        if (!img->addr.type)
            continue;

        pr_info(" %s type: %d addr: 0x%lx\n",
                imagename(i), img->addr.type, img->addr.start);

        pr_info(" %s width: %d height: %d " \
                "stride: %d order: %d format: %s(%d)\n",
                imagename(i), img->width, img->height,
                img->stride, img->order,
                cfname(img->fmt), img->fmt);
        pr_info(" %s rect LT(%d,%d) RB(%d,%d) WH(%d,%d)\n",
                imagename(i), r->x1, r->y1, r->x2, r->y2,
                rect_w(r), rect_h(r));

        c = &cmd->dma[i].base;
        if (c->size) {
            pr_info(" %s dma base addr: 0x%lx " \
                    "size: 0x%x cached: 0x%x\n",
                    imagename(i), c->addr, c->size,
                    c->cached);
        }

        if (img->plane2.type) {
            pr_info(" %s plane2 type: %d addr: 0x%lx\n",
                    imagename(i), img->plane2.type,
                    img->plane2.start);
        }

        c = &cmd->dma[i].plane2;
        if (c->size) {
            pr_info(" %s dma plane2 addr: 0x%lx " \
                    "size: 0x%x cached: 0x%x\n",
                    imagename(i), c->addr, c->size,
                    c->cached);
        }
    }

    if (cmd->dma_all)
        pr_info(" dma size all: 0x%x bytes\n", cmd->dma_all);

    pr_info(" L1: 0x%x L2: 0x%x bytes\n", L1_CACHE_SIZE, L2_CACHE_SIZE);
}
예제 #3
0
static int fimg2d_check_params(struct fimg2d_control *info,
		struct fimg2d_bltcmd *cmd)
{
	int w, h, i;
	struct fimg2d_param *p = &cmd->param;
	struct fimg2d_image *img;
	struct fimg2d_scale *scl;
	struct fimg2d_clip *clp;
	struct fimg2d_rect *r;

	/* dst is mandatory */
	if (!cmd->image[IDST].addr.type)
		return -1;

	/* DST op makes no effect */
	if (cmd->op < 0 || cmd->op == BLIT_OP_DST || cmd->op >= BLIT_OP_END)
		return -1;

	for (i = 0; i < MAX_IMAGES; i++) {
		img = &cmd->image[i];
		if (!img->addr.type)
			continue;

		w = img->width;
		h = img->height;
		r = &img->rect;

		/* 8000: max width & height */
		if (w > 8000 || h > 8000) {
			dev_err(info->dev, "%s too large (w = %d, h = %d)\n",
					imagename(i), w, h);
			return -1;
		}

		if (r->x1 < 0 || r->y1 < 0 ||
			r->x1 >= w || r->y1 >= h ||
			r->x1 >= r->x2 || r->y1 >= r->y2) {
			dev_err(info->dev,
					"%s has invalid clipping rectangle (r = [%d, %d, %d, %d], w = %d, h = %d)\n",
					imagename(i), r->x1, r->y1, r->x2,
					r->y2, w, h);
			return -1;
		}

		if (is_yuvfmt(img->fmt) && img->stride != w) {
			dev_err(info->dev,
					"YUV %s stride and width not equal (stride = %d, w = %d)\n",
					imagename(i), img->stride, w);
			return -1;
		}

		if (img->fmt == CF_YCBCR_422 ||
				img->fmt == CF_YCBCR_420) {
			const char *fmtname = img->fmt == CF_YCBCR_422 ?
					"YCbCr422" : "YCbCr420";

			if ((r->x1 & 1) ||
					(r->x2 & 1)) {
				dev_err(info->dev,
						"%s %s clipping rectangle X coordinates not even (x1 = %d, x2 = %d)\n",
						fmtname, imagename(i),
						r->x1, r->x2);
				return -1;

			}

			if (img->stride & 1) {
				dev_err(info->dev,
						"%s %s stride not even (stride = %d)\n",
						fmtname, imagename(i),
						img->stride);
				return -1;
			}
		}

		if (img->fmt == CF_YCBCR_420) {
			if ((r->y1 & 1) ||
					(r->y2 & 1)) {
				dev_err(info->dev,
						"YCbCr420 %s clipping rectangle Y coordinates not even (y1 = %d, y2 = %d)\n",
						imagename(i),
						r->y1, r->y2);
				return -1;

			}
		}
	}

	clp = &p->clipping;
	if (clp->enable) {
		img = &cmd->image[IDST];

		w = img->width;
		h = img->height;
		r = &img->rect;

		if (clp->x1 < 0 || clp->y1 < 0 ||
			clp->x1 >= w || clp->y1 >= h ||
			clp->x1 >= clp->x2 || clp->y1 >= clp->y2 ||
			clp->x1 >= r->x2 || clp->x2 <= r->x1 ||
			clp->y1 >= r->y2 || clp->y2 <= r->y1)
			return -1;
	}

	scl = &p->scaling;
	if (scl->mode) {
		if (!scl->src_w || !scl->src_h || !scl->dst_w || !scl->dst_h)
			return -1;
	}

	return 0;
}