@@ -18,6 +18,7 @@ intel-ipu6-isys-y := ipu6-isys.o \
ipu6-isys-subdev.o \
ipu6-isys-mcd-phy.o \
ipu6-isys-jsl-phy.o \
- ipu6-isys-dwc-phy.o
+ ipu6-isys-dwc-phy.o \
+ isys-subdev.o
obj-$(CONFIG_VIDEO_INTEL_IPU6) += intel-ipu6-isys.o
@@ -494,7 +494,7 @@ static const struct v4l2_subdev_pad_ops csi2_sd_pad_ops = {
.get_selection = ipu6_isys_csi2_get_sel,
.set_selection = ipu6_isys_csi2_set_sel,
.enum_mbus_code = ipu6_isys_subdev_enum_mbus_code,
- .set_routing = ipu6_isys_subdev_set_routing,
+ .set_routing = isys_subdev_set_routing,
.enable_streams = ipu6_isys_csi2_enable_streams,
.disable_streams = ipu6_isys_csi2_disable_streams,
};
@@ -446,10 +446,9 @@ static int ipu6_isys_link_fmt_validate(struct ipu6_isys_queue *aq)
return -ENOTCONN;
sd = media_entity_to_v4l2_subdev(remote_pad->entity);
- r_stream = ipu6_isys_get_src_stream_by_src_pad(sd, remote_pad->index);
+ r_stream = isys_get_src_stream_by_src_pad(sd, remote_pad->index);
- ret = ipu6_isys_get_stream_pad_fmt(sd, remote_pad->index, r_stream,
- &format);
+ ret = isys_get_stream_pad_fmt(sd, remote_pad->index, r_stream, &format);
if (ret) {
dev_dbg(dev, "failed to get %s: pad %d, stream:%d format\n",
@@ -243,66 +243,6 @@ static int subdev_set_routing(struct v4l2_subdev *sd,
return v4l2_subdev_set_routing_with_fmt(sd, state, routing, &format);
}
-int ipu6_isys_get_stream_pad_fmt(struct v4l2_subdev *sd, u32 pad, u32 stream,
- struct v4l2_mbus_framefmt *format)
-{
- struct v4l2_mbus_framefmt *fmt;
- struct v4l2_subdev_state *state;
-
- if (!sd || !format)
- return -EINVAL;
-
- state = v4l2_subdev_lock_and_get_active_state(sd);
- fmt = v4l2_subdev_state_get_format(state, pad, stream);
- if (fmt)
- *format = *fmt;
- v4l2_subdev_unlock_state(state);
-
- return fmt ? 0 : -EINVAL;
-}
-
-int ipu6_isys_get_stream_pad_crop(struct v4l2_subdev *sd, u32 pad, u32 stream,
- struct v4l2_rect *crop)
-{
- struct v4l2_subdev_state *state;
- struct v4l2_rect *rect;
-
- if (!sd || !crop)
- return -EINVAL;
-
- state = v4l2_subdev_lock_and_get_active_state(sd);
- rect = v4l2_subdev_state_get_crop(state, pad, stream);
- if (rect)
- *crop = *rect;
- v4l2_subdev_unlock_state(state);
-
- return rect ? 0 : -EINVAL;
-}
-
-u32 ipu6_isys_get_src_stream_by_src_pad(struct v4l2_subdev *sd, u32 pad)
-{
- struct v4l2_subdev_state *state;
- struct v4l2_subdev_route *routes;
- unsigned int i;
- u32 source_stream = 0;
-
- state = v4l2_subdev_lock_and_get_active_state(sd);
- if (!state)
- return 0;
-
- routes = state->routing.routes;
- for (i = 0; i < state->routing.num_routes; i++) {
- if (routes[i].source_pad == pad) {
- source_stream = routes[i].source_stream;
- break;
- }
- }
-
- v4l2_subdev_unlock_state(state);
-
- return source_stream;
-}
-
static int ipu6_isys_subdev_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
{
@@ -321,14 +261,6 @@ static int ipu6_isys_subdev_init_state(struct v4l2_subdev *sd,
return subdev_set_routing(sd, state, &routing);
}
-int ipu6_isys_subdev_set_routing(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *state,
- enum v4l2_subdev_format_whence which,
- struct v4l2_subdev_krouting *routing)
-{
- return subdev_set_routing(sd, state, routing);
-}
-
static const struct v4l2_subdev_internal_ops ipu6_isys_subdev_internal_ops = {
.init_state = ipu6_isys_subdev_init_state,
};
@@ -10,6 +10,8 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-subdev.h>
+#include "isys.h"
+
struct ipu6_isys;
struct ipu6_isys_subdev {
@@ -37,15 +39,6 @@ int ipu6_isys_subdev_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state,
struct v4l2_subdev_mbus_code_enum
*code);
-u32 ipu6_isys_get_src_stream_by_src_pad(struct v4l2_subdev *sd, u32 pad);
-int ipu6_isys_get_stream_pad_fmt(struct v4l2_subdev *sd, u32 pad, u32 stream,
- struct v4l2_mbus_framefmt *format);
-int ipu6_isys_get_stream_pad_crop(struct v4l2_subdev *sd, u32 pad, u32 stream,
- struct v4l2_rect *crop);
-int ipu6_isys_subdev_set_routing(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *state,
- enum v4l2_subdev_format_whence which,
- struct v4l2_subdev_krouting *routing);
int ipu6_isys_subdev_init(struct ipu6_isys_subdev *asd,
const struct v4l2_subdev_ops *ops,
unsigned int nr_ctrls,
@@ -387,7 +387,7 @@ static int link_validate(struct media_link *link)
link->sink->entity->name);
s_pad = media_pad_remote_pad_first(&av->pad);
- s_stream = ipu6_isys_get_src_stream_by_src_pad(s_sd, s_pad->index);
+ s_stream = isys_get_src_stream_by_src_pad(s_sd, s_pad->index);
v4l2_subdev_lock_state(s_state);
@@ -456,16 +456,15 @@ static int ipu6_isys_fw_pin_cfg(struct ipu6_isys_video *av,
u32 src_stream;
int ret;
- src_stream = ipu6_isys_get_src_stream_by_src_pad(sd, src_pad->index);
- ret = ipu6_isys_get_stream_pad_fmt(sd, src_pad->index, src_stream,
- &fmt);
+ src_stream = isys_get_src_stream_by_src_pad(sd, src_pad->index);
+ ret = isys_get_stream_pad_fmt(sd, src_pad->index, src_stream, &fmt);
if (ret < 0) {
dev_err(dev, "can't get stream format (%d)\n", ret);
return ret;
}
- ret = ipu6_isys_get_stream_pad_crop(sd, src_pad->index, src_stream,
- &v4l2_crop);
+ ret = isys_get_stream_pad_crop(sd, src_pad->index, src_stream,
+ &v4l2_crop);
if (ret < 0) {
dev_err(dev, "can't get stream crop (%d)\n", ret);
return ret;
@@ -776,8 +775,8 @@ void ipu6_isys_configure_stream_watermark(struct ipu6_isys_video *av,
link_freq = ipu6_isys_csi2_get_link_freq(csi2);
if (link_freq > 0) {
lanes = csi2->nlanes;
- ret = ipu6_isys_get_stream_pad_fmt(&csi2->asd.sd, 0,
- av->source_stream, &format);
+ ret = isys_get_stream_pad_fmt(&csi2->asd.sd, 0,
+ av->source_stream, &format);
if (!ret) {
bpp = ipu6_isys_mbus_code_to_bpp(format.code);
pixel_rate = mul_u64_u32_div(link_freq, lanes * 2, bpp);
@@ -1003,7 +1002,7 @@ int ipu6_isys_video_set_streaming(struct ipu6_isys_video *av, int state,
sd = &stream->asd->sd;
r_pad = media_pad_remote_pad_first(&av->pad);
- r_stream = ipu6_isys_get_src_stream_by_src_pad(sd, r_pad->index);
+ r_stream = isys_get_src_stream_by_src_pad(sd, r_pad->index);
subdev_state = v4l2_subdev_lock_and_get_active_state(sd);
routing = &subdev_state->routing;
new file mode 100644
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013-2025 Intel Corporation
+ */
+
+#include "isys.h"
+
+int isys_get_stream_pad_fmt(struct v4l2_subdev *sd, u32 pad, u32 stream,
+ struct v4l2_mbus_framefmt *format)
+{
+ struct v4l2_mbus_framefmt *fmt;
+ struct v4l2_subdev_state *state;
+
+ if (!sd || !format)
+ return -EINVAL;
+
+ state = v4l2_subdev_lock_and_get_active_state(sd);
+ fmt = v4l2_subdev_state_get_format(state, pad, stream);
+ if (fmt)
+ *format = *fmt;
+ v4l2_subdev_unlock_state(state);
+
+ return fmt ? 0 : -EINVAL;
+}
+
+int isys_get_stream_pad_crop(struct v4l2_subdev *sd, u32 pad, u32 stream,
+ struct v4l2_rect *crop)
+{
+ struct v4l2_subdev_state *state;
+ struct v4l2_rect *rect;
+
+ if (!sd || !crop)
+ return -EINVAL;
+
+ state = v4l2_subdev_lock_and_get_active_state(sd);
+ rect = v4l2_subdev_state_get_crop(state, pad, stream);
+ if (rect)
+ *crop = *rect;
+ v4l2_subdev_unlock_state(state);
+
+ return rect ? 0 : -EINVAL;
+}
+
+u32 isys_get_src_stream_by_src_pad(struct v4l2_subdev *sd, u32 pad)
+{
+ struct v4l2_subdev_state *state;
+ struct v4l2_subdev_route *routes;
+ unsigned int i;
+ u32 source_stream = 0;
+
+ state = v4l2_subdev_lock_and_get_active_state(sd);
+ if (!state)
+ return 0;
+
+ routes = state->routing.routes;
+ for (i = 0; i < state->routing.num_routes; i++) {
+ if (routes[i].source_pad == pad) {
+ source_stream = routes[i].source_stream;
+ break;
+ }
+ }
+
+ v4l2_subdev_unlock_state(state);
+
+ return source_stream;
+}
+
+static int subdev_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_krouting *routing)
+{
+ static const struct v4l2_mbus_framefmt format = {
+ .width = 4096,
+ .height = 3072,
+ .code = MEDIA_BUS_FMT_SGRBG10_1X10,
+ .field = V4L2_FIELD_NONE,
+ };
+ int ret;
+
+ ret = v4l2_subdev_routing_validate(sd, routing,
+ V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
+ if (ret)
+ return ret;
+
+ return v4l2_subdev_set_routing_with_fmt(sd, state, routing, &format);
+}
+
+int isys_subdev_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ enum v4l2_subdev_format_whence which,
+ struct v4l2_subdev_krouting *routing)
+{
+ return subdev_set_routing(sd, state, routing);
+}
new file mode 100644
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (C) 2025 Intel Corporation */
+
+#ifndef ISYS_H
+#define ISYS_H
+
+#include <media/v4l2-subdev.h>
+
+int isys_get_stream_pad_fmt(struct v4l2_subdev *sd, u32 pad, u32 stream,
+ struct v4l2_mbus_framefmt *format);
+int isys_get_stream_pad_crop(struct v4l2_subdev *sd, u32 pad, u32 stream,
+ struct v4l2_rect *crop);
+u32 isys_get_src_stream_by_src_pad(struct v4l2_subdev *sd, u32 pad);
+
+int isys_subdev_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ enum v4l2_subdev_format_whence which,
+ struct v4l2_subdev_krouting *routing);
+#endif
Move ipu6 isys functions that do not have dependency's other than v4l-subdev into separate file. Rename them using isys_ prefix. This is initial commit of changes that separate layers in ipu6 driver to make them reusable in incoming ipu7 driver. Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> --- drivers/media/pci/intel/ipu6/Makefile | 3 +- drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c | 2 +- .../media/pci/intel/ipu6/ipu6-isys-queue.c | 5 +- .../media/pci/intel/ipu6/ipu6-isys-subdev.c | 68 -------------- .../media/pci/intel/ipu6/ipu6-isys-subdev.h | 11 +-- .../media/pci/intel/ipu6/ipu6-isys-video.c | 17 ++-- drivers/media/pci/intel/ipu6/isys-subdev.c | 94 +++++++++++++++++++ drivers/media/pci/intel/ipu6/isys.h | 19 ++++ 8 files changed, 128 insertions(+), 91 deletions(-) create mode 100644 drivers/media/pci/intel/ipu6/isys-subdev.c create mode 100644 drivers/media/pci/intel/ipu6/isys.h