Forum | Documentation | Website | Blog

Skip to content
Snippets Groups Projects
Unverified Commit ab3d2247 authored by Antonio Niño Díaz's avatar Antonio Niño Díaz Committed by GitHub
Browse files

Merge pull request #1836 from Yann-lms/docs_and_m4

Update documentation for STM32MP1 and add Cortex-M4 support
parents 3f995f30 b053a22e
Branches
Tags
No related merge requests found
...@@ -4,6 +4,8 @@ Trusted Firmware-A for STM32MP1 ...@@ -4,6 +4,8 @@ Trusted Firmware-A for STM32MP1
STM32MP1 is a microprocessor designed by STMicroelectronics STM32MP1 is a microprocessor designed by STMicroelectronics
based on a dual Arm Cortex-A7. based on a dual Arm Cortex-A7.
It is an Armv7-A platform, using dedicated code from TF-A. It is an Armv7-A platform, using dedicated code from TF-A.
The STM32MP1 chip also embeds a Cortex-M4.
More information can be found on `STM32MP1 Series`_ page.
Design Design
...@@ -78,7 +80,7 @@ To build: ...@@ -78,7 +80,7 @@ To build:
make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=sp_min make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=sp_min
cd <u-boot_directory> cd <u-boot_directory>
make stm32mp15_basic_defconfig make stm32mp15_basic_defconfig
make DEVICE_TREE=stm32mp157c_ev1 all make DEVICE_TREE=stm32mp157c-ev1 all
./tools/mkimage -T stm32image -a 0xC0100000 -e 0xC0100000 -d u-boot.bin u-boot.stm32 ./tools/mkimage -T stm32image -a 0xC0100000 -e 0xC0100000 -d u-boot.bin u-boot.stm32
The following build options are supported: The following build options are supported:
...@@ -96,3 +98,6 @@ It should contain at least those partitions: ...@@ -96,3 +98,6 @@ It should contain at least those partitions:
- ssbl: to copy the u-boot.stm32 binary - ssbl: to copy the u-boot.stm32 binary
Usually, two copies of fsbl are used (fsbl1 and fsbl2) instead of one partition fsbl. Usually, two copies of fsbl are used (fsbl1 and fsbl2) instead of one partition fsbl.
.. _STM32MP1 Series: https://www.st.com/en/microcontrollers-microprocessors/stm32mp1-series.html
...@@ -70,6 +70,7 @@ enum stm32mp1_parent_id { ...@@ -70,6 +70,7 @@ enum stm32mp1_parent_id {
_HCLK2, _HCLK2,
_CK_PER, _CK_PER,
_CK_MPU, _CK_MPU,
_CK_MCU,
_USB_PHY_48, _USB_PHY_48,
_PARENT_NB, _PARENT_NB,
_UNKNOWN_ID = 0xff, _UNKNOWN_ID = 0xff,
...@@ -93,6 +94,7 @@ enum stm32mp1_parent_sel { ...@@ -93,6 +94,7 @@ enum stm32mp1_parent_sel {
_QSPI_SEL, _QSPI_SEL,
_FMC_SEL, _FMC_SEL,
_ASS_SEL, _ASS_SEL,
_MSS_SEL,
_USBPHY_SEL, _USBPHY_SEL,
_USBO_SEL, _USBO_SEL,
_PARENT_SEL_NB, _PARENT_SEL_NB,
...@@ -117,6 +119,7 @@ enum stm32mp1_div_id { ...@@ -117,6 +119,7 @@ enum stm32mp1_div_id {
enum stm32mp1_clksrc_id { enum stm32mp1_clksrc_id {
CLKSRC_MPU, CLKSRC_MPU,
CLKSRC_AXI, CLKSRC_AXI,
CLKSRC_MCU,
CLKSRC_PLL12, CLKSRC_PLL12,
CLKSRC_PLL3, CLKSRC_PLL3,
CLKSRC_PLL4, CLKSRC_PLL4,
...@@ -129,6 +132,7 @@ enum stm32mp1_clksrc_id { ...@@ -129,6 +132,7 @@ enum stm32mp1_clksrc_id {
enum stm32mp1_clkdiv_id { enum stm32mp1_clkdiv_id {
CLKDIV_MPU, CLKDIV_MPU,
CLKDIV_AXI, CLKDIV_AXI,
CLKDIV_MCU,
CLKDIV_APB1, CLKDIV_APB1,
CLKDIV_APB2, CLKDIV_APB2,
CLKDIV_APB3, CLKDIV_APB3,
...@@ -272,6 +276,7 @@ static const uint8_t stm32mp1_clks[][2] = { ...@@ -272,6 +276,7 @@ static const uint8_t stm32mp1_clks[][2] = {
{ CK_PER, _CK_PER }, { CK_PER, _CK_PER },
{ CK_MPU, _CK_MPU }, { CK_MPU, _CK_MPU },
{ CK_AXI, _ACLK }, { CK_AXI, _ACLK },
{ CK_MCU, _CK_MCU },
{ CK_HSE, _HSE }, { CK_HSE, _HSE },
{ CK_CSI, _CSI }, { CK_CSI, _CSI },
{ CK_LSI, _LSI }, { CK_LSI, _LSI },
...@@ -412,6 +417,10 @@ static const uint8_t ass_parents[] = { ...@@ -412,6 +417,10 @@ static const uint8_t ass_parents[] = {
_HSI, _HSE, _PLL2 _HSI, _HSE, _PLL2
}; };
static const uint8_t mss_parents[] = {
_HSI, _HSE, _CSI, _PLL3
};
static const uint8_t usbphy_parents[] = { static const uint8_t usbphy_parents[] = {
_HSE_KER, _PLL4_R, _HSE_KER_DIV2 _HSE_KER, _PLL4_R, _HSE_KER_DIV2
}; };
...@@ -437,6 +446,7 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { ...@@ -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(_QSPI_SEL, RCC_QSPICKSELR, 0, 0xf, qspi_parents),
_CLK_PARENT(_FMC_SEL, RCC_FMCCKSELR, 0, 0xf, fmc_parents), _CLK_PARENT(_FMC_SEL, RCC_FMCCKSELR, 0, 0xf, fmc_parents),
_CLK_PARENT(_ASS_SEL, RCC_ASSCKSELR, 0, 0x3, ass_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(_USBPHY_SEL, RCC_USBCKSELR, 0, 0x3, usbphy_parents),
_CLK_PARENT(_USBO_SEL, RCC_USBCKSELR, 4, 0x1, usbo_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] = { ...@@ -483,6 +493,10 @@ static const struct stm32mp1_clk_pll stm32mp1_clk_pll[_PLL_NB] = {
}; };
/* Prescaler table lookups for clock computation */ /* 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 */ /* div = /1 /2 /4 /8 /16 : same divider for PMU and APBX */
#define stm32mp1_mpu_div stm32mp1_mpu_apbx_div #define stm32mp1_mpu_div stm32mp1_mpu_apbx_div
...@@ -549,6 +563,13 @@ bool stm32mp1_rcc_is_secure(void) ...@@ -549,6 +563,13 @@ bool stm32mp1_rcc_is_secure(void)
return (mmio_read_32(rcc_base + RCC_TZCR) & RCC_TZCR_TZEN) != 0; 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) void stm32mp1_clk_rcc_regs_lock(void)
{ {
stm32mp1_clk_lock(&reg_lock); stm32mp1_clk_lock(&reg_lock);
...@@ -775,6 +796,51 @@ static unsigned long get_clock_rate(int p) ...@@ -775,6 +796,51 @@ static unsigned long get_clock_rate(int p)
break; break;
} }
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: case _CK_PER:
reg = mmio_read_32(rcc_base + RCC_CPERCKSELR); reg = mmio_read_32(rcc_base + RCC_CPERCKSELR);
switch (reg & RCC_SELR_SRC_MASK) { switch (reg & RCC_SELR_SRC_MASK) {
...@@ -1609,6 +1675,10 @@ int stm32mp1_clk_init(void) ...@@ -1609,6 +1675,10 @@ int stm32mp1_clk_init(void)
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
ret = stm32mp1_set_clksrc(CLK_MCU_HSI);
if (ret != 0) {
return ret;
}
if ((mmio_read_32(rcc_base + RCC_MP_RSTSCLRR) & if ((mmio_read_32(rcc_base + RCC_MP_RSTSCLRR) &
RCC_MP_RSTSCLRR_MPUP0RSTF) != 0) { RCC_MP_RSTSCLRR_MPUP0RSTF) != 0) {
...@@ -1659,6 +1729,10 @@ int stm32mp1_clk_init(void) ...@@ -1659,6 +1729,10 @@ int stm32mp1_clk_init(void)
if (ret != 0) { if (ret != 0) {
return ret; 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); ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB1], rcc_base + RCC_APB1DIVR);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
...@@ -1757,6 +1831,10 @@ int stm32mp1_clk_init(void) ...@@ -1757,6 +1831,10 @@ int stm32mp1_clk_init(void)
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
ret = stm32mp1_set_clksrc(clksrc[CLKSRC_MCU]);
if (ret != 0) {
return ret;
}
stm32mp1_set_rtcsrc(clksrc[CLKSRC_RTC], lse_css); stm32mp1_set_rtcsrc(clksrc[CLKSRC_RTC], lse_css);
/* Configure PKCK */ /* Configure PKCK */
......
...@@ -204,6 +204,7 @@ ...@@ -204,6 +204,7 @@
st,clksrc = < st,clksrc = <
CLK_MPU_PLL1P CLK_MPU_PLL1P
CLK_AXI_PLL2P CLK_AXI_PLL2P
CLK_MCU_PLL3P
CLK_PLL12_HSE CLK_PLL12_HSE
CLK_PLL3_HSE CLK_PLL3_HSE
CLK_PLL4_HSE CLK_PLL4_HSE
...@@ -215,6 +216,7 @@ ...@@ -215,6 +216,7 @@
st,clkdiv = < st,clkdiv = <
1 /*MPU*/ 1 /*MPU*/
0 /*AXI*/ 0 /*AXI*/
0 /*MCU*/
1 /*APB1*/ 1 /*APB1*/
1 /*APB2*/ 1 /*APB2*/
1 /*APB3*/ 1 /*APB3*/
......
...@@ -224,6 +224,7 @@ ...@@ -224,6 +224,7 @@
st,clksrc = < st,clksrc = <
CLK_MPU_PLL1P CLK_MPU_PLL1P
CLK_AXI_PLL2P CLK_AXI_PLL2P
CLK_MCU_PLL3P
CLK_PLL12_HSE CLK_PLL12_HSE
CLK_PLL3_HSE CLK_PLL3_HSE
CLK_PLL4_HSE CLK_PLL4_HSE
...@@ -235,6 +236,7 @@ ...@@ -235,6 +236,7 @@
st,clkdiv = < st,clkdiv = <
1 /*MPU*/ 1 /*MPU*/
0 /*AXI*/ 0 /*AXI*/
0 /*MCU*/
1 /*APB1*/ 1 /*APB1*/
1 /*APB2*/ 1 /*APB2*/
1 /*APB3*/ 1 /*APB3*/
......
...@@ -13,6 +13,7 @@ int stm32mp1_clk_probe(void); ...@@ -13,6 +13,7 @@ int stm32mp1_clk_probe(void);
int stm32mp1_clk_init(void); int stm32mp1_clk_init(void);
bool stm32mp1_rcc_is_secure(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_enable(unsigned long id, bool caller_is_secure);
void __stm32mp1_clk_disable(unsigned long id, bool caller_is_secure); void __stm32mp1_clk_disable(unsigned long id, bool caller_is_secure);
......
...@@ -111,6 +111,7 @@ ...@@ -111,6 +111,7 @@
#define RCC_RCK4SELR U(0x824) #define RCC_RCK4SELR U(0x824)
#define RCC_TIMG1PRER U(0x828) #define RCC_TIMG1PRER U(0x828)
#define RCC_TIMG2PRER U(0x82C) #define RCC_TIMG2PRER U(0x82C)
#define RCC_MCUDIVR U(0x830)
#define RCC_APB1DIVR U(0x834) #define RCC_APB1DIVR U(0x834)
#define RCC_APB2DIVR U(0x838) #define RCC_APB2DIVR U(0x838)
#define RCC_APB3DIVR U(0x83C) #define RCC_APB3DIVR U(0x83C)
...@@ -237,6 +238,7 @@ ...@@ -237,6 +238,7 @@
/* Values for RCC_TZCR register */ /* Values for RCC_TZCR register */
#define RCC_TZCR_TZEN BIT(0) #define RCC_TZCR_TZEN BIT(0)
#define RCC_TZCR_MCKPROT BIT(1)
/* Used for most of RCC_<x>SELR registers */ /* Used for most of RCC_<x>SELR registers */
#define RCC_SELR_SRC_MASK GENMASK(2, 0) #define RCC_SELR_SRC_MASK GENMASK(2, 0)
...@@ -273,6 +275,7 @@ ...@@ -273,6 +275,7 @@
#define RCC_APBXDIV_MASK GENMASK(2, 0) #define RCC_APBXDIV_MASK GENMASK(2, 0)
#define RCC_MPUDIV_MASK GENMASK(2, 0) #define RCC_MPUDIV_MASK GENMASK(2, 0)
#define RCC_AXIDIV_MASK GENMASK(2, 0) #define RCC_AXIDIV_MASK GENMASK(2, 0)
#define RCC_MCUDIV_MASK GENMASK(3, 0)
/* Used for TIMER Prescaler */ /* Used for TIMER Prescaler */
#define RCC_TIMGXPRER_TIMGXPRE BIT(0) #define RCC_TIMGXPRER_TIMGXPRE BIT(0)
...@@ -421,6 +424,7 @@ ...@@ -421,6 +424,7 @@
/* Global Reset Register */ /* Global Reset Register */
#define RCC_MP_GRSTCSETR_MPSYSRST BIT(0) #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_MPUP0RST BIT(4)
#define RCC_MP_GRSTCSETR_MPUP1RST BIT(5) #define RCC_MP_GRSTCSETR_MPUP1RST BIT(5)
......
...@@ -202,6 +202,9 @@ void bl2_el3_plat_arch_setup(void) ...@@ -202,6 +202,9 @@ void bl2_el3_plat_arch_setup(void)
mmio_clrbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST); 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(); generic_delay_timer_init();
if (stm32mp1_clk_probe() < 0) { if (stm32mp1_clk_probe() < 0) {
......
...@@ -183,6 +183,7 @@ enum ddr_type { ...@@ -183,6 +183,7 @@ enum ddr_type {
#define STM32MP1_TZC_BASE U(0x5C006000) #define STM32MP1_TZC_BASE U(0x5C006000)
#define STM32MP1_TZC_A7_ID U(0) #define STM32MP1_TZC_A7_ID U(0)
#define STM32MP1_TZC_M4_ID U(1)
#define STM32MP1_TZC_LCD_ID U(3) #define STM32MP1_TZC_LCD_ID U(3)
#define STM32MP1_TZC_GPU_ID U(4) #define STM32MP1_TZC_GPU_ID U(4)
#define STM32MP1_TZC_MDMA_ID U(5) #define STM32MP1_TZC_MDMA_ID U(5)
......
...@@ -41,6 +41,7 @@ static void init_tzc400(void) ...@@ -41,6 +41,7 @@ static void init_tzc400(void)
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) | TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) |
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) | TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) |
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_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_DMA_ID) |
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) | TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) |
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) | TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) |
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment