diff --git a/drivers/st/ddr/stm32mp1_ddr_helpers.c b/drivers/st/ddr/stm32mp1_ddr_helpers.c index e50b27b..c66c9e7 100644 --- a/drivers/st/ddr/stm32mp1_ddr_helpers.c +++ b/drivers/st/ddr/stm32mp1_ddr_helpers.c @@ -11,7 +11,7 @@ void ddr_enable_clock(void) { - mmio_setbits_32(RCC_BASE + RCC_DDRITFCR, + mmio_setbits_32(stm32mp_rcc_base() + RCC_DDRITFCR, RCC_DDRITFCR_DDRC1EN | RCC_DDRITFCR_DDRC2EN | RCC_DDRITFCR_DDRPHYCEN | diff --git a/drivers/st/ddr/stm32mp1_ram.c b/drivers/st/ddr/stm32mp1_ram.c index 7b13385..59b4351 100644 --- a/drivers/st/ddr/stm32mp1_ram.c +++ b/drivers/st/ddr/stm32mp1_ram.c @@ -298,10 +298,10 @@ VERBOSE("STM32MP DDR probe\n"); - priv->ctl = (struct stm32mp1_ddrctl *)DDRCTRL_BASE; - priv->phy = (struct stm32mp1_ddrphy *)DDRPHYC_BASE; - priv->pwr = PWR_BASE; - priv->rcc = RCC_BASE; + priv->ctl = (struct stm32mp1_ddrctl *)stm32mp_ddrctrl_base(); + priv->phy = (struct stm32mp1_ddrphy *)stm32mp_ddrphyc_base(); + priv->pwr = stm32mp_pwr_base(); + priv->rcc = stm32mp_rcc_base(); priv->info.base = STM32MP_DDR_BASE; priv->info.size = 0; diff --git a/drivers/st/reset/stm32mp1_reset.c b/drivers/st/reset/stm32mp1_reset.c index b9a7ac7..b2de760 100644 --- a/drivers/st/reset/stm32mp1_reset.c +++ b/drivers/st/reset/stm32mp1_reset.c @@ -20,9 +20,10 @@ { uint32_t offset = (id / (uint32_t)__LONG_BIT) * sizeof(uintptr_t); uint32_t bit = id % (uint32_t)__LONG_BIT; + uintptr_t rcc_base = stm32mp_rcc_base(); - mmio_write_32(RCC_BASE + offset, BIT(bit)); - while ((mmio_read_32(RCC_BASE + offset) & BIT(bit)) == 0U) { + mmio_write_32(rcc_base + offset, BIT(bit)); + while ((mmio_read_32(rcc_base + offset) & BIT(bit)) == 0U) { ; } } @@ -32,9 +33,10 @@ uint32_t offset = ((id / (uint32_t)__LONG_BIT) * sizeof(uintptr_t)) + RST_CLR_OFFSET; uint32_t bit = id % (uint32_t)__LONG_BIT; + uintptr_t rcc_base = stm32mp_rcc_base(); - mmio_write_32(RCC_BASE + offset, BIT(bit)); - while ((mmio_read_32(RCC_BASE + offset) & BIT(bit)) != 0U) { + mmio_write_32(rcc_base + offset, BIT(bit)); + while ((mmio_read_32(rcc_base + offset) & BIT(bit)) != 0U) { ; } } diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h index 5f54b10..fa0b630 100644 --- a/plat/st/common/include/stm32mp_common.h +++ b/plat/st/common/include/stm32mp_common.h @@ -16,6 +16,18 @@ void stm32mp_save_boot_ctx_address(uintptr_t address); uintptr_t stm32mp_get_boot_ctx_address(void); +/* Return the base address of the DDR controller */ +uintptr_t stm32mp_ddrctrl_base(void); + +/* Return the base address of the DDR PHY */ +uintptr_t stm32mp_ddrphyc_base(void); + +/* Return the base address of the PWR peripheral */ +uintptr_t stm32mp_pwr_base(void); + +/* Return the base address of the RCC peripheral */ +uintptr_t stm32mp_rcc_base(void); + /* * Platform util functions for the GPIO driver * @bank: Target GPIO bank ID as per DT bindings diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h index 56357db..3415b05 100644 --- a/plat/st/common/include/stm32mp_dt.h +++ b/plat/st/common/include/stm32mp_dt.h @@ -38,6 +38,9 @@ int dt_get_stdout_uart_info(struct dt_node_info *info); int dt_get_stdout_node_offset(void); uint32_t dt_get_ddr_size(void); +uintptr_t dt_get_ddrctrl_base(void); +uintptr_t dt_get_ddrphyc_base(void); +uintptr_t dt_get_pwr_base(void); const char *dt_get_board_model(void); #endif /* STM32MP_DT_H */ diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c index aecef47..2aba41e 100644 --- a/plat/st/common/stm32mp_common.c +++ b/plat/st/common/stm32mp_common.c @@ -10,6 +10,7 @@ #include #include +#include #include uintptr_t plat_get_ns_image_entrypoint(void) @@ -34,6 +35,58 @@ return boot_ctx_address; } +uintptr_t stm32mp_ddrctrl_base(void) +{ + static uintptr_t ddrctrl_base; + + if (ddrctrl_base == 0) { + ddrctrl_base = dt_get_ddrctrl_base(); + + assert(ddrctrl_base == DDRCTRL_BASE); + } + + return ddrctrl_base; +} + +uintptr_t stm32mp_ddrphyc_base(void) +{ + static uintptr_t ddrphyc_base; + + if (ddrphyc_base == 0) { + ddrphyc_base = dt_get_ddrphyc_base(); + + assert(ddrphyc_base == DDRPHYC_BASE); + } + + return ddrphyc_base; +} + +uintptr_t stm32mp_pwr_base(void) +{ + static uintptr_t pwr_base; + + if (pwr_base == 0) { + pwr_base = dt_get_pwr_base(); + + assert(pwr_base == PWR_BASE); + } + + return pwr_base; +} + +uintptr_t stm32mp_rcc_base(void) +{ + static uintptr_t rcc_base; + + if (rcc_base == 0) { + rcc_base = fdt_rcc_read_addr(); + + assert(rcc_base == RCC_BASE); + } + + return rcc_base; +} + uintptr_t stm32_get_gpio_bank_base(unsigned int bank) { if (bank == GPIO_BANK_Z) { diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c index c0b0518..e64433b 100644 --- a/plat/st/common/stm32mp_dt.c +++ b/plat/st/common/stm32mp_dt.c @@ -292,6 +292,73 @@ } /******************************************************************************* + * This function gets DDRCTRL base address information from the DT. + * Returns value on success, and 0 on failure. + ******************************************************************************/ +uintptr_t dt_get_ddrctrl_base(void) +{ + int node; + uint32_t array[4]; + + node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT); + if (node < 0) { + INFO("%s: Cannot read DDR node in DT\n", __func__); + return 0; + } + + if (fdt_read_uint32_array(node, "reg", array, 4) < 0) { + return 0; + } + + return array[0]; +} + +/******************************************************************************* + * This function gets DDRPHYC base address information from the DT. + * Returns value on success, and 0 on failure. + ******************************************************************************/ +uintptr_t dt_get_ddrphyc_base(void) +{ + int node; + uint32_t array[4]; + + node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT); + if (node < 0) { + INFO("%s: Cannot read DDR node in DT\n", __func__); + return 0; + } + + if (fdt_read_uint32_array(node, "reg", array, 4) < 0) { + return 0; + } + + return array[2]; +} + +/******************************************************************************* + * This function gets PWR base address information from the DT. + * Returns value on success, and 0 on failure. + ******************************************************************************/ +uintptr_t dt_get_pwr_base(void) +{ + int node; + const fdt32_t *cuint; + + node = fdt_node_offset_by_compatible(fdt, -1, DT_PWR_COMPAT); + if (node < 0) { + INFO("%s: Cannot read PWR node in DT\n", __func__); + return 0; + } + + cuint = fdt_getprop(fdt, node, "reg", NULL); + if (cuint == NULL) { + return 0; + } + + return fdt32_to_cpu(*cuint); +} + +/******************************************************************************* * This function retrieves board model from DT * Returns string taken from model node, NULL otherwise ******************************************************************************/ diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index 69dc3fb..5ab20845 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -31,7 +31,7 @@ static void print_reset_reason(void) { - uint32_t rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR); + uint32_t rstsr = mmio_read_32(stm32mp_rcc_base() + RCC_MP_RSTSCLRR); if (rstsr == 0U) { WARN("Reset reason unknown\n"); @@ -147,6 +147,8 @@ boot_api_context_t *boot_context = (boot_api_context_t *)stm32mp_get_boot_ctx_address(); uint32_t clk_rate; + uintptr_t pwr_base; + uintptr_t rcc_base; mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, @@ -174,27 +176,30 @@ panic(); } + pwr_base = stm32mp_pwr_base(); + rcc_base = stm32mp_rcc_base(); + /* * Disable the backup domain write protection. * The protection is enable at each reset by hardware * and must be disabled by software. */ - mmio_setbits_32(PWR_BASE + PWR_CR1, PWR_CR1_DBP); + mmio_setbits_32(pwr_base + PWR_CR1, PWR_CR1_DBP); - while ((mmio_read_32(PWR_BASE + PWR_CR1) & PWR_CR1_DBP) == 0U) { + while ((mmio_read_32(pwr_base + PWR_CR1) & PWR_CR1_DBP) == 0U) { ; } /* Reset backup domain on cold boot cases */ - if ((mmio_read_32(RCC_BASE + RCC_BDCR) & RCC_BDCR_RTCSRC_MASK) == 0U) { - mmio_setbits_32(RCC_BASE + RCC_BDCR, RCC_BDCR_VSWRST); + if ((mmio_read_32(rcc_base + RCC_BDCR) & RCC_BDCR_RTCSRC_MASK) == 0U) { + mmio_setbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST); - while ((mmio_read_32(RCC_BASE + RCC_BDCR) & RCC_BDCR_VSWRST) == + while ((mmio_read_32(rcc_base + RCC_BDCR) & RCC_BDCR_VSWRST) == 0U) { ; } - mmio_clrbits_32(RCC_BASE + RCC_BDCR, RCC_BDCR_VSWRST); + mmio_clrbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST); } generic_delay_timer_init(); diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index beb588c..8d7cea3 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -253,6 +253,7 @@ /******************************************************************************* * Device Tree defines ******************************************************************************/ +#define DT_PWR_COMPAT "st,stm32mp1-pwr" #define DT_RCC_CLK_COMPAT "st,stm32mp1-rcc" #endif /* STM32MP1_DEF_H */ diff --git a/plat/st/stm32mp1/stm32mp1_pm.c b/plat/st/stm32mp1/stm32mp1_pm.c index c4d0232..3262607 100644 --- a/plat/st/stm32mp1/stm32mp1_pm.c +++ b/plat/st/stm32mp1/stm32mp1_pm.c @@ -159,7 +159,8 @@ static void __dead2 stm32_system_reset(void) { - mmio_setbits_32(RCC_BASE + RCC_MP_GRSTCSETR, RCC_MP_GRSTCSETR_MPSYSRST); + mmio_setbits_32(stm32mp_rcc_base() + RCC_MP_GRSTCSETR, + RCC_MP_GRSTCSETR_MPSYSRST); /* Loop in case system reset is not immediately caught */ for ( ; ; ) {