Subject: kern/36904: Add AGP support for intel G33 chipset
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Anthony Mallet <anthony.mallet@laas.fr>
List: netbsd-bugs
Date: 09/04/2007 23:35:00
>Number:         36904
>Category:       kern
>Synopsis:       Add AGP support for intel G33 chipset
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Tue Sep 04 23:35:00 +0000 2007
>Originator:     Anthony Mallet
>Release:        NetBSD 4.99.30 i386
>Organization:
>Environment:


System: NetBSD 4.99.30 (FICUS) #54: Wed Sep  5 00:48:15 CEST 2007
	troot@ficus:/usr/obj/sys/arch/i386/compile/FICUS



>Description:


I added AGP support for the intel G33 chipset.
Strong inspiration was taken from the intel datasheets, the latest commit of
Eric Anholt in the FreeBSD agp driver and the X.org intel 2.1.0 driver.

The attached patch doesn't break existing code but has only been tested on my
G33 chipset. Note that the pcidevs files must be regenerated after applying the
patch.



>How-To-Repeat:





>Fix:


--- agp_g33 begins here ---
Index: arch/i386/pci/pchb.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/pci/pchb.c,v
retrieving revision 1.65
diff -u -r1.65 pchb.c
--- arch/i386/pci/pchb.c	15 Aug 2007 02:26:13 -0000	1.65
+++ arch/i386/pci/pchb.c	4 Sep 2007 22:57:56 -0000
@@ -317,6 +317,7 @@
 		case PCI_PRODUCT_INTEL_82945P_MCH:
 		case PCI_PRODUCT_INTEL_82945GM_HB:
 		case PCI_PRODUCT_INTEL_82965Q_HB:
+		case PCI_PRODUCT_INTEL_82G33_HB:
 			/*
 			 * The host bridge is either in GFX mode (internal
 			 * graphics) or in AGP mode. In GFX mode, we pretend
Index: dev/pci/agp.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/agp.c,v
retrieving revision 1.48
diff -u -r1.48 agp.c
--- dev/pci/agp.c	15 Aug 2007 02:26:13 -0000	1.48
+++ dev/pci/agp.c	4 Sep 2007 22:58:00 -0000
@@ -157,6 +157,8 @@
 	  NULL,			agp_i810_attach },
 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82965Q_HB,
 	  NULL,			agp_i810_attach },
+	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82G33_HB,
+	  NULL,			agp_i810_attach },
 #endif
 
 #if NAGP_INTEL > 0
Index: dev/pci/agp_i810.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/agp_i810.c,v
retrieving revision 1.42
diff -u -r1.42 agp_i810.c
--- dev/pci/agp_i810.c	15 Aug 2007 02:26:13 -0000	1.42
+++ dev/pci/agp_i810.c	4 Sep 2007 22:58:01 -0000
@@ -59,27 +59,33 @@
 #define READ4(off)	bus_space_read_4(isc->bst, isc->bsh, off)
 #define WRITE4(off,v)	bus_space_write_4(isc->bst, isc->bsh, off, v)
 #define WRITEGTT(off, v)						\
-	do {								\
-		if (isc->chiptype == CHIP_I915) {			\
+	do switch(isc->chiptype) {					\
+		case CHIP_I915:						\
+		case CHIP_G33:						\
 			bus_space_write_4(isc->gtt_bst, isc->gtt_bsh,	\
 			    (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4,	\
 			    (v));					\
-		} else if (isc->chiptype == CHIP_I965) {		\
+			break;						\
+		case CHIP_I965:						\
 			WRITE4(AGP_I965_GTT +				\
 			    (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4,	\
 			    (v));					\
-		} else {						\
+			break;						\
+		default:						\
 			WRITE4(AGP_I810_GTT +				\
 			    (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4,	\
 			    (v));					\
-		}							\
+			break;						\
 	} while (0)
 
-#define CHIP_I810 0	/* i810/i815 */
-#define CHIP_I830 1	/* 830M/845G */
-#define CHIP_I855 2	/* 852GM/855GM/865G */
-#define CHIP_I915 3	/* 915G/915GM/945G/945GM */
-#define CHIP_I965 4	/* 965Q */
+enum {
+  CHIP_I810,	/* i810/i815 */
+  CHIP_I830,	/* 830M/845G */
+  CHIP_I855,	/* 852GM/855GM/865G */
+  CHIP_I915,	/* 915G/915GM/945G/945GM */
+  CHIP_I965,	/* 965Q */
+  CHIP_G33,	/* G33/Q33/Q35 */
+};
 
 struct agp_i810_softc {
 	u_int32_t initial_aperture;	/* aperture size at startup */
@@ -149,6 +155,8 @@
 	case PCI_PRODUCT_INTEL_82945GM_IGD_1:
 	case PCI_PRODUCT_INTEL_82965Q_IGD:
 	case PCI_PRODUCT_INTEL_82965Q_IGD_1:
+	case PCI_PRODUCT_INTEL_82G33_IGD:
+	case PCI_PRODUCT_INTEL_82G33_IGD_1:
 		return (1);
 	}
 
