| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0+ */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * V4L2 Media Controller Driver for Freescale i.MX5/6 SOC |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2016 Mentor Graphics Inc. |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 7 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 8 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 9 | | - * (at your option) any later version. |
|---|
| 10 | 6 | */ |
|---|
| 11 | 7 | #ifndef _IMX_MEDIA_H |
|---|
| 12 | 8 | #define _IMX_MEDIA_H |
|---|
| .. | .. |
|---|
| 18 | 14 | #include <media/v4l2-subdev.h> |
|---|
| 19 | 15 | #include <media/videobuf2-dma-contig.h> |
|---|
| 20 | 16 | #include <video/imx-ipu-v3.h> |
|---|
| 17 | + |
|---|
| 18 | +/* |
|---|
| 19 | + * Enumeration of the IPU internal sub-devices |
|---|
| 20 | + */ |
|---|
| 21 | +enum { |
|---|
| 22 | + IPU_CSI0 = 0, |
|---|
| 23 | + IPU_CSI1, |
|---|
| 24 | + IPU_VDIC, |
|---|
| 25 | + IPU_IC_PRP, |
|---|
| 26 | + IPU_IC_PRPENC, |
|---|
| 27 | + IPU_IC_PRPVF, |
|---|
| 28 | + NUM_IPU_SUBDEVS, |
|---|
| 29 | +}; |
|---|
| 21 | 30 | |
|---|
| 22 | 31 | /* |
|---|
| 23 | 32 | * Pad definitions for the subdevs with multiple source or |
|---|
| .. | .. |
|---|
| 59 | 68 | #define IMX_MEDIA_EOF_TIMEOUT 1000 |
|---|
| 60 | 69 | |
|---|
| 61 | 70 | struct imx_media_pixfmt { |
|---|
| 71 | + /* the in-memory FourCC pixel format */ |
|---|
| 62 | 72 | u32 fourcc; |
|---|
| 63 | | - u32 codes[4]; |
|---|
| 73 | + /* |
|---|
| 74 | + * the set of equivalent media bus codes for the fourcc. |
|---|
| 75 | + * NOTE! codes pointer is NULL for in-memory-only formats. |
|---|
| 76 | + */ |
|---|
| 77 | + const u32 *codes; |
|---|
| 64 | 78 | int bpp; /* total bpp */ |
|---|
| 65 | 79 | /* cycles per pixel for generic (bayer) formats for the parallel bus */ |
|---|
| 66 | 80 | int cycles; |
|---|
| .. | .. |
|---|
| 68 | 82 | bool planar; /* is a planar format */ |
|---|
| 69 | 83 | bool bayer; /* is a raw bayer format */ |
|---|
| 70 | 84 | bool ipufmt; /* is one of the IPU internal formats */ |
|---|
| 85 | +}; |
|---|
| 86 | + |
|---|
| 87 | +enum imx_pixfmt_sel { |
|---|
| 88 | + PIXFMT_SEL_YUV = BIT(0), /* select YUV formats */ |
|---|
| 89 | + PIXFMT_SEL_RGB = BIT(1), /* select RGB formats */ |
|---|
| 90 | + PIXFMT_SEL_BAYER = BIT(2), /* select BAYER formats */ |
|---|
| 91 | + PIXFMT_SEL_IPU = BIT(3), /* select IPU-internal formats */ |
|---|
| 92 | + PIXFMT_SEL_YUV_RGB = PIXFMT_SEL_YUV | PIXFMT_SEL_RGB, |
|---|
| 93 | + PIXFMT_SEL_ANY = PIXFMT_SEL_YUV | PIXFMT_SEL_RGB | PIXFMT_SEL_BAYER, |
|---|
| 71 | 94 | }; |
|---|
| 72 | 95 | |
|---|
| 73 | 96 | struct imx_media_buffer { |
|---|
| .. | .. |
|---|
| 80 | 103 | |
|---|
| 81 | 104 | /* the user format */ |
|---|
| 82 | 105 | struct v4l2_format fmt; |
|---|
| 106 | + /* the compose rectangle */ |
|---|
| 107 | + struct v4l2_rect compose; |
|---|
| 83 | 108 | const struct imx_media_pixfmt *cc; |
|---|
| 84 | 109 | |
|---|
| 85 | 110 | /* links this vdev to master list */ |
|---|
| .. | .. |
|---|
| 113 | 138 | struct list_head list; |
|---|
| 114 | 139 | }; |
|---|
| 115 | 140 | |
|---|
| 116 | | -struct imx_media_internal_sd_platformdata { |
|---|
| 117 | | - char sd_name[V4L2_SUBDEV_NAME_SIZE]; |
|---|
| 118 | | - u32 grp_id; |
|---|
| 119 | | - int ipu_id; |
|---|
| 120 | | -}; |
|---|
| 121 | | - |
|---|
| 122 | | - |
|---|
| 123 | | -struct imx_media_async_subdev { |
|---|
| 124 | | - struct v4l2_async_subdev asd; |
|---|
| 125 | | - /* the platform device of IPU-internal subdevs */ |
|---|
| 126 | | - struct platform_device *pdev; |
|---|
| 127 | | - struct list_head list; |
|---|
| 128 | | -}; |
|---|
| 129 | | - |
|---|
| 130 | | -static inline struct imx_media_async_subdev * |
|---|
| 131 | | -to_imx_media_asd(struct v4l2_async_subdev *asd) |
|---|
| 132 | | -{ |
|---|
| 133 | | - return container_of(asd, struct imx_media_async_subdev, asd); |
|---|
| 134 | | -} |
|---|
| 135 | | - |
|---|
| 136 | 141 | struct imx_media_dev { |
|---|
| 137 | 142 | struct media_device md; |
|---|
| 138 | 143 | struct v4l2_device v4l2_dev; |
|---|
| .. | .. |
|---|
| 149 | 154 | struct ipu_soc *ipu[2]; |
|---|
| 150 | 155 | |
|---|
| 151 | 156 | /* for async subdev registration */ |
|---|
| 152 | | - struct list_head asd_list; |
|---|
| 153 | | - struct v4l2_async_notifier subdev_notifier; |
|---|
| 154 | | -}; |
|---|
| 157 | + struct v4l2_async_notifier notifier; |
|---|
| 155 | 158 | |
|---|
| 156 | | -enum codespace_sel { |
|---|
| 157 | | - CS_SEL_YUV = 0, |
|---|
| 158 | | - CS_SEL_RGB, |
|---|
| 159 | | - CS_SEL_ANY, |
|---|
| 159 | + /* IC scaler/CSC mem2mem video device */ |
|---|
| 160 | + struct imx_media_video_dev *m2m_vdev; |
|---|
| 161 | + |
|---|
| 162 | + /* the IPU internal subdev's registered synchronously */ |
|---|
| 163 | + struct v4l2_subdev *sync_sd[2][NUM_IPU_SUBDEVS]; |
|---|
| 160 | 164 | }; |
|---|
| 161 | 165 | |
|---|
| 162 | 166 | /* imx-media-utils.c */ |
|---|
| 163 | 167 | const struct imx_media_pixfmt * |
|---|
| 164 | | -imx_media_find_format(u32 fourcc, enum codespace_sel cs_sel, bool allow_bayer); |
|---|
| 165 | | -int imx_media_enum_format(u32 *fourcc, u32 index, enum codespace_sel cs_sel); |
|---|
| 168 | +imx_media_find_pixel_format(u32 fourcc, enum imx_pixfmt_sel sel); |
|---|
| 169 | +int imx_media_enum_pixel_formats(u32 *fourcc, u32 index, |
|---|
| 170 | + enum imx_pixfmt_sel sel); |
|---|
| 166 | 171 | const struct imx_media_pixfmt * |
|---|
| 167 | | -imx_media_find_mbus_format(u32 code, enum codespace_sel cs_sel, |
|---|
| 168 | | - bool allow_bayer); |
|---|
| 169 | | -int imx_media_enum_mbus_format(u32 *code, u32 index, enum codespace_sel cs_sel, |
|---|
| 170 | | - bool allow_bayer); |
|---|
| 171 | | -const struct imx_media_pixfmt * |
|---|
| 172 | | -imx_media_find_ipu_format(u32 code, enum codespace_sel cs_sel); |
|---|
| 173 | | -int imx_media_enum_ipu_format(u32 *code, u32 index, enum codespace_sel cs_sel); |
|---|
| 172 | +imx_media_find_mbus_format(u32 code, enum imx_pixfmt_sel sel); |
|---|
| 173 | +int imx_media_enum_mbus_formats(u32 *code, u32 index, |
|---|
| 174 | + enum imx_pixfmt_sel sel); |
|---|
| 175 | + |
|---|
| 176 | +static inline const struct imx_media_pixfmt * |
|---|
| 177 | +imx_media_find_ipu_format(u32 code, enum imx_pixfmt_sel fmt_sel) |
|---|
| 178 | +{ |
|---|
| 179 | + return imx_media_find_mbus_format(code, fmt_sel | PIXFMT_SEL_IPU); |
|---|
| 180 | +} |
|---|
| 181 | + |
|---|
| 182 | +static inline int imx_media_enum_ipu_formats(u32 *code, u32 index, |
|---|
| 183 | + enum imx_pixfmt_sel fmt_sel) |
|---|
| 184 | +{ |
|---|
| 185 | + return imx_media_enum_mbus_formats(code, index, |
|---|
| 186 | + fmt_sel | PIXFMT_SEL_IPU); |
|---|
| 187 | +} |
|---|
| 188 | + |
|---|
| 174 | 189 | int imx_media_init_mbus_fmt(struct v4l2_mbus_framefmt *mbus, |
|---|
| 175 | 190 | u32 width, u32 height, u32 code, u32 field, |
|---|
| 176 | 191 | const struct imx_media_pixfmt **cc); |
|---|
| 177 | 192 | int imx_media_init_cfg(struct v4l2_subdev *sd, |
|---|
| 178 | 193 | struct v4l2_subdev_pad_config *cfg); |
|---|
| 179 | | -void imx_media_fill_default_mbus_fields(struct v4l2_mbus_framefmt *tryfmt, |
|---|
| 180 | | - struct v4l2_mbus_framefmt *fmt, |
|---|
| 181 | | - bool ic_route); |
|---|
| 194 | +void imx_media_try_colorimetry(struct v4l2_mbus_framefmt *tryfmt, |
|---|
| 195 | + bool ic_route); |
|---|
| 182 | 196 | int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix, |
|---|
| 183 | | - struct v4l2_mbus_framefmt *mbus, |
|---|
| 197 | + const struct v4l2_mbus_framefmt *mbus, |
|---|
| 184 | 198 | const struct imx_media_pixfmt *cc); |
|---|
| 185 | 199 | int imx_media_mbus_fmt_to_ipu_image(struct ipu_image *image, |
|---|
| 186 | | - struct v4l2_mbus_framefmt *mbus); |
|---|
| 200 | + const struct v4l2_mbus_framefmt *mbus); |
|---|
| 187 | 201 | int imx_media_ipu_image_to_mbus_fmt(struct v4l2_mbus_framefmt *mbus, |
|---|
| 188 | | - struct ipu_image *image); |
|---|
| 202 | + const struct ipu_image *image); |
|---|
| 189 | 203 | void imx_media_grp_id_to_sd_name(char *sd_name, int sz, |
|---|
| 190 | 204 | u32 grp_id, int ipu_id); |
|---|
| 191 | 205 | struct v4l2_subdev * |
|---|
| .. | .. |
|---|
| 194 | 208 | struct v4l2_subdev * |
|---|
| 195 | 209 | imx_media_find_subdev_by_devname(struct imx_media_dev *imxmd, |
|---|
| 196 | 210 | const char *devname); |
|---|
| 197 | | -int imx_media_add_video_device(struct imx_media_dev *imxmd, |
|---|
| 198 | | - struct imx_media_video_dev *vdev); |
|---|
| 199 | | -int imx_media_find_mipi_csi2_channel(struct imx_media_dev *imxmd, |
|---|
| 200 | | - struct media_entity *start_entity); |
|---|
| 211 | +void imx_media_add_video_device(struct imx_media_dev *imxmd, |
|---|
| 212 | + struct imx_media_video_dev *vdev); |
|---|
| 213 | +int imx_media_pipeline_csi2_channel(struct media_entity *start_entity); |
|---|
| 201 | 214 | struct media_pad * |
|---|
| 202 | | -imx_media_find_upstream_pad(struct imx_media_dev *imxmd, |
|---|
| 203 | | - struct media_entity *start_entity, |
|---|
| 204 | | - u32 grp_id); |
|---|
| 215 | +imx_media_pipeline_pad(struct media_entity *start_entity, u32 grp_id, |
|---|
| 216 | + enum v4l2_buf_type buftype, bool upstream); |
|---|
| 205 | 217 | struct v4l2_subdev * |
|---|
| 206 | | -imx_media_find_upstream_subdev(struct imx_media_dev *imxmd, |
|---|
| 207 | | - struct media_entity *start_entity, |
|---|
| 208 | | - u32 grp_id); |
|---|
| 218 | +imx_media_pipeline_subdev(struct media_entity *start_entity, u32 grp_id, |
|---|
| 219 | + bool upstream); |
|---|
| 220 | +struct video_device * |
|---|
| 221 | +imx_media_pipeline_video_device(struct media_entity *start_entity, |
|---|
| 222 | + enum v4l2_buf_type buftype, bool upstream); |
|---|
| 223 | +struct fwnode_handle *imx_media_get_pad_fwnode(struct media_pad *pad); |
|---|
| 209 | 224 | |
|---|
| 210 | 225 | struct imx_media_dma_buf { |
|---|
| 211 | 226 | void *virt; |
|---|
| .. | .. |
|---|
| 213 | 228 | unsigned long len; |
|---|
| 214 | 229 | }; |
|---|
| 215 | 230 | |
|---|
| 216 | | -void imx_media_free_dma_buf(struct imx_media_dev *imxmd, |
|---|
| 231 | +void imx_media_free_dma_buf(struct device *dev, |
|---|
| 217 | 232 | struct imx_media_dma_buf *buf); |
|---|
| 218 | | -int imx_media_alloc_dma_buf(struct imx_media_dev *imxmd, |
|---|
| 233 | +int imx_media_alloc_dma_buf(struct device *dev, |
|---|
| 219 | 234 | struct imx_media_dma_buf *buf, |
|---|
| 220 | 235 | int size); |
|---|
| 221 | 236 | |
|---|
| .. | .. |
|---|
| 223 | 238 | struct media_entity *entity, |
|---|
| 224 | 239 | bool on); |
|---|
| 225 | 240 | |
|---|
| 226 | | -/* imx-media-dev.c */ |
|---|
| 227 | | -int imx_media_add_async_subdev(struct imx_media_dev *imxmd, |
|---|
| 228 | | - struct fwnode_handle *fwnode, |
|---|
| 229 | | - struct platform_device *pdev); |
|---|
| 241 | +/* imx-media-dev-common.c */ |
|---|
| 242 | +int imx_media_probe_complete(struct v4l2_async_notifier *notifier); |
|---|
| 243 | +struct imx_media_dev *imx_media_dev_init(struct device *dev, |
|---|
| 244 | + const struct media_device_ops *ops); |
|---|
| 245 | +int imx_media_dev_notifier_register(struct imx_media_dev *imxmd, |
|---|
| 246 | + const struct v4l2_async_notifier_operations *ops); |
|---|
| 230 | 247 | |
|---|
| 231 | 248 | /* imx-media-fim.c */ |
|---|
| 232 | 249 | struct imx_media_fim; |
|---|
| .. | .. |
|---|
| 239 | 256 | void imx_media_fim_free(struct imx_media_fim *fim); |
|---|
| 240 | 257 | |
|---|
| 241 | 258 | /* imx-media-internal-sd.c */ |
|---|
| 242 | | -int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd); |
|---|
| 243 | | -int imx_media_create_internal_links(struct imx_media_dev *imxmd, |
|---|
| 244 | | - struct v4l2_subdev *sd); |
|---|
| 245 | | -void imx_media_remove_internal_subdevs(struct imx_media_dev *imxmd); |
|---|
| 259 | +int imx_media_register_ipu_internal_subdevs(struct imx_media_dev *imxmd, |
|---|
| 260 | + struct v4l2_subdev *csi); |
|---|
| 261 | +void imx_media_unregister_ipu_internal_subdevs(struct imx_media_dev *imxmd); |
|---|
| 246 | 262 | |
|---|
| 247 | 263 | /* imx-media-of.c */ |
|---|
| 248 | 264 | int imx_media_add_of_subdevs(struct imx_media_dev *dev, |
|---|
| 249 | 265 | struct device_node *np); |
|---|
| 250 | | -int imx_media_create_of_links(struct imx_media_dev *imxmd, |
|---|
| 251 | | - struct v4l2_subdev *sd); |
|---|
| 252 | | -int imx_media_create_csi_of_links(struct imx_media_dev *imxmd, |
|---|
| 253 | | - struct v4l2_subdev *csi); |
|---|
| 266 | +int imx_media_of_add_csi(struct imx_media_dev *imxmd, |
|---|
| 267 | + struct device_node *csi_np); |
|---|
| 268 | + |
|---|
| 269 | +/* imx-media-vdic.c */ |
|---|
| 270 | +struct v4l2_subdev *imx_media_vdic_register(struct v4l2_device *v4l2_dev, |
|---|
| 271 | + struct device *ipu_dev, |
|---|
| 272 | + struct ipu_soc *ipu, |
|---|
| 273 | + u32 grp_id); |
|---|
| 274 | +int imx_media_vdic_unregister(struct v4l2_subdev *sd); |
|---|
| 275 | + |
|---|
| 276 | +/* imx-ic-common.c */ |
|---|
| 277 | +struct v4l2_subdev *imx_media_ic_register(struct v4l2_device *v4l2_dev, |
|---|
| 278 | + struct device *ipu_dev, |
|---|
| 279 | + struct ipu_soc *ipu, |
|---|
| 280 | + u32 grp_id); |
|---|
| 281 | +int imx_media_ic_unregister(struct v4l2_subdev *sd); |
|---|
| 254 | 282 | |
|---|
| 255 | 283 | /* imx-media-capture.c */ |
|---|
| 256 | 284 | struct imx_media_video_dev * |
|---|
| 257 | | -imx_media_capture_device_init(struct v4l2_subdev *src_sd, int pad); |
|---|
| 285 | +imx_media_capture_device_init(struct device *dev, struct v4l2_subdev *src_sd, |
|---|
| 286 | + int pad); |
|---|
| 258 | 287 | void imx_media_capture_device_remove(struct imx_media_video_dev *vdev); |
|---|
| 259 | 288 | int imx_media_capture_device_register(struct imx_media_video_dev *vdev); |
|---|
| 260 | 289 | void imx_media_capture_device_unregister(struct imx_media_video_dev *vdev); |
|---|
| 261 | 290 | struct imx_media_buffer * |
|---|
| 262 | 291 | imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev); |
|---|
| 263 | | -void imx_media_capture_device_set_format(struct imx_media_video_dev *vdev, |
|---|
| 264 | | - struct v4l2_pix_format *pix); |
|---|
| 265 | 292 | void imx_media_capture_device_error(struct imx_media_video_dev *vdev); |
|---|
| 266 | 293 | |
|---|
| 294 | +/* imx-media-csc-scaler.c */ |
|---|
| 295 | +struct imx_media_video_dev * |
|---|
| 296 | +imx_media_csc_scaler_device_init(struct imx_media_dev *dev); |
|---|
| 297 | +int imx_media_csc_scaler_device_register(struct imx_media_video_dev *vdev); |
|---|
| 298 | +void imx_media_csc_scaler_device_unregister(struct imx_media_video_dev *vdev); |
|---|
| 299 | + |
|---|
| 267 | 300 | /* subdev group ids */ |
|---|
| 268 | | -#define IMX_MEDIA_GRP_ID_CSI2 BIT(8) |
|---|
| 269 | | -#define IMX_MEDIA_GRP_ID_CSI_BIT 9 |
|---|
| 270 | | -#define IMX_MEDIA_GRP_ID_CSI (0x3 << IMX_MEDIA_GRP_ID_CSI_BIT) |
|---|
| 271 | | -#define IMX_MEDIA_GRP_ID_CSI0 BIT(IMX_MEDIA_GRP_ID_CSI_BIT) |
|---|
| 272 | | -#define IMX_MEDIA_GRP_ID_CSI1 (2 << IMX_MEDIA_GRP_ID_CSI_BIT) |
|---|
| 273 | | -#define IMX_MEDIA_GRP_ID_VDIC BIT(11) |
|---|
| 274 | | -#define IMX_MEDIA_GRP_ID_IC_PRP BIT(12) |
|---|
| 275 | | -#define IMX_MEDIA_GRP_ID_IC_PRPENC BIT(13) |
|---|
| 276 | | -#define IMX_MEDIA_GRP_ID_IC_PRPVF BIT(14) |
|---|
| 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) |
|---|
| 277 | 312 | |
|---|
| 278 | 313 | #endif |
|---|