Lines Matching +full:top +full:- +full:left

1 // SPDX-License-Identifier: GPL-2.0
15 #include <media/v4l2-event.h>
16 #include <media/v4l2-ioctl.h>
73 /* NV12. YUV420SP - 1 plane for Y + 1 plane for (CbCr) */
91 /* YU12. YUV420P - 1 plane for Y + 1 plane for Cb + 1 plane for Cr
124 spin_lock_irqsave(&ctx->bdisp_dev->slock, flags); in bdisp_ctx_state_lock_set()
125 ctx->state |= state; in bdisp_ctx_state_lock_set()
126 spin_unlock_irqrestore(&ctx->bdisp_dev->slock, flags); in bdisp_ctx_state_lock_set()
133 spin_lock_irqsave(&ctx->bdisp_dev->slock, flags); in bdisp_ctx_state_lock_clear()
134 ctx->state &= ~state; in bdisp_ctx_state_lock_clear()
135 spin_unlock_irqrestore(&ctx->bdisp_dev->slock, flags); in bdisp_ctx_state_lock_clear()
143 spin_lock_irqsave(&ctx->bdisp_dev->slock, flags); in bdisp_ctx_state_is_set()
144 ret = (ctx->state & mask) == mask; in bdisp_ctx_state_is_set()
145 spin_unlock_irqrestore(&ctx->bdisp_dev->slock, flags); in bdisp_ctx_state_is_set()
157 if (fmt->pixelformat == pixelformat) in bdisp_find_fmt()
169 return &ctx->src; in ctx_get_frame()
171 return &ctx->dst; in ctx_get_frame()
173 dev_err(ctx->bdisp_dev->dev, in ctx_get_frame()
178 return ERR_PTR(-EINVAL); in ctx_get_frame()
185 if (WARN(!ctx || !ctx->fh.m2m_ctx, "Null hardware context\n")) in bdisp_job_finish()
188 dev_dbg(ctx->bdisp_dev->dev, "%s\n", __func__); in bdisp_job_finish()
190 src_vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); in bdisp_job_finish()
191 dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); in bdisp_job_finish()
194 dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp; in bdisp_job_finish()
195 dst_vb->timecode = src_vb->timecode; in bdisp_job_finish()
196 dst_vb->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; in bdisp_job_finish()
197 dst_vb->flags |= src_vb->flags & in bdisp_job_finish()
203 v4l2_m2m_job_finish(ctx->bdisp_dev->m2m.m2m_dev, in bdisp_job_finish()
204 ctx->fh.m2m_ctx); in bdisp_job_finish()
211 struct bdisp_dev *bdisp = ctx->bdisp_dev; in bdisp_ctx_stop_req()
214 dev_dbg(ctx->bdisp_dev->dev, "%s\n", __func__); in bdisp_ctx_stop_req()
216 cancel_delayed_work(&bdisp->timeout_work); in bdisp_ctx_stop_req()
218 curr_ctx = v4l2_m2m_get_curr_priv(bdisp->m2m.m2m_dev); in bdisp_ctx_stop_req()
219 if (!test_bit(ST_M2M_RUNNING, &bdisp->state) || (curr_ctx != ctx)) in bdisp_ctx_stop_req()
224 ret = wait_event_timeout(bdisp->irq_queue, in bdisp_ctx_stop_req()
229 dev_err(ctx->bdisp_dev->dev, "%s IRQ timeout\n", __func__); in bdisp_ctx_stop_req()
230 return -ETIMEDOUT; in bdisp_ctx_stop_req()
241 if ((ret == -ETIMEDOUT) || (ctx->state & BDISP_CTX_ABORT)) { in __bdisp_job_abort()
257 return -EINVAL; in bdisp_get_addr()
261 if (frame->fmt->nb_planes > 1) in bdisp_get_addr()
264 frame->bytesperline * frame->height); in bdisp_get_addr()
266 if (frame->fmt->nb_planes > 2) in bdisp_get_addr()
269 (frame->bytesperline * frame->height) / 4); in bdisp_get_addr()
271 if (frame->fmt->nb_planes > 3) in bdisp_get_addr()
272 dev_dbg(ctx->bdisp_dev->dev, "ignoring some planes\n"); in bdisp_get_addr()
274 dev_dbg(ctx->bdisp_dev->dev, in bdisp_get_addr()
287 src = &ctx->src; in bdisp_get_bufs()
288 dst = &ctx->dst; in bdisp_get_bufs()
290 src_vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); in bdisp_get_bufs()
291 ret = bdisp_get_addr(ctx, &src_vb->vb2_buf, src, src->paddr); in bdisp_get_bufs()
295 dst_vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); in bdisp_get_bufs()
296 ret = bdisp_get_addr(ctx, &dst_vb->vb2_buf, dst, dst->paddr); in bdisp_get_bufs()
300 dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp; in bdisp_get_bufs()
315 bdisp = ctx->bdisp_dev; in bdisp_device_run()
316 dev_dbg(bdisp->dev, "%s\n", __func__); in bdisp_device_run()
317 spin_lock_irqsave(&bdisp->slock, flags); in bdisp_device_run()
319 if (bdisp->m2m.ctx != ctx) { in bdisp_device_run()
320 dev_dbg(bdisp->dev, "ctx updated: %p -> %p\n", in bdisp_device_run()
321 bdisp->m2m.ctx, ctx); in bdisp_device_run()
322 ctx->state |= BDISP_PARAMS; in bdisp_device_run()
323 bdisp->m2m.ctx = ctx; in bdisp_device_run()
326 if (ctx->state & BDISP_CTX_STOP_REQ) { in bdisp_device_run()
327 ctx->state &= ~BDISP_CTX_STOP_REQ; in bdisp_device_run()
328 ctx->state |= BDISP_CTX_ABORT; in bdisp_device_run()
329 wake_up(&bdisp->irq_queue); in bdisp_device_run()
335 dev_err(bdisp->dev, "cannot get address\n"); in bdisp_device_run()
343 dev_err(bdisp->dev, "could not get HW ready\n"); in bdisp_device_run()
349 dev_err(bdisp->dev, "could not send HW request\n"); in bdisp_device_run()
353 queue_delayed_work(bdisp->work_queue, &bdisp->timeout_work, in bdisp_device_run()
355 set_bit(ST_M2M_RUNNING, &bdisp->state); in bdisp_device_run()
357 ctx->state &= ~BDISP_PARAMS; in bdisp_device_run()
358 spin_unlock_irqrestore(&bdisp->slock, flags); in bdisp_device_run()
370 if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) in __bdisp_s_ctrl()
373 switch (ctrl->id) { in __bdisp_s_ctrl()
375 ctx->hflip = ctrl->val; in __bdisp_s_ctrl()
378 ctx->vflip = ctrl->val; in __bdisp_s_ctrl()
381 dev_err(ctx->bdisp_dev->dev, "unknown control %d\n", ctrl->id); in __bdisp_s_ctrl()
382 return -EINVAL; in __bdisp_s_ctrl()
385 ctx->state |= BDISP_PARAMS; in __bdisp_s_ctrl()
392 struct bdisp_ctx *ctx = container_of(ctrl->handler, struct bdisp_ctx, in bdisp_s_ctrl()
397 spin_lock_irqsave(&ctx->bdisp_dev->slock, flags); in bdisp_s_ctrl()
399 spin_unlock_irqrestore(&ctx->bdisp_dev->slock, flags); in bdisp_s_ctrl()
410 if (ctx->ctrls_rdy) in bdisp_ctrls_create()
413 v4l2_ctrl_handler_init(&ctx->ctrl_handler, BDISP_MAX_CTRL_NUM); in bdisp_ctrls_create()
415 ctx->bdisp_ctrls.hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, in bdisp_ctrls_create()
417 ctx->bdisp_ctrls.vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, in bdisp_ctrls_create()
420 if (ctx->ctrl_handler.error) { in bdisp_ctrls_create()
421 int err = ctx->ctrl_handler.error; in bdisp_ctrls_create()
423 v4l2_ctrl_handler_free(&ctx->ctrl_handler); in bdisp_ctrls_create()
427 ctx->ctrls_rdy = true; in bdisp_ctrls_create()
434 if (ctx->ctrls_rdy) { in bdisp_ctrls_delete()
435 v4l2_ctrl_handler_free(&ctx->ctrl_handler); in bdisp_ctrls_delete()
436 ctx->ctrls_rdy = false; in bdisp_ctrls_delete()
445 struct bdisp_frame *frame = ctx_get_frame(ctx, vq->type); in bdisp_queue_setup()
448 dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); in bdisp_queue_setup()
452 if (!frame->fmt) { in bdisp_queue_setup()
453 dev_err(ctx->bdisp_dev->dev, "Invalid format\n"); in bdisp_queue_setup()
454 return -EINVAL; in bdisp_queue_setup()
458 return sizes[0] < frame->sizeimage ? -EINVAL : 0; in bdisp_queue_setup()
461 sizes[0] = frame->sizeimage; in bdisp_queue_setup()
468 struct bdisp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in bdisp_buf_prepare()
469 struct bdisp_frame *frame = ctx_get_frame(ctx, vb->vb2_queue->type); in bdisp_buf_prepare()
472 dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); in bdisp_buf_prepare()
476 if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) in bdisp_buf_prepare()
477 vb2_set_plane_payload(vb, 0, frame->sizeimage); in bdisp_buf_prepare()
485 struct bdisp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); in bdisp_buf_queue()
487 /* return to V4L2 any 0-size buffer so it can be dequeued by user */ in bdisp_buf_queue()
489 dev_dbg(ctx->bdisp_dev->dev, "0 data buffer, skip it\n"); in bdisp_buf_queue()
494 if (ctx->fh.m2m_ctx) in bdisp_buf_queue()
495 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); in bdisp_buf_queue()
500 struct bdisp_ctx *ctx = q->drv_priv; in bdisp_start_streaming()
502 int ret = pm_runtime_resume_and_get(ctx->bdisp_dev->dev); in bdisp_start_streaming()
505 dev_err(ctx->bdisp_dev->dev, "failed to set runtime PM\n"); in bdisp_start_streaming()
507 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { in bdisp_start_streaming()
508 while ((buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx))) in bdisp_start_streaming()
511 while ((buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx))) in bdisp_start_streaming()
523 struct bdisp_ctx *ctx = q->drv_priv; in bdisp_stop_streaming()
527 pm_runtime_put(ctx->bdisp_dev->dev); in bdisp_stop_streaming()
547 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; in queue_init()
548 src_vq->io_modes = VB2_MMAP | VB2_DMABUF; in queue_init()
549 src_vq->drv_priv = ctx; in queue_init()
550 src_vq->ops = &bdisp_qops; in queue_init()
551 src_vq->mem_ops = &vb2_dma_contig_memops; in queue_init()
552 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); in queue_init()
553 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in queue_init()
554 src_vq->lock = &ctx->bdisp_dev->lock; in queue_init()
555 src_vq->dev = ctx->bdisp_dev->v4l2_dev.dev; in queue_init()
562 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in queue_init()
563 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; in queue_init()
564 dst_vq->drv_priv = ctx; in queue_init()
565 dst_vq->ops = &bdisp_qops; in queue_init()
566 dst_vq->mem_ops = &vb2_dma_contig_memops; in queue_init()
567 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); in queue_init()
568 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in queue_init()
569 dst_vq->lock = &ctx->bdisp_dev->lock; in queue_init()
570 dst_vq->dev = ctx->bdisp_dev->v4l2_dev.dev; in queue_init()
581 if (mutex_lock_interruptible(&bdisp->lock)) in bdisp_open()
582 return -ERESTARTSYS; in bdisp_open()
587 ret = -ENOMEM; in bdisp_open()
590 ctx->bdisp_dev = bdisp; in bdisp_open()
593 dev_err(bdisp->dev, "no memory for nodes\n"); in bdisp_open()
594 ret = -ENOMEM; in bdisp_open()
598 v4l2_fh_init(&ctx->fh, bdisp->m2m.vdev); in bdisp_open()
602 dev_err(bdisp->dev, "Failed to create control\n"); in bdisp_open()
607 ctx->fh.ctrl_handler = &ctx->ctrl_handler; in bdisp_open()
608 file->private_data = &ctx->fh; in bdisp_open()
609 v4l2_fh_add(&ctx->fh); in bdisp_open()
612 ctx->src = bdisp_dflt_fmt; in bdisp_open()
613 ctx->dst = bdisp_dflt_fmt; in bdisp_open()
616 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(bdisp->m2m.m2m_dev, ctx, in bdisp_open()
618 if (IS_ERR(ctx->fh.m2m_ctx)) { in bdisp_open()
619 dev_err(bdisp->dev, "Failed to initialize m2m context\n"); in bdisp_open()
620 ret = PTR_ERR(ctx->fh.m2m_ctx); in bdisp_open()
624 bdisp->m2m.refcnt++; in bdisp_open()
625 set_bit(ST_M2M_OPEN, &bdisp->state); in bdisp_open()
627 dev_dbg(bdisp->dev, "driver opened, ctx = 0x%p\n", ctx); in bdisp_open()
629 mutex_unlock(&bdisp->lock); in bdisp_open()
635 v4l2_fh_del(&ctx->fh); in bdisp_open()
637 v4l2_fh_exit(&ctx->fh); in bdisp_open()
642 mutex_unlock(&bdisp->lock); in bdisp_open()
649 struct bdisp_ctx *ctx = fh_to_ctx(file->private_data); in bdisp_release()
650 struct bdisp_dev *bdisp = ctx->bdisp_dev; in bdisp_release()
652 dev_dbg(bdisp->dev, "%s\n", __func__); in bdisp_release()
654 mutex_lock(&bdisp->lock); in bdisp_release()
656 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); in bdisp_release()
660 v4l2_fh_del(&ctx->fh); in bdisp_release()
661 v4l2_fh_exit(&ctx->fh); in bdisp_release()
663 if (--bdisp->m2m.refcnt <= 0) in bdisp_release()
664 clear_bit(ST_M2M_OPEN, &bdisp->state); in bdisp_release()
670 mutex_unlock(&bdisp->lock); in bdisp_release()
688 struct bdisp_dev *bdisp = ctx->bdisp_dev; in bdisp_querycap()
690 strscpy(cap->driver, bdisp->pdev->name, sizeof(cap->driver)); in bdisp_querycap()
691 strscpy(cap->card, bdisp->pdev->name, sizeof(cap->card)); in bdisp_querycap()
692 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s%d", in bdisp_querycap()
693 BDISP_NAME, bdisp->id); in bdisp_querycap()
702 if (f->index >= ARRAY_SIZE(bdisp_formats)) in bdisp_enum_fmt()
703 return -EINVAL; in bdisp_enum_fmt()
705 fmt = &bdisp_formats[f->index]; in bdisp_enum_fmt()
707 if ((fmt->pixelformat == V4L2_PIX_FMT_YUV420) && in bdisp_enum_fmt()
708 (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)) { in bdisp_enum_fmt()
709 dev_dbg(ctx->bdisp_dev->dev, "No YU12 on capture\n"); in bdisp_enum_fmt()
710 return -EINVAL; in bdisp_enum_fmt()
712 f->pixelformat = fmt->pixelformat; in bdisp_enum_fmt()
721 struct bdisp_frame *frame = ctx_get_frame(ctx, f->type); in bdisp_g_fmt()
724 dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); in bdisp_g_fmt()
728 pix = &f->fmt.pix; in bdisp_g_fmt()
729 pix->width = frame->width; in bdisp_g_fmt()
730 pix->height = frame->height; in bdisp_g_fmt()
731 pix->pixelformat = frame->fmt->pixelformat; in bdisp_g_fmt()
732 pix->field = frame->field; in bdisp_g_fmt()
733 pix->bytesperline = frame->bytesperline; in bdisp_g_fmt()
734 pix->sizeimage = frame->sizeimage; in bdisp_g_fmt()
735 pix->colorspace = (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? in bdisp_g_fmt()
736 frame->colorspace : bdisp_dflt_fmt.colorspace; in bdisp_g_fmt()
744 struct v4l2_pix_format *pix = &f->fmt.pix; in bdisp_try_fmt()
748 format = bdisp_find_fmt(pix->pixelformat); in bdisp_try_fmt()
750 dev_dbg(ctx->bdisp_dev->dev, "Unknown format 0x%x\n", in bdisp_try_fmt()
751 pix->pixelformat); in bdisp_try_fmt()
752 return -EINVAL; in bdisp_try_fmt()
756 if ((format->pixelformat == V4L2_PIX_FMT_YUV420) && in bdisp_try_fmt()
757 (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)) { in bdisp_try_fmt()
758 dev_dbg(ctx->bdisp_dev->dev, "No YU12 on capture\n"); in bdisp_try_fmt()
759 return -EINVAL; in bdisp_try_fmt()
763 if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) || in bdisp_try_fmt()
764 (pix->field != V4L2_FIELD_INTERLACED)) in bdisp_try_fmt()
765 pix->field = V4L2_FIELD_NONE; in bdisp_try_fmt()
768 in_w = pix->width; in bdisp_try_fmt()
769 in_h = pix->height; in bdisp_try_fmt()
770 v4l_bound_align_image(&pix->width, in bdisp_try_fmt()
772 ffs(format->w_align) - 1, in bdisp_try_fmt()
773 &pix->height, in bdisp_try_fmt()
775 ffs(format->h_align) - 1, in bdisp_try_fmt()
777 if ((pix->width != in_w) || (pix->height != in_h)) in bdisp_try_fmt()
778 dev_dbg(ctx->bdisp_dev->dev, in bdisp_try_fmt()
779 "%s size updated: %dx%d -> %dx%d\n", __func__, in bdisp_try_fmt()
780 in_w, in_h, pix->width, pix->height); in bdisp_try_fmt()
782 pix->bytesperline = (pix->width * format->bpp_plane0) / 8; in bdisp_try_fmt()
783 pix->sizeimage = (pix->width * pix->height * format->bpp) / 8; in bdisp_try_fmt()
785 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) in bdisp_try_fmt()
786 pix->colorspace = bdisp_dflt_fmt.colorspace; in bdisp_try_fmt()
802 dev_err(ctx->bdisp_dev->dev, "Cannot set format\n"); in bdisp_s_fmt()
806 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); in bdisp_s_fmt()
808 dev_err(ctx->bdisp_dev->dev, "queue (%d) busy\n", f->type); in bdisp_s_fmt()
809 return -EBUSY; in bdisp_s_fmt()
812 frame = (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? in bdisp_s_fmt()
813 &ctx->src : &ctx->dst; in bdisp_s_fmt()
814 pix = &f->fmt.pix; in bdisp_s_fmt()
815 frame->fmt = bdisp_find_fmt(pix->pixelformat); in bdisp_s_fmt()
816 if (!frame->fmt) { in bdisp_s_fmt()
817 dev_err(ctx->bdisp_dev->dev, "Unknown format 0x%x\n", in bdisp_s_fmt()
818 pix->pixelformat); in bdisp_s_fmt()
819 return -EINVAL; in bdisp_s_fmt()
822 frame->width = pix->width; in bdisp_s_fmt()
823 frame->height = pix->height; in bdisp_s_fmt()
824 frame->bytesperline = pix->bytesperline; in bdisp_s_fmt()
825 frame->sizeimage = pix->sizeimage; in bdisp_s_fmt()
826 frame->field = pix->field; in bdisp_s_fmt()
827 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) in bdisp_s_fmt()
828 frame->colorspace = pix->colorspace; in bdisp_s_fmt()
830 frame->crop.width = frame->width; in bdisp_s_fmt()
831 frame->crop.height = frame->height; in bdisp_s_fmt()
832 frame->crop.left = 0; in bdisp_s_fmt()
833 frame->crop.top = 0; in bdisp_s_fmt()
836 state |= (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ? in bdisp_s_fmt()
849 frame = ctx_get_frame(ctx, s->type); in bdisp_g_selection()
851 dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); in bdisp_g_selection()
855 switch (s->type) { in bdisp_g_selection()
857 switch (s->target) { in bdisp_g_selection()
860 s->r = frame->crop; in bdisp_g_selection()
865 s->r.left = 0; in bdisp_g_selection()
866 s->r.top = 0; in bdisp_g_selection()
867 s->r.width = frame->width; in bdisp_g_selection()
868 s->r.height = frame->height; in bdisp_g_selection()
871 dev_err(ctx->bdisp_dev->dev, "Invalid target\n"); in bdisp_g_selection()
872 return -EINVAL; in bdisp_g_selection()
877 switch (s->target) { in bdisp_g_selection()
881 s->r = frame->crop; in bdisp_g_selection()
886 s->r.left = 0; in bdisp_g_selection()
887 s->r.top = 0; in bdisp_g_selection()
888 s->r.width = frame->width; in bdisp_g_selection()
889 s->r.height = frame->height; in bdisp_g_selection()
892 dev_err(ctx->bdisp_dev->dev, "Invalid target\n"); in bdisp_g_selection()
893 return -EINVAL; in bdisp_g_selection()
898 dev_err(ctx->bdisp_dev->dev, "Invalid type\n"); in bdisp_g_selection()
899 return -EINVAL; in bdisp_g_selection()
909 if (a->left < b->left || a->top < b->top) in is_rect_enclosed()
912 if (a->left + a->width > b->left + b->width) in is_rect_enclosed()
915 if (a->top + a->height > b->top + b->height) in is_rect_enclosed()
929 if ((s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) && in bdisp_s_selection()
930 (s->target == V4L2_SEL_TGT_CROP)) in bdisp_s_selection()
933 if ((s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) && in bdisp_s_selection()
934 (s->target == V4L2_SEL_TGT_COMPOSE)) in bdisp_s_selection()
938 dev_err(ctx->bdisp_dev->dev, "Invalid type / target\n"); in bdisp_s_selection()
939 return -EINVAL; in bdisp_s_selection()
942 frame = ctx_get_frame(ctx, s->type); in bdisp_s_selection()
944 dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); in bdisp_s_selection()
948 in = &s->r; in bdisp_s_selection()
952 out.left = ALIGN(in->left, frame->fmt->w_align); in bdisp_s_selection()
953 out.top = ALIGN(in->top, frame->fmt->h_align); in bdisp_s_selection()
955 if ((out.left < 0) || (out.left >= frame->width) || in bdisp_s_selection()
956 (out.top < 0) || (out.top >= frame->height)) { in bdisp_s_selection()
957 dev_err(ctx->bdisp_dev->dev, in bdisp_s_selection()
959 out.width, out.height, out.left, out.top, in bdisp_s_selection()
960 frame->width, frame->height); in bdisp_s_selection()
961 return -EINVAL; in bdisp_s_selection()
965 out.width = ALIGN(in->width, frame->fmt->w_align); in bdisp_s_selection()
966 out.height = ALIGN(in->height, frame->fmt->w_align); in bdisp_s_selection()
968 if (((out.left + out.width) > frame->width) || in bdisp_s_selection()
969 ((out.top + out.height) > frame->height)) { in bdisp_s_selection()
970 dev_err(ctx->bdisp_dev->dev, in bdisp_s_selection()
972 out.width, out.height, out.left, out.top, in bdisp_s_selection()
973 frame->width, frame->height); in bdisp_s_selection()
974 return -EINVAL; in bdisp_s_selection()
978 if (s->flags & V4L2_SEL_FLAG_LE && !is_rect_enclosed(&out, in)) in bdisp_s_selection()
979 return -ERANGE; in bdisp_s_selection()
981 if (s->flags & V4L2_SEL_FLAG_GE && !is_rect_enclosed(in, &out)) in bdisp_s_selection()
982 return -ERANGE; in bdisp_s_selection()
984 if ((out.left != in->left) || (out.top != in->top) || in bdisp_s_selection()
985 (out.width != in->width) || (out.height != in->height)) { in bdisp_s_selection()
986 dev_dbg(ctx->bdisp_dev->dev, in bdisp_s_selection()
987 "%s crop updated: %dx%d@(%d,%d) -> %dx%d@(%d,%d)\n", in bdisp_s_selection()
988 __func__, in->width, in->height, in->left, in->top, in bdisp_s_selection()
989 out.width, out.height, out.left, out.top); in bdisp_s_selection()
993 frame->crop = out; in bdisp_s_selection()
1006 dev_err(ctx->bdisp_dev->dev, "src not defined\n"); in bdisp_streamon()
1007 return -EINVAL; in bdisp_streamon()
1012 dev_err(ctx->bdisp_dev->dev, "dst not defined\n"); in bdisp_streamon()
1013 return -EINVAL; in bdisp_streamon()
1016 return v4l2_m2m_streamon(file, ctx->fh.m2m_ctx, type); in bdisp_streamon()
1048 return -ENODEV; in bdisp_register_device()
1050 bdisp->vdev.fops = &bdisp_fops; in bdisp_register_device()
1051 bdisp->vdev.ioctl_ops = &bdisp_ioctl_ops; in bdisp_register_device()
1052 bdisp->vdev.release = video_device_release_empty; in bdisp_register_device()
1053 bdisp->vdev.lock = &bdisp->lock; in bdisp_register_device()
1054 bdisp->vdev.vfl_dir = VFL_DIR_M2M; in bdisp_register_device()
1055 bdisp->vdev.v4l2_dev = &bdisp->v4l2_dev; in bdisp_register_device()
1056 bdisp->vdev.device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M; in bdisp_register_device()
1057 snprintf(bdisp->vdev.name, sizeof(bdisp->vdev.name), "%s.%d", in bdisp_register_device()
1058 BDISP_NAME, bdisp->id); in bdisp_register_device()
1060 video_set_drvdata(&bdisp->vdev, bdisp); in bdisp_register_device()
1062 bdisp->m2m.vdev = &bdisp->vdev; in bdisp_register_device()
1063 bdisp->m2m.m2m_dev = v4l2_m2m_init(&bdisp_m2m_ops); in bdisp_register_device()
1064 if (IS_ERR(bdisp->m2m.m2m_dev)) { in bdisp_register_device()
1065 dev_err(bdisp->dev, "failed to initialize v4l2-m2m device\n"); in bdisp_register_device()
1066 return PTR_ERR(bdisp->m2m.m2m_dev); in bdisp_register_device()
1069 ret = video_register_device(&bdisp->vdev, VFL_TYPE_VIDEO, -1); in bdisp_register_device()
1071 dev_err(bdisp->dev, in bdisp_register_device()
1073 v4l2_m2m_release(bdisp->m2m.m2m_dev); in bdisp_register_device()
1085 if (bdisp->m2m.m2m_dev) in bdisp_unregister_device()
1086 v4l2_m2m_release(bdisp->m2m.m2m_dev); in bdisp_unregister_device()
1088 video_unregister_device(bdisp->m2m.vdev); in bdisp_unregister_device()
1096 spin_lock(&bdisp->slock); in bdisp_irq_thread()
1100 cancel_delayed_work(&bdisp->timeout_work); in bdisp_irq_thread()
1102 if (!test_and_clear_bit(ST_M2M_RUNNING, &bdisp->state)) in bdisp_irq_thread()
1105 if (test_and_clear_bit(ST_M2M_SUSPENDING, &bdisp->state)) { in bdisp_irq_thread()
1106 set_bit(ST_M2M_SUSPENDED, &bdisp->state); in bdisp_irq_thread()
1107 wake_up(&bdisp->irq_queue); in bdisp_irq_thread()
1111 ctx = v4l2_m2m_get_curr_priv(bdisp->m2m.m2m_dev); in bdisp_irq_thread()
1112 if (!ctx || !ctx->fh.m2m_ctx) in bdisp_irq_thread()
1115 spin_unlock(&bdisp->slock); in bdisp_irq_thread()
1121 wake_up(&bdisp->irq_queue); in bdisp_irq_thread()
1127 spin_unlock(&bdisp->slock); in bdisp_irq_thread()
1147 ctx = v4l2_m2m_get_curr_priv(bdisp->m2m.m2m_dev); in bdisp_irq_timeout()
1149 dev_err(ctx->bdisp_dev->dev, "Device work timeout\n"); in bdisp_irq_timeout()
1151 spin_lock(&bdisp->slock); in bdisp_irq_timeout()
1152 clear_bit(ST_M2M_RUNNING, &bdisp->state); in bdisp_irq_timeout()
1153 spin_unlock(&bdisp->slock); in bdisp_irq_timeout()
1165 spin_lock_irqsave(&bdisp->slock, flags); in bdisp_m2m_suspend()
1166 if (!test_bit(ST_M2M_RUNNING, &bdisp->state)) { in bdisp_m2m_suspend()
1167 spin_unlock_irqrestore(&bdisp->slock, flags); in bdisp_m2m_suspend()
1170 clear_bit(ST_M2M_SUSPENDED, &bdisp->state); in bdisp_m2m_suspend()
1171 set_bit(ST_M2M_SUSPENDING, &bdisp->state); in bdisp_m2m_suspend()
1172 spin_unlock_irqrestore(&bdisp->slock, flags); in bdisp_m2m_suspend()
1174 timeout = wait_event_timeout(bdisp->irq_queue, in bdisp_m2m_suspend()
1175 test_bit(ST_M2M_SUSPENDED, &bdisp->state), in bdisp_m2m_suspend()
1178 clear_bit(ST_M2M_SUSPENDING, &bdisp->state); in bdisp_m2m_suspend()
1181 dev_err(bdisp->dev, "%s IRQ timeout\n", __func__); in bdisp_m2m_suspend()
1182 return -EAGAIN; in bdisp_m2m_suspend()
1193 spin_lock_irqsave(&bdisp->slock, flags); in bdisp_m2m_resume()
1194 ctx = bdisp->m2m.ctx; in bdisp_m2m_resume()
1195 bdisp->m2m.ctx = NULL; in bdisp_m2m_resume()
1196 spin_unlock_irqrestore(&bdisp->slock, flags); in bdisp_m2m_resume()
1198 if (test_and_clear_bit(ST_M2M_SUSPENDED, &bdisp->state)) in bdisp_m2m_resume()
1207 int ret = clk_enable(bdisp->clock); in bdisp_runtime_resume()
1221 clk_disable(bdisp->clock); in bdisp_runtime_suspend()
1232 spin_lock_irqsave(&bdisp->slock, flags); in bdisp_resume()
1233 opened = test_bit(ST_M2M_OPEN, &bdisp->state); in bdisp_resume()
1234 spin_unlock_irqrestore(&bdisp->slock, flags); in bdisp_resume()
1266 bdisp_hw_free_filters(bdisp->dev); in bdisp_remove()
1268 pm_runtime_disable(&pdev->dev); in bdisp_remove()
1272 v4l2_device_unregister(&bdisp->v4l2_dev); in bdisp_remove()
1274 if (!IS_ERR(bdisp->clock)) in bdisp_remove()
1275 clk_unprepare(bdisp->clock); in bdisp_remove()
1277 destroy_workqueue(bdisp->work_queue); in bdisp_remove()
1279 dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name); in bdisp_remove()
1285 struct device *dev = &pdev->dev; in bdisp_probe()
1292 return -ENOMEM; in bdisp_probe()
1298 bdisp->pdev = pdev; in bdisp_probe()
1299 bdisp->dev = dev; in bdisp_probe()
1302 if (dev->of_node) in bdisp_probe()
1303 bdisp->id = of_alias_get_id(pdev->dev.of_node, BDISP_NAME); in bdisp_probe()
1305 bdisp->id = pdev->id; in bdisp_probe()
1307 init_waitqueue_head(&bdisp->irq_queue); in bdisp_probe()
1308 INIT_DELAYED_WORK(&bdisp->timeout_work, bdisp_irq_timeout); in bdisp_probe()
1309 bdisp->work_queue = create_workqueue(BDISP_NAME); in bdisp_probe()
1310 if (!bdisp->work_queue) in bdisp_probe()
1311 return -ENOMEM; in bdisp_probe()
1313 spin_lock_init(&bdisp->slock); in bdisp_probe()
1314 mutex_init(&bdisp->lock); in bdisp_probe()
1317 bdisp->regs = devm_platform_ioremap_resource(pdev, 0); in bdisp_probe()
1318 if (IS_ERR(bdisp->regs)) { in bdisp_probe()
1319 ret = PTR_ERR(bdisp->regs); in bdisp_probe()
1323 bdisp->clock = devm_clk_get(dev, BDISP_NAME); in bdisp_probe()
1324 if (IS_ERR(bdisp->clock)) { in bdisp_probe()
1326 ret = PTR_ERR(bdisp->clock); in bdisp_probe()
1330 ret = clk_prepare(bdisp->clock); in bdisp_probe()
1333 bdisp->clock = ERR_PTR(-EINVAL); in bdisp_probe()
1343 pdev->name, bdisp); in bdisp_probe()
1350 ret = v4l2_device_register(dev, &bdisp->v4l2_dev); in bdisp_probe()
1368 if (bdisp_hw_alloc_filters(bdisp->dev)) { in bdisp_probe()
1369 dev_err(bdisp->dev, "no memory for filters\n"); in bdisp_probe()
1370 ret = -ENOMEM; in bdisp_probe()
1382 bdisp->id, bdisp->vdev.num); in bdisp_probe()
1389 bdisp_hw_free_filters(bdisp->dev); in bdisp_probe()
1395 v4l2_device_unregister(&bdisp->v4l2_dev); in bdisp_probe()
1397 clk_unprepare(bdisp->clock); in bdisp_probe()
1399 destroy_workqueue(bdisp->work_queue); in bdisp_probe()
1405 .compatible = "st,stih407-bdisp",