aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@starflyer.(none)>2005-07-10 03:31:26 -0400
committerDave Airlie <airlied@linux.ie>2005-07-10 03:31:26 -0400
commitcda173806644d2af22ffd9896eed8ef99b97d356 (patch)
tree374ad48818df951a03c59d54ec75d5b19d4a24c3
parentceb9c27aa7d61c70f4c75f017d9fbc9de50034f1 (diff)
drm: add test for AGP devices and driver override for it.
Added device_is_agp callback to drm_driver. This function is called by the platform-specific drm_device_is_agp function. Added implementation of this function the the Linux-specific portion of the MGA driver to detect PCI G450 cards. Added code to the Linux-specific portion of the generic DRM layer to not initialize AGP infrastructure if the card is not AGP (this matches what already existed in BSD). Fix up i810/i830 and i915 drivers to always return AGP as they don't always report the capability. Fix the MGA to not report AGP for a card that has an AGP chip behind a PCI bridge. From: Ian Romanick, Dave Airlie, Alan Hourihane Signed-off-by: Dave Airlie <airlied@linux.ie>
-rw-r--r--drivers/char/drm/drmP.h28
-rw-r--r--drivers/char/drm/drm_stub.c3
-rw-r--r--drivers/char/drm/i810_dma.c16
-rw-r--r--drivers/char/drm/i810_drv.c1
-rw-r--r--drivers/char/drm/i810_drv.h1
-rw-r--r--drivers/char/drm/i830_dma.c16
-rw-r--r--drivers/char/drm/i830_drv.c1
-rw-r--r--drivers/char/drm/i830_drv.h1
-rw-r--r--drivers/char/drm/i915_dma.c16
-rw-r--r--drivers/char/drm/i915_drv.c1
-rw-r--r--drivers/char/drm/i915_drv.h1
-rw-r--r--drivers/char/drm/mga_drv.c37
-rw-r--r--drivers/char/drm/mga_drv.h4
13 files changed, 123 insertions, 3 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 8e060a2cc3db..a9b61864feba 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -586,7 +586,22 @@ struct drm_driver {
586 int (*kernel_context_switch)(struct drm_device *dev, int old, int new); 586 int (*kernel_context_switch)(struct drm_device *dev, int old, int new);
587 void (*kernel_context_switch_unlock)(struct drm_device *dev, drm_lock_t *lock); 587 void (*kernel_context_switch_unlock)(struct drm_device *dev, drm_lock_t *lock);
588 int (*vblank_wait)(struct drm_device *dev, unsigned int *sequence); 588 int (*vblank_wait)(struct drm_device *dev, unsigned int *sequence);
589
590 /**
591 * Called by \c drm_device_is_agp. Typically used to determine if a
592 * card is really attached to AGP or not.
593 *
594 * \param dev DRM device handle
595 *
596 * \returns
597 * One of three values is returned depending on whether or not the
598 * card is absolutely \b not AGP (return of 0), absolutely \b is AGP
599 * (return of 1), or may or may not be AGP (return of 2).
600 */
601 int (*device_is_agp) (struct drm_device * dev);
602
589 /* these have to be filled in */ 603 /* these have to be filled in */
604
590 int (*postinit)(struct drm_device *, unsigned long flags); 605 int (*postinit)(struct drm_device *, unsigned long flags);
591 irqreturn_t (*irq_handler)( DRM_IRQ_ARGS ); 606 irqreturn_t (*irq_handler)( DRM_IRQ_ARGS );
592 void (*irq_preinstall)(struct drm_device *dev); 607 void (*irq_preinstall)(struct drm_device *dev);
@@ -1041,6 +1056,19 @@ static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsig
1041 return NULL; 1056 return NULL;
1042} 1057}
1043 1058
1059static __inline__ int drm_device_is_agp(drm_device_t *dev)
1060{
1061 if ( dev->driver->device_is_agp != NULL ) {
1062 int err = (*dev->driver->device_is_agp)( dev );
1063
1064 if (err != 2) {
1065 return err;
1066 }
1067 }
1068
1069 return pci_find_capability(dev->pdev, PCI_CAP_ID_AGP);
1070}
1071
1044static __inline__ void drm_core_dropmap(struct drm_map *map) 1072static __inline__ void drm_core_dropmap(struct drm_map *map)
1045{ 1073{
1046} 1074}
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index 48829a1a086a..068ca9a8b0b4 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -91,7 +91,8 @@ static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct
91 goto error_out_unreg; 91 goto error_out_unreg;
92 92
93 if (drm_core_has_AGP(dev)) { 93 if (drm_core_has_AGP(dev)) {
94 dev->agp = drm_agp_init(dev); 94 if (drm_device_is_agp(dev))
95 dev->agp = drm_agp_init(dev);
95 if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) { 96 if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) {
96 DRM_ERROR( "Cannot initialize the agpgart module.\n" ); 97 DRM_ERROR( "Cannot initialize the agpgart module.\n" );
97 retcode = -EINVAL; 98 retcode = -EINVAL;
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
index 18e0b7622893..0a9ac1f2e215 100644
--- a/drivers/char/drm/i810_dma.c
+++ b/drivers/char/drm/i810_dma.c
@@ -1383,3 +1383,19 @@ drm_ioctl_desc_t i810_ioctls[] = {
1383}; 1383};
1384 1384
1385int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); 1385int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls);
1386
1387/**
1388 * Determine if the device really is AGP or not.
1389 *
1390 * All Intel graphics chipsets are treated as AGP, even if they are really
1391 * PCI-e.
1392 *
1393 * \param dev The device to be tested.
1394 *
1395 * \returns
1396 * A value of 1 is always retured to indictate every i810 is AGP.
1397 */
1398int i810_driver_device_is_agp(drm_device_t * dev)
1399{
1400 return 1;
1401}
diff --git a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c
index ff51b3259af9..00609329d578 100644
--- a/drivers/char/drm/i810_drv.c
+++ b/drivers/char/drm/i810_drv.c
@@ -84,6 +84,7 @@ static struct drm_driver driver = {
84 .dev_priv_size = sizeof(drm_i810_buf_priv_t), 84 .dev_priv_size = sizeof(drm_i810_buf_priv_t),
85 .pretakedown = i810_driver_pretakedown, 85 .pretakedown = i810_driver_pretakedown,
86 .prerelease = i810_driver_prerelease, 86 .prerelease = i810_driver_prerelease,
87 .device_is_agp = i810_driver_device_is_agp,
87 .release = i810_driver_release, 88 .release = i810_driver_release,
88 .dma_quiescent = i810_driver_dma_quiescent, 89 .dma_quiescent = i810_driver_dma_quiescent,
89 .reclaim_buffers = i810_reclaim_buffers, 90 .reclaim_buffers = i810_reclaim_buffers,
diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h
index 1b40538d1725..62ee4f58c59a 100644
--- a/drivers/char/drm/i810_drv.h
+++ b/drivers/char/drm/i810_drv.h
@@ -120,6 +120,7 @@ extern int i810_driver_dma_quiescent(drm_device_t *dev);
120extern void i810_driver_release(drm_device_t *dev, struct file *filp); 120extern void i810_driver_release(drm_device_t *dev, struct file *filp);
121extern void i810_driver_pretakedown(drm_device_t *dev); 121extern void i810_driver_pretakedown(drm_device_t *dev);
122extern void i810_driver_prerelease(drm_device_t *dev, DRMFILE filp); 122extern void i810_driver_prerelease(drm_device_t *dev, DRMFILE filp);
123extern int i810_driver_device_is_agp(drm_device_t * dev);
123 124
124#define I810_BASE(reg) ((unsigned long) \ 125#define I810_BASE(reg) ((unsigned long) \
125 dev_priv->mmio_map->handle) 126 dev_priv->mmio_map->handle)
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
index dc7733035864..80d8966397c1 100644
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -1586,3 +1586,19 @@ drm_ioctl_desc_t i830_ioctls[] = {
1586}; 1586};
1587 1587
1588int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); 1588int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls);
1589
1590/**
1591 * Determine if the device really is AGP or not.
1592 *
1593 * All Intel graphics chipsets are treated as AGP, even if they are really
1594 * PCI-e.
1595 *
1596 * \param dev The device to be tested.
1597 *
1598 * \returns
1599 * A value of 1 is always retured to indictate every i8xx is AGP.
1600 */
1601int i830_driver_device_is_agp(drm_device_t * dev)
1602{
1603 return 1;
1604}
diff --git a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c
index bc36be76b8b2..0da9cd19919e 100644
--- a/drivers/char/drm/i830_drv.c
+++ b/drivers/char/drm/i830_drv.c
@@ -88,6 +88,7 @@ static struct drm_driver driver = {
88 .dev_priv_size = sizeof(drm_i830_buf_priv_t), 88 .dev_priv_size = sizeof(drm_i830_buf_priv_t),
89 .pretakedown = i830_driver_pretakedown, 89 .pretakedown = i830_driver_pretakedown,
90 .prerelease = i830_driver_prerelease, 90 .prerelease = i830_driver_prerelease,
91 .device_is_agp = i830_driver_device_is_agp,
91 .release = i830_driver_release, 92 .release = i830_driver_release,
92 .dma_quiescent = i830_driver_dma_quiescent, 93 .dma_quiescent = i830_driver_dma_quiescent,
93 .reclaim_buffers = i830_reclaim_buffers, 94 .reclaim_buffers = i830_reclaim_buffers,
diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h
index df7746131dea..63f96a8b6a4a 100644
--- a/drivers/char/drm/i830_drv.h
+++ b/drivers/char/drm/i830_drv.h
@@ -137,6 +137,7 @@ extern void i830_driver_pretakedown(drm_device_t *dev);
137extern void i830_driver_release(drm_device_t *dev, struct file *filp); 137extern void i830_driver_release(drm_device_t *dev, struct file *filp);
138extern int i830_driver_dma_quiescent(drm_device_t *dev); 138extern int i830_driver_dma_quiescent(drm_device_t *dev);
139extern void i830_driver_prerelease(drm_device_t *dev, DRMFILE filp); 139extern void i830_driver_prerelease(drm_device_t *dev, DRMFILE filp);
140extern int i830_driver_device_is_agp(drm_device_t * dev);
140 141
141#define I830_BASE(reg) ((unsigned long) \ 142#define I830_BASE(reg) ((unsigned long) \
142 dev_priv->mmio_map->handle) 143 dev_priv->mmio_map->handle)
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index 759f22943eb1..34f552f90c4a 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -732,3 +732,19 @@ drm_ioctl_desc_t i915_ioctls[] = {
732}; 732};
733 733
734int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); 734int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
735
736/**
737 * Determine if the device really is AGP or not.
738 *
739 * All Intel graphics chipsets are treated as AGP, even if they are really
740 * PCI-e.
741 *
742 * \param dev The device to be tested.
743 *
744 * \returns
745 * A value of 1 is always retured to indictate every i9x5 is AGP.
746 */
747int i915_driver_device_is_agp(drm_device_t * dev)
748{
749 return 1;
750}
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
index 1f59d3fc79bc..106b9ec02213 100644
--- a/drivers/char/drm/i915_drv.c
+++ b/drivers/char/drm/i915_drv.c
@@ -79,6 +79,7 @@ static struct drm_driver driver = {
79 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, 79 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
80 .pretakedown = i915_driver_pretakedown, 80 .pretakedown = i915_driver_pretakedown,
81 .prerelease = i915_driver_prerelease, 81 .prerelease = i915_driver_prerelease,
82 .device_is_agp = i915_driver_device_is_agp,
82 .irq_preinstall = i915_driver_irq_preinstall, 83 .irq_preinstall = i915_driver_irq_preinstall,
83 .irq_postinstall = i915_driver_irq_postinstall, 84 .irq_postinstall = i915_driver_irq_postinstall,
84 .irq_uninstall = i915_driver_irq_uninstall, 85 .irq_uninstall = i915_driver_irq_uninstall,
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index 93080868d18f..70ed4e68eac8 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -103,6 +103,7 @@ typedef struct drm_i915_private {
103extern void i915_kernel_lost_context(drm_device_t * dev); 103extern void i915_kernel_lost_context(drm_device_t * dev);
104extern void i915_driver_pretakedown(drm_device_t *dev); 104extern void i915_driver_pretakedown(drm_device_t *dev);
105extern void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp); 105extern void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp);
106extern int i915_driver_device_is_agp(drm_device_t *dev);
106 107
107/* i915_irq.c */ 108/* i915_irq.c */
108extern int i915_irq_emit(DRM_IOCTL_ARGS); 109extern int i915_irq_emit(DRM_IOCTL_ARGS);
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
index 844cca9cb29d..94af13bc66a4 100644
--- a/drivers/char/drm/mga_drv.c
+++ b/drivers/char/drm/mga_drv.c
@@ -38,6 +38,7 @@
38 38
39#include "drm_pciids.h" 39#include "drm_pciids.h"
40 40
41static int mga_driver_device_is_agp(drm_device_t * dev);
41static int postinit( struct drm_device *dev, unsigned long flags ) 42static int postinit( struct drm_device *dev, unsigned long flags )
42{ 43{
43 dev->counters += 3; 44 dev->counters += 3;
@@ -81,6 +82,7 @@ static struct drm_driver driver = {
81 .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, 82 .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
82 .pretakedown = mga_driver_pretakedown, 83 .pretakedown = mga_driver_pretakedown,
83 .dma_quiescent = mga_driver_dma_quiescent, 84 .dma_quiescent = mga_driver_dma_quiescent,
85 .device_is_agp = mga_driver_device_is_agp,
84 .vblank_wait = mga_driver_vblank_wait, 86 .vblank_wait = mga_driver_vblank_wait,
85 .irq_preinstall = mga_driver_irq_preinstall, 87 .irq_preinstall = mga_driver_irq_preinstall,
86 .irq_postinstall = mga_driver_irq_postinstall, 88 .irq_postinstall = mga_driver_irq_postinstall,
@@ -128,3 +130,38 @@ module_exit(mga_exit);
128MODULE_AUTHOR( DRIVER_AUTHOR ); 130MODULE_AUTHOR( DRIVER_AUTHOR );
129MODULE_DESCRIPTION( DRIVER_DESC ); 131MODULE_DESCRIPTION( DRIVER_DESC );
130MODULE_LICENSE("GPL and additional rights"); 132MODULE_LICENSE("GPL and additional rights");
133
134/**
135 * Determine if the device really is AGP or not.
136 *
137 * In addition to the usual tests performed by \c drm_device_is_agp, this
138 * function detects PCI G450 cards that appear to the system exactly like
139 * AGP G450 cards.
140 *
141 * \param dev The device to be tested.
142 *
143 * \returns
144 * If the device is a PCI G450, zero is returned. Otherwise 2 is returned.
145 */
146int mga_driver_device_is_agp(drm_device_t * dev)
147{
148 const struct pci_dev * const pdev = dev->pdev;
149
150
151 /* There are PCI versions of the G450. These cards have the
152 * same PCI ID as the AGP G450, but have an additional PCI-to-PCI
153 * bridge chip. We detect these cards, which are not currently
154 * supported by this driver, by looking at the device ID of the
155 * bus the "card" is on. If vendor is 0x3388 (Hint Corp) and the
156 * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the
157 * device.
158 */
159
160 if ( (pdev->device == 0x0525)
161 && (pdev->bus->self->vendor == 0x3388)
162 && (pdev->bus->self->device == 0x0021) ) {
163 return 0;
164 }
165
166 return 2;
167}
diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h
index 9412e2816eb7..38f913905e04 100644
--- a/drivers/char/drm/mga_drv.h
+++ b/drivers/char/drm/mga_drv.h
@@ -38,11 +38,11 @@
38 38
39#define DRIVER_NAME "mga" 39#define DRIVER_NAME "mga"
40#define DRIVER_DESC "Matrox G200/G400" 40#define DRIVER_DESC "Matrox G200/G400"
41#define DRIVER_DATE "20021029" 41#define DRIVER_DATE "20051013"
42 42
43#define DRIVER_MAJOR 3 43#define DRIVER_MAJOR 3
44#define DRIVER_MINOR 1 44#define DRIVER_MINOR 1
45#define DRIVER_PATCHLEVEL 0 45#define DRIVER_PATCHLEVEL 1
46 46
47typedef struct drm_mga_primary_buffer { 47typedef struct drm_mga_primary_buffer {
48 u8 *start; 48 u8 *start;