r3396 - developers/olv/xserver/patches

olv at sita.openmoko.org olv at sita.openmoko.org
Mon Nov 12 13:44:06 CET 2007


Author: olv
Date: 2007-11-12 13:44:02 +0100 (Mon, 12 Nov 2007)
New Revision: 3396

Modified:
   developers/olv/xserver/patches/smedia-glamo.patch
Log:
XVideo support and some code cleanup, still very unstable


Modified: developers/olv/xserver/patches/smedia-glamo.patch
===================================================================
--- developers/olv/xserver/patches/smedia-glamo.patch	2007-11-12 10:58:20 UTC (rev 3395)
+++ developers/olv/xserver/patches/smedia-glamo.patch	2007-11-12 12:44:02 UTC (rev 3396)
@@ -1,8 +1,40 @@
-Index: xserver/hw/kdrive/glamo/Makefile.am
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ xserver/hw/kdrive/glamo/Makefile.am	2007-09-25 19:32:10.000000000 +0800
-@@ -0,0 +1,51 @@
+diff --git a/configure.ac b/configure.ac
+index 76d33f0..2807c50 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1824,6 +1824,7 @@ hw/kdrive/ati/Makefile
+ hw/kdrive/chips/Makefile
+ hw/kdrive/ephyr/Makefile
+ hw/kdrive/epson/Makefile
++hw/kdrive/glamo/Makefile
+ hw/kdrive/fake/Makefile
+ hw/kdrive/fbdev/Makefile
+ hw/kdrive/w100/Makefile
+diff --git a/hw/kdrive/Makefile.am b/hw/kdrive/Makefile.am
+index 8075a56..b97912d 100644
+--- a/hw/kdrive/Makefile.am
++++ b/hw/kdrive/Makefile.am
+@@ -4,7 +4,7 @@ VESA_SUBDIRS = vesa ati chips epson i810 mach64 mga neomagic nvidia pm2 r128 \
+ endif
+ 
+ if KDRIVEFBDEV
+-FBDEV_SUBDIRS = fbdev epson
++FBDEV_SUBDIRS = fbdev epson glamo
+ endif
+ 
+ if KDRIVEW100
+@@ -34,4 +34,4 @@ SUBDIRS =			\
+ 	fake
+ 
+ DIST_SUBDIRS = vesa ati chips epson i810 mach64 mga neomagic nvidia pm2 r128 \
+-               smi via fbdev sdl ephyr src linux fake sis300
++               smi via fbdev sdl ephyr src linux fake sis300 glamo
+diff --git a/hw/kdrive/glamo/Makefile.am b/hw/kdrive/glamo/Makefile.am
+new file mode 100644
+index 0000000..ffb7a30
+--- /dev/null
++++ b/hw/kdrive/glamo/Makefile.am
+@@ -0,0 +1,54 @@
 +if KDRIVEFBDEV
 +FBDEV_INCLUDES =-I$(top_srcdir)/hw/kdrive/fbdev
 +FBDEV_LIBS = $(top_builddir)/hw/kdrive/fbdev/libfbdev.a
@@ -46,19 +78,23 @@
 +
 +Xglamo_LDADD = \
 +	$(GLAMO_LIBS)			\
-+	@KDRIVE_LIBS@
++	@KDRIVE_LIBS@			\
++	@XSERVER_LIBS@
 +
 +Xglamo_DEPENDENCIES =	\
 +	libglamo.a 			\
-+	@KDRIVE_LOCAL_LIBS@
++        $(FBDEV_LIBS)                   \
++        $(VESA_LIBS)                    \
++        $(DRI_LIBS)
 +
 +relink:
 +	rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
-Index: xserver/hw/kdrive/glamo/glamo-regs.h
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ xserver/hw/kdrive/glamo/glamo-regs.h	2007-09-25 19:00:20.000000000 +0800
-@@ -0,0 +1,685 @@
+diff --git a/hw/kdrive/glamo/glamo-regs.h b/hw/kdrive/glamo/glamo-regs.h
+new file mode 100644
+index 0000000..4359a24
+--- /dev/null
++++ b/hw/kdrive/glamo/glamo-regs.h
+@@ -0,0 +1,757 @@
 +#ifndef _GLAMO_REGS_H
 +#define _GLAMO_REGS_H
 +
@@ -288,7 +324,7 @@
 +	GLAMO_CLOCK_2D_DG_M6CLK		= 0x0010,
 +	GLAMO_CLOCK_2D_EN_M6CLK		= 0x0020,
 +	GLAMO_CLOCK_2D_RESET		= 0x1000,
-+	GLAMO_CLOCK_2D_CQ_RESET		= 0x2000,
++	GLAMO_CLOCK_2D_CMDQ_RESET		= 0x2000,
 +};
 +
 +enum glamo_reg_clock_3d {
@@ -319,6 +355,20 @@
 +	GLAMO_CLOCK_MPEG_DEC_RESET	= 0x2000,
 +};
 +
++enum glamo_reg_clock_mproc {
++	GLAMO_CLOCK_MPROC_DG_I0CLK	= 0x0001,
++	GLAMO_CLOCK_MPROC_EN_I0CLK	= 0x0002,
++	GLAMO_CLOCK_MPROC_DG_X5CLK	= 0x0004,
++	GLAMO_CLOCK_MPROC_EN_X5CLK	= 0x0008,
++	//
++	GLAMO_CLOCK_MPROC_EN_KCLK	= 0x0020,
++	GLAMO_CLOCK_MPROC_DG_M4CLK	= 0x0040,
++	GLAMO_CLOCK_MPROC_EN_M4CLK	= 0x0080,
++	GLAMO_CLOCK_MPROC_DG_M10CLK	= 0x0100,
++	GLAMO_CLOCK_MPROC_EN_M10CLK	= 0x0200,
++	GLAMO_CLOCK_MPROC_RESET		= 0x1000,
++};
++
 +enum glamo_reg_clock51 {
 +	GLAMO_CLOCK_GEN51_EN_DIV_MCLK	= 0x0001,
 +	GLAMO_CLOCK_GEN51_EN_DIV_SCLK	= 0x0002,
@@ -348,7 +398,7 @@
 +	GLAMO_HOSTBUS2_MMIO_EN_MMC	= 0x0010,
 +	GLAMO_HOSTBUS2_MMIO_EN_MICROP0	= 0x0020,
 +	GLAMO_HOSTBUS2_MMIO_EN_MICROP1	= 0x0040,
-+	GLAMO_HOSTBUS2_MMIO_EN_CQ	= 0x0080,
++	GLAMO_HOSTBUS2_MMIO_EN_CMDQ	= 0x0080,
 +	GLAMO_HOSTBUS2_MMIO_EN_RISC	= 0x0100,
 +	GLAMO_HOSTBUS2_MMIO_EN_2D	= 0x0200,
 +	GLAMO_HOSTBUS2_MMIO_EN_3D	= 0x0400,
@@ -356,7 +406,7 @@
 +
 +/* LCD Controller */
 +
-+#define REG_LCD(x)	(x)
++#define REG_LCD(x)	(GLAMO_REGOFS_LCD+(x))
 +enum glamo_reg_lcd {
 +	GLAMO_REG_LCD_MODE1		= REG_LCD(0x00),
 +	GLAMO_REG_LCD_MODE2		= REG_LCD(0x02),
@@ -500,6 +550,16 @@
 +	GLAMO_LCD_MODE3_18BITS		= 0x0040,
 +};
 +
++enum glamo_lcd_rot_mode {
++	GLAMO_LCD_ROT_MODE_0		= 0x0000,
++	GLAMO_LCD_ROT_MODE_180		= 0x2000,
++	GLAMO_LCD_ROT_MODE_MIRROR	= 0x4000,
++	GLAMO_LCD_ROT_MODE_FLIP		= 0x6000,
++	GLAMO_LCD_ROT_MODE_90		= 0x8000,
++	GLAMO_LCD_ROT_MODE_270		= 0xa000,
++};
++#define GLAMO_LCD_ROT_MODE_MASK		0xe000
++
 +enum glamo_lcd_cmd_type {
 +	GLAMO_LCD_CMD_TYPE_DISP		= 0x0000,
 +	GLAMO_LCD_CMD_TYPE_PARALLEL	= 0x4000,
@@ -633,17 +693,11 @@
 +	GLAMO_REG_ISP_RGB2YUV_33	= REG_ISP(0xfe),
 +	//
 +	GLAMO_REG_ISP_PORT1_SCALEH_MATRIX	= REG_ISP(0x10c),
-+	//
 +	GLAMO_REG_ISP_PORT1_SCALEV_MATRIX	= REG_ISP(0x120),
-+	//
 +	GLAMO_REG_ISP_PORT2_SCALEH_MATRIX	= REG_ISP(0x134),
-+	//
 +	GLAMO_REG_ISP_PORT2_SCALEV_MATRIX	= REG_ISP(0x148),
-+	//
 +	GLAMO_REG_ISP_DEC_SCALEH_MATRIX		= REG_ISP(0x15c),
-+	//
 +	GLAMO_REG_ISP_DEC_SCALEV_MATRIX		= REG_ISP(0x170),
-+	//
 +	GLAMO_REG_ISP_STATUS			= REG_ISP(0x184),
 +};
 +
@@ -669,6 +723,16 @@
 +	//
 +};
 +
++enum glamo_isp_rot_mode {
++	GLAMO_ISP_ROT_MODE_0		= 0x0000,
++	GLAMO_ISP_ROT_MODE_90		= 0x0400,
++	GLAMO_ISP_ROT_MODE_270		= 0x0800,
++	GLAMO_ISP_ROT_MODE_180		= 0x0c00,
++	GLAMO_ISP_ROT_MODE_MIRROR	= 0x1000,
++	GLAMO_ISP_ROT_MODE_FLIP		= 0x1400,
++};
++#define GLAMO_ISP_ROT_MODE_MASK		0x1c00
++
 +enum glamo_reg_isp_port1_en {
 +	GLAMO_ISP_PORT1_EN_OUTPUT	= 0x0001,
 +//	GLAMO_ISP_PORT1_EN_SCALE	= 0x0002,
@@ -686,19 +750,63 @@
 +	GLAMO_ISP_PORT2_EN_DECODE	= 0x0080,
 +};
 +
-+#define REG_CQ(x)		(GLAMO_REGOFS_CMDQUEUE+(x))
++#define REG_MPEG(x)		(GLAMO_REGOFS_MPEG+(x))
 +
