Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Dec 2007 09:53:13 -0800
From:      Hiroshi Nishida <nishida@asusa.net>
To:        freebsd-stable@freebsd.org
Subject:   Re: G965 patch for 6.3-Beta
Message-ID:  <475D7D09.4000702@asusa.net>
In-Reply-To: <20071210163959.3169b23e.une@hkg.ac.jp>
References:  <4759A1F3.10008@asusa.net> <20071210163959.3169b23e.une@hkg.ac.jp>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------040602000402090908060102
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi.

I've attached the patch.
Please apply it at /sys/pci.

Thank you.

Hiroyuki Une wrote:

> At least, I need. Your patch will fix the problem that xorg fails to 
> detect memory
>
>assinged as the VRAM occationally.
>
>Thank you.
>
>---
>Hiroyuki Une: Hiroshima Kokusai Gakuin University
>une@hkg.ac.jp / harrier@seiryu.id.hkg.ac.jp
>  
>

-- 
Hiroshi Nishida
nishida at asusa.net


--------------040602000402090908060102
Content-Type: text/plain;
 name="agp_i810-965.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="agp_i810-965.diff"

--- agp_i810.c.org	2007-11-16 14:07:27.000000000 -0800
+++ agp_i810.c	2007-12-10 09:20:22.000000000 -0800
@@ -28,6 +28,7 @@
 /*
  * Fixes for 830/845G support: David Dawes <dawes@xfree86.org>
  * 852GM/855GM/865G support added by David Dawes <dawes@xfree86.org>
+ * An experimental 965 support added by Hiroshi Nishida
  */
 
 #include <sys/cdefs.h>
@@ -71,6 +72,8 @@
 #define CHIP_I830 1	/* 830M/845G */
 #define CHIP_I855 2	/* 852GM/855GM/865G */
 #define CHIP_I915 3	/* 915G/915GM */
+#define CHIP_I965 4	/* G965 */
+#define CHIP_G33  5	/* G33/Q33/Q35 */
 
 struct agp_i810_softc {
 	struct agp_softc agp;
@@ -152,6 +155,24 @@
 
 	case 0x27A28086:
 		return ("Intel 82945GM (945GM GMCH) SVGA controller");
+
+	case 0x29728086:
+		return ("Intel 946GZ SVGA controller");
+
+	case 0x29828086:
+		return ("Intel G965 SVGA controller");
+
+	case 0x29928086:
+		return ("Intel Q965 SVGA controller");
+
+	case 0x29a28086:
+		return ("Intel G965 SVGA controller");
+
+	case 0x2a028086:
+		return ("Intel GM965 SVGA controller");
+
+	case 0x2a128086:
+		return ("Intel GME965 SVGA controller");
 	};
 
 	return NULL;
@@ -260,6 +281,12 @@
 		case 0x25928086:
 		case 0x27728086:	/* 945G GMCH */
 		case 0x27A28086:	/* 945GM GMCH */
+		case 0x29728086:	/* 946GZ */
+		case 0x29828086:	/* G965 */
+		case 0x29928086:	/* Q965 */
+		case 0x29a28086:	/* G965 */
+		case 0x2a028086:	/* GM965 */
+		case 0x2a128086:	/* GME965 */
 			gcc1 = pci_read_config(bdev, AGP_I915_DEVEN, 4);
 			if ((gcc1 & AGP_I915_DEVEN_D2F0) ==
 			    AGP_I915_DEVEN_D2F0_DISABLED) {
@@ -317,24 +344,50 @@
 	case 0x27A28086:	/* 945GM GMCH */
 		sc->chiptype = CHIP_I915;
 		break;
+	case 0x29728086:
+	case 0x29828086:
+	case 0x29928086:
+	case 0x29a28086:
+	case 0x2a028086:
+	case 0x2a128086:
+		sc->chiptype = CHIP_I965;
+		break;
 	};
 
+#if 0
 	/* Same for i810 and i830 */
 	if (sc->chiptype == CHIP_I915)
 		rid = AGP_I915_MMADR;
 	else
 		rid = AGP_I810_MMADR;
+#else
+	switch (sc->chiptype) {
+	case CHIP_I915:
+	case CHIP_G33:
+		rid = AGP_I915_MMADR;
+		break;
+	case CHIP_I965:
+		rid = AGP_I965_GTTMMADR;
+		break;
+	default:
+		rid = AGP_I810_MMADR;
+		break;
+	}
+
+	printf("Chip Type: %d, rid:%x\n", sc->chiptype, rid);
+#endif
 
 	sc->regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
 					  RF_ACTIVE);
 	if (!sc->regs) {
 		agp_generic_detach(dev);
+		printf("ENODEV at agp_i810_attach() 1\n");
 		return ENODEV;
 	}
 	sc->bst = rman_get_bustag(sc->regs);
 	sc->bsh = rman_get_bushandle(sc->regs);
 
