smilynx_hw.c revision eb3dced6
1/* 2Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. 3Copyright (C) 2000 Silicon Motion, Inc. All Rights Reserved. 4Copyright (C) 2008 Francisco Jerez. All Rights Reserved. 5 6Permission is hereby granted, free of charge, to any person obtaining a copy of 7this software and associated documentation files (the "Software"), to deal in 8the Software without restriction, including without limitation the rights to 9use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 10of the Software, and to permit persons to whom the Software is furnished to do 11so, subject to the following conditions: 12 13The above copyright notice and this permission notice shall be included in all 14copies or substantial portions of the Software. 15 16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 18NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 20AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 23Except as contained in this notice, the names of The XFree86 Project and 24Silicon Motion shall not be used in advertising or otherwise to promote the 25sale, use or other dealings in this Software without prior written 26authorization from The XFree86 Project or Silicon Motion. 27*/ 28 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32 33#include "smi.h" 34#include "smi_crtc.h" 35#include "smilynx.h" 36 37static unsigned int SMILynx_ddc1Read(ScrnInfoPtr pScrn); 38 39Bool 40SMILynx_HWInit(ScrnInfoPtr pScrn) 41{ 42 SMIPtr pSmi = SMIPTR(pScrn); 43 SMIRegPtr mode = pSmi->mode; 44 vgaHWPtr hwp = VGAHWPTR(pScrn); 45 int vgaIOBase = hwp->IOBase; 46 int vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; 47 int vgaCRData = vgaIOBase + VGA_CRTC_DATA_OFFSET; 48 49 ENTER(); 50 51 if (pSmi->PCIBurst) { 52 mode->SR17 |= 0x20; 53 } else { 54 mode->SR17 &= ~0x20; 55 } 56 57 /* Gamma correction */ 58 if (pSmi->Chipset == SMI_LYNX3DM || pSmi->Chipset == SMI_COUGAR3DR) { 59 if(pScrn->bitsPerPixel == 8) 60 mode->SR66 = (mode->SR66 & 0x33) | 0x00; /* Both RAMLUT on, 6 bits-RAM */ 61 else 62 mode->SR66 = (mode->SR66 & 0x33) | 0x04; /* Both RAMLUT on, Gamma correct ON */ 63 } 64 65 /* Program MCLK */ 66 if (pSmi->MCLK > 0) 67 SMI_CommonCalcClock(pScrn->scrnIndex, pSmi->MCLK, 68 1, 1, 63, 0, 0, 69 pSmi->clockRange.minClock, 70 pSmi->clockRange.maxClock, 71 &mode->SR6A, &mode->SR6B); 72 73 if(!pSmi->useBIOS) { 74 /* Disable DAC and LCD framebuffer r/w operation */ 75 mode->SR21 |= 0xB0; 76 77 /* Power down mode is standby mode, VCLK and MCLK divided by 4 in standby mode */ 78 mode->SR20 = (mode->SR20 & ~0xB0) | 0x10; 79 80 /* Set DPMS state to Off */ 81 mode->SR22 |= 0x30; 82 83 if (pSmi->Chipset != SMI_COUGAR3DR) { 84 /* Select no displays */ 85 mode->SR31 &= ~0x07; 86 87 /* Disable virtual refresh */ 88 mode->SR31 &= ~0x80; 89 90 /* Disable expansion */ 91 mode->SR32 &= ~0x03; 92 /* Enable autocentering */ 93 if (SMI_LYNXM_SERIES(pSmi->Chipset)) 94 mode->SR32 |= 0x04; 95 else 96 mode->SR32 &= ~0x04; 97 98 if (pSmi->lcd == 2) /* Panel is DSTN */ 99 mode->SR21 = 0x00; 100 101 /* Enable HW LCD power sequencing */ 102 mode->SR34 |= 0x80; 103 } 104 105 /* Disable Vertical Expansion/Vertical Centering/Horizontal Centering */ 106 mode->CR90[0xE] &= ~0x7; 107 108 /* use vclk1 */ 109 mode->SR68 = 0x54; 110 111 if(pSmi->Dualhead){ 112 /* set LCD to vclk2 */ 113 mode->SR69 = 0x04; 114 } 115 116 /* Disable panel video */ 117 mode->SRA0 = 0; 118 119 mode->CR33 = 0; 120 mode->CR3A = 0; 121 } 122 123 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17, mode->SR17); 124 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20, mode->SR20); 125 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, mode->SR21); 126 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22, mode->SR22); 127 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, mode->SR31); 128 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32, mode->SR32); 129 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x34, mode->SR34); 130 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66, mode->SR66); 131 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x68, mode->SR68); 132 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x69, mode->SR69); 133 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A, mode->SR6A); 134 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B, mode->SR6B); 135 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0xA0, mode->SRA0); 136 137 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, mode->CR33); 138 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A, mode->CR3A); 139 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, mode->CR90[0xE]); 140 141 LEAVE(TRUE); 142} 143 144/* 145 * This function performs the inverse of the restore function: It saves all the 146 * standard and extended registers that we are going to modify to set up a video 147 * mode. 148 */ 149 150void 151SMILynx_Save(ScrnInfoPtr pScrn) 152{ 153 SMIPtr pSmi = SMIPTR(pScrn); 154 int i; 155 CARD32 offset; 156 SMIRegPtr save = pSmi->save; 157 vgaHWPtr hwp = VGAHWPTR(pScrn); 158 vgaRegPtr vgaSavePtr = &hwp->SavedReg; 159 int vgaIOBase = hwp->IOBase; 160 int vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; 161 int vgaCRData = vgaIOBase + VGA_CRTC_DATA_OFFSET; 162 163 ENTER(); 164 165 /* Save the standard VGA registers */ 166 vgaHWSave(pScrn, vgaSavePtr, VGA_SR_ALL); 167 save->smiDACMask = VGAIN8(pSmi, VGA_DAC_MASK); 168 VGAOUT8(pSmi, VGA_DAC_READ_ADDR, 0); 169 for (i = 0; i < 256; i++) { 170 save->smiDacRegs[i][0] = VGAIN8(pSmi, VGA_DAC_DATA); 171 save->smiDacRegs[i][1] = VGAIN8(pSmi, VGA_DAC_DATA); 172 save->smiDacRegs[i][2] = VGAIN8(pSmi, VGA_DAC_DATA); 173 } 174 for (i = 0, offset = 2; i < 8192; i++, offset += 8) 175 save->smiFont[i] = *(pSmi->FBBase + offset); 176 177 /* Now we save all the extended registers we need. */ 178 save->SR17 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17); 179 save->SR18 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18); 180 181 save->SR20 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20); 182 save->SR21 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); 183 save->SR22 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22); 184 save->SR23 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23); 185 save->SR24 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x24); 186 187 save->SR31 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31); 188 save->SR32 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32); 189 190 save->SR66 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66); 191 save->SR68 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x68); 192 save->SR69 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x69); 193 save->SR6A = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A); 194 save->SR6B = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B); 195 save->SR6C = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6C); 196 save->SR6D = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6D); 197 198 save->SR81 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81); 199 save->SRA0 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0xA0); 200 201 if (pSmi->Dualhead) { 202 /* dualhead stuff */ 203 save->SR40 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x40); 204 save->SR41 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x41); 205 save->SR42 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x42); 206 save->SR43 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x43); 207 save->SR44 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x44); 208 save->SR45 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x45); 209 save->SR48 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x48); 210 save->SR49 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x49); 211 save->SR4A = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4A); 212 save->SR4B = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4B); 213 save->SR4C = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4C); 214 215 save->SR50 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x50); 216 save->SR51 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x51); 217 save->SR52 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x52); 218 save->SR53 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x53); 219 save->SR54 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x54); 220 save->SR55 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x55); 221 save->SR56 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x56); 222 save->SR57 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x57); 223 save->SR5A = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x5A); 224 225 /* PLL2 stuff */ 226 save->SR6E = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6E); 227 save->SR6F = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6F); 228 } 229 230 if (SMI_LYNXM_SERIES(pSmi->Chipset)) { 231 /* Save common registers */ 232 save->CR30 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x30); 233 save->CR3A = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A); 234 for (i = 0; i < 15; i++) { 235 save->CR90[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x90 + i); 236 } 237 for (i = 0; i < 14; i++) { 238 save->CRA0[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0xA0 + i); 239 } 240 241 /* Save primary registers */ 242 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14] & ~0x20); 243 244 save->CR33 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33); 245 for (i = 0; i < 14; i++) { 246 save->CR40[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i); 247 } 248 save->CR9F = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9F); 249 250 /* Save secondary registers */ 251 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14] | 0x20); 252 save->CR33_2 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33); 253 for (i = 0; i < 14; i++) { 254 save->CR40_2[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i); 255 } 256 save->CR9F_2 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9F); 257 258 /* PDR#1069 */ 259 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14]); 260 261 } 262 else { 263 save->CR30 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x30); 264 save->CR33 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33); 265 save->CR3A = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A); 266 for (i = 0; i < 14; i++) { 267 save->CR40[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i); 268 } 269 } 270 271 save->DPR10 = READ_DPR(pSmi, 0x10); 272 save->DPR1C = READ_DPR(pSmi, 0x1C); 273 save->DPR20 = READ_DPR(pSmi, 0x20); 274 save->DPR24 = READ_DPR(pSmi, 0x24); 275 save->DPR28 = READ_DPR(pSmi, 0x28); 276 save->DPR2C = READ_DPR(pSmi, 0x2C); 277 save->DPR30 = READ_DPR(pSmi, 0x30); 278 save->DPR3C = READ_DPR(pSmi, 0x3C); 279 save->DPR40 = READ_DPR(pSmi, 0x40); 280 save->DPR44 = READ_DPR(pSmi, 0x44); 281 282 save->VPR00 = READ_VPR(pSmi, 0x00); 283 save->VPR0C = READ_VPR(pSmi, 0x0C); 284 save->VPR10 = READ_VPR(pSmi, 0x10); 285 286 if (pSmi->Chipset == SMI_COUGAR3DR) { 287 save->FPR00_ = READ_FPR(pSmi, FPR00); 288 save->FPR0C_ = READ_FPR(pSmi, FPR0C); 289 save->FPR10_ = READ_FPR(pSmi, FPR10); 290 } 291 292 save->CPR00 = READ_CPR(pSmi, 0x00); 293 294 if (!pSmi->ModeStructInit) { 295 vgaHWCopyReg(&hwp->ModeReg, vgaSavePtr); 296 memcpy(pSmi->mode, save, sizeof(SMIRegRec)); 297 pSmi->ModeStructInit = TRUE; 298 } 299 300#ifdef USE_INT10 301 if (pSmi->useBIOS && pSmi->pInt10 != NULL) { 302 pSmi->pInt10->num = 0x10; 303 pSmi->pInt10->ax = 0x0F00; 304 xf86ExecX86int10(pSmi->pInt10); 305 save->mode = pSmi->pInt10->ax & 0x007F; 306 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Current mode 0x%02X.\n", 307 save->mode); 308 } 309#endif 310 if (xf86GetVerbosity() > 1) { 311 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 312 "Saved current video mode. Register dump:\n"); 313 SMI_PrintRegs(pScrn); 314 } 315 316 LEAVE(); 317} 318 319/* 320 * This function is used to restore a video mode. It writes out all of the 321 * standard VGA and extended registers needed to setup a video mode. 322 */ 323 324void 325SMILynx_WriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, SMIRegPtr restore) 326{ 327 SMIPtr pSmi = SMIPTR(pScrn); 328 int i; 329 CARD8 tmp; 330 CARD32 offset; 331 vgaHWPtr hwp = VGAHWPTR(pScrn); 332 int vgaIOBase = hwp->IOBase; 333 int vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; 334 int vgaCRData = vgaIOBase + VGA_CRTC_DATA_OFFSET; 335 336 ENTER(); 337 338 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17, restore->SR17); 339 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18, restore->SR18); 340 341 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20, restore->SR20); 342 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, restore->SR21); 343 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22, restore->SR22); 344 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23, restore->SR23); 345 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x24, restore->SR24); 346 347 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, restore->SR31); 348 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32, restore->SR32); 349 350 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66, restore->SR66); 351 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x68, restore->SR68); 352 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x69, restore->SR69); 353 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A, restore->SR6A); 354 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B, restore->SR6B); 355 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6C, restore->SR6C); 356 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6D, restore->SR6D); 357 358 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81, restore->SR81); 359 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0xA0, restore->SRA0); 360 361 if (pSmi->useBIOS && restore->mode != 0){ 362#ifdef USE_INT10 363 pSmi->pInt10->num = 0x10; 364 pSmi->pInt10->ax = restore->mode | 0x80; 365 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode 0x%02X\n", 366 restore->mode); 367 xf86ExecX86int10(pSmi->pInt10); 368 369 /* Enable linear mode. */ 370 outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18); 371 tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA); 372 outb(pSmi->PIOBase + VGA_SEQ_DATA, tmp | 0x01); 373 374 /* Enable DPR/VPR registers. */ 375 tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); 376 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, tmp & ~0x03); 377#endif 378 } else { 379 /* Restore the standard VGA registers */ 380 vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_ALL); 381 if (restore->smiDACMask) { 382 VGAOUT8(pSmi, VGA_DAC_MASK, restore->smiDACMask); 383 } else { 384 VGAOUT8(pSmi, VGA_DAC_MASK, 0xFF); 385 } 386 VGAOUT8(pSmi, VGA_DAC_WRITE_ADDR, 0); 387 for (i = 0; i < 256; i++) { 388 VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][0]); 389 VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][1]); 390 VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][2]); 391 } 392 for (i = 0, offset = 2; i < 8192; i++, offset += 8) { 393 *(pSmi->FBBase + offset) = restore->smiFont[i]; 394 } 395 396 if (SMI_LYNXM_SERIES(pSmi->Chipset)) { 397 /* Restore secondary registers */ 398 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, 399 restore->CR90[14] | 0x20); 400 401 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33_2); 402 for (i = 0; i < 14; i++) { 403 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i, 404 restore->CR40_2[i]); 405 } 406 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9F, restore->CR9F_2); 407 408 /* Restore primary registers */ 409 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, 410 restore->CR90[14] & ~0x20); 411 412 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33); 413 for (i = 0; i < 14; i++) { 414 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i, 415 restore->CR40[i]); 416 } 417 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9F, restore->CR9F); 418 419 /* Restore common registers */ 420 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x30, restore->CR30); 421 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A, restore->CR3A); 422 423 for (i = 0; i < 15; i++) 424 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x90 + i, 425 restore->CR90[i]); 426 427 for (i = 0; i < 14; i++) 428 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0xA0 + i, 429 restore->CRA0[i]); 430 431 }else{ 432 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x30, restore->CR30); 433 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33); 434 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A, restore->CR3A); 435 for (i = 0; i < 14; i++) { 436 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i, 437 restore->CR40[i]); 438 } 439 } 440 441 if (pSmi->Dualhead) { 442 /* dualhead stuff */ 443 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x40, restore->SR40); 444 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x41, restore->SR41); 445 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x42, restore->SR42); 446 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x43, restore->SR43); 447 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x44, restore->SR44); 448 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x45, restore->SR45); 449 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x48, restore->SR48); 450 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x49, restore->SR49); 451 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4A, restore->SR4A); 452 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4B, restore->SR4B); 453 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4C, restore->SR4C); 454 455 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x50, restore->SR50); 456 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x51, restore->SR51); 457 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x52, restore->SR52); 458 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x53, restore->SR53); 459 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x54, restore->SR54); 460 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x55, restore->SR55); 461 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x56, restore->SR56); 462 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x57, restore->SR57); 463 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x5A, restore->SR5A); 464 465 /* PLL2 stuff */ 466 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6E, restore->SR6E); 467 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6F, restore->SR6F); 468 } 469 } 470 471 /* Reset the graphics engine */ 472 WRITE_DPR(pSmi, 0x10, restore->DPR10); 473 WRITE_DPR(pSmi, 0x1C, restore->DPR1C); 474 WRITE_DPR(pSmi, 0x20, restore->DPR20); 475 WRITE_DPR(pSmi, 0x24, restore->DPR24); 476 WRITE_DPR(pSmi, 0x28, restore->DPR28); 477 WRITE_DPR(pSmi, 0x2C, restore->DPR2C); 478 WRITE_DPR(pSmi, 0x30, restore->DPR30); 479 WRITE_DPR(pSmi, 0x3C, restore->DPR3C); 480 WRITE_DPR(pSmi, 0x40, restore->DPR40); 481 WRITE_DPR(pSmi, 0x44, restore->DPR44); 482 483 /* write video controller regs */ 484 WRITE_VPR(pSmi, 0x00, restore->VPR00); 485 WRITE_VPR(pSmi, 0x0C, restore->VPR0C); 486 WRITE_VPR(pSmi, 0x10, restore->VPR10); 487 488 if(pSmi->Chipset == SMI_COUGAR3DR) { 489 WRITE_FPR(pSmi, FPR00, restore->FPR00_); 490 WRITE_FPR(pSmi, FPR0C, restore->FPR0C_); 491 WRITE_FPR(pSmi, FPR10, restore->FPR10_); 492 } 493 494 WRITE_CPR(pSmi, 0x00, restore->CPR00); 495 496 if (xf86GetVerbosity() > 1) { 497 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 498 "Done restoring mode. Register dump:\n"); 499 SMI_PrintRegs(pScrn); 500 } 501 502 vgaHWProtect(pScrn, FALSE); 503 504 LEAVE(); 505} 506 507 508/* 509 * SMI_DisplayPowerManagementSet -- Sets VESA Display Power Management 510 * Signaling (DPMS) Mode. 511 */ 512void 513SMILynx_DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, 514 int flags) 515{ 516 SMIPtr pSmi = SMIPTR(pScrn); 517 SMIRegPtr mode = pSmi->mode; 518 vgaHWPtr hwp = VGAHWPTR(pScrn); 519 520 ENTER(); 521 522 /* If we already are in the requested DPMS mode, just return */ 523 if (pSmi->CurrentDPMS != PowerManagementMode) { 524 /* Read the required SR registers for the DPMS handler */ 525 CARD8 SR01 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01); 526 527 switch (PowerManagementMode) { 528 case DPMSModeOn: 529 SR01 &= ~0x20; /* Screen on */ 530 mode->SR23 &= ~0xC0; /* Disable chip activity detection */ 531 break; 532 case DPMSModeStandby: 533 case DPMSModeSuspend: 534 case DPMSModeOff: 535 SR01 |= 0x20; /* Screen off */ 536 mode->SR23 = (mode->SR23 & ~0x07) | 0xD8; /* Enable chip activity detection 537 Enable internal auto-standby mode 538 Enable both IO Write and Host Memory write detect 539 0 minutes timeout */ 540 break; 541 } 542 543 /* Wait for vertical retrace */ 544 while (hwp->readST01(hwp) & 0x8) ; 545 while (!(hwp->readST01(hwp) & 0x8)) ; 546 547 /* Write the registers */ 548 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01, SR01); 549 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23, mode->SR23); 550 551 /* Set the DPMS mode to every output and CRTC */ 552 xf86DPMSSet(pScrn, PowerManagementMode, flags); 553 554 /* Save the current power state */ 555 pSmi->CurrentDPMS = PowerManagementMode; 556 } 557 558 LEAVE(); 559} 560 561static unsigned int 562SMILynx_ddc1Read(ScrnInfoPtr pScrn) 563{ 564 register vgaHWPtr hwp = VGAHWPTR(pScrn); 565 SMIPtr pSmi = SMIPTR(pScrn); 566 unsigned int ret; 567 568 ENTER(); 569 570 while (hwp->readST01(hwp) & 0x8) ; 571 while (!(hwp->readST01(hwp) & 0x8)) ; 572 573 ret = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72) & 0x08; 574 575 LEAVE(ret); 576} 577 578xf86MonPtr 579SMILynx_ddc1(ScrnInfoPtr pScrn) 580{ 581 SMIPtr pSmi = SMIPTR(pScrn); 582 xf86MonPtr pMon; 583 unsigned char tmp; 584 585 ENTER(); 586 587 tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72); 588 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72, tmp | 0x20); 589 590 pMon = xf86PrintEDID(xf86DoEDID_DDC1(pScrn->scrnIndex, 591 vgaHWddc1SetSpeedWeak(), 592 SMILynx_ddc1Read)); 593 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72, tmp); 594 595 LEAVE(pMon); 596} 597 598 599/* This function is used to debug, it prints out the contents of Lynx regs */ 600void 601SMILynx_PrintRegs(ScrnInfoPtr pScrn) 602{ 603 unsigned char i; 604 SMIPtr pSmi = SMIPTR(pScrn); 605 vgaHWPtr hwp = VGAHWPTR(pScrn); 606 int vgaCRIndex = hwp->IOBase + VGA_CRTC_INDEX_OFFSET; 607 int vgaCRReg = hwp->IOBase + VGA_CRTC_DATA_OFFSET; 608 int vgaStatus = hwp->IOBase + VGA_IN_STAT_1_OFFSET; 609 610 xf86ErrorFVerb(VERBLEV, "MISCELLANEOUS OUTPUT\n %02X\n", 611 VGAIN8(pSmi, VGA_MISC_OUT_R)); 612 613 xf86ErrorFVerb(VERBLEV, "\nSEQUENCER\n" 614 " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); 615 for (i = 0x00; i <= 0xAF; i++) { 616 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 617 if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); 618 xf86ErrorFVerb(VERBLEV, "%02X ", 619 VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, i)); 620 } 621 622 xf86ErrorFVerb(VERBLEV, "\n\nCRT CONTROLLER\n" 623 " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); 624 for (i = 0x00; i <= 0xAD; i++) { 625 if (i == 0x20) i = 0x30; 626 if (i == 0x50) i = 0x90; 627 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 628 if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); 629 xf86ErrorFVerb(VERBLEV, "%02X ", 630 VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRReg, i)); 631 } 632 633 xf86ErrorFVerb(VERBLEV, "\n\nGRAPHICS CONTROLLER\n" 634 " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); 635 for (i = 0x00; i <= 0x08; i++) { 636 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 637 if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); 638 xf86ErrorFVerb(VERBLEV, "%02X ", 639 VGAIN8_INDEX(pSmi, VGA_GRAPH_INDEX, VGA_GRAPH_DATA, i)); 640 } 641 642 xf86ErrorFVerb(VERBLEV, "\n\nATTRIBUTE 0CONTROLLER\n" 643 " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); 644 for (i = 0x00; i <= 0x14; i++) { 645 (void) VGAIN8(pSmi, vgaStatus); 646 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 647 if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); 648 xf86ErrorFVerb(VERBLEV, "%02X ", 649 VGAIN8_INDEX(pSmi, VGA_ATTR_INDEX, VGA_ATTR_DATA_R, i)); 650 } 651 (void) VGAIN8(pSmi, vgaStatus); 652 VGAOUT8(pSmi, VGA_ATTR_INDEX, 0x20); 653} 654