media: tegra-video: Add custom V4L2 control V4L2_CID_TEGRA_SYNCPT_TIMEOUT_RETRY
authorSowjanya Komatineni <skomatineni@nvidia.com>
Fri, 11 Dec 2020 17:02:42 +0000 (18:02 +0100)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Mon, 4 Jan 2021 12:10:22 +0000 (13:10 +0100)
This patch adds custom V4L2 control for syncpt timeout retry to continue
capture on error for specified retries count through this control.

This is useful for HDMI-to-CSI bridge debug purposes like for hotplug scenarios
or for ignoring captures till HDMI input is stabilized.

Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
drivers/staging/media/tegra-video/tegra210.c
drivers/staging/media/tegra-video/vi.c
drivers/staging/media/tegra-video/vi.h

index 063d0a3..f10a041 100644 (file)
@@ -454,6 +454,7 @@ static int chan_capture_kthread_start(void *data)
 {
        struct tegra_vi_channel *chan = data;
        struct tegra_channel_buffer *buf;
+       unsigned int retries = 0;
        int err = 0;
 
        while (1) {
@@ -483,8 +484,15 @@ static int chan_capture_kthread_start(void *data)
                spin_unlock(&chan->start_lock);
 
                err = tegra_channel_capture_frame(chan, buf);
-               if (err)
+               if (!err) {
+                       retries = 0;
+                       continue;
+               }
+
+               if (retries++ > chan->syncpt_timeout_retry)
                        vb2_queue_error(&chan->queue);
+               else
+                       err = 0;
        }
 
        return 0;
index 4773281..70e1e18 100644 (file)
@@ -956,7 +956,6 @@ static const struct v4l2_file_operations tegra_channel_fops = {
 /*
  * V4L2 control operations
  */
-#if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
 static int vi_s_ctrl(struct v4l2_ctrl *ctrl)
 {
        struct tegra_vi_channel *chan = container_of(ctrl->handler,
@@ -968,6 +967,9 @@ static int vi_s_ctrl(struct v4l2_ctrl *ctrl)
                /* pattern change takes effect on next stream */
                chan->pg_mode = ctrl->val + 1;
                break;
+       case V4L2_CID_TEGRA_SYNCPT_TIMEOUT_RETRY:
+               chan->syncpt_timeout_retry = ctrl->val;
+               break;
        default:
                return -EINVAL;
        }
@@ -979,10 +981,22 @@ static const struct v4l2_ctrl_ops vi_ctrl_ops = {
        .s_ctrl = vi_s_ctrl,
 };
 
+#if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
 static const char *const vi_pattern_strings[] = {
        "Black/White Direct Mode",
        "Color Patch Mode",
 };
+#else
+static const struct v4l2_ctrl_config syncpt_timeout_ctrl = {
+       .ops = &vi_ctrl_ops,
+       .id = V4L2_CID_TEGRA_SYNCPT_TIMEOUT_RETRY,
+       .name = "Syncpt timeout retry",
+       .type = V4L2_CTRL_TYPE_INTEGER,
+       .min = 1,
+       .max = 10000,
+       .step = 1,
+       .def = 5,
+};
 #endif
 
 static int tegra_channel_setup_ctrl_handler(struct tegra_vi_channel *chan)
@@ -1004,6 +1018,16 @@ static int tegra_channel_setup_ctrl_handler(struct tegra_vi_channel *chan)
 #else
        struct v4l2_subdev *subdev;
 
+       /* custom control */
+       v4l2_ctrl_new_custom(&chan->ctrl_handler, &syncpt_timeout_ctrl, NULL);
+       if (chan->ctrl_handler.error) {
+               dev_err(chan->vi->dev, "failed to add %s ctrl handler: %d\n",
+                       syncpt_timeout_ctrl.name,
+                       chan->ctrl_handler.error);
+               v4l2_ctrl_handler_free(&chan->ctrl_handler);
+               return chan->ctrl_handler.error;
+       }
+
        subdev = tegra_channel_get_remote_source_subdev(chan);
        if (!subdev)
                return -ENODEV;
index 27061a5..a68e2c0 100644 (file)
@@ -23,6 +23,8 @@
 
 #include "csi.h"
 
+#define V4L2_CID_TEGRA_SYNCPT_TIMEOUT_RETRY    (V4L2_CTRL_CLASS_CAMERA | 0x1001)
+
 #define TEGRA_MIN_WIDTH                32U
 #define TEGRA_MAX_WIDTH                32768U
 #define TEGRA_MIN_HEIGHT       32U
@@ -160,6 +162,7 @@ struct tegra_vi_graph_entity {
  * @of_node: device node of VI channel
  *
  * @ctrl_handler: V4L2 control handler of this video channel
+ * @syncpt_timeout_retry: syncpt timeout retry count for the capture
  * @fmts_bitmap: a bitmap for supported formats matching v4l2 subdev formats
  * @tpg_fmts_bitmap: a bitmap for supported TPG formats
  * @pg_mode: test pattern generator mode (disabled/direct/patch)
@@ -201,6 +204,7 @@ struct tegra_vi_channel {
        struct device_node *of_node;
 
        struct v4l2_ctrl_handler ctrl_handler;
+       unsigned int syncpt_timeout_retry;
        DECLARE_BITMAP(fmts_bitmap, MAX_FORMAT_NUM);
        DECLARE_BITMAP(tpg_fmts_bitmap, MAX_FORMAT_NUM);
        enum tegra_vi_pg_mode pg_mode;