1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun 3*4882a593SmuzhiyunPXA-Camera Host Driver 4*4882a593Smuzhiyun====================== 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunAuthor: Robert Jarzmik <robert.jarzmik@free.fr> 7*4882a593Smuzhiyun 8*4882a593SmuzhiyunConstraints 9*4882a593Smuzhiyun----------- 10*4882a593Smuzhiyun 11*4882a593Smuzhiyuna) Image size for YUV422P format 12*4882a593Smuzhiyun All YUV422P images are enforced to have width x height % 16 = 0. 13*4882a593Smuzhiyun This is due to DMA constraints, which transfers only planes of 8 byte 14*4882a593Smuzhiyun multiples. 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun 17*4882a593SmuzhiyunGlobal video workflow 18*4882a593Smuzhiyun--------------------- 19*4882a593Smuzhiyun 20*4882a593Smuzhiyuna) QCI stopped 21*4882a593Smuzhiyun Initially, the QCI interface is stopped. 22*4882a593Smuzhiyun When a buffer is queued (pxa_videobuf_ops->buf_queue), the QCI starts. 23*4882a593Smuzhiyun 24*4882a593Smuzhiyunb) QCI started 25*4882a593Smuzhiyun More buffers can be queued while the QCI is started without halting the 26*4882a593Smuzhiyun capture. The new buffers are "appended" at the tail of the DMA chain, and 27*4882a593Smuzhiyun smoothly captured one frame after the other. 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun Once a buffer is filled in the QCI interface, it is marked as "DONE" and 30*4882a593Smuzhiyun removed from the active buffers list. It can be then requeud or dequeued by 31*4882a593Smuzhiyun userland application. 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun Once the last buffer is filled in, the QCI interface stops. 34*4882a593Smuzhiyun 35*4882a593Smuzhiyunc) Capture global finite state machine schema 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun.. code-block:: none 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun +----+ +---+ +----+ 40*4882a593Smuzhiyun | DQ | | Q | | DQ | 41*4882a593Smuzhiyun | v | v | v 42*4882a593Smuzhiyun +-----------+ +------------------------+ 43*4882a593Smuzhiyun | STOP | | Wait for capture start | 44*4882a593Smuzhiyun +-----------+ Q +------------------------+ 45*4882a593Smuzhiyun +-> | QCI: stop | ------------------> | QCI: run | <------------+ 46*4882a593Smuzhiyun | | DMA: stop | | DMA: stop | | 47*4882a593Smuzhiyun | +-----------+ +-----> +------------------------+ | 48*4882a593Smuzhiyun | / | | 49*4882a593Smuzhiyun | / +---+ +----+ | | 50*4882a593Smuzhiyun |capture list empty / | Q | | DQ | | QCI Irq EOF | 51*4882a593Smuzhiyun | / | v | v v | 52*4882a593Smuzhiyun | +--------------------+ +----------------------+ | 53*4882a593Smuzhiyun | | DMA hotlink missed | | Capture running | | 54*4882a593Smuzhiyun | +--------------------+ +----------------------+ | 55*4882a593Smuzhiyun | | QCI: run | +-----> | QCI: run | <-+ | 56*4882a593Smuzhiyun | | DMA: stop | / | DMA: run | | | 57*4882a593Smuzhiyun | +--------------------+ / +----------------------+ | Other | 58*4882a593Smuzhiyun | ^ /DMA still | | channels | 59*4882a593Smuzhiyun | | capture list / running | DMA Irq End | not | 60*4882a593Smuzhiyun | | not empty / | | finished | 61*4882a593Smuzhiyun | | / v | yet | 62*4882a593Smuzhiyun | +----------------------+ +----------------------+ | | 63*4882a593Smuzhiyun | | Videobuf released | | Channel completed | | | 64*4882a593Smuzhiyun | +----------------------+ +----------------------+ | | 65*4882a593Smuzhiyun +-- | QCI: run | | QCI: run | --+ | 66*4882a593Smuzhiyun | DMA: run | | DMA: run | | 67*4882a593Smuzhiyun +----------------------+ +----------------------+ | 68*4882a593Smuzhiyun ^ / | | 69*4882a593Smuzhiyun | no overrun / | overrun | 70*4882a593Smuzhiyun | / v | 71*4882a593Smuzhiyun +--------------------+ / +----------------------+ | 72*4882a593Smuzhiyun | Frame completed | / | Frame overran | | 73*4882a593Smuzhiyun +--------------------+ <-----+ +----------------------+ restart frame | 74*4882a593Smuzhiyun | QCI: run | | QCI: stop | --------------+ 75*4882a593Smuzhiyun | DMA: run | | DMA: stop | 76*4882a593Smuzhiyun +--------------------+ +----------------------+ 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun Legend: - each box is a FSM state 79*4882a593Smuzhiyun - each arrow is the condition to transition to another state 80*4882a593Smuzhiyun - an arrow with a comment is a mandatory transition (no condition) 81*4882a593Smuzhiyun - arrow "Q" means : a buffer was enqueued 82*4882a593Smuzhiyun - arrow "DQ" means : a buffer was dequeued 83*4882a593Smuzhiyun - "QCI: stop" means the QCI interface is not enabled 84*4882a593Smuzhiyun - "DMA: stop" means all 3 DMA channels are stopped 85*4882a593Smuzhiyun - "DMA: run" means at least 1 DMA channel is still running 86*4882a593Smuzhiyun 87*4882a593SmuzhiyunDMA usage 88*4882a593Smuzhiyun--------- 89*4882a593Smuzhiyun 90*4882a593Smuzhiyuna) DMA flow 91*4882a593Smuzhiyun - first buffer queued for capture 92*4882a593Smuzhiyun Once a first buffer is queued for capture, the QCI is started, but data 93*4882a593Smuzhiyun transfer is not started. On "End Of Frame" interrupt, the irq handler 94*4882a593Smuzhiyun starts the DMA chain. 95*4882a593Smuzhiyun - capture of one videobuffer 96*4882a593Smuzhiyun The DMA chain starts transferring data into videobuffer RAM pages. 97*4882a593Smuzhiyun When all pages are transferred, the DMA irq is raised on "ENDINTR" status 98*4882a593Smuzhiyun - finishing one videobuffer 99*4882a593Smuzhiyun The DMA irq handler marks the videobuffer as "done", and removes it from 100*4882a593Smuzhiyun the active running queue 101*4882a593Smuzhiyun Meanwhile, the next videobuffer (if there is one), is transferred by DMA 102*4882a593Smuzhiyun - finishing the last videobuffer 103*4882a593Smuzhiyun On the DMA irq of the last videobuffer, the QCI is stopped. 104*4882a593Smuzhiyun 105*4882a593Smuzhiyunb) DMA prepared buffer will have this structure 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun.. code-block:: none 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun +------------+-----+---------------+-----------------+ 110*4882a593Smuzhiyun | desc-sg[0] | ... | desc-sg[last] | finisher/linker | 111*4882a593Smuzhiyun +------------+-----+---------------+-----------------+ 112*4882a593Smuzhiyun 113*4882a593SmuzhiyunThis structure is pointed by dma->sg_cpu. 114*4882a593SmuzhiyunThe descriptors are used as follows: 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun- desc-sg[i]: i-th descriptor, transferring the i-th sg 117*4882a593Smuzhiyun element to the video buffer scatter gather 118*4882a593Smuzhiyun- finisher: has ddadr=DADDR_STOP, dcmd=ENDIRQEN 119*4882a593Smuzhiyun- linker: has ddadr= desc-sg[0] of next video buffer, dcmd=0 120*4882a593Smuzhiyun 121*4882a593SmuzhiyunFor the next schema, let's assume d0=desc-sg[0] .. dN=desc-sg[N], 122*4882a593Smuzhiyun"f" stands for finisher and "l" for linker. 123*4882a593SmuzhiyunA typical running chain is : 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun.. code-block:: none 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun Videobuffer 1 Videobuffer 2 128*4882a593Smuzhiyun +---------+----+---+ +----+----+----+---+ 129*4882a593Smuzhiyun | d0 | .. | dN | l | | d0 | .. | dN | f | 130*4882a593Smuzhiyun +---------+----+-|-+ ^----+----+----+---+ 131*4882a593Smuzhiyun | | 132*4882a593Smuzhiyun +----+ 133*4882a593Smuzhiyun 134*4882a593SmuzhiyunAfter the chaining is finished, the chain looks like : 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun.. code-block:: none 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun Videobuffer 1 Videobuffer 2 Videobuffer 3 139*4882a593Smuzhiyun +---------+----+---+ +----+----+----+---+ +----+----+----+---+ 140*4882a593Smuzhiyun | d0 | .. | dN | l | | d0 | .. | dN | l | | d0 | .. | dN | f | 141*4882a593Smuzhiyun +---------+----+-|-+ ^----+----+----+-|-+ ^----+----+----+---+ 142*4882a593Smuzhiyun | | | | 143*4882a593Smuzhiyun +----+ +----+ 144*4882a593Smuzhiyun new_link 145*4882a593Smuzhiyun 146*4882a593Smuzhiyunc) DMA hot chaining timeslice issue 147*4882a593Smuzhiyun 148*4882a593SmuzhiyunAs DMA chaining is done while DMA _is_ running, the linking may be done 149*4882a593Smuzhiyunwhile the DMA jumps from one Videobuffer to another. On the schema, that 150*4882a593Smuzhiyunwould be a problem if the following sequence is encountered : 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun- DMA chain is Videobuffer1 + Videobuffer2 153*4882a593Smuzhiyun- pxa_videobuf_queue() is called to queue Videobuffer3 154*4882a593Smuzhiyun- DMA controller finishes Videobuffer2, and DMA stops 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun.. code-block:: none 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun => 159*4882a593Smuzhiyun Videobuffer 1 Videobuffer 2 160*4882a593Smuzhiyun +---------+----+---+ +----+----+----+---+ 161*4882a593Smuzhiyun | d0 | .. | dN | l | | d0 | .. | dN | f | 162*4882a593Smuzhiyun +---------+----+-|-+ ^----+----+----+-^-+ 163*4882a593Smuzhiyun | | | 164*4882a593Smuzhiyun +----+ +-- DMA DDADR loads DDADR_STOP 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun- pxa_dma_add_tail_buf() is called, the Videobuffer2 "finisher" is 167*4882a593Smuzhiyun replaced by a "linker" to Videobuffer3 (creation of new_link) 168*4882a593Smuzhiyun- pxa_videobuf_queue() finishes 169*4882a593Smuzhiyun- the DMA irq handler is called, which terminates Videobuffer2 170*4882a593Smuzhiyun- Videobuffer3 capture is not scheduled on DMA chain (as it stopped !!!) 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun.. code-block:: none 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun Videobuffer 1 Videobuffer 2 Videobuffer 3 175*4882a593Smuzhiyun +---------+----+---+ +----+----+----+---+ +----+----+----+---+ 176*4882a593Smuzhiyun | d0 | .. | dN | l | | d0 | .. | dN | l | | d0 | .. | dN | f | 177*4882a593Smuzhiyun +---------+----+-|-+ ^----+----+----+-|-+ ^----+----+----+---+ 178*4882a593Smuzhiyun | | | | 179*4882a593Smuzhiyun +----+ +----+ 180*4882a593Smuzhiyun new_link 181*4882a593Smuzhiyun DMA DDADR still is DDADR_STOP 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun- pxa_camera_check_link_miss() is called 184*4882a593Smuzhiyun This checks if the DMA is finished and a buffer is still on the 185*4882a593Smuzhiyun pcdev->capture list. If that's the case, the capture will be restarted, 186*4882a593Smuzhiyun and Videobuffer3 is scheduled on DMA chain. 187*4882a593Smuzhiyun- the DMA irq handler finishes 188*4882a593Smuzhiyun 189*4882a593Smuzhiyun.. note:: 190*4882a593Smuzhiyun 191*4882a593Smuzhiyun If DMA stops just after pxa_camera_check_link_miss() reads DDADR() 192*4882a593Smuzhiyun value, we have the guarantee that the DMA irq handler will be called back 193*4882a593Smuzhiyun when the DMA will finish the buffer, and pxa_camera_check_link_miss() will 194*4882a593Smuzhiyun be called again, to reschedule Videobuffer3. 195