Replace panel message + MODE_BAD with MODE_PANEL.
[nouveau] / src / riva_dac.c
1 /*
2  * Copyright 1996-1997  David J. McKay
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22
23 /* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen
24    <jpaana@s2.org> */
25
26 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_dac.c,v 1.1 2003/07/31 20:24:29 mvojkovi Exp $ */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include "riva_include.h"
33
34 Bool
35 RivaDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
36 {
37     int i;
38     int horizDisplay    = (mode->CrtcHDisplay/8)   - 1;
39     int horizStart      = (mode->CrtcHSyncStart/8) - 1;
40     int horizEnd        = (mode->CrtcHSyncEnd/8)   - 1;
41     int horizTotal      = (mode->CrtcHTotal/8)     - 5;
42     int horizBlankStart = (mode->CrtcHDisplay/8)   - 1;
43     int horizBlankEnd   = (mode->CrtcHTotal/8)     - 1;
44     int vertDisplay     =  mode->CrtcVDisplay      - 1;
45     int vertStart       =  mode->CrtcVSyncStart    - 1;
46     int vertEnd         =  mode->CrtcVSyncEnd      - 1;
47     int vertTotal       =  mode->CrtcVTotal        - 2;
48     int vertBlankStart  =  mode->CrtcVDisplay      - 1;
49     int vertBlankEnd    =  mode->CrtcVTotal        - 1;
50    
51
52     RivaPtr pRiva = RivaPTR(pScrn);
53     RivaRegPtr rivaReg = &pRiva->ModeReg;
54     RivaFBLayout *pLayout = &pRiva->CurrentLayout;
55     vgaRegPtr   pVga;
56
57     /*
58      * This will initialize all of the generic VGA registers.
59      */
60     if (!vgaHWInit(pScrn, mode))
61         return(FALSE);
62
63     pVga = &VGAHWPTR(pScrn)->ModeReg;
64
65     /*
66      * Set all CRTC values.
67      */
68
69     if(mode->Flags & V_INTERLACE) 
70         vertTotal |= 1;
71
72     pVga->CRTC[0x0]  = Set8Bits(horizTotal);
73     pVga->CRTC[0x1]  = Set8Bits(horizDisplay);
74     pVga->CRTC[0x2]  = Set8Bits(horizBlankStart);
75     pVga->CRTC[0x3]  = SetBitField(horizBlankEnd,4:0,4:0) 
76                        | SetBit(7);
77     pVga->CRTC[0x4]  = Set8Bits(horizStart);
78     pVga->CRTC[0x5]  = SetBitField(horizBlankEnd,5:5,7:7)
79                        | SetBitField(horizEnd,4:0,4:0);
80     pVga->CRTC[0x6]  = SetBitField(vertTotal,7:0,7:0);
81     pVga->CRTC[0x7]  = SetBitField(vertTotal,8:8,0:0)
82                        | SetBitField(vertDisplay,8:8,1:1)
83                        | SetBitField(vertStart,8:8,2:2)
84                        | SetBitField(vertBlankStart,8:8,3:3)
85                        | SetBit(4)
86                        | SetBitField(vertTotal,9:9,5:5)
87                        | SetBitField(vertDisplay,9:9,6:6)
88                        | SetBitField(vertStart,9:9,7:7);
89     pVga->CRTC[0x9]  = SetBitField(vertBlankStart,9:9,5:5)
90                        | SetBit(6)
91                        | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00);
92     pVga->CRTC[0x10] = Set8Bits(vertStart);
93     pVga->CRTC[0x11] = SetBitField(vertEnd,3:0,3:0) | SetBit(5);
94     pVga->CRTC[0x12] = Set8Bits(vertDisplay);
95     pVga->CRTC[0x13] = ((pLayout->displayWidth/8)*(pLayout->bitsPerPixel/8));
96     pVga->CRTC[0x15] = Set8Bits(vertBlankStart);
97     pVga->CRTC[0x16] = Set8Bits(vertBlankEnd);
98
99     pVga->Attribute[0x10] = 0x01;
100
101     rivaReg->screen = SetBitField(horizBlankEnd,6:6,4:4)
102                   | SetBitField(vertBlankStart,10:10,3:3)
103                   | SetBitField(vertStart,10:10,2:2)
104                   | SetBitField(vertDisplay,10:10,1:1)
105                   | SetBitField(vertTotal,10:10,0:0);
106
107     rivaReg->horiz  = SetBitField(horizTotal,8:8,0:0) 
108                   | SetBitField(horizDisplay,8:8,1:1)
109                   | SetBitField(horizBlankStart,8:8,2:2)
110                   | SetBitField(horizStart,8:8,3:3);
111
112     rivaReg->extra  = SetBitField(vertTotal,11:11,0:0)
113                     | SetBitField(vertDisplay,11:11,2:2)
114                     | SetBitField(vertStart,11:11,4:4)
115                     | SetBitField(vertBlankStart,11:11,6:6);
116
117     if(mode->Flags & V_INTERLACE) {
118        horizTotal = (horizTotal >> 1) & ~1;
119        rivaReg->interlace = Set8Bits(horizTotal);
120        rivaReg->horiz |= SetBitField(horizTotal,8:8,4:4);
121     } else {
122        rivaReg->interlace = 0xff;  /* interlace off */
123     }
124
125     /*
126      * Initialize DAC palette.
127      */
128     if(pLayout->bitsPerPixel != 8 )
129     {
130         for (i = 0; i < 256; i++)
131         {
132             pVga->DAC[i*3]     = i;
133             pVga->DAC[(i*3)+1] = i;
134             pVga->DAC[(i*3)+2] = i;
135         }
136     }
137     
138     /*
139      * Calculate the extended registers.
140      */
141
142     if(pLayout->depth < 24) 
143         i = pLayout->depth;
144     else i = 32;
145
146     pRiva->riva.CalcStateExt(&pRiva->riva, 
147                            rivaReg,
148                            i,
149                            pLayout->displayWidth,
150                            mode->CrtcHDisplay,
151                            pScrn->virtualY,
152                            mode->Clock,
153                            mode->Flags);
154
155     rivaReg->cursorConfig = 0x02000100;
156     if(mode->Flags & V_DBLSCAN)
157        rivaReg->cursorConfig |= (1 << 4);
158
159     return (TRUE);
160 }
161
162 void 
163 RivaDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, RivaRegPtr rivaReg,
164              Bool primary)
165 {
166     RivaPtr pRiva = RivaPTR(pScrn);
167     int restore = VGA_SR_MODE;
168
169     restore |= primary ? (VGA_SR_CMAP | VGA_SR_FONTS) : VGA_SR_CMAP;
170     pRiva->riva.LoadStateExt(&pRiva->riva, rivaReg);
171     vgaHWRestore(pScrn, vgaReg, restore);
172 }
173
174 /*
175  * RivaDACSave
176  *
177  * This function saves the video state.
178  */
179 void
180 RivaDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, RivaRegPtr rivaReg,
181           Bool saveFonts)
182 {
183     RivaPtr pRiva = RivaPTR(pScrn);
184
185     pRiva->riva.LockUnlock(&pRiva->riva, 0);
186
187     vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE | 
188                              (saveFonts? VGA_SR_FONTS : 0));
189     pRiva->riva.UnloadStateExt(&pRiva->riva, rivaReg);
190 }
191
192 #define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8)))
193 #define MAKE_INDEX(in, w) (DEPTH_SHIFT(in, w) * 3)
194
195 void
196 RivaDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
197                  VisualPtr pVisual )
198 {
199     int i, index;
200     RivaPtr pRiva = RivaPTR(pScrn);
201     vgaRegPtr   pVga;
202
203     pVga = &VGAHWPTR(pScrn)->ModeReg;
204
205     if(pRiva->CurrentLayout.depth != 8)
206            return;
207
208     for(i = 0; i < numColors; i++) {
209         index = indices[i];
210         pVga->DAC[index*3]     = colors[index].red;
211         pVga->DAC[(index*3)+1] = colors[index].green;
212         pVga->DAC[(index*3)+2] = colors[index].blue;
213     }
214     vgaHWRestore(pScrn, pVga, VGA_SR_CMAP);
215 }
216
217 /*
218  * DDC1 support only requires DDC_SDA_MASK,
219  * DDC2 support requires DDC_SDA_MASK and DDC_SCL_MASK
220  */
221 #define DDC_SDA_READ_MASK  (1 << 3)
222 #define DDC_SCL_READ_MASK  (1 << 2)
223 #define DDC_SDA_WRITE_MASK (1 << 4)
224 #define DDC_SCL_WRITE_MASK (1 << 5)
225
226 static void
227 Riva_I2CGetBits(I2CBusPtr b, int *clock, int *data)
228 {
229     RivaPtr pRiva = RivaPTR(xf86Screens[b->scrnIndex]);
230     unsigned char val;
231
232     /* Get the result. */
233     VGA_WR08(pRiva->riva.PCIO, 0x3d4, pRiva->DDCBase);
234     val = VGA_RD08(pRiva->riva.PCIO, 0x3d5);
235
236     *clock = (val & DDC_SCL_READ_MASK) != 0;
237     *data  = (val & DDC_SDA_READ_MASK) != 0;
238 }
239
240 static void
241 Riva_I2CPutBits(I2CBusPtr b, int clock, int data)
242 {
243     RivaPtr pRiva = RivaPTR(xf86Screens[b->scrnIndex]);
244     unsigned char val;
245
246     VGA_WR08(pRiva->riva.PCIO, 0x3d4, pRiva->DDCBase + 1);
247     val = VGA_RD08(pRiva->riva.PCIO, 0x3d5) & 0xf0;
248     if (clock)
249         val |= DDC_SCL_WRITE_MASK;
250     else
251         val &= ~DDC_SCL_WRITE_MASK;
252
253     if (data)
254         val |= DDC_SDA_WRITE_MASK;
255     else
256         val &= ~DDC_SDA_WRITE_MASK;
257
258     VGA_WR08(pRiva->riva.PCIO, 0x3d4, pRiva->DDCBase + 1);
259     VGA_WR08(pRiva->riva.PCIO, 0x3d5, val | 0x1);
260 }
261
262 Bool
263 RivaDACi2cInit(ScrnInfoPtr pScrn)
264 {
265     RivaPtr pRiva = RivaPTR(pScrn);
266     I2CBusPtr I2CPtr;
267
268     I2CPtr = xf86CreateI2CBusRec();
269     if(!I2CPtr) return FALSE;
270
271     pRiva->I2C = I2CPtr;
272
273     I2CPtr->BusName    = "DDC";
274     I2CPtr->scrnIndex  = pScrn->scrnIndex;
275     I2CPtr->I2CPutBits = Riva_I2CPutBits;
276     I2CPtr->I2CGetBits = Riva_I2CGetBits;
277     I2CPtr->AcknTimeout = 5;
278
279     if (!xf86I2CBusInit(I2CPtr)) {
280         return FALSE;
281     }
282     return TRUE;
283 }
284