mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/3] i2c: qcom-cci: Fix CCI clock rate enforcement
@ 2026-07-27  9:21 Loic Poulain
  2026-07-27  9:21 ` [PATCH v2 1/3] i2c: qcom-cci: Switch msm8953 to the CCI v2 timing/rate config Loic Poulain
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Loic Poulain @ 2026-07-27  9:21 UTC (permalink / raw)
  To: Robert Foss, Andi Shyti, Wolfram Sang, Dmitry Baryshkov, Luca Weiss
  Cc: linux-i2c, linux-arm-msm, linux-kernel, vladimir.zapolskiy,
	Loic Poulain, Wenmeng Liu, Konrad Dybcio

The CCI hw_params timing values (thigh, tlow, etc.) are expressed in
clock ticks and were calibrated for a specific CCI clock frequency per
hardware variant (19.2 MHz for v1/v1.5, 37.5 MHz for v2). Running at the
wrong frequency causes incorrect I2C timings that may violate the I2C
specification.

A previous series removed the cci_clk_rate field and the associated
warning from the driver on the grounds that the warning was noisy and
the rate was already set via assigned-clock-rates in the DT. However,
enforcing a clock frequency configuration through DT is fragile and not
the right approach, the driver owns the hw_params and should own the
clock rate too.

This series first fixes the msm8953 timing table, which is internally
inconsistent (Standard/Fast calibrated for 19.2 MHz but Fast+ for
37.5 MHz), by reusing the v2 config (same hardware version as
msm8996/sdm630). It then reverts the removal of cci_clk_rate and
replaces the passive warn-only approach with an active rate enforcement
at probe time. The rate is applied through the OPP framework so that
boards describing an opp table also get the required power-domain and
regulator votes.

Note: Vladimir suggested selecting the CCI clock rate per I2C mode
(Standard/Fast/Fast+) rather than a single per-variant rate. That would
be a much larger change as it requires a table describing all the rates
supported for a given clock, plus proper vote/arbitration management,
since a single CCI clock is shared by multiple masters that may run in
different modes simultaneously. So this is out of scope for this series,
which keeps the simpler per-variant rate.

Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
Changes in v2:
- Instead of adding a 19.2 MHz cci_clk_rate for msm8953, switch it to
  the v2 config (37.5 MHz). The msm8953 table was internally
  inconsistent (Standard/Fast for 19.2 MHz, Fast+ for 37.5 MHz), so a
  single rate could not satisfy all modes. msm8953 is the same HW
  version as msm8996/sdm630, which already use v2. (Vladimir)
- Remove the msm8953 fix tag (Vladimir)
- Apply the rate via the OPP framework instead of a bare clk_set_rate(),
  managing the vote across runtime PM. (Konrad)
- Link to v1: https://lore.kernel.org/r/20260721-cci-clk-fix-v1-0-5eae78700da8@oss.qualcomm.com

---
Loic Poulain (3):
      i2c: qcom-cci: Switch msm8953 to the CCI v2 timing/rate config
      Revert "i2c: qcom-cci: Remove unused struct member cci_clk_rate"
      i2c: qcom-cci: Fix CCI clock rate enforcement

 drivers/i2c/busses/i2c-qcom-cci.c | 100 ++++++++++++++++++++------------------
 1 file changed, 54 insertions(+), 46 deletions(-)
---
base-commit: fce2dfa773ced15f27dd27cd0b482a7473cdcf2a
change-id: 20260721-cci-clk-fix-fe145b2acfa7

Best regards,
-- 
Loic Poulain <loic.poulain@oss.qualcomm.com>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 1/3] i2c: qcom-cci: Switch msm8953 to the CCI v2 timing/rate config
  2026-07-27  9:21 [PATCH v2 0/3] i2c: qcom-cci: Fix CCI clock rate enforcement Loic Poulain
@ 2026-07-27  9:21 ` Loic Poulain
  2026-07-27 19:21   ` Vladimir Zapolskiy
  2026-07-27  9:21 ` [PATCH v2 2/3] Revert "i2c: qcom-cci: Remove unused struct member cci_clk_rate" Loic Poulain
  2026-07-27  9:21 ` [PATCH v2 3/3] i2c: qcom-cci: Fix CCI clock rate enforcement Loic Poulain
  2 siblings, 1 reply; 15+ messages in thread
From: Loic Poulain @ 2026-07-27  9:21 UTC (permalink / raw)
  To: Robert Foss, Andi Shyti, Wolfram Sang, Dmitry Baryshkov, Luca Weiss
  Cc: linux-i2c, linux-arm-msm, linux-kernel, vladimir.zapolskiy, Loic Poulain

The msm8953 CCI timing table is internally inconsistent. Its Standard
and Fast timings match v1/v1.5, which are calibrated for a 19.2 MHz CCI
clock, but its Fast+ timings are essentially the v2 values, which are
calibrated for 37.5 MHz. Since all masters share a single CCI clock,
no single rate can satisfy all three modes with the current table, and
the DT assigns 19.2 MHz, so Fast+ timings are wrong.

The msm8953 CCI is the same hardware version as msm8996/sdm630, which
already use the cci_v2_data config (37.5 MHz). 37.5 MHz is supported by
the msm8953 CCI RCG, so reuse cci_v2_data for msm8953 as well and drop
the redundant, inconsistent standalone table. This makes all three I2C
modes self-consistent under a single clock rate.

Note this requires the CCI clock to run at 37.5 MHz, the proper clock
rate will be set in an upcoming CCI patch.

Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
 drivers/i2c/busses/i2c-qcom-cci.c | 47 +--------------------------------------
 1 file changed, 1 insertion(+), 46 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c
index 4d64895a9e9e4e0bd5e0ccb5c3cc04b282b1e4d5..23cef922351ce44d71f1691cd7e4aab274fdd196 100644
--- a/drivers/i2c/busses/i2c-qcom-cci.c
+++ b/drivers/i2c/busses/i2c-qcom-cci.c
@@ -772,54 +772,9 @@ static const struct cci_data cci_v2_data = {
 	},
 };
 
-static const struct cci_data cci_msm8953_data = {
-	.num_masters = 2,
-	.queue_size = { 64, 16 },
-	.quirks = {
-		.max_write_len = 11,
-		.max_read_len = 12,
-	},
-	.params[I2C_MODE_STANDARD] = {
-		.thigh = 78,
-		.tlow = 114,
-		.tsu_sto = 28,
-		.tsu_sta = 28,
-		.thd_dat = 10,
-		.thd_sta = 77,
-		.tbuf = 118,
-		.scl_stretch_en = 0,
-		.trdhld = 6,
-		.tsp = 1
-	},
-	.params[I2C_MODE_FAST] = {
-		.thigh = 20,
-		.tlow = 28,
-		.tsu_sto = 21,
-		.tsu_sta = 21,
-		.thd_dat = 13,
-		.thd_sta = 18,
-		.tbuf = 32,
-		.scl_stretch_en = 0,
-		.trdhld = 6,
-		.tsp = 3
-	},
-	.params[I2C_MODE_FAST_PLUS] = {
-		.thigh = 16,
-		.tlow = 22,
-		.tsu_sto = 17,
-		.tsu_sta = 18,
-		.thd_dat = 16,
-		.thd_sta = 15,
-		.tbuf = 19,
-		.scl_stretch_en = 1,
-		.trdhld = 3,
-		.tsp = 3
-	},
-};
-
 static const struct of_device_id cci_dt_match[] = {
 	{ .compatible = "qcom,msm8226-cci", .data = &cci_v1_data},
-	{ .compatible = "qcom,msm8953-cci", .data = &cci_msm8953_data},
+	{ .compatible = "qcom,msm8953-cci", .data = &cci_v2_data},
 	{ .compatible = "qcom,msm8974-cci", .data = &cci_v1_5_data},
 	{ .compatible = "qcom,msm8996-cci", .data = &cci_v2_data},
 

-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 2/3] Revert "i2c: qcom-cci: Remove unused struct member cci_clk_rate"
  2026-07-27  9:21 [PATCH v2 0/3] i2c: qcom-cci: Fix CCI clock rate enforcement Loic Poulain
  2026-07-27  9:21 ` [PATCH v2 1/3] i2c: qcom-cci: Switch msm8953 to the CCI v2 timing/rate config Loic Poulain
