summaryrefslogtreecommitdiff
path: root/chip/stm32/clock-stm32f0.c
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-11-04 12:11:58 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-05 04:22:34 +0000
commit252457d4b21f46889eebad61d4c0a65331919cec (patch)
tree01856c4d31d710b20e85a74c8d7b5836e35c3b98 /chip/stm32/clock-stm32f0.c
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-stabilize-14532.B-ish.tar.gz
In the interest of making long-term branch maintenance incur as little technical debt on us as possible, we should not maintain any files on the branch we are not actually using. This has the added effect of making it extremely clear when merging CLs from the main branch when changes have the possibility to affect us. The follow-on CL adds a convenience script to actually pull updates from the main branch and generate a CL for the update. BUG=b:204206272 BRANCH=ish TEST=make BOARD=arcada_ish && make BOARD=drallion_ish Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I17e4694c38219b5a0823e0a3e55a28d1348f4b18 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262038 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Diffstat (limited to 'chip/stm32/clock-stm32f0.c')
-rw-r--r--chip/stm32/clock-stm32f0.c503
1 files changed, 0 insertions, 503 deletions
diff --git a/chip/stm32/clock-stm32f0.c b/chip/stm32/clock-stm32f0.c
deleted file mode 100644
index 0f63bdd394..0000000000
--- a/chip/stm32/clock-stm32f0.c
+++ /dev/null
@@ -1,503 +0,0 @@
-/* Copyright 2014 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* Clocks and power management settings */
-
-#include "chipset.h"
-#include "clock.h"
-#include "clock-f.h"
-#include "common.h"
-#include "console.h"
-#include "cpu.h"
-#include "hooks.h"
-#include "hwtimer.h"
-#include "registers.h"
-#include "system.h"
-#include "task.h"
-#include "timer.h"
-#include "uart.h"
-#include "util.h"
-
-/* Console output macros */
-#define CPUTS(outstr) cputs(CC_CLOCK, outstr)
-#define CPRINTS(format, args...) cprints(CC_CLOCK, format, ## args)
-
-/* use 48Mhz USB-synchronized High-speed oscillator */
-#define HSI48_CLOCK 48000000
-
-/* use PLL at 38.4MHz as system clock. */
-#define PLL_CLOCK 38400000
-
-/* Low power idle statistics */
-#ifdef CONFIG_LOW_POWER_IDLE
-static int idle_sleep_cnt;
-static int idle_dsleep_cnt;
-static uint64_t idle_dsleep_time_us;
-static int dsleep_recovery_margin_us = 1000000;
-
-/*
- * minimum delay to enter stop mode
- *
- * STOP_MODE_LATENCY: max time to wake up from STOP mode with regulator in low
- * power mode is 5 us + PLL locking time is 200us.
- *
- * SET_RTC_MATCH_DELAY: max time to set RTC match alarm. If we set the alarm
- * in the past, it will never wake up and cause a watchdog.
- * For STM32F3, we are using HSE, which requires additional time to start up.
- * Therefore, the latency for STM32F3 is set longer.
- *
- * RESTORE_HOST_ALARM_LATENCY: max latency between the deferred routine is
- * called and the host alarm is actually restored. In practice, the max latency
- * is measured as ~600us. 1000us should be conservative enough to guarantee
- * we won't miss the host alarm.
- */
-#ifdef CHIP_VARIANT_STM32F373
-#define STOP_MODE_LATENCY 500 /* us */
-#elif defined(CHIP_VARIANT_STM32F05X)
-#define STOP_MODE_LATENCY 300 /* us */
-#elif (CPU_CLOCK == PLL_CLOCK)
-#define STOP_MODE_LATENCY 300 /* us */
-#else
-#define STOP_MODE_LATENCY 50 /* us */
-#endif
-#define SET_RTC_MATCH_DELAY 200 /* us */
-
-#ifdef CONFIG_HOSTCMD_RTC
-#define RESTORE_HOST_ALARM_LATENCY 1000 /* us */
-#endif
-
-#endif /* CONFIG_LOW_POWER_IDLE */
-
-/*
- * RTC clock frequency (By default connected to LSI clock)
- *
- * The LSI on any given chip can be between 30 kHz to 60 kHz.
- * Without calibration, LSI frequency may be off by as much as 50%.
- *
- * Set synchronous clock freq to (RTC clock source / 2) to maximize
- * subsecond resolution. Set asynchronous clock to 1 Hz.
- */
-
-#define RTC_PREDIV_A 1
-#ifdef CONFIG_STM32_CLOCK_LSE
-#define RTC_FREQ (32768 / (RTC_PREDIV_A + 1)) /* Hz */
-/* GCD(RTC_FREQ, 1000000) */
-#define RTC_GCD 64
-#else /* LSI clock, 40kHz-ish */
-#define RTC_FREQ (40000 / (RTC_PREDIV_A + 1)) /* Hz */
-/* GCD(RTC_FREQ, 1000000) */
-#define RTC_GCD 20000
-#endif
-#define RTC_PREDIV_S (RTC_FREQ - 1)
-
-/*
- * There are (1000000 / RTC_FREQ) us per RTC tick, take GCD of both terms
- * for conversion calculations to fit in 32 bits.
- */
-#define US_GCD (1000000 / RTC_GCD)
-#define RTC_FREQ_GCD (RTC_FREQ / RTC_GCD)
-
-int32_t rtcss_to_us(uint32_t rtcss)
-{
- return ((RTC_PREDIV_S - (rtcss & 0x7fff)) * US_GCD) / RTC_FREQ_GCD;
-}
-
-uint32_t us_to_rtcss(int32_t us)
-{
- return RTC_PREDIV_S - us * RTC_FREQ_GCD / US_GCD;
-}
-
-void config_hispeed_clock(void)
-{
-#ifdef CHIP_FAMILY_STM32F3
- /* Ensure that HSE is ON */
- wait_for_ready(&STM32_RCC_CR, BIT(16), BIT(17));
-
- /*
- * HSE = 24MHz, no prescalar, no MCO, with PLL *2 => 48MHz SYSCLK
- * HCLK = SYSCLK, PCLK = HCLK / 2 = 24MHz
- * ADCCLK = PCLK / 6 = 4MHz
- * USB uses SYSCLK = 48MHz
- */
- STM32_RCC_CFGR = 0x0041a400;
-
- /* Enable the PLL */
- STM32_RCC_CR |= 0x01000000;
-
- /* Wait until the PLL is ready */
- while (!(STM32_RCC_CR & 0x02000000))
- ;
-
- /* Switch SYSCLK to PLL */
- STM32_RCC_CFGR |= 0x2;
-
- /* Wait until the PLL is the clock source */
- while ((STM32_RCC_CFGR & 0xc) != 0x8)
- ;
-/* F03X and F05X and F070 don't have HSI48 */
-#elif defined(CHIP_VARIANT_STM32F03X) || \
-defined(CHIP_VARIANT_STM32F05X) || \
-defined(CHIP_VARIANT_STM32F070)
- /* If PLL is the clock source, PLL has already been set up. */
- if ((STM32_RCC_CFGR & 0xc) == 0x8)
- return;
-
- /* Ensure that HSI is ON */
- wait_for_ready(&STM32_RCC_CR, BIT(0), BIT(1));
-
- /*
- * HSI = 8MHz, HSI/2 with PLL *12 = ~48 MHz
- * therefore PCLK = FCLK = SYSCLK = 48MHz
- */
- /* Switch the PLL source to HSI/2 */
- STM32_RCC_CFGR &= ~(0x00018000);
-
- /*
- * Specify HSI/2 clock as input clock to PLL and set PLL (*12).
- */
- STM32_RCC_CFGR |= 0x00280000;
-
- /* Enable the PLL. */
- STM32_RCC_CR |= 0x01000000;
-
- /* Wait until PLL is ready. */
- while (!(STM32_RCC_CR & 0x02000000))
- ;
-
- /* Switch SYSCLK to PLL. */
- STM32_RCC_CFGR |= 0x2;
-
- /* wait until the PLL is the clock source */
- while ((STM32_RCC_CFGR & 0xc) != 0x8)
- ;
-#else
- /* Ensure that HSI48 is ON */
- wait_for_ready(&STM32_RCC_CR2, BIT(16), BIT(17));
-
-#if (CPU_CLOCK == HSI48_CLOCK)
- /*
- * HSI48 = 48MHz, no prescaler, no MCO, no PLL
- * therefore PCLK = FCLK = SYSCLK = 48MHz
- * USB uses HSI48 = 48MHz
- */
-
-#ifdef CONFIG_USB
- /*
- * Configure and enable Clock Recovery System
- *
- * Since we are running from the internal RC HSI48 clock, the CSR
- * is needed to guarantee an accurate 48MHz clock for USB.
- *
- * The default values configure the CRS to use the periodic USB SOF
- * as the SYNC signal for calibrating the HSI48.
- *
- */
-
- /* Enable Clock Recovery System */
- STM32_RCC_APB1ENR |= STM32_RCC_PB1_CRS;
-
- /* Enable automatic trimming */
- STM32_CRS_CR |= STM32_CRS_CR_AUTOTRIMEN;
-
- /* Enable oscillator clock for the frequency error counter */
- STM32_CRS_CR |= STM32_CRS_CR_CEN;
-#endif
-
- /* switch SYSCLK to HSI48 */
- STM32_RCC_CFGR = 0x00000003;
-
- /* wait until the HSI48 is the clock source */
- while ((STM32_RCC_CFGR & 0xc) != 0xc)
- ;
-
-#elif (CPU_CLOCK == PLL_CLOCK)
- /*
- * HSI48 = 48MHz, no prescalar, no MCO, with PLL *4/5 => 38.4MHz SYSCLK
- * therefore PCLK = FCLK = SYSCLK = 38.4MHz
- * USB uses HSI48 = 48MHz
- */
-
- /* If PLL is the clock source, PLL has already been set up. */
- if ((STM32_RCC_CFGR & 0xc) == 0x8)
- return;
-
- /*
- * Specify HSI48 clock as input clock to PLL and set PLL multiplier
- * and divider.
- */
- STM32_RCC_CFGR = 0x00098000;
- STM32_RCC_CFGR2 = 0x4;
-
- /* Enable the PLL. */
- STM32_RCC_CR |= 0x01000000;
-
- /* Wait until PLL is ready. */
- while (!(STM32_RCC_CR & 0x02000000))
- ;
-
- /* Switch SYSCLK to PLL. */
- STM32_RCC_CFGR |= 0x2;
-
- /* wait until the PLL is the clock source */
- while ((STM32_RCC_CFGR & 0xc) != 0x8)
- ;
-
-#else
-#error "CPU_CLOCK must be either 48MHz or 38.4MHz"
-#endif
-#endif
-}
-
-#ifdef CONFIG_HIBERNATE
-void __enter_hibernate(uint32_t seconds, uint32_t microseconds)
-{
- struct rtc_time_reg rtc;
-
- if (seconds || microseconds)
- set_rtc_alarm(seconds, microseconds, &rtc, 0);
-
- /* interrupts off now */
- asm volatile("cpsid i");
-
-#ifdef CONFIG_HIBERNATE_WAKEUP_PINS
- /* enable the wake up pins */
- STM32_PWR_CSR |= CONFIG_HIBERNATE_WAKEUP_PINS;
-#endif
- STM32_PWR_CR |= 0xe;
- CPU_SCB_SYSCTRL |= 0x4;
- /* go to Standby mode */
- asm("wfi");
-
- /* we should never reach that point */
- while (1)
- ;
-}
-#endif
-
-#ifdef CONFIG_HOSTCMD_RTC
-static void restore_host_wake_alarm_deferred(void)
-{
- restore_host_wake_alarm();
-}
-DECLARE_DEFERRED(restore_host_wake_alarm_deferred);
-#endif
-
-#ifdef CONFIG_LOW_POWER_IDLE
-
-void clock_refresh_console_in_use(void)
-{
-}
-
-void __idle(void)
-{
- timestamp_t t0;
- uint32_t rtc_diff;
- int next_delay, margin_us;
- struct rtc_time_reg rtc0, rtc1;
-
- while (1) {
- asm volatile("cpsid i");
-
- t0 = get_time();
- next_delay = __hw_clock_event_get() - t0.le.lo;
-
-#ifdef CONFIG_LOW_POWER_IDLE_LIMITED
- if (idle_is_disabled())
- goto en_int;
-#endif
-
- if (DEEP_SLEEP_ALLOWED &&
-#ifdef CONFIG_HOSTCMD_RTC
- /*
- * Don't go to deep sleep mode if we might miss the
- * wake alarm that the host requested. Note that the
- * host alarm always aligns to second. Considering the
- * worst case, we have to ensure alarm won't go off
- * within RESTORE_HOST_ALARM_LATENCY + 1 second after
- * EC exits deep sleep mode.
- */
- !is_host_wake_alarm_expired(
- (timestamp_t)(next_delay + t0.val + SECOND +
- RESTORE_HOST_ALARM_LATENCY)) &&
-#endif
- (next_delay > (STOP_MODE_LATENCY + SET_RTC_MATCH_DELAY))) {
- /* Deep-sleep in STOP mode */
- idle_dsleep_cnt++;
-
- uart_enable_wakeup(1);
-
- /* Set deep sleep bit */
- CPU_SCB_SYSCTRL |= 0x4;
-
- set_rtc_alarm(0, next_delay - STOP_MODE_LATENCY,
- &rtc0, 0);
- asm("wfi");
-
- CPU_SCB_SYSCTRL &= ~0x4;
-
- uart_enable_wakeup(0);
-
- /*
- * By default only HSI 8MHz is enabled here. Re-enable
- * high-speed clock if in use.
- */
- config_hispeed_clock();
-
- /* Fast forward timer according to RTC counter */
- reset_rtc_alarm(&rtc1);
- rtc_diff = get_rtc_diff(&rtc0, &rtc1);
- t0.val = t0.val + rtc_diff;
- force_time(t0);
-
-#ifdef CONFIG_HOSTCMD_RTC
- hook_call_deferred(
- &restore_host_wake_alarm_deferred_data, 0);
-#endif
- /* Record time spent in deep sleep. */
- idle_dsleep_time_us += rtc_diff;
-
- /* Calculate how close we were to missing deadline */
- margin_us = next_delay - rtc_diff;
- if (margin_us < 0)
- /* Use CPUTS to save stack space */
- CPUTS("Idle overslept!\n");
-
- /* Record the closest to missing a deadline. */
- if (margin_us < dsleep_recovery_margin_us)
- dsleep_recovery_margin_us = margin_us;
- } else {
- idle_sleep_cnt++;
-
- /* Normal idle : only CPU clock stopped */
- asm("wfi");
- }
-#ifdef CONFIG_LOW_POWER_IDLE_LIMITED
-en_int:
-#endif
- asm volatile("cpsie i");
- }
-}
-#endif /* CONFIG_LOW_POWER_IDLE */
-
-int clock_get_freq(void)
-{
- return CPU_CLOCK;
-}
-
-void clock_wait_bus_cycles(enum bus_type bus, uint32_t cycles)
-{
- volatile uint32_t unused __attribute__((unused));
-
- if (bus == BUS_AHB) {
- while (cycles--)
- unused = STM32_DMA1_REGS->isr;
- } else { /* APB */
- while (cycles--)
- unused = STM32_USART_BRR(STM32_USART1_BASE);
- }
-}
-
-void clock_enable_module(enum module_id module, int enable)
-{
- if (module == MODULE_ADC) {
- if (enable)
- STM32_RCC_APB2ENR |= STM32_RCC_APB2ENR_ADCEN;
- else
- STM32_RCC_APB2ENR &= ~STM32_RCC_APB2ENR_ADCEN;
- return;
- } else if (module == MODULE_USB) {
- if (enable)
- STM32_RCC_APB1ENR |= STM32_RCC_PB1_USB;
- else
- STM32_RCC_APB1ENR &= ~STM32_RCC_PB1_USB;
- }
-}
-
-int clock_is_module_enabled(enum module_id module)
-{
- if (module == MODULE_ADC)
- return !!(STM32_RCC_APB2ENR & STM32_RCC_APB2ENR_ADCEN);
- else if (module == MODULE_USB)
- return !!(STM32_RCC_APB1ENR & STM32_RCC_PB1_USB);
- return 0;
-}
-
-void rtc_init(void)
-{
- rtc_unlock_regs();
-
- /* Enter RTC initialize mode */
- STM32_RTC_ISR |= STM32_RTC_ISR_INIT;
- while (!(STM32_RTC_ISR & STM32_RTC_ISR_INITF))
- ;
-
- /* Set clock prescalars */
- STM32_RTC_PRER = (RTC_PREDIV_A << 16) | RTC_PREDIV_S;
-
- /* Start RTC timer */
- STM32_RTC_ISR &= ~STM32_RTC_ISR_INIT;
- while (STM32_RTC_ISR & STM32_RTC_ISR_INITF)
- ;
-
- /* Enable RTC alarm interrupt */
- STM32_RTC_CR |= STM32_RTC_CR_ALRAIE | STM32_RTC_CR_BYPSHAD;
- STM32_EXTI_RTSR |= EXTI_RTC_ALR_EVENT;
- task_enable_irq(STM32_IRQ_RTC_ALARM);
-
- rtc_lock_regs();
-}
-
-#if defined(CONFIG_CMD_RTC) || defined(CONFIG_HOSTCMD_RTC)
-void rtc_set(uint32_t sec)
-{
- struct rtc_time_reg rtc;
-
- sec_to_rtc(sec, &rtc);
- rtc_unlock_regs();
-
- /* Disable alarm */
- STM32_RTC_CR &= ~STM32_RTC_CR_ALRAE;
-
- /* Enter RTC initialize mode */
- STM32_RTC_ISR |= STM32_RTC_ISR_INIT;
- while (!(STM32_RTC_ISR & STM32_RTC_ISR_INITF))
- ;
-
- /* Set clock prescalars */
- STM32_RTC_PRER = (RTC_PREDIV_A << 16) | RTC_PREDIV_S;
-
- STM32_RTC_TR = rtc.rtc_tr;
- STM32_RTC_DR = rtc.rtc_dr;
- /* Start RTC timer */
- STM32_RTC_ISR &= ~STM32_RTC_ISR_INIT;
-
- rtc_lock_regs();
-}
-#endif
-
-#if defined(CONFIG_LOW_POWER_IDLE) && defined(CONFIG_COMMON_RUNTIME)
-#ifdef CONFIG_CMD_IDLE_STATS
-/**
- * Print low power idle statistics
- */
-static int command_idle_stats(int argc, char **argv)
-{
- timestamp_t ts = get_time();
-
- ccprintf("Num idle calls that sleep: %d\n", idle_sleep_cnt);
- ccprintf("Num idle calls that deep-sleep: %d\n", idle_dsleep_cnt);
- ccprintf("Time spent in deep-sleep: %.6llds\n",
- idle_dsleep_time_us);
- ccprintf("Total time on: %.6llds\n", ts.val);
- ccprintf("Deep-sleep closest to wake deadline: %dus\n",
- dsleep_recovery_margin_us);
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(idlestats, command_idle_stats,
- "",
- "Print last idle stats");
-#endif /* CONFIG_CMD_IDLE_STATS */
-#endif