xref: /linux/drivers/gpu/drm/ast/ast_2500.c (revision 260f6f4fda93c8485c8037865c941b42b9cba5d2)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright 2012 Red Hat Inc.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sub license, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19  * USE OR OTHER DEALINGS IN THE SOFTWARE.
20  *
21  * The above copyright notice and this permission notice (including the
22  * next paragraph) shall be included in all copies or substantial portions
23  * of the Software.
24  */
25 /*
26  * Authors: Dave Airlie <airlied@redhat.com>
27  */
28 
29 #include <linux/delay.h>
30 
31 #include <drm/drm_print.h>
32 
33 #include "ast_drv.h"
34 #include "ast_post.h"
35 
36 /*
37  * POST
38  */
39 
40 /*
41  * AST2500 DRAM settings modules
42  */
43 
44 #define REGTBL_NUM           17
45 #define REGIDX_010           0
46 #define REGIDX_014           1
47 #define REGIDX_018           2
48 #define REGIDX_020           3
49 #define REGIDX_024           4
50 #define REGIDX_02C           5
51 #define REGIDX_030           6
52 #define REGIDX_214           7
53 #define REGIDX_2E0           8
54 #define REGIDX_2E4           9
55 #define REGIDX_2E8           10
56 #define REGIDX_2EC           11
57 #define REGIDX_2F0           12
58 #define REGIDX_2F4           13
59 #define REGIDX_2F8           14
60 #define REGIDX_RFC           15
61 #define REGIDX_PLL           16
62 
63 static const u32 ast2500_ddr3_1600_timing_table[REGTBL_NUM] = {
64 	0x64604D38,		     /* 0x010 */
65 	0x29690599,		     /* 0x014 */
66 	0x00000300,		     /* 0x018 */
67 	0x00000000,		     /* 0x020 */
68 	0x00000000,		     /* 0x024 */
69 	0x02181E70,		     /* 0x02C */
70 	0x00000040,		     /* 0x030 */
71 	0x00000024,		     /* 0x214 */
72 	0x02001300,		     /* 0x2E0 */
73 	0x0E0000A0,		     /* 0x2E4 */
74 	0x000E001B,		     /* 0x2E8 */
75 	0x35B8C105,		     /* 0x2EC */
76 	0x08090408,		     /* 0x2F0 */
77 	0x9B000800,		     /* 0x2F4 */
78 	0x0E400A00,		     /* 0x2F8 */
79 	0x9971452F,		     /* tRFC  */
80 	0x000071C1		     /* PLL   */
81 };
82 
83 static const u32 ast2500_ddr4_1600_timing_table[REGTBL_NUM] = {
84 	0x63604E37,		     /* 0x010 */
85 	0xE97AFA99,		     /* 0x014 */
86 	0x00019000,		     /* 0x018 */
87 	0x08000000,		     /* 0x020 */
88 	0x00000400,		     /* 0x024 */
89 	0x00000410,		     /* 0x02C */
90 	0x00000101,		     /* 0x030 */
91 	0x00000024,		     /* 0x214 */
92 	0x03002900,		     /* 0x2E0 */
93 	0x0E0000A0,		     /* 0x2E4 */
94 	0x000E001C,		     /* 0x2E8 */
95 	0x35B8C106,		     /* 0x2EC */
96 	0x08080607,		     /* 0x2F0 */
97 	0x9B000900,		     /* 0x2F4 */
98 	0x0E400A00,		     /* 0x2F8 */
99 	0x99714545,		     /* tRFC  */
100 	0x000071C1		     /* PLL   */
101 };
102 
103 #define TIMEOUT              5000000
104 
ast_2500_patch_ahb(void __iomem * regs)105 void ast_2500_patch_ahb(void __iomem *regs)
106 {
107 	u32 data;
108 
109 	/* Clear bus lock condition */
110 	__ast_moutdwm(regs, 0x1e600000, 0xAEED1A03);
111 	__ast_moutdwm(regs, 0x1e600084, 0x00010000);
112 	__ast_moutdwm(regs, 0x1e600088, 0x00000000);
113 	__ast_moutdwm(regs, 0x1e6e2000, 0x1688A8A8);
114 
115 	data = __ast_mindwm(regs, 0x1e6e2070);
116 	if (data & 0x08000000) { /* check fast reset */
117 		/*
118 		 * If "Fast restet" is enabled for ARM-ICE debugger,
119 		 * then WDT needs to enable, that
120 		 * WDT04 is WDT#1 Reload reg.
121 		 * WDT08 is WDT#1 counter restart reg to avoid system deadlock
122 		 * WDT0C is WDT#1 control reg
123 		 *	[6:5]:= 01:Full chip
124 		 *	[4]:= 1:1MHz clock source
125 		 *	[1]:= 1:WDT will be cleeared and disabled after timeout occurs
126 		 *	[0]:= 1:WDT enable
127 		 */
128 		__ast_moutdwm(regs, 0x1E785004, 0x00000010);
129 		__ast_moutdwm(regs, 0x1E785008, 0x00004755);
130 		__ast_moutdwm(regs, 0x1E78500c, 0x00000033);
131 		udelay(1000);
132 	}
133 
134 	do {
135 		__ast_moutdwm(regs, 0x1e6e2000, 0x1688A8A8);
136 		data = __ast_mindwm(regs, 0x1e6e2000);
137 	} while (data != 1);
138 
139 	__ast_moutdwm(regs, 0x1e6e207c, 0x08000000); /* clear fast reset */
140 }
141 
mmc_test_single_2500(struct ast_device * ast,u32 datagen)142 static bool mmc_test_single_2500(struct ast_device *ast, u32 datagen)
143 {
144 	return mmc_test(ast, datagen, 0x85);
145 }
146 
cbr_test_2500(struct ast_device * ast)147 static bool cbr_test_2500(struct ast_device *ast)
148 {
149 	ast_moutdwm(ast, 0x1E6E0074, 0x0000FFFF);
150 	ast_moutdwm(ast, 0x1E6E007C, 0xFF00FF00);
151 	if (!mmc_test_burst(ast, 0))
152 		return false;
153 	if (!mmc_test_single_2500(ast, 0))
154 		return false;
155 	return true;
156 }
157 
ddr_test_2500(struct ast_device * ast)158 static bool ddr_test_2500(struct ast_device *ast)
159 {
160 	ast_moutdwm(ast, 0x1E6E0074, 0x0000FFFF);
161 	ast_moutdwm(ast, 0x1E6E007C, 0xFF00FF00);
162 	if (!mmc_test_burst(ast, 0))
163 		return false;
164 	if (!mmc_test_burst(ast, 1))
165 		return false;
166 	if (!mmc_test_burst(ast, 2))
167 		return false;
168 	if (!mmc_test_burst(ast, 3))
169 		return false;
170 	if (!mmc_test_single_2500(ast, 0))
171 		return false;
172 	return true;
173 }
174 
ddr_init_common_2500(struct ast_device * ast)175 static void ddr_init_common_2500(struct ast_device *ast)
176 {
177 	ast_moutdwm(ast, 0x1E6E0034, 0x00020080);
178 	ast_moutdwm(ast, 0x1E6E0008, 0x2003000F);
179 	ast_moutdwm(ast, 0x1E6E0038, 0x00000FFF);
180 	ast_moutdwm(ast, 0x1E6E0040, 0x88448844);
181 	ast_moutdwm(ast, 0x1E6E0044, 0x24422288);
182 	ast_moutdwm(ast, 0x1E6E0048, 0x22222222);
183 	ast_moutdwm(ast, 0x1E6E004C, 0x22222222);
184 	ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
185 	ast_moutdwm(ast, 0x1E6E0208, 0x00000000);
186 	ast_moutdwm(ast, 0x1E6E0218, 0x00000000);
187 	ast_moutdwm(ast, 0x1E6E0220, 0x00000000);
188 	ast_moutdwm(ast, 0x1E6E0228, 0x00000000);
189 	ast_moutdwm(ast, 0x1E6E0230, 0x00000000);
190 	ast_moutdwm(ast, 0x1E6E02A8, 0x00000000);
191 	ast_moutdwm(ast, 0x1E6E02B0, 0x00000000);
192 	ast_moutdwm(ast, 0x1E6E0240, 0x86000000);
193 	ast_moutdwm(ast, 0x1E6E0244, 0x00008600);
194 	ast_moutdwm(ast, 0x1E6E0248, 0x80000000);
195 	ast_moutdwm(ast, 0x1E6E024C, 0x80808080);
196 }
197 
ddr_phy_init_2500(struct ast_device * ast)198 static void ddr_phy_init_2500(struct ast_device *ast)
199 {
200 	u32 data, pass, timecnt;
201 
202 	pass = 0;
203 	ast_moutdwm(ast, 0x1E6E0060, 0x00000005);
204 	while (!pass) {
205 		for (timecnt = 0; timecnt < TIMEOUT; timecnt++) {
206 			data = ast_mindwm(ast, 0x1E6E0060) & 0x1;
207 			if (!data)
208 				break;
209 		}
210 		if (timecnt != TIMEOUT) {
211 			data = ast_mindwm(ast, 0x1E6E0300) & 0x000A0000;
212 			if (!data)
213 				pass = 1;
214 		}
215 		if (!pass) {
216 			ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
217 			udelay(10); /* delay 10 us */
218 			ast_moutdwm(ast, 0x1E6E0060, 0x00000005);
219 		}
220 	}
221 
222 	ast_moutdwm(ast, 0x1E6E0060, 0x00000006);
223 }
224 
225 /*
226  * Check DRAM Size
227  * 1Gb : 0x80000000 ~ 0x87FFFFFF
228  * 2Gb : 0x80000000 ~ 0x8FFFFFFF
229  * 4Gb : 0x80000000 ~ 0x9FFFFFFF
230  * 8Gb : 0x80000000 ~ 0xBFFFFFFF
231  */
check_dram_size_2500(struct ast_device * ast,u32 tRFC)232 static void check_dram_size_2500(struct ast_device *ast, u32 tRFC)
233 {
234 	u32 reg_04, reg_14;
235 
236 	reg_04 = ast_mindwm(ast, 0x1E6E0004) & 0xfffffffc;
237 	reg_14 = ast_mindwm(ast, 0x1E6E0014) & 0xffffff00;
238 
239 	ast_moutdwm(ast, 0xA0100000, 0x41424344);
240 	ast_moutdwm(ast, 0x90100000, 0x35363738);
241 	ast_moutdwm(ast, 0x88100000, 0x292A2B2C);
242 	ast_moutdwm(ast, 0x80100000, 0x1D1E1F10);
243 
244 	/* Check 8Gbit */
245 	if (ast_mindwm(ast, 0xA0100000) == 0x41424344) {
246 		reg_04 |= 0x03;
247 		reg_14 |= (tRFC >> 24) & 0xFF;
248 		/* Check 4Gbit */
249 	} else if (ast_mindwm(ast, 0x90100000) == 0x35363738) {
250 		reg_04 |= 0x02;
251 		reg_14 |= (tRFC >> 16) & 0xFF;
252 		/* Check 2Gbit */
253 	} else if (ast_mindwm(ast, 0x88100000) == 0x292A2B2C) {
254 		reg_04 |= 0x01;
255 		reg_14 |= (tRFC >> 8) & 0xFF;
256 	} else {
257 		reg_14 |= tRFC & 0xFF;
258 	}
259 	ast_moutdwm(ast, 0x1E6E0004, reg_04);
260 	ast_moutdwm(ast, 0x1E6E0014, reg_14);
261 }
262 
enable_cache_2500(struct ast_device * ast)263 static void enable_cache_2500(struct ast_device *ast)
264 {
265 	u32 reg_04, data;
266 
267 	reg_04 = ast_mindwm(ast, 0x1E6E0004);
268 	ast_moutdwm(ast, 0x1E6E0004, reg_04 | 0x1000);
269 
270 	do
271 		data = ast_mindwm(ast, 0x1E6E0004);
272 	while (!(data & 0x80000));
273 	ast_moutdwm(ast, 0x1E6E0004, reg_04 | 0x400);
274 }
275 
set_mpll_2500(struct ast_device * ast)276 static void set_mpll_2500(struct ast_device *ast)
277 {
278 	u32 addr, data, param;
279 
280 	/* Reset MMC */
281 	ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
282 	ast_moutdwm(ast, 0x1E6E0034, 0x00020080);
283 	for (addr = 0x1e6e0004; addr < 0x1e6e0090;) {
284 		ast_moutdwm(ast, addr, 0x0);
285 		addr += 4;
286 	}
287 	ast_moutdwm(ast, 0x1E6E0034, 0x00020000);
288 
289 	ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
290 	data = ast_mindwm(ast, 0x1E6E2070) & 0x00800000;
291 	if (data) {
292 		/* CLKIN = 25MHz */
293 		param = 0x930023E0;
294 		ast_moutdwm(ast, 0x1E6E2160, 0x00011320);
295 	} else {
296 		/* CLKIN = 24MHz */
297 		param = 0x93002400;
298 	}
299 	ast_moutdwm(ast, 0x1E6E2020, param);
300 	udelay(100);
301 }
302 
reset_mmc_2500(struct ast_device * ast)303 static void reset_mmc_2500(struct ast_device *ast)
304 {
305 	ast_moutdwm(ast, 0x1E78505C, 0x00000004);
306 	ast_moutdwm(ast, 0x1E785044, 0x00000001);
307 	ast_moutdwm(ast, 0x1E785048, 0x00004755);
308 	ast_moutdwm(ast, 0x1E78504C, 0x00000013);
309 	mdelay(100);
310 	ast_moutdwm(ast, 0x1E785054, 0x00000077);
311 	ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
312 }
313 
ddr3_init_2500(struct ast_device * ast,const u32 * ddr_table)314 static void ddr3_init_2500(struct ast_device *ast, const u32 *ddr_table)
315 {
316 	ast_moutdwm(ast, 0x1E6E0004, 0x00000303);
317 	ast_moutdwm(ast, 0x1E6E0010, ddr_table[REGIDX_010]);
318 	ast_moutdwm(ast, 0x1E6E0014, ddr_table[REGIDX_014]);
319 	ast_moutdwm(ast, 0x1E6E0018, ddr_table[REGIDX_018]);
320 	ast_moutdwm(ast, 0x1E6E0020, ddr_table[REGIDX_020]);	     /* MODEREG4/6 */
321 	ast_moutdwm(ast, 0x1E6E0024, ddr_table[REGIDX_024]);	     /* MODEREG5 */
322 	ast_moutdwm(ast, 0x1E6E002C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */
323 	ast_moutdwm(ast, 0x1E6E0030, ddr_table[REGIDX_030]);	     /* MODEREG1/3 */
324 
325 	/* DDR PHY Setting */
326 	ast_moutdwm(ast, 0x1E6E0200, 0x02492AAE);
327 	ast_moutdwm(ast, 0x1E6E0204, 0x00001001);
328 	ast_moutdwm(ast, 0x1E6E020C, 0x55E00B0B);
329 	ast_moutdwm(ast, 0x1E6E0210, 0x20000000);
330 	ast_moutdwm(ast, 0x1E6E0214, ddr_table[REGIDX_214]);
331 	ast_moutdwm(ast, 0x1E6E02E0, ddr_table[REGIDX_2E0]);
332 	ast_moutdwm(ast, 0x1E6E02E4, ddr_table[REGIDX_2E4]);
333 	ast_moutdwm(ast, 0x1E6E02E8, ddr_table[REGIDX_2E8]);
334 	ast_moutdwm(ast, 0x1E6E02EC, ddr_table[REGIDX_2EC]);
335 	ast_moutdwm(ast, 0x1E6E02F0, ddr_table[REGIDX_2F0]);
336 	ast_moutdwm(ast, 0x1E6E02F4, ddr_table[REGIDX_2F4]);
337 	ast_moutdwm(ast, 0x1E6E02F8, ddr_table[REGIDX_2F8]);
338 	ast_moutdwm(ast, 0x1E6E0290, 0x00100008);
339 	ast_moutdwm(ast, 0x1E6E02C0, 0x00000006);
340 
341 	/* Controller Setting */
342 	ast_moutdwm(ast, 0x1E6E0034, 0x00020091);
343 
344 	/* Wait DDR PHY init done */
345 	ddr_phy_init_2500(ast);
346 
347 	ast_moutdwm(ast, 0x1E6E0120, ddr_table[REGIDX_PLL]);
348 	ast_moutdwm(ast, 0x1E6E000C, 0x42AA5C81);
349 	ast_moutdwm(ast, 0x1E6E0034, 0x0001AF93);
350 
351 	check_dram_size_2500(ast, ddr_table[REGIDX_RFC]);
352 	enable_cache_2500(ast);
353 	ast_moutdwm(ast, 0x1E6E001C, 0x00000008);
354 	ast_moutdwm(ast, 0x1E6E0038, 0xFFFFFF00);
355 }
356 
ddr4_init_2500(struct ast_device * ast,const u32 * ddr_table)357 static void ddr4_init_2500(struct ast_device *ast, const u32 *ddr_table)
358 {
359 	u32 data, data2, pass, retrycnt;
360 	u32 ddr_vref, phy_vref;
361 	u32 min_ddr_vref = 0, min_phy_vref = 0;
362 	u32 max_ddr_vref = 0, max_phy_vref = 0;
363 
364 	ast_moutdwm(ast, 0x1E6E0004, 0x00000313);
365 	ast_moutdwm(ast, 0x1E6E0010, ddr_table[REGIDX_010]);
366 	ast_moutdwm(ast, 0x1E6E0014, ddr_table[REGIDX_014]);
367 	ast_moutdwm(ast, 0x1E6E0018, ddr_table[REGIDX_018]);
368 	ast_moutdwm(ast, 0x1E6E0020, ddr_table[REGIDX_020]);	     /* MODEREG4/6 */
369 	ast_moutdwm(ast, 0x1E6E0024, ddr_table[REGIDX_024]);	     /* MODEREG5 */
370 	ast_moutdwm(ast, 0x1E6E002C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */
371 	ast_moutdwm(ast, 0x1E6E0030, ddr_table[REGIDX_030]);	     /* MODEREG1/3 */
372 
373 	/* DDR PHY Setting */
374 	ast_moutdwm(ast, 0x1E6E0200, 0x42492AAE);
375 	ast_moutdwm(ast, 0x1E6E0204, 0x09002000);
376 	ast_moutdwm(ast, 0x1E6E020C, 0x55E00B0B);
377 	ast_moutdwm(ast, 0x1E6E0210, 0x20000000);
378 	ast_moutdwm(ast, 0x1E6E0214, ddr_table[REGIDX_214]);
379 	ast_moutdwm(ast, 0x1E6E02E0, ddr_table[REGIDX_2E0]);
380 	ast_moutdwm(ast, 0x1E6E02E4, ddr_table[REGIDX_2E4]);
381 	ast_moutdwm(ast, 0x1E6E02E8, ddr_table[REGIDX_2E8]);
382 	ast_moutdwm(ast, 0x1E6E02EC, ddr_table[REGIDX_2EC]);
383 	ast_moutdwm(ast, 0x1E6E02F0, ddr_table[REGIDX_2F0]);
384 	ast_moutdwm(ast, 0x1E6E02F4, ddr_table[REGIDX_2F4]);
385 	ast_moutdwm(ast, 0x1E6E02F8, ddr_table[REGIDX_2F8]);
386 	ast_moutdwm(ast, 0x1E6E0290, 0x00100008);
387 	ast_moutdwm(ast, 0x1E6E02C4, 0x3C183C3C);
388 	ast_moutdwm(ast, 0x1E6E02C8, 0x00631E0E);
389 
390 	/* Controller Setting */
391 	ast_moutdwm(ast, 0x1E6E0034, 0x0001A991);
392 
393 	/* Train PHY Vref first */
394 	pass = 0;
395 
396 	for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) {
397 		max_phy_vref = 0x0;
398 		pass = 0;
399 		ast_moutdwm(ast, 0x1E6E02C0, 0x00001C06);
400 		for (phy_vref = 0x40; phy_vref < 0x80; phy_vref++) {
401 			ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
402 			ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
403 			ast_moutdwm(ast, 0x1E6E02CC, phy_vref | (phy_vref << 8));
404 			/* Fire DFI Init */
405 			ddr_phy_init_2500(ast);
406 			ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
407 			if (cbr_test_2500(ast)) {
408 				pass++;
409 				data = ast_mindwm(ast, 0x1E6E03D0);
410 				data2 = data >> 8;
411 				data  = data & 0xff;
412 				if (data > data2)
413 					data = data2;
414 				if (max_phy_vref < data) {
415 					max_phy_vref = data;
416 					min_phy_vref = phy_vref;
417 				}
418 			} else if (pass > 0) {
419 				break;
420 			}
421 		}
422 	}
423 	ast_moutdwm(ast, 0x1E6E02CC, min_phy_vref | (min_phy_vref << 8));
424 
425 	/* Train DDR Vref next */
426 	pass = 0;
427 
428 	for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) {
429 		min_ddr_vref = 0xFF;
430 		max_ddr_vref = 0x0;
431 		pass = 0;
432 		for (ddr_vref = 0x00; ddr_vref < 0x40; ddr_vref++) {
433 			ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
434 			ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
435 			ast_moutdwm(ast, 0x1E6E02C0, 0x00000006 | (ddr_vref << 8));
436 			/* Fire DFI Init */
437 			ddr_phy_init_2500(ast);
438 			ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
439 			if (cbr_test_2500(ast)) {
440 				pass++;
441 				if (min_ddr_vref > ddr_vref)
442 					min_ddr_vref = ddr_vref;
443 				if (max_ddr_vref < ddr_vref)
444 					max_ddr_vref = ddr_vref;
445 			} else if (pass != 0) {
446 				break;
447 			}
448 		}
449 	}
450 
451 	ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
452 	ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
453 	ddr_vref = (min_ddr_vref + max_ddr_vref + 1) >> 1;
454 	ast_moutdwm(ast, 0x1E6E02C0, 0x00000006 | (ddr_vref << 8));
455 
456 	/* Wait DDR PHY init done */
457 	ddr_phy_init_2500(ast);
458 
459 	ast_moutdwm(ast, 0x1E6E0120, ddr_table[REGIDX_PLL]);
460 	ast_moutdwm(ast, 0x1E6E000C, 0x42AA5C81);
461 	ast_moutdwm(ast, 0x1E6E0034, 0x0001AF93);
462 
463 	check_dram_size_2500(ast, ddr_table[REGIDX_RFC]);
464 	enable_cache_2500(ast);
465 	ast_moutdwm(ast, 0x1E6E001C, 0x00000008);
466 	ast_moutdwm(ast, 0x1E6E0038, 0xFFFFFF00);
467 }
468 
ast_dram_init_2500(struct ast_device * ast)469 static bool ast_dram_init_2500(struct ast_device *ast)
470 {
471 	u32 data;
472 	u32 max_tries = 5;
473 
474 	do {
475 		if (max_tries-- == 0)
476 			return false;
477 		set_mpll_2500(ast);
478 		reset_mmc_2500(ast);
479 		ddr_init_common_2500(ast);
480 
481 		data = ast_mindwm(ast, 0x1E6E2070);
482 		if (data & 0x01000000)
483 			ddr4_init_2500(ast, ast2500_ddr4_1600_timing_table);
484 		else
485 			ddr3_init_2500(ast, ast2500_ddr3_1600_timing_table);
486 	} while (!ddr_test_2500(ast));
487 
488 	ast_moutdwm(ast, 0x1E6E2040, ast_mindwm(ast, 0x1E6E2040) | 0x41);
489 
490 	/* Patch code */
491 	data = ast_mindwm(ast, 0x1E6E200C) & 0xF9FFFFFF;
492 	ast_moutdwm(ast, 0x1E6E200C, data | 0x10000000);
493 
494 	return true;
495 }
496 
ast_post_chip_2500(struct ast_device * ast)497 static void ast_post_chip_2500(struct ast_device *ast)
498 {
499 	struct drm_device *dev = &ast->base;
500 	u32 temp;
501 	u8 reg;
502 
503 	reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
504 	if ((reg & AST_IO_VGACRD0_VRAM_INIT_STATUS_MASK) == 0) {/* vga only */
505 		/* Clear bus lock condition */
506 		ast_2500_patch_ahb(ast->regs);
507 
508 		/* Disable watchdog */
509 		ast_moutdwm(ast, 0x1E78502C, 0x00000000);
510 		ast_moutdwm(ast, 0x1E78504C, 0x00000000);
511 
512 		/*
513 		 * Reset USB port to patch USB unknown device issue
514 		 * SCU90 is Multi-function Pin Control #5
515 		 *	[29]:= 1:Enable USB2.0 Host port#1 (that the mutually shared USB2.0 Hub
516 		 *				port).
517 		 * SCU94 is Multi-function Pin Control #6
518 		 *	[14:13]:= 1x:USB2.0 Host2 controller
519 		 * SCU70 is Hardware Strap reg
520 		 *	[23]:= 1:CLKIN is 25MHz and USBCK1 = 24/48 MHz (determined by
521 		 *				[18]: 0(24)/1(48) MHz)
522 		 * SCU7C is Write clear reg to SCU70
523 		 *	[23]:= write 1 and then SCU70[23] will be clear as 0b.
524 		 */
525 		ast_moutdwm(ast, 0x1E6E2090, 0x20000000);
526 		ast_moutdwm(ast, 0x1E6E2094, 0x00004000);
527 		if (ast_mindwm(ast, 0x1E6E2070) & 0x00800000) {
528 			ast_moutdwm(ast, 0x1E6E207C, 0x00800000);
529 			mdelay(100);
530 			ast_moutdwm(ast, 0x1E6E2070, 0x00800000);
531 		}
532 		/* Modify eSPI reset pin */
533 		temp = ast_mindwm(ast, 0x1E6E2070);
534 		if (temp & 0x02000000)
535 			ast_moutdwm(ast, 0x1E6E207C, 0x00004000);
536 
537 		/* Slow down CPU/AHB CLK in VGA only mode */
538 		temp = ast_read32(ast, 0x12008);
539 		temp |= 0x73;
540 		ast_write32(ast, 0x12008, temp);
541 
542 		if (!ast_dram_init_2500(ast))
543 			drm_err(dev, "DRAM init failed !\n");
544 
545 		temp = ast_mindwm(ast, 0x1e6e2040);
546 		ast_moutdwm(ast, 0x1e6e2040, temp | 0x40);
547 	}
548 
549 	/* wait ready */
550 	do {
551 		reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
552 	} while ((reg & 0x40) == 0);
553 }
554 
ast_2500_post(struct ast_device * ast)555 int ast_2500_post(struct ast_device *ast)
556 {
557 	ast_2300_set_def_ext_reg(ast);
558 
559 	if (ast->config_mode == ast_use_p2a) {
560 		ast_post_chip_2500(ast);
561 	} else {
562 		if (ast->tx_chip == AST_TX_SIL164) {
563 			/* Enable DVO */
564 			ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80);
565 		}
566 	}
567 
568 	return 0;
569 }
570