17104f784Smrg/* 27104f784SmrgCopyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. 37104f784SmrgCopyright (C) 2000 Silicon Motion, Inc. All Rights Reserved. 47104f784SmrgCopyright (C) 2008 Francisco Jerez. All Rights Reserved. 57104f784Smrg 67104f784SmrgPermission is hereby granted, free of charge, to any person obtaining a copy of 77104f784Smrgthis software and associated documentation files (the "Software"), to deal in 87104f784Smrgthe Software without restriction, including without limitation the rights to 97104f784Smrguse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 107104f784Smrgof the Software, and to permit persons to whom the Software is furnished to do 117104f784Smrgso, subject to the following conditions: 127104f784Smrg 137104f784SmrgThe above copyright notice and this permission notice shall be included in all 147104f784Smrgcopies or substantial portions of the Software. 157104f784Smrg 167104f784SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 177104f784SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 187104f784SmrgNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 197104f784SmrgXFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 207104f784SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 217104f784SmrgWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 227104f784Smrg 237104f784SmrgExcept as contained in this notice, the names of The XFree86 Project and 247104f784SmrgSilicon Motion shall not be used in advertising or otherwise to promote the 257104f784Smrgsale, use or other dealings in this Software without prior written 267104f784Smrgauthorization from The XFree86 Project or Silicon Motion. 277104f784Smrg*/ 287104f784Smrg 297104f784Smrg#ifdef HAVE_CONFIG_H 307104f784Smrg#include "config.h" 317104f784Smrg#endif 327104f784Smrg 337104f784Smrg#include "smi.h" 347104f784Smrg#include "smi_crtc.h" 357104f784Smrg#include "smilynx.h" 367104f784Smrg#include "smi_501.h" 377104f784Smrg 387104f784Smrgstatic void 397104f784SmrgSMI_OutputCreateResources(xf86OutputPtr output) 407104f784Smrg{ 417104f784Smrg ENTER(); 427104f784Smrg /* Nothing */ 437104f784Smrg LEAVE(); 447104f784Smrg} 457104f784Smrg 467104f784Smrgstatic int 477104f784SmrgSMI_OutputModeValid(xf86OutputPtr output, DisplayModePtr mode) 487104f784Smrg{ 497104f784Smrg ScrnInfoPtr pScrn = output->scrn; 507104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 517104f784Smrg 527104f784Smrg ENTER(); 537104f784Smrg 547104f784Smrg /* FIXME May also need to test for IS_MSOC(pSmi) here. 557104f784Smrg * Only accept modes matching the panel size because the panel cannot 5672320d7bSmrg * be centered neither shrunk/expanded due to hardware bugs. 577104f784Smrg * Note that as long as plane tr/br and plane window x/y are set to 0 587104f784Smrg * and the mode height matches the panel height, it will work and 597104f784Smrg * set the mode, but at offset 0, and properly program the crt. 607104f784Smrg * But use panel dimensions so that "full screen" programs will do 617104f784Smrg * their own centering. */ 627104f784Smrg if (output->name && strcmp(output->name, "LVDS") == 0 && 637104f784Smrg (mode->HDisplay != pSmi->lcdWidth || mode->VDisplay != pSmi->lcdHeight)) 647104f784Smrg LEAVE(MODE_PANEL); 657104f784Smrg 667104f784Smrg /* The driver is actually programming modes, instead of loading registers 677104f784Smrg * state from static tables. But still, only accept modes that should 687104f784Smrg * be handled correctly by all hardwares. On the MSOC, currently, only 697104f784Smrg * the crt can be programmed to different resolution modes. 707104f784Smrg */ 717104f784Smrg if (mode->HDisplay & 15) 727104f784Smrg LEAVE(MODE_BAD_WIDTH); 737104f784Smrg 747104f784Smrg if((mode->Clock < pSmi->clockRange.minClock) || 757104f784Smrg (mode->Clock > pSmi->clockRange.maxClock) || 767104f784Smrg ((mode->Flags & V_INTERLACE) && !pSmi->clockRange.interlaceAllowed) || 777104f784Smrg ((mode->Flags & V_DBLSCAN) && (mode->VScan > 1) && !pSmi->clockRange.doubleScanAllowed)){ 787104f784Smrg LEAVE(MODE_CLOCK_RANGE); 797104f784Smrg } 807104f784Smrg 817104f784Smrg 827104f784Smrg LEAVE(MODE_OK); 837104f784Smrg} 847104f784Smrg 857104f784Smrgstatic Bool 867104f784SmrgSMI_OutputModeFixup(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode) 877104f784Smrg{ 887104f784Smrg ENTER(); 897104f784Smrg 907104f784Smrg /* Nothing */ 917104f784Smrg 927104f784Smrg LEAVE(TRUE); 937104f784Smrg} 947104f784Smrg 957104f784Smrgstatic void 967104f784SmrgSMI_OutputPrepare(xf86OutputPtr output) 977104f784Smrg{ 987104f784Smrg ENTER(); 997104f784Smrg 1007104f784Smrg /* Nothing */ 1017104f784Smrg 1027104f784Smrg LEAVE(); 1037104f784Smrg} 1047104f784Smrg 1057104f784Smrgstatic void 1067104f784SmrgSMI_OutputCommit(xf86OutputPtr output) 1077104f784Smrg{ 1087104f784Smrg ENTER(); 1097104f784Smrg 1107104f784Smrg output->funcs->dpms(output,DPMSModeOn); 1117104f784Smrg 1127104f784Smrg LEAVE(); 1137104f784Smrg} 1147104f784Smrg 1157104f784Smrgstatic void 1167104f784SmrgSMI_OutputModeSet(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode) 1177104f784Smrg{ 1187104f784Smrg ENTER(); 1197104f784Smrg 1207104f784Smrg /* Nothing */ 1217104f784Smrg 1227104f784Smrg LEAVE(); 1237104f784Smrg} 1247104f784Smrg 1257104f784Smrgstatic xf86OutputStatus 1267104f784SmrgSMI_OutputDetect(xf86OutputPtr output) 1277104f784Smrg{ 1287104f784Smrg ENTER(); 1297104f784Smrg 1307104f784Smrg LEAVE(XF86OutputStatusUnknown); 1317104f784Smrg} 1327104f784Smrg 1337104f784Smrgxf86OutputStatus 1347104f784SmrgSMI_OutputDetect_lcd(xf86OutputPtr output) 1357104f784Smrg{ 1367104f784Smrg ENTER(); 1377104f784Smrg 1387104f784Smrg LEAVE(XF86OutputStatusConnected); 1397104f784Smrg} 1407104f784Smrg 1417104f784SmrgDisplayModePtr 1427104f784SmrgSMI_OutputGetModes_native(xf86OutputPtr output) 1437104f784Smrg{ 1447104f784Smrg SMIPtr pSmi = SMIPTR(output->scrn); 1456e60514dSmacallan DisplayModePtr m; 1467104f784Smrg ENTER(); 1477104f784Smrg 1487104f784Smrg#ifdef HAVE_XMODES 1496e60514dSmacallan m = xf86CVTMode(pSmi->lcdWidth, pSmi->lcdHeight, 60.0f, FALSE, FALSE); 1506e60514dSmacallan xf86SetModeDefaultName(m); 1516e60514dSmacallan LEAVE(m); 1527104f784Smrg#else 1537104f784Smrg LEAVE(NULL); 1547104f784Smrg#endif 1557104f784Smrg} 1567104f784Smrg 1577104f784Smrgstatic void 1587104f784SmrgSMI_OutputDestroy(xf86OutputPtr output) 1597104f784Smrg{ 1607104f784Smrg ENTER(); 1617104f784Smrg 1627b58d2e0Smrg free((xf86OutputFuncsPtr)output->funcs); 1637104f784Smrg 1647104f784Smrg LEAVE(); 1657104f784Smrg} 1667104f784Smrg 1677104f784Smrgvoid 1687104f784SmrgSMI_OutputFuncsInit_base(xf86OutputFuncsPtr* outputFuncs) 1697104f784Smrg{ 1707104f784Smrg *outputFuncs = xnfcalloc(sizeof(xf86OutputFuncsRec), 1); 1717104f784Smrg 1727104f784Smrg (*outputFuncs)->create_resources = SMI_OutputCreateResources; 1737104f784Smrg (*outputFuncs)->mode_valid = SMI_OutputModeValid; 1747104f784Smrg (*outputFuncs)->mode_fixup = SMI_OutputModeFixup; 1757104f784Smrg (*outputFuncs)->prepare = SMI_OutputPrepare; 1767104f784Smrg (*outputFuncs)->commit = SMI_OutputCommit; 1777104f784Smrg (*outputFuncs)->mode_set = SMI_OutputModeSet; 1787104f784Smrg (*outputFuncs)->detect = SMI_OutputDetect; 1797104f784Smrg (*outputFuncs)->destroy = SMI_OutputDestroy; 1807104f784Smrg} 1817104f784Smrg 1827104f784SmrgBool 1837104f784SmrgSMI_OutputPreInit(ScrnInfoPtr pScrn) 1847104f784Smrg{ 1857104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 1867104f784Smrg 1877104f784Smrg ENTER(); 1887104f784Smrg 1897104f784Smrg if(SMI_MSOC_SERIES(pSmi->Chipset)){ 1907104f784Smrg LEAVE( SMI501_OutputPreInit(pScrn) ); 1917104f784Smrg }else{ 1927104f784Smrg LEAVE( SMILynx_OutputPreInit(pScrn) ); 1937104f784Smrg } 1947104f784Smrg} 1957104f784Smrg 196