All of lore.kernel.org
 help / color / mirror / Atom feed
* 2.4.21-RC2 nforce2 agp patch
@ 2003-05-24 16:55 Gutko
  0 siblings, 0 replies; only message in thread
From: Gutko @ 2003-05-24 16:55 UTC (permalink / raw)
  To: Linux Kernel

[-- Attachment #1: Type: text/plain, Size: 325 bytes --]

Hello,
This is patch against 2.4.21-rc2 adding Nvidia Nforce1/Nforce2 AGP 
chipset support.It worked very good on  2.4.21-rc2-ac3. I found this 
patch here : http://etudiant.epita.fr:8000/~nonolk/nforce-agp.diff

Don't know who ported it from 2.5.69, however I know this address above 
belongs to author of this patch

Gutko

[-- Attachment #2: nforce-agp.diff --]
[-- Type: text/plain, Size: 12745 bytes --]

diff --unified --recursive --new-file linux/drivers/char/Config.in linux-2.4.20-nforce/drivers/char/Config.in
--- linux/drivers/char/Config.in	2003-05-09 21:05:38.000000000 +0200
+++ linux-2.4.20-nforce/drivers/char/Config.in	2003-05-09 20:55:34.000000000 +0200
@@ -306,6 +306,7 @@
    bool '  Generic SiS support' CONFIG_AGP_SIS
    bool '  ALI chipset support' CONFIG_AGP_ALI
    bool '  Serverworks LE/HE support' CONFIG_AGP_SWORKS
+   bool '  Nvidia Nforce/Nforce2 support' CONFIG_AGP_NV
    if [ "$CONFIG_IA64" = "y" ]; then
       bool '  HP ZX1 AGP support' CONFIG_AGP_HP_ZX1
    fi
diff --unified --recursive --new-file linux/drivers/char/agp/agp.h linux-2.4.20-nforce/drivers/char/agp/agp.h
--- linux/drivers/char/agp/agp.h	2003-05-09 21:05:38.000000000 +0200
+++ linux-2.4.20-nforce/drivers/char/agp/agp.h	2003-05-09 20:59:06.000000000 +0200
@@ -271,6 +271,12 @@
 #ifndef PCI_DEVICE_ID_AL_M1671_0
 #define PCI_DEVICE_ID_AL_M1671_0	0x1671
 #endif
+#ifndef PCI_DEVICE_ID_NV_NFORCE_0
+#define PCI_DEVICE_ID_NV_NFORCE_0	0x01a4
+#endif
+#ifndef PCI_DEVICE_ID_NV_NFORCE2_0
+#define PCI_DEVICE_ID_NV_NFORCE2_0	0x01e0
+#endif
 
 /* intel register */
 #define INTEL_APBASE    0x10
@@ -412,6 +418,17 @@
 #define SVWRKS_POSTFLUSH  0x14
 #define SVWRKS_DIRFLUSH   0x0c
 
+/* NVidia registers */
+#define NVIDIA_0_APBASE		0x10
+#define NVIDIA_0_APSIZE		0x80
+#define NVIDIA_1_WBC		0xf0
+#define NVIDIA_2_GARTCTRL	0xd0
+#define NVIDIA_2_APBASE		0xd8
+#define NVIDIA_2_APLIMIT	0xdc
+#define NVIDIA_2_ATTBASE(i)	(0xe0 + (i) * 4)
+#define NVIDIA_3_APBASE		0x50
+#define NVIDIA_3_APLIMIT	0x54
+
 /* HP ZX1 SBA registers */
 #define HP_ZX1_CTRL		0x200
 #define HP_ZX1_IBASE		0x300
diff --unified --recursive --new-file linux/drivers/char/agp/agpgart_be.c linux-2.4.20-nforce/drivers/char/agp/agpgart_be.c
--- linux/drivers/char/agp/agpgart_be.c	2003-05-09 21:05:38.000000000 +0200
+++ linux-2.4.20-nforce/drivers/char/agp/agpgart_be.c	2003-05-09 20:58:39.000000000 +0200
@@ -3418,7 +3418,7 @@
 } serverworks_private;
 
 static int serverworks_create_page_map(serverworks_page_map *page_map)
-{
+{	
 	int i;
 	int err = 0;
 
@@ -4003,6 +4003,309 @@
 
 #endif /* CONFIG_AGP_SWORKS */
 
+#ifdef CONFIG_AGP_NV
+
+static aper_size_info_8 nvidia_generic_sizes[5] =
+{
+	{512, 131072, 7, 0},
+	{256, 65536, 6, 8},
+	{128, 32768, 5, 12},
+	{64, 16384, 4, 14},
+	/* The 32M mode still requires a 64k gatt */
+	{32, 16384, 4, 15}
+};
+
+static gatt_mask nvidia_generic_masks[] =
+{
+	{0x00000001, 0}
+};
+
+static struct _nvidia_private {
+	struct pci_dev *dev_1;
+	struct pci_dev *dev_2;
+	struct pci_dev *dev_3;
+	volatile u32 *aperture;
+	int num_active_entries;
+	off_t pg_offset;
+	u32 wbc_mask;
+} nvidia_private;
+
+static int nvidia_fetch_size(void)
+{
+	int i;
+	u8 size_value;
+	aper_size_info_8 *values;
+
+	pci_read_config_byte(agp_bridge.dev, NVIDIA_0_APSIZE, &size_value);
+	size_value &= 0x0f;
+	values = A_SIZE_8(agp_bridge.aperture_sizes);
+
+	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+		if (size_value == values[i].size_value) {
+			agp_bridge.previous_size =
+				agp_bridge.current_size = (void *) (values + i);
+			agp_bridge.aperture_size_idx = i;
+			return values[i].size;
+		}
+	}
+
+	return 0;
+}
+
+static int nvidia_configure(void)
+{
+	int i, num_dirs;
+	u32 apbase, aplimit;
+	aper_size_info_8 *current_size;
+	u32 temp;
+
+	current_size = A_SIZE_8(agp_bridge.current_size);
+
+	/* aperture size */
+	pci_write_config_byte(agp_bridge.dev, NVIDIA_0_APSIZE,
+		current_size->size_value);
+
+    /* address to map to */
+	pci_read_config_dword(agp_bridge.dev, NVIDIA_0_APBASE, &apbase);
+	apbase &= PCI_BASE_ADDRESS_MEM_MASK;
+	agp_bridge.gart_bus_addr = apbase;
+	aplimit = apbase + (current_size->size * 1024 * 1024) - 1;
+	pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_APBASE, apbase);
+	pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_APLIMIT, aplimit);
+	pci_write_config_dword(nvidia_private.dev_3, NVIDIA_3_APBASE, apbase);
+	pci_write_config_dword(nvidia_private.dev_3, NVIDIA_3_APLIMIT, aplimit);
+
+	/* directory size is 64k */
+	num_dirs = current_size->size / 64;
+	nvidia_private.num_active_entries = current_size->num_entries;
+	nvidia_private.pg_offset = 0;
+	if (num_dirs == 0) {
+		num_dirs = 1;
+		nvidia_private.num_active_entries /= (64 / current_size->size);
+		nvidia_private.pg_offset = (apbase & (64 * 1024 * 1024 - 1) &
+			~(current_size->size * 1024 * 1024 - 1)) / PAGE_SIZE;
+	}
+
+	/* attbase */
+	for(i = 0; i < 8; i++) {
+		pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_ATTBASE(i),
+			(agp_bridge.gatt_bus_addr + (i % num_dirs) * 64 * 1024) | 1);
+	}
+
+	/* gtlb control */
+	pci_read_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, &temp);
+	pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, temp | 0x11);
+
+	/* gart control */
+	pci_read_config_dword(agp_bridge.dev, NVIDIA_0_APSIZE, &temp);
+	pci_write_config_dword(agp_bridge.dev, NVIDIA_0_APSIZE, temp | 0x100);
+
+	/* map aperture */
+	nvidia_private.aperture =
+		(volatile u32 *) ioremap(apbase, 33 * PAGE_SIZE);
+
+	return 0;
+}
+
+static void nvidia_cleanup(void)
+{
+	aper_size_info_8 *previous_size;
+	u32 temp;
+
+	/* gart control */
+	pci_read_config_dword(agp_bridge.dev, NVIDIA_0_APSIZE, &temp);
+	pci_write_config_dword(agp_bridge.dev, NVIDIA_0_APSIZE, temp & ~(0x100));
+
+	/* gtlb control */
+	pci_read_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, &temp);
+	pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, temp & ~(0x11));
+
+	/* unmap aperture */
+	iounmap((void *) nvidia_private.aperture);
+
+	/* restore previous aperture size */
+	previous_size = A_SIZE_8(agp_bridge.previous_size);
+	pci_write_config_byte(agp_bridge.dev, NVIDIA_0_APSIZE,
+		previous_size->size_value);
+}
+
+static void nvidia_tlbflush(agp_memory * mem)
+{
+	unsigned long end;
+	u32 wbc_reg, temp;
+	int i;
+
+	/* flush chipset */
+	if (nvidia_private.wbc_mask) {
+		pci_read_config_dword(nvidia_private.dev_1, NVIDIA_1_WBC, &wbc_reg);
+		wbc_reg |= nvidia_private.wbc_mask;
+		pci_write_config_dword(nvidia_private.dev_1, NVIDIA_1_WBC, wbc_reg);
+
+		end = jiffies + 3*HZ;
+		do {
+			pci_read_config_dword(nvidia_private.dev_1,
+					NVIDIA_1_WBC, &wbc_reg);
+			if ((signed)(end - jiffies) <= 0) {
+				printk(KERN_ERR
+				    "TLB flush took more than 3 seconds.\n");
+			}
+		} while (wbc_reg & nvidia_private.wbc_mask);
+	}
+
+	/* flush TLB entries */
+	for(i = 0; i < 32 + 1; i++)
+		temp = nvidia_private.aperture[i * PAGE_SIZE / sizeof(u32)];
+	for(i = 0; i < 32 + 1; i++)
+		temp = nvidia_private.aperture[i * PAGE_SIZE / sizeof(u32)];
+}
+
+static unsigned long nvidia_mask_memory(unsigned long addr, int type)
+{
+	/* Memory type is ignored */
+	return addr | agp_bridge.masks[0].mask;
+}
+
+#if 0
+extern int agp_memory_reserved;
+
+static int nvidia_insert_memory(agp_memory * mem, off_t pg_start, int type)
+{
+	int i, j;
+	
+	if ((type != 0) || (mem->type != 0))
+		return -EINVAL;
+	
+	if ((pg_start + mem->page_count) >
+		(nvidia_private.num_active_entries - agp_memory_reserved/PAGE_SIZE))
+		return -EINVAL;
+	
+	for(j = pg_start; j < (pg_start + mem->page_count); j++) {
+		if (!PGE_EMPTY(agp_bridge, agp_bridge->gatt_table[nvidia_private.pg_offset + j]))
+			return -EBUSY;
+	}
+
+	if (mem->is_flushed == FALSE) {
+		global_cache_flush();
+		mem->is_flushed = TRUE;
+	}
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
+		agp_bridge->gatt_table[nvidia_private.pg_offset + j] = mem->memory[i];
+
+	agp_bridge->tlb_flush(mem);
+	return 0;
+}
+
+static int nvidia_remove_memory(agp_memory * mem, off_t pg_start, int type)
+{
+	int i;
+
+	if ((type != 0) || (mem->type != 0))
+		return -EINVAL;
+	
+	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
+		agp_bridge->gatt_table[nvidia_private.pg_offset + i] =
+		    (unsigned long) agp_bridge->scratch_page;
+	}
+
+	agp_bridge->tlb_flush(mem);
+	return 0;
+}
+#endif
+
+static int __init nvidia_nforce2_setup (struct pci_dev *pdev)
+{
+	nvidia_private.dev_1 =
+		pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1));
+	nvidia_private.dev_2 =
+		pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 2));
+	nvidia_private.dev_3 =
+		pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(30, 0));
+	if (!nvidia_private.dev_1 || !nvidia_private.dev_2 || !nvidia_private.dev_3) 
+	{
+                printk(KERN_INFO PFX "agpgart: Detected an NVIDIA "
+                        "nForce/nForce2 chipset, but could not find "
+                        "the secondary devices.\n");
+                return -ENODEV;
+        }
+	nvidia_private.wbc_mask = 0x80000000; 
+	agp_bridge.masks = nvidia_generic_masks;
+	agp_bridge.aperture_sizes = (void *) nvidia_generic_sizes;
+	agp_bridge.size_type = U8_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 5;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = nvidia_configure;
+	agp_bridge.fetch_size = nvidia_fetch_size;
+	agp_bridge.cleanup = nvidia_cleanup;
+	agp_bridge.tlb_flush = nvidia_tlbflush;
+	agp_bridge.mask_memory = nvidia_mask_memory;
+	agp_bridge.agp_enable = agp_generic_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge.insert_memory = agp_generic_insert_memory;
+	agp_bridge.remove_memory = agp_generic_remove_memory;
+	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge.free_by_type = agp_generic_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = agp_generic_resume;
+	agp_bridge.cant_use_aperture = 0;
+	agp_bridge.dev_private_data = &nvidia_private;
+
+	return 0;
+	
+	(void) pdev; /* unused */
+}
+
+static int __init nvidia_nforce_setup (struct pci_dev *pdev)
+{
+	nvidia_private.dev_1 =
+		pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1));
+	nvidia_private.dev_2 =
+		pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 2));
+	nvidia_private.dev_3 =
+		pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(30, 0));
+	if (!nvidia_private.dev_1 || !nvidia_private.dev_2 || !nvidia_private.dev_3) 
+	{
+                printk(KERN_INFO PFX "agpgart: Detected an NVIDIA "
+                        "nForce/nForce2 chipset, but could not find "
+                        "the secondary devices.\n");
+                return -ENODEV;
+        }
+	nvidia_private.wbc_mask =  0x00010000; 
+	agp_bridge.masks = nvidia_generic_masks;
+	agp_bridge.aperture_sizes = (void *) nvidia_generic_sizes;
+	agp_bridge.size_type = U8_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 5;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = nvidia_configure;
+	agp_bridge.fetch_size = nvidia_fetch_size;
+	agp_bridge.cleanup = nvidia_cleanup;
+	agp_bridge.tlb_flush = nvidia_tlbflush;
+	agp_bridge.mask_memory = nvidia_mask_memory;
+	agp_bridge.agp_enable = agp_generic_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge.insert_memory = agp_generic_insert_memory;
+	agp_bridge.remove_memory = agp_generic_remove_memory;
+	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge.free_by_type = agp_generic_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = agp_generic_resume;
+	agp_bridge.cant_use_aperture = 0;
+	agp_bridge.dev_private_data = &nvidia_private;
+
+	return 0;
+	
+	(void) pdev; /* unused */
+}
+
+#endif /* CONFIG_AGP_NV */
+
 #ifdef CONFIG_AGP_HP_ZX1
 
 #ifndef log2
