mbox series

[v11,0/9] Add HANTRO G2/HEVC decoder support for IMX8MQ

Message ID 20210525161238.1191168-1-benjamin.gaignard@collabora.com
Headers show
Series Add HANTRO G2/HEVC decoder support for IMX8MQ | expand

Message

Benjamin Gaignard May 25, 2021, 4:12 p.m. UTC
The IMX8MQ got two VPUs but until now only G1 has been enabled.
This series aim to add the second VPU (aka G2) and provide basic 
HEVC decoding support.

To be able to decode HEVC it is needed to add/update some of the
structures in the uapi. In addition of them one HANTRO dedicated
control is required to inform the driver of the number of bits to skip
at the beginning of the slice header.
The hardware require to allocate few auxiliary buffers to store the
references frame or tile size data.

The driver has been tested with fluster test suite stream.
For example with this command: ./fluster.py run -ts JCT-VC-HEVC_V1 -d GStreamer-H.265-V4L2SL-Gst1.0

version 11:
 - Rebased on media_stage.
 - Fix minor typo/remarks.

version 10:
 - Shorter version of the previous series without ctrl block patches
   and no DT modifications.
   The scope of this series is limited to HEVC support.

version 9:
 - Corrections in commits messages.
 - Define the dedicated control in hevc-controls.h
 - Add note in documentation.
 - Change max value of the dedicated control.
 - Rebased on media_tree/master branch.

version 8:
 - Add reviewed-by and ack-by tags 
 - Fix the warnings reported by kernel test robot
 - Only patch 9 (adding dedicated control), patch 11 (HEVC support) and
   patch 13 (DT changes) are still missing of review/ack tag.

version 7:
 - Remove 'q' from syscon phandle name to make usable for iMX8MM too.
   Update the bindings documentation.
 - Add review/ack tags.
 - Rebase on top of media_tree/master
 - Be more accurate when computing the size of the memory needed motion
   vectors.
 - Explain why the all clocks need to set in the both DT node.

version 6:
 - fix the errors reported by kernel test robot

version 5:
 - use syscon instead of VPU reset driver.
 - Do not break kernel/DT backward compatibility.
 - Add documentation for dedicated Hantro control.
 - Fix the remarks done by Ezequeil (typo, comments, unused function)
 - Run v4l2-compliance without errors (see below).
 - Do not add field to distinguish version, check postproc reg instead

version 4:
- Split the changes in hevc controls in 2 commits to make them easier to
  review.
- Change hantro_codec_ops run() prototype to return errors   
- Hantro v4l2 dedicated control is now only an integer
- rebase on top of VPU reset changes posted here:
  https://www.spinics.net/lists/arm-kernel/msg878440.html
- Various fix from previous remarks
- Limit the modifications in API to what the driver needs

version 3:
- Fix typo in Hantro v4l2 dedicated control
- Add documentation for the new structures and fields
- Rebased on top of media_tree for-linus-5.12-rc1 tag

version 2:
- remove all change related to scaling
- squash commits to a coherent split
- be more verbose about the added fields
- fix the comments done by Ezequiel about dma_alloc_coherent usage
- fix Dan's comments about control copy, reverse the test logic
in tile_buffer_reallocate, rework some goto and return cases.
- be more verbose about why I change the bindings
- remove all sign-off expect mime since it is confusing
- remove useless clocks in VPUs nodes
 
