Browse Source

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
pull/1983/merge
Manish Pandey 3 years ago
committed by TrustedFirmware Code Review
parent
commit
e672698ce7
  1. 292
      drivers/st/clk/stm32mp1_clk.c
  2. 60
      drivers/st/clk/stm32mp_clkfunc.c
  3. 29
      include/drivers/st/stm32mp1_clk.h
  4. 5
      include/drivers/st/stm32mp_clkfunc.h
  5. 74
      plat/st/common/include/stm32mp_shres_helpers.h
  6. 3
      plat/st/stm32mp1/stm32mp1_boot_device.c
  7. 1
      plat/st/stm32mp1/stm32mp1_def.h

292
drivers/st/clk/stm32mp1_clk.c

@ -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_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),
_CLK_SC_FIXED(RCC_MP_APB2ENSETR, 2, TIM15_K, _PCLK2),
_CLK_SC_SELEC(RCC_MP_APB2ENSETR, 13, USART6_K, _UART6_SEL),
_CLK_SC_FIXED(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(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(RCC_MP_AHB2ENSETR, 8, USBO_K, _USBO_SEL),
_CLK_SC_SELEC(RCC_MP_AHB2ENSETR, 16, SDMMC3_K, _SDMMC3_SEL),
_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_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_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),
_CLK_SELEC(RCC_BDCR, 20, RTC, _RTC_SEL),
_CLK_SELEC(RCC_DBGCFGR, 8, CK_DBG, _UNKNOWN_SEL),
_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),
#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),
#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(N_S, RCC_MP_APB3ENSETR, 11, SYSCFG, _UNKNOWN_ID),
_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(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),
#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(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(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),
#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(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,

60
drivers/st/clk/stm32mp_clkfunc.c

@ -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);
}

29
include/drivers/st/stm32mp1_clk.h

@ -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

5
include/drivers/st/stm32mp_clkfunc.h

@ -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 */

74
plat/st/common/include/stm32mp_shres_helpers.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 */

3
plat/st/stm32mp1/stm32mp1_boot_device.c

@ -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>

1
plat/st/stm32mp1/stm32mp1_def.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…
Cancel
Save