xref: /rk3399_rockchip-uboot/drivers/ram/rockchip/rockchip_dmc.c (revision 16a92a426ee3d8bcd4aba3ee039c6e94031d7fbd)
1*16a92a42STang Yun ping // SPDX-License-Identifier: GPL-2.0
2*16a92a42STang Yun ping /*
3*16a92a42STang Yun ping  * (C) Copyright 2018 Rockchip Electronics Co., Ltd
4*16a92a42STang Yun ping  */
5*16a92a42STang Yun ping #include <asm/arch/rockchip_smccc.h>
6*16a92a42STang Yun ping #include <asm/arch/rockchip_dmc.h>
7*16a92a42STang Yun ping #include <asm/io.h>
8*16a92a42STang Yun ping #include <asm/psci.h>
9*16a92a42STang Yun ping #include <common.h>
10*16a92a42STang Yun ping #include <clk.h>
11*16a92a42STang Yun ping #include <dm.h>
12*16a92a42STang Yun ping #include <dm/of_access.h>
13*16a92a42STang Yun ping #include <dt-structs.h>
14*16a92a42STang Yun ping #include <linux/arm-smccc.h>
15*16a92a42STang Yun ping #include <linux/err.h>
16*16a92a42STang Yun ping #include <linux/errno.h>
17*16a92a42STang Yun ping #include <ram.h>
18*16a92a42STang Yun ping #include <regmap.h>
19*16a92a42STang Yun ping 
20*16a92a42STang Yun ping #define DTS_PAR_OFFSET		(4096)
21*16a92a42STang Yun ping 
22*16a92a42STang Yun ping struct share_params {
23*16a92a42STang Yun ping 	u32 hz;
24*16a92a42STang Yun ping 	u32 lcdc_type;
25*16a92a42STang Yun ping 	u32 vop;
26*16a92a42STang Yun ping 	u32 vop_dclk_mode;
27*16a92a42STang Yun ping 	u32 sr_idle_en;
28*16a92a42STang Yun ping 	u32 addr_mcu_el3;
29*16a92a42STang Yun ping 	/*
30*16a92a42STang Yun ping 	 * 1: need to wait flag1
31*16a92a42STang Yun ping 	 * 0: never wait flag1
32*16a92a42STang Yun ping 	 */
33*16a92a42STang Yun ping 	u32 wait_flag1;
34*16a92a42STang Yun ping 	/*
35*16a92a42STang Yun ping 	 * 1: need to wait flag1
36*16a92a42STang Yun ping 	 * 0: never wait flag1
37*16a92a42STang Yun ping 	 */
38*16a92a42STang Yun ping 	u32 wait_flag0;
39*16a92a42STang Yun ping 	u32 complt_hwirq;
40*16a92a42STang Yun ping 	/* if need, add parameter after */
41*16a92a42STang Yun ping };
42*16a92a42STang Yun ping 
43*16a92a42STang Yun ping static struct share_params *ddr_psci_param;
44*16a92a42STang Yun ping 
45*16a92a42STang Yun ping /* hope this define can adapt all future platfor */
46*16a92a42STang Yun ping static const char * const rk3328_dts_timing[] = {
47*16a92a42STang Yun ping 	"ddr3_speed_bin",
48*16a92a42STang Yun ping 	"ddr4_speed_bin",
49*16a92a42STang Yun ping 	"pd_idle",
50*16a92a42STang Yun ping 	"sr_idle",
51*16a92a42STang Yun ping 	"sr_mc_gate_idle",
52*16a92a42STang Yun ping 	"srpd_lite_idle",
53*16a92a42STang Yun ping 	"standby_idle",
54*16a92a42STang Yun ping 
55*16a92a42STang Yun ping 	"auto_pd_dis_freq",
56*16a92a42STang Yun ping 	"auto_sr_dis_freq",
57*16a92a42STang Yun ping 	"ddr3_dll_dis_freq",
58*16a92a42STang Yun ping 	"ddr4_dll_dis_freq",
59*16a92a42STang Yun ping 	"phy_dll_dis_freq",
60*16a92a42STang Yun ping 
61*16a92a42STang Yun ping 	"ddr3_odt_dis_freq",
62*16a92a42STang Yun ping 	"phy_ddr3_odt_dis_freq",
63*16a92a42STang Yun ping 	"ddr3_drv",
64*16a92a42STang Yun ping 	"ddr3_odt",
65*16a92a42STang Yun ping 	"phy_ddr3_ca_drv",
66*16a92a42STang Yun ping 	"phy_ddr3_ck_drv",
67*16a92a42STang Yun ping 	"phy_ddr3_dq_drv",
68*16a92a42STang Yun ping 	"phy_ddr3_odt",
69*16a92a42STang Yun ping 
70*16a92a42STang Yun ping 	"lpddr3_odt_dis_freq",
71*16a92a42STang Yun ping 	"phy_lpddr3_odt_dis_freq",
72*16a92a42STang Yun ping 	"lpddr3_drv",
73*16a92a42STang Yun ping 	"lpddr3_odt",
74*16a92a42STang Yun ping 	"phy_lpddr3_ca_drv",
75*16a92a42STang Yun ping 	"phy_lpddr3_ck_drv",
76*16a92a42STang Yun ping 	"phy_lpddr3_dq_drv",
77*16a92a42STang Yun ping 	"phy_lpddr3_odt",
78*16a92a42STang Yun ping 
79*16a92a42STang Yun ping 	"lpddr4_odt_dis_freq",
80*16a92a42STang Yun ping 	"phy_lpddr4_odt_dis_freq",
81*16a92a42STang Yun ping 	"lpddr4_drv",
82*16a92a42STang Yun ping 	"lpddr4_dq_odt",
83*16a92a42STang Yun ping 	"lpddr4_ca_odt",
84*16a92a42STang Yun ping 	"phy_lpddr4_ca_drv",
85*16a92a42STang Yun ping 	"phy_lpddr4_ck_cs_drv",
86*16a92a42STang Yun ping 	"phy_lpddr4_dq_drv",
87*16a92a42STang Yun ping 	"phy_lpddr4_odt",
88*16a92a42STang Yun ping 
89*16a92a42STang Yun ping 	"ddr4_odt_dis_freq",
90*16a92a42STang Yun ping 	"phy_ddr4_odt_dis_freq",
91*16a92a42STang Yun ping 	"ddr4_drv",
92*16a92a42STang Yun ping 	"ddr4_odt",
93*16a92a42STang Yun ping 	"phy_ddr4_ca_drv",
94*16a92a42STang Yun ping 	"phy_ddr4_ck_drv",
95*16a92a42STang Yun ping 	"phy_ddr4_dq_drv",
96*16a92a42STang Yun ping 	"phy_ddr4_odt",
97*16a92a42STang Yun ping };
98*16a92a42STang Yun ping 
99*16a92a42STang Yun ping static const char * const px30_dts_timing[] = {
100*16a92a42STang Yun ping 	"ddr2_speed_bin",
101*16a92a42STang Yun ping 	"ddr3_speed_bin",
102*16a92a42STang Yun ping 	"ddr4_speed_bin",
103*16a92a42STang Yun ping 	"pd_idle",
104*16a92a42STang Yun ping 	"sr_idle",
105*16a92a42STang Yun ping 	"sr_mc_gate_idle",
106*16a92a42STang Yun ping 	"srpd_lite_idle",
107*16a92a42STang Yun ping 	"standby_idle",
108*16a92a42STang Yun ping 
109*16a92a42STang Yun ping 	"auto_pd_dis_freq",
110*16a92a42STang Yun ping 	"auto_sr_dis_freq",
111*16a92a42STang Yun ping 	"ddr2_dll_dis_freq",
112*16a92a42STang Yun ping 	"ddr3_dll_dis_freq",
113*16a92a42STang Yun ping 	"ddr4_dll_dis_freq",
114*16a92a42STang Yun ping 	"phy_dll_dis_freq",
115*16a92a42STang Yun ping 
116*16a92a42STang Yun ping 	"ddr2_odt_dis_freq",
117*16a92a42STang Yun ping 	"phy_ddr2_odt_dis_freq",
118*16a92a42STang Yun ping 	"ddr2_drv",
119*16a92a42STang Yun ping 	"ddr2_odt",
120*16a92a42STang Yun ping 	"phy_ddr2_ca_drv",
121*16a92a42STang Yun ping 	"phy_ddr2_ck_drv",
122*16a92a42STang Yun ping 	"phy_ddr2_dq_drv",
123*16a92a42STang Yun ping 	"phy_ddr2_odt",
124*16a92a42STang Yun ping 
125*16a92a42STang Yun ping 	"ddr3_odt_dis_freq",
126*16a92a42STang Yun ping 	"phy_ddr3_odt_dis_freq",
127*16a92a42STang Yun ping 	"ddr3_drv",
128*16a92a42STang Yun ping 	"ddr3_odt",
129*16a92a42STang Yun ping 	"phy_ddr3_ca_drv",
130*16a92a42STang Yun ping 	"phy_ddr3_ck_drv",
131*16a92a42STang Yun ping 	"phy_ddr3_dq_drv",
132*16a92a42STang Yun ping 	"phy_ddr3_odt",
133*16a92a42STang Yun ping 
134*16a92a42STang Yun ping 	"phy_lpddr2_odt_dis_freq",
135*16a92a42STang Yun ping 	"lpddr2_drv",
136*16a92a42STang Yun ping 	"phy_lpddr2_ca_drv",
137*16a92a42STang Yun ping 	"phy_lpddr2_ck_drv",
138*16a92a42STang Yun ping 	"phy_lpddr2_dq_drv",
139*16a92a42STang Yun ping 	"phy_lpddr2_odt",
140*16a92a42STang Yun ping 
141*16a92a42STang Yun ping 	"lpddr3_odt_dis_freq",
142*16a92a42STang Yun ping 	"phy_lpddr3_odt_dis_freq",
143*16a92a42STang Yun ping 	"lpddr3_drv",
144*16a92a42STang Yun ping 	"lpddr3_odt",
145*16a92a42STang Yun ping 	"phy_lpddr3_ca_drv",
146*16a92a42STang Yun ping 	"phy_lpddr3_ck_drv",
147*16a92a42STang Yun ping 	"phy_lpddr3_dq_drv",
148*16a92a42STang Yun ping 	"phy_lpddr3_odt",
149*16a92a42STang Yun ping 
150*16a92a42STang Yun ping 	"lpddr4_odt_dis_freq",
151*16a92a42STang Yun ping 	"phy_lpddr4_odt_dis_freq",
152*16a92a42STang Yun ping 	"lpddr4_drv",
153*16a92a42STang Yun ping 	"lpddr4_dq_odt",
154*16a92a42STang Yun ping 	"lpddr4_ca_odt",
155*16a92a42STang Yun ping 	"phy_lpddr4_ca_drv",
156*16a92a42STang Yun ping 	"phy_lpddr4_ck_cs_drv",
157*16a92a42STang Yun ping 	"phy_lpddr4_dq_drv",
158*16a92a42STang Yun ping 	"phy_lpddr4_odt",
159*16a92a42STang Yun ping 
160*16a92a42STang Yun ping 	"ddr4_odt_dis_freq",
161*16a92a42STang Yun ping 	"phy_ddr4_odt_dis_freq",
162*16a92a42STang Yun ping 	"ddr4_drv",
163*16a92a42STang Yun ping 	"ddr4_odt",
164*16a92a42STang Yun ping 	"phy_ddr4_ca_drv",
165*16a92a42STang Yun ping 	"phy_ddr4_ck_drv",
166*16a92a42STang Yun ping 	"phy_ddr4_dq_drv",
167*16a92a42STang Yun ping 	"phy_ddr4_odt",
168*16a92a42STang Yun ping };
169*16a92a42STang Yun ping 
170*16a92a42STang Yun ping static const char * const rk3328_dts_ca_timing[] = {
171*16a92a42STang Yun ping 	"ddr3a1_ddr4a9_de-skew",
172*16a92a42STang Yun ping 	"ddr3a0_ddr4a10_de-skew",
173*16a92a42STang Yun ping 	"ddr3a3_ddr4a6_de-skew",
174*16a92a42STang Yun ping 	"ddr3a2_ddr4a4_de-skew",
175*16a92a42STang Yun ping 	"ddr3a5_ddr4a8_de-skew",
176*16a92a42STang Yun ping 	"ddr3a4_ddr4a5_de-skew",
177*16a92a42STang Yun ping 	"ddr3a7_ddr4a11_de-skew",
178*16a92a42STang Yun ping 	"ddr3a6_ddr4a7_de-skew",
179*16a92a42STang Yun ping 	"ddr3a9_ddr4a0_de-skew",
180*16a92a42STang Yun ping 	"ddr3a8_ddr4a13_de-skew",
181*16a92a42STang Yun ping 	"ddr3a11_ddr4a3_de-skew",
182*16a92a42STang Yun ping 	"ddr3a10_ddr4cs0_de-skew",
183*16a92a42STang Yun ping 	"ddr3a13_ddr4a2_de-skew",
184*16a92a42STang Yun ping 	"ddr3a12_ddr4ba1_de-skew",
185*16a92a42STang Yun ping 	"ddr3a15_ddr4odt0_de-skew",
186*16a92a42STang Yun ping 	"ddr3a14_ddr4a1_de-skew",
187*16a92a42STang Yun ping 	"ddr3ba1_ddr4a15_de-skew",
188*16a92a42STang Yun ping 	"ddr3ba0_ddr4bg0_de-skew",
189*16a92a42STang Yun ping 	"ddr3ras_ddr4cke_de-skew",
190*16a92a42STang Yun ping 	"ddr3ba2_ddr4ba0_de-skew",
191*16a92a42STang Yun ping 	"ddr3we_ddr4bg1_de-skew",
192*16a92a42STang Yun ping 	"ddr3cas_ddr4a12_de-skew",
193*16a92a42STang Yun ping 	"ddr3ckn_ddr4ckn_de-skew",
194*16a92a42STang Yun ping 	"ddr3ckp_ddr4ckp_de-skew",
195*16a92a42STang Yun ping 	"ddr3cke_ddr4a16_de-skew",
196*16a92a42STang Yun ping 	"ddr3odt0_ddr4a14_de-skew",
197*16a92a42STang Yun ping 	"ddr3cs0_ddr4act_de-skew",
198*16a92a42STang Yun ping 	"ddr3reset_ddr4reset_de-skew",
199*16a92a42STang Yun ping 	"ddr3cs1_ddr4cs1_de-skew",
200*16a92a42STang Yun ping 	"ddr3odt1_ddr4odt1_de-skew",
201*16a92a42STang Yun ping };
202*16a92a42STang Yun ping 
203*16a92a42STang Yun ping static const char * const rk3328_dts_cs0_timing[] = {
204*16a92a42STang Yun ping 	"cs0_dm0_rx_de-skew",
205*16a92a42STang Yun ping 	"cs0_dm0_tx_de-skew",
206*16a92a42STang Yun ping 	"cs0_dq0_rx_de-skew",
207*16a92a42STang Yun ping 	"cs0_dq0_tx_de-skew",
208*16a92a42STang Yun ping 	"cs0_dq1_rx_de-skew",
209*16a92a42STang Yun ping 	"cs0_dq1_tx_de-skew",
210*16a92a42STang Yun ping 	"cs0_dq2_rx_de-skew",
211*16a92a42STang Yun ping 	"cs0_dq2_tx_de-skew",
212*16a92a42STang Yun ping 	"cs0_dq3_rx_de-skew",
213*16a92a42STang Yun ping 	"cs0_dq3_tx_de-skew",
214*16a92a42STang Yun ping 	"cs0_dq4_rx_de-skew",
215*16a92a42STang Yun ping 	"cs0_dq4_tx_de-skew",
216*16a92a42STang Yun ping 	"cs0_dq5_rx_de-skew",
217*16a92a42STang Yun ping 	"cs0_dq5_tx_de-skew",
218*16a92a42STang Yun ping 	"cs0_dq6_rx_de-skew",
219*16a92a42STang Yun ping 	"cs0_dq6_tx_de-skew",
220*16a92a42STang Yun ping 	"cs0_dq7_rx_de-skew",
221*16a92a42STang Yun ping 	"cs0_dq7_tx_de-skew",
222*16a92a42STang Yun ping 	"cs0_dqs0_rx_de-skew",
223*16a92a42STang Yun ping 	"cs0_dqs0p_tx_de-skew",
224*16a92a42STang Yun ping 	"cs0_dqs0n_tx_de-skew",
225*16a92a42STang Yun ping 
226*16a92a42STang Yun ping 	"cs0_dm1_rx_de-skew",
227*16a92a42STang Yun ping 	"cs0_dm1_tx_de-skew",
228*16a92a42STang Yun ping 	"cs0_dq8_rx_de-skew",
229*16a92a42STang Yun ping 	"cs0_dq8_tx_de-skew",
230*16a92a42STang Yun ping 	"cs0_dq9_rx_de-skew",
231*16a92a42STang Yun ping 	"cs0_dq9_tx_de-skew",
232*16a92a42STang Yun ping 	"cs0_dq10_rx_de-skew",
233*16a92a42STang Yun ping 	"cs0_dq10_tx_de-skew",
234*16a92a42STang Yun ping 	"cs0_dq11_rx_de-skew",
235*16a92a42STang Yun ping 	"cs0_dq11_tx_de-skew",
236*16a92a42STang Yun ping 	"cs0_dq12_rx_de-skew",
237*16a92a42STang Yun ping 	"cs0_dq12_tx_de-skew",
238*16a92a42STang Yun ping 	"cs0_dq13_rx_de-skew",
239*16a92a42STang Yun ping 	"cs0_dq13_tx_de-skew",
240*16a92a42STang Yun ping 	"cs0_dq14_rx_de-skew",
241*16a92a42STang Yun ping 	"cs0_dq14_tx_de-skew",
242*16a92a42STang Yun ping 	"cs0_dq15_rx_de-skew",
243*16a92a42STang Yun ping 	"cs0_dq15_tx_de-skew",
244*16a92a42STang Yun ping 	"cs0_dqs1_rx_de-skew",
245*16a92a42STang Yun ping 	"cs0_dqs1p_tx_de-skew",
246*16a92a42STang Yun ping 	"cs0_dqs1n_tx_de-skew",
247*16a92a42STang Yun ping 
248*16a92a42STang Yun ping 	"cs0_dm2_rx_de-skew",
249*16a92a42STang Yun ping 	"cs0_dm2_tx_de-skew",
250*16a92a42STang Yun ping 	"cs0_dq16_rx_de-skew",
251*16a92a42STang Yun ping 	"cs0_dq16_tx_de-skew",
252*16a92a42STang Yun ping 	"cs0_dq17_rx_de-skew",
253*16a92a42STang Yun ping 	"cs0_dq17_tx_de-skew",
254*16a92a42STang Yun ping 	"cs0_dq18_rx_de-skew",
255*16a92a42STang Yun ping 	"cs0_dq18_tx_de-skew",
256*16a92a42STang Yun ping 	"cs0_dq19_rx_de-skew",
257*16a92a42STang Yun ping 	"cs0_dq19_tx_de-skew",
258*16a92a42STang Yun ping 	"cs0_dq20_rx_de-skew",
259*16a92a42STang Yun ping 	"cs0_dq20_tx_de-skew",
260*16a92a42STang Yun ping 	"cs0_dq21_rx_de-skew",
261*16a92a42STang Yun ping 	"cs0_dq21_tx_de-skew",
262*16a92a42STang Yun ping 	"cs0_dq22_rx_de-skew",
263*16a92a42STang Yun ping 	"cs0_dq22_tx_de-skew",
264*16a92a42STang Yun ping 	"cs0_dq23_rx_de-skew",
265*16a92a42STang Yun ping 	"cs0_dq23_tx_de-skew",
266*16a92a42STang Yun ping 	"cs0_dqs2_rx_de-skew",
267*16a92a42STang Yun ping 	"cs0_dqs2p_tx_de-skew",
268*16a92a42STang Yun ping 	"cs0_dqs2n_tx_de-skew",
269*16a92a42STang Yun ping 
270*16a92a42STang Yun ping 	"cs0_dm3_rx_de-skew",
271*16a92a42STang Yun ping 	"cs0_dm3_tx_de-skew",
272*16a92a42STang Yun ping 	"cs0_dq24_rx_de-skew",
273*16a92a42STang Yun ping 	"cs0_dq24_tx_de-skew",
274*16a92a42STang Yun ping 	"cs0_dq25_rx_de-skew",
275*16a92a42STang Yun ping 	"cs0_dq25_tx_de-skew",
276*16a92a42STang Yun ping 	"cs0_dq26_rx_de-skew",
277*16a92a42STang Yun ping 	"cs0_dq26_tx_de-skew",
278*16a92a42STang Yun ping 	"cs0_dq27_rx_de-skew",
279*16a92a42STang Yun ping 	"cs0_dq27_tx_de-skew",
280*16a92a42STang Yun ping 	"cs0_dq28_rx_de-skew",
281*16a92a42STang Yun ping 	"cs0_dq28_tx_de-skew",
282*16a92a42STang Yun ping 	"cs0_dq29_rx_de-skew",
283*16a92a42STang Yun ping 	"cs0_dq29_tx_de-skew",
284*16a92a42STang Yun ping 	"cs0_dq30_rx_de-skew",
285*16a92a42STang Yun ping 	"cs0_dq30_tx_de-skew",
286*16a92a42STang Yun ping 	"cs0_dq31_rx_de-skew",
287*16a92a42STang Yun ping 	"cs0_dq31_tx_de-skew",
288*16a92a42STang Yun ping 	"cs0_dqs3_rx_de-skew",
289*16a92a42STang Yun ping 	"cs0_dqs3p_tx_de-skew",
290*16a92a42STang Yun ping 	"cs0_dqs3n_tx_de-skew",
291*16a92a42STang Yun ping };
292*16a92a42STang Yun ping 
293*16a92a42STang Yun ping static const char * const rk3328_dts_cs1_timing[] = {
294*16a92a42STang Yun ping 	"cs1_dm0_rx_de-skew",
295*16a92a42STang Yun ping 	"cs1_dm0_tx_de-skew",
296*16a92a42STang Yun ping 	"cs1_dq0_rx_de-skew",
297*16a92a42STang Yun ping 	"cs1_dq0_tx_de-skew",
298*16a92a42STang Yun ping 	"cs1_dq1_rx_de-skew",
299*16a92a42STang Yun ping 	"cs1_dq1_tx_de-skew",
300*16a92a42STang Yun ping 	"cs1_dq2_rx_de-skew",
301*16a92a42STang Yun ping 	"cs1_dq2_tx_de-skew",
302*16a92a42STang Yun ping 	"cs1_dq3_rx_de-skew",
303*16a92a42STang Yun ping 	"cs1_dq3_tx_de-skew",
304*16a92a42STang Yun ping 	"cs1_dq4_rx_de-skew",
305*16a92a42STang Yun ping 	"cs1_dq4_tx_de-skew",
306*16a92a42STang Yun ping 	"cs1_dq5_rx_de-skew",
307*16a92a42STang Yun ping 	"cs1_dq5_tx_de-skew",
308*16a92a42STang Yun ping 	"cs1_dq6_rx_de-skew",
309*16a92a42STang Yun ping 	"cs1_dq6_tx_de-skew",
310*16a92a42STang Yun ping 	"cs1_dq7_rx_de-skew",
311*16a92a42STang Yun ping 	"cs1_dq7_tx_de-skew",
312*16a92a42STang Yun ping 	"cs1_dqs0_rx_de-skew",
313*16a92a42STang Yun ping 	"cs1_dqs0p_tx_de-skew",
314*16a92a42STang Yun ping 	"cs1_dqs0n_tx_de-skew",
315*16a92a42STang Yun ping 
316*16a92a42STang Yun ping 	"cs1_dm1_rx_de-skew",
317*16a92a42STang Yun ping 	"cs1_dm1_tx_de-skew",
318*16a92a42STang Yun ping 	"cs1_dq8_rx_de-skew",
319*16a92a42STang Yun ping 	"cs1_dq8_tx_de-skew",
320*16a92a42STang Yun ping 	"cs1_dq9_rx_de-skew",
321*16a92a42STang Yun ping 	"cs1_dq9_tx_de-skew",
322*16a92a42STang Yun ping 	"cs1_dq10_rx_de-skew",
323*16a92a42STang Yun ping 	"cs1_dq10_tx_de-skew",
324*16a92a42STang Yun ping 	"cs1_dq11_rx_de-skew",
325*16a92a42STang Yun ping 	"cs1_dq11_tx_de-skew",
326*16a92a42STang Yun ping 	"cs1_dq12_rx_de-skew",
327*16a92a42STang Yun ping 	"cs1_dq12_tx_de-skew",
328*16a92a42STang Yun ping 	"cs1_dq13_rx_de-skew",
329*16a92a42STang Yun ping 	"cs1_dq13_tx_de-skew",
330*16a92a42STang Yun ping 	"cs1_dq14_rx_de-skew",
331*16a92a42STang Yun ping 	"cs1_dq14_tx_de-skew",
332*16a92a42STang Yun ping 	"cs1_dq15_rx_de-skew",
333*16a92a42STang Yun ping 	"cs1_dq15_tx_de-skew",
334*16a92a42STang Yun ping 	"cs1_dqs1_rx_de-skew",
335*16a92a42STang Yun ping 	"cs1_dqs1p_tx_de-skew",
336*16a92a42STang Yun ping 	"cs1_dqs1n_tx_de-skew",
337*16a92a42STang Yun ping 
338*16a92a42STang Yun ping 	"cs1_dm2_rx_de-skew",
339*16a92a42STang Yun ping 	"cs1_dm2_tx_de-skew",
340*16a92a42STang Yun ping 	"cs1_dq16_rx_de-skew",
341*16a92a42STang Yun ping 	"cs1_dq16_tx_de-skew",
342*16a92a42STang Yun ping 	"cs1_dq17_rx_de-skew",
343*16a92a42STang Yun ping 	"cs1_dq17_tx_de-skew",
344*16a92a42STang Yun ping 	"cs1_dq18_rx_de-skew",
345*16a92a42STang Yun ping 	"cs1_dq18_tx_de-skew",
346*16a92a42STang Yun ping 	"cs1_dq19_rx_de-skew",
347*16a92a42STang Yun ping 	"cs1_dq19_tx_de-skew",
348*16a92a42STang Yun ping 	"cs1_dq20_rx_de-skew",
349*16a92a42STang Yun ping 	"cs1_dq20_tx_de-skew",
350*16a92a42STang Yun ping 	"cs1_dq21_rx_de-skew",
351*16a92a42STang Yun ping 	"cs1_dq21_tx_de-skew",
352*16a92a42STang Yun ping 	"cs1_dq22_rx_de-skew",
353*16a92a42STang Yun ping 	"cs1_dq22_tx_de-skew",
354*16a92a42STang Yun ping 	"cs1_dq23_rx_de-skew",
355*16a92a42STang Yun ping 	"cs1_dq23_tx_de-skew",
356*16a92a42STang Yun ping 	"cs1_dqs2_rx_de-skew",
357*16a92a42STang Yun ping 	"cs1_dqs2p_tx_de-skew",
358*16a92a42STang Yun ping 	"cs1_dqs2n_tx_de-skew",
359*16a92a42STang Yun ping 
360*16a92a42STang Yun ping 	"cs1_dm3_rx_de-skew",
361*16a92a42STang Yun ping 	"cs1_dm3_tx_de-skew",
362*16a92a42STang Yun ping 	"cs1_dq24_rx_de-skew",
363*16a92a42STang Yun ping 	"cs1_dq24_tx_de-skew",
364*16a92a42STang Yun ping 	"cs1_dq25_rx_de-skew",
365*16a92a42STang Yun ping 	"cs1_dq25_tx_de-skew",
366*16a92a42STang Yun ping 	"cs1_dq26_rx_de-skew",
367*16a92a42STang Yun ping 	"cs1_dq26_tx_de-skew",
368*16a92a42STang Yun ping 	"cs1_dq27_rx_de-skew",
369*16a92a42STang Yun ping 	"cs1_dq27_tx_de-skew",
370*16a92a42STang Yun ping 	"cs1_dq28_rx_de-skew",
371*16a92a42STang Yun ping 	"cs1_dq28_tx_de-skew",
372*16a92a42STang Yun ping 	"cs1_dq29_rx_de-skew",
373*16a92a42STang Yun ping 	"cs1_dq29_tx_de-skew",
374*16a92a42STang Yun ping 	"cs1_dq30_rx_de-skew",
375*16a92a42STang Yun ping 	"cs1_dq30_tx_de-skew",
376*16a92a42STang Yun ping 	"cs1_dq31_rx_de-skew",
377*16a92a42STang Yun ping 	"cs1_dq31_tx_de-skew",
378*16a92a42STang Yun ping 	"cs1_dqs3_rx_de-skew",
379*16a92a42STang Yun ping 	"cs1_dqs3p_tx_de-skew",
380*16a92a42STang Yun ping 	"cs1_dqs3n_tx_de-skew",
381*16a92a42STang Yun ping };
382*16a92a42STang Yun ping 
383*16a92a42STang Yun ping struct rk3328_ddr_dts_config_timing {
384*16a92a42STang Yun ping 	unsigned int ddr3_speed_bin;
385*16a92a42STang Yun ping 	unsigned int ddr4_speed_bin;
386*16a92a42STang Yun ping 	unsigned int pd_idle;
387*16a92a42STang Yun ping 	unsigned int sr_idle;
388*16a92a42STang Yun ping 	unsigned int sr_mc_gate_idle;
389*16a92a42STang Yun ping 	unsigned int srpd_lite_idle;
390*16a92a42STang Yun ping 	unsigned int standby_idle;
391*16a92a42STang Yun ping 
392*16a92a42STang Yun ping 	unsigned int auto_pd_dis_freq;
393*16a92a42STang Yun ping 	unsigned int auto_sr_dis_freq;
394*16a92a42STang Yun ping 	/* for ddr3 only */
395*16a92a42STang Yun ping 	unsigned int ddr3_dll_dis_freq;
396*16a92a42STang Yun ping 	/* for ddr4 only */
397*16a92a42STang Yun ping 	unsigned int ddr4_dll_dis_freq;
398*16a92a42STang Yun ping 	unsigned int phy_dll_dis_freq;
399*16a92a42STang Yun ping 
400*16a92a42STang Yun ping 	unsigned int ddr3_odt_dis_freq;
401*16a92a42STang Yun ping 	unsigned int phy_ddr3_odt_dis_freq;
402*16a92a42STang Yun ping 	unsigned int ddr3_drv;
403*16a92a42STang Yun ping 	unsigned int ddr3_odt;
404*16a92a42STang Yun ping 	unsigned int phy_ddr3_ca_drv;
405*16a92a42STang Yun ping 	unsigned int phy_ddr3_ck_drv;
406*16a92a42STang Yun ping 	unsigned int phy_ddr3_dq_drv;
407*16a92a42STang Yun ping 	unsigned int phy_ddr3_odt;
408*16a92a42STang Yun ping 
409*16a92a42STang Yun ping 	unsigned int lpddr3_odt_dis_freq;
410*16a92a42STang Yun ping 	unsigned int phy_lpddr3_odt_dis_freq;
411*16a92a42STang Yun ping 	unsigned int lpddr3_drv;
412*16a92a42STang Yun ping 	unsigned int lpddr3_odt;
413*16a92a42STang Yun ping 	unsigned int phy_lpddr3_ca_drv;
414*16a92a42STang Yun ping 	unsigned int phy_lpddr3_ck_drv;
415*16a92a42STang Yun ping 	unsigned int phy_lpddr3_dq_drv;
416*16a92a42STang Yun ping 	unsigned int phy_lpddr3_odt;
417*16a92a42STang Yun ping 
418*16a92a42STang Yun ping 	unsigned int lpddr4_odt_dis_freq;
419*16a92a42STang Yun ping 	unsigned int phy_lpddr4_odt_dis_freq;
420*16a92a42STang Yun ping 	unsigned int lpddr4_drv;
421*16a92a42STang Yun ping 	unsigned int lpddr4_dq_odt;
422*16a92a42STang Yun ping 	unsigned int lpddr4_ca_odt;
423*16a92a42STang Yun ping 	unsigned int phy_lpddr4_ca_drv;
424*16a92a42STang Yun ping 	unsigned int phy_lpddr4_ck_cs_drv;
425*16a92a42STang Yun ping 	unsigned int phy_lpddr4_dq_drv;
426*16a92a42STang Yun ping 	unsigned int phy_lpddr4_odt;
427*16a92a42STang Yun ping 
428*16a92a42STang Yun ping 	unsigned int ddr4_odt_dis_freq;
429*16a92a42STang Yun ping 	unsigned int phy_ddr4_odt_dis_freq;
430*16a92a42STang Yun ping 	unsigned int ddr4_drv;
431*16a92a42STang Yun ping 	unsigned int ddr4_odt;
432*16a92a42STang Yun ping 	unsigned int phy_ddr4_ca_drv;
433*16a92a42STang Yun ping 	unsigned int phy_ddr4_ck_drv;
434*16a92a42STang Yun ping 	unsigned int phy_ddr4_dq_drv;
435*16a92a42STang Yun ping 	unsigned int phy_ddr4_odt;
436*16a92a42STang Yun ping 
437*16a92a42STang Yun ping 	unsigned int ca_skew[15];
438*16a92a42STang Yun ping 	unsigned int cs0_skew[44];
439*16a92a42STang Yun ping 	unsigned int cs1_skew[44];
440*16a92a42STang Yun ping 
441*16a92a42STang Yun ping 	unsigned int available;
442*16a92a42STang Yun ping };
443*16a92a42STang Yun ping 
444*16a92a42STang Yun ping struct px30_ddr_dts_config_timing {
445*16a92a42STang Yun ping 	unsigned int ddr2_speed_bin;
446*16a92a42STang Yun ping 	unsigned int ddr3_speed_bin;
447*16a92a42STang Yun ping 	unsigned int ddr4_speed_bin;
448*16a92a42STang Yun ping 	unsigned int pd_idle;
449*16a92a42STang Yun ping 	unsigned int sr_idle;
450*16a92a42STang Yun ping 	unsigned int sr_mc_gate_idle;
451*16a92a42STang Yun ping 	unsigned int srpd_lite_idle;
452*16a92a42STang Yun ping 	unsigned int standby_idle;
453*16a92a42STang Yun ping 
454*16a92a42STang Yun ping 	unsigned int auto_pd_dis_freq;
455*16a92a42STang Yun ping 	unsigned int auto_sr_dis_freq;
456*16a92a42STang Yun ping 	/* for ddr2 only */
457*16a92a42STang Yun ping 	unsigned int ddr2_dll_dis_freq;
458*16a92a42STang Yun ping 	/* for ddr3 only */
459*16a92a42STang Yun ping 	unsigned int ddr3_dll_dis_freq;
460*16a92a42STang Yun ping 	/* for ddr4 only */
461*16a92a42STang Yun ping 	unsigned int ddr4_dll_dis_freq;
462*16a92a42STang Yun ping 	unsigned int phy_dll_dis_freq;
463*16a92a42STang Yun ping 
464*16a92a42STang Yun ping 	unsigned int ddr2_odt_dis_freq;
465*16a92a42STang Yun ping 	unsigned int phy_ddr2_odt_dis_freq;
466*16a92a42STang Yun ping 	unsigned int ddr2_drv;
467*16a92a42STang Yun ping 	unsigned int ddr2_odt;
468*16a92a42STang Yun ping 	unsigned int phy_ddr2_ca_drv;
469*16a92a42STang Yun ping 	unsigned int phy_ddr2_ck_drv;
470*16a92a42STang Yun ping 	unsigned int phy_ddr2_dq_drv;
471*16a92a42STang Yun ping 	unsigned int phy_ddr2_odt;
472*16a92a42STang Yun ping 
473*16a92a42STang Yun ping 	unsigned int ddr3_odt_dis_freq;
474*16a92a42STang Yun ping 	unsigned int phy_ddr3_odt_dis_freq;
475*16a92a42STang Yun ping 	unsigned int ddr3_drv;
476*16a92a42STang Yun ping 	unsigned int ddr3_odt;
477*16a92a42STang Yun ping 	unsigned int phy_ddr3_ca_drv;
478*16a92a42STang Yun ping 	unsigned int phy_ddr3_ck_drv;
479*16a92a42STang Yun ping 	unsigned int phy_ddr3_dq_drv;
480*16a92a42STang Yun ping 	unsigned int phy_ddr3_odt;
481*16a92a42STang Yun ping 
482*16a92a42STang Yun ping 	unsigned int phy_lpddr2_odt_dis_freq;
483*16a92a42STang Yun ping 	unsigned int lpddr2_drv;
484*16a92a42STang Yun ping 	unsigned int phy_lpddr2_ca_drv;
485*16a92a42STang Yun ping 	unsigned int phy_lpddr2_ck_drv;
486*16a92a42STang Yun ping 	unsigned int phy_lpddr2_dq_drv;
487*16a92a42STang Yun ping 	unsigned int phy_lpddr2_odt;
488*16a92a42STang Yun ping 
489*16a92a42STang Yun ping 	unsigned int lpddr3_odt_dis_freq;
490*16a92a42STang Yun ping 	unsigned int phy_lpddr3_odt_dis_freq;
491*16a92a42STang Yun ping 	unsigned int lpddr3_drv;
492*16a92a42STang Yun ping 	unsigned int lpddr3_odt;
493*16a92a42STang Yun ping 	unsigned int phy_lpddr3_ca_drv;
494*16a92a42STang Yun ping 	unsigned int phy_lpddr3_ck_drv;
495*16a92a42STang Yun ping 	unsigned int phy_lpddr3_dq_drv;
496*16a92a42STang Yun ping 	unsigned int phy_lpddr3_odt;
497*16a92a42STang Yun ping 
498*16a92a42STang Yun ping 	unsigned int lpddr4_odt_dis_freq;
499*16a92a42STang Yun ping 	unsigned int phy_lpddr4_odt_dis_freq;
500*16a92a42STang Yun ping 	unsigned int lpddr4_drv;
501*16a92a42STang Yun ping 	unsigned int lpddr4_dq_odt;
502*16a92a42STang Yun ping 	unsigned int lpddr4_ca_odt;
503*16a92a42STang Yun ping 	unsigned int phy_lpddr4_ca_drv;
504*16a92a42STang Yun ping 	unsigned int phy_lpddr4_ck_cs_drv;
505*16a92a42STang Yun ping 	unsigned int phy_lpddr4_dq_drv;
506*16a92a42STang Yun ping 	unsigned int phy_lpddr4_odt;
507*16a92a42STang Yun ping 
508*16a92a42STang Yun ping 	unsigned int ddr4_odt_dis_freq;
509*16a92a42STang Yun ping 	unsigned int phy_ddr4_odt_dis_freq;
510*16a92a42STang Yun ping 	unsigned int ddr4_drv;
511*16a92a42STang Yun ping 	unsigned int ddr4_odt;
512*16a92a42STang Yun ping 	unsigned int phy_ddr4_ca_drv;
513*16a92a42STang Yun ping 	unsigned int phy_ddr4_ck_drv;
514*16a92a42STang Yun ping 	unsigned int phy_ddr4_dq_drv;
515*16a92a42STang Yun ping 	unsigned int phy_ddr4_odt;
516*16a92a42STang Yun ping 
517*16a92a42STang Yun ping 	unsigned int ca_skew[15];
518*16a92a42STang Yun ping 	unsigned int cs0_skew[44];
519*16a92a42STang Yun ping 	unsigned int cs1_skew[44];
520*16a92a42STang Yun ping 
521*16a92a42STang Yun ping 	unsigned int available;
522*16a92a42STang Yun ping };
523*16a92a42STang Yun ping 
524*16a92a42STang Yun ping struct rk3328_ddr_de_skew_setting {
525*16a92a42STang Yun ping 	unsigned int ca_de_skew[30];
526*16a92a42STang Yun ping 	unsigned int cs0_de_skew[84];
527*16a92a42STang Yun ping 	unsigned int cs1_de_skew[84];
528*16a92a42STang Yun ping };
529*16a92a42STang Yun ping 
530*16a92a42STang Yun ping static void
531*16a92a42STang Yun ping rk3328_de_skew_setting_2_register(struct rk3328_ddr_de_skew_setting *de_skew,
532*16a92a42STang Yun ping 				  struct rk3328_ddr_dts_config_timing *tim)
533*16a92a42STang Yun ping {
534*16a92a42STang Yun ping 	u32 n;
535*16a92a42STang Yun ping 	u32 offset;
536*16a92a42STang Yun ping 	u32 shift;
537*16a92a42STang Yun ping 
538*16a92a42STang Yun ping 	memset_io(tim->ca_skew, 0, sizeof(tim->ca_skew));
539*16a92a42STang Yun ping 	memset_io(tim->cs0_skew, 0, sizeof(tim->cs0_skew));
540*16a92a42STang Yun ping 	memset_io(tim->cs1_skew, 0, sizeof(tim->cs1_skew));
541*16a92a42STang Yun ping 
542*16a92a42STang Yun ping 	/* CA de-skew */
543*16a92a42STang Yun ping 	for (n = 0; n < ARRAY_SIZE(de_skew->ca_de_skew); n++) {
544*16a92a42STang Yun ping 		offset = n / 2;
545*16a92a42STang Yun ping 		shift = n % 2;
546*16a92a42STang Yun ping 		/* 0 => 4; 1 => 0 */
547*16a92a42STang Yun ping 		shift = (shift == 0) ? 4 : 0;
548*16a92a42STang Yun ping 		tim->ca_skew[offset] &= ~(0xf << shift);
549*16a92a42STang Yun ping 		tim->ca_skew[offset] |= (de_skew->ca_de_skew[n] << shift);
550*16a92a42STang Yun ping 	}
551*16a92a42STang Yun ping 
552*16a92a42STang Yun ping 	/* CS0 data de-skew */
553*16a92a42STang Yun ping 	for (n = 0; n < ARRAY_SIZE(de_skew->cs0_de_skew); n++) {
554*16a92a42STang Yun ping 		offset = ((n / 21) * 11) + ((n % 21) / 2);
555*16a92a42STang Yun ping 		shift = ((n % 21) % 2);
556*16a92a42STang Yun ping 		if ((n % 21) == 20)
557*16a92a42STang Yun ping 			shift = 0;
558*16a92a42STang Yun ping 		else
559*16a92a42STang Yun ping 			/* 0 => 4; 1 => 0 */
560*16a92a42STang Yun ping 			shift = (shift == 0) ? 4 : 0;
561*16a92a42STang Yun ping 		tim->cs0_skew[offset] &= ~(0xf << shift);
562*16a92a42STang Yun ping 		tim->cs0_skew[offset] |= (de_skew->cs0_de_skew[n] << shift);
563*16a92a42STang Yun ping 	}
564*16a92a42STang Yun ping 
565*16a92a42STang Yun ping 	/* CS1 data de-skew */
566*16a92a42STang Yun ping 	for (n = 0; n < ARRAY_SIZE(de_skew->cs1_de_skew); n++) {
567*16a92a42STang Yun ping 		offset = ((n / 21) * 11) + ((n % 21) / 2);
568*16a92a42STang Yun ping 		shift = ((n % 21) % 2);
569*16a92a42STang Yun ping 		if ((n % 21) == 20)
570*16a92a42STang Yun ping 			shift = 0;
571*16a92a42STang Yun ping 		else
572*16a92a42STang Yun ping 			/* 0 => 4; 1 => 0 */
573*16a92a42STang Yun ping 			shift = (shift == 0) ? 4 : 0;
574*16a92a42STang Yun ping 		tim->cs1_skew[offset] &= ~(0xf << shift);
575*16a92a42STang Yun ping 		tim->cs1_skew[offset] |= (de_skew->cs1_de_skew[n] << shift);
576*16a92a42STang Yun ping 	}
577*16a92a42STang Yun ping }
578*16a92a42STang Yun ping 
579*16a92a42STang Yun ping static void px30_de_skew_set_2_reg(struct rk3328_ddr_de_skew_setting *de_skew,
580*16a92a42STang Yun ping 				   struct px30_ddr_dts_config_timing *tim)
581*16a92a42STang Yun ping {
582*16a92a42STang Yun ping 	u32 n;
583*16a92a42STang Yun ping 	u32 offset;
584*16a92a42STang Yun ping 	u32 shift;
585*16a92a42STang Yun ping 
586*16a92a42STang Yun ping 	memset_io(tim->ca_skew, 0, sizeof(tim->ca_skew));
587*16a92a42STang Yun ping 	memset_io(tim->cs0_skew, 0, sizeof(tim->cs0_skew));
588*16a92a42STang Yun ping 	memset_io(tim->cs1_skew, 0, sizeof(tim->cs1_skew));
589*16a92a42STang Yun ping 
590*16a92a42STang Yun ping 	/* CA de-skew */
591*16a92a42STang Yun ping 	for (n = 0; n < ARRAY_SIZE(de_skew->ca_de_skew); n++) {
592*16a92a42STang Yun ping 		offset = n / 2;
593*16a92a42STang Yun ping 		shift = n % 2;
594*16a92a42STang Yun ping 		/* 0 => 4; 1 => 0 */
595*16a92a42STang Yun ping 		shift = (shift == 0) ? 4 : 0;
596*16a92a42STang Yun ping 		tim->ca_skew[offset] &= ~(0xf << shift);
597*16a92a42STang Yun ping 		tim->ca_skew[offset] |= (de_skew->ca_de_skew[n] << shift);
598*16a92a42STang Yun ping 	}
599*16a92a42STang Yun ping 
600*16a92a42STang Yun ping 	/* CS0 data de-skew */
601*16a92a42STang Yun ping 	for (n = 0; n < ARRAY_SIZE(de_skew->cs0_de_skew); n++) {
602*16a92a42STang Yun ping 		offset = ((n / 21) * 11) + ((n % 21) / 2);
603*16a92a42STang Yun ping 		shift = ((n % 21) % 2);
604*16a92a42STang Yun ping 		if ((n % 21) == 20)
605*16a92a42STang Yun ping 			shift = 0;
606*16a92a42STang Yun ping 		else
607*16a92a42STang Yun ping 			/* 0 => 4; 1 => 0 */
608*16a92a42STang Yun ping 			shift = (shift == 0) ? 4 : 0;
609*16a92a42STang Yun ping 		tim->cs0_skew[offset] &= ~(0xf << shift);
610*16a92a42STang Yun ping 		tim->cs0_skew[offset] |= (de_skew->cs0_de_skew[n] << shift);
611*16a92a42STang Yun ping 	}
612*16a92a42STang Yun ping 
613*16a92a42STang Yun ping 	/* CS1 data de-skew */
614*16a92a42STang Yun ping 	for (n = 0; n < ARRAY_SIZE(de_skew->cs1_de_skew); n++) {
615*16a92a42STang Yun ping 		offset = ((n / 21) * 11) + ((n % 21) / 2);
616*16a92a42STang Yun ping 		shift = ((n % 21) % 2);
617*16a92a42STang Yun ping 		if ((n % 21) == 20)
618*16a92a42STang Yun ping 			shift = 0;
619*16a92a42STang Yun ping 		else
620*16a92a42STang Yun ping 			/* 0 => 4; 1 => 0 */
621*16a92a42STang Yun ping 			shift = (shift == 0) ? 4 : 0;
622*16a92a42STang Yun ping 		tim->cs1_skew[offset] &= ~(0xf << shift);
623*16a92a42STang Yun ping 		tim->cs1_skew[offset] |= (de_skew->cs1_de_skew[n] << shift);
624*16a92a42STang Yun ping 	}
625*16a92a42STang Yun ping }
626*16a92a42STang Yun ping 
627*16a92a42STang Yun ping static void of_get_rk3328_timings(struct udevice *dev, uint32_t *timing)
628*16a92a42STang Yun ping {
629*16a92a42STang Yun ping 	struct device_node *np_tim;
630*16a92a42STang Yun ping 	u32 *p;
631*16a92a42STang Yun ping 	struct rk3328_ddr_dts_config_timing *dts_timing;
632*16a92a42STang Yun ping 	struct rk3328_ddr_de_skew_setting *de_skew;
633*16a92a42STang Yun ping 	int ret = 0;
634*16a92a42STang Yun ping 	u32 i;
635*16a92a42STang Yun ping 
636*16a92a42STang Yun ping 	dts_timing =
637*16a92a42STang Yun ping 		(struct rk3328_ddr_dts_config_timing *)(timing +
638*16a92a42STang Yun ping 							DTS_PAR_OFFSET / 4);
639*16a92a42STang Yun ping 
640*16a92a42STang Yun ping 	np_tim = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)),
641*16a92a42STang Yun ping 				  "ddr_timing", 0);
642*16a92a42STang Yun ping 	if (!np_tim) {
643*16a92a42STang Yun ping 		ret = -EINVAL;
644*16a92a42STang Yun ping 		goto end;
645*16a92a42STang Yun ping 	}
646*16a92a42STang Yun ping 	de_skew = malloc(sizeof(*de_skew));
647*16a92a42STang Yun ping 	if (!de_skew) {
648*16a92a42STang Yun ping 		ret = -ENOMEM;
649*16a92a42STang Yun ping 		goto end;
650*16a92a42STang Yun ping 	}
651*16a92a42STang Yun ping 	p = (u32 *)dts_timing;
652*16a92a42STang Yun ping 	for (i = 0; i < ARRAY_SIZE(rk3328_dts_timing); i++)
653*16a92a42STang Yun ping 		ret |= ofnode_read_u32(np_to_ofnode(np_tim),
654*16a92a42STang Yun ping 				       rk3328_dts_timing[i], p + i);
655*16a92a42STang Yun ping 
656*16a92a42STang Yun ping 	p = (u32 *)de_skew->ca_de_skew;
657*16a92a42STang Yun ping 	for (i = 0; i < ARRAY_SIZE(rk3328_dts_ca_timing); i++)
658*16a92a42STang Yun ping 		ret |= ofnode_read_u32(np_to_ofnode(np_tim),
659*16a92a42STang Yun ping 				       rk3328_dts_ca_timing[i], p + i);
660*16a92a42STang Yun ping 	p = (u32 *)de_skew->cs0_de_skew;
661*16a92a42STang Yun ping 	for (i = 0; i < ARRAY_SIZE(rk3328_dts_cs0_timing); i++)
662*16a92a42STang Yun ping 		ret |= ofnode_read_u32(np_to_ofnode(np_tim),
663*16a92a42STang Yun ping 				       rk3328_dts_cs0_timing[i], p + i);
664*16a92a42STang Yun ping 	p = (u32 *)de_skew->cs1_de_skew;
665*16a92a42STang Yun ping 	for (i = 0; i < ARRAY_SIZE(rk3328_dts_cs1_timing); i++)
666*16a92a42STang Yun ping 		ret |= ofnode_read_u32(np_to_ofnode(np_tim),
667*16a92a42STang Yun ping 				       rk3328_dts_cs1_timing[i], p + i);
668*16a92a42STang Yun ping 
669*16a92a42STang Yun ping 	if (!ret)
670*16a92a42STang Yun ping 		rk3328_de_skew_setting_2_register(de_skew, dts_timing);
671*16a92a42STang Yun ping 	free(de_skew);
672*16a92a42STang Yun ping end:
673*16a92a42STang Yun ping 	if (!ret) {
674*16a92a42STang Yun ping 		dts_timing->available = 1;
675*16a92a42STang Yun ping 	} else {
676*16a92a42STang Yun ping 		dts_timing->available = 0;
677*16a92a42STang Yun ping 		printf("of_get_ddr_timings: fail\n");
678*16a92a42STang Yun ping 	}
679*16a92a42STang Yun ping }
680*16a92a42STang Yun ping 
681*16a92a42STang Yun ping static void of_get_px30_timings(struct udevice *dev, uint32_t *timing)
682*16a92a42STang Yun ping {
683*16a92a42STang Yun ping 	struct device_node *np_tim;
684*16a92a42STang Yun ping 	u32 *p;
685*16a92a42STang Yun ping 	struct px30_ddr_dts_config_timing *dts_timing;
686*16a92a42STang Yun ping 	struct rk3328_ddr_de_skew_setting *de_skew;
687*16a92a42STang Yun ping 	int ret = 0;
688*16a92a42STang Yun ping 	u32 i;
689*16a92a42STang Yun ping 
690*16a92a42STang Yun ping 	dts_timing =
691*16a92a42STang Yun ping 		(struct px30_ddr_dts_config_timing *)(timing +
692*16a92a42STang Yun ping 							DTS_PAR_OFFSET / 4);
693*16a92a42STang Yun ping 
694*16a92a42STang Yun ping 	np_tim = of_parse_phandle(ofnode_to_np(dev_ofnode(dev)),
695*16a92a42STang Yun ping 				  "ddr_timing", 0);
696*16a92a42STang Yun ping 	if (!np_tim) {
697*16a92a42STang Yun ping 		ret = -EINVAL;
698*16a92a42STang Yun ping 		goto end;
699*16a92a42STang Yun ping 	}
700*16a92a42STang Yun ping 	de_skew = malloc(sizeof(*de_skew));
701*16a92a42STang Yun ping 	if (!de_skew) {
702*16a92a42STang Yun ping 		ret = -ENOMEM;
703*16a92a42STang Yun ping 		goto end;
704*16a92a42STang Yun ping 	}
705*16a92a42STang Yun ping 	p = (u32 *)dts_timing;
706*16a92a42STang Yun ping 	for (i = 0; i < ARRAY_SIZE(px30_dts_timing); i++)
707*16a92a42STang Yun ping 		ret |= ofnode_read_u32(np_to_ofnode(np_tim), px30_dts_timing[i],
708*16a92a42STang Yun ping 					p + i);
709*16a92a42STang Yun ping 	p = (u32 *)de_skew->ca_de_skew;
710*16a92a42STang Yun ping 	for (i = 0; i < ARRAY_SIZE(rk3328_dts_ca_timing); i++)
711*16a92a42STang Yun ping 		ret |= ofnode_read_u32(np_to_ofnode(np_tim),
712*16a92a42STang Yun ping 				       rk3328_dts_ca_timing[i], p + i);
713*16a92a42STang Yun ping 	p = (u32 *)de_skew->cs0_de_skew;
714*16a92a42STang Yun ping 	for (i = 0; i < ARRAY_SIZE(rk3328_dts_cs0_timing); i++)
715*16a92a42STang Yun ping 		ret |= ofnode_read_u32(np_to_ofnode(np_tim),
716*16a92a42STang Yun ping 				       rk3328_dts_cs0_timing[i], p + i);
717*16a92a42STang Yun ping 	p = (u32 *)de_skew->cs1_de_skew;
718*16a92a42STang Yun ping 	for (i = 0; i < ARRAY_SIZE(rk3328_dts_cs1_timing); i++)
719*16a92a42STang Yun ping 		ret |= ofnode_read_u32(np_to_ofnode(np_tim),
720*16a92a42STang Yun ping 				       rk3328_dts_cs1_timing[i], p + i);
721*16a92a42STang Yun ping 	if (!ret)
722*16a92a42STang Yun ping 		px30_de_skew_set_2_reg(de_skew, dts_timing);
723*16a92a42STang Yun ping 	free(de_skew);
724*16a92a42STang Yun ping end:
725*16a92a42STang Yun ping 	if (!ret) {
726*16a92a42STang Yun ping 		dts_timing->available = 1;
727*16a92a42STang Yun ping 	} else {
728*16a92a42STang Yun ping 		dts_timing->available = 0;
729*16a92a42STang Yun ping 		printf("of_get_ddr_timings: fail\n");
730*16a92a42STang Yun ping 	}
731*16a92a42STang Yun ping }
732*16a92a42STang Yun ping 
733*16a92a42STang Yun ping static __maybe_unused int rk3328_devfreq_init(struct udevice *dev)
734*16a92a42STang Yun ping {
735*16a92a42STang Yun ping 	struct arm_smccc_res res;
736*16a92a42STang Yun ping 	u32 size;
737*16a92a42STang Yun ping 
738*16a92a42STang Yun ping 	res = sip_smc_dram(0, 0,
739*16a92a42STang Yun ping 			   ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION);
740*16a92a42STang Yun ping 	printf("current ATF version 0x%lx!\n", res.a1);
741*16a92a42STang Yun ping 	if (res.a0 || res.a1 < 0x101) {
742*16a92a42STang Yun ping 		printf("trusted firmware need to update or is invalid!\n");
743*16a92a42STang Yun ping 		return -ENXIO;
744*16a92a42STang Yun ping 	}
745*16a92a42STang Yun ping 
746*16a92a42STang Yun ping 	printf("read tf version 0x%lx!\n", res.a1);
747*16a92a42STang Yun ping 
748*16a92a42STang Yun ping 	/*
749*16a92a42STang Yun ping 	 * first 4KB is used for interface parameters
750*16a92a42STang Yun ping 	 * after 4KB * N is dts parameters
751*16a92a42STang Yun ping 	 */
752*16a92a42STang Yun ping 	size = sizeof(struct rk3328_ddr_dts_config_timing);
753*16a92a42STang Yun ping 	res = sip_smc_request_share_mem(DIV_ROUND_UP(size, 4096) + 1,
754*16a92a42STang Yun ping 					SHARE_PAGE_TYPE_DDR);
755*16a92a42STang Yun ping 	if (res.a0 != 0) {
756*16a92a42STang Yun ping 		printf("no ATF memory for init\n");
757*16a92a42STang Yun ping 		return -ENOMEM;
758*16a92a42STang Yun ping 	}
759*16a92a42STang Yun ping 	ddr_psci_param = (struct share_params *)res.a1;
760*16a92a42STang Yun ping 	of_get_rk3328_timings(dev, (uint32_t *)ddr_psci_param);
761*16a92a42STang Yun ping 
762*16a92a42STang Yun ping 	flush_cache((unsigned long)ddr_psci_param,
763*16a92a42STang Yun ping 		    (DIV_ROUND_UP(size, 4096) + 1) * 0x1000);
764*16a92a42STang Yun ping 
765*16a92a42STang Yun ping 	res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0,
766*16a92a42STang Yun ping 			   ROCKCHIP_SIP_CONFIG_DRAM_INIT);
767*16a92a42STang Yun ping 	if (res.a0) {
768*16a92a42STang Yun ping 		printf("rockchip_sip_config_dram_init error:%lx\n",
769*16a92a42STang Yun ping 		       res.a0);
770*16a92a42STang Yun ping 		return -ENOMEM;
771*16a92a42STang Yun ping 	}
772*16a92a42STang Yun ping 
773*16a92a42STang Yun ping 	return 0;
774*16a92a42STang Yun ping }
775*16a92a42STang Yun ping 
776*16a92a42STang Yun ping static __maybe_unused int px30_devfreq_init(struct udevice *dev)
777*16a92a42STang Yun ping {
778*16a92a42STang Yun ping 	struct arm_smccc_res res;
779*16a92a42STang Yun ping 	u32 size;
780*16a92a42STang Yun ping 
781*16a92a42STang Yun ping 	res = sip_smc_dram(0, 0,
782*16a92a42STang Yun ping 			   ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION);
783*16a92a42STang Yun ping 	printf("current ATF version 0x%lx!\n", res.a1);
784*16a92a42STang Yun ping 	if (res.a0 || res.a1 < 0x103) {
785*16a92a42STang Yun ping 		printf("trusted firmware need to update or is invalid!\n");
786*16a92a42STang Yun ping 		return -ENXIO;
787*16a92a42STang Yun ping 	}
788*16a92a42STang Yun ping 
789*16a92a42STang Yun ping 	printf("read tf version 0x%lx!\n", res.a1);
790*16a92a42STang Yun ping 
791*16a92a42STang Yun ping 	/*
792*16a92a42STang Yun ping 	 * first 4KB is used for interface parameters
793*16a92a42STang Yun ping 	 * after 4KB * N is dts parameters
794*16a92a42STang Yun ping 	 */
795*16a92a42STang Yun ping 	size = sizeof(struct px30_ddr_dts_config_timing);
796*16a92a42STang Yun ping 	res = sip_smc_request_share_mem(DIV_ROUND_UP(size, 4096) + 1,
797*16a92a42STang Yun ping 					SHARE_PAGE_TYPE_DDR);
798*16a92a42STang Yun ping 	if (res.a0 != 0) {
799*16a92a42STang Yun ping 		printf("no ATF memory for init\n");
800*16a92a42STang Yun ping 		return -ENOMEM;
801*16a92a42STang Yun ping 	}
802*16a92a42STang Yun ping 
803*16a92a42STang Yun ping 	ddr_psci_param = (struct share_params *)res.a1;
804*16a92a42STang Yun ping 	of_get_px30_timings(dev, (uint32_t *)ddr_psci_param);
805*16a92a42STang Yun ping 
806*16a92a42STang Yun ping 	flush_cache((unsigned long)ddr_psci_param,
807*16a92a42STang Yun ping 		    (DIV_ROUND_UP(size, 4096) + 1) * 0x1000);
808*16a92a42STang Yun ping 	res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0,
809*16a92a42STang Yun ping 			   ROCKCHIP_SIP_CONFIG_DRAM_INIT);
810*16a92a42STang Yun ping 	if (res.a0) {
811*16a92a42STang Yun ping 		printf("rockchip_sip_config_dram_init error:%lx\n",
812*16a92a42STang Yun ping 		       res.a0);
813*16a92a42STang Yun ping 		return -ENOMEM;
814*16a92a42STang Yun ping 	}
815*16a92a42STang Yun ping 
816*16a92a42STang Yun ping 	return 0;
817*16a92a42STang Yun ping }
818*16a92a42STang Yun ping 
819*16a92a42STang Yun ping int rockchip_ddrclk_sip_set_rate_v2(unsigned long drate)
820*16a92a42STang Yun ping {
821*16a92a42STang Yun ping 	struct share_params *p;
822*16a92a42STang Yun ping 	struct arm_smccc_res res;
823*16a92a42STang Yun ping 
824*16a92a42STang Yun ping 	p = ddr_psci_param;
825*16a92a42STang Yun ping 
826*16a92a42STang Yun ping 	p->hz = drate;
827*16a92a42STang Yun ping 	p->lcdc_type = 0;
828*16a92a42STang Yun ping 	p->wait_flag1 = 0;
829*16a92a42STang Yun ping 	p->wait_flag0 = 0;
830*16a92a42STang Yun ping 	p->complt_hwirq = 105;
831*16a92a42STang Yun ping 
832*16a92a42STang Yun ping 	flush_cache((unsigned long)ddr_psci_param, sizeof(struct share_params));
833*16a92a42STang Yun ping 	res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0,
834*16a92a42STang Yun ping 			   ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE);
835*16a92a42STang Yun ping 
836*16a92a42STang Yun ping 	return res.a0;
837*16a92a42STang Yun ping }
838*16a92a42STang Yun ping 
839*16a92a42STang Yun ping unsigned long rockchip_ddrclk_sip_recalc_rate_v2(void)
840*16a92a42STang Yun ping {
841*16a92a42STang Yun ping 	struct arm_smccc_res res;
842*16a92a42STang Yun ping 
843*16a92a42STang Yun ping 	res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0,
844*16a92a42STang Yun ping 			   ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE);
845*16a92a42STang Yun ping 	if (!res.a0)
846*16a92a42STang Yun ping 		return res.a1;
847*16a92a42STang Yun ping 	else
848*16a92a42STang Yun ping 		return 0;
849*16a92a42STang Yun ping }
850*16a92a42STang Yun ping 
851*16a92a42STang Yun ping unsigned long rockchip_ddrclk_sip_round_rate_v2(unsigned long rate)
852*16a92a42STang Yun ping {
853*16a92a42STang Yun ping 	struct share_params *p;
854*16a92a42STang Yun ping 	struct arm_smccc_res res;
855*16a92a42STang Yun ping 
856*16a92a42STang Yun ping 	p = ddr_psci_param;
857*16a92a42STang Yun ping 
858*16a92a42STang Yun ping 	p->hz = rate;
859*16a92a42STang Yun ping 
860*16a92a42STang Yun ping 	flush_cache((unsigned long)ddr_psci_param, sizeof(struct share_params));
861*16a92a42STang Yun ping 
862*16a92a42STang Yun ping 	res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0,
863*16a92a42STang Yun ping 			   ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE);
864*16a92a42STang Yun ping 	if (!res.a0)
865*16a92a42STang Yun ping 		return res.a1;
866*16a92a42STang Yun ping 	else
867*16a92a42STang Yun ping 		return 0;
868*16a92a42STang Yun ping }
869*16a92a42STang Yun ping 
870*16a92a42STang Yun ping int rockchip_dmcfreq_probe(struct udevice *dev)
871*16a92a42STang Yun ping {
872*16a92a42STang Yun ping 	int ret;
873*16a92a42STang Yun ping 
874*16a92a42STang Yun ping #if defined(CONFIG_ROCKCHIP_PX30)
875*16a92a42STang Yun ping 	ret = px30_devfreq_init(dev);
876*16a92a42STang Yun ping #elif defined(CONFIG_ROCKCHIP_RK3328)
877*16a92a42STang Yun ping 	ret = rk3328_devfreq_init(dev);
878*16a92a42STang Yun ping #else
879*16a92a42STang Yun ping 	ret = -1;
880*16a92a42STang Yun ping 	printf("Unsupported chip type\n");
881*16a92a42STang Yun ping #endif
882*16a92a42STang Yun ping 	if (ret)
883*16a92a42STang Yun ping 		return ret;
884*16a92a42STang Yun ping 
885*16a92a42STang Yun ping 	printf("dram freq:%ld Hz\n", rockchip_ddrclk_sip_recalc_rate_v2());
886*16a92a42STang Yun ping 
887*16a92a42STang Yun ping 	return 0;
888*16a92a42STang Yun ping }
889