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