From 21d63d685e687735653b1a3f67445c9aba5cb025 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Thu, 17 Dec 2009 14:48:43 +0800 Subject: [PATCH] --- yaml --- r: 185525 b: refs/heads/master c: c4804411691bdd7d8a57e942cbb502fd52a90074 h: refs/heads/master i: 185523: a7da18fd0212af4265238a11d0a4abfcc8a465b3 v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/i915/i915_dma.c | 121 ++++++++++++++++++ trunk/drivers/gpu/drm/i915/i915_drv.h | 1 + trunk/drivers/gpu/drm/i915/i915_gem_tiling.c | 122 ------------------- 4 files changed, 123 insertions(+), 123 deletions(-) diff --git a/[refs] b/[refs] index 86f023c31f19..5528de0e34e6 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 29105ccc43ead5a0179d04b1404611981e92e278 +refs/heads/master: c4804411691bdd7d8a57e942cbb502fd52a90074 diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index 2307f98349f7..3afe361ec552 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -35,6 +35,8 @@ #include "i915_drv.h" #include "i915_trace.h" #include +#include +#include /* Really want an OS-independent resettable timer. Would like to have * this loop run for (eg) 3 sec, but have the timer reset every time @@ -933,6 +935,120 @@ static int i915_get_bridge_dev(struct drm_device *dev) return 0; } +#define MCHBAR_I915 0x44 +#define MCHBAR_I965 0x48 +#define MCHBAR_SIZE (4*4096) + +#define DEVEN_REG 0x54 +#define DEVEN_MCHBAR_EN (1 << 28) + +/* Allocate space for the MCH regs if needed, return nonzero on error */ +static int +intel_alloc_mchbar_resource(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; + u32 temp_lo, temp_hi = 0; + u64 mchbar_addr; + int ret = 0; + + if (IS_I965G(dev)) + pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi); + pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo); + mchbar_addr = ((u64)temp_hi << 32) | temp_lo; + + /* If ACPI doesn't have it, assume we need to allocate it ourselves */ +#ifdef CONFIG_PNP + if (mchbar_addr && + pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) { + ret = 0; + goto out; + } +#endif + + /* Get some space for it */ + ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, &dev_priv->mch_res, + MCHBAR_SIZE, MCHBAR_SIZE, + PCIBIOS_MIN_MEM, + 0, pcibios_align_resource, + dev_priv->bridge_dev); + if (ret) { + DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret); + dev_priv->mch_res.start = 0; + goto out; + } + + if (IS_I965G(dev)) + pci_write_config_dword(dev_priv->bridge_dev, reg + 4, + upper_32_bits(dev_priv->mch_res.start)); + + pci_write_config_dword(dev_priv->bridge_dev, reg, + lower_32_bits(dev_priv->mch_res.start)); +out: + return ret; +} + +/* Setup MCHBAR if possible, return true if we should disable it again */ +static void +intel_setup_mchbar(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; + u32 temp; + bool enabled; + + dev_priv->mchbar_need_disable = false; + + if (IS_I915G(dev) || IS_I915GM(dev)) { + pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp); + enabled = !!(temp & DEVEN_MCHBAR_EN); + } else { + pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); + enabled = temp & 1; + } + + /* If it's already enabled, don't have to do anything */ + if (enabled) + return; + + if (intel_alloc_mchbar_resource(dev)) + return; + + dev_priv->mchbar_need_disable = true; + + /* Space is allocated or reserved, so enable it. */ + if (IS_I915G(dev) || IS_I915GM(dev)) { + pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, + temp | DEVEN_MCHBAR_EN); + } else { + pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); + pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1); + } +} + +static void +intel_teardown_mchbar(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; + u32 temp; + + if (dev_priv->mchbar_need_disable) { + if (IS_I915G(dev) || IS_I915GM(dev)) { + pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp); + temp &= ~DEVEN_MCHBAR_EN; + pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, temp); + } else { + pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); + temp &= ~1; + pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp); + } + } + + if (dev_priv->mch_res.start) + release_resource(&dev_priv->mch_res); +} + /** * i915_probe_agp - get AGP bootup configuration * @pdev: PCI device @@ -1450,6 +1566,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev->driver->get_vblank_counter = gm45_get_vblank_counter; } + /* Try to make sure MCHBAR is enabled before poking at it */ + intel_setup_mchbar(dev); + i915_gem_load(dev); /* Init HWS */ @@ -1569,6 +1688,8 @@ int i915_driver_unload(struct drm_device *dev) intel_cleanup_overlay(dev); } + intel_teardown_mchbar(dev); + pci_dev_put(dev_priv->bridge_dev); kfree(dev->dev_private); diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index b99b6a841d95..f2742d6d3f54 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -590,6 +590,7 @@ typedef struct drm_i915_private { int child_dev_num; struct child_device_config *child_dev; struct drm_connector *int_lvds_connector; + bool mchbar_need_disable; } drm_i915_private_t; /** driver private structure attached to each drm_gem_object */ diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c b/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c index df278b2685bf..f308fdf43725 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -25,8 +25,6 @@ * */ -#include -#include #include "linux/string.h" #include "linux/bitops.h" #include "drmP.h" @@ -83,120 +81,6 @@ * to match what the GPU expects. */ -#define MCHBAR_I915 0x44 -#define MCHBAR_I965 0x48 -#define MCHBAR_SIZE (4*4096) - -#define DEVEN_REG 0x54 -#define DEVEN_MCHBAR_EN (1 << 28) - -/* Allocate space for the MCH regs if needed, return nonzero on error */ -static int -intel_alloc_mchbar_resource(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; - u32 temp_lo, temp_hi = 0; - u64 mchbar_addr; - int ret = 0; - - if (IS_I965G(dev)) - pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi); - pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo); - mchbar_addr = ((u64)temp_hi << 32) | temp_lo; - - /* If ACPI doesn't have it, assume we need to allocate it ourselves */ -#ifdef CONFIG_PNP - if (mchbar_addr && - pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) { - ret = 0; - goto out; - } -#endif - - /* Get some space for it */ - ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, &dev_priv->mch_res, - MCHBAR_SIZE, MCHBAR_SIZE, - PCIBIOS_MIN_MEM, - 0, pcibios_align_resource, - dev_priv->bridge_dev); - if (ret) { - DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret); - dev_priv->mch_res.start = 0; - goto out; - } - - if (IS_I965G(dev)) - pci_write_config_dword(dev_priv->bridge_dev, reg + 4, - upper_32_bits(dev_priv->mch_res.start)); - - pci_write_config_dword(dev_priv->bridge_dev, reg, - lower_32_bits(dev_priv->mch_res.start)); -out: - return ret; -} - -/* Setup MCHBAR if possible, return true if we should disable it again */ -static bool -intel_setup_mchbar(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; - u32 temp; - bool need_disable = false, enabled; - - if (IS_I915G(dev) || IS_I915GM(dev)) { - pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp); - enabled = !!(temp & DEVEN_MCHBAR_EN); - } else { - pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); - enabled = temp & 1; - } - - /* If it's already enabled, don't have to do anything */ - if (enabled) - goto out; - - if (intel_alloc_mchbar_resource(dev)) - goto out; - - need_disable = true; - - /* Space is allocated or reserved, so enable it. */ - if (IS_I915G(dev) || IS_I915GM(dev)) { - pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, - temp | DEVEN_MCHBAR_EN); - } else { - pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); - pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1); - } -out: - return need_disable; -} - -static void -intel_teardown_mchbar(struct drm_device *dev, bool disable) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; - u32 temp; - - if (disable) { - if (IS_I915G(dev) || IS_I915GM(dev)) { - pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp); - temp &= ~DEVEN_MCHBAR_EN; - pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, temp); - } else { - pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); - temp &= ~1; - pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp); - } - } - - if (dev_priv->mch_res.start) - release_resource(&dev_priv->mch_res); -} - /** * Detects bit 6 swizzling of address lookup between IGD access and CPU * access through main memory. @@ -207,7 +91,6 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; - bool need_disable; if (IS_IRONLAKE(dev)) { /* On Ironlake whatever DRAM config, GPU always do @@ -224,9 +107,6 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) } else if (IS_MOBILE(dev)) { uint32_t dcc; - /* Try to make sure MCHBAR is enabled before poking at it */ - need_disable = intel_setup_mchbar(dev); - /* On mobile 9xx chipsets, channel interleave by the CPU is * determined by DCC. For single-channel, neither the CPU * nor the GPU do swizzling. For dual channel interleaved, @@ -266,8 +146,6 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; } - - intel_teardown_mchbar(dev, need_disable); } else { /* The 965, G33, and newer, have a very flexible memory * configuration. It will enable dual-channel mode