diff options
author | Wei-Ning Huang <wnhuang@google.com> | 2017-06-19 11:42:04 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-06-21 01:02:59 -0700 |
commit | 7eae5a320f019a2d8a0b40c060a802c0e7e03c93 (patch) | |
tree | 48b8632984a34ed9c554a3adb4f5e0f502008c05 | |
parent | 053cb4bb24a948f917b78e7e17ffdff8733d01a0 (diff) | |
download | chrome-ec-7eae5a320f019a2d8a0b40c060a802c0e7e03c93.tar.gz |
stm32f4: clock stm32f412 at 96MHz
On stm32f412, AHB prescaler must be 1 in order for stm32f412 to be
clocked at greater than 50MHz. APBX prescaler must be 2 so the clocks
can be in the right range. When APBX prescaler != 1, it results in 2x
timer clocks on both APB1 and APB2. We added a new
clock_get_timer_freq() function for stm32 to get timer specific clock
frequency so we can return 2x timer clocks when APBX != 1.
Flash latencies also need to be changed when we clock at 96MHz, the
FLASH_ACR_LATENCY defines are moved into the variant-specific switches
so each board can defined latency when setting CPU clocks.
BUG=b:38077127
TEST=`make BOARD=rose -j`, touch performance improved by 2x.
Change-Id: Ieb211ad80c168d3f57e72a8d16b954b703ee1444
Reviewed-on: https://chromium-review.googlesource.com/539375
Commit-Ready: Wei-Ning Huang <wnhuang@chromium.org>
Tested-by: Wei-Ning Huang <wnhuang@chromium.org>
Reviewed-by: Rong Chang <rongchang@chromium.org>
-rw-r--r-- | chip/stm32/clock-f.c | 6 | ||||
-rw-r--r-- | chip/stm32/clock-f.h | 3 | ||||
-rw-r--r-- | chip/stm32/clock-stm32f4.c | 15 | ||||
-rw-r--r-- | chip/stm32/clock-stm32l.c | 5 | ||||
-rw-r--r-- | chip/stm32/clock-stm32l4.c | 5 | ||||
-rw-r--r-- | chip/stm32/hwtimer.c | 3 | ||||
-rw-r--r-- | chip/stm32/hwtimer32.c | 11 | ||||
-rw-r--r-- | chip/stm32/registers.h | 16 |
8 files changed, 54 insertions, 10 deletions
diff --git a/chip/stm32/clock-f.c b/chip/stm32/clock-f.c index e9737ddb14..84dbd45d2a 100644 --- a/chip/stm32/clock-f.c +++ b/chip/stm32/clock-f.c @@ -153,6 +153,12 @@ void __rtc_alarm_irq(void) } DECLARE_IRQ(STM32_IRQ_RTC_ALARM, __rtc_alarm_irq, 1); +__attribute__((weak)) +int clock_get_timer_freq(void) +{ + return clock_get_freq(); +} + void clock_init(void) { /* diff --git a/chip/stm32/clock-f.h b/chip/stm32/clock-f.h index 187bda916d..a75bcb8ccd 100644 --- a/chip/stm32/clock-f.h +++ b/chip/stm32/clock-f.h @@ -67,4 +67,7 @@ void clock_init(void); /* Init high speed clock config */ void config_hispeed_clock(void); +/* Get timer clock frequency (for STM32 only) */ +int clock_get_timer_freq(void); + #endif /* __CROS_EC_CLOCK_F_H */ diff --git a/chip/stm32/clock-stm32f4.c b/chip/stm32/clock-stm32f4.c index 353718f564..3c9f79f4c7 100644 --- a/chip/stm32/clock-stm32f4.c +++ b/chip/stm32/clock-stm32f4.c @@ -109,10 +109,12 @@ void config_hispeed_clock(void) * For STM32F412: max 50 MHz */ /* AHB Prescalar */ - ahbpre = 0x8; /* AHB = system clock / 2 */ - /* NOTE: If apbXpre is not 0, timers are x2 clocked. RM0390 Fig. 13 */ - apb1pre = 0; /* APB1 = AHB */ - apb2pre = 0; /* APB2 = AHB */ + ahbpre = STM32F4_AHB_PRE; + /* NOTE: If apbXpre is not 0, timers are x2 clocked. RM0390 Fig. 13 + * One should define STM32F4_TIMER_CLOCK when apbXpre is not 0. + * STM32F4_TIMER_CLOCK is used for hwtimer in EC. */ + apb1pre = STM32F4_APB1_PRE; + apb2pre = STM32F4_APB2_PRE; #ifdef CONFIG_STM32_CLOCK_HSE_HZ /* RTC clock = 1MHz */ @@ -175,6 +177,11 @@ void config_hispeed_clock(void) #endif } +int clock_get_timer_freq(void) +{ + return STM32F4_TIMER_CLOCK; +} + int clock_get_freq(void) { return STM32F4_IO_CLOCK; diff --git a/chip/stm32/clock-stm32l.c b/chip/stm32/clock-stm32l.c index 709d53f902..7125821040 100644 --- a/chip/stm32/clock-stm32l.c +++ b/chip/stm32/clock-stm32l.c @@ -50,6 +50,11 @@ int clock_get_freq(void) return freq; } +int clock_get_timer_freq(void) +{ + return clock_get_freq(); +} + void clock_wait_bus_cycles(enum bus_type bus, uint32_t cycles) { volatile uint32_t dummy __attribute__((unused)); diff --git a/chip/stm32/clock-stm32l4.c b/chip/stm32/clock-stm32l4.c index 18a23b8d16..c9042d10c4 100644 --- a/chip/stm32/clock-stm32l4.c +++ b/chip/stm32/clock-stm32l4.c @@ -37,6 +37,11 @@ int clock_get_freq(void) return freq; } +int clock_get_timer_freq(void) +{ + return clock_get_freq(); +} + void clock_wait_bus_cycles(enum bus_type bus, uint32_t cycles) { volatile uint32_t dummy __attribute__((unused)); diff --git a/chip/stm32/hwtimer.c b/chip/stm32/hwtimer.c index 89afe1b039..5844c83d81 100644 --- a/chip/stm32/hwtimer.c +++ b/chip/stm32/hwtimer.c @@ -6,6 +6,7 @@ /* Hardware timers driver */ #include "clock.h" +#include "clock-f.h" #include "common.h" #include "hooks.h" #include "hwtimer.h" @@ -304,7 +305,7 @@ static void update_prescaler(void) * prescaler counter ticks down, or if forced via EGR). */ STM32_TIM_PSC(TIM_CLOCK_MSB) = 0; - STM32_TIM_PSC(TIM_CLOCK_LSB) = (clock_get_freq() / SECOND) - 1; + STM32_TIM_PSC(TIM_CLOCK_LSB) = (clock_get_timer_freq() / SECOND) - 1; } DECLARE_HOOK(HOOK_FREQ_CHANGE, update_prescaler, HOOK_PRIO_DEFAULT); diff --git a/chip/stm32/hwtimer32.c b/chip/stm32/hwtimer32.c index 0bd6fa12c9..cf2247157f 100644 --- a/chip/stm32/hwtimer32.c +++ b/chip/stm32/hwtimer32.c @@ -6,6 +6,7 @@ /* Hardware 32-bit timer driver */ #include "clock.h" +#include "clock-f.h" #include "common.h" #include "hooks.h" #include "hwtimer.h" @@ -135,7 +136,7 @@ static void update_prescaler(void) * Pre-scaler value : * the timer is incrementing every microsecond */ - STM32_TIM_PSC(TIM_CLOCK32) = (clock_get_freq() / SECOND) - 1; + STM32_TIM_PSC(TIM_CLOCK32) = (clock_get_timer_freq() / SECOND) - 1; /* * Forcing reloading the pre-scaler, * but try to maintain a sensible time-keeping while triggering @@ -162,7 +163,8 @@ static void update_prescaler(void) #ifdef CONFIG_WATCHDOG_HELP /* Watchdog timer runs at 1KHz */ - STM32_TIM_PSC(TIM_WATCHDOG) = (clock_get_freq() / SECOND * MSEC) - 1; + STM32_TIM_PSC(TIM_WATCHDOG) = + (clock_get_timer_freq() / SECOND * MSEC)- 1; #endif /* CONFIG_WATCHDOG_HELP */ } DECLARE_HOOK(HOOK_FREQ_CHANGE, update_prescaler, HOOK_PRIO_DEFAULT); @@ -188,7 +190,7 @@ int __hw_clock_source_init(uint32_t start_t) STM32_TIM32_ARR(TIM_CLOCK32) = 0xffffffff; /* Update prescaler to increment every microsecond */ - STM32_TIM_PSC(TIM_CLOCK32) = (clock_get_freq() / SECOND) - 1; + STM32_TIM_PSC(TIM_CLOCK32) = (clock_get_timer_freq() / SECOND) - 1; /* Reload the pre-scaler */ STM32_TIM_EGR(TIM_CLOCK32) = 0x0001; @@ -258,7 +260,8 @@ void hwtimer_setup_watchdog(void) STM32_TIM_ARR(TIM_WATCHDOG) = CONFIG_AUX_TIMER_PERIOD_MS; /* Update prescaler: watchdog timer runs at 1KHz */ - STM32_TIM_PSC(TIM_WATCHDOG) = (clock_get_freq() / SECOND * MSEC) - 1; + STM32_TIM_PSC(TIM_WATCHDOG) = + (clock_get_timer_freq() / SECOND * MSEC) - 1; /* Reload the pre-scaler */ STM32_TIM_EGR(TIM_WATCHDOG) = 0x0001; diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h index 7616ea0355..7be2059486 100644 --- a/chip/stm32/registers.h +++ b/chip/stm32/registers.h @@ -957,6 +957,11 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32F4_VCO_CLOCK 336000000 #define STM32F4_HSI_CLOCK 16000000 #define STM32F4_LSI_CLOCK 32000 +#define STM32F4_TIMER_CLOCK STM32F4_IO_CLOCK +#define STM32F4_AHB_PRE 0x8 +#define STM32F4_APB1_PRE 0x0 +#define STM32F4_APB2_PRE 0x0 +#define STM32_FLASH_ACR_LATENCY (1 << 0) #elif defined(CHIP_VARIANT_STM32F412) /* Required or recommended clocks for stm32f412 */ @@ -967,6 +972,11 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32F4_VCO_CLOCK 384000000 #define STM32F4_HSI_CLOCK 16000000 #define STM32F4_LSI_CLOCK 32000 +#define STM32F4_TIMER_CLOCK (STM32F4_IO_CLOCK * 2) +#define STM32F4_AHB_PRE 0x0 +#define STM32F4_APB1_PRE 0x4 +#define STM32F4_APB2_PRE 0x4 +#define STM32_FLASH_ACR_LATENCY (3 << 0) #elif defined(CHIP_VARIANT_STM32F411) /* Required or recommended clocks for stm32f411 */ @@ -977,6 +987,11 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32F4_VCO_CLOCK 384000000 #define STM32F4_HSI_CLOCK 16000000 #define STM32F4_LSI_CLOCK 32000 +#define STM32F4_TIMER_CLOCK STM32F4_IO_CLOCK +#define STM32F4_AHB_PRE 0x8 +#define STM32F4_APB1_PRE 0x0 +#define STM32F4_APB2_PRE 0x0 +#define STM32_FLASH_ACR_LATENCY (1 << 0) #else #error "No valid clocks defined" @@ -1400,7 +1415,6 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t; #define STM32_FLASH_REGS_BASE 0x40023c00 #define STM32_FLASH_ACR REG32(STM32_FLASH_REGS_BASE + 0x00) -#define STM32_FLASH_ACR_LATENCY (1 << 0) #define STM32_FLASH_ACR_SHIFT 0 #define STM32_FLASH_ACR_LAT_MASK 0xf #define STM32_FLASH_ACR_PRFTEN (1 << 8) |