++enum glamo_register_mpeg {
++	//
++	GLAMO_REG_MPEG_DC_ADDRL		= REG_MPEG(0x3c),
++	GLAMO_REG_MPEG_DC_ADDRH		= REG_MPEG(0x3e),
++	GLAMO_REG_MPEG_AC_ADDRL		= REG_MPEG(0x40),
++	GLAMO_REG_MPEG_AC_ADDRH		= REG_MPEG(0x42),
++	//
++	GLAMO_REG_MPEG_SAFE_1		= REG_MPEG(0x60),
++	GLAMO_REG_MPEG_SAFE_2		= REG_MPEG(0x62),
++	GLAMO_REG_MPEG_SAFE_3		= REG_MPEG(0x64),
++	//
++	GLAMO_REG_MPEG_DEC_OUT0_Y_ADDRL	= REG_MPEG(0x6e),
++	GLAMO_REG_MPEG_DEC_OUT0_Y_ADDRH	= REG_MPEG(0x70),
++	GLAMO_REG_MPEG_DEC_OUT0_U_ADDRL	= REG_MPEG(0x72),
++	GLAMO_REG_MPEG_DEC_OUT0_U_ADDRH	= REG_MPEG(0x74),
++	GLAMO_REG_MPEG_DEC_OUT0_V_ADDRL	= REG_MPEG(0x76),
++	GLAMO_REG_MPEG_DEC_OUT0_V_ADDRH	= REG_MPEG(0x78),
++	GLAMO_REG_MPEG_DEC_OUT1_Y_ADDRL	= REG_MPEG(0x7a),
++	GLAMO_REG_MPEG_DEC_OUT1_Y_ADDRH	= REG_MPEG(0x7c),
++	GLAMO_REG_MPEG_DEC_OUT1_U_ADDRL	= REG_MPEG(0x7e),
++	GLAMO_REG_MPEG_DEC_OUT1_U_ADDRH	= REG_MPEG(0x80),
++	GLAMO_REG_MPEG_DEC_OUT1_V_ADDRL	= REG_MPEG(0x82),
++	GLAMO_REG_MPEG_DEC_OUT1_V_ADDRH	= REG_MPEG(0x84),
++	GLAMO_REG_MPEG_DEC_OUT2_Y_ADDRL	= REG_MPEG(0x86),
++	GLAMO_REG_MPEG_DEC_OUT2_Y_ADDRH	= REG_MPEG(0x88),
++	GLAMO_REG_MPEG_DEC_OUT2_U_ADDRL	= REG_MPEG(0x8a),
++	GLAMO_REG_MPEG_DEC_OUT2_U_ADDRH	= REG_MPEG(0x8c),
++	GLAMO_REG_MPEG_DEC_OUT2_V_ADDRL	= REG_MPEG(0x8e),
++	GLAMO_REG_MPEG_DEC_OUT2_V_ADDRH	= REG_MPEG(0x90),
++	GLAMO_REG_MPEG_DEC_WIDTH	= REG_MPEG(0x92),
++	GLAMO_REG_MPEG_DEC_HEIGHT	= REG_MPEG(0x94),
++	GLAMO_REG_MPEG_SPECIAL		= REG_MPEG(0x96),
++	GLAMO_REG_MPEG_DEC_IN_ADDRL	= REG_MPEG(0x98),
++	GLAMO_REG_MPEG_DEC_IN_ADDRH	= REG_MPEG(0x9a),
++	//
++	GLAMO_REG_MPEG_DEBLK_THRESHOLD	= REG_MPEG(0xc0),
++	//
++	GLAMO_REG_MPEG_DEC_STATUS	= REG_MPEG(0xc8),
++	GLAMO_REG_MPEG_DEC_RB0		= REG_MPEG(0xca),
++	GLAMO_REG_MPEG_DEC_RB1		= REG_MPEG(0xcc),
++};
++
++#define REG_CMDQ(x)		(GLAMO_REGOFS_CMDQUEUE+(x))
++
 +enum glamo_register_cq {
-+	GLAMO_REG_CQ_BASE_ADDRL		= REG_CQ(0x00),
-+	GLAMO_REG_CQ_BASE_ADDRH		= REG_CQ(0x02),
-+	GLAMO_REG_CQ_LEN		= REG_CQ(0x04),
-+	GLAMO_REG_CQ_WRITE_ADDRL	= REG_CQ(0x06),
-+	GLAMO_REG_CQ_WRITE_ADDRH	= REG_CQ(0x08),
-+	GLAMO_REG_CQ_FLIP		= REG_CQ(0x0a),
-+	GLAMO_REG_CQ_CONTROL		= REG_CQ(0x0c),
-+	GLAMO_REG_CQ_READ_ADDRL		= REG_CQ(0x0e),
-+	GLAMO_REG_CQ_READ_ADDRH		= REG_CQ(0x10),
-+	GLAMO_REG_CQ_STATUS		= REG_CQ(0x12),
++	GLAMO_REG_CMDQ_BASE_ADDRL		= REG_CMDQ(0x00),
++	GLAMO_REG_CMDQ_BASE_ADDRH		= REG_CMDQ(0x02),
++	GLAMO_REG_CMDQ_LEN		= REG_CMDQ(0x04),
++	GLAMO_REG_CMDQ_WRITE_ADDRL	= REG_CMDQ(0x06),
++	GLAMO_REG_CMDQ_WRITE_ADDRH	= REG_CMDQ(0x08),
++	GLAMO_REG_CMDQ_FLIP		= REG_CMDQ(0x0a),
++	GLAMO_REG_CMDQ_CONTROL		= REG_CMDQ(0x0c),
++	GLAMO_REG_CMDQ_READ_ADDRL		= REG_CMDQ(0x0e),
++	GLAMO_REG_CMDQ_READ_ADDRH		= REG_CMDQ(0x10),
++	GLAMO_REG_CMDQ_STATUS		= REG_CMDQ(0x12),
 +};
 +
 +#define REG_2D(x)		(GLAMO_REGOFS_2D+(x))
@@ -744,11 +852,12 @@
 +};
 +
 +#endif /* _GLAMO_REGS_H */
-Index: xserver/hw/kdrive/glamo/glamo.c
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ xserver/hw/kdrive/glamo/glamo.c	2007-09-26 17:44:47.000000000 +0800
-@@ -0,0 +1,498 @@
+diff --git a/hw/kdrive/glamo/glamo.c b/hw/kdrive/glamo/glamo.c
+new file mode 100644
+index 0000000..8138902
+--- /dev/null
++++ b/hw/kdrive/glamo/glamo.c
+@@ -0,0 +1,487 @@
 +/*
 + * Copyright © 2007 OpenMoko, Inc.
 + *
@@ -1009,7 +1118,6 @@
 +	GLAMOCardInfo *glamoc = screen->card->driver;
 +	Bool ret;
 +
-+	GLAMODrawDisable (pScreen);
 +	ret = glamoc->backend_funcs.randrSetConfig(pScreen, randr, rate, pSize);
 +	GLAMOSetOffscreen (screen);
 +	/*
@@ -1023,7 +1131,6 @@
 +					screen->fb[0].byteStride,
 +					screen->fb[0].frameBuffer);
 +
-+	GLAMODrawEnable (pScreen);
 +	return ret;
 +}
 +
@@ -1044,10 +1151,6 @@
 +	GLAMOScreenInfo *glamos = (GLAMOScreenInfo *)screen->driver;
 +	GLAMOCardInfo *glamoc = screen->card->driver;
 +
-+#ifdef XV
-+	GLAMOFiniVideo(screen->pScreen);
-+#endif
-+
 +	glamoc->backend_funcs.scrfini(screen);
 +	xfree(glamos);
 +	screen->driver = 0;
@@ -1085,9 +1188,6 @@
 +	KdScreenPriv(pScreen);
 +	GLAMOCardInfo(pScreenPriv);
 +
-+#ifdef XV
-+	GLAMOInitVideo(pScreen);
-+#endif
 +	return glamoc->backend_funcs.initScreen(pScreen);
 +}
 +
@@ -1128,8 +1228,6 @@
 +{
 +	GLAMOCardInfo *glamoc = card->driver;
 +
-+	GLAMOUnmapReg(card, glamoc);
-+
 +	glamoc->backend_funcs.restore(card);
 +}
 +
@@ -1247,11 +1345,12 @@
 +	GLAMOGetColors,		/* getColors */
 +	GLAMOPutColors,		/* putColors */
 +};
-Index: xserver/hw/kdrive/glamo/glamo.h
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ xserver/hw/kdrive/glamo/glamo.h	2007-09-26 17:45:48.000000000 +0800
-@@ -0,0 +1,386 @@
+diff --git a/hw/kdrive/glamo/glamo.h b/hw/kdrive/glamo/glamo.h
+new file mode 100644
+index 0000000..10fa664
+--- /dev/null
++++ b/hw/kdrive/glamo/glamo.h
+@@ -0,0 +1,395 @@
 +/*
 + * Copyright © 2007 OpenMoko, Inc.
 + *
@@ -1397,18 +1496,20 @@
 +	KdOffscreenArea *area;
 +} GLAMOCursor;
 +
++#define GLAMO_VIDEO_NUM_BUFS 2
 +typedef struct _GLAMOPortPriv {
 +	int brightness;
 +	int saturation;
 +	RegionRec clip;
-+	CARD32 size;
-+	KdOffscreenArea *off_screen;
 +	DrawablePtr pDraw;
 +	PixmapPtr pPixmap;
 +
-+	CARD32 src_offset;
-+	CARD32 src_pitch;
-+	CARD8 *src_addr;
++	int idx;
++	KdOffscreenArea *off_screen[GLAMO_VIDEO_NUM_BUFS];
++	CARD32 size[GLAMO_VIDEO_NUM_BUFS];
++	CARD32 src_offsets[GLAMO_VIDEO_NUM_BUFS][3];
++	CARD32 src_pitch1;
++	CARD32 src_pitch2;
 +
 +	int id;
 +	int src_x1, src_y1, src_x2, src_y2;
@@ -1632,17 +1733,25 @@
 +Bool
 +GLAMOInitVideo(ScreenPtr pScreen);
 +
++Bool
++GLAMOVideoSetup(ScreenPtr pScreen);
++
 +void
++GLAMOVideoTeardown(ScreenPtr pScreen);
++
++ 
++void
 +GLAMOFiniVideo(ScreenPtr pScreen);
 +
 +extern KdCardFuncs GLAMOFuncs;
 +
 +#endif /* _GLAMO_H_ */
-Index: xserver/hw/kdrive/glamo/glamo_dma.c
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ xserver/hw/kdrive/glamo/glamo_dma.c	2007-09-26 17:45:16.000000000 +0800
-@@ -0,0 +1,410 @@
+diff --git a/hw/kdrive/glamo/glamo_dma.c b/hw/kdrive/glamo/glamo_dma.c
+new file mode 100644
+index 0000000..effe6c5
+--- /dev/null
++++ b/hw/kdrive/glamo/glamo_dma.c
+@@ -0,0 +1,530 @@
 +/*
 + * Copyright © 2007 OpenMoko, Inc.
 + *
@@ -1680,7 +1789,7 @@
 +#include "glamo_sarea.h"
 +#endif /* USE_DRI */
 +
-+#define DEBUG_FIFO 1
++#define DEBUG_FIFO 0
 +
 +#if DEBUG_FIFO
 +static void
@@ -1690,16 +1799,16 @@
 +	char *mmio = glamoc->reg_base;
 +	CARD32 offset;
 +
-+	ErrorF("GLAMO_REG_CQ_STATUS: 0x%04x\n",
-+	    MMIO_IN16(mmio, GLAMO_REG_CQ_STATUS));
++	ErrorF("GLAMO_REG_CMDQ_STATUS: 0x%04x\n",
++	    MMIO_IN16(mmio, GLAMO_REG_CMDQ_STATUS));
 +
-+	offset = MMIO_IN16(mmio, GLAMO_REG_CQ_WRITE_ADDRL);
-+	offset |= (MMIO_IN16(mmio, GLAMO_REG_CQ_WRITE_ADDRH) << 16) & 0x7;
-+	ErrorF("GLAMO_REG_CQ_WRITE_ADDR: 0x%08x\n", (unsigned int) offset);
++	offset = MMIO_IN16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRL);
++	offset |= (MMIO_IN16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRH) << 16) & 0x7;
++	ErrorF("GLAMO_REG_CMDQ_WRITE_ADDR: 0x%08x\n", (unsigned int) offset);
 +
-+	offset = MMIO_IN16(mmio, GLAMO_REG_CQ_READ_ADDRL);
-+	offset |= (MMIO_IN16(mmio, GLAMO_REG_CQ_READ_ADDRH) << 16) & 0x7;
-+	ErrorF("GLAMO_REG_CQ_READ_ADDR: 0x%08x\n", (unsigned int) offset);
++	offset = MMIO_IN16(mmio, GLAMO_REG_CMDQ_READ_ADDRL);
++	offset |= (MMIO_IN16(mmio, GLAMO_REG_CMDQ_READ_ADDRH) << 16) & 0x7;
++	ErrorF("GLAMO_REG_CMDQ_READ_ADDR: 0x%08x\n", (unsigned int) offset);
 +}
 +#endif
 +
