From ab5a0ec88ec848e62cfee49b7e557e7fcc474dac Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sun, 4 Jul 2004 00:24:52 +0000 Subject: [PATCH] Add AGP support for the i852GM, i855GM, and i865G. Add AGP support for a number of new SiS bridges (530-760). Add AGP support for teh VIA 8385. Remove some aperture cleanups. Taken-From: FreeBSD-5 --- sys/dev/agp/agp_i810.c | 114 +++++++++++++++++++++++++++++++-------- sys/dev/agp/agp_intel.c | 14 ++--- sys/dev/agp/agp_nvidia.c | 6 +-- sys/dev/agp/agp_sis.c | 42 +++++++++++++-- sys/dev/agp/agp_via.c | 47 +++++++++++----- sys/dev/agp/agpreg.h | 32 ++++++++++- 6 files changed, 202 insertions(+), 53 deletions(-) diff --git a/sys/dev/agp/agp_i810.c b/sys/dev/agp/agp_i810.c index cd62a1a0b3..9cced763c6 100644 --- a/sys/dev/agp/agp_i810.c +++ b/sys/dev/agp/agp_i810.c @@ -1,4 +1,4 @@ -/*- +/* * Copyright (c) 2000 Doug Rabson * Copyright (c) 2000 Ruslan Ermilov * All rights reserved. @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/pci/agp_i810.c,v 1.1.2.5 2002/09/15 08:45:41 anholt Exp $ - * $DragonFly: src/sys/dev/agp/agp_i810.c,v 1.7 2004/05/13 14:33:14 joerg Exp $ + * $DragonFly: src/sys/dev/agp/agp_i810.c,v 1.8 2004/07/04 00:24:52 dillon Exp $ */ /* @@ -64,7 +64,8 @@ MALLOC_DECLARE(M_AGP); #define WRITE4(off,v) bus_space_write_4(sc->bst, sc->bsh, off, v) #define CHIP_I810 0 /* i810/i815 */ -#define CHIP_I830 1 /* i830/i845 */ +#define CHIP_I830 1 /* 830M/845G */ +#define CHIP_I855 2 /* 852GM/855GM/865G */ struct agp_i810_softc { struct agp_softc agp; @@ -100,13 +101,32 @@ agp_i810_match(device_t dev) return ("Intel 82815 (i815 GMCH) SVGA controller"); case 0x35778086: - return ("Intel 82830 (i830M GMCH) SVGA controller"); + return ("Intel 82830M (i830M GMCH) SVGA controller"); case 0x25628086: - return ("Intel 82845 (i845 GMCH) SVGA controller"); + return ("Intel 82845G (i845 GMCH) SVGA controller"); case 0x25728086: - return ("Intel 82865 (i865 GMCH) SVGA controller"); + return ("Intel 82865G (i865 GMCH) SVGA controller"); + + case 0x35828086: + switch (pci_read_config(dev, AGP_I85X_CAPID, 1)) { + case AGP_I855_GME: + return ("Intel 82855GME (855GME GMCH) SVGA controller"); + + case AGP_I855_GM: + return ("Intel 82855GM (855GM GMCH) SVGA controller"); + + case AGP_I852_GME: + return ("Intel 82852GME (852GME GMCH) SVGA controller"); + + case AGP_I852_GM: + return ("Intel 82852GM (852GM GMCH) SVGA controller"); + + default: + return ("Intel 8285xM (85xGM GMCH) SVGA controller"); + } + /* not reached */ }; return NULL; @@ -164,6 +184,7 @@ agp_i810_probe(device_t dev) if (desc) { device_t bdev; u_int8_t smram; + unsigned int gcc1; int devid = pci_get_devid(dev); bdev = agp_i810_find_bridge(dev); @@ -176,9 +197,12 @@ agp_i810_probe(device_t dev) /* * checking whether internal graphics device has been activated. */ - if ( (devid != 0x35778086 ) && - (devid != 0x25628086 ) && - (devid != 0x25728086 ) ) { + switch(devid) { + case 0x71218086: + case 0x71238086: + case 0x71258086: + case 0x11328086: + /* i810 */ smram = pci_read_config(bdev, AGP_I810_SMRAM, 1); if ((smram & AGP_I810_SMRAM_GMS) == AGP_I810_SMRAM_GMS_DISABLED) { @@ -186,14 +210,21 @@ agp_i810_probe(device_t dev) printf("I810: disabled, not probing\n"); return ENXIO; } - } else { /* I830MG */ - unsigned int gcc1; + break; + case 0x35778086: + case 0x35828086: + case 0x25628086: + case 0x25728086: + /* i830 */ gcc1 = pci_read_config(bdev, AGP_I830_GCC1, 1); if ((gcc1 & AGP_I830_GCC1_DEV2) == AGP_I830_GCC1_DEV2_DISABLED) { if (bootverbose) printf("I830: disabled, not probing\n"); return ENXIO; } + break; + default: + return ENXIO; } device_verbose(dev); @@ -228,9 +259,12 @@ agp_i810_attach(device_t dev) break; case 0x35778086: case 0x25628086: - case 0x25728086: sc->chiptype = CHIP_I830; break; + case 0x25728086: + case 0x35828086: + sc->chiptype = CHIP_I855; + break; }; /* Same for i810 and i830 */ @@ -278,7 +312,7 @@ agp_i810_attach(device_t dev) agp_flush_cache(); /* Install the GATT. */ WRITE4(AGP_I810_PGTBL_CTL, gatt->ag_physical | 1); - } else { + } else if (sc->chiptype == CHIP_I830) { /* The i830 automatically initializes the 128k gatt on boot. */ unsigned int gcc1, pgtblctl; @@ -299,26 +333,60 @@ agp_i810_attach(device_t dev) agp_generic_detach(dev); return EINVAL; } - if (sc->stolen > 0) - device_printf(dev, "detected %dk stolen memory\n", sc->stolen * 4); + 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); /* GATT address is already in there, make sure it's enabled */ pgtblctl = READ4(AGP_I810_PGTBL_CTL); -#if 0 - device_printf(dev, "PGTBL_CTL is 0x%08x\n", pgtblctl); -#endif pgtblctl |= 1; WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); gatt->ag_physical = pgtblctl & ~1; - } + } else { /* CHIP_I855 */ + /* The i855 automatically initializes the 128k gatt on boot. */ + unsigned int gcc1, pgtblctl; - /* - * Make sure the chipset can see everything. - */ - agp_flush_cache(); + 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 - 132) * 1024 / 4096; + break; + case AGP_I855_GCC1_GMS_STOLEN_4M: + sc->stolen = (4096 - 132) * 1024 / 4096; + break; + case AGP_I855_GCC1_GMS_STOLEN_8M: + sc->stolen = (8192 - 132) * 1024 / 4096; + break; + case AGP_I855_GCC1_GMS_STOLEN_16M: + sc->stolen = (16384 - 132) * 1024 / 4096; + break; + case AGP_I855_GCC1_GMS_STOLEN_32M: + sc->stolen = (32768 - 132) * 1024 / 4096; + break; + default: + sc->stolen = 0; + device_printf(dev, + "unknown memory configuration, disabling\n"); + agp_generic_detach(dev); + return EINVAL; + } + 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); + /* GATT address is already in there, make sure it's enabled */ + pgtblctl = READ4(AGP_I810_PGTBL_CTL); + pgtblctl |= 1; + WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); + + gatt->ag_physical = pgtblctl & ~1; + } return 0; } diff --git a/sys/dev/agp/agp_intel.c b/sys/dev/agp/agp_intel.c index 38ddcdb4c6..78fe0c2574 100644 --- a/sys/dev/agp/agp_intel.c +++ b/sys/dev/agp/agp_intel.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/pci/agp_intel.c,v 1.1.2.5 2003/06/02 17:38:19 jhb Exp $ - * $DragonFly: src/sys/dev/agp/agp_intel.c,v 1.4 2003/12/09 19:40:56 dillon Exp $ + * $DragonFly: src/sys/dev/agp/agp_intel.c,v 1.5 2004/07/04 00:24:52 dillon Exp $ */ #include "opt_bus.h" @@ -109,6 +109,9 @@ agp_intel_match(device_t dev) case 0x25788086: return ("Intel 82875P host to AGP bridge"); + + case 0x25608086: /* i845G */ + return ("Intel 82845G host to AGP bridge"); }; if (pci_get_vendor(dev) == 0x8086) @@ -152,10 +155,6 @@ agp_intel_attach(device_t dev) MAX_APSIZE; pci_write_config(dev, AGP_INTEL_APSIZE, value, 1); sc->initial_aperture = AGP_GET_APERTURE(dev); - if (sc->initial_aperture == 0) { - device_printf(dev, "bad initial aperture size, disabling\n"); - return ENXIO; - } for (;;) { gatt = agp_alloc_gatt(dev); @@ -214,6 +213,7 @@ agp_intel_attach(device_t dev) case 0x33408086: /* i855 */ case 0x25708086: /* i865 */ case 0x25788086: /* i875P */ + case 0x25608086: /* i845G */ pci_write_config(dev, AGP_INTEL_I845_MCHCFG, (pci_read_config(dev, AGP_INTEL_I845_MCHCFG, 1) | (1 << 1)), 1); @@ -238,6 +238,7 @@ agp_intel_attach(device_t dev) case 0x25318086: /* i860 */ case 0x25708086: /* i865 */ case 0x25788086: /* i875P */ + case 0x25608086: /* i845G */ pci_write_config(dev, AGP_INTEL_I8XX_ERRSTS, 0x00ff, 2); break; @@ -280,6 +281,7 @@ agp_intel_detach(device_t dev) & ~(1 << 1)), 1); case 0x1a308086: /* i845 */ + case 0x25608086: /* i845G */ case 0x33408086: /* i855 */ case 0x25708086: /* i865 */ case 0x25788086: /* i875P */ @@ -375,7 +377,7 @@ agp_intel_flush_tlb(device_t dev) u_int32_t val; val = pci_read_config(dev, AGP_INTEL_AGPCTRL, 4); - pci_write_config(dev, AGP_INTEL_AGPCTRL, val & ~(1 << 8), 4); + pci_write_config(dev, AGP_INTEL_AGPCTRL, val & ~(1 << 7), 4); pci_write_config(dev, AGP_INTEL_AGPCTRL, val, 4); } diff --git a/sys/dev/agp/agp_nvidia.c b/sys/dev/agp/agp_nvidia.c index da1fd45058..57cb47a40b 100644 --- a/sys/dev/agp/agp_nvidia.c +++ b/sys/dev/agp/agp_nvidia.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * Based on FreeBSD v1.2. - * $DragonFly: src/sys/dev/agp/agp_nvidia.c,v 1.2 2003/12/09 19:40:56 dillon Exp $ + * $DragonFly: src/sys/dev/agp/agp_nvidia.c,v 1.3 2004/07/04 00:24:52 dillon Exp $ */ /* @@ -173,10 +173,6 @@ agp_nvidia_attach (device_t dev) return (error); sc->initial_aperture = AGP_GET_APERTURE(dev); - if (sc->initial_aperture == 0) { - device_printf(dev, "bad initial aperture size, disabling\n"); - return ENXIO; - } for (;;) { gatt = agp_alloc_gatt(dev); diff --git a/sys/dev/agp/agp_sis.c b/sys/dev/agp/agp_sis.c index 40776bb080..942be33d19 100644 --- a/sys/dev/agp/agp_sis.c +++ b/sys/dev/agp/agp_sis.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/pci/agp_sis.c,v 1.1.2.1 2000/07/19 09:48:04 ru Exp $ - * $DragonFly: src/sys/dev/agp/agp_sis.c,v 1.4 2003/12/09 19:40:56 dillon Exp $ + * $DragonFly: src/sys/dev/agp/agp_sis.c,v 1.5 2004/07/04 00:24:52 dillon Exp $ */ #include "opt_bus.h" @@ -65,8 +65,44 @@ agp_sis_match(device_t dev) switch (pci_get_devid(dev)) { case 0x00011039: return ("SiS 5591 host to AGP bridge"); + case 0x05301039: + return ("SiS 530 host to AGP bridge"); + case 0x05401039: + return ("SiS 540 host to AGP bridge"); + case 0x05501039: + return ("SiS 550 host to AGP bridge"); + case 0x06201039: + return ("SiS 620 host to AGP bridge"); + case 0x06301039: + return ("SiS 630 host to AGP bridge"); + case 0x06451039: + return ("SiS 645 host to AGP bridge"); + case 0x06461039: + return ("SiS 645DX host to AGP bridge"); case 0x06481039: return ("SiS 648 host to AGP bridge"); + case 0x06501039: + return ("SiS 650 host to AGP bridge"); + case 0x06511039: + return ("SiS 651 host to AGP bridge"); + case 0x06551039: + return ("SiS 655 host to AGP bridge"); + case 0x06611039: + return ("SiS 661 host to AGP bridge"); + case 0x07301039: + return ("SiS 730 host to AGP bridge"); + case 0x07351039: + return ("SiS 735 host to AGP bridge"); + case 0x07401039: + return ("SiS 740 host to AGP bridge"); + case 0x07411039: + return ("SiS 741 host to AGP bridge"); + case 0x07451039: + return ("SiS 745 host to AGP bridge"); + case 0x07461039: + return ("SiS 746 host to AGP bridge"); + case 0x07601039: + return ("SiS 760 host to AGP bridge"); }; if (pci_get_vendor(dev) == 0x1039) @@ -102,10 +138,6 @@ agp_sis_attach(device_t dev) return error; sc->initial_aperture = AGP_GET_APERTURE(dev); - if (sc->initial_aperture == 0) { - device_printf(dev, "bad initial aperture size, disabling\n"); - return ENXIO; - } for (;;) { gatt = agp_alloc_gatt(dev); diff --git a/sys/dev/agp/agp_via.c b/sys/dev/agp/agp_via.c index d40b1bc656..2484badd45 100644 --- a/sys/dev/agp/agp_via.c +++ b/sys/dev/agp/agp_via.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/pci/agp_via.c,v 1.1.2.2 2001/10/04 09:53:04 ru Exp $ - * $DragonFly: src/sys/dev/agp/agp_via.c,v 1.4 2003/12/09 19:40:56 dillon Exp $ + * $DragonFly: src/sys/dev/agp/agp_via.c,v 1.5 2004/07/04 00:24:52 dillon Exp $ */ #include "opt_bus.h" @@ -46,12 +46,22 @@ #include #include +#define REG_GARTCTRL 0 +#define REG_APSIZE 1 +#define REG_ATTBASE 2 + struct agp_via_softc { struct agp_softc agp; u_int32_t initial_aperture; /* aperture size at startup */ struct agp_gatt *gatt; + int *regs; }; +static int via_v2_regs[] = { AGP_VIA_GARTCTRL, AGP_VIA_APSIZE, + AGP_VIA_ATTBASE }; +static int via_v3_regs[] = { AGP3_VIA_GARTCTRL, AGP3_VIA_APSIZE, + AGP3_VIA_ATTBASE }; + static const char* agp_via_match(device_t dev) { @@ -75,6 +85,8 @@ agp_via_match(device_t dev) return ("VIA 82C694X (Apollo Pro 133A) host to PCI bridge"); case 0x06911106: return ("VIA 82C691 (Apollo Pro) host to PCI bridge"); + case 0x31881106: + return ("VIA 8385 host to PCI bridge"); }; if (pci_get_vendor(dev) == 0x1106) @@ -105,15 +117,20 @@ agp_via_attach(device_t dev) struct agp_gatt *gatt; int error; + switch (pci_get_devid(dev)) { + case 0x31881106: + sc->regs = via_v3_regs; + break; + default: + sc->regs = via_v2_regs; + break; + } + error = agp_generic_attach(dev); if (error) return error; sc->initial_aperture = AGP_GET_APERTURE(dev); - if (sc->initial_aperture == 0) { - device_printf(dev, "bad initial aperture size, disabling\n"); - return ENXIO; - } for (;;) { gatt = agp_alloc_gatt(dev); @@ -132,10 +149,10 @@ agp_via_attach(device_t dev) sc->gatt = gatt; /* Install the gatt. */ - pci_write_config(dev, AGP_VIA_ATTBASE, gatt->ag_physical | 3, 4); + pci_write_config(dev, sc->regs[REG_ATTBASE], gatt->ag_physical | 3, 4); /* Enable the aperture. */ - pci_write_config(dev, AGP_VIA_GARTCTRL, 0x0f, 4); + pci_write_config(dev, sc->regs[REG_GARTCTRL], 0x0f, 4); return 0; } @@ -150,8 +167,8 @@ agp_via_detach(device_t dev) if (error) return error; - pci_write_config(dev, AGP_VIA_GARTCTRL, 0, 4); - pci_write_config(dev, AGP_VIA_ATTBASE, 0, 4); + pci_write_config(dev, sc->regs[REG_GARTCTRL], 0, 4); + pci_write_config(dev, sc->regs[REG_ATTBASE], 0, 4); AGP_SET_APERTURE(dev, sc->initial_aperture); agp_free_gatt(sc->gatt); @@ -161,9 +178,10 @@ agp_via_detach(device_t dev) static u_int32_t agp_via_get_aperture(device_t dev) { + struct agp_via_softc *sc = device_get_softc(dev); u_int32_t apsize; - apsize = pci_read_config(dev, AGP_VIA_APSIZE, 1) & 0x1f; + apsize = pci_read_config(dev, sc->regs[REG_APSIZE], 1) & 0x1f; /* * The size is determined by the number of low bits of @@ -178,6 +196,7 @@ agp_via_get_aperture(device_t dev) static int agp_via_set_aperture(device_t dev, u_int32_t aperture) { + struct agp_via_softc *sc = device_get_softc(dev); u_int32_t apsize; /* @@ -191,7 +210,7 @@ agp_via_set_aperture(device_t dev, u_int32_t aperture) if ((((apsize ^ 0xff) << 20) | ((1 << 20) - 1)) + 1 != aperture) return EINVAL; - pci_write_config(dev, AGP_VIA_APSIZE, apsize, 1); + pci_write_config(dev, sc->regs[REG_APSIZE], apsize, 1); return 0; } @@ -223,8 +242,10 @@ agp_via_unbind_page(device_t dev, int offset) static void agp_via_flush_tlb(device_t dev) { - pci_write_config(dev, AGP_VIA_GARTCTRL, 0x8f, 4); - pci_write_config(dev, AGP_VIA_GARTCTRL, 0x0f, 4); + struct agp_via_softc *sc = device_get_softc(dev); + + pci_write_config(dev, sc->regs[REG_GARTCTRL], 0x8f, 4); + pci_write_config(dev, sc->regs[REG_GARTCTRL], 0x0f, 4); } static device_method_t agp_via_methods[] = { diff --git a/sys/dev/agp/agpreg.h b/sys/dev/agp/agpreg.h index 75f73ed6cd..b05866625f 100644 --- a/sys/dev/agp/agpreg.h +++ b/sys/dev/agp/agpreg.h @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/pci/agpreg.h,v 1.3.2.5 2003/06/02 17:38:19 jhb Exp $ - * $DragonFly: src/sys/dev/agp/agpreg.h,v 1.4 2003/12/09 19:40:56 dillon Exp $ + * $DragonFly: src/sys/dev/agp/agpreg.h,v 1.5 2004/07/04 00:24:52 dillon Exp $ */ #ifndef _PCI_AGPREG_H_ @@ -47,6 +47,29 @@ #define AGP_STATUS 0x4 #define AGP_COMMAND 0x8 +#define AGP_STATUS_AGP3 0x0008 +#define AGP_STATUS_RQ_MASK 0xff000000 +#define AGP_COMMAND_RQ_MASK 0xff000000 +#define AGP_STATUS_ARQSZ_MASK 0xe000 +#define AGP_COMMAND_ARQSZ_MASK 0xe000 +#define AGP_STATUS_CAL_MASK 0x1c00 +#define AGP_COMMAND_CAL_MASK 0x1c00 +#define AGP_STATUS_ISOCH 0x10000 +#define AGP_STATUS_SBA 0x0200 +#define AGP_STATUS_ITA_COH 0x0100 +#define AGP_STATUS_GART64 0x0080 +#define AGP_STATUS_HTRANS 0x0040 +#define AGP_STATUS_64BIT 0x0020 +#define AGP_STATUS_FW 0x0010 +#define AGP_COMMAND_RQ_MASK 0xff000000 +#define AGP_COMMAND_ARQSZ_MASK 0xe000 +#define AGP_COMMAND_CAL_MASK 0x1c00 +#define AGP_COMMAND_SBA 0x0200 +#define AGP_COMMAND_AGP 0x0100 +#define AGP_COMMAND_GART64 0x0080 +#define AGP_COMMAND_64BIT 0x0020 +#define AGP_COMMAND_FW 0x0010 + /* * Config offsets for Intel AGP chipsets. @@ -72,6 +95,13 @@ #define AGP_VIA_APSIZE 0x84 #define AGP_VIA_ATTBASE 0x88 +/* + * Config offsets for VIA AGP 3.0 chipsets. + */ +#define AGP3_VIA_GARTCTRL 0x90 +#define AGP3_VIA_APSIZE 0x94 +#define AGP3_VIA_ATTBASE 0x98 + /* * Config offsets for SiS AGP chipsets. */ -- 2.35.2