[media] s5p-jpeg: add 5420 family support
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>
Mon, 9 Mar 2015 12:32:46 +0000 (09:32 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Tue, 7 Apr 2015 11:14:09 +0000 (08:14 -0300)
JPEG IP found in Exynos5420 is similar to what is in Exynos3250, but
there are some subtle differences which this patch takes into account.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Documentation/devicetree/bindings/media/exynos-jpeg-codec.txt
drivers/media/platform/s5p-jpeg/jpeg-core.c
drivers/media/platform/s5p-jpeg/jpeg-core.h

index bf52ed4a5067de5c9d825f77865321112ec5a651..4ef45636ebdedd538bef484a94705b720aceda66 100644 (file)
@@ -4,7 +4,7 @@ Required properties:
 
 - compatible   : should be one of:
                  "samsung,s5pv210-jpeg", "samsung,exynos4210-jpeg",
-                 "samsung,exynos3250-jpeg";
+                 "samsung,exynos3250-jpeg", "samsung,exynos5420-jpeg";
 - reg          : address and length of the JPEG codec IP register set;
 - interrupts   : specifies the JPEG codec IP interrupt;
 - clock-names   : should contain:
index 12f7452edce3708a989eb0e7f71a94def8a31665..8b0ca2ea9c72915148697f6b5afdbfa80b00cfa7 100644 (file)
@@ -621,6 +621,7 @@ static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
                        return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
                return ctx->subsampling;
        case SJPEG_EXYNOS3250:
+       case SJPEG_EXYNOS5420:
                if (ctx->subsampling > 3)
                        return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
                return exynos3250_decoded_subsampling[ctx->subsampling];
@@ -1142,13 +1143,13 @@ static void jpeg_bound_align_image(struct s5p_jpeg_ctx *ctx,
        w_step = 1 << walign;
        h_step = 1 << halign;
 
-       if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250) {
+       if (ctx->jpeg->variant->hw3250_compat) {
                /*
                 * Rightmost and bottommost pixels are cropped by the
-                * Exynos3250 JPEG IP for RGB formats, for the specific
-                * width and height values respectively. This assignment
-                * will result in v4l_bound_align_image returning dimensions
-                * reduced by 1 for the aforementioned cases.
+                * Exynos3250/compatible JPEG IP for RGB formats, for the
+                * specific width and height values respectively. This
+                * assignment will result in v4l_bound_align_image returning
+                * dimensions reduced by 1 for the aforementioned cases.
                 */
                if (w_step == 4 && ((width & 3) == 1)) {
                        wmax = width;
@@ -1384,12 +1385,12 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
 
        /*
         * Prevent downscaling to YUV420 format by more than 2
-        * for Exynos3250 SoC as it produces broken raw image
+        * for Exynos3250/compatible SoC as it produces broken raw image
         * in such cases.
         */
        if (ct->mode == S5P_JPEG_DECODE &&
            f_type == FMT_TYPE_CAPTURE &&
-           ct->jpeg->variant->version == SJPEG_EXYNOS3250 &&
+           ct->jpeg->variant->hw3250_compat &&
            pix->pixelformat == V4L2_PIX_FMT_YUV420 &&
            ct->scale_factor > 2) {
                scale_rect.width = ct->out_q.w / 2;
@@ -1569,12 +1570,12 @@ static int s5p_jpeg_s_selection(struct file *file, void *fh,
        if (s->target == V4L2_SEL_TGT_COMPOSE) {
                if (ctx->mode != S5P_JPEG_DECODE)
                        return -EINVAL;
-               if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250)
+               if (ctx->jpeg->variant->hw3250_compat)
                        ret = exynos3250_jpeg_try_downscale(ctx, rect);
        } else if (s->target == V4L2_SEL_TGT_CROP) {
                if (ctx->mode != S5P_JPEG_ENCODE)
                        return -EINVAL;
-               if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250)
+               if (ctx->jpeg->variant->hw3250_compat)
                        ret = exynos3250_jpeg_try_crop(ctx, rect);
        }
 
@@ -1604,8 +1605,9 @@ static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val)
        case SJPEG_S5P:
                return 0;
        case SJPEG_EXYNOS3250:
+       case SJPEG_EXYNOS5420:
                /*
-                * The exynos3250 device can produce JPEG image only
+                * The exynos3250/compatible device can produce JPEG image only
                 * of 4:4:4 subsampling when given RGB32 source image.
                 */
                if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
@@ -1624,7 +1626,7 @@ static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val)
        }
 
        /*
-        * The exynos4x12 and exynos3250 devices require resulting
+        * The exynos4x12 and exynos3250/compatible devices require resulting
         * jpeg subsampling not to be lower than the input raw image
         * subsampling.
         */
@@ -2017,6 +2019,16 @@ static void exynos3250_jpeg_device_run(void *priv)
                exynos3250_jpeg_qtbl(jpeg->regs, 2, 1);
                exynos3250_jpeg_qtbl(jpeg->regs, 3, 1);
 
+               /*
+                * Some SoCs require setting Huffman tables before each run
+                */
+               if (jpeg->variant->htbl_reinit) {
+                       s5p_jpeg_set_hdctbl(jpeg->regs);
+                       s5p_jpeg_set_hdctblg(jpeg->regs);
+                       s5p_jpeg_set_hactbl(jpeg->regs);
+                       s5p_jpeg_set_hactblg(jpeg->regs);
+               }
+
                /* Y, Cb, Cr use Huffman table 0 */
                exynos3250_jpeg_htbl_ac(jpeg->regs, 1);
                exynos3250_jpeg_htbl_dc(jpeg->regs, 1);
@@ -2660,13 +2672,12 @@ static int s5p_jpeg_runtime_resume(struct device *dev)
        /*
         * JPEG IP allows storing two Huffman tables for each component.
         * We fill table 0 for each component and do this here only
-        * for S5PC210 and Exynos3250 SoCs. Exynos4x12 SoC requires
-        * programming its Huffman tables each time the encoding process
-        * is initialized, and thus it is accomplished in the device_run
-        * callback of m2m_ops.
+        * for S5PC210 and Exynos3250 SoCs. Exynos4x12 and Exynos542x SoC
+        * require programming their Huffman tables each time the encoding
+        * process is initialized, and thus it is accomplished in the
+        * device_run callback of m2m_ops.
         */
-       if (jpeg->variant->version == SJPEG_S5P ||
-           jpeg->variant->version == SJPEG_EXYNOS3250) {
+       if (!jpeg->variant->htbl_reinit) {
                s5p_jpeg_set_hdctbl(jpeg->regs);
                s5p_jpeg_set_hdctblg(jpeg->regs);
                s5p_jpeg_set_hactbl(jpeg->regs);
@@ -2714,6 +2725,7 @@ static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = {
        .jpeg_irq       = exynos3250_jpeg_irq,
        .m2m_ops        = &exynos3250_jpeg_m2m_ops,
        .fmt_ver_flag   = SJPEG_FMT_FLAG_EXYNOS3250,
+       .hw3250_compat  = 1,
 };
 
 static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
@@ -2721,6 +2733,16 @@ static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
        .jpeg_irq       = exynos4_jpeg_irq,
        .m2m_ops        = &exynos4_jpeg_m2m_ops,
        .fmt_ver_flag   = SJPEG_FMT_FLAG_EXYNOS4,
+       .htbl_reinit    = 1,
+};
+
+static struct s5p_jpeg_variant exynos5420_jpeg_drvdata = {
+       .version        = SJPEG_EXYNOS5420,
+       .jpeg_irq       = exynos3250_jpeg_irq,          /* intentionally 3250 */
+       .m2m_ops        = &exynos3250_jpeg_m2m_ops,     /* intentionally 3250 */
+       .fmt_ver_flag   = SJPEG_FMT_FLAG_EXYNOS3250,    /* intentionally 3250 */
+       .hw3250_compat  = 1,
+       .htbl_reinit    = 1,
 };
 
 static const struct of_device_id samsung_jpeg_match[] = {
@@ -2736,6 +2758,9 @@ static const struct of_device_id samsung_jpeg_match[] = {
        }, {
                .compatible = "samsung,exynos4212-jpeg",
                .data = &exynos4_jpeg_drvdata,
+       }, {
+               .compatible = "samsung,exynos5420-jpeg",
+               .data = &exynos5420_jpeg_drvdata,
        },
        {},
 };
index 764b32de326b2cd4e31ab0b5bc4b5641b260e09d..7d9a9ed19cea882de59b53e40fb0a5ca5df7f203 100644 (file)
 #define SJPEG_SUBSAMPLING_420  0x22
 
 /* Version numbers */
-
-#define SJPEG_S5P              1
-#define SJPEG_EXYNOS3250       2
-#define SJPEG_EXYNOS4          3
+enum sjpeg_version {
+       SJPEG_S5P,
+       SJPEG_EXYNOS3250,
+       SJPEG_EXYNOS4,
+       SJPEG_EXYNOS5420,
+};
 
 enum exynos4_jpeg_result {
        OK_ENC_OR_DEC,
@@ -130,6 +132,8 @@ struct s5p_jpeg {
 struct s5p_jpeg_variant {
        unsigned int            version;
        unsigned int            fmt_ver_flag;
+       unsigned int            hw3250_compat:1;
+       unsigned int            htbl_reinit:1;
        struct v4l2_m2m_ops     *m2m_ops;
        irqreturn_t             (*jpeg_irq)(int irq, void *priv);
 };