From 1a32977b86695c018a59240703b8bdc85d5d4446 Mon Sep 17 00:00:00 2001 From: Wojciech Bieganski Date: Mon, 30 Jan 2017 15:39:26 +0100 Subject: media: fix simultaneous capture Signed-off-by: Wojciech Bieganski Acked-by: Marcel Ziswiler --- .../platform/soc_camera/tegra_camera/common.c | 32 +++++++++++++++++--- .../platform/soc_camera/tegra_camera/common.h | 6 ++-- .../media/platform/soc_camera/tegra_camera/vi2.c | 34 ++++++++++++++++++++-- 3 files changed, 63 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/soc_camera/tegra_camera/common.c b/drivers/media/platform/soc_camera/tegra_camera/common.c index 06741f3ebca1..762c95724609 100644 --- a/drivers/media/platform/soc_camera/tegra_camera/common.c +++ b/drivers/media/platform/soc_camera/tegra_camera/common.c @@ -170,7 +170,9 @@ static int tegra_camera_activate(struct tegra_camera_dev *cam, if (cam_ops->capture_clean) cam_ops->capture_clean(cam); - cam->sof = 1; + cam->sof[0] = 1; + cam->sof[1] = 1; + cam->sof[2] = 1; return 0; } @@ -197,8 +199,12 @@ static void tegra_camera_deactivate(struct tegra_camera_dev *cam) nvhost_module_idle_ext(cam->ndev); - cam->sof = 0; - cam->cal_done = 0; + cam->sof[0] = 0; + cam->sof[1] = 0; + cam->sof[2] = 0; + cam->cal_done[0] = 0; + cam->cal_done[1] = 0; + cam->cal_done[2] = 0; } static int tegra_camera_capture_frame(struct tegra_camera_dev *cam, @@ -219,7 +225,7 @@ static int tegra_camera_capture_frame(struct tegra_camera_dev *cam, if (cam->ops->mipi_calibration && !cam->cal_done[port-1]) { err = cam->ops->mipi_calibration(cam, buf); if (!err) - cam->cal_done = 1; + cam->cal_done[port-1] = 1; } /* Issue start capture */ @@ -555,6 +561,18 @@ static int tegra_camera_start_streaming(struct vb2_queue *q, unsigned int count) vb2_vidq); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct tegra_camera_dev *cam = ici->priv; + struct soc_camera_subdev_desc *ssdesc = &icd->sdesc->subdev_desc; + struct tegra_camera_platform_data *pdata = ssdesc->drv_priv; + int port = pdata->port; + + /* CSI B and CSI C can't work simultaneously */ + if (port == TEGRA_CAMERA_PORT_CSI_B || + port == TEGRA_CAMERA_PORT_CSI_C) { + if (cam->csi_bc_busy) + return -EBUSY; + else + cam->csi_bc_busy = true; + } /* Start kthread to capture frame */ cam->kthread_capture_start = kthread_run( @@ -587,6 +605,12 @@ static int tegra_camera_stop_streaming(struct vb2_queue *q) cam->ops->capture_stop(cam, port); + if (port == TEGRA_CAMERA_PORT_CSI_B || + port == TEGRA_CAMERA_PORT_CSI_C) { + cam->csi_bc_busy = false; + } + + return 0; } diff --git a/drivers/media/platform/soc_camera/tegra_camera/common.h b/drivers/media/platform/soc_camera/tegra_camera/common.h index 1d71c2ba39f5..0b7ef3874efd 100644 --- a/drivers/media/platform/soc_camera/tegra_camera/common.h +++ b/drivers/media/platform/soc_camera/tegra_camera/common.h @@ -130,8 +130,10 @@ struct tegra_camera_dev { /* Test Pattern Generator mode */ int tpg_mode; - int sof; - int cal_done; + int sof[3]; + int cal_done[3]; + + bool csi_bc_busy; }; #define TC_VI_REG_RD(dev, offset) readl(dev->reg_base + offset) diff --git a/drivers/media/platform/soc_camera/tegra_camera/vi2.c b/drivers/media/platform/soc_camera/tegra_camera/vi2.c index 99bef12e1b7f..e79a56162e2d 100644 --- a/drivers/media/platform/soc_camera/tegra_camera/vi2.c +++ b/drivers/media/platform/soc_camera/tegra_camera/vi2.c @@ -360,6 +360,10 @@ static struct tegra_camera_clk vi2_clks0[] = { .name = "vi_sensor", .freq = 24000000, }, + { + .name = "vi_sensor2", + .freq = 24000000, + }, { .name = "csi", .freq = 408000000, @@ -387,6 +391,16 @@ static struct tegra_camera_clk vi2_clks0[] = { .freq = 102000000, .use_devname = 1, }, + { + .name = "cilcd", + .freq = 102000000, + .use_devname = 1, + }, + { + .name = "cile", + .freq = 102000000, + .use_devname = 1, + }, /* Always put "p11_d" at the end */ { .name = "pll_d", @@ -400,6 +414,10 @@ static struct tegra_camera_clk vi2_clks1[] = { .freq = 408000000, .use_devname = 1, }, + { + .name = "vi_sensor", + .freq = 24000000, + }, { .name = "vi_sensor2", .freq = 24000000, @@ -413,6 +431,11 @@ static struct tegra_camera_clk vi2_clks1[] = { .name = "isp", .freq = 0, }, + { + .name = "csus", + .freq = 0, + .use_devname = 1, + }, { .name = "sclk", .freq = 80000000, @@ -421,6 +444,11 @@ static struct tegra_camera_clk vi2_clks1[] = { .name = "emc", .freq = 300000000, }, + { + .name = "cilab", + .freq = 102000000, + .use_devname = 1, + }, { .name = "cilcd", .freq = 102000000, @@ -796,7 +824,7 @@ static int vi2_capture_setup(struct tegra_camera_dev *cam, int port = pdata->port; /* Skip VI2/CSI2 setup for second and later frame capture */ - if (!cam->sof) + if (!cam->sof[port-1]) return 0; /* Setup registers for CSI-A and CSI-B inputs */ @@ -1026,8 +1054,8 @@ static int vi2_capture_wait(struct tegra_camera_dev *cam, } /* Mark SOF flag to Zero after we captured the FIRST frame */ - if (cam->sof) - cam->sof = 0; + if (cam->sof[port-1]) + cam->sof[port-1] = 0; /* Capture syncpt timeout err, then dump error status */ if (err) { -- cgit v1.2.3