2019-05-14 13:59:05

by Maxime Jourdan

[permalink] [raw]
Subject: [PATCH v6 0/4] Add Amlogic video decoder driver

Hi everyone,

[V6] Good news, the firmware situation is resolved. We have received a
redistributable license from Amlogic and the firmwares have been merged
in linux-firmware[5].

[V5] It's been a while since the last patch series regarding the Amlogic
video decoder. Unfortunately, the firmware licensing situation is still
on hold as we await communication from Amlogic. As such, we do not have
the firmwares in linux-firmware yet.
I decided to push the V5 anyway, as changes were starting to pile up.

This patch series adds support for the Amlogic video decoder,
as well as the corresponding dt bindings for GXBB/GXL/GXM chips.

It features decoding for the following formats:
- MPEG 1
- MPEG 2

The following formats will be added in future patches:
- MJPEG
- MPEG 4 (incl. Xvid, H.263)
- H.264
- HEVC (incl. 10-bit)
- VP9 (incl. 10-bit)

The code was made in such a way to allow easy inclusion of those formats
in the future.

The decoder is single instance.

Files:
- vdec.c handles the V4L2 M2M logic
- esparser.c manages the hardware bitstream parser
- vdec_helpers.c provides helpers to DONE the dst buffers as well as
various common code used by the codecs
- vdec_1.c manages the VDEC_1 block of the vdec IP
- vdec_ctrls.c handles the V4L2 controls exposed by the driver
- codec_mpeg12.c enables decoding for MPEG 1/2.
- vdec_platform.c links codec units with vdec units
(e.g vdec_1 with codec_mpeg12) and lists all the available
src/dst formats and requirements (max width/height, etc.),
per compatible chip.

It was tested primarily with ffmpeg's v4l2-m2m implementation. For instance:
$ ffmpeg -c:v mpeg2_v4l2m2m -i sample_mpeg2.mkv -f rawvideo out.nv12

The v4l2-compliance results are available below the patch diff.

Changes since v5 [4]:
- Rebased against media_tree (fixes conflict with platform/meson/Makefile
following the meson CEC driver updates)

Changes since v4 [3]:
- Updated for 5.1:
- cropcap -> g_pixelaspect
- dma_zalloc_coherent -> dma_alloc_coherent
- enum_framesizes: changed from STEPWISE to CONTINUOUS, as suggested by Hans
- Reintroduced support for CREATE_BUFS. It was a driver bug where I wasn't
accounting for the amount of buffers created this way (only buffers created
via REQBUFS were).
- Added the patch introducing V4L2_FMT_FLAG_FIXED_RESOLUTION to the V4L2
framework, needed as MPEG2 on Amlogic hardware only supports a fixed
resolution during a decode session.
- Added support for events and V4L2_EVENT_SOURCE_CHANGE, as it is now checked
by v4l2-compliance for stateful decoders. I was planning on introducing this
for codecs that actually use it (H264, HEVC..), but it doesn't hurt to have
this in the initial commit.
- Added support for controls, mainly V4L2_CID_MIN_BUFFERS_FOR_CAPTURE

Changes since v3 [2]:
- strlcpy -> strscpy
- queue_setup: account for existing buffers when clamping *num_buffers
- removed support for CREATE_BUFS. This caused issues with gstreamer and allowed
userspace to alloc more buffers than the decoder can handle in its fixed list.
So for now we just disable it and only allow allocating via REQBUFS.
- rebased & tested with 4.20-rc1

Changes since v2 [1]:
- Override capture queue's min_buffers_needed in queue_setup
The HW needs the full buffer list to be available when doing start_streaming
- Fix the draining sequence
The blob that we write to the ESPARSER to trigger drain is codec-dependent.
The one that was sent in v1 is specific to H.264 and isn't guaranteed to
trigger drain for MPEG2. For the latter, a simple MPEG2 EOS code
should be sent to the ESPARSER instead.
- Slight enhancements to the way we do vififo offset<=>timestamp matching

