| Message ID | 20260827-derive_clk_perf_tbl_from_perf_domain_opp_table-v2-0-091697dbeb02@oss.qualcomm.com |
|---|---|
| Headers | show |
| Series | soc: qcom: geni: Derive SE clock configuration from OPP table on SA8255P | expand |
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> >
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> >>
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
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
Hi Ulf, Thank you for review. On 04-09-2026 13:26, Ulf Hansson wrote: > 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? I agree that protocol drivers should ideally rely on generic frameworks and avoid platform-specific resource management logic. The challenge here is that the OPP framework currently provides a mechanism to select and apply an operating point, but it does not expose the GENI-specific information required for GSI TRE programming. In addition to selecting an operating point, the GSI path needs to derive the corresponding SE source clock frequency, clock index and divider values, as these fields must be programmed explicitly into the TRE descriptors consumed by the hardware. Today geni_se_clk_freq_match() serves two purposes: 1. Match a requested protocol frequency against the set of supported SE source clock frequencies. 2. Derive the GENI-specific parameters (source clock, clock index and divider) associated with the selected frequency. While OPP can manage clock and performance state selection, it does not currently provide an interface to obtain these GENI-specific clock-configuration parameters. This is why the existing GENI helper is still required. The intent of this series is not to introduce another platform-specific clock-selection path. Rather, it allows firmware-managed platforms to use the same clock-matching infrastructure already used on clock-managed platforms by deriving the clock-performance table from the OPP data. I have removed platform specific set_rate callback in patches for SPI [1] and Serial [2] [1]https://lore.kernel.org/all/20260827-derive_clk_perf_tbl_from_perf_domain_opp_table-v2-6-091697dbeb02@oss.qualcomm.com/ [2]https://lore.kernel.org/all/20260827-derive_clk_perf_tbl_from_perf_domain_opp_table-v2-5-091697dbeb02@oss.qualcomm.com/ > >> 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? devm_pm_opp_set_config() with a .clk_name lets dev_pm_opp_set_rate() internally call clk_set_rate() on a named clk — but that requires an actual clk provider backing the device. On SA8255P there is no Linux clk object for the SE source clock at all: firmware only exposes a set of supported frequencies as OPP levels on the performance-domain device, not as a rate-settable clock. So there's nothing for devm_pm_opp_set_config()'s clk-integration to attach to — the OPP table here isn't describing a DVFS operating point of an existing clock, it's standing in for the clock itself. > >>>> 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. I believe above response can answered your query. Thanks, Praveen Talari > > [...] > > Kind regards > Uffe
Hi Konrad, On 04-09-2026 14:30, Konrad Dybcio wrote: > 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? Currently, geni_se_clk_freq_match() relies on clk_perf_tbl to determine the source clock index and divider corresponding to a requested frequency. On Linux-managed platforms, clk_perf_tbl is populated by geni_se_clk_tbl_get(), which enumerates the supported source clock frequencies using clk_round_rate(). int geni_se_clk_freq_match(struct geni_se *se, unsigned long req_freq, unsigned int *index, unsigned long *res_freq, bool exact) { [...] num_clk_levels = geni_se_clk_tbl_get(se, &tbl); if (num_clk_levels < 0) return num_clk_levels; [...] best_delta = ULONG_MAX; for (i = 0; i < num_clk_levels; i++) { divider = DIV_ROUND_UP(tbl[i], req_freq); new_delta = req_freq - tbl[i] / divider; if (new_delta < best_delta) { /* We have a new best! */ *index = i; *res_freq = tbl[i]; /* If the new best is exact then we're done */ if (new_delta == 0) return 0; /* Record how close we got */ best_delta = new_delta; } } [...] return 0; } On firmware-managed platforms, clk_perf_tbl is populated from the performance-domain OPP table during domain attachment, allowing geni_se_clk_freq_match() to operate on the same source clock frequency information irrespective of how the underlying resources are managed. As a result, the frequency matching logic, including source clock selection and divider calculation, remains common across both Linux-managed and firmware-managed configurations, while only the mechanism used to apply the selected rate differs. Thanks, Praveen Talari > > Konrad
On 9/11/26 7:33 PM, Praveen Talari wrote: > Hi Konrad, > > On 04-09-2026 14:30, Konrad Dybcio wrote: >> 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? > Currently, geni_se_clk_freq_match() relies on clk_perf_tbl to > determine the source clock index and divider corresponding to > a requested frequency. So I think the part that blocks going in the direction I suggested is that the index and divider values you mentioned are then required to be fed into some GENI-internal registers: -- drivers/spi/spi-geni-qcom.c clk_sel = idx & CLK_SEL_MSK; m_clk_cfg = (div << CLK_DIV_SHFT) | SER_CLK_EN; writel(clk_sel, se->base + SE_GENI_CLK_SEL); writel(m_clk_cfg, se->base + GENI_SER_M_CLK_CFG); and it seems like every protocol driver does some NIH things to take care of that.. perhaps this bit could be moved up to the common geni-se layer (Mukesh, are there some historical reasons for this being handled in proto drivers?) I think this may just be an effect of how the hardware is wired up - the ""DFS"" clocks that feed into the serial engines are partly set up in the clock controller driver, but then there's this bit: -- drivers/clk/qcom/clk-rcg2.c clk_rcg2_enable_dfs() /* * Rate changes with consumer writing a register in * their own I/O region */ init->flags |= CLK_GET_RATE_NOCACHE; init->ops = &clk_rcg2_dfs_ops; which is the writes i mentioned above. At a glance, plumbing this into OPP would require making GENI SEs self-consumed clock providers, which sounds no less messy Konrad
Hi Konrad, On 22-09-2026 18:36, Konrad Dybcio wrote: > On 9/11/26 7:33 PM, Praveen Talari wrote: >> Hi Konrad, >> >> On 04-09-2026 14:30, Konrad Dybcio wrote: >>> 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? >> Currently, geni_se_clk_freq_match() relies on clk_perf_tbl to >> determine the source clock index and divider corresponding to >> a requested frequency. > So I think the part that blocks going in the direction I > suggested is that the index and divider values you mentioned > are then required to be fed into some GENI-internal registers: > > -- drivers/spi/spi-geni-qcom.c > clk_sel = idx & CLK_SEL_MSK; > m_clk_cfg = (div << CLK_DIV_SHFT) | SER_CLK_EN; > writel(clk_sel, se->base + SE_GENI_CLK_SEL); > writel(m_clk_cfg, se->base + GENI_SER_M_CLK_CFG); > > and it seems like every protocol driver does some NIH things > to take care of that.. perhaps this bit could be moved up to > the common geni-se layer (Mukesh, are there some historical > reasons for this being handled in proto drivers?) Just to confirm, would you like the clock programming logic to be moved into the common GENI driver (geni-se.c)? If yes, I can take that up in a separate series. Thanks, Praveen Talari > > I think this may just be an effect of how the hardware is wired > up - the ""DFS"" clocks that feed into the serial engines are > partly set up in the clock controller driver, but then there's > this bit: > > -- drivers/clk/qcom/clk-rcg2.c > clk_rcg2_enable_dfs() > /* > * Rate changes with consumer writing a register in > * their own I/O region > */ > init->flags |= CLK_GET_RATE_NOCACHE; > init->ops = &clk_rcg2_dfs_ops; > > which is the writes i mentioned above. > > At a glance, plumbing this into OPP would require making GENI > SEs self-consumed clock providers, which sounds no less messy > > Konrad
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>