xref: /rk3399_ARM-atf/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_mapdrvstren.c (revision f1f04d786795a02f81abeef7d1513e93098591ed)
1 /*
2  * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <stdlib.h>
8 #include <string.h>
9 
10 #include <common/debug.h>
11 
12 #include <ddrphy_phyinit.h>
13 
14 /*
15  * Maps impedance values to register settings
16  *
17  * Reads the pull-up/pull-down driver impedance from drvstren_ohm input
18  * and encodes that value for the CSR field specified in targetcsr input,
19  * based on DDR protocol.
20  *
21  * @param[in] drvstren_ohm drive strenght / ODT impedance in Ohms
22  *
23  * @param[in] targetcsr Target CSR for the impedance value. on of following
24  * enum drvtype:
25  *   - DRVSTRENFSDQP
26  *   - DRVSTRENFSDQN
27  *   - ODTSTRENP
28  *   - ODTSTRENN
29  *   - ADRVSTRENP
30  *   - ADRVSTRENN
31  *
32  * \return >=0 value on success, else negative.
33  */
34 int ddrphy_phyinit_mapdrvstren(uint32_t drvstren_ohm, enum drvtype targetcsr)
35 {
36 	int stren_setting = -1;
37 
38 	if ((targetcsr == DRVSTRENFSDQP) || (targetcsr == DRVSTRENFSDQN)) {
39 		if (drvstren_ohm == 0U) {
40 			stren_setting = 0x00; /* High-impedance */
41 		} else if (drvstren_ohm < 29U) {
42 			stren_setting = 0x3f;
43 		} else if (drvstren_ohm < 31U) {
44 			stren_setting = 0x3e;
45 		} else if (drvstren_ohm < 33U) {
46 			stren_setting = 0x3b;
47 		} else if (drvstren_ohm < 35U) {
48 			stren_setting = 0x3a;
49 		} else if (drvstren_ohm < 38U) {
50 			stren_setting = 0x39;
51 		} else if (drvstren_ohm < 41U) {
52 			stren_setting = 0x38;
53 		} else if (drvstren_ohm < 45U) {
54 			stren_setting = 0x1b;
55 		} else if (drvstren_ohm < 50U) {
56 			stren_setting = 0x1a;
57 		} else if (drvstren_ohm < 56U) {
58 			stren_setting = 0x19;
59 		} else if (drvstren_ohm < 64U) {
60 			stren_setting = 0x18;
61 		} else if (drvstren_ohm < 74U) {
62 			stren_setting = 0x0b;
63 		} else if (drvstren_ohm < 88U) {
64 			stren_setting = 0x0a;
65 		} else if (drvstren_ohm < 108U) {
66 			stren_setting = 0x09;
67 		} else if (drvstren_ohm < 140U) {
68 			stren_setting = 0x08;
69 		} else if (drvstren_ohm < 200U) {
70 			stren_setting = 0x03;
71 		} else if (drvstren_ohm < 360U) {
72 			stren_setting = 0x02;
73 		} else if (drvstren_ohm < 481U) {
74 			stren_setting = 0x01;
75 		} else {
76 			stren_setting = 0x00; /* High-impedance */
77 		}
78 	} else if (targetcsr == ODTSTRENP) {
79 #if STM32MP_DDR3_TYPE
80 		/*
81 		 * DDR3 - P and N has the same impedance and non-zero.
82 		 * user input is half the individual pull-up and pull-down impedances values
83 		 * because of parallel between them.
84 		 */
85 		if (drvstren_ohm == 0U) {
86 			stren_setting = 0x00; /* High-impedance */
87 		} else if (drvstren_ohm < 15U) {
88 			stren_setting = 0x3f;
89 		} else if (drvstren_ohm < 16U) {
90 			stren_setting = 0x3e;
91 		} else if (drvstren_ohm < 17U) {
92 			stren_setting = 0x3b;
93 		} else if (drvstren_ohm < 18U) {
94 			stren_setting = 0x3a;
95 		} else if (drvstren_ohm < 20U) {
96 			stren_setting = 0x39;
97 		} else if (drvstren_ohm < 21U) {
98 			stren_setting = 0x38;
99 		} else if (drvstren_ohm < 23U) {
100 			stren_setting = 0x1b;
101 		} else if (drvstren_ohm < 26U) {
102 			stren_setting = 0x1a;
103 		} else if (drvstren_ohm < 29U) {
104 			stren_setting = 0x19;
105 		} else if (drvstren_ohm < 33U) {
106 			stren_setting = 0x18;
107 		} else if (drvstren_ohm < 38U) {
108 			stren_setting = 0x0b;
109 		} else if (drvstren_ohm < 45U) {
110 			stren_setting = 0x0a;
111 		} else if (drvstren_ohm < 55U) {
112 			stren_setting = 0x09;
113 		} else if (drvstren_ohm < 71U) {
114 			stren_setting = 0x08;
115 		} else if (drvstren_ohm < 101U) {
116 			stren_setting = 0x03;
117 		} else if (drvstren_ohm < 181U) {
118 			stren_setting = 0x02;
119 		} else if (drvstren_ohm < 241U) {
120 			stren_setting = 0x01;
121 		} else {
122 			stren_setting = 0x00; /* High-impedance */
123 		}
124 #elif STM32MP_DDR4_TYPE
125 		/* DDR4 - P is non-zero */
126 		if (drvstren_ohm == 0U) {
127 			stren_setting = 0x00; /* High-impedance */
128 		} else if (drvstren_ohm < 29U) {
129 			stren_setting = 0x3f;
130 		} else if (drvstren_ohm < 31U) {
131 			stren_setting = 0x3e;
132 		} else if (drvstren_ohm < 33U) {
133 			stren_setting = 0x3b;
134 		} else if (drvstren_ohm < 35U) {
135 			stren_setting = 0x3a;
136 		} else if (drvstren_ohm < 38U) {
137 			stren_setting = 0x39;
138 		} else if (drvstren_ohm < 41U) {
139 			stren_setting = 0x38;
140 		} else if (drvstren_ohm < 45U) {
141 			stren_setting = 0x1b;
142 		} else if (drvstren_ohm < 50U) {
143 			stren_setting = 0x1a;
144 		} else if (drvstren_ohm < 56U) {
145 			stren_setting = 0x19;
146 		} else if (drvstren_ohm < 64U) {
147 			stren_setting = 0x18;
148 		} else if (drvstren_ohm < 74U) {
149 			stren_setting = 0x0b;
150 		} else if (drvstren_ohm < 88U) {
151 			stren_setting = 0x0a;
152 		} else if (drvstren_ohm < 108U) {
153 			stren_setting = 0x09;
154 		} else if (drvstren_ohm < 140U) {
155 			stren_setting = 0x08;
156 		} else if (drvstren_ohm < 200U) {
157 			stren_setting = 0x03;
158 		} else if (drvstren_ohm < 360U) {
159 			stren_setting = 0x02;
160 		} else if (drvstren_ohm < 481U) {
161 			stren_setting = 0x01;
162 		} else {
163 			stren_setting = 0x00; /* High-impedance */
164 		}
165 #else /* STM32MP_LPDDR4_TYPE */
166 		/* LPDDR4 - P is high-Z */
167 		stren_setting = 0x00; /* High-impedance */
168 #endif /* STM32MP_DDR3_TYPE */
169 	} else if (targetcsr == ODTSTRENN) {
170 #if STM32MP_DDR3_TYPE
171 		/*
172 		 * DDR3 - P and N has the same impedance and non-zero.
173 		 * Times 2 of user input because of parallel pull-up and pull-down termination.
174 		 */
175 		if (drvstren_ohm == 0U) {
176 			stren_setting = 0x00; /* High-impedance */
177 		} else if (drvstren_ohm < 15U) {
178 			stren_setting = 0x3f;
179 		} else if (drvstren_ohm < 16U) {
180 			stren_setting = 0x3e;
181 		} else if (drvstren_ohm < 17U) {
182 			stren_setting = 0x3b;
183 		} else if (drvstren_ohm < 18U) {
184 			stren_setting = 0x3a;
185 		} else if (drvstren_ohm < 20U) {
186 			stren_setting = 0x39;
187 		} else if (drvstren_ohm < 21U) {
188 			stren_setting = 0x38;
189 		} else if (drvstren_ohm < 23U) {
190 			stren_setting = 0x1b;
191 		} else if (drvstren_ohm < 26U) {
192 			stren_setting = 0x1a;
193 		} else if (drvstren_ohm < 29U) {
194 			stren_setting = 0x19;
195 		} else if (drvstren_ohm < 33U) {
196 			stren_setting = 0x18;
197 		} else if (drvstren_ohm < 38U) {
198 			stren_setting = 0x0b;
199 		} else if (drvstren_ohm < 45U) {
200 			stren_setting = 0x0a;
201 		} else if (drvstren_ohm < 55U) {
202 			stren_setting = 0x09;
203 		} else if (drvstren_ohm < 71U) {
204 			stren_setting = 0x08;
205 		} else if (drvstren_ohm < 101U) {
206 			stren_setting = 0x03;
207 		} else if (drvstren_ohm < 181U) {
208 			stren_setting = 0x02;
209 		} else if (drvstren_ohm < 241U) {
210 			stren_setting = 0x01;
211 		} else {
212 			stren_setting = 0x00; /* High-impedance */
213 		}
214 #elif STM32MP_DDR4_TYPE
215 		/* DDR4 - N is high-Z */
216 		stren_setting = 0x00; /* High-impedance */
217 #else /* STM32MP_LPDDR4_TYPE */
218 		/* LPDDR4 - N is non-zero */
219 		if (drvstren_ohm == 0U) {
220 			stren_setting = 0x00; /* High-impedance */
221 		} else if (drvstren_ohm < 29U) {
222 			stren_setting = 0x3f;
223 		} else if (drvstren_ohm < 31U) {
224 			stren_setting = 0x3e;
225 		} else if (drvstren_ohm < 33U) {
226 			stren_setting = 0x3b;
227 		} else if (drvstren_ohm < 35U) {
228 			stren_setting = 0x3a;
229 		} else if (drvstren_ohm < 38U) {
230 			stren_setting = 0x39;
231 		} else if (drvstren_ohm < 41U) {
232 			stren_setting = 0x38;
233 		} else if (drvstren_ohm < 45U) {
234 			stren_setting = 0x1b;
235 		} else if (drvstren_ohm < 50U) {
236 			stren_setting = 0x1a;
237 		} else if (drvstren_ohm < 56U) {
238 			stren_setting = 0x19;
239 		} else if (drvstren_ohm < 64U) {
240 			stren_setting = 0x18;
241 		} else if (drvstren_ohm < 74U) {
242 			stren_setting = 0x0b;
243 		} else if (drvstren_ohm < 88U) {
244 			stren_setting = 0x0a;
245 		} else if (drvstren_ohm < 108U) {
246 			stren_setting = 0x09;
247 		} else if (drvstren_ohm < 140U) {
248 			stren_setting = 0x08;
249 		} else if (drvstren_ohm < 200U) {
250 			stren_setting = 0x03;
251 		} else if (drvstren_ohm < 360U) {
252 			stren_setting = 0x02;
253 		} else if (drvstren_ohm < 481U) {
254 			stren_setting = 0x01;
255 		} else {
256 			stren_setting = 0x00; /* High-impedance */
257 		}
258 #endif /* STM32MP_DDR3_TYPE */
259 	} else {
260 		/* if ((targetcsr == ADRVSTRENP) || (targetcsr == ADRVSTRENN)) */
261 		if (drvstren_ohm == 120U) {
262 			stren_setting = 0x00;
263 		} else if (drvstren_ohm == 60U) {
264 			stren_setting = 0x01;
265 		} else if (drvstren_ohm == 40U) {
266 			stren_setting = 0x03;
267 		} else if (drvstren_ohm == 30U) {
268 			stren_setting = 0x07;
269 		} else if (drvstren_ohm == 24U) {
270 			stren_setting = 0x0F;
271 		} else if (drvstren_ohm == 20U) {
272 			stren_setting = 0x1F;
273 		} else {
274 			ERROR("%s %d\n", __func__, __LINE__);
275 			VERBOSE("%s userinputadvanced.atximpedance %u Ohms value is not valid.\n",
276 				__func__, drvstren_ohm);
277 			VERBOSE("Valid values are: 20, 24, 30, 40, 60 and 120 Ohms.\n");
278 		}
279 	}
280 
281 	return stren_setting;
282 }
283