xref: /openbmc/linux/drivers/gpu/drm/ast/ast_post.c (revision 1453bf4c)
1312fec14SDave Airlie /*
2312fec14SDave Airlie  * Copyright 2012 Red Hat Inc.
3312fec14SDave Airlie  *
4312fec14SDave Airlie  * Permission is hereby granted, free of charge, to any person obtaining a
5312fec14SDave Airlie  * copy of this software and associated documentation files (the
6312fec14SDave Airlie  * "Software"), to deal in the Software without restriction, including
7312fec14SDave Airlie  * without limitation the rights to use, copy, modify, merge, publish,
8312fec14SDave Airlie  * distribute, sub license, and/or sell copies of the Software, and to
9312fec14SDave Airlie  * permit persons to whom the Software is furnished to do so, subject to
10312fec14SDave Airlie  * the following conditions:
11312fec14SDave Airlie  *
12312fec14SDave Airlie  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13312fec14SDave Airlie  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14312fec14SDave Airlie  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
15312fec14SDave Airlie  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
16312fec14SDave Airlie  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17312fec14SDave Airlie  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18312fec14SDave Airlie  * USE OR OTHER DEALINGS IN THE SOFTWARE.
19312fec14SDave Airlie  *
20312fec14SDave Airlie  * The above copyright notice and this permission notice (including the
21312fec14SDave Airlie  * next paragraph) shall be included in all copies or substantial portions
22312fec14SDave Airlie  * of the Software.
23312fec14SDave Airlie  *
24312fec14SDave Airlie  */
25312fec14SDave Airlie /*
26312fec14SDave Airlie  * Authors: Dave Airlie <airlied@redhat.com>
27312fec14SDave Airlie  */
28312fec14SDave Airlie 
29760285e7SDavid Howells #include <drm/drmP.h>
30312fec14SDave Airlie #include "ast_drv.h"
31312fec14SDave Airlie 
32312fec14SDave Airlie #include "ast_dram_tables.h"
33312fec14SDave Airlie 
34312fec14SDave Airlie static void ast_init_dram_2300(struct drm_device *dev);
35312fec14SDave Airlie 
36312fec14SDave Airlie static void
37312fec14SDave Airlie ast_enable_vga(struct drm_device *dev)
38312fec14SDave Airlie {
39312fec14SDave Airlie 	struct ast_private *ast = dev->dev_private;
40312fec14SDave Airlie 
41312fec14SDave Airlie 	ast_io_write8(ast, 0x43, 0x01);
42312fec14SDave Airlie 	ast_io_write8(ast, 0x42, 0x01);
43312fec14SDave Airlie }
44312fec14SDave Airlie 
45312fec14SDave Airlie #if 0 /* will use later */
46312fec14SDave Airlie static bool
47312fec14SDave Airlie ast_is_vga_enabled(struct drm_device *dev)
48312fec14SDave Airlie {
49312fec14SDave Airlie 	struct ast_private *ast = dev->dev_private;
50312fec14SDave Airlie 	u8 ch;
51312fec14SDave Airlie 
52312fec14SDave Airlie 	if (ast->chip == AST1180) {
53312fec14SDave Airlie 		/* TODO 1180 */
54312fec14SDave Airlie 	} else {
55312fec14SDave Airlie 		ch = ast_io_read8(ast, 0x43);
56312fec14SDave Airlie 		if (ch) {
57312fec14SDave Airlie 			ast_open_key(ast);
58312fec14SDave Airlie 			ch = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff);
59312fec14SDave Airlie 			return ch & 0x04;
60312fec14SDave Airlie 		}
61312fec14SDave Airlie 	}
62312fec14SDave Airlie 	return 0;
63312fec14SDave Airlie }
64312fec14SDave Airlie #endif
65312fec14SDave Airlie 
66312fec14SDave Airlie static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff };
67312fec14SDave Airlie static const u8 extreginfo_ast2300a0[] = { 0x0f, 0x04, 0x1c, 0xff };
68312fec14SDave Airlie static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff };
69312fec14SDave Airlie 
70312fec14SDave Airlie static void
71312fec14SDave Airlie ast_set_def_ext_reg(struct drm_device *dev)
72312fec14SDave Airlie {
73312fec14SDave Airlie 	struct ast_private *ast = dev->dev_private;
74312fec14SDave Airlie 	u8 i, index, reg;
75312fec14SDave Airlie 	const u8 *ext_reg_info;
76312fec14SDave Airlie 
77312fec14SDave Airlie 	/* reset scratch */
78312fec14SDave Airlie 	for (i = 0x81; i <= 0x8f; i++)
79312fec14SDave Airlie 		ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, 0x00);
80312fec14SDave Airlie 
811453bf4cSDave Airlie 	if (ast->chip == AST2300 || ast->chip == AST2400) {
82312fec14SDave Airlie 		if (dev->pdev->revision >= 0x20)
83312fec14SDave Airlie 			ext_reg_info = extreginfo_ast2300;
84312fec14SDave Airlie 		else
85312fec14SDave Airlie 			ext_reg_info = extreginfo_ast2300a0;
86312fec14SDave Airlie 	} else
87312fec14SDave Airlie 		ext_reg_info = extreginfo;
88312fec14SDave Airlie 
89312fec14SDave Airlie 	index = 0xa0;
90312fec14SDave Airlie 	while (*ext_reg_info != 0xff) {
91312fec14SDave Airlie 		ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, index, 0x00, *ext_reg_info);
92312fec14SDave Airlie 		index++;
93312fec14SDave Airlie 		ext_reg_info++;
94312fec14SDave Airlie 	}
95312fec14SDave Airlie 
96312fec14SDave Airlie 	/* disable standard IO/MEM decode if secondary */
97312fec14SDave Airlie 	/* ast_set_index_reg-mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x3); */
98312fec14SDave Airlie 
99312fec14SDave Airlie 	/* Set Ext. Default */
100312fec14SDave Airlie 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x8c, 0x00, 0x01);
101312fec14SDave Airlie 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x00, 0x00);
102312fec14SDave Airlie 
103312fec14SDave Airlie 	/* Enable RAMDAC for A1 */
104312fec14SDave Airlie 	reg = 0x04;
1051453bf4cSDave Airlie 	if (ast->chip == AST2300 || ast->chip == AST2400)
106312fec14SDave Airlie 		reg |= 0x20;
107312fec14SDave Airlie 	ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff, reg);
108312fec14SDave Airlie }
109312fec14SDave Airlie 
110312fec14SDave Airlie static inline u32 mindwm(struct ast_private *ast, u32 r)
111312fec14SDave Airlie {
112312fec14SDave Airlie 	ast_write32(ast, 0xf004, r & 0xffff0000);
113312fec14SDave Airlie 	ast_write32(ast, 0xf000, 0x1);
114312fec14SDave Airlie 
115312fec14SDave Airlie 	return ast_read32(ast, 0x10000 + (r & 0x0000ffff));
116312fec14SDave Airlie }
117312fec14SDave Airlie 
118312fec14SDave Airlie static inline void moutdwm(struct ast_private *ast, u32 r, u32 v)
119312fec14SDave Airlie {
120312fec14SDave Airlie 	ast_write32(ast, 0xf004, r & 0xffff0000);
121312fec14SDave Airlie 	ast_write32(ast, 0xf000, 0x1);
122312fec14SDave Airlie 	ast_write32(ast, 0x10000 + (r & 0x0000ffff), v);
123312fec14SDave Airlie }
124312fec14SDave Airlie 
125312fec14SDave Airlie /*
126312fec14SDave Airlie  * AST2100/2150 DLL CBR Setting
127312fec14SDave Airlie  */
128312fec14SDave Airlie #define CBR_SIZE_AST2150	     ((16 << 10) - 1)
129312fec14SDave Airlie #define CBR_PASSNUM_AST2150          5
130312fec14SDave Airlie #define CBR_THRESHOLD_AST2150        10
131312fec14SDave Airlie #define CBR_THRESHOLD2_AST2150       10
132312fec14SDave Airlie #define TIMEOUT_AST2150              5000000
133312fec14SDave Airlie 
134312fec14SDave Airlie #define CBR_PATNUM_AST2150           8
135312fec14SDave Airlie 
136312fec14SDave Airlie static const u32 pattern_AST2150[14] = {
137312fec14SDave Airlie 	0xFF00FF00,
138312fec14SDave Airlie 	0xCC33CC33,
139312fec14SDave Airlie 	0xAA55AA55,
140312fec14SDave Airlie 	0xFFFE0001,
141312fec14SDave Airlie 	0x683501FE,
142312fec14SDave Airlie 	0x0F1929B0,
143312fec14SDave Airlie 	0x2D0B4346,
144312fec14SDave Airlie 	0x60767F02,
145312fec14SDave Airlie 	0x6FBE36A6,
146312fec14SDave Airlie 	0x3A253035,
147312fec14SDave Airlie 	0x3019686D,
148312fec14SDave Airlie 	0x41C6167E,
149312fec14SDave Airlie 	0x620152BF,
150312fec14SDave Airlie 	0x20F050E0
151312fec14SDave Airlie };
152312fec14SDave Airlie 
153312fec14SDave Airlie static u32 mmctestburst2_ast2150(struct ast_private *ast, u32 datagen)
154312fec14SDave Airlie {
155312fec14SDave Airlie 	u32 data, timeout;
156312fec14SDave Airlie 
157312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x00000000);
158312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x00000001 | (datagen << 3));
159312fec14SDave Airlie 	timeout = 0;
160312fec14SDave Airlie 	do {
161312fec14SDave Airlie 		data = mindwm(ast, 0x1e6e0070) & 0x40;
162312fec14SDave Airlie 		if (++timeout > TIMEOUT_AST2150) {
163312fec14SDave Airlie 			moutdwm(ast, 0x1e6e0070, 0x00000000);
164312fec14SDave Airlie 			return 0xffffffff;
165312fec14SDave Airlie 		}
166312fec14SDave Airlie 	} while (!data);
167312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x00000000);
168312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x00000003 | (datagen << 3));
169312fec14SDave Airlie 	timeout = 0;
170312fec14SDave Airlie 	do {
171312fec14SDave Airlie 		data = mindwm(ast, 0x1e6e0070) & 0x40;
172312fec14SDave Airlie 		if (++timeout > TIMEOUT_AST2150) {
173312fec14SDave Airlie 			moutdwm(ast, 0x1e6e0070, 0x00000000);
174312fec14SDave Airlie 			return 0xffffffff;
175312fec14SDave Airlie 		}
176312fec14SDave Airlie 	} while (!data);
177312fec14SDave Airlie 	data = (mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
178312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x00000000);
179312fec14SDave Airlie 	return data;
180312fec14SDave Airlie }
181312fec14SDave Airlie 
182312fec14SDave Airlie #if 0 /* unused in DDX driver - here for completeness */
183312fec14SDave Airlie static u32 mmctestsingle2_ast2150(struct ast_private *ast, u32 datagen)
184312fec14SDave Airlie {
185312fec14SDave Airlie 	u32 data, timeout;
186312fec14SDave Airlie 
187312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x00000000);
188312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3));
189312fec14SDave Airlie 	timeout = 0;
190312fec14SDave Airlie 	do {
191312fec14SDave Airlie 		data = mindwm(ast, 0x1e6e0070) & 0x40;
192312fec14SDave Airlie 		if (++timeout > TIMEOUT_AST2150) {
193312fec14SDave Airlie 			moutdwm(ast, 0x1e6e0070, 0x00000000);
194312fec14SDave Airlie 			return 0xffffffff;
195312fec14SDave Airlie 		}
196312fec14SDave Airlie 	} while (!data);
197312fec14SDave Airlie 	data = (mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
198312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x00000000);
199312fec14SDave Airlie 	return data;
200312fec14SDave Airlie }
201312fec14SDave Airlie #endif
202312fec14SDave Airlie 
203312fec14SDave Airlie static int cbrtest_ast2150(struct ast_private *ast)
204312fec14SDave Airlie {
205312fec14SDave Airlie 	int i;
206312fec14SDave Airlie 
207312fec14SDave Airlie 	for (i = 0; i < 8; i++)
208312fec14SDave Airlie 		if (mmctestburst2_ast2150(ast, i))
209312fec14SDave Airlie 			return 0;
210312fec14SDave Airlie 	return 1;
211312fec14SDave Airlie }
212312fec14SDave Airlie 
213312fec14SDave Airlie static int cbrscan_ast2150(struct ast_private *ast, int busw)
214312fec14SDave Airlie {
215312fec14SDave Airlie 	u32 patcnt, loop;
216312fec14SDave Airlie 
217312fec14SDave Airlie 	for (patcnt = 0; patcnt < CBR_PATNUM_AST2150; patcnt++) {
218312fec14SDave Airlie 		moutdwm(ast, 0x1e6e007c, pattern_AST2150[patcnt]);
219312fec14SDave Airlie 		for (loop = 0; loop < CBR_PASSNUM_AST2150; loop++) {
220312fec14SDave Airlie 			if (cbrtest_ast2150(ast))
221312fec14SDave Airlie 				break;
222312fec14SDave Airlie 		}
223312fec14SDave Airlie 		if (loop == CBR_PASSNUM_AST2150)
224312fec14SDave Airlie 			return 0;
225312fec14SDave Airlie 	}
226312fec14SDave Airlie 	return 1;
227312fec14SDave Airlie }
228312fec14SDave Airlie 
229312fec14SDave Airlie 
230312fec14SDave Airlie static void cbrdlli_ast2150(struct ast_private *ast, int busw)
231312fec14SDave Airlie {
232312fec14SDave Airlie 	u32 dll_min[4], dll_max[4], dlli, data, passcnt;
233312fec14SDave Airlie 
234312fec14SDave Airlie cbr_start:
235312fec14SDave Airlie 	dll_min[0] = dll_min[1] = dll_min[2] = dll_min[3] = 0xff;
236312fec14SDave Airlie 	dll_max[0] = dll_max[1] = dll_max[2] = dll_max[3] = 0x0;
237312fec14SDave Airlie 	passcnt = 0;
238312fec14SDave Airlie 
239312fec14SDave Airlie 	for (dlli = 0; dlli < 100; dlli++) {
240312fec14SDave Airlie 		moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
241312fec14SDave Airlie 		data = cbrscan_ast2150(ast, busw);
242312fec14SDave Airlie 		if (data != 0) {
243312fec14SDave Airlie 			if (data & 0x1) {
244312fec14SDave Airlie 				if (dll_min[0] > dlli)
245312fec14SDave Airlie 					dll_min[0] = dlli;
246312fec14SDave Airlie 				if (dll_max[0] < dlli)
247312fec14SDave Airlie 					dll_max[0] = dlli;
248312fec14SDave Airlie 			}
249312fec14SDave Airlie 			passcnt++;
250312fec14SDave Airlie 		} else if (passcnt >= CBR_THRESHOLD_AST2150)
251312fec14SDave Airlie 			goto cbr_start;
252312fec14SDave Airlie 	}
253312fec14SDave Airlie 	if (dll_max[0] == 0 || (dll_max[0]-dll_min[0]) < CBR_THRESHOLD_AST2150)
254312fec14SDave Airlie 		goto cbr_start;
255312fec14SDave Airlie 
256312fec14SDave Airlie 	dlli = dll_min[0] + (((dll_max[0] - dll_min[0]) * 7) >> 4);
257312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
258312fec14SDave Airlie }
259312fec14SDave Airlie 
260312fec14SDave Airlie 
261312fec14SDave Airlie 
262312fec14SDave Airlie static void ast_init_dram_reg(struct drm_device *dev)
263312fec14SDave Airlie {
264312fec14SDave Airlie 	struct ast_private *ast = dev->dev_private;
265312fec14SDave Airlie 	u8 j;
266312fec14SDave Airlie 	u32 data, temp, i;
267312fec14SDave Airlie 	const struct ast_dramstruct *dram_reg_info;
268312fec14SDave Airlie 
269312fec14SDave Airlie 	j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
270312fec14SDave Airlie 
271312fec14SDave Airlie 	if ((j & 0x80) == 0) { /* VGA only */
272312fec14SDave Airlie 		if (ast->chip == AST2000) {
273312fec14SDave Airlie 			dram_reg_info = ast2000_dram_table_data;
274312fec14SDave Airlie 			ast_write32(ast, 0xf004, 0x1e6e0000);
275312fec14SDave Airlie 			ast_write32(ast, 0xf000, 0x1);
276312fec14SDave Airlie 			ast_write32(ast, 0x10100, 0xa8);
277312fec14SDave Airlie 
278312fec14SDave Airlie 			do {
279312fec14SDave Airlie 				;
280312fec14SDave Airlie 			} while (ast_read32(ast, 0x10100) != 0xa8);
281312fec14SDave Airlie 		} else {/* AST2100/1100 */
282312fec14SDave Airlie 			if (ast->chip == AST2100 || ast->chip == 2200)
283312fec14SDave Airlie 				dram_reg_info = ast2100_dram_table_data;
284312fec14SDave Airlie 			else
285312fec14SDave Airlie 				dram_reg_info = ast1100_dram_table_data;
286312fec14SDave Airlie 
287312fec14SDave Airlie 			ast_write32(ast, 0xf004, 0x1e6e0000);
288312fec14SDave Airlie 			ast_write32(ast, 0xf000, 0x1);
289312fec14SDave Airlie 			ast_write32(ast, 0x12000, 0x1688A8A8);
290312fec14SDave Airlie 			do {
291312fec14SDave Airlie 				;
292312fec14SDave Airlie 			} while (ast_read32(ast, 0x12000) != 0x01);
293312fec14SDave Airlie 
294312fec14SDave Airlie 			ast_write32(ast, 0x10000, 0xfc600309);
295312fec14SDave Airlie 			do {
296312fec14SDave Airlie 				;
297312fec14SDave Airlie 			} while (ast_read32(ast, 0x10000) != 0x01);
298312fec14SDave Airlie 		}
299312fec14SDave Airlie 
300312fec14SDave Airlie 		while (dram_reg_info->index != 0xffff) {
301312fec14SDave Airlie 			if (dram_reg_info->index == 0xff00) {/* delay fn */
302312fec14SDave Airlie 				for (i = 0; i < 15; i++)
303312fec14SDave Airlie 					udelay(dram_reg_info->data);
304312fec14SDave Airlie 			} else if (dram_reg_info->index == 0x4 && ast->chip != AST2000) {
305312fec14SDave Airlie 				data = dram_reg_info->data;
306312fec14SDave Airlie 				if (ast->dram_type == AST_DRAM_1Gx16)
307312fec14SDave Airlie 					data = 0x00000d89;
308312fec14SDave Airlie 				else if (ast->dram_type == AST_DRAM_1Gx32)
309312fec14SDave Airlie 					data = 0x00000c8d;
310312fec14SDave Airlie 
311312fec14SDave Airlie 				temp = ast_read32(ast, 0x12070);
312312fec14SDave Airlie 				temp &= 0xc;
313312fec14SDave Airlie 				temp <<= 2;
314312fec14SDave Airlie 				ast_write32(ast, 0x10000 + dram_reg_info->index, data | temp);
315312fec14SDave Airlie 			} else
316312fec14SDave Airlie 				ast_write32(ast, 0x10000 + dram_reg_info->index, dram_reg_info->data);
317312fec14SDave Airlie 			dram_reg_info++;
318312fec14SDave Airlie 		}
319312fec14SDave Airlie 
320312fec14SDave Airlie 		/* AST 2100/2150 DRAM calibration */
321312fec14SDave Airlie 		data = ast_read32(ast, 0x10120);
322312fec14SDave Airlie 		if (data == 0x5061) { /* 266Mhz */
323312fec14SDave Airlie 			data = ast_read32(ast, 0x10004);
324312fec14SDave Airlie 			if (data & 0x40)
325312fec14SDave Airlie 				cbrdlli_ast2150(ast, 16); /* 16 bits */
326312fec14SDave Airlie 			else
327312fec14SDave Airlie 				cbrdlli_ast2150(ast, 32); /* 32 bits */
328312fec14SDave Airlie 		}
329312fec14SDave Airlie 
330312fec14SDave Airlie 		switch (ast->chip) {
331312fec14SDave Airlie 		case AST2000:
332312fec14SDave Airlie 			temp = ast_read32(ast, 0x10140);
333312fec14SDave Airlie 			ast_write32(ast, 0x10140, temp | 0x40);
334312fec14SDave Airlie 			break;
335312fec14SDave Airlie 		case AST1100:
336312fec14SDave Airlie 		case AST2100:
337312fec14SDave Airlie 		case AST2200:
338312fec14SDave Airlie 		case AST2150:
339312fec14SDave Airlie 			temp = ast_read32(ast, 0x1200c);
340312fec14SDave Airlie 			ast_write32(ast, 0x1200c, temp & 0xfffffffd);
341312fec14SDave Airlie 			temp = ast_read32(ast, 0x12040);
342312fec14SDave Airlie 			ast_write32(ast, 0x12040, temp | 0x40);
343312fec14SDave Airlie 			break;
344312fec14SDave Airlie 		default:
345312fec14SDave Airlie 			break;
346312fec14SDave Airlie 		}
347312fec14SDave Airlie 	}
348312fec14SDave Airlie 
349312fec14SDave Airlie 	/* wait ready */
350312fec14SDave Airlie 	do {
351312fec14SDave Airlie 		j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
352312fec14SDave Airlie 	} while ((j & 0x40) == 0);
353312fec14SDave Airlie }
354312fec14SDave Airlie 
355312fec14SDave Airlie void ast_post_gpu(struct drm_device *dev)
356312fec14SDave Airlie {
357312fec14SDave Airlie 	u32 reg;
358312fec14SDave Airlie 	struct ast_private *ast = dev->dev_private;
359312fec14SDave Airlie 
360312fec14SDave Airlie 	pci_read_config_dword(ast->dev->pdev, 0x04, &reg);
361312fec14SDave Airlie 	reg |= 0x3;
362312fec14SDave Airlie 	pci_write_config_dword(ast->dev->pdev, 0x04, reg);
363312fec14SDave Airlie 
364312fec14SDave Airlie 	ast_enable_vga(dev);
365312fec14SDave Airlie 	ast_open_key(ast);
366312fec14SDave Airlie 	ast_set_def_ext_reg(dev);
367312fec14SDave Airlie 
3681453bf4cSDave Airlie 	if (ast->chip == AST2300 || ast->chip == AST2400)
369312fec14SDave Airlie 		ast_init_dram_2300(dev);
370312fec14SDave Airlie 	else
371312fec14SDave Airlie 		ast_init_dram_reg(dev);
372312fec14SDave Airlie }
373312fec14SDave Airlie 
374312fec14SDave Airlie /* AST 2300 DRAM settings */
375312fec14SDave Airlie #define AST_DDR3 0
376312fec14SDave Airlie #define AST_DDR2 1
377312fec14SDave Airlie 
378312fec14SDave Airlie struct ast2300_dram_param {
379312fec14SDave Airlie 	u32 dram_type;
380312fec14SDave Airlie 	u32 dram_chipid;
381312fec14SDave Airlie 	u32 dram_freq;
382312fec14SDave Airlie 	u32 vram_size;
383312fec14SDave Airlie 	u32 odt;
384312fec14SDave Airlie 	u32 wodt;
385312fec14SDave Airlie 	u32 rodt;
386312fec14SDave Airlie 	u32 dram_config;
387312fec14SDave Airlie 	u32 reg_PERIOD;
388312fec14SDave Airlie 	u32 reg_MADJ;
389312fec14SDave Airlie 	u32 reg_SADJ;
390312fec14SDave Airlie 	u32 reg_MRS;
391312fec14SDave Airlie 	u32 reg_EMRS;
392312fec14SDave Airlie 	u32 reg_AC1;
393312fec14SDave Airlie 	u32 reg_AC2;
394312fec14SDave Airlie 	u32 reg_DQSIC;
395312fec14SDave Airlie 	u32 reg_DRV;
396312fec14SDave Airlie 	u32 reg_IOZ;
397312fec14SDave Airlie 	u32 reg_DQIDLY;
398312fec14SDave Airlie 	u32 reg_FREQ;
399312fec14SDave Airlie 	u32 madj_max;
400312fec14SDave Airlie 	u32 dll2_finetune_step;
401312fec14SDave Airlie };
402312fec14SDave Airlie 
403312fec14SDave Airlie /*
404312fec14SDave Airlie  * DQSI DLL CBR Setting
405312fec14SDave Airlie  */
406312fec14SDave Airlie #define CBR_SIZE1            ((4  << 10) - 1)
407312fec14SDave Airlie #define CBR_SIZE2            ((64 << 10) - 1)
408312fec14SDave Airlie #define CBR_PASSNUM          5
409312fec14SDave Airlie #define CBR_PASSNUM2         5
410312fec14SDave Airlie #define CBR_THRESHOLD        10
411312fec14SDave Airlie #define CBR_THRESHOLD2       10
412312fec14SDave Airlie #define TIMEOUT              5000000
413312fec14SDave Airlie #define CBR_PATNUM           8
414312fec14SDave Airlie 
415312fec14SDave Airlie static const u32 pattern[8] = {
416312fec14SDave Airlie 	0xFF00FF00,
417312fec14SDave Airlie 	0xCC33CC33,
418312fec14SDave Airlie 	0xAA55AA55,
419312fec14SDave Airlie 	0x88778877,
420312fec14SDave Airlie 	0x92CC4D6E,
421312fec14SDave Airlie 	0x543D3CDE,
422312fec14SDave Airlie 	0xF1E843C7,
423312fec14SDave Airlie 	0x7C61D253
424312fec14SDave Airlie };
425312fec14SDave Airlie 
426312fec14SDave Airlie #if 0 /* unused in DDX, included for completeness */
427312fec14SDave Airlie static int mmc_test_burst(struct ast_private *ast, u32 datagen)
428312fec14SDave Airlie {
429312fec14SDave Airlie 	u32 data, timeout;
430312fec14SDave Airlie 
431312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x00000000);
432312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x000000c1 | (datagen << 3));
433312fec14SDave Airlie 	timeout = 0;
434312fec14SDave Airlie 	do {
435312fec14SDave Airlie 		data = mindwm(ast, 0x1e6e0070) & 0x3000;
436312fec14SDave Airlie 		if (data & 0x2000) {
437312fec14SDave Airlie 			return 0;
438312fec14SDave Airlie 		}
439312fec14SDave Airlie 		if (++timeout > TIMEOUT) {
440312fec14SDave Airlie 			moutdwm(ast, 0x1e6e0070, 0x00000000);
441312fec14SDave Airlie 			return 0;
442312fec14SDave Airlie 		}
443312fec14SDave Airlie 	} while (!data);
444312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x00000000);
445312fec14SDave Airlie 	return 1;
446312fec14SDave Airlie }
447312fec14SDave Airlie #endif
448312fec14SDave Airlie 
449312fec14SDave Airlie static int mmc_test_burst2(struct ast_private *ast, u32 datagen)
450312fec14SDave Airlie {
451312fec14SDave Airlie 	u32 data, timeout;
452312fec14SDave Airlie 
453312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x00000000);
454312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x00000041 | (datagen << 3));
455312fec14SDave Airlie 	timeout = 0;
456312fec14SDave Airlie 	do {
457312fec14SDave Airlie 		data = mindwm(ast, 0x1e6e0070) & 0x1000;
458312fec14SDave Airlie 		if (++timeout > TIMEOUT) {
459312fec14SDave Airlie 			moutdwm(ast, 0x1e6e0070, 0x0);
460312fec14SDave Airlie 			return -1;
461312fec14SDave Airlie 		}
462312fec14SDave Airlie 	} while (!data);
463312fec14SDave Airlie 	data = mindwm(ast, 0x1e6e0078);
464312fec14SDave Airlie 	data = (data | (data >> 16)) & 0xffff;
465312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x0);
466312fec14SDave Airlie 	return data;
467312fec14SDave Airlie }
468312fec14SDave Airlie 
469312fec14SDave Airlie #if 0 /* Unused in DDX here for completeness */
470312fec14SDave Airlie static int mmc_test_single(struct ast_private *ast, u32 datagen)
471312fec14SDave Airlie {
472312fec14SDave Airlie 	u32 data, timeout;
473312fec14SDave Airlie 
474312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x00000000);
475312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x000000c5 | (datagen << 3));
476312fec14SDave Airlie 	timeout = 0;
477312fec14SDave Airlie 	do {
478312fec14SDave Airlie 		data = mindwm(ast, 0x1e6e0070) & 0x3000;
479312fec14SDave Airlie 		if (data & 0x2000)
480312fec14SDave Airlie 			return 0;
481312fec14SDave Airlie 		if (++timeout > TIMEOUT) {
482312fec14SDave Airlie 			moutdwm(ast, 0x1e6e0070, 0x0);
483312fec14SDave Airlie 			return 0;
484312fec14SDave Airlie 		}
485312fec14SDave Airlie 	} while (!data);
486312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x0);
487312fec14SDave Airlie 	return 1;
488312fec14SDave Airlie }
489312fec14SDave Airlie #endif
490312fec14SDave Airlie 
491312fec14SDave Airlie static int mmc_test_single2(struct ast_private *ast, u32 datagen)
492312fec14SDave Airlie {
493312fec14SDave Airlie 	u32 data, timeout;
494312fec14SDave Airlie 
495312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x00000000);
496312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3));
497312fec14SDave Airlie 	timeout = 0;
498312fec14SDave Airlie 	do {
499312fec14SDave Airlie 		data = mindwm(ast, 0x1e6e0070) & 0x1000;
500312fec14SDave Airlie 		if (++timeout > TIMEOUT) {
501312fec14SDave Airlie 			moutdwm(ast, 0x1e6e0070, 0x0);
502312fec14SDave Airlie 			return -1;
503312fec14SDave Airlie 		}
504312fec14SDave Airlie 	} while (!data);
505312fec14SDave Airlie 	data = mindwm(ast, 0x1e6e0078);
506312fec14SDave Airlie 	data = (data | (data >> 16)) & 0xffff;
507312fec14SDave Airlie 	moutdwm(ast, 0x1e6e0070, 0x0);
508312fec14SDave Airlie 	return data;
509312fec14SDave Airlie }
510312fec14SDave Airlie 
511312fec14SDave Airlie static int cbr_test(struct ast_private *ast)
512312fec14SDave Airlie {
513312fec14SDave Airlie 	u32 data;
514312fec14SDave Airlie 	int i;
515312fec14SDave Airlie 	data = mmc_test_single2(ast, 0);
516312fec14SDave Airlie 	if ((data & 0xff) && (data & 0xff00))
517312fec14SDave Airlie 		return 0;
518312fec14SDave Airlie 	for (i = 0; i < 8; i++) {
519312fec14SDave Airlie 		data = mmc_test_burst2(ast, i);
520312fec14SDave Airlie 		if ((data & 0xff) && (data & 0xff00))
521312fec14SDave Airlie 			return 0;
522312fec14SDave Airlie 	}
523312fec14SDave Airlie 	if (!data)
524312fec14SDave Airlie 		return 3;
525312fec14SDave Airlie 	else if (data & 0xff)
526312fec14SDave Airlie 		return 2;
527312fec14SDave Airlie 	return 1;
528312fec14SDave Airlie }
529312fec14SDave Airlie 
530312fec14SDave Airlie static int cbr_scan(struct ast_private *ast)
531312fec14SDave Airlie {
532312fec14SDave Airlie 	u32 data, data2, patcnt, loop;
533312fec14SDave Airlie 
534312fec14SDave Airlie 	data2 = 3;
535312fec14SDave Airlie 	for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
536312fec14SDave Airlie 		moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
537312fec14SDave Airlie 		for (loop = 0; loop < CBR_PASSNUM2; loop++) {
538312fec14SDave Airlie 			if ((data = cbr_test(ast)) != 0) {
539312fec14SDave Airlie 				data2 &= data;
540312fec14SDave Airlie 				if (!data2)
541312fec14SDave Airlie 					return 0;
542312fec14SDave Airlie 				break;
543312fec14SDave Airlie 			}
544312fec14SDave Airlie 		}
545312fec14SDave Airlie 		if (loop == CBR_PASSNUM2)
546312fec14SDave Airlie 			return 0;
547312fec14SDave Airlie 	}
548312fec14SDave Airlie 	return data2;
549312fec14SDave Airlie }
550312fec14SDave Airlie 
551312fec14SDave Airlie static u32 cbr_test2(struct ast_private *ast)
552312fec14SDave Airlie {
553312fec14SDave Airlie 	u32 data;
554312fec14SDave Airlie 
555312fec14SDave Airlie 	data = mmc_test_burst2(ast, 0);
556312fec14SDave Airlie 	if (data == 0xffff)
557312fec14SDave Airlie 		return 0;
558312fec14SDave Airlie 	data |= mmc_test_single2(ast, 0);
559312fec14SDave Airlie 	if (data == 0xffff)
560312fec14SDave Airlie 		return 0;
561312fec14SDave Airlie 
562312fec14SDave Airlie 	return ~data & 0xffff;
563312fec14SDave Airlie }
564312fec14SDave Airlie 
565312fec14SDave Airlie static u32 cbr_scan2(struct ast_private *ast)
566312fec14SDave Airlie {
567312fec14SDave Airlie 	u32 data, data2, patcnt, loop;
568312fec14SDave Airlie 
569312fec14SDave Airlie 	data2 = 0xffff;
570312fec14SDave Airlie 	for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
571312fec14SDave Airlie 		moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
572312fec14SDave Airlie 		for (loop = 0; loop < CBR_PASSNUM2; loop++) {
573312fec14SDave Airlie 			if ((data = cbr_test2(ast)) != 0) {
574312fec14SDave Airlie 				data2 &= data;
575312fec14SDave Airlie 				if (!data)
576312fec14SDave Airlie 					return 0;
577312fec14SDave Airlie 				break;
578312fec14SDave Airlie 			}
579312fec14SDave Airlie 		}
580312fec14SDave Airlie 		if (loop == CBR_PASSNUM2)
581312fec14SDave Airlie 			return 0;
582312fec14SDave Airlie 	}
583312fec14SDave Airlie 	return data2;
584312fec14SDave Airlie }
585312fec14SDave Airlie 
586312fec14SDave Airlie #if 0 /* unused in DDX - added for completeness */
587312fec14SDave Airlie static void finetuneDQI(struct ast_private *ast, struct ast2300_dram_param *param)
588312fec14SDave Airlie {
589312fec14SDave Airlie 	u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt;
590312fec14SDave Airlie 
591312fec14SDave Airlie 	gold_sadj[0] = (mindwm(ast, 0x1E6E0024) >> 16) & 0xffff;
592312fec14SDave Airlie 	gold_sadj[1] = gold_sadj[0] >> 8;
593312fec14SDave Airlie 	gold_sadj[0] = gold_sadj[0] & 0xff;
594312fec14SDave Airlie 	gold_sadj[0] = (gold_sadj[0] + gold_sadj[1]) >> 1;
595312fec14SDave Airlie 	gold_sadj[1] = gold_sadj[0];
596312fec14SDave Airlie 
597312fec14SDave Airlie 	for (cnt = 0; cnt < 16; cnt++) {
598312fec14SDave Airlie 		dllmin[cnt] = 0xff;
599312fec14SDave Airlie 		dllmax[cnt] = 0x0;
600312fec14SDave Airlie 	}
601312fec14SDave Airlie 	passcnt = 0;
602312fec14SDave Airlie 	for (dlli = 0; dlli < 76; dlli++) {
603312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
604312fec14SDave Airlie 		/* Wait DQSI latch phase calibration */
605312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0074, 0x00000010);
606312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0070, 0x00000003);
607312fec14SDave Airlie 		do {
608312fec14SDave Airlie 			data = mindwm(ast, 0x1E6E0070);
609312fec14SDave Airlie 		} while (!(data & 0x00001000));
610312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0070, 0x00000000);
611312fec14SDave Airlie 
612312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0074, CBR_SIZE1);
613312fec14SDave Airlie 		data = cbr_scan2(ast);
614312fec14SDave Airlie 		if (data != 0) {
615312fec14SDave Airlie 			mask = 0x00010001;
616312fec14SDave Airlie 			for (cnt = 0; cnt < 16; cnt++) {
617312fec14SDave Airlie 				if (data & mask) {
618312fec14SDave Airlie 					if (dllmin[cnt] > dlli) {
619312fec14SDave Airlie 						dllmin[cnt] = dlli;
620312fec14SDave Airlie 					}
621312fec14SDave Airlie 					if (dllmax[cnt] < dlli) {
622312fec14SDave Airlie 						dllmax[cnt] = dlli;
623312fec14SDave Airlie 					}
624312fec14SDave Airlie 				}
625312fec14SDave Airlie 				mask <<= 1;
626312fec14SDave Airlie 			}
627312fec14SDave Airlie 			passcnt++;
628312fec14SDave Airlie 		} else if (passcnt >= CBR_THRESHOLD) {
629312fec14SDave Airlie 			break;
630312fec14SDave Airlie 		}
631312fec14SDave Airlie 	}
632312fec14SDave Airlie 	data = 0;
633312fec14SDave Airlie 	for (cnt = 0; cnt < 8; cnt++) {
634312fec14SDave Airlie 		data >>= 3;
635312fec14SDave Airlie 		if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD)) {
636312fec14SDave Airlie 			dlli = (dllmin[cnt] + dllmax[cnt]) >> 1;
637312fec14SDave Airlie 			if (gold_sadj[0] >= dlli) {
638312fec14SDave Airlie 				dlli = (gold_sadj[0] - dlli) >> 1;
639312fec14SDave Airlie 				if (dlli > 3) {
640312fec14SDave Airlie 					dlli = 3;
641312fec14SDave Airlie 				}
642312fec14SDave Airlie 			} else {
643312fec14SDave Airlie 				dlli = (dlli - gold_sadj[0]) >> 1;
644312fec14SDave Airlie 				if (dlli > 4) {
645312fec14SDave Airlie 					dlli = 4;
646312fec14SDave Airlie 				}
647312fec14SDave Airlie 				dlli = (8 - dlli) & 0x7;
648312fec14SDave Airlie 			}
649312fec14SDave Airlie 			data |= dlli << 21;
650312fec14SDave Airlie 		}
651312fec14SDave Airlie 	}
652312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0080, data);
653312fec14SDave Airlie 
654312fec14SDave Airlie 	data = 0;
655312fec14SDave Airlie 	for (cnt = 8; cnt < 16; cnt++) {
656312fec14SDave Airlie 		data >>= 3;
657312fec14SDave Airlie 		if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD)) {
658312fec14SDave Airlie 			dlli = (dllmin[cnt] + dllmax[cnt]) >> 1;
659312fec14SDave Airlie 			if (gold_sadj[1] >= dlli) {
660312fec14SDave Airlie 				dlli = (gold_sadj[1] - dlli) >> 1;
661312fec14SDave Airlie 				if (dlli > 3) {
662312fec14SDave Airlie 					dlli = 3;
663312fec14SDave Airlie 				} else {
664312fec14SDave Airlie 					dlli = (dlli - 1) & 0x7;
665312fec14SDave Airlie 				}
666312fec14SDave Airlie 			} else {
667312fec14SDave Airlie 				dlli = (dlli - gold_sadj[1]) >> 1;
668312fec14SDave Airlie 				dlli += 1;
669312fec14SDave Airlie 				if (dlli > 4) {
670312fec14SDave Airlie 					dlli = 4;
671312fec14SDave Airlie 				}
672312fec14SDave Airlie 				dlli = (8 - dlli) & 0x7;
673312fec14SDave Airlie 			}
674312fec14SDave Airlie 			data |= dlli << 21;
675312fec14SDave Airlie 		}
676312fec14SDave Airlie 	}
677312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0084, data);
678312fec14SDave Airlie 
679312fec14SDave Airlie } /* finetuneDQI */
680312fec14SDave Airlie #endif
681312fec14SDave Airlie 
682312fec14SDave Airlie static void finetuneDQI_L(struct ast_private *ast, struct ast2300_dram_param *param)
683312fec14SDave Airlie {
684312fec14SDave Airlie 	u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt;
685312fec14SDave Airlie 
686312fec14SDave Airlie FINETUNE_START:
687312fec14SDave Airlie 	for (cnt = 0; cnt < 16; cnt++) {
688312fec14SDave Airlie 		dllmin[cnt] = 0xff;
689312fec14SDave Airlie 		dllmax[cnt] = 0x0;
690312fec14SDave Airlie 	}
691312fec14SDave Airlie 	passcnt = 0;
692312fec14SDave Airlie 	for (dlli = 0; dlli < 76; dlli++) {
693312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
694312fec14SDave Airlie 		/* Wait DQSI latch phase calibration */
695312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0074, 0x00000010);
696312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0070, 0x00000003);
697312fec14SDave Airlie 		do {
698312fec14SDave Airlie 			data = mindwm(ast, 0x1E6E0070);
699312fec14SDave Airlie 		} while (!(data & 0x00001000));
700312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0070, 0x00000000);
701312fec14SDave Airlie 
702312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0074, CBR_SIZE1);
703312fec14SDave Airlie 		data = cbr_scan2(ast);
704312fec14SDave Airlie 		if (data != 0) {
705312fec14SDave Airlie 			mask = 0x00010001;
706312fec14SDave Airlie 			for (cnt = 0; cnt < 16; cnt++) {
707312fec14SDave Airlie 				if (data & mask) {
708312fec14SDave Airlie 					if (dllmin[cnt] > dlli) {
709312fec14SDave Airlie 						dllmin[cnt] = dlli;
710312fec14SDave Airlie 					}
711312fec14SDave Airlie 					if (dllmax[cnt] < dlli) {
712312fec14SDave Airlie 						dllmax[cnt] = dlli;
713312fec14SDave Airlie 					}
714312fec14SDave Airlie 				}
715312fec14SDave Airlie 				mask <<= 1;
716312fec14SDave Airlie 			}
717312fec14SDave Airlie 			passcnt++;
718312fec14SDave Airlie 		} else if (passcnt >= CBR_THRESHOLD2) {
719312fec14SDave Airlie 			break;
720312fec14SDave Airlie 		}
721312fec14SDave Airlie 	}
722312fec14SDave Airlie 	gold_sadj[0] = 0x0;
723312fec14SDave Airlie 	passcnt = 0;
724312fec14SDave Airlie 	for (cnt = 0; cnt < 16; cnt++) {
725312fec14SDave Airlie 		if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
726312fec14SDave Airlie 			gold_sadj[0] += dllmin[cnt];
727312fec14SDave Airlie 			passcnt++;
728312fec14SDave Airlie 		}
729312fec14SDave Airlie 	}
730312fec14SDave Airlie 	if (passcnt != 16) {
731312fec14SDave Airlie 		goto FINETUNE_START;
732312fec14SDave Airlie 	}
733312fec14SDave Airlie 	gold_sadj[0] = gold_sadj[0] >> 4;
734312fec14SDave Airlie 	gold_sadj[1] = gold_sadj[0];
735312fec14SDave Airlie 
736312fec14SDave Airlie 	data = 0;
737312fec14SDave Airlie 	for (cnt = 0; cnt < 8; cnt++) {
738312fec14SDave Airlie 		data >>= 3;
739312fec14SDave Airlie 		if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
740312fec14SDave Airlie 			dlli = dllmin[cnt];
741312fec14SDave Airlie 			if (gold_sadj[0] >= dlli) {
742312fec14SDave Airlie 				dlli = ((gold_sadj[0] - dlli) * 19) >> 5;
743312fec14SDave Airlie 				if (dlli > 3) {
744312fec14SDave Airlie 					dlli = 3;
745312fec14SDave Airlie 				}
746312fec14SDave Airlie 			} else {
747312fec14SDave Airlie 				dlli = ((dlli - gold_sadj[0]) * 19) >> 5;
748312fec14SDave Airlie 				if (dlli > 4) {
749312fec14SDave Airlie 					dlli = 4;
750312fec14SDave Airlie 				}
751312fec14SDave Airlie 				dlli = (8 - dlli) & 0x7;
752312fec14SDave Airlie 			}
753312fec14SDave Airlie 			data |= dlli << 21;
754312fec14SDave Airlie 		}
755312fec14SDave Airlie 	}
756312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0080, data);
757312fec14SDave Airlie 
758312fec14SDave Airlie 	data = 0;
759312fec14SDave Airlie 	for (cnt = 8; cnt < 16; cnt++) {
760312fec14SDave Airlie 		data >>= 3;
761312fec14SDave Airlie 		if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
762312fec14SDave Airlie 			dlli = dllmin[cnt];
763312fec14SDave Airlie 			if (gold_sadj[1] >= dlli) {
764312fec14SDave Airlie 				dlli = ((gold_sadj[1] - dlli) * 19) >> 5;
765312fec14SDave Airlie 				if (dlli > 3) {
766312fec14SDave Airlie 					dlli = 3;
767312fec14SDave Airlie 				} else {
768312fec14SDave Airlie 					dlli = (dlli - 1) & 0x7;
769312fec14SDave Airlie 				}
770312fec14SDave Airlie 			} else {
771312fec14SDave Airlie 				dlli = ((dlli - gold_sadj[1]) * 19) >> 5;
772312fec14SDave Airlie 				dlli += 1;
773312fec14SDave Airlie 				if (dlli > 4) {
774312fec14SDave Airlie 					dlli = 4;
775312fec14SDave Airlie 				}
776312fec14SDave Airlie 				dlli = (8 - dlli) & 0x7;
777312fec14SDave Airlie 			}
778312fec14SDave Airlie 			data |= dlli << 21;
779312fec14SDave Airlie 		}
780312fec14SDave Airlie 	}
781312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0084, data);
782312fec14SDave Airlie 
783312fec14SDave Airlie } /* finetuneDQI_L */
784312fec14SDave Airlie 
785312fec14SDave Airlie static void finetuneDQI_L2(struct ast_private *ast, struct ast2300_dram_param *param)
786312fec14SDave Airlie {
787312fec14SDave Airlie 	u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, data2;
788312fec14SDave Airlie 
789312fec14SDave Airlie 	for (cnt = 0; cnt < 16; cnt++) {
790312fec14SDave Airlie 		dllmin[cnt] = 0xff;
791312fec14SDave Airlie 		dllmax[cnt] = 0x0;
792312fec14SDave Airlie 	}
793312fec14SDave Airlie 	passcnt = 0;
794312fec14SDave Airlie 	for (dlli = 0; dlli < 76; dlli++) {
795312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
796312fec14SDave Airlie 		/* Wait DQSI latch phase calibration */
797312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0074, 0x00000010);
798312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0070, 0x00000003);
799312fec14SDave Airlie 		do {
800312fec14SDave Airlie 			data = mindwm(ast, 0x1E6E0070);
801312fec14SDave Airlie 		} while (!(data & 0x00001000));
802312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0070, 0x00000000);
803312fec14SDave Airlie 
804312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0074, CBR_SIZE2);
805312fec14SDave Airlie 		data = cbr_scan2(ast);
806312fec14SDave Airlie 		if (data != 0) {
807312fec14SDave Airlie 			mask = 0x00010001;
808312fec14SDave Airlie 			for (cnt = 0; cnt < 16; cnt++) {
809312fec14SDave Airlie 				if (data & mask) {
810312fec14SDave Airlie 					if (dllmin[cnt] > dlli) {
811312fec14SDave Airlie 						dllmin[cnt] = dlli;
812312fec14SDave Airlie 					}
813312fec14SDave Airlie 					if (dllmax[cnt] < dlli) {
814312fec14SDave Airlie 						dllmax[cnt] = dlli;
815312fec14SDave Airlie 					}
816312fec14SDave Airlie 				}
817312fec14SDave Airlie 				mask <<= 1;
818312fec14SDave Airlie 			}
819312fec14SDave Airlie 			passcnt++;
820312fec14SDave Airlie 		} else if (passcnt >= CBR_THRESHOLD2) {
821312fec14SDave Airlie 			break;
822312fec14SDave Airlie 		}
823312fec14SDave Airlie 	}
824312fec14SDave Airlie 	gold_sadj[0] = 0x0;
825312fec14SDave Airlie 	gold_sadj[1] = 0xFF;
826312fec14SDave Airlie 	for (cnt = 0; cnt < 8; cnt++) {
827312fec14SDave Airlie 		if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
828312fec14SDave Airlie 			if (gold_sadj[0] < dllmin[cnt]) {
829312fec14SDave Airlie 				gold_sadj[0] = dllmin[cnt];
830312fec14SDave Airlie 			}
831312fec14SDave Airlie 			if (gold_sadj[1] > dllmax[cnt]) {
832312fec14SDave Airlie 				gold_sadj[1] = dllmax[cnt];
833312fec14SDave Airlie 			}
834312fec14SDave Airlie 		}
835312fec14SDave Airlie 	}
836312fec14SDave Airlie 	gold_sadj[0] = (gold_sadj[1] + gold_sadj[0]) >> 1;
837312fec14SDave Airlie 	gold_sadj[1] = mindwm(ast, 0x1E6E0080);
838312fec14SDave Airlie 
839312fec14SDave Airlie 	data = 0;
840312fec14SDave Airlie 	for (cnt = 0; cnt < 8; cnt++) {
841312fec14SDave Airlie 		data >>= 3;
842312fec14SDave Airlie 		data2 = gold_sadj[1] & 0x7;
843312fec14SDave Airlie 		gold_sadj[1] >>= 3;
844312fec14SDave Airlie 		if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
845312fec14SDave Airlie 			dlli = (dllmin[cnt] + dllmax[cnt]) >> 1;
846312fec14SDave Airlie 			if (gold_sadj[0] >= dlli) {
847312fec14SDave Airlie 				dlli = (gold_sadj[0] - dlli) >> 1;
848312fec14SDave Airlie 				if (dlli > 0) {
849312fec14SDave Airlie 					dlli = 1;
850312fec14SDave Airlie 				}
851312fec14SDave Airlie 				if (data2 != 3) {
852312fec14SDave Airlie 					data2 = (data2 + dlli) & 0x7;
853312fec14SDave Airlie 				}
854312fec14SDave Airlie 			} else {
855312fec14SDave Airlie 				dlli = (dlli - gold_sadj[0]) >> 1;
856312fec14SDave Airlie 				if (dlli > 0) {
857312fec14SDave Airlie 					dlli = 1;
858312fec14SDave Airlie 				}
859312fec14SDave Airlie 				if (data2 != 4) {
860312fec14SDave Airlie 					data2 = (data2 - dlli) & 0x7;
861312fec14SDave Airlie 				}
862312fec14SDave Airlie 			}
863312fec14SDave Airlie 		}
864312fec14SDave Airlie 		data |= data2 << 21;
865312fec14SDave Airlie 	}
866312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0080, data);
867312fec14SDave Airlie 
868312fec14SDave Airlie 	gold_sadj[0] = 0x0;
869312fec14SDave Airlie 	gold_sadj[1] = 0xFF;
870312fec14SDave Airlie 	for (cnt = 8; cnt < 16; cnt++) {
871312fec14SDave Airlie 		if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
872312fec14SDave Airlie 			if (gold_sadj[0] < dllmin[cnt]) {
873312fec14SDave Airlie 				gold_sadj[0] = dllmin[cnt];
874312fec14SDave Airlie 			}
875312fec14SDave Airlie 			if (gold_sadj[1] > dllmax[cnt]) {
876312fec14SDave Airlie 				gold_sadj[1] = dllmax[cnt];
877312fec14SDave Airlie 			}
878312fec14SDave Airlie 		}
879312fec14SDave Airlie 	}
880312fec14SDave Airlie 	gold_sadj[0] = (gold_sadj[1] + gold_sadj[0]) >> 1;
881312fec14SDave Airlie 	gold_sadj[1] = mindwm(ast, 0x1E6E0084);
882312fec14SDave Airlie 
883312fec14SDave Airlie 	data = 0;
884312fec14SDave Airlie 	for (cnt = 8; cnt < 16; cnt++) {
885312fec14SDave Airlie 		data >>= 3;
886312fec14SDave Airlie 		data2 = gold_sadj[1] & 0x7;
887312fec14SDave Airlie 		gold_sadj[1] >>= 3;
888312fec14SDave Airlie 		if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
889312fec14SDave Airlie 			dlli = (dllmin[cnt] + dllmax[cnt]) >> 1;
890312fec14SDave Airlie 			if (gold_sadj[0] >= dlli) {
891312fec14SDave Airlie 				dlli = (gold_sadj[0] - dlli) >> 1;
892312fec14SDave Airlie 				if (dlli > 0) {
893312fec14SDave Airlie 					dlli = 1;
894312fec14SDave Airlie 				}
895312fec14SDave Airlie 				if (data2 != 3) {
896312fec14SDave Airlie 					data2 = (data2 + dlli) & 0x7;
897312fec14SDave Airlie 				}
898312fec14SDave Airlie 			} else {
899312fec14SDave Airlie 				dlli = (dlli - gold_sadj[0]) >> 1;
900312fec14SDave Airlie 				if (dlli > 0) {
901312fec14SDave Airlie 					dlli = 1;
902312fec14SDave Airlie 				}
903312fec14SDave Airlie 				if (data2 != 4) {
904312fec14SDave Airlie 					data2 = (data2 - dlli) & 0x7;
905312fec14SDave Airlie 				}
906312fec14SDave Airlie 			}
907312fec14SDave Airlie 		}
908312fec14SDave Airlie 		data |= data2 << 21;
909312fec14SDave Airlie 	}
910312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0084, data);
911312fec14SDave Airlie 
912312fec14SDave Airlie } /* finetuneDQI_L2 */
913312fec14SDave Airlie 
914312fec14SDave Airlie static void cbr_dll2(struct ast_private *ast, struct ast2300_dram_param *param)
915312fec14SDave Airlie {
916312fec14SDave Airlie 	u32 dllmin[2], dllmax[2], dlli, data, data2, passcnt;
917312fec14SDave Airlie 
918312fec14SDave Airlie 
919312fec14SDave Airlie 	finetuneDQI_L(ast, param);
920312fec14SDave Airlie 	finetuneDQI_L2(ast, param);
921312fec14SDave Airlie 
922312fec14SDave Airlie CBR_START2:
923312fec14SDave Airlie 	dllmin[0] = dllmin[1] = 0xff;
924312fec14SDave Airlie 	dllmax[0] = dllmax[1] = 0x0;
925312fec14SDave Airlie 	passcnt = 0;
926312fec14SDave Airlie 	for (dlli = 0; dlli < 76; dlli++) {
927312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
928312fec14SDave Airlie 		/* Wait DQSI latch phase calibration */
929312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0074, 0x00000010);
930312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0070, 0x00000003);
931312fec14SDave Airlie 		do {
932312fec14SDave Airlie 			data = mindwm(ast, 0x1E6E0070);
933312fec14SDave Airlie 		} while (!(data & 0x00001000));
934312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0070, 0x00000000);
935312fec14SDave Airlie 
936312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0074, CBR_SIZE2);
937312fec14SDave Airlie 		data = cbr_scan(ast);
938312fec14SDave Airlie 		if (data != 0) {
939312fec14SDave Airlie 			if (data & 0x1) {
940312fec14SDave Airlie 				if (dllmin[0] > dlli) {
941312fec14SDave Airlie 					dllmin[0] = dlli;
942312fec14SDave Airlie 				}
943312fec14SDave Airlie 				if (dllmax[0] < dlli) {
944312fec14SDave Airlie 					dllmax[0] = dlli;
945312fec14SDave Airlie 				}
946312fec14SDave Airlie 			}
947312fec14SDave Airlie 			if (data & 0x2) {
948312fec14SDave Airlie 				if (dllmin[1] > dlli) {
949312fec14SDave Airlie 					dllmin[1] = dlli;
950312fec14SDave Airlie 				}
951312fec14SDave Airlie 				if (dllmax[1] < dlli) {
952312fec14SDave Airlie 					dllmax[1] = dlli;
953312fec14SDave Airlie 				}
954312fec14SDave Airlie 			}
955312fec14SDave Airlie 			passcnt++;
956312fec14SDave Airlie 		} else if (passcnt >= CBR_THRESHOLD) {
957312fec14SDave Airlie 			break;
958312fec14SDave Airlie 		}
959312fec14SDave Airlie 	}
960312fec14SDave Airlie 	if (dllmax[0] == 0 || (dllmax[0]-dllmin[0]) < CBR_THRESHOLD) {
961312fec14SDave Airlie 		goto CBR_START2;
962312fec14SDave Airlie 	}
963312fec14SDave Airlie 	if (dllmax[1] == 0 || (dllmax[1]-dllmin[1]) < CBR_THRESHOLD) {
964312fec14SDave Airlie 		goto CBR_START2;
965312fec14SDave Airlie 	}
966312fec14SDave Airlie 	dlli  = (dllmin[1] + dllmax[1]) >> 1;
967312fec14SDave Airlie 	dlli <<= 8;
968312fec14SDave Airlie 	dlli += (dllmin[0] + dllmax[0]) >> 1;
969312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0068, (mindwm(ast, 0x1E6E0068) & 0xFFFF) | (dlli << 16));
970312fec14SDave Airlie 
971312fec14SDave Airlie 	data  = (mindwm(ast, 0x1E6E0080) >> 24) & 0x1F;
972312fec14SDave Airlie 	data2 = (mindwm(ast, 0x1E6E0018) & 0xff80ffff) | (data << 16);
973312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0018, data2);
974312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0024, 0x8001 | (data << 1) | (param->dll2_finetune_step << 8));
975312fec14SDave Airlie 
976312fec14SDave Airlie 	/* Wait DQSI latch phase calibration */
977312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0074, 0x00000010);
978312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0070, 0x00000003);
979312fec14SDave Airlie 	do {
980312fec14SDave Airlie 		data = mindwm(ast, 0x1E6E0070);
981312fec14SDave Airlie 	} while (!(data & 0x00001000));
982312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0070, 0x00000000);
983312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0070, 0x00000003);
984312fec14SDave Airlie 	do {
985312fec14SDave Airlie 		data = mindwm(ast, 0x1E6E0070);
986312fec14SDave Airlie 	} while (!(data & 0x00001000));
987312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0070, 0x00000000);
988312fec14SDave Airlie } /* CBRDLL2 */
989312fec14SDave Airlie 
990312fec14SDave Airlie static void get_ddr3_info(struct ast_private *ast, struct ast2300_dram_param *param)
991312fec14SDave Airlie {
992312fec14SDave Airlie 	u32 trap, trap_AC2, trap_MRS;
993312fec14SDave Airlie 
994312fec14SDave Airlie 	moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
995312fec14SDave Airlie 
996312fec14SDave Airlie 	/* Ger trap info */
997312fec14SDave Airlie 	trap = (mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
998312fec14SDave Airlie 	trap_AC2  = 0x00020000 + (trap << 16);
999312fec14SDave Airlie 	trap_AC2 |= 0x00300000 + ((trap & 0x2) << 19);
1000312fec14SDave Airlie 	trap_MRS  = 0x00000010 + (trap << 4);
1001312fec14SDave Airlie 	trap_MRS |= ((trap & 0x2) << 18);
1002312fec14SDave Airlie 
1003312fec14SDave Airlie 	param->reg_MADJ       = 0x00034C4C;
1004312fec14SDave Airlie 	param->reg_SADJ       = 0x00001800;
1005312fec14SDave Airlie 	param->reg_DRV        = 0x000000F0;
1006312fec14SDave Airlie 	param->reg_PERIOD     = param->dram_freq;
1007312fec14SDave Airlie 	param->rodt           = 0;
1008312fec14SDave Airlie 
1009312fec14SDave Airlie 	switch (param->dram_freq) {
1010312fec14SDave Airlie 	case 336:
1011312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x0190);
1012312fec14SDave Airlie 		param->wodt          = 0;
1013312fec14SDave Airlie 		param->reg_AC1       = 0x22202725;
1014312fec14SDave Airlie 		param->reg_AC2       = 0xAA007613 | trap_AC2;
1015312fec14SDave Airlie 		param->reg_DQSIC     = 0x000000BA;
1016312fec14SDave Airlie 		param->reg_MRS       = 0x04001400 | trap_MRS;
1017312fec14SDave Airlie 		param->reg_EMRS      = 0x00000000;
1018312fec14SDave Airlie 		param->reg_IOZ       = 0x00000034;
1019312fec14SDave Airlie 		param->reg_DQIDLY    = 0x00000074;
1020312fec14SDave Airlie 		param->reg_FREQ      = 0x00004DC0;
1021312fec14SDave Airlie 		param->madj_max      = 96;
1022312fec14SDave Airlie 		param->dll2_finetune_step = 3;
1023312fec14SDave Airlie 		break;
1024312fec14SDave Airlie 	default:
1025312fec14SDave Airlie 	case 396:
1026312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x03F1);
1027312fec14SDave Airlie 		param->wodt          = 1;
1028312fec14SDave Airlie 		param->reg_AC1       = 0x33302825;
1029312fec14SDave Airlie 		param->reg_AC2       = 0xCC009617 | trap_AC2;
1030312fec14SDave Airlie 		param->reg_DQSIC     = 0x000000E2;
1031312fec14SDave Airlie 		param->reg_MRS       = 0x04001600 | trap_MRS;
1032312fec14SDave Airlie 		param->reg_EMRS      = 0x00000000;
1033312fec14SDave Airlie 		param->reg_IOZ       = 0x00000034;
1034312fec14SDave Airlie 		param->reg_DRV       = 0x000000FA;
1035312fec14SDave Airlie 		param->reg_DQIDLY    = 0x00000089;
1036312fec14SDave Airlie 		param->reg_FREQ      = 0x000050C0;
1037312fec14SDave Airlie 		param->madj_max      = 96;
1038312fec14SDave Airlie 		param->dll2_finetune_step = 4;
1039312fec14SDave Airlie 
1040312fec14SDave Airlie 		switch (param->dram_chipid) {
1041312fec14SDave Airlie 		default:
1042312fec14SDave Airlie 		case AST_DRAM_512Mx16:
1043312fec14SDave Airlie 		case AST_DRAM_1Gx16:
1044312fec14SDave Airlie 			param->reg_AC2   = 0xCC009617 | trap_AC2;
1045312fec14SDave Airlie 			break;
1046312fec14SDave Airlie 		case AST_DRAM_2Gx16:
1047312fec14SDave Airlie 			param->reg_AC2   = 0xCC009622 | trap_AC2;
1048312fec14SDave Airlie 			break;
1049312fec14SDave Airlie 		case AST_DRAM_4Gx16:
1050312fec14SDave Airlie 			param->reg_AC2   = 0xCC00963F | trap_AC2;
1051312fec14SDave Airlie 			break;
1052312fec14SDave Airlie 		}
1053312fec14SDave Airlie 		break;
1054312fec14SDave Airlie 
1055312fec14SDave Airlie 	case 408:
1056312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x01F0);
1057312fec14SDave Airlie 		param->wodt          = 1;
1058312fec14SDave Airlie 		param->reg_AC1       = 0x33302825;
1059312fec14SDave Airlie 		param->reg_AC2       = 0xCC009617 | trap_AC2;
1060312fec14SDave Airlie 		param->reg_DQSIC     = 0x000000E2;
1061312fec14SDave Airlie 		param->reg_MRS       = 0x04001600 | trap_MRS;
1062312fec14SDave Airlie 		param->reg_EMRS      = 0x00000000;
1063312fec14SDave Airlie 		param->reg_IOZ       = 0x00000034;
1064312fec14SDave Airlie 		param->reg_DRV       = 0x000000FA;
1065312fec14SDave Airlie 		param->reg_DQIDLY    = 0x00000089;
1066312fec14SDave Airlie 		param->reg_FREQ      = 0x000050C0;
1067312fec14SDave Airlie 		param->madj_max      = 96;
1068312fec14SDave Airlie 		param->dll2_finetune_step = 4;
1069312fec14SDave Airlie 
1070312fec14SDave Airlie 		switch (param->dram_chipid) {
1071312fec14SDave Airlie 		default:
1072312fec14SDave Airlie 		case AST_DRAM_512Mx16:
1073312fec14SDave Airlie 		case AST_DRAM_1Gx16:
1074312fec14SDave Airlie 			param->reg_AC2   = 0xCC009617 | trap_AC2;
1075312fec14SDave Airlie 			break;
1076312fec14SDave Airlie 		case AST_DRAM_2Gx16:
1077312fec14SDave Airlie 			param->reg_AC2   = 0xCC009622 | trap_AC2;
1078312fec14SDave Airlie 			break;
1079312fec14SDave Airlie 		case AST_DRAM_4Gx16:
1080312fec14SDave Airlie 			param->reg_AC2   = 0xCC00963F | trap_AC2;
1081312fec14SDave Airlie 			break;
1082312fec14SDave Airlie 		}
1083312fec14SDave Airlie 
1084312fec14SDave Airlie 		break;
1085312fec14SDave Airlie 	case 456:
1086312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x0230);
1087312fec14SDave Airlie 		param->wodt          = 0;
1088312fec14SDave Airlie 		param->reg_AC1       = 0x33302926;
1089312fec14SDave Airlie 		param->reg_AC2       = 0xCD44961A;
1090312fec14SDave Airlie 		param->reg_DQSIC     = 0x000000FC;
1091312fec14SDave Airlie 		param->reg_MRS       = 0x00081830;
1092312fec14SDave Airlie 		param->reg_EMRS      = 0x00000000;
1093312fec14SDave Airlie 		param->reg_IOZ       = 0x00000045;
1094312fec14SDave Airlie 		param->reg_DQIDLY    = 0x00000097;
1095312fec14SDave Airlie 		param->reg_FREQ      = 0x000052C0;
1096312fec14SDave Airlie 		param->madj_max      = 88;
1097312fec14SDave Airlie 		param->dll2_finetune_step = 4;
1098312fec14SDave Airlie 		break;
1099312fec14SDave Airlie 	case 504:
1100312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x0270);
1101312fec14SDave Airlie 		param->wodt          = 1;
1102312fec14SDave Airlie 		param->reg_AC1       = 0x33302926;
1103312fec14SDave Airlie 		param->reg_AC2       = 0xDE44A61D;
1104312fec14SDave Airlie 		param->reg_DQSIC     = 0x00000117;
1105312fec14SDave Airlie 		param->reg_MRS       = 0x00081A30;
1106312fec14SDave Airlie 		param->reg_EMRS      = 0x00000000;
1107312fec14SDave Airlie 		param->reg_IOZ       = 0x070000BB;
1108312fec14SDave Airlie 		param->reg_DQIDLY    = 0x000000A0;
1109312fec14SDave Airlie 		param->reg_FREQ      = 0x000054C0;
1110312fec14SDave Airlie 		param->madj_max      = 79;
1111312fec14SDave Airlie 		param->dll2_finetune_step = 4;
1112312fec14SDave Airlie 		break;
1113312fec14SDave Airlie 	case 528:
1114312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x0290);
1115312fec14SDave Airlie 		param->wodt          = 1;
1116312fec14SDave Airlie 		param->rodt          = 1;
1117312fec14SDave Airlie 		param->reg_AC1       = 0x33302926;
1118312fec14SDave Airlie 		param->reg_AC2       = 0xEF44B61E;
1119312fec14SDave Airlie 		param->reg_DQSIC     = 0x00000125;
1120312fec14SDave Airlie 		param->reg_MRS       = 0x00081A30;
1121312fec14SDave Airlie 		param->reg_EMRS      = 0x00000040;
1122312fec14SDave Airlie 		param->reg_DRV       = 0x000000F5;
1123312fec14SDave Airlie 		param->reg_IOZ       = 0x00000023;
1124312fec14SDave Airlie 		param->reg_DQIDLY    = 0x00000088;
1125312fec14SDave Airlie 		param->reg_FREQ      = 0x000055C0;
1126312fec14SDave Airlie 		param->madj_max      = 76;
1127312fec14SDave Airlie 		param->dll2_finetune_step = 3;
1128312fec14SDave Airlie 		break;
1129312fec14SDave Airlie 	case 576:
1130312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x0140);
1131312fec14SDave Airlie 		param->reg_MADJ      = 0x00136868;
1132312fec14SDave Airlie 		param->reg_SADJ      = 0x00004534;
1133312fec14SDave Airlie 		param->wodt          = 1;
1134312fec14SDave Airlie 		param->rodt          = 1;
1135312fec14SDave Airlie 		param->reg_AC1       = 0x33302A37;
1136312fec14SDave Airlie 		param->reg_AC2       = 0xEF56B61E;
1137312fec14SDave Airlie 		param->reg_DQSIC     = 0x0000013F;
1138312fec14SDave Airlie 		param->reg_MRS       = 0x00101A50;
1139312fec14SDave Airlie 		param->reg_EMRS      = 0x00000040;
1140312fec14SDave Airlie 		param->reg_DRV       = 0x000000FA;
1141312fec14SDave Airlie 		param->reg_IOZ       = 0x00000023;
1142312fec14SDave Airlie 		param->reg_DQIDLY    = 0x00000078;
1143312fec14SDave Airlie 		param->reg_FREQ      = 0x000057C0;
1144312fec14SDave Airlie 		param->madj_max      = 136;
1145312fec14SDave Airlie 		param->dll2_finetune_step = 3;
1146312fec14SDave Airlie 		break;
1147312fec14SDave Airlie 	case 600:
1148312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x02E1);
1149312fec14SDave Airlie 		param->reg_MADJ      = 0x00136868;
1150312fec14SDave Airlie 		param->reg_SADJ      = 0x00004534;
1151312fec14SDave Airlie 		param->wodt          = 1;
1152312fec14SDave Airlie 		param->rodt          = 1;
1153312fec14SDave Airlie 		param->reg_AC1       = 0x32302A37;
1154312fec14SDave Airlie 		param->reg_AC2       = 0xDF56B61F;
1155312fec14SDave Airlie 		param->reg_DQSIC     = 0x0000014D;
1156312fec14SDave Airlie 		param->reg_MRS       = 0x00101A50;
1157312fec14SDave Airlie 		param->reg_EMRS      = 0x00000004;
1158312fec14SDave Airlie 		param->reg_DRV       = 0x000000F5;
1159312fec14SDave Airlie 		param->reg_IOZ       = 0x00000023;
1160312fec14SDave Airlie 		param->reg_DQIDLY    = 0x00000078;
1161312fec14SDave Airlie 		param->reg_FREQ      = 0x000058C0;
1162312fec14SDave Airlie 		param->madj_max      = 132;
1163312fec14SDave Airlie 		param->dll2_finetune_step = 3;
1164312fec14SDave Airlie 		break;
1165312fec14SDave Airlie 	case 624:
1166312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x0160);
1167312fec14SDave Airlie 		param->reg_MADJ      = 0x00136868;
1168312fec14SDave Airlie 		param->reg_SADJ      = 0x00004534;
1169312fec14SDave Airlie 		param->wodt          = 1;
1170312fec14SDave Airlie 		param->rodt          = 1;
1171312fec14SDave Airlie 		param->reg_AC1       = 0x32302A37;
1172312fec14SDave Airlie 		param->reg_AC2       = 0xEF56B621;
1173312fec14SDave Airlie 		param->reg_DQSIC     = 0x0000015A;
1174312fec14SDave Airlie 		param->reg_MRS       = 0x02101A50;
1175312fec14SDave Airlie 		param->reg_EMRS      = 0x00000004;
1176312fec14SDave Airlie 		param->reg_DRV       = 0x000000F5;
1177312fec14SDave Airlie 		param->reg_IOZ       = 0x00000034;
1178312fec14SDave Airlie 		param->reg_DQIDLY    = 0x00000078;
1179312fec14SDave Airlie 		param->reg_FREQ      = 0x000059C0;
1180312fec14SDave Airlie 		param->madj_max      = 128;
1181312fec14SDave Airlie 		param->dll2_finetune_step = 3;
1182312fec14SDave Airlie 		break;
1183312fec14SDave Airlie 	} /* switch freq */
1184312fec14SDave Airlie 
1185312fec14SDave Airlie 	switch (param->dram_chipid) {
1186312fec14SDave Airlie 	case AST_DRAM_512Mx16:
1187312fec14SDave Airlie 		param->dram_config = 0x130;
1188312fec14SDave Airlie 		break;
1189312fec14SDave Airlie 	default:
1190312fec14SDave Airlie 	case AST_DRAM_1Gx16:
1191312fec14SDave Airlie 		param->dram_config = 0x131;
1192312fec14SDave Airlie 		break;
1193312fec14SDave Airlie 	case AST_DRAM_2Gx16:
1194312fec14SDave Airlie 		param->dram_config = 0x132;
1195312fec14SDave Airlie 		break;
1196312fec14SDave Airlie 	case AST_DRAM_4Gx16:
1197312fec14SDave Airlie 		param->dram_config = 0x133;
1198312fec14SDave Airlie 		break;
1199312fec14SDave Airlie 	}; /* switch size */
1200312fec14SDave Airlie 
1201312fec14SDave Airlie 	switch (param->vram_size) {
1202312fec14SDave Airlie 	default:
1203312fec14SDave Airlie 	case AST_VIDMEM_SIZE_8M:
1204312fec14SDave Airlie 		param->dram_config |= 0x00;
1205312fec14SDave Airlie 		break;
1206312fec14SDave Airlie 	case AST_VIDMEM_SIZE_16M:
1207312fec14SDave Airlie 		param->dram_config |= 0x04;
1208312fec14SDave Airlie 		break;
1209312fec14SDave Airlie 	case AST_VIDMEM_SIZE_32M:
1210312fec14SDave Airlie 		param->dram_config |= 0x08;
1211312fec14SDave Airlie 		break;
1212312fec14SDave Airlie 	case AST_VIDMEM_SIZE_64M:
1213312fec14SDave Airlie 		param->dram_config |= 0x0c;
1214312fec14SDave Airlie 		break;
1215312fec14SDave Airlie 	}
1216312fec14SDave Airlie 
1217312fec14SDave Airlie }
1218312fec14SDave Airlie 
1219312fec14SDave Airlie static void ddr3_init(struct ast_private *ast, struct ast2300_dram_param *param)
1220312fec14SDave Airlie {
1221312fec14SDave Airlie 	u32 data, data2;
1222312fec14SDave Airlie 
1223312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0000, 0xFC600309);
1224312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0018, 0x00000100);
1225312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0024, 0x00000000);
1226312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0034, 0x00000000);
1227312fec14SDave Airlie 	udelay(10);
1228312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
1229312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
1230312fec14SDave Airlie 	udelay(10);
1231312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
1232312fec14SDave Airlie 	udelay(10);
1233312fec14SDave Airlie 
1234312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0004, param->dram_config);
1235312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0008, 0x90040f);
1236312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0010, param->reg_AC1);
1237312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0014, param->reg_AC2);
1238312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
1239312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0080, 0x00000000);
1240312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0084, 0x00000000);
1241312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
1242312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0018, 0x4040A170);
1243312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0018, 0x20402370);
1244312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0038, 0x00000000);
1245312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0040, 0xFF444444);
1246312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0044, 0x22222222);
1247312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0048, 0x22222222);
1248312fec14SDave Airlie 	moutdwm(ast, 0x1E6E004C, 0x00000002);
1249312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0050, 0x80000000);
1250312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0050, 0x00000000);
1251312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0054, 0);
1252312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0060, param->reg_DRV);
1253312fec14SDave Airlie 	moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
1254312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0070, 0x00000000);
1255312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0074, 0x00000000);
1256312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0078, 0x00000000);
1257312fec14SDave Airlie 	moutdwm(ast, 0x1E6E007C, 0x00000000);
1258312fec14SDave Airlie 	/* Wait MCLK2X lock to MCLK */
1259312fec14SDave Airlie 	do {
1260312fec14SDave Airlie 		data = mindwm(ast, 0x1E6E001C);
1261312fec14SDave Airlie 	} while (!(data & 0x08000000));
1262312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0034, 0x00000001);
1263312fec14SDave Airlie 	moutdwm(ast, 0x1E6E000C, 0x00005C04);
1264312fec14SDave Airlie 	udelay(10);
1265312fec14SDave Airlie 	moutdwm(ast, 0x1E6E000C, 0x00000000);
1266312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0034, 0x00000000);
1267312fec14SDave Airlie 	data = mindwm(ast, 0x1E6E001C);
1268312fec14SDave Airlie 	data = (data >> 8) & 0xff;
1269312fec14SDave Airlie 	while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
1270312fec14SDave Airlie 		data2 = (mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
1271312fec14SDave Airlie 		if ((data2 & 0xff) > param->madj_max) {
1272312fec14SDave Airlie 			break;
1273312fec14SDave Airlie 		}
1274312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0064, data2);
1275312fec14SDave Airlie 		if (data2 & 0x00100000) {
1276312fec14SDave Airlie 			data2 = ((data2 & 0xff) >> 3) + 3;
1277312fec14SDave Airlie 		} else {
1278312fec14SDave Airlie 			data2 = ((data2 & 0xff) >> 2) + 5;
1279312fec14SDave Airlie 		}
1280312fec14SDave Airlie 		data = mindwm(ast, 0x1E6E0068) & 0xffff00ff;
1281312fec14SDave Airlie 		data2 += data & 0xff;
1282312fec14SDave Airlie 		data = data | (data2 << 8);
1283312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0068, data);
1284312fec14SDave Airlie 		udelay(10);
1285312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0064, mindwm(ast, 0x1E6E0064) | 0xC0000);
1286312fec14SDave Airlie 		udelay(10);
1287312fec14SDave Airlie 		data = mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
1288312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0018, data);
1289312fec14SDave Airlie 		data = data | 0x200;
1290312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0018, data);
1291312fec14SDave Airlie 		do {
1292312fec14SDave Airlie 			data = mindwm(ast, 0x1E6E001C);
1293312fec14SDave Airlie 		} while (!(data & 0x08000000));
1294312fec14SDave Airlie 
1295312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0034, 0x00000001);
1296312fec14SDave Airlie 		moutdwm(ast, 0x1E6E000C, 0x00005C04);
1297312fec14SDave Airlie 		udelay(10);
1298312fec14SDave Airlie 		moutdwm(ast, 0x1E6E000C, 0x00000000);
1299312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0034, 0x00000000);
1300312fec14SDave Airlie 		data = mindwm(ast, 0x1E6E001C);
1301312fec14SDave Airlie 		data = (data >> 8) & 0xff;
1302312fec14SDave Airlie 	}
1303312fec14SDave Airlie 	data = mindwm(ast, 0x1E6E0018) | 0xC00;
1304312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0018, data);
1305312fec14SDave Airlie 
1306312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0034, 0x00000001);
1307312fec14SDave Airlie 	moutdwm(ast, 0x1E6E000C, 0x00000040);
1308312fec14SDave Airlie 	udelay(50);
1309312fec14SDave Airlie 	/* Mode Register Setting */
1310312fec14SDave Airlie 	moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
1311312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1312312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0028, 0x00000005);
1313312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0028, 0x00000007);
1314312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0028, 0x00000003);
1315312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0028, 0x00000001);
1316312fec14SDave Airlie 	moutdwm(ast, 0x1E6E002C, param->reg_MRS);
1317312fec14SDave Airlie 	moutdwm(ast, 0x1E6E000C, 0x00005C08);
1318312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0028, 0x00000001);
1319312fec14SDave Airlie 
1320312fec14SDave Airlie 	moutdwm(ast, 0x1E6E000C, 0x7FFF5C01);
1321312fec14SDave Airlie 	data = 0;
1322312fec14SDave Airlie 	if (param->wodt) {
1323312fec14SDave Airlie 		data = 0x300;
1324312fec14SDave Airlie 	}
1325312fec14SDave Airlie 	if (param->rodt) {
1326312fec14SDave Airlie 		data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1327312fec14SDave Airlie 	}
1328312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0034, data | 0x3);
1329312fec14SDave Airlie 
1330312fec14SDave Airlie 	/* Wait DQI delay lock */
1331312fec14SDave Airlie 	do {
1332312fec14SDave Airlie 		data = mindwm(ast, 0x1E6E0080);
1333312fec14SDave Airlie 	} while (!(data & 0x40000000));
1334312fec14SDave Airlie 	/* Wait DQSI delay lock */
1335312fec14SDave Airlie 	do {
1336312fec14SDave Airlie 		data = mindwm(ast, 0x1E6E0020);
1337312fec14SDave Airlie 	} while (!(data & 0x00000800));
1338312fec14SDave Airlie 	/* Calibrate the DQSI delay */
1339312fec14SDave Airlie 	cbr_dll2(ast, param);
1340312fec14SDave Airlie 
1341312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1342312fec14SDave Airlie 	/* ECC Memory Initialization */
1343312fec14SDave Airlie #ifdef ECC
1344312fec14SDave Airlie 	moutdwm(ast, 0x1E6E007C, 0x00000000);
1345312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0070, 0x221);
1346312fec14SDave Airlie 	do {
1347312fec14SDave Airlie 		data = mindwm(ast, 0x1E6E0070);
1348312fec14SDave Airlie 	} while (!(data & 0x00001000));
1349312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0070, 0x00000000);
1350312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0050, 0x80000000);
1351312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0050, 0x00000000);
1352312fec14SDave Airlie #endif
1353312fec14SDave Airlie 
1354312fec14SDave Airlie 
1355312fec14SDave Airlie }
1356312fec14SDave Airlie 
1357312fec14SDave Airlie static void get_ddr2_info(struct ast_private *ast, struct ast2300_dram_param *param)
1358312fec14SDave Airlie {
1359312fec14SDave Airlie 	u32 trap, trap_AC2, trap_MRS;
1360312fec14SDave Airlie 
1361312fec14SDave Airlie 	moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
1362312fec14SDave Airlie 
1363312fec14SDave Airlie 	/* Ger trap info */
1364312fec14SDave Airlie 	trap = (mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
1365312fec14SDave Airlie 	trap_AC2  = (trap << 20) | (trap << 16);
1366312fec14SDave Airlie 	trap_AC2 += 0x00110000;
1367312fec14SDave Airlie 	trap_MRS  = 0x00000040 | (trap << 4);
1368312fec14SDave Airlie 
1369312fec14SDave Airlie 
1370312fec14SDave Airlie 	param->reg_MADJ       = 0x00034C4C;
1371312fec14SDave Airlie 	param->reg_SADJ       = 0x00001800;
1372312fec14SDave Airlie 	param->reg_DRV        = 0x000000F0;
1373312fec14SDave Airlie 	param->reg_PERIOD     = param->dram_freq;
1374312fec14SDave Airlie 	param->rodt           = 0;
1375312fec14SDave Airlie 
1376312fec14SDave Airlie 	switch (param->dram_freq) {
1377312fec14SDave Airlie 	case 264:
1378312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x0130);
1379312fec14SDave Airlie 		param->wodt          = 0;
1380312fec14SDave Airlie 		param->reg_AC1       = 0x11101513;
1381312fec14SDave Airlie 		param->reg_AC2       = 0x78117011;
1382312fec14SDave Airlie 		param->reg_DQSIC     = 0x00000092;
1383312fec14SDave Airlie 		param->reg_MRS       = 0x00000842;
1384312fec14SDave Airlie 		param->reg_EMRS      = 0x00000000;
1385312fec14SDave Airlie 		param->reg_DRV       = 0x000000F0;
1386312fec14SDave Airlie 		param->reg_IOZ       = 0x00000034;
1387312fec14SDave Airlie 		param->reg_DQIDLY    = 0x0000005A;
1388312fec14SDave Airlie 		param->reg_FREQ      = 0x00004AC0;
1389312fec14SDave Airlie 		param->madj_max      = 138;
1390312fec14SDave Airlie 		param->dll2_finetune_step = 3;
1391312fec14SDave Airlie 		break;
1392312fec14SDave Airlie 	case 336:
1393312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x0190);
1394312fec14SDave Airlie 		param->wodt          = 1;
1395312fec14SDave Airlie 		param->reg_AC1       = 0x22202613;
1396312fec14SDave Airlie 		param->reg_AC2       = 0xAA009016 | trap_AC2;
1397312fec14SDave Airlie 		param->reg_DQSIC     = 0x000000BA;
1398312fec14SDave Airlie 		param->reg_MRS       = 0x00000A02 | trap_MRS;
1399312fec14SDave Airlie 		param->reg_EMRS      = 0x00000040;
1400312fec14SDave Airlie 		param->reg_DRV       = 0x000000FA;
1401312fec14SDave Airlie 		param->reg_IOZ       = 0x00000034;
1402312fec14SDave Airlie 		param->reg_DQIDLY    = 0x00000074;
1403312fec14SDave Airlie 		param->reg_FREQ      = 0x00004DC0;
1404312fec14SDave Airlie 		param->madj_max      = 96;
1405312fec14SDave Airlie 		param->dll2_finetune_step = 3;
1406312fec14SDave Airlie 		break;
1407312fec14SDave Airlie 	default:
1408312fec14SDave Airlie 	case 396:
1409312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x03F1);
1410312fec14SDave Airlie 		param->wodt          = 1;
1411312fec14SDave Airlie 		param->rodt          = 0;
1412312fec14SDave Airlie 		param->reg_AC1       = 0x33302714;
1413312fec14SDave Airlie 		param->reg_AC2       = 0xCC00B01B | trap_AC2;
1414312fec14SDave Airlie 		param->reg_DQSIC     = 0x000000E2;
1415312fec14SDave Airlie 		param->reg_MRS       = 0x00000C02 | trap_MRS;
1416312fec14SDave Airlie 		param->reg_EMRS      = 0x00000040;
1417312fec14SDave Airlie 		param->reg_DRV       = 0x000000FA;
1418312fec14SDave Airlie 		param->reg_IOZ       = 0x00000034;
1419312fec14SDave Airlie 		param->reg_DQIDLY    = 0x00000089;
1420312fec14SDave Airlie 		param->reg_FREQ      = 0x000050C0;
1421312fec14SDave Airlie 		param->madj_max      = 96;
1422312fec14SDave Airlie 		param->dll2_finetune_step = 4;
1423312fec14SDave Airlie 
1424312fec14SDave Airlie 		switch (param->dram_chipid) {
1425312fec14SDave Airlie 		case AST_DRAM_512Mx16:
1426312fec14SDave Airlie 			param->reg_AC2   = 0xCC00B016 | trap_AC2;
1427312fec14SDave Airlie 			break;
1428312fec14SDave Airlie 		default:
1429312fec14SDave Airlie 		case AST_DRAM_1Gx16:
1430312fec14SDave Airlie 			param->reg_AC2   = 0xCC00B01B | trap_AC2;
1431312fec14SDave Airlie 			break;
1432312fec14SDave Airlie 		case AST_DRAM_2Gx16:
1433312fec14SDave Airlie 			param->reg_AC2   = 0xCC00B02B | trap_AC2;
1434312fec14SDave Airlie 			break;
1435312fec14SDave Airlie 		case AST_DRAM_4Gx16:
1436312fec14SDave Airlie 			param->reg_AC2   = 0xCC00B03F | trap_AC2;
1437312fec14SDave Airlie 			break;
1438312fec14SDave Airlie 		}
1439312fec14SDave Airlie 
1440312fec14SDave Airlie 		break;
1441312fec14SDave Airlie 
1442312fec14SDave Airlie 	case 408:
1443312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x01F0);
1444312fec14SDave Airlie 		param->wodt          = 1;
1445312fec14SDave Airlie 		param->rodt          = 0;
1446312fec14SDave Airlie 		param->reg_AC1       = 0x33302714;
1447312fec14SDave Airlie 		param->reg_AC2       = 0xCC00B01B | trap_AC2;
1448312fec14SDave Airlie 		param->reg_DQSIC     = 0x000000E2;
1449312fec14SDave Airlie 		param->reg_MRS       = 0x00000C02 | trap_MRS;
1450312fec14SDave Airlie 		param->reg_EMRS      = 0x00000040;
1451312fec14SDave Airlie 		param->reg_DRV       = 0x000000FA;
1452312fec14SDave Airlie 		param->reg_IOZ       = 0x00000034;
1453312fec14SDave Airlie 		param->reg_DQIDLY    = 0x00000089;
1454312fec14SDave Airlie 		param->reg_FREQ      = 0x000050C0;
1455312fec14SDave Airlie 		param->madj_max      = 96;
1456312fec14SDave Airlie 		param->dll2_finetune_step = 4;
1457312fec14SDave Airlie 
1458312fec14SDave Airlie 		switch (param->dram_chipid) {
1459312fec14SDave Airlie 		case AST_DRAM_512Mx16:
1460312fec14SDave Airlie 			param->reg_AC2   = 0xCC00B016 | trap_AC2;
1461312fec14SDave Airlie 			break;
1462312fec14SDave Airlie 		default:
1463312fec14SDave Airlie 		case AST_DRAM_1Gx16:
1464312fec14SDave Airlie 			param->reg_AC2   = 0xCC00B01B | trap_AC2;
1465312fec14SDave Airlie 			break;
1466312fec14SDave Airlie 		case AST_DRAM_2Gx16:
1467312fec14SDave Airlie 			param->reg_AC2   = 0xCC00B02B | trap_AC2;
1468312fec14SDave Airlie 			break;
1469312fec14SDave Airlie 		case AST_DRAM_4Gx16:
1470312fec14SDave Airlie 			param->reg_AC2   = 0xCC00B03F | trap_AC2;
1471312fec14SDave Airlie 			break;
1472312fec14SDave Airlie 		}
1473312fec14SDave Airlie 
1474312fec14SDave Airlie 		break;
1475312fec14SDave Airlie 	case 456:
1476312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x0230);
1477312fec14SDave Airlie 		param->wodt          = 0;
1478312fec14SDave Airlie 		param->reg_AC1       = 0x33302815;
1479312fec14SDave Airlie 		param->reg_AC2       = 0xCD44B01E;
1480312fec14SDave Airlie 		param->reg_DQSIC     = 0x000000FC;
1481312fec14SDave Airlie 		param->reg_MRS       = 0x00000E72;
1482312fec14SDave Airlie 		param->reg_EMRS      = 0x00000000;
1483312fec14SDave Airlie 		param->reg_DRV       = 0x00000000;
1484312fec14SDave Airlie 		param->reg_IOZ       = 0x00000034;
1485312fec14SDave Airlie 		param->reg_DQIDLY    = 0x00000097;
1486312fec14SDave Airlie 		param->reg_FREQ      = 0x000052C0;
1487312fec14SDave Airlie 		param->madj_max      = 88;
1488312fec14SDave Airlie 		param->dll2_finetune_step = 3;
1489312fec14SDave Airlie 		break;
1490312fec14SDave Airlie 	case 504:
1491312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x0261);
1492312fec14SDave Airlie 		param->wodt          = 1;
1493312fec14SDave Airlie 		param->rodt          = 1;
1494312fec14SDave Airlie 		param->reg_AC1       = 0x33302815;
1495312fec14SDave Airlie 		param->reg_AC2       = 0xDE44C022;
1496312fec14SDave Airlie 		param->reg_DQSIC     = 0x00000117;
1497312fec14SDave Airlie 		param->reg_MRS       = 0x00000E72;
1498312fec14SDave Airlie 		param->reg_EMRS      = 0x00000040;
1499312fec14SDave Airlie 		param->reg_DRV       = 0x0000000A;
1500312fec14SDave Airlie 		param->reg_IOZ       = 0x00000045;
1501312fec14SDave Airlie 		param->reg_DQIDLY    = 0x000000A0;
1502312fec14SDave Airlie 		param->reg_FREQ      = 0x000054C0;
1503312fec14SDave Airlie 		param->madj_max      = 79;
1504312fec14SDave Airlie 		param->dll2_finetune_step = 3;
1505312fec14SDave Airlie 		break;
1506312fec14SDave Airlie 	case 528:
1507312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x0120);
1508312fec14SDave Airlie 		param->wodt          = 1;
1509312fec14SDave Airlie 		param->rodt          = 1;
1510312fec14SDave Airlie 		param->reg_AC1       = 0x33302815;
1511312fec14SDave Airlie 		param->reg_AC2       = 0xEF44D024;
1512312fec14SDave Airlie 		param->reg_DQSIC     = 0x00000125;
1513312fec14SDave Airlie 		param->reg_MRS       = 0x00000E72;
1514312fec14SDave Airlie 		param->reg_EMRS      = 0x00000004;
1515312fec14SDave Airlie 		param->reg_DRV       = 0x000000F9;
1516312fec14SDave Airlie 		param->reg_IOZ       = 0x00000045;
1517312fec14SDave Airlie 		param->reg_DQIDLY    = 0x000000A7;
1518312fec14SDave Airlie 		param->reg_FREQ      = 0x000055C0;
1519312fec14SDave Airlie 		param->madj_max      = 76;
1520312fec14SDave Airlie 		param->dll2_finetune_step = 3;
1521312fec14SDave Airlie 		break;
1522312fec14SDave Airlie 	case 552:
1523312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x02A1);
1524312fec14SDave Airlie 		param->wodt          = 1;
1525312fec14SDave Airlie 		param->rodt          = 1;
1526312fec14SDave Airlie 		param->reg_AC1       = 0x43402915;
1527312fec14SDave Airlie 		param->reg_AC2       = 0xFF44E025;
1528312fec14SDave Airlie 		param->reg_DQSIC     = 0x00000132;
1529312fec14SDave Airlie 		param->reg_MRS       = 0x00000E72;
1530312fec14SDave Airlie 		param->reg_EMRS      = 0x00000040;
1531312fec14SDave Airlie 		param->reg_DRV       = 0x0000000A;
1532312fec14SDave Airlie 		param->reg_IOZ       = 0x00000045;
1533312fec14SDave Airlie 		param->reg_DQIDLY    = 0x000000AD;
1534312fec14SDave Airlie 		param->reg_FREQ      = 0x000056C0;
1535312fec14SDave Airlie 		param->madj_max      = 76;
1536312fec14SDave Airlie 		param->dll2_finetune_step = 3;
1537312fec14SDave Airlie 		break;
1538312fec14SDave Airlie 	case 576:
1539312fec14SDave Airlie 		moutdwm(ast, 0x1E6E2020, 0x0140);
1540312fec14SDave Airlie 		param->wodt          = 1;
1541312fec14SDave Airlie 		param->rodt          = 1;
1542312fec14SDave Airlie 		param->reg_AC1       = 0x43402915;
1543312fec14SDave Airlie 		param->reg_AC2       = 0xFF44E027;
1544312fec14SDave Airlie 		param->reg_DQSIC     = 0x0000013F;
1545312fec14SDave Airlie 		param->reg_MRS       = 0x00000E72;
1546312fec14SDave Airlie 		param->reg_EMRS      = 0x00000004;
1547312fec14SDave Airlie 		param->reg_DRV       = 0x000000F5;
1548312fec14SDave Airlie 		param->reg_IOZ       = 0x00000045;
1549312fec14SDave Airlie 		param->reg_DQIDLY    = 0x000000B3;
1550312fec14SDave Airlie 		param->reg_FREQ      = 0x000057C0;
1551312fec14SDave Airlie 		param->madj_max      = 76;
1552312fec14SDave Airlie 		param->dll2_finetune_step = 3;
1553312fec14SDave Airlie 		break;
1554312fec14SDave Airlie 	}
1555312fec14SDave Airlie 
1556312fec14SDave Airlie 	switch (param->dram_chipid) {
1557312fec14SDave Airlie 	case AST_DRAM_512Mx16:
1558312fec14SDave Airlie 		param->dram_config = 0x100;
1559312fec14SDave Airlie 		break;
1560312fec14SDave Airlie 	default:
1561312fec14SDave Airlie 	case AST_DRAM_1Gx16:
1562312fec14SDave Airlie 		param->dram_config = 0x121;
1563312fec14SDave Airlie 		break;
1564312fec14SDave Airlie 	case AST_DRAM_2Gx16:
1565312fec14SDave Airlie 		param->dram_config = 0x122;
1566312fec14SDave Airlie 		break;
1567312fec14SDave Airlie 	case AST_DRAM_4Gx16:
1568312fec14SDave Airlie 		param->dram_config = 0x123;
1569312fec14SDave Airlie 		break;
1570312fec14SDave Airlie 	}; /* switch size */
1571312fec14SDave Airlie 
1572312fec14SDave Airlie 	switch (param->vram_size) {
1573312fec14SDave Airlie 	default:
1574312fec14SDave Airlie 	case AST_VIDMEM_SIZE_8M:
1575312fec14SDave Airlie 		param->dram_config |= 0x00;
1576312fec14SDave Airlie 		break;
1577312fec14SDave Airlie 	case AST_VIDMEM_SIZE_16M:
1578312fec14SDave Airlie 		param->dram_config |= 0x04;
1579312fec14SDave Airlie 		break;
1580312fec14SDave Airlie 	case AST_VIDMEM_SIZE_32M:
1581312fec14SDave Airlie 		param->dram_config |= 0x08;
1582312fec14SDave Airlie 		break;
1583312fec14SDave Airlie 	case AST_VIDMEM_SIZE_64M:
1584312fec14SDave Airlie 		param->dram_config |= 0x0c;
1585312fec14SDave Airlie 		break;
1586312fec14SDave Airlie 	}
1587312fec14SDave Airlie }
1588312fec14SDave Airlie 
1589312fec14SDave Airlie static void ddr2_init(struct ast_private *ast, struct ast2300_dram_param *param)
1590312fec14SDave Airlie {
1591312fec14SDave Airlie 	u32 data, data2;
1592312fec14SDave Airlie 
1593312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0000, 0xFC600309);
1594312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0018, 0x00000100);
1595312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0024, 0x00000000);
1596312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
1597312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
1598312fec14SDave Airlie 	udelay(10);
1599312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
1600312fec14SDave Airlie 	udelay(10);
1601312fec14SDave Airlie 
1602312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0004, param->dram_config);
1603312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0008, 0x90040f);
1604312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0010, param->reg_AC1);
1605312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0014, param->reg_AC2);
1606312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
1607312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0080, 0x00000000);
1608312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0084, 0x00000000);
1609312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
1610312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0018, 0x4040A130);
1611312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0018, 0x20402330);
1612312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0038, 0x00000000);
1613312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0040, 0xFF808000);
1614312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0044, 0x88848466);
1615312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0048, 0x44440008);
1616312fec14SDave Airlie 	moutdwm(ast, 0x1E6E004C, 0x00000000);
1617312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0050, 0x80000000);
1618312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0050, 0x00000000);
1619312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0054, 0);
1620312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0060, param->reg_DRV);
1621312fec14SDave Airlie 	moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
1622312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0070, 0x00000000);
1623312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0074, 0x00000000);
1624312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0078, 0x00000000);
1625312fec14SDave Airlie 	moutdwm(ast, 0x1E6E007C, 0x00000000);
1626312fec14SDave Airlie 
1627312fec14SDave Airlie 	/* Wait MCLK2X lock to MCLK */
1628312fec14SDave Airlie 	do {
1629312fec14SDave Airlie 		data = mindwm(ast, 0x1E6E001C);
1630312fec14SDave Airlie 	} while (!(data & 0x08000000));
1631312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0034, 0x00000001);
1632312fec14SDave Airlie 	moutdwm(ast, 0x1E6E000C, 0x00005C04);
1633312fec14SDave Airlie 	udelay(10);
1634312fec14SDave Airlie 	moutdwm(ast, 0x1E6E000C, 0x00000000);
1635312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0034, 0x00000000);
1636312fec14SDave Airlie 	data = mindwm(ast, 0x1E6E001C);
1637312fec14SDave Airlie 	data = (data >> 8) & 0xff;
1638312fec14SDave Airlie 	while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
1639312fec14SDave Airlie 		data2 = (mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
1640312fec14SDave Airlie 		if ((data2 & 0xff) > param->madj_max) {
1641312fec14SDave Airlie 			break;
1642312fec14SDave Airlie 		}
1643312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0064, data2);
1644312fec14SDave Airlie 		if (data2 & 0x00100000) {
1645312fec14SDave Airlie 			data2 = ((data2 & 0xff) >> 3) + 3;
1646312fec14SDave Airlie 		} else {
1647312fec14SDave Airlie 			data2 = ((data2 & 0xff) >> 2) + 5;
1648312fec14SDave Airlie 		}
1649312fec14SDave Airlie 		data = mindwm(ast, 0x1E6E0068) & 0xffff00ff;
1650312fec14SDave Airlie 		data2 += data & 0xff;
1651312fec14SDave Airlie 		data = data | (data2 << 8);
1652312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0068, data);
1653312fec14SDave Airlie 		udelay(10);
1654312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0064, mindwm(ast, 0x1E6E0064) | 0xC0000);
1655312fec14SDave Airlie 		udelay(10);
1656312fec14SDave Airlie 		data = mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
1657312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0018, data);
1658312fec14SDave Airlie 		data = data | 0x200;
1659312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0018, data);
1660312fec14SDave Airlie 		do {
1661312fec14SDave Airlie 			data = mindwm(ast, 0x1E6E001C);
1662312fec14SDave Airlie 		} while (!(data & 0x08000000));
1663312fec14SDave Airlie 
1664312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0034, 0x00000001);
1665312fec14SDave Airlie 		moutdwm(ast, 0x1E6E000C, 0x00005C04);
1666312fec14SDave Airlie 		udelay(10);
1667312fec14SDave Airlie 		moutdwm(ast, 0x1E6E000C, 0x00000000);
1668312fec14SDave Airlie 		moutdwm(ast, 0x1E6E0034, 0x00000000);
1669312fec14SDave Airlie 		data = mindwm(ast, 0x1E6E001C);
1670312fec14SDave Airlie 		data = (data >> 8) & 0xff;
1671312fec14SDave Airlie 	}
1672312fec14SDave Airlie 	data = mindwm(ast, 0x1E6E0018) | 0xC00;
1673312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0018, data);
1674312fec14SDave Airlie 
1675312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0034, 0x00000001);
1676312fec14SDave Airlie 	moutdwm(ast, 0x1E6E000C, 0x00000000);
1677312fec14SDave Airlie 	udelay(50);
1678312fec14SDave Airlie 	/* Mode Register Setting */
1679312fec14SDave Airlie 	moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
1680312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1681312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0028, 0x00000005);
1682312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0028, 0x00000007);
1683312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0028, 0x00000003);
1684312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0028, 0x00000001);
1685312fec14SDave Airlie 
1686312fec14SDave Airlie 	moutdwm(ast, 0x1E6E000C, 0x00005C08);
1687312fec14SDave Airlie 	moutdwm(ast, 0x1E6E002C, param->reg_MRS);
1688312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0028, 0x00000001);
1689312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0030, param->reg_EMRS | 0x380);
1690312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0028, 0x00000003);
1691312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1692312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0028, 0x00000003);
1693312fec14SDave Airlie 
1694312fec14SDave Airlie 	moutdwm(ast, 0x1E6E000C, 0x7FFF5C01);
1695312fec14SDave Airlie 	data = 0;
1696312fec14SDave Airlie 	if (param->wodt) {
1697312fec14SDave Airlie 		data = 0x500;
1698312fec14SDave Airlie 	}
1699312fec14SDave Airlie 	if (param->rodt) {
1700312fec14SDave Airlie 		data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1701312fec14SDave Airlie 	}
1702312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0034, data | 0x3);
1703312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1704312fec14SDave Airlie 
1705312fec14SDave Airlie 	/* Wait DQI delay lock */
1706312fec14SDave Airlie 	do {
1707312fec14SDave Airlie 		data = mindwm(ast, 0x1E6E0080);
1708312fec14SDave Airlie 	} while (!(data & 0x40000000));
1709312fec14SDave Airlie 	/* Wait DQSI delay lock */
1710312fec14SDave Airlie 	do {
1711312fec14SDave Airlie 		data = mindwm(ast, 0x1E6E0020);
1712312fec14SDave Airlie 	} while (!(data & 0x00000800));
1713312fec14SDave Airlie 	/* Calibrate the DQSI delay */
1714312fec14SDave Airlie 	cbr_dll2(ast, param);
1715312fec14SDave Airlie 
1716312fec14SDave Airlie 	/* ECC Memory Initialization */
1717312fec14SDave Airlie #ifdef ECC
1718312fec14SDave Airlie 	moutdwm(ast, 0x1E6E007C, 0x00000000);
1719312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0070, 0x221);
1720312fec14SDave Airlie 	do {
1721312fec14SDave Airlie 		data = mindwm(ast, 0x1E6E0070);
1722312fec14SDave Airlie 	} while (!(data & 0x00001000));
1723312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0070, 0x00000000);
1724312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0050, 0x80000000);
1725312fec14SDave Airlie 	moutdwm(ast, 0x1E6E0050, 0x00000000);
1726312fec14SDave Airlie #endif
1727312fec14SDave Airlie 
1728312fec14SDave Airlie }
1729312fec14SDave Airlie 
1730312fec14SDave Airlie static void ast_init_dram_2300(struct drm_device *dev)
1731312fec14SDave Airlie {
1732312fec14SDave Airlie 	struct ast_private *ast = dev->dev_private;
1733312fec14SDave Airlie 	struct ast2300_dram_param param;
1734312fec14SDave Airlie 	u32 temp;
1735312fec14SDave Airlie 	u8 reg;
1736312fec14SDave Airlie 
1737312fec14SDave Airlie 	reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
1738312fec14SDave Airlie 	if ((reg & 0x80) == 0) {/* vga only */
1739312fec14SDave Airlie 		ast_write32(ast, 0xf004, 0x1e6e0000);
1740312fec14SDave Airlie 		ast_write32(ast, 0xf000, 0x1);
1741312fec14SDave Airlie 		ast_write32(ast, 0x12000, 0x1688a8a8);
1742312fec14SDave Airlie 		do {
1743312fec14SDave Airlie 			;
1744312fec14SDave Airlie 		} while (ast_read32(ast, 0x12000) != 0x1);
1745312fec14SDave Airlie 
1746312fec14SDave Airlie 		ast_write32(ast, 0x10000, 0xfc600309);
1747312fec14SDave Airlie 		do {
1748312fec14SDave Airlie 			;
1749312fec14SDave Airlie 		} while (ast_read32(ast, 0x10000) != 0x1);
1750312fec14SDave Airlie 
1751312fec14SDave Airlie 		/* Slow down CPU/AHB CLK in VGA only mode */
1752312fec14SDave Airlie 		temp = ast_read32(ast, 0x12008);
1753312fec14SDave Airlie 		temp |= 0x73;
1754312fec14SDave Airlie 		ast_write32(ast, 0x12008, temp);
1755312fec14SDave Airlie 
1756312fec14SDave Airlie 		param.dram_type = AST_DDR3;
1757312fec14SDave Airlie 		if (temp & 0x01000000)
1758312fec14SDave Airlie 			param.dram_type = AST_DDR2;
1759312fec14SDave Airlie 		param.dram_chipid = ast->dram_type;
1760312fec14SDave Airlie 		param.dram_freq = ast->mclk;
1761312fec14SDave Airlie 		param.vram_size = ast->vram_size;
1762312fec14SDave Airlie 
1763312fec14SDave Airlie 		if (param.dram_type == AST_DDR3) {
1764312fec14SDave Airlie 			get_ddr3_info(ast, &param);
1765312fec14SDave Airlie 			ddr3_init(ast, &param);
1766312fec14SDave Airlie 		} else {
1767312fec14SDave Airlie 			get_ddr2_info(ast, &param);
1768312fec14SDave Airlie 			ddr2_init(ast, &param);
1769312fec14SDave Airlie 		}
1770312fec14SDave Airlie 
1771312fec14SDave Airlie 		temp = mindwm(ast, 0x1e6e2040);
1772312fec14SDave Airlie 		moutdwm(ast, 0x1e6e2040, temp | 0x40);
1773312fec14SDave Airlie 	}
1774312fec14SDave Airlie 
1775312fec14SDave Airlie 	/* wait ready */
1776312fec14SDave Airlie 	do {
1777312fec14SDave Airlie 		reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
1778312fec14SDave Airlie 	} while ((reg & 0x40) == 0);
1779312fec14SDave Airlie }
1780312fec14SDave Airlie 
1781