Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save devarsht/1db185b1e187eaf397e9e4c37066777e to your computer and use it in GitHub Desktop.
Save devarsht/1db185b1e187eaf397e9e4c37066777e to your computer and use it in GitHub Desktop.
v7_jpeg_encoder_v6_v7_range_diff
1: cf342fc82027 ! 1: a6127440c125 media: dt-bindings: Add Imagination E5010 JPEG Encoder
@@ Commit message
Signed-off-by: David Huang <d-huang@ti.com>
Signed-off-by: Devarsh Thakkar <devarsht@ti.com>
Reviewed-by: Rob Herring <robh@kernel.org>
+ ---
+ V2: No change
+ V3:
+ - Add vendor specific compatible
+ - Update reg names
+ - Update clocks to 1
+ - Fix dts example with proper naming
+ V4:
+ - Use ti-specific compatible ti,am62a-jpeg-enc as secondary one
+ - Update commit message and title
+ - Remove clock-names as only single clock
+ V5:
+ - Add Reviewed-By tag
+ V6:
+ - No change
+ V7:
+ - No change
## Documentation/devicetree/bindings/media/img,e5010-jpeg-enc.yaml (new) ##
@@
2: 25c39e0883c7 < -: ------------ media: jpeg: Add reference quantization and huffman tables
3: ee7b672770ce ! 2: 381440c52a66 media: imagination: Add E5010 JPEG Encoder driver
@@ Commit message
- DMABUF import, export support
- NV12, NV21, NV16, NV61 video format support
- Compression quality S_CTRL
+ - Cropping support using S_SELECTION
Existing V4L2 M2M based JPEG drivers namely s5p-jpeg, imx-jpeg and rcar_jpu
were referred while making this.
@@ Commit message
Link: https://www.ti.com/lit/pdf/spruj16
[2]: v4l2-compliance test :
- Link: https://gist.github.com/devarsht/7ad3d344e11e2c17befbf16bc079f817
+ Link: https://gist.github.com/devarsht/1f039c631ca953a57f405cfce1b69e49
[3]: E5010 JPEG Encoder Manual tests :
+
Performance:
- Link: https://gist.github.com/devarsht/02397fa4ecee5104898cba67ff08dd4f
+ Link: https://gist.github.com/devarsht/c40672944fd71c9a53ab55adbfd9e28b
Functionality:
- Link: https://gist.github.com/devarsht/b2c4f537d7b0f822dd4da28ffdd970c0
+ Link: https://gist.github.com/devarsht/8e88fcaabff016bb2bac83d89c9d23ce
Compression Quality:
- Link: https://gist.github.com/devarsht/ef14fb216c9b5c484a712c94fffeb26b
+ Link: https://gist.github.com/devarsht/cbcc7cd97e8c48ba1486caa2b7884655
Multi Instance:
- Link: https://gist.github.com/devarsht/0e4949e72d55d0f608f7a28de5e2a4f9
+ Link: https://gist.github.com/devarsht/22c2fca08cd3441fb40f2c7a4cebc95a
+
+ Crop support:
+ Link: https://gist.github.com/devarsht/de6f5142f678bb1a5338abfd9f814abd
+
+ Runtime PM:
+ Link: https://gist.github.com/devarsht/70cd95d4440ddc678489d93885ddd4dd
Co-developed-by: David Huang <d-huang@ti.com>
Signed-off-by: David Huang <d-huang@ti.com>
Signed-off-by: Devarsh Thakkar <devarsht@ti.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+ ---
+ V2:
+ No change
+
+ V3:
+ - Correct license headers
+ - Use more generic name core instead of jasper for base registers
+ - Add Comment for forward declarations
+ - Simplify quantization table calculations
+ - Use v4l2_apply_frmsize_constraints for updating framesize and remove
+ unrequired functions
+ - Place TODO at top of file and in commit message too
+ - Use dev_err_probe helper in probe function
+ - Fix return value checking for failure scenarios in probe function
+ - Use v4l2_err/info/warn helpers instead of dev_err/info/warn helpers
+ - Fix unexpected indentation
+ - Correct commit message
+ - Remove dependency on ARCH_K3 as driver is not specific to that
+
+ V4:
+ - Fix issue with default params setting
+ - Correct v4l2 error prints
+ - Simplify register write functions with single statement return values
+ - Remove unrequired error checks from get_queue()
+ - Drop explicit device_caps setting as it is already taken care by v4l2
+ core
+ - Remove unrequired multiplanar checks and memset from s_fmt, g_fmt
+ callback
+ functions
+ - Fix try_fmt callback to not update the queues
+ - Remove unrequired contiguous format attribute from queue_init
+ - Use dynamic allocation for video_device and remove unrequired
+ assignments in probe()
+ - Remove unrequired checks from queue_setup function
+ - Return queued buffers back if start_streaming fails
+ - Use ARRAY_SIZE in place of hard-coding
+ - Use huffman and quantization tables from reference header file
+
+ V5:
+ - Sort the #includes alphabetically in e5010-jpeg-enc.c
+ - Update commit message to point to V5 test reports
+
+ V6:
+ - Fix sparse warnings and maintain uniform usage of dev ptr to avoid
+ future such bugs. No more errors received as shown below :
+
+ `smatch/smatch_scripts/kchecker
+ drivers/media/platform/imagination/e5010*.c
+ CHECK scripts/mod/empty.c
+ CALL scripts/checksyscalls.sh
+ CHECK arch/arm64/kernel/vdso/vgettimeofday.c
+ CC [M] drivers/media/platform/imagination/e5010-jpeg-enc.o
+ CHECK drivers/media/platform/imagination/e5010-jpeg-enc.c`
+
+ - Drop Reviewed-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+ as patchset got updated to fix sparse warnings mentinoed at
+ https://lore.kernel.org/all/f59b2d27-dc58-40fb-b899-647feb9d72e4@collabora.com/#t
+
+ V7:
+ - Add cropping support, fix S_SELECTION and G_SELECTION ioctls
+ - Fix PM use-case: Re-enable hardware on system resume before resuming the
+ v4l2 m2m jobs
+ - Re-instate Reviewed-by tag as discussed afterwards in mailing list
+
+ Link to previous patch revisions:
+ V3:
+ https://lore.kernel.org/all/20230816152210.4080779-3-devarsht@ti.com/
+ V4:
+ https://lore.kernel.org/all/20240205114239.924697-4-devarsht@ti.com/
+ V5:
+ https://lore.kernel.org/all/20240215134641.3381478-4-devarsht@ti.com/
+ V6:
+ https://lore.kernel.org/all/20240228141140.3530612-4-devarsht@ti.com/
## MAINTAINERS ##
@@ MAINTAINERS: F: drivers/auxdisplay/img-ascii-lcd.c
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+#include <linux/of_device.h>
+#include <linux/pm_runtime.h>
+#include <media/jpeg.h>
-+#include <media/jpeg-enc-reftables.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
++#include <media/v4l2-jpeg.h>
++#include <media/v4l2-rect.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-v4l2.h>
+#include "e5010-jpeg-enc.h"
+#include "e5010-jpeg-enc-hw.h"
+
++/* Luma and chroma qp table to achieve 50% compression quality
++ * This is as per example in Annex K.1 of ITU-T.81
++ */
++static const u8 luma_q_table[64] = {
++ 16, 11, 10, 16, 24, 40, 51, 61,
++ 12, 12, 14, 19, 26, 58, 60, 55,
++ 14, 13, 16, 24, 40, 57, 69, 56,
++ 14, 17, 22, 29, 51, 87, 80, 62,
++ 18, 22, 37, 56, 68, 109, 103, 77,
++ 24, 35, 55, 64, 81, 104, 113, 92,
++ 49, 64, 78, 87, 103, 121, 120, 101,
++ 72, 92, 95, 98, 112, 100, 103, 99
++};
++
++static const u8 chroma_q_table[64] = {
++ 17, 18, 24, 47, 99, 99, 99, 99,
++ 18, 21, 26, 66, 99, 99, 99, 99,
++ 24, 26, 56, 99, 99, 99, 99, 99,
++ 47, 66, 99, 99, 99, 99, 99, 99,
++ 99, 99, 99, 99, 99, 99, 99, 99,
++ 99, 99, 99, 99, 99, 99, 99, 99,
++ 99, 99, 99, 99, 99, 99, 99, 99,
++ 99, 99, 99, 99, 99, 99, 99, 99
++};
++
++/* Zigzag scan pattern */
++static const u8 zigzag[64] = {
++ 0, 1, 8, 16, 9, 2, 3, 10,
++ 17, 24, 32, 25, 18, 11, 4, 5,
++ 12, 19, 26, 33, 40, 48, 41, 34,
++ 27, 20, 13, 6, 7, 14, 21, 28,
++ 35, 42, 49, 56, 57, 50, 43, 36,
++ 29, 22, 15, 23, 30, 37, 44, 51,
++ 58, 59, 52, 45, 38, 31, 39, 46,
++ 53, 60, 61, 54, 47, 55, 62, 63
++};
++
++/*
++ * Contains the data that needs to be sent in the marker segment of an interchange format JPEG
++ * stream or an abbreviated format table specification data stream.
++ * Specifies the huffman table used for encoding the luminance DC coefficient differences.
++ * The table represents Table K.3 of ITU-T.81
++ */
++static const u8 luma_dc_table[] = {
++ 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B
++};
++
++/*
++ * Contains the data that needs to be sent in the marker segment of an interchange format JPEG
++ * stream or an abbreviated format table specification data stream.
++ * Specifies the huffman table used for encoding the luminance AC coefficients.
++ * The table represents Table K.5 of ITU-T.81
++ */
++static const u8 luma_ac_table[] = {
++ 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
++ 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D,
++ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
++ 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52,
++ 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25,
++ 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45,
++ 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64,
++ 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x83,
++ 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
++ 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
++ 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3,
++ 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8,
++ 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
++};
++
++/*
++ * Contains the data that needs to be sent in the marker segment of an interchange format JPEG
++ * stream or an abbreviated format table specification data stream.
++ * Specifies the huffman table used for encoding the chrominance DC coefficient differences.
++ * The table represents Table K.4 of ITU-T.81
++ */
++static const u8 chroma_dc_table[] = {
++ 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
++ 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B
++};
++
++/*
++ * Contains the data that needs to be sent in the marker segment of an interchange format JPEG
++ * stream or an abbreviated format table specification data stream.
++ * Specifies the huffman table used for encoding the chrominance AC coefficients.
++ * The table represents Table K.6 of ITU-T.81
++ */
++static const u8 chroma_ac_table[] = {
++ 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
++ 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
++ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61,
++ 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33,
++ 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18,
++ 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
++ 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63,
++ 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
++ 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
++ 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4,
++ 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
++ 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
++ 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
++};
++
++#define JPEG_LUM_HT 0x00
++#define JPEG_CHR_HT 0x01
++#define JPEG_DC_HT 0x00
++#define JPEG_AC_HT 0x10
++
+/* forward declarations */
+static const struct of_device_id e5010_of_match[];
+
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+ queue->bytesperline[i] = plane_fmt[i].bytesperline;
+ queue->sizeimage[i] = plane_fmt[i].sizeimage;
+ }
++ queue->crop.left = 0;
++ queue->crop.top = 0;
++ queue->crop.width = queue->width;
++ queue->crop.height = queue->height;
+ } else {
+ queue->sizeimage[0] = plane_fmt[0].sizeimage;
+ queue->sizeimage[1] = 0;
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+ struct e5010_context *ctx = file->private_data;
+ struct e5010_q_data *queue;
+
-+ if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
++ if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+
-+ queue = get_queue(ctx, s->type);
++ queue = get_queue(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+
+ switch (s->target) {
+ case V4L2_SEL_TGT_CROP_DEFAULT:
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+ s->r.height = queue->height;
+ break;
+ case V4L2_SEL_TGT_CROP:
-+ s->r = queue->crop;
++ memcpy(&s->r, &queue->crop, sizeof(s->r));
+ break;
+ default:
+ return -EINVAL;
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+{
+ struct e5010_context *ctx = file->private_data;
+ struct e5010_q_data *queue;
++ struct vb2_queue *vq;
++ struct v4l2_rect base_rect;
+
-+ if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
++ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, s->type);
++ if (!vq)
+ return -EINVAL;
+
-+ queue = get_queue(ctx, s->type);
++ if (vb2_is_streaming(vq))
++ return -EBUSY;
+
-+ queue->crop.left = 0;
-+ queue->crop.top = 0;
-+ queue->crop.width = s->r.width;
-+ queue->crop.height = s->r.height;
++ if (s->target != V4L2_SEL_TGT_CROP ||
++ s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
++ return -EINVAL;
++
++ queue = get_queue(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
++ base_rect.top = 0;
++ base_rect.left = 0;
++ base_rect.width = queue->width;
++ base_rect.height = queue->height;
++
++ switch (s->flags) {
++ case 0:
++ s->r.width = round_down(s->r.width, queue->fmt->frmsize.step_width);
++ s->r.height = round_down(s->r.height, queue->fmt->frmsize.step_height);
++ s->r.left = round_down(s->r.left, queue->fmt->frmsize.step_width);
++ s->r.top = round_down(s->r.top, 2);
++
++ if (s->r.left + s->r.width > queue->width)
++ s->r.width = round_down(s->r.width + s->r.left - queue->width,
++ queue->fmt->frmsize.step_width);
++ if (s->r.top + s->r.height > queue->height)
++ s->r.top = round_down(s->r.top + s->r.height - queue->height, 2);
++ break;
++ case V4L2_SEL_FLAG_GE:
++ s->r.width = round_up(s->r.width, queue->fmt->frmsize.step_width);
++ s->r.height = round_up(s->r.height, queue->fmt->frmsize.step_height);
++ s->r.left = round_up(s->r.left, queue->fmt->frmsize.step_width);
++ s->r.top = round_up(s->r.top, 2);
++ break;
++ case V4L2_SEL_FLAG_LE:
++ s->r.width = round_down(s->r.width, queue->fmt->frmsize.step_width);
++ s->r.height = round_down(s->r.height, queue->fmt->frmsize.step_height);
++ s->r.left = round_down(s->r.left, queue->fmt->frmsize.step_width);
++ s->r.top = round_down(s->r.top, 2);
++ break;
++ case V4L2_SEL_FLAG_LE | V4L2_SEL_FLAG_GE:
++ if (!IS_ALIGNED(s->r.width, queue->fmt->frmsize.step_width) ||
++ !IS_ALIGNED(s->r.height, queue->fmt->frmsize.step_height) ||
++ !IS_ALIGNED(s->r.left, queue->fmt->frmsize.step_width) ||
++ !IS_ALIGNED(s->r.top, 2))
++ return -ERANGE;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ if (!v4l2_rect_enclosed(&s->r, &base_rect))
++ return -ERANGE;
++
++ memcpy(&queue->crop, &s->r, sizeof(s->r));
++
++ if (!v4l2_rect_equal(&s->r, &base_rect))
++ queue->crop_set = true;
++
++ dprintk(ctx->e5010, 2, "ctx: 0x%p: crop rectangle: w: %d, h : %d, l : %d, t : %d\n",
++ ctx, queue->crop.width, queue->crop.height, queue->crop.left, queue->crop.top);
+
+ return 0;
+}
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+ case V4L2_CID_JPEG_COMPRESSION_QUALITY:
+ ctx->quality = ctrl->val;
+ calculate_qp_tables(ctx);
++ dprintk(ctx->e5010, 2, "ctx: 0x%p compression quality set to : %d\n", ctx,
++ ctx->quality);
+ break;
+ default:
+ return -EINVAL;
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+ queue->height = DEFAULT_HEIGHT;
+ pix_mp->width = queue->width;
+ pix_mp->height = queue->height;
++ queue->crop.left = 0;
++ queue->crop.top = 0;
++ queue->crop.width = queue->width;
++ queue->crop.height = queue->height;
+ v4l2_apply_frmsize_constraints(&pix_mp->width,
+ &pix_mp->height,
+ &fmt->frmsize);
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+ }
+ queue->width_adjusted = pix_mp->width;
+ queue->height_adjusted = pix_mp->height;
-+ queue->format_set = false;
-+ queue->streaming = false;
+
+ f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_JPEG;
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+ queue->sizeimage[1] = 0;
+ queue->bytesperline[0] = 0;
+ queue->bytesperline[1] = 0;
-+ queue->format_set = false;
-+ queue->streaming = false;
+ queue->width_adjusted = pix_mp->width;
+ queue->height_adjusted = pix_mp->height;
+}
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+ header_write(ctx, buffer, offset, 2, SOF_BASELINE_DCT);
+ header_write(ctx, buffer, offset, 2, 8 + (3 * UC_NUM_COMP));
+ header_write(ctx, buffer, offset, 1, PRECISION);
-+ header_write(ctx, buffer, offset, 2, ctx->out_queue.height);
-+ header_write(ctx, buffer, offset, 2, ctx->out_queue.width);
++ header_write(ctx, buffer, offset, 2, ctx->out_queue.crop.height);
++ header_write(ctx, buffer, offset, 2, ctx->out_queue.crop.width);
+ header_write(ctx, buffer, offset, 1, UC_NUM_COMP);
+
+ /* Luma details */
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+
+ struct e5010_q_data *queue = get_queue(ctx, q->type);
+
-+ queue->streaming = true;
+ v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q);
+ queue->sequence = 0;
+
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+
+ queue = get_queue(ctx, q->type);
+
-+ queue->streaming = false;
-+
+ e5010_vb2_buffers_return(q, VB2_BUF_STATE_ERROR);
+
+ if (V4L2_TYPE_IS_OUTPUT(q->type))
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+ struct e5010_dev *e5010 = ctx->e5010;
+ struct vb2_v4l2_buffer *s_vb, *d_vb;
+ u32 reg = 0;
-+ int ret = 0;
++ int ret = 0, luma_crop_offset = 0, chroma_crop_offset = 0;
+ unsigned long flags;
+ int num_planes = ctx->out_queue.fmt->num_planes;
+
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+
+ /* Set I/O Buffer addresses */
+ reg = (u32)vb2_dma_contig_plane_dma_addr(&s_vb->vb2_buf, 0);
-+ ret = e5010_hw_set_input_luma_addr(e5010->core_base, reg);
++
++ if (ctx->out_queue.crop_set) {
++ luma_crop_offset = ctx->out_queue.bytesperline[0] * ctx->out_queue.crop.top +
++ ctx->out_queue.crop.left;
++
++ if (ctx->out_queue.fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_422) {
++ chroma_crop_offset =
++ ctx->out_queue.bytesperline[0] * ctx->out_queue.crop.top
++ + ctx->out_queue.crop.left;
++ } else {
++ chroma_crop_offset =
++ ctx->out_queue.bytesperline[0] * ctx->out_queue.crop.top / 2
++ + ctx->out_queue.crop.left;
++ }
++
++ dprintk(e5010, 1, "Luma crop offset : %x, chroma crop offset : %x\n",
++ luma_crop_offset, chroma_crop_offset);
++ }
++
++ ret = e5010_hw_set_input_luma_addr(e5010->core_base, reg + luma_crop_offset);
+ if (ret || !reg) {
+ v4l2_err(&e5010->v4l2_dev, "failed to set input luma address\n");
+ goto device_busy_err;
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+
+ dprintk(e5010, 3,
+ "ctx: 0x%p, luma_addr: 0x%x, chroma_addr: 0x%x, out_addr: 0x%x\n",
-+ ctx, (u32)vb2_dma_contig_plane_dma_addr(&s_vb->vb2_buf, 0), reg,
-+ (u32)vb2_dma_contig_plane_dma_addr(&d_vb->vb2_buf, 0));
++ ctx, (u32)vb2_dma_contig_plane_dma_addr(&s_vb->vb2_buf, 0) + luma_crop_offset,
++ reg + chroma_crop_offset, (u32)vb2_dma_contig_plane_dma_addr(&d_vb->vb2_buf, 0));
+
+ dprintk(e5010, 3,
+ "ctx: 0x%p, buf indices: src_index: %d, dst_index: %d\n",
+ ctx, s_vb->vb2_buf.index, d_vb->vb2_buf.index);
+
-+ ret = e5010_hw_set_input_chroma_addr(e5010->core_base, reg);
++ ret = e5010_hw_set_input_chroma_addr(e5010->core_base, reg + chroma_crop_offset);
+ if (ret || !reg) {
+ v4l2_err(&e5010->v4l2_dev, "failed to set input chroma address\n");
+ goto device_busy_err;
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+ }
+
+ /* Set input settings */
-+ ret = e5010_hw_set_horizontal_size(e5010->core_base, ctx->out_queue.width - 1);
++ ret = e5010_hw_set_horizontal_size(e5010->core_base, ctx->out_queue.crop.width - 1);
+ if (ret) {
+ v4l2_err(&e5010->v4l2_dev, "failed to set input width\n");
+ goto device_busy_err;
+ }
+
-+ ret = e5010_hw_set_vertical_size(e5010->core_base, ctx->out_queue.height - 1);
++ ret = e5010_hw_set_vertical_size(e5010->core_base, ctx->out_queue.crop.height - 1);
+ if (ret) {
+ v4l2_err(&e5010->v4l2_dev, "failed to set input width\n");
+ goto device_busy_err;
@@ drivers/media/platform/imagination/e5010-jpeg-enc.c (new)
+ if (ret < 0)
+ return ret;
+
++ ret = e5010_init_device(e5010);
++ if (ret) {
++ dev_err(dev, "Failed to re-enable e5010 device\n");
++ return ret;
++ }
++
+ v4l2_m2m_resume(e5010->m2m_dev);
+
+ return ret;
@@ drivers/media/platform/imagination/e5010-jpeg-enc.h (new)
+ u32 height_adjusted;
+ u32 sizeimage[MAX_PLANES];
+ u32 bytesperline[MAX_PLANES];
-+ bool format_set;
-+ bool streaming;
+ u32 sequence;
+ struct v4l2_rect crop;
++ bool crop_set;
+};
+
+/*
-: ------------ > 3: 7f4e18538fed media: v4l2-jpeg: Export reference quantization and huffman tables
-: ------------ > 4: 48ac70a99632 media: imagination: Use exported tables from v4l2-jpeg core
-: ------------ > 5: a86b2c86932c media: verisilcon : Use exported tables from v4l2-jpeg for hantro codec
-: ------------ > 6: f3415cd3586f math.h Add macros to round to closest specified power of 2
-: ------------ > 7: 6731da6fe8ee media: imagination: Round to closest multiple for cropping region
-: ------------ > 8: eeda15dc1664 gpu: ipu-v3: Use generic macro for rounding to nearest multiple
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment