162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * i.MX8QXP/i.MX8QM JPEG encoder/decoder v4l2 driver
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright 2018-2019 NXP
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <media/v4l2-ctrls.h>
962306a36Sopenharmony_ci#include <media/v4l2-device.h>
1062306a36Sopenharmony_ci#include <media/v4l2-fh.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#ifndef _MXC_JPEG_CORE_H
1362306a36Sopenharmony_ci#define _MXC_JPEG_CORE_H
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#define MXC_JPEG_NAME			"mxc-jpeg"
1662306a36Sopenharmony_ci#define MXC_JPEG_FMT_TYPE_ENC		0
1762306a36Sopenharmony_ci#define MXC_JPEG_FMT_TYPE_RAW		1
1862306a36Sopenharmony_ci#define MXC_JPEG_DEFAULT_WIDTH		1280
1962306a36Sopenharmony_ci#define MXC_JPEG_DEFAULT_HEIGHT		720
2062306a36Sopenharmony_ci#define MXC_JPEG_DEFAULT_PFMT		V4L2_PIX_FMT_BGR24
2162306a36Sopenharmony_ci#define MXC_JPEG_MIN_WIDTH		64
2262306a36Sopenharmony_ci#define MXC_JPEG_MIN_HEIGHT		64
2362306a36Sopenharmony_ci#define MXC_JPEG_MAX_WIDTH		0x2000
2462306a36Sopenharmony_ci#define MXC_JPEG_MAX_HEIGHT		0x2000
2562306a36Sopenharmony_ci#define MXC_JPEG_MAX_CFG_STREAM		0x1000
2662306a36Sopenharmony_ci#define MXC_JPEG_H_ALIGN		3
2762306a36Sopenharmony_ci#define MXC_JPEG_W_ALIGN		3
2862306a36Sopenharmony_ci#define MXC_JPEG_MAX_SIZEIMAGE		0xFFFFFC00
2962306a36Sopenharmony_ci#define MXC_JPEG_MAX_PLANES		2
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_cienum mxc_jpeg_enc_state {
3262306a36Sopenharmony_ci	MXC_JPEG_ENCODING	= 0, /* jpeg encode phase */
3362306a36Sopenharmony_ci	MXC_JPEG_ENC_CONF	= 1, /* jpeg encoder config phase */
3462306a36Sopenharmony_ci};
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_cienum mxc_jpeg_mode {
3762306a36Sopenharmony_ci	MXC_JPEG_DECODE	= 0, /* jpeg decode mode */
3862306a36Sopenharmony_ci	MXC_JPEG_ENCODE	= 1, /* jpeg encode mode */
3962306a36Sopenharmony_ci};
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci/**
4262306a36Sopenharmony_ci * struct mxc_jpeg_fmt - driver's internal color format data
4362306a36Sopenharmony_ci * @name:	format description
4462306a36Sopenharmony_ci * @fourcc:	fourcc code, 0 if not applicable
4562306a36Sopenharmony_ci * @subsampling: subsampling of jpeg components
4662306a36Sopenharmony_ci * @nc:		number of color components
4762306a36Sopenharmony_ci * @depth:	number of bits per pixel
4862306a36Sopenharmony_ci * @mem_planes:	number of memory planes (1 for packed formats)
4962306a36Sopenharmony_ci * @comp_planes:number of component planes, which includes the alpha plane (1 to 4).
5062306a36Sopenharmony_ci * @h_align:	horizontal alignment order (align to 2^h_align)
5162306a36Sopenharmony_ci * @v_align:	vertical alignment order (align to 2^v_align)
5262306a36Sopenharmony_ci * @flags:	flags describing format applicability
5362306a36Sopenharmony_ci * @precision:  jpeg sample precision
5462306a36Sopenharmony_ci * @is_rgb:     is an RGB pixel format
5562306a36Sopenharmony_ci */
5662306a36Sopenharmony_cistruct mxc_jpeg_fmt {
5762306a36Sopenharmony_ci	const char				*name;
5862306a36Sopenharmony_ci	u32					fourcc;
5962306a36Sopenharmony_ci	enum v4l2_jpeg_chroma_subsampling	subsampling;
6062306a36Sopenharmony_ci	int					nc;
6162306a36Sopenharmony_ci	int					depth;
6262306a36Sopenharmony_ci	int					mem_planes;
6362306a36Sopenharmony_ci	int					comp_planes;
6462306a36Sopenharmony_ci	int					h_align;
6562306a36Sopenharmony_ci	int					v_align;
6662306a36Sopenharmony_ci	u32					flags;
6762306a36Sopenharmony_ci	u8					precision;
6862306a36Sopenharmony_ci	u8					is_rgb;
6962306a36Sopenharmony_ci};
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cistruct mxc_jpeg_desc {
7262306a36Sopenharmony_ci	u32 next_descpt_ptr;
7362306a36Sopenharmony_ci	u32 buf_base0;
7462306a36Sopenharmony_ci	u32 buf_base1;
7562306a36Sopenharmony_ci	u32 line_pitch;
7662306a36Sopenharmony_ci	u32 stm_bufbase;
7762306a36Sopenharmony_ci	u32 stm_bufsize;
7862306a36Sopenharmony_ci	u32 imgsize;
7962306a36Sopenharmony_ci	u32 stm_ctrl;
8062306a36Sopenharmony_ci} __packed;
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistruct mxc_jpeg_q_data {
8362306a36Sopenharmony_ci	const struct mxc_jpeg_fmt	*fmt;
8462306a36Sopenharmony_ci	u32				sizeimage[MXC_JPEG_MAX_PLANES];
8562306a36Sopenharmony_ci	u32				bytesperline[MXC_JPEG_MAX_PLANES];
8662306a36Sopenharmony_ci	int				w;
8762306a36Sopenharmony_ci	int				w_adjusted;
8862306a36Sopenharmony_ci	int				h;
8962306a36Sopenharmony_ci	int				h_adjusted;
9062306a36Sopenharmony_ci	unsigned int			sequence;
9162306a36Sopenharmony_ci	struct v4l2_rect		crop;
9262306a36Sopenharmony_ci};
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_cistruct mxc_jpeg_ctx {
9562306a36Sopenharmony_ci	struct mxc_jpeg_dev		*mxc_jpeg;
9662306a36Sopenharmony_ci	struct mxc_jpeg_q_data		out_q;
9762306a36Sopenharmony_ci	struct mxc_jpeg_q_data		cap_q;
9862306a36Sopenharmony_ci	struct v4l2_fh			fh;
9962306a36Sopenharmony_ci	enum mxc_jpeg_enc_state		enc_state;
10062306a36Sopenharmony_ci	int				slot;
10162306a36Sopenharmony_ci	unsigned int			source_change;
10262306a36Sopenharmony_ci	bool				need_initial_source_change_evt;
10362306a36Sopenharmony_ci	bool				header_parsed;
10462306a36Sopenharmony_ci	struct v4l2_ctrl_handler	ctrl_handler;
10562306a36Sopenharmony_ci	u8				jpeg_quality;
10662306a36Sopenharmony_ci	struct delayed_work		task_timer;
10762306a36Sopenharmony_ci};
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_cistruct mxc_jpeg_slot_data {
11062306a36Sopenharmony_ci	int slot;
11162306a36Sopenharmony_ci	bool used;
11262306a36Sopenharmony_ci	struct mxc_jpeg_desc *desc; // enc/dec descriptor
11362306a36Sopenharmony_ci	struct mxc_jpeg_desc *cfg_desc; // configuration descriptor
11462306a36Sopenharmony_ci	void *cfg_stream_vaddr; // configuration bitstream virtual address
11562306a36Sopenharmony_ci	unsigned int cfg_stream_size;
11662306a36Sopenharmony_ci	dma_addr_t desc_handle;
11762306a36Sopenharmony_ci	dma_addr_t cfg_desc_handle; // configuration descriptor dma address
11862306a36Sopenharmony_ci	dma_addr_t cfg_stream_handle; // configuration bitstream dma address
11962306a36Sopenharmony_ci};
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_cistruct mxc_jpeg_dev {
12262306a36Sopenharmony_ci	spinlock_t			hw_lock; /* hardware access lock */
12362306a36Sopenharmony_ci	unsigned int			mode;
12462306a36Sopenharmony_ci	struct mutex			lock; /* v4l2 ioctls serialization */
12562306a36Sopenharmony_ci	struct clk_bulk_data		*clks;
12662306a36Sopenharmony_ci	int				num_clks;
12762306a36Sopenharmony_ci	struct platform_device		*pdev;
12862306a36Sopenharmony_ci	struct device			*dev;
12962306a36Sopenharmony_ci	void __iomem			*base_reg;
13062306a36Sopenharmony_ci	struct v4l2_device		v4l2_dev;
13162306a36Sopenharmony_ci	struct v4l2_m2m_dev		*m2m_dev;
13262306a36Sopenharmony_ci	struct video_device		*dec_vdev;
13362306a36Sopenharmony_ci	struct mxc_jpeg_slot_data	slot_data;
13462306a36Sopenharmony_ci	int				num_domains;
13562306a36Sopenharmony_ci	struct device			**pd_dev;
13662306a36Sopenharmony_ci	struct device_link		**pd_link;
13762306a36Sopenharmony_ci};
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci/**
14062306a36Sopenharmony_ci * struct mxc_jpeg_sof_comp - JPEG Start Of Frame component fields
14162306a36Sopenharmony_ci * @id:				component id
14262306a36Sopenharmony_ci * @v:				vertical sampling
14362306a36Sopenharmony_ci * @h:				horizontal sampling
14462306a36Sopenharmony_ci * @quantization_table_no:	id of quantization table
14562306a36Sopenharmony_ci */
14662306a36Sopenharmony_cistruct mxc_jpeg_sof_comp {
14762306a36Sopenharmony_ci	u8 id;
14862306a36Sopenharmony_ci	u8 v :4;
14962306a36Sopenharmony_ci	u8 h :4;
15062306a36Sopenharmony_ci	u8 quantization_table_no;
15162306a36Sopenharmony_ci} __packed;
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci#define MXC_JPEG_MAX_COMPONENTS 4
15462306a36Sopenharmony_ci/**
15562306a36Sopenharmony_ci * struct mxc_jpeg_sof - JPEG Start Of Frame marker fields
15662306a36Sopenharmony_ci * @length:		Start of Frame length
15762306a36Sopenharmony_ci * @precision:		precision (bits per pixel per color component)
15862306a36Sopenharmony_ci * @height:		image height
15962306a36Sopenharmony_ci * @width:		image width
16062306a36Sopenharmony_ci * @components_no:	number of color components
16162306a36Sopenharmony_ci * @comp:		component fields for each color component
16262306a36Sopenharmony_ci */
16362306a36Sopenharmony_cistruct mxc_jpeg_sof {
16462306a36Sopenharmony_ci	u16 length;
16562306a36Sopenharmony_ci	u8 precision;
16662306a36Sopenharmony_ci	u16 height, width;
16762306a36Sopenharmony_ci	u8 components_no;
16862306a36Sopenharmony_ci	struct mxc_jpeg_sof_comp comp[MXC_JPEG_MAX_COMPONENTS];
16962306a36Sopenharmony_ci} __packed;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci/**
17262306a36Sopenharmony_ci * struct mxc_jpeg_sos_comp - JPEG Start Of Scan component fields
17362306a36Sopenharmony_ci * @id:			component id
17462306a36Sopenharmony_ci * @huffman_table_no:	id of the Huffman table
17562306a36Sopenharmony_ci */
17662306a36Sopenharmony_cistruct mxc_jpeg_sos_comp {
17762306a36Sopenharmony_ci	u8 id; /*component id*/
17862306a36Sopenharmony_ci	u8 huffman_table_no;
17962306a36Sopenharmony_ci} __packed;
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci/**
18262306a36Sopenharmony_ci * struct mxc_jpeg_sos - JPEG Start Of Scan marker fields
18362306a36Sopenharmony_ci * @length:		Start of Frame length
18462306a36Sopenharmony_ci * @components_no:	number of color components
18562306a36Sopenharmony_ci * @comp:		SOS component fields for each color component
18662306a36Sopenharmony_ci * @ignorable_bytes:	ignorable bytes
18762306a36Sopenharmony_ci */
18862306a36Sopenharmony_cistruct mxc_jpeg_sos {
18962306a36Sopenharmony_ci	u16 length;
19062306a36Sopenharmony_ci	u8 components_no;
19162306a36Sopenharmony_ci	struct mxc_jpeg_sos_comp comp[MXC_JPEG_MAX_COMPONENTS];
19262306a36Sopenharmony_ci	u8 ignorable_bytes[3];
19362306a36Sopenharmony_ci} __packed;
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci#endif
196