diff options
author | Bryan Wu <pengw@nvidia.com> | 2015-10-15 13:10:29 -0700 |
---|---|---|
committer | Matthew Pedro <mapedro@nvidia.com> | 2015-10-29 10:52:36 -0700 |
commit | ff5bccb61c1f8da1f63451fda88bd1f65dbee5b2 (patch) | |
tree | 4f3494c090cc004caec0c96a7028c19b40c05264 /drivers/media/platform/soc_camera/tegra_camera/vi2.c | |
parent | b15d976c0a2e6a3c512001a3be3feaf057655b8b (diff) |
media: tegra_camera: introduce 2 kthreads for capture
Use one kthread to start capture a frame and wait for next frame start.
Before waiting, it will move the current buffer to another queue which
will be handled another kthread.
The second kthread (capture_done) will wait for memory output done sync
point event and handle the buffer to videobuffer2 framework as capture
done.
Bug 1686911
Change-Id: Ia092c708ecca3b2e7cbc657a96fd247ea4a00d2f
Signed-off-by: Bryan Wu <pengw@nvidia.com>
Reviewed-on: http://git-master/r/819177
GVS: Gerrit_Virtual_Submit
Reviewed-by: Matthew Pedro <mapedro@nvidia.com>
Diffstat (limited to 'drivers/media/platform/soc_camera/tegra_camera/vi2.c')
-rw-r--r-- | drivers/media/platform/soc_camera/tegra_camera/vi2.c | 60 |
1 files changed, 42 insertions, 18 deletions
diff --git a/drivers/media/platform/soc_camera/tegra_camera/vi2.c b/drivers/media/platform/soc_camera/tegra_camera/vi2.c index aaf6d2734ce3..8c1f81a56b7a 100644 --- a/drivers/media/platform/soc_camera/tegra_camera/vi2.c +++ b/drivers/media/platform/soc_camera/tegra_camera/vi2.c @@ -785,10 +785,9 @@ static int vi2_capture_setup_csi_1(struct tegra_camera_dev *cam, return 0; } -static int vi2_capture_setup(struct tegra_camera_dev *cam) +static int vi2_capture_setup(struct tegra_camera_dev *cam, + struct tegra_camera_buffer *buf) { - struct vb2_buffer *vb = cam->active; - struct tegra_camera_buffer *buf = to_tegra_vb(vb); struct soc_camera_device *icd = buf->icd; struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc; struct tegra_camera_platform_data *pdata = ssdesc->drv_priv; @@ -958,7 +957,7 @@ static void vi2_capture_error_status(struct tegra_camera_dev *cam) } static int vi2_capture_start(struct tegra_camera_dev *cam, - struct tegra_camera_buffer *buf) + struct tegra_camera_buffer *buf) { struct soc_camera_device *icd = buf->icd; struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc; @@ -971,7 +970,6 @@ static int vi2_capture_start(struct tegra_camera_dev *cam, if (err < 0) return err; - /* Only wait on CSI frame end syncpt if we're using CSI. */ if (port == TEGRA_CAMERA_PORT_CSI_A) { if (!nvhost_syncpt_read_ext_check(cam->ndev, cam->syncpt_id_csi_a, &val)) @@ -982,13 +980,6 @@ static int vi2_capture_start(struct tegra_camera_dev *cam, TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT, VI_CSI_PPA_FRAME_START | cam->syncpt_id_csi_a); TC_VI_REG_WT(cam, TEGRA_VI_CSI_0_SINGLE_SHOT, 0x1); - - err = nvhost_syncpt_wait_timeout_ext(cam->ndev, - cam->syncpt_id_csi_a, - cam->syncpt_csi_a, - TEGRA_SYNCPT_CSI_WAIT_TIMEOUT, - NULL, - NULL); } else if (port == TEGRA_CAMERA_PORT_CSI_B || port == TEGRA_CAMERA_PORT_CSI_C) { if (!nvhost_syncpt_read_ext_check(cam->ndev, @@ -1000,7 +991,30 @@ static int vi2_capture_start(struct tegra_camera_dev *cam, TC_VI_REG_WT(cam, TEGRA_VI_CFG_VI_INCR_SYNCPT, VI_CSI_PPB_FRAME_START | cam->syncpt_id_csi_b); TC_VI_REG_WT(cam, TEGRA_VI_CSI_1_SINGLE_SHOT, 0x1); + } + + return err; +} + +static int vi2_capture_wait(struct tegra_camera_dev *cam, + struct tegra_camera_buffer *buf) +{ + struct soc_camera_device *icd = buf->icd; + struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc; + struct tegra_camera_platform_data *pdata = ssdesc->drv_priv; + int port = pdata->port; + int err = 0; + /* Only wait on CSI frame end syncpt if we're using CSI. */ + if (port == TEGRA_CAMERA_PORT_CSI_A) { + err = nvhost_syncpt_wait_timeout_ext(cam->ndev, + cam->syncpt_id_csi_a, + cam->syncpt_csi_a, + TEGRA_SYNCPT_CSI_WAIT_TIMEOUT, + NULL, + NULL); + } else if (port == TEGRA_CAMERA_PORT_CSI_B || + port == TEGRA_CAMERA_PORT_CSI_C) { err = nvhost_syncpt_wait_timeout_ext(cam->ndev, cam->syncpt_id_csi_b, cam->syncpt_csi_b, @@ -1030,7 +1044,7 @@ static int vi2_capture_start(struct tegra_camera_dev *cam, return err; } -static int vi2_capture_stop(struct tegra_camera_dev *cam, int port) +static int vi2_capture_done(struct tegra_camera_dev *cam, int port) { u32 val; int err = 0; @@ -1060,7 +1074,6 @@ static int vi2_capture_stop(struct tegra_camera_dev *cam, int port) TEGRA_SYNCPT_CSI_WAIT_TIMEOUT, NULL, NULL); - TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND, 0xf002); } else if (port == TEGRA_CAMERA_PORT_CSI_B || port == TEGRA_CAMERA_PORT_CSI_C) { if (!nvhost_syncpt_read_ext_check(cam->ndev, @@ -1087,12 +1100,22 @@ static int vi2_capture_stop(struct tegra_camera_dev *cam, int port) TEGRA_SYNCPT_CSI_WAIT_TIMEOUT, NULL, NULL); - TC_VI_REG_WT(cam, TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND, 0xf002); } return err; } +static int vi2_capture_stop(struct tegra_camera_dev *cam, int port) +{ + u32 reg = (port == TEGRA_CAMERA_PORT_CSI_A) ? + TEGRA_CSI_PIXEL_STREAM_PPA_COMMAND : + TEGRA_CSI_PIXEL_STREAM_PPB_COMMAND; + + TC_VI_REG_WT(cam, reg, 0xf002); + + return 0; +} + /* Reset VI2/CSI2 when activating, no sepecial ops for deactiving */ static void vi2_sw_reset(struct tegra_camera_dev *cam) { @@ -1104,13 +1127,12 @@ static void vi2_sw_reset(struct tegra_camera_dev *cam) udelay(10); } -static int vi2_mipi_calibration(struct tegra_camera_dev *cam) +static int vi2_mipi_calibration(struct tegra_camera_dev *cam, + struct tegra_camera_buffer *buf) { void __iomem *mipi_cal; struct regmap *regs; struct platform_device *pdev = cam->ndev; - struct vb2_buffer *vb = cam->active; - struct tegra_camera_buffer *buf = to_tegra_vb(vb); struct soc_camera_device *icd = buf->icd; struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc; struct tegra_camera_platform_data *pdata = ssdesc->drv_priv; @@ -1253,6 +1275,8 @@ struct tegra_camera_ops vi2_ops = { .capture_clean = vi2_capture_clean, .capture_setup = vi2_capture_setup, .capture_start = vi2_capture_start, + .capture_wait = vi2_capture_wait, + .capture_done = vi2_capture_done, .capture_stop = vi2_capture_stop, .activate = vi2_sw_reset, |