Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P
@ 2026-08-04 19:57 Praveen Talari
  2026-08-04 19:57 ` [PATCH 1/7] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0 Praveen Talari
                   ` (6 more replies)
  0 siblings, 7 replies; 34+ messages in thread
From: Praveen Talari @ 2026-08-04 19:57 UTC (permalink / raw)
  To: konrad.dybcio, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c, Praveen Talari

On firmware-managed platforms such as SA8255P, there is no Linux clock
handler available to determine the appropriate SE source clock, source
clock index, and divider values for a requested protocol frequency.
However, these parameters are required when programming GSI TREs, where
the hardware expects an explicit clock source selection and divider
configuration for the serial engine.

In contrast, platforms using Linux-managed clocks derive these
parameters through geni_se_clk_freq_match() using the source clock
information stored in clk_perf_tbl. Since the firmware-managed path
lacks equivalent clock information, protocol drivers cannot reuse the
existing frequency matching logic and instead rely on a direct mapping
between protocol-requested frequencies and performance levels. This
creates a separate clock configuration flow and prevents
firmware-managed platforms from deriving the actual SE clock parameters
required for GSI TRE programming.

To address this limitation, the performance-domain OPP table is treated
as the representation of SE-supported source clock frequencies. During
geni_se_domain_attach(), the OPP entries are used to populate
clk_perf_tbl and related clock performance data, allowing
firmware-managed platforms to leverage the same clock frequency matching
infrastructure used by Linux-managed platforms.

With this change, protocol drivers can use geni_se_clk_freq_match() to
select the closest supported source clock frequency for a requested
protocol rate, derive the corresponding source clock index and divider
values required for GSI TRE programming, and apply the matched clock
through the OPP framework. This removes the dependency on direct
protocol-frequency-to-performance-level mappings and provides a common
clock selection and configuration mechanism across both firmware-managed
and Linux-managed GENI deployments.

Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
Praveen Talari (7):
      pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0
      soc: qcom: geni-se: Populate clk_perf_tbl with SE source clock frequencies from perf OPP table
      soc: qcom: geni-se: Add helper to set SE clock rate via OPP
      serial: qcom-geni: Use geni_se_set_rate() for source clock configuration
      spi: qcom-geni: Use geni_se_set_rate() for setting source clock frequency
      i2c: qcom-geni: Use common GENI resource initialization helper
      i2c: qcom-geni: Use geni_se_set_rate() for setting source clock frequency

 drivers/i2c/busses/i2c-qcom-geni.c      | 45 +++++++++++-----------------
 drivers/pmdomain/arm/scmi_perf_domain.c |  2 +-
 drivers/soc/qcom/qcom-geni-se.c         | 53 ++++++++++++++++++++++++++++++++-
 drivers/spi/spi-geni-qcom.c             | 17 ++++-------
 drivers/tty/serial/qcom_geni_serial.c   | 19 ++++++------
 include/linux/soc/qcom/geni-se.h        |  2 ++
 6 files changed, 88 insertions(+), 50 deletions(-)
---
base-commit: 0f6da28aab51b16762ed82e8fdeaa5042da45b08
change-id: 20260805-derive_clk_perf_tbl_from_perf_domain_opp_table-2f29ad32226a

Best regards,
--  
Praveen Talari <praveen.talari@oss.qualcomm.com>



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

* [PATCH 1/7] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0
  2026-08-04 19:57 [PATCH 0/7] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
@ 2026-08-04 19:57 ` Praveen Talari
  2026-08-10 14:19   ` Ulf Hansson
                     ` (3 more replies)
  2026-08-04 19:57 ` [PATCH 2/7] soc: qcom: geni-se: Populate clk_perf_tbl with SE source clock frequencies from perf OPP table Praveen Talari
                   ` (5 subsequent siblings)
  6 siblings, 4 replies; 34+ messages in thread
From: Praveen Talari @ 2026-08-04 19:57 UTC (permalink / raw)
  To: konrad.dybcio, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c, Praveen Talari

Currently, scmi_pd_set_perf_state() treats a performance state of 0 as
invalid and returns -EINVAL. As a result, devices attached to SCMI
performance domains can report failures when relinquishing their
performance vote.

The OPP framework use performance state 0 to indicate that no performance
vote is required. For example, dev_pm_opp_set_rate(dev, 0) is commonly
used (by firmware or linux)  when a device is runtime suspended.

A zero performance state does not require any SCMI performance request
to be sent. Treat it as a no-op and return success instead of reporting
an error.

Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
 drivers/pmdomain/arm/scmi_perf_domain.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pmdomain/arm/scmi_perf_domain.c b/drivers/pmdomain/arm/scmi_perf_domain.c
index 3693423459c9..e390f902a444 100644
--- a/drivers/pmdomain/arm/scmi_perf_domain.c
+++ b/drivers/pmdomain/arm/scmi_perf_domain.c
@@ -33,7 +33,7 @@ scmi_pd_set_perf_state(struct generic_pm_domain *genpd, unsigned int state)
 		return 0;
 
 	if (!state)
-		return -EINVAL;
+		return 0;
 
 	ret = pd->perf_ops->level_set(pd->ph, pd->domain_id, state, false);
 	if (ret)

-- 
2.34.1



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

* [PATCH 2/7] soc: qcom: geni-se: Populate clk_perf_tbl with SE source clock frequencies from perf OPP table
  2026-08-04 19:57 [PATCH 0/7] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
  2026-08-04 19:57 ` [PATCH 1/7] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0 Praveen Talari
@ 2026-08-04 19:57 ` Praveen Talari
  2026-08-12  7:36   ` Mukesh Savaliya
  2026-08-24 14:56   ` Konrad Dybcio
  2026-08-04 19:57 ` [PATCH 3/7] soc: qcom: geni-se: Add helper to set SE clock rate via OPP Praveen Talari
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 34+ messages in thread
From: Praveen Talari @ 2026-08-04 19:57 UTC (permalink / raw)
  To: konrad.dybcio, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c, Praveen Talari

Currently, on the SA8255P platform, protocol drivers attached via
geni_se_domain_attach() treat each OPP on the perf domain as directly
corresponding to a protocol value such as a baudrate or requested
frequency, and simply request that OPP via
geni_se_set_perf_level()/geni_se_set_perf_opp(). This does not allow
computing a source clock and divider combination for a protocol
requested frequency, unlike the Linux clock managed path which derives
this from se->clk_perf_tbl via geni_se_clk_freq_match(), and then
applies the matched source clock frequency with dev_pm_opp_set_rate().

Change this by treating the OPP table exposed on the perf domain
device as representing the actual SE HW supported source clock
frequencies, the same role clk_perf_tbl plays for the Linux clock
managed path. Populate se->clk_perf_tbl and se->num_clk_levels by
iterating over this OPP table in geni_se_domain_attach(), so that
protocol drivers on the firmware managed (SA8255P) path can also use
geni_se_clk_freq_match() to pick the closest supported source clock
frequency and calculate the required divider, and apply it with
dev_pm_opp_set_rate() the same way as it is done for the Linux clock
managed path, instead of relying on a direct frequency/baudrate-to-
perf-level mapping.

Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
 drivers/soc/qcom/qcom-geni-se.c | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index 873bfbd6b2b7..a88bd092b87e 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -1155,7 +1155,8 @@ EXPORT_SYMBOL_GPL(geni_se_set_perf_opp);
  *
  * This function attaches the power domains ("power" and "perf") required
  * in the SCMI auto-VM environment to the GENI Serial Engine device. It
- * initializes se->pd_list with the attached domains.
+ * initializes se->pd_list with the attached domains, and populates
+ * se->clk_perf_tbl from the OPP table of the "perf" domain device.
  *
  * Return: 0 on success, or a negative error code on failure.
  */
@@ -1166,7 +1167,12 @@ int geni_se_domain_attach(struct geni_se *se)
 		.pd_names = (const char*[]) { "power", "perf" },
 		.num_pd_names = 2,
 	};
+	struct device *perf_dev;
+	struct dev_pm_opp *opp;
+	unsigned int level;
+	int num_opps;
 	int ret;
+	int i;
 
 	ret = devm_pm_domain_attach_list(se->dev,
 					 &pd_data, &se->pd_list);
@@ -1175,6 +1181,29 @@ int geni_se_domain_attach(struct geni_se *se)
 	else if (ret < 0)
 		return ret;
 
+	perf_dev = se->pd_list->pd_devs[DOMAIN_IDX_PERF];
+
+	num_opps = dev_pm_opp_get_opp_count(perf_dev);
+	if (num_opps <= 0)
+		return num_opps < 0 ? num_opps : -ENODEV;
+
+	se->clk_perf_tbl = devm_kcalloc(se->dev, num_opps,
+					sizeof(*se->clk_perf_tbl),
+					GFP_KERNEL);
+	if (!se->clk_perf_tbl)
+		return -ENOMEM;
+
+	for (i = 0, level = 0; i < num_opps; i++, level++) {
+		opp = dev_pm_opp_find_level_ceil(perf_dev, &level);
+		if (IS_ERR(opp))
+			return PTR_ERR(opp);
+
+		se->clk_perf_tbl[i] = level;
+		dev_pm_opp_put(opp);
+	}
+	se->num_clk_levels = num_opps;
+	se->has_opp = true;
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(geni_se_domain_attach);

-- 
2.34.1



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

* [PATCH 3/7] soc: qcom: geni-se: Add helper to set SE clock rate via OPP
  2026-08-04 19:57 [PATCH 0/7] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
  2026-08-04 19:57 ` [PATCH 1/7] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0 Praveen Talari
  2026-08-04 19:57 ` [PATCH 2/7] soc: qcom: geni-se: Populate clk_perf_tbl with SE source clock frequencies from perf OPP table Praveen Talari
@ 2026-08-04 19:57 ` Praveen Talari
  2026-08-12  8:55   ` Mukesh Savaliya
                     ` (2 more replies)
  2026-08-04 19:57 ` [PATCH 4/7] serial: qcom-geni: Use geni_se_set_rate() for source clock configuration Praveen Talari
                   ` (3 subsequent siblings)
  6 siblings, 3 replies; 34+ messages in thread
From: Praveen Talari @ 2026-08-04 19:57 UTC (permalink / raw)
  To: konrad.dybcio, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c, Praveen Talari

GENI protocol drivers need a common way to scale the SE source clock
through the OPP framework. However, the device that owns the OPP table
differs depending on how the SE resources are managed. For Linux clock
managed platforms, the OPP table is associated with the SE device,
whereas on firmware-managed platforms it is associated with the
performance power-domain device. This requires protocol drivers to be
aware of the underlying resource management model when requesting
frequency changes.

Introduce geni_se_set_rate(), a common helper that abstracts this
difference and applies the requested frequency through the appropriate
device. The helper automatically selects the performance-domain device
when power domains are attached and falls back to the SE device
otherwise.

Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
 drivers/soc/qcom/qcom-geni-se.c  | 22 ++++++++++++++++++++++
 include/linux/soc/qcom/geni-se.h |  2 ++
 2 files changed, 24 insertions(+)

diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index a88bd092b87e..12d7cbc84d60 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -1149,6 +1149,28 @@ int geni_se_set_perf_opp(struct geni_se *se, unsigned long clk_freq)
 }
 EXPORT_SYMBOL_GPL(geni_se_set_perf_opp);
 
+/**
+ * geni_se_set_rate() - Set the SE source clock rate via the OPP framework.
+ * @se: Pointer to the struct geni_se instance.
+ * @freq: The source clock frequency to set.
+ *
+ * Applies the given frequency through dev_pm_opp_set_rate(), targeting the
+ * perf domain device when the SE has power domains attached (firmware
+ * managed path), or se->dev otherwise (Linux clock managed path).
+ *
+ * Return: 0 on success, or a negative error code on failure.
+ */
+int geni_se_set_rate(struct geni_se *se, unsigned long freq)
+{
+	struct device *perf_dev = se->dev;
+
+	if (se->pd_list && se->pd_list->pd_devs[DOMAIN_IDX_PERF])
+		perf_dev = se->pd_list->pd_devs[DOMAIN_IDX_PERF];
+
+	return se->has_opp ? dev_pm_opp_set_rate(perf_dev, freq) : 0;
+}
+EXPORT_SYMBOL_GPL(geni_se_set_rate);
+
 /**
  * geni_se_domain_attach() - Attach power domains to a GENI SE device.
  * @se: Pointer to the geni_se structure representing the GENI SE device.
diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni-se.h
index 29a53bbc0dd4..3b411cba9339 100644
--- a/include/linux/soc/qcom/geni-se.h
+++ b/include/linux/soc/qcom/geni-se.h
@@ -596,5 +596,7 @@ int geni_se_domain_attach(struct geni_se *se);
 int geni_se_set_perf_level(struct geni_se *se, unsigned long level);
 
 int geni_se_set_perf_opp(struct geni_se *se, unsigned long clk_freq);
+
+int geni_se_set_rate(struct geni_se *se, unsigned long freq);
 #endif
 #endif

-- 
2.34.1



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

* [PATCH 4/7] serial: qcom-geni: Use geni_se_set_rate() for source clock configuration
  2026-08-04 19:57 [PATCH 0/7] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
                   ` (2 preceding siblings ...)
  2026-08-04 19:57 ` [PATCH 3/7] soc: qcom: geni-se: Add helper to set SE clock rate via OPP Praveen Talari
@ 2026-08-04 19:57 ` Praveen Talari
  2026-08-24 11:39   ` Mukesh Savaliya
                     ` (2 more replies)
  2026-08-04 19:57 ` [PATCH 5/7] spi: qcom-geni: Use geni_se_set_rate() for setting source clock frequency Praveen Talari
                   ` (2 subsequent siblings)
  6 siblings, 3 replies; 34+ messages in thread
