* [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P
@ 2026-08-27 17:59 Praveen Talari
2026-08-27 17:59 ` [PATCH v2 1/9] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0 Praveen Talari
` (9 more replies)
0 siblings, 10 replies; 18+ messages in thread
From: Praveen Talari @ 2026-08-27 17:59 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, Abel Vesa
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>
---
Changes in v2:
- Add new patch to remove OPP rate reset from resource deactivation
- Add new patch to vote source frequency via OPP for I2C
- Compress the SPI, I2C and serial commit messages per review feedback
- Drop a stray blank line before trace_geni_i2c_bus_setup() in the
I2C resource-initialization helper commit.
- Link to v1: https://patch.msgid.link/20260805-derive_clk_perf_tbl_from_perf_domain_opp_table-v1-0-61171ab1cdce@oss.qualcomm.com
---
Praveen Talari (9):
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
soc: qcom: geni-se: Remove OPP rate reset from resource deactivation
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: Vote for SE clock rate using OPP
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 | 72 +++++++++++++++++----------------
drivers/pmdomain/arm/scmi_perf_domain.c | 2 +-
drivers/soc/qcom/qcom-geni-se.c | 62 +++++++++++++++++++++++++---
drivers/spi/spi-geni-qcom.c | 24 +++++------
drivers/tty/serial/qcom_geni_serial.c | 26 ++++++------
include/linux/soc/qcom/geni-se.h | 2 +
6 files changed, 122 insertions(+), 66 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] 18+ messages in thread
* [PATCH v2 1/9] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0
2026-08-27 17:59 [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
@ 2026-08-27 17:59 ` Praveen Talari
2026-09-01 14:31 ` Ulf Hansson
2026-08-27 17:59 ` [PATCH v2 2/9] soc: qcom: geni-se: Populate clk_perf_tbl with SE source clock frequencies from perf OPP table Praveen Talari
` (8 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Praveen Talari @ 2026-08-27 17:59 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, Abel Vesa
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.
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Reviewed-by: Mukesh Savaliya <mukesh.savaliya@oss.qualcomm.com>
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] 18+ messages in thread
* [PATCH v2 2/9] soc: qcom: geni-se: Populate clk_perf_tbl with SE source clock frequencies from perf OPP table
2026-08-27 17:59 [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
2026-08-27 17:59 ` [PATCH v2 1/9] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0 Praveen Talari
@ 2026-08-27 17:59 ` Praveen Talari
2026-08-27 17:59 ` [PATCH v2 3/9] soc: qcom: geni-se: Add helper to set SE clock rate via OPP Praveen Talari
` (7 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Praveen Talari @ 2026-08-27 17:59 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 | 33 ++++++++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index 873bfbd6b2b7..447b9cc6babf 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,31 @@ 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;
+ 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++) {
+ 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] 18+ messages in thread
* [PATCH v2 3/9] soc: qcom: geni-se: Add helper to set SE clock rate via OPP
2026-08-27 17:59 [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
2026-08-27 17:59 ` [PATCH v2 1/9] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0 Praveen Talari
2026-08-27 17:59 ` [PATCH v2 2/9] soc: qcom: geni-se: Populate clk_perf_tbl with SE source clock frequencies from perf OPP table Praveen Talari
@ 2026-08-27 17:59 ` Praveen Talari
2026-09-04 9:01 ` Konrad Dybcio
2026-08-27 17:59 ` [PATCH v2 4/9] soc: qcom: geni-se: Remove OPP rate reset from resource deactivation Praveen Talari
` (6 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Praveen Talari @ 2026-08-27 17:59 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.
Acked-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
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 447b9cc6babf..04f58a6f26ff 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] 18+ messages in thread
* [PATCH v2 4/9] soc: qcom: geni-se: Remove OPP rate reset from resource deactivation
2026-08-27 17:59 [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
` (2 preceding siblings ...)
2026-08-27 17:59 ` [PATCH v2 3/9] soc: qcom: geni-se: Add helper to set SE clock rate via OPP Praveen Talari
@ 2026-08-27 17:59 ` Praveen Talari
2026-09-04 8:49 ` Konrad Dybcio
2026-08-27 17:59 ` [PATCH v2 5/9] serial: qcom-geni: Use geni_se_set_rate() for source clock configuration Praveen Talari
` (5 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Praveen Talari @ 2026-08-27 17:59 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
Remove the dev_pm_opp_set_rate(se->dev, 0) call from
geni_se_resources_deactivate().
OPP resource management should be controlled by the consumer driver.
Additionally, clocks are already disabled by geni_se_clks_off(), making
the OPP rate reset unnecessary during resource deactivation.
Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
drivers/soc/qcom/qcom-geni-se.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index 04f58a6f26ff..d4f0544d73c4 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -1039,8 +1039,8 @@ EXPORT_SYMBOL_GPL(geni_icc_disable);
* geni_se_resources_deactivate() - Deactivate GENI SE device resources
* @se: Pointer to the geni_se structure
*
- * Deactivates device resources for power saving: OPP rate to 0, pin control
- * to sleep state, turns off clocks, and disables interconnect. Skips ACPI devices.
+ * Deactivates device resources for power saving: pin control to sleep
+ * state, turns off clocks, and disables interconnect. Skips ACPI devices.
*
* Return: 0 on success, negative error code on failure
*/
@@ -1051,9 +1051,6 @@ int geni_se_resources_deactivate(struct geni_se *se)
if (has_acpi_companion(se->dev))
return 0;
- if (se->has_opp)
- dev_pm_opp_set_rate(se->dev, 0);
-
ret = pinctrl_pm_select_sleep_state(se->dev);
if (ret)
return ret;
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 5/9] serial: qcom-geni: Use geni_se_set_rate() for source clock configuration
2026-08-27 17:59 [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
` (3 preceding siblings ...)
2026-08-27 17:59 ` [PATCH v2 4/9] soc: qcom: geni-se: Remove OPP rate reset from resource deactivation Praveen Talari
@ 2026-08-27 17:59 ` Praveen Talari
2026-08-27 17:59 ` [PATCH v2 6/9] spi: qcom-geni: Use geni_se_set_rate() for setting source clock frequency Praveen Talari
` (4 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Praveen Talari @ 2026-08-27 17:59 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 compute the divider needed
for a requested baud rate. 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 clk_perf_tbl from
the performance-domain OPP table, allowing firmware-managed
platforms to use geni_se_clk_freq_match().
Call geni_serial_set_rate() unconditionally from
qcom_geni_serial_set_termios(), and 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/tty/serial/qcom_geni_serial.c | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 3633723acef8..23ecd137c521 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;
@@ -2039,15 +2041,19 @@ static void qcom_geni_serial_remove(struct platform_device *pdev)
static int __maybe_unused qcom_geni_serial_runtime_suspend(struct device *dev)
{
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
+ int ret;
- return port->dev_data->power_off ?
- port->dev_data->power_off(&port->se) : 0;
+ ret = port->dev_data->power_off ?
+ port->dev_data->power_off(&port->se) : 0;
+ if (ret)
+ return ret;
+
+ return geni_se_set_rate(&port->se, 0);
}
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 +2062,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 +2122,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 +2130,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 +2137,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 +2145,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] 18+ messages in thread
* [PATCH v2 6/9] spi: qcom-geni: Use geni_se_set_rate() for setting source clock frequency
2026-08-27 17:59 [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
` (4 preceding siblings ...)
2026-08-27 17:59 ` [PATCH v2 5/9] serial: qcom-geni: Use geni_se_set_rate() for source clock configuration Praveen Talari
@ 2026-08-27 17:59 ` Praveen Talari
2026-08-27 17:59 ` [PATCH v2 7/9] i2c: qcom-geni: Vote for SE clock rate using OPP Praveen Talari
` (3 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Praveen Talari @ 2026-08-27 17:59 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 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.
Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
drivers/spi/spi-geni-qcom.c | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index 6566975eb24f..03ce9eff9c24 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;
@@ -1161,9 +1159,14 @@ 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);
+ int ret;
+
+ ret = mas->dev_data->power_off ?
+ mas->dev_data->power_off(&mas->se) : 0;
+ if (ret)
+ return ret;
- return mas->dev_data->power_off ?
- mas->dev_data->power_off(&mas->se) : 0;
+ return geni_se_set_rate(&mas->se, 0);
}
static int __maybe_unused spi_geni_runtime_resume(struct device *dev)
@@ -1178,10 +1181,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 +1224,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] 18+ messages in thread
* [PATCH v2 7/9] i2c: qcom-geni: Vote for SE clock rate using OPP
2026-08-27 17:59 [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
` (5 preceding siblings ...)
2026-08-27 17:59 ` [PATCH v2 6/9] spi: qcom-geni: Use geni_se_set_rate() for setting source clock frequency Praveen Talari
@ 2026-08-27 17:59 ` Praveen Talari
2026-09-04 8:52 ` Konrad Dybcio
2026-08-27 17:59 ` [PATCH v2 8/9] i2c: qcom-geni: Use common GENI resource initialization helper Praveen Talari
` (2 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Praveen Talari @ 2026-08-27 17:59 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 I2C driver currently assumes a fixed source clock selection and always
programs SE_GENI_CLK_SEL to 0, which is not sufficient when the controller
needs to switch between different source clocks.
Add the source clock index and frequency to the I2C clock map entries and
use them while configuring the controller. Request the required
source clock rate through dev_pm_opp_set_rate() and program SE_GENI_CLK_SEL
with the matching source index.
Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
drivers/i2c/busses/i2c-qcom-geni.c | 35 +++++++++++++++++++++++++++--------
1 file changed, 27 insertions(+), 8 deletions(-)
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index 658636c1ee0e..a3b7609e3cf9 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
#include <linux/pm_runtime.h>
#include <linux/soc/qcom/geni-se.h>
#include <linux/spinlock.h>
@@ -165,8 +166,13 @@ struct geni_i2c_clk_fld {
u8 t_high_cnt;
u8 t_low_cnt;
u8 t_cycle_cnt;
+ u8 src_indx;
+ u32 src_clk_freq;
};
+#define CLK_19P2MHZ (19200 * HZ_PER_KHZ)
+#define CLK_32MHZ (32 * HZ_PER_MHZ)
+
/*
* Hardware uses the underlying formula to calculate time periods of
* SCL clock cycle. Firmware uses some additional cycles excluded from the
@@ -180,17 +186,17 @@ struct geni_i2c_clk_fld {
* source_clock = 19.2 MHz
*/
static const struct geni_i2c_clk_fld geni_i2c_clk_map_19p2mhz[] = {
- { I2C_MAX_STANDARD_MODE_FREQ, 7, 10, 12, 26 },
- { I2C_MAX_FAST_MODE_FREQ, 2, 5, 11, 22 },
- { I2C_MAX_FAST_MODE_PLUS_FREQ, 1, 2, 8, 18 },
+ { I2C_MAX_STANDARD_MODE_FREQ, 7, 10, 12, 26, 0, CLK_19P2MHZ },
+ { I2C_MAX_FAST_MODE_FREQ, 2, 5, 11, 22, 0, CLK_19P2MHZ },
+ { I2C_MAX_FAST_MODE_PLUS_FREQ, 1, 2, 8, 18, 0, CLK_19P2MHZ },
{}
};
/* source_clock = 32 MHz */
static const struct geni_i2c_clk_fld geni_i2c_clk_map_32mhz[] = {
- { I2C_MAX_STANDARD_MODE_FREQ, 8, 14, 18, 38 },
- { I2C_MAX_FAST_MODE_FREQ, 4, 3, 9, 19 },
- { I2C_MAX_FAST_MODE_PLUS_FREQ, 2, 3, 5, 15 },
+ { I2C_MAX_STANDARD_MODE_FREQ, 8, 14, 18, 38, 1, CLK_32MHZ },
+ { I2C_MAX_FAST_MODE_FREQ, 4, 3, 9, 19, 1, CLK_32MHZ },
+ { I2C_MAX_FAST_MODE_PLUS_FREQ, 2, 3, 5, 15, 1, CLK_32MHZ },
{}
};
@@ -198,7 +204,7 @@ static int geni_i2c_clk_map_idx(struct geni_i2c_dev *gi2c)
{
const struct geni_i2c_clk_fld *itr;
- if (clk_get_rate(gi2c->se.clk) == 32 * HZ_PER_MHZ)
+ if (clk_get_rate(gi2c->se.clk) == CLK_32MHZ)
itr = geni_i2c_clk_map_32mhz;
else
itr = geni_i2c_clk_map_19p2mhz;
@@ -218,8 +224,13 @@ static int qcom_geni_i2c_conf(struct geni_se *se, unsigned long freq)
struct geni_i2c_dev *gi2c = dev_get_drvdata(se->dev);
const struct geni_i2c_clk_fld *itr = gi2c->clk_fld;
u32 val;
+ int ret;
+
+ ret = dev_pm_opp_set_rate(se->dev, itr->src_clk_freq);
+ if (ret)
+ return ret;
- writel_relaxed(0, gi2c->se.base + SE_GENI_CLK_SEL);
+ writel_relaxed(itr->src_indx, gi2c->se.base + SE_GENI_CLK_SEL);
val = (itr->clk_div << CLK_DIV_SHFT) | SER_CLK_EN;
writel_relaxed(val, gi2c->se.base + GENI_SER_M_CLK_CFG);
@@ -1228,6 +1239,8 @@ static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev)
}
}
+ dev_pm_opp_set_rate(dev, 0);
+
return 0;
}
@@ -1236,6 +1249,12 @@ static int __maybe_unused geni_i2c_runtime_resume(struct device *dev)
int ret = 0;
struct geni_i2c_dev *gi2c = dev_get_drvdata(dev);
+ if (gi2c->clk_fld && gi2c->clk_fld->src_clk_freq) {
+ ret = dev_pm_opp_set_rate(dev, gi2c->clk_fld->src_clk_freq);
+ if (ret)
+ return ret;
+ }
+
if (gi2c->dev_data->power_on) {
ret = gi2c->dev_data->power_on(&gi2c->se);
if (ret)
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 8/9] i2c: qcom-geni: Use common GENI resource initialization helper
2026-08-27 17:59 [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
` (6 preceding siblings ...)
2026-08-27 17:59 ` [PATCH v2 7/9] i2c: qcom-geni: Vote for SE clock rate using OPP Praveen Talari
@ 2026-08-27 17:59 ` Praveen Talari
2026-08-27 17:59 ` [PATCH v2 9/9] i2c: qcom-geni: Use geni_se_set_rate() for setting source clock frequency Praveen Talari
2026-09-01 14:52 ` [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Ulf Hansson
9 siblings, 0 replies; 18+ messages in thread
From: Praveen Talari @ 2026-08-27 17:59 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 | 31 ++++++++++---------------------
1 file changed, 10 insertions(+), 21 deletions(-)
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index a3b7609e3cf9..0b178701e1d1 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -242,7 +242,9 @@ static int qcom_geni_i2c_conf(struct geni_se *se, unsigned long freq)
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)
@@ -1111,24 +1113,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;
@@ -1199,6 +1183,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");
@@ -1300,7 +1289,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,
@@ -1309,7 +1298,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] 18+ messages in thread
* [PATCH v2 9/9] i2c: qcom-geni: Use geni_se_set_rate() for setting source clock frequency
2026-08-27 17:59 [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
` (7 preceding siblings ...)
2026-08-27 17:59 ` [PATCH v2 8/9] i2c: qcom-geni: Use common GENI resource initialization helper Praveen Talari
@ 2026-08-27 17:59 ` Praveen Talari
2026-09-01 14:52 ` [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Ulf Hansson
9 siblings, 0 replies; 18+ messages in thread
From: Praveen Talari @ 2026-08-27 17:59 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 resource management may be handled either through the Linux clock
framework or a firmware-managed performance domain. Source clock
programming currently depends on platform-specific callbacks.
Use geni_se_set_rate() for source clock programming and perform the
source clock configuration from qcom_geni_i2c_conf(), allowing the GENI
core to abstract the underlying resource-management mechanism from the
I2C driver. This removes the need for platform-specific rate-setting
callbacks and enables a common code path across all GENI I2C platforms.
Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
drivers/i2c/busses/i2c-qcom-geni.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index 0b178701e1d1..deb0d822290c 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -16,7 +16,6 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
-#include <linux/pm_opp.h>
#include <linux/pm_runtime.h>
#include <linux/soc/qcom/geni-se.h>
#include <linux/spinlock.h>
@@ -219,14 +218,14 @@ 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;
int ret;
- ret = dev_pm_opp_set_rate(se->dev, itr->src_clk_freq);
+ ret = geni_se_set_rate(&gi2c->se, itr->src_clk_freq);
if (ret)
return ret;
@@ -985,7 +984,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;
@@ -1228,7 +1227,7 @@ static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev)
}
}
- dev_pm_opp_set_rate(dev, 0);
+ geni_se_set_rate(&gi2c->se, 0);
return 0;
}
@@ -1239,7 +1238,7 @@ static int __maybe_unused geni_i2c_runtime_resume(struct device *dev)
struct geni_i2c_dev *gi2c = dev_get_drvdata(dev);
if (gi2c->clk_fld && gi2c->clk_fld->src_clk_freq) {
- ret = dev_pm_opp_set_rate(dev, gi2c->clk_fld->src_clk_freq);
+ ret = geni_se_set_rate(&gi2c->se, gi2c->clk_fld->src_clk_freq);
if (ret)
return ret;
}
@@ -1290,7 +1289,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,
};
@@ -1299,14 +1297,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] 18+ messages in thread
* Re: [PATCH v2 1/9] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0
2026-08-27 17:59 ` [PATCH v2 1/9] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0 Praveen Talari
@ 2026-09-01 14:31 ` Ulf Hansson
0 siblings, 0 replies; 18+ messages in thread
From: Ulf Hansson @ 2026-09-01 14:31 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,
Abel Vesa
On Thu, Aug 27, 2026 at 7:59 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.
>
> 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.
>
> Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
> Reviewed-by: Mukesh Savaliya <mukesh.savaliya@oss.qualcomm.com>
> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
This is already in v7.2. Please rebase your series.
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] 18+ messages in thread
* Re: [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P
2026-08-27 17:59 [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
` (8 preceding siblings ...)
2026-08-27 17:59 ` [PATCH v2 9/9] i2c: qcom-geni: Use geni_se_set_rate() for setting source clock frequency Praveen Talari
@ 2026-09-01 14:52 ` Ulf Hansson
2026-09-01 16:48 ` Praveen Talari
9 siblings, 1 reply; 18+ messages in thread
From: Ulf Hansson @ 2026-09-01 14:52 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,
Abel Vesa
On Thu, Aug 27, 2026 at 7:59 PM Praveen Talari
<praveen.talari@oss.qualcomm.com> wrote:
>
> 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.
Hmm, this sounds like moving backwards when it comes to keeping
drivers as portable as possible.
I understand geni_se_clk_freq_match() has been around for a while, but
fortunately its use seems limited to only a few qcom specific drivers.
Rather than continue down this path, would it not be possible to find
a more generic solution for "geni_se_clk_freq_match()"? Can we replace
it with a common clock/OPP API? In this way, we would not need to
sprinkle drivers with calls to platform specific code.
>
> 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.
Rather than adding yet another platform specific method, would it be
possible to extend the generic OPP library with the pieces that are
missing to make this work in a generic way?
>
> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
Kind regards
Uffe
> ---
> Changes in v2:
> - Add new patch to remove OPP rate reset from resource deactivation
> - Add new patch to vote source frequency via OPP for I2C
> - Compress the SPI, I2C and serial commit messages per review feedback
> - Drop a stray blank line before trace_geni_i2c_bus_setup() in the
> I2C resource-initialization helper commit.
> - Link to v1: https://patch.msgid.link/20260805-derive_clk_perf_tbl_from_perf_domain_opp_table-v1-0-61171ab1cdce@oss.qualcomm.com
>
> ---
> Praveen Talari (9):
> 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
> soc: qcom: geni-se: Remove OPP rate reset from resource deactivation
> 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: Vote for SE clock rate using OPP
> 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 | 72 +++++++++++++++++----------------
> drivers/pmdomain/arm/scmi_perf_domain.c | 2 +-
> drivers/soc/qcom/qcom-geni-se.c | 62 +++++++++++++++++++++++++---
> drivers/spi/spi-geni-qcom.c | 24 +++++------
> drivers/tty/serial/qcom_geni_serial.c | 26 ++++++------
> include/linux/soc/qcom/geni-se.h | 2 +
> 6 files changed, 122 insertions(+), 66 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] 18+ messages in thread
* Re: [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P
2026-09-01 14:52 ` [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Ulf Hansson
@ 2026-09-01 16:48 ` Praveen Talari
2026-09-04 7:56 ` Ulf Hansson
0 siblings, 1 reply; 18+ messages in thread
From: Praveen Talari @ 2026-09-01 16:48 UTC (permalink / raw)
To: Ulf Hansson
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,
Abel Vesa
Hi Ulf,
On 01-09-2026 20:22, Ulf Hansson wrote:
> On Thu, Aug 27, 2026 at 7:59 PM Praveen Talari
> <praveen.talari@oss.qualcomm.com> wrote:
>> 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.
> Hmm, this sounds like moving backwards when it comes to keeping
> drivers as portable as possible.
>
> I understand geni_se_clk_freq_match() has been around for a while, but
> fortunately its use seems limited to only a few qcom specific drivers.
>
> Rather than continue down this path, would it not be possible to find
> a more generic solution for "geni_se_clk_freq_match()"? Can we replace
> it with a common clock/OPP API? In this way, we would not need to
> sprinkle drivers with calls to platform specific code.
I agree that protocol drivers should not need to know whether GENI resources
are managed through the clock framework or a firmware-provided
performance domain.
The intent of this series is actually to move in that direction rather than
introduce a separate flow. Today firmware-managed platforms cannot use
geni_se_clk_freq_match() because clk_perf_tbl is only populated when a
Linux clock
is present. This series derives the same clock-performance
information(clk_perf_tbl) from the OPP
table and populates clk_perf_tbl during geni_se_domain_attach(),
allowing both
resource-management models to reuse the existing
geni_se_clk_freq_match() infrastructure.
Likewise, geni_se_set_rate() hides whether the underlying implementation
uses
dev_pm_opp_set_rate() on a perf-domain device or a regular clock-backed
device,
so protocol drivers no longer need platform-specific callbacks. The goal
is to
converge both paths behind common GENI helpers rather than maintain separate
clock-selection mechanisms.
>
>> 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.
> Rather than adding yet another platform specific method, would it be
> possible to extend the generic OPP library with the pieces that are
> missing to make this work in a generic way?
I agree with the goal of using generic infrastructure. However,
geni_se_clk_freq_match()
derives GENI-specific parameters such as the source clock, clock index,
and divider values
required for GSI TRE programming, which are not represented by the
generic OPP interface today.
This series does not introduce a new clock selection path; it reuses the
existing
geni_se_clk_freq_match() flow on firmware-managed platforms by populating
clk_perf_tbl from OPP data.
>
>> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
> Kind regards
> Uffe
>
>> ---
>> Changes in v2:
>> - Add new patch to remove OPP rate reset from resource deactivation
>> - Add new patch to vote source frequency via OPP for I2C
>> - Compress the SPI, I2C and serial commit messages per review feedback
>> - Drop a stray blank line before trace_geni_i2c_bus_setup() in the
>> I2C resource-initialization helper commit.
>> - Link to v1: https://patch.msgid.link/20260805-derive_clk_perf_tbl_from_perf_domain_opp_table-v1-0-61171ab1cdce@oss.qualcomm.com
>>
>> ---
>> Praveen Talari (9):
>> 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
>> soc: qcom: geni-se: Remove OPP rate reset from resource deactivation
>> 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: Vote for SE clock rate using OPP
>> 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 | 72 +++++++++++++++++----------------
>> drivers/pmdomain/arm/scmi_perf_domain.c | 2 +-
>> drivers/soc/qcom/qcom-geni-se.c | 62 +++++++++++++++++++++++++---
>> drivers/spi/spi-geni-qcom.c | 24 +++++------
>> drivers/tty/serial/qcom_geni_serial.c | 26 ++++++------
>> include/linux/soc/qcom/geni-se.h | 2 +
>> 6 files changed, 122 insertions(+), 66 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] 18+ messages in thread
* Re: [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P
2026-09-01 16:48 ` Praveen Talari
@ 2026-09-04 7:56 ` Ulf Hansson
2026-09-04 9:00 ` Konrad Dybcio
0 siblings, 1 reply; 18+ messages in thread
From: Ulf Hansson @ 2026-09-04 7:56 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,
Abel Vesa
On Tue, Sep 1, 2026 at 6:48 PM Praveen Talari
<praveen.talari@oss.qualcomm.com> wrote:
>
> Hi Ulf,
>
> On 01-09-2026 20:22, Ulf Hansson wrote:
> > On Thu, Aug 27, 2026 at 7:59 PM Praveen Talari
> > <praveen.talari@oss.qualcomm.com> wrote:
> >> 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.
> > Hmm, this sounds like moving backwards when it comes to keeping
> > drivers as portable as possible.
> >
> > I understand geni_se_clk_freq_match() has been around for a while, but
> > fortunately its use seems limited to only a few qcom specific drivers.
> >
> > Rather than continue down this path, would it not be possible to find
> > a more generic solution for "geni_se_clk_freq_match()"? Can we replace
> > it with a common clock/OPP API? In this way, we would not need to
> > sprinkle drivers with calls to platform specific code.
> I agree that protocol drivers should not need to know whether GENI resources
> are managed through the clock framework or a firmware-provided
> performance domain.
>
> The intent of this series is actually to move in that direction rather than
> introduce a separate flow. Today firmware-managed platforms cannot use
> geni_se_clk_freq_match() because clk_perf_tbl is only populated when a
> Linux clock
> is present. This series derives the same clock-performance
> information(clk_perf_tbl) from the OPP
> table and populates clk_perf_tbl during geni_se_domain_attach(),
> allowing both
> resource-management models to reuse the existing
> geni_se_clk_freq_match() infrastructure.
Right, the goal makes sense, but I am not sure the proposed solution
is the way to get there.
We really want to avoid having generic drivers like (spi, uart, i2c,
etc) calling platform specific functions. This isn't just me, it's the
general way for how we do things for drivers. Of course, we have
exceptions, but I think you get my point.
In this case, why isn't it possible to use the clock and OPP
framework? Is there anything missing to make this work?
>
> Likewise, geni_se_set_rate() hides whether the underlying implementation
> uses
> dev_pm_opp_set_rate() on a perf-domain device or a regular clock-backed
> device,
> so protocol drivers no longer need platform-specific callbacks. The goal
> is to
> converge both paths behind common GENI helpers rather than maintain separate
> clock-selection mechanisms.
The OPP layer already has some capabilities for managing clocks. Can't
we use devm_pm_opp_set_config() to prepare an OPP table with the
relevant clk data for the devices, as a way to abstract things?
> >
> >> 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.
> > Rather than adding yet another platform specific method, would it be
> > possible to extend the generic OPP library with the pieces that are
> > missing to make this work in a generic way?
> I agree with the goal of using generic infrastructure. However,
> geni_se_clk_freq_match()
> derives GENI-specific parameters such as the source clock, clock index,
> and divider values
> required for GSI TRE programming, which are not represented by the
> generic OPP interface today.
>
> This series does not introduce a new clock selection path; it reuses the
> existing
> geni_se_clk_freq_match() flow on firmware-managed platforms by populating
> clk_perf_tbl from OPP data.
So geni_se_clk_freq_match() is used by two consumer drivers today,
drivers/spi/spi-geni-qcom.c and drivers/tty/serial/qcom_geni_serial.c.
Beyond the $subject series, there will be even more consumer drivers
that call these platform specific functions. As I said above, I don't
think this is moving things in the right direction.
If this can't be solved with generic frameworks (clocks and OPP),
please clarify why so we can figure out a better way forward.
[...]
Kind regards
Uffe
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 4/9] soc: qcom: geni-se: Remove OPP rate reset from resource deactivation
2026-08-27 17:59 ` [PATCH v2 4/9] soc: qcom: geni-se: Remove OPP rate reset from resource deactivation Praveen Talari
@ 2026-09-04 8:49 ` Konrad Dybcio
0 siblings, 0 replies; 18+ messages in thread
From: Konrad Dybcio @ 2026-09-04 8:49 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/27/26 7:59 PM, Praveen Talari wrote:
> Remove the dev_pm_opp_set_rate(se->dev, 0) call from
> geni_se_resources_deactivate().
>
> OPP resource management should be controlled by the consumer driver.
I believe the opposite was the original intent behind creating
these helpers..
> Additionally, clocks are already disabled by geni_se_clks_off(), making
> the OPP rate reset unnecessary during resource deactivation.
That is, on the other hand, a valid reason
Konrad
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 7/9] i2c: qcom-geni: Vote for SE clock rate using OPP
2026-08-27 17:59 ` [PATCH v2 7/9] i2c: qcom-geni: Vote for SE clock rate using OPP Praveen Talari
@ 2026-09-04 8:52 ` Konrad Dybcio
0 siblings, 0 replies; 18+ messages in thread
From: Konrad Dybcio @ 2026-09-04 8:52 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/27/26 7:59 PM, Praveen Talari wrote:
> The I2C driver currently assumes a fixed source clock selection and always
> programs SE_GENI_CLK_SEL to 0, which is not sufficient when the controller
> needs to switch between different source clocks.
>
> Add the source clock index and frequency to the I2C clock map entries and
> use them while configuring the controller. Request the required
> source clock rate through dev_pm_opp_set_rate() and program SE_GENI_CLK_SEL
> with the matching source index.
>
> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
> ---
[...]
> + dev_pm_opp_set_rate(dev, 0);
This and the below call are unnecessary, rate and enablement/disablement
of a clock are orthogonal operations
Konrad
> +
> return 0;
> }
>
> @@ -1236,6 +1249,12 @@ static int __maybe_unused geni_i2c_runtime_resume(struct device *dev)
> int ret = 0;
> struct geni_i2c_dev *gi2c = dev_get_drvdata(dev);
>
> + if (gi2c->clk_fld && gi2c->clk_fld->src_clk_freq) {
> + ret = dev_pm_opp_set_rate(dev, gi2c->clk_fld->src_clk_freq);
> + if (ret)
> + return ret;
> + }
> +
> if (gi2c->dev_data->power_on) {
> ret = gi2c->dev_data->power_on(&gi2c->se);
> if (ret)
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P
2026-09-04 7:56 ` Ulf Hansson
@ 2026-09-04 9:00 ` Konrad Dybcio
0 siblings, 0 replies; 18+ messages in thread
From: Konrad Dybcio @ 2026-09-04 9:00 UTC (permalink / raw)
To: Ulf Hansson, Praveen Talari
Cc: 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, Abel Vesa
On 9/4/26 9:56 AM, Ulf Hansson wrote:
> On Tue, Sep 1, 2026 at 6:48 PM Praveen Talari
> <praveen.talari@oss.qualcomm.com> wrote:
[...]
> So geni_se_clk_freq_match() is used by two consumer drivers today,
> drivers/spi/spi-geni-qcom.c and drivers/tty/serial/qcom_geni_serial.c.
>
> Beyond the $subject series, there will be even more consumer drivers
> that call these platform specific functions. As I said above, I don't
> think this is moving things in the right direction.
>
> If this can't be solved with generic frameworks (clocks and OPP),
> please clarify why so we can figure out a better way forward.
The way I read it, isn't geni_se_clk_freq_match() more or less
dev_pm_opp_find_freq_exact() called in a loop with an increasing
divider?
Konrad
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 3/9] soc: qcom: geni-se: Add helper to set SE clock rate via OPP
2026-08-27 17:59 ` [PATCH v2 3/9] soc: qcom: geni-se: Add helper to set SE clock rate via OPP Praveen Talari
@ 2026-09-04 9:01 ` Konrad Dybcio
0 siblings, 0 replies; 18+ messages in thread
From: Konrad Dybcio @ 2026-09-04 9:01 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/27/26 7:59 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.
[...]
> +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;
For !se->has_opp, this silently does nothing, which presumably
may have bad consequences if the caller is unaware
Konrad
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2026-09-04 9:01 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-27 17:59 [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Praveen Talari
2026-08-27 17:59 ` [PATCH v2 1/9] pmdomain: arm: Fix -EINVAL from scmi_pd_set_perf_state() on state 0 Praveen Talari
2026-09-01 14:31 ` Ulf Hansson
2026-08-27 17:59 ` [PATCH v2 2/9] soc: qcom: geni-se: Populate clk_perf_tbl with SE source clock frequencies from perf OPP table Praveen Talari
2026-08-27 17:59 ` [PATCH v2 3/9] soc: qcom: geni-se: Add helper to set SE clock rate via OPP Praveen Talari
2026-09-04 9:01 ` Konrad Dybcio
2026-08-27 17:59 ` [PATCH v2 4/9] soc: qcom: geni-se: Remove OPP rate reset from resource deactivation Praveen Talari
2026-09-04 8:49 ` Konrad Dybcio
2026-08-27 17:59 ` [PATCH v2 5/9] serial: qcom-geni: Use geni_se_set_rate() for source clock configuration Praveen Talari
2026-08-27 17:59 ` [PATCH v2 6/9] spi: qcom-geni: Use geni_se_set_rate() for setting source clock frequency Praveen Talari
2026-08-27 17:59 ` [PATCH v2 7/9] i2c: qcom-geni: Vote for SE clock rate using OPP Praveen Talari
2026-09-04 8:52 ` Konrad Dybcio
2026-08-27 17:59 ` [PATCH v2 8/9] i2c: qcom-geni: Use common GENI resource initialization helper Praveen Talari
2026-08-27 17:59 ` [PATCH v2 9/9] i2c: qcom-geni: Use geni_se_set_rate() for setting source clock frequency Praveen Talari
2026-09-01 14:52 ` [PATCH v2 0/9] soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P Ulf Hansson
2026-09-01 16:48 ` Praveen Talari
2026-09-04 7:56 ` Ulf Hansson
2026-09-04 9:00 ` Konrad Dybcio
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox