diff --git a/drivers/st/ddr/stm32mp1_ddr.c b/drivers/st/ddr/stm32mp1_ddr.c index 3db47c4fd..4719e1e68 100644 --- a/drivers/st/ddr/stm32mp1_ddr.c +++ b/drivers/st/ddr/stm32mp1_ddr.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021, STMicroelectronics - All Rights Reserved + * Copyright (C) 2018-2022, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ @@ -7,47 +7,58 @@ #include #include -#include - #include #include #include #include #include -#include #include #include #include #include +#include #include #include -struct reg_desc { - const char *name; - uint16_t offset; /* Offset for base address */ - uint8_t par_offset; /* Offset for parameter array */ -}; - -#define INVALID_OFFSET 0xFFU - -#define TIMEOUT_US_1S 1000000U +#include #define DDRCTL_REG(x, y) \ { \ .name = #x, \ - .offset = offsetof(struct stm32mp1_ddrctl, x), \ + .offset = offsetof(struct stm32mp_ddrctl, x), \ .par_offset = offsetof(struct y, x) \ } #define DDRPHY_REG(x, y) \ { \ .name = #x, \ - .offset = offsetof(struct stm32mp1_ddrphy, x), \ + .offset = offsetof(struct stm32mp_ddrphy, x), \ .par_offset = offsetof(struct y, x) \ } +/* + * PARAMETERS: value get from device tree : + * size / order need to be aligned with binding + * modification NOT ALLOWED !!! + */ +#define DDRCTL_REG_REG_SIZE 25 /* st,ctl-reg */ +#define DDRCTL_REG_TIMING_SIZE 12 /* st,ctl-timing */ +#define DDRCTL_REG_MAP_SIZE 9 /* st,ctl-map */ +#if STM32MP_DDR_DUAL_AXI_PORT +#define DDRCTL_REG_PERF_SIZE 17 /* st,ctl-perf */ +#else +#define DDRCTL_REG_PERF_SIZE 11 /* st,ctl-perf */ +#endif + +#if STM32MP_DDR_32BIT_INTERFACE +#define DDRPHY_REG_REG_SIZE 11 /* st,phy-reg */ +#else +#define DDRPHY_REG_REG_SIZE 9 /* st,phy-reg */ +#endif +#define DDRPHY_REG_TIMING_SIZE 10 /* st,phy-timing */ + #define DDRCTL_REG_REG(x) DDRCTL_REG(x, stm32mp1_ddrctrl_reg) -static const struct reg_desc ddr_reg[] = { +static const struct stm32mp_ddr_reg_desc ddr_reg[DDRCTL_REG_REG_SIZE] = { DDRCTL_REG_REG(mstr), DDRCTL_REG_REG(mrctrl0), DDRCTL_REG_REG(mrctrl1), @@ -76,7 +87,7 @@ static const struct reg_desc ddr_reg[] = { }; #define DDRCTL_REG_TIMING(x) DDRCTL_REG(x, stm32mp1_ddrctrl_timing) -static const struct reg_desc ddr_timing[] = { +static const struct stm32mp_ddr_reg_desc ddr_timing[DDRCTL_REG_TIMING_SIZE] = { DDRCTL_REG_TIMING(rfshtmg), DDRCTL_REG_TIMING(dramtmg0), DDRCTL_REG_TIMING(dramtmg1), @@ -92,7 +103,7 @@ static const struct reg_desc ddr_timing[] = { }; #define DDRCTL_REG_MAP(x) DDRCTL_REG(x, stm32mp1_ddrctrl_map) -static const struct reg_desc ddr_map[] = { +static const struct stm32mp_ddr_reg_desc ddr_map[DDRCTL_REG_MAP_SIZE] = { DDRCTL_REG_MAP(addrmap1), DDRCTL_REG_MAP(addrmap2), DDRCTL_REG_MAP(addrmap3), @@ -105,7 +116,7 @@ static const struct reg_desc ddr_map[] = { }; #define DDRCTL_REG_PERF(x) DDRCTL_REG(x, stm32mp1_ddrctrl_perf) -static const struct reg_desc ddr_perf[] = { +static const struct stm32mp_ddr_reg_desc ddr_perf[DDRCTL_REG_PERF_SIZE] = { DDRCTL_REG_PERF(sched), DDRCTL_REG_PERF(sched1), DDRCTL_REG_PERF(perfhpr1), @@ -117,16 +128,18 @@ static const struct reg_desc ddr_perf[] = { DDRCTL_REG_PERF(pcfgqos1_0), DDRCTL_REG_PERF(pcfgwqos0_0), DDRCTL_REG_PERF(pcfgwqos1_0), +#if STM32MP_DDR_DUAL_AXI_PORT DDRCTL_REG_PERF(pcfgr_1), DDRCTL_REG_PERF(pcfgw_1), DDRCTL_REG_PERF(pcfgqos0_1), DDRCTL_REG_PERF(pcfgqos1_1), DDRCTL_REG_PERF(pcfgwqos0_1), DDRCTL_REG_PERF(pcfgwqos1_1), +#endif }; #define DDRPHY_REG_REG(x) DDRPHY_REG(x, stm32mp1_ddrphy_reg) -static const struct reg_desc ddrphy_reg[] = { +static const struct stm32mp_ddr_reg_desc ddrphy_reg[DDRPHY_REG_REG_SIZE] = { DDRPHY_REG_REG(pgcr), DDRPHY_REG_REG(aciocr), DDRPHY_REG_REG(dxccr), @@ -136,12 +149,14 @@ static const struct reg_desc ddrphy_reg[] = { DDRPHY_REG_REG(zq0cr1), DDRPHY_REG_REG(dx0gcr), DDRPHY_REG_REG(dx1gcr), +#if STM32MP_DDR_32BIT_INTERFACE DDRPHY_REG_REG(dx2gcr), DDRPHY_REG_REG(dx3gcr), +#endif }; #define DDRPHY_REG_TIMING(x) DDRPHY_REG(x, stm32mp1_ddrphy_timing) -static const struct reg_desc ddrphy_timing[] = { +static const struct stm32mp_ddr_reg_desc ddrphy_timing[DDRPHY_REG_TIMING_SIZE] = { DDRPHY_REG_TIMING(ptr0), DDRPHY_REG_TIMING(ptr1), DDRPHY_REG_TIMING(ptr2), @@ -154,174 +169,49 @@ static const struct reg_desc ddrphy_timing[] = { DDRPHY_REG_TIMING(mr3), }; -#define DDRPHY_REG_CAL(x) DDRPHY_REG(x, stm32mp1_ddrphy_cal) -static const struct reg_desc ddrphy_cal[] = { - DDRPHY_REG_CAL(dx0dllcr), - DDRPHY_REG_CAL(dx0dqtr), - DDRPHY_REG_CAL(dx0dqstr), - DDRPHY_REG_CAL(dx1dllcr), - DDRPHY_REG_CAL(dx1dqtr), - DDRPHY_REG_CAL(dx1dqstr), - DDRPHY_REG_CAL(dx2dllcr), - DDRPHY_REG_CAL(dx2dqtr), - DDRPHY_REG_CAL(dx2dqstr), - DDRPHY_REG_CAL(dx3dllcr), - DDRPHY_REG_CAL(dx3dqtr), - DDRPHY_REG_CAL(dx3dqstr), -}; - -#define DDR_REG_DYN(x) \ - { \ - .name = #x, \ - .offset = offsetof(struct stm32mp1_ddrctl, x), \ - .par_offset = INVALID_OFFSET \ - } - -static const struct reg_desc ddr_dyn[] = { - DDR_REG_DYN(stat), - DDR_REG_DYN(init0), - DDR_REG_DYN(dfimisc), - DDR_REG_DYN(dfistat), - DDR_REG_DYN(swctl), - DDR_REG_DYN(swstat), - DDR_REG_DYN(pctrl_0), - DDR_REG_DYN(pctrl_1), -}; - -#define DDRPHY_REG_DYN(x) \ - { \ - .name = #x, \ - .offset = offsetof(struct stm32mp1_ddrphy, x), \ - .par_offset = INVALID_OFFSET \ - } - -static const struct reg_desc ddrphy_dyn[] = { - DDRPHY_REG_DYN(pir), - DDRPHY_REG_DYN(pgsr), -}; - -enum reg_type { - REG_REG, - REG_TIMING, - REG_PERF, - REG_MAP, - REGPHY_REG, - REGPHY_TIMING, - REGPHY_CAL, /* - * Dynamic registers => managed in driver or not changed, - * can be dumped in interactive mode. + * REGISTERS ARRAY: used to parse device tree and interactive mode */ - REG_DYN, - REGPHY_DYN, - REG_TYPE_NB -}; - -enum base_type { - DDR_BASE, - DDRPHY_BASE, - NONE_BASE -}; - -struct ddr_reg_info { - const char *name; - const struct reg_desc *desc; - uint8_t size; - enum base_type base; -}; - -static const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = { +static const struct stm32mp_ddr_reg_info ddr_registers[REG_TYPE_NB] = { [REG_REG] = { .name = "static", .desc = ddr_reg, - .size = ARRAY_SIZE(ddr_reg), + .size = DDRCTL_REG_REG_SIZE, .base = DDR_BASE }, [REG_TIMING] = { .name = "timing", .desc = ddr_timing, - .size = ARRAY_SIZE(ddr_timing), + .size = DDRCTL_REG_TIMING_SIZE, .base = DDR_BASE }, [REG_PERF] = { .name = "perf", .desc = ddr_perf, - .size = ARRAY_SIZE(ddr_perf), + .size = DDRCTL_REG_PERF_SIZE, .base = DDR_BASE }, [REG_MAP] = { .name = "map", .desc = ddr_map, - .size = ARRAY_SIZE(ddr_map), + .size = DDRCTL_REG_MAP_SIZE, .base = DDR_BASE }, [REGPHY_REG] = { .name = "static", .desc = ddrphy_reg, - .size = ARRAY_SIZE(ddrphy_reg), + .size = DDRPHY_REG_REG_SIZE, .base = DDRPHY_BASE }, [REGPHY_TIMING] = { .name = "timing", .desc = ddrphy_timing, - .size = ARRAY_SIZE(ddrphy_timing), - .base = DDRPHY_BASE - }, - [REGPHY_CAL] = { - .name = "cal", - .desc = ddrphy_cal, - .size = ARRAY_SIZE(ddrphy_cal), - .base = DDRPHY_BASE - }, - [REG_DYN] = { - .name = "dyn", - .desc = ddr_dyn, - .size = ARRAY_SIZE(ddr_dyn), - .base = DDR_BASE - }, - [REGPHY_DYN] = { - .name = "dyn", - .desc = ddrphy_dyn, - .size = ARRAY_SIZE(ddrphy_dyn), + .size = DDRPHY_REG_TIMING_SIZE, .base = DDRPHY_BASE }, }; -static uintptr_t get_base_addr(const struct ddr_info *priv, enum base_type base) -{ - if (base == DDRPHY_BASE) { - return (uintptr_t)priv->phy; - } else { - return (uintptr_t)priv->ctl; - } -} - -static void set_reg(const struct ddr_info *priv, - enum reg_type type, - const void *param) -{ - unsigned int i; - unsigned int value; - enum base_type base = ddr_registers[type].base; - uintptr_t base_addr = get_base_addr(priv, base); - const struct reg_desc *desc = ddr_registers[type].desc; - - VERBOSE("init %s\n", ddr_registers[type].name); - for (i = 0; i < ddr_registers[type].size; i++) { - uintptr_t ptr = base_addr + desc[i].offset; - - if (desc[i].par_offset == INVALID_OFFSET) { - ERROR("invalid parameter offset for %s", desc[i].name); - panic(); - } else { - value = *((uint32_t *)((uintptr_t)param + - desc[i].par_offset)); - mmio_write_32(ptr, value); - } - } -} - -static void stm32mp1_ddrphy_idone_wait(struct stm32mp1_ddrphy *phy) +static void stm32mp1_ddrphy_idone_wait(struct stm32mp_ddrphy *phy) { uint32_t pgsr; int error = 0; @@ -366,7 +256,7 @@ static void stm32mp1_ddrphy_idone_wait(struct stm32mp1_ddrphy *phy) (uintptr_t)&phy->pgsr, pgsr); } -static void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, uint32_t pir) +static void stm32mp1_ddrphy_init(struct stm32mp_ddrphy *phy, uint32_t pir) { uint32_t pir_init = pir | DDRPHYC_PIR_INIT; @@ -382,40 +272,8 @@ static void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, uint32_t pir) stm32mp1_ddrphy_idone_wait(phy); } -/* Start quasi dynamic register update */ -static void stm32mp1_start_sw_done(struct stm32mp1_ddrctl *ctl) -{ - mmio_clrbits_32((uintptr_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE); - VERBOSE("[0x%lx] swctl = 0x%x\n", - (uintptr_t)&ctl->swctl, mmio_read_32((uintptr_t)&ctl->swctl)); -} - /* Wait quasi dynamic register update */ -static void stm32mp1_wait_sw_done_ack(struct stm32mp1_ddrctl *ctl) -{ - uint64_t timeout; - uint32_t swstat; - - mmio_setbits_32((uintptr_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE); - VERBOSE("[0x%lx] swctl = 0x%x\n", - (uintptr_t)&ctl->swctl, mmio_read_32((uintptr_t)&ctl->swctl)); - - timeout = timeout_init_us(TIMEOUT_US_1S); - do { - swstat = mmio_read_32((uintptr_t)&ctl->swstat); - VERBOSE("[0x%lx] swstat = 0x%x ", - (uintptr_t)&ctl->swstat, swstat); - if (timeout_elapsed(timeout)) { - panic(); - } - } while ((swstat & DDRCTRL_SWSTAT_SW_DONE_ACK) == 0U); - - VERBOSE("[0x%lx] swstat = 0x%x\n", - (uintptr_t)&ctl->swstat, swstat); -} - -/* Wait quasi dynamic register update */ -static void stm32mp1_wait_operating_mode(struct ddr_info *priv, uint32_t mode) +static void stm32mp1_wait_operating_mode(struct stm32mp_ddr_priv *priv, uint32_t mode) { uint64_t timeout; uint32_t stat; @@ -464,7 +322,7 @@ static void stm32mp1_wait_operating_mode(struct ddr_info *priv, uint32_t mode) } /* Mode Register Writes (MRW or MRS) */ -static void stm32mp1_mode_register_write(struct ddr_info *priv, uint8_t addr, +static void stm32mp1_mode_register_write(struct stm32mp_ddr_priv *priv, uint8_t addr, uint32_t data) { uint32_t mrctrl0; @@ -519,7 +377,7 @@ static void stm32mp1_mode_register_write(struct ddr_info *priv, uint8_t addr, } /* Switch DDR3 from DLL-on to DLL-off */ -static void stm32mp1_ddr3_dll_off(struct ddr_info *priv) +static void stm32mp1_ddr3_dll_off(struct stm32mp_ddr_priv *priv) { uint32_t mr1 = mmio_read_32((uintptr_t)&priv->phy->mr1); uint32_t mr2 = mmio_read_32((uintptr_t)&priv->phy->mr2); @@ -610,14 +468,14 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv) * 9. Set the MSTR.dll_off_mode = 1. * warning: MSTR.dll_off_mode is a quasi-dynamic type 2 field */ - stm32mp1_start_sw_done(priv->ctl); + stm32mp_ddr_start_sw_done(priv->ctl); mmio_setbits_32((uintptr_t)&priv->ctl->mstr, DDRCTRL_MSTR_DLL_OFF_MODE); VERBOSE("[0x%lx] mstr = 0x%x\n", (uintptr_t)&priv->ctl->mstr, mmio_read_32((uintptr_t)&priv->ctl->mstr)); - stm32mp1_wait_sw_done_ack(priv->ctl); + stm32mp_ddr_wait_sw_done_ack(priv->ctl); /* 10. Change the clock frequency to the desired value. */ @@ -642,10 +500,12 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv) DDRPHYC_DXNDLLCR_DLLDIS); mmio_setbits_32((uintptr_t)&priv->phy->dx1dllcr, DDRPHYC_DXNDLLCR_DLLDIS); +#if STM32MP_DDR_32BIT_INTERFACE mmio_setbits_32((uintptr_t)&priv->phy->dx2dllcr, DDRPHYC_DXNDLLCR_DLLDIS); mmio_setbits_32((uintptr_t)&priv->phy->dx3dllcr, DDRPHYC_DXNDLLCR_DLLDIS); +#endif /* 12. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */ mmio_clrbits_32((uintptr_t)&priv->ctl->pwrctl, @@ -670,22 +530,22 @@ static void stm32mp1_ddr3_dll_off(struct ddr_info *priv) mmio_read_32((uintptr_t)&priv->ctl->dbg1)); } -static void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl) +static void stm32mp1_refresh_disable(struct stm32mp_ddrctl *ctl) { - stm32mp1_start_sw_done(ctl); + stm32mp_ddr_start_sw_done(ctl); /* Quasi-dynamic register update*/ mmio_setbits_32((uintptr_t)&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH); mmio_clrbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN); mmio_clrbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN); - stm32mp1_wait_sw_done_ack(ctl); + stm32mp_ddr_wait_sw_done_ack(ctl); } -static void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl, +static void stm32mp1_refresh_restore(struct stm32mp_ddrctl *ctl, uint32_t rfshctl3, uint32_t pwrctl) { - stm32mp1_start_sw_done(ctl); + stm32mp_ddr_start_sw_done(ctl); if ((rfshctl3 & DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH) == 0U) { mmio_clrbits_32((uintptr_t)&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH); @@ -696,30 +556,21 @@ static void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl, } mmio_setbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN); - stm32mp1_wait_sw_done_ack(ctl); + stm32mp_ddr_wait_sw_done_ack(ctl); } -static int board_ddr_power_init(enum ddr_type ddr_type) -{ - if (dt_pmic_status() > 0) { - return pmic_ddr_power_init(ddr_type); - } - - return 0; -} - -void stm32mp1_ddr_init(struct ddr_info *priv, - struct stm32mp1_ddr_config *config) +void stm32mp1_ddr_init(struct stm32mp_ddr_priv *priv, + struct stm32mp_ddr_config *config) { uint32_t pir; int ret = -EINVAL; if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR3) != 0U) { - ret = board_ddr_power_init(STM32MP_DDR3); + ret = stm32mp_board_ddr_power_init(STM32MP_DDR3); } else if ((config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2) != 0U) { - ret = board_ddr_power_init(STM32MP_LPDDR2); + ret = stm32mp_board_ddr_power_init(STM32MP_LPDDR2); } else if ((config->c_reg.mstr & DDRCTRL_MSTR_LPDDR3) != 0U) { - ret = board_ddr_power_init(STM32MP_LPDDR3); + ret = stm32mp_board_ddr_power_init(STM32MP_LPDDR3); } else { ERROR("DDR type not supported\n"); } @@ -729,7 +580,7 @@ void stm32mp1_ddr_init(struct ddr_info *priv, } VERBOSE("name = %s\n", config->info.name); - VERBOSE("speed = %d kHz\n", config->info.speed); + VERBOSE("speed = %u kHz\n", config->info.speed); VERBOSE("size = 0x%x\n", config->info.size); /* DDR INIT SEQUENCE */ @@ -774,7 +625,7 @@ void stm32mp1_ddr_init(struct ddr_info *priv, (uintptr_t)&priv->ctl->dfimisc, mmio_read_32((uintptr_t)&priv->ctl->dfimisc)); - set_reg(priv, REG_REG, &config->c_reg); + stm32mp_ddr_set_reg(priv, REG_REG, &config->c_reg, ddr_registers); /* DDR3 = don't set DLLOFF for init mode */ if ((config->c_reg.mstr & @@ -788,8 +639,8 @@ void stm32mp1_ddr_init(struct ddr_info *priv, mmio_read_32((uintptr_t)&priv->ctl->mstr)); } - set_reg(priv, REG_TIMING, &config->c_timing); - set_reg(priv, REG_MAP, &config->c_map); + stm32mp_ddr_set_reg(priv, REG_TIMING, &config->c_timing, ddr_registers); + stm32mp_ddr_set_reg(priv, REG_MAP, &config->c_map, ddr_registers); /* Skip CTRL init, SDRAM init is done by PHY PUBL */ mmio_clrsetbits_32((uintptr_t)&priv->ctl->init0, @@ -799,7 +650,7 @@ void stm32mp1_ddr_init(struct ddr_info *priv, (uintptr_t)&priv->ctl->init0, mmio_read_32((uintptr_t)&priv->ctl->init0)); - set_reg(priv, REG_PERF, &config->c_perf); + stm32mp_ddr_set_reg(priv, REG_PERF, &config->c_perf, ddr_registers); /* 2. deassert reset signal core_ddrc_rstn, aresetn and presetn */ mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCORERST); @@ -810,9 +661,8 @@ void stm32mp1_ddr_init(struct ddr_info *priv, * 3. start PHY init by accessing relevant PUBL registers * (DXGCR, DCR, PTR*, MR*, DTPR*) */ - set_reg(priv, REGPHY_REG, &config->p_reg); - set_reg(priv, REGPHY_TIMING, &config->p_timing); - set_reg(priv, REGPHY_CAL, &config->p_cal); + stm32mp_ddr_set_reg(priv, REGPHY_REG, &config->p_reg, ddr_registers); + stm32mp_ddr_set_reg(priv, REGPHY_TIMING, &config->p_timing, ddr_registers); /* DDR3 = don't set DLLOFF for init mode */ if ((config->c_reg.mstr & @@ -850,7 +700,7 @@ void stm32mp1_ddr_init(struct ddr_info *priv, * 6. SET DFIMISC.dfi_init_complete_en to 1 * Enable quasi-dynamic register programming. */ - stm32mp1_start_sw_done(priv->ctl); + stm32mp_ddr_start_sw_done(priv->ctl); mmio_setbits_32((uintptr_t)&priv->ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN); @@ -858,7 +708,7 @@ void stm32mp1_ddr_init(struct ddr_info *priv, (uintptr_t)&priv->ctl->dfimisc, mmio_read_32((uintptr_t)&priv->ctl->dfimisc)); - stm32mp1_wait_sw_done_ack(priv->ctl); + stm32mp_ddr_wait_sw_done_ack(priv->ctl); /* * 7. Wait for DWC_ddr_umctl2 to move to normal operation mode @@ -892,9 +742,14 @@ void stm32mp1_ddr_init(struct ddr_info *priv, /* * 10. configure PUBL PIR register to specify which training step * to run - * Warning : RVTRN is not supported by this PUBL + * RVTRN is executed only on LPDDR2/LPDDR3 */ - stm32mp1_ddrphy_init(priv->phy, DDRPHYC_PIR_QSTRN); + pir = DDRPHYC_PIR_QSTRN; + if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR3) == 0U) { + pir |= DDRPHYC_PIR_RVTRN; + } + + stm32mp1_ddrphy_init(priv->phy, pir); /* 11. monitor PUB PGSR.IDONE to poll cpmpletion of training sequence */ stm32mp1_ddrphy_idone_wait(priv->phy); @@ -905,17 +760,5 @@ void stm32mp1_ddr_init(struct ddr_info *priv, stm32mp1_refresh_restore(priv->ctl, config->c_reg.rfshctl3, config->c_reg.pwrctl); - /* Enable uMCTL2 AXI port 0 */ - mmio_setbits_32((uintptr_t)&priv->ctl->pctrl_0, - DDRCTRL_PCTRL_N_PORT_EN); - VERBOSE("[0x%lx] pctrl_0 = 0x%x\n", - (uintptr_t)&priv->ctl->pctrl_0, - mmio_read_32((uintptr_t)&priv->ctl->pctrl_0)); - - /* Enable uMCTL2 AXI port 1 */ - mmio_setbits_32((uintptr_t)&priv->ctl->pctrl_1, - DDRCTRL_PCTRL_N_PORT_EN); - VERBOSE("[0x%lx] pctrl_1 = 0x%x\n", - (uintptr_t)&priv->ctl->pctrl_1, - mmio_read_32((uintptr_t)&priv->ctl->pctrl_1)); + stm32mp_ddr_enable_axi_port(priv->ctl); } diff --git a/drivers/st/ddr/stm32mp1_ddr_helpers.c b/drivers/st/ddr/stm32mp1_ddr_helpers.c index fcb4cfcfd..e0621b513 100644 --- a/drivers/st/ddr/stm32mp1_ddr_helpers.c +++ b/drivers/st/ddr/stm32mp1_ddr_helpers.c @@ -1,21 +1,23 @@ /* - * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ -#include - #include #include +#include + void ddr_enable_clock(void) { stm32mp1_clk_rcc_regs_lock(); mmio_setbits_32(stm32mp_rcc_base() + RCC_DDRITFCR, RCC_DDRITFCR_DDRC1EN | +#if STM32MP_DDR_DUAL_AXI_PORT RCC_DDRITFCR_DDRC2EN | +#endif RCC_DDRITFCR_DDRPHYCEN | RCC_DDRITFCR_DDRPHYCAPBEN | RCC_DDRITFCR_DDRCAPBEN); diff --git a/drivers/st/ddr/stm32mp1_ram.c b/drivers/st/ddr/stm32mp1_ram.c index 064e3180e..b510c8fa2 100644 --- a/drivers/st/ddr/stm32mp1_ram.c +++ b/drivers/st/ddr/stm32mp1_ram.c @@ -1,15 +1,11 @@ /* - * Copyright (C) 2018-2021, STMicroelectronics - All Rights Reserved + * Copyright (C) 2018-2022, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ #include -#include - -#include - #include #include #include @@ -17,14 +13,17 @@ #include #include #include +#include +#include +#include #include +#include -#define DDR_PATTERN 0xAAAAAAAAU -#define DDR_ANTIPATTERN 0x55555555U +#include -static struct ddr_info ddr_priv_data; +static struct stm32mp_ddr_priv ddr_priv_data; -int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed) +int stm32mp1_ddr_clk_enable(struct stm32mp_ddr_priv *priv, uint32_t mem_speed) { unsigned long ddrphy_clk, ddr_clk, mem_speed_hz; @@ -32,7 +31,7 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed) ddrphy_clk = clk_get_rate(DDRPHYC); - VERBOSE("DDR: mem_speed (%d kHz), RCC %ld kHz\n", + VERBOSE("DDR: mem_speed (%u kHz), RCC %lu kHz\n", mem_speed, ddrphy_clk / 1000U); mem_speed_hz = mem_speed * 1000U; @@ -44,157 +43,29 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed) ddr_clk = mem_speed_hz - ddrphy_clk; } if (ddr_clk > (mem_speed_hz / 10)) { - ERROR("DDR expected freq %d kHz, current is %ld kHz\n", + ERROR("DDR expected freq %u kHz, current is %lu kHz\n", mem_speed, ddrphy_clk / 1000U); return -1; } return 0; } -/******************************************************************************* - * This function tests the DDR data bus wiring. - * This is inspired from the Data Bus Test algorithm written by Michael Barr - * in "Programming Embedded Systems in C and C++" book. - * resources.oreilly.com/examples/9781565923546/blob/master/Chapter6/ - * File: memtest.c - This source code belongs to Public Domain. - * Returns 0 if success, and address value else. - ******************************************************************************/ -static uint32_t ddr_test_data_bus(void) -{ - uint32_t pattern; - - for (pattern = 1U; pattern != 0U; pattern <<= 1) { - mmio_write_32(STM32MP_DDR_BASE, pattern); - - if (mmio_read_32(STM32MP_DDR_BASE) != pattern) { - return (uint32_t)STM32MP_DDR_BASE; - } - } - - return 0; -} - -/******************************************************************************* - * This function tests the DDR address bus wiring. - * This is inspired from the Data Bus Test algorithm written by Michael Barr - * in "Programming Embedded Systems in C and C++" book. - * resources.oreilly.com/examples/9781565923546/blob/master/Chapter6/ - * File: memtest.c - This source code belongs to Public Domain. - * Returns 0 if success, and address value else. - ******************************************************************************/ -static uint32_t ddr_test_addr_bus(void) -{ - uint64_t addressmask = (ddr_priv_data.info.size - 1U); - uint64_t offset; - uint64_t testoffset = 0; - - /* Write the default pattern at each of the power-of-two offsets. */ - for (offset = sizeof(uint32_t); (offset & addressmask) != 0U; - offset <<= 1) { - mmio_write_32(STM32MP_DDR_BASE + (uint32_t)offset, - DDR_PATTERN); - } - - /* Check for address bits stuck high. */ - mmio_write_32(STM32MP_DDR_BASE + (uint32_t)testoffset, - DDR_ANTIPATTERN); - - for (offset = sizeof(uint32_t); (offset & addressmask) != 0U; - offset <<= 1) { - if (mmio_read_32(STM32MP_DDR_BASE + (uint32_t)offset) != - DDR_PATTERN) { - return (uint32_t)(STM32MP_DDR_BASE + offset); - } - } - - mmio_write_32(STM32MP_DDR_BASE + (uint32_t)testoffset, DDR_PATTERN); - - /* Check for address bits stuck low or shorted. */ - for (testoffset = sizeof(uint32_t); (testoffset & addressmask) != 0U; - testoffset <<= 1) { - mmio_write_32(STM32MP_DDR_BASE + (uint32_t)testoffset, - DDR_ANTIPATTERN); - - if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) { - return STM32MP_DDR_BASE; - } - - for (offset = sizeof(uint32_t); (offset & addressmask) != 0U; - offset <<= 1) { - if ((mmio_read_32(STM32MP_DDR_BASE + - (uint32_t)offset) != DDR_PATTERN) && - (offset != testoffset)) { - return (uint32_t)(STM32MP_DDR_BASE + offset); - } - } - - mmio_write_32(STM32MP_DDR_BASE + (uint32_t)testoffset, - DDR_PATTERN); - } - - return 0; -} - -/******************************************************************************* - * This function checks the DDR size. It has to be run with Data Cache off. - * This test is run before data have been put in DDR, and is only done for - * cold boot. The DDR data can then be overwritten, and it is not useful to - * restore its content. - * Returns DDR computed size. - ******************************************************************************/ -static uint32_t ddr_check_size(void) -{ - uint32_t offset = sizeof(uint32_t); - - mmio_write_32(STM32MP_DDR_BASE, DDR_PATTERN); - - while (offset < STM32MP_DDR_MAX_SIZE) { - mmio_write_32(STM32MP_DDR_BASE + offset, DDR_ANTIPATTERN); - dsb(); - - if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) { - break; - } - - offset <<= 1; - } - - INFO("Memory size = 0x%x (%d MB)\n", offset, offset / (1024U * 1024U)); - - return offset; -} - static int stm32mp1_ddr_setup(void) { - struct ddr_info *priv = &ddr_priv_data; + struct stm32mp_ddr_priv *priv = &ddr_priv_data; int ret; - struct stm32mp1_ddr_config config; - int node, len; - uint32_t uret, idx; + struct stm32mp_ddr_config config; + int node; + uint32_t uret; void *fdt; -#define PARAM(x, y) \ - { \ - .name = x, \ - .offset = offsetof(struct stm32mp1_ddr_config, y), \ - .size = sizeof(config.y) / sizeof(uint32_t) \ - } - -#define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x) -#define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x) - - const struct { - const char *name; /* Name in DT */ - const uint32_t offset; /* Offset in config struct */ - const uint32_t size; /* Size of parameters */ - } param[] = { + const struct stm32mp_ddr_param param[] = { CTL_PARAM(reg), CTL_PARAM(timing), CTL_PARAM(map), CTL_PARAM(perf), PHY_PARAM(reg), PHY_PARAM(timing), - PHY_PARAM(cal) }; if (fdt_get_address(&fdt) == 0) { @@ -207,36 +78,14 @@ static int stm32mp1_ddr_setup(void) return -EINVAL; } - ret = fdt_read_uint32(fdt, node, "st,mem-speed", &config.info.speed); + ret = stm32mp_ddr_dt_get_info(fdt, node, &config.info); if (ret < 0) { - VERBOSE("%s: no st,mem-speed\n", __func__); - return -EINVAL; + return ret; } - ret = fdt_read_uint32(fdt, node, "st,mem-size", &config.info.size); + + ret = stm32mp_ddr_dt_get_param(fdt, node, param, ARRAY_SIZE(param), (uintptr_t)&config); if (ret < 0) { - VERBOSE("%s: no st,mem-size\n", __func__); - return -EINVAL; - } - config.info.name = fdt_getprop(fdt, node, "st,mem-name", &len); - if (config.info.name == NULL) { - VERBOSE("%s: no st,mem-name\n", __func__); - return -EINVAL; - } - INFO("RAM: %s\n", config.info.name); - - for (idx = 0; idx < ARRAY_SIZE(param); idx++) { - ret = fdt_read_uint32_array(fdt, node, param[idx].name, - param[idx].size, - (void *)((uintptr_t)&config + - param[idx].offset)); - - VERBOSE("%s: %s[0x%x] = %d\n", __func__, - param[idx].name, param[idx].size, ret); - if (ret != 0) { - ERROR("%s: Cannot read %s\n", - __func__, param[idx].name); - return -EINVAL; - } + return ret; } /* Disable axidcg clock gating during init */ @@ -256,21 +105,21 @@ static int stm32mp1_ddr_setup(void) panic(); } - uret = ddr_test_data_bus(); + uret = stm32mp_ddr_test_data_bus(); if (uret != 0U) { ERROR("DDR data bus test: can't access memory @ 0x%x\n", uret); panic(); } - uret = ddr_test_addr_bus(); + uret = stm32mp_ddr_test_addr_bus(config.info.size); if (uret != 0U) { ERROR("DDR addr bus test: can't access memory @ 0x%x\n", uret); panic(); } - uret = ddr_check_size(); + uret = stm32mp_ddr_check_size(); if (uret < config.info.size) { ERROR("DDR size: 0x%x does not match DT config: 0x%x\n", uret, config.info.size); @@ -286,12 +135,12 @@ static int stm32mp1_ddr_setup(void) int stm32mp1_ddr_probe(void) { - struct ddr_info *priv = &ddr_priv_data; + struct stm32mp_ddr_priv *priv = &ddr_priv_data; VERBOSE("STM32MP DDR probe\n"); - priv->ctl = (struct stm32mp1_ddrctl *)stm32mp_ddrctrl_base(); - priv->phy = (struct stm32mp1_ddrphy *)stm32mp_ddrphyc_base(); + priv->ctl = (struct stm32mp_ddrctl *)stm32mp_ddrctrl_base(); + priv->phy = (struct stm32mp_ddrphy *)stm32mp_ddrphyc_base(); priv->pwr = stm32mp_pwr_base(); priv->rcc = stm32mp_rcc_base(); diff --git a/drivers/st/ddr/stm32mp_ddr.c b/drivers/st/ddr/stm32mp_ddr.c new file mode 100644 index 000000000..ffc85ea3e --- /dev/null +++ b/drivers/st/ddr/stm32mp_ddr.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2022, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +#include + +#define INVALID_OFFSET 0xFFU + +static uintptr_t get_base_addr(const struct stm32mp_ddr_priv *priv, enum stm32mp_ddr_base_type base) +{ + if (base == DDRPHY_BASE) { + return (uintptr_t)priv->phy; + } else { + return (uintptr_t)priv->ctl; + } +} + +void stm32mp_ddr_set_reg(const struct stm32mp_ddr_priv *priv, enum stm32mp_ddr_reg_type type, + const void *param, const struct stm32mp_ddr_reg_info *ddr_registers) +{ + unsigned int i; + unsigned int value; + enum stm32mp_ddr_base_type base = ddr_registers[type].base; + uintptr_t base_addr = get_base_addr(priv, base); + const struct stm32mp_ddr_reg_desc *desc = ddr_registers[type].desc; + + VERBOSE("init %s\n", ddr_registers[type].name); + for (i = 0; i < ddr_registers[type].size; i++) { + uintptr_t ptr = base_addr + desc[i].offset; + + if (desc[i].par_offset == INVALID_OFFSET) { + ERROR("invalid parameter offset for %s", desc[i].name); + panic(); + } else { + value = *((uint32_t *)((uintptr_t)param + + desc[i].par_offset)); + mmio_write_32(ptr, value); + } + } +} + +/* Start quasi dynamic register update */ +void stm32mp_ddr_start_sw_done(struct stm32mp_ddrctl *ctl) +{ + mmio_clrbits_32((uintptr_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE); + VERBOSE("[0x%lx] swctl = 0x%x\n", + (uintptr_t)&ctl->swctl, mmio_read_32((uintptr_t)&ctl->swctl)); +} + +/* Wait quasi dynamic register update */ +void stm32mp_ddr_wait_sw_done_ack(struct stm32mp_ddrctl *ctl) +{ + uint64_t timeout; + uint32_t swstat; + + mmio_setbits_32((uintptr_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE); + VERBOSE("[0x%lx] swctl = 0x%x\n", + (uintptr_t)&ctl->swctl, mmio_read_32((uintptr_t)&ctl->swctl)); + + timeout = timeout_init_us(TIMEOUT_US_1S); + do { + swstat = mmio_read_32((uintptr_t)&ctl->swstat); + VERBOSE("[0x%lx] swstat = 0x%x ", + (uintptr_t)&ctl->swstat, swstat); + if (timeout_elapsed(timeout)) { + panic(); + } + } while ((swstat & DDRCTRL_SWSTAT_SW_DONE_ACK) == 0U); + + VERBOSE("[0x%lx] swstat = 0x%x\n", + (uintptr_t)&ctl->swstat, swstat); +} + +void stm32mp_ddr_enable_axi_port(struct stm32mp_ddrctl *ctl) +{ + /* Enable uMCTL2 AXI port 0 */ + mmio_setbits_32((uintptr_t)&ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN); + VERBOSE("[0x%lx] pctrl_0 = 0x%x\n", (uintptr_t)&ctl->pctrl_0, + mmio_read_32((uintptr_t)&ctl->pctrl_0)); + +#if STM32MP_DDR_DUAL_AXI_PORT + /* Enable uMCTL2 AXI port 1 */ + mmio_setbits_32((uintptr_t)&ctl->pctrl_1, DDRCTRL_PCTRL_N_PORT_EN); + VERBOSE("[0x%lx] pctrl_1 = 0x%x\n", (uintptr_t)&ctl->pctrl_1, + mmio_read_32((uintptr_t)&ctl->pctrl_1)); +#endif + +} + +int stm32mp_board_ddr_power_init(enum ddr_type ddr_type) +{ + if (dt_pmic_status() > 0) { + return pmic_ddr_power_init(ddr_type); + } + + return 0; +} diff --git a/drivers/st/ddr/stm32mp_ddr_test.c b/drivers/st/ddr/stm32mp_ddr_test.c new file mode 100644 index 000000000..6b98095d6 --- /dev/null +++ b/drivers/st/ddr/stm32mp_ddr_test.c @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2022, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include + +#define DDR_PATTERN 0xAAAAAAAAU +#define DDR_ANTIPATTERN 0x55555555U + +/******************************************************************************* + * This function tests a simple read/write access to the DDR. + * Note that the previous content is restored after test. + * Returns 0 if success, and address value else. + ******************************************************************************/ +uint32_t stm32mp_ddr_test_rw_access(void) +{ + uint32_t saved_value = mmio_read_32(STM32MP_DDR_BASE); + + mmio_write_32(STM32MP_DDR_BASE, DDR_PATTERN); + + if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) { + return (uint32_t)STM32MP_DDR_BASE; + } + + mmio_write_32(STM32MP_DDR_BASE, saved_value); + + return 0U; +} + +/******************************************************************************* + * This function tests the DDR data bus wiring. + * This is inspired from the Data Bus Test algorithm written by Michael Barr + * in "Programming Embedded Systems in C and C++" book. + * resources.oreilly.com/examples/9781565923546/blob/master/Chapter6/ + * File: memtest.c - This source code belongs to Public Domain. + * Returns 0 if success, and address value else. + ******************************************************************************/ +uint32_t stm32mp_ddr_test_data_bus(void) +{ + uint32_t pattern; + + for (pattern = 1U; pattern != 0U; pattern <<= 1U) { + mmio_write_32(STM32MP_DDR_BASE, pattern); + + if (mmio_read_32(STM32MP_DDR_BASE) != pattern) { + return (uint32_t)STM32MP_DDR_BASE; + } + } + + return 0; +} + +/******************************************************************************* + * This function tests the DDR address bus wiring. + * This is inspired from the Data Bus Test algorithm written by Michael Barr + * in "Programming Embedded Systems in C and C++" book. + * resources.oreilly.com/examples/9781565923546/blob/master/Chapter6/ + * File: memtest.c - This source code belongs to Public Domain. + * size: size in bytes of the DDR memory device. + * Returns 0 if success, and address value else. + ******************************************************************************/ +uint32_t stm32mp_ddr_test_addr_bus(uint64_t size) +{ + uint64_t addressmask = size - 1U; + uint64_t offset; + uint64_t testoffset = 0U; + + /* Write the default pattern at each of the power-of-two offsets. */ + for (offset = sizeof(uint32_t); (offset & addressmask) != 0U; + offset <<= 1U) { + mmio_write_32(STM32MP_DDR_BASE + (uint32_t)offset, + DDR_PATTERN); + } + + /* Check for address bits stuck high. */ + mmio_write_32(STM32MP_DDR_BASE + (uint32_t)testoffset, + DDR_ANTIPATTERN); + + for (offset = sizeof(uint32_t); (offset & addressmask) != 0U; + offset <<= 1U) { + if (mmio_read_32(STM32MP_DDR_BASE + (uint32_t)offset) != + DDR_PATTERN) { + return (uint32_t)(STM32MP_DDR_BASE + offset); + } + } + + mmio_write_32(STM32MP_DDR_BASE + (uint32_t)testoffset, DDR_PATTERN); + + /* Check for address bits stuck low or shorted. */ + for (testoffset = sizeof(uint32_t); (testoffset & addressmask) != 0U; + testoffset <<= 1U) { + mmio_write_32(STM32MP_DDR_BASE + (uint32_t)testoffset, + DDR_ANTIPATTERN); + + if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) { + return STM32MP_DDR_BASE; + } + + for (offset = sizeof(uint32_t); (offset & addressmask) != 0U; + offset <<= 1) { + if ((mmio_read_32(STM32MP_DDR_BASE + + (uint32_t)offset) != DDR_PATTERN) && + (offset != testoffset)) { + return (uint32_t)(STM32MP_DDR_BASE + offset); + } + } + + mmio_write_32(STM32MP_DDR_BASE + (uint32_t)testoffset, + DDR_PATTERN); + } + + return 0U; +} + +/******************************************************************************* + * This function checks the DDR size. It has to be run with Data Cache off. + * This test is run before data have been put in DDR, and is only done for + * cold boot. The DDR data can then be overwritten, and it is not useful to + * restore its content. + * Returns DDR computed size. + ******************************************************************************/ +uint32_t stm32mp_ddr_check_size(void) +{ + uint32_t offset = sizeof(uint32_t); + + mmio_write_32(STM32MP_DDR_BASE, DDR_PATTERN); + + while (offset < STM32MP_DDR_MAX_SIZE) { + mmio_write_32(STM32MP_DDR_BASE + offset, DDR_ANTIPATTERN); + dsb(); + + if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) { + break; + } + + offset <<= 1U; + } + + INFO("Memory size = 0x%x (%u MB)\n", offset, offset / (1024U * 1024U)); + + return offset; +} diff --git a/drivers/st/ddr/stm32mp_ram.c b/drivers/st/ddr/stm32mp_ram.c new file mode 100644 index 000000000..1e555adbb --- /dev/null +++ b/drivers/st/ddr/stm32mp_ram.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2022, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include + +#include + +int stm32mp_ddr_dt_get_info(void *fdt, int node, struct stm32mp_ddr_info *info) +{ + int ret; + + ret = fdt_read_uint32(fdt, node, "st,mem-speed", &info->speed); + if (ret < 0) { + VERBOSE("%s: no st,mem-speed\n", __func__); + return -EINVAL; + } + ret = fdt_read_uint32(fdt, node, "st,mem-size", &info->size); + if (ret < 0) { + VERBOSE("%s: no st,mem-size\n", __func__); + return -EINVAL; + } + info->name = fdt_getprop(fdt, node, "st,mem-name", NULL); + if (info->name == NULL) { + VERBOSE("%s: no st,mem-name\n", __func__); + return -EINVAL; + } + + INFO("RAM: %s\n", info->name); + + return 0; +} + +int stm32mp_ddr_dt_get_param(void *fdt, int node, const struct stm32mp_ddr_param *param, + uint32_t param_size, uintptr_t config) +{ + int ret; + uint32_t idx; + + for (idx = 0U; idx < param_size; idx++) { + ret = fdt_read_uint32_array(fdt, node, param[idx].name, param[idx].size, + (void *)(config + param[idx].offset)); + + VERBOSE("%s: %s[0x%x] = %d\n", __func__, param[idx].name, param[idx].size, ret); + if (ret != 0) { + ERROR("%s: Cannot read %s, error=%d\n", __func__, param[idx].name, ret); + return -EINVAL; + } + } + + return 0; +} diff --git a/fdts/stm32mp15-ddr.dtsi b/fdts/stm32mp15-ddr.dtsi index e5efd9256..d0b3a17fb 100644 --- a/fdts/stm32mp15-ddr.dtsi +++ b/fdts/stm32mp15-ddr.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause /* - * Copyright (C) 2018-2021, STMicroelectronics - All Rights Reserved + * Copyright (C) 2018-2022, STMicroelectronics - All Rights Reserved */ &ddr { @@ -109,19 +109,4 @@ DDR_MR2 DDR_MR3 >; - - st,phy-cal = < - DDR_DX0DLLCR - DDR_DX0DQTR - DDR_DX0DQSTR - DDR_DX1DLLCR - DDR_DX1DQTR - DDR_DX1DQSTR - DDR_DX2DLLCR - DDR_DX2DQTR - DDR_DX2DQSTR - DDR_DX3DLLCR - DDR_DX3DQTR - DDR_DX3DQSTR - >; }; diff --git a/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi index c6d6434a9..5d1001d9b 100644 --- a/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi +++ b/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause /* - * Copyright (c) 2018-2021, STMicroelectronics - All Rights Reserved + * Copyright (c) 2018-2022, STMicroelectronics - All Rights Reserved */ /* @@ -100,20 +100,8 @@ #define DDR_ODTCR 0x00010000 #define DDR_ZQ0CR1 0x00000038 #define DDR_DX0GCR 0x0000CE81 -#define DDR_DX0DLLCR 0x40000000 -#define DDR_DX0DQTR 0xFFFFFFFF -#define DDR_DX0DQSTR 0x3DB02000 #define DDR_DX1GCR 0x0000CE81 -#define DDR_DX1DLLCR 0x40000000 -#define DDR_DX1DQTR 0xFFFFFFFF -#define DDR_DX1DQSTR 0x3DB02000 #define DDR_DX2GCR 0x0000CE80 -#define DDR_DX2DLLCR 0x40000000 -#define DDR_DX2DQTR 0xFFFFFFFF -#define DDR_DX2DQSTR 0x3DB02000 #define DDR_DX3GCR 0x0000CE80 -#define DDR_DX3DLLCR 0x40000000 -#define DDR_DX3DQTR 0xFFFFFFFF -#define DDR_DX3DQSTR 0x3DB02000 #include "stm32mp15-ddr.dtsi" diff --git a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi index 9614ab4c8..6494cebd2 100644 --- a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi +++ b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause /* - * Copyright (c) 2018-2021, STMicroelectronics - All Rights Reserved + * Copyright (c) 2018-2022, STMicroelectronics - All Rights Reserved */ /* @@ -100,20 +100,8 @@ #define DDR_ODTCR 0x00010000 #define DDR_ZQ0CR1 0x00000038 #define DDR_DX0GCR 0x0000CE81 -#define DDR_DX0DLLCR 0x40000000 -#define DDR_DX0DQTR 0xFFFFFFFF -#define DDR_DX0DQSTR 0x3DB02000 #define DDR_DX1GCR 0x0000CE81 -#define DDR_DX1DLLCR 0x40000000 -#define DDR_DX1DQTR 0xFFFFFFFF -#define DDR_DX1DQSTR 0x3DB02000 #define DDR_DX2GCR 0x0000CE81 -#define DDR_DX2DLLCR 0x40000000 -#define DDR_DX2DQTR 0xFFFFFFFF -#define DDR_DX2DQSTR 0x3DB02000 #define DDR_DX3GCR 0x0000CE81 -#define DDR_DX3DLLCR 0x40000000 -#define DDR_DX3DQTR 0xFFFFFFFF -#define DDR_DX3DQSTR 0x3DB02000 #include "stm32mp15-ddr.dtsi" diff --git a/include/drivers/st/stm32mp1_ddr.h b/include/drivers/st/stm32mp1_ddr.h index 4ab37d6b4..df71f35b1 100644 --- a/include/drivers/st/stm32mp1_ddr.h +++ b/include/drivers/st/stm32mp1_ddr.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved + * Copyright (C) 2018-2022, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ @@ -10,29 +10,7 @@ #include #include -#define DT_DDR_COMPAT "st,stm32mp1-ddr" - -struct stm32mp1_ddr_size { - uint64_t base; - uint64_t size; -}; - -/** - * struct ddr_info - * - * @dev: pointer for the device - * @info: UCLASS RAM information - * @ctl: DDR controleur base address - * @phy: DDR PHY base address - * @syscfg: syscfg base address - */ -struct ddr_info { - struct stm32mp1_ddr_size info; - struct stm32mp1_ddrctl *ctl; - struct stm32mp1_ddrphy *phy; - uintptr_t pwr; - uintptr_t rcc; -}; +#include struct stm32mp1_ddrctrl_reg { uint32_t mstr; @@ -101,12 +79,14 @@ struct stm32mp1_ddrctrl_perf { uint32_t pcfgqos1_0; uint32_t pcfgwqos0_0; uint32_t pcfgwqos1_0; +#if STM32MP_DDR_DUAL_AXI_PORT uint32_t pcfgr_1; uint32_t pcfgw_1; uint32_t pcfgqos0_1; uint32_t pcfgqos1_1; uint32_t pcfgwqos0_1; uint32_t pcfgwqos1_1; +#endif }; struct stm32mp1_ddrphy_reg { @@ -119,8 +99,10 @@ struct stm32mp1_ddrphy_reg { uint32_t zq0cr1; uint32_t dx0gcr; uint32_t dx1gcr; +#if STM32MP_DDR_32BIT_INTERFACE uint32_t dx2gcr; uint32_t dx3gcr; +#endif }; struct stm32mp1_ddrphy_timing { @@ -136,39 +118,17 @@ struct stm32mp1_ddrphy_timing { uint32_t mr3; }; -struct stm32mp1_ddrphy_cal { - uint32_t dx0dllcr; - uint32_t dx0dqtr; - uint32_t dx0dqstr; - uint32_t dx1dllcr; - uint32_t dx1dqtr; - uint32_t dx1dqstr; - uint32_t dx2dllcr; - uint32_t dx2dqtr; - uint32_t dx2dqstr; - uint32_t dx3dllcr; - uint32_t dx3dqtr; - uint32_t dx3dqstr; -}; - -struct stm32mp1_ddr_info { - const char *name; - uint32_t speed; /* in kHZ */ - uint32_t size; /* Memory size in byte = col * row * width */ -}; - -struct stm32mp1_ddr_config { - struct stm32mp1_ddr_info info; +struct stm32mp_ddr_config { + struct stm32mp_ddr_info info; struct stm32mp1_ddrctrl_reg c_reg; struct stm32mp1_ddrctrl_timing c_timing; struct stm32mp1_ddrctrl_map c_map; struct stm32mp1_ddrctrl_perf c_perf; struct stm32mp1_ddrphy_reg p_reg; struct stm32mp1_ddrphy_timing p_timing; - struct stm32mp1_ddrphy_cal p_cal; }; -int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed); -void stm32mp1_ddr_init(struct ddr_info *priv, - struct stm32mp1_ddr_config *config); +int stm32mp1_ddr_clk_enable(struct stm32mp_ddr_priv *priv, uint32_t mem_speed); +void stm32mp1_ddr_init(struct stm32mp_ddr_priv *priv, struct stm32mp_ddr_config *config); + #endif /* STM32MP1_DDR_H */ diff --git a/include/drivers/st/stm32mp1_ddr_regs.h b/include/drivers/st/stm32mp1_ddr_regs.h index 01d663834..2fbe1c8a5 100644 --- a/include/drivers/st/stm32mp1_ddr_regs.h +++ b/include/drivers/st/stm32mp1_ddr_regs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ @@ -7,140 +7,11 @@ #ifndef STM32MP1_DDR_REGS_H #define STM32MP1_DDR_REGS_H +#include #include -/* DDR3/LPDDR2/LPDDR3 Controller (DDRCTRL) registers */ -struct stm32mp1_ddrctl { - uint32_t mstr ; /* 0x0 Master */ - uint32_t stat; /* 0x4 Operating Mode Status */ - uint8_t reserved008[0x10 - 0x8]; - uint32_t mrctrl0; /* 0x10 Control 0 */ - uint32_t mrctrl1; /* 0x14 Control 1 */ - uint32_t mrstat; /* 0x18 Status */ - uint32_t reserved01c; /* 0x1c */ - uint32_t derateen; /* 0x20 Temperature Derate Enable */ - uint32_t derateint; /* 0x24 Temperature Derate Interval */ - uint8_t reserved028[0x30 - 0x28]; - uint32_t pwrctl; /* 0x30 Low Power Control */ - uint32_t pwrtmg; /* 0x34 Low Power Timing */ - uint32_t hwlpctl; /* 0x38 Hardware Low Power Control */ - uint8_t reserved03c[0x50 - 0x3C]; - uint32_t rfshctl0; /* 0x50 Refresh Control 0 */ - uint32_t reserved054; /* 0x54 Refresh Control 1 */ - uint32_t reserved058; /* 0x58 Refresh Control 2 */ - uint32_t reserved05C; - uint32_t rfshctl3; /* 0x60 Refresh Control 0 */ - uint32_t rfshtmg; /* 0x64 Refresh Timing */ - uint8_t reserved068[0xc0 - 0x68]; - uint32_t crcparctl0; /* 0xc0 CRC Parity Control0 */ - uint32_t reserved0c4; /* 0xc4 CRC Parity Control1 */ - uint32_t reserved0c8; /* 0xc8 CRC Parity Control2 */ - uint32_t crcparstat; /* 0xcc CRC Parity Status */ - uint32_t init0; /* 0xd0 SDRAM Initialization 0 */ - uint32_t init1; /* 0xd4 SDRAM Initialization 1 */ - uint32_t init2; /* 0xd8 SDRAM Initialization 2 */ - uint32_t init3; /* 0xdc SDRAM Initialization 3 */ - uint32_t init4; /* 0xe0 SDRAM Initialization 4 */ - uint32_t init5; /* 0xe4 SDRAM Initialization 5 */ - uint32_t reserved0e8; - uint32_t reserved0ec; - uint32_t dimmctl; /* 0xf0 DIMM Control */ - uint8_t reserved0f4[0x100 - 0xf4]; - uint32_t dramtmg0; /* 0x100 SDRAM Timing 0 */ - uint32_t dramtmg1; /* 0x104 SDRAM Timing 1 */ - uint32_t dramtmg2; /* 0x108 SDRAM Timing 2 */ - uint32_t dramtmg3; /* 0x10c SDRAM Timing 3 */ - uint32_t dramtmg4; /* 0x110 SDRAM Timing 4 */ - uint32_t dramtmg5; /* 0x114 SDRAM Timing 5 */ - uint32_t dramtmg6; /* 0x118 SDRAM Timing 6 */ - uint32_t dramtmg7; /* 0x11c SDRAM Timing 7 */ - uint32_t dramtmg8; /* 0x120 SDRAM Timing 8 */ - uint8_t reserved124[0x138 - 0x124]; - uint32_t dramtmg14; /* 0x138 SDRAM Timing 14 */ - uint32_t dramtmg15; /* 0x13C SDRAM Timing 15 */ - uint8_t reserved140[0x180 - 0x140]; - uint32_t zqctl0; /* 0x180 ZQ Control 0 */ - uint32_t zqctl1; /* 0x184 ZQ Control 1 */ - uint32_t zqctl2; /* 0x188 ZQ Control 2 */ - uint32_t zqstat; /* 0x18c ZQ Status */ - uint32_t dfitmg0; /* 0x190 DFI Timing 0 */ - uint32_t dfitmg1; /* 0x194 DFI Timing 1 */ - uint32_t dfilpcfg0; /* 0x198 DFI Low Power Configuration 0 */ - uint32_t reserved19c; - uint32_t dfiupd0; /* 0x1a0 DFI Update 0 */ - uint32_t dfiupd1; /* 0x1a4 DFI Update 1 */ - uint32_t dfiupd2; /* 0x1a8 DFI Update 2 */ - uint32_t reserved1ac; - uint32_t dfimisc; /* 0x1b0 DFI Miscellaneous Control */ - uint8_t reserved1b4[0x1bc - 0x1b4]; - uint32_t dfistat; /* 0x1bc DFI Miscellaneous Control */ - uint8_t reserved1c0[0x1c4 - 0x1c0]; - uint32_t dfiphymstr; /* 0x1c4 DFI PHY Master interface */ - uint8_t reserved1c8[0x204 - 0x1c8]; - uint32_t addrmap1; /* 0x204 Address Map 1 */ - uint32_t addrmap2; /* 0x208 Address Map 2 */ - uint32_t addrmap3; /* 0x20c Address Map 3 */ - uint32_t addrmap4; /* 0x210 Address Map 4 */ - uint32_t addrmap5; /* 0x214 Address Map 5 */ - uint32_t addrmap6; /* 0x218 Address Map 6 */ - uint8_t reserved21c[0x224 - 0x21c]; - uint32_t addrmap9; /* 0x224 Address Map 9 */ - uint32_t addrmap10; /* 0x228 Address Map 10 */ - uint32_t addrmap11; /* 0x22C Address Map 11 */ - uint8_t reserved230[0x240 - 0x230]; - uint32_t odtcfg; /* 0x240 ODT Configuration */ - uint32_t odtmap; /* 0x244 ODT/Rank Map */ - uint8_t reserved248[0x250 - 0x248]; - uint32_t sched; /* 0x250 Scheduler Control */ - uint32_t sched1; /* 0x254 Scheduler Control 1 */ - uint32_t reserved258; - uint32_t perfhpr1; /* 0x25c High Priority Read CAM 1 */ - uint32_t reserved260; - uint32_t perflpr1; /* 0x264 Low Priority Read CAM 1 */ - uint32_t reserved268; - uint32_t perfwr1; /* 0x26c Write CAM 1 */ - uint8_t reserved27c[0x300 - 0x270]; - uint32_t dbg0; /* 0x300 Debug 0 */ - uint32_t dbg1; /* 0x304 Debug 1 */ - uint32_t dbgcam; /* 0x308 CAM Debug */ - uint32_t dbgcmd; /* 0x30c Command Debug */ - uint32_t dbgstat; /* 0x310 Status Debug */ - uint8_t reserved314[0x320 - 0x314]; - uint32_t swctl; /* 0x320 Software Programming Control Enable */ - uint32_t swstat; /* 0x324 Software Programming Control Status */ - uint8_t reserved328[0x36c - 0x328]; - uint32_t poisoncfg; /* 0x36c AXI Poison Configuration Register */ - uint32_t poisonstat; /* 0x370 AXI Poison Status Register */ - uint8_t reserved374[0x3fc - 0x374]; - - /* Multi Port registers */ - uint32_t pstat; /* 0x3fc Port Status */ - uint32_t pccfg; /* 0x400 Port Common Configuration */ - - /* PORT 0 */ - uint32_t pcfgr_0; /* 0x404 Configuration Read */ - uint32_t pcfgw_0; /* 0x408 Configuration Write */ - uint8_t reserved40c[0x490 - 0x40c]; - uint32_t pctrl_0; /* 0x490 Port Control Register */ - uint32_t pcfgqos0_0; /* 0x494 Read QoS Configuration 0 */ - uint32_t pcfgqos1_0; /* 0x498 Read QoS Configuration 1 */ - uint32_t pcfgwqos0_0; /* 0x49c Write QoS Configuration 0 */ - uint32_t pcfgwqos1_0; /* 0x4a0 Write QoS Configuration 1 */ - uint8_t reserved4a4[0x4b4 - 0x4a4]; - - /* PORT 1 */ - uint32_t pcfgr_1; /* 0x4b4 Configuration Read */ - uint32_t pcfgw_1; /* 0x4b8 Configuration Write */ - uint8_t reserved4bc[0x540 - 0x4bc]; - uint32_t pctrl_1; /* 0x540 Port 2 Control Register */ - uint32_t pcfgqos0_1; /* 0x544 Read QoS Configuration 0 */ - uint32_t pcfgqos1_1; /* 0x548 Read QoS Configuration 1 */ - uint32_t pcfgwqos0_1; /* 0x54c Write QoS Configuration 0 */ - uint32_t pcfgwqos1_1; /* 0x550 Write QoS Configuration 1 */ -} __packed; - /* DDR Physical Interface Control (DDRPHYC) registers*/ -struct stm32mp1_ddrphy { +struct stm32mp_ddrphy { uint32_t ridr; /* 0x00 R Revision Identification */ uint32_t pir; /* 0x04 R/W PHY Initialization */ uint32_t pgcr; /* 0x08 R/W PHY General Configuration */ @@ -214,6 +85,7 @@ struct stm32mp1_ddrphy { uint32_t dx1dqtr; /* 0x210 Byte lane 1 DQ Timing */ uint32_t dx1dqstr; /* 0x214 Byte lane 1 QS Timing */ uint8_t res6[0x240 - 0x218]; /* 0x218 */ +#if STM32MP_DDR_32BIT_INTERFACE uint32_t dx2gcr; /* 0x240 Byte lane 2 General Configuration */ uint32_t dx2gsr0; /* 0x244 Byte lane 2 General Status 0 */ uint32_t dx2gsr1; /* 0x248 Byte lane 2 General Status 1 */ @@ -227,103 +99,9 @@ struct stm32mp1_ddrphy { uint32_t dx3dllcr; /* 0x28c Byte lane 3 DLL Control */ uint32_t dx3dqtr; /* 0x290 Byte lane 3 DQ Timing */ uint32_t dx3dqstr; /* 0x294 Byte lane 3 QS Timing */ +#endif } __packed; -/* DDR Controller registers offsets */ -#define DDRCTRL_MSTR 0x000 -#define DDRCTRL_STAT 0x004 -#define DDRCTRL_MRCTRL0 0x010 -#define DDRCTRL_MRSTAT 0x018 -#define DDRCTRL_PWRCTL 0x030 -#define DDRCTRL_PWRTMG 0x034 -#define DDRCTRL_HWLPCTL 0x038 -#define DDRCTRL_RFSHCTL3 0x060 -#define DDRCTRL_RFSHTMG 0x064 -#define DDRCTRL_INIT0 0x0D0 -#define DDRCTRL_DFIMISC 0x1B0 -#define DDRCTRL_DBG1 0x304 -#define DDRCTRL_DBGCAM 0x308 -#define DDRCTRL_DBGCMD 0x30C -#define DDRCTRL_DBGSTAT 0x310 -#define DDRCTRL_SWCTL 0x320 -#define DDRCTRL_SWSTAT 0x324 -#define DDRCTRL_PSTAT 0x3FC -#define DDRCTRL_PCTRL_0 0x490 -#define DDRCTRL_PCTRL_1 0x540 - -/* DDR Controller Register fields */ -#define DDRCTRL_MSTR_DDR3 BIT(0) -#define DDRCTRL_MSTR_LPDDR2 BIT(2) -#define DDRCTRL_MSTR_LPDDR3 BIT(3) -#define DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK GENMASK(13, 12) -#define DDRCTRL_MSTR_DATA_BUS_WIDTH_FULL 0 -#define DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF BIT(12) -#define DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER BIT(13) -#define DDRCTRL_MSTR_DLL_OFF_MODE BIT(15) - -#define DDRCTRL_STAT_OPERATING_MODE_MASK GENMASK(2, 0) -#define DDRCTRL_STAT_OPERATING_MODE_NORMAL BIT(0) -#define DDRCTRL_STAT_OPERATING_MODE_SR (BIT(0) | BIT(1)) -#define DDRCTRL_STAT_SELFREF_TYPE_MASK GENMASK(5, 4) -#define DDRCTRL_STAT_SELFREF_TYPE_ASR (BIT(4) | BIT(5)) -#define DDRCTRL_STAT_SELFREF_TYPE_SR BIT(5) - -#define DDRCTRL_MRCTRL0_MR_TYPE_WRITE U(0) -/* Only one rank supported */ -#define DDRCTRL_MRCTRL0_MR_RANK_SHIFT 4 -#define DDRCTRL_MRCTRL0_MR_RANK_ALL \ - BIT(DDRCTRL_MRCTRL0_MR_RANK_SHIFT) -#define DDRCTRL_MRCTRL0_MR_ADDR_SHIFT 12 -#define DDRCTRL_MRCTRL0_MR_ADDR_MASK GENMASK(15, 12) -#define DDRCTRL_MRCTRL0_MR_WR BIT(31) - -#define DDRCTRL_MRSTAT_MR_WR_BUSY BIT(0) - -#define DDRCTRL_PWRCTL_SELFREF_EN BIT(0) -#define DDRCTRL_PWRCTL_POWERDOWN_EN BIT(1) -#define DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE BIT(3) -#define DDRCTRL_PWRCTL_SELFREF_SW BIT(5) - -#define DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK GENMASK(23, 16) -#define DDRCTRL_PWRTMG_SELFREF_TO_X32_0 BIT(16) - -#define DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH BIT(0) - -#define DDRCTRL_HWLPCTL_HW_LP_EN BIT(0) - -#define DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_MASK GENMASK(27, 16) -#define DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_SHIFT 16 - -#define DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK GENMASK(31, 30) -#define DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL BIT(30) - -#define DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN BIT(0) - -#define DDRCTRL_DBG1_DIS_HIF BIT(1) - -#define DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY BIT(29) -#define DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY BIT(28) -#define DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY BIT(26) -#define DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH GENMASK(12, 8) -#define DDRCTRL_DBGCAM_DBG_HPR_Q_DEPTH GENMASK(4, 0) -#define DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY \ - (DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY | \ - DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY) -#define DDRCTRL_DBGCAM_DBG_Q_DEPTH \ - (DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY | \ - DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH | \ - DDRCTRL_DBGCAM_DBG_HPR_Q_DEPTH) - -#define DDRCTRL_DBGCMD_RANK0_REFRESH BIT(0) - -#define DDRCTRL_DBGSTAT_RANK0_REFRESH_BUSY BIT(0) - -#define DDRCTRL_SWCTL_SW_DONE BIT(0) - -#define DDRCTRL_SWSTAT_SW_DONE_ACK BIT(0) - -#define DDRCTRL_PCTRL_N_PORT_EN BIT(0) - /* DDR PHY registers offsets */ #define DDRPHYC_PIR 0x004 #define DDRPHYC_PGCR 0x008 @@ -339,10 +117,12 @@ struct stm32mp1_ddrphy { #define DDRPHYC_DX0DLLCR 0x1CC #define DDRPHYC_DX1GCR 0x200 #define DDRPHYC_DX1DLLCR 0x20C +#if STM32MP_DDR_32BIT_INTERFACE #define DDRPHYC_DX2GCR 0x240 #define DDRPHYC_DX2DLLCR 0x24C #define DDRPHYC_DX3GCR 0x280 #define DDRPHYC_DX3DLLCR 0x28C +#endif /* DDR PHY Register fields */ #define DDRPHYC_PIR_INIT BIT(0) @@ -353,6 +133,7 @@ struct stm32mp1_ddrphy { #define DDRPHYC_PIR_DRAMRST BIT(5) #define DDRPHYC_PIR_DRAMINIT BIT(6) #define DDRPHYC_PIR_QSTRN BIT(7) +#define DDRPHYC_PIR_RVTRN BIT(8) #define DDRPHYC_PIR_ICPC BIT(16) #define DDRPHYC_PIR_ZCALBYP BIT(30) #define DDRPHYC_PIR_INITSTEPS_MASK GENMASK(31, 7) diff --git a/include/drivers/st/stm32mp_ddr.h b/include/drivers/st/stm32mp_ddr.h new file mode 100644 index 000000000..1efca42a1 --- /dev/null +++ b/include/drivers/st/stm32mp_ddr.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2022, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause + */ + +#ifndef STM32MP_DDR_H +#define STM32MP_DDR_H + +#include + +enum stm32mp_ddr_base_type { + DDR_BASE, + DDRPHY_BASE, + NONE_BASE +}; + +enum stm32mp_ddr_reg_type { + REG_REG, + REG_TIMING, + REG_PERF, + REG_MAP, + REGPHY_REG, + REGPHY_TIMING, + REG_TYPE_NB +}; + +struct stm32mp_ddr_reg_desc { + const char *name; + uint16_t offset; /* Offset for base address */ + uint8_t par_offset; /* Offset for parameter array */ +}; + +struct stm32mp_ddr_reg_info { + const char *name; + const struct stm32mp_ddr_reg_desc *desc; + uint8_t size; + enum stm32mp_ddr_base_type base; +}; + +struct stm32mp_ddr_size { + uint64_t base; + uint64_t size; +}; + +struct stm32mp_ddr_priv { + struct stm32mp_ddr_size info; + struct stm32mp_ddrctl *ctl; + struct stm32mp_ddrphy *phy; + uintptr_t pwr; + uintptr_t rcc; +}; + +struct stm32mp_ddr_info { + const char *name; + uint32_t speed; /* in kHZ */ + uint32_t size; /* Memory size in byte = col * row * width */ +}; + +#define TIMEOUT_US_1S 1000000U + +void stm32mp_ddr_set_reg(const struct stm32mp_ddr_priv *priv, enum stm32mp_ddr_reg_type type, + const void *param, const struct stm32mp_ddr_reg_info *ddr_registers); +void stm32mp_ddr_start_sw_done(struct stm32mp_ddrctl *ctl); +void stm32mp_ddr_wait_sw_done_ack(struct stm32mp_ddrctl *ctl); +void stm32mp_ddr_enable_axi_port(struct stm32mp_ddrctl *ctl); +int stm32mp_board_ddr_power_init(enum ddr_type ddr_type); + +#endif /* STM32MP_DDR_H */ diff --git a/include/drivers/st/stm32mp_ddr_test.h b/include/drivers/st/stm32mp_ddr_test.h new file mode 100644 index 000000000..34e522ae3 --- /dev/null +++ b/include/drivers/st/stm32mp_ddr_test.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2022, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef STM32MP_DDR_TEST_H +#define STM32MP_DDR_TEST_H + +#include + +uint32_t stm32mp_ddr_test_rw_access(void); +uint32_t stm32mp_ddr_test_data_bus(void); +uint32_t stm32mp_ddr_test_addr_bus(uint64_t size); +uint32_t stm32mp_ddr_check_size(void); + +#endif /* STM32MP_DDR_TEST_H */ diff --git a/include/drivers/st/stm32mp_ddrctrl_regs.h b/include/drivers/st/stm32mp_ddrctrl_regs.h new file mode 100644 index 000000000..79de86b2a --- /dev/null +++ b/include/drivers/st/stm32mp_ddrctrl_regs.h @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2022, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause + */ + +#ifndef STM32MP_DDRCTRL_REGS_H +#define STM32MP_DDRCTRL_REGS_H + +#include +#include + +#include + +/* DDR Controller (DDRCTRL) registers */ +struct stm32mp_ddrctl { + uint32_t mstr ; /* 0x0 Master */ + uint32_t stat; /* 0x4 Operating Mode Status */ + uint8_t reserved008[0x10 - 0x8]; + uint32_t mrctrl0; /* 0x10 Control 0 */ + uint32_t mrctrl1; /* 0x14 Control 1 */ + uint32_t mrstat; /* 0x18 Status */ + uint32_t mrctrl2; /* 0x1c Control 2 */ + uint32_t derateen; /* 0x20 Temperature Derate Enable */ + uint32_t derateint; /* 0x24 Temperature Derate Interval */ + uint32_t reserved028; + uint32_t deratectl; /* 0x2c Temperature Derate Control */ + uint32_t pwrctl; /* 0x30 Low Power Control */ + uint32_t pwrtmg; /* 0x34 Low Power Timing */ + uint32_t hwlpctl; /* 0x38 Hardware Low Power Control */ + uint8_t reserved03c[0x50 - 0x3c]; + uint32_t rfshctl0; /* 0x50 Refresh Control 0 */ + uint32_t rfshctl1; /* 0x54 Refresh Control 1 */ + uint32_t reserved058; /* 0x58 Refresh Control 2 */ + uint32_t reserved05C; + uint32_t rfshctl3; /* 0x60 Refresh Control 0 */ + uint32_t rfshtmg; /* 0x64 Refresh Timing */ + uint32_t rfshtmg1; /* 0x68 Refresh Timing 1 */ + uint8_t reserved06c[0xc0 - 0x6c]; + uint32_t crcparctl0; /* 0xc0 CRC Parity Control0 */ + uint32_t crcparctl1; /* 0xc4 CRC Parity Control1 */ + uint32_t reserved0c8; /* 0xc8 CRC Parity Control2 */ + uint32_t crcparstat; /* 0xcc CRC Parity Status */ + uint32_t init0; /* 0xd0 SDRAM Initialization 0 */ + uint32_t init1; /* 0xd4 SDRAM Initialization 1 */ + uint32_t init2; /* 0xd8 SDRAM Initialization 2 */ + uint32_t init3; /* 0xdc SDRAM Initialization 3 */ + uint32_t init4; /* 0xe0 SDRAM Initialization 4 */ + uint32_t init5; /* 0xe4 SDRAM Initialization 5 */ + uint32_t init6; /* 0xe8 SDRAM Initialization 6 */ + uint32_t init7; /* 0xec SDRAM Initialization 7 */ + uint32_t dimmctl; /* 0xf0 DIMM Control */ + uint32_t rankctl; /* 0xf4 Rank Control */ + uint8_t reserved0f4[0x100 - 0xf8]; + uint32_t dramtmg0; /* 0x100 SDRAM Timing 0 */ + uint32_t dramtmg1; /* 0x104 SDRAM Timing 1 */ + uint32_t dramtmg2; /* 0x108 SDRAM Timing 2 */ + uint32_t dramtmg3; /* 0x10c SDRAM Timing 3 */ + uint32_t dramtmg4; /* 0x110 SDRAM Timing 4 */ + uint32_t dramtmg5; /* 0x114 SDRAM Timing 5 */ + uint32_t dramtmg6; /* 0x118 SDRAM Timing 6 */ + uint32_t dramtmg7; /* 0x11c SDRAM Timing 7 */ + uint32_t dramtmg8; /* 0x120 SDRAM Timing 8 */ + uint32_t dramtmg9; /* 0x124 SDRAM Timing 9 */ + uint32_t dramtmg10; /* 0x128 SDRAM Timing 10 */ + uint32_t dramtmg11; /* 0x12c SDRAM Timing 11 */ + uint32_t dramtmg12; /* 0x130 SDRAM Timing 12 */ + uint32_t dramtmg13; /* 0x134 SDRAM Timing 13 */ + uint32_t dramtmg14; /* 0x138 SDRAM Timing 14 */ + uint32_t dramtmg15; /* 0x13c SDRAM Timing 15 */ + uint8_t reserved140[0x180 - 0x140]; + uint32_t zqctl0; /* 0x180 ZQ Control 0 */ + uint32_t zqctl1; /* 0x184 ZQ Control 1 */ + uint32_t zqctl2; /* 0x188 ZQ Control 2 */ + uint32_t zqstat; /* 0x18c ZQ Status */ + uint32_t dfitmg0; /* 0x190 DFI Timing 0 */ + uint32_t dfitmg1; /* 0x194 DFI Timing 1 */ + uint32_t dfilpcfg0; /* 0x198 DFI Low Power Configuration 0 */ + uint32_t dfilpcfg1; /* 0x19c DFI Low Power Configuration 1 */ + uint32_t dfiupd0; /* 0x1a0 DFI Update 0 */ + uint32_t dfiupd1; /* 0x1a4 DFI Update 1 */ + uint32_t dfiupd2; /* 0x1a8 DFI Update 2 */ + uint32_t reserved1ac; + uint32_t dfimisc; /* 0x1b0 DFI Miscellaneous Control */ + uint32_t dfitmg2; /* 0x1b4 DFI Timing 2 */ + uint32_t dfitmg3; /* 0x1b8 DFI Timing 3 */ + uint32_t dfistat; /* 0x1bc DFI Status */ + uint32_t dbictl; /* 0x1c0 DM/DBI Control */ + uint32_t dfiphymstr; /* 0x1c4 DFI PHY Master interface */ + uint8_t reserved1c8[0x200 - 0x1c8]; + uint32_t addrmap0; /* 0x200 Address Map 0 */ + uint32_t addrmap1; /* 0x204 Address Map 1 */ + uint32_t addrmap2; /* 0x208 Address Map 2 */ + uint32_t addrmap3; /* 0x20c Address Map 3 */ + uint32_t addrmap4; /* 0x210 Address Map 4 */ + uint32_t addrmap5; /* 0x214 Address Map 5 */ + uint32_t addrmap6; /* 0x218 Address Map 6 */ + uint32_t addrmap7; /* 0x21c Address Map 7 */ + uint32_t addrmap8; /* 0x220 Address Map 8 */ + uint32_t addrmap9; /* 0x224 Address Map 9 */ + uint32_t addrmap10; /* 0x228 Address Map 10 */ + uint32_t addrmap11; /* 0x22C Address Map 11 */ + uint8_t reserved230[0x240 - 0x230]; + uint32_t odtcfg; /* 0x240 ODT Configuration */ + uint32_t odtmap; /* 0x244 ODT/Rank Map */ + uint8_t reserved248[0x250 - 0x248]; + uint32_t sched; /* 0x250 Scheduler Control */ + uint32_t sched1; /* 0x254 Scheduler Control 1 */ + uint32_t reserved258; + uint32_t perfhpr1; /* 0x25c High Priority Read CAM 1 */ + uint32_t reserved260; + uint32_t perflpr1; /* 0x264 Low Priority Read CAM 1 */ + uint32_t reserved268; + uint32_t perfwr1; /* 0x26c Write CAM 1 */ + uint8_t reserved27c[0x300 - 0x270]; + uint32_t dbg0; /* 0x300 Debug 0 */ + uint32_t dbg1; /* 0x304 Debug 1 */ + uint32_t dbgcam; /* 0x308 CAM Debug */ + uint32_t dbgcmd; /* 0x30c Command Debug */ + uint32_t dbgstat; /* 0x310 Status Debug */ + uint8_t reserved314[0x320 - 0x314]; + uint32_t swctl; /* 0x320 Software Programming Control Enable */ + uint32_t swstat; /* 0x324 Software Programming Control Status */ + uint8_t reserved328[0x36c - 0x328]; + uint32_t poisoncfg; /* 0x36c AXI Poison Configuration Register */ + uint32_t poisonstat; /* 0x370 AXI Poison Status Register */ + uint8_t reserved374[0x3f0 - 0x374]; + uint32_t deratestat; /* 0x3f0 Temperature Derate Status */ + uint8_t reserved3f4[0x3fc - 0x3f4]; + + /* Multi Port registers */ + uint32_t pstat; /* 0x3fc Port Status */ + uint32_t pccfg; /* 0x400 Port Common Configuration */ + + /* PORT 0 */ + uint32_t pcfgr_0; /* 0x404 Configuration Read */ + uint32_t pcfgw_0; /* 0x408 Configuration Write */ + uint8_t reserved40c[0x490 - 0x40c]; + uint32_t pctrl_0; /* 0x490 Port Control Register */ + uint32_t pcfgqos0_0; /* 0x494 Read QoS Configuration 0 */ + uint32_t pcfgqos1_0; /* 0x498 Read QoS Configuration 1 */ + uint32_t pcfgwqos0_0; /* 0x49c Write QoS Configuration 0 */ + uint32_t pcfgwqos1_0; /* 0x4a0 Write QoS Configuration 1 */ + uint8_t reserved4a4[0x4b4 - 0x4a4]; + +#if STM32MP_DDR_DUAL_AXI_PORT + /* PORT 1 */ + uint32_t pcfgr_1; /* 0x4b4 Configuration Read */ + uint32_t pcfgw_1; /* 0x4b8 Configuration Write */ + uint8_t reserved4bc[0x540 - 0x4bc]; + uint32_t pctrl_1; /* 0x540 Port 2 Control Register */ + uint32_t pcfgqos0_1; /* 0x544 Read QoS Configuration 0 */ + uint32_t pcfgqos1_1; /* 0x548 Read QoS Configuration 1 */ + uint32_t pcfgwqos0_1; /* 0x54c Write QoS Configuration 0 */ + uint32_t pcfgwqos1_1; /* 0x550 Write QoS Configuration 1 */ +#endif + + uint8_t reserved554[0xff0 - 0x554]; + uint32_t umctl2_ver_number; /* 0xff0 UMCTL2 Version Number */ +} __packed; + +/* DDR Controller registers offsets */ +#define DDRCTRL_MSTR 0x000 +#define DDRCTRL_STAT 0x004 +#define DDRCTRL_MRCTRL0 0x010 +#define DDRCTRL_MRSTAT 0x018 +#define DDRCTRL_PWRCTL 0x030 +#define DDRCTRL_PWRTMG 0x034 +#define DDRCTRL_HWLPCTL 0x038 +#define DDRCTRL_RFSHCTL3 0x060 +#define DDRCTRL_RFSHTMG 0x064 +#define DDRCTRL_INIT0 0x0D0 +#define DDRCTRL_DFIMISC 0x1B0 +#define DDRCTRL_DBG1 0x304 +#define DDRCTRL_DBGCAM 0x308 +#define DDRCTRL_DBGCMD 0x30C +#define DDRCTRL_DBGSTAT 0x310 +#define DDRCTRL_SWCTL 0x320 +#define DDRCTRL_SWSTAT 0x324 +#define DDRCTRL_PSTAT 0x3FC +#define DDRCTRL_PCTRL_0 0x490 +#if STM32MP_DDR_DUAL_AXI_PORT +#define DDRCTRL_PCTRL_1 0x540 +#endif + +/* DDR Controller Register fields */ +#define DDRCTRL_MSTR_DDR3 BIT(0) +#define DDRCTRL_MSTR_LPDDR2 BIT(2) +#define DDRCTRL_MSTR_LPDDR3 BIT(3) +#define DDRCTRL_MSTR_DDR4 BIT(4) +#define DDRCTRL_MSTR_LPDDR4 BIT(5) +#define DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK GENMASK(13, 12) +#define DDRCTRL_MSTR_DATA_BUS_WIDTH_FULL 0 +#define DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF BIT(12) +#define DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER BIT(13) +#define DDRCTRL_MSTR_DLL_OFF_MODE BIT(15) + +#define DDRCTRL_STAT_OPERATING_MODE_MASK GENMASK(2, 0) +#define DDRCTRL_STAT_OPERATING_MODE_NORMAL BIT(0) +#define DDRCTRL_STAT_OPERATING_MODE_SR (BIT(0) | BIT(1)) +#define DDRCTRL_STAT_SELFREF_TYPE_MASK GENMASK(5, 4) +#define DDRCTRL_STAT_SELFREF_TYPE_ASR (BIT(4) | BIT(5)) +#define DDRCTRL_STAT_SELFREF_TYPE_SR BIT(5) + +#define DDRCTRL_MRCTRL0_MR_TYPE_WRITE U(0) +/* Only one rank supported */ +#define DDRCTRL_MRCTRL0_MR_RANK_SHIFT 4 +#define DDRCTRL_MRCTRL0_MR_RANK_ALL \ + BIT(DDRCTRL_MRCTRL0_MR_RANK_SHIFT) +#define DDRCTRL_MRCTRL0_MR_ADDR_SHIFT 12 +#define DDRCTRL_MRCTRL0_MR_ADDR_MASK GENMASK(15, 12) +#define DDRCTRL_MRCTRL0_MR_WR BIT(31) + +#define DDRCTRL_MRSTAT_MR_WR_BUSY BIT(0) + +#define DDRCTRL_PWRCTL_SELFREF_EN BIT(0) +#define DDRCTRL_PWRCTL_POWERDOWN_EN BIT(1) +#define DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE BIT(3) +#define DDRCTRL_PWRCTL_SELFREF_SW BIT(5) + +#define DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK GENMASK(23, 16) +#define DDRCTRL_PWRTMG_SELFREF_TO_X32_0 BIT(16) + +#define DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH BIT(0) +#define DDRCTRL_RFSHCTL3_REFRESH_UPDATE_LEVEL BIT(1) + +#define DDRCTRL_HWLPCTL_HW_LP_EN BIT(0) + +#define DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_MASK GENMASK(27, 16) +#define DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_SHIFT 16 + +#define DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK GENMASK(31, 30) +#define DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL BIT(30) + +#define DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN BIT(0) +#define DDRCTRL_DFIMISC_DFI_INIT_START BIT(5) + +#define DDRCTRL_DFISTAT_DFI_INIT_COMPLETE BIT(0) + +#define DDRCTRL_DBG1_DIS_HIF BIT(1) + +#define DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY BIT(29) +#define DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY BIT(28) +#define DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY BIT(26) +#define DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH GENMASK(12, 8) +#define DDRCTRL_DBGCAM_DBG_HPR_Q_DEPTH GENMASK(4, 0) +#define DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY \ + (DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY | \ + DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY) +#define DDRCTRL_DBGCAM_DBG_Q_DEPTH \ + (DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY | \ + DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH | \ + DDRCTRL_DBGCAM_DBG_HPR_Q_DEPTH) + +#define DDRCTRL_DBGCMD_RANK0_REFRESH BIT(0) + +#define DDRCTRL_DBGSTAT_RANK0_REFRESH_BUSY BIT(0) + +#define DDRCTRL_SWCTL_SW_DONE BIT(0) + +#define DDRCTRL_SWSTAT_SW_DONE_ACK BIT(0) + +#define DDRCTRL_PCTRL_N_PORT_EN BIT(0) + +#endif /* STM32MP_DDRCTRL_REGS_H */ diff --git a/include/drivers/st/stm32mp_ram.h b/include/drivers/st/stm32mp_ram.h new file mode 100644 index 000000000..6e1e21d57 --- /dev/null +++ b/include/drivers/st/stm32mp_ram.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2022, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef STM32MP_RAM_H +#define STM32MP_RAM_H + +#include + +#include + +#define PARAM(x, y) \ + { \ + .name = x, \ + .offset = offsetof(struct stm32mp_ddr_config, y), \ + .size = sizeof(config.y) / sizeof(uint32_t), \ + } + +#define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x) +#define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x) + +struct stm32mp_ddr_param { + const char *name; /* Name in DT */ + const uint32_t offset; /* Offset in config struct */ + const uint32_t size; /* Size of parameters */ +}; + +int stm32mp_ddr_dt_get_info(void *fdt, int node, struct stm32mp_ddr_info *info); +int stm32mp_ddr_dt_get_param(void *fdt, int node, const struct stm32mp_ddr_param *param, + uint32_t param_size, uintptr_t config); + +#endif /* STM32MP_RAM_H */ diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index cc1e0d9ab..a24a5b06c 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -23,6 +23,10 @@ STM32_TF_VERSION ?= 0 # Enable dynamic memory mapping PLAT_XLAT_TABLES_DYNAMIC := 1 +# DDR controller with dual AXI port and 32-bit interface +STM32MP_DDR_DUAL_AXI_PORT:= 1 +STM32MP_DDR_32BIT_INTERFACE:= 1 + ifeq ($(AARCH32_SP),sp_min) # Disable Neon support: sp_min runtime may conflict with non-secure world TF_CFLAGS += -mfloat-abi=soft @@ -127,6 +131,8 @@ endif $(eval $(call assert_booleans,\ $(sort \ PLAT_XLAT_TABLES_DYNAMIC \ + STM32MP_DDR_32BIT_INTERFACE \ + STM32MP_DDR_DUAL_AXI_PORT \ STM32MP_EMMC \ STM32MP_EMMC_BOOT \ STM32MP_RAW_NAND \ @@ -151,6 +157,8 @@ $(eval $(call add_defines,\ PLAT_XLAT_TABLES_DYNAMIC \ STM32_TF_A_COPIES \ STM32_TF_VERSION \ + STM32MP_DDR_32BIT_INTERFACE \ + STM32MP_DDR_DUAL_AXI_PORT \ STM32MP_EMMC \ STM32MP_EMMC_BOOT \ STM32MP_RAW_NAND \ @@ -195,6 +203,7 @@ PLAT_BL_COMMON_SOURCES += drivers/arm/tzc/tzc400.c \ drivers/st/bsec/bsec.c \ drivers/st/clk/stm32mp_clkfunc.c \ drivers/st/clk/stm32mp1_clk.c \ + drivers/st/ddr/stm32mp_ddr.c \ drivers/st/ddr/stm32mp1_ddr_helpers.c \ drivers/st/gpio/stm32_gpio.c \ drivers/st/i2c/stm32_i2c.c \ @@ -288,7 +297,9 @@ BL2_SOURCES += drivers/st/usb/stm32mp1_usb.c \ plat/st/stm32mp1/stm32mp1_usb_dfu.c endif -BL2_SOURCES += drivers/st/ddr/stm32mp1_ddr.c \ +BL2_SOURCES += drivers/st/ddr/stm32mp_ddr_test.c \ + drivers/st/ddr/stm32mp_ram.c \ + drivers/st/ddr/stm32mp1_ddr.c \ drivers/st/ddr/stm32mp1_ram.c BL2_SOURCES += common/desc_image_load.c \ diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index b43245f64..95274696b 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -472,6 +472,7 @@ static inline uint32_t tamp_bkpr(uint32_t idx) * Device Tree defines ******************************************************************************/ #define DT_BSEC_COMPAT "st,stm32mp15-bsec" +#define DT_DDR_COMPAT "st,stm32mp1-ddr" #define DT_IWDG_COMPAT "st,stm32mp1-iwdg" #define DT_PWR_COMPAT "st,stm32mp1,pwr-reg" #define DT_RCC_CLK_COMPAT "st,stm32mp1-rcc"