Unix Technical Forum

[patch] AGP 3.0 support, from FreeBSD

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 ...


Go Back   Unix Technical Forum > Unix Operating Systems > OpenBSD > mailing.openbsd.tech

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-18-2008, 08:21 AM
Dimitry Andric
 
Posts: n/a
Default [patch] AGP 3.0 support, from FreeBSD

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)

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 02:37 PM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com