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