xref: /linux/drivers/gpu/drm/ast/ast_2100.c (revision 1be08550e6e72e8ab29e909db266130b59a47277)
1*1be08550SThomas Zimmermann // SPDX-License-Identifier: MIT
2*1be08550SThomas Zimmermann /*
3*1be08550SThomas Zimmermann  * Copyright 2012 Red Hat Inc.
4*1be08550SThomas Zimmermann  *
5*1be08550SThomas Zimmermann  * Permission is hereby granted, free of charge, to any person obtaining a
6*1be08550SThomas Zimmermann  * copy of this software and associated documentation files (the
7*1be08550SThomas Zimmermann  * "Software"), to deal in the Software without restriction, including
8*1be08550SThomas Zimmermann  * without limitation the rights to use, copy, modify, merge, publish,
9*1be08550SThomas Zimmermann  * distribute, sub license, and/or sell copies of the Software, and to
10*1be08550SThomas Zimmermann  * permit persons to whom the Software is furnished to do so, subject to
11*1be08550SThomas Zimmermann  * the following conditions:
12*1be08550SThomas Zimmermann  *
13*1be08550SThomas Zimmermann  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14*1be08550SThomas Zimmermann  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15*1be08550SThomas Zimmermann  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16*1be08550SThomas Zimmermann  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17*1be08550SThomas Zimmermann  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18*1be08550SThomas Zimmermann  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19*1be08550SThomas Zimmermann  * USE OR OTHER DEALINGS IN THE SOFTWARE.
20*1be08550SThomas Zimmermann  *
21*1be08550SThomas Zimmermann  * The above copyright notice and this permission notice (including the
22*1be08550SThomas Zimmermann  * next paragraph) shall be included in all copies or substantial portions
23*1be08550SThomas Zimmermann  * of the Software.
24*1be08550SThomas Zimmermann  */
25*1be08550SThomas Zimmermann /*
26*1be08550SThomas Zimmermann  * Authors: Dave Airlie <airlied@redhat.com>
27*1be08550SThomas Zimmermann  */
28*1be08550SThomas Zimmermann 
29*1be08550SThomas Zimmermann #include <linux/delay.h>
30*1be08550SThomas Zimmermann 
31*1be08550SThomas Zimmermann #include "ast_dram_tables.h"
32*1be08550SThomas Zimmermann #include "ast_drv.h"
33*1be08550SThomas Zimmermann 
34*1be08550SThomas Zimmermann /*
35*1be08550SThomas Zimmermann  * POST
36*1be08550SThomas Zimmermann  */
37*1be08550SThomas Zimmermann 
38*1be08550SThomas Zimmermann static const struct ast_dramstruct ast1100_dram_table_data[] = {
39*1be08550SThomas Zimmermann 	{ 0x2000, 0x1688a8a8 },
40*1be08550SThomas Zimmermann 	{ 0x2020, 0x000041f0 },
41*1be08550SThomas Zimmermann 	{ 0xFF00, 0x00000043 },
42*1be08550SThomas Zimmermann 	{ 0x0000, 0xfc600309 },
43*1be08550SThomas Zimmermann 	{ 0x006C, 0x00909090 },
44*1be08550SThomas Zimmermann 	{ 0x0064, 0x00050000 },
45*1be08550SThomas Zimmermann 	{ 0x0004, 0x00000585 },
46*1be08550SThomas Zimmermann 	{ 0x0008, 0x0011030f },
47*1be08550SThomas Zimmermann 	{ 0x0010, 0x22201724 },
48*1be08550SThomas Zimmermann 	{ 0x0018, 0x1e29011a },
49*1be08550SThomas Zimmermann 	{ 0x0020, 0x00c82222 },
50*1be08550SThomas Zimmermann 	{ 0x0014, 0x01001523 },
51*1be08550SThomas Zimmermann 	{ 0x001C, 0x1024010d },
52*1be08550SThomas Zimmermann 	{ 0x0024, 0x00cb2522 },
53*1be08550SThomas Zimmermann 	{ 0x0038, 0xffffff82 },
54*1be08550SThomas Zimmermann 	{ 0x003C, 0x00000000 },
55*1be08550SThomas Zimmermann 	{ 0x0040, 0x00000000 },
56*1be08550SThomas Zimmermann 	{ 0x0044, 0x00000000 },
57*1be08550SThomas Zimmermann 	{ 0x0048, 0x00000000 },
58*1be08550SThomas Zimmermann 	{ 0x004C, 0x00000000 },
59*1be08550SThomas Zimmermann 	{ 0x0050, 0x00000000 },
60*1be08550SThomas Zimmermann 	{ 0x0054, 0x00000000 },
61*1be08550SThomas Zimmermann 	{ 0x0058, 0x00000000 },
62*1be08550SThomas Zimmermann 	{ 0x005C, 0x00000000 },
63*1be08550SThomas Zimmermann 	{ 0x0060, 0x032aa02a },
64*1be08550SThomas Zimmermann 	{ 0x0064, 0x002d3000 },
65*1be08550SThomas Zimmermann 	{ 0x0068, 0x00000000 },
66*1be08550SThomas Zimmermann 	{ 0x0070, 0x00000000 },
67*1be08550SThomas Zimmermann 	{ 0x0074, 0x00000000 },
68*1be08550SThomas Zimmermann 	{ 0x0078, 0x00000000 },
69*1be08550SThomas Zimmermann 	{ 0x007C, 0x00000000 },
70*1be08550SThomas Zimmermann 	{ 0x0034, 0x00000001 },
71*1be08550SThomas Zimmermann 	{ 0xFF00, 0x00000043 },
72*1be08550SThomas Zimmermann 	{ 0x002C, 0x00000732 },
73*1be08550SThomas Zimmermann 	{ 0x0030, 0x00000040 },
74*1be08550SThomas Zimmermann 	{ 0x0028, 0x00000005 },
75*1be08550SThomas Zimmermann 	{ 0x0028, 0x00000007 },
76*1be08550SThomas Zimmermann 	{ 0x0028, 0x00000003 },
77*1be08550SThomas Zimmermann 	{ 0x0028, 0x00000001 },
78*1be08550SThomas Zimmermann 	{ 0x000C, 0x00005a08 },
79*1be08550SThomas Zimmermann 	{ 0x002C, 0x00000632 },
80*1be08550SThomas Zimmermann 	{ 0x0028, 0x00000001 },
81*1be08550SThomas Zimmermann 	{ 0x0030, 0x000003c0 },
82*1be08550SThomas Zimmermann 	{ 0x0028, 0x00000003 },
83*1be08550SThomas Zimmermann 	{ 0x0030, 0x00000040 },
84*1be08550SThomas Zimmermann 	{ 0x0028, 0x00000003 },
85*1be08550SThomas Zimmermann 	{ 0x000C, 0x00005a21 },
86*1be08550SThomas Zimmermann 	{ 0x0034, 0x00007c03 },
87*1be08550SThomas Zimmermann 	{ 0x0120, 0x00004c41 },
88*1be08550SThomas Zimmermann 	{ 0xffff, 0xffffffff },
89*1be08550SThomas Zimmermann };
90*1be08550SThomas Zimmermann 
91*1be08550SThomas Zimmermann static const struct ast_dramstruct ast2100_dram_table_data[] = {
92*1be08550SThomas Zimmermann 	{ 0x2000, 0x1688a8a8 },
93*1be08550SThomas Zimmermann 	{ 0x2020, 0x00004120 },
94*1be08550SThomas Zimmermann 	{ 0xFF00, 0x00000043 },
95*1be08550SThomas Zimmermann 	{ 0x0000, 0xfc600309 },
96*1be08550SThomas Zimmermann 	{ 0x006C, 0x00909090 },
97*1be08550SThomas Zimmermann 	{ 0x0064, 0x00070000 },
98*1be08550SThomas Zimmermann 	{ 0x0004, 0x00000489 },
99*1be08550SThomas Zimmermann 	{ 0x0008, 0x0011030f },
100*1be08550SThomas Zimmermann 	{ 0x0010, 0x32302926 },
101*1be08550SThomas Zimmermann 	{ 0x0018, 0x274c0122 },
102*1be08550SThomas Zimmermann 	{ 0x0020, 0x00ce2222 },
103*1be08550SThomas Zimmermann 	{ 0x0014, 0x01001523 },
104*1be08550SThomas Zimmermann 	{ 0x001C, 0x1024010d },
105*1be08550SThomas Zimmermann 	{ 0x0024, 0x00cb2522 },
106*1be08550SThomas Zimmermann 	{ 0x0038, 0xffffff82 },
107*1be08550SThomas Zimmermann 	{ 0x003C, 0x00000000 },
108*1be08550SThomas Zimmermann 	{ 0x0040, 0x00000000 },
109*1be08550SThomas Zimmermann 	{ 0x0044, 0x00000000 },
110*1be08550SThomas Zimmermann 	{ 0x0048, 0x00000000 },
111*1be08550SThomas Zimmermann 	{ 0x004C, 0x00000000 },
112*1be08550SThomas Zimmermann 	{ 0x0050, 0x00000000 },
113*1be08550SThomas Zimmermann 	{ 0x0054, 0x00000000 },
114*1be08550SThomas Zimmermann 	{ 0x0058, 0x00000000 },
115*1be08550SThomas Zimmermann 	{ 0x005C, 0x00000000 },
116*1be08550SThomas Zimmermann 	{ 0x0060, 0x0f2aa02a },
117*1be08550SThomas Zimmermann 	{ 0x0064, 0x003f3005 },
118*1be08550SThomas Zimmermann 	{ 0x0068, 0x02020202 },
119*1be08550SThomas Zimmermann 	{ 0x0070, 0x00000000 },
120*1be08550SThomas Zimmermann 	{ 0x0074, 0x00000000 },
121*1be08550SThomas Zimmermann 	{ 0x0078, 0x00000000 },
122*1be08550SThomas Zimmermann 	{ 0x007C, 0x00000000 },
123*1be08550SThomas Zimmermann 	{ 0x0034, 0x00000001 },
124*1be08550SThomas Zimmermann 	{ 0xFF00, 0x00000043 },
125*1be08550SThomas Zimmermann 	{ 0x002C, 0x00000942 },
126*1be08550SThomas Zimmermann 	{ 0x0030, 0x00000040 },
127*1be08550SThomas Zimmermann 	{ 0x0028, 0x00000005 },
128*1be08550SThomas Zimmermann 	{ 0x0028, 0x00000007 },
129*1be08550SThomas Zimmermann 	{ 0x0028, 0x00000003 },
130*1be08550SThomas Zimmermann 	{ 0x0028, 0x00000001 },
131*1be08550SThomas Zimmermann 	{ 0x000C, 0x00005a08 },
132*1be08550SThomas Zimmermann 	{ 0x002C, 0x00000842 },
133*1be08550SThomas Zimmermann 	{ 0x0028, 0x00000001 },
134*1be08550SThomas Zimmermann 	{ 0x0030, 0x000003c0 },
135*1be08550SThomas Zimmermann 	{ 0x0028, 0x00000003 },
136*1be08550SThomas Zimmermann 	{ 0x0030, 0x00000040 },
137*1be08550SThomas Zimmermann 	{ 0x0028, 0x00000003 },
138*1be08550SThomas Zimmermann 	{ 0x000C, 0x00005a21 },
139*1be08550SThomas Zimmermann 	{ 0x0034, 0x00007c03 },
140*1be08550SThomas Zimmermann 	{ 0x0120, 0x00005061 },
141*1be08550SThomas Zimmermann 	{ 0xffff, 0xffffffff },
142*1be08550SThomas Zimmermann };
143*1be08550SThomas Zimmermann 
144*1be08550SThomas Zimmermann /*
145*1be08550SThomas Zimmermann  * AST2100/2150 DLL CBR Setting
146*1be08550SThomas Zimmermann  */
147*1be08550SThomas Zimmermann #define CBR_SIZE_AST2150	     ((16 << 10) - 1)
148*1be08550SThomas Zimmermann #define CBR_PASSNUM_AST2150          5
149*1be08550SThomas Zimmermann #define CBR_THRESHOLD_AST2150        10
150*1be08550SThomas Zimmermann #define CBR_THRESHOLD2_AST2150       10
151*1be08550SThomas Zimmermann #define TIMEOUT_AST2150              5000000
152*1be08550SThomas Zimmermann 
153*1be08550SThomas Zimmermann #define CBR_PATNUM_AST2150           8
154*1be08550SThomas Zimmermann 
155*1be08550SThomas Zimmermann static const u32 pattern_AST2150[14] = {
156*1be08550SThomas Zimmermann 	0xFF00FF00,
157*1be08550SThomas Zimmermann 	0xCC33CC33,
158*1be08550SThomas Zimmermann 	0xAA55AA55,
159*1be08550SThomas Zimmermann 	0xFFFE0001,
160*1be08550SThomas Zimmermann 	0x683501FE,
161*1be08550SThomas Zimmermann 	0x0F1929B0,
162*1be08550SThomas Zimmermann 	0x2D0B4346,
163*1be08550SThomas Zimmermann 	0x60767F02,
164*1be08550SThomas Zimmermann 	0x6FBE36A6,
165*1be08550SThomas Zimmermann 	0x3A253035,
166*1be08550SThomas Zimmermann 	0x3019686D,
167*1be08550SThomas Zimmermann 	0x41C6167E,
168*1be08550SThomas Zimmermann 	0x620152BF,
169*1be08550SThomas Zimmermann 	0x20F050E0
170*1be08550SThomas Zimmermann };
171*1be08550SThomas Zimmermann 
172*1be08550SThomas Zimmermann static u32 mmctestburst2_ast2150(struct ast_device *ast, u32 datagen)
173*1be08550SThomas Zimmermann {
174*1be08550SThomas Zimmermann 	u32 data, timeout;
175*1be08550SThomas Zimmermann 
176*1be08550SThomas Zimmermann 	ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
177*1be08550SThomas Zimmermann 	ast_moutdwm(ast, 0x1e6e0070, 0x00000001 | (datagen << 3));
178*1be08550SThomas Zimmermann 	timeout = 0;
179*1be08550SThomas Zimmermann 	do {
180*1be08550SThomas Zimmermann 		data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
181*1be08550SThomas Zimmermann 		if (++timeout > TIMEOUT_AST2150) {
182*1be08550SThomas Zimmermann 			ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
183*1be08550SThomas Zimmermann 			return 0xffffffff;
184*1be08550SThomas Zimmermann 		}
185*1be08550SThomas Zimmermann 	} while (!data);
186*1be08550SThomas Zimmermann 	ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
187*1be08550SThomas Zimmermann 	ast_moutdwm(ast, 0x1e6e0070, 0x00000003 | (datagen << 3));
188*1be08550SThomas Zimmermann 	timeout = 0;
189*1be08550SThomas Zimmermann 	do {
190*1be08550SThomas Zimmermann 		data = ast_mindwm(ast, 0x1e6e0070) & 0x40;
191*1be08550SThomas Zimmermann 		if (++timeout > TIMEOUT_AST2150) {
192*1be08550SThomas Zimmermann 			ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
193*1be08550SThomas Zimmermann 			return 0xffffffff;
194*1be08550SThomas Zimmermann 		}
195*1be08550SThomas Zimmermann 	} while (!data);
196*1be08550SThomas Zimmermann 	data = (ast_mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
197*1be08550SThomas Zimmermann 	ast_moutdwm(ast, 0x1e6e0070, 0x00000000);
198*1be08550SThomas Zimmermann 	return data;
199*1be08550SThomas Zimmermann }
200*1be08550SThomas Zimmermann 
201*1be08550SThomas Zimmermann static int cbrtest_ast2150(struct ast_device *ast)
202*1be08550SThomas Zimmermann {
203*1be08550SThomas Zimmermann 	int i;
204*1be08550SThomas Zimmermann 
205*1be08550SThomas Zimmermann 	for (i = 0; i < 8; i++)
206*1be08550SThomas Zimmermann 		if (mmctestburst2_ast2150(ast, i))
207*1be08550SThomas Zimmermann 			return 0;
208*1be08550SThomas Zimmermann 	return 1;
209*1be08550SThomas Zimmermann }
210*1be08550SThomas Zimmermann 
211*1be08550SThomas Zimmermann static int cbrscan_ast2150(struct ast_device *ast, int busw)
212*1be08550SThomas Zimmermann {
213*1be08550SThomas Zimmermann 	u32 patcnt, loop;
214*1be08550SThomas Zimmermann 
215*1be08550SThomas Zimmermann 	for (patcnt = 0; patcnt < CBR_PATNUM_AST2150; patcnt++) {
216*1be08550SThomas Zimmermann 		ast_moutdwm(ast, 0x1e6e007c, pattern_AST2150[patcnt]);
217*1be08550SThomas Zimmermann 		for (loop = 0; loop < CBR_PASSNUM_AST2150; loop++) {
218*1be08550SThomas Zimmermann 			if (cbrtest_ast2150(ast))
219*1be08550SThomas Zimmermann 				break;
220*1be08550SThomas Zimmermann 		}
221*1be08550SThomas Zimmermann 		if (loop == CBR_PASSNUM_AST2150)
222*1be08550SThomas Zimmermann 			return 0;
223*1be08550SThomas Zimmermann 	}
224*1be08550SThomas Zimmermann 	return 1;
225*1be08550SThomas Zimmermann }
226*1be08550SThomas Zimmermann 
227*1be08550SThomas Zimmermann static void cbrdlli_ast2150(struct ast_device *ast, int busw)
228*1be08550SThomas Zimmermann {
229*1be08550SThomas Zimmermann 	u32 dll_min[4], dll_max[4], dlli, data, passcnt;
230*1be08550SThomas Zimmermann 
231*1be08550SThomas Zimmermann cbr_start:
232*1be08550SThomas Zimmermann 	dll_min[0] = 0xff;
233*1be08550SThomas Zimmermann 	dll_min[1] = 0xff;
234*1be08550SThomas Zimmermann 	dll_min[2] = 0xff;
235*1be08550SThomas Zimmermann 	dll_min[3] = 0xff;
236*1be08550SThomas Zimmermann 	dll_max[0] = 0x00;
237*1be08550SThomas Zimmermann 	dll_max[1] = 0x00;
238*1be08550SThomas Zimmermann 	dll_max[2] = 0x00;
239*1be08550SThomas Zimmermann 	dll_max[3] = 0x00;
240*1be08550SThomas Zimmermann 	passcnt = 0;
241*1be08550SThomas Zimmermann 
242*1be08550SThomas Zimmermann 	for (dlli = 0; dlli < 100; dlli++) {
243*1be08550SThomas Zimmermann 		ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
244*1be08550SThomas Zimmermann 		data = cbrscan_ast2150(ast, busw);
245*1be08550SThomas Zimmermann 		if (data != 0) {
246*1be08550SThomas Zimmermann 			if (data & 0x1) {
247*1be08550SThomas Zimmermann 				if (dll_min[0] > dlli)
248*1be08550SThomas Zimmermann 					dll_min[0] = dlli;
249*1be08550SThomas Zimmermann 				if (dll_max[0] < dlli)
250*1be08550SThomas Zimmermann 					dll_max[0] = dlli;
251*1be08550SThomas Zimmermann 			}
252*1be08550SThomas Zimmermann 			passcnt++;
253*1be08550SThomas Zimmermann 		} else if (passcnt >= CBR_THRESHOLD_AST2150) {
254*1be08550SThomas Zimmermann 			goto cbr_start;
255*1be08550SThomas Zimmermann 		}
256*1be08550SThomas Zimmermann 	}
257*1be08550SThomas Zimmermann 	if (dll_max[0] == 0 || (dll_max[0] - dll_min[0]) < CBR_THRESHOLD_AST2150)
258*1be08550SThomas Zimmermann 		goto cbr_start;
259*1be08550SThomas Zimmermann 
260*1be08550SThomas Zimmermann 	dlli = dll_min[0] + (((dll_max[0] - dll_min[0]) * 7) >> 4);
261*1be08550SThomas Zimmermann 	ast_moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
262*1be08550SThomas Zimmermann }
263*1be08550SThomas Zimmermann 
264*1be08550SThomas Zimmermann static void ast_post_chip_2100(struct ast_device *ast)
265*1be08550SThomas Zimmermann {
266*1be08550SThomas Zimmermann 	u8 j;
267*1be08550SThomas Zimmermann 	u32 data, temp, i;
268*1be08550SThomas Zimmermann 	const struct ast_dramstruct *dram_reg_info;
269*1be08550SThomas Zimmermann 
270*1be08550SThomas Zimmermann 	j = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
271*1be08550SThomas Zimmermann 
272*1be08550SThomas Zimmermann 	if ((j & 0x80) == 0) { /* VGA only */
273*1be08550SThomas Zimmermann 		if (ast->chip == AST2100 || ast->chip == AST2200)
274*1be08550SThomas Zimmermann 			dram_reg_info = ast2100_dram_table_data;
275*1be08550SThomas Zimmermann 		else
276*1be08550SThomas Zimmermann 			dram_reg_info = ast1100_dram_table_data;
277*1be08550SThomas Zimmermann 
278*1be08550SThomas Zimmermann 		ast_write32(ast, 0xf004, 0x1e6e0000);
279*1be08550SThomas Zimmermann 		ast_write32(ast, 0xf000, 0x1);
280*1be08550SThomas Zimmermann 		ast_write32(ast, 0x12000, 0x1688A8A8);
281*1be08550SThomas Zimmermann 		do {
282*1be08550SThomas Zimmermann 			;
283*1be08550SThomas Zimmermann 		} while (ast_read32(ast, 0x12000) != 0x01);
284*1be08550SThomas Zimmermann 
285*1be08550SThomas Zimmermann 		ast_write32(ast, 0x10000, 0xfc600309);
286*1be08550SThomas Zimmermann 		do {
287*1be08550SThomas Zimmermann 			;
288*1be08550SThomas Zimmermann 		} while (ast_read32(ast, 0x10000) != 0x01);
289*1be08550SThomas Zimmermann 
290*1be08550SThomas Zimmermann 		while (dram_reg_info->index != 0xffff) {
291*1be08550SThomas Zimmermann 			if (dram_reg_info->index == 0xff00) {/* delay fn */
292*1be08550SThomas Zimmermann 				for (i = 0; i < 15; i++)
293*1be08550SThomas Zimmermann 					udelay(dram_reg_info->data);
294*1be08550SThomas Zimmermann 			} else if (dram_reg_info->index == 0x4) {
295*1be08550SThomas Zimmermann 				data = dram_reg_info->data;
296*1be08550SThomas Zimmermann 				if (ast->dram_type == AST_DRAM_1Gx16)
297*1be08550SThomas Zimmermann 					data = 0x00000d89;
298*1be08550SThomas Zimmermann 				else if (ast->dram_type == AST_DRAM_1Gx32)
299*1be08550SThomas Zimmermann 					data = 0x00000c8d;
300*1be08550SThomas Zimmermann 
301*1be08550SThomas Zimmermann 				temp = ast_read32(ast, 0x12070);
302*1be08550SThomas Zimmermann 				temp &= 0xc;
303*1be08550SThomas Zimmermann 				temp <<= 2;
304*1be08550SThomas Zimmermann 				ast_write32(ast, 0x10000 + dram_reg_info->index, data | temp);
305*1be08550SThomas Zimmermann 			} else {
306*1be08550SThomas Zimmermann 				ast_write32(ast, 0x10000 + dram_reg_info->index,
307*1be08550SThomas Zimmermann 					    dram_reg_info->data);
308*1be08550SThomas Zimmermann 			}
309*1be08550SThomas Zimmermann 			dram_reg_info++;
310*1be08550SThomas Zimmermann 		}
311*1be08550SThomas Zimmermann 
312*1be08550SThomas Zimmermann 		/* AST 2100/2150 DRAM calibration */
313*1be08550SThomas Zimmermann 		data = ast_read32(ast, 0x10120);
314*1be08550SThomas Zimmermann 		if (data == 0x5061) { /* 266Mhz */
315*1be08550SThomas Zimmermann 			data = ast_read32(ast, 0x10004);
316*1be08550SThomas Zimmermann 			if (data & 0x40)
317*1be08550SThomas Zimmermann 				cbrdlli_ast2150(ast, 16); /* 16 bits */
318*1be08550SThomas Zimmermann 			else
319*1be08550SThomas Zimmermann 				cbrdlli_ast2150(ast, 32); /* 32 bits */
320*1be08550SThomas Zimmermann 		}
321*1be08550SThomas Zimmermann 
322*1be08550SThomas Zimmermann 		temp = ast_read32(ast, 0x1200c);
323*1be08550SThomas Zimmermann 		ast_write32(ast, 0x1200c, temp & 0xfffffffd);
324*1be08550SThomas Zimmermann 		temp = ast_read32(ast, 0x12040);
325*1be08550SThomas Zimmermann 		ast_write32(ast, 0x12040, temp | 0x40);
326*1be08550SThomas Zimmermann 	}
327*1be08550SThomas Zimmermann 
328*1be08550SThomas Zimmermann 	/* wait ready */
329*1be08550SThomas Zimmermann 	do {
330*1be08550SThomas Zimmermann 		j = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
331*1be08550SThomas Zimmermann 	} while ((j & 0x40) == 0);
332*1be08550SThomas Zimmermann }
333*1be08550SThomas Zimmermann 
334*1be08550SThomas Zimmermann int ast_2100_post(struct ast_device *ast)
335*1be08550SThomas Zimmermann {
336*1be08550SThomas Zimmermann 	if (ast->config_mode == ast_use_p2a) {
337*1be08550SThomas Zimmermann 		ast_post_chip_2100(ast);
338*1be08550SThomas Zimmermann 	} else {
339*1be08550SThomas Zimmermann 		if (ast->tx_chip == AST_TX_SIL164) {
340*1be08550SThomas Zimmermann 			/* Enable DVO */
341*1be08550SThomas Zimmermann 			ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80);
342*1be08550SThomas Zimmermann 		}
343*1be08550SThomas Zimmermann 	}
344*1be08550SThomas Zimmermann 
345*1be08550SThomas Zimmermann 	return 0;
346*1be08550SThomas Zimmermann }
347