Changes since v1 [0]:
- use named interrupts in the bindings
- rewrite description in the bindings doc
- don't include the dts changes in the patch series
- fill the vb2 queues locks
- fill the video_device lock
- use helpers for wait_prepare and wait_finish vb2_ops
- remove unnecessary usleep in between esparser writes.
Extensive testing of every codec on GXBB/GXL didn't reveal
any fails without it, so just remove it.
- compile v4l2_compliance inside the git repo
- Check for plane number/plane size to pass the latest v4l2-compliance test
- Moved the single instance check (returning -EBUSY) to start/stop streaming
The check was previously in queue_setup but there was no great location to
clear it except for .close().
- Slight rework of the way CAPTURE frames are timestamped for better accuracy
- Implement PAR reporting via VIDIOC_CROPCAP

[5] https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/commit/?id=e04cc56d0e6b6ff05924ff88fdba1a438ee7d3c8
[4] https://patchwork.kernel.org/cover/10879959/
[3] https://patchwork.kernel.org/cover/10669875/
[2] https://lore.kernel.org/patchwork/cover/993093/
[1] https://patchwork.kernel.org/cover/10595803/
[0] https://patchwork.kernel.org/cover/10583391/

Maxime Jourdan (4):
dt-bindings: media: add Amlogic Video Decoder Bindings
media: videodev2: add V4L2_FMT_FLAG_FIXED_RESOLUTION
media: meson: add v4l2 m2m video decoder driver
MAINTAINERS: Add meson video decoder

.../bindings/media/amlogic,vdec.txt | 71 ++
.../media/uapi/v4l/vidioc-enum-fmt.rst | 6 +
MAINTAINERS | 8 +
drivers/media/platform/Kconfig | 10 +
drivers/media/platform/meson/Makefile | 1 +
drivers/media/platform/meson/vdec/Makefile | 8 +
.../media/platform/meson/vdec/codec_mpeg12.c | 209 ++++
.../media/platform/meson/vdec/codec_mpeg12.h | 14 +
drivers/media/platform/meson/vdec/dos_regs.h | 98 ++
drivers/media/platform/meson/vdec/esparser.c | 323 +++++
drivers/media/platform/meson/vdec/esparser.h | 32 +
drivers/media/platform/meson/vdec/vdec.c | 1071 +++++++++++++++++
drivers/media/platform/meson/vdec/vdec.h | 265 ++++
drivers/media/platform/meson/vdec/vdec_1.c | 229 ++++
drivers/media/platform/meson/vdec/vdec_1.h | 14 +
.../media/platform/meson/vdec/vdec_ctrls.c | 51 +
.../media/platform/meson/vdec/vdec_ctrls.h | 14 +
.../media/platform/meson/vdec/vdec_helpers.c | 441 +++++++
.../media/platform/meson/vdec/vdec_helpers.h | 80 ++
.../media/platform/meson/vdec/vdec_platform.c | 107 ++
.../media/platform/meson/vdec/vdec_platform.h | 30 +
include/uapi/linux/videodev2.h | 5 +-
22 files changed, 3085 insertions(+), 2 deletions(-)
create mode 100644 Documentation/devicetree/bindings/media/amlogic,vdec.txt
create mode 100644 drivers/media/platform/meson/vdec/Makefile
create mode 100644 drivers/media/platform/meson/vdec/codec_mpeg12.c
create mode 100644 drivers/media/platform/meson/vdec/codec_mpeg12.h
create mode 100644 drivers/media/platform/meson/vdec/dos_regs.h
create mode 100644 drivers/media/platform/meson/vdec/esparser.c
create mode 100644 drivers/media/platform/meson/vdec/esparser.h
create mode 100644 drivers/media/platform/meson/vdec/vdec.c
create mode 100644 drivers/media/platform/meson/vdec/vdec.h
create mode 100644 drivers/media/platform/meson/vdec/vdec_1.c
create mode 100644 drivers/media/platform/meson/vdec/vdec_1.h
create mode 100644 drivers/media/platform/meson/vdec/vdec_ctrls.c
create mode 100644 drivers/media/platform/meson/vdec/vdec_ctrls.h
create mode 100644 drivers/media/platform/meson/vdec/vdec_helpers.c
create mode 100644 drivers/media/platform/meson/vdec/vdec_helpers.h
create mode 100644 drivers/media/platform/meson/vdec/vdec_platform.c
create mode 100644 drivers/media/platform/meson/vdec/vdec_platform.h


