1 /* 2 Author: 3 Rudolf Cornelissen 4/2002-10/2005 4 */ 5 6 #define MODULE_BIT 0x00100000 7 8 #include "nv_std.h" 9 10 #define PRADR 0x88 11 #define SCADR 0x8a 12 #define WR 0x00 13 #define RD 0x01 14 15 enum 16 { // TVoutput mode to set 17 NOT_SUPPORTED = 0, 18 NTSC640_TST, 19 NTSC640, 20 NTSC800, 21 PAL800_TST, 22 PAL640, 23 PAL800, 24 NTSC720, 25 PAL720, 26 NTSC640_OS, 27 PAL800_OS 28 }; 29 30 /* Dirk Thierbach's Macro setup for registers 0xda-0xfe. 31 * (also see http://sourceforge.net/projects/nv-tv-out/) */ 32 static uint8 BtNtscMacro0 [] = { 33 0x0f,0xfc,0x20,0xd0,0x6f,0x0f,0x00,0x00,0x0c,0xf3,0x09, 34 0xbd,0x67,0xb5,0x90,0xb2,0x7d,0x00,0x00}; 35 static uint8 BtNtscMacro1 [] = { 36 0x0f,0xfc,0x20,0xd0,0x6f,0x0f,0x00,0x00,0x0c,0xf3,0x09, 37 0xbd,0x67,0xb5,0x90,0xb2,0x7d,0x63,0x00}; 38 static uint8 BtNtscMacro2 [] = { 39 0x0f,0xfc,0x20,0xd0,0x6f,0x0f,0x00,0x00,0x0c,0xf3,0x09, 40 0xbd,0x6c,0x31,0x92,0x32,0xdd,0xe3,0x00}; 41 static uint8 BtNtscMacro3 [] = { 42 0x0f,0xfc,0x20,0xd0,0x6f,0x0f,0x00,0x00,0x0c,0xf3,0x09, 43 0xbd,0x66,0xb5,0x90,0xb2,0x7d,0xe3,0x00}; 44 45 static uint8 BtPalMacro0 [] = { 46 0x05,0x57,0x20,0x40,0x6e,0x7e,0xf4,0x51,0x0f,0xf1,0x05, 47 0xd3,0x78,0xa2,0x25,0x54,0xa5,0x00,0x00}; 48 static uint8 BtPalMacro1 [] = { 49 0x05,0x57,0x20,0x40,0x6e,0x7e,0xf4,0x51,0x0f,0xf1,0x05, 50 0xd3,0x78,0xa2,0x25,0x54,0xa5,0x63,0x00}; 51 52 static uint8 BT_set_macro (int std, int mode) 53 { 54 uint8 stat; 55 uint8 buffer[21]; 56 57 LOG(4,("Brooktree: Setting Macro:\n")); 58 59 if ((std < 0) | (std > 1) | (mode < 0) | (mode > 3)) 60 { 61 LOG(4,("Brooktree: Non existing mode or standard selected, aborting.\n")); 62 return 0x80; 63 } 64 65 switch (std) 66 { 67 case 0: 68 /* NTSC */ 69 switch (mode) 70 { 71 case 0: 72 /* disabled */ 73 LOG(4,("Brooktree: NTSC, disabled\n")); 74 memcpy(&buffer[2], &BtNtscMacro0, 19); 75 break; 76 case 1: 77 /* enabled mode 1 */ 78 LOG(4,("Brooktree: NTSC, mode 1\n")); 79 memcpy(&buffer[2], &BtNtscMacro1, 19); 80 break; 81 case 2: 82 /* enabled mode 2 */ 83 LOG(4,("Brooktree: NTSC, mode 2\n")); 84 memcpy(&buffer[2], &BtNtscMacro2, 19); 85 break; 86 case 3: 87 /* enabled mode 3 */ 88 LOG(4,("Brooktree: NTSC, mode 3\n")); 89 memcpy(&buffer[2], &BtNtscMacro3, 19); 90 break; 91 } 92 break; 93 case 1: 94 /* PAL */ 95 switch (mode) 96 { 97 case 0: 98 /* disabled */ 99 LOG(4,("Brooktree: PAL, disabled\n")); 100 memcpy(&buffer[2], &BtPalMacro0, 19); 101 break; 102 case 1: 103 case 2: 104 case 3: 105 /* enabled */ 106 LOG(4,("Brooktree: PAL, enabled\n")); 107 memcpy(&buffer[2], &BtPalMacro1, 19); 108 break; 109 } 110 break; 111 } 112 113 buffer[0] = si->ps.tv_encoder.adress + WR; 114 /* select first register to write to */ 115 buffer[1] = 0xda; 116 117 /* reset status */ 118 i2c_flag_error (-1); 119 120 i2c_bstart(si->ps.tv_encoder.bus); 121 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 122 i2c_bstop(si->ps.tv_encoder.bus); 123 /* log on errors */ 124 stat = i2c_flag_error(0); 125 if (stat) 126 LOG(4,("Brooktree: I2C errors occurred while setting Macro\n")); 127 128 return stat; 129 }//end BT_set_macro. 130 131 /* 132 see if a (possible) BT/CX chip resides at the given adress. 133 Return zero if no errors occurred. 134 */ 135 static uint8 BT_check (uint8 bus, uint8 adress) 136 { 137 uint8 buffer[3]; 138 139 buffer[0] = adress + WR; 140 /* set ESTATUS at b'00'; and enable bt chip-outputs 141 * WARNING: 142 * If bit0 = 0 is issued below (EN_OUT = disabled), the BT will lock SDA 143 * after writing adress $A0 (setting EN_XCLK)!!! 144 * Until a reboot the corresponding I2C bus will be inacessable then!!! */ 145 buffer[1] = 0xc4; 146 /* fixme: if testimage 'was' active txbuffer[3] should become 0x05... 147 * (currently this cannot be detected in a 'foolproof' way so don't touch...) */ 148 /* (ESTATUS b'0x' means: RX ID and VERSION info later..) */ 149 buffer[2] = 0x01; 150 151 /* reset status */ 152 i2c_flag_error (-1); 153 154 /* do check */ 155 i2c_bstart(bus); 156 i2c_writebuffer(bus, buffer, sizeof(buffer)); 157 i2c_bstop(bus); 158 return i2c_flag_error(0); 159 } 160 161 /* identify chiptype */ 162 static uint8 BT_read_type (void) 163 { 164 uint8 id, type, stat; 165 uint8 buffer[3]; 166 167 /* Make sure a CX (Conexant) chip (if this turns out to be there) is set to 168 * BT-compatibility mode! (This command will do nothing on a BT chip...) */ 169 buffer[0] = si->ps.tv_encoder.adress + WR; 170 /* select CX reg. for BT-compatible readback, video still off */ 171 buffer[1] = 0x6c; 172 /* set it up */ 173 buffer[2] = 0x02; 174 175 /* reset status */ 176 i2c_flag_error (-1); 177 178 i2c_bstart(si->ps.tv_encoder.bus); 179 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 180 i2c_bstop(si->ps.tv_encoder.bus); 181 /* abort on errors */ 182 stat = i2c_flag_error(0); 183 if (stat) return stat; 184 185 /* Do actual readtype command */ 186 i2c_bstart(si->ps.tv_encoder.bus); 187 /* issue I2C read command */ 188 i2c_writebyte(si->ps.tv_encoder.bus, si->ps.tv_encoder.adress + RD); 189 /* receive 1 byte; 190 * ACK level to TX after last byte to RX should be 1 (= NACK) (see I2C spec). */ 191 /* note: 192 * While the BT's don't care, CX chips will block the SDA line if 193 * an ACK gets sent! */ 194 id = i2c_readbyte(si->ps.tv_encoder.bus, true); 195 i2c_bstop(si->ps.tv_encoder.bus); 196 /* abort on errors */ 197 stat = i2c_flag_error(0); 198 if (stat) return stat; 199 200 /* check type to be supported one */ 201 type = (id & 0xe0) >> 5; 202 if (type > 3) 203 { 204 LOG(4,("Brooktree: Found unsupported encoder type %d, aborting.\n", type)); 205 return 0x80; 206 } 207 208 /* inform driver about TV encoder found */ 209 si->ps.tvout = true; 210 si->ps.tv_encoder.type = BT868 + type; 211 si->ps.tv_encoder.version = id & 0x1f; 212 213 return stat; 214 } 215 216 bool BT_probe() 217 { 218 bool btfound = false; 219 220 LOG(4,("Brooktree: Checking I2C bus(ses) for first possible TV encoder...\n")); 221 if (si->ps.i2c_bus0) 222 { 223 /* try primary adress on bus 0 */ 224 if (!BT_check(0, PRADR)) 225 { 226 btfound = true; 227 si->ps.tv_encoder.adress = PRADR; 228 si->ps.tv_encoder.bus = 0; 229 } 230 else 231 { 232 /* try secondary adress on bus 0 */ 233 if (!BT_check(0, SCADR)) 234 { 235 btfound = true; 236 si->ps.tv_encoder.adress = SCADR; 237 si->ps.tv_encoder.bus = 0; 238 } 239 } 240 } 241 242 if (si->ps.i2c_bus1 && !btfound) 243 { 244 /* try primary adress on bus 1 */ 245 if (!BT_check(1, PRADR)) 246 { 247 btfound = true; 248 si->ps.tv_encoder.adress = PRADR; 249 si->ps.tv_encoder.bus = 1; 250 } 251 else 252 { 253 /* try secondary adress on bus 1 */ 254 if (!BT_check(1, SCADR)) 255 { 256 btfound = true; 257 si->ps.tv_encoder.adress = SCADR; 258 si->ps.tv_encoder.bus = 1; 259 } 260 } 261 } 262 263 /* identify exact TV encoder type */ 264 if (btfound) 265 { 266 /* if errors are found, retry */ 267 /* note: 268 * NACK: occurs on some ASUS V7700 GeForce cards! 269 * (apparantly the video-in chip or another chip resides at 'BT' adresses 270 * there..) */ 271 uint8 stat; 272 uint8 cnt = 0; 273 while ((stat = BT_read_type()) && (cnt < 3)) 274 { 275 /* don't retry on unsupported chiptype */ 276 if (stat == 0x80) 277 { 278 btfound = 0; 279 break; 280 } 281 cnt++; 282 } 283 if (stat & 0x7f) 284 { 285 LOG(4,("Brooktree: Too much errors occurred, aborting.\n")); 286 btfound = 0; 287 } 288 } 289 290 if (btfound) 291 LOG(4,("Brooktree: Found TV encoder on bus %d, adress $%02x\n", 292 si->ps.tv_encoder.bus, si->ps.tv_encoder.adress)); 293 else 294 LOG(4,("Brooktree: No TV encoder Found\n")); 295 296 return btfound; 297 } 298 299 static uint8 BT_init_PAL640() 300 { 301 uint8 stat; 302 303 uint8 buffer[35]; 304 305 LOG(4,("Brooktree: Setting PAL 640x480 desktop mode\n")); 306 307 buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command 308 buffer[1] = 0x76; //select first bt register to write to 309 buffer[2] = 0x60; 310 buffer[3] = 0x80; 311 buffer[4] = 0x8a; 312 buffer[5] = 0xa6; 313 buffer[6] = 0x68; 314 buffer[7] = 0xc1; 315 buffer[8] = 0x2e; 316 buffer[9] = 0xf2; 317 buffer[10] = 0x27; 318 buffer[11] = 0x00; 319 buffer[12] = 0xb0; 320 buffer[13] = 0x0a; 321 buffer[14] = 0x0b; 322 buffer[15] = 0x71; 323 buffer[16] = 0x5a; 324 buffer[17] = 0xe0; 325 buffer[18] = 0x36; 326 buffer[19] = 0x00; 327 buffer[20] = 0x50; 328 buffer[21] = 0x72; 329 buffer[22] = 0x1c; 330 buffer[23] = 0x8d; //chip-pin CLKI is pixel clock (only non-default here!) 331 buffer[24] = 0x24; 332 buffer[25] = 0xf0; 333 buffer[26] = 0x58; 334 buffer[27] = 0x81; 335 buffer[28] = 0x49; 336 buffer[29] = 0x8c; 337 buffer[30] = 0x0c; 338 buffer[31] = 0x8c; 339 buffer[32] = 0x79; 340 buffer[33] = 0x26; 341 buffer[34] = 0x00; 342 343 /* reset status */ 344 i2c_flag_error (-1); 345 346 i2c_bstart(si->ps.tv_encoder.bus); 347 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 348 i2c_bstop(si->ps.tv_encoder.bus); 349 /* log on errors */ 350 stat = i2c_flag_error(0); 351 if (stat) 352 LOG(4,("Brooktree: I2C errors occurred while setting mode PAL640\n")); 353 354 return stat; 355 }//end BT_init_PAL640. 356 357 static uint8 BT_init_PAL800() 358 { 359 uint8 stat; 360 361 uint8 buffer[35]; 362 363 LOG(4,("Brooktree: Setting PAL 800x600 desktop mode\n")); 364 365 buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command 366 buffer[1] = 0x76; //select first bt register to write to 367 buffer[2] = 0x00; 368 buffer[3] = 0x20; 369 buffer[4] = 0xaa; 370 buffer[5] = 0xca; 371 buffer[6] = 0x9a; 372 buffer[7] = 0x0d; 373 buffer[8] = 0x29; 374 buffer[9] = 0xfc; 375 buffer[10] = 0x39; 376 buffer[11] = 0x00; 377 buffer[12] = 0xc0; 378 buffer[13] = 0x8c; 379 buffer[14] = 0x03; 380 buffer[15] = 0xee; 381 buffer[16] = 0x5f; 382 buffer[17] = 0x58; 383 buffer[18] = 0x3a; 384 buffer[19] = 0x66; 385 buffer[20] = 0x96; 386 buffer[21] = 0x00; 387 buffer[22] = 0x00; 388 buffer[23] = 0x90; //chip-pin CLKI is pixel clock (only non-default here!) 389 buffer[24] = 0x24; 390 buffer[25] = 0xf0; 391 buffer[26] = 0x57; 392 buffer[27] = 0x80; 393 buffer[28] = 0x48; 394 buffer[29] = 0x8c; 395 buffer[30] = 0x18; 396 buffer[31] = 0x28; 397 buffer[32] = 0x87; 398 buffer[33] = 0x1f; 399 buffer[34] = 0x00; 400 401 /* reset status */ 402 i2c_flag_error (-1); 403 404 i2c_bstart(si->ps.tv_encoder.bus); 405 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 406 i2c_bstop(si->ps.tv_encoder.bus); 407 /* log on errors */ 408 stat = i2c_flag_error(0); 409 if (stat) 410 LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800\n")); 411 412 return stat; 413 }//end BT_init_PAL800. 414 415 static uint8 BT_init_NTSC640() 416 { 417 uint8 stat; 418 419 uint8 buffer[35]; 420 421 LOG(4,("Brooktree: Setting NTSC 640x480 desktop mode\n")); 422 423 buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command 424 buffer[1] = 0x76; //select first bt register to write to 425 buffer[2] = 0x00; 426 buffer[3] = 0x80; 427 buffer[4] = 0x84; 428 buffer[5] = 0x96; 429 buffer[6] = 0x60; 430 buffer[7] = 0x7d; 431 buffer[8] = 0x22; 432 buffer[9] = 0xd4; 433 buffer[10] = 0x27; 434 buffer[11] = 0x00; 435 buffer[12] = 0x10; 436 buffer[13] = 0x7e; 437 buffer[14] = 0x03; 438 buffer[15] = 0x58; 439 buffer[16] = 0x4b; 440 buffer[17] = 0xe0; 441 buffer[18] = 0x36; 442 buffer[19] = 0x92; 443 buffer[20] = 0x54; 444 buffer[21] = 0x0e; 445 buffer[22] = 0x88; 446 buffer[23] = 0x8c; //chip-pin CLKI is pixel clock (only non-default here!) 447 buffer[24] = 0x0a; 448 buffer[25] = 0xe5; 449 buffer[26] = 0x76; 450 buffer[27] = 0x79; 451 buffer[28] = 0x44; 452 buffer[29] = 0x85; 453 buffer[30] = 0x00; 454 buffer[31] = 0x00; 455 buffer[32] = 0x80; 456 buffer[33] = 0x20; 457 buffer[34] = 0x00; 458 459 /* reset status */ 460 i2c_flag_error (-1); 461 462 i2c_bstart(si->ps.tv_encoder.bus); 463 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 464 i2c_bstop(si->ps.tv_encoder.bus); 465 /* log on errors */ 466 stat = i2c_flag_error(0); 467 if (stat) 468 LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC640\n")); 469 470 return stat; 471 }//end BT_init_NTSC640. 472 473 static uint8 BT_init_NTSC800() 474 { 475 uint8 stat; 476 477 uint8 buffer[35]; 478 479 LOG(4,("Brooktree: Setting NTSC 800x600 desktop mode\n")); 480 481 buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command 482 buffer[1] = 0x76; //select first bt register to write to 483 buffer[2] = 0xa0; 484 buffer[3] = 0x20; 485 buffer[4] = 0xb6; 486 buffer[5] = 0xce; 487 buffer[6] = 0x84; 488 buffer[7] = 0x55; 489 buffer[8] = 0x20; 490 buffer[9] = 0xd8; 491 buffer[10] = 0x39; 492 buffer[11] = 0x00; 493 buffer[12] = 0x70; 494 buffer[13] = 0x42; 495 buffer[14] = 0x03; 496 buffer[15] = 0xdf; 497 buffer[16] = 0x56; 498 buffer[17] = 0x58; 499 buffer[18] = 0x3a; 500 buffer[19] = 0xcd; 501 buffer[20] = 0x9c; 502 buffer[21] = 0x14; 503 buffer[22] = 0x3b; 504 buffer[23] = 0x91; //chip-pin CLKI is pixel clock (only non-default here!) 505 buffer[24] = 0x0a; 506 buffer[25] = 0xe5; 507 buffer[26] = 0x74; 508 buffer[27] = 0x77; 509 buffer[28] = 0x43; 510 buffer[29] = 0x85; 511 buffer[30] = 0xba; 512 buffer[31] = 0xe8; 513 buffer[32] = 0xa2; 514 buffer[33] = 0x17; 515 buffer[34] = 0x00; 516 517 /* reset status */ 518 i2c_flag_error (-1); 519 520 i2c_bstart(si->ps.tv_encoder.bus); 521 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 522 i2c_bstop(si->ps.tv_encoder.bus); 523 /* log on errors */ 524 stat = i2c_flag_error(0); 525 if (stat) 526 LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800\n")); 527 528 return stat; 529 }//end BT_init_NTSC800. 530 531 static uint8 BT_init_PAL720() 532 { 533 uint8 stat; 534 535 uint8 buffer[35]; 536 537 LOG(4,("Brooktree: Setting PAL 720x576 overscanning DVD mode\n")); 538 539 buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command 540 buffer[1] = 0x76; //select first bt register to write to 541 buffer[2] = 0xf0; 542 buffer[3] = 0xd0; 543 buffer[4] = 0x82; 544 buffer[5] = 0x9c; 545 buffer[6] = 0x5a; 546 buffer[7] = 0x31; 547 buffer[8] = 0x16; 548 buffer[9] = 0x22; 549 buffer[10] = 0xa6; 550 buffer[11] = 0x00; 551 buffer[12] = 0x78; 552 buffer[13] = 0x93; 553 buffer[14] = 0x03; 554 buffer[15] = 0x71; 555 buffer[16] = 0x2a; 556 buffer[17] = 0x40; 557 buffer[18] = 0x0a; 558 buffer[19] = 0x00; 559 buffer[20] = 0x50; 560 buffer[21] = 0x55; 561 buffer[22] = 0x55; 562 buffer[23] = 0x8c; //chip-pin CLKI is pixel clock (only non-default here!) 563 buffer[24] = 0x24; 564 buffer[25] = 0xf0; 565 buffer[26] = 0x59; 566 buffer[27] = 0x82; 567 buffer[28] = 0x49; 568 buffer[29] = 0x8c; 569 buffer[30] = 0x8e; 570 buffer[31] = 0xb0; 571 buffer[32] = 0xe6; 572 buffer[33] = 0x28; 573 buffer[34] = 0x00; 574 575 /* reset status */ 576 i2c_flag_error (-1); 577 578 i2c_bstart(si->ps.tv_encoder.bus); 579 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 580 i2c_bstop(si->ps.tv_encoder.bus); 581 /* log on errors */ 582 stat = i2c_flag_error(0); 583 if (stat) 584 LOG(4,("Brooktree: I2C errors occurred while setting mode PAL720\n")); 585 586 return stat; 587 }//end BT_init_PAL720. 588 589 static uint8 BT_init_NTSC720() 590 { 591 uint8 stat; 592 593 uint8 buffer[35]; 594 595 LOG(4,("Brooktree: Setting NTSC 720x480 overscanning DVD mode\n")); 596 597 buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command 598 buffer[1] = 0x76; //select first bt register to write to. 599 buffer[2] = 0xf0; //lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1) 600 buffer[3] = 0xd0; //lsb h_active: h_active = 720 pixels wide port 601 buffer[4] = 0x83; //scope: OK hsync_width: (hsync_width / h_clk_o) * 63.55556uS = 4.70uS for NTSC 602 buffer[5] = 0x98; //scope: OK hburst_begin: (hburst_begin / h_clk_o) * 63.55556uS = 5.3uS for NTSC 603 buffer[6] = 0x5e; //scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 63.55556uS = 7.94uS for NTSC 604 605 //How to find the correct values for h_blank_o and v_blank_o: 606 // 1. Calculate h_blank_o according to initial setting guideline mentioned below; 607 // 2. Set v_blank_o in the neighbourhood of $18, so that TV picture does not have ghosts on right side in it while 608 // horizontal position is about OK; 609 // 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch); 610 // 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above); 611 // 5. If no vertical shivering occurs when image is centered, you're done. Else: 612 // 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!: 613 // 7. Make sure you update the Chrontel horizontal Phase setting also then! 614 615 if (si->ps.tv_encoder.type >= CX25870)//set CX value 616 { 617 /* confirmed on NV11 using 4:3 TV and 16:9 TV */ 618 buffer[7] = 0x0c; //scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV 619 //(guideline for initial setting: (h_blank_o / h_clk_0) * 63.55556uS = 9.5uS for NTSC) 620 } 621 else //set BT value 622 { 623 /* confirmed on TNT1 using 4:3 TV and 16:9 TV */ 624 buffer[7] = 0x28; //scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV 625 //(guideline for initial setting: (h_blank_o / h_clk_0) * 63.55556uS = 9.5uS for NTSC) 626 } 627 buffer[8] = 0x18; //try-out; scope: checked against other modes, looks OK. v_blank_o: 1e active line ('pixel') 628 629 buffer[9] = 0xf2; //v_active_o: = (active output lines + 2) / field (on TV) 630 buffer[10] = 0x26; //lsn = msn h_clk_o; 631 //b4-5 = msbits h_active; 632 //b7 = b8 v_avtive_o. 633 buffer[11] = 0x00; //h_fract is always 0. 634 buffer[12] = 0x78; //lsb h_clk_i: h_clk_i is horizontal total = 888. 635 buffer[13] = 0x90; //try-out; lsb h_blank_i: #clks between start sync and new line 1st pixel; copy to VGA delta-sync! 636 buffer[14] = 0x03; //b2-0 = msn h_clk_i; 637 //try-out: b3 = msn h_blank_i; 638 //b4 = vblankdly is always 0. 639 buffer[15] = 0x0d; //lsb v_lines_i: v_lines_i = 525 640 buffer[16] = 0x1a; //try-out; v_blank_i: #input lines between start sync and new line (pixel); copy to VGA delta-sync! 641 //Make sure though that this value for the BT is *even*, or image will shiver a *lot* horizontally on TV. 642 buffer[17] = 0xe0; //lsb v_active_i: v_active_i = 480 643 buffer[18] = 0x36; //b1-0 = msn v_lines_i; 644 //b3-2 = msn v_active_i; 645 //b5-4 = ylpf = 3; 646 //b7-6 = clpf = 0. 647 buffer[19] = 0x00; //lsb v_scale: v_scale = off = $1000 648 buffer[20] = 0x50; //b5-0 = msn v_scale; 649 //scope: tuned. b7-6 = msn h_blank_o. 650 //(((PLL_INT + (PLL_FRACT/65536)) / 6) * 13500000) = PIXEL_CLK = (hor.tot. * v_lines_i * 60Hz) 651 buffer[21] = 0x98; //lsb PLL fract: PLL fract = 0x6e98 652 buffer[22] = 0x6e; //msb PLL fract 653 buffer[23] = 0x8c; //b5-0 = PLL int: PLL int = 0x0c; 654 //b6 = by_pll: by_pll = 0; 655 //b7 = EN_XCLK: chip-pin CLKI is pixel clock. 656 buffer[24] = 0x0a; //b0 = ni_out is always 0; 657 //b1 = setup = 1 for NTSC; 658 //b2 = 625line = 0 for NTSC; 659 //b3 = vsync_dur = 1 for NTSC; 660 //b4 = dic_screset is always 0; 661 //b5 = pal_md = 0 for NTSC; 662 //b6 = eclip is always 0; 663 //b7 = reserved (en_scart) is always 0. 664 buffer[25] = 0xe5; //sync_amp $e5 for NTSC 665 buffer[26] = 0x75; //bst_amp $74-$76 for NTSC 666 buffer[27] = 0x78; //mcr: r-y $77-$79 for NTSC 667 buffer[28] = 0x44; //mcb: b-y $43-$44 for NTSC 668 buffer[29] = 0x85; //my: y $85 for NTSC 669 buffer[30] = 0x3c; //lsb msc: msc b31-0: NTSC formula: ((3579545 / pixelclk) * 2^32) = MSC 670 buffer[31] = 0x91; //msc = $20c2913c 671 buffer[32] = 0xc2; 672 buffer[33] = 0x20; //msb msc. 673 buffer[34] = 0x00; //phase_off always $00 674 675 /* reset status */ 676 i2c_flag_error (-1); 677 678 i2c_bstart(si->ps.tv_encoder.bus); 679 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 680 i2c_bstop(si->ps.tv_encoder.bus); 681 /* log on errors */ 682 stat = i2c_flag_error(0); 683 if (stat) 684 LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC720\n")); 685 686 return stat; 687 }//end BT_init_NTSC720. 688 689 static uint8 BT_init_PAL800_OS() 690 { 691 uint8 stat; 692 693 uint8 buffer[35]; 694 695 LOG(4,("Brooktree: Setting PAL 800x600 overscanning VCD mode\n")); 696 697 buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command 698 buffer[1] = 0x76; //select first bt register to write to. 699 buffer[2] = 0x60; //lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1) 700 buffer[3] = 0x20; //lsb h_active: h_active = 800 pixels wide port 701 buffer[4] = 0x8b; //scope: OK hsync_width: (hsync_width / h_clk_o) * 64.0uS = 4.70uS for PAL 702 buffer[5] = 0xa5; //scope: OK hburst_begin: (hburst_begin / h_clk_o) * 64.0uS = 5.6uS for PAL 703 buffer[6] = 0x6b; //scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 64.0uS = 7.97uS for PAL 704 705 //How to find the correct values for h_blank_o and v_blank_o: 706 // 1. Calculate h_blank_o according to initial setting guideline mentioned below; 707 // 2. Set v_blank_o in the neighbourhood of $18, so that TV picture does not have ghosts on right side in it while 708 // horizontal position is about OK; 709 // 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch); 710 // 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above); 711 // 5. If no vertical shivering occurs when image is centered, you're done. Else: 712 // 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!: 713 // 7. Make sure you update the Chrontel horizontal Phase setting also then! 714 715 if (si->ps.tv_encoder.type >= CX25870)//set CX value 716 { 717 /* confirmed on NV11 using 4:3 TV and 16:9 TV */ 718 buffer[7] = 0xf0; 719 buffer[8] = 0x17; 720 } 721 else //set BT value 722 { 723 /* confirmed on TNT1 using 4:3 TV and 16:9 TV */ 724 buffer[7] = 0xd0;//scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV 725 //(guideline for initial setting: (h_blank_o / h_clk_0) * 64.0uS = 10.0uS for PAL) 726 buffer[8] = 0x18;//try-out; scope: checked against other modes, looks OK. v_blank_o: 1e active line ('pixel') 727 } 728 729 buffer[9] = 0x2e; //v_active_o: = (active output lines + 2) / field (on TV) 730 buffer[10] = 0xb7; //lsn = msn h_clk_o; 731 //b4-5 = msbits h_active; 732 //b7 = b8 v_avtive_o. 733 buffer[11] = 0x00; //h_fract is always 0. 734 buffer[12] = 0xb0; //lsb h_clk_i: h_clk_i is horizontal total = 944. 735 736 if (si->ps.tv_encoder.type >= CX25870)//set CX value 737 buffer[13] = 0x20; 738 else //set BT value 739 buffer[13] = 0x14;//try-out; lsb h_blank_i: #clks between start sync and new line 1st pixel; copy to VGA delta-sync! 740 741 buffer[14] = 0x03; //b2-0 = msn h_clk_i; 742 //try-out: b3 = msn h_blank_i; 743 //b4 = vblankdly is always 0. 744 buffer[15] = 0x71; //lsb v_lines_i: v_lines_i = 625 745 746 if (si->ps.tv_encoder.type >= CX25870)//set CX value 747 buffer[16] = 0x08; 748 else //set BT value 749 buffer[16] = 0x2a;//try-out; v_blank_i: #input lines between start sync and new line (pixel); copy to VGA delta-sync! 750 //Make sure though that this value for the BT is *even*, or image will shiver a *lot* horizontally on TV. 751 752 buffer[17] = 0x58; //lsb v_active_i: v_active_i = 600 753 buffer[18] = 0x3a; //b1-0 = msn v_lines_i; 754 //b3-2 = msn v_active_i; 755 //b5-4 = ylpf = 3; 756 //b7-6 = clpf = 0. 757 buffer[19] = 0x00; //lsb v_scale: v_scale = off = $1000 758 buffer[20] = 0x10; //b5-0 = msn v_scale; 759 //scope: tuned. b7-6 = msn h_blank_o. 760 //(((PLL_INT + (PLL_FRACT/65536)) / 6) * 13500000) = PIXEL_CLK = (hor.tot. * v_lines_i * 50Hz) 761 buffer[21] = 0x72; //lsb PLL fract: PLL fract = 0x1c72 762 buffer[22] = 0x1c; //msb PLL fract 763 buffer[23] = 0x8d; //b5-0 = PLL int: PLL int = 0x0d; 764 //b6 = by_pll: by_pll = 0; 765 //b7 = EN_XCLK: chip-pin CLKI is pixel clock. 766 buffer[24] = 0x24; //b0 = ni_out is always 0; 767 //b1 = setup = 0 for PAL; 768 //b2 = 625line = 1 for PAL; 769 //b3 = vsync_dur = 0 for PAL; 770 //b4 = dic_screset is always 0; 771 //b5 = pal_md = 1 for PAL; 772 //b6 = eclip is always 0; 773 //b7 = reserved (en_scart) is always 0. 774 buffer[25] = 0xf0; //sync_amp $f0 for PAL 775 buffer[26] = 0x57; //bst_amp $57-$58 for PAL 776 buffer[27] = 0x80; //mcr: r-y $80-$81 for PAL 777 buffer[28] = 0x48; //mcb: b-y $48-$49 for PAL 778 buffer[29] = 0x8c; //my: y $8c for PAL 779 buffer[30] = 0x31; //lsb msc: msc b31-0: PAL formula: ((4433619 / pixelclk) * 2^32) = MSC 780 buffer[31] = 0x8c; //msc = $26798c31 781 buffer[32] = 0x79; 782 buffer[33] = 0x26; //msb msc. 783 buffer[34] = 0x00; //phase_off always $00 784 785 /* reset status */ 786 i2c_flag_error (-1); 787 788 i2c_bstart(si->ps.tv_encoder.bus); 789 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 790 i2c_bstop(si->ps.tv_encoder.bus); 791 /* log on errors */ 792 stat = i2c_flag_error(0); 793 if (stat) 794 LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800 OS\n")); 795 796 return stat; 797 }//end BT_init_PAL800_OS. 798 799 static uint8 BT_init_NTSC640_OS() 800 { 801 uint8 stat; 802 803 uint8 buffer[35]; 804 805 LOG(4,("Brooktree: Setting NTSC 640x480 overscanning VCD mode\n")); 806 807 buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command 808 buffer[1] = 0x76; //select first bt register to write to. 809 buffer[2] = 0x20; //lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1) 810 buffer[3] = 0x80; //lsb h_active: h_active = 640 pixels wide port 811 buffer[4] = 0x74; //scope: OK hsync_width: (hsync_width / h_clk_o) * 63.55556uS = 4.70uS for NTSC 812 buffer[5] = 0x83; //scope: OK hburst_begin: (hburst_begin / h_clk_o) * 63.55556uS = 5.3uS for NTSC 813 buffer[6] = 0x44; //scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 63.55556uS = 7.94uS for NTSC 814 815 //How to find the correct values for h_blank_o and v_blank_o: 816 // 1. Calculate h_blank_o according to initial setting guideline mentioned below; 817 // 2. Set v_blank_o in the neighbourhood of $18, so that TV picture does not have ghosts on right side in it while 818 // horizontal position is about OK; 819 // 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch); 820 // 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above); 821 // 5. If no vertical shivering occurs when image is centered, you're done. Else: 822 // 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!: 823 // 7. Make sure you update the Chrontel horizontal Phase setting also then! 824 825 buffer[7] = 0xf7; //scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV: 826 //(guideline for initial setting: (h_blank_o / h_clk_0) * 63.55556uS = 9.5uS for NTSC) 827 828 if (si->ps.tv_encoder.type >= CX25870)//set CX value 829 buffer[8] = 0x1d; 830 else //set BT value 831 buffer[8] = 0x1c;//try-out; scope: checked against other modes, looks OK. v_blank_o: 1e active line ('pixel') 832 833 buffer[9] = 0xf2; //v_active_o: = (active output lines + 2) / field (on TV) 834 buffer[10] = 0x26; //lsn = msn h_clk_o; 835 //b4-5 = msbits h_active; 836 //b7 = b8 v_avtive_o. 837 buffer[11] = 0x00; //h_fract is always 0. 838 buffer[12] = 0x10; //lsb h_clk_i: h_clk_i is horizontal total = 784. 839 buffer[13] = 0x14; //try-out; lsb h_blank_i: #clks between start sync and new line 1st pixel; copy to VGA delta-sync! 840 buffer[14] = 0x03; //b2-0 = msn h_clk_i; 841 //try-out: b3 = msn h_blank_i; 842 //b4 = vblankdly is always 0. 843 buffer[15] = 0x0d; //lsb v_lines_i: v_lines_i = 525 844 buffer[16] = 0x18; //try-out; v_blank_i: #input lines between start sync and new line (pixel); copy to VGA delta-sync! 845 //Make sure though that this value for the BT is *even*, or image will shiver a *lot* horizontally on TV. 846 buffer[17] = 0xe0; //lsb v_active_i: v_active_i = 480 847 buffer[18] = 0x36; //b1-0 = msn v_lines_i; 848 //b3-2 = msn v_active_i; 849 //b5-4 = ylpf = 3; 850 //b7-6 = clpf = 0. 851 buffer[19] = 0x00; //lsb v_scale: v_scale = off = $1000 852 buffer[20] = 0x10; //b5-0 = msn v_scale; 853 //scope: tuned. b7-6 = msn h_blank_o. 854 //(((PLL_INT + (PLL_FRACT/65536)) / 6) * 13500000) = PIXEL_CLK = (hor.tot. * v_lines_i * 60Hz) 855 buffer[21] = 0xdb; //lsb PLL fract: PLL fract = 0xf9db 856 buffer[22] = 0xf9; //msb PLL fract 857 buffer[23] = 0x8a; //b5-0 = PLL int: PLL int = 0x0a; 858 //b6 = by_pll: by_pll = 0; 859 //b7 = EN_XCLK: chip-pin CLKI is pixel clock. 860 buffer[24] = 0x0a; //b0 = ni_out is always 0; 861 //b1 = setup = 1 for NTSC; 862 //b2 = 625line = 0 for NTSC; 863 //b3 = vsync_dur = 1 for NTSC; 864 //b4 = dic_screset is always 0; 865 //b5 = pal_md = 0 for NTSC; 866 //b6 = eclip is always 0; 867 //b7 = reserved (en_scart) is always 0. 868 buffer[25] = 0xe5; //sync_amp $e5 for NTSC 869 buffer[26] = 0x75; //bst_amp $74-$76 for NTSC 870 buffer[27] = 0x78; //mcr: r-y $77-$79 for NTSC 871 buffer[28] = 0x44; //mcb: b-y $43-$44 for NTSC 872 buffer[29] = 0x85; //my: y $85 for NTSC 873 buffer[30] = 0x37; //lsb msc: msc b31-0: NTSC formula: ((3579545 / pixelclk) * 2^32) = MSC 874 buffer[31] = 0x12; //msc = $251b1237 875 buffer[32] = 0x1b; 876 buffer[33] = 0x25; //msb msc. 877 buffer[34] = 0x00; //phase_off always $00 878 879 /* reset status */ 880 i2c_flag_error (-1); 881 882 i2c_bstart(si->ps.tv_encoder.bus); 883 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 884 i2c_bstop(si->ps.tv_encoder.bus); 885 /* log on errors */ 886 stat = i2c_flag_error(0); 887 if (stat) 888 LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC640 OS\n")); 889 890 return stat; 891 }//end BT_init_NTSC640_OS. 892 893 static uint8 BT_testsignal(void) 894 { 895 uint8 stat; 896 897 uint8 buffer[3]; 898 899 LOG(4,("Brooktree: Enabling testsignal\n")); 900 901 buffer[0] = si->ps.tv_encoder.adress + WR; 902 /* select bt register for enabling colorbars and outputs */ 903 buffer[1] = 0xc4; 904 /* issue the actual command */ 905 buffer[2] = 0x05; 906 907 /* reset status */ 908 i2c_flag_error (-1); 909 910 i2c_bstart(si->ps.tv_encoder.bus); 911 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 912 i2c_bstop(si->ps.tv_encoder.bus); 913 /* log on errors */ 914 stat = i2c_flag_error(0); 915 if (stat) 916 LOG(4,("Brooktree: I2C errors occurred while setting up flickerfilter and outputs\n")); 917 918 return stat; 919 }//end BT_testsignal. 920 921 static uint8 BT_setup_output(uint8 monstat, uint8 output, uint8 ffilter) 922 { 923 uint8 stat; 924 925 uint8 buffer[7]; 926 927 buffer[0] = si->ps.tv_encoder.adress + WR; 928 /* select first TV config register to write */ 929 buffer[1] = 0xc6; 930 /* input is 24bit mpx'd RGB, BLANK = out, sync = act. hi */ 931 buffer[2] = 0x98; 932 /* disable all filters, exept flicker filter */ 933 buffer[3] = 0x98; 934 if (!ffilter) 935 { 936 /* disable flicker filter */ 937 buffer[3] = 0xc0; 938 LOG(4,("Brooktree: Disabling flickerfilter\n")); 939 } 940 else 941 LOG(4,("Brooktree: Enabling flickerfilter\n")); 942 943 /* (disable filters) */ 944 buffer[4] = 0xc0; 945 /* (disable filters) */ 946 buffer[5] = 0xc0; 947 switch (output) 948 /* Description of ELSA Erazor III hardware layout: 949 * (This is the default (recommended) layout by NVIDIA) 950 * DAC A = CVBS 951 * DAC B = C (chrominance) 952 * DAC C = Y (luminance) */ 953 954 /* Description of Diamond VIPER550: 955 * DAC A = Not connected 956 * DAC B = C (chrominance) 957 * DAC C = Y (luminance) 958 * To be able to connect to CVBS TV's a special cable is supplied: 959 * This cable connects the Y (DAC C) output to the TV CVBS input. */ 960 { 961 case 1: 962 LOG(4,("Brooktree: Forcing both Y/C and CVBS signals where supported by hardware\n")); 963 buffer[6] = 0x18; // Y/C and CVBS out if all ports implemented 964 // in hardware, else only Y/C or CVBS out. 965 break; 966 case 2: 967 LOG(4,("Brooktree: Forcing CVBS signals on all outputs\n")); 968 buffer[6] = 0x00; // put CVBS on all outputs. Used for cards 969 break; // with only Y/C out and 'translation cable'. 970 default: 971 LOG(4,("Brooktree: Outputting signals according to autodetect status:\n")); 972 switch (monstat) // only 'autodetect' remains... 973 { 974 case 1: 975 LOG(4,("Brooktree: Only Y connected, outputting CVBS on all outputs\n")); 976 buffer[6] = 0x00; //only Y connected: must be CVBS! 977 break; 978 case 2: 979 LOG(4,("Brooktree: Only C connected, outputting CVBS on all outputs\n")); 980 buffer[6] = 0x00; //only C connected: must be CVBS! 981 break; //(though cable is wired wrong...) 982 case 5: 983 LOG(4,("Brooktree: CVBS and only Y connected, outputting CVBS on all outputs\n")); 984 buffer[6] = 0x00; //CVBS and only Y connected: 2x CVBS! 985 break; //(officially not supported...) 986 case 6: 987 LOG(4,("Brooktree: CVBS and only C connected, outputting CVBS on all outputs\n")); 988 buffer[6] = 0x00; //CVBS and only C connected: 2x CVBS! 989 break; //(officially not supported...) 990 default: 991 LOG(4,("Brooktree: Outputting both Y/C and CVBS where supported by hardware\n")); 992 buffer[6] = 0x18; //nothing, or 993 //Y/C only, or 994 //CVBS only (but on CVBS output), or 995 //Y/C and CVBS connected: 996 //So activate recommended signals. 997 } 998 } 999 1000 /* reset status */ 1001 i2c_flag_error (-1); 1002 1003 i2c_bstart(si->ps.tv_encoder.bus); 1004 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 1005 i2c_bstop(si->ps.tv_encoder.bus); 1006 /* log on errors */ 1007 stat = i2c_flag_error(0); 1008 if (stat) 1009 LOG(4,("Brooktree: I2C errors occurred while setting up flickerfilter and outputs\n")); 1010 1011 return stat; 1012 }//end BT_setup_output. 1013 1014 static uint8 BT_setup_hphase(uint8 mode) 1015 { 1016 uint8 stat, hoffset; 1017 1018 uint8 buffer[7]; 1019 1020 LOG(4,("Brooktree: Tuning horizontal phase\n")); 1021 1022 /* CX needs timing reset (advised on BT also), first 1mS delay needed! */ 1023 snooze(1000); 1024 1025 /* values below are all tested on TNT1, TNT2 and GeForce2MX */ 1026 buffer[0] = si->ps.tv_encoder.adress + WR; 1027 /* select first TV output timing register to write */ 1028 buffer[1] = 0x6c; 1029 /* turn on active video & generate timing reset on CX chips! */ 1030 buffer[2] = 0x86; 1031 /* (set fail save values...) */ 1032 buffer[3] = 0x00; //set default horizontal sync offset 1033 buffer[4] = 0x02; //set default horizontal sync width 1034 buffer[5] = 0x00; //set default vertical sync offset 1035 1036 /* do specific timing setup for all chips and modes: */ 1037 switch (si->ps.card_type) 1038 { 1039 case NV05: 1040 case NV05M64: 1041 case NV15: 1042 /* confirmed TNT2, TNT2M64, GeForce2Ti. 1043 * (8 pixels delayed hpos, so picture more to the right) */ 1044 hoffset = 8; 1045 break; 1046 default: 1047 /* confirmed TNT1, GeForce256, GeForce2MX. 1048 * (std hpos) 1049 * NOTE: It might be that GeForce needs TNT2 offset: 1050 * for now CX chips get seperate extra offset, until sure. 1051 * (CX is only found AFAIK on GeForce cards, no BT tested 1052 * on GeForce yet. CH was tested on GeForce and seemed to 1053 * indicate TNT1 offset was needed.) */ 1054 hoffset = 0; 1055 break; 1056 } 1057 1058 switch (mode) 1059 { 1060 case NTSC640_TST: 1061 case NTSC640: 1062 if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more... 1063 /* confirmed on TNT1 with BT869 using 4:3 TV and 16:9 TV */ 1064 buffer[3] = (0x1e + hoffset); //set horizontal sync offset 1065 break; 1066 case NTSC800: 1067 if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more... 1068 buffer[3] = (0xe1 + hoffset); //set horizontal sync offset 1069 buffer[4] = 0xc2; 1070 //Vsync offset reg. does not exist on CX: mode is checked and OK. 1071 buffer[5] = 0x40; //set VSync offset (on BT's only) 1072 break; 1073 case PAL640: 1074 if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more... 1075 buffer[3] = (0xa8 + hoffset); 1076 break; 1077 case PAL800_TST: 1078 case PAL800: 1079 if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more... 1080 buffer[3] = (0x2c + hoffset); 1081 break; 1082 case NTSC720: 1083 if (si->ps.tv_encoder.type >= CX25870) 1084 buffer[3] = (0xb2 + hoffset); //set horizontal sync offset CX 1085 else 1086 buffer[3] = (0xd0 + hoffset); //set horizontal sync offset BT 1087 buffer[4] = 0xff; //hsync width = max: 1088 break; //to prevent vertical image 'shivering'. 1089 case PAL720: 1090 buffer[3] = (0xd4 + hoffset); 1091 buffer[4] = 0xff; 1092 break; 1093 case NTSC640_OS: 1094 buffer[3] = (0xc8 + hoffset); 1095 buffer[4] = 0xff; 1096 break; 1097 case PAL800_OS: 1098 if (si->ps.tv_encoder.type >= CX25870) 1099 buffer[3] = (0x78 + hoffset); //set horizontal sync offset CX 1100 else 1101 buffer[3] = (0xc4 + hoffset); //set horizontal sync offset BT 1102 buffer[4] = 0xff; 1103 break; 1104 default: //nothing to be done here... 1105 break; 1106 } 1107 1108 buffer[6] = 0x01; //set default vertical sync width 1109 1110 /* reset status */ 1111 i2c_flag_error (-1); 1112 1113 i2c_bstart(si->ps.tv_encoder.bus); 1114 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 1115 i2c_bstop(si->ps.tv_encoder.bus); 1116 /* log on errors */ 1117 stat = i2c_flag_error(0); 1118 if (stat) 1119 LOG(4,("Brooktree: I2C errors occurred while setting up h_phase\n")); 1120 1121 return stat; 1122 }//end BT_setup_hphase. 1123 1124 static uint8 BT_read_monstat(uint8* monstat) 1125 { 1126 uint8 stat; 1127 uint8 buffer[3]; 1128 1129 /* make sure we have the recommended failsafe selected */ 1130 *monstat = 0; 1131 1132 LOG(4,("Brooktree: Autodetecting connected output devices\n")); 1133 1134 /* set BT to return connection status in ESTATUS on next read CMD: */ 1135 buffer[0] = si->ps.tv_encoder.adress + WR; 1136 /* set ESTATUS at b'01' (return conn.stat.) */ 1137 buffer[1] = 0xc4; 1138 /* and leave chip outputs on. */ 1139 buffer[2] = 0x41; 1140 1141 /* reset status */ 1142 i2c_flag_error (-1); 1143 1144 i2c_bstart(si->ps.tv_encoder.bus); 1145 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 1146 i2c_bstop(si->ps.tv_encoder.bus); 1147 /* log on errors */ 1148 stat = i2c_flag_error(0); 1149 if (stat) 1150 { 1151 LOG(4,("Brooktree: I2C errors occurred while reading connection status (1)\n")); 1152 return stat; 1153 } 1154 1155 /* do actual read connection status: */ 1156 buffer[0] = si->ps.tv_encoder.adress + WR; 1157 /* select register with CHECK_STAT CMD */ 1158 buffer[1] = 0xba; 1159 /* issue actual command. */ 1160 buffer[2] = 0x40; 1161 1162 i2c_bstart(si->ps.tv_encoder.bus); 1163 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 1164 i2c_bstop(si->ps.tv_encoder.bus); 1165 /* log on errors */ 1166 stat = i2c_flag_error(0); 1167 if (stat) 1168 { 1169 LOG(4,("Brooktree: I2C errors occurred while reading connection status (2)\n")); 1170 return stat; 1171 } 1172 1173 /* CX: Wait 600uS for signals to stabilize (see datasheet) */ 1174 /* warning, note: 1175 * datasheet is in error! 60mS needed!! */ 1176 snooze(60000); 1177 1178 /* read back updated connection status: */ 1179 buffer[0] = si->ps.tv_encoder.adress + RD; 1180 1181 /* transmit 1 byte */ 1182 i2c_bstart(si->ps.tv_encoder.bus); 1183 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 1); 1184 1185 /* receive 1 byte */ 1186 /* ACK level to TX after last byte to RX should be 1 (= NACK) (see I2C spec) 1187 * While the BT's don't care, CX chips will block the SDA line if an ACK gets sent! */ 1188 buffer[0] = 1; 1189 i2c_readbuffer(si->ps.tv_encoder.bus, buffer, 1); 1190 i2c_bstop(si->ps.tv_encoder.bus); 1191 /* log on errors */ 1192 stat = i2c_flag_error(0); 1193 if (stat) 1194 { 1195 LOG(4,("Brooktree: I2C errors occurred while reading connection status (3)\n")); 1196 return stat; 1197 } 1198 1199 *monstat = ((buffer[0] & 0xe0) >> 5); 1200 LOG(4,("Brooktree: TV output monitor status = %d\n", *monstat)); 1201 1202 /* instruct BT to go back to normal operation: */ 1203 buffer[0] = si->ps.tv_encoder.adress + WR; 1204 /* select register with CHECK_STAT CMD */ 1205 buffer[1] = 0xba; 1206 /* issue actual command. */ 1207 buffer[2] = 0x00; 1208 1209 i2c_bstart(si->ps.tv_encoder.bus); 1210 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 1211 i2c_bstop(si->ps.tv_encoder.bus); 1212 /* log on errors */ 1213 stat = i2c_flag_error(0); 1214 if (stat) 1215 { 1216 LOG(4,("Brooktree: I2C errors occurred while reading connection status (4)\n")); 1217 return stat; 1218 } 1219 1220 return stat; 1221 }//end BT_read_monstat. 1222 1223 static uint8 BT_killclk_blackout(void) 1224 { 1225 uint8 stat; 1226 1227 uint8 buffer[4]; 1228 1229 LOG(4,("Brooktree: Killing clock and/or blacking out (blocking output signals)\n")); 1230 1231 /* reset status */ 1232 i2c_flag_error (-1); 1233 1234 if (si->ps.tv_encoder.type <= BT869) //BT... 1235 { 1236 /* Only disable external pixelclock input on BT's. 1237 * CX chips will lock the bus if you do this. 1238 * (It looks like the external pixelclock is always OK as long as a valid 1239 * mode is programmed for the TVout chip. This means that disabling the use 1240 * of this clock is not needed anyway. 1241 * If you do disable this input, this pixelclock will rise to about 60Mhz BTW..) */ 1242 1243 /* disable use of external pixelclock source... */ 1244 /* (should prevent BT for being 'overclocked' by RIVA in VGA-only mode...) */ 1245 buffer[0] = si->ps.tv_encoder.adress + WR; 1246 /* select BT register for setting EN_XCLK */ 1247 buffer[1] = 0xa0; 1248 /* clear it */ 1249 buffer[2] = 0x00; 1250 1251 i2c_bstart(si->ps.tv_encoder.bus); 1252 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3); 1253 i2c_bstop(si->ps.tv_encoder.bus); 1254 /* log on errors */ 1255 stat = i2c_flag_error(0); 1256 if (stat) 1257 { 1258 LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (1-BT)\n")); 1259 return stat; 1260 } 1261 } 1262 else //CX... 1263 { 1264 /* Disable CX video out (or wild output will be seen on TV..) */ 1265 buffer[0] = si->ps.tv_encoder.adress + WR; 1266 /* select register in CX */ 1267 buffer[1] = 0x6c; 1268 /* disable active video out. */ 1269 buffer[2] = 0x02; 1270 1271 i2c_bstart(si->ps.tv_encoder.bus); 1272 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3); 1273 i2c_bstop(si->ps.tv_encoder.bus); 1274 /* log on errors */ 1275 stat = i2c_flag_error(0); 1276 if (stat) 1277 { 1278 LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (1-CX)\n")); 1279 return stat; 1280 } 1281 } 1282 1283 /* black-out TVout while outputs are enabled... */ 1284 buffer[0] = si->ps.tv_encoder.adress + WR; 1285 /* select first TV config register to write */ 1286 buffer[1] = 0xc4; 1287 /* disable testimage while outputs remain enabled */ 1288 buffer[2] = 0x01; 1289 /* input is 24bit mpx'd RGB, BLANK = in, sync = act. hi */ 1290 buffer[3] = 0x18; 1291 1292 i2c_bstart(si->ps.tv_encoder.bus); 1293 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer)); 1294 i2c_bstop(si->ps.tv_encoder.bus); 1295 /* log on errors */ 1296 stat = i2c_flag_error(0); 1297 if (stat) 1298 { 1299 LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (2)\n")); 1300 return stat; 1301 } 1302 1303 return stat; 1304 }//end BT_killclk_blackout. 1305 1306 uint8 BT_dpms(bool display) 1307 { 1308 uint8 stat; 1309 1310 uint8 buffer[3]; 1311 1312 LOG(4,("Brooktree: setting DPMS: ")); 1313 1314 /* reset status */ 1315 i2c_flag_error (-1); 1316 1317 /* shutdown all analog electronics... */ 1318 buffer[0] = si->ps.tv_encoder.adress + WR; 1319 /* select first TV config register to write */ 1320 buffer[1] = 0xba; 1321 if (display) 1322 { 1323 /* enable all DACs */ 1324 buffer[2] = 0x00; 1325 LOG(4,("display on\n")); 1326 } 1327 else 1328 { 1329 /* shutdown all DACs */ 1330 buffer[2] = 0x10; 1331 LOG(4,("display off\n")); 1332 } 1333 1334 i2c_bstart(si->ps.tv_encoder.bus); 1335 i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3); 1336 i2c_bstop(si->ps.tv_encoder.bus); 1337 /* log on errors */ 1338 stat = i2c_flag_error(0); 1339 if (stat) 1340 { 1341 LOG(4,("Brooktree: I2C errors occurred while setting DPMS\n")); 1342 return stat; 1343 } 1344 1345 return stat; 1346 }//end BT_dpms. 1347 1348 uint8 BT_check_tvmode(display_mode target) 1349 { 1350 uint8 status = NOT_SUPPORTED; 1351 uint32 mode = ((target.timing.h_display) | ((target.timing.v_display) << 16)); 1352 1353 switch (mode) 1354 { 1355 case (640 | (480 << 16)): 1356 if (((target.flags & TV_BITS) == TV_PAL) && (!(target.flags & TV_VIDEO))) 1357 status = PAL640; 1358 if ((target.flags & TV_BITS) == TV_NTSC) 1359 { 1360 if (!(target.flags & TV_VIDEO)) status = NTSC640; 1361 else status = NTSC640_OS; 1362 } 1363 break; 1364 case (768 | (576 << 16)): 1365 if (((target.flags & TV_BITS) == TV_PAL) && (target.flags & TV_VIDEO)) 1366 status = PAL800_OS; 1367 break; 1368 case (800 | (600 << 16)): 1369 if (((target.flags & TV_BITS) == TV_PAL) && (!(target.flags & TV_VIDEO))) 1370 status = PAL800; 1371 if (((target.flags & TV_BITS) == TV_NTSC) && (!(target.flags & TV_VIDEO))) 1372 status = NTSC800; 1373 break; 1374 case (720 | (480 << 16)): 1375 if (((target.flags & TV_BITS) == TV_NTSC) && (target.flags & TV_VIDEO)) 1376 status = NTSC720; 1377 break; 1378 case (720 | (576 << 16)): 1379 if (((target.flags & TV_BITS) == TV_PAL) && (target.flags & TV_VIDEO)) 1380 status = PAL720; 1381 break; 1382 } 1383 1384 return status; 1385 }//end BT_check_tvmode. 1386 1387 1388 /* 1389 //BeTVOut's SwitchRIVAtoTV(vtot) timing formula: (note: vtot = (v_total - 2)) 1390 //----------------------------------------------------------------------------------- 1391 //HORIZONTAL: 1392 //----------- 1393 h_sync_start = h_display; 1394 1395 //fixme, note, checkout: 1396 //feels like in fact TNT2-M64 nv_crtc.c registerprogramming should be adapted... 1397 if (TNT2-M64) 1398 { 1399 h_sync_end = h_display + 8; 1400 h_total = h_display + 56; 1401 } 1402 else //TNT1, TNT2, Geforce2... (so default) 1403 { 1404 h_sync_end = h_display + 16; 1405 h_total = h_display + 48; 1406 } 1407 1408 //fixme, note, checkout: 1409 //BeTVOut uses two 'tweaks': 1410 // - on TNT2-M64 only: 1411 // register h_blank_e is increased with 1 (so should be done in nv_crtc.c here) 1412 // - 'all cards': 1413 // register h_blank_e b6 = 0 (only influences TNT2-M64 in modes NTSC800 and PAL800). 1414 //----------------------------------------------------------------------------------- 1415 //VERTICAL: 1416 //--------- 1417 v_sync_start = v_display; 1418 v_total = vtot + 2; 1419 v_sync_end = v_total - 1; //(This takes care of the 'cursor trash' on TNT1's...) 1420 //----------------------------------------------------------------------------------- 1421 */ 1422 static status_t BT_update_mode_for_gpu(display_mode *target, uint8 tvmode) 1423 { 1424 //fixme if needed: 1425 //pixelclock is not actually pgm'd because PLL is pgm' earlier during setmode... 1426 switch (tvmode) 1427 { 1428 case NTSC640: 1429 case NTSC640_TST: 1430 target->timing.h_display = 640; 1431 target->timing.h_sync_start = 640; 1432 if (si->ps.card_type == NV05M64) 1433 { 1434 target->timing.h_sync_end = 648; 1435 target->timing.h_total = 696; 1436 } 1437 else 1438 { 1439 //fixme if possible: 1440 //see if tweaking h_sync_end can shift picture 8 pixels right to fix 1441 //ws tv's tuning fault (always going for max. compatibility :) 1442 target->timing.h_sync_end = 656; 1443 target->timing.h_total = 688; 1444 } 1445 target->timing.v_display = 480; 1446 target->timing.v_sync_start = 480; 1447 target->timing.v_sync_end = 555; //This prevents 'cursor trash' on TNT1's 1448 target->timing.v_total = 556; //Above 525 because mode scales down 1449 if (si->ps.card_type == NV05M64) 1450 target->timing.pixel_clock = ((696 * 556 * 60) / 1000); 1451 else 1452 target->timing.pixel_clock = ((688 * 556 * 60) / 1000); 1453 break; 1454 case NTSC800: 1455 target->timing.h_display = 800; 1456 target->timing.h_sync_start = 800; 1457 if (si->ps.card_type == NV05M64) 1458 { 1459 target->timing.h_sync_end = 808; 1460 target->timing.h_total = 856; 1461 } 1462 else 1463 { 1464 target->timing.h_sync_end = 816; 1465 target->timing.h_total = 848; 1466 } 1467 target->timing.v_display = 600; 1468 target->timing.v_sync_start = 600; 1469 target->timing.v_sync_end = 685; //This prevents 'cursor trash' on TNT1's 1470 target->timing.v_total = 686; //Above 525 because mode scales down 1471 if (si->ps.card_type == NV05M64) 1472 target->timing.pixel_clock = ((856 * 686 * 60) / 1000); 1473 else 1474 target->timing.pixel_clock = ((848 * 686 * 60) / 1000); 1475 break; 1476 case PAL640: 1477 target->timing.h_display = 640; 1478 target->timing.h_sync_start = 640; 1479 if (si->ps.card_type == NV05M64) 1480 { 1481 target->timing.h_sync_end = 648; 1482 target->timing.h_total = 696; 1483 } 1484 else 1485 { 1486 target->timing.h_sync_end = 656; 1487 target->timing.h_total = 688; 1488 } 1489 target->timing.v_display = 480; 1490 target->timing.v_sync_start = 480; 1491 target->timing.v_sync_end = 570; //This prevents 'cursor trash' on TNT1's 1492 target->timing.v_total = 571; //Below 625 because mode scales up 1493 if (si->ps.card_type == NV05M64) 1494 target->timing.pixel_clock = ((696 * 571 * 50) / 1000); 1495 else 1496 target->timing.pixel_clock = ((688 * 571 * 50) / 1000); 1497 break; 1498 case PAL800: 1499 case PAL800_TST: 1500 target->timing.h_display = 800; 1501 target->timing.h_sync_start = 800; 1502 if (si->ps.card_type == NV05M64) 1503 { 1504 target->timing.h_sync_end = 808; 1505 target->timing.h_total = 856; 1506 } 1507 else 1508 { 1509 target->timing.h_sync_end = 816; 1510 target->timing.h_total = 848; 1511 } 1512 target->timing.v_display = 600; 1513 target->timing.v_sync_start = 600; 1514 target->timing.v_sync_end = 695; //This prevents 'cursor trash' on TNT1's 1515 target->timing.v_total = 696; //Above 625 because mode scales down 1516 if (si->ps.card_type == NV05M64) 1517 target->timing.pixel_clock = ((856 * 696 * 50) / 1000); 1518 else 1519 target->timing.pixel_clock = ((848 * 696 * 50) / 1000); 1520 break; 1521 case NTSC640_OS: 1522 target->timing.h_display = 640; //BT H_ACTIVE 1523 target->timing.h_sync_start = 744; //set for CH/BT compatible TV output 1524 target->timing.h_sync_end = 744+20; //delta is BT H_BLANKI 1525 target->timing.h_total = 784; //BT H_CLKI 1526 target->timing.v_display = 480; //BT V_ACTIVEI 1527 target->timing.v_sync_start = 490; //set for centered sync pulse 1528 target->timing.v_sync_end = 490+25; //delta is BT V_BLANKI 1529 target->timing.v_total = 525; //BT V_LINESI (== 525: 1:1 scaled mode) 1530 target->timing.pixel_clock = ((784 * 525 * 60) / 1000); //refresh 1531 break; 1532 case PAL800_OS: 1533 target->timing.h_display = 768; //H_ACTIVE 1534 if (si->ps.tv_encoder.type <= BT869) 1535 { 1536 /* confirmed on TNT1 using 4:3 TV and 16:9 TV */ 1537 target->timing.h_sync_start = 856; //set for centered TV output 1538 target->timing.h_sync_end = 856+20; //delta is BT H_BLANKI 1539 } 1540 else 1541 { 1542 /* confirmed on NV11 using 4:3 TV and 16:9 TV */ 1543 target->timing.h_sync_start = 848; //set for centered TV output 1544 target->timing.h_sync_end = 848+20; //delta is BT H_BLANKI 1545 } 1546 target->timing.h_total = 944; //BT H_CLKI 1547 target->timing.v_display = 576; //V_ACTIVEI 1548 target->timing.v_sync_start = 579; //set for centered sync pulse 1549 target->timing.v_sync_end = 579+42; //delta is BT V_BLANKI 1550 target->timing.v_total = 625; //BT V_LINESI (== 625: 1:1 scaled mode) 1551 target->timing.pixel_clock = ((944 * 625 * 50) / 1000); //refresh 1552 break; 1553 case NTSC720: 1554 /* (tested on TNT2 with BT869) */ 1555 target->timing.h_display = 720; //H_ACTIVE 1556 if (si->ps.tv_encoder.type <= BT869) 1557 { 1558 /* confirmed on TNT1 using 4:3 TV and 16:9 TV */ 1559 target->timing.h_sync_start = 744; //do not change! 1560 target->timing.h_sync_end = 744+144; //delta is H_sync_pulse 1561 } 1562 else 1563 { 1564 /* confirmed on NV11 using 4:3 TV and 16:9 TV */ 1565 target->timing.h_sync_start = 728; //do not change! 1566 target->timing.h_sync_end = 728+160; //delta is H_sync_pulse 1567 } 1568 target->timing.h_total = 888; //BT H_TOTAL 1569 target->timing.v_display = 480; //V_ACTIVEI 1570 target->timing.v_sync_start = 490; //set for centered sync pulse 1571 target->timing.v_sync_end = 490+26; //delta is V_sync_pulse 1572 target->timing.v_total = 525; //CH V_TOTAL (== 525: 1:1 scaled mode) 1573 target->timing.pixel_clock = ((888 * 525 * 60) / 1000); //refresh 1574 break; 1575 case PAL720: 1576 target->timing.h_display = 720; //BT H_ACTIVE 1577 target->timing.h_sync_start = 744; //set for centered sync pulse 1578 target->timing.h_sync_end = 744+140; //delta is BT H_BLANKI 1579 target->timing.h_total = 888; //BT H_CLKI 1580 target->timing.v_display = 576; //BT V_ACTIVEI 1581 target->timing.v_sync_start = 579; //set for centered sync pulse 1582 target->timing.v_sync_end = 579+42; //delta is BT V_BLANKI 1583 target->timing.v_total = 625; //BT V_LINESI (== 625: 1:1 scaled mode) 1584 target->timing.pixel_clock = ((888 * 625 * 50) / 1000); //refresh 1585 break; 1586 default: 1587 return B_ERROR; 1588 } 1589 1590 return B_OK; 1591 }//end BT_update_mode_for_gpu. 1592 1593 /* note: 1594 * tested on ELSA Erazor III 32Mb AGP (TNT2/BT869), 1595 * Diamond Viper V550 16Mb PCI (TNT1/BT869), 1596 * and ASUS V7100 GeForce2 MX200 AGP/32Mb (CH7007). */ 1597 static status_t BT_start_tvout(void) 1598 { 1599 /* enable access to primary head */ 1600 set_crtc_owner(0); 1601 1602 /* CAUTION: 1603 * On old cards, PLLSEL (and TV_SETUP?) cannot be read (sometimes?), but 1604 * write actions do succeed ... 1605 * This is confirmed for both ISA and PCI access, on NV04 and NV11. */ 1606 1607 /* setup TVencoder connection */ 1608 /* b1-0 = %01: encoder type is MASTER; 1609 * b24 = 1: VIP datapos is b0-7 */ 1610 //fixme if needed: setup completely instead of relying on pre-init by BIOS.. 1611 //(it seems to work OK on NV04 and NV11 although read reg. doesn't seem to work) 1612 DACW(TV_SETUP, ((DACR(TV_SETUP) & ~0x00000002) | 0x01000001)); 1613 1614 /* tell GPU to use pixelclock from TVencoder instead of using internal source */ 1615 /* (nessecary or display will 'shiver' on both TV and VGA.) */ 1616 if (si->ps.secondary_head) 1617 //fixme: assuming TVout is on primary head!! 1618 DACW(PLLSEL, 0x20030f00); 1619 else 1620 DACW(PLLSEL, 0x00030700); 1621 1622 /* Set overscan color to 'black' */ 1623 /* note: 1624 * Change this instruction for a visible overscan color if you're trying to 1625 * center the output on TV. Use it as a guide-'line' then ;-) */ 1626 ATBW(OSCANCOLOR, 0x00); 1627 1628 /* set CRTC to slaved mode (b7 = 1) and clear TVadjust (b3-5 = %000) */ 1629 CRTCW(PIXEL, ((CRTCR(PIXEL) & 0xc7) | 0x80)); 1630 /* select TV encoder, not panel encoder (b0 = 0). 1631 * Note: 1632 * Both are devices (often) using the CRTC in slaved mode. */ 1633 CRTCW(LCD, (CRTCR(LCD) & 0xfe)); 1634 1635 /* HTOTAL, VTOTAL and OVERFLOW return their default CRTC use, instead of 1636 * H, V-low and V-high 'shadow' counters(?)(b0, 4 and 6 = 0) (b7 use = unknown) */ 1637 CRTCW(TREG, 0x80); 1638 1639 return B_OK; 1640 }//end BT_start_tvout. 1641 1642 /* note: 1643 * tested on ELSA Erazor III 32Mb AGP (TNT2/BT869), 1644 * Diamond Viper V550 16Mb PCI (TNT1/BT869), 1645 * and ASUS V7100 GeForce2 MX200 AGP/32Mb (CH7007). */ 1646 status_t BT_stop_tvout(void) 1647 { 1648 /* prevent BT from being overclocked by VGA-only modes & black-out TV-out */ 1649 BT_killclk_blackout(); 1650 1651 /* enable access to primary head */ 1652 set_crtc_owner(0); 1653 1654 /* switch on VGA monitor HSYNC and VSYNC */ 1655 //fixme: is this needed? 1656 CRTCW(REPAINT1, (CRTCR(REPAINT1) & 0x3f)); 1657 1658 1659 /* wait for one image to be generated to make sure VGA has kicked in and is 1660 * running OK before continuing... 1661 * (Kicking in will fail often if we do not wait here) */ 1662 1663 /* make sure we are 'in' active VGA picture */ 1664 while (NV_REG8(NV8_INSTAT1) & 0x08) snooze(1); 1665 /* wait for next vertical retrace start on VGA */ 1666 while (!(NV_REG8(NV8_INSTAT1) & 0x08)) snooze(1); 1667 /* now wait until we are 'in' active VGA picture again */ 1668 while (NV_REG8(NV8_INSTAT1) & 0x08) snooze(1); 1669 1670 1671 /* set CRTC to master mode (b7 = 0) if it wasn't slaved for a panel before */ 1672 if (!(si->ps.slaved_tmds1)) CRTCW(PIXEL, (CRTCR(PIXEL) & 0x03)); 1673 1674 /* CAUTION: 1675 * On old cards, PLLSEL (and TV_SETUP?) cannot be read (sometimes?), but 1676 * write actions do succeed ... 1677 * This is confirmed for both ISA and PCI access, on NV04 and NV11. */ 1678 1679 /* setup TVencoder connection */ 1680 /* b1-0 = %00: encoder type is SLAVE; 1681 * b24 = 1: VIP datapos is b0-7 */ 1682 //fixme if needed: setup completely instead of relying on pre-init by BIOS.. 1683 //(it seems to work OK on NV04 and NV11 although read reg. doesn't seem to work) 1684 DACW(TV_SETUP, ((DACR(TV_SETUP) & ~0x00000003) | 0x01000000)); 1685 1686 /* tell GPU to use pixelclock from internal source instead of using TVencoder */ 1687 if (si->ps.secondary_head) 1688 DACW(PLLSEL, 0x30000f00); 1689 else 1690 DACW(PLLSEL, 0x10000700); 1691 1692 /* HTOTAL, VTOTAL and OVERFLOW return their default CRTC use, instead of 1693 * H, V-low and V-high 'shadow' counters(?)(b0, 4 and 6 = 0) (b7 use = unknown) */ 1694 CRTCW(TREG, 0x00); 1695 1696 /* select panel encoder, not TV encoder if needed (b0 = 1). 1697 * Note: 1698 * Both are devices (often) using the CRTC in slaved mode. */ 1699 if (si->ps.slaved_tmds1) CRTCW(LCD, (CRTCR(LCD) | 0x01)); 1700 1701 /* fixme if needed: 1702 * a full encoder chip reset could be done here (so after decoupling crtc)... */ 1703 /* (but: beware of the 'locked SDA' syndrome then!) */ 1704 1705 return B_OK; 1706 }//end BT_stop_tvout. 1707 1708 status_t BT_setmode(display_mode target) 1709 { 1710 uint8 tvmode, monstat; 1711 /* enable flickerfilter in desktop modes, disable it in video modes. */ 1712 uint8 ffilter = 0; 1713 1714 /* use a display_mode copy because we might tune it for TVout compatibility */ 1715 display_mode tv_target = target; 1716 1717 /* preset new TVout mode */ 1718 tvmode = BT_check_tvmode(tv_target); 1719 if (!tvmode) return B_ERROR; 1720 1721 /* read current output devices connection status */ 1722 BT_read_monstat(&monstat); 1723 1724 /* (pre)set TV mode */ 1725 /* note: 1726 * Manual config is non-dependent of the state of the PAL hardware input pin; 1727 * Also SDA lockups occur when setting EN_XCLK after autoconfig! 1728 * Make sure PAL_MD=0 for NTSC and PAL_MD = 1 for PAL... */ 1729 switch (tvmode) 1730 { 1731 case NTSC640: 1732 case NTSC640_TST: 1733 ffilter = 1; 1734 BT_init_NTSC640(); 1735 break; 1736 case NTSC800: 1737 ffilter = 1; 1738 BT_init_NTSC800(); 1739 break; 1740 case PAL640: 1741 ffilter = 1; 1742 BT_init_PAL640(); 1743 break; 1744 case PAL800: 1745 case PAL800_TST: 1746 ffilter = 1; 1747 BT_init_PAL800(); 1748 break; 1749 case NTSC640_OS: 1750 BT_init_NTSC640_OS(); 1751 break; 1752 case PAL800_OS: 1753 BT_init_PAL800_OS(); 1754 break; 1755 case NTSC720: 1756 BT_init_NTSC720(); 1757 break; 1758 case PAL720: 1759 BT_init_PAL720(); 1760 break; 1761 } 1762 1763 /* modify BT Hphase signal to center TV image... */ 1764 BT_setup_hphase(tvmode); 1765 1766 /* disable Macro mode */ 1767 switch (tvmode) 1768 { 1769 case NTSC640: 1770 case NTSC640_TST: 1771 case NTSC800: 1772 case NTSC640_OS: 1773 case NTSC720: 1774 /* NTSC */ 1775 BT_set_macro (0, 0); 1776 break; 1777 default: 1778 /* PAL */ 1779 BT_set_macro (1, 0); 1780 break; 1781 } 1782 1783 /* setup output signal routing and flickerfilter */ 1784 BT_setup_output(monstat, (uint8)(si->settings.tv_output), ffilter); 1785 1786 /* update the GPU CRTC timing for the requested mode */ 1787 BT_update_mode_for_gpu(&tv_target, tvmode); 1788 1789 /* setup GPU CRTC timing */ 1790 head1_set_timing(tv_target); 1791 1792 //fixme: only testing older cards for now... 1793 if (si->ps.secondary_head && (si->ps.card_type > NV15)) 1794 { 1795 BT_testsignal(); 1796 return B_OK; 1797 } 1798 1799 /* now set GPU CRTC to slave mode */ 1800 BT_start_tvout(); 1801 1802 //fixme: add code to disable VGA screen when TVout enabled 1803 //(use via nv.setting preset) 1804 1805 return B_OK; 1806 } 1807