aboutsummaryrefslogtreecommitdiffstats
path: root/testing/linux-amlogic/0042-media-meson-vdec-add-MJPEG-decoding-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'testing/linux-amlogic/0042-media-meson-vdec-add-MJPEG-decoding-support.patch')
-rw-r--r--testing/linux-amlogic/0042-media-meson-vdec-add-MJPEG-decoding-support.patch253
1 files changed, 253 insertions, 0 deletions
diff --git a/testing/linux-amlogic/0042-media-meson-vdec-add-MJPEG-decoding-support.patch b/testing/linux-amlogic/0042-media-meson-vdec-add-MJPEG-decoding-support.patch
new file mode 100644
index 0000000000..b72f817fe6
--- /dev/null
+++ b/testing/linux-amlogic/0042-media-meson-vdec-add-MJPEG-decoding-support.patch
@@ -0,0 +1,253 @@
+From 9a662159440cf5e0f55275ef63588e35c91c581e Mon Sep 17 00:00:00 2001
+From: Maxime Jourdan <mjourdan@baylibre.com>
+Date: Sun, 21 Oct 2018 15:14:27 +0200
+Subject: [PATCH] media: meson: vdec: add MJPEG decoding support
+
+Add support for V4L2_PIX_FMT_MJPEG
+
+---
+ drivers/media/platform/meson/vdec/Makefile | 2 +-
+ drivers/media/platform/meson/vdec/codec_mjpeg.c | 140 ++++++++++++++++++++++
+ drivers/media/platform/meson/vdec/codec_mjpeg.h | 13 ++
+ drivers/media/platform/meson/vdec/vdec_platform.c | 31 +++++
+ 4 files changed, 185 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/media/platform/meson/vdec/codec_mjpeg.c
+ create mode 100644 drivers/media/platform/meson/vdec/codec_mjpeg.h
+
+diff --git a/drivers/media/platform/meson/vdec/Makefile b/drivers/media/platform/meson/vdec/Makefile
+index bb7a134..acf07f3 100644
+--- a/drivers/media/platform/meson/vdec/Makefile
++++ b/drivers/media/platform/meson/vdec/Makefile
+@@ -3,6 +3,6 @@
+
+ meson-vdec-objs = esparser.o vdec.o vdec_ctrls.o vdec_helpers.o vdec_platform.o
+ meson-vdec-objs += vdec_1.o
+-meson-vdec-objs += codec_mpeg12.o codec_h264.o codec_mpeg4.o
++meson-vdec-objs += codec_mpeg12.o codec_h264.o codec_mpeg4.o codec_mjpeg.o
+
+ obj-$(CONFIG_VIDEO_MESON_VDEC) += meson-vdec.o
+diff --git a/drivers/media/platform/meson/vdec/codec_mjpeg.c b/drivers/media/platform/meson/vdec/codec_mjpeg.c
+new file mode 100644
+index 0000000..abea9e3
+--- /dev/null
++++ b/drivers/media/platform/meson/vdec/codec_mjpeg.c
+@@ -0,0 +1,140 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Copyright (C) 2018 Maxime Jourdan <maxi.jourdan@wanadoo.fr>
++ */
++
++#include <media/v4l2-mem2mem.h>
++#include <media/videobuf2-dma-contig.h>
++
++#include "vdec_helpers.h"
++#include "dos_regs.h"
++
++/* map FW registers to known MJPEG functions */
++#define MREG_DECODE_PARAM AV_SCRATCH_2
++#define MREG_TO_AMRISC AV_SCRATCH_8
++#define MREG_FROM_AMRISC AV_SCRATCH_9
++#define MREG_FRAME_OFFSET AV_SCRATCH_A
++
++static int codec_mjpeg_can_recycle(struct amvdec_core *core)
++{
++ return !amvdec_read_dos(core, MREG_TO_AMRISC);
++}
++
++static void codec_mjpeg_recycle(struct amvdec_core *core, u32 buf_idx)
++{
++ amvdec_write_dos(core, MREG_TO_AMRISC, buf_idx + 1);
++}
++
++/* 4 point triangle */
++static const uint32_t filt_coef[] = {
++ 0x20402000, 0x20402000, 0x1f3f2101, 0x1f3f2101,
++ 0x1e3e2202, 0x1e3e2202, 0x1d3d2303, 0x1d3d2303,
++ 0x1c3c2404, 0x1c3c2404, 0x1b3b2505, 0x1b3b2505,
++ 0x1a3a2606, 0x1a3a2606, 0x19392707, 0x19392707,
++ 0x18382808, 0x18382808, 0x17372909, 0x17372909,
++ 0x16362a0a, 0x16362a0a, 0x15352b0b, 0x15352b0b,
++ 0x14342c0c, 0x14342c0c, 0x13332d0d, 0x13332d0d,
++ 0x12322e0e, 0x12322e0e, 0x11312f0f, 0x11312f0f,
++ 0x10303010
++};
++
++static void codec_mjpeg_init_scaler(struct amvdec_core *core)
++{
++ int i;
++
++ /* PSCALE cbus bmem enable */
++ amvdec_write_dos(core, PSCALE_CTRL, 0xc000);
++
++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 0);
++ for (i = 0; i < ARRAY_SIZE(filt_coef); ++i) {
++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0);
++ amvdec_write_dos(core, PSCALE_BMEM_DAT, filt_coef[i]);
++ }
++
++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 74);
++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x0008);
++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x60000000);
++
++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 82);
++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x0008);
++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x60000000);
++
++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 78);
++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x0008);
++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x60000000);
++
++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 86);
++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x0008);
++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x60000000);
++
++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 73);
++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x10000);
++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 81);
++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x10000);
++
++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 77);
++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x10000);
++ amvdec_write_dos(core, PSCALE_BMEM_ADDR, 85);
++ amvdec_write_dos(core, PSCALE_BMEM_DAT, 0x10000);
++
++ amvdec_write_dos(core, PSCALE_RST, 0x7);
++ amvdec_write_dos(core, PSCALE_RST, 0);
++}
++
++static int codec_mjpeg_start(struct amvdec_session *sess)
++{
++ struct amvdec_core *core = sess->core;
++
++ amvdec_write_dos(core, AV_SCRATCH_0, 12);
++ amvdec_write_dos(core, AV_SCRATCH_1, 0x031a);
++
++ amvdec_set_canvases(sess, (u32[]){ AV_SCRATCH_4, 0 },
++ (u32[]){ 4, 0 });
++ codec_mjpeg_init_scaler(core);
++
++ amvdec_write_dos(core, MREG_TO_AMRISC, 0);
++ amvdec_write_dos(core, MREG_FROM_AMRISC, 0);
++ amvdec_write_dos(core, MCPU_INTR_MSK, 0xffff);
++ amvdec_write_dos(core, MREG_DECODE_PARAM,
++ (sess->height << 4) | 0x8000);
++ amvdec_write_dos(core, VDEC_ASSIST_AMR1_INT8, 8);
++
++ /* Intra-only codec */
++ sess->keyframe_found = 1;
++
++ return 0;
++}
++
++static int codec_mjpeg_stop(struct amvdec_session *sess)
++{
++ return 0;
++}
++
++static irqreturn_t codec_mjpeg_isr(struct amvdec_session *sess)
++{
++ struct amvdec_core *core = sess->core;
++ u32 reg;
++ u32 buffer_index;
++ u32 offset;
++
++ amvdec_write_dos(core, ASSIST_MBOX1_CLR_REG, 1);
++
++ reg = amvdec_read_dos(core, MREG_FROM_AMRISC);
++ if (!(reg & 0x7))
++ return IRQ_HANDLED;
++
++ buffer_index = ((reg & 0x7) - 1) & 3;
++ offset = amvdec_read_dos(core, MREG_FRAME_OFFSET);
++ amvdec_dst_buf_done_idx(sess, buffer_index, offset, V4L2_FIELD_NONE);
++
++ amvdec_write_dos(core, MREG_FROM_AMRISC, 0);
++ return IRQ_HANDLED;
++}
++
++struct amvdec_codec_ops codec_mjpeg_ops = {
++ .start = codec_mjpeg_start,
++ .stop = codec_mjpeg_stop,
++ .isr = codec_mjpeg_isr,
++ .can_recycle = codec_mjpeg_can_recycle,
++ .recycle = codec_mjpeg_recycle,
++};
+diff --git a/drivers/media/platform/meson/vdec/codec_mjpeg.h b/drivers/media/platform/meson/vdec/codec_mjpeg.h
+new file mode 100644
+index 0000000..cc1cf73
+--- /dev/null
++++ b/drivers/media/platform/meson/vdec/codec_mjpeg.h
+@@ -0,0 +1,13 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
++/*
++ * Copyright (C) 2018 Maxime Jourdan <maxi.jourdan@wanadoo.fr>
++ */
++
++#ifndef __MESON_VDEC_CODEC_MJPEG_H_
++#define __MESON_VDEC_CODEC_MJPEG_H_
++
++#include "vdec.h"
++
++extern struct amvdec_codec_ops codec_mjpeg_ops;
++
++#endif
+\ No newline at end of file
+diff --git a/drivers/media/platform/meson/vdec/vdec_platform.c b/drivers/media/platform/meson/vdec/vdec_platform.c
+index 80b43fd..61def15 100644
+--- a/drivers/media/platform/meson/vdec/vdec_platform.c
++++ b/drivers/media/platform/meson/vdec/vdec_platform.c
+@@ -11,9 +11,20 @@
+ #include "codec_mpeg12.h"
+ #include "codec_h264.h"
+ #include "codec_mpeg4.h"
++#include "codec_mjpeg.h"
+
+ static const struct amvdec_format vdec_formats_gxbb[] = {
+ {
++ .pixfmt = V4L2_PIX_FMT_MJPEG,
++ .min_buffers = 4,
++ .max_buffers = 4,
++ .max_width = 1920,
++ .max_height = 1080,
++ .vdec_ops = &vdec_1_ops,
++ .codec_ops = &codec_mjpeg_ops,
++ .firmware_path = "meson/gx/vmjpeg_mc",
++ .pixfmts_cap = { V4L2_PIX_FMT_YUV420M, 0 },
++ }, {
+ .pixfmt = V4L2_PIX_FMT_MPEG4,
+ .min_buffers = 8,
+ .max_buffers = 8,
+@@ -80,6 +91,16 @@ static const struct amvdec_format vdec_formats_gxbb[] = {
+
+ static const struct amvdec_format vdec_formats_gxl[] = {
+ {
++ .pixfmt = V4L2_PIX_FMT_MJPEG,
++ .min_buffers = 4,
++ .max_buffers = 4,
++ .max_width = 1920,
++ .max_height = 1080,
++ .vdec_ops = &vdec_1_ops,
++ .codec_ops = &codec_mjpeg_ops,
++ .firmware_path = "meson/gx/vmjpeg_mc",
++ .pixfmts_cap = { V4L2_PIX_FMT_YUV420M, 0 },
++ }, {
+ .pixfmt = V4L2_PIX_FMT_MPEG4,
+ .min_buffers = 8,
+ .max_buffers = 8,
+@@ -146,6 +167,16 @@ static const struct amvdec_format vdec_formats_gxl[] = {
+
+ static const struct amvdec_format vdec_formats_gxm[] = {
+ {
++ .pixfmt = V4L2_PIX_FMT_MJPEG,
++ .min_buffers = 4,
++ .max_buffers = 4,
++ .max_width = 1920,
++ .max_height = 1080,
++ .vdec_ops = &vdec_1_ops,
++ .codec_ops = &codec_mjpeg_ops,
++ .firmware_path = "meson/gx/vmjpeg_mc",
++ .pixfmts_cap = { V4L2_PIX_FMT_YUV420M, 0 },
++ }, {
+ .pixfmt = V4L2_PIX_FMT_MPEG4,
+ .min_buffers = 8,
+ .max_buffers = 8,