From: Praveen Talari @ 2026-08-04 19:57 UTC (permalink / raw)
  To: konrad.dybcio, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c, Praveen Talari

The driver calls dev_pm_opp_set_rate() directly on uport->dev to apply
the computed source clock frequency, and dispatches baud rate handling
through a per-variant dev_data->set_rate() callback that either
recalculates the clock divider (Linux clock managed path) or selects
a performance level via geni_se_set_perf_level() (SA8255P firmware
managed path).

Now that geni_se_domain_attach() populates se->clk_perf_tbl from the
perf domain's OPP table, geni_se_clk_freq_match() can resolve a source
clock frequency and divider on the SA8255P path the same way it
already does for the Linux clock managed path. This removes the need
for a separate perf-level based set_rate implementation, so
geni_serial_set_rate() can be called unconditionally and
dev_data->set_rate can be dropped.

Switch to calling geni_serial_set_rate() directly from
qcom_geni_serial_set_termios(), and use geni_se_set_rate() in place of
dev_pm_opp_set_rate() so the frequency is applied to the correct
device (the perf domain device on the firmware managed path, or
uport->dev otherwise) without the driver needing to know which
resources_init variant is in use. Remove the now-unused set_rate field
from struct qcom_geni_device_data and its per-variant initializers.

Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
 drivers/tty/serial/qcom_geni_serial.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 3633723acef8..cd1940eae084 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -114,7 +114,6 @@ struct qcom_geni_device_data {
 	bool console;
 	enum geni_se_xfer_mode mode;
 	int (*resources_init)(struct geni_se *se);
-	int (*set_rate)(struct geni_se *se, unsigned long baud);
 	int (*power_on)(struct geni_se *se);
 	int (*power_off)(struct geni_se *se);
 };
@@ -1474,7 +1473,10 @@ static int geni_serial_set_rate(struct geni_se *se, unsigned long baud)
 
 	uport->uartclk = clk_rate;
 	port->clk_rate = clk_rate;
-	dev_pm_opp_set_rate(uport->dev, clk_rate);
+	ret = geni_se_set_rate(&port->se, clk_rate);
+	if (ret)
+		return ret;
+
 	ser_clk_cfg = SER_CLK_EN;
 	ser_clk_cfg |= clk_div << CLK_DIV_SHFT;
 
@@ -1513,7 +1515,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
 	/* baud rate */
 	baud = uart_get_baud_rate(uport, termios, old, 300, 8000000);
 
-	ret = port->dev_data->set_rate(&port->se, baud);
+	ret = geni_serial_set_rate(&port->se, baud);
 	if (ret)
 		return;
 
@@ -2040,6 +2042,8 @@ static int __maybe_unused qcom_geni_serial_runtime_suspend(struct device *dev)
 {
 	struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
 
+	geni_se_set_rate(&port->se, 0);
+
 	return port->dev_data->power_off ?
 	       port->dev_data->power_off(&port->se) : 0;
 }
@@ -2047,7 +2051,6 @@ static int __maybe_unused qcom_geni_serial_runtime_suspend(struct device *dev)
 static int __maybe_unused qcom_geni_serial_runtime_resume(struct device *dev)
 {
 	struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
-	struct uart_port *uport = &port->uport;
 	int ret;
 
 	if (port->dev_data->power_on) {
@@ -2056,8 +2059,8 @@ static int __maybe_unused qcom_geni_serial_runtime_resume(struct device *dev)
 			return ret;
 	}
 
-	if (port->se.has_opp && port->clk_rate)
-		return dev_pm_opp_set_rate(uport->dev, port->clk_rate);
+	if (port->clk_rate)
+		return geni_se_set_rate(&port->se, port->clk_rate);
 
 	return 0;
 }
@@ -2116,7 +2119,6 @@ static const struct qcom_geni_device_data qcom_geni_console_data = {
 	.console = true,
 	.mode = GENI_SE_FIFO,
 	.resources_init = geni_se_resources_init,
-	.set_rate = geni_serial_set_rate,
 	.power_on = geni_se_resources_activate,
 	.power_off = geni_se_resources_deactivate,
 };
@@ -2125,7 +2127,6 @@ static const struct qcom_geni_device_data sa8255p_qcom_geni_console_data = {
 	.console = true,
 	.mode = GENI_SE_FIFO,
 	.resources_init = geni_se_domain_attach,
-	.set_rate = geni_se_set_perf_level,
 };
 #endif
 
@@ -2133,7 +2134,6 @@ static const struct qcom_geni_device_data qcom_geni_uart_data = {
 	.console = false,
 	.mode = GENI_SE_DMA,
 	.resources_init = geni_se_resources_init,
-	.set_rate = geni_serial_set_rate,
 	.power_on = geni_se_resources_activate,
 	.power_off = geni_se_resources_deactivate,
 };
@@ -2142,7 +2142,6 @@ static const struct qcom_geni_device_data sa8255p_qcom_geni_uart_data = {
 	.console = false,
 	.mode = GENI_SE_DMA,
 	.resources_init = geni_se_domain_attach,
-	.set_rate = geni_se_set_perf_level,
 };
 
 static const struct dev_pm_ops qcom_geni_serial_pm_ops = {

-- 
2.34.1



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

* [PATCH 5/7] spi: qcom-geni: Use geni_se_set_rate() for setting source clock frequency
  2026-08-04 19:57 [PATCH 0/7] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
                   ` (3 preceding siblings ...)
  2026-08-04 19:57 ` [PATCH 4/7] serial: qcom-geni: Use geni_se_set_rate() for source clock configuration Praveen Talari
@ 2026-08-04 19:57 ` Praveen Talari
  2026-08-04 20:03   ` Mark Brown
  2026-08-24 11:52   ` Mukesh Savaliya
  2026-08-04 19:57 ` [PATCH 6/7] i2c: qcom-geni: Use common GENI resource initialization helper Praveen Talari
  2026-08-04 19:57 ` [PATCH 7/7] i2c: qcom-geni: Use geni_se_set_rate() for setting source clock frequency Praveen Talari
  6 siblings, 2 replies; 34+ messages in thread
From: Praveen Talari @ 2026-08-04 19:57 UTC (permalink / raw)
  To: konrad.dybcio, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c, Praveen Talari

On the SA8255P platform there is no Linux clock handler for the SE
source clock, so the driver has no way to look up the source clock
index and divider needed to fill the GSI CONFIG0 TRE for a requested
transfer frequency. To work around this, firmware instead exposes the
SE HW supported source clock frequencies as OPPs on the perf domain
device.

geni_se_domain_attach() now populates se->clk_perf_tbl from this OPP
table at attach time, mirroring clk_perf_tbl on the Linux-clock-managed
path. This lets get_spi_clk_cfg() call geni_se_clk_freq_match() to pick
the closest supported source clock frequency and divider on SA8255P
exactly as it already does when a Linux clock is present, and fill in
the GSI CONFIG0 TRE accordingly.

Switch get_spi_clk_cfg() and spi_geni_runtime_resume() from calling
dev_pm_opp_set_rate() directly to the new geni_se_set_rate() helper, so
the matched frequency is applied to the correct device (the perf
domain device on the firmware managed path, or se->dev otherwise)
without the SPI driver needing to know which resources_init variant is
in use.

Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
 drivers/spi/spi-geni-qcom.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index 6566975eb24f..09e796d22ab1 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -15,7 +15,6 @@
 #include <linux/log2.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/pm_opp.h>
 #include <linux/pm_runtime.h>
 #include <linux/property.h>
 #include <linux/soc/qcom/geni-se.h>
@@ -82,7 +81,6 @@
 
 struct geni_spi_desc {
 	int (*resources_init)(struct geni_se *se);
-	int (*set_rate)(struct geni_se *se, unsigned long clk_freq);
 	int (*power_on)(struct geni_se *se);
 	int (*power_off)(struct geni_se *se);
 };
@@ -150,9 +148,9 @@ static int get_spi_clk_cfg(unsigned int speed_hz,
 
 	dev_dbg(mas->dev, "req %u=>%u sclk %lu, idx %d, div %d\n", speed_hz,
 				actual_hz, sclk_freq, *clk_idx, *clk_div);
-	ret = dev_pm_opp_set_rate(mas->dev, sclk_freq);
+	ret = geni_se_set_rate(&mas->se, sclk_freq);
 	if (ret)
-		dev_err(mas->dev, "dev_pm_opp_set_rate failed %d\n", ret);
+		dev_err(mas->dev, "geni_se_set_rate failed %d\n", ret);
 	else
 		mas->cur_sclk_hz = sclk_freq;
 
@@ -847,7 +845,7 @@ static int setup_se_xfer(struct spi_transfer *xfer,
 	}
 
 	/* Speed and bits per word can be overridden per transfer */
-	ret = mas->dev_data->set_rate(&mas->se, xfer->speed_hz);
+	ret = geni_spi_set_clock_and_bw(&mas->se, xfer->speed_hz);
 	if (ret)
 		return ret;
 
@@ -1162,6 +1160,8 @@ static int __maybe_unused spi_geni_runtime_suspend(struct device *dev)
 	struct spi_controller *spi = dev_get_drvdata(dev);
 	struct spi_geni_master *mas = spi_controller_get_devdata(spi);
 
+	geni_se_set_rate(&mas->se, 0);
+
 	return mas->dev_data->power_off ?
 	       mas->dev_data->power_off(&mas->se) : 0;
 }
@@ -1178,10 +1178,7 @@ static int __maybe_unused spi_geni_runtime_resume(struct device *dev)
 			return ret;
 	}
 
-	if (mas->se.has_opp)
-		return dev_pm_opp_set_rate(mas->dev, mas->cur_sclk_hz);
-
-	return 0;
+	return geni_se_set_rate(&mas->se, mas->cur_sclk_hz);
 }
 
 static int __maybe_unused spi_geni_suspend(struct device *dev)
@@ -1224,14 +1221,12 @@ static const struct dev_pm_ops spi_geni_pm_ops = {
 
 static const struct geni_spi_desc geni_spi = {
 	.resources_init = geni_se_resources_init,
-	.set_rate = geni_spi_set_clock_and_bw,
 	.power_on = geni_se_resources_activate,
 	.power_off = geni_se_resources_deactivate,
 };
 
 static const struct geni_spi_desc sa8255p_geni_spi = {
 	.resources_init = geni_se_domain_attach,
-	.set_rate = geni_se_set_perf_opp,
 };
 
 static const struct of_device_id spi_geni_dt_match[] = {

-- 
2.34.1



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

* [PATCH 6/7] i2c: qcom-geni: Use common GENI resource initialization helper
  2026-08-04 19:57 [PATCH 0/7] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
                   ` (4 preceding siblings ...)
  2026-08-04 19:57 ` [PATCH 5/7] spi: qcom-geni: Use geni_se_set_rate() for setting source clock frequency Praveen Talari
@ 2026-08-04 19:57 ` Praveen Talari
  2026-08-24 13:12   ` Mukesh Savaliya
  2026-08-04 19:57 ` [PATCH 7/7] i2c: qcom-geni: Use geni_se_set_rate() for setting source clock frequency Praveen Talari
  6 siblings, 1 reply; 34+ messages in thread
From: Praveen Talari @ 2026-08-04 19:57 UTC (permalink / raw)
  To: konrad.dybcio, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c, Praveen Talari

The driver implements a custom resources_init() callback for clock
frequency validation and bandwidth vote programming. Neither operation is
required for resource initialization itself.

Move clock frequency validation to probe and program the ICC bandwidth vote
from qcom_geni_i2c_conf(), where the bus frequency is configured. This
allows the driver to use geni_se_resources_init() directly and removes the
I2C-specific resource initialization wrapper.

Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
 drivers/i2c/busses/i2c-qcom-geni.c | 32 +++++++++++---------------------
 1 file changed, 11 insertions(+), 21 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index 658636c1ee0e..a23554d101fd 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -228,10 +228,13 @@ static int qcom_geni_i2c_conf(struct geni_se *se, unsigned long freq)
 	val |= itr->t_low_cnt << LOW_COUNTER_SHFT;
 	val |= itr->t_cycle_cnt;
 	writel_relaxed(val, gi2c->se.base + SE_I2C_SCL_COUNTERS);
+
 	trace_geni_i2c_bus_setup(gi2c->se.dev, gi2c->clk_freq_out,
 				 itr->clk_div, itr->t_high_cnt,
 				 itr->t_low_cnt, itr->t_cycle_cnt);
-	return 0;
+
+	return geni_icc_set_bw_ab(&gi2c->se, GENI_DEFAULT_BW, GENI_DEFAULT_BW,
+				  Bps_to_icc(gi2c->clk_freq_out));
 }
 
 static void geni_i2c_err_misc(struct geni_i2c_dev *gi2c)
