xref: /linux/drivers/gpu/drm/ast/ast_2300.c (revision 8d2b0853add1d7534dc0794e3c8e0b9e8c4ec640)
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 "ast_drv.h"
32 #include "ast_post.h"
33 
34 /*
35  *  POST
36  */
37 
38 void ast_2300_set_def_ext_reg(struct ast_device *ast)
39 {
40 	static const u8 extreginfo[] = { 0x0f, 0x04, 0x1f, 0xff };
41 	u8 i, index, reg;
42 	const u8 *ext_reg_info;
43 
44 	/* reset scratch */
45 	for (i = 0x81; i <= 0x9f; i++)
46 		ast_set_index_reg(ast, AST_IO_VGACRI, i, 0x00);
47 
48 	ext_reg_info = extreginfo;
49 	index = 0xa0;
50 	while (*ext_reg_info != 0xff) {
51 		ast_set_index_reg_mask(ast, AST_IO_VGACRI, index, 0x00, *ext_reg_info);
52 		index++;
53 		ext_reg_info++;
54 	}
55 
56 	/* disable standard IO/MEM decode if secondary */
57 	/* ast_set_index_reg-mask(ast, AST_IO_VGACRI, 0xa1, 0xff, 0x3); */
58 
59 	/* Set Ext. Default */
60 	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x8c, 0x00, 0x01);
61 	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x00, 0x00);
62 
63 	/* Enable RAMDAC for A1 */
64 	reg = 0x04;
65 	reg |= 0x20;
66 	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xff, reg);
67 }
68 
69 /* AST 2300 DRAM settings */
70 #define AST_DDR3 0
71 #define AST_DDR2 1
72 
73 struct ast2300_dram_param {
74 	u32 dram_type;
75 	u32 dram_chipid;
76 	u32 dram_freq;
77 	u32 vram_size;
78 	u32 odt;
79 	u32 wodt;
80 	u32 rodt;
81 	u32 dram_config;
82 	u32 reg_PERIOD;
83 	u32 reg_MADJ;
84 	u32 reg_SADJ;
85 	u32 reg_MRS;
86 	u32 reg_EMRS;
87 	u32 reg_AC1;
88 	u32 reg_AC2;
89 	u32 reg_DQSIC;
90 	u32 reg_DRV;
91 	u32 reg_IOZ;
92 	u32 reg_DQIDLY;
93 	u32 reg_FREQ;
94 	u32 madj_max;
95 	u32 dll2_finetune_step;
96 };
97 
98 /*
99  * DQSI DLL CBR Setting
100  */
101 #define CBR_SIZE0            ((1  << 10) - 1)
102 #define CBR_SIZE1            ((4  << 10) - 1)
103 #define CBR_SIZE2            ((64 << 10) - 1)
104 #define CBR_PASSNUM          5
105 #define CBR_PASSNUM2         5
106 #define CBR_THRESHOLD        10
107 #define CBR_THRESHOLD2       10
108 #define TIMEOUT              5000000
109 #define CBR_PATNUM           8
110 
111 static const u32 pattern[8] = {
112 	0xFF00FF00,
113 	0xCC33CC33,
114 	0xAA55AA55,
115 	0x88778877,
116 	0x92CC4D6E,
117 	0x543D3CDE,
118 	0xF1E843C7,
119 	0x7C61D253
120 };
121 
122 static u32 mmc_test2(struct ast_device *ast, u32 datagen, u8 test_ctl)
123 {
124 	u32 data, timeout;
125 
126 	ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
127 	ast_moutdwm(ast, 0x1e6e0070, (datagen << 3) | test_ctl);
128 	timeout = 0;
129 	do {
130 		data = ast_mindwm(ast, 0x1e6e0070) & 0x1000;
131 		if (++timeout > TIMEOUT) {
132 			ast_moutdwm(ast, 0x1e6e0070, 0x0);
133 			return 0xffffffff;
134 		}
135 	} while (!data);
136 	data = ast_mindwm(ast, 0x1e6e0078);
137 	data = (data | (data >> 16)) & 0xffff;
138 	ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
139 	return data;
140 }
141 
142 static u32 mmc_test_burst2(struct ast_device *ast, u32 datagen)
143 {
144 	return mmc_test2(ast, datagen, 0x41);
145 }
146 
147 static bool mmc_test_single(struct ast_device *ast, u32 datagen)
148 {
149 	return mmc_test(ast, datagen, 0xc5);
150 }
151 
152 static u32 mmc_test_single2(struct ast_device *ast, u32 datagen)
153 {
154 	return mmc_test2(ast, datagen, 0x05);
155 }
156 
157 static int cbr_test(struct ast_device *ast)
158 {
159 	u32 data;
160 	int i;
161 
162 	data = mmc_test_single2(ast, 0);
163 	if ((data & 0xff) && (data & 0xff00))
164 		return 0;
165 	for (i = 0; i < 8; i++) {
166 		data = mmc_test_burst2(ast, i);
167 		if ((data & 0xff) && (data & 0xff00))
168 			return 0;
169 	}
170 	if (!data)
171 		return 3;
172 	else if (data & 0xff)
173 		return 2;
174 	return 1;
175 }
176 
177 static int cbr_scan(struct ast_device *ast)
178 {
179 	u32 data, data2, patcnt, loop;
180 
181 	data2 = 3;
182 	for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
183 		ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
184 		for (loop = 0; loop < CBR_PASSNUM2; loop++) {
185 			data = cbr_test(ast);
186 			if (data != 0) {
187 				data2 &= data;
188 				if (!data2)
189 					return 0;
190 				break;
191 			}
192 		}
193 		if (loop == CBR_PASSNUM2)
194 			return 0;
195 	}
196 	return data2;
197 }
198 
199 static u32 cbr_test2(struct ast_device *ast)
200 {
201 	u32 data;
202 
203 	data = mmc_test_burst2(ast, 0);
204 	if (data == 0xffff)
205 		return 0;
206 	data |= mmc_test_single2(ast, 0);
207 	if (data == 0xffff)
208 		return 0;
209 
210 	return ~data & 0xffff;
211 }
212 
213 static u32 cbr_scan2(struct ast_device *ast)
214 {
215 	u32 data, data2, patcnt, loop;
216 
217 	data2 = 0xffff;
218 	for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
219 		ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
220 		for (loop = 0; loop < CBR_PASSNUM2; loop++) {
221 			data = cbr_test2(ast);
222 			if (data != 0) {
223 				data2 &= data;
224 				if (!data2)
225 					return 0;
226 				break;
227 			}
228 		}
229 		if (loop == CBR_PASSNUM2)
230 			return 0;
231 	}
232 	return data2;
233 }
234 
235 static bool cbr_test3(struct ast_device *ast)
236 {
237 	if (!mmc_test_burst(ast, 0))
238 		return false;
239 	if (!mmc_test_single(ast, 0))
240 		return false;
241 	return true;
242 }
243 
244 static bool cbr_scan3(struct ast_device *ast)
245 {
246 	u32 patcnt, loop;
247 
248 	for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
249 		ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
250 		for (loop = 0; loop < 2; loop++) {
251 			if (cbr_test3(ast))
252 				break;
253 		}
254 		if (loop == 2)
255 			return false;
256 	}
257 	return true;
258 }
259 
260 static bool finetuneDQI_L(struct ast_device *ast, struct ast2300_dram_param *param)
261 {
262 	u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, retry = 0;
263 	bool status = false;
264 FINETUNE_START:
265 	for (cnt = 0; cnt < 16; cnt++) {
266 		dllmin[cnt] = 0xff;
267 		dllmax[cnt] = 0x0;
268 	}
269 	passcnt = 0;
270 	for (dlli = 0; dlli < 76; dlli++) {
271 		ast_moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
272 		ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE1);
273 		data = cbr_scan2(ast);
274 		if (data != 0) {
275 			mask = 0x00010001;
276 			for (cnt = 0; cnt < 16; cnt++) {
277 				if (data & mask) {
278 					if (dllmin[cnt] > dlli)
279 						dllmin[cnt] = dlli;
280 					if (dllmax[cnt] < dlli)
281 						dllmax[cnt] = dlli;
282 				}
283 				mask <<= 1;
284 			}
285 			passcnt++;
286 		} else if (passcnt >= CBR_THRESHOLD2) {
287 			break;
288 		}
289 	}
290 	gold_sadj[0] = 0x0;
291 	passcnt = 0;
292 	for (cnt = 0; cnt < 16; cnt++) {
293 		if ((dllmax[cnt] > dllmin[cnt]) &&
294 		    ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
295 			gold_sadj[0] += dllmin[cnt];
296 			passcnt++;
297 		}
298 	}
299 	if (retry++ > 10)
300 		goto FINETUNE_DONE;
301 	if (passcnt != 16)
302 		goto FINETUNE_START;
303 	status = true;
304 FINETUNE_DONE:
305 	gold_sadj[0] = gold_sadj[0] >> 4;
306 	gold_sadj[1] = gold_sadj[0];
307 
308 	data = 0;
309 	for (cnt = 0; cnt < 8; cnt++) {
310 		data >>= 3;
311 		if ((dllmax[cnt] > dllmin[cnt]) &&
312 		    ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
313 			dlli = dllmin[cnt];
314 			if (gold_sadj[0] >= dlli) {
315 				dlli = ((gold_sadj[0] - dlli) * 19) >> 5;
316 				if (dlli > 3)
317 					dlli = 3;
318 			} else {
319 				dlli = ((dlli - gold_sadj[0]) * 19) >> 5;
320 				if (dlli > 4)
321 					dlli = 4;
322 				dlli = (8 - dlli) & 0x7;
323 			}
324 			data |= dlli << 21;
325 		}
326 	}
327 	ast_moutdwm(ast, 0x1E6E0080, data);
328 
329 	data = 0;
330 	for (cnt = 8; cnt < 16; cnt++) {
331 		data >>= 3;
332 		if ((dllmax[cnt] > dllmin[cnt]) &&
333 		    ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
334 			dlli = dllmin[cnt];
335 			if (gold_sadj[1] >= dlli) {
336 				dlli = ((gold_sadj[1] - dlli) * 19) >> 5;
337 				if (dlli > 3)
338 					dlli = 3;
339 				else
340 					dlli = (dlli - 1) & 0x7;
341 			} else {
342 				dlli = ((dlli - gold_sadj[1]) * 19) >> 5;
343 				dlli += 1;
344 				if (dlli > 4)
345 					dlli = 4;
346 				dlli = (8 - dlli) & 0x7;
347 			}
348 			data |= dlli << 21;
349 		}
350 	}
351 	ast_moutdwm(ast, 0x1E6E0084, data);
352 	return status;
353 } /* finetuneDQI_L */
354 
355 static void finetuneDQSI(struct ast_device *ast)
356 {
357 	u32 dlli, dqsip, dqidly;
358 	u32 reg_mcr18, reg_mcr0c, passcnt[2], diff;
359 	u32 g_dqidly, g_dqsip, g_margin, g_side;
360 	u16 pass[32][2][2];
361 	char tag[2][76];
362 
363 	/* Disable DQI CBR */
364 	reg_mcr0c  = ast_mindwm(ast, 0x1E6E000C);
365 	reg_mcr18  = ast_mindwm(ast, 0x1E6E0018);
366 	reg_mcr18 &= 0x0000ffff;
367 	ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
368 
369 	for (dlli = 0; dlli < 76; dlli++) {
370 		tag[0][dlli] = 0x0;
371 		tag[1][dlli] = 0x0;
372 	}
373 	for (dqidly = 0; dqidly < 32; dqidly++) {
374 		pass[dqidly][0][0] = 0xff;
375 		pass[dqidly][0][1] = 0x0;
376 		pass[dqidly][1][0] = 0xff;
377 		pass[dqidly][1][1] = 0x0;
378 	}
379 	for (dqidly = 0; dqidly < 32; dqidly++) {
380 		passcnt[0] = 0;
381 		passcnt[1] = 0;
382 		for (dqsip = 0; dqsip < 2; dqsip++) {
383 			ast_moutdwm(ast, 0x1E6E000C, 0);
384 			ast_moutdwm(ast, 0x1E6E0018, reg_mcr18 | (dqidly << 16) | (dqsip << 23));
385 			ast_moutdwm(ast, 0x1E6E000C, reg_mcr0c);
386 			for (dlli = 0; dlli < 76; dlli++) {
387 				ast_moutdwm(ast, 0x1E6E0068,
388 					    0x00001300 | (dlli << 16) | (dlli << 24));
389 				ast_moutdwm(ast, 0x1E6E0070, 0);
390 				ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE0);
391 				if (cbr_scan3(ast)) {
392 					if (dlli == 0)
393 						break;
394 					passcnt[dqsip]++;
395 					tag[dqsip][dlli] = 'P';
396 					if (dlli < pass[dqidly][dqsip][0])
397 						pass[dqidly][dqsip][0] = (u16)dlli;
398 					if (dlli > pass[dqidly][dqsip][1])
399 						pass[dqidly][dqsip][1] = (u16)dlli;
400 				} else if (passcnt[dqsip] >= 5) {
401 					break;
402 				} else {
403 					pass[dqidly][dqsip][0] = 0xff;
404 					pass[dqidly][dqsip][1] = 0x0;
405 				}
406 			}
407 		}
408 		if (passcnt[0] == 0 && passcnt[1] == 0)
409 			dqidly++;
410 	}
411 	/* Search margin */
412 	g_dqidly = 0;
413 	g_dqsip = 0;
414 	g_margin = 0;
415 	g_side = 0;
416 
417 	for (dqidly = 0; dqidly < 32; dqidly++) {
418 		for (dqsip = 0; dqsip < 2; dqsip++) {
419 			if (pass[dqidly][dqsip][0] > pass[dqidly][dqsip][1])
420 				continue;
421 			diff = pass[dqidly][dqsip][1] - pass[dqidly][dqsip][0];
422 			if ((diff + 2) < g_margin)
423 				continue;
424 			passcnt[0] = 0;
425 			passcnt[1] = 0;
426 			for (dlli = pass[dqidly][dqsip][0];
427 			     dlli > 0 && tag[dqsip][dlli] != 0;
428 			     dlli--, passcnt[0]++) {
429 			}
430 			for (dlli = pass[dqidly][dqsip][1];
431 			     dlli < 76 && tag[dqsip][dlli] != 0;
432 			     dlli++, passcnt[1]++) {
433 			}
434 			if (passcnt[0] > passcnt[1])
435 				passcnt[0] = passcnt[1];
436 			passcnt[1] = 0;
437 			if (passcnt[0] > g_side)
438 				passcnt[1] = passcnt[0] - g_side;
439 			if (diff > (g_margin + 1) && (passcnt[1] > 0 || passcnt[0] > 8)) {
440 				g_margin = diff;
441 				g_dqidly = dqidly;
442 				g_dqsip  = dqsip;
443 				g_side   = passcnt[0];
444 			} else if (passcnt[1] > 1 && g_side < 8) {
445 				if (diff > g_margin)
446 					g_margin = diff;
447 				g_dqidly = dqidly;
448 				g_dqsip  = dqsip;
449 				g_side   = passcnt[0];
450 			}
451 		}
452 	}
453 	reg_mcr18 = reg_mcr18 | (g_dqidly << 16) | (g_dqsip << 23);
454 	ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
455 }
456 
457 static bool cbr_dll2(struct ast_device *ast, struct ast2300_dram_param *param)
458 {
459 	u32 dllmin[2], dllmax[2], dlli, data, passcnt, retry = 0;
460 	bool status = false;
461 
462 	finetuneDQSI(ast);
463 	if (finetuneDQI_L(ast, param) == false)
464 		return status;
465 
466 CBR_START2:
467 	dllmin[0] = 0xff;
468 	dllmin[1] = 0xff;
469 	dllmax[0] = 0x0;
470 	dllmax[1] = 0x0;
471 	passcnt = 0;
472 	for (dlli = 0; dlli < 76; dlli++) {
473 		ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
474 		ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE2);
475 		data = cbr_scan(ast);
476 		if (data != 0) {
477 			if (data & 0x1) {
478 				if (dllmin[0] > dlli)
479 					dllmin[0] = dlli;
480 				if (dllmax[0] < dlli)
481 					dllmax[0] = dlli;
482 			}
483 			if (data & 0x2) {
484 				if (dllmin[1] > dlli)
485 					dllmin[1] = dlli;
486 				if (dllmax[1] < dlli)
487 					dllmax[1] = dlli;
488 			}
489 			passcnt++;
490 		} else if (passcnt >= CBR_THRESHOLD) {
491 			break;
492 		}
493 	}
494 	if (retry++ > 10)
495 		goto CBR_DONE2;
496 	if (dllmax[0] == 0 || (dllmax[0] - dllmin[0]) < CBR_THRESHOLD)
497 		goto CBR_START2;
498 	if (dllmax[1] == 0 || (dllmax[1] - dllmin[1]) < CBR_THRESHOLD)
499 		goto CBR_START2;
500 	status = true;
501 CBR_DONE2:
502 	dlli  = (dllmin[1] + dllmax[1]) >> 1;
503 	dlli <<= 8;
504 	dlli += (dllmin[0] + dllmax[0]) >> 1;
505 	ast_moutdwm(ast, 0x1E6E0068, ast_mindwm(ast, 0x1E720058) | (dlli << 16));
506 	return status;
507 } /* CBRDLL2 */
508 
509 static void get_ddr3_info(struct ast_device *ast, struct ast2300_dram_param *param)
510 {
511 	u32 trap, trap_AC2, trap_MRS;
512 
513 	ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
514 
515 	/* Ger trap info */
516 	trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
517 	trap_AC2  = 0x00020000 + (trap << 16);
518 	trap_AC2 |= 0x00300000 + ((trap & 0x2) << 19);
519 	trap_MRS  = 0x00000010 + (trap << 4);
520 	trap_MRS |= ((trap & 0x2) << 18);
521 
522 	param->reg_MADJ       = 0x00034C4C;
523 	param->reg_SADJ       = 0x00001800;
524 	param->reg_DRV        = 0x000000F0;
525 	param->reg_PERIOD     = param->dram_freq;
526 	param->rodt           = 0;
527 
528 	switch (param->dram_freq) {
529 	case 336:
530 		ast_moutdwm(ast, 0x1E6E2020, 0x0190);
531 		param->wodt          = 0;
532 		param->reg_AC1       = 0x22202725;
533 		param->reg_AC2       = 0xAA007613 | trap_AC2;
534 		param->reg_DQSIC     = 0x000000BA;
535 		param->reg_MRS       = 0x04001400 | trap_MRS;
536 		param->reg_EMRS      = 0x00000000;
537 		param->reg_IOZ       = 0x00000023;
538 		param->reg_DQIDLY    = 0x00000074;
539 		param->reg_FREQ      = 0x00004DC0;
540 		param->madj_max      = 96;
541 		param->dll2_finetune_step = 3;
542 		switch (param->dram_chipid) {
543 		default:
544 		case AST_DRAM_512Mx16:
545 		case AST_DRAM_1Gx16:
546 			param->reg_AC2   = 0xAA007613 | trap_AC2;
547 			break;
548 		case AST_DRAM_2Gx16:
549 			param->reg_AC2   = 0xAA00761C | trap_AC2;
550 			break;
551 		case AST_DRAM_4Gx16:
552 			param->reg_AC2   = 0xAA007636 | trap_AC2;
553 			break;
554 		}
555 		break;
556 	default:
557 	case 396:
558 		ast_moutdwm(ast, 0x1E6E2020, 0x03F1);
559 		param->wodt          = 1;
560 		param->reg_AC1       = 0x33302825;
561 		param->reg_AC2       = 0xCC009617 | trap_AC2;
562 		param->reg_DQSIC     = 0x000000E2;
563 		param->reg_MRS       = 0x04001600 | trap_MRS;
564 		param->reg_EMRS      = 0x00000000;
565 		param->reg_IOZ       = 0x00000034;
566 		param->reg_DRV       = 0x000000FA;
567 		param->reg_DQIDLY    = 0x00000089;
568 		param->reg_FREQ      = 0x00005040;
569 		param->madj_max      = 96;
570 		param->dll2_finetune_step = 4;
571 
572 		switch (param->dram_chipid) {
573 		default:
574 		case AST_DRAM_512Mx16:
575 		case AST_DRAM_1Gx16:
576 			param->reg_AC2   = 0xCC009617 | trap_AC2;
577 			break;
578 		case AST_DRAM_2Gx16:
579 			param->reg_AC2   = 0xCC009622 | trap_AC2;
580 			break;
581 		case AST_DRAM_4Gx16:
582 			param->reg_AC2   = 0xCC00963F | trap_AC2;
583 			break;
584 		}
585 		break;
586 
587 	case 408:
588 		ast_moutdwm(ast, 0x1E6E2020, 0x01F0);
589 		param->wodt          = 1;
590 		param->reg_AC1       = 0x33302825;
591 		param->reg_AC2       = 0xCC009617 | trap_AC2;
592 		param->reg_DQSIC     = 0x000000E2;
593 		param->reg_MRS       = 0x04001600 | trap_MRS;
594 		param->reg_EMRS      = 0x00000000;
595 		param->reg_IOZ       = 0x00000023;
596 		param->reg_DRV       = 0x000000FA;
597 		param->reg_DQIDLY    = 0x00000089;
598 		param->reg_FREQ      = 0x000050C0;
599 		param->madj_max      = 96;
600 		param->dll2_finetune_step = 4;
601 
602 		switch (param->dram_chipid) {
603 		default:
604 		case AST_DRAM_512Mx16:
605 		case AST_DRAM_1Gx16:
606 			param->reg_AC2   = 0xCC009617 | trap_AC2;
607 			break;
608 		case AST_DRAM_2Gx16:
609 			param->reg_AC2   = 0xCC009622 | trap_AC2;
610 			break;
611 		case AST_DRAM_4Gx16:
612 			param->reg_AC2   = 0xCC00963F | trap_AC2;
613 			break;
614 		}
615 
616 		break;
617 	case 456:
618 		ast_moutdwm(ast, 0x1E6E2020, 0x0230);
619 		param->wodt          = 0;
620 		param->reg_AC1       = 0x33302926;
621 		param->reg_AC2       = 0xCD44961A;
622 		param->reg_DQSIC     = 0x000000FC;
623 		param->reg_MRS       = 0x00081830;
624 		param->reg_EMRS      = 0x00000000;
625 		param->reg_IOZ       = 0x00000045;
626 		param->reg_DQIDLY    = 0x00000097;
627 		param->reg_FREQ      = 0x000052C0;
628 		param->madj_max      = 88;
629 		param->dll2_finetune_step = 4;
630 		break;
631 	case 504:
632 		ast_moutdwm(ast, 0x1E6E2020, 0x0270);
633 		param->wodt          = 1;
634 		param->reg_AC1       = 0x33302926;
635 		param->reg_AC2       = 0xDE44A61D;
636 		param->reg_DQSIC     = 0x00000117;
637 		param->reg_MRS       = 0x00081A30;
638 		param->reg_EMRS      = 0x00000000;
639 		param->reg_IOZ       = 0x070000BB;
640 		param->reg_DQIDLY    = 0x000000A0;
641 		param->reg_FREQ      = 0x000054C0;
642 		param->madj_max      = 79;
643 		param->dll2_finetune_step = 4;
644 		break;
645 	case 528:
646 		ast_moutdwm(ast, 0x1E6E2020, 0x0290);
647 		param->wodt          = 1;
648 		param->rodt          = 1;
649 		param->reg_AC1       = 0x33302926;
650 		param->reg_AC2       = 0xEF44B61E;
651 		param->reg_DQSIC     = 0x00000125;
652 		param->reg_MRS       = 0x00081A30;
653 		param->reg_EMRS      = 0x00000040;
654 		param->reg_DRV       = 0x000000F5;
655 		param->reg_IOZ       = 0x00000023;
656 		param->reg_DQIDLY    = 0x00000088;
657 		param->reg_FREQ      = 0x000055C0;
658 		param->madj_max      = 76;
659 		param->dll2_finetune_step = 3;
660 		break;
661 	case 576:
662 		ast_moutdwm(ast, 0x1E6E2020, 0x0140);
663 		param->reg_MADJ      = 0x00136868;
664 		param->reg_SADJ      = 0x00004534;
665 		param->wodt          = 1;
666 		param->rodt          = 1;
667 		param->reg_AC1       = 0x33302A37;
668 		param->reg_AC2       = 0xEF56B61E;
669 		param->reg_DQSIC     = 0x0000013F;
670 		param->reg_MRS       = 0x00101A50;
671 		param->reg_EMRS      = 0x00000040;
672 		param->reg_DRV       = 0x000000FA;
673 		param->reg_IOZ       = 0x00000023;
674 		param->reg_DQIDLY    = 0x00000078;
675 		param->reg_FREQ      = 0x000057C0;
676 		param->madj_max      = 136;
677 		param->dll2_finetune_step = 3;
678 		break;
679 	case 600:
680 		ast_moutdwm(ast, 0x1E6E2020, 0x02E1);
681 		param->reg_MADJ      = 0x00136868;
682 		param->reg_SADJ      = 0x00004534;
683 		param->wodt          = 1;
684 		param->rodt          = 1;
685 		param->reg_AC1       = 0x32302A37;
686 		param->reg_AC2       = 0xDF56B61F;
687 		param->reg_DQSIC     = 0x0000014D;
688 		param->reg_MRS       = 0x00101A50;
689 		param->reg_EMRS      = 0x00000004;
690 		param->reg_DRV       = 0x000000F5;
691 		param->reg_IOZ       = 0x00000023;
692 		param->reg_DQIDLY    = 0x00000078;
693 		param->reg_FREQ      = 0x000058C0;
694 		param->madj_max      = 132;
695 		param->dll2_finetune_step = 3;
696 		break;
697 	case 624:
698 		ast_moutdwm(ast, 0x1E6E2020, 0x0160);
699 		param->reg_MADJ      = 0x00136868;
700 		param->reg_SADJ      = 0x00004534;
701 		param->wodt          = 1;
702 		param->rodt          = 1;
703 		param->reg_AC1       = 0x32302A37;
704 		param->reg_AC2       = 0xEF56B621;
705 		param->reg_DQSIC     = 0x0000015A;
706 		param->reg_MRS       = 0x02101A50;
707 		param->reg_EMRS      = 0x00000004;
708 		param->reg_DRV       = 0x000000F5;
709 		param->reg_IOZ       = 0x00000034;
710 		param->reg_DQIDLY    = 0x00000078;
711 		param->reg_FREQ      = 0x000059C0;
712 		param->madj_max      = 128;
713 		param->dll2_finetune_step = 3;
714 		break;
715 	} /* switch freq */
716 
717 	switch (param->dram_chipid) {
718 	case AST_DRAM_512Mx16:
719 		param->dram_config = 0x130;
720 		break;
721 	default:
722 	case AST_DRAM_1Gx16:
723 		param->dram_config = 0x131;
724 		break;
725 	case AST_DRAM_2Gx16:
726 		param->dram_config = 0x132;
727 		break;
728 	case AST_DRAM_4Gx16:
729 		param->dram_config = 0x133;
730 		break;
731 	} /* switch size */
732 
733 	switch (param->vram_size) {
734 	default:
735 	case SZ_8M:
736 		param->dram_config |= 0x00;
737 		break;
738 	case SZ_16M:
739 		param->dram_config |= 0x04;
740 		break;
741 	case SZ_32M:
742 		param->dram_config |= 0x08;
743 		break;
744 	case SZ_64M:
745 		param->dram_config |= 0x0c;
746 		break;
747 	}
748 }
749 
750 static void ddr3_init(struct ast_device *ast, struct ast2300_dram_param *param)
751 {
752 	u32 data, data2, retry = 0;
753 
754 ddr3_init_start:
755 	ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
756 	ast_moutdwm(ast, 0x1E6E0018, 0x00000100);
757 	ast_moutdwm(ast, 0x1E6E0024, 0x00000000);
758 	ast_moutdwm(ast, 0x1E6E0034, 0x00000000);
759 	udelay(10);
760 	ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
761 	ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
762 	udelay(10);
763 	ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
764 	udelay(10);
765 
766 	ast_moutdwm(ast, 0x1E6E0004, param->dram_config);
767 	ast_moutdwm(ast, 0x1E6E0008, 0x90040f);
768 	ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1);
769 	ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2);
770 	ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
771 	ast_moutdwm(ast, 0x1E6E0080, 0x00000000);
772 	ast_moutdwm(ast, 0x1E6E0084, 0x00000000);
773 	ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
774 	ast_moutdwm(ast, 0x1E6E0018, 0x4000A170);
775 	ast_moutdwm(ast, 0x1E6E0018, 0x00002370);
776 	ast_moutdwm(ast, 0x1E6E0038, 0x00000000);
777 	ast_moutdwm(ast, 0x1E6E0040, 0xFF444444);
778 	ast_moutdwm(ast, 0x1E6E0044, 0x22222222);
779 	ast_moutdwm(ast, 0x1E6E0048, 0x22222222);
780 	ast_moutdwm(ast, 0x1E6E004C, 0x00000002);
781 	ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
782 	ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
783 	ast_moutdwm(ast, 0x1E6E0054, 0);
784 	ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV);
785 	ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
786 	ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
787 	ast_moutdwm(ast, 0x1E6E0074, 0x00000000);
788 	ast_moutdwm(ast, 0x1E6E0078, 0x00000000);
789 	ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
790 	/* Wait MCLK2X lock to MCLK */
791 	do {
792 		data = ast_mindwm(ast, 0x1E6E001C);
793 	} while (!(data & 0x08000000));
794 	data = ast_mindwm(ast, 0x1E6E001C);
795 	data = (data >> 8) & 0xff;
796 	while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
797 		data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
798 		if ((data2 & 0xff) > param->madj_max)
799 			break;
800 		ast_moutdwm(ast, 0x1E6E0064, data2);
801 		if (data2 & 0x00100000)
802 			data2 = ((data2 & 0xff) >> 3) + 3;
803 		else
804 			data2 = ((data2 & 0xff) >> 2) + 5;
805 		data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff;
806 		data2 += data & 0xff;
807 		data = data | (data2 << 8);
808 		ast_moutdwm(ast, 0x1E6E0068, data);
809 		udelay(10);
810 		ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000);
811 		udelay(10);
812 		data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
813 		ast_moutdwm(ast, 0x1E6E0018, data);
814 		data = data | 0x200;
815 		ast_moutdwm(ast, 0x1E6E0018, data);
816 		do {
817 			data = ast_mindwm(ast, 0x1E6E001C);
818 		} while (!(data & 0x08000000));
819 
820 		data = ast_mindwm(ast, 0x1E6E001C);
821 		data = (data >> 8) & 0xff;
822 	}
823 	ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0068) & 0xffff);
824 	data = ast_mindwm(ast, 0x1E6E0018) | 0xC00;
825 	ast_moutdwm(ast, 0x1E6E0018, data);
826 
827 	ast_moutdwm(ast, 0x1E6E0034, 0x00000001);
828 	ast_moutdwm(ast, 0x1E6E000C, 0x00000040);
829 	udelay(50);
830 	/* Mode Register Setting */
831 	ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
832 	ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
833 	ast_moutdwm(ast, 0x1E6E0028, 0x00000005);
834 	ast_moutdwm(ast, 0x1E6E0028, 0x00000007);
835 	ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
836 	ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
837 	ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS);
838 	ast_moutdwm(ast, 0x1E6E000C, 0x00005C08);
839 	ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
840 
841 	ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
842 	data = 0;
843 	if (param->wodt)
844 		data = 0x300;
845 	if (param->rodt)
846 		data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
847 	ast_moutdwm(ast, 0x1E6E0034, data | 0x3);
848 
849 	/* Calibrate the DQSI delay */
850 	if ((cbr_dll2(ast, param) == false) && (retry++ < 10))
851 		goto ddr3_init_start;
852 
853 	ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
854 	/* ECC Memory Initialization */
855 #ifdef ECC
856 	ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
857 	ast_moutdwm(ast, 0x1E6E0070, 0x221);
858 	do {
859 		data = ast_mindwm(ast, 0x1E6E0070);
860 	} while (!(data & 0x00001000));
861 	ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
862 	ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
863 	ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
864 #endif
865 }
866 
867 static void get_ddr2_info(struct ast_device *ast, struct ast2300_dram_param *param)
868 {
869 	u32 trap, trap_AC2, trap_MRS;
870 
871 	ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
872 
873 	/* Ger trap info */
874 	trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
875 	trap_AC2  = (trap << 20) | (trap << 16);
876 	trap_AC2 += 0x00110000;
877 	trap_MRS  = 0x00000040 | (trap << 4);
878 
879 	param->reg_MADJ       = 0x00034C4C;
880 	param->reg_SADJ       = 0x00001800;
881 	param->reg_DRV        = 0x000000F0;
882 	param->reg_PERIOD     = param->dram_freq;
883 	param->rodt           = 0;
884 
885 	switch (param->dram_freq) {
886 	case 264:
887 		ast_moutdwm(ast, 0x1E6E2020, 0x0130);
888 		param->wodt          = 0;
889 		param->reg_AC1       = 0x11101513;
890 		param->reg_AC2       = 0x78117011;
891 		param->reg_DQSIC     = 0x00000092;
892 		param->reg_MRS       = 0x00000842;
893 		param->reg_EMRS      = 0x00000000;
894 		param->reg_DRV       = 0x000000F0;
895 		param->reg_IOZ       = 0x00000034;
896 		param->reg_DQIDLY    = 0x0000005A;
897 		param->reg_FREQ      = 0x00004AC0;
898 		param->madj_max      = 138;
899 		param->dll2_finetune_step = 3;
900 		break;
901 	case 336:
902 		ast_moutdwm(ast, 0x1E6E2020, 0x0190);
903 		param->wodt          = 1;
904 		param->reg_AC1       = 0x22202613;
905 		param->reg_AC2       = 0xAA009016 | trap_AC2;
906 		param->reg_DQSIC     = 0x000000BA;
907 		param->reg_MRS       = 0x00000A02 | trap_MRS;
908 		param->reg_EMRS      = 0x00000040;
909 		param->reg_DRV       = 0x000000FA;
910 		param->reg_IOZ       = 0x00000034;
911 		param->reg_DQIDLY    = 0x00000074;
912 		param->reg_FREQ      = 0x00004DC0;
913 		param->madj_max      = 96;
914 		param->dll2_finetune_step = 3;
915 		switch (param->dram_chipid) {
916 		default:
917 		case AST_DRAM_512Mx16:
918 			param->reg_AC2   = 0xAA009012 | trap_AC2;
919 			break;
920 		case AST_DRAM_1Gx16:
921 			param->reg_AC2   = 0xAA009016 | trap_AC2;
922 			break;
923 		case AST_DRAM_2Gx16:
924 			param->reg_AC2   = 0xAA009023 | trap_AC2;
925 			break;
926 		case AST_DRAM_4Gx16:
927 			param->reg_AC2   = 0xAA00903B | trap_AC2;
928 			break;
929 		}
930 		break;
931 	default:
932 	case 396:
933 		ast_moutdwm(ast, 0x1E6E2020, 0x03F1);
934 		param->wodt          = 1;
935 		param->rodt          = 0;
936 		param->reg_AC1       = 0x33302714;
937 		param->reg_AC2       = 0xCC00B01B | trap_AC2;
938 		param->reg_DQSIC     = 0x000000E2;
939 		param->reg_MRS       = 0x00000C02 | trap_MRS;
940 		param->reg_EMRS      = 0x00000040;
941 		param->reg_DRV       = 0x000000FA;
942 		param->reg_IOZ       = 0x00000034;
943 		param->reg_DQIDLY    = 0x00000089;
944 		param->reg_FREQ      = 0x00005040;
945 		param->madj_max      = 96;
946 		param->dll2_finetune_step = 4;
947 
948 		switch (param->dram_chipid) {
949 		case AST_DRAM_512Mx16:
950 			param->reg_AC2   = 0xCC00B016 | trap_AC2;
951 			break;
952 		default:
953 		case AST_DRAM_1Gx16:
954 			param->reg_AC2   = 0xCC00B01B | trap_AC2;
955 			break;
956 		case AST_DRAM_2Gx16:
957 			param->reg_AC2   = 0xCC00B02B | trap_AC2;
958 			break;
959 		case AST_DRAM_4Gx16:
960 			param->reg_AC2   = 0xCC00B03F | trap_AC2;
961 			break;
962 		}
963 
964 		break;
965 
966 	case 408:
967 		ast_moutdwm(ast, 0x1E6E2020, 0x01F0);
968 		param->wodt          = 1;
969 		param->rodt          = 0;
970 		param->reg_AC1       = 0x33302714;
971 		param->reg_AC2       = 0xCC00B01B | trap_AC2;
972 		param->reg_DQSIC     = 0x000000E2;
973 		param->reg_MRS       = 0x00000C02 | trap_MRS;
974 		param->reg_EMRS      = 0x00000040;
975 		param->reg_DRV       = 0x000000FA;
976 		param->reg_IOZ       = 0x00000034;
977 		param->reg_DQIDLY    = 0x00000089;
978 		param->reg_FREQ      = 0x000050C0;
979 		param->madj_max      = 96;
980 		param->dll2_finetune_step = 4;
981 
982 		switch (param->dram_chipid) {
983 		case AST_DRAM_512Mx16:
984 			param->reg_AC2   = 0xCC00B016 | trap_AC2;
985 			break;
986 		default:
987 		case AST_DRAM_1Gx16:
988 			param->reg_AC2   = 0xCC00B01B | trap_AC2;
989 			break;
990 		case AST_DRAM_2Gx16:
991 			param->reg_AC2   = 0xCC00B02B | trap_AC2;
992 			break;
993 		case AST_DRAM_4Gx16:
994 			param->reg_AC2   = 0xCC00B03F | trap_AC2;
995 			break;
996 		}
997 
998 		break;
999 	case 456:
1000 		ast_moutdwm(ast, 0x1E6E2020, 0x0230);
1001 		param->wodt          = 0;
1002 		param->reg_AC1       = 0x33302815;
1003 		param->reg_AC2       = 0xCD44B01E;
1004 		param->reg_DQSIC     = 0x000000FC;
1005 		param->reg_MRS       = 0x00000E72;
1006 		param->reg_EMRS      = 0x00000000;
1007 		param->reg_DRV       = 0x00000000;
1008 		param->reg_IOZ       = 0x00000034;
1009 		param->reg_DQIDLY    = 0x00000097;
1010 		param->reg_FREQ      = 0x000052C0;
1011 		param->madj_max      = 88;
1012 		param->dll2_finetune_step = 3;
1013 		break;
1014 	case 504:
1015 		ast_moutdwm(ast, 0x1E6E2020, 0x0261);
1016 		param->wodt          = 1;
1017 		param->rodt          = 1;
1018 		param->reg_AC1       = 0x33302815;
1019 		param->reg_AC2       = 0xDE44C022;
1020 		param->reg_DQSIC     = 0x00000117;
1021 		param->reg_MRS       = 0x00000E72;
1022 		param->reg_EMRS      = 0x00000040;
1023 		param->reg_DRV       = 0x0000000A;
1024 		param->reg_IOZ       = 0x00000045;
1025 		param->reg_DQIDLY    = 0x000000A0;
1026 		param->reg_FREQ      = 0x000054C0;
1027 		param->madj_max      = 79;
1028 		param->dll2_finetune_step = 3;
1029 		break;
1030 	case 528:
1031 		ast_moutdwm(ast, 0x1E6E2020, 0x0120);
1032 		param->wodt          = 1;
1033 		param->rodt          = 1;
1034 		param->reg_AC1       = 0x33302815;
1035 		param->reg_AC2       = 0xEF44D024;
1036 		param->reg_DQSIC     = 0x00000125;
1037 		param->reg_MRS       = 0x00000E72;
1038 		param->reg_EMRS      = 0x00000004;
1039 		param->reg_DRV       = 0x000000F9;
1040 		param->reg_IOZ       = 0x00000045;
1041 		param->reg_DQIDLY    = 0x000000A7;
1042 		param->reg_FREQ      = 0x000055C0;
1043 		param->madj_max      = 76;
1044 		param->dll2_finetune_step = 3;
1045 		break;
1046 	case 552:
1047 		ast_moutdwm(ast, 0x1E6E2020, 0x02A1);
1048 		param->wodt          = 1;
1049 		param->rodt          = 1;
1050 		param->reg_AC1       = 0x43402915;
1051 		param->reg_AC2       = 0xFF44E025;
1052 		param->reg_DQSIC     = 0x00000132;
1053 		param->reg_MRS       = 0x00000E72;
1054 		param->reg_EMRS      = 0x00000040;
1055 		param->reg_DRV       = 0x0000000A;
1056 		param->reg_IOZ       = 0x00000045;
1057 		param->reg_DQIDLY    = 0x000000AD;
1058 		param->reg_FREQ      = 0x000056C0;
1059 		param->madj_max      = 76;
1060 		param->dll2_finetune_step = 3;
1061 		break;
1062 	case 576:
1063 		ast_moutdwm(ast, 0x1E6E2020, 0x0140);
1064 		param->wodt          = 1;
1065 		param->rodt          = 1;
1066 		param->reg_AC1       = 0x43402915;
1067 		param->reg_AC2       = 0xFF44E027;
1068 		param->reg_DQSIC     = 0x0000013F;
1069 		param->reg_MRS       = 0x00000E72;
1070 		param->reg_EMRS      = 0x00000004;
1071 		param->reg_DRV       = 0x000000F5;
1072 		param->reg_IOZ       = 0x00000045;
1073 		param->reg_DQIDLY    = 0x000000B3;
1074 		param->reg_FREQ      = 0x000057C0;
1075 		param->madj_max      = 76;
1076 		param->dll2_finetune_step = 3;
1077 		break;
1078 	}
1079 
1080 	switch (param->dram_chipid) {
1081 	case AST_DRAM_512Mx16:
1082 		param->dram_config = 0x100;
1083 		break;
1084 	default:
1085 	case AST_DRAM_1Gx16:
1086 		param->dram_config = 0x121;
1087 		break;
1088 	case AST_DRAM_2Gx16:
1089 		param->dram_config = 0x122;
1090 		break;
1091 	case AST_DRAM_4Gx16:
1092 		param->dram_config = 0x123;
1093 		break;
1094 	} /* switch size */
1095 
1096 	switch (param->vram_size) {
1097 	default:
1098 	case SZ_8M:
1099 		param->dram_config |= 0x00;
1100 		break;
1101 	case SZ_16M:
1102 		param->dram_config |= 0x04;
1103 		break;
1104 	case SZ_32M:
1105 		param->dram_config |= 0x08;
1106 		break;
1107 	case SZ_64M:
1108 		param->dram_config |= 0x0c;
1109 		break;
1110 	}
1111 }
1112 
1113 static void ddr2_init(struct ast_device *ast, struct ast2300_dram_param *param)
1114 {
1115 	u32 data, data2, retry = 0;
1116 
1117 ddr2_init_start:
1118 	ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
1119 	ast_moutdwm(ast, 0x1E6E0018, 0x00000100);
1120 	ast_moutdwm(ast, 0x1E6E0024, 0x00000000);
1121 	ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
1122 	ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
1123 	udelay(10);
1124 	ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
1125 	udelay(10);
1126 
1127 	ast_moutdwm(ast, 0x1E6E0004, param->dram_config);
1128 	ast_moutdwm(ast, 0x1E6E0008, 0x90040f);
1129 	ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1);
1130 	ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2);
1131 	ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
1132 	ast_moutdwm(ast, 0x1E6E0080, 0x00000000);
1133 	ast_moutdwm(ast, 0x1E6E0084, 0x00000000);
1134 	ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
1135 	ast_moutdwm(ast, 0x1E6E0018, 0x4000A130);
1136 	ast_moutdwm(ast, 0x1E6E0018, 0x00002330);
1137 	ast_moutdwm(ast, 0x1E6E0038, 0x00000000);
1138 	ast_moutdwm(ast, 0x1E6E0040, 0xFF808000);
1139 	ast_moutdwm(ast, 0x1E6E0044, 0x88848466);
1140 	ast_moutdwm(ast, 0x1E6E0048, 0x44440008);
1141 	ast_moutdwm(ast, 0x1E6E004C, 0x00000000);
1142 	ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1143 	ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1144 	ast_moutdwm(ast, 0x1E6E0054, 0);
1145 	ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV);
1146 	ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
1147 	ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1148 	ast_moutdwm(ast, 0x1E6E0074, 0x00000000);
1149 	ast_moutdwm(ast, 0x1E6E0078, 0x00000000);
1150 	ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1151 
1152 	/* Wait MCLK2X lock to MCLK */
1153 	do {
1154 		data = ast_mindwm(ast, 0x1E6E001C);
1155 	} while (!(data & 0x08000000));
1156 	data = ast_mindwm(ast, 0x1E6E001C);
1157 	data = (data >> 8) & 0xff;
1158 	while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
1159 		data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
1160 		if ((data2 & 0xff) > param->madj_max)
1161 			break;
1162 		ast_moutdwm(ast, 0x1E6E0064, data2);
1163 		if (data2 & 0x00100000)
1164 			data2 = ((data2 & 0xff) >> 3) + 3;
1165 		else
1166 			data2 = ((data2 & 0xff) >> 2) + 5;
1167 		data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff;
1168 		data2 += data & 0xff;
1169 		data = data | (data2 << 8);
1170 		ast_moutdwm(ast, 0x1E6E0068, data);
1171 		udelay(10);
1172 		ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000);
1173 		udelay(10);
1174 		data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
1175 		ast_moutdwm(ast, 0x1E6E0018, data);
1176 		data = data | 0x200;
1177 		ast_moutdwm(ast, 0x1E6E0018, data);
1178 		do {
1179 			data = ast_mindwm(ast, 0x1E6E001C);
1180 		} while (!(data & 0x08000000));
1181 
1182 		data = ast_mindwm(ast, 0x1E6E001C);
1183 		data = (data >> 8) & 0xff;
1184 	}
1185 	ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0008) & 0xffff);
1186 	data = ast_mindwm(ast, 0x1E6E0018) | 0xC00;
1187 	ast_moutdwm(ast, 0x1E6E0018, data);
1188 
1189 	ast_moutdwm(ast, 0x1E6E0034, 0x00000001);
1190 	ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
1191 	udelay(50);
1192 	/* Mode Register Setting */
1193 	ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
1194 	ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1195 	ast_moutdwm(ast, 0x1E6E0028, 0x00000005);
1196 	ast_moutdwm(ast, 0x1E6E0028, 0x00000007);
1197 	ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1198 	ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1199 
1200 	ast_moutdwm(ast, 0x1E6E000C, 0x00005C08);
1201 	ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS);
1202 	ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1203 	ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS | 0x380);
1204 	ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1205 	ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1206 	ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1207 
1208 	ast_moutdwm(ast, 0x1E6E000C, 0x7FFF5C01);
1209 	data = 0;
1210 	if (param->wodt)
1211 		data = 0x500;
1212 	if (param->rodt)
1213 		data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1214 	ast_moutdwm(ast, 0x1E6E0034, data | 0x3);
1215 	ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1216 
1217 	/* Calibrate the DQSI delay */
1218 	if ((cbr_dll2(ast, param) == false) && (retry++ < 10))
1219 		goto ddr2_init_start;
1220 
1221 	/* ECC Memory Initialization */
1222 #ifdef ECC
1223 	ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1224 	ast_moutdwm(ast, 0x1E6E0070, 0x221);
1225 	do {
1226 		data = ast_mindwm(ast, 0x1E6E0070);
1227 	} while (!(data & 0x00001000));
1228 	ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1229 	ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1230 	ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1231 #endif
1232 }
1233 
1234 static void ast_post_chip_2300(struct ast_device *ast)
1235 {
1236 	struct ast2300_dram_param param;
1237 	u32 temp;
1238 	u8 reg;
1239 
1240 	reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
1241 	if ((reg & 0x80) == 0) {/* vga only */
1242 		ast_write32(ast, 0xf004, 0x1e6e0000);
1243 		ast_write32(ast, 0xf000, 0x1);
1244 		ast_write32(ast, 0x12000, 0x1688a8a8);
1245 		do {
1246 			;
1247 		} while (ast_read32(ast, 0x12000) != 0x1);
1248 
1249 		ast_write32(ast, 0x10000, 0xfc600309);
1250 		do {
1251 			;
1252 		} while (ast_read32(ast, 0x10000) != 0x1);
1253 
1254 		/* Slow down CPU/AHB CLK in VGA only mode */
1255 		temp = ast_read32(ast, 0x12008);
1256 		temp |= 0x73;
1257 		ast_write32(ast, 0x12008, temp);
1258 
1259 		param.dram_freq = 396;
1260 		param.dram_type = AST_DDR3;
1261 		temp = ast_mindwm(ast, 0x1e6e2070);
1262 		if (temp & 0x01000000)
1263 			param.dram_type = AST_DDR2;
1264 		switch (temp & 0x18000000) {
1265 		case 0:
1266 			param.dram_chipid = AST_DRAM_512Mx16;
1267 			break;
1268 		default:
1269 		case 0x08000000:
1270 			param.dram_chipid = AST_DRAM_1Gx16;
1271 			break;
1272 		case 0x10000000:
1273 			param.dram_chipid = AST_DRAM_2Gx16;
1274 			break;
1275 		case 0x18000000:
1276 			param.dram_chipid = AST_DRAM_4Gx16;
1277 			break;
1278 		}
1279 		switch (temp & 0x0c) {
1280 		default:
1281 		case 0x00:
1282 			param.vram_size = SZ_8M;
1283 			break;
1284 		case 0x04:
1285 			param.vram_size = SZ_16M;
1286 			break;
1287 		case 0x08:
1288 			param.vram_size = SZ_32M;
1289 			break;
1290 		case 0x0c:
1291 			param.vram_size = SZ_64M;
1292 			break;
1293 		}
1294 
1295 		if (param.dram_type == AST_DDR3) {
1296 			get_ddr3_info(ast, &param);
1297 			ddr3_init(ast, &param);
1298 		} else {
1299 			get_ddr2_info(ast, &param);
1300 			ddr2_init(ast, &param);
1301 		}
1302 
1303 		temp = ast_mindwm(ast, 0x1e6e2040);
1304 		ast_moutdwm(ast, 0x1e6e2040, temp | 0x40);
1305 	}
1306 
1307 	/* wait ready */
1308 	do {
1309 		reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
1310 	} while ((reg & 0x40) == 0);
1311 }
1312 
1313 int ast_2300_post(struct ast_device *ast)
1314 {
1315 	ast_2300_set_def_ext_reg(ast);
1316 
1317 	if (ast->config_mode == ast_use_p2a) {
1318 		ast_post_chip_2300(ast);
1319 		ast_init_3rdtx(ast);
1320 	} else {
1321 		if (ast->tx_chip == AST_TX_SIL164) {
1322 			/* Enable DVO */
1323 			ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80);
1324 		}
1325 	}
1326 
1327 	return 0;
1328 }
1329