Lines Matching +full:display +full:- +full:timing
4 * Copyright (C) 2005-2010 Texas Instruments.
11 * Video-for-Linux (Version 2) camera capture driver for
20 * 20-APR-2006 Khasim Modified VRFB based Rotation,
24 * 4-DEC-2006 Jian Changed to support better memory management
26 * 17-Nov-2008 Hardik Changed driver to use video_ioctl2
28 * 23-Feb-2010 Vaibhav H Modified to use new DSS2 interface
40 #include <linux/dma-mapping.h>
43 #include <media/v4l2-device.h>
44 #include <media/v4l2-ioctl.h>
45 #include <media/v4l2-event.h>
81 MODULE_PARM_DESC(debug, "Debug level (0-1)");
99 /* Note: V4L2 defines RGB32 as: RGB-8-8-8-8 we use
105 /* Note: V4L2 defines RGB24 as: RGB-8-8-8 we use
128 pix->height = clamp(pix->height, (u32)VID_MIN_HEIGHT, in omap_vout_try_format()
130 pix->width = clamp(pix->width, (u32)VID_MIN_WIDTH, (u32)VID_MAX_WIDTH); in omap_vout_try_format()
133 if (pix->pixelformat == omap_formats[ifmt].pixelformat) in omap_vout_try_format()
140 pix->pixelformat = omap_formats[ifmt].pixelformat; in omap_vout_try_format()
141 pix->field = V4L2_FIELD_NONE; in omap_vout_try_format()
143 switch (pix->pixelformat) { in omap_vout_try_format()
147 pix->colorspace = V4L2_COLORSPACE_SRGB; in omap_vout_try_format()
152 pix->colorspace = V4L2_COLORSPACE_SRGB; in omap_vout_try_format()
156 pix->colorspace = V4L2_COLORSPACE_SRGB; in omap_vout_try_format()
161 pix->colorspace = V4L2_COLORSPACE_SRGB; in omap_vout_try_format()
165 pix->bytesperline = pix->width * bpp; in omap_vout_try_format()
166 pix->sizeimage = pix->bytesperline * pix->height; in omap_vout_try_format()
195 ret = -EINVAL; in v4l2_rot_to_dss_rot()
203 struct v4l2_rect *crop = &vout->crop; in omap_vout_calculate_offset()
204 struct v4l2_pix_format *pix = &vout->pix; in omap_vout_calculate_offset()
205 int *cropped_offset = &vout->cropped_offset; in omap_vout_calculate_offset()
208 ovid = &vout->vid_info; in omap_vout_calculate_offset()
210 if (ovid->rotation_type == VOUT_ROT_VRFB) { in omap_vout_calculate_offset()
213 vout->line_length = line_length = pix->width; in omap_vout_calculate_offset()
215 if (V4L2_PIX_FMT_YUYV == pix->pixelformat || in omap_vout_calculate_offset()
216 V4L2_PIX_FMT_UYVY == pix->pixelformat) in omap_vout_calculate_offset()
218 else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat) in omap_vout_calculate_offset()
220 else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat) in omap_vout_calculate_offset()
223 vout->ps = ps; in omap_vout_calculate_offset()
226 crop->top + crop->left * ps; in omap_vout_calculate_offset()
229 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "%s Offset:%x\n", in omap_vout_calculate_offset()
230 __func__, vout->cropped_offset); in omap_vout_calculate_offset()
242 struct v4l2_pix_format *pix = &vout->pix; in video_mode_to_dss_mode()
245 ovid = &vout->vid_info; in video_mode_to_dss_mode()
246 ovl = ovid->overlays[0]; in video_mode_to_dss_mode()
248 switch (pix->pixelformat) { in video_mode_to_dss_mode()
262 mode = (ovl->id == OMAP_DSS_VIDEO1) ? in video_mode_to_dss_mode()
269 mode = -EINVAL; in video_mode_to_dss_mode()
286 if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0 && in omapvid_setup_overlay()
287 (outw != vout->pix.width || outh != vout->pix.height)) { in omapvid_setup_overlay()
288 ret = -EINVAL; in omapvid_setup_overlay()
292 vout->dss_mode = video_mode_to_dss_mode(vout); in omapvid_setup_overlay()
293 if (vout->dss_mode == -EINVAL) { in omapvid_setup_overlay()
294 ret = -EINVAL; in omapvid_setup_overlay()
302 cropheight = vout->crop.width; in omapvid_setup_overlay()
303 cropwidth = vout->crop.height; in omapvid_setup_overlay()
304 pixwidth = vout->pix.height; in omapvid_setup_overlay()
306 cropheight = vout->crop.height; in omapvid_setup_overlay()
307 cropwidth = vout->crop.width; in omapvid_setup_overlay()
308 pixwidth = vout->pix.width; in omapvid_setup_overlay()
311 ovl->get_overlay_info(ovl, &info); in omapvid_setup_overlay()
315 info.color_mode = vout->dss_mode; in omapvid_setup_overlay()
316 info.mirror = vout->mirror; in omapvid_setup_overlay()
321 info.global_alpha = vout->win.global_alpha; in omapvid_setup_overlay()
327 info.rotation = vout->rotation; in omapvid_setup_overlay()
332 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, in omapvid_setup_overlay()
336 ovl->is_enabled(ovl), &info.paddr, info.width, info.height, in omapvid_setup_overlay()
341 ret = ovl->set_overlay_info(ovl, &info); in omapvid_setup_overlay()
348 v4l2_warn(&vout->vid_dev->v4l2_dev, "setup_overlay failed\n"); in omapvid_setup_overlay()
361 struct omap_video_timings *timing; in omapvid_init() local
362 struct omapvideo_info *ovid = &vout->vid_info; in omapvid_init()
364 win = &vout->win; in omapvid_init()
365 for (i = 0; i < ovid->num_overlays; i++) { in omapvid_init()
368 ovl = ovid->overlays[i]; in omapvid_init()
369 dssdev = ovl->get_device(ovl); in omapvid_init()
372 return -EINVAL; in omapvid_init()
374 timing = &dssdev->panel.timings; in omapvid_init()
376 outw = win->w.width; in omapvid_init()
377 outh = win->w.height; in omapvid_init()
378 switch (vout->rotation) { in omapvid_init()
384 posy = (timing->y_res - win->w.width) - win->w.left; in omapvid_init()
385 posx = win->w.top; in omapvid_init()
389 posx = (timing->x_res - win->w.width) - win->w.left; in omapvid_init()
390 posy = (timing->y_res - win->w.height) - win->w.top; in omapvid_init()
395 posy = win->w.left; in omapvid_init()
396 posx = (timing->x_res - win->w.height) - win->w.top; in omapvid_init()
400 posx = win->w.left; in omapvid_init()
401 posy = win->w.top; in omapvid_init()
413 v4l2_warn(&vout->vid_dev->v4l2_dev, "apply_changes failed\n"); in omapvid_init()
424 struct omapvideo_info *ovid = &vout->vid_info; in omapvid_apply_changes()
426 for (i = 0; i < ovid->num_overlays; i++) { in omapvid_apply_changes()
429 ovl = ovid->overlays[i]; in omapvid_apply_changes()
430 dssdev = ovl->get_device(ovl); in omapvid_apply_changes()
432 return -EINVAL; in omapvid_apply_changes()
433 ovl->manager->apply(ovl->manager); in omapvid_apply_changes()
444 if (vout->first_int) { in omapvid_handle_interlace_display()
445 vout->first_int = 0; in omapvid_handle_interlace_display()
456 vout->field_id ^= 1; in omapvid_handle_interlace_display()
457 if (fid != vout->field_id) { in omapvid_handle_interlace_display()
459 vout->field_id = fid; in omapvid_handle_interlace_display()
461 if (vout->cur_frm == vout->next_frm) in omapvid_handle_interlace_display()
464 vout->cur_frm->vbuf.vb2_buf.timestamp = ts; in omapvid_handle_interlace_display()
465 vout->cur_frm->vbuf.sequence = vout->sequence++; in omapvid_handle_interlace_display()
466 vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_DONE); in omapvid_handle_interlace_display()
467 vout->cur_frm = vout->next_frm; in omapvid_handle_interlace_display()
469 if (list_empty(&vout->dma_queue) || in omapvid_handle_interlace_display()
470 (vout->cur_frm != vout->next_frm)) in omapvid_handle_interlace_display()
474 return vout->field_id; in omapvid_handle_interlace_display()
489 ovid = &vout->vid_info; in omap_vout_isr()
490 ovl = ovid->overlays[0]; in omap_vout_isr()
492 mgr_id = ovl->manager->id; in omap_vout_isr()
494 /* get the display device attached to the overlay */ in omap_vout_isr()
495 cur_display = ovl->get_device(ovl); in omap_vout_isr()
500 spin_lock(&vout->vbq_lock); in omap_vout_isr()
503 switch (cur_display->type) { in omap_vout_isr()
531 if (!vout->first_int && (vout->cur_frm != vout->next_frm)) { in omap_vout_isr()
532 vout->cur_frm->vbuf.vb2_buf.timestamp = ts; in omap_vout_isr()
533 vout->cur_frm->vbuf.sequence = vout->sequence++; in omap_vout_isr()
534 vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_DONE); in omap_vout_isr()
535 vout->cur_frm = vout->next_frm; in omap_vout_isr()
538 vout->first_int = 0; in omap_vout_isr()
539 if (list_empty(&vout->dma_queue)) in omap_vout_isr()
542 vout->next_frm = list_entry(vout->dma_queue.next, in omap_vout_isr()
544 list_del(&vout->next_frm->queue); in omap_vout_isr()
546 addr = (unsigned long)vout->queued_buf_addr[vout->next_frm->vbuf.vb2_buf.index] in omap_vout_isr()
547 + vout->cropped_offset; in omap_vout_isr()
563 spin_unlock(&vout->vbq_lock); in omap_vout_isr()
575 strscpy(cap->driver, VOUT_NAME, sizeof(cap->driver)); in vidioc_querycap()
576 strscpy(cap->card, vout->vfd->name, sizeof(cap->card)); in vidioc_querycap()
577 snprintf(cap->bus_info, sizeof(cap->bus_info), in vidioc_querycap()
578 "platform:%s.%d", VOUT_NAME, vout->vid); in vidioc_querycap()
585 int index = fmt->index; in vidioc_enum_fmt_vid_out()
588 return -EINVAL; in vidioc_enum_fmt_vid_out()
590 fmt->flags = omap_formats[index].flags; in vidioc_enum_fmt_vid_out()
591 fmt->pixelformat = omap_formats[index].pixelformat; in vidioc_enum_fmt_vid_out()
601 f->fmt.pix = vout->pix; in vidioc_g_fmt_vid_out()
611 struct omap_video_timings *timing; in vidioc_try_fmt_vid_out() local
615 ovid = &vout->vid_info; in vidioc_try_fmt_vid_out()
616 ovl = ovid->overlays[0]; in vidioc_try_fmt_vid_out()
617 /* get the display device attached to the overlay */ in vidioc_try_fmt_vid_out()
618 dssdev = ovl->get_device(ovl); in vidioc_try_fmt_vid_out()
621 return -EINVAL; in vidioc_try_fmt_vid_out()
623 timing = &dssdev->panel.timings; in vidioc_try_fmt_vid_out()
625 vout->fbuf.fmt.height = timing->y_res; in vidioc_try_fmt_vid_out()
626 vout->fbuf.fmt.width = timing->x_res; in vidioc_try_fmt_vid_out()
628 omap_vout_try_format(&f->fmt.pix); in vidioc_try_fmt_vid_out()
638 struct omap_video_timings *timing; in vidioc_s_fmt_vid_out() local
642 if (vb2_is_busy(&vout->vq)) in vidioc_s_fmt_vid_out()
643 return -EBUSY; in vidioc_s_fmt_vid_out()
645 ovid = &vout->vid_info; in vidioc_s_fmt_vid_out()
646 ovl = ovid->overlays[0]; in vidioc_s_fmt_vid_out()
647 dssdev = ovl->get_device(ovl); in vidioc_s_fmt_vid_out()
649 /* get the display device attached to the overlay */ in vidioc_s_fmt_vid_out()
651 ret = -EINVAL; in vidioc_s_fmt_vid_out()
654 timing = &dssdev->panel.timings; in vidioc_s_fmt_vid_out()
656 /* We don't support RGB24-packed mode if vrfb rotation in vidioc_s_fmt_vid_out()
659 f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) { in vidioc_s_fmt_vid_out()
660 ret = -EINVAL; in vidioc_s_fmt_vid_out()
667 vout->fbuf.fmt.height = timing->x_res; in vidioc_s_fmt_vid_out()
668 vout->fbuf.fmt.width = timing->y_res; in vidioc_s_fmt_vid_out()
670 vout->fbuf.fmt.height = timing->y_res; in vidioc_s_fmt_vid_out()
671 vout->fbuf.fmt.width = timing->x_res; in vidioc_s_fmt_vid_out()
676 bpp = omap_vout_try_format(&f->fmt.pix); in vidioc_s_fmt_vid_out()
677 f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height * bpp; in vidioc_s_fmt_vid_out()
680 vout->bpp = bpp; in vidioc_s_fmt_vid_out()
681 vout->pix = f->fmt.pix; in vidioc_s_fmt_vid_out()
682 vout->vrfb_bpp = 1; in vidioc_s_fmt_vid_out()
685 if (V4L2_PIX_FMT_YUYV == vout->pix.pixelformat || in vidioc_s_fmt_vid_out()
686 V4L2_PIX_FMT_UYVY == vout->pix.pixelformat) in vidioc_s_fmt_vid_out()
687 vout->vrfb_bpp = 2; in vidioc_s_fmt_vid_out()
690 omap_vout_new_format(&vout->pix, &vout->fbuf, &vout->crop, &vout->win); in vidioc_s_fmt_vid_out()
705 struct v4l2_window *win = &f->fmt.win; in vidioc_try_fmt_vid_overlay()
707 ovid = &vout->vid_info; in vidioc_try_fmt_vid_overlay()
708 ovl = ovid->overlays[0]; in vidioc_try_fmt_vid_overlay()
710 ret = omap_vout_try_window(&vout->fbuf, win); in vidioc_try_fmt_vid_overlay()
712 if (!ret && !(ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA)) in vidioc_try_fmt_vid_overlay()
713 win->global_alpha = 0; in vidioc_try_fmt_vid_overlay()
725 struct v4l2_window *win = &f->fmt.win; in vidioc_s_fmt_vid_overlay()
727 ovid = &vout->vid_info; in vidioc_s_fmt_vid_overlay()
728 ovl = ovid->overlays[0]; in vidioc_s_fmt_vid_overlay()
730 ret = omap_vout_new_window(&vout->crop, &vout->win, &vout->fbuf, win); in vidioc_s_fmt_vid_overlay()
737 if (ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) in vidioc_s_fmt_vid_overlay()
738 vout->win.global_alpha = win->global_alpha; in vidioc_s_fmt_vid_overlay()
740 win->global_alpha = 0; in vidioc_s_fmt_vid_overlay()
741 if (vout->fbuf.flags & (V4L2_FBUF_FLAG_CHROMAKEY | in vidioc_s_fmt_vid_overlay()
746 if (vout->fbuf.flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) in vidioc_s_fmt_vid_overlay()
749 if (ovl->manager && ovl->manager->get_manager_info && in vidioc_s_fmt_vid_overlay()
750 ovl->manager->set_manager_info) { in vidioc_s_fmt_vid_overlay()
753 ovl->manager->get_manager_info(ovl->manager, &info); in vidioc_s_fmt_vid_overlay()
756 info.trans_key = vout->win.chromakey; in vidioc_s_fmt_vid_overlay()
758 if (ovl->manager->set_manager_info(ovl->manager, &info)) in vidioc_s_fmt_vid_overlay()
759 return -EINVAL; in vidioc_s_fmt_vid_overlay()
771 struct v4l2_window *win = &f->fmt.win; in vidioc_g_fmt_vid_overlay()
773 ovid = &vout->vid_info; in vidioc_g_fmt_vid_overlay()
774 ovl = ovid->overlays[0]; in vidioc_g_fmt_vid_overlay()
776 win->w = vout->win.w; in vidioc_g_fmt_vid_overlay()
777 win->field = vout->win.field; in vidioc_g_fmt_vid_overlay()
778 win->chromakey = vout->win.chromakey; in vidioc_g_fmt_vid_overlay()
779 if (ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) in vidioc_g_fmt_vid_overlay()
780 win->global_alpha = vout->win.global_alpha; in vidioc_g_fmt_vid_overlay()
782 win->global_alpha = 0; in vidioc_g_fmt_vid_overlay()
783 win->clips = NULL; in vidioc_g_fmt_vid_overlay()
784 win->clipcount = 0; in vidioc_g_fmt_vid_overlay()
785 win->bitmap = NULL; in vidioc_g_fmt_vid_overlay()
792 struct v4l2_pix_format *pix = &vout->pix; in vidioc_g_selection()
794 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) in vidioc_g_selection()
795 return -EINVAL; in vidioc_g_selection()
797 switch (sel->target) { in vidioc_g_selection()
799 sel->r = vout->crop; in vidioc_g_selection()
802 omap_vout_default_crop(&vout->pix, &vout->fbuf, &sel->r); in vidioc_g_selection()
806 sel->r.width = pix->width & ~1; in vidioc_g_selection()
807 sel->r.height = pix->height & ~1; in vidioc_g_selection()
810 return -EINVAL; in vidioc_g_selection()
817 int ret = -EINVAL; in vidioc_s_selection()
821 struct omap_video_timings *timing; in vidioc_s_selection() local
824 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) in vidioc_s_selection()
825 return -EINVAL; in vidioc_s_selection()
827 if (sel->target != V4L2_SEL_TGT_CROP) in vidioc_s_selection()
828 return -EINVAL; in vidioc_s_selection()
830 if (vb2_is_busy(&vout->vq)) in vidioc_s_selection()
831 return -EBUSY; in vidioc_s_selection()
833 ovid = &vout->vid_info; in vidioc_s_selection()
834 ovl = ovid->overlays[0]; in vidioc_s_selection()
835 /* get the display device attached to the overlay */ in vidioc_s_selection()
836 dssdev = ovl->get_device(ovl); in vidioc_s_selection()
839 ret = -EINVAL; in vidioc_s_selection()
843 timing = &dssdev->panel.timings; in vidioc_s_selection()
846 vout->fbuf.fmt.height = timing->x_res; in vidioc_s_selection()
847 vout->fbuf.fmt.width = timing->y_res; in vidioc_s_selection()
849 vout->fbuf.fmt.height = timing->y_res; in vidioc_s_selection()
850 vout->fbuf.fmt.width = timing->x_res; in vidioc_s_selection()
853 ret = omap_vout_new_crop(&vout->pix, &vout->crop, &vout->win, in vidioc_s_selection()
854 &vout->fbuf, &sel->r); in vidioc_s_selection()
863 container_of(ctrl->handler, struct omap_vout_device, ctrl_handler); in omap_vout_s_ctrl()
866 switch (ctrl->id) { in omap_vout_s_ctrl()
869 int rotation = ctrl->val; in omap_vout_s_ctrl()
871 ovid = &vout->vid_info; in omap_vout_s_ctrl()
873 if (rotation && ovid->rotation_type == VOUT_ROT_NONE) { in omap_vout_s_ctrl()
874 ret = -ERANGE; in omap_vout_s_ctrl()
878 if (rotation && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) { in omap_vout_s_ctrl()
879 ret = -EINVAL; in omap_vout_s_ctrl()
883 if (v4l2_rot_to_dss_rot(rotation, &vout->rotation, in omap_vout_s_ctrl()
884 vout->mirror)) { in omap_vout_s_ctrl()
885 ret = -EINVAL; in omap_vout_s_ctrl()
893 unsigned int color = ctrl->val; in omap_vout_s_ctrl()
896 ovl = vout->vid_info.overlays[0]; in omap_vout_s_ctrl()
898 if (!ovl->manager || !ovl->manager->get_manager_info) { in omap_vout_s_ctrl()
899 ret = -EINVAL; in omap_vout_s_ctrl()
903 ovl->manager->get_manager_info(ovl->manager, &info); in omap_vout_s_ctrl()
905 if (ovl->manager->set_manager_info(ovl->manager, &info)) { in omap_vout_s_ctrl()
906 ret = -EINVAL; in omap_vout_s_ctrl()
914 unsigned int mirror = ctrl->val; in omap_vout_s_ctrl()
916 ovid = &vout->vid_info; in omap_vout_s_ctrl()
918 if (mirror && ovid->rotation_type == VOUT_ROT_NONE) { in omap_vout_s_ctrl()
919 ret = -ERANGE; in omap_vout_s_ctrl()
923 if (mirror && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) { in omap_vout_s_ctrl()
924 ret = -EINVAL; in omap_vout_s_ctrl()
927 vout->mirror = mirror; in omap_vout_s_ctrl()
931 return -EINVAL; in omap_vout_s_ctrl()
946 int size = vout->pix.sizeimage; in omap_vout_vb2_queue_setup()
948 if (is_rotation_enabled(vout) && vq->num_buffers + *nbufs > VRFB_NUM_BUFS) { in omap_vout_vb2_queue_setup()
949 *nbufs = VRFB_NUM_BUFS - vq->num_buffers; in omap_vout_vb2_queue_setup()
951 return -EINVAL; in omap_vout_vb2_queue_setup()
955 return sizes[0] < size ? -EINVAL : 0; in omap_vout_vb2_queue_setup()
964 struct omap_vout_device *vout = vb2_get_drv_priv(vb->vb2_queue); in omap_vout_vb2_prepare()
965 struct omapvideo_info *ovid = &vout->vid_info; in omap_vout_vb2_prepare()
969 if (vb2_plane_size(vb, 0) < vout->pix.sizeimage) { in omap_vout_vb2_prepare()
970 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, in omap_vout_vb2_prepare()
972 __func__, vb2_plane_size(vb, 0), vout->pix.sizeimage); in omap_vout_vb2_prepare()
973 return -EINVAL; in omap_vout_vb2_prepare()
976 vb2_set_plane_payload(vb, 0, vout->pix.sizeimage); in omap_vout_vb2_prepare()
977 voutbuf->vbuf.field = V4L2_FIELD_NONE; in omap_vout_vb2_prepare()
979 vout->queued_buf_addr[vb->index] = (u8 *)buf_phy_addr; in omap_vout_vb2_prepare()
980 if (ovid->rotation_type == VOUT_ROT_VRFB) in omap_vout_vb2_prepare()
987 struct omap_vout_device *vout = vb2_get_drv_priv(vb->vb2_queue); in omap_vout_vb2_queue()
990 list_add_tail(&voutbuf->queue, &vout->dma_queue); in omap_vout_vb2_queue()
996 struct omapvideo_info *ovid = &vout->vid_info; in omap_vout_vb2_start_streaming()
1002 vout->next_frm = vout->cur_frm = list_entry(vout->dma_queue.next, in omap_vout_vb2_start_streaming()
1005 list_del(&vout->cur_frm->queue); in omap_vout_vb2_start_streaming()
1007 vout->field_id = 0; in omap_vout_vb2_start_streaming()
1008 vout->first_int = 1; in omap_vout_vb2_start_streaming()
1009 vout->sequence = 0; in omap_vout_vb2_start_streaming()
1012 ret = -EINVAL; in omap_vout_vb2_start_streaming()
1015 if (ovid->rotation_type == VOUT_ROT_VRFB) in omap_vout_vb2_start_streaming()
1017 ret = -ENOMEM; in omap_vout_vb2_start_streaming()
1021 addr = (unsigned long)vout->queued_buf_addr[vout->cur_frm->vbuf.vb2_buf.index] in omap_vout_vb2_start_streaming()
1022 + vout->cropped_offset; in omap_vout_vb2_start_streaming()
1030 v4l2_err(&vout->vid_dev->v4l2_dev, in omap_vout_vb2_start_streaming()
1040 v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n"); in omap_vout_vb2_start_streaming()
1042 for (j = 0; j < ovid->num_overlays; j++) { in omap_vout_vb2_start_streaming()
1043 struct omap_overlay *ovl = ovid->overlays[j]; in omap_vout_vb2_start_streaming()
1044 struct omap_dss_device *dssdev = ovl->get_device(ovl); in omap_vout_vb2_start_streaming()
1047 ret = ovl->enable(ovl); in omap_vout_vb2_start_streaming()
1060 for (j = 0; j < ovid->num_overlays; j++) { in omap_vout_vb2_start_streaming()
1061 struct omap_overlay *ovl = ovid->overlays[j]; in omap_vout_vb2_start_streaming()
1062 struct omap_dss_device *dssdev = ovl->get_device(ovl); in omap_vout_vb2_start_streaming()
1065 ovl->disable(ovl); in omap_vout_vb2_start_streaming()
1069 v4l2_err(&vout->vid_dev->v4l2_dev, in omap_vout_vb2_start_streaming()
1073 vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED); in omap_vout_vb2_start_streaming()
1074 list_for_each_entry_safe(buf, tmp, &vout->dma_queue, queue) { in omap_vout_vb2_start_streaming()
1075 list_del(&buf->queue); in omap_vout_vb2_start_streaming()
1076 vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED); in omap_vout_vb2_start_streaming()
1084 struct omapvideo_info *ovid = &vout->vid_info; in omap_vout_vb2_stop_streaming()
1094 for (j = 0; j < ovid->num_overlays; j++) { in omap_vout_vb2_stop_streaming()
1095 struct omap_overlay *ovl = ovid->overlays[j]; in omap_vout_vb2_stop_streaming()
1096 struct omap_dss_device *dssdev = ovl->get_device(ovl); in omap_vout_vb2_stop_streaming()
1099 ovl->disable(ovl); in omap_vout_vb2_stop_streaming()
1103 v4l2_err(&vout->vid_dev->v4l2_dev, in omap_vout_vb2_stop_streaming()
1106 if (vout->next_frm != vout->cur_frm) in omap_vout_vb2_stop_streaming()
1107 vb2_buffer_done(&vout->next_frm->vbuf.vb2_buf, VB2_BUF_STATE_ERROR); in omap_vout_vb2_stop_streaming()
1108 vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_ERROR); in omap_vout_vb2_stop_streaming()
1109 list_for_each_entry_safe(buf, tmp, &vout->dma_queue, queue) { in omap_vout_vb2_stop_streaming()
1110 list_del(&buf->queue); in omap_vout_vb2_stop_streaming()
1111 vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR); in omap_vout_vb2_stop_streaming()
1125 ovid = &vout->vid_info; in vidioc_s_fbuf()
1126 ovl = ovid->overlays[0]; in vidioc_s_fbuf()
1130 if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) && in vidioc_s_fbuf()
1131 (a->flags & V4L2_FBUF_FLAG_CHROMAKEY)) in vidioc_s_fbuf()
1132 return -EINVAL; in vidioc_s_fbuf()
1135 if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY) && in vidioc_s_fbuf()
1136 (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA)) in vidioc_s_fbuf()
1137 return -EINVAL; in vidioc_s_fbuf()
1139 if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY)) { in vidioc_s_fbuf()
1140 vout->fbuf.flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY; in vidioc_s_fbuf()
1143 vout->fbuf.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY; in vidioc_s_fbuf()
1145 if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY)) { in vidioc_s_fbuf()
1146 vout->fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY; in vidioc_s_fbuf()
1149 vout->fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY; in vidioc_s_fbuf()
1151 if (a->flags & (V4L2_FBUF_FLAG_CHROMAKEY | in vidioc_s_fbuf()
1156 if (ovl->manager && ovl->manager->get_manager_info && in vidioc_s_fbuf()
1157 ovl->manager->set_manager_info) { in vidioc_s_fbuf()
1159 ovl->manager->get_manager_info(ovl->manager, &info); in vidioc_s_fbuf()
1162 info.trans_key = vout->win.chromakey; in vidioc_s_fbuf()
1164 if (ovl->manager->set_manager_info(ovl->manager, &info)) in vidioc_s_fbuf()
1165 return -EINVAL; in vidioc_s_fbuf()
1167 if (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) { in vidioc_s_fbuf()
1168 vout->fbuf.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; in vidioc_s_fbuf()
1171 vout->fbuf.flags &= ~V4L2_FBUF_FLAG_LOCAL_ALPHA; in vidioc_s_fbuf()
1174 if (ovl->manager && ovl->manager->get_manager_info && in vidioc_s_fbuf()
1175 ovl->manager->set_manager_info) { in vidioc_s_fbuf()
1176 ovl->manager->get_manager_info(ovl->manager, &info); in vidioc_s_fbuf()
1178 if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0) in vidioc_s_fbuf()
1180 if (ovl->manager->set_manager_info(ovl->manager, &info)) in vidioc_s_fbuf()
1181 return -EINVAL; in vidioc_s_fbuf()
1194 struct omap_video_timings *timing; in vidioc_g_fbuf() local
1197 ovid = &vout->vid_info; in vidioc_g_fbuf()
1198 ovl = ovid->overlays[0]; in vidioc_g_fbuf()
1199 /* get the display device attached to the overlay */ in vidioc_g_fbuf()
1200 dssdev = ovl->get_device(ovl); in vidioc_g_fbuf()
1203 return -EINVAL; in vidioc_g_fbuf()
1205 timing = &dssdev->panel.timings; in vidioc_g_fbuf()
1207 vout->fbuf.fmt.height = timing->y_res; in vidioc_g_fbuf()
1208 vout->fbuf.fmt.width = timing->x_res; in vidioc_g_fbuf()
1209 a->fmt.field = V4L2_FIELD_NONE; in vidioc_g_fbuf()
1210 a->fmt.colorspace = V4L2_COLORSPACE_SRGB; in vidioc_g_fbuf()
1211 a->fmt.pixelformat = V4L2_PIX_FMT_RGBA32; in vidioc_g_fbuf()
1212 a->fmt.height = vout->fbuf.fmt.height; in vidioc_g_fbuf()
1213 a->fmt.width = vout->fbuf.fmt.width; in vidioc_g_fbuf()
1214 a->fmt.bytesperline = vout->fbuf.fmt.width * 4; in vidioc_g_fbuf()
1215 a->fmt.sizeimage = a->fmt.height * a->fmt.bytesperline; in vidioc_g_fbuf()
1216 a->base = vout->fbuf.base; in vidioc_g_fbuf()
1218 a->flags = vout->fbuf.flags; in vidioc_g_fbuf()
1219 a->capability = vout->fbuf.capability; in vidioc_g_fbuf()
1220 a->flags &= ~(V4L2_FBUF_FLAG_SRC_CHROMAKEY | V4L2_FBUF_FLAG_CHROMAKEY | in vidioc_g_fbuf()
1223 if (ovl->manager && ovl->manager->get_manager_info) { in vidioc_g_fbuf()
1224 ovl->manager->get_manager_info(ovl->manager, &info); in vidioc_g_fbuf()
1226 a->flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY; in vidioc_g_fbuf()
1228 a->flags |= V4L2_FBUF_FLAG_CHROMAKEY; in vidioc_g_fbuf()
1230 a->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; in vidioc_g_fbuf()
1239 if (out->index) in vidioc_enum_output()
1240 return -EINVAL; in vidioc_enum_output()
1241 snprintf(out->name, sizeof(out->name), "Overlay"); in vidioc_enum_output()
1242 out->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; in vidioc_enum_output()
1254 return i ? -EINVAL : 0; in vidioc_s_output()
1310 struct omap_overlay *ovl = vout->vid_info.overlays[0]; in omap_vout_setup_video_data()
1311 struct omap_dss_device *display = ovl->get_device(ovl); in omap_vout_setup_video_data() local
1317 pix = &vout->pix; in omap_vout_setup_video_data()
1320 pix->width = QQVGA_WIDTH; in omap_vout_setup_video_data()
1321 pix->height = QQVGA_HEIGHT; in omap_vout_setup_video_data()
1323 /* Default pixel format is RGB 5-6-5 */ in omap_vout_setup_video_data()
1324 pix->pixelformat = V4L2_PIX_FMT_RGB565; in omap_vout_setup_video_data()
1325 pix->field = V4L2_FIELD_NONE; in omap_vout_setup_video_data()
1326 pix->bytesperline = pix->width * 2; in omap_vout_setup_video_data()
1327 pix->sizeimage = pix->bytesperline * pix->height; in omap_vout_setup_video_data()
1328 pix->colorspace = V4L2_COLORSPACE_SRGB; in omap_vout_setup_video_data()
1330 vout->bpp = RGB565_BPP; in omap_vout_setup_video_data()
1331 vout->fbuf.fmt.width = display->panel.timings.x_res; in omap_vout_setup_video_data()
1332 vout->fbuf.fmt.height = display->panel.timings.y_res; in omap_vout_setup_video_data()
1333 vout->cropped_offset = 0; in omap_vout_setup_video_data()
1336 vout->fbuf.flags = V4L2_FBUF_FLAG_OVERLAY; in omap_vout_setup_video_data()
1337 vout->fbuf.capability = V4L2_FBUF_CAP_LOCAL_ALPHA | in omap_vout_setup_video_data()
1340 if (ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) { in omap_vout_setup_video_data()
1341 vout->win.global_alpha = 255; in omap_vout_setup_video_data()
1342 vout->fbuf.capability |= V4L2_FBUF_CAP_GLOBAL_ALPHA; in omap_vout_setup_video_data()
1343 vout->fbuf.flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; in omap_vout_setup_video_data()
1345 vout->win.global_alpha = 0; in omap_vout_setup_video_data()
1347 vout->win.field = V4L2_FIELD_NONE; in omap_vout_setup_video_data()
1349 omap_vout_new_format(pix, &vout->fbuf, &vout->crop, &vout->win); in omap_vout_setup_video_data()
1351 hdl = &vout->ctrl_handler; in omap_vout_setup_video_data()
1353 if (vout->vid_info.rotation_type == VOUT_ROT_VRFB) { in omap_vout_setup_video_data()
1361 if (hdl->error) in omap_vout_setup_video_data()
1362 return hdl->error; in omap_vout_setup_video_data()
1364 vout->rotation = 0; in omap_vout_setup_video_data()
1365 vout->mirror = false; in omap_vout_setup_video_data()
1366 INIT_LIST_HEAD(&vout->dma_queue); in omap_vout_setup_video_data()
1367 if (vout->vid_info.rotation_type == VOUT_ROT_VRFB) in omap_vout_setup_video_data()
1368 vout->vrfb_bpp = 2; in omap_vout_setup_video_data()
1371 vfd = vout->vfd = video_device_alloc(); in omap_vout_setup_video_data()
1377 return -ENOMEM; in omap_vout_setup_video_data()
1379 vfd->ctrl_handler = hdl; in omap_vout_setup_video_data()
1380 vfd->release = video_device_release; in omap_vout_setup_video_data()
1381 vfd->ioctl_ops = &vout_ioctl_ops; in omap_vout_setup_video_data()
1383 strscpy(vfd->name, VOUT_NAME, sizeof(vfd->name)); in omap_vout_setup_video_data()
1385 vfd->fops = &omap_vout_fops; in omap_vout_setup_video_data()
1386 vfd->v4l2_dev = &vout->vid_dev->v4l2_dev; in omap_vout_setup_video_data()
1387 vfd->vfl_dir = VFL_DIR_TX; in omap_vout_setup_video_data()
1388 vfd->minor = -1; in omap_vout_setup_video_data()
1389 vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT | in omap_vout_setup_video_data()
1391 mutex_init(&vout->lock); in omap_vout_setup_video_data()
1393 vq = &vout->vq; in omap_vout_setup_video_data()
1394 vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; in omap_vout_setup_video_data()
1395 vq->io_modes = VB2_MMAP | VB2_DMABUF; in omap_vout_setup_video_data()
1396 vq->drv_priv = vout; in omap_vout_setup_video_data()
1397 vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in omap_vout_setup_video_data()
1398 vq->buf_struct_size = sizeof(struct omap_vout_buffer); in omap_vout_setup_video_data()
1399 vq->dev = vfd->v4l2_dev->dev; in omap_vout_setup_video_data()
1401 vq->ops = &omap_vout_vb2_ops; in omap_vout_setup_video_data()
1402 vq->mem_ops = &vb2_dma_contig_memops; in omap_vout_setup_video_data()
1403 vq->lock = &vout->lock; in omap_vout_setup_video_data()
1404 vq->min_buffers_needed = 1; in omap_vout_setup_video_data()
1405 vfd->queue = vq; in omap_vout_setup_video_data()
1426 vout = vid_dev->vouts[vid_num]; in omap_vout_setup_video_bufs()
1427 ovid = &vout->vid_info; in omap_vout_setup_video_bufs()
1429 if (ovid->rotation_type == VOUT_ROT_VRFB) { in omap_vout_setup_video_bufs()
1447 struct omap_overlay *ovl = vid_dev->overlays[0]; in omap_vout_create_video_devices()
1450 ovl->get_overlay_info(ovl, &info); in omap_vout_create_video_devices()
1452 for (k = 0; k < pdev->num_resources; k++) { in omap_vout_create_video_devices()
1456 dev_err(&pdev->dev, ": could not allocate memory\n"); in omap_vout_create_video_devices()
1457 return -ENOMEM; in omap_vout_create_video_devices()
1460 vout->vid = k; in omap_vout_create_video_devices()
1461 vid_dev->vouts[k] = vout; in omap_vout_create_video_devices()
1462 vout->vid_dev = vid_dev; in omap_vout_create_video_devices()
1464 if (pdev->num_resources == 1) in omap_vout_create_video_devices()
1465 vout->vid_info.overlays[0] = vid_dev->overlays[k + 2]; in omap_vout_create_video_devices()
1468 vout->vid_info.overlays[0] = vid_dev->overlays[k + 1]; in omap_vout_create_video_devices()
1469 vout->vid_info.num_overlays = 1; in omap_vout_create_video_devices()
1470 vout->vid_info.id = k + 1; in omap_vout_create_video_devices()
1471 spin_lock_init(&vout->vbq_lock); in omap_vout_create_video_devices()
1479 vout->fbuf.base = (void *)info.paddr; in omap_vout_create_video_devices()
1483 vout->vid_info.rotation_type = VOUT_ROT_VRFB; in omap_vout_create_video_devices()
1488 ret = -ENOMEM; in omap_vout_create_video_devices()
1496 ret = -ENOMEM; in omap_vout_create_video_devices()
1502 vfd = vout->vfd; in omap_vout_create_video_devices()
1503 if (video_register_device(vfd, VFL_TYPE_GRABBER, -1) < 0) { in omap_vout_create_video_devices()
1504 dev_err(&pdev->dev, in omap_vout_create_video_devices()
1506 vfd->minor = -1; in omap_vout_create_video_devices()
1507 ret = -ENODEV; in omap_vout_create_video_devices()
1512 dev_info(&pdev->dev, in omap_vout_create_video_devices()
1514 vfd->minor); in omap_vout_create_video_devices()
1515 if (k == (pdev->num_resources - 1)) in omap_vout_create_video_devices()
1520 if (vout->vid_info.rotation_type == VOUT_ROT_VRFB) in omap_vout_create_video_devices()
1529 return -ENODEV; in omap_vout_create_video_devices()
1540 vfd = vout->vfd; in omap_vout_cleanup_device()
1541 ovid = &vout->vid_info; in omap_vout_cleanup_device()
1557 v4l2_ctrl_handler_free(&vout->ctrl_handler); in omap_vout_cleanup_device()
1558 if (ovid->rotation_type == VOUT_ROT_VRFB) { in omap_vout_cleanup_device()
1563 if (vout->vrfb_static_allocation) in omap_vout_cleanup_device()
1578 for (k = 0; k < pdev->num_resources; k++) in omap_vout_remove()
1579 omap_vout_cleanup_device(vid_dev->vouts[k]); in omap_vout_remove()
1581 for (k = 0; k < vid_dev->num_displays; k++) { in omap_vout_remove()
1582 if (vid_dev->displays[k]->state != OMAP_DSS_DISPLAY_DISABLED) in omap_vout_remove()
1583 vid_dev->displays[k]->driver->disable(vid_dev->displays[k]); in omap_vout_remove()
1585 omap_dss_put_device(vid_dev->displays[k]); in omap_vout_remove()
1600 return -EPROBE_DEFER; in omap_vout_probe()
1604 dev_err(&pdev->dev, "failed to init dss\n"); in omap_vout_probe()
1608 if (pdev->num_resources == 0) { in omap_vout_probe()
1609 dev_err(&pdev->dev, "probed for an unknown device\n"); in omap_vout_probe()
1610 ret = -ENODEV; in omap_vout_probe()
1616 ret = -ENOMEM; in omap_vout_probe()
1620 vid_dev->num_displays = 0; in omap_vout_probe()
1624 if (!dssdev->driver) { in omap_vout_probe()
1625 dev_warn(&pdev->dev, "no driver for display: %s\n", in omap_vout_probe()
1626 dssdev->name); in omap_vout_probe()
1631 vid_dev->displays[vid_dev->num_displays++] = dssdev; in omap_vout_probe()
1634 if (vid_dev->num_displays == 0) { in omap_vout_probe()
1635 dev_err(&pdev->dev, "no displays\n"); in omap_vout_probe()
1636 ret = -EINVAL; in omap_vout_probe()
1640 vid_dev->num_overlays = omap_dss_get_num_overlays(); in omap_vout_probe()
1641 for (i = 0; i < vid_dev->num_overlays; i++) in omap_vout_probe()
1642 vid_dev->overlays[i] = omap_dss_get_overlay(i); in omap_vout_probe()
1644 vid_dev->num_managers = omap_dss_get_num_overlay_managers(); in omap_vout_probe()
1645 for (i = 0; i < vid_dev->num_managers; i++) in omap_vout_probe()
1646 vid_dev->managers[i] = omap_dss_get_overlay_manager(i); in omap_vout_probe()
1649 * Setup the Display attached to that overlays in omap_vout_probe()
1651 for (i = 1; i < vid_dev->num_overlays; i++) { in omap_vout_probe()
1653 dssdev = ovl->get_device(ovl); in omap_vout_probe()
1658 dev_warn(&pdev->dev, "cannot find display\n"); in omap_vout_probe()
1662 struct omap_dss_driver *dssdrv = def_display->driver; in omap_vout_probe()
1664 ret = dssdrv->enable(def_display); in omap_vout_probe()
1667 * as display may be enabled by frame in omap_vout_probe()
1670 dev_warn(&pdev->dev, in omap_vout_probe()
1671 "'%s' Display already enabled\n", in omap_vout_probe()
1672 def_display->name); in omap_vout_probe()
1677 if (v4l2_device_register(&pdev->dev, &vid_dev->v4l2_dev) < 0) { in omap_vout_probe()
1678 dev_err(&pdev->dev, "v4l2_device_register failed\n"); in omap_vout_probe()
1679 ret = -ENODEV; in omap_vout_probe()
1687 for (i = 0; i < vid_dev->num_displays; i++) { in omap_vout_probe()
1688 struct omap_dss_device *display = vid_dev->displays[i]; in omap_vout_probe() local
1690 if (display->driver->update) in omap_vout_probe()
1691 display->driver->update(display, 0, 0, in omap_vout_probe()
1692 display->panel.timings.x_res, in omap_vout_probe()
1693 display->panel.timings.y_res); in omap_vout_probe()
1698 v4l2_device_unregister(&vid_dev->v4l2_dev); in omap_vout_probe()
1700 for (i = 1; i < vid_dev->num_overlays; i++) { in omap_vout_probe()
1703 dssdev = ovl->get_device(ovl); in omap_vout_probe()
1708 if (def_display && def_display->driver) in omap_vout_probe()
1709 def_display->driver->disable(def_display); in omap_vout_probe()
1729 return -EINVAL; in omap_vout_init()