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