Browse Source

drivers: st: clock: register parent of secure clocks

Introduce stm32mp1_register_clock_parents_secure() in stm32mp1
clock driver to allow platform shared resources to register as
secure the parent clocks of a clock registered as secure.

Change-Id: I53a9ab6aa78ee840ededce67e7b12a84e08ee843
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
pull/1979/head
Etienne Carriere 5 years ago
parent
commit
37e8295abd
  1. 196
      drivers/st/clk/stm32mp1_clk.c
  2. 3
      include/drivers/st/stm32mp1_clk.h

196
drivers/st/clk/stm32mp1_clk.c

@ -577,6 +577,43 @@ static const uint8_t stm32mp1_axi_div[8] = {
1, 2, 3, 4, 4, 4, 4, 4
};
static const char * const stm32mp1_clk_parent_name[_PARENT_NB] __unused = {
[_HSI] = "HSI",
[_HSE] = "HSE",
[_CSI] = "CSI",
[_LSI] = "LSI",
[_LSE] = "LSE",
[_I2S_CKIN] = "I2S_CKIN",
[_HSI_KER] = "HSI_KER",
[_HSE_KER] = "HSE_KER",
[_HSE_KER_DIV2] = "HSE_KER_DIV2",
[_CSI_KER] = "CSI_KER",
[_PLL1_P] = "PLL1_P",
[_PLL1_Q] = "PLL1_Q",
[_PLL1_R] = "PLL1_R",
[_PLL2_P] = "PLL2_P",
[_PLL2_Q] = "PLL2_Q",
[_PLL2_R] = "PLL2_R",
[_PLL3_P] = "PLL3_P",
[_PLL3_Q] = "PLL3_Q",
[_PLL3_R] = "PLL3_R",
[_PLL4_P] = "PLL4_P",
[_PLL4_Q] = "PLL4_Q",
[_PLL4_R] = "PLL4_R",
[_ACLK] = "ACLK",
[_PCLK1] = "PCLK1",
[_PCLK2] = "PCLK2",
[_PCLK3] = "PCLK3",
[_PCLK4] = "PCLK4",
[_PCLK5] = "PCLK5",
[_HCLK6] = "KCLK6",
[_HCLK2] = "HCLK2",
[_CK_PER] = "CK_PER",
[_CK_MPU] = "CK_MPU",
[_CK_MCU] = "CK_MCU",
[_USB_PHY_48] = "USB_PHY_48",
};
/* RCC clock device driver private */
static unsigned long stm32mp1_osc[NB_OSC];
static struct spinlock reg_lock;
@ -2007,6 +2044,165 @@ static void stm32mp1_osc_init(void)
}
}
#ifdef STM32MP_SHARED_RESOURCES
/*
* Get the parent ID of the target parent clock, for tagging as secure
* shared clock dependencies.
*/
static int get_parent_id_parent(unsigned int parent_id)
{
enum stm32mp1_parent_sel s = _UNKNOWN_SEL;
enum stm32mp1_pll_id pll_id;
uint32_t p_sel;
uintptr_t rcc_base = stm32mp_rcc_base();
switch (parent_id) {
case _ACLK:
case _PCLK4:
case _PCLK5:
s = _AXIS_SEL;
break;
case _PLL1_P:
case _PLL1_Q:
case _PLL1_R:
pll_id = _PLL1;
break;
case _PLL2_P:
case _PLL2_Q:
case _PLL2_R:
pll_id = _PLL2;
break;
case _PLL3_P:
case _PLL3_Q:
case _PLL3_R:
pll_id = _PLL3;
break;
case _PLL4_P:
case _PLL4_Q:
case _PLL4_R:
pll_id = _PLL4;
break;
case _PCLK1:
case _PCLK2:
case _HCLK2:
case _HCLK6:
case _CK_PER:
case _CK_MPU:
case _CK_MCU:
case _USB_PHY_48:
/* We do not expect to access these */
panic();
break;
default:
/* Other parents have no parent */
return -1;
}
if (s != _UNKNOWN_SEL) {
const struct stm32mp1_clk_sel *sel = clk_sel_ref(s);
p_sel = (mmio_read_32(rcc_base + sel->offset) >> sel->src) &
sel->msk;
if (p_sel < sel->nb_parent) {
return (int)sel->parent[p_sel];
}
} else {
const struct stm32mp1_clk_pll *pll = pll_ref(pll_id);
p_sel = mmio_read_32(rcc_base + pll->rckxselr) &
RCC_SELR_REFCLK_SRC_MASK;
if (pll->refclk[p_sel] != _UNKNOWN_OSC_ID) {
return (int)pll->refclk[p_sel];
}
}
VERBOSE("No parent selected for %s\n",
stm32mp1_clk_parent_name[parent_id]);
return -1;
}
static void secure_parent_clocks(unsigned long parent_id)
{
int grandparent_id;
switch (parent_id) {
case _PLL3_P:
case _PLL3_Q:
case _PLL3_R:
stm32mp_register_secure_periph(STM32MP1_SHRES_PLL3);
break;
/* These clocks are always secure when RCC is secure */
case _ACLK:
case _HCLK2:
case _HCLK6:
case _PCLK4:
case _PCLK5:
case _PLL1_P:
case _PLL1_Q:
case _PLL1_R:
case _PLL2_P:
case _PLL2_Q:
case _PLL2_R:
case _HSI:
case _HSI_KER:
case _LSI:
case _CSI:
case _CSI_KER:
case _HSE:
case _HSE_KER:
case _HSE_KER_DIV2:
case _LSE:
break;
default:
VERBOSE("Cannot secure parent clock %s\n",
stm32mp1_clk_parent_name[parent_id]);
panic();
}
grandparent_id = get_parent_id_parent(parent_id);
if (grandparent_id >= 0) {
secure_parent_clocks(grandparent_id);
}
}
void stm32mp1_register_clock_parents_secure(unsigned long clock_id)
{
int parent_id;
if (!stm32mp1_rcc_is_secure()) {
return;
}
switch (clock_id) {
case PLL1:
case PLL2:
/* PLL1/PLL2 are always secure: nothing to do */
break;
case PLL3:
stm32mp_register_secure_periph(STM32MP1_SHRES_PLL3);
break;
case PLL4:
ERROR("PLL4 cannot be secured\n");
panic();
break;
default:
/* Others are expected gateable clock */
parent_id = stm32mp1_clk_get_parent(clock_id);
if (parent_id < 0) {
INFO("No parent found for clock %lu\n", clock_id);
} else {
secure_parent_clocks(parent_id);
}
break;
}
}
#endif /* STM32MP_SHARED_RESOURCES */
static void sync_earlyboot_clocks_state(void)
{
unsigned int idx;

3
include/drivers/st/stm32mp1_clk.h

@ -59,4 +59,7 @@ 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
#endif /* STM32MP1_CLK_H */

Loading…
Cancel
Save