This is a discussion on [patch] AGP 3.0 support, from FreeBSD within the mailing.openbsd.tech forums, part of the OpenBSD category; --> Hi all, Here's a patch to port over the AGP 3.0 support from FreeBSD. Since I haven't got any ...
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| Hi all, Here's a patch to port over the AGP 3.0 support from FreeBSD. Since I haven't got any spare AGP 2 or 3 hardware around to test with, it would be nice to get some feedback. For now, there's a debug printf that should tell you in dmesg which AGP version (v2 or v3) and mode (1, 2, 4 or 8x) was used. Of course, you'll only get this when you start X. Also, please note that this doesn't work (yet) for i810, since that driver doesn't use agp_generic_enable(). It should work for the other AGP chipsets, though. Cheers, Dimitry Index: sys/dev/pci/agpvar.h ================================================== ================= RCS file: /cvs/src/sys/dev/pci/agpvar.h,v retrieving revision 1.3 diff -u -d -p -r1.3 agpvar.h --- sys/dev/pci/agpvar.h 25 Jul 2002 23:31:04 -0000 1.3 +++ sys/dev/pci/agpvar.h 27 Feb 2006 19:31:21 -0000 @@ -56,10 +56,7 @@ struct agp_memory_info { /* #define AGP_DEBUG */ #ifdef AGP_DEBUG -#define AGP_DPF(x...) do { \ - printf("agp: "); \ - printf(##x); \ -} while (0) +#define AGP_DPF(fmt, arg...) printf("agp: " fmt ,##arg) #else #define AGP_DPF(x...) do {} while (0) #endif Index: sys/dev/pci/vga_pci.c ================================================== ================= RCS file: /cvs/src/sys/dev/pci/vga_pci.c,v retrieving revision 1.20 diff -u -d -p -r1.20 vga_pci.c --- sys/dev/pci/vga_pci.c 19 Nov 2005 02:18:00 -0000 1.20 +++ sys/dev/pci/vga_pci.c 27 Feb 2006 19:31:21 -0000 @@ -551,23 +551,82 @@ agp_generic_detach(struct vga_pci_softc return 0; } -int -agp_generic_enable(struct vga_pci_softc *sc, u_int32_t mode) +/* + * This does the enable logic for v3, with the same topology + * restrictions as in place for v2 -- one bus, one device on the bus. + */ +static int +agp_v3_enable(struct vga_pci_softc *sc, u_int32_t mode, int capoff, + pcireg_t tstatus, pcireg_t mstatus) { - pcireg_t tstatus, mstatus; - pcireg_t command; - int rq, sba, fw, rate, capoff; + u_int32_t command; + int rq, sba, fw, rate, arqsz, cal; + + /* Set RQ to the min of mode, tstatus and mstatus */ + rq = AGP_MODE_GET_RQ(mode); + if (AGP_MODE_GET_RQ(tstatus) < rq) + rq = AGP_MODE_GET_RQ(tstatus); + if (AGP_MODE_GET_RQ(mstatus) < rq) + rq = AGP_MODE_GET_RQ(mstatus); + + /* + * ARQSZ - Set the value to the maximum one. + * Don't allow the mode register to override values. + */ + arqsz = AGP_MODE_GET_ARQSZ(mode); + if (AGP_MODE_GET_ARQSZ(tstatus) > rq) + rq = AGP_MODE_GET_ARQSZ(tstatus); + if (AGP_MODE_GET_ARQSZ(mstatus) > rq) + rq = AGP_MODE_GET_ARQSZ(mstatus); + + /* Calibration cycle - don't allow override by mode register */ + cal = AGP_MODE_GET_CAL(tstatus); + if (AGP_MODE_GET_CAL(mstatus) < cal) + cal = AGP_MODE_GET_CAL(mstatus); + + /* SBA must be supported for AGP v3. */ + sba = 1; + + /* Set FW if all three support it. */ + fw = (AGP_MODE_GET_FW(tstatus) + & AGP_MODE_GET_FW(mstatus) + & AGP_MODE_GET_FW(mode)); - if (pci_get_capability(sc->sc_pc, sc->sc_pcitag, PCI_CAP_AGP, - &capoff, NULL) == 0) { - printf("agp_generic_enable: not an AGP capable device\n"); - return -1; - } + /* Figure out the max rate */ + rate = (AGP_MODE_GET_RATE(tstatus) + & AGP_MODE_GET_RATE(mstatus) + & AGP_MODE_GET_RATE(mode)); + if (rate & AGP_MODE_V3_RATE_8x) + rate = AGP_MODE_V3_RATE_8x; + else + rate = AGP_MODE_V3_RATE_4x; + printf("Setting AGP v3 mode %d\n", rate * 4); - tstatus = pci_conf_read(sc->sc_pc, sc->sc_pcitag, - sc->sc_capoff + AGP_STATUS); - mstatus = pci_conf_read(sc->sc_pc, sc->sc_pcitag, - capoff + AGP_STATUS); + /* XXX: Not sure what this is good for? */ + pci_conf_write(sc->sc_pc, sc->sc_pcitag, + sc->sc_capoff + AGP_COMMAND, 0); + + /* Construct the new mode word and tell the hardware */ + command = AGP_MODE_SET_RQ(0, rq); + command = AGP_MODE_SET_ARQSZ(command, arqsz); + command = AGP_MODE_SET_CAL(command, cal); + command = AGP_MODE_SET_SBA(command, sba); + command = AGP_MODE_SET_FW(command, fw); + command = AGP_MODE_SET_RATE(command, rate); + command = AGP_MODE_SET_AGP(command, 1); + pci_conf_write(sc->sc_pc, sc->sc_pcitag, + sc->sc_capoff + AGP_COMMAND, command); + pci_conf_write(sc->sc_pc, sc->sc_pcitag, capoff + AGP_COMMAND, command); + + return (0); +} + +static int +agp_v2_enable(struct vga_pci_softc *sc, u_int32_t mode, int capoff, + pcireg_t tstatus, pcireg_t mstatus) +{ + u_int32_t command; + int rq, sba, fw, rate; /* Set RQ to the min of mode, tstatus and mstatus */ rq = AGP_MODE_GET_RQ(mode); @@ -578,26 +637,27 @@ agp_generic_enable(struct vga_pci_softc /* Set SBA if all three can deal with SBA */ sba = (AGP_MODE_GET_SBA(tstatus) - & AGP_MODE_GET_SBA(mstatus) - & AGP_MODE_GET_SBA(mode)); + & AGP_MODE_GET_SBA(mstatus) + & AGP_MODE_GET_SBA(mode)); /* Similar for FW */ fw = (AGP_MODE_GET_FW(tstatus) - & AGP_MODE_GET_FW(mstatus) - & AGP_MODE_GET_FW(mode)); + & AGP_MODE_GET_FW(mstatus) + & AGP_MODE_GET_FW(mode)); /* Figure out the max rate */ rate = (AGP_MODE_GET_RATE(tstatus) - & AGP_MODE_GET_RATE(mstatus) - & AGP_MODE_GET_RATE(mode)); - if (rate & AGP_MODE_RATE_4x) - rate = AGP_MODE_RATE_4x; - else if (rate & AGP_MODE_RATE_2x) - rate = AGP_MODE_RATE_2x; + & AGP_MODE_GET_RATE(mstatus) + & AGP_MODE_GET_RATE(mode)); + if (rate & AGP_MODE_V2_RATE_4x) + rate = AGP_MODE_V2_RATE_4x; + else if (rate & AGP_MODE_V2_RATE_2x) + rate = AGP_MODE_V2_RATE_2x; else - rate = AGP_MODE_RATE_1x; + rate = AGP_MODE_V2_RATE_1x; + printf("Setting AGP v2 mode %d\n", rate); - /* Construct the new mode word and tell the hardware */ + /* Construct the new mode word and tell the hardware */ command = AGP_MODE_SET_RQ(0, rq); command = AGP_MODE_SET_SBA(command, sba); command = AGP_MODE_SET_FW(command, fw); @@ -606,7 +666,39 @@ agp_generic_enable(struct vga_pci_softc pci_conf_write(sc->sc_pc, sc->sc_pcitag, sc->sc_capoff + AGP_COMMAND, command); pci_conf_write(sc->sc_pc, sc->sc_pcitag, capoff + AGP_COMMAND, command); - return 0; + + return (0); +} + +int +agp_generic_enable(struct vga_pci_softc *sc, u_int32_t mode) +{ + pcireg_t tstatus, mstatus; + int capoff; + + if (pci_get_capability(sc->sc_pc, sc->sc_pcitag, PCI_CAP_AGP, + &capoff, NULL) == 0) { + printf("agp_generic_enable: not an AGP capable device\n"); + return -1; + } + + tstatus = pci_conf_read(sc->sc_pc, sc->sc_pcitag, + sc->sc_capoff + AGP_STATUS); + mstatus = pci_conf_read(sc->sc_pc, sc->sc_pcitag, + capoff + AGP_STATUS); + + /* + * Check display and bridge for AGP v3 support. AGP v3 allows + * more variety in topology than v2, e.g. multiple AGP devices + * attached to one bridge, or multiple AGP bridges in one + * system. This doesn't attempt to address those situations, + * but should work fine for a classic single AGP slot system + * with AGP v3. + */ + if (AGP_MODE_GET_MODE_3(tstatus) && AGP_MODE_GET_MODE_3(mstatus)) + return (agp_v3_enable(sc, mode, capoff, tstatus, mstatus)); + else + return (agp_v2_enable(sc, mode, capoff, tstatus, mstatus)); } struct agp_memory * Index: sys/sys/agpio.h ================================================== ================= RCS file: /cvs/src/sys/sys/agpio.h,v retrieving revision 1.1 diff -u -d -p -r1.1 agpio.h --- sys/sys/agpio.h 12 Jul 2002 20:17:03 -0000 1.1 +++ sys/sys/agpio.h 27 Feb 2006 19:31:24 -0000 @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/sys/agpio.h,v 1.1 2000/06/09 16:04:30 dfr Exp $ + * $FreeBSD: src/sys/sys/agpio.h,v 1.4 2003/10/23 18:08:56 jhb Exp $ */ #ifndef _SYS_AGPIO_H_ @@ -41,22 +41,43 @@ /* * Macros to manipulate AGP mode words. + * + * SBA = Sideband Address Port + * FW = Fast Writes */ #define AGP_MODE_GET_RQ(x) (((x) & 0xff000000U) >> 24) +#define AGP_MODE_GET_ARQSZ(x) (((x) & 0x0000e000U) >> 13) +#define AGP_MODE_GET_CAL(x) (((x) & 0x00001c00U) >> 10) #define AGP_MODE_GET_SBA(x) (((x) & 0x00000200U) >> 9) #define AGP_MODE_GET_AGP(x) (((x) & 0x00000100U) >> 8) -#define AGP_MODE_GET_4G(x) (((x) & 0x00000020U) >> 5) +#define AGP_MODE_GET_GART_64(x) (((x) & 0x00000080U) >> 7) +#define AGP_MODE_GET_OVER_4G(x) (((x) & 0x00000020U) >> 5) #define AGP_MODE_GET_FW(x) (((x) & 0x00000010U) >> 4) -#define AGP_MODE_GET_RATE(x) ((x) & 0x00000003U) +#define AGP_MODE_GET_MODE_3(x) (((x) & 0x00000008U) >> 3) +#define AGP_MODE_GET_RATE(x) ((x) & 0x00000007U) #define AGP_MODE_SET_RQ(x,v) (((x) & ~0xff000000U) | ((v) << 24)) +#define AGP_MODE_SET_ARQSZ(x,v) (((x) & ~0x0000e000U) | ((v) << 13)) +#define AGP_MODE_SET_CAL(x,v) (((x) & ~0x00001c00U) | ((v) << 10)) #define AGP_MODE_SET_SBA(x,v) (((x) & ~0x00000200U) | ((v) << 9)) #define AGP_MODE_SET_AGP(x,v) (((x) & ~0x00000100U) | ((v) << 8)) -#define AGP_MODE_SET_4G(x,v) (((x) & ~0x00000020U) | ((v) << 5)) +#define AGP_MODE_SET_GART_64(x,v) (((x) & ~0x00000080U) | ((v) << 7)) +#define AGP_MODE_SET_OVER_4G(x,v) (((x) & ~0x00000020U) | ((v) << 5)) #define AGP_MODE_SET_FW(x,v) (((x) & ~0x00000010U) | ((v) << 4)) -#define AGP_MODE_SET_RATE(x,v) (((x) & ~0x00000003U) | (v)) -#define AGP_MODE_RATE_1x 0x00000001 -#define AGP_MODE_RATE_2x 0x00000002 -#define AGP_MODE_RATE_4x 0x00000004 +#define AGP_MODE_SET_MODE_3(x,v) (((x) & ~0x00000008U) | ((v) << 3)) +#define AGP_MODE_SET_RATE(x,v) (((x) & ~0x00000007U) | (v)) +#define AGP_MODE_V2_RATE_1x 0x00000001 +#define AGP_MODE_V2_RATE_2x 0x00000002 +#define AGP_MODE_V2_RATE_4x 0x00000004 +#define AGP_MODE_V3_RATE_4x 0x00000001 +#define AGP_MODE_V3_RATE_8x 0x00000002 +#define AGP_MODE_V3_RATE_RSVD 0x00000004 + +/* XXX: Compat */ +#define AGP_MODE_GET_4G(x) AGP_MODE_GET_OVER_4G(x) +#define AGP_MODE_SET_4G(x) AGP_MODE_SET_OVER_4G(x) +#define AGP_MODE_RATE_1x AGP_MODE_V2_RATE_1x +#define AGP_MODE_RATE_2x AGP_MODE_V2_RATE_2x +#define AGP_MODE_RATE_4x AGP_MODE_V2_RATE_4x #define AGPIOC_BASE 'A' #define AGPIOC_INFO _IOR (AGPIOC_BASE, 0, agp_info) |