@@ -1716,18 +1825,21 @@
 +		return;
 +
 +	switch (engine) {
++	case GLAMO_ENGINE_CMDQ:
++		reg = GLAMO_REG_CLOCK_2D;
++		mask = GLAMO_CLOCK_2D_CMDQ_RESET;
++		break;
 +	case GLAMO_ENGINE_ISP:
 +		reg = GLAMO_REG_CLOCK_ISP;
 +		mask = GLAMO_CLOCK_ISP2_RESET;
 +		break;
-+	case GLAMO_ENGINE_CQ:
-+		reg = GLAMO_REG_CLOCK_2D;
-+		mask = GLAMO_CLOCK_2D_CQ_RESET;
-+		break;
 +	case GLAMO_ENGINE_2D:
 +		reg = GLAMO_REG_CLOCK_2D;
 +		mask = GLAMO_CLOCK_2D_RESET;
 +		break;
++	default:
++		return;
++		break;
 +	}
 +
 +	MMIOSetBitMask(mmio, reg, mask, 0xffff);
@@ -1746,6 +1858,50 @@
 +	if (!mmio)
 +		return;
 +
++	switch (engine) {
++	case GLAMO_ENGINE_CMDQ:
++		MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_2D,
++			       GLAMO_CLOCK_2D_EN_M6CLK,
++			       0);
++		MMIOSetBitMask(mmio, GLAMO_REG_HOSTBUS(2),
++			       GLAMO_HOSTBUS2_MMIO_EN_CMDQ,
++			       0);
++		MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_GEN5_1,
++			       GLAMO_CLOCK_GEN51_EN_DIV_MCLK,
++			       0);
++		break;
++	case GLAMO_ENGINE_ISP:
++		MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_ISP,
++			       GLAMO_CLOCK_ISP_EN_M2CLK |
++			       GLAMO_CLOCK_ISP_EN_I1CLK,
++			       0);
++		MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_GEN5_2,
++			       GLAMO_CLOCK_GEN52_EN_DIV_ICLK,
++			       0);
++		MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_GEN5_1,
++			       GLAMO_CLOCK_GEN51_EN_DIV_JCLK,
++			       0);
++		MMIOSetBitMask(mmio, GLAMO_REG_HOSTBUS(2),
++			       GLAMO_HOSTBUS2_MMIO_EN_ISP,
++			       0);
++		break;
++	case GLAMO_ENGINE_2D:
++		MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_2D,
++			       GLAMO_CLOCK_2D_EN_M7CLK |
++			       GLAMO_CLOCK_2D_EN_GCLK |
++			       GLAMO_CLOCK_2D_DG_M7CLK |
++			       GLAMO_CLOCK_2D_DG_GCLK,
++			       0);
++		MMIOSetBitMask(mmio, GLAMO_REG_HOSTBUS(2),
++			       GLAMO_HOSTBUS2_MMIO_EN_2D,
++			       0);
++		MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_GEN5_1,
++			       GLAMO_CLOCK_GEN51_EN_DIV_GCLK,
++			       0);
++		break;
++	default:
++		break;
++	}
 +	return;
 +}
 +
@@ -1760,6 +1916,17 @@
 +		return;
 +
 +	switch (engine) {
++	case GLAMO_ENGINE_CMDQ:
++		MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_2D,
++			       GLAMO_CLOCK_2D_EN_M6CLK,
++			       0xffff);
++		MMIOSetBitMask(mmio, GLAMO_REG_HOSTBUS(2),
++			       GLAMO_HOSTBUS2_MMIO_EN_CMDQ,
++			       0xffff);
++		MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_GEN5_1,
++			       GLAMO_CLOCK_GEN51_EN_DIV_MCLK,
++			       0xffff);
++		break;
 +	case GLAMO_ENGINE_ISP:
 +		MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_ISP,
 +			       GLAMO_CLOCK_ISP_EN_M2CLK |
@@ -1775,17 +1942,6 @@
 +			       GLAMO_HOSTBUS2_MMIO_EN_ISP,
 +			       0xffff);
 +		break;
-+	case GLAMO_ENGINE_CQ:
-+		MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_2D,
-+			       GLAMO_CLOCK_2D_EN_M6CLK,
-+			       0xffff);
-+		MMIOSetBitMask(mmio, GLAMO_REG_HOSTBUS(2),
-+			       GLAMO_HOSTBUS2_MMIO_EN_CQ,
-+			       0xffff);
-+		MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_GEN5_1,
-+			       GLAMO_CLOCK_GEN51_EN_DIV_MCLK,
-+			       0xffff);
-+		break;
 +	case GLAMO_ENGINE_2D:
 +		MMIOSetBitMask(mmio, GLAMO_REG_CLOCK_2D,
 +				GLAMO_CLOCK_2D_EN_M7CLK |
@@ -1800,20 +1956,89 @@
 +			       GLAMO_CLOCK_GEN51_EN_DIV_GCLK,
 +			       0xffff);
 +		break;
++	default:
++		break;
 +	}
 +}
 +
++int
++GLAMOEngineBusy(ScreenPtr pScreen, enum glamo_engine engine)
++{
++	KdScreenPriv(pScreen);
++	GLAMOCardInfo(pScreenPriv);
++	GLAMOScreenInfo(pScreenPriv);
++	char *mmio = glamoc->reg_base;
++	CARD16 status, mask, val;
++
++	if (!mmio)
++		return FALSE;
++
++	if (glamos->indirectBuffer != NULL)
++		GLAMOFlushIndirect(glamos, 0);
++
++	switch (engine)
++	{
++	case GLAMO_ENGINE_CMDQ:
++		mask = 0x3;
++		val  = mask;
++		break;
++	case GLAMO_ENGINE_ISP:
++		mask = 0x3 | (1 << 8);
++		val  = 0x3;
++		break;
++	case GLAMO_ENGINE_2D:
++		mask = 0x3 | (1 << 4);
++		val  = 0x3;
++		break;
++	case GLAMO_ENGINE_ALL:
++	default:
++		mask = 1 << 2;
++		val  = mask;
++		break;
++	}
++
++	status = MMIO_IN16(mmio, GLAMO_REG_CMDQ_STATUS);
++
++	return !((status & mask) == val);
++}
++
 +void