@@ -178,7 +186,7 @@
 	struct agp_softc *sc = (void *)self;
 	struct agp_i810_softc *isc;
 	struct agp_gatt *gatt;
-	int error, apbase;
+	int error;
 	bus_size_t mmadrsize;
 
 	isc = malloc(sizeof *isc, M_AGP, M_NOWAIT|M_ZERO);
@@ -235,13 +243,25 @@
 	case PCI_PRODUCT_INTEL_82965Q_IGD_1:
 		isc->chiptype = CHIP_I965;
 		break;
+	case PCI_PRODUCT_INTEL_82G33_IGD:
+	case PCI_PRODUCT_INTEL_82G33_IGD_1:
+		isc->chiptype = CHIP_G33;
+		break;
 	}
 
-	apbase = isc->chiptype == CHIP_I915 ? AGP_I915_GMADR : AGP_I810_GMADR;
-	if (isc->chiptype == CHIP_I965) {
-		error = agp_i965_map_aperture(&isc->vga_pa, sc, AGP_I965_GMADR);
-	} else {
-		error = agp_map_aperture(&isc->vga_pa, sc, apbase);
+	switch(isc->chiptype) {
+	  case CHIP_I915:
+	  case CHIP_G33:
+	    error = agp_map_aperture(&isc->vga_pa, sc, AGP_I915_GMADR);
+	    break;
+
+	  case CHIP_I965:
+	    error = agp_i965_map_aperture(&isc->vga_pa, sc, AGP_I965_GMADR);
+	    break;
+
+	  default:
+	    error = agp_map_aperture(&isc->vga_pa, sc, AGP_I810_GMADR);
+	    break;
 	}
 	if (error != 0) {
 		aprint_error(": can't map aperture\n");
@@ -249,7 +269,7 @@
 		return error;
 	}
 
-	if (isc->chiptype == CHIP_I915) {
+	if (isc->chiptype == CHIP_I915 || isc->chiptype == CHIP_G33) {
 		error = pci_mapreg_map(&isc->vga_pa, AGP_I915_MMADR,
 		    PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh,
 		    NULL, &mmadrsize);
@@ -361,11 +381,14 @@
 
 		gatt->ag_physical = pgtblctl & ~1;
 	} else if (isc->chiptype == CHIP_I855 || isc->chiptype == CHIP_I915 ||
-		   isc->chiptype == CHIP_I965) {
+		   isc->chiptype == CHIP_I965 || isc->chiptype == CHIP_G33) {
 		pcireg_t reg;
 		u_int32_t pgtblctl, stolen;
 		u_int16_t gcc1;
 
+		reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I855_GCC1);
+		gcc1 = (u_int16_t)(reg >> 16);
+
 		/* 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.
@@ -380,14 +403,26 @@
 		case CHIP_I965:
 			stolen = 512 + 4;
 			break;
+		case CHIP_G33:
+			switch(gcc1 & AGP_G33_PGTBL_SIZE_MASK) {
+			case AGP_G33_PGTBL_SIZE_1M:
+				stolen = 1024 + 4;
+				break;
+			case AGP_G33_PGTBL_SIZE_2M:
+				stolen = 2048 + 4;
+				break;
+			default:
+				aprint_error(": bad gtt size\n");
+				agp_generic_detach(sc);
+				return EINVAL;
+			}
+			break;
 		default:
 			aprint_error(": bad chiptype\n");
 			agp_generic_detach(sc);
 			return EINVAL;
                }
 
-		reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I855_GCC1);
-		gcc1 = (u_int16_t)(reg >> 16);
 		switch (gcc1 & AGP_I855_GCC1_GMS) {
 		case AGP_I855_GCC1_GMS_STOLEN_1M:
 			isc->stolen = (1024 - stolen) * 1024 / 4096;
@@ -410,6 +445,14 @@
 		case AGP_I915_GCC1_GMS_STOLEN_64M:
 			isc->stolen = (65536 - stolen) * 1024 / 4096;
 			break;
+#if 0 /* XXX for G33, but the mask above filter those values */
+		case 0x80:
+			isc->stolen = (128*1024 - stolen) * 1024 / 4096;
+			break;
+		case 0x90:
+			isc->stolen = (256*1024 - stolen) * 1024 / 4096;
+			break;
+#endif
 		default:
 			isc->stolen = 0;
 			aprint_error(
@@ -512,6 +555,7 @@
 	case CHIP_I855:
 		return 128 * 1024 * 1024;
 	case CHIP_I915:
+	case CHIP_G33:
 		reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I915_MSAC);
 		msac = (u_int16_t)(reg >> 16);
 		if (msac & AGP_I915_MSAC_APER_128M)
@@ -579,6 +623,7 @@
 		break;
 	case CHIP_I855:
 	case CHIP_I915:
+	case CHIP_G33:
 		if (aperture != agp_i810_get_aperture(sc)) {
 			printf("%s: bad aperture size %d\n",
 			    sc->as_dev.dv_xname, aperture);
Index: dev/pci/agpreg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/agpreg.h,v
retrieving revision 1.14
diff -u -r1.14 agpreg.h
--- dev/pci/agpreg.h	15 Aug 2007 02:26:13 -0000	1.14
+++ dev/pci/agpreg.h	4 Sep 2007 22:58:01 -0000
@@ -240,6 +240,13 @@
 #define AGP_I965_GTT			0x80000
 
 /*
+ * Config registers for G33
+ */
+#define AGP_G33_PGTBL_SIZE_MASK		3<<8
+#define AGP_G33_PGTBL_SIZE_1M		1<<8
+#define AGP_G33_PGTBL_SIZE_2M		2<<8
+
+/*
  * AMD64 GART registers
  */
 #define	AGP_AMD64_APCTRL		0x90
Index: dev/pci/pcidevs
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/pcidevs,v
retrieving revision 1.896
diff -u -r1.896 pcidevs
--- dev/pci/pcidevs	1 Sep 2007 21:43:33 -0000	1.896
+++ dev/pci/pcidevs	4 Sep 2007 22:58:02 -0000
@@ -2386,6 +2386,10 @@
 product INTEL 82965Q_EXP	0x2991  82965Q PCI Express Bridge
 product INTEL 82965Q_IGD	0x2992  82965Q Integrated Graphics Device
 product INTEL 82965Q_IGD_1	0x2993  82965Q Integrated Graphics Device
+product INTEL 82G33_HB		0x29c0	82G33/P35 Host Bridge
+product INTEL 82G33_EXP		0x29c1	82G33/P35 PCI Express Bridge
+product	INTEL 82G33_IGD		0x29c2	82G33 Integrated Graphics Device
+product	INTEL 82G33_IGD_1	0x29c3	82G33 Integrated Graphics Device
 product INTEL 82801I_LAN	0x29c4	82801I LAN Controller
 product INTEL 31244		0x3200	31244 Serial ATA Controller
 product INTEL 82855PM_DDR	0x3340	82855PM MCH Host Controller
--- agp_g33 ends here ---