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