xref: /rk3399_ARM-atf/drivers/st/ddr/stm32mp_ddr.c (revision 066a5958e72860b9945e1416174c22ff0d83b5e5)
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