1 /* Author: 2 Rudolf Cornelissen 4/2003-1/2004 3 */ 4 5 #define MODULE_BIT 0x00008000 6 7 #include "nm_std.h" 8 9 static status_t test_ram(void); 10 static status_t nmxxxx_general_powerup (void); 11 static status_t nm_general_bios_to_powergraphics(void); 12 13 static void nm_dump_configuration_space (void) 14 { 15 #define DUMP_CFG(reg, type) if (si->ps.card_type >= type) do { \ 16 uint32 value = CFGR(reg); \ 17 MSG(("configuration_space 0x%02x %20s 0x%08x\n", \ 18 NMCFG_##reg, #reg, value)); \ 19 } while (0) 20 DUMP_CFG (DEVID, 0); 21 DUMP_CFG (DEVCTRL, 0); 22 DUMP_CFG (CLASS, 0); 23 DUMP_CFG (HEADER, 0); 24 DUMP_CFG (NMBASE2, 0); 25 DUMP_CFG (NMBASE1, 0); 26 DUMP_CFG (NMBASE3, 0); 27 DUMP_CFG (SUBSYSIDR, 0); 28 DUMP_CFG (ROMBASE, 0); 29 DUMP_CFG (CAP_PTR, 0); 30 DUMP_CFG (INTCTRL, 0); 31 DUMP_CFG (OPTION, 0); 32 DUMP_CFG (NM_INDEX, 0); 33 DUMP_CFG (NM_DATA, 0); 34 DUMP_CFG (SUBSYSIDW, 0); 35 DUMP_CFG (OPTION2, G100); 36 DUMP_CFG (OPTION3, 0); 37 DUMP_CFG (OPTION4, 0); 38 DUMP_CFG (PM_IDENT, G100); 39 DUMP_CFG (PM_CSR, G100); 40 DUMP_CFG (AGP_IDENT, 0); 41 DUMP_CFG (AGP_STS, 0); 42 DUMP_CFG (AGP_CMD, 0); 43 #undef DUMP_CFG 44 } 45 46 status_t nm_general_powerup() 47 { 48 status_t status; 49 50 LOG(1,("POWERUP: Neomagic (open)BeOS Accelerant 0.06-1 running.\n")); 51 52 /* detect card type and power it up */ 53 switch(CFGR(DEVID)) 54 { 55 case 0x000110c8: //NM2070 ISA 56 si->ps.card_type = NM2070; 57 LOG(4,("POWERUP: Detected MagicGraph 128 (NM2070)\n")); 58 break; 59 case 0x000210c8: //NM2090 ISA 60 si->ps.card_type = NM2090; 61 LOG(4,("POWERUP: Detected MagicGraph 128V (NM2090)\n")); 62 break; 63 case 0x000310c8: //NM2093 ISA 64 si->ps.card_type = NM2093; 65 LOG(4,("POWERUP: Detected MagicGraph 128ZV (NM2093)\n")); 66 break; 67 case 0x008310c8: //NM2097 PCI 68 si->ps.card_type = NM2097; 69 LOG(4,("POWERUP: Detected MagicGraph 128ZV+ (NM2097)\n")); 70 break; 71 case 0x000410c8: //NM2160 PCI 72 si->ps.card_type = NM2160; 73 LOG(4,("POWERUP: Detected MagicGraph 128XD (NM2160)\n")); 74 break; 75 case 0x000510c8: //NM2200 76 si->ps.card_type = NM2200; 77 LOG(4,("POWERUP: Detected MagicMedia 256AV (NM2200)\n")); 78 break; 79 case 0x002510c8: //NM2230 80 si->ps.card_type = NM2230; 81 LOG(4,("POWERUP: Detected MagicMedia 256AV+ (NM2230)\n")); 82 break; 83 case 0x000610c8: //NM2360 84 si->ps.card_type = NM2360; 85 LOG(4,("POWERUP: Detected MagicMedia 256ZX (NM2360)\n")); 86 break; 87 case 0x001610c8: //NM2380 88 si->ps.card_type = NM2380; 89 LOG(4,("POWERUP: Detected MagicMedia 256XL+ (NM2380)\n")); 90 break; 91 default: 92 LOG(8,("POWERUP: Failed to detect valid card 0x%08x\n",CFGR(DEVID))); 93 return B_ERROR; 94 } 95 96 /* power up the card */ 97 status = nmxxxx_general_powerup(); 98 99 /* override memory detection if requested by user */ 100 if (si->settings.memory != 0) 101 si->ps.memory_size = si->settings.memory; 102 103 return status; 104 } 105 106 static status_t test_ram(void) 107 { 108 uint32 value, offset; 109 status_t result = B_OK; 110 111 /* make sure we don't corrupt the hardware cursor by using fbc.frame_buffer. */ 112 if (si->fbc.frame_buffer == NULL) 113 { 114 LOG(8,("INIT: test_ram detected NULL pointer.\n")); 115 return B_ERROR; 116 } 117 118 for (offset = 0, value = 0x55aa55aa; offset < 256; offset++) 119 { 120 /* write testpattern to cardRAM */ 121 ((uint32 *)si->fbc.frame_buffer)[offset] = value; 122 /* toggle testpattern */ 123 value = 0xffffffff - value; 124 } 125 126 for (offset = 0, value = 0x55aa55aa; offset < 256; offset++) 127 { 128 /* readback and verify testpattern from cardRAM */ 129 if (((uint32 *)si->fbc.frame_buffer)[offset] != value) result = B_ERROR; 130 /* toggle testpattern */ 131 value = 0xffffffff - value; 132 } 133 return result; 134 } 135 136 /* NOTE: 137 * This routine *has* to be done *after* SetDispplayMode has been executed, 138 * or test results will not be representative! 139 * (CAS latency is dependant on nm setup on some (DRAM) boards) */ 140 status_t nm_set_cas_latency() 141 { 142 /* check current RAM access to see if we need to change anything */ 143 if (test_ram() == B_OK) 144 { 145 LOG(4,("INIT: RAM access OK.\n")); 146 return B_OK; 147 } 148 149 /* check if we read PINS at starttime so we have valid registersettings at our disposal */ 150 LOG(4,("INIT: RAM access errors; not fixable: missing coldstart specs.\n")); 151 return B_ERROR; 152 } 153 154 static status_t nmxxxx_general_powerup() 155 { 156 uint8 temp; 157 // status_t result; 158 159 LOG(4, ("INIT: powerup\n")); 160 if (si->settings.logmask & 0x80000000) nm_dump_configuration_space(); 161 162 /* set ISA registermapping to VGA colormode */ 163 temp = (ISARB(MISCR) | 0x01); 164 /* we need to wait a bit or the card will mess-up it's register values.. */ 165 snooze(10); 166 ISAWB(MISCW, temp); 167 168 /* unlock cards GRAPHICS registers (any other value than 0x26 should lock it again) */ 169 ISAGRPHW(GRPHXLOCK, 0x26); 170 171 /* unlock cards CRTC registers */ 172 //don't touch: most cards get into trouble on this! 173 // ISAGRPHW(GENLOCK, 0x00); 174 175 /* initialize the shared_info struct */ 176 set_specs(); 177 /* log the struct settings */ 178 dump_specs(); 179 180 /* activate PCI access: b7 = framebuffer, b6 = registers */ 181 ISAGRPHW(IFACECTRL, 0xc0); 182 183 /* disable VGA-mode cursor (just to be sure) */ 184 ISACRTCW(VGACURCTRL, 0x00); 185 186 /* if the user doesn't want a coldstart OR the BIOS pins info could not be found warmstart */ 187 /*if (si->settings.usebios || (result != B_OK)) */return nm_general_bios_to_powergraphics(); 188 189 /*power up the PLLs,LUT,DAC*/ 190 LOG(2,("INIT: powerup\n")); 191 192 /* turn off both displays and the hardcursor (also disables transfers) */ 193 nm_crtc_dpms(false, false, false); 194 nm_crtc_cursor_hide(); 195 196 /* setup sequencer clocking mode */ 197 ISASEQW(CLKMODE, 0x21); 198 199 /* G100 SGRAM and SDRAM use external pix and dac refs, do *not* activate internals! 200 * (this would create electrical shortcuts, 201 * resulting in extra chip heat and distortions visible on screen */ 202 /* set voltage reference - using DAC reference block partly */ 203 // DXIW(VREFCTRL,0x03); 204 /* wait for 100ms for voltage reference to stabilize */ 205 delay(100000); 206 /* power up the SYSPLL */ 207 // CFGW(OPTION,CFGR(OPTION)|0x20); 208 /* power up the PIXPLL */ 209 // DXIW(PIXCLKCTRL,0x08); 210 211 /* disable pixelclock oscillations before switching on CLUT */ 212 // DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) | 0x04)); 213 /* disable 15bit mode CLUT-overlay function */ 214 // DXIW(GENCTRL, DXIR(GENCTRL & 0xfd)); 215 /* CRTC2->MAFC, 8-bit DAC, CLUT enabled, enable DAC */ 216 // DXIW(MISCCTRL,0x1b); 217 // snooze(250); 218 /* re-enable pixelclock oscillations */ 219 // DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) & 0xfb)); 220 221 /*make sure card is in powergraphics mode*/ 222 // VGAW_I(CRTCEXT,3,0x80); 223 224 /*set the system clocks to powergraphics speed*/ 225 // LOG(2,("INIT: Setting system PLL to powergraphics speeds\n")); 226 // g100_dac_set_sys_pll(); 227 228 /* 'official' RAM initialisation */ 229 // LOG(2,("INIT: RAM init\n")); 230 /* disable plane write mask (needed for SDRAM): actual change needed to get it sent to RAM */ 231 // ACCW(PLNWT,0x00000000); 232 // ACCW(PLNWT,0xffffffff); 233 /* program memory control waitstates */ 234 // ACCW(MCTLWTST,si->ps.mctlwtst_reg); 235 /* set memory configuration including: 236 * - no split framebuffer. 237 * - Mark says b14 (G200) should be done also though not defined for G100 in spec, 238 * - b3 v3_mem_type was included by Mark for memconfig setup: but looks like not defined */ 239 // CFGW(OPTION,(CFGR(OPTION)&0xFFFF8FFF) | ((si->ps.v3_mem_type & 0x04) << 10)); 240 /* set memory buffer type: 241 * - Mark says: if((v3_mem_type & 0x03) == 0x03) then do not or-in bits in option2; 242 * but looks like v3_mem_type b1 is not defined, 243 * - Mark also says: place v3_mem_type b1 in option2 bit13 (if not 0x03) but b13 = reserved. */ 244 // CFGW(OPTION2,(CFGR(OPTION2)&0xFFFFCFFF)|((si->ps.v3_mem_type & 0x01) << 12)); 245 /* set RAM read tap delay */ 246 // CFGW(OPTION2,(CFGR(OPTION2)&0xFFFFFFF0) | ((si->ps.v3_mem_type & 0xf0) >> 4)); 247 /* wait 200uS minimum */ 248 // snooze(250); 249 250 /* reset memory (MACCESS is a write only register!) */ 251 // ACCW(MACCESS, 0x00000000); 252 /* select JEDEC reset method */ 253 // ACCW(MACCESS, 0x00004000); 254 /* perform actual RAM reset */ 255 // ACCW(MACCESS, 0x0000c000); 256 // snooze(250); 257 /* start memory refresh */ 258 // CFGW(OPTION,(CFGR(OPTION)&0xffe07fff) | (si->ps.option_reg & 0x001f8000)); 259 /* set memory control waitstate again AFTER the RAM reset */ 260 // ACCW(MCTLWTST,si->ps.mctlwtst_reg); 261 /* end 'official' RAM initialisation. */ 262 263 /* Bus parameters: enable retries, use advanced read */ 264 // CFGW(OPTION,(CFGR(OPTION)|(1<<22)|(0<<29))); 265 266 /*enable writing to crtc registers*/ 267 // VGAW_I(CRTC,0x11,0); 268 269 /* turn on display */ 270 nm_crtc_dpms(true, true, true); 271 272 return B_OK; 273 } 274 275 status_t nm_general_output_select() 276 { 277 /* log currently selected output */ 278 switch (nm_general_output_read()) 279 { 280 case 0x01: 281 LOG(2, ("INIT: external CRT only mode active\n")); 282 break; 283 case 0x02: 284 LOG(2, ("INIT: internal LCD only mode active\n")); 285 break; 286 case 0x03: 287 LOG(2, ("INIT: simultaneous LCD/CRT mode active\n")); 288 break; 289 } 290 return B_OK; 291 } 292 293 uint8 nm_general_output_read() 294 { 295 uint8 output; 296 297 output = (ISAGRPHR(PANELCTRL1) & 0x03); 298 299 if (output == 0) 300 { 301 /* using 'failsafe' mode: the flatpanel needs all the protection it can get... */ 302 LOG(4, ("INIT: illegal outputmode detected, reporting internal mode!\n")); 303 output = 2; 304 } 305 306 return output; 307 } 308 309 /* basic change of card state from VGA to powergraphics -> should work from BIOS init state*/ 310 static 311 status_t nm_general_bios_to_powergraphics() 312 { 313 LOG(2, ("INIT: Skipping card coldstart!\n")); 314 315 /* turn off display */ 316 nm_crtc_dpms(false, false, false); 317 318 /* set card to 'enhanced' mode: (only VGA standard registers used for NeoMagic cards) */ 319 /* (keep) card enabled, set plain normal memory usage, no old VGA 'tricks' ... */ 320 ISACRTCW(MODECTL, 0xc3); 321 /* ... plain sequential memory use, more than 64Kb RAM installed, 322 * switch to graphics mode ... */ 323 ISASEQW(MEMMODE, 0x0e); 324 /* ... disable bitplane tweaking ... */ 325 ISAGRPHW(ENSETRESET, 0x00); 326 /* ... no logical function tweaking with display data, no data rotation ... */ 327 ISAGRPHW(DATAROTATE, 0x00); 328 /* ... reset read map select to plane 0 ... */ 329 ISAGRPHW(READMAPSEL, 0x00); 330 /* ... set standard mode ... */ 331 ISAGRPHW(MODE, 0x00); 332 /* ... ISA framebuffer mapping is 64Kb window, switch to graphics mode (again), 333 * select standard adressing ... */ 334 ISAGRPHW(MISC, 0x05); 335 /* ... disable bit masking ... */ 336 ISAGRPHW(BITMASK, 0xff); 337 /* ... attributes are in color, switch to graphics mode (again) ... */ 338 ISAATBW(MODECTL, 0x01); 339 /* ... set overscan color to black ... */ 340 ISAATBW(OSCANCOLOR, 0x00); 341 /* ... enable all color planes ... */ 342 ISAATBW(COLPLANE_EN, 0x0f); 343 /* ... reset horizontal pixelpanning ... */ 344 ISAATBW(HORPIXPAN, 0x00); 345 /* ... and reset colorpalette groupselect bits. */ 346 ISAATBW(COLSEL, 0x00); 347 348 /* setup sequencer clocking mode */ 349 ISASEQW(CLKMODE, 0x21); 350 351 /* enable memory above 256Kb: set b4 (disables adress wraparound at 256Kb boundary) */ 352 ISAGRPHW(FBSTADDE, 0x10); 353 354 /* turn on display */ 355 nm_crtc_dpms(true, true, true); 356 357 return B_OK; 358 } 359 360 /* Check if mode virtual_size adheres to the cards _maximum_ contraints, and modify 361 * virtual_size to the nearest valid maximum for the mode on the card if not so. 362 * Then: check if virtual_width adheres to the cards _multiple_ constraints, and 363 * create mode slopspace if not so. 364 * We use acc multiple constraints here if we expect we can use acceleration, because 365 * acc constraints are worse than CRTC constraints. 366 * 367 * Mode slopspace is reflected in fbc->bytes_per_row BTW. */ 368 status_t nm_general_validate_pic_size (display_mode *target, uint32 *bytes_per_row, bool *acc_mode) 369 { 370 /* Note: 371 * This routine assumes that the CRTC memory pitch granularity is 'smaller than', 372 * or 'equals' the acceleration engine memory pitch granularity! */ 373 374 uint32 video_pitch; 375 uint32 acc_mask, crtc_mask; 376 uint8 depth = 8; 377 378 //fixme: checkout the acc pitch constraints for all cards... 379 /* determine pixel multiple based on 2D/3D engine constraints */ 380 switch (si->ps.card_type) 381 { 382 /* case G100: 383 switch (target->space) 384 { 385 case B_CMAP8: acc_mask = 0x7f; depth = 8; break; 386 case B_RGB15: acc_mask = 0x3f; depth = 16; break; 387 case B_RGB16: acc_mask = 0x3f; depth = 16; break; 388 case B_RGB24: acc_mask = 0x7f; depth = 24; break; 389 default: 390 LOG(8,("INIT: unsupported colorspace: 0x%08x\n", target->space)); 391 return B_ERROR; 392 } 393 break; 394 */ default: 395 /* see G100 and up specs: 396 * these cards can do 2D as long as multiples of 32 are used. 397 * (Note: don't mix this up with adress linearisation!) */ 398 switch (target->space) 399 { 400 case B_CMAP8: depth = 8; break; 401 case B_RGB15: depth = 16; break; 402 case B_RGB16: depth = 16; break; 403 case B_RGB24: depth = 24; break; 404 default: 405 LOG(8,("INIT: unsupported colorspace: 0x%08x\n", target->space)); 406 return B_ERROR; 407 } 408 //assuming accpitch = 32 for now.. 409 acc_mask = 0x1f; 410 break; 411 } 412 413 /* determine pixel multiple based on CRTC memory pitch constraints. 414 * (Note: Don't mix this up with CRTC timing contraints! Those are 415 * multiples of 8 for horizontal, 1 for vertical timing.) 416 * 417 * CRTC pitch constraints are the same for all Neomagic cards */ 418 switch (target->space) 419 { 420 case B_CMAP8: crtc_mask = 0x07; break; 421 case B_RGB15: crtc_mask = 0x03; break; 422 case B_RGB16: crtc_mask = 0x03; break; 423 case B_RGB24: crtc_mask = 0x07; break; 424 default: 425 LOG(8,("INIT: unsupported colorspace: 0x%08x\n", target->space)); 426 return B_ERROR; 427 } 428 429 /* check if we can setup this mode with acceleration: 430 * Max sizes need to adhere to both the acceleration engine _and_ the CRTC constraints! */ 431 *acc_mode = true; 432 /* check virtual_width */ 433 switch (si->ps.card_type) 434 { 435 case G100: 436 /* acc constraint: */ 437 if (target->virtual_width > 2048) *acc_mode = false; 438 break; 439 default: 440 /* G200-G550 */ 441 /* acc constraint: */ 442 if (target->virtual_width > 4096) *acc_mode = false; 443 /* for 32bit mode a lower CRTC1 restriction applies! */ 444 // if ((target->space == B_RGB32_LITTLE) && (target->virtual_width > (4092 & ~acc_mask))) 445 // *acc_mode = false; 446 break; 447 } 448 /* virtual_height */ 449 if (target->virtual_height > 2048) *acc_mode = false; 450 451 //fixme: (temp) 452 *acc_mode = false; 453 454 /* now check virtual_size based on CRTC constraints, 455 * making sure virtual_width stays within the 'mask' constraint: which is only 456 * nessesary because of an extra constraint in MIL1/2 cards that exists here. */ 457 458 //fixme: checkout cardspecs here!! 459 460 { 461 /* virtual_width */ 462 //fixme for CRTC2 (identical on all G400+ cards): 463 //16bit mode: max. virtual_width == 16352 (no extra mask needed); 464 //32bit mode: max. virtual_width == 8176 (no extra mask needed); 465 //other colordepths are unsupported on CRTC2. 466 switch(target->space) 467 { 468 case B_CMAP8: 469 if (target->virtual_width > (16368 & ~crtc_mask)) 470 target->virtual_width = (16368 & ~crtc_mask); 471 break; 472 case B_RGB15_LITTLE: 473 case B_RGB16_LITTLE: 474 if (target->virtual_width > (8184 & ~crtc_mask)) 475 target->virtual_width = (8184 & ~crtc_mask); 476 break; 477 case B_RGB24_LITTLE: 478 if (target->virtual_width > (5456 & ~crtc_mask)) 479 target->virtual_width = (5456 & ~crtc_mask); 480 break; 481 } 482 483 /* virtual_height: The only constraint here is the cards memory size which is 484 * checked later on in ProposeMode: virtual_height is adjusted then if needed. 485 * 'Limiting here' to the variable size that's at least available (uint16). */ 486 if (target->virtual_height > 65535) target->virtual_height = 65535; 487 } 488 489 /* OK, now we know that virtual_width is valid, and it's needing no slopspace if 490 * it was confined above, so we can finally calculate safely if we need slopspace 491 * for this mode... */ 492 if (*acc_mode) 493 video_pitch = ((target->virtual_width + acc_mask) & ~acc_mask); 494 else 495 video_pitch = ((target->virtual_width + crtc_mask) & ~crtc_mask); 496 497 LOG(2,("INIT: memory pitch will be set to %d pixels for colorspace 0x%08x\n", 498 video_pitch, target->space)); 499 if (target->virtual_width != video_pitch) 500 LOG(2,("INIT: effective mode slopspace is %d pixels\n", 501 (video_pitch - target->virtual_width))); 502 503 /* now calculate bytes_per_row for this mode */ 504 *bytes_per_row = video_pitch * (depth >> 3); 505 506 return B_OK; 507 } 508