-	if (sc->chiptype == CHIP_I915) {
+	if (sc->chiptype == CHIP_I915 || sc->chiptype == CHIP_G33) {
 		rid = AGP_I915_GTTADR;
 		sc->gtt = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
 						 RF_ACTIVE);
@@ -342,6 +395,7 @@
 			bus_release_resource(dev, SYS_RES_MEMORY,
 					     AGP_I915_MMADR, sc->regs);
 			agp_generic_detach(dev);
+			printf("ENODEV at agp_i810_attach() 2\n");
 			return ENODEV;
 		}
 		sc->gtt_bst = rman_get_bustag(sc->gtt);
@@ -362,12 +416,28 @@
 			bus_release_resource(dev, SYS_RES_MEMORY,
 					     AGP_I915_GTTADR, sc->regs);
 			agp_generic_detach(dev);
+			printf("ENODEV at agp_i810_attach() 3\n");
 			return ENODEV;
 		}
 
 	}
+	else if (sc->chiptype == CHIP_I965) {
+		rid = AGP_I915_GMADR;
+		sc->gm = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 0);
+		if (sc->gm == NULL) {
+			bus_release_resource(dev, SYS_RES_MEMORY,
+					     AGP_I915_MMADR, sc->regs);
+			agp_generic_detach(dev);
+			printf("ENODEV at agp_i810_attach() 4\n");
+			return ENODEV;
+		}
+	}
 
 	sc->initial_aperture = AGP_GET_APERTURE(dev);
+	if (sc->initial_aperture == 0) {
+		device_printf(dev, "bad initial aperture size, disabling\n");
+		return ENXIO;
+	}
 
 	gatt = malloc( sizeof(struct agp_gatt), M_AGP, M_NOWAIT);
 	if (!gatt) {
@@ -432,40 +502,82 @@
 		WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
 
 		gatt->ag_physical = pgtblctl & ~1;
-	} else if (sc->chiptype == CHIP_I855 || sc->chiptype == CHIP_I915) {	/* CHIP_I855 */
-		unsigned int gcc1, pgtblctl, stolen;
+	} else if (sc->chiptype == CHIP_I855 || sc->chiptype == CHIP_I915 ||
+		   sc->chiptype == CHIP_I965 || sc->chiptype == CHIP_G33) {
+		unsigned int gcc1, pgtblctl, stolen, gtt_size;
 
 		/* Stolen memory is set up at the beginning of the aperture by
 		 * the BIOS, consisting of the GATT followed by 4kb for the BIOS
 		 * display.
 		 */
+#if 0
 		if (sc->chiptype == CHIP_I855)
 			stolen = 132;
 		else
 			stolen = 260;
+#else
+		switch (sc->chiptype) {
+		case CHIP_I855:
+			gtt_size = 128;
+			break;
+		case CHIP_I915:
+			gtt_size = 256;
+			break;
+		case CHIP_I965:
+		case CHIP_G33:
+			switch (READ4(AGP_I810_PGTBL_CTL) &
+				AGP_I810_PGTBL_SIZE_MASK) {
+			case AGP_I810_PGTBL_SIZE_128KB:
+				gtt_size = 128;
+				break;
+			case AGP_I810_PGTBL_SIZE_256KB:
+				gtt_size = 256;
+				break;
+			case AGP_I810_PGTBL_SIZE_512KB:
+				gtt_size = 512;
+				break;
+			default:
+				device_printf(dev, "Bad PGTBL size\n");
+				agp_generic_detach(dev);
+				return EINVAL;
+			}
+			break;
+		default:
+			device_printf(dev, "Bad chiptype\n");
+			agp_generic_detach(dev);
+			return EINVAL;
+		}
+#endif
 
+		/* GCC1 is called MGGC on i915+ */
 		gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1);
 		switch (gcc1 & AGP_I855_GCC1_GMS) {
 			case AGP_I855_GCC1_GMS_STOLEN_1M:
-				sc->stolen = (1024 - stolen) * 1024 / 4096;
+				stolen = 1024;
 				break;
 			case AGP_I855_GCC1_GMS_STOLEN_4M: 
-				sc->stolen = (4096 - stolen) * 1024 / 4096;
+				stolen = 4096;
 				break;
 			case AGP_I855_GCC1_GMS_STOLEN_8M: 
-				sc->stolen = (8192 - stolen) * 1024 / 4096;
+				stolen = 8192;
 				break;
 			case AGP_I855_GCC1_GMS_STOLEN_16M: 
-				sc->stolen = (16384 - stolen) * 1024 / 4096;
+				stolen = 16384;
 				break;
 			case AGP_I855_GCC1_GMS_STOLEN_32M: 
-				sc->stolen = (32768 - stolen) * 1024 / 4096;
+				stolen = 32768;
 				break;
 			case AGP_I915_GCC1_GMS_STOLEN_48M: 
-				sc->stolen = (49152 - stolen) * 1024 / 4096;
+				stolen = 49152;
 				break;
 			case AGP_I915_GCC1_GMS_STOLEN_64M: 
-				sc->stolen = (65536 - stolen) * 1024 / 4096;
+				stolen = 65536;
+				break;
+			case AGP_G33_GCC1_GMS_STOLEN_128M:
+				stolen = 128 * 1024;
+				break;
+			case AGP_G33_GCC1_GMS_STOLEN_256M:
+				stolen = 256 * 1024;
 				break;
 			default:
 				sc->stolen = 0;
@@ -473,6 +585,7 @@
 				agp_generic_detach(dev);
 				return EINVAL;
 		}
