diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_dma.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 81 |
1 files changed, 50 insertions, 31 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index afa8a12cd009..dacdf3c577cb 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -39,6 +39,7 @@ | |||
39 | int i915_wait_ring(struct drm_device * dev, int n, const char *caller) | 39 | int i915_wait_ring(struct drm_device * dev, int n, const char *caller) |
40 | { | 40 | { |
41 | drm_i915_private_t *dev_priv = dev->dev_private; | 41 | drm_i915_private_t *dev_priv = dev->dev_private; |
42 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | ||
42 | drm_i915_ring_buffer_t *ring = &(dev_priv->ring); | 43 | drm_i915_ring_buffer_t *ring = &(dev_priv->ring); |
43 | u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; | 44 | u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; |
44 | u32 last_acthd = I915_READ(acthd_reg); | 45 | u32 last_acthd = I915_READ(acthd_reg); |
@@ -55,8 +56,8 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller) | |||
55 | if (ring->space >= n) | 56 | if (ring->space >= n) |
56 | return 0; | 57 | return 0; |
57 | 58 | ||
58 | if (dev_priv->sarea_priv) | 59 | if (master_priv->sarea_priv) |
59 | dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; | 60 | master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; |
60 | 61 | ||
61 | if (ring->head != last_head) | 62 | if (ring->head != last_head) |
62 | i = 0; | 63 | i = 0; |
@@ -121,6 +122,7 @@ static void i915_free_hws(struct drm_device *dev) | |||
121 | void i915_kernel_lost_context(struct drm_device * dev) | 122 | void i915_kernel_lost_context(struct drm_device * dev) |
122 | { | 123 | { |
123 | drm_i915_private_t *dev_priv = dev->dev_private; | 124 | drm_i915_private_t *dev_priv = dev->dev_private; |
125 | struct drm_i915_master_private *master_priv; | ||
124 | drm_i915_ring_buffer_t *ring = &(dev_priv->ring); | 126 | drm_i915_ring_buffer_t *ring = &(dev_priv->ring); |
125 | 127 | ||
126 | ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | 128 | ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; |
@@ -129,8 +131,12 @@ void i915_kernel_lost_context(struct drm_device * dev) | |||
129 | if (ring->space < 0) | 131 | if (ring->space < 0) |
130 | ring->space += ring->Size; | 132 | ring->space += ring->Size; |
131 | 133 | ||
132 | if (ring->head == ring->tail && dev_priv->sarea_priv) | 134 | if (!dev->primary->master) |
133 | dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; | 135 | return; |
136 | |||
137 | master_priv = dev->primary->master->driver_priv; | ||
138 | if (ring->head == ring->tail && master_priv->sarea_priv) | ||
139 | master_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; | ||
134 | } | 140 | } |
135 | 141 | ||
136 | static int i915_dma_cleanup(struct drm_device * dev) | 142 | static int i915_dma_cleanup(struct drm_device * dev) |
@@ -154,25 +160,13 @@ static int i915_dma_cleanup(struct drm_device * dev) | |||
154 | if (I915_NEED_GFX_HWS(dev)) | 160 | if (I915_NEED_GFX_HWS(dev)) |
155 | i915_free_hws(dev); | 161 | i915_free_hws(dev); |
156 | 162 | ||
157 | dev_priv->sarea = NULL; | ||
158 | dev_priv->sarea_priv = NULL; | ||
159 | |||
160 | return 0; | 163 | return 0; |
161 | } | 164 | } |
162 | 165 | ||
163 | static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | 166 | static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) |
164 | { | 167 | { |
165 | drm_i915_private_t *dev_priv = dev->dev_private; | 168 | drm_i915_private_t *dev_priv = dev->dev_private; |
166 | 169 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | |
167 | dev_priv->sarea = drm_getsarea(dev); | ||
168 | if (!dev_priv->sarea) { | ||
169 | DRM_ERROR("can not find sarea!\n"); | ||
170 | i915_dma_cleanup(dev); | ||
171 | return -EINVAL; | ||
172 | } | ||
173 | |||
174 | dev_priv->sarea_priv = (drm_i915_sarea_t *) | ||
175 | ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); | ||
176 | 170 | ||
177 | if (init->ring_size != 0) { | 171 | if (init->ring_size != 0) { |
178 | if (dev_priv->ring.ring_obj != NULL) { | 172 | if (dev_priv->ring.ring_obj != NULL) { |
@@ -207,7 +201,8 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | |||
207 | dev_priv->back_offset = init->back_offset; | 201 | dev_priv->back_offset = init->back_offset; |
208 | dev_priv->front_offset = init->front_offset; | 202 | dev_priv->front_offset = init->front_offset; |
209 | dev_priv->current_page = 0; | 203 | dev_priv->current_page = 0; |
210 | dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; | 204 | if (master_priv->sarea_priv) |
205 | master_priv->sarea_priv->pf_current_page = 0; | ||
211 | 206 | ||
212 | /* Allow hardware batchbuffers unless told otherwise. | 207 | /* Allow hardware batchbuffers unless told otherwise. |
213 | */ | 208 | */ |
@@ -222,11 +217,6 @@ static int i915_dma_resume(struct drm_device * dev) | |||
222 | 217 | ||
223 | DRM_DEBUG("%s\n", __func__); | 218 | DRM_DEBUG("%s\n", __func__); |
224 | 219 | ||
225 | if (!dev_priv->sarea) { | ||
226 | DRM_ERROR("can not find sarea!\n"); | ||
227 | return -EINVAL; | ||
228 | } | ||
229 | |||
230 | if (dev_priv->ring.map.handle == NULL) { | 220 | if (dev_priv->ring.map.handle == NULL) { |
231 | DRM_ERROR("can not ioremap virtual address for" | 221 | DRM_ERROR("can not ioremap virtual address for" |
232 | " ring buffer\n"); | 222 | " ring buffer\n"); |
@@ -435,13 +425,14 @@ i915_emit_box(struct drm_device *dev, | |||
435 | static void i915_emit_breadcrumb(struct drm_device *dev) | 425 | static void i915_emit_breadcrumb(struct drm_device *dev) |
436 | { | 426 | { |
437 | drm_i915_private_t *dev_priv = dev->dev_private; | 427 | drm_i915_private_t *dev_priv = dev->dev_private; |
428 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | ||
438 | RING_LOCALS; | 429 | RING_LOCALS; |
439 | 430 | ||
440 | dev_priv->counter++; | 431 | dev_priv->counter++; |
441 | if (dev_priv->counter > 0x7FFFFFFFUL) | 432 | if (dev_priv->counter > 0x7FFFFFFFUL) |
442 | dev_priv->counter = 0; | 433 | dev_priv->counter = 0; |
443 | if (dev_priv->sarea_priv) | 434 | if (master_priv->sarea_priv) |
444 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter; | 435 | master_priv->sarea_priv->last_enqueue = dev_priv->counter; |
445 | 436 | ||
446 | BEGIN_LP_RING(4); | 437 | BEGIN_LP_RING(4); |
447 | OUT_RING(MI_STORE_DWORD_INDEX); | 438 | OUT_RING(MI_STORE_DWORD_INDEX); |
@@ -537,15 +528,17 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, | |||
537 | static int i915_dispatch_flip(struct drm_device * dev) | 528 | static int i915_dispatch_flip(struct drm_device * dev) |
538 | { | 529 | { |
539 | drm_i915_private_t *dev_priv = dev->dev_private; | 530 | drm_i915_private_t *dev_priv = dev->dev_private; |
531 | struct drm_i915_master_private *master_priv = | ||
532 | dev->primary->master->driver_priv; | ||
540 | RING_LOCALS; | 533 | RING_LOCALS; |
541 | 534 | ||
542 | if (!dev_priv->sarea_priv) | 535 | if (!master_priv->sarea_priv) |
543 | return -EINVAL; | 536 | return -EINVAL; |
544 | 537 | ||
545 | DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", | 538 | DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", |
546 | __func__, | 539 | __func__, |
547 | dev_priv->current_page, | 540 | dev_priv->current_page, |
548 | dev_priv->sarea_priv->pf_current_page); | 541 | master_priv->sarea_priv->pf_current_page); |
549 | 542 | ||
550 | i915_kernel_lost_context(dev); | 543 | i915_kernel_lost_context(dev); |
551 | 544 | ||
@@ -572,7 +565,7 @@ static int i915_dispatch_flip(struct drm_device * dev) | |||
572 | OUT_RING(0); | 565 | OUT_RING(0); |
573 | ADVANCE_LP_RING(); | 566 | ADVANCE_LP_RING(); |
574 | 567 | ||
575 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; | 568 | master_priv->sarea_priv->last_enqueue = dev_priv->counter++; |
576 | 569 | ||
577 | BEGIN_LP_RING(4); | 570 | BEGIN_LP_RING(4); |
578 | OUT_RING(MI_STORE_DWORD_INDEX); | 571 | OUT_RING(MI_STORE_DWORD_INDEX); |
@@ -581,7 +574,7 @@ static int i915_dispatch_flip(struct drm_device * dev) | |||
581 | OUT_RING(0); | 574 | OUT_RING(0); |
582 | ADVANCE_LP_RING(); | 575 | ADVANCE_LP_RING(); |
583 | 576 | ||
584 | dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; | 577 | master_priv->sarea_priv->pf_current_page = dev_priv->current_page; |
585 | return 0; | 578 | return 0; |
586 | } | 579 | } |
587 | 580 | ||
@@ -611,8 +604,9 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, | |||
611 | struct drm_file *file_priv) | 604 | struct drm_file *file_priv) |
612 | { | 605 | { |
613 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 606 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
607 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | ||
614 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) | 608 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) |
615 | dev_priv->sarea_priv; | 609 | master_priv->sarea_priv; |
616 | drm_i915_batchbuffer_t *batch = data; | 610 | drm_i915_batchbuffer_t *batch = data; |
617 | int ret; | 611 | int ret; |
618 | 612 | ||
@@ -644,8 +638,9 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
644 | struct drm_file *file_priv) | 638 | struct drm_file *file_priv) |
645 | { | 639 | { |
646 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 640 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
641 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | ||
647 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) | 642 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) |
648 | dev_priv->sarea_priv; | 643 | master_priv->sarea_priv; |
649 | drm_i915_cmdbuffer_t *cmdbuf = data; | 644 | drm_i915_cmdbuffer_t *cmdbuf = data; |
650 | int ret; | 645 | int ret; |
651 | 646 | ||
@@ -802,6 +797,30 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
802 | return 0; | 797 | return 0; |
803 | } | 798 | } |
804 | 799 | ||
800 | int i915_master_create(struct drm_device *dev, struct drm_master *master) | ||
801 | { | ||
802 | struct drm_i915_master_private *master_priv; | ||
803 | |||
804 | master_priv = drm_calloc(1, sizeof(*master_priv), DRM_MEM_DRIVER); | ||
805 | if (!master_priv) | ||
806 | return -ENOMEM; | ||
807 | |||
808 | master->driver_priv = master_priv; | ||
809 | return 0; | ||
810 | } | ||
811 | |||
812 | void i915_master_destroy(struct drm_device *dev, struct drm_master *master) | ||
813 | { | ||
814 | struct drm_i915_master_private *master_priv = master->driver_priv; | ||
815 | |||
816 | if (!master_priv) | ||
817 | return; | ||
818 | |||
819 | drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER); | ||
820 | |||
821 | master->driver_priv = NULL; | ||
822 | } | ||
823 | |||
805 | int i915_driver_load(struct drm_device *dev, unsigned long flags) | 824 | int i915_driver_load(struct drm_device *dev, unsigned long flags) |
806 | { | 825 | { |
807 | struct drm_i915_private *dev_priv = dev->dev_private; | 826 | struct drm_i915_private *dev_priv = dev->dev_private; |