diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2010-12-01 08:14:59 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-21 19:31:36 -0400 |
commit | 2dab38e2272e9b30540e2782ef7aa8bc45848144 (patch) | |
tree | 002703cb7f650b21953662fc217f0e4368a6579e /drivers/media/video/s5p-fimc | |
parent | 269da4027c9a3466150308a9fe5f2a3a58336cd8 (diff) |
[media] s5p-fimc: Porting to videobuf 2
Porting to videobuf 2 and minor cleanup.
Separate videobuf_queue_ops are are created for m2m
and capture video nodes.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/s5p-fimc')
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-capture.c | 265 | ||||
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.c | 216 | ||||
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.h | 48 |
3 files changed, 362 insertions, 167 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 2f500809f53..24b77b76e68 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c | |||
@@ -27,8 +27,8 @@ | |||
27 | #include <media/v4l2-device.h> | 27 | #include <media/v4l2-device.h> |
28 | #include <media/v4l2-ioctl.h> | 28 | #include <media/v4l2-ioctl.h> |
29 | #include <media/v4l2-mem2mem.h> | 29 | #include <media/v4l2-mem2mem.h> |
30 | #include <media/videobuf-core.h> | 30 | #include <media/videobuf2-core.h> |
31 | #include <media/videobuf-dma-contig.h> | 31 | #include <media/videobuf2-dma-contig.h> |
32 | 32 | ||
33 | #include "fimc-core.h" | 33 | #include "fimc-core.h" |
34 | 34 | ||
@@ -141,7 +141,7 @@ static int fimc_isp_subdev_init(struct fimc_dev *fimc, int index) | |||
141 | * Locking: The caller holds fimc->slock spinlock. | 141 | * Locking: The caller holds fimc->slock spinlock. |
142 | */ | 142 | */ |
143 | int fimc_vid_cap_buf_queue(struct fimc_dev *fimc, | 143 | int fimc_vid_cap_buf_queue(struct fimc_dev *fimc, |
144 | struct fimc_vid_buffer *fimc_vb) | 144 | struct fimc_vid_buffer *fimc_vb) |
145 | { | 145 | { |
146 | struct fimc_vid_cap *cap = &fimc->vid_cap; | 146 | struct fimc_vid_cap *cap = &fimc->vid_cap; |
147 | struct fimc_ctx *ctx = cap->ctx; | 147 | struct fimc_ctx *ctx = cap->ctx; |
@@ -149,7 +149,7 @@ int fimc_vid_cap_buf_queue(struct fimc_dev *fimc, | |||
149 | 149 | ||
150 | BUG_ON(!fimc || !fimc_vb); | 150 | BUG_ON(!fimc || !fimc_vb); |
151 | 151 | ||
152 | ret = fimc_prepare_addr(ctx, fimc_vb, &ctx->d_frame, | 152 | ret = fimc_prepare_addr(ctx, &fimc_vb->vb, &ctx->d_frame, |
153 | &fimc_vb->paddr); | 153 | &fimc_vb->paddr); |
154 | if (ret) | 154 | if (ret) |
155 | return ret; | 155 | return ret; |
@@ -174,7 +174,7 @@ static int fimc_stop_capture(struct fimc_dev *fimc) | |||
174 | { | 174 | { |
175 | unsigned long flags; | 175 | unsigned long flags; |
176 | struct fimc_vid_cap *cap; | 176 | struct fimc_vid_cap *cap; |
177 | int ret; | 177 | struct fimc_vid_buffer *buf; |
178 | 178 | ||
179 | cap = &fimc->vid_cap; | 179 | cap = &fimc->vid_cap; |
180 | 180 | ||
@@ -199,12 +199,224 @@ static int fimc_stop_capture(struct fimc_dev *fimc) | |||
199 | 1 << ST_CAPT_STREAM); | 199 | 1 << ST_CAPT_STREAM); |
200 | 200 | ||
201 | fimc->vid_cap.active_buf_cnt = 0; | 201 | fimc->vid_cap.active_buf_cnt = 0; |
202 | |||
203 | /* Release buffers that were enqueued in the driver by videobuf2. */ | ||
204 | while (!list_empty(&cap->pending_buf_q)) { | ||
205 | buf = pending_queue_pop(cap); | ||
206 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); | ||
207 | } | ||
208 | |||
209 | while (!list_empty(&cap->active_buf_q)) { | ||
210 | buf = active_queue_pop(cap); | ||
211 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); | ||
212 | } | ||
213 | |||
202 | spin_unlock_irqrestore(&fimc->slock, flags); | 214 | spin_unlock_irqrestore(&fimc->slock, flags); |
203 | 215 | ||
204 | dbg("state: 0x%lx", fimc->state); | 216 | dbg("state: 0x%lx", fimc->state); |
205 | return 0; | 217 | return 0; |
206 | } | 218 | } |
207 | 219 | ||
220 | static int start_streaming(struct vb2_queue *q) | ||
221 | { | ||
222 | struct fimc_ctx *ctx = q->drv_priv; | ||
223 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
224 | struct s3c_fimc_isp_info *isp_info; | ||
225 | int ret; | ||
226 | |||
227 | ret = v4l2_subdev_call(fimc->vid_cap.sd, video, s_stream, 1); | ||
228 | if (ret && ret != -ENOIOCTLCMD) | ||
229 | return ret; | ||
230 | |||
231 | ret = fimc_prepare_config(ctx, ctx->state); | ||
232 | if (ret) | ||
233 | return ret; | ||
234 | |||
235 | isp_info = fimc->pdata->isp_info[fimc->vid_cap.input_index]; | ||
236 | fimc_hw_set_camera_type(fimc, isp_info); | ||
237 | fimc_hw_set_camera_source(fimc, isp_info); | ||
238 | fimc_hw_set_camera_offset(fimc, &ctx->s_frame); | ||
239 | |||
240 | if (ctx->state & FIMC_PARAMS) { | ||
241 | ret = fimc_set_scaler_info(ctx); | ||
242 | if (ret) { | ||
243 | err("Scaler setup error"); | ||
244 | return ret; | ||
245 | } | ||
246 | fimc_hw_set_input_path(ctx); | ||
247 | fimc_hw_set_scaler(ctx); | ||
248 | fimc_hw_set_target_format(ctx); | ||
249 | fimc_hw_set_rotation(ctx); | ||
250 | fimc_hw_set_effect(ctx); | ||
251 | } | ||
252 | |||
253 | fimc_hw_set_output_path(ctx); | ||
254 | fimc_hw_set_out_dma(ctx); | ||
255 | |||
256 | INIT_LIST_HEAD(&fimc->vid_cap.pending_buf_q); | ||
257 | INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q); | ||
258 | fimc->vid_cap.active_buf_cnt = 0; | ||
259 | fimc->vid_cap.frame_count = 0; | ||
260 | fimc->vid_cap.buf_index = fimc_hw_get_frame_index(fimc); | ||
261 | |||
262 | set_bit(ST_CAPT_PEND, &fimc->state); | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | static int stop_streaming(struct vb2_queue *q) | ||
268 | { | ||
269 | struct fimc_ctx *ctx = q->drv_priv; | ||
270 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
271 | unsigned long flags; | ||
272 | |||
273 | spin_lock_irqsave(&fimc->slock, flags); | ||
274 | if (!fimc_capture_running(fimc) && !fimc_capture_pending(fimc)) { | ||
275 | spin_unlock_irqrestore(&fimc->slock, flags); | ||
276 | return -EINVAL; | ||
277 | } | ||
278 | spin_unlock_irqrestore(&fimc->slock, flags); | ||
279 | |||
280 | return fimc_stop_capture(fimc); | ||
281 | } | ||
282 | |||
283 | static unsigned int get_plane_size(struct fimc_frame *frame, unsigned int plane) | ||
284 | { | ||
285 | unsigned long size = 0; | ||
286 | |||
287 | if (!frame || plane > frame->fmt->buff_cnt - 1) | ||
288 | return 0; | ||
289 | |||
290 | if (1 == frame->fmt->planes_cnt) { | ||
291 | size = (frame->width * frame->height * frame->fmt->depth) >> 3; | ||
292 | } else if (frame->fmt->planes_cnt <= 3) { | ||
293 | switch (plane) { | ||
294 | case 0: | ||
295 | size = frame->width * frame->height; | ||
296 | break; | ||
297 | case 1: | ||
298 | case 2: | ||
299 | if (S5P_FIMC_YCBCR420 == frame->fmt->color | ||
300 | && 2 != frame->fmt->planes_cnt) | ||
301 | size = (frame->width * frame->height) >> 2; | ||
302 | else /* 422 */ | ||
303 | size = (frame->width * frame->height) >> 1; | ||
304 | break; | ||
305 | } | ||
306 | } else { | ||
307 | size = 0; | ||
308 | } | ||
309 | |||
310 | return size; | ||
311 | } | ||
312 | |||
313 | static int queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, | ||
314 | unsigned int *num_planes, unsigned long sizes[], | ||
315 | void *allocators[]) | ||
316 | { | ||
317 | struct fimc_ctx *ctx = vq->drv_priv; | ||
318 | struct fimc_fmt *fmt = fmt = ctx->d_frame.fmt; | ||
319 | struct fimc_frame *frame; | ||
320 | |||
321 | if (!fmt) | ||
322 | return -EINVAL; | ||
323 | |||
324 | *num_planes = fmt->buff_cnt; | ||
325 | |||
326 | dbg("%s, buffer count=%d, plane count=%d", | ||
327 | __func__, *num_buffers, *num_planes); | ||
328 | |||
329 | frame = ctx_get_frame(ctx, vq->type); | ||
330 | if (IS_ERR(frame)) | ||
331 | return PTR_ERR(frame); | ||
332 | |||
333 | sizes[0] = get_plane_size(frame, 0); | ||
334 | allocators[0] = ctx->fimc_dev->alloc_ctx; | ||
335 | |||
336 | return -EINVAL; | ||
337 | } | ||
338 | |||
339 | static int buffer_init(struct vb2_buffer *vb) | ||
340 | { | ||
341 | /* TODO: */ | ||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | static int buffer_prepare(struct vb2_buffer *vb) | ||
346 | { | ||
347 | struct vb2_queue *vq = vb->vb2_queue; | ||
348 | struct fimc_ctx *ctx = vq->drv_priv; | ||
349 | struct v4l2_device *v4l2_dev = &ctx->fimc_dev->m2m.v4l2_dev; | ||
350 | struct fimc_frame *frame; | ||
351 | unsigned long size; | ||
352 | int i; | ||
353 | |||
354 | frame = ctx_get_frame(ctx, vq->type); | ||
355 | if (IS_ERR(frame)) | ||
356 | return PTR_ERR(frame); | ||
357 | |||
358 | for (i = 0; i < frame->fmt->buff_cnt; i++) { | ||
359 | size = get_plane_size(frame, i); | ||
360 | |||
361 | if (vb2_plane_size(vb, i) < size) { | ||
362 | v4l2_err(v4l2_dev, "User buffer too small (%ld < %ld)\n", | ||
363 | vb2_plane_size(vb, i), size); | ||
364 | return -EINVAL; | ||
365 | } | ||
366 | |||
367 | vb2_set_plane_payload(vb, i, size); | ||
368 | } | ||
369 | |||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | static void buffer_queue(struct vb2_buffer *vb) | ||
374 | { | ||
375 | struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); | ||
376 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
377 | struct fimc_vid_buffer *buf | ||
378 | = container_of(vb, struct fimc_vid_buffer, vb); | ||
379 | struct fimc_vid_cap *vid_cap = &fimc->vid_cap; | ||
380 | unsigned long flags; | ||
381 | |||
382 | spin_lock_irqsave(&fimc->slock, flags); | ||
383 | fimc_vid_cap_buf_queue(fimc, buf); | ||
384 | |||
385 | dbg("active_buf_cnt: %d", fimc->vid_cap.active_buf_cnt); | ||
386 | |||
387 | if (vid_cap->active_buf_cnt >= vid_cap->reqbufs_count || | ||
388 | vid_cap->active_buf_cnt >= FIMC_MAX_OUT_BUFS) { | ||
389 | if (!test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) { | ||
390 | fimc_activate_capture(ctx); | ||
391 | dbg(""); | ||
392 | } | ||
393 | } | ||
394 | spin_unlock_irqrestore(&fimc->slock, flags); | ||
395 | } | ||
396 | |||
397 | static void fimc_lock(struct vb2_queue *vq) | ||
398 | { | ||
399 | struct fimc_ctx *ctx = vb2_get_drv_priv(vq); | ||
400 | mutex_lock(&ctx->fimc_dev->lock); | ||
401 | } | ||
402 | |||
403 | static void fimc_unlock(struct vb2_queue *vq) | ||
404 | { | ||
405 | struct fimc_ctx *ctx = vb2_get_drv_priv(vq); | ||
406 | mutex_unlock(&ctx->fimc_dev->lock); | ||
407 | } | ||
408 | |||
409 | static struct vb2_ops fimc_capture_qops = { | ||
410 | .queue_setup = queue_setup, | ||
411 | .buf_prepare = buffer_prepare, | ||
412 | .buf_queue = buffer_queue, | ||
413 | .buf_init = buffer_init, | ||
414 | .wait_prepare = fimc_unlock, | ||
415 | .wait_finish = fimc_lock, | ||
416 | .start_streaming = start_streaming, | ||
417 | .stop_streaming = stop_streaming, | ||
418 | }; | ||
419 | |||
208 | static int fimc_capture_open(struct file *file) | 420 | static int fimc_capture_open(struct file *file) |
209 | { | 421 | { |
210 | struct fimc_dev *fimc = video_drvdata(file); | 422 | struct fimc_dev *fimc = video_drvdata(file); |
@@ -244,11 +456,10 @@ static int fimc_capture_close(struct file *file) | |||
244 | 456 | ||
245 | if (--fimc->vid_cap.refcnt == 0) { | 457 | if (--fimc->vid_cap.refcnt == 0) { |
246 | fimc_stop_capture(fimc); | 458 | fimc_stop_capture(fimc); |
247 | 459 | vb2_queue_release(&fimc->vid_cap.vbq); | |
248 | videobuf_stop(&fimc->vid_cap.vbq); | ||
249 | videobuf_mmap_free(&fimc->vid_cap.vbq); | ||
250 | 460 | ||
251 | v4l2_err(&fimc->vid_cap.v4l2_dev, "releasing ISP\n"); | 461 | v4l2_err(&fimc->vid_cap.v4l2_dev, "releasing ISP\n"); |
462 | |||
252 | v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0); | 463 | v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0); |
253 | fimc_subdev_unregister(fimc); | 464 | fimc_subdev_unregister(fimc); |
254 | } | 465 | } |
@@ -262,13 +473,12 @@ static unsigned int fimc_capture_poll(struct file *file, | |||
262 | { | 473 | { |
263 | struct fimc_ctx *ctx = file->private_data; | 474 | struct fimc_ctx *ctx = file->private_data; |
264 | struct fimc_dev *fimc = ctx->fimc_dev; | 475 | struct fimc_dev *fimc = ctx->fimc_dev; |
265 | struct fimc_vid_cap *cap = &fimc->vid_cap; | ||
266 | int ret; | 476 | int ret; |
267 | 477 | ||
268 | if (mutex_lock_interruptible(&fimc->lock)) | 478 | if (mutex_lock_interruptible(&fimc->lock)) |
269 | return POLLERR; | 479 | return POLLERR; |
270 | 480 | ||
271 | ret = videobuf_poll_stream(file, &cap->vbq, wait); | 481 | ret = vb2_poll(&fimc->vid_cap.vbq, file, wait); |
272 | mutex_unlock(&fimc->lock); | 482 | mutex_unlock(&fimc->lock); |
273 | 483 | ||
274 | return ret; | 484 | return ret; |
@@ -278,13 +488,12 @@ static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma) | |||
278 | { | 488 | { |
279 | struct fimc_ctx *ctx = file->private_data; | 489 | struct fimc_ctx *ctx = file->private_data; |
280 | struct fimc_dev *fimc = ctx->fimc_dev; | 490 | struct fimc_dev *fimc = ctx->fimc_dev; |
281 | struct fimc_vid_cap *cap = &fimc->vid_cap; | ||
282 | int ret; | 491 | int ret; |
283 | 492 | ||
284 | if (mutex_lock_interruptible(&fimc->lock)) | 493 | if (mutex_lock_interruptible(&fimc->lock)) |
285 | return -ERESTARTSYS; | 494 | return -ERESTARTSYS; |
286 | 495 | ||
287 | ret = videobuf_mmap_mapper(&cap->vbq, vma); | 496 | ret = vb2_mmap(&fimc->vid_cap.vbq, vma); |
288 | mutex_unlock(&fimc->lock); | 497 | mutex_unlock(&fimc->lock); |
289 | 498 | ||
290 | return ret; | 499 | return ret; |
@@ -470,7 +679,7 @@ static int fimc_cap_g_input(struct file *file, void *priv, | |||
470 | } | 679 | } |
471 | 680 | ||
472 | static int fimc_cap_streamon(struct file *file, void *priv, | 681 | static int fimc_cap_streamon(struct file *file, void *priv, |
473 | enum v4l2_buf_type type) | 682 | enum v4l2_buf_type type) |
474 | { | 683 | { |
475 | struct s3c_fimc_isp_info *isp_info; | 684 | struct s3c_fimc_isp_info *isp_info; |
476 | struct fimc_ctx *ctx = priv; | 685 | struct fimc_ctx *ctx = priv; |
@@ -525,7 +734,7 @@ static int fimc_cap_streamon(struct file *file, void *priv, | |||
525 | fimc->vid_cap.buf_index = fimc_hw_get_frame_index(fimc); | 734 | fimc->vid_cap.buf_index = fimc_hw_get_frame_index(fimc); |
526 | 735 | ||
527 | set_bit(ST_CAPT_PEND, &fimc->state); | 736 | set_bit(ST_CAPT_PEND, &fimc->state); |
528 | ret = videobuf_streamon(&fimc->vid_cap.vbq); | 737 | ret = vb2_streamon(&fimc->vid_cap.vbq, type); |
529 | 738 | ||
530 | s_unlock: | 739 | s_unlock: |
531 | mutex_unlock(&fimc->lock); | 740 | mutex_unlock(&fimc->lock); |
@@ -533,7 +742,7 @@ s_unlock: | |||
533 | } | 742 | } |
534 | 743 | ||
535 | static int fimc_cap_streamoff(struct file *file, void *priv, | 744 | static int fimc_cap_streamoff(struct file *file, void *priv, |
536 | enum v4l2_buf_type type) | 745 | enum v4l2_buf_type type) |
537 | { | 746 | { |
538 | struct fimc_ctx *ctx = priv; | 747 | struct fimc_ctx *ctx = priv; |
539 | struct fimc_dev *fimc = ctx->fimc_dev; | 748 | struct fimc_dev *fimc = ctx->fimc_dev; |
@@ -553,7 +762,8 @@ static int fimc_cap_streamoff(struct file *file, void *priv, | |||
553 | return -ERESTARTSYS; | 762 | return -ERESTARTSYS; |
554 | 763 | ||
555 | fimc_stop_capture(fimc); | 764 | fimc_stop_capture(fimc); |
556 | ret = videobuf_streamoff(&cap->vbq); | 765 | ret = vb2_streamoff(&cap->vbq, type); |
766 | |||
557 | mutex_unlock(&fimc->lock); | 767 | mutex_unlock(&fimc->lock); |
558 | return ret; | 768 | return ret; |
559 | } | 769 | } |
@@ -572,7 +782,7 @@ static int fimc_cap_reqbufs(struct file *file, void *priv, | |||
572 | if (mutex_lock_interruptible(&fimc->lock)) | 782 | if (mutex_lock_interruptible(&fimc->lock)) |
573 | return -ERESTARTSYS; | 783 | return -ERESTARTSYS; |
574 | 784 | ||
575 | ret = videobuf_reqbufs(&cap->vbq, reqbufs); | 785 | ret = vb2_reqbufs(&cap->vbq, reqbufs); |
576 | if (!ret) | 786 | if (!ret) |
577 | cap->reqbufs_count = reqbufs->count; | 787 | cap->reqbufs_count = reqbufs->count; |
578 | 788 | ||
@@ -589,7 +799,7 @@ static int fimc_cap_querybuf(struct file *file, void *priv, | |||
589 | if (fimc_capture_active(ctx->fimc_dev)) | 799 | if (fimc_capture_active(ctx->fimc_dev)) |
590 | return -EBUSY; | 800 | return -EBUSY; |
591 | 801 | ||
592 | return videobuf_querybuf(&cap->vbq, buf); | 802 | return vb2_querybuf(&cap->vbq, buf); |
593 | } | 803 | } |
594 | 804 | ||
595 | static int fimc_cap_qbuf(struct file *file, void *priv, | 805 | static int fimc_cap_qbuf(struct file *file, void *priv, |
@@ -603,7 +813,7 @@ static int fimc_cap_qbuf(struct file *file, void *priv, | |||
603 | if (mutex_lock_interruptible(&fimc->lock)) | 813 | if (mutex_lock_interruptible(&fimc->lock)) |
604 | return -ERESTARTSYS; | 814 | return -ERESTARTSYS; |
605 | 815 | ||
606 | ret = videobuf_qbuf(&cap->vbq, buf); | 816 | ret = vb2_qbuf(&cap->vbq, buf); |
607 | 817 | ||
608 | mutex_unlock(&fimc->lock); | 818 | mutex_unlock(&fimc->lock); |
609 | return ret; | 819 | return ret; |
@@ -618,7 +828,7 @@ static int fimc_cap_dqbuf(struct file *file, void *priv, | |||
618 | if (mutex_lock_interruptible(&ctx->fimc_dev->lock)) | 828 | if (mutex_lock_interruptible(&ctx->fimc_dev->lock)) |
619 | return -ERESTARTSYS; | 829 | return -ERESTARTSYS; |
620 | 830 | ||
621 | ret = videobuf_dqbuf(&ctx->fimc_dev->vid_cap.vbq, buf, | 831 | ret = vb2_dqbuf(&ctx->fimc_dev->vid_cap.vbq, buf, |
622 | file->f_flags & O_NONBLOCK); | 832 | file->f_flags & O_NONBLOCK); |
623 | 833 | ||
624 | mutex_unlock(&ctx->fimc_dev->lock); | 834 | mutex_unlock(&ctx->fimc_dev->lock); |
@@ -777,6 +987,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc) | |||
777 | struct fimc_vid_cap *vid_cap; | 987 | struct fimc_vid_cap *vid_cap; |
778 | struct fimc_ctx *ctx; | 988 | struct fimc_ctx *ctx; |
779 | struct v4l2_format f; | 989 | struct v4l2_format f; |
990 | struct vb2_queue *q; | ||
780 | int ret; | 991 | int ret; |
781 | 992 | ||
782 | ctx = kzalloc(sizeof *ctx, GFP_KERNEL); | 993 | ctx = kzalloc(sizeof *ctx, GFP_KERNEL); |
@@ -827,10 +1038,16 @@ int fimc_register_capture_device(struct fimc_dev *fimc) | |||
827 | spin_lock_init(&ctx->slock); | 1038 | spin_lock_init(&ctx->slock); |
828 | vid_cap->ctx = ctx; | 1039 | vid_cap->ctx = ctx; |
829 | 1040 | ||
830 | videobuf_queue_dma_contig_init(&vid_cap->vbq, &fimc_qops, | 1041 | q = &fimc->vid_cap.vbq; |
831 | vid_cap->v4l2_dev.dev, &fimc->irqlock, | 1042 | memset(q, 0, sizeof(*q)); |
832 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | 1043 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
833 | sizeof(struct fimc_vid_buffer), (void *)ctx, NULL); | 1044 | q->io_modes = VB2_MMAP | VB2_USERPTR; |
1045 | q->drv_priv = fimc->vid_cap.ctx; | ||
1046 | q->ops = &fimc_capture_qops; | ||
1047 | q->mem_ops = &vb2_dma_contig_memops; | ||
1048 | q->buf_struct_size = sizeof(struct fimc_vid_buffer); | ||
1049 | |||
1050 | vb2_queue_init(q); | ||
834 | 1051 | ||
835 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); | 1052 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); |
836 | if (ret) { | 1053 | if (ret) { |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 817aa66627f..65d25b374f5 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c | |||
@@ -25,7 +25,8 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <media/v4l2-ioctl.h> | 27 | #include <media/v4l2-ioctl.h> |
28 | #include <media/videobuf-dma-contig.h> | 28 | #include <media/videobuf2-core.h> |
29 | #include <media/videobuf2-dma-contig.h> | ||
29 | 30 | ||
30 | #include "fimc-core.h" | 31 | #include "fimc-core.h" |
31 | 32 | ||
@@ -283,7 +284,7 @@ static void fimc_capture_handler(struct fimc_dev *fimc) | |||
283 | 284 | ||
284 | if (!list_empty(&cap->active_buf_q)) { | 285 | if (!list_empty(&cap->active_buf_q)) { |
285 | v_buf = active_queue_pop(cap); | 286 | v_buf = active_queue_pop(cap); |
286 | fimc_buf_finish(fimc, v_buf); | 287 | vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE); |
287 | } | 288 | } |
288 | 289 | ||
289 | if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) { | 290 | if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) { |
@@ -300,10 +301,6 @@ static void fimc_capture_handler(struct fimc_dev *fimc) | |||
300 | dbg("hw ptr: %d, sw ptr: %d", | 301 | dbg("hw ptr: %d, sw ptr: %d", |
301 | fimc_hw_get_frame_index(fimc), cap->buf_index); | 302 | fimc_hw_get_frame_index(fimc), cap->buf_index); |
302 | 303 | ||
303 | spin_lock(&fimc->irqlock); | ||
304 | v_buf->vb.state = VIDEOBUF_ACTIVE; | ||
305 | spin_unlock(&fimc->irqlock); | ||
306 | |||
307 | /* Move the buffer to the capture active queue */ | 304 | /* Move the buffer to the capture active queue */ |
308 | active_queue_add(cap, v_buf); | 305 | active_queue_add(cap, v_buf); |
309 | 306 | ||
@@ -324,8 +321,6 @@ static void fimc_capture_handler(struct fimc_dev *fimc) | |||
324 | 321 | ||
325 | static irqreturn_t fimc_isr(int irq, void *priv) | 322 | static irqreturn_t fimc_isr(int irq, void *priv) |
326 | { | 323 | { |
327 | struct fimc_vid_buffer *src_buf, *dst_buf; | ||
328 | struct fimc_ctx *ctx; | ||
329 | struct fimc_dev *fimc = priv; | 324 | struct fimc_dev *fimc = priv; |
330 | 325 | ||
331 | BUG_ON(!fimc); | 326 | BUG_ON(!fimc); |
@@ -334,17 +329,17 @@ static irqreturn_t fimc_isr(int irq, void *priv) | |||
334 | spin_lock(&fimc->slock); | 329 | spin_lock(&fimc->slock); |
335 | 330 | ||
336 | if (test_and_clear_bit(ST_M2M_PEND, &fimc->state)) { | 331 | if (test_and_clear_bit(ST_M2M_PEND, &fimc->state)) { |
337 | ctx = v4l2_m2m_get_curr_priv(fimc->m2m.m2m_dev); | 332 | struct vb2_buffer *src_vb, *dst_vb; |
333 | struct fimc_ctx *ctx = v4l2_m2m_get_curr_priv(fimc->m2m.m2m_dev); | ||
334 | |||
338 | if (!ctx || !ctx->m2m_ctx) | 335 | if (!ctx || !ctx->m2m_ctx) |
339 | goto isr_unlock; | 336 | goto isr_unlock; |
340 | src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); | 337 | |
341 | dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); | 338 | src_vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); |
342 | if (src_buf && dst_buf) { | 339 | dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); |
343 | spin_lock(&fimc->irqlock); | 340 | if (src_vb && dst_vb) { |
344 | src_buf->vb.state = dst_buf->vb.state = VIDEOBUF_DONE; | 341 | v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE); |
345 | wake_up(&src_buf->vb.done); | 342 | v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE); |
346 | wake_up(&dst_buf->vb.done); | ||
347 | spin_unlock(&fimc->irqlock); | ||
348 | v4l2_m2m_job_finish(fimc->m2m.m2m_dev, ctx->m2m_ctx); | 343 | v4l2_m2m_job_finish(fimc->m2m.m2m_dev, ctx->m2m_ctx); |
349 | } | 344 | } |
350 | goto isr_unlock; | 345 | goto isr_unlock; |
@@ -365,13 +360,13 @@ isr_unlock: | |||
365 | } | 360 | } |
366 | 361 | ||
367 | /* The color format (planes_cnt, buff_cnt) must be already configured. */ | 362 | /* The color format (planes_cnt, buff_cnt) must be already configured. */ |
368 | int fimc_prepare_addr(struct fimc_ctx *ctx, struct fimc_vid_buffer *buf, | 363 | int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb, |
369 | struct fimc_frame *frame, struct fimc_addr *paddr) | 364 | struct fimc_frame *frame, struct fimc_addr *paddr) |
370 | { | 365 | { |
371 | int ret = 0; | 366 | int ret = 0; |
372 | u32 pix_size; | 367 | u32 pix_size; |
373 | 368 | ||
374 | if (buf == NULL || frame == NULL) | 369 | if (vb == NULL || frame == NULL) |
375 | return -EINVAL; | 370 | return -EINVAL; |
376 | 371 | ||
377 | pix_size = frame->width * frame->height; | 372 | pix_size = frame->width * frame->height; |
@@ -381,7 +376,7 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct fimc_vid_buffer *buf, | |||
381 | frame->size, pix_size); | 376 | frame->size, pix_size); |
382 | 377 | ||
383 | if (frame->fmt->buff_cnt == 1) { | 378 | if (frame->fmt->buff_cnt == 1) { |
384 | paddr->y = videobuf_to_dma_contig(&buf->vb); | 379 | paddr->y = vb2_dma_contig_plane_paddr(vb, 0); |
385 | switch (frame->fmt->planes_cnt) { | 380 | switch (frame->fmt->planes_cnt) { |
386 | case 1: | 381 | case 1: |
387 | paddr->cb = 0; | 382 | paddr->cb = 0; |
@@ -499,7 +494,7 @@ static void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f) | |||
499 | int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) | 494 | int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) |
500 | { | 495 | { |
501 | struct fimc_frame *s_frame, *d_frame; | 496 | struct fimc_frame *s_frame, *d_frame; |
502 | struct fimc_vid_buffer *buf = NULL; | 497 | struct vb2_buffer *vb = NULL; |
503 | int ret = 0; | 498 | int ret = 0; |
504 | 499 | ||
505 | s_frame = &ctx->s_frame; | 500 | s_frame = &ctx->s_frame; |
@@ -522,15 +517,15 @@ int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) | |||
522 | ctx->scaler.enabled = 1; | 517 | ctx->scaler.enabled = 1; |
523 | 518 | ||
524 | if (flags & FIMC_SRC_ADDR) { | 519 | if (flags & FIMC_SRC_ADDR) { |
525 | buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); | 520 | vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx); |
526 | ret = fimc_prepare_addr(ctx, buf, s_frame, &s_frame->paddr); | 521 | ret = fimc_prepare_addr(ctx, vb, s_frame, &s_frame->paddr); |
527 | if (ret) | 522 | if (ret) |
528 | return ret; | 523 | return ret; |
529 | } | 524 | } |
530 | 525 | ||
531 | if (flags & FIMC_DST_ADDR) { | 526 | if (flags & FIMC_DST_ADDR) { |
532 | buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); | 527 | vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); |
533 | ret = fimc_prepare_addr(ctx, buf, d_frame, &d_frame->paddr); | 528 | ret = fimc_prepare_addr(ctx, vb, d_frame, &d_frame->paddr); |
534 | } | 529 | } |
535 | 530 | ||
536 | return ret; | 531 | return ret; |
@@ -587,7 +582,8 @@ static void fimc_dma_run(void *priv) | |||
587 | 582 | ||
588 | fimc_activate_capture(ctx); | 583 | fimc_activate_capture(ctx); |
589 | 584 | ||
590 | ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP); | 585 | ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP | |
586 | FIMC_SRC_FMT | FIMC_DST_FMT); | ||
591 | fimc_hw_activate_input_dma(fimc, true); | 587 | fimc_hw_activate_input_dma(fimc, true); |
592 | 588 | ||
593 | dma_unlock: | 589 | dma_unlock: |
@@ -599,106 +595,72 @@ static void fimc_job_abort(void *priv) | |||
599 | /* Nothing done in job_abort. */ | 595 | /* Nothing done in job_abort. */ |
600 | } | 596 | } |
601 | 597 | ||
602 | static void fimc_buf_release(struct videobuf_queue *vq, | 598 | static int fimc_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, |
603 | struct videobuf_buffer *vb) | 599 | unsigned int *num_planes, unsigned long sizes[], |
600 | void *allocators[]) | ||
604 | { | 601 | { |
605 | videobuf_dma_contig_free(vq, vb); | 602 | struct fimc_ctx *ctx = vb2_get_drv_priv(vq); |
606 | vb->state = VIDEOBUF_NEEDS_INIT; | 603 | struct fimc_frame *fr; |
607 | } | ||
608 | 604 | ||
609 | static int fimc_buf_setup(struct videobuf_queue *vq, unsigned int *count, | 605 | fr = ctx_get_frame(ctx, vq->type); |
610 | unsigned int *size) | 606 | if (IS_ERR(fr)) |
611 | { | 607 | return PTR_ERR(fr); |
612 | struct fimc_ctx *ctx = vq->priv_data; | ||
613 | struct fimc_frame *frame; | ||
614 | 608 | ||
615 | frame = ctx_get_frame(ctx, vq->type); | 609 | *num_planes = 1; |
616 | if (IS_ERR(frame)) | 610 | |
617 | return PTR_ERR(frame); | 611 | sizes[0] = (fr->width * fr->height * fr->fmt->depth) >> 3; |
612 | allocators[0] = ctx->fimc_dev->alloc_ctx; | ||
618 | 613 | ||
619 | *size = (frame->width * frame->height * frame->fmt->depth) >> 3; | ||
620 | if (0 == *count) | ||
621 | *count = 1; | ||
622 | return 0; | 614 | return 0; |
623 | } | 615 | } |
624 | 616 | ||
625 | static int fimc_buf_prepare(struct videobuf_queue *vq, | 617 | static int fimc_buf_prepare(struct vb2_buffer *vb) |
626 | struct videobuf_buffer *vb, enum v4l2_field field) | ||
627 | { | 618 | { |
628 | struct fimc_ctx *ctx = vq->priv_data; | 619 | struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); |
629 | struct v4l2_device *v4l2_dev = &ctx->fimc_dev->m2m.v4l2_dev; | ||
630 | struct fimc_frame *frame; | 620 | struct fimc_frame *frame; |
631 | int ret; | ||
632 | 621 | ||
633 | frame = ctx_get_frame(ctx, vq->type); | 622 | frame = ctx_get_frame(ctx, vb->vb2_queue->type); |
634 | if (IS_ERR(frame)) | 623 | if (IS_ERR(frame)) |
635 | return PTR_ERR(frame); | 624 | return PTR_ERR(frame); |
636 | 625 | ||
637 | if (vb->baddr) { | 626 | if (vb2_plane_size(vb, 0) < frame->size) { |
638 | if (vb->bsize < frame->size) { | 627 | dbg("%s data will not fit into plane (%lu < %lu)\n", |
639 | v4l2_err(v4l2_dev, | 628 | __func__, vb2_plane_size(vb, 0), (long)frame->size); |
640 | "User-provided buffer too small (%d < %d)\n", | ||
641 | vb->bsize, frame->size); | ||
642 | WARN_ON(1); | ||
643 | return -EINVAL; | ||
644 | } | ||
645 | } else if (vb->state != VIDEOBUF_NEEDS_INIT | ||
646 | && vb->bsize < frame->size) { | ||
647 | return -EINVAL; | 629 | return -EINVAL; |
648 | } | 630 | } |
649 | 631 | ||
650 | vb->width = frame->width; | 632 | vb2_set_plane_payload(vb, 0, frame->size); |
651 | vb->height = frame->height; | ||
652 | vb->bytesperline = (frame->width * frame->fmt->depth) >> 3; | ||
653 | vb->size = frame->size; | ||
654 | vb->field = field; | ||
655 | |||
656 | if (VIDEOBUF_NEEDS_INIT == vb->state) { | ||
657 | ret = videobuf_iolock(vq, vb, NULL); | ||
658 | if (ret) { | ||
659 | v4l2_err(v4l2_dev, "Iolock failed\n"); | ||
660 | fimc_buf_release(vq, vb); | ||
661 | return ret; | ||
662 | } | ||
663 | } | ||
664 | vb->state = VIDEOBUF_PREPARED; | ||
665 | |||
666 | return 0; | 633 | return 0; |
667 | } | 634 | } |
668 | 635 | ||
669 | static void fimc_buf_queue(struct videobuf_queue *vq, | 636 | static void fimc_buf_queue(struct vb2_buffer *vb) |
670 | struct videobuf_buffer *vb) | ||
671 | { | 637 | { |
672 | struct fimc_ctx *ctx = vq->priv_data; | 638 | struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); |
673 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
674 | struct fimc_vid_cap *cap = &fimc->vid_cap; | ||
675 | unsigned long flags; | ||
676 | 639 | ||
677 | dbg("ctx: %p, ctx->state: 0x%x", ctx, ctx->state); | 640 | dbg("ctx: %p, ctx->state: 0x%x", ctx, ctx->state); |
678 | 641 | ||
679 | if ((ctx->state & FIMC_CTX_M2M) && ctx->m2m_ctx) { | 642 | if (ctx->m2m_ctx) |
680 | v4l2_m2m_buf_queue(ctx->m2m_ctx, vq, vb); | 643 | v4l2_m2m_buf_queue(ctx->m2m_ctx, vb); |
681 | } else if (ctx->state & FIMC_CTX_CAP) { | 644 | } |
682 | spin_lock_irqsave(&fimc->slock, flags); | ||
683 | fimc_vid_cap_buf_queue(fimc, (struct fimc_vid_buffer *)vb); | ||
684 | 645 | ||
685 | dbg("fimc->cap.active_buf_cnt: %d", | 646 | static void fimc_lock(struct vb2_queue *vq) |
686 | fimc->vid_cap.active_buf_cnt); | 647 | { |
648 | struct fimc_ctx *ctx = vb2_get_drv_priv(vq); | ||
649 | mutex_lock(&ctx->fimc_dev->lock); | ||
650 | } | ||
687 | 651 | ||
688 | if (cap->active_buf_cnt >= cap->reqbufs_count || | 652 | static void fimc_unlock(struct vb2_queue *vq) |
689 | cap->active_buf_cnt >= FIMC_MAX_OUT_BUFS) { | 653 | { |
690 | if (!test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) | 654 | struct fimc_ctx *ctx = vb2_get_drv_priv(vq); |
691 | fimc_activate_capture(ctx); | 655 | mutex_unlock(&ctx->fimc_dev->lock); |
692 | } | ||
693 | spin_unlock_irqrestore(&fimc->slock, flags); | ||
694 | } | ||
695 | } | 656 | } |
696 | 657 | ||
697 | struct videobuf_queue_ops fimc_qops = { | 658 | struct vb2_ops fimc_qops = { |
698 | .buf_setup = fimc_buf_setup, | 659 | .queue_setup = fimc_queue_setup, |
699 | .buf_prepare = fimc_buf_prepare, | 660 | .buf_prepare = fimc_buf_prepare, |
700 | .buf_queue = fimc_buf_queue, | 661 | .buf_queue = fimc_buf_queue, |
701 | .buf_release = fimc_buf_release, | 662 | .wait_prepare = fimc_unlock, |
663 | .wait_finish = fimc_lock, | ||
702 | }; | 664 | }; |
703 | 665 | ||
704 | static int fimc_m2m_querycap(struct file *file, void *priv, | 666 | static int fimc_m2m_querycap(struct file *file, void *priv, |
@@ -867,7 +829,7 @@ static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
867 | struct fimc_ctx *ctx = priv; | 829 | struct fimc_ctx *ctx = priv; |
868 | struct fimc_dev *fimc = ctx->fimc_dev; | 830 | struct fimc_dev *fimc = ctx->fimc_dev; |
869 | struct v4l2_device *v4l2_dev = &fimc->m2m.v4l2_dev; | 831 | struct v4l2_device *v4l2_dev = &fimc->m2m.v4l2_dev; |
870 | struct videobuf_queue *vq; | 832 | struct vb2_queue *vq; |
871 | struct fimc_frame *frame; | 833 | struct fimc_frame *frame; |
872 | struct v4l2_pix_format *pix; | 834 | struct v4l2_pix_format *pix; |
873 | unsigned long flags; | 835 | unsigned long flags; |
@@ -881,9 +843,8 @@ static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
881 | return -ERESTARTSYS; | 843 | return -ERESTARTSYS; |
882 | 844 | ||
883 | vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); | 845 | vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); |
884 | mutex_lock(&vq->vb_lock); | ||
885 | 846 | ||
886 | if (videobuf_queue_is_busy(vq)) { | 847 | if (vb2_is_streaming(vq)) { |
887 | v4l2_err(v4l2_dev, "%s: queue (%d) busy\n", __func__, f->type); | 848 | v4l2_err(v4l2_dev, "%s: queue (%d) busy\n", __func__, f->type); |
888 | ret = -EBUSY; | 849 | ret = -EBUSY; |
889 | goto sf_out; | 850 | goto sf_out; |
@@ -921,7 +882,6 @@ static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
921 | frame->offs_h = 0; | 882 | frame->offs_h = 0; |
922 | frame->offs_v = 0; | 883 | frame->offs_v = 0; |
923 | frame->size = (pix->width * pix->height * frame->fmt->depth) >> 3; | 884 | frame->size = (pix->width * pix->height * frame->fmt->depth) >> 3; |
924 | vq->field = pix->field; | ||
925 | 885 | ||
926 | spin_lock_irqsave(&ctx->slock, flags); | 886 | spin_lock_irqsave(&ctx->slock, flags); |
927 | ctx->state |= FIMC_PARAMS; | 887 | ctx->state |= FIMC_PARAMS; |
@@ -930,7 +890,6 @@ static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
930 | dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height); | 890 | dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height); |
931 | 891 | ||
932 | sf_out: | 892 | sf_out: |
933 | mutex_unlock(&vq->vb_lock); | ||
934 | mutex_unlock(&fimc->lock); | 893 | mutex_unlock(&fimc->lock); |
935 | return ret; | 894 | return ret; |
936 | } | 895 | } |
@@ -968,6 +927,11 @@ static int fimc_m2m_streamon(struct file *file, void *priv, | |||
968 | enum v4l2_buf_type type) | 927 | enum v4l2_buf_type type) |
969 | { | 928 | { |
970 | struct fimc_ctx *ctx = priv; | 929 | struct fimc_ctx *ctx = priv; |
930 | |||
931 | /* The source and target color format need to be set */ | ||
932 | if (~ctx->state & (FIMC_DST_FMT | FIMC_SRC_FMT)) | ||
933 | return -EINVAL; | ||
934 | |||
971 | return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); | 935 | return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); |
972 | } | 936 | } |
973 | 937 | ||
@@ -1301,16 +1265,32 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = { | |||
1301 | 1265 | ||
1302 | }; | 1266 | }; |
1303 | 1267 | ||
1304 | static void queue_init(void *priv, struct videobuf_queue *vq, | 1268 | static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) |
1305 | enum v4l2_buf_type type) | ||
1306 | { | 1269 | { |
1307 | struct fimc_ctx *ctx = priv; | 1270 | struct fimc_ctx *ctx = priv; |
1308 | struct fimc_dev *fimc = ctx->fimc_dev; | 1271 | int ret; |
1272 | |||
1273 | memset(src_vq, 0, sizeof(*src_vq)); | ||
1274 | src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | ||
1275 | src_vq->io_modes = VB2_MMAP | VB2_USERPTR; | ||
1276 | src_vq->drv_priv = ctx; | ||
1277 | src_vq->ops = &fimc_qops; | ||
1278 | src_vq->mem_ops = &vb2_dma_contig_memops; | ||
1279 | src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); | ||
1309 | 1280 | ||
1310 | videobuf_queue_dma_contig_init(vq, &fimc_qops, | 1281 | ret = vb2_queue_init(src_vq); |
1311 | &fimc->pdev->dev, | 1282 | if (ret) |
1312 | &fimc->irqlock, type, V4L2_FIELD_NONE, | 1283 | return ret; |
1313 | sizeof(struct fimc_vid_buffer), priv, NULL); | 1284 | |
1285 | memset(dst_vq, 0, sizeof(*dst_vq)); | ||
1286 | dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | ||
1287 | dst_vq->io_modes = VB2_MMAP | VB2_USERPTR; | ||
1288 | dst_vq->drv_priv = ctx; | ||
1289 | dst_vq->ops = &fimc_qops; | ||
1290 | dst_vq->mem_ops = &vb2_dma_contig_memops; | ||
1291 | dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); | ||
1292 | |||
1293 | return vb2_queue_init(dst_vq); | ||
1314 | } | 1294 | } |
1315 | 1295 | ||
1316 | static int fimc_m2m_open(struct file *file) | 1296 | static int fimc_m2m_open(struct file *file) |
@@ -1355,7 +1335,7 @@ static int fimc_m2m_open(struct file *file) | |||
1355 | ctx->out_path = FIMC_DMA; | 1335 | ctx->out_path = FIMC_DMA; |
1356 | spin_lock_init(&ctx->slock); | 1336 | spin_lock_init(&ctx->slock); |
1357 | 1337 | ||
1358 | ctx->m2m_ctx = v4l2_m2m_ctx_init(ctx, fimc->m2m.m2m_dev, queue_init); | 1338 | ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init); |
1359 | if (IS_ERR(ctx->m2m_ctx)) { | 1339 | if (IS_ERR(ctx->m2m_ctx)) { |
1360 | err = PTR_ERR(ctx->m2m_ctx); | 1340 | err = PTR_ERR(ctx->m2m_ctx); |
1361 | kfree(ctx); | 1341 | kfree(ctx); |
@@ -1415,7 +1395,6 @@ static struct v4l2_m2m_ops m2m_ops = { | |||
1415 | .job_abort = fimc_job_abort, | 1395 | .job_abort = fimc_job_abort, |
1416 | }; | 1396 | }; |
1417 | 1397 | ||
1418 | |||
1419 | static int fimc_register_m2m_device(struct fimc_dev *fimc) | 1398 | static int fimc_register_m2m_device(struct fimc_dev *fimc) |
1420 | { | 1399 | { |
1421 | struct video_device *vfd; | 1400 | struct video_device *vfd; |
@@ -1548,7 +1527,6 @@ static int fimc_probe(struct platform_device *pdev) | |||
1548 | fimc->pdata = pdev->dev.platform_data; | 1527 | fimc->pdata = pdev->dev.platform_data; |
1549 | fimc->state = ST_IDLE; | 1528 | fimc->state = ST_IDLE; |
1550 | 1529 | ||
1551 | spin_lock_init(&fimc->irqlock); | ||
1552 | init_waitqueue_head(&fimc->irq_queue); | 1530 | init_waitqueue_head(&fimc->irq_queue); |
1553 | spin_lock_init(&fimc->slock); | 1531 | spin_lock_init(&fimc->slock); |
1554 | 1532 | ||
@@ -1597,6 +1575,13 @@ static int fimc_probe(struct platform_device *pdev) | |||
1597 | goto err_clk; | 1575 | goto err_clk; |
1598 | } | 1576 | } |
1599 | 1577 | ||
1578 | /* Initialize contiguous memory allocator */ | ||
1579 | fimc->alloc_ctx = vb2_dma_contig_init_ctx(&fimc->pdev->dev); | ||
1580 | if (IS_ERR(fimc->alloc_ctx)) { | ||
1581 | ret = PTR_ERR(fimc->alloc_ctx); | ||
1582 | goto err_irq; | ||
1583 | } | ||
1584 | |||
1600 | ret = fimc_register_m2m_device(fimc); | 1585 | ret = fimc_register_m2m_device(fimc); |
1601 | if (ret) | 1586 | if (ret) |
1602 | goto err_irq; | 1587 | goto err_irq; |
@@ -1656,6 +1641,9 @@ static int __devexit fimc_remove(struct platform_device *pdev) | |||
1656 | fimc_unregister_capture_device(fimc); | 1641 | fimc_unregister_capture_device(fimc); |
1657 | 1642 | ||
1658 | fimc_clk_release(fimc); | 1643 | fimc_clk_release(fimc); |
1644 | |||
1645 | vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx); | ||
1646 | |||
1659 | iounmap(fimc->regs); | 1647 | iounmap(fimc->regs); |
1660 | release_resource(fimc->regs_res); | 1648 | release_resource(fimc->regs_res); |
1661 | kfree(fimc->regs_res); | 1649 | kfree(fimc->regs_res); |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index 4f047d35f8a..590fbf23079 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h | |||
@@ -16,7 +16,8 @@ | |||
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/videodev2.h> | 18 | #include <linux/videodev2.h> |
19 | #include <media/videobuf-core.h> | 19 | #include <linux/io.h> |
20 | #include <media/videobuf2-core.h> | ||
20 | #include <media/v4l2-device.h> | 21 | #include <media/v4l2-device.h> |
21 | #include <media/v4l2-mem2mem.h> | 22 | #include <media/v4l2-mem2mem.h> |
22 | #include <media/v4l2-mediabus.h> | 23 | #include <media/v4l2-mediabus.h> |
@@ -70,13 +71,6 @@ enum fimc_dev_flags { | |||
70 | #define fimc_capture_streaming(dev) \ | 71 | #define fimc_capture_streaming(dev) \ |
71 | test_bit(ST_CAPT_STREAM, &(dev)->state) | 72 | test_bit(ST_CAPT_STREAM, &(dev)->state) |
72 | 73 | ||
73 | #define fimc_buf_finish(dev, vid_buf) do { \ | ||
74 | spin_lock(&(dev)->irqlock); \ | ||
75 | (vid_buf)->vb.state = VIDEOBUF_DONE; \ | ||
76 | spin_unlock(&(dev)->irqlock); \ | ||
77 | wake_up(&(vid_buf)->vb.done); \ | ||
78 | } while (0) | ||
79 | |||
80 | enum fimc_datapath { | 74 | enum fimc_datapath { |
81 | FIMC_CAMERA, | 75 | FIMC_CAMERA, |
82 | FIMC_DMA, | 76 | FIMC_DMA, |
@@ -260,7 +254,8 @@ struct fimc_addr { | |||
260 | * @index: buffer index for the output DMA engine | 254 | * @index: buffer index for the output DMA engine |
261 | */ | 255 | */ |
262 | struct fimc_vid_buffer { | 256 | struct fimc_vid_buffer { |
263 | struct videobuf_buffer vb; | 257 | struct vb2_buffer vb; |
258 | struct list_head list; | ||
264 | struct fimc_addr paddr; | 259 | struct fimc_addr paddr; |
265 | int index; | 260 | int index; |
266 | }; | 261 | }; |
@@ -331,13 +326,14 @@ struct fimc_m2m_device { | |||
331 | */ | 326 | */ |
332 | struct fimc_vid_cap { | 327 | struct fimc_vid_cap { |
333 | struct fimc_ctx *ctx; | 328 | struct fimc_ctx *ctx; |
329 | struct vb2_alloc_ctx *alloc_ctx; | ||
334 | struct video_device *vfd; | 330 | struct video_device *vfd; |
335 | struct v4l2_device v4l2_dev; | 331 | struct v4l2_device v4l2_dev; |
336 | struct v4l2_subdev *sd; | 332 | struct v4l2_subdev *sd;; |
337 | struct v4l2_mbus_framefmt fmt; | 333 | struct v4l2_mbus_framefmt fmt; |
338 | struct list_head pending_buf_q; | 334 | struct list_head pending_buf_q; |
339 | struct list_head active_buf_q; | 335 | struct list_head active_buf_q; |
340 | struct videobuf_queue vbq; | 336 | struct vb2_queue vbq; |
341 | int active_buf_cnt; | 337 | int active_buf_cnt; |
342 | int buf_index; | 338 | int buf_index; |
343 | unsigned int frame_count; | 339 | unsigned int frame_count; |
@@ -417,7 +413,6 @@ struct fimc_ctx; | |||
417 | * @regs: the mapped hardware registers | 413 | * @regs: the mapped hardware registers |
418 | * @regs_res: the resource claimed for IO registers | 414 | * @regs_res: the resource claimed for IO registers |
419 | * @irq: interrupt number of the FIMC subdevice | 415 | * @irq: interrupt number of the FIMC subdevice |
420 | * @irqlock: spinlock protecting videobuffer queue | ||
421 | * @irq_queue: | 416 | * @irq_queue: |
422 | * @m2m: memory-to-memory V4L2 device information | 417 | * @m2m: memory-to-memory V4L2 device information |
423 | * @vid_cap: camera capture device information | 418 | * @vid_cap: camera capture device information |
@@ -434,11 +429,11 @@ struct fimc_dev { | |||
434 | void __iomem *regs; | 429 | void __iomem *regs; |
435 | struct resource *regs_res; | 430 | struct resource *regs_res; |
436 | int irq; | 431 | int irq; |
437 | spinlock_t irqlock; | ||
438 | wait_queue_head_t irq_queue; | 432 | wait_queue_head_t irq_queue; |
439 | struct fimc_m2m_device m2m; | 433 | struct fimc_m2m_device m2m; |
440 | struct fimc_vid_cap vid_cap; | 434 | struct fimc_vid_cap vid_cap; |
441 | unsigned long state; | 435 | unsigned long state; |
436 | struct vb2_alloc_ctx *alloc_ctx; | ||
442 | }; | 437 | }; |
443 | 438 | ||
444 | /** | 439 | /** |
@@ -482,8 +477,6 @@ struct fimc_ctx { | |||
482 | struct v4l2_m2m_ctx *m2m_ctx; | 477 | struct v4l2_m2m_ctx *m2m_ctx; |
483 | }; | 478 | }; |
484 | 479 | ||
485 | extern struct videobuf_queue_ops fimc_qops; | ||
486 | |||
487 | static inline int tiled_fmt(struct fimc_fmt *fmt) | 480 | static inline int tiled_fmt(struct fimc_fmt *fmt) |
488 | { | 481 | { |
489 | return 0; | 482 | return 0; |
@@ -622,7 +615,7 @@ struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f, | |||
622 | int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f); | 615 | int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f); |
623 | int fimc_set_scaler_info(struct fimc_ctx *ctx); | 616 | int fimc_set_scaler_info(struct fimc_ctx *ctx); |
624 | int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags); | 617 | int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags); |
625 | int fimc_prepare_addr(struct fimc_ctx *ctx, struct fimc_vid_buffer *buf, | 618 | int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb, |
626 | struct fimc_frame *frame, struct fimc_addr *paddr); | 619 | struct fimc_frame *frame, struct fimc_addr *paddr); |
627 | 620 | ||
628 | /* -----------------------------------------------------*/ | 621 | /* -----------------------------------------------------*/ |
@@ -649,28 +642,27 @@ static inline void fimc_deactivate_capture(struct fimc_dev *fimc) | |||
649 | } | 642 | } |
650 | 643 | ||
651 | /* | 644 | /* |
652 | * Add video buffer to the active buffers queue. | 645 | * Add buf to the capture active buffers queue. |
653 | * The caller holds irqlock spinlock. | 646 | * Locking: Need to be called with fimc_dev::slock held. |
654 | */ | 647 | */ |
655 | static inline void active_queue_add(struct fimc_vid_cap *vid_cap, | 648 | static inline void active_queue_add(struct fimc_vid_cap *vid_cap, |
656 | struct fimc_vid_buffer *buf) | 649 | struct fimc_vid_buffer *buf) |
657 | { | 650 | { |
658 | buf->vb.state = VIDEOBUF_ACTIVE; | 651 | list_add_tail(&buf->list, &vid_cap->active_buf_q); |
659 | list_add_tail(&buf->vb.queue, &vid_cap->active_buf_q); | ||
660 | vid_cap->active_buf_cnt++; | 652 | vid_cap->active_buf_cnt++; |
661 | } | 653 | } |
662 | 654 | ||
663 | /* | 655 | /* |
664 | * Pop a video buffer from the capture active buffers queue | 656 | * Pop a video buffer from the capture active buffers queue |
665 | * Locking: Need to be called with dev->slock held. | 657 | * Locking: Need to be called with fimc_dev::slock held. |
666 | */ | 658 | */ |
667 | static inline struct fimc_vid_buffer * | 659 | static inline struct fimc_vid_buffer * |
668 | active_queue_pop(struct fimc_vid_cap *vid_cap) | 660 | active_queue_pop(struct fimc_vid_cap *vid_cap) |
669 | { | 661 | { |
670 | struct fimc_vid_buffer *buf; | 662 | struct fimc_vid_buffer *buf; |
671 | buf = list_entry(vid_cap->active_buf_q.next, | 663 | buf = list_entry(vid_cap->active_buf_q.next, |
672 | struct fimc_vid_buffer, vb.queue); | 664 | struct fimc_vid_buffer, list); |
673 | list_del(&buf->vb.queue); | 665 | list_del(&buf->list); |
674 | vid_cap->active_buf_cnt--; | 666 | vid_cap->active_buf_cnt--; |
675 | return buf; | 667 | return buf; |
676 | } | 668 | } |
@@ -679,8 +671,7 @@ active_queue_pop(struct fimc_vid_cap *vid_cap) | |||
679 | static inline void fimc_pending_queue_add(struct fimc_vid_cap *vid_cap, | 671 | static inline void fimc_pending_queue_add(struct fimc_vid_cap *vid_cap, |
680 | struct fimc_vid_buffer *buf) | 672 | struct fimc_vid_buffer *buf) |
681 | { | 673 | { |
682 | buf->vb.state = VIDEOBUF_QUEUED; | 674 | list_add_tail(&buf->list, &vid_cap->pending_buf_q); |
683 | list_add_tail(&buf->vb.queue, &vid_cap->pending_buf_q); | ||
684 | } | 675 | } |
685 | 676 | ||
686 | /* Add video buffer to the capture pending buffers queue */ | 677 | /* Add video buffer to the capture pending buffers queue */ |
@@ -689,10 +680,9 @@ pending_queue_pop(struct fimc_vid_cap *vid_cap) | |||
689 | { | 680 | { |
690 | struct fimc_vid_buffer *buf; | 681 | struct fimc_vid_buffer *buf; |
691 | buf = list_entry(vid_cap->pending_buf_q.next, | 682 | buf = list_entry(vid_cap->pending_buf_q.next, |
692 | struct fimc_vid_buffer, vb.queue); | 683 | struct fimc_vid_buffer, list); |
693 | list_del(&buf->vb.queue); | 684 | list_del(&buf->list); |
694 | return buf; | 685 | return buf; |
695 | } | 686 | } |
696 | 687 | ||
697 | |||
698 | #endif /* FIMC_CORE_H_ */ | 688 | #endif /* FIMC_CORE_H_ */ |