linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* dma start/stop & vb2 APIs
@ 2016-01-18 16:26 Ran Shalit
  2016-01-18 17:45 ` Hans Verkuil
  0 siblings, 1 reply; 6+ messages in thread
From: Ran Shalit @ 2016-01-18 16:26 UTC (permalink / raw)
  To: linux-media

Hello,

I am trying to understand how to implement dma transfer correctly
using videobuf2 APIs.

Normally, application will do semthing like this (video test API):

                xioctl(fd, VIDIOC_DQBUF, &buf)
                process_image(buffers[buf.index].start, buf.bytesused);
                xioctl(fd, VIDIOC_QBUF, &buf)

Therefore, in the driver below I will assume that:
1. VIDIOC_DQBUF -  trigger dma to start
2. interrupt handler in driver - stop dma
3. VIDIOC_QBUF - do nothing with dma.

But, on code review of the following two drivers, I see other things,
much more complex, and I don't understand it yet.

These are the two drivers I reviewed:
- STA2X11
- dt3511

In STA2X11 I see:

1. start_streaming - also triggers dma to start, why ?
2. buf_queue - add buffer to list & if No active buffer, active the
first one , and trigger dma. why do we trigger dma with buf_queue (I
would assume triggering is done with  VIDIOC_DQBUF -> buffer_finish) ?
3. buf_finish - remove buffer from list, but also get the next buffer
in list and trigger dma, why  do we need to trigger a next buffer ?
Isn't buffer_finish is called as a result of VIDIOC_QBUF ?


In dt3511 I see something else as following:
buf_queue()
{...
if (pd->curr_buf)
list_add_tail(&vb->done_entry, &pd->dmaq);
else {
pd->curr_buf = vb;
elbit_start_acq(pd);
}
...}

1. Again, why dma triggering is done as part of  buf_queue instead buf_finish
2. what's the meaning of the condition in this code, it is as if only
the first buffer in buf_queue i striggered, what about the next
ones,why do they only get into list without triggering dma ?
3. In this driver there is no buf_finish.

Thank you for any comments,
Ran

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: dma start/stop & vb2 APIs
  2016-01-18 16:26 dma start/stop & vb2 APIs Ran Shalit
@ 2016-01-18 17:45 ` Hans Verkuil
  2016-01-19  4:45   ` Ran Shalit
  0 siblings, 1 reply; 6+ messages in thread
From: Hans Verkuil @ 2016-01-18 17:45 UTC (permalink / raw)
  To: Ran Shalit, linux-media

On 01/18/2016 05:26 PM, Ran Shalit wrote:
> Hello,
> 
> I am trying to understand how to implement dma transfer correctly
> using videobuf2 APIs.
> 
> Normally, application will do semthing like this (video test API):
> 
>                 xioctl(fd, VIDIOC_DQBUF, &buf)
>                 process_image(buffers[buf.index].start, buf.bytesused);
>                 xioctl(fd, VIDIOC_QBUF, &buf)
> 
> Therefore, in the driver below I will assume that:
> 1. VIDIOC_DQBUF -  trigger dma to start

No. DMA typically starts when VIDIOC_STREAMON is called, although depending
on the hardware the start of the DMA may be delayed if insufficient buffers
have been queued. When the start_streaming op is called you know that STREAMON
has been called and that at least min_buffers_needed buffers have been queued.

> 2. interrupt handler in driver - stop dma

??? No, this just passes the buffer that has been filled by the DMA engine
to vb2 via vb2_buffer_done. The DMA will continue filling the next queued buffer.

> 3. VIDIOC_QBUF - do nothing with dma.
> 
> But, on code review of the following two drivers, I see other things,
> much more complex, and I don't understand it yet.
> 
> These are the two drivers I reviewed:
> - STA2X11
> - dt3511
> 
> In STA2X11 I see:
> 
> 1. start_streaming - also triggers dma to start, why ?

See above, that's what start_streaming typically does.

> 2. buf_queue - add buffer to list & if No active buffer, active the
> first one , and trigger dma. why do we trigger dma with buf_queue

This is old code: if start_streaming is called when there are insufficient
buffers, then start_streaming won't call start_dma and this is postponed
until buf_queue is called and the minimum number of buffers is reached.

These days you'd set the min_buffers_needed field (like in dt3155), and
always start the dma engine in start_streaming. This feature didn't exist
when this driver was written.

> (I
> would assume triggering is done with  VIDIOC_DQBUF -> buffer_finish) ?
> 3. buf_finish - remove buffer from list, but also get the next buffer
> in list and trigger dma, why  do we need to trigger a next buffer ?
> Isn't buffer_finish is called as a result of VIDIOC_QBUF ?

I don't think this in done in the right place. I really wouldn't use sta2x11
as a template. It's poorly maintained.

> 
> 
> In dt3511 I see something else as following:
> buf_queue()
> {...
> if (pd->curr_buf)
> list_add_tail(&vb->done_entry, &pd->dmaq);
> else {
> pd->curr_buf = vb;
> elbit_start_acq(pd);
> }
> ...}
> 
> 1. Again, why dma triggering is done as part of  buf_queue instead buf_finish

?? It doesn't. This is the code from the latest kernel:

static void dt3155_buf_queue(struct vb2_buffer *vb)
{
        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
        struct dt3155_priv *pd = vb2_get_drv_priv(vb->vb2_queue);

        /*  pd->vidq.streaming = 1 when dt3155_buf_queue() is invoked  */
        spin_lock_irq(&pd->lock);
        if (pd->curr_buf)
                list_add_tail(&vb->done_entry, &pd->dmaq);
        else
                pd->curr_buf = vbuf;
        spin_unlock_irq(&pd->lock);
}

Are you looking at the dt3155 driver from some old kernel? I've no idea
where you get that code from. BTW, it's dt3155, not dt3511.

> 2. what's the meaning of the condition in this code, it is as if only
> the first buffer in buf_queue i striggered, what about the next
> ones,why do they only get into list without triggering dma ?
> 3. In this driver there is no buf_finish.

What each vb2_op does is documented in the comment before struct vb2_ops in
videobuf2-core.h. This includes which ops are optional and which aren't
(e.g. buf_finish is optional: if there is nothing to be done there you can
leave it out).

Since there are so many different DMA engines, each with its own peculiarities,
what happens in which op can differ.

Regards,

	Hans

> 
> Thank you for any comments,
> Ran
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: dma start/stop & vb2 APIs
  2016-01-18 17:45 ` Hans Verkuil
