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