Back to home page

OSCL-LXR

 
 

    


0001 .. SPDX-License-Identifier: GPL-2.0
0002 
0003 PXA-Camera Host Driver
0004 ======================
0005 
0006 Author: Robert Jarzmik <robert.jarzmik@free.fr>
0007 
0008 Constraints
0009 -----------
0010 
0011 a) Image size for YUV422P format
0012    All YUV422P images are enforced to have width x height % 16 = 0.
0013    This is due to DMA constraints, which transfers only planes of 8 byte
0014    multiples.
0015 
0016 
0017 Global video workflow
0018 ---------------------
0019 
0020 a) QCI stopped
0021    Initially, the QCI interface is stopped.
0022    When a buffer is queued (pxa_videobuf_ops->buf_queue), the QCI starts.
0023 
0024 b) QCI started
0025    More buffers can be queued while the QCI is started without halting the
0026    capture.  The new buffers are "appended" at the tail of the DMA chain, and
0027    smoothly captured one frame after the other.
0028 
0029    Once a buffer is filled in the QCI interface, it is marked as "DONE" and
0030    removed from the active buffers list. It can be then requeud or dequeued by
0031    userland application.
0032 
0033    Once the last buffer is filled in, the QCI interface stops.
0034 
0035 c) Capture global finite state machine schema
0036 
0037 .. code-block:: none
0038 
0039         +----+                             +---+  +----+
0040         | DQ |                             | Q |  | DQ |
0041         |    v                             |   v  |    v
0042         +-----------+                     +------------------------+
0043         |   STOP    |                     | Wait for capture start |
0044         +-----------+         Q           +------------------------+
0045         +-> | QCI: stop | ------------------> | QCI: run               | <------------+
0046         |   | DMA: stop |                     | DMA: stop              |              |
0047         |   +-----------+             +-----> +------------------------+              |
0048         |                            /                            |                   |
0049         |                           /             +---+  +----+   |                   |
0050         |capture list empty        /              | Q |  | DQ |   | QCI Irq EOF       |
0051         |                         /               |   v  |    v   v                   |
0052         |   +--------------------+             +----------------------+               |
0053         |   | DMA hotlink missed |             |    Capture running   |               |
0054         |   +--------------------+             +----------------------+               |
0055         |   | QCI: run           |     +-----> | QCI: run             | <-+           |
0056         |   | DMA: stop          |    /        | DMA: run             |   |           |
0057         |   +--------------------+   /         +----------------------+   | Other     |
0058         |     ^                     /DMA still            |               | channels  |
0059         |     | capture list       /  running             | DMA Irq End   | not       |
0060         |     | not empty         /                       |               | finished  |
0061         |     |                  /                        v               | yet       |
0062         |   +----------------------+           +----------------------+   |           |
0063         |   |  Videobuf released   |           |  Channel completed   |   |           |
0064         |   +----------------------+           +----------------------+   |           |
0065         +-- | QCI: run             |           | QCI: run             | --+           |
0066         | DMA: run             |           | DMA: run             |               |
0067         +----------------------+           +----------------------+               |
0068                 ^                      /           |                           |
0069                 |          no overrun /            | overrun                   |
0070                 |                    /             v                           |
0071         +--------------------+         /   +----------------------+               |
0072         |  Frame completed   |        /    |     Frame overran    |               |
0073         +--------------------+ <-----+     +----------------------+ restart frame |
0074         | QCI: run           |             | QCI: stop            | --------------+
0075         | DMA: run           |             | DMA: stop            |
0076         +--------------------+             +----------------------+
0077 
0078         Legend: - each box is a FSM state
0079                 - each arrow is the condition to transition to another state
0080                 - an arrow with a comment is a mandatory transition (no condition)
0081                 - arrow "Q" means : a buffer was enqueued
0082                 - arrow "DQ" means : a buffer was dequeued
0083                 - "QCI: stop" means the QCI interface is not enabled
0084                 - "DMA: stop" means all 3 DMA channels are stopped
0085                 - "DMA: run" means at least 1 DMA channel is still running
0086 
0087 DMA usage
0088 ---------
0089 
0090 a) DMA flow
0091      - first buffer queued for capture
0092        Once a first buffer is queued for capture, the QCI is started, but data
0093        transfer is not started. On "End Of Frame" interrupt, the irq handler
0094        starts the DMA chain.
0095      - capture of one videobuffer
0096        The DMA chain starts transferring data into videobuffer RAM pages.
0097        When all pages are transferred, the DMA irq is raised on "ENDINTR" status
0098      - finishing one videobuffer
0099        The DMA irq handler marks the videobuffer as "done", and removes it from
0100        the active running queue
0101        Meanwhile, the next videobuffer (if there is one), is transferred by DMA
0102      - finishing the last videobuffer
0103        On the DMA irq of the last videobuffer, the QCI is stopped.
0104 
0105 b) DMA prepared buffer will have this structure
0106 
0107 .. code-block:: none
0108 
0109      +------------+-----+---------------+-----------------+
0110      | desc-sg[0] | ... | desc-sg[last] | finisher/linker |
0111      +------------+-----+---------------+-----------------+
0112 
0113 This structure is pointed by dma->sg_cpu.
0114 The descriptors are used as follows:
0115 
0116 - desc-sg[i]: i-th descriptor, transferring the i-th sg
0117   element to the video buffer scatter gather
0118 - finisher: has ddadr=DADDR_STOP, dcmd=ENDIRQEN
0119 - linker: has ddadr= desc-sg[0] of next video buffer, dcmd=0
0120 
0121 For the next schema, let's assume d0=desc-sg[0] .. dN=desc-sg[N],
0122 "f" stands for finisher and "l" for linker.
0123 A typical running chain is :
0124 
0125 .. code-block:: none
0126 
0127          Videobuffer 1         Videobuffer 2
0128      +---------+----+---+  +----+----+----+---+
0129      | d0 | .. | dN | l |  | d0 | .. | dN | f |
0130      +---------+----+-|-+  ^----+----+----+---+
0131                       |    |
0132                       +----+
0133 
0134 After the chaining is finished, the chain looks like :
0135 
0136 .. code-block:: none
0137 
0138          Videobuffer 1         Videobuffer 2         Videobuffer 3
0139      +---------+----+---+  +----+----+----+---+  +----+----+----+---+
0140      | d0 | .. | dN | l |  | d0 | .. | dN | l |  | d0 | .. | dN | f |
0141      +---------+----+-|-+  ^----+----+----+-|-+  ^----+----+----+---+
0142                       |    |                |    |
0143                       +----+                +----+
0144                                            new_link
0145 
0146 c) DMA hot chaining timeslice issue
0147 
0148 As DMA chaining is done while DMA _is_ running, the linking may be done
0149 while the DMA jumps from one Videobuffer to another. On the schema, that
0150 would be a problem if the following sequence is encountered :
0151 
0152 - DMA chain is Videobuffer1 + Videobuffer2
0153 - pxa_videobuf_queue() is called to queue Videobuffer3
0154 - DMA controller finishes Videobuffer2, and DMA stops
0155 
0156 .. code-block:: none
0157 
0158       =>
0159          Videobuffer 1         Videobuffer 2
0160      +---------+----+---+  +----+----+----+---+
0161      | d0 | .. | dN | l |  | d0 | .. | dN | f |
0162      +---------+----+-|-+  ^----+----+----+-^-+
0163                       |    |                |
0164                       +----+                +-- DMA DDADR loads DDADR_STOP
0165 
0166 - pxa_dma_add_tail_buf() is called, the Videobuffer2 "finisher" is
0167   replaced by a "linker" to Videobuffer3 (creation of new_link)
0168 - pxa_videobuf_queue() finishes
0169 - the DMA irq handler is called, which terminates Videobuffer2
0170 - Videobuffer3 capture is not scheduled on DMA chain (as it stopped !!!)
0171 
0172 .. code-block:: none
0173 
0174          Videobuffer 1         Videobuffer 2         Videobuffer 3
0175      +---------+----+---+  +----+----+----+---+  +----+----+----+---+
0176      | d0 | .. | dN | l |  | d0 | .. | dN | l |  | d0 | .. | dN | f |
0177      +---------+----+-|-+  ^----+----+----+-|-+  ^----+----+----+---+
0178                       |    |                |    |
0179                       +----+                +----+
0180                                            new_link
0181                                           DMA DDADR still is DDADR_STOP
0182 
0183 - pxa_camera_check_link_miss() is called
0184   This checks if the DMA is finished and a buffer is still on the
0185   pcdev->capture list. If that's the case, the capture will be restarted,
0186   and Videobuffer3 is scheduled on DMA chain.
0187 - the DMA irq handler finishes
0188 
0189 .. note::
0190 
0191      If DMA stops just after pxa_camera_check_link_miss() reads DDADR()
0192      value, we have the guarantee that the DMA irq handler will be called back
0193      when the DMA will finish the buffer, and pxa_camera_check_link_miss() will
0194      be called again, to reschedule Videobuffer3.