xref: /linux/drivers/gpu/drm/ast/ast_2500.c (revision bba2c3615bd6cfee7456d1130f2e6b01b3f4e9ba)
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 #include <linux/pci.h>
31 
32 #include <drm/drm_drv.h>
33 #include <drm/drm_print.h>
34 
35 #include "ast_drv.h"
36 #include "ast_post.h"
37 
38 /*
39  * POST
40  */
41 
42 /*
43  * AST2500 DRAM settings modules
44  */
45 
46 #define REGTBL_NUM           17
47 #define REGIDX_010           0
48 #define REGIDX_014           1
49 #define REGIDX_018           2
50 #define REGIDX_020           3
51 #define REGIDX_024           4
52 #define REGIDX_02C           5
53 #define REGIDX_030           6
54 #define REGIDX_214           7
55 #define REGIDX_2E0           8
56 #define REGIDX_2E4           9
57 #define REGIDX_2E8           10
58 #define REGIDX_2EC           11
59 #define REGIDX_2F0           12
60 #define REGIDX_2F4           13
61 #define REGIDX_2F8           14
62 #define REGIDX_RFC           15
63 #define REGIDX_PLL           16
64 
65 static const u32 ast2500_ddr3_1600_timing_table[REGTBL_NUM] = {
66 	0x64604D38,		     /* 0x010 */
67 	0x29690599,		     /* 0x014 */
68 	0x00000300,		     /* 0x018 */
69 	0x00000000,		     /* 0x020 */
70 	0x00000000,		     /* 0x024 */
71 	0x02181E70,		     /* 0x02C */
72 	0x00000040,		     /* 0x030 */
73 	0x00000024,		     /* 0x214 */
74 	0x02001300,		     /* 0x2E0 */
75 	0x0E0000A0,		     /* 0x2E4 */
76 	0x000E001B,		     /* 0x2E8 */
77 	0x35B8C105,		     /* 0x2EC */
78 	0x08090408,		     /* 0x2F0 */
79 	0x9B000800,		     /* 0x2F4 */
80 	0x0E400A00,		     /* 0x2F8 */
81 	0x9971452F,		     /* tRFC  */
82 	0x000071C1		     /* PLL   */
83 };
84 
85 static const u32 ast2500_ddr4_1600_timing_table[REGTBL_NUM] = {
86 	0x63604E37,		     /* 0x010 */
87 	0xE97AFA99,		     /* 0x014 */
88 	0x00019000,		     /* 0x018 */
89 	0x08000000,		     /* 0x020 */
90 	0x00000400,		     /* 0x024 */
91 	0x00000410,		     /* 0x02C */
92 	0x00000101,		     /* 0x030 */
93 	0x00000024,		     /* 0x214 */
94 	0x03002900,		     /* 0x2E0 */
95 	0x0E0000A0,		     /* 0x2E4 */
96 	0x000E001C,		     /* 0x2E8 */
97 	0x35B8C106,		     /* 0x2EC */
98 	0x08080607,		     /* 0x2F0 */
99 	0x9B000900,		     /* 0x2F4 */
100 	0x0E400A00,		     /* 0x2F8 */
101 	0x99714545,		     /* tRFC  */
102 	0x000071C1		     /* PLL   */
103 };
104 
105 #define TIMEOUT              5000000
106 
107 void ast_2500_patch_ahb(void __iomem *regs)
108 {
109 	u32 data;
110 
111 	/* Clear bus lock condition */
112 	__ast_moutdwm(regs, AST_REG_AHBC00, AST_REG_AHBC00_PROTECT_KEY);
113 	__ast_moutdwm(regs, AST_REG_AHBC84, 0x00010000);
114 	__ast_moutdwm(regs, AST_REG_AHBC88, 0x00000000);
115 	__ast_moutdwm(regs, AST_REG_SCU000, AST_REG_SCU000_PROTECTION_KEY);
116 
117 	data = __ast_mindwm(regs, AST_REG_SCU070);
118 	if (data & 0x08000000) { /* check fast reset */
119 		/*
120 		 * If "Fast restet" is enabled for ARM-ICE debugger,
121 		 * then WDT needs to enable, that
122 		 * WDT04 is WDT#1 Reload reg.
123 		 * WDT08 is WDT#1 counter restart reg to avoid system deadlock
124 		 * WDT0C is WDT#1 control reg
125 		 *	[6:5]:= 01:Full chip
126 		 *	[4]:= 1:1MHz clock source
127 		 *	[1]:= 1:WDT will be cleeared and disabled after timeout occurs
128 		 *	[0]:= 1:WDT enable
129 		 */
130 		__ast_moutdwm(regs, AST_REG_WDT04(0), 0x00000010);
131 		__ast_moutdwm(regs, AST_REG_WDT08(0), 0x00004755);
132 		__ast_moutdwm(regs, AST_REG_WDT0C(0), 0x00000033);
133 		udelay(1000);
134 	}
135 
136 	do {
137 		__ast_moutdwm(regs, AST_REG_SCU000, AST_REG_SCU000_PROTECTION_KEY);
138 		data = __ast_mindwm(regs, AST_REG_SCU000);
139 	} while (data != 1);
140 
141 	__ast_moutdwm(regs, AST_REG_SCU07C, 0x08000000); /* clear fast reset */
142 }
143 
144 static bool mmc_test_single_2500(struct ast_device *ast, u32 datagen)
145 {
146 	return mmc_test(ast, datagen, 0x85);
147 }
148 
149 static bool cbr_test_2500(struct ast_device *ast)
150 {
151 	ast_moutdwm(ast, AST_REG_MCR74, 0x0000FFFF);
152 	ast_moutdwm(ast, AST_REG_MCR7C, 0xFF00FF00);
153 	if (!mmc_test_burst(ast, 0))
154 		return false;
155 	if (!mmc_test_single_2500(ast, 0))
156 		return false;
157 	return true;
158 }
159 
160 static bool ddr_test_2500(struct ast_device *ast)
161 {
162 	ast_moutdwm(ast, AST_REG_MCR74, 0x0000FFFF);
163 	ast_moutdwm(ast, AST_REG_MCR7C, 0xFF00FF00);
164 	if (!mmc_test_burst(ast, 0))
165 		return false;
166 	if (!mmc_test_burst(ast, 1))
167 		return false;
168 	if (!mmc_test_burst(ast, 2))
169 		return false;
170 	if (!mmc_test_burst(ast, 3))
171 		return false;
172 	if (!mmc_test_single_2500(ast, 0))
173 		return false;
174 	return true;
175 }
176 
177 static void ddr_init_common_2500(struct ast_device *ast)
178 {
179 	ast_moutdwm(ast, AST_REG_MCR34, 0x00020080);
180 	ast_moutdwm(ast, AST_REG_MCR08, 0x2003000F);
181 	ast_moutdwm(ast, AST_REG_MCR38, 0x00000FFF);
182 	ast_moutdwm(ast, AST_REG_MCR40, 0x88448844);
183 	ast_moutdwm(ast, AST_REG_MCR44, 0x24422288);
184 	ast_moutdwm(ast, AST_REG_MCR48, 0x22222222);
185 	ast_moutdwm(ast, AST_REG_MCR4C, 0x22222222);
186 	ast_moutdwm(ast, AST_REG_MCR50, 0x80000000);
187 	ast_moutdwm(ast, AST_REG_MCR208, 0x00000000);
188 	ast_moutdwm(ast, AST_REG_MCR218, 0x00000000);
189 	ast_moutdwm(ast, AST_REG_MCR220, 0x00000000);
190 	ast_moutdwm(ast, AST_REG_MCR228, 0x00000000);
191 	ast_moutdwm(ast, AST_REG_MCR230, 0x00000000);
192 	ast_moutdwm(ast, AST_REG_MCR2A8, 0x00000000);
193 	ast_moutdwm(ast, AST_REG_MCR2B0, 0x00000000);
194 	ast_moutdwm(ast, AST_REG_MCR240, 0x86000000);
195 	ast_moutdwm(ast, AST_REG_MCR244, 0x00008600);
196 	ast_moutdwm(ast, AST_REG_MCR248, 0x80000000);
197 	ast_moutdwm(ast, AST_REG_MCR24C, 0x80808080);
198 }
199 
200 static void ddr_phy_init_2500(struct ast_device *ast)
201 {
202 	u32 data, pass, timecnt;
203 
204 	pass = 0;
205 	ast_moutdwm(ast, AST_REG_MCR60, 0x00000005);
206 	while (!pass) {
207 		for (timecnt = 0; timecnt < TIMEOUT; timecnt++) {
208 			data = ast_mindwm(ast, AST_REG_MCR60) & 0x1;
209 			if (!data)
210 				break;
211 		}
212 		if (timecnt != TIMEOUT) {
213 			data = ast_mindwm(ast, AST_REG_MCR300) & 0x000A0000;
214 			if (!data)
215 				pass = 1;
216 		}
217 		if (!pass) {
218 			ast_moutdwm(ast, AST_REG_MCR60, 0x00000000);
219 			udelay(10); /* delay 10 us */
220 			ast_moutdwm(ast, AST_REG_MCR60, 0x00000005);
221 		}
222 	}
223 
224 	ast_moutdwm(ast, AST_REG_MCR60, 0x00000006);
225 }
226 
227 /*
228  * TODO: Review and fix the comments. The function below only detects
229  *       up to 1 GiB of SDRAM.
230  *
231  * Check DRAM Size
232  * 1Gb : 0x80000000 ~ 0x87FFFFFF
233  * 2Gb : 0x80000000 ~ 0x8FFFFFFF
234  * 4Gb : 0x80000000 ~ 0x9FFFFFFF
235  * 8Gb : 0x80000000 ~ 0xBFFFFFFF
236  */
237 static void check_dram_size_2500(struct ast_device *ast, u32 tRFC)
238 {
239 	u32 reg_04, reg_14;
240 
241 	reg_04 = ast_mindwm(ast, AST_REG_MCR04) & 0xfffffffc;
242 	reg_14 = ast_mindwm(ast, AST_REG_MCR14) & 0xffffff00;
243 
244 	ast_moutdwm(ast, AST_SDRAM(0x20100000), 0x41424344);
245 	ast_moutdwm(ast, AST_SDRAM(0x10100000), 0x35363738);
246 	ast_moutdwm(ast, AST_SDRAM(0x08100000), 0x292A2B2C);
247 	ast_moutdwm(ast, AST_SDRAM(0x00100000), 0x1D1E1F10);
248 
249 	/* Check 8Gbit */
250 	if (ast_mindwm(ast, AST_SDRAM(0x20100000)) == 0x41424344) {
251 		reg_04 |= 0x03;
252 		reg_14 |= (tRFC >> 24) & 0xFF;
253 		/* Check 4Gbit */
254 	} else if (ast_mindwm(ast, AST_SDRAM(0x10100000)) == 0x35363738) {
255 		reg_04 |= 0x02;
256 		reg_14 |= (tRFC >> 16) & 0xFF;
257 		/* Check 2Gbit */
258 	} else if (ast_mindwm(ast, AST_SDRAM(0x08100000)) == 0x292A2B2C) {
259 		reg_04 |= 0x01;
260 		reg_14 |= (tRFC >> 8) & 0xFF;
261 	} else {
262 		reg_14 |= tRFC & 0xFF;
263 	}
264 	ast_moutdwm(ast, AST_REG_MCR04, reg_04);
265 	ast_moutdwm(ast, AST_REG_MCR14, reg_14);
266 }
267 
268 static void enable_cache_2500(struct ast_device *ast)
269 {
270 	u32 reg_04, data;
271 
272 	reg_04 = ast_mindwm(ast, AST_REG_MCR04);
273 	ast_moutdwm(ast, AST_REG_MCR04, reg_04 | 0x1000);
274 
275 	do
276 		data = ast_mindwm(ast, AST_REG_MCR04);
277 	while (!(data & 0x80000));
278 	ast_moutdwm(ast, AST_REG_MCR04, reg_04 | 0x400);
279 }
280 
281 static void set_mpll_2500(struct ast_device *ast)
282 {
283 	u32 mcr, data, param;
284 
285 	/* Reset MMC */
286 	ast_moutdwm(ast, AST_REG_MCR00, AST_REG_MCR00_PROTECTION_KEY);
287 	ast_moutdwm(ast, AST_REG_MCR34, 0x00020080);
288 	for (mcr = AST_REG_MCR04; mcr <= AST_REG_MCR8C; mcr += 4)
289 		ast_moutdwm(ast, mcr, 0x00000000);
290 	ast_moutdwm(ast, AST_REG_MCR34, 0x00020000);
291 
292 	ast_moutdwm(ast, AST_REG_SCU000, AST_REG_SCU000_PROTECTION_KEY);
293 	data = ast_mindwm(ast, AST_REG_SCU070) & 0x00800000;
294 	if (data) {
295 		/* CLKIN = 25MHz */
296 		param = 0x930023E0;
297 		ast_moutdwm(ast, AST_REG_SCU160, 0x00011320);
298 	} else {
299 		/* CLKIN = 24MHz */
300 		param = 0x93002400;
301 	}
302 	ast_moutdwm(ast, AST_REG_SCU020, param);
303 	udelay(100);
304 }
305 
306 static void reset_mmc_2500(struct ast_device *ast)
307 {
308 	ast_moutdwm(ast, AST_REG_WDT1C(1), 0x00000004);
309 	ast_moutdwm(ast, AST_REG_WDT04(1), 0x00000001);
310 	ast_moutdwm(ast, AST_REG_WDT08(1), 0x00004755);
311 	ast_moutdwm(ast, AST_REG_WDT0C(1), 0x00000013);
312 	mdelay(100);
313 	ast_moutdwm(ast, AST_REG_WDT14(1), 0x00000077);
314 	ast_moutdwm(ast, AST_REG_MCR00, AST_REG_MCR00_PROTECTION_KEY);
315 }
316 
317 static void ddr3_init_2500(struct ast_device *ast, const u32 *ddr_table)
318 {
319 	ast_moutdwm(ast, AST_REG_MCR04, 0x00000303);
320 	ast_moutdwm(ast, AST_REG_MCR10, ddr_table[REGIDX_010]);
321 	ast_moutdwm(ast, AST_REG_MCR14, ddr_table[REGIDX_014]);
322 	ast_moutdwm(ast, AST_REG_MCR18, ddr_table[REGIDX_018]);
323 	ast_moutdwm(ast, AST_REG_MCR20, ddr_table[REGIDX_020]);	     /* MODEREG4/6 */
324 	ast_moutdwm(ast, AST_REG_MCR24, ddr_table[REGIDX_024]);	     /* MODEREG5 */
325 	ast_moutdwm(ast, AST_REG_MCR2C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */
326 	ast_moutdwm(ast, AST_REG_MCR30, ddr_table[REGIDX_030]);	     /* MODEREG1/3 */
327 
328 	/* DDR PHY Setting */
329 	ast_moutdwm(ast, AST_REG_MCR200, 0x02492AAE);
330 	ast_moutdwm(ast, AST_REG_MCR204, 0x00001001);
331 	ast_moutdwm(ast, AST_REG_MCR20C, 0x55E00B0B);
332 	ast_moutdwm(ast, AST_REG_MCR210, 0x20000000);
333 	ast_moutdwm(ast, AST_REG_MCR214, ddr_table[REGIDX_214]);
334 	ast_moutdwm(ast, AST_REG_MCR2E0, ddr_table[REGIDX_2E0]);
335 	ast_moutdwm(ast, AST_REG_MCR2E4, ddr_table[REGIDX_2E4]);
336 	ast_moutdwm(ast, AST_REG_MCR2E8, ddr_table[REGIDX_2E8]);
337 	ast_moutdwm(ast, AST_REG_MCR2EC, ddr_table[REGIDX_2EC]);
338 	ast_moutdwm(ast, AST_REG_MCR2F0, ddr_table[REGIDX_2F0]);
339 	ast_moutdwm(ast, AST_REG_MCR2F4, ddr_table[REGIDX_2F4]);
340 	ast_moutdwm(ast, AST_REG_MCR2F8, ddr_table[REGIDX_2F8]);
341 	ast_moutdwm(ast, AST_REG_MCR290, 0x00100008);
342 	ast_moutdwm(ast, AST_REG_MCR2C0, 0x00000006);
343 
344 	/* Controller Setting */
345 	ast_moutdwm(ast, AST_REG_MCR34, 0x00020091);
346 
347 	/* Wait DDR PHY init done */
348 	ddr_phy_init_2500(ast);
349 
350 	ast_moutdwm(ast, AST_REG_MCR120, ddr_table[REGIDX_PLL]);
351 	ast_moutdwm(ast, AST_REG_MCR0C, 0x42AA5C81);
352 	ast_moutdwm(ast, AST_REG_MCR34, 0x0001AF93);
353 
354 	check_dram_size_2500(ast, ddr_table[REGIDX_RFC]);
355 	enable_cache_2500(ast);
356 	ast_moutdwm(ast, AST_REG_MCR1C, 0x00000008);
357 	ast_moutdwm(ast, AST_REG_MCR38, 0xFFFFFF00);
358 }
359 
360 static void ddr4_init_2500(struct ast_device *ast, const u32 *ddr_table)
361 {
362 	u32 data, data2, pass, retrycnt;
363 	u32 ddr_vref, phy_vref;
364 	u32 min_ddr_vref = 0, min_phy_vref = 0;
365 	u32 max_ddr_vref = 0, max_phy_vref = 0;
366 
367 	ast_moutdwm(ast, AST_REG_MCR04, 0x00000313);
368 	ast_moutdwm(ast, AST_REG_MCR10, ddr_table[REGIDX_010]);
369 	ast_moutdwm(ast, AST_REG_MCR14, ddr_table[REGIDX_014]);
370 	ast_moutdwm(ast, AST_REG_MCR18, ddr_table[REGIDX_018]);
371 	ast_moutdwm(ast, AST_REG_MCR20, ddr_table[REGIDX_020]);	     /* MODEREG4/6 */
372 	ast_moutdwm(ast, AST_REG_MCR24, ddr_table[REGIDX_024]);	     /* MODEREG5 */
373 	ast_moutdwm(ast, AST_REG_MCR2C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */
374 	ast_moutdwm(ast, AST_REG_MCR30, ddr_table[REGIDX_030]);	     /* MODEREG1/3 */
375 
376 	/* DDR PHY Setting */
377 	ast_moutdwm(ast, AST_REG_MCR200, 0x42492AAE);
378 	ast_moutdwm(ast, AST_REG_MCR204, 0x09002000);
379 	ast_moutdwm(ast, AST_REG_MCR20C, 0x55E00B0B);
380 	ast_moutdwm(ast, AST_REG_MCR210, 0x20000000);
381 	ast_moutdwm(ast, AST_REG_MCR214, ddr_table[REGIDX_214]);
382 	ast_moutdwm(ast, AST_REG_MCR2E0, ddr_table[REGIDX_2E0]);
383 	ast_moutdwm(ast, AST_REG_MCR2E4, ddr_table[REGIDX_2E4]);
384 	ast_moutdwm(ast, AST_REG_MCR2E8, ddr_table[REGIDX_2E8]);
385 	ast_moutdwm(ast, AST_REG_MCR2EC, ddr_table[REGIDX_2EC]);
386 	ast_moutdwm(ast, AST_REG_MCR2F0, ddr_table[REGIDX_2F0]);
387 	ast_moutdwm(ast, AST_REG_MCR2F4, ddr_table[REGIDX_2F4]);
388 	ast_moutdwm(ast, AST_REG_MCR2F8, ddr_table[REGIDX_2F8]);
389 	ast_moutdwm(ast, AST_REG_MCR290, 0x00100008);
390 	ast_moutdwm(ast, AST_REG_MCR2C4, 0x3C183C3C);
391 	ast_moutdwm(ast, AST_REG_MCR2C8, 0x00631E0E);
392 
393 	/* Controller Setting */
394 	ast_moutdwm(ast, AST_REG_MCR34, 0x0001A991);
395 
396 	/* Train PHY Vref first */
397 	pass = 0;
398 
399 	for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) {
400 		max_phy_vref = 0x0;
401 		pass = 0;
402 		ast_moutdwm(ast, AST_REG_MCR2C0, 0x00001C06);
403 		for (phy_vref = 0x40; phy_vref < 0x80; phy_vref++) {
404 			ast_moutdwm(ast, AST_REG_MCR0C, 0x00000000);
405 			ast_moutdwm(ast, AST_REG_MCR60, 0x00000000);
406 			ast_moutdwm(ast, AST_REG_MCR2CC, phy_vref | (phy_vref << 8));
407 			/* Fire DFI Init */
408 			ddr_phy_init_2500(ast);
409 			ast_moutdwm(ast, AST_REG_MCR0C, 0x00005C01);
410 			if (cbr_test_2500(ast)) {
411 				pass++;
412 				data = ast_mindwm(ast, AST_REG_MCR3D0);
413 				data2 = data >> 8;
414 				data  = data & 0xff;
415 				if (data > data2)
416 					data = data2;
417 				if (max_phy_vref < data) {
418 					max_phy_vref = data;
419 					min_phy_vref = phy_vref;
420 				}
421 			} else if (pass > 0) {
422 				break;
423 			}
424 		}
425 	}
426 	ast_moutdwm(ast, AST_REG_MCR2CC, min_phy_vref | (min_phy_vref << 8));
427 
428 	/* Train DDR Vref next */
429 	pass = 0;
430 
431 	for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) {
432 		min_ddr_vref = 0xFF;
433 		max_ddr_vref = 0x0;
434 		pass = 0;
435 		for (ddr_vref = 0x00; ddr_vref < 0x40; ddr_vref++) {
436 			ast_moutdwm(ast, AST_REG_MCR0C, 0x00000000);
437 			ast_moutdwm(ast, AST_REG_MCR60, 0x00000000);
438 			ast_moutdwm(ast, AST_REG_MCR2C0, 0x00000006 | (ddr_vref << 8));
439 			/* Fire DFI Init */
440 			ddr_phy_init_2500(ast);
441 			ast_moutdwm(ast, AST_REG_MCR0C, 0x00005C01);
442 			if (cbr_test_2500(ast)) {
443 				pass++;
444 				if (min_ddr_vref > ddr_vref)
445 					min_ddr_vref = ddr_vref;
446 				if (max_ddr_vref < ddr_vref)
447 					max_ddr_vref = ddr_vref;
448 			} else if (pass != 0) {
449 				break;
450 			}
451 		}
452 	}
453 
454 	ast_moutdwm(ast, AST_REG_MCR0C, 0x00000000);
455 	ast_moutdwm(ast, AST_REG_MCR60, 0x00000000);
456 	ddr_vref = (min_ddr_vref + max_ddr_vref + 1) >> 1;
457 	ast_moutdwm(ast, AST_REG_MCR2C0, 0x00000006 | (ddr_vref << 8));
458 
459 	/* Wait DDR PHY init done */
460 	ddr_phy_init_2500(ast);
461 
462 	ast_moutdwm(ast, AST_REG_MCR120, ddr_table[REGIDX_PLL]);
463 	ast_moutdwm(ast, AST_REG_MCR0C, 0x42AA5C81);
464 	ast_moutdwm(ast, AST_REG_MCR34, 0x0001AF93);
465 
466 	check_dram_size_2500(ast, ddr_table[REGIDX_RFC]);
467 	enable_cache_2500(ast);
468 	ast_moutdwm(ast, AST_REG_MCR1C, 0x00000008);
469 	ast_moutdwm(ast, AST_REG_MCR38, 0xFFFFFF00);
470 }
471 
472 static bool ast_dram_init_2500(struct ast_device *ast)
473 {
474 	u32 data;
475 	u32 max_tries = 5;
476 
477 	do {
478 		if (max_tries-- == 0)
479 			return false;
480 		set_mpll_2500(ast);
481 		reset_mmc_2500(ast);
482 		ddr_init_common_2500(ast);
483 
484 		data = ast_mindwm(ast, AST_REG_SCU070);
485 		if (data & 0x01000000)
486 			ddr4_init_2500(ast, ast2500_ddr4_1600_timing_table);
487 		else
488 			ddr3_init_2500(ast, ast2500_ddr3_1600_timing_table);
489 	} while (!ddr_test_2500(ast));
490 
491 	ast_moutdwm(ast, AST_REG_SCU040, ast_mindwm(ast, AST_REG_SCU040) | 0x41);
492 
493 	/* Patch code */
494 	data = ast_mindwm(ast, AST_REG_SCU00C) & 0xF9FFFFFF;
495 	ast_moutdwm(ast, AST_REG_SCU00C, data | 0x10000000);
496 
497 	return true;
498 }
499 
500 static void ast_post_chip_2500(struct ast_device *ast)
501 {
502 	struct drm_device *dev = &ast->base;
503 	u32 temp;
504 	u8 reg;
505 
506 	reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
507 	if ((reg & AST_IO_VGACRD0_VRAM_INIT_STATUS_MASK) == 0) {/* vga only */
508 		u32 scu008;
509 
510 		/* Clear bus lock condition */
511 		ast_2500_patch_ahb(ast->regs);
512 
513 		/* Disable watchdog */
514 		ast_moutdwm(ast, AST_REG_WDT2C(0), 0x00000000);
515 		ast_moutdwm(ast, AST_REG_WDT0C(1), 0x00000000);
516 
517 		/*
518 		 * Reset USB port to patch USB unknown device issue
519 		 * SCU90 is Multi-function Pin Control #5
520 		 *	[29]:= 1:Enable USB2.0 Host port#1 (that the mutually shared USB2.0 Hub
521 		 *				port).
522 		 * SCU94 is Multi-function Pin Control #6
523 		 *	[14:13]:= 1x:USB2.0 Host2 controller
524 		 * SCU70 is Hardware Strap reg
525 		 *	[23]:= 1:CLKIN is 25MHz and USBCK1 = 24/48 MHz (determined by
526 		 *				[18]: 0(24)/1(48) MHz)
527 		 * SCU7C is Write clear reg to SCU70
528 		 *	[23]:= write 1 and then SCU70[23] will be clear as 0b.
529 		 */
530 		ast_moutdwm(ast, AST_REG_SCU090, 0x20000000);
531 		ast_moutdwm(ast, AST_REG_SCU094, 0x00004000);
532 		if (ast_mindwm(ast, AST_REG_SCU070) & 0x00800000) {
533 			ast_moutdwm(ast, AST_REG_SCU07C, 0x00800000);
534 			mdelay(100);
535 			ast_moutdwm(ast, AST_REG_SCU070, 0x00800000);
536 		}
537 		/* Modify eSPI reset pin */
538 		temp = ast_mindwm(ast, AST_REG_SCU070);
539 		if (temp & 0x02000000)
540 			ast_moutdwm(ast, AST_REG_SCU07C, 0x00004000);
541 
542 		/* Slow down CPU/AHB CLK in VGA only mode */
543 		scu008 = ast_mindwm(ast, AST_REG_SCU008);
544 		scu008 |= 0x00000073;
545 		ast_moutdwm(ast, AST_REG_SCU008, scu008);
546 
547 		if (!ast_dram_init_2500(ast))
548 			drm_err(dev, "DRAM init failed !\n");
549 
550 		temp = ast_mindwm(ast, AST_REG_SCU040);
551 		ast_moutdwm(ast, AST_REG_SCU040, temp | 0x40);
552 	}
553 
554 	/* wait ready */
555 	do {
556 		reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
557 	} while ((reg & 0x40) == 0);
558 }
559 
560 int ast_2500_post(struct ast_device *ast)
561 {
562 	ast_2300_set_def_ext_reg(ast);
563 
564 	if (ast->config_mode == ast_use_p2a) {
565 		ast_post_chip_2500(ast);
566 	} else {
567 		if (ast->tx_chip == AST_TX_SIL164) {
568 			/* Enable DVO */
569 			ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80);
570 		}
571 	}
572 
573 	return 0;
574 }
575 
576 /*
577  * Mode setting
578  */
579 
580 const struct ast_vbios_dclk_info ast_2500_dclk_table[] = {
581 	{0x2c, 0xe7, 0x03},			/* 00: VCLK25_175	*/
582 	{0x95, 0x62, 0x03},			/* 01: VCLK28_322	*/
583 	{0x67, 0x63, 0x01},			/* 02: VCLK31_5		*/
584 	{0x76, 0x63, 0x01},			/* 03: VCLK36		*/
585 	{0xee, 0x67, 0x01},			/* 04: VCLK40		*/
586 	{0x82, 0x62, 0x01},			/* 05: VCLK49_5		*/
587 	{0xc6, 0x64, 0x01},			/* 06: VCLK50		*/
588 	{0x94, 0x62, 0x01},			/* 07: VCLK56_25	*/
589 	{0x80, 0x64, 0x00},			/* 08: VCLK65		*/
590 	{0x7b, 0x63, 0x00},			/* 09: VCLK75		*/
591 	{0x67, 0x62, 0x00},			/* 0a: VCLK78_75	*/
592 	{0x7c, 0x62, 0x00},			/* 0b: VCLK94_5		*/
593 	{0x8e, 0x62, 0x00},			/* 0c: VCLK108		*/
594 	{0x85, 0x24, 0x00},			/* 0d: VCLK135		*/
595 	{0x67, 0x22, 0x00},			/* 0e: VCLK157_5	*/
596 	{0x6a, 0x22, 0x00},			/* 0f: VCLK162		*/
597 	{0x4d, 0x4c, 0x80},			/* 10: VCLK154		*/
598 	{0x68, 0x6f, 0x80},			/* 11: VCLK83.5		*/
599 	{0x28, 0x49, 0x80},			/* 12: VCLK106.5	*/
600 	{0x37, 0x49, 0x80},			/* 13: VCLK146.25	*/
601 	{0x1f, 0x45, 0x80},			/* 14: VCLK148.5	*/
602 	{0x47, 0x6c, 0x80},			/* 15: VCLK71		*/
603 	{0x25, 0x65, 0x80},			/* 16: VCLK88.75	*/
604 	{0x58, 0x01, 0x42},			/* 17: VCLK119		*/
605 	{0x32, 0x67, 0x80},			/* 18: VCLK85_5		*/
606 	{0x6a, 0x6d, 0x80},			/* 19: VCLK97_75	*/
607 	{0x44, 0x20, 0x43},			/* 1a: VCLK118_25	*/
608 };
609 
610 /*
611  * Device initialization
612  */
613 
614 static void ast_2500_detect_widescreen(struct ast_device *ast)
615 {
616 	if (__ast_2100_detect_wsxga_p(ast) || ast->chip == AST2510) {
617 		ast->support_wsxga_p = true;
618 		ast->support_fullhd = true;
619 	}
620 	if (__ast_2100_detect_wuxga(ast))
621 		ast->support_wuxga = true;
622 }
623 
624 static const struct ast_device_quirks ast_2500_device_quirks = {
625 	.crtc_mem_req_threshold_low = 96,
626 	.crtc_mem_req_threshold_high = 120,
627 	.crtc_hsync_precatch_needed = true,
628 };
629 
630 struct drm_device *ast_2500_device_create(struct pci_dev *pdev,
631 					  const struct drm_driver *drv,
632 					  enum ast_chip chip,
633 					  enum ast_config_mode config_mode,
634 					  void __iomem *regs,
635 					  void __iomem *ioregs,
636 					  bool need_post)
637 {
638 	struct drm_device *dev;
639 	struct ast_device *ast;
640 	int ret;
641 
642 	ast = devm_drm_dev_alloc(&pdev->dev, drv, struct ast_device, base);
643 	if (IS_ERR(ast))
644 		return ERR_CAST(ast);
645 	dev = &ast->base;
646 
647 	ast_device_init(ast, chip, config_mode, regs, ioregs, &ast_2500_device_quirks);
648 
649 	ast->dclk_table = ast_2500_dclk_table;
650 
651 	ast_2300_detect_tx_chip(ast);
652 
653 	if (need_post) {
654 		ret = ast_post_gpu(ast);
655 		if (ret)
656 			return ERR_PTR(ret);
657 	}
658 
659 	ret = ast_mm_init(ast);
660 	if (ret)
661 		return ERR_PTR(ret);
662 
663 	/* map reserved buffer */
664 	ast->dp501_fw_buf = NULL;
665 	if (ast->vram_size < pci_resource_len(pdev, 0)) {
666 		ast->dp501_fw_buf = pci_iomap_range(pdev, 0, ast->vram_size, 0);
667 		if (!ast->dp501_fw_buf)
668 			drm_info(dev, "failed to map reserved buffer!\n");
669 	}
670 
671 	ast_2500_detect_widescreen(ast);
672 
673 	ret = ast_mode_config_init(ast);
674 	if (ret)
675 		return ERR_PTR(ret);
676 
677 	return dev;
678 }
679