@ 2026-07-27  9:21 ` Loic Poulain
  2026-07-27  9:21 ` [PATCH v2 3/3] i2c: qcom-cci: Fix CCI clock rate enforcement Loic Poulain
  2 siblings, 0 replies; 15+ messages in thread
From: Loic Poulain @ 2026-07-27  9:21 UTC (permalink / raw)
  To: Robert Foss, Andi Shyti, Wolfram Sang, Dmitry Baryshkov, Luca Weiss
  Cc: linux-i2c, linux-arm-msm, linux-kernel, vladimir.zapolskiy, Loic Poulain

This reverts commit b641af684fc28a07bee9c808eb6c433f9d9bcec6.

The cci_clk_rate field is needed to enforce the correct CCI clock rate
at probe time. The hw_params timing values are in clock ticks and were
calibrated for a specific frequency per hardware variant, so running at
the wrong rate would violate I2C timing specifications.

Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
 drivers/i2c/busses/i2c-qcom-cci.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c
index 23cef922351ce44d71f1691cd7e4aab274fdd196..2ed58b2a2f31c62ee1c972a53b71f86787144b84 100644
--- a/drivers/i2c/busses/i2c-qcom-cci.c
+++ b/drivers/i2c/busses/i2c-qcom-cci.c
@@ -117,6 +117,7 @@ struct cci_data {
 	unsigned int num_masters;
 	struct i2c_adapter_quirks quirks;
 	u16 queue_size[NUM_QUEUES];
+	unsigned long cci_clk_rate;
 	struct hw_params params[3];
 };
 
@@ -668,6 +669,7 @@ static const struct cci_data cci_v1_data = {
 		.max_write_len = 10,
 		.max_read_len = 12,
 	},
