1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
15 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18 * USE OR OTHER DEALINGS IN THE SOFTWARE.
19 *
20 * The above copyright notice and this permission notice (including the
21 * next paragraph) shall be included in all copies or substantial portions
22 * of the Software.
23 *
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_print.h>
33
34#include "ast_dram_tables.h"
35#include "ast_drv.h"
36
37static void ast_post_chip_2300(struct drm_device *dev);
38static void ast_post_chip_2500(struct drm_device *dev);
39
40static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff };
41static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff };
42
43static void
44ast_set_def_ext_reg(struct drm_device *dev)
45{
46	struct ast_device *ast = to_ast_device(dev);
47	u8 i, index, reg;
48	const u8 *ext_reg_info;
49
50	/* reset scratch */
51	for (i = 0x81; i <= 0x9f; i++)
52		ast_set_index_reg(ast, AST_IO_VGACRI, i, 0x00);
53
54	if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast) || IS_AST_GEN6(ast))
55		ext_reg_info = extreginfo_ast2300;
56	else
57		ext_reg_info = extreginfo;
58
59	index = 0xa0;
60	while (*ext_reg_info != 0xff) {
61		ast_set_index_reg_mask(ast, AST_IO_VGACRI, index, 0x00, *ext_reg_info);
62		index++;
63		ext_reg_info++;
64	}
65
66	/* disable standard IO/MEM decode if secondary */
67	/* ast_set_index_reg-mask(ast, AST_IO_VGACRI, 0xa1, 0xff, 0x3); */
68
69	/* Set Ext. Default */
70	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x8c, 0x00, 0x01);
71	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x00, 0x00);
72
73	/* Enable RAMDAC for A1 */
74	reg = 0x04;
75	if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast) || IS_AST_GEN6(ast))
76		reg |= 0x20;
77	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xff, reg);
78}
79
80static u32 __ast_mindwm(void __iomem *regs, u32 r)
81{
82	u32 data;
83
84	__ast_write32(regs, 0xf004, r & 0xffff0000);
85	__ast_write32(regs, 0xf000, 0x1);
86
87	do {
88		data = __ast_read32(regs, 0xf004) & 0xffff0000;
89	} while (data != (r & 0xffff0000));
90
91	return __ast_read32(regs, 0x10000 + (r & 0x0000ffff));
92}
93
94static void __ast_moutdwm(void __iomem *regs, u32 r, u32 v)
95{
96	u32 data;
97
98	__ast_write32(regs, 0xf004, r & 0xffff0000);
99	__ast_write32(regs, 0xf000, 0x1);
100
101	do {
102		data = __ast_read32(regs, 0xf004) & 0xffff0000;
103	} while (data != (r & 0xffff0000));
104
105	__ast_write32(regs, 0x10000 + (r & 0x0000ffff), v);
106}
107
108u32 ast_mindwm(struct ast_device *ast, u32 r)
109{
110	return __ast_mindwm(ast->regs, r);
111}
112
113void ast_moutdwm(struct ast_device *ast, u32 r, u32 v)
114{
115	__ast_moutdwm(ast->regs, r, v);
116}
117
118/*
119 * AST2100/2150 DLL CBR Setting
120 */
121#define CBR_SIZE_AST2150	     ((16 << 10) - 1)
122#define CBR_PASSNUM_AST2150          5
123#define CBR_THRESHOLD_AST2150        10
124#define CBR_THRESHOLD2_AST2150       10
125#define TIMEOUT_AST2150              5000000
126
127#define CBR_PATNUM_AST2150           8
128
129static const u32 pattern_AST2150[14] = {
130	0xFF00FF00,
131	0xCC33CC33,
132	0xAA55AA55,
133	0xFFFE0001,
134	0x683501FE,
135	0x0F1929B0,
136	0x2D0B4346,
137	0x60767F02,
138	0x6FBE36A6,
139	0x3A253035,
140	0x3019686D,
141	0x41C6167E,
142	0x620152BF,
143	0x20F050E0
144};
145
146static u32 mmctestburst2_ast2150(struct ast_device *ast, u32 datagen)
147{
148	u32 data, timeout;
149
150	ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
151	ast_moutdwm(ast, 0x1e6e0070, 0x00000001 | (datagen << 3));
152	timeout = 0;
153	do {
154		data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
155		if (++timeout > TIMEOUT_AST2150) {
156			ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
157			return 0xffffffff;
158		}
159	} while (!data);
160	ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
161	ast_moutdwm(ast, 0x1e6e0070, 0x00000003 | (datagen << 3));
162	timeout = 0;
163	do {
164		data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
165		if (++timeout > TIMEOUT_AST2150) {
166			ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
167			return 0xffffffff;
168		}
169	} while (!data);
170	data = (ast_mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
171	ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
172	return data;
173}
174
175#if 0 /* unused in DDX driver - here for completeness */
176static u32 mmctestsingle2_ast2150(struct ast_device *ast, u32 datagen)
177{
178	u32 data, timeout;
179
180	ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
181	ast_moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3));
182	timeout = 0;
183	do {
184		data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
185		if (++timeout > TIMEOUT_AST2150) {
186			ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
187			return 0xffffffff;
188		}
189	} while (!data);
190	data = (ast_mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
191	ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
192	return data;
193}
194#endif
195
196static int cbrtest_ast2150(struct ast_device *ast)
197{
198	int i;
199
200	for (i = 0; i < 8; i++)
201		if (mmctestburst2_ast2150(ast, i))
202			return 0;
203	return 1;
204}
205
206static int cbrscan_ast2150(struct ast_device *ast, int busw)
207{
208	u32 patcnt, loop;
209
210	for (patcnt = 0; patcnt < CBR_PATNUM_AST2150; patcnt++) {
211		ast_moutdwm(ast, 0x1e6e007c, pattern_AST2150[patcnt]);
212		for (loop = 0; loop < CBR_PASSNUM_AST2150; loop++) {
213			if (cbrtest_ast2150(ast))
214				break;
215		}
216		if (loop == CBR_PASSNUM_AST2150)
217			return 0;
218	}
219	return 1;
220}
221
222
223static void cbrdlli_ast2150(struct ast_device *ast, int busw)
224{
225	u32 dll_min[4], dll_max[4], dlli, data, passcnt;
226
227cbr_start:
228	dll_min[0] = dll_min[1] = dll_min[2] = dll_min[3] = 0xff;
229	dll_max[0] = dll_max[1] = dll_max[2] = dll_max[3] = 0x0;
230	passcnt = 0;
231
232	for (dlli = 0; dlli < 100; dlli++) {
233		ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
234		data = cbrscan_ast2150(ast, busw);
235		if (data != 0) {
236			if (data & 0x1) {
237				if (dll_min[0] > dlli)
238					dll_min[0] = dlli;
239				if (dll_max[0] < dlli)
240					dll_max[0] = dlli;
241			}
242			passcnt++;
243		} else if (passcnt >= CBR_THRESHOLD_AST2150)
244			goto cbr_start;
245	}
246	if (dll_max[0] == 0 || (dll_max[0]-dll_min[0]) < CBR_THRESHOLD_AST2150)
247		goto cbr_start;
248
249	dlli = dll_min[0] + (((dll_max[0] - dll_min[0]) * 7) >> 4);
250	ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
251}
252
253
254
255static void ast_init_dram_reg(struct drm_device *dev)
256{
257	struct ast_device *ast = to_ast_device(dev);
258	u8 j;
259	u32 data, temp, i;
260	const struct ast_dramstruct *dram_reg_info;
261
262	j = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
263
264	if ((j & 0x80) == 0) { /* VGA only */
265		if (IS_AST_GEN1(ast)) {
266			dram_reg_info = ast2000_dram_table_data;
267			ast_write32(ast, 0xf004, 0x1e6e0000);
268			ast_write32(ast, 0xf000, 0x1);
269			ast_write32(ast, 0x10100, 0xa8);
270
271			do {
272				;
273			} while (ast_read32(ast, 0x10100) != 0xa8);
274		} else { /* GEN2/GEN3 */
275			if (ast->chip == AST2100 || ast->chip == AST2200)
276				dram_reg_info = ast2100_dram_table_data;
277			else
278				dram_reg_info = ast1100_dram_table_data;
279
280			ast_write32(ast, 0xf004, 0x1e6e0000);
281			ast_write32(ast, 0xf000, 0x1);
282			ast_write32(ast, 0x12000, 0x1688A8A8);
283			do {
284				;
285			} while (ast_read32(ast, 0x12000) != 0x01);
286
287			ast_write32(ast, 0x10000, 0xfc600309);
288			do {
289				;
290			} while (ast_read32(ast, 0x10000) != 0x01);
291		}
292
293		while (dram_reg_info->index != 0xffff) {
294			if (dram_reg_info->index == 0xff00) {/* delay fn */
295				for (i = 0; i < 15; i++)
296					udelay(dram_reg_info->data);
297			} else if (dram_reg_info->index == 0x4 && !IS_AST_GEN1(ast)) {
298				data = dram_reg_info->data;
299				if (ast->dram_type == AST_DRAM_1Gx16)
300					data = 0x00000d89;
301				else if (ast->dram_type == AST_DRAM_1Gx32)
302					data = 0x00000c8d;
303
304				temp = ast_read32(ast, 0x12070);
305				temp &= 0xc;
306				temp <<= 2;
307				ast_write32(ast, 0x10000 + dram_reg_info->index, data | temp);
308			} else
309				ast_write32(ast, 0x10000 + dram_reg_info->index, dram_reg_info->data);
310			dram_reg_info++;
311		}
312
313		/* AST 2100/2150 DRAM calibration */
314		data = ast_read32(ast, 0x10120);
315		if (data == 0x5061) { /* 266Mhz */
316			data = ast_read32(ast, 0x10004);
317			if (data & 0x40)
318				cbrdlli_ast2150(ast, 16); /* 16 bits */
319			else
320				cbrdlli_ast2150(ast, 32); /* 32 bits */
321		}
322
323		switch (AST_GEN(ast)) {
324		case 1:
325			temp = ast_read32(ast, 0x10140);
326			ast_write32(ast, 0x10140, temp | 0x40);
327			break;
328		case 2:
329		case 3:
330			temp = ast_read32(ast, 0x1200c);
331			ast_write32(ast, 0x1200c, temp & 0xfffffffd);
332			temp = ast_read32(ast, 0x12040);
333			ast_write32(ast, 0x12040, temp | 0x40);
334			break;
335		default:
336			break;
337		}
338	}
339
340	/* wait ready */
341	do {
342		j = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
343	} while ((j & 0x40) == 0);
344}
345
346void ast_post_gpu(struct drm_device *dev)
347{
348	struct ast_device *ast = to_ast_device(dev);
349
350	ast_set_def_ext_reg(dev);
351
352	if (IS_AST_GEN7(ast)) {
353		if (ast->tx_chip_types & AST_TX_ASTDP_BIT)
354			ast_dp_launch(dev);
355	} else if (ast->config_mode == ast_use_p2a) {
356		if (IS_AST_GEN6(ast))
357			ast_post_chip_2500(dev);
358		else if (IS_AST_GEN5(ast) || IS_AST_GEN4(ast))
359			ast_post_chip_2300(dev);
360		else
361			ast_init_dram_reg(dev);
362
363		ast_init_3rdtx(dev);
364	} else {
365		if (ast->tx_chip_types & AST_TX_SIL164_BIT)
366			ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80);	/* Enable DVO */
367	}
368}
369
370/* AST 2300 DRAM settings */
371#define AST_DDR3 0
372#define AST_DDR2 1
373
374struct ast2300_dram_param {
375	u32 dram_type;
376	u32 dram_chipid;
377	u32 dram_freq;
378	u32 vram_size;
379	u32 odt;
380	u32 wodt;
381	u32 rodt;
382	u32 dram_config;
383	u32 reg_PERIOD;
384	u32 reg_MADJ;
385	u32 reg_SADJ;
386	u32 reg_MRS;
387	u32 reg_EMRS;
388	u32 reg_AC1;
389	u32 reg_AC2;
390	u32 reg_DQSIC;
391	u32 reg_DRV;
392	u32 reg_IOZ;
393	u32 reg_DQIDLY;
394	u32 reg_FREQ;
395	u32 madj_max;
396	u32 dll2_finetune_step;
397};
398
399/*
400 * DQSI DLL CBR Setting
401 */
402#define CBR_SIZE0            ((1  << 10) - 1)
403#define CBR_SIZE1            ((4  << 10) - 1)
404#define CBR_SIZE2            ((64 << 10) - 1)
405#define CBR_PASSNUM          5
406#define CBR_PASSNUM2         5
407#define CBR_THRESHOLD        10
408#define CBR_THRESHOLD2       10
409#define TIMEOUT              5000000
410#define CBR_PATNUM           8
411
412static const u32 pattern[8] = {
413	0xFF00FF00,
414	0xCC33CC33,
415	0xAA55AA55,
416	0x88778877,
417	0x92CC4D6E,
418	0x543D3CDE,
419	0xF1E843C7,
420	0x7C61D253
421};
422
423static bool mmc_test(struct ast_device *ast, u32 datagen, u8 test_ctl)
424{
425	u32 data, timeout;
426
427	ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
428	ast_moutdwm(ast, 0x1e6e0070, (datagen << 3) | test_ctl);
429	timeout = 0;
430	do {
431		data = ast_mindwm(ast, 0x1e6e0070) & 0x3000;
432		if (data & 0x2000)
433			return false;
434		if (++timeout > TIMEOUT) {
435			ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
436			return false;
437		}
438	} while (!data);
439	ast_moutdwm(ast, 0x1e6e0070, 0x0);
440	return true;
441}
442
443static u32 mmc_test2(struct ast_device *ast, u32 datagen, u8 test_ctl)
444{
445	u32 data, timeout;
446
447	ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
448	ast_moutdwm(ast, 0x1e6e0070, (datagen << 3) | test_ctl);
449	timeout = 0;
450	do {
451		data = ast_mindwm(ast, 0x1e6e0070) & 0x1000;
452		if (++timeout > TIMEOUT) {
453			ast_moutdwm(ast, 0x1e6e0070, 0x0);
454			return 0xffffffff;
455		}
456	} while (!data);
457	data = ast_mindwm(ast, 0x1e6e0078);
458	data = (data | (data >> 16)) & 0xffff;
459	ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
460	return data;
461}
462
463
464static bool mmc_test_burst(struct ast_device *ast, u32 datagen)
465{
466	return mmc_test(ast, datagen, 0xc1);
467}
468
469static u32 mmc_test_burst2(struct ast_device *ast, u32 datagen)
470{
471	return mmc_test2(ast, datagen, 0x41);
472}
473
474static bool mmc_test_single(struct ast_device *ast, u32 datagen)
475{
476	return mmc_test(ast, datagen, 0xc5);
477}
478
479static u32 mmc_test_single2(struct ast_device *ast, u32 datagen)
480{
481	return mmc_test2(ast, datagen, 0x05);
482}
483
484static bool mmc_test_single_2500(struct ast_device *ast, u32 datagen)
485{
486	return mmc_test(ast, datagen, 0x85);
487}
488
489static int cbr_test(struct ast_device *ast)
490{
491	u32 data;
492	int i;
493	data = mmc_test_single2(ast, 0);
494	if ((data & 0xff) && (data & 0xff00))
495		return 0;
496	for (i = 0; i < 8; i++) {
497		data = mmc_test_burst2(ast, i);
498		if ((data & 0xff) && (data & 0xff00))
499			return 0;
500	}
501	if (!data)
502		return 3;
503	else if (data & 0xff)
504		return 2;
505	return 1;
506}
507
508static int cbr_scan(struct ast_device *ast)
509{
510	u32 data, data2, patcnt, loop;
511
512	data2 = 3;
513	for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
514		ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
515		for (loop = 0; loop < CBR_PASSNUM2; loop++) {
516			if ((data = cbr_test(ast)) != 0) {
517				data2 &= data;
518				if (!data2)
519					return 0;
520				break;
521			}
522		}
523		if (loop == CBR_PASSNUM2)
524			return 0;
525	}
526	return data2;
527}
528
529static u32 cbr_test2(struct ast_device *ast)
530{
531	u32 data;
532
533	data = mmc_test_burst2(ast, 0);
534	if (data == 0xffff)
535		return 0;
536	data |= mmc_test_single2(ast, 0);
537	if (data == 0xffff)
538		return 0;
539
540	return ~data & 0xffff;
541}
542
543static u32 cbr_scan2(struct ast_device *ast)
544{
545	u32 data, data2, patcnt, loop;
546
547	data2 = 0xffff;
548	for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
549		ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
550		for (loop = 0; loop < CBR_PASSNUM2; loop++) {
551			if ((data = cbr_test2(ast)) != 0) {
552				data2 &= data;
553				if (!data2)
554					return 0;
555				break;
556			}
557		}
558		if (loop == CBR_PASSNUM2)
559			return 0;
560	}
561	return data2;
562}
563
564static bool cbr_test3(struct ast_device *ast)
565{
566	if (!mmc_test_burst(ast, 0))
567		return false;
568	if (!mmc_test_single(ast, 0))
569		return false;
570	return true;
571}
572
573static bool cbr_scan3(struct ast_device *ast)
574{
575	u32 patcnt, loop;
576
577	for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
578		ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
579		for (loop = 0; loop < 2; loop++) {
580			if (cbr_test3(ast))
581				break;
582		}
583		if (loop == 2)
584			return false;
585	}
586	return true;
587}
588
589static bool finetuneDQI_L(struct ast_device *ast, struct ast2300_dram_param *param)
590{
591	u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, retry = 0;
592	bool status = false;
593FINETUNE_START:
594	for (cnt = 0; cnt < 16; cnt++) {
595		dllmin[cnt] = 0xff;
596		dllmax[cnt] = 0x0;
597	}
598	passcnt = 0;
599	for (dlli = 0; dlli < 76; dlli++) {
600		ast_moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
601		ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE1);
602		data = cbr_scan2(ast);
603		if (data != 0) {
604			mask = 0x00010001;
605			for (cnt = 0; cnt < 16; cnt++) {
606				if (data & mask) {
607					if (dllmin[cnt] > dlli) {
608						dllmin[cnt] = dlli;
609					}
610					if (dllmax[cnt] < dlli) {
611						dllmax[cnt] = dlli;
612					}
613				}
614				mask <<= 1;
615			}
616			passcnt++;
617		} else if (passcnt >= CBR_THRESHOLD2) {
618			break;
619		}
620	}
621	gold_sadj[0] = 0x0;
622	passcnt = 0;
623	for (cnt = 0; cnt < 16; cnt++) {
624		if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
625			gold_sadj[0] += dllmin[cnt];
626			passcnt++;
627		}
628	}
629	if (retry++ > 10)
630		goto FINETUNE_DONE;
631	if (passcnt != 16) {
632		goto FINETUNE_START;
633	}
634	status = true;
635FINETUNE_DONE:
636	gold_sadj[0] = gold_sadj[0] >> 4;
637	gold_sadj[1] = gold_sadj[0];
638
639	data = 0;
640	for (cnt = 0; cnt < 8; cnt++) {
641		data >>= 3;
642		if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
643			dlli = dllmin[cnt];
644			if (gold_sadj[0] >= dlli) {
645				dlli = ((gold_sadj[0] - dlli) * 19) >> 5;
646				if (dlli > 3) {
647					dlli = 3;
648				}
649			} else {
650				dlli = ((dlli - gold_sadj[0]) * 19) >> 5;
651				if (dlli > 4) {
652					dlli = 4;
653				}
654				dlli = (8 - dlli) & 0x7;
655			}
656			data |= dlli << 21;
657		}
658	}
659	ast_moutdwm(ast, 0x1E6E0080, data);
660
661	data = 0;
662	for (cnt = 8; cnt < 16; cnt++) {
663		data >>= 3;
664		if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
665			dlli = dllmin[cnt];
666			if (gold_sadj[1] >= dlli) {
667				dlli = ((gold_sadj[1] - dlli) * 19) >> 5;
668				if (dlli > 3) {
669					dlli = 3;
670				} else {
671					dlli = (dlli - 1) & 0x7;
672				}
673			} else {
674				dlli = ((dlli - gold_sadj[1]) * 19) >> 5;
675				dlli += 1;
676				if (dlli > 4) {
677					dlli = 4;
678				}
679				dlli = (8 - dlli) & 0x7;
680			}
681			data |= dlli << 21;
682		}
683	}
684	ast_moutdwm(ast, 0x1E6E0084, data);
685	return status;
686} /* finetuneDQI_L */
687
688static void finetuneDQSI(struct ast_device *ast)
689{
690	u32 dlli, dqsip, dqidly;
691	u32 reg_mcr18, reg_mcr0c, passcnt[2], diff;
692	u32 g_dqidly, g_dqsip, g_margin, g_side;
693	u16 pass[32][2][2];
694	char tag[2][76];
695
696	/* Disable DQI CBR */
697	reg_mcr0c  = ast_mindwm(ast, 0x1E6E000C);
698	reg_mcr18  = ast_mindwm(ast, 0x1E6E0018);
699	reg_mcr18 &= 0x0000ffff;
700	ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
701
702	for (dlli = 0; dlli < 76; dlli++) {
703		tag[0][dlli] = 0x0;
704		tag[1][dlli] = 0x0;
705	}
706	for (dqidly = 0; dqidly < 32; dqidly++) {
707		pass[dqidly][0][0] = 0xff;
708		pass[dqidly][0][1] = 0x0;
709		pass[dqidly][1][0] = 0xff;
710		pass[dqidly][1][1] = 0x0;
711	}
712	for (dqidly = 0; dqidly < 32; dqidly++) {
713		passcnt[0] = passcnt[1] = 0;
714		for (dqsip = 0; dqsip < 2; dqsip++) {
715			ast_moutdwm(ast, 0x1E6E000C, 0);
716			ast_moutdwm(ast, 0x1E6E0018, reg_mcr18 | (dqidly << 16) | (dqsip << 23));
717			ast_moutdwm(ast, 0x1E6E000C, reg_mcr0c);
718			for (dlli = 0; dlli < 76; dlli++) {
719				ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
720				ast_moutdwm(ast, 0x1E6E0070, 0);
721				ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE0);
722				if (cbr_scan3(ast)) {
723					if (dlli == 0)
724						break;
725					passcnt[dqsip]++;
726					tag[dqsip][dlli] = 'P';
727					if (dlli < pass[dqidly][dqsip][0])
728						pass[dqidly][dqsip][0] = (u16) dlli;
729					if (dlli > pass[dqidly][dqsip][1])
730						pass[dqidly][dqsip][1] = (u16) dlli;
731				} else if (passcnt[dqsip] >= 5)
732					break;
733				else {
734					pass[dqidly][dqsip][0] = 0xff;
735					pass[dqidly][dqsip][1] = 0x0;
736				}
737			}
738		}
739		if (passcnt[0] == 0 && passcnt[1] == 0)
740			dqidly++;
741	}
742	/* Search margin */
743	g_dqidly = g_dqsip = g_margin = g_side = 0;
744
745	for (dqidly = 0; dqidly < 32; dqidly++) {
746		for (dqsip = 0; dqsip < 2; dqsip++) {
747			if (pass[dqidly][dqsip][0] > pass[dqidly][dqsip][1])
748				continue;
749			diff = pass[dqidly][dqsip][1] - pass[dqidly][dqsip][0];
750			if ((diff+2) < g_margin)
751				continue;
752			passcnt[0] = passcnt[1] = 0;
753			for (dlli = pass[dqidly][dqsip][0]; dlli > 0  && tag[dqsip][dlli] != 0; dlli--, passcnt[0]++);
754			for (dlli = pass[dqidly][dqsip][1]; dlli < 76 && tag[dqsip][dlli] != 0; dlli++, passcnt[1]++);
755			if (passcnt[0] > passcnt[1])
756				passcnt[0] = passcnt[1];
757			passcnt[1] = 0;
758			if (passcnt[0] > g_side)
759				passcnt[1] = passcnt[0] - g_side;
760			if (diff > (g_margin+1) && (passcnt[1] > 0 || passcnt[0] > 8)) {
761				g_margin = diff;
762				g_dqidly = dqidly;
763				g_dqsip  = dqsip;
764				g_side   = passcnt[0];
765			} else if (passcnt[1] > 1 && g_side < 8) {
766				if (diff > g_margin)
767					g_margin = diff;
768				g_dqidly = dqidly;
769				g_dqsip  = dqsip;
770				g_side   = passcnt[0];
771			}
772		}
773	}
774	reg_mcr18 = reg_mcr18 | (g_dqidly << 16) | (g_dqsip << 23);
775	ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
776
777}
778static bool cbr_dll2(struct ast_device *ast, struct ast2300_dram_param *param)
779{
780	u32 dllmin[2], dllmax[2], dlli, data, passcnt, retry = 0;
781	bool status = false;
782
783	finetuneDQSI(ast);
784	if (finetuneDQI_L(ast, param) == false)
785		return status;
786
787CBR_START2:
788	dllmin[0] = dllmin[1] = 0xff;
789	dllmax[0] = dllmax[1] = 0x0;
790	passcnt = 0;
791	for (dlli = 0; dlli < 76; dlli++) {
792		ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
793		ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE2);
794		data = cbr_scan(ast);
795		if (data != 0) {
796			if (data & 0x1) {
797				if (dllmin[0] > dlli) {
798					dllmin[0] = dlli;
799				}
800				if (dllmax[0] < dlli) {
801					dllmax[0] = dlli;
802				}
803			}
804			if (data & 0x2) {
805				if (dllmin[1] > dlli) {
806					dllmin[1] = dlli;
807				}
808				if (dllmax[1] < dlli) {
809					dllmax[1] = dlli;
810				}
811			}
812			passcnt++;
813		} else if (passcnt >= CBR_THRESHOLD) {
814			break;
815		}
816	}
817	if (retry++ > 10)
818		goto CBR_DONE2;
819	if (dllmax[0] == 0 || (dllmax[0]-dllmin[0]) < CBR_THRESHOLD) {
820		goto CBR_START2;
821	}
822	if (dllmax[1] == 0 || (dllmax[1]-dllmin[1]) < CBR_THRESHOLD) {
823		goto CBR_START2;
824	}
825	status = true;
826CBR_DONE2:
827	dlli  = (dllmin[1] + dllmax[1]) >> 1;
828	dlli <<= 8;
829	dlli += (dllmin[0] + dllmax[0]) >> 1;
830	ast_moutdwm(ast, 0x1E6E0068, ast_mindwm(ast, 0x1E720058) | (dlli << 16));
831	return status;
832} /* CBRDLL2 */
833
834static void get_ddr3_info(struct ast_device *ast, struct ast2300_dram_param *param)
835{
836	u32 trap, trap_AC2, trap_MRS;
837
838	ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
839
840	/* Ger trap info */
841	trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
842	trap_AC2  = 0x00020000 + (trap << 16);
843	trap_AC2 |= 0x00300000 + ((trap & 0x2) << 19);
844	trap_MRS  = 0x00000010 + (trap << 4);
845	trap_MRS |= ((trap & 0x2) << 18);
846
847	param->reg_MADJ       = 0x00034C4C;
848	param->reg_SADJ       = 0x00001800;
849	param->reg_DRV        = 0x000000F0;
850	param->reg_PERIOD     = param->dram_freq;
851	param->rodt           = 0;
852
853	switch (param->dram_freq) {
854	case 336:
855		ast_moutdwm(ast, 0x1E6E2020, 0x0190);
856		param->wodt          = 0;
857		param->reg_AC1       = 0x22202725;
858		param->reg_AC2       = 0xAA007613 | trap_AC2;
859		param->reg_DQSIC     = 0x000000BA;
860		param->reg_MRS       = 0x04001400 | trap_MRS;
861		param->reg_EMRS      = 0x00000000;
862		param->reg_IOZ       = 0x00000023;
863		param->reg_DQIDLY    = 0x00000074;
864		param->reg_FREQ      = 0x00004DC0;
865		param->madj_max      = 96;
866		param->dll2_finetune_step = 3;
867		switch (param->dram_chipid) {
868		default:
869		case AST_DRAM_512Mx16:
870		case AST_DRAM_1Gx16:
871			param->reg_AC2   = 0xAA007613 | trap_AC2;
872			break;
873		case AST_DRAM_2Gx16:
874			param->reg_AC2   = 0xAA00761C | trap_AC2;
875			break;
876		case AST_DRAM_4Gx16:
877			param->reg_AC2   = 0xAA007636 | trap_AC2;
878			break;
879		}
880		break;
881	default:
882	case 396:
883		ast_moutdwm(ast, 0x1E6E2020, 0x03F1);
884		param->wodt          = 1;
885		param->reg_AC1       = 0x33302825;
886		param->reg_AC2       = 0xCC009617 | trap_AC2;
887		param->reg_DQSIC     = 0x000000E2;
888		param->reg_MRS       = 0x04001600 | trap_MRS;
889		param->reg_EMRS      = 0x00000000;
890		param->reg_IOZ       = 0x00000034;
891		param->reg_DRV       = 0x000000FA;
892		param->reg_DQIDLY    = 0x00000089;
893		param->reg_FREQ      = 0x00005040;
894		param->madj_max      = 96;
895		param->dll2_finetune_step = 4;
896
897		switch (param->dram_chipid) {
898		default:
899		case AST_DRAM_512Mx16:
900		case AST_DRAM_1Gx16:
901			param->reg_AC2   = 0xCC009617 | trap_AC2;
902			break;
903		case AST_DRAM_2Gx16:
904			param->reg_AC2   = 0xCC009622 | trap_AC2;
905			break;
906		case AST_DRAM_4Gx16:
907			param->reg_AC2   = 0xCC00963F | trap_AC2;
908			break;
909		}
910		break;
911
912	case 408:
913		ast_moutdwm(ast, 0x1E6E2020, 0x01F0);
914		param->wodt          = 1;
915		param->reg_AC1       = 0x33302825;
916		param->reg_AC2       = 0xCC009617 | trap_AC2;
917		param->reg_DQSIC     = 0x000000E2;
918		param->reg_MRS       = 0x04001600 | trap_MRS;
919		param->reg_EMRS      = 0x00000000;
920		param->reg_IOZ       = 0x00000023;
921		param->reg_DRV       = 0x000000FA;
922		param->reg_DQIDLY    = 0x00000089;
923		param->reg_FREQ      = 0x000050C0;
924		param->madj_max      = 96;
925		param->dll2_finetune_step = 4;
926
927		switch (param->dram_chipid) {
928		default:
929		case AST_DRAM_512Mx16:
930		case AST_DRAM_1Gx16:
931			param->reg_AC2   = 0xCC009617 | trap_AC2;
932			break;
933		case AST_DRAM_2Gx16:
934			param->reg_AC2   = 0xCC009622 | trap_AC2;
935			break;
936		case AST_DRAM_4Gx16:
937			param->reg_AC2   = 0xCC00963F | trap_AC2;
938			break;
939		}
940
941		break;
942	case 456:
943		ast_moutdwm(ast, 0x1E6E2020, 0x0230);
944		param->wodt          = 0;
945		param->reg_AC1       = 0x33302926;
946		param->reg_AC2       = 0xCD44961A;
947		param->reg_DQSIC     = 0x000000FC;
948		param->reg_MRS       = 0x00081830;
949		param->reg_EMRS      = 0x00000000;
950		param->reg_IOZ       = 0x00000045;
951		param->reg_DQIDLY    = 0x00000097;
952		param->reg_FREQ      = 0x000052C0;
953		param->madj_max      = 88;
954		param->dll2_finetune_step = 4;
955		break;
956	case 504:
957		ast_moutdwm(ast, 0x1E6E2020, 0x0270);
958		param->wodt          = 1;
959		param->reg_AC1       = 0x33302926;
960		param->reg_AC2       = 0xDE44A61D;
961		param->reg_DQSIC     = 0x00000117;
962		param->reg_MRS       = 0x00081A30;
963		param->reg_EMRS      = 0x00000000;
964		param->reg_IOZ       = 0x070000BB;
965		param->reg_DQIDLY    = 0x000000A0;
966		param->reg_FREQ      = 0x000054C0;
967		param->madj_max      = 79;
968		param->dll2_finetune_step = 4;
969		break;
970	case 528:
971		ast_moutdwm(ast, 0x1E6E2020, 0x0290);
972		param->wodt          = 1;
973		param->rodt          = 1;
974		param->reg_AC1       = 0x33302926;
975		param->reg_AC2       = 0xEF44B61E;
976		param->reg_DQSIC     = 0x00000125;
977		param->reg_MRS       = 0x00081A30;
978		param->reg_EMRS      = 0x00000040;
979		param->reg_DRV       = 0x000000F5;
980		param->reg_IOZ       = 0x00000023;
981		param->reg_DQIDLY    = 0x00000088;
982		param->reg_FREQ      = 0x000055C0;
983		param->madj_max      = 76;
984		param->dll2_finetune_step = 3;
985		break;
986	case 576:
987		ast_moutdwm(ast, 0x1E6E2020, 0x0140);
988		param->reg_MADJ      = 0x00136868;
989		param->reg_SADJ      = 0x00004534;
990		param->wodt          = 1;
991		param->rodt          = 1;
992		param->reg_AC1       = 0x33302A37;
993		param->reg_AC2       = 0xEF56B61E;
994		param->reg_DQSIC     = 0x0000013F;
995		param->reg_MRS       = 0x00101A50;
996		param->reg_EMRS      = 0x00000040;
997		param->reg_DRV       = 0x000000FA;
998		param->reg_IOZ       = 0x00000023;
999		param->reg_DQIDLY    = 0x00000078;
1000		param->reg_FREQ      = 0x000057C0;
1001		param->madj_max      = 136;
1002		param->dll2_finetune_step = 3;
1003		break;
1004	case 600:
1005		ast_moutdwm(ast, 0x1E6E2020, 0x02E1);
1006		param->reg_MADJ      = 0x00136868;
1007		param->reg_SADJ      = 0x00004534;
1008		param->wodt          = 1;
1009		param->rodt          = 1;
1010		param->reg_AC1       = 0x32302A37;
1011		param->reg_AC2       = 0xDF56B61F;
1012		param->reg_DQSIC     = 0x0000014D;
1013		param->reg_MRS       = 0x00101A50;
1014		param->reg_EMRS      = 0x00000004;
1015		param->reg_DRV       = 0x000000F5;
1016		param->reg_IOZ       = 0x00000023;
1017		param->reg_DQIDLY    = 0x00000078;
1018		param->reg_FREQ      = 0x000058C0;
1019		param->madj_max      = 132;
1020		param->dll2_finetune_step = 3;
1021		break;
1022	case 624:
1023		ast_moutdwm(ast, 0x1E6E2020, 0x0160);
1024		param->reg_MADJ      = 0x00136868;
1025		param->reg_SADJ      = 0x00004534;
1026		param->wodt          = 1;
1027		param->rodt          = 1;
1028		param->reg_AC1       = 0x32302A37;
1029		param->reg_AC2       = 0xEF56B621;
1030		param->reg_DQSIC     = 0x0000015A;
1031		param->reg_MRS       = 0x02101A50;
1032		param->reg_EMRS      = 0x00000004;
1033		param->reg_DRV       = 0x000000F5;
1034		param->reg_IOZ       = 0x00000034;
1035		param->reg_DQIDLY    = 0x00000078;
1036		param->reg_FREQ      = 0x000059C0;
1037		param->madj_max      = 128;
1038		param->dll2_finetune_step = 3;
1039		break;
1040	} /* switch freq */
1041
1042	switch (param->dram_chipid) {
1043	case AST_DRAM_512Mx16:
1044		param->dram_config = 0x130;
1045		break;
1046	default:
1047	case AST_DRAM_1Gx16:
1048		param->dram_config = 0x131;
1049		break;
1050	case AST_DRAM_2Gx16:
1051		param->dram_config = 0x132;
1052		break;
1053	case AST_DRAM_4Gx16:
1054		param->dram_config = 0x133;
1055		break;
1056	} /* switch size */
1057
1058	switch (param->vram_size) {
1059	default:
1060	case AST_VIDMEM_SIZE_8M:
1061		param->dram_config |= 0x00;
1062		break;
1063	case AST_VIDMEM_SIZE_16M:
1064		param->dram_config |= 0x04;
1065		break;
1066	case AST_VIDMEM_SIZE_32M:
1067		param->dram_config |= 0x08;
1068		break;
1069	case AST_VIDMEM_SIZE_64M:
1070		param->dram_config |= 0x0c;
1071		break;
1072	}
1073
1074}
1075
1076static void ddr3_init(struct ast_device *ast, struct ast2300_dram_param *param)
1077{
1078	u32 data, data2, retry = 0;
1079
1080ddr3_init_start:
1081	ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
1082	ast_moutdwm(ast, 0x1E6E0018, 0x00000100);
1083	ast_moutdwm(ast, 0x1E6E0024, 0x00000000);
1084	ast_moutdwm(ast, 0x1E6E0034, 0x00000000);
1085	udelay(10);
1086	ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
1087	ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
1088	udelay(10);
1089	ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
1090	udelay(10);
1091
1092	ast_moutdwm(ast, 0x1E6E0004, param->dram_config);
1093	ast_moutdwm(ast, 0x1E6E0008, 0x90040f);
1094	ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1);
1095	ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2);
1096	ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
1097	ast_moutdwm(ast, 0x1E6E0080, 0x00000000);
1098	ast_moutdwm(ast, 0x1E6E0084, 0x00000000);
1099	ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
1100	ast_moutdwm(ast, 0x1E6E0018, 0x4000A170);
1101	ast_moutdwm(ast, 0x1E6E0018, 0x00002370);
1102	ast_moutdwm(ast, 0x1E6E0038, 0x00000000);
1103	ast_moutdwm(ast, 0x1E6E0040, 0xFF444444);
1104	ast_moutdwm(ast, 0x1E6E0044, 0x22222222);
1105	ast_moutdwm(ast, 0x1E6E0048, 0x22222222);
1106	ast_moutdwm(ast, 0x1E6E004C, 0x00000002);
1107	ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1108	ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1109	ast_moutdwm(ast, 0x1E6E0054, 0);
1110	ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV);
1111	ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
1112	ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1113	ast_moutdwm(ast, 0x1E6E0074, 0x00000000);
1114	ast_moutdwm(ast, 0x1E6E0078, 0x00000000);
1115	ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1116	/* Wait MCLK2X lock to MCLK */
1117	do {
1118		data = ast_mindwm(ast, 0x1E6E001C);
1119	} while (!(data & 0x08000000));
1120	data = ast_mindwm(ast, 0x1E6E001C);
1121	data = (data >> 8) & 0xff;
1122	while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
1123		data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
1124		if ((data2 & 0xff) > param->madj_max) {
1125			break;
1126		}
1127		ast_moutdwm(ast, 0x1E6E0064, data2);
1128		if (data2 & 0x00100000) {
1129			data2 = ((data2 & 0xff) >> 3) + 3;
1130		} else {
1131			data2 = ((data2 & 0xff) >> 2) + 5;
1132		}
1133		data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff;
1134		data2 += data & 0xff;
1135		data = data | (data2 << 8);
1136		ast_moutdwm(ast, 0x1E6E0068, data);
1137		udelay(10);
1138		ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000);
1139		udelay(10);
1140		data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
1141		ast_moutdwm(ast, 0x1E6E0018, data);
1142		data = data | 0x200;
1143		ast_moutdwm(ast, 0x1E6E0018, data);
1144		do {
1145			data = ast_mindwm(ast, 0x1E6E001C);
1146		} while (!(data & 0x08000000));
1147
1148		data = ast_mindwm(ast, 0x1E6E001C);
1149		data = (data >> 8) & 0xff;
1150	}
1151	ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0068) & 0xffff);
1152	data = ast_mindwm(ast, 0x1E6E0018) | 0xC00;
1153	ast_moutdwm(ast, 0x1E6E0018, data);
1154
1155	ast_moutdwm(ast, 0x1E6E0034, 0x00000001);
1156	ast_moutdwm(ast, 0x1E6E000C, 0x00000040);
1157	udelay(50);
1158	/* Mode Register Setting */
1159	ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
1160	ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1161	ast_moutdwm(ast, 0x1E6E0028, 0x00000005);
1162	ast_moutdwm(ast, 0x1E6E0028, 0x00000007);
1163	ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1164	ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1165	ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS);
1166	ast_moutdwm(ast, 0x1E6E000C, 0x00005C08);
1167	ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1168
1169	ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
1170	data = 0;
1171	if (param->wodt) {
1172		data = 0x300;
1173	}
1174	if (param->rodt) {
1175		data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1176	}
1177	ast_moutdwm(ast, 0x1E6E0034, data | 0x3);
1178
1179	/* Calibrate the DQSI delay */
1180	if ((cbr_dll2(ast, param) == false) && (retry++ < 10))
1181		goto ddr3_init_start;
1182
1183	ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1184	/* ECC Memory Initialization */
1185#ifdef ECC
1186	ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1187	ast_moutdwm(ast, 0x1E6E0070, 0x221);
1188	do {
1189		data = ast_mindwm(ast, 0x1E6E0070);
1190	} while (!(data & 0x00001000));
1191	ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1192	ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1193	ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1194#endif
1195
1196
1197}
1198
1199static void get_ddr2_info(struct ast_device *ast, struct ast2300_dram_param *param)
1200{
1201	u32 trap, trap_AC2, trap_MRS;
1202
1203	ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
1204
1205	/* Ger trap info */
1206	trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
1207	trap_AC2  = (trap << 20) | (trap << 16);
1208	trap_AC2 += 0x00110000;
1209	trap_MRS  = 0x00000040 | (trap << 4);
1210
1211
1212	param->reg_MADJ       = 0x00034C4C;
1213	param->reg_SADJ       = 0x00001800;
1214	param->reg_DRV        = 0x000000F0;
1215	param->reg_PERIOD     = param->dram_freq;
1216	param->rodt           = 0;
1217
1218	switch (param->dram_freq) {
1219	case 264:
1220		ast_moutdwm(ast, 0x1E6E2020, 0x0130);
1221		param->wodt          = 0;
1222		param->reg_AC1       = 0x11101513;
1223		param->reg_AC2       = 0x78117011;
1224		param->reg_DQSIC     = 0x00000092;
1225		param->reg_MRS       = 0x00000842;
1226		param->reg_EMRS      = 0x00000000;
1227		param->reg_DRV       = 0x000000F0;
1228		param->reg_IOZ       = 0x00000034;
1229		param->reg_DQIDLY    = 0x0000005A;
1230		param->reg_FREQ      = 0x00004AC0;
1231		param->madj_max      = 138;
1232		param->dll2_finetune_step = 3;
1233		break;
1234	case 336:
1235		ast_moutdwm(ast, 0x1E6E2020, 0x0190);
1236		param->wodt          = 1;
1237		param->reg_AC1       = 0x22202613;
1238		param->reg_AC2       = 0xAA009016 | trap_AC2;
1239		param->reg_DQSIC     = 0x000000BA;
1240		param->reg_MRS       = 0x00000A02 | trap_MRS;
1241		param->reg_EMRS      = 0x00000040;
1242		param->reg_DRV       = 0x000000FA;
1243		param->reg_IOZ       = 0x00000034;
1244		param->reg_DQIDLY    = 0x00000074;
1245		param->reg_FREQ      = 0x00004DC0;
1246		param->madj_max      = 96;
1247		param->dll2_finetune_step = 3;
1248		switch (param->dram_chipid) {
1249		default:
1250		case AST_DRAM_512Mx16:
1251			param->reg_AC2   = 0xAA009012 | trap_AC2;
1252			break;
1253		case AST_DRAM_1Gx16:
1254			param->reg_AC2   = 0xAA009016 | trap_AC2;
1255			break;
1256		case AST_DRAM_2Gx16:
1257			param->reg_AC2   = 0xAA009023 | trap_AC2;
1258			break;
1259		case AST_DRAM_4Gx16:
1260			param->reg_AC2   = 0xAA00903B | trap_AC2;
1261			break;
1262		}
1263		break;
1264	default:
1265	case 396:
1266		ast_moutdwm(ast, 0x1E6E2020, 0x03F1);
1267		param->wodt          = 1;
1268		param->rodt          = 0;
1269		param->reg_AC1       = 0x33302714;
1270		param->reg_AC2       = 0xCC00B01B | trap_AC2;
1271		param->reg_DQSIC     = 0x000000E2;
1272		param->reg_MRS       = 0x00000C02 | trap_MRS;
1273		param->reg_EMRS      = 0x00000040;
1274		param->reg_DRV       = 0x000000FA;
1275		param->reg_IOZ       = 0x00000034;
1276		param->reg_DQIDLY    = 0x00000089;
1277		param->reg_FREQ      = 0x00005040;
1278		param->madj_max      = 96;
1279		param->dll2_finetune_step = 4;
1280
1281		switch (param->dram_chipid) {
1282		case AST_DRAM_512Mx16:
1283			param->reg_AC2   = 0xCC00B016 | trap_AC2;
1284			break;
1285		default:
1286		case AST_DRAM_1Gx16:
1287			param->reg_AC2   = 0xCC00B01B | trap_AC2;
1288			break;
1289		case AST_DRAM_2Gx16:
1290			param->reg_AC2   = 0xCC00B02B | trap_AC2;
1291			break;
1292		case AST_DRAM_4Gx16:
1293			param->reg_AC2   = 0xCC00B03F | trap_AC2;
1294			break;
1295		}
1296
1297		break;
1298
1299	case 408:
1300		ast_moutdwm(ast, 0x1E6E2020, 0x01F0);
1301		param->wodt          = 1;
1302		param->rodt          = 0;
1303		param->reg_AC1       = 0x33302714;
1304		param->reg_AC2       = 0xCC00B01B | trap_AC2;
1305		param->reg_DQSIC     = 0x000000E2;
1306		param->reg_MRS       = 0x00000C02 | trap_MRS;
1307		param->reg_EMRS      = 0x00000040;
1308		param->reg_DRV       = 0x000000FA;
1309		param->reg_IOZ       = 0x00000034;
1310		param->reg_DQIDLY    = 0x00000089;
1311		param->reg_FREQ      = 0x000050C0;
1312		param->madj_max      = 96;
1313		param->dll2_finetune_step = 4;
1314
1315		switch (param->dram_chipid) {
1316		case AST_DRAM_512Mx16:
1317			param->reg_AC2   = 0xCC00B016 | trap_AC2;
1318			break;
1319		default:
1320		case AST_DRAM_1Gx16:
1321			param->reg_AC2   = 0xCC00B01B | trap_AC2;
1322			break;
1323		case AST_DRAM_2Gx16:
1324			param->reg_AC2   = 0xCC00B02B | trap_AC2;
1325			break;
1326		case AST_DRAM_4Gx16:
1327			param->reg_AC2   = 0xCC00B03F | trap_AC2;
1328			break;
1329		}
1330
1331		break;
1332	case 456:
1333		ast_moutdwm(ast, 0x1E6E2020, 0x0230);
1334		param->wodt          = 0;
1335		param->reg_AC1       = 0x33302815;
1336		param->reg_AC2       = 0xCD44B01E;
1337		param->reg_DQSIC     = 0x000000FC;
1338		param->reg_MRS       = 0x00000E72;
1339		param->reg_EMRS      = 0x00000000;
1340		param->reg_DRV       = 0x00000000;
1341		param->reg_IOZ       = 0x00000034;
1342		param->reg_DQIDLY    = 0x00000097;
1343		param->reg_FREQ      = 0x000052C0;
1344		param->madj_max      = 88;
1345		param->dll2_finetune_step = 3;
1346		break;
1347	case 504:
1348		ast_moutdwm(ast, 0x1E6E2020, 0x0261);
1349		param->wodt          = 1;
1350		param->rodt          = 1;
1351		param->reg_AC1       = 0x33302815;
1352		param->reg_AC2       = 0xDE44C022;
1353		param->reg_DQSIC     = 0x00000117;
1354		param->reg_MRS       = 0x00000E72;
1355		param->reg_EMRS      = 0x00000040;
1356		param->reg_DRV       = 0x0000000A;
1357		param->reg_IOZ       = 0x00000045;
1358		param->reg_DQIDLY    = 0x000000A0;
1359		param->reg_FREQ      = 0x000054C0;
1360		param->madj_max      = 79;
1361		param->dll2_finetune_step = 3;
1362		break;
1363	case 528:
1364		ast_moutdwm(ast, 0x1E6E2020, 0x0120);
1365		param->wodt          = 1;
1366		param->rodt          = 1;
1367		param->reg_AC1       = 0x33302815;
1368		param->reg_AC2       = 0xEF44D024;
1369		param->reg_DQSIC     = 0x00000125;
1370		param->reg_MRS       = 0x00000E72;
1371		param->reg_EMRS      = 0x00000004;
1372		param->reg_DRV       = 0x000000F9;
1373		param->reg_IOZ       = 0x00000045;
1374		param->reg_DQIDLY    = 0x000000A7;
1375		param->reg_FREQ      = 0x000055C0;
1376		param->madj_max      = 76;
1377		param->dll2_finetune_step = 3;
1378		break;
1379	case 552:
1380		ast_moutdwm(ast, 0x1E6E2020, 0x02A1);
1381		param->wodt          = 1;
1382		param->rodt          = 1;
1383		param->reg_AC1       = 0x43402915;
1384		param->reg_AC2       = 0xFF44E025;
1385		param->reg_DQSIC     = 0x00000132;
1386		param->reg_MRS       = 0x00000E72;
1387		param->reg_EMRS      = 0x00000040;
1388		param->reg_DRV       = 0x0000000A;
1389		param->reg_IOZ       = 0x00000045;
1390		param->reg_DQIDLY    = 0x000000AD;
1391		param->reg_FREQ      = 0x000056C0;
1392		param->madj_max      = 76;
1393		param->dll2_finetune_step = 3;
1394		break;
1395	case 576:
1396		ast_moutdwm(ast, 0x1E6E2020, 0x0140);
1397		param->wodt          = 1;
1398		param->rodt          = 1;
1399		param->reg_AC1       = 0x43402915;
1400		param->reg_AC2       = 0xFF44E027;
1401		param->reg_DQSIC     = 0x0000013F;
1402		param->reg_MRS       = 0x00000E72;
1403		param->reg_EMRS      = 0x00000004;
1404		param->reg_DRV       = 0x000000F5;
1405		param->reg_IOZ       = 0x00000045;
1406		param->reg_DQIDLY    = 0x000000B3;
1407		param->reg_FREQ      = 0x000057C0;
1408		param->madj_max      = 76;
1409		param->dll2_finetune_step = 3;
1410		break;
1411	}
1412
1413	switch (param->dram_chipid) {
1414	case AST_DRAM_512Mx16:
1415		param->dram_config = 0x100;
1416		break;
1417	default:
1418	case AST_DRAM_1Gx16:
1419		param->dram_config = 0x121;
1420		break;
1421	case AST_DRAM_2Gx16:
1422		param->dram_config = 0x122;
1423		break;
1424	case AST_DRAM_4Gx16:
1425		param->dram_config = 0x123;
1426		break;
1427	} /* switch size */
1428
1429	switch (param->vram_size) {
1430	default:
1431	case AST_VIDMEM_SIZE_8M:
1432		param->dram_config |= 0x00;
1433		break;
1434	case AST_VIDMEM_SIZE_16M:
1435		param->dram_config |= 0x04;
1436		break;
1437	case AST_VIDMEM_SIZE_32M:
1438		param->dram_config |= 0x08;
1439		break;
1440	case AST_VIDMEM_SIZE_64M:
1441		param->dram_config |= 0x0c;
1442		break;
1443	}
1444}
1445
1446static void ddr2_init(struct ast_device *ast, struct ast2300_dram_param *param)
1447{
1448	u32 data, data2, retry = 0;
1449
1450ddr2_init_start:
1451	ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
1452	ast_moutdwm(ast, 0x1E6E0018, 0x00000100);
1453	ast_moutdwm(ast, 0x1E6E0024, 0x00000000);
1454	ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
1455	ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
1456	udelay(10);
1457	ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
1458	udelay(10);
1459
1460	ast_moutdwm(ast, 0x1E6E0004, param->dram_config);
1461	ast_moutdwm(ast, 0x1E6E0008, 0x90040f);
1462	ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1);
1463	ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2);
1464	ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
1465	ast_moutdwm(ast, 0x1E6E0080, 0x00000000);
1466	ast_moutdwm(ast, 0x1E6E0084, 0x00000000);
1467	ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
1468	ast_moutdwm(ast, 0x1E6E0018, 0x4000A130);
1469	ast_moutdwm(ast, 0x1E6E0018, 0x00002330);
1470	ast_moutdwm(ast, 0x1E6E0038, 0x00000000);
1471	ast_moutdwm(ast, 0x1E6E0040, 0xFF808000);
1472	ast_moutdwm(ast, 0x1E6E0044, 0x88848466);
1473	ast_moutdwm(ast, 0x1E6E0048, 0x44440008);
1474	ast_moutdwm(ast, 0x1E6E004C, 0x00000000);
1475	ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1476	ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1477	ast_moutdwm(ast, 0x1E6E0054, 0);
1478	ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV);
1479	ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
1480	ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1481	ast_moutdwm(ast, 0x1E6E0074, 0x00000000);
1482	ast_moutdwm(ast, 0x1E6E0078, 0x00000000);
1483	ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1484
1485	/* Wait MCLK2X lock to MCLK */
1486	do {
1487		data = ast_mindwm(ast, 0x1E6E001C);
1488	} while (!(data & 0x08000000));
1489	data = ast_mindwm(ast, 0x1E6E001C);
1490	data = (data >> 8) & 0xff;
1491	while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
1492		data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
1493		if ((data2 & 0xff) > param->madj_max) {
1494			break;
1495		}
1496		ast_moutdwm(ast, 0x1E6E0064, data2);
1497		if (data2 & 0x00100000) {
1498			data2 = ((data2 & 0xff) >> 3) + 3;
1499		} else {
1500			data2 = ((data2 & 0xff) >> 2) + 5;
1501		}
1502		data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff;
1503		data2 += data & 0xff;
1504		data = data | (data2 << 8);
1505		ast_moutdwm(ast, 0x1E6E0068, data);
1506		udelay(10);
1507		ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000);
1508		udelay(10);
1509		data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
1510		ast_moutdwm(ast, 0x1E6E0018, data);
1511		data = data | 0x200;
1512		ast_moutdwm(ast, 0x1E6E0018, data);
1513		do {
1514			data = ast_mindwm(ast, 0x1E6E001C);
1515		} while (!(data & 0x08000000));
1516
1517		data = ast_mindwm(ast, 0x1E6E001C);
1518		data = (data >> 8) & 0xff;
1519	}
1520	ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0008) & 0xffff);
1521	data = ast_mindwm(ast, 0x1E6E0018) | 0xC00;
1522	ast_moutdwm(ast, 0x1E6E0018, data);
1523
1524	ast_moutdwm(ast, 0x1E6E0034, 0x00000001);
1525	ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
1526	udelay(50);
1527	/* Mode Register Setting */
1528	ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
1529	ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1530	ast_moutdwm(ast, 0x1E6E0028, 0x00000005);
1531	ast_moutdwm(ast, 0x1E6E0028, 0x00000007);
1532	ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1533	ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1534
1535	ast_moutdwm(ast, 0x1E6E000C, 0x00005C08);
1536	ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS);
1537	ast_moutdwm(ast, 0x1E6E0028, 0x00000001);
1538	ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS | 0x380);
1539	ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1540	ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1541	ast_moutdwm(ast, 0x1E6E0028, 0x00000003);
1542
1543	ast_moutdwm(ast, 0x1E6E000C, 0x7FFF5C01);
1544	data = 0;
1545	if (param->wodt) {
1546		data = 0x500;
1547	}
1548	if (param->rodt) {
1549		data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1550	}
1551	ast_moutdwm(ast, 0x1E6E0034, data | 0x3);
1552	ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1553
1554	/* Calibrate the DQSI delay */
1555	if ((cbr_dll2(ast, param) == false) && (retry++ < 10))
1556		goto ddr2_init_start;
1557
1558	/* ECC Memory Initialization */
1559#ifdef ECC
1560	ast_moutdwm(ast, 0x1E6E007C, 0x00000000);
1561	ast_moutdwm(ast, 0x1E6E0070, 0x221);
1562	do {
1563		data = ast_mindwm(ast, 0x1E6E0070);
1564	} while (!(data & 0x00001000));
1565	ast_moutdwm(ast, 0x1E6E0070, 0x00000000);
1566	ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1567	ast_moutdwm(ast, 0x1E6E0050, 0x00000000);
1568#endif
1569
1570}
1571
1572static void ast_post_chip_2300(struct drm_device *dev)
1573{
1574	struct ast_device *ast = to_ast_device(dev);
1575	struct ast2300_dram_param param;
1576	u32 temp;
1577	u8 reg;
1578
1579	reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
1580	if ((reg & 0x80) == 0) {/* vga only */
1581		ast_write32(ast, 0xf004, 0x1e6e0000);
1582		ast_write32(ast, 0xf000, 0x1);
1583		ast_write32(ast, 0x12000, 0x1688a8a8);
1584		do {
1585			;
1586		} while (ast_read32(ast, 0x12000) != 0x1);
1587
1588		ast_write32(ast, 0x10000, 0xfc600309);
1589		do {
1590			;
1591		} while (ast_read32(ast, 0x10000) != 0x1);
1592
1593		/* Slow down CPU/AHB CLK in VGA only mode */
1594		temp = ast_read32(ast, 0x12008);
1595		temp |= 0x73;
1596		ast_write32(ast, 0x12008, temp);
1597
1598		param.dram_freq = 396;
1599		param.dram_type = AST_DDR3;
1600		temp = ast_mindwm(ast, 0x1e6e2070);
1601		if (temp & 0x01000000)
1602			param.dram_type = AST_DDR2;
1603                switch (temp & 0x18000000) {
1604		case 0:
1605			param.dram_chipid = AST_DRAM_512Mx16;
1606			break;
1607		default:
1608		case 0x08000000:
1609			param.dram_chipid = AST_DRAM_1Gx16;
1610			break;
1611		case 0x10000000:
1612			param.dram_chipid = AST_DRAM_2Gx16;
1613			break;
1614		case 0x18000000:
1615			param.dram_chipid = AST_DRAM_4Gx16;
1616			break;
1617		}
1618                switch (temp & 0x0c) {
1619                default:
1620		case 0x00:
1621			param.vram_size = AST_VIDMEM_SIZE_8M;
1622			break;
1623
1624		case 0x04:
1625			param.vram_size = AST_VIDMEM_SIZE_16M;
1626			break;
1627
1628		case 0x08:
1629			param.vram_size = AST_VIDMEM_SIZE_32M;
1630			break;
1631
1632		case 0x0c:
1633			param.vram_size = AST_VIDMEM_SIZE_64M;
1634			break;
1635		}
1636
1637		if (param.dram_type == AST_DDR3) {
1638			get_ddr3_info(ast, &param);
1639			ddr3_init(ast, &param);
1640		} else {
1641			get_ddr2_info(ast, &param);
1642			ddr2_init(ast, &param);
1643		}
1644
1645		temp = ast_mindwm(ast, 0x1e6e2040);
1646		ast_moutdwm(ast, 0x1e6e2040, temp | 0x40);
1647	}
1648
1649	/* wait ready */
1650	do {
1651		reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
1652	} while ((reg & 0x40) == 0);
1653}
1654
1655static bool cbr_test_2500(struct ast_device *ast)
1656{
1657	ast_moutdwm(ast, 0x1E6E0074, 0x0000FFFF);
1658	ast_moutdwm(ast, 0x1E6E007C, 0xFF00FF00);
1659	if (!mmc_test_burst(ast, 0))
1660		return false;
1661	if (!mmc_test_single_2500(ast, 0))
1662		return false;
1663	return true;
1664}
1665
1666static bool ddr_test_2500(struct ast_device *ast)
1667{
1668	ast_moutdwm(ast, 0x1E6E0074, 0x0000FFFF);
1669	ast_moutdwm(ast, 0x1E6E007C, 0xFF00FF00);
1670	if (!mmc_test_burst(ast, 0))
1671		return false;
1672	if (!mmc_test_burst(ast, 1))
1673		return false;
1674	if (!mmc_test_burst(ast, 2))
1675		return false;
1676	if (!mmc_test_burst(ast, 3))
1677		return false;
1678	if (!mmc_test_single_2500(ast, 0))
1679		return false;
1680	return true;
1681}
1682
1683static void ddr_init_common_2500(struct ast_device *ast)
1684{
1685	ast_moutdwm(ast, 0x1E6E0034, 0x00020080);
1686	ast_moutdwm(ast, 0x1E6E0008, 0x2003000F);
1687	ast_moutdwm(ast, 0x1E6E0038, 0x00000FFF);
1688	ast_moutdwm(ast, 0x1E6E0040, 0x88448844);
1689	ast_moutdwm(ast, 0x1E6E0044, 0x24422288);
1690	ast_moutdwm(ast, 0x1E6E0048, 0x22222222);
1691	ast_moutdwm(ast, 0x1E6E004C, 0x22222222);
1692	ast_moutdwm(ast, 0x1E6E0050, 0x80000000);
1693	ast_moutdwm(ast, 0x1E6E0208, 0x00000000);
1694	ast_moutdwm(ast, 0x1E6E0218, 0x00000000);
1695	ast_moutdwm(ast, 0x1E6E0220, 0x00000000);
1696	ast_moutdwm(ast, 0x1E6E0228, 0x00000000);
1697	ast_moutdwm(ast, 0x1E6E0230, 0x00000000);
1698	ast_moutdwm(ast, 0x1E6E02A8, 0x00000000);
1699	ast_moutdwm(ast, 0x1E6E02B0, 0x00000000);
1700	ast_moutdwm(ast, 0x1E6E0240, 0x86000000);
1701	ast_moutdwm(ast, 0x1E6E0244, 0x00008600);
1702	ast_moutdwm(ast, 0x1E6E0248, 0x80000000);
1703	ast_moutdwm(ast, 0x1E6E024C, 0x80808080);
1704}
1705
1706static void ddr_phy_init_2500(struct ast_device *ast)
1707{
1708	u32 data, pass, timecnt;
1709
1710	pass = 0;
1711	ast_moutdwm(ast, 0x1E6E0060, 0x00000005);
1712	while (!pass) {
1713		for (timecnt = 0; timecnt < TIMEOUT; timecnt++) {
1714			data = ast_mindwm(ast, 0x1E6E0060) & 0x1;
1715			if (!data)
1716				break;
1717		}
1718		if (timecnt != TIMEOUT) {
1719			data = ast_mindwm(ast, 0x1E6E0300) & 0x000A0000;
1720			if (!data)
1721				pass = 1;
1722		}
1723		if (!pass) {
1724			ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
1725			udelay(10); /* delay 10 us */
1726			ast_moutdwm(ast, 0x1E6E0060, 0x00000005);
1727		}
1728	}
1729
1730	ast_moutdwm(ast, 0x1E6E0060, 0x00000006);
1731}
1732
1733/*
1734 * Check DRAM Size
1735 * 1Gb : 0x80000000 ~ 0x87FFFFFF
1736 * 2Gb : 0x80000000 ~ 0x8FFFFFFF
1737 * 4Gb : 0x80000000 ~ 0x9FFFFFFF
1738 * 8Gb : 0x80000000 ~ 0xBFFFFFFF
1739 */
1740static void check_dram_size_2500(struct ast_device *ast, u32 tRFC)
1741{
1742	u32 reg_04, reg_14;
1743
1744	reg_04 = ast_mindwm(ast, 0x1E6E0004) & 0xfffffffc;
1745	reg_14 = ast_mindwm(ast, 0x1E6E0014) & 0xffffff00;
1746
1747	ast_moutdwm(ast, 0xA0100000, 0x41424344);
1748	ast_moutdwm(ast, 0x90100000, 0x35363738);
1749	ast_moutdwm(ast, 0x88100000, 0x292A2B2C);
1750	ast_moutdwm(ast, 0x80100000, 0x1D1E1F10);
1751
1752	/* Check 8Gbit */
1753	if (ast_mindwm(ast, 0xA0100000) == 0x41424344) {
1754		reg_04 |= 0x03;
1755		reg_14 |= (tRFC >> 24) & 0xFF;
1756		/* Check 4Gbit */
1757	} else if (ast_mindwm(ast, 0x90100000) == 0x35363738) {
1758		reg_04 |= 0x02;
1759		reg_14 |= (tRFC >> 16) & 0xFF;
1760		/* Check 2Gbit */
1761	} else if (ast_mindwm(ast, 0x88100000) == 0x292A2B2C) {
1762		reg_04 |= 0x01;
1763		reg_14 |= (tRFC >> 8) & 0xFF;
1764	} else {
1765		reg_14 |= tRFC & 0xFF;
1766	}
1767	ast_moutdwm(ast, 0x1E6E0004, reg_04);
1768	ast_moutdwm(ast, 0x1E6E0014, reg_14);
1769}
1770
1771static void enable_cache_2500(struct ast_device *ast)
1772{
1773	u32 reg_04, data;
1774
1775	reg_04 = ast_mindwm(ast, 0x1E6E0004);
1776	ast_moutdwm(ast, 0x1E6E0004, reg_04 | 0x1000);
1777
1778	do
1779		data = ast_mindwm(ast, 0x1E6E0004);
1780	while (!(data & 0x80000));
1781	ast_moutdwm(ast, 0x1E6E0004, reg_04 | 0x400);
1782}
1783
1784static void set_mpll_2500(struct ast_device *ast)
1785{
1786	u32 addr, data, param;
1787
1788	/* Reset MMC */
1789	ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
1790	ast_moutdwm(ast, 0x1E6E0034, 0x00020080);
1791	for (addr = 0x1e6e0004; addr < 0x1e6e0090;) {
1792		ast_moutdwm(ast, addr, 0x0);
1793		addr += 4;
1794	}
1795	ast_moutdwm(ast, 0x1E6E0034, 0x00020000);
1796
1797	ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
1798	data = ast_mindwm(ast, 0x1E6E2070) & 0x00800000;
1799	if (data) {
1800		/* CLKIN = 25MHz */
1801		param = 0x930023E0;
1802		ast_moutdwm(ast, 0x1E6E2160, 0x00011320);
1803	} else {
1804		/* CLKIN = 24MHz */
1805		param = 0x93002400;
1806	}
1807	ast_moutdwm(ast, 0x1E6E2020, param);
1808	udelay(100);
1809}
1810
1811static void reset_mmc_2500(struct ast_device *ast)
1812{
1813	ast_moutdwm(ast, 0x1E78505C, 0x00000004);
1814	ast_moutdwm(ast, 0x1E785044, 0x00000001);
1815	ast_moutdwm(ast, 0x1E785048, 0x00004755);
1816	ast_moutdwm(ast, 0x1E78504C, 0x00000013);
1817	mdelay(100);
1818	ast_moutdwm(ast, 0x1E785054, 0x00000077);
1819	ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
1820}
1821
1822static void ddr3_init_2500(struct ast_device *ast, const u32 *ddr_table)
1823{
1824
1825	ast_moutdwm(ast, 0x1E6E0004, 0x00000303);
1826	ast_moutdwm(ast, 0x1E6E0010, ddr_table[REGIDX_010]);
1827	ast_moutdwm(ast, 0x1E6E0014, ddr_table[REGIDX_014]);
1828	ast_moutdwm(ast, 0x1E6E0018, ddr_table[REGIDX_018]);
1829	ast_moutdwm(ast, 0x1E6E0020, ddr_table[REGIDX_020]);	     /* MODEREG4/6 */
1830	ast_moutdwm(ast, 0x1E6E0024, ddr_table[REGIDX_024]);	     /* MODEREG5 */
1831	ast_moutdwm(ast, 0x1E6E002C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */
1832	ast_moutdwm(ast, 0x1E6E0030, ddr_table[REGIDX_030]);	     /* MODEREG1/3 */
1833
1834	/* DDR PHY Setting */
1835	ast_moutdwm(ast, 0x1E6E0200, 0x02492AAE);
1836	ast_moutdwm(ast, 0x1E6E0204, 0x00001001);
1837	ast_moutdwm(ast, 0x1E6E020C, 0x55E00B0B);
1838	ast_moutdwm(ast, 0x1E6E0210, 0x20000000);
1839	ast_moutdwm(ast, 0x1E6E0214, ddr_table[REGIDX_214]);
1840	ast_moutdwm(ast, 0x1E6E02E0, ddr_table[REGIDX_2E0]);
1841	ast_moutdwm(ast, 0x1E6E02E4, ddr_table[REGIDX_2E4]);
1842	ast_moutdwm(ast, 0x1E6E02E8, ddr_table[REGIDX_2E8]);
1843	ast_moutdwm(ast, 0x1E6E02EC, ddr_table[REGIDX_2EC]);
1844	ast_moutdwm(ast, 0x1E6E02F0, ddr_table[REGIDX_2F0]);
1845	ast_moutdwm(ast, 0x1E6E02F4, ddr_table[REGIDX_2F4]);
1846	ast_moutdwm(ast, 0x1E6E02F8, ddr_table[REGIDX_2F8]);
1847	ast_moutdwm(ast, 0x1E6E0290, 0x00100008);
1848	ast_moutdwm(ast, 0x1E6E02C0, 0x00000006);
1849
1850	/* Controller Setting */
1851	ast_moutdwm(ast, 0x1E6E0034, 0x00020091);
1852
1853	/* Wait DDR PHY init done */
1854	ddr_phy_init_2500(ast);
1855
1856	ast_moutdwm(ast, 0x1E6E0120, ddr_table[REGIDX_PLL]);
1857	ast_moutdwm(ast, 0x1E6E000C, 0x42AA5C81);
1858	ast_moutdwm(ast, 0x1E6E0034, 0x0001AF93);
1859
1860	check_dram_size_2500(ast, ddr_table[REGIDX_RFC]);
1861	enable_cache_2500(ast);
1862	ast_moutdwm(ast, 0x1E6E001C, 0x00000008);
1863	ast_moutdwm(ast, 0x1E6E0038, 0xFFFFFF00);
1864}
1865
1866static void ddr4_init_2500(struct ast_device *ast, const u32 *ddr_table)
1867{
1868	u32 data, data2, pass, retrycnt;
1869	u32 ddr_vref, phy_vref;
1870	u32 min_ddr_vref = 0, min_phy_vref = 0;
1871	u32 max_ddr_vref = 0, max_phy_vref = 0;
1872
1873	ast_moutdwm(ast, 0x1E6E0004, 0x00000313);
1874	ast_moutdwm(ast, 0x1E6E0010, ddr_table[REGIDX_010]);
1875	ast_moutdwm(ast, 0x1E6E0014, ddr_table[REGIDX_014]);
1876	ast_moutdwm(ast, 0x1E6E0018, ddr_table[REGIDX_018]);
1877	ast_moutdwm(ast, 0x1E6E0020, ddr_table[REGIDX_020]);	     /* MODEREG4/6 */
1878	ast_moutdwm(ast, 0x1E6E0024, ddr_table[REGIDX_024]);	     /* MODEREG5 */
1879	ast_moutdwm(ast, 0x1E6E002C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */
1880	ast_moutdwm(ast, 0x1E6E0030, ddr_table[REGIDX_030]);	     /* MODEREG1/3 */
1881
1882	/* DDR PHY Setting */
1883	ast_moutdwm(ast, 0x1E6E0200, 0x42492AAE);
1884	ast_moutdwm(ast, 0x1E6E0204, 0x09002000);
1885	ast_moutdwm(ast, 0x1E6E020C, 0x55E00B0B);
1886	ast_moutdwm(ast, 0x1E6E0210, 0x20000000);
1887	ast_moutdwm(ast, 0x1E6E0214, ddr_table[REGIDX_214]);
1888	ast_moutdwm(ast, 0x1E6E02E0, ddr_table[REGIDX_2E0]);
1889	ast_moutdwm(ast, 0x1E6E02E4, ddr_table[REGIDX_2E4]);
1890	ast_moutdwm(ast, 0x1E6E02E8, ddr_table[REGIDX_2E8]);
1891	ast_moutdwm(ast, 0x1E6E02EC, ddr_table[REGIDX_2EC]);
1892	ast_moutdwm(ast, 0x1E6E02F0, ddr_table[REGIDX_2F0]);
1893	ast_moutdwm(ast, 0x1E6E02F4, ddr_table[REGIDX_2F4]);
1894	ast_moutdwm(ast, 0x1E6E02F8, ddr_table[REGIDX_2F8]);
1895	ast_moutdwm(ast, 0x1E6E0290, 0x00100008);
1896	ast_moutdwm(ast, 0x1E6E02C4, 0x3C183C3C);
1897	ast_moutdwm(ast, 0x1E6E02C8, 0x00631E0E);
1898
1899	/* Controller Setting */
1900	ast_moutdwm(ast, 0x1E6E0034, 0x0001A991);
1901
1902	/* Train PHY Vref first */
1903	pass = 0;
1904
1905	for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) {
1906		max_phy_vref = 0x0;
1907		pass = 0;
1908		ast_moutdwm(ast, 0x1E6E02C0, 0x00001C06);
1909		for (phy_vref = 0x40; phy_vref < 0x80; phy_vref++) {
1910			ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
1911			ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
1912			ast_moutdwm(ast, 0x1E6E02CC, phy_vref | (phy_vref << 8));
1913			/* Fire DFI Init */
1914			ddr_phy_init_2500(ast);
1915			ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
1916			if (cbr_test_2500(ast)) {
1917				pass++;
1918				data = ast_mindwm(ast, 0x1E6E03D0);
1919				data2 = data >> 8;
1920				data  = data & 0xff;
1921				if (data > data2)
1922					data = data2;
1923				if (max_phy_vref < data) {
1924					max_phy_vref = data;
1925					min_phy_vref = phy_vref;
1926				}
1927			} else if (pass > 0)
1928				break;
1929		}
1930	}
1931	ast_moutdwm(ast, 0x1E6E02CC, min_phy_vref | (min_phy_vref << 8));
1932
1933	/* Train DDR Vref next */
1934	pass = 0;
1935
1936	for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) {
1937		min_ddr_vref = 0xFF;
1938		max_ddr_vref = 0x0;
1939		pass = 0;
1940		for (ddr_vref = 0x00; ddr_vref < 0x40; ddr_vref++) {
1941			ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
1942			ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
1943			ast_moutdwm(ast, 0x1E6E02C0, 0x00000006 | (ddr_vref << 8));
1944			/* Fire DFI Init */
1945			ddr_phy_init_2500(ast);
1946			ast_moutdwm(ast, 0x1E6E000C, 0x00005C01);
1947			if (cbr_test_2500(ast)) {
1948				pass++;
1949				if (min_ddr_vref > ddr_vref)
1950					min_ddr_vref = ddr_vref;
1951				if (max_ddr_vref < ddr_vref)
1952					max_ddr_vref = ddr_vref;
1953			} else if (pass != 0)
1954				break;
1955		}
1956	}
1957
1958	ast_moutdwm(ast, 0x1E6E000C, 0x00000000);
1959	ast_moutdwm(ast, 0x1E6E0060, 0x00000000);
1960	ddr_vref = (min_ddr_vref + max_ddr_vref + 1) >> 1;
1961	ast_moutdwm(ast, 0x1E6E02C0, 0x00000006 | (ddr_vref << 8));
1962
1963	/* Wait DDR PHY init done */
1964	ddr_phy_init_2500(ast);
1965
1966	ast_moutdwm(ast, 0x1E6E0120, ddr_table[REGIDX_PLL]);
1967	ast_moutdwm(ast, 0x1E6E000C, 0x42AA5C81);
1968	ast_moutdwm(ast, 0x1E6E0034, 0x0001AF93);
1969
1970	check_dram_size_2500(ast, ddr_table[REGIDX_RFC]);
1971	enable_cache_2500(ast);
1972	ast_moutdwm(ast, 0x1E6E001C, 0x00000008);
1973	ast_moutdwm(ast, 0x1E6E0038, 0xFFFFFF00);
1974}
1975
1976static bool ast_dram_init_2500(struct ast_device *ast)
1977{
1978	u32 data;
1979	u32 max_tries = 5;
1980
1981	do {
1982		if (max_tries-- == 0)
1983			return false;
1984		set_mpll_2500(ast);
1985		reset_mmc_2500(ast);
1986		ddr_init_common_2500(ast);
1987
1988		data = ast_mindwm(ast, 0x1E6E2070);
1989		if (data & 0x01000000)
1990			ddr4_init_2500(ast, ast2500_ddr4_1600_timing_table);
1991		else
1992			ddr3_init_2500(ast, ast2500_ddr3_1600_timing_table);
1993	} while (!ddr_test_2500(ast));
1994
1995	ast_moutdwm(ast, 0x1E6E2040, ast_mindwm(ast, 0x1E6E2040) | 0x41);
1996
1997	/* Patch code */
1998	data = ast_mindwm(ast, 0x1E6E200C) & 0xF9FFFFFF;
1999	ast_moutdwm(ast, 0x1E6E200C, data | 0x10000000);
2000
2001	return true;
2002}
2003
2004void ast_patch_ahb_2500(void __iomem *regs)
2005{
2006	u32 data;
2007
2008	/* Clear bus lock condition */
2009	__ast_moutdwm(regs, 0x1e600000, 0xAEED1A03);
2010	__ast_moutdwm(regs, 0x1e600084, 0x00010000);
2011	__ast_moutdwm(regs, 0x1e600088, 0x00000000);
2012	__ast_moutdwm(regs, 0x1e6e2000, 0x1688A8A8);
2013
2014	data = __ast_mindwm(regs, 0x1e6e2070);
2015	if (data & 0x08000000) { /* check fast reset */
2016		/*
2017		 * If "Fast restet" is enabled for ARM-ICE debugger,
2018		 * then WDT needs to enable, that
2019		 * WDT04 is WDT#1 Reload reg.
2020		 * WDT08 is WDT#1 counter restart reg to avoid system deadlock
2021		 * WDT0C is WDT#1 control reg
2022		 *	[6:5]:= 01:Full chip
2023		 *	[4]:= 1:1MHz clock source
2024		 *	[1]:= 1:WDT will be cleeared and disabled after timeout occurs
2025		 *	[0]:= 1:WDT enable
2026		 */
2027		__ast_moutdwm(regs, 0x1E785004, 0x00000010);
2028		__ast_moutdwm(regs, 0x1E785008, 0x00004755);
2029		__ast_moutdwm(regs, 0x1E78500c, 0x00000033);
2030		udelay(1000);
2031	}
2032
2033	do {
2034		__ast_moutdwm(regs, 0x1e6e2000, 0x1688A8A8);
2035		data = __ast_mindwm(regs, 0x1e6e2000);
2036	} while (data != 1);
2037
2038	__ast_moutdwm(regs, 0x1e6e207c, 0x08000000); /* clear fast reset */
2039}
2040
2041void ast_post_chip_2500(struct drm_device *dev)
2042{
2043	struct ast_device *ast = to_ast_device(dev);
2044	u32 temp;
2045	u8 reg;
2046
2047	reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
2048	if ((reg & AST_VRAM_INIT_STATUS_MASK) == 0) {/* vga only */
2049		/* Clear bus lock condition */
2050		ast_patch_ahb_2500(ast->regs);
2051
2052		/* Disable watchdog */
2053		ast_moutdwm(ast, 0x1E78502C, 0x00000000);
2054		ast_moutdwm(ast, 0x1E78504C, 0x00000000);
2055
2056		/*
2057		 * Reset USB port to patch USB unknown device issue
2058		 * SCU90 is Multi-function Pin Control #5
2059		 *	[29]:= 1:Enable USB2.0 Host port#1 (that the mutually shared USB2.0 Hub
2060		 *				port).
2061		 * SCU94 is Multi-function Pin Control #6
2062		 *	[14:13]:= 1x:USB2.0 Host2 controller
2063		 * SCU70 is Hardware Strap reg
2064		 *	[23]:= 1:CLKIN is 25MHz and USBCK1 = 24/48 MHz (determined by
2065		 *				[18]: 0(24)/1(48) MHz)
2066		 * SCU7C is Write clear reg to SCU70
2067		 *	[23]:= write 1 and then SCU70[23] will be clear as 0b.
2068		 */
2069		ast_moutdwm(ast, 0x1E6E2090, 0x20000000);
2070		ast_moutdwm(ast, 0x1E6E2094, 0x00004000);
2071		if (ast_mindwm(ast, 0x1E6E2070) & 0x00800000) {
2072			ast_moutdwm(ast, 0x1E6E207C, 0x00800000);
2073			mdelay(100);
2074			ast_moutdwm(ast, 0x1E6E2070, 0x00800000);
2075		}
2076		/* Modify eSPI reset pin */
2077		temp = ast_mindwm(ast, 0x1E6E2070);
2078		if (temp & 0x02000000)
2079			ast_moutdwm(ast, 0x1E6E207C, 0x00004000);
2080
2081		/* Slow down CPU/AHB CLK in VGA only mode */
2082		temp = ast_read32(ast, 0x12008);
2083		temp |= 0x73;
2084		ast_write32(ast, 0x12008, temp);
2085
2086		if (!ast_dram_init_2500(ast))
2087			drm_err(dev, "DRAM init failed !\n");
2088
2089		temp = ast_mindwm(ast, 0x1e6e2040);
2090		ast_moutdwm(ast, 0x1e6e2040, temp | 0x40);
2091	}
2092
2093	/* wait ready */
2094	do {
2095		reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
2096	} while ((reg & 0x40) == 0);
2097}
2098