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