-+GLAMOWaitIdle(GLAMOScreenInfo *glamos)
++GLAMOEngineWait(ScreenPtr pScreen, enum glamo_engine engine)
 +{
-+	GLAMOCardInfo *glamoc = glamos->glamoc;
++	KdScreenPriv(pScreen);
++	GLAMOCardInfo(pScreenPriv);
++	GLAMOScreenInfo(pScreenPriv);
 +	char *mmio = glamoc->reg_base;
-+	CARD16 status;
++	CARD16 status, mask, val;
 +	TIMEOUT_LOCALS;
 +
++	if (!mmio)
++		return;
++
 +	if (glamos->indirectBuffer != NULL)
 +		GLAMOFlushIndirect(glamos, 0);
 +
++	switch (engine)
++	{
++	case GLAMO_ENGINE_CMDQ:
++		mask = 0x3;
++		val  = mask;
++		break;
++	case GLAMO_ENGINE_ISP:
++		mask = 0x3 | (1 << 8);
++		val  = 0x3;
++		break;
++	case GLAMO_ENGINE_2D:
++		mask = 0x3 | (1 << 4);
++		val  = 0x3;
++		break;
++	case GLAMO_ENGINE_ALL:
++	default:
++		mask = 1 << 2;
++		val  = mask;
++		break;
++	}
++
 +#ifdef USE_DRI
 +	if (glamos->using_dri) {
 +		int ret = 0;
@@ -1835,13 +2060,14 @@
 +#endif
 +
 +	WHILE_NOT_TIMEOUT(.5) {
-+		status = MMIO_IN16(mmio, GLAMO_REG_CQ_STATUS);
-+		if ((status & (1 << 2)) && !(status & (1 << 8)))
++		status = MMIO_IN16(mmio, GLAMO_REG_CMDQ_STATUS);
++		if ((status & mask) == val)
 +			break;
 +	}
 +	if (TIMEDOUT()) {
-+		ErrorF("Timeout idling accelerator, resetting...\n");
-+		GLAMOEngineReset(glamos->screen->pScreen, GLAMO_ENGINE_CQ);
++		ErrorF("Timeout idling accelerator (0x%x), resetting...\n",
++				status);
++		GLAMOEngineReset(glamos->screen->pScreen, GLAMO_ENGINE_CMDQ);
 +		GLAMODrawSetup(glamos->screen->pScreen);
 +	}
 +
@@ -1851,7 +2077,7 @@
 +#endif
 +}
 +
-+dmaBuf *
++static dmaBuf *
 +GLAMOGetDMABuffer(GLAMOScreenInfo *glamos)
 +{
 +	dmaBuf *buf;
@@ -1899,33 +2125,35 @@
 +	count = (buf->used - glamos->indirectStart) / 2;
 +	ring_count = glamos->ring_len / 2;
 +
++	/* write pointer can be ring_size, but not zero */
 +	WHILE_NOT_TIMEOUT(.5) {
 +		if (count <= 0)
 +			break;
 +
-+		glamos->ring_addr[glamos->ring_write++] = *addr++;
 +		if (glamos->ring_write >= ring_count)
 +			glamos->ring_write = 0;
 +
++		glamos->ring_addr[glamos->ring_write++] = *addr++;
++
 +		while (glamos->ring_write == glamos->ring_read)
 +		{
 +			glamos->ring_read =
-+				MMIO_IN16(mmio, GLAMO_REG_CQ_READ_ADDRL);
++				MMIO_IN16(mmio, GLAMO_REG_CMDQ_READ_ADDRL);
 +			glamos->ring_read |=
-+				(MMIO_IN16(mmio, GLAMO_REG_CQ_READ_ADDRH) & 0x7) << 16;
++				(MMIO_IN16(mmio, GLAMO_REG_CMDQ_READ_ADDRH) & 0x7) << 16;
 +		}
 +
 +		count--;
 +	}
 +	if (TIMEDOUT()) {
 +		ErrorF("Timeout submitting packets, resetting...\n");
-+		GLAMOEngineReset(glamos->screen->pScreen, GLAMO_ENGINE_CQ);
++		GLAMOEngineReset(glamos->screen->pScreen, GLAMO_ENGINE_CMDQ);
 +		GLAMODrawSetup(glamos->screen->pScreen);
 +	}
 +
-+	MMIO_OUT16(mmio, GLAMO_REG_CQ_WRITE_ADDRH,
++	MMIO_OUT16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRH,
 +			 (glamos->ring_write >> 15) & 0x7);
-+	MMIO_OUT16(mmio, GLAMO_REG_CQ_WRITE_ADDRL,
++	MMIO_OUT16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRL,
 +			 (glamos->ring_write <<  1) & 0xffff);
 +}
 +
@@ -1938,8 +2166,8 @@
 +		return;
 +
 +#if DEBUG_FIFO
-+	ErrorF("Dispatching %d DWORDS\n", (buf->used - glamos->indirectStart) /
-+	    4);
++	ErrorF("Dispatching %d WORDS\n", (buf->used - glamos->indirectStart) /
++	    2);
 +#endif
 +
 +#ifdef USE_DRI
@@ -1991,20 +2219,20 @@
 +	glamos->ring_addr[glamos->ring_len / 2] = 0x0;
 +	glamos->ring_addr[glamos->ring_len / 2 + 1] = 0x0;
 +
-+	GLAMOEngineEnable(glamos->screen->pScreen, GLAMO_ENGINE_CQ);
-+	GLAMOEngineReset(glamos->screen->pScreen, GLAMO_ENGINE_CQ);
++	GLAMOEngineEnable(glamos->screen->pScreen, GLAMO_ENGINE_CMDQ);
++	GLAMOEngineReset(glamos->screen->pScreen, GLAMO_ENGINE_CMDQ);
 +
-+	MMIO_OUT16(mmio, GLAMO_REG_CQ_BASE_ADDRL,
++	MMIO_OUT16(mmio, GLAMO_REG_CMDQ_BASE_ADDRL,
 +			 glamos->dma_space->offset & 0xffff);
-+	MMIO_OUT16(mmio, GLAMO_REG_CQ_BASE_ADDRH,
++	MMIO_OUT16(mmio, GLAMO_REG_CMDQ_BASE_ADDRH,
 +			 (glamos->dma_space->offset >> 16) & 0x7f);
-+	MMIO_OUT16(mmio, GLAMO_REG_CQ_LEN, cq_len);
++	MMIO_OUT16(mmio, GLAMO_REG_CMDQ_LEN, cq_len);
 +
-+	MMIO_OUT16(mmio, GLAMO_REG_CQ_WRITE_ADDRH, 0);
-+	MMIO_OUT16(mmio, GLAMO_REG_CQ_WRITE_ADDRL, 0);
-+	MMIO_OUT16(mmio, GLAMO_REG_CQ_READ_ADDRH, 0);
-+	MMIO_OUT16(mmio, GLAMO_REG_CQ_READ_ADDRL, 0);
-+	MMIO_OUT16(mmio, GLAMO_REG_CQ_CONTROL,
++	MMIO_OUT16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRH, 0);
++	MMIO_OUT16(mmio, GLAMO_REG_CMDQ_WRITE_ADDRL, 0);
++	MMIO_OUT16(mmio, GLAMO_REG_CMDQ_READ_ADDRH, 0);
++	MMIO_OUT16(mmio, GLAMO_REG_CMDQ_READ_ADDRL, 0);
++	MMIO_OUT16(mmio, GLAMO_REG_CMDQ_CONTROL,
 +			 1 << 12 |
 +			 5 << 8 |
 +			 8 << 4);
@@ -2027,6 +2255,7 @@
 +		GLAMODMAInit(pScreen);
 +
 +	glamos->indirectBuffer = GLAMOGetDMABuffer(glamos);
++
 +	if (glamos->indirectBuffer == FALSE)
 +		FatalError("Failed to allocate DMA buffer.\n");
 +
@@ -2042,7 +2271,7 @@
 +	KdScreenPriv(pScreen);
 +	GLAMOScreenInfo(pScreenPriv);
 +
-+	GLAMOWaitIdle(glamos);
++	GLAMOEngineWait(pScreen, GLAMO_ENGINE_ALL);
 +
 +#ifdef USE_DRI
 +	if (glamos->using_dri)
@@ -2053,11 +2282,12 @@
 +	xfree(glamos->indirectBuffer);
 +	glamos->indirectBuffer = NULL;
 +}
-Index: xserver/hw/kdrive/glamo/glamo_dma.h
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ xserver/hw/kdrive/glamo/glamo_dma.h	2007-09-25 19:17:53.000000000 +0800
-@@ -0,0 +1,159 @@
+diff --git a/hw/kdrive/glamo/glamo_dma.h b/hw/kdrive/glamo/glamo_dma.h
+new file mode 100644
+index 0000000..1ff78b7
+--- /dev/null
++++ b/hw/kdrive/glamo/glamo_dma.h
+@@ -0,0 +1,153 @@
 +/*
 + * Copyright © 2007 OpenMoko, Inc.
 + *
@@ -2089,21 +2319,7 @@
 +#define CCE_DEBUG 1
 +
 +#if !CCE_DEBUG
-+#define DMA_PACKET0(reg, count)						\
-+	(reg)
-+#else
-+#define DMA_PACKET0(reg, count)						\
-+	(__packet0count = (count), __reg = (reg),			\
-+	(reg))
-+#endif
-+#define DMA_PACKET1(reg1, reg2)						\
-+	(GLAMO_CCE_PACKET1 |						\
-+	(((reg2) >> 2) << GLAMO_CCE_PACKET1_REG_2_SHIFT) |  ((reg1) >> 2))
-+#define DMA_PACKET3(type, count)					\
-+	((type) | (((count) - 1) << 16))
 +
-+#if !CCE_DEBUG
-+
 +#define RING_LOCALS	CARD16 *__head; int __count
 +#define BEGIN_DMA(n)							\
 +do {									\
@@ -2133,23 +2349,25 @@
 +	    glamos->indirectBuffer->used);				\
 +	__count = 0;							\
 +	__total = n;							\
-+	__reg = 0;								\
-+	__packet0count = 0;								\
++	__reg = 0;							\
++	__packet0count = 0;						\
 +} while (0)
 +#define END_DMA() do {							\
 +	if (__count != __total)						\
-+		FatalError("count != total (%d vs %d) at %s:%d\n",	 \
++		FatalError("count != total (%d vs %d) at %s:%d\n",	\
 +		     __count, __total, __FILE__, __LINE__);		\
 +	glamos->indirectBuffer->used += __count * 2;			\
 +} while (0)
 +
 +#endif
 +
-+#define OUT_RING(val) do {						\
-+	__head[__count++] = (val);					\
++#define OUT_PAIR(v1, v2)						\
++do {									\
++	__head[__count++] = (v1);					\
++	__head[__count++] = (v2);					\
 +} while (0)
 +
-+#define OUT_RING_REG(reg, val) do {					\
++#define OUT_BURST_REG(reg, val) do {					\
 +	if (__reg != reg)						\
 +		FatalError("unexpected reg (0x%x vs 0x%x) at %s:%d\n",	\
 +		    reg, __reg, __FILE__, __LINE__);			\
@@ -2157,15 +2375,17 @@
 +		FatalError("overrun of packet0 at %s:%d\n",		\
 +		    __FILE__, __LINE__);				\
 +	__head[__count++] = (val);					\
-+	__reg += 4;							\
++	__reg += 2;							\
 +} while (0)
 +
-+#define OUT_RING_F(x) OUT_RING(GET_FLOAT_BITS(x))
++#define OUT_REG(reg, val)						\
++	OUT_PAIR(reg, val)
 +
-+#define OUT_REG(reg, val)						\
++#define OUT_BURST(reg, n)						\
 +do {									\
-+	OUT_RING(DMA_PACKET0(reg, 1));					\
-+	OUT_RING(val);							\
++	OUT_PAIR((1 << 15) | reg, n);					\
++	__reg = reg;							\
++	__packet0count = n;						\
 +} while (0)
 +
 +#define TIMEOUT_LOCALS struct timeval _target, _curtime
@@ -2189,9 +2409,6 @@
 +
 +#define TIMEDOUT()	(!tv_le(&_curtime, &_target))
 +
-+dmaBuf *
-+GLAMOGetDMABuffer(GLAMOScreenInfo *glamos);
-+
 +void
 +GLAMOFlushIndirect(GLAMOScreenInfo *glamos, Bool discard);
 +
@@ -2202,9 +2419,10 @@
 +GLAMODMATeardown(ScreenPtr pScreen);
 +
 +enum glamo_engine {
++	GLAMO_ENGINE_CMDQ,
 +	GLAMO_ENGINE_ISP,
-+	GLAMO_ENGINE_CQ,
 +	GLAMO_ENGINE_2D,
++	GLAMO_ENGINE_ALL /* for GLAMOEngineWait */
 +};
 +
 +void
@@ -2216,12 +2434,19 @@
 +void
 +GLAMOEngineReset(ScreenPtr pScreen, enum glamo_engine engine);
 +
++int
++GLAMOEngineBusy(ScreenPtr pScreen, enum glamo_engine engine);
++
++void
++GLAMOEngineWait(ScreenPtr pScreen, enum glamo_engine engine);
++
 +#endif /* _GLAMO_DMA_H_ */
-Index: xserver/hw/kdrive/glamo/glamo_draw.c
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ xserver/hw/kdrive/glamo/glamo_draw.c	2007-09-26 17:46:30.000000000 +0800
-@@ -0,0 +1,522 @@
+diff --git a/hw/kdrive/glamo/glamo_draw.c b/hw/kdrive/glamo/glamo_draw.c
+new file mode 100644
+index 0000000..f58a1fc
+--- /dev/null
++++ b/hw/kdrive/glamo/glamo_draw.c
+@@ -0,0 +1,557 @@
 +/*
 + * Copyright © 2007 OpenMoko, Inc.
 + *
@@ -2256,6 +2481,15 @@
 +#include "glamo_draw.h"
 +#include "kaa.h"
 +
++#define ENGINE_MAX_WIDTH 640
++#define ENGINE_MAX_HEIGHT 640
++#define ENGINE_MAX_PITCH (ENGINE_MAX_WIDTH * 2)
++
++#define ENGINE_CHECK(pPix) \
++	(((pPix)->drawable.width > ENGINE_MAX_WIDTH) || \
++	 ((pPix)->drawable.height > ENGINE_MAX_HEIGHT) || \
++	 ((pPix)->devKind > ENGINE_MAX_PITCH))
++
 +static const CARD8 GLAMOSolidRop[16] = {
 +    /* GXclear      */      0x00,         /* 0 */
 +    /* GXand        */      0xa0,         /* src AND dst */
@@ -2294,12 +2528,15 @@
 +    /* GXset        */      0xff,         /* 1 */
 +};
 +
-+GLAMOScreenInfo *accel_glamos;
-+CARD32 settings, color, src_pitch_offset, dst_pitch_offset;
++static struct {
++	GLAMOScreenInfo *glamos;
++	CARD32 src_offset, dst_offset;
++	CARD16 src_pitch, dst_pitch;
++} glamo_blt;
 +
-+int sample_count;
-+float sample_offsets_x[255];
-+float sample_offsets_y[255];
++static int sample_count;
++static float sample_offsets_x[255];
++static float sample_offsets_y[255];
 +
 +void
 +GLAMODrawSetup(ScreenPtr pScreen)
@@ -2311,11 +2548,8 @@
 +static void
 +GLAMOWaitMarker(ScreenPtr pScreen, int marker)
 +{
-+	KdScreenPriv(pScreen);
-+	GLAMOScreenInfo(pScreenPriv);
-+
 +	ENTER_DRAW(0);
-+	GLAMOWaitIdle(glamos);
++	GLAMOEngineWait(pScreen, GLAMO_ENGINE_ALL);
 +	LEAVE_DRAW(0);
 +}
 +
@@ -2330,9 +2564,11 @@
 +	offset = ((CARD8 *)pPix->devPrivate.ptr -
 +		  pScreenPriv->screen->memory_base);
 +
-+	ErrorF ("Enter %s 0x%x (%dx%dx%d/%d)\n", function, (unsigned int) offset,
-+	    pPix->drawable.width, pPix->drawable.height, pPix->drawable.depth,
-+	    (unsigned int) pPix->drawable.bitsPerPixel);
++	ErrorF ("Enter %s 0x%x (%dx%dx%d/%d)\n",
++			function, (unsigned int) offset,
++			pPix->drawable.width, pPix->drawable.height,
++			pPix->drawable.depth,
++			(unsigned int) pPix->drawable.bitsPerPixel);
 +    } else
 +	ErrorF ("Enter %s\n", function);
 +}
