mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 00:51:29 +00:00
stm32: Add delay after enabling peripheral clock
We need a dummy read after enabling AHB peripheral clock before we can access the peripheral. For APB, we also need a dummy read for STM32F3. BRANCH=All affected BUG=chrome-os-partner:33007 TEST=make buildall Change-Id: I47f4a024dca294f555428c3f2053c1d32835ebe0 Signed-off-by: Vic Yang <victoryang@google.com> Reviewed-on: https://chromium-review.googlesource.com/246181 Reviewed-by: Alec Berg <alecaberg@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Tested-by: Vic Yang <victoryang@chromium.org> Commit-Queue: Vic Yang <victoryang@chromium.org>
This commit is contained in:
committed by
ChromeOS Commit Bot
parent
a9ae00b101
commit
049463f8ad
@@ -9,6 +9,7 @@
|
||||
#define __USB_PD_CONFIG_H
|
||||
|
||||
#include "charge_state.h"
|
||||
#include "clock.h"
|
||||
#include "registers.h"
|
||||
|
||||
/* Port and task configuration */
|
||||
@@ -46,6 +47,8 @@
|
||||
static inline void spi_enable_clock(int port)
|
||||
{
|
||||
STM32_RCC_APB2ENR |= STM32_RCC_PB2_SPI1;
|
||||
/* Delay 1 APB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_APB, 1);
|
||||
}
|
||||
|
||||
#define DMAC_SPI_TX(p) STM32_DMAC_CH3
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
/* ryu sensor hub configuration */
|
||||
|
||||
#include "clock.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "driver/accelgyro_lsm6ds0.h"
|
||||
@@ -64,6 +65,8 @@ void board_config_pre_init(void)
|
||||
* and the register write as no effect.
|
||||
*/
|
||||
STM32_RCC_APB2ENR |= 1 << 0;
|
||||
/* Delay 1 APB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_APB, 1);
|
||||
/*
|
||||
* Remap USART DMA to match the USART driver
|
||||
* the DMA mapping is :
|
||||
|
||||
@@ -266,6 +266,12 @@ static void adc_init(void)
|
||||
*/
|
||||
STM32_RCC_APB2ENR |= (1 << 9);
|
||||
|
||||
/*
|
||||
* ADC clock is divided with respect to AHB, so no delay needed
|
||||
* here. If ADC clock is the same as AHB, a dummy read on ADC
|
||||
* register is needed here.
|
||||
*/
|
||||
|
||||
if (!adc_powered()) {
|
||||
/* Power on ADC module */
|
||||
STM32_ADC_CR2 |= (1 << 0); /* ADON */
|
||||
|
||||
@@ -265,6 +265,19 @@ int clock_get_freq(void)
|
||||
return CPU_CLOCK;
|
||||
}
|
||||
|
||||
void clock_wait_bus_cycles(enum bus_type bus, uint32_t cycles)
|
||||
{
|
||||
volatile uint32_t dummy __attribute__((unused));
|
||||
|
||||
if (bus == BUS_AHB) {
|
||||
while (cycles--)
|
||||
dummy = STM32_DMA1_REGS->isr;
|
||||
} else { /* APB */
|
||||
while (cycles--)
|
||||
dummy = STM32_USART_BRR(STM32_USART1_BASE);
|
||||
}
|
||||
}
|
||||
|
||||
void clock_init(void)
|
||||
{
|
||||
/*
|
||||
|
||||
@@ -418,6 +418,19 @@ int clock_get_freq(void)
|
||||
return CPU_CLOCK;
|
||||
}
|
||||
|
||||
void clock_wait_bus_cycles(enum bus_type bus, uint32_t cycles)
|
||||
{
|
||||
volatile uint32_t dummy __attribute__((unused));
|
||||
|
||||
if (bus == BUS_AHB) {
|
||||
while (cycles--)
|
||||
dummy = STM32_DMA1_REGS->isr;
|
||||
} else { /* APB */
|
||||
while (cycles--)
|
||||
dummy = STM32_USART_BRR(STM32_USART1_BASE);
|
||||
}
|
||||
}
|
||||
|
||||
void clock_enable_module(enum module_id module, int enable)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -50,6 +50,19 @@ int clock_get_freq(void)
|
||||
return freq;
|
||||
}
|
||||
|
||||
void clock_wait_bus_cycles(enum bus_type bus, uint32_t cycles)
|
||||
{
|
||||
volatile uint32_t dummy __attribute__((unused));
|
||||
|
||||
if (bus == BUS_AHB) {
|
||||
while (cycles--)
|
||||
dummy = STM32_DMA1_REGS->isr;
|
||||
} else { /* APB */
|
||||
while (cycles--)
|
||||
dummy = STM32_USART_BRR(STM32_USART1_BASE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set which oscillator is used for the clock
|
||||
*
|
||||
|
||||
@@ -7,12 +7,15 @@
|
||||
#define _CRC_HW_H
|
||||
/* CRC-32 hardware implementation with USB constants */
|
||||
|
||||
#include "clock.h"
|
||||
#include "registers.h"
|
||||
|
||||
static inline void crc32_init(void)
|
||||
{
|
||||
/* switch on CRC controller */
|
||||
STM32_RCC_AHBENR |= 1 << 6; /* switch on CRC controller */
|
||||
/* Delay 1 AHB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_AHB, 1);
|
||||
/* reset CRC state */
|
||||
STM32_CRC_CR = STM32_CRC_CR_RESET | STM32_CRC_CR_REV_OUT
|
||||
| STM32_CRC_CR_REV_IN_WORD;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "clock.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "dma.h"
|
||||
@@ -211,6 +212,8 @@ void dma_init(void)
|
||||
{
|
||||
/* Enable DMA1; current chips don't have DMA2 */
|
||||
STM32_RCC_AHBENR |= STM32_RCC_HB_DMA1;
|
||||
/* Delay 1 AHB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_AHB, 1);
|
||||
}
|
||||
|
||||
int dma_wait(enum dma_channel channel)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
/* GPIO module for Chrome EC */
|
||||
|
||||
#include "clock.h"
|
||||
#include "common.h"
|
||||
#include "gpio.h"
|
||||
#include "hooks.h"
|
||||
@@ -116,6 +117,9 @@ void gpio_enable_clocks(void)
|
||||
#else
|
||||
STM32_RCC_APB2ENR |= 0x1fd;
|
||||
#endif
|
||||
|
||||
/* Delay 1 APB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_APB, 1);
|
||||
}
|
||||
|
||||
void gpio_set_alternate_function(uint32_t port, uint32_t mask, int func)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
/* GPIO module for Chrome EC */
|
||||
|
||||
#include "clock.h"
|
||||
#include "common.h"
|
||||
#include "gpio.h"
|
||||
#include "hooks.h"
|
||||
@@ -26,6 +27,9 @@ void gpio_enable_clocks(void)
|
||||
* and support disabling some of them in low-power idle.
|
||||
*/
|
||||
STM32_RCC_AHBENR |= 0x7e0000;
|
||||
|
||||
/* Delay 1 AHB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_AHB, 1);
|
||||
}
|
||||
|
||||
static void gpio_init(void)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
/* GPIO module for Chrome EC */
|
||||
|
||||
#include "clock.h"
|
||||
#include "common.h"
|
||||
#include "gpio.h"
|
||||
#include "hooks.h"
|
||||
@@ -26,6 +27,9 @@ void gpio_enable_clocks(void)
|
||||
* and support disabling some of them in low-power idle.
|
||||
*/
|
||||
STM32_RCC_AHBENR |= 0x7e0000;
|
||||
|
||||
/* Delay 1 AHB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_AHB, 1);
|
||||
}
|
||||
|
||||
static void gpio_init(void)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
/* GPIO module for Chrome EC */
|
||||
|
||||
#include "clock.h"
|
||||
#include "common.h"
|
||||
#include "gpio.h"
|
||||
#include "hooks.h"
|
||||
@@ -26,6 +27,9 @@ void gpio_enable_clocks(void)
|
||||
* and support disabling some of them in low-power idle.
|
||||
*/
|
||||
STM32_RCC_AHBENR |= 0x3f;
|
||||
|
||||
/* Delay 1 AHB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_AHB, 1);
|
||||
}
|
||||
|
||||
static void gpio_init(void)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
/* GPIO module for Chrome EC */
|
||||
|
||||
#include "clock.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "gpio.h"
|
||||
@@ -28,6 +29,9 @@ void gpio_pre_init(void)
|
||||
/* Required to configure external IRQ lines (SYSCFG_EXTICRn) */
|
||||
STM32_RCC_APB2ENR |= 1 << 0;
|
||||
|
||||
/* Delay 1 APB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_APB, 1);
|
||||
|
||||
if (!is_warm)
|
||||
gpio_enable_clocks();
|
||||
|
||||
|
||||
@@ -320,6 +320,9 @@ int __hw_clock_source_init(uint32_t start_t)
|
||||
__hw_timer_enable_clock(TIM_CLOCK_MSB, 1);
|
||||
__hw_timer_enable_clock(TIM_CLOCK_LSB, 1);
|
||||
|
||||
/* Delay 1 APB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_APB, 1);
|
||||
|
||||
/*
|
||||
* Timer configuration : Upcounter, counter disabled, update event only
|
||||
* on overflow.
|
||||
@@ -405,6 +408,9 @@ void hwtimer_setup_watchdog(void)
|
||||
/* Enable clock */
|
||||
__hw_timer_enable_clock(TIM_WATCHDOG, 1);
|
||||
|
||||
/* Delay 1 APB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_APB, 1);
|
||||
|
||||
/*
|
||||
* Timer configuration : Down counter, counter disabled, update
|
||||
* event only on overflow.
|
||||
|
||||
@@ -148,6 +148,8 @@ int __hw_clock_source_init(uint32_t start_t)
|
||||
{
|
||||
/* Enable TIM peripheral block clocks */
|
||||
__hw_timer_enable_clock(TIM_CLOCK32, 1);
|
||||
/* Delay 1 APB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_APB, 1);
|
||||
|
||||
/*
|
||||
* Timer configuration : Upcounter, counter disabled, update event only
|
||||
@@ -218,6 +220,8 @@ void hwtimer_setup_watchdog(void)
|
||||
{
|
||||
/* Enable clock */
|
||||
__hw_timer_enable_clock(TIM_WATCHDOG, 1);
|
||||
/* Delay 1 APB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_APB, 1);
|
||||
|
||||
/*
|
||||
* Timer configuration : Up counter, counter disabled, update
|
||||
|
||||
@@ -343,6 +343,9 @@ static void i2c_init_port(unsigned int port)
|
||||
|
||||
/* enable I2C2 clock */
|
||||
STM32_RCC_APB1ENR |= 1 << i2c_clock_bit[port];
|
||||
|
||||
/* Delay 1 APB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_APB, 1);
|
||||
}
|
||||
|
||||
/* force reset of the i2c peripheral */
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
#include "chipset.h"
|
||||
#include "clock.h"
|
||||
#include "console.h"
|
||||
#include "dma.h"
|
||||
#include "gpio.h"
|
||||
@@ -630,6 +631,9 @@ static void spi_init(void)
|
||||
/* Enable clocks to SPI1 module */
|
||||
STM32_RCC_APB2ENR |= STM32_RCC_PB2_SPI1;
|
||||
|
||||
/* Delay 1 APB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_APB, 1);
|
||||
|
||||
/*
|
||||
* Enable rx/tx DMA and get ready to receive our first transaction and
|
||||
* "disable" FIFO by setting event to happen after only 1 byte
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
/* System module for Chrome EC : hardware specific implementation */
|
||||
|
||||
#include "clock.h"
|
||||
#include "console.h"
|
||||
#include "cpu.h"
|
||||
#include "flash.h"
|
||||
@@ -165,6 +166,8 @@ void system_pre_init(void)
|
||||
STM32_RCC_APB1ENR |= 1 << 28;
|
||||
/* enable backup registers */
|
||||
STM32_RCC_APB1ENR |= 1 << 27;
|
||||
/* Delay 1 APB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_APB, 1);
|
||||
/* Enable access to RCC CSR register and RTC backup registers */
|
||||
STM32_PWR_CR |= 1 << 8;
|
||||
|
||||
|
||||
@@ -279,6 +279,12 @@ void uart_init(void)
|
||||
STM32_RCC_APB1ENR |= CONCAT2(STM32_RCC_PB1_USART, UARTN);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For STM32F3, A delay of 1 APB clock cycles is needed before we
|
||||
* can access any USART register. Fortunately, we have
|
||||
* gpio_config_module() below and thus don't need to add the delay.
|
||||
*/
|
||||
|
||||
/* Configure GPIOs */
|
||||
gpio_config_module(MODULE_UART, 1);
|
||||
|
||||
|
||||
@@ -75,6 +75,12 @@ void usart_init(struct usart_config const *config)
|
||||
*/
|
||||
*(config->hw->clock_register) |= config->hw->clock_enable;
|
||||
|
||||
/*
|
||||
* For STM32F3, A delay of 1 APB clock cycles is needed before we
|
||||
* can access any USART register. Fortunately, we have
|
||||
* gpio_config_module() below and thus don't need to add the delay.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Switch all GPIOs assigned to the USART module over to their USART
|
||||
* alternate functions.
|
||||
|
||||
@@ -582,6 +582,8 @@ void pd_hw_init(int port)
|
||||
#ifdef CONFIG_PD_USE_DAC_AS_REF
|
||||
/* Enable DAC interface clock. */
|
||||
STM32_RCC_APB1ENR |= (1 << 29);
|
||||
/* Delay 1 APB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_APB, 1);
|
||||
/* set voltage Vout=0.850V (Vref = 3.0V) */
|
||||
STM32_DAC_DHR12RD = 850 * 4096 / 3000;
|
||||
/* Start DAC channel 1 */
|
||||
@@ -593,6 +595,8 @@ void pd_hw_init(int port)
|
||||
#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3)
|
||||
/* turn on COMP/SYSCFG */
|
||||
STM32_RCC_APB2ENR |= 1 << 0;
|
||||
/* Delay 1 APB clock cycle after the clock is enabled */
|
||||
clock_wait_bus_cycles(BUS_APB, 1);
|
||||
/* currently in hi-speed mode : TODO revisit later, INM = PA0(INM6) */
|
||||
STM32_COMP_CSR = STM32_COMP_CMP1MODE_LSPEED |
|
||||
STM32_COMP_CMP1INSEL_INM6 |
|
||||
|
||||
@@ -47,7 +47,7 @@ void clock_enable_module(enum module_id module, int enable);
|
||||
void clock_enable_pll(int enable, int notify);
|
||||
|
||||
/**
|
||||
* Wait for a number of clock cycles.
|
||||
* Wait for a number of CPU clock cycles.
|
||||
*
|
||||
* Simple busy waiting for use before clocks/timers are initialized.
|
||||
*
|
||||
@@ -55,6 +55,21 @@ void clock_enable_pll(int enable, int notify);
|
||||
*/
|
||||
void clock_wait_cycles(uint32_t cycles);
|
||||
|
||||
enum bus_type {
|
||||
BUS_AHB,
|
||||
BUS_APB,
|
||||
};
|
||||
|
||||
/**
|
||||
* Wait for a number of peripheral bus clock cycles.
|
||||
*
|
||||
* Dummy read on peripherals for delay.
|
||||
*
|
||||
* @param bus Which bus clock cycle to use.
|
||||
* @param cycles Number of cycles to wait.
|
||||
*/
|
||||
void clock_wait_bus_cycles(enum bus_type bus, uint32_t cycles);
|
||||
|
||||
/* Clock gate control modes for clock_enable_peripheral() */
|
||||
#define CGC_MODE_RUN (1 << 0)
|
||||
#define CGC_MODE_SLEEP (1 << 1)
|
||||
|
||||
Reference in New Issue
Block a user