diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_dma.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 321 |
1 files changed, 85 insertions, 236 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2dd2c93ebfa3..251987307ebe 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -40,8 +40,7 @@ | |||
40 | #include <linux/pnp.h> | 40 | #include <linux/pnp.h> |
41 | #include <linux/vga_switcheroo.h> | 41 | #include <linux/vga_switcheroo.h> |
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | 43 | #include <acpi/video.h> | |
44 | extern int intel_max_stolen; /* from AGP driver */ | ||
45 | 44 | ||
46 | /** | 45 | /** |
47 | * Sets up the hardware status page for devices that need a physical address | 46 | * Sets up the hardware status page for devices that need a physical address |
@@ -64,7 +63,7 @@ static int i915_init_phys_hws(struct drm_device *dev) | |||
64 | 63 | ||
65 | memset(dev_priv->render_ring.status_page.page_addr, 0, PAGE_SIZE); | 64 | memset(dev_priv->render_ring.status_page.page_addr, 0, PAGE_SIZE); |
66 | 65 | ||
67 | if (IS_I965G(dev)) | 66 | if (INTEL_INFO(dev)->gen >= 4) |
68 | dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) & | 67 | dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) & |
69 | 0xf0; | 68 | 0xf0; |
70 | 69 | ||
@@ -222,7 +221,7 @@ static int i915_dma_resume(struct drm_device * dev) | |||
222 | DRM_DEBUG_DRIVER("hw status page @ %p\n", | 221 | DRM_DEBUG_DRIVER("hw status page @ %p\n", |
223 | ring->status_page.page_addr); | 222 | ring->status_page.page_addr); |
224 | if (ring->status_page.gfx_addr != 0) | 223 | if (ring->status_page.gfx_addr != 0) |
225 | ring->setup_status_page(dev, ring); | 224 | intel_ring_setup_status_page(dev, ring); |
226 | else | 225 | else |
227 | I915_WRITE(HWS_PGA, dev_priv->dma_status_page); | 226 | I915_WRITE(HWS_PGA, dev_priv->dma_status_page); |
228 | 227 | ||
@@ -377,7 +376,7 @@ i915_emit_box(struct drm_device *dev, | |||
377 | return -EINVAL; | 376 | return -EINVAL; |
378 | } | 377 | } |
379 | 378 | ||
380 | if (IS_I965G(dev)) { | 379 | if (INTEL_INFO(dev)->gen >= 4) { |
381 | BEGIN_LP_RING(4); | 380 | BEGIN_LP_RING(4); |
382 | OUT_RING(GFX_OP_DRAWRECT_INFO_I965); | 381 | OUT_RING(GFX_OP_DRAWRECT_INFO_I965); |
383 | OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); | 382 | OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); |
@@ -481,7 +480,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, | |||
481 | 480 | ||
482 | if (!IS_I830(dev) && !IS_845G(dev)) { | 481 | if (!IS_I830(dev) && !IS_845G(dev)) { |
483 | BEGIN_LP_RING(2); | 482 | BEGIN_LP_RING(2); |
484 | if (IS_I965G(dev)) { | 483 | if (INTEL_INFO(dev)->gen >= 4) { |
485 | OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); | 484 | OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); |
486 | OUT_RING(batch->start); | 485 | OUT_RING(batch->start); |
487 | } else { | 486 | } else { |
@@ -888,12 +887,12 @@ static int | |||
888 | intel_alloc_mchbar_resource(struct drm_device *dev) | 887 | intel_alloc_mchbar_resource(struct drm_device *dev) |
889 | { | 888 | { |
890 | drm_i915_private_t *dev_priv = dev->dev_private; | 889 | drm_i915_private_t *dev_priv = dev->dev_private; |
891 | int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; | 890 | int reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; |
892 | u32 temp_lo, temp_hi = 0; | 891 | u32 temp_lo, temp_hi = 0; |
893 | u64 mchbar_addr; | 892 | u64 mchbar_addr; |
894 | int ret; | 893 | int ret; |
895 | 894 | ||
896 | if (IS_I965G(dev)) | 895 | if (INTEL_INFO(dev)->gen >= 4) |
897 | pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi); | 896 | pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi); |
898 | pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo); | 897 | pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo); |
899 | mchbar_addr = ((u64)temp_hi << 32) | temp_lo; | 898 | mchbar_addr = ((u64)temp_hi << 32) | temp_lo; |
@@ -920,7 +919,7 @@ intel_alloc_mchbar_resource(struct drm_device *dev) | |||
920 | return ret; | 919 | return ret; |
921 | } | 920 | } |
922 | 921 | ||
923 | if (IS_I965G(dev)) | 922 | if (INTEL_INFO(dev)->gen >= 4) |
924 | pci_write_config_dword(dev_priv->bridge_dev, reg + 4, | 923 | pci_write_config_dword(dev_priv->bridge_dev, reg + 4, |
925 | upper_32_bits(dev_priv->mch_res.start)); | 924 | upper_32_bits(dev_priv->mch_res.start)); |
926 | 925 | ||
@@ -934,7 +933,7 @@ static void | |||
934 | intel_setup_mchbar(struct drm_device *dev) | 933 | intel_setup_mchbar(struct drm_device *dev) |
935 | { | 934 | { |
936 | drm_i915_private_t *dev_priv = dev->dev_private; | 935 | drm_i915_private_t *dev_priv = dev->dev_private; |
937 | int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; | 936 | int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; |
938 | u32 temp; | 937 | u32 temp; |
939 | bool enabled; | 938 | bool enabled; |
940 | 939 | ||
@@ -971,7 +970,7 @@ static void | |||
971 | intel_teardown_mchbar(struct drm_device *dev) | 970 | intel_teardown_mchbar(struct drm_device *dev) |
972 | { | 971 | { |
973 | drm_i915_private_t *dev_priv = dev->dev_private; | 972 | drm_i915_private_t *dev_priv = dev->dev_private; |
974 | int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; | 973 | int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; |
975 | u32 temp; | 974 | u32 temp; |
976 | 975 | ||
977 | if (dev_priv->mchbar_need_disable) { | 976 | if (dev_priv->mchbar_need_disable) { |
@@ -990,174 +989,6 @@ intel_teardown_mchbar(struct drm_device *dev) | |||
990 | release_resource(&dev_priv->mch_res); | 989 | release_resource(&dev_priv->mch_res); |
991 | } | 990 | } |
992 | 991 | ||
993 | /** | ||
994 | * i915_probe_agp - get AGP bootup configuration | ||
995 | * @pdev: PCI device | ||
996 | * @aperture_size: returns AGP aperture configured size | ||
997 | * @preallocated_size: returns size of BIOS preallocated AGP space | ||
998 | * | ||
999 | * Since Intel integrated graphics are UMA, the BIOS has to set aside | ||
1000 | * some RAM for the framebuffer at early boot. This code figures out | ||
1001 | * how much was set aside so we can use it for our own purposes. | ||
1002 | */ | ||
1003 | static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size, | ||
1004 | uint32_t *preallocated_size, | ||
1005 | uint32_t *start) | ||
1006 | { | ||
1007 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1008 | u16 tmp = 0; | ||
1009 | unsigned long overhead; | ||
1010 | unsigned long stolen; | ||
1011 | |||
1012 | /* Get the fb aperture size and "stolen" memory amount. */ | ||
1013 | pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &tmp); | ||
1014 | |||
1015 | *aperture_size = 1024 * 1024; | ||
1016 | *preallocated_size = 1024 * 1024; | ||
1017 | |||
1018 | switch (dev->pdev->device) { | ||
1019 | case PCI_DEVICE_ID_INTEL_82830_CGC: | ||
1020 | case PCI_DEVICE_ID_INTEL_82845G_IG: | ||
1021 | case PCI_DEVICE_ID_INTEL_82855GM_IG: | ||
1022 | case PCI_DEVICE_ID_INTEL_82865_IG: | ||
1023 | if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M) | ||
1024 | *aperture_size *= 64; | ||
1025 | else | ||
1026 | *aperture_size *= 128; | ||
1027 | break; | ||
1028 | default: | ||
1029 | /* 9xx supports large sizes, just look at the length */ | ||
1030 | *aperture_size = pci_resource_len(dev->pdev, 2); | ||
1031 | break; | ||
1032 | } | ||
1033 | |||
1034 | /* | ||
1035 | * Some of the preallocated space is taken by the GTT | ||
1036 | * and popup. GTT is 1K per MB of aperture size, and popup is 4K. | ||
1037 | */ | ||
1038 | if (IS_G4X(dev) || IS_PINEVIEW(dev) || IS_IRONLAKE(dev) || IS_GEN6(dev)) | ||
1039 | overhead = 4096; | ||
1040 | else | ||
1041 | overhead = (*aperture_size / 1024) + 4096; | ||
1042 | |||
1043 | if (IS_GEN6(dev)) { | ||
1044 | /* SNB has memory control reg at 0x50.w */ | ||
1045 | pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &tmp); | ||
1046 | |||
1047 | switch (tmp & SNB_GMCH_GMS_STOLEN_MASK) { | ||
1048 | case INTEL_855_GMCH_GMS_DISABLED: | ||
1049 | DRM_ERROR("video memory is disabled\n"); | ||
1050 | return -1; | ||
1051 | case SNB_GMCH_GMS_STOLEN_32M: | ||
1052 | stolen = 32 * 1024 * 1024; | ||
1053 | break; | ||
1054 | case SNB_GMCH_GMS_STOLEN_64M: | ||
1055 | stolen = 64 * 1024 * 1024; | ||
1056 | break; | ||
1057 | case SNB_GMCH_GMS_STOLEN_96M: | ||
1058 | stolen = 96 * 1024 * 1024; | ||
1059 | break; | ||
1060 | case SNB_GMCH_GMS_STOLEN_128M: | ||
1061 | stolen = 128 * 1024 * 1024; | ||
1062 | break; | ||
1063 | case SNB_GMCH_GMS_STOLEN_160M: | ||
1064 | stolen = 160 * 1024 * 1024; | ||
1065 | break; | ||
1066 | case SNB_GMCH_GMS_STOLEN_192M: | ||
1067 | stolen = 192 * 1024 * 1024; | ||
1068 | break; | ||
1069 | case SNB_GMCH_GMS_STOLEN_224M: | ||
1070 | stolen = 224 * 1024 * 1024; | ||
1071 | break; | ||
1072 | case SNB_GMCH_GMS_STOLEN_256M: | ||
1073 | stolen = 256 * 1024 * 1024; | ||
1074 | break; | ||
1075 | case SNB_GMCH_GMS_STOLEN_288M: | ||
1076 | stolen = 288 * 1024 * 1024; | ||
1077 | break; | ||
1078 | case SNB_GMCH_GMS_STOLEN_320M: | ||
1079 | stolen = 320 * 1024 * 1024; | ||
1080 | break; | ||
1081 | case SNB_GMCH_GMS_STOLEN_352M: | ||
1082 | stolen = 352 * 1024 * 1024; | ||
1083 | break; | ||
1084 | case SNB_GMCH_GMS_STOLEN_384M: | ||
1085 | stolen = 384 * 1024 * 1024; | ||
1086 | break; | ||
1087 | case SNB_GMCH_GMS_STOLEN_416M: | ||
1088 | stolen = 416 * 1024 * 1024; | ||
1089 | break; | ||
1090 | case SNB_GMCH_GMS_STOLEN_448M: | ||
1091 | stolen = 448 * 1024 * 1024; | ||
1092 | break; | ||
1093 | case SNB_GMCH_GMS_STOLEN_480M: | ||
1094 | stolen = 480 * 1024 * 1024; | ||
1095 | break; | ||
1096 | case SNB_GMCH_GMS_STOLEN_512M: | ||
1097 | stolen = 512 * 1024 * 1024; | ||
1098 | break; | ||
1099 | default: | ||
1100 | DRM_ERROR("unexpected GMCH_GMS value: 0x%02x\n", | ||
1101 | tmp & SNB_GMCH_GMS_STOLEN_MASK); | ||
1102 | return -1; | ||
1103 | } | ||
1104 | } else { | ||
1105 | switch (tmp & INTEL_GMCH_GMS_MASK) { | ||
1106 | case INTEL_855_GMCH_GMS_DISABLED: | ||
1107 | DRM_ERROR("video memory is disabled\n"); | ||
1108 | return -1; | ||
1109 | case INTEL_855_GMCH_GMS_STOLEN_1M: | ||
1110 | stolen = 1 * 1024 * 1024; | ||
1111 | break; | ||
1112 | case INTEL_855_GMCH_GMS_STOLEN_4M: | ||
1113 | stolen = 4 * 1024 * 1024; | ||
1114 | break; | ||
1115 | case INTEL_855_GMCH_GMS_STOLEN_8M: | ||
1116 | stolen = 8 * 1024 * 1024; | ||
1117 | break; | ||
1118 | case INTEL_855_GMCH_GMS_STOLEN_16M: | ||
1119 | stolen = 16 * 1024 * 1024; | ||
1120 | break; | ||
1121 | case INTEL_855_GMCH_GMS_STOLEN_32M: | ||
1122 | stolen = 32 * 1024 * 1024; | ||
1123 | break; | ||
1124 | case INTEL_915G_GMCH_GMS_STOLEN_48M: | ||
1125 | stolen = 48 * 1024 * 1024; | ||
1126 | break; | ||
1127 | case INTEL_915G_GMCH_GMS_STOLEN_64M: | ||
1128 | stolen = 64 * 1024 * 1024; | ||
1129 | break; | ||
1130 | case INTEL_GMCH_GMS_STOLEN_128M: | ||
1131 | stolen = 128 * 1024 * 1024; | ||
1132 | break; | ||
1133 | case INTEL_GMCH_GMS_STOLEN_256M: | ||
1134 | stolen = 256 * 1024 * 1024; | ||
1135 | break; | ||
1136 | case INTEL_GMCH_GMS_STOLEN_96M: | ||
1137 | stolen = 96 * 1024 * 1024; | ||
1138 | break; | ||
1139 | case INTEL_GMCH_GMS_STOLEN_160M: | ||
1140 | stolen = 160 * 1024 * 1024; | ||
1141 | break; | ||
1142 | case INTEL_GMCH_GMS_STOLEN_224M: | ||
1143 | stolen = 224 * 1024 * 1024; | ||
1144 | break; | ||
1145 | case INTEL_GMCH_GMS_STOLEN_352M: | ||
1146 | stolen = 352 * 1024 * 1024; | ||
1147 | break; | ||
1148 | default: | ||
1149 | DRM_ERROR("unexpected GMCH_GMS value: 0x%02x\n", | ||
1150 | tmp & INTEL_GMCH_GMS_MASK); | ||
1151 | return -1; | ||
1152 | } | ||
1153 | } | ||
1154 | |||
1155 | *preallocated_size = stolen - overhead; | ||
1156 | *start = overhead; | ||
1157 | |||
1158 | return 0; | ||
1159 | } | ||
1160 | |||
1161 | #define PTE_ADDRESS_MASK 0xfffff000 | 992 | #define PTE_ADDRESS_MASK 0xfffff000 |
1162 | #define PTE_ADDRESS_MASK_HIGH 0x000000f0 /* i915+ */ | 993 | #define PTE_ADDRESS_MASK_HIGH 0x000000f0 /* i915+ */ |
1163 | #define PTE_MAPPING_TYPE_UNCACHED (0 << 1) | 994 | #define PTE_MAPPING_TYPE_UNCACHED (0 << 1) |
@@ -1181,11 +1012,11 @@ static unsigned long i915_gtt_to_phys(struct drm_device *dev, | |||
1181 | { | 1012 | { |
1182 | unsigned long *gtt; | 1013 | unsigned long *gtt; |
1183 | unsigned long entry, phys; | 1014 | unsigned long entry, phys; |
1184 | int gtt_bar = IS_I9XX(dev) ? 0 : 1; | 1015 | int gtt_bar = IS_GEN2(dev) ? 1 : 0; |
1185 | int gtt_offset, gtt_size; | 1016 | int gtt_offset, gtt_size; |
1186 | 1017 | ||
1187 | if (IS_I965G(dev)) { | 1018 | if (INTEL_INFO(dev)->gen >= 4) { |
1188 | if (IS_G4X(dev) || IS_IRONLAKE(dev) || IS_GEN6(dev)) { | 1019 | if (IS_G4X(dev) || INTEL_INFO(dev)->gen > 4) { |
1189 | gtt_offset = 2*1024*1024; | 1020 | gtt_offset = 2*1024*1024; |
1190 | gtt_size = 2*1024*1024; | 1021 | gtt_size = 2*1024*1024; |
1191 | } else { | 1022 | } else { |
@@ -1210,10 +1041,8 @@ static unsigned long i915_gtt_to_phys(struct drm_device *dev, | |||
1210 | DRM_DEBUG_DRIVER("GTT addr: 0x%08lx, PTE: 0x%08lx\n", gtt_addr, entry); | 1041 | DRM_DEBUG_DRIVER("GTT addr: 0x%08lx, PTE: 0x%08lx\n", gtt_addr, entry); |
1211 | 1042 | ||
1212 | /* Mask out these reserved bits on this hardware. */ | 1043 | /* Mask out these reserved bits on this hardware. */ |
1213 | if (!IS_I9XX(dev) || IS_I915G(dev) || IS_I915GM(dev) || | 1044 | if (INTEL_INFO(dev)->gen < 4 && !IS_G33(dev)) |
1214 | IS_I945G(dev) || IS_I945GM(dev)) { | ||
1215 | entry &= ~PTE_ADDRESS_MASK_HIGH; | 1045 | entry &= ~PTE_ADDRESS_MASK_HIGH; |
1216 | } | ||
1217 | 1046 | ||
1218 | /* If it's not a mapping type we know, then bail. */ | 1047 | /* If it's not a mapping type we know, then bail. */ |
1219 | if ((entry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_UNCACHED && | 1048 | if ((entry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_UNCACHED && |
@@ -1252,7 +1081,7 @@ static void i915_setup_compression(struct drm_device *dev, int size) | |||
1252 | unsigned long ll_base = 0; | 1081 | unsigned long ll_base = 0; |
1253 | 1082 | ||
1254 | /* Leave 1M for line length buffer & misc. */ | 1083 | /* Leave 1M for line length buffer & misc. */ |
1255 | compressed_fb = drm_mm_search_free(&dev_priv->vram, size, 4096, 0); | 1084 | compressed_fb = drm_mm_search_free(&dev_priv->mm.vram, size, 4096, 0); |
1256 | if (!compressed_fb) { | 1085 | if (!compressed_fb) { |
1257 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; | 1086 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; |
1258 | i915_warn_stolen(dev); | 1087 | i915_warn_stolen(dev); |
@@ -1273,7 +1102,7 @@ static void i915_setup_compression(struct drm_device *dev, int size) | |||
1273 | } | 1102 | } |
1274 | 1103 | ||
1275 | if (!(IS_GM45(dev) || IS_IRONLAKE_M(dev))) { | 1104 | if (!(IS_GM45(dev) || IS_IRONLAKE_M(dev))) { |
1276 | compressed_llb = drm_mm_search_free(&dev_priv->vram, 4096, | 1105 | compressed_llb = drm_mm_search_free(&dev_priv->mm.vram, 4096, |
1277 | 4096, 0); | 1106 | 4096, 0); |
1278 | if (!compressed_llb) { | 1107 | if (!compressed_llb) { |
1279 | i915_warn_stolen(dev); | 1108 | i915_warn_stolen(dev); |
@@ -1343,10 +1172,8 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_ | |||
1343 | /* i915 resume handler doesn't set to D0 */ | 1172 | /* i915 resume handler doesn't set to D0 */ |
1344 | pci_set_power_state(dev->pdev, PCI_D0); | 1173 | pci_set_power_state(dev->pdev, PCI_D0); |
1345 | i915_resume(dev); | 1174 | i915_resume(dev); |
1346 | drm_kms_helper_poll_enable(dev); | ||
1347 | } else { | 1175 | } else { |
1348 | printk(KERN_ERR "i915: switched off\n"); | 1176 | printk(KERN_ERR "i915: switched off\n"); |
1349 | drm_kms_helper_poll_disable(dev); | ||
1350 | i915_suspend(dev, pmm); | 1177 | i915_suspend(dev, pmm); |
1351 | } | 1178 | } |
1352 | } | 1179 | } |
@@ -1363,20 +1190,14 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev) | |||
1363 | } | 1190 | } |
1364 | 1191 | ||
1365 | static int i915_load_modeset_init(struct drm_device *dev, | 1192 | static int i915_load_modeset_init(struct drm_device *dev, |
1366 | unsigned long prealloc_start, | ||
1367 | unsigned long prealloc_size, | 1193 | unsigned long prealloc_size, |
1368 | unsigned long agp_size) | 1194 | unsigned long agp_size) |
1369 | { | 1195 | { |
1370 | struct drm_i915_private *dev_priv = dev->dev_private; | 1196 | struct drm_i915_private *dev_priv = dev->dev_private; |
1371 | int fb_bar = IS_I9XX(dev) ? 2 : 0; | ||
1372 | int ret = 0; | 1197 | int ret = 0; |
1373 | 1198 | ||
1374 | dev->mode_config.fb_base = pci_resource_start(dev->pdev, fb_bar) & | 1199 | /* Basic memrange allocator for stolen space (aka mm.vram) */ |
1375 | 0xff000000; | 1200 | drm_mm_init(&dev_priv->mm.vram, 0, prealloc_size); |
1376 | |||
1377 | /* Basic memrange allocator for stolen space (aka vram) */ | ||
1378 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); | ||
1379 | DRM_INFO("set up %ldM of stolen space\n", prealloc_size / (1024*1024)); | ||
1380 | 1201 | ||
1381 | /* We're off and running w/KMS */ | 1202 | /* We're off and running w/KMS */ |
1382 | dev_priv->mm.suspended = 0; | 1203 | dev_priv->mm.suspended = 0; |
@@ -1443,12 +1264,6 @@ static int i915_load_modeset_init(struct drm_device *dev, | |||
1443 | /* FIXME: do pre/post-mode set stuff in core KMS code */ | 1264 | /* FIXME: do pre/post-mode set stuff in core KMS code */ |
1444 | dev->vblank_disable_allowed = 1; | 1265 | dev->vblank_disable_allowed = 1; |
1445 | 1266 | ||
1446 | /* | ||
1447 | * Initialize the hardware status page IRQ location. | ||
1448 | */ | ||
1449 | |||
1450 | I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); | ||
1451 | |||
1452 | ret = intel_fbdev_init(dev); | 1267 | ret = intel_fbdev_init(dev); |
1453 | if (ret) | 1268 | if (ret) |
1454 | goto cleanup_irq; | 1269 | goto cleanup_irq; |
@@ -1907,7 +1722,7 @@ static struct drm_i915_private *i915_mch_dev; | |||
1907 | * - dev_priv->fmax | 1722 | * - dev_priv->fmax |
1908 | * - dev_priv->gpu_busy | 1723 | * - dev_priv->gpu_busy |
1909 | */ | 1724 | */ |
1910 | DEFINE_SPINLOCK(mchdev_lock); | 1725 | static DEFINE_SPINLOCK(mchdev_lock); |
1911 | 1726 | ||
1912 | /** | 1727 | /** |
1913 | * i915_read_mch_val - return value for IPS use | 1728 | * i915_read_mch_val - return value for IPS use |
@@ -2062,7 +1877,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2062 | struct drm_i915_private *dev_priv; | 1877 | struct drm_i915_private *dev_priv; |
2063 | resource_size_t base, size; | 1878 | resource_size_t base, size; |
2064 | int ret = 0, mmio_bar; | 1879 | int ret = 0, mmio_bar; |
2065 | uint32_t agp_size, prealloc_size, prealloc_start; | 1880 | uint32_t agp_size, prealloc_size; |
2066 | /* i915 has 4 more counters */ | 1881 | /* i915 has 4 more counters */ |
2067 | dev->counters += 4; | 1882 | dev->counters += 4; |
2068 | dev->types[6] = _DRM_STAT_IRQ; | 1883 | dev->types[6] = _DRM_STAT_IRQ; |
@@ -2079,7 +1894,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2079 | dev_priv->info = (struct intel_device_info *) flags; | 1894 | dev_priv->info = (struct intel_device_info *) flags; |
2080 | 1895 | ||
2081 | /* Add register map (needed for suspend/resume) */ | 1896 | /* Add register map (needed for suspend/resume) */ |
2082 | mmio_bar = IS_I9XX(dev) ? 0 : 1; | 1897 | mmio_bar = IS_GEN2(dev) ? 1 : 0; |
2083 | base = pci_resource_start(dev->pdev, mmio_bar); | 1898 | base = pci_resource_start(dev->pdev, mmio_bar); |
2084 | size = pci_resource_len(dev->pdev, mmio_bar); | 1899 | size = pci_resource_len(dev->pdev, mmio_bar); |
2085 | 1900 | ||
@@ -2121,17 +1936,32 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2121 | "performance may suffer.\n"); | 1936 | "performance may suffer.\n"); |
2122 | } | 1937 | } |
2123 | 1938 | ||
2124 | ret = i915_probe_agp(dev, &agp_size, &prealloc_size, &prealloc_start); | 1939 | dev_priv->mm.gtt = intel_gtt_get(); |
2125 | if (ret) | 1940 | if (!dev_priv->mm.gtt) { |
1941 | DRM_ERROR("Failed to initialize GTT\n"); | ||
1942 | ret = -ENODEV; | ||
2126 | goto out_iomapfree; | 1943 | goto out_iomapfree; |
2127 | |||
2128 | if (prealloc_size > intel_max_stolen) { | ||
2129 | DRM_INFO("detected %dM stolen memory, trimming to %dM\n", | ||
2130 | prealloc_size >> 20, intel_max_stolen >> 20); | ||
2131 | prealloc_size = intel_max_stolen; | ||
2132 | } | 1944 | } |
2133 | 1945 | ||
2134 | dev_priv->wq = create_singlethread_workqueue("i915"); | 1946 | prealloc_size = dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT; |
1947 | agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; | ||
1948 | |||
1949 | /* The i915 workqueue is primarily used for batched retirement of | ||
1950 | * requests (and thus managing bo) once the task has been completed | ||
1951 | * by the GPU. i915_gem_retire_requests() is called directly when we | ||
1952 | * need high-priority retirement, such as waiting for an explicit | ||
1953 | * bo. | ||
1954 | * | ||
1955 | * It is also used for periodic low-priority events, such as | ||
1956 | * idle-timers and hangcheck. | ||
1957 | * | ||
1958 | * All tasks on the workqueue are expected to acquire the dev mutex | ||
1959 | * so there is no point in running more than one instance of the | ||
1960 | * workqueue at any time: max_active = 1 and NON_REENTRANT. | ||
1961 | */ | ||
1962 | dev_priv->wq = alloc_workqueue("i915", | ||
1963 | WQ_UNBOUND | WQ_NON_REENTRANT, | ||
1964 | 1); | ||
2135 | if (dev_priv->wq == NULL) { | 1965 | if (dev_priv->wq == NULL) { |
2136 | DRM_ERROR("Failed to create our workqueue.\n"); | 1966 | DRM_ERROR("Failed to create our workqueue.\n"); |
2137 | ret = -ENOMEM; | 1967 | ret = -ENOMEM; |
@@ -2166,6 +1996,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2166 | 1996 | ||
2167 | /* Try to make sure MCHBAR is enabled before poking at it */ | 1997 | /* Try to make sure MCHBAR is enabled before poking at it */ |
2168 | intel_setup_mchbar(dev); | 1998 | intel_setup_mchbar(dev); |
1999 | intel_setup_gmbus(dev); | ||
2000 | intel_opregion_setup(dev); | ||
2169 | 2001 | ||
2170 | i915_gem_load(dev); | 2002 | i915_gem_load(dev); |
2171 | 2003 | ||
@@ -2212,8 +2044,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2212 | intel_detect_pch(dev); | 2044 | intel_detect_pch(dev); |
2213 | 2045 | ||
2214 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 2046 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
2215 | ret = i915_load_modeset_init(dev, prealloc_start, | 2047 | ret = i915_load_modeset_init(dev, prealloc_size, agp_size); |
2216 | prealloc_size, agp_size); | ||
2217 | if (ret < 0) { | 2048 | if (ret < 0) { |
2218 | DRM_ERROR("failed to init modeset\n"); | 2049 | DRM_ERROR("failed to init modeset\n"); |
2219 | goto out_workqueue_free; | 2050 | goto out_workqueue_free; |
@@ -2221,7 +2052,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2221 | } | 2052 | } |
2222 | 2053 | ||
2223 | /* Must be done after probing outputs */ | 2054 | /* Must be done after probing outputs */ |
2224 | intel_opregion_init(dev, 0); | 2055 | intel_opregion_init(dev); |
2056 | acpi_video_register(); | ||
2225 | 2057 | ||
2226 | setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, | 2058 | setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, |
2227 | (unsigned long) dev); | 2059 | (unsigned long) dev); |
@@ -2252,15 +2084,20 @@ free_priv: | |||
2252 | int i915_driver_unload(struct drm_device *dev) | 2084 | int i915_driver_unload(struct drm_device *dev) |
2253 | { | 2085 | { |
2254 | struct drm_i915_private *dev_priv = dev->dev_private; | 2086 | struct drm_i915_private *dev_priv = dev->dev_private; |
2255 | 2087 | int ret; | |
2256 | i915_destroy_error_state(dev); | ||
2257 | 2088 | ||
2258 | spin_lock(&mchdev_lock); | 2089 | spin_lock(&mchdev_lock); |
2259 | i915_mch_dev = NULL; | 2090 | i915_mch_dev = NULL; |
2260 | spin_unlock(&mchdev_lock); | 2091 | spin_unlock(&mchdev_lock); |
2261 | 2092 | ||
2262 | destroy_workqueue(dev_priv->wq); | 2093 | mutex_lock(&dev->struct_mutex); |
2263 | del_timer_sync(&dev_priv->hangcheck_timer); | 2094 | ret = i915_gpu_idle(dev); |
2095 | if (ret) | ||
2096 | DRM_ERROR("failed to idle hardware: %d\n", ret); | ||
2097 | mutex_unlock(&dev->struct_mutex); | ||
2098 | |||
2099 | /* Cancel the retire work handler, which should be idle now. */ | ||
2100 | cancel_delayed_work_sync(&dev_priv->mm.retire_work); | ||
2264 | 2101 | ||
2265 | io_mapping_free(dev_priv->mm.gtt_mapping); | 2102 | io_mapping_free(dev_priv->mm.gtt_mapping); |
2266 | if (dev_priv->mm.gtt_mtrr >= 0) { | 2103 | if (dev_priv->mm.gtt_mtrr >= 0) { |
@@ -2269,7 +2106,10 @@ int i915_driver_unload(struct drm_device *dev) | |||
2269 | dev_priv->mm.gtt_mtrr = -1; | 2106 | dev_priv->mm.gtt_mtrr = -1; |
2270 | } | 2107 | } |
2271 | 2108 | ||
2109 | acpi_video_unregister(); | ||
2110 | |||
2272 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 2111 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
2112 | intel_fbdev_fini(dev); | ||
2273 | intel_modeset_cleanup(dev); | 2113 | intel_modeset_cleanup(dev); |
2274 | 2114 | ||
2275 | /* | 2115 | /* |
@@ -2281,20 +2121,28 @@ int i915_driver_unload(struct drm_device *dev) | |||
2281 | dev_priv->child_dev = NULL; | 2121 | dev_priv->child_dev = NULL; |
2282 | dev_priv->child_dev_num = 0; | 2122 | dev_priv->child_dev_num = 0; |
2283 | } | 2123 | } |
2284 | drm_irq_uninstall(dev); | 2124 | |
2285 | vga_switcheroo_unregister_client(dev->pdev); | 2125 | vga_switcheroo_unregister_client(dev->pdev); |
2286 | vga_client_register(dev->pdev, NULL, NULL, NULL); | 2126 | vga_client_register(dev->pdev, NULL, NULL, NULL); |
2287 | } | 2127 | } |
2288 | 2128 | ||
2129 | /* Free error state after interrupts are fully disabled. */ | ||
2130 | del_timer_sync(&dev_priv->hangcheck_timer); | ||
2131 | cancel_work_sync(&dev_priv->error_work); | ||
2132 | i915_destroy_error_state(dev); | ||
2133 | |||
2289 | if (dev->pdev->msi_enabled) | 2134 | if (dev->pdev->msi_enabled) |
2290 | pci_disable_msi(dev->pdev); | 2135 | pci_disable_msi(dev->pdev); |
2291 | 2136 | ||
2292 | if (dev_priv->regs != NULL) | 2137 | if (dev_priv->regs != NULL) |
2293 | iounmap(dev_priv->regs); | 2138 | iounmap(dev_priv->regs); |
2294 | 2139 | ||
2295 | intel_opregion_free(dev, 0); | 2140 | intel_opregion_fini(dev); |
2296 | 2141 | ||
2297 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 2142 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
2143 | /* Flush any outstanding unpin_work. */ | ||
2144 | flush_workqueue(dev_priv->wq); | ||
2145 | |||
2298 | i915_gem_free_all_phys_object(dev); | 2146 | i915_gem_free_all_phys_object(dev); |
2299 | 2147 | ||
2300 | mutex_lock(&dev->struct_mutex); | 2148 | mutex_lock(&dev->struct_mutex); |
@@ -2302,34 +2150,35 @@ int i915_driver_unload(struct drm_device *dev) | |||
2302 | mutex_unlock(&dev->struct_mutex); | 2150 | mutex_unlock(&dev->struct_mutex); |
2303 | if (I915_HAS_FBC(dev) && i915_powersave) | 2151 | if (I915_HAS_FBC(dev) && i915_powersave) |
2304 | i915_cleanup_compression(dev); | 2152 | i915_cleanup_compression(dev); |
2305 | drm_mm_takedown(&dev_priv->vram); | 2153 | drm_mm_takedown(&dev_priv->mm.vram); |
2306 | i915_gem_lastclose(dev); | ||
2307 | 2154 | ||
2308 | intel_cleanup_overlay(dev); | 2155 | intel_cleanup_overlay(dev); |
2309 | } | 2156 | } |
2310 | 2157 | ||
2158 | intel_teardown_gmbus(dev); | ||
2311 | intel_teardown_mchbar(dev); | 2159 | intel_teardown_mchbar(dev); |
2312 | 2160 | ||
2161 | destroy_workqueue(dev_priv->wq); | ||
2162 | |||
2313 | pci_dev_put(dev_priv->bridge_dev); | 2163 | pci_dev_put(dev_priv->bridge_dev); |
2314 | kfree(dev->dev_private); | 2164 | kfree(dev->dev_private); |
2315 | 2165 | ||
2316 | return 0; | 2166 | return 0; |
2317 | } | 2167 | } |
2318 | 2168 | ||
2319 | int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv) | 2169 | int i915_driver_open(struct drm_device *dev, struct drm_file *file) |
2320 | { | 2170 | { |
2321 | struct drm_i915_file_private *i915_file_priv; | 2171 | struct drm_i915_file_private *file_priv; |
2322 | 2172 | ||
2323 | DRM_DEBUG_DRIVER("\n"); | 2173 | DRM_DEBUG_DRIVER("\n"); |
2324 | i915_file_priv = (struct drm_i915_file_private *) | 2174 | file_priv = kmalloc(sizeof(*file_priv), GFP_KERNEL); |
2325 | kmalloc(sizeof(*i915_file_priv), GFP_KERNEL); | 2175 | if (!file_priv) |
2326 | |||
2327 | if (!i915_file_priv) | ||
2328 | return -ENOMEM; | 2176 | return -ENOMEM; |
2329 | 2177 | ||
2330 | file_priv->driver_priv = i915_file_priv; | 2178 | file->driver_priv = file_priv; |
2331 | 2179 | ||
2332 | INIT_LIST_HEAD(&i915_file_priv->mm.request_list); | 2180 | spin_lock_init(&file_priv->mm.lock); |
2181 | INIT_LIST_HEAD(&file_priv->mm.request_list); | ||
2333 | 2182 | ||
2334 | return 0; | 2183 | return 0; |
2335 | } | 2184 | } |
@@ -2372,11 +2221,11 @@ void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) | |||
2372 | i915_mem_release(dev, file_priv, dev_priv->agp_heap); | 2221 | i915_mem_release(dev, file_priv, dev_priv->agp_heap); |
2373 | } | 2222 | } |
2374 | 2223 | ||
2375 | void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) | 2224 | void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) |
2376 | { | 2225 | { |
2377 | struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv; | 2226 | struct drm_i915_file_private *file_priv = file->driver_priv; |
2378 | 2227 | ||
2379 | kfree(i915_file_priv); | 2228 | kfree(file_priv); |
2380 | } | 2229 | } |
2381 | 2230 | ||
2382 | struct drm_ioctl_desc i915_ioctls[] = { | 2231 | struct drm_ioctl_desc i915_ioctls[] = { |