smi_output.c revision 6e60514d
1/*
2Copyright (C) 1994-1999 The XFree86 Project, Inc.  All Rights Reserved.
3Copyright (C) 2000 Silicon Motion, Inc.  All Rights Reserved.
4Copyright (C) 2008 Francisco Jerez. All Rights Reserved.
5
6Permission is hereby granted, free of charge, to any person obtaining a copy of
7this software and associated documentation files (the "Software"), to deal in
8the Software without restriction, including without limitation the rights to
9use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10of the Software, and to permit persons to whom the Software is furnished to do
11so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
18NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23Except as contained in this notice, the names of The XFree86 Project and
24Silicon Motion shall not be used in advertising or otherwise to promote the
25sale, use or other dealings in this Software without prior written
26authorization from The XFree86 Project or Silicon Motion.
27*/
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include "smi.h"
34#include "smi_crtc.h"
35#include "smilynx.h"
36#include "smi_501.h"
37
38static void
39SMI_OutputCreateResources(xf86OutputPtr output)
40{
41    ENTER();
42    /* Nothing */
43    LEAVE();
44}
45
46static int
47SMI_OutputModeValid(xf86OutputPtr output, DisplayModePtr mode)
48{
49    ScrnInfoPtr pScrn = output->scrn;
50    SMIPtr pSmi = SMIPTR(pScrn);
51
52    ENTER();
53
54    /* FIXME May also need to test for IS_MSOC(pSmi) here.
55     * Only accept modes matching the panel size because the panel cannot
56     * be centered neither shrinked/expanded due to hardware bugs.
57     * Note that as long as plane tr/br and plane window x/y are set to 0
58     * and the mode height matches the panel height, it will work and
59     * set the mode, but at offset 0, and properly program the crt.
60     * But use panel dimensions so that "full screen" programs will do
61     * their own centering. */
62    if (output->name && strcmp(output->name, "LVDS") == 0 &&
63	(mode->HDisplay != pSmi->lcdWidth || mode->VDisplay != pSmi->lcdHeight))
64	LEAVE(MODE_PANEL);
65
66    /* The driver is actually programming modes, instead of loading registers
67     * state from static tables. But still, only accept modes that should
68     * be handled correctly by all hardwares. On the MSOC, currently, only
69     * the crt can be programmed to different resolution modes.
70     */
71    if (mode->HDisplay & 15)
72	LEAVE(MODE_BAD_WIDTH);
73
74    if((mode->Clock < pSmi->clockRange.minClock) ||
75       (mode->Clock > pSmi->clockRange.maxClock) ||
76       ((mode->Flags & V_INTERLACE) && !pSmi->clockRange.interlaceAllowed) ||
77       ((mode->Flags & V_DBLSCAN) && (mode->VScan > 1) && !pSmi->clockRange.doubleScanAllowed)){
78	LEAVE(MODE_CLOCK_RANGE);
79    }
80
81
82    LEAVE(MODE_OK);
83}
84
85static Bool
86SMI_OutputModeFixup(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
87{
88    ENTER();
89
90    /* Nothing */
91
92    LEAVE(TRUE);
93}
94
95static void
96SMI_OutputPrepare(xf86OutputPtr output)
97{
98    ENTER();
99
100    /* Nothing */
101
102    LEAVE();
103}
104
105static void
106SMI_OutputCommit(xf86OutputPtr output)
107{
108    ENTER();
109
110    output->funcs->dpms(output,DPMSModeOn);
111
112    LEAVE();
113}
114
115static void
116SMI_OutputModeSet(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
117{
118    ENTER();
119
120    /* Nothing */
121
122    LEAVE();
123}
124
125static xf86OutputStatus
126SMI_OutputDetect(xf86OutputPtr output)
127{
128    ENTER();
129
130    LEAVE(XF86OutputStatusUnknown);
131}
132
133xf86OutputStatus
134SMI_OutputDetect_lcd(xf86OutputPtr output)
135{
136    ENTER();
137
138    LEAVE(XF86OutputStatusConnected);
139}
140
141DisplayModePtr
142SMI_OutputGetModes_native(xf86OutputPtr output)
143{
144    SMIPtr pSmi = SMIPTR(output->scrn);
145    DisplayModePtr m;
146    ENTER();
147
148#ifdef HAVE_XMODES
149    m = xf86CVTMode(pSmi->lcdWidth, pSmi->lcdHeight, 60.0f, FALSE, FALSE);
150    xf86SetModeDefaultName(m);
151    LEAVE(m);
152#else
153    LEAVE(NULL);
154#endif
155}
156
157static void
158SMI_OutputDestroy(xf86OutputPtr output)
159{
160    ENTER();
161
162    free((xf86OutputFuncsPtr)output->funcs);
163
164    LEAVE();
165}
166
167void
168SMI_OutputFuncsInit_base(xf86OutputFuncsPtr* outputFuncs)
169{
170    *outputFuncs = xnfcalloc(sizeof(xf86OutputFuncsRec), 1);
171
172    (*outputFuncs)->create_resources = SMI_OutputCreateResources;
173    (*outputFuncs)->mode_valid = SMI_OutputModeValid;
174    (*outputFuncs)->mode_fixup = SMI_OutputModeFixup;
175    (*outputFuncs)->prepare = SMI_OutputPrepare;
176    (*outputFuncs)->commit = SMI_OutputCommit;
177    (*outputFuncs)->mode_set = SMI_OutputModeSet;
178    (*outputFuncs)->detect = SMI_OutputDetect;
179    (*outputFuncs)->destroy = SMI_OutputDestroy;
180}
181
182Bool
183SMI_OutputPreInit(ScrnInfoPtr pScrn)
184{
185    SMIPtr pSmi = SMIPTR(pScrn);
186
187    ENTER();
188
189    if(SMI_MSOC_SERIES(pSmi->Chipset)){
190	LEAVE( SMI501_OutputPreInit(pScrn) );
191    }else{
192	LEAVE( SMILynx_OutputPreInit(pScrn) );
193    }
194}
195
196