.. | .. |
---|
| 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 |
---|