~ubuntu-branches/ubuntu/karmic/xserver-xorg-video-nouveau/karmic

« back to all changes in this revision

Viewing changes to src/nv_dac.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Lamb
  • Date: 2008-07-06 20:26:53 UTC
  • Revision ID: james.westby@ubuntu.com-20080706202653-e99oiii765j3a0qn
Tags: upstream-0.0.10~git+20080706+b1f3169
ImportĀ upstreamĀ versionĀ 0.0.10~git+20080706+b1f3169

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2003 NVIDIA, Corporation
 
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
 * THE AUTHORS 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
#include "nv_include.h"
 
24
 
 
25
static int
 
26
NVDACPanelTweaks(NVPtr pNv, NVRegPtr state)
 
27
{
 
28
   int tweak = 0;
 
29
 
 
30
   if(pNv->usePanelTweak) {
 
31
       tweak = pNv->PanelTweak;
 
32
   } else {
 
33
       /* begin flat panel hacks */
 
34
       /* This is unfortunate, but some chips need this register
 
35
          tweaked or else you get artifacts where adjacent pixels are
 
36
          swapped.  There are no hard rules for what to set here so all
 
37
          we can do is experiment and apply hacks. */
 
38
 
 
39
       if(((pNv->Chipset & 0xffff) == 0x0328) && (state->bpp == 32)) {
 
40
          /* At least one NV34 laptop needs this workaround. */
 
41
          tweak = -1;
 
42
       }
 
43
 
 
44
       if((pNv->Chipset & 0xfff0) == CHIPSET_NV31) {
 
45
          tweak = 1;
 
46
       }
 
47
       /* end flat panel hacks */
 
48
   }
 
49
 
 
50
   return tweak;
 
51
}
 
52
 
 
53
Bool
 
54
NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
 
