From: Dave Stevenson <dave.stevenson@raspberrypi.com>
To: Sakari Ailus <sakari.ailus@linux.intel.com>,
linux-media@vger.kernel.org, Rob Herring <robh+dt@kernel.org>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
Conor Dooley <conor+dt@kernel.org>,
devicetree@vger.kernel.org
Cc: Dave Stevenson <dave.stevenson@raspberrypi.com>
Subject: [PATCH 17/21] media: i2c: imx258: Support faster pixel rate on binned modes
Date: Tue, 30 May 2023 18:29:56 +0100 [thread overview]
Message-ID: <20230530173000.3060865-18-dave.stevenson@raspberrypi.com> (raw)
In-Reply-To: <20230530173000.3060865-1-dave.stevenson@raspberrypi.com>
With the binned modes, there is little point in faithfully
reproducing the horizontal line length of 5352 pixels on the CSI2
bus, and the FIFO between the pixel array and MIPI serialiser
allows us to remove that dependency.
Allow the pixel array to run with the normal settings, with the MIPI
serialiser at half the rate. This requires some additional
information for the link frequency to pixel rate function that
needs to be added to the configuration tables.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/imx258.c | 109 ++++++++++++++++++++++++-------------
1 file changed, 71 insertions(+), 38 deletions(-)
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index b9b650d40365..986757650378 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -103,6 +103,11 @@ struct imx258_reg_list {
const struct imx258_reg *regs;
};
+struct imx258_link_cfg {
+ unsigned int lf_to_pix_rate_factor;
+ struct imx258_reg_list reg_list;
+};
+
#define IMX258_LANE_CONFIGS 2
#define IMX258_2_LANE_MODE 0
#define IMX258_4_LANE_MODE 1
@@ -112,8 +117,8 @@ struct imx258_link_freq_config {
u64 link_frequency;
u32 pixels_per_line;
- /* PLL registers for this link frequency */
- struct imx258_reg_list reg_list[IMX258_LANE_CONFIGS];
+ /* Configuration for this link frequency / num lanes selection */
+ struct imx258_link_cfg link_cfg[IMX258_LANE_CONFIGS];
};
/* Mode : resolution and related config&values */
@@ -272,7 +277,7 @@ static const struct imx258_reg mipi_640mbps_19_2mhz_4l[] = {
static const struct imx258_reg mipi_642mbps_24mhz_2l[] = {
{ 0x0136, 0x18 },
{ 0x0137, 0x00 },
- { 0x0301, 0x0A },
+ { 0x0301, 0x05 },
{ 0x0303, 0x02 },
{ 0x0305, 0x04 },
{ 0x0306, 0x00 },
@@ -478,14 +483,22 @@ enum {
};
/*
- * pixel_rate = link_freq * data-rate * nr_of_lanes / bits_per_sample
- * data rate => double data rate;
- * number of lanes => (configurable 2 or 4);
- * bits per pixel => 10
+ * Pixel rate does not necessarily relate to link frequency on this sensor as
+ * there is a FIFO between the pixel array pipeline and the MIPI serializer.
+ * The recommendation from Sony is that the pixel array is always run with a
+ * line length of 5352 pixels, which means that there is a large amount of
+ * blanking time for the 1048x780 mode. There is no need to replicate this
+ * blanking on the CSI2 bus, and the configuration of register 0x0301 allows the
+ * divider to be altered.
+ *
+ * The actual factor between link frequency and pixel rate is in the
+ * imx258_link_cfg, so use this to convert between the two.
+ * bits per pixel being 10, and D-PHY being DDR is assumed by this function, so
+ * the value is only the combination of number of lanes and pixel clock divider.
*/
-static u64 link_freq_to_pixel_rate(u64 f, unsigned int nlanes)
+static u64 link_freq_to_pixel_rate(u64 f, const struct imx258_link_cfg *link_cfg)
{
- f *= 2 * nlanes;
+ f *= 2 * link_cfg->lf_to_pix_rate_factor;
do_div(f, 10);
return f;
@@ -510,31 +523,33 @@ static const s64 link_freq_menu_items_24[] = {
IMX258_LINK_FREQ_321MHZ,
};
+#define REGS(_list) { .num_of_regs = ARRAY_SIZE(_list), .regs = _list, }
+
/* Link frequency configs */
static const struct imx258_link_freq_config link_freq_configs_19_2[] = {
[IMX258_LINK_FREQ_1267MBPS] = {
.pixels_per_line = IMX258_PPL_DEFAULT,
- .reg_list = {
+ .link_cfg = {
[IMX258_2_LANE_MODE] = {
- .num_of_regs = ARRAY_SIZE(mipi_1267mbps_19_2mhz_2l),
- .regs = mipi_1267mbps_19_2mhz_2l,
+ .lf_to_pix_rate_factor = 2 * 2,
+ .reg_list = REGS(mipi_1267mbps_19_2mhz_2l),
},
[IMX258_4_LANE_MODE] = {
- .num_of_regs = ARRAY_SIZE(mipi_1267mbps_19_2mhz_4l),
- .regs = mipi_1267mbps_19_2mhz_4l,
+ .lf_to_pix_rate_factor = 4,
+ .reg_list = REGS(mipi_1267mbps_19_2mhz_4l),
},
}
},
[IMX258_LINK_FREQ_640MBPS] = {
.pixels_per_line = IMX258_PPL_DEFAULT,
- .reg_list = {
+ .link_cfg = {
[IMX258_2_LANE_MODE] = {
- .num_of_regs = ARRAY_SIZE(mipi_640mbps_19_2mhz_2l),
- .regs = mipi_640mbps_19_2mhz_2l,
+ .lf_to_pix_rate_factor = 2,
+ .reg_list = REGS(mipi_640mbps_19_2mhz_2l),
},
[IMX258_4_LANE_MODE] = {
- .num_of_regs = ARRAY_SIZE(mipi_640mbps_19_2mhz_4l),
- .regs = mipi_640mbps_19_2mhz_4l,
+ .lf_to_pix_rate_factor = 4,
+ .reg_list = REGS(mipi_640mbps_19_2mhz_4l),
},
}
},
@@ -543,27 +558,27 @@ static const struct imx258_link_freq_config link_freq_configs_19_2[] = {
static const struct imx258_link_freq_config link_freq_configs_24[] = {
[IMX258_LINK_FREQ_1267MBPS] = {
.pixels_per_line = IMX258_PPL_DEFAULT,
- .reg_list = {
+ .link_cfg = {
[IMX258_2_LANE_MODE] = {
- .num_of_regs = ARRAY_SIZE(mipi_1272mbps_24mhz_2l),
- .regs = mipi_1272mbps_24mhz_2l,
+ .lf_to_pix_rate_factor = 2,
+ .reg_list = REGS(mipi_1272mbps_24mhz_2l),
},
[IMX258_4_LANE_MODE] = {
- .num_of_regs = ARRAY_SIZE(mipi_1272mbps_24mhz_4l),
- .regs = mipi_1272mbps_24mhz_4l,
+ .lf_to_pix_rate_factor = 4,
+ .reg_list = REGS(mipi_1272mbps_24mhz_4l),
},
}
},
[IMX258_LINK_FREQ_640MBPS] = {
.pixels_per_line = IMX258_PPL_DEFAULT,
- .reg_list = {
+ .link_cfg = {
[IMX258_2_LANE_MODE] = {
- .num_of_regs = ARRAY_SIZE(mipi_642mbps_24mhz_2l),
- .regs = mipi_642mbps_24mhz_2l,
+ .lf_to_pix_rate_factor = 2 * 2,
+ .reg_list = REGS(mipi_642mbps_24mhz_2l),
},
[IMX258_4_LANE_MODE] = {
- .num_of_regs = ARRAY_SIZE(mipi_642mbps_24mhz_4l),
- .regs = mipi_642mbps_24mhz_4l,
+ .lf_to_pix_rate_factor = 4,
+ .reg_list = REGS(mipi_642mbps_24mhz_4l),
},
}
},
@@ -643,7 +658,7 @@ struct imx258 {
const struct imx258_link_freq_config *link_freq_configs;
const s64 *link_freq_menu_items;
- unsigned int nlanes;
+ unsigned int lane_mode_idx;
unsigned int csi2_flags;
/*
@@ -976,8 +991,10 @@ static int imx258_set_pad_format(struct v4l2_subdev *sd,
struct v4l2_subdev_format *fmt)
{
struct imx258 *imx258 = to_imx258(sd);
- const struct imx258_mode *mode;
+ const struct imx258_link_freq_config *link_freq_cfgs;
+ const struct imx258_link_cfg *link_cfg;
struct v4l2_mbus_framefmt *framefmt;
+ const struct imx258_mode *mode;
s32 vblank_def;
s32 vblank_min;
s64 h_blank;
@@ -1001,7 +1018,11 @@ static int imx258_set_pad_format(struct v4l2_subdev *sd,
__v4l2_ctrl_s_ctrl(imx258->link_freq, mode->link_freq_index);
link_freq = imx258->link_freq_menu_items[mode->link_freq_index];
- pixel_rate = link_freq_to_pixel_rate(link_freq, imx258->nlanes);
+ link_freq_cfgs =
+ &imx258->link_freq_configs[mode->link_freq_index];
+
+ link_cfg = &link_freq_cfgs->link_cfg[imx258->lane_mode_idx];
+ pixel_rate = link_freq_to_pixel_rate(link_freq, link_cfg);
__v4l2_ctrl_modify_range(imx258->pixel_rate, pixel_rate,
pixel_rate, 1, pixel_rate);
/* Update limits and set FPS to default */
@@ -1098,7 +1119,8 @@ static int imx258_start_streaming(struct imx258 *imx258)
/* Setup PLL */
link_freq_index = imx258->cur_mode->link_freq_index;
link_freq_cfg = &imx258->link_freq_configs[link_freq_index];
- reg_list = &link_freq_cfg->reg_list[imx258->nlanes == 2 ? 0 : 1];
+
+ reg_list = &link_freq_cfg->link_cfg[imx258->lane_mode_idx].reg_list;
ret = imx258_write_regs(imx258, reg_list->regs, reg_list->num_of_regs);
if (ret) {
dev_err(&client->dev, "%s failed to set plls\n", __func__);
@@ -1324,9 +1346,11 @@ static const struct v4l2_subdev_internal_ops imx258_internal_ops = {
static int imx258_init_controls(struct imx258 *imx258)
{
struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
+ const struct imx258_link_freq_config *link_freq_cfgs;
struct v4l2_fwnode_device_properties props;
- struct v4l2_ctrl_handler *ctrl_hdlr;
struct v4l2_ctrl *vflip, *hflip;
+ struct v4l2_ctrl_handler *ctrl_hdlr;
+ const struct imx258_link_cfg *link_cfg;
s64 vblank_def;
s64 vblank_min;
s64 pixel_rate;
@@ -1360,8 +1384,11 @@ static int imx258_init_controls(struct imx258 *imx258)
if (vflip)
vflip->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ link_freq_cfgs = &imx258->link_freq_configs[0];
+ link_cfg = link_freq_cfgs[imx258->lane_mode_idx].link_cfg;
pixel_rate = link_freq_to_pixel_rate(imx258->link_freq_menu_items[0],
- imx258->nlanes);
+ link_cfg);
+
/* By default, PIXEL_RATE is read only */
imx258->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,
V4L2_CID_PIXEL_RATE,
@@ -1522,10 +1549,16 @@ static int imx258_probe(struct i2c_client *client)
}
/* Get number of data lanes */
- imx258->nlanes = ep.bus.mipi_csi2.num_data_lanes;
- if (imx258->nlanes != 2 && imx258->nlanes != 4) {
+ switch (ep.bus.mipi_csi2.num_data_lanes) {
+ case 2:
+ imx258->lane_mode_idx = IMX258_2_LANE_MODE;
+ break;
+ case 4:
+ imx258->lane_mode_idx = IMX258_4_LANE_MODE;
+ break;
+ default:
dev_err(&client->dev, "Invalid data lanes: %u\n",
- imx258->nlanes);
+ ep.bus.mipi_csi2.num_data_lanes);
ret = -EINVAL;
goto error_endpoint_poweron;
}
--
2.25.1
next prev parent reply other threads:[~2023-05-30 17:31 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-30 17:29 [PATCH 00/21] imx258 improvements series Dave Stevenson
2023-05-30 17:29 ` [PATCH 01/21] media: i2c: imx258: Remove unused defines Dave Stevenson
2023-05-31 15:08 ` Jacopo Mondi
2023-05-30 17:29 ` [PATCH 02/21] media: i2c: imx258: Make image geometry meet sensor requirements Dave Stevenson
2023-05-31 15:09 ` Jacopo Mondi
2023-05-30 17:29 ` [PATCH 03/21] media: i2c: imx258: Disable digital cropping on binned modes Dave Stevenson
2023-05-31 15:02 ` Jacopo Mondi
2023-05-30 17:29 ` [PATCH 04/21] media: i2c: imx258: Remove redundant I2C writes Dave Stevenson
2023-05-31 15:10 ` Jacopo Mondi
2023-05-30 17:29 ` [PATCH 05/21] media: i2c: imx258: Add regulator control Dave Stevenson
2023-05-31 15:11 ` Jacopo Mondi
2023-05-31 15:26 ` Dave Stevenson
2023-05-30 17:29 ` [PATCH 06/21] media: i2c: imx258: Make V4L2_CID_VBLANK configurable Dave Stevenson
2023-05-31 15:16 ` Jacopo Mondi
2023-05-31 15:33 ` Dave Stevenson
2023-05-30 17:29 ` [PATCH 07/21] media: i2c: imx258: Split out common registers from the mode based ones Dave Stevenson
2023-05-31 15:26 ` Jacopo Mondi
2023-05-30 17:29 ` [PATCH 08/21] media: i2c: imx258: Add support for 24MHz clock Dave Stevenson
2023-06-02 12:59 ` Jacopo Mondi
2023-05-30 17:29 ` [PATCH 09/21] media: i2c: imx258: Add support for running on 2 CSI data lanes Dave Stevenson
2023-05-30 17:37 ` Dave Stevenson
2023-05-31 8:07 ` kernel test robot
2023-06-02 13:23 ` Jacopo Mondi
2023-06-02 17:46 ` Dave Stevenson
2023-05-30 17:29 ` [PATCH 10/21] media: i2c: imx258: Follow normal V4L2 behaviours for clipping exposure Dave Stevenson
2023-05-31 15:27 ` Jacopo Mondi
2023-05-30 17:29 ` [PATCH 11/21] media: i2c: imx258: Add get_selection for pixel array information Dave Stevenson
2023-06-02 13:24 ` Jacopo Mondi
2023-05-30 17:29 ` [PATCH 12/21] media: i2c: imx258: Allow configuration of clock lane behaviour Dave Stevenson
2023-06-02 13:26 ` Jacopo Mondi
2023-06-02 15:18 ` Dave Stevenson
2023-05-30 17:29 ` [PATCH 13/21] media: i2c: imx258: Correct max FRM_LENGTH_LINES value Dave Stevenson
2023-06-02 13:33 ` Jacopo Mondi
2023-05-30 17:29 ` [PATCH 14/21] media: i2c: imx258: Add support for long exposure modes Dave Stevenson
2023-06-02 13:38 ` Jacopo Mondi
2023-06-02 17:12 ` Dave Stevenson
2023-05-30 17:29 ` [PATCH 15/21] media: i2c: imx258: Issue reset before starting streaming Dave Stevenson
2023-06-02 13:42 ` Jacopo Mondi
2023-05-30 17:29 ` [PATCH 16/21] media: i2c: imx258: Set pixel_rate range to the same as the value Dave Stevenson
2023-06-02 13:44 ` Jacopo Mondi
2023-05-30 17:29 ` Dave Stevenson [this message]
2023-05-30 17:29 ` [PATCH 18/21] dt-bindings: media: imx258: Rename to include vendor prefix Dave Stevenson
2023-05-30 17:35 ` Conor Dooley
2023-05-30 17:29 ` [PATCH 19/21] dt-bindings: media: imx258: Add alternate compatible strings Dave Stevenson
2023-05-30 17:38 ` Conor Dooley
2023-05-30 17:48 ` Dave Stevenson
2023-05-30 19:36 ` Conor Dooley
2023-05-30 17:29 ` [PATCH 20/21] media: i2c: imx258: Change register settings for variants of the sensor Dave Stevenson
2023-06-02 13:48 ` Jacopo Mondi
2023-06-02 14:30 ` Dave Stevenson
2023-05-30 17:30 ` [PATCH 21/21] media: i2c: imx258: Make HFLIP and VFLIP controls writable Dave Stevenson
2023-06-02 13:58 ` Jacopo Mondi
2023-06-02 14:42 ` Dave Stevenson
2023-07-18 12:08 ` [PATCH 00/21] imx258 improvements series Arnaud Ferraris
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=20230530173000.3060865-18-dave.stevenson@raspberrypi.com \
--to=dave.stevenson@raspberrypi.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=linux-media@vger.kernel.org \
--cc=robh+dt@kernel.org \
--cc=sakari.ailus@linux.intel.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;
as well as URLs for NNTP newsgroup(s).