]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
media: tegra: Add docs for Tegra V4L2 camera
authorAndrew Chew <achew@nvidia.com>
Mon, 6 Aug 2012 21:43:09 +0000 (14:43 -0700)
committerDan Willemsen <dwillemsen@nvidia.com>
Sat, 14 Sep 2013 19:39:00 +0000 (12:39 -0700)
This readme describes theory of operations of the Tegra camera host driver.

Signed-off-by: Andrew Chew <achew@nvidia.com>
Change-Id: I9e6f761cd60f5b8a537174290df21fb85f016dca
Reviewed-on: http://git-master/r/145347
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Allen Martin <amartin@nvidia.com>
Rebase-Id: R1061406eb5ae03b04863f8605b328294e37079de

Documentation/video4linux/README.tegra [new file with mode: 0644]

diff --git a/Documentation/video4linux/README.tegra b/Documentation/video4linux/README.tegra
new file mode 100644 (file)
index 0000000..610eede
--- /dev/null
@@ -0,0 +1,180 @@
+Theory of Operations
+====================
+
+There are three separate drivers within the V4L2 framework that are interesting
+to Tegra-based platforms.  They are as follows:
+
+Image Sensor driver
+===================
+This driver communicates only with the image sensor hardware (typically via
+I2C transactions), and is intentionally PLATFORM-AGNOSTIC.  Existing image
+sensor drivers can be found in drivers/media/video.  For example, the ov9740
+driver communicates with the Omnivision OV9740 image sensor with built-in ISP.
+
+Some of the things that this driver is responsible for are:
+
+Setting up the proper output format of the image sensor,
+
+Setting up image output extents
+
+Setting up capture and crop regions
+
+Camera Host driver
+==================
+This driver communicates only with the camera controller on a given platform,
+and is intentionally IMAGE-SENSOR-AGNOSTIC.  Existing camera host drivers
+can be found in drivers/media/video, of which tegra_v4l2_camera.c is the
+example that is interesting to us.  This camera host driver knows how to
+program the CSI/VI block on Tegra2 and Tegra3 platforms.
+
+Some of the things that this driver is responsible for are:
+
+Setting up the proper input format (image frame data flowing from the image
+sensor to the camera host),
+
+Setting up the proper output format (image frame data flowing from the
+camera host to system memory),
+
+Programming the DMA destination to receive the image frame data,
+
+Starting and stopping the reception of image frame data.
+
+Videobuf driver
+===============
+This driver is responsible for the allocation and deallocation of buffers that
+are used to hold image frame data.  Different camera hosts have different
+DMA requirements, which makes it necessary to allow for different methods of
+buffer allocation.  For example, the Tegra2 and Tegra3 camera host cannot
+DMA via a scatter-gather list, so the image frame buffers must be physically
+contiguous.  The videobuf-dma-contig.c videobuf driver can be found in
+drivers/media/video, and contains a videobuf implementation that allocates
+physically contiguous regions.  One can also have a videobuf driver that
+uses a different allocator like nvmap.
+
+The nvhost driver and Syncpts
+=============================
+
+The camera host driver (tegra_v4l2_camera) has a dependency on the nvhost
+driver/subsystem in order to make use of syncpts.  In other words, the camera
+host driver is a client of nvhost.
+
+A syncpt is essentially an incrementing hardware counter that triggers an
+interrupt when a certain number (or threshold) is reached.  The interrupt,
+however, is hidden from clients of nvhost.  Instead, asynchronous completion
+notification is done via calling an nvhost  routine that goes to sleep, and
+wakes up upon completion.
+
+Tegra has a number of syncpts that serve various purposes.  The two syncpts
+that are used by the camera host driver are the VI and CSI syncpts.  Other
+syncpts are used in display, etc.
+
+A syncpt increments when a certain hardware condition is met.
+
+The public operations available for a syncpt are:
+
+nvhost_syncpt_read_ext(syncpt_id) - Read the current syncpt counter value.
+nvhost_syncpt_wait_timeout_ext(syncpt_id, threshold, timeout) - Go to sleep
+    until the syncpt value reaches the threshold, or until the timeout
+    expires.
+nvhost_syncpt_cpu_incr_ext(syncpt_id) - Manually increment a syncpt.
+
+Syncpts are used in the camera host driver in order to signify the completion
+of an operation.  The typical usage case can be illustrated by summarizing
+the steps that the camera host driver takes in capturing a single frame
+(this is called one-shot mode, where we program up each frame transfer
+separately):
+
+0) At the very start, read the current syncpt values and remember them.  See
+   tegra_camera_activate() -> tegra_camera_save_syncpts(), where we read
+   the current values and store them in pcdev->syncpt_csi and pcdev->syncpt_vi.
+
+1) Program the camera host registers to prepare to receive frames from the
+   image sensor using the proper input format.  Note that we are at this
+   point NOT telling the camera host to DMA a frame.  That comes later.  See
+   tegra_camera_capture_setup(), where we do a whole bunch of magical
+   register writes depending on our input format, output format, image extents,
+   etc.
+
+2) Increment our remembered copies of the current syncpt values according to
+   how many syncpt increments we are expecting for the given operation we
+   want to perform.  For capturing a single frame, we are expecting a single
+   increment on the CSI syncpt when the reception of the frame is complete, and
+   a single increment on the VI syncpt when the DMA of the frame is complete.
+   See tegra_camera_capture_start(), where we increment pcdev->syncpt_csi
+   and pcdev->syncpt_vi.
+
+3) Program the DMA destination registers, and toggle the bit in
+   TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND to do the DMA on the next available
+   frame.  See tegra_camera_capture_start() for this.
+
+4) Call nvhost_syncpt_wait_timeout_ext() to wait on the CSI syncpt threshold.
+   Remember that we incremented our local syncpt values in step 2.  Those
+   new values become the threshold to wait for.  See
+   tegra_camera_capture_start().
+
+5) When the frame finishes its transfer from the image sensor to the camera
+   host, the CSI syncpt hardware counter will be incremented by hardware.
+   Since the hardware syncpt value will now match the threshold, our call to
+   nvhost_syncpt_wait_timeout_ext() in step 4 wakes up.
+
+6) We now tell the camera host to get ready for the DMA to complete.  We do
+   this by writing again to TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND.  See
+   tegra_camera_capture_stop().
+
+7) When the camera host finishes its DMA, we expect the hardware to increment
+   the VI syncpt.  Therefore, we call nvhost_syncpt_wait_timeout_ext() on
+   the VI syncpt with our new threshold that we got by the incrementing in
+   step 2.  See tegra_camera_capture_stop().
+
+8) When the camera host finally finishes its DMA, the VI syncpt hardware
+   counter increments.  Since our VI syncpt threshold is met, the call to
+   nvhost_syncpt_wait_timeout_ext() wakes up, and we are done.  See
+   tegra_camera_capture_stop().
+
+9) To capture the next frame, go back to step 2.  The tegra_v4l2_camera driver
+   calls tegra_camera_capture_setup at the beginning, and then a worker thread
+   repeatedly calls tegra_camera_capture_start() and
+   tegra_camera_capture_stop().  See tegra_camera_work() ->
+   tegra_camera_capture_frame().
+
+Note for VIP: Only a single syncpt is used for the VIP path.  We use the
+continuous VIP VSYNC syncpt to determine the completion of a frame transfer.
+In addition, to start and finish the capture of a frame, the
+VI_CAMERA_CONTROL register is used.  See tegra_camera_capture_start() and
+tegra_camera_capture_stop() to see how that register is used for the VIP path.
+Essentially, steps 4, 5, and 6 are eliminated, and instead of writing to
+TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND or TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND,
+we write to VI_CAMERA_CONTROL to achieve the same purpose for VIP.
+
+VIP versus CSI
+==============
+VI_VI_CORE_CONTROL bits 26:24 (INPUT_TO_CORE_EXT) should be set to 0
+(use INPUT_TO_CORE).
+
+VI_VI_INPUT_CONTROL bit 1 (VIP_INPUT_ENABLE) should be set to 1 (ENABLED),
+bit 26:25 (SYNC_FORMAT) should be set to 1 (ITU656), and bit 27 (FIELD_DETECT)
+should be set to 1 (ENABLED).
+
+VI_H_DOWNSCALE_CONTROL bit 0 (INPUT_H_SIZE_SEL) should be set to 0 (VIP),
+and bits 3:2 (INPUT_H_SIZE_SEL_EXT) should be set to 0 (USE INPUT_H_SIZE_SEL).
+
+Rather than placing the image width and height into VI_CSI_PPA_H_ACTIVE and
+VI_CSI_PPA_V_ACTIVE, respectively (or the CSI B counterparts), use
+VI_VIP_H_ACTIVE and VI_VIP_V_ACTIVE bits 31:16.  Bits 15:0 of VI_VIP_H_ACTIVE
+and VI_VIP_V_ACTIVE are the number of clock cycles to wait after receiving
+HSYNC or VSYNC before starting.  This can be used to adjust the vertical and
+horizontal back porches.
+
+VI_PIN_INPUT_ENABLE should be set to 0x00006fff, which enables input pins
+VHS, VVS, and VD11..VD0.
+
+VI_PIN_INVERSION bits 1 and 2 can be used to invert input pins VHS and VVS,
+respectively.
+
+VI_CONT_SYNCPT_VIP_VSYNC bit 8 (enable VIP_VSYNC) should be set to 1, and
+bits 7:0 should hold the index of the syncpt to be used.  When this syncpt
+is enabled, the syncpt specified by the index will increment by 1 every
+time a VSYNC occurs.  We use this syncpt to signal frame completion.
+
+VI_CAMERA_CONTROL bit 0 should be set to 1 to start capturing.  Writing a 0
+to this bit is ignored, so to stop capturing, write 1 to bit 2.