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