mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-05 22:41:44 +00:00
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>
This commit is contained in:
committed by
chrome-bot
parent
053cb4bb24
commit
7eae5a320f
@@ -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)
|
||||
{
|
||||
/*
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user