mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-17 01:54:22 +00:00
stm32mp1: add minimal support for co-processor Cortex-M4
STM32MP1 chip embeds a dual Cortex-A7 and a Cortex-M4. The support for Cortex-M4 clocks is added when configuring the clock tree. Some minimal security features to allow communications between A7 and M4 are also added. Change-Id: I60417e244a476f60a2758f4969700b2684056665 Signed-off-by: Yann Gautier <yann.gautier@st.com>
This commit is contained in:
parent
774b4a8190
commit
b053a22e8a
8 changed files with 92 additions and 0 deletions
|
@ -70,6 +70,7 @@ enum stm32mp1_parent_id {
|
|||
_HCLK2,
|
||||
_CK_PER,
|
||||
_CK_MPU,
|
||||
_CK_MCU,
|
||||
_USB_PHY_48,
|
||||
_PARENT_NB,
|
||||
_UNKNOWN_ID = 0xff,
|
||||
|
@ -93,6 +94,7 @@ enum stm32mp1_parent_sel {
|
|||
_QSPI_SEL,
|
||||
_FMC_SEL,
|
||||
_ASS_SEL,
|
||||
_MSS_SEL,
|
||||
_USBPHY_SEL,
|
||||
_USBO_SEL,
|
||||
_PARENT_SEL_NB,
|
||||
|
@ -117,6 +119,7 @@ enum stm32mp1_div_id {
|
|||
enum stm32mp1_clksrc_id {
|
||||
CLKSRC_MPU,
|
||||
CLKSRC_AXI,
|
||||
CLKSRC_MCU,
|
||||
CLKSRC_PLL12,
|
||||
CLKSRC_PLL3,
|
||||
CLKSRC_PLL4,
|
||||
|
@ -129,6 +132,7 @@ enum stm32mp1_clksrc_id {
|
|||
enum stm32mp1_clkdiv_id {
|
||||
CLKDIV_MPU,
|
||||
CLKDIV_AXI,
|
||||
CLKDIV_MCU,
|
||||
CLKDIV_APB1,
|
||||
CLKDIV_APB2,
|
||||
CLKDIV_APB3,
|
||||
|
@ -272,6 +276,7 @@ static const uint8_t stm32mp1_clks[][2] = {
|
|||
{ CK_PER, _CK_PER },
|
||||
{ CK_MPU, _CK_MPU },
|
||||
{ CK_AXI, _ACLK },
|
||||
{ CK_MCU, _CK_MCU },
|
||||
{ CK_HSE, _HSE },
|
||||
{ CK_CSI, _CSI },
|
||||
{ CK_LSI, _LSI },
|
||||
|
@ -412,6 +417,10 @@ static const uint8_t ass_parents[] = {
|
|||
_HSI, _HSE, _PLL2
|
||||
};
|
||||
|
||||
static const uint8_t mss_parents[] = {
|
||||
_HSI, _HSE, _CSI, _PLL3
|
||||
};
|
||||
|
||||
static const uint8_t usbphy_parents[] = {
|
||||
_HSE_KER, _PLL4_R, _HSE_KER_DIV2
|
||||
};
|
||||
|
@ -437,6 +446,7 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
|
|||
_CLK_PARENT(_QSPI_SEL, RCC_QSPICKSELR, 0, 0xf, qspi_parents),
|
||||
_CLK_PARENT(_FMC_SEL, RCC_FMCCKSELR, 0, 0xf, fmc_parents),
|
||||
_CLK_PARENT(_ASS_SEL, RCC_ASSCKSELR, 0, 0x3, ass_parents),
|
||||
_CLK_PARENT(_MSS_SEL, RCC_MSSCKSELR, 0, 0x3, mss_parents),
|
||||
_CLK_PARENT(_USBPHY_SEL, RCC_USBCKSELR, 0, 0x3, usbphy_parents),
|
||||
_CLK_PARENT(_USBO_SEL, RCC_USBCKSELR, 4, 0x1, usbo_parents),
|
||||
};
|
||||
|
@ -483,6 +493,10 @@ static const struct stm32mp1_clk_pll stm32mp1_clk_pll[_PLL_NB] = {
|
|||
};
|
||||
|
||||
/* Prescaler table lookups for clock computation */
|
||||
/* div = /1 /2 /4 /8 / 16 /64 /128 /512 */
|
||||
static const uint8_t stm32mp1_mcu_div[16] = {
|
||||
0, 1, 2, 3, 4, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9
|
||||
};
|
||||
|
||||
/* div = /1 /2 /4 /8 /16 : same divider for PMU and APBX */
|
||||
#define stm32mp1_mpu_div stm32mp1_mpu_apbx_div
|
||||
|
@ -549,6 +563,13 @@ bool stm32mp1_rcc_is_secure(void)
|
|||
return (mmio_read_32(rcc_base + RCC_TZCR) & RCC_TZCR_TZEN) != 0;
|
||||
}
|
||||
|
||||
bool stm32mp1_rcc_is_mckprot(void)
|
||||
{
|
||||
uintptr_t rcc_base = stm32mp_rcc_base();
|
||||
|
||||
return (mmio_read_32(rcc_base + RCC_TZCR) & RCC_TZCR_MCKPROT) != 0;
|
||||
}
|
||||
|
||||
void stm32mp1_clk_rcc_regs_lock(void)
|
||||
{
|
||||
stm32mp1_clk_lock(®_lock);
|
||||
|
@ -775,6 +796,51 @@ static unsigned long get_clock_rate(int p)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
/* MCU sub system */
|
||||
case _CK_MCU:
|
||||
case _PCLK1:
|
||||
case _PCLK2:
|
||||
case _PCLK3:
|
||||
reg = mmio_read_32(rcc_base + RCC_MSSCKSELR);
|
||||
switch (reg & RCC_SELR_SRC_MASK) {
|
||||
case RCC_MSSCKSELR_HSI:
|
||||
clock = stm32mp1_clk_get_fixed(_HSI);
|
||||
break;
|
||||
case RCC_MSSCKSELR_HSE:
|
||||
clock = stm32mp1_clk_get_fixed(_HSE);
|
||||
break;
|
||||
case RCC_MSSCKSELR_CSI:
|
||||
clock = stm32mp1_clk_get_fixed(_CSI);
|
||||
break;
|
||||
case RCC_MSSCKSELR_PLL:
|
||||
clock = stm32mp1_read_pll_freq(_PLL3, _DIV_P);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* MCU clock divider */
|
||||
reg = mmio_read_32(rcc_base + RCC_MCUDIVR);
|
||||
clock >>= stm32mp1_mcu_div[reg & RCC_MCUDIV_MASK];
|
||||
|
||||
switch (p) {
|
||||
case _PCLK1:
|
||||
reg = mmio_read_32(rcc_base + RCC_APB1DIVR);
|
||||
clock >>= stm32mp1_apbx_div[reg & RCC_APBXDIV_MASK];
|
||||
break;
|
||||
case _PCLK2:
|
||||
reg = mmio_read_32(rcc_base + RCC_APB2DIVR);
|
||||
clock >>= stm32mp1_apbx_div[reg & RCC_APBXDIV_MASK];
|
||||
break;
|
||||
case _PCLK3:
|
||||
reg = mmio_read_32(rcc_base + RCC_APB3DIVR);
|
||||
clock >>= stm32mp1_apbx_div[reg & RCC_APBXDIV_MASK];
|
||||
break;
|
||||
case _CK_MCU:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case _CK_PER:
|
||||
reg = mmio_read_32(rcc_base + RCC_CPERCKSELR);
|
||||
switch (reg & RCC_SELR_SRC_MASK) {
|
||||
|
@ -1609,6 +1675,10 @@ int stm32mp1_clk_init(void)
|
|||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = stm32mp1_set_clksrc(CLK_MCU_HSI);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((mmio_read_32(rcc_base + RCC_MP_RSTSCLRR) &
|
||||
RCC_MP_RSTSCLRR_MPUP0RSTF) != 0) {
|
||||
|
@ -1659,6 +1729,10 @@ int stm32mp1_clk_init(void)
|
|||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_MCU], rcc_base + RCC_MCUDIVR);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB1], rcc_base + RCC_APB1DIVR);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
|
@ -1757,6 +1831,10 @@ int stm32mp1_clk_init(void)
|
|||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = stm32mp1_set_clksrc(clksrc[CLKSRC_MCU]);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
stm32mp1_set_rtcsrc(clksrc[CLKSRC_RTC], lse_css);
|
||||
|
||||
/* Configure PKCK */
|
||||
|
|
|
@ -204,6 +204,7 @@
|
|||
st,clksrc = <
|
||||
CLK_MPU_PLL1P
|
||||
CLK_AXI_PLL2P
|
||||
CLK_MCU_PLL3P
|
||||
CLK_PLL12_HSE
|
||||
CLK_PLL3_HSE
|
||||
CLK_PLL4_HSE
|
||||
|
@ -215,6 +216,7 @@
|
|||
st,clkdiv = <
|
||||
1 /*MPU*/
|
||||
0 /*AXI*/
|
||||
0 /*MCU*/
|
||||
1 /*APB1*/
|
||||
1 /*APB2*/
|
||||
1 /*APB3*/
|
||||
|
|
|
@ -224,6 +224,7 @@
|
|||
st,clksrc = <
|
||||
CLK_MPU_PLL1P
|
||||
CLK_AXI_PLL2P
|
||||
CLK_MCU_PLL3P
|
||||
CLK_PLL12_HSE
|
||||
CLK_PLL3_HSE
|
||||
CLK_PLL4_HSE
|
||||
|
@ -235,6 +236,7 @@
|
|||
st,clkdiv = <
|
||||
1 /*MPU*/
|
||||
0 /*AXI*/
|
||||
0 /*MCU*/
|
||||
1 /*APB1*/
|
||||
1 /*APB2*/
|
||||
1 /*APB3*/
|
||||
|
|
|
@ -13,6 +13,7 @@ int stm32mp1_clk_probe(void);
|
|||
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);
|
||||
|
|
|
@ -111,6 +111,7 @@
|
|||
#define RCC_RCK4SELR U(0x824)
|
||||
#define RCC_TIMG1PRER U(0x828)
|
||||
#define RCC_TIMG2PRER U(0x82C)
|
||||
#define RCC_MCUDIVR U(0x830)
|
||||
#define RCC_APB1DIVR U(0x834)
|
||||
#define RCC_APB2DIVR U(0x838)
|
||||
#define RCC_APB3DIVR U(0x83C)
|
||||
|
@ -237,6 +238,7 @@
|
|||
|
||||
/* Values for RCC_TZCR register */
|
||||
#define RCC_TZCR_TZEN BIT(0)
|
||||
#define RCC_TZCR_MCKPROT BIT(1)
|
||||
|
||||
/* Used for most of RCC_<x>SELR registers */
|
||||
#define RCC_SELR_SRC_MASK GENMASK(2, 0)
|
||||
|
@ -273,6 +275,7 @@
|
|||
#define RCC_APBXDIV_MASK GENMASK(2, 0)
|
||||
#define RCC_MPUDIV_MASK GENMASK(2, 0)
|
||||
#define RCC_AXIDIV_MASK GENMASK(2, 0)
|
||||
#define RCC_MCUDIV_MASK GENMASK(3, 0)
|
||||
|
||||
/* Used for TIMER Prescaler */
|
||||
#define RCC_TIMGXPRER_TIMGXPRE BIT(0)
|
||||
|
@ -421,6 +424,7 @@
|
|||
|
||||
/* Global Reset Register */
|
||||
#define RCC_MP_GRSTCSETR_MPSYSRST BIT(0)
|
||||
#define RCC_MP_GRSTCSETR_MCURST BIT(1)
|
||||
#define RCC_MP_GRSTCSETR_MPUP0RST BIT(4)
|
||||
#define RCC_MP_GRSTCSETR_MPUP1RST BIT(5)
|
||||
|
||||
|
|
|
@ -202,6 +202,9 @@ void bl2_el3_plat_arch_setup(void)
|
|||
mmio_clrbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST);
|
||||
}
|
||||
|
||||
/* Disable MCKPROT */
|
||||
mmio_clrbits_32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT);
|
||||
|
||||
generic_delay_timer_init();
|
||||
|
||||
if (stm32mp1_clk_probe() < 0) {
|
||||
|
|
|
@ -183,6 +183,7 @@ enum ddr_type {
|
|||
#define STM32MP1_TZC_BASE U(0x5C006000)
|
||||
|
||||
#define STM32MP1_TZC_A7_ID U(0)
|
||||
#define STM32MP1_TZC_M4_ID U(1)
|
||||
#define STM32MP1_TZC_LCD_ID U(3)
|
||||
#define STM32MP1_TZC_GPU_ID U(4)
|
||||
#define STM32MP1_TZC_MDMA_ID U(5)
|
||||
|
|
|
@ -41,6 +41,7 @@ static void init_tzc400(void)
|
|||
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) |
|
||||
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) |
|
||||
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_ID) |
|
||||
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_M4_ID) |
|
||||
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DMA_ID) |
|
||||
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) |
|
||||
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) |
|
||||
|
|
Loading…
Add table
Reference in a new issue