162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Hantro VPU codec driver
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright 2018 Google LLC.
662306a36Sopenharmony_ci *	Tomasz Figa <tfiga@chromium.org>
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Based on s5p-mfc driver by Samsung Electronics Co., Ltd.
962306a36Sopenharmony_ci * Copyright (C) 2011 Samsung Electronics Co., Ltd.
1062306a36Sopenharmony_ci */
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#ifndef HANTRO_H_
1362306a36Sopenharmony_ci#define HANTRO_H_
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/platform_device.h>
1662306a36Sopenharmony_ci#include <linux/videodev2.h>
1762306a36Sopenharmony_ci#include <linux/wait.h>
1862306a36Sopenharmony_ci#include <linux/clk.h>
1962306a36Sopenharmony_ci#include <linux/reset.h>
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#include <media/v4l2-ctrls.h>
2262306a36Sopenharmony_ci#include <media/v4l2-device.h>
2362306a36Sopenharmony_ci#include <media/v4l2-ioctl.h>
2462306a36Sopenharmony_ci#include <media/v4l2-mem2mem.h>
2562306a36Sopenharmony_ci#include <media/videobuf2-core.h>
2662306a36Sopenharmony_ci#include <media/videobuf2-dma-contig.h>
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#include "hantro_hw.h"
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_cistruct hantro_ctx;
3162306a36Sopenharmony_cistruct hantro_codec_ops;
3262306a36Sopenharmony_cistruct hantro_postproc_ops;
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#define HANTRO_JPEG_ENCODER	BIT(0)
3562306a36Sopenharmony_ci#define HANTRO_ENCODERS		0x0000ffff
3662306a36Sopenharmony_ci#define HANTRO_MPEG2_DECODER	BIT(16)
3762306a36Sopenharmony_ci#define HANTRO_VP8_DECODER	BIT(17)
3862306a36Sopenharmony_ci#define HANTRO_H264_DECODER	BIT(18)
3962306a36Sopenharmony_ci#define HANTRO_HEVC_DECODER	BIT(19)
4062306a36Sopenharmony_ci#define HANTRO_VP9_DECODER	BIT(20)
4162306a36Sopenharmony_ci#define HANTRO_AV1_DECODER	BIT(21)
4262306a36Sopenharmony_ci#define HANTRO_DECODERS		0xffff0000
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/**
4562306a36Sopenharmony_ci * struct hantro_irq - irq handler and name
4662306a36Sopenharmony_ci *
4762306a36Sopenharmony_ci * @name:			irq name for device tree lookup
4862306a36Sopenharmony_ci * @handler:			interrupt handler
4962306a36Sopenharmony_ci */
5062306a36Sopenharmony_cistruct hantro_irq {
5162306a36Sopenharmony_ci	const char *name;
5262306a36Sopenharmony_ci	irqreturn_t (*handler)(int irq, void *priv);
5362306a36Sopenharmony_ci};
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci/**
5662306a36Sopenharmony_ci * struct hantro_variant - information about VPU hardware variant
5762306a36Sopenharmony_ci *
5862306a36Sopenharmony_ci * @enc_offset:			Offset from VPU base to encoder registers.
5962306a36Sopenharmony_ci * @dec_offset:			Offset from VPU base to decoder registers.
6062306a36Sopenharmony_ci * @enc_fmts:			Encoder formats.
6162306a36Sopenharmony_ci * @num_enc_fmts:		Number of encoder formats.
6262306a36Sopenharmony_ci * @dec_fmts:			Decoder formats.
6362306a36Sopenharmony_ci * @num_dec_fmts:		Number of decoder formats.
6462306a36Sopenharmony_ci * @postproc_fmts:		Post-processor formats.
6562306a36Sopenharmony_ci * @num_postproc_fmts:		Number of post-processor formats.
6662306a36Sopenharmony_ci * @postproc_ops:		Post-processor ops.
6762306a36Sopenharmony_ci * @codec:			Supported codecs
6862306a36Sopenharmony_ci * @codec_ops:			Codec ops.
6962306a36Sopenharmony_ci * @init:			Initialize hardware, optional.
7062306a36Sopenharmony_ci * @runtime_resume:		reenable hardware after power gating, optional.
7162306a36Sopenharmony_ci * @irqs:			array of irq names and interrupt handlers
7262306a36Sopenharmony_ci * @num_irqs:			number of irqs in the array
7362306a36Sopenharmony_ci * @clk_names:			array of clock names
7462306a36Sopenharmony_ci * @num_clocks:			number of clocks in the array
7562306a36Sopenharmony_ci * @reg_names:			array of register range names
7662306a36Sopenharmony_ci * @num_regs:			number of register range names in the array
7762306a36Sopenharmony_ci * @double_buffer:		core needs double buffering
7862306a36Sopenharmony_ci * @legacy_regs:		core uses legacy register set
7962306a36Sopenharmony_ci * @late_postproc:		postproc must be set up at the end of the job
8062306a36Sopenharmony_ci */
8162306a36Sopenharmony_cistruct hantro_variant {
8262306a36Sopenharmony_ci	unsigned int enc_offset;
8362306a36Sopenharmony_ci	unsigned int dec_offset;
8462306a36Sopenharmony_ci	const struct hantro_fmt *enc_fmts;
8562306a36Sopenharmony_ci	unsigned int num_enc_fmts;
8662306a36Sopenharmony_ci	const struct hantro_fmt *dec_fmts;
8762306a36Sopenharmony_ci	unsigned int num_dec_fmts;
8862306a36Sopenharmony_ci	const struct hantro_fmt *postproc_fmts;
8962306a36Sopenharmony_ci	unsigned int num_postproc_fmts;
9062306a36Sopenharmony_ci	const struct hantro_postproc_ops *postproc_ops;
9162306a36Sopenharmony_ci	unsigned int codec;
9262306a36Sopenharmony_ci	const struct hantro_codec_ops *codec_ops;
9362306a36Sopenharmony_ci	int (*init)(struct hantro_dev *vpu);
9462306a36Sopenharmony_ci	int (*runtime_resume)(struct hantro_dev *vpu);
9562306a36Sopenharmony_ci	const struct hantro_irq *irqs;
9662306a36Sopenharmony_ci	int num_irqs;
9762306a36Sopenharmony_ci	const char * const *clk_names;
9862306a36Sopenharmony_ci	int num_clocks;
9962306a36Sopenharmony_ci	const char * const *reg_names;
10062306a36Sopenharmony_ci	int num_regs;
10162306a36Sopenharmony_ci	unsigned int double_buffer : 1;
10262306a36Sopenharmony_ci	unsigned int legacy_regs : 1;
10362306a36Sopenharmony_ci	unsigned int late_postproc : 1;
10462306a36Sopenharmony_ci};
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci/**
10762306a36Sopenharmony_ci * enum hantro_codec_mode - codec operating mode.
10862306a36Sopenharmony_ci * @HANTRO_MODE_NONE:  No operating mode. Used for RAW video formats.
10962306a36Sopenharmony_ci * @HANTRO_MODE_JPEG_ENC: JPEG encoder.
11062306a36Sopenharmony_ci * @HANTRO_MODE_H264_DEC: H264 decoder.
11162306a36Sopenharmony_ci * @HANTRO_MODE_MPEG2_DEC: MPEG-2 decoder.
11262306a36Sopenharmony_ci * @HANTRO_MODE_VP8_DEC: VP8 decoder.
11362306a36Sopenharmony_ci * @HANTRO_MODE_HEVC_DEC: HEVC decoder.
11462306a36Sopenharmony_ci * @HANTRO_MODE_VP9_DEC: VP9 decoder.
11562306a36Sopenharmony_ci * @HANTRO_MODE_AV1_DEC: AV1 decoder
11662306a36Sopenharmony_ci */
11762306a36Sopenharmony_cienum hantro_codec_mode {
11862306a36Sopenharmony_ci	HANTRO_MODE_NONE = -1,
11962306a36Sopenharmony_ci	HANTRO_MODE_JPEG_ENC,
12062306a36Sopenharmony_ci	HANTRO_MODE_H264_DEC,
12162306a36Sopenharmony_ci	HANTRO_MODE_MPEG2_DEC,
12262306a36Sopenharmony_ci	HANTRO_MODE_VP8_DEC,
12362306a36Sopenharmony_ci	HANTRO_MODE_HEVC_DEC,
12462306a36Sopenharmony_ci	HANTRO_MODE_VP9_DEC,
12562306a36Sopenharmony_ci	HANTRO_MODE_AV1_DEC,
12662306a36Sopenharmony_ci};
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci/*
12962306a36Sopenharmony_ci * struct hantro_ctrl - helper type to declare supported controls
13062306a36Sopenharmony_ci * @codec:	codec id this control belong to (HANTRO_JPEG_ENCODER, etc.)
13162306a36Sopenharmony_ci * @cfg:	control configuration
13262306a36Sopenharmony_ci */
13362306a36Sopenharmony_cistruct hantro_ctrl {
13462306a36Sopenharmony_ci	unsigned int codec;
13562306a36Sopenharmony_ci	struct v4l2_ctrl_config cfg;
13662306a36Sopenharmony_ci};
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci/*
13962306a36Sopenharmony_ci * struct hantro_func - Hantro VPU functionality
14062306a36Sopenharmony_ci *
14162306a36Sopenharmony_ci * @id:			processing functionality ID (can be
14262306a36Sopenharmony_ci *			%MEDIA_ENT_F_PROC_VIDEO_ENCODER or
14362306a36Sopenharmony_ci *			%MEDIA_ENT_F_PROC_VIDEO_DECODER)
14462306a36Sopenharmony_ci * @vdev:		&struct video_device that exposes the encoder or
14562306a36Sopenharmony_ci *			decoder functionality
14662306a36Sopenharmony_ci * @source_pad:		&struct media_pad with the source pad.
14762306a36Sopenharmony_ci * @sink:		&struct media_entity pointer with the sink entity
14862306a36Sopenharmony_ci * @sink_pad:		&struct media_pad with the sink pad.
14962306a36Sopenharmony_ci * @proc:		&struct media_entity pointer with the M2M device itself.
15062306a36Sopenharmony_ci * @proc_pads:		&struct media_pad with the @proc pads.
15162306a36Sopenharmony_ci * @intf_devnode:	&struct media_intf devnode pointer with the interface
15262306a36Sopenharmony_ci *			with controls the M2M device.
15362306a36Sopenharmony_ci *
15462306a36Sopenharmony_ci * Contains everything needed to attach the video device to the media device.
15562306a36Sopenharmony_ci */
15662306a36Sopenharmony_cistruct hantro_func {
15762306a36Sopenharmony_ci	unsigned int id;
15862306a36Sopenharmony_ci	struct video_device vdev;
15962306a36Sopenharmony_ci	struct media_pad source_pad;
16062306a36Sopenharmony_ci	struct media_entity sink;
16162306a36Sopenharmony_ci	struct media_pad sink_pad;
16262306a36Sopenharmony_ci	struct media_entity proc;
16362306a36Sopenharmony_ci	struct media_pad proc_pads[2];
16462306a36Sopenharmony_ci	struct media_intf_devnode *intf_devnode;
16562306a36Sopenharmony_ci};
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_cistatic inline struct hantro_func *
16862306a36Sopenharmony_cihantro_vdev_to_func(struct video_device *vdev)
16962306a36Sopenharmony_ci{
17062306a36Sopenharmony_ci	return container_of(vdev, struct hantro_func, vdev);
17162306a36Sopenharmony_ci}
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci/**
17462306a36Sopenharmony_ci * struct hantro_dev - driver data
17562306a36Sopenharmony_ci * @v4l2_dev:		V4L2 device to register video devices for.
17662306a36Sopenharmony_ci * @m2m_dev:		mem2mem device associated to this device.
17762306a36Sopenharmony_ci * @mdev:		media device associated to this device.
17862306a36Sopenharmony_ci * @encoder:		encoder functionality.
17962306a36Sopenharmony_ci * @decoder:		decoder functionality.
18062306a36Sopenharmony_ci * @pdev:		Pointer to VPU platform device.
18162306a36Sopenharmony_ci * @dev:		Pointer to device for convenient logging using
18262306a36Sopenharmony_ci *			dev_ macros.
18362306a36Sopenharmony_ci * @clocks:		Array of clock handles.
18462306a36Sopenharmony_ci * @resets:		Array of reset handles.
18562306a36Sopenharmony_ci * @reg_bases:		Mapped addresses of VPU registers.
18662306a36Sopenharmony_ci * @enc_base:		Mapped address of VPU encoder register for convenience.
18762306a36Sopenharmony_ci * @dec_base:		Mapped address of VPU decoder register for convenience.
18862306a36Sopenharmony_ci * @ctrl_base:		Mapped address of VPU control block.
18962306a36Sopenharmony_ci * @vpu_mutex:		Mutex to synchronize V4L2 calls.
19062306a36Sopenharmony_ci * @irqlock:		Spinlock to synchronize access to data structures
19162306a36Sopenharmony_ci *			shared with interrupt handlers.
19262306a36Sopenharmony_ci * @variant:		Hardware variant-specific parameters.
19362306a36Sopenharmony_ci * @watchdog_work:	Delayed work for hardware timeout handling.
19462306a36Sopenharmony_ci */
19562306a36Sopenharmony_cistruct hantro_dev {
19662306a36Sopenharmony_ci	struct v4l2_device v4l2_dev;
19762306a36Sopenharmony_ci	struct v4l2_m2m_dev *m2m_dev;
19862306a36Sopenharmony_ci	struct media_device mdev;
19962306a36Sopenharmony_ci	struct hantro_func *encoder;
20062306a36Sopenharmony_ci	struct hantro_func *decoder;
20162306a36Sopenharmony_ci	struct platform_device *pdev;
20262306a36Sopenharmony_ci	struct device *dev;
20362306a36Sopenharmony_ci	struct clk_bulk_data *clocks;
20462306a36Sopenharmony_ci	struct reset_control *resets;
20562306a36Sopenharmony_ci	void __iomem **reg_bases;
20662306a36Sopenharmony_ci	void __iomem *enc_base;
20762306a36Sopenharmony_ci	void __iomem *dec_base;
20862306a36Sopenharmony_ci	void __iomem *ctrl_base;
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci	struct mutex vpu_mutex;	/* video_device lock */
21162306a36Sopenharmony_ci	spinlock_t irqlock;
21262306a36Sopenharmony_ci	const struct hantro_variant *variant;
21362306a36Sopenharmony_ci	struct delayed_work watchdog_work;
21462306a36Sopenharmony_ci};
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci/**
21762306a36Sopenharmony_ci * struct hantro_ctx - Context (instance) private data.
21862306a36Sopenharmony_ci *
21962306a36Sopenharmony_ci * @dev:		VPU driver data to which the context belongs.
22062306a36Sopenharmony_ci * @fh:			V4L2 file handler.
22162306a36Sopenharmony_ci * @is_encoder:		Decoder or encoder context?
22262306a36Sopenharmony_ci *
22362306a36Sopenharmony_ci * @sequence_cap:       Sequence counter for capture queue
22462306a36Sopenharmony_ci * @sequence_out:       Sequence counter for output queue
22562306a36Sopenharmony_ci *
22662306a36Sopenharmony_ci * @vpu_src_fmt:	Descriptor of active source format.
22762306a36Sopenharmony_ci * @src_fmt:		V4L2 pixel format of active source format.
22862306a36Sopenharmony_ci * @vpu_dst_fmt:	Descriptor of active destination format.
22962306a36Sopenharmony_ci * @dst_fmt:		V4L2 pixel format of active destination format.
23062306a36Sopenharmony_ci *
23162306a36Sopenharmony_ci * @ctrl_handler:	Control handler used to register controls.
23262306a36Sopenharmony_ci * @jpeg_quality:	User-specified JPEG compression quality.
23362306a36Sopenharmony_ci * @bit_depth:		Bit depth of current frame
23462306a36Sopenharmony_ci * @need_postproc:	Set to true if the bitstream features require to
23562306a36Sopenharmony_ci *			use the post-processor.
23662306a36Sopenharmony_ci *
23762306a36Sopenharmony_ci * @codec_ops:		Set of operations related to codec mode.
23862306a36Sopenharmony_ci * @postproc:		Post-processing context.
23962306a36Sopenharmony_ci * @h264_dec:		H.264-decoding context.
24062306a36Sopenharmony_ci * @jpeg_enc:		JPEG-encoding context.
24162306a36Sopenharmony_ci * @mpeg2_dec:		MPEG-2-decoding context.
24262306a36Sopenharmony_ci * @vp8_dec:		VP8-decoding context.
24362306a36Sopenharmony_ci * @hevc_dec:		HEVC-decoding context.
24462306a36Sopenharmony_ci * @vp9_dec:		VP9-decoding context.
24562306a36Sopenharmony_ci * @av1_dec:		AV1-decoding context.
24662306a36Sopenharmony_ci */
24762306a36Sopenharmony_cistruct hantro_ctx {
24862306a36Sopenharmony_ci	struct hantro_dev *dev;
24962306a36Sopenharmony_ci	struct v4l2_fh fh;
25062306a36Sopenharmony_ci	bool is_encoder;
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	u32 sequence_cap;
25362306a36Sopenharmony_ci	u32 sequence_out;
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	const struct hantro_fmt *vpu_src_fmt;
25662306a36Sopenharmony_ci	struct v4l2_pix_format_mplane src_fmt;
25762306a36Sopenharmony_ci	const struct hantro_fmt *vpu_dst_fmt;
25862306a36Sopenharmony_ci	struct v4l2_pix_format_mplane dst_fmt;
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci	struct v4l2_ctrl_handler ctrl_handler;
26162306a36Sopenharmony_ci	int jpeg_quality;
26262306a36Sopenharmony_ci	int bit_depth;
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci	const struct hantro_codec_ops *codec_ops;
26562306a36Sopenharmony_ci	struct hantro_postproc_ctx postproc;
26662306a36Sopenharmony_ci	bool need_postproc;
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci	/* Specific for particular codec modes. */
26962306a36Sopenharmony_ci	union {
27062306a36Sopenharmony_ci		struct hantro_h264_dec_hw_ctx h264_dec;
27162306a36Sopenharmony_ci		struct hantro_mpeg2_dec_hw_ctx mpeg2_dec;
27262306a36Sopenharmony_ci		struct hantro_vp8_dec_hw_ctx vp8_dec;
27362306a36Sopenharmony_ci		struct hantro_hevc_dec_hw_ctx hevc_dec;
27462306a36Sopenharmony_ci		struct hantro_vp9_dec_hw_ctx vp9_dec;
27562306a36Sopenharmony_ci		struct hantro_av1_dec_hw_ctx av1_dec;
27662306a36Sopenharmony_ci	};
27762306a36Sopenharmony_ci};
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci/**
28062306a36Sopenharmony_ci * struct hantro_fmt - information about supported video formats.
28162306a36Sopenharmony_ci * @name:	Human readable name of the format.
28262306a36Sopenharmony_ci * @fourcc:	FourCC code of the format. See V4L2_PIX_FMT_*.
28362306a36Sopenharmony_ci * @codec_mode:	Codec mode related to this format. See
28462306a36Sopenharmony_ci *		enum hantro_codec_mode.
28562306a36Sopenharmony_ci * @header_size: Optional header size. Currently used by JPEG encoder.
28662306a36Sopenharmony_ci * @max_depth:	Maximum depth, for bitstream formats
28762306a36Sopenharmony_ci * @enc_fmt:	Format identifier for encoder registers.
28862306a36Sopenharmony_ci * @frmsize:	Supported range of frame sizes (only for bitstream formats).
28962306a36Sopenharmony_ci * @postprocessed: Indicates if this format needs the post-processor.
29062306a36Sopenharmony_ci * @match_depth: Indicates if format bit depth must match video bit depth
29162306a36Sopenharmony_ci */
29262306a36Sopenharmony_cistruct hantro_fmt {
29362306a36Sopenharmony_ci	char *name;
29462306a36Sopenharmony_ci	u32 fourcc;
29562306a36Sopenharmony_ci	enum hantro_codec_mode codec_mode;
29662306a36Sopenharmony_ci	int header_size;
29762306a36Sopenharmony_ci	int max_depth;
29862306a36Sopenharmony_ci	enum hantro_enc_fmt enc_fmt;
29962306a36Sopenharmony_ci	struct v4l2_frmsize_stepwise frmsize;
30062306a36Sopenharmony_ci	bool postprocessed;
30162306a36Sopenharmony_ci	bool match_depth;
30262306a36Sopenharmony_ci};
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_cistruct hantro_reg {
30562306a36Sopenharmony_ci	u32 base;
30662306a36Sopenharmony_ci	u32 shift;
30762306a36Sopenharmony_ci	u32 mask;
30862306a36Sopenharmony_ci};
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_cistruct hantro_postproc_regs {
31162306a36Sopenharmony_ci	struct hantro_reg pipeline_en;
31262306a36Sopenharmony_ci	struct hantro_reg max_burst;
31362306a36Sopenharmony_ci	struct hantro_reg clk_gate;
31462306a36Sopenharmony_ci	struct hantro_reg out_swap32;
31562306a36Sopenharmony_ci	struct hantro_reg out_endian;
31662306a36Sopenharmony_ci	struct hantro_reg out_luma_base;
31762306a36Sopenharmony_ci	struct hantro_reg input_width;
31862306a36Sopenharmony_ci	struct hantro_reg input_height;
31962306a36Sopenharmony_ci	struct hantro_reg output_width;
32062306a36Sopenharmony_ci	struct hantro_reg output_height;
32162306a36Sopenharmony_ci	struct hantro_reg input_fmt;
32262306a36Sopenharmony_ci	struct hantro_reg output_fmt;
32362306a36Sopenharmony_ci	struct hantro_reg orig_width;
32462306a36Sopenharmony_ci	struct hantro_reg display_width;
32562306a36Sopenharmony_ci};
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_cistruct hantro_vp9_decoded_buffer_info {
32862306a36Sopenharmony_ci	/* Info needed when the decoded frame serves as a reference frame. */
32962306a36Sopenharmony_ci	unsigned short width;
33062306a36Sopenharmony_ci	unsigned short height;
33162306a36Sopenharmony_ci	u32 bit_depth : 4;
33262306a36Sopenharmony_ci};
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_cistruct hantro_decoded_buffer {
33562306a36Sopenharmony_ci	/* Must be the first field in this struct. */
33662306a36Sopenharmony_ci	struct v4l2_m2m_buffer base;
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci	union {
33962306a36Sopenharmony_ci		struct hantro_vp9_decoded_buffer_info vp9;
34062306a36Sopenharmony_ci	};
34162306a36Sopenharmony_ci};
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci/* Logging helpers */
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci/**
34662306a36Sopenharmony_ci * DOC: hantro_debug: Module parameter to control level of debugging messages.
34762306a36Sopenharmony_ci *
34862306a36Sopenharmony_ci * Level of debugging messages can be controlled by bits of
34962306a36Sopenharmony_ci * module parameter called "debug". Meaning of particular
35062306a36Sopenharmony_ci * bits is as follows:
35162306a36Sopenharmony_ci *
35262306a36Sopenharmony_ci * bit 0 - global information: mode, size, init, release
35362306a36Sopenharmony_ci * bit 1 - each run start/result information
35462306a36Sopenharmony_ci * bit 2 - contents of small controls from userspace
35562306a36Sopenharmony_ci * bit 3 - contents of big controls from userspace
35662306a36Sopenharmony_ci * bit 4 - detail fmt, ctrl, buffer q/dq information
35762306a36Sopenharmony_ci * bit 5 - detail function enter/leave trace information
35862306a36Sopenharmony_ci * bit 6 - register write/read information
35962306a36Sopenharmony_ci */
36062306a36Sopenharmony_ciextern int hantro_debug;
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci#define vpu_debug(level, fmt, args...)				\
36362306a36Sopenharmony_ci	do {							\
36462306a36Sopenharmony_ci		if (hantro_debug & BIT(level))		\
36562306a36Sopenharmony_ci			pr_info("%s:%d: " fmt,	                \
36662306a36Sopenharmony_ci				 __func__, __LINE__, ##args);	\
36762306a36Sopenharmony_ci	} while (0)
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci#define vpu_err(fmt, args...)					\
37062306a36Sopenharmony_ci	pr_err("%s:%d: " fmt, __func__, __LINE__, ##args)
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci/* Structure access helpers. */
37362306a36Sopenharmony_cistatic __always_inline struct hantro_ctx *fh_to_ctx(struct v4l2_fh *fh)
37462306a36Sopenharmony_ci{
37562306a36Sopenharmony_ci	return container_of(fh, struct hantro_ctx, fh);
37662306a36Sopenharmony_ci}
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci/* Register accessors. */
37962306a36Sopenharmony_cistatic __always_inline void vepu_write_relaxed(struct hantro_dev *vpu,
38062306a36Sopenharmony_ci					       u32 val, u32 reg)
38162306a36Sopenharmony_ci{
38262306a36Sopenharmony_ci	vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val);
38362306a36Sopenharmony_ci	writel_relaxed(val, vpu->enc_base + reg);
38462306a36Sopenharmony_ci}
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_cistatic __always_inline void vepu_write(struct hantro_dev *vpu, u32 val, u32 reg)
38762306a36Sopenharmony_ci{
38862306a36Sopenharmony_ci	vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val);
38962306a36Sopenharmony_ci	writel(val, vpu->enc_base + reg);
39062306a36Sopenharmony_ci}
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_cistatic __always_inline u32 vepu_read(struct hantro_dev *vpu, u32 reg)
39362306a36Sopenharmony_ci{
39462306a36Sopenharmony_ci	u32 val = readl(vpu->enc_base + reg);
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci	vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val);
39762306a36Sopenharmony_ci	return val;
39862306a36Sopenharmony_ci}
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_cistatic __always_inline void vdpu_write_relaxed(struct hantro_dev *vpu,
40162306a36Sopenharmony_ci					       u32 val, u32 reg)
40262306a36Sopenharmony_ci{
40362306a36Sopenharmony_ci	vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val);
40462306a36Sopenharmony_ci	writel_relaxed(val, vpu->dec_base + reg);
40562306a36Sopenharmony_ci}
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_cistatic __always_inline void vdpu_write(struct hantro_dev *vpu, u32 val, u32 reg)
40862306a36Sopenharmony_ci{
40962306a36Sopenharmony_ci	vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val);
41062306a36Sopenharmony_ci	writel(val, vpu->dec_base + reg);
41162306a36Sopenharmony_ci}
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_cistatic __always_inline void hantro_write_addr(struct hantro_dev *vpu,
41462306a36Sopenharmony_ci					      unsigned long offset,
41562306a36Sopenharmony_ci					      dma_addr_t addr)
41662306a36Sopenharmony_ci{
41762306a36Sopenharmony_ci	vdpu_write(vpu, addr & 0xffffffff, offset);
41862306a36Sopenharmony_ci}
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_cistatic __always_inline u32 vdpu_read(struct hantro_dev *vpu, u32 reg)
42162306a36Sopenharmony_ci{
42262306a36Sopenharmony_ci	u32 val = readl(vpu->dec_base + reg);
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci	vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val);
42562306a36Sopenharmony_ci	return val;
42662306a36Sopenharmony_ci}
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_cistatic __always_inline u32 vdpu_read_mask(struct hantro_dev *vpu,
42962306a36Sopenharmony_ci					  const struct hantro_reg *reg,
43062306a36Sopenharmony_ci					  u32 val)
43162306a36Sopenharmony_ci{
43262306a36Sopenharmony_ci	u32 v;
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci	v = vdpu_read(vpu, reg->base);
43562306a36Sopenharmony_ci	v &= ~(reg->mask << reg->shift);
43662306a36Sopenharmony_ci	v |= ((val & reg->mask) << reg->shift);
43762306a36Sopenharmony_ci	return v;
43862306a36Sopenharmony_ci}
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_cistatic __always_inline void hantro_reg_write(struct hantro_dev *vpu,
44162306a36Sopenharmony_ci					     const struct hantro_reg *reg,
44262306a36Sopenharmony_ci					     u32 val)
44362306a36Sopenharmony_ci{
44462306a36Sopenharmony_ci	vdpu_write(vpu, vdpu_read_mask(vpu, reg, val), reg->base);
44562306a36Sopenharmony_ci}
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_cistatic __always_inline void hantro_reg_write_relaxed(struct hantro_dev *vpu,
44862306a36Sopenharmony_ci						     const struct hantro_reg *reg,
44962306a36Sopenharmony_ci						     u32 val)
45062306a36Sopenharmony_ci{
45162306a36Sopenharmony_ci	vdpu_write_relaxed(vpu, vdpu_read_mask(vpu, reg, val), reg->base);
45262306a36Sopenharmony_ci}
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_civoid *hantro_get_ctrl(struct hantro_ctx *ctx, u32 id);
45562306a36Sopenharmony_cidma_addr_t hantro_get_ref(struct hantro_ctx *ctx, u64 ts);
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_cistatic inline struct vb2_v4l2_buffer *
45862306a36Sopenharmony_cihantro_get_src_buf(struct hantro_ctx *ctx)
45962306a36Sopenharmony_ci{
46062306a36Sopenharmony_ci	return v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
46162306a36Sopenharmony_ci}
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_cistatic inline struct vb2_v4l2_buffer *
46462306a36Sopenharmony_cihantro_get_dst_buf(struct hantro_ctx *ctx)
46562306a36Sopenharmony_ci{
46662306a36Sopenharmony_ci	return v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
46762306a36Sopenharmony_ci}
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_cibool hantro_needs_postproc(const struct hantro_ctx *ctx,
47062306a36Sopenharmony_ci			   const struct hantro_fmt *fmt);
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_cistatic inline dma_addr_t
47362306a36Sopenharmony_cihantro_get_dec_buf_addr(struct hantro_ctx *ctx, struct vb2_buffer *vb)
47462306a36Sopenharmony_ci{
47562306a36Sopenharmony_ci	if (hantro_needs_postproc(ctx, ctx->vpu_dst_fmt))
47662306a36Sopenharmony_ci		return ctx->postproc.dec_q[vb->index].dma;
47762306a36Sopenharmony_ci	return vb2_dma_contig_plane_dma_addr(vb, 0);
47862306a36Sopenharmony_ci}
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_cistatic inline struct hantro_decoded_buffer *
48162306a36Sopenharmony_civb2_to_hantro_decoded_buf(struct vb2_buffer *buf)
48262306a36Sopenharmony_ci{
48362306a36Sopenharmony_ci	return container_of(buf, struct hantro_decoded_buffer, base.vb.vb2_buf);
48462306a36Sopenharmony_ci}
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_civoid hantro_postproc_disable(struct hantro_ctx *ctx);
48762306a36Sopenharmony_civoid hantro_postproc_enable(struct hantro_ctx *ctx);
48862306a36Sopenharmony_civoid hantro_postproc_free(struct hantro_ctx *ctx);
48962306a36Sopenharmony_ciint hantro_postproc_alloc(struct hantro_ctx *ctx);
49062306a36Sopenharmony_ciint hanto_postproc_enum_framesizes(struct hantro_ctx *ctx,
49162306a36Sopenharmony_ci				   struct v4l2_frmsizeenum *fsize);
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci#endif /* HANTRO_H_ */
494