1/*
2 * VIA TV additions
3 */
4
5
6#ifdef HAVE_CONFIG_H
7#include "config.h"
8#endif
9
10#include "trident.h"
11#include "trident_regs.h"
12
13/***************************************************************************
14 *
15 * TV parameters for VT1621
16 *
17 ***************************************************************************/
18#define TV_MODE  8
19#define TVX_MODE_SIZE 0X72
20#define TVX_CRTC_NUM 0x10
21#define TVX_REG_NUM 0x62
22#define TVX_VT1621_PORT 0x40
23#define SMBUS_BASE 0x5000
24unsigned char TVX_VT1621_Table[TV_MODE][TVX_MODE_SIZE] = {
25{
26/* NTSC, 640x480, bpp=8,16 */
270x02, 0x54, 0xE0, 0xFA, 0x11, 0x5D, 0x11, 0x57, 0x5A, 0x56,
280xA0, 0x26, 0x0A, 0x55, 0x37, 0x86,
29
300x6A, 0x0B, 0x22, 0x27, 0x43, 0x50, 0x13, 0x50,
310xB0, 0x07, 0xEE, 0x15, 0x90, 0xE4, 0x00, 0xA8,
320x00, 0x00, 0x0E, 0x48, 0x38, 0x38, 0x00, 0x1C,
330x00, 0x40, 0x0C, 0x02, 0x01, 0x80, 0x00, 0x00,
340x0F, 0x06, 0x99, 0x7C, 0x04, 0x5D, 0x36, 0x9B,
350x54, 0x00, 0x00, 0xB4, 0x2F, 0x85, 0xFF, 0x00,
360x00, 0x17, 0x15, 0x21, 0x15, 0x05, 0x05, 0x02,
370x1B, 0x1B, 0x24, 0xF8, 0x07, 0x00, 0x00, 0x0F,
380x0F, 0x60, 0x01, 0x0A, 0x00, 0x05, 0x04, 0xFF,
390x03, 0x01, 0x90, 0x33, 0x00, 0x00, 0x00, 0x00,
400x00, 0x04, 0x47, 0x02, 0x02, 0xFD, 0x06, 0xf8,
410x0B, 0xF3, 0x0F, 0x70, 0x05, 0xF9, 0x0B, 0xF1,
420x11, 0x6E
43},
44{
45/* NTSC, 800x600, bpp=8,16 */
460X02, 0x79, 0XE0, 0x73, 0x02, 0x80, 0x01, 0x7A, 0x7E, 0xEC,
470xA0, 0x8A, 0x0E, 0xEB, 0x8B, 0x89,
48
490x8B, 0x0B, 0x6A, 0x27, 0x43, 0x50, 0x12, 0x50,
500xBC, 0x0A, 0XE8, 0x15, 0x88, 0xDC, 0x00, 0x98,
510x00, 0x00, 0x0A, 0x48, 0x1C, 0x28, 0x03, 0x20,
520x00, 0x40, 0x36, 0x02, 0x03, 0x80, 0x00, 0x00,
530x0D, 0x04, 0x04, 0x7B, 0x00, 0x5D, 0xC1, 0x9B,
540x6B, 0x00, 0x00, 0xA1, 0x3F, 0x9D, 0x2F, 0x10,
550x00, 0x17, 0x15, 0x21, 0x15, 0x05, 0x05, 0x02,
560x1B, 0x1B, 0x24, 0xF8, 0x07, 0x00, 0x00, 0x0F,
570x0F, 0x60, 0x01, 0x0A, 0x00, 0x05, 0x04, 0xFF,
580x03, 0x01, 0xD6, 0x80, 0x00, 0x00, 0x00, 0x00,
590x00, 0x0C, 0x46, 0x02, 0x02, 0xFD, 0x06, 0xF8,
600x0B, 0xF3, 0x0F, 0x70, 0x05, 0xF9, 0x0B, 0xF1,
610x11, 0x6E
62},
63{
64/* NTSC, 640x480, bpp=32 */
650X02, 0x54, 0XE0, 0xFA, 0x11, 0x5D, 0x01, 0x57, 0x5A, 0x56,
660xA0, 0x26, 0x0A, 0X55, 0x37, 0x46,
67
680x6A, 0x0B, 0x23, 0x33, 0x43, 0x50, 0x13, 0x51,
690xB0, 0x07, 0xAB, 0x15, 0x90, 0xA9, 0x00, 0x98,
700x00, 0x00, 0x0E, 0x48, 0x38, 0x38, 0x03, 0x1C,
710x00, 0x40, 0x0C, 0x02, 0x03, 0x80, 0x00, 0x00,
720x0F, 0x04, 0x99, 0x7A, 0x04, 0x5E, 0xB6, 0x90,
730x5B, 0x00, 0x00, 0x67, 0x2F, 0x88, 0xFA, 0x00,
740x00, 0x17, 0x15, 0x21, 0x15, 0x05, 0x05, 0x02,
750x1B, 0x1B, 0x24, 0xF8, 0x07, 0x00, 0x00, 0x0F,
760x0F, 0x60, 0x01, 0x0A, 0x00, 0x05, 0x04, 0xFF,
770x03, 0x01, 0xA0, 0x33, 0x1B, 0x00, 0X00, 0x00,
780x00, 0x08, 0x47, 0x02, 0x02, 0xFD, 0x06, 0xf8,
790x0B, 0xF3, 0x0F, 0x70, 0x05, 0xF9, 0x0B, 0xF1,
800x11, 0x6E
81},
82{
83/* NTSC, 800x600, bpp=32 */
840X02, 0x79, 0XE0, 0x73, 0x02, 0x80, 0x01, 0x7B, 0x7E, 0xEC,
850xA0, 0x8A, 0x0E, 0xEB, 0x8B, 0x49,
86
870x8B, 0x0B, 0x6B, 0x27, 0x43, 0x50, 0x12, 0x2D,
880xBC, 0x0C, 0xED, 0x15, 0x88, 0xEE, 0x00, 0x99,
890x00, 0x00, 0x0A, 0x48, 0x1C, 0x28, 0x03, 0x20,
900x00, 0x40, 0x36, 0x02, 0x03, 0x80, 0x00, 0x00,
910x0D, 0x04, 0x04, 0x7A, 0x00, 0x5D, 0xC1, 0x9B,
920x6B, 0x00, 0x00, 0xA1, 0x3F, 0x9D, 0x2F, 0x10,
930x00, 0x17, 0x15, 0x21, 0x15, 0x05, 0x05, 0x02,
940x1B, 0x1B, 0x24, 0xF8, 0x07, 0x00, 0x00, 0x0F,
950x0F, 0x60, 0x01, 0x0A, 0x00, 0x05, 0x04, 0xFF,
960x03, 0x01, 0xC6, 0x90, 0x00, 0x00, 0x00, 0x00,
970x00, 0x08, 0x46, 0x02, 0x02, 0xFD, 0x06, 0xF8,
980x0B, 0xF3, 0x0F, 0x70, 0x05, 0xF9, 0x0B, 0xF1,
990x11, 0x6E
100},
101{
102/* PAL, 640x480, bpp=8,16 */
1030X82, 0x5D, 0XE0, 0x23, 0x02, 0x64, 0x01, 0x56, 0x5A, 0x6F,
1040xA0, 0x0D, 0x0F, 0x6E, 0x24, 0xC1,
105
1060x6B, 0x0B, 0x03, 0x67, 0x40, 0x50, 0x12, 0x96,
1070xCE, 0x32, 0xFF, 0x01, 0x7E, 0xF6, 0x00, 0xA8,
1080x00, 0x00, 0x07, 0x48, 0x20, 0x1C, 0x44, 0x60,
1090x44, 0x4F, 0x1B, 0x02, 0x03, 0x80, 0x00, 0x00,
1100x0C, 0x0C, 0xD7, 0x84, 0x04, 0x68, 0x3B, 0x9C,
1110x57, 0x63, 0x17, 0xAC, 0x25, 0x80, 0x29, 0x10,
1120x00, 0x1A, 0x22, 0x2A, 0x22, 0x05, 0x02, 0x00,
1130x1C, 0x3D, 0x14, 0xFE, 0x03, 0x54, 0x01, 0xFE,
1140x7E, 0x60, 0x00, 0x08, 0x00, 0x04, 0x07, 0x55,
1150x01, 0x01, 0xA0, 0x33, 0x00, 0x00, 0x00, 0x00,
1160x00, 0x0C, 0x4E, 0xFE, 0x03, 0xFB, 0x06, 0xF8,
1170x0A, 0xF5, 0x0C, 0x73, 0x06, 0xF8, 0x0B, 0xF2,
1180x10, 0x6F
119},
120{
121/* PAL, 800x600, bpp=8,16 */
1220X82, 0x5B, 0XE0, 0x91, 0x02, 0x73, 0x07, 0x6C, 0x70, 0xEC,
1230xA0, 0xA8, 0x0B, 0xEB, 0xAD, 0xC7,
124
1250x8B, 0x0B, 0x1A, 0x47, 0x40, 0x50, 0x12, 0x56,
1260x00, 0x37, 0xF7, 0x00, 0x7D, 0xE2, 0x00, 0xB9,
1270x00, 0x00, 0x0E, 0x48, 0x38, 0x38, 0x44, 0x62,
1280x44, 0x4F, 0x53, 0x02, 0x07, 0x80, 0x00, 0x00,
1290x0A, 0x05, 0xA2, 0x83, 0x08, 0x68, 0x46, 0x99,
1300x68, 0x63, 0x17, 0xAC, 0x25, 0x80, 0x6B, 0x10,
1310x00, 0x1A, 0x22, 0x2A, 0x22, 0x05, 0x02, 0x00,
1320x1C, 0x3D, 0x14, 0xFE, 0x03, 0x54, 0x01, 0xFE,
1330x7E, 0x60, 0x00, 0x08, 0x00, 0x04, 0x07, 0x55,
1340x01, 0x01, 0xE6, 0x90, 0x00, 0x00, 0x00, 0x00,
1350x00, 0x0C, 0x4D, 0xFB, 0x04, 0xFB, 0x07, 0xF8,
1360x09, 0xF6, 0x0A, 0x74, 0x06, 0xF8, 0x0B, 0xF2,
1370x10, 0x6F
138},
139{
140/* PAL, 640x480, bpp=32 */
1410X82, 0x5D, 0XE0, 0x23, 0x02, 0x64, 0x01, 0x56, 0x5A, 0x6F,
1420xA0, 0x0D, 0x0F, 0x6E, 0x24, 0x81,
143
1440x6B, 0x0B, 0x02, 0x67, 0x40, 0x50, 0x12, 0x93,
1450xCE, 0x32, 0xF0, 0x01, 0x88, 0xE8, 0x00, 0xA8,
1460x00, 0x00, 0x07, 0x48, 0x20, 0x1C, 0x44, 0x60,
1470x44, 0x4F, 0x1B, 0x02, 0x03, 0x80, 0x00, 0x00,
1480x0C, 0x05, 0xE2, 0x84, 0x00, 0x68, 0x3B, 0x9C,
1490x57, 0x63, 0x17, 0xAC, 0x25, 0x80, 0x29, 0x10,
1500x00, 0x1A, 0x22, 0x2A, 0x22, 0x05, 0x02, 0x00,
1510x1C, 0x3D, 0x14, 0xFE, 0x03, 0x54, 0x01, 0xFE,
1520x7E, 0x60, 0x00, 0x08, 0x00, 0x04, 0x07, 0x55,
1530x01, 0x01, 0xA0, 0x33, 0x00, 0x00, 0x00, 0x00,
1540x00, 0x0C, 0x4E, 0xFE, 0x03, 0xFB, 0x06, 0xF8,
1550x0A, 0xF5, 0x0C, 0x73, 0x06, 0xF8, 0x0B, 0xF2,
1560x10, 0x6F
157},
158{
159/* PAL, 800x600, bpp=32 */
1600X82, 0x5B, 0XE0, 0x91, 0x02, 0x73, 0x07, 0x6C, 0x70, 0xEC,
1610xA0, 0xA8, 0x0B, 0xEB, 0xAD, 0x87,
162
1630x8B, 0x0B, 0x1A, 0x67, 0x40, 0x50, 0x12, 0x53,
1640x00, 0x37, 0xEE, 0x00, 0x83, 0xEB, 0x00, 0xB9,
1650x00, 0x00, 0x0E, 0x48, 0x38, 0x38, 0x44, 0x62,
1660x44, 0x4F, 0x53, 0x02, 0x07, 0x80, 0x00, 0x00,
1670x0A, 0x05, 0x5E, 0x83, 0x08, 0x68, 0x46, 0x99,
1680x68, 0x63, 0x17, 0xAC, 0x25, 0x80, 0x6B, 0x10,
1690x00, 0x1A, 0x22, 0x2A, 0x22, 0x05, 0x02, 0x00,
1700x1C, 0x3D, 0x14, 0xFE, 0x03, 0x54, 0x01, 0xFE,
1710x7E, 0x60, 0x00, 0x08, 0x00, 0x04, 0x07, 0x55,
1720x01, 0x01, 0xA0, 0x22, 0x00, 0x00, 0x00, 0x00,
1730x00, 0x0C, 0x4D, 0xFB, 0x04, 0xFB, 0x07, 0xF8,
1740x09, 0xF6, 0x0A, 0x74, 0x06, 0xF8, 0x0B, 0xF2,
1750x10, 0x6F
176}
177};
178/* TV Parameters for CH7005C */
179#define TV_CH7005C_MODE_SIZE 45
180#define TV_CH7005C_CRTC_NUM 0x10
181#define TV_CH7005C_TVREG_NUM 29
182#define TV_CH7005C_PORT 0xEA
183unsigned char TV_CH7005C_Table[TV_MODE][TV_CH7005C_MODE_SIZE]={
184{
185/* NTSC 640x480 bpp=8,16 */
1860x02, 0x80, 0x20, 0x02, 0x00, 0x5D, 0X80, 0X57, 0X80, 0X56,
1870XBA, 0X10, 0X8C, 0X50, 0XF8, 0X7F,
188
1890X6A, 0X7A, 0X00, 0X09, 0X80, 0X66, 0X00, 0X60,
1900X2E, 0XFF, 0X01, 0X0B, 0X0C, 0X03, 0X40, 0X3F,
1910X7E, 0X40, 0X02, 0X00, 0X08, 0X00, 0X00, 0X00,
1920X00, 0X00, 0X0A, 0X02, 0X05
193},
194{
195/* NTSC 800X600 bpp=8,16 */
1960x02, 0x80, 0x20, 0x02, 0x00, 0x7D, 0X80, 0X6E, 0X1C, 0XBA,
1970XF0, 0X70, 0X8C, 0XBA, 0X78, 0X53,
198
1990X8C, 0X4A, 0X00, 0X09, 0X80, 0XAE, 0X01, 0X80,
2000X2E, 0X02, 0X01, 0X0B, 0X7E, 0X7E, 0X7E, 0X7E,
2010X7E, 0X40, 0X01, 0X0C, 0X00, 0X00, 0X00, 0X00,
2020X00, 0X00, 0X0A, 0X00, 0X05
203},
204{
205/* NTSC 640x480 bpp=32 */
2060x02, 0x80, 0x20, 0x02, 0x00, 0x5D, 0X80, 0X57, 0X80, 0X56,
2070XBA, 0X10, 0X8C, 0X50, 0XBD, 0X57,
208
2090X6A, 0X7A, 0X00, 0X09, 0X80, 0X67, 0X00, 0X60,
2100X2E, 0XFF, 0X01, 0X0B, 0X0C, 0X03, 0X40, 0X3F,
2110X7E, 0X40, 0X02, 0X00, 0X07, 0X0C, 0X0D, 0X00,
2120X00, 0X00, 0X0A, 0X02, 0X05
213},
214{
215/* NTSC 800X600 bpp=32 */
2160x02, 0x80, 0x20, 0x02, 0x00, 0x7D, 0X80, 0X6E, 0X1C, 0XBA,
2170XF0, 0X70, 0X8C, 0XBA, 0XF8, 0X53,
218
2190X8C, 0X4A, 0X00, 0X09, 0X80, 0XAF, 0X01, 0X80,
2200X2E, 0X02, 0X01, 0X0B, 0X0C, 0X03, 0X40, 0X3F,
2210X7E, 0X40, 0X01, 0X0C, 0X00, 0X00, 0X00, 0X00,
2220X00, 0X00, 0X0A, 0X00, 0X05
223},
224{
225/* PAL 640x480 bpp=8,16 */
2260x82, 0x80, 0x20, 0x02, 0x00, 0x71, 0X74, 0X62, 0X84, 0X6F,
2270XF0, 0X10, 0X09, 0XEB, 0X80, 0X5F,
228
2290X81, 0X4A, 0X00, 0X09, 0X80, 0X84, 0X00, 0X70,
2300X28, 0X02, 0X01, 0X0B, 0X0C, 0X03, 0X40, 0X3F,
2310X7E, 0X40, 0X02, 0X00, 0X08, 0X00, 0X00, 0X00,
2320X00, 0X00, 0X0A, 0X01, 0X05
233},
234{
235/* PAL 800x600 bpp=8,16 */
2360x82, 0x80, 0x20, 0x02, 0x00, 0x73, 0X76, 0X6A, 0X8C, 0XEC,
2370XF0, 0X7E, 0X09, 0XEB, 0X8F, 0X8D,
238
2390X83, 0X4A, 0X00, 0X09, 0X80, 0X7E, 0X00, 0X70,
2400X3F, 0X02, 0X01, 0X0B, 0X0C, 0X03, 0X40, 0X3F,
2410X7E, 0X40, 0X02, 0X00, 0X08, 0X00, 0X00, 0X00,
2420X00, 0X00, 0X0A, 0X01, 0X05
243},
244{
245/* PAL 640x480 bpp=32 */
2460x82, 0x80, 0x20, 0x02, 0x00, 0x71, 0X74, 0X62, 0X84, 0X6F,
2470XF0, 0X10, 0X09, 0XEB, 0X80, 0X1F,
248
2490X81, 0X4A, 0X00, 0X09, 0X80, 0X84, 0X00, 0X70,
2500X28, 0X02, 0X01, 0X0B, 0X0C, 0X03, 0X40, 0X3F,
2510X7E, 0X40, 0X02, 0X00, 0X08, 0X00, 0X00, 0X00,
2520X00, 0X00, 0X0A, 0X01, 0X05
253},
254{
255/* PAL 800X600 bpp=32 */
2560x82, 0x80, 0x20, 0x02, 0x00, 0x73, 0X76, 0X6A, 0X8C, 0XEC,
2570XF0, 0X7E, 0X09, 0XEB, 0X5D, 0X48,
258
2590X83, 0X4A, 0X00, 0X09, 0X80, 0X7E, 0X00, 0X70,
2600X3F, 0X02, 0X01, 0X0B, 0X0C, 0X03, 0X40, 0X3F,
2610X7E, 0X40, 0X02, 0X00, 0X08, 0X00, 0X00, 0X00,
2620X00, 0X00, 0X0A, 0X01, 0X05
263}
264};
265
266static unsigned char smbus_read(ScrnInfoPtr pScrn, unsigned char bIndex, unsigned char devAdr)
267{
268    TRIDENTPtr pTrident=TRIDENTPTR(pScrn);
269    unsigned short i;
270    unsigned char  bData;
271
272    /* clear host status */
273    OUTB(SMBUS_BASE, 0xFF);
274
275    /* check SMBUS ready */
276    for ( i = 0; i < 0xFFFF; i++ )
277        if ( (INB(SMBUS_BASE) & 0x01) == 0 )
278            break;
279
280    /* set host command */
281    OUTB(SMBUS_BASE+3, bIndex);
282
283    /* set slave address */
284    OUTB(SMBUS_BASE+4, devAdr | 0x01);
285
286    /* start */
287    OUTB(SMBUS_BASE+2, 0x48);
288
289    /* SMBUS Wait Ready */
290    for ( i = 0; i < 0xFFFF; i++ )
291        if ( (INB(SMBUS_BASE) & 0x01) == 0 )
292            break;
293    bData=INB(SMBUS_BASE+5);
294
295    return bData;
296
297}
298
299static void smbus_write(ScrnInfoPtr pScrn, unsigned char bData, unsigned char bIndex, unsigned char devAdr)
300{
301    TRIDENTPtr pTrident=TRIDENTPTR(pScrn);
302    unsigned short i;
303
304    /* clear host status */
305    OUTB(SMBUS_BASE, 0xFF);
306
307    /* check SMBUS ready */
308    for ( i = 0; i < 0xFFFF; i++ )
309        if ( (INB(SMBUS_BASE) & 0x01) == 0 )
310           break;
311
312    OUTB(SMBUS_BASE+2, 0x08);
313
314    /* set host command */
315    OUTB(SMBUS_BASE+3, bIndex);
316
317    /* set slave address */
318    OUTB(SMBUS_BASE+4, devAdr & 0xFE);
319
320    OUTB(SMBUS_BASE+5, bData);
321
322    /* start */
323    OUTB(SMBUS_BASE+2, 0x48);
324
325    /* SMBUS Wait Ready */
326    for ( i = 0; i < 0xFFFF; i++ )
327    if ( (INB(SMBUS_BASE) & 0x01) == 0 )
328       break;
329}
330void VIA_SaveTVDepentVGAReg(ScrnInfoPtr pScrn)
331{
332    TRIDENTPtr pTrident=TRIDENTPTR(pScrn);
333    unsigned char protect;
334    unsigned char bTmp;
335    int i;
336    unsigned char VGA_RegIdx_about_TV[VGA_REGNUM_ABOUT_TV]={
337                  0xD8,0XD9,/* SR */
338                  0X33,/* GR */
339                  0XC0,0XD0,0XD1,0XD2,0XD3,0XE0,0XE3,0XE4,0XE5,/* CR */
340                  0XE6,0XE7,0XF0,0XF1,0XF6,0XFE,0XFF
341                  };
342    unsigned char TV_CH7005C_RegIdx[TV_CH7005C_TVREG_NUM]={
343                  0X00,0X01,0X03,0X04,0X06,0X07,0X08,0X09,
344		  0X0A,0X0B,0X0D,0X0E,0X10,0X11,0X13,0X14,
345		  0X15,0X17,0X18,0X19,0X1A,0X1B,0X1C,0X1D,
346		  0X1E,0X1F,0X20,0X21,0X3D
347                  };
348
349    /*ErrorF("VIAB3D: VIA_SaveTVDepentVGAReg:\n");*/
350
351    /* Unprotect */
352    OUTB(0x3C4, 0x11);
353    protect = INB(0x3C5);
354    OUTB(0x3C5, 0x92);
355
356    /* Set TV Hw environment */
357    OUTB(0x3d4,0xc1);
358    OUTB(0x3d5,0x41);
359
360    /* SR_d8,SR_d9 */
361    for (i=0; i<2; i++)
362    {
363        OUTB(0x3c4,VGA_RegIdx_about_TV[i]);
364        bTmp=INB(0x3c5);
365        pTrident->DefaultTVDependVGASetting[i]=bTmp;
366    }
367
368    /* GR_33 */
369    OUTB(0x3ce,0x33);
370    bTmp=INB(0x3cf);
371    pTrident->DefaultTVDependVGASetting[2]=bTmp;
372
373    /* CR_c0,d0,d1,d2,d3,e0,e3,e4,e5,e6,e7,f0,f1,f6,fe,ff */
374    for (i=3; i<VGA_REGNUM_ABOUT_TV; i++)
375    {
376        OUTB(0x3d4,VGA_RegIdx_about_TV[i]);
377        bTmp=INB(0x3d5);
378        pTrident->DefaultTVDependVGASetting[i]=bTmp;
379    }
380
381    switch (pTrident->TVChipset)
382    {
383       case 1:
384             for (i=0; i<TVX_REG_NUM; i++)
385             {
386                 bTmp=smbus_read(pScrn,i,TVX_VT1621_PORT);
387                 pTrident->DefaultTVDependVGASetting[VGA_REGNUM_ABOUT_TV+i]=bTmp;
388             }
389	     break;
390       case 2:
391             for (i=0; i<TV_CH7005C_TVREG_NUM; i++)
392	     {
393                 bTmp=smbus_read(pScrn,TV_CH7005C_RegIdx[i],TV_CH7005C_PORT);
394                 pTrident->DefaultTVDependVGASetting[VGA_REGNUM_ABOUT_TV+i]=bTmp;
395	     }
396	     break;
397       default:
398             ErrorF("VIAB3D: VIA_SaveTVDepentVGAReg: Wrong Chipset setting\n");
399	     break;
400
401    }
402    /* protect */
403    OUTB(0x3C4, 0x11);
404    OUTB(0x3C5, protect);
405}
406void VIA_RestoreTVDependVGAReg(ScrnInfoPtr pScrn)
407{
408    TRIDENTPtr pTrident=TRIDENTPTR(pScrn);
409    unsigned char protect;
410    unsigned char bTmp;
411    int i;
412    unsigned char VGA_RegIdx_about_TV[VGA_REGNUM_ABOUT_TV]={
413                  0xD8,0XD9,/* SR */
414                  0X33,/* GR */
415                  0XC0,0XD0,0XD1,0XD2,0XD3,0XE0,0XE3,0XE4,0XE5,/* CR */
416                  0XE6,0XE7,0XF0,0XF1,0XF6,0XFE,0XFF
417                  };
418    unsigned char TV_CH7005C_RegIdx[TV_CH7005C_TVREG_NUM]={
419                  0X00,0X01,0X03,0X04,0X06,0X07,0X08,0X09,
420		  0X0A,0X0B,0X0D,0X0E,0X10,0X11,0X13,0X14,
421		  0X15,0X17,0X18,0X19,0X1A,0X1B,0X1C,0X1D,
422		  0X1E,0X1F,0X20,0X21,0X3D
423                  };
424
425    /*ErrorF("VIAB3D: VIA_RestoreTVDependVGAReg:\n");*/
426
427    /* Unprotect */
428    OUTB(0x3C4, 0x11);
429    protect = INB(0x3C5);
430    OUTB(0x3C5, 0x92);
431
432    /* Set TV Hw environment */
433    OUTB(0x3d4,0xc1);
434    OUTB(0x3d5,0x41);
435
436    /* SR_d8,SR_d9 */
437    for (i=0; i<2; i++)
438    {
439        OUTB(0x3c4,VGA_RegIdx_about_TV[i]);
440        bTmp=pTrident->DefaultTVDependVGASetting[i];
441        OUTB(0x3c5,bTmp);
442    }
443    /* GR_33 */
444    OUTB(0x3ce,0x33);
445    bTmp=pTrident->DefaultTVDependVGASetting[2];
446    OUTB(0x3cf,bTmp);
447
448    /* CR_c0,d0,d1,d2,d3,e0,e3,e4,e5,e6,e7,f0,f1,f6,fe,ff */
449    for (i=3; i<VGA_REGNUM_ABOUT_TV; i++)
450    {
451        OUTB(0x3d4,VGA_RegIdx_about_TV[i]);
452        bTmp=pTrident->DefaultTVDependVGASetting[i];
453        OUTB(0x3d5,bTmp);
454    }
455    switch (pTrident->TVChipset)
456    {
457         case 1:
458                for (i=0; i<TVX_REG_NUM; i++)
459                {
460                    bTmp=pTrident->DefaultTVDependVGASetting[VGA_REGNUM_ABOUT_TV+i];
461                    smbus_write(pScrn,bTmp,i,TVX_VT1621_PORT);
462		}
463		break;
464         case 2:
465	        for (i=0; i<TV_CH7005C_TVREG_NUM; i++)
466		{
467                    bTmp=pTrident->DefaultTVDependVGASetting[VGA_REGNUM_ABOUT_TV+i];
468                    smbus_write(pScrn,bTmp,TV_CH7005C_RegIdx[i],TV_CH7005C_PORT);
469		}
470		break;
471       default:
472             ErrorF("VIAB3D: VIA_SaveTVDepentVGAReg: Wrong Chipset setting\n");
473	     break;
474    }
475    /* protect */
476    OUTB(0x3C4, 0x11);
477    OUTB(0x3C5, protect);
478}
479void VIA_TVInit(ScrnInfoPtr pScrn)
480{
481    TRIDENTPtr pTrident=TRIDENTPTR(pScrn);
482    unsigned char idx=0;
483    unsigned char i;
484    unsigned char protect;
485    unsigned char TV_CRTC[TVX_CRTC_NUM] =
486       { 0xC0,0xD0,0xD1,0xD2,0xD3,0xE0,0xE3,0xE4,0xE5,
487         0xE6,0xE7,0xF0,0xF1,0xF6,0xFE,0xFF  };
488    unsigned char TV_CH7005C_RegIdx[TV_CH7005C_TVREG_NUM]={
489                  0X00,0X01,0X03,0X04,0X06,0X07,0X08,0X09,
490		  0X0A,0X0B,0X0D,0X0E,0X10,0X11,0X13,0X14,
491		  0X15,0X17,0X18,0X19,0X1A,0X1B,0X1C,0X1D,
492		  0X1E,0X1F,0X20,0X21,0X3D
493                  };
494
495#ifdef DEBUG_CODE_TRACE
496    ErrorF("VIAB3D: VIA_TVInit:\n");
497#endif
498
499    if (pScrn->currentMode->HDisplay==640 && pScrn->currentMode->VDisplay==480 && (pScrn->depth==8 || pScrn->depth==16) && pTrident->TVSignalMode == 0)
500    {
501       /* Overlay window 1 position OK */
502       ErrorF("VIAB3D: VIA_TVInit: TV Params 640x480x8(16) NTSC\n");
503       idx=0;
504       pTrident->OverrideHsync=-71;
505       pTrident->OverrideVsync=15;
506     }
507    else if (pScrn->currentMode->HDisplay==800 && pScrn->currentMode->VDisplay==600 && (pScrn->depth==8 || pScrn->depth==16) && pTrident->TVSignalMode == 0)
508    {
509       /* Overlay window 1 position OK */
510       ErrorF("VIAB3D: VIA_TVInit: TV Params 800x600x8(16) NTSC\n");
511       idx=1;
512       pTrident->OverrideHsync=-152;
513       pTrident->OverrideVsync=72;
514       }
515    else if (pScrn->currentMode->HDisplay==640 && pScrn->currentMode->VDisplay==480 && pScrn->depth==24 && pTrident->TVSignalMode == 0)
516    {
517       ErrorF("VIAB3D: VIA_TVInit: TV Params 640x480x32 NTSC\n");
518       idx=2;
519       pTrident->OverrideHsync=-65;
520       pTrident->OverrideVsync=14;
521       }
522    else if (pScrn->currentMode->HDisplay==800 && pScrn->currentMode->VDisplay==600 && pScrn->depth==24 && pTrident->TVSignalMode == 0)
523    {
524       ErrorF("VIAB3D: VIA_TVInit: TV Params 800x600x32 NTSC\n");
525       idx=3;
526       pTrident->OverrideHsync=-158;
527       pTrident->OverrideVsync=72;
528       }
529    else if (pScrn->currentMode->HDisplay==640 && pScrn->currentMode->VDisplay==480 && (pScrn->depth==8 || pScrn->depth==16) && pTrident->TVSignalMode == 1)
530    {
531       /* Overlay window 1 position OK */
532       ErrorF("VIAB3D: VIA_TVInit: TV Params 640x480x8(16) PAL\n");
533       idx=4;
534       pTrident->OverrideHsync=2;
535       pTrident->OverrideVsync=65;
536       }
537    else if (pScrn->currentMode->HDisplay==800 && pScrn->currentMode->VDisplay==600 && (pScrn->depth==8 || pScrn->depth==16) && pTrident->TVSignalMode == 1)
538    {
539       ErrorF("VIAB3D: VIA_TVInit: TV Params 800x600x8(16) PAL\n");
540       /* patch TV screen defection */
541       idx=5;
542       /* patch 800x600 screen defect */
543       OUTB(0x3d4,0x2f);
544       OUTB(0x3d5,0xbf);
545       pTrident->OverrideHsync=-145;
546       pTrident->OverrideVsync=43;
547       }
548    else if (pScrn->currentMode->HDisplay==640 && pScrn->currentMode->VDisplay==480 && pScrn->depth==24 && pTrident->TVSignalMode == 1)
549    {
550       ErrorF("VIAB3D: VIA_TVInit: TV Params 640x480x32 PAL\n");
551       idx=6;
552       pTrident->OverrideHsync=0;
553       pTrident->OverrideVsync=63;
554       }
555    else if (pScrn->currentMode->HDisplay==800 && pScrn->currentMode->VDisplay==600 && pScrn->depth==24 && pTrident->TVSignalMode == 1)
556    {
557       ErrorF("VIAB3D: VIA_TVInit: TV Params 800x600x32 PAL\n");
558       idx=7;
559       OUTB(0x3d4,0x2f);
560       OUTB(0x3d5,0xbf);
561       pTrident->OverrideHsync=-141;
562       pTrident->OverrideVsync=42;
563       }
564    else
565    {
566       ErrorF("VIAB3D: VIA_TVInit: TV Params default mode\n");
567       return;
568    }
569
570    /* Unprotect */
571    OUTB(0x3C4, 0x11);
572    protect = INB(0x3C5);
573    OUTB(0x3C5, 0x92);
574
575    /* Set TV hw environment */
576    OUTB(0x3c4,0x24);
577    OUTB(0x3c5,0x4f);
578    OUTB(0x3d4,0xc1);
579    OUTB(0x3d5,0x41);
580    OUTB(0x3ce,0x23);
581    OUTB(0x3cf,0x88);
582
583    /* set CRT + TV */
584    OUTB(0x3CE,0x33);
585    OUTB(0x3CF,0x20);
586
587    /* set CRTC */
588    for( i = 0; i < TVX_CRTC_NUM; i++ )
589    {
590         OUTB(0x3D4, TV_CRTC[i]);
591
592	 if (pTrident->TVChipset==2) {
593            OUTB(0x3D5, TV_CH7005C_Table[idx][i]);
594	 }
595	 else {
596	    OUTB(0x3D5, TVX_VT1621_Table[idx][i]);
597	 }
598    }
599
600
601    /* Digital TV interface control */
602    switch (pTrident->TVChipset)
603    {
604           case 1: OUTB(0x3C4,0xD8);
605                   OUTB(0x3C5,0x60);
606                   OUTB(0x3C4,0xD9);
607                   OUTB(0x3C5,0x38);
608		   break;
609           case 2: OUTB(0x3c4,0xd8);
610	           OUTB(0x3c5,0x24);
611                   OUTB(0x3C4,0xD9);
612                   OUTB(0x3C5,0x18);
613		   break;
614    }
615
616    switch (pTrident->TVChipset)
617    {
618           case 1:
619                  /* set TVX registers */
620                  for (i=0; i < TVX_REG_NUM; i++ )
621                  {
622                      smbus_write(pScrn,TVX_VT1621_Table[idx][TVX_CRTC_NUM+i], i, TVX_VT1621_PORT);
623                  }
624		  break;
625           case 2:
626	          for (i=0; i<TV_CH7005C_TVREG_NUM; i++)
627		  {
628                      smbus_write(pScrn,TV_CH7005C_Table[idx][TV_CH7005C_CRTC_NUM+i], TV_CH7005C_RegIdx[i], TV_CH7005C_PORT);
629		  }
630	          break;
631    }
632
633    /*VIA_DumpReg(pScrn);*/
634
635    /* protect */
636    OUTB(0x3C4, 0x11);
637    OUTB(0x3C5, protect);
638}
639void VIA_DumpReg(ScrnInfoPtr pScrn)
640{
641    TRIDENTPtr pTrident=TRIDENTPTR(pScrn);
642    int i,j;
643    unsigned char bTmp;
644    unsigned char protect;
645
646    /* Unprotect */
647    OUTB(0x3C4, 0x11);
648    protect = INB(0x3C5);
649    OUTB(0x3C5, 0x92);
650
651    /* SR */
652    for (i=0; i<16; i++)
653    {
654        for (j=0; j<16; j++)
655	{
656            OUTB(0x3c4,(16*i+j));
657	    bTmp=INB(0x3c5);
658
659	    ErrorF("SR%02x=%02x ",(16*i+j),bTmp);
660	}
661	ErrorF("\n");
662    }
663    ErrorF("\n");
664    /* CR */
665    for (i=0; i<16; i++)
666    {
667        for (j=0; j<16; j++)
668	{
669            OUTB(0x3d4,(16*i+j));
670	    bTmp=INB(0x3d5);
671
672	    ErrorF("CR%02x=%02x ",(16*i+j),bTmp);
673	}
674	ErrorF("\n");
675    }
676    ErrorF("\n");
677    /* GR */
678    for (i=0; i<16; i++)
679    {
680        for (j=0; j<16; j++)
681	{
682            OUTB(0x3ce,(16*i+j));
683	    bTmp=INB(0x3cf);
684
685	    ErrorF("GR%02x=%02x ",(16*i+j),bTmp);
686	}
687	ErrorF("\n");
688    }
689    ErrorF("\n");
690    /* SM */
691    for (i=0; i<16; i++)
692    {
693        for (j=0; j<16; j++)
694	{
695	    if (pTrident->TVChipset==2)
696               bTmp=smbus_read(pScrn,(16*i+j),TV_CH7005C_PORT);
697	    else bTmp=smbus_read(pScrn,(16*i+j),TVX_VT1621_PORT);
698	    ErrorF("SM%02x=%02x ",(16*i+j),bTmp);
699	}
700	ErrorF("\n");
701    }
702    ErrorF("\n");
703    /* protect */
704    OUTB(0x3C4, 0x11);
705    OUTB(0x3C5, protect);
706
707}
708