brintos

brintos / linux-shallow public Read only

0
0
Text · 8.5 KiB · 4691991 Raw
195 lines · plain
1.. SPDX-License-Identifier: GPL-2.02 3PXA-Camera Host Driver4======================5 6Author: Robert Jarzmik <robert.jarzmik@free.fr>7 8Constraints9-----------10 11a) Image size for YUV422P format12   All YUV422P images are enforced to have width x height % 16 = 0.13   This is due to DMA constraints, which transfers only planes of 8 byte14   multiples.15 16 17Global video workflow18---------------------19 20a) QCI stopped21   Initially, the QCI interface is stopped.22   When a buffer is queued, start_streaming is called and the QCI starts.23 24b) QCI started25   More buffers can be queued while the QCI is started without halting the26   capture.  The new buffers are "appended" at the tail of the DMA chain, and27   smoothly captured one frame after the other.28 29   Once a buffer is filled in the QCI interface, it is marked as "DONE" and30   removed from the active buffers list. It can be then requeud or dequeued by31   userland application.32 33   Once the last buffer is filled in, the QCI interface stops.34 35c) Capture global finite state machine schema36 37.. code-block:: none38 39	+----+                             +---+  +----+40	| DQ |                             | Q |  | DQ |41	|    v                             |   v  |    v42	+-----------+                     +------------------------+43	|   STOP    |                     | Wait for capture start |44	+-----------+         Q           +------------------------+45	+-> | QCI: stop | ------------------> | QCI: run               | <------------+46	|   | DMA: stop |                     | DMA: stop              |              |47	|   +-----------+             +-----> +------------------------+              |48	|                            /                            |                   |49	|                           /             +---+  +----+   |                   |50	|capture list empty        /              | Q |  | DQ |   | QCI Irq EOF       |51	|                         /               |   v  |    v   v                   |52	|   +--------------------+             +----------------------+               |53	|   | DMA hotlink missed |             |    Capture running   |               |54	|   +--------------------+             +----------------------+               |55	|   | QCI: run           |     +-----> | QCI: run             | <-+           |56	|   | DMA: stop          |    /        | DMA: run             |   |           |57	|   +--------------------+   /         +----------------------+   | Other     |58	|     ^                     /DMA still            |               | channels  |59	|     | capture list       /  running             | DMA Irq End   | not       |60	|     | not empty         /                       |               | finished  |61	|     |                  /                        v               | yet       |62	|   +----------------------+           +----------------------+   |           |63	|   |  Videobuf released   |           |  Channel completed   |   |           |64	|   +----------------------+           +----------------------+   |           |65	+-- | QCI: run             |           | QCI: run             | --+           |66	| DMA: run             |           | DMA: run             |               |67	+----------------------+           +----------------------+               |68		^                      /           |                           |69		|          no overrun /            | overrun                   |70		|                    /             v                           |71	+--------------------+         /   +----------------------+               |72	|  Frame completed   |        /    |     Frame overran    |               |73	+--------------------+ <-----+     +----------------------+ restart frame |74	| QCI: run           |             | QCI: stop            | --------------+75	| DMA: run           |             | DMA: stop            |76	+--------------------+             +----------------------+77 78	Legend: - each box is a FSM state79		- each arrow is the condition to transition to another state80		- an arrow with a comment is a mandatory transition (no condition)81		- arrow "Q" means : a buffer was enqueued82		- arrow "DQ" means : a buffer was dequeued83		- "QCI: stop" means the QCI interface is not enabled84		- "DMA: stop" means all 3 DMA channels are stopped85		- "DMA: run" means at least 1 DMA channel is still running86 87DMA usage88---------89 90a) DMA flow91     - first buffer queued for capture92       Once a first buffer is queued for capture, the QCI is started, but data93       transfer is not started. On "End Of Frame" interrupt, the irq handler94       starts the DMA chain.95     - capture of one videobuffer96       The DMA chain starts transferring data into videobuffer RAM pages.97       When all pages are transferred, the DMA irq is raised on "ENDINTR" status98     - finishing one videobuffer99       The DMA irq handler marks the videobuffer as "done", and removes it from100       the active running queue101       Meanwhile, the next videobuffer (if there is one), is transferred by DMA102     - finishing the last videobuffer103       On the DMA irq of the last videobuffer, the QCI is stopped.104 105b) DMA prepared buffer will have this structure106 107.. code-block:: none108 109     +------------+-----+---------------+-----------------+110     | desc-sg[0] | ... | desc-sg[last] | finisher/linker |111     +------------+-----+---------------+-----------------+112 113This structure is pointed by dma->sg_cpu.114The descriptors are used as follows:115 116- desc-sg[i]: i-th descriptor, transferring the i-th sg117  element to the video buffer scatter gather118- finisher: has ddadr=DADDR_STOP, dcmd=ENDIRQEN119- linker: has ddadr= desc-sg[0] of next video buffer, dcmd=0120 121For the next schema, let's assume d0=desc-sg[0] .. dN=desc-sg[N],122"f" stands for finisher and "l" for linker.123A typical running chain is :124 125.. code-block:: none126 127         Videobuffer 1         Videobuffer 2128     +---------+----+---+  +----+----+----+---+129     | d0 | .. | dN | l |  | d0 | .. | dN | f |130     +---------+----+-|-+  ^----+----+----+---+131                      |    |132                      +----+133 134After the chaining is finished, the chain looks like :135 136.. code-block:: none137 138         Videobuffer 1         Videobuffer 2         Videobuffer 3139     +---------+----+---+  +----+----+----+---+  +----+----+----+---+140     | d0 | .. | dN | l |  | d0 | .. | dN | l |  | d0 | .. | dN | f |141     +---------+----+-|-+  ^----+----+----+-|-+  ^----+----+----+---+142                      |    |                |    |143                      +----+                +----+144                                           new_link145 146c) DMA hot chaining timeslice issue147 148As DMA chaining is done while DMA _is_ running, the linking may be done149while the DMA jumps from one Videobuffer to another. On the schema, that150would be a problem if the following sequence is encountered :151 152- DMA chain is Videobuffer1 + Videobuffer2153- pxa_videobuf_queue() is called to queue Videobuffer3154- DMA controller finishes Videobuffer2, and DMA stops155 156.. code-block:: none157 158      =>159         Videobuffer 1         Videobuffer 2160     +---------+----+---+  +----+----+----+---+161     | d0 | .. | dN | l |  | d0 | .. | dN | f |162     +---------+----+-|-+  ^----+----+----+-^-+163                      |    |                |164                      +----+                +-- DMA DDADR loads DDADR_STOP165 166- pxa_dma_add_tail_buf() is called, the Videobuffer2 "finisher" is167  replaced by a "linker" to Videobuffer3 (creation of new_link)168- pxa_videobuf_queue() finishes169- the DMA irq handler is called, which terminates Videobuffer2170- Videobuffer3 capture is not scheduled on DMA chain (as it stopped !!!)171 172.. code-block:: none173 174         Videobuffer 1         Videobuffer 2         Videobuffer 3175     +---------+----+---+  +----+----+----+---+  +----+----+----+---+176     | d0 | .. | dN | l |  | d0 | .. | dN | l |  | d0 | .. | dN | f |177     +---------+----+-|-+  ^----+----+----+-|-+  ^----+----+----+---+178                      |    |                |    |179                      +----+                +----+180                                           new_link181                                          DMA DDADR still is DDADR_STOP182 183- pxa_camera_check_link_miss() is called184  This checks if the DMA is finished and a buffer is still on the185  pcdev->capture list. If that's the case, the capture will be restarted,186  and Videobuffer3 is scheduled on DMA chain.187- the DMA irq handler finishes188 189.. note::190 191     If DMA stops just after pxa_camera_check_link_miss() reads DDADR()192     value, we have the guarantee that the DMA irq handler will be called back193     when the DMA will finish the buffer, and pxa_camera_check_link_miss() will194     be called again, to reschedule Videobuffer3.195