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

Decouple timers from system clock #16958

Merged
merged 33 commits into from
Jul 24, 2019

Conversation

carlescufi
Copy link
Member

@carlescufi carlescufi commented Jun 20, 2019

Second split out from #16469. Includes #16957.
Do not merge until #16957 is merged

The clock control initialization code used system clock
frequency as a CPU clock frequency. This commit corrects
that by obtaining the needed value from DTS.

Signed-off-by: Piotr Zięcik <[email protected]>
The log_backend_swo used system clock frequency
as a base for SWO clock calculation. This commit
corrects that by obtaining the needed value from DTS.

Signed-off-by: Piotr Zięcik <[email protected]>
The spi_dw driver used system clock frequency
as a base for SPI bus frequency calculation.
This commit corrects that by obtaining the needed value from DTS.

Signed-off-by: Piotr Zięcik <[email protected]>
The uart_cmsdk_apb driver used system clock frequency
as a base for baudrate calculation. This commit corrects
that by obtaining the needed value from DTS.

Signed-off-by: Piotr Zięcik <[email protected]>
The uart_pl011 driver used system clock frequency
as a base for baudrate calculation. This commit corrects
that by obtaining the needed value from DTS.

Signed-off-by: Piotr Zięcik <[email protected]>
The uart_cc32xx driver used system clock frequency
as a base for baudrate calculation. This commit corrects
that by obtaining the needed value from DTS.

Signed-off-by: Piotr Zięcik <[email protected]>
The uart_msp432p4xx driver used system clock frequency
as a base for baudrate calculation. This commit corrects
that by obtaining the needed value from DTS.

Signed-off-by: Piotr Zięcik <[email protected]>
The uart_qmsi driver used system clock frequency
as a base for baudrate calculation. This commit corrects
that by obtaining the needed value from DTS.

Signed-off-by: Piotr Zięcik <[email protected]>
The uart_stellaris driver used system clock frequency
as a base for baudrate calculation. This commit corrects
that by obtaining the needed value from DTS.

Signed-off-by: Piotr Zięcik <[email protected]>
The uart_cc13xx_cc26xx driver used system clock frequency
as a base for baudrate calculation. This commit corrects
that by obtaining the needed value from DTS.

Signed-off-by: Piotr Zięcik <[email protected]>
The wdog_cmsdk_apb driver used system clock frequency
as a base for timeout calculation. This commit corrects
that by obtaining the needed value from DTS.

Signed-off-by: Piotr Zięcik <[email protected]>
The adc_stm32 driver used system timer frequency as a base for
busy-wait delay calculation. This commit corrects that by obtaining
the needed value from SystemCoreClock variable.

Signed-off-by: Piotr Zięcik <[email protected]>
This commit adds the kernel.h include in order to provide
sys_clock_hw_cycles_per_sec() declaration.

Signed-off-by: Piotr Zięcik <[email protected]>
@erwango
Copy link
Member

erwango commented Jul 22, 2019

@galak

@erwango drivers/adc/adc_stm32.c why use SystemCoreClock?

We use SystemCoreClock as on STM devices clock freq changes between boot time and run time. SystemCoreClock is updated to hold the current frequency. Note that frequency change happens only at clock_control driver init:

  • Default boot time frequency use to be a default low speed freq (SystemCoreClock is set in soc.c)
  • High speed freq is set at clock_control driver init when configuring RCC IP (PLL configuration for instance). SystemCoreClock is then updated to the configured freq.

@carlescufi carlescufi removed the DNM This PR should not be merged (Do Not Merge) label Jul 22, 2019
@galak
Copy link
Collaborator

galak commented Jul 22, 2019

We use SystemCoreClock as on STM devices clock freq changes between boot time and run time. SystemCoreClock is updated to hold the current frequency. Note that frequency change happens only at clock_control driver init:

  • Default boot time frequency use to be a default low speed freq (SystemCoreClock is set in soc.c)
  • High speed freq is set at clock_control driver init when configuring RCC IP (PLL configuration for instance). SystemCoreClock is then updated to the configured freq.

So does that mean sys_clock_hw_cycles_per_sec will report the wrong thing?

@erwango
Copy link
Member

erwango commented Jul 23, 2019

@galak

So does that mean sys_clock_hw_cycles_per_sec will report the wrong thing?

This is indeed the case before clock_control driver init (done before kernel init).
So, looking into it more, I don't think we should face many issues using sys_clock_hw_cycles_per_sec instead of SystemCoreClock.

Also, practically, I'm not 100% sure CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC holds the correct information (since it was not used). So it would have to be checked vs boards clock configuration.

@erwango
Copy link
Member

erwango commented Jul 23, 2019

@galak

Anyway, point is for now STM32 don't use CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, directly or indirectly (since sys_clock_hw_cycles_per_sec is still using CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC value), so we're in line with current PR.

I agree STM32 should also move to clock_control configuration to DT, and eventually get rid of SystemCoreClock and use sys_clock_hw_cycles_per_sec instead (once it will return dt value and/or able to return run time updated frequency). But I don't think this should block current PR.

@galak
Copy link
Collaborator

galak commented Jul 23, 2019

Do any of these still need cleaning up:

drivers/clock_control/clock_stm32_ll_common.c:	 * SystemCoreClock is preferred to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
drivers/clock_control/clock_stm32_ll_h7.c:	 * SystemCoreClock is preferred to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
drivers/clock_control/clock_stm32_ll_h7.c:	SysTick_Config(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000);
drivers/clock_control/clock_stm32_ll_h7.c:	SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
drivers/timer/Kconfig:	  TSC frequency to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC (the local APIC
drivers/timer/Kconfig:	  value of CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC will be used instead;
drivers/timer/apic_timer.c: * CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=<hz> must contain the frequency seen
drivers/timer/apic_timer.c: *     the TSC frequency to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC. This can be
drivers/timer/apic_timer.c:	(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
drivers/timer/rv32m1_lptmr_timer.c:    (MHZ(8) != CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC)
include/sys_clock.h:	return CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
include/sys_clock.h:	(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC == 0)
include/sys_clock.h:	(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC % CONFIG_SYS_CLOCK_TICKS_PER_SEC)
kernel/timeout.c:int z_clock_hw_cycles_per_sec = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
subsys/testsuite/ztest/include/ztest.h:#define CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC 10000000
tests/benchmarks/boot_time/testcase.yaml:    filter: CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC >= 1000000

@carlescufi
Copy link
Member Author

Do any of these still need cleaning up:

drivers/clock_control/clock_stm32_ll_common.c:	 * SystemCoreClock is preferred to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
drivers/clock_control/clock_stm32_ll_h7.c:	 * SystemCoreClock is preferred to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
drivers/clock_control/clock_stm32_ll_h7.c:	SysTick_Config(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000);
drivers/clock_control/clock_stm32_ll_h7.c:	SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
drivers/timer/Kconfig:	  TSC frequency to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC (the local APIC
drivers/timer/Kconfig:	  value of CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC will be used instead;
drivers/timer/apic_timer.c: * CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=<hz> must contain the frequency seen
drivers/timer/apic_timer.c: *     the TSC frequency to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC. This can be
drivers/timer/apic_timer.c:	(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
drivers/timer/rv32m1_lptmr_timer.c:    (MHZ(8) != CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC)
include/sys_clock.h:	return CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
include/sys_clock.h:	(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC == 0)
include/sys_clock.h:	(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC % CONFIG_SYS_CLOCK_TICKS_PER_SEC)
kernel/timeout.c:int z_clock_hw_cycles_per_sec = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
subsys/testsuite/ztest/include/ztest.h:#define CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC 10000000
tests/benchmarks/boot_time/testcase.yaml:    filter: CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC >= 1000000

From what I can tell, no, but we need to confirm it. Since Piotr is away what I will do is merge this PR to avoid it getting stale, and make sure he takes a look at the list once he's back.

@carlescufi carlescufi merged commit 4fc2445 into zephyrproject-rtos:master Jul 24, 2019
@pizi-nordic
Copy link
Collaborator

./drivers/clock_control/clock_stm32_ll_common.c:         * SystemCoreClock is preferred to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
./drivers/clock_control/clock_stm32_ll_h7.c:     * SystemCoreClock is preferred to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
./drivers/clock_control/clock_stm32_ll_h7.c:    SysTick_Config(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000);
./drivers/clock_control/clock_stm32_ll_h7.c:    SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;

The code above configures the clocking tree. Ideally, the information to perform this task should be taken from DTS, not the CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC. On the other hand, it also configures SysTick, which has to be set basing on CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC. I do not know STM SoC enough to say if the two things mentioned above could be easily decoupled.

./drivers/timer/Kconfig:          TSC frequency to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC (the local APIC
./drivers/timer/Kconfig:          value of CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC will be used instead;
./drivers/timer/apic_timer.c: * CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=<hz> must contain the frequency seen
./drivers/timer/apic_timer.c: *     the TSC frequency to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC. This can be
./drivers/timer/apic_timer.c:   (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
./drivers/timer/mchp_xec_rtos_timer.c:BUILD_ASSERT_MSG(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC == 32768,
./drivers/timer/mchp_xec_rtos_timer.c: * CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=<hz> must be set to 32768.
./drivers/timer/mchp_xec_rtos_timer.c:  (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
./drivers/timer/mchp_xec_rtos_timer.c:#define CPT1000 ((CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC * 1000UL) \
./drivers/timer/rv32m1_lptmr_timer.c:    (MHZ(8) != CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC)

./include/sys_clock.h:  return CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
./include/sys_clock.h:  (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC == 0)
./include/sys_clock.h:  (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC % CONFIG_SYS_CLOCK_TICKS_PER_SEC)

./kernel/timeout.c:int z_clock_hw_cycles_per_sec = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;

These are parts of system timer implementation. The value of CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC has to be known there in order to configure hardware for given frequency.

./subsys/testsuite/ztest/include/ztest.h:#define CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC 10000000

Here I do not know why the value of CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC is used. Maybe someone knowing ztest will tell us why this is not taken form the board configuration.

./tests/benchmarks/boot_time/testcase.yaml:    filter: CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC >= 1000000

This looks like hack ensuring precise measurement of time. I am not sure it this is still needed after @andyross fixes in the area.

@pabigot pabigot removed the dev-review To be discussed in dev-review meeting label Oct 24, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants