From 7479b937682459af2103bc1410bacccfeb881602 Mon Sep 17 00:00:00 2001 From: Cho KyongHo Date: Mon, 4 May 2015 15:47:38 +0900 Subject: [PATCH] [COMMON] media: smfc: store control variables at the start of H/W run 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 --- .../media/platform/exynos/smfc/smfc-regs.c | 33 ++++++++++--------- drivers/media/platform/exynos/smfc/smfc.c | 22 ++++++++----- drivers/media/platform/exynos/smfc/smfc.h | 9 ++--- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/drivers/media/platform/exynos/smfc/smfc-regs.c b/drivers/media/platform/exynos/smfc/smfc-regs.c index 55af10e2e2e8..d76dc0440f01 100644 --- a/drivers/media/platform/exynos/smfc/smfc-regs.c +++ b/drivers/media/platform/exynos/smfc/smfc-regs.c @@ -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 */ diff --git a/drivers/media/platform/exynos/smfc/smfc.c b/drivers/media/platform/exynos/smfc/smfc.c index e69179d568e5..4bb754d8c0d2 100644 --- a/drivers/media/platform/exynos/smfc/smfc.c +++ b/drivers/media/platform/exynos/smfc/smfc.c @@ -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; diff --git a/drivers/media/platform/exynos/smfc/smfc.h b/drivers/media/platform/exynos/smfc/smfc.h index c24b5626ae47..52d0a7d44db5 100644 --- a/drivers/media/platform/exynos/smfc/smfc.h +++ b/drivers/media/platform/exynos/smfc/smfc.h @@ -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); -- 2.20.1