1/* 2 * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 3 * Copyright (c) 2003-2006, X.Org Foundation 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 * COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 * 23 * Except as contained in this notice, the name of the copyright holder(s) 24 * and author(s) shall not be used in advertising or otherwise to promote 25 * the sale, use or other dealings in this Software without prior written 26 * authorization from the copyright holder(s) and author(s). 27 */ 28 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32 33#include <X11/extensions/Xv.h> 34#include "dix.h" 35#include "dixstruct.h" 36 37#include "savage_driver.h" 38#include "savage_streams.h" 39 40#define STREAMS_TRACE 4 41 42static void OverlayTwisterInit(ScrnInfoPtr pScrn); 43static void OverlayParamInit(ScrnInfoPtr pScrn); 44static void InitStreamsForExpansion(ScrnInfoPtr pScrn); 45static void PatchEnableSPofPanel(ScrnInfoPtr pScrn); 46 47static void 48SavageInitSecondaryStreamOld(ScrnInfoPtr pScrn) 49{ 50 SavagePtr psav = SAVPTR(pScrn); 51 vgaHWPtr hwp; 52 unsigned short vgaIOBase, vgaCRIndex, vgaCRReg; 53 int offset = (psav->FBStart2nd - psav->FBStart); 54 int colorkey = pScrn->colorKey; 55 int pitch = pScrn->displayWidth * DEPTH_BPP(DEPTH_2ND(pScrn))/8; 56 CARD8 cr92; 57 58 hwp = VGAHWPTR(pScrn); 59 vgaHWGetIOBase(hwp); 60 vgaIOBase = hwp->IOBase; 61 vgaCRIndex = vgaIOBase + 4; 62 vgaCRReg = vgaIOBase + 5; 63 64 OUTREG(COL_CHROMA_KEY_CONTROL_REG, 0x37000000 | (colorkey & 0xFF)); 65 OUTREG(CHROMA_KEY_UPPER_BOUND_REG, 0x00000000 | (colorkey & 0xFF)); 66 OUTREG(BLEND_CONTROL_REG, 0x05000000 ); 67 OUTREG(SSTREAM_CONTROL_REG, SSTREAMS_MODE(DEPTH_BPP(DEPTH_2ND(pScrn))) 68 << 24 | pScrn->displayWidth ); 69 OUTREG(SSTREAM_STRETCH_REG, 1 << 15); 70 OUTREG(SSTREAM_VSCALE_REG, 1 << 15); 71 OUTREG(SSTREAM_LINES_REG, pScrn->virtualY ); 72 OUTREG(SSTREAM_VINITIAL_REG, 0 ); 73 OUTREG(SSTREAM_FBADDR0_REG, offset & 0x1ffffff & ~BASE_PAD); 74 OUTREG(SSTREAM_FBADDR1_REG, 0 ); 75 76 OUTREG(SSTREAM_STRIDE_REG, pitch); 77 OUTREG(SSTREAM_WINDOW_START_REG, OS_XY(0,0)); 78 OUTREG(SSTREAM_WINDOW_SIZE_REG, 79 OS_WH(pScrn->displayWidth, pScrn->virtualY)); 80 81 pitch = (pitch + 7) / 8; 82 VGAOUT8(vgaCRIndex, 0x92); 83 cr92 = VGAIN8(vgaCRReg); 84 VGAOUT8(vgaCRReg, (cr92 & 0x40) | (pitch >> 8) | 0x80); 85 VGAOUT8(vgaCRIndex, 0x93); 86 VGAOUT8(vgaCRReg, pitch); 87 OUTREG(STREAMS_FIFO_REG, 2 | 25 << 5 | 32 << 11); 88} 89 90static void 91SavageInitSecondaryStreamNew(ScrnInfoPtr pScrn) 92{ 93 SavagePtr psav = SAVPTR(pScrn); 94 vgaHWPtr hwp; 95 unsigned short vgaIOBase, vgaCRIndex, vgaCRReg; 96 int offset = (psav->FBStart2nd - psav->FBStart); 97 int colorkey = pScrn->colorKey; 98 int pitch = pScrn->displayWidth * DEPTH_BPP(DEPTH_2ND(pScrn))/8; 99 CARD8 cr92; 100 101 hwp = VGAHWPTR(pScrn); 102 103 vgaHWGetIOBase(hwp); 104 vgaIOBase = hwp->IOBase; 105 vgaCRIndex = vgaIOBase + 4; 106 vgaCRReg = vgaIOBase + 5; 107 108 OUTREG( SEC_STREAM_CKEY_LOW, 0x47000000 | (colorkey & 0xFF)); 109 OUTREG( SEC_STREAM_CKEY_UPPER, 0x47000000 | (colorkey & 0xFF)); 110 OUTREG( BLEND_CONTROL, SSTREAMS_MODE(DEPTH_BPP(DEPTH_2ND(pScrn))) << 9 111 | 0x08 ); 112 if( psav->Chipset == S3_SAVAGE2000 ) { 113 OUTREG(SEC_STREAM_HSCALING, 1 << 15); 114 OUTREG(SEC_STREAM_HSCALE_NORMALIZE, 2048 << 16 ); 115 OUTREG(SEC_STREAM_VSCALING, 1 << 15); 116 } else { 117 OUTREG(SEC_STREAM_HSCALING,((pScrn->displayWidth &0xfff)<<20) | 1<<15); 118 /* BUGBUG need to add 00040000 if src stride > 2048 */ 119 OUTREG(SEC_STREAM_VSCALING,((pScrn->virtualY &0xfff)<<20) | 1<<15); 120 } 121 122 OUTREG(SEC_STREAM_FBUF_ADDR0, offset & (0x7ffffff & ~BASE_PAD)); 123 OUTREG(SEC_STREAM_STRIDE, pitch); 124 OUTREG(SEC_STREAM_WINDOW_START, OS_XY(0,0)); 125 /* ? width may need to be increased by 1 */ 126 OUTREG(SEC_STREAM_WINDOW_SZ, OS_WH(pScrn->displayWidth, pScrn->virtualY)); 127 128 pitch = (pitch + 7) / 8; 129 VGAOUT8(vgaCRIndex, 0x92); 130 cr92 = VGAIN8(vgaCRReg); 131 VGAOUT8(vgaCRReg, (cr92 & 0x40) | (pitch >> 8) | 0x80); 132 VGAOUT8(vgaCRIndex, 0x93); 133 VGAOUT8(vgaCRReg, pitch); 134} 135 136void 137SavageInitSecondaryStream(ScrnInfoPtr pScrn) 138{ 139 SavagePtr psav = SAVPTR(pScrn); 140 141 if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) || 142 (psav->Chipset == S3_SAVAGE2000) ) 143 SavageInitSecondaryStreamNew(pScrn); 144 else 145 SavageInitSecondaryStreamOld(pScrn); 146} 147 148void SavageInitStreamsOld(ScrnInfoPtr pScrn) 149{ 150 SavagePtr psav = SAVPTR(pScrn); 151 /*unsigned long jDelta;*/ 152 unsigned long format = 0; 153 154 /* 155 * For the OLD streams engine, several of these registers 156 * cannot be touched unless streams are on. Seems backwards to me; 157 * I'd want to set 'em up, then cut 'em loose. 158 */ 159 160 xf86ErrorFVerb(STREAMS_TRACE, "SavageInitStreams\n" ); 161 162 if (psav->FBStart2nd) { 163 unsigned long jDelta = pScrn->displayWidth; 164 format = 0 << 24; 165 OUTREG( PSTREAM_STRIDE_REG, jDelta ); 166 OUTREG( PSTREAM_FBSIZE_REG, jDelta * pScrn->virtualY >> 3 ); 167 OUTREG( PSTREAM_FBADDR0_REG, pScrn->fbOffset ); 168 OUTREG( PSTREAM_FBADDR1_REG, 0 ); 169 } else { 170 /*jDelta = pScrn->displayWidth * (pScrn->bitsPerPixel + 7) / 8;*/ 171 switch( pScrn->depth ) { 172 case 8: format = 0 << 24; break; 173 case 15: format = 3 << 24; break; 174 case 16: format = 5 << 24; break; 175 case 24: format = 7 << 24; break; 176 } 177 OUTREG(PSTREAM_FBSIZE_REG, 178 pScrn->virtualY * pScrn->virtualX * (pScrn->bitsPerPixel >> 3)); 179 } 180 181 OUTREG(FIFO_CONTROL, 0x18ffeL); 182 183 OUTREG( PSTREAM_WINDOW_START_REG, OS_XY(0,0) ); 184 OUTREG( PSTREAM_WINDOW_SIZE_REG, OS_WH(pScrn->displayWidth, pScrn->virtualY) ); 185/* OUTREG( PSTREAM_FBADDR0_REG, pScrn->fbOffset ); 186 OUTREG( PSTREAM_FBADDR1_REG, 0 ); */ 187 /*OUTREG( PSTREAM_STRIDE_REG, jDelta );*/ 188 OUTREG( PSTREAM_CONTROL_REG, format ); 189 /*OUTREG( PSTREAM_FBSIZE_REG, jDelta * pScrn->virtualY >> 3 );*/ 190 191 OUTREG( COL_CHROMA_KEY_CONTROL_REG, 0 ); 192 OUTREG( SSTREAM_CONTROL_REG, 0 ); 193 OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 0 ); 194 OUTREG( SSTREAM_STRETCH_REG, 0 ); 195 OUTREG( COLOR_ADJUSTMENT_REG, 0 ); 196 OUTREG( BLEND_CONTROL_REG, 1 << 24 ); 197 OUTREG( DOUBLE_BUFFER_REG, 0 ); 198 OUTREG( SSTREAM_FBADDR0_REG, 0 ); 199 OUTREG( SSTREAM_FBADDR1_REG, 0 ); 200 OUTREG( SSTREAM_FBADDR2_REG, 0 ); 201 OUTREG( SSTREAM_FBSIZE_REG, 0 ); 202 OUTREG( SSTREAM_STRIDE_REG, 0 ); 203 OUTREG( SSTREAM_VSCALE_REG, 0 ); 204 OUTREG( SSTREAM_LINES_REG, 0 ); 205 OUTREG( SSTREAM_VINITIAL_REG, 0 ); 206 OUTREG( SSTREAM_WINDOW_START_REG, OS_XY(0xfffe, 0xfffe) ); 207 OUTREG( SSTREAM_WINDOW_SIZE_REG, OS_WH(10,2) ); 208 209 if (S3_MOBILE_TWISTER_SERIES(psav->Chipset) && 210 psav->FPExpansion) { 211 OverlayTwisterInit(pScrn); 212 } 213} 214 215void SavageInitStreamsNew(ScrnInfoPtr pScrn) 216{ 217 SavagePtr psav = SAVPTR(pScrn); 218 /*unsigned long jDelta;*/ 219 220 xf86ErrorFVerb(STREAMS_TRACE, "SavageInitStreams\n" ); 221 222 if ( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) && 223 (psav->DisplayType == MT_LCD) && 224 !psav->CrtOnly && 225 !psav->TvOn ) 226 { 227 OverlayParamInit( pScrn ); 228 } 229 230 if (psav->IsSecondary) { 231 OUTREG(PRI_STREAM2_BUFFERSIZE, 232 pScrn->virtualX * pScrn->virtualY * (pScrn->bitsPerPixel >> 3)); 233 } else if (psav->IsPrimary){ 234 OUTREG(PRI_STREAM_BUFFERSIZE, 235 pScrn->virtualX * pScrn->virtualY * (pScrn->bitsPerPixel >> 3)); 236 } else { 237 OUTREG(PRI_STREAM_BUFFERSIZE, 238 pScrn->virtualX * pScrn->virtualY * (pScrn->bitsPerPixel >> 3)); 239#if 0 240 OUTREG(PRI_STREAM2_BUFFERSIZE, 241 pScrn->virtualX * pScrn->virtualY * (pScrn->bitsPerPixel >> 3)); 242#endif 243 } 244 245 if (psav->FBStart2nd) { 246 unsigned long jDelta = pScrn->displayWidth; 247 OUTREG( PRI_STREAM_BUFFERSIZE, jDelta * pScrn->virtualY >> 3 ); 248 OUTREG( PRI_STREAM_FBUF_ADDR0, pScrn->fbOffset ); 249 OUTREG( PRI_STREAM_STRIDE, jDelta ); 250 } 251 252 if (psav->IsSecondary) { 253 OUTREG( SEC_STREAM2_CKEY_LOW, 0 ); 254 OUTREG( SEC_STREAM2_CKEY_UPPER, 0 ); 255 OUTREG( SEC_STREAM2_HSCALING, 0 ); 256 OUTREG( SEC_STREAM2_VSCALING, 0 ); 257 OUTREG( BLEND_CONTROL, 0 ); 258 OUTREG( SEC_STREAM2_FBUF_ADDR0, 0 ); 259 OUTREG( SEC_STREAM2_FBUF_ADDR1, 0 ); 260 OUTREG( SEC_STREAM2_FBUF_ADDR2, 0 ); 261 OUTREG( SEC_STREAM2_WINDOW_START, 0 ); 262 OUTREG( SEC_STREAM2_WINDOW_SZ, 0 ); 263/* OUTREG( SEC_STREAM2_BUFFERSIZE, 0 ); */ 264 OUTREG( SEC_STREAM2_OPAQUE_OVERLAY, 0 ); 265 OUTREG( SEC_STREAM2_STRIDE_LPB, 0 ); 266 267 /* These values specify brightness, contrast, saturation and hue. */ 268 OUTREG( SEC_STREAM2_COLOR_CONVERT1, 0x0000C892 ); 269 OUTREG( SEC_STREAM2_COLOR_CONVERT2, 0x00039F9A ); 270 OUTREG( SEC_STREAM2_COLOR_CONVERT3, 0x01F1547E ); 271 } else if (psav->IsPrimary) { 272 OUTREG( SEC_STREAM_CKEY_LOW, 0 ); 273 OUTREG( SEC_STREAM_CKEY_UPPER, 0 ); 274 OUTREG( SEC_STREAM_HSCALING, 0 ); 275 OUTREG( SEC_STREAM_VSCALING, 0 ); 276 OUTREG( BLEND_CONTROL, 0 ); 277 OUTREG( SEC_STREAM_FBUF_ADDR0, 0 ); 278 OUTREG( SEC_STREAM_FBUF_ADDR1, 0 ); 279 OUTREG( SEC_STREAM_FBUF_ADDR2, 0 ); 280 OUTREG( SEC_STREAM_WINDOW_START, 0 ); 281 OUTREG( SEC_STREAM_WINDOW_SZ, 0 ); 282/* OUTREG( SEC_STREAM_BUFFERSIZE, 0 ); */ 283 OUTREG( SEC_STREAM_TILE_OFF, 0 ); 284 OUTREG( SEC_STREAM_OPAQUE_OVERLAY, 0 ); 285 OUTREG( SEC_STREAM_STRIDE, 0 ); 286 287 /* These values specify brightness, contrast, saturation and hue. */ 288 OUTREG( SEC_STREAM_COLOR_CONVERT1, 0x0000C892 ); 289 OUTREG( SEC_STREAM_COLOR_CONVERT2, 0x00039F9A ); 290 OUTREG( SEC_STREAM_COLOR_CONVERT3, 0x01F1547E ); 291 } else { 292 OUTREG( SEC_STREAM_CKEY_LOW, 0 ); 293 OUTREG( SEC_STREAM_CKEY_UPPER, 0 ); 294 OUTREG( SEC_STREAM_HSCALING, 0 ); 295 OUTREG( SEC_STREAM_VSCALING, 0 ); 296 OUTREG( BLEND_CONTROL, 0 ); 297 OUTREG( SEC_STREAM_FBUF_ADDR0, 0 ); 298 OUTREG( SEC_STREAM_FBUF_ADDR1, 0 ); 299 OUTREG( SEC_STREAM_FBUF_ADDR2, 0 ); 300 OUTREG( SEC_STREAM_WINDOW_START, 0 ); 301 OUTREG( SEC_STREAM_WINDOW_SZ, 0 ); 302/* OUTREG( SEC_STREAM_BUFFERSIZE, 0 ); */ 303 OUTREG( SEC_STREAM_TILE_OFF, 0 ); 304 OUTREG( SEC_STREAM_OPAQUE_OVERLAY, 0 ); 305 OUTREG( SEC_STREAM_STRIDE, 0 ); 306 307 /* These values specify brightness, contrast, saturation and hue. */ 308 OUTREG( SEC_STREAM_COLOR_CONVERT1, 0x0000C892 ); 309 OUTREG( SEC_STREAM_COLOR_CONVERT2, 0x00039F9A ); 310 OUTREG( SEC_STREAM_COLOR_CONVERT3, 0x01F1547E ); 311#if 0 312 sleep(1); 313 OUTREG( SEC_STREAM2_CKEY_LOW, 0 ); 314 OUTREG( SEC_STREAM2_CKEY_UPPER, 0 ); 315 OUTREG( SEC_STREAM2_HSCALING, 0 ); 316 OUTREG( SEC_STREAM2_VSCALING, 0 ); 317 OUTREG( BLEND_CONTROL, 0 ); 318 OUTREG( SEC_STREAM2_FBUF_ADDR0, 0 ); 319 OUTREG( SEC_STREAM2_FBUF_ADDR1, 0 ); 320 OUTREG( SEC_STREAM2_FBUF_ADDR2, 0 ); 321 OUTREG( SEC_STREAM2_WINDOW_START, 0 ); 322 OUTREG( SEC_STREAM2_WINDOW_SZ, 0 ); 323/* OUTREG( SEC_STREAM2_BUFFERSIZE, 0 ); */ 324 OUTREG( SEC_STREAM2_OPAQUE_OVERLAY, 0 ); 325 OUTREG( SEC_STREAM2_STRIDE_LPB, 0 ); 326 327 /* These values specify brightness, contrast, saturation and hue. */ 328 OUTREG( SEC_STREAM2_COLOR_CONVERT1, 0x0000C892 ); 329 OUTREG( SEC_STREAM2_COLOR_CONVERT2, 0x00039F9A ); 330 OUTREG( SEC_STREAM2_COLOR_CONVERT3, 0x01F1547E ); 331#endif 332 } 333} 334 335void SavageInitStreams2000(ScrnInfoPtr pScrn) 336{ 337 SavagePtr psav = SAVPTR(pScrn); 338 /*unsigned long jDelta;*/ 339 340 xf86ErrorFVerb(STREAMS_TRACE, "SavageInitStreams\n" ); 341 342 OUTREG(PRI_STREAM_BUFFERSIZE, 343 pScrn->virtualX * pScrn->virtualY * (pScrn->bitsPerPixel >> 3)); 344 OUTREG(PRI_STREAM2_BUFFERSIZE, 345 pScrn->virtualX * pScrn->virtualY * (pScrn->bitsPerPixel >> 3)); 346 347 348 if (psav->FBStart2nd) { 349 unsigned long jDelta = pScrn->displayWidth; 350 OUTREG( PRI_STREAM_BUFFERSIZE, jDelta * pScrn->virtualY >> 3 ); 351 OUTREG( PRI_STREAM_FBUF_ADDR0, pScrn->fbOffset ); 352 OUTREG( PRI_STREAM_STRIDE, jDelta ); 353 } 354 355 356 OUTREG( SEC_STREAM_CKEY_LOW, (4L << 29) ); 357 OUTREG( SEC_STREAM_CKEY_UPPER, 0 ); 358 OUTREG( SEC_STREAM_HSCALING, 0 ); 359 OUTREG( SEC_STREAM_VSCALING, 0 ); 360 OUTREG(SEC_STREAM2_STRIDE_LPB, 0); 361 OUTREG( BLEND_CONTROL, 0 ); 362 OUTREG( SEC_STREAM_FBUF_ADDR0, 0 ); 363 OUTREG( SEC_STREAM_FBUF_ADDR1, 0 ); 364 OUTREG( SEC_STREAM_FBUF_ADDR2, 0 ); 365 OUTREG( SEC_STREAM_WINDOW_START, 0 ); 366 OUTREG( SEC_STREAM_WINDOW_SZ, 0 ); 367/* OUTREG( SEC_STREAM_BUFFERSIZE, 0 ); */ 368 OUTREG( SEC_STREAM_TILE_OFF, 0 ); 369 OUTREG( SEC_STREAM_OPAQUE_OVERLAY, 0 ); 370 OUTREG( SEC_STREAM_STRIDE, 0 ); 371 372 /* FIFO related regs */ 373 OUTREG8(CRT_ADDRESS_REG,0x86); 374 OUTREG8(CRT_DATA_REG,0x2c); 375 376 OUTREG8(CRT_ADDRESS_REG,0x87); 377 OUTREG8(CRT_DATA_REG,0xf8); 378 379 OUTREG8(CRT_ADDRESS_REG,0x89); 380 OUTREG8(CRT_DATA_REG,0x40); 381 382 383 /* These values specify brightness, contrast, saturation and hue. */ 384 OUTREG( SEC_STREAM_COLOR_CONVERT0_2000, 0x640092 /*0x0000C892*/ ); 385 OUTREG( SEC_STREAM_COLOR_CONVERT1_2000, 0x19a0000 /*0x00033400*/ ); 386 OUTREG( SEC_STREAM_COLOR_CONVERT2_2000, 0x001cf /*0x000001CF*/ ); 387 OUTREG( SEC_STREAM_COLOR_CONVERT3_2000, 0xF8CA007E /*0x01F1547E*/ ); 388 389} 390 391/* 392 * Function to get lcd factor, display offset for overlay use 393 * Input: pScrn; Output: x,yfactor, displayoffset in pScrn 394 */ 395static void OverlayTwisterInit(ScrnInfoPtr pScrn) 396{ 397 SavagePtr psav = SAVPTR(pScrn); 398 399 psav->cxScreen = psav->iResX; 400 InitStreamsForExpansion(pScrn); 401 PatchEnableSPofPanel(pScrn); 402} 403 404/* Function to get lcd factor, display offset for overlay use 405 * Input: pScrn; Output: x,yfactor, displayoffset in pScrn 406 */ 407static void OverlayParamInit(ScrnInfoPtr pScrn) 408{ 409 SavagePtr psav = SAVPTR(pScrn); 410 411 psav = SAVPTR(pScrn); 412 psav->cxScreen = pScrn->currentMode->HDisplay; 413 InitStreamsForExpansion(pScrn); 414} 415 416static 417void PatchEnableSPofPanel(ScrnInfoPtr pScrn) 418{ 419 SavagePtr psav = SAVPTR(pScrn); 420 421 UnLockExtRegs(); 422 423 if (pScrn->bitsPerPixel == 8) { 424 OUTREG8(CRT_ADDRESS_REG,0x90); 425 OUTREG8(CRT_DATA_REG,INREG8(CRT_DATA_REG)|0x40); 426 } 427 else { 428 OUTREG8(CRT_ADDRESS_REG,0x90); 429 OUTREG8(CRT_DATA_REG,INREG8(CRT_DATA_REG)|0x48); 430 } 431 432 VerticalRetraceWait(); 433 434 OUTREG8(CRT_ADDRESS_REG,0x67); 435 OUTREG8(CRT_DATA_REG,(INREG8(CRT_DATA_REG)&0xf3)|0x04); 436 437 OUTREG8(CRT_ADDRESS_REG,0x65); 438 OUTREG8(CRT_DATA_REG,INREG8(CRT_DATA_REG)|0xC0); 439 440 if (pScrn->bitsPerPixel == 8) { 441 OUTREG32(PSTREAM_CONTROL_REG,0x00000000); 442 } else { 443 OUTREG32(PSTREAM_CONTROL_REG,0x02000000); 444 } 445 446 OUTREG32(PSTREAM_WINDOW_SIZE_REG, 0x0); 447 /*OUTREG32(PSTREAM_WINDOW_SIZE_REG, OS_WH(pScrn->displayWidth, pScrn->virtualY));*/ 448 449} 450 451 452/* Function to calculate lcd expansion x,y factor and offset for overlay 453 */ 454static void InitStreamsForExpansion(ScrnInfoPtr pScrn) 455{ 456 SavagePtr psav = SAVPTR(pScrn); 457 int PanelSizeX,PanelSizeY; 458 int ViewPortWidth,ViewPortHeight; 459 int XExpansion, YExpansion; 460 int XFactor, YFactor; 461 int Hstate, Vstate; 462 463 static CARD32 Xfactors[] = { 464 0x00010001, 465 0x00010001, /* 1 */ 466 0, 467 0x00090008, /* 3 */ 468 0x00050004, /* 4 */ 469 0, 470 0x00030002, /* 6 */ 471 0x00020001 /* 7 */ 472 }; 473 474 static CARD32 Yfactors[] = { 475 0x00010001, 0x00010001, 476 0, 0x00060005, 477 0x00050004, 0x00040003, 478 0, 0x00030002, 479 0x00020001, 0x00050002, 480 0x000C0005, 0x00080003, 481 0x00090004, 0, 482 0x00030001, 0x00040001, 483 }; 484 485 486 487 PanelSizeX = psav->PanelX; 488 PanelSizeY = psav->PanelY; 489 ViewPortWidth = pScrn->currentMode->HDisplay; 490 ViewPortHeight = pScrn->currentMode->VDisplay; 491 492 if( PanelSizeX == 1408 ) 493 PanelSizeX = 1400; 494 495 XExpansion = 0x00010001; 496 YExpansion = 0x00010001; 497 498 psav->displayXoffset = 0; 499 psav->displayYoffset = 0; 500 501 VGAOUT8(0x3C4, HZEXP_COMP_1); 502 Hstate = VGAIN8(0x3C5); 503 VGAOUT8(0x3C4, VTEXP_COMP_1); 504 Vstate = VGAIN8(0x3C5); 505 VGAOUT8(0x3C4, HZEXP_FACTOR_IGA1); 506 XFactor = VGAIN8(0x3C5); 507 VGAOUT8(0x3C4, VTEXP_FACTOR_IGA1); 508 YFactor = VGAIN8(0x3C5); 509 510 if( Hstate & EC1_EXPAND_ON ) 511 { 512 XExpansion = Xfactors[XFactor>>4]; 513 } 514 515 if( Vstate & EC1_EXPAND_ON ) 516 { 517 YExpansion = Yfactors[YFactor>>4]; 518 } 519 520 psav->XExp1 = XExpansion >> 16; 521 psav->XExp2 = XExpansion & 0xFFFF; 522 523 psav->YExp1 = YExpansion >> 16; 524 psav->YExp2 = YExpansion & 0xFFFF; 525 526 psav->displayXoffset = 527 ((PanelSizeX - (psav->XExp1 * ViewPortWidth) / psav->XExp2) / 2 + 7) & 0xfff8; 528 psav->displayYoffset = 529 ((PanelSizeY - (psav->YExp1 * ViewPortHeight) / psav->YExp2) / 2); 530 531} /* InitStreamsForExpansionPM */ 532 533void 534SavageStreamsOn(ScrnInfoPtr pScrn) 535{ 536 SavagePtr psav = SAVPTR(pScrn); 537 unsigned char jStreamsControl; 538 unsigned short vgaCRIndex = psav->vgaIOBase + 4; 539 unsigned short vgaCRReg = psav->vgaIOBase + 5; 540 541 xf86ErrorFVerb(STREAMS_TRACE, "SavageStreamsOn\n" ); 542 543 /* Sequence stolen from streams.c in M7 NT driver */ 544 545 546 xf86EnableIO(); 547 548 /* Unlock extended registers. */ 549 550 VGAOUT16(vgaCRIndex, 0x4838); 551 VGAOUT16(vgaCRIndex, 0xa039); 552 VGAOUT16(0x3c4, 0x0608); 553 554 VGAOUT8( vgaCRIndex, EXT_MISC_CTRL2 ); 555 556 if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ) 557 { 558 SavageInitStreamsNew( pScrn ); 559 560 jStreamsControl = VGAIN8( vgaCRReg ) | ENABLE_STREAM1; 561 562 if (psav->IsSecondary) { 563 SelectIGA2(); 564 /* Wait for VBLANK. */ 565 VerticalRetraceWait(); 566 /* Fire up streams! */ 567 VGAOUT16( vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2 ); 568 SelectIGA1(); 569 /* These values specify brightness, contrast, saturation and hue. */ 570 OUTREG( SEC_STREAM2_COLOR_CONVERT1, 0x0000C892 ); 571 OUTREG( SEC_STREAM2_COLOR_CONVERT2, 0x00039F9A ); 572 OUTREG( SEC_STREAM2_COLOR_CONVERT3, 0x01F1547E ); 573 } else if (psav->IsPrimary) { 574 /* Wait for VBLANK. */ 575 VerticalRetraceWait(); 576 /* Fire up streams! */ 577 VGAOUT16( vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2 ); 578 /* These values specify brightness, contrast, saturation and hue. */ 579 OUTREG( SEC_STREAM_COLOR_CONVERT1, 0x0000C892 ); 580 OUTREG( SEC_STREAM_COLOR_CONVERT2, 0x00039F9A ); 581 OUTREG( SEC_STREAM_COLOR_CONVERT3, 0x01F1547E ); 582 } else { 583 /* Wait for VBLANK. */ 584 VerticalRetraceWait(); 585 /* Fire up streams! */ 586 VGAOUT16( vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2 ); 587#if 0 588 SelectIGA2(); 589 /* Wait for VBLANK. */ 590 VerticalRetraceWait(); 591 /* Fire up streams! */ 592 VGAOUT16( vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2 ); 593 SelectIGA1(); 594#endif 595 /* These values specify brightness, contrast, saturation and hue. */ 596 OUTREG( SEC_STREAM_COLOR_CONVERT1, 0x0000C892 ); 597 OUTREG( SEC_STREAM_COLOR_CONVERT2, 0x00039F9A ); 598 OUTREG( SEC_STREAM_COLOR_CONVERT3, 0x01F1547E ); 599#if 0 600 sleep(1); 601 OUTREG( SEC_STREAM2_COLOR_CONVERT1, 0x0000C892 ); 602 OUTREG( SEC_STREAM2_COLOR_CONVERT2, 0x00039F9A ); 603 OUTREG( SEC_STREAM2_COLOR_CONVERT3, 0x01F1547E ); 604#endif 605 } 606 } 607 else if (psav->Chipset == S3_SAVAGE2000) 608 { 609 SavageInitStreams2000( pScrn ); 610 611 jStreamsControl = VGAIN8( vgaCRReg ) | ENABLE_STREAM1; 612 613 /* Wait for VBLANK. */ 614 VerticalRetraceWait(); 615 /* Fire up streams! */ 616 VGAOUT16( vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2 ); 617 /* These values specify brightness, contrast, saturation and hue. */ 618 OUTREG( SEC_STREAM_COLOR_CONVERT0_2000, 0x0000C892 ); 619 OUTREG( SEC_STREAM_COLOR_CONVERT1_2000, 0x00033400 ); 620 OUTREG( SEC_STREAM_COLOR_CONVERT2_2000, 0x000001CF ); 621 OUTREG( SEC_STREAM_COLOR_CONVERT3_2000, 0x01F1547E ); 622 } 623 else 624 { 625 jStreamsControl = VGAIN8( vgaCRReg ) | ENABLE_STREAMS_OLD; 626 627 /* Wait for VBLANK. */ 628 629 VerticalRetraceWait(); 630 631 /* Fire up streams! */ 632 633 VGAOUT16( vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2 ); 634 635 SavageInitStreamsOld( pScrn ); 636 } 637 638 /* Wait for VBLANK. */ 639 640 VerticalRetraceWait(); 641 642 /* Turn on secondary stream TV flicker filter, once we support TV. */ 643 644 /* SR70 |= 0x10 */ 645 646 psav->videoFlags |= VF_STREAMS_ON; 647 648} 649 650void 651SavageStreamsOff(ScrnInfoPtr pScrn) 652{ 653 SavagePtr psav = SAVPTR(pScrn); 654 unsigned char jStreamsControl; 655 unsigned short vgaCRIndex = psav->vgaIOBase + 4; 656 unsigned short vgaCRReg = psav->vgaIOBase + 5; 657 658 xf86ErrorFVerb(STREAMS_TRACE, "SavageStreamsOff\n" ); 659 660 xf86EnableIO(); 661 662 /* Unlock extended registers. */ 663 664 VGAOUT16(vgaCRIndex, 0x4838); 665 VGAOUT16(vgaCRIndex, 0xa039); 666 VGAOUT16(0x3c4, 0x0608); 667 668 VGAOUT8( vgaCRIndex, EXT_MISC_CTRL2 ); 669 if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) || 670 (psav->Chipset == S3_SAVAGE2000) ) 671 jStreamsControl = VGAIN8( vgaCRReg ) & NO_STREAMS; 672 else 673 jStreamsControl = VGAIN8( vgaCRReg ) & NO_STREAMS_OLD; 674 675 /* Wait for VBLANK. */ 676 677 VerticalRetraceWait(); 678 679 /* Kill streams. */ 680 if (psav->IsSecondary) { 681 SelectIGA2(); 682 VGAOUT16( vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2 ); 683 SelectIGA1(); 684 } else if (psav->IsPrimary) { 685 VGAOUT16( vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2 ); 686 } else { 687 VGAOUT16( vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2 ); 688#if 0 689 SelectIGA2(); 690 VGAOUT16( vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2 ); 691 SelectIGA1(); 692#endif 693 } 694 695 VGAOUT16( vgaCRIndex, 0x0093 ); 696 VGAOUT8( vgaCRIndex, 0x92 ); 697 VGAOUT8( vgaCRReg, VGAIN8(vgaCRReg) & 0x40 ); 698 699 psav->videoFlags &= ~VF_STREAMS_ON; 700 701} 702 703