@ 2016-01-19  4:45   ` Ran Shalit
  2016-01-19  7:33     ` Hans Verkuil
  0 siblings, 1 reply; 6+ messages in thread
From: Ran Shalit @ 2016-01-19  4:45 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media

On Mon, Jan 18, 2016 at 7:45 PM, Hans Verkuil <hverkuil@xs4all.nl> wrote:
> On 01/18/2016 05:26 PM, Ran Shalit wrote:
>> Hello,
>>
>> I am trying to understand how to implement dma transfer correctly
>> using videobuf2 APIs.
>>
>> Normally, application will do semthing like this (video test API):
>>
>>                 xioctl(fd, VIDIOC_DQBUF, &buf)
>>                 process_image(buffers[buf.index].start, buf.bytesused);
>>                 xioctl(fd, VIDIOC_QBUF, &buf)
>>
>> Therefore, in the driver below I will assume that:
>> 1. VIDIOC_DQBUF -  trigger dma to start
>
> No. DMA typically starts when VIDIOC_STREAMON is called, although depending
> on the hardware the start of the DMA may be delayed if insufficient buffers
> have been queued. When the start_streaming op is called you know that STREAMON
> has been called and that at least min_buffers_needed buffers have been queued.
>
>> 2. interrupt handler in driver - stop dma
>
> ??? No, this just passes the buffer that has been filled by the DMA engine
> to vb2 via vb2_buffer_done. The DMA will continue filling the next queued buffer.
>

Hi,
Just to be sure I got it all right:
"The DMA will continue filling the next queued buffer" is usually the
responsibility of the interrupt handler .
Interrrupt will get the new buffer from list and trigger next dma
transaction with that buffer.
 Is that Right ?

