1 /* SPDX-License-Identifier: GPL-2.0 */
3 * V4L2 Capture ISI subdev for i.MX8QXP/QM platform
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
10 #ifndef __MXC_ISI_CORE_H__
11 #define __MXC_ISI_CORE_H__
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>
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>
32 struct media_intf_devnode
;
37 #define MXC_ISI_PIPE_PAD_SINK 0
38 #define MXC_ISI_PIPE_PAD_SOURCE 1
39 #define MXC_ISI_PIPE_PADS_NUM 2
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
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
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
63 struct mxc_isi_m2m_ctx
;
70 enum mxc_isi_encoding
{
76 enum mxc_isi_input_id
{
77 /* Inputs from the crossbar switch range from 0 to 15 */
78 MXC_ISI_INPUT_MEM
= 16,
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),
87 struct mxc_isi_format_info
{
90 enum mxc_isi_video_type type
;
95 u8 depth
[MXC_MAX_PLANES
];
98 enum mxc_isi_encoding encoding
;
101 struct mxc_isi_bus_format_info
{
105 enum mxc_isi_encoding encoding
;
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
;
121 struct 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
;
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
;
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
;
138 struct mxc_isi_panic_thd
{
144 struct 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
;
150 struct 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
);
164 struct mxc_isi_plat_data
{
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
;
178 struct mxc_isi_dma_buffer
{
184 struct mxc_isi_input
{
185 unsigned int enable_count
;
188 struct mxc_isi_crossbar
{
189 struct mxc_isi_dev
*isi
;
191 unsigned int num_sinks
;
192 unsigned int num_sources
;
193 struct mxc_isi_input
*inputs
;
195 struct v4l2_subdev sd
;
196 struct media_pad
*pads
;
199 struct mxc_isi_video
{
200 struct mxc_isi_pipe
*pipe
;
202 struct video_device vdev
;
203 struct media_pad pad
;
205 /* Protects is_streaming, and the vdev and vb2_q operations */
209 struct v4l2_pix_format_mplane pix
;
210 const struct mxc_isi_format_info
*fmtinfo
;
213 struct v4l2_ctrl_handler handler
;
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
;
225 /* Protects out_pending, out_active, out_discard and frame_count */
228 struct mxc_isi_dma_buffer discard_buffer
[MXC_MAX_PLANES
];
231 typedef void(*mxc_isi_pipe_irq_t
)(struct mxc_isi_pipe
*, u32
);
233 struct mxc_isi_pipe
{
234 struct mxc_isi_dev
*isi
;
238 struct media_pipeline pipe
;
240 struct v4l2_subdev sd
;
241 struct media_pad pads
[MXC_ISI_PIPE_PADS_NUM
];
243 struct mxc_isi_video video
;
246 * Protects use_count, irq_handler, res_available, res_acquired,
247 * chained_res, and the CHNL_CTRL register.
250 unsigned int use_count
;
251 mxc_isi_pipe_irq_t irq_handler
;
253 #define MXC_ISI_CHANNEL_RES_LINE_BUF BIT(0)
254 #define MXC_ISI_CHANNEL_RES_OUTPUT_BUF BIT(1)
262 struct mxc_isi_dev
*isi
;
263 struct mxc_isi_pipe
*pipe
;
265 struct media_pad pad
;
266 struct video_device vdev
;
267 struct media_intf_devnode
*intf
;
268 struct v4l2_m2m_dev
*m2m_dev
;
270 /* Protects last_ctx, usage_count and chained_count */
273 struct mxc_isi_m2m_ctx
*last_ctx
;
281 const struct mxc_isi_plat_data
*pdata
;
284 struct clk_bulk_data
*clks
;
285 struct regmap
*gasket
;
287 struct mxc_isi_crossbar crossbar
;
288 struct mxc_isi_pipe
*pipes
;
289 struct mxc_isi_m2m m2m
;
291 struct media_device media_dev
;
292 struct v4l2_device v4l2_dev
;
293 struct v4l2_async_notifier notifier
;
295 struct dentry
*debugfs_root
;
298 extern const struct mxc_gasket_ops mxc_imx8_gasket_ops
;
299 extern const struct mxc_gasket_ops mxc_imx93_gasket_ops
;
301 int mxc_isi_crossbar_init(struct mxc_isi_dev
*isi
);
302 void mxc_isi_crossbar_cleanup(struct mxc_isi_crossbar
*xbar
);
303 int mxc_isi_crossbar_register(struct mxc_isi_crossbar
*xbar
);
304 void mxc_isi_crossbar_unregister(struct mxc_isi_crossbar
*xbar
);
306 const struct mxc_isi_bus_format_info
*
307 mxc_isi_bus_format_by_code(u32 code
, unsigned int pad
);
308 const struct mxc_isi_bus_format_info
*
309 mxc_isi_bus_format_by_index(unsigned int index
, unsigned int pad
);
310 const struct mxc_isi_format_info
*
311 mxc_isi_format_by_fourcc(u32 fourcc
, enum mxc_isi_video_type type
);
312 const struct mxc_isi_format_info
*
313 mxc_isi_format_enum(unsigned int index
, enum mxc_isi_video_type type
);
314 const struct mxc_isi_format_info
*
315 mxc_isi_format_try(struct mxc_isi_pipe
*pipe
, struct v4l2_pix_format_mplane
*pix
,
316 enum mxc_isi_video_type type
);
318 int mxc_isi_pipe_init(struct mxc_isi_dev
*isi
, unsigned int id
);
319 void mxc_isi_pipe_cleanup(struct mxc_isi_pipe
*pipe
);
320 int mxc_isi_pipe_acquire(struct mxc_isi_pipe
*pipe
,
321 mxc_isi_pipe_irq_t irq_handler
);
322 void mxc_isi_pipe_release(struct mxc_isi_pipe
*pipe
);
323 int mxc_isi_pipe_enable(struct mxc_isi_pipe
*pipe
);
324 void mxc_isi_pipe_disable(struct mxc_isi_pipe
*pipe
);
326 int mxc_isi_video_register(struct mxc_isi_pipe
*pipe
,
327 struct v4l2_device
*v4l2_dev
);
328 void mxc_isi_video_unregister(struct mxc_isi_pipe
*pipe
);
329 void mxc_isi_video_suspend(struct mxc_isi_pipe
*pipe
);
330 int mxc_isi_video_resume(struct mxc_isi_pipe
*pipe
);
331 int 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
[]);
335 void 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
);
338 int 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
);
342 #ifdef CONFIG_VIDEO_IMX8_ISI_M2M
343 int mxc_isi_m2m_register(struct mxc_isi_dev
*isi
, struct v4l2_device
*v4l2_dev
);
344 int mxc_isi_m2m_unregister(struct mxc_isi_dev
*isi
);
346 static inline int mxc_isi_m2m_register(struct mxc_isi_dev
*isi
,
347 struct v4l2_device
*v4l2_dev
)
351 static inline int mxc_isi_m2m_unregister(struct mxc_isi_dev
*isi
)
357 int mxc_isi_channel_acquire(struct mxc_isi_pipe
*pipe
,
358 mxc_isi_pipe_irq_t irq_handler
, bool bypass
);
359 void mxc_isi_channel_release(struct mxc_isi_pipe
*pipe
);
360 void mxc_isi_channel_get(struct mxc_isi_pipe
*pipe
);
361 void mxc_isi_channel_put(struct mxc_isi_pipe
*pipe
);
362 void mxc_isi_channel_enable(struct mxc_isi_pipe
*pipe
);
363 void mxc_isi_channel_disable(struct mxc_isi_pipe
*pipe
);
364 int mxc_isi_channel_chain(struct mxc_isi_pipe
*pipe
, bool bypass
);
365 void mxc_isi_channel_unchain(struct mxc_isi_pipe
*pipe
);
367 void 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
);
375 void 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
);
378 void 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
);
381 void mxc_isi_channel_m2m_start(struct mxc_isi_pipe
*pipe
);
383 void mxc_isi_channel_set_alpha(struct mxc_isi_pipe
*pipe
, u8 alpha
);
384 void mxc_isi_channel_set_flip(struct mxc_isi_pipe
*pipe
, bool hflip
, bool vflip
);
386 void mxc_isi_channel_set_inbuf(struct mxc_isi_pipe
*pipe
, dma_addr_t dma_addr
);
387 void 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
);
391 u32
mxc_isi_channel_irq_status(struct mxc_isi_pipe
*pipe
, bool clear
);
392 void mxc_isi_channel_irq_clear(struct mxc_isi_pipe
*pipe
);
394 #if IS_ENABLED(CONFIG_DEBUG_FS)
395 void mxc_isi_debug_init(struct mxc_isi_dev
*isi
);
396 void mxc_isi_debug_cleanup(struct mxc_isi_dev
*isi
);
398 static inline void mxc_isi_debug_init(struct mxc_isi_dev
*isi
)
401 static inline void mxc_isi_debug_cleanup(struct mxc_isi_dev
*isi
)
406 #endif /* __MXC_ISI_CORE_H__ */