diff -u --ignore-matching-lines=GETRESERVED /X11R6/SourceForge/IPcop/ipcop/build/usr/src/linux-2.4.24/drivers/char/agp/agpgart_be.c ./agpgart_be.c
--- /X11R6/SourceForge/IPcop/ipcop/build/usr/src/linux-2.4.24/drivers/char/agp/agpgart_be.c	2003-11-28 18:26:20.000000000 +0000
+++ ./agpgart_be.c	2004-01-23 11:01:58.000000000 +0000
@@ -799,6 +894,28 @@
 	return (unsigned long)page_address(page);
 }
 
+/* Exists to support ARGB cursors */
+static unsigned long i830_alloc_pages(void)
+{
+	struct page * page;
+	
+	page = alloc_pages(GFP_KERNEL, 2);
+	if (page == NULL) {
+		return 0;
+	}
+
+#ifdef CONFIG_X86
+	if (change_page_attr(page, 4, PAGE_KERNEL_NOCACHE) < 0) {
+		__free_page(page); 
+		return 0;
+	}
+#endif
+	get_page(page);
+	LockPage(page);
+	atomic_inc(&agp_bridge.current_memory_agp);
+	return (unsigned long)page_address(page);
+}
+
 static void agp_generic_destroy_page(unsigned long addr)
 {
 	void *pt = (void *) addr;
@@ -818,6 +935,25 @@
 	atomic_dec(&agp_bridge.current_memory_agp);
 }
 
+static void i830_destroy_pages(unsigned long addr)
+{
+	void *pt = (void *) addr;
+	struct page *page;
+
+	if (pt == NULL) {
+		return;
+	}
+	
+	page = virt_to_page(pt);
+#ifdef CONFIG_X86
+	change_page_attr(page, 4, PAGE_KERNEL); 
+#endif	
+	put_page(page);
+	UnlockPage(page);
+	free_pages((unsigned long) pt, 2);
+	atomic_dec(&agp_bridge.current_memory_agp);
+}
+
 /* End Basic Page Allocation Routines */
 
 void agp_enable(u32 mode)