55
{
 
56
    int i;
 
57
    int horizDisplay    = (mode->CrtcHDisplay/8)   - 1;
 
58
    int horizStart      = (mode->CrtcHSyncStart/8) - 1;
 
59
    int horizEnd        = (mode->CrtcHSyncEnd/8)   - 1;
 
60
    int horizTotal      = (mode->CrtcHTotal/8)     - 5;
 
61
    int horizBlankStart = (mode->CrtcHDisplay/8)   - 1;
 
62
    int horizBlankEnd   = (mode->CrtcHTotal/8)     - 1;
 
63
    int vertDisplay     =  mode->CrtcVDisplay      - 1;
 
64
    int vertStart       =  mode->CrtcVSyncStart    - 1;
 
65
    int vertEnd         =  mode->CrtcVSyncEnd      - 1;
 
66
    int vertTotal       =  mode->CrtcVTotal        - 2;
 
67
    int vertBlankStart  =  mode->CrtcVDisplay      - 1;
 
68
    int vertBlankEnd    =  mode->CrtcVTotal        - 1;
 
69
   
 
70
    NVPtr pNv = NVPTR(pScrn);
 
71
    NVRegPtr nvReg = &pNv->ModeReg;
 
72
    vgaRegPtr   pVga;
 
73
 
 
74
    /*
 
75
     * Initialize all of the generic VGA registers.  Don't bother with
 
76
     * VGA_FIX_SYNC_PULSES, given the relevant CRTC settings are overridden
 
77
     * below.  Ditto for the KGA workaround.
 
78
     */
 
79
    if (!vgaHWInit(pScrn, mode))
 
80
        return(FALSE);
 
81
 
 
82
    pVga = &VGAHWPTR(pScrn)->ModeReg;
 
83
 
 
84
    /*
 
85
     * Set all CRTC values.
 
86
     */
 
87
 
 
88
    if(mode->Flags & V_INTERLACE) 
 
89
        vertTotal |= 1;
 
90
 
 
91
    if(pNv->FlatPanel == 1) {
 
92
        vertStart = vertTotal - 3;  
 
93
        vertEnd = vertTotal - 2;
 
94
        vertBlankStart = vertStart;
 
95
        horizStart = horizTotal - 5;
 
96
        horizEnd = horizTotal - 2;   
 
97
        horizBlankEnd = horizTotal + 4;   
 
98
        if ( ( pNv->Architecture == NV_ARCH_40 && ((pNv->Chipset & 0xfff0) == CHIPSET_NV40) ) || pNv->Architecture == NV_ARCH_30 || pNv->Architecture == NV_ARCH_20 || pNv->Architecture == NV_ARCH_10 )        { 
 
99
                /* This reportedly works around Xv some overlay bandwidth problems*/
 
100
                horizTotal += 2;
 
101
                }
 
102
    }
 
103
 
 
104
    pVga->CRTC[0x0]  = Set8Bits(horizTotal);
 
105
    pVga->CRTC[0x1]  = Set8Bits(horizDisplay);
 
106
    pVga->CRTC[0x2]  = Set8Bits(horizBlankStart);
 
107
    pVga->CRTC[0x3]  = SetBitField(horizBlankEnd,4:0,4:0) 
 
108
                       | SetBit(7);
 
109
    pVga->CRTC[0x4]  = Set8Bits(horizStart);
 
110
    pVga->CRTC[0x5]  = SetBitField(horizBlankEnd,5:5,7:7)
 
111
                       | SetBitField(horizEnd,4:0,4:0);
 
112
    pVga->CRTC[0x6]  = SetBitField(vertTotal,7:0,7:0);
 
113
    pVga->CRTC[0x7]  = SetBitField(vertTotal,8:8,0:0)
 
114
                       | SetBitField(vertDisplay,8:8,1:1)
 
115
                       | SetBitField(vertStart,8:8,2:2)
 
116
                       | SetBitField(vertBlankStart,8:8,3:3)
 
117
                       | SetBit(4)
 
118
                       | SetBitField(vertTotal,9:9,5:5)
 
119
                       | SetBitField(vertDisplay,9:9,6:6)
 
120
                       | SetBitField(vertStart,9:9,7:7);
 
121
    pVga->CRTC[0x9]  = SetBitField(vertBlankStart,9:9,5:5)
 
122
                       | SetBit(6)
 
123
                       | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00);
 
124
    pVga->CRTC[0x10] = Set8Bits(vertStart);
 
125
    pVga->CRTC[0x11] = SetBitField(vertEnd,3:0,3:0) | SetBit(5);
 
126
    pVga->CRTC[0x12] = Set8Bits(vertDisplay);
 
127
    pVga->CRTC[0x13] = ((pScrn->displayWidth/8)*(pScrn->bitsPerPixel/8));
 
128
    pVga->CRTC[0x15] = Set8Bits(vertBlankStart);
 
129
    pVga->CRTC[0x16] = Set8Bits(vertBlankEnd);
 
130
 
 
131
    pVga->Attribute[0x10] = 0x01;
 
132
 
 
133
    if(pNv->Television)
 
134
       pVga->Attribute[0x11] = 0x00;
 
135
 
 
136
    nvReg->screen = SetBitField(horizBlankEnd,6:6,4:4)
 
137
                  | SetBitField(vertBlankStart,10:10,3:3)
 
138
                  | SetBitField(vertStart,10:10,2:2)
 
139
                  | SetBitField(vertDisplay,10:10,1:1)
 
140
                  | SetBitField(vertTotal,10:10,0:0);
 
141
 
 
142
    nvReg->horiz  = SetBitField(horizTotal,8:8,0:0) 
 
143
                  | SetBitField(horizDisplay,8:8,1:1)
 
144
                  | SetBitField(horizBlankStart,8:8,2:2)
 
145
                  | SetBitField(horizStart,8:8,3:3);
 
146
 
 
147
    nvReg->extra  = SetBitField(vertTotal,11:11,0:0)
 
148
                    | SetBitField(vertDisplay,11:11,2:2)
 
149
                    | SetBitField(vertStart,11:11,4:4)
 
