1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <asm/cacheflush.h>
27#include <linux/clk.h>
28#include <linux/mm.h>
29#include <linux/module.h>
30#include <linux/omap-iommu.h>
31#include <linux/pagemap.h>
32#include <linux/scatterlist.h>
33#include <linux/sched.h>
34#include <linux/slab.h>
35#include <linux/vmalloc.h>
36#include <media/v4l2-dev.h>
37#include <media/v4l2-ioctl.h>
38
39#include "ispvideo.h"
40#include "isp.h"
41
42
43
44
45
46
47
48
49
50
51static struct isp_format_info formats[] = {
52 { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
53 V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
54 V4L2_PIX_FMT_GREY, 8, 1, },
55 { V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y10_1X10,
56 V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y8_1X8,
57 V4L2_PIX_FMT_Y10, 10, 2, },
58 { V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y10_1X10,
59 V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y8_1X8,
60 V4L2_PIX_FMT_Y12, 12, 2, },
61 { V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8,
62 V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8,
63 V4L2_PIX_FMT_SBGGR8, 8, 1, },
64 { V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8,
65 V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8,
66 V4L2_PIX_FMT_SGBRG8, 8, 1, },
67 { V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8,
68 V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8,
69 V4L2_PIX_FMT_SGRBG8, 8, 1, },
70 { V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
71 V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
72 V4L2_PIX_FMT_SRGGB8, 8, 1, },
73 { V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8,
74 V4L2_MBUS_FMT_SBGGR10_1X10, 0,
75 V4L2_PIX_FMT_SBGGR10DPCM8, 8, 1, },
76 { V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8,
77 V4L2_MBUS_FMT_SGBRG10_1X10, 0,
78 V4L2_PIX_FMT_SGBRG10DPCM8, 8, 1, },
79 { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
80 V4L2_MBUS_FMT_SGRBG10_1X10, 0,
81 V4L2_PIX_FMT_SGRBG10DPCM8, 8, 1, },
82 { V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8,
83 V4L2_MBUS_FMT_SRGGB10_1X10, 0,
84 V4L2_PIX_FMT_SRGGB10DPCM8, 8, 1, },
85 { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10,
86 V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8,
87 V4L2_PIX_FMT_SBGGR10, 10, 2, },
88 { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10,
89 V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG8_1X8,
90 V4L2_PIX_FMT_SGBRG10, 10, 2, },
91 { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10,
92 V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG8_1X8,
93 V4L2_PIX_FMT_SGRBG10, 10, 2, },
94 { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10,
95 V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB8_1X8,
96 V4L2_PIX_FMT_SRGGB10, 10, 2, },
97 { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10,
98 V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR8_1X8,
99 V4L2_PIX_FMT_SBGGR12, 12, 2, },
100 { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10,
101 V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG8_1X8,
102 V4L2_PIX_FMT_SGBRG12, 12, 2, },
103 { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10,
104 V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG8_1X8,
105 V4L2_PIX_FMT_SGRBG12, 12, 2, },
106 { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10,
107 V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB8_1X8,
108 V4L2_PIX_FMT_SRGGB12, 12, 2, },
109 { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16,
110 V4L2_MBUS_FMT_UYVY8_1X16, 0,
111 V4L2_PIX_FMT_UYVY, 16, 2, },
112 { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16,
113 V4L2_MBUS_FMT_YUYV8_1X16, 0,
114 V4L2_PIX_FMT_YUYV, 16, 2, },
115 { V4L2_MBUS_FMT_UYVY8_2X8, V4L2_MBUS_FMT_UYVY8_2X8,
116 V4L2_MBUS_FMT_UYVY8_2X8, 0,
117 V4L2_PIX_FMT_UYVY, 8, 2, },
118 { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_MBUS_FMT_YUYV8_2X8,
119 V4L2_MBUS_FMT_YUYV8_2X8, 0,
120 V4L2_PIX_FMT_YUYV, 8, 2, },
121
122
123
124 { 0, }
125};
126
127const struct isp_format_info *
128omap3isp_video_format_info(enum v4l2_mbus_pixelcode code)
129{
130 unsigned int i;
131
132 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
133 if (formats[i].code == code)
134 return &formats[i];
135 }
136
137 return NULL;
138}
139
140
141
142
143
144
145
146
147
148
149
150
151
152static unsigned int isp_video_mbus_to_pix(const struct isp_video *video,
153 const struct v4l2_mbus_framefmt *mbus,
154 struct v4l2_pix_format *pix)
155{
156 unsigned int bpl = pix->bytesperline;
157 unsigned int min_bpl;
158 unsigned int i;
159
160 memset(pix, 0, sizeof(*pix));
161 pix->width = mbus->width;
162 pix->height = mbus->height;
163
164 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
165 if (formats[i].code == mbus->code)
166 break;
167 }
168
169 if (WARN_ON(i == ARRAY_SIZE(formats)))
170 return 0;
171
172 min_bpl = pix->width * formats[i].bpp;
173
174
175
176
177
178 if (video->bpl_max)
179 bpl = clamp(bpl, min_bpl, video->bpl_max);
180 else
181 bpl = min_bpl;
182
183 if (!video->bpl_zero_padding || bpl != min_bpl)
184 bpl = ALIGN(bpl, video->bpl_alignment);
185
186 pix->pixelformat = formats[i].pixelformat;
187 pix->bytesperline = bpl;
188 pix->sizeimage = pix->bytesperline * pix->height;
189 pix->colorspace = mbus->colorspace;
190 pix->field = mbus->field;
191
192 return bpl - min_bpl;
193}
194
195static void isp_video_pix_to_mbus(const struct v4l2_pix_format *pix,
196 struct v4l2_mbus_framefmt *mbus)
197{
198 unsigned int i;
199
200 memset(mbus, 0, sizeof(*mbus));
201 mbus->width = pix->width;
202 mbus->height = pix->height;
203
204
205
206
207 for (i = 0; i < ARRAY_SIZE(formats) - 1; ++i) {
208 if (formats[i].pixelformat == pix->pixelformat)
209 break;
210 }
211
212 mbus->code = formats[i].code;
213 mbus->colorspace = pix->colorspace;
214 mbus->field = pix->field;
215}
216
217static struct v4l2_subdev *
218isp_video_remote_subdev(struct isp_video *video, u32 *pad)
219{
220 struct media_pad *remote;
221
222 remote = media_entity_remote_source(&video->pad);
223
224 if (remote == NULL ||
225 media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
226 return NULL;
227
228 if (pad)
229 *pad = remote->index;
230
231 return media_entity_to_v4l2_subdev(remote->entity);
232}
233
234
235static int isp_video_get_graph_data(struct isp_video *video,
236 struct isp_pipeline *pipe)
237{
238 struct media_entity_graph graph;
239 struct media_entity *entity = &video->video.entity;
240 struct media_device *mdev = entity->parent;
241 struct isp_video *far_end = NULL;
242
243 mutex_lock(&mdev->graph_mutex);
244 media_entity_graph_walk_start(&graph, entity);
245
246 while ((entity = media_entity_graph_walk_next(&graph))) {
247 struct isp_video *__video;
248
249 pipe->entities |= 1 << entity->id;
250
251 if (far_end != NULL)
252 continue;
253
254 if (entity == &video->video.entity)
255 continue;
256
257 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
258 continue;
259
260 __video = to_isp_video(media_entity_to_video_device(entity));
261 if (__video->type != video->type)
262 far_end = __video;
263 }
264
265 mutex_unlock(&mdev->graph_mutex);
266
267 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
268 pipe->input = far_end;
269 pipe->output = video;
270 } else {
271 if (far_end == NULL)
272 return -EPIPE;
273
274 pipe->input = video;
275 pipe->output = far_end;
276 }
277
278 return 0;
279}
280
281
282
283
284
285
286
287
288
289
290
291
292static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
293{
294 struct isp_device *isp = pipe->output->isp;
295 struct media_pad *pad;
296 struct v4l2_subdev *subdev;
297
298 subdev = isp_video_remote_subdev(pipe->output, NULL);
299 if (subdev == NULL)
300 return -EPIPE;
301
302 while (1) {
303
304 pad = &subdev->entity.pads[0];
305 if (!(pad->flags & MEDIA_PAD_FL_SINK))
306 break;
307
308
309 if (subdev == &isp->isp_res.subdev)
310 omap3isp_resizer_max_rate(&isp->isp_res,
311 &pipe->max_rate);
312
313
314
315
316
317 pad = media_entity_remote_source(pad);
318 if (pad == NULL)
319 return -EPIPE;
320
321 if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
322 break;
323
324 subdev = media_entity_to_v4l2_subdev(pad->entity);
325 }
326
327 return 0;
328}
329
330static int
331__isp_video_get_format(struct isp_video *video, struct v4l2_format *format)
332{
333 struct v4l2_subdev_format fmt;
334 struct v4l2_subdev *subdev;
335 u32 pad;
336 int ret;
337
338 subdev = isp_video_remote_subdev(video, &pad);
339 if (subdev == NULL)
340 return -EINVAL;
341
342 mutex_lock(&video->mutex);
343
344 fmt.pad = pad;
345 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
346 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
347 if (ret == -ENOIOCTLCMD)
348 ret = -EINVAL;
349
350 mutex_unlock(&video->mutex);
351
352 if (ret)
353 return ret;
354
355 format->type = video->type;
356 return isp_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
357}
358
359static int
360isp_video_check_format(struct isp_video *video, struct isp_video_fh *vfh)
361{
362 struct v4l2_format format;
363 int ret;
364
365 memcpy(&format, &vfh->format, sizeof(format));
366 ret = __isp_video_get_format(video, &format);
367 if (ret < 0)
368 return ret;
369
370 if (vfh->format.fmt.pix.pixelformat != format.fmt.pix.pixelformat ||
371 vfh->format.fmt.pix.height != format.fmt.pix.height ||
372 vfh->format.fmt.pix.width != format.fmt.pix.width ||
373 vfh->format.fmt.pix.bytesperline != format.fmt.pix.bytesperline ||
374 vfh->format.fmt.pix.sizeimage != format.fmt.pix.sizeimage)
375 return -EINVAL;
376
377 return ret;
378}
379
380
381
382
383
384#define IOMMU_FLAG (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8)
385
386
387
388
389
390
391
392
393
394
395static dma_addr_t
396ispmmu_vmap(struct isp_device *isp, const struct scatterlist *sglist, int sglen)
397{
398 struct sg_table *sgt;
399 u32 da;
400
401 sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
402 if (sgt == NULL)
403 return -ENOMEM;
404
405 sgt->sgl = (struct scatterlist *)sglist;
406 sgt->nents = sglen;
407 sgt->orig_nents = sglen;
408
409 da = omap_iommu_vmap(isp->domain, isp->dev, 0, sgt, IOMMU_FLAG);
410 if (IS_ERR_VALUE(da))
411 kfree(sgt);
412
413 return da;
414}
415
416
417
418
419
420
421static void ispmmu_vunmap(struct isp_device *isp, dma_addr_t da)
422{
423 struct sg_table *sgt;
424
425 sgt = omap_iommu_vunmap(isp->domain, isp->dev, (u32)da);
426 kfree(sgt);
427}
428
429
430
431
432
433static void isp_video_queue_prepare(struct isp_video_queue *queue,
434 unsigned int *nbuffers, unsigned int *size)
435{
436 struct isp_video_fh *vfh =
437 container_of(queue, struct isp_video_fh, queue);
438 struct isp_video *video = vfh->video;
439
440 *size = vfh->format.fmt.pix.sizeimage;
441 if (*size == 0)
442 return;
443
444 *nbuffers = min(*nbuffers, video->capture_mem / PAGE_ALIGN(*size));
445}
446
447static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
448{
449 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
450 struct isp_buffer *buffer = to_isp_buffer(buf);
451 struct isp_video *video = vfh->video;
452
453 if (buffer->isp_addr) {
454 ispmmu_vunmap(video->isp, buffer->isp_addr);
455 buffer->isp_addr = 0;
456 }
457}
458
459static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
460{
461 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
462 struct isp_buffer *buffer = to_isp_buffer(buf);
463 struct isp_video *video = vfh->video;
464 unsigned long addr;
465
466 addr = ispmmu_vmap(video->isp, buf->sglist, buf->sglen);
467 if (IS_ERR_VALUE(addr))
468 return -EIO;
469
470 if (!IS_ALIGNED(addr, 32)) {
471 dev_dbg(video->isp->dev, "Buffer address must be "
472 "aligned to 32 bytes boundary.\n");
473 ispmmu_vunmap(video->isp, buffer->isp_addr);
474 return -EINVAL;
475 }
476
477 buf->vbuf.bytesused = vfh->format.fmt.pix.sizeimage;
478 buffer->isp_addr = addr;
479 return 0;
480}
481
482
483
484
485
486
487
488
489
490
491static void isp_video_buffer_queue(struct isp_video_buffer *buf)
492{
493 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
494 struct isp_buffer *buffer = to_isp_buffer(buf);
495 struct isp_video *video = vfh->video;
496 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
497 enum isp_pipeline_state state;
498 unsigned long flags;
499 unsigned int empty;
500 unsigned int start;
501
502 empty = list_empty(&video->dmaqueue);
503 list_add_tail(&buffer->buffer.irqlist, &video->dmaqueue);
504
505 if (empty) {
506 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
507 state = ISP_PIPELINE_QUEUE_OUTPUT;
508 else
509 state = ISP_PIPELINE_QUEUE_INPUT;
510
511 spin_lock_irqsave(&pipe->lock, flags);
512 pipe->state |= state;
513 video->ops->queue(video, buffer);
514 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_QUEUED;
515
516 start = isp_pipeline_ready(pipe);
517 if (start)
518 pipe->state |= ISP_PIPELINE_STREAM;
519 spin_unlock_irqrestore(&pipe->lock, flags);
520
521 if (start)
522 omap3isp_pipeline_set_stream(pipe,
523 ISP_PIPELINE_STREAM_SINGLESHOT);
524 }
525}
526
527static const struct isp_video_queue_operations isp_video_queue_ops = {
528 .queue_prepare = &isp_video_queue_prepare,
529 .buffer_prepare = &isp_video_buffer_prepare,
530 .buffer_queue = &isp_video_buffer_queue,
531 .buffer_cleanup = &isp_video_buffer_cleanup,
532};
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
551{
552 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
553 struct isp_video_queue *queue = video->queue;
554 enum isp_pipeline_state state;
555 struct isp_video_buffer *buf;
556 unsigned long flags;
557 struct timespec ts;
558
559 spin_lock_irqsave(&queue->irqlock, flags);
560 if (WARN_ON(list_empty(&video->dmaqueue))) {
561 spin_unlock_irqrestore(&queue->irqlock, flags);
562 return NULL;
563 }
564
565 buf = list_first_entry(&video->dmaqueue, struct isp_video_buffer,
566 irqlist);
567 list_del(&buf->irqlist);
568 spin_unlock_irqrestore(&queue->irqlock, flags);
569
570 ktime_get_ts(&ts);
571 buf->vbuf.timestamp.tv_sec = ts.tv_sec;
572 buf->vbuf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
573
574
575
576
577
578
579
580 if (video == pipe->output && !pipe->do_propagation)
581 buf->vbuf.sequence = atomic_inc_return(&pipe->frame_number);
582 else
583 buf->vbuf.sequence = atomic_read(&pipe->frame_number);
584
585
586 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->error) {
587 buf->state = ISP_BUF_STATE_ERROR;
588 pipe->error = false;
589 } else {
590 buf->state = ISP_BUF_STATE_DONE;
591 }
592
593 wake_up(&buf->wait);
594
595 if (list_empty(&video->dmaqueue)) {
596 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
597 state = ISP_PIPELINE_QUEUE_OUTPUT
598 | ISP_PIPELINE_STREAM;
599 else
600 state = ISP_PIPELINE_QUEUE_INPUT
601 | ISP_PIPELINE_STREAM;
602
603 spin_lock_irqsave(&pipe->lock, flags);
604 pipe->state &= ~state;
605 if (video->pipe.stream_state == ISP_PIPELINE_STREAM_CONTINUOUS)
606 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
607 spin_unlock_irqrestore(&pipe->lock, flags);
608 return NULL;
609 }
610
611 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->input != NULL) {
612 spin_lock_irqsave(&pipe->lock, flags);
613 pipe->state &= ~ISP_PIPELINE_STREAM;
614 spin_unlock_irqrestore(&pipe->lock, flags);
615 }
616
617 buf = list_first_entry(&video->dmaqueue, struct isp_video_buffer,
618 irqlist);
619 buf->state = ISP_BUF_STATE_ACTIVE;
620 return to_isp_buffer(buf);
621}
622
623
624
625
626
627
628
629
630
631
632
633void omap3isp_video_resume(struct isp_video *video, int continuous)
634{
635 struct isp_buffer *buf = NULL;
636
637 if (continuous && video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
638 omap3isp_video_queue_discard_done(video->queue);
639
640 if (!list_empty(&video->dmaqueue)) {
641 buf = list_first_entry(&video->dmaqueue,
642 struct isp_buffer, buffer.irqlist);
643 video->ops->queue(video, buf);
644 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_QUEUED;
645 } else {
646 if (continuous)
647 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
648 }
649}
650
651
652
653
654
655static int
656isp_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
657{
658 struct isp_video *video = video_drvdata(file);
659
660 strlcpy(cap->driver, ISP_VIDEO_DRIVER_NAME, sizeof(cap->driver));
661 strlcpy(cap->card, video->video.name, sizeof(cap->card));
662 strlcpy(cap->bus_info, "media", sizeof(cap->bus_info));
663
664 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
665 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
666 else
667 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
668
669 return 0;
670}
671
672static int
673isp_video_get_format(struct file *file, void *fh, struct v4l2_format *format)
674{
675 struct isp_video_fh *vfh = to_isp_video_fh(fh);
676 struct isp_video *video = video_drvdata(file);
677
678 if (format->type != video->type)
679 return -EINVAL;
680
681 mutex_lock(&video->mutex);
682 *format = vfh->format;
683 mutex_unlock(&video->mutex);
684
685 return 0;
686}
687
688static int
689isp_video_set_format(struct file *file, void *fh, struct v4l2_format *format)
690{
691 struct isp_video_fh *vfh = to_isp_video_fh(fh);
692 struct isp_video *video = video_drvdata(file);
693 struct v4l2_mbus_framefmt fmt;
694
695 if (format->type != video->type)
696 return -EINVAL;
697
698 mutex_lock(&video->mutex);
699
700
701
702
703 isp_video_pix_to_mbus(&format->fmt.pix, &fmt);
704 isp_video_mbus_to_pix(video, &fmt, &format->fmt.pix);
705
706 vfh->format = *format;
707
708 mutex_unlock(&video->mutex);
709 return 0;
710}
711
712static int
713isp_video_try_format(struct file *file, void *fh, struct v4l2_format *format)
714{
715 struct isp_video *video = video_drvdata(file);
716 struct v4l2_subdev_format fmt;
717 struct v4l2_subdev *subdev;
718 u32 pad;
719 int ret;
720
721 if (format->type != video->type)
722 return -EINVAL;
723
724 subdev = isp_video_remote_subdev(video, &pad);
725 if (subdev == NULL)
726 return -EINVAL;
727
728 isp_video_pix_to_mbus(&format->fmt.pix, &fmt.format);
729
730 fmt.pad = pad;
731 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
732 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
733 if (ret)
734 return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
735
736 isp_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
737 return 0;
738}
739
740static int
741isp_video_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
742{
743 struct isp_video *video = video_drvdata(file);
744 struct v4l2_subdev *subdev;
745 int ret;
746
747 subdev = isp_video_remote_subdev(video, NULL);
748 if (subdev == NULL)
749 return -EINVAL;
750
751 mutex_lock(&video->mutex);
752 ret = v4l2_subdev_call(subdev, video, cropcap, cropcap);
753 mutex_unlock(&video->mutex);
754
755 return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
756}
757
758static int
759isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop)
760{
761 struct isp_video *video = video_drvdata(file);
762 struct v4l2_subdev_format format;
763 struct v4l2_subdev *subdev;
764 u32 pad;
765 int ret;
766
767 subdev = isp_video_remote_subdev(video, &pad);
768 if (subdev == NULL)
769 return -EINVAL;
770
771
772
773
774 ret = v4l2_subdev_call(subdev, video, g_crop, crop);
775 if (ret != -ENOIOCTLCMD)
776 return ret;
777
778 format.pad = pad;
779 format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
780 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &format);
781 if (ret < 0)
782 return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
783
784 crop->c.left = 0;
785 crop->c.top = 0;
786 crop->c.width = format.format.width;
787 crop->c.height = format.format.height;
788
789 return 0;
790}
791
792static int
793isp_video_set_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
794{
795 struct isp_video *video = video_drvdata(file);
796 struct v4l2_subdev *subdev;
797 int ret;
798
799 subdev = isp_video_remote_subdev(video, NULL);
800 if (subdev == NULL)
801 return -EINVAL;
802
803 mutex_lock(&video->mutex);
804 ret = v4l2_subdev_call(subdev, video, s_crop, crop);
805 mutex_unlock(&video->mutex);
806
807 return ret == -ENOIOCTLCMD ? -ENOTTY : ret;
808}
809
810static int
811isp_video_get_param(struct file *file, void *fh, struct v4l2_streamparm *a)
812{
813 struct isp_video_fh *vfh = to_isp_video_fh(fh);
814 struct isp_video *video = video_drvdata(file);
815
816 if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
817 video->type != a->type)
818 return -EINVAL;
819
820 memset(a, 0, sizeof(*a));
821 a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
822 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
823 a->parm.output.timeperframe = vfh->timeperframe;
824
825 return 0;
826}
827
828static int
829isp_video_set_param(struct file *file, void *fh, struct v4l2_streamparm *a)
830{
831 struct isp_video_fh *vfh = to_isp_video_fh(fh);
832 struct isp_video *video = video_drvdata(file);
833
834 if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
835 video->type != a->type)
836 return -EINVAL;
837
838 if (a->parm.output.timeperframe.denominator == 0)
839 a->parm.output.timeperframe.denominator = 1;
840
841 vfh->timeperframe = a->parm.output.timeperframe;
842
843 return 0;
844}
845
846static int
847isp_video_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb)
848{
849 struct isp_video_fh *vfh = to_isp_video_fh(fh);
850
851 return omap3isp_video_queue_reqbufs(&vfh->queue, rb);
852}
853
854static int
855isp_video_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
856{
857 struct isp_video_fh *vfh = to_isp_video_fh(fh);
858
859 return omap3isp_video_queue_querybuf(&vfh->queue, b);
860}
861
862static int
863isp_video_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
864{
865 struct isp_video_fh *vfh = to_isp_video_fh(fh);
866
867 return omap3isp_video_queue_qbuf(&vfh->queue, b);
868}
869
870static int
871isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
872{
873 struct isp_video_fh *vfh = to_isp_video_fh(fh);
874
875 return omap3isp_video_queue_dqbuf(&vfh->queue, b,
876 file->f_flags & O_NONBLOCK);
877}
878
879static int isp_video_check_external_subdevs(struct isp_video *video,
880 struct isp_pipeline *pipe)
881{
882 struct isp_device *isp = video->isp;
883 struct media_entity *ents[] = {
884 &isp->isp_csi2a.subdev.entity,
885 &isp->isp_csi2c.subdev.entity,
886 &isp->isp_ccp2.subdev.entity,
887 &isp->isp_ccdc.subdev.entity
888 };
889 struct media_pad *source_pad;
890 struct media_entity *source = NULL;
891 struct media_entity *sink;
892 struct v4l2_subdev_format fmt;
893 struct v4l2_ext_controls ctrls;
894 struct v4l2_ext_control ctrl;
895 unsigned int i;
896 int ret = 0;
897
898 for (i = 0; i < ARRAY_SIZE(ents); i++) {
899
900 if (!(pipe->entities & (1 << ents[i]->id)))
901 continue;
902
903
904 source_pad = media_entity_remote_source(&ents[i]->pads[0]);
905 if (source_pad == NULL)
906 continue;
907
908 source = source_pad->entity;
909 sink = ents[i];
910 break;
911 }
912
913 if (!source) {
914 dev_warn(isp->dev, "can't find source, failing now\n");
915 return ret;
916 }
917
918 if (media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
919 return 0;
920
921 pipe->external = media_entity_to_v4l2_subdev(source);
922
923 fmt.pad = source_pad->index;
924 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
925 ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(sink),
926 pad, get_fmt, NULL, &fmt);
927 if (unlikely(ret < 0)) {
928 dev_warn(isp->dev, "get_fmt returned null!\n");
929 return ret;
930 }
931
932 pipe->external_width =
933 omap3isp_video_format_info(fmt.format.code)->width;
934
935 memset(&ctrls, 0, sizeof(ctrls));
936 memset(&ctrl, 0, sizeof(ctrl));
937
938 ctrl.id = V4L2_CID_PIXEL_RATE;
939
940 ctrls.count = 1;
941 ctrls.controls = &ctrl;
942
943 ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls);
944 if (ret < 0) {
945 dev_warn(isp->dev, "no pixel rate control in subdev %s\n",
946 pipe->external->name);
947 return ret;
948 }
949
950 pipe->external_rate = ctrl.value64;
951
952 if (pipe->entities & (1 << isp->isp_ccdc.subdev.entity.id)) {
953 unsigned int rate = UINT_MAX;
954
955
956
957
958 omap3isp_ccdc_max_rate(&isp->isp_ccdc, &rate);
959 if (pipe->external_rate > rate)
960 return -ENOSPC;
961 }
962
963 return 0;
964}
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997static int
998isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
999{
1000 struct isp_video_fh *vfh = to_isp_video_fh(fh);
1001 struct isp_video *video = video_drvdata(file);
1002 enum isp_pipeline_state state;
1003 struct isp_pipeline *pipe;
1004 unsigned long flags;
1005 int ret;
1006
1007 if (type != video->type)
1008 return -EINVAL;
1009
1010 mutex_lock(&video->stream_lock);
1011
1012 if (video->streaming) {
1013 mutex_unlock(&video->stream_lock);
1014 return -EBUSY;
1015 }
1016
1017
1018
1019
1020 pipe = video->video.entity.pipe
1021 ? to_isp_pipeline(&video->video.entity) : &video->pipe;
1022
1023 pipe->entities = 0;
1024
1025 if (video->isp->pdata->set_constraints)
1026 video->isp->pdata->set_constraints(video->isp, true);
1027 pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
1028 pipe->max_rate = pipe->l3_ick;
1029
1030 ret = media_entity_pipeline_start(&video->video.entity, &pipe->pipe);
1031 if (ret < 0)
1032 goto err_pipeline_start;
1033
1034
1035
1036
1037 ret = isp_video_check_format(video, vfh);
1038 if (ret < 0)
1039 goto err_check_format;
1040
1041 video->bpl_padding = ret;
1042 video->bpl_value = vfh->format.fmt.pix.bytesperline;
1043
1044 ret = isp_video_get_graph_data(video, pipe);
1045 if (ret < 0)
1046 goto err_check_format;
1047
1048 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1049 state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
1050 else
1051 state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
1052
1053 ret = isp_video_check_external_subdevs(video, pipe);
1054 if (ret < 0)
1055 goto err_check_format;
1056
1057
1058 ret = isp_video_validate_pipeline(pipe);
1059 if (ret < 0)
1060 goto err_check_format;
1061
1062 pipe->error = false;
1063
1064 spin_lock_irqsave(&pipe->lock, flags);
1065 pipe->state &= ~ISP_PIPELINE_STREAM;
1066 pipe->state |= state;
1067 spin_unlock_irqrestore(&pipe->lock, flags);
1068
1069
1070
1071
1072
1073 if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1074 pipe->max_timeperframe = vfh->timeperframe;
1075
1076 video->queue = &vfh->queue;
1077 INIT_LIST_HEAD(&video->dmaqueue);
1078 atomic_set(&pipe->frame_number, -1);
1079
1080 ret = omap3isp_video_queue_streamon(&vfh->queue);
1081 if (ret < 0)
1082 goto err_check_format;
1083
1084
1085
1086
1087
1088 if (pipe->input == NULL) {
1089 ret = omap3isp_pipeline_set_stream(pipe,
1090 ISP_PIPELINE_STREAM_CONTINUOUS);
1091 if (ret < 0)
1092 goto err_set_stream;
1093 spin_lock_irqsave(&video->queue->irqlock, flags);
1094 if (list_empty(&video->dmaqueue))
1095 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
1096 spin_unlock_irqrestore(&video->queue->irqlock, flags);
1097 }
1098
1099 video->streaming = 1;
1100
1101 mutex_unlock(&video->stream_lock);
1102 return 0;
1103
1104err_set_stream:
1105 omap3isp_video_queue_streamoff(&vfh->queue);
1106err_check_format:
1107 media_entity_pipeline_stop(&video->video.entity);
1108err_pipeline_start:
1109 if (video->isp->pdata->set_constraints)
1110 video->isp->pdata->set_constraints(video->isp, false);
1111
1112
1113
1114
1115
1116
1117
1118 INIT_LIST_HEAD(&video->dmaqueue);
1119 video->queue = NULL;
1120
1121 mutex_unlock(&video->stream_lock);
1122 return ret;
1123}
1124
1125static int
1126isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
1127{
1128 struct isp_video_fh *vfh = to_isp_video_fh(fh);
1129 struct isp_video *video = video_drvdata(file);
1130 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
1131 enum isp_pipeline_state state;
1132 unsigned int streaming;
1133 unsigned long flags;
1134
1135 if (type != video->type)
1136 return -EINVAL;
1137
1138 mutex_lock(&video->stream_lock);
1139
1140
1141 mutex_lock(&vfh->queue.lock);
1142 streaming = vfh->queue.streaming;
1143 mutex_unlock(&vfh->queue.lock);
1144
1145 if (!streaming)
1146 goto done;
1147
1148
1149 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1150 state = ISP_PIPELINE_STREAM_OUTPUT
1151 | ISP_PIPELINE_QUEUE_OUTPUT;
1152 else
1153 state = ISP_PIPELINE_STREAM_INPUT
1154 | ISP_PIPELINE_QUEUE_INPUT;
1155
1156 spin_lock_irqsave(&pipe->lock, flags);
1157 pipe->state &= ~state;
1158 spin_unlock_irqrestore(&pipe->lock, flags);
1159
1160
1161 omap3isp_pipeline_set_stream(pipe, ISP_PIPELINE_STREAM_STOPPED);
1162 omap3isp_video_queue_streamoff(&vfh->queue);
1163 video->queue = NULL;
1164 video->streaming = 0;
1165
1166 if (video->isp->pdata->set_constraints)
1167 video->isp->pdata->set_constraints(video->isp, false);
1168 media_entity_pipeline_stop(&video->video.entity);
1169
1170done:
1171 mutex_unlock(&video->stream_lock);
1172 return 0;
1173}
1174
1175static int
1176isp_video_enum_input(struct file *file, void *fh, struct v4l2_input *input)
1177{
1178 if (input->index > 0)
1179 return -EINVAL;
1180
1181 strlcpy(input->name, "camera", sizeof(input->name));
1182 input->type = V4L2_INPUT_TYPE_CAMERA;
1183
1184 return 0;
1185}
1186
1187static int
1188isp_video_g_input(struct file *file, void *fh, unsigned int *input)
1189{
1190 *input = 0;
1191
1192 return 0;
1193}
1194
1195static int
1196isp_video_s_input(struct file *file, void *fh, unsigned int input)
1197{
1198 return input == 0 ? 0 : -EINVAL;
1199}
1200
1201static const struct v4l2_ioctl_ops isp_video_ioctl_ops = {
1202 .vidioc_querycap = isp_video_querycap,
1203 .vidioc_g_fmt_vid_cap = isp_video_get_format,
1204 .vidioc_s_fmt_vid_cap = isp_video_set_format,
1205 .vidioc_try_fmt_vid_cap = isp_video_try_format,
1206 .vidioc_g_fmt_vid_out = isp_video_get_format,
1207 .vidioc_s_fmt_vid_out = isp_video_set_format,
1208 .vidioc_try_fmt_vid_out = isp_video_try_format,
1209 .vidioc_cropcap = isp_video_cropcap,
1210 .vidioc_g_crop = isp_video_get_crop,
1211 .vidioc_s_crop = isp_video_set_crop,
1212 .vidioc_g_parm = isp_video_get_param,
1213 .vidioc_s_parm = isp_video_set_param,
1214 .vidioc_reqbufs = isp_video_reqbufs,
1215 .vidioc_querybuf = isp_video_querybuf,
1216 .vidioc_qbuf = isp_video_qbuf,
1217 .vidioc_dqbuf = isp_video_dqbuf,
1218 .vidioc_streamon = isp_video_streamon,
1219 .vidioc_streamoff = isp_video_streamoff,
1220 .vidioc_enum_input = isp_video_enum_input,
1221 .vidioc_g_input = isp_video_g_input,
1222 .vidioc_s_input = isp_video_s_input,
1223};
1224
1225
1226
1227
1228
1229static int isp_video_open(struct file *file)
1230{
1231 struct isp_video *video = video_drvdata(file);
1232 struct isp_video_fh *handle;
1233 int ret = 0;
1234
1235 handle = kzalloc(sizeof(*handle), GFP_KERNEL);
1236 if (handle == NULL)
1237 return -ENOMEM;
1238
1239 v4l2_fh_init(&handle->vfh, &video->video);
1240 v4l2_fh_add(&handle->vfh);
1241
1242
1243 if (omap3isp_get(video->isp) == NULL) {
1244 ret = -EBUSY;
1245 goto done;
1246 }
1247
1248 ret = omap3isp_pipeline_pm_use(&video->video.entity, 1);
1249 if (ret < 0) {
1250 omap3isp_put(video->isp);
1251 goto done;
1252 }
1253
1254 omap3isp_video_queue_init(&handle->queue, video->type,
1255 &isp_video_queue_ops, video->isp->dev,
1256 sizeof(struct isp_buffer));
1257
1258 memset(&handle->format, 0, sizeof(handle->format));
1259 handle->format.type = video->type;
1260 handle->timeperframe.denominator = 1;
1261
1262 handle->video = video;
1263 file->private_data = &handle->vfh;
1264
1265done:
1266 if (ret < 0) {
1267 v4l2_fh_del(&handle->vfh);
1268 kfree(handle);
1269 }
1270
1271 return ret;
1272}
1273
1274static int isp_video_release(struct file *file)
1275{
1276 struct isp_video *video = video_drvdata(file);
1277 struct v4l2_fh *vfh = file->private_data;
1278 struct isp_video_fh *handle = to_isp_video_fh(vfh);
1279
1280
1281 isp_video_streamoff(file, vfh, video->type);
1282
1283 mutex_lock(&handle->queue.lock);
1284 omap3isp_video_queue_cleanup(&handle->queue);
1285 mutex_unlock(&handle->queue.lock);
1286
1287 omap3isp_pipeline_pm_use(&video->video.entity, 0);
1288
1289
1290 v4l2_fh_del(vfh);
1291 kfree(handle);
1292 file->private_data = NULL;
1293
1294 omap3isp_put(video->isp);
1295
1296 return 0;
1297}
1298
1299static unsigned int isp_video_poll(struct file *file, poll_table *wait)
1300{
1301 struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
1302 struct isp_video_queue *queue = &vfh->queue;
1303
1304 return omap3isp_video_queue_poll(queue, file, wait);
1305}
1306
1307static int isp_video_mmap(struct file *file, struct vm_area_struct *vma)
1308{
1309 struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
1310
1311 return omap3isp_video_queue_mmap(&vfh->queue, vma);
1312}
1313
1314static struct v4l2_file_operations isp_video_fops = {
1315 .owner = THIS_MODULE,
1316 .unlocked_ioctl = video_ioctl2,
1317 .open = isp_video_open,
1318 .release = isp_video_release,
1319 .poll = isp_video_poll,
1320 .mmap = isp_video_mmap,
1321};
1322
1323
1324
1325
1326
1327static const struct isp_video_operations isp_video_dummy_ops = {
1328};
1329
1330int omap3isp_video_init(struct isp_video *video, const char *name)
1331{
1332 const char *direction;
1333 int ret;
1334
1335 switch (video->type) {
1336 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1337 direction = "output";
1338 video->pad.flags = MEDIA_PAD_FL_SINK;
1339 break;
1340 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1341 direction = "input";
1342 video->pad.flags = MEDIA_PAD_FL_SOURCE;
1343 video->video.vfl_dir = VFL_DIR_TX;
1344 break;
1345
1346 default:
1347 return -EINVAL;
1348 }
1349
1350 ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
1351 if (ret < 0)
1352 return ret;
1353
1354 mutex_init(&video->mutex);
1355 atomic_set(&video->active, 0);
1356
1357 spin_lock_init(&video->pipe.lock);
1358 mutex_init(&video->stream_lock);
1359
1360
1361 if (video->ops == NULL)
1362 video->ops = &isp_video_dummy_ops;
1363
1364 video->video.fops = &isp_video_fops;
1365 snprintf(video->video.name, sizeof(video->video.name),
1366 "OMAP3 ISP %s %s", name, direction);
1367 video->video.vfl_type = VFL_TYPE_GRABBER;
1368 video->video.release = video_device_release_empty;
1369 video->video.ioctl_ops = &isp_video_ioctl_ops;
1370 video->pipe.stream_state = ISP_PIPELINE_STREAM_STOPPED;
1371
1372 video_set_drvdata(&video->video, video);
1373
1374 return 0;
1375}
1376
1377void omap3isp_video_cleanup(struct isp_video *video)
1378{
1379 media_entity_cleanup(&video->video.entity);
1380 mutex_destroy(&video->stream_lock);
1381 mutex_destroy(&video->mutex);
1382}
1383
1384int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev)
1385{
1386 int ret;
1387
1388 video->video.v4l2_dev = vdev;
1389
1390 ret = video_register_device(&video->video, VFL_TYPE_GRABBER, -1);
1391 if (ret < 0)
1392 dev_err(video->isp->dev,
1393 "%s: could not register video device (%d)\n",
1394 __func__, ret);
1395
1396 return ret;
1397}
1398
1399void omap3isp_video_unregister(struct isp_video *video)
1400{
1401 if (video_is_registered(&video->video))
1402 video_unregister_device(&video->video);
1403}
1404