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()
545 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; in queue_init()
546 src_vq->io_modes = VB2_MMAP | VB2_DMABUF; in queue_init()
547 src_vq->drv_priv = ctx; in queue_init()
548 src_vq->ops = &bdisp_qops; in queue_init()
549 src_vq->mem_ops = &vb2_dma_contig_memops; in queue_init()
550 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); in queue_init()
551 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in queue_init()
552 src_vq->lock = &ctx->bdisp_dev->lock; in queue_init()
553 src_vq->dev = ctx->bdisp_dev->v4l2_dev.dev; in queue_init()
560 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in queue_init()
561 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; in queue_init()
562 dst_vq->drv_priv = ctx; in queue_init()
563 dst_vq->ops = &bdisp_qops; in queue_init()
564 dst_vq->mem_ops = &vb2_dma_contig_memops; in queue_init()
565 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); in queue_init()
566 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; in queue_init()
567 dst_vq->lock = &ctx->bdisp_dev->lock; in queue_init()
568 dst_vq->dev = ctx->bdisp_dev->v4l2_dev.dev; in queue_init()
579 if (mutex_lock_interruptible(&bdisp->lock)) in bdisp_open()
580 return -ERESTARTSYS; in bdisp_open()
585 ret = -ENOMEM; in bdisp_open()
588 ctx->bdisp_dev = bdisp; in bdisp_open()
591 dev_err(bdisp->dev, "no memory for nodes\n"); in bdisp_open()
592 ret = -ENOMEM; in bdisp_open()
596 v4l2_fh_init(&ctx->fh, bdisp->m2m.vdev); in bdisp_open()
600 dev_err(bdisp->dev, "Failed to create control\n"); in bdisp_open()
605 ctx->fh.ctrl_handler = &ctx->ctrl_handler; in bdisp_open()
606 file->private_data = &ctx->fh; in bdisp_open()
607 v4l2_fh_add(&ctx->fh); in bdisp_open()
610 ctx->src = bdisp_dflt_fmt; in bdisp_open()
611 ctx->dst = bdisp_dflt_fmt; in bdisp_open()
614 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(bdisp->m2m.m2m_dev, ctx, in bdisp_open()
616 if (IS_ERR(ctx->fh.m2m_ctx)) { in bdisp_open()
617 dev_err(bdisp->dev, "Failed to initialize m2m context\n"); in bdisp_open()
618 ret = PTR_ERR(ctx->fh.m2m_ctx); in bdisp_open()
622 bdisp->m2m.refcnt++; in bdisp_open()
623 set_bit(ST_M2M_OPEN, &bdisp->state); in bdisp_open()
625 dev_dbg(bdisp->dev, "driver opened, ctx = 0x%p\n", ctx); in bdisp_open()
627 mutex_unlock(&bdisp->lock); in bdisp_open()
633 v4l2_fh_del(&ctx->fh); in bdisp_open()
635 v4l2_fh_exit(&ctx->fh); in bdisp_open()
640 mutex_unlock(&bdisp->lock); in bdisp_open()
647 struct bdisp_ctx *ctx = fh_to_ctx(file->private_data); in bdisp_release()
648 struct bdisp_dev *bdisp = ctx->bdisp_dev; in bdisp_release()
650 dev_dbg(bdisp->dev, "%s\n", __func__); in bdisp_release()
652 mutex_lock(&bdisp->lock); in bdisp_release()
654 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); in bdisp_release()
658 v4l2_fh_del(&ctx->fh); in bdisp_release()
659 v4l2_fh_exit(&ctx->fh); in bdisp_release()
661 if (--bdisp->m2m.refcnt <= 0) in bdisp_release()
662 clear_bit(ST_M2M_OPEN, &bdisp->state); in bdisp_release()
668 mutex_unlock(&bdisp->lock); in bdisp_release()
686 struct bdisp_dev *bdisp = ctx->bdisp_dev; in bdisp_querycap()
688 strscpy(cap->driver, bdisp->pdev->name, sizeof(cap->driver)); in bdisp_querycap()
689 strscpy(cap->card, bdisp->pdev->name, sizeof(cap->card)); in bdisp_querycap()
690 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s%d", in bdisp_querycap()
691 BDISP_NAME, bdisp->id); in bdisp_querycap()
700 if (f->index >= ARRAY_SIZE(bdisp_formats)) in bdisp_enum_fmt()
701 return -EINVAL; in bdisp_enum_fmt()
703 fmt = &bdisp_formats[f->index]; in bdisp_enum_fmt()
705 if ((fmt->pixelformat == V4L2_PIX_FMT_YUV420) && in bdisp_enum_fmt()
706 (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)) { in bdisp_enum_fmt()
707 dev_dbg(ctx->bdisp_dev->dev, "No YU12 on capture\n"); in bdisp_enum_fmt()
708 return -EINVAL; in bdisp_enum_fmt()
710 f->pixelformat = fmt->pixelformat; in bdisp_enum_fmt()
719 struct bdisp_frame *frame = ctx_get_frame(ctx, f->type); in bdisp_g_fmt()
722 dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); in bdisp_g_fmt()
726 pix = &f->fmt.pix; in bdisp_g_fmt()
727 pix->width = frame->width; in bdisp_g_fmt()
728 pix->height = frame->height; in bdisp_g_fmt()
729 pix->pixelformat = frame->fmt->pixelformat; in bdisp_g_fmt()
730 pix->field = frame->field; in bdisp_g_fmt()
731 pix->bytesperline = frame->bytesperline; in bdisp_g_fmt()
732 pix->sizeimage = frame->sizeimage; in bdisp_g_fmt()
733 pix->colorspace = (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? in bdisp_g_fmt()
734 frame->colorspace : bdisp_dflt_fmt.colorspace; in bdisp_g_fmt()
742 struct v4l2_pix_format *pix = &f->fmt.pix; in bdisp_try_fmt()
746 format = bdisp_find_fmt(pix->pixelformat); in bdisp_try_fmt()
748 dev_dbg(ctx->bdisp_dev->dev, "Unknown format 0x%x\n", in bdisp_try_fmt()
749 pix->pixelformat); in bdisp_try_fmt()
750 return -EINVAL; in bdisp_try_fmt()
754 if ((format->pixelformat == V4L2_PIX_FMT_YUV420) && in bdisp_try_fmt()
755 (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)) { in bdisp_try_fmt()
756 dev_dbg(ctx->bdisp_dev->dev, "No YU12 on capture\n"); in bdisp_try_fmt()
757 return -EINVAL; in bdisp_try_fmt()
761 if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) || in bdisp_try_fmt()
762 (pix->field != V4L2_FIELD_INTERLACED)) in bdisp_try_fmt()
763 pix->field = V4L2_FIELD_NONE; in bdisp_try_fmt()
766 in_w = pix->width; in bdisp_try_fmt()
767 in_h = pix->height; in bdisp_try_fmt()
768 v4l_bound_align_image(&pix->width, in bdisp_try_fmt()
770 ffs(format->w_align) - 1, in bdisp_try_fmt()
771 &pix->height, in bdisp_try_fmt()
773 ffs(format->h_align) - 1, in bdisp_try_fmt()
775 if ((pix->width != in_w) || (pix->height != in_h)) in bdisp_try_fmt()
776 dev_dbg(ctx->bdisp_dev->dev, in bdisp_try_fmt()
777 "%s size updated: %dx%d -> %dx%d\n", __func__, in bdisp_try_fmt()
778 in_w, in_h, pix->width, pix->height); in bdisp_try_fmt()
780 pix->bytesperline = (pix->width * format->bpp_plane0) / 8; in bdisp_try_fmt()
781 pix->sizeimage = (pix->width * pix->height * format->bpp) / 8; in bdisp_try_fmt()
783 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) in bdisp_try_fmt()
784 pix->colorspace = bdisp_dflt_fmt.colorspace; in bdisp_try_fmt()
800 dev_err(ctx->bdisp_dev->dev, "Cannot set format\n"); in bdisp_s_fmt()
804 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); in bdisp_s_fmt()
806 dev_err(ctx->bdisp_dev->dev, "queue (%d) busy\n", f->type); in bdisp_s_fmt()
807 return -EBUSY; in bdisp_s_fmt()
810 frame = (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? in bdisp_s_fmt()
811 &ctx->src : &ctx->dst; in bdisp_s_fmt()
812 pix = &f->fmt.pix; in bdisp_s_fmt()
813 frame->fmt = bdisp_find_fmt(pix->pixelformat); in bdisp_s_fmt()
814 if (!frame->fmt) { in bdisp_s_fmt()
815 dev_err(ctx->bdisp_dev->dev, "Unknown format 0x%x\n", in bdisp_s_fmt()
816 pix->pixelformat); in bdisp_s_fmt()
817 return -EINVAL; in bdisp_s_fmt()
820 frame->width = pix->width; in bdisp_s_fmt()
821 frame->height = pix->height; in bdisp_s_fmt()
822 frame->bytesperline = pix->bytesperline; in bdisp_s_fmt()
823 frame->sizeimage = pix->sizeimage; in bdisp_s_fmt()
824 frame->field = pix->field; in bdisp_s_fmt()
825 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) in bdisp_s_fmt()
826 frame->colorspace = pix->colorspace; in bdisp_s_fmt()
828 frame->crop.width = frame->width; in bdisp_s_fmt()
829 frame->crop.height = frame->height; in bdisp_s_fmt()
830 frame->crop.left = 0; in bdisp_s_fmt()
831 frame->crop.top = 0; in bdisp_s_fmt()
834 state |= (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ? in bdisp_s_fmt()
847 frame = ctx_get_frame(ctx, s->type); in bdisp_g_selection()
849 dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); in bdisp_g_selection()
853 switch (s->type) { in bdisp_g_selection()
855 switch (s->target) { in bdisp_g_selection()
858 s->r = frame->crop; in bdisp_g_selection()
863 s->r.left = 0; in bdisp_g_selection()
864 s->r.top = 0; in bdisp_g_selection()
865 s->r.width = frame->width; in bdisp_g_selection()
866 s->r.height = frame->height; in bdisp_g_selection()
869 dev_err(ctx->bdisp_dev->dev, "Invalid target\n"); in bdisp_g_selection()
870 return -EINVAL; in bdisp_g_selection()
875 switch (s->target) { in bdisp_g_selection()
879 s->r = frame->crop; in bdisp_g_selection()
884 s->r.left = 0; in bdisp_g_selection()
885 s->r.top = 0; in bdisp_g_selection()
886 s->r.width = frame->width; in bdisp_g_selection()
887 s->r.height = frame->height; in bdisp_g_selection()
890 dev_err(ctx->bdisp_dev->dev, "Invalid target\n"); in bdisp_g_selection()
891 return -EINVAL; in bdisp_g_selection()
896 dev_err(ctx->bdisp_dev->dev, "Invalid type\n"); in bdisp_g_selection()
897 return -EINVAL; in bdisp_g_selection()
907 if (a->left < b->left || a->top < b->top) in is_rect_enclosed()
910 if (a->left + a->width > b->left + b->width) in is_rect_enclosed()
913 if (a->top + a->height > b->top + b->height) in is_rect_enclosed()
927 if ((s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) && in bdisp_s_selection()
928 (s->target == V4L2_SEL_TGT_CROP)) in bdisp_s_selection()
931 if ((s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) && in bdisp_s_selection()
932 (s->target == V4L2_SEL_TGT_COMPOSE)) in bdisp_s_selection()
936 dev_err(ctx->bdisp_dev->dev, "Invalid type / target\n"); in bdisp_s_selection()
937 return -EINVAL; in bdisp_s_selection()
940 frame = ctx_get_frame(ctx, s->type); in bdisp_s_selection()
942 dev_err(ctx->bdisp_dev->dev, "Invalid frame (%p)\n", frame); in bdisp_s_selection()
946 in = &s->r; in bdisp_s_selection()
950 out.left = ALIGN(in->left, frame->fmt->w_align); in bdisp_s_selection()
951 out.top = ALIGN(in->top, frame->fmt->h_align); in bdisp_s_selection()
953 if ((out.left < 0) || (out.left >= frame->width) || in bdisp_s_selection()
954 (out.top < 0) || (out.top >= frame->height)) { in bdisp_s_selection()
955 dev_err(ctx->bdisp_dev->dev, in bdisp_s_selection()
957 out.width, out.height, out.left, out.top, in bdisp_s_selection()
958 frame->width, frame->height); in bdisp_s_selection()
959 return -EINVAL; in bdisp_s_selection()
963 out.width = ALIGN(in->width, frame->fmt->w_align); in bdisp_s_selection()
964 out.height = ALIGN(in->height, frame->fmt->w_align); in bdisp_s_selection()
966 if (((out.left + out.width) > frame->width) || in bdisp_s_selection()
967 ((out.top + out.height) > frame->height)) { in bdisp_s_selection()
968 dev_err(ctx->bdisp_dev->dev, in bdisp_s_selection()
970 out.width, out.height, out.left, out.top, in bdisp_s_selection()
971 frame->width, frame->height); in bdisp_s_selection()
972 return -EINVAL; in bdisp_s_selection()
976 if (s->flags & V4L2_SEL_FLAG_LE && !is_rect_enclosed(&out, in)) in bdisp_s_selection()
977 return -ERANGE; in bdisp_s_selection()
979 if (s->flags & V4L2_SEL_FLAG_GE && !is_rect_enclosed(in, &out)) in bdisp_s_selection()
980 return -ERANGE; in bdisp_s_selection()
982 if ((out.left != in->left) || (out.top != in->top) || in bdisp_s_selection()
983 (out.width != in->width) || (out.height != in->height)) { in bdisp_s_selection()
984 dev_dbg(ctx->bdisp_dev->dev, in bdisp_s_selection()
985 "%s crop updated: %dx%d@(%d,%d) -> %dx%d@(%d,%d)\n", in bdisp_s_selection()
986 __func__, in->width, in->height, in->left, in->top, in bdisp_s_selection()
987 out.width, out.height, out.left, out.top); in bdisp_s_selection()
991 frame->crop = out; in bdisp_s_selection()
1004 dev_err(ctx->bdisp_dev->dev, "src not defined\n"); in bdisp_streamon()
1005 return -EINVAL; in bdisp_streamon()
1010 dev_err(ctx->bdisp_dev->dev, "dst not defined\n"); in bdisp_streamon()
1011 return -EINVAL; in bdisp_streamon()
1014 return v4l2_m2m_streamon(file, ctx->fh.m2m_ctx, type); in bdisp_streamon()
1046 return -ENODEV; in bdisp_register_device()
1048 bdisp->vdev.fops = &bdisp_fops; in bdisp_register_device()
1049 bdisp->vdev.ioctl_ops = &bdisp_ioctl_ops; in bdisp_register_device()
1050 bdisp->vdev.release = video_device_release_empty; in bdisp_register_device()
1051 bdisp->vdev.lock = &bdisp->lock; in bdisp_register_device()
1052 bdisp->vdev.vfl_dir = VFL_DIR_M2M; in bdisp_register_device()
1053 bdisp->vdev.v4l2_dev = &bdisp->v4l2_dev; in bdisp_register_device()
1054 bdisp->vdev.device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M; in bdisp_register_device()
1055 snprintf(bdisp->vdev.name, sizeof(bdisp->vdev.name), "%s.%d", in bdisp_register_device()
1056 BDISP_NAME, bdisp->id); in bdisp_register_device()
1058 video_set_drvdata(&bdisp->vdev, bdisp); in bdisp_register_device()
1060 bdisp->m2m.vdev = &bdisp->vdev; in bdisp_register_device()
1061 bdisp->m2m.m2m_dev = v4l2_m2m_init(&bdisp_m2m_ops); in bdisp_register_device()
1062 if (IS_ERR(bdisp->m2m.m2m_dev)) { in bdisp_register_device()
1063 dev_err(bdisp->dev, "failed to initialize v4l2-m2m device\n"); in bdisp_register_device()
1064 return PTR_ERR(bdisp->m2m.m2m_dev); in bdisp_register_device()
1067 ret = video_register_device(&bdisp->vdev, VFL_TYPE_VIDEO, -1); in bdisp_register_device()
1069 dev_err(bdisp->dev, in bdisp_register_device()
1071 v4l2_m2m_release(bdisp->m2m.m2m_dev); in bdisp_register_device()
1083 if (bdisp->m2m.m2m_dev) in bdisp_unregister_device()
1084 v4l2_m2m_release(bdisp->m2m.m2m_dev); in bdisp_unregister_device()
1086 video_unregister_device(bdisp->m2m.vdev); in bdisp_unregister_device()
1094 spin_lock(&bdisp->slock); in bdisp_irq_thread()
1098 cancel_delayed_work(&bdisp->timeout_work); in bdisp_irq_thread()
1100 if (!test_and_clear_bit(ST_M2M_RUNNING, &bdisp->state)) in bdisp_irq_thread()
1103 if (test_and_clear_bit(ST_M2M_SUSPENDING, &bdisp->state)) { in bdisp_irq_thread()
1104 set_bit(ST_M2M_SUSPENDED, &bdisp->state); in bdisp_irq_thread()
1105 wake_up(&bdisp->irq_queue); in bdisp_irq_thread()
1109 ctx = v4l2_m2m_get_curr_priv(bdisp->m2m.m2m_dev); in bdisp_irq_thread()
1110 if (!ctx || !ctx->fh.m2m_ctx) in bdisp_irq_thread()
1113 spin_unlock(&bdisp->slock); in bdisp_irq_thread()
1119 wake_up(&bdisp->irq_queue); in bdisp_irq_thread()
1125 spin_unlock(&bdisp->slock); in bdisp_irq_thread()
1145 ctx = v4l2_m2m_get_curr_priv(bdisp->m2m.m2m_dev); in bdisp_irq_timeout()
1147 dev_err(ctx->bdisp_dev->dev, "Device work timeout\n"); in bdisp_irq_timeout()
1149 spin_lock(&bdisp->slock); in bdisp_irq_timeout()
1150 clear_bit(ST_M2M_RUNNING, &bdisp->state); in bdisp_irq_timeout()
1151 spin_unlock(&bdisp->slock); in bdisp_irq_timeout()
1163 spin_lock_irqsave(&bdisp->slock, flags); in bdisp_m2m_suspend()
1164 if (!test_bit(ST_M2M_RUNNING, &bdisp->state)) { in bdisp_m2m_suspend()
1165 spin_unlock_irqrestore(&bdisp->slock, flags); in bdisp_m2m_suspend()
1168 clear_bit(ST_M2M_SUSPENDED, &bdisp->state); in bdisp_m2m_suspend()
1169 set_bit(ST_M2M_SUSPENDING, &bdisp->state); in bdisp_m2m_suspend()
1170 spin_unlock_irqrestore(&bdisp->slock, flags); in bdisp_m2m_suspend()
1172 time_left = wait_event_timeout(bdisp->irq_queue, in bdisp_m2m_suspend()
1173 test_bit(ST_M2M_SUSPENDED, &bdisp->state), in bdisp_m2m_suspend()
1176 clear_bit(ST_M2M_SUSPENDING, &bdisp->state); in bdisp_m2m_suspend()
1179 dev_err(bdisp->dev, "%s IRQ timeout\n", __func__); in bdisp_m2m_suspend()
1180 return -EAGAIN; in bdisp_m2m_suspend()
1191 spin_lock_irqsave(&bdisp->slock, flags); in bdisp_m2m_resume()
1192 ctx = bdisp->m2m.ctx; in bdisp_m2m_resume()
1193 bdisp->m2m.ctx = NULL; in bdisp_m2m_resume()
1194 spin_unlock_irqrestore(&bdisp->slock, flags); in bdisp_m2m_resume()
1196 if (test_and_clear_bit(ST_M2M_SUSPENDED, &bdisp->state)) in bdisp_m2m_resume()
1205 int ret = clk_enable(bdisp->clock); in bdisp_runtime_resume()
1219 clk_disable(bdisp->clock); in bdisp_runtime_suspend()
1230 spin_lock_irqsave(&bdisp->slock, flags); in bdisp_resume()
1231 opened = test_bit(ST_M2M_OPEN, &bdisp->state); in bdisp_resume()
1232 spin_unlock_irqrestore(&bdisp->slock, flags); in bdisp_resume()
1264 bdisp_hw_free_filters(bdisp->dev); in bdisp_remove()
1266 pm_runtime_disable(&pdev->dev); in bdisp_remove()
1270 v4l2_device_unregister(&bdisp->v4l2_dev); in bdisp_remove()
1272 if (!IS_ERR(bdisp->clock)) in bdisp_remove()
1273 clk_unprepare(bdisp->clock); in bdisp_remove()
1275 destroy_workqueue(bdisp->work_queue); in bdisp_remove()
1277 dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name); in bdisp_remove()
1283 struct device *dev = &pdev->dev; in bdisp_probe()
1290 return -ENOMEM; in bdisp_probe()
1296 bdisp->pdev = pdev; in bdisp_probe()
1297 bdisp->dev = dev; in bdisp_probe()
1300 if (dev->of_node) in bdisp_probe()
1301 bdisp->id = of_alias_get_id(pdev->dev.of_node, BDISP_NAME); in bdisp_probe()
1303 bdisp->id = pdev->id; in bdisp_probe()
1305 init_waitqueue_head(&bdisp->irq_queue); in bdisp_probe()
1306 INIT_DELAYED_WORK(&bdisp->timeout_work, bdisp_irq_timeout); in bdisp_probe()
1307 bdisp->work_queue = create_workqueue(BDISP_NAME); in bdisp_probe()
1308 if (!bdisp->work_queue) in bdisp_probe()
1309 return -ENOMEM; in bdisp_probe()
1311 spin_lock_init(&bdisp->slock); in bdisp_probe()
1312 mutex_init(&bdisp->lock); in bdisp_probe()
1315 bdisp->regs = devm_platform_ioremap_resource(pdev, 0); in bdisp_probe()
1316 if (IS_ERR(bdisp->regs)) { in bdisp_probe()
1317 ret = PTR_ERR(bdisp->regs); in bdisp_probe()
1321 bdisp->clock = devm_clk_get(dev, BDISP_NAME); in bdisp_probe()
1322 if (IS_ERR(bdisp->clock)) { in bdisp_probe()
1324 ret = PTR_ERR(bdisp->clock); in bdisp_probe()
1328 ret = clk_prepare(bdisp->clock); in bdisp_probe()
1331 bdisp->clock = ERR_PTR(-EINVAL); in bdisp_probe()
1341 pdev->name, bdisp); in bdisp_probe()
1348 ret = v4l2_device_register(dev, &bdisp->v4l2_dev); in bdisp_probe()
1366 if (bdisp_hw_alloc_filters(bdisp->dev)) { in bdisp_probe()
1367 dev_err(bdisp->dev, "no memory for filters\n"); in bdisp_probe()
1368 ret = -ENOMEM; in bdisp_probe()
1380 bdisp->id, bdisp->vdev.num); in bdisp_probe()
1387 bdisp_hw_free_filters(bdisp->dev); in bdisp_probe()
1393 v4l2_device_unregister(&bdisp->v4l2_dev); in bdisp_probe()
1395 clk_unprepare(bdisp->clock); in bdisp_probe()
1397 destroy_workqueue(bdisp->work_queue); in bdisp_probe()
1403 .compatible = "st,stih407-bdisp",