Benjamin Gaignard (9):
  media: hevc: Add fields and flags for hevc PPS
  media: hevc: Add decode params control
  media: hantro: change hantro_codec_ops run prototype to return errors
  media: hantro: Define HEVC codec profiles and supported features
  media: hantro: Only use postproc when post processed formats are
    defined
  media: uapi: Add a control for HANTRO driver
  media: hantro: handle V4L2_PIX_FMT_HEVC_SLICE control
  media: hantro: Introduce G2/HEVC decoder
  media: hantro: IMX8M: add variant for G2/HEVC codec

 .../userspace-api/media/drivers/hantro.rst    |  19 +
 .../userspace-api/media/drivers/index.rst     |   1 +
 .../media/v4l/ext-ctrls-codec.rst             | 108 +++-
 .../media/v4l/vidioc-queryctrl.rst            |   6 +
 drivers/media/v4l2-core/v4l2-ctrls-core.c     |  21 +-
 drivers/media/v4l2-core/v4l2-ctrls-defs.c     |   4 +
 drivers/staging/media/hantro/Makefile         |   2 +
 drivers/staging/media/hantro/hantro.h         |  13 +-
 drivers/staging/media/hantro/hantro_drv.c     |  99 ++-
 .../staging/media/hantro/hantro_g1_h264_dec.c |  10 +-
 .../media/hantro/hantro_g1_mpeg2_dec.c        |   4 +-
 .../staging/media/hantro/hantro_g1_vp8_dec.c  |   6 +-
 .../staging/media/hantro/hantro_g2_hevc_dec.c | 588 ++++++++++++++++++
 drivers/staging/media/hantro/hantro_g2_regs.h | 198 ++++++
 .../staging/media/hantro/hantro_h1_jpeg_enc.c |   4 +-
 drivers/staging/media/hantro/hantro_hevc.c    | 327 ++++++++++
 drivers/staging/media/hantro/hantro_hw.h      |  69 +-
 .../staging/media/hantro/hantro_postproc.c    |  14 +
 drivers/staging/media/hantro/hantro_v4l2.c    |   5 +-
 drivers/staging/media/hantro/imx8m_vpu_hw.c   |  96 ++-
 .../media/hantro/rk3399_vpu_hw_jpeg_enc.c     |   4 +-
 .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c    |   4 +-
 .../media/hantro/rk3399_vpu_hw_vp8_dec.c      |   6 +-
 drivers/staging/media/sunxi/cedrus/cedrus.c   |   6 +
 drivers/staging/media/sunxi/cedrus/cedrus.h   |   1 +
 .../staging/media/sunxi/cedrus/cedrus_dec.c   |   2 +
 .../staging/media/sunxi/cedrus/cedrus_h265.c  |  12 +-
 include/media/hevc-ctrls.h                    |  46 +-
 28 files changed, 1606 insertions(+), 69 deletions(-)
 create mode 100644 Documentation/userspace-api/media/drivers/hantro.rst
 create mode 100644 drivers/staging/media/hantro/hantro_g2_hevc_dec.c
 create mode 100644 drivers/staging/media/hantro/hantro_g2_regs.h
 create mode 100644 drivers/staging/media/hantro/hantro_hevc.c

Comments

Hans Verkuil May 26, 2021, 9:52 a.m. UTC | #1
On 25/05/2021 18:12, Benjamin Gaignard wrote:
> Add variant to IMX8M to enable G2/HEVC codec.

> Define the capabilities for the hardware up to 3840x2160.

> G2 doesn't have a postprocessor, uses the same clocks and has it

> own interrupt.

> 

> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>

> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>

> Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>

> ---

>  drivers/staging/media/hantro/hantro_drv.c   |  1 +

>  drivers/staging/media/hantro/hantro_hw.h    |  1 +

>  drivers/staging/media/hantro/imx8m_vpu_hw.c | 96 ++++++++++++++++++++-

>  3 files changed, 96 insertions(+), 2 deletions(-)

> 

> diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c

> index ae8a0037706f..507cd5b454b3 100644

> --- a/drivers/staging/media/hantro/hantro_drv.c

> +++ b/drivers/staging/media/hantro/hantro_drv.c

