[PATCH 13/13] media: i2c: os05b10: add 2-lane support

Tarang Raval posted 13 patches 1 month ago
There is a newer version of this series
[PATCH 13/13] media: i2c: os05b10: add 2-lane support
Posted by Tarang Raval 1 month ago
Add support for 2-lane.

Update link-frequency handling to select 750 MHz for 2-lane and 600 MHz for
4-lane, and adjust pixel rate computation accordingly. Extend endpoint
parsing to accept 2 or 4 data lanes.

Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
---
 drivers/media/i2c/os05b10.c | 94 ++++++++++++++++++++++++++++---------
 1 file changed, 71 insertions(+), 23 deletions(-)

diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
index 1393c7b5d860..7107a69157e8 100644
--- a/drivers/media/i2c/os05b10.c
+++ b/drivers/media/i2c/os05b10.c
@@ -114,7 +114,8 @@
 #define OS05B10_TRANSPARENT_EFFECT	0xa0
 #define OS05B10_ROLLING_BAR_EFFECT	0xc0
 
-#define OS05B10_LINK_FREQ_600MHZ	(600 * HZ_PER_MHZ)
+#define OS05B10_LINK_FREQ_4LANE		(600 * HZ_PER_MHZ)
+#define OS05B10_LINK_FREQ_2LANE		(750 * HZ_PER_MHZ)
 
 static const struct v4l2_rect os05b10_native_area = {
 	.top = 0,
@@ -137,12 +138,6 @@ static const char * const os05b10_supply_name[] = {
 };
 
 static const struct cci_reg_sequence os05b10_common_regs[] = {
-	{ OS05B10_REG_PLL_CTRL_01, 		0x44 },
-	{ OS05B10_REG_PLL_CTRL_03, 		0x02 },
-	{ OS05B10_REG_PLL_CTRL_05, 		0x32 },
-	{ OS05B10_REG_PLL_CTRL_06, 		0x00 },
-	{ OS05B10_REG_PLL_CTRL_25, 		0x3b },
-	{ OS05B10_REG_MIPI_SC_CTRL, 		0x72 },
 	{ OS05B10_REG_ANALOG_GAIN_SHORT, 	0x0080 },
 	{ OS05B10_REG_DIGITAL_GAIN_SHORT, 	0x0400 },
 	{ OS05B10_REG_EXPOSURE_SHORT, 		0x000020 },
@@ -533,6 +528,24 @@ static const struct cci_reg_sequence mode_1280_720_regs[] = {
 	{ CCI_REG8(0x4837), 0x0d },
 };
 
+static const struct cci_reg_sequence os05b10_2lane_regs[] = {
+	{ OS05B10_REG_PLL_CTRL_01, 	0x44 },
+	{ OS05B10_REG_PLL_CTRL_03, 	0x02 },
+	{ OS05B10_REG_PLL_CTRL_05, 	0x64 },
+	{ OS05B10_REG_PLL_CTRL_06, 	0x00 },
+	{ OS05B10_REG_PLL_CTRL_25, 	0x3b },
+	{ OS05B10_REG_MIPI_SC_CTRL,	OS05B10_2_LANE_MODE },
+};
+
+static const struct cci_reg_sequence os05b10_4lane_regs[] = {
+	{ OS05B10_REG_PLL_CTRL_01, 	0x44 },
+	{ OS05B10_REG_PLL_CTRL_03, 	0x02 },
+	{ OS05B10_REG_PLL_CTRL_05, 	0x32 },
+	{ OS05B10_REG_PLL_CTRL_06, 	0x00 },
+	{ OS05B10_REG_PLL_CTRL_25, 	0x3b },
+	{ OS05B10_REG_MIPI_SC_CTRL, 	OS05B10_4_LANE_MODE },
+};
+
 struct os05b10 {
 	struct device *dev;
 	struct regmap *cci;
@@ -652,8 +665,12 @@ static const struct os05b10_mode supported_modes_10bit[] = {
 	},
 };
 
-static const s64 link_frequencies[] = {
-	OS05B10_LINK_FREQ_600MHZ,
+static const s64 link_frequencies_4lane[] = {
+	OS05B10_LINK_FREQ_4LANE,
+};
+
+static const s64 link_frequencies_2lane[] = {
+	OS05B10_LINK_FREQ_2LANE,
 };
 
 static const u32 os05b10_mbus_codes[] = {
@@ -804,7 +821,9 @@ static int os05b10_enum_mbus_code(struct v4l2_subdev *sd,
 static u64 os05b10_pixel_rate(struct os05b10 *os05b10,
 			      const struct os05b10_mode *mode)
 {
-	u64 link_freq = link_frequencies[os05b10->link_freq_index];
+	u64 link_freq = (os05b10->data_lanes == 2) ?
+			link_frequencies_2lane[os05b10->link_freq_index] :
+			link_frequencies_4lane[os05b10->link_freq_index];
 	u64 pixel_rate = div_u64(link_freq * 2 * os05b10->data_lanes, mode->bpp);
 
 	dev_dbg(os05b10->dev,
@@ -972,6 +991,17 @@ static int os05b10_enable_streams(struct v4l2_subdev *sd,
 	ret = pm_runtime_resume_and_get(os05b10->dev);
 	if (ret < 0)
 		return ret;
+	/* Set pll & mipi lane configuration */
+	if (os05b10->data_lanes == 2)
+		cci_multi_reg_write(os05b10->cci, os05b10_2lane_regs,
+				    ARRAY_SIZE(os05b10_2lane_regs), &ret);
+	else
+		cci_multi_reg_write(os05b10->cci, os05b10_4lane_regs,
+				    ARRAY_SIZE(os05b10_4lane_regs), &ret);
+	if (ret) {
+		dev_err(os05b10->dev, "failed to write pll & mipi lane registers\n");
+		goto err_rpm_put;
+	}
 
 	/* Write common registers */
 	ret = cci_multi_reg_write(os05b10->cci, os05b10_common_regs,
@@ -1184,22 +1214,39 @@ static int os05b10_parse_endpoint(struct os05b10 *os05b10)
 	if (ret)
 		return ret;
 
-	if (bus_cfg.bus.mipi_csi2.num_data_lanes != 4) {
+	if (bus_cfg.bus.mipi_csi2.num_data_lanes != 4 &&
+	    bus_cfg.bus.mipi_csi2.num_data_lanes != 2) {
 		ret = dev_err_probe(os05b10->dev, -EINVAL,
-				    "only 4 data lanes are supported\n");
+				    "4 and 2 data lanes are supported\n");
 		goto error_out;
 	}
 
 	os05b10->data_lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
 
-	ret = v4l2_link_freq_to_bitmap(os05b10->dev, bus_cfg.link_frequencies,
-				       bus_cfg.nr_of_link_frequencies,
-				       link_frequencies,
-				       ARRAY_SIZE(link_frequencies),
-				       &link_freq_bitmap);
-	if (ret) {
-		dev_err(os05b10->dev, "only 600MHz frequency is available\n");
-		goto error_out;
+	if (os05b10->data_lanes == 2) {
+		ret = v4l2_link_freq_to_bitmap(os05b10->dev,
+					       bus_cfg.link_frequencies_2lane,
+					       bus_cfg.nr_of_link_frequencies_2lane,
+					       link_frequencies_2lane,
+					       ARRAY_SIZE(link_frequencies_2lane),
+					       &link_freq_bitmap);
+		if (ret) {
+			dev_err(os05b10->dev,
+				"For 2 lane 750MHz frequency is available\n");
+			goto error_out;
+		}
+	} else {
+		ret = v4l2_link_freq_to_bitmap(os05b10->dev,
+					       bus_cfg.link_frequencies_4lane,
+					       bus_cfg.nr_of_link_frequencies_4lane,
+					       link_frequencies_4lane,
+					       ARRAY_SIZE(link_frequencies_4lane),
+					       &link_freq_bitmap);
+		if (ret) {
+			dev_err(os05b10->dev,
+				"For 4 lane 600MHz frequency is available\n");
+			goto error_out;
+		}
 	}
 
 	os05b10->link_freq_index = __ffs(link_freq_bitmap);
@@ -1229,10 +1276,11 @@ static int os05b10_init_controls(struct os05b10 *os05b10)
 
 	os05b10->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &os05b10_ctrl_ops,
 						    V4L2_CID_LINK_FREQ,
-						    ARRAY_SIZE(link_frequencies) - 1,
+						    ARRAY_SIZE(link_frequencies_4lane) - 1,
 						    os05b10->link_freq_index,
-						    link_frequencies);
-
+						    (os05b10->data_lanes == 2) ?
+						    link_frequencies_2lane :
+						    link_frequencies_4lane);
 	if (os05b10->link_freq)
 		os05b10->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 
-- 
2.34.1
Re: [PATCH 13/13] media: i2c: os05b10: add 2-lane support
Posted by kernel test robot 1 month ago
Hi Tarang,

kernel test robot noticed the following build errors:

[auto build test ERROR on sailus-media-tree/master]
[also build test ERROR on linus/master v7.0-rc2 next-20260306]
[cannot apply to sailus-media-tree/streams]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Tarang-Raval/media-i2c-os05b10-drop-unused-group-hold-programming/20260306-212656
base:   git://linuxtv.org/sailus/media_tree.git master
patch link:    https://lore.kernel.org/r/20260306123304.76722-14-tarang.raval%40siliconsignals.io
patch subject: [PATCH 13/13] media: i2c: os05b10: add 2-lane support
config: openrisc-randconfig-r071-20260307 (https://download.01.org/0day-ci/archive/20260307/202603070920.GtWqPt5Q-lkp@intel.com/config)
compiler: or1k-linux-gcc (GCC) 15.2.0
smatch: v0.5.0-9004-gb810ac53
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260307/202603070920.GtWqPt5Q-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603070920.GtWqPt5Q-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/media/i2c/os05b10.c: In function 'os05b10_parse_endpoint':
>> drivers/media/i2c/os05b10.c:1228:56: error: 'struct v4l2_fwnode_endpoint' has no member named 'link_frequencies_2lane'; did you mean 'link_frequencies'?
    1228 |                                                bus_cfg.link_frequencies_2lane,
         |                                                        ^~~~~~~~~~~~~~~~~~~~~~
         |                                                        link_frequencies
>> drivers/media/i2c/os05b10.c:1229:56: error: 'struct v4l2_fwnode_endpoint' has no member named 'nr_of_link_frequencies_2lane'; did you mean 'nr_of_link_frequencies'?
    1229 |                                                bus_cfg.nr_of_link_frequencies_2lane,
         |                                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
         |                                                        nr_of_link_frequencies
>> drivers/media/i2c/os05b10.c:1240:56: error: 'struct v4l2_fwnode_endpoint' has no member named 'link_frequencies_4lane'; did you mean 'link_frequencies'?
    1240 |                                                bus_cfg.link_frequencies_4lane,
         |                                                        ^~~~~~~~~~~~~~~~~~~~~~
         |                                                        link_frequencies
>> drivers/media/i2c/os05b10.c:1241:56: error: 'struct v4l2_fwnode_endpoint' has no member named 'nr_of_link_frequencies_4lane'; did you mean 'nr_of_link_frequencies'?
    1241 |                                                bus_cfg.nr_of_link_frequencies_4lane,
         |                                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
         |                                                        nr_of_link_frequencies


vim +1228 drivers/media/i2c/os05b10.c

  1196	
  1197	static int os05b10_parse_endpoint(struct os05b10 *os05b10)
  1198	{
  1199		struct v4l2_fwnode_endpoint bus_cfg = {
  1200			.bus_type = V4L2_MBUS_CSI2_DPHY
  1201		};
  1202		unsigned long link_freq_bitmap;
  1203		struct fwnode_handle *ep;
  1204		int ret;
  1205	
  1206		ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(os05b10->dev), 0, 0, 0);
  1207		if (!ep) {
  1208			dev_err(os05b10->dev, "Failed to get next endpoint\n");
  1209			return -EINVAL;
  1210		}
  1211	
  1212		ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
  1213		fwnode_handle_put(ep);
  1214		if (ret)
  1215			return ret;
  1216	
  1217		if (bus_cfg.bus.mipi_csi2.num_data_lanes != 4 &&
  1218		    bus_cfg.bus.mipi_csi2.num_data_lanes != 2) {
  1219			ret = dev_err_probe(os05b10->dev, -EINVAL,
  1220					    "4 and 2 data lanes are supported\n");
  1221			goto error_out;
  1222		}
  1223	
  1224		os05b10->data_lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
  1225	
  1226		if (os05b10->data_lanes == 2) {
  1227			ret = v4l2_link_freq_to_bitmap(os05b10->dev,
> 1228						       bus_cfg.link_frequencies_2lane,
> 1229						       bus_cfg.nr_of_link_frequencies_2lane,
  1230						       link_frequencies_2lane,
  1231						       ARRAY_SIZE(link_frequencies_2lane),
  1232						       &link_freq_bitmap);
  1233			if (ret) {
  1234				dev_err(os05b10->dev,
  1235					"For 2 lane 750MHz frequency is available\n");
  1236				goto error_out;
  1237			}
  1238		} else {
  1239			ret = v4l2_link_freq_to_bitmap(os05b10->dev,
> 1240						       bus_cfg.link_frequencies_4lane,
> 1241						       bus_cfg.nr_of_link_frequencies_4lane,
  1242						       link_frequencies_4lane,
  1243						       ARRAY_SIZE(link_frequencies_4lane),
  1244						       &link_freq_bitmap);
  1245			if (ret) {
  1246				dev_err(os05b10->dev,
  1247					"For 4 lane 600MHz frequency is available\n");
  1248				goto error_out;
  1249			}
  1250		}
  1251	
  1252		os05b10->link_freq_index = __ffs(link_freq_bitmap);
  1253	
  1254	error_out:
  1255		v4l2_fwnode_endpoint_free(&bus_cfg);
  1256	
  1257		return ret;
  1258	}
  1259	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki