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