> @@ -588,6 +588,7 @@ static const struct of_device_id of_hantro_match[] = {

>  #endif

>  #ifdef CONFIG_VIDEO_HANTRO_IMX8M

>  	{ .compatible = "nxp,imx8mq-vpu", .data = &imx8mq_vpu_variant, },

> +	{ .compatible = "nxp,imx8mq-vpu-g2", .data = &imx8mq_vpu_g2_variant },


From checkpatch:

WARNING: DT compatible string "nxp,imx8mq-vpu-g2" appears un-documented -- check ./Documentation/devicetree/bindings/
#29: FILE: drivers/staging/media/hantro/hantro_drv.c:591:
+       { .compatible = "nxp,imx8mq-vpu-g2", .data = &imx8mq_vpu_g2_variant },

Is a patch missing for bindings adding "nxp,imx8mq-vpu-g2"?

Regards,

	Hans


>  #endif

>  #ifdef CONFIG_VIDEO_HANTRO_SAMA5D4

>  	{ .compatible = "microchip,sama5d4-vdec", .data = &sama5d4_vdec_variant, },

> diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h

> index b743b255bf32..5cc083112017 100644

> --- a/drivers/staging/media/hantro/hantro_hw.h

> +++ b/drivers/staging/media/hantro/hantro_hw.h

> @@ -206,6 +206,7 @@ extern const struct hantro_variant rk3328_vpu_variant;

>  extern const struct hantro_variant rk3288_vpu_variant;

>  extern const struct hantro_variant imx8mq_vpu_variant;

>  extern const struct hantro_variant sama5d4_vdec_variant;

> +extern const struct hantro_variant imx8mq_vpu_g2_variant;

>  

>  extern const struct hantro_postproc_regs hantro_g1_postproc_regs;

>  

> diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c

> index 9eb556460e52..ea152e1e6514 100644

> --- a/drivers/staging/media/hantro/imx8m_vpu_hw.c

> +++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c

> @@ -9,6 +9,9 @@

>  #include <linux/delay.h>

>  

>  #include "hantro.h"

> +#include "hantro_jpeg.h"

> +#include "hantro_g1_regs.h"

> +#include "hantro_g2_regs.h"

>  

>  #define CTRL_SOFT_RESET		0x00

>  #define RESET_G1		BIT(1)

> @@ -128,6 +131,62 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = {

>  	},

>  };

>  

> +static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = {

> +	{

> +		.fourcc = V4L2_PIX_FMT_NV12,

> +		.codec_mode = HANTRO_MODE_NONE,

> +	},

> +	{

> +		.fourcc = V4L2_PIX_FMT_HEVC_SLICE,

> +		.codec_mode = HANTRO_MODE_HEVC_DEC,

> +		.max_depth = 2,

> +		.frmsize = {

> +			.min_width = 48,

> +			.max_width = 3840,

> +			.step_width = MB_DIM,

> +			.min_height = 48,

> +			.max_height = 2160,

> +			.step_height = MB_DIM,

> +		},

> +	},

> +};

> +

> +static irqreturn_t imx8m_vpu_g1_irq(int irq, void *dev_id)

> +{

> +	struct hantro_dev *vpu = dev_id;

> +	enum vb2_buffer_state state;

> +	u32 status;

> +

> +	status = vdpu_read(vpu, G1_REG_INTERRUPT);

> +	state = (status & G1_REG_INTERRUPT_DEC_RDY_INT) ?

> +		 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;

> +

> +	vdpu_write(vpu, 0, G1_REG_INTERRUPT);

> +	vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG);

> +

> +	hantro_irq_done(vpu, state);

> +

> +	return IRQ_HANDLED;

> +}

> +

> +static irqreturn_t imx8m_vpu_g2_irq(int irq, void *dev_id)

> +{

> +	struct hantro_dev *vpu = dev_id;

> +	enum vb2_buffer_state state;

> +	u32 status;

> +

> +	status = vdpu_read(vpu, HEVC_REG_INTERRUPT);

> +	state = (status & HEVC_REG_INTERRUPT_DEC_RDY_INT) ?

> +		 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;

> +

> +	vdpu_write(vpu, 0, HEVC_REG_INTERRUPT);

> +	vdpu_write(vpu, HEVC_REG_CONFIG_DEC_CLK_GATE_E, HEVC_REG_CONFIG);

> +

> +	hantro_irq_done(vpu, state);

> +

> +	return IRQ_HANDLED;

> +}

> +

>  static int imx8mq_vpu_hw_init(struct hantro_dev *vpu)