@@ -2358,8 +2594,8 @@
 +{
 +	KdScreenPriv(pPix->drawable.pScreen);
 +	GLAMOScreenInfo(pScreenPriv);
-+	CARD32 offset, pitch;
 +	FbBits mask;
++	CARD16 cmd2;
 +	RING_LOCALS;
 +
 +	if (pPix->drawable.bitsPerPixel != 16)
@@ -2367,24 +2603,28 @@
 +
 +	mask = FbFullMask(16);
 +	if ((pm & mask) != mask)
-+		GLAMO_FALLBACK(("Can't do planemask 0x%08x\n", (unsigned int) pm));
++		GLAMO_FALLBACK(("Can't do planemask 0x%08x\n",
++					(unsigned int) pm));
 +
-+	accel_glamos = glamos;
++	if (ENGINE_CHECK(pPix))
++		GLAMO_FALLBACK(("Out of engine's capability\n"));
 +
-+	settings = GLAMOSolidRop[alu] << 8;
-+	offset = ((CARD8 *) pPix->devPrivate.ptr -
-+			pScreenPriv->screen->memory_base);
-+	pitch = pPix->devKind;
++	glamo_blt.glamos = glamos;
++	glamo_blt.dst_offset = (CARD8 *) pPix->devPrivate.ptr -
++					 pScreenPriv->screen->memory_base;
++	glamo_blt.dst_pitch = pPix->devKind;
 +
++	cmd2 = GLAMOSolidRop[alu] << 8;
++
 +	ENTER_DRAW(pPix);
 +
 +	BEGIN_DMA(12);
-+	OUT_REG(GLAMO_REG_2D_DST_ADDRL, offset & 0xffff);
-+	OUT_REG(GLAMO_REG_2D_DST_ADDRH, (offset >> 16) & 0x7f);
-+	OUT_REG(GLAMO_REG_2D_DST_PITCH, pitch);
-+	OUT_REG(GLAMO_REG_2D_DST_HEIGHT, pPix->drawable.height);
++	OUT_REG(GLAMO_REG_2D_DST_ADDRL, glamo_blt.dst_offset & 0xffff);
++	OUT_REG(GLAMO_REG_2D_DST_ADDRH, (glamo_blt.dst_offset >> 16) & 0x7f);
++	OUT_REG(GLAMO_REG_2D_DST_PITCH, glamo_blt.dst_pitch);
++	OUT_REG(GLAMO_REG_2D_DST_HEIGHT, ENGINE_MAX_HEIGHT - 1);
 +	OUT_REG(GLAMO_REG_2D_PAT_FG, fg);
-+	OUT_REG(GLAMO_REG_2D_COMMAND2, settings);
++	OUT_REG(GLAMO_REG_2D_COMMAND2, cmd2);
 +	END_DMA();
 +
 +	LEAVE_DRAW(pPix);
@@ -2395,10 +2635,11 @@
 +static void
 +GLAMOSolid(int x1, int y1, int x2, int y2)
 +{
-+	ENTER_DRAW(0);
-+	GLAMOScreenInfo *glamos = accel_glamos;
++	GLAMOScreenInfo *glamos = glamo_blt.glamos;
 +	RING_LOCALS;
 +
++	ENTER_DRAW(0);
++
 +	BEGIN_DMA(14);
 +	OUT_REG(GLAMO_REG_2D_DST_X, x1);
 +	OUT_REG(GLAMO_REG_2D_DST_Y, y1);
@@ -2408,6 +2649,7 @@
 +	OUT_REG(GLAMO_REG_2D_ID1, 0);
 +	OUT_REG(GLAMO_REG_2D_ID2, 0);
 +	END_DMA();
++
 +	LEAVE_DRAW(0);
 +}
 +
@@ -2419,12 +2661,12 @@
 +}
 +
 +static Bool
-+GLAMOPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu, Pixel pm)
++GLAMOPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy,
++		int alu, Pixel pm)
 +{
 +	KdScreenPriv(pDst->drawable.pScreen);
 +	GLAMOScreenInfo(pScreenPriv);
-+	CARD32 src_offset, src_pitch;
-+	CARD32 dst_offset, dst_pitch;
++	CARD16 cmd2;
 +	FbBits mask;
 +	RING_LOCALS;
 +
@@ -2434,35 +2676,33 @@
 +
 +	mask = FbFullMask(16);
 +	if ((pm & mask) != mask)
-+		GLAMO_FALLBACK(("Can't do planemask 0x%08x", (unsigned int) pm));
++		GLAMO_FALLBACK(("Can't do planemask 0x%08x",
++					(unsigned int) pm));
 +
-+	accel_glamos = glamos;
++	if ((ENGINE_CHECK(pSrc) || ENGINE_CHECK(pDst)))
++		GLAMO_FALLBACK(("Out of engine's capability\n"));
 +
-+	src_offset = ((CARD8 *) pSrc->devPrivate.ptr -
-+			pScreenPriv->screen->memory_base);
-+	src_pitch = pSrc->devKind;
++	glamo_blt.glamos = glamos;
++	glamo_blt.src_offset = (CARD8 *) pSrc->devPrivate.ptr -
++					 pScreenPriv->screen->memory_base;
++	glamo_blt.src_pitch = pSrc->devKind;
++	glamo_blt.dst_offset = (CARD8 *) pDst->devPrivate.ptr -
++					 pScreenPriv->screen->memory_base;
++	glamo_blt.dst_pitch = pDst->devKind;
 +
-+	dst_offset = ((CARD8 *) pDst->devPrivate.ptr -
-+			pScreenPriv->screen->memory_base);
-+	dst_pitch = pDst->devKind;
++	cmd2 = GLAMOBltRop[alu] << 8;
 +
-+	settings = GLAMOBltRop[alu] << 8;
++	ENTER_DRAW(pDst);
 +
-+	ENTER_DRAW (pDst);
-+
 +	BEGIN_DMA(16);
-+
-+	OUT_REG(GLAMO_REG_2D_SRC_ADDRL, src_offset & 0xffff);
-+	OUT_REG(GLAMO_REG_2D_SRC_ADDRH, (src_offset >> 16) & 0x7f);
-+	OUT_REG(GLAMO_REG_2D_SRC_PITCH, src_pitch);
-+
-+	OUT_REG(GLAMO_REG_2D_DST_ADDRL, dst_offset & 0xffff);
-+	OUT_REG(GLAMO_REG_2D_DST_ADDRH, (dst_offset >> 16) & 0x7f);
-+	OUT_REG(GLAMO_REG_2D_DST_PITCH, dst_pitch);
-+	OUT_REG(GLAMO_REG_2D_DST_HEIGHT, pDst->drawable.height);
-+
-+	OUT_REG(GLAMO_REG_2D_COMMAND2, settings);
-+
++	OUT_REG(GLAMO_REG_2D_SRC_ADDRL, glamo_blt.src_offset & 0xffff);
++	OUT_REG(GLAMO_REG_2D_SRC_ADDRH, (glamo_blt.src_offset >> 16) & 0x7f);
++	OUT_REG(GLAMO_REG_2D_SRC_PITCH, glamo_blt.src_pitch);
++	OUT_REG(GLAMO_REG_2D_DST_ADDRL, glamo_blt.dst_offset & 0xffff);
++	OUT_REG(GLAMO_REG_2D_DST_ADDRH, (glamo_blt.dst_offset >> 16) & 0x7f);
++	OUT_REG(GLAMO_REG_2D_DST_PITCH, glamo_blt.dst_pitch);
++	OUT_REG(GLAMO_REG_2D_DST_HEIGHT, ENGINE_MAX_HEIGHT - 1);
++	OUT_REG(GLAMO_REG_2D_COMMAND2, cmd2);
 +	END_DMA();
 +
 +	LEAVE_DRAW(pDst);
@@ -2473,9 +2713,11 @@
 +static void
 +GLAMOCopy(int srcX, int srcY, int dstX, int dstY, int w, int h)
 +{
-+	GLAMOScreenInfo *glamos = accel_glamos;
++	GLAMOScreenInfo *glamos = glamo_blt.glamos;
 +	RING_LOCALS;
 +
++	ENTER_DRAW (0);
++
 +	BEGIN_DMA(18);
 +	OUT_REG(GLAMO_REG_2D_SRC_X, srcX);
 +	OUT_REG(GLAMO_REG_2D_SRC_Y, srcY);
@@ -2487,6 +2729,8 @@
 +	OUT_REG(GLAMO_REG_2D_ID1, 0);
 +	OUT_REG(GLAMO_REG_2D_ID2, 0);
 +	END_DMA();
++
++	LEAVE_DRAW(0);
 +}
 +
 +static void
@@ -2653,6 +2897,10 @@
 +	if (!kaaDrawInit(pScreen, &glamos->kaa))
 +		return FALSE;
 +
++#ifdef XV
++	GLAMOInitVideo(pScreen);
++#endif
++
 +	return TRUE;
 +}
 +
@@ -2716,6 +2964,10 @@
 +	}
 +#endif
 +
++#ifdef XV
++	GLAMOVideoSetup(pScreen);
++#endif
++
 +	kaaMarkSync(pScreen);
 +}
 +
@@ -2723,12 +2975,21 @@
 +GLAMODrawDisable(ScreenPtr pScreen)
 +{
 +	kaaWaitSync(pScreen);
++
++#ifdef XV
++	GLAMOVideoTeardown(pScreen);
++#endif
++
 +	GLAMODMATeardown(pScreen);
 +}
 +
 +void
 +GLAMODrawFini(ScreenPtr pScreen)
 +{
++#ifdef XV
++	GLAMOFiniVideo(pScreen);
++#endif
++
 +#ifdef USE_DRI
 +	KdScreenPriv(pScreen);
 +	GLAMOScreenInfo(pScreenPriv);
@@ -2743,12 +3004,12 @@
 +
 +	kaaDrawFini(pScreen);
 +}
-+
-Index: xserver/hw/kdrive/glamo/glamo_draw.h
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ xserver/hw/kdrive/glamo/glamo_draw.h	2007-09-25 19:02:01.000000000 +0800
-@@ -0,0 +1,59 @@
+diff --git a/hw/kdrive/glamo/glamo_draw.h b/hw/kdrive/glamo/glamo_draw.h
+new file mode 100644
+index 0000000..f23f812
+--- /dev/null
++++ b/hw/kdrive/glamo/glamo_draw.h
+@@ -0,0 +1,57 @@
 +/*
 + * Copyright © 2007 OpenMoko, Inc.
 + *
@@ -2777,10 +3038,8 @@
 +#ifndef _GLAMO_DRAW_H_
 +#define _GLAMO_DRAW_H_
 +
-+void GLAMOWaitIdle(GLAMOScreenInfo *glamos);
-+
 +#define GLAMO_TRACE_FALL 1
-+#define GLAMO_TRACE_DRAW 1
++#define GLAMO_TRACE_DRAW 0
 +
 +#if GLAMO_TRACE_FALL
 +#define GLAMO_FALLBACK(x)			\
@@ -2808,11 +3067,12 @@
 +#endif /* !GLAMO_TRACE */
 +
 +#endif /* _GLAMO_DRAW_H_ */
-Index: xserver/hw/kdrive/glamo/glamo_stub.c
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ xserver/hw/kdrive/glamo/glamo_stub.c	2007-09-26 17:45:27.000000000 +0800
-@@ -0,0 +1,84 @@
+diff --git a/hw/kdrive/glamo/glamo_stub.c b/hw/kdrive/glamo/glamo_stub.c
+new file mode 100644
+index 0000000..df43455
+--- /dev/null
++++ b/hw/kdrive/glamo/glamo_stub.c
+@@ -0,0 +1,78 @@
 +/*
 + * Copyright © 2007 OpenMoko, Inc.
 + *
@@ -2864,16 +3124,10 @@
 +void
 +InitInput(int argc, char **argv)
 +{
-+	KdKeyboardInfo *ki;
-+
-+	KdAddKeyboardDriver(&LinuxKeyboardDriver);
-+	KdAddPointerDriver(&LinuxMouseDriver);
-+#ifdef TSLIB
-+	KdAddPointerDriver(&TsDriver);
++	KdInitInput (&LinuxEvdevMouseFuncs, &LinuxEvdevKeyboardFuncs);
++#ifdef TOUCHSCREEN
++	KdAddMouseDriver (&TsFuncs);
 +#endif
-+
-+	ki = KdParseKeyboard("keybd");
-+	KdAddKeyboard(ki);
 +}
 +
 +void
@@ -2897,11 +3151,12 @@
 +
 +	return ret;
 +}
-Index: xserver/hw/kdrive/glamo/glamo_video.c
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ xserver/hw/kdrive/glamo/glamo_video.c	2007-09-26 17:47:55.000000000 +0800
-@@ -0,0 +1,798 @@
+diff --git a/hw/kdrive/glamo/glamo_video.c b/hw/kdrive/glamo/glamo_video.c
+new file mode 100644
+index 0000000..b362db1
+--- /dev/null
++++ b/hw/kdrive/glamo/glamo_video.c
+@@ -0,0 +1,974 @@
 +/*
 + * Copyright © 2007 OpenMoko, Inc.
 + *
@@ -2942,6 +3197,9 @@
 +
 +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
 +
++#define SYS_PITCH_ALIGN(w) (((w) + 3) & ~3)
++#define VID_PITCH_ALIGN(w) (((w) + 1) & ~1)
++
 +static Atom xvBrightness, xvSaturation;
 +
 +#define IMAGE_MAX_WIDTH		2048
@@ -2950,15 +3208,18 @@
 +static void
 +GLAMOStopVideo(KdScreenInfo *screen, pointer data, Bool exit)
 +{
++	int i;
++
 +	ScreenPtr pScreen = screen->pScreen;
 +	GLAMOPortPrivPtr pPortPriv = (GLAMOPortPrivPtr)data;
 +
 +	REGION_EMPTY(screen->pScreen, &pPortPriv->clip);
 +
-+	if (pPortPriv->off_screen) {
-+		KdOffscreenFree (pScreen, pPortPriv->off_screen);
-+		pPortPriv->off_screen = 0;
-+	}
++	for (i = 0; i < GLAMO_VIDEO_NUM_BUFS; i++)
++		if (pPortPriv->off_screen[i]) {
++			KdOffscreenFree (pScreen, pPortPriv->off_screen[i]);
++			pPortPriv->off_screen[i] = 0;
++		}
 +}
 +
 +static int
@@ -3058,12 +3319,13 @@
 +	KdScreenPriv(pScreen);
 +	GLAMOScreenInfo(pScreenPriv);
 +	PixmapPtr pPixmap = pPortPriv->pPixmap;
-+	CARD32 dst_offset, dst_pitch;
-+	int dstxoff, dstyoff, srcDatatype;
++	CARD32 dst_offset, dst_pitch, *offsets;
++	int dstxoff, dstyoff;
 +	RING_LOCALS;
 +
 +	BoxPtr pBox = REGION_RECTS(&pPortPriv->clip);
 +	int nBox = REGION_NUM_RECTS(&pPortPriv->clip);
++	int en3;
 +
 +	dst_offset = ((CARD8 *)pPixmap->devPrivate.ptr -
 +	    pScreenPriv->screen->memory_base);
@@ -3077,85 +3339,24 @@
 +	dstyoff = 0;
 +#endif
 +
-+	BEGIN_DMA(14);
-+	OUT_REG(GLAMO_REG_ISP_YUV2RGB_11, 0x0167);
-+	OUT_REG(GLAMO_REG_ISP_YUV2RGB_21, 0x01c5);
-+	OUT_REG(GLAMO_REG_ISP_YUV2RGB_32, 0x00b6);
-+	OUT_REG(GLAMO_REG_ISP_YUV2RGB_33, 0x0058);
-+	OUT_REG(GLAMO_REG_ISP_YUV2RGB_RG, 0xb3 << 8 | 0x89);
-+	OUT_REG(GLAMO_REG_ISP_YUV2RGB_B, 0xe2);
++	en3 = GLAMO_ISP_EN3_PLANE_MODE |
++	      GLAMO_ISP_EN3_YUV_INPUT |
++	      GLAMO_ISP_EN3_YUV420;
++	en3 |= GLAMO_ISP_EN3_SCALE_IMPROVE;
 +
-+	/* TODO weight matrix */
++	BEGIN_DMA(8);
 +
-+	OUT_REG(GLAMO_REG_ISP_PORT2_EN, GLAMO_ISP_PORT2_EN_DECODE);
++	OUT_REG(GLAMO_REG_ISP_EN3, en3);
++	OUT_REG(GLAMO_REG_ISP_DEC_PITCH_Y, pPortPriv->src_pitch1 & 0x1fff);
++	OUT_REG(GLAMO_REG_ISP_DEC_PITCH_UV, pPortPriv->src_pitch2 & 0x1fff);
++	OUT_REG(GLAMO_REG_ISP_PORT1_DEC_PITCH, dst_pitch & 0x1fff);
 +
 +	END_DMA();
 +
-+	if (pPortPriv->id == FOURCC_UYVY)
-+		srcDatatype = 3;
-+	else
-+		srcDatatype = 1;
++	offsets = pPortPriv->src_offsets[pPortPriv->idx];
 +
-+	BEGIN_DMA(8);
-+#if 0
-+	OUT_REG(GLAMO_REG_ISP_EN3, GLAMO_ISP_EN3_SCALE_IMPROVE |
-+				   GLAMO_ISP_EN3_PLANE_MODE |
-+				   GLAMO_ISP_EN3_YUV_INPUT |
-+				   GLAMO_ISP_EN3_YUV420);
-+	OUT_REG(GLAMO_REG_ISP_PORT1_DEC_EN, GLAMO_ISP_PORT1_EN_OUTPUT);
-+
-+	OUT_REG(GLAMO_REG_ISP_DEC_SCALEH, 1 << 11);
-+	OUT_REG(GLAMO_REG_ISP_DEC_SCALEV, 1 << 11);
-+
-+	{
-+		struct {
-+			int src_block_y;
-+			int src_block_x;
-+			int src_block_h;
-+			int src_block_w;
-+			int jpeg_out_y;
-+			int jpeg_out_x;
-+			int fifo_full_cnt;
-+			int in_length;
-+			int fifo_data_cnt;
-+			int in_height;
-+		} onfly;
-+
-+		onfly.src_block_y = 32;
-+		onfly.src_block_x = 32;
-+		onfly.src_block_h = 36;
-+		onfly.src_block_w = 35;
-+		onfly.jpeg_out_y = 32;
-+		onfly.jpeg_out_x = 32;
-+		onfly.fifo_full_cnt = 0;
-+		onfly.in_length = onfly.jpeg_out_x + 3;
-+		onfly.fifo_data_cnt = onfly.src_block_w * onfly.src_block_h / 2;
-+		onfly.in_height = onfly.jpeg_out_y + 2;
-+
-+		OUT_REG(GLAMO_REG_ISP_ONFLY_MODE1, onfly.src_block_y << 10 | onfly.src_block_x << 2);
-+		OUT_REG(GLAMO_REG_ISP_ONFLY_MODE2, onfly.src_block_h << 8 | onfly.src_block_w);
-+		OUT_REG(GLAMO_REG_ISP_ONFLY_MODE3, onfly.jpeg_out_y << 8 | onfly.jpeg_out_x);
-+		OUT_REG(GLAMO_REG_ISP_ONFLY_MODE4, onfly.fifo_full_cnt << 8 | onfly.in_length);
-+		OUT_REG(GLAMO_REG_ISP_ONFLY_MODE5, onfly.fifo_data_cnt << 6 | onfly.in_height);
-+	}
-+#endif
-+
-+	OUT_REG(GLAMO_REG_ISP_EN1,
-+		GLAMO_ISP_EN1_YUV420 |
-+		GLAMO_ISP_EN1_YUV_INPUT |
-+		GLAMO_ISP_EN1_YUV_PACK |
-+		((srcDatatype << 4) & 0x7));
-+
-+	OUT_REG(GLAMO_REG_ISP_PORT1_CAP_EN,
-+		GLAMO_ISP_PORT1_EN_OUTPUT);
-+
-+	OUT_REG(GLAMO_REG_ISP_CAP_PITCH, pPortPriv->src_pitch);
-+	OUT_REG(GLAMO_REG_ISP_PORT1_CAP_PITCH, dst_pitch);
-+
-+	END_DMA();
-+
 +	while (nBox--) {
-+		int srcX, srcY, dstX, dstY, srcw, srch, dstw, dsth;
++		int srcX, srcY, dstX, dstY, srcw, srch, dstw, dsth, scale;
 +		CARD32 srcO, dstO;
 +
 +		dstX = pBox->x1 + dstxoff;
@@ -3169,29 +3370,44 @@
 +		srcw = pPortPriv->src_w - srcX; /* XXX */
 +		srch = pPortPriv->src_h - srcY; /* XXX */
 +
-+		srcO = pPortPriv->src_offset + srcY * pPortPriv->src_pitch + srcX * 2;
++		GLAMOEngineWait(pScreen, GLAMO_ENGINE_ISP);
++
++		BEGIN_DMA(16);
++		srcO = offsets[0] + srcY * pPortPriv->src_pitch1 + srcX;
++		OUT_REG(GLAMO_REG_ISP_DEC_Y_ADDRL, srcO & 0xffff);
++		OUT_REG(GLAMO_REG_ISP_DEC_Y_ADDRH, (srcO >> 16) & 0x7f);
++
++		srcO = offsets[1] + srcY * pPortPriv->src_pitch2 + srcX;
++		OUT_REG(GLAMO_REG_ISP_DEC_U_ADDRL, srcO & 0xffff);
++		OUT_REG(GLAMO_REG_ISP_DEC_U_ADDRH, (srcO >> 16) & 0x7f);
++
++		srcO = offsets[2] + srcY * pPortPriv->src_pitch2 + srcX;
++		OUT_REG(GLAMO_REG_ISP_DEC_V_ADDRL, srcO & 0xffff);
++		OUT_REG(GLAMO_REG_ISP_DEC_V_ADDRH, (srcO >> 16) & 0x7f);
++
++		OUT_REG(GLAMO_REG_ISP_DEC_HEIGHT, srch & 0x1fff);
++		OUT_REG(GLAMO_REG_ISP_DEC_WIDTH, srcw & 0x1fff);
++		END_DMA();
++
++		BEGIN_DMA(16);
 +		dstO = dst_offset + dstY * dst_pitch + dstX * 2;
++		OUT_REG(GLAMO_REG_ISP_PORT1_DEC_0_ADDRL, dstO & 0xffff);
++		OUT_REG(GLAMO_REG_ISP_PORT1_DEC_0_ADDRH, (dstO >> 16) & 0x7f);
 +
-+		BEGIN_DMA(18);
++		OUT_REG(GLAMO_REG_ISP_PORT1_DEC_WIDTH, dstw & 0x1fff);
++		OUT_REG(GLAMO_REG_ISP_PORT1_DEC_HEIGHT, dsth & 0x1fff);
 +
-+		OUT_REG(GLAMO_REG_ISP_CAP_0_ADDRL, srcO & 0xffff);
-+		OUT_REG(GLAMO_REG_ISP_CAP_0_ADDRH, (srcO >> 16) & 0x7f);
-+		OUT_REG(GLAMO_REG_ISP_CAP_HEIGHT, srch);
-+		OUT_REG(GLAMO_REG_ISP_CAP_WIDTH, srcw);
++		scale = (srcw << 11) / dstw;
++		OUT_REG(GLAMO_REG_ISP_DEC_SCALEH, scale);
 +
-+		OUT_REG(GLAMO_REG_ISP_PORT1_CAP_0_ADDRL, dstO & 0xffff);
-+		OUT_REG(GLAMO_REG_ISP_PORT1_CAP_0_ADDRH, (dstO >> 16) & 0x7f);
-+		OUT_REG(GLAMO_REG_ISP_PORT1_CAP_WIDTH, dstw);
-+		OUT_REG(GLAMO_REG_ISP_PORT1_CAP_HEIGHT, dsth);
++		scale = (srch << 11) / dsth;
++		OUT_REG(GLAMO_REG_ISP_DEC_SCALEV, scale);
 +
-+		/* fire */
 +		OUT_REG(GLAMO_REG_ISP_EN1, GLAMO_ISP_EN1_FIRE_ISP);
 +		OUT_REG(GLAMO_REG_ISP_EN1, 0);
 +
 +		END_DMA();
 +
-+		GLAMOWaitIdle(glamos);
-+
 +		pBox++;
 +	}
 +#ifdef DAMAGEEXT