@@ -1058,7 +1194,11 @@
 {
 	agp_free_key(curr->key);
    	if(curr->type == AGP_PHYS_MEMORY) {
-	   	agp_bridge.agp_destroy_page((unsigned long)
+		if (curr->page_count == 4)
+			i830_destroy_pages((unsigned long)
+				 phys_to_virt(curr->memory[0]));
+		else
+	   		agp_bridge.agp_destroy_page((unsigned long)
 				 phys_to_virt(curr->memory[0]));
 		vfree(curr->memory);
 	}
@@ -1108,15 +1251,25 @@
 {
 	{128, 32768, 5},
 	/* The 64M mode still requires a 128k gatt */
-	{64, 16384, 5}
+	{64, 16384, 5},
+	/* For GDG/ALV */
+	{256, 65536, 6}
 };
 
 static struct _intel_i830_private {
 	struct pci_dev *i830_dev;   /* device one */
 	volatile u8 *registers;
+	volatile u32 *gtt;	/* GDG/ALV */
 	int gtt_entries;
+/* REWRITE { */
+#ifdef REWRITE_PREALLOCATED
+	agp_memory *reserved_memory;
+#endif
+/* REWRITE } */
 } intel_i830_private;
 
+static int intel_i830_fetch_size(void);
+
 static void intel_i830_init_gtt_entries(void)
 {
 	u16 gmch_ctrl;
@@ -1124,42 +1277,67 @@
 	u8 rdct;
 	int local = 0;
 	static const int ddt[4] = { 0, 16, 32, 64 };
+        int size;
+ 
 
 	pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
 
+	/* We obtain the size of the GTT, which is also stored (for some
+	 * reason) at the top of stolen memory. Then we add 4KB to that
+  	 * for the video BIOS popup, which is also stored in there. */
+	size = intel_i830_fetch_size() + 4;
+
+/* MGM { */
 	if (agp_bridge.dev->device != PCI_DEVICE_ID_INTEL_830_M_0 &&
 	    agp_bridge.dev->device != PCI_DEVICE_ID_INTEL_845_G_0) {
 		switch (gmch_ctrl & I855_GMCH_GMS_MASK) {
 		case I855_GMCH_GMS_STOLEN_1M:
-			gtt_entries = MB(1) - KB(132);
+			gtt_entries = MB(1) - KB(size);
 			break;
 		case I855_GMCH_GMS_STOLEN_4M:
-			gtt_entries = MB(4) - KB(132);
+			gtt_entries = MB(4) - KB(size);
 			break;
 		case I855_GMCH_GMS_STOLEN_8M:
-			gtt_entries = MB(8) - KB(132);
+			gtt_entries = MB(8) - KB(size);
 			break;
 		case I855_GMCH_GMS_STOLEN_16M:
-			gtt_entries = MB(16) - KB(132);
+			gtt_entries = MB(16) - KB(size);
 			break;
 		case I855_GMCH_GMS_STOLEN_32M:
-			gtt_entries = MB(32) - KB(132);
+			gtt_entries = MB(32) - KB(size);
+			break;
+		case GDG_GMCH_GMS_STOLEN_48M:
+			/* Check it's really GDG */
+			if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_GDG_0 ||
+			    agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_ALV_0)
+				gtt_entries = MB(48) - KB(size);
+			else
+				gtt_entries = 0;
+			break;
+		case GDG_GMCH_GMS_STOLEN_64M:
+			/* Check it's really GDG */
+			if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_GDG_0 ||
+			    agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_ALV_0)
+				gtt_entries = MB(64) - KB(size);
+			else
+				gtt_entries = 0;
 			break;
 		default:
 			gtt_entries = 0;
 			break;
 		}
 	} else
+/* MGM } */
 	{
 		switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
 		case I830_GMCH_GMS_STOLEN_512:
-			gtt_entries = KB(512) - KB(132);
+			gtt_entries = KB(512) - KB(size);
 			break;
 		case I830_GMCH_GMS_STOLEN_1024:
-			gtt_entries = MB(1) - KB(132);
+			gtt_entries = MB(1) - KB(size);
 			break;
 		case I830_GMCH_GMS_STOLEN_8192:
-			gtt_entries = MB(8) - KB(132);
+			gtt_entries = MB(8) - KB(size);
 			break;
 		case I830_GMCH_GMS_LOCAL:
 			rdct = INREG8(intel_i830_private.registers,
@@ -1193,14 +1371,32 @@
 	int page_order;
 	aper_size_info_fixed *size;
 	int num_entries;
-	u32 temp;
+	u32 temp, temp2;
+/* REWRITE { */
+#ifdef REWRITE_PREALLOCATED
+	agp_memory *new;
+	int scratch_pages, i;
+	u32 first_page;
+#endif
+/* REWRITE } */
 
 	size = agp_bridge.current_size;
 	page_order = size->page_order;
 	num_entries = size->num_entries;
 	agp_bridge.gatt_table_real = 0;
 
-	pci_read_config_dword(intel_i830_private.i830_dev,I810_MMADDR,&temp);
+	if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_GDG_0 ||
+	    agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_ALV_0) {
+		pci_read_config_dword(intel_i830_private.i830_dev,
+							GDG_MMADDR,&temp);
+		pci_read_config_dword(intel_i830_private.i830_dev,
+							GDG_PTEADDR,&temp2);
+		intel_i830_private.gtt = (volatile u32 *) ioremap(temp2, 256 * 1024);
+		if (!intel_i830_private.gtt) return (-ENOMEM);
+	} else
+		pci_read_config_dword(intel_i830_private.i830_dev,	
+							I810_MMADDR,&temp);
+
 	temp &= 0xfff80000;
 
 	intel_i830_private.registers = (volatile u8 *) ioremap(temp,128 * 4096);
@@ -1234,6 +1468,24 @@
 
 	values = A_SIZE_FIX(agp_bridge.aperture_sizes);
 
+/* GDG { */
+	if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_GDG_0 ||
+	    agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_ALV_0) {
+		u32 temp, offset = 0;
+		pci_read_config_dword(intel_i830_private.i830_dev,
+							GDG_GMADDR,&temp);
+#define GDG_256MB_ADDRESS_MASK (1<<27)
+		if (temp & GDG_256MB_ADDRESS_MASK)
+			offset = 0;	/* 128MB aperture */
+		else
+			offset = 2;	/* 256MB aperture */
+		agp_bridge.previous_size = agp_bridge.current_size = (void *)(values + offset);
+		agp_bridge.aperture_size_idx = offset;
+		return(values[offset].size);
+	}
+/* GDG } */
+
+/* MGM { */
 	if (agp_bridge.dev->device != PCI_DEVICE_ID_INTEL_830_M_0 &&
 	    agp_bridge.dev->device != PCI_DEVICE_ID_INTEL_845_G_0) {
 		agp_bridge.previous_size = agp_bridge.current_size = (void *) values;
@@ -1241,13 +1493,14 @@
 		return(values[0].size);
 	}
 		
+/* MGM } */
 	pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
 	if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
 		agp_bridge.previous_size = agp_bridge.current_size = (void *) values;
 		agp_bridge.aperture_size_idx = 0;
 		return(values[0].size);
 	} else {
-		agp_bridge.previous_size = agp_bridge.current_size = (void *) values;
+		agp_bridge.previous_size = agp_bridge.current_size = (void *)(values + 1);
 		agp_bridge.aperture_size_idx = 1;
 		return(values[1].size);
 	}
