xref: /haiku/src/add-ons/accelerants/nvidia/engine/nv_brooktreetv.c (revision 0c73ffe8e7af2261a4b985d8d6dc39b29bee882f)
112566cbdSRudolf Cornelissen /*
212566cbdSRudolf Cornelissen 	Author:
3b2459715SRudolf Cornelissen 	Rudolf Cornelissen 4/2002-10/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 
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 */
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 */
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 
21612566cbdSRudolf Cornelissen bool BT_probe()
21712566cbdSRudolf Cornelissen {
21812566cbdSRudolf Cornelissen 	bool btfound = false;
21912566cbdSRudolf Cornelissen 
2209a7218c5SRudolf Cornelissen 	LOG(4,("Brooktree: Checking I2C bus(ses) for first possible TV encoder...\n"));
22112566cbdSRudolf Cornelissen 	if (si->ps.i2c_bus0)
22212566cbdSRudolf Cornelissen 	{
22312566cbdSRudolf Cornelissen 		/* try primary adress on bus 0 */
22412566cbdSRudolf Cornelissen 		if (!BT_check(0, PRADR))
22512566cbdSRudolf Cornelissen 		{
22612566cbdSRudolf Cornelissen 			btfound = true;
22712566cbdSRudolf Cornelissen 			si->ps.tv_encoder.adress = PRADR;
22812566cbdSRudolf Cornelissen 			si->ps.tv_encoder.bus = 0;
22912566cbdSRudolf Cornelissen 		}
23012566cbdSRudolf Cornelissen 		else
23112566cbdSRudolf Cornelissen 		{
23212566cbdSRudolf Cornelissen 			/* try secondary adress on bus 0 */
23312566cbdSRudolf Cornelissen 			if (!BT_check(0, SCADR))
23412566cbdSRudolf Cornelissen 			{
23512566cbdSRudolf Cornelissen 				btfound = true;
23612566cbdSRudolf Cornelissen 				si->ps.tv_encoder.adress = SCADR;
23712566cbdSRudolf Cornelissen 				si->ps.tv_encoder.bus = 0;
23812566cbdSRudolf Cornelissen 			}
23912566cbdSRudolf Cornelissen 		}
24012566cbdSRudolf Cornelissen 	}
24112566cbdSRudolf Cornelissen 
24212566cbdSRudolf Cornelissen 	if (si->ps.i2c_bus1 && !btfound)
24312566cbdSRudolf Cornelissen 	{
24412566cbdSRudolf Cornelissen 		/* try primary adress on bus 1 */
24512566cbdSRudolf Cornelissen 		if (!BT_check(1, PRADR))
24612566cbdSRudolf Cornelissen 		{
24712566cbdSRudolf Cornelissen 			btfound = true;
24812566cbdSRudolf Cornelissen 			si->ps.tv_encoder.adress = PRADR;
24912566cbdSRudolf Cornelissen 			si->ps.tv_encoder.bus = 1;
25012566cbdSRudolf Cornelissen 		}
25112566cbdSRudolf Cornelissen 		else
25212566cbdSRudolf Cornelissen 		{
25312566cbdSRudolf Cornelissen 			/* try secondary adress on bus 1 */
25412566cbdSRudolf Cornelissen 			if (!BT_check(1, SCADR))
25512566cbdSRudolf Cornelissen 			{
25612566cbdSRudolf Cornelissen 				btfound = true;
25712566cbdSRudolf Cornelissen 				si->ps.tv_encoder.adress = SCADR;
25812566cbdSRudolf Cornelissen 				si->ps.tv_encoder.bus = 1;
25912566cbdSRudolf Cornelissen 			}
26012566cbdSRudolf Cornelissen 		}
26112566cbdSRudolf Cornelissen 	}
26212566cbdSRudolf Cornelissen 
26312566cbdSRudolf Cornelissen 	/* identify exact TV encoder type */
26412566cbdSRudolf Cornelissen 	if (btfound)
26512566cbdSRudolf Cornelissen 	{
26612566cbdSRudolf Cornelissen 		/* if errors are found, retry */
26712566cbdSRudolf Cornelissen 		/* note:
26812566cbdSRudolf Cornelissen 		 * NACK: occurs on some ASUS V7700 GeForce cards!
26912566cbdSRudolf Cornelissen 		 * (apparantly the video-in chip or another chip resides at 'BT' adresses
27012566cbdSRudolf Cornelissen 		 * there..) */
27112566cbdSRudolf Cornelissen 		uint8 stat;
27212566cbdSRudolf Cornelissen 		uint8 cnt = 0;
27312566cbdSRudolf Cornelissen 		while ((stat = BT_read_type()) && (cnt < 3))
27412566cbdSRudolf Cornelissen 		{
2750ece4905SRudolf Cornelissen 			/* don't retry on unsupported chiptype */
2760ece4905SRudolf Cornelissen 			if (stat == 0x80)
2770ece4905SRudolf Cornelissen 			{
2780ece4905SRudolf Cornelissen 				btfound = 0;
2790ece4905SRudolf Cornelissen 				break;
2800ece4905SRudolf Cornelissen 			}
28112566cbdSRudolf Cornelissen 			cnt++;
28212566cbdSRudolf Cornelissen 		}
2830ece4905SRudolf Cornelissen 		if (stat & 0x7f)
28412566cbdSRudolf Cornelissen 		{
2859a7218c5SRudolf Cornelissen 			LOG(4,("Brooktree: Too much errors occurred, aborting.\n"));
28612566cbdSRudolf Cornelissen 			btfound = 0;
28712566cbdSRudolf Cornelissen 		}
28812566cbdSRudolf Cornelissen 	}
28912566cbdSRudolf Cornelissen 
29012566cbdSRudolf Cornelissen 	if (btfound)
29112566cbdSRudolf Cornelissen 		LOG(4,("Brooktree: Found TV encoder on bus %d, adress $%02x\n",
29212566cbdSRudolf Cornelissen 			si->ps.tv_encoder.bus, si->ps.tv_encoder.adress));
29312566cbdSRudolf Cornelissen 	else
29412566cbdSRudolf Cornelissen 		LOG(4,("Brooktree: No TV encoder Found\n"));
29512566cbdSRudolf Cornelissen 
29612566cbdSRudolf Cornelissen 	return btfound;
29712566cbdSRudolf Cornelissen }
29812566cbdSRudolf Cornelissen 
29977497c49SRudolf Cornelissen static uint8 BT_init_PAL640()
300fb6cadf1Sshatty {
30177497c49SRudolf Cornelissen 	uint8 stat;
302fb6cadf1Sshatty 
30377497c49SRudolf Cornelissen 	uint8 buffer[35];
304fb6cadf1Sshatty 
3059a7218c5SRudolf Cornelissen 	LOG(4,("Brooktree: Setting PAL 640x480 desktop mode\n"));
3069a7218c5SRudolf Cornelissen 
3079a7218c5SRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
30877497c49SRudolf Cornelissen 	buffer[1] = 0x76;			//select first bt register to write to
30977497c49SRudolf Cornelissen 	buffer[2] = 0x60;
31077497c49SRudolf Cornelissen 	buffer[3] = 0x80;
31177497c49SRudolf Cornelissen 	buffer[4] = 0x8a;
31277497c49SRudolf Cornelissen 	buffer[5] = 0xa6;
31377497c49SRudolf Cornelissen 	buffer[6] = 0x68;
31477497c49SRudolf Cornelissen 	buffer[7] = 0xc1;
31577497c49SRudolf Cornelissen 	buffer[8] = 0x2e;
31677497c49SRudolf Cornelissen 	buffer[9] = 0xf2;
31777497c49SRudolf Cornelissen 	buffer[10] = 0x27;
31877497c49SRudolf Cornelissen 	buffer[11] = 0x00;
31977497c49SRudolf Cornelissen 	buffer[12] = 0xb0;
32077497c49SRudolf Cornelissen 	buffer[13] = 0x0a;
32177497c49SRudolf Cornelissen 	buffer[14] = 0x0b;
32277497c49SRudolf Cornelissen 	buffer[15] = 0x71;
32377497c49SRudolf Cornelissen 	buffer[16] = 0x5a;
32477497c49SRudolf Cornelissen 	buffer[17] = 0xe0;
32577497c49SRudolf Cornelissen 	buffer[18] = 0x36;
32677497c49SRudolf Cornelissen 	buffer[19] = 0x00;
32777497c49SRudolf Cornelissen 	buffer[20] = 0x50;
32877497c49SRudolf Cornelissen 	buffer[21] = 0x72;
32977497c49SRudolf Cornelissen 	buffer[22] = 0x1c;
33077497c49SRudolf Cornelissen 	buffer[23] = 0x8d;		//chip-pin CLKI is pixel clock (only non-default here!)
33177497c49SRudolf Cornelissen 	buffer[24] = 0x24;
33277497c49SRudolf Cornelissen 	buffer[25] = 0xf0;
33377497c49SRudolf Cornelissen 	buffer[26] = 0x58;
33477497c49SRudolf Cornelissen 	buffer[27] = 0x81;
33577497c49SRudolf Cornelissen 	buffer[28] = 0x49;
33677497c49SRudolf Cornelissen 	buffer[29] = 0x8c;
33777497c49SRudolf Cornelissen 	buffer[30] = 0x0c;
33877497c49SRudolf Cornelissen 	buffer[31] = 0x8c;
33977497c49SRudolf Cornelissen 	buffer[32] = 0x79;
34077497c49SRudolf Cornelissen 	buffer[33] = 0x26;
34177497c49SRudolf Cornelissen 	buffer[34] = 0x00;
34277497c49SRudolf Cornelissen 
34377497c49SRudolf Cornelissen 	/* reset status */
34477497c49SRudolf Cornelissen 	i2c_flag_error (-1);
34577497c49SRudolf Cornelissen 
34677497c49SRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
34777497c49SRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
34877497c49SRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
34977497c49SRudolf Cornelissen 	/* log on errors */
35077497c49SRudolf Cornelissen 	stat = i2c_flag_error(0);
35177497c49SRudolf Cornelissen 	if (stat)
35277497c49SRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while setting mode PAL640\n"));
35377497c49SRudolf Cornelissen 
35477497c49SRudolf Cornelissen 	return stat;
35577497c49SRudolf Cornelissen }//end BT_init_PAL640.
35677497c49SRudolf Cornelissen 
35777497c49SRudolf Cornelissen static uint8 BT_init_PAL800()
358fb6cadf1Sshatty {
35977497c49SRudolf Cornelissen 	uint8 stat;
360fb6cadf1Sshatty 
36177497c49SRudolf Cornelissen 	uint8 buffer[35];
362fb6cadf1Sshatty 
3639a7218c5SRudolf Cornelissen 	LOG(4,("Brooktree: Setting PAL 800x600 desktop mode\n"));
3649a7218c5SRudolf Cornelissen 
3659a7218c5SRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
36677497c49SRudolf Cornelissen 	buffer[1] = 0x76;			//select first bt register to write to
36777497c49SRudolf Cornelissen 	buffer[2] = 0x00;
36877497c49SRudolf Cornelissen 	buffer[3] = 0x20;
36977497c49SRudolf Cornelissen 	buffer[4] = 0xaa;
37077497c49SRudolf Cornelissen 	buffer[5] = 0xca;
37177497c49SRudolf Cornelissen 	buffer[6] = 0x9a;
37277497c49SRudolf Cornelissen 	buffer[7] = 0x0d;
37377497c49SRudolf Cornelissen 	buffer[8] = 0x29;
37477497c49SRudolf Cornelissen 	buffer[9] = 0xfc;
37577497c49SRudolf Cornelissen 	buffer[10] = 0x39;
37677497c49SRudolf Cornelissen 	buffer[11] = 0x00;
37777497c49SRudolf Cornelissen 	buffer[12] = 0xc0;
37877497c49SRudolf Cornelissen 	buffer[13] = 0x8c;
37977497c49SRudolf Cornelissen 	buffer[14] = 0x03;
38077497c49SRudolf Cornelissen 	buffer[15] = 0xee;
38177497c49SRudolf Cornelissen 	buffer[16] = 0x5f;
38277497c49SRudolf Cornelissen 	buffer[17] = 0x58;
38377497c49SRudolf Cornelissen 	buffer[18] = 0x3a;
38477497c49SRudolf Cornelissen 	buffer[19] = 0x66;
38577497c49SRudolf Cornelissen 	buffer[20] = 0x96;
38677497c49SRudolf Cornelissen 	buffer[21] = 0x00;
38777497c49SRudolf Cornelissen 	buffer[22] = 0x00;
38877497c49SRudolf Cornelissen 	buffer[23] = 0x90;		//chip-pin CLKI is pixel clock (only non-default here!)
38977497c49SRudolf Cornelissen 	buffer[24] = 0x24;
39077497c49SRudolf Cornelissen 	buffer[25] = 0xf0;
39177497c49SRudolf Cornelissen 	buffer[26] = 0x57;
39277497c49SRudolf Cornelissen 	buffer[27] = 0x80;
39377497c49SRudolf Cornelissen 	buffer[28] = 0x48;
39477497c49SRudolf Cornelissen 	buffer[29] = 0x8c;
39577497c49SRudolf Cornelissen 	buffer[30] = 0x18;
39677497c49SRudolf Cornelissen 	buffer[31] = 0x28;
39777497c49SRudolf Cornelissen 	buffer[32] = 0x87;
39877497c49SRudolf Cornelissen 	buffer[33] = 0x1f;
39977497c49SRudolf Cornelissen 	buffer[34] = 0x00;
40077497c49SRudolf Cornelissen 
40177497c49SRudolf Cornelissen 	/* reset status */
40277497c49SRudolf Cornelissen 	i2c_flag_error (-1);
40377497c49SRudolf Cornelissen 
40477497c49SRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
40577497c49SRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
40677497c49SRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
40777497c49SRudolf Cornelissen 	/* log on errors */
40877497c49SRudolf Cornelissen 	stat = i2c_flag_error(0);
40977497c49SRudolf Cornelissen 	if (stat)
41077497c49SRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800\n"));
41177497c49SRudolf Cornelissen 
41277497c49SRudolf Cornelissen 	return stat;
41377497c49SRudolf Cornelissen }//end BT_init_PAL800.
41477497c49SRudolf Cornelissen 
41577497c49SRudolf Cornelissen static uint8 BT_init_NTSC640()
416fb6cadf1Sshatty {
41777497c49SRudolf Cornelissen 	uint8 stat;
418fb6cadf1Sshatty 
41977497c49SRudolf Cornelissen 	uint8 buffer[35];
42077497c49SRudolf Cornelissen 
4219a7218c5SRudolf Cornelissen 	LOG(4,("Brooktree: Setting NTSC 640x480 desktop mode\n"));
4229a7218c5SRudolf Cornelissen 
4239a7218c5SRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
42477497c49SRudolf Cornelissen 	buffer[1] = 0x76;			//select first bt register to write to
42577497c49SRudolf Cornelissen 	buffer[2] = 0x00;
42677497c49SRudolf Cornelissen 	buffer[3] = 0x80;
42777497c49SRudolf Cornelissen 	buffer[4] = 0x84;
42877497c49SRudolf Cornelissen 	buffer[5] = 0x96;
42977497c49SRudolf Cornelissen 	buffer[6] = 0x60;
43077497c49SRudolf Cornelissen 	buffer[7] = 0x7d;
43177497c49SRudolf Cornelissen 	buffer[8] = 0x22;
43277497c49SRudolf Cornelissen 	buffer[9] = 0xd4;
43377497c49SRudolf Cornelissen 	buffer[10] = 0x27;
43477497c49SRudolf Cornelissen 	buffer[11] = 0x00;
43577497c49SRudolf Cornelissen 	buffer[12] = 0x10;
43677497c49SRudolf Cornelissen 	buffer[13] = 0x7e;
43777497c49SRudolf Cornelissen 	buffer[14] = 0x03;
43877497c49SRudolf Cornelissen 	buffer[15] = 0x58;
43977497c49SRudolf Cornelissen 	buffer[16] = 0x4b;
44077497c49SRudolf Cornelissen 	buffer[17] = 0xe0;
44177497c49SRudolf Cornelissen 	buffer[18] = 0x36;
44277497c49SRudolf Cornelissen 	buffer[19] = 0x92;
44377497c49SRudolf Cornelissen 	buffer[20] = 0x54;
44477497c49SRudolf Cornelissen 	buffer[21] = 0x0e;
44577497c49SRudolf Cornelissen 	buffer[22] = 0x88;
44677497c49SRudolf Cornelissen 	buffer[23] = 0x8c;		//chip-pin CLKI is pixel clock (only non-default here!)
44777497c49SRudolf Cornelissen 	buffer[24] = 0x0a;
44877497c49SRudolf Cornelissen 	buffer[25] = 0xe5;
44977497c49SRudolf Cornelissen 	buffer[26] = 0x76;
45077497c49SRudolf Cornelissen 	buffer[27] = 0x79;
45177497c49SRudolf Cornelissen 	buffer[28] = 0x44;
45277497c49SRudolf Cornelissen 	buffer[29] = 0x85;
45377497c49SRudolf Cornelissen 	buffer[30] = 0x00;
45477497c49SRudolf Cornelissen 	buffer[31] = 0x00;
45577497c49SRudolf Cornelissen 	buffer[32] = 0x80;
45677497c49SRudolf Cornelissen 	buffer[33] = 0x20;
45777497c49SRudolf Cornelissen 	buffer[34] = 0x00;
45877497c49SRudolf Cornelissen 
45977497c49SRudolf Cornelissen 	/* reset status */
46077497c49SRudolf Cornelissen 	i2c_flag_error (-1);
46177497c49SRudolf Cornelissen 
46277497c49SRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
46377497c49SRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
46477497c49SRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
46577497c49SRudolf Cornelissen 	/* log on errors */
46677497c49SRudolf Cornelissen 	stat = i2c_flag_error(0);
46777497c49SRudolf Cornelissen 	if (stat)
46877497c49SRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC640\n"));
46977497c49SRudolf Cornelissen 
47077497c49SRudolf Cornelissen 	return stat;
47177497c49SRudolf Cornelissen }//end BT_init_NTSC640.
47277497c49SRudolf Cornelissen 
47377497c49SRudolf Cornelissen static uint8 BT_init_NTSC800()
474fb6cadf1Sshatty {
47577497c49SRudolf Cornelissen 	uint8 stat;
476fb6cadf1Sshatty 
47777497c49SRudolf Cornelissen 	uint8 buffer[35];
478fb6cadf1Sshatty 
4799a7218c5SRudolf Cornelissen 	LOG(4,("Brooktree: Setting NTSC 800x600 desktop mode\n"));
4809a7218c5SRudolf Cornelissen 
4819a7218c5SRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
48277497c49SRudolf Cornelissen 	buffer[1] = 0x76;			//select first bt register to write to
48377497c49SRudolf Cornelissen 	buffer[2] = 0xa0;
48477497c49SRudolf Cornelissen 	buffer[3] = 0x20;
48577497c49SRudolf Cornelissen 	buffer[4] = 0xb6;
48677497c49SRudolf Cornelissen 	buffer[5] = 0xce;
48777497c49SRudolf Cornelissen 	buffer[6] = 0x84;
48877497c49SRudolf Cornelissen 	buffer[7] = 0x55;
48977497c49SRudolf Cornelissen 	buffer[8] = 0x20;
49077497c49SRudolf Cornelissen 	buffer[9] = 0xd8;
49177497c49SRudolf Cornelissen 	buffer[10] = 0x39;
49277497c49SRudolf Cornelissen 	buffer[11] = 0x00;
49377497c49SRudolf Cornelissen 	buffer[12] = 0x70;
49477497c49SRudolf Cornelissen 	buffer[13] = 0x42;
49577497c49SRudolf Cornelissen 	buffer[14] = 0x03;
49677497c49SRudolf Cornelissen 	buffer[15] = 0xdf;
49777497c49SRudolf Cornelissen 	buffer[16] = 0x56;
49877497c49SRudolf Cornelissen 	buffer[17] = 0x58;
49977497c49SRudolf Cornelissen 	buffer[18] = 0x3a;
50077497c49SRudolf Cornelissen 	buffer[19] = 0xcd;
50177497c49SRudolf Cornelissen 	buffer[20] = 0x9c;
50277497c49SRudolf Cornelissen 	buffer[21] = 0x14;
50377497c49SRudolf Cornelissen 	buffer[22] = 0x3b;
50477497c49SRudolf Cornelissen 	buffer[23] = 0x91;		//chip-pin CLKI is pixel clock (only non-default here!)
50577497c49SRudolf Cornelissen 	buffer[24] = 0x0a;
50677497c49SRudolf Cornelissen 	buffer[25] = 0xe5;
50777497c49SRudolf Cornelissen 	buffer[26] = 0x74;
50877497c49SRudolf Cornelissen 	buffer[27] = 0x77;
50977497c49SRudolf Cornelissen 	buffer[28] = 0x43;
51077497c49SRudolf Cornelissen 	buffer[29] = 0x85;
51177497c49SRudolf Cornelissen 	buffer[30] = 0xba;
51277497c49SRudolf Cornelissen 	buffer[31] = 0xe8;
51377497c49SRudolf Cornelissen 	buffer[32] = 0xa2;
51477497c49SRudolf Cornelissen 	buffer[33] = 0x17;
51577497c49SRudolf Cornelissen 	buffer[34] = 0x00;
51677497c49SRudolf Cornelissen 
51777497c49SRudolf Cornelissen 	/* reset status */
51877497c49SRudolf Cornelissen 	i2c_flag_error (-1);
51977497c49SRudolf Cornelissen 
52077497c49SRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
52177497c49SRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
52277497c49SRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
52377497c49SRudolf Cornelissen 	/* log on errors */
52477497c49SRudolf Cornelissen 	stat = i2c_flag_error(0);
52577497c49SRudolf Cornelissen 	if (stat)
52677497c49SRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800\n"));
52777497c49SRudolf Cornelissen 
52877497c49SRudolf Cornelissen 	return stat;
52977497c49SRudolf Cornelissen }//end BT_init_NTSC800.
53077497c49SRudolf Cornelissen 
53177497c49SRudolf Cornelissen static uint8 BT_init_PAL720()
532fb6cadf1Sshatty {
53377497c49SRudolf Cornelissen 	uint8 stat;
53477497c49SRudolf Cornelissen 
53577497c49SRudolf Cornelissen 	uint8 buffer[35];
53677497c49SRudolf Cornelissen 
5379a7218c5SRudolf Cornelissen 	LOG(4,("Brooktree: Setting PAL 720x576 overscanning DVD mode\n"));
5389a7218c5SRudolf Cornelissen 
5399a7218c5SRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
54077497c49SRudolf Cornelissen 	buffer[1] = 0x76;			//select first bt register to write to
54177497c49SRudolf Cornelissen 	buffer[2] = 0xf0;
54277497c49SRudolf Cornelissen 	buffer[3] = 0xd0;
54377497c49SRudolf Cornelissen 	buffer[4] = 0x82;
54477497c49SRudolf Cornelissen 	buffer[5] = 0x9c;
54577497c49SRudolf Cornelissen 	buffer[6] = 0x5a;
54677497c49SRudolf Cornelissen 	buffer[7] = 0x31;
54777497c49SRudolf Cornelissen 	buffer[8] = 0x16;
54877497c49SRudolf Cornelissen 	buffer[9] = 0x22;
54977497c49SRudolf Cornelissen 	buffer[10] = 0xa6;
55077497c49SRudolf Cornelissen 	buffer[11] = 0x00;
55177497c49SRudolf Cornelissen 	buffer[12] = 0x78;
55277497c49SRudolf Cornelissen 	buffer[13] = 0x93;
55377497c49SRudolf Cornelissen 	buffer[14] = 0x03;
55477497c49SRudolf Cornelissen 	buffer[15] = 0x71;
55577497c49SRudolf Cornelissen 	buffer[16] = 0x2a;
55677497c49SRudolf Cornelissen 	buffer[17] = 0x40;
55777497c49SRudolf Cornelissen 	buffer[18] = 0x0a;
55877497c49SRudolf Cornelissen 	buffer[19] = 0x00;
55977497c49SRudolf Cornelissen 	buffer[20] = 0x50;
56077497c49SRudolf Cornelissen 	buffer[21] = 0x55;
56177497c49SRudolf Cornelissen 	buffer[22] = 0x55;
56277497c49SRudolf Cornelissen 	buffer[23] = 0x8c;		//chip-pin CLKI is pixel clock (only non-default here!)
56377497c49SRudolf Cornelissen 	buffer[24] = 0x24;
56477497c49SRudolf Cornelissen 	buffer[25] = 0xf0;
56577497c49SRudolf Cornelissen 	buffer[26] = 0x59;
56677497c49SRudolf Cornelissen 	buffer[27] = 0x82;
56777497c49SRudolf Cornelissen 	buffer[28] = 0x49;
56877497c49SRudolf Cornelissen 	buffer[29] = 0x8c;
56977497c49SRudolf Cornelissen 	buffer[30] = 0x8e;
57077497c49SRudolf Cornelissen 	buffer[31] = 0xb0;
57177497c49SRudolf Cornelissen 	buffer[32] = 0xe6;
57277497c49SRudolf Cornelissen 	buffer[33] = 0x28;
57377497c49SRudolf Cornelissen 	buffer[34] = 0x00;
57477497c49SRudolf Cornelissen 
57577497c49SRudolf Cornelissen 	/* reset status */
57677497c49SRudolf Cornelissen 	i2c_flag_error (-1);
57777497c49SRudolf Cornelissen 
57877497c49SRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
57977497c49SRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
58077497c49SRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
58177497c49SRudolf Cornelissen 	/* log on errors */
58277497c49SRudolf Cornelissen 	stat = i2c_flag_error(0);
58377497c49SRudolf Cornelissen 	if (stat)
58477497c49SRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while setting mode PAL720\n"));
58577497c49SRudolf Cornelissen 
58677497c49SRudolf Cornelissen 	return stat;
58777497c49SRudolf Cornelissen }//end BT_init_PAL720.
58877497c49SRudolf Cornelissen 
58977497c49SRudolf Cornelissen static uint8 BT_init_NTSC720()
590fb6cadf1Sshatty {
59177497c49SRudolf Cornelissen 	uint8 stat;
592fb6cadf1Sshatty 
59377497c49SRudolf Cornelissen 	uint8 buffer[35];
59477497c49SRudolf Cornelissen 
5959a7218c5SRudolf Cornelissen 	LOG(4,("Brooktree: Setting NTSC 720x480 overscanning DVD mode\n"));
5969a7218c5SRudolf Cornelissen 
5979a7218c5SRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
59877497c49SRudolf Cornelissen 	buffer[1] = 0x76;		//select first bt register to write to.
59977497c49SRudolf Cornelissen 	buffer[2] = 0xf0;		//lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1)
60077497c49SRudolf Cornelissen 	buffer[3] = 0xd0;		//lsb h_active: h_active = 720 pixels wide port
60177497c49SRudolf Cornelissen 	buffer[4] = 0x83;	//scope: OK hsync_width: (hsync_width / h_clk_o) * 63.55556uS = 4.70uS for NTSC
60277497c49SRudolf Cornelissen 	buffer[5] = 0x98;	//scope: OK	hburst_begin: (hburst_begin / h_clk_o) * 63.55556uS = 5.3uS for NTSC
60377497c49SRudolf Cornelissen 	buffer[6] = 0x5e;	//scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 63.55556uS = 7.94uS for NTSC
60477497c49SRudolf Cornelissen 
60577497c49SRudolf Cornelissen 	//How to find the correct values for h_blank_o and v_blank_o:
60677497c49SRudolf Cornelissen 	// 1. Calculate h_blank_o according to initial setting guideline mentioned below;
60777497c49SRudolf 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
60877497c49SRudolf Cornelissen 	//    horizontal position is about OK;
60977497c49SRudolf Cornelissen 	// 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch);
61077497c49SRudolf Cornelissen 	// 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above);
61177497c49SRudolf Cornelissen 	// 5. If no vertical shivering occurs when image is centered, you're done. Else:
61277497c49SRudolf Cornelissen 	// 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!:
61377497c49SRudolf Cornelissen 	// 7. Make sure you update the Chrontel horizontal Phase setting also then!
61477497c49SRudolf Cornelissen 
6155cadaa5fSRudolf Cornelissen 	if (si->ps.tv_encoder.type >= CX25870)//set CX value
6165cadaa5fSRudolf Cornelissen 	{
617195828c4SRudolf Cornelissen 		/* confirmed on NV11 using 4:3 TV and 16:9 TV */
6185cadaa5fSRudolf Cornelissen 		buffer[7] = 0x0c;	//scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV
6195cadaa5fSRudolf Cornelissen 							//(guideline for initial setting: (h_blank_o / h_clk_0) * 63.55556uS = 9.5uS for NTSC)
6205cadaa5fSRudolf Cornelissen 	}
6215cadaa5fSRudolf Cornelissen 	else //set BT value
6225cadaa5fSRudolf Cornelissen 	{
6235cadaa5fSRudolf Cornelissen 		/* confirmed on TNT1 using 4:3 TV and 16:9 TV */
62477497c49SRudolf Cornelissen 		buffer[7] = 0x28;	//scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV
62577497c49SRudolf Cornelissen 							//(guideline for initial setting: (h_blank_o / h_clk_0) * 63.55556uS = 9.5uS for NTSC)
6265cadaa5fSRudolf Cornelissen 	}
62777497c49SRudolf Cornelissen 	buffer[8] = 0x18;	//try-out; scope: checked against other modes, looks OK.	v_blank_o: 1e active line ('pixel')
62877497c49SRudolf Cornelissen 
62977497c49SRudolf Cornelissen 	buffer[9] = 0xf2;		//v_active_o: = (active output lines + 2) / field (on TV)
63077497c49SRudolf Cornelissen 	buffer[10] = 0x26;		//lsn = msn h_clk_o;
63177497c49SRudolf Cornelissen 							//b4-5 = msbits h_active;
63277497c49SRudolf Cornelissen 							//b7 = b8 v_avtive_o.
63377497c49SRudolf Cornelissen 	buffer[11] = 0x00;		//h_fract is always 0.
63477497c49SRudolf Cornelissen 	buffer[12] = 0x78;		//lsb h_clk_i: h_clk_i is horizontal total = 888.
63577497c49SRudolf Cornelissen 	buffer[13] = 0x90; 	//try-out; lsb h_blank_i: #clks between start sync and new line 1st pixel; copy to VGA delta-sync!
63677497c49SRudolf Cornelissen 	buffer[14] = 0x03;		//b2-0 = msn h_clk_i;
63777497c49SRudolf Cornelissen 						//try-out: b3 = msn h_blank_i;
63877497c49SRudolf Cornelissen 							//b4 = vblankdly is always 0.
63977497c49SRudolf Cornelissen 	buffer[15] = 0x0d;		//lsb v_lines_i: v_lines_i = 525
64077497c49SRudolf Cornelissen 	buffer[16] = 0x1a; 	//try-out;	v_blank_i: #input lines between start sync and new line (pixel); copy to VGA delta-sync!
64177497c49SRudolf Cornelissen 						//Make sure though that this value for the BT is *even*, or image will shiver a *lot* horizontally on TV.
64277497c49SRudolf Cornelissen 	buffer[17] = 0xe0;		//lsb v_active_i: v_active_i = 480
64377497c49SRudolf Cornelissen 	buffer[18] = 0x36;		//b1-0 = msn v_lines_i;
64477497c49SRudolf Cornelissen 							//b3-2 = msn v_active_i;
64577497c49SRudolf Cornelissen 							//b5-4 = ylpf = 3;
64677497c49SRudolf Cornelissen 							//b7-6 = clpf = 0.
64777497c49SRudolf Cornelissen 	buffer[19] = 0x00;		//lsb v_scale: v_scale = off = $1000
64877497c49SRudolf Cornelissen 	buffer[20] = 0x50;		//b5-0 = msn v_scale;
64977497c49SRudolf Cornelissen 						//scope: tuned. b7-6 = msn h_blank_o.
65077497c49SRudolf Cornelissen 							//(((PLL_INT + (PLL_FRACT/65536)) / 6) * 13500000) = PIXEL_CLK = (hor.tot. * v_lines_i * 60Hz)
65177497c49SRudolf Cornelissen 	buffer[21] = 0x98;		//lsb PLL fract: PLL fract = 0x6e98
65277497c49SRudolf Cornelissen 	buffer[22] = 0x6e;		//msb PLL fract
65377497c49SRudolf Cornelissen 	buffer[23] = 0x8c;		//b5-0 = PLL int: PLL int = 0x0c;
65477497c49SRudolf Cornelissen 							//b6 = by_pll: by_pll = 0;
65577497c49SRudolf Cornelissen 							//b7 = EN_XCLK: chip-pin CLKI is pixel clock.
65677497c49SRudolf Cornelissen 	buffer[24] = 0x0a;		//b0 = ni_out is always 0;
65777497c49SRudolf Cornelissen 							//b1 = setup = 1 for NTSC;
65877497c49SRudolf Cornelissen 							//b2 = 625line = 0 for NTSC;
65977497c49SRudolf Cornelissen 							//b3 = vsync_dur = 1 for NTSC;
66077497c49SRudolf Cornelissen 							//b4 = dic_screset is always 0;
66177497c49SRudolf Cornelissen 							//b5 = pal_md = 0 for NTSC;
66277497c49SRudolf Cornelissen 							//b6 = eclip is always 0;
66377497c49SRudolf Cornelissen 							//b7 = reserved (en_scart) is always 0.
66477497c49SRudolf Cornelissen 	buffer[25] = 0xe5;		//sync_amp $e5 for NTSC
66577497c49SRudolf Cornelissen 	buffer[26] = 0x75;		//bst_amp $74-$76 for NTSC
66677497c49SRudolf Cornelissen 	buffer[27] = 0x78;		//mcr: r-y $77-$79 for NTSC
66777497c49SRudolf Cornelissen 	buffer[28] = 0x44;		//mcb: b-y $43-$44 for NTSC
66877497c49SRudolf Cornelissen 	buffer[29] = 0x85;		//my: y $85 for NTSC
66977497c49SRudolf Cornelissen 	buffer[30] = 0x3c;		//lsb msc: msc b31-0: NTSC formula: ((3579545 / pixelclk) * 2^32) = MSC
67077497c49SRudolf Cornelissen 	buffer[31] = 0x91;		//msc = $20c2913c
67177497c49SRudolf Cornelissen 	buffer[32] = 0xc2;
67277497c49SRudolf Cornelissen 	buffer[33] = 0x20;		//msb msc.
67377497c49SRudolf Cornelissen 	buffer[34] = 0x00;		//phase_off always $00
67477497c49SRudolf Cornelissen 
67577497c49SRudolf Cornelissen 	/* reset status */
67677497c49SRudolf Cornelissen 	i2c_flag_error (-1);
67777497c49SRudolf Cornelissen 
67877497c49SRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
67977497c49SRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
68077497c49SRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
68177497c49SRudolf Cornelissen 	/* log on errors */
68277497c49SRudolf Cornelissen 	stat = i2c_flag_error(0);
68377497c49SRudolf Cornelissen 	if (stat)
68477497c49SRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC720\n"));
68577497c49SRudolf Cornelissen 
68677497c49SRudolf Cornelissen 	return stat;
68777497c49SRudolf Cornelissen }//end BT_init_NTSC720.
68877497c49SRudolf Cornelissen 
68977497c49SRudolf Cornelissen static uint8 BT_init_PAL800_OS()
690fb6cadf1Sshatty {
69177497c49SRudolf Cornelissen 	uint8 stat;
692fb6cadf1Sshatty 
69377497c49SRudolf Cornelissen 	uint8 buffer[35];
69477497c49SRudolf Cornelissen 
6959a7218c5SRudolf Cornelissen 	LOG(4,("Brooktree: Setting PAL 800x600 overscanning VCD mode\n"));
6969a7218c5SRudolf Cornelissen 
6979a7218c5SRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
69877497c49SRudolf Cornelissen 	buffer[1] = 0x76;		//select first bt register to write to.
69977497c49SRudolf Cornelissen 	buffer[2] = 0x60;		//lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1)
70077497c49SRudolf Cornelissen 	buffer[3] = 0x20;		//lsb h_active: h_active = 800 pixels wide port
70177497c49SRudolf Cornelissen 	buffer[4] = 0x8b;	//scope: OK hsync_width: (hsync_width / h_clk_o) * 64.0uS = 4.70uS for PAL
70277497c49SRudolf Cornelissen 	buffer[5] = 0xa5;	//scope: OK	hburst_begin: (hburst_begin / h_clk_o) * 64.0uS = 5.6uS for PAL
70377497c49SRudolf Cornelissen 	buffer[6] = 0x6b;	//scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 64.0uS = 7.97uS for PAL
70477497c49SRudolf Cornelissen 
70577497c49SRudolf Cornelissen 	//How to find the correct values for h_blank_o and v_blank_o:
70677497c49SRudolf Cornelissen 	// 1. Calculate h_blank_o according to initial setting guideline mentioned below;
70777497c49SRudolf 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
70877497c49SRudolf Cornelissen 	//    horizontal position is about OK;
70977497c49SRudolf Cornelissen 	// 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch);
71077497c49SRudolf Cornelissen 	// 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above);
71177497c49SRudolf Cornelissen 	// 5. If no vertical shivering occurs when image is centered, you're done. Else:
71277497c49SRudolf Cornelissen 	// 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!:
71377497c49SRudolf Cornelissen 	// 7. Make sure you update the Chrontel horizontal Phase setting also then!
71477497c49SRudolf Cornelissen 
71577497c49SRudolf Cornelissen 	if (si->ps.tv_encoder.type >= CX25870)//set CX value
716fb6cadf1Sshatty 	{
717195828c4SRudolf Cornelissen 		/* confirmed on NV11 using 4:3 TV and 16:9 TV */
7185cadaa5fSRudolf Cornelissen 		buffer[7] = 0xf0;
71977497c49SRudolf Cornelissen 		buffer[8] = 0x17;
720fb6cadf1Sshatty 	}
7215cadaa5fSRudolf Cornelissen 	else //set BT value
7225cadaa5fSRudolf Cornelissen 	{
7234e918a7cSRudolf Cornelissen 		/* confirmed on TNT1 using 4:3 TV and 16:9 TV */
7246245f19cSRudolf Cornelissen 		buffer[7] = 0xd0;//scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV
72577497c49SRudolf Cornelissen 						//(guideline for initial setting: (h_blank_o / h_clk_0) * 64.0uS = 10.0uS for PAL)
72677497c49SRudolf Cornelissen 		buffer[8] = 0x18;//try-out; scope: checked against other modes, looks OK.	v_blank_o: 1e active line ('pixel')
72777497c49SRudolf Cornelissen 	}
72877497c49SRudolf Cornelissen 
72977497c49SRudolf Cornelissen 	buffer[9] = 0x2e;		//v_active_o: = (active output lines + 2) / field (on TV)
73077497c49SRudolf Cornelissen 	buffer[10] = 0xb7;		//lsn = msn h_clk_o;
73177497c49SRudolf Cornelissen 							//b4-5 = msbits h_active;
73277497c49SRudolf Cornelissen 							//b7 = b8 v_avtive_o.
73377497c49SRudolf Cornelissen 	buffer[11] = 0x00;		//h_fract is always 0.
73477497c49SRudolf Cornelissen 	buffer[12] = 0xb0;		//lsb h_clk_i: h_clk_i is horizontal total = 944.
73577497c49SRudolf Cornelissen 
73677497c49SRudolf Cornelissen 	if (si->ps.tv_encoder.type >= CX25870)//set CX value
73777497c49SRudolf Cornelissen 		buffer[13] = 0x20;
73877497c49SRudolf Cornelissen 	else //set BT value
73977497c49SRudolf Cornelissen 		buffer[13] = 0x14;//try-out; lsb h_blank_i: #clks between start sync and new line 1st pixel; copy to VGA delta-sync!
74077497c49SRudolf Cornelissen 
74177497c49SRudolf Cornelissen 	buffer[14] = 0x03;		//b2-0 = msn h_clk_i;
74277497c49SRudolf Cornelissen 					 	//try-out: b3 = msn h_blank_i;
74377497c49SRudolf Cornelissen 							//b4 = vblankdly is always 0.
74477497c49SRudolf Cornelissen 	buffer[15] = 0x71;		//lsb v_lines_i: v_lines_i = 625
74577497c49SRudolf Cornelissen 
74677497c49SRudolf Cornelissen 	if (si->ps.tv_encoder.type >= CX25870)//set CX value
74777497c49SRudolf Cornelissen 		buffer[16] = 0x08;
74877497c49SRudolf Cornelissen 	else				//set BT value
74977497c49SRudolf Cornelissen 		buffer[16] = 0x2a;//try-out; v_blank_i: #input lines between start sync and new line (pixel); copy to VGA delta-sync!
75077497c49SRudolf Cornelissen 					 	//Make sure though that this value for the BT is *even*, or image will shiver a *lot* horizontally on TV.
75177497c49SRudolf Cornelissen 
75277497c49SRudolf Cornelissen 	buffer[17] = 0x58;		//lsb v_active_i: v_active_i = 600
75377497c49SRudolf Cornelissen 	buffer[18] = 0x3a;		//b1-0 = msn v_lines_i;
75477497c49SRudolf Cornelissen 							//b3-2 = msn v_active_i;
75577497c49SRudolf Cornelissen 							//b5-4 = ylpf = 3;
75677497c49SRudolf Cornelissen 							//b7-6 = clpf = 0.
75777497c49SRudolf Cornelissen 	buffer[19] = 0x00;		//lsb v_scale: v_scale = off = $1000
75877497c49SRudolf Cornelissen 	buffer[20] = 0x10;		//b5-0 = msn v_scale;
75977497c49SRudolf Cornelissen 						//scope: tuned. b7-6 = msn h_blank_o.
76077497c49SRudolf Cornelissen 							//(((PLL_INT + (PLL_FRACT/65536)) / 6) * 13500000) = PIXEL_CLK = (hor.tot. * v_lines_i * 50Hz)
76177497c49SRudolf Cornelissen 	buffer[21] = 0x72;		//lsb PLL fract: PLL fract = 0x1c72
76277497c49SRudolf Cornelissen 	buffer[22] = 0x1c;		//msb PLL fract
76377497c49SRudolf Cornelissen 	buffer[23] = 0x8d;		//b5-0 = PLL int: PLL int = 0x0d;
76477497c49SRudolf Cornelissen 							//b6 = by_pll: by_pll = 0;
76577497c49SRudolf Cornelissen 							//b7 = EN_XCLK: chip-pin CLKI is pixel clock.
76677497c49SRudolf Cornelissen 	buffer[24] = 0x24;		//b0 = ni_out is always 0;
76777497c49SRudolf Cornelissen 							//b1 = setup = 0 for PAL;
76877497c49SRudolf Cornelissen 							//b2 = 625line = 1 for PAL;
76977497c49SRudolf Cornelissen 							//b3 = vsync_dur = 0 for PAL;
77077497c49SRudolf Cornelissen 							//b4 = dic_screset is always 0;
77177497c49SRudolf Cornelissen 							//b5 = pal_md = 1 for PAL;
77277497c49SRudolf Cornelissen 							//b6 = eclip is always 0;
77377497c49SRudolf Cornelissen 							//b7 = reserved (en_scart) is always 0.
77477497c49SRudolf Cornelissen 	buffer[25] = 0xf0;		//sync_amp $f0 for PAL
77577497c49SRudolf Cornelissen 	buffer[26] = 0x57;		//bst_amp $57-$58 for PAL
77677497c49SRudolf Cornelissen 	buffer[27] = 0x80;		//mcr: r-y $80-$81 for PAL
77777497c49SRudolf Cornelissen 	buffer[28] = 0x48;		//mcb: b-y $48-$49 for PAL
77877497c49SRudolf Cornelissen 	buffer[29] = 0x8c;		//my: y $8c for PAL
77977497c49SRudolf Cornelissen 	buffer[30] = 0x31;		//lsb msc: msc b31-0: PAL formula: ((4433619 / pixelclk) * 2^32) = MSC
78077497c49SRudolf Cornelissen 	buffer[31] = 0x8c;		//msc = $26798c31
78177497c49SRudolf Cornelissen 	buffer[32] = 0x79;
78277497c49SRudolf Cornelissen 	buffer[33] = 0x26;		//msb msc.
78377497c49SRudolf Cornelissen 	buffer[34] = 0x00;		//phase_off always $00
78477497c49SRudolf Cornelissen 
78577497c49SRudolf Cornelissen 	/* reset status */
78677497c49SRudolf Cornelissen 	i2c_flag_error (-1);
78777497c49SRudolf Cornelissen 
78877497c49SRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
78977497c49SRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
79077497c49SRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
79177497c49SRudolf Cornelissen 	/* log on errors */
79277497c49SRudolf Cornelissen 	stat = i2c_flag_error(0);
79377497c49SRudolf Cornelissen 	if (stat)
79477497c49SRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while setting mode PAL800 OS\n"));
79577497c49SRudolf Cornelissen 
79677497c49SRudolf Cornelissen 	return stat;
79777497c49SRudolf Cornelissen }//end BT_init_PAL800_OS.
79877497c49SRudolf Cornelissen 
79977497c49SRudolf Cornelissen static uint8 BT_init_NTSC640_OS()
800fb6cadf1Sshatty {
80177497c49SRudolf Cornelissen 	uint8 stat;
802fb6cadf1Sshatty 
80377497c49SRudolf Cornelissen 	uint8 buffer[35];
804fb6cadf1Sshatty 
8059a7218c5SRudolf Cornelissen 	LOG(4,("Brooktree: Setting NTSC 640x480 overscanning VCD mode\n"));
8069a7218c5SRudolf Cornelissen 
8079a7218c5SRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + WR;	//issue I2C write command
80877497c49SRudolf Cornelissen 	buffer[1] = 0x76;		//select first bt register to write to.
80977497c49SRudolf Cornelissen 	buffer[2] = 0x20;		//lsb h_clk_o: overscan comp = 0, so h_clk_o = 2 * h_clk_i (VSR=2 = scaling=1)
81077497c49SRudolf Cornelissen 	buffer[3] = 0x80;		//lsb h_active: h_active = 640 pixels wide port
81177497c49SRudolf Cornelissen 	buffer[4] = 0x74;	//scope: OK hsync_width: (hsync_width / h_clk_o) * 63.55556uS = 4.70uS for NTSC
81277497c49SRudolf Cornelissen 	buffer[5] = 0x83;	//scope: OK	hburst_begin: (hburst_begin / h_clk_o) * 63.55556uS = 5.3uS for NTSC
81377497c49SRudolf Cornelissen 	buffer[6] = 0x44;	//scope: OK hburst_end: ((hburst_end + 128) / h_clk_o) * 63.55556uS = 7.94uS for NTSC
814fb6cadf1Sshatty 
81577497c49SRudolf Cornelissen 	//How to find the correct values for h_blank_o and v_blank_o:
81677497c49SRudolf Cornelissen 	// 1. Calculate h_blank_o according to initial setting guideline mentioned below;
81777497c49SRudolf 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
81877497c49SRudolf Cornelissen 	//    horizontal position is about OK;
81977497c49SRudolf Cornelissen 	// 3. Then tune h_blank_o for centered output on scope (look at front porch and back porch);
82077497c49SRudolf Cornelissen 	// 4. Now shift the TV output using Hsync_offset for centered output while looking at TV (in method 'SetBT_Hphase' above);
82177497c49SRudolf Cornelissen 	// 5. If no vertical shivering occurs when image is centered, you're done. Else:
82277497c49SRudolf Cornelissen 	// 6. Modify the RIVA (BeScreen) h_sync_start setting somewhat to get stable centered picture possible on TV AND!:
82377497c49SRudolf Cornelissen 	// 7. Make sure you update the Chrontel horizontal Phase setting also then!
824fb6cadf1Sshatty 
82577497c49SRudolf Cornelissen 	buffer[7] = 0xf7;	//scope: tuned. lsb h_blank_o: h_blank_o = horizontal viewport location on TV:
82677497c49SRudolf Cornelissen 						//(guideline for initial setting: (h_blank_o / h_clk_0) * 63.55556uS = 9.5uS for NTSC)
827fb6cadf1Sshatty 
82877497c49SRudolf Cornelissen 	if (si->ps.tv_encoder.type >= CX25870)//set CX value
82977497c49SRudolf Cornelissen 		buffer[8] = 0x1d;
83077497c49SRudolf Cornelissen 	else //set BT value
83177497c49SRudolf Cornelissen 		buffer[8] = 0x1c;//try-out; scope: checked against other modes, looks OK.	v_blank_o: 1e active line ('pixel')
832fb6cadf1Sshatty 
83377497c49SRudolf Cornelissen 	buffer[9] = 0xf2;		//v_active_o: = (active output lines + 2) / field (on TV)
83477497c49SRudolf Cornelissen 	buffer[10] = 0x26;		//lsn = msn h_clk_o;
83577497c49SRudolf Cornelissen 							//b4-5 = msbits h_active;
83677497c49SRudolf Cornelissen 							//b7 = b8 v_avtive_o.
83777497c49SRudolf Cornelissen 	buffer[11] = 0x00;		//h_fract is always 0.
83877497c49SRudolf Cornelissen 	buffer[12] = 0x10;		//lsb h_clk_i: h_clk_i is horizontal total = 784.
83977497c49SRudolf Cornelissen 	buffer[13] = 0x14;	//try-out; lsb h_blank_i: #clks between start sync and new line 1st pixel; copy to VGA delta-sync!
84077497c49SRudolf Cornelissen 	buffer[14] = 0x03;		//b2-0 = msn h_clk_i;
84177497c49SRudolf Cornelissen 						//try-out: b3 = msn h_blank_i;
84277497c49SRudolf Cornelissen 							//b4 = vblankdly is always 0.
84377497c49SRudolf Cornelissen 	buffer[15] = 0x0d;		//lsb v_lines_i: v_lines_i = 525
84477497c49SRudolf Cornelissen 	buffer[16] = 0x18;	//try-out;	v_blank_i: #input lines between start sync and new line (pixel); copy to VGA delta-sync!
84577497c49SRudolf Cornelissen 					 	//Make sure though that this value for the BT is *even*, or image will shiver a *lot* horizontally on TV.
84677497c49SRudolf Cornelissen 	buffer[17] = 0xe0;		//lsb v_active_i: v_active_i = 480
84777497c49SRudolf Cornelissen 	buffer[18] = 0x36;		//b1-0 = msn v_lines_i;
84877497c49SRudolf Cornelissen 							//b3-2 = msn v_active_i;
84977497c49SRudolf Cornelissen 							//b5-4 = ylpf = 3;
85077497c49SRudolf Cornelissen 							//b7-6 = clpf = 0.
85177497c49SRudolf Cornelissen 	buffer[19] = 0x00;		//lsb v_scale: v_scale = off = $1000
85277497c49SRudolf Cornelissen 	buffer[20] = 0x10;		//b5-0 = msn v_scale;
85377497c49SRudolf Cornelissen 						//scope: tuned. b7-6 = msn h_blank_o.
85477497c49SRudolf Cornelissen 							//(((PLL_INT + (PLL_FRACT/65536)) / 6) * 13500000) = PIXEL_CLK = (hor.tot. * v_lines_i * 60Hz)
85577497c49SRudolf Cornelissen 	buffer[21] = 0xdb;		//lsb PLL fract: PLL fract = 0xf9db
85677497c49SRudolf Cornelissen 	buffer[22] = 0xf9;		//msb PLL fract
85777497c49SRudolf Cornelissen 	buffer[23] = 0x8a;		//b5-0 = PLL int: PLL int = 0x0a;
85877497c49SRudolf Cornelissen 							//b6 = by_pll: by_pll = 0;
85977497c49SRudolf Cornelissen 							//b7 = EN_XCLK: chip-pin CLKI is pixel clock.
86077497c49SRudolf Cornelissen 	buffer[24] = 0x0a;		//b0 = ni_out is always 0;
86177497c49SRudolf Cornelissen 							//b1 = setup = 1 for NTSC;
86277497c49SRudolf Cornelissen 							//b2 = 625line = 0 for NTSC;
86377497c49SRudolf Cornelissen 							//b3 = vsync_dur = 1 for NTSC;
86477497c49SRudolf Cornelissen 							//b4 = dic_screset is always 0;
86577497c49SRudolf Cornelissen 							//b5 = pal_md = 0 for NTSC;
86677497c49SRudolf Cornelissen 							//b6 = eclip is always 0;
86777497c49SRudolf Cornelissen 							//b7 = reserved (en_scart) is always 0.
86877497c49SRudolf Cornelissen 	buffer[25] = 0xe5;		//sync_amp $e5 for NTSC
86977497c49SRudolf Cornelissen 	buffer[26] = 0x75;		//bst_amp $74-$76 for NTSC
87077497c49SRudolf Cornelissen 	buffer[27] = 0x78;		//mcr: r-y $77-$79 for NTSC
87177497c49SRudolf Cornelissen 	buffer[28] = 0x44;		//mcb: b-y $43-$44 for NTSC
87277497c49SRudolf Cornelissen 	buffer[29] = 0x85;		//my: y $85 for NTSC
87377497c49SRudolf Cornelissen 	buffer[30] = 0x37;		//lsb msc: msc b31-0: NTSC formula: ((3579545 / pixelclk) * 2^32) = MSC
87477497c49SRudolf Cornelissen 	buffer[31] = 0x12;		//msc = $251b1237
87577497c49SRudolf Cornelissen 	buffer[32] = 0x1b;
87677497c49SRudolf Cornelissen 	buffer[33] = 0x25;		//msb msc.
87777497c49SRudolf Cornelissen 	buffer[34] = 0x00;		//phase_off always $00
878fb6cadf1Sshatty 
87977497c49SRudolf Cornelissen 	/* reset status */
88077497c49SRudolf Cornelissen 	i2c_flag_error (-1);
881fb6cadf1Sshatty 
88277497c49SRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
88377497c49SRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
88477497c49SRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
88577497c49SRudolf Cornelissen 	/* log on errors */
88677497c49SRudolf Cornelissen 	stat = i2c_flag_error(0);
88777497c49SRudolf Cornelissen 	if (stat)
88877497c49SRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while setting mode NTSC640 OS\n"));
889fb6cadf1Sshatty 
89077497c49SRudolf Cornelissen 	return stat;
89177497c49SRudolf Cornelissen }//end BT_init_NTSC640_OS.
892fb6cadf1Sshatty 
89321f6ecabSRudolf Cornelissen static uint8 BT_testsignal(void)
89421f6ecabSRudolf Cornelissen {
89521f6ecabSRudolf Cornelissen 	uint8 stat;
89621f6ecabSRudolf Cornelissen 
89721f6ecabSRudolf Cornelissen 	uint8 buffer[3];
89821f6ecabSRudolf Cornelissen 
8999a7218c5SRudolf Cornelissen 	LOG(4,("Brooktree: Enabling testsignal\n"));
9009a7218c5SRudolf Cornelissen 
90121f6ecabSRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + WR;
90221f6ecabSRudolf Cornelissen 	/* select bt register for enabling colorbars and outputs */
90321f6ecabSRudolf Cornelissen 	buffer[1] = 0xc4;
90421f6ecabSRudolf Cornelissen 	/* issue the actual command */
90521f6ecabSRudolf Cornelissen 	buffer[2] = 0x05;
90621f6ecabSRudolf Cornelissen 
90721f6ecabSRudolf Cornelissen 	/* reset status */
90821f6ecabSRudolf Cornelissen 	i2c_flag_error (-1);
90921f6ecabSRudolf Cornelissen 
91021f6ecabSRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
91121f6ecabSRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
91221f6ecabSRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
91321f6ecabSRudolf Cornelissen 	/* log on errors */
91421f6ecabSRudolf Cornelissen 	stat = i2c_flag_error(0);
91521f6ecabSRudolf Cornelissen 	if (stat)
91621f6ecabSRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while setting up flickerfilter and outputs\n"));
91721f6ecabSRudolf Cornelissen 
91821f6ecabSRudolf Cornelissen 	return stat;
91921f6ecabSRudolf Cornelissen }//end BT_testsignal.
92021f6ecabSRudolf Cornelissen 
92121f6ecabSRudolf Cornelissen static uint8 BT_setup_output(uint8 monstat, uint8 output, uint8 ffilter)
92221f6ecabSRudolf Cornelissen {
92321f6ecabSRudolf Cornelissen 	uint8 stat;
92421f6ecabSRudolf Cornelissen 
92521f6ecabSRudolf Cornelissen 	uint8 buffer[7];
92621f6ecabSRudolf Cornelissen 
92721f6ecabSRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + WR;
92821f6ecabSRudolf Cornelissen 	/* select first TV config register to write */
92921f6ecabSRudolf Cornelissen 	buffer[1] = 0xc6;
93021f6ecabSRudolf Cornelissen 	/* input is 24bit mpx'd RGB, BLANK = out, sync = act. hi */
93121f6ecabSRudolf Cornelissen 	buffer[2] = 0x98;
93221f6ecabSRudolf Cornelissen 	/* disable all filters, exept flicker filter */
93321f6ecabSRudolf Cornelissen 	buffer[3] = 0x98;
93421f6ecabSRudolf Cornelissen 	if (!ffilter)
93521f6ecabSRudolf Cornelissen 	{
93621f6ecabSRudolf Cornelissen 		/* disable flicker filter */
93721f6ecabSRudolf Cornelissen 		buffer[3] = 0xc0;
9389a7218c5SRudolf Cornelissen 		LOG(4,("Brooktree: Disabling flickerfilter\n"));
93921f6ecabSRudolf Cornelissen 	}
9409a7218c5SRudolf Cornelissen 	else
9419a7218c5SRudolf Cornelissen 		LOG(4,("Brooktree: Enabling flickerfilter\n"));
9429a7218c5SRudolf Cornelissen 
94321f6ecabSRudolf Cornelissen 	/* (disable filters) */
94421f6ecabSRudolf Cornelissen 	buffer[4] = 0xc0;
94521f6ecabSRudolf Cornelissen 	/* (disable filters) */
94621f6ecabSRudolf Cornelissen 	buffer[5] = 0xc0;
94721f6ecabSRudolf Cornelissen 	switch (output)
94821f6ecabSRudolf Cornelissen 	/* Description of ELSA Erazor III hardware layout:
94921f6ecabSRudolf Cornelissen 	 * (This is the default (recommended) layout by NVIDIA)
95021f6ecabSRudolf Cornelissen 	 * DAC A = CVBS
95121f6ecabSRudolf Cornelissen 	 * DAC B = C (chrominance)
95221f6ecabSRudolf Cornelissen 	 * DAC C = Y (luminance) */
95321f6ecabSRudolf Cornelissen 
95421f6ecabSRudolf Cornelissen 	/* Description of Diamond VIPER550:
95521f6ecabSRudolf Cornelissen 	 * DAC A = Not connected
95621f6ecabSRudolf Cornelissen 	 * DAC B = C (chrominance)
95721f6ecabSRudolf Cornelissen 	 * DAC C = Y (luminance)
95821f6ecabSRudolf Cornelissen 	 * To be able to connect to CVBS TV's a special cable is supplied:
95921f6ecabSRudolf Cornelissen 	 * This cable connects the Y (DAC C) output to the TV CVBS input. */
96021f6ecabSRudolf Cornelissen 	{
9619a7218c5SRudolf Cornelissen 	case 1:
9629a7218c5SRudolf Cornelissen 		LOG(4,("Brooktree: Outputting both Y/C and CVBS where supported by hardware\n"));
9639a7218c5SRudolf Cornelissen 		buffer[6] = 0x18;	// Y/C and CVBS out if all ports implemented
96421f6ecabSRudolf Cornelissen 							// in hardware, else only Y/C or CVBS out.
96521f6ecabSRudolf Cornelissen 		break;
9669a7218c5SRudolf Cornelissen 	case 2:
9679a7218c5SRudolf Cornelissen 		LOG(4,("Brooktree: Outputting CVBS on all outputs\n"));
9689a7218c5SRudolf Cornelissen 		buffer[6] = 0x00;	// put CVBS on all outputs. Used for cards
96921f6ecabSRudolf Cornelissen 		break;				// with only Y/C out and 'translation cable'.
9709a7218c5SRudolf Cornelissen 	default:
971b0fce481SRudolf Cornelissen 		LOG(4,("Brooktree: Outputting signals according to autodetect status:\n"));
9729a7218c5SRudolf Cornelissen 		switch (monstat)	// only 'autodetect' remains...
97321f6ecabSRudolf Cornelissen 		{
9749a7218c5SRudolf Cornelissen 		case 1:
975b0fce481SRudolf Cornelissen 			LOG(4,("Brooktree: Only Y connected, outputting CVBS on all outputs\n"));
9769a7218c5SRudolf Cornelissen 			buffer[6] = 0x00;	//only Y connected: must be CVBS!
97721f6ecabSRudolf Cornelissen 			break;
9789a7218c5SRudolf Cornelissen 		case 2:
979b0fce481SRudolf Cornelissen 			LOG(4,("Brooktree: Only C connected, outputting CVBS on all outputs\n"));
9809a7218c5SRudolf Cornelissen 			buffer[6] = 0x00;	//only C connected: must be CVBS!
98121f6ecabSRudolf Cornelissen 			break;				//(though cable is wired wrong...)
9829a7218c5SRudolf Cornelissen 		case 5:
983b0fce481SRudolf Cornelissen 			LOG(4,("Brooktree: CVBS and only Y connected, outputting CVBS on all outputs\n"));
9849a7218c5SRudolf Cornelissen 			buffer[6] = 0x00;	//CVBS and only Y connected: 2x CVBS!
98521f6ecabSRudolf Cornelissen 			break;			   	//(officially not supported...)
9869a7218c5SRudolf Cornelissen 		case 6:
987b0fce481SRudolf Cornelissen 			LOG(4,("Brooktree: CVBS and only C connected, outputting CVBS on all outputs\n"));
9889a7218c5SRudolf Cornelissen 			buffer[6] = 0x00;	//CVBS and only C connected: 2x CVBS!
98921f6ecabSRudolf Cornelissen 			break;			   	//(officially not supported...)
9909a7218c5SRudolf Cornelissen 		default:
991b0fce481SRudolf Cornelissen 			LOG(4,("Brooktree: Outputting both Y/C and CVBS where supported by hardware\n"));
9929a7218c5SRudolf Cornelissen 			buffer[6] = 0x18;	//nothing, or
99321f6ecabSRudolf Cornelissen 							 	//Y/C only, or
99421f6ecabSRudolf Cornelissen 							 	//CVBS only (but on CVBS output), or
99521f6ecabSRudolf Cornelissen 							 	//Y/C and CVBS connected:
99621f6ecabSRudolf Cornelissen 							 	//So activate recommended signals.
99721f6ecabSRudolf Cornelissen 		}
99821f6ecabSRudolf Cornelissen 	}
99921f6ecabSRudolf Cornelissen 
100021f6ecabSRudolf Cornelissen 	/* reset status */
100121f6ecabSRudolf Cornelissen 	i2c_flag_error (-1);
100221f6ecabSRudolf Cornelissen 
100321f6ecabSRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
100421f6ecabSRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
100521f6ecabSRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
100621f6ecabSRudolf Cornelissen 	/* log on errors */
100721f6ecabSRudolf Cornelissen 	stat = i2c_flag_error(0);
100821f6ecabSRudolf Cornelissen 	if (stat)
100921f6ecabSRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while setting up flickerfilter and outputs\n"));
101021f6ecabSRudolf Cornelissen 
101121f6ecabSRudolf Cornelissen 	return stat;
101221f6ecabSRudolf Cornelissen }//end BT_setup_output.
101321f6ecabSRudolf Cornelissen 
101421f6ecabSRudolf Cornelissen static uint8 BT_setup_hphase(uint8 mode)
101521f6ecabSRudolf Cornelissen {
101621f6ecabSRudolf Cornelissen 	uint8 stat, hoffset;
101721f6ecabSRudolf Cornelissen 
101821f6ecabSRudolf Cornelissen 	uint8 buffer[7];
101921f6ecabSRudolf Cornelissen 
10209a7218c5SRudolf Cornelissen 	LOG(4,("Brooktree: Tuning horizontal phase\n"));
10219a7218c5SRudolf Cornelissen 
102221f6ecabSRudolf Cornelissen 	/* CX needs timing reset (advised on BT also), first 1mS delay needed! */
102321f6ecabSRudolf Cornelissen 	snooze(1000);
102421f6ecabSRudolf Cornelissen 
102521f6ecabSRudolf Cornelissen 	/* values below are all tested on TNT1, TNT2 and GeForce2MX */
102621f6ecabSRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + WR;
102721f6ecabSRudolf Cornelissen 	/* select first TV output timing register to write */
102821f6ecabSRudolf Cornelissen 	buffer[1] = 0x6c;
102921f6ecabSRudolf Cornelissen 	/* turn on active video & generate timing reset on CX chips! */
103021f6ecabSRudolf Cornelissen 	buffer[2] = 0x86;
103121f6ecabSRudolf Cornelissen 	/* (set fail save values...) */
103221f6ecabSRudolf Cornelissen 	buffer[3] = 0x00;		//set default horizontal sync offset
103321f6ecabSRudolf Cornelissen 	buffer[4] = 0x02;		//set default horizontal sync width
103421f6ecabSRudolf Cornelissen 	buffer[5] = 0x00;		//set default vertical sync offset
103521f6ecabSRudolf Cornelissen 
103621f6ecabSRudolf Cornelissen 	/* do specific timing setup for all chips and modes: */
10374594e58aSRudolf Cornelissen 	switch (si->ps.card_type)
1038b0fce481SRudolf Cornelissen 	{
10394594e58aSRudolf Cornelissen 	case NV05:
10404594e58aSRudolf Cornelissen 	case NV05M64:
10414594e58aSRudolf Cornelissen 	case NV15:
10424594e58aSRudolf Cornelissen 		/* confirmed TNT2, TNT2M64, GeForce2Ti.
1043b0fce481SRudolf Cornelissen 		 * (8 pixels delayed hpos, so picture more to the right) */
1044b0fce481SRudolf Cornelissen 		hoffset = 8;
10454594e58aSRudolf Cornelissen 		break;
10464594e58aSRudolf Cornelissen 	default:
10474594e58aSRudolf Cornelissen 		/* confirmed TNT1, GeForce256, GeForce2MX.
1048b0fce481SRudolf Cornelissen 		 * (std hpos)
1049b0fce481SRudolf Cornelissen 		 * NOTE: It might be that GeForce needs TNT2 offset:
1050b0fce481SRudolf Cornelissen 		 * for now CX chips get seperate extra offset, until sure.
1051b0fce481SRudolf Cornelissen 		 * (CX is only found AFAIK on GeForce cards, no BT tested
1052b0fce481SRudolf Cornelissen 		 * on GeForce yet. CH was tested on GeForce and seemed to
1053b0fce481SRudolf Cornelissen 		 * indicate TNT1 offset was needed.) */
1054b0fce481SRudolf Cornelissen 		hoffset = 0;
10554594e58aSRudolf Cornelissen 		break;
1056b0fce481SRudolf Cornelissen 	}
105721f6ecabSRudolf Cornelissen 
105821f6ecabSRudolf Cornelissen 	switch (mode)
105921f6ecabSRudolf Cornelissen 	{
106021f6ecabSRudolf Cornelissen 	case NTSC640_TST:
106121f6ecabSRudolf Cornelissen 	case NTSC640:
106221f6ecabSRudolf Cornelissen 		if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
10634e918a7cSRudolf Cornelissen 		/* confirmed on TNT1 with BT869 using 4:3 TV and 16:9 TV */
1064f2069d6cSRudolf Cornelissen 		buffer[3] = (0x1e + hoffset);	//set horizontal sync offset
106521f6ecabSRudolf Cornelissen 		break;
106621f6ecabSRudolf Cornelissen 	case NTSC800:
106721f6ecabSRudolf Cornelissen 		if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
106821f6ecabSRudolf Cornelissen 		buffer[3] = (0xe1 + hoffset);	//set horizontal sync offset
106921f6ecabSRudolf Cornelissen 		buffer[4] = 0xc2;
107021f6ecabSRudolf Cornelissen 		//Vsync offset reg. does not exist on CX: mode is checked and OK.
107121f6ecabSRudolf Cornelissen 		buffer[5] = 0x40;				//set VSync offset (on BT's only)
107221f6ecabSRudolf Cornelissen 		break;
107321f6ecabSRudolf Cornelissen 	case PAL640:
107421f6ecabSRudolf Cornelissen 		if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
107521f6ecabSRudolf Cornelissen 		buffer[3] = (0xa8 + hoffset);
107621f6ecabSRudolf Cornelissen 		break;
107721f6ecabSRudolf Cornelissen 	case PAL800_TST:
107821f6ecabSRudolf Cornelissen 	case PAL800:
107921f6ecabSRudolf Cornelissen 		if (si->ps.tv_encoder.type >= CX25870) hoffset +=8; //if CX shift picture right some more...
108021f6ecabSRudolf Cornelissen 		buffer[3] = (0x2c + hoffset);
108121f6ecabSRudolf Cornelissen 		break;
108221f6ecabSRudolf Cornelissen 	case NTSC720:
108321f6ecabSRudolf Cornelissen 		if (si->ps.tv_encoder.type >= CX25870)
108421f6ecabSRudolf Cornelissen 			buffer[3] = (0xb2 + hoffset); //set horizontal sync offset CX
108521f6ecabSRudolf Cornelissen 		else
108621f6ecabSRudolf Cornelissen 			buffer[3] = (0xd0 + hoffset); //set horizontal sync offset BT
108721f6ecabSRudolf Cornelissen 		buffer[4] = 0xff;				//hsync width = max:
108821f6ecabSRudolf Cornelissen 		break;							//to prevent vertical image 'shivering'.
108921f6ecabSRudolf Cornelissen 	case PAL720:
109021f6ecabSRudolf Cornelissen 		buffer[3] = (0xd4 + hoffset);
109121f6ecabSRudolf Cornelissen 		buffer[4] = 0xff;
109221f6ecabSRudolf Cornelissen 		break;
109321f6ecabSRudolf Cornelissen 	case NTSC640_OS:
109421f6ecabSRudolf Cornelissen 		buffer[3] = (0xc8 + hoffset);
109521f6ecabSRudolf Cornelissen 		buffer[4] = 0xff;
109621f6ecabSRudolf Cornelissen 		break;
109721f6ecabSRudolf Cornelissen 	case PAL800_OS:
109821f6ecabSRudolf Cornelissen 		if (si->ps.tv_encoder.type >= CX25870)
109921f6ecabSRudolf Cornelissen 			buffer[3] = (0x78 + hoffset); //set horizontal sync offset CX
110021f6ecabSRudolf Cornelissen 		else
110121f6ecabSRudolf Cornelissen 			buffer[3] = (0xc4 + hoffset); //set horizontal sync offset BT
110221f6ecabSRudolf Cornelissen 		buffer[4] = 0xff;
110321f6ecabSRudolf Cornelissen 		break;
110421f6ecabSRudolf Cornelissen 	default: //nothing to be done here...
110521f6ecabSRudolf Cornelissen 		break;
110621f6ecabSRudolf Cornelissen 	}
110721f6ecabSRudolf Cornelissen 
110821f6ecabSRudolf Cornelissen 	buffer[6] = 0x01;		//set default vertical sync width
110921f6ecabSRudolf Cornelissen 
111021f6ecabSRudolf Cornelissen 	/* reset status */
111121f6ecabSRudolf Cornelissen 	i2c_flag_error (-1);
111221f6ecabSRudolf Cornelissen 
111321f6ecabSRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
111421f6ecabSRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
111521f6ecabSRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
111621f6ecabSRudolf Cornelissen 	/* log on errors */
111721f6ecabSRudolf Cornelissen 	stat = i2c_flag_error(0);
111821f6ecabSRudolf Cornelissen 	if (stat)
111921f6ecabSRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while setting up h_phase\n"));
112021f6ecabSRudolf Cornelissen 
112121f6ecabSRudolf Cornelissen 	return stat;
112221f6ecabSRudolf Cornelissen }//end BT_setup_hphase.
112321f6ecabSRudolf Cornelissen 
112421f6ecabSRudolf Cornelissen static uint8 BT_read_monstat(uint8* monstat)
112521f6ecabSRudolf Cornelissen {
112621f6ecabSRudolf Cornelissen 	uint8 stat;
112721f6ecabSRudolf Cornelissen 	uint8 buffer[3];
112821f6ecabSRudolf Cornelissen 
1129efe9c7a6SRudolf Cornelissen 	/* make sure we have the recommended failsafe selected */
1130efe9c7a6SRudolf Cornelissen 	*monstat = 0;
1131efe9c7a6SRudolf Cornelissen 
11329a7218c5SRudolf Cornelissen 	LOG(4,("Brooktree: Autodetecting connected output devices\n"));
11339a7218c5SRudolf Cornelissen 
113421f6ecabSRudolf Cornelissen 	/* set BT to return connection status in ESTATUS on next read CMD: */
113521f6ecabSRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + WR;
113621f6ecabSRudolf Cornelissen 	/* set ESTATUS at b'01' (return conn.stat.) */
113721f6ecabSRudolf Cornelissen 	buffer[1] = 0xc4;
113821f6ecabSRudolf Cornelissen 	/* and leave chip outputs on. */
113921f6ecabSRudolf Cornelissen 	buffer[2] = 0x41;
114021f6ecabSRudolf Cornelissen 
114121f6ecabSRudolf Cornelissen 	/* reset status */
114221f6ecabSRudolf Cornelissen 	i2c_flag_error (-1);
114321f6ecabSRudolf Cornelissen 
114421f6ecabSRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
114521f6ecabSRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
114621f6ecabSRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
114721f6ecabSRudolf Cornelissen 	/* log on errors */
114821f6ecabSRudolf Cornelissen 	stat = i2c_flag_error(0);
114921f6ecabSRudolf Cornelissen 	if (stat)
115021f6ecabSRudolf Cornelissen 	{
115121f6ecabSRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while reading connection status (1)\n"));
115221f6ecabSRudolf Cornelissen 		return stat;
115321f6ecabSRudolf Cornelissen 	}
115421f6ecabSRudolf Cornelissen 
115521f6ecabSRudolf Cornelissen 	/* do actual read connection status: */
115621f6ecabSRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + WR;
115721f6ecabSRudolf Cornelissen 	/* select register with CHECK_STAT CMD */
115821f6ecabSRudolf Cornelissen 	buffer[1] = 0xba;
115921f6ecabSRudolf Cornelissen 	/* issue actual command. */
116021f6ecabSRudolf Cornelissen 	buffer[2] = 0x40;
116121f6ecabSRudolf Cornelissen 
116221f6ecabSRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
116321f6ecabSRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
116421f6ecabSRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
116521f6ecabSRudolf Cornelissen 	/* log on errors */
116621f6ecabSRudolf Cornelissen 	stat = i2c_flag_error(0);
116721f6ecabSRudolf Cornelissen 	if (stat)
116821f6ecabSRudolf Cornelissen 	{
116921f6ecabSRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while reading connection status (2)\n"));
117021f6ecabSRudolf Cornelissen 		return stat;
117121f6ecabSRudolf Cornelissen 	}
117221f6ecabSRudolf Cornelissen 
117321f6ecabSRudolf Cornelissen 	/* CX: Wait 600uS for signals to stabilize (see datasheet) */
117421f6ecabSRudolf Cornelissen 	/* warning, note:
117521f6ecabSRudolf Cornelissen 	 * datasheet is in error! 60mS needed!! */
117621f6ecabSRudolf Cornelissen 	snooze(60000);
117721f6ecabSRudolf Cornelissen 
117821f6ecabSRudolf Cornelissen 	/* read back updated connection status: */
117921f6ecabSRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + RD;
118021f6ecabSRudolf Cornelissen 
118121f6ecabSRudolf Cornelissen 	/* transmit 1 byte */
118221f6ecabSRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
118321f6ecabSRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 1);
118421f6ecabSRudolf Cornelissen 
118521f6ecabSRudolf Cornelissen 	/* receive 1 byte */
11869a7218c5SRudolf Cornelissen 	/* ACK level to TX after last byte to RX should be 1 (= NACK) (see I2C spec)
118721f6ecabSRudolf Cornelissen 	 * While the BT's don't care, CX chips will block the SDA line if an ACK gets sent! */
118821f6ecabSRudolf Cornelissen 	buffer[0] = 1;
118921f6ecabSRudolf Cornelissen 	i2c_readbuffer(si->ps.tv_encoder.bus, buffer, 1);
119021f6ecabSRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
119121f6ecabSRudolf Cornelissen 	/* log on errors */
119221f6ecabSRudolf Cornelissen 	stat = i2c_flag_error(0);
119321f6ecabSRudolf Cornelissen 	if (stat)
119421f6ecabSRudolf Cornelissen 	{
119521f6ecabSRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while reading connection status (3)\n"));
119621f6ecabSRudolf Cornelissen 		return stat;
119721f6ecabSRudolf Cornelissen 	}
119821f6ecabSRudolf Cornelissen 
119921f6ecabSRudolf Cornelissen 	*monstat = ((buffer[0] & 0xe0) >> 5);
120021f6ecabSRudolf Cornelissen 	LOG(4,("Brooktree: TV output monitor status = %d\n", *monstat));
120121f6ecabSRudolf Cornelissen 
120221f6ecabSRudolf Cornelissen 	/* instruct BT to go back to normal operation: */
120321f6ecabSRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + WR;
120421f6ecabSRudolf Cornelissen 	/* select register with CHECK_STAT CMD */
120521f6ecabSRudolf Cornelissen 	buffer[1] = 0xba;
120621f6ecabSRudolf Cornelissen 	/* issue actual command. */
120721f6ecabSRudolf Cornelissen 	buffer[2] = 0x00;
120821f6ecabSRudolf Cornelissen 
120921f6ecabSRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
121021f6ecabSRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
121121f6ecabSRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
121221f6ecabSRudolf Cornelissen 	/* log on errors */
121321f6ecabSRudolf Cornelissen 	stat = i2c_flag_error(0);
121421f6ecabSRudolf Cornelissen 	if (stat)
121521f6ecabSRudolf Cornelissen 	{
121621f6ecabSRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while reading connection status (4)\n"));
121721f6ecabSRudolf Cornelissen 		return stat;
121821f6ecabSRudolf Cornelissen 	}
121921f6ecabSRudolf Cornelissen 
122021f6ecabSRudolf Cornelissen 	return stat;
122121f6ecabSRudolf Cornelissen }//end BT_read_monstat.
122221f6ecabSRudolf Cornelissen 
122321f6ecabSRudolf Cornelissen static uint8 BT_killclk_blackout(void)
122421f6ecabSRudolf Cornelissen {
122521f6ecabSRudolf Cornelissen 	uint8 stat;
122621f6ecabSRudolf Cornelissen 
122721f6ecabSRudolf Cornelissen 	uint8 buffer[4];
122821f6ecabSRudolf Cornelissen 
12299a7218c5SRudolf Cornelissen 	LOG(4,("Brooktree: Killing clock and/or blacking out (blocking output signals)\n"));
12309a7218c5SRudolf Cornelissen 
123121f6ecabSRudolf Cornelissen 	/* reset status */
123221f6ecabSRudolf Cornelissen 	i2c_flag_error (-1);
123321f6ecabSRudolf Cornelissen 
123421f6ecabSRudolf Cornelissen 	if (si->ps.tv_encoder.type <= BT869) //BT...
123521f6ecabSRudolf Cornelissen 	{
123621f6ecabSRudolf Cornelissen 		/* Only disable external pixelclock input on BT's.
123721f6ecabSRudolf Cornelissen 		 * CX chips will lock the bus if you do this.
123821f6ecabSRudolf Cornelissen 		 * (It looks like the external pixelclock is always OK as long as a valid
123921f6ecabSRudolf Cornelissen 		 * mode is programmed for the TVout chip. This means that disabling the use
124021f6ecabSRudolf Cornelissen 		 * of this clock is not needed anyway.
124121f6ecabSRudolf Cornelissen 		 * If you do disable this input, this pixelclock will rise to about 60Mhz BTW..) */
124221f6ecabSRudolf Cornelissen 
124321f6ecabSRudolf Cornelissen 		/* disable use of external pixelclock source... */
124421f6ecabSRudolf Cornelissen 		/* (should prevent BT for being 'overclocked' by RIVA in VGA-only mode...) */
124521f6ecabSRudolf Cornelissen 		buffer[0] = si->ps.tv_encoder.adress + WR;
124621f6ecabSRudolf Cornelissen 		/* select BT register for setting EN_XCLK */
124721f6ecabSRudolf Cornelissen 		buffer[1] = 0xa0;
124821f6ecabSRudolf Cornelissen 		/* clear it */
124921f6ecabSRudolf Cornelissen 		buffer[2] = 0x00;
125021f6ecabSRudolf Cornelissen 
125121f6ecabSRudolf Cornelissen 		i2c_bstart(si->ps.tv_encoder.bus);
125221f6ecabSRudolf Cornelissen 		i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3);
125321f6ecabSRudolf Cornelissen 		i2c_bstop(si->ps.tv_encoder.bus);
125421f6ecabSRudolf Cornelissen 		/* log on errors */
125521f6ecabSRudolf Cornelissen 		stat = i2c_flag_error(0);
125621f6ecabSRudolf Cornelissen 		if (stat)
125721f6ecabSRudolf Cornelissen 		{
125821f6ecabSRudolf Cornelissen 			LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (1-BT)\n"));
125921f6ecabSRudolf Cornelissen 			return stat;
126021f6ecabSRudolf Cornelissen 		}
126121f6ecabSRudolf Cornelissen 	}
126221f6ecabSRudolf Cornelissen 	else //CX...
126321f6ecabSRudolf Cornelissen 	{
126421f6ecabSRudolf Cornelissen 		/* Disable CX video out (or wild output will be seen on TV..) */
126521f6ecabSRudolf Cornelissen 		buffer[0] = si->ps.tv_encoder.adress + WR;
126621f6ecabSRudolf Cornelissen 		/* select register in CX */
126721f6ecabSRudolf Cornelissen 		buffer[1] = 0x6c;
126821f6ecabSRudolf Cornelissen 		/* disable active video out. */
126921f6ecabSRudolf Cornelissen 		buffer[2] = 0x02;
127021f6ecabSRudolf Cornelissen 
127121f6ecabSRudolf Cornelissen 		i2c_bstart(si->ps.tv_encoder.bus);
127221f6ecabSRudolf Cornelissen 		i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3);
127321f6ecabSRudolf Cornelissen 		i2c_bstop(si->ps.tv_encoder.bus);
127421f6ecabSRudolf Cornelissen 		/* log on errors */
127521f6ecabSRudolf Cornelissen 		stat = i2c_flag_error(0);
127621f6ecabSRudolf Cornelissen 		if (stat)
127721f6ecabSRudolf Cornelissen 		{
127821f6ecabSRudolf Cornelissen 			LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (1-CX)\n"));
127921f6ecabSRudolf Cornelissen 			return stat;
128021f6ecabSRudolf Cornelissen 		}
128121f6ecabSRudolf Cornelissen 	}
128221f6ecabSRudolf Cornelissen 
128321f6ecabSRudolf Cornelissen 	/* black-out TVout while outputs are enabled... */
128421f6ecabSRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + WR;
128521f6ecabSRudolf Cornelissen 	/* select first TV config register to write */
128621f6ecabSRudolf Cornelissen 	buffer[1] = 0xc4;
128721f6ecabSRudolf Cornelissen 	/* disable testimage while outputs remain enabled */
128821f6ecabSRudolf Cornelissen 	buffer[2] = 0x01;
128921f6ecabSRudolf Cornelissen 	/* input is 24bit mpx'd RGB, BLANK = in, sync = act. hi */
129021f6ecabSRudolf Cornelissen 	buffer[3] = 0x18;
129121f6ecabSRudolf Cornelissen 
129221f6ecabSRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
129321f6ecabSRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, sizeof(buffer));
129421f6ecabSRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
129521f6ecabSRudolf Cornelissen 	/* log on errors */
129621f6ecabSRudolf Cornelissen 	stat = i2c_flag_error(0);
129721f6ecabSRudolf Cornelissen 	if (stat)
129821f6ecabSRudolf Cornelissen 	{
129921f6ecabSRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while doing killclk_blackout (2)\n"));
130021f6ecabSRudolf Cornelissen 		return stat;
130121f6ecabSRudolf Cornelissen 	}
130221f6ecabSRudolf Cornelissen 
130321f6ecabSRudolf Cornelissen 	return stat;
130421f6ecabSRudolf Cornelissen }//end BT_killclk_blackout.
130521f6ecabSRudolf Cornelissen 
13063aa21459SRudolf Cornelissen uint8 BT_dpms(bool display)
13073aa21459SRudolf Cornelissen {
13083aa21459SRudolf Cornelissen 	uint8 stat;
13093aa21459SRudolf Cornelissen 
13103aa21459SRudolf Cornelissen 	uint8 buffer[3];
13113aa21459SRudolf Cornelissen 
13123aa21459SRudolf Cornelissen 	LOG(4,("Brooktree: setting DPMS: "));
13133aa21459SRudolf Cornelissen 
13143aa21459SRudolf Cornelissen 	/* reset status */
13153aa21459SRudolf Cornelissen 	i2c_flag_error (-1);
13163aa21459SRudolf Cornelissen 
13173aa21459SRudolf Cornelissen 	/* shutdown all analog electronics... */
13183aa21459SRudolf Cornelissen 	buffer[0] = si->ps.tv_encoder.adress + WR;
13193aa21459SRudolf Cornelissen 	/* select first TV config register to write */
13203aa21459SRudolf Cornelissen 	buffer[1] = 0xba;
13213aa21459SRudolf Cornelissen 	if (display)
13223aa21459SRudolf Cornelissen 	{
13233aa21459SRudolf Cornelissen 		/* enable all DACs */
13243aa21459SRudolf Cornelissen 		buffer[2] = 0x00;
13253aa21459SRudolf Cornelissen 		LOG(4,("display on\n"));
13263aa21459SRudolf Cornelissen 	}
13273aa21459SRudolf Cornelissen 	else
13283aa21459SRudolf Cornelissen 	{
13293aa21459SRudolf Cornelissen 		/* shutdown all DACs */
13303aa21459SRudolf Cornelissen 		buffer[2] = 0x10;
13313aa21459SRudolf Cornelissen 		LOG(4,("display off\n"));
13323aa21459SRudolf Cornelissen 	}
13333aa21459SRudolf Cornelissen 
13343aa21459SRudolf Cornelissen 	i2c_bstart(si->ps.tv_encoder.bus);
13353aa21459SRudolf Cornelissen 	i2c_writebuffer(si->ps.tv_encoder.bus, buffer, 3);
13363aa21459SRudolf Cornelissen 	i2c_bstop(si->ps.tv_encoder.bus);
13373aa21459SRudolf Cornelissen 	/* log on errors */
13383aa21459SRudolf Cornelissen 	stat = i2c_flag_error(0);
13393aa21459SRudolf Cornelissen 	if (stat)
13403aa21459SRudolf Cornelissen 	{
13413aa21459SRudolf Cornelissen 		LOG(4,("Brooktree: I2C errors occurred while setting DPMS\n"));
13423aa21459SRudolf Cornelissen 		return stat;
13433aa21459SRudolf Cornelissen 	}
13443aa21459SRudolf Cornelissen 
13453aa21459SRudolf Cornelissen 	return stat;
13463aa21459SRudolf Cornelissen }//end BT_dpms.
13473aa21459SRudolf Cornelissen 
1348b2459715SRudolf Cornelissen uint8 BT_check_tvmode(display_mode target)
1349fb6cadf1Sshatty {
1350b2459715SRudolf Cornelissen 	uint8 status = NOT_SUPPORTED;
1351b2459715SRudolf Cornelissen 	uint32 mode = ((target.timing.h_display) | ((target.timing.v_display) << 16));
1352b2459715SRudolf Cornelissen 
1353b2459715SRudolf Cornelissen 	switch (mode)
1354b2459715SRudolf Cornelissen 	{
1355b2459715SRudolf Cornelissen 	case (640 | (480 << 16)):
1356c5fe5f2dSRudolf Cornelissen 		if (((target.flags & TV_BITS) == TV_PAL) && (!(target.flags & TV_VIDEO)))
1357c5fe5f2dSRudolf Cornelissen 			status = PAL640;
1358b2459715SRudolf Cornelissen 		if ((target.flags & TV_BITS) == TV_NTSC)
1359b2459715SRudolf Cornelissen 		{
1360b2459715SRudolf Cornelissen 			if (!(target.flags & TV_VIDEO)) status = NTSC640;
1361b2459715SRudolf Cornelissen 			else status = NTSC640_OS;
1362b2459715SRudolf Cornelissen 		}
1363b2459715SRudolf Cornelissen 		break;
1364c5fe5f2dSRudolf Cornelissen 	case (768 | (576 << 16)):
1365c5fe5f2dSRudolf Cornelissen 		if (((target.flags & TV_BITS) == TV_PAL) && (target.flags & TV_VIDEO))
1366c5fe5f2dSRudolf Cornelissen 			status = PAL800_OS;
1367c5fe5f2dSRudolf Cornelissen 		break;
1368b2459715SRudolf Cornelissen 	case (800 | (600 << 16)):
1369c5fe5f2dSRudolf Cornelissen 		if (((target.flags & TV_BITS) == TV_PAL) && (!(target.flags & TV_VIDEO)))
1370c5fe5f2dSRudolf Cornelissen 			status = PAL800;
1371c5fe5f2dSRudolf Cornelissen 		if (((target.flags & TV_BITS) == TV_NTSC) && (!(target.flags & TV_VIDEO)))
1372c5fe5f2dSRudolf Cornelissen 			status = NTSC800;
1373b2459715SRudolf Cornelissen 		break;
1374b2459715SRudolf Cornelissen 	case (720 | (480 << 16)):
1375b2459715SRudolf Cornelissen 		if (((target.flags & TV_BITS) == TV_NTSC) && (target.flags & TV_VIDEO))
1376b2459715SRudolf Cornelissen 			status = NTSC720;
1377b2459715SRudolf Cornelissen 		break;
1378b2459715SRudolf Cornelissen 	case (720 | (576 << 16)):
1379b2459715SRudolf Cornelissen 		if (((target.flags & TV_BITS) == TV_PAL) && (target.flags & TV_VIDEO))
1380b2459715SRudolf Cornelissen 			status = PAL720;
1381b2459715SRudolf Cornelissen 		break;
1382b2459715SRudolf Cornelissen 	}
1383b2459715SRudolf Cornelissen 
1384b2459715SRudolf Cornelissen 	return status;
1385b2459715SRudolf Cornelissen }//end BT_check_tvmode.
1386b2459715SRudolf Cornelissen 
1387bd7693f2SRudolf Cornelissen 
1388bd7693f2SRudolf Cornelissen /*
1389da3804eeSRudolf Cornelissen //BeTVOut's SwitchRIVAtoTV(vtot) timing formula: (note: vtot = (v_total - 2))
1390bd7693f2SRudolf Cornelissen //-----------------------------------------------------------------------------------
1391bd7693f2SRudolf Cornelissen //HORIZONTAL:
1392bd7693f2SRudolf Cornelissen //-----------
1393bd7693f2SRudolf Cornelissen h_sync_start = h_display;
1394bd7693f2SRudolf Cornelissen 
1395bd7693f2SRudolf Cornelissen //fixme, note, checkout:
1396bd7693f2SRudolf Cornelissen //feels like in fact TNT2-M64 nv_crtc.c registerprogramming should be adapted...
1397bd7693f2SRudolf Cornelissen if (TNT2-M64)
1398bd7693f2SRudolf Cornelissen {
1399bd7693f2SRudolf Cornelissen 	h_sync_end = h_display + 8;
1400bd7693f2SRudolf Cornelissen 	h_total = h_display + 56;
1401bd7693f2SRudolf Cornelissen }
1402bd7693f2SRudolf Cornelissen else //TNT1, TNT2, Geforce2... (so default)
1403bd7693f2SRudolf Cornelissen {
1404bd7693f2SRudolf Cornelissen 	h_sync_end = h_display + 16;
1405bd7693f2SRudolf Cornelissen 	h_total = h_display + 48;
1406bd7693f2SRudolf Cornelissen }
1407bd7693f2SRudolf Cornelissen 
1408bd7693f2SRudolf Cornelissen //fixme, note, checkout:
1409bd7693f2SRudolf Cornelissen //BeTVOut uses two 'tweaks':
1410bd7693f2SRudolf Cornelissen // - on TNT2-M64 only:
1411bd7693f2SRudolf Cornelissen //   register h_blank_e is increased with 1 (so should be done in nv_crtc.c here)
1412463f0fabSRudolf Cornelissen // - 'all cards':
1413463f0fabSRudolf Cornelissen //   register h_blank_e b6 = 0 (only influences TNT2-M64 in modes NTSC800 and PAL800).
1414bd7693f2SRudolf Cornelissen //-----------------------------------------------------------------------------------
1415bd7693f2SRudolf Cornelissen //VERTICAL:
1416bd7693f2SRudolf Cornelissen //---------
1417da3804eeSRudolf Cornelissen v_sync_start = v_display;
1418da3804eeSRudolf Cornelissen v_total = vtot + 2;
1419da3804eeSRudolf Cornelissen v_sync_end = v_total - 1; //(This takes care of the 'cursor trash' on TNT1's...)
1420bd7693f2SRudolf Cornelissen //-----------------------------------------------------------------------------------
1421bd7693f2SRudolf Cornelissen */
142285406c4dSRudolf Cornelissen static status_t BT_update_mode_for_gpu(display_mode *target, uint8 tvmode)
142385406c4dSRudolf Cornelissen {
1424b0fce481SRudolf Cornelissen 	//fixme if needed:
1425b0fce481SRudolf Cornelissen 	//pixelclock is not actually pgm'd because PLL is pgm' earlier during setmode...
142685406c4dSRudolf Cornelissen 	switch (tvmode)
142785406c4dSRudolf Cornelissen 	{
142885406c4dSRudolf Cornelissen 	case NTSC640:
142985406c4dSRudolf Cornelissen 	case NTSC640_TST:
1430bd7693f2SRudolf Cornelissen 		target->timing.h_display = 640;
1431bd7693f2SRudolf Cornelissen 		target->timing.h_sync_start = 640;
1432bd7693f2SRudolf Cornelissen 		if (si->ps.card_type == NV05M64)
1433bd7693f2SRudolf Cornelissen 		{
1434bd7693f2SRudolf Cornelissen 			target->timing.h_sync_end = 648;
1435bd7693f2SRudolf Cornelissen 			target->timing.h_total = 696;
1436bd7693f2SRudolf Cornelissen 		}
1437bd7693f2SRudolf Cornelissen 		else
1438bd7693f2SRudolf Cornelissen 		{
14394e918a7cSRudolf Cornelissen 			//fixme if possible:
14404e918a7cSRudolf Cornelissen 			//see if tweaking h_sync_end can shift picture 8 pixels right to fix
14414e918a7cSRudolf Cornelissen 			//ws tv's tuning fault (always going for max. compatibility :)
1442bd7693f2SRudolf Cornelissen 			target->timing.h_sync_end = 656;
1443bd7693f2SRudolf Cornelissen 			target->timing.h_total = 688;
1444bd7693f2SRudolf Cornelissen 		}
1445bd7693f2SRudolf Cornelissen 		target->timing.v_display = 480;
1446da3804eeSRudolf Cornelissen 		target->timing.v_sync_start = 480;
1447da3804eeSRudolf Cornelissen 		target->timing.v_sync_end = 555;	//This prevents 'cursor trash' on TNT1's
1448da3804eeSRudolf Cornelissen 		target->timing.v_total = 556;		//Above 525 because mode scales down
1449da3804eeSRudolf Cornelissen 		if (si->ps.card_type == NV05M64)
1450da3804eeSRudolf Cornelissen 			target->timing.pixel_clock = ((696 * 556 * 60) / 1000);
1451da3804eeSRudolf Cornelissen 		else
1452da3804eeSRudolf Cornelissen 			target->timing.pixel_clock = ((688 * 556 * 60) / 1000);
145385406c4dSRudolf Cornelissen 		break;
145485406c4dSRudolf Cornelissen 	case NTSC800:
1455da3804eeSRudolf Cornelissen 		target->timing.h_display = 800;
1456da3804eeSRudolf Cornelissen 		target->timing.h_sync_start = 800;
1457da3804eeSRudolf Cornelissen 		if (si->ps.card_type == NV05M64)
1458da3804eeSRudolf Cornelissen 		{
1459da3804eeSRudolf Cornelissen 			target->timing.h_sync_end = 808;
1460da3804eeSRudolf Cornelissen 			target->timing.h_total = 856;
1461da3804eeSRudolf Cornelissen 		}
1462da3804eeSRudolf Cornelissen 		else
1463da3804eeSRudolf Cornelissen 		{
1464da3804eeSRudolf Cornelissen 			target->timing.h_sync_end = 816;
1465da3804eeSRudolf Cornelissen 			target->timing.h_total = 848;
1466da3804eeSRudolf Cornelissen 		}
1467da3804eeSRudolf Cornelissen 		target->timing.v_display = 600;
1468da3804eeSRudolf Cornelissen 		target->timing.v_sync_start = 600;
1469da3804eeSRudolf Cornelissen 		target->timing.v_sync_end = 685;	//This prevents 'cursor trash' on TNT1's
1470da3804eeSRudolf Cornelissen 		target->timing.v_total = 686;		//Above 525 because mode scales down
1471da3804eeSRudolf Cornelissen 		if (si->ps.card_type == NV05M64)
1472da3804eeSRudolf Cornelissen 			target->timing.pixel_clock = ((856 * 686 * 60) / 1000);
1473da3804eeSRudolf Cornelissen 		else
1474da3804eeSRudolf Cornelissen 			target->timing.pixel_clock = ((848 * 686 * 60) / 1000);
147585406c4dSRudolf Cornelissen 		break;
147685406c4dSRudolf Cornelissen 	case PAL640:
1477bd7693f2SRudolf Cornelissen 		target->timing.h_display = 640;
1478da3804eeSRudolf Cornelissen 		target->timing.h_sync_start = 640;
1479da3804eeSRudolf Cornelissen 		if (si->ps.card_type == NV05M64)
1480da3804eeSRudolf Cornelissen 		{
1481da3804eeSRudolf Cornelissen 			target->timing.h_sync_end = 648;
1482da3804eeSRudolf Cornelissen 			target->timing.h_total = 696;
1483da3804eeSRudolf Cornelissen 		}
1484da3804eeSRudolf Cornelissen 		else
1485da3804eeSRudolf Cornelissen 		{
1486da3804eeSRudolf Cornelissen 			target->timing.h_sync_end = 656;
1487da3804eeSRudolf Cornelissen 			target->timing.h_total = 688;
1488da3804eeSRudolf Cornelissen 		}
1489bd7693f2SRudolf Cornelissen 		target->timing.v_display = 480;
1490da3804eeSRudolf Cornelissen 		target->timing.v_sync_start = 480;
1491da3804eeSRudolf Cornelissen 		target->timing.v_sync_end = 570;	//This prevents 'cursor trash' on TNT1's
1492da3804eeSRudolf Cornelissen 		target->timing.v_total = 571;		//Below 625 because mode scales up
1493da3804eeSRudolf Cornelissen 		if (si->ps.card_type == NV05M64)
1494da3804eeSRudolf Cornelissen 			target->timing.pixel_clock = ((696 * 571 * 50) / 1000);
1495da3804eeSRudolf Cornelissen 		else
1496da3804eeSRudolf Cornelissen 			target->timing.pixel_clock = ((688 * 571 * 50) / 1000);
149785406c4dSRudolf Cornelissen 		break;
149885406c4dSRudolf Cornelissen 	case PAL800:
149985406c4dSRudolf Cornelissen 	case PAL800_TST:
1500da3804eeSRudolf Cornelissen 		target->timing.h_display = 800;
1501da3804eeSRudolf Cornelissen 		target->timing.h_sync_start = 800;
1502da3804eeSRudolf Cornelissen 		if (si->ps.card_type == NV05M64)
1503da3804eeSRudolf Cornelissen 		{
1504da3804eeSRudolf Cornelissen 			target->timing.h_sync_end = 808;
1505da3804eeSRudolf Cornelissen 			target->timing.h_total = 856;
1506da3804eeSRudolf Cornelissen 		}
1507da3804eeSRudolf Cornelissen 		else
1508da3804eeSRudolf Cornelissen 		{
1509da3804eeSRudolf Cornelissen 			target->timing.h_sync_end = 816;
1510da3804eeSRudolf Cornelissen 			target->timing.h_total = 848;
1511da3804eeSRudolf Cornelissen 		}
1512da3804eeSRudolf Cornelissen 		target->timing.v_display = 600;
1513da3804eeSRudolf Cornelissen 		target->timing.v_sync_start = 600;
1514da3804eeSRudolf Cornelissen 		target->timing.v_sync_end = 695;	//This prevents 'cursor trash' on TNT1's
1515da3804eeSRudolf Cornelissen 		target->timing.v_total = 696;		//Above 625 because mode scales down
1516da3804eeSRudolf Cornelissen 		if (si->ps.card_type == NV05M64)
1517da3804eeSRudolf Cornelissen 			target->timing.pixel_clock = ((856 * 696 * 50) / 1000);
1518da3804eeSRudolf Cornelissen 		else
1519da3804eeSRudolf Cornelissen 			target->timing.pixel_clock = ((848 * 696 * 50) / 1000);
152085406c4dSRudolf Cornelissen 		break;
152185406c4dSRudolf Cornelissen 	case NTSC640_OS:
152285406c4dSRudolf Cornelissen 		target->timing.h_display = 640;			//BT H_ACTIVE
152385406c4dSRudolf Cornelissen 		target->timing.h_sync_start = 744;		//set for CH/BT compatible TV output
152485406c4dSRudolf Cornelissen 		target->timing.h_sync_end = 744+20;		//delta is BT H_BLANKI
152585406c4dSRudolf Cornelissen 		target->timing.h_total = 784;			//BT H_CLKI
152685406c4dSRudolf Cornelissen 		target->timing.v_display = 480;			//BT  V_ACTIVEI
152785406c4dSRudolf Cornelissen 		target->timing.v_sync_start = 490;		//set for centered sync pulse
152885406c4dSRudolf Cornelissen 		target->timing.v_sync_end = 490+25;		//delta is BT V_BLANKI
1529da3804eeSRudolf Cornelissen 		target->timing.v_total = 525;			//BT V_LINESI (== 525: 1:1 scaled mode)
153085406c4dSRudolf Cornelissen 		target->timing.pixel_clock = ((784 * 525 * 60) / 1000); //refresh
153185406c4dSRudolf Cornelissen 		break;
153285406c4dSRudolf Cornelissen 	case PAL800_OS:
153385406c4dSRudolf Cornelissen 		target->timing.h_display = 768;			//H_ACTIVE
15346245f19cSRudolf Cornelissen 		if (si->ps.tv_encoder.type <= BT869)
15356245f19cSRudolf Cornelissen 		{
15364e918a7cSRudolf Cornelissen 			/* confirmed on TNT1 using 4:3 TV and 16:9 TV */
15376245f19cSRudolf Cornelissen 			target->timing.h_sync_start = 856;		//set for centered TV output
15386245f19cSRudolf Cornelissen 			target->timing.h_sync_end = 856+20;		//delta is BT H_BLANKI
15396245f19cSRudolf Cornelissen 		}
15406245f19cSRudolf Cornelissen 		else
15416245f19cSRudolf Cornelissen 		{
1542195828c4SRudolf Cornelissen 			/* confirmed on NV11 using 4:3 TV and 16:9 TV */
154385406c4dSRudolf Cornelissen 			target->timing.h_sync_start = 848;		//set for centered TV output
154485406c4dSRudolf Cornelissen 			target->timing.h_sync_end = 848+20;		//delta is BT H_BLANKI
15456245f19cSRudolf Cornelissen 		}
154685406c4dSRudolf Cornelissen 		target->timing.h_total = 944;			//BT H_CLKI
154785406c4dSRudolf Cornelissen 		target->timing.v_display = 576;			//V_ACTIVEI
154885406c4dSRudolf Cornelissen 		target->timing.v_sync_start = 579;		//set for centered sync pulse
154985406c4dSRudolf Cornelissen 		target->timing.v_sync_end = 579+42;		//delta is BT V_BLANKI
1550da3804eeSRudolf Cornelissen 		target->timing.v_total = 625;			//BT V_LINESI (== 625: 1:1 scaled mode)
155185406c4dSRudolf Cornelissen 		target->timing.pixel_clock = ((944 * 625 * 50) / 1000); //refresh
155285406c4dSRudolf Cornelissen 		break;
155385406c4dSRudolf Cornelissen 	case NTSC720:
155485406c4dSRudolf Cornelissen 		/* (tested on TNT2 with BT869) */
155585406c4dSRudolf Cornelissen 		target->timing.h_display = 720;			//H_ACTIVE
15565cadaa5fSRudolf Cornelissen 		if (si->ps.tv_encoder.type <= BT869)
15575cadaa5fSRudolf Cornelissen 		{
15585cadaa5fSRudolf Cornelissen 			/* confirmed on TNT1 using 4:3 TV and 16:9 TV */
155985406c4dSRudolf Cornelissen 			target->timing.h_sync_start = 744;		//do not change!
156085406c4dSRudolf Cornelissen 			target->timing.h_sync_end = 744+144;	//delta is H_sync_pulse
15615cadaa5fSRudolf Cornelissen 		}
15625cadaa5fSRudolf Cornelissen 		else
15635cadaa5fSRudolf Cornelissen 		{
1564195828c4SRudolf Cornelissen 			/* confirmed on NV11 using 4:3 TV and 16:9 TV */
15655cadaa5fSRudolf Cornelissen 			target->timing.h_sync_start = 728;		//do not change!
15665cadaa5fSRudolf Cornelissen 			target->timing.h_sync_end = 728+160;	//delta is H_sync_pulse
15675cadaa5fSRudolf Cornelissen 		}
156885406c4dSRudolf Cornelissen 		target->timing.h_total = 888;			//BT H_TOTAL
156985406c4dSRudolf Cornelissen 		target->timing.v_display = 480;			//V_ACTIVEI
157085406c4dSRudolf Cornelissen 		target->timing.v_sync_start = 490;		//set for centered sync pulse
157185406c4dSRudolf Cornelissen 		target->timing.v_sync_end = 490+26;		//delta is V_sync_pulse
1572da3804eeSRudolf Cornelissen 		target->timing.v_total = 525;			//CH V_TOTAL (== 525: 1:1 scaled mode)
157385406c4dSRudolf Cornelissen 		target->timing.pixel_clock = ((888 * 525 * 60) / 1000); //refresh
157485406c4dSRudolf Cornelissen 		break;
157585406c4dSRudolf Cornelissen 	case PAL720:
157685406c4dSRudolf Cornelissen 		target->timing.h_display = 720;			//BT H_ACTIVE
157785406c4dSRudolf Cornelissen 		target->timing.h_sync_start = 744;		//set for centered sync pulse
157885406c4dSRudolf Cornelissen 		target->timing.h_sync_end = 744+140;	//delta is BT H_BLANKI
157985406c4dSRudolf Cornelissen 		target->timing.h_total = 888;			//BT H_CLKI
158085406c4dSRudolf Cornelissen 		target->timing.v_display = 576;			//BT  V_ACTIVEI
158185406c4dSRudolf Cornelissen 		target->timing.v_sync_start = 579;		//set for centered sync pulse
158285406c4dSRudolf Cornelissen 		target->timing.v_sync_end = 579+42;		//delta is BT V_BLANKI
1583da3804eeSRudolf Cornelissen 		target->timing.v_total = 625;			//BT V_LINESI (== 625: 1:1 scaled mode)
158485406c4dSRudolf Cornelissen 		target->timing.pixel_clock = ((888 * 625 * 50) / 1000); //refresh
158585406c4dSRudolf Cornelissen 		break;
158685406c4dSRudolf Cornelissen 	default:
158785406c4dSRudolf Cornelissen 		return B_ERROR;
158885406c4dSRudolf Cornelissen 	}
158985406c4dSRudolf Cornelissen 
159085406c4dSRudolf Cornelissen 	return B_OK;
159185406c4dSRudolf Cornelissen }//end BT_update_mode_for_gpu.
159285406c4dSRudolf Cornelissen 
159322a0d15bSRudolf Cornelissen /* note:
159422a0d15bSRudolf Cornelissen  * tested on ELSA Erazor III 32Mb AGP (TNT2/BT869),
159522a0d15bSRudolf Cornelissen  * Diamond Viper V550 16Mb PCI (TNT1/BT869),
159622a0d15bSRudolf Cornelissen  * and ASUS V7100 GeForce2 MX200 AGP/32Mb (CH7007). */
159722a0d15bSRudolf Cornelissen static status_t BT_start_tvout(void)
159822a0d15bSRudolf Cornelissen {
159922a0d15bSRudolf Cornelissen 	/* enable access to primary head */
160022a0d15bSRudolf Cornelissen 	set_crtc_owner(0);
160122a0d15bSRudolf Cornelissen 
16029b394aa2SRudolf Cornelissen 	/* CAUTION:
16035cadaa5fSRudolf Cornelissen 	 * On old cards, PLLSEL (and TV_SETUP?) cannot be read (sometimes?), but
16045cadaa5fSRudolf Cornelissen 	 * write actions do succeed ...
16055cadaa5fSRudolf Cornelissen 	 * This is confirmed for both ISA and PCI access, on NV04 and NV11. */
160622a0d15bSRudolf Cornelissen 
160722a0d15bSRudolf Cornelissen 	/* setup TVencoder connection */
160822a0d15bSRudolf Cornelissen 	/* b1-0 = %01: encoder type is MASTER;
160922a0d15bSRudolf Cornelissen 	 * b24 = 1: VIP datapos is b0-7 */
1610b0fce481SRudolf Cornelissen 	//fixme if needed: setup completely instead of relying on pre-init by BIOS..
16115cadaa5fSRudolf Cornelissen 	//(it seems to work OK on NV04 and NV11 although read reg. doesn't seem to work)
1612b0fce481SRudolf Cornelissen 	DACW(TV_SETUP, ((DACR(TV_SETUP) & ~0x00000002) | 0x01000001));
161322a0d15bSRudolf Cornelissen 
161422a0d15bSRudolf Cornelissen 	/* tell GPU to use pixelclock from TVencoder instead of using internal source */
161522a0d15bSRudolf Cornelissen 	/* (nessecary or display will 'shiver' on both TV and VGA.) */
16169b394aa2SRudolf Cornelissen 	if (si->ps.secondary_head)
16175cadaa5fSRudolf Cornelissen 		//fixme: assuming TVout is on primary head!!
16185cadaa5fSRudolf Cornelissen 		DACW(PLLSEL, 0x20030f00);
16199b394aa2SRudolf Cornelissen 	else
16209b394aa2SRudolf Cornelissen 		DACW(PLLSEL, 0x00030700);
162122a0d15bSRudolf Cornelissen 
162222a0d15bSRudolf Cornelissen 	/* Set overscan color to 'black' */
162322a0d15bSRudolf Cornelissen 	/* note:
162422a0d15bSRudolf Cornelissen 	 * Change this instruction for a visible overscan color if you're trying to
162522a0d15bSRudolf Cornelissen 	 * center the output on TV. Use it as a guide-'line' then ;-) */
162622a0d15bSRudolf Cornelissen 	ATBW(OSCANCOLOR, 0x00);
162722a0d15bSRudolf Cornelissen 
162822a0d15bSRudolf Cornelissen 	/* set CRTC to slaved mode (b7 = 1) and clear TVadjust (b3-5 = %000) */
162922a0d15bSRudolf Cornelissen 	CRTCW(PIXEL, ((CRTCR(PIXEL) & 0xc7) | 0x80));
1630bd419083SRudolf Cornelissen 	/* select TV encoder, not panel encoder (b0 = 0).
1631bd419083SRudolf Cornelissen 	 * Note:
1632b0fce481SRudolf Cornelissen 	 * Both are devices (often) using the CRTC in slaved mode. */
1633bd419083SRudolf Cornelissen 	CRTCW(LCD, (CRTCR(LCD) & 0xfe));
163422a0d15bSRudolf Cornelissen 
1635bd419083SRudolf Cornelissen 	/* HTOTAL, VTOTAL and OVERFLOW return their default CRTC use, instead of
1636bd419083SRudolf Cornelissen 	 * H, V-low and V-high 'shadow' counters(?)(b0, 4 and 6 = 0) (b7 use = unknown) */
1637bd419083SRudolf Cornelissen 	CRTCW(TREG, 0x80);
163822a0d15bSRudolf Cornelissen 
163922a0d15bSRudolf Cornelissen 	return B_OK;
164022a0d15bSRudolf Cornelissen }//end BT_start_tvout.
164122a0d15bSRudolf Cornelissen 
1642bd419083SRudolf Cornelissen /* note:
1643bd419083SRudolf Cornelissen  * tested on ELSA Erazor III 32Mb AGP (TNT2/BT869),
1644bd419083SRudolf Cornelissen  * Diamond Viper V550 16Mb PCI (TNT1/BT869),
1645bd419083SRudolf Cornelissen  * and ASUS V7100 GeForce2 MX200 AGP/32Mb (CH7007). */
164622a0d15bSRudolf Cornelissen status_t BT_stop_tvout(void)
164722a0d15bSRudolf Cornelissen {
164822a0d15bSRudolf Cornelissen 	/* prevent BT from being overclocked by VGA-only modes & black-out TV-out */
164922a0d15bSRudolf Cornelissen 	BT_killclk_blackout();
165022a0d15bSRudolf Cornelissen 
1651bd419083SRudolf Cornelissen 	/* enable access to primary head */
1652bd419083SRudolf Cornelissen 	set_crtc_owner(0);
1653bd419083SRudolf Cornelissen 
1654bd419083SRudolf Cornelissen 	/* switch on VGA monitor HSYNC and VSYNC */
1655bd419083SRudolf Cornelissen //fixme: see if better DPMS state fetching can be setup for crtc.c (!)
1656bd419083SRudolf Cornelissen 	CRTCW(REPAINT1, (CRTCR(REPAINT1) & 0x3f));
1657bd419083SRudolf Cornelissen 
1658bd419083SRudolf Cornelissen 
16590b36eea4SRudolf Cornelissen 	/* wait for one image to be generated to make sure VGA has kicked in and is
16600b36eea4SRudolf Cornelissen 	 * running OK before continuing...
16610b36eea4SRudolf Cornelissen 	 * (Kicking in will fail often if we do not wait here) */
1662bd419083SRudolf Cornelissen 
16630b36eea4SRudolf Cornelissen 	/* make sure we are 'in' active VGA picture */
16640b36eea4SRudolf Cornelissen 	while (NV_REG8(NV8_INSTAT1) & 0x08) snooze(1);
16650b36eea4SRudolf Cornelissen 	/* wait for next vertical retrace start on VGA */
16660b36eea4SRudolf Cornelissen 	while (!(NV_REG8(NV8_INSTAT1) & 0x08)) snooze(1);
16670b36eea4SRudolf Cornelissen 	/* now wait until we are 'in' active VGA picture again */
16680b36eea4SRudolf Cornelissen 	while (NV_REG8(NV8_INSTAT1) & 0x08) snooze(1);
1669bd419083SRudolf Cornelissen 
16700b36eea4SRudolf Cornelissen 
1671b0fce481SRudolf Cornelissen 	/* set CRTC to master mode (b7 = 0) if it wasn't slaved for a panel before */
1672b0fce481SRudolf Cornelissen 	if (!(si->ps.slaved_tmds1))	CRTCW(PIXEL, (CRTCR(PIXEL) & 0x03));
16730b36eea4SRudolf Cornelissen 
16745cadaa5fSRudolf Cornelissen 	/* CAUTION:
16755cadaa5fSRudolf Cornelissen 	 * On old cards, PLLSEL (and TV_SETUP?) cannot be read (sometimes?), but
16765cadaa5fSRudolf Cornelissen 	 * write actions do succeed ...
16775cadaa5fSRudolf Cornelissen 	 * This is confirmed for both ISA and PCI access, on NV04 and NV11. */
1678bd419083SRudolf Cornelissen 
16790b36eea4SRudolf Cornelissen 	/* setup TVencoder connection */
16800b36eea4SRudolf Cornelissen 	/* b1-0 = %00: encoder type is SLAVE;
16810b36eea4SRudolf Cornelissen 	 * b24 = 1: VIP datapos is b0-7 */
1682b0fce481SRudolf Cornelissen 	//fixme if needed: setup completely instead of relying on pre-init by BIOS..
16835cadaa5fSRudolf Cornelissen 	//(it seems to work OK on NV04 and NV11 although read reg. doesn't seem to work)
1684b0fce481SRudolf Cornelissen 	DACW(TV_SETUP, ((DACR(TV_SETUP) & ~0x00000003) | 0x01000000));
1685bd419083SRudolf Cornelissen 
16860b36eea4SRudolf Cornelissen 	/* tell GPU to use pixelclock from internal source instead of using TVencoder */
16875cadaa5fSRudolf Cornelissen 	if (si->ps.secondary_head)
16885cadaa5fSRudolf Cornelissen 		DACW(PLLSEL, 0x30000f00);
16895cadaa5fSRudolf Cornelissen 	else
16900b36eea4SRudolf Cornelissen 		DACW(PLLSEL, 0x10000700);
1691bd419083SRudolf Cornelissen 
16920b36eea4SRudolf Cornelissen 	/* HTOTAL, VTOTAL and OVERFLOW return their default CRTC use, instead of
16930b36eea4SRudolf Cornelissen 	 * H, V-low and V-high 'shadow' counters(?)(b0, 4 and 6 = 0) (b7 use = unknown) */
16940b36eea4SRudolf Cornelissen 	CRTCW(TREG, 0x00);
1695bd419083SRudolf Cornelissen 
1696b0fce481SRudolf Cornelissen 	/* select panel encoder, not TV encoder if needed (b0 = 1).
16970b36eea4SRudolf Cornelissen 	 * Note:
1698b0fce481SRudolf Cornelissen 	 * Both are devices (often) using the CRTC in slaved mode. */
1699b0fce481SRudolf Cornelissen 	if (si->ps.slaved_tmds1) CRTCW(LCD, (CRTCR(LCD) | 0x01));
170022a0d15bSRudolf Cornelissen 
170122a0d15bSRudolf Cornelissen 	/* fixme if needed:
170222a0d15bSRudolf Cornelissen 	 * a full encoder chip reset could be done here (so after decoupling crtc)... */
1703b0fce481SRudolf Cornelissen 	/* (but: beware of the 'locked SDA' syndrome then!) */
170422a0d15bSRudolf Cornelissen 
170522a0d15bSRudolf Cornelissen 	return B_OK;
1706bd419083SRudolf Cornelissen }//end BT_stop_tvout.
170722a0d15bSRudolf Cornelissen 
1708b2459715SRudolf Cornelissen status_t BT_setmode(display_mode target)
1709b2459715SRudolf Cornelissen {
1710efe9c7a6SRudolf Cornelissen 	uint8 tvmode, monstat;
1711efe9c7a6SRudolf Cornelissen 	/* enable flickerfilter in desktop modes, disable it in video modes. */
1712efe9c7a6SRudolf Cornelissen 	uint8 ffilter = 0;
1713b2459715SRudolf Cornelissen 
1714fb6cadf1Sshatty 	/* use a display_mode copy because we might tune it for TVout compatibility */
1715fb6cadf1Sshatty 	display_mode tv_target = target;
1716fb6cadf1Sshatty 
1717fb6cadf1Sshatty 	/* preset new TVout mode */
1718b2459715SRudolf Cornelissen 	tvmode = BT_check_tvmode(tv_target);
1719b2459715SRudolf Cornelissen 	if (!tvmode) return B_ERROR;
1720b2459715SRudolf Cornelissen 
1721efe9c7a6SRudolf Cornelissen 	/* read current output devices connection status */
1722efe9c7a6SRudolf Cornelissen 	BT_read_monstat(&monstat);
1723efe9c7a6SRudolf Cornelissen 
1724efe9c7a6SRudolf Cornelissen 	/* (pre)set TV mode */
1725efe9c7a6SRudolf Cornelissen 	/* note:
1726efe9c7a6SRudolf Cornelissen 	 * Manual config is non-dependent of the state of the PAL hardware input pin;
1727efe9c7a6SRudolf Cornelissen 	 * Also SDA lockups occur when setting EN_XCLK after autoconfig!
1728efe9c7a6SRudolf Cornelissen 	 * Make sure PAL_MD=0 for NTSC and PAL_MD = 1 for PAL... */
1729b2459715SRudolf Cornelissen 	switch (tvmode)
1730fb6cadf1Sshatty 	{
1731b2459715SRudolf Cornelissen 	case NTSC640:
1732b2459715SRudolf Cornelissen 	case NTSC640_TST:
1733efe9c7a6SRudolf Cornelissen 		ffilter = 1;
1734efe9c7a6SRudolf Cornelissen 		BT_init_NTSC640();
1735b2459715SRudolf Cornelissen 		break;
1736b2459715SRudolf Cornelissen 	case NTSC800:
1737efe9c7a6SRudolf Cornelissen 		ffilter = 1;
1738efe9c7a6SRudolf Cornelissen 		BT_init_NTSC800();
1739b2459715SRudolf Cornelissen 		break;
1740b2459715SRudolf Cornelissen 	case PAL640:
1741efe9c7a6SRudolf Cornelissen 		ffilter = 1;
1742efe9c7a6SRudolf Cornelissen 		BT_init_PAL640();
1743b2459715SRudolf Cornelissen 		break;
1744b2459715SRudolf Cornelissen 	case PAL800:
1745b2459715SRudolf Cornelissen 	case PAL800_TST:
1746efe9c7a6SRudolf Cornelissen 		ffilter = 1;
1747efe9c7a6SRudolf Cornelissen 		BT_init_PAL800();
1748b2459715SRudolf Cornelissen 		break;
1749b2459715SRudolf Cornelissen 	case NTSC640_OS:
1750efe9c7a6SRudolf Cornelissen 		BT_init_NTSC640_OS();
1751b2459715SRudolf Cornelissen 		break;
1752b2459715SRudolf Cornelissen 	case PAL800_OS:
1753efe9c7a6SRudolf Cornelissen 		BT_init_PAL800_OS();
1754b2459715SRudolf Cornelissen 		break;
1755b2459715SRudolf Cornelissen 	case NTSC720:
1756efe9c7a6SRudolf Cornelissen 		BT_init_NTSC720();
1757b2459715SRudolf Cornelissen 		break;
1758b2459715SRudolf Cornelissen 	case PAL720:
1759efe9c7a6SRudolf Cornelissen 		BT_init_PAL720();
1760b2459715SRudolf Cornelissen 		break;
1761fb6cadf1Sshatty 	}
1762fb6cadf1Sshatty 
1763efe9c7a6SRudolf Cornelissen 	/* modify BT Hphase signal to center TV image... */
1764efe9c7a6SRudolf Cornelissen 	BT_setup_hphase(tvmode);
1765fb6cadf1Sshatty 
1766efe9c7a6SRudolf Cornelissen 	/* disable Macro mode */
1767efe9c7a6SRudolf Cornelissen 	switch (tvmode)
1768efe9c7a6SRudolf Cornelissen 	{
1769efe9c7a6SRudolf Cornelissen 	case NTSC640:
1770efe9c7a6SRudolf Cornelissen 	case NTSC640_TST:
1771efe9c7a6SRudolf Cornelissen 	case NTSC800:
1772efe9c7a6SRudolf Cornelissen 	case NTSC640_OS:
1773efe9c7a6SRudolf Cornelissen 	case NTSC720:
1774efe9c7a6SRudolf Cornelissen 		/* NTSC */
1775efe9c7a6SRudolf Cornelissen 		BT_set_macro (0, 0);
1776efe9c7a6SRudolf Cornelissen 		break;
1777efe9c7a6SRudolf Cornelissen 	default:
1778efe9c7a6SRudolf Cornelissen 		/* PAL */
1779efe9c7a6SRudolf Cornelissen 		BT_set_macro (1, 0);
1780efe9c7a6SRudolf Cornelissen 		break;
1781efe9c7a6SRudolf Cornelissen 	}
1782fb6cadf1Sshatty 
1783efe9c7a6SRudolf Cornelissen 	/* setup output signal routing and flickerfilter */
1784*0c73ffe8SRudolf Cornelissen 	BT_setup_output(monstat, (uint8)(si->settings.tv_output), ffilter);
1785fb6cadf1Sshatty 
178685406c4dSRudolf Cornelissen 	/* update the GPU CRTC timing for the requested mode */
178785406c4dSRudolf Cornelissen 	BT_update_mode_for_gpu(&tv_target, tvmode);
1788fb6cadf1Sshatty 
1789efe9c7a6SRudolf Cornelissen 	/* setup GPU CRTC timing */
1790b2459715SRudolf Cornelissen 	head1_set_timing(tv_target);
1791fb6cadf1Sshatty 
17925cadaa5fSRudolf Cornelissen //fixme: only testing older cards for now...
17935cadaa5fSRudolf Cornelissen if (si->ps.secondary_head && (si->ps.card_type > NV15))
1794b0fce481SRudolf Cornelissen {
1795b0fce481SRudolf Cornelissen 	BT_testsignal();
1796b0fce481SRudolf Cornelissen 	return B_OK;
1797b0fce481SRudolf Cornelissen }
1798b0fce481SRudolf Cornelissen 
179922a0d15bSRudolf Cornelissen 	/* now set GPU CRTC to slave mode */
1800b0fce481SRudolf Cornelissen 	BT_start_tvout();
1801efe9c7a6SRudolf Cornelissen 
1802efe9c7a6SRudolf Cornelissen //fixme: add code to disable VGA screen when TVout enabled
1803efe9c7a6SRudolf Cornelissen //(use via nv.setting preset)
1804fb6cadf1Sshatty 
1805b2459715SRudolf Cornelissen 	return B_OK;
1806fb6cadf1Sshatty }
1807