From nobody Tue Aug 25 03:43:33 2026 Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9551044CAEA for ; Wed, 8 Jul 2026 14:49:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783522177; cv=none; b=B2gtzc6KBmZ9F8f/45Qtrmqz0zeESStxnSRznLSYEqZGxd8QkxKLHPu9o2MoGTgKQQaaLE9g/niOtrwDaYUIsPj2X1El9324F3WsYTfiQd7yvRym/DnvI10R2PTPZLXTPM/AMD7T0asyuWhkKd4fb3n+0JNR2HdS/imMu+hwlfw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783522177; c=relaxed/simple; bh=EC2k5Q0O6GiAWVyB1n2jyIk0jzm5yjtUjDUXeFdZxaI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VMX0vllGoi75maM0ptlxxBOFqqgPkQ7YzFzD1Rz+Mg012QwmTsBBZEVsonBFWwf0kXa1U9F/ph2Hcsd5HS5lV+apo7hzUE43IUI1CBg2hfK1VDdb8gx7YqX12IIfML1C9c8c8L2C/u079hm2Yk0yiT+sSGZF3bwX8lcexcFDvQ8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=raspberrypi.com; spf=pass smtp.mailfrom=raspberrypi.com; dkim=pass (2048-bit key) header.d=raspberrypi.com header.i=@raspberrypi.com header.b=HCTXw/hv; arc=none smtp.client-ip=209.85.128.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=raspberrypi.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=raspberrypi.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="HCTXw/hv" Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-493d1e8aa46so6033635e9.0 for ; Wed, 08 Jul 2026 07:49:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1783522163; x=1784126963; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=B9fBhGmPu1qXjzzF9oDlHeeaawJIqqZK7Ydx3tiH29k=; b=HCTXw/hvzseypO2Ydyem0fWhnDrNTa+yB351tN4nMG5EJw7moe9lpq2iod4Iy4XOQh wq+lrcIXXh1Of8Lbb3aBYT0lA7dJzLNF2BPlCv0DZ37Aqtg2OXbI9EXZjIvjDuv0LZlB C/kHourHdM3WGzf4O7+VqKm8nNZACij+2Lnn0XYfsGfcICzZh47hs0bWsqSZWXpb0uZf A/upbLihrAdsrrgt+HAhBgViIMw17eIjaa2apgUOFDljd87gKO6O4I6TiR/OWwHcAQlg vAAjnXzbJtTdpBkiSxzRgLtWhigozEfaI59mg4j11XQdlKd0a4lBx+D5ikSm1Bv2+qfx idtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783522163; x=1784126963; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=B9fBhGmPu1qXjzzF9oDlHeeaawJIqqZK7Ydx3tiH29k=; b=iXIU7ClW8t4DXm65yFOlCcyEnZ8vlCHtOagaCn5ftx1MYCJlviaCuOTfzrJ945f1xl fNo4hKo0xUkD7AN629SU8ptTgehAIex1CZYQ2lodYYODKqP5N8sxzqJFMSGDNtKR1Ynv Rk/ira5M701ZQ7ZLQDXktMD9X/PCVltSaNaitZUeXutR3/U67ZerZAap2JZPv00cBl8i iFsr5dnVm2DqzmQVWWwUEuZtxoy41q9ihAjuofxOS8usTkdOeCFUWUQGsmhSt86f+4My w2YZN1vcbz9zriJOAsr33OfX41Xow8YeecvBaEZYtQq3a/Y2OApkNG/WTSP47dlyzVh0 qLFQ== X-Forwarded-Encrypted: i=1; AHgh+RpzX/G7Ad5JEy96vly/3AhWN2OgaEAynmNRFNtkAtkEspNU1w8GEQ+r67VnEYfe93NvLtyKj4KtkA+PP+s=@vger.kernel.org X-Gm-Message-State: AOJu0YxNUGyLM0k84OA+L/D7OhoB7+1TNKM//2fZlJgVO+R+nu91xjvT lm6cWRK6LX86KfK7PIqazv7f3ho6/PUctwMavn/3WgHtKJe+SQYhtaiMKvzCdL4lyiU= X-Gm-Gg: AfdE7clEgFrXDHGK6g9nrcKWjdVBBXFerh7ib3V8ZNauy/j4ys7h33knrg0dgdsASrj MncnGUdtxCNABC+yZWSO281YfxpyB4NsTk7yQAD7YZHSU9vH3+YGUnOu5fnX5Zm2n9ETlSTunFw 7VQLc+yAek9RYxBlX4OGbrM2odWsi6r4m35Dxlg9iaA7wyBEKiaeMuNXCvQp3LGpq37mMgbVDP2 vwFdfF0Hr/ADqsMk1ULVTpY63THBNAqmQaMBWztT2UPpK0bTrBW6TVvxvk9G8GaBiOaYRQJGGT9 8OBkS4xaY7CxhdQg3GeNkVT6ivoearDPKcgWXOEHaNJminLxH1Z2dOK7Ck2l/0tLaiq4y2doZp8 PWpXN6iNKKAI9j0sdtafCP75RJdFHGRwZX6kVel+fOn4L9OyuMMMwg2EzWlBY2e/w7bvJTJaHrw xyVcqOJWnO564c1Ble/U/OSvOJgNTaDgg2Rtr3zUp9AwEYH0pw8s/W8Lq8CbI/TQrnPgRdPThuz vs= X-Received: by 2002:a05:600c:8a16:10b0:493:bef8:ba8 with SMTP id 5b1f17b1804b1-493e68fc32amr24755525e9.39.1783522163580; Wed, 08 Jul 2026 07:49:23 -0700 (PDT) Received: from [127.0.1.1] ([2a00:1098:3142:e::8]) by smtp.googlemail.com with ESMTPSA id 5b1f17b1804b1-493e0fbd355sm135363315e9.13.2026.07.08.07.49.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Jul 2026 07:49:23 -0700 (PDT) From: Dave Stevenson Date: Wed, 08 Jul 2026 15:48:54 +0100 Subject: [PATCH v3 18/20] media: imx355: Support 2 lane readout Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260708-media-imx355-v3-18-9df386a623d7@raspberrypi.com> References: <20260708-media-imx355-v3-0-9df386a623d7@raspberrypi.com> In-Reply-To: <20260708-media-imx355-v3-0-9df386a623d7@raspberrypi.com> To: Sakari Ailus , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Richard Acayan Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, David Heidelberg , Jacopo Mondi , devicetree@vger.kernel.org, Dave Stevenson X-Mailer: b4 0.14.1 The sensor supports 2 or 4 lane readout, but the driver only allowed for 4 lanes. Add 2 lane support. The clock tree only supports single PLL mode to feed both IOP (MIPI) and IVT (Pixel array). 2 lane mode supports a MIPI link frequency of up to 445MHz (890Mbit/s) cf 360MHz (720Mbit/s) for 4lane. Update clock setup and pixel rates to match. Signed-off-by: Dave Stevenson --- drivers/media/i2c/imx355.c | 67 +++++++++++++++++++++++++++++++++---------= ---- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c index e45d60d665a1..2be665b5b453 100644 --- a/drivers/media/i2c/imx355.c +++ b/drivers/media/i2c/imx355.c @@ -27,11 +27,14 @@ #define IMX355_REG_CHIP_ID CCI_REG16(0x0016) #define IMX355_CHIP_ID 0x0355 =20 +#define IMX355_REG_LANE_SEL CCI_REG8(0x0114) + /* PLL registers that depend on the external clock frequency */ #define IMX355_REG_EXTCLK_FREQ CCI_REG16(0x0136) #define IMX355_REG_PLL_OP_PREDIV CCI_REG8(0x030d) #define IMX355_REG_PLL_OP_MUL CCI_REG16(0x030e) #define IMX355_REG_PLL_IVT_PCK_DIV CCI_REG8(0x0301) +#define IMX355_REG_PLL_IVT_SYSCK_DIV CCI_REG8(0x0303) #define IMX355_PLL_OP_PREDIV 2 #define IMX355_PLL_IVT_PCK_DIV 5 =20 @@ -80,6 +83,8 @@ #define IMX355_TEST_PATTERN_GRAY_COLOR_BARS 3 #define IMX355_TEST_PATTERN_PN9 4 =20 +#define IMX355_REG_REQ_LINK_BIT_RATE CCI_REG16(0x0820) + #define IMX355_REG_BINNING_MODE CCI_REG8(0x0900) #define IMX355_REG_BINNING_TYPE CCI_REG8(0x0901) #define IMX355_REG_BINNING_WEIGHTING CCI_REG8(0x0902) @@ -87,9 +92,6 @@ /* Flip Control */ #define IMX355_REG_ORIENTATION CCI_REG8(0x0101) =20 -/* number of data lanes */ -#define IMX355_DATA_LANES 4 - #define IMX355_PIXEL_ARRAY_TOP 0 #define IMX355_PIXEL_ARRAY_LEFT 0 #define IMX355_PIXEL_ARRAY_WIDTH 3280 @@ -120,30 +122,38 @@ struct imx355_mode { =20 struct imx355_clk_params { u32 ext_clk; - u16 extclk_freq; /* External clock (MHz) in 8.8 fixed point) */ - u16 pll_op_mpy; /* OP system PLL multiplier */ + u16 extclk_freq; /* External clock (MHz) in 8.8 fixed point) */ + u16 pll_op_mpy[2]; /* OP system PLL multiplier */ + u8 pll_op_prediv[2]; /* OP system pre PLL d */ }; =20 /* * The clock tree is in single PLL mode, so PREDIV_VT and MPY_IVT do nothi= ng. - * All modes use the same PLL setup for OP, with IOPCK being 720MHz. + * In 4 lane mode the MIPI rate is 360Mhz (720Mbit/s) and pixel rate is + * 288MPix/s. + * In 2 lane mode the MIPI rate is 444MHz (888Mbit/s) and pixel rate + * 177.6MPix/s with a 24MHz clock, and 441.6MHz (883.2Mbit/s) and 176.6MPi= x/s + * with a 19.2MHz clock. */ static const struct imx355_clk_params imx355_clk_params[] =3D { { .ext_clk =3D 19200000, - .extclk_freq =3D 0x1333, /* 19.2 MHz */ - .pll_op_mpy =3D 75, /* 19.2 / 2 * 75 =3D 720 MHz */ + .extclk_freq =3D 0x1333, + .pll_op_mpy =3D { 75, 92 }, + .pll_op_prediv =3D { 2, 2 } }, { .ext_clk =3D 24000000, - .extclk_freq =3D 0x1800, /* 24.0 MHz */ - .pll_op_mpy =3D 60, /* 24.0 / 2 * 60 =3D 720 MHz */ + .extclk_freq =3D 0x1800, + .pll_op_mpy =3D { 60, 111 }, + .pll_op_prediv =3D { 2, 3 } }, }; =20 struct imx355_hwcfg { s64 link_freq_menu; unsigned long link_freq_bitmap; + unsigned int num_lanes; }; =20 struct imx355 { @@ -239,7 +249,6 @@ static const struct cci_reg_sequence imx355_global_regs= [] =3D { { CCI_REG8(0x305a), 0x00 }, { CCI_REG8(0x0112), 0x0a }, { CCI_REG8(0x0113), 0x0a }, - { CCI_REG8(0x0114), 0x03 }, { IMX355_REG_PLL_IVT_PCK_DIV, IMX355_PLL_IVT_PCK_DIV }, { CCI_REG8(0x0303), 0x01 }, { CCI_REG8(0x0305), 0x02 }, @@ -250,8 +259,6 @@ static const struct cci_reg_sequence imx355_global_regs= [] =3D { { CCI_REG8(0x0310), 0x00 }, { CCI_REG8(0x0220), 0x00 }, { CCI_REG8(0x0222), 0x01 }, - { CCI_REG8(0x0820), 0x0b }, - { CCI_REG8(0x0821), 0x40 }, { CCI_REG8(0x3088), 0x04 }, { CCI_REG8(0x6813), 0x02 }, { CCI_REG8(0x6835), 0x07 }, @@ -816,6 +823,7 @@ imx355_set_pad_format(struct v4l2_subdev *sd, __v4l2_ctrl_modify_range(imx355->vblank, IMX355_VBLANK_MIN, height, 1, vblank_def); __v4l2_ctrl_s_ctrl(imx355->vblank, vblank_def); + h_blank =3D mode->llp - imx355->cur_mode->width; /* * Currently hblank is not changeable. @@ -879,6 +887,8 @@ static int imx355_start_streaming(struct imx355 *imx355) { const struct imx355_reg_list *reg_list; const struct imx355_mode *mode; + int lane_idx =3D imx355->hwcfg->num_lanes =3D=3D 4 ? 0 : 1; + u64 link_bitrate; u8 binning_mode; int ret =3D 0; =20 @@ -914,7 +924,21 @@ static int imx355_start_streaming(struct imx355 *imx35= 5) cci_write(imx355->regmap, IMX355_REG_EXTCLK_FREQ, imx355->clk_params->extclk_freq, &ret); cci_write(imx355->regmap, IMX355_REG_PLL_OP_MUL, - imx355->clk_params->pll_op_mpy, &ret); + imx355->clk_params->pll_op_mpy[lane_idx], &ret); + cci_write(imx355->regmap, IMX355_REG_PLL_OP_PREDIV, + imx355->clk_params->pll_op_prediv[lane_idx], &ret); + cci_write(imx355->regmap, IMX355_REG_PLL_IVT_SYSCK_DIV, + lane_idx ? 2 : 1, &ret); + + /* Set MIPI configuration */ + cci_write(imx355->regmap, IMX355_REG_LANE_SEL, + imx355->hwcfg->num_lanes - 1, &ret); + + link_bitrate =3D imx355->link_freq->qmenu_int[imx355->link_freq->val] * + imx355->hwcfg->num_lanes * 2; + do_div(link_bitrate, 1000000); + cci_write(imx355->regmap, IMX355_REG_REQ_LINK_BIT_RATE, link_bitrate, + &ret); =20 /* set digital gain control to all color mode */ cci_write(imx355->regmap, IMX355_REG_DPGA_USE_GLOBAL_GAIN, 1, &ret); @@ -1100,9 +1124,9 @@ static int imx355_init_controls(struct imx355 *imx355) imx355->link_freq->flags |=3D V4L2_CTRL_FLAG_READ_ONLY; =20 /* pixel_rate =3D link_freq * 2 * nr_of_lanes / bits_per_sample */ - pixel_rate =3D imx355->hwcfg->link_freq_menu * 2 * 4; + pixel_rate =3D imx355->hwcfg->link_freq_menu * 2 * imx355->hwcfg->num_lan= es; do_div(pixel_rate, 10); - /* By default, PIXEL_RATE is read only */ + v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_PIXEL_RATE, pixel_rate, pixel_rate, 1, pixel_rate); =20 @@ -1185,6 +1209,7 @@ static struct imx355_hwcfg *imx355_get_hwcfg(struct i= mx355 *imx355) const struct imx355_clk_params *clk =3D imx355->clk_params; struct fwnode_handle *ep; struct fwnode_handle *fwnode =3D dev_fwnode(dev); + int lane_idx; int ret; =20 if (!fwnode) @@ -1202,11 +1227,15 @@ static struct imx355_hwcfg *imx355_get_hwcfg(struct= imx355 *imx355) if (!cfg) goto out_err; =20 - if (bus_cfg.bus.mipi_csi2.num_data_lanes !=3D IMX355_DATA_LANES) + if (bus_cfg.bus.mipi_csi2.num_data_lanes !=3D 2 && + bus_cfg.bus.mipi_csi2.num_data_lanes !=3D 4) goto out_err; =20 - cfg->link_freq_menu =3D (clk->ext_clk * clk->pll_op_mpy) / - (IMX355_PLL_OP_PREDIV * 2); + cfg->num_lanes =3D bus_cfg.bus.mipi_csi2.num_data_lanes; + + lane_idx =3D cfg->num_lanes =3D=3D 4 ? 0 : 1; + cfg->link_freq_menu =3D (clk->ext_clk * clk->pll_op_mpy[lane_idx]) / + (clk->pll_op_prediv[lane_idx] * 2); ret =3D v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies, bus_cfg.nr_of_link_frequencies, &cfg->link_freq_menu, 1, --=20 2.34.1