From 5bc6693b834d651cab53e478633bb8db8c046913 Mon Sep 17 00:00:00 2001 From: Janghyuck Kim Date: Mon, 12 Jun 2017 22:01:30 +0900 Subject: [PATCH] [HACK] media: scaler: add extra size for source buffer Change-Id: Ie54f0c1b897943109e0ddc84cd3f7c66b047cf16 Signed-off-by: Janghyuck Kim --- .../platform/exynos/scaler/scaler-core.c | 42 +++++++++++++++++-- drivers/media/platform/exynos/scaler/scaler.h | 1 + 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/exynos/scaler/scaler-core.c b/drivers/media/platform/exynos/scaler/scaler-core.c index 7cb687869705..bb92fc222633 100644 --- a/drivers/media/platform/exynos/scaler/scaler-core.c +++ b/drivers/media/platform/exynos/scaler/scaler-core.c @@ -42,6 +42,14 @@ module_param_named(sc_log_level, sc_log_level, uint, 0644); int sc_set_blur; module_param_named(sc_set_blur, sc_set_blur, uint, 0644); +#define BUF_EXT_SIZE 512 +#define BUF_WIDTH_ALIGN 128 + +static inline unsigned int sc_ext_buf_size(int width) +{ + return IS_ALIGNED(width, BUF_WIDTH_ALIGN) ? 0 : BUF_EXT_SIZE; +} + /* * If true, writes the latency of H/W operation to v4l2_buffer.reserved2 * in the unit of nano seconds. It must not be enabled with real use-case @@ -360,6 +368,7 @@ static const struct sc_variant sc_variant[] = { .ratio_20bit = 1, .initphase = 1, .pixfmt_10bit = 1, + .extra_buf = 1, }, { .limit_input = { .min_w = 16, @@ -654,7 +663,7 @@ int sc_calc_s10b_planesize(u32 pixelformat, u32 width, u32 height, } static int sc_calc_fmt_s10b_size(const struct sc_fmt *sc_fmt, - struct v4l2_pix_format_mplane *pixm) + struct v4l2_pix_format_mplane *pixm, unsigned int ext_size) { int i, ret; @@ -668,8 +677,13 @@ static int sc_calc_fmt_s10b_size(const struct sc_fmt *sc_fmt, pixm->width, pixm->height, &pixm->plane_fmt[0].sizeimage, &pixm->plane_fmt[1].sizeimage, false); - if (ret) + if (ret) { pr_err("Scaler doesn't support %s format\n", sc_fmt->name); + return ret; + } + + for (i = 0; ext_size && i < pixm->num_planes; i++) + pixm->plane_fmt[i].sizeimage += (i == 0) ? ext_size : ext_size/2; return ret; } @@ -684,6 +698,7 @@ static int sc_v4l2_try_fmt_mplane(struct file *file, void *fh, int i; int h_align = 0; int w_align = 0; + unsigned int ext_size = 0; if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) { v4l2_err(&ctx->sc_dev->m2m.v4l2_dev, @@ -718,8 +733,11 @@ static int sc_v4l2_try_fmt_mplane(struct file *file, void *fh, pixm->num_planes = sc_fmt->num_planes; pixm->colorspace = 0; + if (ctx->sc_dev->variant->extra_buf && V4L2_TYPE_IS_OUTPUT(f->type)) + ext_size = sc_ext_buf_size(pixm->width); + if (sc_fmt_is_s10bit_yuv(sc_fmt->pixelformat)) - return sc_calc_fmt_s10b_size(sc_fmt, pixm); + return sc_calc_fmt_s10b_size(sc_fmt, pixm, ext_size); for (i = 0; i < pixm->num_planes; ++i) { pixm->plane_fmt[i].bytesperline = (pixm->width * @@ -741,6 +759,9 @@ static int sc_v4l2_try_fmt_mplane(struct file *file, void *fh, pixm->plane_fmt[i].sizeimage); } + for (i = 0; ext_size && i < pixm->num_planes; i++) + pixm->plane_fmt[i].sizeimage += (i == 0) ? ext_size : ext_size/2; + return 0; } @@ -1101,10 +1122,14 @@ static void sc_calc_intbufsize(struct sc_dev *sc, struct sc_int_frame *int_frame { struct sc_frame *frame = &int_frame->frame; unsigned int pixsize, bytesize; + unsigned int ext_size = 0, i; pixsize = frame->width * frame->height; bytesize = (pixsize * frame->sc_fmt->bitperpixel[0]) >> 3; + if (sc->variant->extra_buf) + ext_size = sc_ext_buf_size(frame->width); + switch (frame->sc_fmt->num_comp) { case 1: frame->addr.size[SC_PLANE_Y] = bytesize; @@ -1146,6 +1171,9 @@ static void sc_calc_intbufsize(struct sc_dev *sc, struct sc_int_frame *int_frame break; } + for (i = 0; ext_size && i < frame->sc_fmt->num_comp; i++) + frame->addr.size[i] += (i == 0) ? ext_size : ext_size/2; + memcpy(&int_frame->src_addr, &frame->addr, sizeof(int_frame->src_addr)); memcpy(&int_frame->dst_addr, &frame->addr, sizeof(int_frame->dst_addr)); } @@ -2952,6 +2980,7 @@ static int sc_m2m1shot_prepare_format(struct m2m1shot_context *m21ctx, &ctx->s_frame : &ctx->d_frame; s32 size_min = (dir == DMA_TO_DEVICE) ? 16 : 4; int i; + unsigned int ext_size = 0; frame->sc_fmt = sc_find_format(ctx->sc_dev, fmt->fmt, (dir == DMA_TO_DEVICE)); @@ -3019,6 +3048,13 @@ static int sc_m2m1shot_prepare_format(struct m2m1shot_context *m21ctx, } } + if (ctx->sc_dev->variant->extra_buf && dir == DMA_TO_DEVICE) { + ext_size = sc_ext_buf_size(fmt->width); + + for (i = 0; i < frame->sc_fmt->num_planes; i++) + bytes_used[i] += (i == 0) ? ext_size : ext_size/2; + } + frame->width = fmt->width; frame->height = fmt->height; frame->crop = fmt->crop; diff --git a/drivers/media/platform/exynos/scaler/scaler.h b/drivers/media/platform/exynos/scaler/scaler.h index 19d1bcab5f75..af9cab6ab466 100644 --- a/drivers/media/platform/exynos/scaler/scaler.h +++ b/drivers/media/platform/exynos/scaler/scaler.h @@ -244,6 +244,7 @@ struct sc_variant { u8 ratio_20bit:1; u8 initphase:1; u8 pixfmt_10bit:1; + u8 extra_buf:1; }; /* -- 2.20.1