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>
This commit is contained in:
parent
a2150c33ed
commit
37e8295abd
|
@ -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;
|
||||
|
|
|
@ -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…
Reference in New Issue