aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_dma.c
diff options
context:
space:
mode:
authorZhenyu Wang <zhenyuw@linux.intel.com>2009-12-17 01:48:43 -0500
committerEric Anholt <eric@anholt.net>2010-02-16 14:48:43 -0500
commitc4804411691bdd7d8a57e942cbb502fd52a90074 (patch)
tree531ffc5769370909b692336e32c51c44f04a6cbd /drivers/gpu/drm/i915/i915_dma.c
parent29105ccc43ead5a0179d04b1404611981e92e278 (diff)
drm/i915: Keep MCHBAR always enabled
As we need more and more controls within MCHBAR for memory config and power management, this trys to keep MCHBAR enabled from driver load and only tear down in driver unload. Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com> Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_dma.c')
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 2307f98349f7..3afe361ec552 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -35,6 +35,8 @@
35#include "i915_drv.h" 35#include "i915_drv.h"
36#include "i915_trace.h" 36#include "i915_trace.h"
37#include <linux/vgaarb.h> 37#include <linux/vgaarb.h>
38#include <linux/acpi.h>
39#include <linux/pnp.h>
38 40
39/* Really want an OS-independent resettable timer. Would like to have 41/* Really want an OS-independent resettable timer. Would like to have
40 * this loop run for (eg) 3 sec, but have the timer reset every time 42 * 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)
933 return 0; 935 return 0;
934} 936}
935 937
938#define MCHBAR_I915 0x44
939#define MCHBAR_I965 0x48
940#define MCHBAR_SIZE (4*4096)
941
942#define DEVEN_REG 0x54
943#define DEVEN_MCHBAR_EN (1 << 28)
944
945/* Allocate space for the MCH regs if needed, return nonzero on error */
946static int
947intel_alloc_mchbar_resource(struct drm_device *dev)
948{
949 drm_i915_private_t *dev_priv = dev->dev_private;
950 int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
951 u32 temp_lo, temp_hi = 0;
952 u64 mchbar_addr;
953 int ret = 0;
954
955 if (IS_I965G(dev))
956 pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi);
957 pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo);
958 mchbar_addr = ((u64)temp_hi << 32) | temp_lo;
959
960 /* If ACPI doesn't have it, assume we need to allocate it ourselves */
961#ifdef CONFIG_PNP
962 if (mchbar_addr &&
963 pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) {
964 ret = 0;
965 goto out;
966 }
967#endif
968
969 /* Get some space for it */
970 ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, &dev_priv->mch_res,
971 MCHBAR_SIZE, MCHBAR_SIZE,
972 PCIBIOS_MIN_MEM,
973 0, pcibios_align_resource,
974 dev_priv->bridge_dev);
975 if (ret) {
976 DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret);
977 dev_priv->mch_res.start = 0;
978 goto out;
979 }
980
981 if (IS_I965G(dev))
982 pci_write_config_dword(dev_priv->bridge_dev, reg + 4,
983 upper_32_bits(dev_priv->mch_res.start));
984
985 pci_write_config_dword(dev_priv->bridge_dev, reg,
986 lower_32_bits(dev_priv->mch_res.start));
987out:
988 return ret;
989}
990
991/* Setup MCHBAR if possible, return true if we should disable it again */
992static void
993intel_setup_mchbar(struct drm_device *dev)
994{
995 drm_i915_private_t *dev_priv = dev->dev_private;
996 int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
997 u32 temp;
998 bool enabled;
999
1000 dev_priv->mchbar_need_disable = false;
1001
1002 if (IS_I915G(dev) || IS_I915GM(dev)) {
1003 pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp);
1004 enabled = !!(temp & DEVEN_MCHBAR_EN);
1005 } else {
1006 pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
1007 enabled = temp & 1;
1008 }
1009
1010 /* If it's already enabled, don't have to do anything */
1011 if (enabled)
1012 return;
1013
1014 if (intel_alloc_mchbar_resource(dev))
1015 return;
1016
1017 dev_priv->mchbar_need_disable = true;
1018
1019 /* Space is allocated or reserved, so enable it. */
1020 if (IS_I915G(dev) || IS_I915GM(dev)) {
1021 pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG,
1022 temp | DEVEN_MCHBAR_EN);
1023 } else {
1024 pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
1025 pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1);
1026 }
1027}
1028
1029static void
1030intel_teardown_mchbar(struct drm_device *dev)
1031{
1032 drm_i915_private_t *dev_priv = dev->dev_private;
1033 int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
1034 u32 temp;
1035
1036 if (dev_priv->mchbar_need_disable) {
1037 if (IS_I915G(dev) || IS_I915GM(dev)) {
1038 pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp);
1039 temp &= ~DEVEN_MCHBAR_EN;
1040 pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, temp);
1041 } else {
1042 pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
1043 temp &= ~1;
1044 pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp);
1045 }
1046 }
1047
1048 if (dev_priv->mch_res.start)
1049 release_resource(&dev_priv->mch_res);
1050}
1051
936/** 1052/**
937 * i915_probe_agp - get AGP bootup configuration 1053 * i915_probe_agp - get AGP bootup configuration
938 * @pdev: PCI device 1054 * @pdev: PCI device
@@ -1450,6 +1566,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1450 dev->driver->get_vblank_counter = gm45_get_vblank_counter; 1566 dev->driver->get_vblank_counter = gm45_get_vblank_counter;
1451 } 1567 }
1452 1568
1569 /* Try to make sure MCHBAR is enabled before poking at it */
1570 intel_setup_mchbar(dev);
1571
1453 i915_gem_load(dev); 1572 i915_gem_load(dev);
1454 1573
1455 /* Init HWS */ 1574 /* Init HWS */
@@ -1569,6 +1688,8 @@ int i915_driver_unload(struct drm_device *dev)
1569 intel_cleanup_overlay(dev); 1688 intel_cleanup_overlay(dev);
1570 } 1689 }
1571 1690
1691 intel_teardown_mchbar(dev);
1692
1572 pci_dev_put(dev_priv->bridge_dev); 1693 pci_dev_put(dev_priv->bridge_dev);
1573 kfree(dev->dev_private); 1694 kfree(dev->dev_private);
1574 1695