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