150
                    | SetBitField(vertBlankStart,11:11,6:6);
 
151
 
 
152
    if(mode->Flags & V_INTERLACE) {
 
153
       horizTotal = (horizTotal >> 1) & ~1;
 
154
       nvReg->interlace = Set8Bits(horizTotal);
 
155
       nvReg->horiz |= SetBitField(horizTotal,8:8,4:4);
 
156
    } else {
 
157
       nvReg->interlace = 0xff;  /* interlace off */
 
158
    }
 
159
 
 
160
 
 
161
    /*
 
162
     * Initialize DAC palette.
 
163
     */
 
164
    if(pScrn->bitsPerPixel != 8 )
 
165
    {
 
166
        for (i = 0; i < 256; i++)
 
167
        {
 
168
            pVga->DAC[i*3]     = i;
 
169
            pVga->DAC[(i*3)+1] = i;
 
170
            pVga->DAC[(i*3)+2] = i;
 
171
        }
 
172
    }
 
173
    
 
174
    /*
 
175
     * Calculate the extended registers.
 
176
     */
 
177
 
 
178
    if (pScrn->depth < 24) 
 
179
        i = pScrn->depth;
 
180
    else i = 32;
 
181
 
 
182
    if(pNv->Architecture >= NV_ARCH_10)
 
183
        pNv->CURSOR = (CARD32 *)pNv->Cursor->map;
 
184
 
 
185
    NVCalcStateExt(pNv, 
 
186
                    nvReg,
 
187
                    i,
 
188
                    pScrn->displayWidth,
 
189
                    mode->CrtcHDisplay,
 
190
                    pScrn->virtualY,
 
191
                    mode->Clock,
 
192
                    mode->Flags);
 
193
 
 
194
    nvReg->scale = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_CONTROL) & 0xfff000ff;
 
195
    if(pNv->FlatPanel == 1) {
 
196
       nvReg->pixel |= (1 << 7);
 
197
       if(!pNv->fpScaler || (pNv->fpWidth <= mode->HDisplay)
 
198
                         || (pNv->fpHeight <= mode->VDisplay))
 
199
       {
 
200
           nvReg->scale |= (1 << 8) ;
 
201
       }
 
202
       nvReg->crtcSync = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_HCRTC);
 
203
       nvReg->crtcSync += NVDACPanelTweaks(pNv, nvReg);
 
204
    }
 
205
 
 
206
    nvReg->vpll = nvReg->pll;
 
207
    nvReg->vpll2 = nvReg->pll;
 
208
    nvReg->vpllB = nvReg->pllB;
 
209
    nvReg->vpll2B = nvReg->pllB;
 
210
 
 
211
    nvReg->fifo = nvReadCurVGA(pNv, 0x1c) & ~(1<<5);
 
212
 
 
213
    if(pNv->crtc_active[1]) {
 
214
       nvReg->head  = NVReadCRTC(pNv, 0, NV_CRTC_FSEL) & ~0x00001000;
 
215
       nvReg->head2 = NVReadCRTC(pNv, 1, NV_CRTC_FSEL) | 0x00001000;
 
216
       nvReg->crtcOwner = 3;
 
217
       nvReg->pllsel |= 0x20000800;
 
218
       nvReg->vpll = NVReadRAMDAC(pNv, 0, NV_RAMDAC_VPLL);
 
219
       if(pNv->twoStagePLL) 
 
220
          nvReg->vpllB = NVReadRAMDAC(pNv, 0, NV_RAMDAC_VPLL_B);
 
221
    } else if(pNv->twoHeads) {
 
222
       nvReg->head  =  NVReadCRTC(pNv, 0, NV_CRTC_FSEL) | 0x00001000;
 
223
       nvReg->head2 =  NVReadCRTC(pNv, 1, NV_CRTC_FSEL) & ~0x00001000;
 
224
       nvReg->crtcOwner = 0;
 
225
       nvReg->vpll2 = NVReadRAMDAC(pNv, 0, NV_RAMDAC_VPLL2);
 
226
       if(pNv->twoStagePLL) 
 
227
          nvReg->vpll2B = NVReadRAMDAC(pNv, 0, NV_RAMDAC_VPLL2_B);
 
228
    }
 
