xref: /rk3399_ARM-atf/drivers/st/ddr/stm32mp2_ram.c (revision f05b4894acfb681017bfda71fb16e6079a4f6a43)
1 /*
2  * Copyright (C) 2021-2025, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
5  */
6 
7 #include <errno.h>
8 
9 #include <arch_helpers.h>
10 #include <common/debug.h>
11 #include <common/fdt_wrappers.h>
12 #include <drivers/clk.h>
13 #include <drivers/st/stm32mp2_ddr.h>
14 #include <drivers/st/stm32mp2_ddr_helpers.h>
15 #include <drivers/st/stm32mp2_ram.h>
16 #include <drivers/st/stm32mp_ddr.h>
17 #include <drivers/st/stm32mp_ddr_test.h>
18 #include <drivers/st/stm32mp_ram.h>
19 
20 #include <lib/mmio.h>
21 #include <libfdt.h>
22 
23 #include <platform_def.h>
24 
25 static struct stm32mp_ddr_priv ddr_priv_data;
26 static bool ddr_self_refresh;
27 
28 static int ddr_dt_get_ui_param(void *fdt, int node, struct stm32mp_ddr_config *config)
29 {
30 	int ret;
31 	uint32_t size;
32 
33 	size = sizeof(struct user_input_basic) / sizeof(int);
34 	ret = fdt_read_uint32_array(fdt, node, "st,phy-basic", size, (uint32_t *)&config->uib);
35 
36 	VERBOSE("%s: %s[0x%x] = %d\n", __func__, "st,phy-basic", size, ret);
37 	if (ret != 0) {
38 		ERROR("%s: can't read %s, error=%d\n", __func__, "st,phy-basic", ret);
39 		return -EINVAL;
40 	}
41 
42 	size = sizeof(struct user_input_advanced) / sizeof(int);
43 	ret = fdt_read_uint32_array(fdt, node, "st,phy-advanced", size, (uint32_t *)&config->uia);
44 
45 	VERBOSE("%s: %s[0x%x] = %d\n", __func__, "st,phy-advanced", size, ret);
46 	if (ret != 0) {
47 		ERROR("%s: can't read %s, error=%d\n", __func__, "st,phy-advanced", ret);
48 		return -EINVAL;
49 	}
50 
51 	size = sizeof(struct user_input_mode_register) / sizeof(int);
52 	ret = fdt_read_uint32_array(fdt, node, "st,phy-mr", size, (uint32_t *)&config->uim);
53 
54 	VERBOSE("%s: %s[0x%x] = %d\n", __func__, "st,phy-mr", size, ret);
55 	if (ret != 0) {
56 		ERROR("%s: can't read %s, error=%d\n", __func__, "st,phy-mr", ret);
57 		return -EINVAL;
58 	}
59 
60 	size = sizeof(struct user_input_swizzle) / sizeof(int);
61 	ret = fdt_read_uint32_array(fdt, node, "st,phy-swizzle", size, (uint32_t *)&config->uis);
62 
63 	VERBOSE("%s: %s[0x%x] = %d\n", __func__, "st,phy-swizzle", size, ret);
64 	if (ret != 0) {
65 		ERROR("%s: can't read %s, error=%d\n", __func__, "st,phy-swizzle", ret);
66 		return -EINVAL;
67 	}
68 
69 	return 0;
70 }
71 
72 static int stm32mp2_ddr_setup(void)
73 {
74 	struct stm32mp_ddr_priv *priv = &ddr_priv_data;
75 	int ret;
76 	struct stm32mp_ddr_config config;
77 	int node;
78 	uintptr_t uret;
79 	void *fdt;
80 
81 	const struct stm32mp_ddr_param param[] = {
82 		CTL_PARAM(reg),
83 		CTL_PARAM(timing),
84 		CTL_PARAM(map),
85 		CTL_PARAM(perf)
86 	};
87 
88 	if (fdt_get_address(&fdt) == 0) {
89 		return -ENOENT;
90 	}
91 
92 	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
93 	if (node < 0) {
94 		ERROR("%s: can't read DDR node in DT\n", __func__);
95 		return -EINVAL;
96 	}
97 
98 	ret = stm32mp_ddr_dt_get_info(fdt, node, &config.info);
99 	if (ret < 0) {
100 		return ret;
101 	}
102 
103 	ret = stm32mp_ddr_dt_get_param(fdt, node, param, ARRAY_SIZE(param), (uintptr_t)&config);
104 	if (ret < 0) {
105 		return ret;
106 	}
107 
108 	ret = ddr_dt_get_ui_param(fdt, node, &config);
109 	if (ret < 0) {
110 		return ret;
111 	}
112 
113 	config.self_refresh = false;
114 
115 	if (stm32mp_is_wakeup_from_standby()) {
116 		config.self_refresh = true;
117 	}
118 
119 	/*  Map dynamically RETRAM area to save or restore PHY retention registers */
120 	if (stm32mp_map_retram() != 0) {
121 		panic();
122 	}
123 
124 	stm32mp2_ddr_init(priv, &config);
125 
126 	/*  Unmap RETRAM, no more used until next DDR initialization call */
127 	if (stm32mp_unmap_retram() != 0) {
128 		panic();
129 	}
130 
131 	priv->info.size = config.info.size;
132 
133 	VERBOSE("%s : ram size(%lx, %lx)\n", __func__, priv->info.base, priv->info.size);
134 
135 	if (stm32mp_map_ddr_non_cacheable() != 0) {
136 		panic();
137 	}
138 
139 	if (config.self_refresh) {
140 		uret = stm32mp_ddr_test_rw_access();
141 		if (uret != 0UL) {
142 			ERROR("DDR rw test: can't access memory @ 0x%lx\n", uret);
143 			panic();
144 		}
145 	} else {
146 		size_t retsize;
147 
148 		uret = stm32mp_ddr_test_data_bus();
149 		if (uret != 0UL) {
150 			ERROR("DDR data bus test: can't access memory @ 0x%lx\n", uret);
151 			panic();
152 		}
153 
154 		uret = stm32mp_ddr_test_addr_bus(config.info.size);
155 		if (uret != 0UL) {
156 			ERROR("DDR addr bus test: can't access memory @ 0x%lx\n", uret);
157 			panic();
158 		}
159 
160 		retsize = stm32mp_ddr_check_size();
161 		if (retsize < config.info.size) {
162 			ERROR("DDR size: 0x%zx does not match DT config: 0x%zx\n",
163 			      retsize, config.info.size);
164 			panic();
165 		}
166 
167 		INFO("Memory size = 0x%zx (%zu MB)\n", retsize, retsize / (1024U * 1024U));
168 	}
169 
170 	/*
171 	 * Initialization sequence has configured DDR registers with settings.
172 	 * The Self Refresh (SR) mode corresponding to these settings has now
173 	 * to be set.
174 	 */
175 	ddr_set_sr_mode(ddr_read_sr_mode());
176 
177 	if (stm32mp_unmap_ddr() != 0) {
178 		panic();
179 	}
180 
181 	/* Save DDR self_refresh state */
182 	ddr_self_refresh = config.self_refresh;
183 
184 	return 0;
185 }
186 
187 bool stm32mp2_ddr_is_restored(void)
188 {
189 	return ddr_self_refresh;
190 }
191 
192 int stm32mp2_ddr_probe(void)
193 {
194 	struct stm32mp_ddr_priv *priv = &ddr_priv_data;
195 
196 	VERBOSE("STM32MP DDR probe\n");
197 
198 	priv->ctl = (struct stm32mp_ddrctl *)stm32mp_ddrctrl_base();
199 	priv->phy = (struct stm32mp_ddrphy *)stm32mp_ddrphyc_base();
200 	priv->pwr = stm32mp_pwr_base();
201 	priv->rcc = stm32mp_rcc_base();
202 
203 	priv->info.base = STM32MP_DDR_BASE;
204 	priv->info.size = 0;
205 
206 	return stm32mp2_ddr_setup();
207 }
208