1
2
3
4
5#include <linux/kernel.h>
6#include <linux/init.h>
7#include <linux/module.h>
8#include <linux/errno.h>
9#include <linux/interrupt.h>
10#include <linux/string.h>
11#include <linux/wait.h>
12#include <linux/time.h>
13#include <linux/platform_device.h>
14#include <linux/irq.h>
15#include <linux/mm.h>
16#include <linux/mutex.h>
17#include <linux/videodev2.h>
18#include <linux/slab.h>
19
20
21#include <media/v4l2-dev.h>
22#include <media/v4l2-common.h>
23#include <media/v4l2-ioctl.h>
24#include <media/v4l2-device.h>
25#include <media/davinci/vpbe_display.h>
26#include <media/davinci/vpbe_types.h>
27#include <media/davinci/vpbe.h>
28#include <media/davinci/vpbe_venc.h>
29#include <media/davinci/vpbe_osd.h>
30#include "vpbe_venc_regs.h"
31
32#define VPBE_DISPLAY_DRIVER "vpbe-v4l2"
33
34static int debug;
35
36#define VPBE_DEFAULT_NUM_BUFS 3
37
38module_param(debug, int, 0644);
39
40static int vpbe_set_osd_display_params(struct vpbe_display *disp_dev,
41 struct vpbe_layer *layer);
42
43static int venc_is_second_field(struct vpbe_display *disp_dev)
44{
45 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
46 int ret, val;
47
48 ret = v4l2_subdev_call(vpbe_dev->venc,
49 core,
50 command,
51 VENC_GET_FLD,
52 &val);
53 if (ret < 0) {
54 v4l2_err(&vpbe_dev->v4l2_dev,
55 "Error in getting Field ID 0\n");
56 return 1;
57 }
58 return val;
59}
60
61static void vpbe_isr_even_field(struct vpbe_display *disp_obj,
62 struct vpbe_layer *layer)
63{
64 if (layer->cur_frm == layer->next_frm)
65 return;
66
67 layer->cur_frm->vb.vb2_buf.timestamp = ktime_get_ns();
68 vb2_buffer_done(&layer->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
69
70 layer->cur_frm = layer->next_frm;
71}
72
73static void vpbe_isr_odd_field(struct vpbe_display *disp_obj,
74 struct vpbe_layer *layer)
75{
76 struct osd_state *osd_device = disp_obj->osd_device;
77 unsigned long addr;
78
79 spin_lock(&disp_obj->dma_queue_lock);
80 if (list_empty(&layer->dma_queue) ||
81 (layer->cur_frm != layer->next_frm)) {
82 spin_unlock(&disp_obj->dma_queue_lock);
83 return;
84 }
85
86
87
88
89
90
91 layer->next_frm = list_entry(layer->dma_queue.next,
92 struct vpbe_disp_buffer, list);
93
94 list_del(&layer->next_frm->list);
95 spin_unlock(&disp_obj->dma_queue_lock);
96
97 layer->next_frm->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
98 addr = vb2_dma_contig_plane_dma_addr(&layer->next_frm->vb.vb2_buf, 0);
99 osd_device->ops.start_layer(osd_device,
100 layer->layer_info.id,
101 addr,
102 disp_obj->cbcr_ofst);
103}
104
105
106static irqreturn_t venc_isr(int irq, void *arg)
107{
108 struct vpbe_display *disp_dev = (struct vpbe_display *)arg;
109 struct vpbe_layer *layer;
110 static unsigned last_event;
111 unsigned event = 0;
112 int fid;
113 int i;
114
115 if (!arg || !disp_dev->dev[0])
116 return IRQ_HANDLED;
117
118 if (venc_is_second_field(disp_dev))
119 event |= VENC_SECOND_FIELD;
120 else
121 event |= VENC_FIRST_FIELD;
122
123 if (event == (last_event & ~VENC_END_OF_FRAME)) {
124
125
126
127
128
129
130
131 event |= VENC_END_OF_FRAME;
132 } else if (event == VENC_SECOND_FIELD) {
133
134 event |= VENC_END_OF_FRAME;
135 }
136 last_event = event;
137
138 for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
139 layer = disp_dev->dev[i];
140
141 if (!vb2_start_streaming_called(&layer->buffer_queue))
142 continue;
143
144 if (layer->layer_first_int) {
145 layer->layer_first_int = 0;
146 continue;
147 }
148
149 if ((V4L2_FIELD_NONE == layer->pix_fmt.field) &&
150 (event & VENC_END_OF_FRAME)) {
151
152
153 vpbe_isr_even_field(disp_dev, layer);
154 vpbe_isr_odd_field(disp_dev, layer);
155 } else {
156
157
158 layer->field_id ^= 1;
159 if (event & VENC_FIRST_FIELD)
160 fid = 0;
161 else
162 fid = 1;
163
164
165
166
167
168 if (fid != layer->field_id) {
169
170 layer->field_id = fid;
171 continue;
172 }
173
174
175
176
177 if (0 == fid)
178 vpbe_isr_even_field(disp_dev, layer);
179 else
180 vpbe_isr_odd_field(disp_dev, layer);
181 }
182 }
183
184 return IRQ_HANDLED;
185}
186
187
188
189
190
191
192
193static int vpbe_buffer_prepare(struct vb2_buffer *vb)
194{
195 struct vb2_queue *q = vb->vb2_queue;
196 struct vpbe_layer *layer = vb2_get_drv_priv(q);
197 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
198 unsigned long addr;
199
200 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
201 "vpbe_buffer_prepare\n");
202
203 vb2_set_plane_payload(vb, 0, layer->pix_fmt.sizeimage);
204 if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
205 return -EINVAL;
206
207 addr = vb2_dma_contig_plane_dma_addr(vb, 0);
208 if (!IS_ALIGNED(addr, 8)) {
209 v4l2_err(&vpbe_dev->v4l2_dev,
210 "buffer_prepare:offset is not aligned to 32 bytes\n");
211 return -EINVAL;
212 }
213 return 0;
214}
215
216
217
218
219
220static int
221vpbe_buffer_queue_setup(struct vb2_queue *vq,
222 unsigned int *nbuffers, unsigned int *nplanes,
223 unsigned int sizes[], struct device *alloc_devs[])
224
225{
226
227 struct vpbe_layer *layer = vb2_get_drv_priv(vq);
228 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
229
230 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_setup\n");
231
232
233 if (vq->num_buffers + *nbuffers < VPBE_DEFAULT_NUM_BUFS)
234 *nbuffers = VPBE_DEFAULT_NUM_BUFS - vq->num_buffers;
235
236 if (*nplanes)
237 return sizes[0] < layer->pix_fmt.sizeimage ? -EINVAL : 0;
238
239 *nplanes = 1;
240 sizes[0] = layer->pix_fmt.sizeimage;
241
242 return 0;
243}
244
245
246
247
248
249static void vpbe_buffer_queue(struct vb2_buffer *vb)
250{
251 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
252
253 struct vpbe_disp_buffer *buf = container_of(vbuf,
254 struct vpbe_disp_buffer, vb);
255 struct vpbe_layer *layer = vb2_get_drv_priv(vb->vb2_queue);
256 struct vpbe_display *disp = layer->disp_dev;
257 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
258 unsigned long flags;
259
260 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
261 "vpbe_buffer_queue\n");
262
263
264 spin_lock_irqsave(&disp->dma_queue_lock, flags);
265 list_add_tail(&buf->list, &layer->dma_queue);
266 spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
267}
268
269static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
270{
271 struct vpbe_layer *layer = vb2_get_drv_priv(vq);
272 struct osd_state *osd_device = layer->disp_dev->osd_device;
273 int ret;
274
275 osd_device->ops.disable_layer(osd_device, layer->layer_info.id);
276
277
278 layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next,
279 struct vpbe_disp_buffer, list);
280
281 list_del(&layer->cur_frm->list);
282
283 layer->cur_frm->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
284
285 layer->field_id = 0;
286
287
288 ret = vpbe_set_osd_display_params(layer->disp_dev, layer);
289 if (ret < 0) {
290 struct vpbe_disp_buffer *buf, *tmp;
291
292 vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
293 VB2_BUF_STATE_QUEUED);
294 list_for_each_entry_safe(buf, tmp, &layer->dma_queue, list) {
295 list_del(&buf->list);
296 vb2_buffer_done(&buf->vb.vb2_buf,
297 VB2_BUF_STATE_QUEUED);
298 }
299
300 return ret;
301 }
302
303
304
305
306
307 layer->layer_first_int = 1;
308
309 return ret;
310}
311
312static void vpbe_stop_streaming(struct vb2_queue *vq)
313{
314 struct vpbe_layer *layer = vb2_get_drv_priv(vq);
315 struct osd_state *osd_device = layer->disp_dev->osd_device;
316 struct vpbe_display *disp = layer->disp_dev;
317 unsigned long flags;
318
319 if (!vb2_is_streaming(vq))
320 return;
321
322 osd_device->ops.disable_layer(osd_device, layer->layer_info.id);
323
324
325 spin_lock_irqsave(&disp->dma_queue_lock, flags);
326 if (layer->cur_frm == layer->next_frm) {
327 vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
328 VB2_BUF_STATE_ERROR);
329 } else {
330 if (layer->cur_frm)
331 vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
332 VB2_BUF_STATE_ERROR);
333 if (layer->next_frm)
334 vb2_buffer_done(&layer->next_frm->vb.vb2_buf,
335 VB2_BUF_STATE_ERROR);
336 }
337
338 while (!list_empty(&layer->dma_queue)) {
339 layer->next_frm = list_entry(layer->dma_queue.next,
340 struct vpbe_disp_buffer, list);
341 list_del(&layer->next_frm->list);
342 vb2_buffer_done(&layer->next_frm->vb.vb2_buf,
343 VB2_BUF_STATE_ERROR);
344 }
345 spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
346}
347
348static const struct vb2_ops video_qops = {
349 .queue_setup = vpbe_buffer_queue_setup,
350 .wait_prepare = vb2_ops_wait_prepare,
351 .wait_finish = vb2_ops_wait_finish,
352 .buf_prepare = vpbe_buffer_prepare,
353 .start_streaming = vpbe_start_streaming,
354 .stop_streaming = vpbe_stop_streaming,
355 .buf_queue = vpbe_buffer_queue,
356};
357
358static
359struct vpbe_layer*
360_vpbe_display_get_other_win_layer(struct vpbe_display *disp_dev,
361 struct vpbe_layer *layer)
362{
363 enum vpbe_display_device_id thiswin, otherwin;
364 thiswin = layer->device_id;
365
366 otherwin = (thiswin == VPBE_DISPLAY_DEVICE_0) ?
367 VPBE_DISPLAY_DEVICE_1 : VPBE_DISPLAY_DEVICE_0;
368 return disp_dev->dev[otherwin];
369}
370
371static int vpbe_set_osd_display_params(struct vpbe_display *disp_dev,
372 struct vpbe_layer *layer)
373{
374 struct osd_layer_config *cfg = &layer->layer_info.config;
375 struct osd_state *osd_device = disp_dev->osd_device;
376 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
377 unsigned long addr;
378 int ret;
379
380 addr = vb2_dma_contig_plane_dma_addr(&layer->cur_frm->vb.vb2_buf, 0);
381
382 osd_device->ops.start_layer(osd_device,
383 layer->layer_info.id,
384 addr,
385 disp_dev->cbcr_ofst);
386
387 ret = osd_device->ops.enable_layer(osd_device,
388 layer->layer_info.id, 0);
389 if (ret < 0) {
390 v4l2_err(&vpbe_dev->v4l2_dev,
391 "Error in enabling osd window layer 0\n");
392 return -1;
393 }
394
395
396 layer->layer_info.enable = 1;
397 if (cfg->pixfmt == PIXFMT_NV12) {
398 struct vpbe_layer *otherlayer =
399 _vpbe_display_get_other_win_layer(disp_dev, layer);
400
401 ret = osd_device->ops.enable_layer(osd_device,
402 otherlayer->layer_info.id, 1);
403 if (ret < 0) {
404 v4l2_err(&vpbe_dev->v4l2_dev,
405 "Error in enabling osd window layer 1\n");
406 return -1;
407 }
408 otherlayer->layer_info.enable = 1;
409 }
410 return 0;
411}
412
413static void
414vpbe_disp_calculate_scale_factor(struct vpbe_display *disp_dev,
415 struct vpbe_layer *layer,
416 int expected_xsize, int expected_ysize)
417{
418 struct display_layer_info *layer_info = &layer->layer_info;
419 struct v4l2_pix_format *pixfmt = &layer->pix_fmt;
420 struct osd_layer_config *cfg = &layer->layer_info.config;
421 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
422 int calculated_xsize;
423 int h_exp = 0;
424 int v_exp = 0;
425 int h_scale;
426 int v_scale;
427
428 v4l2_std_id standard_id = vpbe_dev->current_timings.std_id;
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447 cfg->xsize = pixfmt->width;
448 cfg->ysize = pixfmt->height;
449 layer_info->h_zoom = ZOOM_X1;
450 layer_info->v_zoom = ZOOM_X1;
451 layer_info->h_exp = H_EXP_OFF;
452 layer_info->v_exp = V_EXP_OFF;
453
454 if (pixfmt->width < expected_xsize) {
455 h_scale = vpbe_dev->current_timings.xres / pixfmt->width;
456 if (h_scale < 2)
457 h_scale = 1;
458 else if (h_scale >= 4)
459 h_scale = 4;
460 else
461 h_scale = 2;
462 cfg->xsize *= h_scale;
463 if (cfg->xsize < expected_xsize) {
464 if ((standard_id & V4L2_STD_525_60) ||
465 (standard_id & V4L2_STD_625_50)) {
466 calculated_xsize = (cfg->xsize *
467 VPBE_DISPLAY_H_EXP_RATIO_N) /
468 VPBE_DISPLAY_H_EXP_RATIO_D;
469 if (calculated_xsize <= expected_xsize) {
470 h_exp = 1;
471 cfg->xsize = calculated_xsize;
472 }
473 }
474 }
475 if (h_scale == 2)
476 layer_info->h_zoom = ZOOM_X2;
477 else if (h_scale == 4)
478 layer_info->h_zoom = ZOOM_X4;
479 if (h_exp)
480 layer_info->h_exp = H_EXP_9_OVER_8;
481 } else {
482
483 cfg->xsize = expected_xsize;
484 }
485
486 if (pixfmt->height < expected_ysize) {
487 v_scale = expected_ysize / pixfmt->height;
488 if (v_scale < 2)
489 v_scale = 1;
490 else if (v_scale >= 4)
491 v_scale = 4;
492 else
493 v_scale = 2;
494 cfg->ysize *= v_scale;
495 if (cfg->ysize < expected_ysize) {
496 if ((standard_id & V4L2_STD_625_50)) {
497 calculated_xsize = (cfg->ysize *
498 VPBE_DISPLAY_V_EXP_RATIO_N) /
499 VPBE_DISPLAY_V_EXP_RATIO_D;
500 if (calculated_xsize <= expected_ysize) {
501 v_exp = 1;
502 cfg->ysize = calculated_xsize;
503 }
504 }
505 }
506 if (v_scale == 2)
507 layer_info->v_zoom = ZOOM_X2;
508 else if (v_scale == 4)
509 layer_info->v_zoom = ZOOM_X4;
510 if (v_exp)
511 layer_info->v_exp = V_EXP_6_OVER_5;
512 } else {
513
514 cfg->ysize = expected_ysize;
515 }
516 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
517 "crop display xsize = %d, ysize = %d\n",
518 cfg->xsize, cfg->ysize);
519}
520
521static void vpbe_disp_adj_position(struct vpbe_display *disp_dev,
522 struct vpbe_layer *layer,
523 int top, int left)
524{
525 struct osd_layer_config *cfg = &layer->layer_info.config;
526 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
527
528 cfg->xpos = min((unsigned int)left,
529 vpbe_dev->current_timings.xres - cfg->xsize);
530 cfg->ypos = min((unsigned int)top,
531 vpbe_dev->current_timings.yres - cfg->ysize);
532
533 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
534 "new xpos = %d, ypos = %d\n",
535 cfg->xpos, cfg->ypos);
536}
537
538static void vpbe_disp_check_window_params(struct vpbe_display *disp_dev,
539 struct v4l2_rect *c)
540{
541 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
542
543 if ((c->width == 0) ||
544 ((c->width + c->left) > vpbe_dev->current_timings.xres))
545 c->width = vpbe_dev->current_timings.xres - c->left;
546
547 if ((c->height == 0) || ((c->height + c->top) >
548 vpbe_dev->current_timings.yres))
549 c->height = vpbe_dev->current_timings.yres - c->top;
550
551
552 if (vpbe_dev->current_timings.interlaced)
553 c->height &= (~0x01);
554
555}
556
557
558
559
560
561
562
563static int vpbe_try_format(struct vpbe_display *disp_dev,
564 struct v4l2_pix_format *pixfmt, int check)
565{
566 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
567 int min_height = 1;
568 int min_width = 32;
569 int max_height;
570 int max_width;
571 int bpp;
572
573 if ((pixfmt->pixelformat != V4L2_PIX_FMT_UYVY) &&
574 (pixfmt->pixelformat != V4L2_PIX_FMT_NV12))
575
576 pixfmt->pixelformat = V4L2_PIX_FMT_UYVY;
577
578
579 if ((pixfmt->field != V4L2_FIELD_INTERLACED) &&
580 (pixfmt->field != V4L2_FIELD_NONE)) {
581 if (vpbe_dev->current_timings.interlaced)
582 pixfmt->field = V4L2_FIELD_INTERLACED;
583 else
584 pixfmt->field = V4L2_FIELD_NONE;
585 }
586
587 if (pixfmt->field == V4L2_FIELD_INTERLACED)
588 min_height = 2;
589
590 if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
591 bpp = 1;
592 else
593 bpp = 2;
594
595 max_width = vpbe_dev->current_timings.xres;
596 max_height = vpbe_dev->current_timings.yres;
597
598 min_width /= bpp;
599
600 if (!pixfmt->width || (pixfmt->width < min_width) ||
601 (pixfmt->width > max_width)) {
602 pixfmt->width = vpbe_dev->current_timings.xres;
603 }
604
605 if (!pixfmt->height || (pixfmt->height < min_height) ||
606 (pixfmt->height > max_height)) {
607 pixfmt->height = vpbe_dev->current_timings.yres;
608 }
609
610 if (pixfmt->bytesperline < (pixfmt->width * bpp))
611 pixfmt->bytesperline = pixfmt->width * bpp;
612
613
614 pixfmt->bytesperline = ((pixfmt->width * bpp + 31) & ~31);
615
616 if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
617 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height +
618 (pixfmt->bytesperline * pixfmt->height >> 1);
619 else
620 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
621
622 return 0;
623}
624
625static int vpbe_display_querycap(struct file *file, void *priv,
626 struct v4l2_capability *cap)
627{
628 struct vpbe_layer *layer = video_drvdata(file);
629 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
630
631 snprintf(cap->driver, sizeof(cap->driver), "%s",
632 dev_name(vpbe_dev->pdev));
633 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
634 dev_name(vpbe_dev->pdev));
635 strscpy(cap->card, vpbe_dev->cfg->module_name, sizeof(cap->card));
636
637 return 0;
638}
639
640static int vpbe_display_s_selection(struct file *file, void *priv,
641 struct v4l2_selection *sel)
642{
643 struct vpbe_layer *layer = video_drvdata(file);
644 struct vpbe_display *disp_dev = layer->disp_dev;
645 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
646 struct osd_layer_config *cfg = &layer->layer_info.config;
647 struct osd_state *osd_device = disp_dev->osd_device;
648 struct v4l2_rect rect = sel->r;
649 int ret;
650
651 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
652 "VIDIOC_S_SELECTION, layer id = %d\n", layer->device_id);
653
654 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
655 sel->target != V4L2_SEL_TGT_CROP)
656 return -EINVAL;
657
658 if (rect.top < 0)
659 rect.top = 0;
660 if (rect.left < 0)
661 rect.left = 0;
662
663 vpbe_disp_check_window_params(disp_dev, &rect);
664
665 osd_device->ops.get_layer_config(osd_device,
666 layer->layer_info.id, cfg);
667
668 vpbe_disp_calculate_scale_factor(disp_dev, layer,
669 rect.width,
670 rect.height);
671 vpbe_disp_adj_position(disp_dev, layer, rect.top,
672 rect.left);
673 ret = osd_device->ops.set_layer_config(osd_device,
674 layer->layer_info.id, cfg);
675 if (ret < 0) {
676 v4l2_err(&vpbe_dev->v4l2_dev,
677 "Error in set layer config:\n");
678 return -EINVAL;
679 }
680
681
682 osd_device->ops.set_zoom(osd_device,
683 layer->layer_info.id,
684 layer->layer_info.h_zoom,
685 layer->layer_info.v_zoom);
686 ret = osd_device->ops.set_vid_expansion(osd_device,
687 layer->layer_info.h_exp,
688 layer->layer_info.v_exp);
689 if (ret < 0) {
690 v4l2_err(&vpbe_dev->v4l2_dev,
691 "Error in set vid expansion:\n");
692 return -EINVAL;
693 }
694
695 if ((layer->layer_info.h_zoom != ZOOM_X1) ||
696 (layer->layer_info.v_zoom != ZOOM_X1) ||
697 (layer->layer_info.h_exp != H_EXP_OFF) ||
698 (layer->layer_info.v_exp != V_EXP_OFF))
699
700 osd_device->ops.set_interpolation_filter(osd_device, 1);
701 else
702 osd_device->ops.set_interpolation_filter(osd_device, 0);
703
704 sel->r = rect;
705 return 0;
706}
707
708static int vpbe_display_g_selection(struct file *file, void *priv,
709 struct v4l2_selection *sel)
710{
711 struct vpbe_layer *layer = video_drvdata(file);
712 struct osd_layer_config *cfg = &layer->layer_info.config;
713 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
714 struct osd_state *osd_device = layer->disp_dev->osd_device;
715 struct v4l2_rect *rect = &sel->r;
716
717 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
718 "VIDIOC_G_SELECTION, layer id = %d\n",
719 layer->device_id);
720
721 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
722 return -EINVAL;
723
724 switch (sel->target) {
725 case V4L2_SEL_TGT_CROP:
726 osd_device->ops.get_layer_config(osd_device,
727 layer->layer_info.id, cfg);
728 rect->top = cfg->ypos;
729 rect->left = cfg->xpos;
730 rect->width = cfg->xsize;
731 rect->height = cfg->ysize;
732 break;
733 case V4L2_SEL_TGT_CROP_DEFAULT:
734 case V4L2_SEL_TGT_CROP_BOUNDS:
735 rect->left = 0;
736 rect->top = 0;
737 rect->width = vpbe_dev->current_timings.xres;
738 rect->height = vpbe_dev->current_timings.yres;
739 break;
740 default:
741 return -EINVAL;
742 }
743
744 return 0;
745}
746
747static int vpbe_display_g_pixelaspect(struct file *file, void *priv,
748 int type, struct v4l2_fract *f)
749{
750 struct vpbe_layer *layer = video_drvdata(file);
751 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
752
753 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_CROPCAP ioctl\n");
754
755 if (type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
756 return -EINVAL;
757
758 *f = vpbe_dev->current_timings.aspect;
759 return 0;
760}
761
762static int vpbe_display_g_fmt(struct file *file, void *priv,
763 struct v4l2_format *fmt)
764{
765 struct vpbe_layer *layer = video_drvdata(file);
766 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
767
768 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
769 "VIDIOC_G_FMT, layer id = %d\n",
770 layer->device_id);
771
772
773 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
774 v4l2_err(&vpbe_dev->v4l2_dev, "invalid type\n");
775 return -EINVAL;
776 }
777
778 fmt->fmt.pix = layer->pix_fmt;
779
780 return 0;
781}
782
783static int vpbe_display_enum_fmt(struct file *file, void *priv,
784 struct v4l2_fmtdesc *fmt)
785{
786 struct vpbe_layer *layer = video_drvdata(file);
787 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
788
789 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
790 "VIDIOC_ENUM_FMT, layer id = %d\n",
791 layer->device_id);
792 if (fmt->index > 1) {
793 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid format index\n");
794 return -EINVAL;
795 }
796
797
798 if (fmt->index == 0)
799 fmt->pixelformat = V4L2_PIX_FMT_UYVY;
800 else
801 fmt->pixelformat = V4L2_PIX_FMT_NV12;
802
803 return 0;
804}
805
806static int vpbe_display_s_fmt(struct file *file, void *priv,
807 struct v4l2_format *fmt)
808{
809 struct vpbe_layer *layer = video_drvdata(file);
810 struct vpbe_display *disp_dev = layer->disp_dev;
811 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
812 struct osd_layer_config *cfg = &layer->layer_info.config;
813 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
814 struct osd_state *osd_device = disp_dev->osd_device;
815 int ret;
816
817 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
818 "VIDIOC_S_FMT, layer id = %d\n",
819 layer->device_id);
820
821 if (vb2_is_busy(&layer->buffer_queue))
822 return -EBUSY;
823
824 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
825 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "invalid type\n");
826 return -EINVAL;
827 }
828
829 ret = vpbe_try_format(disp_dev, pixfmt, 1);
830 if (ret)
831 return ret;
832
833
834
835
836 layer->pix_fmt = *pixfmt;
837 if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12) {
838 struct vpbe_layer *otherlayer;
839
840 otherlayer = _vpbe_display_get_other_win_layer(disp_dev, layer);
841
842
843
844 ret = osd_device->ops.request_layer(osd_device,
845 otherlayer->layer_info.id);
846 if (ret < 0) {
847 v4l2_err(&vpbe_dev->v4l2_dev,
848 "Display Manager failed to allocate layer\n");
849 return -EBUSY;
850 }
851 }
852
853
854 osd_device->ops.get_layer_config(osd_device,
855 layer->layer_info.id, cfg);
856
857 cfg->xsize = pixfmt->width;
858 cfg->ysize = pixfmt->height;
859 cfg->line_length = pixfmt->bytesperline;
860 cfg->ypos = 0;
861 cfg->xpos = 0;
862 cfg->interlaced = vpbe_dev->current_timings.interlaced;
863
864 if (V4L2_PIX_FMT_UYVY == pixfmt->pixelformat)
865 cfg->pixfmt = PIXFMT_YCBCRI;
866
867
868 if (V4L2_PIX_FMT_NV12 == pixfmt->pixelformat) {
869 struct vpbe_layer *otherlayer;
870 cfg->pixfmt = PIXFMT_NV12;
871 otherlayer = _vpbe_display_get_other_win_layer(disp_dev,
872 layer);
873 otherlayer->layer_info.config.pixfmt = PIXFMT_NV12;
874 }
875
876
877 ret = osd_device->ops.set_layer_config(osd_device,
878 layer->layer_info.id, cfg);
879 if (ret < 0) {
880 v4l2_err(&vpbe_dev->v4l2_dev,
881 "Error in S_FMT params:\n");
882 return -EINVAL;
883 }
884
885
886 osd_device->ops.get_layer_config(osd_device,
887 layer->layer_info.id, cfg);
888
889 return 0;
890}
891
892static int vpbe_display_try_fmt(struct file *file, void *priv,
893 struct v4l2_format *fmt)
894{
895 struct vpbe_layer *layer = video_drvdata(file);
896 struct vpbe_display *disp_dev = layer->disp_dev;
897 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
898 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
899
900 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_TRY_FMT\n");
901
902 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
903 v4l2_err(&vpbe_dev->v4l2_dev, "invalid type\n");
904 return -EINVAL;
905 }
906
907
908 return vpbe_try_format(disp_dev, pixfmt, 0);
909
910}
911
912
913
914
915
916
917
918static int vpbe_display_s_std(struct file *file, void *priv,
919 v4l2_std_id std_id)
920{
921 struct vpbe_layer *layer = video_drvdata(file);
922 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
923 int ret;
924
925 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_STD\n");
926
927 if (vb2_is_busy(&layer->buffer_queue))
928 return -EBUSY;
929
930 if (vpbe_dev->ops.s_std) {
931 ret = vpbe_dev->ops.s_std(vpbe_dev, std_id);
932 if (ret) {
933 v4l2_err(&vpbe_dev->v4l2_dev,
934 "Failed to set standard for sub devices\n");
935 return -EINVAL;
936 }
937 } else {
938 return -EINVAL;
939 }
940
941 return 0;
942}
943
944
945
946
947
948
949
950static int vpbe_display_g_std(struct file *file, void *priv,
951 v4l2_std_id *std_id)
952{
953 struct vpbe_layer *layer = video_drvdata(file);
954 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
955
956 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_STD\n");
957
958
959 if (vpbe_dev->current_timings.timings_type & VPBE_ENC_STD) {
960 *std_id = vpbe_dev->current_timings.std_id;
961 return 0;
962 }
963
964 return -EINVAL;
965}
966
967
968
969
970
971
972
973static int vpbe_display_enum_output(struct file *file, void *priv,
974 struct v4l2_output *output)
975{
976 struct vpbe_layer *layer = video_drvdata(file);
977 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
978 int ret;
979
980 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_OUTPUT\n");
981
982
983 if (!vpbe_dev->ops.enum_outputs)
984 return -EINVAL;
985
986 ret = vpbe_dev->ops.enum_outputs(vpbe_dev, output);
987 if (ret) {
988 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
989 "Failed to enumerate outputs\n");
990 return -EINVAL;
991 }
992
993 return 0;
994}
995
996
997
998
999
1000static int vpbe_display_s_output(struct file *file, void *priv,
1001 unsigned int i)
1002{
1003 struct vpbe_layer *layer = video_drvdata(file);
1004 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
1005 int ret;
1006
1007 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_OUTPUT\n");
1008
1009 if (vb2_is_busy(&layer->buffer_queue))
1010 return -EBUSY;
1011
1012 if (!vpbe_dev->ops.set_output)
1013 return -EINVAL;
1014
1015 ret = vpbe_dev->ops.set_output(vpbe_dev, i);
1016 if (ret) {
1017 v4l2_err(&vpbe_dev->v4l2_dev,
1018 "Failed to set output for sub devices\n");
1019 return -EINVAL;
1020 }
1021
1022 return 0;
1023}
1024
1025
1026
1027
1028
1029static int vpbe_display_g_output(struct file *file, void *priv,
1030 unsigned int *i)
1031{
1032 struct vpbe_layer *layer = video_drvdata(file);
1033 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
1034
1035 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_OUTPUT\n");
1036
1037 *i = vpbe_dev->current_out_index;
1038
1039 return 0;
1040}
1041
1042
1043
1044
1045
1046
1047
1048static int
1049vpbe_display_enum_dv_timings(struct file *file, void *priv,
1050 struct v4l2_enum_dv_timings *timings)
1051{
1052 struct vpbe_layer *layer = video_drvdata(file);
1053 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
1054 int ret;
1055
1056 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_DV_TIMINGS\n");
1057
1058
1059 if (!vpbe_dev->ops.enum_dv_timings)
1060 return -EINVAL;
1061
1062 ret = vpbe_dev->ops.enum_dv_timings(vpbe_dev, timings);
1063 if (ret) {
1064 v4l2_err(&vpbe_dev->v4l2_dev,
1065 "Failed to enumerate dv timings info\n");
1066 return -EINVAL;
1067 }
1068
1069 return 0;
1070}
1071
1072
1073
1074
1075
1076
1077
1078static int
1079vpbe_display_s_dv_timings(struct file *file, void *priv,
1080 struct v4l2_dv_timings *timings)
1081{
1082 struct vpbe_layer *layer = video_drvdata(file);
1083 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
1084 int ret;
1085
1086 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_DV_TIMINGS\n");
1087
1088 if (vb2_is_busy(&layer->buffer_queue))
1089 return -EBUSY;
1090
1091
1092 if (!vpbe_dev->ops.s_dv_timings)
1093 return -EINVAL;
1094
1095 ret = vpbe_dev->ops.s_dv_timings(vpbe_dev, timings);
1096 if (ret) {
1097 v4l2_err(&vpbe_dev->v4l2_dev,
1098 "Failed to set the dv timings info\n");
1099 return -EINVAL;
1100 }
1101
1102 return 0;
1103}
1104
1105
1106
1107
1108
1109
1110
1111static int
1112vpbe_display_g_dv_timings(struct file *file, void *priv,
1113 struct v4l2_dv_timings *dv_timings)
1114{
1115 struct vpbe_layer *layer = video_drvdata(file);
1116 struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
1117
1118 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_DV_TIMINGS\n");
1119
1120
1121
1122 if (vpbe_dev->current_timings.timings_type &
1123 VPBE_ENC_DV_TIMINGS) {
1124 *dv_timings = vpbe_dev->current_timings.dv_timings;
1125 } else {
1126 return -EINVAL;
1127 }
1128
1129 return 0;
1130}
1131
1132
1133
1134
1135
1136
1137static int vpbe_display_open(struct file *file)
1138{
1139 struct vpbe_layer *layer = video_drvdata(file);
1140 struct vpbe_display *disp_dev = layer->disp_dev;
1141 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
1142 struct osd_state *osd_device = disp_dev->osd_device;
1143 int err;
1144
1145
1146 err = v4l2_fh_open(file);
1147 if (err) {
1148 v4l2_err(&vpbe_dev->v4l2_dev, "v4l2_fh_open failed\n");
1149 return err;
1150 }
1151
1152
1153 if (!v4l2_fh_is_singular_file(file))
1154 return err;
1155
1156 if (!layer->usrs) {
1157 if (mutex_lock_interruptible(&layer->opslock))
1158 return -ERESTARTSYS;
1159
1160 err = osd_device->ops.request_layer(osd_device,
1161 layer->layer_info.id);
1162 mutex_unlock(&layer->opslock);
1163 if (err < 0) {
1164
1165 v4l2_err(&vpbe_dev->v4l2_dev,
1166 "Display Manager failed to allocate layer\n");
1167 v4l2_fh_release(file);
1168 return -EINVAL;
1169 }
1170 }
1171
1172 layer->usrs++;
1173 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
1174 "vpbe display device opened successfully\n");
1175 return 0;
1176}
1177
1178
1179
1180
1181
1182
1183static int vpbe_display_release(struct file *file)
1184{
1185 struct vpbe_layer *layer = video_drvdata(file);
1186 struct osd_layer_config *cfg = &layer->layer_info.config;
1187 struct vpbe_display *disp_dev = layer->disp_dev;
1188 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
1189 struct osd_state *osd_device = disp_dev->osd_device;
1190
1191 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_release\n");
1192
1193 mutex_lock(&layer->opslock);
1194
1195 osd_device->ops.disable_layer(osd_device,
1196 layer->layer_info.id);
1197
1198 layer->usrs--;
1199
1200 if (!layer->usrs) {
1201 if (cfg->pixfmt == PIXFMT_NV12) {
1202 struct vpbe_layer *otherlayer;
1203 otherlayer =
1204 _vpbe_display_get_other_win_layer(disp_dev, layer);
1205 osd_device->ops.disable_layer(osd_device,
1206 otherlayer->layer_info.id);
1207 osd_device->ops.release_layer(osd_device,
1208 otherlayer->layer_info.id);
1209 }
1210 osd_device->ops.disable_layer(osd_device,
1211 layer->layer_info.id);
1212 osd_device->ops.release_layer(osd_device,
1213 layer->layer_info.id);
1214 }
1215
1216 _vb2_fop_release(file, NULL);
1217 mutex_unlock(&layer->opslock);
1218
1219 disp_dev->cbcr_ofst = 0;
1220
1221 return 0;
1222}
1223
1224
1225static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
1226 .vidioc_querycap = vpbe_display_querycap,
1227 .vidioc_g_fmt_vid_out = vpbe_display_g_fmt,
1228 .vidioc_enum_fmt_vid_out = vpbe_display_enum_fmt,
1229 .vidioc_s_fmt_vid_out = vpbe_display_s_fmt,
1230 .vidioc_try_fmt_vid_out = vpbe_display_try_fmt,
1231
1232 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1233 .vidioc_create_bufs = vb2_ioctl_create_bufs,
1234 .vidioc_querybuf = vb2_ioctl_querybuf,
1235 .vidioc_qbuf = vb2_ioctl_qbuf,
1236 .vidioc_dqbuf = vb2_ioctl_dqbuf,
1237 .vidioc_streamon = vb2_ioctl_streamon,
1238 .vidioc_streamoff = vb2_ioctl_streamoff,
1239 .vidioc_expbuf = vb2_ioctl_expbuf,
1240
1241 .vidioc_g_pixelaspect = vpbe_display_g_pixelaspect,
1242 .vidioc_g_selection = vpbe_display_g_selection,
1243 .vidioc_s_selection = vpbe_display_s_selection,
1244
1245 .vidioc_s_std = vpbe_display_s_std,
1246 .vidioc_g_std = vpbe_display_g_std,
1247
1248 .vidioc_enum_output = vpbe_display_enum_output,
1249 .vidioc_s_output = vpbe_display_s_output,
1250 .vidioc_g_output = vpbe_display_g_output,
1251
1252 .vidioc_s_dv_timings = vpbe_display_s_dv_timings,
1253 .vidioc_g_dv_timings = vpbe_display_g_dv_timings,
1254 .vidioc_enum_dv_timings = vpbe_display_enum_dv_timings,
1255};
1256
1257static const struct v4l2_file_operations vpbe_fops = {
1258 .owner = THIS_MODULE,
1259 .open = vpbe_display_open,
1260 .release = vpbe_display_release,
1261 .unlocked_ioctl = video_ioctl2,
1262 .mmap = vb2_fop_mmap,
1263 .poll = vb2_fop_poll,
1264};
1265
1266static int vpbe_device_get(struct device *dev, void *data)
1267{
1268 struct platform_device *pdev = to_platform_device(dev);
1269 struct vpbe_display *vpbe_disp = data;
1270
1271 if (strcmp("vpbe_controller", pdev->name) == 0)
1272 vpbe_disp->vpbe_dev = platform_get_drvdata(pdev);
1273
1274 if (strstr(pdev->name, "vpbe-osd"))
1275 vpbe_disp->osd_device = platform_get_drvdata(pdev);
1276
1277 return 0;
1278}
1279
1280static int init_vpbe_layer(int i, struct vpbe_display *disp_dev,
1281 struct platform_device *pdev)
1282{
1283 struct vpbe_layer *vpbe_display_layer = NULL;
1284 struct video_device *vbd = NULL;
1285
1286
1287 disp_dev->dev[i] = kzalloc(sizeof(*disp_dev->dev[i]), GFP_KERNEL);
1288 if (!disp_dev->dev[i])
1289 return -ENOMEM;
1290
1291 spin_lock_init(&disp_dev->dev[i]->irqlock);
1292 mutex_init(&disp_dev->dev[i]->opslock);
1293
1294
1295 vpbe_display_layer = disp_dev->dev[i];
1296 vbd = &vpbe_display_layer->video_dev;
1297
1298 vbd->release = video_device_release_empty;
1299 vbd->fops = &vpbe_fops;
1300 vbd->ioctl_ops = &vpbe_ioctl_ops;
1301 vbd->minor = -1;
1302 vbd->v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev;
1303 vbd->lock = &vpbe_display_layer->opslock;
1304 vbd->vfl_dir = VFL_DIR_TX;
1305 vbd->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
1306
1307 if (disp_dev->vpbe_dev->current_timings.timings_type &
1308 VPBE_ENC_STD)
1309 vbd->tvnorms = (V4L2_STD_525_60 | V4L2_STD_625_50);
1310
1311 snprintf(vbd->name, sizeof(vbd->name),
1312 "DaVinci_VPBE Display_DRIVER_V%d.%d.%d",
1313 (VPBE_DISPLAY_VERSION_CODE >> 16) & 0xff,
1314 (VPBE_DISPLAY_VERSION_CODE >> 8) & 0xff,
1315 (VPBE_DISPLAY_VERSION_CODE) & 0xff);
1316
1317 vpbe_display_layer->device_id = i;
1318
1319 vpbe_display_layer->layer_info.id =
1320 ((i == VPBE_DISPLAY_DEVICE_0) ? WIN_VID0 : WIN_VID1);
1321
1322
1323 return 0;
1324}
1325
1326static int register_device(struct vpbe_layer *vpbe_display_layer,
1327 struct vpbe_display *disp_dev,
1328 struct platform_device *pdev)
1329{
1330 int err;
1331
1332 v4l2_info(&disp_dev->vpbe_dev->v4l2_dev,
1333 "Trying to register VPBE display device.\n");
1334 v4l2_info(&disp_dev->vpbe_dev->v4l2_dev,
1335 "layer=%p,layer->video_dev=%p\n",
1336 vpbe_display_layer,
1337 &vpbe_display_layer->video_dev);
1338
1339 vpbe_display_layer->video_dev.queue = &vpbe_display_layer->buffer_queue;
1340 err = video_register_device(&vpbe_display_layer->video_dev,
1341 VFL_TYPE_VIDEO,
1342 -1);
1343 if (err)
1344 return -ENODEV;
1345
1346 vpbe_display_layer->disp_dev = disp_dev;
1347
1348 platform_set_drvdata(pdev, disp_dev);
1349 video_set_drvdata(&vpbe_display_layer->video_dev,
1350 vpbe_display_layer);
1351
1352 return 0;
1353}
1354
1355
1356
1357
1358
1359
1360
1361
1362static int vpbe_display_probe(struct platform_device *pdev)
1363{
1364 struct vpbe_display *disp_dev;
1365 struct v4l2_device *v4l2_dev;
1366 struct resource *res = NULL;
1367 struct vb2_queue *q;
1368 int k;
1369 int i;
1370 int err;
1371 int irq;
1372
1373 printk(KERN_DEBUG "vpbe_display_probe\n");
1374
1375 disp_dev = devm_kzalloc(&pdev->dev, sizeof(*disp_dev), GFP_KERNEL);
1376 if (!disp_dev)
1377 return -ENOMEM;
1378
1379 spin_lock_init(&disp_dev->dma_queue_lock);
1380
1381
1382
1383
1384 err = bus_for_each_dev(&platform_bus_type, NULL, disp_dev,
1385 vpbe_device_get);
1386 if (err < 0)
1387 return err;
1388
1389 v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev;
1390
1391 if (disp_dev->vpbe_dev->ops.initialize) {
1392 err = disp_dev->vpbe_dev->ops.initialize(&pdev->dev,
1393 disp_dev->vpbe_dev);
1394 if (err) {
1395 v4l2_err(v4l2_dev, "Error initing vpbe\n");
1396 err = -ENOMEM;
1397 goto probe_out;
1398 }
1399 }
1400
1401 for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
1402 if (init_vpbe_layer(i, disp_dev, pdev)) {
1403 err = -ENODEV;
1404 goto probe_out;
1405 }
1406 }
1407
1408 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1409 if (!res) {
1410 v4l2_err(v4l2_dev, "Unable to get VENC interrupt resource\n");
1411 err = -ENODEV;
1412 goto probe_out;
1413 }
1414
1415 irq = res->start;
1416 err = devm_request_irq(&pdev->dev, irq, venc_isr, 0,
1417 VPBE_DISPLAY_DRIVER, disp_dev);
1418 if (err) {
1419 v4l2_err(v4l2_dev, "VPBE IRQ request failed\n");
1420 goto probe_out;
1421 }
1422
1423 for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
1424
1425 q = &disp_dev->dev[i]->buffer_queue;
1426 memset(q, 0, sizeof(*q));
1427 q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1428 q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
1429 q->drv_priv = disp_dev->dev[i];
1430 q->ops = &video_qops;
1431 q->mem_ops = &vb2_dma_contig_memops;
1432 q->buf_struct_size = sizeof(struct vpbe_disp_buffer);
1433 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1434 q->min_buffers_needed = 1;
1435 q->lock = &disp_dev->dev[i]->opslock;
1436 q->dev = disp_dev->vpbe_dev->pdev;
1437 err = vb2_queue_init(q);
1438 if (err) {
1439 v4l2_err(v4l2_dev, "vb2_queue_init() failed\n");
1440 goto probe_out;
1441 }
1442
1443 INIT_LIST_HEAD(&disp_dev->dev[i]->dma_queue);
1444
1445 if (register_device(disp_dev->dev[i], disp_dev, pdev)) {
1446 err = -ENODEV;
1447 goto probe_out;
1448 }
1449 }
1450
1451 v4l2_dbg(1, debug, v4l2_dev,
1452 "Successfully completed the probing of vpbe v4l2 device\n");
1453
1454 return 0;
1455
1456probe_out:
1457 for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) {
1458
1459 if (disp_dev->dev[k]) {
1460 video_unregister_device(&disp_dev->dev[k]->video_dev);
1461 kfree(disp_dev->dev[k]);
1462 }
1463 }
1464 return err;
1465}
1466
1467
1468
1469
1470
1471static int vpbe_display_remove(struct platform_device *pdev)
1472{
1473 struct vpbe_layer *vpbe_display_layer;
1474 struct vpbe_display *disp_dev = platform_get_drvdata(pdev);
1475 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
1476 int i;
1477
1478 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_remove\n");
1479
1480
1481 if (vpbe_dev->ops.deinitialize)
1482 vpbe_dev->ops.deinitialize(&pdev->dev, vpbe_dev);
1483
1484 for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
1485
1486 vpbe_display_layer = disp_dev->dev[i];
1487
1488 video_unregister_device(&vpbe_display_layer->video_dev);
1489
1490 }
1491 for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
1492 kfree(disp_dev->dev[i]);
1493 disp_dev->dev[i] = NULL;
1494 }
1495
1496 return 0;
1497}
1498
1499static struct platform_driver vpbe_display_driver = {
1500 .driver = {
1501 .name = VPBE_DISPLAY_DRIVER,
1502 .bus = &platform_bus_type,
1503 },
1504 .probe = vpbe_display_probe,
1505 .remove = vpbe_display_remove,
1506};
1507
1508module_platform_driver(vpbe_display_driver);
1509
1510MODULE_DESCRIPTION("TI DM644x/DM355/DM365 VPBE Display controller");
1511MODULE_LICENSE("GPL");
1512MODULE_AUTHOR("Texas Instruments");
1513