]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - drivers/media/pci/intel/ipu-isys-video.c
UBUNTU: SAUCE: IPU6 driver release for kernel 5.13
[mirror_ubuntu-jammy-kernel.git] / drivers / media / pci / intel / ipu-isys-video.c
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2013 - 2021 Intel Corporation
3
4 #include <linux/delay.h>
5 #include <linux/firmware.h>
6 #include <linux/init_task.h>
7 #include <linux/kthread.h>
8 #include <linux/pm_runtime.h>
9 #include <linux/module.h>
10 #include <linux/version.h>
11 #include <linux/compat.h>
12
13 #include <uapi/linux/sched/types.h>
14
15 #include <media/media-entity.h>
16 #include <media/v4l2-device.h>
17 #include <media/v4l2-ioctl.h>
18 #include <media/v4l2-mc.h>
19
20 #include "ipu.h"
21 #include "ipu-bus.h"
22 #include "ipu-cpd.h"
23 #include "ipu-isys.h"
24 #include "ipu-isys-video.h"
25 #include "ipu-platform.h"
26 #include "ipu-platform-regs.h"
27 #include "ipu-platform-buttress-regs.h"
28 #include "ipu-trace.h"
29 #include "ipu-fw-isys.h"
30 #include "ipu-fw-com.h"
31
32 /* use max resolution pixel rate by default */
33 #define DEFAULT_PIXEL_RATE (360000000ULL * 2 * 4 / 10)
34
35 const struct ipu_isys_pixelformat ipu_isys_pfmts_be_soc[] = {
36 {V4L2_PIX_FMT_Y10, 16, 10, 0, MEDIA_BUS_FMT_Y10_1X10,
37 IPU_FW_ISYS_FRAME_FORMAT_RAW16},
38 {V4L2_PIX_FMT_UYVY, 16, 16, 0, MEDIA_BUS_FMT_UYVY8_1X16,
39 IPU_FW_ISYS_FRAME_FORMAT_UYVY},
40 {V4L2_PIX_FMT_YUYV, 16, 16, 0, MEDIA_BUS_FMT_YUYV8_1X16,
41 IPU_FW_ISYS_FRAME_FORMAT_YUYV},
42 {V4L2_PIX_FMT_NV16, 16, 16, 8, MEDIA_BUS_FMT_UYVY8_1X16,
43 IPU_FW_ISYS_FRAME_FORMAT_NV16},
44 {V4L2_PIX_FMT_XRGB32, 32, 32, 0, MEDIA_BUS_FMT_RGB565_1X16,
45 IPU_FW_ISYS_FRAME_FORMAT_RGBA888},
46 {V4L2_PIX_FMT_XBGR32, 32, 32, 0, MEDIA_BUS_FMT_RGB888_1X24,
47 IPU_FW_ISYS_FRAME_FORMAT_RGBA888},
48 /* Raw bayer formats. */
49 {V4L2_PIX_FMT_SBGGR12, 16, 12, 0, MEDIA_BUS_FMT_SBGGR12_1X12,
50 IPU_FW_ISYS_FRAME_FORMAT_RAW16},
51 {V4L2_PIX_FMT_SGBRG12, 16, 12, 0, MEDIA_BUS_FMT_SGBRG12_1X12,
52 IPU_FW_ISYS_FRAME_FORMAT_RAW16},
53 {V4L2_PIX_FMT_SGRBG12, 16, 12, 0, MEDIA_BUS_FMT_SGRBG12_1X12,
54 IPU_FW_ISYS_FRAME_FORMAT_RAW16},
55 {V4L2_PIX_FMT_SRGGB12, 16, 12, 0, MEDIA_BUS_FMT_SRGGB12_1X12,
56 IPU_FW_ISYS_FRAME_FORMAT_RAW16},
57 {V4L2_PIX_FMT_SBGGR10, 16, 10, 0, MEDIA_BUS_FMT_SBGGR10_1X10,
58 IPU_FW_ISYS_FRAME_FORMAT_RAW16},
59 {V4L2_PIX_FMT_SGBRG10, 16, 10, 0, MEDIA_BUS_FMT_SGBRG10_1X10,
60 IPU_FW_ISYS_FRAME_FORMAT_RAW16},
61 {V4L2_PIX_FMT_SGRBG10, 16, 10, 0, MEDIA_BUS_FMT_SGRBG10_1X10,
62 IPU_FW_ISYS_FRAME_FORMAT_RAW16},
63 {V4L2_PIX_FMT_SRGGB10, 16, 10, 0, MEDIA_BUS_FMT_SRGGB10_1X10,
64 IPU_FW_ISYS_FRAME_FORMAT_RAW16},
65 {V4L2_PIX_FMT_SBGGR8, 8, 8, 0, MEDIA_BUS_FMT_SBGGR8_1X8,
66 IPU_FW_ISYS_FRAME_FORMAT_RAW8},
67 {V4L2_PIX_FMT_SGBRG8, 8, 8, 0, MEDIA_BUS_FMT_SGBRG8_1X8,
68 IPU_FW_ISYS_FRAME_FORMAT_RAW8},
69 {V4L2_PIX_FMT_SGRBG8, 8, 8, 0, MEDIA_BUS_FMT_SGRBG8_1X8,
70 IPU_FW_ISYS_FRAME_FORMAT_RAW8},
71 {V4L2_PIX_FMT_SRGGB8, 8, 8, 0, MEDIA_BUS_FMT_SRGGB8_1X8,
72 IPU_FW_ISYS_FRAME_FORMAT_RAW8},
73 {}
74 };
75
76 const struct ipu_isys_pixelformat ipu_isys_pfmts_packed[] = {
77 {V4L2_PIX_FMT_Y10, 10, 10, 0, MEDIA_BUS_FMT_Y10_1X10,
78 IPU_FW_ISYS_FRAME_FORMAT_RAW10},
79 #ifdef V4L2_PIX_FMT_Y210
80 {V4L2_PIX_FMT_Y210, 20, 20, 0, MEDIA_BUS_FMT_YUYV10_1X20,
81 IPU_FW_ISYS_FRAME_FORMAT_YUYV},
82 #endif
83 {V4L2_PIX_FMT_UYVY, 16, 16, 0, MEDIA_BUS_FMT_UYVY8_1X16,
84 IPU_FW_ISYS_FRAME_FORMAT_UYVY},
85 {V4L2_PIX_FMT_YUYV, 16, 16, 0, MEDIA_BUS_FMT_YUYV8_1X16,
86 IPU_FW_ISYS_FRAME_FORMAT_YUYV},
87 {V4L2_PIX_FMT_RGB565, 16, 16, 0, MEDIA_BUS_FMT_RGB565_1X16,
88 IPU_FW_ISYS_FRAME_FORMAT_RGB565},
89 {V4L2_PIX_FMT_BGR24, 24, 24, 0, MEDIA_BUS_FMT_RGB888_1X24,
90 IPU_FW_ISYS_FRAME_FORMAT_RGBA888},
91 #ifndef V4L2_PIX_FMT_SBGGR12P
92 {V4L2_PIX_FMT_SBGGR12, 12, 12, 0, MEDIA_BUS_FMT_SBGGR12_1X12,
93 IPU_FW_ISYS_FRAME_FORMAT_RAW12},
94 {V4L2_PIX_FMT_SGBRG12, 12, 12, 0, MEDIA_BUS_FMT_SGBRG12_1X12,
95 IPU_FW_ISYS_FRAME_FORMAT_RAW12},
96 {V4L2_PIX_FMT_SGRBG12, 12, 12, 0, MEDIA_BUS_FMT_SGRBG12_1X12,
97 IPU_FW_ISYS_FRAME_FORMAT_RAW12},
98 {V4L2_PIX_FMT_SRGGB12, 12, 12, 0, MEDIA_BUS_FMT_SRGGB12_1X12,
99 IPU_FW_ISYS_FRAME_FORMAT_RAW12},
100 #else /* V4L2_PIX_FMT_SBGGR12P */
101 {V4L2_PIX_FMT_SBGGR12P, 12, 12, 0, MEDIA_BUS_FMT_SBGGR12_1X12,
102 IPU_FW_ISYS_FRAME_FORMAT_RAW12},
103 {V4L2_PIX_FMT_SGBRG12P, 12, 12, 0, MEDIA_BUS_FMT_SGBRG12_1X12,
104 IPU_FW_ISYS_FRAME_FORMAT_RAW12},
105 {V4L2_PIX_FMT_SGRBG12P, 12, 12, 0, MEDIA_BUS_FMT_SGRBG12_1X12,
106 IPU_FW_ISYS_FRAME_FORMAT_RAW12},
107 {V4L2_PIX_FMT_SRGGB12P, 12, 12, 0, MEDIA_BUS_FMT_SRGGB12_1X12,
108 IPU_FW_ISYS_FRAME_FORMAT_RAW12},
109 #endif /* V4L2_PIX_FMT_SBGGR12P */
110 {V4L2_PIX_FMT_SBGGR10P, 10, 10, 0, MEDIA_BUS_FMT_SBGGR10_1X10,
111 IPU_FW_ISYS_FRAME_FORMAT_RAW10},
112 {V4L2_PIX_FMT_SGBRG10P, 10, 10, 0, MEDIA_BUS_FMT_SGBRG10_1X10,
113 IPU_FW_ISYS_FRAME_FORMAT_RAW10},
114 {V4L2_PIX_FMT_SGRBG10P, 10, 10, 0, MEDIA_BUS_FMT_SGRBG10_1X10,
115 IPU_FW_ISYS_FRAME_FORMAT_RAW10},
116 {V4L2_PIX_FMT_SRGGB10P, 10, 10, 0, MEDIA_BUS_FMT_SRGGB10_1X10,
117 IPU_FW_ISYS_FRAME_FORMAT_RAW10},
118 {V4L2_PIX_FMT_SBGGR8, 8, 8, 0, MEDIA_BUS_FMT_SBGGR8_1X8,
119 IPU_FW_ISYS_FRAME_FORMAT_RAW8},
120 {V4L2_PIX_FMT_SGBRG8, 8, 8, 0, MEDIA_BUS_FMT_SGBRG8_1X8,
121 IPU_FW_ISYS_FRAME_FORMAT_RAW8},
122 {V4L2_PIX_FMT_SGRBG8, 8, 8, 0, MEDIA_BUS_FMT_SGRBG8_1X8,
123 IPU_FW_ISYS_FRAME_FORMAT_RAW8},
124 {V4L2_PIX_FMT_SRGGB8, 8, 8, 0, MEDIA_BUS_FMT_SRGGB8_1X8,
125 IPU_FW_ISYS_FRAME_FORMAT_RAW8},
126 {}
127 };
128
129 static int video_open(struct file *file)
130 {
131 struct ipu_isys_video *av = video_drvdata(file);
132 struct ipu_isys *isys = av->isys;
133 struct ipu_bus_device *adev = to_ipu_bus_device(&isys->adev->dev);
134 struct ipu_device *isp = adev->isp;
135 int rval;
136 const struct ipu_isys_internal_pdata *ipdata;
137
138 mutex_lock(&isys->mutex);
139
140 if (isys->reset_needed || isp->flr_done) {
141 mutex_unlock(&isys->mutex);
142 dev_warn(&isys->adev->dev, "isys power cycle required\n");
143 return -EIO;
144 }
145 mutex_unlock(&isys->mutex);
146
147 rval = pm_runtime_get_sync(&isys->adev->dev);
148 if (rval < 0) {
149 pm_runtime_put_noidle(&isys->adev->dev);
150 return rval;
151 }
152
153 rval = v4l2_fh_open(file);
154 if (rval)
155 goto out_power_down;
156
157 rval = v4l2_pipeline_pm_get(&av->vdev.entity);
158 if (rval)
159 goto out_v4l2_fh_release;
160
161 mutex_lock(&isys->mutex);
162
163 if (isys->video_opened++) {
164 /* Already open */
165 mutex_unlock(&isys->mutex);
166 return 0;
167 }
168
169 ipdata = isys->pdata->ipdata;
170 ipu_configure_spc(adev->isp,
171 &ipdata->hw_variant,
172 IPU_CPD_PKG_DIR_ISYS_SERVER_IDX,
173 isys->pdata->base, isys->pkg_dir,
174 isys->pkg_dir_dma_addr);
175
176 /*
177 * Buffers could have been left to wrong queue at last closure.
178 * Move them now back to empty buffer queue.
179 */
180 ipu_cleanup_fw_msg_bufs(isys);
181
182 if (isys->fwcom) {
183 /*
184 * Something went wrong in previous shutdown. As we are now
185 * restarting isys we can safely delete old context.
186 */
187 dev_err(&isys->adev->dev, "Clearing old context\n");
188 ipu_fw_isys_cleanup(isys);
189 }
190
191 rval = ipu_fw_isys_init(av->isys, ipdata->num_parallel_streams);
192 if (rval < 0)
193 goto out_lib_init;
194
195 mutex_unlock(&isys->mutex);
196
197 return 0;
198
199 out_lib_init:
200 isys->video_opened--;
201 mutex_unlock(&isys->mutex);
202 v4l2_pipeline_pm_put(&av->vdev.entity);
203
204 out_v4l2_fh_release:
205 v4l2_fh_release(file);
206 out_power_down:
207 pm_runtime_put(&isys->adev->dev);
208
209 return rval;
210 }
211
212 static int video_release(struct file *file)
213 {
214 struct ipu_isys_video *av = video_drvdata(file);
215 int ret = 0;
216
217 vb2_fop_release(file);
218
219 mutex_lock(&av->isys->mutex);
220
221 if (!--av->isys->video_opened) {
222 ipu_fw_isys_close(av->isys);
223 if (av->isys->fwcom) {
224 av->isys->reset_needed = true;
225 ret = -EIO;
226 }
227 }
228
229 mutex_unlock(&av->isys->mutex);
230
231 v4l2_pipeline_pm_put(&av->vdev.entity);
232
233 if (av->isys->reset_needed)
234 pm_runtime_put_sync(&av->isys->adev->dev);
235 else
236 pm_runtime_put(&av->isys->adev->dev);
237
238 return ret;
239 }
240
241 static struct media_pad *other_pad(struct media_pad *pad)
242 {
243 struct media_link *link;
244
245 list_for_each_entry(link, &pad->entity->links, list) {
246 if ((link->flags & MEDIA_LNK_FL_LINK_TYPE)
247 != MEDIA_LNK_FL_DATA_LINK)
248 continue;
249
250 return link->source == pad ? link->sink : link->source;
251 }
252
253 WARN_ON(1);
254 return NULL;
255 }
256
257 const struct ipu_isys_pixelformat *
258 ipu_isys_get_pixelformat(struct ipu_isys_video *av, u32 pixelformat)
259 {
260 struct media_pad *pad = other_pad(&av->vdev.entity.pads[0]);
261 struct v4l2_subdev *sd;
262 const u32 *supported_codes;
263 const struct ipu_isys_pixelformat *pfmt;
264
265 if (!pad || !pad->entity) {
266 WARN_ON(1);
267 return NULL;
268 }
269
270 sd = media_entity_to_v4l2_subdev(pad->entity);
271 supported_codes = to_ipu_isys_subdev(sd)->supported_codes[pad->index];
272
273 for (pfmt = av->pfmts; pfmt->bpp; pfmt++) {
274 unsigned int i;
275
276 if (pfmt->pixelformat != pixelformat)
277 continue;
278
279 for (i = 0; supported_codes[i]; i++) {
280 if (pfmt->code == supported_codes[i])
281 return pfmt;
282 }
283 }
284
285 /* Not found. Get the default, i.e. the first defined one. */
286 for (pfmt = av->pfmts; pfmt->bpp; pfmt++) {
287 if (pfmt->code == *supported_codes)
288 return pfmt;
289 }
290
291 WARN_ON(1);
292 return NULL;
293 }
294
295 int ipu_isys_vidioc_querycap(struct file *file, void *fh,
296 struct v4l2_capability *cap)
297 {
298 struct ipu_isys_video *av = video_drvdata(file);
299
300 strlcpy(cap->driver, IPU_ISYS_NAME, sizeof(cap->driver));
301 strlcpy(cap->card, av->isys->media_dev.model, sizeof(cap->card));
302 snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
303 av->isys->media_dev.bus_info);
304 return 0;
305 }
306
307 int ipu_isys_vidioc_enum_fmt(struct file *file, void *fh,
308 struct v4l2_fmtdesc *f)
309 {
310 struct ipu_isys_video *av = video_drvdata(file);
311 struct media_pad *pad = other_pad(&av->vdev.entity.pads[0]);
312 struct v4l2_subdev *sd;
313 const u32 *supported_codes;
314 const struct ipu_isys_pixelformat *pfmt;
315 u32 index;
316
317 if (!pad || !pad->entity)
318 return -EINVAL;
319 sd = media_entity_to_v4l2_subdev(pad->entity);
320 supported_codes = to_ipu_isys_subdev(sd)->supported_codes[pad->index];
321
322 /* Walk the 0-terminated array for the f->index-th code. */
323 for (index = f->index; *supported_codes && index;
324 index--, supported_codes++) {
325 };
326
327 if (!*supported_codes)
328 return -EINVAL;
329
330 f->flags = 0;
331
332 /* Code found */
333 for (pfmt = av->pfmts; pfmt->bpp; pfmt++)
334 if (pfmt->code == *supported_codes)
335 break;
336
337 if (!pfmt->bpp) {
338 dev_warn(&av->isys->adev->dev,
339 "Format not found in mapping table.");
340 return -EINVAL;
341 }
342
343 f->pixelformat = pfmt->pixelformat;
344
345 return 0;
346 }
347
348 static int vidioc_g_fmt_vid_cap_mplane(struct file *file, void *fh,
349 struct v4l2_format *fmt)
350 {
351 struct ipu_isys_video *av = video_drvdata(file);
352
353 fmt->fmt.pix_mp = av->mpix;
354
355 return 0;
356 }
357
358 const struct ipu_isys_pixelformat *
359 ipu_isys_video_try_fmt_vid_mplane_default(struct ipu_isys_video *av,
360 struct v4l2_pix_format_mplane *mpix)
361 {
362 return ipu_isys_video_try_fmt_vid_mplane(av, mpix, 0);
363 }
364
365 const struct ipu_isys_pixelformat *
366 ipu_isys_video_try_fmt_vid_mplane(struct ipu_isys_video *av,
367 struct v4l2_pix_format_mplane *mpix,
368 int store_csi2_header)
369 {
370 const struct ipu_isys_pixelformat *pfmt =
371 ipu_isys_get_pixelformat(av, mpix->pixelformat);
372
373 if (!pfmt)
374 return NULL;
375 mpix->pixelformat = pfmt->pixelformat;
376 mpix->num_planes = 1;
377
378 mpix->width = clamp(mpix->width, IPU_ISYS_MIN_WIDTH,
379 IPU_ISYS_MAX_WIDTH);
380 mpix->height = clamp(mpix->height, IPU_ISYS_MIN_HEIGHT,
381 IPU_ISYS_MAX_HEIGHT);
382
383 if (!av->packed)
384 mpix->plane_fmt[0].bytesperline =
385 mpix->width * DIV_ROUND_UP(pfmt->bpp_planar ?
386 pfmt->bpp_planar : pfmt->bpp,
387 BITS_PER_BYTE);
388 else if (store_csi2_header)
389 mpix->plane_fmt[0].bytesperline =
390 DIV_ROUND_UP(av->line_header_length +
391 av->line_footer_length +
392 (unsigned int)mpix->width * pfmt->bpp,
393 BITS_PER_BYTE);
394 else
395 mpix->plane_fmt[0].bytesperline =
396 DIV_ROUND_UP((unsigned int)mpix->width * pfmt->bpp,
397 BITS_PER_BYTE);
398
399 mpix->plane_fmt[0].bytesperline = ALIGN(mpix->plane_fmt[0].bytesperline,
400 av->isys->line_align);
401
402 if (pfmt->bpp_planar)
403 mpix->plane_fmt[0].bytesperline =
404 mpix->plane_fmt[0].bytesperline *
405 pfmt->bpp / pfmt->bpp_planar;
406 /*
407 * (height + 1) * bytesperline due to a hardware issue: the DMA unit
408 * is a power of two, and a line should be transferred as few units
409 * as possible. The result is that up to line length more data than
410 * the image size may be transferred to memory after the image.
411 * Another limition is the GDA allocation unit size. For low
412 * resolution it gives a bigger number. Use larger one to avoid
413 * memory corruption.
414 */
415 mpix->plane_fmt[0].sizeimage =
416 max(max(mpix->plane_fmt[0].sizeimage,
417 mpix->plane_fmt[0].bytesperline * mpix->height +
418 max(mpix->plane_fmt[0].bytesperline,
419 av->isys->pdata->ipdata->isys_dma_overshoot)), 1U);
420
421 if (av->compression_ctrl)
422 av->compression = v4l2_ctrl_g_ctrl(av->compression_ctrl);
423
424 /* overwrite bpl/height with compression alignment */
425 if (av->compression) {
426 u32 planar_tile_status_size, tile_status_size;
427
428 mpix->plane_fmt[0].bytesperline =
429 ALIGN(mpix->plane_fmt[0].bytesperline,
430 IPU_ISYS_COMPRESSION_LINE_ALIGN);
431 mpix->height = ALIGN(mpix->height,
432 IPU_ISYS_COMPRESSION_HEIGHT_ALIGN);
433
434 mpix->plane_fmt[0].sizeimage =
435 ALIGN(mpix->plane_fmt[0].bytesperline * mpix->height,
436 IPU_ISYS_COMPRESSION_PAGE_ALIGN);
437
438 /* ISYS compression only for RAW and single plannar */
439 planar_tile_status_size =
440 DIV_ROUND_UP_ULL((mpix->plane_fmt[0].bytesperline *
441 mpix->height /
442 IPU_ISYS_COMPRESSION_TILE_SIZE_BYTES) *
443 IPU_ISYS_COMPRESSION_TILE_STATUS_BITS,
444 BITS_PER_BYTE);
445 tile_status_size = ALIGN(planar_tile_status_size,
446 IPU_ISYS_COMPRESSION_PAGE_ALIGN);
447
448 /* tile status buffer offsets relative to buffer base address */
449 av->ts_offsets[0] = mpix->plane_fmt[0].sizeimage;
450 mpix->plane_fmt[0].sizeimage += tile_status_size;
451
452 dev_dbg(&av->isys->adev->dev,
453 "cmprs: bpl:%d, height:%d img size:%d, ts_sz:%d\n",
454 mpix->plane_fmt[0].bytesperline, mpix->height,
455 av->ts_offsets[0], tile_status_size);
456 }
457
458 memset(mpix->plane_fmt[0].reserved, 0,
459 sizeof(mpix->plane_fmt[0].reserved));
460
461 if (mpix->field == V4L2_FIELD_ANY)
462 mpix->field = V4L2_FIELD_NONE;
463 /* Use defaults */
464 mpix->colorspace = V4L2_COLORSPACE_RAW;
465 mpix->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
466 mpix->quantization = V4L2_QUANTIZATION_DEFAULT;
467 mpix->xfer_func = V4L2_XFER_FUNC_DEFAULT;
468
469 return pfmt;
470 }
471
472 static int vidioc_s_fmt_vid_cap_mplane(struct file *file, void *fh,
473 struct v4l2_format *f)
474 {
475 struct ipu_isys_video *av = video_drvdata(file);
476
477 if (av->aq.vbq.streaming)
478 return -EBUSY;
479
480 av->pfmt = av->try_fmt_vid_mplane(av, &f->fmt.pix_mp);
481 av->mpix = f->fmt.pix_mp;
482
483 return 0;
484 }
485
486 static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *fh,
487 struct v4l2_format *f)
488 {
489 struct ipu_isys_video *av = video_drvdata(file);
490
491 av->try_fmt_vid_mplane(av, &f->fmt.pix_mp);
492
493 return 0;
494 }
495
496 static long ipu_isys_vidioc_private(struct file *file, void *fh,
497 bool valid_prio, unsigned int cmd,
498 void *arg)
499 {
500 struct ipu_isys_video *av = video_drvdata(file);
501 int ret = 0;
502
503 switch (cmd) {
504 case VIDIOC_IPU_GET_DRIVER_VERSION:
505 *(u32 *)arg = IPU_DRIVER_VERSION;
506 break;
507
508 default:
509 dev_dbg(&av->isys->adev->dev, "unsupported private ioctl %x\n",
510 cmd);
511 }
512
513 return ret;
514 }
515
516 static int vidioc_enum_input(struct file *file, void *fh,
517 struct v4l2_input *input)
518 {
519 if (input->index > 0)
520 return -EINVAL;
521 strlcpy(input->name, "camera", sizeof(input->name));
522 input->type = V4L2_INPUT_TYPE_CAMERA;
523
524 return 0;
525 }
526
527 static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
528 {
529 *input = 0;
530
531 return 0;
532 }
533
534 static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
535 {
536 return input == 0 ? 0 : -EINVAL;
537 }
538
539 /*
540 * Return true if an entity directly connected to an Iunit entity is
541 * an image source for the ISP. This can be any external directly
542 * connected entity or any of the test pattern generators in the
543 * Iunit.
544 */
545 static bool is_external(struct ipu_isys_video *av, struct media_entity *entity)
546 {
547 struct v4l2_subdev *sd;
548
549 /* All video nodes are ours. */
550 if (!is_media_entity_v4l2_subdev(entity))
551 return false;
552
553 sd = media_entity_to_v4l2_subdev(entity);
554 if (strncmp(sd->name, IPU_ISYS_ENTITY_PREFIX,
555 strlen(IPU_ISYS_ENTITY_PREFIX)) != 0)
556 return true;
557
558 return false;
559 }
560
561 static int link_validate(struct media_link *link)
562 {
563 struct ipu_isys_video *av =
564 container_of(link->sink, struct ipu_isys_video, pad);
565 /* All sub-devices connected to a video node are ours. */
566 struct ipu_isys_pipeline *ip =
567 to_ipu_isys_pipeline(av->vdev.entity.pipe);
568 struct v4l2_subdev *sd;
569
570 if (!link->source->entity)
571 return -EINVAL;
572 sd = media_entity_to_v4l2_subdev(link->source->entity);
573 if (is_external(av, link->source->entity)) {
574 ip->external = media_entity_remote_pad(av->vdev.entity.pads);
575 ip->source = to_ipu_isys_subdev(sd)->source;
576 }
577
578 ip->nr_queues++;
579
580 return 0;
581 }
582
583 static void get_stream_opened(struct ipu_isys_video *av)
584 {
585 unsigned long flags;
586
587 spin_lock_irqsave(&av->isys->lock, flags);
588 av->isys->stream_opened++;
589 spin_unlock_irqrestore(&av->isys->lock, flags);
590 }
591
592 static void put_stream_opened(struct ipu_isys_video *av)
593 {
594 unsigned long flags;
595
596 spin_lock_irqsave(&av->isys->lock, flags);
597 av->isys->stream_opened--;
598 spin_unlock_irqrestore(&av->isys->lock, flags);
599 }
600
601 static int get_stream_handle(struct ipu_isys_video *av)
602 {
603 struct ipu_isys_pipeline *ip =
604 to_ipu_isys_pipeline(av->vdev.entity.pipe);
605 unsigned int stream_handle;
606 unsigned long flags;
607
608 spin_lock_irqsave(&av->isys->lock, flags);
609 for (stream_handle = 0;
610 stream_handle < IPU_ISYS_MAX_STREAMS; stream_handle++)
611 if (!av->isys->pipes[stream_handle])
612 break;
613 if (stream_handle == IPU_ISYS_MAX_STREAMS) {
614 spin_unlock_irqrestore(&av->isys->lock, flags);
615 return -EBUSY;
616 }
617 av->isys->pipes[stream_handle] = ip;
618 ip->stream_handle = stream_handle;
619 spin_unlock_irqrestore(&av->isys->lock, flags);
620 return 0;
621 }
622
623 static void put_stream_handle(struct ipu_isys_video *av)
624 {
625 struct ipu_isys_pipeline *ip =
626 to_ipu_isys_pipeline(av->vdev.entity.pipe);
627 unsigned long flags;
628
629 spin_lock_irqsave(&av->isys->lock, flags);
630 av->isys->pipes[ip->stream_handle] = NULL;
631 ip->stream_handle = -1;
632 spin_unlock_irqrestore(&av->isys->lock, flags);
633 }
634
635 static int get_external_facing_format(struct ipu_isys_pipeline *ip,
636 struct v4l2_subdev_format *format)
637 {
638 struct ipu_isys_video *av = container_of(ip, struct ipu_isys_video, ip);
639 struct v4l2_subdev *sd;
640 struct media_pad *external_facing;
641
642 if (!ip->external->entity) {
643 WARN_ON(1);
644 return -ENODEV;
645 }
646 sd = media_entity_to_v4l2_subdev(ip->external->entity);
647 external_facing = (strncmp(sd->name, IPU_ISYS_ENTITY_PREFIX,
648 strlen(IPU_ISYS_ENTITY_PREFIX)) == 0) ?
649 ip->external :
650 media_entity_remote_pad(ip->external);
651 if (WARN_ON(!external_facing)) {
652 dev_warn(&av->isys->adev->dev,
653 "no external facing pad --- driver bug?\n");
654 return -EINVAL;
655 }
656
657 format->which = V4L2_SUBDEV_FORMAT_ACTIVE;
658 format->pad = 0;
659 sd = media_entity_to_v4l2_subdev(external_facing->entity);
660
661 return v4l2_subdev_call(sd, pad, get_fmt, NULL, format);
662 }
663
664 static void short_packet_queue_destroy(struct ipu_isys_pipeline *ip)
665 {
666 struct ipu_isys_video *av = container_of(ip, struct ipu_isys_video, ip);
667 unsigned int i;
668
669 if (!ip->short_packet_bufs)
670 return;
671 for (i = 0; i < IPU_ISYS_SHORT_PACKET_BUFFER_NUM; i++) {
672 if (ip->short_packet_bufs[i].buffer)
673 dma_free_coherent(&av->isys->adev->dev,
674 ip->short_packet_buffer_size,
675 ip->short_packet_bufs[i].buffer,
676 ip->short_packet_bufs[i].dma_addr);
677 }
678 kfree(ip->short_packet_bufs);
679 ip->short_packet_bufs = NULL;
680 }
681
682 static int short_packet_queue_setup(struct ipu_isys_pipeline *ip)
683 {
684 struct ipu_isys_video *av = container_of(ip, struct ipu_isys_video, ip);
685 struct v4l2_subdev_format source_fmt = { 0 };
686 unsigned int i;
687 int rval;
688 size_t buf_size;
689
690 INIT_LIST_HEAD(&ip->pending_interlaced_bufs);
691 ip->cur_field = V4L2_FIELD_TOP;
692
693 if (ip->isys->short_packet_source == IPU_ISYS_SHORT_PACKET_FROM_TUNIT) {
694 ip->short_packet_trace_index = 0;
695 return 0;
696 }
697
698 rval = get_external_facing_format(ip, &source_fmt);
699 if (rval)
700 return rval;
701 buf_size = IPU_ISYS_SHORT_PACKET_BUF_SIZE(source_fmt.format.height);
702 ip->short_packet_buffer_size = buf_size;
703 ip->num_short_packet_lines =
704 IPU_ISYS_SHORT_PACKET_PKT_LINES(source_fmt.format.height);
705
706 /* Initialize short packet queue. */
707 INIT_LIST_HEAD(&ip->short_packet_incoming);
708 INIT_LIST_HEAD(&ip->short_packet_active);
709
710 ip->short_packet_bufs =
711 kzalloc(sizeof(struct ipu_isys_private_buffer) *
712 IPU_ISYS_SHORT_PACKET_BUFFER_NUM, GFP_KERNEL);
713 if (!ip->short_packet_bufs)
714 return -ENOMEM;
715
716 for (i = 0; i < IPU_ISYS_SHORT_PACKET_BUFFER_NUM; i++) {
717 struct ipu_isys_private_buffer *buf = &ip->short_packet_bufs[i];
718
719 buf->index = (unsigned int)i;
720 buf->ip = ip;
721 buf->ib.type = IPU_ISYS_SHORT_PACKET_BUFFER;
722 buf->bytesused = buf_size;
723 buf->buffer = dma_alloc_coherent(&av->isys->adev->dev, buf_size,
724 &buf->dma_addr, GFP_KERNEL);
725 if (!buf->buffer) {
726 short_packet_queue_destroy(ip);
727 return -ENOMEM;
728 }
729 list_add(&buf->ib.head, &ip->short_packet_incoming);
730 }
731
732 return 0;
733 }
734
735 static void
736 csi_short_packet_prepare_fw_cfg(struct ipu_isys_pipeline *ip,
737 struct ipu_fw_isys_stream_cfg_data_abi *cfg)
738 {
739 int input_pin = cfg->nof_input_pins++;
740 int output_pin = cfg->nof_output_pins++;
741 struct ipu_fw_isys_input_pin_info_abi *input_info =
742 &cfg->input_pins[input_pin];
743 struct ipu_fw_isys_output_pin_info_abi *output_info =
744 &cfg->output_pins[output_pin];
745 struct ipu_isys *isys = ip->isys;
746
747 /*
748 * Setting dt as IPU_ISYS_SHORT_PACKET_GENERAL_DT will cause
749 * MIPI receiver to receive all MIPI short packets.
750 */
751 input_info->dt = IPU_ISYS_SHORT_PACKET_GENERAL_DT;
752 input_info->input_res.width = IPU_ISYS_SHORT_PACKET_WIDTH;
753 input_info->input_res.height = ip->num_short_packet_lines;
754
755 ip->output_pins[output_pin].pin_ready =
756 ipu_isys_queue_short_packet_ready;
757 ip->output_pins[output_pin].aq = NULL;
758 ip->short_packet_output_pin = output_pin;
759
760 output_info->input_pin_id = input_pin;
761 output_info->output_res.width = IPU_ISYS_SHORT_PACKET_WIDTH;
762 output_info->output_res.height = ip->num_short_packet_lines;
763 output_info->stride = IPU_ISYS_SHORT_PACKET_WIDTH *
764 IPU_ISYS_SHORT_PACKET_UNITSIZE;
765 output_info->pt = IPU_ISYS_SHORT_PACKET_PT;
766 output_info->ft = IPU_ISYS_SHORT_PACKET_FT;
767 output_info->send_irq = 1;
768 memset(output_info->ts_offsets, 0, sizeof(output_info->ts_offsets));
769 output_info->s2m_pixel_soc_pixel_remapping =
770 S2M_PIXEL_SOC_PIXEL_REMAPPING_FLAG_NO_REMAPPING;
771 output_info->csi_be_soc_pixel_remapping =
772 CSI_BE_SOC_PIXEL_REMAPPING_FLAG_NO_REMAPPING;
773 output_info->sensor_type = isys->sensor_info.sensor_metadata;
774 output_info->snoopable = true;
775 output_info->error_handling_enable = false;
776 }
777
778 void
779 ipu_isys_prepare_fw_cfg_default(struct ipu_isys_video *av,
780 struct ipu_fw_isys_stream_cfg_data_abi *cfg)
781 {
782 struct ipu_isys_pipeline *ip =
783 to_ipu_isys_pipeline(av->vdev.entity.pipe);
784 struct ipu_isys_queue *aq = &av->aq;
785 struct ipu_fw_isys_output_pin_info_abi *pin_info;
786 struct ipu_isys *isys = av->isys;
787 unsigned int type_index, type;
788 int pin = cfg->nof_output_pins++;
789
790 aq->fw_output = pin;
791 ip->output_pins[pin].pin_ready = ipu_isys_queue_buf_ready;
792 ip->output_pins[pin].aq = aq;
793
794 pin_info = &cfg->output_pins[pin];
795 pin_info->input_pin_id = 0;
796 pin_info->output_res.width = av->mpix.width;
797 pin_info->output_res.height = av->mpix.height;
798
799 if (!av->pfmt->bpp_planar)
800 pin_info->stride = av->mpix.plane_fmt[0].bytesperline;
801 else
802 pin_info->stride = ALIGN(DIV_ROUND_UP(av->mpix.width *
803 av->pfmt->bpp_planar,
804 BITS_PER_BYTE),
805 av->isys->line_align);
806
807 pin_info->pt = aq->css_pin_type;
808 pin_info->ft = av->pfmt->css_pixelformat;
809 pin_info->send_irq = 1;
810 memset(pin_info->ts_offsets, 0, sizeof(pin_info->ts_offsets));
811 pin_info->s2m_pixel_soc_pixel_remapping =
812 S2M_PIXEL_SOC_PIXEL_REMAPPING_FLAG_NO_REMAPPING;
813 pin_info->csi_be_soc_pixel_remapping =
814 CSI_BE_SOC_PIXEL_REMAPPING_FLAG_NO_REMAPPING;
815 cfg->vc = 0;
816
817 switch (pin_info->pt) {
818 /* non-snoopable sensor data to PSYS */
819 case IPU_FW_ISYS_PIN_TYPE_RAW_NS:
820 type_index = IPU_FW_ISYS_VC1_SENSOR_DATA;
821 pin_info->sensor_type = isys->sensor_types[type_index]++;
822 pin_info->snoopable = false;
823 pin_info->error_handling_enable = false;
824 type = isys->sensor_types[type_index];
825 if (type > isys->sensor_info.vc1_data_end)
826 isys->sensor_types[type_index] =
827 isys->sensor_info.vc1_data_start;
828
829 break;
830 /* snoopable META/Stats data to CPU */
831 case IPU_FW_ISYS_PIN_TYPE_METADATA_0:
832 case IPU_FW_ISYS_PIN_TYPE_METADATA_1:
833 pin_info->sensor_type = isys->sensor_info.sensor_metadata;
834 pin_info->snoopable = true;
835 pin_info->error_handling_enable = false;
836 break;
837 case IPU_FW_ISYS_PIN_TYPE_RAW_SOC:
838 if (av->compression) {
839 type_index = IPU_FW_ISYS_VC1_SENSOR_DATA;
840 pin_info->sensor_type
841 = isys->sensor_types[type_index]++;
842 pin_info->snoopable = false;
843 pin_info->error_handling_enable = false;
844 type = isys->sensor_types[type_index];
845 if (type > isys->sensor_info.vc1_data_end)
846 isys->sensor_types[type_index] =
847 isys->sensor_info.vc1_data_start;
848 } else {
849 type_index = IPU_FW_ISYS_VC0_SENSOR_DATA;
850 pin_info->sensor_type
851 = isys->sensor_types[type_index]++;
852 pin_info->snoopable = true;
853 pin_info->error_handling_enable = false;
854 type = isys->sensor_types[type_index];
855 if (type > isys->sensor_info.vc0_data_end)
856 isys->sensor_types[type_index] =
857 isys->sensor_info.vc0_data_start;
858 }
859 break;
860 case IPU_FW_ISYS_PIN_TYPE_MIPI:
861 type_index = IPU_FW_ISYS_VC0_SENSOR_DATA;
862 pin_info->sensor_type = isys->sensor_types[type_index]++;
863 pin_info->snoopable = true;
864 pin_info->error_handling_enable = false;
865 type = isys->sensor_types[type_index];
866 if (type > isys->sensor_info.vc0_data_end)
867 isys->sensor_types[type_index] =
868 isys->sensor_info.vc0_data_start;
869
870 break;
871
872 default:
873 dev_err(&av->isys->adev->dev,
874 "Unknown pin type, use metadata type as default\n");
875
876 pin_info->sensor_type = isys->sensor_info.sensor_metadata;
877 pin_info->snoopable = true;
878 pin_info->error_handling_enable = false;
879 }
880 if (av->compression) {
881 pin_info->payload_buf_size = av->mpix.plane_fmt[0].sizeimage;
882 pin_info->reserve_compression = av->compression;
883 pin_info->ts_offsets[0] = av->ts_offsets[0];
884 }
885 }
886
887 static unsigned int ipu_isys_get_compression_scheme(u32 code)
888 {
889 switch (code) {
890 case MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8:
891 case MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8:
892 case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:
893 case MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8:
894 return 3;
895 default:
896 return 0;
897 }
898 }
899
900 static unsigned int get_comp_format(u32 code)
901 {
902 unsigned int predictor = 0; /* currently hard coded */
903 unsigned int udt = ipu_isys_mbus_code_to_mipi(code);
904 unsigned int scheme = ipu_isys_get_compression_scheme(code);
905
906 /* if data type is not user defined return here */
907 if (udt < IPU_ISYS_MIPI_CSI2_TYPE_USER_DEF(1) ||
908 udt > IPU_ISYS_MIPI_CSI2_TYPE_USER_DEF(8))
909 return 0;
910
911 /*
912 * For each user defined type (1..8) there is configuration bitfield for
913 * decompression.
914 *
915 * | bit 3 | bits 2:0 |
916 * | predictor | scheme |
917 * compression schemes:
918 * 000 = no compression
919 * 001 = 10 - 6 - 10
920 * 010 = 10 - 7 - 10
921 * 011 = 10 - 8 - 10
922 * 100 = 12 - 6 - 12
923 * 101 = 12 - 7 - 12
924 * 110 = 12 - 8 - 12
925 */
926
927 return ((predictor << 3) | scheme) <<
928 ((udt - IPU_ISYS_MIPI_CSI2_TYPE_USER_DEF(1)) * 4);
929 }
930
931 /* Create stream and start it using the CSS FW ABI. */
932 static int start_stream_firmware(struct ipu_isys_video *av,
933 struct ipu_isys_buffer_list *bl)
934 {
935 struct ipu_isys_pipeline *ip =
936 to_ipu_isys_pipeline(av->vdev.entity.pipe);
937 struct device *dev = &av->isys->adev->dev;
938 struct v4l2_subdev_selection sel_fmt = {
939 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
940 .target = V4L2_SEL_TGT_CROP,
941 .pad = CSI2_BE_PAD_SOURCE,
942 };
943 struct ipu_fw_isys_stream_cfg_data_abi *stream_cfg;
944 struct isys_fw_msgs *msg = NULL;
945 struct ipu_fw_isys_frame_buff_set_abi *buf = NULL;
946 struct ipu_isys_queue *aq;
947 struct ipu_isys_video *isl_av = NULL;
948 struct v4l2_subdev_format source_fmt = { 0 };
949 struct v4l2_subdev *be_sd = NULL;
950 struct media_pad *source_pad = media_entity_remote_pad(&av->pad);
951 struct ipu_fw_isys_cropping_abi *crop;
952 enum ipu_fw_isys_send_type send_type;
953 int rval, rvalout, tout;
954
955 rval = get_external_facing_format(ip, &source_fmt);
956 if (rval)
957 return rval;
958
959 msg = ipu_get_fw_msg_buf(ip);
960 if (!msg)
961 return -ENOMEM;
962
963 stream_cfg = to_stream_cfg_msg_buf(msg);
964 stream_cfg->compfmt = get_comp_format(source_fmt.format.code);
965 stream_cfg->input_pins[0].input_res.width = source_fmt.format.width;
966 stream_cfg->input_pins[0].input_res.height = source_fmt.format.height;
967 stream_cfg->input_pins[0].dt =
968 ipu_isys_mbus_code_to_mipi(source_fmt.format.code);
969 stream_cfg->input_pins[0].mapped_dt = N_IPU_FW_ISYS_MIPI_DATA_TYPE;
970 stream_cfg->input_pins[0].mipi_decompression =
971 IPU_FW_ISYS_MIPI_COMPRESSION_TYPE_NO_COMPRESSION;
972 stream_cfg->input_pins[0].capture_mode =
973 IPU_FW_ISYS_CAPTURE_MODE_REGULAR;
974 if (ip->csi2 && !v4l2_ctrl_g_ctrl(ip->csi2->store_csi2_header))
975 stream_cfg->input_pins[0].mipi_store_mode =
976 IPU_FW_ISYS_MIPI_STORE_MODE_DISCARD_LONG_HEADER;
977
978 stream_cfg->src = ip->source;
979 stream_cfg->vc = 0;
980 stream_cfg->isl_use = ip->isl_mode;
981 stream_cfg->nof_input_pins = 1;
982 stream_cfg->sensor_type = IPU_FW_ISYS_SENSOR_MODE_NORMAL;
983
984 /*
985 * Only CSI2-BE and SOC BE has the capability to do crop,
986 * so get the crop info from csi2-be or csi2-be-soc.
987 */
988 if (ip->csi2_be) {
989 be_sd = &ip->csi2_be->asd.sd;
990 } else if (ip->csi2_be_soc) {
991 be_sd = &ip->csi2_be_soc->asd.sd;
992 if (source_pad)
993 sel_fmt.pad = source_pad->index;
994 }
995 crop = &stream_cfg->crop;
996 if (be_sd &&
997 !v4l2_subdev_call(be_sd, pad, get_selection, NULL, &sel_fmt)) {
998 crop->left_offset = sel_fmt.r.left;
999 crop->top_offset = sel_fmt.r.top;
1000 crop->right_offset = sel_fmt.r.left + sel_fmt.r.width;
1001 crop->bottom_offset = sel_fmt.r.top + sel_fmt.r.height;
1002
1003 } else {
1004 crop->right_offset = source_fmt.format.width;
1005 crop->bottom_offset = source_fmt.format.height;
1006 }
1007
1008 /*
1009 * If the CSI-2 backend's video node is part of the pipeline
1010 * it must be arranged first in the output pin list. This is
1011 * the most probably a firmware requirement.
1012 */
1013 if (ip->isl_mode == IPU_ISL_CSI2_BE)
1014 isl_av = &ip->csi2_be->av;
1015
1016 if (isl_av) {
1017 struct ipu_isys_queue *safe;
1018
1019 list_for_each_entry_safe(aq, safe, &ip->queues, node) {
1020 struct ipu_isys_video *av = ipu_isys_queue_to_video(aq);
1021
1022 if (av != isl_av)
1023 continue;
1024
1025 list_del(&aq->node);
1026 list_add(&aq->node, &ip->queues);
1027 break;
1028 }
1029 }
1030
1031 list_for_each_entry(aq, &ip->queues, node) {
1032 struct ipu_isys_video *__av = ipu_isys_queue_to_video(aq);
1033
1034 __av->prepare_fw_stream(__av, stream_cfg);
1035 }
1036
1037 if (ip->interlaced && ip->isys->short_packet_source ==
1038 IPU_ISYS_SHORT_PACKET_FROM_RECEIVER)
1039 csi_short_packet_prepare_fw_cfg(ip, stream_cfg);
1040
1041 ipu_fw_isys_dump_stream_cfg(dev, stream_cfg);
1042
1043 ip->nr_output_pins = stream_cfg->nof_output_pins;
1044
1045 rval = get_stream_handle(av);
1046 if (rval) {
1047 dev_dbg(dev, "Can't get stream_handle\n");
1048 return rval;
1049 }
1050
1051 reinit_completion(&ip->stream_open_completion);
1052
1053 ipu_fw_isys_set_params(stream_cfg);
1054
1055 rval = ipu_fw_isys_complex_cmd(av->isys,
1056 ip->stream_handle,
1057 stream_cfg,
1058 to_dma_addr(msg),
1059 sizeof(*stream_cfg),
1060 IPU_FW_ISYS_SEND_TYPE_STREAM_OPEN);
1061 ipu_put_fw_mgs_buf(av->isys, (uintptr_t)stream_cfg);
1062
1063 if (rval < 0) {
1064 dev_err(dev, "can't open stream (%d)\n", rval);
1065 goto out_put_stream_handle;
1066 }
1067
1068 get_stream_opened(av);
1069
1070 tout = wait_for_completion_timeout(&ip->stream_open_completion,
1071 IPU_LIB_CALL_TIMEOUT_JIFFIES);
1072 if (!tout) {
1073 dev_err(dev, "stream open time out\n");
1074 rval = -ETIMEDOUT;
1075 goto out_put_stream_opened;
1076 }
1077 if (ip->error) {
1078 dev_err(dev, "stream open error: %d\n", ip->error);
1079 rval = -EIO;
1080 goto out_put_stream_opened;
1081 }
1082 dev_dbg(dev, "start stream: open complete\n");
1083
1084 if (bl) {
1085 msg = ipu_get_fw_msg_buf(ip);
1086 if (!msg) {
1087 rval = -ENOMEM;
1088 goto out_put_stream_opened;
1089 }
1090 buf = to_frame_msg_buf(msg);
1091 }
1092
1093 if (bl) {
1094 ipu_isys_buffer_to_fw_frame_buff(buf, ip, bl);
1095 ipu_isys_buffer_list_queue(bl,
1096 IPU_ISYS_BUFFER_LIST_FL_ACTIVE, 0);
1097 }
1098
1099 reinit_completion(&ip->stream_start_completion);
1100
1101 if (bl) {
1102 send_type = IPU_FW_ISYS_SEND_TYPE_STREAM_START_AND_CAPTURE;
1103 ipu_fw_isys_dump_frame_buff_set(dev, buf,
1104 stream_cfg->nof_output_pins);
1105 rval = ipu_fw_isys_complex_cmd(av->isys,
1106 ip->stream_handle,
1107 buf, to_dma_addr(msg),
1108 sizeof(*buf),
1109 send_type);
1110 ipu_put_fw_mgs_buf(av->isys, (uintptr_t)buf);
1111 } else {
1112 send_type = IPU_FW_ISYS_SEND_TYPE_STREAM_START;
1113 rval = ipu_fw_isys_simple_cmd(av->isys,
1114 ip->stream_handle,
1115 send_type);
1116 }
1117
1118 if (rval < 0) {
1119 dev_err(dev, "can't start streaming (%d)\n", rval);
1120 goto out_stream_close;
1121 }
1122
1123 tout = wait_for_completion_timeout(&ip->stream_start_completion,
1124 IPU_LIB_CALL_TIMEOUT_JIFFIES);
1125 if (!tout) {
1126 dev_err(dev, "stream start time out\n");
1127 rval = -ETIMEDOUT;
1128 goto out_stream_close;
1129 }
1130 if (ip->error) {
1131 dev_err(dev, "stream start error: %d\n", ip->error);
1132 rval = -EIO;
1133 goto out_stream_close;
1134 }
1135 dev_dbg(dev, "start stream: complete\n");
1136
1137 return 0;
1138
1139 out_stream_close:
1140 reinit_completion(&ip->stream_close_completion);
1141
1142 rvalout = ipu_fw_isys_simple_cmd(av->isys,
1143 ip->stream_handle,
1144 IPU_FW_ISYS_SEND_TYPE_STREAM_CLOSE);
1145 if (rvalout < 0) {
1146 dev_dbg(dev, "can't close stream (%d)\n", rvalout);
1147 goto out_put_stream_opened;
1148 }
1149
1150 tout = wait_for_completion_timeout(&ip->stream_close_completion,
1151 IPU_LIB_CALL_TIMEOUT_JIFFIES);
1152 if (!tout)
1153 dev_err(dev, "stream close time out\n");
1154 else if (ip->error)
1155 dev_err(dev, "stream close error: %d\n", ip->error);
1156 else
1157 dev_dbg(dev, "stream close complete\n");
1158
1159 out_put_stream_opened:
1160 put_stream_opened(av);
1161
1162 out_put_stream_handle:
1163 put_stream_handle(av);
1164 return rval;
1165 }
1166
1167 static void stop_streaming_firmware(struct ipu_isys_video *av)
1168 {
1169 struct ipu_isys_pipeline *ip =
1170 to_ipu_isys_pipeline(av->vdev.entity.pipe);
1171 struct device *dev = &av->isys->adev->dev;
1172 int rval, tout;
1173 enum ipu_fw_isys_send_type send_type =
1174 IPU_FW_ISYS_SEND_TYPE_STREAM_FLUSH;
1175
1176 reinit_completion(&ip->stream_stop_completion);
1177
1178 rval = ipu_fw_isys_simple_cmd(av->isys, ip->stream_handle,
1179 send_type);
1180
1181 if (rval < 0) {
1182 dev_err(dev, "can't stop stream (%d)\n", rval);
1183 return;
1184 }
1185
1186 tout = wait_for_completion_timeout(&ip->stream_stop_completion,
1187 IPU_LIB_CALL_TIMEOUT_JIFFIES);
1188 if (!tout)
1189 dev_err(dev, "stream stop time out\n");
1190 else if (ip->error)
1191 dev_err(dev, "stream stop error: %d\n", ip->error);
1192 else
1193 dev_dbg(dev, "stop stream: complete\n");
1194 }
1195
1196 static void close_streaming_firmware(struct ipu_isys_video *av)
1197 {
1198 struct ipu_isys_pipeline *ip =
1199 to_ipu_isys_pipeline(av->vdev.entity.pipe);
1200 struct device *dev = &av->isys->adev->dev;
1201 int rval, tout;
1202
1203 reinit_completion(&ip->stream_close_completion);
1204
1205 rval = ipu_fw_isys_simple_cmd(av->isys, ip->stream_handle,
1206 IPU_FW_ISYS_SEND_TYPE_STREAM_CLOSE);
1207 if (rval < 0) {
1208 dev_err(dev, "can't close stream (%d)\n", rval);
1209 return;
1210 }
1211
1212 tout = wait_for_completion_timeout(&ip->stream_close_completion,
1213 IPU_LIB_CALL_TIMEOUT_JIFFIES);
1214 if (!tout)
1215 dev_err(dev, "stream close time out\n");
1216 else if (ip->error)
1217 dev_err(dev, "stream close error: %d\n", ip->error);
1218 else
1219 dev_dbg(dev, "close stream: complete\n");
1220
1221 put_stream_opened(av);
1222 put_stream_handle(av);
1223 }
1224
1225 void
1226 ipu_isys_video_add_capture_done(struct ipu_isys_pipeline *ip,
1227 void (*capture_done)
1228 (struct ipu_isys_pipeline *ip,
1229 struct ipu_fw_isys_resp_info_abi *resp))
1230 {
1231 unsigned int i;
1232
1233 /* Different instances may register same function. Add only once */
1234 for (i = 0; i < IPU_NUM_CAPTURE_DONE; i++)
1235 if (ip->capture_done[i] == capture_done)
1236 return;
1237
1238 for (i = 0; i < IPU_NUM_CAPTURE_DONE; i++) {
1239 if (!ip->capture_done[i]) {
1240 ip->capture_done[i] = capture_done;
1241 return;
1242 }
1243 }
1244 /*
1245 * Too many call backs registered. Change to IPU_NUM_CAPTURE_DONE
1246 * constant probably required.
1247 */
1248 WARN_ON(1);
1249 }
1250
1251 int ipu_isys_video_prepare_streaming(struct ipu_isys_video *av,
1252 unsigned int state)
1253 {
1254 struct ipu_isys *isys = av->isys;
1255 struct device *dev = &isys->adev->dev;
1256 struct ipu_isys_pipeline *ip;
1257 struct media_graph graph;
1258 struct media_entity *entity;
1259 struct media_device *mdev = &av->isys->media_dev;
1260 int rval;
1261 unsigned int i;
1262
1263 dev_dbg(dev, "prepare stream: %d\n", state);
1264
1265 if (!state) {
1266 ip = to_ipu_isys_pipeline(av->vdev.entity.pipe);
1267
1268 if (ip->interlaced && isys->short_packet_source ==
1269 IPU_ISYS_SHORT_PACKET_FROM_RECEIVER)
1270 short_packet_queue_destroy(ip);
1271 media_pipeline_stop(&av->vdev.entity);
1272 media_entity_enum_cleanup(&ip->entity_enum);
1273 return 0;
1274 }
1275
1276 ip = &av->ip;
1277
1278 WARN_ON(ip->nr_streaming);
1279 ip->has_sof = false;
1280 ip->nr_queues = 0;
1281 ip->external = NULL;
1282 atomic_set(&ip->sequence, 0);
1283 ip->isl_mode = IPU_ISL_OFF;
1284
1285 for (i = 0; i < IPU_NUM_CAPTURE_DONE; i++)
1286 ip->capture_done[i] = NULL;
1287 ip->csi2_be = NULL;
1288 ip->csi2_be_soc = NULL;
1289 ip->csi2 = NULL;
1290 ip->seq_index = 0;
1291 memset(ip->seq, 0, sizeof(ip->seq));
1292
1293 WARN_ON(!list_empty(&ip->queues));
1294 ip->interlaced = false;
1295
1296 rval = media_entity_enum_init(&ip->entity_enum, mdev);
1297 if (rval)
1298 return rval;
1299
1300 rval = media_pipeline_start(&av->vdev.entity, &ip->pipe);
1301 if (rval < 0) {
1302 dev_dbg(dev, "pipeline start failed\n");
1303 goto out_enum_cleanup;
1304 }
1305
1306 if (!ip->external) {
1307 dev_err(dev, "no external entity set! Driver bug?\n");
1308 rval = -EINVAL;
1309 goto out_pipeline_stop;
1310 }
1311
1312 rval = media_graph_walk_init(&graph, mdev);
1313 if (rval)
1314 goto out_pipeline_stop;
1315
1316 /* Gather all entities in the graph. */
1317 mutex_lock(&mdev->graph_mutex);
1318 media_graph_walk_start(&graph, &av->vdev.entity);
1319 while ((entity = media_graph_walk_next(&graph)))
1320 media_entity_enum_set(&ip->entity_enum, entity);
1321
1322 mutex_unlock(&mdev->graph_mutex);
1323
1324 media_graph_walk_cleanup(&graph);
1325
1326 if (ip->interlaced) {
1327 rval = short_packet_queue_setup(ip);
1328 if (rval) {
1329 dev_err(&isys->adev->dev,
1330 "Failed to setup short packet buffer.\n");
1331 goto out_pipeline_stop;
1332 }
1333 }
1334
1335 dev_dbg(dev, "prepare stream: external entity %s\n",
1336 ip->external->entity->name);
1337
1338 return 0;
1339
1340 out_pipeline_stop:
1341 media_pipeline_stop(&av->vdev.entity);
1342
1343 out_enum_cleanup:
1344 media_entity_enum_cleanup(&ip->entity_enum);
1345
1346 return rval;
1347 }
1348
1349 static void configure_stream_watermark(struct ipu_isys_video *av)
1350 {
1351 u32 vblank, hblank;
1352 u64 pixel_rate;
1353 int ret = 0;
1354 struct v4l2_subdev *esd;
1355 struct v4l2_ctrl *ctrl;
1356 struct ipu_isys_pipeline *ip;
1357 struct isys_iwake_watermark *iwake_watermark;
1358 struct v4l2_control vb = { .id = V4L2_CID_VBLANK, .value = 0 };
1359 struct v4l2_control hb = { .id = V4L2_CID_HBLANK, .value = 0 };
1360
1361 ip = to_ipu_isys_pipeline(av->vdev.entity.pipe);
1362 if (!ip->external->entity) {
1363 WARN_ON(1);
1364 return;
1365 }
1366 esd = media_entity_to_v4l2_subdev(ip->external->entity);
1367
1368 av->watermark->width = av->mpix.width;
1369 av->watermark->height = av->mpix.height;
1370
1371 ret = v4l2_g_ctrl(esd->ctrl_handler, &vb);
1372 if (!ret && vb.value >= 0)
1373 vblank = vb.value;
1374 else
1375 vblank = 0;
1376
1377 ret = v4l2_g_ctrl(esd->ctrl_handler, &hb);
1378 if (!ret && hb.value >= 0)
1379 hblank = hb.value;
1380 else
1381 hblank = 0;
1382
1383 ctrl = v4l2_ctrl_find(esd->ctrl_handler, V4L2_CID_PIXEL_RATE);
1384
1385 if (!ctrl)
1386 pixel_rate = DEFAULT_PIXEL_RATE;
1387 else
1388 pixel_rate = v4l2_ctrl_g_ctrl_int64(ctrl);
1389
1390 av->watermark->vblank = vblank;
1391 av->watermark->hblank = hblank;
1392 av->watermark->pixel_rate = pixel_rate;
1393 if (!pixel_rate) {
1394 iwake_watermark = av->isys->iwake_watermark;
1395 mutex_lock(&iwake_watermark->mutex);
1396 iwake_watermark->force_iwake_disable = true;
1397 mutex_unlock(&iwake_watermark->mutex);
1398 WARN(1, "%s Invalid pixel_rate, disable iwake.\n", __func__);
1399 return;
1400 }
1401 }
1402
1403 static void calculate_stream_datarate(struct video_stream_watermark *watermark)
1404 {
1405 u64 pixels_per_line, bytes_per_line, line_time_ns;
1406 u64 pages_per_line, pb_bytes_per_line, stream_data_rate;
1407 u16 sram_granulrity_shift =
1408 (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) ?
1409 IPU6_SRAM_GRANULRITY_SHIFT : IPU6SE_SRAM_GRANULRITY_SHIFT;
1410 u16 sram_granulrity_size =
1411 (ipu_ver == IPU_VER_6 || ipu_ver == IPU_VER_6EP) ?
1412 IPU6_SRAM_GRANULRITY_SIZE : IPU6SE_SRAM_GRANULRITY_SIZE;
1413
1414 pixels_per_line = watermark->width + watermark->hblank;
1415 line_time_ns =
1416 pixels_per_line * 1000 / (watermark->pixel_rate / 1000000);
1417 /* 2 bytes per Bayer pixel */
1418 bytes_per_line = watermark->width << 1;
1419 /* bytes to IS pixel buffer pages */
1420 pages_per_line = bytes_per_line >> sram_granulrity_shift;
1421
1422 /* pages for each line */
1423 pages_per_line = DIV_ROUND_UP(bytes_per_line,
1424 sram_granulrity_size);
1425 pb_bytes_per_line = pages_per_line << sram_granulrity_shift;
1426
1427 /* data rate MB/s */
1428 stream_data_rate = (pb_bytes_per_line * 1000) / line_time_ns;
1429 watermark->stream_data_rate = stream_data_rate;
1430 }
1431
1432 static void update_stream_watermark(struct ipu_isys_video *av, bool state)
1433 {
1434 struct isys_iwake_watermark *iwake_watermark;
1435
1436 iwake_watermark = av->isys->iwake_watermark;
1437 if (state) {
1438 calculate_stream_datarate(av->watermark);
1439 mutex_lock(&iwake_watermark->mutex);
1440 list_add(&av->watermark->stream_node,
1441 &iwake_watermark->video_list);
1442 mutex_unlock(&iwake_watermark->mutex);
1443 } else {
1444 av->watermark->stream_data_rate = 0;
1445 mutex_lock(&iwake_watermark->mutex);
1446 list_del(&av->watermark->stream_node);
1447 mutex_unlock(&iwake_watermark->mutex);
1448 }
1449 update_watermark_setting(av->isys);
1450 }
1451
1452 int ipu_isys_video_set_streaming(struct ipu_isys_video *av,
1453 unsigned int state,
1454 struct ipu_isys_buffer_list *bl)
1455 {
1456 struct device *dev = &av->isys->adev->dev;
1457 struct media_device *mdev = av->vdev.entity.graph_obj.mdev;
1458 struct media_entity_enum entities;
1459
1460 struct media_entity *entity, *entity2;
1461 struct ipu_isys_pipeline *ip =
1462 to_ipu_isys_pipeline(av->vdev.entity.pipe);
1463 struct v4l2_subdev *sd, *esd;
1464 int rval = 0;
1465
1466 dev_dbg(dev, "set stream: %d\n", state);
1467
1468 if (!ip->external->entity) {
1469 WARN_ON(1);
1470 return -ENODEV;
1471 }
1472 esd = media_entity_to_v4l2_subdev(ip->external->entity);
1473
1474 if (state) {
1475 rval = media_graph_walk_init(&ip->graph, mdev);
1476 if (rval)
1477 return rval;
1478 rval = media_entity_enum_init(&entities, mdev);
1479 if (rval)
1480 goto out_media_entity_graph_init;
1481 }
1482
1483 if (!state) {
1484 stop_streaming_firmware(av);
1485
1486 /* stop external sub-device now. */
1487 dev_info(dev, "stream off %s\n", ip->external->entity->name);
1488
1489 v4l2_subdev_call(esd, video, s_stream, state);
1490 }
1491
1492 mutex_lock(&mdev->graph_mutex);
1493
1494 media_graph_walk_start(&ip->graph,
1495 &av->vdev.entity);
1496
1497 while ((entity = media_graph_walk_next(&ip->graph))) {
1498 sd = media_entity_to_v4l2_subdev(entity);
1499
1500 /* Non-subdev nodes can be safely ignored here. */
1501 if (!is_media_entity_v4l2_subdev(entity))
1502 continue;
1503
1504 /* Don't start truly external devices quite yet. */
1505 if (strncmp(sd->name, IPU_ISYS_ENTITY_PREFIX,
1506 strlen(IPU_ISYS_ENTITY_PREFIX)) != 0 ||
1507 ip->external->entity == entity)
1508 continue;
1509
1510 dev_dbg(dev, "s_stream %s entity %s\n", state ? "on" : "off",
1511 entity->name);
1512 rval = v4l2_subdev_call(sd, video, s_stream, state);
1513 if (!state)
1514 continue;
1515 if (rval && rval != -ENOIOCTLCMD) {
1516 mutex_unlock(&mdev->graph_mutex);
1517 goto out_media_entity_stop_streaming;
1518 }
1519
1520 media_entity_enum_set(&entities, entity);
1521 }
1522
1523 mutex_unlock(&mdev->graph_mutex);
1524
1525 if (av->aq.css_pin_type == IPU_FW_ISYS_PIN_TYPE_RAW_SOC) {
1526 if (state)
1527 configure_stream_watermark(av);
1528 update_stream_watermark(av, state);
1529 }
1530
1531 /* Oh crap */
1532 if (state) {
1533 rval = start_stream_firmware(av, bl);
1534 if (rval)
1535 goto out_media_entity_stop_streaming;
1536
1537 dev_dbg(dev, "set stream: source %d, stream_handle %d\n",
1538 ip->source, ip->stream_handle);
1539
1540 /* Start external sub-device now. */
1541 dev_info(dev, "stream on %s\n", ip->external->entity->name);
1542
1543 rval = v4l2_subdev_call(esd, video, s_stream, state);
1544 if (rval)
1545 goto out_media_entity_stop_streaming_firmware;
1546 } else {
1547 close_streaming_firmware(av);
1548 }
1549
1550 if (state)
1551 media_entity_enum_cleanup(&entities);
1552 else
1553 media_graph_walk_cleanup(&ip->graph);
1554 av->streaming = state;
1555
1556 return 0;
1557
1558 out_media_entity_stop_streaming_firmware:
1559 stop_streaming_firmware(av);
1560
1561 out_media_entity_stop_streaming:
1562 mutex_lock(&mdev->graph_mutex);
1563
1564 media_graph_walk_start(&ip->graph,
1565 &av->vdev.entity);
1566
1567 while (state && (entity2 = media_graph_walk_next(&ip->graph)) &&
1568 entity2 != entity) {
1569 sd = media_entity_to_v4l2_subdev(entity2);
1570
1571 if (!media_entity_enum_test(&entities, entity2))
1572 continue;
1573
1574 v4l2_subdev_call(sd, video, s_stream, 0);
1575 }
1576
1577 mutex_unlock(&mdev->graph_mutex);
1578
1579 media_entity_enum_cleanup(&entities);
1580
1581 out_media_entity_graph_init:
1582 media_graph_walk_cleanup(&ip->graph);
1583
1584 return rval;
1585 }
1586
1587 #ifdef CONFIG_COMPAT
1588 static long ipu_isys_compat_ioctl(struct file *file, unsigned int cmd,
1589 unsigned long arg)
1590 {
1591 long ret = -ENOIOCTLCMD;
1592 void __user *up = compat_ptr(arg);
1593
1594 /*
1595 * at present, there is not any private IOCTL need to compat handle
1596 */
1597 if (file->f_op->unlocked_ioctl)
1598 ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)up);
1599
1600 return ret;
1601 }
1602 #endif
1603
1604 static const struct v4l2_ioctl_ops ioctl_ops_mplane = {
1605 .vidioc_querycap = ipu_isys_vidioc_querycap,
1606 .vidioc_enum_fmt_vid_cap = ipu_isys_vidioc_enum_fmt,
1607 .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt_vid_cap_mplane,
1608 .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt_vid_cap_mplane,
1609 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane,
1610 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1611 .vidioc_create_bufs = vb2_ioctl_create_bufs,
1612 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1613 .vidioc_querybuf = vb2_ioctl_querybuf,
1614 .vidioc_qbuf = vb2_ioctl_qbuf,
1615 .vidioc_dqbuf = vb2_ioctl_dqbuf,
1616 .vidioc_streamon = vb2_ioctl_streamon,
1617 .vidioc_streamoff = vb2_ioctl_streamoff,
1618 .vidioc_expbuf = vb2_ioctl_expbuf,
1619 .vidioc_default = ipu_isys_vidioc_private,
1620 .vidioc_enum_input = vidioc_enum_input,
1621 .vidioc_g_input = vidioc_g_input,
1622 .vidioc_s_input = vidioc_s_input,
1623 };
1624
1625 static const struct media_entity_operations entity_ops = {
1626 .link_validate = link_validate,
1627 };
1628
1629 static const struct v4l2_file_operations isys_fops = {
1630 .owner = THIS_MODULE,
1631 .poll = vb2_fop_poll,
1632 .unlocked_ioctl = video_ioctl2,
1633 #ifdef CONFIG_COMPAT
1634 .compat_ioctl32 = ipu_isys_compat_ioctl,
1635 #endif
1636 .mmap = vb2_fop_mmap,
1637 .open = video_open,
1638 .release = video_release,
1639 };
1640
1641 /*
1642 * Do everything that's needed to initialise things related to video
1643 * buffer queue, video node, and the related media entity. The caller
1644 * is expected to assign isys field and set the name of the video
1645 * device.
1646 */
1647 int ipu_isys_video_init(struct ipu_isys_video *av,
1648 struct media_entity *entity,
1649 unsigned int pad, unsigned long pad_flags,
1650 unsigned int flags)
1651 {
1652 const struct v4l2_ioctl_ops *ioctl_ops = NULL;
1653 int rval;
1654
1655 mutex_init(&av->mutex);
1656 init_completion(&av->ip.stream_open_completion);
1657 init_completion(&av->ip.stream_close_completion);
1658 init_completion(&av->ip.stream_start_completion);
1659 init_completion(&av->ip.stream_stop_completion);
1660 INIT_LIST_HEAD(&av->ip.queues);
1661 spin_lock_init(&av->ip.short_packet_queue_lock);
1662 av->ip.isys = av->isys;
1663
1664 if (!av->watermark) {
1665 av->watermark = kzalloc(sizeof(*av->watermark), GFP_KERNEL);
1666 if (!av->watermark) {
1667 rval = -ENOMEM;
1668 goto out_mutex_destroy;
1669 }
1670 }
1671
1672 av->vdev.device_caps = V4L2_CAP_STREAMING;
1673 if (pad_flags & MEDIA_PAD_FL_SINK) {
1674 av->aq.vbq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1675 ioctl_ops = &ioctl_ops_mplane;
1676 av->vdev.device_caps |= V4L2_CAP_VIDEO_CAPTURE_MPLANE;
1677 av->vdev.vfl_dir = VFL_DIR_RX;
1678 } else {
1679 av->aq.vbq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1680 av->vdev.vfl_dir = VFL_DIR_TX;
1681 av->vdev.device_caps |= V4L2_CAP_VIDEO_OUTPUT_MPLANE;
1682 }
1683 rval = ipu_isys_queue_init(&av->aq);
1684 if (rval)
1685 goto out_mutex_destroy;
1686
1687 av->pad.flags = pad_flags | MEDIA_PAD_FL_MUST_CONNECT;
1688 rval = media_entity_pads_init(&av->vdev.entity, 1, &av->pad);
1689 if (rval)
1690 goto out_ipu_isys_queue_cleanup;
1691
1692 av->vdev.entity.ops = &entity_ops;
1693 av->vdev.release = video_device_release_empty;
1694 av->vdev.fops = &isys_fops;
1695 av->vdev.v4l2_dev = &av->isys->v4l2_dev;
1696 if (!av->vdev.ioctl_ops)
1697 av->vdev.ioctl_ops = ioctl_ops;
1698 av->vdev.queue = &av->aq.vbq;
1699 av->vdev.lock = &av->mutex;
1700 set_bit(V4L2_FL_USES_V4L2_FH, &av->vdev.flags);
1701 video_set_drvdata(&av->vdev, av);
1702
1703 mutex_lock(&av->mutex);
1704
1705 rval = video_register_device(&av->vdev, VFL_TYPE_VIDEO, -1);
1706 if (rval)
1707 goto out_media_entity_cleanup;
1708
1709 if (pad_flags & MEDIA_PAD_FL_SINK)
1710 rval = media_create_pad_link(entity, pad,
1711 &av->vdev.entity, 0, flags);
1712 else
1713 rval = media_create_pad_link(&av->vdev.entity, 0, entity,
1714 pad, flags);
1715 if (rval) {
1716 dev_info(&av->isys->adev->dev, "can't create link\n");
1717 goto out_media_entity_cleanup;
1718 }
1719
1720 av->pfmt = av->try_fmt_vid_mplane(av, &av->mpix);
1721
1722 mutex_unlock(&av->mutex);
1723
1724 return rval;
1725
1726 out_media_entity_cleanup:
1727 video_unregister_device(&av->vdev);
1728 mutex_unlock(&av->mutex);
1729 media_entity_cleanup(&av->vdev.entity);
1730
1731 out_ipu_isys_queue_cleanup:
1732 ipu_isys_queue_cleanup(&av->aq);
1733
1734 out_mutex_destroy:
1735 kfree(av->watermark);
1736 mutex_destroy(&av->mutex);
1737
1738 return rval;
1739 }
1740
1741 void ipu_isys_video_cleanup(struct ipu_isys_video *av)
1742 {
1743 kfree(av->watermark);
1744 video_unregister_device(&av->vdev);
1745 media_entity_cleanup(&av->vdev.entity);
1746 mutex_destroy(&av->mutex);
1747 ipu_isys_queue_cleanup(&av->aq);
1748 }