On Mon, 2010-03-08 at 23:40 -0500, Quiliro Ordóñez wrote:
> Will this fix come to the repos soon?

I have been working on this a little bit.  The patch applies pretty
easily to the SiliconMotion driver that's currently in the metad
repository (you just have to change the indentation in one of the patch
chunks).  I have a modified Debian source tree with the patch added that
gets to the build process cleanly.

Unfortunately, I don't have a good compiler toolchain for the Yeeloong,
and I've been working on that problem too but haven't had much luck.  Is
there someone who's interested in building this?  I've attached the
modified patch -- all you should have to do is drop it in
debian/patches, add its filename to debian/patches/series, and rebuild.

Alternatively, if anyone could help me build/get the compiler chain,
that'd be cool too.  :)

-- 
Brett Smith
Licensing Compliance Engineer, Free Software Foundation

Join us in Cambridge for LibrePlanet, March 19th-21st!
http://groups.fsf.org/wiki/LibrePlanet2010

--- orig/src/smi_video.c	2010-03-10 11:37:37.000000000 -0500
+++ mod/src/smi_video.c	2010-03-10 11:38:51.000000000 -0500
@@ -283,6 +283,7 @@
     XVIMAGE_YUY2,
     XVIMAGE_YV12,
     XVIMAGE_I420,
+    XVIMAGE_UYVY,
     {
 	FOURCC_RV15,			/* id				*/
 	XvRGB,				/* type				*/
@@ -1119,7 +1120,7 @@
 	vpr00 |= 0x0010000E;
     } else {
 	/*
-	  Bit 21     = 10: Vertical Interpolation                   = enabled
+	  Bit 21     = 1: Vertical Interpolation                   = enabled
 	  Bit 24     = 1: Select Video Window I Source Addr        = 1
 	  1= Video window I source addr = capture port buffer ?
 	*/
@@ -1491,6 +1492,117 @@
     LEAVE_PROC("SMI_QueryBestSize");
 }
 
+static void myXVCopyYUV12ToPacked(const unsigned char *srcy, const unsigned char *srcv, const unsigned char *srcu,
+		unsigned char *dst, int srcPitchy, int srcPitchuv, int dstPitch, int h, int w)
+{
+	int i, j;
+	unsigned char const *y, *u, *v;
+	int dstinc, yinc, uinc, vinc;
+
+	y = srcy;
+	u = srcu;
+	v = srcv;
+
+	dstinc = dstPitch - 2*w;
+	yinc = srcPitchy - w;
+	uinc = srcPitchuv - w/2;
+	vinc = srcPitchuv - w/2;
+
+	for (i = 0; i < h; i++) {
+		asm (
+//			".set arch=loongson2f\n\t"
+			".set noreorder\n\t"
+			"move $8, %8 \n\t"
+			"1: \n\t"
+			"beqz $8, 2f \n\t"
+			"xor $f0, $f0, $f0 \n\t"
+			"ldc1 $f4, (%0) \n\t"
+			"punpcklbh $f2, $f4, $f0 \n\t"
+			"punpckhbh $f4, $f4, $f0 \n\t"
+			"ldc1 $f16, 8(%0) \n\t"
+			"punpcklbh $f14, $f16, $f0 \n\t"
+			"punpckhbh $f16, $f16, $f0 \n\t"
+			
+			"lwc1 $f8, (%1) \n\t"
+			"lwc1 $f12, (%2) \n\t"
+			"punpcklbh $f8, $f8, $f12 \n\t"
+			"punpcklbh $f6, $f0, $f8 \n\t"
+			"punpckhbh $f8, $f0, $f8 \n\t"
+			"lwc1 $f18, 4(%1) \n\t"
+			"lwc1 $f12, 4(%2) \n\t"
+			"punpcklbh $f18, $f18, $f12 \n\t"
+			"punpcklbh $f10, $f0, $f18 \n\t"
+			"punpckhbh $f12, $f0, $f18 \n\t"
+
+			"or $f2, $f2, $f6 \n\t"
+			"or $f4, $f4, $f8 \n\t"
+			"or $f14, $f14, $f10 \n\t"
+			"or $f16, $f16, $f12 \n\t"
+
+			"sdc1 $f2, (%3) \n\t"
+			"sdc1 $f4, 8(%3) \n\t"
+			"add %0, 16 \n\t"
+			"add %1, 8 \n\t"
+			"add %2, 8 \n\t"
+			"sdc1 $f14, 0x10(%3) \n\t"
+			"sdc1 $f16, 0x18(%3) \n\t"
+			"add $8, -1 \n\t"
+			"b 1b \n\t"
+			"add %3, 32 \n\t"
+			"2: \n\t"
+			".set reorder\n\t"
+			: "=r" (y), "=r" (u), "=r" (v), "=r" (dst)
+			: "0" (y), "1" (u), "2" (v), "3" (dst), "r" (w>>4)
+			: "memory","$8"
+		);
+
+		asm (
+//			".set arch=loongson2f\n\t"
+			".set noreorder\n\t"
+			"move $8, %8 \n\t"
+			"1: \n\t"
+			"beqz $8, 2f \n\t"
+			"xor $f0, $f0, $f0 \n\t"
+			"ldc1 $f4, (%0) \n\t"
+			"punpcklbh $f2, $f4, $f0 \n\t"
+			"punpckhbh $f4, $f4, $f0 \n\t"
+			
+			"lwc1 $f8, (%1) \n\t"
+			"lwc1 $f12, (%2) \n\t"
+			"punpcklbh $f8, $f8, $f12 \n\t"
+			"punpcklbh $f6, $f0, $f8 \n\t"
+			"punpckhbh $f8, $f0, $f8 \n\t"
+
+			"or $f2, $f2, $f6 \n\t"
+			"or $f4, $f4, $f8 \n\t"
+
+			"sdc1 $f2, (%3) \n\t"
+			"sdc1 $f4, 8(%3) \n\t"
+			"add %0, 8 \n\t"
+			"add %1, 4 \n\t"
+			"add %2, 4 \n\t"
+			"add $8, -1 \n\t"
+			"b 1b \n\t"
+			"add %3, 16 \n\t"
+			"2:\n\t"
+			".set reorder\n\t"
+			: "=r" (y), "=r" (u), "=r" (v), "=r" (dst)
+			: "0" (y), "1" (u), "2" (v), "3" (dst), "r" ((w&0xf)/8)
+			: "memory","$8"
+		);
+
+		for (j = (w&7)/2; j; j--) {
+			*dst++ = *y++;
+			*dst++ = *u++;
+			*dst++ = *y++;
+			*dst++ = *v++;
+		}
+		y += yinc;
+		u = (i%2) ? (u + uinc): (u - w/2);
+		v = (i%2) ? (v + vinc): (v - w/2);
+		dst += dstinc;
+	}
+}
 
 static int
 SMI_PutImage(
@@ -1609,7 +1721,7 @@
 	   offset3 = tmp;
 	}
 	nLines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
