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 VIA Accelerant 0.16 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 0x30221106: 103 si->ps.card_type = CLE3022; 104 si->ps.card_arch = CLE266; 105 LOG(4,("POWERUP: Detected VIA CLE266 Unichrome Pro (CLE3022)\n")); 106 status = engxx_general_powerup(); 107 break; 108 case 0x31081106: 109 //fixme: card_type unknown.. 110 si->ps.card_type = VT3204; 111 si->ps.card_arch = K8M800; 112 LOG(4,("POWERUP: Detected VIA K8M800 Unichrome Pro (unknown chiptype)\n")); 113 status = engxx_general_powerup(); 114 break; 115 case 0x31221106: 116 si->ps.card_type = CLE3122; 117 si->ps.card_arch = CLE266; 118 LOG(4,("POWERUP: Detected VIA CLE266 Unichrome Pro (CLE3122)\n")); 119 status = engxx_general_powerup(); 120 break; 121 case 0x32041106: 122 si->ps.card_type = VT3204; 123 si->ps.card_arch = K8M800; 124 LOG(4,("POWERUP: Detected VIA K8M800 Unichrome Pro (VT3204)\n")); 125 status = engxx_general_powerup(); 126 break; 127 case 0x32051106: 128 si->ps.card_type = VT3205; 129 si->ps.card_arch = KM400; 130 LOG(4,("POWERUP: Detected VIA KM400 Unichrome (VT3205)\n")); 131 status = engxx_general_powerup(); 132 break; 133 case 0x72041106: 134 si->ps.card_type = VT7204; 135 si->ps.card_arch = K8M800; 136 LOG(4,("POWERUP: Detected VIA K8M800 Unichrome Pro (VT7204)\n")); 137 status = engxx_general_powerup(); 138 break; 139 case 0x72051106: 140 si->ps.card_type = VT7205; 141 si->ps.card_arch = KM400; 142 LOG(4,("POWERUP: Detected VIA KM400 Unichrome (VT7205)\n")); 143 status = engxx_general_powerup(); 144 break; 145 default: 146 LOG(8,("POWERUP: Failed to detect valid card 0x%08x\n",CFGR(DEVID))); 147 return B_ERROR; 148 } 149 150 return status; 151 } 152 153 static status_t test_ram() 154 { 155 uint32 value, offset; 156 status_t result = B_OK; 157 158 /* make sure we don't corrupt the hardware cursor by using fbc.frame_buffer. */ 159 if (si->fbc.frame_buffer == NULL) 160 { 161 LOG(8,("INIT: test_ram detected NULL pointer.\n")); 162 return B_ERROR; 163 } 164 165 for (offset = 0, value = 0x55aa55aa; offset < 256; offset++) 166 { 167 /* write testpattern to cardRAM */ 168 ((uint32 *)si->fbc.frame_buffer)[offset] = value; 169 /* toggle testpattern */ 170 value = 0xffffffff - value; 171 } 172 173 for (offset = 0, value = 0x55aa55aa; offset < 256; offset++) 174 { 175 /* readback and verify testpattern from cardRAM */ 176 if (((uint32 *)si->fbc.frame_buffer)[offset] != value) result = B_ERROR; 177 /* toggle testpattern */ 178 value = 0xffffffff - value; 179 } 180 return result; 181 } 182 183 /* NOTE: 184 * This routine *has* to be done *after* SetDispplayMode has been executed, 185 * or test results will not be representative! 186 * (CAS latency is dependant on NV setup on some (DRAM) boards) */ 187 status_t eng_set_cas_latency() 188 { 189 status_t result = B_ERROR; 190 uint8 latency = 0; 191 192 /* check current RAM access to see if we need to change anything */ 193 if (test_ram() == B_OK) 194 { 195 LOG(4,("INIT: RAM access OK.\n")); 196 return B_OK; 197 } 198 199 /* check if we read PINS at starttime so we have valid registersettings at our disposal */ 200 if (si->ps.pins_status != B_OK) 201 { 202 LOG(4,("INIT: RAM access errors; not fixable: PINS was not read from cardBIOS.\n")); 203 return B_ERROR; 204 } 205 206 /* OK. We might have a problem, try to fix it now.. */ 207 LOG(4,("INIT: RAM access errors; tuning CAS latency if prudent...\n")); 208 209 switch(si->ps.card_type) 210 { 211 default: 212 LOG(4,("INIT: RAM CAS tuning not implemented for this card, aborting.\n")); 213 return B_OK; 214 break; 215 } 216 if (result == B_OK) 217 LOG(4,("INIT: RAM access OK. CAS latency set to %d cycles.\n", latency)); 218 else 219 LOG(4,("INIT: RAM access not fixable. CAS latency set to %d cycles.\n", latency)); 220 221 return result; 222 } 223 224 void setup_virtualized_heads(bool cross) 225 { 226 if (cross) 227 { 228 head1_validate_timing = (crtc_validate_timing) eng_crtc2_validate_timing; 229 head1_set_timing = (crtc_set_timing) eng_crtc2_set_timing; 230 head1_depth = (crtc_depth) eng_crtc2_depth; 231 head1_dpms = (crtc_dpms) eng_crtc2_dpms; 232 head1_dpms_fetch = (crtc_dpms_fetch) eng_crtc2_dpms_fetch; 233 head1_set_display_pitch = (crtc_set_display_pitch) eng_crtc2_set_display_pitch; 234 head1_set_display_start = (crtc_set_display_start) eng_crtc2_set_display_start; 235 head1_cursor_init = (crtc_cursor_init) eng_crtc2_cursor_init; 236 head1_cursor_show = (crtc_cursor_show) eng_crtc2_cursor_show; 237 head1_cursor_hide = (crtc_cursor_hide) eng_crtc2_cursor_hide; 238 head1_cursor_define = (crtc_cursor_define) eng_crtc2_cursor_define; 239 head1_cursor_position = (crtc_cursor_position) eng_crtc2_cursor_position; 240 241 head1_mode = (dac_mode) eng_dac2_mode; 242 head1_palette = (dac_palette) eng_dac2_palette; 243 head1_set_pix_pll = (dac_set_pix_pll) eng_dac2_set_pix_pll; 244 head1_pix_pll_find = (dac_pix_pll_find) eng_dac2_pix_pll_find; 245 246 head2_validate_timing = (crtc_validate_timing) eng_crtc_validate_timing; 247 head2_set_timing = (crtc_set_timing) eng_crtc_set_timing; 248 head2_depth = (crtc_depth) eng_crtc_depth; 249 head2_dpms = (crtc_dpms) eng_crtc_dpms; 250 head2_dpms_fetch = (crtc_dpms_fetch) eng_crtc_dpms_fetch; 251 head2_set_display_pitch = (crtc_set_display_pitch) eng_crtc_set_display_pitch; 252 head2_set_display_start = (crtc_set_display_start) eng_crtc_set_display_start; 253 head2_cursor_init = (crtc_cursor_init) eng_crtc_cursor_init; 254 head2_cursor_show = (crtc_cursor_show) eng_crtc_cursor_show; 255 head2_cursor_hide = (crtc_cursor_hide) eng_crtc_cursor_hide; 256 head2_cursor_define = (crtc_cursor_define) eng_crtc_cursor_define; 257 head2_cursor_position = (crtc_cursor_position) eng_crtc_cursor_position; 258 259 head2_mode = (dac_mode) eng_dac_mode; 260 head2_palette = (dac_palette) eng_dac_palette; 261 head2_set_pix_pll = (dac_set_pix_pll) eng_dac_set_pix_pll; 262 head2_pix_pll_find = (dac_pix_pll_find) eng_dac_pix_pll_find; 263 } 264 else 265 { 266 head1_validate_timing = (crtc_validate_timing) eng_crtc_validate_timing; 267 head1_set_timing = (crtc_set_timing) eng_crtc_set_timing; 268 head1_depth = (crtc_depth) eng_crtc_depth; 269 head1_dpms = (crtc_dpms) eng_crtc_dpms; 270 head1_dpms_fetch = (crtc_dpms_fetch) eng_crtc_dpms_fetch; 271 head1_set_display_pitch = (crtc_set_display_pitch) eng_crtc_set_display_pitch; 272 head1_set_display_start = (crtc_set_display_start) eng_crtc_set_display_start; 273 head1_cursor_init = (crtc_cursor_init) eng_crtc_cursor_init; 274 head1_cursor_show = (crtc_cursor_show) eng_crtc_cursor_show; 275 head1_cursor_hide = (crtc_cursor_hide) eng_crtc_cursor_hide; 276 head1_cursor_define = (crtc_cursor_define) eng_crtc_cursor_define; 277 head1_cursor_position = (crtc_cursor_position) eng_crtc_cursor_position; 278 279 head1_mode = (dac_mode) eng_dac_mode; 280 head1_palette = (dac_palette) eng_dac_palette; 281 head1_set_pix_pll = (dac_set_pix_pll) eng_dac_set_pix_pll; 282 head1_pix_pll_find = (dac_pix_pll_find) eng_dac_pix_pll_find; 283 284 head2_validate_timing = (crtc_validate_timing) eng_crtc2_validate_timing; 285 head2_set_timing = (crtc_set_timing) eng_crtc2_set_timing; 286 head2_depth = (crtc_depth) eng_crtc2_depth; 287 head2_dpms = (crtc_dpms) eng_crtc2_dpms; 288 head2_dpms_fetch = (crtc_dpms_fetch) eng_crtc2_dpms_fetch; 289 head2_set_display_pitch = (crtc_set_display_pitch) eng_crtc2_set_display_pitch; 290 head2_set_display_start = (crtc_set_display_start) eng_crtc2_set_display_start; 291 head2_cursor_init = (crtc_cursor_init) eng_crtc2_cursor_init; 292 head2_cursor_show = (crtc_cursor_show) eng_crtc2_cursor_show; 293 head2_cursor_hide = (crtc_cursor_hide) eng_crtc2_cursor_hide; 294 head2_cursor_define = (crtc_cursor_define) eng_crtc2_cursor_define; 295 head2_cursor_position = (crtc_cursor_position) eng_crtc2_cursor_position; 296 297 head2_mode = (dac_mode) eng_dac2_mode; 298 head2_palette = (dac_palette) eng_dac2_palette; 299 head2_set_pix_pll = (dac_set_pix_pll) eng_dac2_set_pix_pll; 300 head2_pix_pll_find = (dac_pix_pll_find) eng_dac2_pix_pll_find; 301 } 302 } 303 304 void set_crtc_owner(bool head) 305 { 306 if (si->ps.secondary_head) 307 { 308 if (!head) 309 { 310 /* note: 'OWNER' is a non-standard register in behaviour(!) on NV11's, 311 * while non-NV11 cards behave normally. 312 * 313 * Double-write action needed on those strange NV11 cards: */ 314 /* RESET: needed on NV11 */ 315 CRTCW(OWNER, 0xff); 316 /* enable access to CRTC1, SEQ1, GRPH1, ATB1, ??? */ 317 CRTCW(OWNER, 0x00); 318 } 319 else 320 { 321 /* note: 'OWNER' is a non-standard register in behaviour(!) on NV11's, 322 * while non-NV11 cards behave normally. 323 * 324 * Double-write action needed on those strange NV11 cards: */ 325 /* RESET: needed on NV11 */ 326 CRTC2W(OWNER, 0xff); 327 /* enable access to CRTC2, SEQ2, GRPH2, ATB2, ??? */ 328 CRTC2W(OWNER, 0x03); 329 } 330 } 331 } 332 333 static status_t engxx_general_powerup() 334 { 335 LOG(4,("POWERUP: Chip revision is $%02x\n", si->ps.chip_rev)); 336 LOG(4, ("INIT: card powerup\n")); 337 338 /* setup cardspecs */ 339 /* note: 340 * this MUST be done before the driver attempts a card coldstart */ 341 set_specs(); 342 343 /* only process BIOS for finetuning specs and coldstarting card if requested 344 * by the user; 345 * note: 346 * this in fact frees the driver from relying on the BIOS to be executed 347 * at system power-up POST time. */ 348 if (!si->settings.usebios) 349 { 350 LOG(2, ("INIT: Attempting card coldstart!\n")); 351 /* update the cardspecs in the shared_info PINS struct according to reported 352 * specs as much as is possible; 353 * this also coldstarts the card if possible (executes BIOS CMD script(s)) */ 354 // parse_pins(); 355 } 356 else 357 { 358 LOG(2, ("INIT: Skipping card coldstart!\n")); 359 } 360 361 /* get RAM size and fake panel startup (panel init code is still missing) */ 362 fake_panel_start(); 363 364 /* log the final card specifications */ 365 dump_pins(); 366 367 /* dump config space as it is after a possible coldstart attempt */ 368 if (si->settings.logmask & 0x80000000) eng_dump_configuration_space(); 369 370 /* setup CRTC and DAC functions access: determined in fake_panel_start */ 371 setup_virtualized_heads(si->ps.crtc2_prim); 372 373 /* do powerup needed from pre-inited card state as done by system POST cardBIOS 374 * execution or driver coldstart above */ 375 return eng_general_bios_to_powergraphics(); 376 } 377 378 /* this routine switches the CRTC/DAC sets to 'connectors', but only for analog 379 * outputs. We need this to make sure the analog 'switch' is set in the same way the 380 * digital 'switch' is set by the BIOS or we might not be able to use dualhead. */ 381 status_t eng_general_output_select(bool cross) 382 { 383 /* make sure this call is warranted */ 384 if (si->ps.secondary_head) 385 { 386 /* NV11 cards can't switch heads (confirmed) */ 387 if (si->ps.card_type != NV11) 388 { 389 if (cross) 390 { 391 LOG(4,("INIT: switching analog outputs to be cross-connected\n")); 392 393 /* enable head 2 on connector 1 */ 394 /* (b8 = select CRTC (head) for output, 395 * b4 = ??? (confirmed not to be a FP switch), 396 * b0 = enable CRT) */ 397 DACW(OUTPUT, 0x00000101); 398 /* enable head 1 on connector 2 */ 399 DAC2W(OUTPUT, 0x00000001); 400 } 401 else 402 { 403 LOG(4,("INIT: switching analog outputs to be straight-through\n")); 404 405 /* enable head 1 on connector 1 */ 406 DACW(OUTPUT, 0x00000001); 407 /* enable head 2 on connector 2 */ 408 DAC2W(OUTPUT, 0x00000101); 409 } 410 } 411 else 412 { 413 LOG(4,("INIT: NV11 analog outputs are hardwired to be straight-through\n")); 414 } 415 return B_OK; 416 } 417 else 418 { 419 return B_ERROR; 420 } 421 } 422 423 /* this routine switches CRTC/DAC set use. We need this because it's unknown howto 424 * switch digital panels to/from a specific CRTC/DAC set. */ 425 status_t eng_general_head_select(bool cross) 426 { 427 /* make sure this call is warranted */ 428 if (si->ps.secondary_head) 429 { 430 /* invert CRTC/DAC use to do switching */ 431 if (cross) 432 { 433 LOG(4,("INIT: switching CRTC/DAC use to be cross-connected\n")); 434 si->crtc_switch_mode = !si->ps.crtc2_prim; 435 } 436 else 437 { 438 LOG(4,("INIT: switching CRTC/DAC use to be straight-through\n")); 439 si->crtc_switch_mode = si->ps.crtc2_prim; 440 } 441 /* update CRTC and DAC functions access */ 442 setup_virtualized_heads(si->crtc_switch_mode); 443 444 return B_OK; 445 } 446 else 447 { 448 return B_ERROR; 449 } 450 } 451 452 /* basic change of card state from VGA to enhanced mode: 453 * Should work from VGA BIOS POST init state. */ 454 static status_t eng_general_bios_to_powergraphics() 455 { 456 /* let acc engine make power off/power on cycle to start 'fresh' */ 457 // ENG_REG32(RG32_PWRUPCTRL) = 0x13110011; 458 snooze(1000); 459 460 /* power-up all hardware function blocks */ 461 // ENG_REG32(RG32_PWRUPCTRL) = 0x13111111; 462 463 /* select colormode CRTC registers base adresses, 464 * but don't touch the current selected pixelclock source yet */ 465 ENG_REG8(RG8_MISCW) = (((ENG_REG8(RG8_MISCR)) & 0x0c) | 0xc3); 466 467 /* unlock (extended) registers for R/W access */ 468 SEQW(LOCK, 0x01); 469 CRTCW(VSYNCE ,(CRTCR(VSYNCE) & 0x7f)); 470 471 /* turn off both displays and the hardcursors (also disables transfers) */ 472 head1_dpms(false, false, false); 473 head1_cursor_hide(); 474 if (si->ps.secondary_head) 475 { 476 // head2_dpms(false, false, false); 477 // head2_cursor_hide(); 478 } 479 480 // if (si->ps.secondary_head) 481 if (0) 482 { 483 /* switch overlay engine to CRTC1 */ 484 /* bit 17: GPU FP port #1 (confirmed NV25, NV28, confirmed not on NV34), 485 * bit 16: GPU FP port #2 (confirmed NV25, NV28, NV34), 486 * bit 12: overlay engine (all cards), 487 * bit 9: TVout chip #2 (confirmed on NV18, NV25, NV28), 488 * bit 8: TVout chip #1 (all cards), 489 * bit 4: both I2C busses (all cards) */ 490 ENG_REG32(RG32_2FUNCSEL) &= ~0x00001000; 491 ENG_REG32(RG32_FUNCSEL) |= 0x00001000; 492 } 493 si->overlay.crtc = false; 494 495 /* set card to 'enhanced' mode: (only VGA standard registers used here) */ 496 /* (keep) card enabled, set plain normal memory usage, no old VGA 'tricks' ... */ 497 CRTCW(MODECTL, 0xc3); 498 /* ... plain sequential memory use, more than 64Kb RAM installed, 499 * switch to graphics mode ... */ 500 SEQW(MEMMODE, 0x0e); 501 /* ... disable bitplane tweaking ... */ 502 GRPHW(ENSETRESET, 0x00); 503 /* ... no logical function tweaking with display data, no data rotation ... */ 504 GRPHW(DATAROTATE, 0x00); 505 /* ... reset read map select to plane 0 ... */ 506 GRPHW(READMAPSEL, 0x00); 507 /* ... set standard mode ... */ 508 GRPHW(MODE, 0x00); 509 /* ... ISA framebuffer mapping is 64Kb window, switch to graphics mode (again), 510 * select standard adressing ... */ 511 GRPHW(MISC, 0x05); 512 /* ... disable bit masking ... */ 513 GRPHW(BITMASK, 0xff); 514 /* ... attributes are in color, switch to graphics mode (again) ... */ 515 ATBW(MODECTL, 0x01); 516 /* ... set overscan color to black ... */ 517 ATBW(OSCANCOLOR, 0x00); 518 /* ... enable all color planes ... */ 519 ATBW(COLPLANE_EN, 0x0f); 520 /* ... reset horizontal pixelpanning ... */ 521 ATBW(HORPIXPAN, 0x00); 522 /* ... reset colorpalette groupselect bits ... */ 523 ATBW(COLSEL, 0x00); 524 /* ... do unknown standard VGA register ... */ 525 ATBW(0x16, 0x01); 526 /* ... and enable all four byteplanes. */ 527 SEQW(MAPMASK, 0x0f); 528 /* setup sequencer clocking mode */ 529 SEQW(CLKMODE, 0x21); 530 531 /* setup AGP: 532 * Note: 533 * This may only be done when no transfers are in progress on the bus, so now 534 * is probably a good time.. */ 535 eng_agp_setup(); 536 537 /* turn screen one on */ 538 head1_dpms(true, true, true); 539 540 return B_OK; 541 } 542 543 /* Check if mode virtual_size adheres to the cards _maximum_ contraints, and modify 544 * virtual_size to the nearest valid maximum for the mode on the card if not so. 545 * Also: check if virtual_width adheres to the cards granularity constraints, and 546 * create mode slopspace if not so. 547 * We use acc or crtc granularity constraints based on the 'worst case' scenario. 548 * 549 * Mode slopspace is reflected in fbc->bytes_per_row BTW. */ 550 status_t eng_general_validate_pic_size (display_mode *target, uint32 *bytes_per_row, bool *acc_mode) 551 { 552 uint32 video_pitch; 553 uint32 acc_mask, crtc_mask; 554 uint32 max_crtc_width, max_acc_width; 555 uint8 depth = 8; 556 557 /* determine pixel multiple based on 2D/3D engine constraints */ 558 //via fixme. 559 switch (si->ps.card_arch) 560 { 561 default: 562 /* confirmed for: 563 * TNT1, TNT2, TNT2-M64, GeForce2 MX400, GeForce4 MX440, GeForceFX 5200 */ 564 switch (target->space) 565 { 566 case B_CMAP8: acc_mask = 0x0f; depth = 8; break; 567 case B_RGB15: acc_mask = 0x07; depth = 16; break; 568 case B_RGB16: acc_mask = 0x07; depth = 16; break; 569 case B_RGB24: acc_mask = 0x0f; depth = 24; break; 570 case B_RGB32: acc_mask = 0x03; depth = 32; break; 571 default: 572 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 573 return B_ERROR; 574 } 575 break; 576 } 577 578 //via ok: 579 /* determine pixel multiple based on CRTC memory pitch constraints. 580 * (Note: Don't mix this up with CRTC timing contraints! Those are 581 * multiples of 8 for horizontal, 1 for vertical timing.) */ 582 switch (si->ps.card_type) 583 { 584 default: 585 switch (target->space) 586 { 587 case B_CMAP8: crtc_mask = 0x07; break; 588 case B_RGB15: crtc_mask = 0x03; break; 589 case B_RGB16: crtc_mask = 0x03; break; 590 case B_RGB24: crtc_mask = 0x07; break; 591 case B_RGB32: crtc_mask = 0x01; break; 592 default: 593 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 594 return B_ERROR; 595 } 596 break; 597 } 598 599 /* set virtual_width limit for accelerated modes */ 600 //via fixme: 601 switch (si->ps.card_arch) 602 { 603 case NV04A: 604 /* confirmed for: 605 * TNT1, TNT2, TNT2-M64 */ 606 switch(target->space) 607 { 608 case B_CMAP8: max_acc_width = 8176; break; 609 case B_RGB15: max_acc_width = 4088; break; 610 case B_RGB16: max_acc_width = 4088; break; 611 case B_RGB24: max_acc_width = 2720; break; 612 case B_RGB32: max_acc_width = 2044; break; 613 default: 614 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 615 return B_ERROR; 616 } 617 break; 618 default: 619 /* confirmed for: 620 * GeForce2 MX400, GeForce4 MX440, GeForceFX 5200 */ 621 switch(target->space) 622 { 623 case B_CMAP8: max_acc_width = 16368; break; 624 case B_RGB15: max_acc_width = 8184; break; 625 case B_RGB16: max_acc_width = 8184; break; 626 case B_RGB24: max_acc_width = 5456; break; 627 case B_RGB32: max_acc_width = 4092; break; 628 default: 629 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 630 return B_ERROR; 631 } 632 /* NV31 (confirmed GeForceFX 5600) has NV20A granularity! 633 * So let it fall through... */ 634 if (si->ps.card_type != NV31) break; 635 case NV20A: 636 /* confirmed for: 637 * GeForce4 Ti4200 */ 638 switch(target->space) 639 { 640 case B_CMAP8: max_acc_width = 16320; break; 641 case B_RGB15: max_acc_width = 8160; break; 642 case B_RGB16: max_acc_width = 8160; break; 643 case B_RGB24: max_acc_width = 5440; break; 644 case B_RGB32: max_acc_width = 4080; break; 645 default: 646 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 647 return B_ERROR; 648 } 649 break; 650 } 651 652 //via ok: 653 /* set virtual_width limit for unaccelerated modes */ 654 switch (si->ps.card_type) 655 { 656 default: 657 switch(target->space) 658 { 659 case B_CMAP8: max_crtc_width = 16376; break; 660 case B_RGB15: max_crtc_width = 8188; break; 661 case B_RGB16: max_crtc_width = 8188; break; 662 case B_RGB24: max_crtc_width = 5456; break; 663 case B_RGB32: max_crtc_width = 4094; break; 664 default: 665 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 666 return B_ERROR; 667 } 668 break; 669 } 670 671 /* check for acc capability, and adjust mode to adhere to hardware constraints */ 672 if (max_acc_width <= max_crtc_width) 673 { 674 /* check if we can setup this mode with acceleration */ 675 // *acc_mode = true; 676 //blocking acc totally: 677 *acc_mode = false; 678 /* virtual_width */ 679 if (target->virtual_width > max_acc_width) *acc_mode = false; 680 /* virtual_height */ 681 /* (NV cards can even do more than this(?)... 682 * but 4096 is confirmed on all cards at max. accelerated width.) */ 683 if (target->virtual_height > 4096) *acc_mode = false; 684 685 /* now check virtual_size based on CRTC constraints */ 686 if (target->virtual_width > max_crtc_width) target->virtual_width = max_crtc_width; 687 /* virtual_height: The only constraint here is the cards memory size which is 688 * checked later on in ProposeMode: virtual_height is adjusted then if needed. 689 * 'Limiting here' to the variable size that's at least available (uint16). */ 690 if (target->virtual_height > 65535) target->virtual_height = 65535; 691 692 /* OK, now we know that virtual_width is valid, and it's needing no slopspace if 693 * it was confined above, so we can finally calculate safely if we need slopspace 694 * for this mode... */ 695 if (*acc_mode) 696 { 697 /* the mode needs to adhere to the largest granularity imposed... */ 698 if (acc_mask < crtc_mask) 699 video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask); 700 else 701 video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask); 702 } 703 else /* unaccelerated mode */ 704 video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask); 705 } 706 else /* max_acc_width > max_crtc_width */ 707 { 708 /* check if we can setup this mode with acceleration */ 709 // *acc_mode = true; 710 //blocking acc totally: 711 *acc_mode = false; 712 /* (we already know virtual_width will be no problem) */ 713 /* virtual_height */ 714 /* (NV cards can even do more than this(?)... 715 * but 4096 is confirmed on all cards at max. accelerated width.) */ 716 if (target->virtual_height > 4096) *acc_mode = false; 717 718 /* now check virtual_size based on CRTC constraints */ 719 if (*acc_mode) 720 { 721 /* note that max_crtc_width already adheres to crtc_mask */ 722 if (target->virtual_width > (max_crtc_width & ~acc_mask)) 723 target->virtual_width = (max_crtc_width & ~acc_mask); 724 } 725 else /* unaccelerated mode */ 726 { 727 if (target->virtual_width > max_crtc_width) 728 target->virtual_width = max_crtc_width; 729 } 730 /* virtual_height: The only constraint here is the cards memory size which is 731 * checked later on in ProposeMode: virtual_height is adjusted then if needed. 732 * 'Limiting here' to the variable size that's at least available (uint16). */ 733 if (target->virtual_height > 65535) target->virtual_height = 65535; 734 735 /* OK, now we know that virtual_width is valid, and it's needing no slopspace if 736 * it was confined above, so we can finally calculate safely if we need slopspace 737 * for this mode... */ 738 if (*acc_mode) 739 { 740 /* the mode needs to adhere to the largest granularity imposed... */ 741 if (acc_mask < crtc_mask) 742 video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask); 743 else 744 video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask); 745 } 746 else /* unaccelerated mode */ 747 video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask); 748 } 749 750 LOG(2,("INIT: memory pitch will be set to %d pixels for colorspace 0x%08x\n", 751 video_pitch, target->space)); 752 if (target->virtual_width != video_pitch) 753 LOG(2,("INIT: effective mode slopspace is %d pixels\n", 754 (video_pitch - target->virtual_width))); 755 756 /* now calculate bytes_per_row for this mode */ 757 *bytes_per_row = video_pitch * (depth >> 3); 758 759 return B_OK; 760 } 761