1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (C) 2022, STMicroelectronics - All Rights Reserved 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <common/debug.h> 8*91f16700Schasinglulu #include <drivers/delay_timer.h> 9*91f16700Schasinglulu #include <drivers/st/stm32mp_ddr.h> 10*91f16700Schasinglulu #include <drivers/st/stm32mp_ddrctrl_regs.h> 11*91f16700Schasinglulu #include <drivers/st/stm32mp_pmic.h> 12*91f16700Schasinglulu #include <lib/mmio.h> 13*91f16700Schasinglulu 14*91f16700Schasinglulu #include <platform_def.h> 15*91f16700Schasinglulu 16*91f16700Schasinglulu #define INVALID_OFFSET 0xFFU 17*91f16700Schasinglulu 18*91f16700Schasinglulu static uintptr_t get_base_addr(const struct stm32mp_ddr_priv *priv, enum stm32mp_ddr_base_type base) 19*91f16700Schasinglulu { 20*91f16700Schasinglulu if (base == DDRPHY_BASE) { 21*91f16700Schasinglulu return (uintptr_t)priv->phy; 22*91f16700Schasinglulu } else { 23*91f16700Schasinglulu return (uintptr_t)priv->ctl; 24*91f16700Schasinglulu } 25*91f16700Schasinglulu } 26*91f16700Schasinglulu 27*91f16700Schasinglulu void stm32mp_ddr_set_reg(const struct stm32mp_ddr_priv *priv, enum stm32mp_ddr_reg_type type, 28*91f16700Schasinglulu const void *param, const struct stm32mp_ddr_reg_info *ddr_registers) 29*91f16700Schasinglulu { 30*91f16700Schasinglulu unsigned int i; 31*91f16700Schasinglulu unsigned int value; 32*91f16700Schasinglulu enum stm32mp_ddr_base_type base = ddr_registers[type].base; 33*91f16700Schasinglulu uintptr_t base_addr = get_base_addr(priv, base); 34*91f16700Schasinglulu const struct stm32mp_ddr_reg_desc *desc = ddr_registers[type].desc; 35*91f16700Schasinglulu 36*91f16700Schasinglulu VERBOSE("init %s\n", ddr_registers[type].name); 37*91f16700Schasinglulu for (i = 0; i < ddr_registers[type].size; i++) { 38*91f16700Schasinglulu uintptr_t ptr = base_addr + desc[i].offset; 39*91f16700Schasinglulu 40*91f16700Schasinglulu if (desc[i].par_offset == INVALID_OFFSET) { 41*91f16700Schasinglulu ERROR("invalid parameter offset for %s", desc[i].name); 42*91f16700Schasinglulu panic(); 43*91f16700Schasinglulu } else { 44*91f16700Schasinglulu value = *((uint32_t *)((uintptr_t)param + 45*91f16700Schasinglulu desc[i].par_offset)); 46*91f16700Schasinglulu mmio_write_32(ptr, value); 47*91f16700Schasinglulu } 48*91f16700Schasinglulu } 49*91f16700Schasinglulu } 50*91f16700Schasinglulu 51*91f16700Schasinglulu /* Start quasi dynamic register update */ 52*91f16700Schasinglulu void stm32mp_ddr_start_sw_done(struct stm32mp_ddrctl *ctl) 53*91f16700Schasinglulu { 54*91f16700Schasinglulu mmio_clrbits_32((uintptr_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE); 55*91f16700Schasinglulu VERBOSE("[0x%lx] swctl = 0x%x\n", 56*91f16700Schasinglulu (uintptr_t)&ctl->swctl, mmio_read_32((uintptr_t)&ctl->swctl)); 57*91f16700Schasinglulu } 58*91f16700Schasinglulu 59*91f16700Schasinglulu /* Wait quasi dynamic register update */ 60*91f16700Schasinglulu void stm32mp_ddr_wait_sw_done_ack(struct stm32mp_ddrctl *ctl) 61*91f16700Schasinglulu { 62*91f16700Schasinglulu uint64_t timeout; 63*91f16700Schasinglulu uint32_t swstat; 64*91f16700Schasinglulu 65*91f16700Schasinglulu mmio_setbits_32((uintptr_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE); 66*91f16700Schasinglulu VERBOSE("[0x%lx] swctl = 0x%x\n", 67*91f16700Schasinglulu (uintptr_t)&ctl->swctl, mmio_read_32((uintptr_t)&ctl->swctl)); 68*91f16700Schasinglulu 69*91f16700Schasinglulu timeout = timeout_init_us(TIMEOUT_US_1S); 70*91f16700Schasinglulu do { 71*91f16700Schasinglulu swstat = mmio_read_32((uintptr_t)&ctl->swstat); 72*91f16700Schasinglulu VERBOSE("[0x%lx] swstat = 0x%x ", 73*91f16700Schasinglulu (uintptr_t)&ctl->swstat, swstat); 74*91f16700Schasinglulu if (timeout_elapsed(timeout)) { 75*91f16700Schasinglulu panic(); 76*91f16700Schasinglulu } 77*91f16700Schasinglulu } while ((swstat & DDRCTRL_SWSTAT_SW_DONE_ACK) == 0U); 78*91f16700Schasinglulu 79*91f16700Schasinglulu VERBOSE("[0x%lx] swstat = 0x%x\n", 80*91f16700Schasinglulu (uintptr_t)&ctl->swstat, swstat); 81*91f16700Schasinglulu } 82*91f16700Schasinglulu 83*91f16700Schasinglulu void stm32mp_ddr_enable_axi_port(struct stm32mp_ddrctl *ctl) 84*91f16700Schasinglulu { 85*91f16700Schasinglulu /* Enable uMCTL2 AXI port 0 */ 86*91f16700Schasinglulu mmio_setbits_32((uintptr_t)&ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN); 87*91f16700Schasinglulu VERBOSE("[0x%lx] pctrl_0 = 0x%x\n", (uintptr_t)&ctl->pctrl_0, 88*91f16700Schasinglulu mmio_read_32((uintptr_t)&ctl->pctrl_0)); 89*91f16700Schasinglulu 90*91f16700Schasinglulu #if STM32MP_DDR_DUAL_AXI_PORT 91*91f16700Schasinglulu /* Enable uMCTL2 AXI port 1 */ 92*91f16700Schasinglulu mmio_setbits_32((uintptr_t)&ctl->pctrl_1, DDRCTRL_PCTRL_N_PORT_EN); 93*91f16700Schasinglulu VERBOSE("[0x%lx] pctrl_1 = 0x%x\n", (uintptr_t)&ctl->pctrl_1, 94*91f16700Schasinglulu mmio_read_32((uintptr_t)&ctl->pctrl_1)); 95*91f16700Schasinglulu #endif 96*91f16700Schasinglulu 97*91f16700Schasinglulu } 98*91f16700Schasinglulu 99*91f16700Schasinglulu int stm32mp_board_ddr_power_init(enum ddr_type ddr_type) 100*91f16700Schasinglulu { 101*91f16700Schasinglulu if (dt_pmic_status() > 0) { 102*91f16700Schasinglulu return pmic_ddr_power_init(ddr_type); 103*91f16700Schasinglulu } 104*91f16700Schasinglulu 105*91f16700Schasinglulu return 0; 106*91f16700Schasinglulu } 107