+		sc->stolen = (stolen - gtt_size - 4) * 1024 / 4096;
 		if (sc->stolen > 0)
 			device_printf(dev, "detected %dk stolen memory\n", sc->stolen * 4);
 		device_printf(dev, "aperture size is %dM\n", sc->initial_aperture / 1024 / 1024);
@@ -518,6 +631,7 @@
 	}
 	free(sc->gatt, M_AGP);
 
+#if 0
 	if (sc->chiptype == CHIP_I915) {
 		bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_GMADR,
 				     sc->gm);
@@ -529,6 +643,35 @@
 		bus_release_resource(dev, SYS_RES_MEMORY, AGP_I810_MMADR,
 				     sc->regs);
 	}
+#else
+	switch (sc->chiptype) {
+	case CHIP_I810:
+	case CHIP_I830:
+	case CHIP_I855:
+		bus_release_resource(dev, SYS_RES_MEMORY, AGP_I810_MMADR,
+				     sc->regs);
+		break;
+	case CHIP_I915:
+	case CHIP_G33:
+		bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_GMADR,
+				     sc->gm);
+		bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_GTTADR,
+				     sc->gtt);
+		bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_MMADR,
+				     sc->regs);
+		break;
+	case CHIP_I965:
+		bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_GTTADR,
+				     sc->gtt);
+		bus_release_resource(dev, SYS_RES_MEMORY, AGP_I965_GTTMMADR,
+				     sc->regs);
+		break;
+	default:
+		device_printf(dev, "Bad chiptype at agp_i810_detach()\n");
+		agp_generic_detach(dev);
+		return EINVAL;
+	}
+#endif
 	agp_free_res(dev);
 
 	child = device_find_child( dev, "drmsub", 0 );
@@ -561,6 +704,8 @@
 	case CHIP_I855:
 		return 128 * 1024 * 1024;
 	case CHIP_I915:
+	case CHIP_I965:
+	case CHIP_G33:
 		/* The documentation states that AGP_I915_MSAC should have bit
 		 * 1 set if the aperture is 128MB instead of 256.  However,
 		 * that bit appears to not get set, so we instead use the
@@ -620,6 +765,8 @@
 		}
 		break;
 	case CHIP_I915:
+	case CHIP_I965:
+	case CHIP_G33:
 		temp = pci_read_config(dev, AGP_I915_MSAC, 1);
 		temp &= ~AGP_I915_MSAC_GMASIZE;
 
@@ -642,6 +789,46 @@
 	return 0;
 }
 
+/**
+ * Writes a GTT entry mapping the page at the given offset from the beginning
+ * of the aperture to the given physical address.
+ */
+static void
+agp_i810_write_gtt_entry(device_t dev, int offset, vm_offset_t physical,
+			 int enabled)
+{
+	struct agp_i810_softc *sc = device_get_softc(dev);
+	u_int32_t pte;
+
+	pte = (u_int32_t)physical | 1;
+	if (sc->chiptype == CHIP_I965 || sc->chiptype == CHIP_G33) {
+		pte |= (physical & 0x0000000f00000000ull) >> 28;
+	} else {
+		/* If we do actually have memory above 4GB on an older system,
+		 * crash cleanly rather than scribble on system memory,
+		 * so we know we need to fix it.
+		 */
+		KASSERT((pte & 0x0000000f00000000ull) == 0,
+		    (">4GB physical address in agp"));
+	}
+
+	switch (sc->chiptype) {
+	case CHIP_I810:
+	case CHIP_I830:
+	case CHIP_I855:
+		WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4,
+		    physical | 1);
+		break;
+	case CHIP_I915:
+	case CHIP_G33:
+		WRITEGTT((offset >> AGP_PAGE_SHIFT) * 4, pte);
+		break;
+	case CHIP_I965:
+		WRITE4((offset >> AGP_PAGE_SHIFT) * 4 + (512 * 1024), pte);
+		break;
+	}
+}
+
 static int
 agp_i810_bind_page(device_t dev, int offset, vm_offset_t physical)
 {
@@ -659,11 +846,15 @@
 		}
 	}
 
