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