1577a7ad3SMauro Carvalho Chehab.. SPDX-License-Identifier: GPL-2.0 2577a7ad3SMauro Carvalho Chehab 3577a7ad3SMauro Carvalho ChehabPXA-Camera Host Driver 4577a7ad3SMauro Carvalho Chehab====================== 5577a7ad3SMauro Carvalho Chehab 6577a7ad3SMauro Carvalho ChehabAuthor: Robert Jarzmik <robert.jarzmik@free.fr> 7577a7ad3SMauro Carvalho Chehab 8577a7ad3SMauro Carvalho ChehabConstraints 9577a7ad3SMauro Carvalho Chehab----------- 10577a7ad3SMauro Carvalho Chehab 11577a7ad3SMauro Carvalho Chehaba) Image size for YUV422P format 12577a7ad3SMauro Carvalho Chehab All YUV422P images are enforced to have width x height % 16 = 0. 13577a7ad3SMauro Carvalho Chehab This is due to DMA constraints, which transfers only planes of 8 byte 14577a7ad3SMauro Carvalho Chehab multiples. 15577a7ad3SMauro Carvalho Chehab 16577a7ad3SMauro Carvalho Chehab 17577a7ad3SMauro Carvalho ChehabGlobal video workflow 18577a7ad3SMauro Carvalho Chehab--------------------- 19577a7ad3SMauro Carvalho Chehab 20577a7ad3SMauro Carvalho Chehaba) QCI stopped 21577a7ad3SMauro Carvalho Chehab Initially, the QCI interface is stopped. 22*f068a6ceSHans Verkuil When a buffer is queued, start_streaming is called and the QCI starts. 23577a7ad3SMauro Carvalho Chehab 24577a7ad3SMauro Carvalho Chehabb) QCI started 25577a7ad3SMauro Carvalho Chehab More buffers can be queued while the QCI is started without halting the 26577a7ad3SMauro Carvalho Chehab capture. The new buffers are "appended" at the tail of the DMA chain, and 27577a7ad3SMauro Carvalho Chehab smoothly captured one frame after the other. 28577a7ad3SMauro Carvalho Chehab 29577a7ad3SMauro Carvalho Chehab Once a buffer is filled in the QCI interface, it is marked as "DONE" and 30577a7ad3SMauro Carvalho Chehab removed from the active buffers list. It can be then requeud or dequeued by 31577a7ad3SMauro Carvalho Chehab userland application. 32577a7ad3SMauro Carvalho Chehab 33577a7ad3SMauro Carvalho Chehab Once the last buffer is filled in, the QCI interface stops. 34577a7ad3SMauro Carvalho Chehab 35577a7ad3SMauro Carvalho Chehabc) Capture global finite state machine schema 36577a7ad3SMauro Carvalho Chehab 37577a7ad3SMauro Carvalho Chehab.. code-block:: none 38577a7ad3SMauro Carvalho Chehab 39577a7ad3SMauro Carvalho Chehab +----+ +---+ +----+ 40577a7ad3SMauro Carvalho Chehab | DQ | | Q | | DQ | 41577a7ad3SMauro Carvalho Chehab | v | v | v 42577a7ad3SMauro Carvalho Chehab +-----------+ +------------------------+ 43577a7ad3SMauro Carvalho Chehab | STOP | | Wait for capture start | 44577a7ad3SMauro Carvalho Chehab +-----------+ Q +------------------------+ 45577a7ad3SMauro Carvalho Chehab +-> | QCI: stop | ------------------> | QCI: run | <------------+ 46577a7ad3SMauro Carvalho Chehab | | DMA: stop | | DMA: stop | | 47577a7ad3SMauro Carvalho Chehab | +-----------+ +-----> +------------------------+ | 48577a7ad3SMauro Carvalho Chehab | / | | 49577a7ad3SMauro Carvalho Chehab | / +---+ +----+ | | 50577a7ad3SMauro Carvalho Chehab |capture list empty / | Q | | DQ | | QCI Irq EOF | 51577a7ad3SMauro Carvalho Chehab | / | v | v v | 52577a7ad3SMauro Carvalho Chehab | +--------------------+ +----------------------+ | 53577a7ad3SMauro Carvalho Chehab | | DMA hotlink missed | | Capture running | | 54577a7ad3SMauro Carvalho Chehab | +--------------------+ +----------------------+ | 55577a7ad3SMauro Carvalho Chehab | | QCI: run | +-----> | QCI: run | <-+ | 56577a7ad3SMauro Carvalho Chehab | | DMA: stop | / | DMA: run | | | 57577a7ad3SMauro Carvalho Chehab | +--------------------+ / +----------------------+ | Other | 58577a7ad3SMauro Carvalho Chehab | ^ /DMA still | | channels | 59577a7ad3SMauro Carvalho Chehab | | capture list / running | DMA Irq End | not | 60577a7ad3SMauro Carvalho Chehab | | not empty / | | finished | 61577a7ad3SMauro Carvalho Chehab | | / v | yet | 62577a7ad3SMauro Carvalho Chehab | +----------------------+ +----------------------+ | | 63577a7ad3SMauro Carvalho Chehab | | Videobuf released | | Channel completed | | | 64577a7ad3SMauro Carvalho Chehab | +----------------------+ +----------------------+ | | 65577a7ad3SMauro Carvalho Chehab +-- | QCI: run | | QCI: run | --+ | 66577a7ad3SMauro Carvalho Chehab | DMA: run | | DMA: run | | 67577a7ad3SMauro Carvalho Chehab +----------------------+ +----------------------+ | 68577a7ad3SMauro Carvalho Chehab ^ / | | 69577a7ad3SMauro Carvalho Chehab | no overrun / | overrun | 70577a7ad3SMauro Carvalho Chehab | / v | 71577a7ad3SMauro Carvalho Chehab +--------------------+ / +----------------------+ | 72577a7ad3SMauro Carvalho Chehab | Frame completed | / | Frame overran | | 73577a7ad3SMauro Carvalho Chehab +--------------------+ <-----+ +----------------------+ restart frame | 74577a7ad3SMauro Carvalho Chehab | QCI: run | | QCI: stop | --------------+ 75577a7ad3SMauro Carvalho Chehab | DMA: run | | DMA: stop | 76577a7ad3SMauro Carvalho Chehab +--------------------+ +----------------------+ 77577a7ad3SMauro Carvalho Chehab 78577a7ad3SMauro Carvalho Chehab Legend: - each box is a FSM state 79577a7ad3SMauro Carvalho Chehab - each arrow is the condition to transition to another state 80577a7ad3SMauro Carvalho Chehab - an arrow with a comment is a mandatory transition (no condition) 81577a7ad3SMauro Carvalho Chehab - arrow "Q" means : a buffer was enqueued 82577a7ad3SMauro Carvalho Chehab - arrow "DQ" means : a buffer was dequeued 83577a7ad3SMauro Carvalho Chehab - "QCI: stop" means the QCI interface is not enabled 84577a7ad3SMauro Carvalho Chehab - "DMA: stop" means all 3 DMA channels are stopped 85577a7ad3SMauro Carvalho Chehab - "DMA: run" means at least 1 DMA channel is still running 86577a7ad3SMauro Carvalho Chehab 87577a7ad3SMauro Carvalho ChehabDMA usage 88577a7ad3SMauro Carvalho Chehab--------- 89577a7ad3SMauro Carvalho Chehab 90577a7ad3SMauro Carvalho Chehaba) DMA flow 91577a7ad3SMauro Carvalho Chehab - first buffer queued for capture 92577a7ad3SMauro Carvalho Chehab Once a first buffer is queued for capture, the QCI is started, but data 93577a7ad3SMauro Carvalho Chehab transfer is not started. On "End Of Frame" interrupt, the irq handler 94577a7ad3SMauro Carvalho Chehab starts the DMA chain. 95577a7ad3SMauro Carvalho Chehab - capture of one videobuffer 96577a7ad3SMauro Carvalho Chehab The DMA chain starts transferring data into videobuffer RAM pages. 97577a7ad3SMauro Carvalho Chehab When all pages are transferred, the DMA irq is raised on "ENDINTR" status 98577a7ad3SMauro Carvalho Chehab - finishing one videobuffer 99577a7ad3SMauro Carvalho Chehab The DMA irq handler marks the videobuffer as "done", and removes it from 100577a7ad3SMauro Carvalho Chehab the active running queue 101577a7ad3SMauro Carvalho Chehab Meanwhile, the next videobuffer (if there is one), is transferred by DMA 102577a7ad3SMauro Carvalho Chehab - finishing the last videobuffer 103577a7ad3SMauro Carvalho Chehab On the DMA irq of the last videobuffer, the QCI is stopped. 104577a7ad3SMauro Carvalho Chehab 105577a7ad3SMauro Carvalho Chehabb) DMA prepared buffer will have this structure 106577a7ad3SMauro Carvalho Chehab 107577a7ad3SMauro Carvalho Chehab.. code-block:: none 108577a7ad3SMauro Carvalho Chehab 109577a7ad3SMauro Carvalho Chehab +------------+-----+---------------+-----------------+ 110577a7ad3SMauro Carvalho Chehab | desc-sg[0] | ... | desc-sg[last] | finisher/linker | 111577a7ad3SMauro Carvalho Chehab +------------+-----+---------------+-----------------+ 112577a7ad3SMauro Carvalho Chehab 113577a7ad3SMauro Carvalho ChehabThis structure is pointed by dma->sg_cpu. 114577a7ad3SMauro Carvalho ChehabThe descriptors are used as follows: 115577a7ad3SMauro Carvalho Chehab 116577a7ad3SMauro Carvalho Chehab- desc-sg[i]: i-th descriptor, transferring the i-th sg 117577a7ad3SMauro Carvalho Chehab element to the video buffer scatter gather 118577a7ad3SMauro Carvalho Chehab- finisher: has ddadr=DADDR_STOP, dcmd=ENDIRQEN 119577a7ad3SMauro Carvalho Chehab- linker: has ddadr= desc-sg[0] of next video buffer, dcmd=0 120577a7ad3SMauro Carvalho Chehab 121577a7ad3SMauro Carvalho ChehabFor the next schema, let's assume d0=desc-sg[0] .. dN=desc-sg[N], 122577a7ad3SMauro Carvalho Chehab"f" stands for finisher and "l" for linker. 123577a7ad3SMauro Carvalho ChehabA typical running chain is : 124577a7ad3SMauro Carvalho Chehab 125577a7ad3SMauro Carvalho Chehab.. code-block:: none 126577a7ad3SMauro Carvalho Chehab 127577a7ad3SMauro Carvalho Chehab Videobuffer 1 Videobuffer 2 128577a7ad3SMauro Carvalho Chehab +---------+----+---+ +----+----+----+---+ 129577a7ad3SMauro Carvalho Chehab | d0 | .. | dN | l | | d0 | .. | dN | f | 130577a7ad3SMauro Carvalho Chehab +---------+----+-|-+ ^----+----+----+---+ 131577a7ad3SMauro Carvalho Chehab | | 132577a7ad3SMauro Carvalho Chehab +----+ 133577a7ad3SMauro Carvalho Chehab 134577a7ad3SMauro Carvalho ChehabAfter the chaining is finished, the chain looks like : 135577a7ad3SMauro Carvalho Chehab 136577a7ad3SMauro Carvalho Chehab.. code-block:: none 137577a7ad3SMauro Carvalho Chehab 138577a7ad3SMauro Carvalho Chehab Videobuffer 1 Videobuffer 2 Videobuffer 3 139577a7ad3SMauro Carvalho Chehab +---------+----+---+ +----+----+----+---+ +----+----+----+---+ 140577a7ad3SMauro Carvalho Chehab | d0 | .. | dN | l | | d0 | .. | dN | l | | d0 | .. | dN | f | 141577a7ad3SMauro Carvalho Chehab +---------+----+-|-+ ^----+----+----+-|-+ ^----+----+----+---+ 142577a7ad3SMauro Carvalho Chehab | | | | 143577a7ad3SMauro Carvalho Chehab +----+ +----+ 144577a7ad3SMauro Carvalho Chehab new_link 145577a7ad3SMauro Carvalho Chehab 146577a7ad3SMauro Carvalho Chehabc) DMA hot chaining timeslice issue 147577a7ad3SMauro Carvalho Chehab 148577a7ad3SMauro Carvalho ChehabAs DMA chaining is done while DMA _is_ running, the linking may be done 149577a7ad3SMauro Carvalho Chehabwhile the DMA jumps from one Videobuffer to another. On the schema, that 150577a7ad3SMauro Carvalho Chehabwould be a problem if the following sequence is encountered : 151577a7ad3SMauro Carvalho Chehab 152577a7ad3SMauro Carvalho Chehab- DMA chain is Videobuffer1 + Videobuffer2 153577a7ad3SMauro Carvalho Chehab- pxa_videobuf_queue() is called to queue Videobuffer3 154577a7ad3SMauro Carvalho Chehab- DMA controller finishes Videobuffer2, and DMA stops 155577a7ad3SMauro Carvalho Chehab 156577a7ad3SMauro Carvalho Chehab.. code-block:: none 157577a7ad3SMauro Carvalho Chehab 158577a7ad3SMauro Carvalho Chehab => 159577a7ad3SMauro Carvalho Chehab Videobuffer 1 Videobuffer 2 160577a7ad3SMauro Carvalho Chehab +---------+----+---+ +----+----+----+---+ 161577a7ad3SMauro Carvalho Chehab | d0 | .. | dN | l | | d0 | .. | dN | f | 162577a7ad3SMauro Carvalho Chehab +---------+----+-|-+ ^----+----+----+-^-+ 163577a7ad3SMauro Carvalho Chehab | | | 164577a7ad3SMauro Carvalho Chehab +----+ +-- DMA DDADR loads DDADR_STOP 165577a7ad3SMauro Carvalho Chehab 166577a7ad3SMauro Carvalho Chehab- pxa_dma_add_tail_buf() is called, the Videobuffer2 "finisher" is 167577a7ad3SMauro Carvalho Chehab replaced by a "linker" to Videobuffer3 (creation of new_link) 168577a7ad3SMauro Carvalho Chehab- pxa_videobuf_queue() finishes 169577a7ad3SMauro Carvalho Chehab- the DMA irq handler is called, which terminates Videobuffer2 170577a7ad3SMauro Carvalho Chehab- Videobuffer3 capture is not scheduled on DMA chain (as it stopped !!!) 171577a7ad3SMauro Carvalho Chehab 172577a7ad3SMauro Carvalho Chehab.. code-block:: none 173577a7ad3SMauro Carvalho Chehab 174577a7ad3SMauro Carvalho Chehab Videobuffer 1 Videobuffer 2 Videobuffer 3 175577a7ad3SMauro Carvalho Chehab +---------+----+---+ +----+----+----+---+ +----+----+----+---+ 176577a7ad3SMauro Carvalho Chehab | d0 | .. | dN | l | | d0 | .. | dN | l | | d0 | .. | dN | f | 177577a7ad3SMauro Carvalho Chehab +---------+----+-|-+ ^----+----+----+-|-+ ^----+----+----+---+ 178577a7ad3SMauro Carvalho Chehab | | | | 179577a7ad3SMauro Carvalho Chehab +----+ +----+ 180577a7ad3SMauro Carvalho Chehab new_link 181577a7ad3SMauro Carvalho Chehab DMA DDADR still is DDADR_STOP 182577a7ad3SMauro Carvalho Chehab 183577a7ad3SMauro Carvalho Chehab- pxa_camera_check_link_miss() is called 184577a7ad3SMauro Carvalho Chehab This checks if the DMA is finished and a buffer is still on the 185577a7ad3SMauro Carvalho Chehab pcdev->capture list. If that's the case, the capture will be restarted, 186577a7ad3SMauro Carvalho Chehab and Videobuffer3 is scheduled on DMA chain. 187577a7ad3SMauro Carvalho Chehab- the DMA irq handler finishes 188577a7ad3SMauro Carvalho Chehab 189577a7ad3SMauro Carvalho Chehab.. note:: 190577a7ad3SMauro Carvalho Chehab 191577a7ad3SMauro Carvalho Chehab If DMA stops just after pxa_camera_check_link_miss() reads DDADR() 192577a7ad3SMauro Carvalho Chehab value, we have the guarantee that the DMA irq handler will be called back 193577a7ad3SMauro Carvalho Chehab when the DMA will finish the buffer, and pxa_camera_check_link_miss() will 194577a7ad3SMauro Carvalho Chehab be called again, to reschedule Videobuffer3. 195