229
 
 
230
    nvReg->cursorConfig = 0x00000100;
 
231
    if(mode->Flags & V_DBLSCAN)
 
232
       nvReg->cursorConfig |= (1 << 4);
 
233
    if(pNv->alphaCursor) {
 
234
        if((pNv->Chipset & 0x0ff0) != CHIPSET_NV11) 
 
235
           nvReg->cursorConfig |= 0x04011000;
 
236
        else
 
237
           nvReg->cursorConfig |= 0x14011000;
 
238
        nvReg->general |= (1 << 29);
 
239
    } else
 
240
       nvReg->cursorConfig |= 0x02000000;
 
241
 
 
242
    if(pNv->twoHeads) {
 
243
        if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
 
244
           nvReg->dither = nvReadCurRAMDAC(pNv, NV_RAMDAC_DITHER_NV11) & ~0x00010000;
 
245
           if(pNv->FPDither)
 
246
              nvReg->dither |= 0x00010000;
 
247
        } else {
 
248
           nvReg->dither = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_DITHER) & ~1;
 
249
           if(pNv->FPDither)
 
250
              nvReg->dither |= 1;
 
251
        } 
 
252
    }
 
253
 
 
254
    nvReg->timingH = 0;
 
255
    nvReg->timingV = 0;
 
256
    nvReg->displayV = mode->CrtcVDisplay;
 
257
 
 
258
    return (TRUE);
 
259
}
 
260
 
 
261
void 
 
262
NVDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, NVRegPtr nvReg,
 
263
             Bool primary)
 
264
{
 
265
    int restore = VGA_SR_MODE;
 
266
 
 
267
    if(primary) restore |= VGA_SR_CMAP | VGA_SR_FONTS;
 
268
    NVLoadStateExt(pScrn, nvReg);
 
269
#if defined(__powerpc__)
 
270
    restore &= ~VGA_SR_FONTS;
 
271
#endif
 
272
    vgaHWRestore(pScrn, vgaReg, restore);
 
273
}
 
274
 
 
275
/*
 
276
 * NVDACSave
 
277
 *
 
278
 * This function saves the video state.
 
279
 */
 
280
void
 
281
NVDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, NVRegPtr nvReg,
 
282
          Bool saveFonts)
 
283
{
 
284
    NVPtr pNv = NVPTR(pScrn);
 
285
 
 
286
#if defined(__powerpc__)
 
287
    saveFonts = FALSE;
 
288
#endif
 
289
 
 
290
    vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE | 
 
291
                             (saveFonts? VGA_SR_FONTS : 0));
 
292
    NVUnloadStateExt(pNv, nvReg);
 
293
 
 
294
        /* can't read this reliably on NV11 */
 
295
        if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
 
296
                /* 0 if inactive -> crtc0 is active, otherwise 1 */
 
297
                nvReg->crtcOwner = pNv->crtc_active[1];
 
298
        }
 
299
}
 
300
 
 
301
#define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8)))
 
302
#define MAKE_INDEX(in, w) (DEPTH_SHIFT(in, w) * 3)
 
303
 
 
304
void
 
305
NVDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
 
306
                 VisualPtr pVisual )
 