@@ -1100,24 +1103,6 @@ static int geni_i2c_init(struct geni_i2c_dev *gi2c)
 	return ret;
 }
 
-static int geni_i2c_resources_init(struct geni_se *se)
-{
-	struct geni_i2c_dev *gi2c = dev_get_drvdata(se->dev);
-	int ret;
-
-	ret = geni_se_resources_init(&gi2c->se);
-	if (ret)
-		return ret;
-
-	ret = geni_i2c_clk_map_idx(gi2c);
-	if (ret)
-		return dev_err_probe(gi2c->se.dev, ret, "Invalid clk frequency %d Hz\n",
-				     gi2c->clk_freq_out);
-
-	return geni_icc_set_bw_ab(&gi2c->se, GENI_DEFAULT_BW, GENI_DEFAULT_BW,
-				  Bps_to_icc(gi2c->clk_freq_out));
-}
-
 static int geni_i2c_probe(struct platform_device *pdev)
 {
 	struct geni_i2c_dev *gi2c;
@@ -1188,6 +1173,11 @@ static int geni_i2c_probe(struct platform_device *pdev)
 	if (ret < 0)
 		return ret;
 
+	ret = geni_i2c_clk_map_idx(gi2c);
+	if (ret)
+		return dev_err_probe(gi2c->se.dev, ret, "Invalid clk frequency %d Hz\n",
+				     gi2c->clk_freq_out);
+
 	ret = i2c_add_adapter(&gi2c->adap);
 	if (ret)
 		return dev_err_probe(dev, ret, "Error adding i2c adapter\n");
@@ -1281,7 +1271,7 @@ static const struct dev_pm_ops geni_i2c_pm_ops = {
 };
 
 static const struct geni_i2c_desc geni_i2c = {
-	.resources_init = geni_i2c_resources_init,
+	.resources_init = geni_se_resources_init,
 	.set_rate = qcom_geni_i2c_conf,
 	.power_on = geni_se_resources_activate,
 	.power_off = geni_se_resources_deactivate,
@@ -1290,7 +1280,7 @@ static const struct geni_i2c_desc geni_i2c = {
 static const struct geni_i2c_desc i2c_master_hub = {
 	.no_dma_support = true,
 	.tx_fifo_depth = 16,
-	.resources_init = geni_i2c_resources_init,
+	.resources_init = geni_se_resources_init,
 	.set_rate = qcom_geni_i2c_conf,
 	.power_on = geni_se_resources_activate,
 	.power_off = geni_se_resources_deactivate,

-- 
2.34.1



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

* [PATCH 7/7] i2c: qcom-geni: Use geni_se_set_rate() for setting source clock frequency
  2026-08-04 19:57 [PATCH 0/7] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
                   ` (5 preceding siblings ...)
  2026-08-04 19:57 ` [PATCH 6/7] i2c: qcom-geni: Use common GENI resource initialization helper Praveen Talari
@ 2026-08-04 19:57 ` Praveen Talari
  2026-08-24 13:41   ` Mukesh Savaliya
  2026-08-24 15:06   ` Konrad Dybcio
  6 siblings, 2 replies; 34+ messages in thread
From: Praveen Talari @ 2026-08-04 19:57 UTC (permalink / raw)
  To: konrad.dybcio, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c, Praveen Talari

On the SA8255P platform there is no Linux clock handler for the SE source
clock; resources are instead managed by firmware via a genpd performance
domain. The I2C driver therefore relies on geni_se_set_rate() to apply the
fixed 19.2 MHz source clock frequency expected by the SCL divider and
counter values programmed by qcom_geni_i2c_conf().

Call geni_se_set_rate() directly from qcom_geni_i2c_conf() so the
configured frequency is applied to the correct device (the perf domain
device on the firmware-managed path, or se->dev otherwise) without the I2C
driver needing to know which resources_init() variant is in use.

Drop the now-unused set_rate field from struct geni_i2c_desc, the
geni_se_set_perf_opp() usage on the SA8255P variant, and the unused freq
parameter from qcom_geni_i2c_conf().

Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
 drivers/i2c/busses/i2c-qcom-geni.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index a23554d101fd..4561e2d235d5 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -213,11 +213,11 @@ static int geni_i2c_clk_map_idx(struct geni_i2c_dev *gi2c)
 	return -EINVAL;
 }
 
-static int qcom_geni_i2c_conf(struct geni_se *se, unsigned long freq)
+static int qcom_geni_i2c_conf(struct geni_se *se)
 {
 	struct geni_i2c_dev *gi2c = dev_get_drvdata(se->dev);
 	const struct geni_i2c_clk_fld *itr = gi2c->clk_fld;
-	u32 val;
+	u32 val, ret;
 
 	writel_relaxed(0, gi2c->se.base + SE_GENI_CLK_SEL);
 
@@ -233,6 +233,10 @@ static int qcom_geni_i2c_conf(struct geni_se *se, unsigned long freq)
 				 itr->clk_div, itr->t_high_cnt,
 				 itr->t_low_cnt, itr->t_cycle_cnt);
 
+	ret = geni_se_set_rate(&gi2c->se, 19200000);
+	if (ret)
+		return ret;
+
 	return geni_icc_set_bw_ab(&gi2c->se, GENI_DEFAULT_BW, GENI_DEFAULT_BW,
 				  Bps_to_icc(gi2c->clk_freq_out));
 }
@@ -975,7 +979,7 @@ static int geni_i2c_xfer(struct i2c_adapter *adap,
 		return ret;
 	}
 
-	ret = gi2c->dev_data->set_rate(&gi2c->se, gi2c->clk_freq_out);
+	ret = qcom_geni_i2c_conf(&gi2c->se);
 	if (ret)
 		return ret;
 
@@ -1272,7 +1276,6 @@ static const struct dev_pm_ops geni_i2c_pm_ops = {
 
 static const struct geni_i2c_desc geni_i2c = {
 	.resources_init = geni_se_resources_init,
-	.set_rate = qcom_geni_i2c_conf,
 	.power_on = geni_se_resources_activate,
 	.power_off = geni_se_resources_deactivate,
 };
@@ -1281,14 +1284,12 @@ static const struct geni_i2c_desc i2c_master_hub = {
 	.no_dma_support = true,
 	.tx_fifo_depth = 16,
 	.resources_init = geni_se_resources_init,
-	.set_rate = qcom_geni_i2c_conf,
 	.power_on = geni_se_resources_activate,
 	.power_off = geni_se_resources_deactivate,
 };
 
 static const struct geni_i2c_desc sa8255p_geni_i2c = {
 	.resources_init = geni_se_domain_attach,
-	.set_rate = geni_se_set_perf_opp,
 };
 
 #ifdef CONFIG_ACPI

-- 
2.34.1



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

* Re: [PATCH 5/7] spi: qcom-geni: Use geni_se_set_rate() for setting source clock frequency
  2026-08-04 19:57 ` [PATCH 5/7] spi: qcom-geni: Use geni_se_set_rate() for setting source clock frequency Praveen Talari
@ 2026-08-04 20:03   ` Mark Brown
  2026-08-24 11:52   ` Mukesh Savaliya
  1 sibling, 0 replies; 34+ messages in thread
From: Mark Brown @ 2026-08-04 20:03 UTC (permalink / raw)
  To: Praveen Talari
  Cc: konrad.dybcio, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Viken Dadhaniya, Andi Shyti, mukesh.savaliya, chandana.chiluveru,
	arm-scmi, linux-arm-kernel, linux-pm, linux-kernel, linux-arm-msm,
	linux-serial, linux-spi, linux-i2c

[-- Attachment #1: Type: text/plain, Size: 468 bytes --]

On Wed, Aug 05, 2026 at 01:27:43AM +0530, Praveen Talari wrote:
> On the SA8255P platform there is no Linux clock handler for the SE
> source clock, so the driver has no way to look up the source clock
> index and divider needed to fill the GSI CONFIG0 TRE for a requested
> transfer frequency. To work around this, firmware instead exposes the
> SE HW supported source clock frequencies as OPPs on the perf domain
> device.

Acked-by: Mark Brown <broonie@kernel.org>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 1/7] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0
  2026-08-04 19:57 ` [PATCH 1/7] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0 Praveen Talari
@ 2026-08-10 14:19   ` Ulf Hansson
  2026-08-12  6:58   ` Mukesh Savaliya
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 34+ messages in thread
From: Ulf Hansson @ 2026-08-10 14:19 UTC (permalink / raw)
  To: Praveen Talari
  Cc: konrad.dybcio, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti, mukesh.savaliya,
	chandana.chiluveru, arm-scmi, linux-arm-kernel, linux-pm,
	linux-kernel, linux-arm-msm, linux-serial, linux-spi, linux-i2c

On Tue, Aug 4, 2026 at 9:58 PM Praveen Talari
<praveen.talari@oss.qualcomm.com> wrote:
>
> Currently, scmi_pd_set_perf_state() treats a performance state of 0 as
> invalid and returns -EINVAL. As a result, devices attached to SCMI
> performance domains can report failures when relinquishing their
> performance vote.

Yes, this is indeed a problem. I recall that I hesitated when deciding
what was best here, returning an error code or 0.

The reasoning I had for returning -EINVAL, was that I didn't want
genpd to believe that it actually succeeded in setting the performance
state to 0, when in fact it didn't.

However, except for the problem below with the OPP library, it
actually also screws up the internal performance state aggregation in
genpd, potentially leading us to running at higher state than
necessary.

>
> The OPP framework use performance state 0 to indicate that no performance
> vote is required. For example, dev_pm_opp_set_rate(dev, 0) is commonly
> used (by firmware or linux)  when a device is runtime suspended.
>
> A zero performance state does not require any SCMI performance request
> to be sent. Treat it as a no-op and return success instead of reporting
> an error.
>
> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>

I added a fixes+stable tag and applied this for fixes, thanks!

Kind regards
Uffe



> ---
>  drivers/pmdomain/arm/scmi_perf_domain.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/pmdomain/arm/scmi_perf_domain.c b/drivers/pmdomain/arm/scmi_perf_domain.c
> index 3693423459c9..e390f902a444 100644
> --- a/drivers/pmdomain/arm/scmi_perf_domain.c
> +++ b/drivers/pmdomain/arm/scmi_perf_domain.c
> @@ -33,7 +33,7 @@ scmi_pd_set_perf_state(struct generic_pm_domain *genpd, unsigned int state)
>                 return 0;
>
>         if (!state)
> -               return -EINVAL;
> +               return 0;
>
>         ret = pd->perf_ops->level_set(pd->ph, pd->domain_id, state, false);
>         if (ret)
>
> --
> 2.34.1
>


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

* Re: [PATCH 1/7] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0
  2026-08-04 19:57 ` [PATCH 1/7] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0 Praveen Talari
  2026-08-10 14:19   ` Ulf Hansson
@ 2026-08-12  6:58   ` Mukesh Savaliya
  2026-08-12  7:24   ` Mukesh Savaliya
  2026-08-25  8:22   ` Abel Vesa
  3 siblings, 0 replies; 34+ messages in thread
From: Mukesh Savaliya @ 2026-08-12  6:58 UTC (permalink / raw)
  To: Praveen Talari, konrad.dybcio, Sudeep Holla, Cristian Marussi,
	Ulf Hansson, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
	Jiri Slaby, Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, arm-scmi, linux-arm-kernel, linux-pm,
	linux-kernel, linux-arm-msm, linux-serial, linux-spi, linux-i2c



On 8/5/2026 1:27 AM, Praveen Talari wrote:
> Currently, scmi_pd_set_perf_state() treats a performance state of 0 as
> invalid and returns -EINVAL. As a result, devices attached to SCMI
> performance domains can report failures when relinquishing their
> performance vote.
> 
> The OPP framework use performance state 0 to indicate that no performance
> vote is required. For example, dev_pm_opp_set_rate(dev, 0) is commonly
> used (by firmware or linux)  when a device is runtime suspended.
> 
> A zero performance state does not require any SCMI performance request
> to be sent. Treat it as a no-op and return success instead of reporting
> an error.
> 
> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
> ---

Acked-by : Mukesh Savaliya <mukesh.savaliya@oss.qualcomm.com>


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

* Re: [PATCH 1/7] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0
  2026-08-04 19:57 ` [PATCH 1/7] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0 Praveen Talari
  2026-08-10 14:19   ` Ulf Hansson
  2026-08-12  6:58   ` Mukesh Savaliya
@ 2026-08-12  7:24   ` Mukesh Savaliya
  2026-08-12  8:57     ` Ulf Hansson
  2026-08-25  8:22   ` Abel Vesa
  3 siblings, 1 reply; 34+ messages in thread
From: Mukesh Savaliya @ 2026-08-12  7:24 UTC (permalink / raw)
  To: Praveen Talari, konrad.dybcio, Sudeep Holla, Cristian Marussi,
	Ulf Hansson, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
	Jiri Slaby, Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, arm-scmi, linux-arm-kernel, linux-pm,
	linux-kernel, linux-arm-msm, linux-serial, linux-spi, linux-i2c



On 8/5/2026 1:27 AM, Praveen Talari wrote:
[...]

> ---
>   drivers/pmdomain/arm/scmi_perf_domain.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pmdomain/arm/scmi_perf_domain.c b/drivers/pmdomain/arm/scmi_perf_domain.c
> index 3693423459c9..e390f902a444 100644
> --- a/drivers/pmdomain/arm/scmi_perf_domain.c
> +++ b/drivers/pmdomain/arm/scmi_perf_domain.c
> @@ -33,7 +33,7 @@ scmi_pd_set_perf_state(struct generic_pm_domain *genpd, unsigned int state)
>   		return 0;
>   
>   	if (!state)
> -		return -EINVAL;
> +		return 0;

Won't this cause an issue to other drivers ? how are they going to take 
action based on changed return value ?

Remove Acked-by due to this till i give back.
>   
>   	ret = pd->perf_ops->level_set(pd->ph, pd->domain_id, state, false);
>   	if (ret)
> 



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

* Re: [PATCH 2/7] soc: qcom: geni-se: Populate clk_perf_tbl with SE source clock frequencies from perf OPP table
  2026-08-04 19:57 ` [PATCH 2/7] soc: qcom: geni-se: Populate clk_perf_tbl with SE source clock frequencies from perf OPP table Praveen Talari
@ 2026-08-12  7:36   ` Mukesh Savaliya
  2026-08-24 14:56   ` Konrad Dybcio
  1 sibling, 0 replies; 34+ messages in thread
From: Mukesh Savaliya @ 2026-08-12  7:36 UTC (permalink / raw)
  To: Praveen Talari, konrad.dybcio, Sudeep Holla, Cristian Marussi,
	Ulf Hansson, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
	Jiri Slaby, Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, arm-scmi, linux-arm-kernel, linux-pm,
	linux-kernel, linux-arm-msm, linux-serial, linux-spi, linux-i2c



On 8/5/2026 1:27 AM, Praveen Talari wrote:
> Currently, on the SA8255P platform, protocol drivers attached via
> geni_se_domain_attach() treat each OPP on the perf domain as directly
> corresponding to a protocol value such as a baudrate or requested
> frequency, and simply request that OPP via
> geni_se_set_perf_level()/geni_se_set_perf_opp(). This does not allow
> computing a source clock and divider combination for a protocol
> requested frequency, unlike the Linux clock managed path which derives
> this from se->clk_perf_tbl via geni_se_clk_freq_match(), and then
> applies the matched source clock frequency with dev_pm_opp_set_rate().
> 
> Change this by treating the OPP table exposed on the perf domain
> device as representing the actual SE HW supported source clock
> frequencies, the same role clk_perf_tbl plays for the Linux clock
> managed path. Populate se->clk_perf_tbl and se->num_clk_levels by
> iterating over this OPP table in geni_se_domain_attach(), so that
> protocol drivers on the firmware managed (SA8255P) path can also use
> geni_se_clk_freq_match() to pick the closest supported source clock
> frequency and calculate the required divider, and apply it with
> dev_pm_opp_set_rate() the same way as it is done for the Linux clock
> managed path, instead of relying on a direct frequency/baudrate-to-
> perf-level mapping.
> 
> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
> ---
Acked-by: Mukesh Savaliya <mukesh.savaliya@oss.qualcomm.com>


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

* Re: [PATCH 3/7] soc: qcom: geni-se: Add helper to set SE clock rate via OPP
  2026-08-04 19:57 ` [PATCH 3/7] soc: qcom: geni-se: Add helper to set SE clock rate via OPP Praveen Talari
@ 2026-08-12  8:55   ` Mukesh Savaliya
  2026-08-24 11:07   ` Mukesh Savaliya
  2026-08-24 14:58   ` Konrad Dybcio
  2 siblings, 0 replies; 34+ messages in thread
From: Mukesh Savaliya @ 2026-08-12  8:55 UTC (permalink / raw)
  To: Praveen Talari, konrad.dybcio, Sudeep Holla, Cristian Marussi,
	Ulf Hansson, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
	Jiri Slaby, Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, arm-scmi, linux-arm-kernel, linux-pm,
	linux-kernel, linux-arm-msm, linux-serial, linux-spi, linux-i2c



On 8/5/2026 1:27 AM, Praveen Talari wrote:
> GENI protocol drivers need a common way to scale the SE source clock
> through the OPP framework. However, the device that owns the OPP table
> differs depending on how the SE resources are managed. For Linux clock
> managed platforms, the OPP table is associated with the SE device,
> whereas on firmware-managed platforms it is associated with the
> performance power-domain device. This requires protocol drivers to be
> aware of the underlying resource management model when requesting
> frequency changes.
> 
> Introduce geni_se_set_rate(), a common helper that abstracts this
> difference and applies the requested frequency through the appropriate
> device. The helper automatically selects the performance-domain device
> when power domains are attached and falls back to the SE device
> otherwise.
> 
> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
> ---

Acked-by: Mukesh Savaliya <mukesh.savaliya@oss.qualcomm.com>


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

* Re: [PATCH 1/7] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0
  2026-08-12  7:24   ` Mukesh Savaliya
@ 2026-08-12  8:57     ` Ulf Hansson
  2026-08-12  9:13       ` Mukesh Savaliya
  0 siblings, 1 reply; 34+ messages in thread
From: Ulf Hansson @ 2026-08-12  8:57 UTC (permalink / raw)
  To: Mukesh Savaliya
  Cc: Praveen Talari, konrad.dybcio, Sudeep Holla, Cristian Marussi,
	Ulf Hansson, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
	Jiri Slaby, Mark Brown, Viken Dadhaniya, Andi Shyti,
	chandana.chiluveru, arm-scmi, linux-arm-kernel, linux-pm,
	linux-kernel, linux-arm-msm, linux-serial, linux-spi, linux-i2c

On Wed, Aug 12, 2026 at 9:24 AM Mukesh Savaliya
<mukesh.savaliya@oss.qualcomm.com> wrote:
>
>
>
> On 8/5/2026 1:27 AM, Praveen Talari wrote:
> [...]
>
> > ---
> >   drivers/pmdomain/arm/scmi_perf_domain.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/pmdomain/arm/scmi_perf_domain.c b/drivers/pmdomain/arm/scmi_perf_domain.c
> > index 3693423459c9..e390f902a444 100644
> > --- a/drivers/pmdomain/arm/scmi_perf_domain.c
> > +++ b/drivers/pmdomain/arm/scmi_perf_domain.c
> > @@ -33,7 +33,7 @@ scmi_pd_set_perf_state(struct generic_pm_domain *genpd, unsigned int state)
> >               return 0;
> >
> >       if (!state)
> > -             return -EINVAL;
> > +             return 0;
>
> Won't this cause an issue to other drivers ? how are they going to take
> action based on changed return value ?

I think it's rather the opposite. With the current returned value
(-EINVAL) the driver doesn't really know what to do. It tried to drop
its vote, but that failed - so what can it do?

Moreover, from genpd point of view, this fixes a real bug as the
aggregation for the performance state becomes incorrect during runtime
suspend/resume.

>
> Remove Acked-by due to this till i give back.
> >
> >       ret = pd->perf_ops->level_set(pd->ph, pd->domain_id, state, false);
> >       if (ret)
> >
>

Kind regards
Uffe


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

* Re: [PATCH 1/7] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0
  2026-08-12  8:57     ` Ulf Hansson
@ 2026-08-12  9:13       ` Mukesh Savaliya
  0 siblings, 0 replies; 34+ messages in thread
From: Mukesh Savaliya @ 2026-08-12  9:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Praveen Talari, konrad.dybcio, Sudeep Holla, Cristian Marussi,
	Ulf Hansson, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
	Jiri Slaby, Mark Brown, Viken Dadhaniya, Andi Shyti,
	chandana.chiluveru, arm-scmi, linux-arm-kernel, linux-pm,
	linux-kernel, linux-arm-msm, linux-serial, linux-spi, linux-i2c



On 8/12/2026 2:27 PM, Ulf Hansson wrote:
> On Wed, Aug 12, 2026 at 9:24 AM Mukesh Savaliya

[...]
>>> --- a/drivers/pmdomain/arm/scmi_perf_domain.c
>>> +++ b/drivers/pmdomain/arm/scmi_perf_domain.c
>>> @@ -33,7 +33,7 @@ scmi_pd_set_perf_state(struct generic_pm_domain *genpd, unsigned int state)
>>>                return 0;
>>>
>>>        if (!state)
>>> -             return -EINVAL;
>>> +             return 0;
>>
>> Won't this cause an issue to other drivers ? how are they going to take
>> action based on changed return value ?
> 
> I think it's rather the opposite. With the current returned value
> (-EINVAL) the driver doesn't really know what to do. It tried to drop
> its vote, but that failed - so what can it do?
> 
> Moreover, from genpd point of view, this fixes a real bug as the
> aggregation for the performance state becomes incorrect during runtime
> suspend/resume.
> 
Got it, thanks Ulf for your explanation and also read your previous 
comments.
>>
>> Remove Acked-by due to this till i give back.

Reviewed-by: Mukesh Savaliya <mukesh.savaliya@oss.qualcomm.com>



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

* Re: [PATCH 3/7] soc: qcom: geni-se: Add helper to set SE clock rate via OPP
  2026-08-04 19:57 ` [PATCH 3/7] soc: qcom: geni-se: Add helper to set SE clock rate via OPP Praveen Talari
  2026-08-12  8:55   ` Mukesh Savaliya
@ 2026-08-24 11:07   ` Mukesh Savaliya
  2026-08-24 14:58   ` Konrad Dybcio
  2 siblings, 0 replies; 34+ messages in thread
From: Mukesh Savaliya @ 2026-08-24 11:07 UTC (permalink / raw)
  To: Praveen Talari, konrad.dybcio, Sudeep Holla, Cristian Marussi,
	Ulf Hansson, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
	Jiri Slaby, Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, arm-scmi, linux-arm-kernel, linux-pm,
	linux-kernel, linux-arm-msm, linux-serial, linux-spi, linux-i2c



On 8/5/2026 1:27 AM, Praveen Talari wrote:
> GENI protocol drivers need a common way to scale the SE source clock
> through the OPP framework. However, the device that owns the OPP table
> differs depending on how the SE resources are managed. For Linux clock
> managed platforms, the OPP table is associated with the SE device,
> whereas on firmware-managed platforms it is associated with the
> performance power-domain device. This requires protocol drivers to be
> aware of the underlying resource management model when requesting
> frequency changes.
> 
> Introduce geni_se_set_rate(), a common helper that abstracts this
> difference and applies the requested frequency through the appropriate
> device. The helper automatically selects the performance-domain device
> when power domains are attached and falls back to the SE device
> otherwise.
> 
> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
> ---
Acked-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>


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

* Re: [PATCH 4/7] serial: qcom-geni: Use geni_se_set_rate() for source clock configuration
  2026-08-04 19:57 ` [PATCH 4/7] serial: qcom-geni: Use geni_se_set_rate() for source clock configuration Praveen Talari
@ 2026-08-24 11:39   ` Mukesh Savaliya
  2026-08-24 11:40   ` Mukesh Savaliya
  2026-08-24 15:05   ` Konrad Dybcio
  2 siblings, 0 replies; 34+ messages in thread
From: Mukesh Savaliya @ 2026-08-24 11:39 UTC (permalink / raw)
  To: Praveen Talari, konrad.dybcio, Sudeep Holla, Cristian Marussi,
	Ulf Hansson, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
	Jiri Slaby, Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, arm-scmi, linux-arm-kernel, linux-pm,
	linux-kernel, linux-arm-msm, linux-serial, linux-spi, linux-i2c




On 8/5/2026 1:27 AM, Praveen Talari wrote:


> @@ -1474,7 +1473,10 @@ static int geni_serial_set_rate(struct geni_se *se, unsigned long baud)
>   
>   	uport->uartclk = clk_rate;
>   	port->clk_rate = clk_rate;
> -	dev_pm_opp_set_rate(uport->dev, clk_rate);
> +	ret = geni_se_set_rate(&port->se, clk_rate);
> +	if (ret)
Can you add trace log with an error for geni serial driver ?> +		return ret;
> +
>   	ser_clk_cfg = SER_CLK_EN;
>   	ser_clk_cfg |= clk_div << CLK_DIV_SHFT;
>   
> @@ -1513,7 +1515,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,

[...]



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

* Re: [PATCH 4/7] serial: qcom-geni: Use geni_se_set_rate() for source clock configuration
  2026-08-04 19:57 ` [PATCH 4/7] serial: qcom-geni: Use geni_se_set_rate() for source clock configuration Praveen Talari
  2026-08-24 11:39   ` Mukesh Savaliya
@ 2026-08-24 11:40   ` Mukesh Savaliya
  2026-08-24 15:05   ` Konrad Dybcio
  2 siblings, 0 replies; 34+ messages in thread
From: Mukesh Savaliya @ 2026-08-24 11:40 UTC (permalink / raw)
  To: Praveen Talari, konrad.dybcio, Sudeep Holla, Cristian Marussi,
	Ulf Hansson, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
	Jiri Slaby, Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, arm-scmi, linux-arm-kernel, linux-pm,
	linux-kernel, linux-arm-msm, linux-serial, linux-spi, linux-i2c


On 8/5/2026 1:27 AM, Praveen Talari wrote:
> The driver calls dev_pm_opp_set_rate() directly on uport->dev to apply
> the computed source clock frequency, and dispatches baud rate handling
> through a per-variant dev_data->set_rate() callback that either
> recalculates the clock divider (Linux clock managed path) or selects
> a performance level via geni_se_set_perf_level() (SA8255P firmware
> managed path).
> 
> Now that geni_se_domain_attach() populates se->clk_perf_tbl from the
> perf domain's OPP table, geni_se_clk_freq_match() can resolve a source
> clock frequency and divider on the SA8255P path the same way it
> already does for the Linux clock managed path. This removes the need
> for a separate perf-level based set_rate implementation, so
> geni_serial_set_rate() can be called unconditionally and
> dev_data->set_rate can be dropped.
> 
> Switch to calling geni_serial_set_rate() directly from
> qcom_geni_serial_set_termios(), and use geni_se_set_rate() in place of
> dev_pm_opp_set_rate() so the frequency is applied to the correct
> device (the perf domain device on the firmware managed path, or
> uport->dev otherwise) without the driver needing to know which
> resources_init variant is in use. Remove the now-unused set_rate field
> from struct qcom_geni_device_data and its per-variant initializers.
> 

This commit message seems quite long and repeats the rationale few times:
1. removes need for perf-level based set_rate
2. call geni_serial_set_rate unconditionally
3. use geni_se_set_rate instead of dev_pm_opp_set_rate

Review, if below makes sense, tried to shorten it.

geni_se_set_rate() now abstracts source clock programming for both
clock-managed and SCMI/perf-domain managed GENI instances.

Use geni_serial_set_rate() unconditionally from
qcom_geni_serial_set_termios() and remove the per-variant set_rate()
callback. This allows the UART driver to configure source clocks
without needing to know whether resources are managed through Linux
clocks or the SA8255P firmware-controlled performance domain.


> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
> ---


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

* Re: [PATCH 5/7] spi: qcom-geni: Use geni_se_set_rate() for setting source clock frequency
  2026-08-04 19:57 ` [PATCH 5/7] spi: qcom-geni: Use geni_se_set_rate() for setting source clock frequency Praveen Talari
  2026-08-04 20:03   ` Mark Brown
@ 2026-08-24 11:52   ` Mukesh Savaliya
  1 sibling, 0 replies; 34+ messages in thread
From: Mukesh Savaliya @ 2026-08-24 11:52 UTC (permalink / raw)
  To: Praveen Talari, konrad.dybcio, Sudeep Holla, Cristian Marussi,
	Ulf Hansson, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
	Jiri Slaby, Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, arm-scmi, linux-arm-kernel, linux-pm,
	linux-kernel, linux-arm-msm, linux-serial, linux-spi, linux-i2c



On 8/5/2026 1:27 AM, Praveen Talari wrote:
> On the SA8255P platform there is no Linux clock handler for the SE
> source clock, so the driver has no way to look up the source clock
> index and divider needed to fill the GSI CONFIG0 TRE for a requested
> transfer frequency. To work around this, firmware instead exposes the
> SE HW supported source clock frequencies as OPPs on the perf domain
> device.
> 
> geni_se_domain_attach() now populates se->clk_perf_tbl from this OPP
> table at attach time, mirroring clk_perf_tbl on the Linux-clock-managed
> path. This lets get_spi_clk_cfg() call geni_se_clk_freq_match() to pick
> the closest supported source clock frequency and divider on SA8255P
> exactly as it already does when a Linux clock is present, and fill in
> the GSI CONFIG0 TRE accordingly.
> 
> Switch get_spi_clk_cfg() and spi_geni_runtime_resume() from calling
> dev_pm_opp_set_rate() directly to the new geni_se_set_rate() helper, so
> the matched frequency is applied to the correct device (the perf
> domain device on the firmware managed path, or se->dev otherwise)
> without the SPI driver needing to know which resources_init variant is
> in use.
> 

let me suggest little compressed commit message removing some duplication.

geni_se_domain_attach() now populates clk_perf_tbl from
the performance-domain OPP table, allowing firmware-managed
platforms to use geni_se_clk_freq_match().

Use geni_se_set_rate() instead of dev_pm_opp_set_rate()
so clock programming is handled centrally by the GENI core,
independent of the underlying clock-control mechanism.

> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
> ---
>   drivers/spi/spi-geni-qcom.c | 17 ++++++-----------
>   1 file changed, 6 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c

[...]

> @@ -150,9 +148,9 @@ static int get_spi_clk_cfg(unsigned int speed_hz,
>   
>   	dev_dbg(mas->dev, "req %u=>%u sclk %lu, idx %d, div %d\n", speed_hz,
>   				actual_hz, sclk_freq, *clk_idx, *clk_div);
> -	ret = dev_pm_opp_set_rate(mas->dev, sclk_freq);
> +	ret = geni_se_set_rate(&mas->se, sclk_freq);
>   	if (ret)
> -		dev_err(mas->dev, "dev_pm_opp_set_rate failed %d\n", ret);
> +		dev_err(mas->dev, "geni_se_set_rate failed %d\n", ret);
little verbose - "Failed to set source clock rate %d">   	else
>   		mas->cur_sclk_hz = sclk_freq;
>   
> @@ -847,7 +845,7 @@ static int setup_se_xfer(struct spi_transfer *xfer,
>   	}

[...]



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

* Re: [PATCH 6/7] i2c: qcom-geni: Use common GENI resource initialization helper
  2026-08-04 19:57 ` [PATCH 6/7] i2c: qcom-geni: Use common GENI resource initialization helper Praveen Talari
@ 2026-08-24 13:12   ` Mukesh Savaliya
  2026-08-25 13:34     ` Praveen Talari
  0 siblings, 1 reply; 34+ messages in thread
From: Mukesh Savaliya @ 2026-08-24 13:12 UTC (permalink / raw)
  To: Praveen Talari, konrad.dybcio, Sudeep Holla, Cristian Marussi,
	Ulf Hansson, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
	Jiri Slaby, Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, arm-scmi, linux-arm-kernel, linux-pm,
	linux-kernel, linux-arm-msm, linux-serial, linux-spi, linux-i2c



On 8/5/2026 1:27 AM, Praveen Talari wrote:

[...]

> @@ -228,10 +228,13 @@ static int qcom_geni_i2c_conf(struct geni_se *se, unsigned long freq)
>   	val |= itr->t_low_cnt << LOW_COUNTER_SHFT;
>   	val |= itr->t_cycle_cnt;
>   	writel_relaxed(val, gi2c->se.base + SE_I2C_SCL_COUNTERS);
> +
>   	trace_geni_i2c_bus_setup(gi2c->se.dev, gi2c->clk_freq_out,
>   				 itr->clk_div, itr->t_high_cnt,
>   				 itr->t_low_cnt, itr->t_cycle_cnt);
> -	return 0;
> +

This looks wrong to me.
First accessed registers and then we are setting ICC vote ? we should 
enable resources first.

> +	return geni_icc_set_bw_ab(&gi2c->se, GENI_DEFAULT_BW, GENI_DEFAULT_BW,
> +				  Bps_to_icc(gi2c->clk_freq_out));
>   }
>   
>   static void geni_i2c_err_misc(struct geni_i2c_dev *gi2c)
> @@ -1100,24 +1103,6 @@ static int geni_i2c_init(struct geni_i2c_dev *gi2c)
>   	return ret;
>   }
>   
> -static int geni_i2c_resources_init(struct geni_se *se)
> -{
> -	struct geni_i2c_dev *gi2c = dev_get_drvdata(se->dev);
> -	int ret;
> -
> -	ret = geni_se_resources_init(&gi2c->se);
> -	if (ret)
> -		return ret;
> -
> -	ret = geni_i2c_clk_map_idx(gi2c);
> -	if (ret)
> -		return dev_err_probe(gi2c->se.dev, ret, "Invalid clk frequency %d Hz\n",
> -				     gi2c->clk_freq_out);
> -
> -	return geni_icc_set_bw_ab(&gi2c->se, GENI_DEFAULT_BW, GENI_DEFAULT_BW,
> -				  Bps_to_icc(gi2c->clk_freq_out));
> -}
> -
>   static int geni_i2c_probe(struct platform_device *pdev)
>   {
>   	struct geni_i2c_dev *gi2c;
> @@ -1188,6 +1173,11 @@ static int geni_i2c_probe(struct platform_device *pdev)
>   	if (ret < 0)
>   		return ret;
>   
> +	ret = geni_i2c_clk_map_idx(gi2c);
> +	if (ret)
> +		return dev_err_probe(gi2c->se.dev, ret, "Invalid clk frequency %d Hz\n",
> +				     gi2c->clk_freq_out);
> +

why not move to geni_i2c_init() ?

Check recent patch @ i2c: qcom-geni: add I2C frequency table for 32 MHz 
firmware-based SEs.

Let's agree to move there, to avoid issue.

>   	ret = i2c_add_adapter(&gi2c->adap);
>   	if (ret)
>   		return dev_err_probe(dev, ret, "Error adding i2c adapter\n");
> @@ -1281,7 +1271,7 @@ static const struct dev_pm_ops geni_i2c_pm_ops = {
>   };
>   
>   static const struct geni_i2c_desc geni_i2c = {
> -	.resources_init = geni_i2c_resources_init,
> +	.resources_init = geni_se_resources_init,

why to add common driver function to i2c ? and also spi, uart ?
Can we not call that function from within i2c specific hookup function ? 
i think design wise should keep i2c as local function.

Also driver specific anything can be managed in local function.

>   	.set_rate = qcom_geni_i2c_conf,
>   	.power_on = geni_se_resources_activate,
>   	.power_off = geni_se_resources_deactivate,
> @@ -1290,7 +1280,7 @@ static const struct geni_i2c_desc geni_i2c = {
>   static const struct geni_i2c_desc i2c_master_hub = {
>   	.no_dma_support = true,
>   	.tx_fifo_depth = 16,
> -	.resources_init = geni_i2c_resources_init,
> +	.resources_init = geni_se_resources_init,
>   	.set_rate = qcom_geni_i2c_conf,
>   	.power_on = geni_se_resources_activate,
>   	.power_off = geni_se_resources_deactivate,
> 



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

* Re: [PATCH 7/7] i2c: qcom-geni: Use geni_se_set_rate() for setting source clock frequency
  2026-08-04 19:57 ` [PATCH 7/7] i2c: qcom-geni: Use geni_se_set_rate() for setting source clock frequency Praveen Talari
@ 2026-08-24 13:41   ` Mukesh Savaliya
  2026-08-25 18:03     ` Praveen Talari
  2026-08-24 15:06   ` Konrad Dybcio
  1 sibling, 1 reply; 34+ messages in thread
From: Mukesh Savaliya @ 2026-08-24 13:41 UTC (permalink / raw)
  To: Praveen Talari, konrad.dybcio, Sudeep Holla, Cristian Marussi,
	Ulf Hansson, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
	Jiri Slaby, Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, arm-scmi, linux-arm-kernel, linux-pm,
	linux-kernel, linux-arm-msm, linux-serial, linux-spi, linux-i2c



On 8/5/2026 1:27 AM, Praveen Talari wrote:
> On the SA8255P platform there is no Linux clock handler for the SE source
> clock; resources are instead managed by firmware via a genpd performance
> domain. The I2C driver therefore relies on geni_se_set_rate() to apply the
> fixed 19.2 MHz source clock frequency expected by the SCL divider and

somewhere it's 32 MHz also and this may change too ?

> counter values programmed by qcom_geni_i2c_conf().
> 
> Call geni_se_set_rate() directly from qcom_geni_i2c_conf() so the
> configured frequency is applied to the correct device (the perf domain
> device on the firmware-managed path, or se->dev otherwise) without the I2C
> driver needing to know which resources_init() variant is in use.
> 
> Drop the now-unused set_rate field from struct geni_i2c_desc, the
> geni_se_set_perf_opp() usage on the SA8255P variant, and the unused freq
> parameter from qcom_geni_i2c_conf().
> 
> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
> ---
>   drivers/i2c/busses/i2c-qcom-geni.c | 13 +++++++------
>   1 file changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
> index a23554d101fd..4561e2d235d5 100644
> --- a/drivers/i2c/busses/i2c-qcom-geni.c
> +++ b/drivers/i2c/busses/i2c-qcom-geni.c
> @@ -213,11 +213,11 @@ static int geni_i2c_clk_map_idx(struct geni_i2c_dev *gi2c)
>   	return -EINVAL;
>   }
>   
> -static int qcom_geni_i2c_conf(struct geni_se *se, unsigned long freq)
> +static int qcom_geni_i2c_conf(struct geni_se *se)
>   {
>   	struct geni_i2c_dev *gi2c = dev_get_drvdata(se->dev);
>   	const struct geni_i2c_clk_fld *itr = gi2c->clk_fld;
> -	u32 val;
> +	u32 val, ret;
>   
>   	writel_relaxed(0, gi2c->se.base + SE_GENI_CLK_SEL);
>   
> @@ -233,6 +233,10 @@ static int qcom_geni_i2c_conf(struct geni_se *se, unsigned long freq)
>   				 itr->clk_div, itr->t_high_cnt,
>   				 itr->t_low_cnt, itr->t_cycle_cnt);
>   
> +	ret = geni_se_set_rate(&gi2c->se, 19200000);

hard code ?
May work currently, but if higher frequency support added, source may 
change.

Also you have added in commit message, but add a comment also here.

> +	if (ret)
> +		return ret;
> +
>   	return geni_icc_set_bw_ab(&gi2c->se, GENI_DEFAULT_BW, GENI_DEFAULT_BW,
>   				  Bps_to_icc(gi2c->clk_freq_out));
>   }

[...]



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

* Re: [PATCH 2/7] soc: qcom: geni-se: Populate clk_perf_tbl with SE source clock frequencies from perf OPP table
  2026-08-04 19:57 ` [PATCH 2/7] soc: qcom: geni-se: Populate clk_perf_tbl with SE source clock frequencies from perf OPP table Praveen Talari
  2026-08-12  7:36   ` Mukesh Savaliya
@ 2026-08-24 14:56   ` Konrad Dybcio
  2026-08-24 16:55     ` Praveen Talari
  1 sibling, 1 reply; 34+ messages in thread
From: Konrad Dybcio @ 2026-08-24 14:56 UTC (permalink / raw)
  To: Praveen Talari, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c

On 8/4/26 9:57 PM, Praveen Talari wrote:
> Currently, on the SA8255P platform, protocol drivers attached via
> geni_se_domain_attach() treat each OPP on the perf domain as directly
> corresponding to a protocol value such as a baudrate or requested
> frequency, and simply request that OPP via

[...]

> @@ -1175,6 +1181,29 @@ int geni_se_domain_attach(struct geni_se *se)
>  	else if (ret < 0)
>  		return ret;
>  
> +	perf_dev = se->pd_list->pd_devs[DOMAIN_IDX_PERF];
> +
> +	num_opps = dev_pm_opp_get_opp_count(perf_dev);
> +	if (num_opps <= 0)
> +		return num_opps < 0 ? num_opps : -ENODEV;

if (num_opps < 0)
	return num_opps;
if (num_opps == 0)
	return -ENODEV;

> +
> +	se->clk_perf_tbl = devm_kcalloc(se->dev, num_opps,
> +					sizeof(*se->clk_perf_tbl),
> +					GFP_KERNEL);
> +	if (!se->clk_perf_tbl)
> +		return -ENOMEM;
> +
> +	for (i = 0, level = 0; i < num_opps; i++, level++) {

One iterator is sufficient here

Konrad


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

* Re: [PATCH 3/7] soc: qcom: geni-se: Add helper to set SE clock rate via OPP
  2026-08-04 19:57 ` [PATCH 3/7] soc: qcom: geni-se: Add helper to set SE clock rate via OPP Praveen Talari
  2026-08-12  8:55   ` Mukesh Savaliya
  2026-08-24 11:07   ` Mukesh Savaliya
@ 2026-08-24 14:58   ` Konrad Dybcio
  2026-08-24 17:00     ` Praveen Talari
  2 siblings, 1 reply; 34+ messages in thread
From: Konrad Dybcio @ 2026-08-24 14:58 UTC (permalink / raw)
  To: Praveen Talari, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c

On 8/4/26 9:57 PM, Praveen Talari wrote:
> GENI protocol drivers need a common way to scale the SE source clock
> through the OPP framework. However, the device that owns the OPP table
> differs depending on how the SE resources are managed. For Linux clock
> managed platforms, the OPP table is associated with the SE device,
> whereas on firmware-managed platforms it is associated with the
> performance power-domain device. This requires protocol drivers to be
> aware of the underlying resource management model when requesting
> frequency changes.

[...]

> +/**
> + * geni_se_set_rate() - Set the SE source clock rate via the OPP framework.
> + * @se: Pointer to the struct geni_se instance.
> + * @freq: The source clock frequency to set.
> + *
> + * Applies the given frequency through dev_pm_opp_set_rate(), targeting the
> + * perf domain device when the SE has power domains attached (firmware
> + * managed path), or se->dev otherwise (Linux clock managed path).
> + *
> + * Return: 0 on success, or a negative error code on failure.
> + */
> +int geni_se_set_rate(struct geni_se *se, unsigned long freq)
> +{
> +	struct device *perf_dev = se->dev;
> +
> +	if (se->pd_list && se->pd_list->pd_devs[DOMAIN_IDX_PERF])

The latter will always be true if the former is

Konrad

> +		perf_dev = se->pd_list->pd_devs[DOMAIN_IDX_PERF];
> +
> +	return se->has_opp ? dev_pm_opp_set_rate(perf_dev, freq) : 0;


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

* Re: [PATCH 4/7] serial: qcom-geni: Use geni_se_set_rate() for source clock configuration
  2026-08-04 19:57 ` [PATCH 4/7] serial: qcom-geni: Use geni_se_set_rate() for source clock configuration Praveen Talari
  2026-08-24 11:39   ` Mukesh Savaliya
  2026-08-24 11:40   ` Mukesh Savaliya
@ 2026-08-24 15:05   ` Konrad Dybcio
  2026-08-25  4:00     ` Praveen Talari
  2 siblings, 1 reply; 34+ messages in thread
From: Konrad Dybcio @ 2026-08-24 15:05 UTC (permalink / raw)
  To: Praveen Talari, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c

On 8/4/26 9:57 PM, Praveen Talari wrote:
> The driver calls dev_pm_opp_set_rate() directly on uport->dev to apply
> the computed source clock frequency, and dispatches baud rate handling
> through a per-variant dev_data->set_rate() callback that either
> recalculates the clock divider (Linux clock managed path) or selects
> a performance level via geni_se_set_perf_level() (SA8255P firmware
> managed path).

[...]

> +	geni_se_set_rate(&port->se, 0);

This ends up calling dev_pm_opp_set_rate(0) [i see this is an existing
bug in geni_se_resources_deactivate()], which removes the power vote,
but does nothing to the clock (neither set_rate nor disable_unprepare),
which will crash the platform

Both of these calls (new and existing) should be removed. Clocks will
be disabled by geni_se_clks_off() in geni_se_resources_deactivate().

Then, we should do dev_pm_set_opp(se->dev, NULL) *after* they are off
to remove any trailing OPP resources (i.e. icc votes defined in the OPP
table in our case)

Konrad


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

* Re: [PATCH 7/7] i2c: qcom-geni: Use geni_se_set_rate() for setting source clock frequency
  2026-08-04 19:57 ` [PATCH 7/7] i2c: qcom-geni: Use geni_se_set_rate() for setting source clock frequency Praveen Talari
  2026-08-24 13:41   ` Mukesh Savaliya
@ 2026-08-24 15:06   ` Konrad Dybcio
  2026-08-25  8:19     ` Praveen Talari
  1 sibling, 1 reply; 34+ messages in thread
From: Konrad Dybcio @ 2026-08-24 15:06 UTC (permalink / raw)
  To: Praveen Talari, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c

On 8/4/26 9:57 PM, Praveen Talari wrote:
> On the SA8255P platform there is no Linux clock handler for the SE source
> clock; resources are instead managed by firmware via a genpd performance
> domain. The I2C driver therefore relies on geni_se_set_rate() to apply the
> fixed 19.2 MHz source clock frequency expected by the SCL divider and
> counter values programmed by qcom_geni_i2c_conf().

[...]

> @@ -233,6 +233,10 @@ static int qcom_geni_i2c_conf(struct geni_se *se, unsigned long freq)
>  				 itr->clk_div, itr->t_high_cnt,
>  				 itr->t_low_cnt, itr->t_cycle_cnt);
>  
> +	ret = geni_se_set_rate(&gi2c->se, 19200000);
> +	if (ret)
> +		return ret;

This wasn't here before and the commit message only says something to the
amount of "it's necessary" - what's the difference?

Konrad


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

* Re: [PATCH 2/7] soc: qcom: geni-se: Populate clk_perf_tbl with SE source clock frequencies from perf OPP table
  2026-08-24 14:56   ` Konrad Dybcio
@ 2026-08-24 16:55     ` Praveen Talari
  0 siblings, 0 replies; 34+ messages in thread
From: Praveen Talari @ 2026-08-24 16:55 UTC (permalink / raw)
  To: Konrad Dybcio, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c

HI Konrad,

On 24-08-2026 20:26, Konrad Dybcio wrote:
> On 8/4/26 9:57 PM, Praveen Talari wrote:
>> Currently, on the SA8255P platform, protocol drivers attached via
>> geni_se_domain_attach() treat each OPP on the perf domain as directly
>> corresponding to a protocol value such as a baudrate or requested
>> frequency, and simply request that OPP via
> [...]
>
>> @@ -1175,6 +1181,29 @@ int geni_se_domain_attach(struct geni_se *se)
>>   	else if (ret < 0)
>>   		return ret;
>>   
>> +	perf_dev = se->pd_list->pd_devs[DOMAIN_IDX_PERF];
>> +
>> +	num_opps = dev_pm_opp_get_opp_count(perf_dev);
>> +	if (num_opps <= 0)
>> +		return num_opps < 0 ? num_opps : -ENODEV;
> if (num_opps < 0)
> 	return num_opps;
> if (num_opps == 0)
> 	return -ENODEV;
Sure, will update in next patch.
>
>> +
>> +	se->clk_perf_tbl = devm_kcalloc(se->dev, num_opps,
>> +					sizeof(*se->clk_perf_tbl),
>> +					GFP_KERNEL);
>> +	if (!se->clk_perf_tbl)
>> +		return -ENOMEM;
>> +
>> +	for (i = 0, level = 0; i < num_opps; i++, level++) {
> One iterator is sufficient here

Will review and update.


Thanks,

Praveen Talari

>
> Konrad


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

* Re: [PATCH 3/7] soc: qcom: geni-se: Add helper to set SE clock rate via OPP
  2026-08-24 14:58   ` Konrad Dybcio
@ 2026-08-24 17:00     ` Praveen Talari
  0 siblings, 0 replies; 34+ messages in thread
From: Praveen Talari @ 2026-08-24 17:00 UTC (permalink / raw)
  To: Konrad Dybcio, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c


On 24-08-2026 20:28, Konrad Dybcio wrote:
> On 8/4/26 9:57 PM, Praveen Talari wrote:
>> GENI protocol drivers need a common way to scale the SE source clock
>> through the OPP framework. However, the device that owns the OPP table
>> differs depending on how the SE resources are managed. For Linux clock
>> managed platforms, the OPP table is associated with the SE device,
>> whereas on firmware-managed platforms it is associated with the
>> performance power-domain device. This requires protocol drivers to be
>> aware of the underlying resource management model when requesting
>> frequency changes.
> [...]
>
>> +/**
>> + * geni_se_set_rate() - Set the SE source clock rate via the OPP framework.
>> + * @se: Pointer to the struct geni_se instance.
>> + * @freq: The source clock frequency to set.
>> + *
>> + * Applies the given frequency through dev_pm_opp_set_rate(), targeting the
>> + * perf domain device when the SE has power domains attached (firmware
>> + * managed path), or se->dev otherwise (Linux clock managed path).
>> + *
>> + * Return: 0 on success, or a negative error code on failure.
>> + */
>> +int geni_se_set_rate(struct geni_se *se, unsigned long freq)
>> +{
>> +	struct device *perf_dev = se->dev;
>> +
>> +	if (se->pd_list && se->pd_list->pd_devs[DOMAIN_IDX_PERF])
> The latter will always be true if the former is

Sure. I'll simplify the condition to just check se->pd_list.

Thanks,

Praveen Talari

>
> Konrad
>
>> +		perf_dev = se->pd_list->pd_devs[DOMAIN_IDX_PERF];
>> +
>> +	return se->has_opp ? dev_pm_opp_set_rate(perf_dev, freq) : 0;


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

* Re: [PATCH 4/7] serial: qcom-geni: Use geni_se_set_rate() for source clock configuration
  2026-08-24 15:05   ` Konrad Dybcio
@ 2026-08-25  4:00     ` Praveen Talari
  2026-08-25  8:28       ` Konrad Dybcio
  0 siblings, 1 reply; 34+ messages in thread
From: Praveen Talari @ 2026-08-25  4:00 UTC (permalink / raw)
  To: Konrad Dybcio, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c

HI Konrad,

On 24-08-2026 20:35, Konrad Dybcio wrote:
> On 8/4/26 9:57 PM, Praveen Talari wrote:
>> The driver calls dev_pm_opp_set_rate() directly on uport->dev to apply
>> the computed source clock frequency, and dispatches baud rate handling
>> through a per-variant dev_data->set_rate() callback that either
>> recalculates the clock divider (Linux clock managed path) or selects
>> a performance level via geni_se_set_perf_level() (SA8255P firmware
>> managed path).
> [...]
>
>> +	geni_se_set_rate(&port->se, 0);
> This ends up calling dev_pm_opp_set_rate(0) [i see this is an existing
> bug in geni_se_resources_deactivate()], which removes the power vote,
> but does nothing to the clock (neither set_rate nor disable_unprepare),
> which will crash the platform
>
> Both of these calls (new and existing) should be removed. Clocks will
> be disabled by geni_se_clks_off() in geni_se_resources_deactivate().
>
> Then, we should do dev_pm_set_opp(se->dev, NULL) *after* they are off
> to remove any trailing OPP resources (i.e. icc votes defined in the OPP
> table in our case)
So, if I understand correctly, the expected sequence is:

1. Disable the clocks.

2. Remove the OPP/performance resources.


Thanks,

Praveen Talari

>
> Konrad


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

* Re: [PATCH 7/7] i2c: qcom-geni: Use geni_se_set_rate() for setting source clock frequency
  2026-08-24 15:06   ` Konrad Dybcio
@ 2026-08-25  8:19     ` Praveen Talari
  0 siblings, 0 replies; 34+ messages in thread
From: Praveen Talari @ 2026-08-25  8:19 UTC (permalink / raw)
  To: Konrad Dybcio, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c

Hi Konrad,

Thank you for review.

On 24-08-2026 20:36, Konrad Dybcio wrote:
> On 8/4/26 9:57 PM, Praveen Talari wrote:
>> On the SA8255P platform there is no Linux clock handler for the SE source
>> clock; resources are instead managed by firmware via a genpd performance
>> domain. The I2C driver therefore relies on geni_se_set_rate() to apply the
>> fixed 19.2 MHz source clock frequency expected by the SCL divider and
>> counter values programmed by qcom_geni_i2c_conf().
> [...]
>
>> @@ -233,6 +233,10 @@ static int qcom_geni_i2c_conf(struct geni_se *se, unsigned long freq)
>>   				 itr->clk_div, itr->t_high_cnt,
>>   				 itr->t_low_cnt, itr->t_cycle_cnt);
>>   
>> +	ret = geni_se_set_rate(&gi2c->se, 19200000);
>> +	if (ret)
>> +		return ret;
> This wasn't here before and the commit message only says something to the

Yes, it was not there earlier. I have added because of Fast-mode Plus (1 
MHz)

cannot achieve the required timings with the default 19.2 MHz source clock.

A higher source frequency (for example, 32.5 MHz or 37.5 MHz) is required,

along with the associated voltage/performance vote.


Thanks,

Praveen Talari


> amount of "it's necessary" - what's the difference?
>
> Konrad


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

* Re: [PATCH 1/7] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0
  2026-08-04 19:57 ` [PATCH 1/7] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0 Praveen Talari
                     ` (2 preceding siblings ...)
  2026-08-12  7:24   ` Mukesh Savaliya
@ 2026-08-25  8:22   ` Abel Vesa
  3 siblings, 0 replies; 34+ messages in thread
From: Abel Vesa @ 2026-08-25  8:22 UTC (permalink / raw)
  To: Praveen Talari
  Cc: konrad.dybcio, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti, mukesh.savaliya,
	chandana.chiluveru, arm-scmi, linux-arm-kernel, linux-pm,
	linux-kernel, linux-arm-msm, linux-serial, linux-spi, linux-i2c

On 26-08-05 01:27:39, Praveen Talari wrote:
> Currently, scmi_pd_set_perf_state() treats a performance state of 0 as
> invalid and returns -EINVAL. As a result, devices attached to SCMI
> performance domains can report failures when relinquishing their
> performance vote.
> 
> The OPP framework use performance state 0 to indicate that no performance
> vote is required. For example, dev_pm_opp_set_rate(dev, 0) is commonly
> used (by firmware or linux)  when a device is runtime suspended.
> 
> A zero performance state does not require any SCMI performance request
> to be sent. Treat it as a no-op and return success instead of reporting
> an error.
> 
> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>

Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>


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

* Re: [PATCH 4/7] serial: qcom-geni: Use geni_se_set_rate() for source clock configuration
  2026-08-25  4:00     ` Praveen Talari
@ 2026-08-25  8:28       ` Konrad Dybcio
  0 siblings, 0 replies; 34+ messages in thread
From: Konrad Dybcio @ 2026-08-25  8:28 UTC (permalink / raw)
  To: Praveen Talari, Sudeep Holla, Cristian Marussi, Ulf Hansson,
	Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman, Jiri Slaby,
	Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: mukesh.savaliya, chandana.chiluveru, arm-scmi, linux-arm-kernel,
	linux-pm, linux-kernel, linux-arm-msm, linux-serial, linux-spi,
	linux-i2c

On 8/25/26 6:00 AM, Praveen Talari wrote:
> HI Konrad,
> 
> On 24-08-2026 20:35, Konrad Dybcio wrote:
>> On 8/4/26 9:57 PM, Praveen Talari wrote:
>>> The driver calls dev_pm_opp_set_rate() directly on uport->dev to apply
>>> the computed source clock frequency, and dispatches baud rate handling
>>> through a per-variant dev_data->set_rate() callback that either
>>> recalculates the clock divider (Linux clock managed path) or selects
>>> a performance level via geni_se_set_perf_level() (SA8255P firmware
>>> managed path).
>> [...]
>>
>>> +    geni_se_set_rate(&port->se, 0);
>> This ends up calling dev_pm_opp_set_rate(0) [i see this is an existing
>> bug in geni_se_resources_deactivate()], which removes the power vote,
>> but does nothing to the clock (neither set_rate nor disable_unprepare),
>> which will crash the platform
>>
>> Both of these calls (new and existing) should be removed. Clocks will
>> be disabled by geni_se_clks_off() in geni_se_resources_deactivate().
>>
>> Then, we should do dev_pm_set_opp(se->dev, NULL) *after* they are off
>> to remove any trailing OPP resources (i.e. icc votes defined in the OPP
>> table in our case)
> So, if I understand correctly, the expected sequence is:
> 
> 1. Disable the clocks.
> 
> 2. Remove the OPP/performance resources.

Yes, otherwise there is no guarantee that the clocks have sufficient
power for a given rate

Konrad


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

* Re: [PATCH 6/7] i2c: qcom-geni: Use common GENI resource initialization helper
  2026-08-24 13:12   ` Mukesh Savaliya
@ 2026-08-25 13:34     ` Praveen Talari
  0 siblings, 0 replies; 34+ messages in thread
From: Praveen Talari @ 2026-08-25 13:34 UTC (permalink / raw)
  To: Mukesh Savaliya, konrad.dybcio, Sudeep Holla, Cristian Marussi,
	Ulf Hansson, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
	Jiri Slaby, Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, arm-scmi, linux-arm-kernel, linux-pm,
	linux-kernel, linux-arm-msm, linux-serial, linux-spi, linux-i2c

Hi Mukesh

On 24-08-2026 18:42, Mukesh Savaliya wrote:
>
>
> On 8/5/2026 1:27 AM, Praveen Talari wrote:
>
> [...]
>
>> @@ -228,10 +228,13 @@ static int qcom_geni_i2c_conf(struct geni_se 
>> *se, unsigned long freq)
>>       val |= itr->t_low_cnt << LOW_COUNTER_SHFT;
>>       val |= itr->t_cycle_cnt;
>>       writel_relaxed(val, gi2c->se.base + SE_I2C_SCL_COUNTERS);
>> +
>>       trace_geni_i2c_bus_setup(gi2c->se.dev, gi2c->clk_freq_out,
>>                    itr->clk_div, itr->t_high_cnt,
>>                    itr->t_low_cnt, itr->t_cycle_cnt);
>> -    return 0;
>> +
>
> This looks wrong to me.
> First accessed registers and then we are setting ICC vote ? we should 
> enable resources first.

At this point the hardware resources are already enabled and  the ICC 
call only updates

the interconnect bandwidth vote. Therefore there is no dependency 
requiring the

ICC vote to be issued before these register accesses.

>
>> +    return geni_icc_set_bw_ab(&gi2c->se, GENI_DEFAULT_BW, 
>> GENI_DEFAULT_BW,
>> +                  Bps_to_icc(gi2c->clk_freq_out));
>>   }
>>     static void geni_i2c_err_misc(struct geni_i2c_dev *gi2c)
>> @@ -1100,24 +1103,6 @@ static int geni_i2c_init(struct geni_i2c_dev 
>> *gi2c)
>>       return ret;
>>   }
>>   -static int geni_i2c_resources_init(struct geni_se *se)
>> -{
>> -    struct geni_i2c_dev *gi2c = dev_get_drvdata(se->dev);
>> -    int ret;
>> -
>> -    ret = geni_se_resources_init(&gi2c->se);
>> -    if (ret)
>> -        return ret;
>> -
>> -    ret = geni_i2c_clk_map_idx(gi2c);
>> -    if (ret)
>> -        return dev_err_probe(gi2c->se.dev, ret, "Invalid clk 
>> frequency %d Hz\n",
>> -                     gi2c->clk_freq_out);
>> -
>> -    return geni_icc_set_bw_ab(&gi2c->se, GENI_DEFAULT_BW, 
>> GENI_DEFAULT_BW,
>> -                  Bps_to_icc(gi2c->clk_freq_out));
>> -}
>> -
>>   static int geni_i2c_probe(struct platform_device *pdev)
>>   {
>>       struct geni_i2c_dev *gi2c;
>> @@ -1188,6 +1173,11 @@ static int geni_i2c_probe(struct 
>> platform_device *pdev)
>>       if (ret < 0)
>>           return ret;
>>   +    ret = geni_i2c_clk_map_idx(gi2c);
>> +    if (ret)
>> +        return dev_err_probe(gi2c->se.dev, ret, "Invalid clk 
>> frequency %d Hz\n",
>> +                     gi2c->clk_freq_out);
>> +
>
> why not move to geni_i2c_init() ?
>
> Check recent patch @ i2c: qcom-geni: add I2C frequency table for 32 
> MHz firmware-based SEs.
Okay let me review it and update.
>
>
> Let's agree to move there, to avoid issue.
>
>>       ret = i2c_add_adapter(&gi2c->adap);
>>       if (ret)
>>           return dev_err_probe(dev, ret, "Error adding i2c adapter\n");
>> @@ -1281,7 +1271,7 @@ static const struct dev_pm_ops geni_i2c_pm_ops = {
>>   };
>>     static const struct geni_i2c_desc geni_i2c = {
>> -    .resources_init = geni_i2c_resources_init,
>> +    .resources_init = geni_se_resources_init,
>
> why to add common driver function to i2c ? and also spi, uart ?


The goal was to provide a common helper that avoids duplicating

the same logic across multiple consumer drivers. As a side note,

this refactoring was done based on Konrad's earlier suggestion to

consolidate the functionality into a generic implementation.

> Can we not call that function from within i2c specific hookup function 
> ? i think design wise should keep i2c as local function.
>
> Also driver specific anything can be managed in local function.
>
>>       .set_rate = qcom_geni_i2c_conf,
>>       .power_on = geni_se_resources_activate,
>>       .power_off = geni_se_resources_deactivate,
>> @@ -1290,7 +1280,7 @@ static const struct geni_i2c_desc geni_i2c = {
>>   static const struct geni_i2c_desc i2c_master_hub = {
>>       .no_dma_support = true,
>>       .tx_fifo_depth = 16,
>> -    .resources_init = geni_i2c_resources_init,
>> +    .resources_init = geni_se_resources_init,
>>       .set_rate = qcom_geni_i2c_conf,
>>       .power_on = geni_se_resources_activate,
>>       .power_off = geni_se_resources_deactivate,
>>
>


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

* Re: [PATCH 7/7] i2c: qcom-geni: Use geni_se_set_rate() for setting source clock frequency
  2026-08-24 13:41   ` Mukesh Savaliya
@ 2026-08-25 18:03     ` Praveen Talari
  0 siblings, 0 replies; 34+ messages in thread
From: Praveen Talari @ 2026-08-25 18:03 UTC (permalink / raw)
  To: Mukesh Savaliya, konrad.dybcio, Sudeep Holla, Cristian Marussi,
	Ulf Hansson, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
	Jiri Slaby, Mark Brown, Viken Dadhaniya, Andi Shyti
  Cc: chandana.chiluveru, arm-scmi, linux-arm-kernel, linux-pm,
	linux-kernel, linux-arm-msm, linux-serial, linux-spi, linux-i2c

Hi Mukesh

On 24-08-2026 19:11, Mukesh Savaliya wrote:
>
>
> On 8/5/2026 1:27 AM, Praveen Talari wrote:
>> On the SA8255P platform there is no Linux clock handler for the SE 
>> source
>> clock; resources are instead managed by firmware via a genpd performance
>> domain. The I2C driver therefore relies on geni_se_set_rate() to 
>> apply the
>> fixed 19.2 MHz source clock frequency expected by the SCL divider and
>
> somewhere it's 32 MHz also and this may change too ?
19.2 MHz is just the frequency currently requested by the I2C driver.

Other frequencies such as 32 MHz are also supported and may change in 
the future.
>
>> counter values programmed by qcom_geni_i2c_conf().
>>
>> Call geni_se_set_rate() directly from qcom_geni_i2c_conf() so the
>> configured frequency is applied to the correct device (the perf domain
>> device on the firmware-managed path, or se->dev otherwise) without 
>> the I2C
>> driver needing to know which resources_init() variant is in use.
>>
>> Drop the now-unused set_rate field from struct geni_i2c_desc, the
>> geni_se_set_perf_opp() usage on the SA8255P variant, and the unused freq
>> parameter from qcom_geni_i2c_conf().
>>
>> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
>> ---
>>   drivers/i2c/busses/i2c-qcom-geni.c | 13 +++++++------
>>   1 file changed, 7 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-qcom-geni.c 
>> b/drivers/i2c/busses/i2c-qcom-geni.c
>> index a23554d101fd..4561e2d235d5 100644
>> --- a/drivers/i2c/busses/i2c-qcom-geni.c
>> +++ b/drivers/i2c/busses/i2c-qcom-geni.c
>> @@ -213,11 +213,11 @@ static int geni_i2c_clk_map_idx(struct 
>> geni_i2c_dev *gi2c)
>>       return -EINVAL;
>>   }
>>   -static int qcom_geni_i2c_conf(struct geni_se *se, unsigned long freq)
>> +static int qcom_geni_i2c_conf(struct geni_se *se)
>>   {
>>       struct geni_i2c_dev *gi2c = dev_get_drvdata(se->dev);
>>       const struct geni_i2c_clk_fld *itr = gi2c->clk_fld;
>> -    u32 val;
>> +    u32 val, ret;
>>         writel_relaxed(0, gi2c->se.base + SE_GENI_CLK_SEL);
>>   @@ -233,6 +233,10 @@ static int qcom_geni_i2c_conf(struct geni_se 
>> *se, unsigned long freq)
>>                    itr->clk_div, itr->t_high_cnt,
>>                    itr->t_low_cnt, itr->t_cycle_cnt);
>>   +    ret = geni_se_set_rate(&gi2c->se, 19200000);
>
> hard code ?
Good point. The 19.2 MHz value is not intended to be a permanent 
limitation.
This matches the frequency currently used by the I2C driver and 
therefore preserves
the existing behavior. If support for higher source clock frequencies 
(e.g. 32 MHz or others)
is added in the future, the requested OPP/performance state will need to 
be updated accordingly.
> May work currently, but if higher frequency support added, source may 
> change.
>
> Also you have added in commit message, but add a comment also here.
>
>> +    if (ret)
>> +        return ret;
>> +
>>       return geni_icc_set_bw_ab(&gi2c->se, GENI_DEFAULT_BW, 
>> GENI_DEFAULT_BW,
>>                     Bps_to_icc(gi2c->clk_freq_out));
>>   }
>
> [...]
>


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

end of thread, other threads:[~2026-08-25 18:03 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-04 19:57 [PATCH 0/7] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
2026-08-04 19:57 ` [PATCH 1/7] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0 Praveen Talari
2026-08-10 14:19   ` Ulf Hansson
2026-08-12  6:58   ` Mukesh Savaliya
2026-08-12  7:24   ` Mukesh Savaliya
2026-08-12  8:57     ` Ulf Hansson
2026-08-12  9:13       ` Mukesh Savaliya
2026-08-25  8:22   ` Abel Vesa
2026-08-04 19:57 ` [PATCH 2/7] soc: qcom: geni-se: Populate clk_perf_tbl with SE source clock frequencies from perf OPP table Praveen Talari
2026-08-12  7:36   ` Mukesh Savaliya
2026-08-24 14:56   ` Konrad Dybcio
2026-08-24 16:55     ` Praveen Talari
2026-08-04 19:57 ` [PATCH 3/7] soc: qcom: geni-se: Add helper to set SE clock rate via OPP Praveen Talari
2026-08-12  8:55   ` Mukesh Savaliya
2026-08-24 11:07   ` Mukesh Savaliya
2026-08-24 14:58   ` Konrad Dybcio
2026-08-24 17:00     ` Praveen Talari
2026-08-04 19:57 ` [PATCH 4/7] serial: qcom-geni: Use geni_se_set_rate() for source clock configuration Praveen Talari
2026-08-24 11:39   ` Mukesh Savaliya
2026-08-24 11:40   ` Mukesh Savaliya
2026-08-24 15:05   ` Konrad Dybcio
2026-08-25  4:00     ` Praveen Talari
2026-08-25  8:28       ` Konrad Dybcio
2026-08-04 19:57 ` [PATCH 5/7] spi: qcom-geni: Use geni_se_set_rate() for setting source clock frequency Praveen Talari
2026-08-04 20:03   ` Mark Brown
2026-08-24 11:52   ` Mukesh Savaliya
2026-08-04 19:57 ` [PATCH 6/7] i2c: qcom-geni: Use common GENI resource initialization helper Praveen Talari
2026-08-24 13:12   ` Mukesh Savaliya
2026-08-25 13:34     ` Praveen Talari
2026-08-04 19:57 ` [PATCH 7/7] i2c: qcom-geni: Use geni_se_set_rate() for setting source clock frequency Praveen Talari
2026-08-24 13:41   ` Mukesh Savaliya
2026-08-25 18:03     ` Praveen Talari
2026-08-24 15:06   ` Konrad Dybcio
2026-08-25  8:19     ` Praveen Talari

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