-	xf86XVCopyYUV12ToPacked(buf + (top * srcPitch) + (left >> 1), 
+	myXVCopyYUV12ToPacked(buf + (top * srcPitch) + (left >> 1), 
 				buf + offset2, buf + offset3, dstStart,
 				srcPitch, srcPitch2, dstPitch, nLines, nPixels);
 	break;
@@ -1882,7 +1994,7 @@
 {
     SMIPtr pSmi = SMIPTR(pScrn);
     CARD32 vpr00;
-    int hstretch, vstretch;
+    uint_least32_t hstretch, vstretch;
 
     ENTER_PROC("SMI_DisplayVideo");
 
@@ -1909,13 +2021,13 @@
     }
 
     if (drw_w > vid_w) {
-	hstretch = (2560 * vid_w / drw_w + 5) / 10;
+	hstretch = ((uint_least32_t)(vid_w - 1) << 16) / (drw_w - 1);
     } else {
 	hstretch = 0;
     }
 
     if (drw_h > vid_h) {
-	vstretch = (2560 * vid_h / drw_h + 5) / 10;
+	vstretch = ((uint_least32_t)(vid_h - 1) << 16) / (drw_h - 1);
 	vpr00 |= 1 << 21;
     } else {
 	vstretch = 0;
@@ -1928,7 +2040,8 @@
     WRITE_VPR(pSmi, 0x18, (dstBox->x2) | (dstBox->y2 << 16));
     WRITE_VPR(pSmi, 0x1C, offset >> 3);
     WRITE_VPR(pSmi, 0x20, (pitch >> 3) | ((pitch >> 3) << 16));
-    WRITE_VPR(pSmi, 0x24, (hstretch << 8) | vstretch);
+    WRITE_VPR(pSmi, 0x24, (hstretch & 0xff00) | ((vstretch & 0xff00) >> 8));
+    WRITE_VPR(pSmi, 0x68, ((hstretch & 0xff) << 8) | (vstretch & 0xff));
 
     LEAVE_PROC("SMI_DisplayVideo");
 }
_______________________________________________
gNewSense-dev mailing list
gNewSense-dev@nongnu.org
http://lists.nongnu.org/mailman/listinfo/gnewsense-dev

Reply via email to