+	.cci_clk_rate =  19200000,
 	.params[I2C_MODE_STANDARD] = {
 		.thigh = 78,
 		.tlow = 114,
@@ -701,6 +703,7 @@ static const struct cci_data cci_v1_5_data = {
 		.max_write_len = 10,
 		.max_read_len = 12,
 	},
+	.cci_clk_rate =  19200000,
 	.params[I2C_MODE_STANDARD] = {
 		.thigh = 78,
 		.tlow = 114,
@@ -734,6 +737,7 @@ static const struct cci_data cci_v2_data = {
 		.max_write_len = 11,
 		.max_read_len = 12,
 	},
+	.cci_clk_rate =  37500000,
 	.params[I2C_MODE_STANDARD] = {
 		.thigh = 201,
 		.tlow = 174,

-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 3/3] i2c: qcom-cci: Fix CCI clock rate enforcement
  2026-07-27  9:21 [PATCH v2 0/3] i2c: qcom-cci: Fix CCI clock rate enforcement Loic Poulain
  2026-07-27  9:21 ` [PATCH v2 1/3] i2c: qcom-cci: Switch msm8953 to the CCI v2 timing/rate config Loic Poulain
  2026-07-27  9:21 ` [PATCH v2 2/3] Revert "i2c: qcom-cci: Remove unused struct member cci_clk_rate" Loic Poulain
@ 2026-07-27  9:21 ` Loic Poulain
  2026-07-27  9:33   ` Mukesh Savaliya
  2026-07-28 15:57   ` Vladimir Zapolskiy
  2 siblings, 2 replies; 15+ messages in thread
From: Loic Poulain @ 2026-07-27  9:21 UTC (permalink / raw)
  To: Robert Foss, Andi Shyti, Wolfram Sang, Dmitry Baryshkov, Luca Weiss
  Cc: linux-i2c, linux-arm-msm, linux-kernel, vladimir.zapolskiy,
	Loic Poulain, Wenmeng Liu, Konrad Dybcio

The hw_params timing values (thigh, tlow, etc.) are in CCI clock ticks
and were calibrated for a specific clock rate per hardware variant. If
the clock is running at a different rate the I2C timings will be wrong,
potentially violating the I2C specification.

Rather than just warning about a mismatch like before, actively set
the clock to the expected rate, using the OPP framework so that boards
which (will) describe an opp table also get the required power-domain and
regulator votes for that rate. The OPP table is optional, boards without
one simply fall back to a plain clk_set_rate() behavior, so existing DTs
keep working.

Tested-by: Wenmeng Liu <wenmeng.liu@oss.qualcomm.com>
Suggested-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
 drivers/i2c/busses/i2c-qcom-cci.c | 49 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c
index 2ed58b2a2f31c62ee1c972a53b71f86787144b84..87d64e308a8152b99ff4cfb4255e24edfb751e75 100644
--- a/drivers/i2c/busses/i2c-qcom-cci.c
+++ b/drivers/i2c/busses/i2c-qcom-cci.c
@@ -11,6 +11,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/pm_opp.h>
 
 #define CCI_HW_VERSION				0x0
 #define CCI_RESET_CMD				0x004
@@ -128,6 +129,7 @@ struct cci {
 	const struct cci_data *data;
 	struct clk_bulk_data *clocks;
 	int nclocks;
+	struct clk *cci_clk;
 	struct cci_master master[NUM_MASTERS];
 };
 
@@ -472,10 +474,35 @@ static void cci_disable_clocks(struct cci *cci)
 	clk_bulk_disable_unprepare(cci->nclocks, cci->clocks);
 }
 
+static int cci_set_core_rate(struct cci *cci, unsigned long rate)
+{
+	struct device *dev = cci->dev;
+	int ret;
+
+	ret = dev_pm_opp_set_rate(dev, rate);
+	if (ret) {
+		dev_warn(dev, "CCI clock could not be set to %lu Hz\n", rate);
+		return ret;
+	}
+
+	if (!rate)
+		return 0;
+
+	/*
+	 * The hw_params timings are only valid at the expected rate,
+	 * so verify what actually landed on the hardware.
+	 */
+	if (clk_get_rate(cci->cci_clk) != rate)
+		dev_warn(dev, "CCI clock is not at expected %lu Hz\n", rate);
+
+	return 0;
+}
+
 static int __maybe_unused cci_suspend_runtime(struct device *dev)
 {
 	struct cci *cci = dev_get_drvdata(dev);
 
+	cci_set_core_rate(cci, 0);
 	cci_disable_clocks(cci);
 	return 0;
 }
@@ -485,6 +512,10 @@ static int __maybe_unused cci_resume_runtime(struct device *dev)
 	struct cci *cci = dev_get_drvdata(dev);
 	int ret;
 
+	ret = cci_set_core_rate(cci, cci->data->cci_clk_rate);
+	if (ret)
+		return ret;
+
 	ret = cci_enable_clocks(cci);
 	if (ret)
 		return ret;
@@ -587,6 +618,24 @@ static int cci_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, -EINVAL, "not enough clocks in DT\n");
 	cci->nclocks = ret;
 
+	cci->cci_clk = devm_clk_get(dev, "cci");
+	if (IS_ERR(cci->cci_clk))
+		return dev_err_probe(dev, PTR_ERR(cci->cci_clk),
+				     "failed to get CCI clock\n");
+
+	ret = devm_pm_opp_set_clkname(dev, "cci");
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to set CCI OPP clk\n");
+
+	/* OPP table is optional */
+	ret = devm_pm_opp_of_add_table(dev);
+	if (ret && ret != -ENODEV)
+		return dev_err_probe(dev, ret, "failed to add OPP table\n");
+
+	ret = cci_set_core_rate(cci, cci->data->cci_clk_rate);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to set CCI clock rate\n");
+
 	ret = cci_enable_clocks(cci);
 	if (ret < 0)
 		return ret;

-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 3/3] i2c: qcom-cci: Fix CCI clock rate enforcement
  2026-07-27  9:21 ` [PATCH v2 3/3] i2c: qcom-cci: Fix CCI clock rate enforcement Loic Poulain
@ 2026-07-27  9:33   ` Mukesh Savaliya
  2026-07-27  9:45     ` Loic Poulain
  2026-07-28 15:57   ` Vladimir Zapolskiy
  1 sibling, 1 reply; 15+ messages in thread
From: Mukesh Savaliya @ 2026-07-27  9:33 UTC (permalink / raw)
  To: Loic Poulain, Robert Foss, Andi Shyti, Wolfram Sang,
	Dmitry Baryshkov, Luca Weiss
  Cc: linux-i2c, linux-arm-msm, linux-kernel, vladimir.zapolskiy,
	Wenmeng Liu, Konrad Dybcio



On 7/27/2026 2:51 PM, Loic Poulain wrote:
[...]

> @@ -587,6 +618,24 @@ static int cci_probe(struct platform_device *pdev)
>   		return dev_err_probe(dev, -EINVAL, "not enough clocks in DT\n");
>   	cci->nclocks = ret;
>   
> +	cci->cci_clk = devm_clk_get(dev, "cci");
> +	if (IS_ERR(cci->cci_clk))
> +		return dev_err_probe(dev, PTR_ERR(cci->cci_clk),
> +				     "failed to get CCI clock\n");
> +
> +	ret = devm_pm_opp_set_clkname(dev, "cci");
> +	if (ret)
> +		return dev_err_probe(dev, ret, "failed to set CCI OPP clk\n");
> +
> +	/* OPP table is optional */
> +	ret = devm_pm_opp_of_add_table(dev);
> +	if (ret && ret != -ENODEV)
> +		return dev_err_probe(dev, ret, "failed to add OPP table\n");
> +

if this is an optional why to return with an error ? IMO, further 
operations should continue which are not opp dependent ?

> +	ret = cci_set_core_rate(cci, cci->data->cci_clk_rate);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "failed to set CCI clock rate\n");
> +
>   	ret = cci_enable_clocks(cci);
>   	if (ret < 0)
>   		return ret;
> 


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 3/3] i2c: qcom-cci: Fix CCI clock rate enforcement
  2026-07-27  9:33   ` Mukesh Savaliya
@ 2026-07-27  9:45     ` Loic Poulain
  2026-07-27  9:50       ` Mukesh Savaliya
  0 siblings, 1 reply; 15+ messages in thread
From: Loic Poulain @ 2026-07-27  9:45 UTC (permalink / raw)
  To: Mukesh Savaliya
  Cc: Robert Foss, Andi Shyti, Wolfram Sang, Dmitry Baryshkov,
	Luca Weiss, linux-i2c, linux-arm-msm, linux-kernel,
	vladimir.zapolskiy, Wenmeng Liu, Konrad Dybcio

Hi Mukesh,

On Mon, Jul 27, 2026 at 11:33 AM Mukesh Savaliya
<mukesh.savaliya@oss.qualcomm.com> wrote:
>
>
>
> On 7/27/2026 2:51 PM, Loic Poulain wrote:
> [...]
>
> > @@ -587,6 +618,24 @@ static int cci_probe(struct platform_device *pdev)
> >               return dev_err_probe(dev, -EINVAL, "not enough clocks in DT\n");
> >       cci->nclocks = ret;
> >
> > +     cci->cci_clk = devm_clk_get(dev, "cci");
> > +     if (IS_ERR(cci->cci_clk))
> > +             return dev_err_probe(dev, PTR_ERR(cci->cci_clk),
> > +                                  "failed to get CCI clock\n");
> > +
> > +     ret = devm_pm_opp_set_clkname(dev, "cci");
> > +     if (ret)
> > +             return dev_err_probe(dev, ret, "failed to set CCI OPP clk\n");
> > +
> > +     /* OPP table is optional */
> > +     ret = devm_pm_opp_of_add_table(dev);
> > +     if (ret && ret != -ENODEV)
> > +             return dev_err_probe(dev, ret, "failed to add OPP table\n");
> > +
>
> if this is an optional why to return with an error ? IMO, further
> operations should continue which are not opp dependent ?

The OPP table is optional only in the sense that it may be absent,
that's the -ENODEV case, which we deliberately don't treat as an
error. If a table is present but malformed, or can't be added yet
because a required resource isn't ready (-EPROBE_DEFER), we do want to
report/propagate the error rather than silently continue. This is the
established idiom (spi-qcom-qspi, qcom_geni_serial...).

Regards,
Loic


>
> > +     ret = cci_set_core_rate(cci, cci->data->cci_clk_rate);
> > +     if (ret)
> > +             return dev_err_probe(dev, ret, "failed to set CCI clock rate\n");
> > +
> >       ret = cci_enable_clocks(cci);
> >       if (ret < 0)
> >               return ret;
> >
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 3/3] i2c: qcom-cci: Fix CCI clock rate enforcement
  2026-07-27  9:45     ` Loic Poulain
@ 2026-07-27  9:50       ` Mukesh Savaliya
  0 siblings, 0 replies; 15+ messages in thread
From: Mukesh Savaliya @ 2026-07-27  9:50 UTC (permalink / raw)
  To: Loic Poulain
  Cc: Robert Foss, Andi Shyti, Wolfram Sang, Dmitry Baryshkov,
	Luca Weiss, linux-i2c, linux-arm-msm, linux-kernel,
	vladimir.zapolskiy, Wenmeng Liu, Konrad Dybcio

Thanks Loic !

On 7/27/2026 3:15 PM, Loic Poulain wrote:
> Hi Mukesh,
> 
> On Mon, Jul 27, 2026 at 11:33 AM Mukesh Savaliya
> <mukesh.savaliya@oss.qualcomm.com> wrote:
>>
>>
>>
>> On 7/27/2026 2:51 PM, Loic Poulain wrote:
>> [...]
>>
>>> @@ -587,6 +618,24 @@ static int cci_probe(struct platform_device *pdev)
>>>                return dev_err_probe(dev, -EINVAL, "not enough clocks in DT\n");
>>>        cci->nclocks = ret;
>>>
>>> +     cci->cci_clk = devm_clk_get(dev, "cci");
>>> +     if (IS_ERR(cci->cci_clk))
>>> +             return dev_err_probe(dev, PTR_ERR(cci->cci_clk),
>>> +                                  "failed to get CCI clock\n");
>>> +
>>> +     ret = devm_pm_opp_set_clkname(dev, "cci");
>>> +     if (ret)
>>> +             return dev_err_probe(dev, ret, "failed to set CCI OPP clk\n");
>>> +
>>> +     /* OPP table is optional */
>>> +     ret = devm_pm_opp_of_add_table(dev);
>>> +     if (ret && ret != -ENODEV)
>>> +             return dev_err_probe(dev, ret, "failed to add OPP table\n");
>>> +
>>
>> if this is an optional why to return with an error ? IMO, further
>> operations should continue which are not opp dependent ?
> 
> The OPP table is optional only in the sense that it may be absent,
> that's the -ENODEV case, which we deliberately don't treat as an
> error. If a table is present but malformed, or can't be added yet
> because a required resource isn't ready (-EPROBE_DEFER), we do want to
> report/propagate the error rather than silently continue. This is the
> established idiom (spi-qcom-qspi, qcom_geni_serial...).
> 
Sorry, understood now. hence protected with both the conditions. Makes 
sense.

> Regards,
> Loic
> 
> 
>>
>>> +     ret = cci_set_core_rate(cci, cci->data->cci_clk_rate);
>>> +     if (ret)
>>> +             return dev_err_probe(dev, ret, "failed to set CCI clock rate\n");
>>> +
>>>        ret = cci_enable_clocks(cci);
>>>        if (ret < 0)
>>>                return ret;
>>>
>>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 1/3] i2c: qcom-cci: Switch msm8953 to the CCI v2 timing/rate config
  2026-07-27  9:21 ` [PATCH v2 1/3] i2c: qcom-cci: Switch msm8953 to the CCI v2 timing/rate config Loic Poulain
@ 2026-07-27 19:21   ` Vladimir Zapolskiy
  2026-07-28  8:20     ` Loic Poulain
  0 siblings, 1 reply; 15+ messages in thread
From: Vladimir Zapolskiy @ 2026-07-27 19:21 UTC (permalink / raw)
  To: Loic Poulain, Robert Foss, Andi Shyti, Wolfram Sang,
	Dmitry Baryshkov, Luca Weiss
  Cc: linux-i2c, linux-arm-msm, linux-kernel

Hi Loic,

On 7/27/26 12:21, Loic Poulain wrote:
> The msm8953 CCI timing table is internally inconsistent. Its Standard

likely I was misunderstood in my v1 review comments, and I believe v3
will be needed...

If there is just one master, or two masters set in equal speed mode,
then there is no such issue as "msm8953 CCI timing table is internally
inconsistent". In other words generally it shall be permitted to have
supply clock frequency intermixed speed modes for any CCI variant.

I'll repeat the same point as given in v1, namely supply clock frequency
is not a property of CCI revision (therefore v1 1/3 or v2 2/3 is invalid),
it is a property of the mode settings. It's correct to remove 'cci_clk_rate'
from 'struct cci_data', and it will be correct to add (or parameterize in
any other way) 'cci_clk_rate' to 'struct hw_params'. Each instance of
'struct hw_params' is strictly bound to a particular CCI clock frequency.

> and Fast timings match v1/v1.5, which are calibrated for a 19.2 MHz CCI
> clock, but its Fast+ timings are essentially the v2 values, which are
> calibrated for 37.5 MHz. Since all masters share a single CCI clock,

But what if you have only one master?..

I think the msm8953 data is correct, it shall not be removed.

> no single rate can satisfy all three modes with the current table, and
> the DT assigns 19.2 MHz, so Fast+ timings are wrong.

They are not wrong, eh...

> 
> The msm8953 CCI is the same hardware version as msm8996/sdm630, which
> already use the cci_v2_data config (37.5 MHz). 37.5 MHz is supported by
> the msm8953 CCI RCG, so reuse cci_v2_data for msm8953 as well and drop
> the redundant, inconsistent standalone table. This makes all three I2C
> modes self-consistent under a single clock rate.
> 
> Note this requires the CCI clock to run at 37.5 MHz, the proper clock
> rate will be set in an upcoming CCI patch.
> 
> Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>

-- 
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 1/3] i2c: qcom-cci: Switch msm8953 to the CCI v2 timing/rate config
  2026-07-27 19:21   ` Vladimir Zapolskiy
