imx-media.h (9658B)
1/* SPDX-License-Identifier: GPL-2.0+ */ 2/* 3 * V4L2 Media Controller Driver for Freescale i.MX5/6 SOC 4 * 5 * Copyright (c) 2016 Mentor Graphics Inc. 6 */ 7#ifndef _IMX_MEDIA_H 8#define _IMX_MEDIA_H 9 10#include <linux/platform_device.h> 11#include <media/v4l2-ctrls.h> 12#include <media/v4l2-device.h> 13#include <media/v4l2-fwnode.h> 14#include <media/v4l2-subdev.h> 15#include <media/videobuf2-dma-contig.h> 16#include <video/imx-ipu-v3.h> 17 18#define IMX_MEDIA_DEF_PIX_WIDTH 640 19#define IMX_MEDIA_DEF_PIX_HEIGHT 480 20 21/* 22 * Enumeration of the IPU internal sub-devices 23 */ 24enum { 25 IPU_CSI0 = 0, 26 IPU_CSI1, 27 IPU_VDIC, 28 IPU_IC_PRP, 29 IPU_IC_PRPENC, 30 IPU_IC_PRPVF, 31 NUM_IPU_SUBDEVS, 32}; 33 34/* 35 * Pad definitions for the subdevs with multiple source or 36 * sink pads 37 */ 38 39/* ipu_csi */ 40enum { 41 CSI_SINK_PAD = 0, 42 CSI_SRC_PAD_DIRECT, 43 CSI_SRC_PAD_IDMAC, 44 CSI_NUM_PADS, 45}; 46 47/* ipu_vdic */ 48enum { 49 VDIC_SINK_PAD_DIRECT = 0, 50 VDIC_SINK_PAD_IDMAC, 51 VDIC_SRC_PAD_DIRECT, 52 VDIC_NUM_PADS, 53}; 54 55/* ipu_ic_prp */ 56enum { 57 PRP_SINK_PAD = 0, 58 PRP_SRC_PAD_PRPENC, 59 PRP_SRC_PAD_PRPVF, 60 PRP_NUM_PADS, 61}; 62 63/* ipu_ic_prpencvf */ 64enum { 65 PRPENCVF_SINK_PAD = 0, 66 PRPENCVF_SRC_PAD, 67 PRPENCVF_NUM_PADS, 68}; 69 70/* How long to wait for EOF interrupts in the buffer-capture subdevs */ 71#define IMX_MEDIA_EOF_TIMEOUT 2000 72 73struct imx_media_pixfmt { 74 /* the in-memory FourCC pixel format */ 75 u32 fourcc; 76 /* 77 * the set of equivalent media bus codes for the fourcc. 78 * NOTE! codes pointer is NULL for in-memory-only formats. 79 */ 80 const u32 *codes; 81 int bpp; /* total bpp */ 82 /* cycles per pixel for generic (bayer) formats for the parallel bus */ 83 int cycles; 84 enum ipu_color_space cs; 85 bool planar; /* is a planar format */ 86 bool bayer; /* is a raw bayer format */ 87 bool ipufmt; /* is one of the IPU internal formats */ 88}; 89 90enum imx_pixfmt_sel { 91 PIXFMT_SEL_YUV = BIT(0), /* select YUV formats */ 92 PIXFMT_SEL_RGB = BIT(1), /* select RGB formats */ 93 PIXFMT_SEL_BAYER = BIT(2), /* select BAYER formats */ 94 PIXFMT_SEL_IPU = BIT(3), /* select IPU-internal formats */ 95 PIXFMT_SEL_YUV_RGB = PIXFMT_SEL_YUV | PIXFMT_SEL_RGB, 96 PIXFMT_SEL_ANY = PIXFMT_SEL_YUV | PIXFMT_SEL_RGB | PIXFMT_SEL_BAYER, 97}; 98 99struct imx_media_buffer { 100 struct vb2_v4l2_buffer vbuf; /* v4l buffer must be first */ 101 struct list_head list; 102}; 103 104struct imx_media_video_dev { 105 struct video_device *vfd; 106 107 /* the user format */ 108 struct v4l2_pix_format fmt; 109 /* the compose rectangle */ 110 struct v4l2_rect compose; 111 const struct imx_media_pixfmt *cc; 112 113 /* links this vdev to master list */ 114 struct list_head list; 115}; 116 117static inline struct imx_media_buffer *to_imx_media_vb(struct vb2_buffer *vb) 118{ 119 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 120 121 return container_of(vbuf, struct imx_media_buffer, vbuf); 122} 123 124/* 125 * to support control inheritance to video devices, this 126 * retrieves a pad's list_head of video devices that can 127 * be reached from the pad. Note that only the lists in 128 * source pads get populated, sink pads have empty lists. 129 */ 130static inline struct list_head * 131to_pad_vdev_list(struct v4l2_subdev *sd, int pad_index) 132{ 133 struct list_head *vdev_list = sd->host_priv; 134 135 return vdev_list ? &vdev_list[pad_index] : NULL; 136} 137 138/* an entry in a pad's video device list */ 139struct imx_media_pad_vdev { 140 struct imx_media_video_dev *vdev; 141 struct list_head list; 142}; 143 144struct imx_media_dev { 145 struct media_device md; 146 struct v4l2_device v4l2_dev; 147 148 /* the pipeline object */ 149 struct media_pipeline pipe; 150 151 struct mutex mutex; /* protect elements below */ 152 153 /* master video device list */ 154 struct list_head vdev_list; 155 156 /* IPUs this media driver control, valid after subdevs bound */ 157 struct ipu_soc *ipu[2]; 158 159 /* for async subdev registration */ 160 struct v4l2_async_notifier notifier; 161 162 /* IC scaler/CSC mem2mem video device */ 163 struct imx_media_video_dev *m2m_vdev; 164 165 /* the IPU internal subdev's registered synchronously */ 166 struct v4l2_subdev *sync_sd[2][NUM_IPU_SUBDEVS]; 167}; 168 169/* imx-media-utils.c */ 170const struct imx_media_pixfmt * 171imx_media_find_pixel_format(u32 fourcc, enum imx_pixfmt_sel sel); 172int imx_media_enum_pixel_formats(u32 *fourcc, u32 index, 173 enum imx_pixfmt_sel sel, u32 code); 174const struct imx_media_pixfmt * 175imx_media_find_mbus_format(u32 code, enum imx_pixfmt_sel sel); 176int imx_media_enum_mbus_formats(u32 *code, u32 index, 177 enum imx_pixfmt_sel sel); 178 179static inline const struct imx_media_pixfmt * 180imx_media_find_ipu_format(u32 code, enum imx_pixfmt_sel fmt_sel) 181{ 182 return imx_media_find_mbus_format(code, fmt_sel | PIXFMT_SEL_IPU); 183} 184 185static inline int imx_media_enum_ipu_formats(u32 *code, u32 index, 186 enum imx_pixfmt_sel fmt_sel) 187{ 188 return imx_media_enum_mbus_formats(code, index, 189 fmt_sel | PIXFMT_SEL_IPU); 190} 191 192int imx_media_init_mbus_fmt(struct v4l2_mbus_framefmt *mbus, 193 u32 width, u32 height, u32 code, u32 field, 194 const struct imx_media_pixfmt **cc); 195int imx_media_init_cfg(struct v4l2_subdev *sd, 196 struct v4l2_subdev_state *sd_state); 197void imx_media_try_colorimetry(struct v4l2_mbus_framefmt *tryfmt, 198 bool ic_route); 199int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix, 200 const struct v4l2_mbus_framefmt *mbus, 201 const struct imx_media_pixfmt *cc); 202void imx_media_grp_id_to_sd_name(char *sd_name, int sz, 203 u32 grp_id, int ipu_id); 204struct v4l2_subdev * 205imx_media_find_subdev_by_fwnode(struct imx_media_dev *imxmd, 206 struct fwnode_handle *fwnode); 207struct v4l2_subdev * 208imx_media_find_subdev_by_devname(struct imx_media_dev *imxmd, 209 const char *devname); 210void imx_media_add_video_device(struct imx_media_dev *imxmd, 211 struct imx_media_video_dev *vdev); 212int imx_media_pipeline_csi2_channel(struct media_entity *start_entity); 213struct media_pad * 214imx_media_pipeline_pad(struct media_entity *start_entity, u32 grp_id, 215 enum v4l2_buf_type buftype, bool upstream); 216struct v4l2_subdev * 217imx_media_pipeline_subdev(struct media_entity *start_entity, u32 grp_id, 218 bool upstream); 219struct video_device * 220imx_media_pipeline_video_device(struct media_entity *start_entity, 221 enum v4l2_buf_type buftype, bool upstream); 222struct fwnode_handle *imx_media_get_pad_fwnode(struct media_pad *pad); 223 224struct imx_media_dma_buf { 225 void *virt; 226 dma_addr_t phys; 227 unsigned long len; 228}; 229 230void imx_media_free_dma_buf(struct device *dev, 231 struct imx_media_dma_buf *buf); 232int imx_media_alloc_dma_buf(struct device *dev, 233 struct imx_media_dma_buf *buf, 234 int size); 235 236int imx_media_pipeline_set_stream(struct imx_media_dev *imxmd, 237 struct media_entity *entity, 238 bool on); 239 240/* imx-media-dev-common.c */ 241int imx_media_probe_complete(struct v4l2_async_notifier *notifier); 242struct imx_media_dev *imx_media_dev_init(struct device *dev, 243 const struct media_device_ops *ops); 244int imx_media_dev_notifier_register(struct imx_media_dev *imxmd, 245 const struct v4l2_async_notifier_operations *ops); 246 247/* imx-media-fim.c */ 248struct imx_media_fim; 249void imx_media_fim_eof_monitor(struct imx_media_fim *fim, ktime_t timestamp); 250int imx_media_fim_set_stream(struct imx_media_fim *fim, 251 const struct v4l2_fract *frame_interval, 252 bool on); 253int imx_media_fim_add_controls(struct imx_media_fim *fim); 254struct imx_media_fim *imx_media_fim_init(struct v4l2_subdev *sd); 255void imx_media_fim_free(struct imx_media_fim *fim); 256 257/* imx-media-internal-sd.c */ 258int imx_media_register_ipu_internal_subdevs(struct imx_media_dev *imxmd, 259 struct v4l2_subdev *csi); 260void imx_media_unregister_ipu_internal_subdevs(struct imx_media_dev *imxmd); 261 262/* imx-media-of.c */ 263int imx_media_add_of_subdevs(struct imx_media_dev *dev, 264 struct device_node *np); 265int imx_media_of_add_csi(struct imx_media_dev *imxmd, 266 struct device_node *csi_np); 267 268/* imx-media-vdic.c */ 269struct v4l2_subdev *imx_media_vdic_register(struct v4l2_device *v4l2_dev, 270 struct device *ipu_dev, 271 struct ipu_soc *ipu, 272 u32 grp_id); 273int imx_media_vdic_unregister(struct v4l2_subdev *sd); 274 275/* imx-ic-common.c */ 276struct v4l2_subdev *imx_media_ic_register(struct v4l2_device *v4l2_dev, 277 struct device *ipu_dev, 278 struct ipu_soc *ipu, 279 u32 grp_id); 280int imx_media_ic_unregister(struct v4l2_subdev *sd); 281 282/* imx-media-capture.c */ 283struct imx_media_video_dev * 284imx_media_capture_device_init(struct device *dev, struct v4l2_subdev *src_sd, 285 int pad, bool legacy_api); 286void imx_media_capture_device_remove(struct imx_media_video_dev *vdev); 287int imx_media_capture_device_register(struct imx_media_video_dev *vdev, 288 u32 link_flags); 289void imx_media_capture_device_unregister(struct imx_media_video_dev *vdev); 290struct imx_media_buffer * 291imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev); 292void imx_media_capture_device_error(struct imx_media_video_dev *vdev); 293 294/* imx-media-csc-scaler.c */ 295struct imx_media_video_dev * 296imx_media_csc_scaler_device_init(struct imx_media_dev *dev); 297int imx_media_csc_scaler_device_register(struct imx_media_video_dev *vdev); 298void imx_media_csc_scaler_device_unregister(struct imx_media_video_dev *vdev); 299 300/* subdev group ids */ 301#define IMX_MEDIA_GRP_ID_CSI2 BIT(8) 302#define IMX_MEDIA_GRP_ID_CSI BIT(9) 303#define IMX_MEDIA_GRP_ID_IPU_CSI_BIT 10 304#define IMX_MEDIA_GRP_ID_IPU_CSI (0x3 << IMX_MEDIA_GRP_ID_IPU_CSI_BIT) 305#define IMX_MEDIA_GRP_ID_IPU_CSI0 BIT(IMX_MEDIA_GRP_ID_IPU_CSI_BIT) 306#define IMX_MEDIA_GRP_ID_IPU_CSI1 (2 << IMX_MEDIA_GRP_ID_IPU_CSI_BIT) 307#define IMX_MEDIA_GRP_ID_IPU_VDIC BIT(12) 308#define IMX_MEDIA_GRP_ID_IPU_IC_PRP BIT(13) 309#define IMX_MEDIA_GRP_ID_IPU_IC_PRPENC BIT(14) 310#define IMX_MEDIA_GRP_ID_IPU_IC_PRPVF BIT(15) 311#define IMX_MEDIA_GRP_ID_CSI_MUX BIT(16) 312 313#endif