307
{
 
308
    int i, index;
 
309
    vgaRegPtr pVga = &VGAHWPTR(pScrn)->ModeReg;
 
310
 
 
311
    switch(pScrn->depth) {
 
312
    case 15:
 
313
        for(i = 0; i < numColors; i++) {
 
314
            index = indices[i];
 
315
            pVga->DAC[MAKE_INDEX(index, 5) + 0] = colors[index].red;
 
316
            pVga->DAC[MAKE_INDEX(index, 5) + 1] = colors[index].green;
 
317
            pVga->DAC[MAKE_INDEX(index, 5) + 2] = colors[index].blue;
 
318
        }
 
319
        break;
 
320
    case 16:
 
321
        for(i = 0; i < numColors; i++) {
 
322
            index = indices[i];
 
323
            pVga->DAC[MAKE_INDEX(index, 6) + 1] = colors[index].green;
 
324
            if(index < 32) {
 
325
                pVga->DAC[MAKE_INDEX(index, 5) + 0] = colors[index].red;
 
326
                pVga->DAC[MAKE_INDEX(index, 5) + 2] = colors[index].blue;
 
327
            }
 
328
        }
 
329
        break;
 
330
    default:
 
331
        for(i = 0; i < numColors; i++) {
 
332
            index = indices[i];
 
333
            pVga->DAC[index*3]     = colors[index].red;
 
334
            pVga->DAC[(index*3)+1] = colors[index].green;
 
335
            pVga->DAC[(index*3)+2] = colors[index].blue;
 
336
        }
 
337
        break;
 
338
    }
 
339
    vgaHWRestore(pScrn, pVga, VGA_SR_CMAP);
 
340
}
 
341
 
 
342
/*
 
343
 * DDC1 support only requires DDC_SDA_MASK,
 
344
 * DDC2 support requires DDC_SDA_MASK and DDC_SCL_MASK
 
345
 */
 
346
#define DDC_SDA_READ_MASK  (1 << 3)
 
347
#define DDC_SCL_READ_MASK  (1 << 2)
 
348
#define DDC_SDA_WRITE_MASK (1 << 4)
 
349
#define DDC_SCL_WRITE_MASK (1 << 5)
 
350
 
 
351
static void
 
352
NV_I2CGetBits(I2CBusPtr b, int *clock, int *data)
 
353
{
 
354
    NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
 
355
    unsigned char val;
 
356
 
 
357
    /* Get the result. */
 
358
    val = nvReadCurVGA(pNv, pNv->DDCBase);
 
359
 
 
360
    *clock = (val & DDC_SCL_READ_MASK) != 0;
 
361
    *data  = (val & DDC_SDA_READ_MASK) != 0;
 
362
}
 
363
 
 
364
static void
 
365
NV_I2CPutBits(I2CBusPtr b, int clock, int data)
 
366
{
 
367
    NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
 
368
    unsigned char val;
 
369
 
 
370
    val = nvReadCurVGA(pNv, pNv->DDCBase + 1) & 0xf0;
 
371
    if (clock)
 
372
        val |= DDC_SCL_WRITE_MASK;
 
373
    else
 
374
        val &= ~DDC_SCL_WRITE_MASK;
 
375
 
 
376
    if (data)
 
377
        val |= DDC_SDA_WRITE_MASK;
 
378
    else
 
379
        val &= ~DDC_SDA_WRITE_MASK;
 
380
 
 
381
    nvWriteCurVGA(pNv, pNv->DDCBase + 1, val | 0x1);
 
382
}
 
383
 
 
384
Bool
 
385
NVDACi2cInit(ScrnInfoPtr pScrn)
 
386
{
 
387
    NVPtr pNv = NVPTR(pScrn);
 
388
    I2CBusPtr I2CPtr;
 
389
 
 
390
    I2CPtr = xf86CreateI2CBusRec();
 
391
    if(!I2CPtr) return FALSE;
 
392
 
 
393
    pNv->I2C = I2CPtr;
 
394
 
 
395
    I2CPtr->BusName    = "DDC";
 
396
    I2CPtr->scrnIndex  = pScrn->scrnIndex;
 
397
    I2CPtr->I2CPutBits = NV_I2CPutBits;
 
398
    I2CPtr->I2CGetBits = NV_I2CGetBits;
 
399
    I2CPtr->AcknTimeout = 5;
 
400
 
 
401
    if (!xf86I2CBusInit(I2CPtr)) {
 
402
        return FALSE;
 
403
    }
 
404
    return TRUE;
 
405
}
 
406