Merge tag 'wireless-drivers-for-davem-2018-04-26' of git://git.kernel.org/pub/scm...
[linux-2.6-block.git] / drivers / staging / xgifb / vb_init.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
949eb0ae 2#include <linux/delay.h>
02a81dd9 3#include <linux/vmalloc.h>
6048d761 4
d7636e0b 5#include "XGIfb.h"
d7636e0b 6#include "vb_def.h"
d7636e0b 7#include "vb_util.h"
8#include "vb_setmode.h"
e054102b 9#include "vb_init.h"
d6461e49
PH
10static const unsigned short XGINew_DDRDRAM_TYPE340[4][2] = {
11 { 16, 0x45},
12 { 8, 0x35},
13 { 4, 0x31},
14 { 2, 0x21} };
15
16static const unsigned short XGINew_DDRDRAM_TYPE20[12][2] = {
17 { 128, 0x5D},
18 { 64, 0x59},
19 { 64, 0x4D},
20 { 32, 0x55},
21 { 32, 0x49},
22 { 32, 0x3D},
23 { 16, 0x51},
24 { 16, 0x45},
25 { 16, 0x39},
26 { 8, 0x41},
27 { 8, 0x35},
28 { 4, 0x31} };
d7636e0b 29
02a81dd9
AK
30#define XGIFB_ROM_SIZE 65536
31
bf32fcb9
KT
32static unsigned char
33XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension,
34 struct vb_device_info *pVBInfo)
d7636e0b 35{
b9ebf5e5 36 unsigned char data, temp;
d7636e0b 37
b9ebf5e5 38 if (HwDeviceExtension->jChipType < XG20) {
6d12dae4
PH
39 data = xgifb_reg_get(pVBInfo->P3c4, 0x39) & 0x02;
40 if (data == 0)
41 data = (xgifb_reg_get(pVBInfo->P3c4, 0x3A) &
42 0x02) >> 1;
43 return data;
b9ebf5e5 44 } else if (HwDeviceExtension->jChipType == XG27) {
58839b01 45 temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B);
bf32fcb9 46 /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
6490311f 47 if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08))
b9ebf5e5
AK
48 data = 0; /* DDR */
49 else
50 data = 1; /* DDRII */
51 return data;
52 } else if (HwDeviceExtension->jChipType == XG21) {
bf32fcb9
KT
53 /* Independent GPIO control */
54 xgifb_reg_and(pVBInfo->P3d4, 0xB4, ~0x02);
d8acac94 55 usleep_range(800, 1800);
b9bf6e4e 56 xgifb_reg_or(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */
bf32fcb9 57 /* GPIOF 0:DVI 1:DVO */
fb70b191 58 data = xgifb_reg_get(pVBInfo->P3d4, 0x48);
bb1243a6
WF
59 /*
60 * HOTPLUG_SUPPORT
61 * for current XG20 & XG21, GPIOH is floating, driver will
288f152c
JR
62 * fix DDR temporarily
63 */
fb70b191
PH
64 /* DVI read GPIOH */
65 data &= 0x01; /* 1=DDRII, 0=DDR */
b9ebf5e5 66 /* ~HOTPLUG_SUPPORT */
b9bf6e4e 67 xgifb_reg_or(pVBInfo->P3d4, 0xB4, 0x02);
b9ebf5e5 68 return data;
9c8c8315
TG
69 }
70 data = xgifb_reg_get(pVBInfo->P3d4, 0x97) & 0x01;
d7636e0b 71
9c8c8315
TG
72 if (data == 1)
73 data++;
d7636e0b 74
9c8c8315 75 return data;
b9ebf5e5 76}
d7636e0b 77
bf32fcb9
KT
78static void XGINew_DDR1x_MRS_340(unsigned long P3c4,
79 struct vb_device_info *pVBInfo)
b9ebf5e5 80{
8104e329
AK
81 xgifb_reg_set(P3c4, 0x18, 0x01);
82 xgifb_reg_set(P3c4, 0x19, 0x20);
83 xgifb_reg_set(P3c4, 0x16, 0x00);
84 xgifb_reg_set(P3c4, 0x16, 0x80);
d7636e0b 85
d8acac94 86 usleep_range(3, 1003);
6d12dae4
PH
87 xgifb_reg_set(P3c4, 0x18, 0x00);
88 xgifb_reg_set(P3c4, 0x19, 0x20);
89 xgifb_reg_set(P3c4, 0x16, 0x00);
90 xgifb_reg_set(P3c4, 0x16, 0x80);
d7636e0b 91
d8acac94 92 usleep_range(60, 1060);
597d96b6 93 xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */
8104e329 94 xgifb_reg_set(P3c4, 0x19, 0x01);
0904f7f3
AK
95 xgifb_reg_set(P3c4, 0x16, 0x03);
96 xgifb_reg_set(P3c4, 0x16, 0x83);
d8acac94 97 usleep_range(1, 1001);
8104e329 98 xgifb_reg_set(P3c4, 0x1B, 0x03);
d8acac94 99 usleep_range(500, 1500);
597d96b6 100 xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */
8104e329 101 xgifb_reg_set(P3c4, 0x19, 0x00);
0904f7f3
AK
102 xgifb_reg_set(P3c4, 0x16, 0x03);
103 xgifb_reg_set(P3c4, 0x16, 0x83);
8104e329 104 xgifb_reg_set(P3c4, 0x1B, 0x00);
b9ebf5e5 105}
d7636e0b 106
b053af16 107static void XGINew_SetMemoryClock(struct vb_device_info *pVBInfo)
b9ebf5e5 108{
bf32fcb9
KT
109 xgifb_reg_set(pVBInfo->P3c4,
110 0x28,
2af1a29d 111 pVBInfo->MCLKData[pVBInfo->ram_type].SR28);
bf32fcb9
KT
112 xgifb_reg_set(pVBInfo->P3c4,
113 0x29,
2af1a29d 114 pVBInfo->MCLKData[pVBInfo->ram_type].SR29);
bf32fcb9
KT
115 xgifb_reg_set(pVBInfo->P3c4,
116 0x2A,
2af1a29d 117 pVBInfo->MCLKData[pVBInfo->ram_type].SR2A);
bf32fcb9
KT
118
119 xgifb_reg_set(pVBInfo->P3c4,
120 0x2E,
9b047458 121 XGI340_ECLKData[pVBInfo->ram_type].SR2E);
bf32fcb9
KT
122 xgifb_reg_set(pVBInfo->P3c4,
123 0x2F,
9b047458 124 XGI340_ECLKData[pVBInfo->ram_type].SR2F);
bf32fcb9
KT
125 xgifb_reg_set(pVBInfo->P3c4,
126 0x30,
9b047458 127 XGI340_ECLKData[pVBInfo->ram_type].SR30);
b9ebf5e5 128}
d7636e0b 129
b9ebf5e5
AK
130static void XGINew_DDRII_Bootup_XG27(
131 struct xgi_hw_device_info *HwDeviceExtension,
132 unsigned long P3c4, struct vb_device_info *pVBInfo)
133{
134 unsigned long P3d4 = P3c4 + 0x10;
694683f6 135
2af1a29d 136 pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
b053af16 137 XGINew_SetMemoryClock(pVBInfo);
d7636e0b 138
b9ebf5e5 139 /* Set Double Frequency */
6d12dae4 140 xgifb_reg_set(P3d4, 0x97, pVBInfo->XGINew_CR97); /* CR97 */
d7636e0b 141
d8acac94 142 usleep_range(200, 1200);
d7636e0b 143
8104e329
AK
144 xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS2 */
145 xgifb_reg_set(P3c4, 0x19, 0x80); /* Set SR19 */
146 xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
d8acac94 147 usleep_range(15, 1015);
8104e329 148 xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
d8acac94 149 usleep_range(15, 1015);
d7636e0b 150
8104e329
AK
151 xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS3 */
152 xgifb_reg_set(P3c4, 0x19, 0xC0); /* Set SR19 */
153 xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
d8acac94 154 usleep_range(15, 1015);
8104e329 155 xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
d8acac94 156 usleep_range(15, 1015);
d7636e0b 157
8104e329
AK
158 xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS1 */
159 xgifb_reg_set(P3c4, 0x19, 0x40); /* Set SR19 */
160 xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
d8acac94 161 usleep_range(30, 1030);
8104e329 162 xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
d8acac94 163 usleep_range(15, 1015);
d7636e0b 164
8104e329
AK
165 xgifb_reg_set(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Enable */
166 xgifb_reg_set(P3c4, 0x19, 0x0A); /* Set SR19 */
167 xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */
d8acac94 168 usleep_range(30, 1030);
8104e329
AK
169 xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */
170 xgifb_reg_set(P3c4, 0x16, 0x80); /* Set SR16 */
d7636e0b 171
8104e329 172 xgifb_reg_set(P3c4, 0x1B, 0x04); /* Set SR1B */
d8acac94 173 usleep_range(60, 1060);
8104e329 174 xgifb_reg_set(P3c4, 0x1B, 0x00); /* Set SR1B */
d7636e0b 175
8104e329
AK
176 xgifb_reg_set(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Reset */
177 xgifb_reg_set(P3c4, 0x19, 0x08); /* Set SR19 */
178 xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */
d7636e0b 179
d8acac94 180 usleep_range(30, 1030);
8104e329 181 xgifb_reg_set(P3c4, 0x16, 0x83); /* Set SR16 */
d8acac94 182 usleep_range(15, 1015);
d7636e0b 183
8104e329
AK
184 xgifb_reg_set(P3c4, 0x18, 0x80); /* Set SR18 */ /* MRS, ODT */
185 xgifb_reg_set(P3c4, 0x19, 0x46); /* Set SR19 */
186 xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
d8acac94 187 usleep_range(30, 1030);
8104e329 188 xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
d8acac94 189 usleep_range(15, 1015);
d7636e0b 190
8104e329
AK
191 xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS */
192 xgifb_reg_set(P3c4, 0x19, 0x40); /* Set SR19 */
193 xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
d8acac94 194 usleep_range(30, 1030);
8104e329 195 xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
d8acac94 196 usleep_range(15, 1015);
d7636e0b 197
bf32fcb9
KT
198 /* Set SR1B refresh control 000:close; 010:open */
199 xgifb_reg_set(P3c4, 0x1B, 0x04);
d8acac94 200 usleep_range(200, 1200);
b9ebf5e5 201}
d7636e0b 202
b9ebf5e5 203static void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension,
945e17ce
WF
204 unsigned long P3c4,
205 struct vb_device_info *pVBInfo)
b9ebf5e5
AK
206{
207 unsigned long P3d4 = P3c4 + 0x10;
d7636e0b 208
2af1a29d 209 pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
b053af16 210 XGINew_SetMemoryClock(pVBInfo);
d7636e0b 211
8104e329 212 xgifb_reg_set(P3d4, 0x97, 0x11); /* CR97 */
d7636e0b 213
d8acac94 214 usleep_range(200, 1200);
8104e329
AK
215 xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS2 */
216 xgifb_reg_set(P3c4, 0x19, 0x80);
217 xgifb_reg_set(P3c4, 0x16, 0x05);
218 xgifb_reg_set(P3c4, 0x16, 0x85);
219
220 xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS3 */
221 xgifb_reg_set(P3c4, 0x19, 0xC0);
222 xgifb_reg_set(P3c4, 0x16, 0x05);
223 xgifb_reg_set(P3c4, 0x16, 0x85);
224
225 xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS1 */
226 xgifb_reg_set(P3c4, 0x19, 0x40);
227 xgifb_reg_set(P3c4, 0x16, 0x05);
228 xgifb_reg_set(P3c4, 0x16, 0x85);
229
8104e329
AK
230 xgifb_reg_set(P3c4, 0x18, 0x42); /* MRS1 */
231 xgifb_reg_set(P3c4, 0x19, 0x02);
232 xgifb_reg_set(P3c4, 0x16, 0x05);
233 xgifb_reg_set(P3c4, 0x16, 0x85);
a24d60f4 234
d8acac94 235 usleep_range(15, 1015);
8104e329 236 xgifb_reg_set(P3c4, 0x1B, 0x04); /* SR1B */
d8acac94 237 usleep_range(30, 1030);
8104e329 238 xgifb_reg_set(P3c4, 0x1B, 0x00); /* SR1B */
d8acac94 239 usleep_range(100, 1100);
a24d60f4 240
8104e329
AK
241 xgifb_reg_set(P3c4, 0x18, 0x42); /* MRS1 */
242 xgifb_reg_set(P3c4, 0x19, 0x00);
243 xgifb_reg_set(P3c4, 0x16, 0x05);
244 xgifb_reg_set(P3c4, 0x16, 0x85);
a24d60f4 245
d8acac94 246 usleep_range(200, 1200);
b9ebf5e5 247}
a24d60f4 248
bf32fcb9
KT
249static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4,
250 struct vb_device_info *pVBInfo)
b9ebf5e5 251{
8104e329
AK
252 xgifb_reg_set(P3c4, 0x18, 0x01);
253 xgifb_reg_set(P3c4, 0x19, 0x40);
254 xgifb_reg_set(P3c4, 0x16, 0x00);
255 xgifb_reg_set(P3c4, 0x16, 0x80);
d8acac94 256 usleep_range(60, 1060);
a24d60f4 257
8104e329
AK
258 xgifb_reg_set(P3c4, 0x18, 0x00);
259 xgifb_reg_set(P3c4, 0x19, 0x40);
260 xgifb_reg_set(P3c4, 0x16, 0x00);
261 xgifb_reg_set(P3c4, 0x16, 0x80);
d8acac94 262 usleep_range(60, 1060);
597d96b6 263 xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */
8104e329
AK
264 xgifb_reg_set(P3c4, 0x19, 0x01);
265 xgifb_reg_set(P3c4, 0x16, 0x03);
266 xgifb_reg_set(P3c4, 0x16, 0x83);
d8acac94 267 usleep_range(1, 1001);
8104e329 268 xgifb_reg_set(P3c4, 0x1B, 0x03);
d8acac94 269 usleep_range(500, 1500);
597d96b6 270 xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */
8104e329
AK
271 xgifb_reg_set(P3c4, 0x19, 0x00);
272 xgifb_reg_set(P3c4, 0x16, 0x03);
273 xgifb_reg_set(P3c4, 0x16, 0x83);
274 xgifb_reg_set(P3c4, 0x1B, 0x00);
b9ebf5e5 275}
a24d60f4 276
b9ebf5e5
AK
277static void XGINew_DDR1x_DefaultRegister(
278 struct xgi_hw_device_info *HwDeviceExtension,
279 unsigned long Port, struct vb_device_info *pVBInfo)
280{
281 unsigned long P3d4 = Port, P3c4 = Port - 0x10;
a24d60f4 282
b9ebf5e5 283 if (HwDeviceExtension->jChipType >= XG20) {
b053af16 284 XGINew_SetMemoryClock(pVBInfo);
bf32fcb9
KT
285 xgifb_reg_set(P3d4,
286 0x82,
2af1a29d 287 pVBInfo->CR40[11][pVBInfo->ram_type]); /* CR82 */
bf32fcb9
KT
288 xgifb_reg_set(P3d4,
289 0x85,
2af1a29d 290 pVBInfo->CR40[12][pVBInfo->ram_type]); /* CR85 */
bf32fcb9
KT
291 xgifb_reg_set(P3d4,
292 0x86,
2af1a29d 293 pVBInfo->CR40[13][pVBInfo->ram_type]); /* CR86 */
a24d60f4 294
8104e329
AK
295 xgifb_reg_set(P3d4, 0x98, 0x01);
296 xgifb_reg_set(P3d4, 0x9A, 0x02);
a24d60f4 297
b9ebf5e5
AK
298 XGINew_DDR1x_MRS_XG20(P3c4, pVBInfo);
299 } else {
b053af16 300 XGINew_SetMemoryClock(pVBInfo);
a24d60f4 301
b9ebf5e5 302 switch (HwDeviceExtension->jChipType) {
b9ebf5e5 303 case XG42:
bf32fcb9
KT
304 /* CR82 */
305 xgifb_reg_set(P3d4,
306 0x82,
2af1a29d 307 pVBInfo->CR40[11][pVBInfo->ram_type]);
bf32fcb9
KT
308 /* CR85 */
309 xgifb_reg_set(P3d4,
310 0x85,
2af1a29d 311 pVBInfo->CR40[12][pVBInfo->ram_type]);
bf32fcb9
KT
312 /* CR86 */
313 xgifb_reg_set(P3d4,
314 0x86,
2af1a29d 315 pVBInfo->CR40[13][pVBInfo->ram_type]);
b9ebf5e5
AK
316 break;
317 default:
8104e329
AK
318 xgifb_reg_set(P3d4, 0x82, 0x88);
319 xgifb_reg_set(P3d4, 0x86, 0x00);
bf32fcb9
KT
320 /* Insert read command for delay */
321 xgifb_reg_get(P3d4, 0x86);
8104e329 322 xgifb_reg_set(P3d4, 0x86, 0x88);
58839b01 323 xgifb_reg_get(P3d4, 0x86);
bf32fcb9
KT
324 xgifb_reg_set(P3d4,
325 0x86,
2af1a29d 326 pVBInfo->CR40[13][pVBInfo->ram_type]);
8104e329
AK
327 xgifb_reg_set(P3d4, 0x82, 0x77);
328 xgifb_reg_set(P3d4, 0x85, 0x00);
bf32fcb9
KT
329
330 /* Insert read command for delay */
331 xgifb_reg_get(P3d4, 0x85);
8104e329 332 xgifb_reg_set(P3d4, 0x85, 0x88);
bf32fcb9
KT
333
334 /* Insert read command for delay */
335 xgifb_reg_get(P3d4, 0x85);
336 /* CR85 */
337 xgifb_reg_set(P3d4,
338 0x85,
2af1a29d 339 pVBInfo->CR40[12][pVBInfo->ram_type]);
bf32fcb9
KT
340 /* CR82 */
341 xgifb_reg_set(P3d4,
342 0x82,
2af1a29d 343 pVBInfo->CR40[11][pVBInfo->ram_type]);
b9ebf5e5 344 break;
a24d60f4 345 }
a24d60f4 346
8104e329
AK
347 xgifb_reg_set(P3d4, 0x97, 0x00);
348 xgifb_reg_set(P3d4, 0x98, 0x01);
349 xgifb_reg_set(P3d4, 0x9A, 0x02);
b9ebf5e5
AK
350 XGINew_DDR1x_MRS_340(P3c4, pVBInfo);
351 }
352}
a24d60f4 353
b9ebf5e5
AK
354static void XGINew_DDR2_DefaultRegister(
355 struct xgi_hw_device_info *HwDeviceExtension,
356 unsigned long Port, struct vb_device_info *pVBInfo)
357{
358 unsigned long P3d4 = Port, P3c4 = Port - 0x10;
bb1243a6
WF
359 /*
360 * keep following setting sequence, each setting in
56e18f8c
CB
361 * the same reg insert idle
362 */
8104e329
AK
363 xgifb_reg_set(P3d4, 0x82, 0x77);
364 xgifb_reg_set(P3d4, 0x86, 0x00);
58839b01 365 xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */
8104e329 366 xgifb_reg_set(P3d4, 0x86, 0x88);
58839b01 367 xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */
bf32fcb9 368 /* CR86 */
2af1a29d 369 xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][pVBInfo->ram_type]);
8104e329
AK
370 xgifb_reg_set(P3d4, 0x82, 0x77);
371 xgifb_reg_set(P3d4, 0x85, 0x00);
58839b01 372 xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */
8104e329 373 xgifb_reg_set(P3d4, 0x85, 0x88);
58839b01 374 xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */
2af1a29d
AK
375 xgifb_reg_set(P3d4,
376 0x85,
377 pVBInfo->CR40[12][pVBInfo->ram_type]); /* CR85 */
b9ebf5e5 378 if (HwDeviceExtension->jChipType == XG27)
bf32fcb9 379 /* CR82 */
2af1a29d 380 xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][pVBInfo->ram_type]);
b9ebf5e5 381 else
8104e329 382 xgifb_reg_set(P3d4, 0x82, 0xA8); /* CR82 */
a24d60f4 383
8104e329
AK
384 xgifb_reg_set(P3d4, 0x98, 0x01);
385 xgifb_reg_set(P3d4, 0x9A, 0x02);
b9ebf5e5
AK
386 if (HwDeviceExtension->jChipType == XG27)
387 XGINew_DDRII_Bootup_XG27(HwDeviceExtension, P3c4, pVBInfo);
388 else
389 XGINew_DDR2_MRS_XG20(HwDeviceExtension, P3c4, pVBInfo);
390}
a24d60f4 391
0141bb2e 392static void XGI_SetDRAM_Helper(unsigned long P3d4, u8 seed, u8 temp2, u8 reg,
945e17ce 393 u8 shift_factor, u8 mask1, u8 mask2)
0141bb2e
PH
394{
395 u8 j;
694683f6 396
0141bb2e
PH
397 for (j = 0; j < 4; j++) {
398 temp2 |= (((seed >> (2 * j)) & 0x03) << shift_factor);
399 xgifb_reg_set(P3d4, reg, temp2);
400 xgifb_reg_get(P3d4, reg);
401 temp2 &= mask1;
402 temp2 += mask2;
403 }
404}
405
b9ebf5e5
AK
406static void XGINew_SetDRAMDefaultRegister340(
407 struct xgi_hw_device_info *HwDeviceExtension,
408 unsigned long Port, struct vb_device_info *pVBInfo)
409{
fc008aff 410 unsigned char temp, temp1, temp2, temp3, j, k;
a24d60f4 411
b9ebf5e5 412 unsigned long P3d4 = Port, P3c4 = Port - 0x10;
a24d60f4 413
2af1a29d
AK
414 xgifb_reg_set(P3d4, 0x6D, pVBInfo->CR40[8][pVBInfo->ram_type]);
415 xgifb_reg_set(P3d4, 0x68, pVBInfo->CR40[5][pVBInfo->ram_type]);
416 xgifb_reg_set(P3d4, 0x69, pVBInfo->CR40[6][pVBInfo->ram_type]);
417 xgifb_reg_set(P3d4, 0x6A, pVBInfo->CR40[7][pVBInfo->ram_type]);
a24d60f4 418
1504ecbe 419 /* CR6B DQS fine tune delay */
6a7fd2db 420 temp = 0xaa;
1504ecbe 421 XGI_SetDRAM_Helper(P3d4, temp, 0, 0x6B, 2, 0xF0, 0x10);
a24d60f4 422
1504ecbe
PH
423 /* CR6E DQM fine tune delay */
424 XGI_SetDRAM_Helper(P3d4, 0, 0, 0x6E, 2, 0xF0, 0x10);
a24d60f4 425
b9ebf5e5
AK
426 temp3 = 0;
427 for (k = 0; k < 4; k++) {
bf32fcb9
KT
428 /* CR6E_D[1:0] select channel */
429 xgifb_reg_and_or(P3d4, 0x6E, 0xFC, temp3);
1504ecbe 430 XGI_SetDRAM_Helper(P3d4, 0, 0, 0x6F, 0, 0xF8, 0x08);
b9ebf5e5
AK
431 temp3 += 0x01;
432 }
a24d60f4 433
2af1a29d
AK
434 xgifb_reg_set(P3d4,
435 0x80,
436 pVBInfo->CR40[9][pVBInfo->ram_type]); /* CR80 */
437 xgifb_reg_set(P3d4,
438 0x81,
439 pVBInfo->CR40[10][pVBInfo->ram_type]); /* CR81 */
a24d60f4 440
b9ebf5e5 441 temp2 = 0x80;
bf32fcb9 442 /* CR89 terminator type select */
0141bb2e 443 XGI_SetDRAM_Helper(P3d4, 0, temp2, 0x89, 0, 0xF0, 0x10);
a24d60f4 444
7e29d632 445 temp = 0;
b9ebf5e5
AK
446 temp1 = temp & 0x03;
447 temp2 |= temp1;
8104e329 448 xgifb_reg_set(P3d4, 0x89, temp2);
a24d60f4 449
2af1a29d 450 temp = pVBInfo->CR40[3][pVBInfo->ram_type];
b9ebf5e5
AK
451 temp1 = temp & 0x0F;
452 temp2 = (temp >> 4) & 0x07;
453 temp3 = temp & 0x80;
8104e329
AK
454 xgifb_reg_set(P3d4, 0x45, temp1); /* CR45 */
455 xgifb_reg_set(P3d4, 0x99, temp2); /* CR99 */
b9bf6e4e 456 xgifb_reg_or(P3d4, 0x40, temp3); /* CR40_D[7] */
2af1a29d
AK
457 xgifb_reg_set(P3d4,
458 0x41,
459 pVBInfo->CR40[0][pVBInfo->ram_type]); /* CR41 */
a24d60f4 460
b9ebf5e5 461 if (HwDeviceExtension->jChipType == XG27)
6d12dae4 462 xgifb_reg_set(P3d4, 0x8F, XG27_CR8F); /* CR8F */
a24d60f4 463
bf32fcb9 464 for (j = 0; j <= 6; j++) /* CR90 - CR96 */
8104e329 465 xgifb_reg_set(P3d4, (0x90 + j),
945e17ce 466 pVBInfo->CR40[14 + j][pVBInfo->ram_type]);
a24d60f4 467
bf32fcb9 468 for (j = 0; j <= 2; j++) /* CRC3 - CRC5 */
8104e329 469 xgifb_reg_set(P3d4, (0xC3 + j),
945e17ce 470 pVBInfo->CR40[21 + j][pVBInfo->ram_type]);
a24d60f4 471
bf32fcb9 472 for (j = 0; j < 2; j++) /* CR8A - CR8B */
8104e329 473 xgifb_reg_set(P3d4, (0x8A + j),
945e17ce 474 pVBInfo->CR40[1 + j][pVBInfo->ram_type]);
a24d60f4 475
18408da0 476 if (HwDeviceExtension->jChipType == XG42)
8104e329 477 xgifb_reg_set(P3d4, 0x8C, 0x87);
a24d60f4 478
2af1a29d
AK
479 xgifb_reg_set(P3d4,
480 0x59,
481 pVBInfo->CR40[4][pVBInfo->ram_type]); /* CR59 */
a24d60f4 482
8104e329
AK
483 xgifb_reg_set(P3d4, 0x83, 0x09); /* CR83 */
484 xgifb_reg_set(P3d4, 0x87, 0x00); /* CR87 */
6d12dae4 485 xgifb_reg_set(P3d4, 0xCF, XG40_CRCF); /* CRCF */
2af1a29d 486 if (pVBInfo->ram_type) {
8104e329 487 xgifb_reg_set(P3c4, 0x17, 0x80); /* SR17 DDRII */
b9ebf5e5 488 if (HwDeviceExtension->jChipType == XG27)
8104e329 489 xgifb_reg_set(P3c4, 0x17, 0x02); /* SR17 DDRII */
a24d60f4 490
b9ebf5e5 491 } else {
8104e329 492 xgifb_reg_set(P3c4, 0x17, 0x00); /* SR17 DDR */
b9ebf5e5 493 }
8104e329 494 xgifb_reg_set(P3c4, 0x1A, 0x87); /* SR1A */
a24d60f4 495
b9ebf5e5
AK
496 temp = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
497 if (temp == 0) {
498 XGINew_DDR1x_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo);
499 } else {
8104e329 500 xgifb_reg_set(P3d4, 0xB0, 0x80); /* DDRII Dual frequency mode */
b9ebf5e5
AK
501 XGINew_DDR2_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo);
502 }
d7ab4a4f 503 xgifb_reg_set(P3c4, 0x1B, 0x03); /* SR1B */
b9ebf5e5 504}
a24d60f4 505
d6461e49
PH
506static unsigned short XGINew_SetDRAMSize20Reg(
507 unsigned short dram_size,
b9ebf5e5 508 struct vb_device_info *pVBInfo)
d7636e0b 509{
b9ebf5e5
AK
510 unsigned short data = 0, memsize = 0;
511 int RankSize;
512 unsigned char ChannelNo;
d7636e0b 513
d6461e49 514 RankSize = dram_size * pVBInfo->ram_bus / 8;
58839b01 515 data = xgifb_reg_get(pVBInfo->P3c4, 0x13);
b9ebf5e5 516 data &= 0x80;
d7636e0b 517
b9ebf5e5
AK
518 if (data == 0x80)
519 RankSize *= 2;
a24d60f4 520
b9ebf5e5 521 data = 0;
a24d60f4 522
ee055a48 523 if (pVBInfo->ram_channel == 3)
b9ebf5e5
AK
524 ChannelNo = 4;
525 else
ee055a48 526 ChannelNo = pVBInfo->ram_channel;
a24d60f4 527
b9ebf5e5
AK
528 if (ChannelNo * RankSize <= 256) {
529 while ((RankSize >>= 1) > 0)
530 data += 0x10;
a24d60f4 531
b9ebf5e5 532 memsize = data >> 4;
a24d60f4 533
949eb0ae 534 /* Fix DRAM Sizing Error */
bf32fcb9
KT
535 xgifb_reg_set(pVBInfo->P3c4,
536 0x14,
537 (xgifb_reg_get(pVBInfo->P3c4, 0x14) & 0x0F) |
538 (data & 0xF0));
d8acac94 539 usleep_range(15, 1015);
b9ebf5e5
AK
540 }
541 return memsize;
542}
a24d60f4 543
b9ebf5e5 544static int XGINew_ReadWriteRest(unsigned short StopAddr,
945e17ce
WF
545 unsigned short StartAddr,
546 struct vb_device_info *pVBInfo)
b9ebf5e5
AK
547{
548 int i;
549 unsigned long Position = 0;
c44fa627 550 void __iomem *fbaddr = pVBInfo->FBAddr;
a24d60f4 551
c44fa627 552 writel(Position, fbaddr + Position);
a24d60f4 553
b9ebf5e5
AK
554 for (i = StartAddr; i <= StopAddr; i++) {
555 Position = 1 << i;
c44fa627 556 writel(Position, fbaddr + Position);
b9ebf5e5 557 }
a24d60f4 558
d3d62d1d
CB
559 /* Fix #1759 Memory Size error in Multi-Adapter. */
560 usleep_range(500, 1500);
a24d60f4 561
b9ebf5e5
AK
562 Position = 0;
563
c44fa627 564 if (readl(fbaddr + Position) != Position)
b9ebf5e5 565 return 0;
d7636e0b 566
b9ebf5e5
AK
567 for (i = StartAddr; i <= StopAddr; i++) {
568 Position = 1 << i;
c44fa627 569 if (readl(fbaddr + Position) != Position)
b9ebf5e5
AK
570 return 0;
571 }
572 return 1;
d7636e0b 573}
a24d60f4 574
b9ebf5e5 575static unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo)
d7636e0b 576{
b9ebf5e5 577 unsigned char data;
a24d60f4 578
58839b01 579 data = xgifb_reg_get(pVBInfo->P3d4, 0x97);
a24d60f4 580
b9ebf5e5 581 if ((data & 0x10) == 0) {
58839b01 582 data = xgifb_reg_get(pVBInfo->P3c4, 0x39);
1f8bb58e 583 return (data & 0x02) >> 1;
b9ebf5e5 584 }
9c8c8315 585 return data & 0x01;
b9ebf5e5 586}
a24d60f4 587
b9ebf5e5 588static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension,
945e17ce 589 struct vb_device_info *pVBInfo)
b9ebf5e5
AK
590{
591 unsigned char data;
a24d60f4 592
b9ebf5e5
AK
593 switch (HwDeviceExtension->jChipType) {
594 case XG20:
595 case XG21:
58839b01 596 data = xgifb_reg_get(pVBInfo->P3d4, 0x97);
b9ebf5e5 597 data = data & 0x01;
ee055a48 598 pVBInfo->ram_channel = 1; /* XG20 "JUST" one channel */
a24d60f4 599
b9ebf5e5 600 if (data == 0) { /* Single_32_16 */
a24d60f4 601
b9ebf5e5
AK
602 if ((HwDeviceExtension->ulVideoMemorySize - 1)
603 > 0x1000000) {
2f0f395e 604 pVBInfo->ram_bus = 32; /* 32 bits */
bf32fcb9
KT
605 /* 22bit + 2 rank + 32bit */
606 xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1);
8104e329 607 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x52);
d8acac94 608 usleep_range(15, 1015);
a24d60f4 609
b9ebf5e5
AK
610 if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
611 return;
d7636e0b 612
bf32fcb9
KT
613 if ((HwDeviceExtension->ulVideoMemorySize - 1) >
614 0x800000) {
615 /* 22bit + 1 rank + 32bit */
616 xgifb_reg_set(pVBInfo->P3c4,
617 0x13,
618 0x31);
619 xgifb_reg_set(pVBInfo->P3c4,
620 0x14,
621 0x42);
d8acac94 622 usleep_range(15, 1015);
a24d60f4 623
bf32fcb9
KT
624 if (XGINew_ReadWriteRest(23,
625 23,
626 pVBInfo) == 1)
b9ebf5e5
AK
627 return;
628 }
629 }
a24d60f4 630
bf32fcb9
KT
631 if ((HwDeviceExtension->ulVideoMemorySize - 1) >
632 0x800000) {
2f0f395e 633 pVBInfo->ram_bus = 16; /* 16 bits */
bf32fcb9
KT
634 /* 22bit + 2 rank + 16bit */
635 xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1);
8104e329 636 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x41);
d8acac94 637 usleep_range(15, 1015);
a24d60f4 638
b9ebf5e5
AK
639 if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
640 return;
9c8c8315
TG
641 xgifb_reg_set(pVBInfo->P3c4,
642 0x13,
643 0x31);
d8acac94 644 usleep_range(15, 1015);
b9ebf5e5 645 }
a24d60f4 646
b9ebf5e5 647 } else { /* Dual_16_8 */
bf32fcb9
KT
648 if ((HwDeviceExtension->ulVideoMemorySize - 1) >
649 0x800000) {
2f0f395e 650 pVBInfo->ram_bus = 16; /* 16 bits */
bf32fcb9
KT
651 /* (0x31:12x8x2) 22bit + 2 rank */
652 xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1);
bb1243a6 653 /* 0x41:16Mx16 bit */
bf32fcb9 654 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x41);
d8acac94 655 usleep_range(15, 1015);
a24d60f4 656
b9ebf5e5
AK
657 if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
658 return;
a24d60f4 659
bf32fcb9
KT
660 if ((HwDeviceExtension->ulVideoMemorySize - 1) >
661 0x400000) {
662 /* (0x31:12x8x2) 22bit + 1 rank */
663 xgifb_reg_set(pVBInfo->P3c4,
664 0x13,
665 0x31);
bb1243a6 666 /* 0x31:8Mx16 bit */
bf32fcb9
KT
667 xgifb_reg_set(pVBInfo->P3c4,
668 0x14,
669 0x31);
d8acac94 670 usleep_range(15, 1015);
a24d60f4 671
bf32fcb9
KT
672 if (XGINew_ReadWriteRest(22,
673 22,
674 pVBInfo) == 1)
b9ebf5e5
AK
675 return;
676 }
677 }
a24d60f4 678
bf32fcb9
KT
679 if ((HwDeviceExtension->ulVideoMemorySize - 1) >
680 0x400000) {
2f0f395e 681 pVBInfo->ram_bus = 8; /* 8 bits */
bf32fcb9
KT
682 /* (0x31:12x8x2) 22bit + 2 rank */
683 xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1);
bb1243a6 684 /* 0x30:8Mx8 bit */
bf32fcb9 685 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x30);
d8acac94 686 usleep_range(15, 1015);
d7636e0b 687
b9ebf5e5
AK
688 if (XGINew_ReadWriteRest(22, 21, pVBInfo) == 1)
689 return;
9c8c8315
TG
690
691 /* (0x31:12x8x2) 22bit + 1 rank */
692 xgifb_reg_set(pVBInfo->P3c4,
693 0x13,
694 0x31);
d8acac94 695 usleep_range(15, 1015);
a24d60f4
PS
696 }
697 }
b9ebf5e5 698 break;
a24d60f4 699
b9ebf5e5 700 case XG27:
2f0f395e 701 pVBInfo->ram_bus = 16; /* 16 bits */
ee055a48 702 pVBInfo->ram_channel = 1; /* Single channel */
bb1243a6 703 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x51); /* 32Mx16 bit */
b9ebf5e5 704 break;
b9ebf5e5
AK
705 case XG42:
706 /*
56e18f8c
CB
707 * XG42 SR14 D[3] Reserve
708 * D[2] = 1, Dual Channel
709 * = 0, Single Channel
710 *
711 * It's Different from Other XG40 Series.
b9ebf5e5
AK
712 */
713 if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII, DDR2x */
2f0f395e 714 pVBInfo->ram_bus = 32; /* 32 bits */
ee055a48 715 pVBInfo->ram_channel = 2; /* 2 Channel */
8104e329
AK
716 xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1);
717 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x44);
a24d60f4 718
b9ebf5e5
AK
719 if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
720 return;
a24d60f4 721
8104e329
AK
722 xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21);
723 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x34);
b9ebf5e5
AK
724 if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
725 return;
a24d60f4 726
ee055a48 727 pVBInfo->ram_channel = 1; /* Single Channel */
8104e329
AK
728 xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1);
729 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x40);
d7636e0b 730
b9ebf5e5
AK
731 if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
732 return;
9c8c8315
TG
733 xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21);
734 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x30);
b9ebf5e5 735 } else { /* DDR */
2f0f395e 736 pVBInfo->ram_bus = 64; /* 64 bits */
ee055a48 737 pVBInfo->ram_channel = 1; /* 1 channels */
8104e329
AK
738 xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1);
739 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x52);
d7636e0b 740
b9ebf5e5
AK
741 if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
742 return;
9c8c8315
TG
743 xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21);
744 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x42);
b9ebf5e5 745 }
d7636e0b 746
b9ebf5e5 747 break;
d7636e0b 748
b9ebf5e5 749 default: /* XG40 */
d7636e0b 750
b9ebf5e5 751 if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII */
2f0f395e 752 pVBInfo->ram_bus = 32; /* 32 bits */
ee055a48 753 pVBInfo->ram_channel = 3;
8104e329
AK
754 xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1);
755 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4C);
d7636e0b 756
b9ebf5e5
AK
757 if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1)
758 return;
d7636e0b 759
ee055a48 760 pVBInfo->ram_channel = 2; /* 2 channels */
8104e329 761 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x48);
a24d60f4 762
b9ebf5e5
AK
763 if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
764 return;
d7636e0b 765
8104e329
AK
766 xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21);
767 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x3C);
d7636e0b 768
b9ebf5e5 769 if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) {
ee055a48 770 pVBInfo->ram_channel = 3; /* 4 channels */
b9ebf5e5 771 } else {
ee055a48 772 pVBInfo->ram_channel = 2; /* 2 channels */
8104e329 773 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x38);
b9ebf5e5
AK
774 }
775 } else { /* DDR */
2f0f395e 776 pVBInfo->ram_bus = 64; /* 64 bits */
ee055a48 777 pVBInfo->ram_channel = 2; /* 2 channels */
8104e329
AK
778 xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1);
779 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x5A);
d7636e0b 780
9c8c8315 781 if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1)
b9ebf5e5 782 return;
9c8c8315
TG
783 xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21);
784 xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4A);
b9ebf5e5
AK
785 }
786 break;
a24d60f4 787 }
d7636e0b 788}
789
b9ebf5e5 790static int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension,
945e17ce 791 struct vb_device_info *pVBInfo)
d7636e0b 792{
672f5ee2
PH
793 u8 i, size;
794 unsigned short memsize, start_addr;
d6461e49 795 const unsigned short (*dram_table)[2];
d7636e0b 796
8104e329
AK
797 xgifb_reg_set(pVBInfo->P3c4, 0x15, 0x00); /* noninterleaving */
798 xgifb_reg_set(pVBInfo->P3c4, 0x1C, 0x00); /* nontiling */
b9ebf5e5 799 XGINew_CheckChannel(HwDeviceExtension, pVBInfo);
d7636e0b 800
b9ebf5e5 801 if (HwDeviceExtension->jChipType >= XG20) {
672f5ee2
PH
802 dram_table = XGINew_DDRDRAM_TYPE20;
803 size = ARRAY_SIZE(XGINew_DDRDRAM_TYPE20);
804 start_addr = 5;
b9ebf5e5 805 } else {
672f5ee2
PH
806 dram_table = XGINew_DDRDRAM_TYPE340;
807 size = ARRAY_SIZE(XGINew_DDRDRAM_TYPE340);
808 start_addr = 9;
809 }
810
811 for (i = 0; i < size; i++) {
4e55d0b3 812 /* SetDRAMSizingType */
d6461e49 813 xgifb_reg_and_or(pVBInfo->P3c4, 0x13, 0x80, dram_table[i][1]);
d8acac94 814 usleep_range(50, 1050); /* should delay 50 ns */
4e55d0b3 815
d6461e49 816 memsize = XGINew_SetDRAMSize20Reg(dram_table[i][0], pVBInfo);
672f5ee2
PH
817
818 if (memsize == 0)
819 continue;
820
821 memsize += (pVBInfo->ram_channel - 2) + 20;
822 if ((HwDeviceExtension->ulVideoMemorySize - 1) <
c3a56f75 823 (unsigned long)(1 << memsize))
672f5ee2
PH
824 continue;
825
826 if (XGINew_ReadWriteRest(memsize, start_addr, pVBInfo) == 1)
827 return 1;
a24d60f4 828 }
b9ebf5e5 829 return 0;
a24d60f4 830}
d7636e0b 831
fab04b97 832static void XGINew_SetDRAMSize_340(struct xgifb_video_info *xgifb_info,
945e17ce
WF
833 struct xgi_hw_device_info *HwDeviceExtension,
834 struct vb_device_info *pVBInfo)
d7636e0b 835{
b9ebf5e5 836 unsigned short data;
a24d60f4 837
b9ebf5e5 838 pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
a24d60f4 839
fab04b97 840 XGISetModeNew(xgifb_info, HwDeviceExtension, 0x2e);
a24d60f4 841
58839b01 842 data = xgifb_reg_get(pVBInfo->P3c4, 0x21);
bf32fcb9 843 /* disable read cache */
c3a56f75 844 xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short)(data & 0xDF));
fab04b97 845 XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
a24d60f4 846
b9ebf5e5 847 XGINew_DDRSizing340(HwDeviceExtension, pVBInfo);
58839b01 848 data = xgifb_reg_get(pVBInfo->P3c4, 0x21);
bf32fcb9 849 /* enable read cache */
c3a56f75 850 xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short)(data | 0x20));
b9ebf5e5 851}
a24d60f4 852
08ce239c 853static u8 *xgifb_copy_rom(struct pci_dev *dev, size_t *rom_size)
02a81dd9
AK
854{
855 void __iomem *rom_address;
82986dd9 856 u8 *rom_copy;
02a81dd9 857
08ce239c 858 rom_address = pci_map_rom(dev, rom_size);
076e2358 859 if (!rom_address)
02a81dd9
AK
860 return NULL;
861
862 rom_copy = vzalloc(XGIFB_ROM_SIZE);
076e2358 863 if (!rom_copy)
02a81dd9
AK
864 goto done;
865
08ce239c
AK
866 *rom_size = min_t(size_t, *rom_size, XGIFB_ROM_SIZE);
867 memcpy_fromio(rom_copy, rom_address, *rom_size);
02a81dd9
AK
868
869done:
870 pci_unmap_rom(dev, rom_address);
871 return rom_copy;
872}
873
334ab072 874static bool xgifb_read_vbios(struct pci_dev *pdev)
b9ebf5e5 875{
02a81dd9 876 struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev);
82986dd9 877 u8 *vbios;
b9ebf5e5 878 unsigned long i;
d1805b38 879 unsigned char j;
97f4532d 880 struct XGI21_LVDSCapStruct *lvds;
08ce239c 881 size_t vbios_size;
d1805b38 882 int entry;
a24d60f4 883
08ce239c 884 vbios = xgifb_copy_rom(pdev, &vbios_size);
076e2358 885 if (!vbios) {
be25aef0 886 dev_err(&pdev->dev, "Video BIOS not available\n");
c0d60da8 887 return false;
02a81dd9 888 }
08ce239c
AK
889 if (vbios_size <= 0x65)
890 goto error;
25aa75f1
AK
891 /*
892 * The user can ignore the LVDS bit in the BIOS and force the display
893 * type.
894 */
895 if (!(vbios[0x65] & 0x1) &&
896 (!xgifb_info->display2_force ||
897 xgifb_info->display2 != XGIFB_DISP_LCD)) {
02a81dd9 898 vfree(vbios);
c0d60da8 899 return false;
02a81dd9 900 }
08ce239c
AK
901 if (vbios_size <= 0x317)
902 goto error;
4b21d990 903 i = vbios[0x316] | (vbios[0x317] << 8);
08ce239c
AK
904 if (vbios_size <= i - 1)
905 goto error;
4b21d990 906 j = vbios[i - 1];
08ce239c
AK
907 if (j == 0)
908 goto error;
bd761274
AK
909 if (j == 0xff)
910 j = 1;
bb1243a6
WF
911
912 /* Read the LVDS table index scratch register set by the BIOS. */
913
d1805b38
AK
914 entry = xgifb_reg_get(xgifb_info->dev_info.P3d4, 0x36);
915 if (entry >= j)
916 entry = 0;
917 i += entry * 25;
fab04b97 918 lvds = &xgifb_info->lvds_data;
d1805b38
AK
919 if (vbios_size <= i + 24)
920 goto error;
921 lvds->LVDS_Capability = vbios[i] | (vbios[i + 1] << 8);
922 lvds->LVDSHT = vbios[i + 2] | (vbios[i + 3] << 8);
923 lvds->LVDSVT = vbios[i + 4] | (vbios[i + 5] << 8);
924 lvds->LVDSHDE = vbios[i + 6] | (vbios[i + 7] << 8);
925 lvds->LVDSVDE = vbios[i + 8] | (vbios[i + 9] << 8);
926 lvds->LVDSHFP = vbios[i + 10] | (vbios[i + 11] << 8);
927 lvds->LVDSVFP = vbios[i + 12] | (vbios[i + 13] << 8);
928 lvds->LVDSHSYNC = vbios[i + 14] | (vbios[i + 15] << 8);
929 lvds->LVDSVSYNC = vbios[i + 16] | (vbios[i + 17] << 8);
930 lvds->VCLKData1 = vbios[i + 18];
931 lvds->VCLKData2 = vbios[i + 19];
932 lvds->PSC_S1 = vbios[i + 20];
933 lvds->PSC_S2 = vbios[i + 21];
934 lvds->PSC_S3 = vbios[i + 22];
935 lvds->PSC_S4 = vbios[i + 23];
936 lvds->PSC_S5 = vbios[i + 24];
02a81dd9 937 vfree(vbios);
c0d60da8 938 return true;
08ce239c 939error:
be25aef0 940 dev_err(&pdev->dev, "Video BIOS corrupted\n");
08ce239c 941 vfree(vbios);
c0d60da8 942 return false;
b9ebf5e5 943}
a24d60f4 944
b053af16 945static void XGINew_ChkSenseStatus(struct vb_device_info *pVBInfo)
b9ebf5e5
AK
946{
947 unsigned short tempbx = 0, temp, tempcx, CR3CData;
a24d60f4 948
58839b01 949 temp = xgifb_reg_get(pVBInfo->P3d4, 0x32);
a24d60f4 950
b9ebf5e5
AK
951 if (temp & Monitor1Sense)
952 tempbx |= ActiveCRT1;
953 if (temp & LCDSense)
954 tempbx |= ActiveLCD;
955 if (temp & Monitor2Sense)
956 tempbx |= ActiveCRT2;
957 if (temp & TVSense) {
958 tempbx |= ActiveTV;
959 if (temp & AVIDEOSense)
960 tempbx |= (ActiveAVideo << 8);
961 if (temp & SVIDEOSense)
962 tempbx |= (ActiveSVideo << 8);
963 if (temp & SCARTSense)
964 tempbx |= (ActiveSCART << 8);
965 if (temp & HiTVSense)
966 tempbx |= (ActiveHiTV << 8);
967 if (temp & YPbPrSense)
968 tempbx |= (ActiveYPbPr << 8);
969 }
a24d60f4 970
58839b01
AK
971 tempcx = xgifb_reg_get(pVBInfo->P3d4, 0x3d);
972 tempcx |= (xgifb_reg_get(pVBInfo->P3d4, 0x3e) << 8);
a24d60f4 973
b9ebf5e5 974 if (tempbx & tempcx) {
58839b01 975 CR3CData = xgifb_reg_get(pVBInfo->P3d4, 0x3c);
3bcc2460 976 if (!(CR3CData & DisplayDeviceFromCMOS))
b9ebf5e5 977 tempcx = 0x1FF0;
b9ebf5e5
AK
978 } else {
979 tempcx = 0x1FF0;
b9ebf5e5 980 }
a24d60f4 981
b9ebf5e5 982 tempbx &= tempcx;
8104e329
AK
983 xgifb_reg_set(pVBInfo->P3d4, 0x3d, (tempbx & 0x00FF));
984 xgifb_reg_set(pVBInfo->P3d4, 0x3e, ((tempbx & 0xFF00) >> 8));
b9ebf5e5 985}
d7636e0b 986
b053af16 987static void XGINew_SetModeScratch(struct vb_device_info *pVBInfo)
b9ebf5e5
AK
988{
989 unsigned short temp, tempcl = 0, tempch = 0, CR31Data, CR38Data;
d7636e0b 990
58839b01
AK
991 temp = xgifb_reg_get(pVBInfo->P3d4, 0x3d);
992 temp |= xgifb_reg_get(pVBInfo->P3d4, 0x3e) << 8;
993 temp |= (xgifb_reg_get(pVBInfo->P3d4, 0x31) & (DriverMode >> 8)) << 8;
d7636e0b 994
b9ebf5e5
AK
995 if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
996 if (temp & ActiveCRT2)
997 tempcl = SetCRT2ToRAMDAC;
998 }
d7636e0b 999
b9ebf5e5
AK
1000 if (temp & ActiveLCD) {
1001 tempcl |= SetCRT2ToLCD;
1002 if (temp & DriverMode) {
1003 if (temp & ActiveTV) {
1004 tempch = SetToLCDA | EnableDualEdge;
1005 temp ^= SetCRT2ToLCD;
d7636e0b 1006
b9ebf5e5
AK
1007 if ((temp >> 8) & ActiveAVideo)
1008 tempcl |= SetCRT2ToAVIDEO;
1009 if ((temp >> 8) & ActiveSVideo)
1010 tempcl |= SetCRT2ToSVIDEO;
1011 if ((temp >> 8) & ActiveSCART)
1012 tempcl |= SetCRT2ToSCART;
a24d60f4 1013
b9ebf5e5
AK
1014 if (pVBInfo->IF_DEF_HiVision == 1) {
1015 if ((temp >> 8) & ActiveHiTV)
599801f9 1016 tempcl |= SetCRT2ToHiVision;
b9ebf5e5 1017 }
a24d60f4 1018
b9ebf5e5
AK
1019 if (pVBInfo->IF_DEF_YPbPr == 1) {
1020 if ((temp >> 8) & ActiveYPbPr)
1021 tempch |= SetYPbPr;
1022 }
1023 }
1024 }
1025 } else {
1026 if ((temp >> 8) & ActiveAVideo)
1027 tempcl |= SetCRT2ToAVIDEO;
1028 if ((temp >> 8) & ActiveSVideo)
1029 tempcl |= SetCRT2ToSVIDEO;
1030 if ((temp >> 8) & ActiveSCART)
1031 tempcl |= SetCRT2ToSCART;
a24d60f4 1032
b9ebf5e5
AK
1033 if (pVBInfo->IF_DEF_HiVision == 1) {
1034 if ((temp >> 8) & ActiveHiTV)
599801f9 1035 tempcl |= SetCRT2ToHiVision;
b9ebf5e5 1036 }
a24d60f4 1037
b9ebf5e5
AK
1038 if (pVBInfo->IF_DEF_YPbPr == 1) {
1039 if ((temp >> 8) & ActiveYPbPr)
1040 tempch |= SetYPbPr;
1041 }
1042 }
d7636e0b 1043
b9ebf5e5 1044 tempcl |= SetSimuScanMode;
49a906a9
WF
1045 if ((!(temp & ActiveCRT1)) && ((temp & ActiveLCD) ||
1046 (temp & ActiveTV) ||
1047 (temp & ActiveCRT2)))
6896b94e 1048 tempcl ^= (SetSimuScanMode | SwitchCRT2);
b9ebf5e5 1049 if ((temp & ActiveLCD) && (temp & ActiveTV))
6896b94e 1050 tempcl ^= (SetSimuScanMode | SwitchCRT2);
8104e329 1051 xgifb_reg_set(pVBInfo->P3d4, 0x30, tempcl);
d7636e0b 1052
58839b01 1053 CR31Data = xgifb_reg_get(pVBInfo->P3d4, 0x31);
b9ebf5e5
AK
1054 CR31Data &= ~(SetNotSimuMode >> 8);
1055 if (!(temp & ActiveCRT1))
1056 CR31Data |= (SetNotSimuMode >> 8);
1057 CR31Data &= ~(DisableCRT2Display >> 8);
1058 if (!((temp & ActiveLCD) || (temp & ActiveTV) || (temp & ActiveCRT2)))
1059 CR31Data |= (DisableCRT2Display >> 8);
8104e329 1060 xgifb_reg_set(pVBInfo->P3d4, 0x31, CR31Data);
d7636e0b 1061
58839b01 1062 CR38Data = xgifb_reg_get(pVBInfo->P3d4, 0x38);
b9ebf5e5
AK
1063 CR38Data &= ~SetYPbPr;
1064 CR38Data |= tempch;
8104e329 1065 xgifb_reg_set(pVBInfo->P3d4, 0x38, CR38Data);
b9ebf5e5 1066}
a24d60f4 1067
40544b04
AK
1068static unsigned short XGINew_SenseLCD(struct xgi_hw_device_info
1069 *HwDeviceExtension,
1070 struct vb_device_info *pVBInfo)
1071{
bcd1f165
PH
1072 unsigned short temp = HwDeviceExtension->ulCRT2LCDType;
1073
1074 switch (HwDeviceExtension->ulCRT2LCDType) {
1075 case LCD_640x480:
1076 case LCD_1024x600:
1077 case LCD_1152x864:
1078 case LCD_1280x960:
1079 case LCD_1152x768:
1080 case LCD_1920x1440:
1081 case LCD_2048x1536:
1082 temp = 0; /* overwrite used ulCRT2LCDType */
1083 break;
1084 case LCD_UNKNOWN: /* unknown lcd, do nothing */
40544b04 1085 return 0;
40544b04 1086 }
bcd1f165
PH
1087 xgifb_reg_and_or(pVBInfo->P3d4, 0x36, 0xF0, temp);
1088 return 1;
40544b04
AK
1089}
1090
c0d60da8 1091static void XGINew_GetXG21Sense(struct pci_dev *pdev,
945e17ce 1092 struct vb_device_info *pVBInfo)
b9ebf5e5 1093{
c0d60da8 1094 struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev);
b9ebf5e5 1095 unsigned char Temp;
a24d60f4 1096
334ab072 1097 if (xgifb_read_vbios(pdev)) { /* For XG21 LVDS */
b9bf6e4e 1098 xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense);
bf32fcb9
KT
1099 /* LVDS on chip */
1100 xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0);
b9ebf5e5 1101 } else {
bb1243a6 1102 /* Enable GPIOA/B read */
bf32fcb9 1103 xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03);
58839b01 1104 Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0xC0;
b9ebf5e5 1105 if (Temp == 0xC0) { /* DVI & DVO GPIOA/B pull high */
c0d60da8 1106 XGINew_SenseLCD(&xgifb_info->hw_info, pVBInfo);
b9bf6e4e 1107 xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense);
bf32fcb9
KT
1108 /* Enable read GPIOF */
1109 xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x20, 0x20);
9195ba09
PH
1110 if (xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x04)
1111 Temp = 0xA0; /* Only DVO on chip */
a24d60f4 1112 else
9195ba09
PH
1113 Temp = 0x80; /* TMDS on chip */
1114 xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, Temp);
bf32fcb9
KT
1115 /* Disable read GPIOF */
1116 xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x20);
a24d60f4 1117 }
b9ebf5e5 1118 }
b9ebf5e5 1119}
a24d60f4 1120
b053af16 1121static void XGINew_GetXG27Sense(struct vb_device_info *pVBInfo)
b9ebf5e5
AK
1122{
1123 unsigned char Temp, bCR4A;
a24d60f4 1124
58839b01 1125 bCR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
bb1243a6 1126 /* Enable GPIOA/B/C read */
bf32fcb9 1127 xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x07, 0x07);
58839b01 1128 Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x07;
8104e329 1129 xgifb_reg_set(pVBInfo->P3d4, 0x4A, bCR4A);
a24d60f4 1130
b9ebf5e5 1131 if (Temp <= 0x02) {
bf32fcb9
KT
1132 /* LVDS setting */
1133 xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0);
8104e329 1134 xgifb_reg_set(pVBInfo->P3d4, 0x30, 0x21);
b9ebf5e5 1135 } else {
bf32fcb9
KT
1136 /* TMDS/DVO setting */
1137 xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0);
b9ebf5e5 1138 }
b9bf6e4e 1139 xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense);
b9ebf5e5 1140}
a24d60f4 1141
b9ebf5e5
AK
1142static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo)
1143{
1144 unsigned char CR38, CR4A, temp;
a24d60f4 1145
58839b01 1146 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
bf32fcb9
KT
1147 /* enable GPIOE read */
1148 xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x10, 0x10);
58839b01 1149 CR38 = xgifb_reg_get(pVBInfo->P3d4, 0x38);
b9ebf5e5
AK
1150 temp = 0;
1151 if ((CR38 & 0xE0) > 0x80) {
58839b01 1152 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
b9ebf5e5
AK
1153 temp &= 0x08;
1154 temp >>= 3;
1155 }
a24d60f4 1156
8104e329 1157 xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
a24d60f4 1158
b9ebf5e5
AK
1159 return temp;
1160}
a24d60f4 1161
b9ebf5e5
AK
1162static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo)
1163{
1164 unsigned char CR4A, temp;
a24d60f4 1165
58839b01 1166 CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
bf32fcb9
KT
1167 /* enable GPIOA/B/C read */
1168 xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03);
58839b01 1169 temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
986eb9fa 1170 if (temp > 2)
2f123cbc 1171 temp = ((temp & 0x04) >> 1) | ((~temp) & 0x01);
a24d60f4 1172
8104e329 1173 xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
a24d60f4 1174
b9ebf5e5
AK
1175 return temp;
1176}
a24d60f4 1177
c976c781
AK
1178static bool xgifb_bridge_is_on(struct vb_device_info *vb_info)
1179{
1180 u8 flag;
1181
1182 flag = xgifb_reg_get(vb_info->Part4Port, 0x00);
1183 return flag == 1 || flag == 2;
1184}
1185
6048d761 1186unsigned char XGIInitNew(struct pci_dev *pdev)
b9ebf5e5 1187{
ab886ff8 1188 struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev);
6048d761 1189 struct xgi_hw_device_info *HwDeviceExtension = &xgifb_info->hw_info;
b9ebf5e5
AK
1190 struct vb_device_info VBINF;
1191 struct vb_device_info *pVBInfo = &VBINF;
1192 unsigned char i, temp = 0, temp1;
a24d60f4 1193
b9ebf5e5 1194 pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
a24d60f4 1195
076e2358 1196 if (!pVBInfo->FBAddr) {
19185703 1197 dev_dbg(&pdev->dev, "pVBInfo->FBAddr == 0\n");
b9ebf5e5
AK
1198 return 0;
1199 }
a24d60f4 1200
56810a92 1201 XGIRegInit(pVBInfo, xgifb_info->vga_base);
d7636e0b 1202
b8e1cc5c
AK
1203 outb(0x67, pVBInfo->P3c2);
1204
b9ebf5e5
AK
1205 InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
1206
949eb0ae 1207 /* Openkey */
8104e329 1208 xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
b9ebf5e5
AK
1209
1210 /* GetXG21Sense (GPIO) */
1211 if (HwDeviceExtension->jChipType == XG21)
c0d60da8 1212 XGINew_GetXG21Sense(pdev, pVBInfo);
b9ebf5e5
AK
1213
1214 if (HwDeviceExtension->jChipType == XG27)
b053af16 1215 XGINew_GetXG27Sense(pVBInfo);
b9ebf5e5 1216
949eb0ae 1217 /* Reset Extended register */
b9ebf5e5
AK
1218
1219 for (i = 0x06; i < 0x20; i++)
8104e329 1220 xgifb_reg_set(pVBInfo->P3c4, i, 0);
b9ebf5e5
AK
1221
1222 for (i = 0x21; i <= 0x27; i++)
8104e329 1223 xgifb_reg_set(pVBInfo->P3c4, i, 0);
b9ebf5e5 1224
06587335 1225 for (i = 0x31; i <= 0x3B; i++)
8104e329 1226 xgifb_reg_set(pVBInfo->P3c4, i, 0);
d7636e0b 1227
949eb0ae 1228 /* Auto over driver for XG42 */
bf32fcb9 1229 if (HwDeviceExtension->jChipType == XG42)
8104e329 1230 xgifb_reg_set(pVBInfo->P3c4, 0x3B, 0xC0);
d7636e0b 1231
b9ebf5e5 1232 for (i = 0x79; i <= 0x7C; i++)
949eb0ae 1233 xgifb_reg_set(pVBInfo->P3d4, i, 0);
d7636e0b 1234
b9ebf5e5 1235 if (HwDeviceExtension->jChipType >= XG20)
6d12dae4 1236 xgifb_reg_set(pVBInfo->P3d4, 0x97, pVBInfo->XGINew_CR97);
a24d60f4 1237
949eb0ae 1238 /* SetDefExt1Regs begin */
6d12dae4 1239 xgifb_reg_set(pVBInfo->P3c4, 0x07, XGI330_SR07);
b9ebf5e5 1240 if (HwDeviceExtension->jChipType == XG27) {
6d12dae4
PH
1241 xgifb_reg_set(pVBInfo->P3c4, 0x40, XG27_SR40);
1242 xgifb_reg_set(pVBInfo->P3c4, 0x41, XG27_SR41);
a24d60f4 1243 }
8104e329 1244 xgifb_reg_set(pVBInfo->P3c4, 0x11, 0x0F);
6d12dae4 1245 xgifb_reg_set(pVBInfo->P3c4, 0x1F, XGI330_SR1F);
949eb0ae 1246 /* Frame buffer can read/write SR20 */
bf32fcb9 1247 xgifb_reg_set(pVBInfo->P3c4, 0x20, 0xA0);
949eb0ae 1248 /* H/W request for slow corner chip */
bf32fcb9 1249 xgifb_reg_set(pVBInfo->P3c4, 0x36, 0x70);
949eb0ae 1250 if (HwDeviceExtension->jChipType == XG27)
6d12dae4 1251 xgifb_reg_set(pVBInfo->P3c4, 0x36, XG27_SR36);
a24d60f4 1252
949eb0ae 1253 if (HwDeviceExtension->jChipType < XG20) {
6048d761
AK
1254 u32 Temp;
1255
06587335
AK
1256 /* Set AGP customize registers (in SetDefAGPRegs) Start */
1257 for (i = 0x47; i <= 0x4C; i++)
bf32fcb9
KT
1258 xgifb_reg_set(pVBInfo->P3d4,
1259 i,
ea12b4e0 1260 XGI340_AGPReg[i - 0x47]);
06587335
AK
1261
1262 for (i = 0x70; i <= 0x71; i++)
bf32fcb9
KT
1263 xgifb_reg_set(pVBInfo->P3d4,
1264 i,
ea12b4e0 1265 XGI340_AGPReg[6 + i - 0x70]);
06587335
AK
1266
1267 for (i = 0x74; i <= 0x77; i++)
bf32fcb9
KT
1268 xgifb_reg_set(pVBInfo->P3d4,
1269 i,
ea12b4e0 1270 XGI340_AGPReg[8 + i - 0x74]);
06587335 1271
6048d761 1272 pci_read_config_dword(pdev, 0x50, &Temp);
06587335
AK
1273 Temp >>= 20;
1274 Temp &= 0xF;
1275
1276 if (Temp == 1)
8104e329 1277 xgifb_reg_set(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */
b9ebf5e5 1278 } /* != XG20 */
a24d60f4 1279
b9ebf5e5 1280 /* Set PCI */
6d12dae4
PH
1281 xgifb_reg_set(pVBInfo->P3c4, 0x23, XGI330_SR23);
1282 xgifb_reg_set(pVBInfo->P3c4, 0x24, XGI330_SR24);
38c09652 1283 xgifb_reg_set(pVBInfo->P3c4, 0x25, 0);
a24d60f4 1284
949eb0ae 1285 if (HwDeviceExtension->jChipType < XG20) {
b9ebf5e5 1286 /* Set VB */
b053af16 1287 XGI_UnLockCRT2(pVBInfo);
949eb0ae 1288 /* disable VideoCapture */
bf32fcb9 1289 xgifb_reg_and_or(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00);
8104e329 1290 xgifb_reg_set(pVBInfo->Part1Port, 0x00, 0x00);
bf32fcb9 1291 /* chk if BCLK>=100MHz */
9388ad9c 1292 temp1 = xgifb_reg_get(pVBInfo->P3d4, 0x7B);
a24d60f4 1293
bf32fcb9 1294 xgifb_reg_set(pVBInfo->Part1Port,
6d12dae4 1295 0x02, XGI330_CRT2Data_1_2);
a24d60f4 1296
8104e329 1297 xgifb_reg_set(pVBInfo->Part1Port, 0x2E, 0x08); /* use VB */
b9ebf5e5 1298 } /* != XG20 */
a24d60f4 1299
8104e329 1300 xgifb_reg_set(pVBInfo->P3c4, 0x27, 0x1F);
b9ebf5e5 1301
bf32fcb9
KT
1302 if ((HwDeviceExtension->jChipType == XG42) &&
1303 XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) != 0) {
1304 /* Not DDR */
1305 xgifb_reg_set(pVBInfo->P3c4,
1306 0x31,
6d12dae4 1307 (XGI330_SR31 & 0x3F) | 0x40);
bf32fcb9
KT
1308 xgifb_reg_set(pVBInfo->P3c4,
1309 0x32,
6d12dae4 1310 (XGI330_SR32 & 0xFC) | 0x01);
a24d60f4 1311 } else {
6d12dae4
PH
1312 xgifb_reg_set(pVBInfo->P3c4, 0x31, XGI330_SR31);
1313 xgifb_reg_set(pVBInfo->P3c4, 0x32, XGI330_SR32);
b9ebf5e5 1314 }
6d12dae4 1315 xgifb_reg_set(pVBInfo->P3c4, 0x33, XGI330_SR33);
a24d60f4 1316
949eb0ae 1317 if (HwDeviceExtension->jChipType < XG20) {
c976c781 1318 if (xgifb_bridge_is_on(pVBInfo)) {
6bc54277
AK
1319 xgifb_reg_set(pVBInfo->Part2Port, 0x00, 0x1C);
1320 xgifb_reg_set(pVBInfo->Part4Port,
1321 0x0D, XGI330_CRT2Data_4_D);
1322 xgifb_reg_set(pVBInfo->Part4Port,
1323 0x0E, XGI330_CRT2Data_4_E);
1324 xgifb_reg_set(pVBInfo->Part4Port,
1325 0x10, XGI330_CRT2Data_4_10);
1326 xgifb_reg_set(pVBInfo->Part4Port, 0x0F, 0x3F);
b053af16 1327 XGI_LockCRT2(pVBInfo);
a24d60f4 1328 }
b9ebf5e5 1329 } /* != XG20 */
a24d60f4 1330
b9ebf5e5 1331 XGI_SenseCRT1(pVBInfo);
d7636e0b 1332
b9ebf5e5 1333 if (HwDeviceExtension->jChipType == XG21) {
bf32fcb9
KT
1334 xgifb_reg_and_or(pVBInfo->P3d4,
1335 0x32,
1336 ~Monitor1Sense,
1337 Monitor1Sense); /* Z9 default has CRT */
b9ebf5e5 1338 temp = GetXG21FPBits(pVBInfo);
ec9e5d3e 1339 xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x01, temp);
a24d60f4 1340 }
b9ebf5e5 1341 if (HwDeviceExtension->jChipType == XG27) {
bf32fcb9
KT
1342 xgifb_reg_and_or(pVBInfo->P3d4,
1343 0x32,
1344 ~Monitor1Sense,
1345 Monitor1Sense); /* Z9 default has CRT */
b9ebf5e5 1346 temp = GetXG27FPBits(pVBInfo);
ec9e5d3e 1347 xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x03, temp);
b9ebf5e5 1348 }
d7636e0b 1349
2af1a29d 1350 pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
d7636e0b 1351
bf32fcb9
KT
1352 XGINew_SetDRAMDefaultRegister340(HwDeviceExtension,
1353 pVBInfo->P3d4,
1354 pVBInfo);
a24d60f4 1355
fab04b97 1356 XGINew_SetDRAMSize_340(xgifb_info, HwDeviceExtension, pVBInfo);
d7636e0b 1357
38c09652
AK
1358 xgifb_reg_set(pVBInfo->P3c4, 0x22, 0xfa);
1359 xgifb_reg_set(pVBInfo->P3c4, 0x21, 0xa3);
d7636e0b 1360
b053af16
AK
1361 XGINew_ChkSenseStatus(pVBInfo);
1362 XGINew_SetModeScratch(pVBInfo);
a24d60f4 1363
8104e329 1364 xgifb_reg_set(pVBInfo->P3d4, 0x8c, 0x87);
d7636e0b 1365
b9ebf5e5
AK
1366 return 1;
1367} /* end of init */