@@ -1264,7 +1517,14 @@
 
 	current_size = A_SIZE_FIX(agp_bridge.current_size);
 
-	pci_read_config_dword(intel_i830_private.i830_dev,I810_GMADDR,&temp);
+	if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_GDG_0 ||
+	    agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_ALV_0)
+		pci_read_config_dword(intel_i830_private.i830_dev,
+							GDG_GMADDR,&temp);
+	else
+		pci_read_config_dword(intel_i830_private.i830_dev,
+							I810_GMADDR,&temp);
+
 	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
 	pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
@@ -1274,15 +1534,26 @@
 	OUTREG32(intel_i830_private.registers,I810_PGETBL_CTL,agp_bridge.gatt_bus_addr | I810_PGETBL_ENABLED);
 	CACHE_FLUSH();
 
-	if (agp_bridge.needs_scratch_page == TRUE)
-		for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++)
-			OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge.scratch_page);
+	if (agp_bridge.needs_scratch_page == TRUE) {
+		if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_GDG_0 ||
+		    agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_ALV_0) {
+			for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++)
+				OUTREG32(intel_i830_private.gtt, i, agp_bridge.scratch_page);
+		} else {
+			for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++)
+				OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge.scratch_page);
+		}
+	}
 
 	return (0);
 }
 
 static void intel_i830_cleanup(void)
 {
+	if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_GDG_0 ||
+	    agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_ALV_0)
+		iounmap((void *)intel_i830_private.gtt);
+
 	iounmap((void *) intel_i830_private.registers);
 }
 
@@ -1315,9 +1603,14 @@
 
 	CACHE_FLUSH();
 
-	for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
-		OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (j * 4),
-			 agp_bridge.mask_memory(mem->memory[i], mem->type));
+	if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_GDG_0 ||
+	    agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_ALV_0) {
+		for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
+			OUTREG32(intel_i830_private.gtt, j, agp_bridge.mask_memory(mem->memory[i], mem->type));
+	} else {
+		for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
+			OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (j * 4),agp_bridge.mask_memory(mem->memory[i], mem->type));
+	}
 
 	CACHE_FLUSH();
 
@@ -1337,8 +1630,14 @@
 		return (-EINVAL);
 	}
 
-	for (i = pg_start; i < (mem->page_count + pg_start); i++)
-		OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge.scratch_page);
+	if (agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_GDG_0 ||
+	    agp_bridge.dev->device == PCI_DEVICE_ID_INTEL_ALV_0) {
+		for (i = pg_start; i < (mem->page_count + pg_start); i++)
+			OUTREG32(intel_i830_private.gtt, i, agp_bridge.scratch_page);
+	} else {
+		for (i = pg_start; i < (mem->page_count + pg_start); i++)
+			OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge.scratch_page);
+	}
 
 	CACHE_FLUSH();
 
@@ -1363,24 +1662,40 @@
 		 * aperture
 		 */
 