Thank you all very much for the time,
Ran


>> 3. VIDIOC_QBUF - do nothing with dma.
>>
>> But, on code review of the following two drivers, I see other things,
>> much more complex, and I don't understand it yet.
>>
>> These are the two drivers I reviewed:
>> - STA2X11
>> - dt3511
>>
>> In STA2X11 I see:
>>
>> 1. start_streaming - also triggers dma to start, why ?
>
> See above, that's what start_streaming typically does.
>
>> 2. buf_queue - add buffer to list & if No active buffer, active the
>> first one , and trigger dma. why do we trigger dma with buf_queue
>
> This is old code: if start_streaming is called when there are insufficient
> buffers, then start_streaming won't call start_dma and this is postponed
> until buf_queue is called and the minimum number of buffers is reached.
>
> These days you'd set the min_buffers_needed field (like in dt3155), and
> always start the dma engine in start_streaming. This feature didn't exist
> when this driver was written.
>
>> (I
>> would assume triggering is done with  VIDIOC_DQBUF -> buffer_finish) ?
>> 3. buf_finish - remove buffer from list, but also get the next buffer
>> in list and trigger dma, why  do we need to trigger a next buffer ?
>> Isn't buffer_finish is called as a result of VIDIOC_QBUF ?
>
> I don't think this in done in the right place. I really wouldn't use sta2x11
> as a template. It's poorly maintained.
>
>>
>>
>> In dt3511 I see something else as following:
>> buf_queue()
>> {...
>> if (pd->curr_buf)
>> list_add_tail(&vb->done_entry, &pd->dmaq);
>> else {
>> pd->curr_buf = vb;
>> elbit_start_acq(pd);
>> }
>> ...}
>>
>> 1. Again, why dma triggering is done as part of  buf_queue instead buf_finish
>
> ?? It doesn't. This is the code from the latest kernel:
>
> static void dt3155_buf_queue(struct vb2_buffer *vb)
> {
>         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
>         struct dt3155_priv *pd = vb2_get_drv_priv(vb->vb2_queue);
>
>         /*  pd->vidq.streaming = 1 when dt3155_buf_queue() is invoked  */
>         spin_lock_irq(&pd->lock);
>         if (pd->curr_buf)
>                 list_add_tail(&vb->done_entry, &pd->dmaq);
>         else
>                 pd->curr_buf = vbuf;
>         spin_unlock_irq(&pd->lock);
> }
>
> Are you looking at the dt3155 driver from some old kernel? I've no idea
> where you get that code from. BTW, it's dt3155, not dt3511.
>
>> 2. what's the meaning of the condition in this code, it is as if only
>> the first buffer in buf_queue i striggered, what about the next
>> ones,why do they only get into list without triggering dma ?
>> 3. In this driver there is no buf_finish.
>
> What each vb2_op does is documented in the comment before struct vb2_ops in
> videobuf2-core.h. This includes which ops are optional and which aren't
> (e.g. buf_finish is optional: if there is nothing to be done there you can
> leave it out).
>
> Since there are so many different DMA engines, each with its own peculiarities,
> what happens in which op can differ.
>
> Regards,
>
>         Hans
>
>>
>> Thank you for any comments,
>> Ran
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-media" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: dma start/stop & vb2 APIs
  2016-01-19  4:45   ` Ran Shalit
@ 2016-01-19  7:33     ` Hans Verkuil
  2016-01-30 11:55       ` Ran Shalit
  0 siblings, 1 reply; 6+ messages in thread
From: Hans Verkuil @ 2016-01-19  7:33 UTC (permalink / raw)
  To: Ran Shalit; +Cc: linux-media

On 01/19/2016 05:45 AM, Ran Shalit wrote:
> On Mon, Jan 18, 2016 at 7:45 PM, Hans Verkuil <hverkuil@xs4all.nl> wrote:
>> On 01/18/2016 05:26 PM, Ran Shalit wrote:
>>> Hello,
>>>
>>> I am trying to understand how to implement dma transfer correctly
>>> using videobuf2 APIs.
>>>
>>> Normally, application will do semthing like this (video test API):
>>>
>>>                 xioctl(fd, VIDIOC_DQBUF, &buf)
>>>                 process_image(buffers[buf.index].start, buf.bytesused);
>>>                 xioctl(fd, VIDIOC_QBUF, &buf)
>>>
>>> Therefore, in the driver below I will assume that:
>>> 1. VIDIOC_DQBUF -  trigger dma to start
>>
>> No. DMA typically starts when VIDIOC_STREAMON is called, although depending
>> on the hardware the start of the DMA may be delayed if insufficient buffers
>> have been queued. When the start_streaming op is called you know that STREAMON
>> has been called and that at least min_buffers_needed buffers have been queued.
>>
>>> 2. interrupt handler in driver - stop dma
>>
>> ??? No, this just passes the buffer that has been filled by the DMA engine
>> to vb2 via vb2_buffer_done. The DMA will continue filling the next queued buffer.
>>
> 
> Hi,
> Just to be sure I got it all right:
> "The DMA will continue filling the next queued buffer" is usually the
> responsibility of the interrupt handler .
> Interrrupt will get the new buffer from list and trigger next dma
> transaction with that buffer.
>  Is that Right ?

Usually that's true. Again, I can't give absolutes because it depends on
the DMA hardware details. There tend to be two main types of DMA:

1) the DMA engine has pointers to the current and next frame: in that case
the irq handler has to update the pointers once the current frame finishes
the DMA.

2) the DMA engine has a list of descriptors describing each frame and that
links each frame to the next one. In that case the list of descriptors is
updated whenever a new buffer is queued. For engines like this the interrupt
function just returns the DMAed buffer and doesn't have to do anything else.

Regards,

	Hans

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: dma start/stop & vb2 APIs
  2016-01-19  7:33     ` Hans Verkuil
