1 /***************************************************************************\
3 |* Copyright 2003 NVIDIA, Corporation. All rights reserved. *|
5 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
6 |* international laws. Users and possessors of this source code are *|
7 |* hereby granted a nonexclusive, royalty-free copyright license to *|
8 |* use this code in individual and commercial software. *|
10 |* Any use of this source code must include, in the user documenta- *|
11 |* tion and internal comments to the code, notices to the end user *|
14 |* Copyright 2003 NVIDIA, Corporation. All rights reserved. *|
16 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
17 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
18 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
19 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
20 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
21 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
22 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
23 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
24 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
25 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
26 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
28 |* U.S. Government End Users. This source code is a "commercial *|
29 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
30 |* consisting of "commercial computer software" and "commercial *|
31 |* computer software documentation," as such terms are used in *|
32 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
33 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
34 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
35 |* all U.S. Government End Users acquire the source code with only *|
36 |* those rights set forth herein. *|
38 \***************************************************************************/
40 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c,v 1.45 2005/07/09 00:53:00 mvojkovi Exp $ */
42 #include "nv_include.h"
45 NVDACPanelTweaks(NVPtr pNv, NVRegPtr state)
49 if(pNv->usePanelTweak) {
50 tweak = pNv->PanelTweak;
52 /* begin flat panel hacks */
53 /* This is unfortunate, but some chips need this register
54 tweaked or else you get artifacts where adjacent pixels are
55 swapped. There are no hard rules for what to set here so all
56 we can do is experiment and apply hacks. */
58 if(((pNv->Chipset & 0xffff) == 0x0328) && (state->bpp == 32)) {
59 /* At least one NV34 laptop needs this workaround. */
63 if((pNv->Chipset & 0xfff0) == CHIPSET_NV31) {
66 /* end flat panel hacks */
73 NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
76 int horizDisplay = (mode->CrtcHDisplay/8) - 1;
77 int horizStart = (mode->CrtcHSyncStart/8) - 1;
78 int horizEnd = (mode->CrtcHSyncEnd/8) - 1;
79 int horizTotal = (mode->CrtcHTotal/8) - 5;
80 int horizBlankStart = (mode->CrtcHDisplay/8) - 1;
81 int horizBlankEnd = (mode->CrtcHTotal/8) - 1;
82 int vertDisplay = mode->CrtcVDisplay - 1;
83 int vertStart = mode->CrtcVSyncStart - 1;
84 int vertEnd = mode->CrtcVSyncEnd - 1;
85 int vertTotal = mode->CrtcVTotal - 2;
86 int vertBlankStart = mode->CrtcVDisplay - 1;
87 int vertBlankEnd = mode->CrtcVTotal - 1;
89 NVPtr pNv = NVPTR(pScrn);
90 NVRegPtr nvReg = &pNv->ModeReg;
94 * Initialize all of the generic VGA registers. Don't bother with
95 * VGA_FIX_SYNC_PULSES, given the relevant CRTC settings are overridden
96 * below. Ditto for the KGA workaround.
98 if (!vgaHWInit(pScrn, mode))
101 pVga = &VGAHWPTR(pScrn)->ModeReg;
104 * Set all CRTC values.
107 if(mode->Flags & V_INTERLACE)
110 if(pNv->FlatPanel == 1) {
111 vertStart = vertTotal - 3;
112 vertEnd = vertTotal - 2;
113 vertBlankStart = vertStart;
114 horizStart = horizTotal - 5;
115 horizEnd = horizTotal - 2;
116 horizBlankEnd = horizTotal + 4;
117 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 ) {
118 /* This reportedly works around Xv some overlay bandwidth problems*/
123 pVga->CRTC[0x0] = Set8Bits(horizTotal);
124 pVga->CRTC[0x1] = Set8Bits(horizDisplay);
125 pVga->CRTC[0x2] = Set8Bits(horizBlankStart);
126 pVga->CRTC[0x3] = SetBitField(horizBlankEnd,4:0,4:0)
128 pVga->CRTC[0x4] = Set8Bits(horizStart);
129 pVga->CRTC[0x5] = SetBitField(horizBlankEnd,5:5,7:7)
130 | SetBitField(horizEnd,4:0,4:0);
131 pVga->CRTC[0x6] = SetBitField(vertTotal,7:0,7:0);
132 pVga->CRTC[0x7] = SetBitField(vertTotal,8:8,0:0)
133 | SetBitField(vertDisplay,8:8,1:1)
134 | SetBitField(vertStart,8:8,2:2)
135 | SetBitField(vertBlankStart,8:8,3:3)
137 | SetBitField(vertTotal,9:9,5:5)
138 | SetBitField(vertDisplay,9:9,6:6)
139 | SetBitField(vertStart,9:9,7:7);
140 pVga->CRTC[0x9] = SetBitField(vertBlankStart,9:9,5:5)
142 | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00);
143 pVga->CRTC[0x10] = Set8Bits(vertStart);
144 pVga->CRTC[0x11] = SetBitField(vertEnd,3:0,3:0) | SetBit(5);
145 pVga->CRTC[0x12] = Set8Bits(vertDisplay);
146 pVga->CRTC[0x13] = ((pScrn->displayWidth/8)*(pScrn->bitsPerPixel/8));
147 pVga->CRTC[0x15] = Set8Bits(vertBlankStart);
148 pVga->CRTC[0x16] = Set8Bits(vertBlankEnd);
150 pVga->Attribute[0x10] = 0x01;
153 pVga->Attribute[0x11] = 0x00;
155 nvReg->screen = SetBitField(horizBlankEnd,6:6,4:4)
156 | SetBitField(vertBlankStart,10:10,3:3)
157 | SetBitField(vertStart,10:10,2:2)
158 | SetBitField(vertDisplay,10:10,1:1)
159 | SetBitField(vertTotal,10:10,0:0);
161 nvReg->horiz = SetBitField(horizTotal,8:8,0:0)
162 | SetBitField(horizDisplay,8:8,1:1)
163 | SetBitField(horizBlankStart,8:8,2:2)
164 | SetBitField(horizStart,8:8,3:3);
166 nvReg->extra = SetBitField(vertTotal,11:11,0:0)
167 | SetBitField(vertDisplay,11:11,2:2)
168 | SetBitField(vertStart,11:11,4:4)
169 | SetBitField(vertBlankStart,11:11,6:6);
171 if(mode->Flags & V_INTERLACE) {
172 horizTotal = (horizTotal >> 1) & ~1;
173 nvReg->interlace = Set8Bits(horizTotal);
174 nvReg->horiz |= SetBitField(horizTotal,8:8,4:4);
176 nvReg->interlace = 0xff; /* interlace off */
181 * Initialize DAC palette.
183 if(pScrn->bitsPerPixel != 8 )
185 for (i = 0; i < 256; i++)
188 pVga->DAC[(i*3)+1] = i;
189 pVga->DAC[(i*3)+2] = i;
194 * Calculate the extended registers.
197 if (pScrn->depth < 24)
201 if(pNv->Architecture >= NV_ARCH_10)
202 pNv->CURSOR = (CARD32 *)pNv->Cursor->map;
213 nvReg->scale = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_CONTROL) & 0xfff000ff;
214 if(pNv->FlatPanel == 1) {
215 nvReg->pixel |= (1 << 7);
216 if(!pNv->fpScaler || (pNv->fpWidth <= mode->HDisplay)
217 || (pNv->fpHeight <= mode->VDisplay))
219 nvReg->scale |= (1 << 8) ;
221 nvReg->crtcSync = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_HCRTC);
222 nvReg->crtcSync += NVDACPanelTweaks(pNv, nvReg);
225 nvReg->vpll = nvReg->pll;
226 nvReg->vpll2 = nvReg->pll;
227 nvReg->vpllB = nvReg->pllB;
228 nvReg->vpll2B = nvReg->pllB;
230 nvReg->fifo = nvReadCurVGA(pNv, 0x1c) & ~(1<<5);
232 if(pNv->crtc_active[1]) {
233 nvReg->head = NVReadCRTC(pNv, 0, NV_CRTC_FSEL) & ~0x00001000;
234 nvReg->head2 = NVReadCRTC(pNv, 1, NV_CRTC_FSEL) | 0x00001000;
235 nvReg->crtcOwner = 3;
236 nvReg->pllsel |= 0x20000800;
237 nvReg->vpll = NVReadRAMDAC(pNv, 0, NV_RAMDAC_VPLL);
239 nvReg->vpllB = NVReadRAMDAC(pNv, 0, NV_RAMDAC_VPLL_B);
240 } else if(pNv->twoHeads) {
241 nvReg->head = NVReadCRTC(pNv, 0, NV_CRTC_FSEL) | 0x00001000;
242 nvReg->head2 = NVReadCRTC(pNv, 1, NV_CRTC_FSEL) & ~0x00001000;
243 nvReg->crtcOwner = 0;
244 nvReg->vpll2 = NVReadRAMDAC(pNv, 0, NV_RAMDAC_VPLL2);
246 nvReg->vpll2B = NVReadRAMDAC(pNv, 0, NV_RAMDAC_VPLL2_B);
249 nvReg->cursorConfig = 0x00000100;
250 if(mode->Flags & V_DBLSCAN)
251 nvReg->cursorConfig |= (1 << 4);
252 if(pNv->alphaCursor) {
253 if((pNv->Chipset & 0x0ff0) != CHIPSET_NV11)
254 nvReg->cursorConfig |= 0x04011000;
256 nvReg->cursorConfig |= 0x14011000;
257 nvReg->general |= (1 << 29);
259 nvReg->cursorConfig |= 0x02000000;
262 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
263 nvReg->dither = nvReadCurRAMDAC(pNv, NV_RAMDAC_DITHER_NV11) & ~0x00010000;
265 nvReg->dither |= 0x00010000;
267 nvReg->dither = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_DITHER) & ~1;
275 nvReg->displayV = mode->CrtcVDisplay;
281 NVDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, NVRegPtr nvReg,
284 int restore = VGA_SR_MODE;
286 if(primary) restore |= VGA_SR_CMAP | VGA_SR_FONTS;
287 NVLoadStateExt(pScrn, nvReg);
288 #if defined(__powerpc__)
289 restore &= ~VGA_SR_FONTS;
291 vgaHWRestore(pScrn, vgaReg, restore);
297 * This function saves the video state.
300 NVDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, NVRegPtr nvReg,
303 NVPtr pNv = NVPTR(pScrn);
305 #if defined(__powerpc__)
309 vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE |
310 (saveFonts? VGA_SR_FONTS : 0));
311 NVUnloadStateExt(pNv, nvReg);
313 /* can't read this reliably on NV11 */
314 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
315 /* 0 if inactive -> crtc0 is active, otherwise 1 */
316 nvReg->crtcOwner = pNv->crtc_active[1];
320 #define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8)))
321 #define MAKE_INDEX(in, w) (DEPTH_SHIFT(in, w) * 3)
324 NVDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
328 vgaRegPtr pVga = &VGAHWPTR(pScrn)->ModeReg;
330 switch(pScrn->depth) {
332 for(i = 0; i < numColors; i++) {
334 pVga->DAC[MAKE_INDEX(index, 5) + 0] = colors[index].red;
335 pVga->DAC[MAKE_INDEX(index, 5) + 1] = colors[index].green;
336 pVga->DAC[MAKE_INDEX(index, 5) + 2] = colors[index].blue;
340 for(i = 0; i < numColors; i++) {
342 pVga->DAC[MAKE_INDEX(index, 6) + 1] = colors[index].green;
344 pVga->DAC[MAKE_INDEX(index, 5) + 0] = colors[index].red;
345 pVga->DAC[MAKE_INDEX(index, 5) + 2] = colors[index].blue;
350 for(i = 0; i < numColors; i++) {
352 pVga->DAC[index*3] = colors[index].red;
353 pVga->DAC[(index*3)+1] = colors[index].green;
354 pVga->DAC[(index*3)+2] = colors[index].blue;
358 vgaHWRestore(pScrn, pVga, VGA_SR_CMAP);
362 * DDC1 support only requires DDC_SDA_MASK,
363 * DDC2 support requires DDC_SDA_MASK and DDC_SCL_MASK
365 #define DDC_SDA_READ_MASK (1 << 3)
366 #define DDC_SCL_READ_MASK (1 << 2)
367 #define DDC_SDA_WRITE_MASK (1 << 4)
368 #define DDC_SCL_WRITE_MASK (1 << 5)
371 NV_I2CGetBits(I2CBusPtr b, int *clock, int *data)
373 NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
376 /* Get the result. */
377 val = nvReadCurVGA(pNv, pNv->DDCBase);
379 *clock = (val & DDC_SCL_READ_MASK) != 0;
380 *data = (val & DDC_SDA_READ_MASK) != 0;
384 NV_I2CPutBits(I2CBusPtr b, int clock, int data)
386 NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
389 val = nvReadCurVGA(pNv, pNv->DDCBase + 1) & 0xf0;
391 val |= DDC_SCL_WRITE_MASK;
393 val &= ~DDC_SCL_WRITE_MASK;
396 val |= DDC_SDA_WRITE_MASK;
398 val &= ~DDC_SDA_WRITE_MASK;
400 nvWriteCurVGA(pNv, pNv->DDCBase + 1, val | 0x1);
404 NVDACi2cInit(ScrnInfoPtr pScrn)
406 NVPtr pNv = NVPTR(pScrn);
409 I2CPtr = xf86CreateI2CBusRec();
410 if(!I2CPtr) return FALSE;
414 I2CPtr->BusName = "DDC";
415 I2CPtr->scrnIndex = pScrn->scrnIndex;
416 I2CPtr->I2CPutBits = NV_I2CPutBits;
417 I2CPtr->I2CGetBits = NV_I2CGetBits;
418 I2CPtr->AcknTimeout = 5;
420 if (!xf86I2CBusInit(I2CPtr)) {