smilynx_hw.c revision 7104f784
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 if (pSmi->useBIOS && pSmi->pInt10 != NULL) { 301 pSmi->pInt10->num = 0x10; 302 pSmi->pInt10->ax = 0x0F00; 303 xf86ExecX86int10(pSmi->pInt10); 304 save->mode = pSmi->pInt10->ax & 0x007F; 305 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Current mode 0x%02X.\n", 306 save->mode); 307 } 308 309 if (xf86GetVerbosity() > 1) { 310 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 311 "Saved current video mode. Register dump:\n"); 312 SMI_PrintRegs(pScrn); 313 } 314 315 LEAVE(); 316} 317 318/* 319 * This function is used to restore a video mode. It writes out all of the 320 * standard VGA and extended registers needed to setup a video mode. 321 */ 322 323void 324SMILynx_WriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, SMIRegPtr restore) 325{ 326 SMIPtr pSmi = SMIPTR(pScrn); 327 int i; 328 CARD8 tmp; 329 CARD32 offset; 330 vgaHWPtr hwp = VGAHWPTR(pScrn); 331 int vgaIOBase = hwp->IOBase; 332 int vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; 333 int vgaCRData = vgaIOBase + VGA_CRTC_DATA_OFFSET; 334 335 ENTER(); 336 337 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17, restore->SR17); 338 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18, restore->SR18); 339 340 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20, restore->SR20); 341 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, restore->SR21); 342 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22, restore->SR22); 343 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23, restore->SR23); 344 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x24, restore->SR24); 345 346 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, restore->SR31); 347 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32, restore->SR32); 348 349 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66, restore->SR66); 350 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x68, restore->SR68); 351 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x69, restore->SR69); 352 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A, restore->SR6A); 353 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B, restore->SR6B); 354 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6C, restore->SR6C); 355 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6D, restore->SR6D); 356 357 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81, restore->SR81); 358 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0xA0, restore->SRA0); 359 360 if (pSmi->useBIOS && restore->mode != 0){ 361 pSmi->pInt10->num = 0x10; 362 pSmi->pInt10->ax = restore->mode | 0x80; 363 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode 0x%02X\n", 364 restore->mode); 365 xf86ExecX86int10(pSmi->pInt10); 366 367 /* Enable linear mode. */ 368 outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18); 369 tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA); 370 outb(pSmi->PIOBase + VGA_SEQ_DATA, tmp | 0x01); 371 372 /* Enable DPR/VPR registers. */ 373 tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); 374 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, tmp & ~0x03); 375 } else { 376 /* Restore the standard VGA registers */ 377 vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_ALL); 378 if (restore->smiDACMask) { 379 VGAOUT8(pSmi, VGA_DAC_MASK, restore->smiDACMask); 380 } else { 381 VGAOUT8(pSmi, VGA_DAC_MASK, 0xFF); 382 } 383 VGAOUT8(pSmi, VGA_DAC_WRITE_ADDR, 0); 384 for (i = 0; i < 256; i++) { 385 VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][0]); 386 VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][1]); 387 VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][2]); 388 } 389 for (i = 0, offset = 2; i < 8192; i++, offset += 8) { 390 *(pSmi->FBBase + offset) = restore->smiFont[i]; 391 } 392 393 if (SMI_LYNXM_SERIES(pSmi->Chipset)) { 394 /* Restore secondary registers */ 395 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, 396 restore->CR90[14] | 0x20); 397 398 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33_2); 399 for (i = 0; i < 14; i++) { 400 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i, 401 restore->CR40_2[i]); 402 } 403 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9F, restore->CR9F_2); 404 405 /* Restore primary registers */ 406 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, 407 restore->CR90[14] & ~0x20); 408 409 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33); 410 for (i = 0; i < 14; i++) { 411 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i, 412 restore->CR40[i]); 413 } 414 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9F, restore->CR9F); 415 416 /* Restore common registers */ 417 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x30, restore->CR30); 418 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A, restore->CR3A); 419 420 for (i = 0; i < 15; i++) 421 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x90 + i, 422 restore->CR90[i]); 423 424 for (i = 0; i < 14; i++) 425 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0xA0 + i, 426 restore->CRA0[i]); 427 428 }else{ 429 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x30, restore->CR30); 430 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33); 431 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A, restore->CR3A); 432 for (i = 0; i < 14; i++) { 433 VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i, 434 restore->CR40[i]); 435 } 436 } 437 438 if (pSmi->Dualhead) { 439 /* dualhead stuff */ 440 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x40, restore->SR40); 441 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x41, restore->SR41); 442 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x42, restore->SR42); 443 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x43, restore->SR43); 444 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x44, restore->SR44); 445 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x45, restore->SR45); 446 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x48, restore->SR48); 447 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x49, restore->SR49); 448 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4A, restore->SR4A); 449 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4B, restore->SR4B); 450 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4C, restore->SR4C); 451 452 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x50, restore->SR50); 453 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x51, restore->SR51); 454 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x52, restore->SR52); 455 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x53, restore->SR53); 456 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x54, restore->SR54); 457 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x55, restore->SR55); 458 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x56, restore->SR56); 459 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x57, restore->SR57); 460 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x5A, restore->SR5A); 461 462 /* PLL2 stuff */ 463 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6E, restore->SR6E); 464 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6F, restore->SR6F); 465 } 466 } 467 468 /* Reset the graphics engine */ 469 WRITE_DPR(pSmi, 0x10, restore->DPR10); 470 WRITE_DPR(pSmi, 0x1C, restore->DPR1C); 471 WRITE_DPR(pSmi, 0x20, restore->DPR20); 472 WRITE_DPR(pSmi, 0x24, restore->DPR24); 473 WRITE_DPR(pSmi, 0x28, restore->DPR28); 474 WRITE_DPR(pSmi, 0x2C, restore->DPR2C); 475 WRITE_DPR(pSmi, 0x30, restore->DPR30); 476 WRITE_DPR(pSmi, 0x3C, restore->DPR3C); 477 WRITE_DPR(pSmi, 0x40, restore->DPR40); 478 WRITE_DPR(pSmi, 0x44, restore->DPR44); 479 480 /* write video controller regs */ 481 WRITE_VPR(pSmi, 0x00, restore->VPR00); 482 WRITE_VPR(pSmi, 0x0C, restore->VPR0C); 483 WRITE_VPR(pSmi, 0x10, restore->VPR10); 484 485 if(pSmi->Chipset == SMI_COUGAR3DR) { 486 WRITE_FPR(pSmi, FPR00, restore->FPR00_); 487 WRITE_FPR(pSmi, FPR0C, restore->FPR0C_); 488 WRITE_FPR(pSmi, FPR10, restore->FPR10_); 489 } 490 491 WRITE_CPR(pSmi, 0x00, restore->CPR00); 492 493 if (xf86GetVerbosity() > 1) { 494 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV, 495 "Done restoring mode. Register dump:\n"); 496 SMI_PrintRegs(pScrn); 497 } 498 499 vgaHWProtect(pScrn, FALSE); 500 501 LEAVE(); 502} 503 504 505/* 506 * SMI_DisplayPowerManagementSet -- Sets VESA Display Power Management 507 * Signaling (DPMS) Mode. 508 */ 509void 510SMILynx_DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, 511 int flags) 512{ 513 SMIPtr pSmi = SMIPTR(pScrn); 514 SMIRegPtr mode = pSmi->mode; 515 vgaHWPtr hwp = VGAHWPTR(pScrn); 516 517 ENTER(); 518 519 /* If we already are in the requested DPMS mode, just return */ 520 if (pSmi->CurrentDPMS != PowerManagementMode) { 521 /* Read the required SR registers for the DPMS handler */ 522 CARD8 SR01 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01); 523 524 switch (PowerManagementMode) { 525 case DPMSModeOn: 526 SR01 &= ~0x20; /* Screen on */ 527 mode->SR23 &= ~0xC0; /* Disable chip activity detection */ 528 break; 529 case DPMSModeStandby: 530 case DPMSModeSuspend: 531 case DPMSModeOff: 532 SR01 |= 0x20; /* Screen off */ 533 mode->SR23 = (mode->SR23 & ~0x07) | 0xD8; /* Enable chip activity detection 534 Enable internal auto-standby mode 535 Enable both IO Write and Host Memory write detect 536 0 minutes timeout */ 537 break; 538 } 539 540 /* Wait for vertical retrace */ 541 while (hwp->readST01(hwp) & 0x8) ; 542 while (!(hwp->readST01(hwp) & 0x8)) ; 543 544 /* Write the registers */ 545 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01, SR01); 546 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23, mode->SR23); 547 548 /* Set the DPMS mode to every output and CRTC */ 549 xf86DPMSSet(pScrn, PowerManagementMode, flags); 550 551 /* Save the current power state */ 552 pSmi->CurrentDPMS = PowerManagementMode; 553 } 554 555 LEAVE(); 556} 557 558static unsigned int 559SMILynx_ddc1Read(ScrnInfoPtr pScrn) 560{ 561 register vgaHWPtr hwp = VGAHWPTR(pScrn); 562 SMIPtr pSmi = SMIPTR(pScrn); 563 unsigned int ret; 564 565 ENTER(); 566 567 while (hwp->readST01(hwp) & 0x8) ; 568 while (!(hwp->readST01(hwp) & 0x8)) ; 569 570 ret = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72) & 0x08; 571 572 LEAVE(ret); 573} 574 575xf86MonPtr 576SMILynx_ddc1(ScrnInfoPtr pScrn) 577{ 578 SMIPtr pSmi = SMIPTR(pScrn); 579 xf86MonPtr pMon; 580 unsigned char tmp; 581 582 ENTER(); 583 584 tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72); 585 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72, tmp | 0x20); 586 587 pMon = xf86PrintEDID(xf86DoEDID_DDC1(pScrn->scrnIndex, 588 vgaHWddc1SetSpeedWeak(), 589 SMILynx_ddc1Read)); 590 VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72, tmp); 591 592 LEAVE(pMon); 593} 594 595 596/* This function is used to debug, it prints out the contents of Lynx regs */ 597void 598SMILynx_PrintRegs(ScrnInfoPtr pScrn) 599{ 600 unsigned char i; 601 SMIPtr pSmi = SMIPTR(pScrn); 602 vgaHWPtr hwp = VGAHWPTR(pScrn); 603 int vgaCRIndex = hwp->IOBase + VGA_CRTC_INDEX_OFFSET; 604 int vgaCRReg = hwp->IOBase + VGA_CRTC_DATA_OFFSET; 605 int vgaStatus = hwp->IOBase + VGA_IN_STAT_1_OFFSET; 606 607 xf86ErrorFVerb(VERBLEV, "MISCELLANEOUS OUTPUT\n %02X\n", 608 VGAIN8(pSmi, VGA_MISC_OUT_R)); 609 610 xf86ErrorFVerb(VERBLEV, "\nSEQUENCER\n" 611 " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); 612 for (i = 0x00; i <= 0xAF; i++) { 613 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 614 if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); 615 xf86ErrorFVerb(VERBLEV, "%02X ", 616 VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, i)); 617 } 618 619 xf86ErrorFVerb(VERBLEV, "\n\nCRT CONTROLLER\n" 620 " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); 621 for (i = 0x00; i <= 0xAD; i++) { 622 if (i == 0x20) i = 0x30; 623 if (i == 0x50) i = 0x90; 624 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 625 if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); 626 xf86ErrorFVerb(VERBLEV, "%02X ", 627 VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRReg, i)); 628 } 629 630 xf86ErrorFVerb(VERBLEV, "\n\nGRAPHICS CONTROLLER\n" 631 " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); 632 for (i = 0x00; i <= 0x08; i++) { 633 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 634 if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); 635 xf86ErrorFVerb(VERBLEV, "%02X ", 636 VGAIN8_INDEX(pSmi, VGA_GRAPH_INDEX, VGA_GRAPH_DATA, i)); 637 } 638 639 xf86ErrorFVerb(VERBLEV, "\n\nATTRIBUTE 0CONTROLLER\n" 640 " x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF"); 641 for (i = 0x00; i <= 0x14; i++) { 642 (void) VGAIN8(pSmi, vgaStatus); 643 if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i); 644 if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " "); 645 xf86ErrorFVerb(VERBLEV, "%02X ", 646 VGAIN8_INDEX(pSmi, VGA_ATTR_INDEX, VGA_ATTR_DATA_R, i)); 647 } 648 (void) VGAIN8(pSmi, vgaStatus); 649 VGAOUT8(pSmi, VGA_ATTR_INDEX, 0x20); 650} 651