Index: agp_i810.c =================================================================== RCS file: /home/ncvs/src/sys/pci/agp_i810.c,v retrieving revision 1.38 diff -u -r1.38 agp_i810.c --- agp_i810.c 27 Jun 2006 14:05:11 -0000 1.38 +++ agp_i810.c 15 Aug 2006 06:58:28 -0000 @@ -67,10 +67,13 @@ #define WRITE4(off,v) bus_space_write_4(sc->bst, sc->bsh, off, v) #define WRITEGTT(off,v) bus_space_write_4(sc->gtt_bst, sc->gtt_bsh, off, v) -#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 */ +enum { + CHIP_I810, /* i810/i815 */ + CHIP_I830, /* 830M/845G */ + CHIP_I855, /* 852GM/855GM/865G */ + CHIP_I915, /* 915G/915GM */ + CHIP_I965 /* G965 */ +}; struct agp_i810_softc { struct agp_softc agp; @@ -90,6 +93,11 @@ bus_space_handle_t gtt_bsh; /* bus_space handle */ void *argb_cursor; /* contigmalloc area for ARGB cursor */ + + /* list of allocated resources */ + struct resource_spec resource_specs[3]; + struct resource *resources[3]; + int resource_count; }; /* For adding new devices, devid is the id of the graphics controller @@ -130,6 +138,8 @@ {0x27A28086, CHIP_I915, 0x00020000, "Intel 82945GM (945GM GMCH) SVGA controller"}, */ + {0x29828086, CHIP_I965, 0x00020000, + "Intel 965G SVGA controller"}, {0, 0, 0, NULL} }; @@ -197,6 +207,8 @@ { device_t bdev; const struct agp_i810_match *match; + u_int8_t smram; + int gcc1, deven; if (resource_disabled("agp", device_get_unit(dev))) return (ENXIO); @@ -214,20 +226,18 @@ /* * checking whether internal graphics device has been activated. */ - if (match->chiptype == CHIP_I810) { - u_int8_t smram; - + switch (match->chiptype) { + case CHIP_I810: smram = pci_read_config(bdev, AGP_I810_SMRAM, 1); - if ((smram & AGP_I810_SMRAM_GMS) - == AGP_I810_SMRAM_GMS_DISABLED) { + if ((smram & AGP_I810_SMRAM_GMS) == + AGP_I810_SMRAM_GMS_DISABLED) { if (bootverbose) printf("I810: disabled, not probing\n"); return ENXIO; } - } else if (match->chiptype == CHIP_I830 || - match->chiptype == CHIP_I855) { - unsigned int gcc1; - + break; + case CHIP_I830: + case CHIP_I855: gcc1 = pci_read_config(bdev, AGP_I830_GCC1, 1); if ((gcc1 & AGP_I830_GCC1_DEV2) == AGP_I830_GCC1_DEV2_DISABLED) { @@ -235,16 +245,17 @@ printf("I830: disabled, not probing\n"); return ENXIO; } - } else if (match->chiptype == CHIP_I915) { - unsigned int gcc1; - - gcc1 = pci_read_config(bdev, AGP_I915_DEVEN, 4); - if ((gcc1 & AGP_I915_DEVEN_D2F0) == + break; + case CHIP_I915: + case CHIP_I965: + deven = pci_read_config(bdev, AGP_I915_DEVEN, 4); + if ((deven & AGP_I915_DEVEN_D2F0) == AGP_I915_DEVEN_D2F0_DISABLED) { if (bootverbose) printf("I915: disabled, not probing\n"); return ENXIO; } + break; } if (match->devid == 0x35828086) { @@ -277,13 +288,44 @@ return BUS_PROBE_DEFAULT; } +static void +agp_i810_dump_regs(device_t dev) +{ + struct agp_i810_softc *sc = device_get_softc(dev); + + device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n", + READ4(AGP_I810_PGTBL_CTL)); + + switch (sc->chiptype) { + case CHIP_I810: + device_printf(dev, "AGP_I810_MISCC: %04x\n", + pci_read_config(sc->bdev, AGP_I810_MISCC, 2)); + break; + case CHIP_I830: + device_printf(dev, "AGP_I830_GCC1: %02x\n", + pci_read_config(sc->bdev, AGP_I830_GCC1, 1)); + break; + case CHIP_I855: + device_printf(dev, "AGP_I855_GCC1: %02x\n", + pci_read_config(sc->bdev, AGP_I855_GCC1, 1)); + break; + case CHIP_I915: + case CHIP_I965: + device_printf(dev, "AGP_I855_GCC1: %02x\n", + pci_read_config(sc->bdev, AGP_I855_GCC1, 1)); + device_printf(dev, "AGP_I915_MSAC: %02x\n", + pci_read_config(sc->bdev, AGP_I915_MSAC, 1)); + break; + } +} + static int agp_i810_attach(device_t dev) { struct agp_i810_softc *sc = device_get_softc(dev); struct agp_gatt *gatt; const struct agp_i810_match *match; - int error, rid; + int error; sc->bdev = agp_i810_find_bridge(dev); if (!sc->bdev) @@ -296,31 +338,86 @@ match = agp_i810_match(dev); sc->chiptype = match->chiptype; - /* Same for i810 and i830 */ - if (sc->chiptype == CHIP_I915) - rid = AGP_I915_MMADR; - else - rid = AGP_I810_MMADR; + /* The i810 through i855 have the registers at BAR 1, and the GATT + * gets allocated by us. The i915 has registers in BAR 0 and + * the GATT is at the start of the aperture, and should only be + * accessed by the OS through BAR 3. The G965 has registers and GATT + * in the same BAR (0) -- first 512kb is regisers, second 512kb is + * GATT. + */ + switch (sc->chiptype) { + case CHIP_I810: + case CHIP_I830: + case CHIP_I855: + sc->resource_specs[0].type = SYS_RES_MEMORY; + sc->resource_specs[0].rid = AGP_I810_MMADR; + sc->regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &sc->resource_specs[0].rid, RF_ACTIVE); + if (sc->regs == NULL) { + agp_generic_detach(dev); + return ENODEV; + } + sc->resources[0] = sc->regs; + sc->resource_count++; + break; + case CHIP_I915: + sc->resource_specs[0].type = SYS_RES_MEMORY; + sc->resource_specs[0].rid = AGP_I915_MMADR; + sc->regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &sc->resource_specs[0].rid, RF_ACTIVE); + if (sc->regs == NULL) { + agp_generic_detach(dev); + return ENODEV; + } + sc->resources[0] = sc->regs; + sc->resource_count++; - sc->regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (!sc->regs) { - agp_generic_detach(dev); - return ENODEV; - } - sc->bst = rman_get_bustag(sc->regs); - sc->bsh = rman_get_bushandle(sc->regs); + sc->resource_specs[1].type = SYS_RES_MEMORY; + sc->resource_specs[1].rid = AGP_I915_GTTADR; + sc->gtt = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &sc->resource_specs[1].rid, RF_ACTIVE); + if (sc->gtt == NULL) { + bus_release_resources(dev, sc->resource_specs, + sc->resources); + agp_generic_detach(dev); + return ENODEV; + } + sc->resources[1] = sc->gtt; + sc->resource_count++; + break; + case CHIP_I965: + sc->resource_specs[0].type = SYS_RES_MEMORY; + sc->resource_specs[0].rid = AGP_I965_GTTMMADR; + sc->regs = bus_alloc_resource(dev, SYS_RES_MEMORY, + &sc->resource_specs[0].rid, 0, 512 * 1024, 1, RF_ACTIVE); + if (sc->regs == NULL) { + agp_generic_detach(dev); + return ENODEV; + } + sc->resources[0] = sc->regs; + sc->resource_count++; - if (sc->chiptype == CHIP_I915) { - rid = AGP_I915_GTTADR; - sc->gtt = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (!sc->gtt) { - bus_release_resource(dev, SYS_RES_MEMORY, - AGP_I810_MMADR, sc->regs); + sc->resource_specs[1].type = SYS_RES_MEMORY; + sc->resource_specs[1].rid = AGP_I965_GTTMMADR; + sc->gtt = bus_alloc_resource(dev, SYS_RES_MEMORY, + &sc->resource_specs[1].rid, + 512 * 1024, 1024 * 1024, 1, RF_ACTIVE); + if (sc->gtt == NULL) { + bus_release_resources(dev, sc->resource_specs, + sc->resources); agp_generic_detach(dev); return ENODEV; } + sc->resources[1] = sc->gtt; + sc->resource_count++; + break; + } + sc->resources[sc->resource_count] = NULL; + sc->resource_specs[sc->resource_count].type = -1; + + sc->bst = rman_get_bustag(sc->regs); + sc->bsh = rman_get_bushandle(sc->regs); + if (sc->gtt != NULL) { sc->gtt_bst = rman_get_bustag(sc->gtt); sc->gtt_bsh = rman_get_bushandle(sc->gtt); } @@ -329,6 +426,8 @@ gatt = malloc( sizeof(struct agp_gatt), M_AGP, M_NOWAIT); if (!gatt) { + bus_release_resources(dev, sc->resource_specs, + sc->resources); agp_generic_detach(dev); return ENOMEM; } @@ -349,6 +448,8 @@ if (!gatt->ag_virtual) { if (bootverbose) device_printf(dev, "contiguous allocation failed\n"); + bus_release_resources(dev, sc->resource_specs, + sc->resources); free(gatt, M_AGP); agp_generic_detach(dev); return ENOMEM; @@ -377,6 +478,9 @@ default: sc->stolen = 0; device_printf(dev, "unknown memory configuration, disabling\n"); + bus_release_resources(dev, sc->resource_specs, + sc->resources); + free(gatt, M_AGP); agp_generic_detach(dev); return EINVAL; } @@ -390,18 +494,34 @@ WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); gatt->ag_physical = pgtblctl & ~1; - } else if (sc->chiptype == CHIP_I855 || sc->chiptype == CHIP_I915) { /* CHIP_I855 */ + } else if (sc->chiptype == CHIP_I855 || sc->chiptype == CHIP_I915 || + sc->chiptype == CHIP_I965) { unsigned int gcc1, pgtblctl, stolen; /* 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 (sc->chiptype == CHIP_I855) - stolen = 132; - else - stolen = 260; + switch (sc->chiptype) { + case CHIP_I855: + stolen = 128 + 4; + break; + case CHIP_I915: + stolen = 256 + 4; + break; + case CHIP_I965: + stolen = 512 + 4; + break; + default: + device_printf(dev, "Bad chiptype\n"); + bus_release_resources(dev, sc->resource_specs, + sc->resources); + free(gatt, M_AGP); + agp_generic_detach(dev); + return EINVAL; + } + /* 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: @@ -428,6 +548,9 @@ default: sc->stolen = 0; device_printf(dev, "unknown memory configuration, disabling\n"); + bus_release_resources(dev, sc->resource_specs, + sc->resources); + free(gatt, M_AGP); agp_generic_detach(dev); return EINVAL; } @@ -443,6 +566,8 @@ gatt->ag_physical = pgtblctl & ~1; } + agp_i810_dump_regs(dev); + return 0; } @@ -474,15 +599,7 @@ } free(sc->gatt, M_AGP); - if (sc->chiptype == CHIP_I915) { - bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_GTTADR, - sc->gtt); - bus_release_resource(dev, SYS_RES_MEMORY, AGP_I915_MMADR, - sc->regs); - } else { - bus_release_resource(dev, SYS_RES_MEMORY, AGP_I810_MMADR, - sc->regs); - } + bus_release_resources(dev, sc->resource_specs, sc->resources); return 0; } @@ -511,12 +628,19 @@ return 128 * 1024 * 1024; case CHIP_I915: temp = pci_read_config(dev, AGP_I915_MSAC, 1); - if ((temp & AGP_I915_MSAC_GMASIZE) == - AGP_I915_MSAC_GMASIZE_128) { + switch (temp & AGP_I915_MSAC_GMASIZE) { + case AGP_I915_MSAC_GMASIZE_128: return 128 * 1024 * 1024; - } else { + case AGP_I915_MSAC_GMASIZE_256: return 256 * 1024 * 1024; + default: + device_printf(dev, "Unknown aperture size (0x%x)\n", + temp); } + case CHIP_I965: + return 512 * 1024 * 1024; + default: + device_printf(dev, "Unknown chipset\n"); } return 0; @@ -587,6 +711,12 @@ pci_write_config(dev, AGP_I915_MSAC, temp, 1); break; + case CHIP_I965: + if (aperture != 512 * 1024 * 1024) { + device_printf(dev, "bad aperture size %d\n", aperture); + return EINVAL; + } + break; } return 0; @@ -609,7 +739,7 @@ } } - if (sc->chiptype == CHIP_I915) { + if (sc->chiptype == CHIP_I915 || sc->chiptype == CHIP_I965) { WRITEGTT((offset >> AGP_PAGE_SHIFT) * 4, physical | 1); } else { WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, physical | 1); @@ -633,7 +763,7 @@ } } - if (sc->chiptype == CHIP_I915) { + if (sc->chiptype == CHIP_I915 || sc->chiptype == CHIP_I965) { WRITEGTT((offset >> AGP_PAGE_SHIFT) * 4, 0); } else { WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, 0); @@ -798,7 +928,8 @@ for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) { u_int32_t physical = mem->am_physical + i; - if (sc->chiptype == CHIP_I915) { + if (sc->chiptype == CHIP_I915 || + sc->chiptype == CHIP_I965) { WRITEGTT(((offset + i) >> AGP_PAGE_SHIFT) * 4, physical | 1); } else { @@ -844,7 +975,8 @@ for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) { vm_offset_t offset = mem->am_offset; - if (sc->chiptype == CHIP_I915) { + if (sc->chiptype == CHIP_I915 || + sc->chiptype == CHIP_I965) { WRITEGTT(((offset + i) >> AGP_PAGE_SHIFT) * 4, 0); } else { Index: agpreg.h =================================================================== RCS file: /home/ncvs/src/sys/pci/agpreg.h,v retrieving revision 1.17 diff -u -r1.17 agpreg.h --- agpreg.h 20 Dec 2005 22:45:24 -0000 1.17 +++ agpreg.h 15 Aug 2006 03:27:42 -0000 @@ -244,6 +244,11 @@ #define AGP_I915_MSAC_GMASIZE_256 0x00 /* + * G965 registers + */ +#define AGP_I965_GTTMMADR 0x10 + +/* * NVIDIA nForce/nForce2 registers */ #define AGP_NVIDIA_0_APBASE 0x10