xref: /OK3568_Linux_fs/kernel/Documentation/driver-api/media/drivers/pxa_camera.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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