diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index c9bb9ff..11fd666 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -70,6 +70,7 @@ _HCLK2, _CK_PER, _CK_MPU, + _CK_MCU, _USB_PHY_48, _PARENT_NB, _UNKNOWN_ID = 0xff, @@ -93,6 +94,7 @@ _QSPI_SEL, _FMC_SEL, _ASS_SEL, + _MSS_SEL, _USBPHY_SEL, _USBO_SEL, _PARENT_SEL_NB, @@ -117,6 +119,7 @@ enum stm32mp1_clksrc_id { CLKSRC_MPU, CLKSRC_AXI, + CLKSRC_MCU, CLKSRC_PLL12, CLKSRC_PLL3, CLKSRC_PLL4, @@ -129,6 +132,7 @@ enum stm32mp1_clkdiv_id { CLKDIV_MPU, CLKDIV_AXI, + CLKDIV_MCU, CLKDIV_APB1, CLKDIV_APB2, CLKDIV_APB3, @@ -272,6 +276,7 @@ { 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 @@ _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 @@ _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 @@ }; /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 */ diff --git a/fdts/stm32mp157a-dk1.dts b/fdts/stm32mp157a-dk1.dts index 0314171..cf0fe28 100644 --- a/fdts/stm32mp157a-dk1.dts +++ b/fdts/stm32mp157a-dk1.dts @@ -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*/ diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts index 5d8817f..0fadffb 100644 --- a/fdts/stm32mp157c-ed1.dts +++ b/fdts/stm32mp157c-ed1.dts @@ -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*/ diff --git a/include/drivers/st/stm32mp1_clk.h b/include/drivers/st/stm32mp1_clk.h index 1e0d949..7afa5ad 100644 --- a/include/drivers/st/stm32mp1_clk.h +++ b/include/drivers/st/stm32mp1_clk.h @@ -13,6 +13,7 @@ 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); diff --git a/include/drivers/st/stm32mp1_rcc.h b/include/drivers/st/stm32mp1_rcc.h index 1922c48..eaa853d 100644 --- a/include/drivers/st/stm32mp1_rcc.h +++ b/include/drivers/st/stm32mp1_rcc.h @@ -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_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) diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index c7bc39f..2477954 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -202,6 +202,9 @@ 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) { diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index f0dc575..1c897bd 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -183,6 +183,7 @@ #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) diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c index ebf1587..0ad43e4 100644 --- a/plat/st/stm32mp1/stm32mp1_security.c +++ b/plat/st/stm32mp1/stm32mp1_security.c @@ -41,6 +41,7 @@ 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) |