diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_dma.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 794 |
1 files changed, 376 insertions, 418 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index cb900dc83d95..0568dbdc10ef 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -50,6 +50,8 @@ | |||
50 | static int i915_init_phys_hws(struct drm_device *dev) | 50 | static int i915_init_phys_hws(struct drm_device *dev) |
51 | { | 51 | { |
52 | drm_i915_private_t *dev_priv = dev->dev_private; | 52 | drm_i915_private_t *dev_priv = dev->dev_private; |
53 | struct intel_ring_buffer *ring = LP_RING(dev_priv); | ||
54 | |||
53 | /* Program Hardware Status Page */ | 55 | /* Program Hardware Status Page */ |
54 | dev_priv->status_page_dmah = | 56 | dev_priv->status_page_dmah = |
55 | drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE); | 57 | drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE); |
@@ -58,11 +60,10 @@ static int i915_init_phys_hws(struct drm_device *dev) | |||
58 | DRM_ERROR("Can not allocate hardware status page\n"); | 60 | DRM_ERROR("Can not allocate hardware status page\n"); |
59 | return -ENOMEM; | 61 | return -ENOMEM; |
60 | } | 62 | } |
61 | dev_priv->render_ring.status_page.page_addr | 63 | ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; |
62 | = dev_priv->status_page_dmah->vaddr; | ||
63 | dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; | 64 | dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; |
64 | 65 | ||
65 | memset(dev_priv->render_ring.status_page.page_addr, 0, PAGE_SIZE); | 66 | memset(ring->status_page.page_addr, 0, PAGE_SIZE); |
66 | 67 | ||
67 | if (INTEL_INFO(dev)->gen >= 4) | 68 | if (INTEL_INFO(dev)->gen >= 4) |
68 | dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) & | 69 | dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) & |
@@ -80,13 +81,15 @@ static int i915_init_phys_hws(struct drm_device *dev) | |||
80 | static void i915_free_hws(struct drm_device *dev) | 81 | static void i915_free_hws(struct drm_device *dev) |
81 | { | 82 | { |
82 | drm_i915_private_t *dev_priv = dev->dev_private; | 83 | drm_i915_private_t *dev_priv = dev->dev_private; |
84 | struct intel_ring_buffer *ring = LP_RING(dev_priv); | ||
85 | |||
83 | if (dev_priv->status_page_dmah) { | 86 | if (dev_priv->status_page_dmah) { |
84 | drm_pci_free(dev, dev_priv->status_page_dmah); | 87 | drm_pci_free(dev, dev_priv->status_page_dmah); |
85 | dev_priv->status_page_dmah = NULL; | 88 | dev_priv->status_page_dmah = NULL; |
86 | } | 89 | } |
87 | 90 | ||
88 | if (dev_priv->render_ring.status_page.gfx_addr) { | 91 | if (ring->status_page.gfx_addr) { |
89 | dev_priv->render_ring.status_page.gfx_addr = 0; | 92 | ring->status_page.gfx_addr = 0; |
90 | drm_core_ioremapfree(&dev_priv->hws_map, dev); | 93 | drm_core_ioremapfree(&dev_priv->hws_map, dev); |
91 | } | 94 | } |
92 | 95 | ||
@@ -98,7 +101,7 @@ void i915_kernel_lost_context(struct drm_device * dev) | |||
98 | { | 101 | { |
99 | drm_i915_private_t *dev_priv = dev->dev_private; | 102 | drm_i915_private_t *dev_priv = dev->dev_private; |
100 | struct drm_i915_master_private *master_priv; | 103 | struct drm_i915_master_private *master_priv; |
101 | struct intel_ring_buffer *ring = &dev_priv->render_ring; | 104 | struct intel_ring_buffer *ring = LP_RING(dev_priv); |
102 | 105 | ||
103 | /* | 106 | /* |
104 | * We should never lose context on the ring with modesetting | 107 | * We should never lose context on the ring with modesetting |
@@ -107,8 +110,8 @@ void i915_kernel_lost_context(struct drm_device * dev) | |||
107 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 110 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
108 | return; | 111 | return; |
109 | 112 | ||
110 | ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | 113 | ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; |
111 | ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; | 114 | ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; |
112 | ring->space = ring->head - (ring->tail + 8); | 115 | ring->space = ring->head - (ring->tail + 8); |
113 | if (ring->space < 0) | 116 | if (ring->space < 0) |
114 | ring->space += ring->size; | 117 | ring->space += ring->size; |
@@ -124,6 +127,8 @@ void i915_kernel_lost_context(struct drm_device * dev) | |||
124 | static int i915_dma_cleanup(struct drm_device * dev) | 127 | static int i915_dma_cleanup(struct drm_device * dev) |
125 | { | 128 | { |
126 | drm_i915_private_t *dev_priv = dev->dev_private; | 129 | drm_i915_private_t *dev_priv = dev->dev_private; |
130 | int i; | ||
131 | |||
127 | /* Make sure interrupts are disabled here because the uninstall ioctl | 132 | /* Make sure interrupts are disabled here because the uninstall ioctl |
128 | * may not have been called from userspace and after dev_private | 133 | * may not have been called from userspace and after dev_private |
129 | * is freed, it's too late. | 134 | * is freed, it's too late. |
@@ -132,9 +137,8 @@ static int i915_dma_cleanup(struct drm_device * dev) | |||
132 | drm_irq_uninstall(dev); | 137 | drm_irq_uninstall(dev); |
133 | 138 | ||
134 | mutex_lock(&dev->struct_mutex); | 139 | mutex_lock(&dev->struct_mutex); |
135 | intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); | 140 | for (i = 0; i < I915_NUM_RINGS; i++) |
136 | intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); | 141 | intel_cleanup_ring_buffer(&dev_priv->ring[i]); |
137 | intel_cleanup_ring_buffer(dev, &dev_priv->blt_ring); | ||
138 | mutex_unlock(&dev->struct_mutex); | 142 | mutex_unlock(&dev->struct_mutex); |
139 | 143 | ||
140 | /* Clear the HWS virtual address at teardown */ | 144 | /* Clear the HWS virtual address at teardown */ |
@@ -148,6 +152,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | |||
148 | { | 152 | { |
149 | drm_i915_private_t *dev_priv = dev->dev_private; | 153 | drm_i915_private_t *dev_priv = dev->dev_private; |
150 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | 154 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; |
155 | struct intel_ring_buffer *ring = LP_RING(dev_priv); | ||
151 | 156 | ||
152 | master_priv->sarea = drm_getsarea(dev); | 157 | master_priv->sarea = drm_getsarea(dev); |
153 | if (master_priv->sarea) { | 158 | if (master_priv->sarea) { |
@@ -158,24 +163,24 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | |||
158 | } | 163 | } |
159 | 164 | ||
160 | if (init->ring_size != 0) { | 165 | if (init->ring_size != 0) { |
161 | if (dev_priv->render_ring.gem_object != NULL) { | 166 | if (ring->obj != NULL) { |
162 | i915_dma_cleanup(dev); | 167 | i915_dma_cleanup(dev); |
163 | DRM_ERROR("Client tried to initialize ringbuffer in " | 168 | DRM_ERROR("Client tried to initialize ringbuffer in " |
164 | "GEM mode\n"); | 169 | "GEM mode\n"); |
165 | return -EINVAL; | 170 | return -EINVAL; |
166 | } | 171 | } |
167 | 172 | ||
168 | dev_priv->render_ring.size = init->ring_size; | 173 | ring->size = init->ring_size; |
169 | 174 | ||
170 | dev_priv->render_ring.map.offset = init->ring_start; | 175 | ring->map.offset = init->ring_start; |
171 | dev_priv->render_ring.map.size = init->ring_size; | 176 | ring->map.size = init->ring_size; |
172 | dev_priv->render_ring.map.type = 0; | 177 | ring->map.type = 0; |
173 | dev_priv->render_ring.map.flags = 0; | 178 | ring->map.flags = 0; |
174 | dev_priv->render_ring.map.mtrr = 0; | 179 | ring->map.mtrr = 0; |
175 | 180 | ||
176 | drm_core_ioremap_wc(&dev_priv->render_ring.map, dev); | 181 | drm_core_ioremap_wc(&ring->map, dev); |
177 | 182 | ||
178 | if (dev_priv->render_ring.map.handle == NULL) { | 183 | if (ring->map.handle == NULL) { |
179 | i915_dma_cleanup(dev); | 184 | i915_dma_cleanup(dev); |
180 | DRM_ERROR("can not ioremap virtual address for" | 185 | DRM_ERROR("can not ioremap virtual address for" |
181 | " ring buffer\n"); | 186 | " ring buffer\n"); |
@@ -183,7 +188,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | |||
183 | } | 188 | } |
184 | } | 189 | } |
185 | 190 | ||
186 | dev_priv->render_ring.virtual_start = dev_priv->render_ring.map.handle; | 191 | ring->virtual_start = ring->map.handle; |
187 | 192 | ||
188 | dev_priv->cpp = init->cpp; | 193 | dev_priv->cpp = init->cpp; |
189 | dev_priv->back_offset = init->back_offset; | 194 | dev_priv->back_offset = init->back_offset; |
@@ -202,12 +207,10 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | |||
202 | static int i915_dma_resume(struct drm_device * dev) | 207 | static int i915_dma_resume(struct drm_device * dev) |
203 | { | 208 | { |
204 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 209 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
210 | struct intel_ring_buffer *ring = LP_RING(dev_priv); | ||
205 | 211 | ||
206 | struct intel_ring_buffer *ring; | ||
207 | DRM_DEBUG_DRIVER("%s\n", __func__); | 212 | DRM_DEBUG_DRIVER("%s\n", __func__); |
208 | 213 | ||
209 | ring = &dev_priv->render_ring; | ||
210 | |||
211 | if (ring->map.handle == NULL) { | 214 | if (ring->map.handle == NULL) { |
212 | DRM_ERROR("can not ioremap virtual address for" | 215 | DRM_ERROR("can not ioremap virtual address for" |
213 | " ring buffer\n"); | 216 | " ring buffer\n"); |
@@ -222,7 +225,7 @@ static int i915_dma_resume(struct drm_device * dev) | |||
222 | DRM_DEBUG_DRIVER("hw status page @ %p\n", | 225 | DRM_DEBUG_DRIVER("hw status page @ %p\n", |
223 | ring->status_page.page_addr); | 226 | ring->status_page.page_addr); |
224 | if (ring->status_page.gfx_addr != 0) | 227 | if (ring->status_page.gfx_addr != 0) |
225 | intel_ring_setup_status_page(dev, ring); | 228 | intel_ring_setup_status_page(ring); |
226 | else | 229 | else |
227 | I915_WRITE(HWS_PGA, dev_priv->dma_status_page); | 230 | I915_WRITE(HWS_PGA, dev_priv->dma_status_page); |
228 | 231 | ||
@@ -264,7 +267,7 @@ static int i915_dma_init(struct drm_device *dev, void *data, | |||
264 | * instruction detected will be given a size of zero, which is a | 267 | * instruction detected will be given a size of zero, which is a |
265 | * signal to abort the rest of the buffer. | 268 | * signal to abort the rest of the buffer. |
266 | */ | 269 | */ |
267 | static int do_validate_cmd(int cmd) | 270 | static int validate_cmd(int cmd) |
268 | { | 271 | { |
269 | switch (((cmd >> 29) & 0x7)) { | 272 | switch (((cmd >> 29) & 0x7)) { |
270 | case 0x0: | 273 | case 0x0: |
@@ -322,40 +325,27 @@ static int do_validate_cmd(int cmd) | |||
322 | return 0; | 325 | return 0; |
323 | } | 326 | } |
324 | 327 | ||
325 | static int validate_cmd(int cmd) | ||
326 | { | ||
327 | int ret = do_validate_cmd(cmd); | ||
328 | |||
329 | /* printk("validate_cmd( %x ): %d\n", cmd, ret); */ | ||
330 | |||
331 | return ret; | ||
332 | } | ||
333 | |||
334 | static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) | 328 | static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) |
335 | { | 329 | { |
336 | drm_i915_private_t *dev_priv = dev->dev_private; | 330 | drm_i915_private_t *dev_priv = dev->dev_private; |
337 | int i; | 331 | int i, ret; |
338 | 332 | ||
339 | if ((dwords+1) * sizeof(int) >= dev_priv->render_ring.size - 8) | 333 | if ((dwords+1) * sizeof(int) >= LP_RING(dev_priv)->size - 8) |
340 | return -EINVAL; | 334 | return -EINVAL; |
341 | 335 | ||
342 | BEGIN_LP_RING((dwords+1)&~1); | ||
343 | |||
344 | for (i = 0; i < dwords;) { | 336 | for (i = 0; i < dwords;) { |
345 | int cmd, sz; | 337 | int sz = validate_cmd(buffer[i]); |
346 | 338 | if (sz == 0 || i + sz > dwords) | |
347 | cmd = buffer[i]; | ||
348 | |||
349 | if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) | ||
350 | return -EINVAL; | 339 | return -EINVAL; |
351 | 340 | i += sz; | |
352 | OUT_RING(cmd); | ||
353 | |||
354 | while (++i, --sz) { | ||
355 | OUT_RING(buffer[i]); | ||
356 | } | ||
357 | } | 341 | } |
358 | 342 | ||
343 | ret = BEGIN_LP_RING((dwords+1)&~1); | ||
344 | if (ret) | ||
345 | return ret; | ||
346 | |||
347 | for (i = 0; i < dwords; i++) | ||
348 | OUT_RING(buffer[i]); | ||
359 | if (dwords & 1) | 349 | if (dwords & 1) |
360 | OUT_RING(0); | 350 | OUT_RING(0); |
361 | 351 | ||
@@ -366,34 +356,41 @@ static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) | |||
366 | 356 | ||
367 | int | 357 | int |
368 | i915_emit_box(struct drm_device *dev, | 358 | i915_emit_box(struct drm_device *dev, |
369 | struct drm_clip_rect *boxes, | 359 | struct drm_clip_rect *box, |
370 | int i, int DR1, int DR4) | 360 | int DR1, int DR4) |
371 | { | 361 | { |
372 | struct drm_clip_rect box = boxes[i]; | 362 | struct drm_i915_private *dev_priv = dev->dev_private; |
363 | int ret; | ||
373 | 364 | ||
374 | if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { | 365 | if (box->y2 <= box->y1 || box->x2 <= box->x1 || |
366 | box->y2 <= 0 || box->x2 <= 0) { | ||
375 | DRM_ERROR("Bad box %d,%d..%d,%d\n", | 367 | DRM_ERROR("Bad box %d,%d..%d,%d\n", |
376 | box.x1, box.y1, box.x2, box.y2); | 368 | box->x1, box->y1, box->x2, box->y2); |
377 | return -EINVAL; | 369 | return -EINVAL; |
378 | } | 370 | } |
379 | 371 | ||
380 | if (INTEL_INFO(dev)->gen >= 4) { | 372 | if (INTEL_INFO(dev)->gen >= 4) { |
381 | BEGIN_LP_RING(4); | 373 | ret = BEGIN_LP_RING(4); |
374 | if (ret) | ||
375 | return ret; | ||
376 | |||
382 | OUT_RING(GFX_OP_DRAWRECT_INFO_I965); | 377 | OUT_RING(GFX_OP_DRAWRECT_INFO_I965); |
383 | OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); | 378 | OUT_RING((box->x1 & 0xffff) | (box->y1 << 16)); |
384 | OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); | 379 | OUT_RING(((box->x2 - 1) & 0xffff) | ((box->y2 - 1) << 16)); |
385 | OUT_RING(DR4); | 380 | OUT_RING(DR4); |
386 | ADVANCE_LP_RING(); | ||
387 | } else { | 381 | } else { |
388 | BEGIN_LP_RING(6); | 382 | ret = BEGIN_LP_RING(6); |
383 | if (ret) | ||
384 | return ret; | ||
385 | |||
389 | OUT_RING(GFX_OP_DRAWRECT_INFO); | 386 | OUT_RING(GFX_OP_DRAWRECT_INFO); |
390 | OUT_RING(DR1); | 387 | OUT_RING(DR1); |
391 | OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); | 388 | OUT_RING((box->x1 & 0xffff) | (box->y1 << 16)); |
392 | OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); | 389 | OUT_RING(((box->x2 - 1) & 0xffff) | ((box->y2 - 1) << 16)); |
393 | OUT_RING(DR4); | 390 | OUT_RING(DR4); |
394 | OUT_RING(0); | 391 | OUT_RING(0); |
395 | ADVANCE_LP_RING(); | ||
396 | } | 392 | } |
393 | ADVANCE_LP_RING(); | ||
397 | 394 | ||
398 | return 0; | 395 | return 0; |
399 | } | 396 | } |
@@ -413,12 +410,13 @@ static void i915_emit_breadcrumb(struct drm_device *dev) | |||
413 | if (master_priv->sarea_priv) | 410 | if (master_priv->sarea_priv) |
414 | master_priv->sarea_priv->last_enqueue = dev_priv->counter; | 411 | master_priv->sarea_priv->last_enqueue = dev_priv->counter; |
415 | 412 | ||
416 | BEGIN_LP_RING(4); | 413 | if (BEGIN_LP_RING(4) == 0) { |
417 | OUT_RING(MI_STORE_DWORD_INDEX); | 414 | OUT_RING(MI_STORE_DWORD_INDEX); |
418 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | 415 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
419 | OUT_RING(dev_priv->counter); | 416 | OUT_RING(dev_priv->counter); |
420 | OUT_RING(0); | 417 | OUT_RING(0); |
421 | ADVANCE_LP_RING(); | 418 | ADVANCE_LP_RING(); |
419 | } | ||
422 | } | 420 | } |
423 | 421 | ||
424 | static int i915_dispatch_cmdbuffer(struct drm_device * dev, | 422 | static int i915_dispatch_cmdbuffer(struct drm_device * dev, |
@@ -440,7 +438,7 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev, | |||
440 | 438 | ||
441 | for (i = 0; i < count; i++) { | 439 | for (i = 0; i < count; i++) { |
442 | if (i < nbox) { | 440 | if (i < nbox) { |
443 | ret = i915_emit_box(dev, cliprects, i, | 441 | ret = i915_emit_box(dev, &cliprects[i], |
444 | cmd->DR1, cmd->DR4); | 442 | cmd->DR1, cmd->DR4); |
445 | if (ret) | 443 | if (ret) |
446 | return ret; | 444 | return ret; |
@@ -459,8 +457,9 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, | |||
459 | drm_i915_batchbuffer_t * batch, | 457 | drm_i915_batchbuffer_t * batch, |
460 | struct drm_clip_rect *cliprects) | 458 | struct drm_clip_rect *cliprects) |
461 | { | 459 | { |
460 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
462 | int nbox = batch->num_cliprects; | 461 | int nbox = batch->num_cliprects; |
463 | int i = 0, count; | 462 | int i, count, ret; |
464 | 463 | ||
465 | if ((batch->start | batch->used) & 0x7) { | 464 | if ((batch->start | batch->used) & 0x7) { |
466 | DRM_ERROR("alignment"); | 465 | DRM_ERROR("alignment"); |
@@ -470,17 +469,19 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, | |||
470 | i915_kernel_lost_context(dev); | 469 | i915_kernel_lost_context(dev); |
471 | 470 | ||
472 | count = nbox ? nbox : 1; | 471 | count = nbox ? nbox : 1; |
473 | |||
474 | for (i = 0; i < count; i++) { | 472 | for (i = 0; i < count; i++) { |
475 | if (i < nbox) { | 473 | if (i < nbox) { |
476 | int ret = i915_emit_box(dev, cliprects, i, | 474 | ret = i915_emit_box(dev, &cliprects[i], |
477 | batch->DR1, batch->DR4); | 475 | batch->DR1, batch->DR4); |
478 | if (ret) | 476 | if (ret) |
479 | return ret; | 477 | return ret; |
480 | } | 478 | } |
481 | 479 | ||
482 | if (!IS_I830(dev) && !IS_845G(dev)) { | 480 | if (!IS_I830(dev) && !IS_845G(dev)) { |
483 | BEGIN_LP_RING(2); | 481 | ret = BEGIN_LP_RING(2); |
482 | if (ret) | ||
483 | return ret; | ||
484 | |||
484 | if (INTEL_INFO(dev)->gen >= 4) { | 485 | if (INTEL_INFO(dev)->gen >= 4) { |
485 | OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); | 486 | OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); |
486 | OUT_RING(batch->start); | 487 | OUT_RING(batch->start); |
@@ -488,26 +489,29 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, | |||
488 | OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); | 489 | OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); |
489 | OUT_RING(batch->start | MI_BATCH_NON_SECURE); | 490 | OUT_RING(batch->start | MI_BATCH_NON_SECURE); |
490 | } | 491 | } |
491 | ADVANCE_LP_RING(); | ||
492 | } else { | 492 | } else { |
493 | BEGIN_LP_RING(4); | 493 | ret = BEGIN_LP_RING(4); |
494 | if (ret) | ||
495 | return ret; | ||
496 | |||
494 | OUT_RING(MI_BATCH_BUFFER); | 497 | OUT_RING(MI_BATCH_BUFFER); |
495 | OUT_RING(batch->start | MI_BATCH_NON_SECURE); | 498 | OUT_RING(batch->start | MI_BATCH_NON_SECURE); |
496 | OUT_RING(batch->start + batch->used - 4); | 499 | OUT_RING(batch->start + batch->used - 4); |
497 | OUT_RING(0); | 500 | OUT_RING(0); |
498 | ADVANCE_LP_RING(); | ||
499 | } | 501 | } |
502 | ADVANCE_LP_RING(); | ||
500 | } | 503 | } |
501 | 504 | ||
502 | 505 | ||
503 | if (IS_G4X(dev) || IS_GEN5(dev)) { | 506 | if (IS_G4X(dev) || IS_GEN5(dev)) { |
504 | BEGIN_LP_RING(2); | 507 | if (BEGIN_LP_RING(2) == 0) { |
505 | OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP); | 508 | OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP); |
506 | OUT_RING(MI_NOOP); | 509 | OUT_RING(MI_NOOP); |
507 | ADVANCE_LP_RING(); | 510 | ADVANCE_LP_RING(); |
511 | } | ||
508 | } | 512 | } |
509 | i915_emit_breadcrumb(dev); | ||
510 | 513 | ||
514 | i915_emit_breadcrumb(dev); | ||
511 | return 0; | 515 | return 0; |
512 | } | 516 | } |
513 | 517 | ||
@@ -516,6 +520,7 @@ static int i915_dispatch_flip(struct drm_device * dev) | |||
516 | drm_i915_private_t *dev_priv = dev->dev_private; | 520 | drm_i915_private_t *dev_priv = dev->dev_private; |
517 | struct drm_i915_master_private *master_priv = | 521 | struct drm_i915_master_private *master_priv = |
518 | dev->primary->master->driver_priv; | 522 | dev->primary->master->driver_priv; |
523 | int ret; | ||
519 | 524 | ||
520 | if (!master_priv->sarea_priv) | 525 | if (!master_priv->sarea_priv) |
521 | return -EINVAL; | 526 | return -EINVAL; |
@@ -527,12 +532,13 @@ static int i915_dispatch_flip(struct drm_device * dev) | |||
527 | 532 | ||
528 | i915_kernel_lost_context(dev); | 533 | i915_kernel_lost_context(dev); |
529 | 534 | ||
530 | BEGIN_LP_RING(2); | 535 | ret = BEGIN_LP_RING(10); |
536 | if (ret) | ||
537 | return ret; | ||
538 | |||
531 | OUT_RING(MI_FLUSH | MI_READ_FLUSH); | 539 | OUT_RING(MI_FLUSH | MI_READ_FLUSH); |
532 | OUT_RING(0); | 540 | OUT_RING(0); |
533 | ADVANCE_LP_RING(); | ||
534 | 541 | ||
535 | BEGIN_LP_RING(6); | ||
536 | OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); | 542 | OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); |
537 | OUT_RING(0); | 543 | OUT_RING(0); |
538 | if (dev_priv->current_page == 0) { | 544 | if (dev_priv->current_page == 0) { |
@@ -543,33 +549,32 @@ static int i915_dispatch_flip(struct drm_device * dev) | |||
543 | dev_priv->current_page = 0; | 549 | dev_priv->current_page = 0; |
544 | } | 550 | } |
545 | OUT_RING(0); | 551 | OUT_RING(0); |
546 | ADVANCE_LP_RING(); | ||
547 | 552 | ||
548 | BEGIN_LP_RING(2); | ||
549 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); | 553 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); |
550 | OUT_RING(0); | 554 | OUT_RING(0); |
555 | |||
551 | ADVANCE_LP_RING(); | 556 | ADVANCE_LP_RING(); |
552 | 557 | ||
553 | master_priv->sarea_priv->last_enqueue = dev_priv->counter++; | 558 | master_priv->sarea_priv->last_enqueue = dev_priv->counter++; |
554 | 559 | ||
555 | BEGIN_LP_RING(4); | 560 | if (BEGIN_LP_RING(4) == 0) { |
556 | OUT_RING(MI_STORE_DWORD_INDEX); | 561 | OUT_RING(MI_STORE_DWORD_INDEX); |
557 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | 562 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
558 | OUT_RING(dev_priv->counter); | 563 | OUT_RING(dev_priv->counter); |
559 | OUT_RING(0); | 564 | OUT_RING(0); |
560 | ADVANCE_LP_RING(); | 565 | ADVANCE_LP_RING(); |
566 | } | ||
561 | 567 | ||
562 | master_priv->sarea_priv->pf_current_page = dev_priv->current_page; | 568 | master_priv->sarea_priv->pf_current_page = dev_priv->current_page; |
563 | return 0; | 569 | return 0; |
564 | } | 570 | } |
565 | 571 | ||
566 | static int i915_quiescent(struct drm_device * dev) | 572 | static int i915_quiescent(struct drm_device *dev) |
567 | { | 573 | { |
568 | drm_i915_private_t *dev_priv = dev->dev_private; | 574 | struct intel_ring_buffer *ring = LP_RING(dev->dev_private); |
569 | 575 | ||
570 | i915_kernel_lost_context(dev); | 576 | i915_kernel_lost_context(dev); |
571 | return intel_wait_ring_buffer(dev, &dev_priv->render_ring, | 577 | return intel_wait_ring_buffer(ring, ring->size - 8); |
572 | dev_priv->render_ring.size - 8); | ||
573 | } | 578 | } |
574 | 579 | ||
575 | static int i915_flush_ioctl(struct drm_device *dev, void *data, | 580 | static int i915_flush_ioctl(struct drm_device *dev, void *data, |
@@ -768,9 +773,15 @@ static int i915_getparam(struct drm_device *dev, void *data, | |||
768 | case I915_PARAM_HAS_BLT: | 773 | case I915_PARAM_HAS_BLT: |
769 | value = HAS_BLT(dev); | 774 | value = HAS_BLT(dev); |
770 | break; | 775 | break; |
776 | case I915_PARAM_HAS_RELAXED_FENCING: | ||
777 | value = 1; | ||
778 | break; | ||
771 | case I915_PARAM_HAS_COHERENT_RINGS: | 779 | case I915_PARAM_HAS_COHERENT_RINGS: |
772 | value = 1; | 780 | value = 1; |
773 | break; | 781 | break; |
782 | case I915_PARAM_HAS_EXEC_CONSTANTS: | ||
783 | value = INTEL_INFO(dev)->gen >= 4; | ||
784 | break; | ||
774 | default: | 785 | default: |
775 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", | 786 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", |
776 | param->param); | 787 | param->param); |
@@ -826,7 +837,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
826 | { | 837 | { |
827 | drm_i915_private_t *dev_priv = dev->dev_private; | 838 | drm_i915_private_t *dev_priv = dev->dev_private; |
828 | drm_i915_hws_addr_t *hws = data; | 839 | drm_i915_hws_addr_t *hws = data; |
829 | struct intel_ring_buffer *ring = &dev_priv->render_ring; | 840 | struct intel_ring_buffer *ring = LP_RING(dev_priv); |
830 | 841 | ||
831 | if (!I915_NEED_GFX_HWS(dev)) | 842 | if (!I915_NEED_GFX_HWS(dev)) |
832 | return -EINVAL; | 843 | return -EINVAL; |
@@ -1005,73 +1016,47 @@ intel_teardown_mchbar(struct drm_device *dev) | |||
1005 | #define PTE_VALID (1 << 0) | 1016 | #define PTE_VALID (1 << 0) |
1006 | 1017 | ||
1007 | /** | 1018 | /** |
1008 | * i915_gtt_to_phys - take a GTT address and turn it into a physical one | 1019 | * i915_stolen_to_phys - take an offset into stolen memory and turn it into |
1020 | * a physical one | ||
1009 | * @dev: drm device | 1021 | * @dev: drm device |
1010 | * @gtt_addr: address to translate | 1022 | * @offset: address to translate |
1011 | * | 1023 | * |
1012 | * Some chip functions require allocations from stolen space but need the | 1024 | * Some chip functions require allocations from stolen space and need the |
1013 | * physical address of the memory in question. We use this routine | 1025 | * physical address of the memory in question. |
1014 | * to get a physical address suitable for register programming from a given | ||
1015 | * GTT address. | ||
1016 | */ | 1026 | */ |
1017 | static unsigned long i915_gtt_to_phys(struct drm_device *dev, | 1027 | static unsigned long i915_stolen_to_phys(struct drm_device *dev, u32 offset) |
1018 | unsigned long gtt_addr) | ||
1019 | { | 1028 | { |
1020 | unsigned long *gtt; | 1029 | struct drm_i915_private *dev_priv = dev->dev_private; |
1021 | unsigned long entry, phys; | 1030 | struct pci_dev *pdev = dev_priv->bridge_dev; |
1022 | int gtt_bar = IS_GEN2(dev) ? 1 : 0; | 1031 | u32 base; |
1023 | int gtt_offset, gtt_size; | 1032 | |
1024 | 1033 | #if 0 | |
1025 | if (INTEL_INFO(dev)->gen >= 4) { | 1034 | /* On the machines I have tested the Graphics Base of Stolen Memory |
1026 | if (IS_G4X(dev) || INTEL_INFO(dev)->gen > 4) { | 1035 | * is unreliable, so compute the base by subtracting the stolen memory |
1027 | gtt_offset = 2*1024*1024; | 1036 | * from the Top of Low Usable DRAM which is where the BIOS places |
1028 | gtt_size = 2*1024*1024; | 1037 | * the graphics stolen memory. |
1029 | } else { | 1038 | */ |
1030 | gtt_offset = 512*1024; | 1039 | if (INTEL_INFO(dev)->gen > 3 || IS_G33(dev)) { |
1031 | gtt_size = 512*1024; | 1040 | /* top 32bits are reserved = 0 */ |
1032 | } | 1041 | pci_read_config_dword(pdev, 0xA4, &base); |
1033 | } else { | 1042 | } else { |
1034 | gtt_bar = 3; | 1043 | /* XXX presume 8xx is the same as i915 */ |
1035 | gtt_offset = 0; | 1044 | pci_bus_read_config_dword(pdev->bus, 2, 0x5C, &base); |
1036 | gtt_size = pci_resource_len(dev->pdev, gtt_bar); | 1045 | } |
1037 | } | 1046 | #else |
1038 | 1047 | if (INTEL_INFO(dev)->gen > 3 || IS_G33(dev)) { | |
1039 | gtt = ioremap_wc(pci_resource_start(dev->pdev, gtt_bar) + gtt_offset, | 1048 | u16 val; |
1040 | gtt_size); | 1049 | pci_read_config_word(pdev, 0xb0, &val); |
1041 | if (!gtt) { | 1050 | base = val >> 4 << 20; |
1042 | DRM_ERROR("ioremap of GTT failed\n"); | 1051 | } else { |
1043 | return 0; | 1052 | u8 val; |
1044 | } | 1053 | pci_read_config_byte(pdev, 0x9c, &val); |
1045 | 1054 | base = val >> 3 << 27; | |
1046 | entry = *(volatile u32 *)(gtt + (gtt_addr / 1024)); | ||
1047 | |||
1048 | DRM_DEBUG_DRIVER("GTT addr: 0x%08lx, PTE: 0x%08lx\n", gtt_addr, entry); | ||
1049 | |||
1050 | /* Mask out these reserved bits on this hardware. */ | ||
1051 | if (INTEL_INFO(dev)->gen < 4 && !IS_G33(dev)) | ||
1052 | entry &= ~PTE_ADDRESS_MASK_HIGH; | ||
1053 | |||
1054 | /* If it's not a mapping type we know, then bail. */ | ||
1055 | if ((entry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_UNCACHED && | ||
1056 | (entry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_CACHED) { | ||
1057 | iounmap(gtt); | ||
1058 | return 0; | ||
1059 | } | ||
1060 | |||
1061 | if (!(entry & PTE_VALID)) { | ||
1062 | DRM_ERROR("bad GTT entry in stolen space\n"); | ||
1063 | iounmap(gtt); | ||
1064 | return 0; | ||
1065 | } | 1055 | } |
1056 | base -= dev_priv->mm.gtt->stolen_size; | ||
1057 | #endif | ||
1066 | 1058 | ||
1067 | iounmap(gtt); | 1059 | return base + offset; |
1068 | |||
1069 | phys =(entry & PTE_ADDRESS_MASK) | | ||
1070 | ((uint64_t)(entry & PTE_ADDRESS_MASK_HIGH) << (32 - 4)); | ||
1071 | |||
1072 | DRM_DEBUG_DRIVER("GTT addr: 0x%08lx, phys addr: 0x%08lx\n", gtt_addr, phys); | ||
1073 | |||
1074 | return phys; | ||
1075 | } | 1060 | } |
1076 | 1061 | ||
1077 | static void i915_warn_stolen(struct drm_device *dev) | 1062 | static void i915_warn_stolen(struct drm_device *dev) |
@@ -1087,54 +1072,35 @@ static void i915_setup_compression(struct drm_device *dev, int size) | |||
1087 | unsigned long cfb_base; | 1072 | unsigned long cfb_base; |
1088 | unsigned long ll_base = 0; | 1073 | unsigned long ll_base = 0; |
1089 | 1074 | ||
1090 | /* Leave 1M for line length buffer & misc. */ | 1075 | compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096, 0); |
1091 | compressed_fb = drm_mm_search_free(&dev_priv->mm.vram, size, 4096, 0); | 1076 | if (compressed_fb) |
1092 | if (!compressed_fb) { | 1077 | compressed_fb = drm_mm_get_block(compressed_fb, size, 4096); |
1093 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; | 1078 | if (!compressed_fb) |
1094 | i915_warn_stolen(dev); | 1079 | goto err; |
1095 | return; | ||
1096 | } | ||
1097 | 1080 | ||
1098 | compressed_fb = drm_mm_get_block(compressed_fb, size, 4096); | 1081 | cfb_base = i915_stolen_to_phys(dev, compressed_fb->start); |
1099 | if (!compressed_fb) { | 1082 | if (!cfb_base) |
1100 | i915_warn_stolen(dev); | 1083 | goto err_fb; |
1101 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; | ||
1102 | return; | ||
1103 | } | ||
1104 | 1084 | ||
1105 | cfb_base = i915_gtt_to_phys(dev, compressed_fb->start); | 1085 | if (!(IS_GM45(dev) || HAS_PCH_SPLIT(dev))) { |
1106 | if (!cfb_base) { | 1086 | compressed_llb = drm_mm_search_free(&dev_priv->mm.stolen, |
1107 | DRM_ERROR("failed to get stolen phys addr, disabling FBC\n"); | 1087 | 4096, 4096, 0); |
1108 | drm_mm_put_block(compressed_fb); | 1088 | if (compressed_llb) |
1109 | } | 1089 | compressed_llb = drm_mm_get_block(compressed_llb, |
1090 | 4096, 4096); | ||
1091 | if (!compressed_llb) | ||
1092 | goto err_fb; | ||
1110 | 1093 | ||
1111 | if (!(IS_GM45(dev) || IS_IRONLAKE_M(dev))) { | 1094 | ll_base = i915_stolen_to_phys(dev, compressed_llb->start); |
1112 | compressed_llb = drm_mm_search_free(&dev_priv->mm.vram, 4096, | 1095 | if (!ll_base) |
1113 | 4096, 0); | 1096 | goto err_llb; |
1114 | if (!compressed_llb) { | ||
1115 | i915_warn_stolen(dev); | ||
1116 | return; | ||
1117 | } | ||
1118 | |||
1119 | compressed_llb = drm_mm_get_block(compressed_llb, 4096, 4096); | ||
1120 | if (!compressed_llb) { | ||
1121 | i915_warn_stolen(dev); | ||
1122 | return; | ||
1123 | } | ||
1124 | |||
1125 | ll_base = i915_gtt_to_phys(dev, compressed_llb->start); | ||
1126 | if (!ll_base) { | ||
1127 | DRM_ERROR("failed to get stolen phys addr, disabling FBC\n"); | ||
1128 | drm_mm_put_block(compressed_fb); | ||
1129 | drm_mm_put_block(compressed_llb); | ||
1130 | } | ||
1131 | } | 1097 | } |
1132 | 1098 | ||
1133 | dev_priv->cfb_size = size; | 1099 | dev_priv->cfb_size = size; |
1134 | 1100 | ||
1135 | intel_disable_fbc(dev); | 1101 | intel_disable_fbc(dev); |
1136 | dev_priv->compressed_fb = compressed_fb; | 1102 | dev_priv->compressed_fb = compressed_fb; |
1137 | if (IS_IRONLAKE_M(dev)) | 1103 | if (HAS_PCH_SPLIT(dev)) |
1138 | I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start); | 1104 | I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start); |
1139 | else if (IS_GM45(dev)) { | 1105 | else if (IS_GM45(dev)) { |
1140 | I915_WRITE(DPFC_CB_BASE, compressed_fb->start); | 1106 | I915_WRITE(DPFC_CB_BASE, compressed_fb->start); |
@@ -1144,8 +1110,17 @@ static void i915_setup_compression(struct drm_device *dev, int size) | |||
1144 | dev_priv->compressed_llb = compressed_llb; | 1110 | dev_priv->compressed_llb = compressed_llb; |
1145 | } | 1111 | } |
1146 | 1112 | ||
1147 | DRM_DEBUG_KMS("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base, | 1113 | DRM_DEBUG_KMS("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", |
1148 | ll_base, size >> 20); | 1114 | cfb_base, ll_base, size >> 20); |
1115 | return; | ||
1116 | |||
1117 | err_llb: | ||
1118 | drm_mm_put_block(compressed_llb); | ||
1119 | err_fb: | ||
1120 | drm_mm_put_block(compressed_fb); | ||
1121 | err: | ||
1122 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; | ||
1123 | i915_warn_stolen(dev); | ||
1149 | } | 1124 | } |
1150 | 1125 | ||
1151 | static void i915_cleanup_compression(struct drm_device *dev) | 1126 | static void i915_cleanup_compression(struct drm_device *dev) |
@@ -1176,12 +1151,16 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_ | |||
1176 | pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; | 1151 | pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; |
1177 | if (state == VGA_SWITCHEROO_ON) { | 1152 | if (state == VGA_SWITCHEROO_ON) { |
1178 | printk(KERN_INFO "i915: switched on\n"); | 1153 | printk(KERN_INFO "i915: switched on\n"); |
1154 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | ||
1179 | /* i915 resume handler doesn't set to D0 */ | 1155 | /* i915 resume handler doesn't set to D0 */ |
1180 | pci_set_power_state(dev->pdev, PCI_D0); | 1156 | pci_set_power_state(dev->pdev, PCI_D0); |
1181 | i915_resume(dev); | 1157 | i915_resume(dev); |
1158 | dev->switch_power_state = DRM_SWITCH_POWER_ON; | ||
1182 | } else { | 1159 | } else { |
1183 | printk(KERN_ERR "i915: switched off\n"); | 1160 | printk(KERN_ERR "i915: switched off\n"); |
1161 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | ||
1184 | i915_suspend(dev, pmm); | 1162 | i915_suspend(dev, pmm); |
1163 | dev->switch_power_state = DRM_SWITCH_POWER_OFF; | ||
1185 | } | 1164 | } |
1186 | } | 1165 | } |
1187 | 1166 | ||
@@ -1196,17 +1175,20 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev) | |||
1196 | return can_switch; | 1175 | return can_switch; |
1197 | } | 1176 | } |
1198 | 1177 | ||
1199 | static int i915_load_modeset_init(struct drm_device *dev, | 1178 | static int i915_load_modeset_init(struct drm_device *dev) |
1200 | unsigned long prealloc_size, | ||
1201 | unsigned long agp_size) | ||
1202 | { | 1179 | { |
1203 | struct drm_i915_private *dev_priv = dev->dev_private; | 1180 | struct drm_i915_private *dev_priv = dev->dev_private; |
1181 | unsigned long prealloc_size, gtt_size, mappable_size; | ||
1204 | int ret = 0; | 1182 | int ret = 0; |
1205 | 1183 | ||
1206 | /* Basic memrange allocator for stolen space (aka mm.vram) */ | 1184 | prealloc_size = dev_priv->mm.gtt->stolen_size; |
1207 | drm_mm_init(&dev_priv->mm.vram, 0, prealloc_size); | 1185 | gtt_size = dev_priv->mm.gtt->gtt_total_entries << PAGE_SHIFT; |
1186 | mappable_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; | ||
1208 | 1187 | ||
1209 | /* Let GEM Manage from end of prealloc space to end of aperture. | 1188 | /* Basic memrange allocator for stolen space */ |
1189 | drm_mm_init(&dev_priv->mm.stolen, 0, prealloc_size); | ||
1190 | |||
1191 | /* Let GEM Manage all of the aperture. | ||
1210 | * | 1192 | * |
1211 | * However, leave one page at the end still bound to the scratch page. | 1193 | * However, leave one page at the end still bound to the scratch page. |
1212 | * There are a number of places where the hardware apparently | 1194 | * There are a number of places where the hardware apparently |
@@ -1215,7 +1197,7 @@ static int i915_load_modeset_init(struct drm_device *dev, | |||
1215 | * at the last page of the aperture. One page should be enough to | 1197 | * at the last page of the aperture. One page should be enough to |
1216 | * keep any prefetching inside of the aperture. | 1198 | * keep any prefetching inside of the aperture. |
1217 | */ | 1199 | */ |
1218 | i915_gem_do_init(dev, prealloc_size, agp_size - 4096); | 1200 | i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE); |
1219 | 1201 | ||
1220 | mutex_lock(&dev->struct_mutex); | 1202 | mutex_lock(&dev->struct_mutex); |
1221 | ret = i915_gem_init_ringbuffer(dev); | 1203 | ret = i915_gem_init_ringbuffer(dev); |
@@ -1227,16 +1209,17 @@ static int i915_load_modeset_init(struct drm_device *dev, | |||
1227 | if (I915_HAS_FBC(dev) && i915_powersave) { | 1209 | if (I915_HAS_FBC(dev) && i915_powersave) { |
1228 | int cfb_size; | 1210 | int cfb_size; |
1229 | 1211 | ||
1230 | /* Try to get an 8M buffer... */ | 1212 | /* Leave 1M for line length buffer & misc. */ |
1231 | if (prealloc_size > (9*1024*1024)) | 1213 | |
1232 | cfb_size = 8*1024*1024; | 1214 | /* Try to get a 32M buffer... */ |
1215 | if (prealloc_size > (36*1024*1024)) | ||
1216 | cfb_size = 32*1024*1024; | ||
1233 | else /* fall back to 7/8 of the stolen space */ | 1217 | else /* fall back to 7/8 of the stolen space */ |
1234 | cfb_size = prealloc_size * 7 / 8; | 1218 | cfb_size = prealloc_size * 7 / 8; |
1235 | i915_setup_compression(dev, cfb_size); | 1219 | i915_setup_compression(dev, cfb_size); |
1236 | } | 1220 | } |
1237 | 1221 | ||
1238 | /* Allow hardware batchbuffers unless told otherwise. | 1222 | /* Allow hardware batchbuffers unless told otherwise. */ |
1239 | */ | ||
1240 | dev_priv->allow_batchbuffer = 1; | 1223 | dev_priv->allow_batchbuffer = 1; |
1241 | 1224 | ||
1242 | ret = intel_parse_bios(dev); | 1225 | ret = intel_parse_bios(dev); |
@@ -1252,6 +1235,7 @@ static int i915_load_modeset_init(struct drm_device *dev, | |||
1252 | 1235 | ||
1253 | ret = vga_switcheroo_register_client(dev->pdev, | 1236 | ret = vga_switcheroo_register_client(dev->pdev, |
1254 | i915_switcheroo_set_state, | 1237 | i915_switcheroo_set_state, |
1238 | NULL, | ||
1255 | i915_switcheroo_can_switch); | 1239 | i915_switcheroo_can_switch); |
1256 | if (ret) | 1240 | if (ret) |
1257 | goto cleanup_vga_client; | 1241 | goto cleanup_vga_client; |
@@ -1426,152 +1410,12 @@ static void i915_ironlake_get_mem_freq(struct drm_device *dev) | |||
1426 | } | 1410 | } |
1427 | } | 1411 | } |
1428 | 1412 | ||
1429 | struct v_table { | 1413 | static const struct cparams { |
1430 | u8 vid; | 1414 | u16 i; |
1431 | unsigned long vd; /* in .1 mil */ | 1415 | u16 t; |
1432 | unsigned long vm; /* in .1 mil */ | 1416 | u16 m; |
1433 | u8 pvid; | 1417 | u16 c; |
1434 | }; | 1418 | } cparams[] = { |
1435 | |||
1436 | static struct v_table v_table[] = { | ||
1437 | { 0, 16125, 15000, 0x7f, }, | ||
1438 | { 1, 16000, 14875, 0x7e, }, | ||
1439 | { 2, 15875, 14750, 0x7d, }, | ||
1440 | { 3, 15750, 14625, 0x7c, }, | ||
1441 | { 4, 15625, 14500, 0x7b, }, | ||
1442 | { 5, 15500, 14375, 0x7a, }, | ||
1443 | { 6, 15375, 14250, 0x79, }, | ||
1444 | { 7, 15250, 14125, 0x78, }, | ||
1445 | { 8, 15125, 14000, 0x77, }, | ||
1446 | { 9, 15000, 13875, 0x76, }, | ||
1447 | { 10, 14875, 13750, 0x75, }, | ||
1448 | { 11, 14750, 13625, 0x74, }, | ||
1449 | { 12, 14625, 13500, 0x73, }, | ||
1450 | { 13, 14500, 13375, 0x72, }, | ||
1451 | { 14, 14375, 13250, 0x71, }, | ||
1452 | { 15, 14250, 13125, 0x70, }, | ||
1453 | { 16, 14125, 13000, 0x6f, }, | ||
1454 | { 17, 14000, 12875, 0x6e, }, | ||
1455 | { 18, 13875, 12750, 0x6d, }, | ||
1456 | { 19, 13750, 12625, 0x6c, }, | ||
1457 | { 20, 13625, 12500, 0x6b, }, | ||
1458 | { 21, 13500, 12375, 0x6a, }, | ||
1459 | { 22, 13375, 12250, 0x69, }, | ||
1460 | { 23, 13250, 12125, 0x68, }, | ||
1461 | { 24, 13125, 12000, 0x67, }, | ||
1462 | { 25, 13000, 11875, 0x66, }, | ||
1463 | { 26, 12875, 11750, 0x65, }, | ||
1464 | { 27, 12750, 11625, 0x64, }, | ||
1465 | { 28, 12625, 11500, 0x63, }, | ||
1466 | { 29, 12500, 11375, 0x62, }, | ||
1467 | { 30, 12375, 11250, 0x61, }, | ||
1468 | { 31, 12250, 11125, 0x60, }, | ||
1469 | { 32, 12125, 11000, 0x5f, }, | ||
1470 | { 33, 12000, 10875, 0x5e, }, | ||
1471 | { 34, 11875, 10750, 0x5d, }, | ||
1472 | { 35, 11750, 10625, 0x5c, }, | ||
1473 | { 36, 11625, 10500, 0x5b, }, | ||
1474 | { 37, 11500, 10375, 0x5a, }, | ||
1475 | { 38, 11375, 10250, 0x59, }, | ||
1476 | { 39, 11250, 10125, 0x58, }, | ||
1477 | { 40, 11125, 10000, 0x57, }, | ||
1478 | { 41, 11000, 9875, 0x56, }, | ||
1479 | { 42, 10875, 9750, 0x55, }, | ||
1480 | { 43, 10750, 9625, 0x54, }, | ||
1481 | { 44, 10625, 9500, 0x53, }, | ||
1482 | { 45, 10500, 9375, 0x52, }, | ||
1483 | { 46, 10375, 9250, 0x51, }, | ||
1484 | { 47, 10250, 9125, 0x50, }, | ||
1485 | { 48, 10125, 9000, 0x4f, }, | ||
1486 | { 49, 10000, 8875, 0x4e, }, | ||
1487 | { 50, 9875, 8750, 0x4d, }, | ||
1488 | { 51, 9750, 8625, 0x4c, }, | ||
1489 | { 52, 9625, 8500, 0x4b, }, | ||
1490 | { 53, 9500, 8375, 0x4a, }, | ||
1491 | { 54, 9375, 8250, 0x49, }, | ||
1492 | { 55, 9250, 8125, 0x48, }, | ||
1493 | { 56, 9125, 8000, 0x47, }, | ||
1494 | { 57, 9000, 7875, 0x46, }, | ||
1495 | { 58, 8875, 7750, 0x45, }, | ||
1496 | { 59, 8750, 7625, 0x44, }, | ||
1497 | { 60, 8625, 7500, 0x43, }, | ||
1498 | { 61, 8500, 7375, 0x42, }, | ||
1499 | { 62, 8375, 7250, 0x41, }, | ||
1500 | { 63, 8250, 7125, 0x40, }, | ||
1501 | { 64, 8125, 7000, 0x3f, }, | ||
1502 | { 65, 8000, 6875, 0x3e, }, | ||
1503 | { 66, 7875, 6750, 0x3d, }, | ||
1504 | { 67, 7750, 6625, 0x3c, }, | ||
1505 | { 68, 7625, 6500, 0x3b, }, | ||
1506 | { 69, 7500, 6375, 0x3a, }, | ||
1507 | { 70, 7375, 6250, 0x39, }, | ||
1508 | { 71, 7250, 6125, 0x38, }, | ||
1509 | { 72, 7125, 6000, 0x37, }, | ||
1510 | { 73, 7000, 5875, 0x36, }, | ||
1511 | { 74, 6875, 5750, 0x35, }, | ||
1512 | { 75, 6750, 5625, 0x34, }, | ||
1513 | { 76, 6625, 5500, 0x33, }, | ||
1514 | { 77, 6500, 5375, 0x32, }, | ||
1515 | { 78, 6375, 5250, 0x31, }, | ||
1516 | { 79, 6250, 5125, 0x30, }, | ||
1517 | { 80, 6125, 5000, 0x2f, }, | ||
1518 | { 81, 6000, 4875, 0x2e, }, | ||
1519 | { 82, 5875, 4750, 0x2d, }, | ||
1520 | { 83, 5750, 4625, 0x2c, }, | ||
1521 | { 84, 5625, 4500, 0x2b, }, | ||
1522 | { 85, 5500, 4375, 0x2a, }, | ||
1523 | { 86, 5375, 4250, 0x29, }, | ||
1524 | { 87, 5250, 4125, 0x28, }, | ||
1525 | { 88, 5125, 4000, 0x27, }, | ||
1526 | { 89, 5000, 3875, 0x26, }, | ||
1527 | { 90, 4875, 3750, 0x25, }, | ||
1528 | { 91, 4750, 3625, 0x24, }, | ||
1529 | { 92, 4625, 3500, 0x23, }, | ||
1530 | { 93, 4500, 3375, 0x22, }, | ||
1531 | { 94, 4375, 3250, 0x21, }, | ||
1532 | { 95, 4250, 3125, 0x20, }, | ||
1533 | { 96, 4125, 3000, 0x1f, }, | ||
1534 | { 97, 4125, 3000, 0x1e, }, | ||
1535 | { 98, 4125, 3000, 0x1d, }, | ||
1536 | { 99, 4125, 3000, 0x1c, }, | ||
1537 | { 100, 4125, 3000, 0x1b, }, | ||
1538 | { 101, 4125, 3000, 0x1a, }, | ||
1539 | { 102, 4125, 3000, 0x19, }, | ||
1540 | { 103, 4125, 3000, 0x18, }, | ||
1541 | { 104, 4125, 3000, 0x17, }, | ||
1542 | { 105, 4125, 3000, 0x16, }, | ||
1543 | { 106, 4125, 3000, 0x15, }, | ||
1544 | { 107, 4125, 3000, 0x14, }, | ||
1545 | { 108, 4125, 3000, 0x13, }, | ||
1546 | { 109, 4125, 3000, 0x12, }, | ||
1547 | { 110, 4125, 3000, 0x11, }, | ||
1548 | { 111, 4125, 3000, 0x10, }, | ||
1549 | { 112, 4125, 3000, 0x0f, }, | ||
1550 | { 113, 4125, 3000, 0x0e, }, | ||
1551 | { 114, 4125, 3000, 0x0d, }, | ||
1552 | { 115, 4125, 3000, 0x0c, }, | ||
1553 | { 116, 4125, 3000, 0x0b, }, | ||
1554 | { 117, 4125, 3000, 0x0a, }, | ||
1555 | { 118, 4125, 3000, 0x09, }, | ||
1556 | { 119, 4125, 3000, 0x08, }, | ||
1557 | { 120, 1125, 0, 0x07, }, | ||
1558 | { 121, 1000, 0, 0x06, }, | ||
1559 | { 122, 875, 0, 0x05, }, | ||
1560 | { 123, 750, 0, 0x04, }, | ||
1561 | { 124, 625, 0, 0x03, }, | ||
1562 | { 125, 500, 0, 0x02, }, | ||
1563 | { 126, 375, 0, 0x01, }, | ||
1564 | { 127, 0, 0, 0x00, }, | ||
1565 | }; | ||
1566 | |||
1567 | struct cparams { | ||
1568 | int i; | ||
1569 | int t; | ||
1570 | int m; | ||
1571 | int c; | ||
1572 | }; | ||
1573 | |||
1574 | static struct cparams cparams[] = { | ||
1575 | { 1, 1333, 301, 28664 }, | 1419 | { 1, 1333, 301, 28664 }, |
1576 | { 1, 1066, 294, 24460 }, | 1420 | { 1, 1066, 294, 24460 }, |
1577 | { 1, 800, 294, 25192 }, | 1421 | { 1, 800, 294, 25192 }, |
@@ -1637,21 +1481,145 @@ unsigned long i915_mch_val(struct drm_i915_private *dev_priv) | |||
1637 | return ((m * x) / 127) - b; | 1481 | return ((m * x) / 127) - b; |
1638 | } | 1482 | } |
1639 | 1483 | ||
1640 | static unsigned long pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid) | 1484 | static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid) |
1641 | { | 1485 | { |
1642 | unsigned long val = 0; | 1486 | static const struct v_table { |
1643 | int i; | 1487 | u16 vd; /* in .1 mil */ |
1644 | 1488 | u16 vm; /* in .1 mil */ | |
1645 | for (i = 0; i < ARRAY_SIZE(v_table); i++) { | 1489 | } v_table[] = { |
1646 | if (v_table[i].pvid == pxvid) { | 1490 | { 0, 0, }, |
1647 | if (IS_MOBILE(dev_priv->dev)) | 1491 | { 375, 0, }, |
1648 | val = v_table[i].vm; | 1492 | { 500, 0, }, |
1649 | else | 1493 | { 625, 0, }, |
1650 | val = v_table[i].vd; | 1494 | { 750, 0, }, |
1651 | } | 1495 | { 875, 0, }, |
1652 | } | 1496 | { 1000, 0, }, |
1653 | 1497 | { 1125, 0, }, | |
1654 | return val; | 1498 | { 4125, 3000, }, |
1499 | { 4125, 3000, }, | ||
1500 | { 4125, 3000, }, | ||
1501 | { 4125, 3000, }, | ||
1502 | { 4125, 3000, }, | ||
1503 | { 4125, 3000, }, | ||
1504 | { 4125, 3000, }, | ||
1505 | { 4125, 3000, }, | ||
1506 | { 4125, 3000, }, | ||
1507 | { 4125, 3000, }, | ||
1508 | { 4125, 3000, }, | ||
1509 | { 4125, 3000, }, | ||
1510 | { 4125, 3000, }, | ||
1511 | { 4125, 3000, }, | ||
1512 | { 4125, 3000, }, | ||
1513 | { 4125, 3000, }, | ||
1514 | { 4125, 3000, }, | ||
1515 | { 4125, 3000, }, | ||
1516 | { 4125, 3000, }, | ||
1517 | { 4125, 3000, }, | ||
1518 | { 4125, 3000, }, | ||
1519 | { 4125, 3000, }, | ||
1520 | { 4125, 3000, }, | ||
1521 | { 4125, 3000, }, | ||
1522 | { 4250, 3125, }, | ||
1523 | { 4375, 3250, }, | ||
1524 | { 4500, 3375, }, | ||
1525 | { 4625, 3500, }, | ||
1526 | { 4750, 3625, }, | ||
1527 | { 4875, 3750, }, | ||
1528 | { 5000, 3875, }, | ||
1529 | { 5125, 4000, }, | ||
1530 | { 5250, 4125, }, | ||
1531 | { 5375, 4250, }, | ||
1532 | { 5500, 4375, }, | ||
1533 | { 5625, 4500, }, | ||
1534 | { 5750, 4625, }, | ||
1535 | { 5875, 4750, }, | ||
1536 | { 6000, 4875, }, | ||
1537 | { 6125, 5000, }, | ||
1538 | { 6250, 5125, }, | ||
1539 | { 6375, 5250, }, | ||
1540 | { 6500, 5375, }, | ||
1541 | { 6625, 5500, }, | ||
1542 | { 6750, 5625, }, | ||
1543 | { 6875, 5750, }, | ||
1544 | { 7000, 5875, }, | ||
1545 | { 7125, 6000, }, | ||
1546 | { 7250, 6125, }, | ||
1547 | { 7375, 6250, }, | ||
1548 | { 7500, 6375, }, | ||
1549 | { 7625, 6500, }, | ||
1550 | { 7750, 6625, }, | ||
1551 | { 7875, 6750, }, | ||
1552 | { 8000, 6875, }, | ||
1553 | { 8125, 7000, }, | ||
1554 | { 8250, 7125, }, | ||
1555 | { 8375, 7250, }, | ||
1556 | { 8500, 7375, }, | ||
1557 | { 8625, 7500, }, | ||
1558 | { 8750, 7625, }, | ||
1559 | { 8875, 7750, }, | ||
1560 | { 9000, 7875, }, | ||
1561 | { 9125, 8000, }, | ||
1562 | { 9250, 8125, }, | ||
1563 | { 9375, 8250, }, | ||
1564 | { 9500, 8375, }, | ||
1565 | { 9625, 8500, }, | ||
1566 | { 9750, 8625, }, | ||
1567 | { 9875, 8750, }, | ||
1568 | { 10000, 8875, }, | ||
1569 | { 10125, 9000, }, | ||
1570 | { 10250, 9125, }, | ||
1571 | { 10375, 9250, }, | ||
1572 | { 10500, 9375, }, | ||
1573 | { 10625, 9500, }, | ||
1574 | { 10750, 9625, }, | ||
1575 | { 10875, 9750, }, | ||
1576 | { 11000, 9875, }, | ||
1577 | { 11125, 10000, }, | ||
1578 | { 11250, 10125, }, | ||
1579 | { 11375, 10250, }, | ||
1580 | { 11500, 10375, }, | ||
1581 | { 11625, 10500, }, | ||
1582 | { 11750, 10625, }, | ||
1583 | { 11875, 10750, }, | ||
1584 | { 12000, 10875, }, | ||
1585 | { 12125, 11000, }, | ||
1586 | { 12250, 11125, }, | ||
1587 | { 12375, 11250, }, | ||
1588 | { 12500, 11375, }, | ||
1589 | { 12625, 11500, }, | ||
1590 | { 12750, 11625, }, | ||
1591 | { 12875, 11750, }, | ||
1592 | { 13000, 11875, }, | ||
1593 | { 13125, 12000, }, | ||
1594 | { 13250, 12125, }, | ||
1595 | { 13375, 12250, }, | ||
1596 | { 13500, 12375, }, | ||
1597 | { 13625, 12500, }, | ||
1598 | { 13750, 12625, }, | ||
1599 | { 13875, 12750, }, | ||
1600 | { 14000, 12875, }, | ||
1601 | { 14125, 13000, }, | ||
1602 | { 14250, 13125, }, | ||
1603 | { 14375, 13250, }, | ||
1604 | { 14500, 13375, }, | ||
1605 | { 14625, 13500, }, | ||
1606 | { 14750, 13625, }, | ||
1607 | { 14875, 13750, }, | ||
1608 | { 15000, 13875, }, | ||
1609 | { 15125, 14000, }, | ||
1610 | { 15250, 14125, }, | ||
1611 | { 15375, 14250, }, | ||
1612 | { 15500, 14375, }, | ||
1613 | { 15625, 14500, }, | ||
1614 | { 15750, 14625, }, | ||
1615 | { 15875, 14750, }, | ||
1616 | { 16000, 14875, }, | ||
1617 | { 16125, 15000, }, | ||
1618 | }; | ||
1619 | if (dev_priv->info->is_mobile) | ||
1620 | return v_table[pxvid].vm; | ||
1621 | else | ||
1622 | return v_table[pxvid].vd; | ||
1655 | } | 1623 | } |
1656 | 1624 | ||
1657 | void i915_update_gfx_val(struct drm_i915_private *dev_priv) | 1625 | void i915_update_gfx_val(struct drm_i915_private *dev_priv) |
@@ -1905,9 +1873,9 @@ ips_ping_for_i915_load(void) | |||
1905 | int i915_driver_load(struct drm_device *dev, unsigned long flags) | 1873 | int i915_driver_load(struct drm_device *dev, unsigned long flags) |
1906 | { | 1874 | { |
1907 | struct drm_i915_private *dev_priv; | 1875 | struct drm_i915_private *dev_priv; |
1908 | resource_size_t base, size; | ||
1909 | int ret = 0, mmio_bar; | 1876 | int ret = 0, mmio_bar; |
1910 | uint32_t agp_size, prealloc_size; | 1877 | uint32_t agp_size; |
1878 | |||
1911 | /* i915 has 4 more counters */ | 1879 | /* i915 has 4 more counters */ |
1912 | dev->counters += 4; | 1880 | dev->counters += 4; |
1913 | dev->types[6] = _DRM_STAT_IRQ; | 1881 | dev->types[6] = _DRM_STAT_IRQ; |
@@ -1923,11 +1891,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1923 | dev_priv->dev = dev; | 1891 | dev_priv->dev = dev; |
1924 | dev_priv->info = (struct intel_device_info *) flags; | 1892 | dev_priv->info = (struct intel_device_info *) flags; |
1925 | 1893 | ||
1926 | /* Add register map (needed for suspend/resume) */ | ||
1927 | mmio_bar = IS_GEN2(dev) ? 1 : 0; | ||
1928 | base = pci_resource_start(dev->pdev, mmio_bar); | ||
1929 | size = pci_resource_len(dev->pdev, mmio_bar); | ||
1930 | |||
1931 | if (i915_get_bridge_dev(dev)) { | 1894 | if (i915_get_bridge_dev(dev)) { |
1932 | ret = -EIO; | 1895 | ret = -EIO; |
1933 | goto free_priv; | 1896 | goto free_priv; |
@@ -1937,16 +1900,25 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1937 | if (IS_GEN2(dev)) | 1900 | if (IS_GEN2(dev)) |
1938 | dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); | 1901 | dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); |
1939 | 1902 | ||
1940 | dev_priv->regs = ioremap(base, size); | 1903 | mmio_bar = IS_GEN2(dev) ? 1 : 0; |
1904 | dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, 0); | ||
1941 | if (!dev_priv->regs) { | 1905 | if (!dev_priv->regs) { |
1942 | DRM_ERROR("failed to map registers\n"); | 1906 | DRM_ERROR("failed to map registers\n"); |
1943 | ret = -EIO; | 1907 | ret = -EIO; |
1944 | goto put_bridge; | 1908 | goto put_bridge; |
1945 | } | 1909 | } |
1946 | 1910 | ||
1911 | dev_priv->mm.gtt = intel_gtt_get(); | ||
1912 | if (!dev_priv->mm.gtt) { | ||
1913 | DRM_ERROR("Failed to initialize GTT\n"); | ||
1914 | ret = -ENODEV; | ||
1915 | goto out_iomapfree; | ||
1916 | } | ||
1917 | |||
1918 | agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; | ||
1919 | |||
1947 | dev_priv->mm.gtt_mapping = | 1920 | dev_priv->mm.gtt_mapping = |
1948 | io_mapping_create_wc(dev->agp->base, | 1921 | io_mapping_create_wc(dev->agp->base, agp_size); |
1949 | dev->agp->agp_info.aper_size * 1024*1024); | ||
1950 | if (dev_priv->mm.gtt_mapping == NULL) { | 1922 | if (dev_priv->mm.gtt_mapping == NULL) { |
1951 | ret = -EIO; | 1923 | ret = -EIO; |
1952 | goto out_rmmap; | 1924 | goto out_rmmap; |
@@ -1958,24 +1930,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1958 | * MTRR if present. Even if a UC MTRR isn't present. | 1930 | * MTRR if present. Even if a UC MTRR isn't present. |
1959 | */ | 1931 | */ |
1960 | dev_priv->mm.gtt_mtrr = mtrr_add(dev->agp->base, | 1932 | dev_priv->mm.gtt_mtrr = mtrr_add(dev->agp->base, |
1961 | dev->agp->agp_info.aper_size * | 1933 | agp_size, |
1962 | 1024 * 1024, | ||
1963 | MTRR_TYPE_WRCOMB, 1); | 1934 | MTRR_TYPE_WRCOMB, 1); |
1964 | if (dev_priv->mm.gtt_mtrr < 0) { | 1935 | if (dev_priv->mm.gtt_mtrr < 0) { |
1965 | DRM_INFO("MTRR allocation failed. Graphics " | 1936 | DRM_INFO("MTRR allocation failed. Graphics " |
1966 | "performance may suffer.\n"); | 1937 | "performance may suffer.\n"); |
1967 | } | 1938 | } |
1968 | 1939 | ||
1969 | dev_priv->mm.gtt = intel_gtt_get(); | ||
1970 | if (!dev_priv->mm.gtt) { | ||
1971 | DRM_ERROR("Failed to initialize GTT\n"); | ||
1972 | ret = -ENODEV; | ||
1973 | goto out_iomapfree; | ||
1974 | } | ||
1975 | |||
1976 | prealloc_size = dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT; | ||
1977 | agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; | ||
1978 | |||
1979 | /* The i915 workqueue is primarily used for batched retirement of | 1940 | /* The i915 workqueue is primarily used for batched retirement of |
1980 | * requests (and thus managing bo) once the task has been completed | 1941 | * requests (and thus managing bo) once the task has been completed |
1981 | * by the GPU. i915_gem_retire_requests() is called directly when we | 1942 | * by the GPU. i915_gem_retire_requests() is called directly when we |
@@ -1983,7 +1944,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1983 | * bo. | 1944 | * bo. |
1984 | * | 1945 | * |
1985 | * It is also used for periodic low-priority events, such as | 1946 | * It is also used for periodic low-priority events, such as |
1986 | * idle-timers and hangcheck. | 1947 | * idle-timers and recording error state. |
1987 | * | 1948 | * |
1988 | * All tasks on the workqueue are expected to acquire the dev mutex | 1949 | * All tasks on the workqueue are expected to acquire the dev mutex |
1989 | * so there is no point in running more than one instance of the | 1950 | * so there is no point in running more than one instance of the |
@@ -2001,20 +1962,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2001 | /* enable GEM by default */ | 1962 | /* enable GEM by default */ |
2002 | dev_priv->has_gem = 1; | 1963 | dev_priv->has_gem = 1; |
2003 | 1964 | ||
2004 | if (prealloc_size > agp_size * 3 / 4) { | ||
2005 | DRM_ERROR("Detected broken video BIOS with %d/%dkB of video " | ||
2006 | "memory stolen.\n", | ||
2007 | prealloc_size / 1024, agp_size / 1024); | ||
2008 | DRM_ERROR("Disabling GEM. (try reducing stolen memory or " | ||
2009 | "updating the BIOS to fix).\n"); | ||
2010 | dev_priv->has_gem = 0; | ||
2011 | } | ||
2012 | |||
2013 | if (dev_priv->has_gem == 0 && | 1965 | if (dev_priv->has_gem == 0 && |
2014 | drm_core_check_feature(dev, DRIVER_MODESET)) { | 1966 | drm_core_check_feature(dev, DRIVER_MODESET)) { |
2015 | DRM_ERROR("kernel modesetting requires GEM, disabling driver.\n"); | 1967 | DRM_ERROR("kernel modesetting requires GEM, disabling driver.\n"); |
2016 | ret = -ENODEV; | 1968 | ret = -ENODEV; |
2017 | goto out_iomapfree; | 1969 | goto out_workqueue_free; |
2018 | } | 1970 | } |
2019 | 1971 | ||
2020 | dev->driver->get_vblank_counter = i915_get_vblank_counter; | 1972 | dev->driver->get_vblank_counter = i915_get_vblank_counter; |
@@ -2037,8 +1989,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2037 | /* Init HWS */ | 1989 | /* Init HWS */ |
2038 | if (!I915_NEED_GFX_HWS(dev)) { | 1990 | if (!I915_NEED_GFX_HWS(dev)) { |
2039 | ret = i915_init_phys_hws(dev); | 1991 | ret = i915_init_phys_hws(dev); |
2040 | if (ret != 0) | 1992 | if (ret) |
2041 | goto out_workqueue_free; | 1993 | goto out_gem_unload; |
2042 | } | 1994 | } |
2043 | 1995 | ||
2044 | if (IS_PINEVIEW(dev)) | 1996 | if (IS_PINEVIEW(dev)) |
@@ -2060,16 +2012,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2060 | if (!IS_I945G(dev) && !IS_I945GM(dev)) | 2012 | if (!IS_I945G(dev) && !IS_I945GM(dev)) |
2061 | pci_enable_msi(dev->pdev); | 2013 | pci_enable_msi(dev->pdev); |
2062 | 2014 | ||
2063 | spin_lock_init(&dev_priv->user_irq_lock); | 2015 | spin_lock_init(&dev_priv->irq_lock); |
2064 | spin_lock_init(&dev_priv->error_lock); | 2016 | spin_lock_init(&dev_priv->error_lock); |
2065 | dev_priv->trace_irq_seqno = 0; | 2017 | dev_priv->trace_irq_seqno = 0; |
2066 | 2018 | ||
2067 | ret = drm_vblank_init(dev, I915_NUM_PIPE); | 2019 | ret = drm_vblank_init(dev, I915_NUM_PIPE); |
2068 | 2020 | if (ret) | |
2069 | if (ret) { | 2021 | goto out_gem_unload; |
2070 | (void) i915_driver_unload(dev); | ||
2071 | return ret; | ||
2072 | } | ||
2073 | 2022 | ||
2074 | /* Start out suspended */ | 2023 | /* Start out suspended */ |
2075 | dev_priv->mm.suspended = 1; | 2024 | dev_priv->mm.suspended = 1; |
@@ -2077,10 +2026,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2077 | intel_detect_pch(dev); | 2026 | intel_detect_pch(dev); |
2078 | 2027 | ||
2079 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 2028 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
2080 | ret = i915_load_modeset_init(dev, prealloc_size, agp_size); | 2029 | ret = i915_load_modeset_init(dev); |
2081 | if (ret < 0) { | 2030 | if (ret < 0) { |
2082 | DRM_ERROR("failed to init modeset\n"); | 2031 | DRM_ERROR("failed to init modeset\n"); |
2083 | goto out_workqueue_free; | 2032 | goto out_gem_unload; |
2084 | } | 2033 | } |
2085 | } | 2034 | } |
2086 | 2035 | ||
@@ -2100,12 +2049,18 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2100 | 2049 | ||
2101 | return 0; | 2050 | return 0; |
2102 | 2051 | ||
2052 | out_gem_unload: | ||
2053 | if (dev->pdev->msi_enabled) | ||
2054 | pci_disable_msi(dev->pdev); | ||
2055 | |||
2056 | intel_teardown_gmbus(dev); | ||
2057 | intel_teardown_mchbar(dev); | ||
2103 | out_workqueue_free: | 2058 | out_workqueue_free: |
2104 | destroy_workqueue(dev_priv->wq); | 2059 | destroy_workqueue(dev_priv->wq); |
2105 | out_iomapfree: | 2060 | out_iomapfree: |
2106 | io_mapping_free(dev_priv->mm.gtt_mapping); | 2061 | io_mapping_free(dev_priv->mm.gtt_mapping); |
2107 | out_rmmap: | 2062 | out_rmmap: |
2108 | iounmap(dev_priv->regs); | 2063 | pci_iounmap(dev->pdev, dev_priv->regs); |
2109 | put_bridge: | 2064 | put_bridge: |
2110 | pci_dev_put(dev_priv->bridge_dev); | 2065 | pci_dev_put(dev_priv->bridge_dev); |
2111 | free_priv: | 2066 | free_priv: |
@@ -2122,6 +2077,9 @@ int i915_driver_unload(struct drm_device *dev) | |||
2122 | i915_mch_dev = NULL; | 2077 | i915_mch_dev = NULL; |
2123 | spin_unlock(&mchdev_lock); | 2078 | spin_unlock(&mchdev_lock); |
2124 | 2079 | ||
2080 | if (dev_priv->mm.inactive_shrinker.shrink) | ||
2081 | unregister_shrinker(&dev_priv->mm.inactive_shrinker); | ||
2082 | |||
2125 | mutex_lock(&dev->struct_mutex); | 2083 | mutex_lock(&dev->struct_mutex); |
2126 | ret = i915_gpu_idle(dev); | 2084 | ret = i915_gpu_idle(dev); |
2127 | if (ret) | 2085 | if (ret) |
@@ -2179,7 +2137,7 @@ int i915_driver_unload(struct drm_device *dev) | |||
2179 | mutex_unlock(&dev->struct_mutex); | 2137 | mutex_unlock(&dev->struct_mutex); |
2180 | if (I915_HAS_FBC(dev) && i915_powersave) | 2138 | if (I915_HAS_FBC(dev) && i915_powersave) |
2181 | i915_cleanup_compression(dev); | 2139 | i915_cleanup_compression(dev); |
2182 | drm_mm_takedown(&dev_priv->mm.vram); | 2140 | drm_mm_takedown(&dev_priv->mm.stolen); |
2183 | 2141 | ||
2184 | intel_cleanup_overlay(dev); | 2142 | intel_cleanup_overlay(dev); |
2185 | 2143 | ||
@@ -2188,7 +2146,7 @@ int i915_driver_unload(struct drm_device *dev) | |||
2188 | } | 2146 | } |
2189 | 2147 | ||
2190 | if (dev_priv->regs != NULL) | 2148 | if (dev_priv->regs != NULL) |
2191 | iounmap(dev_priv->regs); | 2149 | pci_iounmap(dev->pdev, dev_priv->regs); |
2192 | 2150 | ||
2193 | intel_teardown_gmbus(dev); | 2151 | intel_teardown_gmbus(dev); |
2194 | intel_teardown_mchbar(dev); | 2152 | intel_teardown_mchbar(dev); |