>  {

>  	vpu->ctrl_base = vpu->reg_bases[vpu->variant->num_regs - 1];

> @@ -142,6 +201,13 @@ static void imx8m_vpu_g1_reset(struct hantro_ctx *ctx)

>  	imx8m_soft_reset(vpu, RESET_G1);

>  }

>  

> +static void imx8m_vpu_g2_reset(struct hantro_ctx *ctx)

> +{

> +	struct hantro_dev *vpu = ctx->dev;

> +

> +	imx8m_soft_reset(vpu, RESET_G2);

> +}

> +

>  /*

>   * Supported codec ops.

>   */

> @@ -167,13 +233,25 @@ static const struct hantro_codec_ops imx8mq_vpu_codec_ops[] = {

>  	},

>  };

>  

> +static const struct hantro_codec_ops imx8mq_vpu_g2_codec_ops[] = {

> +	[HANTRO_MODE_HEVC_DEC] = {

> +		.run = hantro_g2_hevc_dec_run,

> +		.reset = imx8m_vpu_g2_reset,

> +		.init = hantro_hevc_dec_init,

> +		.exit = hantro_hevc_dec_exit,

> +	},

> +};

> +

>  /*

>   * VPU variants.

>   */

>  

>  static const struct hantro_irq imx8mq_irqs[] = {

> -	{ "g1", hantro_g1_irq },

> -	{ "g2", NULL /* TODO: imx8m_vpu_g2_irq */ },

> +	{ "g1", imx8m_vpu_g1_irq },

> +};

> +

> +static const struct hantro_irq imx8mq_g2_irqs[] = {

> +	{ "g2", imx8m_vpu_g2_irq },

>  };

>  

>  static const char * const imx8mq_clk_names[] = { "g1", "g2", "bus" };

> @@ -197,3 +275,17 @@ const struct hantro_variant imx8mq_vpu_variant = {

>  	.reg_names = imx8mq_reg_names,

>  	.num_regs = ARRAY_SIZE(imx8mq_reg_names)

>  };

> +

> +const struct hantro_variant imx8mq_vpu_g2_variant = {

> +	.dec_offset = 0x0,

> +	.dec_fmts = imx8m_vpu_g2_dec_fmts,

> +	.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_g2_dec_fmts),

> +	.codec = HANTRO_HEVC_DECODER,

> +	.codec_ops = imx8mq_vpu_g2_codec_ops,

> +	.init = imx8mq_vpu_hw_init,

> +	.runtime_resume = imx8mq_runtime_resume,

> +	.irqs = imx8mq_g2_irqs,

> +	.num_irqs = ARRAY_SIZE(imx8mq_g2_irqs),

> +	.clk_names = imx8mq_clk_names,

> +	.num_clocks = ARRAY_SIZE(imx8mq_clk_names),

> +};

>
Benjamin Gaignard May 26, 2021, 11:10 a.m. UTC | #2
Le 26/05/2021 à 11:52, Hans Verkuil a écrit :
> On 25/05/2021 18:12, Benjamin Gaignard wrote:

>> Add variant to IMX8M to enable G2/HEVC codec.

>> Define the capabilities for the hardware up to 3840x2160.

>> G2 doesn't have a postprocessor, uses the same clocks and has it

>> own interrupt.

>>

>> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>

>> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>

>> Reviewed-by: Ezequiel Garcia <ezequiel@collabora.com>

>> ---

>>   drivers/staging/media/hantro/hantro_drv.c   |  1 +

>>   drivers/staging/media/hantro/hantro_hw.h    |  1 +

>>   drivers/staging/media/hantro/imx8m_vpu_hw.c | 96 ++++++++++++++++++++-

>>   3 files changed, 96 insertions(+), 2 deletions(-)

>>

>> diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c

>> index ae8a0037706f..507cd5b454b3 100644

>> --- a/drivers/staging/media/hantro/hantro_drv.c

>> +++ b/drivers/staging/media/hantro/hantro_drv.c

>> @@ -588,6 +588,7 @@ static const struct of_device_id of_hantro_match[] = {

>>   #endif

>>   #ifdef CONFIG_VIDEO_HANTRO_IMX8M

>>   	{ .compatible = "nxp,imx8mq-vpu", .data = &imx8mq_vpu_variant, },

>> +	{ .compatible = "nxp,imx8mq-vpu-g2", .data = &imx8mq_vpu_g2_variant },

>  From checkpatch:

>

> WARNING: DT compatible string "nxp,imx8mq-vpu-g2" appears un-documented -- check ./Documentation/devicetree/bindings/

> #29: FILE: drivers/staging/media/hantro/hantro_drv.c:591:

> +       { .compatible = "nxp,imx8mq-vpu-g2", .data = &imx8mq_vpu_g2_variant },

>

> Is a patch missing for bindings adding "nxp,imx8mq-vpu-g2"?


The DT and bindings patches are delayed because NXP guys want to use power domain to drive
the control block:
https://lore.kernel.org/linux-media/20210407073534.376722-1-benjamin.gaignard@collabora.com/T/#m6bd571fee94b1b1fa5c5d3fa6315ae5c9f4c8fad

Regards,
Benjamin

>

> Regards,

>

> 	Hans

>

>

>>   #endif

>>   #ifdef CONFIG_VIDEO_HANTRO_SAMA5D4

>>   	{ .compatible = "microchip,sama5d4-vdec", .data = &sama5d4_vdec_variant, },

>> diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h

>> index b743b255bf32..5cc083112017 100644

>> --- a/drivers/staging/media/hantro/hantro_hw.h

>> +++ b/drivers/staging/media/hantro/hantro_hw.h

>> @@ -206,6 +206,7 @@ extern const struct hantro_variant rk3328_vpu_variant;

>>   extern const struct hantro_variant rk3288_vpu_variant;

>>   extern const struct hantro_variant imx8mq_vpu_variant;

>>   extern const struct hantro_variant sama5d4_vdec_variant;

>> +extern const struct hantro_variant imx8mq_vpu_g2_variant;

>>   

>>   extern const struct hantro_postproc_regs hantro_g1_postproc_regs;

>>   

>> diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c

>> index 9eb556460e52..ea152e1e6514 100644

>> --- a/drivers/staging/media/hantro/imx8m_vpu_hw.c

>> +++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c

>> @@ -9,6 +9,9 @@

>>   #include <linux/delay.h>

>>   

>>   #include "hantro.h"

>> +#include "hantro_jpeg.h"

>> +#include "hantro_g1_regs.h"

>> +#include "hantro_g2_regs.h"

>>   

>>   #define CTRL_SOFT_RESET		0x00

>>   #define RESET_G1		BIT(1)

>> @@ -128,6 +131,62 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = {

>>   	},

>>   };

>>   

>> +static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = {

>> +	{

>> +		.fourcc = V4L2_PIX_FMT_NV12,

>> +		.codec_mode = HANTRO_MODE_NONE,

>> +	},

>> +	{

>> +		.fourcc = V4L2_PIX_FMT_HEVC_SLICE,

>> +		.codec_mode = HANTRO_MODE_HEVC_DEC,

>> +		.max_depth = 2,

>> +		.frmsize = {

>> +			.min_width = 48,

>> +			.max_width = 3840,

>> +			.step_width = MB_DIM,

>> +			.min_height = 48,

>> +			.max_height = 2160,

>> +			.step_height = MB_DIM,

>> +		},

>> +	},

>> +};

>> +

>> +static irqreturn_t imx8m_vpu_g1_irq(int irq, void *dev_id)

>> +{

>> +	struct hantro_dev *vpu = dev_id;

>> +	enum vb2_buffer_state state;

>> +	u32 status;

>> +

>> +	status = vdpu_read(vpu, G1_REG_INTERRUPT);

>> +	state = (status & G1_REG_INTERRUPT_DEC_RDY_INT) ?

>> +		 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;

>> +

>> +	vdpu_write(vpu, 0, G1_REG_INTERRUPT);

>> +	vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG);

