1 /* CTRC functionality */ 2 /* Author: 3 Rudolf Cornelissen 11/2002-6/2009 4 */ 5 6 #define MODULE_BIT 0x00040000 7 8 #include "nv_std.h" 9 10 /* 11 Enable/Disable interrupts. Just a wrapper around the 12 ioctl() to the kernel driver. 13 */ 14 status_t nv_crtc_interrupt_enable(bool flag) 15 { 16 status_t result = B_OK; 17 nv_set_vblank_int svi; 18 19 if (si->ps.int_assigned) 20 { 21 /* set the magic number so the driver knows we're for real */ 22 svi.magic = NV_PRIVATE_DATA_MAGIC; 23 svi.crtc = 0; 24 svi.do_it = flag; 25 /* contact driver and get a pointer to the registers and shared data */ 26 result = ioctl(fd, NV_RUN_INTERRUPTS, &svi, sizeof(svi)); 27 } 28 29 return result; 30 } 31 32 /* doing general fail-safe default setup here */ 33 //fixme: this is a _very_ basic setup, and it's preliminary... 34 status_t nv_crtc_update_fifo() 35 { 36 uint8 bytes_per_pixel = 1; 37 uint32 drain; 38 39 /* we are only using this on >>coldstarted<< cards which really need this */ 40 //fixme: re-enable or remove after general user confirmation of behaviour... 41 if (/*(si->settings.usebios) ||*/ (si->ps.card_type != NV05M64)) return B_OK; 42 43 /* enable access to primary head */ 44 set_crtc_owner(0); 45 46 /* set CRTC FIFO low watermark according to memory drain */ 47 switch(si->dm.space) 48 { 49 case B_CMAP8: 50 bytes_per_pixel = 1; 51 break; 52 case B_RGB15_LITTLE: 53 case B_RGB16_LITTLE: 54 bytes_per_pixel = 2; 55 break; 56 case B_RGB24_LITTLE: 57 bytes_per_pixel = 3; 58 break; 59 case B_RGB32_LITTLE: 60 bytes_per_pixel = 4; 61 break; 62 } 63 /* fixme: 64 * - I should probably include the refreshrate as well; 65 * - and the memory clocking speed, core clocking speed, RAM buswidth.. */ 66 drain = si->dm.timing.h_display * si->dm.timing.v_display * bytes_per_pixel; 67 68 /* Doesn't work for other than 32bit space (yet?) */ 69 if (si->dm.space != B_RGB32_LITTLE) 70 { 71 /* BIOS defaults */ 72 CRTCW(FIFO, 0x03); 73 CRTCW(FIFO_LWM, 0x20); 74 LOG(4,("CRTC: FIFO low-watermark set to $20, burst size 256 (BIOS defaults)\n")); 75 return B_OK; 76 } 77 78 if (drain > (((uint32)1280) * 1024 * 4)) 79 { 80 /* set CRTC FIFO burst size for 'smaller' bursts */ 81 CRTCW(FIFO, 0x01); 82 /* Instruct CRTC to fetch new data 'earlier' */ 83 CRTCW(FIFO_LWM, 0x40); 84 LOG(4,("CRTC: FIFO low-watermark set to $40, burst size 64\n")); 85 } 86 else 87 { 88 if (drain > (((uint32)1024) * 768 * 4)) 89 { 90 /* BIOS default */ 91 CRTCW(FIFO, 0x02); 92 /* Instruct CRTC to fetch new data 'earlier' */ 93 CRTCW(FIFO_LWM, 0x40); 94 LOG(4,("CRTC: FIFO low-watermark set to $40, burst size 128\n")); 95 } 96 else 97 { 98 /* BIOS defaults */ 99 CRTCW(FIFO, 0x03); 100 CRTCW(FIFO_LWM, 0x20); 101 LOG(4,("CRTC: FIFO low-watermark set to $20, burst size 256 (BIOS defaults)\n")); 102 } 103 } 104 105 return B_OK; 106 } 107 108 /* Adjust passed parameters to a valid mode line */ 109 status_t nv_crtc_validate_timing( 110 uint16 *hd_e,uint16 *hs_s,uint16 *hs_e,uint16 *ht, 111 uint16 *vd_e,uint16 *vs_s,uint16 *vs_e,uint16 *vt 112 ) 113 { 114 /* horizontal */ 115 /* make all parameters multiples of 8 */ 116 *hd_e &= 0xfff8; 117 *hs_s &= 0xfff8; 118 *hs_e &= 0xfff8; 119 *ht &= 0xfff8; 120 121 /* confine to required number of bits, taking logic into account */ 122 if (*hd_e > ((0x01ff - 2) << 3)) *hd_e = ((0x01ff - 2) << 3); 123 if (*hs_s > ((0x01ff - 1) << 3)) *hs_s = ((0x01ff - 1) << 3); 124 if (*hs_e > ( 0x01ff << 3)) *hs_e = ( 0x01ff << 3); 125 if (*ht > ((0x01ff + 5) << 3)) *ht = ((0x01ff + 5) << 3); 126 127 /* NOTE: keep horizontal timing at multiples of 8! */ 128 /* confine to a reasonable width */ 129 if (*hd_e < 640) *hd_e = 640; 130 if (si->ps.card_type > NV04) 131 { 132 if (*hd_e > 2048) *hd_e = 2048; 133 } 134 else 135 { 136 if (*hd_e > 1920) *hd_e = 1920; 137 } 138 139 /* if hor. total does not leave room for a sensible sync pulse, increase it! */ 140 if (*ht < (*hd_e + 80)) *ht = (*hd_e + 80); 141 142 /* if hor. total does not adhere to max. blanking pulse width, decrease it! */ 143 if (*ht > (*hd_e + 0x3f8)) *ht = (*hd_e + 0x3f8); 144 145 /* make sure sync pulse is not during display */ 146 if (*hs_e > (*ht - 8)) *hs_e = (*ht - 8); 147 if (*hs_s < (*hd_e + 8)) *hs_s = (*hd_e + 8); 148 149 /* correct sync pulse if it is too long: 150 * there are only 5 bits available to save this in the card registers! */ 151 if (*hs_e > (*hs_s + 0xf8)) *hs_e = (*hs_s + 0xf8); 152 153 /*vertical*/ 154 /* confine to required number of bits, taking logic into account */ 155 //fixme if needed: on GeForce cards there are 12 instead of 11 bits... 156 if (*vd_e > (0x7ff - 2)) *vd_e = (0x7ff - 2); 157 if (*vs_s > (0x7ff - 1)) *vs_s = (0x7ff - 1); 158 if (*vs_e > 0x7ff ) *vs_e = 0x7ff ; 159 if (*vt > (0x7ff + 2)) *vt = (0x7ff + 2); 160 161 /* confine to a reasonable height */ 162 if (*vd_e < 480) *vd_e = 480; 163 if (si->ps.card_type > NV04) 164 { 165 if (*vd_e > 1536) *vd_e = 1536; 166 } 167 else 168 { 169 if (*vd_e > 1440) *vd_e = 1440; 170 } 171 172 /*if vertical total does not leave room for a sync pulse, increase it!*/ 173 if (*vt < (*vd_e + 3)) *vt = (*vd_e + 3); 174 175 /* if vert. total does not adhere to max. blanking pulse width, decrease it! */ 176 if (*vt > (*vd_e + 0xff)) *vt = (*vd_e + 0xff); 177 178 /* make sure sync pulse is not during display */ 179 if (*vs_e > (*vt - 1)) *vs_e = (*vt - 1); 180 if (*vs_s < (*vd_e + 1)) *vs_s = (*vd_e + 1); 181 182 /* correct sync pulse if it is too long: 183 * there are only 4 bits available to save this in the card registers! */ 184 if (*vs_e > (*vs_s + 0x0f)) *vs_e = (*vs_s + 0x0f); 185 186 return B_OK; 187 } 188 189 /*set a mode line - inputs are in pixels*/ 190 status_t nv_crtc_set_timing(display_mode target) 191 { 192 uint8 temp; 193 194 uint32 htotal; /*total horizontal total VCLKs*/ 195 uint32 hdisp_e; /*end of horizontal display (begins at 0)*/ 196 uint32 hsync_s; /*begin of horizontal sync pulse*/ 197 uint32 hsync_e; /*end of horizontal sync pulse*/ 198 uint32 hblnk_s; /*begin horizontal blanking*/ 199 uint32 hblnk_e; /*end horizontal blanking*/ 200 201 uint32 vtotal; /*total vertical total scanlines*/ 202 uint32 vdisp_e; /*end of vertical display*/ 203 uint32 vsync_s; /*begin of vertical sync pulse*/ 204 uint32 vsync_e; /*end of vertical sync pulse*/ 205 uint32 vblnk_s; /*begin vertical blanking*/ 206 uint32 vblnk_e; /*end vertical blanking*/ 207 208 uint32 linecomp; /*split screen and vdisp_e interrupt*/ 209 210 LOG(4,("CRTC: setting timing\n")); 211 212 /* setup tuned internal modeline for flatpanel if connected and active */ 213 /* notes: 214 * - the CRTC modeline must end earlier than the panel modeline to keep correct 215 * sync going; 216 * - if the CRTC modeline ends too soon, pixelnoise will occur in 8 (or so) pixel 217 * wide horizontal stripes. This can be observed earliest on fullscreen overlay, 218 * and if it gets worse, also normal desktop output will suffer. The stripes 219 * are mainly visible at the left of the screen, over the entire screen height. */ 220 if (si->ps.monitors & CRTC1_TMDS) 221 { 222 LOG(2,("CRTC: DFP active: tuning modeline\n")); 223 224 /* horizontal timing */ 225 target.timing.h_sync_start = 226 ((uint16)((si->ps.p1_timing.h_sync_start / ((float)si->ps.p1_timing.h_display)) * 227 target.timing.h_display)) & 0xfff8; 228 229 target.timing.h_sync_end = 230 ((uint16)((si->ps.p1_timing.h_sync_end / ((float)si->ps.p1_timing.h_display)) * 231 target.timing.h_display)) & 0xfff8; 232 233 target.timing.h_total = 234 (((uint16)((si->ps.p1_timing.h_total / ((float)si->ps.p1_timing.h_display)) * 235 target.timing.h_display)) & 0xfff8) - 8; 236 237 /* in native mode the CRTC needs some extra time to keep synced correctly; 238 * OTOH the overlay unit distorts if we reserve too much time! */ 239 if (target.timing.h_display == si->ps.p1_timing.h_display) 240 { 241 /* NV11 timing has different constraints than later cards */ 242 if (si->ps.card_type == NV11) 243 target.timing.h_total -= 56; 244 else 245 /* confirmed NV34 with 1680x1050 panel */ 246 target.timing.h_total -= 32; 247 } 248 249 if (target.timing.h_sync_start == target.timing.h_display) 250 target.timing.h_sync_start += 8; 251 if (target.timing.h_sync_end == target.timing.h_total) 252 target.timing.h_sync_end -= 8; 253 254 /* vertical timing */ 255 target.timing.v_sync_start = 256 ((uint16)((si->ps.p1_timing.v_sync_start / ((float)si->ps.p1_timing.v_display)) * 257 target.timing.v_display)); 258 259 target.timing.v_sync_end = 260 ((uint16)((si->ps.p1_timing.v_sync_end / ((float)si->ps.p1_timing.v_display)) * 261 target.timing.v_display)); 262 263 target.timing.v_total = 264 ((uint16)((si->ps.p1_timing.v_total / ((float)si->ps.p1_timing.v_display)) * 265 target.timing.v_display)) - 1; 266 267 if (target.timing.v_sync_start == target.timing.v_display) 268 target.timing.v_sync_start += 1; 269 if (target.timing.v_sync_end == target.timing.v_total) 270 target.timing.v_sync_end -= 1; 271 272 /* disable GPU scaling testmode so automatic scaling will be done */ 273 DACW(FP_DEBUG1, 0); 274 } 275 276 /* Modify parameters as required by standard VGA */ 277 htotal = ((target.timing.h_total >> 3) - 5); 278 hdisp_e = ((target.timing.h_display >> 3) - 1); 279 hblnk_s = hdisp_e; 280 hblnk_e = (htotal + 4); 281 hsync_s = (target.timing.h_sync_start >> 3); 282 hsync_e = (target.timing.h_sync_end >> 3); 283 284 vtotal = target.timing.v_total - 2; 285 vdisp_e = target.timing.v_display - 1; 286 vblnk_s = vdisp_e; 287 vblnk_e = (vtotal + 1); 288 vsync_s = target.timing.v_sync_start; 289 vsync_e = target.timing.v_sync_end; 290 291 /* prevent memory adress counter from being reset (linecomp may not occur) */ 292 linecomp = target.timing.v_display; 293 294 /* enable access to primary head */ 295 set_crtc_owner(0); 296 297 /* Note for laptop and DVI flatpanels: 298 * CRTC timing has a seperate set of registers from flatpanel timing. 299 * The flatpanel timing registers have scaling registers that are used to match 300 * these two modelines. */ 301 { 302 LOG(4,("CRTC: Setting full timing...\n")); 303 304 /* log the mode that will be set */ 305 LOG(2,("CRTC:\n\tHTOT:%x\n\tHDISPEND:%x\n\tHBLNKS:%x\n\tHBLNKE:%x\n\tHSYNCS:%x\n\tHSYNCE:%x\n\t",htotal,hdisp_e,hblnk_s,hblnk_e,hsync_s,hsync_e)); 306 LOG(2,("VTOT:%x\n\tVDISPEND:%x\n\tVBLNKS:%x\n\tVBLNKE:%x\n\tVSYNCS:%x\n\tVSYNCE:%x\n",vtotal,vdisp_e,vblnk_s,vblnk_e,vsync_s,vsync_e)); 307 308 /* actually program the card! */ 309 /* unlock CRTC registers at index 0-7 */ 310 CRTCW(VSYNCE, (CRTCR(VSYNCE) & 0x7f)); 311 /* horizontal standard VGA regs */ 312 CRTCW(HTOTAL, (htotal & 0xff)); 313 CRTCW(HDISPE, (hdisp_e & 0xff)); 314 CRTCW(HBLANKS, (hblnk_s & 0xff)); 315 /* also unlock vertical retrace registers in advance */ 316 CRTCW(HBLANKE, ((hblnk_e & 0x1f) | 0x80)); 317 CRTCW(HSYNCS, (hsync_s & 0xff)); 318 CRTCW(HSYNCE, ((hsync_e & 0x1f) | ((hblnk_e & 0x20) << 2))); 319 320 /* vertical standard VGA regs */ 321 CRTCW(VTOTAL, (vtotal & 0xff)); 322 CRTCW(OVERFLOW, 323 ( 324 ((vtotal & 0x100) >> (8 - 0)) | ((vtotal & 0x200) >> (9 - 5)) | 325 ((vdisp_e & 0x100) >> (8 - 1)) | ((vdisp_e & 0x200) >> (9 - 6)) | 326 ((vsync_s & 0x100) >> (8 - 2)) | ((vsync_s & 0x200) >> (9 - 7)) | 327 ((vblnk_s & 0x100) >> (8 - 3)) | ((linecomp & 0x100) >> (8 - 4)) 328 )); 329 CRTCW(PRROWSCN, 0x00); /* not used */ 330 CRTCW(MAXSCLIN, (((vblnk_s & 0x200) >> (9 - 5)) | ((linecomp & 0x200) >> (9 - 6)))); 331 CRTCW(VSYNCS, (vsync_s & 0xff)); 332 CRTCW(VSYNCE, ((CRTCR(VSYNCE) & 0xf0) | (vsync_e & 0x0f))); 333 CRTCW(VDISPE, (vdisp_e & 0xff)); 334 CRTCW(VBLANKS, (vblnk_s & 0xff)); 335 CRTCW(VBLANKE, (vblnk_e & 0xff)); 336 CRTCW(LINECOMP, (linecomp & 0xff)); 337 338 /* horizontal extended regs */ 339 //fixme: we reset bit4. is this correct?? 340 CRTCW(HEB, (CRTCR(HEB) & 0xe0) | 341 ( 342 ((htotal & 0x100) >> (8 - 0)) | 343 ((hdisp_e & 0x100) >> (8 - 1)) | 344 ((hblnk_s & 0x100) >> (8 - 2)) | 345 ((hsync_s & 0x100) >> (8 - 3)) 346 )); 347 348 /* (mostly) vertical extended regs */ 349 CRTCW(LSR, 350 ( 351 ((vtotal & 0x400) >> (10 - 0)) | 352 ((vdisp_e & 0x400) >> (10 - 1)) | 353 ((vsync_s & 0x400) >> (10 - 2)) | 354 ((vblnk_s & 0x400) >> (10 - 3)) | 355 ((hblnk_e & 0x040) >> (6 - 4)) 356 //fixme: we still miss one linecomp bit!?! is this it?? 357 //| ((linecomp & 0x400) >> 3) 358 )); 359 360 /* more vertical extended regs (on GeForce cards only) */ 361 if (si->ps.card_arch >= NV10A) 362 { 363 CRTCW(EXTRA, 364 ( 365 ((vtotal & 0x800) >> (11 - 0)) | 366 ((vdisp_e & 0x800) >> (11 - 2)) | 367 ((vsync_s & 0x800) >> (11 - 4)) | 368 ((vblnk_s & 0x800) >> (11 - 6)) 369 //fixme: do we miss another linecomp bit!?! 370 )); 371 } 372 373 /* setup 'large screen' mode */ 374 if (target.timing.h_display >= 1280) 375 CRTCW(REPAINT1, (CRTCR(REPAINT1) & 0xfb)); 376 else 377 CRTCW(REPAINT1, (CRTCR(REPAINT1) | 0x04)); 378 379 /* setup HSYNC & VSYNC polarity */ 380 LOG(2,("CRTC: sync polarity: ")); 381 temp = NV_REG8(NV8_MISCR); 382 if (target.timing.flags & B_POSITIVE_HSYNC) 383 { 384 LOG(2,("H:pos ")); 385 temp &= ~0x40; 386 } 387 else 388 { 389 LOG(2,("H:neg ")); 390 temp |= 0x40; 391 } 392 if (target.timing.flags & B_POSITIVE_VSYNC) 393 { 394 LOG(2,("V:pos ")); 395 temp &= ~0x80; 396 } 397 else 398 { 399 LOG(2,("V:neg ")); 400 temp |= 0x80; 401 } 402 NV_REG8(NV8_MISCW) = temp; 403 404 LOG(2,(", MISC reg readback: $%02x\n", NV_REG8(NV8_MISCR))); 405 } 406 407 /* always disable interlaced operation */ 408 /* (interlace is supported on upto and including NV10, NV15, and NV30 and up) */ 409 CRTCW(INTERLACE, 0xff); 410 411 /* disable CRTC slaved mode unless a panel is in use */ 412 // fixme: this kills TVout when it was in use... 413 if (!(si->ps.monitors & CRTC1_TMDS)) CRTCW(PIXEL, (CRTCR(PIXEL) & 0x7f)); 414 415 /* setup flatpanel if connected and active */ 416 if (si->ps.monitors & CRTC1_TMDS) 417 { 418 uint32 iscale_x, iscale_y; 419 420 /* calculate inverse scaling factors used by hardware in 20.12 format */ 421 iscale_x = (((1 << 12) * target.timing.h_display) / si->ps.p1_timing.h_display); 422 iscale_y = (((1 << 12) * target.timing.v_display) / si->ps.p1_timing.v_display); 423 424 /* unblock flatpanel timing programming (or something like that..) */ 425 CRTCW(FP_HTIMING, 0); 426 CRTCW(FP_VTIMING, 0); 427 LOG(2,("CRTC: FP_HTIMING reg readback: $%02x\n", CRTCR(FP_HTIMING))); 428 LOG(2,("CRTC: FP_VTIMING reg readback: $%02x\n", CRTCR(FP_VTIMING))); 429 430 /* enable full width visibility on flatpanel */ 431 DACW(FP_HVALID_S, 0); 432 DACW(FP_HVALID_E, (si->ps.p1_timing.h_display - 1)); 433 /* enable full height visibility on flatpanel */ 434 DACW(FP_VVALID_S, 0); 435 DACW(FP_VVALID_E, (si->ps.p1_timing.v_display - 1)); 436 437 /* nVidia cards support upscaling except on ??? */ 438 /* NV11 cards can upscale after all! */ 439 if (0)//si->ps.card_type == NV11) 440 { 441 /* disable last fetched line limiting */ 442 DACW(FP_DEBUG2, 0x00000000); 443 /* inform panel to scale if needed */ 444 if ((iscale_x != (1 << 12)) || (iscale_y != (1 << 12))) 445 { 446 LOG(2,("CRTC: DFP needs to do scaling\n")); 447 DACW(FP_TG_CTRL, (DACR(FP_TG_CTRL) | 0x00000100)); 448 } 449 else 450 { 451 LOG(2,("CRTC: no scaling for DFP needed\n")); 452 DACW(FP_TG_CTRL, (DACR(FP_TG_CTRL) & 0xfffffeff)); 453 } 454 } 455 else 456 { 457 float dm_aspect; 458 459 LOG(2,("CRTC: GPU scales for DFP if needed\n")); 460 461 /* calculate display mode aspect */ 462 dm_aspect = (target.timing.h_display / ((float)target.timing.v_display)); 463 464 /* limit last fetched line if vertical scaling is done */ 465 if (iscale_y != (1 << 12)) 466 DACW(FP_DEBUG2, ((1 << 28) | ((target.timing.v_display - 1) << 16))); 467 else 468 DACW(FP_DEBUG2, 0x00000000); 469 470 /* inform panel not to scale */ 471 DACW(FP_TG_CTRL, (DACR(FP_TG_CTRL) & 0xfffffeff)); 472 473 /* GPU scaling is automatically setup by hardware, so only modify this 474 * scalingfactor for non 4:3 (1.33) aspect panels; 475 * let's consider 1280x1024 1:33 aspect (it's 1.25 aspect actually!) */ 476 477 /* correct for widescreen panels relative to mode... 478 * (so if panel is more widescreen than mode being set) */ 479 /* BTW: known widescreen panels: 480 * 1280 x 800 (1.60), 481 * 1440 x 900 (1.60), 482 * 1680 x 1050 (1.60), 483 * 1920 x 1200 (1.60). */ 484 /* known 4:3 aspect non-standard resolution panels: 485 * 1400 x 1050 (1.33). */ 486 /* NOTE: 487 * allow 0.10 difference so 1280x1024 panels will be used fullscreen! */ 488 if ((iscale_x != (1 << 12)) && (si->ps.crtc1_screen.aspect > (dm_aspect + 0.10))) 489 { 490 uint16 diff; 491 492 LOG(2,("CRTC: (relative) widescreen panel: tuning horizontal scaling\n")); 493 494 /* X-scaling should be the same as Y-scaling */ 495 iscale_x = iscale_y; 496 /* enable testmode (b12) and program modified X-scaling factor */ 497 DACW(FP_DEBUG1, (((iscale_x >> 1) & 0x00000fff) | (1 << 12))); 498 /* center/cut-off left and right side of screen */ 499 diff = ((si->ps.p1_timing.h_display - 500 ((target.timing.h_display * (1 << 12)) / iscale_x)) 501 / 2); 502 DACW(FP_HVALID_S, diff); 503 DACW(FP_HVALID_E, ((si->ps.p1_timing.h_display - diff) - 1)); 504 } 505 /* correct for portrait panels... */ 506 /* NOTE: 507 * allow 0.10 difference so 1280x1024 panels will be used fullscreen! */ 508 if ((iscale_y != (1 << 12)) && (si->ps.crtc1_screen.aspect < (dm_aspect - 0.10))) 509 { 510 LOG(2,("CRTC: (relative) portrait panel: should tune vertical scaling\n")); 511 /* fixme: implement if this kind of portrait panels exist on nVidia... */ 512 } 513 } 514 515 /* do some logging.. */ 516 LOG(2,("CRTC: FP_HVALID_S reg readback: $%08x\n", DACR(FP_HVALID_S))); 517 LOG(2,("CRTC: FP_HVALID_E reg readback: $%08x\n", DACR(FP_HVALID_E))); 518 LOG(2,("CRTC: FP_VVALID_S reg readback: $%08x\n", DACR(FP_VVALID_S))); 519 LOG(2,("CRTC: FP_VVALID_E reg readback: $%08x\n", DACR(FP_VVALID_E))); 520 LOG(2,("CRTC: FP_DEBUG0 reg readback: $%08x\n", DACR(FP_DEBUG0))); 521 LOG(2,("CRTC: FP_DEBUG1 reg readback: $%08x\n", DACR(FP_DEBUG1))); 522 LOG(2,("CRTC: FP_DEBUG2 reg readback: $%08x\n", DACR(FP_DEBUG2))); 523 LOG(2,("CRTC: FP_DEBUG3 reg readback: $%08x\n", DACR(FP_DEBUG3))); 524 LOG(2,("CRTC: FP_TG_CTRL reg readback: $%08x\n", DACR(FP_TG_CTRL))); 525 } 526 527 return B_OK; 528 } 529 530 status_t nv_crtc_depth(int mode) 531 { 532 uint8 viddelay = 0; 533 uint32 genctrl = 0; 534 535 /* set VCLK scaling */ 536 switch(mode) 537 { 538 case BPP8: 539 viddelay = 0x01; 540 /* genctrl b4 & b5 reset: 'direct mode' */ 541 genctrl = 0x00101100; 542 break; 543 case BPP15: 544 viddelay = 0x02; 545 /* genctrl b4 & b5 set: 'indirect mode' (via colorpalette) */ 546 genctrl = 0x00100130; 547 break; 548 case BPP16: 549 viddelay = 0x02; 550 /* genctrl b4 & b5 set: 'indirect mode' (via colorpalette) */ 551 genctrl = 0x00101130; 552 break; 553 case BPP24: 554 viddelay = 0x03; 555 /* genctrl b4 & b5 set: 'indirect mode' (via colorpalette) */ 556 genctrl = 0x00100130; 557 break; 558 case BPP32: 559 viddelay = 0x03; 560 /* genctrl b4 & b5 set: 'indirect mode' (via colorpalette) */ 561 genctrl = 0x00101130; 562 break; 563 } 564 /* enable access to primary head */ 565 set_crtc_owner(0); 566 567 CRTCW(PIXEL, ((CRTCR(PIXEL) & 0xfc) | viddelay)); 568 DACW(GENCTRL, genctrl); 569 570 return B_OK; 571 } 572 573 status_t nv_crtc_dpms(bool display, bool h, bool v, bool do_panel) 574 { 575 uint8 temp; 576 char msg[100]; 577 578 sprintf(msg, "CRTC: setting DPMS: "); 579 580 /* enable access to primary head */ 581 set_crtc_owner(0); 582 583 /* start synchronous reset: required before turning screen off! */ 584 SEQW(RESET, 0x01); 585 586 temp = SEQR(CLKMODE); 587 if (display) 588 { 589 /* turn screen on */ 590 SEQW(CLKMODE, (temp & ~0x20)); 591 592 /* end synchronous reset because display should be enabled */ 593 SEQW(RESET, 0x03); 594 595 if (do_panel && (si->ps.monitors & CRTC1_TMDS)) 596 { 597 if (!si->ps.laptop) 598 { 599 /* restore original panelsync and panel-enable */ 600 uint32 panelsync = 0x00000000; 601 if(si->ps.p1_timing.flags & B_POSITIVE_VSYNC) panelsync |= 0x00000001; 602 if(si->ps.p1_timing.flags & B_POSITIVE_HSYNC) panelsync |= 0x00000010; 603 /* display enable polarity (not an official flag) */ 604 if(si->ps.p1_timing.flags & B_BLANK_PEDESTAL) panelsync |= 0x10000000; 605 DACW(FP_TG_CTRL, ((DACR(FP_TG_CTRL) & 0xcfffffcc) | panelsync)); 606 607 //fixme?: looks like we don't need this after all: 608 /* powerup both LVDS (laptop panellink) and TMDS (DVI panellink) 609 * internal transmitters... */ 610 /* note: 611 * the powerbits in this register are hardwired to the DVI connectors, 612 * instead of to the DACs! (confirmed NV34) */ 613 //fixme... 614 //DACW(FP_DEBUG0, (DACR(FP_DEBUG0) & 0xcfffffff)); 615 /* ... and powerup external TMDS transmitter if it exists */ 616 /* (confirmed OK on NV28 and NV34) */ 617 //CRTCW(0x59, (CRTCR(0x59) | 0x01)); 618 619 sprintf(msg, "%s(panel-)", msg); 620 } 621 else 622 { 623 //fixme? linux only does this on dualhead cards... 624 //fixme: see if LVDS head can be determined with two panels there... 625 if (!(si->ps.monitors & CRTC2_TMDS) && (si->ps.card_type != NV11)) 626 { 627 /* b2 = 0 = enable laptop panel backlight */ 628 /* note: this seems to be a write-only register. */ 629 NV_REG32(NV32_LVDS_PWR) = 0x00000003; 630 631 sprintf(msg, "%s(panel-)", msg); 632 } 633 } 634 } 635 636 sprintf(msg, "%sdisplay on, ", msg); 637 } 638 else 639 { 640 /* turn screen off */ 641 SEQW(CLKMODE, (temp | 0x20)); 642 643 if (do_panel && (si->ps.monitors & CRTC1_TMDS)) 644 { 645 if (!si->ps.laptop) 646 { 647 /* shutoff panelsync and disable panel */ 648 DACW(FP_TG_CTRL, ((DACR(FP_TG_CTRL) & 0xcfffffcc) | 0x20000022)); 649 650 //fixme?: looks like we don't need this after all: 651 /* powerdown both LVDS (laptop panellink) and TMDS (DVI panellink) 652 * internal transmitters... */ 653 /* note: 654 * the powerbits in this register are hardwired to the DVI connectors, 655 * instead of to the DACs! (confirmed NV34) */ 656 //fixme... 657 //DACW(FP_DEBUG0, (DACR(FP_DEBUG0) | 0x30000000)); 658 /* ... and powerdown external TMDS transmitter if it exists */ 659 /* (confirmed OK on NV28 and NV34) */ 660 //CRTCW(0x59, (CRTCR(0x59) & 0xfe)); 661 662 sprintf(msg, "%s(panel-)", msg); 663 } 664 else 665 { 666 //fixme? linux only does this on dualhead cards... 667 //fixme: see if LVDS head can be determined with two panels there... 668 if (!(si->ps.monitors & CRTC2_TMDS) && (si->ps.card_type != NV11)) 669 { 670 /* b2 = 1 = disable laptop panel backlight */ 671 /* note: this seems to be a write-only register. */ 672 NV_REG32(NV32_LVDS_PWR) = 0x00000007; 673 674 sprintf(msg, "%s(panel-)", msg); 675 } 676 } 677 } 678 679 sprintf(msg, "%sdisplay off, ", msg); 680 } 681 682 if (h) 683 { 684 CRTCW(REPAINT1, (CRTCR(REPAINT1) & 0x7f)); 685 sprintf(msg, "%shsync enabled, ", msg); 686 } 687 else 688 { 689 CRTCW(REPAINT1, (CRTCR(REPAINT1) | 0x80)); 690 sprintf(msg, "%shsync disabled, ", msg); 691 } 692 if (v) 693 { 694 CRTCW(REPAINT1, (CRTCR(REPAINT1) & 0xbf)); 695 sprintf(msg, "%svsync enabled\n", msg); 696 } 697 else 698 { 699 CRTCW(REPAINT1, (CRTCR(REPAINT1) | 0x40)); 700 sprintf(msg, "%svsync disabled\n", msg); 701 } 702 703 LOG(4, (msg)); 704 705 return B_OK; 706 } 707 708 status_t nv_crtc_set_display_pitch() 709 { 710 uint32 offset; 711 712 LOG(4,("CRTC: setting card pitch (offset between lines)\n")); 713 714 /* figure out offset value hardware needs */ 715 offset = si->fbc.bytes_per_row / 8; 716 717 LOG(2,("CRTC: offset register set to: $%04x\n", offset)); 718 719 /* enable access to primary head */ 720 set_crtc_owner(0); 721 722 /* program the card */ 723 CRTCW(PITCHL, (offset & 0x00ff)); 724 CRTCW(REPAINT0, ((CRTCR(REPAINT0) & 0x1f) | ((offset & 0x0700) >> 3))); 725 726 return B_OK; 727 } 728 729 status_t nv_crtc_set_display_start(uint32 startadd,uint8 bpp) 730 { 731 uint8 temp; 732 uint32 timeout = 0; 733 734 LOG(4,("CRTC: setting card RAM to be displayed bpp %d\n", bpp)); 735 736 LOG(2,("CRTC: startadd: $%08x\n", startadd)); 737 LOG(2,("CRTC: frameRAM: $%08x\n", si->framebuffer)); 738 LOG(2,("CRTC: framebuffer: $%08x\n", si->fbc.frame_buffer)); 739 740 /* we might have no retraces during setmode! */ 741 /* wait 25mS max. for retrace to occur (refresh > 40Hz) */ 742 while (((NV_REG32(NV32_RASTER) & 0x000007ff) < si->dm.timing.v_display) && 743 (timeout < (25000/10))) 744 { 745 /* don't snooze much longer or retrace might get missed! */ 746 snooze(10); 747 timeout++; 748 } 749 750 /* enable access to primary head */ 751 set_crtc_owner(0); 752 753 if (si->ps.card_arch == NV04A) 754 { 755 /* upto 32Mb RAM adressing: must be used this way on pre-NV10! */ 756 757 /* set standard registers */ 758 /* (NVidia: startadress in 32bit words (b2 - b17) */ 759 CRTCW(FBSTADDL, ((startadd & 0x000003fc) >> 2)); 760 CRTCW(FBSTADDH, ((startadd & 0x0003fc00) >> 10)); 761 762 /* set extended registers */ 763 /* NV4 extended bits: (b18-22) */ 764 temp = (CRTCR(REPAINT0) & 0xe0); 765 CRTCW(REPAINT0, (temp | ((startadd & 0x007c0000) >> 18))); 766 /* NV4 extended bits: (b23-24) */ 767 temp = (CRTCR(HEB) & 0x9f); 768 CRTCW(HEB, (temp | ((startadd & 0x01800000) >> 18))); 769 } 770 else 771 { 772 /* upto 4Gb RAM adressing: must be used on NV10 and later! */ 773 /* NOTE: 774 * While this register also exists on pre-NV10 cards, it will 775 * wrap-around at 16Mb boundaries!! */ 776 777 /* 30bit adress in 32bit words */ 778 NV_REG32(NV32_NV10FBSTADD32) = (startadd & 0xfffffffc); 779 } 780 781 /* set NV4/NV10 byte adress: (b0 - 1) */ 782 ATBW(HORPIXPAN, ((startadd & 0x00000003) << 1)); 783 784 return B_OK; 785 } 786 787 status_t nv_crtc_cursor_init() 788 { 789 int i; 790 vuint32 * fb; 791 /* cursor bitmap will be stored at the start of the framebuffer */ 792 const uint32 curadd = 0; 793 794 /* enable access to primary head */ 795 set_crtc_owner(0); 796 797 /* set cursor bitmap adress ... */ 798 if ((si->ps.card_arch == NV04A) || (si->ps.laptop)) 799 { 800 /* must be used this way on pre-NV10 and on all 'Go' cards! */ 801 802 /* cursorbitmap must start on 2Kbyte boundary: */ 803 /* set adress bit11-16, and set 'no doublescan' (registerbit 1 = 0) */ 804 CRTCW(CURCTL0, ((curadd & 0x0001f800) >> 9)); 805 /* set adress bit17-23, and set graphics mode cursor(?) (registerbit 7 = 1) */ 806 CRTCW(CURCTL1, (((curadd & 0x00fe0000) >> 17) | 0x80)); 807 /* set adress bit24-31 */ 808 CRTCW(CURCTL2, ((curadd & 0xff000000) >> 24)); 809 } 810 else 811 { 812 /* upto 4Gb RAM adressing: 813 * can be used on NV10 and later (except for 'Go' cards)! */ 814 /* NOTE: 815 * This register does not exist on pre-NV10 and 'Go' cards. */ 816 817 /* cursorbitmap must still start on 2Kbyte boundary: */ 818 NV_REG32(NV32_NV10CURADD32) = (curadd & 0xfffff800); 819 } 820 821 /* set cursor colour: not needed because of direct nature of cursor bitmap. */ 822 823 /*clear cursor*/ 824 fb = (vuint32 *) si->framebuffer + curadd; 825 for (i=0;i<(2048/4);i++) 826 { 827 fb[i]=0; 828 } 829 830 /* select 32x32 pixel, 16bit color cursorbitmap, no doublescan */ 831 NV_REG32(NV32_CURCONF) = 0x02000100; 832 833 /* activate hardware-sync between cursor updates and vertical retrace where 834 * available */ 835 if (si->ps.card_arch >= NV10A) 836 DACW(NV10_CURSYNC, (DACR(NV10_CURSYNC) | 0x02000000)); 837 838 /* activate hardware cursor */ 839 nv_crtc_cursor_show(); 840 841 return B_OK; 842 } 843 844 status_t nv_crtc_cursor_show() 845 { 846 LOG(4,("CRTC: enabling cursor\n")); 847 848 /* enable access to CRTC1 on dualhead cards */ 849 set_crtc_owner(0); 850 851 /* b0 = 1 enables cursor */ 852 CRTCW(CURCTL0, (CRTCR(CURCTL0) | 0x01)); 853 854 /* workaround for hardware bug confirmed existing on NV43: 855 * Cursor visibility is not updated without a position update if its hardware 856 * retrace sync is enabled. */ 857 if (si->ps.card_arch == NV40A) DACW(CURPOS, (DACR(CURPOS))); 858 859 return B_OK; 860 } 861 862 status_t nv_crtc_cursor_hide() 863 { 864 LOG(4,("CRTC: disabling cursor\n")); 865 866 /* enable access to primary head */ 867 set_crtc_owner(0); 868 869 /* b0 = 0 disables cursor */ 870 CRTCW(CURCTL0, (CRTCR(CURCTL0) & 0xfe)); 871 872 /* workaround for hardware bug confirmed existing on NV43: 873 * Cursor visibility is not updated without a position update if its hardware 874 * retrace sync is enabled. */ 875 if (si->ps.card_arch == NV40A) DACW(CURPOS, (DACR(CURPOS))); 876 877 return B_OK; 878 } 879 880 /*set up cursor shape*/ 881 status_t nv_crtc_cursor_define(uint8* andMask,uint8* xorMask) 882 { 883 int x, y; 884 uint8 b; 885 vuint16 *cursor; 886 uint16 pixel; 887 888 /* get a pointer to the cursor */ 889 cursor = (vuint16*) si->framebuffer; 890 891 /* draw the cursor */ 892 /* (Nvidia cards have a RGB15 direct color cursor bitmap, bit #16 is transparancy) */ 893 for (y = 0; y < 16; y++) 894 { 895 b = 0x80; 896 for (x = 0; x < 8; x++) 897 { 898 /* preset transparant */ 899 pixel = 0x0000; 900 /* set white if requested */ 901 if ((!(*andMask & b)) && (!(*xorMask & b))) pixel = 0xffff; 902 /* set black if requested */ 903 if ((!(*andMask & b)) && (*xorMask & b)) pixel = 0x8000; 904 /* set invert if requested */ 905 if ( (*andMask & b) && (*xorMask & b)) pixel = 0x7fff; 906 /* place the pixel in the bitmap */ 907 cursor[x + (y * 32)] = pixel; 908 b >>= 1; 909 } 910 xorMask++; 911 andMask++; 912 b = 0x80; 913 for (; x < 16; x++) 914 { 915 /* preset transparant */ 916 pixel = 0x0000; 917 /* set white if requested */ 918 if ((!(*andMask & b)) && (!(*xorMask & b))) pixel = 0xffff; 919 /* set black if requested */ 920 if ((!(*andMask & b)) && (*xorMask & b)) pixel = 0x8000; 921 /* set invert if requested */ 922 if ( (*andMask & b) && (*xorMask & b)) pixel = 0x7fff; 923 /* place the pixel in the bitmap */ 924 cursor[x + (y * 32)] = pixel; 925 b >>= 1; 926 } 927 xorMask++; 928 andMask++; 929 } 930 931 return B_OK; 932 } 933 934 /* position the cursor */ 935 status_t nv_crtc_cursor_position(uint16 x, uint16 y) 936 { 937 /* the cursor position is updated during retrace by card hardware except for 938 * pre-GeForce cards */ 939 if (si->ps.card_arch < NV10A) 940 { 941 uint16 yhigh; 942 uint32 timeout = 0; 943 944 /* make sure we are beyond the first line of the cursorbitmap being drawn during 945 * updating the position to prevent distortions: no double buffering feature */ 946 /* Note: 947 * we need to return as quick as possible or some apps will exhibit lagging.. */ 948 949 /* read the old cursor Y position */ 950 yhigh = ((DACR(CURPOS) & 0x0fff0000) >> 16); 951 /* make sure we will wait until we are below both the old and new Y position: 952 * visible cursorbitmap drawing needs to be done at least... */ 953 if (y > yhigh) yhigh = y; 954 955 if (yhigh < (si->dm.timing.v_display - 16)) 956 { 957 /* we have vertical lines below old and new cursorposition to spare. So we 958 * update the cursor postion 'mid-screen', but below that area. */ 959 /* wait 25mS max. (refresh > 40Hz) */ 960 while ((((uint16)(NV_REG32(NV32_RASTER) & 0x000007ff)) < (yhigh + 16)) && 961 (timeout < (25000/10))) 962 { 963 snooze(10); 964 timeout++; 965 } 966 } 967 else 968 { 969 timeout = 0; 970 /* no room to spare, just wait for retrace (is relatively slow) */ 971 /* wait 25mS max. (refresh > 40Hz) */ 972 while (((NV_REG32(NV32_RASTER) & 0x000007ff) < si->dm.timing.v_display) && 973 (timeout < (25000/10))) 974 { 975 /* don't snooze much longer or retrace might get missed! */ 976 snooze(10); 977 timeout++; 978 } 979 } 980 } 981 982 /* update cursorposition */ 983 DACW(CURPOS, ((x & 0x0fff) | ((y & 0x0fff) << 16))); 984 985 return B_OK; 986 } 987 988 status_t nv_crtc_stop_tvout(void) 989 { 990 uint16 cnt; 991 992 LOG(4,("CRTC: stopping TV output\n")); 993 994 /* enable access to primary head */ 995 set_crtc_owner(0); 996 997 /* just to be sure Vsync is _really_ enabled */ 998 CRTCW(REPAINT1, (CRTCR(REPAINT1) & 0xbf)); 999 1000 /* wait for one image to be generated to make sure VGA has kicked in and is 1001 * running OK before continuing... 1002 * (Kicking in will fail often if we do not wait here) */ 1003 /* Note: 1004 * The used CRTC's Vsync is required to be enabled here. The DPMS state 1005 * programming in the driver makes sure this is the case. 1006 * (except for driver startup: see nv_general.c.) */ 1007 1008 /* make sure we are 'in' active VGA picture: wait with timeout! */ 1009 cnt = 1; 1010 while ((NV_REG8(NV8_INSTAT1) & 0x08) && cnt) 1011 { 1012 snooze(1); 1013 cnt++; 1014 } 1015 /* wait for next vertical retrace start on VGA: wait with timeout! */ 1016 cnt = 1; 1017 while ((!(NV_REG8(NV8_INSTAT1) & 0x08)) && cnt) 1018 { 1019 snooze(1); 1020 cnt++; 1021 } 1022 /* now wait until we are 'in' active VGA picture again: wait with timeout! */ 1023 cnt = 1; 1024 while ((NV_REG8(NV8_INSTAT1) & 0x08) && cnt) 1025 { 1026 snooze(1); 1027 cnt++; 1028 } 1029 1030 /* set CRTC to master mode (b7 = 0) if it wasn't slaved for a panel before */ 1031 if (!(si->ps.slaved_tmds1)) CRTCW(PIXEL, (CRTCR(PIXEL) & 0x03)); 1032 1033 /* CAUTION: 1034 * On old cards, PLLSEL (and TV_SETUP?) cannot be read (sometimes?), but 1035 * write actions do succeed ... 1036 * This is confirmed for both ISA and PCI access, on NV04 and NV11. */ 1037 1038 /* setup TVencoder connection */ 1039 /* b1-0 = %00: encoder type is SLAVE; 1040 * b24 = 1: VIP datapos is b0-7 */ 1041 //fixme if needed: setup completely instead of relying on pre-init by BIOS.. 1042 //(it seems to work OK on NV04 and NV11 although read reg. doesn't seem to work) 1043 DACW(TV_SETUP, ((DACR(TV_SETUP) & ~0x00000003) | 0x01000000)); 1044 1045 /* tell GPU to use pixelclock from internal source instead of using TVencoder */ 1046 if (si->ps.secondary_head) 1047 DACW(PLLSEL, 0x30000f00); 1048 else 1049 DACW(PLLSEL, 0x10000700); 1050 1051 /* HTOTAL, VTOTAL and OVERFLOW return their default CRTC use, instead of 1052 * H, V-low and V-high 'shadow' counters(?)(b0, 4 and 6 = 0) (b7 use = unknown) */ 1053 CRTCW(TREG, 0x00); 1054 1055 /* select panel encoder, not TV encoder if needed (b0 = 1). 1056 * Note: 1057 * Both are devices (often) using the CRTC in slaved mode. */ 1058 if (si->ps.slaved_tmds1) CRTCW(LCD, (CRTCR(LCD) | 0x01)); 1059 1060 return B_OK; 1061 } 1062 1063 status_t nv_crtc_start_tvout(void) 1064 { 1065 LOG(4,("CRTC: starting TV output\n")); 1066 1067 if (si->ps.secondary_head) 1068 { 1069 /* switch TV encoder to CRTC1 */ 1070 NV_REG32(NV32_2FUNCSEL) &= ~0x00000100; 1071 NV_REG32(NV32_FUNCSEL) |= 0x00000100; 1072 } 1073 1074 /* enable access to primary head */ 1075 set_crtc_owner(0); 1076 1077 /* CAUTION: 1078 * On old cards, PLLSEL (and TV_SETUP?) cannot be read (sometimes?), but 1079 * write actions do succeed ... 1080 * This is confirmed for both ISA and PCI access, on NV04 and NV11. */ 1081 1082 /* setup TVencoder connection */ 1083 /* b1-0 = %01: encoder type is MASTER; 1084 * b24 = 1: VIP datapos is b0-7 */ 1085 //fixme if needed: setup completely instead of relying on pre-init by BIOS.. 1086 //(it seems to work OK on NV04 and NV11 although read reg. doesn't seem to work) 1087 DACW(TV_SETUP, ((DACR(TV_SETUP) & ~0x00000002) | 0x01000001)); 1088 1089 /* tell GPU to use pixelclock from TVencoder instead of using internal source */ 1090 /* (nessecary or display will 'shiver' on both TV and VGA.) */ 1091 if (si->ps.secondary_head) 1092 DACW(PLLSEL, 0x20030f00); 1093 else 1094 DACW(PLLSEL, 0x00030700); 1095 1096 /* Set overscan color to 'black' */ 1097 /* note: 1098 * Change this instruction for a visible overscan color if you're trying to 1099 * center the output on TV. Use it as a guide-'line' then ;-) */ 1100 ATBW(OSCANCOLOR, 0x00); 1101 1102 /* set CRTC to slaved mode (b7 = 1) and clear TVadjust (b3-5 = %000) */ 1103 CRTCW(PIXEL, ((CRTCR(PIXEL) & 0xc7) | 0x80)); 1104 /* select TV encoder, not panel encoder (b0 = 0). 1105 * Note: 1106 * Both are devices (often) using the CRTC in slaved mode. */ 1107 CRTCW(LCD, (CRTCR(LCD) & 0xfe)); 1108 1109 /* HTOTAL, VTOTAL and OVERFLOW return their default CRTC use, instead of 1110 * H, V-low and V-high 'shadow' counters(?)(b0, 4 and 6 = 0) (b7 use = unknown) */ 1111 CRTCW(TREG, 0x80); 1112 1113 return B_OK; 1114 } 1115