@ 2026-07-28  8:20     ` Loic Poulain
  2026-07-28  9:38       ` Vladimir Zapolskiy
  0 siblings, 1 reply; 15+ messages in thread
From: Loic Poulain @ 2026-07-28  8:20 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Robert Foss, Andi Shyti, Wolfram Sang, Dmitry Baryshkov,
	Luca Weiss, linux-i2c, linux-arm-msm, linux-kernel

Hi Vladimir,

On Mon, Jul 27, 2026 at 9:21 PM Vladimir Zapolskiy
<vladimir.zapolskiy@linaro.org> wrote:
>
> Hi Loic,
>
> On 7/27/26 12:21, Loic Poulain wrote:
> > The msm8953 CCI timing table is internally inconsistent. Its Standard
>
> likely I was misunderstood in my v1 review comments, and I believe v3
> will be needed...
>
> If there is just one master, or two masters set in equal speed mode,
> then there is no such issue as "msm8953 CCI timing table is internally
> inconsistent". In other words generally it shall be permitted to have
> supply clock frequency intermixed speed modes for any CCI variant.

The two masters sharing the supply clock are independently
configurable in terms of mode, so we simply can't guarantee they will
run in same mode.

>
> I'll repeat the same point as given in v1, namely supply clock frequency
> is not a property of CCI revision (therefore v1 1/3 or v2 2/3 is invalid),
> it is a property of the mode settings. It's correct to remove 'cci_clk_rate'
> from 'struct cci_data', and it will be correct to add (or parameterize in
> any other way) 'cci_clk_rate' to 'struct hw_params'. Each instance of
> 'struct hw_params' is strictly bound to a particular CCI clock frequency.
>
> > and Fast timings match v1/v1.5, which are calibrated for a 19.2 MHz CCI
> > clock, but its Fast+ timings are essentially the v2 values, which are
> > calibrated for 37.5 MHz. Since all masters share a single CCI clock,

So, you're right that the supply clock frequency is a property of the
mode/timing settings (though I'm not entirely sure timings are fully
hardware rev agnostic). I don't dispute that.
However, this reflects the current driver behavior. It's not
incorrect, it is a simplified approach that uses a single frequency
point across all operating modes of a given platform.
I added a brief paragraph in the V2 cover letter to explain why it's
out of scope.

My argument is about scope. Today the driver has no mechanism to pick
a rate per mode, a single CCI clock is shared by N masters (usually
two) that can run in different modes simultaneously, so per-mode
scaling requires (1) per-mode rate info in the params table, and (2)
vote/arbitration logic to select the highest required rate and still
apply correct timings for every master at that rate. Concretely, with
one master in Standard and another in Fast+, you'd need a 37.5 MHz
shared clock and a Standard-mode row calibrated for 37.5 MHz, which
the msm8953 table simply does not provide today. So this isn't a small
tweak, it's a new capability backed by new table data. It would bring
more fine tuned supply rate, but without huge benefit, as cci clock is
gated most of the time due to runtime-pm.

> But what if you have only one master?..

It's not important here? we have N master (usually two) and have to
deal with that.

> I think the msm8953 data is correct, it shall not be removed.

The msm8953 table as it stands is internally inconsistent (without
per-mode rate info), no single clock makes all three modes correct.
Moreover, msm8953 is the same HW version as msm8996/sdm630, which
already use cci_v2_data, there's no strong reason for msm8953 to keep
a bespoke, half-and-half table.

> > no single rate can satisfy all three modes with the current table, and
> > the DT assigns 19.2 MHz, so Fast+ timings are wrong.

This series intentionally does the minimal correct thing, aligning the
timings with a single supply clock and enforcing that clock in the
driver, which owns hw_params and has all the info to produce correct
timing. It fixes reported devices misbehaving when no (or incorrect)
assigned-clock-rate is set.

Not saying what you propose is not do-able, and I clearly understand
what you mean, but I'd prefer to land this simple
alignment/enforcement first and treat per-mode clock scaling as a
follow-up, rather than coupling a straightforward fix to a larger
refactor. Please clearly Nack if you do not agree with this first
step.

