diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2010-09-06 14:08:44 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-09-08 16:20:21 -0400 |
commit | 19966754328d99ee003ddfc7a8c31ceb115483ac (patch) | |
tree | c057dfaf9f9354168102e5ae450ebefbc158bd28 /drivers/gpu/drm/i915/i915_dma.c | |
parent | ac622a9cdb742cad90648d95f2c4877774518f19 (diff) |
drm/i915: die, i915_probe_agp, die
Use the detection from intel-gtt.ko instead. Hooray!
Also move the stolen mem allocator to the other gtt stuff in dev_prv->mem.
v2: Chris Wilson noted that my error handling was crap. Fix it. He also
said that this fixes a problem on his i845. Indeed, i915_probe_agp
misses a special case for i830/i845 stolen mem detection.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=25476
Cc: stable@kernel.org
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_dma.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 190 |
1 files changed, 12 insertions, 178 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a693b27f3df4..428c75b466aa 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -989,172 +989,6 @@ intel_teardown_mchbar(struct drm_device *dev) | |||
989 | release_resource(&dev_priv->mch_res); | 989 | release_resource(&dev_priv->mch_res); |
990 | } | 990 | } |
991 | 991 | ||
992 | /** | ||
993 | * i915_probe_agp - get AGP bootup configuration | ||
994 | * @pdev: PCI device | ||
995 | * @aperture_size: returns AGP aperture configured size | ||
996 | * @preallocated_size: returns size of BIOS preallocated AGP space | ||
997 | * | ||
998 | * Since Intel integrated graphics are UMA, the BIOS has to set aside | ||
999 | * some RAM for the framebuffer at early boot. This code figures out | ||
1000 | * how much was set aside so we can use it for our own purposes. | ||
1001 | */ | ||
1002 | static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size, | ||
1003 | uint32_t *preallocated_size) | ||
1004 | { | ||
1005 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1006 | u16 tmp = 0; | ||
1007 | unsigned long overhead; | ||
1008 | unsigned long stolen; | ||
1009 | |||
1010 | /* Get the fb aperture size and "stolen" memory amount. */ | ||
1011 | pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &tmp); | ||
1012 | |||
1013 | *aperture_size = 1024 * 1024; | ||
1014 | *preallocated_size = 1024 * 1024; | ||
1015 | |||
1016 | switch (dev->pdev->device) { | ||
1017 | case PCI_DEVICE_ID_INTEL_82830_CGC: | ||
1018 | case PCI_DEVICE_ID_INTEL_82845G_IG: | ||
1019 | case PCI_DEVICE_ID_INTEL_82855GM_IG: | ||
1020 | case PCI_DEVICE_ID_INTEL_82865_IG: | ||
1021 | if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M) | ||
1022 | *aperture_size *= 64; | ||
1023 | else | ||
1024 | *aperture_size *= 128; | ||
1025 | break; | ||
1026 | default: | ||
1027 | /* 9xx supports large sizes, just look at the length */ | ||
1028 | *aperture_size = pci_resource_len(dev->pdev, 2); | ||
1029 | break; | ||
1030 | } | ||
1031 | |||
1032 | /* | ||
1033 | * Some of the preallocated space is taken by the GTT | ||
1034 | * and popup. GTT is 1K per MB of aperture size, and popup is 4K. | ||
1035 | */ | ||
1036 | if (IS_G4X(dev) || IS_PINEVIEW(dev) || IS_IRONLAKE(dev) || IS_GEN6(dev)) | ||
1037 | overhead = 4096; | ||
1038 | else | ||
1039 | overhead = (*aperture_size / 1024) + 4096; | ||
1040 | |||
1041 | if (IS_GEN6(dev)) { | ||
1042 | /* SNB has memory control reg at 0x50.w */ | ||
1043 | pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &tmp); | ||
1044 | |||
1045 | switch (tmp & SNB_GMCH_GMS_STOLEN_MASK) { | ||
1046 | case INTEL_855_GMCH_GMS_DISABLED: | ||
1047 | DRM_ERROR("video memory is disabled\n"); | ||
1048 | return -1; | ||
1049 | case SNB_GMCH_GMS_STOLEN_32M: | ||
1050 | stolen = 32 * 1024 * 1024; | ||
1051 | break; | ||
1052 | case SNB_GMCH_GMS_STOLEN_64M: | ||
1053 | stolen = 64 * 1024 * 1024; | ||
1054 | break; | ||
1055 | case SNB_GMCH_GMS_STOLEN_96M: | ||
1056 | stolen = 96 * 1024 * 1024; | ||
1057 | break; | ||
1058 | case SNB_GMCH_GMS_STOLEN_128M: | ||
1059 | stolen = 128 * 1024 * 1024; | ||
1060 | break; | ||
1061 | case SNB_GMCH_GMS_STOLEN_160M: | ||
1062 | stolen = 160 * 1024 * 1024; | ||
1063 | break; | ||
1064 | case SNB_GMCH_GMS_STOLEN_192M: | ||
1065 | stolen = 192 * 1024 * 1024; | ||
1066 | break; | ||
1067 | case SNB_GMCH_GMS_STOLEN_224M: | ||
1068 | stolen = 224 * 1024 * 1024; | ||
1069 | break; | ||
1070 | case SNB_GMCH_GMS_STOLEN_256M: | ||
1071 | stolen = 256 * 1024 * 1024; | ||
1072 | break; | ||
1073 | case SNB_GMCH_GMS_STOLEN_288M: | ||
1074 | stolen = 288 * 1024 * 1024; | ||
1075 | break; | ||
1076 | case SNB_GMCH_GMS_STOLEN_320M: | ||
1077 | stolen = 320 * 1024 * 1024; | ||
1078 | break; | ||
1079 | case SNB_GMCH_GMS_STOLEN_352M: | ||
1080 | stolen = 352 * 1024 * 1024; | ||
1081 | break; | ||
1082 | case SNB_GMCH_GMS_STOLEN_384M: | ||
1083 | stolen = 384 * 1024 * 1024; | ||
1084 | break; | ||
1085 | case SNB_GMCH_GMS_STOLEN_416M: | ||
1086 | stolen = 416 * 1024 * 1024; | ||
1087 | break; | ||
1088 | case SNB_GMCH_GMS_STOLEN_448M: | ||
1089 | stolen = 448 * 1024 * 1024; | ||
1090 | break; | ||
1091 | case SNB_GMCH_GMS_STOLEN_480M: | ||
1092 | stolen = 480 * 1024 * 1024; | ||
1093 | break; | ||
1094 | case SNB_GMCH_GMS_STOLEN_512M: | ||
1095 | stolen = 512 * 1024 * 1024; | ||
1096 | break; | ||
1097 | default: | ||
1098 | DRM_ERROR("unexpected GMCH_GMS value: 0x%02x\n", | ||
1099 | tmp & SNB_GMCH_GMS_STOLEN_MASK); | ||
1100 | return -1; | ||
1101 | } | ||
1102 | } else { | ||
1103 | switch (tmp & INTEL_GMCH_GMS_MASK) { | ||
1104 | case INTEL_855_GMCH_GMS_DISABLED: | ||
1105 | DRM_ERROR("video memory is disabled\n"); | ||
1106 | return -1; | ||
1107 | case INTEL_855_GMCH_GMS_STOLEN_1M: | ||
1108 | stolen = 1 * 1024 * 1024; | ||
1109 | break; | ||
1110 | case INTEL_855_GMCH_GMS_STOLEN_4M: | ||
1111 | stolen = 4 * 1024 * 1024; | ||
1112 | break; | ||
1113 | case INTEL_855_GMCH_GMS_STOLEN_8M: | ||
1114 | stolen = 8 * 1024 * 1024; | ||
1115 | break; | ||
1116 | case INTEL_855_GMCH_GMS_STOLEN_16M: | ||
1117 | stolen = 16 * 1024 * 1024; | ||
1118 | break; | ||
1119 | case INTEL_855_GMCH_GMS_STOLEN_32M: | ||
1120 | stolen = 32 * 1024 * 1024; | ||
1121 | break; | ||
1122 | case INTEL_915G_GMCH_GMS_STOLEN_48M: | ||
1123 | stolen = 48 * 1024 * 1024; | ||
1124 | break; | ||
1125 | case INTEL_915G_GMCH_GMS_STOLEN_64M: | ||
1126 | stolen = 64 * 1024 * 1024; | ||
1127 | break; | ||
1128 | case INTEL_GMCH_GMS_STOLEN_128M: | ||
1129 | stolen = 128 * 1024 * 1024; | ||
1130 | break; | ||
1131 | case INTEL_GMCH_GMS_STOLEN_256M: | ||
1132 | stolen = 256 * 1024 * 1024; | ||
1133 | break; | ||
1134 | case INTEL_GMCH_GMS_STOLEN_96M: | ||
1135 | stolen = 96 * 1024 * 1024; | ||
1136 | break; | ||
1137 | case INTEL_GMCH_GMS_STOLEN_160M: | ||
1138 | stolen = 160 * 1024 * 1024; | ||
1139 | break; | ||
1140 | case INTEL_GMCH_GMS_STOLEN_224M: | ||
1141 | stolen = 224 * 1024 * 1024; | ||
1142 | break; | ||
1143 | case INTEL_GMCH_GMS_STOLEN_352M: | ||
1144 | stolen = 352 * 1024 * 1024; | ||
1145 | break; | ||
1146 | default: | ||
1147 | DRM_ERROR("unexpected GMCH_GMS value: 0x%02x\n", | ||
1148 | tmp & INTEL_GMCH_GMS_MASK); | ||
1149 | return -1; | ||
1150 | } | ||
1151 | } | ||
1152 | |||
1153 | *preallocated_size = stolen - overhead; | ||
1154 | |||
1155 | return 0; | ||
1156 | } | ||
1157 | |||
1158 | #define PTE_ADDRESS_MASK 0xfffff000 | 992 | #define PTE_ADDRESS_MASK 0xfffff000 |
1159 | #define PTE_ADDRESS_MASK_HIGH 0x000000f0 /* i915+ */ | 993 | #define PTE_ADDRESS_MASK_HIGH 0x000000f0 /* i915+ */ |
1160 | #define PTE_MAPPING_TYPE_UNCACHED (0 << 1) | 994 | #define PTE_MAPPING_TYPE_UNCACHED (0 << 1) |
@@ -1249,7 +1083,7 @@ static void i915_setup_compression(struct drm_device *dev, int size) | |||
1249 | unsigned long ll_base = 0; | 1083 | unsigned long ll_base = 0; |
1250 | 1084 | ||
1251 | /* Leave 1M for line length buffer & misc. */ | 1085 | /* Leave 1M for line length buffer & misc. */ |
1252 | compressed_fb = drm_mm_search_free(&dev_priv->vram, size, 4096, 0); | 1086 | compressed_fb = drm_mm_search_free(&dev_priv->mm.vram, size, 4096, 0); |
1253 | if (!compressed_fb) { | 1087 | if (!compressed_fb) { |
1254 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; | 1088 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; |
1255 | i915_warn_stolen(dev); | 1089 | i915_warn_stolen(dev); |
@@ -1270,7 +1104,7 @@ static void i915_setup_compression(struct drm_device *dev, int size) | |||
1270 | } | 1104 | } |
1271 | 1105 | ||
1272 | if (!(IS_GM45(dev) || IS_IRONLAKE_M(dev))) { | 1106 | if (!(IS_GM45(dev) || IS_IRONLAKE_M(dev))) { |
1273 | compressed_llb = drm_mm_search_free(&dev_priv->vram, 4096, | 1107 | compressed_llb = drm_mm_search_free(&dev_priv->mm.vram, 4096, |
1274 | 4096, 0); | 1108 | 4096, 0); |
1275 | if (!compressed_llb) { | 1109 | if (!compressed_llb) { |
1276 | i915_warn_stolen(dev); | 1110 | i915_warn_stolen(dev); |
@@ -1366,8 +1200,8 @@ static int i915_load_modeset_init(struct drm_device *dev, | |||
1366 | struct drm_i915_private *dev_priv = dev->dev_private; | 1200 | struct drm_i915_private *dev_priv = dev->dev_private; |
1367 | int ret = 0; | 1201 | int ret = 0; |
1368 | 1202 | ||
1369 | /* Basic memrange allocator for stolen space (aka vram) */ | 1203 | /* Basic memrange allocator for stolen space (aka mm.vram) */ |
1370 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); | 1204 | drm_mm_init(&dev_priv->mm.vram, 0, prealloc_size); |
1371 | DRM_INFO("set up %ldM of stolen space\n", prealloc_size / (1024*1024)); | 1205 | DRM_INFO("set up %ldM of stolen space\n", prealloc_size / (1024*1024)); |
1372 | 1206 | ||
1373 | /* We're off and running w/KMS */ | 1207 | /* We're off and running w/KMS */ |
@@ -2107,16 +1941,16 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2107 | "performance may suffer.\n"); | 1941 | "performance may suffer.\n"); |
2108 | } | 1942 | } |
2109 | 1943 | ||
2110 | ret = i915_probe_agp(dev, &agp_size, &prealloc_size); | 1944 | dev_priv->mm.gtt = intel_gtt_get(); |
2111 | if (ret) | 1945 | if (!dev_priv->mm.gtt) { |
1946 | DRM_ERROR("Failed to initialize GTT\n"); | ||
1947 | ret = -ENODEV; | ||
2112 | goto out_iomapfree; | 1948 | goto out_iomapfree; |
2113 | |||
2114 | if (prealloc_size > intel_max_stolen) { | ||
2115 | DRM_INFO("detected %dM stolen memory, trimming to %dM\n", | ||
2116 | prealloc_size >> 20, intel_max_stolen >> 20); | ||
2117 | prealloc_size = intel_max_stolen; | ||
2118 | } | 1949 | } |
2119 | 1950 | ||
1951 | prealloc_size = dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT; | ||
1952 | agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; | ||
1953 | |||
2120 | dev_priv->wq = create_singlethread_workqueue("i915"); | 1954 | dev_priv->wq = create_singlethread_workqueue("i915"); |
2121 | if (dev_priv->wq == NULL) { | 1955 | if (dev_priv->wq == NULL) { |
2122 | DRM_ERROR("Failed to create our workqueue.\n"); | 1956 | DRM_ERROR("Failed to create our workqueue.\n"); |
@@ -2301,7 +2135,7 @@ int i915_driver_unload(struct drm_device *dev) | |||
2301 | mutex_unlock(&dev->struct_mutex); | 2135 | mutex_unlock(&dev->struct_mutex); |
2302 | if (I915_HAS_FBC(dev) && i915_powersave) | 2136 | if (I915_HAS_FBC(dev) && i915_powersave) |
2303 | i915_cleanup_compression(dev); | 2137 | i915_cleanup_compression(dev); |
2304 | drm_mm_takedown(&dev_priv->vram); | 2138 | drm_mm_takedown(&dev_priv->mm.vram); |
2305 | 2139 | ||
2306 | intel_cleanup_overlay(dev); | 2140 | intel_cleanup_overlay(dev); |
2307 | } | 2141 | } |