@@ -4702,6 +5005,22 @@
 		via_generic_setup },
 #endif /* CONFIG_AGP_VIA */
 
+#ifdef CONFIG_AGP_NV
+	{ PCI_DEVICE_ID_NV_NFORCE2_0,
+		PCI_VENDOR_ID_NVIDIA,
+                NV_NFORCE_2,
+		"Nvidia",
+		"Nforce2",
+		nvidia_nforce2_setup },
+
+	{ PCI_DEVICE_ID_NV_NFORCE_0,
+	        PCI_VENDOR_ID_NVIDIA,
+                NV_NFORCE,
+		"Nvidia",
+		"Nforce",
+		nvidia_nforce_setup },
+#endif /* CONFIG_AGP_NV */
+
 #ifdef CONFIG_AGP_HP_ZX1
 	{ PCI_DEVICE_ID_HP_ZX1_LBA,
 		PCI_VENDOR_ID_HP,
diff --unified --recursive --new-file linux/include/linux/agp_backend.h linux-2.4.20-nforce/include/linux/agp_backend.h
--- linux/include/linux/agp_backend.h	2003-05-09 21:05:44.000000000 +0200
+++ linux-2.4.20-nforce/include/linux/agp_backend.h	2003-05-09 20:58:20.000000000 +0200
@@ -82,6 +82,8 @@
 	SVWRKS_LE,
 	SVWRKS_GENERIC,
 	HP_ZX1,
+	NV_NFORCE,
+        NV_NFORCE_2,
 };
 
 typedef struct _agp_version {

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2003-05-24 16:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-05-24 16:55 2.4.21-RC2 nforce2 agp patch Gutko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.