Merge changes from topic "st-clk-updates" into integration
* changes: refactor(st-clock): update STGEN management feat(st-clock): assign clocks to the correct BL feat(st-clock): do not refcount on non-secure clocks in bl32 feat(st-clock): define secure and non-secure gate clocks refactor(stm32mp1): remove unused refcount helper functions fix(stm32mp1): add missing debug.h refactor(st-clock): use refcnt instead of secure status
This commit is contained in:
commit
e672698ce7
|
@ -15,7 +15,6 @@
|
|||
#include <common/fdt_wrappers.h>
|
||||
#include <drivers/clk.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <drivers/generic_delay_timer.h>
|
||||
#include <drivers/st/stm32mp_clkfunc.h>
|
||||
#include <drivers/st/stm32mp1_clk.h>
|
||||
#include <drivers/st/stm32mp1_rcc.h>
|
||||
|
@ -241,6 +240,7 @@ struct stm32mp1_clk_gate {
|
|||
uint8_t bit;
|
||||
uint8_t index;
|
||||
uint8_t set_clr;
|
||||
uint8_t secure;
|
||||
uint8_t sel; /* Relates to enum stm32mp1_parent_sel */
|
||||
uint8_t fixed; /* Relates to enum stm32mp1_parent_id */
|
||||
};
|
||||
|
@ -266,45 +266,49 @@ struct stm32mp1_clk_pll {
|
|||
};
|
||||
|
||||
/* Clocks with selectable source and non set/clr register access */
|
||||
#define _CLK_SELEC(off, b, idx, s) \
|
||||
#define _CLK_SELEC(sec, off, b, idx, s) \
|
||||
{ \
|
||||
.offset = (off), \
|
||||
.bit = (b), \
|
||||
.index = (idx), \
|
||||
.set_clr = 0, \
|
||||
.secure = (sec), \
|
||||
.sel = (s), \
|
||||
.fixed = _UNKNOWN_ID, \
|
||||
}
|
||||
|
||||
/* Clocks with fixed source and non set/clr register access */
|
||||
#define _CLK_FIXED(off, b, idx, f) \
|
||||
#define _CLK_FIXED(sec, off, b, idx, f) \
|
||||
{ \
|
||||
.offset = (off), \
|
||||
.bit = (b), \
|
||||
.index = (idx), \
|
||||
.set_clr = 0, \
|
||||
.secure = (sec), \
|
||||
.sel = _UNKNOWN_SEL, \
|
||||
.fixed = (f), \
|
||||
}
|
||||
|
||||
/* Clocks with selectable source and set/clr register access */
|
||||
#define _CLK_SC_SELEC(off, b, idx, s) \
|
||||
#define _CLK_SC_SELEC(sec, off, b, idx, s) \
|
||||
{ \
|
||||
.offset = (off), \
|
||||
.bit = (b), \
|
||||
.index = (idx), \
|
||||
.set_clr = 1, \
|
||||
.secure = (sec), \
|
||||
.sel = (s), \
|
||||
.fixed = _UNKNOWN_ID, \
|
||||
}
|
||||
|
||||
/* Clocks with fixed source and set/clr register access */
|
||||
#define _CLK_SC_FIXED(off, b, idx, f) \
|
||||
#define _CLK_SC_FIXED(sec, off, b, idx, f) \
|
||||
{ \
|
||||
.offset = (off), \
|
||||
.bit = (b), \
|
||||
.index = (idx), \
|
||||
.set_clr = 1, \
|
||||
.secure = (sec), \
|
||||
.sel = _UNKNOWN_SEL, \
|
||||
.fixed = (f), \
|
||||
}
|
||||
|
@ -338,81 +342,94 @@ struct stm32mp1_clk_pll {
|
|||
|
||||
#define NB_GATES ARRAY_SIZE(stm32mp1_clk_gate)
|
||||
|
||||
#define SEC 1
|
||||
#define N_S 0
|
||||
|
||||
static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = {
|
||||
_CLK_FIXED(RCC_DDRITFCR, 0, DDRC1, _ACLK),
|
||||
_CLK_FIXED(RCC_DDRITFCR, 1, DDRC1LP, _ACLK),
|
||||
_CLK_FIXED(RCC_DDRITFCR, 2, DDRC2, _ACLK),
|
||||
_CLK_FIXED(RCC_DDRITFCR, 3, DDRC2LP, _ACLK),
|
||||
_CLK_FIXED(RCC_DDRITFCR, 4, DDRPHYC, _PLL2_R),
|
||||
_CLK_FIXED(RCC_DDRITFCR, 5, DDRPHYCLP, _PLL2_R),
|
||||
_CLK_FIXED(RCC_DDRITFCR, 6, DDRCAPB, _PCLK4),
|
||||
_CLK_FIXED(RCC_DDRITFCR, 7, DDRCAPBLP, _PCLK4),
|
||||
_CLK_FIXED(RCC_DDRITFCR, 8, AXIDCG, _ACLK),
|
||||
_CLK_FIXED(RCC_DDRITFCR, 9, DDRPHYCAPB, _PCLK4),
|
||||
_CLK_FIXED(RCC_DDRITFCR, 10, DDRPHYCAPBLP, _PCLK4),
|
||||
_CLK_FIXED(SEC, RCC_DDRITFCR, 0, DDRC1, _ACLK),
|
||||
_CLK_FIXED(SEC, RCC_DDRITFCR, 1, DDRC1LP, _ACLK),
|
||||
_CLK_FIXED(SEC, RCC_DDRITFCR, 2, DDRC2, _ACLK),
|
||||
_CLK_FIXED(SEC, RCC_DDRITFCR, 3, DDRC2LP, _ACLK),
|
||||
_CLK_FIXED(SEC, RCC_DDRITFCR, 4, DDRPHYC, _PLL2_R),
|
||||
_CLK_FIXED(SEC, RCC_DDRITFCR, 5, DDRPHYCLP, _PLL2_R),
|
||||
_CLK_FIXED(SEC, RCC_DDRITFCR, 6, DDRCAPB, _PCLK4),
|
||||
_CLK_FIXED(SEC, RCC_DDRITFCR, 7, DDRCAPBLP, _PCLK4),
|
||||
_CLK_FIXED(SEC, RCC_DDRITFCR, 8, AXIDCG, _ACLK),
|
||||
_CLK_FIXED(SEC, RCC_DDRITFCR, 9, DDRPHYCAPB, _PCLK4),
|
||||
_CLK_FIXED(SEC, RCC_DDRITFCR, 10, DDRPHYCAPBLP, _PCLK4),
|
||||
|
||||
_CLK_SC_FIXED(RCC_MP_APB1ENSETR, 6, TIM12_K, _PCLK1),
|
||||
_CLK_SC_SELEC(RCC_MP_APB1ENSETR, 14, USART2_K, _UART24_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_APB1ENSETR, 15, USART3_K, _UART35_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_APB1ENSETR, 16, UART4_K, _UART24_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_APB1ENSETR, 17, UART5_K, _UART35_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_APB1ENSETR, 18, UART7_K, _UART78_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_APB1ENSETR, 19, UART8_K, _UART78_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_APB1ENSETR, 21, I2C1_K, _I2C12_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_APB1ENSETR, 22, I2C2_K, _I2C12_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_APB1ENSETR, 23, I2C3_K, _I2C35_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_APB1ENSETR, 24, I2C5_K, _I2C35_SEL),
|
||||
#if defined(IMAGE_BL32)
|
||||
_CLK_SC_FIXED(N_S, RCC_MP_APB1ENSETR, 6, TIM12_K, _PCLK1),
|
||||
#endif
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_APB1ENSETR, 14, USART2_K, _UART24_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_APB1ENSETR, 15, USART3_K, _UART35_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_APB1ENSETR, 16, UART4_K, _UART24_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_APB1ENSETR, 17, UART5_K, _UART35_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_APB1ENSETR, 18, UART7_K, _UART78_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_APB1ENSETR, 19, UART8_K, _UART78_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_APB1ENSETR, 21, I2C1_K, _I2C12_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_APB1ENSETR, 22, I2C2_K, _I2C12_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_APB1ENSETR, 23, I2C3_K, _I2C35_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_APB1ENSETR, 24, I2C5_K, _I2C35_SEL),
|
||||
|
||||
_CLK_SC_FIXED(RCC_MP_APB2ENSETR, 2, TIM15_K, _PCLK2),
|
||||
_CLK_SC_SELEC(RCC_MP_APB2ENSETR, 13, USART6_K, _UART6_SEL),
|
||||
#if defined(IMAGE_BL32)
|
||||
_CLK_SC_FIXED(N_S, RCC_MP_APB2ENSETR, 2, TIM15_K, _PCLK2),
|
||||
#endif
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_APB2ENSETR, 13, USART6_K, _UART6_SEL),
|
||||
|
||||
_CLK_SC_FIXED(RCC_MP_APB3ENSETR, 11, SYSCFG, _UNKNOWN_ID),
|
||||
_CLK_SC_FIXED(N_S, RCC_MP_APB3ENSETR, 11, SYSCFG, _UNKNOWN_ID),
|
||||
|
||||
_CLK_SC_SELEC(RCC_MP_APB4ENSETR, 8, DDRPERFM, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_APB4ENSETR, 15, IWDG2, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_APB4ENSETR, 16, USBPHY_K, _USBPHY_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_APB4ENSETR, 8, DDRPERFM, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_APB4ENSETR, 15, IWDG2, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_APB4ENSETR, 16, USBPHY_K, _USBPHY_SEL),
|
||||
|
||||
_CLK_SC_SELEC(RCC_MP_APB5ENSETR, 0, SPI6_K, _SPI6_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_APB5ENSETR, 2, I2C4_K, _I2C46_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_APB5ENSETR, 3, I2C6_K, _I2C46_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_APB5ENSETR, 4, USART1_K, _UART1_SEL),
|
||||
_CLK_SC_FIXED(RCC_MP_APB5ENSETR, 8, RTCAPB, _PCLK5),
|
||||
_CLK_SC_FIXED(RCC_MP_APB5ENSETR, 11, TZC1, _PCLK5),
|
||||
_CLK_SC_FIXED(RCC_MP_APB5ENSETR, 12, TZC2, _PCLK5),
|
||||
_CLK_SC_FIXED(RCC_MP_APB5ENSETR, 13, TZPC, _PCLK5),
|
||||
_CLK_SC_FIXED(RCC_MP_APB5ENSETR, 15, IWDG1, _PCLK5),
|
||||
_CLK_SC_FIXED(RCC_MP_APB5ENSETR, 16, BSEC, _PCLK5),
|
||||
_CLK_SC_SELEC(RCC_MP_APB5ENSETR, 20, STGEN_K, _STGEN_SEL),
|
||||
_CLK_SC_SELEC(SEC, RCC_MP_APB5ENSETR, 0, SPI6_K, _SPI6_SEL),
|
||||
_CLK_SC_SELEC(SEC, RCC_MP_APB5ENSETR, 2, I2C4_K, _I2C46_SEL),
|
||||
_CLK_SC_SELEC(SEC, RCC_MP_APB5ENSETR, 3, I2C6_K, _I2C46_SEL),
|
||||
_CLK_SC_SELEC(SEC, RCC_MP_APB5ENSETR, 4, USART1_K, _UART1_SEL),
|
||||
_CLK_SC_FIXED(SEC, RCC_MP_APB5ENSETR, 8, RTCAPB, _PCLK5),
|
||||
_CLK_SC_FIXED(SEC, RCC_MP_APB5ENSETR, 11, TZC1, _PCLK5),
|
||||
_CLK_SC_FIXED(SEC, RCC_MP_APB5ENSETR, 12, TZC2, _PCLK5),
|
||||
_CLK_SC_FIXED(SEC, RCC_MP_APB5ENSETR, 13, TZPC, _PCLK5),
|
||||
_CLK_SC_FIXED(SEC, RCC_MP_APB5ENSETR, 15, IWDG1, _PCLK5),
|
||||
_CLK_SC_FIXED(SEC, RCC_MP_APB5ENSETR, 16, BSEC, _PCLK5),
|
||||
_CLK_SC_SELEC(SEC, RCC_MP_APB5ENSETR, 20, STGEN_K, _STGEN_SEL),
|
||||
|
||||
_CLK_SC_SELEC(RCC_MP_AHB2ENSETR, 8, USBO_K, _USBO_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_AHB2ENSETR, 16, SDMMC3_K, _SDMMC3_SEL),
|
||||
#if defined(IMAGE_BL32)
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 8, USBO_K, _USBO_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB2ENSETR, 16, SDMMC3_K, _SDMMC3_SEL),
|
||||
#endif
|
||||
|
||||
_CLK_SC_SELEC(RCC_MP_AHB4ENSETR, 0, GPIOA, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_AHB4ENSETR, 1, GPIOB, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_AHB4ENSETR, 2, GPIOC, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_AHB4ENSETR, 3, GPIOD, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_AHB4ENSETR, 4, GPIOE, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_AHB4ENSETR, 5, GPIOF, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_AHB4ENSETR, 6, GPIOG, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_AHB4ENSETR, 7, GPIOH, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_AHB4ENSETR, 8, GPIOI, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_AHB4ENSETR, 9, GPIOJ, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_AHB4ENSETR, 10, GPIOK, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 0, GPIOA, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 1, GPIOB, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 2, GPIOC, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 3, GPIOD, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 4, GPIOE, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 5, GPIOF, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 6, GPIOG, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 7, GPIOH, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 8, GPIOI, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 9, GPIOJ, _UNKNOWN_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB4ENSETR, 10, GPIOK, _UNKNOWN_SEL),
|
||||
|
||||
_CLK_SC_FIXED(RCC_MP_AHB5ENSETR, 0, GPIOZ, _PCLK5),
|
||||
_CLK_SC_FIXED(RCC_MP_AHB5ENSETR, 4, CRYP1, _PCLK5),
|
||||
_CLK_SC_FIXED(RCC_MP_AHB5ENSETR, 5, HASH1, _PCLK5),
|
||||
_CLK_SC_SELEC(RCC_MP_AHB5ENSETR, 6, RNG1_K, _RNG1_SEL),
|
||||
_CLK_SC_FIXED(RCC_MP_AHB5ENSETR, 8, BKPSRAM, _PCLK5),
|
||||
_CLK_SC_FIXED(SEC, RCC_MP_AHB5ENSETR, 0, GPIOZ, _PCLK5),
|
||||
_CLK_SC_FIXED(SEC, RCC_MP_AHB5ENSETR, 4, CRYP1, _PCLK5),
|
||||
_CLK_SC_FIXED(SEC, RCC_MP_AHB5ENSETR, 5, HASH1, _PCLK5),
|
||||
_CLK_SC_SELEC(SEC, RCC_MP_AHB5ENSETR, 6, RNG1_K, _RNG1_SEL),
|
||||
_CLK_SC_FIXED(SEC, RCC_MP_AHB5ENSETR, 8, BKPSRAM, _PCLK5),
|
||||
|
||||
_CLK_SC_SELEC(RCC_MP_AHB6ENSETR, 12, FMC_K, _FMC_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_AHB6ENSETR, 14, QSPI_K, _QSPI_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_AHB6ENSETR, 16, SDMMC1_K, _SDMMC12_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_AHB6ENSETR, 17, SDMMC2_K, _SDMMC12_SEL),
|
||||
_CLK_SC_SELEC(RCC_MP_AHB6ENSETR, 24, USBH, _UNKNOWN_SEL),
|
||||
#if defined(IMAGE_BL2)
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 12, FMC_K, _FMC_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 14, QSPI_K, _QSPI_SEL),
|
||||
#endif
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 16, SDMMC1_K, _SDMMC12_SEL),
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 17, SDMMC2_K, _SDMMC12_SEL),
|
||||
#if defined(IMAGE_BL32)
|
||||
_CLK_SC_SELEC(N_S, RCC_MP_AHB6ENSETR, 24, USBH, _UNKNOWN_SEL),
|
||||
#endif
|
||||
|
||||
_CLK_SELEC(RCC_BDCR, 20, RTC, _RTC_SEL),
|
||||
_CLK_SELEC(RCC_DBGCFGR, 8, CK_DBG, _UNKNOWN_SEL),
|
||||
_CLK_SELEC(SEC, RCC_BDCR, 20, RTC, _RTC_SEL),
|
||||
_CLK_SELEC(N_S, RCC_DBGCFGR, 8, CK_DBG, _UNKNOWN_SEL),
|
||||
};
|
||||
|
||||
static const uint8_t i2c12_parents[] = {
|
||||
|
@ -628,6 +645,13 @@ static const struct stm32mp1_clk_gate *gate_ref(unsigned int idx)
|
|||
return &stm32mp1_clk_gate[idx];
|
||||
}
|
||||
|
||||
#if defined(IMAGE_BL32)
|
||||
static bool gate_is_non_secure(const struct stm32mp1_clk_gate *gate)
|
||||
{
|
||||
return gate->secure == N_S;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct stm32mp1_clk_sel *clk_sel_ref(unsigned int idx)
|
||||
{
|
||||
return &stm32mp1_clk_sel[idx];
|
||||
|
@ -1062,17 +1086,6 @@ static bool __clk_is_enabled(struct stm32mp1_clk_gate const *gate)
|
|||
return mmio_read_32(rcc_base + gate->offset) & BIT(gate->bit);
|
||||
}
|
||||
|
||||
unsigned int stm32mp1_clk_get_refcount(unsigned long id)
|
||||
{
|
||||
int i = stm32mp1_clk_get_gated_id(id);
|
||||
|
||||
if (i < 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
return gate_refcounts[i];
|
||||
}
|
||||
|
||||
/* Oscillators and PLLs are not gated at runtime */
|
||||
static bool clock_is_always_on(unsigned long id)
|
||||
{
|
||||
|
@ -1101,11 +1114,10 @@ static bool clock_is_always_on(unsigned long id)
|
|||
}
|
||||
}
|
||||
|
||||
void __stm32mp1_clk_enable(unsigned long id, bool secure)
|
||||
static void __stm32mp1_clk_enable(unsigned long id, bool with_refcnt)
|
||||
{
|
||||
const struct stm32mp1_clk_gate *gate;
|
||||
int i;
|
||||
unsigned int *refcnt;
|
||||
|
||||
if (clock_is_always_on(id)) {
|
||||
return;
|
||||
|
@ -1118,22 +1130,39 @@ void __stm32mp1_clk_enable(unsigned long id, bool secure)
|
|||
}
|
||||
|
||||
gate = gate_ref(i);
|
||||
refcnt = &gate_refcounts[i];
|
||||
|
||||
if (!with_refcnt) {
|
||||
__clk_enable(gate);
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(IMAGE_BL32)
|
||||
if (gate_is_non_secure(gate)) {
|
||||
/* Enable non-secure clock w/o any refcounting */
|
||||
__clk_enable(gate);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
stm32mp1_clk_lock(&refcount_lock);
|
||||
|
||||
if (stm32mp_incr_shrefcnt(refcnt, secure) != 0) {
|
||||
if (gate_refcounts[i] == 0U) {
|
||||
__clk_enable(gate);
|
||||
}
|
||||
|
||||
gate_refcounts[i]++;
|
||||
if (gate_refcounts[i] == UINT_MAX) {
|
||||
ERROR("Clock %lu refcount reached max value\n", id);
|
||||
panic();
|
||||
}
|
||||
|
||||
stm32mp1_clk_unlock(&refcount_lock);
|
||||
}
|
||||
|
||||
void __stm32mp1_clk_disable(unsigned long id, bool secure)
|
||||
static void __stm32mp1_clk_disable(unsigned long id, bool with_refcnt)
|
||||
{
|
||||
const struct stm32mp1_clk_gate *gate;
|
||||
int i;
|
||||
unsigned int *refcnt;
|
||||
|
||||
if (clock_is_always_on(id)) {
|
||||
return;
|
||||
|
@ -1146,11 +1175,28 @@ void __stm32mp1_clk_disable(unsigned long id, bool secure)
|
|||
}
|
||||
|
||||
gate = gate_ref(i);
|
||||
refcnt = &gate_refcounts[i];
|
||||
|
||||
if (!with_refcnt) {
|
||||
__clk_disable(gate);
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(IMAGE_BL32)
|
||||
if (gate_is_non_secure(gate)) {
|
||||
/* Don't disable non-secure clocks */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
stm32mp1_clk_lock(&refcount_lock);
|
||||
|
||||
if (stm32mp_decr_shrefcnt(refcnt, secure) != 0) {
|
||||
if (gate_refcounts[i] == 0U) {
|
||||
ERROR("Clock %lu refcount reached 0\n", id);
|
||||
panic();
|
||||
}
|
||||
gate_refcounts[i]--;
|
||||
|
||||
if (gate_refcounts[i] == 0U) {
|
||||
__clk_disable(gate);
|
||||
}
|
||||
|
||||
|
@ -1720,50 +1766,6 @@ static void stm32mp1_set_rtcsrc(unsigned int clksrc, bool lse_css)
|
|||
}
|
||||
}
|
||||
|
||||
static void stm32mp1_stgen_config(void)
|
||||
{
|
||||
uint32_t cntfid0;
|
||||
unsigned long rate;
|
||||
unsigned long long counter;
|
||||
|
||||
cntfid0 = mmio_read_32(STGEN_BASE + CNTFID_OFF);
|
||||
rate = get_clock_rate(stm32mp1_clk_get_parent(STGEN_K));
|
||||
|
||||
if (cntfid0 == rate) {
|
||||
return;
|
||||
}
|
||||
|
||||
mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
|
||||
counter = (unsigned long long)mmio_read_32(STGEN_BASE + CNTCVL_OFF);
|
||||
counter |= ((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF)) << 32;
|
||||
counter = (counter * rate / cntfid0);
|
||||
|
||||
mmio_write_32(STGEN_BASE + CNTCVL_OFF, (uint32_t)counter);
|
||||
mmio_write_32(STGEN_BASE + CNTCVU_OFF, (uint32_t)(counter >> 32));
|
||||
mmio_write_32(STGEN_BASE + CNTFID_OFF, rate);
|
||||
mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
|
||||
|
||||
write_cntfrq((u_register_t)rate);
|
||||
|
||||
/* Need to update timer with new frequency */
|
||||
generic_delay_timer_init();
|
||||
}
|
||||
|
||||
void stm32mp1_stgen_increment(unsigned long long offset_in_ms)
|
||||
{
|
||||
unsigned long long cnt;
|
||||
|
||||
cnt = ((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF) << 32) |
|
||||
mmio_read_32(STGEN_BASE + CNTCVL_OFF);
|
||||
|
||||
cnt += (offset_in_ms * mmio_read_32(STGEN_BASE + CNTFID_OFF)) / 1000U;
|
||||
|
||||
mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
|
||||
mmio_write_32(STGEN_BASE + CNTCVL_OFF, (uint32_t)cnt);
|
||||
mmio_write_32(STGEN_BASE + CNTCVU_OFF, (uint32_t)(cnt >> 32));
|
||||
mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
|
||||
}
|
||||
|
||||
static void stm32mp1_pkcs_config(uint32_t pkcs)
|
||||
{
|
||||
uintptr_t address = stm32mp_rcc_base() + ((pkcs >> 4) & 0xFFFU);
|
||||
|
@ -1959,7 +1961,8 @@ int stm32mp1_clk_init(void)
|
|||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
stm32mp1_stgen_config();
|
||||
|
||||
stm32mp_stgen_config(stm32mp_clk_get_rate(STGEN_K));
|
||||
}
|
||||
|
||||
/* Select DIV */
|
||||
|
@ -2133,7 +2136,8 @@ int stm32mp1_clk_init(void)
|
|||
if (stm32mp1_osc[_HSI] == 0U) {
|
||||
stm32mp1_hsi_set(false);
|
||||
}
|
||||
stm32mp1_stgen_config();
|
||||
|
||||
stm32mp_stgen_config(stm32mp_clk_get_rate(STGEN_K));
|
||||
|
||||
/* Software Self-Refresh mode (SSR) during DDR initilialization */
|
||||
mmio_clrsetbits_32(rcc_base + RCC_DDRITFCR,
|
||||
|
|
|
@ -6,10 +6,13 @@
|
|||
|
||||
#include <errno.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <common/fdt_wrappers.h>
|
||||
#include <drivers/clk.h>
|
||||
#include <drivers/generic_delay_timer.h>
|
||||
#include <drivers/st/stm32_gpio.h>
|
||||
#include <drivers/st/stm32mp_clkfunc.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <libfdt.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
@ -318,3 +321,60 @@ unsigned long fdt_get_uart_clock_freq(uintptr_t instance)
|
|||
|
||||
return clk_get_rate((unsigned long)clk_id);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function configures and restores the STGEN counter depending on the
|
||||
* connected clock.
|
||||
******************************************************************************/
|
||||
void stm32mp_stgen_config(unsigned long rate)
|
||||
{
|
||||
uint32_t cntfid0;
|
||||
unsigned long long counter;
|
||||
|
||||
cntfid0 = mmio_read_32(STGEN_BASE + CNTFID_OFF);
|
||||
|
||||
if (cntfid0 == rate) {
|
||||
return;
|
||||
}
|
||||
|
||||
mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
|
||||
counter = stm32mp_stgen_get_counter() * rate / cntfid0;
|
||||
|
||||
mmio_write_32(STGEN_BASE + CNTCVL_OFF, (uint32_t)counter);
|
||||
mmio_write_32(STGEN_BASE + CNTCVU_OFF, (uint32_t)(counter >> 32));
|
||||
mmio_write_32(STGEN_BASE + CNTFID_OFF, rate);
|
||||
mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
|
||||
|
||||
write_cntfrq_el0(rate);
|
||||
|
||||
/* Need to update timer with new frequency */
|
||||
generic_delay_timer_init();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function returns the STGEN counter value.
|
||||
******************************************************************************/
|
||||
unsigned long long stm32mp_stgen_get_counter(void)
|
||||
{
|
||||
return (((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF) << 32) |
|
||||
mmio_read_32(STGEN_BASE + CNTCVL_OFF));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function restores the STGEN counter value.
|
||||
* It takes a first input value as a counter backup value to be restored and a
|
||||
* offset in ms to be added.
|
||||
******************************************************************************/
|
||||
void stm32mp_stgen_restore_counter(unsigned long long value,
|
||||
unsigned long long offset_in_ms)
|
||||
{
|
||||
unsigned long long cnt;
|
||||
|
||||
cnt = value + ((offset_in_ms *
|
||||
mmio_read_32(STGEN_BASE + CNTFID_OFF)) / 1000U);
|
||||
|
||||
mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
|
||||
mmio_write_32(STGEN_BASE + CNTCVL_OFF, (uint32_t)cnt);
|
||||
mmio_write_32(STGEN_BASE + CNTCVU_OFF, (uint32_t)(cnt >> 32));
|
||||
mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved
|
||||
* Copyright (c) 2018-2022, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -28,37 +28,10 @@ int stm32mp1_clk_init(void);
|
|||
bool stm32mp1_rcc_is_secure(void);
|
||||
bool stm32mp1_rcc_is_mckprot(void);
|
||||
|
||||
void __stm32mp1_clk_enable(unsigned long id, bool caller_is_secure);
|
||||
void __stm32mp1_clk_disable(unsigned long id, bool caller_is_secure);
|
||||
|
||||
static inline void stm32mp1_clk_enable_non_secure(unsigned long id)
|
||||
{
|
||||
__stm32mp1_clk_enable(id, false);
|
||||
}
|
||||
|
||||
static inline void stm32mp1_clk_enable_secure(unsigned long id)
|
||||
{
|
||||
__stm32mp1_clk_enable(id, true);
|
||||
}
|
||||
|
||||
static inline void stm32mp1_clk_disable_non_secure(unsigned long id)
|
||||
{
|
||||
__stm32mp1_clk_disable(id, false);
|
||||
}
|
||||
|
||||
static inline void stm32mp1_clk_disable_secure(unsigned long id)
|
||||
{
|
||||
__stm32mp1_clk_disable(id, true);
|
||||
}
|
||||
|
||||
unsigned int stm32mp1_clk_get_refcount(unsigned long id);
|
||||
|
||||
/* SMP protection on RCC registers access */
|
||||
void stm32mp1_clk_rcc_regs_lock(void);
|
||||
void stm32mp1_clk_rcc_regs_unlock(void);
|
||||
|
||||
void stm32mp1_stgen_increment(unsigned long long offset_in_ms);
|
||||
|
||||
#ifdef STM32MP_SHARED_RESOURCES
|
||||
void stm32mp1_register_clock_parents_secure(unsigned long id);
|
||||
#endif
|
||||
|
|
|
@ -28,4 +28,9 @@ bool fdt_get_rcc_secure_status(void);
|
|||
int fdt_get_clock_id(int node);
|
||||
unsigned long fdt_get_uart_clock_freq(uintptr_t instance);
|
||||
|
||||
void stm32mp_stgen_config(unsigned long rate);
|
||||
void stm32mp_stgen_restore_counter(unsigned long long value,
|
||||
unsigned long long offset_in_ms);
|
||||
unsigned long long stm32mp_stgen_get_counter(void);
|
||||
|
||||
#endif /* STM32MP_CLKFUNC_H */
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef STM32MP_SHRES_HELPERS_H
|
||||
#define STM32MP_SHRES_HELPERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
|
||||
/*
|
||||
* Shared reference counter: increments by 2 on secure increment
|
||||
* request, decrements by 2 on secure decrement request. Bit #0
|
||||
* is set to 1 on non-secure increment request and reset to 0 on
|
||||
* non-secure decrement request. The counter initializes to
|
||||
* either 0, 1 or 2 upon their expect default state.
|
||||
* Counters saturates once above UINT_MAX / 2.
|
||||
*/
|
||||
#define SHREFCNT_NONSECURE_FLAG 0x1UL
|
||||
#define SHREFCNT_SECURE_STEP 0x2UL
|
||||
#define SHREFCNT_MAX (UINT32_MAX / 2)
|
||||
|
||||
/* Return 1 if refcnt increments from 0, else return 0 */
|
||||
static inline int stm32mp_incr_shrefcnt(unsigned int *refcnt, bool secure)
|
||||
{
|
||||
int rc = !*refcnt;
|
||||
|
||||
if (secure) {
|
||||
*refcnt += SHREFCNT_SECURE_STEP;
|
||||
if (*refcnt >= SHREFCNT_MAX) {
|
||||
panic();
|
||||
}
|
||||
} else {
|
||||
*refcnt |= SHREFCNT_NONSECURE_FLAG;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Return 1 if refcnt decrements to 0, else return 0 */
|
||||
static inline int stm32mp_decr_shrefcnt(unsigned int *refcnt, bool secure)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (secure) {
|
||||
if (*refcnt < SHREFCNT_MAX) {
|
||||
if (*refcnt < SHREFCNT_SECURE_STEP) {
|
||||
panic();
|
||||
}
|
||||
*refcnt -= SHREFCNT_SECURE_STEP;
|
||||
rc = !*refcnt;
|
||||
}
|
||||
} else {
|
||||
rc = (*refcnt == SHREFCNT_NONSECURE_FLAG) ? 1 : 0;
|
||||
*refcnt &= ~SHREFCNT_NONSECURE_FLAG;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline int stm32mp_incr_refcnt(unsigned int *refcnt)
|
||||
{
|
||||
return stm32mp_incr_shrefcnt(refcnt, true);
|
||||
}
|
||||
|
||||
static inline int stm32mp_decr_refcnt(unsigned int *refcnt)
|
||||
{
|
||||
return stm32mp_decr_shrefcnt(refcnt, true);
|
||||
}
|
||||
|
||||
#endif /* STM32MP_SHRES_HELPERS_H */
|
|
@ -1,11 +1,12 @@
|
|||
/*
|
||||
* Copyright (c) 2019, STMicroelectronics - All Rights Reserved
|
||||
* Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/nand.h>
|
||||
#include <drivers/raw_nand.h>
|
||||
#include <drivers/spi_nand.h>
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include <stm32mp_auth.h>
|
||||
#include <stm32mp_common.h>
|
||||
#include <stm32mp_dt.h>
|
||||
#include <stm32mp_shres_helpers.h>
|
||||
#include <stm32mp1_dbgmcu.h>
|
||||
#include <stm32mp1_private.h>
|
||||
#include <stm32mp1_shared_resources.h>
|
||||
|
|
Loading…
Reference in New Issue