1 /* Authors: 2 Mark Watson 12/1999, 3 Apsed, 4 Rudolf Cornelissen 10/2002-11/2004 5 */ 6 7 #define MODULE_BIT 0x00008000 8 9 #include "std.h" 10 11 static status_t test_ram(void); 12 static status_t engxx_general_powerup (void); 13 static status_t eng_general_bios_to_powergraphics(void); 14 15 static void eng_dump_configuration_space (void) 16 { 17 #define DUMP_CFG(reg, type) if (si->ps.card_type >= type) do { \ 18 uint32 value = CFGR(reg); \ 19 MSG(("configuration_space 0x%02x %20s 0x%08x\n", \ 20 ENCFG_##reg, #reg, value)); \ 21 } while (0) 22 DUMP_CFG (DEVID, 0); 23 DUMP_CFG (DEVCTRL, 0); 24 DUMP_CFG (CLASS, 0); 25 DUMP_CFG (HEADER, 0); 26 DUMP_CFG (BASE1REGS,0); 27 DUMP_CFG (BASE2FB, 0); 28 DUMP_CFG (BASE3, 0); 29 DUMP_CFG (BASE4, 0); 30 DUMP_CFG (BASE5, 0); 31 DUMP_CFG (BASE6, 0); 32 DUMP_CFG (BASE7, 0); 33 DUMP_CFG (SUBSYSID1,0); 34 DUMP_CFG (ROMBASE, 0); 35 DUMP_CFG (CAPPTR, 0); 36 DUMP_CFG (CFG_1, 0); 37 DUMP_CFG (INTERRUPT,0); 38 DUMP_CFG (SUBSYSID2,0); 39 DUMP_CFG (AGPREF, 0); 40 DUMP_CFG (AGPSTAT, 0); 41 DUMP_CFG (AGPCMD, 0); 42 DUMP_CFG (ROMSHADOW,0); 43 DUMP_CFG (VGA, 0); 44 DUMP_CFG (SCHRATCH, 0); 45 DUMP_CFG (CFG_10, 0); 46 DUMP_CFG (CFG_11, 0); 47 DUMP_CFG (CFG_12, 0); 48 DUMP_CFG (CFG_13, 0); 49 DUMP_CFG (CFG_14, 0); 50 DUMP_CFG (CFG_15, 0); 51 DUMP_CFG (CFG_16, 0); 52 DUMP_CFG (CFG_17, 0); 53 DUMP_CFG (CFG_18, 0); 54 DUMP_CFG (CFG_19, 0); 55 DUMP_CFG (CFG_20, 0); 56 DUMP_CFG (CFG_21, 0); 57 DUMP_CFG (CFG_22, 0); 58 DUMP_CFG (CFG_23, 0); 59 DUMP_CFG (CFG_24, 0); 60 DUMP_CFG (CFG_25, 0); 61 DUMP_CFG (CFG_26, 0); 62 DUMP_CFG (CFG_27, 0); 63 DUMP_CFG (CFG_28, 0); 64 DUMP_CFG (CFG_29, 0); 65 DUMP_CFG (CFG_30, 0); 66 DUMP_CFG (CFG_31, 0); 67 DUMP_CFG (CFG_32, 0); 68 DUMP_CFG (CFG_33, 0); 69 DUMP_CFG (CFG_34, 0); 70 DUMP_CFG (CFG_35, 0); 71 DUMP_CFG (CFG_36, 0); 72 DUMP_CFG (CFG_37, 0); 73 DUMP_CFG (CFG_38, 0); 74 DUMP_CFG (CFG_39, 0); 75 DUMP_CFG (CFG_40, 0); 76 DUMP_CFG (CFG_41, 0); 77 DUMP_CFG (CFG_42, 0); 78 DUMP_CFG (CFG_43, 0); 79 DUMP_CFG (CFG_44, 0); 80 DUMP_CFG (CFG_45, 0); 81 DUMP_CFG (CFG_46, 0); 82 DUMP_CFG (CFG_47, 0); 83 DUMP_CFG (CFG_48, 0); 84 DUMP_CFG (CFG_49, 0); 85 DUMP_CFG (CFG_50, 0); 86 #undef DUMP_CFG 87 } 88 89 status_t eng_general_powerup() 90 { 91 status_t status; 92 93 LOG(1,("POWERUP: Haiku skeleton Accelerant 0.01 running.\n")); 94 95 /* preset no laptop */ 96 si->ps.laptop = false; 97 98 /* detect card type and power it up */ 99 switch(CFGR(DEVID)) 100 { 101 /* Vendor Via */ 102 /* case 0x31221106: 103 si->ps.card_type = NV04; 104 si->ps.card_arch = NV04A; 105 LOG(4,("POWERUP: Detected Nvidia TNT1 (NV04)\n")); 106 status = engxx_general_powerup(); 107 break; 108 */ default: 109 LOG(8,("POWERUP: Failed to detect valid card 0x%08x\n",CFGR(DEVID))); 110 return B_ERROR; 111 } 112 113 return status; 114 } 115 116 static status_t test_ram() 117 { 118 uint32 value, offset; 119 status_t result = B_OK; 120 121 /* make sure we don't corrupt the hardware cursor by using fbc.frame_buffer. */ 122 if (si->fbc.frame_buffer == NULL) 123 { 124 LOG(8,("INIT: test_ram detected NULL pointer.\n")); 125 return B_ERROR; 126 } 127 128 for (offset = 0, value = 0x55aa55aa; offset < 256; offset++) 129 { 130 /* write testpattern to cardRAM */ 131 ((uint32 *)si->fbc.frame_buffer)[offset] = value; 132 /* toggle testpattern */ 133 value = 0xffffffff - value; 134 } 135 136 for (offset = 0, value = 0x55aa55aa; offset < 256; offset++) 137 { 138 /* readback and verify testpattern from cardRAM */ 139 if (((uint32 *)si->fbc.frame_buffer)[offset] != value) result = B_ERROR; 140 /* toggle testpattern */ 141 value = 0xffffffff - value; 142 } 143 return result; 144 } 145 146 /* NOTE: 147 * This routine *has* to be done *after* SetDispplayMode has been executed, 148 * or test results will not be representative! 149 * (CAS latency is dependant on NV setup on some (DRAM) boards) */ 150 status_t eng_set_cas_latency() 151 { 152 status_t result = B_ERROR; 153 uint8 latency = 0; 154 155 /* check current RAM access to see if we need to change anything */ 156 if (test_ram() == B_OK) 157 { 158 LOG(4,("INIT: RAM access OK.\n")); 159 return B_OK; 160 } 161 162 /* check if we read PINS at starttime so we have valid registersettings at our disposal */ 163 if (si->ps.pins_status != B_OK) 164 { 165 LOG(4,("INIT: RAM access errors; not fixable: PINS was not read from cardBIOS.\n")); 166 return B_ERROR; 167 } 168 169 /* OK. We might have a problem, try to fix it now.. */ 170 LOG(4,("INIT: RAM access errors; tuning CAS latency if prudent...\n")); 171 172 switch(si->ps.card_type) 173 { 174 default: 175 LOG(4,("INIT: RAM CAS tuning not implemented for this card, aborting.\n")); 176 return B_OK; 177 break; 178 } 179 if (result == B_OK) 180 LOG(4,("INIT: RAM access OK. CAS latency set to %d cycles.\n", latency)); 181 else 182 LOG(4,("INIT: RAM access not fixable. CAS latency set to %d cycles.\n", latency)); 183 184 return result; 185 } 186 187 void setup_virtualized_heads(bool cross) 188 { 189 if (cross) 190 { 191 head1_validate_timing = (crtc_validate_timing) eng_crtc2_validate_timing; 192 head1_set_timing = (crtc_set_timing) eng_crtc2_set_timing; 193 head1_depth = (crtc_depth) eng_crtc2_depth; 194 head1_dpms = (crtc_dpms) eng_crtc2_dpms; 195 head1_dpms_fetch = (crtc_dpms_fetch) eng_crtc2_dpms_fetch; 196 head1_set_display_pitch = (crtc_set_display_pitch) eng_crtc2_set_display_pitch; 197 head1_set_display_start = (crtc_set_display_start) eng_crtc2_set_display_start; 198 head1_cursor_init = (crtc_cursor_init) eng_crtc2_cursor_init; 199 head1_cursor_show = (crtc_cursor_show) eng_crtc2_cursor_show; 200 head1_cursor_hide = (crtc_cursor_hide) eng_crtc2_cursor_hide; 201 head1_cursor_define = (crtc_cursor_define) eng_crtc2_cursor_define; 202 head1_cursor_position = (crtc_cursor_position) eng_crtc2_cursor_position; 203 204 head1_mode = (dac_mode) eng_dac2_mode; 205 head1_palette = (dac_palette) eng_dac2_palette; 206 head1_set_pix_pll = (dac_set_pix_pll) eng_dac2_set_pix_pll; 207 head1_pix_pll_find = (dac_pix_pll_find) eng_dac2_pix_pll_find; 208 209 head2_validate_timing = (crtc_validate_timing) eng_crtc_validate_timing; 210 head2_set_timing = (crtc_set_timing) eng_crtc_set_timing; 211 head2_depth = (crtc_depth) eng_crtc_depth; 212 head2_dpms = (crtc_dpms) eng_crtc_dpms; 213 head2_dpms_fetch = (crtc_dpms_fetch) eng_crtc_dpms_fetch; 214 head2_set_display_pitch = (crtc_set_display_pitch) eng_crtc_set_display_pitch; 215 head2_set_display_start = (crtc_set_display_start) eng_crtc_set_display_start; 216 head2_cursor_init = (crtc_cursor_init) eng_crtc_cursor_init; 217 head2_cursor_show = (crtc_cursor_show) eng_crtc_cursor_show; 218 head2_cursor_hide = (crtc_cursor_hide) eng_crtc_cursor_hide; 219 head2_cursor_define = (crtc_cursor_define) eng_crtc_cursor_define; 220 head2_cursor_position = (crtc_cursor_position) eng_crtc_cursor_position; 221 222 head2_mode = (dac_mode) eng_dac_mode; 223 head2_palette = (dac_palette) eng_dac_palette; 224 head2_set_pix_pll = (dac_set_pix_pll) eng_dac_set_pix_pll; 225 head2_pix_pll_find = (dac_pix_pll_find) eng_dac_pix_pll_find; 226 } 227 else 228 { 229 head1_validate_timing = (crtc_validate_timing) eng_crtc_validate_timing; 230 head1_set_timing = (crtc_set_timing) eng_crtc_set_timing; 231 head1_depth = (crtc_depth) eng_crtc_depth; 232 head1_dpms = (crtc_dpms) eng_crtc_dpms; 233 head1_dpms_fetch = (crtc_dpms_fetch) eng_crtc_dpms_fetch; 234 head1_set_display_pitch = (crtc_set_display_pitch) eng_crtc_set_display_pitch; 235 head1_set_display_start = (crtc_set_display_start) eng_crtc_set_display_start; 236 head1_cursor_init = (crtc_cursor_init) eng_crtc_cursor_init; 237 head1_cursor_show = (crtc_cursor_show) eng_crtc_cursor_show; 238 head1_cursor_hide = (crtc_cursor_hide) eng_crtc_cursor_hide; 239 head1_cursor_define = (crtc_cursor_define) eng_crtc_cursor_define; 240 head1_cursor_position = (crtc_cursor_position) eng_crtc_cursor_position; 241 242 head1_mode = (dac_mode) eng_dac_mode; 243 head1_palette = (dac_palette) eng_dac_palette; 244 head1_set_pix_pll = (dac_set_pix_pll) eng_dac_set_pix_pll; 245 head1_pix_pll_find = (dac_pix_pll_find) eng_dac_pix_pll_find; 246 247 head2_validate_timing = (crtc_validate_timing) eng_crtc2_validate_timing; 248 head2_set_timing = (crtc_set_timing) eng_crtc2_set_timing; 249 head2_depth = (crtc_depth) eng_crtc2_depth; 250 head2_dpms = (crtc_dpms) eng_crtc2_dpms; 251 head2_dpms_fetch = (crtc_dpms_fetch) eng_crtc2_dpms_fetch; 252 head2_set_display_pitch = (crtc_set_display_pitch) eng_crtc2_set_display_pitch; 253 head2_set_display_start = (crtc_set_display_start) eng_crtc2_set_display_start; 254 head2_cursor_init = (crtc_cursor_init) eng_crtc2_cursor_init; 255 head2_cursor_show = (crtc_cursor_show) eng_crtc2_cursor_show; 256 head2_cursor_hide = (crtc_cursor_hide) eng_crtc2_cursor_hide; 257 head2_cursor_define = (crtc_cursor_define) eng_crtc2_cursor_define; 258 head2_cursor_position = (crtc_cursor_position) eng_crtc2_cursor_position; 259 260 head2_mode = (dac_mode) eng_dac2_mode; 261 head2_palette = (dac_palette) eng_dac2_palette; 262 head2_set_pix_pll = (dac_set_pix_pll) eng_dac2_set_pix_pll; 263 head2_pix_pll_find = (dac_pix_pll_find) eng_dac2_pix_pll_find; 264 } 265 } 266 267 void set_crtc_owner(bool head) 268 { 269 if (si->ps.secondary_head) 270 { 271 if (!head) 272 { 273 /* note: 'OWNER' is a non-standard register in behaviour(!) on NV11's, 274 * while non-NV11 cards behave normally. 275 * 276 * Double-write action needed on those strange NV11 cards: */ 277 /* RESET: needed on NV11 */ 278 CRTCW(OWNER, 0xff); 279 /* enable access to CRTC1, SEQ1, GRPH1, ATB1, ??? */ 280 CRTCW(OWNER, 0x00); 281 } 282 else 283 { 284 /* note: 'OWNER' is a non-standard register in behaviour(!) on NV11's, 285 * while non-NV11 cards behave normally. 286 * 287 * Double-write action needed on those strange NV11 cards: */ 288 /* RESET: needed on NV11 */ 289 CRTC2W(OWNER, 0xff); 290 /* enable access to CRTC2, SEQ2, GRPH2, ATB2, ??? */ 291 CRTC2W(OWNER, 0x03); 292 } 293 } 294 } 295 296 static status_t engxx_general_powerup() 297 { 298 LOG(4, ("INIT: card powerup\n")); 299 300 /* setup cardspecs */ 301 /* note: 302 * this MUST be done before the driver attempts a card coldstart */ 303 set_specs(); 304 305 /* only process BIOS for finetuning specs and coldstarting card if requested 306 * by the user; 307 * note: 308 * this in fact frees the driver from relying on the BIOS to be executed 309 * at system power-up POST time. */ 310 if (!si->settings.usebios) 311 { 312 LOG(2, ("INIT: Attempting card coldstart!\n")); 313 /* update the cardspecs in the shared_info PINS struct according to reported 314 * specs as much as is possible; 315 * this also coldstarts the card if possible (executes BIOS CMD script(s)) */ 316 // parse_pins(); 317 } 318 else 319 { 320 LOG(2, ("INIT: Skipping card coldstart!\n")); 321 } 322 323 /* get RAM size and fake panel startup (panel init code is still missing) */ 324 fake_panel_start(); 325 326 /* log the final card specifications */ 327 dump_pins(); 328 329 /* dump config space as it is after a possible coldstart attempt */ 330 if (si->settings.logmask & 0x80000000) eng_dump_configuration_space(); 331 332 /* setup CRTC and DAC functions access: determined in fake_panel_start */ 333 setup_virtualized_heads(si->ps.crtc2_prim); 334 335 /* do powerup needed from pre-inited card state as done by system POST cardBIOS 336 * execution or driver coldstart above */ 337 return eng_general_bios_to_powergraphics(); 338 } 339 340 /* this routine switches the CRTC/DAC sets to 'connectors', but only for analog 341 * outputs. We need this to make sure the analog 'switch' is set in the same way the 342 * digital 'switch' is set by the BIOS or we might not be able to use dualhead. */ 343 status_t eng_general_output_select(bool cross) 344 { 345 /* make sure this call is warranted */ 346 if (si->ps.secondary_head) 347 { 348 /* NV11 cards can't switch heads (confirmed) */ 349 if (si->ps.card_type != NV11) 350 { 351 if (cross) 352 { 353 LOG(4,("INIT: switching analog outputs to be cross-connected\n")); 354 355 /* enable head 2 on connector 1 */ 356 /* (b8 = select CRTC (head) for output, 357 * b4 = ??? (confirmed not to be a FP switch), 358 * b0 = enable CRT) */ 359 DACW(OUTPUT, 0x00000101); 360 /* enable head 1 on connector 2 */ 361 DAC2W(OUTPUT, 0x00000001); 362 } 363 else 364 { 365 LOG(4,("INIT: switching analog outputs to be straight-through\n")); 366 367 /* enable head 1 on connector 1 */ 368 DACW(OUTPUT, 0x00000001); 369 /* enable head 2 on connector 2 */ 370 DAC2W(OUTPUT, 0x00000101); 371 } 372 } 373 else 374 { 375 LOG(4,("INIT: NV11 analog outputs are hardwired to be straight-through\n")); 376 } 377 return B_OK; 378 } 379 else 380 { 381 return B_ERROR; 382 } 383 } 384 385 /* this routine switches CRTC/DAC set use. We need this because it's unknown howto 386 * switch digital panels to/from a specific CRTC/DAC set. */ 387 status_t eng_general_head_select(bool cross) 388 { 389 /* make sure this call is warranted */ 390 if (si->ps.secondary_head) 391 { 392 /* invert CRTC/DAC use to do switching */ 393 if (cross) 394 { 395 LOG(4,("INIT: switching CRTC/DAC use to be cross-connected\n")); 396 si->crtc_switch_mode = !si->ps.crtc2_prim; 397 } 398 else 399 { 400 LOG(4,("INIT: switching CRTC/DAC use to be straight-through\n")); 401 si->crtc_switch_mode = si->ps.crtc2_prim; 402 } 403 /* update CRTC and DAC functions access */ 404 setup_virtualized_heads(si->crtc_switch_mode); 405 406 return B_OK; 407 } 408 else 409 { 410 return B_ERROR; 411 } 412 } 413 414 /* basic change of card state from VGA to enhanced mode: 415 * Should work from VGA BIOS POST init state. */ 416 static status_t eng_general_bios_to_powergraphics() 417 { 418 /* let acc engine make power off/power on cycle to start 'fresh' */ 419 // ENG_RG32(RG32_PWRUPCTRL) = 0x13110011; 420 snooze(1000); 421 422 /* power-up all hardware function blocks */ 423 /* bit 28: OVERLAY ENGINE (BES), 424 * bit 25: CRTC2, (> NV04A) 425 * bit 24: CRTC1, 426 * bit 20: framebuffer, 427 * bit 16: PPMI, 428 * bit 12: PGRAPH, 429 * bit 8: PFIFO, 430 * bit 4: PMEDIA, 431 * bit 0: TVOUT. (> NV04A) */ 432 // ENG_RG32(RG32_PWRUPCTRL) = 0x13111111; 433 434 /* select colormode CRTC registers base adresses */ 435 // ENG_REG8(RG8_MISCW) = 0xcb; 436 437 /* enable access to primary head */ 438 // set_crtc_owner(0); 439 /* unlock head's registers for R/W access */ 440 // CRTCW(LOCK, 0x57); 441 // CRTCW(VSYNCE ,(CRTCR(VSYNCE) & 0x7f)); 442 // if (si->ps.secondary_head) 443 if (0) 444 { 445 /* enable access to secondary head */ 446 set_crtc_owner(1); 447 /* unlock head's registers for R/W access */ 448 CRTC2W(LOCK, 0x57); 449 CRTC2W(VSYNCE ,(CRTCR(VSYNCE) & 0x7f)); 450 } 451 452 /* turn off both displays and the hardcursors (also disables transfers) */ 453 // head1_dpms(false, false, false); 454 // head1_cursor_hide(); 455 // if (si->ps.secondary_head) 456 if (0) 457 { 458 // head2_dpms(false, false, false); 459 // head2_cursor_hide(); 460 } 461 462 // if (si->ps.secondary_head) 463 if (0) 464 { 465 /* switch overlay engine to CRTC1 */ 466 /* bit 17: GPU FP port #1 (confirmed NV25, NV28, confirmed not on NV34), 467 * bit 16: GPU FP port #2 (confirmed NV25, NV28, NV34), 468 * bit 12: overlay engine (all cards), 469 * bit 9: TVout chip #2 (confirmed on NV18, NV25, NV28), 470 * bit 8: TVout chip #1 (all cards), 471 * bit 4: both I2C busses (all cards) */ 472 ENG_RG32(RG32_2FUNCSEL) &= ~0x00001000; 473 ENG_RG32(RG32_FUNCSEL) |= 0x00001000; 474 } 475 si->overlay.crtc = false; 476 477 /* enable 'enhanced' mode on primary head: */ 478 /* enable access to primary head */ 479 // set_crtc_owner(0); 480 /* note: 'BUFFER' is a non-standard register in behaviour(!) on most 481 * NV11's like the GeForce2 MX200, while the MX400 and non-NV11 cards 482 * behave normally. 483 * Also readback is not nessesarily what was written before! 484 * 485 * Double-write action needed on those strange NV11 cards: */ 486 /* RESET: don't doublebuffer CRTC access: set programmed values immediately... */ 487 // CRTCW(BUFFER, 0xff); 488 /* ... and use fine pitched CRTC granularity on > NV4 cards (b2 = 0) */ 489 /* note: this has no effect on possible bandwidth issues. */ 490 // CRTCW(BUFFER, 0xfb); 491 /* select VGA mode (old VGA register) */ 492 // CRTCW(MODECTL, 0xc3); 493 /* select graphics mode (old VGA register) */ 494 // SEQW(MEMMODE, 0x0e); 495 /* select 8 dots character clocks (old VGA register) */ 496 // SEQW(CLKMODE, 0x21); 497 /* select VGA mode (old VGA register) */ 498 // GRPHW(MODE, 0x00); 499 /* select graphics mode (old VGA register) */ 500 // GRPHW(MISC, 0x01); 501 /* select graphics mode (old VGA register) */ 502 // ATBW(MODECTL, 0x01); 503 /* enable 'enhanced mode', enable Vsync & Hsync, 504 * set DAC palette to 8-bit width, disable large screen */ 505 // CRTCW(REPAINT1, 0x04); 506 507 /* enable 'enhanced' mode on secondary head: */ 508 // if (si->ps.secondary_head) 509 if (0) 510 { 511 /* enable access to secondary head */ 512 set_crtc_owner(1); 513 /* select colormode CRTC2 registers base adresses */ 514 ENG_REG8(RG8_MISCW) = 0xcb; 515 /* note: 'BUFFER' is a non-standard register in behaviour(!) on most 516 * NV11's like the GeForce2 MX200, while the MX400 and non-NV11 cards 517 * behave normally. 518 * Also readback is not nessesarily what was written before! 519 * 520 * Double-write action needed on those strange NV11 cards: */ 521 /* RESET: don't doublebuffer CRTC2 access: set programmed values immediately... */ 522 CRTC2W(BUFFER, 0xff); 523 /* ... and use fine pitched CRTC granularity on > NV4 cards (b2 = 0) */ 524 /* note: this has no effect on possible bandwidth issues. */ 525 CRTC2W(BUFFER, 0xfb); 526 /* select VGA mode (old VGA register) */ 527 CRTC2W(MODECTL, 0xc3); 528 /* select graphics mode (old VGA register) */ 529 SEQW(MEMMODE, 0x0e); 530 /* select 8 dots character clocks (old VGA register) */ 531 SEQW(CLKMODE, 0x21); 532 /* select VGA mode (old VGA register) */ 533 GRPHW(MODE, 0x00); 534 /* select graphics mode (old VGA register) */ 535 GRPHW(MISC, 0x01); 536 /* select graphics mode (old VGA register) */ 537 ATB2W(MODECTL, 0x01); 538 /* enable 'enhanced mode', enable Vsync & Hsync, 539 * set DAC palette to 8-bit width, disable large screen */ 540 CRTC2W(REPAINT1, 0x04); 541 } 542 543 /* enable palettes */ 544 // DACW(GENCTRL, 0x00100100); 545 // if (si->ps.secondary_head) DAC2W(GENCTRL, 0x00100100); 546 547 /* enable programmable PLLs */ 548 // DACW(PLLSEL, 0x10000700); 549 // if (si->ps.secondary_head) DACW(PLLSEL, (DACR(PLLSEL) | 0x20000800)); 550 551 /* turn on DAC and make sure detection testsignal routing is disabled 552 * (b16 = disable DAC, 553 * b12 = enable testsignal output */ 554 // DACW(TSTCTRL, (DACR(TSTCTRL) & 0xfffeefff)); 555 /* turn on DAC2 if it exists 556 * (NOTE: testsignal function block resides in DAC1 only (!)) */ 557 // if (si->ps.secondary_head) DAC2W(TSTCTRL, (DAC2R(TSTCTRL) & 0xfffeefff)); 558 559 /* setup AGP: 560 * Note: 561 * This may only be done when no transfers are in progress on the bus, so now 562 * is probably a good time.. */ 563 eng_agp_setup(); 564 565 /* turn screen one on */ 566 // head1_dpms(true, true, true); 567 568 return B_OK; 569 } 570 571 /* Check if mode virtual_size adheres to the cards _maximum_ contraints, and modify 572 * virtual_size to the nearest valid maximum for the mode on the card if not so. 573 * Also: check if virtual_width adheres to the cards granularity constraints, and 574 * create mode slopspace if not so. 575 * We use acc or crtc granularity constraints based on the 'worst case' scenario. 576 * 577 * Mode slopspace is reflected in fbc->bytes_per_row BTW. */ 578 status_t eng_general_validate_pic_size (display_mode *target, uint32 *bytes_per_row, bool *acc_mode) 579 { 580 uint32 video_pitch; 581 uint32 acc_mask, crtc_mask; 582 uint32 max_crtc_width, max_acc_width; 583 uint8 depth = 8; 584 585 /* determine pixel multiple based on 2D/3D engine constraints */ 586 switch (si->ps.card_arch) 587 { 588 default: 589 /* confirmed for: 590 * TNT1, TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForceFX 5200 */ 591 switch (target->space) 592 { 593 case B_CMAP8: acc_mask = 0x0f; depth = 8; break; 594 case B_RGB15: acc_mask = 0x07; depth = 16; break; 595 case B_RGB16: acc_mask = 0x07; depth = 16; break; 596 case B_RGB24: acc_mask = 0x0f; depth = 24; break; 597 case B_RGB32: acc_mask = 0x03; depth = 32; break; 598 default: 599 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 600 return B_ERROR; 601 } 602 /* NV31 (confirmed GeForceFX 5600) has NV20A granularity! 603 * So let it fall through... */ 604 if (si->ps.card_type != NV31) break; 605 case NV20A: 606 /* confirmed for: 607 * GeForce4 Ti4200 */ 608 switch (target->space) 609 { 610 case B_CMAP8: acc_mask = 0x3f; depth = 8; break; 611 case B_RGB15: acc_mask = 0x1f; depth = 16; break; 612 case B_RGB16: acc_mask = 0x1f; depth = 16; break; 613 case B_RGB24: acc_mask = 0x3f; depth = 24; break; 614 case B_RGB32: acc_mask = 0x0f; depth = 32; break; 615 default: 616 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 617 return B_ERROR; 618 } 619 break; 620 } 621 622 /* determine pixel multiple based on CRTC memory pitch constraints: 623 * -> all NV cards have same granularity constraints on CRTC1 and CRTC2, 624 * provided that the CRTC1 and CRTC2 BUFFER register b2 = 0; 625 * 626 * (Note: Don't mix this up with CRTC timing contraints! Those are 627 * multiples of 8 for horizontal, 1 for vertical timing.) */ 628 switch (si->ps.card_type) 629 { 630 default: 631 // case NV04: 632 /* confirmed for: 633 * TNT1 always; 634 * TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForce4 Ti4200, 635 * GeForceFX 5200: if the CRTC1 (and CRTC2) BUFFER register b2 = 0 */ 636 /* NOTE: 637 * Unfortunately older cards have a hardware fault that prevents use. 638 * We need doubled granularity on those to prevent the single top line 639 * from shifting to the left! 640 * This is confirmed for TNT2, GeForce2 MX200, GeForce2 MX400. 641 * Confirmed OK are: 642 * GeForce4 MX440, GeForce4 Ti4200, GeForceFX 5200. */ 643 switch (target->space) 644 { 645 case B_CMAP8: crtc_mask = 0x0f; break; /* 0x07 */ 646 case B_RGB15: crtc_mask = 0x07; break; /* 0x03 */ 647 case B_RGB16: crtc_mask = 0x07; break; /* 0x03 */ 648 case B_RGB24: crtc_mask = 0x0f; break; /* 0x07 */ 649 case B_RGB32: crtc_mask = 0x03; break; /* 0x01 */ 650 default: 651 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 652 return B_ERROR; 653 } 654 break; 655 // default: 656 /* confirmed for: 657 * TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForce4 Ti4200, 658 * GeForceFX 5200: if the CRTC1 (and CRTC2) BUFFER register b2 = 1 */ 659 /* switch (target->space) 660 { 661 case B_CMAP8: crtc_mask = 0x1f; break; 662 case B_RGB15: crtc_mask = 0x0f; break; 663 case B_RGB16: crtc_mask = 0x0f; break; 664 case B_RGB24: crtc_mask = 0x1f; break; 665 case B_RGB32: crtc_mask = 0x07; break; 666 default: 667 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 668 return B_ERROR; 669 } 670 break; 671 */ } 672 673 /* set virtual_width limit for accelerated modes */ 674 switch (si->ps.card_arch) 675 { 676 case NV04A: 677 /* confirmed for: 678 * TNT1, TNT2, TNT2-M64 */ 679 switch(target->space) 680 { 681 case B_CMAP8: max_acc_width = 8176; break; 682 case B_RGB15: max_acc_width = 4088; break; 683 case B_RGB16: max_acc_width = 4088; break; 684 case B_RGB24: max_acc_width = 2720; break; 685 case B_RGB32: max_acc_width = 2044; break; 686 default: 687 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 688 return B_ERROR; 689 } 690 break; 691 default: 692 /* confirmed for: 693 * GeForce2 MX400, GeForce4 MX440, GeForceFX 5200 */ 694 switch(target->space) 695 { 696 case B_CMAP8: max_acc_width = 16368; break; 697 case B_RGB15: max_acc_width = 8184; break; 698 case B_RGB16: max_acc_width = 8184; break; 699 case B_RGB24: max_acc_width = 5456; break; 700 case B_RGB32: max_acc_width = 4092; break; 701 default: 702 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 703 return B_ERROR; 704 } 705 /* NV31 (confirmed GeForceFX 5600) has NV20A granularity! 706 * So let it fall through... */ 707 if (si->ps.card_type != NV31) break; 708 case NV20A: 709 /* confirmed for: 710 * GeForce4 Ti4200 */ 711 switch(target->space) 712 { 713 case B_CMAP8: max_acc_width = 16320; break; 714 case B_RGB15: max_acc_width = 8160; break; 715 case B_RGB16: max_acc_width = 8160; break; 716 case B_RGB24: max_acc_width = 5440; break; 717 case B_RGB32: max_acc_width = 4080; break; 718 default: 719 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 720 return B_ERROR; 721 } 722 break; 723 } 724 725 /* set virtual_width limit for unaccelerated modes */ 726 switch (si->ps.card_type) 727 { 728 default: 729 // case NV04: 730 /* confirmed for: 731 * TNT1 always; 732 * TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForce4 Ti4200, 733 * GeForceFX 5200: if the CRTC1 (and CRTC2) BUFFER register b2 = 0 */ 734 /* NOTE: 735 * Unfortunately older cards have a hardware fault that prevents use. 736 * We need doubled granularity on those to prevent the single top line 737 * from shifting to the left! 738 * This is confirmed for TNT2, GeForce2 MX200, GeForce2 MX400. 739 * Confirmed OK are: 740 * GeForce4 MX440, GeForce4 Ti4200, GeForceFX 5200. */ 741 switch(target->space) 742 { 743 case B_CMAP8: max_crtc_width = 16368; break; /* 16376 */ 744 case B_RGB15: max_crtc_width = 8184; break; /* 8188 */ 745 case B_RGB16: max_crtc_width = 8184; break; /* 8188 */ 746 case B_RGB24: max_crtc_width = 5456; break; /* 5456 */ 747 case B_RGB32: max_crtc_width = 4092; break; /* 4094 */ 748 default: 749 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 750 return B_ERROR; 751 } 752 break; 753 // default: 754 /* confirmed for: 755 * TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForce4 Ti4200, 756 * GeForceFX 5200: if the CRTC1 (and CRTC2) BUFFER register b2 = 1 */ 757 /* switch(target->space) 758 { 759 case B_CMAP8: max_crtc_width = 16352; break; 760 case B_RGB15: max_crtc_width = 8176; break; 761 case B_RGB16: max_crtc_width = 8176; break; 762 case B_RGB24: max_crtc_width = 5440; break; 763 case B_RGB32: max_crtc_width = 4088; break; 764 default: 765 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 766 return B_ERROR; 767 } 768 break; 769 */ } 770 771 /* check for acc capability, and adjust mode to adhere to hardware constraints */ 772 if (max_acc_width <= max_crtc_width) 773 { 774 /* check if we can setup this mode with acceleration */ 775 // *acc_mode = true; 776 //blocking acc totally: 777 *acc_mode = false; 778 /* virtual_width */ 779 if (target->virtual_width > max_acc_width) *acc_mode = false; 780 /* virtual_height */ 781 /* (NV cards can even do more than this(?)... 782 * but 4096 is confirmed on all cards at max. accelerated width.) */ 783 if (target->virtual_height > 4096) *acc_mode = false; 784 785 /* now check virtual_size based on CRTC constraints */ 786 if (target->virtual_width > max_crtc_width) target->virtual_width = max_crtc_width; 787 /* virtual_height: The only constraint here is the cards memory size which is 788 * checked later on in ProposeMode: virtual_height is adjusted then if needed. 789 * 'Limiting here' to the variable size that's at least available (uint16). */ 790 if (target->virtual_height > 65535) target->virtual_height = 65535; 791 792 /* OK, now we know that virtual_width is valid, and it's needing no slopspace if 793 * it was confined above, so we can finally calculate safely if we need slopspace 794 * for this mode... */ 795 if (*acc_mode) 796 { 797 /* the mode needs to adhere to the largest granularity imposed... */ 798 if (acc_mask < crtc_mask) 799 video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask); 800 else 801 video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask); 802 } 803 else /* unaccelerated mode */ 804 video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask); 805 } 806 else /* max_acc_width > max_crtc_width */ 807 { 808 /* check if we can setup this mode with acceleration */ 809 *acc_mode = true; 810 /* (we already know virtual_width will be no problem) */ 811 /* virtual_height */ 812 /* (NV cards can even do more than this(?)... 813 * but 4096 is confirmed on all cards at max. accelerated width.) */ 814 if (target->virtual_height > 4096) *acc_mode = false; 815 816 /* now check virtual_size based on CRTC constraints */ 817 if (*acc_mode) 818 { 819 /* note that max_crtc_width already adheres to crtc_mask */ 820 if (target->virtual_width > (max_crtc_width & ~acc_mask)) 821 target->virtual_width = (max_crtc_width & ~acc_mask); 822 } 823 else /* unaccelerated mode */ 824 { 825 if (target->virtual_width > max_crtc_width) 826 target->virtual_width = max_crtc_width; 827 } 828 /* virtual_height: The only constraint here is the cards memory size which is 829 * checked later on in ProposeMode: virtual_height is adjusted then if needed. 830 * 'Limiting here' to the variable size that's at least available (uint16). */ 831 if (target->virtual_height > 65535) target->virtual_height = 65535; 832 833 /* OK, now we know that virtual_width is valid, and it's needing no slopspace if 834 * it was confined above, so we can finally calculate safely if we need slopspace 835 * for this mode... */ 836 if (*acc_mode) 837 { 838 /* the mode needs to adhere to the largest granularity imposed... */ 839 if (acc_mask < crtc_mask) 840 video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask); 841 else 842 video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask); 843 } 844 else /* unaccelerated mode */ 845 video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask); 846 } 847 848 LOG(2,("INIT: memory pitch will be set to %d pixels for colorspace 0x%08x\n", 849 video_pitch, target->space)); 850 if (target->virtual_width != video_pitch) 851 LOG(2,("INIT: effective mode slopspace is %d pixels\n", 852 (video_pitch - target->virtual_width))); 853 854 /* now calculate bytes_per_row for this mode */ 855 *bytes_per_row = video_pitch * (depth >> 3); 856 857 return B_OK; 858 } 859