diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/platform/s5p-jpeg/jpeg-core.c | 59 | ||||
-rw-r--r-- | drivers/media/platform/s5p-jpeg/jpeg-core.h | 12 |
2 files changed, 50 insertions, 21 deletions
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 12f7452edce3..8b0ca2ea9c72 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c | |||
@@ -621,6 +621,7 @@ static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx) | |||
621 | return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; | 621 | return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; |
622 | return ctx->subsampling; | 622 | return ctx->subsampling; |
623 | case SJPEG_EXYNOS3250: | 623 | case SJPEG_EXYNOS3250: |
624 | case SJPEG_EXYNOS5420: | ||
624 | if (ctx->subsampling > 3) | 625 | if (ctx->subsampling > 3) |
625 | return V4L2_JPEG_CHROMA_SUBSAMPLING_411; | 626 | return V4L2_JPEG_CHROMA_SUBSAMPLING_411; |
626 | return exynos3250_decoded_subsampling[ctx->subsampling]; | 627 | return exynos3250_decoded_subsampling[ctx->subsampling]; |
@@ -1142,13 +1143,13 @@ static void jpeg_bound_align_image(struct s5p_jpeg_ctx *ctx, | |||
1142 | w_step = 1 << walign; | 1143 | w_step = 1 << walign; |
1143 | h_step = 1 << halign; | 1144 | h_step = 1 << halign; |
1144 | 1145 | ||
1145 | if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250) { | 1146 | if (ctx->jpeg->variant->hw3250_compat) { |
1146 | /* | 1147 | /* |
1147 | * Rightmost and bottommost pixels are cropped by the | 1148 | * Rightmost and bottommost pixels are cropped by the |
1148 | * Exynos3250 JPEG IP for RGB formats, for the specific | 1149 | * Exynos3250/compatible JPEG IP for RGB formats, for the |
1149 | * width and height values respectively. This assignment | 1150 | * specific width and height values respectively. This |
1150 | * will result in v4l_bound_align_image returning dimensions | 1151 | * assignment will result in v4l_bound_align_image returning |
1151 | * reduced by 1 for the aforementioned cases. | 1152 | * dimensions reduced by 1 for the aforementioned cases. |
1152 | */ | 1153 | */ |
1153 | if (w_step == 4 && ((width & 3) == 1)) { | 1154 | if (w_step == 4 && ((width & 3) == 1)) { |
1154 | wmax = width; | 1155 | wmax = width; |
@@ -1384,12 +1385,12 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f) | |||
1384 | 1385 | ||
1385 | /* | 1386 | /* |
1386 | * Prevent downscaling to YUV420 format by more than 2 | 1387 | * Prevent downscaling to YUV420 format by more than 2 |
1387 | * for Exynos3250 SoC as it produces broken raw image | 1388 | * for Exynos3250/compatible SoC as it produces broken raw image |
1388 | * in such cases. | 1389 | * in such cases. |
1389 | */ | 1390 | */ |
1390 | if (ct->mode == S5P_JPEG_DECODE && | 1391 | if (ct->mode == S5P_JPEG_DECODE && |
1391 | f_type == FMT_TYPE_CAPTURE && | 1392 | f_type == FMT_TYPE_CAPTURE && |
1392 | ct->jpeg->variant->version == SJPEG_EXYNOS3250 && | 1393 | ct->jpeg->variant->hw3250_compat && |
1393 | pix->pixelformat == V4L2_PIX_FMT_YUV420 && | 1394 | pix->pixelformat == V4L2_PIX_FMT_YUV420 && |
1394 | ct->scale_factor > 2) { | 1395 | ct->scale_factor > 2) { |
1395 | scale_rect.width = ct->out_q.w / 2; | 1396 | scale_rect.width = ct->out_q.w / 2; |
@@ -1569,12 +1570,12 @@ static int s5p_jpeg_s_selection(struct file *file, void *fh, | |||
1569 | if (s->target == V4L2_SEL_TGT_COMPOSE) { | 1570 | if (s->target == V4L2_SEL_TGT_COMPOSE) { |
1570 | if (ctx->mode != S5P_JPEG_DECODE) | 1571 | if (ctx->mode != S5P_JPEG_DECODE) |
1571 | return -EINVAL; | 1572 | return -EINVAL; |
1572 | if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250) | 1573 | if (ctx->jpeg->variant->hw3250_compat) |
1573 | ret = exynos3250_jpeg_try_downscale(ctx, rect); | 1574 | ret = exynos3250_jpeg_try_downscale(ctx, rect); |
1574 | } else if (s->target == V4L2_SEL_TGT_CROP) { | 1575 | } else if (s->target == V4L2_SEL_TGT_CROP) { |
1575 | if (ctx->mode != S5P_JPEG_ENCODE) | 1576 | if (ctx->mode != S5P_JPEG_ENCODE) |
1576 | return -EINVAL; | 1577 | return -EINVAL; |
1577 | if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250) | 1578 | if (ctx->jpeg->variant->hw3250_compat) |
1578 | ret = exynos3250_jpeg_try_crop(ctx, rect); | 1579 | ret = exynos3250_jpeg_try_crop(ctx, rect); |
1579 | } | 1580 | } |
1580 | 1581 | ||
@@ -1604,8 +1605,9 @@ static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val) | |||
1604 | case SJPEG_S5P: | 1605 | case SJPEG_S5P: |
1605 | return 0; | 1606 | return 0; |
1606 | case SJPEG_EXYNOS3250: | 1607 | case SJPEG_EXYNOS3250: |
1608 | case SJPEG_EXYNOS5420: | ||
1607 | /* | 1609 | /* |
1608 | * The exynos3250 device can produce JPEG image only | 1610 | * The exynos3250/compatible device can produce JPEG image only |
1609 | * of 4:4:4 subsampling when given RGB32 source image. | 1611 | * of 4:4:4 subsampling when given RGB32 source image. |
1610 | */ | 1612 | */ |
1611 | if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32) | 1613 | 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) | |||
1624 | } | 1626 | } |
1625 | 1627 | ||
1626 | /* | 1628 | /* |
1627 | * The exynos4x12 and exynos3250 devices require resulting | 1629 | * The exynos4x12 and exynos3250/compatible devices require resulting |
1628 | * jpeg subsampling not to be lower than the input raw image | 1630 | * jpeg subsampling not to be lower than the input raw image |
1629 | * subsampling. | 1631 | * subsampling. |
1630 | */ | 1632 | */ |
@@ -2017,6 +2019,16 @@ static void exynos3250_jpeg_device_run(void *priv) | |||
2017 | exynos3250_jpeg_qtbl(jpeg->regs, 2, 1); | 2019 | exynos3250_jpeg_qtbl(jpeg->regs, 2, 1); |
2018 | exynos3250_jpeg_qtbl(jpeg->regs, 3, 1); | 2020 | exynos3250_jpeg_qtbl(jpeg->regs, 3, 1); |
2019 | 2021 | ||
2022 | /* | ||
2023 | * Some SoCs require setting Huffman tables before each run | ||
2024 | */ | ||
2025 | if (jpeg->variant->htbl_reinit) { | ||
2026 | s5p_jpeg_set_hdctbl(jpeg->regs); | ||
2027 | s5p_jpeg_set_hdctblg(jpeg->regs); | ||
2028 | s5p_jpeg_set_hactbl(jpeg->regs); | ||
2029 | s5p_jpeg_set_hactblg(jpeg->regs); | ||
2030 | } | ||
2031 | |||
2020 | /* Y, Cb, Cr use Huffman table 0 */ | 2032 | /* Y, Cb, Cr use Huffman table 0 */ |
2021 | exynos3250_jpeg_htbl_ac(jpeg->regs, 1); | 2033 | exynos3250_jpeg_htbl_ac(jpeg->regs, 1); |
2022 | exynos3250_jpeg_htbl_dc(jpeg->regs, 1); | 2034 | exynos3250_jpeg_htbl_dc(jpeg->regs, 1); |
@@ -2660,13 +2672,12 @@ static int s5p_jpeg_runtime_resume(struct device *dev) | |||
2660 | /* | 2672 | /* |
2661 | * JPEG IP allows storing two Huffman tables for each component. | 2673 | * JPEG IP allows storing two Huffman tables for each component. |
2662 | * We fill table 0 for each component and do this here only | 2674 | * We fill table 0 for each component and do this here only |
2663 | * for S5PC210 and Exynos3250 SoCs. Exynos4x12 SoC requires | 2675 | * for S5PC210 and Exynos3250 SoCs. Exynos4x12 and Exynos542x SoC |
2664 | * programming its Huffman tables each time the encoding process | 2676 | * require programming their Huffman tables each time the encoding |
2665 | * is initialized, and thus it is accomplished in the device_run | 2677 | * process is initialized, and thus it is accomplished in the |
2666 | * callback of m2m_ops. | 2678 | * device_run callback of m2m_ops. |
2667 | */ | 2679 | */ |
2668 | if (jpeg->variant->version == SJPEG_S5P || | 2680 | if (!jpeg->variant->htbl_reinit) { |
2669 | jpeg->variant->version == SJPEG_EXYNOS3250) { | ||
2670 | s5p_jpeg_set_hdctbl(jpeg->regs); | 2681 | s5p_jpeg_set_hdctbl(jpeg->regs); |
2671 | s5p_jpeg_set_hdctblg(jpeg->regs); | 2682 | s5p_jpeg_set_hdctblg(jpeg->regs); |
2672 | s5p_jpeg_set_hactbl(jpeg->regs); | 2683 | s5p_jpeg_set_hactbl(jpeg->regs); |
@@ -2714,6 +2725,7 @@ static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = { | |||
2714 | .jpeg_irq = exynos3250_jpeg_irq, | 2725 | .jpeg_irq = exynos3250_jpeg_irq, |
2715 | .m2m_ops = &exynos3250_jpeg_m2m_ops, | 2726 | .m2m_ops = &exynos3250_jpeg_m2m_ops, |
2716 | .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250, | 2727 | .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250, |
2728 | .hw3250_compat = 1, | ||
2717 | }; | 2729 | }; |
2718 | 2730 | ||
2719 | static struct s5p_jpeg_variant exynos4_jpeg_drvdata = { | 2731 | static struct s5p_jpeg_variant exynos4_jpeg_drvdata = { |
@@ -2721,6 +2733,16 @@ static struct s5p_jpeg_variant exynos4_jpeg_drvdata = { | |||
2721 | .jpeg_irq = exynos4_jpeg_irq, | 2733 | .jpeg_irq = exynos4_jpeg_irq, |
2722 | .m2m_ops = &exynos4_jpeg_m2m_ops, | 2734 | .m2m_ops = &exynos4_jpeg_m2m_ops, |
2723 | .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4, | 2735 | .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4, |
2736 | .htbl_reinit = 1, | ||
2737 | }; | ||
2738 | |||
2739 | static struct s5p_jpeg_variant exynos5420_jpeg_drvdata = { | ||
2740 | .version = SJPEG_EXYNOS5420, | ||
2741 | .jpeg_irq = exynos3250_jpeg_irq, /* intentionally 3250 */ | ||
2742 | .m2m_ops = &exynos3250_jpeg_m2m_ops, /* intentionally 3250 */ | ||
2743 | .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250, /* intentionally 3250 */ | ||
2744 | .hw3250_compat = 1, | ||
2745 | .htbl_reinit = 1, | ||
2724 | }; | 2746 | }; |
2725 | 2747 | ||
2726 | static const struct of_device_id samsung_jpeg_match[] = { | 2748 | static const struct of_device_id samsung_jpeg_match[] = { |
@@ -2736,6 +2758,9 @@ static const struct of_device_id samsung_jpeg_match[] = { | |||
2736 | }, { | 2758 | }, { |
2737 | .compatible = "samsung,exynos4212-jpeg", | 2759 | .compatible = "samsung,exynos4212-jpeg", |
2738 | .data = &exynos4_jpeg_drvdata, | 2760 | .data = &exynos4_jpeg_drvdata, |
2761 | }, { | ||
2762 | .compatible = "samsung,exynos5420-jpeg", | ||
2763 | .data = &exynos5420_jpeg_drvdata, | ||
2739 | }, | 2764 | }, |
2740 | {}, | 2765 | {}, |
2741 | }; | 2766 | }; |
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h index 764b32de326b..7d9a9ed19cea 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.h +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h | |||
@@ -67,10 +67,12 @@ | |||
67 | #define SJPEG_SUBSAMPLING_420 0x22 | 67 | #define SJPEG_SUBSAMPLING_420 0x22 |
68 | 68 | ||
69 | /* Version numbers */ | 69 | /* Version numbers */ |
70 | 70 | enum sjpeg_version { | |
71 | #define SJPEG_S5P 1 | 71 | SJPEG_S5P, |
72 | #define SJPEG_EXYNOS3250 2 | 72 | SJPEG_EXYNOS3250, |
73 | #define SJPEG_EXYNOS4 3 | 73 | SJPEG_EXYNOS4, |
74 | SJPEG_EXYNOS5420, | ||
75 | }; | ||
74 | 76 | ||
75 | enum exynos4_jpeg_result { | 77 | enum exynos4_jpeg_result { |
76 | OK_ENC_OR_DEC, | 78 | OK_ENC_OR_DEC, |
@@ -130,6 +132,8 @@ struct s5p_jpeg { | |||
130 | struct s5p_jpeg_variant { | 132 | struct s5p_jpeg_variant { |
131 | unsigned int version; | 133 | unsigned int version; |
132 | unsigned int fmt_ver_flag; | 134 | unsigned int fmt_ver_flag; |
135 | unsigned int hw3250_compat:1; | ||
136 | unsigned int htbl_reinit:1; | ||
133 | struct v4l2_m2m_ops *m2m_ops; | 137 | struct v4l2_m2m_ops *m2m_ops; |
134 | irqreturn_t (*jpeg_irq)(int irq, void *priv); | 138 | irqreturn_t (*jpeg_irq)(int irq, void *priv); |
135 | }; | 139 | }; |