112566cbdSRudolf Cornelissen /*
212566cbdSRudolf Cornelissen Author:
3a658603aSRudolf Cornelissen Rudolf Cornelissen 4/2002-11/2005
4fb6cadf1Sshatty */
5fb6cadf1Sshatty
6fb6cadf1Sshatty #define MODULE_BIT 0x00100000
7fb6cadf1Sshatty
8fb6cadf1Sshatty #include "nv_std.h"
9fb6cadf1Sshatty
1012566cbdSRudolf Cornelissen #define PRADR 0x88
1112566cbdSRudolf Cornelissen #define SCADR 0x8a
1212566cbdSRudolf Cornelissen #define WR 0x00
1312566cbdSRudolf Cornelissen #define RD 0x01
1412566cbdSRudolf Cornelissen
1521f6ecabSRudolf Cornelissen enum
1621f6ecabSRudolf Cornelissen { // TVoutput mode to set
17b2459715SRudolf Cornelissen NOT_SUPPORTED = 0,
1821f6ecabSRudolf Cornelissen NTSC640_TST,
1921f6ecabSRudolf Cornelissen NTSC640,
2021f6ecabSRudolf Cornelissen NTSC800,
2121f6ecabSRudolf Cornelissen PAL800_TST,
2221f6ecabSRudolf Cornelissen PAL640,
2321f6ecabSRudolf Cornelissen PAL800,
2421f6ecabSRudolf Cornelissen NTSC720,
2521f6ecabSRudolf Cornelissen PAL720,
2621f6ecabSRudolf Cornelissen NTSC640_OS,
2721f6ecabSRudolf Cornelissen PAL800_OS
2821f6ecabSRudolf Cornelissen };
2921f6ecabSRudolf Cornelissen
30b0fce481SRudolf Cornelissen /* Dirk Thierbach's Macro setup for registers 0xda-0xfe.
31b0fce481SRudolf Cornelissen * (also see http://sourceforge.net/projects/nv-tv-out/) */
329a7218c5SRudolf Cornelissen static uint8 BtNtscMacro0 [] = {
339a7218c5SRudolf Cornelissen 0x0f,0xfc,0x20,0xd0,0x6f,0x0f,0x00,0x00,0x0c,0xf3,0x09,
349a7218c5SRudolf Cornelissen 0xbd,0x67,0xb5,0x90,0xb2,0x7d,0x00,0x00};
359a7218c5SRudolf Cornelissen static uint8 BtNtscMacro1 [] = {
369a7218c5SRudolf Cornelissen 0x0f,0xfc,0x20,0xd0,0x6f,0x0f,0x00,0x00,0x0c,0xf3,0x09,
379a7218c5SRudolf Cornelissen 0xbd,0x67,0xb5,0x90,0xb2,0x7d,0x63,0x00};
389a7218c5SRudolf Cornelissen static uint8 BtNtscMacro2 [] = {
399a7218c5SRudolf Cornelissen 0x0f,0xfc,0x20,0xd0,0x6f,0x0f,0x00,0x00,0x0c,0xf3,0x09,
409a7218c5SRudolf Cornelissen 0xbd,0x6c,0x31,0x92,0x32,0xdd,0xe3,0x00};
419a7218c5SRudolf Cornelissen static uint8 BtNtscMacro3 [] = {
429a7218c5SRudolf Cornelissen 0x0f,0xfc,0x20,0xd0,0x6f,0x0f,0x00,0x00,0x0c,0xf3,0x09,
439a7218c5SRudolf Cornelissen 0xbd,0x66,0xb5,0x90,0xb2,0x7d,0xe3,0x00};
449a7218c5SRudolf Cornelissen
459a7218c5SRudolf Cornelissen static uint8 BtPalMacro0 [] = {
469a7218c5SRudolf Cornelissen 0x05,0x57,0x20,0x40,0x6e,0x7e,0xf4,0x51,0x0f,0xf1,0x05,
479a7218c5SRudolf Cornelissen 0xd3,0x78,0xa2,0x25,0x54,0xa5,0x00,0x00};
489a7218c5SRudolf Cornelissen static uint8 BtPalMacro1 [] = {
499a7218c5SRudolf Cornelissen 0x05,0x57,0x20,0x40,0x6e,0x7e,0xf4,0x51,0x0f,0xf1,0x05,
509a7218c5SRudolf Cornelissen 0xd3,0x78,0xa2,0x25,0x54,0xa5,0x63,0x00};
519a7218c5SRudolf Cornelissen
BT_set_macro(int std,int mode)529a7218c5SRudolf Cornelissen static uint8 BT_set_macro (int std, int mode)
539a7218c5SRudolf Cornelissen {
549a7218c5SRudolf Cornelissen uint8 stat;
559a7218c5SRudolf Cornelissen uint8 buffer[21];
569a7218c5SRudolf Cornelissen
57b0fce481SRudolf Cornelissen LOG(4,("Brooktree: Setting Macro:\n"));
589a7218c5SRudolf Cornelissen
599a7218c5SRudolf Cornelissen if ((std < 0) | (std > 1) | (mode < 0) | (mode > 3))
609a7218c5SRudolf Cornelissen {
619a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Non existing mode or standard selected, aborting.\n"));
629a7218c5SRudolf Cornelissen return 0x80;
639a7218c5SRudolf Cornelissen }
649a7218c5SRudolf Cornelissen
659a7218c5SRudolf Cornelissen switch (std)
669a7218c5SRudolf Cornelissen {
679a7218c5SRudolf Cornelissen case 0:
689a7218c5SRudolf Cornelissen /* NTSC */
699a7218c5SRudolf Cornelissen switch (mode)
709a7218c5SRudolf Cornelissen {
719a7218c5SRudolf Cornelissen case 0:
729a7218c5SRudolf Cornelissen /* disabled */
73b0fce481SRudolf Cornelissen LOG(4,("Brooktree: NTSC, disabled\n"));
749a7218c5SRudolf Cornelissen memcpy(&buffer[2], &BtNtscMacro0, 19);
759a7218c5SRudolf Cornelissen break;
769a7218c5SRudolf Cornelissen case 1:
779a7218c5SRudolf Cornelissen /* enabled mode 1 */
78b0fce481SRudolf Cornelissen LOG(4,("Brooktree: NTSC, mode 1\n"));
799a7218c5SRudolf Cornelissen memcpy(&buffer[2], &BtNtscMacro1, 19);
809a7218c5SRudolf Cornelissen break;
819a7218c5SRudolf Cornelissen case 2:
829a7218c5SRudolf Cornelissen /* enabled mode 2 */
83b0fce481SRudolf Cornelissen LOG(4,("Brooktree: NTSC, mode 2\n"));
849a7218c5SRudolf Cornelissen memcpy(&buffer[2], &BtNtscMacro2, 19);
859a7218c5SRudolf Cornelissen break;
869a7218c5SRudolf Cornelissen case 3:
879a7218c5SRudolf Cornelissen /* enabled mode 3 */
88b0fce481SRudolf Cornelissen LOG(4,("Brooktree: NTSC, mode 3\n"));
899a7218c5SRudolf Cornelissen memcpy(&buffer[2], &BtNtscMacro3, 19);
909a7218c5SRudolf Cornelissen break;
919a7218c5SRudolf Cornelissen }
929a7218c5SRudolf Cornelissen break;
939a7218c5SRudolf Cornelissen case 1:
949a7218c5SRudolf Cornelissen /* PAL */
959a7218c5SRudolf Cornelissen switch (mode)
969a7218c5SRudolf Cornelissen {
979a7218c5SRudolf Cornelissen case 0:
989a7218c5SRudolf Cornelissen /* disabled */
99b0fce481SRudolf Cornelissen LOG(4,("Brooktree: PAL, disabled\n"));
1009a7218c5SRudolf Cornelissen memcpy(&buffer[2], &BtPalMacro0, 19);
1019a7218c5SRudolf Cornelissen break;
1029a7218c5SRudolf Cornelissen case 1:
1039a7218c5SRudolf Cornelissen case 2:
1049a7218c5SRudolf Cornelissen case 3:
1059a7218c5SRudolf Cornelissen /* enabled */
106b0fce481SRudolf Cornelissen LOG(4,("Brooktree: PAL, enabled\n"));
1079a7218c5SRudolf Cornelissen memcpy(&buffer[2], &BtPalMacro1, 19);
1089a7218c5SRudolf Cornelissen break;
1099a7218c5SRudolf Cornelissen }
1109a7218c5SRudolf Cornelissen break;
1119a7218c5SRudolf Cornelissen }
1129a7218c5SRudolf Cornelissen
1139a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR;
1149a7218c5SRudolf Cornelissen /* select first register to write to */
1159a7218c5SRudolf Cornelissen buffer[1] = 0xda;
1169a7218c5SRudolf Cornelissen
1179a7218c5SRudolf Cornelissen /* reset status */
1189a7218c5SRudolf Cornelissen i2c_flag_error (-1);
1199a7218c5SRudolf Cornelissen
1209a7218c5SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
1219a7218c5SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
1229a7218c5SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
1239a7218c5SRudolf Cornelissen /* log on errors */
1249a7218c5SRudolf Cornelissen stat = i2c_flag_error(0);
1259a7218c5SRudolf Cornelissen if (stat)
1269a7218c5SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting Macro\n"));
1279a7218c5SRudolf Cornelissen
1289a7218c5SRudolf Cornelissen return stat;
1299a7218c5SRudolf Cornelissen }//end BT_set_macro.
1309a7218c5SRudolf Cornelissen
13112566cbdSRudolf Cornelissen /*
13212566cbdSRudolf Cornelissen see if a (possible) BT/CX chip resides at the given adress.
13312566cbdSRudolf Cornelissen Return zero if no errors occurred.
13412566cbdSRudolf Cornelissen */
BT_check(uint8 bus,uint8 adress)13512566cbdSRudolf Cornelissen static uint8 BT_check (uint8 bus, uint8 adress)
13612566cbdSRudolf Cornelissen {
1370ece4905SRudolf Cornelissen uint8 buffer[3];
13812566cbdSRudolf Cornelissen
1390ece4905SRudolf Cornelissen buffer[0] = adress + WR;
14012566cbdSRudolf Cornelissen /* set ESTATUS at b'00'; and enable bt chip-outputs
14112566cbdSRudolf Cornelissen * WARNING:
14212566cbdSRudolf Cornelissen * If bit0 = 0 is issued below (EN_OUT = disabled), the BT will lock SDA
14312566cbdSRudolf Cornelissen * after writing adress $A0 (setting EN_XCLK)!!!
1449a7218c5SRudolf Cornelissen * Until a reboot the corresponding I2C bus will be inacessable then!!! */
1450ece4905SRudolf Cornelissen buffer[1] = 0xc4;
14612566cbdSRudolf Cornelissen /* fixme: if testimage 'was' active txbuffer[3] should become 0x05...
14712566cbdSRudolf Cornelissen * (currently this cannot be detected in a 'foolproof' way so don't touch...) */
14812566cbdSRudolf Cornelissen /* (ESTATUS b'0x' means: RX ID and VERSION info later..) */
1490ece4905SRudolf Cornelissen buffer[2] = 0x01;
1500ece4905SRudolf Cornelissen
1510ece4905SRudolf Cornelissen /* reset status */
1520ece4905SRudolf Cornelissen i2c_flag_error (-1);
1530ece4905SRudolf Cornelissen
1540ece4905SRudolf Cornelissen /* do check */
1550ece4905SRudolf Cornelissen i2c_bstart(bus);
1560ece4905SRudolf Cornelissen i2c_writebuffer(bus, buffer, sizeof(buffer));
15712566cbdSRudolf Cornelissen i2c_bstop(bus);
15812566cbdSRudolf Cornelissen return i2c_flag_error(0);
15912566cbdSRudolf Cornelissen }
16012566cbdSRudolf Cornelissen
16112566cbdSRudolf Cornelissen /* identify chiptype */
BT_read_type(void)16212566cbdSRudolf Cornelissen static uint8 BT_read_type (void)
16312566cbdSRudolf Cornelissen {
1640ece4905SRudolf Cornelissen uint8 id, type, stat;
1650ece4905SRudolf Cornelissen uint8 buffer[3];
1660ece4905SRudolf Cornelissen
1670ece4905SRudolf Cornelissen /* Make sure a CX (Conexant) chip (if this turns out to be there) is set to
1680ece4905SRudolf Cornelissen * BT-compatibility mode! (This command will do nothing on a BT chip...) */
1690ece4905SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR;
1700ece4905SRudolf Cornelissen /* select CX reg. for BT-compatible readback, video still off */
1710ece4905SRudolf Cornelissen buffer[1] = 0x6c;
1720ece4905SRudolf Cornelissen /* set it up */
1730ece4905SRudolf Cornelissen buffer[2] = 0x02;
17412566cbdSRudolf Cornelissen
17512566cbdSRudolf Cornelissen /* reset status */
17612566cbdSRudolf Cornelissen i2c_flag_error (-1);
17712566cbdSRudolf Cornelissen
17812566cbdSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
1790ece4905SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
18012566cbdSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
18112566cbdSRudolf Cornelissen /* abort on errors */
18212566cbdSRudolf Cornelissen stat = i2c_flag_error(0);
18312566cbdSRudolf Cornelissen if (stat) return stat;
18412566cbdSRudolf Cornelissen
18512566cbdSRudolf Cornelissen /* Do actual readtype command */
18612566cbdSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
1879a7218c5SRudolf Cornelissen /* issue I2C read command */
18812566cbdSRudolf Cornelissen i2c_writebyte(si->ps.tv_encoder.bus, si->ps.tv_encoder.adress + RD);
18912566cbdSRudolf Cornelissen /* receive 1 byte;
1909a7218c5SRudolf Cornelissen * ACK level to TX after last byte to RX should be 1 (= NACK) (see I2C spec). */
19112566cbdSRudolf Cornelissen /* note:
19212566cbdSRudolf Cornelissen * While the BT's don't care, CX chips will block the SDA line if
19312566cbdSRudolf Cornelissen * an ACK gets sent! */
19412566cbdSRudolf Cornelissen id = i2c_readbyte(si->ps.tv_encoder.bus, true);
19512566cbdSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
19612566cbdSRudolf Cornelissen /* abort on errors */
19712566cbdSRudolf Cornelissen stat = i2c_flag_error(0);
19812566cbdSRudolf Cornelissen if (stat) return stat;
19912566cbdSRudolf Cornelissen
2000ece4905SRudolf Cornelissen /* check type to be supported one */
2010ece4905SRudolf Cornelissen type = (id & 0xe0) >> 5;
2020ece4905SRudolf Cornelissen if (type > 3)
2030ece4905SRudolf Cornelissen {
2040ece4905SRudolf Cornelissen LOG(4,("Brooktree: Found unsupported encoder type %d, aborting.\n", type));
2050ece4905SRudolf Cornelissen return 0x80;
2060ece4905SRudolf Cornelissen }
2070ece4905SRudolf Cornelissen
20812566cbdSRudolf Cornelissen /* inform driver about TV encoder found */
20912566cbdSRudolf Cornelissen si->ps.tvout = true;
2100ece4905SRudolf Cornelissen si->ps.tv_encoder.type = BT868 + type;
21112566cbdSRudolf Cornelissen si->ps.tv_encoder.version = id & 0x1f;
21212566cbdSRudolf Cornelissen
21312566cbdSRudolf Cornelissen return stat;
21412566cbdSRudolf Cornelissen }
21512566cbdSRudolf Cornelissen
BT_probe()21612566cbdSRudolf Cornelissen bool BT_probe()
21712566cbdSRudolf Cornelissen {
218260dcf8eSRudolf Cornelissen uint8 bus;
21912566cbdSRudolf Cornelissen bool btfound = false;
220260dcf8eSRudolf Cornelissen bool *i2c_bus = &(si->ps.i2c_bus0);
22112566cbdSRudolf Cornelissen
222260dcf8eSRudolf Cornelissen LOG(4,("Brooktree: Checking wired I2C bus(ses) for first possible TV encoder...\n"));
223260dcf8eSRudolf Cornelissen for (bus = 0; bus < 3; bus++)
22412566cbdSRudolf Cornelissen {
225260dcf8eSRudolf Cornelissen if (i2c_bus[bus] && !btfound)
226260dcf8eSRudolf Cornelissen {
227260dcf8eSRudolf Cornelissen /* try primary adress on bus */
228260dcf8eSRudolf Cornelissen if (!BT_check(bus, PRADR))
22912566cbdSRudolf Cornelissen {
23012566cbdSRudolf Cornelissen btfound = true;
23112566cbdSRudolf Cornelissen si->ps.tv_encoder.adress = PRADR;
232260dcf8eSRudolf Cornelissen si->ps.tv_encoder.bus = bus;
23312566cbdSRudolf Cornelissen }
23412566cbdSRudolf Cornelissen else
23512566cbdSRudolf Cornelissen {
236260dcf8eSRudolf Cornelissen /* try secondary adress on bus */
237260dcf8eSRudolf Cornelissen if (!BT_check(bus, SCADR))
23812566cbdSRudolf Cornelissen {
23912566cbdSRudolf Cornelissen btfound = true;
24012566cbdSRudolf Cornelissen si->ps.tv_encoder.adress = SCADR;
241260dcf8eSRudolf Cornelissen si->ps.tv_encoder.bus = bus;
24212566cbdSRudolf Cornelissen }
24312566cbdSRudolf Cornelissen }
24412566cbdSRudolf Cornelissen }
24512566cbdSRudolf Cornelissen }
24612566cbdSRudolf Cornelissen
24712566cbdSRudolf Cornelissen /* identify exact TV encoder type */
24812566cbdSRudolf Cornelissen if (btfound)
24912566cbdSRudolf Cornelissen {
25012566cbdSRudolf Cornelissen /* if errors are found, retry */
25112566cbdSRudolf Cornelissen /* note:
25212566cbdSRudolf Cornelissen * NACK: occurs on some ASUS V7700 GeForce cards!
25312566cbdSRudolf Cornelissen * (apparantly the video-in chip or another chip resides at 'BT' adresses
25412566cbdSRudolf Cornelissen * there..) */
25512566cbdSRudolf Cornelissen uint8 stat;
25612566cbdSRudolf Cornelissen uint8 cnt = 0;
25712566cbdSRudolf Cornelissen while ((stat = BT_read_type()) && (cnt < 3))
25812566cbdSRudolf Cornelissen {
2590ece4905SRudolf Cornelissen /* don't retry on unsupported chiptype */
2600ece4905SRudolf Cornelissen if (stat == 0x80)
2610ece4905SRudolf Cornelissen {
2620ece4905SRudolf Cornelissen btfound = 0;
2630ece4905SRudolf Cornelissen break;
2640ece4905SRudolf Cornelissen }
26512566cbdSRudolf Cornelissen cnt++;
26612566cbdSRudolf Cornelissen }
2670ece4905SRudolf Cornelissen if (stat & 0x7f)
26812566cbdSRudolf Cornelissen {
2699a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Too much errors occurred, aborting.\n"));
27012566cbdSRudolf Cornelissen btfound = 0;
27112566cbdSRudolf Cornelissen }
27212566cbdSRudolf Cornelissen }
27312566cbdSRudolf Cornelissen
27412566cbdSRudolf Cornelissen if (btfound)
27512566cbdSRudolf Cornelissen LOG(4,("Brooktree: Found TV encoder on bus %d, adress $%02x\n",
27612566cbdSRudolf Cornelissen si->ps.tv_encoder.bus, si->ps.tv_encoder.adress));
27712566cbdSRudolf Cornelissen else
27812566cbdSRudolf Cornelissen LOG(4,("Brooktree: No TV encoder Found\n"));
27912566cbdSRudolf Cornelissen
28012566cbdSRudolf Cornelissen return btfound;
28112566cbdSRudolf Cornelissen }
28212566cbdSRudolf Cornelissen
BT_init_PAL640()28377497c49SRudolf Cornelissen static uint8 BT_init_PAL640()
284fb6cadf1Sshatty {
28577497c49SRudolf Cornelissen uint8 stat;
286fb6cadf1Sshatty
28777497c49SRudolf Cornelissen uint8 buffer[35];
288fb6cadf1Sshatty
2899a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting PAL 640x480 desktop mode\n"));
2909a7218c5SRudolf Cornelissen
2919a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command
29277497c49SRudolf Cornelissen buffer[1] = 0x76; //select first bt register to write to
29377497c49SRudolf Cornelissen buffer[2] = 0x60;
29477497c49SRudolf Cornelissen buffer[3] = 0x80;
29577497c49SRudolf Cornelissen buffer[4] = 0x8a;
29677497c49SRudolf Cornelissen buffer[5] = 0xa6;
29777497c49SRudolf Cornelissen buffer[6] = 0x68;
29877497c49SRudolf Cornelissen buffer[7] = 0xc1;
29977497c49SRudolf Cornelissen buffer[8] = 0x2e;
30077497c49SRudolf Cornelissen buffer[9] = 0xf2;
30177497c49SRudolf Cornelissen buffer[10] = 0x27;
30277497c49SRudolf Cornelissen buffer[11] = 0x00;
30377497c49SRudolf Cornelissen buffer[12] = 0xb0;
30477497c49SRudolf Cornelissen buffer[13] = 0x0a;
30577497c49SRudolf Cornelissen buffer[14] = 0x0b;
30677497c49SRudolf Cornelissen buffer[15] = 0x71;
30777497c49SRudolf Cornelissen buffer[16] = 0x5a;
30877497c49SRudolf Cornelissen buffer[17] = 0xe0;
30977497c49SRudolf Cornelissen buffer[18] = 0x36;
31077497c49SRudolf Cornelissen buffer[19] = 0x00;
31177497c49SRudolf Cornelissen buffer[20] = 0x50;
31277497c49SRudolf Cornelissen buffer[21] = 0x72;
31377497c49SRudolf Cornelissen buffer[22] = 0x1c;
31477497c49SRudolf Cornelissen buffer[23] = 0x8d; //chip-pin CLKI is pixel clock (only non-default here!)
31577497c49SRudolf Cornelissen buffer[24] = 0x24;
31677497c49SRudolf Cornelissen buffer[25] = 0xf0;
31777497c49SRudolf Cornelissen buffer[26] = 0x58;
31877497c49SRudolf Cornelissen buffer[27] = 0x81;
31977497c49SRudolf Cornelissen buffer[28] = 0x49;
32077497c49SRudolf Cornelissen buffer[29] = 0x8c;
32177497c49SRudolf Cornelissen buffer[30] = 0x0c;
32277497c49SRudolf Cornelissen buffer[31] = 0x8c;
32377497c49SRudolf Cornelissen buffer[32] = 0x79;
32477497c49SRudolf Cornelissen buffer[33] = 0x26;
32577497c49SRudolf Cornelissen buffer[34] = 0x00;
32677497c49SRudolf Cornelissen
32777497c49SRudolf Cornelissen /* reset status */
32877497c49SRudolf Cornelissen i2c_flag_error (-1);
32977497c49SRudolf Cornelissen
33077497c49SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
33177497c49SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
33277497c49SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
33377497c49SRudolf Cornelissen /* log on errors */
33477497c49SRudolf Cornelissen stat = i2c_flag_error(0);
33577497c49SRudolf Cornelissen if (stat)
33677497c49SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting mode PAL640\n"));
33777497c49SRudolf Cornelissen
33877497c49SRudolf Cornelissen return stat;
33977497c49SRudolf Cornelissen }//end BT_init_PAL640.
34077497c49SRudolf Cornelissen
BT_init_PAL800()34177497c49SRudolf Cornelissen static uint8 BT_init_PAL800()
342fb6cadf1Sshatty {
34377497c49SRudolf Cornelissen uint8 stat;
344fb6cadf1Sshatty
34577497c49SRudolf Cornelissen uint8 buffer[35];
346fb6cadf1Sshatty
3479a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting PAL 800x600 desktop mode\n"));
3489a7218c5SRudolf Cornelissen
3499a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command
35077497c49SRudolf Cornelissen buffer[1] = 0x76; //select first bt register to write to
35177497c49SRudolf Cornelissen buffer[2] = 0x00;
35277497c49SRudolf Cornelissen buffer[3] = 0x20;
35377497c49SRudolf Cornelissen buffer[4] = 0xaa;
35477497c49SRudolf Cornelissen buffer[5] = 0xca;
35577497c49SRudolf Cornelissen buffer[6] = 0x9a;
35677497c49SRudolf Cornelissen buffer[7] = 0x0d;
35777497c49SRudolf Cornelissen buffer[8] = 0x29;
35877497c49SRudolf Cornelissen buffer[9] = 0xfc;
35977497c49SRudolf Cornelissen buffer[10] = 0x39;
36077497c49SRudolf Cornelissen buffer[11] = 0x00;
36177497c49SRudolf Cornelissen buffer[12] = 0xc0;
36277497c49SRudolf Cornelissen buffer[13] = 0x8c;
36377497c49SRudolf Cornelissen buffer[14] = 0x03;
36477497c49SRudolf Cornelissen buffer[15] = 0xee;
36577497c49SRudolf Cornelissen buffer[16] = 0x5f;
36677497c49SRudolf Cornelissen buffer[17] = 0x58;
36777497c49SRudolf Cornelissen buffer[18] = 0x3a;
36877497c49SRudolf Cornelissen buffer[19] = 0x66;
36977497c49SRudolf Cornelissen buffer[20] = 0x96;
37077497c49SRudolf Cornelissen buffer[21] = 0x00;
37177497c49SRudolf Cornelissen buffer[22] = 0x00;
37277497c49SRudolf Cornelissen buffer[23] = 0x90; //chip-pin CLKI is pixel clock (only non-default here!)
37377497c49SRudolf Cornelissen buffer[24] = 0x24;
37477497c49SRudolf Cornelissen buffer[25] = 0xf0;
37577497c49SRudolf Cornelissen buffer[26] = 0x57;
37677497c49SRudolf Cornelissen buffer[27] = 0x80;
37777497c49SRudolf Cornelissen buffer[28] = 0x48;
37877497c49SRudolf Cornelissen buffer[29] = 0x8c;
37977497c49SRudolf Cornelissen buffer[30] = 0x18;
38077497c49SRudolf Cornelissen buffer[31] = 0x28;
38177497c49SRudolf Cornelissen buffer[32] = 0x87;
38277497c49SRudolf Cornelissen buffer[33] = 0x1f;
38377497c49SRudolf Cornelissen buffer[34] = 0x00;
38477497c49SRudolf Cornelissen
38577497c49SRudolf Cornelissen /* reset status */
38677497c49SRudolf Cornelissen i2c_flag_error (-1);
38777497c49SRudolf Cornelissen
38877497c49SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
38977497c49SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
39077497c49SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
39177497c49SRudolf Cornelissen /* log on errors */
39277497c49SRudolf Cornelissen stat = i2c_flag_error(0);
39377497c49SRudolf Cornelissen if (stat)
39477497c49SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800\n"));
39577497c49SRudolf Cornelissen
39677497c49SRudolf Cornelissen return stat;
39777497c49SRudolf Cornelissen }//end BT_init_PAL800.
39877497c49SRudolf Cornelissen
BT_init_NTSC640()39977497c49SRudolf Cornelissen static uint8 BT_init_NTSC640()
400fb6cadf1Sshatty {
40177497c49SRudolf Cornelissen uint8 stat;
402fb6cadf1Sshatty
40377497c49SRudolf Cornelissen uint8 buffer[35];
40477497c49SRudolf Cornelissen
4059a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting NTSC 640x480 desktop mode\n"));
4069a7218c5SRudolf Cornelissen
4079a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command
40877497c49SRudolf Cornelissen buffer[1] = 0x76; //select first bt register to write to
40977497c49SRudolf Cornelissen buffer[2] = 0x00;
41077497c49SRudolf Cornelissen buffer[3] = 0x80;
41177497c49SRudolf Cornelissen buffer[4] = 0x84;
41277497c49SRudolf Cornelissen buffer[5] = 0x96;
41377497c49SRudolf Cornelissen buffer[6] = 0x60;
41477497c49SRudolf Cornelissen buffer[7] = 0x7d;
41577497c49SRudolf Cornelissen buffer[8] = 0x22;
41677497c49SRudolf Cornelissen buffer[9] = 0xd4;
41777497c49SRudolf Cornelissen buffer[10] = 0x27;
41877497c49SRudolf Cornelissen buffer[11] = 0x00;
41977497c49SRudolf Cornelissen buffer[12] = 0x10;
42077497c49SRudolf Cornelissen buffer[13] = 0x7e;
42177497c49SRudolf Cornelissen buffer[14] = 0x03;
42277497c49SRudolf Cornelissen buffer[15] = 0x58;
42377497c49SRudolf Cornelissen buffer[16] = 0x4b;
42477497c49SRudolf Cornelissen buffer[17] = 0xe0;
42577497c49SRudolf Cornelissen buffer[18] = 0x36;
42677497c49SRudolf Cornelissen buffer[19] = 0x92;
42777497c49SRudolf Cornelissen buffer[20] = 0x54;
42877497c49SRudolf Cornelissen buffer[21] = 0x0e;
42977497c49SRudolf Cornelissen buffer[22] = 0x88;
43077497c49SRudolf Cornelissen buffer[23] = 0x8c; //chip-pin CLKI is pixel clock (only non-default here!)
43177497c49SRudolf Cornelissen buffer[24] = 0x0a;
43277497c49SRudolf Cornelissen buffer[25] = 0xe5;
43377497c49SRudolf Cornelissen buffer[26] = 0x76;
43477497c49SRudolf Cornelissen buffer[27] = 0x79;
43577497c49SRudolf Cornelissen buffer[28] = 0x44;
43677497c49SRudolf Cornelissen buffer[29] = 0x85;
43777497c49SRudolf Cornelissen buffer[30] = 0x00;
43877497c49SRudolf Cornelissen buffer[31] = 0x00;
43977497c49SRudolf Cornelissen buffer[32] = 0x80;
44077497c49SRudolf Cornelissen buffer[33] = 0x20;
44177497c49SRudolf Cornelissen buffer[34] = 0x00;
44277497c49SRudolf Cornelissen
44377497c49SRudolf Cornelissen /* reset status */
44477497c49SRudolf Cornelissen i2c_flag_error (-1);
44577497c49SRudolf Cornelissen
44677497c49SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
44777497c49SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
44877497c49SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
44977497c49SRudolf Cornelissen /* log on errors */
45077497c49SRudolf Cornelissen stat = i2c_flag_error(0);
45177497c49SRudolf Cornelissen if (stat)
45277497c49SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC640\n"));
45377497c49SRudolf Cornelissen
45477497c49SRudolf Cornelissen return stat;
45577497c49SRudolf Cornelissen }//end BT_init_NTSC640.
45677497c49SRudolf Cornelissen
BT_init_NTSC800()45777497c49SRudolf Cornelissen static uint8 BT_init_NTSC800()
458fb6cadf1Sshatty {
45977497c49SRudolf Cornelissen uint8 stat;
460fb6cadf1Sshatty
46177497c49SRudolf Cornelissen uint8 buffer[35];
462fb6cadf1Sshatty
4639a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting NTSC 800x600 desktop mode\n"));
4649a7218c5SRudolf Cornelissen
4659a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command
46677497c49SRudolf Cornelissen buffer[1] = 0x76; //select first bt register to write to
46777497c49SRudolf Cornelissen buffer[2] = 0xa0;
46877497c49SRudolf Cornelissen buffer[3] = 0x20;
46977497c49SRudolf Cornelissen buffer[4] = 0xb6;
47077497c49SRudolf Cornelissen buffer[5] = 0xce;
47177497c49SRudolf Cornelissen buffer[6] = 0x84;
47277497c49SRudolf Cornelissen buffer[7] = 0x55;
47377497c49SRudolf Cornelissen buffer[8] = 0x20;
47477497c49SRudolf Cornelissen buffer[9] = 0xd8;
47577497c49SRudolf Cornelissen buffer[10] = 0x39;
47677497c49SRudolf Cornelissen buffer[11] = 0x00;
47777497c49SRudolf Cornelissen buffer[12] = 0x70;
47877497c49SRudolf Cornelissen buffer[13] = 0x42;
47977497c49SRudolf Cornelissen buffer[14] = 0x03;
48077497c49SRudolf Cornelissen buffer[15] = 0xdf;
48177497c49SRudolf Cornelissen buffer[16] = 0x56;
48277497c49SRudolf Cornelissen buffer[17] = 0x58;
48377497c49SRudolf Cornelissen buffer[18] = 0x3a;
48477497c49SRudolf Cornelissen buffer[19] = 0xcd;
48577497c49SRudolf Cornelissen buffer[20] = 0x9c;
48677497c49SRudolf Cornelissen buffer[21] = 0x14;
48777497c49SRudolf Cornelissen buffer[22] = 0x3b;
48877497c49SRudolf Cornelissen buffer[23] = 0x91; //chip-pin CLKI is pixel clock (only non-default here!)
48977497c49SRudolf Cornelissen buffer[24] = 0x0a;
49077497c49SRudolf Cornelissen buffer[25] = 0xe5;
49177497c49SRudolf Cornelissen buffer[26] = 0x74;
49277497c49SRudolf Cornelissen buffer[27] = 0x77;
49377497c49SRudolf Cornelissen buffer[28] = 0x43;
49477497c49SRudolf Cornelissen buffer[29] = 0x85;
49577497c49SRudolf Cornelissen buffer[30] = 0xba;
49677497c49SRudolf Cornelissen buffer[31] = 0xe8;
49777497c49SRudolf Cornelissen buffer[32] = 0xa2;
49877497c49SRudolf Cornelissen buffer[33] = 0x17;
49977497c49SRudolf Cornelissen buffer[34] = 0x00;
50077497c49SRudolf Cornelissen
50177497c49SRudolf Cornelissen /* reset status */
50277497c49SRudolf Cornelissen i2c_flag_error (-1);
50377497c49SRudolf Cornelissen
50477497c49SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
50577497c49SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
50677497c49SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
50777497c49SRudolf Cornelissen /* log on errors */
50877497c49SRudolf Cornelissen stat = i2c_flag_error(0);
50977497c49SRudolf Cornelissen if (stat)
51077497c49SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800\n"));
51177497c49SRudolf Cornelissen
51277497c49SRudolf Cornelissen return stat;
51377497c49SRudolf Cornelissen }//end BT_init_NTSC800.
51477497c49SRudolf Cornelissen
BT_init_PAL720()51577497c49SRudolf Cornelissen static uint8 BT_init_PAL720()
516fb6cadf1Sshatty {
51777497c49SRudolf Cornelissen uint8 stat;
51877497c49SRudolf Cornelissen
51977497c49SRudolf Cornelissen uint8 buffer[35];
52077497c49SRudolf Cornelissen
5219a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting PAL 720x576 overscanning DVD mode\n"));
5229a7218c5SRudolf Cornelissen
5239a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command
52477497c49SRudolf Cornelissen buffer[1] = 0x76; //select first bt register to write to
52577497c49SRudolf Cornelissen buffer[2] = 0xf0;
52677497c49SRudolf Cornelissen buffer[3] = 0xd0;
52777497c49SRudolf Cornelissen buffer[4] = 0x82;
52877497c49SRudolf Cornelissen buffer[5] = 0x9c;
52977497c49SRudolf Cornelissen buffer[6] = 0x5a;
53077497c49SRudolf Cornelissen buffer[7] = 0x31;
53177497c49SRudolf Cornelissen buffer[8] = 0x16;
53277497c49SRudolf Cornelissen buffer[9] = 0x22;
53377497c49SRudolf Cornelissen buffer[10] = 0xa6;
53477497c49SRudolf Cornelissen buffer[11] = 0x00;
53577497c49SRudolf Cornelissen buffer[12] = 0x78;
53677497c49SRudolf Cornelissen buffer[13] = 0x93;
53777497c49SRudolf Cornelissen buffer[14] = 0x03;
53877497c49SRudolf Cornelissen buffer[15] = 0x71;
53977497c49SRudolf Cornelissen buffer[16] = 0x2a;
54077497c49SRudolf Cornelissen buffer[17] = 0x40;
54177497c49SRudolf Cornelissen buffer[18] = 0x0a;
54277497c49SRudolf Cornelissen buffer[19] = 0x00;
54377497c49SRudolf Cornelissen buffer[20] = 0x50;
54477497c49SRudolf Cornelissen buffer[21] = 0x55;
54577497c49SRudolf Cornelissen buffer[22] = 0x55;
54677497c49SRudolf Cornelissen buffer[23] = 0x8c; //chip-pin CLKI is pixel clock (only non-default here!)
54777497c49SRudolf Cornelissen buffer[24] = 0x24;
54877497c49SRudolf Cornelissen buffer[25] = 0xf0;
54977497c49SRudolf Cornelissen buffer[26] = 0x59;
55077497c49SRudolf Cornelissen buffer[27] = 0x82;
55177497c49SRudolf Cornelissen buffer[28] = 0x49;
55277497c49SRudolf Cornelissen buffer[29] = 0x8c;
55377497c49SRudolf Cornelissen buffer[30] = 0x8e;
55477497c49SRudolf Cornelissen buffer[31] = 0xb0;
55577497c49SRudolf Cornelissen buffer[32] = 0xe6;
55677497c49SRudolf Cornelissen buffer[33] = 0x28;
55777497c49SRudolf Cornelissen buffer[34] = 0x00;
55877497c49SRudolf Cornelissen
55977497c49SRudolf Cornelissen /* reset status */
56077497c49SRudolf Cornelissen i2c_flag_error (-1);
56177497c49SRudolf Cornelissen
56277497c49SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
56377497c49SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
56477497c49SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
56577497c49SRudolf Cornelissen /* log on errors */
56677497c49SRudolf Cornelissen stat = i2c_flag_error(0);
56777497c49SRudolf Cornelissen if (stat)
56877497c49SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting mode PAL720\n"));
56977497c49SRudolf Cornelissen
57077497c49SRudolf Cornelissen return stat;
57177497c49SRudolf Cornelissen }//end BT_init_PAL720.
57277497c49SRudolf Cornelissen
BT_init_NTSC720()57377497c49SRudolf Cornelissen static uint8 BT_init_NTSC720()
574fb6cadf1Sshatty {
57577497c49SRudolf Cornelissen uint8 stat;
576fb6cadf1Sshatty
57777497c49SRudolf Cornelissen uint8 buffer[35];
57877497c49SRudolf Cornelissen
5799a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting NTSC 720x480 overscanning DVD mode\n"));
5809a7218c5SRudolf Cornelissen
5819a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command
58277497c49SRudolf Cornelissen buffer[1] = 0x76; //select first bt register to write to.
58377497c49SRudolf Cornelissen buffer[2] = 0xf0; //lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1)
58477497c49SRudolf Cornelissen buffer[3] = 0xd0; //lsb h_active: h_active = 720 pixels wide port
58577497c49SRudolf Cornelissen buffer[4] = 0x83; //scope: OK hsync_width: (hsync_width / h_clk_o) * 63.55556uS = 4.70uS for NTSC
58677497c49SRudolf Cornelissen buffer[5] = 0x98; //scope: OK hburst_begin: (hburst_begin / h_clk_o) * 63.55556uS = 5.3uS for NTSC
58777497c49SRudolf Cornelissen buffer[6] = 0x5e; //scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 63.55556uS = 7.94uS for NTSC
58877497c49SRudolf Cornelissen
58977497c49SRudolf Cornelissen //How to find the correct values for h_blank_o and v_blank_o:
59077497c49SRudolf Cornelissen // 1. Calculate h_blank_o according to initial setting guideline mentioned below;
59177497c49SRudolf Cornelissen // 2. Set v_blank_o in the neighbourhood of $18, so that TV picture does not have ghosts on right side in it while
59277497c49SRudolf Cornelissen // horizontal position is about OK;
59377497c49SRudolf Cornelissen // 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch);
59477497c49SRudolf Cornelissen // 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above);
59577497c49SRudolf Cornelissen // 5. If no vertical shivering occurs when image is centered, you're done. Else:
59677497c49SRudolf Cornelissen // 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!:
59777497c49SRudolf Cornelissen // 7. Make sure you update the Chrontel horizontal Phase setting also then!
59877497c49SRudolf Cornelissen
5995cadaa5fSRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870)//set CX value
6005cadaa5fSRudolf Cornelissen {
601195828c4SRudolf Cornelissen /* confirmed on NV11 using 4:3 TV and 16:9 TV */
6025cadaa5fSRudolf Cornelissen buffer[7] = 0x0c; //scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV
6035cadaa5fSRudolf Cornelissen //(guideline for initial setting: (h_blank_o / h_clk_0) * 63.55556uS = 9.5uS for NTSC)
6045cadaa5fSRudolf Cornelissen }
6055cadaa5fSRudolf Cornelissen else //set BT value
6065cadaa5fSRudolf Cornelissen {
6075cadaa5fSRudolf Cornelissen /* confirmed on TNT1 using 4:3 TV and 16:9 TV */
60877497c49SRudolf Cornelissen buffer[7] = 0x28; //scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV
60977497c49SRudolf Cornelissen //(guideline for initial setting: (h_blank_o / h_clk_0) * 63.55556uS = 9.5uS for NTSC)
6105cadaa5fSRudolf Cornelissen }
61177497c49SRudolf Cornelissen buffer[8] = 0x18; //try-out; scope: checked against other modes, looks OK. v_blank_o: 1e active line ('pixel')
61277497c49SRudolf Cornelissen
61377497c49SRudolf Cornelissen buffer[9] = 0xf2; //v_active_o: = (active output lines + 2) / field (on TV)
61477497c49SRudolf Cornelissen buffer[10] = 0x26; //lsn = msn h_clk_o;
61577497c49SRudolf Cornelissen //b4-5 = msbits h_active;
61677497c49SRudolf Cornelissen //b7 = b8 v_avtive_o.
61777497c49SRudolf Cornelissen buffer[11] = 0x00; //h_fract is always 0.
61877497c49SRudolf Cornelissen buffer[12] = 0x78; //lsb h_clk_i: h_clk_i is horizontal total = 888.
61977497c49SRudolf Cornelissen buffer[13] = 0x90; //try-out; lsb h_blank_i: #clks between start sync and new line 1st pixel; copy to VGA delta-sync!
62077497c49SRudolf Cornelissen buffer[14] = 0x03; //b2-0 = msn h_clk_i;
62177497c49SRudolf Cornelissen //try-out: b3 = msn h_blank_i;
62277497c49SRudolf Cornelissen //b4 = vblankdly is always 0.
62377497c49SRudolf Cornelissen buffer[15] = 0x0d; //lsb v_lines_i: v_lines_i = 525
62477497c49SRudolf Cornelissen buffer[16] = 0x1a; //try-out; v_blank_i: #input lines between start sync and new line (pixel); copy to VGA delta-sync!
62577497c49SRudolf Cornelissen //Make sure though that this value for the BT is *even*, or image will shiver a *lot* horizontally on TV.
62677497c49SRudolf Cornelissen buffer[17] = 0xe0; //lsb v_active_i: v_active_i = 480
62777497c49SRudolf Cornelissen buffer[18] = 0x36; //b1-0 = msn v_lines_i;
62877497c49SRudolf Cornelissen //b3-2 = msn v_active_i;
62977497c49SRudolf Cornelissen //b5-4 = ylpf = 3;
63077497c49SRudolf Cornelissen //b7-6 = clpf = 0.
63177497c49SRudolf Cornelissen buffer[19] = 0x00; //lsb v_scale: v_scale = off = $1000
63277497c49SRudolf Cornelissen buffer[20] = 0x50; //b5-0 = msn v_scale;
63377497c49SRudolf Cornelissen //scope: tuned. b7-6 = msn h_blank_o.
63477497c49SRudolf Cornelissen //(((PLL_INT + (PLL_FRACT/65536)) / 6) * 13500000) = PIXEL_CLK = (hor.tot. * v_lines_i * 60Hz)
63577497c49SRudolf Cornelissen buffer[21] = 0x98; //lsb PLL fract: PLL fract = 0x6e98
63677497c49SRudolf Cornelissen buffer[22] = 0x6e; //msb PLL fract
63777497c49SRudolf Cornelissen buffer[23] = 0x8c; //b5-0 = PLL int: PLL int = 0x0c;
63877497c49SRudolf Cornelissen //b6 = by_pll: by_pll = 0;
63977497c49SRudolf Cornelissen //b7 = EN_XCLK: chip-pin CLKI is pixel clock.
64077497c49SRudolf Cornelissen buffer[24] = 0x0a; //b0 = ni_out is always 0;
64177497c49SRudolf Cornelissen //b1 = setup = 1 for NTSC;
64277497c49SRudolf Cornelissen //b2 = 625line = 0 for NTSC;
64377497c49SRudolf Cornelissen //b3 = vsync_dur = 1 for NTSC;
64477497c49SRudolf Cornelissen //b4 = dic_screset is always 0;
64577497c49SRudolf Cornelissen //b5 = pal_md = 0 for NTSC;
64677497c49SRudolf Cornelissen //b6 = eclip is always 0;
64777497c49SRudolf Cornelissen //b7 = reserved (en_scart) is always 0.
64877497c49SRudolf Cornelissen buffer[25] = 0xe5; //sync_amp $e5 for NTSC
64977497c49SRudolf Cornelissen buffer[26] = 0x75; //bst_amp $74-$76 for NTSC
65077497c49SRudolf Cornelissen buffer[27] = 0x78; //mcr: r-y $77-$79 for NTSC
65177497c49SRudolf Cornelissen buffer[28] = 0x44; //mcb: b-y $43-$44 for NTSC
65277497c49SRudolf Cornelissen buffer[29] = 0x85; //my: y $85 for NTSC
65377497c49SRudolf Cornelissen buffer[30] = 0x3c; //lsb msc: msc b31-0: NTSC formula: ((3579545 / pixelclk) * 2^32) = MSC
65477497c49SRudolf Cornelissen buffer[31] = 0x91; //msc = $20c2913c
65577497c49SRudolf Cornelissen buffer[32] = 0xc2;
65677497c49SRudolf Cornelissen buffer[33] = 0x20; //msb msc.
65777497c49SRudolf Cornelissen buffer[34] = 0x00; //phase_off always $00
65877497c49SRudolf Cornelissen
65977497c49SRudolf Cornelissen /* reset status */
66077497c49SRudolf Cornelissen i2c_flag_error (-1);
66177497c49SRudolf Cornelissen
66277497c49SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
66377497c49SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
66477497c49SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
66577497c49SRudolf Cornelissen /* log on errors */
66677497c49SRudolf Cornelissen stat = i2c_flag_error(0);
66777497c49SRudolf Cornelissen if (stat)
66877497c49SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC720\n"));
66977497c49SRudolf Cornelissen
67077497c49SRudolf Cornelissen return stat;
67177497c49SRudolf Cornelissen }//end BT_init_NTSC720.
67277497c49SRudolf Cornelissen
BT_init_PAL800_OS()67377497c49SRudolf Cornelissen static uint8 BT_init_PAL800_OS()
674fb6cadf1Sshatty {
67577497c49SRudolf Cornelissen uint8 stat;
676fb6cadf1Sshatty
67777497c49SRudolf Cornelissen uint8 buffer[35];
67877497c49SRudolf Cornelissen
6799a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting PAL 800x600 overscanning VCD mode\n"));
6809a7218c5SRudolf Cornelissen
6819a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command
68277497c49SRudolf Cornelissen buffer[1] = 0x76; //select first bt register to write to.
68377497c49SRudolf Cornelissen buffer[2] = 0x60; //lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1)
68477497c49SRudolf Cornelissen buffer[3] = 0x20; //lsb h_active: h_active = 800 pixels wide port
68577497c49SRudolf Cornelissen buffer[4] = 0x8b; //scope: OK hsync_width: (hsync_width / h_clk_o) * 64.0uS = 4.70uS for PAL
68677497c49SRudolf Cornelissen buffer[5] = 0xa5; //scope: OK hburst_begin: (hburst_begin / h_clk_o) * 64.0uS = 5.6uS for PAL
68777497c49SRudolf Cornelissen buffer[6] = 0x6b; //scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 64.0uS = 7.97uS for PAL
68877497c49SRudolf Cornelissen
68977497c49SRudolf Cornelissen //How to find the correct values for h_blank_o and v_blank_o:
69077497c49SRudolf Cornelissen // 1. Calculate h_blank_o according to initial setting guideline mentioned below;
69177497c49SRudolf Cornelissen // 2. Set v_blank_o in the neighbourhood of $18, so that TV picture does not have ghosts on right side in it while
69277497c49SRudolf Cornelissen // horizontal position is about OK;
69377497c49SRudolf Cornelissen // 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch);
69477497c49SRudolf Cornelissen // 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above);
69577497c49SRudolf Cornelissen // 5. If no vertical shivering occurs when image is centered, you're done. Else:
69677497c49SRudolf Cornelissen // 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!:
69777497c49SRudolf Cornelissen // 7. Make sure you update the Chrontel horizontal Phase setting also then!
69877497c49SRudolf Cornelissen
69977497c49SRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870)//set CX value
700fb6cadf1Sshatty {
701195828c4SRudolf Cornelissen /* confirmed on NV11 using 4:3 TV and 16:9 TV */
7025cadaa5fSRudolf Cornelissen buffer[7] = 0xf0;
70377497c49SRudolf Cornelissen buffer[8] = 0x17;
704fb6cadf1Sshatty }
7055cadaa5fSRudolf Cornelissen else //set BT value
7065cadaa5fSRudolf Cornelissen {
7074e918a7cSRudolf Cornelissen /* confirmed on TNT1 using 4:3 TV and 16:9 TV */
7086245f19cSRudolf Cornelissen buffer[7] = 0xd0;//scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV
70977497c49SRudolf Cornelissen //(guideline for initial setting: (h_blank_o / h_clk_0) * 64.0uS = 10.0uS for PAL)
71077497c49SRudolf Cornelissen buffer[8] = 0x18;//try-out; scope: checked against other modes, looks OK. v_blank_o: 1e active line ('pixel')
71177497c49SRudolf Cornelissen }
71277497c49SRudolf Cornelissen
71377497c49SRudolf Cornelissen buffer[9] = 0x2e; //v_active_o: = (active output lines + 2) / field (on TV)
71477497c49SRudolf Cornelissen buffer[10] = 0xb7; //lsn = msn h_clk_o;
71577497c49SRudolf Cornelissen //b4-5 = msbits h_active;
71677497c49SRudolf Cornelissen //b7 = b8 v_avtive_o.
71777497c49SRudolf Cornelissen buffer[11] = 0x00; //h_fract is always 0.
71877497c49SRudolf Cornelissen buffer[12] = 0xb0; //lsb h_clk_i: h_clk_i is horizontal total = 944.
71977497c49SRudolf Cornelissen
72077497c49SRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870)//set CX value
72177497c49SRudolf Cornelissen buffer[13] = 0x20;
72277497c49SRudolf Cornelissen else //set BT value
72377497c49SRudolf Cornelissen buffer[13] = 0x14;//try-out; lsb h_blank_i: #clks between start sync and new line 1st pixel; copy to VGA delta-sync!
72477497c49SRudolf Cornelissen
72577497c49SRudolf Cornelissen buffer[14] = 0x03; //b2-0 = msn h_clk_i;
72677497c49SRudolf Cornelissen //try-out: b3 = msn h_blank_i;
72777497c49SRudolf Cornelissen //b4 = vblankdly is always 0.
72877497c49SRudolf Cornelissen buffer[15] = 0x71; //lsb v_lines_i: v_lines_i = 625
72977497c49SRudolf Cornelissen
73077497c49SRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870)//set CX value
73177497c49SRudolf Cornelissen buffer[16] = 0x08;
73277497c49SRudolf Cornelissen else //set BT value
73377497c49SRudolf Cornelissen buffer[16] = 0x2a;//try-out; v_blank_i: #input lines between start sync and new line (pixel); copy to VGA delta-sync!
73477497c49SRudolf Cornelissen //Make sure though that this value for the BT is *even*, or image will shiver a *lot* horizontally on TV.
73577497c49SRudolf Cornelissen
73677497c49SRudolf Cornelissen buffer[17] = 0x58; //lsb v_active_i: v_active_i = 600
73777497c49SRudolf Cornelissen buffer[18] = 0x3a; //b1-0 = msn v_lines_i;
73877497c49SRudolf Cornelissen //b3-2 = msn v_active_i;
73977497c49SRudolf Cornelissen //b5-4 = ylpf = 3;
74077497c49SRudolf Cornelissen //b7-6 = clpf = 0.
74177497c49SRudolf Cornelissen buffer[19] = 0x00; //lsb v_scale: v_scale = off = $1000
74277497c49SRudolf Cornelissen buffer[20] = 0x10; //b5-0 = msn v_scale;
74377497c49SRudolf Cornelissen //scope: tuned. b7-6 = msn h_blank_o.
74477497c49SRudolf Cornelissen //(((PLL_INT + (PLL_FRACT/65536)) / 6) * 13500000) = PIXEL_CLK = (hor.tot. * v_lines_i * 50Hz)
74577497c49SRudolf Cornelissen buffer[21] = 0x72; //lsb PLL fract: PLL fract = 0x1c72
74677497c49SRudolf Cornelissen buffer[22] = 0x1c; //msb PLL fract
74777497c49SRudolf Cornelissen buffer[23] = 0x8d; //b5-0 = PLL int: PLL int = 0x0d;
74877497c49SRudolf Cornelissen //b6 = by_pll: by_pll = 0;
74977497c49SRudolf Cornelissen //b7 = EN_XCLK: chip-pin CLKI is pixel clock.
75077497c49SRudolf Cornelissen buffer[24] = 0x24; //b0 = ni_out is always 0;
75177497c49SRudolf Cornelissen //b1 = setup = 0 for PAL;
75277497c49SRudolf Cornelissen //b2 = 625line = 1 for PAL;
75377497c49SRudolf Cornelissen //b3 = vsync_dur = 0 for PAL;
75477497c49SRudolf Cornelissen //b4 = dic_screset is always 0;
75577497c49SRudolf Cornelissen //b5 = pal_md = 1 for PAL;
75677497c49SRudolf Cornelissen //b6 = eclip is always 0;
75777497c49SRudolf Cornelissen //b7 = reserved (en_scart) is always 0.
75877497c49SRudolf Cornelissen buffer[25] = 0xf0; //sync_amp $f0 for PAL
75977497c49SRudolf Cornelissen buffer[26] = 0x57; //bst_amp $57-$58 for PAL
76077497c49SRudolf Cornelissen buffer[27] = 0x80; //mcr: r-y $80-$81 for PAL
76177497c49SRudolf Cornelissen buffer[28] = 0x48; //mcb: b-y $48-$49 for PAL
76277497c49SRudolf Cornelissen buffer[29] = 0x8c; //my: y $8c for PAL
76377497c49SRudolf Cornelissen buffer[30] = 0x31; //lsb msc: msc b31-0: PAL formula: ((4433619 / pixelclk) * 2^32) = MSC
76477497c49SRudolf Cornelissen buffer[31] = 0x8c; //msc = $26798c31
76577497c49SRudolf Cornelissen buffer[32] = 0x79;
76677497c49SRudolf Cornelissen buffer[33] = 0x26; //msb msc.
76777497c49SRudolf Cornelissen buffer[34] = 0x00; //phase_off always $00
76877497c49SRudolf Cornelissen
76977497c49SRudolf Cornelissen /* reset status */
77077497c49SRudolf Cornelissen i2c_flag_error (-1);
77177497c49SRudolf Cornelissen
77277497c49SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
77377497c49SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
77477497c49SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
77577497c49SRudolf Cornelissen /* log on errors */
77677497c49SRudolf Cornelissen stat = i2c_flag_error(0);
77777497c49SRudolf Cornelissen if (stat)
77877497c49SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800 OS\n"));
77977497c49SRudolf Cornelissen
78077497c49SRudolf Cornelissen return stat;
78177497c49SRudolf Cornelissen }//end BT_init_PAL800_OS.
78277497c49SRudolf Cornelissen
BT_init_NTSC640_OS()78377497c49SRudolf Cornelissen static uint8 BT_init_NTSC640_OS()
784fb6cadf1Sshatty {
78577497c49SRudolf Cornelissen uint8 stat;
786fb6cadf1Sshatty
78777497c49SRudolf Cornelissen uint8 buffer[35];
788fb6cadf1Sshatty
7899a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Setting NTSC 640x480 overscanning VCD mode\n"));
7909a7218c5SRudolf Cornelissen
7919a7218c5SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR; //issue I2C write command
79277497c49SRudolf Cornelissen buffer[1] = 0x76; //select first bt register to write to.
79377497c49SRudolf Cornelissen buffer[2] = 0x20; //lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1)
79477497c49SRudolf Cornelissen buffer[3] = 0x80; //lsb h_active: h_active = 640 pixels wide port
79577497c49SRudolf Cornelissen buffer[4] = 0x74; //scope: OK hsync_width: (hsync_width / h_clk_o) * 63.55556uS = 4.70uS for NTSC
79677497c49SRudolf Cornelissen buffer[5] = 0x83; //scope: OK hburst_begin: (hburst_begin / h_clk_o) * 63.55556uS = 5.3uS for NTSC
79777497c49SRudolf Cornelissen buffer[6] = 0x44; //scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 63.55556uS = 7.94uS for NTSC
798fb6cadf1Sshatty
79977497c49SRudolf Cornelissen //How to find the correct values for h_blank_o and v_blank_o:
80077497c49SRudolf Cornelissen // 1. Calculate h_blank_o according to initial setting guideline mentioned below;
80177497c49SRudolf Cornelissen // 2. Set v_blank_o in the neighbourhood of $18, so that TV picture does not have ghosts on right side in it while
80277497c49SRudolf Cornelissen // horizontal position is about OK;
80377497c49SRudolf Cornelissen // 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch);
80477497c49SRudolf Cornelissen // 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above);
80577497c49SRudolf Cornelissen // 5. If no vertical shivering occurs when image is centered, you're done. Else:
80677497c49SRudolf Cornelissen // 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!:
80777497c49SRudolf Cornelissen // 7. Make sure you update the Chrontel horizontal Phase setting also then!
808fb6cadf1Sshatty
80977497c49SRudolf Cornelissen buffer[7] = 0xf7; //scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV:
81077497c49SRudolf Cornelissen //(guideline for initial setting: (h_blank_o / h_clk_0) * 63.55556uS = 9.5uS for NTSC)
811fb6cadf1Sshatty
81277497c49SRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870)//set CX value
81377497c49SRudolf Cornelissen buffer[8] = 0x1d;
81477497c49SRudolf Cornelissen else //set BT value
81577497c49SRudolf Cornelissen buffer[8] = 0x1c;//try-out; scope: checked against other modes, looks OK. v_blank_o: 1e active line ('pixel')
816fb6cadf1Sshatty
81777497c49SRudolf Cornelissen buffer[9] = 0xf2; //v_active_o: = (active output lines + 2) / field (on TV)
81877497c49SRudolf Cornelissen buffer[10] = 0x26; //lsn = msn h_clk_o;
81977497c49SRudolf Cornelissen //b4-5 = msbits h_active;
82077497c49SRudolf Cornelissen //b7 = b8 v_avtive_o.
82177497c49SRudolf Cornelissen buffer[11] = 0x00; //h_fract is always 0.
82277497c49SRudolf Cornelissen buffer[12] = 0x10; //lsb h_clk_i: h_clk_i is horizontal total = 784.
82377497c49SRudolf Cornelissen buffer[13] = 0x14; //try-out; lsb h_blank_i: #clks between start sync and new line 1st pixel; copy to VGA delta-sync!
82477497c49SRudolf Cornelissen buffer[14] = 0x03; //b2-0 = msn h_clk_i;
82577497c49SRudolf Cornelissen //try-out: b3 = msn h_blank_i;
82677497c49SRudolf Cornelissen //b4 = vblankdly is always 0.
82777497c49SRudolf Cornelissen buffer[15] = 0x0d; //lsb v_lines_i: v_lines_i = 525
82877497c49SRudolf Cornelissen buffer[16] = 0x18; //try-out; v_blank_i: #input lines between start sync and new line (pixel); copy to VGA delta-sync!
82977497c49SRudolf Cornelissen //Make sure though that this value for the BT is *even*, or image will shiver a *lot* horizontally on TV.
83077497c49SRudolf Cornelissen buffer[17] = 0xe0; //lsb v_active_i: v_active_i = 480
83177497c49SRudolf Cornelissen buffer[18] = 0x36; //b1-0 = msn v_lines_i;
83277497c49SRudolf Cornelissen //b3-2 = msn v_active_i;
83377497c49SRudolf Cornelissen //b5-4 = ylpf = 3;
83477497c49SRudolf Cornelissen //b7-6 = clpf = 0.
83577497c49SRudolf Cornelissen buffer[19] = 0x00; //lsb v_scale: v_scale = off = $1000
83677497c49SRudolf Cornelissen buffer[20] = 0x10; //b5-0 = msn v_scale;
83777497c49SRudolf Cornelissen //scope: tuned. b7-6 = msn h_blank_o.
83877497c49SRudolf Cornelissen //(((PLL_INT + (PLL_FRACT/65536)) / 6) * 13500000) = PIXEL_CLK = (hor.tot. * v_lines_i * 60Hz)
83977497c49SRudolf Cornelissen buffer[21] = 0xdb; //lsb PLL fract: PLL fract = 0xf9db
84077497c49SRudolf Cornelissen buffer[22] = 0xf9; //msb PLL fract
84177497c49SRudolf Cornelissen buffer[23] = 0x8a; //b5-0 = PLL int: PLL int = 0x0a;
84277497c49SRudolf Cornelissen //b6 = by_pll: by_pll = 0;
84377497c49SRudolf Cornelissen //b7 = EN_XCLK: chip-pin CLKI is pixel clock.
84477497c49SRudolf Cornelissen buffer[24] = 0x0a; //b0 = ni_out is always 0;
84577497c49SRudolf Cornelissen //b1 = setup = 1 for NTSC;
84677497c49SRudolf Cornelissen //b2 = 625line = 0 for NTSC;
84777497c49SRudolf Cornelissen //b3 = vsync_dur = 1 for NTSC;
84877497c49SRudolf Cornelissen //b4 = dic_screset is always 0;
84977497c49SRudolf Cornelissen //b5 = pal_md = 0 for NTSC;
85077497c49SRudolf Cornelissen //b6 = eclip is always 0;
85177497c49SRudolf Cornelissen //b7 = reserved (en_scart) is always 0.
85277497c49SRudolf Cornelissen buffer[25] = 0xe5; //sync_amp $e5 for NTSC
85377497c49SRudolf Cornelissen buffer[26] = 0x75; //bst_amp $74-$76 for NTSC
85477497c49SRudolf Cornelissen buffer[27] = 0x78; //mcr: r-y $77-$79 for NTSC
85577497c49SRudolf Cornelissen buffer[28] = 0x44; //mcb: b-y $43-$44 for NTSC
85677497c49SRudolf Cornelissen buffer[29] = 0x85; //my: y $85 for NTSC
85777497c49SRudolf Cornelissen buffer[30] = 0x37; //lsb msc: msc b31-0: NTSC formula: ((3579545 / pixelclk) * 2^32) = MSC
85877497c49SRudolf Cornelissen buffer[31] = 0x12; //msc = $251b1237
85977497c49SRudolf Cornelissen buffer[32] = 0x1b;
86077497c49SRudolf Cornelissen buffer[33] = 0x25; //msb msc.
86177497c49SRudolf Cornelissen buffer[34] = 0x00; //phase_off always $00
862fb6cadf1Sshatty
86377497c49SRudolf Cornelissen /* reset status */
86477497c49SRudolf Cornelissen i2c_flag_error (-1);
865fb6cadf1Sshatty
86677497c49SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
86777497c49SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
86877497c49SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
86977497c49SRudolf Cornelissen /* log on errors */
87077497c49SRudolf Cornelissen stat = i2c_flag_error(0);
87177497c49SRudolf Cornelissen if (stat)
87277497c49SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC640 OS\n"));
873fb6cadf1Sshatty
87477497c49SRudolf Cornelissen return stat;
87577497c49SRudolf Cornelissen }//end BT_init_NTSC640_OS.
876fb6cadf1Sshatty
BT_testsignal(void)87721f6ecabSRudolf Cornelissen static uint8 BT_testsignal(void)
87821f6ecabSRudolf Cornelissen {
87921f6ecabSRudolf Cornelissen uint8 stat;
88021f6ecabSRudolf Cornelissen
88121f6ecabSRudolf Cornelissen uint8 buffer[3];
88221f6ecabSRudolf Cornelissen
8839a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Enabling testsignal\n"));
8849a7218c5SRudolf Cornelissen
88521f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR;
88621f6ecabSRudolf Cornelissen /* select bt register for enabling colorbars and outputs */
88721f6ecabSRudolf Cornelissen buffer[1] = 0xc4;
88821f6ecabSRudolf Cornelissen /* issue the actual command */
88921f6ecabSRudolf Cornelissen buffer[2] = 0x05;
89021f6ecabSRudolf Cornelissen
89121f6ecabSRudolf Cornelissen /* reset status */
89221f6ecabSRudolf Cornelissen i2c_flag_error (-1);
89321f6ecabSRudolf Cornelissen
89421f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
89521f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
89621f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
89721f6ecabSRudolf Cornelissen /* log on errors */
89821f6ecabSRudolf Cornelissen stat = i2c_flag_error(0);
89921f6ecabSRudolf Cornelissen if (stat)
90021f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting up flickerfilter and outputs\n"));
90121f6ecabSRudolf Cornelissen
90221f6ecabSRudolf Cornelissen return stat;
90321f6ecabSRudolf Cornelissen }//end BT_testsignal.
90421f6ecabSRudolf Cornelissen
BT_setup_output(uint8 monstat,uint8 output,uint8 ffilter)90521f6ecabSRudolf Cornelissen static uint8 BT_setup_output(uint8 monstat, uint8 output, uint8 ffilter)
90621f6ecabSRudolf Cornelissen {
90721f6ecabSRudolf Cornelissen uint8 stat;
90821f6ecabSRudolf Cornelissen
90921f6ecabSRudolf Cornelissen uint8 buffer[7];
91021f6ecabSRudolf Cornelissen
91121f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR;
91221f6ecabSRudolf Cornelissen /* select first TV config register to write */
91321f6ecabSRudolf Cornelissen buffer[1] = 0xc6;
91421f6ecabSRudolf Cornelissen /* input is 24bit mpx'd RGB, BLANK = out, sync = act. hi */
91521f6ecabSRudolf Cornelissen buffer[2] = 0x98;
91621f6ecabSRudolf Cornelissen /* disable all filters, exept flicker filter */
91721f6ecabSRudolf Cornelissen buffer[3] = 0x98;
91821f6ecabSRudolf Cornelissen if (!ffilter)
91921f6ecabSRudolf Cornelissen {
92021f6ecabSRudolf Cornelissen /* disable flicker filter */
92121f6ecabSRudolf Cornelissen buffer[3] = 0xc0;
9229a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Disabling flickerfilter\n"));
92321f6ecabSRudolf Cornelissen }
9249a7218c5SRudolf Cornelissen else
9259a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Enabling flickerfilter\n"));
9269a7218c5SRudolf Cornelissen
92721f6ecabSRudolf Cornelissen /* (disable filters) */
92821f6ecabSRudolf Cornelissen buffer[4] = 0xc0;
92921f6ecabSRudolf Cornelissen /* (disable filters) */
93021f6ecabSRudolf Cornelissen buffer[5] = 0xc0;
93121f6ecabSRudolf Cornelissen switch (output)
93221f6ecabSRudolf Cornelissen /* Description of ELSA Erazor III hardware layout:
93321f6ecabSRudolf Cornelissen * (This is the default (recommended) layout by NVIDIA)
93421f6ecabSRudolf Cornelissen * DAC A = CVBS
93521f6ecabSRudolf Cornelissen * DAC B = C (chrominance)
93621f6ecabSRudolf Cornelissen * DAC C = Y (luminance) */
93721f6ecabSRudolf Cornelissen
93821f6ecabSRudolf Cornelissen /* Description of Diamond VIPER550:
93921f6ecabSRudolf Cornelissen * DAC A = Not connected
94021f6ecabSRudolf Cornelissen * DAC B = C (chrominance)
94121f6ecabSRudolf Cornelissen * DAC C = Y (luminance)
94221f6ecabSRudolf Cornelissen * To be able to connect to CVBS TV's a special cable is supplied:
94321f6ecabSRudolf Cornelissen * This cable connects the Y (DAC C) output to the TV CVBS input. */
94421f6ecabSRudolf Cornelissen {
9459a7218c5SRudolf Cornelissen case 1:
9465890efa4SRudolf Cornelissen LOG(4,("Brooktree: Forcing both Y/C and CVBS signals where supported by hardware\n"));
9479a7218c5SRudolf Cornelissen buffer[6] = 0x18; // Y/C and CVBS out if all ports implemented
94821f6ecabSRudolf Cornelissen // in hardware, else only Y/C or CVBS out.
94921f6ecabSRudolf Cornelissen break;
9509a7218c5SRudolf Cornelissen case 2:
9515890efa4SRudolf Cornelissen LOG(4,("Brooktree: Forcing CVBS signals on all outputs\n"));
9529a7218c5SRudolf Cornelissen buffer[6] = 0x00; // put CVBS on all outputs. Used for cards
95321f6ecabSRudolf Cornelissen break; // with only Y/C out and 'translation cable'.
9549a7218c5SRudolf Cornelissen default:
955b0fce481SRudolf Cornelissen LOG(4,("Brooktree: Outputting signals according to autodetect status:\n"));
9569a7218c5SRudolf Cornelissen switch (monstat) // only 'autodetect' remains...
95721f6ecabSRudolf Cornelissen {
9589a7218c5SRudolf Cornelissen case 1:
959b0fce481SRudolf Cornelissen LOG(4,("Brooktree: Only Y connected, outputting CVBS on all outputs\n"));
9609a7218c5SRudolf Cornelissen buffer[6] = 0x00; //only Y connected: must be CVBS!
96121f6ecabSRudolf Cornelissen break;
9629a7218c5SRudolf Cornelissen case 2:
963b0fce481SRudolf Cornelissen LOG(4,("Brooktree: Only C connected, outputting CVBS on all outputs\n"));
9649a7218c5SRudolf Cornelissen buffer[6] = 0x00; //only C connected: must be CVBS!
96521f6ecabSRudolf Cornelissen break; //(though cable is wired wrong...)
9669a7218c5SRudolf Cornelissen case 5:
967b0fce481SRudolf Cornelissen LOG(4,("Brooktree: CVBS and only Y connected, outputting CVBS on all outputs\n"));
9689a7218c5SRudolf Cornelissen buffer[6] = 0x00; //CVBS and only Y connected: 2x CVBS!
96921f6ecabSRudolf Cornelissen break; //(officially not supported...)
9709a7218c5SRudolf Cornelissen case 6:
971b0fce481SRudolf Cornelissen LOG(4,("Brooktree: CVBS and only C connected, outputting CVBS on all outputs\n"));
9729a7218c5SRudolf Cornelissen buffer[6] = 0x00; //CVBS and only C connected: 2x CVBS!
97321f6ecabSRudolf Cornelissen break; //(officially not supported...)
9749a7218c5SRudolf Cornelissen default:
975b0fce481SRudolf Cornelissen LOG(4,("Brooktree: Outputting both Y/C and CVBS where supported by hardware\n"));
9769a7218c5SRudolf Cornelissen buffer[6] = 0x18; //nothing, or
97721f6ecabSRudolf Cornelissen //Y/C only, or
97821f6ecabSRudolf Cornelissen //CVBS only (but on CVBS output), or
97921f6ecabSRudolf Cornelissen //Y/C and CVBS connected:
98021f6ecabSRudolf Cornelissen //So activate recommended signals.
98121f6ecabSRudolf Cornelissen }
98221f6ecabSRudolf Cornelissen }
98321f6ecabSRudolf Cornelissen
98421f6ecabSRudolf Cornelissen /* reset status */
98521f6ecabSRudolf Cornelissen i2c_flag_error (-1);
98621f6ecabSRudolf Cornelissen
98721f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
98821f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
98921f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
99021f6ecabSRudolf Cornelissen /* log on errors */
99121f6ecabSRudolf Cornelissen stat = i2c_flag_error(0);
99221f6ecabSRudolf Cornelissen if (stat)
99321f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting up flickerfilter and outputs\n"));
99421f6ecabSRudolf Cornelissen
99521f6ecabSRudolf Cornelissen return stat;
99621f6ecabSRudolf Cornelissen }//end BT_setup_output.
99721f6ecabSRudolf Cornelissen
BT_setup_hphase(uint8 mode)99821f6ecabSRudolf Cornelissen static uint8 BT_setup_hphase(uint8 mode)
99921f6ecabSRudolf Cornelissen {
100021f6ecabSRudolf Cornelissen uint8 stat, hoffset;
100121f6ecabSRudolf Cornelissen
100221f6ecabSRudolf Cornelissen uint8 buffer[7];
100321f6ecabSRudolf Cornelissen
10049a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Tuning horizontal phase\n"));
10059a7218c5SRudolf Cornelissen
100621f6ecabSRudolf Cornelissen /* CX needs timing reset (advised on BT also), first 1mS delay needed! */
100721f6ecabSRudolf Cornelissen snooze(1000);
100821f6ecabSRudolf Cornelissen
100921f6ecabSRudolf Cornelissen /* values below are all tested on TNT1, TNT2 and GeForce2MX */
101021f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR;
101121f6ecabSRudolf Cornelissen /* select first TV output timing register to write */
101221f6ecabSRudolf Cornelissen buffer[1] = 0x6c;
101321f6ecabSRudolf Cornelissen /* turn on active video & generate timing reset on CX chips! */
101421f6ecabSRudolf Cornelissen buffer[2] = 0x86;
101521f6ecabSRudolf Cornelissen /* (set fail save values...) */
101621f6ecabSRudolf Cornelissen buffer[3] = 0x00; //set default horizontal sync offset
101721f6ecabSRudolf Cornelissen buffer[4] = 0x02; //set default horizontal sync width
101821f6ecabSRudolf Cornelissen buffer[5] = 0x00; //set default vertical sync offset
101921f6ecabSRudolf Cornelissen
102021f6ecabSRudolf Cornelissen /* do specific timing setup for all chips and modes: */
10214594e58aSRudolf Cornelissen switch (si->ps.card_type)
1022b0fce481SRudolf Cornelissen {
10234594e58aSRudolf Cornelissen case NV05:
10244594e58aSRudolf Cornelissen case NV05M64:
10254594e58aSRudolf Cornelissen case NV15:
10264594e58aSRudolf Cornelissen /* confirmed TNT2, TNT2M64, GeForce2Ti.
1027b0fce481SRudolf Cornelissen * (8 pixels delayed hpos, so picture more to the right) */
1028b0fce481SRudolf Cornelissen hoffset = 8;
10294594e58aSRudolf Cornelissen break;
10304594e58aSRudolf Cornelissen default:
10314594e58aSRudolf Cornelissen /* confirmed TNT1, GeForce256, GeForce2MX.
1032b0fce481SRudolf Cornelissen * (std hpos)
1033b0fce481SRudolf Cornelissen * NOTE: It might be that GeForce needs TNT2 offset:
1034b0fce481SRudolf Cornelissen * for now CX chips get seperate extra offset, until sure.
1035b0fce481SRudolf Cornelissen * (CX is only found AFAIK on GeForce cards, no BT tested
1036b0fce481SRudolf Cornelissen * on GeForce yet. CH was tested on GeForce and seemed to
1037b0fce481SRudolf Cornelissen * indicate TNT1 offset was needed.) */
1038b0fce481SRudolf Cornelissen hoffset = 0;
10394594e58aSRudolf Cornelissen break;
1040b0fce481SRudolf Cornelissen }
104121f6ecabSRudolf Cornelissen
104221f6ecabSRudolf Cornelissen switch (mode)
104321f6ecabSRudolf Cornelissen {
104421f6ecabSRudolf Cornelissen case NTSC640_TST:
104521f6ecabSRudolf Cornelissen case NTSC640:
104621f6ecabSRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
10474e918a7cSRudolf Cornelissen /* confirmed on TNT1 with BT869 using 4:3 TV and 16:9 TV */
1048f2069d6cSRudolf Cornelissen buffer[3] = (0x1e + hoffset); //set horizontal sync offset
104921f6ecabSRudolf Cornelissen break;
105021f6ecabSRudolf Cornelissen case NTSC800:
105121f6ecabSRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
105221f6ecabSRudolf Cornelissen buffer[3] = (0xe1 + hoffset); //set horizontal sync offset
105321f6ecabSRudolf Cornelissen buffer[4] = 0xc2;
105421f6ecabSRudolf Cornelissen //Vsync offset reg. does not exist on CX: mode is checked and OK.
105521f6ecabSRudolf Cornelissen buffer[5] = 0x40; //set VSync offset (on BT's only)
105621f6ecabSRudolf Cornelissen break;
105721f6ecabSRudolf Cornelissen case PAL640:
105821f6ecabSRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
105921f6ecabSRudolf Cornelissen buffer[3] = (0xa8 + hoffset);
106021f6ecabSRudolf Cornelissen break;
106121f6ecabSRudolf Cornelissen case PAL800_TST:
106221f6ecabSRudolf Cornelissen case PAL800:
106321f6ecabSRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
106421f6ecabSRudolf Cornelissen buffer[3] = (0x2c + hoffset);
106521f6ecabSRudolf Cornelissen break;
106621f6ecabSRudolf Cornelissen case NTSC720:
106721f6ecabSRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870)
106821f6ecabSRudolf Cornelissen buffer[3] = (0xb2 + hoffset); //set horizontal sync offset CX
106921f6ecabSRudolf Cornelissen else
107021f6ecabSRudolf Cornelissen buffer[3] = (0xd0 + hoffset); //set horizontal sync offset BT
107121f6ecabSRudolf Cornelissen buffer[4] = 0xff; //hsync width = max:
107221f6ecabSRudolf Cornelissen break; //to prevent vertical image 'shivering'.
107321f6ecabSRudolf Cornelissen case PAL720:
107421f6ecabSRudolf Cornelissen buffer[3] = (0xd4 + hoffset);
107521f6ecabSRudolf Cornelissen buffer[4] = 0xff;
107621f6ecabSRudolf Cornelissen break;
107721f6ecabSRudolf Cornelissen case NTSC640_OS:
107821f6ecabSRudolf Cornelissen buffer[3] = (0xc8 + hoffset);
107921f6ecabSRudolf Cornelissen buffer[4] = 0xff;
108021f6ecabSRudolf Cornelissen break;
108121f6ecabSRudolf Cornelissen case PAL800_OS:
108221f6ecabSRudolf Cornelissen if (si->ps.tv_encoder.type >= CX25870)
108321f6ecabSRudolf Cornelissen buffer[3] = (0x78 + hoffset); //set horizontal sync offset CX
108421f6ecabSRudolf Cornelissen else
108521f6ecabSRudolf Cornelissen buffer[3] = (0xc4 + hoffset); //set horizontal sync offset BT
108621f6ecabSRudolf Cornelissen buffer[4] = 0xff;
108721f6ecabSRudolf Cornelissen break;
108821f6ecabSRudolf Cornelissen default: //nothing to be done here...
108921f6ecabSRudolf Cornelissen break;
109021f6ecabSRudolf Cornelissen }
109121f6ecabSRudolf Cornelissen
109221f6ecabSRudolf Cornelissen buffer[6] = 0x01; //set default vertical sync width
109321f6ecabSRudolf Cornelissen
109421f6ecabSRudolf Cornelissen /* reset status */
109521f6ecabSRudolf Cornelissen i2c_flag_error (-1);
109621f6ecabSRudolf Cornelissen
109721f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
109821f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
109921f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
110021f6ecabSRudolf Cornelissen /* log on errors */
110121f6ecabSRudolf Cornelissen stat = i2c_flag_error(0);
110221f6ecabSRudolf Cornelissen if (stat)
110321f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting up h_phase\n"));
110421f6ecabSRudolf Cornelissen
110521f6ecabSRudolf Cornelissen return stat;
110621f6ecabSRudolf Cornelissen }//end BT_setup_hphase.
110721f6ecabSRudolf Cornelissen
BT_read_monstat(uint8 * monstat)110821f6ecabSRudolf Cornelissen static uint8 BT_read_monstat(uint8* monstat)
110921f6ecabSRudolf Cornelissen {
111021f6ecabSRudolf Cornelissen uint8 stat;
111121f6ecabSRudolf Cornelissen uint8 buffer[3];
111221f6ecabSRudolf Cornelissen
1113efe9c7a6SRudolf Cornelissen /* make sure we have the recommended failsafe selected */
1114efe9c7a6SRudolf Cornelissen *monstat = 0;
1115efe9c7a6SRudolf Cornelissen
11169a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Autodetecting connected output devices\n"));
11179a7218c5SRudolf Cornelissen
111821f6ecabSRudolf Cornelissen /* set BT to return connection status in ESTATUS on next read CMD: */
111921f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR;
112021f6ecabSRudolf Cornelissen /* set ESTATUS at b'01' (return conn.stat.) */
112121f6ecabSRudolf Cornelissen buffer[1] = 0xc4;
112221f6ecabSRudolf Cornelissen /* and leave chip outputs on. */
112321f6ecabSRudolf Cornelissen buffer[2] = 0x41;
112421f6ecabSRudolf Cornelissen
112521f6ecabSRudolf Cornelissen /* reset status */
112621f6ecabSRudolf Cornelissen i2c_flag_error (-1);
112721f6ecabSRudolf Cornelissen
112821f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
112921f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
113021f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
113121f6ecabSRudolf Cornelissen /* log on errors */
113221f6ecabSRudolf Cornelissen stat = i2c_flag_error(0);
113321f6ecabSRudolf Cornelissen if (stat)
113421f6ecabSRudolf Cornelissen {
113521f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while reading connection status (1)\n"));
113621f6ecabSRudolf Cornelissen return stat;
113721f6ecabSRudolf Cornelissen }
113821f6ecabSRudolf Cornelissen
113921f6ecabSRudolf Cornelissen /* do actual read connection status: */
114021f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR;
114121f6ecabSRudolf Cornelissen /* select register with CHECK_STAT CMD */
114221f6ecabSRudolf Cornelissen buffer[1] = 0xba;
114321f6ecabSRudolf Cornelissen /* issue actual command. */
114421f6ecabSRudolf Cornelissen buffer[2] = 0x40;
114521f6ecabSRudolf Cornelissen
114621f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
114721f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
114821f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
114921f6ecabSRudolf Cornelissen /* log on errors */
115021f6ecabSRudolf Cornelissen stat = i2c_flag_error(0);
115121f6ecabSRudolf Cornelissen if (stat)
115221f6ecabSRudolf Cornelissen {
115321f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while reading connection status (2)\n"));
115421f6ecabSRudolf Cornelissen return stat;
115521f6ecabSRudolf Cornelissen }
115621f6ecabSRudolf Cornelissen
115721f6ecabSRudolf Cornelissen /* CX: Wait 600uS for signals to stabilize (see datasheet) */
115821f6ecabSRudolf Cornelissen /* warning, note:
115921f6ecabSRudolf Cornelissen * datasheet is in error! 60mS needed!! */
116021f6ecabSRudolf Cornelissen snooze(60000);
116121f6ecabSRudolf Cornelissen
116221f6ecabSRudolf Cornelissen /* read back updated connection status: */
116321f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + RD;
116421f6ecabSRudolf Cornelissen
116521f6ecabSRudolf Cornelissen /* transmit 1 byte */
116621f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
116721f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 1);
116821f6ecabSRudolf Cornelissen
116921f6ecabSRudolf Cornelissen /* receive 1 byte */
11709a7218c5SRudolf Cornelissen /* ACK level to TX after last byte to RX should be 1 (= NACK) (see I2C spec)
117121f6ecabSRudolf Cornelissen * While the BT's don't care, CX chips will block the SDA line if an ACK gets sent! */
117221f6ecabSRudolf Cornelissen buffer[0] = 1;
117321f6ecabSRudolf Cornelissen i2c_readbuffer(si->ps.tv_encoder.bus, buffer, 1);
117421f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
117521f6ecabSRudolf Cornelissen /* log on errors */
117621f6ecabSRudolf Cornelissen stat = i2c_flag_error(0);
117721f6ecabSRudolf Cornelissen if (stat)
117821f6ecabSRudolf Cornelissen {
117921f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while reading connection status (3)\n"));
118021f6ecabSRudolf Cornelissen return stat;
118121f6ecabSRudolf Cornelissen }
118221f6ecabSRudolf Cornelissen
118321f6ecabSRudolf Cornelissen *monstat = ((buffer[0] & 0xe0) >> 5);
118421f6ecabSRudolf Cornelissen LOG(4,("Brooktree: TV output monitor status = %d\n", *monstat));
118521f6ecabSRudolf Cornelissen
118621f6ecabSRudolf Cornelissen /* instruct BT to go back to normal operation: */
118721f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR;
118821f6ecabSRudolf Cornelissen /* select register with CHECK_STAT CMD */
118921f6ecabSRudolf Cornelissen buffer[1] = 0xba;
119021f6ecabSRudolf Cornelissen /* issue actual command. */
119121f6ecabSRudolf Cornelissen buffer[2] = 0x00;
119221f6ecabSRudolf Cornelissen
119321f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
119421f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
119521f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
119621f6ecabSRudolf Cornelissen /* log on errors */
119721f6ecabSRudolf Cornelissen stat = i2c_flag_error(0);
119821f6ecabSRudolf Cornelissen if (stat)
119921f6ecabSRudolf Cornelissen {
120021f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while reading connection status (4)\n"));
120121f6ecabSRudolf Cornelissen return stat;
120221f6ecabSRudolf Cornelissen }
120321f6ecabSRudolf Cornelissen
120421f6ecabSRudolf Cornelissen return stat;
120521f6ecabSRudolf Cornelissen }//end BT_read_monstat.
120621f6ecabSRudolf Cornelissen
BT_killclk_blackout(void)120721f6ecabSRudolf Cornelissen static uint8 BT_killclk_blackout(void)
120821f6ecabSRudolf Cornelissen {
120921f6ecabSRudolf Cornelissen uint8 stat;
121021f6ecabSRudolf Cornelissen
121121f6ecabSRudolf Cornelissen uint8 buffer[4];
121221f6ecabSRudolf Cornelissen
12139a7218c5SRudolf Cornelissen LOG(4,("Brooktree: Killing clock and/or blacking out (blocking output signals)\n"));
12149a7218c5SRudolf Cornelissen
121521f6ecabSRudolf Cornelissen /* reset status */
121621f6ecabSRudolf Cornelissen i2c_flag_error (-1);
121721f6ecabSRudolf Cornelissen
121821f6ecabSRudolf Cornelissen if (si->ps.tv_encoder.type <= BT869) //BT...
121921f6ecabSRudolf Cornelissen {
122021f6ecabSRudolf Cornelissen /* Only disable external pixelclock input on BT's.
122121f6ecabSRudolf Cornelissen * CX chips will lock the bus if you do this.
122221f6ecabSRudolf Cornelissen * (It looks like the external pixelclock is always OK as long as a valid
122321f6ecabSRudolf Cornelissen * mode is programmed for the TVout chip. This means that disabling the use
122421f6ecabSRudolf Cornelissen * of this clock is not needed anyway.
122521f6ecabSRudolf Cornelissen * If you do disable this input, this pixelclock will rise to about 60Mhz BTW..) */
122621f6ecabSRudolf Cornelissen
122721f6ecabSRudolf Cornelissen /* disable use of external pixelclock source... */
122821f6ecabSRudolf Cornelissen /* (should prevent BT for being 'overclocked' by RIVA in VGA-only mode...) */
122921f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR;
123021f6ecabSRudolf Cornelissen /* select BT register for setting EN_XCLK */
123121f6ecabSRudolf Cornelissen buffer[1] = 0xa0;
123221f6ecabSRudolf Cornelissen /* clear it */
123321f6ecabSRudolf Cornelissen buffer[2] = 0x00;
123421f6ecabSRudolf Cornelissen
123521f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
123621f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3);
123721f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
123821f6ecabSRudolf Cornelissen /* log on errors */
123921f6ecabSRudolf Cornelissen stat = i2c_flag_error(0);
124021f6ecabSRudolf Cornelissen if (stat)
124121f6ecabSRudolf Cornelissen {
124221f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (1-BT)\n"));
124321f6ecabSRudolf Cornelissen return stat;
124421f6ecabSRudolf Cornelissen }
124521f6ecabSRudolf Cornelissen }
124621f6ecabSRudolf Cornelissen else //CX...
124721f6ecabSRudolf Cornelissen {
124821f6ecabSRudolf Cornelissen /* Disable CX video out (or wild output will be seen on TV..) */
124921f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR;
125021f6ecabSRudolf Cornelissen /* select register in CX */
125121f6ecabSRudolf Cornelissen buffer[1] = 0x6c;
125221f6ecabSRudolf Cornelissen /* disable active video out. */
125321f6ecabSRudolf Cornelissen buffer[2] = 0x02;
125421f6ecabSRudolf Cornelissen
125521f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
125621f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3);
125721f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
125821f6ecabSRudolf Cornelissen /* log on errors */
125921f6ecabSRudolf Cornelissen stat = i2c_flag_error(0);
126021f6ecabSRudolf Cornelissen if (stat)
126121f6ecabSRudolf Cornelissen {
126221f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (1-CX)\n"));
126321f6ecabSRudolf Cornelissen return stat;
126421f6ecabSRudolf Cornelissen }
126521f6ecabSRudolf Cornelissen }
126621f6ecabSRudolf Cornelissen
126721f6ecabSRudolf Cornelissen /* black-out TVout while outputs are enabled... */
126821f6ecabSRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR;
126921f6ecabSRudolf Cornelissen /* select first TV config register to write */
127021f6ecabSRudolf Cornelissen buffer[1] = 0xc4;
127121f6ecabSRudolf Cornelissen /* disable testimage while outputs remain enabled */
127221f6ecabSRudolf Cornelissen buffer[2] = 0x01;
127321f6ecabSRudolf Cornelissen /* input is 24bit mpx'd RGB, BLANK = in, sync = act. hi */
127421f6ecabSRudolf Cornelissen buffer[3] = 0x18;
127521f6ecabSRudolf Cornelissen
127621f6ecabSRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
127721f6ecabSRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
127821f6ecabSRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
127921f6ecabSRudolf Cornelissen /* log on errors */
128021f6ecabSRudolf Cornelissen stat = i2c_flag_error(0);
128121f6ecabSRudolf Cornelissen if (stat)
128221f6ecabSRudolf Cornelissen {
128321f6ecabSRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (2)\n"));
128421f6ecabSRudolf Cornelissen return stat;
128521f6ecabSRudolf Cornelissen }
128621f6ecabSRudolf Cornelissen
128721f6ecabSRudolf Cornelissen return stat;
128821f6ecabSRudolf Cornelissen }//end BT_killclk_blackout.
128921f6ecabSRudolf Cornelissen
BT_dpms(bool display)12903aa21459SRudolf Cornelissen uint8 BT_dpms(bool display)
12913aa21459SRudolf Cornelissen {
12923aa21459SRudolf Cornelissen uint8 stat;
12933aa21459SRudolf Cornelissen
12943aa21459SRudolf Cornelissen uint8 buffer[3];
12953aa21459SRudolf Cornelissen
12963aa21459SRudolf Cornelissen LOG(4,("Brooktree: setting DPMS: "));
12973aa21459SRudolf Cornelissen
12983aa21459SRudolf Cornelissen /* reset status */
12993aa21459SRudolf Cornelissen i2c_flag_error (-1);
13003aa21459SRudolf Cornelissen
13013aa21459SRudolf Cornelissen /* shutdown all analog electronics... */
13023aa21459SRudolf Cornelissen buffer[0] = si->ps.tv_encoder.adress + WR;
13033aa21459SRudolf Cornelissen /* select first TV config register to write */
13043aa21459SRudolf Cornelissen buffer[1] = 0xba;
13053aa21459SRudolf Cornelissen if (display)
13063aa21459SRudolf Cornelissen {
13073aa21459SRudolf Cornelissen /* enable all DACs */
13083aa21459SRudolf Cornelissen buffer[2] = 0x00;
13093aa21459SRudolf Cornelissen LOG(4,("display on\n"));
13103aa21459SRudolf Cornelissen }
13113aa21459SRudolf Cornelissen else
13123aa21459SRudolf Cornelissen {
13133aa21459SRudolf Cornelissen /* shutdown all DACs */
13143aa21459SRudolf Cornelissen buffer[2] = 0x10;
13153aa21459SRudolf Cornelissen LOG(4,("display off\n"));
13163aa21459SRudolf Cornelissen }
13173aa21459SRudolf Cornelissen
13183aa21459SRudolf Cornelissen i2c_bstart(si->ps.tv_encoder.bus);
13193aa21459SRudolf Cornelissen i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3);
13203aa21459SRudolf Cornelissen i2c_bstop(si->ps.tv_encoder.bus);
13213aa21459SRudolf Cornelissen /* log on errors */
13223aa21459SRudolf Cornelissen stat = i2c_flag_error(0);
13233aa21459SRudolf Cornelissen if (stat)
13243aa21459SRudolf Cornelissen {
13253aa21459SRudolf Cornelissen LOG(4,("Brooktree: I2C errors occurred while setting DPMS\n"));
13263aa21459SRudolf Cornelissen return stat;
13273aa21459SRudolf Cornelissen }
13283aa21459SRudolf Cornelissen
13293aa21459SRudolf Cornelissen return stat;
13303aa21459SRudolf Cornelissen }//end BT_dpms.
13313aa21459SRudolf Cornelissen
BT_check_tvmode(display_mode target)1332b2459715SRudolf Cornelissen uint8 BT_check_tvmode(display_mode target)
1333fb6cadf1Sshatty {
1334b2459715SRudolf Cornelissen uint8 status = NOT_SUPPORTED;
1335b2459715SRudolf Cornelissen uint32 mode = ((target.timing.h_display) | ((target.timing.v_display) << 16));
1336b2459715SRudolf Cornelissen
1337b2459715SRudolf Cornelissen switch (mode)
1338b2459715SRudolf Cornelissen {
1339b2459715SRudolf Cornelissen case (640 | (480 << 16)):
1340c5fe5f2dSRudolf Cornelissen if (((target.flags & TV_BITS) == TV_PAL) && (!(target.flags & TV_VIDEO)))
1341c5fe5f2dSRudolf Cornelissen status = PAL640;
1342b2459715SRudolf Cornelissen if ((target.flags & TV_BITS) == TV_NTSC)
1343b2459715SRudolf Cornelissen {
1344b2459715SRudolf Cornelissen if (!(target.flags & TV_VIDEO)) status = NTSC640;
1345b2459715SRudolf Cornelissen else status = NTSC640_OS;
1346b2459715SRudolf Cornelissen }
1347b2459715SRudolf Cornelissen break;
1348c5fe5f2dSRudolf Cornelissen case (768 | (576 << 16)):
1349c5fe5f2dSRudolf Cornelissen if (((target.flags & TV_BITS) == TV_PAL) && (target.flags & TV_VIDEO))
1350c5fe5f2dSRudolf Cornelissen status = PAL800_OS;
1351c5fe5f2dSRudolf Cornelissen break;
1352b2459715SRudolf Cornelissen case (800 | (600 << 16)):
1353c5fe5f2dSRudolf Cornelissen if (((target.flags & TV_BITS) == TV_PAL) && (!(target.flags & TV_VIDEO)))
1354c5fe5f2dSRudolf Cornelissen status = PAL800;
1355c5fe5f2dSRudolf Cornelissen if (((target.flags & TV_BITS) == TV_NTSC) && (!(target.flags & TV_VIDEO)))
1356c5fe5f2dSRudolf Cornelissen status = NTSC800;
1357b2459715SRudolf Cornelissen break;
1358b2459715SRudolf Cornelissen case (720 | (480 << 16)):
1359b2459715SRudolf Cornelissen if (((target.flags & TV_BITS) == TV_NTSC) && (target.flags & TV_VIDEO))
1360b2459715SRudolf Cornelissen status = NTSC720;
1361b2459715SRudolf Cornelissen break;
1362b2459715SRudolf Cornelissen case (720 | (576 << 16)):
1363b2459715SRudolf Cornelissen if (((target.flags & TV_BITS) == TV_PAL) && (target.flags & TV_VIDEO))
1364b2459715SRudolf Cornelissen status = PAL720;
1365b2459715SRudolf Cornelissen break;
1366b2459715SRudolf Cornelissen }
1367b2459715SRudolf Cornelissen
1368b2459715SRudolf Cornelissen return status;
1369b2459715SRudolf Cornelissen }//end BT_check_tvmode.
1370b2459715SRudolf Cornelissen
1371bd7693f2SRudolf Cornelissen
1372bd7693f2SRudolf Cornelissen /*
1373da3804eeSRudolf Cornelissen //BeTVOut's SwitchRIVAtoTV(vtot) timing formula: (note: vtot = (v_total - 2))
1374bd7693f2SRudolf Cornelissen //-----------------------------------------------------------------------------------
1375bd7693f2SRudolf Cornelissen //HORIZONTAL:
1376bd7693f2SRudolf Cornelissen //-----------
1377bd7693f2SRudolf Cornelissen h_sync_start = h_display;
1378bd7693f2SRudolf Cornelissen
1379bd7693f2SRudolf Cornelissen //fixme, note, checkout:
1380bd7693f2SRudolf Cornelissen //feels like in fact TNT2-M64 nv_crtc.c registerprogramming should be adapted...
1381bd7693f2SRudolf Cornelissen if (TNT2-M64)
1382bd7693f2SRudolf Cornelissen {
1383bd7693f2SRudolf Cornelissen h_sync_end = h_display + 8;
1384bd7693f2SRudolf Cornelissen h_total = h_display + 56;
1385bd7693f2SRudolf Cornelissen }
1386bd7693f2SRudolf Cornelissen else //TNT1, TNT2, Geforce2... (so default)
1387bd7693f2SRudolf Cornelissen {
1388bd7693f2SRudolf Cornelissen h_sync_end = h_display + 16;
1389bd7693f2SRudolf Cornelissen h_total = h_display + 48;
1390bd7693f2SRudolf Cornelissen }
1391bd7693f2SRudolf Cornelissen
1392bd7693f2SRudolf Cornelissen //fixme, note, checkout:
1393bd7693f2SRudolf Cornelissen //BeTVOut uses two 'tweaks':
1394bd7693f2SRudolf Cornelissen // - on TNT2-M64 only:
1395bd7693f2SRudolf Cornelissen // register h_blank_e is increased with 1 (so should be done in nv_crtc.c here)
1396463f0fabSRudolf Cornelissen // - 'all cards':
1397463f0fabSRudolf Cornelissen // register h_blank_e b6 = 0 (only influences TNT2-M64 in modes NTSC800 and PAL800).
1398bd7693f2SRudolf Cornelissen //-----------------------------------------------------------------------------------
1399bd7693f2SRudolf Cornelissen //VERTICAL:
1400bd7693f2SRudolf Cornelissen //---------
1401da3804eeSRudolf Cornelissen v_sync_start = v_display;
1402da3804eeSRudolf Cornelissen v_total = vtot + 2;
1403da3804eeSRudolf Cornelissen v_sync_end = v_total - 1; //(This takes care of the 'cursor trash' on TNT1's...)
1404bd7693f2SRudolf Cornelissen //-----------------------------------------------------------------------------------
1405bd7693f2SRudolf Cornelissen */
BT_update_mode_for_gpu(display_mode * target,uint8 tvmode)140685406c4dSRudolf Cornelissen static status_t BT_update_mode_for_gpu(display_mode *target, uint8 tvmode)
140785406c4dSRudolf Cornelissen {
1408b0fce481SRudolf Cornelissen //fixme if needed:
1409b0fce481SRudolf Cornelissen //pixelclock is not actually pgm'd because PLL is pgm' earlier during setmode...
141085406c4dSRudolf Cornelissen switch (tvmode)
141185406c4dSRudolf Cornelissen {
141285406c4dSRudolf Cornelissen case NTSC640:
141385406c4dSRudolf Cornelissen case NTSC640_TST:
1414bd7693f2SRudolf Cornelissen target->timing.h_display = 640;
1415bd7693f2SRudolf Cornelissen target->timing.h_sync_start = 640;
1416bd7693f2SRudolf Cornelissen if (si->ps.card_type == NV05M64)
1417bd7693f2SRudolf Cornelissen {
1418bd7693f2SRudolf Cornelissen target->timing.h_sync_end = 648;
1419bd7693f2SRudolf Cornelissen target->timing.h_total = 696;
1420bd7693f2SRudolf Cornelissen }
1421bd7693f2SRudolf Cornelissen else
1422bd7693f2SRudolf Cornelissen {
14234e918a7cSRudolf Cornelissen //fixme if possible:
14244e918a7cSRudolf Cornelissen //see if tweaking h_sync_end can shift picture 8 pixels right to fix
14254e918a7cSRudolf Cornelissen //ws tv's tuning fault (always going for max. compatibility :)
1426bd7693f2SRudolf Cornelissen target->timing.h_sync_end = 656;
1427bd7693f2SRudolf Cornelissen target->timing.h_total = 688;
1428bd7693f2SRudolf Cornelissen }
1429bd7693f2SRudolf Cornelissen target->timing.v_display = 480;
1430da3804eeSRudolf Cornelissen target->timing.v_sync_start = 480;
1431da3804eeSRudolf Cornelissen target->timing.v_sync_end = 555; //This prevents 'cursor trash' on TNT1's
1432da3804eeSRudolf Cornelissen target->timing.v_total = 556; //Above 525 because mode scales down
1433da3804eeSRudolf Cornelissen if (si->ps.card_type == NV05M64)
1434da3804eeSRudolf Cornelissen target->timing.pixel_clock = ((696 * 556 * 60) / 1000);
1435da3804eeSRudolf Cornelissen else
1436da3804eeSRudolf Cornelissen target->timing.pixel_clock = ((688 * 556 * 60) / 1000);
143785406c4dSRudolf Cornelissen break;
143885406c4dSRudolf Cornelissen case NTSC800:
1439da3804eeSRudolf Cornelissen target->timing.h_display = 800;
1440da3804eeSRudolf Cornelissen target->timing.h_sync_start = 800;
1441da3804eeSRudolf Cornelissen if (si->ps.card_type == NV05M64)
1442da3804eeSRudolf Cornelissen {
1443da3804eeSRudolf Cornelissen target->timing.h_sync_end = 808;
1444da3804eeSRudolf Cornelissen target->timing.h_total = 856;
1445da3804eeSRudolf Cornelissen }
1446da3804eeSRudolf Cornelissen else
1447da3804eeSRudolf Cornelissen {
1448da3804eeSRudolf Cornelissen target->timing.h_sync_end = 816;
1449da3804eeSRudolf Cornelissen target->timing.h_total = 848;
1450da3804eeSRudolf Cornelissen }
1451da3804eeSRudolf Cornelissen target->timing.v_display = 600;
1452da3804eeSRudolf Cornelissen target->timing.v_sync_start = 600;
1453da3804eeSRudolf Cornelissen target->timing.v_sync_end = 685; //This prevents 'cursor trash' on TNT1's
1454da3804eeSRudolf Cornelissen target->timing.v_total = 686; //Above 525 because mode scales down
1455da3804eeSRudolf Cornelissen if (si->ps.card_type == NV05M64)
1456da3804eeSRudolf Cornelissen target->timing.pixel_clock = ((856 * 686 * 60) / 1000);
1457da3804eeSRudolf Cornelissen else
1458da3804eeSRudolf Cornelissen target->timing.pixel_clock = ((848 * 686 * 60) / 1000);
145985406c4dSRudolf Cornelissen break;
146085406c4dSRudolf Cornelissen case PAL640:
1461bd7693f2SRudolf Cornelissen target->timing.h_display = 640;
1462da3804eeSRudolf Cornelissen target->timing.h_sync_start = 640;
1463da3804eeSRudolf Cornelissen if (si->ps.card_type == NV05M64)
1464da3804eeSRudolf Cornelissen {
1465da3804eeSRudolf Cornelissen target->timing.h_sync_end = 648;
1466da3804eeSRudolf Cornelissen target->timing.h_total = 696;
1467da3804eeSRudolf Cornelissen }
1468da3804eeSRudolf Cornelissen else
1469da3804eeSRudolf Cornelissen {
1470da3804eeSRudolf Cornelissen target->timing.h_sync_end = 656;
1471da3804eeSRudolf Cornelissen target->timing.h_total = 688;
1472da3804eeSRudolf Cornelissen }
1473bd7693f2SRudolf Cornelissen target->timing.v_display = 480;
1474da3804eeSRudolf Cornelissen target->timing.v_sync_start = 480;
1475da3804eeSRudolf Cornelissen target->timing.v_sync_end = 570; //This prevents 'cursor trash' on TNT1's
1476da3804eeSRudolf Cornelissen target->timing.v_total = 571; //Below 625 because mode scales up
1477da3804eeSRudolf Cornelissen if (si->ps.card_type == NV05M64)
1478da3804eeSRudolf Cornelissen target->timing.pixel_clock = ((696 * 571 * 50) / 1000);
1479da3804eeSRudolf Cornelissen else
1480da3804eeSRudolf Cornelissen target->timing.pixel_clock = ((688 * 571 * 50) / 1000);
148185406c4dSRudolf Cornelissen break;
148285406c4dSRudolf Cornelissen case PAL800:
148385406c4dSRudolf Cornelissen case PAL800_TST:
1484da3804eeSRudolf Cornelissen target->timing.h_display = 800;
1485da3804eeSRudolf Cornelissen target->timing.h_sync_start = 800;
1486da3804eeSRudolf Cornelissen if (si->ps.card_type == NV05M64)
1487da3804eeSRudolf Cornelissen {
1488da3804eeSRudolf Cornelissen target->timing.h_sync_end = 808;
1489da3804eeSRudolf Cornelissen target->timing.h_total = 856;
1490da3804eeSRudolf Cornelissen }
1491da3804eeSRudolf Cornelissen else
1492da3804eeSRudolf Cornelissen {
1493da3804eeSRudolf Cornelissen target->timing.h_sync_end = 816;
1494da3804eeSRudolf Cornelissen target->timing.h_total = 848;
1495da3804eeSRudolf Cornelissen }
1496da3804eeSRudolf Cornelissen target->timing.v_display = 600;
1497da3804eeSRudolf Cornelissen target->timing.v_sync_start = 600;
1498da3804eeSRudolf Cornelissen target->timing.v_sync_end = 695; //This prevents 'cursor trash' on TNT1's
1499da3804eeSRudolf Cornelissen target->timing.v_total = 696; //Above 625 because mode scales down
1500da3804eeSRudolf Cornelissen if (si->ps.card_type == NV05M64)
1501da3804eeSRudolf Cornelissen target->timing.pixel_clock = ((856 * 696 * 50) / 1000);
1502da3804eeSRudolf Cornelissen else
1503da3804eeSRudolf Cornelissen target->timing.pixel_clock = ((848 * 696 * 50) / 1000);
150485406c4dSRudolf Cornelissen break;
150585406c4dSRudolf Cornelissen case NTSC640_OS:
150685406c4dSRudolf Cornelissen target->timing.h_display = 640; //BT H_ACTIVE
150785406c4dSRudolf Cornelissen target->timing.h_sync_start = 744; //set for CH/BT compatible TV output
150885406c4dSRudolf Cornelissen target->timing.h_sync_end = 744+20; //delta is BT H_BLANKI
150985406c4dSRudolf Cornelissen target->timing.h_total = 784; //BT H_CLKI
151085406c4dSRudolf Cornelissen target->timing.v_display = 480; //BT V_ACTIVEI
151185406c4dSRudolf Cornelissen target->timing.v_sync_start = 490; //set for centered sync pulse
151285406c4dSRudolf Cornelissen target->timing.v_sync_end = 490+25; //delta is BT V_BLANKI
1513da3804eeSRudolf Cornelissen target->timing.v_total = 525; //BT V_LINESI (== 525: 1:1 scaled mode)
151485406c4dSRudolf Cornelissen target->timing.pixel_clock = ((784 * 525 * 60) / 1000); //refresh
151585406c4dSRudolf Cornelissen break;
151685406c4dSRudolf Cornelissen case PAL800_OS:
151785406c4dSRudolf Cornelissen target->timing.h_display = 768; //H_ACTIVE
15186245f19cSRudolf Cornelissen if (si->ps.tv_encoder.type <= BT869)
15196245f19cSRudolf Cornelissen {
15204e918a7cSRudolf Cornelissen /* confirmed on TNT1 using 4:3 TV and 16:9 TV */
15216245f19cSRudolf Cornelissen target->timing.h_sync_start = 856; //set for centered TV output
15226245f19cSRudolf Cornelissen target->timing.h_sync_end = 856+20; //delta is BT H_BLANKI
15236245f19cSRudolf Cornelissen }
15246245f19cSRudolf Cornelissen else
15256245f19cSRudolf Cornelissen {
1526195828c4SRudolf Cornelissen /* confirmed on NV11 using 4:3 TV and 16:9 TV */
152785406c4dSRudolf Cornelissen target->timing.h_sync_start = 848; //set for centered TV output
152885406c4dSRudolf Cornelissen target->timing.h_sync_end = 848+20; //delta is BT H_BLANKI
15296245f19cSRudolf Cornelissen }
153085406c4dSRudolf Cornelissen target->timing.h_total = 944; //BT H_CLKI
153185406c4dSRudolf Cornelissen target->timing.v_display = 576; //V_ACTIVEI
153285406c4dSRudolf Cornelissen target->timing.v_sync_start = 579; //set for centered sync pulse
153385406c4dSRudolf Cornelissen target->timing.v_sync_end = 579+42; //delta is BT V_BLANKI
1534da3804eeSRudolf Cornelissen target->timing.v_total = 625; //BT V_LINESI (== 625: 1:1 scaled mode)
153585406c4dSRudolf Cornelissen target->timing.pixel_clock = ((944 * 625 * 50) / 1000); //refresh
153685406c4dSRudolf Cornelissen break;
153785406c4dSRudolf Cornelissen case NTSC720:
153885406c4dSRudolf Cornelissen /* (tested on TNT2 with BT869) */
153985406c4dSRudolf Cornelissen target->timing.h_display = 720; //H_ACTIVE
15405cadaa5fSRudolf Cornelissen if (si->ps.tv_encoder.type <= BT869)
15415cadaa5fSRudolf Cornelissen {
15425cadaa5fSRudolf Cornelissen /* confirmed on TNT1 using 4:3 TV and 16:9 TV */
154385406c4dSRudolf Cornelissen target->timing.h_sync_start = 744; //do not change!
154485406c4dSRudolf Cornelissen target->timing.h_sync_end = 744+144; //delta is H_sync_pulse
15455cadaa5fSRudolf Cornelissen }
15465cadaa5fSRudolf Cornelissen else
15475cadaa5fSRudolf Cornelissen {
1548195828c4SRudolf Cornelissen /* confirmed on NV11 using 4:3 TV and 16:9 TV */
15495cadaa5fSRudolf Cornelissen target->timing.h_sync_start = 728; //do not change!
15505cadaa5fSRudolf Cornelissen target->timing.h_sync_end = 728+160; //delta is H_sync_pulse
15515cadaa5fSRudolf Cornelissen }
155285406c4dSRudolf Cornelissen target->timing.h_total = 888; //BT H_TOTAL
155385406c4dSRudolf Cornelissen target->timing.v_display = 480; //V_ACTIVEI
155485406c4dSRudolf Cornelissen target->timing.v_sync_start = 490; //set for centered sync pulse
155585406c4dSRudolf Cornelissen target->timing.v_sync_end = 490+26; //delta is V_sync_pulse
1556da3804eeSRudolf Cornelissen target->timing.v_total = 525; //CH V_TOTAL (== 525: 1:1 scaled mode)
155785406c4dSRudolf Cornelissen target->timing.pixel_clock = ((888 * 525 * 60) / 1000); //refresh
155885406c4dSRudolf Cornelissen break;
155985406c4dSRudolf Cornelissen case PAL720:
156085406c4dSRudolf Cornelissen target->timing.h_display = 720; //BT H_ACTIVE
156185406c4dSRudolf Cornelissen target->timing.h_sync_start = 744; //set for centered sync pulse
156285406c4dSRudolf Cornelissen target->timing.h_sync_end = 744+140; //delta is BT H_BLANKI
156385406c4dSRudolf Cornelissen target->timing.h_total = 888; //BT H_CLKI
156485406c4dSRudolf Cornelissen target->timing.v_display = 576; //BT V_ACTIVEI
156585406c4dSRudolf Cornelissen target->timing.v_sync_start = 579; //set for centered sync pulse
156685406c4dSRudolf Cornelissen target->timing.v_sync_end = 579+42; //delta is BT V_BLANKI
1567da3804eeSRudolf Cornelissen target->timing.v_total = 625; //BT V_LINESI (== 625: 1:1 scaled mode)
156885406c4dSRudolf Cornelissen target->timing.pixel_clock = ((888 * 625 * 50) / 1000); //refresh
156985406c4dSRudolf Cornelissen break;
157085406c4dSRudolf Cornelissen default:
157185406c4dSRudolf Cornelissen return B_ERROR;
157285406c4dSRudolf Cornelissen }
157385406c4dSRudolf Cornelissen
157485406c4dSRudolf Cornelissen return B_OK;
157585406c4dSRudolf Cornelissen }//end BT_update_mode_for_gpu.
157685406c4dSRudolf Cornelissen
157722a0d15bSRudolf Cornelissen /* note:
157822a0d15bSRudolf Cornelissen * tested on ELSA Erazor III 32Mb AGP (TNT2/BT869),
157922a0d15bSRudolf Cornelissen * Diamond Viper V550 16Mb PCI (TNT1/BT869),
158022a0d15bSRudolf Cornelissen * and ASUS V7100 GeForce2 MX200 AGP/32Mb (CH7007). */
BT_start_tvout(display_mode tv_target)158191731297SRudolf Cornelissen static status_t BT_start_tvout(display_mode tv_target)
158222a0d15bSRudolf Cornelissen {
15833c71b494SRudolf Cornelissen /* TV_PRIMARY tells us that the head to be used with TVout is the head that's
15843c71b494SRudolf Cornelissen * actually assigned as being the primary head at powerup:
15853c71b494SRudolf Cornelissen * so non dualhead-mode-dependant, and not 'fixed' CRTC1! */
1586d7dfe68dSRudolf Cornelissen if (tv_target.flags & TV_PRIMARY)
15873c71b494SRudolf Cornelissen {
15883c71b494SRudolf Cornelissen if ((tv_target.flags & DUALHEAD_BITS) != DUALHEAD_SWITCH)
1589c0ebc619SRudolf Cornelissen head1_start_tvout();
1590d7dfe68dSRudolf Cornelissen else
1591c0ebc619SRudolf Cornelissen head2_start_tvout();
15923c71b494SRudolf Cornelissen }
15933c71b494SRudolf Cornelissen else
15943c71b494SRudolf Cornelissen {
15953c71b494SRudolf Cornelissen if ((tv_target.flags & DUALHEAD_BITS) != DUALHEAD_SWITCH)
15963c71b494SRudolf Cornelissen head2_start_tvout();
15973c71b494SRudolf Cornelissen else
15983c71b494SRudolf Cornelissen head1_start_tvout();
15993c71b494SRudolf Cornelissen }
160022a0d15bSRudolf Cornelissen
160122a0d15bSRudolf Cornelissen return B_OK;
160222a0d15bSRudolf Cornelissen }//end BT_start_tvout.
160322a0d15bSRudolf Cornelissen
1604bd419083SRudolf Cornelissen /* note:
1605bd419083SRudolf Cornelissen * tested on ELSA Erazor III 32Mb AGP (TNT2/BT869),
1606bd419083SRudolf Cornelissen * Diamond Viper V550 16Mb PCI (TNT1/BT869),
1607bd419083SRudolf Cornelissen * and ASUS V7100 GeForce2 MX200 AGP/32Mb (CH7007). */
BT_stop_tvout(void)160822a0d15bSRudolf Cornelissen status_t BT_stop_tvout(void)
160922a0d15bSRudolf Cornelissen {
161022a0d15bSRudolf Cornelissen /* prevent BT from being overclocked by VGA-only modes & black-out TV-out */
161122a0d15bSRudolf Cornelissen BT_killclk_blackout();
161222a0d15bSRudolf Cornelissen
16133c71b494SRudolf Cornelissen /* TV_PRIMARY tells us that the head to be used with TVout is the head that's
16143c71b494SRudolf Cornelissen * actually assigned as being the primary head at powerup:
16153c71b494SRudolf Cornelissen * so non dualhead-mode-dependant, and not 'fixed' CRTC1! */
1616d7dfe68dSRudolf Cornelissen if (si->dm.flags & TV_PRIMARY)
16173c71b494SRudolf Cornelissen {
16183c71b494SRudolf Cornelissen if ((si->dm.flags & DUALHEAD_BITS) != DUALHEAD_SWITCH)
1619c0ebc619SRudolf Cornelissen head1_stop_tvout();
1620d7dfe68dSRudolf Cornelissen else
1621c0ebc619SRudolf Cornelissen head2_stop_tvout();
16223c71b494SRudolf Cornelissen }
16233c71b494SRudolf Cornelissen else
16243c71b494SRudolf Cornelissen {
16253c71b494SRudolf Cornelissen if ((si->dm.flags & DUALHEAD_BITS) != DUALHEAD_SWITCH)
16263c71b494SRudolf Cornelissen head2_stop_tvout();
16273c71b494SRudolf Cornelissen else
16283c71b494SRudolf Cornelissen head1_stop_tvout();
16293c71b494SRudolf Cornelissen }
163022a0d15bSRudolf Cornelissen
163122a0d15bSRudolf Cornelissen /* fixme if needed:
163222a0d15bSRudolf Cornelissen * a full encoder chip reset could be done here (so after decoupling crtc)... */
1633b0fce481SRudolf Cornelissen /* (but: beware of the 'locked SDA' syndrome then!) */
163422a0d15bSRudolf Cornelissen
1635*4022652cSRudolf Cornelissen /* fixme if needed: we _could_ setup a TVout mode and apply the testsignal here... */
1636*4022652cSRudolf Cornelissen if (0)
1637*4022652cSRudolf Cornelissen {
1638*4022652cSRudolf Cornelissen //set mode (selecting PAL/NTSC according to board wiring for example) etc, then:
1639*4022652cSRudolf Cornelissen BT_testsignal();
1640*4022652cSRudolf Cornelissen }
1641*4022652cSRudolf Cornelissen
164222a0d15bSRudolf Cornelissen return B_OK;
1643bd419083SRudolf Cornelissen }//end BT_stop_tvout.
164422a0d15bSRudolf Cornelissen
BT_setmode(display_mode target)1645b2459715SRudolf Cornelissen status_t BT_setmode(display_mode target)
1646b2459715SRudolf Cornelissen {
1647efe9c7a6SRudolf Cornelissen uint8 tvmode, monstat;
1648efe9c7a6SRudolf Cornelissen /* enable flickerfilter in desktop modes, disable it in video modes. */
1649efe9c7a6SRudolf Cornelissen uint8 ffilter = 0;
1650b2459715SRudolf Cornelissen
1651fb6cadf1Sshatty /* use a display_mode copy because we might tune it for TVout compatibility */
1652fb6cadf1Sshatty display_mode tv_target = target;
1653fb6cadf1Sshatty
1654fb6cadf1Sshatty /* preset new TVout mode */
1655b2459715SRudolf Cornelissen tvmode = BT_check_tvmode(tv_target);
1656b2459715SRudolf Cornelissen if (!tvmode) return B_ERROR;
1657b2459715SRudolf Cornelissen
1658efe9c7a6SRudolf Cornelissen /* read current output devices connection status */
1659efe9c7a6SRudolf Cornelissen BT_read_monstat(&monstat);
1660efe9c7a6SRudolf Cornelissen
1661efe9c7a6SRudolf Cornelissen /* (pre)set TV mode */
1662efe9c7a6SRudolf Cornelissen /* note:
1663efe9c7a6SRudolf Cornelissen * Manual config is non-dependent of the state of the PAL hardware input pin;
1664efe9c7a6SRudolf Cornelissen * Also SDA lockups occur when setting EN_XCLK after autoconfig!
1665efe9c7a6SRudolf Cornelissen * Make sure PAL_MD=0 for NTSC and PAL_MD = 1 for PAL... */
1666b2459715SRudolf Cornelissen switch (tvmode)
1667fb6cadf1Sshatty {
1668b2459715SRudolf Cornelissen case NTSC640:
1669b2459715SRudolf Cornelissen case NTSC640_TST:
1670efe9c7a6SRudolf Cornelissen ffilter = 1;
1671efe9c7a6SRudolf Cornelissen BT_init_NTSC640();
1672b2459715SRudolf Cornelissen break;
1673b2459715SRudolf Cornelissen case NTSC800:
1674efe9c7a6SRudolf Cornelissen ffilter = 1;
1675efe9c7a6SRudolf Cornelissen BT_init_NTSC800();
1676b2459715SRudolf Cornelissen break;
1677b2459715SRudolf Cornelissen case PAL640:
1678efe9c7a6SRudolf Cornelissen ffilter = 1;
1679efe9c7a6SRudolf Cornelissen BT_init_PAL640();
1680b2459715SRudolf Cornelissen break;
1681b2459715SRudolf Cornelissen case PAL800:
1682b2459715SRudolf Cornelissen case PAL800_TST:
1683efe9c7a6SRudolf Cornelissen ffilter = 1;
1684efe9c7a6SRudolf Cornelissen BT_init_PAL800();
1685b2459715SRudolf Cornelissen break;
1686b2459715SRudolf Cornelissen case NTSC640_OS:
1687efe9c7a6SRudolf Cornelissen BT_init_NTSC640_OS();
1688b2459715SRudolf Cornelissen break;
1689b2459715SRudolf Cornelissen case PAL800_OS:
1690efe9c7a6SRudolf Cornelissen BT_init_PAL800_OS();
1691b2459715SRudolf Cornelissen break;
1692b2459715SRudolf Cornelissen case NTSC720:
1693efe9c7a6SRudolf Cornelissen BT_init_NTSC720();
1694b2459715SRudolf Cornelissen break;
1695b2459715SRudolf Cornelissen case PAL720:
1696efe9c7a6SRudolf Cornelissen BT_init_PAL720();
1697b2459715SRudolf Cornelissen break;
1698fb6cadf1Sshatty }
1699fb6cadf1Sshatty
1700efe9c7a6SRudolf Cornelissen /* modify BT Hphase signal to center TV image... */
1701efe9c7a6SRudolf Cornelissen BT_setup_hphase(tvmode);
1702fb6cadf1Sshatty
1703efe9c7a6SRudolf Cornelissen /* disable Macro mode */
1704efe9c7a6SRudolf Cornelissen switch (tvmode)
1705efe9c7a6SRudolf Cornelissen {
1706efe9c7a6SRudolf Cornelissen case NTSC640:
1707efe9c7a6SRudolf Cornelissen case NTSC640_TST:
1708efe9c7a6SRudolf Cornelissen case NTSC800:
1709efe9c7a6SRudolf Cornelissen case NTSC640_OS:
1710efe9c7a6SRudolf Cornelissen case NTSC720:
1711efe9c7a6SRudolf Cornelissen /* NTSC */
1712efe9c7a6SRudolf Cornelissen BT_set_macro (0, 0);
1713efe9c7a6SRudolf Cornelissen break;
1714efe9c7a6SRudolf Cornelissen default:
1715efe9c7a6SRudolf Cornelissen /* PAL */
1716efe9c7a6SRudolf Cornelissen BT_set_macro (1, 0);
1717efe9c7a6SRudolf Cornelissen break;
1718efe9c7a6SRudolf Cornelissen }
1719fb6cadf1Sshatty
1720efe9c7a6SRudolf Cornelissen /* setup output signal routing and flickerfilter */
17210c73ffe8SRudolf Cornelissen BT_setup_output(monstat, (uint8)(si->settings.tv_output), ffilter);
1722fb6cadf1Sshatty
172385406c4dSRudolf Cornelissen /* update the GPU CRTC timing for the requested mode */
172485406c4dSRudolf Cornelissen BT_update_mode_for_gpu(&tv_target, tvmode);
1725fb6cadf1Sshatty
1726efe9c7a6SRudolf Cornelissen /* setup GPU CRTC timing */
17273c71b494SRudolf Cornelissen /* TV_PRIMARY tells us that the head to be used with TVout is the head that's
17283c71b494SRudolf Cornelissen * actually assigned as being the primary head at powerup:
17293c71b494SRudolf Cornelissen * so non dualhead-mode-dependant, and not 'fixed' CRTC1! */
1730d7dfe68dSRudolf Cornelissen if (tv_target.flags & TV_PRIMARY)
17313c71b494SRudolf Cornelissen {
17323c71b494SRudolf Cornelissen if ((tv_target.flags & DUALHEAD_BITS) != DUALHEAD_SWITCH)
1733b2459715SRudolf Cornelissen head1_set_timing(tv_target);
1734d7dfe68dSRudolf Cornelissen else
173591731297SRudolf Cornelissen head2_set_timing(tv_target);
17363c71b494SRudolf Cornelissen }
17373c71b494SRudolf Cornelissen else
17383c71b494SRudolf Cornelissen {
17393c71b494SRudolf Cornelissen if ((tv_target.flags & DUALHEAD_BITS) != DUALHEAD_SWITCH)
17403c71b494SRudolf Cornelissen head2_set_timing(tv_target);
17413c71b494SRudolf Cornelissen else
17423c71b494SRudolf Cornelissen head1_set_timing(tv_target);
17433c71b494SRudolf Cornelissen }
174491731297SRudolf Cornelissen
174522a0d15bSRudolf Cornelissen /* now set GPU CRTC to slave mode */
174691731297SRudolf Cornelissen BT_start_tvout(tv_target);
1747efe9c7a6SRudolf Cornelissen
1748b2459715SRudolf Cornelissen return B_OK;
1749fb6cadf1Sshatty }
1750