Skip to content

Commit

Permalink
drm/i915: Disable GEM when a broken video BIOS takes up the whole ape…
Browse files Browse the repository at this point in the history
…rture.

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>
  • Loading branch information
Eric Anholt committed Jul 10, 2009
1 parent e99da35 commit 2a34f5e
Showing 1 changed file with 20 additions and 9 deletions.
29 changes: 20 additions & 9 deletions drivers/gpu/drm/i915/i915_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -885,8 +885,8 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
* some RAM for the framebuffer at early boot. This code figures out
* how much was set aside so we can use it for our own purposes.
*/
static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size,
unsigned long *preallocated_size)
static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size,
uint32_t *preallocated_size)
{
struct pci_dev *bridge_dev;
u16 tmp = 0;
Expand Down Expand Up @@ -984,10 +984,11 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size,
return 0;
}

static int i915_load_modeset_init(struct drm_device *dev)
static int i915_load_modeset_init(struct drm_device *dev,
unsigned long prealloc_size,
unsigned long agp_size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long agp_size, prealloc_size;
int fb_bar = IS_I9XX(dev) ? 2 : 0;
int ret = 0;

Expand All @@ -1002,10 +1003,6 @@ static int i915_load_modeset_init(struct drm_device *dev)
if (IS_I965G(dev) || IS_G33(dev))
dev_priv->cursor_needs_physical = false;

ret = i915_probe_agp(dev, &agp_size, &prealloc_size);
if (ret)
goto out;

/* Basic memrange allocator for stolen space (aka vram) */
drm_mm_init(&dev_priv->vram, 0, prealloc_size);

Expand Down Expand Up @@ -1136,6 +1133,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
struct drm_i915_private *dev_priv = dev->dev_private;
resource_size_t base, size;
int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1;
uint32_t agp_size, prealloc_size;

/* i915 has 4 more counters */
dev->counters += 4;
Expand Down Expand Up @@ -1184,9 +1182,22 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
"performance may suffer.\n");
}

ret = i915_probe_agp(dev, &agp_size, &prealloc_size);
if (ret)
goto out_iomapfree;

/* enable GEM by default */
dev_priv->has_gem = 1;

if (prealloc_size > agp_size * 3 / 4) {
DRM_ERROR("Detected broken video BIOS with %d/%dkB of video "
"memory stolen.\n",
prealloc_size / 1024, agp_size / 1024);
DRM_ERROR("Disabling GEM. (try reducing stolen memory or "
"updating the BIOS to fix).\n");
dev_priv->has_gem = 0;
}

dev->driver->get_vblank_counter = i915_get_vblank_counter;
dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
if (IS_G4X(dev) || IS_IGDNG(dev)) {
Expand Down Expand Up @@ -1231,7 +1242,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
}

if (drm_core_check_feature(dev, DRIVER_MODESET)) {
ret = i915_load_modeset_init(dev);
ret = i915_load_modeset_init(dev, prealloc_size, agp_size);
if (ret < 0) {
DRM_ERROR("failed to init modeset\n");
goto out_rmmap;
Expand Down

0 comments on commit 2a34f5e

Please sign in to comment.