via_vt162x.c revision 7e6fb56f
17e6fb56fSmrg/* 27e6fb56fSmrg * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] 37e6fb56fSmrg * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. 47e6fb56fSmrg * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. 57e6fb56fSmrg * 67e6fb56fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 77e6fb56fSmrg * copy of this software and associated documentation files (the "Software"), 87e6fb56fSmrg * to deal in the Software without restriction, including without limitation 97e6fb56fSmrg * the rights to use, copy, modify, merge, publish, distribute, sub license, 107e6fb56fSmrg * and/or sell copies of the Software, and to permit persons to whom the 117e6fb56fSmrg * Software is furnished to do so, subject to the following conditions: 127e6fb56fSmrg * 137e6fb56fSmrg * The above copyright notice and this permission notice (including the 147e6fb56fSmrg * next paragraph) shall be included in all copies or substantial portions 157e6fb56fSmrg * of the Software. 167e6fb56fSmrg * 177e6fb56fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 187e6fb56fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 197e6fb56fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 207e6fb56fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 217e6fb56fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 227e6fb56fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 237e6fb56fSmrg * DEALINGS IN THE SOFTWARE. 247e6fb56fSmrg */ 257e6fb56fSmrg 267e6fb56fSmrg#ifdef HAVE_CONFIG_H 277e6fb56fSmrg#include "config.h" 287e6fb56fSmrg#endif 297e6fb56fSmrg 307e6fb56fSmrg#include "via_driver.h" 317e6fb56fSmrg#include "via_vgahw.h" 327e6fb56fSmrg#include "via_vt162x.h" 337e6fb56fSmrg#include "via_id.h" 347e6fb56fSmrg 357e6fb56fSmrgstatic void 367e6fb56fSmrgViaSetTVClockSource(ScrnInfoPtr pScrn) 377e6fb56fSmrg{ 387e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetTVClockSource\n")); 397e6fb56fSmrg 407e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 417e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 427e6fb56fSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 437e6fb56fSmrg 447e6fb56fSmrg /* External TV: */ 457e6fb56fSmrg switch(pVia->Chipset) { 467e6fb56fSmrg case VIA_CX700: 477e6fb56fSmrg case VIA_VX800: 487e6fb56fSmrg if (pBIOSInfo->FirstCRTC->IsActive) { 497e6fb56fSmrg if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP1) 507e6fb56fSmrg ViaCrtcMask(hwp, 0x6C, 0xB0, 0xF0); 517e6fb56fSmrg else if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP0) 527e6fb56fSmrg ViaCrtcMask(hwp, 0x6C, 0x90, 0xF0); 537e6fb56fSmrg } else { 547e6fb56fSmrg /* IGA2 */ 557e6fb56fSmrg if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP1) 567e6fb56fSmrg ViaCrtcMask(hwp, 0x6C, 0x0B, 0x0F); 577e6fb56fSmrg else if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP0) 587e6fb56fSmrg ViaCrtcMask(hwp, 0x6C, 0x09, 0x0F); 597e6fb56fSmrg } 607e6fb56fSmrg break; 617e6fb56fSmrg default: 627e6fb56fSmrg if (pBIOSInfo->FirstCRTC->IsActive) 637e6fb56fSmrg ViaCrtcMask(hwp, 0x6C, 0x21, 0x21); 647e6fb56fSmrg else 657e6fb56fSmrg ViaCrtcMask(hwp, 0x6C, 0xA1, 0xA1); 667e6fb56fSmrg break; 677e6fb56fSmrg } 687e6fb56fSmrg} 697e6fb56fSmrg 707e6fb56fSmrgstatic void 717e6fb56fSmrgVT162xPrintRegs(ScrnInfoPtr pScrn) 727e6fb56fSmrg{ 737e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 747e6fb56fSmrg CARD8 i, buf; 757e6fb56fSmrg 767e6fb56fSmrg 777e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Printing registers for %s\n", 787e6fb56fSmrg pBIOSInfo->TVI2CDev->DevName); 797e6fb56fSmrg 807e6fb56fSmrg for (i = 0; i < pBIOSInfo->TVNumRegs; i++) { 817e6fb56fSmrg xf86I2CReadByte(pBIOSInfo->TVI2CDev, i, &buf); 827e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV%02X: 0x%02X\n", i, buf); 837e6fb56fSmrg } 847e6fb56fSmrg 857e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "End of TV registers.\n"); 867e6fb56fSmrg} 877e6fb56fSmrg 887e6fb56fSmrg 897e6fb56fSmrgI2CDevPtr 907e6fb56fSmrgViaVT162xDetect(ScrnInfoPtr pScrn, I2CBusPtr pBus, CARD8 Address) 917e6fb56fSmrg{ 927e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 937e6fb56fSmrg I2CDevPtr pDev = xf86CreateI2CDevRec(); 947e6fb56fSmrg CARD8 buf; 957e6fb56fSmrg 967e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaVT162xDetect\n")); 977e6fb56fSmrg 987e6fb56fSmrg pDev->DevName = "VT162x"; 997e6fb56fSmrg pDev->SlaveAddr = Address; 1007e6fb56fSmrg pDev->pI2CBus = pBus; 1017e6fb56fSmrg 1027e6fb56fSmrg if (!xf86I2CDevInit(pDev)) { 1037e6fb56fSmrg xf86DestroyI2CDevRec(pDev, TRUE); 1047e6fb56fSmrg return NULL; 1057e6fb56fSmrg } 1067e6fb56fSmrg 1077e6fb56fSmrg if (!xf86I2CReadByte(pDev, 0x1B, &buf)) { 1087e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1097e6fb56fSmrg "Unable to read from %s Slave %d.\n", 1107e6fb56fSmrg pBus->BusName, Address); 1117e6fb56fSmrg xf86DestroyI2CDevRec(pDev, TRUE); 1127e6fb56fSmrg return NULL; 1137e6fb56fSmrg } 1147e6fb56fSmrg 1157e6fb56fSmrg switch (buf) { 1167e6fb56fSmrg case 0x02: 1177e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 1187e6fb56fSmrg "Detected VIA Technologies VT1621 TV Encoder\n"); 1197e6fb56fSmrg pBIOSInfo->TVEncoder = VIA_VT1621; 1207e6fb56fSmrg pDev->DevName = "VT1621"; 1217e6fb56fSmrg break; 1227e6fb56fSmrg case 0x03: 1237e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 1247e6fb56fSmrg "Detected VIA Technologies VT1622 TV Encoder\n"); 1257e6fb56fSmrg pBIOSInfo->TVEncoder = VIA_VT1622; 1267e6fb56fSmrg pDev->DevName = "VT1622"; 1277e6fb56fSmrg break; 1287e6fb56fSmrg case 0x10: 1297e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 1307e6fb56fSmrg "Detected VIA Technologies VT1622A/VT1623 TV Encoder\n"); 1317e6fb56fSmrg pBIOSInfo->TVEncoder = VIA_VT1623; 1327e6fb56fSmrg pDev->DevName = "VT1623"; 1337e6fb56fSmrg break; 1347e6fb56fSmrg case 0x50: 1357e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 1367e6fb56fSmrg "Detected VIA Technologies VT1625 TV Encoder\n"); 1377e6fb56fSmrg pBIOSInfo->TVEncoder = VIA_VT1625; 1387e6fb56fSmrg pDev->DevName = "VT1625"; 1397e6fb56fSmrg break; 1407e6fb56fSmrg default: 1417e6fb56fSmrg pBIOSInfo->TVEncoder = VIA_NONETV; 1427e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1437e6fb56fSmrg "Unknown TV Encoder found at %s %X.\n", 1447e6fb56fSmrg pBus->BusName, Address); 1457e6fb56fSmrg xf86DestroyI2CDevRec(pDev, TRUE); 1467e6fb56fSmrg pDev = NULL; 1477e6fb56fSmrg break; 1487e6fb56fSmrg } 1497e6fb56fSmrg 1507e6fb56fSmrg return pDev; 1517e6fb56fSmrg} 1527e6fb56fSmrg 1537e6fb56fSmrg 1547e6fb56fSmrgstatic void 1557e6fb56fSmrgVT162xSave(ScrnInfoPtr pScrn) 1567e6fb56fSmrg{ 1577e6fb56fSmrg int i; 1587e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 1597e6fb56fSmrg 1607e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT162xSave\n")); 1617e6fb56fSmrg 1627e6fb56fSmrg for (i = 0; i < pBIOSInfo->TVNumRegs; i++) 1637e6fb56fSmrg xf86I2CReadByte(pBIOSInfo->TVI2CDev, i, &(pBIOSInfo->TVRegs[i])); 1647e6fb56fSmrg 1657e6fb56fSmrg} 1667e6fb56fSmrg 1677e6fb56fSmrgstatic void 1687e6fb56fSmrgVT162xRestore(ScrnInfoPtr pScrn) 1697e6fb56fSmrg{ 1707e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 1717e6fb56fSmrg int i; 1727e6fb56fSmrg 1737e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT162xRestore\n")); 1747e6fb56fSmrg 1757e6fb56fSmrg for (i = 0; i < pBIOSInfo->TVNumRegs; i++) 1767e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, pBIOSInfo->TVRegs[i]); 1777e6fb56fSmrg} 1787e6fb56fSmrg 1797e6fb56fSmrg 1807e6fb56fSmrg/* 1817e6fb56fSmrg * For VT1621 the same as for VT1622/VT1622A/VT1623, but result is different. 1827e6fb56fSmrg * Still needs testing on VT1621, of course. 1837e6fb56fSmrg */ 1847e6fb56fSmrgstatic CARD8 1857e6fb56fSmrgVT162xDACSenseI2C(I2CDevPtr pDev) 1867e6fb56fSmrg{ 1877e6fb56fSmrg CARD8 save, sense; 1887e6fb56fSmrg 1897e6fb56fSmrg xf86I2CReadByte(pDev, 0x0E, &save); 1907e6fb56fSmrg xf86I2CWriteByte(pDev, 0x0E, 0x00); 1917e6fb56fSmrg xf86I2CWriteByte(pDev, 0x0E, 0x80); 1927e6fb56fSmrg xf86I2CWriteByte(pDev, 0x0E, 0x00); 1937e6fb56fSmrg xf86I2CReadByte(pDev, 0x0F, &sense); 1947e6fb56fSmrg xf86I2CWriteByte(pDev, 0x0E, save); 1957e6fb56fSmrg 1967e6fb56fSmrg return (sense & 0x0F); 1977e6fb56fSmrg} 1987e6fb56fSmrg 1997e6fb56fSmrg/* 2007e6fb56fSmrg * VT1625 moves DACa through DACd from bits 0-3 to 2-5. 2017e6fb56fSmrg */ 2027e6fb56fSmrgstatic CARD8 2037e6fb56fSmrgVT1625DACSenseI2C(I2CDevPtr pDev) 2047e6fb56fSmrg{ 2057e6fb56fSmrg CARD8 save, sense; 2067e6fb56fSmrg 2077e6fb56fSmrg xf86I2CReadByte(pDev, 0x0E, &save); 2087e6fb56fSmrg xf86I2CWriteByte(pDev, 0x0E, 0x00); 2097e6fb56fSmrg xf86I2CWriteByte(pDev, 0x0E, 0x80); 2107e6fb56fSmrg xf86I2CWriteByte(pDev, 0x0E, 0x00); 2117e6fb56fSmrg xf86I2CReadByte(pDev, 0x0F, &sense); 2127e6fb56fSmrg xf86I2CWriteByte(pDev, 0x0E, save); 2137e6fb56fSmrg 2147e6fb56fSmrg return (sense & 0x3F); 2157e6fb56fSmrg} 2167e6fb56fSmrg 2177e6fb56fSmrg/* 2187e6fb56fSmrg * VT1621 only knows composite and s-video. 2197e6fb56fSmrg */ 2207e6fb56fSmrgstatic Bool 2217e6fb56fSmrgVT1621DACSense(ScrnInfoPtr pScrn) 2227e6fb56fSmrg{ 2237e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 2247e6fb56fSmrg CARD8 sense; 2257e6fb56fSmrg 2267e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1621DACSense\n")); 2277e6fb56fSmrg 2287e6fb56fSmrg sense = VT162xDACSenseI2C(pBIOSInfo->TVI2CDev); 2297e6fb56fSmrg switch (sense) { 2307e6fb56fSmrg case 0x00: 2317e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_SC; 2327e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2337e6fb56fSmrg "VT1621: S-Video & Composite connected.\n"); 2347e6fb56fSmrg return TRUE; 2357e6fb56fSmrg case 0x01: 2367e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_COMPOSITE; 2377e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2387e6fb56fSmrg "VT1621: Composite connected.\n"); 2397e6fb56fSmrg return TRUE; 2407e6fb56fSmrg case 0x02: 2417e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_SVIDEO; 2427e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2437e6fb56fSmrg "VT1621: S-Video connected.\n"); 2447e6fb56fSmrg return TRUE; 2457e6fb56fSmrg case 0x03: 2467e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_NONE; 2477e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2487e6fb56fSmrg "VT1621: Nothing connected.\n"); 2497e6fb56fSmrg return FALSE; 2507e6fb56fSmrg default: 2517e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_NONE; 2527e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2537e6fb56fSmrg "VT1621: Unknown cable combination: 0x0%2X.\n", sense); 2547e6fb56fSmrg return FALSE; 2557e6fb56fSmrg } 2567e6fb56fSmrg} 2577e6fb56fSmrg 2587e6fb56fSmrg/* 2597e6fb56fSmrg * VT1622, VT1622A and VT1623 know composite, s-video, RGB and YCBCR. 2607e6fb56fSmrg */ 2617e6fb56fSmrgstatic Bool 2627e6fb56fSmrgVT1622DACSense(ScrnInfoPtr pScrn) 2637e6fb56fSmrg{ 2647e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 2657e6fb56fSmrg CARD8 sense; 2667e6fb56fSmrg 2677e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1622DACSense\n")); 2687e6fb56fSmrg 2697e6fb56fSmrg sense = VT162xDACSenseI2C(pBIOSInfo->TVI2CDev); 2707e6fb56fSmrg switch (sense) { 2717e6fb56fSmrg case 0x00: /* DAC A,B,C,D */ 2727e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_RGB; 2737e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2747e6fb56fSmrg "VT162x: RGB connected.\n"); 2757e6fb56fSmrg return TRUE; 2767e6fb56fSmrg case 0x01: /* DAC A,B,C */ 2777e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_SC; 2787e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2797e6fb56fSmrg "VT162x: S-Video & Composite connected.\n"); 2807e6fb56fSmrg return TRUE; 2817e6fb56fSmrg case 0x07: /* DAC A */ 2827e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_COMPOSITE; 2837e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2847e6fb56fSmrg "VT162x: Composite connected.\n"); 2857e6fb56fSmrg return TRUE; 2867e6fb56fSmrg case 0x08: /* DAC B,C,D */ 2877e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_YCBCR; 2887e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2897e6fb56fSmrg "VT162x: YcBcR connected.\n"); 2907e6fb56fSmrg return TRUE; 2917e6fb56fSmrg case 0x09: /* DAC B,C */ 2927e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_SVIDEO; 2937e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2947e6fb56fSmrg "VT162x: S-Video connected.\n"); 2957e6fb56fSmrg return TRUE; 2967e6fb56fSmrg case 0x0F: 2977e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_NONE; 2987e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2997e6fb56fSmrg "VT162x: Nothing connected.\n"); 3007e6fb56fSmrg return FALSE; 3017e6fb56fSmrg default: 3027e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_NONE; 3037e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3047e6fb56fSmrg "VT162x: Unknown cable combination: 0x0%2X.\n", sense); 3057e6fb56fSmrg return FALSE; 3067e6fb56fSmrg } 3077e6fb56fSmrg} 3087e6fb56fSmrg 3097e6fb56fSmrg/* 3107e6fb56fSmrg * VT1625 knows composite, s-video, RGB and YCBCR. 3117e6fb56fSmrg */ 3127e6fb56fSmrgstatic Bool 3137e6fb56fSmrgVT1625DACSense(ScrnInfoPtr pScrn) 3147e6fb56fSmrg{ 3157e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 3167e6fb56fSmrg CARD8 sense; 3177e6fb56fSmrg 3187e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1625DACSense\n")); 3197e6fb56fSmrg 3207e6fb56fSmrg sense = VT1625DACSenseI2C(pBIOSInfo->TVI2CDev); 3217e6fb56fSmrg switch (sense) { 3227e6fb56fSmrg case 0x00: /* DAC A,B,C,D,E,F */ 3237e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_RGB; 3247e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3257e6fb56fSmrg "VT1625: RGB connected.\n"); 3267e6fb56fSmrg return TRUE; 3277e6fb56fSmrg case 0x07: /* DAC A,B,C */ 3287e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_SC; 3297e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3307e6fb56fSmrg "VT1625: S-Video & Composite connected.\n"); 3317e6fb56fSmrg return TRUE; 3327e6fb56fSmrg case 0x37: /* DAC C */ 3337e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_COMPOSITE; 3347e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3357e6fb56fSmrg "VT1625: Composite connected.\n"); 3367e6fb56fSmrg return TRUE; 3377e6fb56fSmrg case 0x38: /* DAC D,E,F */ 3387e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_YCBCR; 3397e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3407e6fb56fSmrg "VT1625: YCbCr connected.\n"); 3417e6fb56fSmrg return TRUE; 3427e6fb56fSmrg case 0x0F: /* DAC A,B */ 3437e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_SVIDEO; 3447e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3457e6fb56fSmrg "VT1625: S-Video connected.\n"); 3467e6fb56fSmrg return TRUE; 3477e6fb56fSmrg case 0x3F: 3487e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_NONE; 3497e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3507e6fb56fSmrg "VT1625: Nothing connected.\n"); 3517e6fb56fSmrg return FALSE; 3527e6fb56fSmrg default: 3537e6fb56fSmrg pBIOSInfo->TVOutput = TVOUTPUT_NONE; 3547e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3557e6fb56fSmrg "VT1625: Unknown cable combination: 0x0%2X.\n", sense); 3567e6fb56fSmrg return FALSE; 3577e6fb56fSmrg } 3587e6fb56fSmrg} 3597e6fb56fSmrg 3607e6fb56fSmrgstatic CARD8 3617e6fb56fSmrgVT1621ModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) 3627e6fb56fSmrg{ 3637e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 3647e6fb56fSmrg int i; 3657e6fb56fSmrg 3667e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1621ModeIndex\n")); 3677e6fb56fSmrg 3687e6fb56fSmrg for (i = 0; VT1621Table[i].Width; i++) { 3697e6fb56fSmrg if ((VT1621Table[i].Width == mode->CrtcHDisplay) && 3707e6fb56fSmrg (VT1621Table[i].Height == mode->CrtcVDisplay) && 3717e6fb56fSmrg (VT1621Table[i].Standard == pBIOSInfo->TVType) && 3727e6fb56fSmrg !(strcmp(VT1621Table[i].name, mode->name))) 3737e6fb56fSmrg return i; 3747e6fb56fSmrg } 3757e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VT1621ModeIndex:" 3767e6fb56fSmrg " Mode \"%s\" not found in Table\n", mode->name); 3777e6fb56fSmrg return 0xFF; 3787e6fb56fSmrg} 3797e6fb56fSmrg 3807e6fb56fSmrgstatic ModeStatus 3817e6fb56fSmrgVT1621ModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode) 3827e6fb56fSmrg{ 3837e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 3847e6fb56fSmrg 3857e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1621ModeValid\n")); 3867e6fb56fSmrg 3877e6fb56fSmrg if ((mode->PrivSize != sizeof(struct VT162xModePrivate)) || 3887e6fb56fSmrg ((mode->Private != (void *)&VT162xModePrivateNTSC) && 3897e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivatePAL))) { 3907e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3917e6fb56fSmrg "Not a mode defined by the TV Encoder.\n"); 3927e6fb56fSmrg return MODE_BAD; 3937e6fb56fSmrg } 3947e6fb56fSmrg 3957e6fb56fSmrg if ((pBIOSInfo->TVType == TVTYPE_NTSC) && 3967e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivateNTSC)) { 3977e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3987e6fb56fSmrg "TV standard is NTSC. This is a PAL mode.\n"); 3997e6fb56fSmrg return MODE_BAD; 4007e6fb56fSmrg } else if ((pBIOSInfo->TVType == TVTYPE_PAL) && 4017e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivatePAL)) { 4027e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4037e6fb56fSmrg "TV standard is PAL. This is a NTSC mode.\n"); 4047e6fb56fSmrg return MODE_BAD; 4057e6fb56fSmrg } 4067e6fb56fSmrg 4077e6fb56fSmrg if (VT1621ModeIndex(pScrn, mode) != 0xFF) 4087e6fb56fSmrg return MODE_OK; 4097e6fb56fSmrg return MODE_BAD; 4107e6fb56fSmrg} 4117e6fb56fSmrg 4127e6fb56fSmrgstatic CARD8 4137e6fb56fSmrgVT1622ModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) 4147e6fb56fSmrg{ 4157e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 4167e6fb56fSmrg struct VT162XTableRec *Table; 4177e6fb56fSmrg int i; 4187e6fb56fSmrg 4197e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1622ModeIndex\n")); 4207e6fb56fSmrg 4217e6fb56fSmrg if (pBIOSInfo->TVEncoder == VIA_VT1622) 4227e6fb56fSmrg Table = VT1622Table; 4237e6fb56fSmrg else if (pBIOSInfo->TVEncoder == VIA_VT1625) 4247e6fb56fSmrg Table = VT1625Table; 4257e6fb56fSmrg else 4267e6fb56fSmrg Table = VT1623Table; 4277e6fb56fSmrg 4287e6fb56fSmrg for (i = 0; Table[i].Width; i++) { 4297e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 4307e6fb56fSmrg "width=%d:%d, height=%d:%d, std=%d:%d, name=%s:%s.\n", 4317e6fb56fSmrg Table[i].Width, mode->CrtcHDisplay, 4327e6fb56fSmrg Table[i].Height, mode->CrtcVDisplay, 4337e6fb56fSmrg Table[i].Standard, pBIOSInfo->TVType, 4347e6fb56fSmrg Table[i].name, mode->name); 4357e6fb56fSmrg 4367e6fb56fSmrg if ((Table[i].Width == mode->CrtcHDisplay) && 4377e6fb56fSmrg (Table[i].Height == mode->CrtcVDisplay) && 4387e6fb56fSmrg (Table[i].Standard == pBIOSInfo->TVType) && 4397e6fb56fSmrg !strcmp(Table[i].name, mode->name)) 4407e6fb56fSmrg return i; 4417e6fb56fSmrg } 4427e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VT1622ModeIndex:" 4437e6fb56fSmrg " Mode \"%s\" not found in Table\n", mode->name); 4447e6fb56fSmrg return 0xFF; 4457e6fb56fSmrg} 4467e6fb56fSmrg 4477e6fb56fSmrgstatic ModeStatus 4487e6fb56fSmrgVT1622ModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode) 4497e6fb56fSmrg{ 4507e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 4517e6fb56fSmrg 4527e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1622ModeValid\n")); 4537e6fb56fSmrg 4547e6fb56fSmrg if ((mode->PrivSize != sizeof(struct VT162xModePrivate)) || 4557e6fb56fSmrg ((mode->Private != (void *)&VT162xModePrivateNTSC) && 4567e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivatePAL))) { 4577e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4587e6fb56fSmrg "Not a mode defined by the TV Encoder.\n"); 4597e6fb56fSmrg return MODE_BAD; 4607e6fb56fSmrg } 4617e6fb56fSmrg 4627e6fb56fSmrg if ((pBIOSInfo->TVType == TVTYPE_NTSC) && 4637e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivateNTSC)) { 4647e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4657e6fb56fSmrg "TV standard is NTSC. This is a PAL mode.\n"); 4667e6fb56fSmrg return MODE_BAD; 4677e6fb56fSmrg } else if ((pBIOSInfo->TVType == TVTYPE_PAL) && 4687e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivatePAL)) { 4697e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4707e6fb56fSmrg "TV standard is PAL. This is a NTSC mode.\n"); 4717e6fb56fSmrg return MODE_BAD; 4727e6fb56fSmrg } 4737e6fb56fSmrg 4747e6fb56fSmrg if (VT1622ModeIndex(pScrn, mode) != 0xFF) 4757e6fb56fSmrg return MODE_OK; 4767e6fb56fSmrg return MODE_BAD; 4777e6fb56fSmrg} 4787e6fb56fSmrg 4797e6fb56fSmrgstatic ModeStatus 4807e6fb56fSmrgVT1625ModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode) 4817e6fb56fSmrg{ 4827e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 4837e6fb56fSmrg 4847e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1625ModeValid\n")); 4857e6fb56fSmrg 4867e6fb56fSmrg if ((mode->PrivSize != sizeof(struct VT162xModePrivate)) || 4877e6fb56fSmrg ((mode->Private != (void *)&VT162xModePrivateNTSC) && 4887e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivatePAL) && 4897e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivate480P) && 4907e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivate576P) && 4917e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivate720P) && 4927e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivate1080I))) { 4937e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4947e6fb56fSmrg "Not a mode defined by the TV Encoder.\n"); 4957e6fb56fSmrg return MODE_BAD; 4967e6fb56fSmrg } 4977e6fb56fSmrg 4987e6fb56fSmrg if ((pBIOSInfo->TVType == TVTYPE_NTSC) && 4997e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivateNTSC)) { 5007e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 5017e6fb56fSmrg "TV standard is NTSC. This is an incompatible mode.\n"); 5027e6fb56fSmrg return MODE_BAD; 5037e6fb56fSmrg } else if ((pBIOSInfo->TVType == TVTYPE_PAL) && 5047e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivatePAL)) { 5057e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 5067e6fb56fSmrg "TV standard is PAL. This is an incompatible mode.\n"); 5077e6fb56fSmrg return MODE_BAD; 5087e6fb56fSmrg } else if ((pBIOSInfo->TVType == TVTYPE_480P) && 5097e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivate480P)) { 5107e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 5117e6fb56fSmrg "TV standard is 480P. This is an incompatible mode.\n"); 5127e6fb56fSmrg return MODE_BAD; 5137e6fb56fSmrg } else if ((pBIOSInfo->TVType == TVTYPE_576P) && 5147e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivate576P)) { 5157e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 5167e6fb56fSmrg "TV standard is 576P. This is an incompatible mode.\n"); 5177e6fb56fSmrg return MODE_BAD; 5187e6fb56fSmrg } else if ((pBIOSInfo->TVType == TVTYPE_720P) && 5197e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivate720P)) { 5207e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 5217e6fb56fSmrg "TV standard is 720P. This is an incompatible mode.\n"); 5227e6fb56fSmrg return MODE_BAD; 5237e6fb56fSmrg } else if ((pBIOSInfo->TVType == TVTYPE_1080I) && 5247e6fb56fSmrg (mode->Private != (void *)&VT162xModePrivate1080I)) { 5257e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 5267e6fb56fSmrg "TV standard is 1080I. This is an incompatible mode.\n"); 5277e6fb56fSmrg return MODE_BAD; 5287e6fb56fSmrg } 5297e6fb56fSmrg 5307e6fb56fSmrg if (VT1622ModeIndex(pScrn, mode) != 0xFF) 5317e6fb56fSmrg return MODE_OK; 5327e6fb56fSmrg return MODE_BAD; 5337e6fb56fSmrg} 5347e6fb56fSmrg 5357e6fb56fSmrg 5367e6fb56fSmrgstatic void 5377e6fb56fSmrgVT162xSetSubCarrier(I2CDevPtr pDev, CARD32 SubCarrier) 5387e6fb56fSmrg{ 5397e6fb56fSmrg xf86I2CWriteByte(pDev, 0x16, SubCarrier & 0xFF); 5407e6fb56fSmrg xf86I2CWriteByte(pDev, 0x17, (SubCarrier >> 8) & 0xFF); 5417e6fb56fSmrg xf86I2CWriteByte(pDev, 0x18, (SubCarrier >> 16) & 0xFF); 5427e6fb56fSmrg xf86I2CWriteByte(pDev, 0x19, (SubCarrier >> 24) & 0xFF); 5437e6fb56fSmrg} 5447e6fb56fSmrg 5457e6fb56fSmrgstatic void 5467e6fb56fSmrgVT1621ModeI2C(ScrnInfoPtr pScrn, DisplayModePtr mode) 5477e6fb56fSmrg{ 5487e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 5497e6fb56fSmrg struct VT1621TableRec Table = VT1621Table[VT1621ModeIndex(pScrn, mode)]; 5507e6fb56fSmrg CARD8 i; 5517e6fb56fSmrg 5527e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1621ModeI2C\n")); 5537e6fb56fSmrg 5547e6fb56fSmrg for (i = 0; i < 0x16; i++) 5557e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, Table.TV[i]); 5567e6fb56fSmrg 5577e6fb56fSmrg VT162xSetSubCarrier(pBIOSInfo->TVI2CDev, Table.SubCarrier); 5587e6fb56fSmrg 5597e6fb56fSmrg /* Skip reserved (1A) and version ID (1B). */ 5607e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1C, Table.TV[0x1C]); 5617e6fb56fSmrg 5627e6fb56fSmrg /* Skip software reset (1D). */ 5637e6fb56fSmrg for (i = 0x1E; i < 0x24; i++) 5647e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, Table.TV[i]); 5657e6fb56fSmrg 5667e6fb56fSmrg /* Write some zeroes? */ 5677e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x24, 0x00); 5687e6fb56fSmrg for (i = 0; i < 0x08; i++) 5697e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x4A + i, 0x00); 5707e6fb56fSmrg 5717e6fb56fSmrg if (pBIOSInfo->TVOutput == TVOUTPUT_COMPOSITE) 5727e6fb56fSmrg for (i = 0; i < 0x10; i++) 5737e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x52 + i, Table.TVC[i]); 5747e6fb56fSmrg else 5757e6fb56fSmrg for (i = 0; i < 0x10; i++) 5767e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x52 + i, Table.TVS[i]); 5777e6fb56fSmrg 5787e6fb56fSmrg /* Turn on all Composite and S-Video output. */ 5797e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, 0x00); 5807e6fb56fSmrg 5817e6fb56fSmrg if (pBIOSInfo->TVDotCrawl) { 5827e6fb56fSmrg if (Table.DotCrawlSubCarrier) { 5837e6fb56fSmrg xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x11, &i); 5847e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x11, i | 0x08); 5857e6fb56fSmrg 5867e6fb56fSmrg VT162xSetSubCarrier(pBIOSInfo->TVI2CDev, Table.DotCrawlSubCarrier); 5877e6fb56fSmrg } else 5887e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "This mode does not currently " 5897e6fb56fSmrg "support DotCrawl suppression.\n"); 5907e6fb56fSmrg } 5917e6fb56fSmrg} 5927e6fb56fSmrg 5937e6fb56fSmrgstatic void 5947e6fb56fSmrgVT1621ModeCrtc(ScrnInfoPtr pScrn, DisplayModePtr mode) 5957e6fb56fSmrg{ 5967e6fb56fSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 5977e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 5987e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 5997e6fb56fSmrg struct VT1621TableRec Table = VT1621Table[VT1621ModeIndex(pScrn, mode)]; 6007e6fb56fSmrg 6017e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1621ModeCrtc\n")); 6027e6fb56fSmrg 6037e6fb56fSmrg if (pVia->IsSecondary) { 6047e6fb56fSmrg hwp->writeCrtc(hwp, 0x6A, 0x80); 6057e6fb56fSmrg hwp->writeCrtc(hwp, 0x6B, 0x20); 6067e6fb56fSmrg hwp->writeCrtc(hwp, 0x6C, 0x80); 6077e6fb56fSmrg 6087e6fb56fSmrg /* Disable LCD Scaling */ 6097e6fb56fSmrg if (!pVia->SAMM || pVia->FirstInit) 6107e6fb56fSmrg hwp->writeCrtc(hwp, 0x79, 0x00); 6117e6fb56fSmrg 6127e6fb56fSmrg } else { 6137e6fb56fSmrg hwp->writeCrtc(hwp, 0x6A, 0x00); 6147e6fb56fSmrg hwp->writeCrtc(hwp, 0x6B, 0x80); 6157e6fb56fSmrg hwp->writeCrtc(hwp, 0x6C, Table.PrimaryCR6C); 6167e6fb56fSmrg } 6177e6fb56fSmrg pBIOSInfo->ClockExternal = TRUE; 6187e6fb56fSmrg ViaCrtcMask(hwp, 0x6A, 0x40, 0x40); 6197e6fb56fSmrg ViaCrtcMask(hwp, 0x6C, 0x01, 0x01); 6207e6fb56fSmrg} 6217e6fb56fSmrg 6227e6fb56fSmrg/* 6237e6fb56fSmrg * Also suited for VT1622A, VT1623, VT1625. 6247e6fb56fSmrg */ 6257e6fb56fSmrgstatic void 6267e6fb56fSmrgVT1622ModeI2C(ScrnInfoPtr pScrn, DisplayModePtr mode) 6277e6fb56fSmrg{ 6287e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 6297e6fb56fSmrg struct VT162XTableRec Table; 6307e6fb56fSmrg CARD8 save, i; 6317e6fb56fSmrg 6327e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1622ModeI2C\n")); 6337e6fb56fSmrg 6347e6fb56fSmrg if (pBIOSInfo->TVEncoder == VIA_VT1622) 6357e6fb56fSmrg Table = VT1622Table[VT1622ModeIndex(pScrn, mode)]; 6367e6fb56fSmrg else if (pBIOSInfo->TVEncoder == VIA_VT1625) 6377e6fb56fSmrg Table = VT1625Table[VT1622ModeIndex(pScrn, mode)]; 6387e6fb56fSmrg else /* VT1622A/VT1623 */ 6397e6fb56fSmrg Table = VT1623Table[VT1622ModeIndex(pScrn, mode)]; 6407e6fb56fSmrg 6417e6fb56fSmrg /* TV reset. */ 6427e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1D, 0x00); 6437e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1D, 0x80); 6447e6fb56fSmrg 6457e6fb56fSmrg for (i = 0; i < 0x16; i++) 6467e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, Table.TV1[i]); 6477e6fb56fSmrg 6487e6fb56fSmrg VT162xSetSubCarrier(pBIOSInfo->TVI2CDev, Table.SubCarrier); 6497e6fb56fSmrg 6507e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1A, Table.TV1[0x1A]); 6517e6fb56fSmrg 6527e6fb56fSmrg /* Skip version ID. */ 6537e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1C, Table.TV1[0x1C]); 6547e6fb56fSmrg 6557e6fb56fSmrg /* Skip software reset. */ 6567e6fb56fSmrg for (i = 0x1E; i < 0x30; i++) 6577e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, Table.TV1[i]); 6587e6fb56fSmrg 6597e6fb56fSmrg for (i = 0; i < 0x1B; i++) 6607e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x4A + i, Table.TV2[i]); 6617e6fb56fSmrg 6627e6fb56fSmrg /* Turn on all Composite and S-Video output. */ 6637e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, 0x00); 6647e6fb56fSmrg 6657e6fb56fSmrg if (pBIOSInfo->TVDotCrawl) { 6667e6fb56fSmrg if (Table.DotCrawlSubCarrier) { 6677e6fb56fSmrg xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x11, &save); 6687e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x11, save | 0x08); 6697e6fb56fSmrg 6707e6fb56fSmrg VT162xSetSubCarrier(pBIOSInfo->TVI2CDev, Table.DotCrawlSubCarrier); 6717e6fb56fSmrg } else 6727e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "This mode does not currently " 6737e6fb56fSmrg "support DotCrawl suppression.\n"); 6747e6fb56fSmrg } 6757e6fb56fSmrg 6767e6fb56fSmrg if (pBIOSInfo->TVOutput == TVOUTPUT_RGB) { 6777e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x02, 0x2A); 6787e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x65, Table.RGB[0]); 6797e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x66, Table.RGB[1]); 6807e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x67, Table.RGB[2]); 6817e6fb56fSmrg if (Table.RGB[3]) 6827e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x27, Table.RGB[3]); 6837e6fb56fSmrg if (Table.RGB[4]) 6847e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x2B, Table.RGB[4]); 6857e6fb56fSmrg if (Table.RGB[5]) 6867e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x2C, Table.RGB[5]); 6877e6fb56fSmrg if (pBIOSInfo->TVEncoder == VIA_VT1625) { 6887e6fb56fSmrg if (pBIOSInfo->TVType < TVTYPE_480P) { 6897e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x02, 0x12); 6907e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x23, 0x7E); 6917e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x4A, 0x85); 6927e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x4B, 0x0A); 6937e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x4E, 0x00); 6947e6fb56fSmrg } else { 6957e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x02, 0x12); 6967e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x4A, 0x85); 6977e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x4B, 0x0A); 6987e6fb56fSmrg } 6997e6fb56fSmrg } 7007e6fb56fSmrg } else if (pBIOSInfo->TVOutput == TVOUTPUT_YCBCR) { 7017e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x02, 0x03); 7027e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x65, Table.YCbCr[0]); 7037e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x66, Table.YCbCr[1]); 7047e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x67, Table.YCbCr[2]); 7057e6fb56fSmrg if (pBIOSInfo->TVEncoder == VIA_VT1625) { 7067e6fb56fSmrg if (pBIOSInfo->TVType < TVTYPE_480P) { 7077e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x23, 0x7E); 7087e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x4E, 0x00); 7097e6fb56fSmrg } 7107e6fb56fSmrg } 7117e6fb56fSmrg } 7127e6fb56fSmrg 7137e6fb56fSmrg /* Configure flicker filter. */ 7147e6fb56fSmrg xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x03, &save); 7157e6fb56fSmrg save &= 0xFC; 7167e6fb56fSmrg if (pBIOSInfo->TVDeflicker == 1) 7177e6fb56fSmrg save |= 0x01; 7187e6fb56fSmrg else if (pBIOSInfo->TVDeflicker == 2) 7197e6fb56fSmrg save |= 0x02; 7207e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x03, save); 7217e6fb56fSmrg} 7227e6fb56fSmrg 7237e6fb56fSmrg/* 7247e6fb56fSmrg * Also suited for VT1622A, VT1623, VT1625. 7257e6fb56fSmrg */ 7267e6fb56fSmrgstatic void 7277e6fb56fSmrgVT1622ModeCrtc(ScrnInfoPtr pScrn, DisplayModePtr mode) 7287e6fb56fSmrg{ 7297e6fb56fSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 7307e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 7317e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 7327e6fb56fSmrg struct VT162XTableRec Table; 7337e6fb56fSmrg 7347e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1622ModeCrtc\n")); 7357e6fb56fSmrg 7367e6fb56fSmrg if (pBIOSInfo->TVEncoder == VIA_VT1622) 7377e6fb56fSmrg Table = VT1622Table[VT1622ModeIndex(pScrn, mode)]; 7387e6fb56fSmrg else if (pBIOSInfo->TVEncoder == VIA_VT1625) 7397e6fb56fSmrg Table = VT1625Table[VT1622ModeIndex(pScrn, mode)]; 7407e6fb56fSmrg else /* VT1622A/VT1623 */ 7417e6fb56fSmrg Table = VT1623Table[VT1622ModeIndex(pScrn, mode)]; 7427e6fb56fSmrg 7437e6fb56fSmrg hwp->writeCrtc(hwp, 0x6A, 0x00); 7447e6fb56fSmrg hwp->writeCrtc(hwp, 0x6B, 0x00); 7457e6fb56fSmrg hwp->writeCrtc(hwp, 0x6C, 0x00); 7467e6fb56fSmrg 7477e6fb56fSmrg if (pVia->IsSecondary) { 7487e6fb56fSmrg hwp->writeCrtc(hwp, 0x6C, Table.SecondaryCR6C); 7497e6fb56fSmrg 7507e6fb56fSmrg ViaCrtcMask(hwp, 0x6A, 0x80, 0x80); 7517e6fb56fSmrg ViaCrtcMask(hwp, 0x6C, 0x80, 0x80); 7527e6fb56fSmrg 7537e6fb56fSmrg /* CLE266Ax use 2x XCLK. */ 7547e6fb56fSmrg if ((pVia->Chipset == VIA_CLE266) && CLE266_REV_IS_AX(pVia->ChipRev)) { 7557e6fb56fSmrg ViaCrtcMask(hwp, 0x6B, 0x20, 0x20); 7567e6fb56fSmrg 7577e6fb56fSmrg /* Fix TV clock polarity for CLE266A2. */ 7587e6fb56fSmrg if (pVia->ChipRev == 0x02) 7597e6fb56fSmrg ViaCrtcMask(hwp, 0x6C, 0x1C, 0x1C); 7607e6fb56fSmrg } 7617e6fb56fSmrg 7627e6fb56fSmrg /* Disable LCD scaling. */ 7637e6fb56fSmrg if (!pVia->SAMM || pVia->FirstInit) 7647e6fb56fSmrg hwp->writeCrtc(hwp, 0x79, 0x00); 7657e6fb56fSmrg 7667e6fb56fSmrg } else { 7677e6fb56fSmrg if ((pVia->Chipset == VIA_CLE266) && CLE266_REV_IS_AX(pVia->ChipRev)) { 7687e6fb56fSmrg ViaCrtcMask(hwp, 0x6B, 0x80, 0x80); 7697e6fb56fSmrg 7707e6fb56fSmrg /* Fix TV clock polarity for CLE266A2. */ 7717e6fb56fSmrg if (pVia->ChipRev == 0x02) 7727e6fb56fSmrg hwp->writeCrtc(hwp, 0x6C, Table.PrimaryCR6C); 7737e6fb56fSmrg } 7747e6fb56fSmrg } 7757e6fb56fSmrg pBIOSInfo->ClockExternal = TRUE; 7767e6fb56fSmrg ViaCrtcMask(hwp, 0x6A, 0x40, 0x40); 7777e6fb56fSmrg ViaSetTVClockSource(pScrn); 7787e6fb56fSmrg} 7797e6fb56fSmrg 7807e6fb56fSmrg 7817e6fb56fSmrgstatic void 7827e6fb56fSmrgVT1621Power(ScrnInfoPtr pScrn, Bool On) 7837e6fb56fSmrg{ 7847e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 7857e6fb56fSmrg 7867e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1621Power\n")); 7877e6fb56fSmrg 7887e6fb56fSmrg if (On) 7897e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, 0x00); 7907e6fb56fSmrg else 7917e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, 0x03); 7927e6fb56fSmrg} 7937e6fb56fSmrg 7947e6fb56fSmrgstatic void 7957e6fb56fSmrgVT1622Power(ScrnInfoPtr pScrn, Bool On) 7967e6fb56fSmrg{ 7977e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 7987e6fb56fSmrg 7997e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1622Power\n")); 8007e6fb56fSmrg 8017e6fb56fSmrg if (On) 8027e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, 0x00); 8037e6fb56fSmrg else 8047e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, 0x0F); 8057e6fb56fSmrg} 8067e6fb56fSmrg 8077e6fb56fSmrgstatic void 8087e6fb56fSmrgVT1625Power(ScrnInfoPtr pScrn, Bool On) 8097e6fb56fSmrg{ 8107e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 8117e6fb56fSmrg 8127e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1625Power\n")); 8137e6fb56fSmrg 8147e6fb56fSmrg if (On) 8157e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, 0x00); 8167e6fb56fSmrg else 8177e6fb56fSmrg xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, 0x3F); 8187e6fb56fSmrg} 8197e6fb56fSmrg 8207e6fb56fSmrg 8217e6fb56fSmrgvoid 8227e6fb56fSmrgViaVT162xInit(ScrnInfoPtr pScrn) 8237e6fb56fSmrg{ 8247e6fb56fSmrg VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 8257e6fb56fSmrg 8267e6fb56fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaVT162xInit\n")); 8277e6fb56fSmrg 8287e6fb56fSmrg switch (pBIOSInfo->TVEncoder) { 8297e6fb56fSmrg case VIA_VT1621: 8307e6fb56fSmrg pBIOSInfo->TVSave = VT162xSave; 8317e6fb56fSmrg pBIOSInfo->TVRestore = VT162xRestore; 8327e6fb56fSmrg pBIOSInfo->TVDACSense = VT1621DACSense; 8337e6fb56fSmrg pBIOSInfo->TVModeValid = VT1621ModeValid; 8347e6fb56fSmrg pBIOSInfo->TVModeI2C = VT1621ModeI2C; 8357e6fb56fSmrg pBIOSInfo->TVModeCrtc = VT1621ModeCrtc; 8367e6fb56fSmrg pBIOSInfo->TVPower = VT1621Power; 8377e6fb56fSmrg pBIOSInfo->TVModes = VT1621Modes; 8387e6fb56fSmrg pBIOSInfo->TVPrintRegs = VT162xPrintRegs; 8397e6fb56fSmrg pBIOSInfo->TVNumRegs = 0x68; 8407e6fb56fSmrg break; 8417e6fb56fSmrg case VIA_VT1622: 8427e6fb56fSmrg pBIOSInfo->TVSave = VT162xSave; 8437e6fb56fSmrg pBIOSInfo->TVRestore = VT162xRestore; 8447e6fb56fSmrg pBIOSInfo->TVDACSense = VT1622DACSense; 8457e6fb56fSmrg pBIOSInfo->TVModeValid = VT1622ModeValid; 8467e6fb56fSmrg pBIOSInfo->TVModeI2C = VT1622ModeI2C; 8477e6fb56fSmrg pBIOSInfo->TVModeCrtc = VT1622ModeCrtc; 8487e6fb56fSmrg pBIOSInfo->TVPower = VT1622Power; 8497e6fb56fSmrg pBIOSInfo->TVModes = VT1622Modes; 8507e6fb56fSmrg pBIOSInfo->TVPrintRegs = VT162xPrintRegs; 8517e6fb56fSmrg pBIOSInfo->TVNumRegs = 0x68; 8527e6fb56fSmrg break; 8537e6fb56fSmrg case VIA_VT1623: 8547e6fb56fSmrg pBIOSInfo->TVSave = VT162xSave; 8557e6fb56fSmrg pBIOSInfo->TVRestore = VT162xRestore; 8567e6fb56fSmrg pBIOSInfo->TVDACSense = VT1622DACSense; 8577e6fb56fSmrg pBIOSInfo->TVModeValid = VT1622ModeValid; 8587e6fb56fSmrg pBIOSInfo->TVModeI2C = VT1622ModeI2C; 8597e6fb56fSmrg pBIOSInfo->TVModeCrtc = VT1622ModeCrtc; 8607e6fb56fSmrg pBIOSInfo->TVPower = VT1622Power; 8617e6fb56fSmrg pBIOSInfo->TVModes = VT1623Modes; 8627e6fb56fSmrg pBIOSInfo->TVPrintRegs = VT162xPrintRegs; 8637e6fb56fSmrg pBIOSInfo->TVNumRegs = 0x6C; 8647e6fb56fSmrg break; 8657e6fb56fSmrg case VIA_VT1625: 8667e6fb56fSmrg pBIOSInfo->TVSave = VT162xSave; 8677e6fb56fSmrg pBIOSInfo->TVRestore = VT162xRestore; 8687e6fb56fSmrg pBIOSInfo->TVDACSense = VT1625DACSense; 8697e6fb56fSmrg pBIOSInfo->TVModeValid = VT1625ModeValid; 8707e6fb56fSmrg pBIOSInfo->TVModeI2C = VT1622ModeI2C; 8717e6fb56fSmrg pBIOSInfo->TVModeCrtc = VT1622ModeCrtc; 8727e6fb56fSmrg pBIOSInfo->TVPower = VT1625Power; 8737e6fb56fSmrg pBIOSInfo->TVModes = VT1625Modes; 8747e6fb56fSmrg pBIOSInfo->TVPrintRegs = VT162xPrintRegs; 8757e6fb56fSmrg pBIOSInfo->TVNumRegs = 0x6C; 8767e6fb56fSmrg break; 8777e6fb56fSmrg default: 8787e6fb56fSmrg break; 8797e6fb56fSmrg } 8807e6fb56fSmrg} 881