Cheers,
Loic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 1/3] i2c: qcom-cci: Switch msm8953 to the CCI v2 timing/rate config
  2026-07-28  8:20     ` Loic Poulain
@ 2026-07-28  9:38       ` Vladimir Zapolskiy
  2026-07-28 10:26         ` Loic Poulain
  0 siblings, 1 reply; 15+ messages in thread
From: Vladimir Zapolskiy @ 2026-07-28  9:38 UTC (permalink / raw)
  To: Loic Poulain
  Cc: Robert Foss, Andi Shyti, Wolfram Sang, Dmitry Baryshkov,
	Luca Weiss, linux-i2c, linux-arm-msm, linux-kernel

Hi Loic,

On 7/28/26 11:20, Loic Poulain wrote:
> Hi Vladimir,
> 
> On Mon, Jul 27, 2026 at 9:21 PM Vladimir Zapolskiy
> <vladimir.zapolskiy@linaro.org> wrote:
>>
>> Hi Loic,
>>
>> On 7/27/26 12:21, Loic Poulain wrote:
>>> The msm8953 CCI timing table is internally inconsistent. Its Standard
>>
>> likely I was misunderstood in my v1 review comments, and I believe v3
>> will be needed...
>>
>> If there is just one master, or two masters set in equal speed mode,
>> then there is no such issue as "msm8953 CCI timing table is internally
>> inconsistent". In other words generally it shall be permitted to have
>> supply clock frequency intermixed speed modes for any CCI variant.
> 
> The two masters sharing the supply clock are independently
> configurable in terms of mode, so we simply can't guarantee they will
> run in same mode.

There should be no restriction or guarantee to configure the same mode
for two masters. The supply clock frequency is one for both masters,
but speed mode selection is based on its presense in the driver by
the CCI frequency.

If there is no match in the driver for CCI clock frequency/speed mode,
return -EOPNOTSUPP for such master.

Think of it, right now for each CCI hardware revision 3 'struct hw_params'
are provided by the driver, some of them match 19.2MHz frequency, some of
them match 37.5MHz frequency or intermixed for msm8953 case. Likely there
is no restriction to provide 6 'struct hw_params' for each CCI hardware
revision covering both 19.2MHz and 37.5MHz supply clock frequencies, then
any combination of speed modes can be configured on any CCI hardware for
two masters.

The main point is that CCI clock frequency is not specific to CCI hardware,
but it is specific to 'struct hw_params' mode.

>> I'll repeat the same point as given in v1, namely supply clock frequency
>> is not a property of CCI revision (therefore v1 1/3 or v2 2/3 is invalid),
>> it is a property of the mode settings. It's correct to remove 'cci_clk_rate'
>> from 'struct cci_data', and it will be correct to add (or parameterize in
>> any other way) 'cci_clk_rate' to 'struct hw_params'. Each instance of
>> 'struct hw_params' is strictly bound to a particular CCI clock frequency.
>>
>>> and Fast timings match v1/v1.5, which are calibrated for a 19.2 MHz CCI
>>> clock, but its Fast+ timings are essentially the v2 values, which are
>>> calibrated for 37.5 MHz. Since all masters share a single CCI clock,
> 
> So, you're right that the supply clock frequency is a property of the
> mode/timing settings (though I'm not entirely sure timings are fully
> hardware rev agnostic). I don't dispute that.
> However, this reflects the current driver behavior. It's not
> incorrect, it is a simplified approach that uses a single frequency
> point across all operating modes of a given platform.

The driver should be fixed/improved. Reverting the link between CCI
clock frequency and CCI hardware revision is invalid, it should not
be done.

> I added a brief paragraph in the V2 cover letter to explain why it's
> out of scope.
> 
> My argument is about scope. Today the driver has no mechanism to pick
> a rate per mode, a single CCI clock is shared by N masters (usually
> two) that can run in different modes simultaneously, so per-mode
> scaling requires (1) per-mode rate info in the params table, and (2)
> vote/arbitration logic to select the highest required rate and still
> apply correct timings for every master at that rate. Concretely, with
> one master in Standard and another in Fast+, you'd need a 37.5 MHz
> shared clock and a Standard-mode row calibrated for 37.5 MHz, which

This is a limitation of the driver only. For a selected CCI revision
please add 'struct hw_params' for Standard mode / 37.5MHz supply clock
frequency, and the problem is solved.

> the msm8953 table simply does not provide today. So this isn't a small
> tweak, it's a new capability backed by new table data. It would bring
> more fine tuned supply rate, but without huge benefit, as cci clock is
> gated most of the time due to runtime-pm.
> 
>> But what if you have only one master?..
> 
> It's not important here? we have N master (usually two) and have to
> deal with that.

It is important in sense that any one master usecases are properly
supported.

>> I think the msm8953 data is correct, it shall not be removed.
> 
> The msm8953 table as it stands is internally inconsistent (without
> per-mode rate info), no single clock makes all three modes correct.

It is so, because there is msm8953 data is incomplete. But the present
msm8953 data is correct.

> Moreover, msm8953 is the same HW version as msm8996/sdm630, which
> already use cci_v2_data, there's no strong reason for msm8953 to keep
> a bespoke, half-and-half table.
> 

Okay, I read it as 'struct hw_params' data for msm8953 can be removed
and v2 data should be used for this CCI hardvare variant.

>>> no single rate can satisfy all three modes with the current table, and
>>> the DT assigns 19.2 MHz, so Fast+ timings are wrong.

If hypotetically 'struct hw_params' Fast+ timing for 19.2MHz supply
clock is added to the driver, this usecase will supported by the driver.
As for today the driver has a bug, no doubt.

> This series intentionally does the minimal correct thing, aligning the
> timings with a single supply clock and enforcing that clock in the
> driver, which owns hw_params and has all the info to produce correct
> timing. It fixes reported devices misbehaving when no (or incorrect)
> assigned-clock-rate is set.

Since we're discussing it, this fix is not the only one possible,
and the fix which returns the link between CCI hardware revision and
CCI supply clock frequency is an invalid fix.

> Not saying what you propose is not do-able, and I clearly understand
> what you mean, but I'd prefer to land this simple
> alignment/enforcement first and treat per-mode clock scaling as a
> follow-up, rather than coupling a straightforward fix to a larger
> refactor. Please clearly Nack if you do not agree with this first
> step.
  
Instead of a non-productive NAK I can provide a simple change adding
a proper link between speed mode and registers programming.

-- 
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 1/3] i2c: qcom-cci: Switch msm8953 to the CCI v2 timing/rate config
  2026-07-28  9:38       ` Vladimir Zapolskiy
@ 2026-07-28 10:26         ` Loic Poulain
  2026-07-29 11:40           ` Vladimir Zapolskiy
  0 siblings, 1 reply; 15+ messages in thread
From: Loic Poulain @ 2026-07-28 10:26 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Robert Foss, Andi Shyti, Wolfram Sang, Dmitry Baryshkov,
	Luca Weiss, linux-i2c, linux-arm-msm, linux-kernel

On Tue, Jul 28, 2026 at 11:38 AM Vladimir Zapolskiy
<vladimir.zapolskiy@linaro.org> wrote:
>
> Hi Loic,
>
> On 7/28/26 11:20, Loic Poulain wrote:
> > Hi Vladimir,
> >
> > On Mon, Jul 27, 2026 at 9:21 PM Vladimir Zapolskiy
> > <vladimir.zapolskiy@linaro.org> wrote:
> >>
> >> Hi Loic,
> >>
> >> On 7/27/26 12:21, Loic Poulain wrote:
> >>> The msm8953 CCI timing table is internally inconsistent. Its Standard
> >>
> >> likely I was misunderstood in my v1 review comments, and I believe v3
> >> will be needed...
> >>
> >> If there is just one master, or two masters set in equal speed mode,
> >> then there is no such issue as "msm8953 CCI timing table is internally
> >> inconsistent". In other words generally it shall be permitted to have
> >> supply clock frequency intermixed speed modes for any CCI variant.
> >
> > The two masters sharing the supply clock are independently
> > configurable in terms of mode, so we simply can't guarantee they will
> > run in same mode.
>
> There should be no restriction or guarantee to configure the same mode
> for two masters. The supply clock frequency is one for both masters,
> but speed mode selection is based on its presense in the driver by
> the CCI frequency.
>
> If there is no match in the driver for CCI clock frequency/speed mode,
> return -EOPNOTSUPP for such master.
>
> Think of it, right now for each CCI hardware revision 3 'struct hw_params'
> are provided by the driver, some of them match 19.2MHz frequency, some of
> them match 37.5MHz frequency or intermixed for msm8953 case. Likely there
> is no restriction to provide 6 'struct hw_params' for each CCI hardware
> revision covering both 19.2MHz and 37.5MHz supply clock frequencies, then
> any combination of speed modes can be configured on any CCI hardware for
> two masters.
>
> The main point is that CCI clock frequency is not specific to CCI hardware,
> but it is specific to 'struct hw_params' mode.
>
> >> I'll repeat the same point as given in v1, namely supply clock frequency
> >> is not a property of CCI revision (therefore v1 1/3 or v2 2/3 is invalid),
> >> it is a property of the mode settings. It's correct to remove 'cci_clk_rate'
> >> from 'struct cci_data', and it will be correct to add (or parameterize in
> >> any other way) 'cci_clk_rate' to 'struct hw_params'. Each instance of
> >> 'struct hw_params' is strictly bound to a particular CCI clock frequency.
> >>
> >>> and Fast timings match v1/v1.5, which are calibrated for a 19.2 MHz CCI
> >>> clock, but its Fast+ timings are essentially the v2 values, which are
> >>> calibrated for 37.5 MHz. Since all masters share a single CCI clock,
> >
> > So, you're right that the supply clock frequency is a property of the
> > mode/timing settings (though I'm not entirely sure timings are fully
> > hardware rev agnostic). I don't dispute that.
> > However, this reflects the current driver behavior. It's not
> > incorrect, it is a simplified approach that uses a single frequency
> > point across all operating modes of a given platform.
>
> The driver should be fixed/improved. Reverting the link between CCI
> clock frequency and CCI hardware revision is invalid, it should not
> be done.
>
> > I added a brief paragraph in the V2 cover letter to explain why it's
> > out of scope.
> >
> > My argument is about scope. Today the driver has no mechanism to pick
> > a rate per mode, a single CCI clock is shared by N masters (usually
> > two) that can run in different modes simultaneously, so per-mode
> > scaling requires (1) per-mode rate info in the params table, and (2)
> > vote/arbitration logic to select the highest required rate and still
> > apply correct timings for every master at that rate. Concretely, with
> > one master in Standard and another in Fast+, you'd need a 37.5 MHz
> > shared clock and a Standard-mode row calibrated for 37.5 MHz, which
>
> This is a limitation of the driver only. For a selected CCI revision
> please add 'struct hw_params' for Standard mode / 37.5MHz supply clock
> frequency, and the problem is solved.
>
> > the msm8953 table simply does not provide today. So this isn't a small
> > tweak, it's a new capability backed by new table data. It would bring
> > more fine tuned supply rate, but without huge benefit, as cci clock is
> > gated most of the time due to runtime-pm.
> >
> >> But what if you have only one master?..
> >
> > It's not important here? we have N master (usually two) and have to
> > deal with that.
>
> It is important in sense that any one master usecases are properly
> supported.
>
> >> I think the msm8953 data is correct, it shall not be removed.
> >
> > The msm8953 table as it stands is internally inconsistent (without
> > per-mode rate info), no single clock makes all three modes correct.
>
> It is so, because there is msm8953 data is incomplete. But the present
> msm8953 data is correct.
>
> > Moreover, msm8953 is the same HW version as msm8996/sdm630, which
> > already use cci_v2_data, there's no strong reason for msm8953 to keep
> > a bespoke, half-and-half table.
> >
>
> Okay, I read it as 'struct hw_params' data for msm8953 can be removed
> and v2 data should be used for this CCI hardvare variant.
>
> >>> no single rate can satisfy all three modes with the current table, and
> >>> the DT assigns 19.2 MHz, so Fast+ timings are wrong.
>
> If hypotetically 'struct hw_params' Fast+ timing for 19.2MHz supply
> clock is added to the driver, this usecase will supported by the driver.
> As for today the driver has a bug, no doubt.
>
> > This series intentionally does the minimal correct thing, aligning the
> > timings with a single supply clock and enforcing that clock in the
> > driver, which owns hw_params and has all the info to produce correct
> > timing. It fixes reported devices misbehaving when no (or incorrect)
> > assigned-clock-rate is set.
>
> Since we're discussing it, this fix is not the only one possible,
> and the fix which returns the link between CCI hardware revision and
> CCI supply clock frequency is an invalid fix.
>
> > Not saying what you propose is not do-able, and I clearly understand
> > what you mean, but I'd prefer to land this simple
> > alignment/enforcement first and treat per-mode clock scaling as a
> > follow-up, rather than coupling a straightforward fix to a larger
> > refactor. Please clearly Nack if you do not agree with this first
> > step.
>
> Instead of a non-productive NAK I can provide a simple change adding
> a proper link between speed mode and registers programming.