-		if (pg_count != 1) return(NULL);
+		if (pg_count != 1 && pg_count != 4) return(NULL);
 
-		nw = agp_create_memory(1);
+		nw = agp_create_memory(pg_count);
 
 		if (nw == NULL) return(NULL);
 
 		MOD_INC_USE_COUNT;
-		nw->memory[0] = agp_bridge.agp_alloc_page();
-		physical = nw->memory[0];
+		if (pg_count == 1)
+			nw->memory[0] = agp_bridge.agp_alloc_page();
+		else {
+			/* kludge to get 4 physical pages for ARGB cursor */
+			nw->memory[0] = i830_alloc_pages();
+			nw->memory[1] = nw->memory[0] + PAGE_SIZE;
+			nw->memory[2] = nw->memory[1] + PAGE_SIZE;
+			nw->memory[3] = nw->memory[2] + PAGE_SIZE;
+		}
+
 		if (nw->memory[0] == 0) {
 			/* free this structure */
 			agp_free_memory(nw);
 			return(NULL);
 		}
 
+		physical = nw->memory[0];
+
 		nw->memory[0] = virt_to_phys((void *) nw->memory[0]);
-		nw->page_count = 1;
-		nw->num_scratch_pages = 1;
+		if (pg_count == 4) {
+			/* kludge to enable 4 physical pages for ARGB cursor */
+			nw->memory[1] = virt_to_phys((void *) nw->memory[1]);
+			nw->memory[2] = virt_to_phys((void *) nw->memory[2]);
+			nw->memory[3] = virt_to_phys((void *) nw->memory[3]);
+		}
+		nw->page_count = pg_count;
+		nw->num_scratch_pages = pg_count;
 		nw->type = AGP_PHYS_MEMORY;
 		nw->physical = virt_to_phys((void *) physical);
 		return(nw);
@@ -6104,6 +6462,23 @@
 		"865G",
 		 intel_845_setup },
 
+/* SPDG } */
+/* GDG { */
+	{ PCI_DEVICE_ID_INTEL_GDG_0,
+		PCI_VENDOR_ID_INTEL,
+		INTEL_GDG,
+		"Intel(R)",
+		"Grantsdale-G",
+		 intel_845_setup },
+/* GDG } */
+/* ALV { */
+	{ PCI_DEVICE_ID_INTEL_ALV_0,
+		PCI_VENDOR_ID_INTEL,
+		INTEL_ALV,
+		"Intel(R)",
+		"Grantsdale-G",
+		 intel_845_setup },
+/* ALV } */
 	{ PCI_DEVICE_ID_INTEL_840_0,
 		PCI_VENDOR_ID_INTEL,
 		INTEL_I840,
@@ -6821,6 +7196,62 @@
 				   "865G Chipset.\n");
 			agp_bridge.type = INTEL_I810;
 			return intel_i830_setup(i810_dev);
+/* GDG { */
+		case PCI_DEVICE_ID_INTEL_GDG_0:
+			i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+					PCI_DEVICE_ID_INTEL_GDG_1, NULL);
+			if(i810_dev && PCI_FUNC(i810_dev->devfn) != 0) {
+				i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+					PCI_DEVICE_ID_INTEL_GDG_1, i810_dev);
+			}
+
+			if (i810_dev == NULL) {
+                                /* 
+                                 * We probably have a GDG chipset
+                                 * with an external graphics
+                                 * card. It will be initialized later 
+                                 */
+				printk(KERN_ERR PFX "Detected an "
+				       "Intel(R) GDG, but could not"
+				       " find the"
+				       " secondary device. Assuming a "
+				       "non-integrated video card.\n");
+				agp_bridge.type = INTEL_GDG;
+				break;
+			}
+			printk(KERN_INFO PFX "Detected an Intel(R) "
+				   "GDG Chipset.\n");
+			agp_bridge.type = INTEL_I810;
+			return intel_i830_setup(i810_dev);
+/* GDG } */
+/* ALV { */
+		case PCI_DEVICE_ID_INTEL_ALV_0:
+			i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+					PCI_DEVICE_ID_INTEL_ALV_1, NULL);
+			if(i810_dev && PCI_FUNC(i810_dev->devfn) != 0) {
+				i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+					PCI_DEVICE_ID_INTEL_ALV_1, i810_dev);
+			}
+
+			if (i810_dev == NULL) {
+                                /* 
+                                 * We probably have a ALV chipset
+                                 * with an external graphics
+                                 * card. It will be initialized later 
+                                 */
+				printk(KERN_ERR PFX "Detected an "
+				       "Intel(R) ALV, but could not"
+				       " find the"
+				       " secondary device. Assuming a "
+				       "non-integrated video card.\n");
+				agp_bridge.type = INTEL_ALV;
+				break;
+			}
+			printk(KERN_INFO PFX "Detected an Intel(R) "
+				   "ALV Chipset.\n");
+			agp_bridge.type = INTEL_I810;
+			return intel_i830_setup(i810_dev);
+/* ALV } */
 		default:
 			break;
 		}
