17104f784Smrg/* 27104f784SmrgCopyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. 37104f784SmrgCopyright (C) 2000 Silicon Motion, Inc. All Rights Reserved. 47104f784SmrgCopyright (C) 2008 Mandriva Linux. All Rights Reserved. 57104f784SmrgCopyright (C) 2008 Francisco Jerez. All Rights Reserved. 67104f784Smrg 77104f784SmrgPermission is hereby granted, free of charge, to any person obtaining a copy of 87104f784Smrgthis software and associated documentation files (the "Software"), to deal in 97104f784Smrgthe Software without restriction, including without limitation the rights to 107104f784Smrguse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 117104f784Smrgof the Software, and to permit persons to whom the Software is furnished to do 127104f784Smrgso, subject to the following conditions: 137104f784Smrg 147104f784SmrgThe above copyright notice and this permission notice shall be included in all 157104f784Smrgcopies or substantial portions of the Software. 167104f784Smrg 177104f784SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 187104f784SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 197104f784SmrgNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 207104f784SmrgXFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 217104f784SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 227104f784SmrgWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 237104f784Smrg 247104f784SmrgExcept as contained in this notice, the names of The XFree86 Project and 257104f784SmrgSilicon Motion shall not be used in advertising or otherwise to promote the 267104f784Smrgsale, use or other dealings in this Software without prior written 277104f784Smrgauthorization from The XFree86 Project or Silicon Motion. 287104f784Smrg*/ 297104f784Smrg 307104f784Smrg#ifdef HAVE_CONFIG_H 317104f784Smrg#include "config.h" 327104f784Smrg#endif 337104f784Smrg 347104f784Smrg#include "smi.h" 357104f784Smrg#include "smi_crtc.h" 367104f784Smrg#include "smi_501.h" 377104f784Smrg 387104f784Smrg 397104f784Smrgstatic void 407104f784SmrgSMI501_OutputDPMS_lcd(xf86OutputPtr output, int dpms) 417104f784Smrg{ 427104f784Smrg ScrnInfoPtr pScrn = output->scrn; 437104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 447104f784Smrg MSOCRegPtr mode = pSmi->mode; 457104f784Smrg 467104f784Smrg ENTER(); 477104f784Smrg 487104f784Smrg mode->system_ctl.value = READ_SCR(pSmi, SYSTEM_CTL); 497104f784Smrg switch (dpms) { 507104f784Smrg case DPMSModeOn: 517104f784Smrg SMI501_PowerPanel(pScrn, mode, TRUE); 527104f784Smrg case DPMSModeStandby: 537104f784Smrg break; 547104f784Smrg case DPMSModeSuspend: 557104f784Smrg break; 567104f784Smrg case DPMSModeOff: 577104f784Smrg SMI501_PowerPanel(pScrn, mode, FALSE); 587104f784Smrg break; 597104f784Smrg } 607104f784Smrg 617104f784Smrg LEAVE(); 627104f784Smrg} 637104f784Smrg 647104f784Smrgstatic void 657104f784SmrgSMI501_OutputDPMS_crt(xf86OutputPtr output, int dpms) 667104f784Smrg{ 677104f784Smrg ScrnInfoPtr pScrn = output->scrn; 687104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 697104f784Smrg MSOCRegPtr mode = pSmi->mode; 707104f784Smrg 717104f784Smrg ENTER(); 727104f784Smrg 737104f784Smrg mode->system_ctl.value = READ_SCR(pSmi, SYSTEM_CTL); 747104f784Smrg switch (dpms) { 757104f784Smrg case DPMSModeOn: 767104f784Smrg mode->system_ctl.f.dpmsh = 0; 777104f784Smrg mode->system_ctl.f.dpmsv = 0; 787104f784Smrg break; 797104f784Smrg case DPMSModeStandby: 807104f784Smrg mode->system_ctl.f.dpmsh = 1; 817104f784Smrg mode->system_ctl.f.dpmsv = 0; 827104f784Smrg break; 837104f784Smrg case DPMSModeSuspend: 847104f784Smrg mode->system_ctl.f.dpmsh = 0; 857104f784Smrg mode->system_ctl.f.dpmsv = 1; 867104f784Smrg break; 877104f784Smrg case DPMSModeOff: 887104f784Smrg mode->system_ctl.f.dpmsh = 1; 897104f784Smrg mode->system_ctl.f.dpmsv = 1; 907104f784Smrg break; 917104f784Smrg } 927104f784Smrg WRITE_SCR(pSmi, SYSTEM_CTL, mode->system_ctl.value); 937104f784Smrg 947104f784Smrg LEAVE(); 957104f784Smrg} 967104f784Smrg 977104f784Smrg#ifdef USE_CRTC_DETECT 987104f784Smrgstatic xf86OutputStatus 997104f784SmrgSMI501_OutputDetect_crt(xf86OutputPtr output) 1007104f784Smrg{ 1017104f784Smrg ScrnInfoPtr pScrn = output->scrn; 1027104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 1037104f784Smrg MSOCRegPtr mode = pSmi->mode; 1047104f784Smrg xf86OutputStatus status; 1057104f784Smrg 1067104f784Smrg ENTER(); 1077104f784Smrg 1087104f784Smrg mode->crt_detect.value = READ_SCR(pSmi, CRT_DETECT); 1097104f784Smrg mode->crt_detect.f.enable = 1; 1107104f784Smrg WRITE_SCR(pSmi, CRT_DETECT, mode->crt_detect.value); 1117104f784Smrg SMI501_WaitVSync(pSmi, 1); 1127104f784Smrg 1137104f784Smrg mode->crt_detect.value = READ_SCR(pSmi, CRT_DETECT); 1147104f784Smrg 1157104f784Smrg /* FIXME This appears to have a fixed value, whatever I do, and 1167104f784Smrg * the binary pattern is 1000000010000100 1177104f784Smrg * regardless of crt being connected or not, so maybe this is 1187104f784Smrg * just telling there is a VGA output? 1197104f784Smrg */ 1207104f784Smrg status = mode->crt_detect.f.data ? 1217104f784Smrg XF86OutputStatusConnected : XF86OutputStatusUnknown; 1227104f784Smrg 1237104f784Smrg mode->crt_detect.f.enable = 0; 1247104f784Smrg WRITE_SCR(pSmi, CRT_DETECT, mode->crt_detect.value); 1257104f784Smrg SMI501_WaitVSync(pSmi, 1); 1267104f784Smrg 1277104f784Smrg LEAVE(status); 1287104f784Smrg} 1297104f784Smrg#endif 1307104f784Smrg 1317104f784SmrgBool 1327104f784SmrgSMI501_OutputPreInit(ScrnInfoPtr pScrn) 1337104f784Smrg{ 1347104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 1357104f784Smrg xf86OutputPtr output; 1367104f784Smrg xf86OutputFuncsPtr outputFuncs; 1377104f784Smrg 1387104f784Smrg ENTER(); 1397104f784Smrg 1407104f784Smrg /* CRTC0 is LCD */ 1417104f784Smrg SMI_OutputFuncsInit_base(&outputFuncs); 1427104f784Smrg outputFuncs->dpms = SMI501_OutputDPMS_lcd; 1437104f784Smrg outputFuncs->get_modes = SMI_OutputGetModes_native; 1447104f784Smrg outputFuncs->detect = SMI_OutputDetect_lcd; 1457104f784Smrg 1467104f784Smrg if (! (output = xf86OutputCreate(pScrn, outputFuncs, "LVDS"))) 1477104f784Smrg LEAVE(FALSE); 1487104f784Smrg 1497104f784Smrg output->possible_crtcs = 1 << 0; 1507104f784Smrg output->possible_clones = 0; 1517104f784Smrg output->interlaceAllowed = FALSE; 1527104f784Smrg output->doubleScanAllowed = FALSE; 1537104f784Smrg 1547104f784Smrg /* CRTC1 is CRT */ 1557104f784Smrg if (pSmi->Dualhead) { 1567104f784Smrg SMI_OutputFuncsInit_base(&outputFuncs); 1577104f784Smrg outputFuncs->dpms = SMI501_OutputDPMS_crt; 1587104f784Smrg outputFuncs->get_modes = SMI_OutputGetModes_native; 1597104f784Smrg#ifdef USE_CRTC_DETECT 1607104f784Smrg outputFuncs->detect = SMI501_OutputDetect_crt; 1617104f784Smrg#endif 1627104f784Smrg 1637104f784Smrg if (! (output = xf86OutputCreate(pScrn, outputFuncs, "VGA"))) 1647104f784Smrg LEAVE(FALSE); 1657104f784Smrg 1667104f784Smrg output->possible_crtcs = 1 << 1; 1677104f784Smrg output->possible_clones = 0; 1687104f784Smrg output->interlaceAllowed = FALSE; 1697104f784Smrg output->doubleScanAllowed = FALSE; 1707104f784Smrg } 1717104f784Smrg 1727104f784Smrg LEAVE(TRUE); 1737104f784Smrg} 174