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