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;
91 NVFBLayout *pLayout = &pNv->CurrentLayout;
95 * Initialize all of the generic VGA registers. Don't bother with
96 * VGA_FIX_SYNC_PULSES, given the relevant CRTC settings are overridden
97 * below. Ditto for the KGA workaround.
99 if (!vgaHWInit(pScrn, mode))
102 pVga = &VGAHWPTR(pScrn)->ModeReg;
105 * Set all CRTC values.
108 if(mode->Flags & V_INTERLACE)
111 if(pNv->FlatPanel == 1) {
112 vertStart = vertTotal - 3;
113 vertEnd = vertTotal - 2;
114 vertBlankStart = vertStart;
115 horizStart = horizTotal - 5;
116 horizEnd = horizTotal - 2;
117 horizBlankEnd = horizTotal + 4;
118 if ( pNv->Architecture == NV_ARCH_30 || pNv->Architecture == NV_ARCH_20 || pNv->Architecture == NV_ARCH_10 ) {
119 /* This reportedly works around Xv some overlay bandwidth problems*/
124 pVga->CRTC[0x0] = Set8Bits(horizTotal);
125 pVga->CRTC[0x1] = Set8Bits(horizDisplay);
126 pVga->CRTC[0x2] = Set8Bits(horizBlankStart);
127 pVga->CRTC[0x3] = SetBitField(horizBlankEnd,4:0,4:0)
129 pVga->CRTC[0x4] = Set8Bits(horizStart);
130 pVga->CRTC[0x5] = SetBitField(horizBlankEnd,5:5,7:7)
131 | SetBitField(horizEnd,4:0,4:0);
132 pVga->CRTC[0x6] = SetBitField(vertTotal,7:0,7:0);
133 pVga->CRTC[0x7] = SetBitField(vertTotal,8:8,0:0)
134 | SetBitField(vertDisplay,8:8,1:1)
135 | SetBitField(vertStart,8:8,2:2)
136 | SetBitField(vertBlankStart,8:8,3:3)
138 | SetBitField(vertTotal,9:9,5:5)
139 | SetBitField(vertDisplay,9:9,6:6)
140 | SetBitField(vertStart,9:9,7:7);
141 pVga->CRTC[0x9] = SetBitField(vertBlankStart,9:9,5:5)
143 | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00);
144 pVga->CRTC[0x10] = Set8Bits(vertStart);
145 pVga->CRTC[0x11] = SetBitField(vertEnd,3:0,3:0) | SetBit(5);
146 pVga->CRTC[0x12] = Set8Bits(vertDisplay);
147 pVga->CRTC[0x13] = ((pLayout->displayWidth/8)*(pLayout->bitsPerPixel/8));
148 pVga->CRTC[0x15] = Set8Bits(vertBlankStart);
149 pVga->CRTC[0x16] = Set8Bits(vertBlankEnd);
151 pVga->Attribute[0x10] = 0x01;
154 pVga->Attribute[0x11] = 0x00;
156 nvReg->screen = SetBitField(horizBlankEnd,6:6,4:4)
157 | SetBitField(vertBlankStart,10:10,3:3)
158 | SetBitField(vertStart,10:10,2:2)
159 | SetBitField(vertDisplay,10:10,1:1)
160 | SetBitField(vertTotal,10:10,0:0);
162 nvReg->horiz = SetBitField(horizTotal,8:8,0:0)
163 | SetBitField(horizDisplay,8:8,1:1)
164 | SetBitField(horizBlankStart,8:8,2:2)
165 | SetBitField(horizStart,8:8,3:3);
167 nvReg->extra = SetBitField(vertTotal,11:11,0:0)
168 | SetBitField(vertDisplay,11:11,2:2)
169 | SetBitField(vertStart,11:11,4:4)
170 | SetBitField(vertBlankStart,11:11,6:6);
172 if(mode->Flags & V_INTERLACE) {
173 horizTotal = (horizTotal >> 1) & ~1;
174 nvReg->interlace = Set8Bits(horizTotal);
175 nvReg->horiz |= SetBitField(horizTotal,8:8,4:4);
177 nvReg->interlace = 0xff; /* interlace off */
182 * Initialize DAC palette.
184 if(pLayout->bitsPerPixel != 8 )
186 for (i = 0; i < 256; i++)
189 pVga->DAC[(i*3)+1] = i;
190 pVga->DAC[(i*3)+2] = i;
195 * Calculate the extended registers.
198 if(pLayout->depth < 24)
202 if(pNv->Architecture >= NV_ARCH_10)
203 pNv->CURSOR = (CARD32 *)pNv->Cursor->map;
208 pLayout->displayWidth,
214 nvReg->scale = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_CONTROL) & 0xfff000ff;
215 if(pNv->FlatPanel == 1) {
216 nvReg->pixel |= (1 << 7);
217 if(!pNv->fpScaler || (pNv->fpWidth <= mode->HDisplay)
218 || (pNv->fpHeight <= mode->VDisplay))
220 nvReg->scale |= (1 << 8) ;
222 nvReg->crtcSync = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_HCRTC);
223 nvReg->crtcSync += NVDACPanelTweaks(pNv, nvReg);
226 nvReg->vpll = nvReg->pll;
227 nvReg->vpll2 = nvReg->pll;
228 nvReg->vpllB = nvReg->pllB;
229 nvReg->vpll2B = nvReg->pllB;
231 nvReg->fifo = nvReadVGA(pNv, 0x1c) & ~(1<<5);
233 if(pNv->crtc_active[1]) {
234 nvReg->head = nvReadCRTC(pNv, 0, NV_CRTC_FSEL) & ~0x00001000;
235 nvReg->head2 = nvReadCRTC(pNv, 1, NV_CRTC_FSEL) | 0x00001000;
236 nvReg->crtcOwner = 3;
237 nvReg->pllsel |= 0x20000800;
238 nvReg->vpll = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL);
240 nvReg->vpllB = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL_B);
241 } else if(pNv->twoHeads) {
242 nvReg->head = nvReadCRTC(pNv, 0, NV_CRTC_FSEL) | 0x00001000;
243 nvReg->head2 = nvReadCRTC(pNv, 1, NV_CRTC_FSEL) & ~0x00001000;
244 nvReg->crtcOwner = 0;
245 nvReg->vpll2 = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL2);
247 nvReg->vpll2B = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL2_B);
250 nvReg->cursorConfig = 0x00000100;
251 if(mode->Flags & V_DBLSCAN)
252 nvReg->cursorConfig |= (1 << 4);
253 if(pNv->alphaCursor) {
254 if((pNv->Chipset & 0x0ff0) != CHIPSET_NV11)
255 nvReg->cursorConfig |= 0x04011000;
257 nvReg->cursorConfig |= 0x14011000;
258 nvReg->general |= (1 << 29);
260 nvReg->cursorConfig |= 0x02000000;
263 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
264 nvReg->dither = nvReadCurRAMDAC(pNv, NV_RAMDAC_DITHER_NV11) & ~0x00010000;
266 nvReg->dither |= 0x00010000;
268 nvReg->dither = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_DITHER) & ~1;
276 nvReg->displayV = mode->CrtcVDisplay;
282 NVDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, NVRegPtr nvReg,
285 int restore = VGA_SR_MODE;
287 if(primary) restore |= VGA_SR_CMAP | VGA_SR_FONTS;
288 NVLoadStateExt(pScrn, nvReg);
289 #if defined(__powerpc__)
290 restore &= ~VGA_SR_FONTS;
292 vgaHWRestore(pScrn, vgaReg, restore);
298 * This function saves the video state.
301 NVDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, NVRegPtr nvReg,
304 NVPtr pNv = NVPTR(pScrn);
306 #if defined(__powerpc__)
310 vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE |
311 (saveFonts? VGA_SR_FONTS : 0));
312 NVUnloadStateExt(pNv, nvReg);
314 /* can't read this reliably on NV11 */
315 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
316 /* 0 if inactive -> crtc0 is active, otherwise 1 */
317 nvReg->crtcOwner = pNv->crtc_active[1];
321 #define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8)))
322 #define MAKE_INDEX(in, w) (DEPTH_SHIFT(in, w) * 3)
325 NVDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
329 NVPtr pNv = NVPTR(pScrn);
332 pVga = &VGAHWPTR(pScrn)->ModeReg;
334 switch(pNv->CurrentLayout.depth) {
336 for(i = 0; i < numColors; i++) {
338 pVga->DAC[MAKE_INDEX(index, 5) + 0] = colors[index].red;
339 pVga->DAC[MAKE_INDEX(index, 5) + 1] = colors[index].green;
340 pVga->DAC[MAKE_INDEX(index, 5) + 2] = colors[index].blue;
344 for(i = 0; i < numColors; i++) {
346 pVga->DAC[MAKE_INDEX(index, 6) + 1] = colors[index].green;
348 pVga->DAC[MAKE_INDEX(index, 5) + 0] = colors[index].red;
349 pVga->DAC[MAKE_INDEX(index, 5) + 2] = colors[index].blue;
354 for(i = 0; i < numColors; i++) {
356 pVga->DAC[index*3] = colors[index].red;
357 pVga->DAC[(index*3)+1] = colors[index].green;
358 pVga->DAC[(index*3)+2] = colors[index].blue;
362 vgaHWRestore(pScrn, pVga, VGA_SR_CMAP);
366 * DDC1 support only requires DDC_SDA_MASK,
367 * DDC2 support requires DDC_SDA_MASK and DDC_SCL_MASK
369 #define DDC_SDA_READ_MASK (1 << 3)
370 #define DDC_SCL_READ_MASK (1 << 2)
371 #define DDC_SDA_WRITE_MASK (1 << 4)
372 #define DDC_SCL_WRITE_MASK (1 << 5)
375 NV_I2CGetBits(I2CBusPtr b, int *clock, int *data)
377 NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
380 /* Get the result. */
381 val = nvReadVGA(pNv, pNv->DDCBase);
383 *clock = (val & DDC_SCL_READ_MASK) != 0;
384 *data = (val & DDC_SDA_READ_MASK) != 0;
388 NV_I2CPutBits(I2CBusPtr b, int clock, int data)
390 NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
393 val = nvReadVGA(pNv, pNv->DDCBase + 1) & 0xf0;
395 val |= DDC_SCL_WRITE_MASK;
397 val &= ~DDC_SCL_WRITE_MASK;
400 val |= DDC_SDA_WRITE_MASK;
402 val &= ~DDC_SDA_WRITE_MASK;
404 nvWriteVGA(pNv, pNv->DDCBase + 1, val | 0x1);
408 NVDACi2cInit(ScrnInfoPtr pScrn)
410 NVPtr pNv = NVPTR(pScrn);
413 I2CPtr = xf86CreateI2CBusRec();
414 if(!I2CPtr) return FALSE;
418 I2CPtr->BusName = "DDC";
419 I2CPtr->scrnIndex = pScrn->scrnIndex;
420 I2CPtr->I2CPutBits = NV_I2CPutBits;
421 I2CPtr->I2CGetBits = NV_I2CGetBits;
422 I2CPtr->AcknTimeout = 5;
424 if (!xf86I2CBusInit(I2CPtr)) {