2 * Copyright 1996-1997 David J. McKay
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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
23 /* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen
26 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_dac.c,v 1.1 2003/07/31 20:24:29 mvojkovi Exp $ */
28 #include "riva_include.h"
31 RivaDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
34 int horizDisplay = (mode->CrtcHDisplay/8) - 1;
35 int horizStart = (mode->CrtcHSyncStart/8) - 1;
36 int horizEnd = (mode->CrtcHSyncEnd/8) - 1;
37 int horizTotal = (mode->CrtcHTotal/8) - 5;
38 int horizBlankStart = (mode->CrtcHDisplay/8) - 1;
39 int horizBlankEnd = (mode->CrtcHTotal/8) - 1;
40 int vertDisplay = mode->CrtcVDisplay - 1;
41 int vertStart = mode->CrtcVSyncStart - 1;
42 int vertEnd = mode->CrtcVSyncEnd - 1;
43 int vertTotal = mode->CrtcVTotal - 2;
44 int vertBlankStart = mode->CrtcVDisplay - 1;
45 int vertBlankEnd = mode->CrtcVTotal - 1;
48 RivaPtr pRiva = RivaPTR(pScrn);
49 RivaRegPtr rivaReg = &pRiva->ModeReg;
50 RivaFBLayout *pLayout = &pRiva->CurrentLayout;
54 * This will initialize all of the generic VGA registers.
56 if (!vgaHWInit(pScrn, mode))
59 pVga = &VGAHWPTR(pScrn)->ModeReg;
62 * Set all CRTC values.
65 if(mode->Flags & V_INTERLACE)
68 pVga->CRTC[0x0] = Set8Bits(horizTotal);
69 pVga->CRTC[0x1] = Set8Bits(horizDisplay);
70 pVga->CRTC[0x2] = Set8Bits(horizBlankStart);
71 pVga->CRTC[0x3] = SetBitField(horizBlankEnd,4:0,4:0)
73 pVga->CRTC[0x4] = Set8Bits(horizStart);
74 pVga->CRTC[0x5] = SetBitField(horizBlankEnd,5:5,7:7)
75 | SetBitField(horizEnd,4:0,4:0);
76 pVga->CRTC[0x6] = SetBitField(vertTotal,7:0,7:0);
77 pVga->CRTC[0x7] = SetBitField(vertTotal,8:8,0:0)
78 | SetBitField(vertDisplay,8:8,1:1)
79 | SetBitField(vertStart,8:8,2:2)
80 | SetBitField(vertBlankStart,8:8,3:3)
82 | SetBitField(vertTotal,9:9,5:5)
83 | SetBitField(vertDisplay,9:9,6:6)
84 | SetBitField(vertStart,9:9,7:7);
85 pVga->CRTC[0x9] = SetBitField(vertBlankStart,9:9,5:5)
87 | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00);
88 pVga->CRTC[0x10] = Set8Bits(vertStart);
89 pVga->CRTC[0x11] = SetBitField(vertEnd,3:0,3:0) | SetBit(5);
90 pVga->CRTC[0x12] = Set8Bits(vertDisplay);
91 pVga->CRTC[0x13] = ((pLayout->displayWidth/8)*(pLayout->bitsPerPixel/8));
92 pVga->CRTC[0x15] = Set8Bits(vertBlankStart);
93 pVga->CRTC[0x16] = Set8Bits(vertBlankEnd);
95 pVga->Attribute[0x10] = 0x01;
97 rivaReg->screen = SetBitField(horizBlankEnd,6:6,4:4)
98 | SetBitField(vertBlankStart,10:10,3:3)
99 | SetBitField(vertStart,10:10,2:2)
100 | SetBitField(vertDisplay,10:10,1:1)
101 | SetBitField(vertTotal,10:10,0:0);
103 rivaReg->horiz = SetBitField(horizTotal,8:8,0:0)
104 | SetBitField(horizDisplay,8:8,1:1)
105 | SetBitField(horizBlankStart,8:8,2:2)
106 | SetBitField(horizStart,8:8,3:3);
108 rivaReg->extra = SetBitField(vertTotal,11:11,0:0)
109 | SetBitField(vertDisplay,11:11,2:2)
110 | SetBitField(vertStart,11:11,4:4)
111 | SetBitField(vertBlankStart,11:11,6:6);
113 if(mode->Flags & V_INTERLACE) {
114 horizTotal = (horizTotal >> 1) & ~1;
115 rivaReg->interlace = Set8Bits(horizTotal);
116 rivaReg->horiz |= SetBitField(horizTotal,8:8,4:4);
118 rivaReg->interlace = 0xff; /* interlace off */
122 * Initialize DAC palette.
124 if(pLayout->bitsPerPixel != 8 )
126 for (i = 0; i < 256; i++)
129 pVga->DAC[(i*3)+1] = i;
130 pVga->DAC[(i*3)+2] = i;
135 * Calculate the extended registers.
138 if(pLayout->depth < 24)
142 pRiva->riva.CalcStateExt(&pRiva->riva,
145 pLayout->displayWidth,
151 rivaReg->cursorConfig = 0x02000100;
152 if(mode->Flags & V_DBLSCAN)
153 rivaReg->cursorConfig |= (1 << 4);
159 RivaDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, RivaRegPtr rivaReg,
162 RivaPtr pRiva = RivaPTR(pScrn);
163 int restore = VGA_SR_MODE;
165 restore |= primary ? (VGA_SR_CMAP | VGA_SR_FONTS) : VGA_SR_CMAP;
166 pRiva->riva.LoadStateExt(&pRiva->riva, rivaReg);
167 vgaHWRestore(pScrn, vgaReg, restore);
173 * This function saves the video state.
176 RivaDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, RivaRegPtr rivaReg,
179 RivaPtr pRiva = RivaPTR(pScrn);
181 pRiva->riva.LockUnlock(&pRiva->riva, 0);
183 vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE |
184 (saveFonts? VGA_SR_FONTS : 0));
185 pRiva->riva.UnloadStateExt(&pRiva->riva, rivaReg);
188 #define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8)))
189 #define MAKE_INDEX(in, w) (DEPTH_SHIFT(in, w) * 3)
192 RivaDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
196 RivaPtr pRiva = RivaPTR(pScrn);
199 pVga = &VGAHWPTR(pScrn)->ModeReg;
201 if(pRiva->CurrentLayout.depth != 8)
204 for(i = 0; i < numColors; i++) {
206 pVga->DAC[index*3] = colors[index].red;
207 pVga->DAC[(index*3)+1] = colors[index].green;
208 pVga->DAC[(index*3)+2] = colors[index].blue;
210 vgaHWRestore(pScrn, pVga, VGA_SR_CMAP);
214 * DDC1 support only requires DDC_SDA_MASK,
215 * DDC2 support requires DDC_SDA_MASK and DDC_SCL_MASK
217 #define DDC_SDA_READ_MASK (1 << 3)
218 #define DDC_SCL_READ_MASK (1 << 2)
219 #define DDC_SDA_WRITE_MASK (1 << 4)
220 #define DDC_SCL_WRITE_MASK (1 << 5)
223 Riva_I2CGetBits(I2CBusPtr b, int *clock, int *data)
225 RivaPtr pRiva = RivaPTR(xf86Screens[b->scrnIndex]);
228 /* Get the result. */
229 VGA_WR08(pRiva->riva.PCIO, 0x3d4, pRiva->DDCBase);
230 val = VGA_RD08(pRiva->riva.PCIO, 0x3d5);
232 *clock = (val & DDC_SCL_READ_MASK) != 0;
233 *data = (val & DDC_SDA_READ_MASK) != 0;
237 Riva_I2CPutBits(I2CBusPtr b, int clock, int data)
239 RivaPtr pRiva = RivaPTR(xf86Screens[b->scrnIndex]);
242 VGA_WR08(pRiva->riva.PCIO, 0x3d4, pRiva->DDCBase + 1);
243 val = VGA_RD08(pRiva->riva.PCIO, 0x3d5) & 0xf0;
245 val |= DDC_SCL_WRITE_MASK;
247 val &= ~DDC_SCL_WRITE_MASK;
250 val |= DDC_SDA_WRITE_MASK;
252 val &= ~DDC_SDA_WRITE_MASK;
254 VGA_WR08(pRiva->riva.PCIO, 0x3d4, pRiva->DDCBase + 1);
255 VGA_WR08(pRiva->riva.PCIO, 0x3d5, val | 0x1);
259 RivaDACi2cInit(ScrnInfoPtr pScrn)
261 RivaPtr pRiva = RivaPTR(pScrn);
264 I2CPtr = xf86CreateI2CBusRec();
265 if(!I2CPtr) return FALSE;
269 I2CPtr->BusName = "DDC";
270 I2CPtr->scrnIndex = pScrn->scrnIndex;
271 I2CPtr->I2CPutBits = Riva_I2CPutBits;
272 I2CPtr->I2CGetBits = Riva_I2CGetBits;
273 I2CPtr->AcknTimeout = 5;
275 if (!xf86I2CBusInit(I2CPtr)) {