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#ifdef HAVE_CONFIG_H 27#include "config.h" 28#endif 29 30#include "riva_include.h" 31 32Bool 33RivaDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 34{ 35 int i; 36 int horizDisplay = (mode->CrtcHDisplay/8) - 1; 37 int horizStart = (mode->CrtcHSyncStart/8) - 1; 38 int horizEnd = (mode->CrtcHSyncEnd/8) - 1; 39 int horizTotal = (mode->CrtcHTotal/8) - 5; 40 int horizBlankStart = (mode->CrtcHDisplay/8) - 1; 41 int horizBlankEnd = (mode->CrtcHTotal/8) - 1; 42 int vertDisplay = mode->CrtcVDisplay - 1; 43 int vertStart = mode->CrtcVSyncStart - 1; 44 int vertEnd = mode->CrtcVSyncEnd - 1; 45 int vertTotal = mode->CrtcVTotal - 2; 46 int vertBlankStart = mode->CrtcVDisplay - 1; 47 int vertBlankEnd = mode->CrtcVTotal - 1; 48 49 50 RivaPtr pRiva = RivaPTR(pScrn); 51 RivaRegPtr rivaReg = &pRiva->ModeReg; 52 RivaFBLayout *pLayout = &pRiva->CurrentLayout; 53 vgaRegPtr pVga; 54 55 /* 56 * This will initialize all of the generic VGA registers. 57 */ 58 if (!vgaHWInit(pScrn, mode)) 59 return(FALSE); 60 61 pVga = &VGAHWPTR(pScrn)->ModeReg; 62 63 /* 64 * Set all CRTC values. 65 */ 66 67 if(mode->Flags & V_INTERLACE) 68 vertTotal |= 1; 69 70 pVga->CRTC[0x0] = RIVA_Set8Bits(horizTotal); 71 pVga->CRTC[0x1] = RIVA_Set8Bits(horizDisplay); 72 pVga->CRTC[0x2] = RIVA_Set8Bits(horizBlankStart); 73 pVga->CRTC[0x3] = RIVA_SetBitField(horizBlankEnd,4:0,4:0) 74 | RIVA_SetBit(7); 75 pVga->CRTC[0x4] = RIVA_Set8Bits(horizStart); 76 pVga->CRTC[0x5] = RIVA_SetBitField(horizBlankEnd,5:5,7:7) 77 | RIVA_SetBitField(horizEnd,4:0,4:0); 78 pVga->CRTC[0x6] = RIVA_SetBitField(vertTotal,7:0,7:0); 79 pVga->CRTC[0x7] = RIVA_SetBitField(vertTotal,8:8,0:0) 80 | RIVA_SetBitField(vertDisplay,8:8,1:1) 81 | RIVA_SetBitField(vertStart,8:8,2:2) 82 | RIVA_SetBitField(vertBlankStart,8:8,3:3) 83 | RIVA_SetBit(4) 84 | RIVA_SetBitField(vertTotal,9:9,5:5) 85 | RIVA_SetBitField(vertDisplay,9:9,6:6) 86 | RIVA_SetBitField(vertStart,9:9,7:7); 87 pVga->CRTC[0x9] = RIVA_SetBitField(vertBlankStart,9:9,5:5) 88 | RIVA_SetBit(6) 89 | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00); 90 pVga->CRTC[0x10] = RIVA_Set8Bits(vertStart); 91 pVga->CRTC[0x11] = RIVA_SetBitField(vertEnd,3:0,3:0) | RIVA_SetBit(5); 92 pVga->CRTC[0x12] = RIVA_Set8Bits(vertDisplay); 93 pVga->CRTC[0x13] = ((pLayout->displayWidth/8)*(pLayout->bitsPerPixel/8)); 94 pVga->CRTC[0x15] = RIVA_Set8Bits(vertBlankStart); 95 pVga->CRTC[0x16] = RIVA_Set8Bits(vertBlankEnd); 96 97 pVga->Attribute[0x10] = 0x01; 98 99 rivaReg->screen = RIVA_SetBitField(horizBlankEnd,6:6,4:4) 100 | RIVA_SetBitField(vertBlankStart,10:10,3:3) 101 | RIVA_SetBitField(vertStart,10:10,2:2) 102 | RIVA_SetBitField(vertDisplay,10:10,1:1) 103 | RIVA_SetBitField(vertTotal,10:10,0:0); 104 105 rivaReg->horiz = RIVA_SetBitField(horizTotal,8:8,0:0) 106 | RIVA_SetBitField(horizDisplay,8:8,1:1) 107 | RIVA_SetBitField(horizBlankStart,8:8,2:2) 108 | RIVA_SetBitField(horizStart,8:8,3:3); 109 110 rivaReg->extra = RIVA_SetBitField(vertTotal,11:11,0:0) 111 | RIVA_SetBitField(vertDisplay,11:11,2:2) 112 | RIVA_SetBitField(vertStart,11:11,4:4) 113 | RIVA_SetBitField(vertBlankStart,11:11,6:6); 114 115 if(mode->Flags & V_INTERLACE) { 116 horizTotal = (horizTotal >> 1) & ~1; 117 rivaReg->interlace = RIVA_Set8Bits(horizTotal); 118 rivaReg->horiz |= RIVA_SetBitField(horizTotal,8:8,4:4); 119 } else { 120 rivaReg->interlace = 0xff; /* interlace off */ 121 } 122 123 /* 124 * Initialize DAC palette. 125 */ 126 if(pLayout->bitsPerPixel != 8 ) 127 { 128 for (i = 0; i < 256; i++) 129 { 130 pVga->DAC[i*3] = i; 131 pVga->DAC[(i*3)+1] = i; 132 pVga->DAC[(i*3)+2] = i; 133 } 134 } 135 136 /* 137 * Calculate the extended registers. 138 */ 139 140 if(pLayout->depth < 24) 141 i = pLayout->depth; 142 else i = 32; 143 144 pRiva->riva.CalcStateExt(&pRiva->riva, 145 rivaReg, 146 i, 147 pLayout->displayWidth, 148 mode->CrtcHDisplay, 149 pScrn->virtualY, 150 mode->Clock, 151 mode->Flags); 152 153 rivaReg->cursorConfig = 0x02000100; 154 if(mode->Flags & V_DBLSCAN) 155 rivaReg->cursorConfig |= (1 << 4); 156 157 return (TRUE); 158} 159 160void 161RivaDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, RivaRegPtr rivaReg, 162 Bool primary) 163{ 164 RivaPtr pRiva = RivaPTR(pScrn); 165 int restore = VGA_SR_MODE; 166 167 restore |= primary ? (VGA_SR_CMAP | VGA_SR_FONTS) : VGA_SR_CMAP; 168 pRiva->riva.LoadStateExt(&pRiva->riva, rivaReg); 169 vgaHWRestore(pScrn, vgaReg, restore); 170} 171 172/* 173 * RivaDACSave 174 * 175 * This function saves the video state. 176 */ 177void 178RivaDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, RivaRegPtr rivaReg, 179 Bool saveFonts) 180{ 181 RivaPtr pRiva = RivaPTR(pScrn); 182 183 pRiva->riva.LockUnlock(&pRiva->riva, 0); 184 185 vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE | 186 (saveFonts? VGA_SR_FONTS : 0)); 187 pRiva->riva.UnloadStateExt(&pRiva->riva, rivaReg); 188} 189 190#define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8))) 191#define MAKE_INDEX(in, w) (DEPTH_SHIFT(in, w) * 3) 192 193void 194RivaDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, 195 VisualPtr pVisual ) 196{ 197 int i, index; 198 RivaPtr pRiva = RivaPTR(pScrn); 199 vgaRegPtr pVga; 200 201 pVga = &VGAHWPTR(pScrn)->ModeReg; 202 203 if(pRiva->CurrentLayout.depth != 8) 204 return; 205 206 for(i = 0; i < numColors; i++) { 207 index = indices[i]; 208 pVga->DAC[index*3] = colors[index].red; 209 pVga->DAC[(index*3)+1] = colors[index].green; 210 pVga->DAC[(index*3)+2] = colors[index].blue; 211 } 212 vgaHWRestore(pScrn, pVga, VGA_SR_CMAP); 213} 214 215/* 216 * DDC1 support only requires DDC_SDA_MASK, 217 * DDC2 support requires DDC_SDA_MASK and DDC_SCL_MASK 218 */ 219#define DDC_SDA_READ_MASK (1 << 3) 220#define DDC_SCL_READ_MASK (1 << 2) 221#define DDC_SDA_WRITE_MASK (1 << 4) 222#define DDC_SCL_WRITE_MASK (1 << 5) 223 224static void 225Riva_I2CGetBits(I2CBusPtr b, int *clock, int *data) 226{ 227#ifdef XF86_SCRN_INTERFACE 228 RivaPtr pRiva = RivaPTR(b->pScrn); 229#else 230 RivaPtr pRiva = RivaPTR(xf86Screens[b->scrnIndex]); 231#endif 232 unsigned char val; 233 234 /* Get the result. */ 235 VGA_WR08(pRiva->riva.PCIO, 0x3d4, pRiva->DDCBase); 236 val = VGA_RD08(pRiva->riva.PCIO, 0x3d5); 237 238 *clock = (val & DDC_SCL_READ_MASK) != 0; 239 *data = (val & DDC_SDA_READ_MASK) != 0; 240} 241 242static void 243Riva_I2CPutBits(I2CBusPtr b, int clock, int data) 244{ 245#ifdef XF86_SCRN_INTERFACE 246 RivaPtr pRiva = RivaPTR(b->pScrn); 247#else 248 RivaPtr pRiva = RivaPTR(xf86Screens[b->scrnIndex]); 249#endif 250 unsigned char val; 251 252 VGA_WR08(pRiva->riva.PCIO, 0x3d4, pRiva->DDCBase + 1); 253 val = VGA_RD08(pRiva->riva.PCIO, 0x3d5) & 0xf0; 254 if (clock) 255 val |= DDC_SCL_WRITE_MASK; 256 else 257 val &= ~DDC_SCL_WRITE_MASK; 258 259 if (data) 260 val |= DDC_SDA_WRITE_MASK; 261 else 262 val &= ~DDC_SDA_WRITE_MASK; 263 264 VGA_WR08(pRiva->riva.PCIO, 0x3d4, pRiva->DDCBase + 1); 265 VGA_WR08(pRiva->riva.PCIO, 0x3d5, val | 0x1); 266} 267 268Bool 269RivaDACi2cInit(ScrnInfoPtr pScrn) 270{ 271 RivaPtr pRiva = RivaPTR(pScrn); 272 I2CBusPtr I2CPtr; 273 274 I2CPtr = xf86CreateI2CBusRec(); 275 if(!I2CPtr) return FALSE; 276 277 pRiva->I2C = I2CPtr; 278 279 I2CPtr->BusName = "DDC"; 280 I2CPtr->scrnIndex = pScrn->scrnIndex; 281#ifdef XF86_SCRN_INTERFACE 282 I2CPtr->pScrn = pScrn; 283#endif 284 I2CPtr->I2CPutBits = Riva_I2CPutBits; 285 I2CPtr->I2CGetBits = Riva_I2CGetBits; 286 I2CPtr->AcknTimeout = 5; 287 288 if (!xf86I2CBusInit(I2CPtr)) { 289 return FALSE; 290 } 291 return TRUE; 292} 293