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