From nobody Wed Aug 26 01:47:49 2026 Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) (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 ADCB63AD505 for ; Wed, 8 Jul 2026 14:49:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783522155; cv=none; b=KopJS/LUA3kWEf0KjAjiP04RepSZFPQfVwsquszePP1D4VkyNiqH620UqIURfRkYEhQlrz1COecntD2K2pZt02ZLqUIlUebSVwKg5+dx8RhQ+tiPdxMsNRkOt86RSE40Z3r6invAnNQdGcPye97mNGbh5bXdztXdlTTeXZ8ACk0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783522155; c=relaxed/simple; bh=FZflqWVIXRCruuWP6g2ExyXMwReUCGhn7A4b9MiKxTM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZXGwmsOC7HUPe6tUghdZosNAqM2K4TBh00dAAGZejAg8OqYyz3Opa5EvT4KJLW9LPOcFLgqJ2HBq4AoEFsDAWtk4UwTlv0ZunfjwAQtPz8xx7/0Whc7nRJgVobRpyPgTwgCGuU2h/EPwwGC5LBXsrzwOX5msVdBv59WFzXF5U/4= 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=czqY0tQL; arc=none smtp.client-ip=209.85.128.47 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="czqY0tQL" Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-493c19bad03so7509145e9.2 for ; Wed, 08 Jul 2026 07:49:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1783522150; x=1784126950; 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=NAB/TZ4h8IUmeg+tgDmUhADP6t4/HyOBMb86upV86GM=; b=czqY0tQLN+TVyk7+ipF0m2et96XejWjE1/rHWDa+sK/rUkuExppYwzLigE626HendF 3Nu9igwVeY6f5fz7z66kzLlYcHXmAHx14GgwQhpVhUf/srL87ukQH731UZKr1sEpnVfC OrWRq+ClfRJejK7njCX0N9wlC6cksotMpYdgMtdqCw3487mtLbpN2NoagmtS9lWYBqAr npNLLpSM90/cbFKKnAwG63SMFBnYmRqHhh9PzupGk0eZRfHfAUJS1Eq/ZdYSRqRN35oi 3KRWpZCXoAFudq6NH6d2kniivSADfdR0iKgcdv3kCyHAYf7Sxfp8qoc/PTHu6FSetrAs fBIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783522150; x=1784126950; 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=NAB/TZ4h8IUmeg+tgDmUhADP6t4/HyOBMb86upV86GM=; b=HXqhrMwh/KmcAyAeuAY9x9+n6qxu1wObNsNHkhTAQLGzGGSXVbLyYKgyFPQrqrM7Lo 3mAKPDHJ8MaHdJzD8AeOoM6OYDZqnFe6nJZ8T/V3qSKirM97Z4jDfVIfTfaFG40zxiFu uespjuaLoCil8XIZiDVyRQmn7W85vIPMWS8cTyLajCK+V0D4ZohEY3pSdbR9PAtvN8c9 c0BY5ch9dHpxHT13jNdxx/N1GVxE8u2iK6X3fSYSZLBK8m5VLZF67S6vDhxSyJ2ANiIq 2dlHPvrEciTZ8vX4Gz75QIEN29bXdI985lst/WK9mOgg2ejIw29lXb5JywRhGI+SREhN 221g== X-Forwarded-Encrypted: i=1; AHgh+Rp3OQ5T/diGxDMzV6pqXXHbktq+4xXz1WqOk6dfuui4B9gOSwdfUbKI8/J/nBanxEve+EsHR1vv04ks+rI=@vger.kernel.org X-Gm-Message-State: AOJu0YwSlHqG5XnWSryobPhCbsZRuUNtpiaDSlaYfH5N9XmkaN8uMEwd TcluNTvTfqD5LaongY9jAA+ikVE4qc/dbci+GHi3kn7yiE/Uowcj852t17XYsvSQaBi9+4GW2u2 nyary X-Gm-Gg: AfdE7clBzNgY1kdzcfCc4zABZ97XIoAa44L3LQA6hBvMyExWsx6vLRUpM7Rlntt0eih 5yQRsEzsyAJo5YumakUDTE5AppjDwhVLEa+e1I2WfJSdOhLrLdTdoyqWUbsKOwL7ev8JKX4xSRT qSHab8cbz9oA2acPVdiC2eSRyiMMS9w7PtXDFXVCyaRGVZZ+Nrqf6j8PgIxe9LbYJSrb5URmEra ZK795IAo8ihR5gI/8qD0zqmkSiNSLfkiT0mnbNij6DOksuzTvihFt2k/CVoTqRVxiIWSttaZ0++ O6QjO79wa+zH7xCQQmPg2EGcxfeZ2XhQItoPmTgjtLZoCT0POG2r26L8oYqYvjrOKZTI3hfHMtA wfDiTWphWUcDlzuVvnFntcFhyNQk5f4gIPeBhOat32kvwEGLnLRZMcUcWJk0tUapQU55kMX7hoO +DBdBiCG11PFF9PLdplr9FWtSwQz/gOJMn9Oo14ck8/ZyIIMQdMkg9Sw4LDc36R7qH X-Received: by 2002:a05:600c:354e:b0:493:b87c:c87d with SMTP id 5b1f17b1804b1-493e683ab6bmr31834115e9.11.1783522150060; Wed, 08 Jul 2026 07:49:10 -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.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Jul 2026 07:49:09 -0700 (PDT) From: Dave Stevenson Date: Wed, 08 Jul 2026 15:48:37 +0100 Subject: [PATCH v3 01/20] media: i2c: imx355: Add support for 24 MHz external clock 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-1-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 From: David Heidelberg The IMX355 sensor supports multiple external clock frequencies, including 19.2 MHz and 24 MHz. The driver currently supports only fixed 19.2 MHz input clock. Refactor the clock handling to make the PLL configuration dependent on the external clock frequency and add support for 24 MHz. Introduce a table of clock parameter sets and program the corresponding EXTCLK frequency and PLL multipliers to maintain consistent internal VCO frequencies across supported inputs. The PLL settings are adjusted so that OP VCO remains at 720 MHz This preserves existing timing characteristics while allowing systems using a 24 MHz clock to operate correctly. No functional change for existing 19.2 MHz users. Assisted-by: Claude:claude-opus-4-6 Signed-off-by: David Heidelberg Signed-off-by: Dave Stevenson --- drivers/media/i2c/imx355.c | 77 +++++++++++++++++++++++++++---------------= ---- 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c index 27a5c212a527..ad9a9464175b 100644 --- a/drivers/media/i2c/imx355.c +++ b/drivers/media/i2c/imx355.c @@ -25,6 +25,10 @@ #define IMX355_REG_CHIP_ID 0x0016 #define IMX355_CHIP_ID 0x0355 =20 +/* PLL registers that depend on the external clock frequency */ +#define IMX355_REG_EXTCLK_FREQ 0x0136 +#define IMX355_REG_PLL_OP_MUL 0x030e + /* V_TIMING internal */ #define IMX355_REG_FLL 0x0340 #define IMX355_FLL_MAX 0xffff @@ -63,7 +67,6 @@ =20 /* default link frequency and external clock */ #define IMX355_LINK_FREQ_DEFAULT 360000000LL -#define IMX355_EXT_CLK 19200000 #define IMX355_LINK_FREQ_INDEX 0 =20 /* number of data lanes */ @@ -100,6 +103,29 @@ struct imx355_mode { struct imx355_reg_list reg_list; }; =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 */ +}; + +/* + * 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. + */ +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 */ + }, + { + .ext_clk =3D 24000000, + .extclk_freq =3D 0x1800, /* 24.0 MHz */ + .pll_op_mpy =3D 60, /* 24.0 / 2 * 60 =3D 720 MHz */ + }, +}; + struct imx355_hwcfg { unsigned long link_freq_bitmap; }; @@ -125,6 +151,7 @@ struct imx355 { const struct imx355_mode *cur_mode; =20 struct imx355_hwcfg *hwcfg; + const struct imx355_clk_params *clk_params; =20 /* * Mutex for serialized access: @@ -144,8 +171,6 @@ static const struct regulator_bulk_data imx355_supplies= [] =3D { }; =20 static const struct imx355_reg imx355_global_regs[] =3D { - { 0x0136, 0x13 }, - { 0x0137, 0x33 }, { 0x304e, 0x03 }, { 0x4348, 0x16 }, { 0x4350, 0x19 }, @@ -235,8 +260,6 @@ static const struct imx355_reg mode_3268x2448_regs[] = =3D { { 0x0307, 0x78 }, { 0x030b, 0x01 }, { 0x030d, 0x02 }, - { 0x030e, 0x00 }, - { 0x030f, 0x4b }, { 0x0310, 0x00 }, { 0x0700, 0x00 }, { 0x0701, 0x10 }, @@ -284,8 +307,6 @@ static const struct imx355_reg mode_3264x2448_regs[] = =3D { { 0x0307, 0x78 }, { 0x030b, 0x01 }, { 0x030d, 0x02 }, - { 0x030e, 0x00 }, - { 0x030f, 0x4b }, { 0x0310, 0x00 }, { 0x0700, 0x00 }, { 0x0701, 0x10 }, @@ -333,8 +354,6 @@ static const struct imx355_reg mode_3280x2464_regs[] = =3D { { 0x0307, 0x78 }, { 0x030b, 0x01 }, { 0x030d, 0x02 }, - { 0x030e, 0x00 }, - { 0x030f, 0x4b }, { 0x0310, 0x00 }, { 0x0700, 0x00 }, { 0x0701, 0x10 }, @@ -382,8 +401,6 @@ static const struct imx355_reg mode_1940x1096_regs[] = =3D { { 0x0307, 0x78 }, { 0x030b, 0x01 }, { 0x030d, 0x02 }, - { 0x030e, 0x00 }, - { 0x030f, 0x4b }, { 0x0310, 0x00 }, { 0x0700, 0x00 }, { 0x0701, 0x10 }, @@ -431,8 +448,6 @@ static const struct imx355_reg mode_1936x1096_regs[] = =3D { { 0x0307, 0x78 }, { 0x030b, 0x01 }, { 0x030d, 0x02 }, - { 0x030e, 0x00 }, - { 0x030f, 0x4b }, { 0x0310, 0x00 }, { 0x0700, 0x00 }, { 0x0701, 0x10 }, @@ -480,8 +495,6 @@ static const struct imx355_reg mode_1924x1080_regs[] = =3D { { 0x0307, 0x78 }, { 0x030b, 0x01 }, { 0x030d, 0x02 }, - { 0x030e, 0x00 }, - { 0x030f, 0x4b }, { 0x0310, 0x00 }, { 0x0700, 0x00 }, { 0x0701, 0x10 }, @@ -529,8 +542,6 @@ static const struct imx355_reg mode_1920x1080_regs[] = =3D { { 0x0307, 0x78 }, { 0x030b, 0x01 }, { 0x030d, 0x02 }, - { 0x030e, 0x00 }, - { 0x030f, 0x4b }, { 0x0310, 0x00 }, { 0x0700, 0x00 }, { 0x0701, 0x10 }, @@ -578,8 +589,6 @@ static const struct imx355_reg mode_1640x1232_regs[] = =3D { { 0x0307, 0x78 }, { 0x030b, 0x01 }, { 0x030d, 0x02 }, - { 0x030e, 0x00 }, - { 0x030f, 0x4b }, { 0x0310, 0x00 }, { 0x0700, 0x00 }, { 0x0701, 0x10 }, @@ -627,8 +636,6 @@ static const struct imx355_reg mode_1640x922_regs[] =3D= { { 0x0307, 0x78 }, { 0x030b, 0x01 }, { 0x030d, 0x02 }, - { 0x030e, 0x00 }, - { 0x030f, 0x4b }, { 0x0310, 0x00 }, { 0x0700, 0x00 }, { 0x0701, 0x10 }, @@ -676,8 +683,6 @@ static const struct imx355_reg mode_1300x736_regs[] =3D= { { 0x0307, 0x78 }, { 0x030b, 0x01 }, { 0x030d, 0x02 }, - { 0x030e, 0x00 }, - { 0x030f, 0x4b }, { 0x0310, 0x00 }, { 0x0700, 0x00 }, { 0x0701, 0x10 }, @@ -725,8 +730,6 @@ static const struct imx355_reg mode_1296x736_regs[] =3D= { { 0x0307, 0x78 }, { 0x030b, 0x01 }, { 0x030d, 0x02 }, - { 0x030e, 0x00 }, - { 0x030f, 0x4b }, { 0x0310, 0x00 }, { 0x0700, 0x00 }, { 0x0701, 0x10 }, @@ -774,8 +777,6 @@ static const struct imx355_reg mode_1284x720_regs[] =3D= { { 0x0307, 0x78 }, { 0x030b, 0x01 }, { 0x030d, 0x02 }, - { 0x030e, 0x00 }, - { 0x030f, 0x4b }, { 0x0310, 0x00 }, { 0x0700, 0x00 }, { 0x0701, 0x10 }, @@ -823,8 +824,6 @@ static const struct imx355_reg mode_1280x720_regs[] =3D= { { 0x0307, 0x78 }, { 0x030b, 0x01 }, { 0x030d, 0x02 }, - { 0x030e, 0x00 }, - { 0x030f, 0x4b }, { 0x0310, 0x00 }, { 0x0700, 0x00 }, { 0x0701, 0x10 }, @@ -872,8 +871,6 @@ static const struct imx355_reg mode_820x616_regs[] =3D { { 0x0307, 0x78 }, { 0x030b, 0x01 }, { 0x030d, 0x02 }, - { 0x030e, 0x00 }, - { 0x030f, 0x4b }, { 0x0310, 0x00 }, { 0x0700, 0x02 }, { 0x0701, 0x78 }, @@ -1422,6 +1419,16 @@ static int imx355_start_streaming(struct imx355 *imx= 355) return ret; } =20 + /* Set PLL registers for the external clock frequency */ + ret =3D imx355_write_reg(imx355, IMX355_REG_EXTCLK_FREQ, 2, + imx355->clk_params->extclk_freq); + if (ret) + return ret; + ret =3D imx355_write_reg(imx355, IMX355_REG_PLL_OP_MUL, 2, + imx355->clk_params->pll_op_mpy); + if (ret) + return ret; + /* set digital gain control to all color mode */ ret =3D imx355_write_reg(imx355, IMX355_REG_DPGA_USE_GLOBAL_GAIN, 1, 1); if (ret) @@ -1749,7 +1756,13 @@ static int imx355_probe(struct i2c_client *client) "failed to get clock\n"); =20 freq =3D clk_get_rate(imx355->clk); - if (freq !=3D IMX355_EXT_CLK) + for (unsigned int i =3D 0; i < ARRAY_SIZE(imx355_clk_params); i++) { + if (freq =3D=3D imx355_clk_params[i].ext_clk) { + imx355->clk_params =3D &imx355_clk_params[i]; + break; + } + } + if (!imx355->clk_params) return dev_err_probe(imx355->dev, -EINVAL, "external clock %lu is not supported\n", freq); --=20 2.34.1