root@libretech-cc:~# v4l2-compliance -d /dev/video0
v4l2-compliance SHA: 40fd5611c5176137c80616f6ee93b36f0d88f2d5, 64 bits

Compliance test for meson-vdec device /dev/video0:

Driver Info:
Driver name : meson-vdec
Card type : Amlogic Video Decoder
Bus info : platform:meson-vdec
Driver version : 5.1.0
Capabilities : 0x84204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Detected Stateful Decoder

Required ioctls:
test VIDIOC_QUERYCAP: OK

Allow for multiple opens:
test second /dev/video0 open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK

Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0

Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)

Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
test VIDIOC_QUERYCTRL: OK
test VIDIOC_G/S_CTRL: OK
test VIDIOC_G/S/TRY_EXT_CTRLS: OK
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 2 Private Controls: 0

Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
test VIDIOC_TRY_FMT: OK
test VIDIOC_S_FMT: OK
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK

Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK

Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
test VIDIOC_EXPBUF: OK
test Requests: OK (Not Supported)

Total for meson-vdec device /dev/video0: 44, Succeeded: 44, Failed: 0, Warnings: 0

--
2.21.0


2019-05-14 13:59:08

by Maxime Jourdan

[permalink] [raw]
Subject: [PATCH v6 2/4] media: videodev2: add V4L2_FMT_FLAG_FIXED_RESOLUTION

When a v4l2 driver exposes V4L2_EVENT_SOURCE_CHANGE, some (usually
OUTPUT) formats may not be able to trigger this event.

For instance, MPEG2 on Amlogic hardware does not support resolution
switching on the fly, and a decode session must operate at a set
resolution defined before the decoding start.

Add a enum_fmt format flag to tag those specific formats.

Signed-off-by: Maxime Jourdan <[email protected]>
---
Documentation/media/uapi/v4l/vidioc-enum-fmt.rst | 6 ++++++
include/uapi/linux/videodev2.h | 5 +++--
2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst b/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst
index 822d6730e7d2..b11448a1848b 100644
--- a/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst
+++ b/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst
@@ -127,6 +127,12 @@ one until ``EINVAL`` is returned.
- This format is not native to the device but emulated through
software (usually libv4l2), where possible try to use a native
format instead for better performance.
+ * - ``V4L2_FMT_FLAG_FIXED_RESOLUTION``
+ - 0x0004
+ - Dynamic resolution switching is not supported for this format,
+ even if the event ``V4L2_EVENT_SOURCE_CHANGE`` is supported by
+ the device.
+


Return Value
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 1050a75fb7ef..9b0a7f82dd92 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -768,8 +768,9 @@ struct v4l2_fmtdesc {
__u32 reserved[4];
};

-#define V4L2_FMT_FLAG_COMPRESSED 0x0001
-#define V4L2_FMT_FLAG_EMULATED 0x0002
+#define V4L2_FMT_FLAG_COMPRESSED 0x0001
+#define V4L2_FMT_FLAG_EMULATED 0x0002
+#define V4L2_FMT_FLAG_FIXED_RESOLUTION 0x0004

