GNU Linux-libre 4.19.281-gnu1
[releases.git] / drivers / media / platform / qcom / camss / camss-video.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * camss-video.c
4  *
5  * Qualcomm MSM Camera Subsystem - V4L2 device node
6  *
7  * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
8  * Copyright (C) 2015-2018 Linaro Ltd.
9  */
10 #include <linux/slab.h>
11 #include <media/media-entity.h>
12 #include <media/v4l2-dev.h>
13 #include <media/v4l2-device.h>
14 #include <media/v4l2-ioctl.h>
15 #include <media/v4l2-mc.h>
16 #include <media/videobuf2-dma-sg.h>
17
18 #include "camss-video.h"
19 #include "camss.h"
20
21 struct fract {
22         u8 numerator;
23         u8 denominator;
24 };
25
26 /*
27  * struct camss_format_info - ISP media bus format information
28  * @code: V4L2 media bus format code
29  * @pixelformat: V4L2 pixel format FCC identifier
30  * @planes: Number of planes
31  * @hsub: Horizontal subsampling (for each plane)
32  * @vsub: Vertical subsampling (for each plane)
33  * @bpp: Bits per pixel when stored in memory (for each plane)
34  */
35 struct camss_format_info {
36         u32 code;
37         u32 pixelformat;
38         u8 planes;
39         struct fract hsub[3];
40         struct fract vsub[3];
41         unsigned int bpp[3];
42 };
43
44 static const struct camss_format_info formats_rdi_8x16[] = {
45         { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_UYVY, 1,
46           { { 1, 1 } }, { { 1, 1 } }, { 16 } },
47         { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_VYUY, 1,
48           { { 1, 1 } }, { { 1, 1 } }, { 16 } },
49         { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1,
50           { { 1, 1 } }, { { 1, 1 } }, { 16 } },
51         { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_YVYU, 1,
52           { { 1, 1 } }, { { 1, 1 } }, { 16 } },
53         { MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 1,
54           { { 1, 1 } }, { { 1, 1 } }, { 8 } },
55         { MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 1,
56           { { 1, 1 } }, { { 1, 1 } }, { 8 } },
57         { MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 1,
58           { { 1, 1 } }, { { 1, 1 } }, { 8 } },
59         { MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 1,
60           { { 1, 1 } }, { { 1, 1 } }, { 8 } },
61         { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10P, 1,
62           { { 1, 1 } }, { { 1, 1 } }, { 10 } },
63         { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10P, 1,
64           { { 1, 1 } }, { { 1, 1 } }, { 10 } },
65         { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10P, 1,
66           { { 1, 1 } }, { { 1, 1 } }, { 10 } },
67         { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10P, 1,
68           { { 1, 1 } }, { { 1, 1 } }, { 10 } },
69         { MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12P, 1,
70           { { 1, 1 } }, { { 1, 1 } }, { 12 } },
71         { MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12P, 1,
72           { { 1, 1 } }, { { 1, 1 } }, { 12 } },
73         { MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12P, 1,
74           { { 1, 1 } }, { { 1, 1 } }, { 12 } },
75         { MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12P, 1,
76           { { 1, 1 } }, { { 1, 1 } }, { 12 } },
77         { MEDIA_BUS_FMT_Y10_1X10, V4L2_PIX_FMT_Y10P, 1,
78           { { 1, 1 } }, { { 1, 1 } }, { 10 } },
79 };
80
81 static const struct camss_format_info formats_rdi_8x96[] = {
82         { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_UYVY, 1,
83           { { 1, 1 } }, { { 1, 1 } }, { 16 } },
84         { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_VYUY, 1,
85           { { 1, 1 } }, { { 1, 1 } }, { 16 } },
86         { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1,
87           { { 1, 1 } }, { { 1, 1 } }, { 16 } },
88         { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_YVYU, 1,
89           { { 1, 1 } }, { { 1, 1 } }, { 16 } },
90         { MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 1,
91           { { 1, 1 } }, { { 1, 1 } }, { 8 } },
92         { MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 1,
93           { { 1, 1 } }, { { 1, 1 } }, { 8 } },
94         { MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 1,
95           { { 1, 1 } }, { { 1, 1 } }, { 8 } },
96         { MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 1,
97           { { 1, 1 } }, { { 1, 1 } }, { 8 } },
98         { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10P, 1,
99           { { 1, 1 } }, { { 1, 1 } }, { 10 } },
100         { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10P, 1,
101           { { 1, 1 } }, { { 1, 1 } }, { 10 } },
102         { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10P, 1,
103           { { 1, 1 } }, { { 1, 1 } }, { 10 } },
104         { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10P, 1,
105           { { 1, 1 } }, { { 1, 1 } }, { 10 } },
106         { MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_PIX_FMT_SBGGR10, 1,
107           { { 1, 1 } }, { { 1, 1 } }, { 16 } },
108         { MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12P, 1,
109           { { 1, 1 } }, { { 1, 1 } }, { 12 } },
110         { MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12P, 1,
111           { { 1, 1 } }, { { 1, 1 } }, { 12 } },
112         { MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12P, 1,
113           { { 1, 1 } }, { { 1, 1 } }, { 12 } },
114         { MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12P, 1,
115           { { 1, 1 } }, { { 1, 1 } }, { 12 } },
116         { MEDIA_BUS_FMT_SBGGR14_1X14, V4L2_PIX_FMT_SBGGR14P, 1,
117           { { 1, 1 } }, { { 1, 1 } }, { 14 } },
118         { MEDIA_BUS_FMT_SGBRG14_1X14, V4L2_PIX_FMT_SGBRG14P, 1,
119           { { 1, 1 } }, { { 1, 1 } }, { 14 } },
120         { MEDIA_BUS_FMT_SGRBG14_1X14, V4L2_PIX_FMT_SGRBG14P, 1,
121           { { 1, 1 } }, { { 1, 1 } }, { 14 } },
122         { MEDIA_BUS_FMT_SRGGB14_1X14, V4L2_PIX_FMT_SRGGB14P, 1,
123           { { 1, 1 } }, { { 1, 1 } }, { 14 } },
124         { MEDIA_BUS_FMT_Y10_1X10, V4L2_PIX_FMT_Y10P, 1,
125           { { 1, 1 } }, { { 1, 1 } }, { 10 } },
126         { MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, V4L2_PIX_FMT_Y10, 1,
127           { { 1, 1 } }, { { 1, 1 } }, { 16 } },
128 };
129
130 static const struct camss_format_info formats_pix_8x16[] = {
131         { MEDIA_BUS_FMT_YUYV8_1_5X8, V4L2_PIX_FMT_NV12, 1,
132           { { 1, 1 } }, { { 2, 3 } }, { 8 } },
133         { MEDIA_BUS_FMT_YVYU8_1_5X8, V4L2_PIX_FMT_NV12, 1,
134           { { 1, 1 } }, { { 2, 3 } }, { 8 } },
135         { MEDIA_BUS_FMT_UYVY8_1_5X8, V4L2_PIX_FMT_NV12, 1,
136           { { 1, 1 } }, { { 2, 3 } }, { 8 } },
137         { MEDIA_BUS_FMT_VYUY8_1_5X8, V4L2_PIX_FMT_NV12, 1,
138           { { 1, 1 } }, { { 2, 3 } }, { 8 } },
139         { MEDIA_BUS_FMT_YUYV8_1_5X8, V4L2_PIX_FMT_NV21, 1,
140           { { 1, 1 } }, { { 2, 3 } }, { 8 } },
141         { MEDIA_BUS_FMT_YVYU8_1_5X8, V4L2_PIX_FMT_NV21, 1,
142           { { 1, 1 } }, { { 2, 3 } }, { 8 } },
143         { MEDIA_BUS_FMT_UYVY8_1_5X8, V4L2_PIX_FMT_NV21, 1,
144           { { 1, 1 } }, { { 2, 3 } }, { 8 } },
145         { MEDIA_BUS_FMT_VYUY8_1_5X8, V4L2_PIX_FMT_NV21, 1,
146           { { 1, 1 } }, { { 2, 3 } }, { 8 } },
147         { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_NV16, 1,
148           { { 1, 1 } }, { { 1, 2 } }, { 8 } },
149         { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_NV16, 1,
150           { { 1, 1 } }, { { 1, 2 } }, { 8 } },
151         { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_NV16, 1,
152           { { 1, 1 } }, { { 1, 2 } }, { 8 } },
153         { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_NV16, 1,
154           { { 1, 1 } }, { { 1, 2 } }, { 8 } },
155         { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_NV61, 1,
156           { { 1, 1 } }, { { 1, 2 } }, { 8 } },
157         { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_NV61, 1,
158           { { 1, 1 } }, { { 1, 2 } }, { 8 } },
159         { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_NV61, 1,
160           { { 1, 1 } }, { { 1, 2 } }, { 8 } },
161         { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_NV61, 1,
162           { { 1, 1 } }, { { 1, 2 } }, { 8 } },
163 };
164
165 static const struct camss_format_info formats_pix_8x96[] = {
166         { MEDIA_BUS_FMT_YUYV8_1_5X8, V4L2_PIX_FMT_NV12, 1,
167           { { 1, 1 } }, { { 2, 3 } }, { 8 } },
168         { MEDIA_BUS_FMT_YVYU8_1_5X8, V4L2_PIX_FMT_NV12, 1,
169           { { 1, 1 } }, { { 2, 3 } }, { 8 } },
170         { MEDIA_BUS_FMT_UYVY8_1_5X8, V4L2_PIX_FMT_NV12, 1,
171           { { 1, 1 } }, { { 2, 3 } }, { 8 } },
172         { MEDIA_BUS_FMT_VYUY8_1_5X8, V4L2_PIX_FMT_NV12, 1,
173           { { 1, 1 } }, { { 2, 3 } }, { 8 } },
174         { MEDIA_BUS_FMT_YUYV8_1_5X8, V4L2_PIX_FMT_NV21, 1,
175           { { 1, 1 } }, { { 2, 3 } }, { 8 } },
176         { MEDIA_BUS_FMT_YVYU8_1_5X8, V4L2_PIX_FMT_NV21, 1,
177           { { 1, 1 } }, { { 2, 3 } }, { 8 } },
178         { MEDIA_BUS_FMT_UYVY8_1_5X8, V4L2_PIX_FMT_NV21, 1,
179           { { 1, 1 } }, { { 2, 3 } }, { 8 } },
180         { MEDIA_BUS_FMT_VYUY8_1_5X8, V4L2_PIX_FMT_NV21, 1,
181           { { 1, 1 } }, { { 2, 3 } }, { 8 } },
182         { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_NV16, 1,
183           { { 1, 1 } }, { { 1, 2 } }, { 8 } },
184         { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_NV16, 1,
185           { { 1, 1 } }, { { 1, 2 } }, { 8 } },
186         { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_NV16, 1,
187           { { 1, 1 } }, { { 1, 2 } }, { 8 } },
188         { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_NV16, 1,
189           { { 1, 1 } }, { { 1, 2 } }, { 8 } },
190         { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_NV61, 1,
191           { { 1, 1 } }, { { 1, 2 } }, { 8 } },
192         { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_NV61, 1,
193           { { 1, 1 } }, { { 1, 2 } }, { 8 } },
194         { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_NV61, 1,
195           { { 1, 1 } }, { { 1, 2 } }, { 8 } },
196         { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_NV61, 1,
197           { { 1, 1 } }, { { 1, 2 } }, { 8 } },
198         { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_UYVY, 1,
199           { { 1, 1 } }, { { 1, 1 } }, { 16 } },
200         { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_VYUY, 1,
201           { { 1, 1 } }, { { 1, 1 } }, { 16 } },
202         { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1,
203           { { 1, 1 } }, { { 1, 1 } }, { 16 } },
204         { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_YVYU, 1,
205           { { 1, 1 } }, { { 1, 1 } }, { 16 } },
206 };
207
208 /* -----------------------------------------------------------------------------
209  * Helper functions
210  */
211
212 static int video_find_format(u32 code, u32 pixelformat,
213                              const struct camss_format_info *formats,
214                              unsigned int nformats)
215 {
216         int i;
217
218         for (i = 0; i < nformats; i++) {
219                 if (formats[i].code == code &&
220                     formats[i].pixelformat == pixelformat)
221                         return i;
222         }
223
224         for (i = 0; i < nformats; i++)
225                 if (formats[i].code == code)
226                         return i;
227
228         WARN_ON(1);
229
230         return -EINVAL;
231 }
232
233 /*
234  * video_mbus_to_pix_mp - Convert v4l2_mbus_framefmt to v4l2_pix_format_mplane
235  * @mbus: v4l2_mbus_framefmt format (input)
236  * @pix: v4l2_pix_format_mplane format (output)
237  * @f: a pointer to formats array element to be used for the conversion
238  * @alignment: bytesperline alignment value
239  *
240  * Fill the output pix structure with information from the input mbus format.
241  *
242  * Return 0 on success or a negative error code otherwise
243  */
244 static int video_mbus_to_pix_mp(const struct v4l2_mbus_framefmt *mbus,
245                                 struct v4l2_pix_format_mplane *pix,
246                                 const struct camss_format_info *f,
247                                 unsigned int alignment)
248 {
249         unsigned int i;
250         u32 bytesperline;
251
252         memset(pix, 0, sizeof(*pix));
253         v4l2_fill_pix_format_mplane(pix, mbus);
254         pix->pixelformat = f->pixelformat;
255         pix->num_planes = f->planes;
256         for (i = 0; i < pix->num_planes; i++) {
257                 bytesperline = pix->width / f->hsub[i].numerator *
258                         f->hsub[i].denominator * f->bpp[i] / 8;
259                 bytesperline = ALIGN(bytesperline, alignment);
260                 pix->plane_fmt[i].bytesperline = bytesperline;
261                 pix->plane_fmt[i].sizeimage = pix->height /
262                                 f->vsub[i].numerator * f->vsub[i].denominator *
263                                 bytesperline;
264         }
265
266         return 0;
267 }
268
269 static struct v4l2_subdev *video_remote_subdev(struct camss_video *video,
270                                                u32 *pad)
271 {
272         struct media_pad *remote;
273
274         remote = media_entity_remote_pad(&video->pad);
275
276         if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
277                 return NULL;
278
279         if (pad)
280                 *pad = remote->index;
281
282         return media_entity_to_v4l2_subdev(remote->entity);
283 }
284
285 static int video_get_subdev_format(struct camss_video *video,
286                                    struct v4l2_format *format)
287 {
288         struct v4l2_subdev_format fmt;
289         struct v4l2_subdev *subdev;
290         u32 pad;
291         int ret;
292
293         subdev = video_remote_subdev(video, &pad);
294         if (subdev == NULL)
295                 return -EPIPE;
296
297         fmt.pad = pad;
298         fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
299
300         ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
301         if (ret)
302                 return ret;
303
304         ret = video_find_format(fmt.format.code,
305                                 format->fmt.pix_mp.pixelformat,
306                                 video->formats, video->nformats);
307         if (ret < 0)
308                 return ret;
309
310         format->type = video->type;
311
312         return video_mbus_to_pix_mp(&fmt.format, &format->fmt.pix_mp,
313                                     &video->formats[ret], video->bpl_alignment);
314 }
315
316 /* -----------------------------------------------------------------------------
317  * Video queue operations
318  */
319
320 static int video_queue_setup(struct vb2_queue *q,
321         unsigned int *num_buffers, unsigned int *num_planes,
322         unsigned int sizes[], struct device *alloc_devs[])
323 {
324         struct camss_video *video = vb2_get_drv_priv(q);
325         const struct v4l2_pix_format_mplane *format =
326                                                 &video->active_fmt.fmt.pix_mp;
327         unsigned int i;
328
329         if (*num_planes) {
330                 if (*num_planes != format->num_planes)
331                         return -EINVAL;
332
333                 for (i = 0; i < *num_planes; i++)
334                         if (sizes[i] < format->plane_fmt[i].sizeimage)
335                                 return -EINVAL;
336
337                 return 0;
338         }
339
340         *num_planes = format->num_planes;
341
342         for (i = 0; i < *num_planes; i++)
343                 sizes[i] = format->plane_fmt[i].sizeimage;
344
345         return 0;
346 }
347
348 static int video_buf_init(struct vb2_buffer *vb)
349 {
350         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
351         struct camss_video *video = vb2_get_drv_priv(vb->vb2_queue);
352         struct camss_buffer *buffer = container_of(vbuf, struct camss_buffer,
353                                                    vb);
354         const struct v4l2_pix_format_mplane *format =
355                                                 &video->active_fmt.fmt.pix_mp;
356         struct sg_table *sgt;
357         unsigned int i;
358
359         for (i = 0; i < format->num_planes; i++) {
360                 sgt = vb2_dma_sg_plane_desc(vb, i);
361                 if (!sgt)
362                         return -EFAULT;
363
364                 buffer->addr[i] = sg_dma_address(sgt->sgl);
365         }
366
367         if (format->pixelformat == V4L2_PIX_FMT_NV12 ||
368                         format->pixelformat == V4L2_PIX_FMT_NV21 ||
369                         format->pixelformat == V4L2_PIX_FMT_NV16 ||
370                         format->pixelformat == V4L2_PIX_FMT_NV61)
371                 buffer->addr[1] = buffer->addr[0] +
372                                 format->plane_fmt[0].bytesperline *
373                                 format->height;
374
375         return 0;
376 }
377
378 static int video_buf_prepare(struct vb2_buffer *vb)
379 {
380         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
381         struct camss_video *video = vb2_get_drv_priv(vb->vb2_queue);
382         const struct v4l2_pix_format_mplane *format =
383                                                 &video->active_fmt.fmt.pix_mp;
384         unsigned int i;
385
386         for (i = 0; i < format->num_planes; i++) {
387                 if (format->plane_fmt[i].sizeimage > vb2_plane_size(vb, i))
388                         return -EINVAL;
389
390                 vb2_set_plane_payload(vb, i, format->plane_fmt[i].sizeimage);
391         }
392
393         vbuf->field = V4L2_FIELD_NONE;
394
395         return 0;
396 }
397
398 static void video_buf_queue(struct vb2_buffer *vb)
399 {
400         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
401         struct camss_video *video = vb2_get_drv_priv(vb->vb2_queue);
402         struct camss_buffer *buffer = container_of(vbuf, struct camss_buffer,
403                                                    vb);
404
405         video->ops->queue_buffer(video, buffer);
406 }
407
408 static int video_check_format(struct camss_video *video)
409 {
410         struct v4l2_pix_format_mplane *pix = &video->active_fmt.fmt.pix_mp;
411         struct v4l2_format format;
412         struct v4l2_pix_format_mplane *sd_pix = &format.fmt.pix_mp;
413         int ret;
414
415         sd_pix->pixelformat = pix->pixelformat;
416         ret = video_get_subdev_format(video, &format);
417         if (ret < 0)
418                 return ret;
419
420         if (pix->pixelformat != sd_pix->pixelformat ||
421             pix->height != sd_pix->height ||
422             pix->width != sd_pix->width ||
423             pix->num_planes != sd_pix->num_planes ||
424             pix->field != format.fmt.pix_mp.field)
425                 return -EPIPE;
426
427         return 0;
428 }
429
430 static int video_start_streaming(struct vb2_queue *q, unsigned int count)
431 {
432         struct camss_video *video = vb2_get_drv_priv(q);
433         struct video_device *vdev = &video->vdev;
434         struct media_entity *entity;
435         struct media_pad *pad;
436         struct v4l2_subdev *subdev;
437         int ret;
438
439         ret = media_pipeline_start(&vdev->entity, &video->pipe);
440         if (ret < 0)
441                 goto flush_buffers;
442
443         ret = video_check_format(video);
444         if (ret < 0)
445                 goto error;
446
447         entity = &vdev->entity;
448         while (1) {
449                 pad = &entity->pads[0];
450                 if (!(pad->flags & MEDIA_PAD_FL_SINK))
451                         break;
452
453                 pad = media_entity_remote_pad(pad);
454                 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
455                         break;
456
457                 entity = pad->entity;
458                 subdev = media_entity_to_v4l2_subdev(entity);
459
460                 ret = v4l2_subdev_call(subdev, video, s_stream, 1);
461                 if (ret < 0 && ret != -ENOIOCTLCMD)
462                         goto error;
463         }
464
465         return 0;
466
467 error:
468         media_pipeline_stop(&vdev->entity);
469
470 flush_buffers:
471         video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED);
472
473         return ret;
474 }
475
476 static void video_stop_streaming(struct vb2_queue *q)
477 {
478         struct camss_video *video = vb2_get_drv_priv(q);
479         struct video_device *vdev = &video->vdev;
480         struct media_entity *entity;
481         struct media_pad *pad;
482         struct v4l2_subdev *subdev;
483
484         entity = &vdev->entity;
485         while (1) {
486                 pad = &entity->pads[0];
487                 if (!(pad->flags & MEDIA_PAD_FL_SINK))
488                         break;
489
490                 pad = media_entity_remote_pad(pad);
491                 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
492                         break;
493
494                 entity = pad->entity;
495                 subdev = media_entity_to_v4l2_subdev(entity);
496
497                 v4l2_subdev_call(subdev, video, s_stream, 0);
498         }
499
500         media_pipeline_stop(&vdev->entity);
501
502         video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
503 }
504
505 static const struct vb2_ops msm_video_vb2_q_ops = {
506         .queue_setup     = video_queue_setup,
507         .wait_prepare    = vb2_ops_wait_prepare,
508         .wait_finish     = vb2_ops_wait_finish,
509         .buf_init        = video_buf_init,
510         .buf_prepare     = video_buf_prepare,
511         .buf_queue       = video_buf_queue,
512         .start_streaming = video_start_streaming,
513         .stop_streaming  = video_stop_streaming,
514 };
515
516 /* -----------------------------------------------------------------------------
517  * V4L2 ioctls
518  */
519
520 static int video_querycap(struct file *file, void *fh,
521                           struct v4l2_capability *cap)
522 {
523         struct camss_video *video = video_drvdata(file);
524
525         strlcpy(cap->driver, "qcom-camss", sizeof(cap->driver));
526         strlcpy(cap->card, "Qualcomm Camera Subsystem", sizeof(cap->card));
527         snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
528                  dev_name(video->camss->dev));
529
530         return 0;
531 }
532
533 static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
534 {
535         struct camss_video *video = video_drvdata(file);
536         int i, j, k;
537
538         if (f->type != video->type)
539                 return -EINVAL;
540
541         if (f->index >= video->nformats)
542                 return -EINVAL;
543
544         /* find index "i" of "k"th unique pixelformat in formats array */
545         k = -1;
546         for (i = 0; i < video->nformats; i++) {
547                 for (j = 0; j < i; j++) {
548                         if (video->formats[i].pixelformat ==
549                                         video->formats[j].pixelformat)
550                                 break;
551                 }
552
553                 if (j == i)
554                         k++;
555
556                 if (k == f->index)
557                         break;
558         }
559
560         if (k < f->index)
561                 return -EINVAL;
562
563         f->pixelformat = video->formats[i].pixelformat;
564
565         return 0;
566 }
567
568 static int video_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
569 {
570         struct camss_video *video = video_drvdata(file);
571
572         *f = video->active_fmt;
573
574         return 0;
575 }
576
577 static int __video_try_fmt(struct camss_video *video, struct v4l2_format *f)
578 {
579         struct v4l2_pix_format_mplane *pix_mp;
580         const struct camss_format_info *fi;
581         struct v4l2_plane_pix_format *p;
582         u32 bytesperline[3] = { 0 };
583         u32 sizeimage[3] = { 0 };
584         u32 width, height;
585         u32 bpl, lines;
586         int i, j;
587
588         pix_mp = &f->fmt.pix_mp;
589
590         if (video->line_based)
591                 for (i = 0; i < pix_mp->num_planes && i < 3; i++) {
592                         p = &pix_mp->plane_fmt[i];
593                         bytesperline[i] = clamp_t(u32, p->bytesperline,
594                                                   1, 65528);
595                         sizeimage[i] = clamp_t(u32, p->sizeimage,
596                                                bytesperline[i],
597                                                bytesperline[i] * 4096);
598                 }
599
600         for (j = 0; j < video->nformats; j++)
601                 if (pix_mp->pixelformat == video->formats[j].pixelformat)
602                         break;
603
604         if (j == video->nformats)
605                 j = 0; /* default format */
606
607         fi = &video->formats[j];
608         width = pix_mp->width;
609         height = pix_mp->height;
610
611         memset(pix_mp, 0, sizeof(*pix_mp));
612
613         pix_mp->pixelformat = fi->pixelformat;
614         pix_mp->width = clamp_t(u32, width, 1, 8191);
615         pix_mp->height = clamp_t(u32, height, 1, 8191);
616         pix_mp->num_planes = fi->planes;
617         for (i = 0; i < pix_mp->num_planes; i++) {
618                 bpl = pix_mp->width / fi->hsub[i].numerator *
619                         fi->hsub[i].denominator * fi->bpp[i] / 8;
620                 bpl = ALIGN(bpl, video->bpl_alignment);
621                 pix_mp->plane_fmt[i].bytesperline = bpl;
622                 pix_mp->plane_fmt[i].sizeimage = pix_mp->height /
623                         fi->vsub[i].numerator * fi->vsub[i].denominator * bpl;
624         }
625
626         pix_mp->field = V4L2_FIELD_NONE;
627         pix_mp->colorspace = V4L2_COLORSPACE_SRGB;
628         pix_mp->flags = 0;
629         pix_mp->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(pix_mp->colorspace);
630         pix_mp->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
631                                         pix_mp->colorspace, pix_mp->ycbcr_enc);
632         pix_mp->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(pix_mp->colorspace);
633
634         if (video->line_based)
635                 for (i = 0; i < pix_mp->num_planes; i++) {
636                         p = &pix_mp->plane_fmt[i];
637                         p->bytesperline = clamp_t(u32, p->bytesperline,
638                                                   1, 65528);
639                         p->sizeimage = clamp_t(u32, p->sizeimage,
640                                                p->bytesperline,
641                                                p->bytesperline * 4096);
642                         lines = p->sizeimage / p->bytesperline;
643
644                         if (p->bytesperline < bytesperline[i])
645                                 p->bytesperline = ALIGN(bytesperline[i], 8);
646
647                         if (p->sizeimage < p->bytesperline * lines)
648                                 p->sizeimage = p->bytesperline * lines;
649
650                         if (p->sizeimage < sizeimage[i])
651                                 p->sizeimage = sizeimage[i];
652                 }
653
654         return 0;
655 }
656
657 static int video_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
658 {
659         struct camss_video *video = video_drvdata(file);
660
661         return __video_try_fmt(video, f);
662 }
663
664 static int video_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
665 {
666         struct camss_video *video = video_drvdata(file);
667         int ret;
668
669         if (vb2_is_busy(&video->vb2_q))
670                 return -EBUSY;
671
672         ret = __video_try_fmt(video, f);
673         if (ret < 0)
674                 return ret;
675
676         video->active_fmt = *f;
677
678         return 0;
679 }
680
681 static int video_enum_input(struct file *file, void *fh,
682                             struct v4l2_input *input)
683 {
684         if (input->index > 0)
685                 return -EINVAL;
686
687         strlcpy(input->name, "camera", sizeof(input->name));
688         input->type = V4L2_INPUT_TYPE_CAMERA;
689
690         return 0;
691 }
692
693 static int video_g_input(struct file *file, void *fh, unsigned int *input)
694 {
695         *input = 0;
696
697         return 0;
698 }
699
700 static int video_s_input(struct file *file, void *fh, unsigned int input)
701 {
702         return input == 0 ? 0 : -EINVAL;
703 }
704
705 static const struct v4l2_ioctl_ops msm_vid_ioctl_ops = {
706         .vidioc_querycap                = video_querycap,
707         .vidioc_enum_fmt_vid_cap_mplane = video_enum_fmt,
708         .vidioc_g_fmt_vid_cap_mplane    = video_g_fmt,
709         .vidioc_s_fmt_vid_cap_mplane    = video_s_fmt,
710         .vidioc_try_fmt_vid_cap_mplane  = video_try_fmt,
711         .vidioc_reqbufs                 = vb2_ioctl_reqbufs,
712         .vidioc_querybuf                = vb2_ioctl_querybuf,
713         .vidioc_qbuf                    = vb2_ioctl_qbuf,
714         .vidioc_expbuf                  = vb2_ioctl_expbuf,
715         .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
716         .vidioc_create_bufs             = vb2_ioctl_create_bufs,
717         .vidioc_prepare_buf             = vb2_ioctl_prepare_buf,
718         .vidioc_streamon                = vb2_ioctl_streamon,
719         .vidioc_streamoff               = vb2_ioctl_streamoff,
720         .vidioc_enum_input              = video_enum_input,
721         .vidioc_g_input                 = video_g_input,
722         .vidioc_s_input                 = video_s_input,
723 };
724
725 /* -----------------------------------------------------------------------------
726  * V4L2 file operations
727  */
728
729 static int video_open(struct file *file)
730 {
731         struct video_device *vdev = video_devdata(file);
732         struct camss_video *video = video_drvdata(file);
733         struct v4l2_fh *vfh;
734         int ret;
735
736         mutex_lock(&video->lock);
737
738         vfh = kzalloc(sizeof(*vfh), GFP_KERNEL);
739         if (vfh == NULL) {
740                 ret = -ENOMEM;
741                 goto error_alloc;
742         }
743
744         v4l2_fh_init(vfh, vdev);
745         v4l2_fh_add(vfh);
746
747         file->private_data = vfh;
748
749         ret = v4l2_pipeline_pm_use(&vdev->entity, 1);
750         if (ret < 0) {
751                 dev_err(video->camss->dev, "Failed to power up pipeline: %d\n",
752                         ret);
753                 goto error_pm_use;
754         }
755
756         mutex_unlock(&video->lock);
757
758         return 0;
759
760 error_pm_use:
761         v4l2_fh_release(file);
762
763 error_alloc:
764         mutex_unlock(&video->lock);
765
766         return ret;
767 }
768
769 static int video_release(struct file *file)
770 {
771         struct video_device *vdev = video_devdata(file);
772
773         vb2_fop_release(file);
774
775         v4l2_pipeline_pm_use(&vdev->entity, 0);
776
777         file->private_data = NULL;
778
779         return 0;
780 }
781
782 static const struct v4l2_file_operations msm_vid_fops = {
783         .owner          = THIS_MODULE,
784         .unlocked_ioctl = video_ioctl2,
785         .open           = video_open,
786         .release        = video_release,
787         .poll           = vb2_fop_poll,
788         .mmap           = vb2_fop_mmap,
789         .read           = vb2_fop_read,
790 };
791
792 /* -----------------------------------------------------------------------------
793  * CAMSS video core
794  */
795
796 static void msm_video_release(struct video_device *vdev)
797 {
798         struct camss_video *video = video_get_drvdata(vdev);
799
800         media_entity_cleanup(&vdev->entity);
801
802         mutex_destroy(&video->q_lock);
803         mutex_destroy(&video->lock);
804
805         if (atomic_dec_and_test(&video->camss->ref_count))
806                 camss_delete(video->camss);
807 }
808
809 /*
810  * msm_video_init_format - Helper function to initialize format
811  * @video: struct camss_video
812  *
813  * Initialize pad format with default value.
814  *
815  * Return 0 on success or a negative error code otherwise
816  */
817 static int msm_video_init_format(struct camss_video *video)
818 {
819         int ret;
820         struct v4l2_format format = {
821                 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
822                 .fmt.pix_mp = {
823                         .width = 1920,
824                         .height = 1080,
825                         .pixelformat = video->formats[0].pixelformat,
826                 },
827         };
828
829         ret = __video_try_fmt(video, &format);
830         if (ret < 0)
831                 return ret;
832
833         video->active_fmt = format;
834
835         return 0;
836 }
837
838 /*
839  * msm_video_register - Register a video device node
840  * @video: struct camss_video
841  * @v4l2_dev: V4L2 device
842  * @name: name to be used for the video device node
843  *
844  * Initialize and register a video device node to a V4L2 device. Also
845  * initialize the vb2 queue.
846  *
847  * Return 0 on success or a negative error code otherwise
848  */
849
850 int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev,
851                        const char *name, int is_pix)
852 {
853         struct media_pad *pad = &video->pad;
854         struct video_device *vdev;
855         struct vb2_queue *q;
856         int ret;
857
858         vdev = &video->vdev;
859
860         mutex_init(&video->q_lock);
861
862         q = &video->vb2_q;
863         q->drv_priv = video;
864         q->mem_ops = &vb2_dma_sg_memops;
865         q->ops = &msm_video_vb2_q_ops;
866         q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
867         q->io_modes = VB2_DMABUF | VB2_MMAP | VB2_READ;
868         q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
869         q->buf_struct_size = sizeof(struct camss_buffer);
870         q->dev = video->camss->dev;
871         q->lock = &video->q_lock;
872         ret = vb2_queue_init(q);
873         if (ret < 0) {
874                 dev_err(v4l2_dev->dev, "Failed to init vb2 queue: %d\n", ret);
875                 goto error_vb2_init;
876         }
877
878         pad->flags = MEDIA_PAD_FL_SINK;
879         ret = media_entity_pads_init(&vdev->entity, 1, pad);
880         if (ret < 0) {
881                 dev_err(v4l2_dev->dev, "Failed to init video entity: %d\n",
882                         ret);
883                 goto error_media_init;
884         }
885
886         mutex_init(&video->lock);
887
888         if (video->camss->version == CAMSS_8x16) {
889                 if (is_pix) {
890                         video->formats = formats_pix_8x16;
891                         video->nformats = ARRAY_SIZE(formats_pix_8x16);
892                 } else {
893                         video->formats = formats_rdi_8x16;
894                         video->nformats = ARRAY_SIZE(formats_rdi_8x16);
895                 }
896         } else if (video->camss->version == CAMSS_8x96) {
897                 if (is_pix) {
898                         video->formats = formats_pix_8x96;
899                         video->nformats = ARRAY_SIZE(formats_pix_8x96);
900                 } else {
901                         video->formats = formats_rdi_8x96;
902                         video->nformats = ARRAY_SIZE(formats_rdi_8x96);
903                 }
904         } else {
905                 ret = -EINVAL;
906                 goto error_video_register;
907         }
908
909         ret = msm_video_init_format(video);
910         if (ret < 0) {
911                 dev_err(v4l2_dev->dev, "Failed to init format: %d\n", ret);
912                 goto error_video_register;
913         }
914
915         vdev->fops = &msm_vid_fops;
916         vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING |
917                                                         V4L2_CAP_READWRITE;
918         vdev->ioctl_ops = &msm_vid_ioctl_ops;
919         vdev->release = msm_video_release;
920         vdev->v4l2_dev = v4l2_dev;
921         vdev->vfl_dir = VFL_DIR_RX;
922         vdev->queue = &video->vb2_q;
923         vdev->lock = &video->lock;
924         strlcpy(vdev->name, name, sizeof(vdev->name));
925
926         ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
927         if (ret < 0) {
928                 dev_err(v4l2_dev->dev, "Failed to register video device: %d\n",
929                         ret);
930                 goto error_video_register;
931         }
932
933         video_set_drvdata(vdev, video);
934         atomic_inc(&video->camss->ref_count);
935
936         return 0;
937
938 error_video_register:
939         media_entity_cleanup(&vdev->entity);
940         mutex_destroy(&video->lock);
941 error_media_init:
942         vb2_queue_release(&video->vb2_q);
943 error_vb2_init:
944         mutex_destroy(&video->q_lock);
945
946         return ret;
947 }
948
949 void msm_video_stop_streaming(struct camss_video *video)
950 {
951         if (vb2_is_streaming(&video->vb2_q))
952                 vb2_queue_release(&video->vb2_q);
953 }
954
955 void msm_video_unregister(struct camss_video *video)
956 {
957         atomic_inc(&video->camss->ref_count);
958         video_unregister_device(&video->vdev);
959         atomic_dec(&video->camss->ref_count);
960 }