summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/savage_streams.c32
-rw-r--r--src/savage_streams.h13
-rw-r--r--src/savage_video.c221
3 files changed, 207 insertions, 59 deletions
diff --git a/src/savage_streams.c b/src/savage_streams.c
index 8b6d560..2fe2c25 100644
--- a/src/savage_streams.c
+++ b/src/savage_streams.c
@@ -145,6 +145,8 @@ void SavageInitStreamsOld(ScrnInfoPtr pScrn)
OUTREG(PSTREAM_FBSIZE_REG,
pScrn->virtualY * pScrn->virtualX * (pScrn->bitsPerPixel >> 3));
}
+
+ OUTREG(FIFO_CONTROL, 0x18ffeL);
OUTREG( PSTREAM_WINDOW_START_REG, OS_XY(0,0) );
OUTREG( PSTREAM_WINDOW_SIZE_REG, OS_WH(pScrn->displayWidth, pScrn->virtualY) );
@@ -319,10 +321,11 @@ void SavageInitStreams2000(ScrnInfoPtr pScrn)
}
- OUTREG( SEC_STREAM_CKEY_LOW, 0 );
+ OUTREG( SEC_STREAM_CKEY_LOW, (4L << 29) );
OUTREG( SEC_STREAM_CKEY_UPPER, 0 );
OUTREG( SEC_STREAM_HSCALING, 0 );
OUTREG( SEC_STREAM_VSCALING, 0 );
+ OUTREG(SEC_STREAM2_STRIDE_LPB, 0);
OUTREG( BLEND_CONTROL, 0 );
OUTREG( SEC_STREAM_FBUF_ADDR0, 0 );
OUTREG( SEC_STREAM_FBUF_ADDR1, 0 );
@@ -334,11 +337,22 @@ void SavageInitStreams2000(ScrnInfoPtr pScrn)
OUTREG( SEC_STREAM_OPAQUE_OVERLAY, 0 );
OUTREG( SEC_STREAM_STRIDE, 0 );
+ /* FIFO related regs */
+ OUTREG8(CRT_ADDRESS_REG,0x86);
+ OUTREG8(CRT_DATA_REG,0x2c);
+
+ OUTREG8(CRT_ADDRESS_REG,0x87);
+ OUTREG8(CRT_DATA_REG,0xf8);
+
+ OUTREG8(CRT_ADDRESS_REG,0x89);
+ OUTREG8(CRT_DATA_REG,0x40);
+
+
/* These values specify brightness, contrast, saturation and hue. */
- OUTREG( SEC_STREAM_COLOR_CONVERT0_2000, 0x0000C892 );
- OUTREG( SEC_STREAM_COLOR_CONVERT1_2000, 0x00033400 );
- OUTREG( SEC_STREAM_COLOR_CONVERT2_2000, 0x000001CF );
- OUTREG( SEC_STREAM_COLOR_CONVERT3_2000, 0x01F1547E );
+ OUTREG( SEC_STREAM_COLOR_CONVERT0_2000, 0x640092 /*0x0000C892*/ );
+ OUTREG( SEC_STREAM_COLOR_CONVERT1_2000, 0x19a0000 /*0x00033400*/ );
+ OUTREG( SEC_STREAM_COLOR_CONVERT2_2000, 0x001cf /*0x000001CF*/ );
+ OUTREG( SEC_STREAM_COLOR_CONVERT3_2000, 0xF8CA007E /*0x01F1547E*/ );
}
@@ -384,10 +398,10 @@ void PatchEnableSPofPanel(ScrnInfoPtr pScrn)
}
VerticalRetraceWait();
-
+
OUTREG8(CRT_ADDRESS_REG,0x67);
OUTREG8(CRT_DATA_REG,(INREG8(CRT_DATA_REG)&0xf3)|0x04);
-
+
OUTREG8(CRT_ADDRESS_REG,0x65);
OUTREG8(CRT_DATA_REG,INREG8(CRT_DATA_REG)|0xC0);
@@ -396,8 +410,10 @@ void PatchEnableSPofPanel(ScrnInfoPtr pScrn)
} else {
OUTREG32(PSTREAM_CONTROL_REG,0x02000000);
}
+
OUTREG32(PSTREAM_WINDOW_SIZE_REG, 0x0);
-
+ /*OUTREG32(PSTREAM_WINDOW_SIZE_REG, OS_WH(pScrn->displayWidth, pScrn->virtualY));*/
+
}
diff --git a/src/savage_streams.h b/src/savage_streams.h
index 8991109..ad16ad7 100644
--- a/src/savage_streams.h
+++ b/src/savage_streams.h
@@ -197,6 +197,19 @@
#define SEC_STREAM_COLOR_CONVERT1_2000 0x819c
#define SEC_STREAM_COLOR_CONVERT2_2000 0x81e0
#define SEC_STREAM_COLOR_CONVERT3_2000 0x81e4
+#define SEC_STREAM_SRC_START_2000 0x818c
+#define SEC_STREAM_SRC_SIZE_2000 0x81a8
+#define SEC_STREAM_BUFFERSIZE_2000 0x81a4
+#define S_SRC_H_Mask 0x00000fff
+#define S_SRC_W_Shift 16
+#define S_SRC_W_Mask 0x0fff0000
+#define SRCSIZE(w,h) (((w <<S_SRC_W_Shift) & S_SRC_W_Mask) | (h & S_SRC_H_Mask))
+#define SRCSTART(x,y) (((x <<S_SRC_W_Shift) & 0x7ff0000) | (y & 0x000007ff))
+#define VSCALING_2000(h0,h1) ((unsigned int) (((float)h0/(float)h1) * (float)(65536.0) ))
+#define HSCALING_NORMALIZE(h0,h1) ((unsigned int) ((float)2048.0 * ((float)h0/ (float)h1))) << 16
+#define HSCALING_2000(w0,w1) ((unsigned int) (((float)w0/ (float)w1) * (float)(65536.0)))
+#define XY_2000(x,y) ((((x)<<X_Shift)&X_Mask) | (((y)<<Y_Shift)&Y_Mask))
+#define WH_2000(w,h) ((((w)<<W_Shift)&W_Mask) | (((h)<<H_Shift)&H_Mask))
#define BASE_PAD 0xf
diff --git a/src/savage_video.c b/src/savage_video.c
index 677ebf8..c354d25 100644
--- a/src/savage_video.c
+++ b/src/savage_video.c
@@ -219,8 +219,8 @@ unsigned int GetBlendForFourCC( int id )
{
switch( id ) {
case FOURCC_YUY2:
- case FOURCC_YV12:
- case FOURCC_I420:
+ case FOURCC_YV12: /* shouldn't this be 4? */
+ case FOURCC_I420: /* shouldn't this be 4? */
return 1;
case FOURCC_Y211:
return 4;
@@ -233,6 +233,28 @@ unsigned int GetBlendForFourCC( int id )
}
}
+static
+unsigned int GetBlendForFourCC2000( int id )
+{
+ switch( id ) {
+ case FOURCC_YUY2:
+ return 1;
+ case FOURCC_I420:
+ return 1; /* was 4 */
+ case FOURCC_YV12:
+ return 1; /* was 4 */
+ case FOURCC_Y211:
+ return 4;
+ case FOURCC_RV15:
+ return 3;
+ case FOURCC_RV16:
+ return 5;
+ default:
+ return 0;
+ }
+}
+
+
void savageOUTREG( SavagePtr psav, unsigned long offset, unsigned long value )
{
ErrorF( "MMIO %08lx, was %08lx, want %08lx,",
@@ -550,9 +572,9 @@ void SavageSetColorKey2000(ScrnInfoPtr pScrn)
blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue;
if( !pPriv->colorKey ) {
- OUTREG( SEC_STREAM_CKEY_LOW, 0 );
- OUTREG( SEC_STREAM_CKEY_UPPER, 0 );
- OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 9) | 0x08 ));
+ OUTREG( SEC_STREAM_CKEY_LOW, 0);
+ OUTREG( SEC_STREAM_CKEY_UPPER, 0);
+ OUTREG( BLEND_CONTROL, (8 << 2));
}
else {
switch (pScrn->depth) {
@@ -560,30 +582,30 @@ void SavageSetColorKey2000(ScrnInfoPtr pScrn)
OUTREG( SEC_STREAM_CKEY_LOW,
0x47000000 | (pPriv->colorKey & 0xFF) );
OUTREG( SEC_STREAM_CKEY_UPPER,
- 0x47000000 | (pPriv->colorKey & 0xFF) );
+ (pPriv->colorKey & 0xFF) );
break;
case 15:
OUTREG( SEC_STREAM_CKEY_LOW,
0x45000000 | (red<<19) | (green<<11) | (blue<<3) );
OUTREG( SEC_STREAM_CKEY_UPPER,
- 0x45000000 | (red<<19) | (green<<11) | (blue<<3) );
+ (red<<19) | (green<<11) | (blue<<3) );
break;
case 16:
OUTREG( SEC_STREAM_CKEY_LOW,
0x46000000 | (red<<19) | (green<<10) | (blue<<3) );
OUTREG( SEC_STREAM_CKEY_UPPER,
- 0x46020002 | (red<<19) | (green<<10) | (blue<<3) );
+ (red<<19) | (green<<10) | (blue<<3) );
break;
case 24:
OUTREG( SEC_STREAM_CKEY_LOW,
0x47000000 | (red<<16) | (green<<8) | (blue) );
OUTREG( SEC_STREAM_CKEY_UPPER,
- 0x47000000 | (red<<16) | (green<<8) | (blue) );
+ (red<<16) | (green<<8) | (blue) );
break;
}
/* We assume destination colorkey */
- OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 9) | 0x08 ));
+ OUTREG( BLEND_CONTROL, INREG(BLEND_CONTROL) | (8 << 2));
}
}
@@ -704,31 +726,69 @@ void SavageSetColor2000( ScrnInfoPtr pScrn )
/* Brightness/contrast/saturation/hue computations. */
- double k, dk1, dk2, dk3, dk4, dk5, dk6, dk7, dkb;
+ double k, yb, dk1, dk2, dk3, dk4, dk5, dk6, dk7, dkb;
int k1, k2, k3, k4, k5, k6, k7, kb;
- double s = pPriv->saturation / 128.0;
+ double s = pPriv->saturation / 10000.0;
double h = pPriv->hue * 0.017453292;
unsigned long assembly1, assembly2, assembly3, assembly4;
+ unsigned long brightness = pPriv->brightness;
xf86ErrorFVerb(XVTRACE, "bright %d, contrast %d, saturation %d, hue %d\n",
pPriv->brightness, (int)pPriv->contrast, (int)pPriv->saturation, pPriv->hue );
- if( psav->videoFourCC == FOURCC_Y211 )
+ if( psav->videoFourCC == FOURCC_Y211 ) {
k = 1.0;/* YUV */
- else
- k = 1.14;/* YCrCb */
-
+ yb = 0.0;
+ } else {
+ k = 1.1;/* YCrCb */
+ yb = 14.0;
+ }
- dk1 = 128 * k * pPriv->contrast;
+ dk1 = 128 * k * (pPriv->contrast / 10000.0);
+ if (dk1 < 0)
+ dk1 -= 0.5;
+ else
+ dk1 += 0.5;
dk2 = 64.0 * 1.371 * k * s * cos(h);
+ if (dk2 < 0)
+ dk2 -= 0.5;
+ else
+ dk2 += 0.5;
dk3 = -64.0 * 1.371 * k * s * sin(h);
- dk4 = -128.0 * k * s * (0.698 * cos(h) - 0.336 * sin(h));
- dk5 = -128.0 * k * s * (0.698 * sin(h) + 0.336 * cos(h));
- dk6 = 64.0 * 1.732 * k * s * sin(h);/* == k3 / 1.26331, right? */
- dk7 = 64.0 * 1.732 * k * s * cos(h);/* == k2 / -1.26331, right? */
- dkb = 128.0 * pPriv->brightness + 0.5;
- if( psav->videoFourCC != FOURCC_Y211 )
- dkb = 128 * (pPriv->brightness * k * pPriv->contrast + 0.5);
+ if (dk3 < 0)
+ dk3 -= 0.5;
+ else
+ dk3 += 0.5;
+ dk4 = -128.0 * k * s * (0.698 * cos(h) + 0.336 * sin(h));
+ if (dk4 < 0)
+ dk4 -= 0.5;
+ else
+ dk4 += 0.5;
+ dk5 = 128.0 * k * s * (0.698 * sin(h) - 0.336 * cos(h));
+ if (dk5 < 0)
+ dk5 -= 0.5;
+ else
+ dk5 += 0.5;
+ dk6 = 64.0 * 1.732 * k * s * sin(h);
+ if (dk6 < 0)
+ dk6 -= 0.5;
+ else
+ dk6 += 0.5;
+ dk7 = 64.0 * 1.732 * k * s * cos(h);
+ if (dk7 < 0)
+ dk7 -= 0.5;
+ else
+ dk7 += 0.5;
+
+ if (pPriv->brightness <= 0)
+ brightness = pPriv->brightness * 200 / 750 - 200;
+ else
+ brightness = (pPriv->brightness - 750) * 200 / (10000 - 750);
+ dkb = 128 * (brightness - (k * pPriv->contrast * yb / 10000.0) + 0.5);
+ if (dkb < 0)
+ dkb -= 0.5;
+ else
+ dkb += 0.5;
k1 = (int)(dk1 /*+0.5*/) & 0x1ff;
k2 = (int)(dk2 /*+0.5*/) & 0x1ff;
@@ -746,6 +806,13 @@ void SavageSetColor2000( ScrnInfoPtr pScrn )
kb = (int)(dkb /*+0.5*/) & 0xffff;
assembly4 = (kb<<16) | k7;
+#if 0
+ assembly1 = 0x640092;
+ assembly2 = 0x19a0000;
+ assembly3 = 0x001cf;
+ assembly4 = 0xf8ca007e;
+#endif
+
OUTREG( SEC_STREAM_COLOR_CONVERT0_2000, assembly1 );
OUTREG( SEC_STREAM_COLOR_CONVERT1_2000, assembly2 );
OUTREG( SEC_STREAM_COLOR_CONVERT2_2000, assembly3 );
@@ -1241,8 +1308,7 @@ SavageSetBlend(ScrnInfoPtr pScrn, int id)
{
SavagePtr psav = SAVPTR(pScrn);
- if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ||
- (psav->Chipset == S3_SAVAGE2000) )
+ if ( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) )
{
psav->blendBase = GetBlendForFourCC( id );
xf86ErrorFVerb(XVTRACE+1,"Format %4.4s, blend is %08x\n", (char*)&id, psav->blendBase );
@@ -1256,7 +1322,17 @@ SavageSetBlend(ScrnInfoPtr pScrn, int id)
OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 17) | (8 << 12) ));
#endif
}
+ } else if (psav->Chipset == S3_SAVAGE2000) {
+ psav->blendBase = GetBlendForFourCC2000( id );
+ xf86ErrorFVerb(XVTRACE+1,"Format %4.4s, blend is %08x\n", (char*)&id, psav->blendBase );
+ if (id != FOURCC_YV12)
+ OUTREG( BLEND_CONTROL,
+ ((psav->blendBase << 24) | (8 << 2) /*| 0x20000000*/));
+ else
+ OUTREG( BLEND_CONTROL,
+ ((psav->blendBase << 24) | (8 << 2) /*| 0x10000000*/));
}
+
psav->videoFourCC = id;
}
@@ -1364,12 +1440,17 @@ SavageDisplayVideoOld(
* bit_15 = 1: Enable vertical interpolation
* 0: Line duplicaion
*/
- /*
+ /*
* Vertical Interpolation is very bandwidth intensive. Some savages can't
* seem to handle it. Default is line doubling. --AGD
*/
if (pPriv->interpolation) {
- OUTREG(SSTREAM_LINES_REG, 0x8000 | src_h );
+ if (src_w * 16 <= 0x3300) {
+ OUTREG(SSTREAM_LINES_REG, 0x8000 | src_h );
+ OUTREG(FIFO_CONTROL, (INREG(FIFO_CONTROL) + 1));
+ } else {
+ OUTREG(SSTREAM_LINES_REG, src_h );
+ }
} else {
OUTREG(SSTREAM_LINES_REG, src_h );
}
@@ -1393,7 +1474,10 @@ SavageDisplayVideoOld(
cr92 = VGAIN8(vgaCRReg);
VGAOUT8(vgaCRReg, (cr92 & 0x40) | (pitch >> 8) | 0x80);
VGAOUT8(vgaCRIndex, 0x93);
- VGAOUT8(vgaCRReg, pitch);
+ if (psav->bTiled && (( drw_h > src_h) || (drw_w > src_w)))
+ VGAOUT8(vgaCRReg, pitch | 0xf);
+ else
+ VGAOUT8(vgaCRReg, pitch);
}
}
@@ -1552,51 +1636,84 @@ SavageDisplayVideo2000(
/*DisplayModePtr mode = pScrn->currentMode;*/
SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr;
int vgaCRIndex, vgaCRReg, vgaIOBase;
-
+ CARD32 addr0, addr1, addr2;
vgaIOBase = hwp->IOBase;
vgaCRIndex = vgaIOBase + 4;
vgaCRReg = vgaIOBase + 5;
- if ( psav->videoFourCC != id ) {
- SavageSetBlend(pScrn,id);
- SavageResetVideo(pScrn);
+
+ if( psav->videoFourCC != id )
+ SavageStreamsOff(pScrn);
+
+ if( !psav->videoFlags & VF_STREAMS_ON )
+ {
+ SavageSetBlend(pScrn,id);
+ SavageStreamsOn(pScrn);
+ SavageResetVideo(pScrn);
}
- /* Calculate horizontal and vertical scale factors. */
+ if (src_w > drw_w)
+ OUTREG(SEC_STREAM_SRC_START_2000, 0);
+ else
+ OUTREG(SEC_STREAM_SRC_START_2000, SRCSTART(x1, y1));
+
+ /*OUTREG(SEC_STREAM_SRC_SIZE_2000, SRCSIZE(src_w, src_h));*/
+ OUTREG(SEC_STREAM_SRC_SIZE_2000,
+ SRCSIZE((dstBox->x2-dstBox->x1), (dstBox->y2-dstBox->y1)));
+ /*
+ buffersize = (src_w * src_h * 2) / 4096;
+ OUTREG(SEC_STREAM_BUFFERSIZE_2000, (buffersize & 0xffffff) << 12);
+ */
+
+ /*SavageResetVideo(pScrn);*/
- OUTREG(SEC_STREAM_HSCALING,
- (65536 * src_w / drw_w) & 0x1FFFFF );
+ if( src_w > drw_w )
+ OUTREG(SEC_STREAM_HSCALE_NORMALIZE, HSCALING_NORMALIZE(drw_w,src_w));
+ else
+ OUTREG(SEC_STREAM_HSCALE_NORMALIZE, (2048 << 16));
- if( src_w < drw_w )
- OUTREG(SEC_STREAM_HSCALE_NORMALIZE,
- ((2048 * src_w / drw_w) & 0x7ff) << 16 );
+ /* Calculate horizontal and vertical scale factors. */
+ if ((src_w > drw_w) || (src_h > drw_h))
+ OUTREG(SEC_STREAM_HSCALING, (HSCALING_2000(src_w,drw_w)) | 0x01000000);
else
- OUTREG(SEC_STREAM_HSCALE_NORMALIZE, 2048 << 16 );
+ OUTREG(SEC_STREAM_HSCALING, HSCALING_2000(src_w,drw_w));
- OUTREG(SEC_STREAM_VSCALING,
- (65536 * src_h / drw_h) & 0x1FFFFF );
+ OUTREG(SEC_STREAM_VSCALING, VSCALING_2000(src_h,drw_h));
/*
* Set surface location and stride. We use x1>>15 because all surfaces
* are 2 bytes/pixel.
*/
- OUTREG(SEC_STREAM_FBUF_ADDR0, (offset + (x1>>15))
- & (0x7ffffff & ~BASE_PAD));
- OUTREG(SEC_STREAM_STRIDE, pitch & 0xfff );
- OUTREG(SEC_STREAM_WINDOW_START, ((dstBox->x1+1) << 16) | (dstBox->y1+1) );
- OUTREG(SEC_STREAM_WINDOW_SZ, ((dstBox->x2-dstBox->x1) << 16)
- | (dstBox->x2-dstBox->x1) );
+ addr0 = offset + (x1>>15); /* Y in YCbCr420 */
+ addr1 = addr0 + (width * height); /* Cb in in YCbCr420 */
+ addr2 = addr1 + ((width * height) / 4); /* Cr in in YCbCr420 */
+ OUTREG(SEC_STREAM_FBUF_ADDR0, (addr0) & (0x3fffff & ~BASE_PAD));
+#if 0
+ OUTREG(SEC_STREAM_FBUF_ADDR1, (addr1) & (0x3fffff & ~BASE_PAD));
+ OUTREG(SEC_STREAM_FBUF_ADDR2, (addr2) & (0x3fffff & ~BASE_PAD));
+#endif
+
+ OUTREG(SEC_STREAM_WINDOW_START, XY_2000(dstBox->x1,dstBox->y1));
+ OUTREG(SEC_STREAM_WINDOW_SZ,
+ WH_2000((dstBox->x2-dstBox->x1),(dstBox->y2-dstBox->y1)));
+
+ /*pitch = width * 2;*/
+ OUTREG(SEC_STREAM_STRIDE, pitch & 0xfff);
+#if 0
+ /* Y stride + CbCr stride in YCbCr420 */
+ OUTREG(SEC_STREAM_STRIDE, (pitch & 0xfff) + ((pitch & 0xfff) << 15));
+#endif
#if 0
/* Set color key on primary. */
- SavageSetColor2000( pScrn );
+ SavageSetColorKey2000( pScrn );
#endif
+#if 0
/* Set FIFO L2 on second stream. */
- /* Is CR92 shadowed for crtc2? -- AGD */
if( pPriv->lastKnownPitch != pitch )
{
unsigned char cr92;
@@ -1609,6 +1726,7 @@ SavageDisplayVideo2000(
VGAOUT8(vgaCRIndex, 0x93);
VGAOUT8(vgaCRReg, pitch);
}
+#endif
}
static int
@@ -1701,7 +1819,8 @@ SavagePutImage(
npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left;
left <<= 1;
- offset = ((pPriv->area->box.y1 * pitch)) + (top * dstPitch);
+ /*offset = ((pPriv->area->box.y1 * pitch)) + (top * dstPitch);*/
+ offset = pPriv->area->box.y1 * psav->lDelta;
dst_start = (psav->FBBase + ((offset + left) & ~BASE_PAD));
switch(id) {