[COMMON] media: smfc: store control variables at the start of H/W run
authorCho KyongHo <pullip.cho@samsung.com>
Mon, 4 May 2015 06:47:38 +0000 (15:47 +0900)
committerSeungchul Kim <sc377.kim@samsung.com>
Mon, 28 May 2018 05:30:56 +0000 (14:30 +0900)
V4L2 control variables can be configured during H/W configuration.
Direct reference to the control variables several during H/W
configuration may result in inconsistent configuration to the H/W
because users may change the control variables during H/W
configurations. Therefore it is safe to keep a copy of the values
of the control variables before H/W configuration and to refer to
the copy. It is not important to configure the most latest values
of the control variables because the users do not know when the
H/W is configured.

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

index 55af10e2e2e8341e64f507b7c8410cd1e3071caa..d76dc0440f01fea080959465df8136955216b944 100644 (file)
@@ -132,17 +132,16 @@ static void smfc_hwconfigure_qtable(void __iomem *reg, unsigned int factor,
                __raw_writel(smfc_calc_quantizers(i, factor, table), reg + i);
 }
 
-void smfc_hwconfigure_tables(struct smfc_ctx *ctx)
+void smfc_hwconfigure_tables(struct smfc_ctx *ctx, unsigned int qfactor)
 {
        size_t i;
        void __iomem *base = ctx->smfc->reg;
-       unsigned int factor = ctx->quality_factor;
-       factor = (factor < 50) ? 5000 / factor : 200 - factor * 2;
+       qfactor = (qfactor < 50) ? 5000 / qfactor : 200 - qfactor * 2;
 
        smfc_hwconfigure_qtable(base + REG_QTBL_BASE,
-                               factor, default_luma_qtbl);
+                               qfactor, default_luma_qtbl);
        smfc_hwconfigure_qtable(base + REG_QTBL_BASE + SMFC_MCU_SIZE,
-                               factor, default_chroma_qtbl);
+                               qfactor, default_chroma_qtbl);
 
        /* Huffman tables */
        for (i = 0; i < 4; i++) {
@@ -172,17 +171,16 @@ void smfc_hwconfigure_tables(struct smfc_ctx *ctx)
        __raw_writel(SMFC_DHT_LEN, base + REG_MAIN_DHT_LEN);
 }
 
-void smfc_hwconfigure_2nd_tables(struct smfc_ctx *ctx)
+void smfc_hwconfigure_2nd_tables(struct smfc_ctx *ctx, unsigned int qfactor)
 {
        /* Qunatiazation table 2 and 3 will be used by the secondary image */
        void __iomem *base = ctx->smfc->reg;
        void __iomem *qtblbase = base + REG_QTBL_BASE + SMFC_MCU_SIZE * 2;
-       unsigned int factor = ctx->thumb_quality_factor;
-       factor = (factor < 50) ? 5000 / factor : 200 - factor * 2;
+       qfactor = (qfactor < 50) ? 5000 / qfactor : 200 - qfactor * 2;
 
-       smfc_hwconfigure_qtable(qtblbase, factor, default_luma_qtbl);
+       smfc_hwconfigure_qtable(qtblbase, qfactor, default_luma_qtbl);
        smfc_hwconfigure_qtable(qtblbase + SMFC_MCU_SIZE,
-                               factor, default_chroma_qtbl);
+                               qfactor, default_chroma_qtbl);
        /* Huffman table for the secondary image is the same as the main image */
        __raw_writel(VAL_SEC_TABLE_SELECT, base + REG_SEC_TABLE_SELECT);
        __raw_writel(SMFC_DHT_LEN, base + REG_SEC_DHT_LEN);
@@ -274,7 +272,8 @@ void smfc_hwconfigure_2nd_image(struct smfc_ctx *ctx)
        __raw_writel(format, ctx->smfc->reg + REG_SEC_IMAGE_FORMAT);
 }
 
-void smfc_hwconfigure_image(struct smfc_ctx *ctx)
+void smfc_hwconfigure_image(struct smfc_ctx *ctx,
+                           unsigned int hfactor, unsigned int vfactor)
 {
        struct vb2_v4l2_buffer *vb2buf_img, *vb2buf_jpg;
        u32 stream_address;
@@ -294,8 +293,10 @@ void smfc_hwconfigure_image(struct smfc_ctx *ctx)
                 * during compression
                 */
                format |= smfc_get_jpeg_format(
-                       max(ctx->chroma_hfactor, ctx->img_fmt->chroma_hfactor),
-                       max(ctx->chroma_vfactor, ctx->img_fmt->chroma_vfactor));
+                               max_t(unsigned int, hfactor,
+                                       ctx->img_fmt->chroma_hfactor),
+                               max_t(unsigned int, vfactor,
+                                       ctx->img_fmt->chroma_vfactor));
        }
 
        smfc_hwconfigure_image_base(ctx, &vb2buf_img->vb2_buf, false);
