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 /*
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 };
30
31 /*
32 * Pad definitions for the subdevs with multiple source or
33 * sink pads
34 */
35
36 /* ipu_csi */
37 enum {
38 CSI_SINK_PAD = 0,
39 CSI_SRC_PAD_DIRECT,
40 CSI_SRC_PAD_IDMAC,
41 CSI_NUM_PADS,
42 };
43
44 /* ipu_vdic */
45 enum {
46 VDIC_SINK_PAD_DIRECT = 0,
47 VDIC_SINK_PAD_IDMAC,
48 VDIC_SRC_PAD_DIRECT,
49 VDIC_NUM_PADS,
50 };
51
52 /* ipu_ic_prp */
53 enum {
54 PRP_SINK_PAD = 0,
55 PRP_SRC_PAD_PRPENC,
56 PRP_SRC_PAD_PRPVF,
57 PRP_NUM_PADS,
58 };
59
60 /* ipu_ic_prpencvf */
61 enum {
62 PRPENCVF_SINK_PAD = 0,
63 PRPENCVF_SRC_PAD,
64 PRPENCVF_NUM_PADS,
65 };
66
67 /* How long to wait for EOF interrupts in the buffer-capture subdevs */
68 #define IMX_MEDIA_EOF_TIMEOUT 1000
69
70 struct imx_media_pixfmt {
71 /* the in-memory FourCC pixel format */
72 u32 fourcc;
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;
78 int bpp; /* total bpp */
79 /* cycles per pixel for generic (bayer) formats for the parallel bus */
80 int cycles;
81 enum ipu_color_space cs;
82 bool planar; /* is a planar format */
83 bool bayer; /* is a raw bayer format */
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,
94 };
95
96 struct imx_media_buffer {
97 struct vb2_v4l2_buffer vbuf; /* v4l buffer must be first */
98 struct list_head list;
99 };
100
101 struct imx_media_video_dev {
102 struct video_device *vfd;
103
104 /* the user format */
105 struct v4l2_format fmt;
106 /* the compose rectangle */
107 struct v4l2_rect compose;
108 const struct imx_media_pixfmt *cc;
109
110 /* links this vdev to master list */
111 struct list_head list;
112 };
113
to_imx_media_vb(struct vb2_buffer * vb)114 static inline struct imx_media_buffer *to_imx_media_vb(struct vb2_buffer *vb)
115 {
116 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
117
118 return container_of(vbuf, struct imx_media_buffer, vbuf);
119 }
120
121 /*
122 * to support control inheritance to video devices, this
123 * retrieves a pad's list_head of video devices that can
124 * be reached from the pad. Note that only the lists in
125 * source pads get populated, sink pads have empty lists.
126 */
127 static inline struct list_head *
to_pad_vdev_list(struct v4l2_subdev * sd,int pad_index)128 to_pad_vdev_list(struct v4l2_subdev *sd, int pad_index)
129 {
130 struct list_head *vdev_list = sd->host_priv;
131
132 return vdev_list ? &vdev_list[pad_index] : NULL;
133 }
134
135 /* an entry in a pad's video device list */
136 struct imx_media_pad_vdev {
137 struct imx_media_video_dev *vdev;
138 struct list_head list;
139 };
140
141 struct imx_media_dev {
142 struct media_device md;
143 struct v4l2_device v4l2_dev;
144
145 /* the pipeline object */
146 struct media_pipeline pipe;
147
148 struct mutex mutex; /* protect elements below */
149
150 /* master video device list */
151 struct list_head vdev_list;
152
153 /* IPUs this media driver control, valid after subdevs bound */
154 struct ipu_soc *ipu[2];
155
156 /* for async subdev registration */
157 struct v4l2_async_notifier notifier;
158
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];
164 };
165
166 /* imx-media-utils.c */
167 const struct imx_media_pixfmt *
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);
171 const struct imx_media_pixfmt *
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 *
imx_media_find_ipu_format(u32 code,enum imx_pixfmt_sel fmt_sel)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
imx_media_enum_ipu_formats(u32 * code,u32 index,enum imx_pixfmt_sel fmt_sel)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
189 int imx_media_init_mbus_fmt(struct v4l2_mbus_framefmt *mbus,
190 u32 width, u32 height, u32 code, u32 field,
191 const struct imx_media_pixfmt **cc);
192 int imx_media_init_cfg(struct v4l2_subdev *sd,
193 struct v4l2_subdev_pad_config *cfg);
194 void imx_media_try_colorimetry(struct v4l2_mbus_framefmt *tryfmt,
195 bool ic_route);
196 int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix,
197 const struct v4l2_mbus_framefmt *mbus,
198 const struct imx_media_pixfmt *cc);
199 int imx_media_mbus_fmt_to_ipu_image(struct ipu_image *image,
200 const struct v4l2_mbus_framefmt *mbus);
201 int imx_media_ipu_image_to_mbus_fmt(struct v4l2_mbus_framefmt *mbus,
202 const struct ipu_image *image);
203 void imx_media_grp_id_to_sd_name(char *sd_name, int sz,
204 u32 grp_id, int ipu_id);
205 struct v4l2_subdev *
206 imx_media_find_subdev_by_fwnode(struct imx_media_dev *imxmd,
207 struct fwnode_handle *fwnode);
208 struct v4l2_subdev *
209 imx_media_find_subdev_by_devname(struct imx_media_dev *imxmd,
210 const char *devname);
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);
214 struct media_pad *
215 imx_media_pipeline_pad(struct media_entity *start_entity, u32 grp_id,
216 enum v4l2_buf_type buftype, bool upstream);
217 struct v4l2_subdev *
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);
224
225 struct imx_media_dma_buf {
226 void *virt;
227 dma_addr_t phys;
228 unsigned long len;
229 };
230
231 void imx_media_free_dma_buf(struct device *dev,
232 struct imx_media_dma_buf *buf);
233 int imx_media_alloc_dma_buf(struct device *dev,
234 struct imx_media_dma_buf *buf,
235 int size);
236
237 int imx_media_pipeline_set_stream(struct imx_media_dev *imxmd,
238 struct media_entity *entity,
239 bool on);
240
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);
247
248 /* imx-media-fim.c */
249 struct imx_media_fim;
250 void imx_media_fim_eof_monitor(struct imx_media_fim *fim, ktime_t timestamp);
251 int imx_media_fim_set_stream(struct imx_media_fim *fim,
252 const struct v4l2_fract *frame_interval,
253 bool on);
254 int imx_media_fim_add_controls(struct imx_media_fim *fim);
255 struct imx_media_fim *imx_media_fim_init(struct v4l2_subdev *sd);
256 void imx_media_fim_free(struct imx_media_fim *fim);
257
258 /* imx-media-internal-sd.c */
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);
262
263 /* imx-media-of.c */
264 int imx_media_add_of_subdevs(struct imx_media_dev *dev,
265 struct device_node *np);
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);
282
283 /* imx-media-capture.c */
284 struct imx_media_video_dev *
285 imx_media_capture_device_init(struct device *dev, struct v4l2_subdev *src_sd,
286 int pad);
287 void imx_media_capture_device_remove(struct imx_media_video_dev *vdev);
288 int imx_media_capture_device_register(struct imx_media_video_dev *vdev);
289 void imx_media_capture_device_unregister(struct imx_media_video_dev *vdev);
290 struct imx_media_buffer *
291 imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev);
292 void imx_media_capture_device_error(struct imx_media_video_dev *vdev);
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
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
314