vi5: camera: add ovrride capture timeout control

add CID to override the capture timeout.

bug 4737219

Change-Id: I6df8e760ce8051054ba34a8b85b00bb237f9cd98
Signed-off-by: snchen <snchen@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3173821
(cherry picked from commit 20374db85d)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3196700
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
snchen
2024-07-09 15:29:04 +08:00
committed by Jon Hunter
parent 267eedc25d
commit 28668cde01
4 changed files with 95 additions and 13 deletions

View File

@@ -1,5 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2017-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. /* SPDX-FileCopyrightText: Copyright (c) 2017-2024 NVIDIA CORPORATION & AFFILIATES.
* All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
/** /**
* @file drivers/media/platform/tegra/camera/fusa-capture/capture-vi.c * @file drivers/media/platform/tegra/camera/fusa-capture/capture-vi.c
@@ -1457,7 +1469,12 @@ int vi_capture_status(
/* negative timeout means wait forever */ /* negative timeout means wait forever */
if (timeout_ms < 0) { if (timeout_ms < 0) {
wait_for_completion(&capture->capture_resp); ret = wait_for_completion_interruptible(&capture->capture_resp);
if (ret == -ERESTARTSYS) {
dev_dbg(chan->dev,
"capture status interrupted\n");
return -ETIMEDOUT;
}
} else { } else {
ret = wait_for_completion_timeout( ret = wait_for_completion_timeout(
&capture->capture_resp, &capture->capture_resp,

View File

@@ -1,8 +1,14 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
/* /* SPDX-FileCopyrightText: Copyright (c) 2016-2024 NVIDIA CORPORATION & AFFILIATES.
* All rights reserved.
*
* Tegra Video Input 5 device common APIs * Tegra Video Input 5 device common APIs
* *
* Copyright (c) 2016-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * Author: Frank Chen <frank@nvidia.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/ */
#include <linux/errno.h> #include <linux/errno.h>
@@ -134,6 +140,9 @@ static int tegra_vi5_s_ctrl(struct v4l2_ctrl *ctrl)
case TEGRA_CAMERA_CID_WRITE_ISPFORMAT: case TEGRA_CAMERA_CID_WRITE_ISPFORMAT:
chan->write_ispformat = ctrl->val; chan->write_ispformat = ctrl->val;
break; break;
case TEGRA_CAMERA_CID_VI_CAPTURE_TIMEOUT:
chan->capture_timeout_ms = ctrl->val;
break;
default: default:
dev_err(&chan->video->dev, "%s:Not valid ctrl\n", __func__); dev_err(&chan->video->dev, "%s:Not valid ctrl\n", __func__);
return -EINVAL; return -EINVAL;
@@ -200,6 +209,16 @@ static const struct v4l2_ctrl_config vi5_custom_ctrls[] = {
.step = 1, .step = 1,
.dims = { SENSOR_CTRL_BLOB_SIZE }, .dims = { SENSOR_CTRL_BLOB_SIZE },
}, },
{
.ops = &vi5_ctrl_ops,
.id = TEGRA_CAMERA_CID_VI_CAPTURE_TIMEOUT,
.name = "Override capture timeout ms",
.type = V4L2_CTRL_TYPE_INTEGER,
.def = CAPTURE_TIMEOUT_MS,
.min = -1,
.max = 0x7FFFFFFF,
.step = 1,
},
}; };
static int vi5_add_ctrls(struct tegra_channel *chan) static int vi5_add_ctrls(struct tegra_channel *chan)
@@ -497,6 +516,7 @@ static void vi5_capture_dequeue(struct tegra_channel *chan,
unsigned long flags; unsigned long flags;
struct tegra_mc_vi *vi = chan->vi; struct tegra_mc_vi *vi = chan->vi;
struct vb2_v4l2_buffer *vb = &buf->buf; struct vb2_v4l2_buffer *vb = &buf->buf;
int timeout_ms = CAPTURE_TIMEOUT_MS;
struct timespec64 ts; struct timespec64 ts;
struct capture_descriptor *descr = NULL; struct capture_descriptor *descr = NULL;
@@ -507,12 +527,21 @@ static void vi5_capture_dequeue(struct tegra_channel *chan,
goto rel_buf; goto rel_buf;
/* Dequeue a frame and check its capture status */ /* Dequeue a frame and check its capture status */
err = vi_capture_status(chan->tegra_vi_channel[vi_port], CAPTURE_TIMEOUT_MS); timeout_ms = chan->capture_timeout_ms;
err = vi_capture_status(chan->tegra_vi_channel[vi_port], timeout_ms);
if (err) { if (err) {
if (err == -ETIMEDOUT) { if (err == -ETIMEDOUT) {
dev_err(vi->dev, if (timeout_ms < 0) {
"uncorr_err: request timed out after %d ms\n", spin_lock_irqsave(&chan->capture_state_lock, flags);
CAPTURE_TIMEOUT_MS); chan->capture_state = CAPTURE_ERROR_TIMEOUT;
spin_unlock_irqrestore(&chan->capture_state_lock, flags);
buf->vb2_state = VB2_BUF_STATE_ERROR;
goto rel_buf;
} else {
dev_err(vi->dev,
"uncorr_err: request timed out after %d ms\n",
timeout_ms);
}
} else { } else {
dev_err(vi->dev, "uncorr_err: request err %d\n", err); dev_err(vi->dev, "uncorr_err: request err %d\n", err);
} }
@@ -702,6 +731,7 @@ static int tegra_channel_kthread_capture_dequeue(void *data)
struct tegra_channel_buffer *buf; struct tegra_channel_buffer *buf;
set_freezable(); set_freezable();
allow_signal(SIGINT);
while (1) { while (1) {
try_to_freeze(); try_to_freeze();
@@ -722,6 +752,12 @@ static int tegra_channel_kthread_capture_dequeue(void *data)
} }
spin_lock_irqsave(&chan->capture_state_lock, flags); spin_lock_irqsave(&chan->capture_state_lock, flags);
if (chan->capture_state == CAPTURE_ERROR_TIMEOUT) {
spin_unlock_irqrestore(&chan->capture_state_lock,
flags);
break;
}
if (chan->capture_state == CAPTURE_ERROR) { if (chan->capture_state == CAPTURE_ERROR) {
spin_unlock_irqrestore(&chan->capture_state_lock, spin_unlock_irqrestore(&chan->capture_state_lock,
flags); flags);
@@ -791,6 +827,7 @@ static void vi5_channel_stop_kthreads(struct tegra_channel *chan)
/* Stop the kthread for capture dequeue */ /* Stop the kthread for capture dequeue */
if (chan->kthread_capture_dequeue) { if (chan->kthread_capture_dequeue) {
send_sig(SIGINT, chan->kthread_capture_dequeue, 1);
kthread_stop(chan->kthread_capture_dequeue); kthread_stop(chan->kthread_capture_dequeue);
chan->kthread_capture_dequeue = NULL; chan->kthread_capture_dequeue = NULL;
} }

View File

@@ -1,8 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /* SPDX-FileCopyrightText: Copyright (c) 2012-2024 NVIDIA CORPORATION & AFFILIATES.
* All rights reserved.
*
* drivers/media/platform/tegra/camera/mc_common.h
*
* Tegra Media controller common APIs * Tegra Media controller common APIs
* *
* Copyright (c) 2012-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CAMERA_MC_COMMON_H__ #ifndef __CAMERA_MC_COMMON_H__
@@ -229,6 +243,7 @@ struct tegra_channel {
struct v4l2_fh *fh; struct v4l2_fh *fh;
bool bypass; bool bypass;
bool write_ispformat; bool write_ispformat;
int capture_timeout_ms;
bool low_latency; bool low_latency;
enum tegra_vi_pg_mode pg_mode; enum tegra_vi_pg_mode pg_mode;
bool bfirst_fstart; bool bfirst_fstart;

View File

@@ -1,8 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /* SPDX-FileCopyrightText: Copyright (c) 2017-2024 NVIDIA CORPORATION & AFFILIATES.
* tegra-v4l2-camera.h - utilities for tegra camera driver * All rights reserved.
* *
* Copyright (c) 2017-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * TEGRA_V4L2_CAMERA.h - utilities for tegra camera driver
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __TEGRA_V4L2_CAMERA__ #ifndef __TEGRA_V4L2_CAMERA__
@@ -48,6 +60,7 @@
#define TEGRA_CAMERA_CID_SENSOR_DV_TIMINGS (TEGRA_CAMERA_CID_BASE+108) #define TEGRA_CAMERA_CID_SENSOR_DV_TIMINGS (TEGRA_CAMERA_CID_BASE+108)
#define TEGRA_CAMERA_CID_LOW_LATENCY (TEGRA_CAMERA_CID_BASE+109) #define TEGRA_CAMERA_CID_LOW_LATENCY (TEGRA_CAMERA_CID_BASE+109)
#define TEGRA_CAMERA_CID_VI_PREFERRED_STRIDE (TEGRA_CAMERA_CID_BASE+110) #define TEGRA_CAMERA_CID_VI_PREFERRED_STRIDE (TEGRA_CAMERA_CID_BASE+110)
#define TEGRA_CAMERA_CID_VI_CAPTURE_TIMEOUT (TEGRA_CAMERA_CID_BASE+111)
/** /**
* This is temporary with the current v4l2 infrastructure * This is temporary with the current v4l2 infrastructure