/* Frame Size and frame rate enumeration */
/*
--
2.21.0

2019-05-14 14:00:18

by Maxime Jourdan

[permalink] [raw]
Subject: [PATCH v6 1/4] dt-bindings: media: add Amlogic Video Decoder Bindings

Add documentation for the meson vdec dts node.

Reviewed-by: Rob Herring <[email protected]>
Signed-off-by: Maxime Jourdan <[email protected]>
---
.../bindings/media/amlogic,vdec.txt | 71 +++++++++++++++++++
1 file changed, 71 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/amlogic,vdec.txt

diff --git a/Documentation/devicetree/bindings/media/amlogic,vdec.txt b/Documentation/devicetree/bindings/media/amlogic,vdec.txt
new file mode 100644
index 000000000000..aabdd01bcf32
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/amlogic,vdec.txt
@@ -0,0 +1,71 @@
+Amlogic Video Decoder
+================================
+
+The video decoding IP lies within the DOS memory region,
+except for the hardware bitstream parser that makes use of an undocumented
+region.
+
+It makes use of the following blocks:
+
+- ESPARSER is a bitstream parser that outputs to a VIFIFO. Further VDEC blocks
+then feed from this VIFIFO.
+- VDEC_1 can decode MPEG-1, MPEG-2, MPEG-4 part 2, MJPEG, H.263, H.264, VC-1.
+- VDEC_HEVC can decode HEVC and VP9.
+
+Both VDEC_1 and VDEC_HEVC share the "vdec" IRQ and as such cannot run
+concurrently.
+
+Device Tree Bindings:
+---------------------
+
+VDEC: Video Decoder
+--------------------------
+
+Required properties:
+- compatible: value should be different for each SoC family as :
+ - GXBB (S905) : "amlogic,gxbb-vdec"
+ - GXL (S905X, S905D) : "amlogic,gxl-vdec"
+ - GXM (S912) : "amlogic,gxm-vdec"
+- reg: base address and size of he following memory-mapped regions :
+ - dos
+ - esparser
+- reg-names: should contain the names of the previous memory regions
+- interrupts: should contain the following IRQs:
+ - vdec
+ - esparser
+- interrupt-names: should contain the names of the previous interrupts
+- amlogic,ao-sysctrl: should point to the AOBUS sysctrl node
+- amlogic,canvas: should point to a canvas provider node
+- clocks: should contain the following clocks :
+ - dos_parser
+ - dos
+ - vdec_1
+ - vdec_hevc
+- clock-names: should contain the names of the previous clocks
+- resets: should contain the parser reset
+- reset-names: should be "esparser"
+
+Example:
+
+vdec: video-decoder@c8820000 {
+ compatible = "amlogic,gxbb-vdec";
+ reg = <0x0 0xc8820000 0x0 0x10000>,
+ <0x0 0xc110a580 0x0 0xe4>;
+ reg-names = "dos", "esparser";
+
+ interrupts = <GIC_SPI 44 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 32 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "vdec", "esparser";
+
+ amlogic,ao-sysctrl = <&sysctrl_AO>;
+ amlogic,canvas = <&canvas>;
+
+ clocks = <&clkc CLKID_DOS_PARSER>,
+ <&clkc CLKID_DOS>,
+ <&clkc CLKID_VDEC_1>,
+ <&clkc CLKID_VDEC_HEVC>;
+ clock-names = "dos_parser", "dos", "vdec_1", "vdec_hevc";
+
+ resets = <&reset RESET_PARSER>;
+ reset-names = "esparser";
+};
--
2.21.0

2019-05-14 18:48:40

by Martin Blumenstingl

[permalink] [raw]
Subject: Re: [PATCH v6 1/4] dt-bindings: media: add Amlogic Video Decoder Bindings

Hi Maxime,

On Tue, May 14, 2019 at 3:56 PM Maxime Jourdan <[email protected]> wrote:
>
> Add documentation for the meson vdec dts node.
thank you for working on this!

> Reviewed-by: Rob Herring <[email protected]>
> Signed-off-by: Maxime Jourdan <[email protected]>
Reviewed-by: Martin Blumenstingl <[email protected]>

[...]
> +Required properties:
> +- compatible: value should be different for each SoC family as :
> + - GXBB (S905) : "amlogic,gxbb-vdec"
> + - GXL (S905X, S905D) : "amlogic,gxl-vdec"
> + - GXM (S912) : "amlogic,gxm-vdec"
> +- reg: base address and size of he following memory-mapped regions :
> + - dos
> + - esparser
> +- reg-names: should contain the names of the previous memory regions
> +- interrupts: should contain the following IRQs:
> + - vdec
> + - esparser
> +- interrupt-names: should contain the names of the previous interrupts
Maxime already mentioned in the RFC version that there may be more
interrupts in the future. I'm fine with adding the missing ones on
demand

> +- amlogic,ao-sysctrl: should point to the AOBUS sysctrl node
my goal is to remove this property at some point and replace it with
references to the power-domains.
however, we don't have a power-domain driver for this yet (it's
somewhere on my TODO-list - it involves splitting the current
meson-gx-pwrc-vpu into two separate drivers, so we need to do it
carefully so we don't break HDMI support)


Regards
Martin