aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_dma.c')
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c72
1 files changed, 62 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index f112c769d53..8c4783180bf 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -846,7 +846,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
846 return 0; 846 return 0;
847 } 847 }
848 848
849 printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws->addr); 849 DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr);
850 850
851 dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); 851 dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12);
852 852
@@ -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
@@ -1082,6 +1079,44 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master)
1082 master->driver_priv = NULL; 1079 master->driver_priv = NULL;
1083} 1080}
1084 1081
1082static void i915_get_mem_freq(struct drm_device *dev)
1083{
1084 drm_i915_private_t *dev_priv = dev->dev_private;
1085 u32 tmp;
1086
1087 if (!IS_IGD(dev))
1088 return;
1089
1090 tmp = I915_READ(CLKCFG);
1091
1092 switch (tmp & CLKCFG_FSB_MASK) {
1093 case CLKCFG_FSB_533:
1094 dev_priv->fsb_freq = 533; /* 133*4 */
1095 break;
1096 case CLKCFG_FSB_800:
1097 dev_priv->fsb_freq = 800; /* 200*4 */
1098 break;
1099 case CLKCFG_FSB_667:
1100 dev_priv->fsb_freq = 667; /* 167*4 */
1101 break;
1102 case CLKCFG_FSB_400:
1103 dev_priv->fsb_freq = 400; /* 100*4 */
1104 break;
1105 }
1106
1107 switch (tmp & CLKCFG_MEM_MASK) {
1108 case CLKCFG_MEM_533:
1109 dev_priv->mem_freq = 533;
1110 break;
1111 case CLKCFG_MEM_667:
1112 dev_priv->mem_freq = 667;
1113 break;
1114 case CLKCFG_MEM_800:
1115 dev_priv->mem_freq = 800;
1116 break;
1117 }
1118}
1119
1085/** 1120/**
1086 * i915_driver_load - setup chip and create an initial config 1121 * i915_driver_load - setup chip and create an initial config
1087 * @dev: DRM device 1122 * @dev: DRM device
@@ -1098,6 +1133,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1098 struct drm_i915_private *dev_priv = dev->dev_private; 1133 struct drm_i915_private *dev_priv = dev->dev_private;
1099 resource_size_t base, size; 1134 resource_size_t base, size;
1100 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;
1101 1137
1102 /* i915 has 4 more counters */ 1138 /* i915 has 4 more counters */
1103 dev->counters += 4; 1139 dev->counters += 4;
@@ -1146,9 +1182,22 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1146 "performance may suffer.\n"); 1182 "performance may suffer.\n");
1147 } 1183 }
1148 1184
1185 ret = i915_probe_agp(dev, &agp_size, &prealloc_size);
1186 if (ret)
1187 goto out_iomapfree;
1188
1149 /* enable GEM by default */ 1189 /* enable GEM by default */
1150 dev_priv->has_gem = 1; 1190 dev_priv->has_gem = 1;
1151 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
1152 dev->driver->get_vblank_counter = i915_get_vblank_counter; 1201 dev->driver->get_vblank_counter = i915_get_vblank_counter;
1153 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ 1202 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
1154 if (IS_G4X(dev) || IS_IGDNG(dev)) { 1203 if (IS_G4X(dev) || IS_IGDNG(dev)) {
@@ -1165,6 +1214,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1165 goto out_iomapfree; 1214 goto out_iomapfree;
1166 } 1215 }
1167 1216
1217 i915_get_mem_freq(dev);
1218
1168 /* On the 945G/GM, the chipset reports the MSI capability on the 1219 /* On the 945G/GM, the chipset reports the MSI capability on the
1169 * integrated graphics even though the support isn't actually there 1220 * integrated graphics even though the support isn't actually there
1170 * according to the published specs. It doesn't appear to function 1221 * according to the published specs. It doesn't appear to function
@@ -1180,6 +1231,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1180 pci_enable_msi(dev->pdev); 1231 pci_enable_msi(dev->pdev);
1181 1232
1182 spin_lock_init(&dev_priv->user_irq_lock); 1233 spin_lock_init(&dev_priv->user_irq_lock);
1234 spin_lock_init(&dev_priv->error_lock);
1183 dev_priv->user_irq_refcount = 0; 1235 dev_priv->user_irq_refcount = 0;
1184 1236
1185 ret = drm_vblank_init(dev, I915_NUM_PIPE); 1237 ret = drm_vblank_init(dev, I915_NUM_PIPE);
@@ -1190,7 +1242,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1190 } 1242 }
1191 1243
1192 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 1244 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
1193 ret = i915_load_modeset_init(dev); 1245 ret = i915_load_modeset_init(dev, prealloc_size, agp_size);
1194 if (ret < 0) { 1246 if (ret < 0) {
1195 DRM_ERROR("failed to init modeset\n"); 1247 DRM_ERROR("failed to init modeset\n");
1196 goto out_rmmap; 1248 goto out_rmmap;