>> +

>> +	hantro_irq_done(vpu, state);

>> +

>> +	return IRQ_HANDLED;

>> +}

>> +

>> +static irqreturn_t imx8m_vpu_g2_irq(int irq, void *dev_id)

>> +{

>> +	struct hantro_dev *vpu = dev_id;

>> +	enum vb2_buffer_state state;

>> +	u32 status;

>> +

>> +	status = vdpu_read(vpu, HEVC_REG_INTERRUPT);

>> +	state = (status & HEVC_REG_INTERRUPT_DEC_RDY_INT) ?

>> +		 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;

>> +

>> +	vdpu_write(vpu, 0, HEVC_REG_INTERRUPT);

>> +	vdpu_write(vpu, HEVC_REG_CONFIG_DEC_CLK_GATE_E, HEVC_REG_CONFIG);

>> +

>> +	hantro_irq_done(vpu, state);

>> +

>> +	return IRQ_HANDLED;

>> +}

>> +

>>   static int imx8mq_vpu_hw_init(struct hantro_dev *vpu)

>>   {

>>   	vpu->ctrl_base = vpu->reg_bases[vpu->variant->num_regs - 1];

>> @@ -142,6 +201,13 @@ static void imx8m_vpu_g1_reset(struct hantro_ctx *ctx)

>>   	imx8m_soft_reset(vpu, RESET_G1);

>>   }

>>   

>> +static void imx8m_vpu_g2_reset(struct hantro_ctx *ctx)

>> +{

>> +	struct hantro_dev *vpu = ctx->dev;

>> +

>> +	imx8m_soft_reset(vpu, RESET_G2);

>> +}

>> +

>>   /*

>>    * Supported codec ops.

>>    */

>> @@ -167,13 +233,25 @@ static const struct hantro_codec_ops imx8mq_vpu_codec_ops[] = {

>>   	},

>>   };

>>   

>> +static const struct hantro_codec_ops imx8mq_vpu_g2_codec_ops[] = {

>> +	[HANTRO_MODE_HEVC_DEC] = {

>> +		.run = hantro_g2_hevc_dec_run,

>> +		.reset = imx8m_vpu_g2_reset,

>> +		.init = hantro_hevc_dec_init,

>> +		.exit = hantro_hevc_dec_exit,

>> +	},

>> +};

>> +

>>   /*

>>    * VPU variants.

>>    */

>>   

>>   static const struct hantro_irq imx8mq_irqs[] = {

>> -	{ "g1", hantro_g1_irq },

>> -	{ "g2", NULL /* TODO: imx8m_vpu_g2_irq */ },

>> +	{ "g1", imx8m_vpu_g1_irq },

>> +};

>> +

>> +static const struct hantro_irq imx8mq_g2_irqs[] = {

>> +	{ "g2", imx8m_vpu_g2_irq },

>>   };

>>   

>>   static const char * const imx8mq_clk_names[] = { "g1", "g2", "bus" };

>> @@ -197,3 +275,17 @@ const struct hantro_variant imx8mq_vpu_variant = {

>>   	.reg_names = imx8mq_reg_names,

>>   	.num_regs = ARRAY_SIZE(imx8mq_reg_names)

>>   };

>> +

>> +const struct hantro_variant imx8mq_vpu_g2_variant = {

>> +	.dec_offset = 0x0,

>> +	.dec_fmts = imx8m_vpu_g2_dec_fmts,

>> +	.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_g2_dec_fmts),

>> +	.codec = HANTRO_HEVC_DECODER,

>> +	.codec_ops = imx8mq_vpu_g2_codec_ops,

>> +	.init = imx8mq_vpu_hw_init,

>> +	.runtime_resume = imx8mq_runtime_resume,

>> +	.irqs = imx8mq_g2_irqs,

>> +	.num_irqs = ARRAY_SIZE(imx8mq_g2_irqs),

>> +	.clk_names = imx8mq_clk_names,

>> +	.num_clocks = ARRAY_SIZE(imx8mq_clk_names),

>> +};

>>