xref: /linux/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h (revision 00c6649bafef628955569dd39a59e3170e48f7b5) !
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 
29 struct clk_bulk_data;
30 struct dentry;
31 struct device;
32 struct media_intf_devnode;
33 struct regmap;
34 struct 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 
62 struct mxc_isi_dev;
63 struct mxc_isi_m2m_ctx;
64 
65 enum mxc_isi_buf_id {
66 	MXC_ISI_BUF1 = 0x0,
67 	MXC_ISI_BUF2,
68 };
69 
70 enum mxc_isi_encoding {
71 	MXC_ISI_ENC_RAW,
72 	MXC_ISI_ENC_RGB,
73 	MXC_ISI_ENC_YUV,
74 };
75 
76 enum mxc_isi_input_id {
77 	/* Inputs from the crossbar switch range from 0 to 15 */
78 	MXC_ISI_INPUT_MEM = 16,
79 };
80 
81 enum 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 
87 struct 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 
101 struct mxc_isi_bus_format_info {
102 	u32	mbus_code;
103 	u32	output;
104 	u32	pads;
105 	enum mxc_isi_encoding encoding;
106 };
107 
108 struct 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 
116 struct mxc_isi_reg {
117 	u32 mask;
118 };
119 
120 struct mxc_isi_ier_reg {
121 	/* Overflow Y/U/V trigger enable*/
122 	struct mxc_isi_reg oflw_y_buf_en;
123 	struct mxc_isi_reg oflw_u_buf_en;
124 	struct mxc_isi_reg oflw_v_buf_en;
125 
126 	/* Excess overflow Y/U/V trigger enable*/
127 	struct mxc_isi_reg excs_oflw_y_buf_en;
128 	struct mxc_isi_reg excs_oflw_u_buf_en;
129 	struct mxc_isi_reg excs_oflw_v_buf_en;
130 
131 	/* Panic Y/U/V trigger enable*/
132 	struct mxc_isi_reg panic_y_buf_en;
133 	struct mxc_isi_reg panic_v_buf_en;
134 	struct mxc_isi_reg panic_u_buf_en;
135 };
136 
137 struct mxc_isi_panic_thd {
138 	u32 mask;
139 	u32 offset;
140 	u32 threshold;
141 };
142 
143 struct mxc_isi_set_thd {
144 	struct mxc_isi_panic_thd panic_set_thd_y;
145 	struct mxc_isi_panic_thd panic_set_thd_u;
146 	struct mxc_isi_panic_thd panic_set_thd_v;
147 };
148 
149 struct mxc_gasket_ops {
150 	void (*enable)(struct mxc_isi_dev *isi,
151 		       const struct v4l2_mbus_frame_desc *fd,
152 		       const struct v4l2_mbus_framefmt *fmt,
153 		       const unsigned int port);
154 	void (*disable)(struct mxc_isi_dev *isi, const unsigned int port);
155 };
156 
157 enum model {
158 	MXC_ISI_IMX8MN,
159 	MXC_ISI_IMX8MP,
160 	MXC_ISI_IMX8QM,
161 	MXC_ISI_IMX8QXP,
162 	MXC_ISI_IMX8ULP,
163 	MXC_ISI_IMX91,
164 	MXC_ISI_IMX93,
165 	MXC_ISI_IMX95,
166 };
167 
168 struct mxc_isi_plat_data {
169 	enum model model;
170 	unsigned int num_ports;
171 	unsigned int num_channels;
172 	unsigned int reg_offset;
173 	const struct mxc_isi_ier_reg  *ier_reg;
174 	const struct mxc_isi_set_thd *set_thd;
175 	const struct mxc_gasket_ops *gasket_ops;
176 	bool buf_active_reverse;
177 	bool has_36bit_dma;
178 };
179 
180 struct mxc_isi_dma_buffer {
181 	size_t				size;
182 	void				*addr;
183 	dma_addr_t			dma;
184 };
185 
186 struct mxc_isi_input {
187 	unsigned int			enable_count;
188 };
189 
190 struct mxc_isi_crossbar {
191 	struct mxc_isi_dev		*isi;
192 
193 	unsigned int			num_sinks;
194 	unsigned int			num_sources;
195 	struct mxc_isi_input		*inputs;
196 
197 	struct v4l2_subdev		sd;
198 	struct media_pad		*pads;
199 };
200 
201 struct mxc_isi_video {
202 	struct mxc_isi_pipe		*pipe;
203 
204 	struct video_device		vdev;
205 	struct media_pad		pad;
206 
207 	/* Protects the vdev and vb2_q operations */
208 	struct mutex			lock;
209 
210 	struct v4l2_pix_format_mplane	pix;
211 	const struct mxc_isi_format_info *fmtinfo;
212 
213 	struct {
214 		struct v4l2_ctrl_handler handler;
215 		unsigned int		alpha;
216 		bool			hflip;
217 		bool			vflip;
218 	} ctrls;
219 
220 	struct vb2_queue		vb2_q;
221 	struct mxc_isi_buffer		buf_discard[3];
222 	struct list_head		out_pending;
223 	struct list_head		out_active;
224 	struct list_head		out_discard;
225 	u32				frame_count;
226 	/* Protects out_pending, out_active, out_discard and frame_count */
227 	spinlock_t			buf_lock;
228 
229 	struct mxc_isi_dma_buffer	discard_buffer[MXC_MAX_PLANES];
230 };
231 
232 typedef void(*mxc_isi_pipe_irq_t)(struct mxc_isi_pipe *, u32);
233 
234 struct mxc_isi_pipe {
235 	struct mxc_isi_dev		*isi;
236 	u32				id;
237 	void __iomem			*regs;
238 
239 	struct media_pipeline		pipe;
240 
241 	struct v4l2_subdev		sd;
242 	struct media_pad		pads[MXC_ISI_PIPE_PADS_NUM];
243 
244 	struct mxc_isi_video		video;
245 
246 	/*
247 	 * Protects use_count, irq_handler, res_available, res_acquired,
248 	 * chained_res, and the CHNL_CTRL register.
249 	 */
250 	struct mutex			lock;
251 	unsigned int			use_count;
252 	mxc_isi_pipe_irq_t		irq_handler;
253 
254 #define MXC_ISI_CHANNEL_RES_LINE_BUF	BIT(0)
255 #define MXC_ISI_CHANNEL_RES_OUTPUT_BUF	BIT(1)
256 	u8				available_res;
257 	u8				acquired_res;
258 	u8				chained_res;
259 	bool				chained;
260 };
261 
262 struct mxc_isi_m2m {
263 	struct mxc_isi_dev		*isi;
264 	struct mxc_isi_pipe		*pipe;
265 
266 	struct media_pad		pad;
267 	struct video_device		vdev;
268 	struct media_intf_devnode	*intf;
269 	struct v4l2_m2m_dev		*m2m_dev;
270 
271 	/* Protects last_ctx, usage_count and chained_count */
272 	struct mutex			lock;
273 
274 	struct mxc_isi_m2m_ctx		*last_ctx;
275 	int				usage_count;
276 	int				chained_count;
277 };
278 
279 struct mxc_isi_dev {
280 	struct device			*dev;
281 
282 	const struct mxc_isi_plat_data	*pdata;
283 
284 	void __iomem			*regs;
285 	struct clk_bulk_data		*clks;
286 	int				num_clks;
287 	struct regmap			*gasket;
288 
289 	struct mxc_isi_crossbar		crossbar;
290 	struct mxc_isi_pipe		*pipes;
291 	struct mxc_isi_m2m		m2m;
292 
293 	struct media_device		media_dev;
294 	struct v4l2_device		v4l2_dev;
295 	struct v4l2_async_notifier	notifier;
296 
297 	struct dentry			*debugfs_root;
298 };
299 
300 extern const struct mxc_gasket_ops mxc_imx8_gasket_ops;
301 extern const struct mxc_gasket_ops mxc_imx93_gasket_ops;
302 
303 int mxc_isi_crossbar_init(struct mxc_isi_dev *isi);
304 void mxc_isi_crossbar_cleanup(struct mxc_isi_crossbar *xbar);
305 int mxc_isi_crossbar_register(struct mxc_isi_crossbar *xbar);
306 void mxc_isi_crossbar_unregister(struct mxc_isi_crossbar *xbar);
307 
308 const struct mxc_isi_bus_format_info *
309 mxc_isi_bus_format_by_code(u32 code, unsigned int pad);
310 const struct mxc_isi_bus_format_info *
311 mxc_isi_bus_format_by_index(unsigned int index, unsigned int pad);
312 const struct mxc_isi_format_info *
313 mxc_isi_format_by_fourcc(u32 fourcc, enum mxc_isi_video_type type);
314 const struct mxc_isi_format_info *
315 mxc_isi_format_enum(unsigned int index, enum mxc_isi_video_type type);
316 const struct mxc_isi_format_info *
317 mxc_isi_format_try(struct mxc_isi_pipe *pipe, struct v4l2_pix_format_mplane *pix,
318 		   enum mxc_isi_video_type type);
319 
320 int mxc_isi_pipe_init(struct mxc_isi_dev *isi, unsigned int id);
321 void mxc_isi_pipe_cleanup(struct mxc_isi_pipe *pipe);
322 int mxc_isi_pipe_acquire(struct mxc_isi_pipe *pipe,
323 			 mxc_isi_pipe_irq_t irq_handler);
324 void mxc_isi_pipe_release(struct mxc_isi_pipe *pipe);
325 int mxc_isi_pipe_enable(struct mxc_isi_pipe *pipe);
326 void mxc_isi_pipe_disable(struct mxc_isi_pipe *pipe);
327 
328 int mxc_isi_video_register(struct mxc_isi_pipe *pipe,
329 			   struct v4l2_device *v4l2_dev);
330 void mxc_isi_video_unregister(struct mxc_isi_pipe *pipe);
331 void mxc_isi_video_suspend(struct mxc_isi_pipe *pipe);
332 int mxc_isi_video_resume(struct mxc_isi_pipe *pipe);
333 int mxc_isi_video_queue_setup(const struct v4l2_pix_format_mplane *format,
334 			      const struct mxc_isi_format_info *info,
335 			      unsigned int *num_buffers,
336 			      unsigned int *num_planes, unsigned int sizes[]);
337 void mxc_isi_video_buffer_init(struct vb2_buffer *vb2, dma_addr_t dma_addrs[3],
338 			       const struct mxc_isi_format_info *info,
339 			       const struct v4l2_pix_format_mplane *pix);
340 int mxc_isi_video_buffer_prepare(struct mxc_isi_dev *isi, struct vb2_buffer *vb2,
341 				 const struct mxc_isi_format_info *info,
342 				 const struct v4l2_pix_format_mplane *pix);
343 
344 #ifdef CONFIG_VIDEO_IMX8_ISI_M2M
345 int mxc_isi_m2m_register(struct mxc_isi_dev *isi, struct v4l2_device *v4l2_dev);
346 int mxc_isi_m2m_unregister(struct mxc_isi_dev *isi);
347 void mxc_isi_m2m_suspend(struct mxc_isi_m2m *m2m);
348 int mxc_isi_m2m_resume(struct mxc_isi_m2m *m2m);
349 #else
350 static inline int mxc_isi_m2m_register(struct mxc_isi_dev *isi,
351 				       struct v4l2_device *v4l2_dev)
352 {
353 	return 0;
354 }
355 static inline int mxc_isi_m2m_unregister(struct mxc_isi_dev *isi)
356 {
357 	return 0;
358 }
359 static inline void mxc_isi_m2m_suspend(struct mxc_isi_m2m *m2m)
360 {
361 }
362 static inline int mxc_isi_m2m_resume(struct mxc_isi_m2m *m2m)
363 {
364 	return 0;
365 }
366 #endif
367 
368 int mxc_isi_channel_acquire(struct mxc_isi_pipe *pipe,
369 			    mxc_isi_pipe_irq_t irq_handler, bool bypass);
370 void mxc_isi_channel_release(struct mxc_isi_pipe *pipe);
371 void mxc_isi_channel_get(struct mxc_isi_pipe *pipe);
372 void mxc_isi_channel_put(struct mxc_isi_pipe *pipe);
373 void mxc_isi_channel_enable(struct mxc_isi_pipe *pipe);
374 void mxc_isi_channel_disable(struct mxc_isi_pipe *pipe);
375 int mxc_isi_channel_chain(struct mxc_isi_pipe *pipe);
376 void mxc_isi_channel_unchain(struct mxc_isi_pipe *pipe);
377 
378 void mxc_isi_channel_config(struct mxc_isi_pipe *pipe,
379 			    enum mxc_isi_input_id input,
380 			    const struct v4l2_area *in_size,
381 			    const struct v4l2_area *scale,
382 			    const struct v4l2_rect *crop,
383 			    enum mxc_isi_encoding in_encoding,
384 			    enum mxc_isi_encoding out_encoding);
385 
386 void mxc_isi_channel_set_input_format(struct mxc_isi_pipe *pipe,
387 				      const struct mxc_isi_format_info *info,
388 				      const struct v4l2_pix_format_mplane *format);
389 void mxc_isi_channel_set_output_format(struct mxc_isi_pipe *pipe,
390 				       const struct mxc_isi_format_info *info,
391 				       struct v4l2_pix_format_mplane *format);
392 void mxc_isi_channel_m2m_start(struct mxc_isi_pipe *pipe);
393 
394 void mxc_isi_channel_set_alpha(struct mxc_isi_pipe *pipe, u8 alpha);
395 void mxc_isi_channel_set_flip(struct mxc_isi_pipe *pipe, bool hflip, bool vflip);
396 
397 void mxc_isi_channel_set_inbuf(struct mxc_isi_pipe *pipe, dma_addr_t dma_addr);
398 void mxc_isi_channel_set_outbuf(struct mxc_isi_pipe *pipe,
399 				const dma_addr_t dma_addrs[3],
400 				enum mxc_isi_buf_id buf_id);
401 
402 u32 mxc_isi_channel_irq_status(struct mxc_isi_pipe *pipe, bool clear);
403 void mxc_isi_channel_irq_clear(struct mxc_isi_pipe *pipe);
404 
405 #if IS_ENABLED(CONFIG_DEBUG_FS)
406 void mxc_isi_debug_init(struct mxc_isi_dev *isi);
407 void mxc_isi_debug_cleanup(struct mxc_isi_dev *isi);
408 #else
409 static inline void mxc_isi_debug_init(struct mxc_isi_dev *isi)
410 {
411 }
412 static inline void mxc_isi_debug_cleanup(struct mxc_isi_dev *isi)
413 {
414 }
415 #endif
416 
417 #endif /* __MXC_ISI_CORE_H__ */
418