[PATCH 3/7] soc: qcom: geni-se: Add helper to set SE clock rate via OPP
Praveen Talari <[email protected]> Wed, 05 Aug 2026 01:27:41 +0530
| Newsgroups | gmane.linux.serial,gmane.linux.ports.arm.kernel,gmane.linux.power-management.general,gmane.linux.kernel,gmane.linux.ports.arm.msm,gmane.linux.kernel.spi.devel,gmane.linux.drivers.i2c |
|---|---|
| Message-ID | <20260805-derive_clk_perf_tbl_from_perf_domain_opp_table-v1-3-61171ab1cdce@oss.qualcomm.com> |
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 <[email protected]> --- 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