2020-10-21 16:31:16

by Sowjanya Komatineni

[permalink] [raw]
Subject: [PATCH v1 0/9] media: tegra-video: Add support for capturing from HDMI-to-CSI bridge

This series includes below changes to allow capturing from HDMI-to-CSI bridges.
- Add DV timing, EDID and log status V4L2 IOCTLs
- Subscribe V4L2_EVENT_SOURCE_CHANGE
- Implement V4L2 device notify callback to report queue error on source change
during active streaming.
- Add support for NV16 V4L2 Pixel format.

This series also include below fixes
- Allow format change for subdevs that don't have crop support.
- Correct V4L2 Pixel format for RGB888_1X24
- Enable VI pixel transform for YUV and RGB formats.


Sowjanya Komatineni (9):
media: tegra-video: Use zero crop settings if subdev has no
get_selection
media: tegra-video: Enable VI pixel transform for YUV and RGB formats
media: tegra-video: Fix V4L2 pixel format for RGB888_1X24
media: tegra-video: Add support for V4L2_PIX_FMT_NV16
media: tegra-video: Add DV timing support
media: tegra-video: Add support for EDID ioctl ops
media: tegra-video: Add support for VIDIOC_LOG_STATUS ioctl
media: tegra-video: Add support for V4L2_EVENT_SOURCE_CHANGE
media: tegra-video: Implement V4L2 device notify callback

drivers/staging/media/tegra-video/tegra210.c | 30 ++++-
drivers/staging/media/tegra-video/vi.c | 171 ++++++++++++++++++++++++++-
drivers/staging/media/tegra-video/video.c | 18 +++
3 files changed, 211 insertions(+), 8 deletions(-)

--
2.7.4


2020-10-21 16:34:05

by Sowjanya Komatineni

[permalink] [raw]
Subject: [PATCH v1 8/9] media: tegra-video: Add support for V4L2_EVENT_SOURCE_CHANGE

Current implementation uses v4l2_ctrl_subscribe_event() and this
does not handle V4L2_EVENT_SOURCE_CHANGE.

So, update driver to handle V4L2_EVENT_SOURCE_CHANGE.

Signed-off-by: Sowjanya Komatineni <[email protected]>
---
drivers/staging/media/tegra-video/vi.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c
index 936e5e5..28c06a9 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -642,6 +642,18 @@ static int tegra_channel_set_subdev_active_fmt(struct tegra_vi_channel *chan)
return 0;
}

+static int
+tegra_channel_subscribe_event(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub)
+{
+ switch (sub->type) {
+ case V4L2_EVENT_SOURCE_CHANGE:
+ return v4l2_event_subscribe(fh, sub, 4, NULL);
+ }
+
+ return v4l2_ctrl_subscribe_event(fh, sub);
+}
+
static int tegra_channel_g_selection(struct file *file, void *priv,
struct v4l2_selection *sel)
{
@@ -902,7 +914,7 @@ static const struct v4l2_ioctl_ops tegra_channel_ioctl_ops = {
.vidioc_expbuf = vb2_ioctl_expbuf,
.vidioc_streamon = vb2_ioctl_streamon,
.vidioc_streamoff = vb2_ioctl_streamoff,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_subscribe_event = tegra_channel_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
.vidioc_g_selection = tegra_channel_g_selection,
.vidioc_s_selection = tegra_channel_s_selection,
--
2.7.4

2020-10-21 16:34:35

by Sowjanya Komatineni

[permalink] [raw]
Subject: [PATCH v1 3/9] media: tegra-video: Fix V4L2 pixel format for RGB888_1X24

V4L2 pixel format is incorrect for RGB888_1X24.

This patch fixes it.

Signed-off-by: Sowjanya Komatineni <[email protected]>
---
drivers/staging/media/tegra-video/tegra210.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/media/tegra-video/tegra210.c b/drivers/staging/media/tegra-video/tegra210.c
index 6b23aa7..c883925 100644
--- a/drivers/staging/media/tegra-video/tegra210.c
+++ b/drivers/staging/media/tegra-video/tegra210.c
@@ -619,7 +619,7 @@ static const struct tegra_video_format tegra210_video_formats[] = {
TEGRA210_VIDEO_FMT(RAW12, 12, SGBRG12_1X12, 2, T_R16_I, SGBRG12),
TEGRA210_VIDEO_FMT(RAW12, 12, SBGGR12_1X12, 2, T_R16_I, SBGGR12),
/* RGB888 */
- TEGRA210_VIDEO_FMT(RGB888, 24, RGB888_1X24, 4, T_A8R8G8B8, RGB24),
+ TEGRA210_VIDEO_FMT(RGB888, 24, RGB888_1X24, 4, T_A8R8G8B8, XRGB32),
TEGRA210_VIDEO_FMT(RGB888, 24, RGB888_1X32_PADHI, 4, T_A8B8G8R8,
XBGR32),
/* YUV422 */
--
2.7.4

2020-10-21 17:33:23

by Sowjanya Komatineni

[permalink] [raw]
Subject: [PATCH v1 5/9] media: tegra-video: Add DV timing support

This patch adds below v4l2 DV timing ioctls to support HDMI-to-CSI
bridges.

Signed-off-by: Sowjanya Komatineni <[email protected]>
---
drivers/staging/media/tegra-video/vi.c | 97 ++++++++++++++++++++++++++++++++++
1 file changed, 97 insertions(+)

diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c
index 525c087..d0d84da 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -18,6 +18,7 @@
#include <linux/pm_runtime.h>
#include <linux/slab.h>

+#include <media/v4l2-dv-timings.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-fwnode.h>
@@ -720,6 +721,97 @@ static int tegra_channel_s_selection(struct file *file, void *fh,
return ret;
}

+static int tegra_channel_g_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+ struct tegra_vi_channel *chan = video_drvdata(file);
+ struct v4l2_subdev *subdev;
+
+ subdev = tegra_channel_get_remote_source_subdev(chan);
+ if (!v4l2_subdev_has_op(subdev, video, g_dv_timings))
+ return -ENOTTY;
+
+ return v4l2_device_call_until_err(chan->video.v4l2_dev, 0,
+ video, g_dv_timings, timings);
+}
+
+static int tegra_channel_s_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+ struct tegra_vi_channel *chan = video_drvdata(file);
+ struct v4l2_subdev *subdev;
+ struct v4l2_bt_timings *bt = &timings->bt;
+ struct v4l2_dv_timings curr_timings;
+ int ret;
+
+ subdev = tegra_channel_get_remote_source_subdev(chan);
+ if (!v4l2_subdev_has_op(subdev, video, s_dv_timings))
+ return -ENOTTY;
+
+ ret = tegra_channel_g_dv_timings(file, fh, &curr_timings);
+ if (ret)
+ return ret;
+
+ if (v4l2_match_dv_timings(timings, &curr_timings, 0, false))
+ return 0;
+
+ if (vb2_is_busy(&chan->queue))
+ return -EBUSY;
+
+ ret = v4l2_device_call_until_err(chan->video.v4l2_dev, 0,
+ video, s_dv_timings, timings);
+ if (ret)
+ return ret;
+
+ chan->format.width = bt->width;
+ chan->format.height = bt->height;
+ chan->format.bytesperline = bt->width * chan->fmtinfo->bpp;
+ chan->format.sizeimage = chan->format.bytesperline * bt->height;
+ tegra_channel_fmt_align(chan, &chan->format, chan->fmtinfo->bpp);
+
+ return 0;
+}
+
+static int tegra_channel_query_dv_timings(struct file *file, void *fh,
+ struct v4l2_dv_timings *timings)
+{
+ struct tegra_vi_channel *chan = video_drvdata(file);
+ struct v4l2_subdev *subdev;
+
+ subdev = tegra_channel_get_remote_source_subdev(chan);
+ if (!v4l2_subdev_has_op(subdev, video, query_dv_timings))
+ return -ENOTTY;
+
+ return v4l2_device_call_until_err(chan->video.v4l2_dev, 0,
+ video, query_dv_timings, timings);
+}
+
+static int tegra_channel_enum_dv_timings(struct file *file, void *fh,
+ struct v4l2_enum_dv_timings *timings)
+{
+ struct tegra_vi_channel *chan = video_drvdata(file);
+ struct v4l2_subdev *subdev;
+
+ subdev = tegra_channel_get_remote_source_subdev(chan);
+ if (!v4l2_subdev_has_op(subdev, pad, enum_dv_timings))
+ return -ENOTTY;
+
+ return v4l2_subdev_call(subdev, pad, enum_dv_timings, timings);
+}
+
+static int tegra_channel_dv_timings_cap(struct file *file, void *fh,
+ struct v4l2_dv_timings_cap *cap)
+{
+ struct tegra_vi_channel *chan = video_drvdata(file);
+ struct v4l2_subdev *subdev;
+
+ subdev = tegra_channel_get_remote_source_subdev(chan);
+ if (!v4l2_subdev_has_op(subdev, pad, dv_timings_cap))
+ return -ENOTTY;
+
+ return v4l2_subdev_call(subdev, pad, dv_timings_cap, cap);
+}
+
static int tegra_channel_enum_input(struct file *file, void *fh,
struct v4l2_input *inp)
{
@@ -779,6 +871,11 @@ static const struct v4l2_ioctl_ops tegra_channel_ioctl_ops = {
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
.vidioc_g_selection = tegra_channel_g_selection,
.vidioc_s_selection = tegra_channel_s_selection,
+ .vidioc_g_dv_timings = tegra_channel_g_dv_timings,
+ .vidioc_s_dv_timings = tegra_channel_s_dv_timings,
+ .vidioc_query_dv_timings = tegra_channel_query_dv_timings,
+ .vidioc_enum_dv_timings = tegra_channel_enum_dv_timings,
+ .vidioc_dv_timings_cap = tegra_channel_dv_timings_cap,
};

/*
--
2.7.4

2020-10-21 17:33:23

by Sowjanya Komatineni

[permalink] [raw]
Subject: [PATCH v1 4/9] media: tegra-video: Add support for V4L2_PIX_FMT_NV16

NV16 are two-plane versions of YUV422 format.

VI/CSI surface0 registers corresponds to first Y plane and
surface1 registers corresponds to seconds UV plane.

This patch updates image size for NV16 format to include both planes
and programs VI/CSI surface1 registers for UV plane capture.

Signed-off-by: Sowjanya Komatineni <[email protected]>
---
drivers/staging/media/tegra-video/tegra210.c | 13 +++++++++++++
drivers/staging/media/tegra-video/vi.c | 2 ++
2 files changed, 15 insertions(+)

diff --git a/drivers/staging/media/tegra-video/tegra210.c b/drivers/staging/media/tegra-video/tegra210.c
index c883925..929d277 100644
--- a/drivers/staging/media/tegra-video/tegra210.c
+++ b/drivers/staging/media/tegra-video/tegra210.c
@@ -287,6 +287,7 @@ static int tegra_channel_capture_frame(struct tegra_vi_channel *chan,
{
u32 thresh, value, frame_start, mw_ack_done;
int bytes_per_line = chan->format.bytesperline;
+ u32 sizeimage = chan->format.sizeimage;
int err;

/* program buffer address by using surface 0 */
@@ -296,6 +297,18 @@ static int tegra_channel_capture_frame(struct tegra_vi_channel *chan,
vi_csi_write(chan, TEGRA_VI_CSI_SURFACE0_STRIDE, bytes_per_line);

/*
+ * Program surface 1 for UV plane with offset sizeimage from Y plane.
+ */
+ if (chan->fmtinfo->fourcc == V4L2_PIX_FMT_NV16) {
+ vi_csi_write(chan, TEGRA_VI_CSI_SURFACE1_OFFSET_MSB,
+ ((u64)buf->addr + sizeimage / 2) >> 32);
+ vi_csi_write(chan, TEGRA_VI_CSI_SURFACE1_OFFSET_LSB,
+ buf->addr + sizeimage / 2);
+ vi_csi_write(chan, TEGRA_VI_CSI_SURFACE1_STRIDE,
+ bytes_per_line);
+ }
+
+ /*
* Tegra VI block interacts with host1x syncpt for synchronizing
* programmed condition of capture state and hardware operation.
* Frame start and Memory write acknowledge syncpts has their own
diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c
index 7edd35c..525c087 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -484,6 +484,8 @@ static void tegra_channel_fmt_align(struct tegra_vi_channel *chan,

pix->bytesperline = clamp(bpl, min_bpl, max_bpl);
pix->sizeimage = pix->bytesperline * pix->height;
+ if (pix->pixelformat == V4L2_PIX_FMT_NV16)
+ pix->sizeimage *= 2;
}

static int __tegra_channel_try_format(struct tegra_vi_channel *chan,
--
2.7.4