summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bsd-core/drmP.h12
-rw-r--r--bsd-core/drm_agpsupport.c11
-rw-r--r--bsd-core/mga_drv.c27
-rw-r--r--linux-core/drmP.h17
-rw-r--r--linux-core/drm_stub.c3
-rw-r--r--linux-core/mga_drv.c43
-rw-r--r--shared-core/mga_drv.h4
7 files changed, 114 insertions, 3 deletions
diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h
index 6af29718..9943a4f6 100644
--- a/bsd-core/drmP.h
+++ b/bsd-core/drmP.h
@@ -638,6 +638,18 @@ struct drm_device {
void (*irq_handler)(DRM_IRQ_ARGS);
int (*vblank_wait)(drm_device_t *dev, unsigned int *sequence);
+ /**
+ * Called by \c drm_device_is_agp. Typically used to determine if a
+ * card is really attached to AGP or not.
+ *
+ * \param dev DRM device handle
+ *
+ * \returns true if the card really is attached to AGP, false
+ * otherwise.
+ */
+ int (*device_is_agp) (struct drm_device * dev);
+
+
drm_ioctl_desc_t *driver_ioctls;
int max_driver_ioctl;
diff --git a/bsd-core/drm_agpsupport.c b/bsd-core/drm_agpsupport.c
index 6d58134a..33fb3f0c 100644
--- a/bsd-core/drm_agpsupport.c
+++ b/bsd-core/drm_agpsupport.c
@@ -46,6 +46,12 @@ drm_device_is_agp(drm_device_t *dev)
u_int32_t status;
u_int8_t ptr, next;
+
+ if ( (dev->driver->device_is_agp != NULL)
+ && ! (*dev->driver->device_is_agp)( dev ) ) {
+ return 0;
+ }
+
/*
* Check the CAP_LIST bit of the PCI status register first.
*/
@@ -71,6 +77,11 @@ drm_device_is_agp(drm_device_t *dev)
return 0;
#else
+ if ( (dev->driver->device_is_agp != NULL)
+ && ! (*dev->driver->device_is_agp)( dev ) ) {
+ return 0;
+ }
+
/* XXX: fill me in for non-FreeBSD */
return 1;
#endif
diff --git a/bsd-core/mga_drv.c b/bsd-core/mga_drv.c
index bff8c42f..1dd4c81b 100644
--- a/bsd-core/mga_drv.c
+++ b/bsd-core/mga_drv.c
@@ -37,11 +37,14 @@
#include "mga_drv.h"
#include "drm_pciids.h"
+int mga_driver_device_is_agp(drm_device_t * dev)
/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
static drm_pci_id_list_t mga_pciidlist[] = {
mga_PCI_IDS
};
+static int mga_driver_device_is_agp(drm_device_t * dev);
+
extern drm_ioctl_desc_t mga_ioctls[];
extern int mga_max_ioctl;
@@ -58,6 +61,8 @@ static void mga_configure(drm_device_t *dev)
dev->dma_ioctl = mga_dma_buffers;
dev->dma_quiescent = mga_driver_dma_quiescent;
+ dev->device_is_agp = mga_driver_device_is_agp;
+
dev->driver_ioctls = mga_ioctls;
dev->max_driver_ioctl = mga_max_ioctl;
@@ -76,6 +81,28 @@ static void mga_configure(drm_device_t *dev)
dev->use_vbl_irq = 1;
}
+/**
+ * Determine if the device really is AGP or not.
+ *
+ * In addition to the usual tests performed by \c drm_device_is_agp, this
+ * function detects PCI G450 cards that appear to the system exactly like
+ * AGP G450 cards.
+ *
+ * \param dev The device to be tested.
+ *
+ * \returns
+ * If the device is a PCI G450, zero is returned. Otherwise non-zero is
+ * returned.
+ *
+ * \bug
+ * This function needs to be filled in! The implementation in
+ * linux-core/mga_drv.c shows what needs to be done.
+ */
+int mga_driver_device_is_agp(drm_device_t * dev)
+{
+ return 1;
+}
+
#ifdef __FreeBSD__
static int
mga_probe(device_t dev)
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index b7f4640f..167bef0f 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -541,6 +541,18 @@ struct drm_driver {
int new);
int (*kernel_context_switch_unlock) (struct drm_device * dev);
int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence);
+
+ /**
+ * Called by \c drm_device_is_agp. Typically used to determine if a
+ * card is really attached to AGP or not.
+ *
+ * \param dev DRM device handle
+ *
+ * \returns true if the card really is attached to AGP, false
+ * otherwise.
+ */
+ int (*device_is_agp) (struct drm_device * dev);
+
/* these have to be filled in */
int (*postinit) (struct drm_device *, unsigned long flags);
irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
@@ -1016,6 +1028,11 @@ static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev,
static __inline__ int drm_device_is_agp(drm_device_t *dev)
{
+ if ( (dev->driver->device_is_agp != NULL)
+ && ! (*dev->driver->device_is_agp)( dev ) ) {
+ return 0;
+ }
+
return pci_find_capability(dev->pdev, PCI_CAP_ID_AGP);
}
diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c
index a3cc5667..338996d6 100644
--- a/linux-core/drm_stub.c
+++ b/linux-core/drm_stub.c
@@ -99,7 +99,8 @@ static int fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
goto error_out_unreg;
if (drm_core_has_AGP(dev)) {
- dev->agp = drm_agp_init(dev);
+ if (drm_device_is_agp(dev))
+ dev->agp = drm_agp_init(dev);
if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP)
&& (dev->agp == NULL)) {
DRM_ERROR("Cannot initialize the agpgart module.\n");
diff --git a/linux-core/mga_drv.c b/linux-core/mga_drv.c
index bdb591ee..e0f1ab31 100644
--- a/linux-core/mga_drv.c
+++ b/linux-core/mga_drv.c
@@ -37,6 +37,7 @@
#include "drm_pciids.h"
+static int mga_driver_device_is_agp(drm_device_t * dev);
static int postinit(struct drm_device *dev, unsigned long flags)
{
dev->counters += 3;
@@ -82,6 +83,7 @@ static struct drm_driver driver = {
DRIVER_IRQ_VBL,
.pretakedown = mga_driver_pretakedown,
.dma_quiescent = mga_driver_dma_quiescent,
+ .device_is_agp = mga_driver_device_is_agp,
.vblank_wait = mga_driver_vblank_wait,
.irq_preinstall = mga_driver_irq_preinstall,
.irq_postinstall = mga_driver_irq_postinstall,
@@ -134,3 +136,44 @@ module_exit(mga_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL and additional rights");
+
+/**
+ * Determine if the device really is AGP or not.
+ *
+ * In addition to the usual tests performed by \c drm_device_is_agp, this
+ * function detects PCI G450 cards that appear to the system exactly like
+ * AGP G450 cards.
+ *
+ * \param dev The device to be tested.
+ *
+ * \returns
+ * If the device is a PCI G450, zero is returned. Otherwise non-zero is
+ * returned.
+ */
+int mga_driver_device_is_agp(drm_device_t * dev)
+{
+ const struct pci_dev * const pdev = dev->pdev;
+
+
+ /* There are PCI versions of the G450. These cards have the
+ * same PCI ID as the AGP G450, but have an additional PCI-to-PCI
+ * bridge chip. We detect these cards, which are not currently
+ * supported by this driver, by looking at the device ID of the
+ * bus the "card" is on. If vendor is 0x3388 (Hint Corp) and the
+ * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the
+ * device.
+ */
+
+ if ( (pdev->device == 0x0525)
+ && (pdev->bus->self->vendor == 0x3388)
+ && (pdev->bus->self->device == 0x0021) ) {
+#if defined( __powerpc__ )
+ DRM_ERROR("GXT135p is not yet supported\n");
+#else
+ DRM_ERROR("PCI G450 is not yet supported\n");
+#endif
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/shared-core/mga_drv.h b/shared-core/mga_drv.h
index 55d3f85c..f1c3cf3e 100644
--- a/shared-core/mga_drv.h
+++ b/shared-core/mga_drv.h
@@ -38,11 +38,11 @@
#define DRIVER_NAME "mga"
#define DRIVER_DESC "Matrox G200/G400"
-#define DRIVER_DATE "20021029"
+#define DRIVER_DATE "20051013"
#define DRIVER_MAJOR 3
#define DRIVER_MINOR 1
-#define DRIVER_PATCHLEVEL 0
+#define DRIVER_PATCHLEVEL 1
typedef struct drm_mga_primary_buffer {
u8 *start;