[COMMON] media: smfc: fix configuration to MAX_STREAM_SIZE register
authorCho KyongHo <pullip.cho@samsung.com>
Wed, 13 May 2015 01:14:43 +0000 (10:14 +0900)
committerSeungchul Kim <sc377.kim@samsung.com>
Mon, 28 May 2018 05:31:00 +0000 (14:31 +0900)
If SMFC finds that the compressed stream should be written over the
size configured in MAX_STREAM_SIZE register, it stops working and
asserts interrupt to the CPU that the destination buffer is too small
to store the compressed stream.
The restriction of the value in MAX_STREAM_SIZE:
 - The value should be multiple of 64
 - If the stream base is not aligned by 16 bytes, 64 - unaligned bytes
   should be added to the value.

Change-Id: I2198d001d93a8b6ad03a0c02f928bd1d65b85983
Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
drivers/media/platform/exynos/smfc/smfc-regs.c
drivers/media/platform/exynos/smfc/smfc-regs.h

index ff24f3147ee7c345830b0b3105e8800ec336cc6b..36e4cd6b351c902a55ee03f54eeda3a9ca08b857 100644 (file)
@@ -278,6 +278,7 @@ void smfc_hwconfigure_image(struct smfc_ctx *ctx,
        struct vb2_v4l2_buffer *vb2buf_img, *vb2buf_jpg;
        u32 stream_address;
        u32 format = ctx->img_fmt->regcfg;
+       u32 maxstreamsize;
 
        __raw_writel(ctx->width | (ctx->height << 16),
                        ctx->smfc->reg + REG_MAIN_IMAGE_SIZE);
@@ -300,13 +301,15 @@ void smfc_hwconfigure_image(struct smfc_ctx *ctx,
        }
 
        smfc_hwconfigure_image_base(ctx, &vb2buf_img->vb2_buf, false);
-       stream_address = smfc_hwconfigure_jpeg_base(ctx, &vb2buf_jpg->vb2_buf,
-                                                   false);
-
        __raw_writel(format, ctx->smfc->reg + REG_MAIN_IMAGE_FORMAT);
-       __raw_writel(vb2_plane_size(&vb2buf_jpg->vb2_buf, 0) -
-                                       (stream_address & SMFC_ADDR_ALIGN_MASK),
-                       ctx->smfc->reg + REG_MAIN_MAX_STREAM_SIZE);
+       stream_address = smfc_hwconfigure_jpeg_base(
+                                       ctx, &vb2buf_jpg->vb2_buf, false);
+       maxstreamsize = round_down(vb2_plane_size(&vb2buf_jpg->vb2_buf, 0),
+                                  SMFC_STREAMSIZE_ALIGN);
+       if (!IS_ALIGNED(stream_address, 16))
+               maxstreamsize += SMFC_EXTRA_STREAMSIZE(stream_address);
+
+       __raw_writel(maxstreamsize, ctx->smfc->reg + REG_MAIN_MAX_STREAM_SIZE);
 }
 
 void smfc_hwconfigure_start(struct smfc_ctx *ctx,
index 1167230c07de98d96ca279ec8d564ab9495165f8..d0eb77a4c86876999a6a9477fcca35128713b0d8 100644 (file)
 #define SMFC_MAX_HEIGHT        16368U
 #define SMFC_MIN_WIDTH 8U
 #define SMFC_MIN_HEIGHT        8U
-#define SMFC_ADDR_ALIGN_MASK (16 - 1) /* 128-bit align */
+#define SMFC_ADDR_ALIGN 16     /* 128-bit align */
+#define SMFC_ADDR_ALIGN_MASK (SMFC_ADDR_ALIGN - 1)
+#define SMFC_STREAMSIZE_ALIGN 64
+#define SMFC_STREAMSIZE_ALIGN_MASK (64 - 1)
+#define SMFC_EXTRA_STREAMSIZE(base)    \
+               (SMFC_STREAMSIZE_ALIGN - ((base) & SMFC_ADDR_ALIGN_MASK))
 
 /********** H/W REGISTERS and DEFAULT VALUES **********************************/
 #define REG_MAIN_JPEG_CNTL             0x000