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 
41 static void I128SavePalette(I128Ptr pI128);
42 static void I128RestorePalette(I128Ptr pI128);
43 
44 
45 void
I128SaveState(ScrnInfoPtr pScrn)46 I128SaveState(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 
188 void
I128RestoreState(ScrnInfoPtr pScrn)189 I128RestoreState(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 
360 Bool
I128Init(ScrnInfoPtr pScrn,DisplayModePtr mode)361 I128Init(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 
534 static void
I128SavePalette(I128Ptr pI128)535 I128SavePalette(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 
554 static void
I128RestorePalette(I128Ptr pI128)555 I128RestorePalette(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 
571 void
I128LoadPalette(ScrnInfoPtr pScrn,int numColors,int * indices,LOCO * colors,VisualPtr pVisual)572 I128LoadPalette(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