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