1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * V4L2 Capture ISI subdev for i.MX8QXP/QM platform
4 *
5 * ISI is a Image Sensor Interface of i.MX8QXP/QM platform, which
6 * used to process image from camera sensor to memory or DC
7 * Copyright 2019-2020 NXP
8 */
9
10#ifndef __MXC_ISI_CORE_H__
11#define __MXC_ISI_CORE_H__
12
13#include <linux/list.h>
14#include <linux/mutex.h>
15#include <linux/spinlock.h>
16#include <linux/types.h>
17#include <linux/videodev2.h>
18
19#include <media/media-device.h>
20#include <media/media-entity.h>
21#include <media/v4l2-async.h>
22#include <media/v4l2-ctrls.h>
23#include <media/v4l2-dev.h>
24#include <media/v4l2-device.h>
25#include <media/v4l2-subdev.h>
26#include <media/videobuf2-core.h>
27#include <media/videobuf2-v4l2.h>
28
29struct clk_bulk_data;
30struct dentry;
31struct device;
32struct media_intf_devnode;
33struct regmap;
34struct v4l2_m2m_dev;
35
36/* Pipeline pads */
37#define MXC_ISI_PIPE_PAD_SINK		0
38#define MXC_ISI_PIPE_PAD_SOURCE		1
39#define MXC_ISI_PIPE_PADS_NUM		2
40
41#define MXC_ISI_MIN_WIDTH		1U
42#define MXC_ISI_MIN_HEIGHT		1U
43#define MXC_ISI_MAX_WIDTH_UNCHAINED	2048U
44#define MXC_ISI_MAX_WIDTH_CHAINED	4096U
45#define MXC_ISI_MAX_HEIGHT		8191U
46
47#define MXC_ISI_DEF_WIDTH		1920U
48#define MXC_ISI_DEF_HEIGHT		1080U
49#define MXC_ISI_DEF_MBUS_CODE_SINK	MEDIA_BUS_FMT_UYVY8_1X16
50#define MXC_ISI_DEF_MBUS_CODE_SOURCE	MEDIA_BUS_FMT_YUV8_1X24
51#define MXC_ISI_DEF_PIXEL_FORMAT	V4L2_PIX_FMT_YUYV
52#define MXC_ISI_DEF_COLOR_SPACE		V4L2_COLORSPACE_SRGB
53#define MXC_ISI_DEF_YCBCR_ENC		V4L2_YCBCR_ENC_601
54#define MXC_ISI_DEF_QUANTIZATION	V4L2_QUANTIZATION_LIM_RANGE
55#define MXC_ISI_DEF_XFER_FUNC		V4L2_XFER_FUNC_SRGB
56
57#define MXC_ISI_DRIVER_NAME		"mxc-isi"
58#define MXC_ISI_CAPTURE			"mxc-isi-cap"
59#define MXC_ISI_M2M			"mxc-isi-m2m"
60#define MXC_MAX_PLANES			3
61
62struct mxc_isi_dev;
63struct mxc_isi_m2m_ctx;
64
65enum mxc_isi_buf_id {
66	MXC_ISI_BUF1 = 0x0,
67	MXC_ISI_BUF2,
68};
69
70enum mxc_isi_encoding {
71	MXC_ISI_ENC_RAW,
72	MXC_ISI_ENC_RGB,
73	MXC_ISI_ENC_YUV,
74};
75
76enum mxc_isi_input_id {
77	/* Inputs from the crossbar switch range from 0 to 15 */
78	MXC_ISI_INPUT_MEM = 16,
79};
80
81enum mxc_isi_video_type {
82	MXC_ISI_VIDEO_CAP = BIT(0),
83	MXC_ISI_VIDEO_M2M_OUT = BIT(1),
84	MXC_ISI_VIDEO_M2M_CAP = BIT(2),
85};
86
87struct mxc_isi_format_info {
88	u32	mbus_code;
89	u32	fourcc;
90	enum mxc_isi_video_type type;
91	u32	isi_in_format;
92	u32	isi_out_format;
93	u8	mem_planes;
94	u8	color_planes;
95	u8	depth[MXC_MAX_PLANES];
96	u8	hsub;
97	u8	vsub;
98	enum mxc_isi_encoding encoding;
99};
100
101struct mxc_isi_bus_format_info {
102	u32	mbus_code;
103	u32	output;
104	u32	pads;
105	enum mxc_isi_encoding encoding;
106};
107
108struct mxc_isi_buffer {
109	struct vb2_v4l2_buffer  v4l2_buf;
110	struct list_head	list;
111	dma_addr_t		dma_addrs[3];
112	enum mxc_isi_buf_id	id;
113	bool discard;
114};
115
116struct mxc_isi_reg {
117	u32 offset;
118	u32 mask;
119};
120
121struct mxc_isi_ier_reg {
122	/* Overflow Y/U/V trigger enable*/
123	struct mxc_isi_reg oflw_y_buf_en;
124	struct mxc_isi_reg oflw_u_buf_en;
125	struct mxc_isi_reg oflw_v_buf_en;
126
127	/* Excess overflow Y/U/V trigger enable*/
128	struct mxc_isi_reg excs_oflw_y_buf_en;
129	struct mxc_isi_reg excs_oflw_u_buf_en;
130	struct mxc_isi_reg excs_oflw_v_buf_en;
131
132	/* Panic Y/U/V trigger enable*/
133	struct mxc_isi_reg panic_y_buf_en;
134	struct mxc_isi_reg panic_v_buf_en;
135	struct mxc_isi_reg panic_u_buf_en;
136};
137
138struct mxc_isi_panic_thd {
139	u32 mask;
140	u32 offset;
141	u32 threshold;
142};
143
144struct mxc_isi_set_thd {
145	struct mxc_isi_panic_thd panic_set_thd_y;
146	struct mxc_isi_panic_thd panic_set_thd_u;
147	struct mxc_isi_panic_thd panic_set_thd_v;
148};
149
150struct mxc_gasket_ops {
151	void (*enable)(struct mxc_isi_dev *isi,
152		       const struct v4l2_mbus_frame_desc *fd,
153		       const struct v4l2_mbus_framefmt *fmt,
154		       const unsigned int port);
155	void (*disable)(struct mxc_isi_dev *isi, const unsigned int port);
156};
157
158enum model {
159	MXC_ISI_IMX8MN,
160	MXC_ISI_IMX8MP,
161	MXC_ISI_IMX93,
162};
163
164struct mxc_isi_plat_data {
165	enum model model;
166	unsigned int num_ports;
167	unsigned int num_channels;
168	unsigned int reg_offset;
169	const struct mxc_isi_ier_reg  *ier_reg;
170	const struct mxc_isi_set_thd *set_thd;
171	const struct mxc_gasket_ops *gasket_ops;
172	const struct clk_bulk_data *clks;
173	unsigned int num_clks;
174	bool buf_active_reverse;
175	bool has_36bit_dma;
176};
177
178struct mxc_isi_dma_buffer {
179	size_t				size;
180	void				*addr;
181	dma_addr_t			dma;
182};
183
184struct mxc_isi_input {
185	unsigned int			enable_count;
186};
187
188struct mxc_isi_crossbar {
189	struct mxc_isi_dev		*isi;
190
191	unsigned int			num_sinks;
192	unsigned int			num_sources;
193	struct mxc_isi_input		*inputs;
194
195	struct v4l2_subdev		sd;
196	struct media_pad		*pads;
197};
198
199struct mxc_isi_video {
200	struct mxc_isi_pipe		*pipe;
201
202	struct video_device		vdev;
203	struct media_pad		pad;
204
205	/* Protects is_streaming, and the vdev and vb2_q operations */
206	struct mutex			lock;
207	bool				is_streaming;
208
209	struct v4l2_pix_format_mplane	pix;
210	const struct mxc_isi_format_info *fmtinfo;
211
212	struct {
213		struct v4l2_ctrl_handler handler;
214		unsigned int		alpha;
215		bool			hflip;
216		bool			vflip;
217	} ctrls;
218
219	struct vb2_queue		vb2_q;
220	struct mxc_isi_buffer		buf_discard[3];
221	struct list_head		out_pending;
222	struct list_head		out_active;
223	struct list_head		out_discard;
224	u32				frame_count;
225	/* Protects out_pending, out_active, out_discard and frame_count */
226	spinlock_t			buf_lock;
227
228	struct mxc_isi_dma_buffer	discard_buffer[MXC_MAX_PLANES];
229};
230
231typedef void(*mxc_isi_pipe_irq_t)(struct mxc_isi_pipe *, u32);
232
233struct mxc_isi_pipe {
234	struct mxc_isi_dev		*isi;
235	u32				id;
236	void __iomem			*regs;
237
238	struct media_pipeline		pipe;
239
240	struct v4l2_subdev		sd;
241	struct media_pad		pads[MXC_ISI_PIPE_PADS_NUM];
242
243	struct mxc_isi_video		video;
244
245	/*
246	 * Protects use_count, irq_handler, res_available, res_acquired,
247	 * chained_res, and the CHNL_CTRL register.
248	 */
249	struct mutex			lock;
250	unsigned int			use_count;
251	mxc_isi_pipe_irq_t		irq_handler;
252
253#define MXC_ISI_CHANNEL_RES_LINE_BUF	BIT(0)
254#define MXC_ISI_CHANNEL_RES_OUTPUT_BUF	BIT(1)
255	u8				available_res;
256	u8				acquired_res;
257	u8				chained_res;
258	bool				chained;
259};
260
261struct mxc_isi_m2m {
262	struct mxc_isi_dev		*isi;
263	struct mxc_isi_pipe		*pipe;
264
265	struct media_pad		pad;
266	struct video_device		vdev;
267	struct media_intf_devnode	*intf;
268	struct v4l2_m2m_dev		*m2m_dev;
269
270	/* Protects last_ctx, usage_count and chained_count */
271	struct mutex			lock;
272
273	struct mxc_isi_m2m_ctx		*last_ctx;
274	int				usage_count;
275	int				chained_count;
276};
277
278struct mxc_isi_dev {
279	struct device			*dev;
280
281	const struct mxc_isi_plat_data	*pdata;
282
283	void __iomem			*regs;
284	struct clk_bulk_data		*clks;
285	struct regmap			*gasket;
286
287	struct mxc_isi_crossbar		crossbar;
288	struct mxc_isi_pipe		*pipes;
289	struct mxc_isi_m2m		m2m;
290
291	struct media_device		media_dev;
292	struct v4l2_device		v4l2_dev;
293	struct v4l2_async_notifier	notifier;
294
295	struct dentry			*debugfs_root;
296};
297
298extern const struct mxc_gasket_ops mxc_imx8_gasket_ops;
299extern const struct mxc_gasket_ops mxc_imx93_gasket_ops;
300
301int mxc_isi_crossbar_init(struct mxc_isi_dev *isi);
302void mxc_isi_crossbar_cleanup(struct mxc_isi_crossbar *xbar);
303int mxc_isi_crossbar_register(struct mxc_isi_crossbar *xbar);
304void mxc_isi_crossbar_unregister(struct mxc_isi_crossbar *xbar);
305
306const struct mxc_isi_bus_format_info *
307mxc_isi_bus_format_by_code(u32 code, unsigned int pad);
308const struct mxc_isi_bus_format_info *
309mxc_isi_bus_format_by_index(unsigned int index, unsigned int pad);
310const struct mxc_isi_format_info *
311mxc_isi_format_by_fourcc(u32 fourcc, enum mxc_isi_video_type type);
312const struct mxc_isi_format_info *
313mxc_isi_format_enum(unsigned int index, enum mxc_isi_video_type type);
314const struct mxc_isi_format_info *
315mxc_isi_format_try(struct mxc_isi_pipe *pipe, struct v4l2_pix_format_mplane *pix,
316		   enum mxc_isi_video_type type);
317
318int mxc_isi_pipe_init(struct mxc_isi_dev *isi, unsigned int id);
319void mxc_isi_pipe_cleanup(struct mxc_isi_pipe *pipe);
320int mxc_isi_pipe_acquire(struct mxc_isi_pipe *pipe,
321			 mxc_isi_pipe_irq_t irq_handler);
322void mxc_isi_pipe_release(struct mxc_isi_pipe *pipe);
323int mxc_isi_pipe_enable(struct mxc_isi_pipe *pipe);
324void mxc_isi_pipe_disable(struct mxc_isi_pipe *pipe);
325
326int mxc_isi_video_register(struct mxc_isi_pipe *pipe,
327			   struct v4l2_device *v4l2_dev);
328void mxc_isi_video_unregister(struct mxc_isi_pipe *pipe);
329void mxc_isi_video_suspend(struct mxc_isi_pipe *pipe);
330int mxc_isi_video_resume(struct mxc_isi_pipe *pipe);
331int mxc_isi_video_queue_setup(const struct v4l2_pix_format_mplane *format,
332			      const struct mxc_isi_format_info *info,
333			      unsigned int *num_buffers,
334			      unsigned int *num_planes, unsigned int sizes[]);
335void mxc_isi_video_buffer_init(struct vb2_buffer *vb2, dma_addr_t dma_addrs[3],
336			       const struct mxc_isi_format_info *info,
337			       const struct v4l2_pix_format_mplane *pix);
338int mxc_isi_video_buffer_prepare(struct mxc_isi_dev *isi, struct vb2_buffer *vb2,
339				 const struct mxc_isi_format_info *info,
340				 const struct v4l2_pix_format_mplane *pix);
341
342#ifdef CONFIG_VIDEO_IMX8_ISI_M2M
343int mxc_isi_m2m_register(struct mxc_isi_dev *isi, struct v4l2_device *v4l2_dev);
344int mxc_isi_m2m_unregister(struct mxc_isi_dev *isi);
345#else
346static inline int mxc_isi_m2m_register(struct mxc_isi_dev *isi,
347				       struct v4l2_device *v4l2_dev)
348{
349	return 0;
350}
351static inline int mxc_isi_m2m_unregister(struct mxc_isi_dev *isi)
352{
353	return 0;
354}
355#endif
356
357int mxc_isi_channel_acquire(struct mxc_isi_pipe *pipe,
358			    mxc_isi_pipe_irq_t irq_handler, bool bypass);
359void mxc_isi_channel_release(struct mxc_isi_pipe *pipe);
360void mxc_isi_channel_get(struct mxc_isi_pipe *pipe);
361void mxc_isi_channel_put(struct mxc_isi_pipe *pipe);
362void mxc_isi_channel_enable(struct mxc_isi_pipe *pipe);
363void mxc_isi_channel_disable(struct mxc_isi_pipe *pipe);
364int mxc_isi_channel_chain(struct mxc_isi_pipe *pipe, bool bypass);
365void mxc_isi_channel_unchain(struct mxc_isi_pipe *pipe);
366
367void mxc_isi_channel_config(struct mxc_isi_pipe *pipe,
368			    enum mxc_isi_input_id input,
369			    const struct v4l2_area *in_size,
370			    const struct v4l2_area *scale,
371			    const struct v4l2_rect *crop,
372			    enum mxc_isi_encoding in_encoding,
373			    enum mxc_isi_encoding out_encoding);
374
375void mxc_isi_channel_set_input_format(struct mxc_isi_pipe *pipe,
376				      const struct mxc_isi_format_info *info,
377				      const struct v4l2_pix_format_mplane *format);
378void mxc_isi_channel_set_output_format(struct mxc_isi_pipe *pipe,
379				       const struct mxc_isi_format_info *info,
380				       struct v4l2_pix_format_mplane *format);
381void mxc_isi_channel_m2m_start(struct mxc_isi_pipe *pipe);
382
383void mxc_isi_channel_set_alpha(struct mxc_isi_pipe *pipe, u8 alpha);
384void mxc_isi_channel_set_flip(struct mxc_isi_pipe *pipe, bool hflip, bool vflip);
385
386void mxc_isi_channel_set_inbuf(struct mxc_isi_pipe *pipe, dma_addr_t dma_addr);
387void mxc_isi_channel_set_outbuf(struct mxc_isi_pipe *pipe,
388				const dma_addr_t dma_addrs[3],
389				enum mxc_isi_buf_id buf_id);
390
391u32 mxc_isi_channel_irq_status(struct mxc_isi_pipe *pipe, bool clear);
392void mxc_isi_channel_irq_clear(struct mxc_isi_pipe *pipe);
393
394#if IS_ENABLED(CONFIG_DEBUG_FS)
395void mxc_isi_debug_init(struct mxc_isi_dev *isi);
396void mxc_isi_debug_cleanup(struct mxc_isi_dev *isi);
397#else
398static inline void mxc_isi_debug_init(struct mxc_isi_dev *isi)
399{
400}
401static inline void mxc_isi_debug_cleanup(struct mxc_isi_dev *isi)
402{
403}
404#endif
405
406#endif /* __MXC_ISI_CORE_H__ */
407