diff -u --ignore-matching-lines=GETRESERVED /X11R6/SourceForge/IPcop/ipcop/build/usr/src/linux-2.4.24/drivers/char/agp/agp.h ./agp.h
--- /X11R6/SourceForge/IPcop/ipcop/build/usr/src/linux-2.4.24/drivers/char/agp/agp.h	2003-11-28 18:26:20.000000000 +0000
+++ ./agp.h	2004-01-23 10:42:31.000000000 +0000
@@ -178,6 +189,9 @@
 #ifndef PCI_DEVICE_ID_VIA_8385_0
 #define PCI_DEVICE_ID_VIA_8385_0	0x3188
 #endif 
+#ifndef PCI_DEVICE_ID_VIA_CLE266
+#define PCI_DEVICE_ID_VIA_CLE266	0x3123
+#endif 
 #ifndef PCI_DEVICE_ID_INTEL_810_0
 #define PCI_DEVICE_ID_INTEL_810_0       0x7120
 #endif
@@ -211,6 +225,18 @@
 #ifndef PCI_DEVICE_ID_INTEL_865_G_1
 #define PCI_DEVICE_ID_INTEL_865_G_1	0x2572
 #endif
+#ifndef PCI_DEVICE_ID_INTEL_GDG_0
+#define PCI_DEVICE_ID_INTEL_GDG_0	0x2580
+#endif
+#ifndef PCI_DEVICE_ID_INTEL_GDG_1
+#define PCI_DEVICE_ID_INTEL_GDG_1	0x2582
+#endif
+#ifndef PCI_DEVICE_ID_INTEL_ALV_0
+#define PCI_DEVICE_ID_INTEL_ALV_0	0x2590
+#endif
+#ifndef PCI_DEVICE_ID_INTEL_ALV_1
+#define PCI_DEVICE_ID_INTEL_ALV_1	0x2592
+#endif
 #ifndef PCI_DEVICE_ID_INTEL_820_0
 #define PCI_DEVICE_ID_INTEL_820_0       0x2500
 #endif
@@ -386,7 +412,7 @@
 #define I830_RDRAM_ND(x)           (((x) & 0x20) >> 5)
 #define I830_RDRAM_DDT(x)          (((x) & 0x18) >> 3)
 
-/* This one is for I830MP w. an external graphic card */
+/* This one is for I830MP with an external graphics card */
 #define INTEL_I830_ERRSTS          0x92
 
 /* intel 815 register */
@@ -401,7 +427,7 @@
 #define INTEL_I840_MCHCFG   0x50
 #define INTEL_I840_ERRSTS   0xc8
  
-/* intel i845 registers */
+/* intel i845/i845G registers */
 #define INTEL_I845_AGPM     0x51
 #define INTEL_I845_ERRSTS   0xc8
 
@@ -435,6 +461,12 @@
 #define I810_DRAM_ROW_0        0x00000001
 #define I810_DRAM_ROW_0_SDRAM  0x00000001
 
+/* intel GDG registers */
+#define GDG_GMADDR 0x18
+#define GDG_MMADDR 0x10
+#define GDG_PTEADDR 0x1C
+#define GDG_GMCH_GMS_STOLEN_48M    (0x6 << 4)
+#define GDG_GMCH_GMS_STOLEN_64M    (0x7 << 4)
 
 
 /* VIA register */
