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