So I guess what you'd like is something along these lines:
https://github.com/loicpoulain/linux/commit/fdacebb22d914ca64b0c3d4e257a913dc0cd16dd

My intention was simply to move this 'disruptive' change out of the
series scope, as I don't believe this series itself is incorrect.

However, if you'd really rather have everything addressed in a single
series, I'd be inclined to either pick/rework the series in that
direction.

Regards,
Loic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 3/3] i2c: qcom-cci: Fix CCI clock rate enforcement
  2026-07-27  9:21 ` [PATCH v2 3/3] i2c: qcom-cci: Fix CCI clock rate enforcement Loic Poulain
  2026-07-27  9:33   ` Mukesh Savaliya
@ 2026-07-28 15:57   ` Vladimir Zapolskiy
  2026-07-29 11:35     ` Loic Poulain
  1 sibling, 1 reply; 15+ messages in thread
From: Vladimir Zapolskiy @ 2026-07-28 15:57 UTC (permalink / raw)
  To: Loic Poulain, Robert Foss, Andi Shyti, Wolfram Sang,
	Dmitry Baryshkov, Luca Weiss
  Cc: linux-i2c, linux-arm-msm, linux-kernel, Wenmeng Liu, Konrad Dybcio

Hi Loic.

On 7/27/26 12:21, Loic Poulain wrote:
> The hw_params timing values (thigh, tlow, etc.) are in CCI clock ticks
> and were calibrated for a specific clock rate per hardware variant. If
> the clock is running at a different rate the I2C timings will be wrong,
> potentially violating the I2C specification.
> 
> Rather than just warning about a mismatch like before, actively set
> the clock to the expected rate, using the OPP framework so that boards
> which (will) describe an opp table also get the required power-domain and
> regulator votes for that rate. The OPP table is optional, boards without
> one simply fall back to a plain clk_set_rate() behavior, so existing DTs
> keep working.
> 

Can you please share any deficiencies you see, if a regular mechanism
of 'assigned-clock-rates' is used in dt descriptions instead of setting
a supported clock rate from the driver? Or is opps mechanism supposed to
substitute it?

For instance qcom,i2c-cci.yaml example uses 'assigned-clock-rates'
properly, in many .dtsi files (NB, but not all, which means for a number
of platforms CCI hw programming is done incorrectly today) CCI clock
rate is set this way.

It seems to be sufficient to get the clock rate in probe, compare it
against the supported clock rate associated with a wanted mode, return
-EOPNOTSUPP if there is no match.

To get a better idea of my proposal please check this simple commit:

* https://github.com/torvalds/linux/compare/master...vzapolskiy:linux-lpc32xx:cci-speed-modes

> Tested-by: Wenmeng Liu <wenmeng.liu@oss.qualcomm.com>
> Suggested-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>

-- 
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 3/3] i2c: qcom-cci: Fix CCI clock rate enforcement
  2026-07-28 15:57   ` Vladimir Zapolskiy
@ 2026-07-29 11:35     ` Loic Poulain
  2026-07-29 11:51       ` Vladimir Zapolskiy
  0 siblings, 1 reply; 15+ messages in thread
From: Loic Poulain @ 2026-07-29 11:35 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Robert Foss, Andi Shyti, Wolfram Sang, Dmitry Baryshkov,
	Luca Weiss, linux-i2c, linux-arm-msm, linux-kernel, Wenmeng Liu,
	Konrad Dybcio

Hi Vladimir,

On Tue, Jul 28, 2026 at 5:58 PM Vladimir Zapolskiy
<vladimir.zapolskiy@linaro.org> wrote:
>
> Hi Loic.
>
> On 7/27/26 12:21, Loic Poulain wrote:
> > The hw_params timing values (thigh, tlow, etc.) are in CCI clock ticks
> > and were calibrated for a specific clock rate per hardware variant. If
> > the clock is running at a different rate the I2C timings will be wrong,
> > potentially violating the I2C specification.
> >
> > Rather than just warning about a mismatch like before, actively set
> > the clock to the expected rate, using the OPP framework so that boards
> > which (will) describe an opp table also get the required power-domain and
> > regulator votes for that rate. The OPP table is optional, boards without
> > one simply fall back to a plain clk_set_rate() behavior, so existing DTs
> > keep working.
> >
>
> Can you please share any deficiencies you see, if a regular mechanism
> of 'assigned-clock-rates' is used in dt descriptions instead of setting
> a supported clock rate from the driver? Or is opps mechanism supposed to
> substitute it?

assigned-clock-rates describes an initial hardware clock configuration
applied before probe, but is a bit unclear about when we should really
use it. In our case the CCI core rate isn't a fixed hardware property,
it's a software policy tied to the I2C mode(s) the driver programs.
The driver is then component that knows which rate a given mode
needs, so it should own that decision.

Driving it from DT means the DT author has to know the per-mode rate
constraints (effectively reading the driver) and keep the two in sync
(the CCI/I2C bus rate and the CCI core rate), which is probably why
several dts files got it wrong today. Enforcing the rate in the driver
fixes all of those cases in one go.

OPP doesn't really substitute the  assigned-clock-rates, we just use
it to describe the constraints/votes (power-domain, regulator)
associated with each operating rate (picked at runtime), if any.

> For instance qcom,i2c-cci.yaml example uses 'assigned-clock-rates'
> properly, in many .dtsi files (NB, but not all, which means for a number
> of platforms CCI hw programming is done incorrectly today) CCI clock
> rate is set this way.

Yes and that's fragile. I think we should remove that from the example.

>
> It seems to be sufficient to get the clock rate in probe, compare it
> against the supported clock rate associated with a wanted mode, return
> -EOPNOTSUPP if there is no match.

Certainly valid, but I don't think it would hurt to complement it with
additional enforcement in the driver. I don't see why the CCI driver
should be prevented from configuring its own clock. It has all the
information required to determine the correct rate and should not have
to rely on or trust whatever clock state happens to be programmed
beforehand. Instead of merely rejecting an unexpected rate, it can
program the correct one itself, which is standard driver behavior and
not particularly different from what many other drivers do.

> To get a better idea of my proposal please check this simple commit:
>
> * https://github.com/torvalds/linux/compare/master...vzapolskiy:linux-lpc32xx:cci-speed-modes

Thanks, I think I have a clear understanding of what you're advocating
for. While it does expand the scope of the original series somewhat,
now we've discussed it in enough detail, I've taken your suggestions
into account for the upcoming v3. Let's continue the discussion on
that version.

Regards,
Loic


>
> > Tested-by: Wenmeng Liu <wenmeng.liu@oss.qualcomm.com>
> > Suggested-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> > Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
>
> --
> Best wishes,
> Vladimir

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 1/3] i2c: qcom-cci: Switch msm8953 to the CCI v2 timing/rate config
  2026-07-28 10:26         ` Loic Poulain