+#if 0
 	if (sc->chiptype == CHIP_I915) {
 		WRITEGTT((offset >> AGP_PAGE_SHIFT) * 4, physical | 1);
 	} else {
 		WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, physical | 1);
 	}
+#else
+	agp_i810_write_gtt_entry(dev, offset, physical, 1);
+#endif
 
 	return 0;
 }
@@ -683,11 +874,15 @@
 		}
 	}
 
+#if 0
 	if (sc->chiptype == CHIP_I915) {
 		WRITEGTT((offset >> AGP_PAGE_SHIFT) * 4, 0);
 	} else {
 		WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, 0);
 	}
+#else
+	agp_i810_write_gtt_entry(dev, offset, 0, 0);
+#endif
 	
 	return 0;
 }
@@ -848,6 +1043,7 @@
 		for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
 			u_int32_t physical = mem->am_physical + i;
 
+#if 0
 			if (sc->chiptype == CHIP_I915) {
 				WRITEGTT(((offset + i) >> AGP_PAGE_SHIFT) * 4,
 				    physical | 1);
@@ -856,6 +1052,9 @@
 				    ((offset + i) >> AGP_PAGE_SHIFT) * 4,
 				    physical | 1);
 			}
+#else
+			agp_i810_write_gtt_entry(dev, offset + i, physical, 1);
+#endif
 		}
 		agp_flush_cache();
 		mem->am_offset = offset;
@@ -894,6 +1093,7 @@
 		for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
 			vm_offset_t offset = mem->am_offset;
 
+#if 0
 			if (sc->chiptype == CHIP_I915) {
 				WRITEGTT(((offset + i) >> AGP_PAGE_SHIFT) * 4,
 				    0);
@@ -901,6 +1101,9 @@
 				WRITE4(AGP_I810_GTT +
 				    ((offset + i) >> AGP_PAGE_SHIFT) * 4, 0);
 			}
+#else
+			agp_i810_write_gtt_entry(dev, offset + i, 0, 0);
+#endif
 		}
 		agp_flush_cache();
 		mem->am_is_bound = 0;
--- agpreg.h.org	2007-11-20 16:19:46.000000000 -0800
+++ agpreg.h	2007-11-27 15:42:27.000000000 -0800
@@ -180,10 +180,19 @@
  * Memory mapped register offsets for i810 chipset.
  */
 #define AGP_I810_PGTBL_CTL	0x2020
-#define AGP_I810_DRT		0x3000
-#define AGP_I810_DRT_UNPOPULATED 0x00
-#define AGP_I810_DRT_POPULATED	0x01
-#define AGP_I810_GTT		0x10000
+
+/**
+ * This field determines the actual size of the global GTT on the 965
+ * and G33
+ */
+#define AGP_I810_PGTBL_SIZE_MASK	0x0000000e
+#define AGP_I810_PGTBL_SIZE_512KB	(0 << 1)
+#define AGP_I810_PGTBL_SIZE_256KB	(1 << 1)
+#define AGP_I810_PGTBL_SIZE_128KB	(2 << 1)
+#define AGP_I810_DRT			0x3000
+#define AGP_I810_DRT_UNPOPULATED	0x00
+#define AGP_I810_DRT_POPULATED		0x01
+#define AGP_I810_GTT			0x10000
  
 /*
  * Config registers for i830MG device 0
@@ -244,6 +253,21 @@
 #define AGP_I915_MSAC_GMASIZE_256	0x00
 
 /*
+ * G965 registers
+ */
+#define AGP_I965_GTTMMADR		0x10
+#define AGP_I965_MSAC			0x62
+#define AGP_I965_MSAC_GMASIZE_128	0x00
+#define AGP_I965_MSAC_GMASIZE_256	0x02
+#define AGP_I965_MSAC_GMASIZE_512	0x06
+
+/*
+ * G33 registers
+ */
+#define AGP_G33_GCC1_GMS_STOLEN_128M	0x80
+#define AGP_G33_GCC1_GMS_STOLEN_256M	0x90
+
+/*
  * NVIDIA nForce/nForce2 registers
  */
 #define	AGP_NVIDIA_0_APBASE		0x10

--------------040602000402090908060102--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?475D7D09.4000702>