diff options
author | Andrew Chew <achew@nvidia.com> | 2012-08-06 14:43:09 -0700 |
---|---|---|
committer | Winnie Hsu <whsu@nvidia.com> | 2012-12-17 11:29:49 -0800 |
commit | bce66df644851d87a7ba8c54eae9fc51d0614b3f (patch) | |
tree | 3c68204807bb3c1025f02d497bfaf0e1113119a9 /Documentation | |
parent | 4d667a6aff6ce8089973b73a5e6645e750045356 (diff) |
media: tegra: Add docs for Tegra V4L2 camera
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
(cherry picked from commit 7dd02775470d2b243f96b7d1f4e8b9c4e3b3ada6)
Signed-off-by: Bryan Wu <pengw@nvidia.com>
Change-Id: I10fd56ea6e3e83db6e09b75126a2048552ef052c
Reviewed-on: http://git-master/r/170822
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Andrew Chew <achew@nvidia.com>
Reviewed-by: Winnie Hsu <whsu@nvidia.com>
GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/video4linux/README.tegra | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/Documentation/video4linux/README.tegra b/Documentation/video4linux/README.tegra new file mode 100644 index 000000000000..610eeded2ae9 --- /dev/null +++ b/Documentation/video4linux/README.tegra @@ -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. |