@ 2026-07-29 11:40           ` Vladimir Zapolskiy
  0 siblings, 0 replies; 15+ messages in thread
From: Vladimir Zapolskiy @ 2026-07-29 11:40 UTC (permalink / raw)
  To: Loic Poulain
  Cc: Robert Foss, Andi Shyti, Wolfram Sang, Dmitry Baryshkov,
	Luca Weiss, linux-i2c, linux-arm-msm, linux-kernel,
	Konrad Dybcio, Stephan Gerhold

Hi Loic,

cc: Stephan, Konrad as participants of this old discussion:

* https://lore.kernel.org/linux-arm-msm/aL6Vp-3er71AJPJd@linaro.org/

On 7/28/26 13:26, Loic Poulain wrote:
> On Tue, Jul 28, 2026 at 11:38 AM Vladimir Zapolskiy
> <vladimir.zapolskiy@linaro.org> wrote:
>>
>> Hi Loic,
>>
>> On 7/28/26 11:20, Loic Poulain wrote:
>>> Hi Vladimir,
>>>
>>> On Mon, Jul 27, 2026 at 9:21 PM Vladimir Zapolskiy
>>> <vladimir.zapolskiy@linaro.org> wrote:
>>>>
>>>> Hi Loic,
>>>>
>>>> On 7/27/26 12:21, Loic Poulain wrote:
>>>>> The msm8953 CCI timing table is internally inconsistent. Its Standard
>>>>
>>>> likely I was misunderstood in my v1 review comments, and I believe v3
>>>> will be needed...
>>>>
>>>> If there is just one master, or two masters set in equal speed mode,
>>>> then there is no such issue as "msm8953 CCI timing table is internally
>>>> inconsistent". In other words generally it shall be permitted to have
>>>> supply clock frequency intermixed speed modes for any CCI variant.
>>>
>>> The two masters sharing the supply clock are independently
>>> configurable in terms of mode, so we simply can't guarantee they will
>>> run in same mode.
>>
>> There should be no restriction or guarantee to configure the same mode
>> for two masters. The supply clock frequency is one for both masters,
>> but speed mode selection is based on its presense in the driver by
>> the CCI frequency.
>>
>> If there is no match in the driver for CCI clock frequency/speed mode,
>> return -EOPNOTSUPP for such master.
>>
>> Think of it, right now for each CCI hardware revision 3 'struct hw_params'
>> are provided by the driver, some of them match 19.2MHz frequency, some of
>> them match 37.5MHz frequency or intermixed for msm8953 case. Likely there
>> is no restriction to provide 6 'struct hw_params' for each CCI hardware
>> revision covering both 19.2MHz and 37.5MHz supply clock frequencies, then
>> any combination of speed modes can be configured on any CCI hardware for
>> two masters.
>>
>> The main point is that CCI clock frequency is not specific to CCI hardware,
>> but it is specific to 'struct hw_params' mode.
>>
>>>> I'll repeat the same point as given in v1, namely supply clock frequency
>>>> is not a property of CCI revision (therefore v1 1/3 or v2 2/3 is invalid),
>>>> it is a property of the mode settings. It's correct to remove 'cci_clk_rate'
>>>> from 'struct cci_data', and it will be correct to add (or parameterize in
>>>> any other way) 'cci_clk_rate' to 'struct hw_params'. Each instance of
>>>> 'struct hw_params' is strictly bound to a particular CCI clock frequency.
>>>>
>>>>> and Fast timings match v1/v1.5, which are calibrated for a 19.2 MHz CCI
>>>>> clock, but its Fast+ timings are essentially the v2 values, which are
>>>>> calibrated for 37.5 MHz. Since all masters share a single CCI clock,
>>>
>>> So, you're right that the supply clock frequency is a property of the
>>> mode/timing settings (though I'm not entirely sure timings are fully
>>> hardware rev agnostic). I don't dispute that.
>>> However, this reflects the current driver behavior. It's not
>>> incorrect, it is a simplified approach that uses a single frequency
>>> point across all operating modes of a given platform.
>>
>> The driver should be fixed/improved. Reverting the link between CCI
>> clock frequency and CCI hardware revision is invalid, it should not
>> be done.
>>
>>> I added a brief paragraph in the V2 cover letter to explain why it's
>>> out of scope.
>>>
>>> My argument is about scope. Today the driver has no mechanism to pick
>>> a rate per mode, a single CCI clock is shared by N masters (usually
>>> two) that can run in different modes simultaneously, so per-mode
>>> scaling requires (1) per-mode rate info in the params table, and (2)
>>> vote/arbitration logic to select the highest required rate and still
>>> apply correct timings for every master at that rate. Concretely, with
>>> one master in Standard and another in Fast+, you'd need a 37.5 MHz
>>> shared clock and a Standard-mode row calibrated for 37.5 MHz, which
>>
>> This is a limitation of the driver only. For a selected CCI revision
>> please add 'struct hw_params' for Standard mode / 37.5MHz supply clock
>> frequency, and the problem is solved.
>>
>>> the msm8953 table simply does not provide today. So this isn't a small
>>> tweak, it's a new capability backed by new table data. It would bring
>>> more fine tuned supply rate, but without huge benefit, as cci clock is
>>> gated most of the time due to runtime-pm.
>>>
>>>> But what if you have only one master?..
>>>
>>> It's not important here? we have N master (usually two) and have to
>>> deal with that.
>>
>> It is important in sense that any one master usecases are properly
>> supported.
>>
>>>> I think the msm8953 data is correct, it shall not be removed.
>>>
>>> The msm8953 table as it stands is internally inconsistent (without
>>> per-mode rate info), no single clock makes all three modes correct.
>>
>> It is so, because there is msm8953 data is incomplete. But the present
>> msm8953 data is correct.
>>
>>> Moreover, msm8953 is the same HW version as msm8996/sdm630, which
>>> already use cci_v2_data, there's no strong reason for msm8953 to keep
>>> a bespoke, half-and-half table.
>>>
>>
>> Okay, I read it as 'struct hw_params' data for msm8953 can be removed
>> and v2 data should be used for this CCI hardvare variant.
>>
>>>>> no single rate can satisfy all three modes with the current table, and
>>>>> the DT assigns 19.2 MHz, so Fast+ timings are wrong.
>>
>> If hypotetically 'struct hw_params' Fast+ timing for 19.2MHz supply
>> clock is added to the driver, this usecase will supported by the driver.
>> As for today the driver has a bug, no doubt.
>>
>>> This series intentionally does the minimal correct thing, aligning the
>>> timings with a single supply clock and enforcing that clock in the
>>> driver, which owns hw_params and has all the info to produce correct
>>> timing. It fixes reported devices misbehaving when no (or incorrect)
>>> assigned-clock-rate is set.
>>
>> Since we're discussing it, this fix is not the only one possible,
>> and the fix which returns the link between CCI hardware revision and
>> CCI supply clock frequency is an invalid fix.
>>
>>> Not saying what you propose is not do-able, and I clearly understand
>>> what you mean, but I'd prefer to land this simple
>>> alignment/enforcement first and treat per-mode clock scaling as a
>>> follow-up, rather than coupling a straightforward fix to a larger
>>> refactor. Please clearly Nack if you do not agree with this first
>>> step.
>>
>> Instead of a non-productive NAK I can provide a simple change adding
>> a proper link between speed mode and registers programming.
> 
> So I guess what you'd like is something along these lines:
> https://github.com/loicpoulain/linux/commit/fdacebb22d914ca64b0c3d4e257a913dc0cd16dd
> 

I shared another and personally more preferred variant yesterday:
* https://github.com/vzapolskiy/linux-lpc32xx/commit/e3dee612da90

The main differences:
* all CCI programming data is consolidated and removed from driver
   data specific to CCI revisions,
* as an immediate positive side effect 19.2MHz supply clock frequency
   is supported for v2 revision of CCI.

> My intention was simply to move this 'disruptive' change out of the
> series scope, as I don't believe this series itself is incorrect.
> 
> However, if you'd really rather have everything addressed in a single
> series, I'd be inclined to either pick/rework the series in that
> direction.
> 

If you find it possible to incorporate the change above, it would
be very much appreciated.

The next question to solve is to fix CCI mode programming for all
platforms with CCI v2 revision, which are obviously broken right
now, and partially are fixed by the change proposed by me above.

These platform .dtsi files contain CCI clock rate assignment:
* agatti.dtsi
* msm8916.dtsi
* msm8939.dtsi
* msm8953.dtsi
* msm8996.dtsi
* sdm630.dtsi
* sdm845.dtsi
* sm6350.dtsi

These platform .dtsi files do not contain CCI clock rate assignments:
* kodiak.dtsi
* lemans.dtsi
* milos.dtsi
* monaco.dtsi
* sc8280xp.dtsi
* sdm670.dtsi
* sm8250.dtsi
* sm8450.dtsi
* sm8550.dtsi
* sm8650.dtsi
* talos.dtsi

One proposed "fix" (note that formally it is not a fix, but it compliments
a today's flaw in the driver) is to add CCI clock rate assigments like this,
it seems Stephan and me support such an approach, its benefit is that it
does not require any driver changes:
* https://lore.kernel.org/linux-arm-msm/20260729112719.1151700-1-vladimir.zapolskiy@linaro.org

Another and likely more preferred approach suggested by Konrad is to
use OPP tables. If this one is selected, then, as Konrad said, it would
be needed to resurrect/rebase his series, it would be important to update
the dt binding documentation etc. Please note, that a forcible setting
of CCI clock rate over OPP mechanism can also be done independently on
top of my non-intrusive "read-only" change.

-- 
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 3/3] i2c: qcom-cci: Fix CCI clock rate enforcement
  2026-07-29 11:35     ` Loic Poulain
