i128init.c revision b3e38ee4
1/*
2 * Copyright 1995-2000 by Robin Cutshaw <robin@XFree86.Org>
3 * Copyright 1998 by Number Nine Visual Technology, Inc.
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of Robin Cutshaw not be used in
10 * advertising or publicity pertaining to distribution of the software without
11 * specific, written prior permission.  Robin Cutshaw and Number Nine make no
12 * representations about the suitability of this software for any purpose.  It
13 * is provided "as is" without express or implied warranty.
14 *
15 * ROBIN CUTSHAW AND NUMBER NINE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
16 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 * FITNESS, IN NO EVENT SHALL ROBIN CUTSHAW OR NUMBER NINE BE LIABLE FOR
18 * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
20 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
21 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 *
23 */
24
25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29
30
31#include "xf86.h"
32#include "xf86PciInfo.h"
33#include "xf86Pci.h"
34
35#include "i128.h"
36#include "i128reg.h"
37#include "Ti302X.h"
38#include "IBMRGB.h"
39
40#include <unistd.h>
41
42static void I128SavePalette(I128Ptr pI128);
43static void I128RestorePalette(I128Ptr pI128);
44
45
46void
47I128SaveState(ScrnInfoPtr pScrn)
48{
49        I128Ptr pI128 = I128PTR(pScrn);
50	I128RegPtr iR = &pI128->RegRec;
51
52        if (pI128->Debug)
53        	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128SaveState start\n");
54
55	if (pI128->Debug) {
56		unsigned long tmp1 = inl(iR->iobase + 0x1C);
57		unsigned long tmp2 = inl(iR->iobase + 0x20);
58        	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128SaveState saving, config1/2 = 0x%lx/0x%lx\n", tmp1, tmp2);
59		I128DumpActiveRegisters(pScrn);
60	}
61
62	/* iobase is filled in during the device probe (as well as config 1&2)*/
63
64	if ((pI128->io.id&0x7) > 0) {
65		iR->vga_ctl = inl(iR->iobase + 0x30);
66	}
67
68	iR->i128_base_g[INT_VCNT] = pI128->mem.rbase_g[INT_VCNT]; /*  0x0020  */
69	iR->i128_base_g[INT_HCNT] = pI128->mem.rbase_g[INT_HCNT]; /*  0x0024  */
70	iR->i128_base_g[DB_ADR]   = pI128->mem.rbase_g[DB_ADR];   /*  0x0028  */
71	iR->i128_base_g[DB_PTCH]  = pI128->mem.rbase_g[DB_PTCH];  /*  0x002C  */
72	iR->i128_base_g[CRT_HAC]  = pI128->mem.rbase_g[CRT_HAC];  /*  0x0030  */
73	iR->i128_base_g[CRT_HBL]  = pI128->mem.rbase_g[CRT_HBL];  /*  0x0034  */
74	iR->i128_base_g[CRT_HFP]  = pI128->mem.rbase_g[CRT_HFP];  /*  0x0038  */
75	iR->i128_base_g[CRT_HS]   = pI128->mem.rbase_g[CRT_HS];   /*  0x003C  */
76	iR->i128_base_g[CRT_VAC]  = pI128->mem.rbase_g[CRT_VAC];  /*  0x0040  */
77	iR->i128_base_g[CRT_VBL]  = pI128->mem.rbase_g[CRT_VBL];  /*  0x0044  */
78	iR->i128_base_g[CRT_VFP]  = pI128->mem.rbase_g[CRT_VFP];  /*  0x0048  */
79	iR->i128_base_g[CRT_VS]   = pI128->mem.rbase_g[CRT_VS];   /*  0x004C  */
80	iR->i128_base_g[CRT_LCNT] = pI128->mem.rbase_g[CRT_LCNT]; /*  0x0050  */
81	iR->i128_base_g[CRT_ZOOM] = pI128->mem.rbase_g[CRT_ZOOM]; /*  0x0054  */
82	iR->i128_base_g[CRT_1CON] = pI128->mem.rbase_g[CRT_1CON]; /*  0x0058  */
83	iR->i128_base_g[CRT_2CON] = pI128->mem.rbase_g[CRT_2CON]; /*  0x005C  */
84
85	iR->i128_base_w[MW0_CTRL] = pI128->mem.rbase_w[MW0_CTRL]; /*  0x0000  */
86	iR->i128_base_w[MW0_SZ]   = pI128->mem.rbase_w[MW0_SZ];   /*  0x0008  */
87	iR->i128_base_w[MW0_PGE]  = pI128->mem.rbase_w[MW0_PGE];  /*  0x000C  */
88	iR->i128_base_w[MW0_ORG]  = pI128->mem.rbase_w[MW0_ORG];  /*  0x0010  */
89	iR->i128_base_w[MW0_MSRC] = pI128->mem.rbase_w[MW0_MSRC]; /*  0x0018  */
90	iR->i128_base_w[MW0_WKEY] = pI128->mem.rbase_w[MW0_WKEY]; /*  0x001C  */
91	iR->i128_base_w[MW0_KDAT] = pI128->mem.rbase_w[MW0_KDAT]; /*  0x0020  */
92	iR->i128_base_w[MW0_MASK] = pI128->mem.rbase_w[MW0_MASK]; /*  0x0024  */
93
94	if (pI128->RamdacType == TI3025_DAC) {
95		pI128->mem.rbase_g[INDEX_TI] = TI_CURS_CONTROL;		MB;
96		iR->Ti302X[TI_CURS_CONTROL] = pI128->mem.rbase_g[DATA_TI];
97		pI128->mem.rbase_g[INDEX_TI] = TI_TRUE_COLOR_CONTROL;	MB;
98		iR->Ti302X[TI_TRUE_COLOR_CONTROL] = pI128->mem.rbase_g[DATA_TI];
99		pI128->mem.rbase_g[INDEX_TI] = TI_VGA_SWITCH_CONTROL;	MB;
100		iR->Ti302X[TI_VGA_SWITCH_CONTROL] = pI128->mem.rbase_g[DATA_TI];
101		pI128->mem.rbase_g[INDEX_TI] = TI_MUX_CONTROL_1;	MB;
102		iR->Ti302X[TI_MUX_CONTROL_1] = pI128->mem.rbase_g[DATA_TI];
103		pI128->mem.rbase_g[INDEX_TI] = TI_MUX_CONTROL_2;	MB;
104		iR->Ti302X[TI_MUX_CONTROL_2] = pI128->mem.rbase_g[DATA_TI];
105		pI128->mem.rbase_g[INDEX_TI] = TI_INPUT_CLOCK_SELECT;	MB;
106		iR->Ti302X[TI_INPUT_CLOCK_SELECT] = pI128->mem.rbase_g[DATA_TI];
107		pI128->mem.rbase_g[INDEX_TI] = TI_OUTPUT_CLOCK_SELECT;	MB;
108		iR->Ti302X[TI_OUTPUT_CLOCK_SELECT] = pI128->mem.rbase_g[DATA_TI];
109		pI128->mem.rbase_g[INDEX_TI] = TI_PALETTE_PAGE;		MB;
110		iR->Ti302X[TI_PALETTE_PAGE] = pI128->mem.rbase_g[DATA_TI];
111		pI128->mem.rbase_g[INDEX_TI] = TI_GENERAL_CONTROL;	MB;
112		iR->Ti302X[TI_GENERAL_CONTROL] = pI128->mem.rbase_g[DATA_TI];
113		pI128->mem.rbase_g[INDEX_TI] = TI_MISC_CONTROL;		MB;
114		iR->Ti302X[TI_MISC_CONTROL] = pI128->mem.rbase_g[DATA_TI];
115		pI128->mem.rbase_g[INDEX_TI] = TI_AUXILIARY_CONTROL;	MB;
116		iR->Ti302X[TI_AUXILIARY_CONTROL] = pI128->mem.rbase_g[DATA_TI];
117		pI128->mem.rbase_g[INDEX_TI] = TI_GENERAL_IO_CONTROL;	MB;
118		iR->Ti302X[TI_GENERAL_IO_CONTROL] = pI128->mem.rbase_g[DATA_TI];
119		pI128->mem.rbase_g[INDEX_TI] = TI_GENERAL_IO_DATA;	MB;
120		iR->Ti302X[TI_GENERAL_IO_DATA] = pI128->mem.rbase_g[DATA_TI];
121		pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_DCLK_CONTROL;	MB;
122		iR->Ti302X[TI_MCLK_DCLK_CONTROL] = pI128->mem.rbase_g[DATA_TI];
123		pI128->mem.rbase_g[INDEX_TI] = TI_COLOR_KEY_CONTROL;	MB;
124		iR->Ti302X[TI_COLOR_KEY_CONTROL] = pI128->mem.rbase_g[DATA_TI];
125
126		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
127		pI128->mem.rbase_g[DATA_TI] = 0x00;			MB;
128		pI128->mem.rbase_g[INDEX_TI] = TI_PIXEL_CLOCK_PLL_DATA;	MB;
129		iR->Ti3025[0] = pI128->mem.rbase_g[DATA_TI];
130
131		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
132		pI128->mem.rbase_g[DATA_TI] = 0x01;			MB;
133		pI128->mem.rbase_g[INDEX_TI] = TI_PIXEL_CLOCK_PLL_DATA;	MB;
134		iR->Ti3025[1] = pI128->mem.rbase_g[DATA_TI];
135
136		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
137		pI128->mem.rbase_g[DATA_TI] = 0x02;			MB;
138		pI128->mem.rbase_g[INDEX_TI] = TI_PIXEL_CLOCK_PLL_DATA;	MB;
139		iR->Ti3025[2] = pI128->mem.rbase_g[DATA_TI];
140
141		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
142		pI128->mem.rbase_g[DATA_TI] = 0x00;			MB;
143		pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA;	MB;
144		iR->Ti3025[3] = pI128->mem.rbase_g[DATA_TI];
145
146		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
147		pI128->mem.rbase_g[DATA_TI] = 0x01;			MB;
148		pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA;	MB;
149		iR->Ti3025[4] = pI128->mem.rbase_g[DATA_TI];
150
151		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
152		pI128->mem.rbase_g[DATA_TI] = 0x02;			MB;
153		pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA;	MB;
154		iR->Ti3025[5] = pI128->mem.rbase_g[DATA_TI];
155
156		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
157		pI128->mem.rbase_g[DATA_TI] = 0x00;			MB;
158		pI128->mem.rbase_g[INDEX_TI] = TI_LOOP_CLOCK_PLL_DATA;	MB;
159		iR->Ti3025[6] = pI128->mem.rbase_g[DATA_TI];
160
161		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
162		pI128->mem.rbase_g[DATA_TI] = 0x01;			MB;
163		pI128->mem.rbase_g[INDEX_TI] = TI_LOOP_CLOCK_PLL_DATA;	MB;
164		iR->Ti3025[7] = pI128->mem.rbase_g[DATA_TI];
165
166		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
167		pI128->mem.rbase_g[DATA_TI] = 0x02;			MB;
168		pI128->mem.rbase_g[INDEX_TI] = TI_LOOP_CLOCK_PLL_DATA;	MB;
169		iR->Ti3025[8] = pI128->mem.rbase_g[DATA_TI];
170	} else if ((pI128->RamdacType == IBM526_DAC) ||
171		   (pI128->RamdacType == IBM528_DAC) ||
172		   (pI128->RamdacType == SILVER_HAMMER_DAC)) {
173		CARD32 i;
174
175		for (i=0; i<0x94; i++) {
176			pI128->mem.rbase_g[IDXL_I] = i;			MB;
177			iR->IBMRGB[i] = pI128->mem.rbase_g[DATA_I];
178		}
179	}
180
181	I128SavePalette(pI128);
182
183        if (pI128->Debug)
184        	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128SaveState complete\n");
185
186}
187
188
189void
190I128RestoreState(ScrnInfoPtr pScrn)
191{
192        I128Ptr pI128 = I128PTR(pScrn);
193	I128RegPtr iR = &pI128->RegRec;
194
195        if (pI128->Debug)
196        	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128RestoreState start\n");
197
198	if (pI128->RamdacType == TI3025_DAC) {
199		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
200		pI128->mem.rbase_g[DATA_TI] = 0x00;			MB;
201		pI128->mem.rbase_g[INDEX_TI] = TI_PIXEL_CLOCK_PLL_DATA;	MB;
202		pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[0];		MB;
203
204		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
205		pI128->mem.rbase_g[DATA_TI] = 0x01;			MB;
206		pI128->mem.rbase_g[INDEX_TI] = TI_PIXEL_CLOCK_PLL_DATA;	MB;
207		pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[1];		MB;
208
209		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
210		pI128->mem.rbase_g[DATA_TI] = 0x02;			MB;
211		pI128->mem.rbase_g[INDEX_TI] = TI_PIXEL_CLOCK_PLL_DATA;	MB;
212		pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[2];		MB;
213
214		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
215		pI128->mem.rbase_g[DATA_TI] = 0x00;			MB;
216		pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA;	MB;
217		pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[3];		MB;
218
219		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
220		pI128->mem.rbase_g[DATA_TI] = 0x01;			MB;
221		pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA;	MB;
222		pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[4];		MB;
223
224		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
225		pI128->mem.rbase_g[DATA_TI] = 0x02;			MB;
226		pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_PLL_DATA;	MB;
227		pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[5];		MB;
228
229		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
230		pI128->mem.rbase_g[DATA_TI] = 0x00;			MB;
231		pI128->mem.rbase_g[INDEX_TI] = TI_LOOP_CLOCK_PLL_DATA;	MB;
232		pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[6];		MB;
233
234		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
235		pI128->mem.rbase_g[DATA_TI] = 0x01;			MB;
236		pI128->mem.rbase_g[INDEX_TI] = TI_LOOP_CLOCK_PLL_DATA;	MB;
237		pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[7];		MB;
238
239		pI128->mem.rbase_g[INDEX_TI] = TI_PLL_CONTROL;		MB;
240		pI128->mem.rbase_g[DATA_TI] = 0x02;			MB;
241		pI128->mem.rbase_g[INDEX_TI] = TI_LOOP_CLOCK_PLL_DATA;	MB;
242		pI128->mem.rbase_g[DATA_TI] = iR->Ti3025[8];		MB;
243
244		pI128->mem.rbase_g[INDEX_TI] = TI_CURS_CONTROL;		MB;
245		pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_CURS_CONTROL];MB;
246		pI128->mem.rbase_g[INDEX_TI] = TI_TRUE_COLOR_CONTROL;	MB;
247		pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_TRUE_COLOR_CONTROL]; MB;
248		pI128->mem.rbase_g[INDEX_TI] = TI_VGA_SWITCH_CONTROL;	MB;
249		pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_VGA_SWITCH_CONTROL]; MB;
250		pI128->mem.rbase_g[INDEX_TI] = TI_MUX_CONTROL_1;	MB;
251		pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_MUX_CONTROL_1];MB;
252		pI128->mem.rbase_g[INDEX_TI] = TI_MUX_CONTROL_2;	MB;
253		pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_MUX_CONTROL_2];MB;
254		pI128->mem.rbase_g[INDEX_TI] = TI_INPUT_CLOCK_SELECT;	MB;
255		pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_INPUT_CLOCK_SELECT]; MB;
256		pI128->mem.rbase_g[INDEX_TI] = TI_OUTPUT_CLOCK_SELECT;	MB;
257		pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_OUTPUT_CLOCK_SELECT];MB;
258		pI128->mem.rbase_g[INDEX_TI] = TI_PALETTE_PAGE;		MB;
259		pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_PALETTE_PAGE];MB;
260		pI128->mem.rbase_g[INDEX_TI] = TI_GENERAL_CONTROL;	MB;
261		pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_GENERAL_CONTROL]; MB;
262		pI128->mem.rbase_g[INDEX_TI] = TI_MISC_CONTROL;		MB;
263		pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_MISC_CONTROL];MB;
264		pI128->mem.rbase_g[INDEX_TI] = TI_AUXILIARY_CONTROL;	MB;
265		pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_AUXILIARY_CONTROL]; MB;
266		pI128->mem.rbase_g[INDEX_TI] = TI_GENERAL_IO_CONTROL;	MB;
267		pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_GENERAL_IO_CONTROL]; MB;
268		pI128->mem.rbase_g[INDEX_TI] = TI_GENERAL_IO_DATA;	MB;
269		pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_GENERAL_IO_DATA]; MB;
270		pI128->mem.rbase_g[INDEX_TI] = TI_MCLK_DCLK_CONTROL;	MB;
271		pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_MCLK_DCLK_CONTROL]; MB;
272		pI128->mem.rbase_g[INDEX_TI] = TI_COLOR_KEY_CONTROL;	MB;
273		pI128->mem.rbase_g[DATA_TI] = iR->Ti302X[TI_COLOR_KEY_CONTROL]; MB;
274	} else if ((pI128->RamdacType == IBM526_DAC) ||
275		   (pI128->RamdacType == IBM528_DAC) ||
276		   (pI128->RamdacType == SILVER_HAMMER_DAC)) {
277		CARD32 i;
278
279		if (pI128->Debug) {
280			unsigned long tmp1 = inl(iR->iobase + 0x1C);
281			unsigned long tmp2 = inl(iR->iobase + 0x20);
282       	 	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128RestoreState restoring, config1/2 = 0x%lx/0x%lx\n", tmp1, tmp2);
283			I128DumpActiveRegisters(pScrn);
284		}
285
286		for (i=0; i<0x94; i++) {
287			if ((i == IBMRGB_sysclk_vco_div) ||
288			    (i == IBMRGB_sysclk_ref_div))
289				continue;
290			pI128->mem.rbase_g[IDXL_I] = i;			MB;
291			pI128->mem.rbase_g[DATA_I] = iR->IBMRGB[i];	MB;
292		}
293
294   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_ref_div;	MB;
295   		pI128->mem.rbase_g[DATA_I] =
296			iR->IBMRGB[IBMRGB_sysclk_ref_div];		MB;
297   		pI128->mem.rbase_g[IDXL_I] = IBMRGB_sysclk_vco_div;	MB;
298   		pI128->mem.rbase_g[DATA_I] =
299			iR->IBMRGB[IBMRGB_sysclk_vco_div];		MB;
300		usleep(50000);
301	}
302
303	/* iobase is filled in during the device probe (as well as config 1&2)*/
304
305	if (((pI128->io.id&0x7) > 0) ||
306	    (pI128->Chipset == PCI_CHIP_I128_T2R) ||
307	    (pI128->Chipset == PCI_CHIP_I128_T2R4)) {
308		outl(iR->iobase + 0x30, iR->vga_ctl);
309	}
310
311	I128RestorePalette(pI128);
312
313	pI128->mem.rbase_w[MW0_CTRL] = iR->i128_base_w[MW0_CTRL]; /*  0x0000  */
314	pI128->mem.rbase_w[MW0_SZ]   = iR->i128_base_w[MW0_SZ];   /*  0x0008  */
315	pI128->mem.rbase_w[MW0_PGE]  = iR->i128_base_w[MW0_PGE];  /*  0x000C  */
316	pI128->mem.rbase_w[MW0_ORG]  = iR->i128_base_w[MW0_ORG];  /*  0x0010  */
317	pI128->mem.rbase_w[MW0_MSRC] = iR->i128_base_w[MW0_MSRC]; /*  0x0018  */
318	pI128->mem.rbase_w[MW0_WKEY] = iR->i128_base_w[MW0_WKEY]; /*  0x001C  */
319	pI128->mem.rbase_w[MW0_KDAT] = iR->i128_base_w[MW0_KDAT]; /*  0x0020  */
320	pI128->mem.rbase_w[MW0_MASK] = iR->i128_base_w[MW0_MASK]; /*  0x0024  */
321									MB;
322
323	pI128->mem.rbase_g[INT_VCNT] = iR->i128_base_g[INT_VCNT]; /*  0x0020  */
324	pI128->mem.rbase_g[INT_HCNT] = iR->i128_base_g[INT_HCNT]; /*  0x0024  */
325	pI128->mem.rbase_g[DB_ADR]   = iR->i128_base_g[DB_ADR];   /*  0x0028  */
326	pI128->mem.rbase_g[DB_PTCH]  = iR->i128_base_g[DB_PTCH];  /*  0x002C  */
327	pI128->mem.rbase_g[CRT_HAC]  = iR->i128_base_g[CRT_HAC];  /*  0x0030  */
328	pI128->mem.rbase_g[CRT_HBL]  = iR->i128_base_g[CRT_HBL];  /*  0x0034  */
329	pI128->mem.rbase_g[CRT_HFP]  = iR->i128_base_g[CRT_HFP];  /*  0x0038  */
330	pI128->mem.rbase_g[CRT_HS]   = iR->i128_base_g[CRT_HS];   /*  0x003C  */
331	pI128->mem.rbase_g[CRT_VAC]  = iR->i128_base_g[CRT_VAC];  /*  0x0040  */
332	pI128->mem.rbase_g[CRT_VBL]  = iR->i128_base_g[CRT_VBL];  /*  0x0044  */
333	pI128->mem.rbase_g[CRT_VFP]  = iR->i128_base_g[CRT_VFP];  /*  0x0048  */
334	pI128->mem.rbase_g[CRT_VS]   = iR->i128_base_g[CRT_VS];   /*  0x004C  */
335	pI128->mem.rbase_g[CRT_LCNT] = iR->i128_base_g[CRT_LCNT]; /*  0x0050  */
336	pI128->mem.rbase_g[CRT_ZOOM] = iR->i128_base_g[CRT_ZOOM]; /*  0x0054  */
337	pI128->mem.rbase_g[CRT_1CON] = iR->i128_base_g[CRT_1CON]; /*  0x0058  */
338	pI128->mem.rbase_g[CRT_2CON] = iR->i128_base_g[CRT_2CON]; /*  0x005C  */
339									MB;
340
341	if (pI128->Debug) {
342		unsigned long tmp1 = inl(iR->iobase + 0x1C);
343		unsigned long tmp2 = inl(iR->iobase + 0x20);
344        	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128RestoreState resetting config1/2 from 0x%lx/0x%lx to 0x%lx/0x%lx\n", tmp1, tmp2, (unsigned long)iR->config1, (unsigned long)iR->config2);
345		I128DumpActiveRegisters(pScrn);
346	}
347
348	if (pI128->MemoryType == I128_MEMORY_SGRAM) {
349		outl(iR->iobase + 0x24, iR->sgram & 0x7FFFFFFF);
350		outl(iR->iobase + 0x24, iR->sgram | 0x80000000);
351	}
352
353	outl(iR->iobase + 0x20, iR->config2);
354	outl(iR->iobase + 0x1C, iR->config1);
355
356        if (pI128->Debug)
357        	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128RestoreState complete\n");
358}
359
360
361Bool
362I128Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
363{
364	I128Ptr pI128;
365	I128RegPtr iR;
366	int pitch_multiplier, iclock;
367	Bool ret;
368	CARD32 tmp;
369	int doubled = 1;
370
371	if (mode->Flags & V_DBLSCAN)
372		doubled = 2;
373
374        pI128 = I128PTR(pScrn);
375	iR = &pI128->RegRec;
376	pI128->HDisplay = mode->HDisplay;
377
378        if (pI128->Debug)
379        	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128Init start\n");
380
381	/* config 1 and 2 were saved in Probe()
382	 * we reset here again in case there was a VT switch
383	 */
384
385	outl(iR->iobase + 0x1C, pI128->io.config1);
386	outl(iR->iobase + 0x20, pI128->io.config2);
387
388	if (pI128->MemoryType == I128_MEMORY_SGRAM) {
389		outl(iR->iobase + 0x24, pI128->io.sgram & 0x7FFFFFFF);
390		outl(iR->iobase + 0x24, pI128->io.sgram | 0x80000000);
391	}
392
393
394	if (pI128->bitsPerPixel == 32)		pitch_multiplier = 4;
395	else if (pI128->bitsPerPixel == 16)	pitch_multiplier = 2;
396	else					pitch_multiplier = 1;
397
398	if (pI128->RamdacType == TI3025_DAC)
399		iclock = 4;
400	else if (pI128->RamdacType == IBM528_DAC)
401		iclock = 128 / pI128->bitsPerPixel;
402	else if (pI128->RamdacType == SILVER_HAMMER_DAC)
403		iclock = 64 / pI128->bitsPerPixel;
404	else if ((pI128->MemoryType == I128_MEMORY_DRAM) ||
405		 (pI128->MemoryType == I128_MEMORY_SGRAM))
406		iclock = 32 / pI128->bitsPerPixel; /* IBM526 DAC 32b bus */
407	else
408		iclock = 64 / pI128->bitsPerPixel; /* IBM524/526 DAC */
409
410	pI128->mem.rbase_g[INT_VCNT] = 0x00;
411	pI128->mem.rbase_g[INT_HCNT] = 0x00;
412	pI128->mem.rbase_g[DB_ADR] = pI128->displayOffset;
413	pI128->mem.rbase_g[DB_PTCH] = pI128->displayWidth * pitch_multiplier;
414	pI128->mem.rbase_g[CRT_HAC] = mode->HDisplay/iclock;
415	pI128->mem.rbase_g[CRT_HBL] = (mode->HTotal - mode->HDisplay)/iclock;
416	pI128->mem.rbase_g[CRT_HFP] = (mode->HSyncStart - mode->HDisplay)/iclock;
417	pI128->mem.rbase_g[CRT_HS] = (mode->HSyncEnd - mode->HSyncStart)/iclock;
418	pI128->mem.rbase_g[CRT_VAC] = mode->VDisplay * doubled;
419	pI128->mem.rbase_g[CRT_VBL] = (mode->VTotal - mode->VDisplay) * doubled;
420	pI128->mem.rbase_g[CRT_VFP] = (mode->VSyncStart - mode->VDisplay)* doubled;
421	pI128->mem.rbase_g[CRT_VS] = (mode->VSyncEnd - mode->VSyncStart) * doubled;
422	tmp = 0x00000070;
423	if (pI128->Chipset == PCI_CHIP_I128_T2R)
424		tmp |= 0x00000100;
425	if (pI128->Chipset == PCI_CHIP_I128_T2R4) {
426		if (pI128->FlatPanel)
427			tmp |= 0x00000100;    /* Turn on digital flat panel */
428		else
429			tmp &= 0xfffffeff;    /* Turn off digital flat panel */
430	}
431	if (pI128->DACSyncOnGreen || (mode->Flags & V_CSYNC))
432		tmp |= 0x00000004;
433	pI128->mem.rbase_g[CRT_1CON] = tmp;
434	if ((pI128->MemoryType == I128_MEMORY_DRAM) ||
435	    (pI128->MemoryType == I128_MEMORY_SGRAM))
436		tmp = 0x20000100;
437	else if (pI128->MemoryType == I128_MEMORY_WRAM)
438		tmp = 0x00040100;
439	else {
440		tmp = 0x00040101;
441		if (pI128->MemorySize == 2048)
442			tmp |= 0x00000002;
443		if ((pI128->displayWidth & (pI128->displayWidth-1)) ||
444		    ((pI128->displayWidth * pI128->bitsPerPixel) > 32768L))
445			tmp |= 0x01000000;  /* split transfer */
446	}
447	pI128->mem.rbase_g[CRT_2CON] = tmp;
448        if (mode->Flags & V_DBLSCAN)
449		pI128->DoubleScan = TRUE;
450        else
451		pI128->DoubleScan = FALSE;
452	pI128->mem.rbase_g[CRT_ZOOM] = (pI128->DoubleScan ? 0x00000001 : 0x00000000);
453
454       switch (pI128->bitsPerPixel) {
455#if X_BYTE_ORDER == X_BIG_ENDIAN
456       case 32:
457               pI128->mem.rbase_w[MW0_CTRL] = 0x00060000;
458               break;
459       case 16:
460               pI128->mem.rbase_w[MW0_CTRL] = 0x00020000;
461               break;
462#endif
463       default:
464               pI128->mem.rbase_w[MW0_CTRL] = 0x00000000;
465               break;
466       }
467
468	switch (pI128->MemorySize) {
469		case 2048:
470			pI128->mem.rbase_w[MW0_SZ]   = 0x00000009;
471			break;
472		case 8192:
473			pI128->mem.rbase_w[MW0_SZ]   = 0x0000000B;
474			break;
475		case 8192+4096:
476			/* no break */
477		case 16384:
478			pI128->mem.rbase_w[MW0_SZ]   = 0x0000000C;
479			break;
480		case 16384+4096:
481			/* no break */
482		case 16384+8192:
483			/* no break */
484		case 16384+8192+4096:
485			/* no break */
486		case 32768:
487			pI128->mem.rbase_w[MW0_SZ]   = 0x0000000D;
488			break;
489		case 4096:
490			/* no break */
491		default:
492			pI128->mem.rbase_w[MW0_SZ]   = 0x0000000A;/* default 4MB */
493			break;
494	}
495	pI128->mem.rbase_w[MW0_PGE]  = 0x00000000;
496	pI128->mem.rbase_w[MW0_ORG]  = 0x00000000;
497	pI128->mem.rbase_w[MW0_MSRC] = 0x00000000;
498	pI128->mem.rbase_w[MW0_WKEY] = 0x00000000;
499	pI128->mem.rbase_w[MW0_KDAT] = 0x00000000;
500	pI128->mem.rbase_w[MW0_MASK] = 0xFFFFFFFF;
501									MB;
502
503	if ((pI128->io.id&0x7) > 0 || pI128->Chipset == PCI_CHIP_I128_T2R
504			        || pI128->Chipset == PCI_CHIP_I128_T2R4) {
505
506	   	pI128->io.vga_ctl &= 0x0000FF00;
507   		pI128->io.vga_ctl |= 0x00000082;
508                if (pI128->FlatPanel && (mode->Flags & V_DBLSCAN))
509		   pI128->io.vga_ctl |= 0x00000020;  /* Stretch horizontally */
510   		outl(iR->iobase + 0x30, pI128->io.vga_ctl);
511
512                if (pI128->Chipset == PCI_CHIP_I128_T2R4) {
513                        outl(iR->iobase + 0x24, 0x211BF030);
514			usleep(5000);
515			outl(iR->iobase + 0x24, 0xA11BF030);
516		} else if (pI128->MemoryType == I128_MEMORY_SGRAM) {
517			outl(iR->iobase + 0x24, 0x21089030);
518			usleep(5000);
519			outl(iR->iobase + 0x24, 0xA1089030);
520		}
521	}
522
523	ret = pI128->ProgramDAC(pScrn, mode);
524
525	pI128->InitCursorFlag = TRUE;
526	pI128->Initialized = 1;
527
528        if (pI128->Debug)
529        	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "I128Init complete\n");
530
531	return(ret);
532}
533
534
535static void
536I128SavePalette(I128Ptr pI128)
537{
538   short i;
539
540   pI128->mem.rbase_g[PEL_MASK] = 0xff;					MB;
541
542   if (!pI128->LUTSaved) {
543   	pI128->mem.rbase_g[RD_ADR] = 0x00;				MB;
544   	for (i=0; i<256; i++) {
545   	   pI128->lutorig[i].r = pI128->mem.rbase_g[PAL_DAT];		MB;
546   	   pI128->lutorig[i].g = pI128->mem.rbase_g[PAL_DAT];		MB;
547   	   pI128->lutorig[i].b = pI128->mem.rbase_g[PAL_DAT];		MB;
548   	}
549	pI128->LUTSaved = TRUE;
550   }
551
552}
553
554
555static void
556I128RestorePalette(I128Ptr pI128)
557{
558   int i;
559   /* restore the LUT */
560
561   pI128->mem.rbase_g[PEL_MASK] = 0xff;				MB;
562   pI128->mem.rbase_g[WR_ADR] = 0x00;				MB;
563
564   for (i=0; i<256; i++) {
565      pI128->mem.rbase_g[PAL_DAT] = pI128->lutorig[i].r;		MB;
566      pI128->mem.rbase_g[PAL_DAT] = pI128->lutorig[i].g;		MB;
567      pI128->mem.rbase_g[PAL_DAT] = pI128->lutorig[i].b;		MB;
568   }
569}
570
571
572void
573I128LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
574	VisualPtr pVisual)
575{
576   I128Ptr pI128;
577
578   if (pVisual->nplanes != 8)
579      return;
580
581   pI128 = I128PTR(pScrn);
582
583   pI128->mem.rbase_g[PEL_MASK] = 0xff;					MB;
584
585   while (numColors--) {
586      pI128->mem.rbase_g[WR_ADR] = *indices;				MB;
587      pI128->mem.rbase_g[PAL_DAT] = colors[*indices].red;		MB;
588      pI128->mem.rbase_g[PAL_DAT] = colors[*indices].green;		MB;
589      pI128->mem.rbase_g[PAL_DAT] = colors[*indices].blue;		MB;
590      indices++;
591   }
592}
593