@@ -3207,12 +3423,159 @@
 +	KdScreenPriv(pScreen);
 +	GLAMOScreenInfo(pScreenPriv);
 +	GLAMOPortPrivPtr pPortPriv = glamos->pAdaptor->pPortPrivates[0].ptr;
++	int i;
 +
-+	if (pPortPriv->off_screen == area)
-+		pPortPriv->off_screen = 0;
++	for (i = 0; i < GLAMO_VIDEO_NUM_BUFS; i++)
++		if (pPortPriv->off_screen[i] == area)
++		{
++			pPortPriv->off_screen[i] = 0;
++
++			break;
++		}
 +}
 +
 +static int
++GLAMOUploadImage(KdScreenInfo *screen, DrawablePtr pDraw,
++		 GLAMOPortPrivPtr pPortPriv,
++		 short src_x, short src_y,
++		 short src_w, short src_h,
++		 int id,
++		 int randr,
++		 unsigned char *buf,
++		 short width, short height)
++{
++	CARD32 *offsets;
++	int srcPitch1, srcPitch2, dstPitch1, dstPitch2;
++	int src_x2, src_y2, size;
++	int idx;
++
++	src_x2 = src_x + src_w;
++	src_y2 = src_y + src_h;
++
++	src_x &= ~1;
++	src_y &= ~1;
++	src_w  = (src_x2 - src_x + 1) & ~1;
++	src_h  = (src_y2 - src_y + 1) & ~1;
++
++	switch (id) {
++	case FOURCC_YV12:
++	case FOURCC_I420:
++		srcPitch1 = SYS_PITCH_ALIGN(width);
++		srcPitch2 = SYS_PITCH_ALIGN(width / 2);
++		dstPitch1 = VID_PITCH_ALIGN(src_w);
++		dstPitch2 = VID_PITCH_ALIGN(src_w / 2);
++		size = (dstPitch1 + dstPitch2) * src_h;
++		break;
++	case FOURCC_UYVY:
++	case FOURCC_YUY2:
++	default:
++		srcPitch1 = width << 1;
++		srcPitch2 = 0;
++		dstPitch1 = src_w << 1;
++		dstPitch2 = 0;
++		size = dstPitch1 * src_h;
++		break;
++	}
++
++	idx = pPortPriv->idx;
++	//ErrorF("uploading to buffer %d\n", idx);
++
++	if (!pPortPriv->off_screen[idx] ||
++	    size > pPortPriv->off_screen[idx]->size) {
++		if (pPortPriv->off_screen[idx])
++			KdOffscreenFree(screen->pScreen,
++					pPortPriv->off_screen[idx]);
++
++		pPortPriv->off_screen[idx] =
++			KdOffscreenAlloc(screen->pScreen,
++					 size, VID_PITCH_ALIGN(1), TRUE,
++					 GLAMOVideoSave, pPortPriv);
++		if (!pPortPriv->off_screen[idx])
++			return BadAlloc;
++	}
++
++	if (pDraw->type == DRAWABLE_WINDOW)
++		pPortPriv->pPixmap =
++		    (*screen->pScreen->GetWindowPixmap)((WindowPtr)pDraw);
++	else
++		pPortPriv->pPixmap = (PixmapPtr)pDraw;
++
++	/* Migrate the pixmap to offscreen if necessary. */
++	if (!kaaPixmapIsOffscreen(pPortPriv->pPixmap))
++		kaaMoveInPixmap(pPortPriv->pPixmap);
++
++	if (!kaaPixmapIsOffscreen(pPortPriv->pPixmap))
++		return BadAlloc;
++
++	pPortPriv->pDraw = pDraw;
++
++	offsets = pPortPriv->src_offsets[idx];
++	offsets[0] = pPortPriv->off_screen[idx]->offset;
++	offsets[1] = offsets[0] + dstPitch1 * src_h;
++	offsets[2] = offsets[1] + dstPitch2 * src_h / 2;
++	pPortPriv->src_pitch1 = dstPitch1;
++	pPortPriv->src_pitch2 = dstPitch2;
++	pPortPriv->size[idx] = size;
++
++	/* copy data */
++	switch (id) {
++	case FOURCC_YV12:
++	case FOURCC_I420:
++		{
++			CARD8 *src1, *src2, *src3;
++			CARD8 *dst1, *dst2, *dst3;
++			int i;
++
++			src1 = buf + (src_y * srcPitch1) + src_x;
++			src2 = buf + (height * srcPitch1) +
++				(src_y * srcPitch2) + src_x / 2;
++			src3 = src2 + height * srcPitch2 / 2;
++
++			dst1 = (CARD8 *) (screen->memory_base + offsets[0]);
++
++			if (id == FOURCC_I420) {
++				dst2 = (CARD8 *) (screen->memory_base +
++						  offsets[1]);
++				dst3 = (CARD8 *) (screen->memory_base +
++						  offsets[2]);
++			} else {
++				dst2 = (CARD8 *) (screen->memory_base +
++						  offsets[2]);
++				dst3 = (CARD8 *) (screen->memory_base +
++						  offsets[1]);
++			}
++
++			for (i = 0; i < src_h; i++) {
++				memcpy(dst1, src1, src_w);
++				src1 += srcPitch1;
++				dst1 += dstPitch1;
++
++				if (!(i & 1)) {
++					memcpy(dst2, src2, src_w / 2);
++					memcpy(dst3, src3, src_w / 2);
++
++					src2 += srcPitch2;
++					dst2 += dstPitch2;
++					src3 += srcPitch2;
++					dst3 += dstPitch2;
++				}
++			}
++		}
++		break;
++	case FOURCC_UYVY:
++	case FOURCC_YUY2:
++	default:
++		KdXVCopyPackedData(screen, buf,
++				(CARD8 *)(screen->memory_base + offsets[0]),
++				randr, srcPitch1, dstPitch1,
++				src_w, src_h, src_y, src_x, src_h, src_w);
++		break;
++	}
++
++	return Success;
++}
++
++static int
 +GLAMOPutImage(KdScreenInfo *screen, DrawablePtr pDraw,
 +	       short src_x, short src_y,
 +	       short drw_x, short drw_y,
@@ -3229,13 +3592,11 @@
 +	ScreenPtr pScreen = screen->pScreen;
 +	KdScreenPriv(pScreen);
 +	GLAMOCardInfo(pScreenPriv);
-+	GLAMOScreenInfo(pScreenPriv);
 +	GLAMOPortPrivPtr pPortPriv = (GLAMOPortPrivPtr)data;
 +	char *mmio = glamoc->reg_base;
 +	INT32 x1, x2, y1, y2;
 +	int randr = RR_Rotate_0 /* XXX */;
-+	int srcPitch, srcPitch2, dstPitch;
-+	int top, left, npixels, nlines, size;
++	int top, left, npixels, nlines;
 +	BoxRec dstBox;
 +	int dst_width = width, dst_height = height;
 +	int rot_x1, rot_y1, rot_x2, rot_y2;
@@ -3327,87 +3688,25 @@
 +		break;
 +	}
 +
-+	switch(id) {
-+	case FOURCC_YV12:
-+	case FOURCC_I420:
-+		dstPitch = ((dst_width << 1) + 15) & ~15;
-+		srcPitch = (width + 3) & ~3;
-+		srcPitch2 = ((width >> 1) + 3) & ~3;
-+		size = dstPitch * dst_height;
-+		break;
-+	case FOURCC_UYVY:
-+	case FOURCC_YUY2:
-+	default:
-+		dstPitch = ((dst_width << 1) + 15) & ~15;
-+		srcPitch = (width << 1);
-+		srcPitch2 = 0;
-+		size = dstPitch * dst_height;
-+		break;
-+	}
-+
-+	if (pPortPriv->off_screen != NULL && size != pPortPriv->size) {
-+		KdOffscreenFree(screen->pScreen, pPortPriv->off_screen);
-+		pPortPriv->off_screen = 0;
-+	}
-+
-+	if (pPortPriv->off_screen == NULL) {
-+		pPortPriv->off_screen = KdOffscreenAlloc(screen->pScreen,
-+		    size * 2, 64, TRUE, GLAMOVideoSave, pPortPriv);
-+		if (pPortPriv->off_screen == NULL)
-+			return BadAlloc;
-+	}
-+
-+
-+	if (pDraw->type == DRAWABLE_WINDOW)
-+		pPortPriv->pPixmap =
-+		    (*pScreen->GetWindowPixmap)((WindowPtr)pDraw);
-+	else
-+		pPortPriv->pPixmap = (PixmapPtr)pDraw;
-+
-+	/* Migrate the pixmap to offscreen if necessary. */
-+	if (!kaaPixmapIsOffscreen(pPortPriv->pPixmap))
-+		kaaMoveInPixmap(pPortPriv->pPixmap);
-+
-+	if (!kaaPixmapIsOffscreen(pPortPriv->pPixmap)) {
-+		return BadAlloc;
-+	}
-+
-+	pPortPriv->src_offset = pPortPriv->off_screen->offset;
-+	pPortPriv->src_addr = (CARD8 *)(pScreenPriv->screen->memory_base +
-+	    pPortPriv->src_offset);
-+	pPortPriv->src_pitch = dstPitch;
-+	pPortPriv->size = size;
-+	pPortPriv->pDraw = pDraw;
-+
-+	/* copy data */
 +	top = rot_y1 >> 16;
-+	left = (rot_x1 >> 16) & ~1;
-+	npixels = ((((rot_x2 + 0xffff) >> 16) + 1) & ~1) - left;
++	left = rot_x1 >> 16;
++	npixels = ((rot_x2 + 0xffff) >> 16) - left;
++	nlines  = ((rot_y2 + 0xffff) >> 16) - top;
 +
-+	/* Since we're probably overwriting the area that might still be used
-+	 * for the last PutImage request, wait for idle.
++	/* 
++	 * We kaaWaitSync below.  This guarantees only one buffer
++	 * is locked by ISP.  Thus, if ISP is busy, the buffer
++	 * knext is free.
++	 *
++	 * This is a simple scheme.  Only dual buffer benefits.
 +	 */
-+	GLAMOWaitIdle(glamos);
++	if (GLAMOEngineBusy(pScreen, GLAMO_ENGINE_ISP))
++		pPortPriv->idx = (pPortPriv->idx + 1) % GLAMO_VIDEO_NUM_BUFS;
 +
-+	switch(id) {
-+	case FOURCC_YV12:
-+	case FOURCC_I420:
-+		top &= ~1;
-+		nlines = ((((rot_y2 + 0xffff) >> 16) + 1) & ~1) - top;
-+		/* pack the source as YUY2 to vram */
-+		KdXVCopyPlanarData(screen, buf, pPortPriv->src_addr, randr,
-+		    srcPitch, srcPitch2, dstPitch, rot_src_w, rot_src_h,
-+		    height, top, left, nlines, npixels, id);
-+		break;
-+	case FOURCC_UYVY:
-+	case FOURCC_YUY2:
-+	default:
-+		nlines = ((rot_y2 + 0xffff) >> 16) - top;
-+		KdXVCopyPackedData(screen, buf, pPortPriv->src_addr, randr,
-+		    srcPitch, dstPitch, rot_src_w, rot_src_h, top, left,
-+		    nlines, npixels);
-+		break;
-+	}
++	if (GLAMOUploadImage(screen, pDraw, pPortPriv,
++			     left, top, npixels, nlines,
++			     id, randr, buf, width, height))
++		return BadAlloc;
 +
 +	/* update cliplist */
 +	if (!REGION_EQUAL(screen->pScreen, &pPortPriv->clip, clipBoxes)) {
@@ -3428,14 +3727,15 @@
 +	pPortPriv->dst_w = rot_drw_w;
 +	pPortPriv->dst_h = rot_drw_h;
 +
++	kaaWaitSync(pScreen);
 +	GlamoDisplayVideo(screen, pPortPriv);
 +
 +	return Success;
 +}
 +
 +static int
