1 /* Authors: 2 Mark Watson 12/1999, 3 Apsed, 4 Rudolf Cornelissen 10/2002-10/2009 5 */ 6 7 #define MODULE_BIT 0x00008000 8 9 #include "mga_std.h" 10 11 static status_t test_ram(void); 12 static status_t mil_general_powerup (void); 13 static status_t g100_general_powerup (void); 14 static status_t g200_general_powerup (void); 15 static status_t g400_general_powerup (void); 16 static status_t g450_general_powerup (void); 17 static status_t gx00_general_bios_to_powergraphics(void); 18 19 static void mga_dump_configuration_space (void) 20 { 21 #define DUMP_CFG(reg, type) if (si->ps.card_type >= type) do { \ 22 uint32 value = CFGR(reg); \ 23 MSG(("configuration_space 0x%02x %20s 0x%08x\n", \ 24 MGACFG_##reg, #reg, value)); \ 25 } while (0) 26 DUMP_CFG (DEVID, 0); 27 DUMP_CFG (DEVCTRL, 0); 28 DUMP_CFG (CLASS, 0); 29 DUMP_CFG (HEADER, 0); 30 DUMP_CFG (MGABASE2, 0); 31 DUMP_CFG (MGABASE1, 0); 32 DUMP_CFG (MGABASE3, MYST); 33 DUMP_CFG (SUBSYSIDR, MYST); 34 DUMP_CFG (ROMBASE, 0); 35 DUMP_CFG (CAP_PTR, MIL2); 36 DUMP_CFG (INTCTRL, 0); 37 DUMP_CFG (OPTION, 0); 38 DUMP_CFG (MGA_INDEX, 0); 39 DUMP_CFG (MGA_DATA, 0); 40 DUMP_CFG (SUBSYSIDW, MYST); 41 DUMP_CFG (OPTION2, G100); 42 DUMP_CFG (OPTION3, G400); 43 DUMP_CFG (OPTION4, G400); 44 DUMP_CFG (PM_IDENT, G100); 45 DUMP_CFG (PM_CSR, G100); 46 DUMP_CFG (AGP_IDENT, MIL2); 47 DUMP_CFG (AGP_STS, MIL2); 48 DUMP_CFG (AGP_CMD, MIL2); 49 #undef DUMP_CFG 50 } 51 52 status_t gx00_general_powerup() 53 { 54 status_t status; 55 uint8 card_class; 56 57 LOG(1,("POWERUP: Haiku Matrox Accelerant 0.33 running.\n")); 58 59 /* log VBLANK INT usability status */ 60 if (si->ps.int_assigned) 61 LOG(4,("POWERUP: Usable INT assigned to HW; Vblank semaphore enabled\n")); 62 else 63 LOG(4,("POWERUP: No (usable) INT assigned to HW; Vblank semaphore disabled\n")); 64 65 /* WARNING: 66 * _adi.name_ and _adi.chipset_ can contain 31 readable characters max.!!! */ 67 68 /* detect card type and power it up */ 69 switch(CFGR(DEVID)) 70 { 71 case 0x051a102b: //MGA-1064 Mystique PCI 72 sprintf(si->adi.name, "Matrox Mystique PCI"); 73 sprintf(si->adi.chipset, "MGA-1064"); 74 LOG(8,("POWERUP: Unimplemented Matrox device %08x\n",CFGR(DEVID))); 75 return B_ERROR; 76 case 0x0519102b: //MGA-2064 Millenium PCI 77 si->ps.card_type = MIL1; 78 sprintf(si->adi.name, "Matrox Millennium I"); 79 sprintf(si->adi.chipset, "MGA-2064"); 80 status = mil_general_powerup(); 81 break; 82 case 0x051b102b:case 0x051f102b: //MGA-2164 Millenium II PCI/AGP 83 si->ps.card_type = MIL2; 84 sprintf(si->adi.name, "Matrox Millennium II"); 85 sprintf(si->adi.chipset, "MGA-2164"); 86 status = mil_general_powerup(); 87 break; 88 case 0x1000102b:case 0x1001102b: //G100 89 si->ps.card_type = G100; 90 sprintf(si->adi.name, "Matrox MGA G100"); 91 sprintf(si->adi.chipset, "G100"); 92 status = g100_general_powerup(); 93 break; 94 case 0x0520102b:case 0x0521102b: //G200 95 si->ps.card_type = G200; 96 sprintf(si->adi.name, "Matrox MGA G200"); 97 sprintf(si->adi.chipset, "G200"); 98 status = g200_general_powerup(); 99 break; 100 case 0x0525102b: //G400, G400MAX or G450 101 /* get classinfo to distinguish different types */ 102 card_class = CFGR(CLASS) & 0xff; 103 if (card_class & 0x80) 104 { 105 /* G450 */ 106 si->ps.card_type = G450; 107 sprintf(si->adi.name, "Matrox MGA G450"); 108 sprintf(si->adi.chipset, "G450 revision %x", (card_class & 0x7f)); 109 LOG(4, ("50 revision %x\n", card_class & 0x7f)); 110 status = g450_general_powerup(); 111 } 112 else 113 { 114 /* standard G400, G400MAX */ 115 /* the only difference is the max RAMDAC speed, accounted for via pins. */ 116 si->ps.card_type = G400; 117 sprintf(si->adi.name, "Matrox MGA G400"); 118 sprintf(si->adi.chipset, "G400 revision %x", (card_class & 0x7f)); 119 status = g400_general_powerup(); 120 } 121 break; 122 case 0x2527102b://G550 patch from Jean-Michel Batto 123 si->ps.card_type = G450; 124 sprintf(si->adi.name, "Matrox MGA G550"); 125 sprintf(si->adi.chipset, "G550"); 126 status = g450_general_powerup(); 127 break; 128 default: 129 LOG(8,("POWERUP: Failed to detect valid card 0x%08x\n",CFGR(DEVID))); 130 return B_ERROR; 131 } 132 133 /* override memory detection if requested by user */ 134 if (si->settings.memory != 0) 135 si->ps.memory_size = si->settings.memory; 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 ((vuint32 *)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 (((vuint32 *)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 MGA setup on some (DRAM) boards) */ 174 status_t mga_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 case G100: 199 if (!si->ps.sdram) 200 { 201 LOG(4,("INIT: G100 SGRAM CAS tuning not permitted, aborting.\n")); 202 return B_OK; 203 } 204 /* SDRAM card */ 205 for (latency = 4; latency >= 2; latency-- ) 206 { 207 /* MCTLWTST is a write-only register! */ 208 ACCW(MCTLWTST, ((si->ps.mctlwtst_reg & 0xfffffffc) | (latency - 2))); 209 result = test_ram(); 210 if (result == B_OK) break; 211 } 212 break; 213 case G200: 214 /* fixme: implement this */ 215 LOG(4,("INIT: G200 RAM CAS tuning not implemented, aborting.\n")); 216 return B_OK; 217 break; 218 case G400: 219 case G400MAX: 220 /* fixme: implement this if needed */ 221 LOG(4,("INIT: G400/G400MAX RAM CAS tuning not implemented, aborting.\n")); 222 return B_OK; 223 break; 224 case G450: 225 case G550: 226 /* fixme: implement this if needed */ 227 LOG(4,("INIT: G450/G550 RAM CAS tuning not implemented, aborting.\n")); 228 return B_OK; 229 break; 230 default: 231 /* fixme: Millenium2 and others if needed */ 232 LOG(4,("INIT: RAM CAS tuning not implemented for this card, aborting.\n")); 233 return B_OK; 234 break; 235 } 236 if (result == B_OK) 237 LOG(4,("INIT: RAM access OK. CAS latency set to %d cycles.\n", latency)); 238 else 239 LOG(4,("INIT: RAM access not fixable. CAS latency set to %d cycles.\n", latency)); 240 241 return result; 242 } 243 244 static 245 status_t mil_general_powerup() 246 { 247 status_t result; 248 249 LOG(4, ("INIT: Millenium I/II powerup\n")); 250 LOG(4, ("INIT: Detected %s (%s)\n", si->adi.name, si->adi.chipset)); 251 if (si->settings.logmask & 0x80000000) mga_dump_configuration_space(); 252 253 /* initialize the shared_info PINS struct */ 254 result = parse_pins(); 255 if (result != B_OK) fake_pins(); 256 257 /* log the PINS struct settings */ 258 dump_pins(); 259 260 //remove this: 261 fake_pins(); 262 LOG(2, ("INIT: Using faked PINS for now:\n")); 263 dump_pins(); 264 //end remove this. 265 266 /* if the user doesn't want a coldstart OR the BIOS pins info could not be found warmstart */ 267 //restore this line: 268 // if (si->settings.usebios || (result != B_OK)) return gx00_general_bios_to_powergraphics(); 269 270 //set to powergraphics etc. 271 LOG(2, ("INIT: Skipping card coldstart!\n")); 272 mil2_dac_init(); 273 274 //ok: 275 /* disable overscan, select 0 IRE, select straight-through sync signals from CRTC */ 276 DXIW (GENCTRL, (DXIR (GENCTRL) & 0x0c)); 277 /* fixme: checkout if we need this sync inverting stuff: already done via CRTC!?! 278 | (vsync_pos? 0x00:0x02) 279 | (hsync_pos? 0x00:0x01)); */ 280 281 /* 8-bit DAC, enable DAC */ 282 DXIW(MISCCTRL, 0x0c); 283 // 284 285 VGAW_I(SEQ,1,0x00); 286 /*enable screen*/ 287 288 return B_OK; 289 } 290 291 static 292 status_t g100_general_powerup() 293 { 294 status_t result; 295 296 LOG(4, ("INIT: G100 powerup\n")); 297 LOG(4, ("INIT: Detected %s (%s)\n", si->adi.name, si->adi.chipset)); 298 if (si->settings.logmask & 0x80000000) mga_dump_configuration_space(); 299 300 /* initialize the shared_info PINS struct */ 301 result = parse_pins(); 302 if (result != B_OK) fake_pins(); 303 304 /* log the PINS struct settings */ 305 dump_pins(); 306 307 /* if the user doesn't want a coldstart OR the BIOS pins info could not be found warmstart */ 308 if (si->settings.usebios || (result != B_OK)) return gx00_general_bios_to_powergraphics(); 309 310 /*power up the PLLs,LUT,DAC*/ 311 LOG(2,("INIT: PLL/LUT/DAC powerup\n")); 312 /* turn off both displays and the hardcursor (also disables transfers) */ 313 gx00_crtc_dpms(false, false, false); 314 /* on singlehead cards with TVout program the MAVEN as well */ 315 if (si->ps.tvout) gx00_maven_dpms(false, false, false); 316 gx00_crtc_cursor_hide(); 317 /* G100 SGRAM and SDRAM use external pix and dac refs, do *not* activate internals! 318 * (this would create electrical shortcuts, 319 * resulting in extra chip heat and distortions visible on screen */ 320 /* set voltage reference - using DAC reference block partly */ 321 DXIW(VREFCTRL,0x03); 322 /* wait for 100ms for voltage reference to stabilize */ 323 delay(100000); 324 /* power up the SYSPLL */ 325 CFGW(OPTION,CFGR(OPTION)|0x20); 326 /* power up the PIXPLL */ 327 DXIW(PIXCLKCTRL,0x08); 328 329 /* disable pixelclock oscillations before switching on CLUT */ 330 DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) | 0x04)); 331 /* disable 15bit mode CLUT-overlay function */ 332 DXIW(GENCTRL, DXIR(GENCTRL & 0xfd)); 333 /* CRTC2->MAFC, 8-bit DAC, CLUT enabled, enable DAC */ 334 DXIW(MISCCTRL,0x1b); 335 snooze(250); 336 /* re-enable pixelclock oscillations */ 337 DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) & 0xfb)); 338 339 /* setup i2c bus */ 340 i2c_init(); 341 342 /*make sure card is in powergraphics mode*/ 343 VGAW_I(CRTCEXT,3,0x80); 344 345 /*set the system clocks to powergraphics speed*/ 346 LOG(2,("INIT: Setting system PLL to powergraphics speeds\n")); 347 g100_dac_set_sys_pll(); 348 349 /* 'official' RAM initialisation */ 350 LOG(2,("INIT: RAM init\n")); 351 /* disable plane write mask (needed for SDRAM): actual change needed to get it sent to RAM */ 352 ACCW(PLNWT,0x00000000); 353 ACCW(PLNWT,0xffffffff); 354 /* program memory control waitstates */ 355 ACCW(MCTLWTST,si->ps.mctlwtst_reg); 356 /* set memory configuration including: 357 * - no split framebuffer. 358 * - Mark says b14 (G200) should be done also though not defined for G100 in spec, 359 * - b3 v3_mem_type was included by Mark for memconfig setup: but looks like not defined */ 360 CFGW(OPTION,(CFGR(OPTION)&0xFFFF8FFF) | ((si->ps.v3_mem_type & 0x04) << 10)); 361 /* set memory buffer type: 362 * - Mark says: if((v3_mem_type & 0x03) == 0x03) then do not or-in bits in option2; 363 * but looks like v3_mem_type b1 is not defined, 364 * - Mark also says: place v3_mem_type b1 in option2 bit13 (if not 0x03) but b13 = reserved. */ 365 CFGW(OPTION2,(CFGR(OPTION2)&0xFFFFCFFF)|((si->ps.v3_mem_type & 0x01) << 12)); 366 /* set RAM read tap delay */ 367 CFGW(OPTION2,(CFGR(OPTION2)&0xFFFFFFF0) | ((si->ps.v3_mem_type & 0xf0) >> 4)); 368 /* wait 200uS minimum */ 369 snooze(250); 370 371 /* reset memory (MACCESS is a write only register!) */ 372 ACCW(MACCESS, 0x00000000); 373 /* select JEDEC reset method */ 374 ACCW(MACCESS, 0x00004000); 375 /* perform actual RAM reset */ 376 ACCW(MACCESS, 0x0000c000); 377 snooze(250); 378 /* start memory refresh */ 379 CFGW(OPTION,(CFGR(OPTION)&0xffe07fff) | (si->ps.option_reg & 0x001f8000)); 380 /* set memory control waitstate again AFTER the RAM reset */ 381 ACCW(MCTLWTST,si->ps.mctlwtst_reg); 382 /* end 'official' RAM initialisation. */ 383 384 /* Bus parameters: enable retries, use advanced read */ 385 CFGW(OPTION,(CFGR(OPTION)|(1<<22)|(0<<29))); 386 387 /*enable writing to crtc registers*/ 388 VGAW_I(CRTC,0x11,0); 389 390 return B_OK; 391 } 392 393 static 394 status_t g200_general_powerup() 395 { 396 status_t result; 397 398 LOG(4, ("INIT: G200 powerup\n")); 399 LOG(4, ("INIT: Detected %s (%s)\n", si->adi.name, si->adi.chipset)); 400 if (si->settings.logmask & 0x80000000) mga_dump_configuration_space(); 401 402 /* initialize the shared_info PINS struct */ 403 result = parse_pins(); 404 if (result != B_OK) fake_pins(); 405 406 /* log the PINS struct settings */ 407 dump_pins(); 408 409 /* if the user doesn't want a coldstart OR the BIOS pins info could not be found warmstart */ 410 if (si->settings.usebios || (result != B_OK)) return gx00_general_bios_to_powergraphics(); 411 412 /*power up the PLLs,LUT,DAC*/ 413 LOG(2,("INIT: PLL/LUT/DAC powerup\n")); 414 /* turn off both displays and the hardcursor (also disables transfers) */ 415 gx00_crtc_dpms(false, false, false); 416 /* on singlehead cards with TVout program the MAVEN as well */ 417 if (si->ps.tvout) gx00_maven_dpms(false, false, false); 418 gx00_crtc_cursor_hide(); 419 /* G200 SGRAM and SDRAM use external pix and dac refs, do *not* activate internals! 420 * (this would create electrical shortcuts, 421 * resulting in extra chip heat and distortions visible on screen */ 422 /* set voltage reference - using DAC reference block partly */ 423 DXIW(VREFCTRL,0x03); 424 /* wait for 100ms for voltage reference to stabilize */ 425 delay(100000); 426 /* power up the SYSPLL */ 427 CFGW(OPTION,CFGR(OPTION)|0x20); 428 /* power up the PIXPLL */ 429 DXIW(PIXCLKCTRL,0x08); 430 431 /* disable pixelclock oscillations before switching on CLUT */ 432 DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) | 0x04)); 433 /* disable 15bit mode CLUT-overlay function */ 434 DXIW(GENCTRL, DXIR(GENCTRL & 0xfd)); 435 /* CRTC2->MAFC, 8-bit DAC, CLUT enabled, enable DAC */ 436 DXIW(MISCCTRL,0x1b); 437 snooze(250); 438 /* re-enable pixelclock oscillations */ 439 DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) & 0xfb)); 440 441 /* setup i2c bus */ 442 i2c_init(); 443 444 /*make sure card is in powergraphics mode*/ 445 VGAW_I(CRTCEXT,3,0x80); 446 447 /*set the system clocks to powergraphics speed*/ 448 LOG(2,("INIT: Setting system PLL to powergraphics speeds\n")); 449 g200_dac_set_sys_pll(); 450 451 /* 'official' RAM initialisation */ 452 LOG(2,("INIT: RAM init\n")); 453 /* disable hardware plane write mask if SDRAM card */ 454 if (si->ps.sdram) CFGW(OPTION,(CFGR(OPTION) & 0xffffbfff)); 455 /* disable plane write mask (needed for SDRAM): actual change needed to get it sent to RAM */ 456 ACCW(PLNWT,0x00000000); 457 ACCW(PLNWT,0xffffffff); 458 /* program memory control waitstates */ 459 ACCW(MCTLWTST,si->ps.mctlwtst_reg); 460 /* set memory configuration including: 461 * - SDRAM / SGRAM special functions select. */ 462 CFGW(OPTION,(CFGR(OPTION)&0xFFFF83FF) | ((si->ps.v3_mem_type & 0x07) << 10)); 463 if (!si->ps.sdram) CFGW(OPTION,(CFGR(OPTION) | (0x01 << 14))); 464 /* set memory buffer type */ 465 CFGW(OPTION2,(CFGR(OPTION2)&0xFFFFCFFF)|((si->ps.v3_option2_reg & 0x03) << 12)); 466 /* set mode register opcode and streamer flow control */ 467 ACCW(MEMRDBK,(ACCR(MEMRDBK)&0x0000FFFF)|(si->ps.memrdbk_reg & 0xffff0000)); 468 /* set RAM read tap delays */ 469 ACCW(MEMRDBK,(ACCR(MEMRDBK)&0xFFFF0000)|(si->ps.memrdbk_reg & 0x0000ffff)); 470 /* wait 200uS minimum */ 471 snooze(250); 472 473 /* reset memory (MACCESS is a write only register!) */ 474 ACCW(MACCESS, 0x00000000); 475 /* perform actual RAM reset */ 476 ACCW(MACCESS, 0x00008000); 477 snooze(250); 478 /* start memory refresh */ 479 CFGW(OPTION,(CFGR(OPTION)&0xffe07fff) | (si->ps.option_reg & 0x001f8000)); 480 /* set memory control waitstate again AFTER the RAM reset */ 481 ACCW(MCTLWTST,si->ps.mctlwtst_reg); 482 /* end 'official' RAM initialisation. */ 483 484 /* Bus parameters: enable retries, use advanced read */ 485 CFGW(OPTION,(CFGR(OPTION)|(1<<22)|(0<<29))); 486 487 /*enable writing to crtc registers*/ 488 VGAW_I(CRTC,0x11,0); 489 490 return B_OK; 491 } 492 493 static 494 status_t g400_general_powerup() 495 { 496 status_t result; 497 498 LOG(4, ("INIT: G400/G400MAX powerup\n")); 499 LOG(4, ("INIT: Detected %s (%s)\n", si->adi.name, si->adi.chipset)); 500 if (si->settings.logmask & 0x80000000) mga_dump_configuration_space(); 501 502 /* initialize the shared_info PINS struct */ 503 result = parse_pins(); 504 if (result != B_OK) fake_pins(); 505 506 /* log the PINS struct settings */ 507 dump_pins(); 508 509 /* if the user doesn't want a coldstart OR the BIOS pins info could not be found warmstart */ 510 if (si->settings.usebios || (result != B_OK)) return gx00_general_bios_to_powergraphics(); 511 512 /* reset MAVEN so we know the sync polarity is at reset situation (Hpos, Vpos) */ 513 if (si->ps.tvout) 514 { 515 ACCW(RST, 0x00000002); 516 snooze(1000); 517 ACCW(RST, 0x00000000); 518 } 519 520 /*power up the PLLs,LUT,DAC*/ 521 LOG(4,("INIT: PLL/LUT/DAC powerup\n")); 522 /* turn off both displays and the hardcursor (also disables transfers) */ 523 gx00_crtc_dpms(false, false, false); 524 g400_crtc2_dpms(false, false, false); 525 gx00_crtc_cursor_hide(); 526 527 /* set voltage reference - not using DAC reference block */ 528 DXIW(VREFCTRL,0x00); 529 /* wait for 100ms for voltage reference to stabilize */ 530 delay(100000); 531 /* power up the SYSPLL */ 532 CFGW(OPTION,CFGR(OPTION)|0x20); 533 /* power up the PIXPLL */ 534 DXIW(PIXCLKCTRL,0x08); 535 536 /* disable pixelclock oscillations before switching on CLUT */ 537 DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) | 0x04)); 538 /* disable 15bit mode CLUT-overlay function */ 539 DXIW(GENCTRL, DXIR(GENCTRL & 0xfd)); 540 /* CRTC2->MAFC, 8-bit DAC, CLUT enabled, enable DAC */ 541 DXIW(MISCCTRL,0x9b); 542 snooze(250); 543 /* re-enable pixelclock oscillations */ 544 DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) & 0xfb)); 545 546 DXIW(MAFCDEL,0x02); /*makes CRTC2 stable! Matrox specify 8, but use 4 - grrrr!*/ 547 DXIW(PANELMODE,0x00); /*eclipse panellink*/ 548 549 /* setup i2c bus */ 550 i2c_init(); 551 552 /* make sure card is in powergraphics mode */ 553 VGAW_I(CRTCEXT,3,0x80); 554 555 /* set the system clocks to powergraphics speed */ 556 LOG(2,("INIT: Setting system PLL to powergraphics speeds\n")); 557 g400_dac_set_sys_pll(); 558 559 /* 'official' RAM initialisation */ 560 LOG(2,("INIT: RAM init\n")); 561 /* disable hardware plane write mask if SDRAM card */ 562 if (si->ps.sdram) CFGW(OPTION,(CFGR(OPTION) & 0xffffbfff)); 563 /* disable plane write mask (needed for SDRAM): actual change needed to get it sent to RAM */ 564 ACCW(PLNWT,0x00000000); 565 ACCW(PLNWT,0xffffffff); 566 /* program memory control waitstates */ 567 ACCW(MCTLWTST, si->ps.mctlwtst_reg); 568 /* set memory configuration including: 569 * - SDRAM / SGRAM special functions select. */ 570 CFGW(OPTION,(CFGR(OPTION)&0xFFFF83FF) | (si->ps.option_reg & 0x00001c00)); 571 if (!si->ps.sdram) CFGW(OPTION,(CFGR(OPTION) | (0x01 << 14))); 572 /* set mode register opcode and streamer flow control */ 573 ACCW(MEMRDBK,(ACCR(MEMRDBK)&0x0000FFFF)|(si->ps.memrdbk_reg & 0xffff0000)); 574 /* set RAM read tap delays */ 575 ACCW(MEMRDBK,(ACCR(MEMRDBK)&0xFFFF0000)|(si->ps.memrdbk_reg & 0x0000ffff)); 576 /* wait 200uS minimum */ 577 snooze(250); 578 579 /* reset memory (MACCESS is a write only register!) */ 580 ACCW(MACCESS, 0x00000000); 581 /* perform actual RAM reset */ 582 ACCW(MACCESS, 0x00008000); 583 snooze(250); 584 /* start memory refresh */ 585 CFGW(OPTION,(CFGR(OPTION)&0xffe07fff) | (si->ps.option_reg & 0x001f8000)); 586 /* set memory control waitstate again AFTER the RAM reset */ 587 ACCW(MCTLWTST,si->ps.mctlwtst_reg); 588 /* end 'official' RAM initialisation. */ 589 590 /* 'advance read' busparameter and 'memory priority' enable/disable setup */ 591 CFGW(OPTION, ((CFGR(OPTION) & 0xefbfffff) | (si->ps.option_reg & 0x10400000))); 592 593 /*enable writing to crtc registers*/ 594 VGAW_I(CRTC,0x11,0); 595 if (si->ps.secondary_head) 596 { 597 MAVW(LOCK,0x01); 598 CR2W(DATACTL,0x00000000); 599 } 600 601 return B_OK; 602 } 603 604 static 605 status_t g450_general_powerup() 606 { 607 status_t result; 608 uint32 pwr_cas[] = {0, 1, 5, 6, 7, 5, 2, 3}; 609 610 /* used for convenience: MACCESS is a write only register! */ 611 uint32 maccess = 0x00000000; 612 613 LOG(4, ("INIT: G450/G550 powerup\n")); 614 LOG(4, ("INIT: Detected %s (%s)\n", si->adi.name, si->adi.chipset)); 615 if (si->settings.logmask & 0x80000000) mga_dump_configuration_space(); 616 617 /* initialize the shared_info PINS struct */ 618 result = parse_pins(); 619 if (result != B_OK) fake_pins(); 620 621 /* log the PINS struct settings */ 622 dump_pins(); 623 624 /* check output connector setup */ 625 if (si->ps.primary_dvi && si->ps.secondary_head && 626 si->ps.tvout && (i2c_sec_tv_adapter() != B_OK)) 627 { 628 /* signal CRTC2 DPMS which connector to program or readout */ 629 si->crossed_conns = true; 630 } 631 632 /* if the user doesn't want a coldstart OR the BIOS pins info could not be found warmstart */ 633 if (si->settings.usebios || (result != B_OK)) return gx00_general_bios_to_powergraphics(); 634 635 /* power up the PLLs,LUT,DAC */ 636 LOG(4,("INIT: PLL/LUT/DAC powerup\n")); 637 /* disable outputs */ 638 DXIW(OUTPUTCONN,0x00); 639 /* turn off both displays and the hardcursor (also disables transfers) */ 640 gx00_crtc_dpms(false, false, false); 641 g400_crtc2_dpms(false, false, false); 642 gx00_crtc_cursor_hide(); 643 644 /* power up everything except DVI electronics (for now) */ 645 DXIW(PWRCTRL,0x1b); 646 /* set voltage reference - not using DAC reference block */ 647 DXIW(VREFCTRL,0x00); 648 /* wait for 100ms for voltage reference to stabilize */ 649 delay(100000); 650 /* power up the SYSPLL */ 651 CFGW(OPTION,CFGR(OPTION)|0x20); 652 /* power up the PIXPLL */ 653 DXIW(PIXCLKCTRL,0x08); 654 655 /* disable pixelclock oscillations before switching on CLUT */ 656 DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) | 0x04)); 657 /* disable 15bit mode CLUT-overlay function */ 658 DXIW(GENCTRL, DXIR(GENCTRL & 0xfd)); 659 /* CRTC2->MAFC, 8-bit DAC, CLUT enabled, enable DAC */ 660 DXIW(MISCCTRL,0x9b); 661 snooze(250); 662 663 /* re-enable pixelclock oscillations */ 664 DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) & 0xfb)); 665 666 //fixme: 667 DXIW(MAFCDEL,0x02); /*makes CRTC2 stable! Matrox specify 8, but use 4 - grrrr!*/ 668 DXIW(PANELMODE,0x00); /*eclipse panellink*/ 669 670 /* setup i2c bus */ 671 i2c_init(); 672 673 /* make sure card is in powergraphics mode */ 674 VGAW_I(CRTCEXT,3,0x80); 675 676 /* set the system clocks to powergraphics speed */ 677 LOG(2,("INIT: Setting system PLL to powergraphics speeds\n")); 678 g450_dac_set_sys_pll(); 679 680 /* 'official' RAM initialisation */ 681 LOG(2,("INIT: RAM init\n")); 682 /* stop memory refresh, and setup b9, memconfig, b13, sgram planemask function, b21 fields, 683 * and don't touch the rest */ 684 CFGW(OPTION, ((CFGR(OPTION) & 0xf8400164) | (si->ps.option_reg & 0x00207e00))); 685 /* setup b10-b15 unknown field */ 686 CFGW(OPTION2, ((CFGR(OPTION2) & 0xffff0200) | (si->ps.option2_reg & 0x0000fc00))); 687 688 /* program memory control waitstates */ 689 ACCW(MCTLWTST, si->ps.mctlwtst_reg); 690 /* program option4 b0-3 and b29-30 fields, reset the rest: stop memory clock */ 691 CFGW(OPTION4, (si->ps.option4_reg & 0x6000000f)); 692 /* set RAM read tap delays and mode register opcode / streamer flow control */ 693 ACCW(MEMRDBK, si->ps.memrdbk_reg); 694 /* b7 v5_mem_type = done by Mark Watson. fixme: still confirm! (unknown bits) */ 695 maccess = ((((uint32)si->ps.v5_mem_type) & 0x80) >> 1); 696 ACCW(MACCESS, maccess); 697 /* clear b0-1 and 3, and set b31 in option4: re-enable memory clock */ 698 CFGW(OPTION4, ((si->ps.option4_reg & 0x60000004) | 0x80000000)); 699 snooze(250); 700 701 /* if DDR RAM */ 702 if ((si->ps.v5_mem_type & 0x0060) == 0x0020) 703 { 704 /* if not 'EMRSW RAM-option' available */ 705 if (!(si->ps.v5_mem_type & 0x0100)) 706 { 707 /* clear unknown bits */ 708 maccess = 0x00000000; 709 ACCW(MACCESS, maccess); 710 /* clear b12: unknown bit */ 711 ACCW(MEMRDBK, (si->ps.memrdbk_reg & 0xffffefff)); 712 } 713 else 714 /* if not 'DLL RAM-option' available */ 715 if (!(si->ps.v5_mem_type & 0x0200)) 716 { 717 /* clear b12: unknown bit */ 718 ACCW(MEMRDBK, (si->ps.memrdbk_reg & 0xffffefff)); 719 } 720 } 721 722 /* create positive flank to generate memory reset */ 723 //fixme: G550 is still noted as a G450, fix upon trouble.. 724 if (si->ps.card_type == G450) { 725 ACCW(MACCESS, (maccess & 0xffff3fff)); 726 ACCW(MACCESS, (maccess | 0x0000c000)); 727 } else { //G550 728 ACCW(MACCESS, (maccess & 0xffff7fff)); 729 ACCW(MACCESS, (maccess | 0x00008000)); 730 } 731 snooze(250); 732 733 /* start memory refresh */ 734 CFGW(OPTION,(CFGR(OPTION)&0xffe07fff) | (si->ps.option_reg & 0x001f8000)); 735 736 /* disable plane write mask (needed for SDRAM): actual change needed to get it sent to RAM */ 737 ACCW(PLNWT,0x00000000); 738 ACCW(PLNWT,0xffffffff); 739 740 /* if not 'MEMCASLT RAM-option' available */ 741 if (!(si->ps.v5_mem_type & 0x0400)) 742 { 743 /* calculate powergraphics CAS-latency from pins CAS-latency, and update register setting */ 744 ACCW(MCTLWTST, 745 ((si->ps.mctlwtst_reg & 0xfffffff8) | pwr_cas[(si->ps.mctlwtst_reg & 0x07)])); 746 747 } 748 749 /*enable writing to crtc registers*/ 750 VGAW_I(CRTC,0x11,0); 751 //fixme.. 752 if (si->ps.secondary_head) 753 { 754 //MAVW(LOCK,0x01); 755 CR2W(DATACTL,0x00000000); 756 } 757 758 /* enable primary analog output */ 759 gx50_general_output_select(); 760 761 /* enable 'straight-through' sync outputs on both analog output connectors and 762 * make sure CRTC1 sync outputs are patched through! */ 763 DXIW(SYNCCTRL,0x00); 764 765 return B_OK; 766 } 767 768 status_t gx50_general_output_select() 769 { 770 /* make sure this call is warranted */ 771 if ((si->ps.card_type != G450) && (si->ps.card_type != G550)) return B_ERROR; 772 773 /* choose primary analog outputconnector */ 774 if (si->ps.primary_dvi && si->ps.secondary_head && si->ps.tvout) 775 { 776 if (i2c_sec_tv_adapter() == B_OK) 777 { 778 LOG(4,("INIT: secondary TV-adapter detected, using primary connector\n")); 779 DXIW(OUTPUTCONN,0x01); 780 /* signal CRTC2 DPMS which connector to program */ 781 si->crossed_conns = false; 782 } 783 else 784 { 785 LOG(4,("INIT: no secondary TV-adapter detected, using secondary connector\n")); 786 DXIW(OUTPUTCONN,0x04); 787 /* signal CRTC2 DPMS which connector to program */ 788 si->crossed_conns = true; 789 } 790 } 791 else 792 { 793 LOG(4,("INIT: using primary connector\n")); 794 DXIW(OUTPUTCONN,0x01); 795 /* signal CRTC2 DPMS which connector to program */ 796 si->crossed_conns = false; 797 } 798 return B_OK; 799 } 800 801 /* connect CRTC(s) to the specified DAC(s) */ 802 status_t gx00_general_dac_select(int dac) 803 { 804 /*MISCCTRL, clock src,...*/ 805 switch(dac) 806 { 807 /* G100 - G400 */ 808 case DS_CRTC1DAC: 809 case DS_CRTC1DAC_CRTC2MAVEN: 810 /* connect CRTC1 to pixPLL */ 811 DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0xc)|0x1); 812 /* connect CRTC2 to vidPLL, connect CRTC1 to internal DAC and 813 * enable CRTC2 external video timing reset signal. 814 * (Setting for MAVEN 'master mode' TVout signal generation.) */ 815 if (si->ps.secondary_head) CR2W(CTL,(CR2R(CTL)&0xffe00779)|0xD0000002); 816 /* disable CRTC1 external video timing reset signal */ 817 VGAW_I(CRTCEXT,1,(VGAR_I(CRTCEXT,1)&0x77)); 818 /* select CRTC2 RGB24 MAFC mode: connects CRTC2 to MAVEN DAC */ 819 DXIW(MISCCTRL,(DXIR(MISCCTRL)&0x19)|0x82); 820 break; 821 case DS_CRTC1MAVEN: 822 case DS_CRTC1MAVEN_CRTC2DAC: 823 /* connect CRTC1 to vidPLL */ 824 DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0xc)|0x2); 825 /* connect CRTC2 to pixPLL and internal DAC and 826 * disable CRTC2 external video timing reset signal */ 827 if (si->ps.secondary_head) CR2W(CTL,(CR2R(CTL)&0x2fe00779)|0x4|(0x1<<20)); 828 /* enable CRTC1 external video timing reset signal. 829 * note: this is nolonger used as G450/G550 cannot do TVout on CRTC1 */ 830 VGAW_I(CRTCEXT,1,(VGAR_I(CRTCEXT,1)|0x88)); 831 /* select CRTC1 RGB24 MAFC mode: connects CRTC1 to MAVEN DAC */ 832 DXIW(MISCCTRL,(DXIR(MISCCTRL)&0x19)|0x02); 833 break; 834 /* G450/G550 */ 835 case DS_CRTC1CON1_CRTC2CON2: 836 if (si->ps.card_type < G450) return B_ERROR; 837 /* connect CRTC1 to pixPLL */ 838 DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0xc)|0x1); 839 /* connect CRTC2 to vidPLL, connect CRTC1 to DAC1, disable CRTC2 840 * external video timing reset signal, set CRTC2 progressive scan mode 841 * and disable TVout mode (b12). 842 * (Setting for MAVEN 'slave mode' TVout signal generation.) */ 843 //fixme: enable timing resets if TVout is used in master mode! 844 //otherwise keep it disabled. 845 CR2W(CTL,(CR2R(CTL)&0x2de00779)|0x6|(0x0<<20)); 846 /* connect DAC1 to CON1, CRTC2/'DAC2' to CON2 (monitor mode) */ 847 DXIW(OUTPUTCONN,0x09); 848 /* Select 1.5 Volt MAVEN DAC ref. for monitor mode */ 849 DXIW(GENIOCTRL, DXIR(GENIOCTRL) & ~0x40); 850 DXIW(GENIODATA, 0x00); 851 /* signal CRTC2 DPMS which connector to program */ 852 si->crossed_conns = false; 853 break; 854 //fixme: toggle PLL's below if possible: 855 // otherwise toggle PLL's for G400 2nd case? 856 case DS_CRTC1CON2_CRTC2CON1: 857 if (si->ps.card_type < G450) return B_ERROR; 858 /* connect CRTC1 to pixPLL */ 859 DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0xc)|0x1); 860 /* connect CRTC2 to vidPLL and DAC1, disable CRTC2 external 861 * video timing reset signal, and set CRTC2 progressive scan mode and 862 * disable TVout mode (b12). */ 863 CR2W(CTL,(CR2R(CTL)&0x2de00779)|0x6|(0x1<<20)); 864 /* connect DAC1 to CON2 (monitor mode), CRTC2/'DAC2' to CON1 */ 865 DXIW(OUTPUTCONN,0x05); 866 /* Select 1.5 Volt MAVEN DAC ref. for monitor mode */ 867 DXIW(GENIOCTRL, DXIR(GENIOCTRL) & ~0x40); 868 DXIW(GENIODATA, 0x00); 869 /* signal CRTC2 DPMS which connector to program */ 870 si->crossed_conns = true; 871 break; 872 default: 873 return B_ERROR; 874 } 875 return B_OK; 876 } 877 878 /* basic change of card state from VGA to powergraphics -> should work from BIOS init state*/ 879 static 880 status_t gx00_general_bios_to_powergraphics() 881 { 882 LOG(2, ("INIT: Skipping card coldstart!\n")); 883 884 //set to powergraphics etc. 885 CFGW(DEVCTRL,(2|CFGR(DEVCTRL))); 886 /*enable device response (already enabled here!)*/ 887 888 VGAW_I(CRTC,0x11,0); 889 /*allow me to change CRTC*/ 890 891 VGAW_I(CRTCEXT,3,0x80); 892 /*use powergraphix (+ trash other bits, they are set later)*/ 893 894 VGAW(MISCW,0x08); 895 /*set only MGA pixel clock in MISC - I don't want to map VGA stuff under this OS*/ 896 897 switch (si->ps.card_type) 898 { 899 case G400: 900 case G400MAX: 901 /* reset MAVEN so we know the sync polarity is at reset situation (Hpos, Vpos) */ 902 if (si->ps.tvout) 903 { 904 ACCW(RST, 0x00000002); 905 snooze(1000); 906 ACCW(RST, 0x00000000); 907 } 908 /* makes CRTC2 stable! Matrox specify 8, but use 4 - grrrr! */ 909 DXIW(MAFCDEL,0x02); 910 break; 911 case G450: 912 case G550: 913 /* power up everything except DVI electronics (for now) */ 914 DXIW(PWRCTRL,0x1b); 915 /* enable 'straight-through' sync outputs on both analog output 916 * connectors and make sure CRTC1 sync outputs are patched through! */ 917 DXIW(SYNCCTRL,0x00); 918 break; 919 default: 920 break; 921 } 922 923 if (si->ps.card_type >= G100) 924 { 925 DXIW(MISCCTRL,0x9b); 926 /*CRTC2->MAFC, 8-bit DAC, CLUT enabled, enable DAC*/ 927 928 DXIW(MULCTRL,0x4); 929 /*RGBA direct mode*/ 930 } 931 else 932 { 933 LOG(8, ("INIT: < G100 DAC powerup badly implemented, MISC 0x%02x\n", VGAR(MISCR))); 934 } // apsed TODO MIL2 935 936 VGAW_I(SEQ,1,0x00); 937 /*enable screen*/ 938 939 return B_OK; 940 } 941 942 /* Check if mode virtual_size adheres to the cards _maximum_ contraints, and modify 943 * virtual_size to the nearest valid maximum for the mode on the card if not so. 944 * Then: check if virtual_width adheres to the cards _multiple_ constraints, and 945 * create mode slopspace if not so. 946 * We use acc multiple constraints here if we expect we can use acceleration, because 947 * acc constraints are worse than CRTC constraints. 948 * 949 * Mode slopspace is reflected in fbc->bytes_per_row BTW. */ 950 //fixme: seperate heads for real dualhead modes: 951 //CRTC1 and 2 constraints differ! 952 status_t gx00_general_validate_pic_size (display_mode *target, uint32 *bytes_per_row, bool *acc_mode) 953 { 954 /* Note: 955 * This routine assumes that the CRTC memory pitch granularity is 'smaller than', 956 * or 'equals' the acceleration engine memory pitch granularity! */ 957 958 uint32 video_pitch; 959 uint32 acc_mask, crtc_mask; 960 uint8 depth = 8; 961 962 /* determine pixel multiple based on 2D/3D engine constraints */ 963 switch (si->ps.card_type) 964 { 965 case MIL1: 966 case MIL2: 967 /* see MIL1/2 specs: 968 * these cards always use a 64bit RAMDAC (TVP3026) and interleaved memory */ 969 switch (target->space) 970 { 971 case B_CMAP8: acc_mask = 0x7f; depth = 8; break; 972 case B_RGB15: acc_mask = 0x3f; depth = 16; break; 973 case B_RGB16: acc_mask = 0x3f; depth = 16; break; 974 case B_RGB24: acc_mask = 0x7f; depth = 24; break; 975 case B_RGB32: acc_mask = 0x1f; depth = 32; break; 976 default: 977 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 978 return B_ERROR; 979 } 980 break; 981 default: 982 /* see G100 and up specs: 983 * these cards can do 2D as long as multiples of 32 are used. 984 * (Note: don't mix this up with adress linearisation!) */ 985 switch (target->space) 986 { 987 case B_CMAP8: depth = 8; break; 988 case B_RGB15: depth = 16; break; 989 case B_RGB16: depth = 16; break; 990 case B_RGB24: depth = 24; break; 991 case B_RGB32: depth = 32; break; 992 default: 993 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 994 return B_ERROR; 995 } 996 acc_mask = 0x1f; 997 break; 998 } 999 1000 /* determine pixel multiple based on CRTC memory pitch constraints. 1001 * (Note: Don't mix this up with CRTC timing contraints! Those are 1002 * multiples of 8 for horizontal, 1 for vertical timing.) */ 1003 switch (si->ps.card_type) 1004 { 1005 case MIL1: 1006 case MIL2: 1007 /* see MIL1/2 specs: 1008 * these cards always use a 64bit RAMDAC and interleaved memory */ 1009 switch (target->space) 1010 { 1011 case B_CMAP8: crtc_mask = 0x7f; break; 1012 case B_RGB15: crtc_mask = 0x3f; break; 1013 case B_RGB16: crtc_mask = 0x3f; break; 1014 /* for B_RGB24 crtc_mask 0x7f is worst case scenario (MIL2 constraint) */ 1015 case B_RGB24: crtc_mask = 0x7f; break; 1016 case B_RGB32: crtc_mask = 0x1f; break; 1017 default: 1018 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 1019 return B_ERROR; 1020 } 1021 break; 1022 default: 1023 /* see G100 and up specs */ 1024 switch (target->space) 1025 { 1026 case B_CMAP8: crtc_mask = 0x0f; break; 1027 case B_RGB15: crtc_mask = 0x07; break; 1028 case B_RGB16: crtc_mask = 0x07; break; 1029 case B_RGB24: crtc_mask = 0x0f; break; 1030 case B_RGB32: crtc_mask = 0x03; break; 1031 default: 1032 LOG(8,("INIT: unknown color space: 0x%08x\n", target->space)); 1033 return B_ERROR; 1034 } 1035 /* see G400 specs: CRTC2 has different constraints */ 1036 /* Note: 1037 * set for RGB and B_YCbCr422 modes. Other modes need larger multiples! */ 1038 if (target->flags & DUALHEAD_BITS) 1039 { 1040 switch (target->space) 1041 { 1042 case B_RGB16: crtc_mask = 0x1f; break; 1043 case B_RGB32: crtc_mask = 0x0f; break; 1044 default: 1045 LOG(8,("INIT: illegal DH color space: 0x%08x\n", target->space)); 1046 return B_ERROR; 1047 } 1048 } 1049 break; 1050 } 1051 1052 /* check if we can setup this mode with acceleration: 1053 * Max sizes need to adhere to both the acceleration engine _and_ the CRTC constraints! */ 1054 *acc_mode = true; 1055 /* check virtual_width */ 1056 switch (si->ps.card_type) 1057 { 1058 case MIL1: 1059 case MIL2: 1060 case G100: 1061 /* acc constraint: */ 1062 if (target->virtual_width > 2048) *acc_mode = false; 1063 break; 1064 default: 1065 /* G200-G550 */ 1066 /* acc constraint: */ 1067 if (target->virtual_width > 4096) *acc_mode = false; 1068 /* for 32bit mode a lower CRTC1 restriction applies! */ 1069 if ((target->space == B_RGB32_LITTLE) && (target->virtual_width > (4092 & ~acc_mask))) 1070 *acc_mode = false; 1071 break; 1072 } 1073 /* virtual_height */ 1074 if (target->virtual_height > 2048) *acc_mode = false; 1075 1076 /* now check virtual_size based on CRTC constraints, 1077 * making sure virtual_width stays within the 'mask' constraint: which is only 1078 * nessesary because of an extra constraint in MIL1/2 cards that exists here. */ 1079 { 1080 /* virtual_width */ 1081 //fixme for CRTC2 (identical on all G400+ cards): 1082 //16bit mode: max. virtual_width == 16352 (no extra mask needed); 1083 //32bit mode: max. virtual_width == 8176 (no extra mask needed); 1084 //other colordepths are unsupported on CRTC2. 1085 switch(target->space) 1086 { 1087 case B_CMAP8: 1088 if (target->virtual_width > (16368 & ~crtc_mask)) 1089 target->virtual_width = (16368 & ~crtc_mask); 1090 break; 1091 case B_RGB15_LITTLE: 1092 case B_RGB16_LITTLE: 1093 if (target->virtual_width > (8184 & ~crtc_mask)) 1094 target->virtual_width = (8184 & ~crtc_mask); 1095 break; 1096 case B_RGB24_LITTLE: 1097 if (target->virtual_width > (5456 & ~crtc_mask)) 1098 target->virtual_width = (5456 & ~crtc_mask); 1099 break; 1100 case B_RGB32_LITTLE: 1101 if (target->virtual_width > (4092 & ~crtc_mask)) 1102 target->virtual_width = (4092 & ~crtc_mask); 1103 break; 1104 } 1105 1106 /* virtual_height: The only constraint here is the cards memory size which is 1107 * checked later on in ProposeMode: virtual_height is adjusted then if needed. 1108 * 'Limiting here' to the variable size that's at least available (uint16). */ 1109 if (target->virtual_height > 65535) target->virtual_height = 65535; 1110 } 1111 1112 /* OK, now we know that virtual_width is valid, and it's needing no slopspace if 1113 * it was confined above, so we can finally calculate safely if we need slopspace 1114 * for this mode... */ 1115 if (*acc_mode) 1116 video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask); 1117 else 1118 video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask); 1119 1120 LOG(2,("INIT: memory pitch will be set to %d pixels for colorspace 0x%08x\n", 1121 video_pitch, target->space)); 1122 if (target->virtual_width != video_pitch) 1123 LOG(2,("INIT: effective mode slopspace is %d pixels\n", 1124 (video_pitch - target->virtual_width))); 1125 1126 /* now calculate bytes_per_row for this mode */ 1127 *bytes_per_row = video_pitch * (depth >> 3); 1128 1129 return B_OK; 1130 } 1131