@ 2026-07-29 11:51       ` Vladimir Zapolskiy
  0 siblings, 0 replies; 15+ messages in thread
From: Vladimir Zapolskiy @ 2026-07-29 11:51 UTC (permalink / raw)
  To: Loic Poulain
  Cc: Robert Foss, Andi Shyti, Wolfram Sang, Dmitry Baryshkov,
	Luca Weiss, linux-i2c, linux-arm-msm, linux-kernel, Wenmeng Liu,
	Konrad Dybcio, Stephen Boyd, Stephan Gerhold

Hi Loic.

On 7/29/26 14:35, Loic Poulain wrote:
> Hi Vladimir,
> 
> On Tue, Jul 28, 2026 at 5:58 PM Vladimir Zapolskiy
> <vladimir.zapolskiy@linaro.org> wrote:
>>
>> Hi Loic.
>>
>> On 7/27/26 12:21, Loic Poulain wrote:
>>> The hw_params timing values (thigh, tlow, etc.) are in CCI clock ticks
>>> and were calibrated for a specific clock rate per hardware variant. If
>>> the clock is running at a different rate the I2C timings will be wrong,
>>> potentially violating the I2C specification.
>>>
>>> Rather than just warning about a mismatch like before, actively set
>>> the clock to the expected rate, using the OPP framework so that boards
>>> which (will) describe an opp table also get the required power-domain and
>>> regulator votes for that rate. The OPP table is optional, boards without
>>> one simply fall back to a plain clk_set_rate() behavior, so existing DTs
>>> keep working.
>>>
>>
>> Can you please share any deficiencies you see, if a regular mechanism
>> of 'assigned-clock-rates' is used in dt descriptions instead of setting
>> a supported clock rate from the driver? Or is opps mechanism supposed to
>> substitute it?
> 
> assigned-clock-rates describes an initial hardware clock configuration
> applied before probe, but is a bit unclear about when we should really
> use it. In our case the CCI core rate isn't a fixed hardware property,
> it's a software policy tied to the I2C mode(s) the driver programs.
> The driver is then component that knows which rate a given mode
> needs, so it should own that decision.

Sent you a verbose comment, but we can continue discussion here.

I'm fine with 'assigned-clocks' variant, but what you say is also fine
with me, if the CCI device driver forcibly sets the desired clock rate,
please note that it does not exclude to set 19.2MHz rate for CCI v2
revisions, for instance, that's why I believe my change shared with
you is a step towards the right direction. A change to implement
a policy mechanism and set the wanted rate can be done on top of it.

> Driving it from DT means the DT author has to know the per-mode rate
> constraints (effectively reading the driver) and keep the two in sync
> (the CCI/I2C bus rate and the CCI core rate), which is probably why
> several dts files got it wrong today. Enforcing the rate in the driver
> fixes all of those cases in one go.
> 
> OPP doesn't really substitute the  assigned-clock-rates, we just use
> it to describe the constraints/votes (power-domain, regulator)
> associated with each operating rate (picked at runtime), if any.
> 
>> For instance qcom,i2c-cci.yaml example uses 'assigned-clock-rates'
>> properly, in many .dtsi files (NB, but not all, which means for a number
>> of platforms CCI hw programming is done incorrectly today) CCI clock
>> rate is set this way.
> 
> Yes and that's fragile. I think we should remove that from the example.
> 

It's up to you, there will be no objections from my side. There might be
pro et contra arguments about 'assigned-clocks' mechanism though.

>>
>> It seems to be sufficient to get the clock rate in probe, compare it
>> against the supported clock rate associated with a wanted mode, return
>> -EOPNOTSUPP if there is no match.
> 
> Certainly valid, but I don't think it would hurt to complement it with
> additional enforcement in the driver. I don't see why the CCI driver
> should be prevented from configuring its own clock. It has all the
> information required to determine the correct rate and should not have
> to rely on or trust whatever clock state happens to be programmed
> beforehand. Instead of merely rejecting an unexpected rate, it can
> program the correct one itself, which is standard driver behavior and
> not particularly different from what many other drivers do.
> 
>> To get a better idea of my proposal please check this simple commit:
>>
>> * https://github.com/torvalds/linux/compare/master...vzapolskiy:linux-lpc32xx:cci-speed-modes
> 
> Thanks, I think I have a clear understanding of what you're advocating
> for. While it does expand the scope of the original series somewhat,
> now we've discussed it in enough detail, I've taken your suggestions
> into account for the upcoming v3. Let's continue the discussion on
> that version.
> 

Thank you!

-- 
Best wishes,
Vladimir

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-07-29 11:51 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-27  9:21 [PATCH v2 0/3] i2c: qcom-cci: Fix CCI clock rate enforcement Loic Poulain
2026-07-27  9:21 ` [PATCH v2 1/3] i2c: qcom-cci: Switch msm8953 to the CCI v2 timing/rate config Loic Poulain
2026-07-27 19:21   ` Vladimir Zapolskiy
2026-07-28  8:20     ` Loic Poulain
2026-07-28  9:38       ` Vladimir Zapolskiy
2026-07-28 10:26         ` Loic Poulain
2026-07-29 11:40           ` Vladimir Zapolskiy
2026-07-27  9:21 ` [PATCH v2 2/3] Revert "i2c: qcom-cci: Remove unused struct member cci_clk_rate" Loic Poulain
2026-07-27  9:21 ` [PATCH v2 3/3] i2c: qcom-cci: Fix CCI clock rate enforcement Loic Poulain
2026-07-27  9:33   ` Mukesh Savaliya
2026-07-27  9:45     ` Loic Poulain
2026-07-27  9:50       ` Mukesh Savaliya
2026-07-28 15:57   ` Vladimir Zapolskiy
2026-07-29 11:35     ` Loic Poulain
2026-07-29 11:51       ` Vladimir Zapolskiy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®