@ 2016-01-30 11:55       ` Ran Shalit
  2016-01-30 12:26         ` Hans Verkuil
  0 siblings, 1 reply; 6+ messages in thread
From: Ran Shalit @ 2016-01-30 11:55 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media

On Tue, Jan 19, 2016 at 9:33 AM, Hans Verkuil <hverkuil@xs4all.nl> wrote:
> On 01/19/2016 05:45 AM, Ran Shalit wrote:
>> On Mon, Jan 18, 2016 at 7:45 PM, Hans Verkuil <hverkuil@xs4all.nl> wrote:
>>> On 01/18/2016 05:26 PM, Ran Shalit wrote:
>>>> Hello,
>>>>
>>>> I am trying to understand how to implement dma transfer correctly
>>>> using videobuf2 APIs.
>>>>
>>>> Normally, application will do semthing like this (video test API):
>>>>
>>>>                 xioctl(fd, VIDIOC_DQBUF, &buf)
>>>>                 process_image(buffers[buf.index].start, buf.bytesused);
>>>>                 xioctl(fd, VIDIOC_QBUF, &buf)
>>>>
>>>> Therefore, in the driver below I will assume that:
>>>> 1. VIDIOC_DQBUF -  trigger dma to start
>>>
>>> No. DMA typically starts when VIDIOC_STREAMON is called, although depending
>>> on the hardware the start of the DMA may be delayed if insufficient buffers
>>> have been queued. When the start_streaming op is called you know that STREAMON
>>> has been called and that at least min_buffers_needed buffers have been queued.
>>>
>>>> 2. interrupt handler in driver - stop dma
>>>
>>> ??? No, this just passes the buffer that has been filled by the DMA engine
>>> to vb2 via vb2_buffer_done. The DMA will continue filling the next queued buffer.
>>>
>>
>> Hi,
>> Just to be sure I got it all right:
>> "The DMA will continue filling the next queued buffer" is usually the
>> responsibility of the interrupt handler .
>> Interrrupt will get the new buffer from list and trigger next dma
>> transaction with that buffer.
>>  Is that Right ?
>
> Usually that's true. Again, I can't give absolutes because it depends on
> the DMA hardware details. There tend to be two main types of DMA:
>
> 1) the DMA engine has pointers to the current and next frame: in that case
> the irq handler has to update the pointers once the current frame finishes
> the DMA.
>
> 2) the DMA engine has a list of descriptors describing each frame and that
> links each frame to the next one. In that case the list of descriptors is
> updated whenever a new buffer is queued. For engines like this the interrupt
> function just returns the DMAed buffer and doesn't have to do anything else.
>

Hi,

Is the first dma engine type above is usually used with contigous dma
(videobuf2-dma-contig.h), while
the second type referese to sg (scatter-gather) mode (videobuf2-dma-sg.h ) ?

Thank you very much,
Ran

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: dma start/stop & vb2 APIs
  2016-01-30 11:55       ` Ran Shalit
@ 2016-01-30 12:26         ` Hans Verkuil
  0 siblings, 0 replies; 6+ messages in thread
From: Hans Verkuil @ 2016-01-30 12:26 UTC (permalink / raw)
  To: Ran Shalit; +Cc: linux-media



On 01/30/2016 12:55 PM, Ran Shalit wrote:
> On Tue, Jan 19, 2016 at 9:33 AM, Hans Verkuil <hverkuil@xs4all.nl> wrote:
>> On 01/19/2016 05:45 AM, Ran Shalit wrote:
>>> On Mon, Jan 18, 2016 at 7:45 PM, Hans Verkuil <hverkuil@xs4all.nl> wrote:
>>>> On 01/18/2016 05:26 PM, Ran Shalit wrote:
>>>>> Hello,
>>>>>
>>>>> I am trying to understand how to implement dma transfer correctly
>>>>> using videobuf2 APIs.
>>>>>
>>>>> Normally, application will do semthing like this (video test API):
>>>>>
>>>>>                 xioctl(fd, VIDIOC_DQBUF, &buf)
>>>>>                 process_image(buffers[buf.index].start, buf.bytesused);
>>>>>                 xioctl(fd, VIDIOC_QBUF, &buf)
>>>>>
>>>>> Therefore, in the driver below I will assume that:
>>>>> 1. VIDIOC_DQBUF -  trigger dma to start
>>>>
>>>> No. DMA typically starts when VIDIOC_STREAMON is called, although depending
>>>> on the hardware the start of the DMA may be delayed if insufficient buffers
>>>> have been queued. When the start_streaming op is called you know that STREAMON
>>>> has been called and that at least min_buffers_needed buffers have been queued.
>>>>
>>>>> 2. interrupt handler in driver - stop dma
>>>>
>>>> ??? No, this just passes the buffer that has been filled by the DMA engine
>>>> to vb2 via vb2_buffer_done. The DMA will continue filling the next queued buffer.
>>>>
>>>
>>> Hi,
>>> Just to be sure I got it all right:
>>> "The DMA will continue filling the next queued buffer" is usually the
>>> responsibility of the interrupt handler .
>>> Interrrupt will get the new buffer from list and trigger next dma
>>> transaction with that buffer.
>>>  Is that Right ?
>>
>> Usually that's true. Again, I can't give absolutes because it depends on
>> the DMA hardware details. There tend to be two main types of DMA:
>>
>> 1) the DMA engine has pointers to the current and next frame: in that case
>> the irq handler has to update the pointers once the current frame finishes
>> the DMA.
>>
>> 2) the DMA engine has a list of descriptors describing each frame and that
>> links each frame to the next one. In that case the list of descriptors is
>> updated whenever a new buffer is queued. For engines like this the interrupt
>> function just returns the DMAed buffer and doesn't have to do anything else.
>>
> 
> Hi,
> 
> Is the first dma engine type above is usually used with contigous dma
> (videobuf2-dma-contig.h), while
> the second type referese to sg (scatter-gather) mode (videobuf2-dma-sg.h ) ?

Yes.

	Hans

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-01-30 12:27 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-18 16:26 dma start/stop & vb2 APIs Ran Shalit
2016-01-18 17:45 ` Hans Verkuil
2016-01-19  4:45   ` Ran Shalit
2016-01-19  7:33     ` Hans Verkuil
2016-01-30 11:55       ` Ran Shalit
2016-01-30 12:26         ` Hans Verkuil

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).