From: Jai Luthra <jai.luthra@ideasonboard.com>
To: Jai Luthra <jai.luthra@linux.dev>,
Mauro Carvalho Chehab <mchehab@kernel.org>,
Hans Verkuil <hverkuil@xs4all.nl>,
Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>,
Sakari Ailus <sakari.ailus@linux.intel.com>,
Maxime Ripard <mripard@kernel.org>
Cc: Devarsh Thakkar <devarsht@ti.com>,
Rishikesh Donadkar <r-donadkar@ti.com>,
Vaishnav Achath <vaishnav.a@ti.com>,
Changhuang Liang <changhuang.liang@starfivetech.com>,
linux-media@vger.kernel.org, linux-kernel@vger.kernel.org,
Jai Luthra <jai.luthra@ideasonboard.com>
Subject: [PATCH 5/6] media: cadence: cdns-csi2rx: Support multiple pixels per clock cycle
Date: Mon, 24 Mar 2025 17:31:41 +0530 [thread overview]
Message-ID: <20250324-probe_fixes-v1-5-5cd5b9e1cfac@ideasonboard.com> (raw)
In-Reply-To: <20250324-probe_fixes-v1-0-5cd5b9e1cfac@ideasonboard.com>
The output pixel interface is a parallel bus (32 bits), which
supports sending multiple pixels (1, 2 or 4) per clock cycle for
smaller pixel widths like RAW8-RAW16.
Dual-pixel and Quad-pixel modes can be a requirement if the export rate
of the Cadence IP in Single-pixel mode maxes out before the maximum
supported DPHY-RX frequency, which is the case with TI's integration of
this IP [1].
So, we export a function that lets the downstream hardware block request
a higher pixel-per-clock on a particular output pad.
We check if we can support the requested pixels per clock given the
known maximum for the currently configured format. If not, we set it
to the highest feasible value and return this value to the caller.
[1] Section 12.6.1.4.8.14 CSI_RX_IF Programming Restrictions of AM62 TRM
Link: https://www.ti.com/lit/pdf/spruj16
Signed-off-by: Jai Luthra <jai.luthra@ideasonboard.com>
---
drivers/media/platform/cadence/cdns-csi2rx.c | 74 +++++++++++++++++++++-------
drivers/media/platform/cadence/cdns-csi2rx.h | 19 +++++++
2 files changed, 75 insertions(+), 18 deletions(-)
diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index b489967563cde96ac109c44a665b30e573125721..e394afe954fcdb7219dfd14df7a82e8e19cbd572 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -22,6 +22,8 @@
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
+#include "cdns-csi2rx.h"
+
#define CSI2RX_DEVICE_CFG_REG 0x000
#define CSI2RX_SOFT_RESET_REG 0x004
@@ -53,6 +55,8 @@
#define CSI2RX_STREAM_CFG_REG(n) (CSI2RX_STREAM_BASE(n) + 0x00c)
#define CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF (1 << 8)
+#define CSI2RX_STREAM_CFG_NUM_PIXELS_MASK GENMASK(5, 4)
+#define CSI2RX_STREAM_CFG_NUM_PIXELS(n) ((n) >> 1)
#define CSI2RX_LANES_MAX 4
#define CSI2RX_STREAMS_MAX 4
@@ -68,7 +72,10 @@ enum csi2rx_pads {
struct csi2rx_fmt {
u32 code;
+ /* width of a single pixel on CSI-2 bus */
u8 bpp;
+ /* max pixels per clock supported on output bus */
+ u8 max_pixels;
};
struct csi2rx_priv {
@@ -90,6 +97,7 @@ struct csi2rx_priv {
struct reset_control *pixel_rst[CSI2RX_STREAMS_MAX];
struct phy *dphy;
+ u8 num_pixels[CSI2RX_STREAMS_MAX];
u8 lanes[CSI2RX_LANES_MAX];
u8 num_lanes;
u8 max_lanes;
@@ -106,22 +114,22 @@ struct csi2rx_priv {
};
static const struct csi2rx_fmt formats[] = {
- { .code = MEDIA_BUS_FMT_YUYV8_1X16, .bpp = 16, },
- { .code = MEDIA_BUS_FMT_UYVY8_1X16, .bpp = 16, },
- { .code = MEDIA_BUS_FMT_YVYU8_1X16, .bpp = 16, },
- { .code = MEDIA_BUS_FMT_VYUY8_1X16, .bpp = 16, },
- { .code = MEDIA_BUS_FMT_SBGGR8_1X8, .bpp = 8, },
- { .code = MEDIA_BUS_FMT_SGBRG8_1X8, .bpp = 8, },
- { .code = MEDIA_BUS_FMT_SGRBG8_1X8, .bpp = 8, },
- { .code = MEDIA_BUS_FMT_SRGGB8_1X8, .bpp = 8, },
- { .code = MEDIA_BUS_FMT_Y8_1X8, .bpp = 8, },
- { .code = MEDIA_BUS_FMT_SBGGR10_1X10, .bpp = 10, },
- { .code = MEDIA_BUS_FMT_SGBRG10_1X10, .bpp = 10, },
- { .code = MEDIA_BUS_FMT_SGRBG10_1X10, .bpp = 10, },
- { .code = MEDIA_BUS_FMT_SRGGB10_1X10, .bpp = 10, },
- { .code = MEDIA_BUS_FMT_RGB565_1X16, .bpp = 16, },
- { .code = MEDIA_BUS_FMT_RGB888_1X24, .bpp = 24, },
- { .code = MEDIA_BUS_FMT_BGR888_1X24, .bpp = 24, },
+ { .code = MEDIA_BUS_FMT_YUYV8_1X16, .bpp = 16, .max_pixels = 2, },
+ { .code = MEDIA_BUS_FMT_UYVY8_1X16, .bpp = 16, .max_pixels = 2, },
+ { .code = MEDIA_BUS_FMT_YVYU8_1X16, .bpp = 16, .max_pixels = 2, },
+ { .code = MEDIA_BUS_FMT_VYUY8_1X16, .bpp = 16, .max_pixels = 2, },
+ { .code = MEDIA_BUS_FMT_SBGGR8_1X8, .bpp = 8, .max_pixels = 4, },
+ { .code = MEDIA_BUS_FMT_SGBRG8_1X8, .bpp = 8, .max_pixels = 4, },
+ { .code = MEDIA_BUS_FMT_SGRBG8_1X8, .bpp = 8, .max_pixels = 4, },
+ { .code = MEDIA_BUS_FMT_SRGGB8_1X8, .bpp = 8, .max_pixels = 4, },
+ { .code = MEDIA_BUS_FMT_Y8_1X8, .bpp = 8, .max_pixels = 4, },
+ { .code = MEDIA_BUS_FMT_SBGGR10_1X10, .bpp = 10, .max_pixels = 2, },
+ { .code = MEDIA_BUS_FMT_SGBRG10_1X10, .bpp = 10, .max_pixels = 2, },
+ { .code = MEDIA_BUS_FMT_SGRBG10_1X10, .bpp = 10, .max_pixels = 2, },
+ { .code = MEDIA_BUS_FMT_SRGGB10_1X10, .bpp = 10, .max_pixels = 2, },
+ { .code = MEDIA_BUS_FMT_RGB565_1X16, .bpp = 16, .max_pixels = 1, },
+ { .code = MEDIA_BUS_FMT_RGB888_1X24, .bpp = 24, .max_pixels = 1, },
+ { .code = MEDIA_BUS_FMT_BGR888_1X24, .bpp = 24, .max_pixels = 1, },
};
static const struct csi2rx_fmt *csi2rx_get_fmt_by_code(u32 code)
@@ -274,8 +282,10 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx)
reset_control_deassert(csi2rx->pixel_rst[i]);
- writel(CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF,
- csi2rx->base + CSI2RX_STREAM_CFG_REG(i));
+ reg = CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF;
+ reg |= FIELD_PREP(CSI2RX_STREAM_CFG_NUM_PIXELS_MASK,
+ csi2rx->num_pixels[i]);
+ writel(reg, csi2rx->base + CSI2RX_STREAM_CFG_REG(i));
/*
* Enable one virtual channel. When multiple virtual channels
@@ -456,6 +466,34 @@ static int csi2rx_init_state(struct v4l2_subdev *subdev,
return csi2rx_set_fmt(subdev, state, &format);
}
+int cdns_csi2rx_negotiate_ppc(struct v4l2_subdev *subdev, unsigned int pad,
+ u8 *ppc)
+{
+ struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev);
+ const struct csi2rx_fmt *csi_fmt;
+ struct v4l2_subdev_state *state;
+ struct v4l2_mbus_framefmt *fmt;
+ int ret = 0;
+
+ if (!ppc || pad < CSI2RX_PAD_SOURCE_STREAM0 || pad >= CSI2RX_PAD_MAX)
+ return -EINVAL;
+
+ state = v4l2_subdev_lock_and_get_active_state(subdev);
+ fmt = v4l2_subdev_state_get_format(state, pad);
+ csi_fmt = csi2rx_get_fmt_by_code(fmt->code);
+
+ /* Reduce requested PPC if it is too high */
+ *ppc = min(*ppc, csi_fmt->max_pixels);
+
+ v4l2_subdev_unlock_state(state);
+
+ csi2rx->num_pixels[pad - CSI2RX_PAD_SOURCE_STREAM0] =
+ CSI2RX_STREAM_CFG_NUM_PIXELS(*ppc);
+
+ return ret;
+}
+EXPORT_SYMBOL(cdns_csi2rx_negotiate_ppc);
+
static const struct v4l2_subdev_pad_ops csi2rx_pad_ops = {
.enum_mbus_code = csi2rx_enum_mbus_code,
.get_fmt = v4l2_subdev_get_fmt,
diff --git a/drivers/media/platform/cadence/cdns-csi2rx.h b/drivers/media/platform/cadence/cdns-csi2rx.h
new file mode 100644
index 0000000000000000000000000000000000000000..128d47e8513c99c083f49e249e876be6d19389f6
--- /dev/null
+++ b/drivers/media/platform/cadence/cdns-csi2rx.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+#ifndef CDNS_CSI2RX_H
+#define CDNS_CSI2RX_H
+
+#include <media/v4l2-subdev.h>
+
+/**
+ * cdns_csi2rx_negotiate_ppc - Negotiate pixel-per-clock on output interface
+ *
+ * @subdev: point to &struct v4l2_subdev
+ * @pad: pad number of the source pad
+ * @ppc: pointer to requested pixel-per-clock value
+ *
+ * Returns 0 on success, negative error code otherwise.
+ */
+int cdns_csi2rx_negotiate_ppc(struct v4l2_subdev *subdev, unsigned int pad,
+ u8 *ppc);
+
+#endif
--
2.48.1
next prev parent reply other threads:[~2025-03-24 12:02 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-24 12:01 [PATCH 0/6] media: ti, cdns: Multiple pixel support and misc fixes Jai Luthra
2025-03-24 12:01 ` [PATCH 1/6] media: ti: j721e-csi2rx: Use devm_of_platform_populate Jai Luthra
2025-03-27 6:25 ` Devarsh Thakkar
2025-03-24 12:01 ` [PATCH 2/6] media: ti: j721e-csi2rx: Use fwnode_get_named_child_node Jai Luthra
2025-03-27 6:31 ` Devarsh Thakkar
2025-03-24 12:01 ` [PATCH 3/6] media: ti: j721e-csi2rx: Fix source subdev link creation Jai Luthra
2025-03-27 10:14 ` Devarsh Thakkar
2025-03-24 12:01 ` [PATCH 4/6] media: cadence: csi2rx: Implement get_fwnode_pad op Jai Luthra
2025-03-27 10:24 ` Devarsh Thakkar
2025-03-28 2:39 ` 回复: " Changhuang Liang
2025-03-24 12:01 ` Jai Luthra [this message]
2025-03-24 14:28 ` [PATCH 5/6] media: cadence: cdns-csi2rx: Support multiple pixels per clock cycle kernel test robot
2025-03-24 18:21 ` kernel test robot
2025-03-24 12:01 ` [PATCH 6/6] media: ti: j721e-csi2rx: Support multiple pixels per clock Jai Luthra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250324-probe_fixes-v1-5-5cd5b9e1cfac@ideasonboard.com \
--to=jai.luthra@ideasonboard.com \
--cc=changhuang.liang@starfivetech.com \
--cc=devarsht@ti.com \
--cc=hverkuil@xs4all.nl \
--cc=jai.luthra@linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@kernel.org \
--cc=mripard@kernel.org \
--cc=r-donadkar@ti.com \
--cc=sakari.ailus@linux.intel.com \
--cc=tomi.valkeinen@ideasonboard.com \
--cc=vaishnav.a@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox