xref: /rk3399_ARM-atf/plat/st/stm32mp2/plat_ddr.c (revision e2d6e5e21adcf9e41a335c31d5c337c65ad0a133)
1 /*
2  * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <errno.h>
9 #include <stdint.h>
10 
11 #include <common/fdt_wrappers.h>
12 #include <drivers/delay_timer.h>
13 #include <drivers/st/regulator.h>
14 #include <drivers/st/stm32mp_ddr.h>
15 
16 #include <libfdt.h>
17 #include <platform_def.h>
18 
19 #if STM32MP_DDR3_TYPE
20 struct ddr3_supply {
21 	struct rdev *vdd;
22 	struct rdev *vref;
23 	struct rdev *vtt;
24 };
25 
26 static void ddr3_supply_read(void *fdt, int node, struct ddr3_supply *supply)
27 {
28 	supply->vdd = regulator_get_by_supply_name(fdt, node, "vdd");
29 	supply->vref = regulator_get_by_supply_name(fdt, node, "vref");
30 	supply->vtt = regulator_get_by_supply_name(fdt, node, "vtt");
31 }
32 
33 static int ddr_power_init(void *fdt, int node)
34 {
35 	int status;
36 	struct ddr3_supply supply;
37 
38 	ddr3_supply_read(fdt, node, &supply);
39 	if ((supply.vdd == NULL) || (supply.vref == NULL) || (supply.vtt == NULL)) {
40 		return -ENOENT;
41 	}
42 
43 	/*
44 	 * DDR3 power on sequence is:
45 	 * enable VREF_DDR, VTT_DDR, VPP_DDR
46 	 */
47 	status = regulator_set_min_voltage(supply.vdd);
48 	if (status != 0) {
49 		return status;
50 	}
51 
52 	status = regulator_enable(supply.vdd);
53 	if (status != 0) {
54 		return status;
55 	}
56 
57 	status = regulator_enable(supply.vref);
58 	if (status != 0) {
59 		return status;
60 	}
61 
62 	return regulator_enable(supply.vtt);
63 }
64 #endif /* STM32MP_DDR3_TYPE */
65 
66 #if STM32MP_DDR4_TYPE
67 struct ddr4_supply {
68 	struct rdev *vdd;
69 	struct rdev *vref;
70 	struct rdev *vtt;
71 	struct rdev *vpp;
72 };
73 
74 static void ddr4_supply_read(void *fdt, int node, struct ddr4_supply *supply)
75 {
76 	supply->vpp = regulator_get_by_supply_name(fdt, node, "vpp");
77 	supply->vdd = regulator_get_by_supply_name(fdt, node, "vdd");
78 	supply->vref = regulator_get_by_supply_name(fdt, node, "vref");
79 	supply->vtt = regulator_get_by_supply_name(fdt, node, "vtt");
80 }
81 
82 static int ddr_power_init(void *fdt, int node)
83 {
84 	int status;
85 	struct ddr4_supply supply;
86 
87 	ddr4_supply_read(fdt, node, &supply);
88 	if ((supply.vpp == NULL) || (supply.vdd == NULL) || (supply.vref == NULL) ||
89 	    (supply.vtt == NULL)) {
90 		return -ENOENT;
91 	}
92 
93 	/*
94 	 * DDR4 power on sequence is:
95 	 * enable VPP_DDR
96 	 * enable VREF_DDR, VTT_DDR, VPP_DDR
97 	 */
98 	status = regulator_set_min_voltage(supply.vpp);
99 	if (status != 0) {
100 		return status;
101 	}
102 
103 	status = regulator_set_min_voltage(supply.vdd);
104 	if (status != 0) {
105 		return status;
106 	}
107 
108 	status = regulator_enable(supply.vpp);
109 	if (status != 0) {
110 		return status;
111 	}
112 
113 	status = regulator_enable(supply.vdd);
114 	if (status != 0) {
115 		return status;
116 	}
117 
118 	status = regulator_enable(supply.vref);
119 	if (status != 0) {
120 		return status;
121 	}
122 
123 	return regulator_enable(supply.vtt);
124 }
125 #endif /* STM32MP_DDR4_TYPE */
126 
127 #if STM32MP_LPDDR4_TYPE
128 struct lpddr4_supply {
129 	struct rdev *vdd1;
130 	struct rdev *vdd2;
131 	struct rdev *vddq;
132 };
133 
134 static void lpddr4_supply_read(void *fdt, int node, struct lpddr4_supply *supply)
135 {
136 	supply->vdd1 = regulator_get_by_supply_name(fdt, node, "vdd1");
137 	supply->vdd2 = regulator_get_by_supply_name(fdt, node, "vdd2");
138 	supply->vddq = regulator_get_by_supply_name(fdt, node, "vddq");
139 }
140 
141 static int ddr_power_init(void *fdt, int node)
142 {
143 	int status;
144 	struct lpddr4_supply supply;
145 
146 	lpddr4_supply_read(fdt, node, &supply);
147 	if ((supply.vdd1 == NULL) || (supply.vdd2 == NULL) || (supply.vddq == NULL)) {
148 		return -ENOENT;
149 	}
150 
151 	/*
152 	 * LPDDR4 power on sequence is:
153 	 * enable VDD1_DDR
154 	 * enable VDD2_DDR
155 	 * enable VDDQ_DDR
156 	 */
157 	status = regulator_set_min_voltage(supply.vdd1);
158 	if (status != 0) {
159 		return status;
160 	}
161 
162 	status = regulator_set_min_voltage(supply.vdd2);
163 	if (status != 0) {
164 		return status;
165 	}
166 
167 	status = regulator_set_min_voltage(supply.vddq);
168 	if (status != 0) {
169 		return status;
170 	}
171 
172 	status = regulator_enable(supply.vdd1);
173 	if (status != 0) {
174 		return status;
175 	}
176 
177 	status = regulator_enable(supply.vdd2);
178 	if (status != 0) {
179 		return status;
180 	}
181 
182 	return regulator_enable(supply.vddq);
183 }
184 #endif /* STM32MP_LPDDR4_TYPE */
185 
186 int stm32mp_board_ddr_power_init(enum ddr_type ddr_type)
187 {
188 	void *fdt = NULL;
189 	int node;
190 
191 	VERBOSE("DDR power init, ddr_type = %u\n", ddr_type);
192 
193 #if STM32MP_DDR3_TYPE
194 	assert(ddr_type == STM32MP_DDR3);
195 #elif STM32MP_DDR4_TYPE
196 	assert(ddr_type == STM32MP_DDR4);
197 #elif STM32MP_LPDDR4_TYPE
198 	assert(ddr_type == STM32MP_LPDDR4);
199 #else
200 	ERROR("DDR type (%u) not supported\n", ddr_type);
201 	panic();
202 #endif
203 
204 	if (fdt_get_address(&fdt) == 0) {
205 		return -FDT_ERR_NOTFOUND;
206 	}
207 
208 	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
209 	if (node < 0) {
210 		ERROR("%s: Cannot read DDR node in DT\n", __func__);
211 		return -EINVAL;
212 	}
213 
214 	return ddr_power_init(fdt, node);
215 }
216