1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2022 StarFive Technology Co., Ltd.
4  * Author: Yanhong Wang<yanhong.wang@starfivetech.com>
5  */
6 
7 #include <asm/io.h>
8 
9 #include "starfive_ddr.h"
10 
11 static const struct ddr_reg_cfg ddr_start_cfg[] = {
12 	{89,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
13 	{78,	0xfffffcff,	0x0,		(OFFSET_SEL | REGCLRSETALL)},
14 	{345,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
15 	{334,	0xfffffcff,	0x0,		(OFFSET_SEL | REGCLRSETALL)},
16 	{601,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
17 	{590,	0xfffffcff,	0x0,		(OFFSET_SEL | REGCLRSETALL)},
18 	{857,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
19 	{846,	0xfffffcff,	0x0,		(OFFSET_SEL | REGCLRSETALL)},
20 	{1793,	0xfffffeff,	0x0,		(OFFSET_SEL | REGCLRSETALL)},
21 	{1793,	0xfffcffff,	0x0,		(OFFSET_SEL | REGCLRSETALL)},
22 	{125,	0xfff0ffff,	0x00010000,	(OFFSET_SEL | REGCLRSETALL)},
23 	{102,	0xfffffffc,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
24 	{105,	0xffffffe0,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
25 	{92,	0xfffffffe,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
26 	{94,	0xffffe0ff,	0x00000200,	(OFFSET_SEL | REGCLRSETALL)},
27 	{96,	0xfffff0ff,	0x00000400,	(OFFSET_SEL | REGCLRSETALL)},
28 	{89,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
29 	{381,	0xfff0ffff,	0x00010000,	(OFFSET_SEL | REGCLRSETALL)},
30 	{358,	0xfffffffc,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
31 	{361,	0xffffffe0,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
32 	{348,	0xfffffffe,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
33 	{350,	0xffffe0ff,	0x00000200,	(OFFSET_SEL | REGCLRSETALL)},
34 	{352,	0xfffff0ff,	0x00000400,	(OFFSET_SEL | REGCLRSETALL)},
35 	{345,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
36 	{637,	0xfff0ffff,	0x00010000,	(OFFSET_SEL | REGCLRSETALL)},
37 	{614,	0xfffffffc,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
38 	{617,	0xffffffe0,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
39 	{604,	0xfffffffe,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
40 	{606,	0xffffe0ff,	0x00000200,	(OFFSET_SEL | REGCLRSETALL)},
41 	{608,	0xfffff0ff,	0x00000400,	(OFFSET_SEL | REGCLRSETALL)},
42 	{601,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
43 	{893,	0xfff0ffff,	0x00010000,	(OFFSET_SEL | REGCLRSETALL)},
44 	{870,	0xfffffffc,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
45 	{873,	0xffffffe0,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
46 	{860,	0xfffffffe,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
47 	{862,	0xffffe0ff,	0x00000200,	(OFFSET_SEL | REGCLRSETALL)},
48 	{864,	0xfffff0ff,	0x00000400,	(OFFSET_SEL | REGCLRSETALL)},
49 	{857,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
50 	{1895,	0xffffe000,	0x00001342,	(OFFSET_SEL | REGCLRSETALL)},
51 	{1835,	0xfffff0ff,	0x00000200,	(OFFSET_SEL | REGCLRSETALL)},
52 	{1793,	0xfffffeff,	0x00000100,	(OFFSET_SEL | REGCLRSETALL)},
53 	{62,	0xfffffeff,	0x0,		REGCLRSETALL},
54 	{66,	0xfffffeff,	0x0,		REGCLRSETALL},
55 	{166,	0xffffff80,	0x00000001,	REGCLRSETALL},
56 	{62,	0xfff0ffff,	0x00010000,	REGCLRSETALL},
57 	{62,	0xf0ffffff,	0x01000000,	REGCLRSETALL},
58 	{166,	0xffff80ff,	0x00000100,	REGCLRSETALL},
59 	{179,	0xff80ffff,	0x00010000,	REGCLRSETALL},
60 	{67,	0xffe0ffff,	0x00010000,	REGCLRSETALL},
61 	{67,	0xe0ffffff,	0x01000000,	REGCLRSETALL},
62 	{179,	0x80ffffff,	0x01000000,	REGCLRSETALL},
63 	{166,	0xff80ffff,	0x00010000,	REGCLRSETALL},
64 	{62,	0xfff0ffff,	0x00010000,	REGCLRSETALL},
65 	{62,	0xf0ffffff,	0x01000000,	REGCLRSETALL},
66 	{166,	0x80ffffff,	0x01000000,	REGCLRSETALL},
67 	{182,	0xff80ffff,	0x00010000,	REGCLRSETALL},
68 	{67,	0xffe0ffff,	0x00010000,	REGCLRSETALL},
69 	{67,	0xe0ffffff,	0x01000000,	REGCLRSETALL},
70 	{182,	0x80ffffff,	0x01000000,	REGCLRSETALL},
71 	{167,	0xffffff80,	0x00000017,	REGCLRSETALL},
72 	{62,	0xfff0ffff,	0x00010000,	REGCLRSETALL},
73 	{62,	0xf0ffffff,	0x01000000,	REGCLRSETALL},
74 	{167,	0xffff80ff,	0x00001700,	REGCLRSETALL},
75 	{185,	0xff80ffff,	0x00200000,	REGCLRSETALL},
76 	{67,	0xffe0ffff,	0x00010000,	REGCLRSETALL},
77 	{67,	0xe0ffffff,	0x01000000,	REGCLRSETALL},
78 	{185,	0x80ffffff,	0x20000000,	REGCLRSETALL},
79 	{10,	0xffffffe0,	0x00000002,	REGCLRSETALL},
80 	{0,	0xfffffffe,	0x00000001,	REGCLRSETALL},
81 	{11,	0xfffffff0,	0x00000005,	(F_CLRSET | REG2G)},
82 	{247,	0xffffffff,	0x00000008,	REGCLRSETALL},
83 	{249,	0xffffffff,	0x00000800,	REGCLRSETALL},
84 	{252,	0xffffffff,	0x00000008,	REGCLRSETALL},
85 	{254,	0xffffffff,	0x00000800,	REGCLRSETALL},
86 	{281,	0xffffffff,	0x33000000,	REGCLRSETALL},
87 	{305,	0xffffffff,	0x33000000,	REGCLRSETALL},
88 	{329,	0xffffffff,	0x33000000,	REGCLRSETALL},
89 	{353,	0xffffffff,	0x33000000,	REGCLRSETALL},
90 	{289,	0xffffffff,	0x36000000,	(F_CLRSET | REG8G)},
91 	{313,	0xffffffff,	0x36000000,	(F_CLRSET | REG8G)},
92 	{337,	0xffffffff,	0x36000000,	(F_CLRSET | REG8G)},
93 	{361,	0xffffffff,	0x36000000,	(F_CLRSET | REG8G)},
94 	{289,	0xffffffff,	0x66000000,	(F_CLRSET | REG2G | REG4G)},
95 	{313,	0xffffffff,	0x66000000,	(F_CLRSET | REG2G | REG4G)},
96 	{337,	0xffffffff,	0x66000000,	(F_CLRSET | REG2G | REG4G)},
97 	{361,	0xffffffff,	0x66000000,	(F_CLRSET | REG2G | REG4G)},
98 	{282,	0xffffffff,	0x00160000,	REGCLRSETALL},
99 	{306,	0xffffffff,	0x00160000,	REGCLRSETALL},
100 	{330,	0xffffffff,	0x00160000,	REGCLRSETALL},
101 	{354,	0xffffffff,	0x00160000,	REGCLRSETALL},
102 	{290,	0xffffffff,	0x00160000,	REGCLRSETALL},
103 	{314,	0xffffffff,	0x00160000,	REGCLRSETALL},
104 	{338,	0xffffffff,	0x00160000,	REGCLRSETALL},
105 	{362,	0xffffffff,	0x00160000,	REGCLRSETALL},
106 	{282,	0xffffff00,	0x17,		REGCLRSETALL},
107 	{306,	0xffffff00,	0x17,		REGCLRSETALL},
108 	{330,	0xffffff00,	0x17,		REGCLRSETALL},
109 	{354,	0xffffff00,	0x17,		REGCLRSETALL},
110 	{290,	0xffffff00,	0x17,		REGCLRSETALL},
111 	{314,	0xffffff00,	0x17,		REGCLRSETALL},
112 	{338,	0xffffff00,	0x17,		REGCLRSETALL},
113 	{362,	0xffffff00,	0x17,		REGCLRSETALL},
114 	{282,	0xffff00ff,	0x2000,		REGCLRSETALL},
115 	{306,	0xffff00ff,	0x2000,		REGCLRSETALL},
116 	{330,	0xffff00ff,	0x2000,		REGCLRSETALL},
117 	{354,	0xffff00ff,	0x2000,		REGCLRSETALL},
118 	{290,	0xffff00ff,	0x2000,		REGCLRSETALL},
119 	{314,	0xffff00ff,	0x2000,		REGCLRSETALL},
120 	{338,	0xffff00ff,	0x2000,		REGCLRSETALL},
121 	{362,	0xffff00ff,	0x2000,		REGCLRSETALL},
122 	{65,	0xffffffff,	0x00000100,	(OFFSET_SEL | REGCLRSETALL)},
123 	{321,	0xffffffff,	0x00000100,	(OFFSET_SEL | REGCLRSETALL)},
124 	{577,	0xffffffff,	0x00000100,	(OFFSET_SEL | REGCLRSETALL)},
125 	{833,	0xffffffff,	0x00000100,	(OFFSET_SEL | REGCLRSETALL)},
126 	{96,	0x0,		0x300,		(OFFSET_SEL | REGADDSETALL)},
127 	{352,	0x0,		0x300,		(OFFSET_SEL | REGADDSETALL)},
128 	{608,	0x0,		0x300,		(OFFSET_SEL | REGADDSETALL)},
129 	{864,	0x0,		0x300,		(OFFSET_SEL | REGADDSETALL)},
130 	{96,	0xff00ffff,	0x00120000,	(OFFSET_SEL | REGCLRSETALL)},
131 	{352,	0xff00ffff,	0x00120000,	(OFFSET_SEL | REGCLRSETALL)},
132 	{608,	0xff00ffff,	0x00120000,	(OFFSET_SEL | REGCLRSETALL)},
133 	{864,	0xff00ffff,	0x00120000,	(OFFSET_SEL | REGCLRSETALL)},
134 	{33,	0xffffff00,	0x0040,		(OFFSET_SEL | REGCLRSETALL)},
135 	{289,	0xffffff00,	0x0040,		(OFFSET_SEL | REGCLRSETALL)},
136 	{545,	0xffffff00,	0x0040,		(OFFSET_SEL | REGCLRSETALL)},
137 	{801,	0xffffff00,	0x0040,		(OFFSET_SEL | REGCLRSETALL)},
138 	{1038,	0xfcffffff,	0x03000000,	(OFFSET_SEL | REGCLRSETALL)},
139 	{1294,	0xfcffffff,	0x03000000,	(OFFSET_SEL | REGCLRSETALL)},
140 	{1550,	0xfcffffff,	0x03000000,	(OFFSET_SEL | REGCLRSETALL)},
141 	{83,	0xffc0ffff,	0x70000,	(OFFSET_SEL | REGCLRSETALL)},
142 	{339,	0xffc0ffff,	0x70000,	(OFFSET_SEL | REGCLRSETALL)},
143 	{595,	0xffc0ffff,	0x70000,	(OFFSET_SEL | REGCLRSETALL)},
144 	{851,	0xffc0ffff,	0x70000,	(OFFSET_SEL | REGCLRSETALL)},
145 	{1062,	0xf800ffff,	0x70000,	(OFFSET_SEL | REGCLRSETALL)},
146 	{1318,	0xf800ffff,	0x70000,	(OFFSET_SEL | REGCLRSETALL)},
147 	{1574,	0xf800ffff,	0x70000,	(OFFSET_SEL | REGCLRSETALL)},
148 	{1892,	0xfffc0000,	0x15547,	(OFFSET_SEL | REGCLRSETALL)},
149 	{1893,	0xfffc0000,	0x7,		(OFFSET_SEL | REGCLRSETALL)},
150 	{1852,	0xffffe000,	0x07a,		(OFFSET_SEL | REGCLRSETALL)},
151 	{1853,	0xffffffff,	0x0100,		(OFFSET_SEL | REGCLRSETALL)},
152 	{1822,	0xffffffff,	0xFF,		(OFFSET_SEL | REGCLRSETALL)},
153 	{1896,	0xfffffc00,	0x03d5,		(OFFSET_SEL | REGCLRSETALL)},
154 	{91,	0xfc00ffff,	0x03d50000,	(OFFSET_SEL | REGCLRSETALL)},
155 	{347,	0xfc00ffff,	0x03d50000,	(OFFSET_SEL | REGCLRSETALL)},
156 	{603,	0xfc00ffff,	0x03d50000,	(OFFSET_SEL | REGCLRSETALL)},
157 	{859,	0xfc00ffff,	0x03d50000,	(OFFSET_SEL | REGCLRSETALL)},
158 	{1912,	0x0,		0xcc3bfc7,	(OFFSET_SEL | REGSETALL)},
159 	{1913,	0x0,		0xff8f,		(OFFSET_SEL | REGSETALL)},
160 	{1914,	0x0,		0x33f07ff,	(OFFSET_SEL | REGSETALL)},
161 	{1915,	0x0,		0xc3c37ff,	(OFFSET_SEL | REGSETALL)},
162 	{1916,	0x0,		0x1fffff10,	(OFFSET_SEL | REGSETALL)},
163 	{1917,	0x0,		0x230070,	(OFFSET_SEL | REGSETALL)},
164 	{1918,	0x0,		0x3ff7ffff,	(OFFSET_SEL | REG4G | REG2G | F_SET)},
165 	{1918,	0x0,		0x3ff7ffff,	(OFFSET_SEL | REG8G | F_SET)},
166 	{1919,	0x0,		0xe10,		(OFFSET_SEL | REGSETALL)},
167 	{1920,	0x0,		0x1fffffff,	(OFFSET_SEL | REGSETALL)},
168 	{1921,	0x0,		0x188411,	(OFFSET_SEL | REGSETALL)},
169 	{1922,	0x0,		0x1fffffff,	(OFFSET_SEL | REGSETALL)},
170 	{1923,	0x0,		0x180400,	(OFFSET_SEL | REGSETALL)},
171 	{1924,	0x0,		0x1fffffff,	(OFFSET_SEL | REGSETALL)},
172 	{1925,	0x0,		0x180400,	(OFFSET_SEL | REGSETALL)},
173 	{1926,	0x0,		0x1fffffcf,	(OFFSET_SEL | REGSETALL)},
174 	{1927,	0x0,		0x188400,	(OFFSET_SEL | REGSETALL)},
175 	{1928,	0x0,		0x1fffffff,	(OFFSET_SEL | REGSETALL)},
176 	{1929,	0x0,		0x4188411,	(OFFSET_SEL | REGSETALL)},
177 	{1837,	0x0,		0x24410,	(OFFSET_SEL | REGSETALL)},
178 	{1840,	0x0,		0x24410,	(OFFSET_SEL | REGSETALL)},
179 	{1842,	0x0,		0x2ffff,	(OFFSET_SEL | REGSETALL)},
180 	{76,	0xff0000f8,	0x00ff8f07,	(OFFSET_SEL | REGCLRSETALL)},
181 	{332,	0xff0000f8,	0x00ff8f07,	(OFFSET_SEL | REGCLRSETALL)},
182 	{588,	0xff0000f8,	0x00ff8f07,	(OFFSET_SEL | REGCLRSETALL)},
183 	{844,	0xff0000f8,	0x00ff8f07,	(OFFSET_SEL | REGCLRSETALL)},
184 	{77,	0xffff0000,	0xff8f,		(OFFSET_SEL | REGCLRSETALL)},
185 	{333,	0xffff0000,	0xff8f,		(OFFSET_SEL | REGCLRSETALL)},
186 	{589,	0xffff0000,	0xff8f,		(OFFSET_SEL | REGCLRSETALL)},
187 	{845,	0xffff0000,	0xff8f,		(OFFSET_SEL | REGCLRSETALL)},
188 	{1062,	0xffffff00,	0xff,		(OFFSET_SEL | REG4G | REG2G | F_CLRSET)},
189 	{1318,	0xffffff00,	0xff,		(OFFSET_SEL | REG4G | REG2G | F_CLRSET)},
190 	{1574,	0xffffff00,	0xff,		(OFFSET_SEL | REG4G | REG2G | F_CLRSET)},
191 	{1062,	0xffffff00,	0xfb,		(OFFSET_SEL | REG8G | F_CLRSET)},
192 	{1318,	0xffffff00,	0xfb,		(OFFSET_SEL | REG8G | F_CLRSET)},
193 	{1574,	0xffffff00,	0xfb,		(OFFSET_SEL | REG8G | F_CLRSET)},
194 	{1028,	0xffffffff,	0x1000000,	(OFFSET_SEL | REGCLRSETALL)},
195 	{1284,	0xffffffff,	0x1000000,	(OFFSET_SEL | REGCLRSETALL)},
196 	{1540,	0xffffffff,	0x1000000,	(OFFSET_SEL | REGCLRSETALL)},
197 	{1848,	0x0,		0x3cf07f8,	(OFFSET_SEL | REGSETALL)},
198 	{1849,	0x0,		0x3f,		(OFFSET_SEL | REGSETALL)},
199 	{1850,	0x0,		0x1fffff,	(OFFSET_SEL | REGSETALL)},
200 	{1851,	0x0,		0x060000,	(OFFSET_SEL | REGSETALL)},
201 	{130,	0x0000ffff,	0xffff0000,	(OFFSET_SEL | REGCLRSETALL)},
202 	{386,	0x0000ffff,	0xffff0000,	(OFFSET_SEL | REGCLRSETALL)},
203 	{642,	0x0000ffff,	0xffff0000,	(OFFSET_SEL | REGCLRSETALL)},
204 	{898,	0x0000ffff,	0xffff0000,	(OFFSET_SEL | REGCLRSETALL)},
205 	{131,	0xfffffff0,	0xf,		(OFFSET_SEL | REGCLRSETALL)},
206 	{387,	0xfffffff0,	0xf,		(OFFSET_SEL | REGCLRSETALL)},
207 	{643,	0xfffffff0,	0xf,		(OFFSET_SEL | REGCLRSETALL)},
208 	{899,	0xfffffff0,	0xf,		(OFFSET_SEL | REGCLRSETALL)},
209 	{29,	0xc0ffffff,	0x10000000,	(OFFSET_SEL | REGCLRSETALL)},
210 	{285,	0xc0ffffff,	0x10000000,	(OFFSET_SEL | REGCLRSETALL)},
211 	{541,	0xc0ffffff,	0x10000000,	(OFFSET_SEL | REGCLRSETALL)},
212 	{797,	0xc0ffffff,	0x10000000,	(OFFSET_SEL | REGCLRSETALL)},
213 	{30,	0xffffffff,	0x00080000,	(OFFSET_SEL | REGCLRSETALL)},
214 	{286,	0xffffffff,	0x00080000,	(OFFSET_SEL | REGCLRSETALL)},
215 	{542,	0xffffffff,	0x00080000,	(OFFSET_SEL | REGCLRSETALL)},
216 	{798,	0xffffffff,	0x00080000,	(OFFSET_SEL | REGCLRSETALL)},
217 	{31,	0xffffffc0,	0x00000010,	(OFFSET_SEL | REGCLRSETALL)},
218 	{287,	0xffffffc0,	0x00000010,	(OFFSET_SEL | REGCLRSETALL)},
219 	{543,	0xffffffc0,	0x00000010,	(OFFSET_SEL | REGCLRSETALL)},
220 	{799,	0xffffffc0,	0x00000010,	(OFFSET_SEL | REGCLRSETALL)},
221 	{1071,	0xfffffff0,	0x00000008,	(OFFSET_SEL | REGCLRSETALL)},
222 	{1327,	0xfffffff0,	0x00000008,	(OFFSET_SEL | REGCLRSETALL)},
223 	{1583,	0xfffffff0,	0x00000008,	(OFFSET_SEL | REGCLRSETALL)},
224 	{1808,	0xfffffff0,	0x00000008,	(OFFSET_SEL | REGCLRSETALL)},
225 	{1896,	0xfff0ffff,	0x00080000,	(OFFSET_SEL | REGCLRSETALL)},
226 };
227 
ddr_reg_set(u32 * reg,const struct ddr_reg_cfg * data,u32 len,u32 mask)228 void ddr_reg_set(u32 *reg, const struct ddr_reg_cfg *data,
229 		 u32 len, u32 mask)
230 {
231 	u32 *addr;
232 	u32 i;
233 
234 	for (i = 0; i < len; i++) {
235 		if (!(data[i].flag & mask))
236 			continue;
237 
238 		if (data[i].flag & OFFSET_SEL)
239 			addr = reg + PHY_AC_BASE_ADDR + data[i].offset;
240 		else
241 			addr = reg + PHY_BASE_ADDR + data[i].offset;
242 
243 		if (data[i].flag & F_CLRSET)
244 			DDR_REG_TRIGGER(addr, data[i].mask, data[i].val);
245 		else if (data[i].flag & F_SET)
246 			out_le32(addr, data[i].val);
247 		else
248 			out_le32(addr, in_le32(addr) + data[i].val);
249 	}
250 }
251 
ddr_phy_start(u32 * phyreg,enum ddr_size_t size)252 void ddr_phy_start(u32 *phyreg, enum ddr_size_t size)
253 {
254 	u32 len;
255 	u32 mask;
256 
257 	switch (size) {
258 	case DDR_SIZE_2G:
259 		mask = REG2G;
260 		break;
261 
262 	case DDR_SIZE_4G:
263 		mask = REG4G;
264 		break;
265 
266 	case DDR_SIZE_8G:
267 		mask = REG8G;
268 		break;
269 
270 	case DDR_SIZE_16G:
271 	default:
272 		return;
273 	};
274 
275 	len = ARRAY_SIZE(ddr_start_cfg);
276 	ddr_reg_set(phyreg, ddr_start_cfg, len, mask);
277 	out_le32(phyreg, 0x01);
278 }
279