Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] stm32h7: Enable support for optional/alternate clocks #42097

Closed
wants to merge 19 commits into from

Conversation

erwango
Copy link
Member

@erwango erwango commented Jan 24, 2022

TL;DR

STM32 clock_control driver update (limited to H7 for now) to provide a way to configure alternate clocks on peripherals that support it:

    clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00001000>,  <- Existing, bus driven, "register" clock
             <&rcc STM32_SRC_PLL3_P SPI123_SEL(2)>;   <- Newly added alternate clock (PLL3_P output here)

This alternate clock source could be selected in peripheral driver thanks to new clock_control_configure() API:

	if (IS_ENABLED(STM32_SPI_OPT_CLOCK_SUPPORT) && (cfg->pclk_len > 1)) {
		if (clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
					    (clock_control_subsys_t) &cfg->pclken[1],
					    NULL) != 0) {
			LOG_ERR("Could not select alternate SPI source clock");
			return -EIO;
		}
	}

Goal

Aim of this work is to enable the use of an optional clock in a device configuration.
This is particularly required in case of STM32H7 based platform on which device clock configuration is usually based on 2 different clocks (cf #41650)

  • A register clock, required for device configuration, usually coming from APB/AHB bus.
  • A kernel clock, which will be used to clock the hardware block (and hence is the one driving the device frequency), typically derived from an alternate clck source (PLL output, fixed clock, ..)

Fixes #41650

Why it worked so far on H7

Device clock configuration used to be functional up to now since clock configuration was set so that APB clk and alternate device clk (the default reset one) were equivalent.

Secondary goal

Besides the initial goal, idea was to provide the basis to support equivalent functionalities on onther STM32 series, such as the possibility to provide an alternate clock to a peripheral. For instance, configuring LSE as the LPUART or LPTIM clock, or HSI48 as the USB clock.

Update of clock_control API (03/14):

Reworked to make use of new clock_control_configure() API, cf #43790

Implementation options:

Alternate clocks bindings

Additional/Alternate clocks could be fixed clocks (HSI, HSE, ..), PLL outputs (PLLX_P/Q/R), sysclock, ....
For all these clocks, I've decided to keep existing RCC device driver as the clock controller. As a consequence, the dt binding used to select a specific clock looks to:

	clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00001000>,  <- Existing, bus driven, "register" clock
		 <&rcc STM32_SRC_PLL3_P SPI123_SEL(2)>;   <- Newly added alternate clock (PLL3_P output here)

Another way to support this would have been to set up each potential clock source as a clock controler on its own and use the following binding:

	clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00001000>,  <- Existing, bus driven, "register" clock
		 <&pll3 pll_p_output SPI123_SEL(2)>;      <- Discarded binding option

I've discarded this second option because, to be consistent with the binding, this second option would require to instantiate each potential source clock as a device driver, each one implementing clock_control API. This would have had negative impact on code footprint, which could have been considered ok for STM32H7 series but problematic on "smaller" STM32 series.

Clock mux bindings

Complete solution requires to find a way to configure clock mux (as per_ck).

First option is to add a dedicated node descibing the clock mux. Its only property is to configure its clock input

&perck {
	clocks = <&rcc STM32_SRC_HSI_KER CKPER_SEL(0)>;
	status = "okay";
};

Works fine, main drawback is the cost (~220 bytes of flash)

A much simpler alternative was to add clock configuration directly to the clock consumer end node:

	clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00001000>,
		 <&rcc STM32_SRC_HSI_KER CKPER_SEL(0)>,
		 <&rcc STM32_SRC_CKPER SPI123_SEL(4)>;

Though, this proposal has 2 main drawbacks:

  • If board dts is poorly configured, 2 consumers of the same internal clock (per_ck here) could set conflicting configurations
  • This adds complexity on the consumers driver implementation side that should be able to differentiate between all these clocks

In the end the addition of a clock mux node device felt saner.

Dependencies

This work is based on:

Limitations and next steps:

  • Only STM32 SPI driver is made aware of this. All STM32 drivers should be updated to take this new clock config into account.
  • Extend to other STM32 series. This kernel clock is generally not available on other STM32 series, but most of this work can be reused to support the configuration of alternate peripheral clocks (like HSI on LPUART). This extension would first require a clock_control driver clean up similar to driver/clock_control: Clean up stm32h7 and stm32u5 drivers #41585.
  • It is not possible today to clock_off supplementary clocks as they potentially clocks multiple peripherals (or even the core itself). So, this most likely requires the use of power-domains

@github-actions github-actions bot added area: API Changes to public APIs area: Boards area: Devicetree area: Devicetree Binding PR modifies or adds a Device Tree binding area: Documentation area: SPI SPI bus area: Tests Issues related to a particular existing or missing test platform: STM32 ST Micro STM32 labels Jan 24, 2022
@erwango erwango requested review from ABOSTM and FRASTM January 24, 2022 16:32
@erwango
Copy link
Member Author

erwango commented Jan 24, 2022

@heinwessels, @r2r0, FYI

@erwango erwango changed the title stm32h7: Enable support for kernel clocks [POC|RFC]stm32h7: Enable support for kernel clocks Jan 24, 2022
@erwango erwango added the RFC Request For Comments: want input from the community label Jan 24, 2022
@erwango erwango changed the title [POC|RFC]stm32h7: Enable support for kernel clocks [POC|RFC] stm32h7: Enable support for kernel clocks Jan 24, 2022
@erwango erwango force-pushed the dev_h7_periph_clks branch from a22d2b8 to fa49f32 Compare January 25, 2022 08:16
@erwango erwango changed the title [POC|RFC] stm32h7: Enable support for kernel clocks [POC|RFC] stm32h7: Enable support for multiple/alternate clocks Jan 25, 2022
@erwango erwango changed the title [POC|RFC] stm32h7: Enable support for multiple/alternate clocks [POC|RFC] stm32h7: Enable support for optional/alternate clocks Jan 25, 2022
@erwango erwango force-pushed the dev_h7_periph_clks branch 8 times, most recently from 168bd7f to 258e232 Compare January 31, 2022 16:05
@erwango
Copy link
Member Author

erwango commented Feb 4, 2022

Added clock mux support following discussion on L5 case here

@erwango erwango force-pushed the dev_h7_periph_clks branch 2 times, most recently from 8c9c150 to 703e0a2 Compare March 3, 2022 15:05
erwango added 15 commits March 23, 2022 15:35
Set bus binding values using registers offset values.
As a consequence update driver to take this into account
in clock_on and clock_off functions.

Signed-off-by: Erwan Gouriou <[email protected]>
Rework test to additionally test clock_on and clock_off APIs

Signed-off-by: Erwan Gouriou <[email protected]>
Add support for alternate clocks configuration.

Signed-off-by: Erwan Gouriou <[email protected]>
Add a test case using PLL3P output as SPI clock source.
Modify the test source to allow testing various tests sources.

Signed-off-by: Erwan Gouriou <[email protected]>
On some series (H7, U5), it is possible define clock configuration
with disabled PLL outputs.
In that case, it is legit that matching pll property is not available.
Define corresponding STM32_PLLX_Y_DIVISOR macros using DT_PROP_OR
to avoid build issues in case prop is not available.

Signed-off-by: Erwan Gouriou <[email protected]>
Cleanup the test a little bit to give some clarity.

Signed-off-by: Erwan Gouriou <[email protected]>
Add a DT based macros to be used by stm32 device drivers to
populate pclken[] arrays at build time.

Signed-off-by: Erwan Gouriou <[email protected]>
Make use of STM32_DT_CLOCKS_ macros to have the test work conditionally
based on alt clock presence.

Signed-off-by: Erwan Gouriou <[email protected]>
Enable SPI on nucleo_h723zg board

Signed-off-by: Erwan Gouriou <[email protected]>
Add support for an alternate clock. If available,
alternate clock is enabled and used to get the
device clock rate.

Fixes zephyrproject-rtos#41650

Signed-off-by: Erwan Gouriou <[email protected]>
Add STM32 clock mux binding.
Only property of a node using such compatible is to
select a clock input.

Signed-off-by: Erwan Gouriou <[email protected]>
Add a clock multiplexer driver.
Its only function is to select a clock input.

Signed-off-by: Erwan Gouriou <[email protected]>
Add perck clock-mux node as disabled by default and
the include bindings helping to select it.

Signed-off-by: Erwan Gouriou <[email protected]>
Add support for CKPER clock mux.

Signed-off-by: Erwan Gouriou <[email protected]>
Add 2 scenarios to test CKPER used as a clock source.

Signed-off-by: Erwan Gouriou <[email protected]>
@erwango erwango force-pushed the dev_h7_periph_clks branch from 549ced5 to 3380bba Compare March 23, 2022 14:39
warasilapm added a commit to warasilapm/zephyr that referenced this pull request May 4, 2022
The STM32u% series of processors has a unique set of clock sources for
the FDCAN peripheral. This brings the selection in line with the
existing can_stm32fd clock selection Kconfigs.

This change was tested on a proprietary board using the STM32U5 series
which exposes the CAN pins of the SOC using a transciever on a live CAN
bus as well as on the nucleo_g474re board from ST in loopback mode.

HSE and PLL1Q tests run and all passed.

PLL2P is not currently supported by the clock drivers for STM32U5, and
as such is currently untested. When this support is added, the driver
should be able to use this clock without issue.

When changes from zephyrproject-rtos#42097 are merged this fix should be deprecated in
favor of using the methods outlined there.

Signed-off-by: Peter Maxwell Warasila <[email protected]>
MaureenHelm pushed a commit that referenced this pull request May 5, 2022
The STM32u% series of processors has a unique set of clock sources for
the FDCAN peripheral. This brings the selection in line with the
existing can_stm32fd clock selection Kconfigs.

This change was tested on a proprietary board using the STM32U5 series
which exposes the CAN pins of the SOC using a transciever on a live CAN
bus as well as on the nucleo_g474re board from ST in loopback mode.

HSE and PLL1Q tests run and all passed.

PLL2P is not currently supported by the clock drivers for STM32U5, and
as such is currently untested. When this support is added, the driver
should be able to use this clock without issue.

When changes from #42097 are merged this fix should be deprecated in
favor of using the methods outlined there.

Signed-off-by: Peter Maxwell Warasila <[email protected]>
@erwango
Copy link
Member Author

erwango commented May 11, 2022

Closing, now that #45053 is merged

@erwango erwango closed this May 11, 2022
@erwango erwango deleted the dev_h7_periph_clks branch January 19, 2024 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: API Changes to public APIs area: Boards area: Devicetree Binding PR modifies or adds a Device Tree binding area: Devicetree area: Documentation area: SPI SPI bus area: Tests Issues related to a particular existing or missing test platform: STM32 ST Micro STM32 RFC Request For Comments: want input from the community
Projects
None yet
Development

Successfully merging this pull request may close these issues.

STM32H7 SPI123 incorrect clock source used for prescaler calculation
2 participants