__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++) {
__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);
__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;
* 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);
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;
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 */
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)
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);
}
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;
}
/* 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);