-+GLAMOReputImage(KdScreenInfo *screen, DrawablePtr pDraw, short drw_x, short drw_y,
-+    RegionPtr clipBoxes, pointer data)
++GLAMOReputImage(KdScreenInfo *screen, DrawablePtr pDraw,
++		short drw_x, short drw_y, RegionPtr clipBoxes, pointer data)
 +{
 +	ScreenPtr pScreen = screen->pScreen;
 +	GLAMOPortPrivPtr	pPortPriv = (GLAMOPortPrivPtr)data;
@@ -3469,6 +3769,7 @@
 +
 +	/* XXX: What do the drw_x and drw_y here mean for us? */
 +
++	kaaWaitSync(pScreen);
 +	GlamoDisplayVideo(screen, pPortPriv);
 +
 +	return Success;
@@ -3494,20 +3795,23 @@
 +	case FOURCC_YV12:
 +	case FOURCC_I420:
 +		*h = (*h + 1) & ~1;
-+		size = (*w + 3) & ~3;
++
++		tmp = SYS_PITCH_ALIGN(*w);
++		size = tmp * *h;
++
 +		if (pitches)
-+			pitches[0] = size;
-+		size *= *h;
++			pitches[0] = tmp;
 +		if (offsets)
 +			offsets[1] = size;
-+		tmp = ((*w >> 1) + 3) & ~3;
++
++		tmp = SYS_PITCH_ALIGN(*w / 2);
++		size += tmp * *h / 2;
 +		if (pitches)
 +			pitches[1] = pitches[2] = tmp;
-+		tmp *= (*h >> 1);
-+		size += tmp;
 +		if (offsets)
 +			offsets[2] = size;
-+		size += tmp;
++
++		size += tmp * *h / 2;
 +		break;
 +	case FOURCC_UYVY:
 +	case FOURCC_YUY2:
@@ -3547,6 +3851,7 @@
 +{
 +};
 +
++#ifdef PACKED_IMAGE
 +#define NUM_IMAGES 4
 +
 +static KdImageRec Images[NUM_IMAGES] =
@@ -3556,7 +3861,16 @@
 +	XVIMAGE_I420,
 +	XVIMAGE_UYVY
 +};
++#else
++#define NUM_IMAGES 2
 +
++static KdImageRec Images[NUM_IMAGES] =
++{
++	XVIMAGE_YV12,
++	XVIMAGE_I420,
++};
++#endif /* PACKED_IMAGE */
++
 +static KdVideoAdaptorPtr
 +GLAMOSetupImageVideo(ScreenPtr pScreen)
 +{
@@ -3566,10 +3880,11 @@
 +	GLAMOPortPrivPtr pPortPriv;
 +	int i;
 +
-+	glamos->num_texture_ports = 16;
++	glamos->num_texture_ports = 1;
 +
-+	adapt = xcalloc(1, sizeof(KdVideoAdaptorRec) + glamos->num_texture_ports *
-+	    (sizeof(GLAMOPortPrivRec) + sizeof(DevUnion)));
++	adapt = xcalloc(1, sizeof(KdVideoAdaptorRec) +
++			   glamos->num_texture_ports *
++			   (sizeof(GLAMOPortPrivRec) + sizeof(DevUnion)));
 +	if (adapt == NULL)
 +		return NULL;
 +
@@ -3583,8 +3898,8 @@
 +	adapt->nPorts = glamos->num_texture_ports;
 +	adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
 +
-+	pPortPriv =
-+	    (GLAMOPortPrivPtr)(&adapt->pPortPrivates[glamos->num_texture_ports]);
++	pPortPriv = (GLAMOPortPrivPtr)
++		(&adapt->pPortPrivates[glamos->num_texture_ports]);
 +
 +	for (i = 0; i < glamos->num_texture_ports; i++)
 +		adapt->pPortPrivates[i].ptr = &pPortPriv[i];
@@ -3605,8 +3920,8 @@
 +	adapt->ReputImage = GLAMOReputImage;
 +	adapt->QueryImageAttributes = GLAMOQueryImageAttributes;
 +
-+	/* gotta uninit this someplace */
-+	REGION_INIT(pScreen, &pPortPriv->clip, NullBox, 0);
++	for (i = 0; i < glamos->num_texture_ports; i++)
++		REGION_INIT(pScreen, &pPortPriv[i].clip, NullBox, 0);
 +
 +	glamos->pAdaptor = adapt;
 +
@@ -3616,22 +3931,6 @@
 +	return adapt;
 +}
 +
-+static void GLAMOPowerUp(ScreenPtr pScreen)
-+{
-+	GLAMOEngineEnable(pScreen, GLAMO_ENGINE_ISP);
-+	GLAMOEngineReset(pScreen, GLAMO_ENGINE_ISP);
-+
-+	/* HW_DEBUG_0?? */
-+	//MMIOSetBitMask(mmio, REG_ISP(0x102), 0x0020, 0);
-+}
-+
-+static void GLAMOPowerDown(ScreenPtr pScreen)
-+{
-+	GLAMOEngineReset(pScreen, GLAMO_ENGINE_ISP);
-+
-+	/* ... and stop the clock */
-+}
-+
 +Bool GLAMOInitVideo(ScreenPtr pScreen)
 +{
 +	KdScreenPriv(pScreen);
@@ -3652,8 +3951,6 @@
 +	newAdaptor = GLAMOSetupImageVideo(pScreen);
 +
 +	if (newAdaptor)  {
-+		GLAMOPowerUp(pScreen);
-+
 +		if (!num_adaptors) {
 +			num_adaptors = 1;
 +			adaptors = &newAdaptor;
@@ -3691,12 +3988,146 @@
 +	if (!adapt)
 +		return;
 +
-+	GLAMOPowerDown(pScreen);
-+
 +	for (i = 0; i < glamos->num_texture_ports; i++) {
-+		pPortPriv = (GLAMOPortPrivPtr)(&adapt->pPortPrivates[i].ptr);
++		pPortPriv = (GLAMOPortPrivPtr)(adapt->pPortPrivates[i].ptr);
 +		REGION_UNINIT(pScreen, &pPortPriv->clip);
 +	}
 +	xfree(adapt);
 +	glamos->pAdaptor = NULL;
 +}
++
++static void GLAMOSetOnFlyRegs(ScreenPtr pScreen)
++{
++	KdScreenPriv(pScreen);
++	GLAMOScreenInfo(pScreenPriv);
++	struct {
++		int src_block_x;
++		int src_block_y;
++		int src_block_w;
++		int src_block_h;
++		int jpeg_out_y;
++		int jpeg_out_x;
++		int fifo_full_cnt;
++		int in_length;
++		int fifo_data_cnt;
++		int in_height;
++	} onfly;
++	RING_LOCALS;
++
++	onfly.src_block_y = 32;
++	onfly.src_block_x = 32;
++	onfly.src_block_w = 36;
++	onfly.src_block_h = 35;
++	onfly.jpeg_out_y = 32;
++	onfly.jpeg_out_x = 32;
++	onfly.fifo_full_cnt = onfly.src_block_w * 2 + 2;
++	onfly.in_length = onfly.jpeg_out_x + 3;
++	onfly.fifo_data_cnt = onfly.src_block_w * onfly.src_block_h / 2;
++	onfly.in_height = onfly.jpeg_out_y + 2;
++
++	BEGIN_DMA(10);
++	OUT_REG(GLAMO_REG_ISP_ONFLY_MODE1,
++		onfly.src_block_y << 10 | onfly.src_block_x << 2);
++	OUT_REG(GLAMO_REG_ISP_ONFLY_MODE2,
++		onfly.src_block_h << 8 | onfly.src_block_w);
++	OUT_REG(GLAMO_REG_ISP_ONFLY_MODE3,
++		onfly.jpeg_out_y << 8 | onfly.jpeg_out_x);
++	OUT_REG(GLAMO_REG_ISP_ONFLY_MODE4,
++		onfly.fifo_full_cnt << 8 | onfly.in_length);
++	OUT_REG(GLAMO_REG_ISP_ONFLY_MODE5,
++		onfly.fifo_data_cnt << 6 | onfly.in_height);
++	END_DMA();
++}
++
++static void GLAMOSetWeightRegs(ScreenPtr pScreen)
++{
++	KdScreenPriv(pScreen);
++	GLAMOScreenInfo(pScreenPriv);
++	int left = 1 << 14;
++	RING_LOCALS;
++
++	/* nearest */
++
++	BEGIN_DMA(12);
++	OUT_BURST(GLAMO_REG_ISP_DEC_SCALEH_MATRIX, 10);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX +  0, left);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX +  2, 0);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX +  4, left);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX +  6, 0);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX +  8, left);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX + 10, 0);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX + 12, left);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX + 14, 0);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX + 16, left);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEH_MATRIX + 18, 0);
++	END_DMA();
++
++	BEGIN_DMA(12);
++	OUT_BURST(GLAMO_REG_ISP_DEC_SCALEV_MATRIX, 10);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX +  0, left);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX +  2, 0);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX +  4, left);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX +  6, 0);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX +  8, left);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX + 10, 0);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX + 12, left);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX + 14, 0);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX + 16, left);
++	OUT_BURST_REG(GLAMO_REG_ISP_DEC_SCALEV_MATRIX + 18, 0);
++	END_DMA();
++}
++
++static void GLAMOInitISP(ScreenPtr pScreen)
++{
++	KdScreenPriv(pScreen);
++	GLAMOScreenInfo(pScreenPriv);
++	RING_LOCALS;
++
++	BEGIN_DMA(16);
++
++	/*
++	 * In 8.8 fixed point,
++	 *
++	 *  R = Y + 1.402 (Cr-128)
++	 *    = Y + 0x0167 Cr - 0xb3
++	 *
++	 *  G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128)
++	 *    = Y - 0x0058 Cb - 0x00b6 Cr + 0x89
++	 *
++	 *  B = Y + 1.772 (Cb-128)
++	 *    = Y + 0x01c5 Cb - 0xe2
++	 */
++
++	OUT_REG(GLAMO_REG_ISP_YUV2RGB_11, 0x0167);
++	OUT_REG(GLAMO_REG_ISP_YUV2RGB_21, 0x01c5);
++	OUT_REG(GLAMO_REG_ISP_YUV2RGB_32, 0x00b6);
++	OUT_REG(GLAMO_REG_ISP_YUV2RGB_33, 0x0058);
++	OUT_REG(GLAMO_REG_ISP_YUV2RGB_RG, 0xb3 << 8 | 0x89);
++	OUT_REG(GLAMO_REG_ISP_YUV2RGB_B, 0xe2);
++
++	OUT_REG(GLAMO_REG_ISP_PORT1_DEC_EN, GLAMO_ISP_PORT1_EN_OUTPUT);
++	OUT_REG(GLAMO_REG_ISP_PORT2_EN, GLAMO_ISP_PORT2_EN_DECODE);
++
++	END_DMA();
++
++	GLAMOSetOnFlyRegs(pScreen);
++	GLAMOSetWeightRegs(pScreen);
++}
++
++Bool
++GLAMOVideoSetup(ScreenPtr pScreen)
++{
++	GLAMOEngineEnable(pScreen, GLAMO_ENGINE_ISP);
++	GLAMOEngineReset(pScreen, GLAMO_ENGINE_ISP);
++
++	GLAMOInitISP(pScreen);
++
++	return TRUE;
++}
++
++void
++GLAMOVideoTeardown(ScreenPtr pScreen)
++{
++	GLAMOEngineReset(pScreen, GLAMO_ENGINE_ISP);
++	GLAMOEngineDisable(pScreen, GLAMO_ENGINE_ISP);
++}





More information about the commitlog mailing list