aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2009-07-02 12:30:50 -0400
committerEric Anholt <eric@anholt.net>2009-07-10 15:29:33 -0400
commit2a34f5e6b61c7e8f3b6f25847bcda88511b0ead4 (patch)
tree526c57a829dab840793897b88fcb7ea67085e8eb /drivers
parente99da35f060f9a3407f7def474a1df31f3b8643a (diff)
drm/i915: Disable GEM when a broken video BIOS takes up the whole aperture.
This is seen on some G41 systems, where the BIOS will consume all but a few KB of the aperture. This should be bad for all operating systems, as it means that the OS can't dynamically manage memory between graphics and the rest of the system, and OSes that did static memory management statically add memory in addition to the BIOS allocation anyway. So, instead of working around it, just fail out verbosely. fd.o bug #21574 Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 0e704bb26e99..8c4783180bf6 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -885,8 +885,8 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
885 * some RAM for the framebuffer at early boot. This code figures out 885 * some RAM for the framebuffer at early boot. This code figures out
886 * how much was set aside so we can use it for our own purposes. 886 * how much was set aside so we can use it for our own purposes.
887 */ 887 */
888static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size, 888static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size,
889 unsigned long *preallocated_size) 889 uint32_t *preallocated_size)
890{ 890{
891 struct pci_dev *bridge_dev; 891 struct pci_dev *bridge_dev;
892 u16 tmp = 0; 892 u16 tmp = 0;
@@ -984,10 +984,11 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size,
984 return 0; 984 return 0;
985} 985}
986 986
987static int i915_load_modeset_init(struct drm_device *dev) 987static int i915_load_modeset_init(struct drm_device *dev,
988 unsigned long prealloc_size,
989 unsigned long agp_size)
988{ 990{
989 struct drm_i915_private *dev_priv = dev->dev_private; 991 struct drm_i915_private *dev_priv = dev->dev_private;
990 unsigned long agp_size, prealloc_size;
991 int fb_bar = IS_I9XX(dev) ? 2 : 0; 992 int fb_bar = IS_I9XX(dev) ? 2 : 0;
992 int ret = 0; 993 int ret = 0;
993 994
@@ -1002,10 +1003,6 @@ static int i915_load_modeset_init(struct drm_device *dev)
1002 if (IS_I965G(dev) || IS_G33(dev)) 1003 if (IS_I965G(dev) || IS_G33(dev))
1003 dev_priv->cursor_needs_physical = false; 1004 dev_priv->cursor_needs_physical = false;
1004 1005
1005 ret = i915_probe_agp(dev, &agp_size, &prealloc_size);
1006 if (ret)
1007 goto out;
1008
1009 /* Basic memrange allocator for stolen space (aka vram) */ 1006 /* Basic memrange allocator for stolen space (aka vram) */
1010 drm_mm_init(&dev_priv->vram, 0, prealloc_size); 1007 drm_mm_init(&dev_priv->vram, 0, prealloc_size);
1011 1008
@@ -1136,6 +1133,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1136 struct drm_i915_private *dev_priv = dev->dev_private; 1133 struct drm_i915_private *dev_priv = dev->dev_private;
1137 resource_size_t base, size; 1134 resource_size_t base, size;
1138 int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; 1135 int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1;
1136 uint32_t agp_size, prealloc_size;
1139 1137
1140 /* i915 has 4 more counters */ 1138 /* i915 has 4 more counters */
1141 dev->counters += 4; 1139 dev->counters += 4;
@@ -1184,9 +1182,22 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1184 "performance may suffer.\n"); 1182 "performance may suffer.\n");
1185 } 1183 }
1186 1184
1185 ret = i915_probe_agp(dev, &agp_size, &prealloc_size);
1186 if (ret)
1187 goto out_iomapfree;
1188
1187 /* enable GEM by default */ 1189 /* enable GEM by default */
1188 dev_priv->has_gem = 1; 1190 dev_priv->has_gem = 1;
1189 1191
1192 if (prealloc_size > agp_size * 3 / 4) {
1193 DRM_ERROR("Detected broken video BIOS with %d/%dkB of video "
1194 "memory stolen.\n",
1195 prealloc_size / 1024, agp_size / 1024);
1196 DRM_ERROR("Disabling GEM. (try reducing stolen memory or "
1197 "updating the BIOS to fix).\n");
1198 dev_priv->has_gem = 0;
1199 }
1200
1190 dev->driver->get_vblank_counter = i915_get_vblank_counter; 1201 dev->driver->get_vblank_counter = i915_get_vblank_counter;
1191 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ 1202 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
1192 if (IS_G4X(dev) || IS_IGDNG(dev)) { 1203 if (IS_G4X(dev) || IS_IGDNG(dev)) {
@@ -1231,7 +1242,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1231 } 1242 }
1232 1243
1233 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 1244 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
1234 ret = i915_load_modeset_init(dev); 1245 ret = i915_load_modeset_init(dev, prealloc_size, agp_size);
1235 if (ret < 0) { 1246 if (ret < 0) {
1236 DRM_ERROR("failed to init modeset\n"); 1247 DRM_ERROR("failed to init modeset\n");
1237 goto out_rmmap; 1248 goto out_rmmap;