1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2021 Rockchip Electronics Co., Ltd.
4 */
5
6 #include <common.h>
7 #include <dm.h>
8 #include <syscon.h>
9 #include <asm/io.h>
10 #include <dm/of_access.h>
11 #include <asm/arch/clock.h>
12 #include <asm/arch/rockchip_smccc.h>
13 #include <asm/arch/sdram.h>
14 #include <asm/arch/sdram_common.h>
15
16 #define DDR2_PARAMS_PHANDLE_NAME "ddr2_params"
17 #define DDR3_PARAMS_PHANDLE_NAME "ddr3_params"
18 #define DDR4_PARAMS_PHANDLE_NAME "ddr4_params"
19 #define LPDDR2_PARAMS_PHANDLE_NAME "lpddr2_params"
20 #define LPDDR3_PARAMS_PHANDLE_NAME "lpddr3_params"
21 #define LPDDR4_PARAMS_PHANDLE_NAME "lpddr4_params"
22 #define LPDDR4X_PARAMS_PHANDLE_NAME "lpddr4x_params"
23 #define LPDDR5_PARAMS_PHANDLE_NAME "lpddr5_params"
24
25 #define DTS_PAR_OFFSET (4096)
26 #define PARAMS_INVALID_VAL (0xff00aa99)
27 #define PARAMS_IGNORE_THIS (0)
28
29 #define PMUGRF_OS_REG(n) (0x200 + (n) * 4)
30
31 struct rk3326_ddr_de_skew_setting {
32 unsigned int ca_de_skew[30];
33 unsigned int cs0_de_skew[84];
34 unsigned int cs1_de_skew[84];
35 };
36
37 /* there is a matching relationship, modify it with caution */
38 static char *dmc_fsp_params[] = {
39 "debug_print_level",
40 "phy_de_skew_en",
41 /* if need, add parameter after */
42 };
43
44 /* there is a matching relationship, modify it with caution */
45 static char *ddr_params_v1[] = {
46 /* version information V1.00 */
47 "version",
48 "expanded_version",
49 "reserved",
50 /* freq info, freq_0 is final frequency, unit: MHz */
51 "freq_0",
52 "freq_1",
53 "freq_2",
54 "freq_3",
55 "freq_4",
56 "freq_5",
57 /* power save setting */
58 "pd_idle",
59 "sr_idle",
60 "sr_mc_gate_idle",
61 "srpd_lite_idle",
62 "standby_idle",
63 "pd_dis_freq",
64 "sr_dis_freq",
65 "dram_dll_dis_freq",
66 "phy_dll_dis_freq",
67 /* drv when odt on */
68 "phy_dq_drv_odten",
69 "phy_ca_drv_odten",
70 "phy_clk_drv_odten",
71 "dram_dq_drv_odten",
72 /* drv when odt off */
73 "phy_dq_drv_odtoff",
74 "phy_ca_drv_odtoff",
75 "phy_clk_drv_odtoff",
76 "dram_dq_drv_odtoff",
77 /* odt info */
78 "dram_odt",
79 "phy_odt",
80 "phy_odt_puup_en",
81 "phy_odt_pudn_en",
82 /* odt enable freq */
83 "dram_dq_odt_en_freq",
84 "phy_odt_en_freq",
85 /* slew rate when odt enable */
86 "phy_dq_sr_odten",
87 "phy_ca_sr_odten",
88 "phy_clk_sr_odten",
89 /* slew rate when odt disable */
90 "phy_dq_sr_odtoff",
91 "phy_ca_sr_odtoff",
92 "phy_clk_sr_odtoff",
93 /* ssmod setting*/
94 "ssmod_downspread",
95 "ssmod_div",
96 "ssmod_spread",
97 /* 2T mode */
98 "mode_2t",
99 /* speed bin */
100 "speed_bin",
101 /* dram extended temperature support */
102 "dram_ext_temp",
103 /* byte map */
104 "byte_map",
105 /* dq map */
106 "dq_map_cs0_dq_l",
107 "dq_map_cs0_dq_h",
108 "dq_map_cs1_dq_l",
109 "dq_map_cs1_dq_h",
110 /* for LPDDR4 and LPDDR4X */
111 /* odt info */
112 "lp4_ca_odt",
113 "lp4_drv_pu_cal_odten",
114 "lp4_drv_pu_cal_odtoff",
115 "phy_lp4_drv_pulldown_en_odten",
116 "phy_lp4_drv_pulldown_en_odtoff",
117 /* odt enable freq */
118 "lp4_ca_odt_en_freq",
119 /* lp4 cs drv info and ca odt info */
120 "phy_lp4_cs_drv_odten",
121 "phy_lp4_cs_drv_odtoff",
122 "lp4_odte_ck_en",
123 "lp4_odte_cs_en",
124 "lp4_odtd_ca_en",
125 /* lp4 vref info when odt enable */
126 "phy_lp4_dq_vref_odten",
127 "lp4_dq_vref_odten",
128 "lp4_ca_vref_odten",
129 /* lp4 vref info when odt disable */
130 "phy_lp4_dq_vref_odtoff",
131 "lp4_dq_vref_odtoff",
132 "lp4_ca_vref_odtoff",
133 /* if need, add parameter after and change the minor version. */
134 };
135
136 /* the expanded version V1.00 add skew info */
137 static char *ddr_params_exp_v1[] = {
138 "ddr3a1_ddr4a9_de-skew",
139 "ddr3a0_ddr4a10_de-skew",
140 "ddr3a3_ddr4a6_de-skew",
141 "ddr3a2_ddr4a4_de-skew",
142 "ddr3a5_ddr4a8_de-skew",
143 "ddr3a4_ddr4a5_de-skew",
144 "ddr3a7_ddr4a11_de-skew",
145 "ddr3a6_ddr4a7_de-skew",
146 "ddr3a9_ddr4a0_de-skew",
147 "ddr3a8_ddr4a13_de-skew",
148 "ddr3a11_ddr4a3_de-skew",
149 "ddr3a10_ddr4cs0_de-skew",
150 "ddr3a13_ddr4a2_de-skew",
151 "ddr3a12_ddr4ba1_de-skew",
152 "ddr3a15_ddr4odt0_de-skew",
153 "ddr3a14_ddr4a1_de-skew",
154 "ddr3ba1_ddr4a15_de-skew",
155 "ddr3ba0_ddr4bg0_de-skew",
156 "ddr3ras_ddr4cke_de-skew",
157 "ddr3ba2_ddr4ba0_de-skew",
158 "ddr3we_ddr4bg1_de-skew",
159 "ddr3cas_ddr4a12_de-skew",
160 "ddr3ckn_ddr4ckn_de-skew",
161 "ddr3ckp_ddr4ckp_de-skew",
162 "ddr3cke_ddr4a16_de-skew",
163 "ddr3odt0_ddr4a14_de-skew",
164 "ddr3cs0_ddr4act_de-skew",
165 "ddr3reset_ddr4reset_de-skew",
166 "ddr3cs1_ddr4cs1_de-skew",
167 "ddr3odt1_ddr4odt1_de-skew",
168
169 "cs0_dm0_rx_de-skew",
170 "cs0_dm0_tx_de-skew",
171 "cs0_dq0_rx_de-skew",
172 "cs0_dq0_tx_de-skew",
173 "cs0_dq1_rx_de-skew",
174 "cs0_dq1_tx_de-skew",
175 "cs0_dq2_rx_de-skew",
176 "cs0_dq2_tx_de-skew",
177 "cs0_dq3_rx_de-skew",
178 "cs0_dq3_tx_de-skew",
179 "cs0_dq4_rx_de-skew",
180 "cs0_dq4_tx_de-skew",
181 "cs0_dq5_rx_de-skew",
182 "cs0_dq5_tx_de-skew",
183 "cs0_dq6_rx_de-skew",
184 "cs0_dq6_tx_de-skew",
185 "cs0_dq7_rx_de-skew",
186 "cs0_dq7_tx_de-skew",
187 "cs0_dqs0_rx_de-skew",
188 "cs0_dqs0p_tx_de-skew",
189 "cs0_dqs0n_tx_de-skew",
190
191 "cs0_dm1_rx_de-skew",
192 "cs0_dm1_tx_de-skew",
193 "cs0_dq8_rx_de-skew",
194 "cs0_dq8_tx_de-skew",
195 "cs0_dq9_rx_de-skew",
196 "cs0_dq9_tx_de-skew",
197 "cs0_dq10_rx_de-skew",
198 "cs0_dq10_tx_de-skew",
199 "cs0_dq11_rx_de-skew",
200 "cs0_dq11_tx_de-skew",
201 "cs0_dq12_rx_de-skew",
202 "cs0_dq12_tx_de-skew",
203 "cs0_dq13_rx_de-skew",
204 "cs0_dq13_tx_de-skew",
205 "cs0_dq14_rx_de-skew",
206 "cs0_dq14_tx_de-skew",
207 "cs0_dq15_rx_de-skew",
208 "cs0_dq15_tx_de-skew",
209 "cs0_dqs1_rx_de-skew",
210 "cs0_dqs1p_tx_de-skew",
211 "cs0_dqs1n_tx_de-skew",
212
213 "cs0_dm2_rx_de-skew",
214 "cs0_dm2_tx_de-skew",
215 "cs0_dq16_rx_de-skew",
216 "cs0_dq16_tx_de-skew",
217 "cs0_dq17_rx_de-skew",
218 "cs0_dq17_tx_de-skew",
219 "cs0_dq18_rx_de-skew",
220 "cs0_dq18_tx_de-skew",
221 "cs0_dq19_rx_de-skew",
222 "cs0_dq19_tx_de-skew",
223 "cs0_dq20_rx_de-skew",
224 "cs0_dq20_tx_de-skew",
225 "cs0_dq21_rx_de-skew",
226 "cs0_dq21_tx_de-skew",
227 "cs0_dq22_rx_de-skew",
228 "cs0_dq22_tx_de-skew",
229 "cs0_dq23_rx_de-skew",
230 "cs0_dq23_tx_de-skew",
231 "cs0_dqs2_rx_de-skew",
232 "cs0_dqs2p_tx_de-skew",
233 "cs0_dqs2n_tx_de-skew",
234
235 "cs0_dm3_rx_de-skew",
236 "cs0_dm3_tx_de-skew",
237 "cs0_dq24_rx_de-skew",
238 "cs0_dq24_tx_de-skew",
239 "cs0_dq25_rx_de-skew",
240 "cs0_dq25_tx_de-skew",
241 "cs0_dq26_rx_de-skew",
242 "cs0_dq26_tx_de-skew",
243 "cs0_dq27_rx_de-skew",
244 "cs0_dq27_tx_de-skew",
245 "cs0_dq28_rx_de-skew",
246 "cs0_dq28_tx_de-skew",
247 "cs0_dq29_rx_de-skew",
248 "cs0_dq29_tx_de-skew",
249 "cs0_dq30_rx_de-skew",
250 "cs0_dq30_tx_de-skew",
251 "cs0_dq31_rx_de-skew",
252 "cs0_dq31_tx_de-skew",
253 "cs0_dqs3_rx_de-skew",
254 "cs0_dqs3p_tx_de-skew",
255 "cs0_dqs3n_tx_de-skew",
256
257 "cs1_dm0_rx_de-skew",
258 "cs1_dm0_tx_de-skew",
259 "cs1_dq0_rx_de-skew",
260 "cs1_dq0_tx_de-skew",
261 "cs1_dq1_rx_de-skew",
262 "cs1_dq1_tx_de-skew",
263 "cs1_dq2_rx_de-skew",
264 "cs1_dq2_tx_de-skew",
265 "cs1_dq3_rx_de-skew",
266 "cs1_dq3_tx_de-skew",
267 "cs1_dq4_rx_de-skew",
268 "cs1_dq4_tx_de-skew",
269 "cs1_dq5_rx_de-skew",
270 "cs1_dq5_tx_de-skew",
271 "cs1_dq6_rx_de-skew",
272 "cs1_dq6_tx_de-skew",
273 "cs1_dq7_rx_de-skew",
274 "cs1_dq7_tx_de-skew",
275 "cs1_dqs0_rx_de-skew",
276 "cs1_dqs0p_tx_de-skew",
277 "cs1_dqs0n_tx_de-skew",
278
279 "cs1_dm1_rx_de-skew",
280 "cs1_dm1_tx_de-skew",
281 "cs1_dq8_rx_de-skew",
282 "cs1_dq8_tx_de-skew",
283 "cs1_dq9_rx_de-skew",
284 "cs1_dq9_tx_de-skew",
285 "cs1_dq10_rx_de-skew",
286 "cs1_dq10_tx_de-skew",
287 "cs1_dq11_rx_de-skew",
288 "cs1_dq11_tx_de-skew",
289 "cs1_dq12_rx_de-skew",
290 "cs1_dq12_tx_de-skew",
291 "cs1_dq13_rx_de-skew",
292 "cs1_dq13_tx_de-skew",
293 "cs1_dq14_rx_de-skew",
294 "cs1_dq14_tx_de-skew",
295 "cs1_dq15_rx_de-skew",
296 "cs1_dq15_tx_de-skew",
297 "cs1_dqs1_rx_de-skew",
298 "cs1_dqs1p_tx_de-skew",
299 "cs1_dqs1n_tx_de-skew",
300
301 "cs1_dm2_rx_de-skew",
302 "cs1_dm2_tx_de-skew",
303 "cs1_dq16_rx_de-skew",
304 "cs1_dq16_tx_de-skew",
305 "cs1_dq17_rx_de-skew",
306 "cs1_dq17_tx_de-skew",
307 "cs1_dq18_rx_de-skew",
308 "cs1_dq18_tx_de-skew",
309 "cs1_dq19_rx_de-skew",
310 "cs1_dq19_tx_de-skew",
311 "cs1_dq20_rx_de-skew",
312 "cs1_dq20_tx_de-skew",
313 "cs1_dq21_rx_de-skew",
314 "cs1_dq21_tx_de-skew",
315 "cs1_dq22_rx_de-skew",
316 "cs1_dq22_tx_de-skew",
317 "cs1_dq23_rx_de-skew",
318 "cs1_dq23_tx_de-skew",
319 "cs1_dqs2_rx_de-skew",
320 "cs1_dqs2p_tx_de-skew",
321 "cs1_dqs2n_tx_de-skew",
322
323 "cs1_dm3_rx_de-skew",
324 "cs1_dm3_tx_de-skew",
325 "cs1_dq24_rx_de-skew",
326 "cs1_dq24_tx_de-skew",
327 "cs1_dq25_rx_de-skew",
328 "cs1_dq25_tx_de-skew",
329 "cs1_dq26_rx_de-skew",
330 "cs1_dq26_tx_de-skew",
331 "cs1_dq27_rx_de-skew",
332 "cs1_dq27_tx_de-skew",
333 "cs1_dq28_rx_de-skew",
334 "cs1_dq28_tx_de-skew",
335 "cs1_dq29_rx_de-skew",
336 "cs1_dq29_tx_de-skew",
337 "cs1_dq30_rx_de-skew",
338 "cs1_dq30_tx_de-skew",
339 "cs1_dq31_rx_de-skew",
340 "cs1_dq31_tx_de-skew",
341 "cs1_dqs3_rx_de-skew",
342 "cs1_dqs3p_tx_de-skew",
343 "cs1_dqs3n_tx_de-skew",
344 };
345
get_atf_version(void)346 static int get_atf_version(void)
347 {
348 struct arm_smccc_res res;
349
350 res = sip_smc_dram(0, 0, ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION);
351
352 if (res.a0)
353 return -ENOMEM;
354 else
355 return res.a1;
356 }
357
dmc_fsp_probe(struct udevice * dev)358 static int dmc_fsp_probe(struct udevice *dev)
359 {
360 struct device_node *np_params, *np_tim;
361 struct arm_smccc_res res;
362 void *pmugrf_base;
363 int *p = NULL;
364 char *phandle_name = NULL;
365 char **ddr_params;
366 char **ddr_params_exp;
367 int ddr_params_version;
368 int expanded_version;
369 u32 dram_type, os_reg2_val, os_reg3_val;
370 u32 phy_de_skew_en;
371 u32 i = 0, count = 0, size = 0, count_exp = 0;
372 ulong atf_version_limit;
373
374 atf_version_limit = dev_get_driver_data(dev);
375 if (get_atf_version() < atf_version_limit) {
376 printf("%s: trusted firmware need to update or is invalid!\n", __func__);
377 printf("%s: current ATF version 0x%x, required version 0x%lx\n",
378 __func__, get_atf_version(), atf_version_limit);
379 return 0;
380 }
381
382 pmugrf_base = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
383 os_reg2_val = readl(pmugrf_base + PMUGRF_OS_REG(2));
384 os_reg3_val = readl(pmugrf_base + PMUGRF_OS_REG(3));
385 dram_type = SYS_REG_DEC_DDRTYPE_V3(os_reg2_val, os_reg3_val);
386
387 if (dram_type == DDR2)
388 phandle_name = DDR2_PARAMS_PHANDLE_NAME;
389 else if (dram_type == DDR3)
390 phandle_name = DDR3_PARAMS_PHANDLE_NAME;
391 else if (dram_type == DDR4)
392 phandle_name = DDR4_PARAMS_PHANDLE_NAME;
393 else if (dram_type == LPDDR2)
394 phandle_name = LPDDR2_PARAMS_PHANDLE_NAME;
395 else if (dram_type == LPDDR3)
396 phandle_name = LPDDR3_PARAMS_PHANDLE_NAME;
397 else if (dram_type == LPDDR4)
398 phandle_name = LPDDR4_PARAMS_PHANDLE_NAME;
399 else if (dram_type == LPDDR4X)
400 phandle_name = LPDDR4X_PARAMS_PHANDLE_NAME;
401 else if (dram_type == LPDDR5)
402 phandle_name = LPDDR5_PARAMS_PHANDLE_NAME;
403 else
404 printf("%s: dram_type unsupported\n", __func__);
405
406 np_params = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)), phandle_name, 0);
407 if (!np_params) {
408 printf("%s: of_parse_phandle %s error!\n", __func__, phandle_name);
409 return -EINVAL;
410 }
411
412 ddr_params_version = ofnode_read_u32_default(np_to_ofnode(np_params), "version", -1);
413 if (ddr_params_version < 0) {
414 printf("%s: get ddr_params_version error\n", __func__);
415 return -EINVAL;
416 }
417
418 if ((ddr_params_version & 0xff00) == 0x100 &&
419 (ddr_params_version & 0xffff) <= 0x101) {
420 count = ARRAY_SIZE(ddr_params_v1);
421 ddr_params = ddr_params_v1;
422 } else {
423 printf("%s: ddr_params_version=0x%x unsupported\n", __func__, ddr_params_version);
424 return -EINVAL;
425 }
426
427 expanded_version = ofnode_read_u32_default(np_to_ofnode(np_params),
428 "expanded_version", 0);
429 if (expanded_version != PARAMS_IGNORE_THIS) {
430 if ((expanded_version & 0xff00) == 0x100 &&
431 (expanded_version & 0xffff) <= 0x100) {
432 count_exp = ARRAY_SIZE(ddr_params_exp_v1);
433 ddr_params_exp = ddr_params_exp_v1;
434 } else {
435 printf("expanded_version=0x%x unsupported\n",
436 expanded_version);
437 return -1;
438 }
439 } else if ((ddr_params_version & 0xffff) == 0x101) {
440 count_exp = ARRAY_SIZE(ddr_params_exp_v1);
441 }
442 /*
443 * page 0 is used for share param
444 * page 1~N is used for dmc_fsp and ddr_params_exp param
445 */
446 size = ((count + count_exp) * 4 + 4096);
447 res = sip_smc_request_share_mem(DIV_ROUND_UP(size, 4096) + 1, SHARE_PAGE_TYPE_DDRFSP);
448 if (res.a0 != 0) {
449 printf("%s:no share memory for init\n", __func__);
450 return -ENOMEM;
451 }
452
453 /* fill share memory and pass to the atf */
454 p = (int *)(res.a1);
455 for (i = 0; i < ARRAY_SIZE(dmc_fsp_params); i++)
456 p[i] = dev_read_u32_default(dev, dmc_fsp_params[i], PARAMS_INVALID_VAL);
457
458 phy_de_skew_en = p[1];
459
460 p = (int *)(res.a1 + DTS_PAR_OFFSET / 4);
461 for (i = 0; i < ARRAY_SIZE(ddr_params_v1); i++) {
462 p[i] = ofnode_read_u32_default(np_to_ofnode(np_params), ddr_params[i],
463 PARAMS_INVALID_VAL);
464 }
465
466 if (expanded_version != PARAMS_IGNORE_THIS) {
467 if ((expanded_version & 0xff00) == 0x100 &&
468 (expanded_version & 0xffff) <= 0x100) {
469 phandle_name = "ddr_timing";
470 np_tim =
471 of_parse_phandle(ofnode_to_np(dev_ofnode(dev)),
472 phandle_name, 0);
473 if (!np_tim) {
474 printf("%s: of_parse_phandle %s error!\n",
475 __func__, phandle_name);
476 return -EINVAL;
477 }
478 for (i = count; i < (count + count_exp); i++) {
479 p[i] =
480 ofnode_read_u32_default(np_to_ofnode(np_tim),
481 ddr_params_exp[i -
482 count],
483 PARAMS_INVALID_VAL);
484 }
485 /* expanded_version and start point */
486 p[1] = (p[1] & 0xffff) | (count << 16);
487 }
488 } else if (phy_de_skew_en && (phy_de_skew_en != PARAMS_INVALID_VAL)) {
489 phandle_name = "ddr_timing";
490 np_tim = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)), phandle_name, 0);
491 if (!np_tim) {
492 printf("%s: of_parse_phandle %s error!\n", __func__, phandle_name);
493 return -EINVAL;
494 }
495 for (i = count;
496 i < (count + ARRAY_SIZE(ddr_params_exp_v1)); i++) {
497 p[i] =
498 ofnode_read_u32_default(np_to_ofnode(np_tim),
499 ddr_params_exp_v1[i - count],
500 PARAMS_INVALID_VAL);
501 }
502 }
503
504 flush_cache((unsigned long)(res.a1), (DIV_ROUND_UP(size, 4096) + 1) * 0x1000);
505 res = sip_smc_dram(SHARE_PAGE_TYPE_DDRFSP, 0, ROCKCHIP_SIP_CONFIG_DRAM_FSP_INIT);
506 if (res.a0) {
507 printf("%s: rockchip_sip_config_dram_fsp_init error:%lx\n", __func__, res.a0);
508 return -ENOMEM;
509 }
510
511 return 0;
512 }
513
514 static const struct udevice_id rockchip_dmc_fsp_ids[] = {
515 { .compatible = "rockchip,rk3568-dmc-fsp", .data = 0x102},
516 { .compatible = "rockchip,px30s-dmc-fsp", .data = 0x106},
517 { }
518 };
519
520 U_BOOT_DRIVER(dmc_fsp) = {
521 .name = "rockchip_dmc_fsp",
522 .id = UCLASS_DMC,
523 .probe = dmc_fsp_probe,
524 .of_match = rockchip_dmc_fsp_ids,
525 };
526