@@ -308,7 +309,7 @@ void smfc_hwconfigure_image(struct smfc_ctx *ctx)
                        ctx->smfc->reg + REG_MAIN_MAX_STREAM_SIZE);
 }
 
-void smfc_hwconfigure_start(struct smfc_ctx *ctx)
+void smfc_hwconfigure_start(struct smfc_ctx *ctx, unsigned int rst_int)
 {
        u32 cfg;
        void __iomem *base = ctx->smfc->reg;
@@ -325,8 +326,8 @@ void smfc_hwconfigure_start(struct smfc_ctx *ctx)
        cfg |= 1 << 19; /* update huffman table from SFR */
        cfg |= 1 << 28; /* enables interrupt */
        cfg |= 1 << 29; /* Release reset */
-       if (ctx->restart_interval != 0)
-               cfg |= (ctx->restart_interval << 3) | (1 << 2);
+       if (rst_int != 0)
+               cfg |= (rst_int << 3) | (1 << 2);
        if (!!(ctx->flags & SMFC_CTX_B2B_COMPRESS))
                cfg |= 1 << 31; /* back-to-back enable */
 
index e69179d568e5886651908eb5051b3996496e7f22..4bb754d8c0d2d02af0550a4f420224d9a24f6dee 100644 (file)
@@ -1135,12 +1135,6 @@ static const struct v4l2_ioctl_ops smfc_v4l2_ioctl_ops = {
 
 static void smfc_configure_secondary_image(struct smfc_ctx *ctx)
 {
-       if (!(ctx->flags & SMFC_CTX_B2B_COMPRESS) ||
-                       WARN_ON(!(ctx->flags & SMFC_CTX_COMPRESS)))
-               return;
-
-       smfc_hwconfigure_2nd_tables(ctx);
-       smfc_hwconfigure_2nd_image(ctx);
 }
 
 static void smfc_m2m_device_run(void *priv)
@@ -1148,6 +1142,11 @@ static void smfc_m2m_device_run(void *priv)
        struct smfc_ctx *ctx = priv;
        unsigned long flags;
        int ret;
+       unsigned char chroma_hfactor = ctx->chroma_hfactor;
+       unsigned char chroma_vfactor = ctx->chroma_vfactor;
+       unsigned char restart_interval = ctx->restart_interval;
+       unsigned char quality_factor = ctx->quality_factor;
+       unsigned char thumb_quality_factor = ctx->thumb_quality_factor;
 
        ret = in_irq() ? pm_runtime_get(ctx->smfc->dev) :
                         pm_runtime_get_sync(ctx->smfc->dev);
@@ -1172,10 +1171,15 @@ static void smfc_m2m_device_run(void *priv)
        }
 
        smfc_hwconfigure_reset(ctx->smfc);
-       smfc_hwconfigure_tables(ctx);
-       smfc_hwconfigure_image(ctx);
+       smfc_hwconfigure_tables(ctx, quality_factor);
+       smfc_hwconfigure_image(ctx, chroma_hfactor, chroma_vfactor);
        smfc_configure_secondary_image(ctx);
-       smfc_hwconfigure_start(ctx);
+       if (!!(ctx->flags & SMFC_CTX_B2B_COMPRESS) &&
+                       !!(ctx->flags & SMFC_CTX_COMPRESS)) {
+               smfc_hwconfigure_2nd_tables(ctx, thumb_quality_factor);
+               smfc_hwconfigure_2nd_image(ctx);
+       }
+       smfc_hwconfigure_start(ctx, restart_interval);
 
        spin_lock_irqsave(&ctx->smfc->flag_lock, flags);
        ctx->smfc->flags |= SMFC_DEV_RUNNING;
index c24b5626ae47981ead9e643af88d8516045728dc..52d0a7d44db5228ddecb2d3d96c802537675478e 100644 (file)
@@ -107,10 +107,11 @@ static inline bool smfc_is_compressed_type(struct smfc_ctx *ctx, __u32 type)
 }
 
 /* H/W Configuration */
-void smfc_hwconfigure_tables(struct smfc_ctx *ctx);
-void smfc_hwconfigure_image(struct smfc_ctx *ctx);
-void smfc_hwconfigure_start(struct smfc_ctx *ctx);
-void smfc_hwconfigure_2nd_tables(struct smfc_ctx *ctx);
+void smfc_hwconfigure_tables(struct smfc_ctx *ctx, unsigned int qfactor);
+void smfc_hwconfigure_image(struct smfc_ctx *ctx,
+                           unsigned int hfactor, unsigned int vfactor);
+void smfc_hwconfigure_start(struct smfc_ctx *ctx, unsigned int rst_int);
+void smfc_hwconfigure_2nd_tables(struct smfc_ctx *ctx, unsigned int qfactor);
 void smfc_hwconfigure_2nd_image(struct smfc_ctx *ctx);
 bool smfc_hwstatus_okay(struct smfc_dev *smfc, struct smfc_ctx *ctx);
 void smfc_hwconfigure_reset(struct smfc_dev *smfc);