1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2016 NextThing Co
4 * Copyright (C) 2016-2019 Bootlin
6 * Author: Maxime Ripard <maxime.ripard@bootlin.com>
9 #include <linux/device.h>
10 #include <linux/interrupt.h>
11 #include <linux/list.h>
12 #include <linux/mutex.h>
13 #include <linux/spinlock.h>
14 #include <media/videobuf2-dma-contig.h>
15 #include <media/videobuf2-v4l2.h>
17 #include "sun4i_csi.h"
19 struct sun4i_csi_buffer
{
20 struct vb2_v4l2_buffer vb
;
21 struct list_head list
;
24 static inline struct sun4i_csi_buffer
*
25 vb2_v4l2_to_csi_buffer(const struct vb2_v4l2_buffer
*p
)
27 return container_of(p
, struct sun4i_csi_buffer
, vb
);
30 static inline struct sun4i_csi_buffer
*
31 vb2_to_csi_buffer(const struct vb2_buffer
*p
)
33 return vb2_v4l2_to_csi_buffer(to_vb2_v4l2_buffer(p
));
36 static void sun4i_csi_capture_start(struct sun4i_csi
*csi
)
38 writel(CSI_CPT_CTRL_VIDEO_START
, csi
->regs
+ CSI_CPT_CTRL_REG
);
41 static void sun4i_csi_capture_stop(struct sun4i_csi
*csi
)
43 writel(0, csi
->regs
+ CSI_CPT_CTRL_REG
);
46 static int sun4i_csi_queue_setup(struct vb2_queue
*vq
,
47 unsigned int *nbuffers
,
48 unsigned int *nplanes
,
50 struct device
*alloc_devs
[])
52 struct sun4i_csi
*csi
= vb2_get_drv_priv(vq
);
53 unsigned int num_planes
= csi
->fmt
.num_planes
;
57 if (*nplanes
!= num_planes
)
60 for (i
= 0; i
< num_planes
; i
++)
61 if (sizes
[i
] < csi
->fmt
.plane_fmt
[i
].sizeimage
)
66 *nplanes
= num_planes
;
67 for (i
= 0; i
< num_planes
; i
++)
68 sizes
[i
] = csi
->fmt
.plane_fmt
[i
].sizeimage
;
73 static int sun4i_csi_buffer_prepare(struct vb2_buffer
*vb
)
75 struct sun4i_csi
*csi
= vb2_get_drv_priv(vb
->vb2_queue
);
78 for (i
= 0; i
< csi
->fmt
.num_planes
; i
++) {
79 unsigned long size
= csi
->fmt
.plane_fmt
[i
].sizeimage
;
81 if (vb2_plane_size(vb
, i
) < size
) {
82 dev_err(csi
->dev
, "buffer too small (%lu < %lu)\n",
83 vb2_plane_size(vb
, i
), size
);
87 vb2_set_plane_payload(vb
, i
, size
);
93 static int sun4i_csi_setup_scratch_buffer(struct sun4i_csi
*csi
,
96 dma_addr_t addr
= csi
->scratch
.paddr
;
100 "No more available buffer, using the scratch buffer\n");
102 for (plane
= 0; plane
< csi
->fmt
.num_planes
; plane
++) {
103 writel(addr
, csi
->regs
+ CSI_BUF_ADDR_REG(plane
, slot
));
104 addr
+= csi
->fmt
.plane_fmt
[plane
].sizeimage
;
107 csi
->current_buf
[slot
] = NULL
;
111 static int sun4i_csi_buffer_fill_slot(struct sun4i_csi
*csi
, unsigned int slot
)
113 struct sun4i_csi_buffer
*c_buf
;
114 struct vb2_v4l2_buffer
*v_buf
;
118 * We should never end up in a situation where we overwrite an
119 * already filled slot.
121 if (WARN_ON(csi
->current_buf
[slot
]))
124 if (list_empty(&csi
->buf_list
))
125 return sun4i_csi_setup_scratch_buffer(csi
, slot
);
127 c_buf
= list_first_entry(&csi
->buf_list
, struct sun4i_csi_buffer
, list
);
128 list_del_init(&c_buf
->list
);
131 csi
->current_buf
[slot
] = v_buf
;
133 for (plane
= 0; plane
< csi
->fmt
.num_planes
; plane
++) {
136 buf_addr
= vb2_dma_contig_plane_dma_addr(&v_buf
->vb2_buf
,
138 writel(buf_addr
, csi
->regs
+ CSI_BUF_ADDR_REG(plane
, slot
));
144 static int sun4i_csi_buffer_fill_all(struct sun4i_csi
*csi
)
149 for (slot
= 0; slot
< CSI_MAX_BUFFER
; slot
++) {
150 ret
= sun4i_csi_buffer_fill_slot(csi
, slot
);
158 static void sun4i_csi_buffer_mark_done(struct sun4i_csi
*csi
,
160 unsigned int sequence
)
162 struct vb2_v4l2_buffer
*v_buf
;
164 if (!csi
->current_buf
[slot
]) {
165 dev_dbg(csi
->dev
, "Scratch buffer was used, ignoring..\n");
169 v_buf
= csi
->current_buf
[slot
];
170 v_buf
->field
= csi
->fmt
.field
;
171 v_buf
->sequence
= sequence
;
172 v_buf
->vb2_buf
.timestamp
= ktime_get_ns();
173 vb2_buffer_done(&v_buf
->vb2_buf
, VB2_BUF_STATE_DONE
);
175 csi
->current_buf
[slot
] = NULL
;
178 static int sun4i_csi_buffer_flip(struct sun4i_csi
*csi
, unsigned int sequence
)
180 u32 reg
= readl(csi
->regs
+ CSI_BUF_CTRL_REG
);
183 /* Our next buffer is not the current buffer */
184 next
= !(reg
& CSI_BUF_CTRL_DBS
);
186 /* Report the previous buffer as done */
187 sun4i_csi_buffer_mark_done(csi
, next
, sequence
);
189 /* Put a new buffer in there */
190 return sun4i_csi_buffer_fill_slot(csi
, next
);
193 static void sun4i_csi_buffer_queue(struct vb2_buffer
*vb
)
195 struct sun4i_csi
*csi
= vb2_get_drv_priv(vb
->vb2_queue
);
196 struct sun4i_csi_buffer
*buf
= vb2_to_csi_buffer(vb
);
199 spin_lock_irqsave(&csi
->qlock
, flags
);
200 list_add_tail(&buf
->list
, &csi
->buf_list
);
201 spin_unlock_irqrestore(&csi
->qlock
, flags
);
204 static void return_all_buffers(struct sun4i_csi
*csi
,
205 enum vb2_buffer_state state
)
207 struct sun4i_csi_buffer
*buf
, *node
;
210 list_for_each_entry_safe(buf
, node
, &csi
->buf_list
, list
) {
211 vb2_buffer_done(&buf
->vb
.vb2_buf
, state
);
212 list_del(&buf
->list
);
215 for (slot
= 0; slot
< CSI_MAX_BUFFER
; slot
++) {
216 struct vb2_v4l2_buffer
*v_buf
= csi
->current_buf
[slot
];
221 vb2_buffer_done(&v_buf
->vb2_buf
, state
);
222 csi
->current_buf
[slot
] = NULL
;
226 static int sun4i_csi_start_streaming(struct vb2_queue
*vq
, unsigned int count
)
228 struct sun4i_csi
*csi
= vb2_get_drv_priv(vq
);
229 struct v4l2_fwnode_bus_parallel
*bus
= &csi
->bus
;
230 const struct sun4i_csi_format
*csi_fmt
;
231 unsigned long href_pol
, pclk_pol
, vref_pol
;
236 csi_fmt
= sun4i_csi_find_format(&csi
->fmt
.pixelformat
, NULL
);
240 dev_dbg(csi
->dev
, "Starting capture\n");
245 * We need a scratch buffer in case where we'll not have any
246 * more buffer queued so that we don't error out. One of those
247 * cases is when you end up at the last frame to capture, you
248 * don't havea any buffer queued any more, and yet it doesn't
249 * really matter since you'll never reach the next buffer.
251 * Since we support the multi-planar API, we need to have a
252 * buffer for each plane. Allocating a single one large enough
253 * to hold all the buffers is simpler, so let's go for that.
255 csi
->scratch
.size
= 0;
256 for (i
= 0; i
< csi
->fmt
.num_planes
; i
++)
257 csi
->scratch
.size
+= csi
->fmt
.plane_fmt
[i
].sizeimage
;
259 csi
->scratch
.vaddr
= dma_alloc_coherent(csi
->dev
,
263 if (!csi
->scratch
.vaddr
) {
264 dev_err(csi
->dev
, "Failed to allocate scratch buffer\n");
266 goto err_clear_dma_queue
;
269 ret
= media_pipeline_start(&csi
->vdev
.entity
, &csi
->vdev
.pipe
);
271 goto err_free_scratch_buffer
;
273 spin_lock_irqsave(&csi
->qlock
, flags
);
276 writel(CSI_WIN_CTRL_W_ACTIVE(csi
->fmt
.width
* 2),
277 csi
->regs
+ CSI_WIN_CTRL_W_REG
);
278 writel(CSI_WIN_CTRL_H_ACTIVE(csi
->fmt
.height
),
279 csi
->regs
+ CSI_WIN_CTRL_H_REG
);
282 * This hardware uses [HV]REF instead of [HV]SYNC. Based on the
283 * provided timing diagrams in the manual, positive polarity
284 * equals active high [HV]REF.
286 * When the back porch is 0, [HV]REF is more or less equivalent
287 * to [HV]SYNC inverted.
289 href_pol
= !!(bus
->flags
& V4L2_MBUS_HSYNC_ACTIVE_LOW
);
290 vref_pol
= !!(bus
->flags
& V4L2_MBUS_VSYNC_ACTIVE_LOW
);
291 pclk_pol
= !!(bus
->flags
& V4L2_MBUS_PCLK_SAMPLE_RISING
);
292 writel(CSI_CFG_INPUT_FMT(csi_fmt
->input
) |
293 CSI_CFG_OUTPUT_FMT(csi_fmt
->output
) |
294 CSI_CFG_VREF_POL(vref_pol
) |
295 CSI_CFG_HREF_POL(href_pol
) |
296 CSI_CFG_PCLK_POL(pclk_pol
),
297 csi
->regs
+ CSI_CFG_REG
);
299 /* Setup buffer length */
300 writel(csi
->fmt
.plane_fmt
[0].bytesperline
,
301 csi
->regs
+ CSI_BUF_LEN_REG
);
303 /* Prepare our buffers in hardware */
304 ret
= sun4i_csi_buffer_fill_all(csi
);
306 spin_unlock_irqrestore(&csi
->qlock
, flags
);
307 goto err_disable_pipeline
;
310 /* Enable double buffering */
311 writel(CSI_BUF_CTRL_DBE
, csi
->regs
+ CSI_BUF_CTRL_REG
);
313 /* Clear the pending interrupts */
314 writel(CSI_INT_FRM_DONE
, csi
->regs
+ 0x34);
316 /* Enable frame done interrupt */
317 writel(CSI_INT_FRM_DONE
, csi
->regs
+ CSI_INT_EN_REG
);
319 sun4i_csi_capture_start(csi
);
321 spin_unlock_irqrestore(&csi
->qlock
, flags
);
323 ret
= v4l2_subdev_call(csi
->src_subdev
, video
, s_stream
, 1);
324 if (ret
< 0 && ret
!= -ENOIOCTLCMD
)
325 goto err_disable_device
;
330 sun4i_csi_capture_stop(csi
);
332 err_disable_pipeline
:
333 media_pipeline_stop(&csi
->vdev
.entity
);
335 err_free_scratch_buffer
:
336 dma_free_coherent(csi
->dev
, csi
->scratch
.size
, csi
->scratch
.vaddr
,
340 spin_lock_irqsave(&csi
->qlock
, flags
);
341 return_all_buffers(csi
, VB2_BUF_STATE_QUEUED
);
342 spin_unlock_irqrestore(&csi
->qlock
, flags
);
347 static void sun4i_csi_stop_streaming(struct vb2_queue
*vq
)
349 struct sun4i_csi
*csi
= vb2_get_drv_priv(vq
);
352 dev_dbg(csi
->dev
, "Stopping capture\n");
354 v4l2_subdev_call(csi
->src_subdev
, video
, s_stream
, 0);
355 sun4i_csi_capture_stop(csi
);
357 /* Release all active buffers */
358 spin_lock_irqsave(&csi
->qlock
, flags
);
359 return_all_buffers(csi
, VB2_BUF_STATE_ERROR
);
360 spin_unlock_irqrestore(&csi
->qlock
, flags
);
362 media_pipeline_stop(&csi
->vdev
.entity
);
364 dma_free_coherent(csi
->dev
, csi
->scratch
.size
, csi
->scratch
.vaddr
,
368 static const struct vb2_ops sun4i_csi_qops
= {
369 .queue_setup
= sun4i_csi_queue_setup
,
370 .buf_prepare
= sun4i_csi_buffer_prepare
,
371 .buf_queue
= sun4i_csi_buffer_queue
,
372 .start_streaming
= sun4i_csi_start_streaming
,
373 .stop_streaming
= sun4i_csi_stop_streaming
,
374 .wait_prepare
= vb2_ops_wait_prepare
,
375 .wait_finish
= vb2_ops_wait_finish
,
378 static irqreturn_t
sun4i_csi_irq(int irq
, void *data
)
380 struct sun4i_csi
*csi
= data
;
383 reg
= readl(csi
->regs
+ CSI_INT_STA_REG
);
385 /* Acknowledge the interrupts */
386 writel(reg
, csi
->regs
+ CSI_INT_STA_REG
);
388 if (!(reg
& CSI_INT_FRM_DONE
))
391 spin_lock(&csi
->qlock
);
392 if (sun4i_csi_buffer_flip(csi
, csi
->sequence
++)) {
393 dev_warn(csi
->dev
, "%s: Flip failed\n", __func__
);
394 sun4i_csi_capture_stop(csi
);
396 spin_unlock(&csi
->qlock
);
401 int sun4i_csi_dma_register(struct sun4i_csi
*csi
, int irq
)
403 struct vb2_queue
*q
= &csi
->queue
;
407 spin_lock_init(&csi
->qlock
);
408 mutex_init(&csi
->lock
);
410 INIT_LIST_HEAD(&csi
->buf_list
);
411 for (i
= 0; i
< CSI_MAX_BUFFER
; i
++)
412 csi
->current_buf
[i
] = NULL
;
414 q
->min_buffers_needed
= 3;
415 q
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
416 q
->io_modes
= VB2_MMAP
;
417 q
->lock
= &csi
->lock
;
419 q
->buf_struct_size
= sizeof(struct sun4i_csi_buffer
);
420 q
->ops
= &sun4i_csi_qops
;
421 q
->mem_ops
= &vb2_dma_contig_memops
;
422 q
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
;
425 ret
= vb2_queue_init(q
);
427 dev_err(csi
->dev
, "failed to initialize VB2 queue\n");
431 ret
= v4l2_device_register(csi
->dev
, &csi
->v4l
);
433 dev_err(csi
->dev
, "Couldn't register the v4l2 device\n");
437 ret
= devm_request_irq(csi
->dev
, irq
, sun4i_csi_irq
, 0,
438 dev_name(csi
->dev
), csi
);
440 dev_err(csi
->dev
, "Couldn't register our interrupt\n");
441 goto err_unregister_device
;
446 err_unregister_device
:
447 v4l2_device_unregister(&csi
->v4l
);
450 vb2_queue_release(q
);
453 mutex_destroy(&csi
->lock
);
457 void sun4i_csi_dma_unregister(struct sun4i_csi
*csi
)
459 v4l2_device_unregister(&csi
->v4l
);
460 vb2_queue_release(&csi
->queue
);
461 mutex_destroy(&csi
->lock
);