diff options
author | Dave Airlie <airlied@redhat.com> | 2010-12-21 18:48:54 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-12-21 18:48:54 -0500 |
commit | ae09f09e94d755ed45c58b695675636c0ec53f9e (patch) | |
tree | 77cb9bac7d81f5b1250b8638a007e10c17b600af /drivers/gpu/drm | |
parent | 1d99e5c57255d188773fb437391df24fe8faf575 (diff) | |
parent | 5909a77ac62cc042f94bd262016cf468a2f96022 (diff) |
Merge remote branch 'intel/drm-intel-next' of /ssd/git/drm-next into drm-core-next
* 'intel/drm-intel-next' of /ssd/git/drm-next: (771 commits)
drm/i915: Undo "Uncouple render/power ctx before suspending"
drm/i915: Allow the application to choose the constant addressing mode
drm/i915: dynamic render p-state support for Sandy Bridge
drm/i915: Enable EI mode for RCx decision making on Sandybridge
drm/i915/sdvo: Border and stall select became test bits in gen5
drm/i915: Add Guess-o-matic for pageflip timestamping.
drm/i915: Add support for precise vblank timestamping (v2)
drm/i915: Add frame buffer compression on Sandybridge
drm/i915: Add self-refresh support on Sandybridge
drm/i915: Wait for vblank before unpinning old fb
Revert "drm/i915: Avoid using PIPE_CONTROL on Ironlake"
drm/i915: Pass clock limits down to PLL matcher
drm/i915: Poll for seqno completion if IRQ is disabled
drm/i915/ringbuffer: Make IRQ refcnting atomic
agp/intel: Fix missed cached memory flags setting in i965_write_entry()
drm/i915/sdvo: Only use the SDVO pin if it is in the valid range
drm/i915: Enable RC6 autodownclocking on Sandybridge
drm/i915: Terminate the FORCE WAKE after we have finished reading
drm/i915/gtt: Clear the cachelines upon resume
drm/i915: Restore GTT mapping first upon resume
...
Diffstat (limited to 'drivers/gpu/drm')
43 files changed, 6870 insertions, 4808 deletions
diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c index 252fdb98b73..0cb2ba50af5 100644 --- a/drivers/gpu/drm/drm_agpsupport.c +++ b/drivers/gpu/drm/drm_agpsupport.c | |||
@@ -466,10 +466,4 @@ drm_agp_bind_pages(struct drm_device *dev, | |||
466 | } | 466 | } |
467 | EXPORT_SYMBOL(drm_agp_bind_pages); | 467 | EXPORT_SYMBOL(drm_agp_bind_pages); |
468 | 468 | ||
469 | void drm_agp_chipset_flush(struct drm_device *dev) | ||
470 | { | ||
471 | agp_flush_chipset(dev->agp->bridge); | ||
472 | } | ||
473 | EXPORT_SYMBOL(drm_agp_chipset_flush); | ||
474 | |||
475 | #endif /* __OS_HAS_AGP */ | 469 | #endif /* __OS_HAS_AGP */ |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 4c200931a6b..c6b2e27a446 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -241,7 +241,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) | |||
241 | } | 241 | } |
242 | 242 | ||
243 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 243 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
244 | if (!drm_helper_encoder_in_use(encoder)) { | 244 | if (encoder->crtc && !drm_helper_encoder_in_use(encoder)) { |
245 | drm_encoder_disable(encoder); | 245 | drm_encoder_disable(encoder); |
246 | /* disconnector encoder from any connector */ | 246 | /* disconnector encoder from any connector */ |
247 | encoder->crtc = NULL; | 247 | encoder->crtc = NULL; |
@@ -482,6 +482,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
482 | int count = 0, ro, fail = 0; | 482 | int count = 0, ro, fail = 0; |
483 | struct drm_crtc_helper_funcs *crtc_funcs; | 483 | struct drm_crtc_helper_funcs *crtc_funcs; |
484 | int ret = 0; | 484 | int ret = 0; |
485 | int i; | ||
485 | 486 | ||
486 | DRM_DEBUG_KMS("\n"); | 487 | DRM_DEBUG_KMS("\n"); |
487 | 488 | ||
@@ -677,6 +678,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
677 | if (ret != 0) | 678 | if (ret != 0) |
678 | goto fail; | 679 | goto fail; |
679 | } | 680 | } |
681 | DRM_DEBUG_KMS("Setting connector DPMS state to on\n"); | ||
682 | for (i = 0; i < set->num_connectors; i++) { | ||
683 | DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id, | ||
684 | drm_get_connector_name(set->connectors[i])); | ||
685 | set->connectors[i]->dpms = DRM_MODE_DPMS_ON; | ||
686 | } | ||
680 | 687 | ||
681 | kfree(save_connectors); | 688 | kfree(save_connectors); |
682 | kfree(save_encoders); | 689 | kfree(save_encoders); |
@@ -852,7 +859,7 @@ static void output_poll_execute(struct work_struct *work) | |||
852 | struct delayed_work *delayed_work = to_delayed_work(work); | 859 | struct delayed_work *delayed_work = to_delayed_work(work); |
853 | struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work); | 860 | struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work); |
854 | struct drm_connector *connector; | 861 | struct drm_connector *connector; |
855 | enum drm_connector_status old_status, status; | 862 | enum drm_connector_status old_status; |
856 | bool repoll = false, changed = false; | 863 | bool repoll = false, changed = false; |
857 | 864 | ||
858 | if (!drm_kms_helper_poll) | 865 | if (!drm_kms_helper_poll) |
@@ -877,8 +884,9 @@ static void output_poll_execute(struct work_struct *work) | |||
877 | !(connector->polled & DRM_CONNECTOR_POLL_HPD)) | 884 | !(connector->polled & DRM_CONNECTOR_POLL_HPD)) |
878 | continue; | 885 | continue; |
879 | 886 | ||
880 | status = connector->funcs->detect(connector, false); | 887 | connector->status = connector->funcs->detect(connector, false); |
881 | if (old_status != status) | 888 | DRM_DEBUG_KMS("connector status updated to %d\n", connector->status); |
889 | if (old_status != connector->status) | ||
882 | changed = true; | 890 | changed = true; |
883 | } | 891 | } |
884 | 892 | ||
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 55160d7c38b..8304c42195f 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -1047,10 +1047,13 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
1047 | struct timeval now; | 1047 | struct timeval now; |
1048 | unsigned long flags; | 1048 | unsigned long flags; |
1049 | unsigned int seq; | 1049 | unsigned int seq; |
1050 | int ret; | ||
1050 | 1051 | ||
1051 | e = kzalloc(sizeof *e, GFP_KERNEL); | 1052 | e = kzalloc(sizeof *e, GFP_KERNEL); |
1052 | if (e == NULL) | 1053 | if (e == NULL) { |
1053 | return -ENOMEM; | 1054 | ret = -ENOMEM; |
1055 | goto err_put; | ||
1056 | } | ||
1054 | 1057 | ||
1055 | e->pipe = pipe; | 1058 | e->pipe = pipe; |
1056 | e->base.pid = current->pid; | 1059 | e->base.pid = current->pid; |
@@ -1064,9 +1067,8 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
1064 | spin_lock_irqsave(&dev->event_lock, flags); | 1067 | spin_lock_irqsave(&dev->event_lock, flags); |
1065 | 1068 | ||
1066 | if (file_priv->event_space < sizeof e->event) { | 1069 | if (file_priv->event_space < sizeof e->event) { |
1067 | spin_unlock_irqrestore(&dev->event_lock, flags); | 1070 | ret = -EBUSY; |
1068 | kfree(e); | 1071 | goto err_unlock; |
1069 | return -ENOMEM; | ||
1070 | } | 1072 | } |
1071 | 1073 | ||
1072 | file_priv->event_space -= sizeof e->event; | 1074 | file_priv->event_space -= sizeof e->event; |
@@ -1103,6 +1105,13 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
1103 | spin_unlock_irqrestore(&dev->event_lock, flags); | 1105 | spin_unlock_irqrestore(&dev->event_lock, flags); |
1104 | 1106 | ||
1105 | return 0; | 1107 | return 0; |
1108 | |||
1109 | err_unlock: | ||
1110 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
1111 | kfree(e); | ||
1112 | err_put: | ||
1113 | drm_vblank_put(dev, e->pipe); | ||
1114 | return ret; | ||
1106 | } | 1115 | } |
1107 | 1116 | ||
1108 | /** | 1117 | /** |
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index a6bfc302ed9..c59515ba7e6 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -392,10 +392,36 @@ void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, | |||
392 | mm->scanned_blocks = 0; | 392 | mm->scanned_blocks = 0; |
393 | mm->scan_hit_start = 0; | 393 | mm->scan_hit_start = 0; |
394 | mm->scan_hit_size = 0; | 394 | mm->scan_hit_size = 0; |
395 | mm->scan_check_range = 0; | ||
395 | } | 396 | } |
396 | EXPORT_SYMBOL(drm_mm_init_scan); | 397 | EXPORT_SYMBOL(drm_mm_init_scan); |
397 | 398 | ||
398 | /** | 399 | /** |
400 | * Initializa lru scanning. | ||
401 | * | ||
402 | * This simply sets up the scanning routines with the parameters for the desired | ||
403 | * hole. This version is for range-restricted scans. | ||
404 | * | ||
405 | * Warning: As long as the scan list is non-empty, no other operations than | ||
406 | * adding/removing nodes to/from the scan list are allowed. | ||
407 | */ | ||
408 | void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size, | ||
409 | unsigned alignment, | ||
410 | unsigned long start, | ||
411 | unsigned long end) | ||
412 | { | ||
413 | mm->scan_alignment = alignment; | ||
414 | mm->scan_size = size; | ||
415 | mm->scanned_blocks = 0; | ||
416 | mm->scan_hit_start = 0; | ||
417 | mm->scan_hit_size = 0; | ||
418 | mm->scan_start = start; | ||
419 | mm->scan_end = end; | ||
420 | mm->scan_check_range = 1; | ||
421 | } | ||
422 | EXPORT_SYMBOL(drm_mm_init_scan_with_range); | ||
423 | |||
424 | /** | ||
399 | * Add a node to the scan list that might be freed to make space for the desired | 425 | * Add a node to the scan list that might be freed to make space for the desired |
400 | * hole. | 426 | * hole. |
401 | * | 427 | * |
@@ -406,6 +432,8 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) | |||
406 | struct drm_mm *mm = node->mm; | 432 | struct drm_mm *mm = node->mm; |
407 | struct list_head *prev_free, *next_free; | 433 | struct list_head *prev_free, *next_free; |
408 | struct drm_mm_node *prev_node, *next_node; | 434 | struct drm_mm_node *prev_node, *next_node; |
435 | unsigned long adj_start; | ||
436 | unsigned long adj_end; | ||
409 | 437 | ||
410 | mm->scanned_blocks++; | 438 | mm->scanned_blocks++; |
411 | 439 | ||
@@ -452,7 +480,17 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) | |||
452 | node->free_stack.prev = prev_free; | 480 | node->free_stack.prev = prev_free; |
453 | node->free_stack.next = next_free; | 481 | node->free_stack.next = next_free; |
454 | 482 | ||
455 | if (check_free_hole(node->start, node->start + node->size, | 483 | if (mm->scan_check_range) { |
484 | adj_start = node->start < mm->scan_start ? | ||
485 | mm->scan_start : node->start; | ||
486 | adj_end = node->start + node->size > mm->scan_end ? | ||
487 | mm->scan_end : node->start + node->size; | ||
488 | } else { | ||
489 | adj_start = node->start; | ||
490 | adj_end = node->start + node->size; | ||
491 | } | ||
492 | |||
493 | if (check_free_hole(adj_start , adj_end, | ||
456 | mm->scan_size, mm->scan_alignment)) { | 494 | mm->scan_size, mm->scan_alignment)) { |
457 | mm->scan_hit_start = node->start; | 495 | mm->scan_hit_start = node->start; |
458 | mm->scan_hit_size = node->size; | 496 | mm->scan_hit_size = node->size; |
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index fdc833d5cc7..0ae6a7c5020 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -9,6 +9,8 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | |||
9 | i915_gem.o \ | 9 | i915_gem.o \ |
10 | i915_gem_debug.o \ | 10 | i915_gem_debug.o \ |
11 | i915_gem_evict.o \ | 11 | i915_gem_evict.o \ |
12 | i915_gem_execbuffer.o \ | ||
13 | i915_gem_gtt.o \ | ||
12 | i915_gem_tiling.o \ | 14 | i915_gem_tiling.o \ |
13 | i915_trace_points.o \ | 15 | i915_trace_points.o \ |
14 | intel_display.o \ | 16 | intel_display.o \ |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 1f4f3ceb63c..92f75782c33 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "drmP.h" | 32 | #include "drmP.h" |
33 | #include "drm.h" | 33 | #include "drm.h" |
34 | #include "intel_drv.h" | 34 | #include "intel_drv.h" |
35 | #include "intel_ringbuffer.h" | ||
35 | #include "i915_drm.h" | 36 | #include "i915_drm.h" |
36 | #include "i915_drv.h" | 37 | #include "i915_drv.h" |
37 | 38 | ||
@@ -72,7 +73,6 @@ static int i915_capabilities(struct seq_file *m, void *data) | |||
72 | B(is_broadwater); | 73 | B(is_broadwater); |
73 | B(is_crestline); | 74 | B(is_crestline); |
74 | B(has_fbc); | 75 | B(has_fbc); |
75 | B(has_rc6); | ||
76 | B(has_pipe_cxsr); | 76 | B(has_pipe_cxsr); |
77 | B(has_hotplug); | 77 | B(has_hotplug); |
78 | B(cursor_needs_physical); | 78 | B(cursor_needs_physical); |
@@ -86,19 +86,19 @@ static int i915_capabilities(struct seq_file *m, void *data) | |||
86 | return 0; | 86 | return 0; |
87 | } | 87 | } |
88 | 88 | ||
89 | static const char *get_pin_flag(struct drm_i915_gem_object *obj_priv) | 89 | static const char *get_pin_flag(struct drm_i915_gem_object *obj) |
90 | { | 90 | { |
91 | if (obj_priv->user_pin_count > 0) | 91 | if (obj->user_pin_count > 0) |
92 | return "P"; | 92 | return "P"; |
93 | else if (obj_priv->pin_count > 0) | 93 | else if (obj->pin_count > 0) |
94 | return "p"; | 94 | return "p"; |
95 | else | 95 | else |
96 | return " "; | 96 | return " "; |
97 | } | 97 | } |
98 | 98 | ||
99 | static const char *get_tiling_flag(struct drm_i915_gem_object *obj_priv) | 99 | static const char *get_tiling_flag(struct drm_i915_gem_object *obj) |
100 | { | 100 | { |
101 | switch (obj_priv->tiling_mode) { | 101 | switch (obj->tiling_mode) { |
102 | default: | 102 | default: |
103 | case I915_TILING_NONE: return " "; | 103 | case I915_TILING_NONE: return " "; |
104 | case I915_TILING_X: return "X"; | 104 | case I915_TILING_X: return "X"; |
@@ -109,7 +109,7 @@ static const char *get_tiling_flag(struct drm_i915_gem_object *obj_priv) | |||
109 | static void | 109 | static void |
110 | describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) | 110 | describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) |
111 | { | 111 | { |
112 | seq_printf(m, "%p: %s%s %8zd %08x %08x %d%s%s", | 112 | seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d%s%s", |
113 | &obj->base, | 113 | &obj->base, |
114 | get_pin_flag(obj), | 114 | get_pin_flag(obj), |
115 | get_tiling_flag(obj), | 115 | get_tiling_flag(obj), |
@@ -117,6 +117,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) | |||
117 | obj->base.read_domains, | 117 | obj->base.read_domains, |
118 | obj->base.write_domain, | 118 | obj->base.write_domain, |
119 | obj->last_rendering_seqno, | 119 | obj->last_rendering_seqno, |
120 | obj->last_fenced_seqno, | ||
120 | obj->dirty ? " dirty" : "", | 121 | obj->dirty ? " dirty" : "", |
121 | obj->madv == I915_MADV_DONTNEED ? " purgeable" : ""); | 122 | obj->madv == I915_MADV_DONTNEED ? " purgeable" : ""); |
122 | if (obj->base.name) | 123 | if (obj->base.name) |
@@ -124,7 +125,17 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) | |||
124 | if (obj->fence_reg != I915_FENCE_REG_NONE) | 125 | if (obj->fence_reg != I915_FENCE_REG_NONE) |
125 | seq_printf(m, " (fence: %d)", obj->fence_reg); | 126 | seq_printf(m, " (fence: %d)", obj->fence_reg); |
126 | if (obj->gtt_space != NULL) | 127 | if (obj->gtt_space != NULL) |
127 | seq_printf(m, " (gtt_offset: %08x)", obj->gtt_offset); | 128 | seq_printf(m, " (gtt offset: %08x, size: %08x)", |
129 | obj->gtt_offset, (unsigned int)obj->gtt_space->size); | ||
130 | if (obj->pin_mappable || obj->fault_mappable) { | ||
131 | char s[3], *t = s; | ||
132 | if (obj->pin_mappable) | ||
133 | *t++ = 'p'; | ||
134 | if (obj->fault_mappable) | ||
135 | *t++ = 'f'; | ||
136 | *t = '\0'; | ||
137 | seq_printf(m, " (%s mappable)", s); | ||
138 | } | ||
128 | if (obj->ring != NULL) | 139 | if (obj->ring != NULL) |
129 | seq_printf(m, " (%s)", obj->ring->name); | 140 | seq_printf(m, " (%s)", obj->ring->name); |
130 | } | 141 | } |
@@ -136,7 +147,7 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
136 | struct list_head *head; | 147 | struct list_head *head; |
137 | struct drm_device *dev = node->minor->dev; | 148 | struct drm_device *dev = node->minor->dev; |
138 | drm_i915_private_t *dev_priv = dev->dev_private; | 149 | drm_i915_private_t *dev_priv = dev->dev_private; |
139 | struct drm_i915_gem_object *obj_priv; | 150 | struct drm_i915_gem_object *obj; |
140 | size_t total_obj_size, total_gtt_size; | 151 | size_t total_obj_size, total_gtt_size; |
141 | int count, ret; | 152 | int count, ret; |
142 | 153 | ||
@@ -171,12 +182,12 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
171 | } | 182 | } |
172 | 183 | ||
173 | total_obj_size = total_gtt_size = count = 0; | 184 | total_obj_size = total_gtt_size = count = 0; |
174 | list_for_each_entry(obj_priv, head, mm_list) { | 185 | list_for_each_entry(obj, head, mm_list) { |
175 | seq_printf(m, " "); | 186 | seq_printf(m, " "); |
176 | describe_obj(m, obj_priv); | 187 | describe_obj(m, obj); |
177 | seq_printf(m, "\n"); | 188 | seq_printf(m, "\n"); |
178 | total_obj_size += obj_priv->base.size; | 189 | total_obj_size += obj->base.size; |
179 | total_gtt_size += obj_priv->gtt_space->size; | 190 | total_gtt_size += obj->gtt_space->size; |
180 | count++; | 191 | count++; |
181 | } | 192 | } |
182 | mutex_unlock(&dev->struct_mutex); | 193 | mutex_unlock(&dev->struct_mutex); |
@@ -186,24 +197,79 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
186 | return 0; | 197 | return 0; |
187 | } | 198 | } |
188 | 199 | ||
200 | #define count_objects(list, member) do { \ | ||
201 | list_for_each_entry(obj, list, member) { \ | ||
202 | size += obj->gtt_space->size; \ | ||
203 | ++count; \ | ||
204 | if (obj->map_and_fenceable) { \ | ||
205 | mappable_size += obj->gtt_space->size; \ | ||
206 | ++mappable_count; \ | ||
207 | } \ | ||
208 | } \ | ||
209 | } while(0) | ||
210 | |||
189 | static int i915_gem_object_info(struct seq_file *m, void* data) | 211 | static int i915_gem_object_info(struct seq_file *m, void* data) |
190 | { | 212 | { |
191 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 213 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
192 | struct drm_device *dev = node->minor->dev; | 214 | struct drm_device *dev = node->minor->dev; |
193 | struct drm_i915_private *dev_priv = dev->dev_private; | 215 | struct drm_i915_private *dev_priv = dev->dev_private; |
216 | u32 count, mappable_count; | ||
217 | size_t size, mappable_size; | ||
218 | struct drm_i915_gem_object *obj; | ||
194 | int ret; | 219 | int ret; |
195 | 220 | ||
196 | ret = mutex_lock_interruptible(&dev->struct_mutex); | 221 | ret = mutex_lock_interruptible(&dev->struct_mutex); |
197 | if (ret) | 222 | if (ret) |
198 | return ret; | 223 | return ret; |
199 | 224 | ||
200 | seq_printf(m, "%u objects\n", dev_priv->mm.object_count); | 225 | seq_printf(m, "%u objects, %zu bytes\n", |
201 | seq_printf(m, "%zu object bytes\n", dev_priv->mm.object_memory); | 226 | dev_priv->mm.object_count, |
202 | seq_printf(m, "%u pinned\n", dev_priv->mm.pin_count); | 227 | dev_priv->mm.object_memory); |
203 | seq_printf(m, "%zu pin bytes\n", dev_priv->mm.pin_memory); | 228 | |
204 | seq_printf(m, "%u objects in gtt\n", dev_priv->mm.gtt_count); | 229 | size = count = mappable_size = mappable_count = 0; |
205 | seq_printf(m, "%zu gtt bytes\n", dev_priv->mm.gtt_memory); | 230 | count_objects(&dev_priv->mm.gtt_list, gtt_list); |
206 | seq_printf(m, "%zu gtt total\n", dev_priv->mm.gtt_total); | 231 | seq_printf(m, "%u [%u] objects, %zu [%zu] bytes in gtt\n", |
232 | count, mappable_count, size, mappable_size); | ||
233 | |||
234 | size = count = mappable_size = mappable_count = 0; | ||
235 | count_objects(&dev_priv->mm.active_list, mm_list); | ||
236 | count_objects(&dev_priv->mm.flushing_list, mm_list); | ||
237 | seq_printf(m, " %u [%u] active objects, %zu [%zu] bytes\n", | ||
238 | count, mappable_count, size, mappable_size); | ||
239 | |||
240 | size = count = mappable_size = mappable_count = 0; | ||
241 | count_objects(&dev_priv->mm.pinned_list, mm_list); | ||
242 | seq_printf(m, " %u [%u] pinned objects, %zu [%zu] bytes\n", | ||
243 | count, mappable_count, size, mappable_size); | ||
244 | |||
245 | size = count = mappable_size = mappable_count = 0; | ||
246 | count_objects(&dev_priv->mm.inactive_list, mm_list); | ||
247 | seq_printf(m, " %u [%u] inactive objects, %zu [%zu] bytes\n", | ||
248 | count, mappable_count, size, mappable_size); | ||
249 | |||
250 | size = count = mappable_size = mappable_count = 0; | ||
251 | count_objects(&dev_priv->mm.deferred_free_list, mm_list); | ||
252 | seq_printf(m, " %u [%u] freed objects, %zu [%zu] bytes\n", | ||
253 | count, mappable_count, size, mappable_size); | ||
254 | |||
255 | size = count = mappable_size = mappable_count = 0; | ||
256 | list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { | ||
257 | if (obj->fault_mappable) { | ||
258 | size += obj->gtt_space->size; | ||
259 | ++count; | ||
260 | } | ||
261 | if (obj->pin_mappable) { | ||
262 | mappable_size += obj->gtt_space->size; | ||
263 | ++mappable_count; | ||
264 | } | ||
265 | } | ||
266 | seq_printf(m, "%u pinned mappable objects, %zu bytes\n", | ||
267 | mappable_count, mappable_size); | ||
268 | seq_printf(m, "%u fault mappable objects, %zu bytes\n", | ||
269 | count, size); | ||
270 | |||
271 | seq_printf(m, "%zu [%zu] gtt total\n", | ||
272 | dev_priv->mm.gtt_total, dev_priv->mm.mappable_gtt_total); | ||
207 | 273 | ||
208 | mutex_unlock(&dev->struct_mutex); | 274 | mutex_unlock(&dev->struct_mutex); |
209 | 275 | ||
@@ -243,14 +309,14 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) | |||
243 | seq_printf(m, "%d prepares\n", work->pending); | 309 | seq_printf(m, "%d prepares\n", work->pending); |
244 | 310 | ||
245 | if (work->old_fb_obj) { | 311 | if (work->old_fb_obj) { |
246 | struct drm_i915_gem_object *obj_priv = to_intel_bo(work->old_fb_obj); | 312 | struct drm_i915_gem_object *obj = work->old_fb_obj; |
247 | if(obj_priv) | 313 | if (obj) |
248 | seq_printf(m, "Old framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset ); | 314 | seq_printf(m, "Old framebuffer gtt_offset 0x%08x\n", obj->gtt_offset); |
249 | } | 315 | } |
250 | if (work->pending_flip_obj) { | 316 | if (work->pending_flip_obj) { |
251 | struct drm_i915_gem_object *obj_priv = to_intel_bo(work->pending_flip_obj); | 317 | struct drm_i915_gem_object *obj = work->pending_flip_obj; |
252 | if(obj_priv) | 318 | if (obj) |
253 | seq_printf(m, "New framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset ); | 319 | seq_printf(m, "New framebuffer gtt_offset 0x%08x\n", obj->gtt_offset); |
254 | } | 320 | } |
255 | } | 321 | } |
256 | spin_unlock_irqrestore(&dev->event_lock, flags); | 322 | spin_unlock_irqrestore(&dev->event_lock, flags); |
@@ -265,44 +331,80 @@ static int i915_gem_request_info(struct seq_file *m, void *data) | |||
265 | struct drm_device *dev = node->minor->dev; | 331 | struct drm_device *dev = node->minor->dev; |
266 | drm_i915_private_t *dev_priv = dev->dev_private; | 332 | drm_i915_private_t *dev_priv = dev->dev_private; |
267 | struct drm_i915_gem_request *gem_request; | 333 | struct drm_i915_gem_request *gem_request; |
268 | int ret; | 334 | int ret, count; |
269 | 335 | ||
270 | ret = mutex_lock_interruptible(&dev->struct_mutex); | 336 | ret = mutex_lock_interruptible(&dev->struct_mutex); |
271 | if (ret) | 337 | if (ret) |
272 | return ret; | 338 | return ret; |
273 | 339 | ||
274 | seq_printf(m, "Request:\n"); | 340 | count = 0; |
275 | list_for_each_entry(gem_request, &dev_priv->render_ring.request_list, | 341 | if (!list_empty(&dev_priv->ring[RCS].request_list)) { |
276 | list) { | 342 | seq_printf(m, "Render requests:\n"); |
277 | seq_printf(m, " %d @ %d\n", | 343 | list_for_each_entry(gem_request, |
278 | gem_request->seqno, | 344 | &dev_priv->ring[RCS].request_list, |
279 | (int) (jiffies - gem_request->emitted_jiffies)); | 345 | list) { |
346 | seq_printf(m, " %d @ %d\n", | ||
347 | gem_request->seqno, | ||
348 | (int) (jiffies - gem_request->emitted_jiffies)); | ||
349 | } | ||
350 | count++; | ||
351 | } | ||
352 | if (!list_empty(&dev_priv->ring[VCS].request_list)) { | ||
353 | seq_printf(m, "BSD requests:\n"); | ||
354 | list_for_each_entry(gem_request, | ||
355 | &dev_priv->ring[VCS].request_list, | ||
356 | list) { | ||
357 | seq_printf(m, " %d @ %d\n", | ||
358 | gem_request->seqno, | ||
359 | (int) (jiffies - gem_request->emitted_jiffies)); | ||
360 | } | ||
361 | count++; | ||
362 | } | ||
363 | if (!list_empty(&dev_priv->ring[BCS].request_list)) { | ||
364 | seq_printf(m, "BLT requests:\n"); | ||
365 | list_for_each_entry(gem_request, | ||
366 | &dev_priv->ring[BCS].request_list, | ||
367 | list) { | ||
368 | seq_printf(m, " %d @ %d\n", | ||
369 | gem_request->seqno, | ||
370 | (int) (jiffies - gem_request->emitted_jiffies)); | ||
371 | } | ||
372 | count++; | ||
280 | } | 373 | } |
281 | mutex_unlock(&dev->struct_mutex); | 374 | mutex_unlock(&dev->struct_mutex); |
282 | 375 | ||
376 | if (count == 0) | ||
377 | seq_printf(m, "No requests\n"); | ||
378 | |||
283 | return 0; | 379 | return 0; |
284 | } | 380 | } |
285 | 381 | ||
382 | static void i915_ring_seqno_info(struct seq_file *m, | ||
383 | struct intel_ring_buffer *ring) | ||
384 | { | ||
385 | if (ring->get_seqno) { | ||
386 | seq_printf(m, "Current sequence (%s): %d\n", | ||
387 | ring->name, ring->get_seqno(ring)); | ||
388 | seq_printf(m, "Waiter sequence (%s): %d\n", | ||
389 | ring->name, ring->waiting_seqno); | ||
390 | seq_printf(m, "IRQ sequence (%s): %d\n", | ||
391 | ring->name, ring->irq_seqno); | ||
392 | } | ||
393 | } | ||
394 | |||
286 | static int i915_gem_seqno_info(struct seq_file *m, void *data) | 395 | static int i915_gem_seqno_info(struct seq_file *m, void *data) |
287 | { | 396 | { |
288 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 397 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
289 | struct drm_device *dev = node->minor->dev; | 398 | struct drm_device *dev = node->minor->dev; |
290 | drm_i915_private_t *dev_priv = dev->dev_private; | 399 | drm_i915_private_t *dev_priv = dev->dev_private; |
291 | int ret; | 400 | int ret, i; |
292 | 401 | ||
293 | ret = mutex_lock_interruptible(&dev->struct_mutex); | 402 | ret = mutex_lock_interruptible(&dev->struct_mutex); |
294 | if (ret) | 403 | if (ret) |
295 | return ret; | 404 | return ret; |
296 | 405 | ||
297 | if (dev_priv->render_ring.status_page.page_addr != NULL) { | 406 | for (i = 0; i < I915_NUM_RINGS; i++) |
298 | seq_printf(m, "Current sequence: %d\n", | 407 | i915_ring_seqno_info(m, &dev_priv->ring[i]); |
299 | dev_priv->render_ring.get_seqno(dev, &dev_priv->render_ring)); | ||
300 | } else { | ||
301 | seq_printf(m, "Current sequence: hws uninitialized\n"); | ||
302 | } | ||
303 | seq_printf(m, "Waiter sequence: %d\n", | ||
304 | dev_priv->mm.waiting_gem_seqno); | ||
305 | seq_printf(m, "IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno); | ||
306 | 408 | ||
307 | mutex_unlock(&dev->struct_mutex); | 409 | mutex_unlock(&dev->struct_mutex); |
308 | 410 | ||
@@ -315,7 +417,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
315 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 417 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
316 | struct drm_device *dev = node->minor->dev; | 418 | struct drm_device *dev = node->minor->dev; |
317 | drm_i915_private_t *dev_priv = dev->dev_private; | 419 | drm_i915_private_t *dev_priv = dev->dev_private; |
318 | int ret; | 420 | int ret, i; |
319 | 421 | ||
320 | ret = mutex_lock_interruptible(&dev->struct_mutex); | 422 | ret = mutex_lock_interruptible(&dev->struct_mutex); |
321 | if (ret) | 423 | if (ret) |
@@ -354,16 +456,8 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
354 | } | 456 | } |
355 | seq_printf(m, "Interrupts received: %d\n", | 457 | seq_printf(m, "Interrupts received: %d\n", |
356 | atomic_read(&dev_priv->irq_received)); | 458 | atomic_read(&dev_priv->irq_received)); |
357 | if (dev_priv->render_ring.status_page.page_addr != NULL) { | 459 | for (i = 0; i < I915_NUM_RINGS; i++) |
358 | seq_printf(m, "Current sequence: %d\n", | 460 | i915_ring_seqno_info(m, &dev_priv->ring[i]); |
359 | dev_priv->render_ring.get_seqno(dev, &dev_priv->render_ring)); | ||
360 | } else { | ||
361 | seq_printf(m, "Current sequence: hws uninitialized\n"); | ||
362 | } | ||
363 | seq_printf(m, "Waiter sequence: %d\n", | ||
364 | dev_priv->mm.waiting_gem_seqno); | ||
365 | seq_printf(m, "IRQ sequence: %d\n", | ||
366 | dev_priv->mm.irq_gem_seqno); | ||
367 | mutex_unlock(&dev->struct_mutex); | 461 | mutex_unlock(&dev->struct_mutex); |
368 | 462 | ||
369 | return 0; | 463 | return 0; |
@@ -383,29 +477,17 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data) | |||
383 | seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start); | 477 | seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start); |
384 | seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs); | 478 | seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs); |
385 | for (i = 0; i < dev_priv->num_fence_regs; i++) { | 479 | for (i = 0; i < dev_priv->num_fence_regs; i++) { |
386 | struct drm_gem_object *obj = dev_priv->fence_regs[i].obj; | 480 | struct drm_i915_gem_object *obj = dev_priv->fence_regs[i].obj; |
387 | 481 | ||
388 | if (obj == NULL) { | 482 | seq_printf(m, "Fenced object[%2d] = ", i); |
389 | seq_printf(m, "Fenced object[%2d] = unused\n", i); | 483 | if (obj == NULL) |
390 | } else { | 484 | seq_printf(m, "unused"); |
391 | struct drm_i915_gem_object *obj_priv; | 485 | else |
392 | 486 | describe_obj(m, obj); | |
393 | obj_priv = to_intel_bo(obj); | 487 | seq_printf(m, "\n"); |
394 | seq_printf(m, "Fenced object[%2d] = %p: %s " | ||
395 | "%08x %08zx %08x %s %08x %08x %d", | ||
396 | i, obj, get_pin_flag(obj_priv), | ||
397 | obj_priv->gtt_offset, | ||
398 | obj->size, obj_priv->stride, | ||
399 | get_tiling_flag(obj_priv), | ||
400 | obj->read_domains, obj->write_domain, | ||
401 | obj_priv->last_rendering_seqno); | ||
402 | if (obj->name) | ||
403 | seq_printf(m, " (name: %d)", obj->name); | ||
404 | seq_printf(m, "\n"); | ||
405 | } | ||
406 | } | 488 | } |
407 | mutex_unlock(&dev->struct_mutex); | ||
408 | 489 | ||
490 | mutex_unlock(&dev->struct_mutex); | ||
409 | return 0; | 491 | return 0; |
410 | } | 492 | } |
411 | 493 | ||
@@ -414,10 +496,12 @@ static int i915_hws_info(struct seq_file *m, void *data) | |||
414 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 496 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
415 | struct drm_device *dev = node->minor->dev; | 497 | struct drm_device *dev = node->minor->dev; |
416 | drm_i915_private_t *dev_priv = dev->dev_private; | 498 | drm_i915_private_t *dev_priv = dev->dev_private; |
417 | int i; | 499 | struct intel_ring_buffer *ring; |
418 | volatile u32 *hws; | 500 | volatile u32 *hws; |
501 | int i; | ||
419 | 502 | ||
420 | hws = (volatile u32 *)dev_priv->render_ring.status_page.page_addr; | 503 | ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; |
504 | hws = (volatile u32 *)ring->status_page.page_addr; | ||
421 | if (hws == NULL) | 505 | if (hws == NULL) |
422 | return 0; | 506 | return 0; |
423 | 507 | ||
@@ -431,14 +515,14 @@ static int i915_hws_info(struct seq_file *m, void *data) | |||
431 | 515 | ||
432 | static void i915_dump_object(struct seq_file *m, | 516 | static void i915_dump_object(struct seq_file *m, |
433 | struct io_mapping *mapping, | 517 | struct io_mapping *mapping, |
434 | struct drm_i915_gem_object *obj_priv) | 518 | struct drm_i915_gem_object *obj) |
435 | { | 519 | { |
436 | int page, page_count, i; | 520 | int page, page_count, i; |
437 | 521 | ||
438 | page_count = obj_priv->base.size / PAGE_SIZE; | 522 | page_count = obj->base.size / PAGE_SIZE; |
439 | for (page = 0; page < page_count; page++) { | 523 | for (page = 0; page < page_count; page++) { |
440 | u32 *mem = io_mapping_map_wc(mapping, | 524 | u32 *mem = io_mapping_map_wc(mapping, |
441 | obj_priv->gtt_offset + page * PAGE_SIZE); | 525 | obj->gtt_offset + page * PAGE_SIZE); |
442 | for (i = 0; i < PAGE_SIZE; i += 4) | 526 | for (i = 0; i < PAGE_SIZE; i += 4) |
443 | seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); | 527 | seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); |
444 | io_mapping_unmap(mem); | 528 | io_mapping_unmap(mem); |
@@ -450,25 +534,21 @@ static int i915_batchbuffer_info(struct seq_file *m, void *data) | |||
450 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 534 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
451 | struct drm_device *dev = node->minor->dev; | 535 | struct drm_device *dev = node->minor->dev; |
452 | drm_i915_private_t *dev_priv = dev->dev_private; | 536 | drm_i915_private_t *dev_priv = dev->dev_private; |
453 | struct drm_gem_object *obj; | 537 | struct drm_i915_gem_object *obj; |
454 | struct drm_i915_gem_object *obj_priv; | ||
455 | int ret; | 538 | int ret; |
456 | 539 | ||
457 | ret = mutex_lock_interruptible(&dev->struct_mutex); | 540 | ret = mutex_lock_interruptible(&dev->struct_mutex); |
458 | if (ret) | 541 | if (ret) |
459 | return ret; | 542 | return ret; |
460 | 543 | ||
461 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, mm_list) { | 544 | list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { |
462 | obj = &obj_priv->base; | 545 | if (obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) { |
463 | if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { | 546 | seq_printf(m, "--- gtt_offset = 0x%08x\n", obj->gtt_offset); |
464 | seq_printf(m, "--- gtt_offset = 0x%08x\n", | 547 | i915_dump_object(m, dev_priv->mm.gtt_mapping, obj); |
465 | obj_priv->gtt_offset); | ||
466 | i915_dump_object(m, dev_priv->mm.gtt_mapping, obj_priv); | ||
467 | } | 548 | } |
468 | } | 549 | } |
469 | 550 | ||
470 | mutex_unlock(&dev->struct_mutex); | 551 | mutex_unlock(&dev->struct_mutex); |
471 | |||
472 | return 0; | 552 | return 0; |
473 | } | 553 | } |
474 | 554 | ||
@@ -477,19 +557,21 @@ static int i915_ringbuffer_data(struct seq_file *m, void *data) | |||
477 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 557 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
478 | struct drm_device *dev = node->minor->dev; | 558 | struct drm_device *dev = node->minor->dev; |
479 | drm_i915_private_t *dev_priv = dev->dev_private; | 559 | drm_i915_private_t *dev_priv = dev->dev_private; |
560 | struct intel_ring_buffer *ring; | ||
480 | int ret; | 561 | int ret; |
481 | 562 | ||
482 | ret = mutex_lock_interruptible(&dev->struct_mutex); | 563 | ret = mutex_lock_interruptible(&dev->struct_mutex); |
483 | if (ret) | 564 | if (ret) |
484 | return ret; | 565 | return ret; |
485 | 566 | ||
486 | if (!dev_priv->render_ring.gem_object) { | 567 | ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; |
568 | if (!ring->obj) { | ||
487 | seq_printf(m, "No ringbuffer setup\n"); | 569 | seq_printf(m, "No ringbuffer setup\n"); |
488 | } else { | 570 | } else { |
489 | u8 *virt = dev_priv->render_ring.virtual_start; | 571 | u8 *virt = ring->virtual_start; |
490 | uint32_t off; | 572 | uint32_t off; |
491 | 573 | ||
492 | for (off = 0; off < dev_priv->render_ring.size; off += 4) { | 574 | for (off = 0; off < ring->size; off += 4) { |
493 | uint32_t *ptr = (uint32_t *)(virt + off); | 575 | uint32_t *ptr = (uint32_t *)(virt + off); |
494 | seq_printf(m, "%08x : %08x\n", off, *ptr); | 576 | seq_printf(m, "%08x : %08x\n", off, *ptr); |
495 | } | 577 | } |
@@ -504,19 +586,38 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
504 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 586 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
505 | struct drm_device *dev = node->minor->dev; | 587 | struct drm_device *dev = node->minor->dev; |
506 | drm_i915_private_t *dev_priv = dev->dev_private; | 588 | drm_i915_private_t *dev_priv = dev->dev_private; |
507 | unsigned int head, tail; | 589 | struct intel_ring_buffer *ring; |
508 | 590 | ||
509 | head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | 591 | ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; |
510 | tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; | 592 | if (ring->size == 0) |
593 | return 0; | ||
511 | 594 | ||
512 | seq_printf(m, "RingHead : %08x\n", head); | 595 | seq_printf(m, "Ring %s:\n", ring->name); |
513 | seq_printf(m, "RingTail : %08x\n", tail); | 596 | seq_printf(m, " Head : %08x\n", I915_READ_HEAD(ring) & HEAD_ADDR); |
514 | seq_printf(m, "RingSize : %08lx\n", dev_priv->render_ring.size); | 597 | seq_printf(m, " Tail : %08x\n", I915_READ_TAIL(ring) & TAIL_ADDR); |
515 | seq_printf(m, "Acthd : %08x\n", I915_READ(INTEL_INFO(dev)->gen >= 4 ? ACTHD_I965 : ACTHD)); | 598 | seq_printf(m, " Size : %08x\n", ring->size); |
599 | seq_printf(m, " Active : %08x\n", intel_ring_get_active_head(ring)); | ||
600 | seq_printf(m, " NOPID : %08x\n", I915_READ_NOPID(ring)); | ||
601 | if (IS_GEN6(dev)) { | ||
602 | seq_printf(m, " Sync 0 : %08x\n", I915_READ_SYNC_0(ring)); | ||
603 | seq_printf(m, " Sync 1 : %08x\n", I915_READ_SYNC_1(ring)); | ||
604 | } | ||
605 | seq_printf(m, " Control : %08x\n", I915_READ_CTL(ring)); | ||
606 | seq_printf(m, " Start : %08x\n", I915_READ_START(ring)); | ||
516 | 607 | ||
517 | return 0; | 608 | return 0; |
518 | } | 609 | } |
519 | 610 | ||
611 | static const char *ring_str(int ring) | ||
612 | { | ||
613 | switch (ring) { | ||
614 | case RING_RENDER: return " render"; | ||
615 | case RING_BSD: return " bsd"; | ||
616 | case RING_BLT: return " blt"; | ||
617 | default: return ""; | ||
618 | } | ||
619 | } | ||
620 | |||
520 | static const char *pin_flag(int pinned) | 621 | static const char *pin_flag(int pinned) |
521 | { | 622 | { |
522 | if (pinned > 0) | 623 | if (pinned > 0) |
@@ -547,6 +648,36 @@ static const char *purgeable_flag(int purgeable) | |||
547 | return purgeable ? " purgeable" : ""; | 648 | return purgeable ? " purgeable" : ""; |
548 | } | 649 | } |
549 | 650 | ||
651 | static void print_error_buffers(struct seq_file *m, | ||
652 | const char *name, | ||
653 | struct drm_i915_error_buffer *err, | ||
654 | int count) | ||
655 | { | ||
656 | seq_printf(m, "%s [%d]:\n", name, count); | ||
657 | |||
658 | while (count--) { | ||
659 | seq_printf(m, " %08x %8zd %04x %04x %08x%s%s%s%s%s", | ||
660 | err->gtt_offset, | ||
661 | err->size, | ||
662 | err->read_domains, | ||
663 | err->write_domain, | ||
664 | err->seqno, | ||
665 | pin_flag(err->pinned), | ||
666 | tiling_flag(err->tiling), | ||
667 | dirty_flag(err->dirty), | ||
668 | purgeable_flag(err->purgeable), | ||
669 | ring_str(err->ring)); | ||
670 | |||
671 | if (err->name) | ||
672 | seq_printf(m, " (name: %d)", err->name); | ||
673 | if (err->fence_reg != I915_FENCE_REG_NONE) | ||
674 | seq_printf(m, " (fence: %d)", err->fence_reg); | ||
675 | |||
676 | seq_printf(m, "\n"); | ||
677 | err++; | ||
678 | } | ||
679 | } | ||
680 | |||
550 | static int i915_error_state(struct seq_file *m, void *unused) | 681 | static int i915_error_state(struct seq_file *m, void *unused) |
551 | { | 682 | { |
552 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 683 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
@@ -568,41 +699,46 @@ static int i915_error_state(struct seq_file *m, void *unused) | |||
568 | error->time.tv_usec); | 699 | error->time.tv_usec); |
569 | seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); | 700 | seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); |
570 | seq_printf(m, "EIR: 0x%08x\n", error->eir); | 701 | seq_printf(m, "EIR: 0x%08x\n", error->eir); |
571 | seq_printf(m, " PGTBL_ER: 0x%08x\n", error->pgtbl_er); | 702 | seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); |
572 | seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); | 703 | if (INTEL_INFO(dev)->gen >= 6) { |
704 | seq_printf(m, "ERROR: 0x%08x\n", error->error); | ||
705 | seq_printf(m, "Blitter command stream:\n"); | ||
706 | seq_printf(m, " ACTHD: 0x%08x\n", error->bcs_acthd); | ||
707 | seq_printf(m, " IPEIR: 0x%08x\n", error->bcs_ipeir); | ||
708 | seq_printf(m, " IPEHR: 0x%08x\n", error->bcs_ipehr); | ||
709 | seq_printf(m, " INSTDONE: 0x%08x\n", error->bcs_instdone); | ||
710 | seq_printf(m, " seqno: 0x%08x\n", error->bcs_seqno); | ||
711 | seq_printf(m, "Video (BSD) command stream:\n"); | ||
712 | seq_printf(m, " ACTHD: 0x%08x\n", error->vcs_acthd); | ||
713 | seq_printf(m, " IPEIR: 0x%08x\n", error->vcs_ipeir); | ||
714 | seq_printf(m, " IPEHR: 0x%08x\n", error->vcs_ipehr); | ||
715 | seq_printf(m, " INSTDONE: 0x%08x\n", error->vcs_instdone); | ||
716 | seq_printf(m, " seqno: 0x%08x\n", error->vcs_seqno); | ||
717 | } | ||
718 | seq_printf(m, "Render command stream:\n"); | ||
719 | seq_printf(m, " ACTHD: 0x%08x\n", error->acthd); | ||
573 | seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir); | 720 | seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir); |
574 | seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr); | 721 | seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr); |
575 | seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone); | 722 | seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone); |
576 | seq_printf(m, " ACTHD: 0x%08x\n", error->acthd); | ||
577 | if (INTEL_INFO(dev)->gen >= 4) { | 723 | if (INTEL_INFO(dev)->gen >= 4) { |
578 | seq_printf(m, " INSTPS: 0x%08x\n", error->instps); | ||
579 | seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); | 724 | seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); |
725 | seq_printf(m, " INSTPS: 0x%08x\n", error->instps); | ||
580 | } | 726 | } |
581 | seq_printf(m, "seqno: 0x%08x\n", error->seqno); | 727 | seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); |
582 | 728 | seq_printf(m, " seqno: 0x%08x\n", error->seqno); | |
583 | if (error->active_bo_count) { | 729 | |
584 | seq_printf(m, "Buffers [%d]:\n", error->active_bo_count); | 730 | for (i = 0; i < 16; i++) |
585 | 731 | seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); | |
586 | for (i = 0; i < error->active_bo_count; i++) { | 732 | |
587 | seq_printf(m, " %08x %8zd %08x %08x %08x%s%s%s%s", | 733 | if (error->active_bo) |
588 | error->active_bo[i].gtt_offset, | 734 | print_error_buffers(m, "Active", |
589 | error->active_bo[i].size, | 735 | error->active_bo, |
590 | error->active_bo[i].read_domains, | 736 | error->active_bo_count); |
591 | error->active_bo[i].write_domain, | 737 | |
592 | error->active_bo[i].seqno, | 738 | if (error->pinned_bo) |
593 | pin_flag(error->active_bo[i].pinned), | 739 | print_error_buffers(m, "Pinned", |
594 | tiling_flag(error->active_bo[i].tiling), | 740 | error->pinned_bo, |
595 | dirty_flag(error->active_bo[i].dirty), | 741 | error->pinned_bo_count); |
596 | purgeable_flag(error->active_bo[i].purgeable)); | ||
597 | |||
598 | if (error->active_bo[i].name) | ||
599 | seq_printf(m, " (name: %d)", error->active_bo[i].name); | ||
600 | if (error->active_bo[i].fence_reg != I915_FENCE_REG_NONE) | ||
601 | seq_printf(m, " (fence: %d)", error->active_bo[i].fence_reg); | ||
602 | |||
603 | seq_printf(m, "\n"); | ||
604 | } | ||
605 | } | ||
606 | 742 | ||
607 | for (i = 0; i < ARRAY_SIZE(error->batchbuffer); i++) { | 743 | for (i = 0; i < ARRAY_SIZE(error->batchbuffer); i++) { |
608 | if (error->batchbuffer[i]) { | 744 | if (error->batchbuffer[i]) { |
@@ -635,6 +771,9 @@ static int i915_error_state(struct seq_file *m, void *unused) | |||
635 | if (error->overlay) | 771 | if (error->overlay) |
636 | intel_overlay_print_error_state(m, error->overlay); | 772 | intel_overlay_print_error_state(m, error->overlay); |
637 | 773 | ||
774 | if (error->display) | ||
775 | intel_display_print_error_state(m, dev, error->display); | ||
776 | |||
638 | out: | 777 | out: |
639 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); | 778 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); |
640 | 779 | ||
@@ -658,15 +797,51 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) | |||
658 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 797 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
659 | struct drm_device *dev = node->minor->dev; | 798 | struct drm_device *dev = node->minor->dev; |
660 | drm_i915_private_t *dev_priv = dev->dev_private; | 799 | drm_i915_private_t *dev_priv = dev->dev_private; |
661 | u16 rgvswctl = I915_READ16(MEMSWCTL); | ||
662 | u16 rgvstat = I915_READ16(MEMSTAT_ILK); | ||
663 | 800 | ||
664 | seq_printf(m, "Requested P-state: %d\n", (rgvswctl >> 8) & 0xf); | 801 | if (IS_GEN5(dev)) { |
665 | seq_printf(m, "Requested VID: %d\n", rgvswctl & 0x3f); | 802 | u16 rgvswctl = I915_READ16(MEMSWCTL); |
666 | seq_printf(m, "Current VID: %d\n", (rgvstat & MEMSTAT_VID_MASK) >> | 803 | u16 rgvstat = I915_READ16(MEMSTAT_ILK); |
667 | MEMSTAT_VID_SHIFT); | 804 | |
668 | seq_printf(m, "Current P-state: %d\n", | 805 | seq_printf(m, "Requested P-state: %d\n", (rgvswctl >> 8) & 0xf); |
669 | (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT); | 806 | seq_printf(m, "Requested VID: %d\n", rgvswctl & 0x3f); |
807 | seq_printf(m, "Current VID: %d\n", (rgvstat & MEMSTAT_VID_MASK) >> | ||
808 | MEMSTAT_VID_SHIFT); | ||
809 | seq_printf(m, "Current P-state: %d\n", | ||
810 | (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT); | ||
811 | } else if (IS_GEN6(dev)) { | ||
812 | u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); | ||
813 | u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS); | ||
814 | u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); | ||
815 | int max_freq; | ||
816 | |||
817 | /* RPSTAT1 is in the GT power well */ | ||
818 | __gen6_force_wake_get(dev_priv); | ||
819 | |||
820 | seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status); | ||
821 | seq_printf(m, "RPSTAT1: 0x%08x\n", I915_READ(GEN6_RPSTAT1)); | ||
822 | seq_printf(m, "Render p-state ratio: %d\n", | ||
823 | (gt_perf_status & 0xff00) >> 8); | ||
824 | seq_printf(m, "Render p-state VID: %d\n", | ||
825 | gt_perf_status & 0xff); | ||
826 | seq_printf(m, "Render p-state limit: %d\n", | ||
827 | rp_state_limits & 0xff); | ||
828 | |||
829 | max_freq = (rp_state_cap & 0xff0000) >> 16; | ||
830 | seq_printf(m, "Lowest (RPN) frequency: %dMHz\n", | ||
831 | max_freq * 100); | ||
832 | |||
833 | max_freq = (rp_state_cap & 0xff00) >> 8; | ||
834 | seq_printf(m, "Nominal (RP1) frequency: %dMHz\n", | ||
835 | max_freq * 100); | ||
836 | |||
837 | max_freq = rp_state_cap & 0xff; | ||
838 | seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n", | ||
839 | max_freq * 100); | ||
840 | |||
841 | __gen6_force_wake_put(dev_priv); | ||
842 | } else { | ||
843 | seq_printf(m, "no P-state info available\n"); | ||
844 | } | ||
670 | 845 | ||
671 | return 0; | 846 | return 0; |
672 | } | 847 | } |
@@ -794,7 +969,7 @@ static int i915_sr_status(struct seq_file *m, void *unused) | |||
794 | drm_i915_private_t *dev_priv = dev->dev_private; | 969 | drm_i915_private_t *dev_priv = dev->dev_private; |
795 | bool sr_enabled = false; | 970 | bool sr_enabled = false; |
796 | 971 | ||
797 | if (IS_GEN5(dev)) | 972 | if (HAS_PCH_SPLIT(dev)) |
798 | sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; | 973 | sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; |
799 | else if (IS_CRESTLINE(dev) || IS_I945G(dev) || IS_I945GM(dev)) | 974 | else if (IS_CRESTLINE(dev) || IS_I945G(dev) || IS_I945GM(dev)) |
800 | sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; | 975 | sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; |
@@ -886,7 +1061,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) | |||
886 | fb->base.height, | 1061 | fb->base.height, |
887 | fb->base.depth, | 1062 | fb->base.depth, |
888 | fb->base.bits_per_pixel); | 1063 | fb->base.bits_per_pixel); |
889 | describe_obj(m, to_intel_bo(fb->obj)); | 1064 | describe_obj(m, fb->obj); |
890 | seq_printf(m, "\n"); | 1065 | seq_printf(m, "\n"); |
891 | 1066 | ||
892 | list_for_each_entry(fb, &dev->mode_config.fb_list, base.head) { | 1067 | list_for_each_entry(fb, &dev->mode_config.fb_list, base.head) { |
@@ -898,7 +1073,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) | |||
898 | fb->base.height, | 1073 | fb->base.height, |
899 | fb->base.depth, | 1074 | fb->base.depth, |
900 | fb->base.bits_per_pixel); | 1075 | fb->base.bits_per_pixel); |
901 | describe_obj(m, to_intel_bo(fb->obj)); | 1076 | describe_obj(m, fb->obj); |
902 | seq_printf(m, "\n"); | 1077 | seq_printf(m, "\n"); |
903 | } | 1078 | } |
904 | 1079 | ||
@@ -943,7 +1118,6 @@ i915_wedged_write(struct file *filp, | |||
943 | loff_t *ppos) | 1118 | loff_t *ppos) |
944 | { | 1119 | { |
945 | struct drm_device *dev = filp->private_data; | 1120 | struct drm_device *dev = filp->private_data; |
946 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
947 | char buf[20]; | 1121 | char buf[20]; |
948 | int val = 1; | 1122 | int val = 1; |
949 | 1123 | ||
@@ -959,12 +1133,7 @@ i915_wedged_write(struct file *filp, | |||
959 | } | 1133 | } |
960 | 1134 | ||
961 | DRM_INFO("Manually setting wedged to %d\n", val); | 1135 | DRM_INFO("Manually setting wedged to %d\n", val); |
962 | 1136 | i915_handle_error(dev, val); | |
963 | atomic_set(&dev_priv->mm.wedged, val); | ||
964 | if (val) { | ||
965 | wake_up_all(&dev_priv->irq_queue); | ||
966 | queue_work(dev_priv->wq, &dev_priv->error_work); | ||
967 | } | ||
968 | 1137 | ||
969 | return cnt; | 1138 | return cnt; |
970 | } | 1139 | } |
@@ -1028,9 +1197,15 @@ static struct drm_info_list i915_debugfs_list[] = { | |||
1028 | {"i915_gem_seqno", i915_gem_seqno_info, 0}, | 1197 | {"i915_gem_seqno", i915_gem_seqno_info, 0}, |
1029 | {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, | 1198 | {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, |
1030 | {"i915_gem_interrupt", i915_interrupt_info, 0}, | 1199 | {"i915_gem_interrupt", i915_interrupt_info, 0}, |
1031 | {"i915_gem_hws", i915_hws_info, 0}, | 1200 | {"i915_gem_hws", i915_hws_info, 0, (void *)RCS}, |
1032 | {"i915_ringbuffer_data", i915_ringbuffer_data, 0}, | 1201 | {"i915_gem_hws_blt", i915_hws_info, 0, (void *)BCS}, |
1033 | {"i915_ringbuffer_info", i915_ringbuffer_info, 0}, | 1202 | {"i915_gem_hws_bsd", i915_hws_info, 0, (void *)VCS}, |
1203 | {"i915_ringbuffer_data", i915_ringbuffer_data, 0, (void *)RCS}, | ||
1204 | {"i915_ringbuffer_info", i915_ringbuffer_info, 0, (void *)RCS}, | ||
1205 | {"i915_bsd_ringbuffer_data", i915_ringbuffer_data, 0, (void *)VCS}, | ||
1206 | {"i915_bsd_ringbuffer_info", i915_ringbuffer_info, 0, (void *)VCS}, | ||
1207 | {"i915_blt_ringbuffer_data", i915_ringbuffer_data, 0, (void *)BCS}, | ||
1208 | {"i915_blt_ringbuffer_info", i915_ringbuffer_info, 0, (void *)BCS}, | ||
1034 | {"i915_batchbuffers", i915_batchbuffer_info, 0}, | 1209 | {"i915_batchbuffers", i915_batchbuffer_info, 0}, |
1035 | {"i915_error_state", i915_error_state, 0}, | 1210 | {"i915_error_state", i915_error_state, 0}, |
1036 | {"i915_rstdby_delays", i915_rstdby_delays, 0}, | 1211 | {"i915_rstdby_delays", i915_rstdby_delays, 0}, |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 7a26f4dd21a..18746e6cb12 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -49,6 +49,8 @@ | |||
49 | static int i915_init_phys_hws(struct drm_device *dev) | 49 | static int i915_init_phys_hws(struct drm_device *dev) |
50 | { | 50 | { |
51 | drm_i915_private_t *dev_priv = dev->dev_private; | 51 | drm_i915_private_t *dev_priv = dev->dev_private; |
52 | struct intel_ring_buffer *ring = LP_RING(dev_priv); | ||
53 | |||
52 | /* Program Hardware Status Page */ | 54 | /* Program Hardware Status Page */ |
53 | dev_priv->status_page_dmah = | 55 | dev_priv->status_page_dmah = |
54 | drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE); | 56 | drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE); |
@@ -57,11 +59,10 @@ static int i915_init_phys_hws(struct drm_device *dev) | |||
57 | DRM_ERROR("Can not allocate hardware status page\n"); | 59 | DRM_ERROR("Can not allocate hardware status page\n"); |
58 | return -ENOMEM; | 60 | return -ENOMEM; |
59 | } | 61 | } |
60 | dev_priv->render_ring.status_page.page_addr | 62 | ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; |
61 | = dev_priv->status_page_dmah->vaddr; | ||
62 | dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; | 63 | dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; |
63 | 64 | ||
64 | memset(dev_priv->render_ring.status_page.page_addr, 0, PAGE_SIZE); | 65 | memset(ring->status_page.page_addr, 0, PAGE_SIZE); |
65 | 66 | ||
66 | if (INTEL_INFO(dev)->gen >= 4) | 67 | if (INTEL_INFO(dev)->gen >= 4) |
67 | dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) & | 68 | dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) & |
@@ -79,13 +80,15 @@ static int i915_init_phys_hws(struct drm_device *dev) | |||
79 | static void i915_free_hws(struct drm_device *dev) | 80 | static void i915_free_hws(struct drm_device *dev) |
80 | { | 81 | { |
81 | drm_i915_private_t *dev_priv = dev->dev_private; | 82 | drm_i915_private_t *dev_priv = dev->dev_private; |
83 | struct intel_ring_buffer *ring = LP_RING(dev_priv); | ||
84 | |||
82 | if (dev_priv->status_page_dmah) { | 85 | if (dev_priv->status_page_dmah) { |
83 | drm_pci_free(dev, dev_priv->status_page_dmah); | 86 | drm_pci_free(dev, dev_priv->status_page_dmah); |
84 | dev_priv->status_page_dmah = NULL; | 87 | dev_priv->status_page_dmah = NULL; |
85 | } | 88 | } |
86 | 89 | ||
87 | if (dev_priv->render_ring.status_page.gfx_addr) { | 90 | if (ring->status_page.gfx_addr) { |
88 | dev_priv->render_ring.status_page.gfx_addr = 0; | 91 | ring->status_page.gfx_addr = 0; |
89 | drm_core_ioremapfree(&dev_priv->hws_map, dev); | 92 | drm_core_ioremapfree(&dev_priv->hws_map, dev); |
90 | } | 93 | } |
91 | 94 | ||
@@ -97,7 +100,7 @@ void i915_kernel_lost_context(struct drm_device * dev) | |||
97 | { | 100 | { |
98 | drm_i915_private_t *dev_priv = dev->dev_private; | 101 | drm_i915_private_t *dev_priv = dev->dev_private; |
99 | struct drm_i915_master_private *master_priv; | 102 | struct drm_i915_master_private *master_priv; |
100 | struct intel_ring_buffer *ring = &dev_priv->render_ring; | 103 | struct intel_ring_buffer *ring = LP_RING(dev_priv); |
101 | 104 | ||
102 | /* | 105 | /* |
103 | * We should never lose context on the ring with modesetting | 106 | * We should never lose context on the ring with modesetting |
@@ -106,8 +109,8 @@ void i915_kernel_lost_context(struct drm_device * dev) | |||
106 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 109 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
107 | return; | 110 | return; |
108 | 111 | ||
109 | ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | 112 | ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; |
110 | ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; | 113 | ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; |
111 | ring->space = ring->head - (ring->tail + 8); | 114 | ring->space = ring->head - (ring->tail + 8); |
112 | if (ring->space < 0) | 115 | if (ring->space < 0) |
113 | ring->space += ring->size; | 116 | ring->space += ring->size; |
@@ -123,6 +126,8 @@ void i915_kernel_lost_context(struct drm_device * dev) | |||
123 | static int i915_dma_cleanup(struct drm_device * dev) | 126 | static int i915_dma_cleanup(struct drm_device * dev) |
124 | { | 127 | { |
125 | drm_i915_private_t *dev_priv = dev->dev_private; | 128 | drm_i915_private_t *dev_priv = dev->dev_private; |
129 | int i; | ||
130 | |||
126 | /* Make sure interrupts are disabled here because the uninstall ioctl | 131 | /* Make sure interrupts are disabled here because the uninstall ioctl |
127 | * may not have been called from userspace and after dev_private | 132 | * may not have been called from userspace and after dev_private |
128 | * is freed, it's too late. | 133 | * is freed, it's too late. |
@@ -131,9 +136,8 @@ static int i915_dma_cleanup(struct drm_device * dev) | |||
131 | drm_irq_uninstall(dev); | 136 | drm_irq_uninstall(dev); |
132 | 137 | ||
133 | mutex_lock(&dev->struct_mutex); | 138 | mutex_lock(&dev->struct_mutex); |
134 | intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); | 139 | for (i = 0; i < I915_NUM_RINGS; i++) |
135 | intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); | 140 | intel_cleanup_ring_buffer(&dev_priv->ring[i]); |
136 | intel_cleanup_ring_buffer(dev, &dev_priv->blt_ring); | ||
137 | mutex_unlock(&dev->struct_mutex); | 141 | mutex_unlock(&dev->struct_mutex); |
138 | 142 | ||
139 | /* Clear the HWS virtual address at teardown */ | 143 | /* Clear the HWS virtual address at teardown */ |
@@ -147,6 +151,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | |||
147 | { | 151 | { |
148 | drm_i915_private_t *dev_priv = dev->dev_private; | 152 | drm_i915_private_t *dev_priv = dev->dev_private; |
149 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | 153 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; |
154 | struct intel_ring_buffer *ring = LP_RING(dev_priv); | ||
150 | 155 | ||
151 | master_priv->sarea = drm_getsarea(dev); | 156 | master_priv->sarea = drm_getsarea(dev); |
152 | if (master_priv->sarea) { | 157 | if (master_priv->sarea) { |
@@ -157,24 +162,24 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | |||
157 | } | 162 | } |
158 | 163 | ||
159 | if (init->ring_size != 0) { | 164 | if (init->ring_size != 0) { |
160 | if (dev_priv->render_ring.gem_object != NULL) { | 165 | if (ring->obj != NULL) { |
161 | i915_dma_cleanup(dev); | 166 | i915_dma_cleanup(dev); |
162 | DRM_ERROR("Client tried to initialize ringbuffer in " | 167 | DRM_ERROR("Client tried to initialize ringbuffer in " |
163 | "GEM mode\n"); | 168 | "GEM mode\n"); |
164 | return -EINVAL; | 169 | return -EINVAL; |
165 | } | 170 | } |
166 | 171 | ||
167 | dev_priv->render_ring.size = init->ring_size; | 172 | ring->size = init->ring_size; |
168 | 173 | ||
169 | dev_priv->render_ring.map.offset = init->ring_start; | 174 | ring->map.offset = init->ring_start; |
170 | dev_priv->render_ring.map.size = init->ring_size; | 175 | ring->map.size = init->ring_size; |
171 | dev_priv->render_ring.map.type = 0; | 176 | ring->map.type = 0; |
172 | dev_priv->render_ring.map.flags = 0; | 177 | ring->map.flags = 0; |
173 | dev_priv->render_ring.map.mtrr = 0; | 178 | ring->map.mtrr = 0; |
174 | 179 | ||
175 | drm_core_ioremap_wc(&dev_priv->render_ring.map, dev); | 180 | drm_core_ioremap_wc(&ring->map, dev); |
176 | 181 | ||
177 | if (dev_priv->render_ring.map.handle == NULL) { | 182 | if (ring->map.handle == NULL) { |
178 | i915_dma_cleanup(dev); | 183 | i915_dma_cleanup(dev); |
179 | DRM_ERROR("can not ioremap virtual address for" | 184 | DRM_ERROR("can not ioremap virtual address for" |
180 | " ring buffer\n"); | 185 | " ring buffer\n"); |
@@ -182,7 +187,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | |||
182 | } | 187 | } |
183 | } | 188 | } |
184 | 189 | ||
185 | dev_priv->render_ring.virtual_start = dev_priv->render_ring.map.handle; | 190 | ring->virtual_start = ring->map.handle; |
186 | 191 | ||
187 | dev_priv->cpp = init->cpp; | 192 | dev_priv->cpp = init->cpp; |
188 | dev_priv->back_offset = init->back_offset; | 193 | dev_priv->back_offset = init->back_offset; |
@@ -201,12 +206,10 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | |||
201 | static int i915_dma_resume(struct drm_device * dev) | 206 | static int i915_dma_resume(struct drm_device * dev) |
202 | { | 207 | { |
203 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 208 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
209 | struct intel_ring_buffer *ring = LP_RING(dev_priv); | ||
204 | 210 | ||
205 | struct intel_ring_buffer *ring; | ||
206 | DRM_DEBUG_DRIVER("%s\n", __func__); | 211 | DRM_DEBUG_DRIVER("%s\n", __func__); |
207 | 212 | ||
208 | ring = &dev_priv->render_ring; | ||
209 | |||
210 | if (ring->map.handle == NULL) { | 213 | if (ring->map.handle == NULL) { |
211 | DRM_ERROR("can not ioremap virtual address for" | 214 | DRM_ERROR("can not ioremap virtual address for" |
212 | " ring buffer\n"); | 215 | " ring buffer\n"); |
@@ -221,7 +224,7 @@ static int i915_dma_resume(struct drm_device * dev) | |||
221 | DRM_DEBUG_DRIVER("hw status page @ %p\n", | 224 | DRM_DEBUG_DRIVER("hw status page @ %p\n", |
222 | ring->status_page.page_addr); | 225 | ring->status_page.page_addr); |
223 | if (ring->status_page.gfx_addr != 0) | 226 | if (ring->status_page.gfx_addr != 0) |
224 | intel_ring_setup_status_page(dev, ring); | 227 | intel_ring_setup_status_page(ring); |
225 | else | 228 | else |
226 | I915_WRITE(HWS_PGA, dev_priv->dma_status_page); | 229 | I915_WRITE(HWS_PGA, dev_priv->dma_status_page); |
227 | 230 | ||
@@ -263,7 +266,7 @@ static int i915_dma_init(struct drm_device *dev, void *data, | |||
263 | * instruction detected will be given a size of zero, which is a | 266 | * instruction detected will be given a size of zero, which is a |
264 | * signal to abort the rest of the buffer. | 267 | * signal to abort the rest of the buffer. |
265 | */ | 268 | */ |
266 | static int do_validate_cmd(int cmd) | 269 | static int validate_cmd(int cmd) |
267 | { | 270 | { |
268 | switch (((cmd >> 29) & 0x7)) { | 271 | switch (((cmd >> 29) & 0x7)) { |
269 | case 0x0: | 272 | case 0x0: |
@@ -321,40 +324,27 @@ static int do_validate_cmd(int cmd) | |||
321 | return 0; | 324 | return 0; |
322 | } | 325 | } |
323 | 326 | ||
324 | static int validate_cmd(int cmd) | ||
325 | { | ||
326 | int ret = do_validate_cmd(cmd); | ||
327 | |||
328 | /* printk("validate_cmd( %x ): %d\n", cmd, ret); */ | ||
329 | |||
330 | return ret; | ||
331 | } | ||
332 | |||
333 | static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) | 327 | static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) |
334 | { | 328 | { |
335 | drm_i915_private_t *dev_priv = dev->dev_private; | 329 | drm_i915_private_t *dev_priv = dev->dev_private; |
336 | int i; | 330 | int i, ret; |
337 | 331 | ||
338 | if ((dwords+1) * sizeof(int) >= dev_priv->render_ring.size - 8) | 332 | if ((dwords+1) * sizeof(int) >= LP_RING(dev_priv)->size - 8) |
339 | return -EINVAL; | 333 | return -EINVAL; |
340 | 334 | ||
341 | BEGIN_LP_RING((dwords+1)&~1); | ||
342 | |||
343 | for (i = 0; i < dwords;) { | 335 | for (i = 0; i < dwords;) { |
344 | int cmd, sz; | 336 | int sz = validate_cmd(buffer[i]); |
345 | 337 | if (sz == 0 || i + sz > dwords) | |
346 | cmd = buffer[i]; | ||
347 | |||
348 | if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) | ||
349 | return -EINVAL; | 338 | return -EINVAL; |
350 | 339 | i += sz; | |
351 | OUT_RING(cmd); | ||
352 | |||
353 | while (++i, --sz) { | ||
354 | OUT_RING(buffer[i]); | ||
355 | } | ||
356 | } | 340 | } |
357 | 341 | ||
342 | ret = BEGIN_LP_RING((dwords+1)&~1); | ||
343 | if (ret) | ||
344 | return ret; | ||
345 | |||
346 | for (i = 0; i < dwords; i++) | ||
347 | OUT_RING(buffer[i]); | ||
358 | if (dwords & 1) | 348 | if (dwords & 1) |
359 | OUT_RING(0); | 349 | OUT_RING(0); |
360 | 350 | ||
@@ -365,34 +355,41 @@ static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) | |||
365 | 355 | ||
366 | int | 356 | int |
367 | i915_emit_box(struct drm_device *dev, | 357 | i915_emit_box(struct drm_device *dev, |
368 | struct drm_clip_rect *boxes, | 358 | struct drm_clip_rect *box, |
369 | int i, int DR1, int DR4) | 359 | int DR1, int DR4) |
370 | { | 360 | { |
371 | struct drm_clip_rect box = boxes[i]; | 361 | struct drm_i915_private *dev_priv = dev->dev_private; |
362 | int ret; | ||
372 | 363 | ||
373 | if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { | 364 | if (box->y2 <= box->y1 || box->x2 <= box->x1 || |
365 | box->y2 <= 0 || box->x2 <= 0) { | ||
374 | DRM_ERROR("Bad box %d,%d..%d,%d\n", | 366 | DRM_ERROR("Bad box %d,%d..%d,%d\n", |
375 | box.x1, box.y1, box.x2, box.y2); | 367 | box->x1, box->y1, box->x2, box->y2); |
376 | return -EINVAL; | 368 | return -EINVAL; |
377 | } | 369 | } |
378 | 370 | ||
379 | if (INTEL_INFO(dev)->gen >= 4) { | 371 | if (INTEL_INFO(dev)->gen >= 4) { |
380 | BEGIN_LP_RING(4); | 372 | ret = BEGIN_LP_RING(4); |
373 | if (ret) | ||
374 | return ret; | ||
375 | |||
381 | OUT_RING(GFX_OP_DRAWRECT_INFO_I965); | 376 | OUT_RING(GFX_OP_DRAWRECT_INFO_I965); |
382 | OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); | 377 | OUT_RING((box->x1 & 0xffff) | (box->y1 << 16)); |
383 | OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); | 378 | OUT_RING(((box->x2 - 1) & 0xffff) | ((box->y2 - 1) << 16)); |
384 | OUT_RING(DR4); | 379 | OUT_RING(DR4); |
385 | ADVANCE_LP_RING(); | ||
386 | } else { | 380 | } else { |
387 | BEGIN_LP_RING(6); | 381 | ret = BEGIN_LP_RING(6); |
382 | if (ret) | ||
383 | return ret; | ||
384 | |||
388 | OUT_RING(GFX_OP_DRAWRECT_INFO); | 385 | OUT_RING(GFX_OP_DRAWRECT_INFO); |
389 | OUT_RING(DR1); | 386 | OUT_RING(DR1); |
390 | OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); | 387 | OUT_RING((box->x1 & 0xffff) | (box->y1 << 16)); |
391 | OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); | 388 | OUT_RING(((box->x2 - 1) & 0xffff) | ((box->y2 - 1) << 16)); |
392 | OUT_RING(DR4); | 389 | OUT_RING(DR4); |
393 | OUT_RING(0); | 390 | OUT_RING(0); |
394 | ADVANCE_LP_RING(); | ||
395 | } | 391 | } |
392 | ADVANCE_LP_RING(); | ||
396 | 393 | ||
397 | return 0; | 394 | return 0; |
398 | } | 395 | } |
@@ -412,12 +409,13 @@ static void i915_emit_breadcrumb(struct drm_device *dev) | |||
412 | if (master_priv->sarea_priv) | 409 | if (master_priv->sarea_priv) |
413 | master_priv->sarea_priv->last_enqueue = dev_priv->counter; | 410 | master_priv->sarea_priv->last_enqueue = dev_priv->counter; |
414 | 411 | ||
415 | BEGIN_LP_RING(4); | 412 | if (BEGIN_LP_RING(4) == 0) { |
416 | OUT_RING(MI_STORE_DWORD_INDEX); | 413 | OUT_RING(MI_STORE_DWORD_INDEX); |
417 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | 414 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
418 | OUT_RING(dev_priv->counter); | 415 | OUT_RING(dev_priv->counter); |
419 | OUT_RING(0); | 416 | OUT_RING(0); |
420 | ADVANCE_LP_RING(); | 417 | ADVANCE_LP_RING(); |
418 | } | ||
421 | } | 419 | } |
422 | 420 | ||
423 | static int i915_dispatch_cmdbuffer(struct drm_device * dev, | 421 | static int i915_dispatch_cmdbuffer(struct drm_device * dev, |
@@ -439,7 +437,7 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev, | |||
439 | 437 | ||
440 | for (i = 0; i < count; i++) { | 438 | for (i = 0; i < count; i++) { |
441 | if (i < nbox) { | 439 | if (i < nbox) { |
442 | ret = i915_emit_box(dev, cliprects, i, | 440 | ret = i915_emit_box(dev, &cliprects[i], |
443 | cmd->DR1, cmd->DR4); | 441 | cmd->DR1, cmd->DR4); |
444 | if (ret) | 442 | if (ret) |
445 | return ret; | 443 | return ret; |
@@ -458,8 +456,9 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, | |||
458 | drm_i915_batchbuffer_t * batch, | 456 | drm_i915_batchbuffer_t * batch, |
459 | struct drm_clip_rect *cliprects) | 457 | struct drm_clip_rect *cliprects) |
460 | { | 458 | { |
459 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
461 | int nbox = batch->num_cliprects; | 460 | int nbox = batch->num_cliprects; |
462 | int i = 0, count; | 461 | int i, count, ret; |
463 | 462 | ||
464 | if ((batch->start | batch->used) & 0x7) { | 463 | if ((batch->start | batch->used) & 0x7) { |
465 | DRM_ERROR("alignment"); | 464 | DRM_ERROR("alignment"); |
@@ -469,17 +468,19 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, | |||
469 | i915_kernel_lost_context(dev); | 468 | i915_kernel_lost_context(dev); |
470 | 469 | ||
471 | count = nbox ? nbox : 1; | 470 | count = nbox ? nbox : 1; |
472 | |||
473 | for (i = 0; i < count; i++) { | 471 | for (i = 0; i < count; i++) { |
474 | if (i < nbox) { | 472 | if (i < nbox) { |
475 | int ret = i915_emit_box(dev, cliprects, i, | 473 | ret = i915_emit_box(dev, &cliprects[i], |
476 | batch->DR1, batch->DR4); | 474 | batch->DR1, batch->DR4); |
477 | if (ret) | 475 | if (ret) |
478 | return ret; | 476 | return ret; |
479 | } | 477 | } |
480 | 478 | ||
481 | if (!IS_I830(dev) && !IS_845G(dev)) { | 479 | if (!IS_I830(dev) && !IS_845G(dev)) { |
482 | BEGIN_LP_RING(2); | 480 | ret = BEGIN_LP_RING(2); |
481 | if (ret) | ||
482 | return ret; | ||
483 | |||
483 | if (INTEL_INFO(dev)->gen >= 4) { | 484 | if (INTEL_INFO(dev)->gen >= 4) { |
484 | OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); | 485 | OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); |
485 | OUT_RING(batch->start); | 486 | OUT_RING(batch->start); |
@@ -487,26 +488,29 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, | |||
487 | OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); | 488 | OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); |
488 | OUT_RING(batch->start | MI_BATCH_NON_SECURE); | 489 | OUT_RING(batch->start | MI_BATCH_NON_SECURE); |
489 | } | 490 | } |
490 | ADVANCE_LP_RING(); | ||
491 | } else { | 491 | } else { |
492 | BEGIN_LP_RING(4); | 492 | ret = BEGIN_LP_RING(4); |
493 | if (ret) | ||
494 | return ret; | ||
495 | |||
493 | OUT_RING(MI_BATCH_BUFFER); | 496 | OUT_RING(MI_BATCH_BUFFER); |
494 | OUT_RING(batch->start | MI_BATCH_NON_SECURE); | 497 | OUT_RING(batch->start | MI_BATCH_NON_SECURE); |
495 | OUT_RING(batch->start + batch->used - 4); | 498 | OUT_RING(batch->start + batch->used - 4); |
496 | OUT_RING(0); | 499 | OUT_RING(0); |
497 | ADVANCE_LP_RING(); | ||
498 | } | 500 | } |
501 | ADVANCE_LP_RING(); | ||
499 | } | 502 | } |
500 | 503 | ||
501 | 504 | ||
502 | if (IS_G4X(dev) || IS_GEN5(dev)) { | 505 | if (IS_G4X(dev) || IS_GEN5(dev)) { |
503 | BEGIN_LP_RING(2); | 506 | if (BEGIN_LP_RING(2) == 0) { |
504 | OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP); | 507 | OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP); |
505 | OUT_RING(MI_NOOP); | 508 | OUT_RING(MI_NOOP); |
506 | ADVANCE_LP_RING(); | 509 | ADVANCE_LP_RING(); |
510 | } | ||
507 | } | 511 | } |
508 | i915_emit_breadcrumb(dev); | ||
509 | 512 | ||
513 | i915_emit_breadcrumb(dev); | ||
510 | return 0; | 514 | return 0; |
511 | } | 515 | } |
512 | 516 | ||
@@ -515,6 +519,7 @@ static int i915_dispatch_flip(struct drm_device * dev) | |||
515 | drm_i915_private_t *dev_priv = dev->dev_private; | 519 | drm_i915_private_t *dev_priv = dev->dev_private; |
516 | struct drm_i915_master_private *master_priv = | 520 | struct drm_i915_master_private *master_priv = |
517 | dev->primary->master->driver_priv; | 521 | dev->primary->master->driver_priv; |
522 | int ret; | ||
518 | 523 | ||
519 | if (!master_priv->sarea_priv) | 524 | if (!master_priv->sarea_priv) |
520 | return -EINVAL; | 525 | return -EINVAL; |
@@ -526,12 +531,13 @@ static int i915_dispatch_flip(struct drm_device * dev) | |||
526 | 531 | ||
527 | i915_kernel_lost_context(dev); | 532 | i915_kernel_lost_context(dev); |
528 | 533 | ||
529 | BEGIN_LP_RING(2); | 534 | ret = BEGIN_LP_RING(10); |
535 | if (ret) | ||
536 | return ret; | ||
537 | |||
530 | OUT_RING(MI_FLUSH | MI_READ_FLUSH); | 538 | OUT_RING(MI_FLUSH | MI_READ_FLUSH); |
531 | OUT_RING(0); | 539 | OUT_RING(0); |
532 | ADVANCE_LP_RING(); | ||
533 | 540 | ||
534 | BEGIN_LP_RING(6); | ||
535 | OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); | 541 | OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); |
536 | OUT_RING(0); | 542 | OUT_RING(0); |
537 | if (dev_priv->current_page == 0) { | 543 | if (dev_priv->current_page == 0) { |
@@ -542,33 +548,32 @@ static int i915_dispatch_flip(struct drm_device * dev) | |||
542 | dev_priv->current_page = 0; | 548 | dev_priv->current_page = 0; |
543 | } | 549 | } |
544 | OUT_RING(0); | 550 | OUT_RING(0); |
545 | ADVANCE_LP_RING(); | ||
546 | 551 | ||
547 | BEGIN_LP_RING(2); | ||
548 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); | 552 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); |
549 | OUT_RING(0); | 553 | OUT_RING(0); |
554 | |||
550 | ADVANCE_LP_RING(); | 555 | ADVANCE_LP_RING(); |
551 | 556 | ||
552 | master_priv->sarea_priv->last_enqueue = dev_priv->counter++; | 557 | master_priv->sarea_priv->last_enqueue = dev_priv->counter++; |
553 | 558 | ||
554 | BEGIN_LP_RING(4); | 559 | if (BEGIN_LP_RING(4) == 0) { |
555 | OUT_RING(MI_STORE_DWORD_INDEX); | 560 | OUT_RING(MI_STORE_DWORD_INDEX); |
556 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | 561 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
557 | OUT_RING(dev_priv->counter); | 562 | OUT_RING(dev_priv->counter); |
558 | OUT_RING(0); | 563 | OUT_RING(0); |
559 | ADVANCE_LP_RING(); | 564 | ADVANCE_LP_RING(); |
565 | } | ||
560 | 566 | ||
561 | master_priv->sarea_priv->pf_current_page = dev_priv->current_page; | 567 | master_priv->sarea_priv->pf_current_page = dev_priv->current_page; |
562 | return 0; | 568 | return 0; |
563 | } | 569 | } |
564 | 570 | ||
565 | static int i915_quiescent(struct drm_device * dev) | 571 | static int i915_quiescent(struct drm_device *dev) |
566 | { | 572 | { |
567 | drm_i915_private_t *dev_priv = dev->dev_private; | 573 | struct intel_ring_buffer *ring = LP_RING(dev->dev_private); |
568 | 574 | ||
569 | i915_kernel_lost_context(dev); | 575 | i915_kernel_lost_context(dev); |
570 | return intel_wait_ring_buffer(dev, &dev_priv->render_ring, | 576 | return intel_wait_ring_buffer(ring, ring->size - 8); |
571 | dev_priv->render_ring.size - 8); | ||
572 | } | 577 | } |
573 | 578 | ||
574 | static int i915_flush_ioctl(struct drm_device *dev, void *data, | 579 | static int i915_flush_ioctl(struct drm_device *dev, void *data, |
@@ -767,6 +772,15 @@ static int i915_getparam(struct drm_device *dev, void *data, | |||
767 | case I915_PARAM_HAS_BLT: | 772 | case I915_PARAM_HAS_BLT: |
768 | value = HAS_BLT(dev); | 773 | value = HAS_BLT(dev); |
769 | break; | 774 | break; |
775 | case I915_PARAM_HAS_RELAXED_FENCING: | ||
776 | value = 1; | ||
777 | break; | ||
778 | case I915_PARAM_HAS_COHERENT_RINGS: | ||
779 | value = 1; | ||
780 | break; | ||
781 | case I915_PARAM_HAS_EXEC_CONSTANTS: | ||
782 | value = INTEL_INFO(dev)->gen >= 4; | ||
783 | break; | ||
770 | default: | 784 | default: |
771 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", | 785 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", |
772 | param->param); | 786 | param->param); |
@@ -822,7 +836,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
822 | { | 836 | { |
823 | drm_i915_private_t *dev_priv = dev->dev_private; | 837 | drm_i915_private_t *dev_priv = dev->dev_private; |
824 | drm_i915_hws_addr_t *hws = data; | 838 | drm_i915_hws_addr_t *hws = data; |
825 | struct intel_ring_buffer *ring = &dev_priv->render_ring; | 839 | struct intel_ring_buffer *ring = LP_RING(dev_priv); |
826 | 840 | ||
827 | if (!I915_NEED_GFX_HWS(dev)) | 841 | if (!I915_NEED_GFX_HWS(dev)) |
828 | return -EINVAL; | 842 | return -EINVAL; |
@@ -1001,73 +1015,47 @@ intel_teardown_mchbar(struct drm_device *dev) | |||
1001 | #define PTE_VALID (1 << 0) | 1015 | #define PTE_VALID (1 << 0) |
1002 | 1016 | ||
1003 | /** | 1017 | /** |
1004 | * i915_gtt_to_phys - take a GTT address and turn it into a physical one | 1018 | * i915_stolen_to_phys - take an offset into stolen memory and turn it into |
1019 | * a physical one | ||
1005 | * @dev: drm device | 1020 | * @dev: drm device |
1006 | * @gtt_addr: address to translate | 1021 | * @offset: address to translate |
1007 | * | 1022 | * |
1008 | * Some chip functions require allocations from stolen space but need the | 1023 | * Some chip functions require allocations from stolen space and need the |
1009 | * physical address of the memory in question. We use this routine | 1024 | * physical address of the memory in question. |
1010 | * to get a physical address suitable for register programming from a given | ||
1011 | * GTT address. | ||
1012 | */ | 1025 | */ |
1013 | static unsigned long i915_gtt_to_phys(struct drm_device *dev, | 1026 | static unsigned long i915_stolen_to_phys(struct drm_device *dev, u32 offset) |
1014 | unsigned long gtt_addr) | ||
1015 | { | 1027 | { |
1016 | unsigned long *gtt; | 1028 | struct drm_i915_private *dev_priv = dev->dev_private; |
1017 | unsigned long entry, phys; | 1029 | struct pci_dev *pdev = dev_priv->bridge_dev; |
1018 | int gtt_bar = IS_GEN2(dev) ? 1 : 0; | 1030 | u32 base; |
1019 | int gtt_offset, gtt_size; | 1031 | |
1020 | 1032 | #if 0 | |
1021 | if (INTEL_INFO(dev)->gen >= 4) { | 1033 | /* On the machines I have tested the Graphics Base of Stolen Memory |
1022 | if (IS_G4X(dev) || INTEL_INFO(dev)->gen > 4) { | 1034 | * is unreliable, so compute the base by subtracting the stolen memory |
1023 | gtt_offset = 2*1024*1024; | 1035 | * from the Top of Low Usable DRAM which is where the BIOS places |
1024 | gtt_size = 2*1024*1024; | 1036 | * the graphics stolen memory. |
1025 | } else { | 1037 | */ |
1026 | gtt_offset = 512*1024; | 1038 | if (INTEL_INFO(dev)->gen > 3 || IS_G33(dev)) { |
1027 | gtt_size = 512*1024; | 1039 | /* top 32bits are reserved = 0 */ |
1028 | } | 1040 | pci_read_config_dword(pdev, 0xA4, &base); |
1029 | } else { | 1041 | } else { |
1030 | gtt_bar = 3; | 1042 | /* XXX presume 8xx is the same as i915 */ |
1031 | gtt_offset = 0; | 1043 | pci_bus_read_config_dword(pdev->bus, 2, 0x5C, &base); |
1032 | gtt_size = pci_resource_len(dev->pdev, gtt_bar); | 1044 | } |
1033 | } | 1045 | #else |
1034 | 1046 | if (INTEL_INFO(dev)->gen > 3 || IS_G33(dev)) { | |
1035 | gtt = ioremap_wc(pci_resource_start(dev->pdev, gtt_bar) + gtt_offset, | 1047 | u16 val; |
1036 | gtt_size); | 1048 | pci_read_config_word(pdev, 0xb0, &val); |
1037 | if (!gtt) { | 1049 | base = val >> 4 << 20; |
1038 | DRM_ERROR("ioremap of GTT failed\n"); | 1050 | } else { |
1039 | return 0; | 1051 | u8 val; |
1040 | } | 1052 | pci_read_config_byte(pdev, 0x9c, &val); |
1041 | 1053 | base = val >> 3 << 27; | |
1042 | entry = *(volatile u32 *)(gtt + (gtt_addr / 1024)); | ||
1043 | |||
1044 | DRM_DEBUG_DRIVER("GTT addr: 0x%08lx, PTE: 0x%08lx\n", gtt_addr, entry); | ||
1045 | |||
1046 | /* Mask out these reserved bits on this hardware. */ | ||
1047 | if (INTEL_INFO(dev)->gen < 4 && !IS_G33(dev)) | ||
1048 | entry &= ~PTE_ADDRESS_MASK_HIGH; | ||
1049 | |||
1050 | /* If it's not a mapping type we know, then bail. */ | ||
1051 | if ((entry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_UNCACHED && | ||
1052 | (entry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_CACHED) { | ||
1053 | iounmap(gtt); | ||
1054 | return 0; | ||
1055 | } | ||
1056 | |||
1057 | if (!(entry & PTE_VALID)) { | ||
1058 | DRM_ERROR("bad GTT entry in stolen space\n"); | ||
1059 | iounmap(gtt); | ||
1060 | return 0; | ||
1061 | } | 1054 | } |
1055 | base -= dev_priv->mm.gtt->stolen_size; | ||
1056 | #endif | ||
1062 | 1057 | ||
1063 | iounmap(gtt); | 1058 | return base + offset; |
1064 | |||
1065 | phys =(entry & PTE_ADDRESS_MASK) | | ||
1066 | ((uint64_t)(entry & PTE_ADDRESS_MASK_HIGH) << (32 - 4)); | ||
1067 | |||
1068 | DRM_DEBUG_DRIVER("GTT addr: 0x%08lx, phys addr: 0x%08lx\n", gtt_addr, phys); | ||
1069 | |||
1070 | return phys; | ||
1071 | } | 1059 | } |
1072 | 1060 | ||
1073 | static void i915_warn_stolen(struct drm_device *dev) | 1061 | static void i915_warn_stolen(struct drm_device *dev) |
@@ -1083,54 +1071,35 @@ static void i915_setup_compression(struct drm_device *dev, int size) | |||
1083 | unsigned long cfb_base; | 1071 | unsigned long cfb_base; |
1084 | unsigned long ll_base = 0; | 1072 | unsigned long ll_base = 0; |
1085 | 1073 | ||
1086 | /* Leave 1M for line length buffer & misc. */ | 1074 | compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096, 0); |
1087 | compressed_fb = drm_mm_search_free(&dev_priv->mm.vram, size, 4096, 0); | 1075 | if (compressed_fb) |
1088 | if (!compressed_fb) { | 1076 | compressed_fb = drm_mm_get_block(compressed_fb, size, 4096); |
1089 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; | 1077 | if (!compressed_fb) |
1090 | i915_warn_stolen(dev); | 1078 | goto err; |
1091 | return; | ||
1092 | } | ||
1093 | 1079 | ||
1094 | compressed_fb = drm_mm_get_block(compressed_fb, size, 4096); | 1080 | cfb_base = i915_stolen_to_phys(dev, compressed_fb->start); |
1095 | if (!compressed_fb) { | 1081 | if (!cfb_base) |
1096 | i915_warn_stolen(dev); | 1082 | goto err_fb; |
1097 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; | ||
1098 | return; | ||
1099 | } | ||
1100 | 1083 | ||
1101 | cfb_base = i915_gtt_to_phys(dev, compressed_fb->start); | 1084 | if (!(IS_GM45(dev) || HAS_PCH_SPLIT(dev))) { |
1102 | if (!cfb_base) { | 1085 | compressed_llb = drm_mm_search_free(&dev_priv->mm.stolen, |
1103 | DRM_ERROR("failed to get stolen phys addr, disabling FBC\n"); | 1086 | 4096, 4096, 0); |
1104 | drm_mm_put_block(compressed_fb); | 1087 | if (compressed_llb) |
1105 | } | 1088 | compressed_llb = drm_mm_get_block(compressed_llb, |
1089 | 4096, 4096); | ||
1090 | if (!compressed_llb) | ||
1091 | goto err_fb; | ||
1106 | 1092 | ||
1107 | if (!(IS_GM45(dev) || IS_IRONLAKE_M(dev))) { | 1093 | ll_base = i915_stolen_to_phys(dev, compressed_llb->start); |
1108 | compressed_llb = drm_mm_search_free(&dev_priv->mm.vram, 4096, | 1094 | if (!ll_base) |
1109 | 4096, 0); | 1095 | goto err_llb; |
1110 | if (!compressed_llb) { | ||
1111 | i915_warn_stolen(dev); | ||
1112 | return; | ||
1113 | } | ||
1114 | |||
1115 | compressed_llb = drm_mm_get_block(compressed_llb, 4096, 4096); | ||
1116 | if (!compressed_llb) { | ||
1117 | i915_warn_stolen(dev); | ||
1118 | return; | ||
1119 | } | ||
1120 | |||
1121 | ll_base = i915_gtt_to_phys(dev, compressed_llb->start); | ||
1122 | if (!ll_base) { | ||
1123 | DRM_ERROR("failed to get stolen phys addr, disabling FBC\n"); | ||
1124 | drm_mm_put_block(compressed_fb); | ||
1125 | drm_mm_put_block(compressed_llb); | ||
1126 | } | ||
1127 | } | 1096 | } |
1128 | 1097 | ||
1129 | dev_priv->cfb_size = size; | 1098 | dev_priv->cfb_size = size; |
1130 | 1099 | ||
1131 | intel_disable_fbc(dev); | 1100 | intel_disable_fbc(dev); |
1132 | dev_priv->compressed_fb = compressed_fb; | 1101 | dev_priv->compressed_fb = compressed_fb; |
1133 | if (IS_IRONLAKE_M(dev)) | 1102 | if (HAS_PCH_SPLIT(dev)) |
1134 | I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start); | 1103 | I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start); |
1135 | else if (IS_GM45(dev)) { | 1104 | else if (IS_GM45(dev)) { |
1136 | I915_WRITE(DPFC_CB_BASE, compressed_fb->start); | 1105 | I915_WRITE(DPFC_CB_BASE, compressed_fb->start); |
@@ -1140,8 +1109,17 @@ static void i915_setup_compression(struct drm_device *dev, int size) | |||
1140 | dev_priv->compressed_llb = compressed_llb; | 1109 | dev_priv->compressed_llb = compressed_llb; |
1141 | } | 1110 | } |
1142 | 1111 | ||
1143 | DRM_DEBUG_KMS("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base, | 1112 | DRM_DEBUG_KMS("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", |
1144 | ll_base, size >> 20); | 1113 | cfb_base, ll_base, size >> 20); |
1114 | return; | ||
1115 | |||
1116 | err_llb: | ||
1117 | drm_mm_put_block(compressed_llb); | ||
1118 | err_fb: | ||
1119 | drm_mm_put_block(compressed_fb); | ||
1120 | err: | ||
1121 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; | ||
1122 | i915_warn_stolen(dev); | ||
1145 | } | 1123 | } |
1146 | 1124 | ||
1147 | static void i915_cleanup_compression(struct drm_device *dev) | 1125 | static void i915_cleanup_compression(struct drm_device *dev) |
@@ -1192,17 +1170,20 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev) | |||
1192 | return can_switch; | 1170 | return can_switch; |
1193 | } | 1171 | } |
1194 | 1172 | ||
1195 | static int i915_load_modeset_init(struct drm_device *dev, | 1173 | static int i915_load_modeset_init(struct drm_device *dev) |
1196 | unsigned long prealloc_size, | ||
1197 | unsigned long agp_size) | ||
1198 | { | 1174 | { |
1199 | struct drm_i915_private *dev_priv = dev->dev_private; | 1175 | struct drm_i915_private *dev_priv = dev->dev_private; |
1176 | unsigned long prealloc_size, gtt_size, mappable_size; | ||
1200 | int ret = 0; | 1177 | int ret = 0; |
1201 | 1178 | ||
1202 | /* Basic memrange allocator for stolen space (aka mm.vram) */ | 1179 | prealloc_size = dev_priv->mm.gtt->stolen_size; |
1203 | drm_mm_init(&dev_priv->mm.vram, 0, prealloc_size); | 1180 | gtt_size = dev_priv->mm.gtt->gtt_total_entries << PAGE_SHIFT; |
1181 | mappable_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; | ||
1182 | |||
1183 | /* Basic memrange allocator for stolen space */ | ||
1184 | drm_mm_init(&dev_priv->mm.stolen, 0, prealloc_size); | ||
1204 | 1185 | ||
1205 | /* Let GEM Manage from end of prealloc space to end of aperture. | 1186 | /* Let GEM Manage all of the aperture. |
1206 | * | 1187 | * |
1207 | * However, leave one page at the end still bound to the scratch page. | 1188 | * However, leave one page at the end still bound to the scratch page. |
1208 | * There are a number of places where the hardware apparently | 1189 | * There are a number of places where the hardware apparently |
@@ -1211,7 +1192,7 @@ static int i915_load_modeset_init(struct drm_device *dev, | |||
1211 | * at the last page of the aperture. One page should be enough to | 1192 | * at the last page of the aperture. One page should be enough to |
1212 | * keep any prefetching inside of the aperture. | 1193 | * keep any prefetching inside of the aperture. |
1213 | */ | 1194 | */ |
1214 | i915_gem_do_init(dev, prealloc_size, agp_size - 4096); | 1195 | i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE); |
1215 | 1196 | ||
1216 | mutex_lock(&dev->struct_mutex); | 1197 | mutex_lock(&dev->struct_mutex); |
1217 | ret = i915_gem_init_ringbuffer(dev); | 1198 | ret = i915_gem_init_ringbuffer(dev); |
@@ -1223,16 +1204,17 @@ static int i915_load_modeset_init(struct drm_device *dev, | |||
1223 | if (I915_HAS_FBC(dev) && i915_powersave) { | 1204 | if (I915_HAS_FBC(dev) && i915_powersave) { |
1224 | int cfb_size; | 1205 | int cfb_size; |
1225 | 1206 | ||
1226 | /* Try to get an 8M buffer... */ | 1207 | /* Leave 1M for line length buffer & misc. */ |
1227 | if (prealloc_size > (9*1024*1024)) | 1208 | |
1228 | cfb_size = 8*1024*1024; | 1209 | /* Try to get a 32M buffer... */ |
1210 | if (prealloc_size > (36*1024*1024)) | ||
1211 | cfb_size = 32*1024*1024; | ||
1229 | else /* fall back to 7/8 of the stolen space */ | 1212 | else /* fall back to 7/8 of the stolen space */ |
1230 | cfb_size = prealloc_size * 7 / 8; | 1213 | cfb_size = prealloc_size * 7 / 8; |
1231 | i915_setup_compression(dev, cfb_size); | 1214 | i915_setup_compression(dev, cfb_size); |
1232 | } | 1215 | } |
1233 | 1216 | ||
1234 | /* Allow hardware batchbuffers unless told otherwise. | 1217 | /* Allow hardware batchbuffers unless told otherwise. */ |
1235 | */ | ||
1236 | dev_priv->allow_batchbuffer = 1; | 1218 | dev_priv->allow_batchbuffer = 1; |
1237 | 1219 | ||
1238 | ret = intel_parse_bios(dev); | 1220 | ret = intel_parse_bios(dev); |
@@ -1422,152 +1404,12 @@ static void i915_ironlake_get_mem_freq(struct drm_device *dev) | |||
1422 | } | 1404 | } |
1423 | } | 1405 | } |
1424 | 1406 | ||
1425 | struct v_table { | 1407 | static const struct cparams { |
1426 | u8 vid; | 1408 | u16 i; |
1427 | unsigned long vd; /* in .1 mil */ | 1409 | u16 t; |
1428 | unsigned long vm; /* in .1 mil */ | 1410 | u16 m; |
1429 | u8 pvid; | 1411 | u16 c; |
1430 | }; | 1412 | } cparams[] = { |
1431 | |||
1432 | static struct v_table v_table[] = { | ||
1433 | { 0, 16125, 15000, 0x7f, }, | ||
1434 | { 1, 16000, 14875, 0x7e, }, | ||
1435 | { 2, 15875, 14750, 0x7d, }, | ||
1436 | { 3, 15750, 14625, 0x7c, }, | ||
1437 | { 4, 15625, 14500, 0x7b, }, | ||
1438 | { 5, 15500, 14375, 0x7a, }, | ||
1439 | { 6, 15375, 14250, 0x79, }, | ||
1440 | { 7, 15250, 14125, 0x78, }, | ||
1441 | { 8, 15125, 14000, 0x77, }, | ||
1442 | { 9, 15000, 13875, 0x76, }, | ||
1443 | { 10, 14875, 13750, 0x75, }, | ||
1444 | { 11, 14750, 13625, 0x74, }, | ||
1445 | { 12, 14625, 13500, 0x73, }, | ||
1446 | { 13, 14500, 13375, 0x72, }, | ||
1447 | { 14, 14375, 13250, 0x71, }, | ||
1448 | { 15, 14250, 13125, 0x70, }, | ||
1449 | { 16, 14125, 13000, 0x6f, }, | ||
1450 | { 17, 14000, 12875, 0x6e, }, | ||
1451 | { 18, 13875, 12750, 0x6d, }, | ||
1452 | { 19, 13750, 12625, 0x6c, }, | ||
1453 | { 20, 13625, 12500, 0x6b, }, | ||
1454 | { 21, 13500, 12375, 0x6a, }, | ||
1455 | { 22, 13375, 12250, 0x69, }, | ||
1456 | { 23, 13250, 12125, 0x68, }, | ||
1457 | { 24, 13125, 12000, 0x67, }, | ||
1458 | { 25, 13000, 11875, 0x66, }, | ||
1459 | { 26, 12875, 11750, 0x65, }, | ||
1460 | { 27, 12750, 11625, 0x64, }, | ||
1461 | { 28, 12625, 11500, 0x63, }, | ||
1462 | { 29, 12500, 11375, 0x62, }, | ||
1463 | { 30, 12375, 11250, 0x61, }, | ||
1464 | { 31, 12250, 11125, 0x60, }, | ||
1465 | { 32, 12125, 11000, 0x5f, }, | ||
1466 | { 33, 12000, 10875, 0x5e, }, | ||
1467 | { 34, 11875, 10750, 0x5d, }, | ||
1468 | { 35, 11750, 10625, 0x5c, }, | ||
1469 | { 36, 11625, 10500, 0x5b, }, | ||
1470 | { 37, 11500, 10375, 0x5a, }, | ||
1471 | { 38, 11375, 10250, 0x59, }, | ||
1472 | { 39, 11250, 10125, 0x58, }, | ||
1473 | { 40, 11125, 10000, 0x57, }, | ||
1474 | { 41, 11000, 9875, 0x56, }, | ||
1475 | { 42, 10875, 9750, 0x55, }, | ||
1476 | { 43, 10750, 9625, 0x54, }, | ||
1477 | { 44, 10625, 9500, 0x53, }, | ||
1478 | { 45, 10500, 9375, 0x52, }, | ||
1479 | { 46, 10375, 9250, 0x51, }, | ||
1480 | { 47, 10250, 9125, 0x50, }, | ||
1481 | { 48, 10125, 9000, 0x4f, }, | ||
1482 | { 49, 10000, 8875, 0x4e, }, | ||
1483 | { 50, 9875, 8750, 0x4d, }, | ||
1484 | { 51, 9750, 8625, 0x4c, }, | ||
1485 | { 52, 9625, 8500, 0x4b, }, | ||
1486 | { 53, 9500, 8375, 0x4a, }, | ||
1487 | { 54, 9375, 8250, 0x49, }, | ||
1488 | { 55, 9250, 8125, 0x48, }, | ||
1489 | { 56, 9125, 8000, 0x47, }, | ||
1490 | { 57, 9000, 7875, 0x46, }, | ||
1491 | { 58, 8875, 7750, 0x45, }, | ||
1492 | { 59, 8750, 7625, 0x44, }, | ||
1493 | { 60, 8625, 7500, 0x43, }, | ||
1494 | { 61, 8500, 7375, 0x42, }, | ||
1495 | { 62, 8375, 7250, 0x41, }, | ||
1496 | { 63, 8250, 7125, 0x40, }, | ||
1497 | { 64, 8125, 7000, 0x3f, }, | ||
1498 | { 65, 8000, 6875, 0x3e, }, | ||
1499 | { 66, 7875, 6750, 0x3d, }, | ||
1500 | { 67, 7750, 6625, 0x3c, }, | ||
1501 | { 68, 7625, 6500, 0x3b, }, | ||
1502 | { 69, 7500, 6375, 0x3a, }, | ||
1503 | { 70, 7375, 6250, 0x39, }, | ||
1504 | { 71, 7250, 6125, 0x38, }, | ||
1505 | { 72, 7125, 6000, 0x37, }, | ||
1506 | { 73, 7000, 5875, 0x36, }, | ||
1507 | { 74, 6875, 5750, 0x35, }, | ||
1508 | { 75, 6750, 5625, 0x34, }, | ||
1509 | { 76, 6625, 5500, 0x33, }, | ||
1510 | { 77, 6500, 5375, 0x32, }, | ||
1511 | { 78, 6375, 5250, 0x31, }, | ||
1512 | { 79, 6250, 5125, 0x30, }, | ||
1513 | { 80, 6125, 5000, 0x2f, }, | ||
1514 | { 81, 6000, 4875, 0x2e, }, | ||
1515 | { 82, 5875, 4750, 0x2d, }, | ||
1516 | { 83, 5750, 4625, 0x2c, }, | ||
1517 | { 84, 5625, 4500, 0x2b, }, | ||
1518 | { 85, 5500, 4375, 0x2a, }, | ||
1519 | { 86, 5375, 4250, 0x29, }, | ||
1520 | { 87, 5250, 4125, 0x28, }, | ||
1521 | { 88, 5125, 4000, 0x27, }, | ||
1522 | { 89, 5000, 3875, 0x26, }, | ||
1523 | { 90, 4875, 3750, 0x25, }, | ||
1524 | { 91, 4750, 3625, 0x24, }, | ||
1525 | { 92, 4625, 3500, 0x23, }, | ||
1526 | { 93, 4500, 3375, 0x22, }, | ||
1527 | { 94, 4375, 3250, 0x21, }, | ||
1528 | { 95, 4250, 3125, 0x20, }, | ||
1529 | { 96, 4125, 3000, 0x1f, }, | ||
1530 | { 97, 4125, 3000, 0x1e, }, | ||
1531 | { 98, 4125, 3000, 0x1d, }, | ||
1532 | { 99, 4125, 3000, 0x1c, }, | ||
1533 | { 100, 4125, 3000, 0x1b, }, | ||
1534 | { 101, 4125, 3000, 0x1a, }, | ||
1535 | { 102, 4125, 3000, 0x19, }, | ||
1536 | { 103, 4125, 3000, 0x18, }, | ||
1537 | { 104, 4125, 3000, 0x17, }, | ||
1538 | { 105, 4125, 3000, 0x16, }, | ||
1539 | { 106, 4125, 3000, 0x15, }, | ||
1540 | { 107, 4125, 3000, 0x14, }, | ||
1541 | { 108, 4125, 3000, 0x13, }, | ||
1542 | { 109, 4125, 3000, 0x12, }, | ||
1543 | { 110, 4125, 3000, 0x11, }, | ||
1544 | { 111, 4125, 3000, 0x10, }, | ||
1545 | { 112, 4125, 3000, 0x0f, }, | ||
1546 | { 113, 4125, 3000, 0x0e, }, | ||
1547 | { 114, 4125, 3000, 0x0d, }, | ||
1548 | { 115, 4125, 3000, 0x0c, }, | ||
1549 | { 116, 4125, 3000, 0x0b, }, | ||
1550 | { 117, 4125, 3000, 0x0a, }, | ||
1551 | { 118, 4125, 3000, 0x09, }, | ||
1552 | { 119, 4125, 3000, 0x08, }, | ||
1553 | { 120, 1125, 0, 0x07, }, | ||
1554 | { 121, 1000, 0, 0x06, }, | ||
1555 | { 122, 875, 0, 0x05, }, | ||
1556 | { 123, 750, 0, 0x04, }, | ||
1557 | { 124, 625, 0, 0x03, }, | ||
1558 | { 125, 500, 0, 0x02, }, | ||
1559 | { 126, 375, 0, 0x01, }, | ||
1560 | { 127, 0, 0, 0x00, }, | ||
1561 | }; | ||
1562 | |||
1563 | struct cparams { | ||
1564 | int i; | ||
1565 | int t; | ||
1566 | int m; | ||
1567 | int c; | ||
1568 | }; | ||
1569 | |||
1570 | static struct cparams cparams[] = { | ||
1571 | { 1, 1333, 301, 28664 }, | 1413 | { 1, 1333, 301, 28664 }, |
1572 | { 1, 1066, 294, 24460 }, | 1414 | { 1, 1066, 294, 24460 }, |
1573 | { 1, 800, 294, 25192 }, | 1415 | { 1, 800, 294, 25192 }, |
@@ -1633,21 +1475,145 @@ unsigned long i915_mch_val(struct drm_i915_private *dev_priv) | |||
1633 | return ((m * x) / 127) - b; | 1475 | return ((m * x) / 127) - b; |
1634 | } | 1476 | } |
1635 | 1477 | ||
1636 | static unsigned long pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid) | 1478 | static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid) |
1637 | { | 1479 | { |
1638 | unsigned long val = 0; | 1480 | static const struct v_table { |
1639 | int i; | 1481 | u16 vd; /* in .1 mil */ |
1640 | 1482 | u16 vm; /* in .1 mil */ | |
1641 | for (i = 0; i < ARRAY_SIZE(v_table); i++) { | 1483 | } v_table[] = { |
1642 | if (v_table[i].pvid == pxvid) { | 1484 | { 0, 0, }, |
1643 | if (IS_MOBILE(dev_priv->dev)) | 1485 | { 375, 0, }, |
1644 | val = v_table[i].vm; | 1486 | { 500, 0, }, |
1645 | else | 1487 | { 625, 0, }, |
1646 | val = v_table[i].vd; | 1488 | { 750, 0, }, |
1647 | } | 1489 | { 875, 0, }, |
1648 | } | 1490 | { 1000, 0, }, |
1649 | 1491 | { 1125, 0, }, | |
1650 | return val; | 1492 | { 4125, 3000, }, |
1493 | { 4125, 3000, }, | ||
1494 | { 4125, 3000, }, | ||
1495 | { 4125, 3000, }, | ||
1496 | { 4125, 3000, }, | ||
1497 | { 4125, 3000, }, | ||
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 | { 4250, 3125, }, | ||
1517 | { 4375, 3250, }, | ||
1518 | { 4500, 3375, }, | ||
1519 | { 4625, 3500, }, | ||
1520 | { 4750, 3625, }, | ||
1521 | { 4875, 3750, }, | ||
1522 | { 5000, 3875, }, | ||
1523 | { 5125, 4000, }, | ||
1524 | { 5250, 4125, }, | ||
1525 | { 5375, 4250, }, | ||
1526 | { 5500, 4375, }, | ||
1527 | { 5625, 4500, }, | ||
1528 | { 5750, 4625, }, | ||
1529 | { 5875, 4750, }, | ||
1530 | { 6000, 4875, }, | ||
1531 | { 6125, 5000, }, | ||
1532 | { 6250, 5125, }, | ||
1533 | { 6375, 5250, }, | ||
1534 | { 6500, 5375, }, | ||
1535 | { 6625, 5500, }, | ||
1536 | { 6750, 5625, }, | ||
1537 | { 6875, 5750, }, | ||
1538 | { 7000, 5875, }, | ||
1539 | { 7125, 6000, }, | ||
1540 | { 7250, 6125, }, | ||
1541 | { 7375, 6250, }, | ||
1542 | { 7500, 6375, }, | ||
1543 | { 7625, 6500, }, | ||
1544 | { 7750, 6625, }, | ||
1545 | { 7875, 6750, }, | ||
1546 | { 8000, 6875, }, | ||
1547 | { 8125, 7000, }, | ||
1548 | { 8250, 7125, }, | ||
1549 | { 8375, 7250, }, | ||
1550 | { 8500, 7375, }, | ||
1551 | { 8625, 7500, }, | ||
1552 | { 8750, 7625, }, | ||
1553 | { 8875, 7750, }, | ||
1554 | { 9000, 7875, }, | ||
1555 | { 9125, 8000, }, | ||
1556 | { 9250, 8125, }, | ||
1557 | { 9375, 8250, }, | ||
1558 | { 9500, 8375, }, | ||
1559 | { 9625, 8500, }, | ||
1560 | { 9750, 8625, }, | ||
1561 | { 9875, 8750, }, | ||
1562 | { 10000, 8875, }, | ||
1563 | { 10125, 9000, }, | ||
1564 | { 10250, 9125, }, | ||
1565 | { 10375, 9250, }, | ||
1566 | { 10500, 9375, }, | ||
1567 | { 10625, 9500, }, | ||
1568 | { 10750, 9625, }, | ||
1569 | { 10875, 9750, }, | ||
1570 | { 11000, 9875, }, | ||
1571 | { 11125, 10000, }, | ||
1572 | { 11250, 10125, }, | ||
1573 | { 11375, 10250, }, | ||
1574 | { 11500, 10375, }, | ||
1575 | { 11625, 10500, }, | ||
1576 | { 11750, 10625, }, | ||
1577 | { 11875, 10750, }, | ||
1578 | { 12000, 10875, }, | ||
1579 | { 12125, 11000, }, | ||
1580 | { 12250, 11125, }, | ||
1581 | { 12375, 11250, }, | ||
1582 | { 12500, 11375, }, | ||
1583 | { 12625, 11500, }, | ||
1584 | { 12750, 11625, }, | ||
1585 | { 12875, 11750, }, | ||
1586 | { 13000, 11875, }, | ||
1587 | { 13125, 12000, }, | ||
1588 | { 13250, 12125, }, | ||
1589 | { 13375, 12250, }, | ||
1590 | { 13500, 12375, }, | ||
1591 | { 13625, 12500, }, | ||
1592 | { 13750, 12625, }, | ||
1593 | { 13875, 12750, }, | ||
1594 | { 14000, 12875, }, | ||
1595 | { 14125, 13000, }, | ||
1596 | { 14250, 13125, }, | ||
1597 | { 14375, 13250, }, | ||
1598 | { 14500, 13375, }, | ||
1599 | { 14625, 13500, }, | ||
1600 | { 14750, 13625, }, | ||
1601 | { 14875, 13750, }, | ||
1602 | { 15000, 13875, }, | ||
1603 | { 15125, 14000, }, | ||
1604 | { 15250, 14125, }, | ||
1605 | { 15375, 14250, }, | ||
1606 | { 15500, 14375, }, | ||
1607 | { 15625, 14500, }, | ||
1608 | { 15750, 14625, }, | ||
1609 | { 15875, 14750, }, | ||
1610 | { 16000, 14875, }, | ||
1611 | { 16125, 15000, }, | ||
1612 | }; | ||
1613 | if (dev_priv->info->is_mobile) | ||
1614 | return v_table[pxvid].vm; | ||
1615 | else | ||
1616 | return v_table[pxvid].vd; | ||
1651 | } | 1617 | } |
1652 | 1618 | ||
1653 | void i915_update_gfx_val(struct drm_i915_private *dev_priv) | 1619 | void i915_update_gfx_val(struct drm_i915_private *dev_priv) |
@@ -1881,9 +1847,9 @@ EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable); | |||
1881 | int i915_driver_load(struct drm_device *dev, unsigned long flags) | 1847 | int i915_driver_load(struct drm_device *dev, unsigned long flags) |
1882 | { | 1848 | { |
1883 | struct drm_i915_private *dev_priv; | 1849 | struct drm_i915_private *dev_priv; |
1884 | resource_size_t base, size; | ||
1885 | int ret = 0, mmio_bar; | 1850 | int ret = 0, mmio_bar; |
1886 | uint32_t agp_size, prealloc_size; | 1851 | uint32_t agp_size; |
1852 | |||
1887 | /* i915 has 4 more counters */ | 1853 | /* i915 has 4 more counters */ |
1888 | dev->counters += 4; | 1854 | dev->counters += 4; |
1889 | dev->types[6] = _DRM_STAT_IRQ; | 1855 | dev->types[6] = _DRM_STAT_IRQ; |
@@ -1899,11 +1865,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1899 | dev_priv->dev = dev; | 1865 | dev_priv->dev = dev; |
1900 | dev_priv->info = (struct intel_device_info *) flags; | 1866 | dev_priv->info = (struct intel_device_info *) flags; |
1901 | 1867 | ||
1902 | /* Add register map (needed for suspend/resume) */ | ||
1903 | mmio_bar = IS_GEN2(dev) ? 1 : 0; | ||
1904 | base = pci_resource_start(dev->pdev, mmio_bar); | ||
1905 | size = pci_resource_len(dev->pdev, mmio_bar); | ||
1906 | |||
1907 | if (i915_get_bridge_dev(dev)) { | 1868 | if (i915_get_bridge_dev(dev)) { |
1908 | ret = -EIO; | 1869 | ret = -EIO; |
1909 | goto free_priv; | 1870 | goto free_priv; |
@@ -1913,16 +1874,25 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1913 | if (IS_GEN2(dev)) | 1874 | if (IS_GEN2(dev)) |
1914 | dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); | 1875 | dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); |
1915 | 1876 | ||
1916 | dev_priv->regs = ioremap(base, size); | 1877 | mmio_bar = IS_GEN2(dev) ? 1 : 0; |
1878 | dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, 0); | ||
1917 | if (!dev_priv->regs) { | 1879 | if (!dev_priv->regs) { |
1918 | DRM_ERROR("failed to map registers\n"); | 1880 | DRM_ERROR("failed to map registers\n"); |
1919 | ret = -EIO; | 1881 | ret = -EIO; |
1920 | goto put_bridge; | 1882 | goto put_bridge; |
1921 | } | 1883 | } |
1922 | 1884 | ||
1885 | dev_priv->mm.gtt = intel_gtt_get(); | ||
1886 | if (!dev_priv->mm.gtt) { | ||
1887 | DRM_ERROR("Failed to initialize GTT\n"); | ||
1888 | ret = -ENODEV; | ||
1889 | goto out_iomapfree; | ||
1890 | } | ||
1891 | |||
1892 | agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; | ||
1893 | |||
1923 | dev_priv->mm.gtt_mapping = | 1894 | dev_priv->mm.gtt_mapping = |
1924 | io_mapping_create_wc(dev->agp->base, | 1895 | io_mapping_create_wc(dev->agp->base, agp_size); |
1925 | dev->agp->agp_info.aper_size * 1024*1024); | ||
1926 | if (dev_priv->mm.gtt_mapping == NULL) { | 1896 | if (dev_priv->mm.gtt_mapping == NULL) { |
1927 | ret = -EIO; | 1897 | ret = -EIO; |
1928 | goto out_rmmap; | 1898 | goto out_rmmap; |
@@ -1934,24 +1904,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1934 | * MTRR if present. Even if a UC MTRR isn't present. | 1904 | * MTRR if present. Even if a UC MTRR isn't present. |
1935 | */ | 1905 | */ |
1936 | dev_priv->mm.gtt_mtrr = mtrr_add(dev->agp->base, | 1906 | dev_priv->mm.gtt_mtrr = mtrr_add(dev->agp->base, |
1937 | dev->agp->agp_info.aper_size * | 1907 | agp_size, |
1938 | 1024 * 1024, | ||
1939 | MTRR_TYPE_WRCOMB, 1); | 1908 | MTRR_TYPE_WRCOMB, 1); |
1940 | if (dev_priv->mm.gtt_mtrr < 0) { | 1909 | if (dev_priv->mm.gtt_mtrr < 0) { |
1941 | DRM_INFO("MTRR allocation failed. Graphics " | 1910 | DRM_INFO("MTRR allocation failed. Graphics " |
1942 | "performance may suffer.\n"); | 1911 | "performance may suffer.\n"); |
1943 | } | 1912 | } |
1944 | 1913 | ||
1945 | dev_priv->mm.gtt = intel_gtt_get(); | ||
1946 | if (!dev_priv->mm.gtt) { | ||
1947 | DRM_ERROR("Failed to initialize GTT\n"); | ||
1948 | ret = -ENODEV; | ||
1949 | goto out_iomapfree; | ||
1950 | } | ||
1951 | |||
1952 | prealloc_size = dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT; | ||
1953 | agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; | ||
1954 | |||
1955 | /* The i915 workqueue is primarily used for batched retirement of | 1914 | /* The i915 workqueue is primarily used for batched retirement of |
1956 | * requests (and thus managing bo) once the task has been completed | 1915 | * requests (and thus managing bo) once the task has been completed |
1957 | * by the GPU. i915_gem_retire_requests() is called directly when we | 1916 | * by the GPU. i915_gem_retire_requests() is called directly when we |
@@ -1959,7 +1918,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1959 | * bo. | 1918 | * bo. |
1960 | * | 1919 | * |
1961 | * It is also used for periodic low-priority events, such as | 1920 | * It is also used for periodic low-priority events, such as |
1962 | * idle-timers and hangcheck. | 1921 | * idle-timers and recording error state. |
1963 | * | 1922 | * |
1964 | * All tasks on the workqueue are expected to acquire the dev mutex | 1923 | * All tasks on the workqueue are expected to acquire the dev mutex |
1965 | * so there is no point in running more than one instance of the | 1924 | * so there is no point in running more than one instance of the |
@@ -1977,20 +1936,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1977 | /* enable GEM by default */ | 1936 | /* enable GEM by default */ |
1978 | dev_priv->has_gem = 1; | 1937 | dev_priv->has_gem = 1; |
1979 | 1938 | ||
1980 | if (prealloc_size > agp_size * 3 / 4) { | ||
1981 | DRM_ERROR("Detected broken video BIOS with %d/%dkB of video " | ||
1982 | "memory stolen.\n", | ||
1983 | prealloc_size / 1024, agp_size / 1024); | ||
1984 | DRM_ERROR("Disabling GEM. (try reducing stolen memory or " | ||
1985 | "updating the BIOS to fix).\n"); | ||
1986 | dev_priv->has_gem = 0; | ||
1987 | } | ||
1988 | |||
1989 | if (dev_priv->has_gem == 0 && | 1939 | if (dev_priv->has_gem == 0 && |
1990 | drm_core_check_feature(dev, DRIVER_MODESET)) { | 1940 | drm_core_check_feature(dev, DRIVER_MODESET)) { |
1991 | DRM_ERROR("kernel modesetting requires GEM, disabling driver.\n"); | 1941 | DRM_ERROR("kernel modesetting requires GEM, disabling driver.\n"); |
1992 | ret = -ENODEV; | 1942 | ret = -ENODEV; |
1993 | goto out_iomapfree; | 1943 | goto out_workqueue_free; |
1994 | } | 1944 | } |
1995 | 1945 | ||
1996 | dev->driver->get_vblank_counter = i915_get_vblank_counter; | 1946 | dev->driver->get_vblank_counter = i915_get_vblank_counter; |
@@ -2013,8 +1963,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2013 | /* Init HWS */ | 1963 | /* Init HWS */ |
2014 | if (!I915_NEED_GFX_HWS(dev)) { | 1964 | if (!I915_NEED_GFX_HWS(dev)) { |
2015 | ret = i915_init_phys_hws(dev); | 1965 | ret = i915_init_phys_hws(dev); |
2016 | if (ret != 0) | 1966 | if (ret) |
2017 | goto out_workqueue_free; | 1967 | goto out_gem_unload; |
2018 | } | 1968 | } |
2019 | 1969 | ||
2020 | if (IS_PINEVIEW(dev)) | 1970 | if (IS_PINEVIEW(dev)) |
@@ -2036,16 +1986,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2036 | if (!IS_I945G(dev) && !IS_I945GM(dev)) | 1986 | if (!IS_I945G(dev) && !IS_I945GM(dev)) |
2037 | pci_enable_msi(dev->pdev); | 1987 | pci_enable_msi(dev->pdev); |
2038 | 1988 | ||
2039 | spin_lock_init(&dev_priv->user_irq_lock); | 1989 | spin_lock_init(&dev_priv->irq_lock); |
2040 | spin_lock_init(&dev_priv->error_lock); | 1990 | spin_lock_init(&dev_priv->error_lock); |
2041 | dev_priv->trace_irq_seqno = 0; | 1991 | dev_priv->trace_irq_seqno = 0; |
2042 | 1992 | ||
2043 | ret = drm_vblank_init(dev, I915_NUM_PIPE); | 1993 | ret = drm_vblank_init(dev, I915_NUM_PIPE); |
2044 | 1994 | if (ret) | |
2045 | if (ret) { | 1995 | goto out_gem_unload; |
2046 | (void) i915_driver_unload(dev); | ||
2047 | return ret; | ||
2048 | } | ||
2049 | 1996 | ||
2050 | /* Start out suspended */ | 1997 | /* Start out suspended */ |
2051 | dev_priv->mm.suspended = 1; | 1998 | dev_priv->mm.suspended = 1; |
@@ -2053,10 +2000,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2053 | intel_detect_pch(dev); | 2000 | intel_detect_pch(dev); |
2054 | 2001 | ||
2055 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 2002 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
2056 | ret = i915_load_modeset_init(dev, prealloc_size, agp_size); | 2003 | ret = i915_load_modeset_init(dev); |
2057 | if (ret < 0) { | 2004 | if (ret < 0) { |
2058 | DRM_ERROR("failed to init modeset\n"); | 2005 | DRM_ERROR("failed to init modeset\n"); |
2059 | goto out_workqueue_free; | 2006 | goto out_gem_unload; |
2060 | } | 2007 | } |
2061 | } | 2008 | } |
2062 | 2009 | ||
@@ -2074,12 +2021,18 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2074 | 2021 | ||
2075 | return 0; | 2022 | return 0; |
2076 | 2023 | ||
2024 | out_gem_unload: | ||
2025 | if (dev->pdev->msi_enabled) | ||
2026 | pci_disable_msi(dev->pdev); | ||
2027 | |||
2028 | intel_teardown_gmbus(dev); | ||
2029 | intel_teardown_mchbar(dev); | ||
2077 | out_workqueue_free: | 2030 | out_workqueue_free: |
2078 | destroy_workqueue(dev_priv->wq); | 2031 | destroy_workqueue(dev_priv->wq); |
2079 | out_iomapfree: | 2032 | out_iomapfree: |
2080 | io_mapping_free(dev_priv->mm.gtt_mapping); | 2033 | io_mapping_free(dev_priv->mm.gtt_mapping); |
2081 | out_rmmap: | 2034 | out_rmmap: |
2082 | iounmap(dev_priv->regs); | 2035 | pci_iounmap(dev->pdev, dev_priv->regs); |
2083 | put_bridge: | 2036 | put_bridge: |
2084 | pci_dev_put(dev_priv->bridge_dev); | 2037 | pci_dev_put(dev_priv->bridge_dev); |
2085 | free_priv: | 2038 | free_priv: |
@@ -2096,6 +2049,9 @@ int i915_driver_unload(struct drm_device *dev) | |||
2096 | i915_mch_dev = NULL; | 2049 | i915_mch_dev = NULL; |
2097 | spin_unlock(&mchdev_lock); | 2050 | spin_unlock(&mchdev_lock); |
2098 | 2051 | ||
2052 | if (dev_priv->mm.inactive_shrinker.shrink) | ||
2053 | unregister_shrinker(&dev_priv->mm.inactive_shrinker); | ||
2054 | |||
2099 | mutex_lock(&dev->struct_mutex); | 2055 | mutex_lock(&dev->struct_mutex); |
2100 | ret = i915_gpu_idle(dev); | 2056 | ret = i915_gpu_idle(dev); |
2101 | if (ret) | 2057 | if (ret) |
@@ -2153,7 +2109,7 @@ int i915_driver_unload(struct drm_device *dev) | |||
2153 | mutex_unlock(&dev->struct_mutex); | 2109 | mutex_unlock(&dev->struct_mutex); |
2154 | if (I915_HAS_FBC(dev) && i915_powersave) | 2110 | if (I915_HAS_FBC(dev) && i915_powersave) |
2155 | i915_cleanup_compression(dev); | 2111 | i915_cleanup_compression(dev); |
2156 | drm_mm_takedown(&dev_priv->mm.vram); | 2112 | drm_mm_takedown(&dev_priv->mm.stolen); |
2157 | 2113 | ||
2158 | intel_cleanup_overlay(dev); | 2114 | intel_cleanup_overlay(dev); |
2159 | 2115 | ||
@@ -2162,7 +2118,7 @@ int i915_driver_unload(struct drm_device *dev) | |||
2162 | } | 2118 | } |
2163 | 2119 | ||
2164 | if (dev_priv->regs != NULL) | 2120 | if (dev_priv->regs != NULL) |
2165 | iounmap(dev_priv->regs); | 2121 | pci_iounmap(dev->pdev, dev_priv->regs); |
2166 | 2122 | ||
2167 | intel_teardown_gmbus(dev); | 2123 | intel_teardown_gmbus(dev); |
2168 | intel_teardown_mchbar(dev); | 2124 | intel_teardown_mchbar(dev); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f737960712e..9eee6cf7901 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -111,7 +111,7 @@ static const struct intel_device_info intel_i965g_info = { | |||
111 | 111 | ||
112 | static const struct intel_device_info intel_i965gm_info = { | 112 | static const struct intel_device_info intel_i965gm_info = { |
113 | .gen = 4, .is_crestline = 1, | 113 | .gen = 4, .is_crestline = 1, |
114 | .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, | 114 | .is_mobile = 1, .has_fbc = 1, .has_hotplug = 1, |
115 | .has_overlay = 1, | 115 | .has_overlay = 1, |
116 | .supports_tv = 1, | 116 | .supports_tv = 1, |
117 | }; | 117 | }; |
@@ -130,7 +130,7 @@ static const struct intel_device_info intel_g45_info = { | |||
130 | 130 | ||
131 | static const struct intel_device_info intel_gm45_info = { | 131 | static const struct intel_device_info intel_gm45_info = { |
132 | .gen = 4, .is_g4x = 1, | 132 | .gen = 4, .is_g4x = 1, |
133 | .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, | 133 | .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, |
134 | .has_pipe_cxsr = 1, .has_hotplug = 1, | 134 | .has_pipe_cxsr = 1, .has_hotplug = 1, |
135 | .supports_tv = 1, | 135 | .supports_tv = 1, |
136 | .has_bsd_ring = 1, | 136 | .has_bsd_ring = 1, |
@@ -150,7 +150,7 @@ static const struct intel_device_info intel_ironlake_d_info = { | |||
150 | 150 | ||
151 | static const struct intel_device_info intel_ironlake_m_info = { | 151 | static const struct intel_device_info intel_ironlake_m_info = { |
152 | .gen = 5, .is_mobile = 1, | 152 | .gen = 5, .is_mobile = 1, |
153 | .need_gfx_hws = 1, .has_rc6 = 1, .has_hotplug = 1, | 153 | .need_gfx_hws = 1, .has_hotplug = 1, |
154 | .has_fbc = 0, /* disabled due to buggy hardware */ | 154 | .has_fbc = 0, /* disabled due to buggy hardware */ |
155 | .has_bsd_ring = 1, | 155 | .has_bsd_ring = 1, |
156 | }; | 156 | }; |
@@ -165,6 +165,7 @@ static const struct intel_device_info intel_sandybridge_d_info = { | |||
165 | static const struct intel_device_info intel_sandybridge_m_info = { | 165 | static const struct intel_device_info intel_sandybridge_m_info = { |
166 | .gen = 6, .is_mobile = 1, | 166 | .gen = 6, .is_mobile = 1, |
167 | .need_gfx_hws = 1, .has_hotplug = 1, | 167 | .need_gfx_hws = 1, .has_hotplug = 1, |
168 | .has_fbc = 1, | ||
168 | .has_bsd_ring = 1, | 169 | .has_bsd_ring = 1, |
169 | .has_blt_ring = 1, | 170 | .has_blt_ring = 1, |
170 | }; | 171 | }; |
@@ -244,6 +245,28 @@ void intel_detect_pch (struct drm_device *dev) | |||
244 | } | 245 | } |
245 | } | 246 | } |
246 | 247 | ||
248 | void __gen6_force_wake_get(struct drm_i915_private *dev_priv) | ||
249 | { | ||
250 | int count; | ||
251 | |||
252 | count = 0; | ||
253 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1)) | ||
254 | udelay(10); | ||
255 | |||
256 | I915_WRITE_NOTRACE(FORCEWAKE, 1); | ||
257 | POSTING_READ(FORCEWAKE); | ||
258 | |||
259 | count = 0; | ||
260 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0) | ||
261 | udelay(10); | ||
262 | } | ||
263 | |||
264 | void __gen6_force_wake_put(struct drm_i915_private *dev_priv) | ||
265 | { | ||
266 | I915_WRITE_NOTRACE(FORCEWAKE, 0); | ||
267 | POSTING_READ(FORCEWAKE); | ||
268 | } | ||
269 | |||
247 | static int i915_drm_freeze(struct drm_device *dev) | 270 | static int i915_drm_freeze(struct drm_device *dev) |
248 | { | 271 | { |
249 | struct drm_i915_private *dev_priv = dev->dev_private; | 272 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -304,6 +327,12 @@ static int i915_drm_thaw(struct drm_device *dev) | |||
304 | struct drm_i915_private *dev_priv = dev->dev_private; | 327 | struct drm_i915_private *dev_priv = dev->dev_private; |
305 | int error = 0; | 328 | int error = 0; |
306 | 329 | ||
330 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
331 | mutex_lock(&dev->struct_mutex); | ||
332 | i915_gem_restore_gtt_mappings(dev); | ||
333 | mutex_unlock(&dev->struct_mutex); | ||
334 | } | ||
335 | |||
307 | i915_restore_state(dev); | 336 | i915_restore_state(dev); |
308 | intel_opregion_setup(dev); | 337 | intel_opregion_setup(dev); |
309 | 338 | ||
@@ -405,6 +434,14 @@ static int ironlake_do_reset(struct drm_device *dev, u8 flags) | |||
405 | return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); | 434 | return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); |
406 | } | 435 | } |
407 | 436 | ||
437 | static int gen6_do_reset(struct drm_device *dev, u8 flags) | ||
438 | { | ||
439 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
440 | |||
441 | I915_WRITE(GEN6_GDRST, GEN6_GRDOM_FULL); | ||
442 | return wait_for((I915_READ(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); | ||
443 | } | ||
444 | |||
408 | /** | 445 | /** |
409 | * i965_reset - reset chip after a hang | 446 | * i965_reset - reset chip after a hang |
410 | * @dev: drm device to reset | 447 | * @dev: drm device to reset |
@@ -431,7 +468,8 @@ int i915_reset(struct drm_device *dev, u8 flags) | |||
431 | bool need_display = true; | 468 | bool need_display = true; |
432 | int ret; | 469 | int ret; |
433 | 470 | ||
434 | mutex_lock(&dev->struct_mutex); | 471 | if (!mutex_trylock(&dev->struct_mutex)) |
472 | return -EBUSY; | ||
435 | 473 | ||
436 | i915_gem_reset(dev); | 474 | i915_gem_reset(dev); |
437 | 475 | ||
@@ -439,6 +477,9 @@ int i915_reset(struct drm_device *dev, u8 flags) | |||
439 | if (get_seconds() - dev_priv->last_gpu_reset < 5) { | 477 | if (get_seconds() - dev_priv->last_gpu_reset < 5) { |
440 | DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); | 478 | DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); |
441 | } else switch (INTEL_INFO(dev)->gen) { | 479 | } else switch (INTEL_INFO(dev)->gen) { |
480 | case 6: | ||
481 | ret = gen6_do_reset(dev, flags); | ||
482 | break; | ||
442 | case 5: | 483 | case 5: |
443 | ret = ironlake_do_reset(dev, flags); | 484 | ret = ironlake_do_reset(dev, flags); |
444 | break; | 485 | break; |
@@ -472,9 +513,14 @@ int i915_reset(struct drm_device *dev, u8 flags) | |||
472 | */ | 513 | */ |
473 | if (drm_core_check_feature(dev, DRIVER_MODESET) || | 514 | if (drm_core_check_feature(dev, DRIVER_MODESET) || |
474 | !dev_priv->mm.suspended) { | 515 | !dev_priv->mm.suspended) { |
475 | struct intel_ring_buffer *ring = &dev_priv->render_ring; | ||
476 | dev_priv->mm.suspended = 0; | 516 | dev_priv->mm.suspended = 0; |
477 | ring->init(dev, ring); | 517 | |
518 | dev_priv->ring[RCS].init(&dev_priv->ring[RCS]); | ||
519 | if (HAS_BSD(dev)) | ||
520 | dev_priv->ring[VCS].init(&dev_priv->ring[VCS]); | ||
521 | if (HAS_BLT(dev)) | ||
522 | dev_priv->ring[BCS].init(&dev_priv->ring[BCS]); | ||
523 | |||
478 | mutex_unlock(&dev->struct_mutex); | 524 | mutex_unlock(&dev->struct_mutex); |
479 | drm_irq_uninstall(dev); | 525 | drm_irq_uninstall(dev); |
480 | drm_irq_install(dev); | 526 | drm_irq_install(dev); |
@@ -606,6 +652,8 @@ static struct drm_driver driver = { | |||
606 | .device_is_agp = i915_driver_device_is_agp, | 652 | .device_is_agp = i915_driver_device_is_agp, |
607 | .enable_vblank = i915_enable_vblank, | 653 | .enable_vblank = i915_enable_vblank, |
608 | .disable_vblank = i915_disable_vblank, | 654 | .disable_vblank = i915_disable_vblank, |
655 | .get_vblank_timestamp = i915_get_vblank_timestamp, | ||
656 | .get_scanout_position = i915_get_crtc_scanoutpos, | ||
609 | .irq_preinstall = i915_driver_irq_preinstall, | 657 | .irq_preinstall = i915_driver_irq_preinstall, |
610 | .irq_postinstall = i915_driver_irq_postinstall, | 658 | .irq_postinstall = i915_driver_irq_postinstall, |
611 | .irq_uninstall = i915_driver_irq_uninstall, | 659 | .irq_uninstall = i915_driver_irq_uninstall, |
@@ -661,8 +709,6 @@ static int __init i915_init(void) | |||
661 | 709 | ||
662 | driver.num_ioctls = i915_max_ioctl; | 710 | driver.num_ioctls = i915_max_ioctl; |
663 | 711 | ||
664 | i915_gem_shrinker_init(); | ||
665 | |||
666 | /* | 712 | /* |
667 | * If CONFIG_DRM_I915_KMS is set, default to KMS unless | 713 | * If CONFIG_DRM_I915_KMS is set, default to KMS unless |
668 | * explicitly disabled with the module pararmeter. | 714 | * explicitly disabled with the module pararmeter. |
@@ -684,17 +730,11 @@ static int __init i915_init(void) | |||
684 | driver.driver_features &= ~DRIVER_MODESET; | 730 | driver.driver_features &= ~DRIVER_MODESET; |
685 | #endif | 731 | #endif |
686 | 732 | ||
687 | if (!(driver.driver_features & DRIVER_MODESET)) { | ||
688 | driver.suspend = i915_suspend; | ||
689 | driver.resume = i915_resume; | ||
690 | } | ||
691 | |||
692 | return drm_init(&driver); | 733 | return drm_init(&driver); |
693 | } | 734 | } |
694 | 735 | ||
695 | static void __exit i915_exit(void) | 736 | static void __exit i915_exit(void) |
696 | { | 737 | { |
697 | i915_gem_shrinker_exit(); | ||
698 | drm_exit(&driver); | 738 | drm_exit(&driver); |
699 | } | 739 | } |
700 | 740 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 409826da309..aac1bf332f7 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -89,7 +89,7 @@ struct drm_i915_gem_phys_object { | |||
89 | int id; | 89 | int id; |
90 | struct page **page_list; | 90 | struct page **page_list; |
91 | drm_dma_handle_t *handle; | 91 | drm_dma_handle_t *handle; |
92 | struct drm_gem_object *cur_obj; | 92 | struct drm_i915_gem_object *cur_obj; |
93 | }; | 93 | }; |
94 | 94 | ||
95 | struct mem_block { | 95 | struct mem_block { |
@@ -124,9 +124,9 @@ struct drm_i915_master_private { | |||
124 | #define I915_FENCE_REG_NONE -1 | 124 | #define I915_FENCE_REG_NONE -1 |
125 | 125 | ||
126 | struct drm_i915_fence_reg { | 126 | struct drm_i915_fence_reg { |
127 | struct drm_gem_object *obj; | ||
128 | struct list_head lru_list; | 127 | struct list_head lru_list; |
129 | bool gpu; | 128 | struct drm_i915_gem_object *obj; |
129 | uint32_t setup_seqno; | ||
130 | }; | 130 | }; |
131 | 131 | ||
132 | struct sdvo_device_mapping { | 132 | struct sdvo_device_mapping { |
@@ -139,6 +139,8 @@ struct sdvo_device_mapping { | |||
139 | u8 ddc_pin; | 139 | u8 ddc_pin; |
140 | }; | 140 | }; |
141 | 141 | ||
142 | struct intel_display_error_state; | ||
143 | |||
142 | struct drm_i915_error_state { | 144 | struct drm_i915_error_state { |
143 | u32 eir; | 145 | u32 eir; |
144 | u32 pgtbl_er; | 146 | u32 pgtbl_er; |
@@ -148,11 +150,23 @@ struct drm_i915_error_state { | |||
148 | u32 ipehr; | 150 | u32 ipehr; |
149 | u32 instdone; | 151 | u32 instdone; |
150 | u32 acthd; | 152 | u32 acthd; |
153 | u32 error; /* gen6+ */ | ||
154 | u32 bcs_acthd; /* gen6+ blt engine */ | ||
155 | u32 bcs_ipehr; | ||
156 | u32 bcs_ipeir; | ||
157 | u32 bcs_instdone; | ||
158 | u32 bcs_seqno; | ||
159 | u32 vcs_acthd; /* gen6+ bsd engine */ | ||
160 | u32 vcs_ipehr; | ||
161 | u32 vcs_ipeir; | ||
162 | u32 vcs_instdone; | ||
163 | u32 vcs_seqno; | ||
151 | u32 instpm; | 164 | u32 instpm; |
152 | u32 instps; | 165 | u32 instps; |
153 | u32 instdone1; | 166 | u32 instdone1; |
154 | u32 seqno; | 167 | u32 seqno; |
155 | u64 bbaddr; | 168 | u64 bbaddr; |
169 | u64 fence[16]; | ||
156 | struct timeval time; | 170 | struct timeval time; |
157 | struct drm_i915_error_object { | 171 | struct drm_i915_error_object { |
158 | int page_count; | 172 | int page_count; |
@@ -171,9 +185,11 @@ struct drm_i915_error_state { | |||
171 | u32 tiling:2; | 185 | u32 tiling:2; |
172 | u32 dirty:1; | 186 | u32 dirty:1; |
173 | u32 purgeable:1; | 187 | u32 purgeable:1; |
174 | } *active_bo; | 188 | u32 ring:4; |
175 | u32 active_bo_count; | 189 | } *active_bo, *pinned_bo; |
190 | u32 active_bo_count, pinned_bo_count; | ||
176 | struct intel_overlay_error_state *overlay; | 191 | struct intel_overlay_error_state *overlay; |
192 | struct intel_display_error_state *display; | ||
177 | }; | 193 | }; |
178 | 194 | ||
179 | struct drm_i915_display_funcs { | 195 | struct drm_i915_display_funcs { |
@@ -207,7 +223,6 @@ struct intel_device_info { | |||
207 | u8 is_broadwater : 1; | 223 | u8 is_broadwater : 1; |
208 | u8 is_crestline : 1; | 224 | u8 is_crestline : 1; |
209 | u8 has_fbc : 1; | 225 | u8 has_fbc : 1; |
210 | u8 has_rc6 : 1; | ||
211 | u8 has_pipe_cxsr : 1; | 226 | u8 has_pipe_cxsr : 1; |
212 | u8 has_hotplug : 1; | 227 | u8 has_hotplug : 1; |
213 | u8 cursor_needs_physical : 1; | 228 | u8 cursor_needs_physical : 1; |
@@ -243,6 +258,7 @@ typedef struct drm_i915_private { | |||
243 | const struct intel_device_info *info; | 258 | const struct intel_device_info *info; |
244 | 259 | ||
245 | int has_gem; | 260 | int has_gem; |
261 | int relative_constants_mode; | ||
246 | 262 | ||
247 | void __iomem *regs; | 263 | void __iomem *regs; |
248 | 264 | ||
@@ -253,20 +269,15 @@ typedef struct drm_i915_private { | |||
253 | } *gmbus; | 269 | } *gmbus; |
254 | 270 | ||
255 | struct pci_dev *bridge_dev; | 271 | struct pci_dev *bridge_dev; |
256 | struct intel_ring_buffer render_ring; | 272 | struct intel_ring_buffer ring[I915_NUM_RINGS]; |
257 | struct intel_ring_buffer bsd_ring; | ||
258 | struct intel_ring_buffer blt_ring; | ||
259 | uint32_t next_seqno; | 273 | uint32_t next_seqno; |
260 | 274 | ||
261 | drm_dma_handle_t *status_page_dmah; | 275 | drm_dma_handle_t *status_page_dmah; |
262 | void *seqno_page; | ||
263 | dma_addr_t dma_status_page; | 276 | dma_addr_t dma_status_page; |
264 | uint32_t counter; | 277 | uint32_t counter; |
265 | unsigned int seqno_gfx_addr; | ||
266 | drm_local_map_t hws_map; | 278 | drm_local_map_t hws_map; |
267 | struct drm_gem_object *seqno_obj; | 279 | struct drm_i915_gem_object *pwrctx; |
268 | struct drm_gem_object *pwrctx; | 280 | struct drm_i915_gem_object *renderctx; |
269 | struct drm_gem_object *renderctx; | ||
270 | 281 | ||
271 | struct resource mch_res; | 282 | struct resource mch_res; |
272 | 283 | ||
@@ -275,25 +286,17 @@ typedef struct drm_i915_private { | |||
275 | int front_offset; | 286 | int front_offset; |
276 | int current_page; | 287 | int current_page; |
277 | int page_flipping; | 288 | int page_flipping; |
278 | #define I915_DEBUG_READ (1<<0) | ||
279 | #define I915_DEBUG_WRITE (1<<1) | ||
280 | unsigned long debug_flags; | ||
281 | 289 | ||
282 | wait_queue_head_t irq_queue; | ||
283 | atomic_t irq_received; | 290 | atomic_t irq_received; |
284 | /** Protects user_irq_refcount and irq_mask_reg */ | ||
285 | spinlock_t user_irq_lock; | ||
286 | u32 trace_irq_seqno; | 291 | u32 trace_irq_seqno; |
292 | |||
293 | /* protects the irq masks */ | ||
294 | spinlock_t irq_lock; | ||
287 | /** Cached value of IMR to avoid reads in updating the bitfield */ | 295 | /** Cached value of IMR to avoid reads in updating the bitfield */ |
288 | u32 irq_mask_reg; | ||
289 | u32 pipestat[2]; | 296 | u32 pipestat[2]; |
290 | /** splitted irq regs for graphics and display engine on Ironlake, | 297 | u32 irq_mask; |
291 | irq_mask_reg is still used for display irq. */ | 298 | u32 gt_irq_mask; |
292 | u32 gt_irq_mask_reg; | 299 | u32 pch_irq_mask; |
293 | u32 gt_irq_enable_reg; | ||
294 | u32 de_irq_enable_reg; | ||
295 | u32 pch_irq_mask_reg; | ||
296 | u32 pch_irq_enable_reg; | ||
297 | 300 | ||
298 | u32 hotplug_supported_mask; | 301 | u32 hotplug_supported_mask; |
299 | struct work_struct hotplug_work; | 302 | struct work_struct hotplug_work; |
@@ -306,7 +309,7 @@ typedef struct drm_i915_private { | |||
306 | int num_pipe; | 309 | int num_pipe; |
307 | 310 | ||
308 | /* For hangcheck timer */ | 311 | /* For hangcheck timer */ |
309 | #define DRM_I915_HANGCHECK_PERIOD 250 /* in ms */ | 312 | #define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */ |
310 | struct timer_list hangcheck_timer; | 313 | struct timer_list hangcheck_timer; |
311 | int hangcheck_count; | 314 | int hangcheck_count; |
312 | uint32_t last_acthd; | 315 | uint32_t last_acthd; |
@@ -530,23 +533,21 @@ typedef struct drm_i915_private { | |||
530 | 533 | ||
531 | struct { | 534 | struct { |
532 | /** Bridge to intel-gtt-ko */ | 535 | /** Bridge to intel-gtt-ko */ |
533 | struct intel_gtt *gtt; | 536 | const struct intel_gtt *gtt; |
534 | /** Memory allocator for GTT stolen memory */ | 537 | /** Memory allocator for GTT stolen memory */ |
535 | struct drm_mm vram; | 538 | struct drm_mm stolen; |
536 | /** Memory allocator for GTT */ | 539 | /** Memory allocator for GTT */ |
537 | struct drm_mm gtt_space; | 540 | struct drm_mm gtt_space; |
541 | /** List of all objects in gtt_space. Used to restore gtt | ||
542 | * mappings on resume */ | ||
543 | struct list_head gtt_list; | ||
544 | /** End of mappable part of GTT */ | ||
545 | unsigned long gtt_mappable_end; | ||
538 | 546 | ||
539 | struct io_mapping *gtt_mapping; | 547 | struct io_mapping *gtt_mapping; |
540 | int gtt_mtrr; | 548 | int gtt_mtrr; |
541 | 549 | ||
542 | /** | 550 | struct shrinker inactive_shrinker; |
543 | * Membership on list of all loaded devices, used to evict | ||
544 | * inactive buffers under memory pressure. | ||
545 | * | ||
546 | * Modifications should only be done whilst holding the | ||
547 | * shrink_list_lock spinlock. | ||
548 | */ | ||
549 | struct list_head shrink_list; | ||
550 | 551 | ||
551 | /** | 552 | /** |
552 | * List of objects currently involved in rendering. | 553 | * List of objects currently involved in rendering. |
@@ -609,16 +610,6 @@ typedef struct drm_i915_private { | |||
609 | struct delayed_work retire_work; | 610 | struct delayed_work retire_work; |
610 | 611 | ||
611 | /** | 612 | /** |
612 | * Waiting sequence number, if any | ||
613 | */ | ||
614 | uint32_t waiting_gem_seqno; | ||
615 | |||
616 | /** | ||
617 | * Last seq seen at irq time | ||
618 | */ | ||
619 | uint32_t irq_gem_seqno; | ||
620 | |||
621 | /** | ||
622 | * Flag if the X Server, and thus DRM, is not currently in | 613 | * Flag if the X Server, and thus DRM, is not currently in |
623 | * control of the device. | 614 | * control of the device. |
624 | * | 615 | * |
@@ -645,16 +636,11 @@ typedef struct drm_i915_private { | |||
645 | /* storage for physical objects */ | 636 | /* storage for physical objects */ |
646 | struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; | 637 | struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; |
647 | 638 | ||
648 | uint32_t flush_rings; | ||
649 | |||
650 | /* accounting, useful for userland debugging */ | 639 | /* accounting, useful for userland debugging */ |
651 | size_t object_memory; | ||
652 | size_t pin_memory; | ||
653 | size_t gtt_memory; | ||
654 | size_t gtt_total; | 640 | size_t gtt_total; |
641 | size_t mappable_gtt_total; | ||
642 | size_t object_memory; | ||
655 | u32 object_count; | 643 | u32 object_count; |
656 | u32 pin_count; | ||
657 | u32 gtt_count; | ||
658 | } mm; | 644 | } mm; |
659 | struct sdvo_device_mapping sdvo_mappings[2]; | 645 | struct sdvo_device_mapping sdvo_mappings[2]; |
660 | /* indicate whether the LVDS_BORDER should be enabled or not */ | 646 | /* indicate whether the LVDS_BORDER should be enabled or not */ |
@@ -688,14 +674,14 @@ typedef struct drm_i915_private { | |||
688 | u8 fmax; | 674 | u8 fmax; |
689 | u8 fstart; | 675 | u8 fstart; |
690 | 676 | ||
691 | u64 last_count1; | 677 | u64 last_count1; |
692 | unsigned long last_time1; | 678 | unsigned long last_time1; |
693 | u64 last_count2; | 679 | u64 last_count2; |
694 | struct timespec last_time2; | 680 | struct timespec last_time2; |
695 | unsigned long gfx_power; | 681 | unsigned long gfx_power; |
696 | int c_m; | 682 | int c_m; |
697 | int r_t; | 683 | int r_t; |
698 | u8 corr; | 684 | u8 corr; |
699 | spinlock_t *mchdev_lock; | 685 | spinlock_t *mchdev_lock; |
700 | 686 | ||
701 | enum no_fbc_reason no_fbc_reason; | 687 | enum no_fbc_reason no_fbc_reason; |
@@ -709,20 +695,20 @@ typedef struct drm_i915_private { | |||
709 | struct intel_fbdev *fbdev; | 695 | struct intel_fbdev *fbdev; |
710 | } drm_i915_private_t; | 696 | } drm_i915_private_t; |
711 | 697 | ||
712 | /** driver private structure attached to each drm_gem_object */ | ||
713 | struct drm_i915_gem_object { | 698 | struct drm_i915_gem_object { |
714 | struct drm_gem_object base; | 699 | struct drm_gem_object base; |
715 | 700 | ||
716 | /** Current space allocated to this object in the GTT, if any. */ | 701 | /** Current space allocated to this object in the GTT, if any. */ |
717 | struct drm_mm_node *gtt_space; | 702 | struct drm_mm_node *gtt_space; |
703 | struct list_head gtt_list; | ||
718 | 704 | ||
719 | /** This object's place on the active/flushing/inactive lists */ | 705 | /** This object's place on the active/flushing/inactive lists */ |
720 | struct list_head ring_list; | 706 | struct list_head ring_list; |
721 | struct list_head mm_list; | 707 | struct list_head mm_list; |
722 | /** This object's place on GPU write list */ | 708 | /** This object's place on GPU write list */ |
723 | struct list_head gpu_write_list; | 709 | struct list_head gpu_write_list; |
724 | /** This object's place on eviction list */ | 710 | /** This object's place in the batchbuffer or on the eviction list */ |
725 | struct list_head evict_list; | 711 | struct list_head exec_list; |
726 | 712 | ||
727 | /** | 713 | /** |
728 | * This is set if the object is on the active or flushing lists | 714 | * This is set if the object is on the active or flushing lists |
@@ -738,6 +724,12 @@ struct drm_i915_gem_object { | |||
738 | unsigned int dirty : 1; | 724 | unsigned int dirty : 1; |
739 | 725 | ||
740 | /** | 726 | /** |
727 | * This is set if the object has been written to since the last | ||
728 | * GPU flush. | ||
729 | */ | ||
730 | unsigned int pending_gpu_write : 1; | ||
731 | |||
732 | /** | ||
741 | * Fence register bits (if any) for this object. Will be set | 733 | * Fence register bits (if any) for this object. Will be set |
742 | * as needed when mapped into the GTT. | 734 | * as needed when mapped into the GTT. |
743 | * Protected by dev->struct_mutex. | 735 | * Protected by dev->struct_mutex. |
@@ -747,29 +739,15 @@ struct drm_i915_gem_object { | |||
747 | signed int fence_reg : 5; | 739 | signed int fence_reg : 5; |
748 | 740 | ||
749 | /** | 741 | /** |
750 | * Used for checking the object doesn't appear more than once | ||
751 | * in an execbuffer object list. | ||
752 | */ | ||
753 | unsigned int in_execbuffer : 1; | ||
754 | |||
755 | /** | ||
756 | * Advice: are the backing pages purgeable? | 742 | * Advice: are the backing pages purgeable? |
757 | */ | 743 | */ |
758 | unsigned int madv : 2; | 744 | unsigned int madv : 2; |
759 | 745 | ||
760 | /** | 746 | /** |
761 | * Refcount for the pages array. With the current locking scheme, there | ||
762 | * are at most two concurrent users: Binding a bo to the gtt and | ||
763 | * pwrite/pread using physical addresses. So two bits for a maximum | ||
764 | * of two users are enough. | ||
765 | */ | ||
766 | unsigned int pages_refcount : 2; | ||
767 | #define DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT 0x3 | ||
768 | |||
769 | /** | ||
770 | * Current tiling mode for the object. | 747 | * Current tiling mode for the object. |
771 | */ | 748 | */ |
772 | unsigned int tiling_mode : 2; | 749 | unsigned int tiling_mode : 2; |
750 | unsigned int tiling_changed : 1; | ||
773 | 751 | ||
774 | /** How many users have pinned this object in GTT space. The following | 752 | /** How many users have pinned this object in GTT space. The following |
775 | * users can each hold at most one reference: pwrite/pread, pin_ioctl | 753 | * users can each hold at most one reference: pwrite/pread, pin_ioctl |
@@ -783,28 +761,54 @@ struct drm_i915_gem_object { | |||
783 | unsigned int pin_count : 4; | 761 | unsigned int pin_count : 4; |
784 | #define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf | 762 | #define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf |
785 | 763 | ||
786 | /** AGP memory structure for our GTT binding. */ | 764 | /** |
787 | DRM_AGP_MEM *agp_mem; | 765 | * Is the object at the current location in the gtt mappable and |
766 | * fenceable? Used to avoid costly recalculations. | ||
767 | */ | ||
768 | unsigned int map_and_fenceable : 1; | ||
769 | |||
770 | /** | ||
771 | * Whether the current gtt mapping needs to be mappable (and isn't just | ||
772 | * mappable by accident). Track pin and fault separate for a more | ||
773 | * accurate mappable working set. | ||
774 | */ | ||
775 | unsigned int fault_mappable : 1; | ||
776 | unsigned int pin_mappable : 1; | ||
777 | |||
778 | /* | ||
779 | * Is the GPU currently using a fence to access this buffer, | ||
780 | */ | ||
781 | unsigned int pending_fenced_gpu_access:1; | ||
782 | unsigned int fenced_gpu_access:1; | ||
788 | 783 | ||
789 | struct page **pages; | 784 | struct page **pages; |
790 | 785 | ||
791 | /** | 786 | /** |
792 | * Current offset of the object in GTT space. | 787 | * DMAR support |
793 | * | ||
794 | * This is the same as gtt_space->start | ||
795 | */ | 788 | */ |
796 | uint32_t gtt_offset; | 789 | struct scatterlist *sg_list; |
790 | int num_sg; | ||
797 | 791 | ||
798 | /* Which ring is refering to is this object */ | 792 | /** |
799 | struct intel_ring_buffer *ring; | 793 | * Used for performing relocations during execbuffer insertion. |
794 | */ | ||
795 | struct hlist_node exec_node; | ||
796 | unsigned long exec_handle; | ||
800 | 797 | ||
801 | /** | 798 | /** |
802 | * Fake offset for use by mmap(2) | 799 | * Current offset of the object in GTT space. |
800 | * | ||
801 | * This is the same as gtt_space->start | ||
803 | */ | 802 | */ |
804 | uint64_t mmap_offset; | 803 | uint32_t gtt_offset; |
805 | 804 | ||
806 | /** Breadcrumb of last rendering to the buffer. */ | 805 | /** Breadcrumb of last rendering to the buffer. */ |
807 | uint32_t last_rendering_seqno; | 806 | uint32_t last_rendering_seqno; |
807 | struct intel_ring_buffer *ring; | ||
808 | |||
809 | /** Breadcrumb of last fenced GPU access to the buffer. */ | ||
810 | uint32_t last_fenced_seqno; | ||
811 | struct intel_ring_buffer *last_fenced_ring; | ||
808 | 812 | ||
809 | /** Current tiling stride for the object, if it's tiled. */ | 813 | /** Current tiling stride for the object, if it's tiled. */ |
810 | uint32_t stride; | 814 | uint32_t stride; |
@@ -880,6 +884,68 @@ enum intel_chip_family { | |||
880 | CHIP_I965 = 0x08, | 884 | CHIP_I965 = 0x08, |
881 | }; | 885 | }; |
882 | 886 | ||
887 | #define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) | ||
888 | |||
889 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) | ||
890 | #define IS_845G(dev) ((dev)->pci_device == 0x2562) | ||
891 | #define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x) | ||
892 | #define IS_I865G(dev) ((dev)->pci_device == 0x2572) | ||
893 | #define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) | ||
894 | #define IS_I915GM(dev) ((dev)->pci_device == 0x2592) | ||
895 | #define IS_I945G(dev) ((dev)->pci_device == 0x2772) | ||
896 | #define IS_I945GM(dev) (INTEL_INFO(dev)->is_i945gm) | ||
897 | #define IS_BROADWATER(dev) (INTEL_INFO(dev)->is_broadwater) | ||
898 | #define IS_CRESTLINE(dev) (INTEL_INFO(dev)->is_crestline) | ||
899 | #define IS_GM45(dev) ((dev)->pci_device == 0x2A42) | ||
900 | #define IS_G4X(dev) (INTEL_INFO(dev)->is_g4x) | ||
901 | #define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001) | ||
902 | #define IS_PINEVIEW_M(dev) ((dev)->pci_device == 0xa011) | ||
903 | #define IS_PINEVIEW(dev) (INTEL_INFO(dev)->is_pineview) | ||
904 | #define IS_G33(dev) (INTEL_INFO(dev)->is_g33) | ||
905 | #define IS_IRONLAKE_D(dev) ((dev)->pci_device == 0x0042) | ||
906 | #define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) | ||
907 | #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) | ||
908 | |||
909 | #define IS_GEN2(dev) (INTEL_INFO(dev)->gen == 2) | ||
910 | #define IS_GEN3(dev) (INTEL_INFO(dev)->gen == 3) | ||
911 | #define IS_GEN4(dev) (INTEL_INFO(dev)->gen == 4) | ||
912 | #define IS_GEN5(dev) (INTEL_INFO(dev)->gen == 5) | ||
913 | #define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6) | ||
914 | |||
915 | #define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring) | ||
916 | #define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring) | ||
917 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) | ||
918 | |||
919 | #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) | ||
920 | #define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) | ||
921 | |||
922 | /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte | ||
923 | * rows, which changed the alignment requirements and fence programming. | ||
924 | */ | ||
925 | #define HAS_128_BYTE_Y_TILING(dev) (!IS_GEN2(dev) && !(IS_I915G(dev) || \ | ||
926 | IS_I915GM(dev))) | ||
927 | #define SUPPORTS_DIGITAL_OUTPUTS(dev) (!IS_GEN2(dev) && !IS_PINEVIEW(dev)) | ||
928 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_GEN5(dev)) | ||
929 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_GEN5(dev)) | ||
930 | #define SUPPORTS_EDP(dev) (IS_IRONLAKE_M(dev)) | ||
931 | #define SUPPORTS_TV(dev) (INTEL_INFO(dev)->supports_tv) | ||
932 | #define I915_HAS_HOTPLUG(dev) (INTEL_INFO(dev)->has_hotplug) | ||
933 | /* dsparb controlled by hw only */ | ||
934 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IRONLAKE(dev)) | ||
935 | |||
936 | #define HAS_FW_BLC(dev) (INTEL_INFO(dev)->gen > 2) | ||
937 | #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) | ||
938 | #define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) | ||
939 | |||
940 | #define HAS_PCH_SPLIT(dev) (IS_GEN5(dev) || IS_GEN6(dev)) | ||
941 | #define HAS_PIPE_CONTROL(dev) (IS_GEN5(dev) || IS_GEN6(dev)) | ||
942 | |||
943 | #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) | ||
944 | #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) | ||
945 | #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) | ||
946 | |||
947 | #include "i915_trace.h" | ||
948 | |||
883 | extern struct drm_ioctl_desc i915_ioctls[]; | 949 | extern struct drm_ioctl_desc i915_ioctls[]; |
884 | extern int i915_max_ioctl; | 950 | extern int i915_max_ioctl; |
885 | extern unsigned int i915_fbpercrtc; | 951 | extern unsigned int i915_fbpercrtc; |
@@ -907,8 +973,8 @@ extern int i915_driver_device_is_agp(struct drm_device * dev); | |||
907 | extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, | 973 | extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, |
908 | unsigned long arg); | 974 | unsigned long arg); |
909 | extern int i915_emit_box(struct drm_device *dev, | 975 | extern int i915_emit_box(struct drm_device *dev, |
910 | struct drm_clip_rect *boxes, | 976 | struct drm_clip_rect *box, |
911 | int i, int DR1, int DR4); | 977 | int DR1, int DR4); |
912 | extern int i915_reset(struct drm_device *dev, u8 flags); | 978 | extern int i915_reset(struct drm_device *dev, u8 flags); |
913 | extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); | 979 | extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); |
914 | extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv); | 980 | extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv); |
@@ -918,6 +984,7 @@ extern void i915_update_gfx_val(struct drm_i915_private *dev_priv); | |||
918 | 984 | ||
919 | /* i915_irq.c */ | 985 | /* i915_irq.c */ |
920 | void i915_hangcheck_elapsed(unsigned long data); | 986 | void i915_hangcheck_elapsed(unsigned long data); |
987 | void i915_handle_error(struct drm_device *dev, bool wedged); | ||
921 | extern int i915_irq_emit(struct drm_device *dev, void *data, | 988 | extern int i915_irq_emit(struct drm_device *dev, void *data, |
922 | struct drm_file *file_priv); | 989 | struct drm_file *file_priv); |
923 | extern int i915_irq_wait(struct drm_device *dev, void *data, | 990 | extern int i915_irq_wait(struct drm_device *dev, void *data, |
@@ -953,6 +1020,13 @@ void | |||
953 | i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); | 1020 | i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); |
954 | 1021 | ||
955 | void intel_enable_asle (struct drm_device *dev); | 1022 | void intel_enable_asle (struct drm_device *dev); |
1023 | int i915_get_vblank_timestamp(struct drm_device *dev, int crtc, | ||
1024 | int *max_error, | ||
1025 | struct timeval *vblank_time, | ||
1026 | unsigned flags); | ||
1027 | |||
1028 | int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, | ||
1029 | int *vpos, int *hpos); | ||
956 | 1030 | ||
957 | #ifdef CONFIG_DEBUG_FS | 1031 | #ifdef CONFIG_DEBUG_FS |
958 | extern void i915_destroy_error_state(struct drm_device *dev); | 1032 | extern void i915_destroy_error_state(struct drm_device *dev); |
@@ -1017,15 +1091,28 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | |||
1017 | struct drm_file *file_priv); | 1091 | struct drm_file *file_priv); |
1018 | void i915_gem_load(struct drm_device *dev); | 1092 | void i915_gem_load(struct drm_device *dev); |
1019 | int i915_gem_init_object(struct drm_gem_object *obj); | 1093 | int i915_gem_init_object(struct drm_gem_object *obj); |
1020 | struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, | 1094 | void i915_gem_flush_ring(struct drm_device *dev, |
1021 | size_t size); | 1095 | struct intel_ring_buffer *ring, |
1096 | uint32_t invalidate_domains, | ||
1097 | uint32_t flush_domains); | ||
1098 | struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, | ||
1099 | size_t size); | ||
1022 | void i915_gem_free_object(struct drm_gem_object *obj); | 1100 | void i915_gem_free_object(struct drm_gem_object *obj); |
1023 | int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); | 1101 | int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, |
1024 | void i915_gem_object_unpin(struct drm_gem_object *obj); | 1102 | uint32_t alignment, |
1025 | int i915_gem_object_unbind(struct drm_gem_object *obj); | 1103 | bool map_and_fenceable); |
1026 | void i915_gem_release_mmap(struct drm_gem_object *obj); | 1104 | void i915_gem_object_unpin(struct drm_i915_gem_object *obj); |
1105 | int __must_check i915_gem_object_unbind(struct drm_i915_gem_object *obj); | ||
1106 | void i915_gem_release_mmap(struct drm_i915_gem_object *obj); | ||
1027 | void i915_gem_lastclose(struct drm_device *dev); | 1107 | void i915_gem_lastclose(struct drm_device *dev); |
1028 | 1108 | ||
1109 | int __must_check i915_mutex_lock_interruptible(struct drm_device *dev); | ||
1110 | int __must_check i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, | ||
1111 | bool interruptible); | ||
1112 | void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, | ||
1113 | struct intel_ring_buffer *ring, | ||
1114 | u32 seqno); | ||
1115 | |||
1029 | /** | 1116 | /** |
1030 | * Returns true if seq1 is later than seq2. | 1117 | * Returns true if seq1 is later than seq2. |
1031 | */ | 1118 | */ |
@@ -1035,73 +1122,88 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2) | |||
1035 | return (int32_t)(seq1 - seq2) >= 0; | 1122 | return (int32_t)(seq1 - seq2) >= 0; |
1036 | } | 1123 | } |
1037 | 1124 | ||
1038 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj, | 1125 | static inline u32 |
1039 | bool interruptible); | 1126 | i915_gem_next_request_seqno(struct drm_device *dev, |
1040 | int i915_gem_object_put_fence_reg(struct drm_gem_object *obj, | 1127 | struct intel_ring_buffer *ring) |
1041 | bool interruptible); | 1128 | { |
1129 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1130 | return ring->outstanding_lazy_request = dev_priv->next_seqno; | ||
1131 | } | ||
1132 | |||
1133 | int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj, | ||
1134 | struct intel_ring_buffer *pipelined, | ||
1135 | bool interruptible); | ||
1136 | int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj); | ||
1137 | |||
1042 | void i915_gem_retire_requests(struct drm_device *dev); | 1138 | void i915_gem_retire_requests(struct drm_device *dev); |
1043 | void i915_gem_reset(struct drm_device *dev); | 1139 | void i915_gem_reset(struct drm_device *dev); |
1044 | void i915_gem_clflush_object(struct drm_gem_object *obj); | 1140 | void i915_gem_clflush_object(struct drm_i915_gem_object *obj); |
1045 | int i915_gem_object_set_domain(struct drm_gem_object *obj, | 1141 | int __must_check i915_gem_object_set_domain(struct drm_i915_gem_object *obj, |
1046 | uint32_t read_domains, | 1142 | uint32_t read_domains, |
1047 | uint32_t write_domain); | 1143 | uint32_t write_domain); |
1048 | int i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj, | 1144 | int __must_check i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj, |
1049 | bool interruptible); | 1145 | bool interruptible); |
1050 | int i915_gem_init_ringbuffer(struct drm_device *dev); | 1146 | int __must_check i915_gem_init_ringbuffer(struct drm_device *dev); |
1051 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); | 1147 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); |
1052 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, | 1148 | void i915_gem_do_init(struct drm_device *dev, |
1053 | unsigned long end); | 1149 | unsigned long start, |
1054 | int i915_gpu_idle(struct drm_device *dev); | 1150 | unsigned long mappable_end, |
1055 | int i915_gem_idle(struct drm_device *dev); | 1151 | unsigned long end); |
1056 | uint32_t i915_add_request(struct drm_device *dev, | 1152 | int __must_check i915_gpu_idle(struct drm_device *dev); |
1057 | struct drm_file *file_priv, | 1153 | int __must_check i915_gem_idle(struct drm_device *dev); |
1058 | struct drm_i915_gem_request *request, | 1154 | int __must_check i915_add_request(struct drm_device *dev, |
1059 | struct intel_ring_buffer *ring); | 1155 | struct drm_file *file_priv, |
1060 | int i915_do_wait_request(struct drm_device *dev, | 1156 | struct drm_i915_gem_request *request, |
1061 | uint32_t seqno, | 1157 | struct intel_ring_buffer *ring); |
1062 | bool interruptible, | 1158 | int __must_check i915_do_wait_request(struct drm_device *dev, |
1063 | struct intel_ring_buffer *ring); | 1159 | uint32_t seqno, |
1160 | bool interruptible, | ||
1161 | struct intel_ring_buffer *ring); | ||
1064 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); | 1162 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); |
1065 | int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, | 1163 | int __must_check |
1066 | int write); | 1164 | i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, |
1067 | int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj, | 1165 | bool write); |
1068 | bool pipelined); | 1166 | int __must_check |
1167 | i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj, | ||
1168 | struct intel_ring_buffer *pipelined); | ||
1069 | int i915_gem_attach_phys_object(struct drm_device *dev, | 1169 | int i915_gem_attach_phys_object(struct drm_device *dev, |
1070 | struct drm_gem_object *obj, | 1170 | struct drm_i915_gem_object *obj, |
1071 | int id, | 1171 | int id, |
1072 | int align); | 1172 | int align); |
1073 | void i915_gem_detach_phys_object(struct drm_device *dev, | 1173 | void i915_gem_detach_phys_object(struct drm_device *dev, |
1074 | struct drm_gem_object *obj); | 1174 | struct drm_i915_gem_object *obj); |
1075 | void i915_gem_free_all_phys_object(struct drm_device *dev); | 1175 | void i915_gem_free_all_phys_object(struct drm_device *dev); |
1076 | void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); | 1176 | void i915_gem_release(struct drm_device *dev, struct drm_file *file); |
1077 | 1177 | ||
1078 | void i915_gem_shrinker_init(void); | 1178 | /* i915_gem_gtt.c */ |
1079 | void i915_gem_shrinker_exit(void); | 1179 | void i915_gem_restore_gtt_mappings(struct drm_device *dev); |
1180 | int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj); | ||
1181 | void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj); | ||
1080 | 1182 | ||
1081 | /* i915_gem_evict.c */ | 1183 | /* i915_gem_evict.c */ |
1082 | int i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment); | 1184 | int __must_check i915_gem_evict_something(struct drm_device *dev, int min_size, |
1083 | int i915_gem_evict_everything(struct drm_device *dev); | 1185 | unsigned alignment, bool mappable); |
1084 | int i915_gem_evict_inactive(struct drm_device *dev); | 1186 | int __must_check i915_gem_evict_everything(struct drm_device *dev, |
1187 | bool purgeable_only); | ||
1188 | int __must_check i915_gem_evict_inactive(struct drm_device *dev, | ||
1189 | bool purgeable_only); | ||
1085 | 1190 | ||
1086 | /* i915_gem_tiling.c */ | 1191 | /* i915_gem_tiling.c */ |
1087 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); | 1192 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); |
1088 | void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); | 1193 | void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj); |
1089 | void i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj); | 1194 | void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj); |
1090 | bool i915_tiling_ok(struct drm_device *dev, int stride, int size, | ||
1091 | int tiling_mode); | ||
1092 | bool i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, | ||
1093 | int tiling_mode); | ||
1094 | 1195 | ||
1095 | /* i915_gem_debug.c */ | 1196 | /* i915_gem_debug.c */ |
1096 | void i915_gem_dump_object(struct drm_gem_object *obj, int len, | 1197 | void i915_gem_dump_object(struct drm_i915_gem_object *obj, int len, |
1097 | const char *where, uint32_t mark); | 1198 | const char *where, uint32_t mark); |
1098 | #if WATCH_LISTS | 1199 | #if WATCH_LISTS |
1099 | int i915_verify_lists(struct drm_device *dev); | 1200 | int i915_verify_lists(struct drm_device *dev); |
1100 | #else | 1201 | #else |
1101 | #define i915_verify_lists(dev) 0 | 1202 | #define i915_verify_lists(dev) 0 |
1102 | #endif | 1203 | #endif |
1103 | void i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle); | 1204 | void i915_gem_object_check_coherency(struct drm_i915_gem_object *obj, |
1104 | void i915_gem_dump_object(struct drm_gem_object *obj, int len, | 1205 | int handle); |
1206 | void i915_gem_dump_object(struct drm_i915_gem_object *obj, int len, | ||
1105 | const char *where, uint32_t mark); | 1207 | const char *where, uint32_t mark); |
1106 | 1208 | ||
1107 | /* i915_debugfs.c */ | 1209 | /* i915_debugfs.c */ |
@@ -1163,6 +1265,7 @@ extern void intel_disable_fbc(struct drm_device *dev); | |||
1163 | extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); | 1265 | extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); |
1164 | extern bool intel_fbc_enabled(struct drm_device *dev); | 1266 | extern bool intel_fbc_enabled(struct drm_device *dev); |
1165 | extern bool ironlake_set_drps(struct drm_device *dev, u8 val); | 1267 | extern bool ironlake_set_drps(struct drm_device *dev, u8 val); |
1268 | extern void gen6_set_rps(struct drm_device *dev, u8 val); | ||
1166 | extern void intel_detect_pch (struct drm_device *dev); | 1269 | extern void intel_detect_pch (struct drm_device *dev); |
1167 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | 1270 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); |
1168 | 1271 | ||
@@ -1170,79 +1273,120 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | |||
1170 | #ifdef CONFIG_DEBUG_FS | 1273 | #ifdef CONFIG_DEBUG_FS |
1171 | extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); | 1274 | extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); |
1172 | extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error); | 1275 | extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error); |
1276 | |||
1277 | extern struct intel_display_error_state *intel_display_capture_error_state(struct drm_device *dev); | ||
1278 | extern void intel_display_print_error_state(struct seq_file *m, | ||
1279 | struct drm_device *dev, | ||
1280 | struct intel_display_error_state *error); | ||
1173 | #endif | 1281 | #endif |
1174 | 1282 | ||
1283 | #define LP_RING(d) (&((struct drm_i915_private *)(d))->ring[RCS]) | ||
1284 | |||
1285 | #define BEGIN_LP_RING(n) \ | ||
1286 | intel_ring_begin(LP_RING(dev_priv), (n)) | ||
1287 | |||
1288 | #define OUT_RING(x) \ | ||
1289 | intel_ring_emit(LP_RING(dev_priv), x) | ||
1290 | |||
1291 | #define ADVANCE_LP_RING() \ | ||
1292 | intel_ring_advance(LP_RING(dev_priv)) | ||
1293 | |||
1175 | /** | 1294 | /** |
1176 | * Lock test for when it's just for synchronization of ring access. | 1295 | * Lock test for when it's just for synchronization of ring access. |
1177 | * | 1296 | * |
1178 | * In that case, we don't need to do it when GEM is initialized as nobody else | 1297 | * In that case, we don't need to do it when GEM is initialized as nobody else |
1179 | * has access to the ring. | 1298 | * has access to the ring. |
1180 | */ | 1299 | */ |
1181 | #define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do { \ | 1300 | #define RING_LOCK_TEST_WITH_RETURN(dev, file) do { \ |
1182 | if (((drm_i915_private_t *)dev->dev_private)->render_ring.gem_object \ | 1301 | if (LP_RING(dev->dev_private)->obj == NULL) \ |
1183 | == NULL) \ | 1302 | LOCK_TEST_WITH_RETURN(dev, file); \ |
1184 | LOCK_TEST_WITH_RETURN(dev, file_priv); \ | ||
1185 | } while (0) | 1303 | } while (0) |
1186 | 1304 | ||
1187 | static inline u32 i915_read(struct drm_i915_private *dev_priv, u32 reg) | 1305 | |
1306 | #define __i915_read(x, y) \ | ||
1307 | static inline u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ | ||
1308 | u##x val = read##y(dev_priv->regs + reg); \ | ||
1309 | trace_i915_reg_rw('R', reg, val, sizeof(val)); \ | ||
1310 | return val; \ | ||
1311 | } | ||
1312 | __i915_read(8, b) | ||
1313 | __i915_read(16, w) | ||
1314 | __i915_read(32, l) | ||
1315 | __i915_read(64, q) | ||
1316 | #undef __i915_read | ||
1317 | |||
1318 | #define __i915_write(x, y) \ | ||
1319 | static inline void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ | ||
1320 | trace_i915_reg_rw('W', reg, val, sizeof(val)); \ | ||
1321 | write##y(val, dev_priv->regs + reg); \ | ||
1322 | } | ||
1323 | __i915_write(8, b) | ||
1324 | __i915_write(16, w) | ||
1325 | __i915_write(32, l) | ||
1326 | __i915_write(64, q) | ||
1327 | #undef __i915_write | ||
1328 | |||
1329 | #define I915_READ8(reg) i915_read8(dev_priv, (reg)) | ||
1330 | #define I915_WRITE8(reg, val) i915_write8(dev_priv, (reg), (val)) | ||
1331 | |||
1332 | #define I915_READ16(reg) i915_read16(dev_priv, (reg)) | ||
1333 | #define I915_WRITE16(reg, val) i915_write16(dev_priv, (reg), (val)) | ||
1334 | #define I915_READ16_NOTRACE(reg) readw(dev_priv->regs + (reg)) | ||
1335 | #define I915_WRITE16_NOTRACE(reg, val) writew(val, dev_priv->regs + (reg)) | ||
1336 | |||
1337 | #define I915_READ(reg) i915_read32(dev_priv, (reg)) | ||
1338 | #define I915_WRITE(reg, val) i915_write32(dev_priv, (reg), (val)) | ||
1339 | #define I915_READ_NOTRACE(reg) readl(dev_priv->regs + (reg)) | ||
1340 | #define I915_WRITE_NOTRACE(reg, val) writel(val, dev_priv->regs + (reg)) | ||
1341 | |||
1342 | #define I915_WRITE64(reg, val) i915_write64(dev_priv, (reg), (val)) | ||
1343 | #define I915_READ64(reg) i915_read64(dev_priv, (reg)) | ||
1344 | |||
1345 | #define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) | ||
1346 | #define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) | ||
1347 | |||
1348 | |||
1349 | /* On SNB platform, before reading ring registers forcewake bit | ||
1350 | * must be set to prevent GT core from power down and stale values being | ||
1351 | * returned. | ||
1352 | */ | ||
1353 | void __gen6_force_wake_get(struct drm_i915_private *dev_priv); | ||
1354 | void __gen6_force_wake_put (struct drm_i915_private *dev_priv); | ||
1355 | static inline u32 i915_safe_read(struct drm_i915_private *dev_priv, u32 reg) | ||
1188 | { | 1356 | { |
1189 | u32 val; | 1357 | u32 val; |
1190 | 1358 | ||
1191 | val = readl(dev_priv->regs + reg); | 1359 | if (dev_priv->info->gen >= 6) { |
1192 | if (dev_priv->debug_flags & I915_DEBUG_READ) | 1360 | __gen6_force_wake_get(dev_priv); |
1193 | printk(KERN_ERR "read 0x%08x from 0x%08x\n", val, reg); | 1361 | val = I915_READ(reg); |
1362 | __gen6_force_wake_put(dev_priv); | ||
1363 | } else | ||
1364 | val = I915_READ(reg); | ||
1365 | |||
1194 | return val; | 1366 | return val; |
1195 | } | 1367 | } |
1196 | 1368 | ||
1197 | static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, | 1369 | static inline void |
1198 | u32 val) | 1370 | i915_write(struct drm_i915_private *dev_priv, u32 reg, u64 val, int len) |
1199 | { | 1371 | { |
1200 | writel(val, dev_priv->regs + reg); | 1372 | /* Trace down the write operation before the real write */ |
1201 | if (dev_priv->debug_flags & I915_DEBUG_WRITE) | 1373 | trace_i915_reg_rw('W', reg, val, len); |
1202 | printk(KERN_ERR "wrote 0x%08x to 0x%08x\n", val, reg); | 1374 | switch (len) { |
1375 | case 8: | ||
1376 | writeq(val, dev_priv->regs + reg); | ||
1377 | break; | ||
1378 | case 4: | ||
1379 | writel(val, dev_priv->regs + reg); | ||
1380 | break; | ||
1381 | case 2: | ||
1382 | writew(val, dev_priv->regs + reg); | ||
1383 | break; | ||
1384 | case 1: | ||
1385 | writeb(val, dev_priv->regs + reg); | ||
1386 | break; | ||
1387 | } | ||
1203 | } | 1388 | } |
1204 | 1389 | ||
1205 | #define I915_READ(reg) i915_read(dev_priv, (reg)) | ||
1206 | #define I915_WRITE(reg, val) i915_write(dev_priv, (reg), (val)) | ||
1207 | #define I915_READ16(reg) readw(dev_priv->regs + (reg)) | ||
1208 | #define I915_WRITE16(reg, val) writel(val, dev_priv->regs + (reg)) | ||
1209 | #define I915_READ8(reg) readb(dev_priv->regs + (reg)) | ||
1210 | #define I915_WRITE8(reg, val) writeb(val, dev_priv->regs + (reg)) | ||
1211 | #define I915_WRITE64(reg, val) writeq(val, dev_priv->regs + (reg)) | ||
1212 | #define I915_READ64(reg) readq(dev_priv->regs + (reg)) | ||
1213 | #define POSTING_READ(reg) (void)I915_READ(reg) | ||
1214 | #define POSTING_READ16(reg) (void)I915_READ16(reg) | ||
1215 | |||
1216 | #define I915_DEBUG_ENABLE_IO() (dev_priv->debug_flags |= I915_DEBUG_READ | \ | ||
1217 | I915_DEBUG_WRITE) | ||
1218 | #define I915_DEBUG_DISABLE_IO() (dev_priv->debug_flags &= ~(I915_DEBUG_READ | \ | ||
1219 | I915_DEBUG_WRITE)) | ||
1220 | |||
1221 | #define I915_VERBOSE 0 | ||
1222 | |||
1223 | #define BEGIN_LP_RING(n) do { \ | ||
1224 | drm_i915_private_t *dev_priv__ = dev->dev_private; \ | ||
1225 | if (I915_VERBOSE) \ | ||
1226 | DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ | ||
1227 | intel_ring_begin(dev, &dev_priv__->render_ring, (n)); \ | ||
1228 | } while (0) | ||
1229 | |||
1230 | |||
1231 | #define OUT_RING(x) do { \ | ||
1232 | drm_i915_private_t *dev_priv__ = dev->dev_private; \ | ||
1233 | if (I915_VERBOSE) \ | ||
1234 | DRM_DEBUG(" OUT_RING %x\n", (int)(x)); \ | ||
1235 | intel_ring_emit(dev, &dev_priv__->render_ring, x); \ | ||
1236 | } while (0) | ||
1237 | |||
1238 | #define ADVANCE_LP_RING() do { \ | ||
1239 | drm_i915_private_t *dev_priv__ = dev->dev_private; \ | ||
1240 | if (I915_VERBOSE) \ | ||
1241 | DRM_DEBUG("ADVANCE_LP_RING %x\n", \ | ||
1242 | dev_priv__->render_ring.tail); \ | ||
1243 | intel_ring_advance(dev, &dev_priv__->render_ring); \ | ||
1244 | } while(0) | ||
1245 | |||
1246 | /** | 1390 | /** |
1247 | * Reads a dword out of the status page, which is written to from the command | 1391 | * Reads a dword out of the status page, which is written to from the command |
1248 | * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or | 1392 | * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or |
@@ -1259,72 +1403,9 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, | |||
1259 | * The area from dword 0x20 to 0x3ff is available for driver usage. | 1403 | * The area from dword 0x20 to 0x3ff is available for driver usage. |
1260 | */ | 1404 | */ |
1261 | #define READ_HWSP(dev_priv, reg) (((volatile u32 *)\ | 1405 | #define READ_HWSP(dev_priv, reg) (((volatile u32 *)\ |
1262 | (dev_priv->render_ring.status_page.page_addr))[reg]) | 1406 | (LP_RING(dev_priv)->status_page.page_addr))[reg]) |
1263 | #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) | 1407 | #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) |
1264 | #define I915_GEM_HWS_INDEX 0x20 | 1408 | #define I915_GEM_HWS_INDEX 0x20 |
1265 | #define I915_BREADCRUMB_INDEX 0x21 | 1409 | #define I915_BREADCRUMB_INDEX 0x21 |
1266 | 1410 | ||
1267 | #define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) | ||
1268 | |||
1269 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) | ||
1270 | #define IS_845G(dev) ((dev)->pci_device == 0x2562) | ||
1271 | #define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x) | ||
1272 | #define IS_I865G(dev) ((dev)->pci_device == 0x2572) | ||
1273 | #define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) | ||
1274 | #define IS_I915GM(dev) ((dev)->pci_device == 0x2592) | ||
1275 | #define IS_I945G(dev) ((dev)->pci_device == 0x2772) | ||
1276 | #define IS_I945GM(dev) (INTEL_INFO(dev)->is_i945gm) | ||
1277 | #define IS_BROADWATER(dev) (INTEL_INFO(dev)->is_broadwater) | ||
1278 | #define IS_CRESTLINE(dev) (INTEL_INFO(dev)->is_crestline) | ||
1279 | #define IS_GM45(dev) ((dev)->pci_device == 0x2A42) | ||
1280 | #define IS_G4X(dev) (INTEL_INFO(dev)->is_g4x) | ||
1281 | #define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001) | ||
1282 | #define IS_PINEVIEW_M(dev) ((dev)->pci_device == 0xa011) | ||
1283 | #define IS_PINEVIEW(dev) (INTEL_INFO(dev)->is_pineview) | ||
1284 | #define IS_G33(dev) (INTEL_INFO(dev)->is_g33) | ||
1285 | #define IS_IRONLAKE_D(dev) ((dev)->pci_device == 0x0042) | ||
1286 | #define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) | ||
1287 | #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) | ||
1288 | |||
1289 | #define IS_GEN2(dev) (INTEL_INFO(dev)->gen == 2) | ||
1290 | #define IS_GEN3(dev) (INTEL_INFO(dev)->gen == 3) | ||
1291 | #define IS_GEN4(dev) (INTEL_INFO(dev)->gen == 4) | ||
1292 | #define IS_GEN5(dev) (INTEL_INFO(dev)->gen == 5) | ||
1293 | #define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6) | ||
1294 | |||
1295 | #define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring) | ||
1296 | #define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring) | ||
1297 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) | ||
1298 | |||
1299 | #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) | ||
1300 | #define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) | ||
1301 | |||
1302 | /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte | ||
1303 | * rows, which changed the alignment requirements and fence programming. | ||
1304 | */ | ||
1305 | #define HAS_128_BYTE_Y_TILING(dev) (!IS_GEN2(dev) && !(IS_I915G(dev) || \ | ||
1306 | IS_I915GM(dev))) | ||
1307 | #define SUPPORTS_DIGITAL_OUTPUTS(dev) (!IS_GEN2(dev) && !IS_PINEVIEW(dev)) | ||
1308 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_GEN5(dev)) | ||
1309 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_GEN5(dev)) | ||
1310 | #define SUPPORTS_EDP(dev) (IS_IRONLAKE_M(dev)) | ||
1311 | #define SUPPORTS_TV(dev) (INTEL_INFO(dev)->supports_tv) | ||
1312 | #define I915_HAS_HOTPLUG(dev) (INTEL_INFO(dev)->has_hotplug) | ||
1313 | /* dsparb controlled by hw only */ | ||
1314 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IRONLAKE(dev)) | ||
1315 | |||
1316 | #define HAS_FW_BLC(dev) (INTEL_INFO(dev)->gen > 2) | ||
1317 | #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) | ||
1318 | #define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) | ||
1319 | #define I915_HAS_RC6(dev) (INTEL_INFO(dev)->has_rc6) | ||
1320 | |||
1321 | #define HAS_PCH_SPLIT(dev) (IS_GEN5(dev) || IS_GEN6(dev)) | ||
1322 | #define HAS_PIPE_CONTROL(dev) (IS_GEN5(dev) || IS_GEN6(dev)) | ||
1323 | |||
1324 | #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) | ||
1325 | #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) | ||
1326 | #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) | ||
1327 | |||
1328 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) | ||
1329 | |||
1330 | #endif | 1411 | #endif |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 17b1cba3b5f..c79c0b62ef6 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -34,39 +34,31 @@ | |||
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/swap.h> | 35 | #include <linux/swap.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/intel-gtt.h> | ||
38 | 37 | ||
39 | static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj); | 38 | static void i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj); |
40 | 39 | static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); | |
41 | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj, | 40 | static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj); |
42 | bool pipelined); | 41 | static int i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, |
43 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); | 42 | bool write); |
44 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); | 43 | static int i915_gem_object_set_cpu_read_domain_range(struct drm_i915_gem_object *obj, |
45 | static int i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, | ||
46 | int write); | ||
47 | static int i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, | ||
48 | uint64_t offset, | 44 | uint64_t offset, |
49 | uint64_t size); | 45 | uint64_t size); |
50 | static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj); | 46 | static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_i915_gem_object *obj); |
51 | static int i915_gem_object_wait_rendering(struct drm_gem_object *obj, | 47 | static int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, |
52 | bool interruptible); | 48 | unsigned alignment, |
53 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 49 | bool map_and_fenceable); |
54 | unsigned alignment); | 50 | static void i915_gem_clear_fence_reg(struct drm_device *dev, |
55 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); | 51 | struct drm_i915_fence_reg *reg); |
56 | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | 52 | static int i915_gem_phys_pwrite(struct drm_device *dev, |
53 | struct drm_i915_gem_object *obj, | ||
57 | struct drm_i915_gem_pwrite *args, | 54 | struct drm_i915_gem_pwrite *args, |
58 | struct drm_file *file_priv); | 55 | struct drm_file *file); |
59 | static void i915_gem_free_object_tail(struct drm_gem_object *obj); | 56 | static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj); |
60 | 57 | ||
61 | static int | 58 | static int i915_gem_inactive_shrink(struct shrinker *shrinker, |
62 | i915_gem_object_get_pages(struct drm_gem_object *obj, | 59 | int nr_to_scan, |
63 | gfp_t gfpmask); | 60 | gfp_t gfp_mask); |
64 | 61 | ||
65 | static void | ||
66 | i915_gem_object_put_pages(struct drm_gem_object *obj); | ||
67 | |||
68 | static LIST_HEAD(shrink_list); | ||
69 | static DEFINE_SPINLOCK(shrink_list_lock); | ||
70 | 62 | ||
71 | /* some bookkeeping */ | 63 | /* some bookkeeping */ |
72 | static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, | 64 | static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, |
@@ -83,34 +75,6 @@ static void i915_gem_info_remove_obj(struct drm_i915_private *dev_priv, | |||
83 | dev_priv->mm.object_memory -= size; | 75 | dev_priv->mm.object_memory -= size; |
84 | } | 76 | } |
85 | 77 | ||
86 | static void i915_gem_info_add_gtt(struct drm_i915_private *dev_priv, | ||
87 | size_t size) | ||
88 | { | ||
89 | dev_priv->mm.gtt_count++; | ||
90 | dev_priv->mm.gtt_memory += size; | ||
91 | } | ||
92 | |||
93 | static void i915_gem_info_remove_gtt(struct drm_i915_private *dev_priv, | ||
94 | size_t size) | ||
95 | { | ||
96 | dev_priv->mm.gtt_count--; | ||
97 | dev_priv->mm.gtt_memory -= size; | ||
98 | } | ||
99 | |||
100 | static void i915_gem_info_add_pin(struct drm_i915_private *dev_priv, | ||
101 | size_t size) | ||
102 | { | ||
103 | dev_priv->mm.pin_count++; | ||
104 | dev_priv->mm.pin_memory += size; | ||
105 | } | ||
106 | |||
107 | static void i915_gem_info_remove_pin(struct drm_i915_private *dev_priv, | ||
108 | size_t size) | ||
109 | { | ||
110 | dev_priv->mm.pin_count--; | ||
111 | dev_priv->mm.pin_memory -= size; | ||
112 | } | ||
113 | |||
114 | int | 78 | int |
115 | i915_gem_check_is_wedged(struct drm_device *dev) | 79 | i915_gem_check_is_wedged(struct drm_device *dev) |
116 | { | 80 | { |
@@ -141,7 +105,7 @@ i915_gem_check_is_wedged(struct drm_device *dev) | |||
141 | return -EIO; | 105 | return -EIO; |
142 | } | 106 | } |
143 | 107 | ||
144 | static int i915_mutex_lock_interruptible(struct drm_device *dev) | 108 | int i915_mutex_lock_interruptible(struct drm_device *dev) |
145 | { | 109 | { |
146 | struct drm_i915_private *dev_priv = dev->dev_private; | 110 | struct drm_i915_private *dev_priv = dev->dev_private; |
147 | int ret; | 111 | int ret; |
@@ -164,75 +128,76 @@ static int i915_mutex_lock_interruptible(struct drm_device *dev) | |||
164 | } | 128 | } |
165 | 129 | ||
166 | static inline bool | 130 | static inline bool |
167 | i915_gem_object_is_inactive(struct drm_i915_gem_object *obj_priv) | 131 | i915_gem_object_is_inactive(struct drm_i915_gem_object *obj) |
168 | { | 132 | { |
169 | return obj_priv->gtt_space && | 133 | return obj->gtt_space && !obj->active && obj->pin_count == 0; |
170 | !obj_priv->active && | ||
171 | obj_priv->pin_count == 0; | ||
172 | } | 134 | } |
173 | 135 | ||
174 | int i915_gem_do_init(struct drm_device *dev, | 136 | void i915_gem_do_init(struct drm_device *dev, |
175 | unsigned long start, | 137 | unsigned long start, |
176 | unsigned long end) | 138 | unsigned long mappable_end, |
139 | unsigned long end) | ||
177 | { | 140 | { |
178 | drm_i915_private_t *dev_priv = dev->dev_private; | 141 | drm_i915_private_t *dev_priv = dev->dev_private; |
179 | 142 | ||
180 | if (start >= end || | ||
181 | (start & (PAGE_SIZE - 1)) != 0 || | ||
182 | (end & (PAGE_SIZE - 1)) != 0) { | ||
183 | return -EINVAL; | ||
184 | } | ||
185 | |||
186 | drm_mm_init(&dev_priv->mm.gtt_space, start, | 143 | drm_mm_init(&dev_priv->mm.gtt_space, start, |
187 | end - start); | 144 | end - start); |
188 | 145 | ||
189 | dev_priv->mm.gtt_total = end - start; | 146 | dev_priv->mm.gtt_total = end - start; |
190 | 147 | dev_priv->mm.mappable_gtt_total = min(end, mappable_end) - start; | |
191 | return 0; | 148 | dev_priv->mm.gtt_mappable_end = mappable_end; |
192 | } | 149 | } |
193 | 150 | ||
194 | int | 151 | int |
195 | i915_gem_init_ioctl(struct drm_device *dev, void *data, | 152 | i915_gem_init_ioctl(struct drm_device *dev, void *data, |
196 | struct drm_file *file_priv) | 153 | struct drm_file *file) |
197 | { | 154 | { |
198 | struct drm_i915_gem_init *args = data; | 155 | struct drm_i915_gem_init *args = data; |
199 | int ret; | 156 | |
157 | if (args->gtt_start >= args->gtt_end || | ||
158 | (args->gtt_end | args->gtt_start) & (PAGE_SIZE - 1)) | ||
159 | return -EINVAL; | ||
200 | 160 | ||
201 | mutex_lock(&dev->struct_mutex); | 161 | mutex_lock(&dev->struct_mutex); |
202 | ret = i915_gem_do_init(dev, args->gtt_start, args->gtt_end); | 162 | i915_gem_do_init(dev, args->gtt_start, args->gtt_end, args->gtt_end); |
203 | mutex_unlock(&dev->struct_mutex); | 163 | mutex_unlock(&dev->struct_mutex); |
204 | 164 | ||
205 | return ret; | 165 | return 0; |
206 | } | 166 | } |
207 | 167 | ||
208 | int | 168 | int |
209 | i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | 169 | i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, |
210 | struct drm_file *file_priv) | 170 | struct drm_file *file) |
211 | { | 171 | { |
212 | struct drm_i915_private *dev_priv = dev->dev_private; | 172 | struct drm_i915_private *dev_priv = dev->dev_private; |
213 | struct drm_i915_gem_get_aperture *args = data; | 173 | struct drm_i915_gem_get_aperture *args = data; |
174 | struct drm_i915_gem_object *obj; | ||
175 | size_t pinned; | ||
214 | 176 | ||
215 | if (!(dev->driver->driver_features & DRIVER_GEM)) | 177 | if (!(dev->driver->driver_features & DRIVER_GEM)) |
216 | return -ENODEV; | 178 | return -ENODEV; |
217 | 179 | ||
180 | pinned = 0; | ||
218 | mutex_lock(&dev->struct_mutex); | 181 | mutex_lock(&dev->struct_mutex); |
219 | args->aper_size = dev_priv->mm.gtt_total; | 182 | list_for_each_entry(obj, &dev_priv->mm.pinned_list, mm_list) |
220 | args->aper_available_size = args->aper_size - dev_priv->mm.pin_memory; | 183 | pinned += obj->gtt_space->size; |
221 | mutex_unlock(&dev->struct_mutex); | 184 | mutex_unlock(&dev->struct_mutex); |
222 | 185 | ||
186 | args->aper_size = dev_priv->mm.gtt_total; | ||
187 | args->aper_available_size = args->aper_size -pinned; | ||
188 | |||
223 | return 0; | 189 | return 0; |
224 | } | 190 | } |
225 | 191 | ||
226 | |||
227 | /** | 192 | /** |
228 | * Creates a new mm object and returns a handle to it. | 193 | * Creates a new mm object and returns a handle to it. |
229 | */ | 194 | */ |
230 | int | 195 | int |
231 | i915_gem_create_ioctl(struct drm_device *dev, void *data, | 196 | i915_gem_create_ioctl(struct drm_device *dev, void *data, |
232 | struct drm_file *file_priv) | 197 | struct drm_file *file) |
233 | { | 198 | { |
234 | struct drm_i915_gem_create *args = data; | 199 | struct drm_i915_gem_create *args = data; |
235 | struct drm_gem_object *obj; | 200 | struct drm_i915_gem_object *obj; |
236 | int ret; | 201 | int ret; |
237 | u32 handle; | 202 | u32 handle; |
238 | 203 | ||
@@ -243,45 +208,28 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, | |||
243 | if (obj == NULL) | 208 | if (obj == NULL) |
244 | return -ENOMEM; | 209 | return -ENOMEM; |
245 | 210 | ||
246 | ret = drm_gem_handle_create(file_priv, obj, &handle); | 211 | ret = drm_gem_handle_create(file, &obj->base, &handle); |
247 | if (ret) { | 212 | if (ret) { |
248 | drm_gem_object_release(obj); | 213 | drm_gem_object_release(&obj->base); |
249 | i915_gem_info_remove_obj(dev->dev_private, obj->size); | 214 | i915_gem_info_remove_obj(dev->dev_private, obj->base.size); |
250 | kfree(obj); | 215 | kfree(obj); |
251 | return ret; | 216 | return ret; |
252 | } | 217 | } |
253 | 218 | ||
254 | /* drop reference from allocate - handle holds it now */ | 219 | /* drop reference from allocate - handle holds it now */ |
255 | drm_gem_object_unreference(obj); | 220 | drm_gem_object_unreference(&obj->base); |
256 | trace_i915_gem_object_create(obj); | 221 | trace_i915_gem_object_create(obj); |
257 | 222 | ||
258 | args->handle = handle; | 223 | args->handle = handle; |
259 | return 0; | 224 | return 0; |
260 | } | 225 | } |
261 | 226 | ||
262 | static inline int | 227 | static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) |
263 | fast_shmem_read(struct page **pages, | ||
264 | loff_t page_base, int page_offset, | ||
265 | char __user *data, | ||
266 | int length) | ||
267 | { | 228 | { |
268 | char *vaddr; | 229 | drm_i915_private_t *dev_priv = obj->base.dev->dev_private; |
269 | int ret; | ||
270 | |||
271 | vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT]); | ||
272 | ret = __copy_to_user_inatomic(data, vaddr + page_offset, length); | ||
273 | kunmap_atomic(vaddr); | ||
274 | |||
275 | return ret; | ||
276 | } | ||
277 | |||
278 | static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj) | ||
279 | { | ||
280 | drm_i915_private_t *dev_priv = obj->dev->dev_private; | ||
281 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
282 | 230 | ||
283 | return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 && | 231 | return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 && |
284 | obj_priv->tiling_mode != I915_TILING_NONE; | 232 | obj->tiling_mode != I915_TILING_NONE; |
285 | } | 233 | } |
286 | 234 | ||
287 | static inline void | 235 | static inline void |
@@ -357,38 +305,51 @@ slow_shmem_bit17_copy(struct page *gpu_page, | |||
357 | * fault, it fails so we can fall back to i915_gem_shmem_pwrite_slow(). | 305 | * fault, it fails so we can fall back to i915_gem_shmem_pwrite_slow(). |
358 | */ | 306 | */ |
359 | static int | 307 | static int |
360 | i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj, | 308 | i915_gem_shmem_pread_fast(struct drm_device *dev, |
309 | struct drm_i915_gem_object *obj, | ||
361 | struct drm_i915_gem_pread *args, | 310 | struct drm_i915_gem_pread *args, |
362 | struct drm_file *file_priv) | 311 | struct drm_file *file) |
363 | { | 312 | { |
364 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 313 | struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; |
365 | ssize_t remain; | 314 | ssize_t remain; |
366 | loff_t offset, page_base; | 315 | loff_t offset; |
367 | char __user *user_data; | 316 | char __user *user_data; |
368 | int page_offset, page_length; | 317 | int page_offset, page_length; |
369 | 318 | ||
370 | user_data = (char __user *) (uintptr_t) args->data_ptr; | 319 | user_data = (char __user *) (uintptr_t) args->data_ptr; |
371 | remain = args->size; | 320 | remain = args->size; |
372 | 321 | ||
373 | obj_priv = to_intel_bo(obj); | ||
374 | offset = args->offset; | 322 | offset = args->offset; |
375 | 323 | ||
376 | while (remain > 0) { | 324 | while (remain > 0) { |
325 | struct page *page; | ||
326 | char *vaddr; | ||
327 | int ret; | ||
328 | |||
377 | /* Operation in this page | 329 | /* Operation in this page |
378 | * | 330 | * |
379 | * page_base = page offset within aperture | ||
380 | * page_offset = offset within page | 331 | * page_offset = offset within page |
381 | * page_length = bytes to copy for this page | 332 | * page_length = bytes to copy for this page |
382 | */ | 333 | */ |
383 | page_base = (offset & ~(PAGE_SIZE-1)); | ||
384 | page_offset = offset & (PAGE_SIZE-1); | 334 | page_offset = offset & (PAGE_SIZE-1); |
385 | page_length = remain; | 335 | page_length = remain; |
386 | if ((page_offset + remain) > PAGE_SIZE) | 336 | if ((page_offset + remain) > PAGE_SIZE) |
387 | page_length = PAGE_SIZE - page_offset; | 337 | page_length = PAGE_SIZE - page_offset; |
388 | 338 | ||
389 | if (fast_shmem_read(obj_priv->pages, | 339 | page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT, |
390 | page_base, page_offset, | 340 | GFP_HIGHUSER | __GFP_RECLAIMABLE); |
391 | user_data, page_length)) | 341 | if (IS_ERR(page)) |
342 | return PTR_ERR(page); | ||
343 | |||
344 | vaddr = kmap_atomic(page); | ||
345 | ret = __copy_to_user_inatomic(user_data, | ||
346 | vaddr + page_offset, | ||
347 | page_length); | ||
348 | kunmap_atomic(vaddr); | ||
349 | |||
350 | mark_page_accessed(page); | ||
351 | page_cache_release(page); | ||
352 | if (ret) | ||
392 | return -EFAULT; | 353 | return -EFAULT; |
393 | 354 | ||
394 | remain -= page_length; | 355 | remain -= page_length; |
@@ -399,30 +360,6 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
399 | return 0; | 360 | return 0; |
400 | } | 361 | } |
401 | 362 | ||
402 | static int | ||
403 | i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj) | ||
404 | { | ||
405 | int ret; | ||
406 | |||
407 | ret = i915_gem_object_get_pages(obj, __GFP_NORETRY | __GFP_NOWARN); | ||
408 | |||
409 | /* If we've insufficient memory to map in the pages, attempt | ||
410 | * to make some space by throwing out some old buffers. | ||
411 | */ | ||
412 | if (ret == -ENOMEM) { | ||
413 | struct drm_device *dev = obj->dev; | ||
414 | |||
415 | ret = i915_gem_evict_something(dev, obj->size, | ||
416 | i915_gem_get_gtt_alignment(obj)); | ||
417 | if (ret) | ||
418 | return ret; | ||
419 | |||
420 | ret = i915_gem_object_get_pages(obj, 0); | ||
421 | } | ||
422 | |||
423 | return ret; | ||
424 | } | ||
425 | |||
426 | /** | 363 | /** |
427 | * This is the fallback shmem pread path, which allocates temporary storage | 364 | * This is the fallback shmem pread path, which allocates temporary storage |
428 | * in kernel space to copy_to_user into outside of the struct_mutex, so we | 365 | * in kernel space to copy_to_user into outside of the struct_mutex, so we |
@@ -430,18 +367,19 @@ i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj) | |||
430 | * and not take page faults. | 367 | * and not take page faults. |
431 | */ | 368 | */ |
432 | static int | 369 | static int |
433 | i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, | 370 | i915_gem_shmem_pread_slow(struct drm_device *dev, |
371 | struct drm_i915_gem_object *obj, | ||
434 | struct drm_i915_gem_pread *args, | 372 | struct drm_i915_gem_pread *args, |
435 | struct drm_file *file_priv) | 373 | struct drm_file *file) |
436 | { | 374 | { |
437 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 375 | struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; |
438 | struct mm_struct *mm = current->mm; | 376 | struct mm_struct *mm = current->mm; |
439 | struct page **user_pages; | 377 | struct page **user_pages; |
440 | ssize_t remain; | 378 | ssize_t remain; |
441 | loff_t offset, pinned_pages, i; | 379 | loff_t offset, pinned_pages, i; |
442 | loff_t first_data_page, last_data_page, num_pages; | 380 | loff_t first_data_page, last_data_page, num_pages; |
443 | int shmem_page_index, shmem_page_offset; | 381 | int shmem_page_offset; |
444 | int data_page_index, data_page_offset; | 382 | int data_page_index, data_page_offset; |
445 | int page_length; | 383 | int page_length; |
446 | int ret; | 384 | int ret; |
447 | uint64_t data_ptr = args->data_ptr; | 385 | uint64_t data_ptr = args->data_ptr; |
@@ -480,19 +418,18 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
480 | 418 | ||
481 | do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); | 419 | do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); |
482 | 420 | ||
483 | obj_priv = to_intel_bo(obj); | ||
484 | offset = args->offset; | 421 | offset = args->offset; |
485 | 422 | ||
486 | while (remain > 0) { | 423 | while (remain > 0) { |
424 | struct page *page; | ||
425 | |||
487 | /* Operation in this page | 426 | /* Operation in this page |
488 | * | 427 | * |
489 | * shmem_page_index = page number within shmem file | ||
490 | * shmem_page_offset = offset within page in shmem file | 428 | * shmem_page_offset = offset within page in shmem file |
491 | * data_page_index = page number in get_user_pages return | 429 | * data_page_index = page number in get_user_pages return |
492 | * data_page_offset = offset with data_page_index page. | 430 | * data_page_offset = offset with data_page_index page. |
493 | * page_length = bytes to copy for this page | 431 | * page_length = bytes to copy for this page |
494 | */ | 432 | */ |
495 | shmem_page_index = offset / PAGE_SIZE; | ||
496 | shmem_page_offset = offset & ~PAGE_MASK; | 433 | shmem_page_offset = offset & ~PAGE_MASK; |
497 | data_page_index = data_ptr / PAGE_SIZE - first_data_page; | 434 | data_page_index = data_ptr / PAGE_SIZE - first_data_page; |
498 | data_page_offset = data_ptr & ~PAGE_MASK; | 435 | data_page_offset = data_ptr & ~PAGE_MASK; |
@@ -503,8 +440,13 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
503 | if ((data_page_offset + page_length) > PAGE_SIZE) | 440 | if ((data_page_offset + page_length) > PAGE_SIZE) |
504 | page_length = PAGE_SIZE - data_page_offset; | 441 | page_length = PAGE_SIZE - data_page_offset; |
505 | 442 | ||
443 | page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT, | ||
444 | GFP_HIGHUSER | __GFP_RECLAIMABLE); | ||
445 | if (IS_ERR(page)) | ||
446 | return PTR_ERR(page); | ||
447 | |||
506 | if (do_bit17_swizzling) { | 448 | if (do_bit17_swizzling) { |
507 | slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], | 449 | slow_shmem_bit17_copy(page, |
508 | shmem_page_offset, | 450 | shmem_page_offset, |
509 | user_pages[data_page_index], | 451 | user_pages[data_page_index], |
510 | data_page_offset, | 452 | data_page_offset, |
@@ -513,11 +455,14 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
513 | } else { | 455 | } else { |
514 | slow_shmem_copy(user_pages[data_page_index], | 456 | slow_shmem_copy(user_pages[data_page_index], |
515 | data_page_offset, | 457 | data_page_offset, |
516 | obj_priv->pages[shmem_page_index], | 458 | page, |
517 | shmem_page_offset, | 459 | shmem_page_offset, |
518 | page_length); | 460 | page_length); |
519 | } | 461 | } |
520 | 462 | ||
463 | mark_page_accessed(page); | ||
464 | page_cache_release(page); | ||
465 | |||
521 | remain -= page_length; | 466 | remain -= page_length; |
522 | data_ptr += page_length; | 467 | data_ptr += page_length; |
523 | offset += page_length; | 468 | offset += page_length; |
@@ -526,6 +471,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
526 | out: | 471 | out: |
527 | for (i = 0; i < pinned_pages; i++) { | 472 | for (i = 0; i < pinned_pages; i++) { |
528 | SetPageDirty(user_pages[i]); | 473 | SetPageDirty(user_pages[i]); |
474 | mark_page_accessed(user_pages[i]); | ||
529 | page_cache_release(user_pages[i]); | 475 | page_cache_release(user_pages[i]); |
530 | } | 476 | } |
531 | drm_free_large(user_pages); | 477 | drm_free_large(user_pages); |
@@ -540,11 +486,10 @@ out: | |||
540 | */ | 486 | */ |
541 | int | 487 | int |
542 | i915_gem_pread_ioctl(struct drm_device *dev, void *data, | 488 | i915_gem_pread_ioctl(struct drm_device *dev, void *data, |
543 | struct drm_file *file_priv) | 489 | struct drm_file *file) |
544 | { | 490 | { |
545 | struct drm_i915_gem_pread *args = data; | 491 | struct drm_i915_gem_pread *args = data; |
546 | struct drm_gem_object *obj; | 492 | struct drm_i915_gem_object *obj; |
547 | struct drm_i915_gem_object *obj_priv; | ||
548 | int ret = 0; | 493 | int ret = 0; |
549 | 494 | ||
550 | if (args->size == 0) | 495 | if (args->size == 0) |
@@ -564,39 +509,33 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
564 | if (ret) | 509 | if (ret) |
565 | return ret; | 510 | return ret; |
566 | 511 | ||
567 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 512 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); |
568 | if (obj == NULL) { | 513 | if (obj == NULL) { |
569 | ret = -ENOENT; | 514 | ret = -ENOENT; |
570 | goto unlock; | 515 | goto unlock; |
571 | } | 516 | } |
572 | obj_priv = to_intel_bo(obj); | ||
573 | 517 | ||
574 | /* Bounds check source. */ | 518 | /* Bounds check source. */ |
575 | if (args->offset > obj->size || args->size > obj->size - args->offset) { | 519 | if (args->offset > obj->base.size || |
520 | args->size > obj->base.size - args->offset) { | ||
576 | ret = -EINVAL; | 521 | ret = -EINVAL; |
577 | goto out; | 522 | goto out; |
578 | } | 523 | } |
579 | 524 | ||
580 | ret = i915_gem_object_get_pages_or_evict(obj); | ||
581 | if (ret) | ||
582 | goto out; | ||
583 | |||
584 | ret = i915_gem_object_set_cpu_read_domain_range(obj, | 525 | ret = i915_gem_object_set_cpu_read_domain_range(obj, |
585 | args->offset, | 526 | args->offset, |
586 | args->size); | 527 | args->size); |
587 | if (ret) | 528 | if (ret) |
588 | goto out_put; | 529 | goto out; |
589 | 530 | ||
590 | ret = -EFAULT; | 531 | ret = -EFAULT; |
591 | if (!i915_gem_object_needs_bit17_swizzle(obj)) | 532 | if (!i915_gem_object_needs_bit17_swizzle(obj)) |
592 | ret = i915_gem_shmem_pread_fast(dev, obj, args, file_priv); | 533 | ret = i915_gem_shmem_pread_fast(dev, obj, args, file); |
593 | if (ret == -EFAULT) | 534 | if (ret == -EFAULT) |
594 | ret = i915_gem_shmem_pread_slow(dev, obj, args, file_priv); | 535 | ret = i915_gem_shmem_pread_slow(dev, obj, args, file); |
595 | 536 | ||
596 | out_put: | ||
597 | i915_gem_object_put_pages(obj); | ||
598 | out: | 537 | out: |
599 | drm_gem_object_unreference(obj); | 538 | drm_gem_object_unreference(&obj->base); |
600 | unlock: | 539 | unlock: |
601 | mutex_unlock(&dev->struct_mutex); | 540 | mutex_unlock(&dev->struct_mutex); |
602 | return ret; | 541 | return ret; |
@@ -646,32 +585,16 @@ slow_kernel_write(struct io_mapping *mapping, | |||
646 | io_mapping_unmap(dst_vaddr); | 585 | io_mapping_unmap(dst_vaddr); |
647 | } | 586 | } |
648 | 587 | ||
649 | static inline int | ||
650 | fast_shmem_write(struct page **pages, | ||
651 | loff_t page_base, int page_offset, | ||
652 | char __user *data, | ||
653 | int length) | ||
654 | { | ||
655 | char *vaddr; | ||
656 | int ret; | ||
657 | |||
658 | vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT]); | ||
659 | ret = __copy_from_user_inatomic(vaddr + page_offset, data, length); | ||
660 | kunmap_atomic(vaddr); | ||
661 | |||
662 | return ret; | ||
663 | } | ||
664 | |||
665 | /** | 588 | /** |
666 | * This is the fast pwrite path, where we copy the data directly from the | 589 | * This is the fast pwrite path, where we copy the data directly from the |
667 | * user into the GTT, uncached. | 590 | * user into the GTT, uncached. |
668 | */ | 591 | */ |
669 | static int | 592 | static int |
670 | i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, | 593 | i915_gem_gtt_pwrite_fast(struct drm_device *dev, |
594 | struct drm_i915_gem_object *obj, | ||
671 | struct drm_i915_gem_pwrite *args, | 595 | struct drm_i915_gem_pwrite *args, |
672 | struct drm_file *file_priv) | 596 | struct drm_file *file) |
673 | { | 597 | { |
674 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
675 | drm_i915_private_t *dev_priv = dev->dev_private; | 598 | drm_i915_private_t *dev_priv = dev->dev_private; |
676 | ssize_t remain; | 599 | ssize_t remain; |
677 | loff_t offset, page_base; | 600 | loff_t offset, page_base; |
@@ -681,8 +604,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
681 | user_data = (char __user *) (uintptr_t) args->data_ptr; | 604 | user_data = (char __user *) (uintptr_t) args->data_ptr; |
682 | remain = args->size; | 605 | remain = args->size; |
683 | 606 | ||
684 | obj_priv = to_intel_bo(obj); | 607 | offset = obj->gtt_offset + args->offset; |
685 | offset = obj_priv->gtt_offset + args->offset; | ||
686 | 608 | ||
687 | while (remain > 0) { | 609 | while (remain > 0) { |
688 | /* Operation in this page | 610 | /* Operation in this page |
@@ -722,11 +644,11 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
722 | * than using i915_gem_gtt_pwrite_fast on a G45 (32-bit). | 644 | * than using i915_gem_gtt_pwrite_fast on a G45 (32-bit). |
723 | */ | 645 | */ |
724 | static int | 646 | static int |
725 | i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, | 647 | i915_gem_gtt_pwrite_slow(struct drm_device *dev, |
648 | struct drm_i915_gem_object *obj, | ||
726 | struct drm_i915_gem_pwrite *args, | 649 | struct drm_i915_gem_pwrite *args, |
727 | struct drm_file *file_priv) | 650 | struct drm_file *file) |
728 | { | 651 | { |
729 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
730 | drm_i915_private_t *dev_priv = dev->dev_private; | 652 | drm_i915_private_t *dev_priv = dev->dev_private; |
731 | ssize_t remain; | 653 | ssize_t remain; |
732 | loff_t gtt_page_base, offset; | 654 | loff_t gtt_page_base, offset; |
@@ -763,12 +685,15 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
763 | goto out_unpin_pages; | 685 | goto out_unpin_pages; |
764 | } | 686 | } |
765 | 687 | ||
766 | ret = i915_gem_object_set_to_gtt_domain(obj, 1); | 688 | ret = i915_gem_object_set_to_gtt_domain(obj, true); |
689 | if (ret) | ||
690 | goto out_unpin_pages; | ||
691 | |||
692 | ret = i915_gem_object_put_fence(obj); | ||
767 | if (ret) | 693 | if (ret) |
768 | goto out_unpin_pages; | 694 | goto out_unpin_pages; |
769 | 695 | ||
770 | obj_priv = to_intel_bo(obj); | 696 | offset = obj->gtt_offset + args->offset; |
771 | offset = obj_priv->gtt_offset + args->offset; | ||
772 | 697 | ||
773 | while (remain > 0) { | 698 | while (remain > 0) { |
774 | /* Operation in this page | 699 | /* Operation in this page |
@@ -814,39 +739,58 @@ out_unpin_pages: | |||
814 | * copy_from_user into the kmapped pages backing the object. | 739 | * copy_from_user into the kmapped pages backing the object. |
815 | */ | 740 | */ |
816 | static int | 741 | static int |
817 | i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, | 742 | i915_gem_shmem_pwrite_fast(struct drm_device *dev, |
743 | struct drm_i915_gem_object *obj, | ||
818 | struct drm_i915_gem_pwrite *args, | 744 | struct drm_i915_gem_pwrite *args, |
819 | struct drm_file *file_priv) | 745 | struct drm_file *file) |
820 | { | 746 | { |
821 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 747 | struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; |
822 | ssize_t remain; | 748 | ssize_t remain; |
823 | loff_t offset, page_base; | 749 | loff_t offset; |
824 | char __user *user_data; | 750 | char __user *user_data; |
825 | int page_offset, page_length; | 751 | int page_offset, page_length; |
826 | 752 | ||
827 | user_data = (char __user *) (uintptr_t) args->data_ptr; | 753 | user_data = (char __user *) (uintptr_t) args->data_ptr; |
828 | remain = args->size; | 754 | remain = args->size; |
829 | 755 | ||
830 | obj_priv = to_intel_bo(obj); | ||
831 | offset = args->offset; | 756 | offset = args->offset; |
832 | obj_priv->dirty = 1; | 757 | obj->dirty = 1; |
833 | 758 | ||
834 | while (remain > 0) { | 759 | while (remain > 0) { |
760 | struct page *page; | ||
761 | char *vaddr; | ||
762 | int ret; | ||
763 | |||
835 | /* Operation in this page | 764 | /* Operation in this page |
836 | * | 765 | * |
837 | * page_base = page offset within aperture | ||
838 | * page_offset = offset within page | 766 | * page_offset = offset within page |
839 | * page_length = bytes to copy for this page | 767 | * page_length = bytes to copy for this page |
840 | */ | 768 | */ |
841 | page_base = (offset & ~(PAGE_SIZE-1)); | ||
842 | page_offset = offset & (PAGE_SIZE-1); | 769 | page_offset = offset & (PAGE_SIZE-1); |
843 | page_length = remain; | 770 | page_length = remain; |
844 | if ((page_offset + remain) > PAGE_SIZE) | 771 | if ((page_offset + remain) > PAGE_SIZE) |
845 | page_length = PAGE_SIZE - page_offset; | 772 | page_length = PAGE_SIZE - page_offset; |
846 | 773 | ||
847 | if (fast_shmem_write(obj_priv->pages, | 774 | page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT, |
848 | page_base, page_offset, | 775 | GFP_HIGHUSER | __GFP_RECLAIMABLE); |
849 | user_data, page_length)) | 776 | if (IS_ERR(page)) |
777 | return PTR_ERR(page); | ||
778 | |||
779 | vaddr = kmap_atomic(page, KM_USER0); | ||
780 | ret = __copy_from_user_inatomic(vaddr + page_offset, | ||
781 | user_data, | ||
782 | page_length); | ||
783 | kunmap_atomic(vaddr, KM_USER0); | ||
784 | |||
785 | set_page_dirty(page); | ||
786 | mark_page_accessed(page); | ||
787 | page_cache_release(page); | ||
788 | |||
789 | /* If we get a fault while copying data, then (presumably) our | ||
790 | * source page isn't available. Return the error and we'll | ||
791 | * retry in the slow path. | ||
792 | */ | ||
793 | if (ret) | ||
850 | return -EFAULT; | 794 | return -EFAULT; |
851 | 795 | ||
852 | remain -= page_length; | 796 | remain -= page_length; |
@@ -865,17 +809,18 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
865 | * struct_mutex is held. | 809 | * struct_mutex is held. |
866 | */ | 810 | */ |
867 | static int | 811 | static int |
868 | i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, | 812 | i915_gem_shmem_pwrite_slow(struct drm_device *dev, |
813 | struct drm_i915_gem_object *obj, | ||
869 | struct drm_i915_gem_pwrite *args, | 814 | struct drm_i915_gem_pwrite *args, |
870 | struct drm_file *file_priv) | 815 | struct drm_file *file) |
871 | { | 816 | { |
872 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 817 | struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; |
873 | struct mm_struct *mm = current->mm; | 818 | struct mm_struct *mm = current->mm; |
874 | struct page **user_pages; | 819 | struct page **user_pages; |
875 | ssize_t remain; | 820 | ssize_t remain; |
876 | loff_t offset, pinned_pages, i; | 821 | loff_t offset, pinned_pages, i; |
877 | loff_t first_data_page, last_data_page, num_pages; | 822 | loff_t first_data_page, last_data_page, num_pages; |
878 | int shmem_page_index, shmem_page_offset; | 823 | int shmem_page_offset; |
879 | int data_page_index, data_page_offset; | 824 | int data_page_index, data_page_offset; |
880 | int page_length; | 825 | int page_length; |
881 | int ret; | 826 | int ret; |
@@ -913,20 +858,19 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
913 | 858 | ||
914 | do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); | 859 | do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); |
915 | 860 | ||
916 | obj_priv = to_intel_bo(obj); | ||
917 | offset = args->offset; | 861 | offset = args->offset; |
918 | obj_priv->dirty = 1; | 862 | obj->dirty = 1; |
919 | 863 | ||
920 | while (remain > 0) { | 864 | while (remain > 0) { |
865 | struct page *page; | ||
866 | |||
921 | /* Operation in this page | 867 | /* Operation in this page |
922 | * | 868 | * |
923 | * shmem_page_index = page number within shmem file | ||
924 | * shmem_page_offset = offset within page in shmem file | 869 | * shmem_page_offset = offset within page in shmem file |
925 | * data_page_index = page number in get_user_pages return | 870 | * data_page_index = page number in get_user_pages return |
926 | * data_page_offset = offset with data_page_index page. | 871 | * data_page_offset = offset with data_page_index page. |
927 | * page_length = bytes to copy for this page | 872 | * page_length = bytes to copy for this page |
928 | */ | 873 | */ |
929 | shmem_page_index = offset / PAGE_SIZE; | ||
930 | shmem_page_offset = offset & ~PAGE_MASK; | 874 | shmem_page_offset = offset & ~PAGE_MASK; |
931 | data_page_index = data_ptr / PAGE_SIZE - first_data_page; | 875 | data_page_index = data_ptr / PAGE_SIZE - first_data_page; |
932 | data_page_offset = data_ptr & ~PAGE_MASK; | 876 | data_page_offset = data_ptr & ~PAGE_MASK; |
@@ -937,21 +881,32 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
937 | if ((data_page_offset + page_length) > PAGE_SIZE) | 881 | if ((data_page_offset + page_length) > PAGE_SIZE) |
938 | page_length = PAGE_SIZE - data_page_offset; | 882 | page_length = PAGE_SIZE - data_page_offset; |
939 | 883 | ||
884 | page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT, | ||
885 | GFP_HIGHUSER | __GFP_RECLAIMABLE); | ||
886 | if (IS_ERR(page)) { | ||
887 | ret = PTR_ERR(page); | ||
888 | goto out; | ||
889 | } | ||
890 | |||
940 | if (do_bit17_swizzling) { | 891 | if (do_bit17_swizzling) { |
941 | slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], | 892 | slow_shmem_bit17_copy(page, |
942 | shmem_page_offset, | 893 | shmem_page_offset, |
943 | user_pages[data_page_index], | 894 | user_pages[data_page_index], |
944 | data_page_offset, | 895 | data_page_offset, |
945 | page_length, | 896 | page_length, |
946 | 0); | 897 | 0); |
947 | } else { | 898 | } else { |
948 | slow_shmem_copy(obj_priv->pages[shmem_page_index], | 899 | slow_shmem_copy(page, |
949 | shmem_page_offset, | 900 | shmem_page_offset, |
950 | user_pages[data_page_index], | 901 | user_pages[data_page_index], |
951 | data_page_offset, | 902 | data_page_offset, |
952 | page_length); | 903 | page_length); |
953 | } | 904 | } |
954 | 905 | ||
906 | set_page_dirty(page); | ||
907 | mark_page_accessed(page); | ||
908 | page_cache_release(page); | ||
909 | |||
955 | remain -= page_length; | 910 | remain -= page_length; |
956 | data_ptr += page_length; | 911 | data_ptr += page_length; |
957 | offset += page_length; | 912 | offset += page_length; |
@@ -975,8 +930,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
975 | struct drm_file *file) | 930 | struct drm_file *file) |
976 | { | 931 | { |
977 | struct drm_i915_gem_pwrite *args = data; | 932 | struct drm_i915_gem_pwrite *args = data; |
978 | struct drm_gem_object *obj; | 933 | struct drm_i915_gem_object *obj; |
979 | struct drm_i915_gem_object *obj_priv; | ||
980 | int ret; | 934 | int ret; |
981 | 935 | ||
982 | if (args->size == 0) | 936 | if (args->size == 0) |
@@ -996,15 +950,15 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
996 | if (ret) | 950 | if (ret) |
997 | return ret; | 951 | return ret; |
998 | 952 | ||
999 | obj = drm_gem_object_lookup(dev, file, args->handle); | 953 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); |
1000 | if (obj == NULL) { | 954 | if (obj == NULL) { |
1001 | ret = -ENOENT; | 955 | ret = -ENOENT; |
1002 | goto unlock; | 956 | goto unlock; |
1003 | } | 957 | } |
1004 | obj_priv = to_intel_bo(obj); | ||
1005 | 958 | ||
1006 | /* Bounds check destination. */ | 959 | /* Bounds check destination. */ |
1007 | if (args->offset > obj->size || args->size > obj->size - args->offset) { | 960 | if (args->offset > obj->base.size || |
961 | args->size > obj->base.size - args->offset) { | ||
1008 | ret = -EINVAL; | 962 | ret = -EINVAL; |
1009 | goto out; | 963 | goto out; |
1010 | } | 964 | } |
@@ -1015,16 +969,19 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
1015 | * pread/pwrite currently are reading and writing from the CPU | 969 | * pread/pwrite currently are reading and writing from the CPU |
1016 | * perspective, requiring manual detiling by the client. | 970 | * perspective, requiring manual detiling by the client. |
1017 | */ | 971 | */ |
1018 | if (obj_priv->phys_obj) | 972 | if (obj->phys_obj) |
1019 | ret = i915_gem_phys_pwrite(dev, obj, args, file); | 973 | ret = i915_gem_phys_pwrite(dev, obj, args, file); |
1020 | else if (obj_priv->tiling_mode == I915_TILING_NONE && | 974 | else if (obj->gtt_space && |
1021 | obj_priv->gtt_space && | 975 | obj->base.write_domain != I915_GEM_DOMAIN_CPU) { |
1022 | obj->write_domain != I915_GEM_DOMAIN_CPU) { | 976 | ret = i915_gem_object_pin(obj, 0, true); |
1023 | ret = i915_gem_object_pin(obj, 0); | ||
1024 | if (ret) | 977 | if (ret) |
1025 | goto out; | 978 | goto out; |
1026 | 979 | ||
1027 | ret = i915_gem_object_set_to_gtt_domain(obj, 1); | 980 | ret = i915_gem_object_set_to_gtt_domain(obj, true); |
981 | if (ret) | ||
982 | goto out_unpin; | ||
983 | |||
984 | ret = i915_gem_object_put_fence(obj); | ||
1028 | if (ret) | 985 | if (ret) |
1029 | goto out_unpin; | 986 | goto out_unpin; |
1030 | 987 | ||
@@ -1035,26 +992,19 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
1035 | out_unpin: | 992 | out_unpin: |
1036 | i915_gem_object_unpin(obj); | 993 | i915_gem_object_unpin(obj); |
1037 | } else { | 994 | } else { |
1038 | ret = i915_gem_object_get_pages_or_evict(obj); | ||
1039 | if (ret) | ||
1040 | goto out; | ||
1041 | |||
1042 | ret = i915_gem_object_set_to_cpu_domain(obj, 1); | 995 | ret = i915_gem_object_set_to_cpu_domain(obj, 1); |
1043 | if (ret) | 996 | if (ret) |
1044 | goto out_put; | 997 | goto out; |
1045 | 998 | ||
1046 | ret = -EFAULT; | 999 | ret = -EFAULT; |
1047 | if (!i915_gem_object_needs_bit17_swizzle(obj)) | 1000 | if (!i915_gem_object_needs_bit17_swizzle(obj)) |
1048 | ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file); | 1001 | ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file); |
1049 | if (ret == -EFAULT) | 1002 | if (ret == -EFAULT) |
1050 | ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file); | 1003 | ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file); |
1051 | |||
1052 | out_put: | ||
1053 | i915_gem_object_put_pages(obj); | ||
1054 | } | 1004 | } |
1055 | 1005 | ||
1056 | out: | 1006 | out: |
1057 | drm_gem_object_unreference(obj); | 1007 | drm_gem_object_unreference(&obj->base); |
1058 | unlock: | 1008 | unlock: |
1059 | mutex_unlock(&dev->struct_mutex); | 1009 | mutex_unlock(&dev->struct_mutex); |
1060 | return ret; | 1010 | return ret; |
@@ -1066,12 +1016,10 @@ unlock: | |||
1066 | */ | 1016 | */ |
1067 | int | 1017 | int |
1068 | i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | 1018 | i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, |
1069 | struct drm_file *file_priv) | 1019 | struct drm_file *file) |
1070 | { | 1020 | { |
1071 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1072 | struct drm_i915_gem_set_domain *args = data; | 1021 | struct drm_i915_gem_set_domain *args = data; |
1073 | struct drm_gem_object *obj; | 1022 | struct drm_i915_gem_object *obj; |
1074 | struct drm_i915_gem_object *obj_priv; | ||
1075 | uint32_t read_domains = args->read_domains; | 1023 | uint32_t read_domains = args->read_domains; |
1076 | uint32_t write_domain = args->write_domain; | 1024 | uint32_t write_domain = args->write_domain; |
1077 | int ret; | 1025 | int ret; |
@@ -1096,28 +1044,15 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
1096 | if (ret) | 1044 | if (ret) |
1097 | return ret; | 1045 | return ret; |
1098 | 1046 | ||
1099 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 1047 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); |
1100 | if (obj == NULL) { | 1048 | if (obj == NULL) { |
1101 | ret = -ENOENT; | 1049 | ret = -ENOENT; |
1102 | goto unlock; | 1050 | goto unlock; |
1103 | } | 1051 | } |
1104 | obj_priv = to_intel_bo(obj); | ||
1105 | |||
1106 | intel_mark_busy(dev, obj); | ||
1107 | 1052 | ||
1108 | if (read_domains & I915_GEM_DOMAIN_GTT) { | 1053 | if (read_domains & I915_GEM_DOMAIN_GTT) { |
1109 | ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); | 1054 | ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); |
1110 | 1055 | ||
1111 | /* Update the LRU on the fence for the CPU access that's | ||
1112 | * about to occur. | ||
1113 | */ | ||
1114 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { | ||
1115 | struct drm_i915_fence_reg *reg = | ||
1116 | &dev_priv->fence_regs[obj_priv->fence_reg]; | ||
1117 | list_move_tail(®->lru_list, | ||
1118 | &dev_priv->mm.fence_list); | ||
1119 | } | ||
1120 | |||
1121 | /* Silently promote "you're not bound, there was nothing to do" | 1056 | /* Silently promote "you're not bound, there was nothing to do" |
1122 | * to success, since the client was just asking us to | 1057 | * to success, since the client was just asking us to |
1123 | * make sure everything was done. | 1058 | * make sure everything was done. |
@@ -1128,11 +1063,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
1128 | ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); | 1063 | ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); |
1129 | } | 1064 | } |
1130 | 1065 | ||
1131 | /* Maintain LRU order of "inactive" objects */ | 1066 | drm_gem_object_unreference(&obj->base); |
1132 | if (ret == 0 && i915_gem_object_is_inactive(obj_priv)) | ||
1133 | list_move_tail(&obj_priv->mm_list, &dev_priv->mm.inactive_list); | ||
1134 | |||
1135 | drm_gem_object_unreference(obj); | ||
1136 | unlock: | 1067 | unlock: |
1137 | mutex_unlock(&dev->struct_mutex); | 1068 | mutex_unlock(&dev->struct_mutex); |
1138 | return ret; | 1069 | return ret; |
@@ -1143,10 +1074,10 @@ unlock: | |||
1143 | */ | 1074 | */ |
1144 | int | 1075 | int |
1145 | i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, | 1076 | i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, |
1146 | struct drm_file *file_priv) | 1077 | struct drm_file *file) |
1147 | { | 1078 | { |
1148 | struct drm_i915_gem_sw_finish *args = data; | 1079 | struct drm_i915_gem_sw_finish *args = data; |
1149 | struct drm_gem_object *obj; | 1080 | struct drm_i915_gem_object *obj; |
1150 | int ret = 0; | 1081 | int ret = 0; |
1151 | 1082 | ||
1152 | if (!(dev->driver->driver_features & DRIVER_GEM)) | 1083 | if (!(dev->driver->driver_features & DRIVER_GEM)) |
@@ -1156,17 +1087,17 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, | |||
1156 | if (ret) | 1087 | if (ret) |
1157 | return ret; | 1088 | return ret; |
1158 | 1089 | ||
1159 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 1090 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); |
1160 | if (obj == NULL) { | 1091 | if (obj == NULL) { |
1161 | ret = -ENOENT; | 1092 | ret = -ENOENT; |
1162 | goto unlock; | 1093 | goto unlock; |
1163 | } | 1094 | } |
1164 | 1095 | ||
1165 | /* Pinned buffers may be scanout, so flush the cache */ | 1096 | /* Pinned buffers may be scanout, so flush the cache */ |
1166 | if (to_intel_bo(obj)->pin_count) | 1097 | if (obj->pin_count) |
1167 | i915_gem_object_flush_cpu_write_domain(obj); | 1098 | i915_gem_object_flush_cpu_write_domain(obj); |
1168 | 1099 | ||
1169 | drm_gem_object_unreference(obj); | 1100 | drm_gem_object_unreference(&obj->base); |
1170 | unlock: | 1101 | unlock: |
1171 | mutex_unlock(&dev->struct_mutex); | 1102 | mutex_unlock(&dev->struct_mutex); |
1172 | return ret; | 1103 | return ret; |
@@ -1181,8 +1112,9 @@ unlock: | |||
1181 | */ | 1112 | */ |
1182 | int | 1113 | int |
1183 | i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | 1114 | i915_gem_mmap_ioctl(struct drm_device *dev, void *data, |
1184 | struct drm_file *file_priv) | 1115 | struct drm_file *file) |
1185 | { | 1116 | { |
1117 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1186 | struct drm_i915_gem_mmap *args = data; | 1118 | struct drm_i915_gem_mmap *args = data; |
1187 | struct drm_gem_object *obj; | 1119 | struct drm_gem_object *obj; |
1188 | loff_t offset; | 1120 | loff_t offset; |
@@ -1191,10 +1123,15 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
1191 | if (!(dev->driver->driver_features & DRIVER_GEM)) | 1123 | if (!(dev->driver->driver_features & DRIVER_GEM)) |
1192 | return -ENODEV; | 1124 | return -ENODEV; |
1193 | 1125 | ||
1194 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 1126 | obj = drm_gem_object_lookup(dev, file, args->handle); |
1195 | if (obj == NULL) | 1127 | if (obj == NULL) |
1196 | return -ENOENT; | 1128 | return -ENOENT; |
1197 | 1129 | ||
1130 | if (obj->size > dev_priv->mm.gtt_mappable_end) { | ||
1131 | drm_gem_object_unreference_unlocked(obj); | ||
1132 | return -E2BIG; | ||
1133 | } | ||
1134 | |||
1198 | offset = args->offset; | 1135 | offset = args->offset; |
1199 | 1136 | ||
1200 | down_write(¤t->mm->mmap_sem); | 1137 | down_write(¤t->mm->mmap_sem); |
@@ -1229,10 +1166,9 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
1229 | */ | 1166 | */ |
1230 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | 1167 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
1231 | { | 1168 | { |
1232 | struct drm_gem_object *obj = vma->vm_private_data; | 1169 | struct drm_i915_gem_object *obj = to_intel_bo(vma->vm_private_data); |
1233 | struct drm_device *dev = obj->dev; | 1170 | struct drm_device *dev = obj->base.dev; |
1234 | drm_i915_private_t *dev_priv = dev->dev_private; | 1171 | drm_i915_private_t *dev_priv = dev->dev_private; |
1235 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
1236 | pgoff_t page_offset; | 1172 | pgoff_t page_offset; |
1237 | unsigned long pfn; | 1173 | unsigned long pfn; |
1238 | int ret = 0; | 1174 | int ret = 0; |
@@ -1244,27 +1180,35 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1244 | 1180 | ||
1245 | /* Now bind it into the GTT if needed */ | 1181 | /* Now bind it into the GTT if needed */ |
1246 | mutex_lock(&dev->struct_mutex); | 1182 | mutex_lock(&dev->struct_mutex); |
1247 | if (!obj_priv->gtt_space) { | ||
1248 | ret = i915_gem_object_bind_to_gtt(obj, 0); | ||
1249 | if (ret) | ||
1250 | goto unlock; | ||
1251 | 1183 | ||
1252 | ret = i915_gem_object_set_to_gtt_domain(obj, write); | 1184 | if (!obj->map_and_fenceable) { |
1185 | ret = i915_gem_object_unbind(obj); | ||
1253 | if (ret) | 1186 | if (ret) |
1254 | goto unlock; | 1187 | goto unlock; |
1255 | } | 1188 | } |
1256 | 1189 | if (!obj->gtt_space) { | |
1257 | /* Need a new fence register? */ | 1190 | ret = i915_gem_object_bind_to_gtt(obj, 0, true); |
1258 | if (obj_priv->tiling_mode != I915_TILING_NONE) { | ||
1259 | ret = i915_gem_object_get_fence_reg(obj, true); | ||
1260 | if (ret) | 1191 | if (ret) |
1261 | goto unlock; | 1192 | goto unlock; |
1262 | } | 1193 | } |
1263 | 1194 | ||
1264 | if (i915_gem_object_is_inactive(obj_priv)) | 1195 | ret = i915_gem_object_set_to_gtt_domain(obj, write); |
1265 | list_move_tail(&obj_priv->mm_list, &dev_priv->mm.inactive_list); | 1196 | if (ret) |
1197 | goto unlock; | ||
1198 | |||
1199 | if (obj->tiling_mode == I915_TILING_NONE) | ||
1200 | ret = i915_gem_object_put_fence(obj); | ||
1201 | else | ||
1202 | ret = i915_gem_object_get_fence(obj, NULL, true); | ||
1203 | if (ret) | ||
1204 | goto unlock; | ||
1205 | |||
1206 | if (i915_gem_object_is_inactive(obj)) | ||
1207 | list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); | ||
1208 | |||
1209 | obj->fault_mappable = true; | ||
1266 | 1210 | ||
1267 | pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) + | 1211 | pfn = ((dev->agp->base + obj->gtt_offset) >> PAGE_SHIFT) + |
1268 | page_offset; | 1212 | page_offset; |
1269 | 1213 | ||
1270 | /* Finally, remap it using the new GTT offset */ | 1214 | /* Finally, remap it using the new GTT offset */ |
@@ -1273,11 +1217,12 @@ unlock: | |||
1273 | mutex_unlock(&dev->struct_mutex); | 1217 | mutex_unlock(&dev->struct_mutex); |
1274 | 1218 | ||
1275 | switch (ret) { | 1219 | switch (ret) { |
1220 | case -EAGAIN: | ||
1221 | set_need_resched(); | ||
1276 | case 0: | 1222 | case 0: |
1277 | case -ERESTARTSYS: | 1223 | case -ERESTARTSYS: |
1278 | return VM_FAULT_NOPAGE; | 1224 | return VM_FAULT_NOPAGE; |
1279 | case -ENOMEM: | 1225 | case -ENOMEM: |
1280 | case -EAGAIN: | ||
1281 | return VM_FAULT_OOM; | 1226 | return VM_FAULT_OOM; |
1282 | default: | 1227 | default: |
1283 | return VM_FAULT_SIGBUS; | 1228 | return VM_FAULT_SIGBUS; |
@@ -1296,37 +1241,39 @@ unlock: | |||
1296 | * This routine allocates and attaches a fake offset for @obj. | 1241 | * This routine allocates and attaches a fake offset for @obj. |
1297 | */ | 1242 | */ |
1298 | static int | 1243 | static int |
1299 | i915_gem_create_mmap_offset(struct drm_gem_object *obj) | 1244 | i915_gem_create_mmap_offset(struct drm_i915_gem_object *obj) |
1300 | { | 1245 | { |
1301 | struct drm_device *dev = obj->dev; | 1246 | struct drm_device *dev = obj->base.dev; |
1302 | struct drm_gem_mm *mm = dev->mm_private; | 1247 | struct drm_gem_mm *mm = dev->mm_private; |
1303 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
1304 | struct drm_map_list *list; | 1248 | struct drm_map_list *list; |
1305 | struct drm_local_map *map; | 1249 | struct drm_local_map *map; |
1306 | int ret = 0; | 1250 | int ret = 0; |
1307 | 1251 | ||
1308 | /* Set the object up for mmap'ing */ | 1252 | /* Set the object up for mmap'ing */ |
1309 | list = &obj->map_list; | 1253 | list = &obj->base.map_list; |
1310 | list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL); | 1254 | list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL); |
1311 | if (!list->map) | 1255 | if (!list->map) |
1312 | return -ENOMEM; | 1256 | return -ENOMEM; |
1313 | 1257 | ||
1314 | map = list->map; | 1258 | map = list->map; |
1315 | map->type = _DRM_GEM; | 1259 | map->type = _DRM_GEM; |
1316 | map->size = obj->size; | 1260 | map->size = obj->base.size; |
1317 | map->handle = obj; | 1261 | map->handle = obj; |
1318 | 1262 | ||
1319 | /* Get a DRM GEM mmap offset allocated... */ | 1263 | /* Get a DRM GEM mmap offset allocated... */ |
1320 | list->file_offset_node = drm_mm_search_free(&mm->offset_manager, | 1264 | list->file_offset_node = drm_mm_search_free(&mm->offset_manager, |
1321 | obj->size / PAGE_SIZE, 0, 0); | 1265 | obj->base.size / PAGE_SIZE, |
1266 | 0, 0); | ||
1322 | if (!list->file_offset_node) { | 1267 | if (!list->file_offset_node) { |
1323 | DRM_ERROR("failed to allocate offset for bo %d\n", obj->name); | 1268 | DRM_ERROR("failed to allocate offset for bo %d\n", |
1269 | obj->base.name); | ||
1324 | ret = -ENOSPC; | 1270 | ret = -ENOSPC; |
1325 | goto out_free_list; | 1271 | goto out_free_list; |
1326 | } | 1272 | } |
1327 | 1273 | ||
1328 | list->file_offset_node = drm_mm_get_block(list->file_offset_node, | 1274 | list->file_offset_node = drm_mm_get_block(list->file_offset_node, |
1329 | obj->size / PAGE_SIZE, 0); | 1275 | obj->base.size / PAGE_SIZE, |
1276 | 0); | ||
1330 | if (!list->file_offset_node) { | 1277 | if (!list->file_offset_node) { |
1331 | ret = -ENOMEM; | 1278 | ret = -ENOMEM; |
1332 | goto out_free_list; | 1279 | goto out_free_list; |
@@ -1339,16 +1286,13 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj) | |||
1339 | goto out_free_mm; | 1286 | goto out_free_mm; |
1340 | } | 1287 | } |
1341 | 1288 | ||
1342 | /* By now we should be all set, any drm_mmap request on the offset | ||
1343 | * below will get to our mmap & fault handler */ | ||
1344 | obj_priv->mmap_offset = ((uint64_t) list->hash.key) << PAGE_SHIFT; | ||
1345 | |||
1346 | return 0; | 1289 | return 0; |
1347 | 1290 | ||
1348 | out_free_mm: | 1291 | out_free_mm: |
1349 | drm_mm_put_block(list->file_offset_node); | 1292 | drm_mm_put_block(list->file_offset_node); |
1350 | out_free_list: | 1293 | out_free_list: |
1351 | kfree(list->map); | 1294 | kfree(list->map); |
1295 | list->map = NULL; | ||
1352 | 1296 | ||
1353 | return ret; | 1297 | return ret; |
1354 | } | 1298 | } |
@@ -1368,38 +1312,51 @@ out_free_list: | |||
1368 | * fixup by i915_gem_fault(). | 1312 | * fixup by i915_gem_fault(). |
1369 | */ | 1313 | */ |
1370 | void | 1314 | void |
1371 | i915_gem_release_mmap(struct drm_gem_object *obj) | 1315 | i915_gem_release_mmap(struct drm_i915_gem_object *obj) |
1372 | { | 1316 | { |
1373 | struct drm_device *dev = obj->dev; | 1317 | if (!obj->fault_mappable) |
1374 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 1318 | return; |
1319 | |||
1320 | unmap_mapping_range(obj->base.dev->dev_mapping, | ||
1321 | (loff_t)obj->base.map_list.hash.key<<PAGE_SHIFT, | ||
1322 | obj->base.size, 1); | ||
1375 | 1323 | ||
1376 | if (dev->dev_mapping) | 1324 | obj->fault_mappable = false; |
1377 | unmap_mapping_range(dev->dev_mapping, | ||
1378 | obj_priv->mmap_offset, obj->size, 1); | ||
1379 | } | 1325 | } |
1380 | 1326 | ||
1381 | static void | 1327 | static void |
1382 | i915_gem_free_mmap_offset(struct drm_gem_object *obj) | 1328 | i915_gem_free_mmap_offset(struct drm_i915_gem_object *obj) |
1383 | { | 1329 | { |
1384 | struct drm_device *dev = obj->dev; | 1330 | struct drm_device *dev = obj->base.dev; |
1385 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
1386 | struct drm_gem_mm *mm = dev->mm_private; | 1331 | struct drm_gem_mm *mm = dev->mm_private; |
1387 | struct drm_map_list *list; | 1332 | struct drm_map_list *list = &obj->base.map_list; |
1388 | 1333 | ||
1389 | list = &obj->map_list; | ||
1390 | drm_ht_remove_item(&mm->offset_hash, &list->hash); | 1334 | drm_ht_remove_item(&mm->offset_hash, &list->hash); |
1335 | drm_mm_put_block(list->file_offset_node); | ||
1336 | kfree(list->map); | ||
1337 | list->map = NULL; | ||
1338 | } | ||
1391 | 1339 | ||
1392 | if (list->file_offset_node) { | 1340 | static uint32_t |
1393 | drm_mm_put_block(list->file_offset_node); | 1341 | i915_gem_get_gtt_size(struct drm_i915_gem_object *obj) |
1394 | list->file_offset_node = NULL; | 1342 | { |
1395 | } | 1343 | struct drm_device *dev = obj->base.dev; |
1344 | uint32_t size; | ||
1396 | 1345 | ||
1397 | if (list->map) { | 1346 | if (INTEL_INFO(dev)->gen >= 4 || |
1398 | kfree(list->map); | 1347 | obj->tiling_mode == I915_TILING_NONE) |
1399 | list->map = NULL; | 1348 | return obj->base.size; |
1400 | } | ||
1401 | 1349 | ||
1402 | obj_priv->mmap_offset = 0; | 1350 | /* Previous chips need a power-of-two fence region when tiling */ |
1351 | if (INTEL_INFO(dev)->gen == 3) | ||
1352 | size = 1024*1024; | ||
1353 | else | ||
1354 | size = 512*1024; | ||
1355 | |||
1356 | while (size < obj->base.size) | ||
1357 | size <<= 1; | ||
1358 | |||
1359 | return size; | ||
1403 | } | 1360 | } |
1404 | 1361 | ||
1405 | /** | 1362 | /** |
@@ -1407,42 +1364,68 @@ i915_gem_free_mmap_offset(struct drm_gem_object *obj) | |||
1407 | * @obj: object to check | 1364 | * @obj: object to check |
1408 | * | 1365 | * |
1409 | * Return the required GTT alignment for an object, taking into account | 1366 | * Return the required GTT alignment for an object, taking into account |
1410 | * potential fence register mapping if needed. | 1367 | * potential fence register mapping. |
1411 | */ | 1368 | */ |
1412 | static uint32_t | 1369 | static uint32_t |
1413 | i915_gem_get_gtt_alignment(struct drm_gem_object *obj) | 1370 | i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj) |
1414 | { | 1371 | { |
1415 | struct drm_device *dev = obj->dev; | 1372 | struct drm_device *dev = obj->base.dev; |
1416 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
1417 | int start, i; | ||
1418 | 1373 | ||
1419 | /* | 1374 | /* |
1420 | * Minimum alignment is 4k (GTT page size), but might be greater | 1375 | * Minimum alignment is 4k (GTT page size), but might be greater |
1421 | * if a fence register is needed for the object. | 1376 | * if a fence register is needed for the object. |
1422 | */ | 1377 | */ |
1423 | if (INTEL_INFO(dev)->gen >= 4 || obj_priv->tiling_mode == I915_TILING_NONE) | 1378 | if (INTEL_INFO(dev)->gen >= 4 || |
1379 | obj->tiling_mode == I915_TILING_NONE) | ||
1424 | return 4096; | 1380 | return 4096; |
1425 | 1381 | ||
1426 | /* | 1382 | /* |
1427 | * Previous chips need to be aligned to the size of the smallest | 1383 | * Previous chips need to be aligned to the size of the smallest |
1428 | * fence register that can contain the object. | 1384 | * fence register that can contain the object. |
1429 | */ | 1385 | */ |
1430 | if (INTEL_INFO(dev)->gen == 3) | 1386 | return i915_gem_get_gtt_size(obj); |
1431 | start = 1024*1024; | 1387 | } |
1432 | else | ||
1433 | start = 512*1024; | ||
1434 | 1388 | ||
1435 | for (i = start; i < obj->size; i <<= 1) | 1389 | /** |
1436 | ; | 1390 | * i915_gem_get_unfenced_gtt_alignment - return required GTT alignment for an |
1391 | * unfenced object | ||
1392 | * @obj: object to check | ||
1393 | * | ||
1394 | * Return the required GTT alignment for an object, only taking into account | ||
1395 | * unfenced tiled surface requirements. | ||
1396 | */ | ||
1397 | static uint32_t | ||
1398 | i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj) | ||
1399 | { | ||
1400 | struct drm_device *dev = obj->base.dev; | ||
1401 | int tile_height; | ||
1402 | |||
1403 | /* | ||
1404 | * Minimum alignment is 4k (GTT page size) for sane hw. | ||
1405 | */ | ||
1406 | if (INTEL_INFO(dev)->gen >= 4 || IS_G33(dev) || | ||
1407 | obj->tiling_mode == I915_TILING_NONE) | ||
1408 | return 4096; | ||
1409 | |||
1410 | /* | ||
1411 | * Older chips need unfenced tiled buffers to be aligned to the left | ||
1412 | * edge of an even tile row (where tile rows are counted as if the bo is | ||
1413 | * placed in a fenced gtt region). | ||
1414 | */ | ||
1415 | if (IS_GEN2(dev) || | ||
1416 | (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) | ||
1417 | tile_height = 32; | ||
1418 | else | ||
1419 | tile_height = 8; | ||
1437 | 1420 | ||
1438 | return i; | 1421 | return tile_height * obj->stride * 2; |
1439 | } | 1422 | } |
1440 | 1423 | ||
1441 | /** | 1424 | /** |
1442 | * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing | 1425 | * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing |
1443 | * @dev: DRM device | 1426 | * @dev: DRM device |
1444 | * @data: GTT mapping ioctl data | 1427 | * @data: GTT mapping ioctl data |
1445 | * @file_priv: GEM object info | 1428 | * @file: GEM object info |
1446 | * | 1429 | * |
1447 | * Simply returns the fake offset to userspace so it can mmap it. | 1430 | * Simply returns the fake offset to userspace so it can mmap it. |
1448 | * The mmap call will end up in drm_gem_mmap(), which will set things | 1431 | * The mmap call will end up in drm_gem_mmap(), which will set things |
@@ -1455,11 +1438,11 @@ i915_gem_get_gtt_alignment(struct drm_gem_object *obj) | |||
1455 | */ | 1438 | */ |
1456 | int | 1439 | int |
1457 | i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | 1440 | i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, |
1458 | struct drm_file *file_priv) | 1441 | struct drm_file *file) |
1459 | { | 1442 | { |
1443 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1460 | struct drm_i915_gem_mmap_gtt *args = data; | 1444 | struct drm_i915_gem_mmap_gtt *args = data; |
1461 | struct drm_gem_object *obj; | 1445 | struct drm_i915_gem_object *obj; |
1462 | struct drm_i915_gem_object *obj_priv; | ||
1463 | int ret; | 1446 | int ret; |
1464 | 1447 | ||
1465 | if (!(dev->driver->driver_features & DRIVER_GEM)) | 1448 | if (!(dev->driver->driver_features & DRIVER_GEM)) |
@@ -1469,130 +1452,196 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | |||
1469 | if (ret) | 1452 | if (ret) |
1470 | return ret; | 1453 | return ret; |
1471 | 1454 | ||
1472 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 1455 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); |
1473 | if (obj == NULL) { | 1456 | if (obj == NULL) { |
1474 | ret = -ENOENT; | 1457 | ret = -ENOENT; |
1475 | goto unlock; | 1458 | goto unlock; |
1476 | } | 1459 | } |
1477 | obj_priv = to_intel_bo(obj); | ||
1478 | 1460 | ||
1479 | if (obj_priv->madv != I915_MADV_WILLNEED) { | 1461 | if (obj->base.size > dev_priv->mm.gtt_mappable_end) { |
1462 | ret = -E2BIG; | ||
1463 | goto unlock; | ||
1464 | } | ||
1465 | |||
1466 | if (obj->madv != I915_MADV_WILLNEED) { | ||
1480 | DRM_ERROR("Attempting to mmap a purgeable buffer\n"); | 1467 | DRM_ERROR("Attempting to mmap a purgeable buffer\n"); |
1481 | ret = -EINVAL; | 1468 | ret = -EINVAL; |
1482 | goto out; | 1469 | goto out; |
1483 | } | 1470 | } |
1484 | 1471 | ||
1485 | if (!obj_priv->mmap_offset) { | 1472 | if (!obj->base.map_list.map) { |
1486 | ret = i915_gem_create_mmap_offset(obj); | 1473 | ret = i915_gem_create_mmap_offset(obj); |
1487 | if (ret) | 1474 | if (ret) |
1488 | goto out; | 1475 | goto out; |
1489 | } | 1476 | } |
1490 | 1477 | ||
1491 | args->offset = obj_priv->mmap_offset; | 1478 | args->offset = (u64)obj->base.map_list.hash.key << PAGE_SHIFT; |
1492 | |||
1493 | /* | ||
1494 | * Pull it into the GTT so that we have a page list (makes the | ||
1495 | * initial fault faster and any subsequent flushing possible). | ||
1496 | */ | ||
1497 | if (!obj_priv->agp_mem) { | ||
1498 | ret = i915_gem_object_bind_to_gtt(obj, 0); | ||
1499 | if (ret) | ||
1500 | goto out; | ||
1501 | } | ||
1502 | 1479 | ||
1503 | out: | 1480 | out: |
1504 | drm_gem_object_unreference(obj); | 1481 | drm_gem_object_unreference(&obj->base); |
1505 | unlock: | 1482 | unlock: |
1506 | mutex_unlock(&dev->struct_mutex); | 1483 | mutex_unlock(&dev->struct_mutex); |
1507 | return ret; | 1484 | return ret; |
1508 | } | 1485 | } |
1509 | 1486 | ||
1487 | static int | ||
1488 | i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, | ||
1489 | gfp_t gfpmask) | ||
1490 | { | ||
1491 | int page_count, i; | ||
1492 | struct address_space *mapping; | ||
1493 | struct inode *inode; | ||
1494 | struct page *page; | ||
1495 | |||
1496 | /* Get the list of pages out of our struct file. They'll be pinned | ||
1497 | * at this point until we release them. | ||
1498 | */ | ||
1499 | page_count = obj->base.size / PAGE_SIZE; | ||
1500 | BUG_ON(obj->pages != NULL); | ||
1501 | obj->pages = drm_malloc_ab(page_count, sizeof(struct page *)); | ||
1502 | if (obj->pages == NULL) | ||
1503 | return -ENOMEM; | ||
1504 | |||
1505 | inode = obj->base.filp->f_path.dentry->d_inode; | ||
1506 | mapping = inode->i_mapping; | ||
1507 | for (i = 0; i < page_count; i++) { | ||
1508 | page = read_cache_page_gfp(mapping, i, | ||
1509 | GFP_HIGHUSER | | ||
1510 | __GFP_COLD | | ||
1511 | __GFP_RECLAIMABLE | | ||
1512 | gfpmask); | ||
1513 | if (IS_ERR(page)) | ||
1514 | goto err_pages; | ||
1515 | |||
1516 | obj->pages[i] = page; | ||
1517 | } | ||
1518 | |||
1519 | if (obj->tiling_mode != I915_TILING_NONE) | ||
1520 | i915_gem_object_do_bit_17_swizzle(obj); | ||
1521 | |||
1522 | return 0; | ||
1523 | |||
1524 | err_pages: | ||
1525 | while (i--) | ||
1526 | page_cache_release(obj->pages[i]); | ||
1527 | |||
1528 | drm_free_large(obj->pages); | ||
1529 | obj->pages = NULL; | ||
1530 | return PTR_ERR(page); | ||
1531 | } | ||
1532 | |||
1510 | static void | 1533 | static void |
1511 | i915_gem_object_put_pages(struct drm_gem_object *obj) | 1534 | i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) |
1512 | { | 1535 | { |
1513 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 1536 | int page_count = obj->base.size / PAGE_SIZE; |
1514 | int page_count = obj->size / PAGE_SIZE; | ||
1515 | int i; | 1537 | int i; |
1516 | 1538 | ||
1517 | BUG_ON(obj_priv->pages_refcount == 0); | 1539 | BUG_ON(obj->madv == __I915_MADV_PURGED); |
1518 | BUG_ON(obj_priv->madv == __I915_MADV_PURGED); | ||
1519 | 1540 | ||
1520 | if (--obj_priv->pages_refcount != 0) | 1541 | if (obj->tiling_mode != I915_TILING_NONE) |
1521 | return; | ||
1522 | |||
1523 | if (obj_priv->tiling_mode != I915_TILING_NONE) | ||
1524 | i915_gem_object_save_bit_17_swizzle(obj); | 1542 | i915_gem_object_save_bit_17_swizzle(obj); |
1525 | 1543 | ||
1526 | if (obj_priv->madv == I915_MADV_DONTNEED) | 1544 | if (obj->madv == I915_MADV_DONTNEED) |
1527 | obj_priv->dirty = 0; | 1545 | obj->dirty = 0; |
1528 | 1546 | ||
1529 | for (i = 0; i < page_count; i++) { | 1547 | for (i = 0; i < page_count; i++) { |
1530 | if (obj_priv->dirty) | 1548 | if (obj->dirty) |
1531 | set_page_dirty(obj_priv->pages[i]); | 1549 | set_page_dirty(obj->pages[i]); |
1532 | 1550 | ||
1533 | if (obj_priv->madv == I915_MADV_WILLNEED) | 1551 | if (obj->madv == I915_MADV_WILLNEED) |
1534 | mark_page_accessed(obj_priv->pages[i]); | 1552 | mark_page_accessed(obj->pages[i]); |
1535 | 1553 | ||
1536 | page_cache_release(obj_priv->pages[i]); | 1554 | page_cache_release(obj->pages[i]); |
1537 | } | 1555 | } |
1538 | obj_priv->dirty = 0; | 1556 | obj->dirty = 0; |
1539 | |||
1540 | drm_free_large(obj_priv->pages); | ||
1541 | obj_priv->pages = NULL; | ||
1542 | } | ||
1543 | |||
1544 | static uint32_t | ||
1545 | i915_gem_next_request_seqno(struct drm_device *dev, | ||
1546 | struct intel_ring_buffer *ring) | ||
1547 | { | ||
1548 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1549 | 1557 | ||
1550 | ring->outstanding_lazy_request = true; | 1558 | drm_free_large(obj->pages); |
1551 | return dev_priv->next_seqno; | 1559 | obj->pages = NULL; |
1552 | } | 1560 | } |
1553 | 1561 | ||
1554 | static void | 1562 | void |
1555 | i915_gem_object_move_to_active(struct drm_gem_object *obj, | 1563 | i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, |
1556 | struct intel_ring_buffer *ring) | 1564 | struct intel_ring_buffer *ring, |
1565 | u32 seqno) | ||
1557 | { | 1566 | { |
1558 | struct drm_device *dev = obj->dev; | 1567 | struct drm_device *dev = obj->base.dev; |
1559 | struct drm_i915_private *dev_priv = dev->dev_private; | 1568 | struct drm_i915_private *dev_priv = dev->dev_private; |
1560 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
1561 | uint32_t seqno = i915_gem_next_request_seqno(dev, ring); | ||
1562 | 1569 | ||
1563 | BUG_ON(ring == NULL); | 1570 | BUG_ON(ring == NULL); |
1564 | obj_priv->ring = ring; | 1571 | obj->ring = ring; |
1565 | 1572 | ||
1566 | /* Add a reference if we're newly entering the active list. */ | 1573 | /* Add a reference if we're newly entering the active list. */ |
1567 | if (!obj_priv->active) { | 1574 | if (!obj->active) { |
1568 | drm_gem_object_reference(obj); | 1575 | drm_gem_object_reference(&obj->base); |
1569 | obj_priv->active = 1; | 1576 | obj->active = 1; |
1570 | } | 1577 | } |
1571 | 1578 | ||
1572 | /* Move from whatever list we were on to the tail of execution. */ | 1579 | /* Move from whatever list we were on to the tail of execution. */ |
1573 | list_move_tail(&obj_priv->mm_list, &dev_priv->mm.active_list); | 1580 | list_move_tail(&obj->mm_list, &dev_priv->mm.active_list); |
1574 | list_move_tail(&obj_priv->ring_list, &ring->active_list); | 1581 | list_move_tail(&obj->ring_list, &ring->active_list); |
1575 | obj_priv->last_rendering_seqno = seqno; | 1582 | |
1583 | obj->last_rendering_seqno = seqno; | ||
1584 | if (obj->fenced_gpu_access) { | ||
1585 | struct drm_i915_fence_reg *reg; | ||
1586 | |||
1587 | BUG_ON(obj->fence_reg == I915_FENCE_REG_NONE); | ||
1588 | |||
1589 | obj->last_fenced_seqno = seqno; | ||
1590 | obj->last_fenced_ring = ring; | ||
1591 | |||
1592 | reg = &dev_priv->fence_regs[obj->fence_reg]; | ||
1593 | list_move_tail(®->lru_list, &dev_priv->mm.fence_list); | ||
1594 | } | ||
1595 | } | ||
1596 | |||
1597 | static void | ||
1598 | i915_gem_object_move_off_active(struct drm_i915_gem_object *obj) | ||
1599 | { | ||
1600 | list_del_init(&obj->ring_list); | ||
1601 | obj->last_rendering_seqno = 0; | ||
1576 | } | 1602 | } |
1577 | 1603 | ||
1578 | static void | 1604 | static void |
1579 | i915_gem_object_move_to_flushing(struct drm_gem_object *obj) | 1605 | i915_gem_object_move_to_flushing(struct drm_i915_gem_object *obj) |
1580 | { | 1606 | { |
1581 | struct drm_device *dev = obj->dev; | 1607 | struct drm_device *dev = obj->base.dev; |
1582 | drm_i915_private_t *dev_priv = dev->dev_private; | 1608 | drm_i915_private_t *dev_priv = dev->dev_private; |
1583 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
1584 | 1609 | ||
1585 | BUG_ON(!obj_priv->active); | 1610 | BUG_ON(!obj->active); |
1586 | list_move_tail(&obj_priv->mm_list, &dev_priv->mm.flushing_list); | 1611 | list_move_tail(&obj->mm_list, &dev_priv->mm.flushing_list); |
1587 | list_del_init(&obj_priv->ring_list); | 1612 | |
1588 | obj_priv->last_rendering_seqno = 0; | 1613 | i915_gem_object_move_off_active(obj); |
1614 | } | ||
1615 | |||
1616 | static void | ||
1617 | i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) | ||
1618 | { | ||
1619 | struct drm_device *dev = obj->base.dev; | ||
1620 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1621 | |||
1622 | if (obj->pin_count != 0) | ||
1623 | list_move_tail(&obj->mm_list, &dev_priv->mm.pinned_list); | ||
1624 | else | ||
1625 | list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); | ||
1626 | |||
1627 | BUG_ON(!list_empty(&obj->gpu_write_list)); | ||
1628 | BUG_ON(!obj->active); | ||
1629 | obj->ring = NULL; | ||
1630 | |||
1631 | i915_gem_object_move_off_active(obj); | ||
1632 | obj->fenced_gpu_access = false; | ||
1633 | |||
1634 | obj->active = 0; | ||
1635 | obj->pending_gpu_write = false; | ||
1636 | drm_gem_object_unreference(&obj->base); | ||
1637 | |||
1638 | WARN_ON(i915_verify_lists(dev)); | ||
1589 | } | 1639 | } |
1590 | 1640 | ||
1591 | /* Immediately discard the backing storage */ | 1641 | /* Immediately discard the backing storage */ |
1592 | static void | 1642 | static void |
1593 | i915_gem_object_truncate(struct drm_gem_object *obj) | 1643 | i915_gem_object_truncate(struct drm_i915_gem_object *obj) |
1594 | { | 1644 | { |
1595 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
1596 | struct inode *inode; | 1645 | struct inode *inode; |
1597 | 1646 | ||
1598 | /* Our goal here is to return as much of the memory as | 1647 | /* Our goal here is to return as much of the memory as |
@@ -1601,42 +1650,18 @@ i915_gem_object_truncate(struct drm_gem_object *obj) | |||
1601 | * backing pages, *now*. Here we mirror the actions taken | 1650 | * backing pages, *now*. Here we mirror the actions taken |
1602 | * when by shmem_delete_inode() to release the backing store. | 1651 | * when by shmem_delete_inode() to release the backing store. |
1603 | */ | 1652 | */ |
1604 | inode = obj->filp->f_path.dentry->d_inode; | 1653 | inode = obj->base.filp->f_path.dentry->d_inode; |
1605 | truncate_inode_pages(inode->i_mapping, 0); | 1654 | truncate_inode_pages(inode->i_mapping, 0); |
1606 | if (inode->i_op->truncate_range) | 1655 | if (inode->i_op->truncate_range) |
1607 | inode->i_op->truncate_range(inode, 0, (loff_t)-1); | 1656 | inode->i_op->truncate_range(inode, 0, (loff_t)-1); |
1608 | 1657 | ||
1609 | obj_priv->madv = __I915_MADV_PURGED; | 1658 | obj->madv = __I915_MADV_PURGED; |
1610 | } | 1659 | } |
1611 | 1660 | ||
1612 | static inline int | 1661 | static inline int |
1613 | i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj_priv) | 1662 | i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj) |
1614 | { | ||
1615 | return obj_priv->madv == I915_MADV_DONTNEED; | ||
1616 | } | ||
1617 | |||
1618 | static void | ||
1619 | i915_gem_object_move_to_inactive(struct drm_gem_object *obj) | ||
1620 | { | 1663 | { |
1621 | struct drm_device *dev = obj->dev; | 1664 | return obj->madv == I915_MADV_DONTNEED; |
1622 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1623 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
1624 | |||
1625 | if (obj_priv->pin_count != 0) | ||
1626 | list_move_tail(&obj_priv->mm_list, &dev_priv->mm.pinned_list); | ||
1627 | else | ||
1628 | list_move_tail(&obj_priv->mm_list, &dev_priv->mm.inactive_list); | ||
1629 | list_del_init(&obj_priv->ring_list); | ||
1630 | |||
1631 | BUG_ON(!list_empty(&obj_priv->gpu_write_list)); | ||
1632 | |||
1633 | obj_priv->last_rendering_seqno = 0; | ||
1634 | obj_priv->ring = NULL; | ||
1635 | if (obj_priv->active) { | ||
1636 | obj_priv->active = 0; | ||
1637 | drm_gem_object_unreference(obj); | ||
1638 | } | ||
1639 | WARN_ON(i915_verify_lists(dev)); | ||
1640 | } | 1665 | } |
1641 | 1666 | ||
1642 | static void | 1667 | static void |
@@ -1644,37 +1669,27 @@ i915_gem_process_flushing_list(struct drm_device *dev, | |||
1644 | uint32_t flush_domains, | 1669 | uint32_t flush_domains, |
1645 | struct intel_ring_buffer *ring) | 1670 | struct intel_ring_buffer *ring) |
1646 | { | 1671 | { |
1647 | drm_i915_private_t *dev_priv = dev->dev_private; | 1672 | struct drm_i915_gem_object *obj, *next; |
1648 | struct drm_i915_gem_object *obj_priv, *next; | ||
1649 | 1673 | ||
1650 | list_for_each_entry_safe(obj_priv, next, | 1674 | list_for_each_entry_safe(obj, next, |
1651 | &ring->gpu_write_list, | 1675 | &ring->gpu_write_list, |
1652 | gpu_write_list) { | 1676 | gpu_write_list) { |
1653 | struct drm_gem_object *obj = &obj_priv->base; | 1677 | if (obj->base.write_domain & flush_domains) { |
1654 | 1678 | uint32_t old_write_domain = obj->base.write_domain; | |
1655 | if (obj->write_domain & flush_domains) { | ||
1656 | uint32_t old_write_domain = obj->write_domain; | ||
1657 | 1679 | ||
1658 | obj->write_domain = 0; | 1680 | obj->base.write_domain = 0; |
1659 | list_del_init(&obj_priv->gpu_write_list); | 1681 | list_del_init(&obj->gpu_write_list); |
1660 | i915_gem_object_move_to_active(obj, ring); | 1682 | i915_gem_object_move_to_active(obj, ring, |
1661 | 1683 | i915_gem_next_request_seqno(dev, ring)); | |
1662 | /* update the fence lru list */ | ||
1663 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { | ||
1664 | struct drm_i915_fence_reg *reg = | ||
1665 | &dev_priv->fence_regs[obj_priv->fence_reg]; | ||
1666 | list_move_tail(®->lru_list, | ||
1667 | &dev_priv->mm.fence_list); | ||
1668 | } | ||
1669 | 1684 | ||
1670 | trace_i915_gem_object_change_domain(obj, | 1685 | trace_i915_gem_object_change_domain(obj, |
1671 | obj->read_domains, | 1686 | obj->base.read_domains, |
1672 | old_write_domain); | 1687 | old_write_domain); |
1673 | } | 1688 | } |
1674 | } | 1689 | } |
1675 | } | 1690 | } |
1676 | 1691 | ||
1677 | uint32_t | 1692 | int |
1678 | i915_add_request(struct drm_device *dev, | 1693 | i915_add_request(struct drm_device *dev, |
1679 | struct drm_file *file, | 1694 | struct drm_file *file, |
1680 | struct drm_i915_gem_request *request, | 1695 | struct drm_i915_gem_request *request, |
@@ -1684,17 +1699,17 @@ i915_add_request(struct drm_device *dev, | |||
1684 | struct drm_i915_file_private *file_priv = NULL; | 1699 | struct drm_i915_file_private *file_priv = NULL; |
1685 | uint32_t seqno; | 1700 | uint32_t seqno; |
1686 | int was_empty; | 1701 | int was_empty; |
1702 | int ret; | ||
1703 | |||
1704 | BUG_ON(request == NULL); | ||
1687 | 1705 | ||
1688 | if (file != NULL) | 1706 | if (file != NULL) |
1689 | file_priv = file->driver_priv; | 1707 | file_priv = file->driver_priv; |
1690 | 1708 | ||
1691 | if (request == NULL) { | 1709 | ret = ring->add_request(ring, &seqno); |
1692 | request = kzalloc(sizeof(*request), GFP_KERNEL); | 1710 | if (ret) |
1693 | if (request == NULL) | 1711 | return ret; |
1694 | return 0; | ||
1695 | } | ||
1696 | 1712 | ||
1697 | seqno = ring->add_request(dev, ring, 0); | ||
1698 | ring->outstanding_lazy_request = false; | 1713 | ring->outstanding_lazy_request = false; |
1699 | 1714 | ||
1700 | request->seqno = seqno; | 1715 | request->seqno = seqno; |
@@ -1718,26 +1733,7 @@ i915_add_request(struct drm_device *dev, | |||
1718 | queue_delayed_work(dev_priv->wq, | 1733 | queue_delayed_work(dev_priv->wq, |
1719 | &dev_priv->mm.retire_work, HZ); | 1734 | &dev_priv->mm.retire_work, HZ); |
1720 | } | 1735 | } |
1721 | return seqno; | 1736 | return 0; |
1722 | } | ||
1723 | |||
1724 | /** | ||
1725 | * Command execution barrier | ||
1726 | * | ||
1727 | * Ensures that all commands in the ring are finished | ||
1728 | * before signalling the CPU | ||
1729 | */ | ||
1730 | static void | ||
1731 | i915_retire_commands(struct drm_device *dev, struct intel_ring_buffer *ring) | ||
1732 | { | ||
1733 | uint32_t flush_domains = 0; | ||
1734 | |||
1735 | /* The sampler always gets flushed on i965 (sigh) */ | ||
1736 | if (INTEL_INFO(dev)->gen >= 4) | ||
1737 | flush_domains |= I915_GEM_DOMAIN_SAMPLER; | ||
1738 | |||
1739 | ring->flush(dev, ring, | ||
1740 | I915_GEM_DOMAIN_COMMAND, flush_domains); | ||
1741 | } | 1737 | } |
1742 | 1738 | ||
1743 | static inline void | 1739 | static inline void |
@@ -1770,62 +1766,76 @@ static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, | |||
1770 | } | 1766 | } |
1771 | 1767 | ||
1772 | while (!list_empty(&ring->active_list)) { | 1768 | while (!list_empty(&ring->active_list)) { |
1773 | struct drm_i915_gem_object *obj_priv; | 1769 | struct drm_i915_gem_object *obj; |
1774 | 1770 | ||
1775 | obj_priv = list_first_entry(&ring->active_list, | 1771 | obj = list_first_entry(&ring->active_list, |
1776 | struct drm_i915_gem_object, | 1772 | struct drm_i915_gem_object, |
1777 | ring_list); | 1773 | ring_list); |
1778 | 1774 | ||
1779 | obj_priv->base.write_domain = 0; | 1775 | obj->base.write_domain = 0; |
1780 | list_del_init(&obj_priv->gpu_write_list); | 1776 | list_del_init(&obj->gpu_write_list); |
1781 | i915_gem_object_move_to_inactive(&obj_priv->base); | 1777 | i915_gem_object_move_to_inactive(obj); |
1778 | } | ||
1779 | } | ||
1780 | |||
1781 | static void i915_gem_reset_fences(struct drm_device *dev) | ||
1782 | { | ||
1783 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1784 | int i; | ||
1785 | |||
1786 | for (i = 0; i < 16; i++) { | ||
1787 | struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; | ||
1788 | struct drm_i915_gem_object *obj = reg->obj; | ||
1789 | |||
1790 | if (!obj) | ||
1791 | continue; | ||
1792 | |||
1793 | if (obj->tiling_mode) | ||
1794 | i915_gem_release_mmap(obj); | ||
1795 | |||
1796 | reg->obj->fence_reg = I915_FENCE_REG_NONE; | ||
1797 | reg->obj->fenced_gpu_access = false; | ||
1798 | reg->obj->last_fenced_seqno = 0; | ||
1799 | reg->obj->last_fenced_ring = NULL; | ||
1800 | i915_gem_clear_fence_reg(dev, reg); | ||
1782 | } | 1801 | } |
1783 | } | 1802 | } |
1784 | 1803 | ||
1785 | void i915_gem_reset(struct drm_device *dev) | 1804 | void i915_gem_reset(struct drm_device *dev) |
1786 | { | 1805 | { |
1787 | struct drm_i915_private *dev_priv = dev->dev_private; | 1806 | struct drm_i915_private *dev_priv = dev->dev_private; |
1788 | struct drm_i915_gem_object *obj_priv; | 1807 | struct drm_i915_gem_object *obj; |
1789 | int i; | 1808 | int i; |
1790 | 1809 | ||
1791 | i915_gem_reset_ring_lists(dev_priv, &dev_priv->render_ring); | 1810 | for (i = 0; i < I915_NUM_RINGS; i++) |
1792 | i915_gem_reset_ring_lists(dev_priv, &dev_priv->bsd_ring); | 1811 | i915_gem_reset_ring_lists(dev_priv, &dev_priv->ring[i]); |
1793 | i915_gem_reset_ring_lists(dev_priv, &dev_priv->blt_ring); | ||
1794 | 1812 | ||
1795 | /* Remove anything from the flushing lists. The GPU cache is likely | 1813 | /* Remove anything from the flushing lists. The GPU cache is likely |
1796 | * to be lost on reset along with the data, so simply move the | 1814 | * to be lost on reset along with the data, so simply move the |
1797 | * lost bo to the inactive list. | 1815 | * lost bo to the inactive list. |
1798 | */ | 1816 | */ |
1799 | while (!list_empty(&dev_priv->mm.flushing_list)) { | 1817 | while (!list_empty(&dev_priv->mm.flushing_list)) { |
1800 | obj_priv = list_first_entry(&dev_priv->mm.flushing_list, | 1818 | obj= list_first_entry(&dev_priv->mm.flushing_list, |
1801 | struct drm_i915_gem_object, | 1819 | struct drm_i915_gem_object, |
1802 | mm_list); | 1820 | mm_list); |
1803 | 1821 | ||
1804 | obj_priv->base.write_domain = 0; | 1822 | obj->base.write_domain = 0; |
1805 | list_del_init(&obj_priv->gpu_write_list); | 1823 | list_del_init(&obj->gpu_write_list); |
1806 | i915_gem_object_move_to_inactive(&obj_priv->base); | 1824 | i915_gem_object_move_to_inactive(obj); |
1807 | } | 1825 | } |
1808 | 1826 | ||
1809 | /* Move everything out of the GPU domains to ensure we do any | 1827 | /* Move everything out of the GPU domains to ensure we do any |
1810 | * necessary invalidation upon reuse. | 1828 | * necessary invalidation upon reuse. |
1811 | */ | 1829 | */ |
1812 | list_for_each_entry(obj_priv, | 1830 | list_for_each_entry(obj, |
1813 | &dev_priv->mm.inactive_list, | 1831 | &dev_priv->mm.inactive_list, |
1814 | mm_list) | 1832 | mm_list) |
1815 | { | 1833 | { |
1816 | obj_priv->base.read_domains &= ~I915_GEM_GPU_DOMAINS; | 1834 | obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS; |
1817 | } | 1835 | } |
1818 | 1836 | ||
1819 | /* The fence registers are invalidated so clear them out */ | 1837 | /* The fence registers are invalidated so clear them out */ |
1820 | for (i = 0; i < 16; i++) { | 1838 | i915_gem_reset_fences(dev); |
1821 | struct drm_i915_fence_reg *reg; | ||
1822 | |||
1823 | reg = &dev_priv->fence_regs[i]; | ||
1824 | if (!reg->obj) | ||
1825 | continue; | ||
1826 | |||
1827 | i915_gem_clear_fence_reg(reg->obj); | ||
1828 | } | ||
1829 | } | 1839 | } |
1830 | 1840 | ||
1831 | /** | 1841 | /** |
@@ -1837,6 +1847,7 @@ i915_gem_retire_requests_ring(struct drm_device *dev, | |||
1837 | { | 1847 | { |
1838 | drm_i915_private_t *dev_priv = dev->dev_private; | 1848 | drm_i915_private_t *dev_priv = dev->dev_private; |
1839 | uint32_t seqno; | 1849 | uint32_t seqno; |
1850 | int i; | ||
1840 | 1851 | ||
1841 | if (!ring->status_page.page_addr || | 1852 | if (!ring->status_page.page_addr || |
1842 | list_empty(&ring->request_list)) | 1853 | list_empty(&ring->request_list)) |
@@ -1844,7 +1855,12 @@ i915_gem_retire_requests_ring(struct drm_device *dev, | |||
1844 | 1855 | ||
1845 | WARN_ON(i915_verify_lists(dev)); | 1856 | WARN_ON(i915_verify_lists(dev)); |
1846 | 1857 | ||
1847 | seqno = ring->get_seqno(dev, ring); | 1858 | seqno = ring->get_seqno(ring); |
1859 | |||
1860 | for (i = 0; i < I915_NUM_RINGS; i++) | ||
1861 | if (seqno >= ring->sync_seqno[i]) | ||
1862 | ring->sync_seqno[i] = 0; | ||
1863 | |||
1848 | while (!list_empty(&ring->request_list)) { | 1864 | while (!list_empty(&ring->request_list)) { |
1849 | struct drm_i915_gem_request *request; | 1865 | struct drm_i915_gem_request *request; |
1850 | 1866 | ||
@@ -1866,18 +1882,16 @@ i915_gem_retire_requests_ring(struct drm_device *dev, | |||
1866 | * by the ringbuffer to the flushing/inactive lists as appropriate. | 1882 | * by the ringbuffer to the flushing/inactive lists as appropriate. |
1867 | */ | 1883 | */ |
1868 | while (!list_empty(&ring->active_list)) { | 1884 | while (!list_empty(&ring->active_list)) { |
1869 | struct drm_gem_object *obj; | 1885 | struct drm_i915_gem_object *obj; |
1870 | struct drm_i915_gem_object *obj_priv; | ||
1871 | 1886 | ||
1872 | obj_priv = list_first_entry(&ring->active_list, | 1887 | obj= list_first_entry(&ring->active_list, |
1873 | struct drm_i915_gem_object, | 1888 | struct drm_i915_gem_object, |
1874 | ring_list); | 1889 | ring_list); |
1875 | 1890 | ||
1876 | if (!i915_seqno_passed(seqno, obj_priv->last_rendering_seqno)) | 1891 | if (!i915_seqno_passed(seqno, obj->last_rendering_seqno)) |
1877 | break; | 1892 | break; |
1878 | 1893 | ||
1879 | obj = &obj_priv->base; | 1894 | if (obj->base.write_domain != 0) |
1880 | if (obj->write_domain != 0) | ||
1881 | i915_gem_object_move_to_flushing(obj); | 1895 | i915_gem_object_move_to_flushing(obj); |
1882 | else | 1896 | else |
1883 | i915_gem_object_move_to_inactive(obj); | 1897 | i915_gem_object_move_to_inactive(obj); |
@@ -1885,7 +1899,7 @@ i915_gem_retire_requests_ring(struct drm_device *dev, | |||
1885 | 1899 | ||
1886 | if (unlikely (dev_priv->trace_irq_seqno && | 1900 | if (unlikely (dev_priv->trace_irq_seqno && |
1887 | i915_seqno_passed(dev_priv->trace_irq_seqno, seqno))) { | 1901 | i915_seqno_passed(dev_priv->trace_irq_seqno, seqno))) { |
1888 | ring->user_irq_put(dev, ring); | 1902 | ring->irq_put(ring); |
1889 | dev_priv->trace_irq_seqno = 0; | 1903 | dev_priv->trace_irq_seqno = 0; |
1890 | } | 1904 | } |
1891 | 1905 | ||
@@ -1896,24 +1910,24 @@ void | |||
1896 | i915_gem_retire_requests(struct drm_device *dev) | 1910 | i915_gem_retire_requests(struct drm_device *dev) |
1897 | { | 1911 | { |
1898 | drm_i915_private_t *dev_priv = dev->dev_private; | 1912 | drm_i915_private_t *dev_priv = dev->dev_private; |
1913 | int i; | ||
1899 | 1914 | ||
1900 | if (!list_empty(&dev_priv->mm.deferred_free_list)) { | 1915 | if (!list_empty(&dev_priv->mm.deferred_free_list)) { |
1901 | struct drm_i915_gem_object *obj_priv, *tmp; | 1916 | struct drm_i915_gem_object *obj, *next; |
1902 | 1917 | ||
1903 | /* We must be careful that during unbind() we do not | 1918 | /* We must be careful that during unbind() we do not |
1904 | * accidentally infinitely recurse into retire requests. | 1919 | * accidentally infinitely recurse into retire requests. |
1905 | * Currently: | 1920 | * Currently: |
1906 | * retire -> free -> unbind -> wait -> retire_ring | 1921 | * retire -> free -> unbind -> wait -> retire_ring |
1907 | */ | 1922 | */ |
1908 | list_for_each_entry_safe(obj_priv, tmp, | 1923 | list_for_each_entry_safe(obj, next, |
1909 | &dev_priv->mm.deferred_free_list, | 1924 | &dev_priv->mm.deferred_free_list, |
1910 | mm_list) | 1925 | mm_list) |
1911 | i915_gem_free_object_tail(&obj_priv->base); | 1926 | i915_gem_free_object_tail(obj); |
1912 | } | 1927 | } |
1913 | 1928 | ||
1914 | i915_gem_retire_requests_ring(dev, &dev_priv->render_ring); | 1929 | for (i = 0; i < I915_NUM_RINGS; i++) |
1915 | i915_gem_retire_requests_ring(dev, &dev_priv->bsd_ring); | 1930 | i915_gem_retire_requests_ring(dev, &dev_priv->ring[i]); |
1916 | i915_gem_retire_requests_ring(dev, &dev_priv->blt_ring); | ||
1917 | } | 1931 | } |
1918 | 1932 | ||
1919 | static void | 1933 | static void |
@@ -1935,9 +1949,9 @@ i915_gem_retire_work_handler(struct work_struct *work) | |||
1935 | i915_gem_retire_requests(dev); | 1949 | i915_gem_retire_requests(dev); |
1936 | 1950 | ||
1937 | if (!dev_priv->mm.suspended && | 1951 | if (!dev_priv->mm.suspended && |
1938 | (!list_empty(&dev_priv->render_ring.request_list) || | 1952 | (!list_empty(&dev_priv->ring[RCS].request_list) || |
1939 | !list_empty(&dev_priv->bsd_ring.request_list) || | 1953 | !list_empty(&dev_priv->ring[VCS].request_list) || |
1940 | !list_empty(&dev_priv->blt_ring.request_list))) | 1954 | !list_empty(&dev_priv->ring[BCS].request_list))) |
1941 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); | 1955 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); |
1942 | mutex_unlock(&dev->struct_mutex); | 1956 | mutex_unlock(&dev->struct_mutex); |
1943 | } | 1957 | } |
@@ -1955,14 +1969,23 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, | |||
1955 | if (atomic_read(&dev_priv->mm.wedged)) | 1969 | if (atomic_read(&dev_priv->mm.wedged)) |
1956 | return -EAGAIN; | 1970 | return -EAGAIN; |
1957 | 1971 | ||
1958 | if (ring->outstanding_lazy_request) { | 1972 | if (seqno == ring->outstanding_lazy_request) { |
1959 | seqno = i915_add_request(dev, NULL, NULL, ring); | 1973 | struct drm_i915_gem_request *request; |
1960 | if (seqno == 0) | 1974 | |
1975 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
1976 | if (request == NULL) | ||
1961 | return -ENOMEM; | 1977 | return -ENOMEM; |
1978 | |||
1979 | ret = i915_add_request(dev, NULL, request, ring); | ||
1980 | if (ret) { | ||
1981 | kfree(request); | ||
1982 | return ret; | ||
1983 | } | ||
1984 | |||
1985 | seqno = request->seqno; | ||
1962 | } | 1986 | } |
1963 | BUG_ON(seqno == dev_priv->next_seqno); | ||
1964 | 1987 | ||
1965 | if (!i915_seqno_passed(ring->get_seqno(dev, ring), seqno)) { | 1988 | if (!i915_seqno_passed(ring->get_seqno(ring), seqno)) { |
1966 | if (HAS_PCH_SPLIT(dev)) | 1989 | if (HAS_PCH_SPLIT(dev)) |
1967 | ier = I915_READ(DEIER) | I915_READ(GTIER); | 1990 | ier = I915_READ(DEIER) | I915_READ(GTIER); |
1968 | else | 1991 | else |
@@ -1976,21 +1999,23 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, | |||
1976 | 1999 | ||
1977 | trace_i915_gem_request_wait_begin(dev, seqno); | 2000 | trace_i915_gem_request_wait_begin(dev, seqno); |
1978 | 2001 | ||
1979 | ring->waiting_gem_seqno = seqno; | 2002 | ring->waiting_seqno = seqno; |
1980 | ring->user_irq_get(dev, ring); | 2003 | if (ring->irq_get(ring)) { |
1981 | if (interruptible) | 2004 | if (interruptible) |
1982 | ret = wait_event_interruptible(ring->irq_queue, | 2005 | ret = wait_event_interruptible(ring->irq_queue, |
1983 | i915_seqno_passed( | 2006 | i915_seqno_passed(ring->get_seqno(ring), seqno) |
1984 | ring->get_seqno(dev, ring), seqno) | 2007 | || atomic_read(&dev_priv->mm.wedged)); |
1985 | || atomic_read(&dev_priv->mm.wedged)); | 2008 | else |
1986 | else | 2009 | wait_event(ring->irq_queue, |
1987 | wait_event(ring->irq_queue, | 2010 | i915_seqno_passed(ring->get_seqno(ring), seqno) |
1988 | i915_seqno_passed( | 2011 | || atomic_read(&dev_priv->mm.wedged)); |
1989 | ring->get_seqno(dev, ring), seqno) | ||
1990 | || atomic_read(&dev_priv->mm.wedged)); | ||
1991 | 2012 | ||
1992 | ring->user_irq_put(dev, ring); | 2013 | ring->irq_put(ring); |
1993 | ring->waiting_gem_seqno = 0; | 2014 | } else if (wait_for(i915_seqno_passed(ring->get_seqno(ring), |
2015 | seqno) || | ||
2016 | atomic_read(&dev_priv->mm.wedged), 3000)) | ||
2017 | ret = -EBUSY; | ||
2018 | ring->waiting_seqno = 0; | ||
1994 | 2019 | ||
1995 | trace_i915_gem_request_wait_end(dev, seqno); | 2020 | trace_i915_gem_request_wait_end(dev, seqno); |
1996 | } | 2021 | } |
@@ -1999,7 +2024,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, | |||
1999 | 2024 | ||
2000 | if (ret && ret != -ERESTARTSYS) | 2025 | if (ret && ret != -ERESTARTSYS) |
2001 | DRM_ERROR("%s returns %d (awaiting %d at %d, next %d)\n", | 2026 | DRM_ERROR("%s returns %d (awaiting %d at %d, next %d)\n", |
2002 | __func__, ret, seqno, ring->get_seqno(dev, ring), | 2027 | __func__, ret, seqno, ring->get_seqno(ring), |
2003 | dev_priv->next_seqno); | 2028 | dev_priv->next_seqno); |
2004 | 2029 | ||
2005 | /* Directly dispatch request retiring. While we have the work queue | 2030 | /* Directly dispatch request retiring. While we have the work queue |
@@ -2024,70 +2049,30 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno, | |||
2024 | return i915_do_wait_request(dev, seqno, 1, ring); | 2049 | return i915_do_wait_request(dev, seqno, 1, ring); |
2025 | } | 2050 | } |
2026 | 2051 | ||
2027 | static void | ||
2028 | i915_gem_flush_ring(struct drm_device *dev, | ||
2029 | struct drm_file *file_priv, | ||
2030 | struct intel_ring_buffer *ring, | ||
2031 | uint32_t invalidate_domains, | ||
2032 | uint32_t flush_domains) | ||
2033 | { | ||
2034 | ring->flush(dev, ring, invalidate_domains, flush_domains); | ||
2035 | i915_gem_process_flushing_list(dev, flush_domains, ring); | ||
2036 | } | ||
2037 | |||
2038 | static void | ||
2039 | i915_gem_flush(struct drm_device *dev, | ||
2040 | struct drm_file *file_priv, | ||
2041 | uint32_t invalidate_domains, | ||
2042 | uint32_t flush_domains, | ||
2043 | uint32_t flush_rings) | ||
2044 | { | ||
2045 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2046 | |||
2047 | if (flush_domains & I915_GEM_DOMAIN_CPU) | ||
2048 | drm_agp_chipset_flush(dev); | ||
2049 | |||
2050 | if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) { | ||
2051 | if (flush_rings & RING_RENDER) | ||
2052 | i915_gem_flush_ring(dev, file_priv, | ||
2053 | &dev_priv->render_ring, | ||
2054 | invalidate_domains, flush_domains); | ||
2055 | if (flush_rings & RING_BSD) | ||
2056 | i915_gem_flush_ring(dev, file_priv, | ||
2057 | &dev_priv->bsd_ring, | ||
2058 | invalidate_domains, flush_domains); | ||
2059 | if (flush_rings & RING_BLT) | ||
2060 | i915_gem_flush_ring(dev, file_priv, | ||
2061 | &dev_priv->blt_ring, | ||
2062 | invalidate_domains, flush_domains); | ||
2063 | } | ||
2064 | } | ||
2065 | |||
2066 | /** | 2052 | /** |
2067 | * Ensures that all rendering to the object has completed and the object is | 2053 | * Ensures that all rendering to the object has completed and the object is |
2068 | * safe to unbind from the GTT or access from the CPU. | 2054 | * safe to unbind from the GTT or access from the CPU. |
2069 | */ | 2055 | */ |
2070 | static int | 2056 | int |
2071 | i915_gem_object_wait_rendering(struct drm_gem_object *obj, | 2057 | i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, |
2072 | bool interruptible) | 2058 | bool interruptible) |
2073 | { | 2059 | { |
2074 | struct drm_device *dev = obj->dev; | 2060 | struct drm_device *dev = obj->base.dev; |
2075 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
2076 | int ret; | 2061 | int ret; |
2077 | 2062 | ||
2078 | /* This function only exists to support waiting for existing rendering, | 2063 | /* This function only exists to support waiting for existing rendering, |
2079 | * not for emitting required flushes. | 2064 | * not for emitting required flushes. |
2080 | */ | 2065 | */ |
2081 | BUG_ON((obj->write_domain & I915_GEM_GPU_DOMAINS) != 0); | 2066 | BUG_ON((obj->base.write_domain & I915_GEM_GPU_DOMAINS) != 0); |
2082 | 2067 | ||
2083 | /* If there is rendering queued on the buffer being evicted, wait for | 2068 | /* If there is rendering queued on the buffer being evicted, wait for |
2084 | * it. | 2069 | * it. |
2085 | */ | 2070 | */ |
2086 | if (obj_priv->active) { | 2071 | if (obj->active) { |
2087 | ret = i915_do_wait_request(dev, | 2072 | ret = i915_do_wait_request(dev, |
2088 | obj_priv->last_rendering_seqno, | 2073 | obj->last_rendering_seqno, |
2089 | interruptible, | 2074 | interruptible, |
2090 | obj_priv->ring); | 2075 | obj->ring); |
2091 | if (ret) | 2076 | if (ret) |
2092 | return ret; | 2077 | return ret; |
2093 | } | 2078 | } |
@@ -2099,17 +2084,14 @@ i915_gem_object_wait_rendering(struct drm_gem_object *obj, | |||
2099 | * Unbinds an object from the GTT aperture. | 2084 | * Unbinds an object from the GTT aperture. |
2100 | */ | 2085 | */ |
2101 | int | 2086 | int |
2102 | i915_gem_object_unbind(struct drm_gem_object *obj) | 2087 | i915_gem_object_unbind(struct drm_i915_gem_object *obj) |
2103 | { | 2088 | { |
2104 | struct drm_device *dev = obj->dev; | ||
2105 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2106 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
2107 | int ret = 0; | 2089 | int ret = 0; |
2108 | 2090 | ||
2109 | if (obj_priv->gtt_space == NULL) | 2091 | if (obj->gtt_space == NULL) |
2110 | return 0; | 2092 | return 0; |
2111 | 2093 | ||
2112 | if (obj_priv->pin_count != 0) { | 2094 | if (obj->pin_count != 0) { |
2113 | DRM_ERROR("Attempting to unbind pinned buffer\n"); | 2095 | DRM_ERROR("Attempting to unbind pinned buffer\n"); |
2114 | return -EINVAL; | 2096 | return -EINVAL; |
2115 | } | 2097 | } |
@@ -2132,27 +2114,27 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
2132 | */ | 2114 | */ |
2133 | if (ret) { | 2115 | if (ret) { |
2134 | i915_gem_clflush_object(obj); | 2116 | i915_gem_clflush_object(obj); |
2135 | obj->read_domains = obj->write_domain = I915_GEM_DOMAIN_CPU; | 2117 | obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU; |
2136 | } | 2118 | } |
2137 | 2119 | ||
2138 | /* release the fence reg _after_ flushing */ | 2120 | /* release the fence reg _after_ flushing */ |
2139 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 2121 | ret = i915_gem_object_put_fence(obj); |
2140 | i915_gem_clear_fence_reg(obj); | 2122 | if (ret == -ERESTARTSYS) |
2141 | 2123 | return ret; | |
2142 | drm_unbind_agp(obj_priv->agp_mem); | ||
2143 | drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); | ||
2144 | 2124 | ||
2145 | i915_gem_object_put_pages(obj); | 2125 | i915_gem_gtt_unbind_object(obj); |
2146 | BUG_ON(obj_priv->pages_refcount); | 2126 | i915_gem_object_put_pages_gtt(obj); |
2147 | 2127 | ||
2148 | i915_gem_info_remove_gtt(dev_priv, obj->size); | 2128 | list_del_init(&obj->gtt_list); |
2149 | list_del_init(&obj_priv->mm_list); | 2129 | list_del_init(&obj->mm_list); |
2130 | /* Avoid an unnecessary call to unbind on rebind. */ | ||
2131 | obj->map_and_fenceable = true; | ||
2150 | 2132 | ||
2151 | drm_mm_put_block(obj_priv->gtt_space); | 2133 | drm_mm_put_block(obj->gtt_space); |
2152 | obj_priv->gtt_space = NULL; | 2134 | obj->gtt_space = NULL; |
2153 | obj_priv->gtt_offset = 0; | 2135 | obj->gtt_offset = 0; |
2154 | 2136 | ||
2155 | if (i915_gem_object_is_purgeable(obj_priv)) | 2137 | if (i915_gem_object_is_purgeable(obj)) |
2156 | i915_gem_object_truncate(obj); | 2138 | i915_gem_object_truncate(obj); |
2157 | 2139 | ||
2158 | trace_i915_gem_object_unbind(obj); | 2140 | trace_i915_gem_object_unbind(obj); |
@@ -2160,14 +2142,25 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
2160 | return ret; | 2142 | return ret; |
2161 | } | 2143 | } |
2162 | 2144 | ||
2145 | void | ||
2146 | i915_gem_flush_ring(struct drm_device *dev, | ||
2147 | struct intel_ring_buffer *ring, | ||
2148 | uint32_t invalidate_domains, | ||
2149 | uint32_t flush_domains) | ||
2150 | { | ||
2151 | ring->flush(ring, invalidate_domains, flush_domains); | ||
2152 | i915_gem_process_flushing_list(dev, flush_domains, ring); | ||
2153 | } | ||
2154 | |||
2163 | static int i915_ring_idle(struct drm_device *dev, | 2155 | static int i915_ring_idle(struct drm_device *dev, |
2164 | struct intel_ring_buffer *ring) | 2156 | struct intel_ring_buffer *ring) |
2165 | { | 2157 | { |
2166 | if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list)) | 2158 | if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list)) |
2167 | return 0; | 2159 | return 0; |
2168 | 2160 | ||
2169 | i915_gem_flush_ring(dev, NULL, ring, | 2161 | if (!list_empty(&ring->gpu_write_list)) |
2170 | I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); | 2162 | i915_gem_flush_ring(dev, ring, |
2163 | I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); | ||
2171 | return i915_wait_request(dev, | 2164 | return i915_wait_request(dev, |
2172 | i915_gem_next_request_seqno(dev, ring), | 2165 | i915_gem_next_request_seqno(dev, ring), |
2173 | ring); | 2166 | ring); |
@@ -2178,7 +2171,7 @@ i915_gpu_idle(struct drm_device *dev) | |||
2178 | { | 2171 | { |
2179 | drm_i915_private_t *dev_priv = dev->dev_private; | 2172 | drm_i915_private_t *dev_priv = dev->dev_private; |
2180 | bool lists_empty; | 2173 | bool lists_empty; |
2181 | int ret; | 2174 | int ret, i; |
2182 | 2175 | ||
2183 | lists_empty = (list_empty(&dev_priv->mm.flushing_list) && | 2176 | lists_empty = (list_empty(&dev_priv->mm.flushing_list) && |
2184 | list_empty(&dev_priv->mm.active_list)); | 2177 | list_empty(&dev_priv->mm.active_list)); |
@@ -2186,258 +2179,296 @@ i915_gpu_idle(struct drm_device *dev) | |||
2186 | return 0; | 2179 | return 0; |
2187 | 2180 | ||
2188 | /* Flush everything onto the inactive list. */ | 2181 | /* Flush everything onto the inactive list. */ |
2189 | ret = i915_ring_idle(dev, &dev_priv->render_ring); | 2182 | for (i = 0; i < I915_NUM_RINGS; i++) { |
2190 | if (ret) | 2183 | ret = i915_ring_idle(dev, &dev_priv->ring[i]); |
2191 | return ret; | 2184 | if (ret) |
2192 | 2185 | return ret; | |
2193 | ret = i915_ring_idle(dev, &dev_priv->bsd_ring); | ||
2194 | if (ret) | ||
2195 | return ret; | ||
2196 | |||
2197 | ret = i915_ring_idle(dev, &dev_priv->blt_ring); | ||
2198 | if (ret) | ||
2199 | return ret; | ||
2200 | |||
2201 | return 0; | ||
2202 | } | ||
2203 | |||
2204 | static int | ||
2205 | i915_gem_object_get_pages(struct drm_gem_object *obj, | ||
2206 | gfp_t gfpmask) | ||
2207 | { | ||
2208 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
2209 | int page_count, i; | ||
2210 | struct address_space *mapping; | ||
2211 | struct inode *inode; | ||
2212 | struct page *page; | ||
2213 | |||
2214 | BUG_ON(obj_priv->pages_refcount | ||
2215 | == DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT); | ||
2216 | |||
2217 | if (obj_priv->pages_refcount++ != 0) | ||
2218 | return 0; | ||
2219 | |||
2220 | /* Get the list of pages out of our struct file. They'll be pinned | ||
2221 | * at this point until we release them. | ||
2222 | */ | ||
2223 | page_count = obj->size / PAGE_SIZE; | ||
2224 | BUG_ON(obj_priv->pages != NULL); | ||
2225 | obj_priv->pages = drm_calloc_large(page_count, sizeof(struct page *)); | ||
2226 | if (obj_priv->pages == NULL) { | ||
2227 | obj_priv->pages_refcount--; | ||
2228 | return -ENOMEM; | ||
2229 | } | ||
2230 | |||
2231 | inode = obj->filp->f_path.dentry->d_inode; | ||
2232 | mapping = inode->i_mapping; | ||
2233 | for (i = 0; i < page_count; i++) { | ||
2234 | page = read_cache_page_gfp(mapping, i, | ||
2235 | GFP_HIGHUSER | | ||
2236 | __GFP_COLD | | ||
2237 | __GFP_RECLAIMABLE | | ||
2238 | gfpmask); | ||
2239 | if (IS_ERR(page)) | ||
2240 | goto err_pages; | ||
2241 | |||
2242 | obj_priv->pages[i] = page; | ||
2243 | } | 2186 | } |
2244 | 2187 | ||
2245 | if (obj_priv->tiling_mode != I915_TILING_NONE) | ||
2246 | i915_gem_object_do_bit_17_swizzle(obj); | ||
2247 | |||
2248 | return 0; | 2188 | return 0; |
2249 | |||
2250 | err_pages: | ||
2251 | while (i--) | ||
2252 | page_cache_release(obj_priv->pages[i]); | ||
2253 | |||
2254 | drm_free_large(obj_priv->pages); | ||
2255 | obj_priv->pages = NULL; | ||
2256 | obj_priv->pages_refcount--; | ||
2257 | return PTR_ERR(page); | ||
2258 | } | 2189 | } |
2259 | 2190 | ||
2260 | static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg) | 2191 | static int sandybridge_write_fence_reg(struct drm_i915_gem_object *obj, |
2192 | struct intel_ring_buffer *pipelined) | ||
2261 | { | 2193 | { |
2262 | struct drm_gem_object *obj = reg->obj; | 2194 | struct drm_device *dev = obj->base.dev; |
2263 | struct drm_device *dev = obj->dev; | ||
2264 | drm_i915_private_t *dev_priv = dev->dev_private; | 2195 | drm_i915_private_t *dev_priv = dev->dev_private; |
2265 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2196 | u32 size = obj->gtt_space->size; |
2266 | int regnum = obj_priv->fence_reg; | 2197 | int regnum = obj->fence_reg; |
2267 | uint64_t val; | 2198 | uint64_t val; |
2268 | 2199 | ||
2269 | val = (uint64_t)((obj_priv->gtt_offset + obj->size - 4096) & | 2200 | val = (uint64_t)((obj->gtt_offset + size - 4096) & |
2270 | 0xfffff000) << 32; | 2201 | 0xfffff000) << 32; |
2271 | val |= obj_priv->gtt_offset & 0xfffff000; | 2202 | val |= obj->gtt_offset & 0xfffff000; |
2272 | val |= (uint64_t)((obj_priv->stride / 128) - 1) << | 2203 | val |= (uint64_t)((obj->stride / 128) - 1) << |
2273 | SANDYBRIDGE_FENCE_PITCH_SHIFT; | 2204 | SANDYBRIDGE_FENCE_PITCH_SHIFT; |
2274 | 2205 | ||
2275 | if (obj_priv->tiling_mode == I915_TILING_Y) | 2206 | if (obj->tiling_mode == I915_TILING_Y) |
2276 | val |= 1 << I965_FENCE_TILING_Y_SHIFT; | 2207 | val |= 1 << I965_FENCE_TILING_Y_SHIFT; |
2277 | val |= I965_FENCE_REG_VALID; | 2208 | val |= I965_FENCE_REG_VALID; |
2278 | 2209 | ||
2279 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (regnum * 8), val); | 2210 | if (pipelined) { |
2211 | int ret = intel_ring_begin(pipelined, 6); | ||
2212 | if (ret) | ||
2213 | return ret; | ||
2214 | |||
2215 | intel_ring_emit(pipelined, MI_NOOP); | ||
2216 | intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(2)); | ||
2217 | intel_ring_emit(pipelined, FENCE_REG_SANDYBRIDGE_0 + regnum*8); | ||
2218 | intel_ring_emit(pipelined, (u32)val); | ||
2219 | intel_ring_emit(pipelined, FENCE_REG_SANDYBRIDGE_0 + regnum*8 + 4); | ||
2220 | intel_ring_emit(pipelined, (u32)(val >> 32)); | ||
2221 | intel_ring_advance(pipelined); | ||
2222 | } else | ||
2223 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + regnum * 8, val); | ||
2224 | |||
2225 | return 0; | ||
2280 | } | 2226 | } |
2281 | 2227 | ||
2282 | static void i965_write_fence_reg(struct drm_i915_fence_reg *reg) | 2228 | static int i965_write_fence_reg(struct drm_i915_gem_object *obj, |
2229 | struct intel_ring_buffer *pipelined) | ||
2283 | { | 2230 | { |
2284 | struct drm_gem_object *obj = reg->obj; | 2231 | struct drm_device *dev = obj->base.dev; |
2285 | struct drm_device *dev = obj->dev; | ||
2286 | drm_i915_private_t *dev_priv = dev->dev_private; | 2232 | drm_i915_private_t *dev_priv = dev->dev_private; |
2287 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2233 | u32 size = obj->gtt_space->size; |
2288 | int regnum = obj_priv->fence_reg; | 2234 | int regnum = obj->fence_reg; |
2289 | uint64_t val; | 2235 | uint64_t val; |
2290 | 2236 | ||
2291 | val = (uint64_t)((obj_priv->gtt_offset + obj->size - 4096) & | 2237 | val = (uint64_t)((obj->gtt_offset + size - 4096) & |
2292 | 0xfffff000) << 32; | 2238 | 0xfffff000) << 32; |
2293 | val |= obj_priv->gtt_offset & 0xfffff000; | 2239 | val |= obj->gtt_offset & 0xfffff000; |
2294 | val |= ((obj_priv->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT; | 2240 | val |= ((obj->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT; |
2295 | if (obj_priv->tiling_mode == I915_TILING_Y) | 2241 | if (obj->tiling_mode == I915_TILING_Y) |
2296 | val |= 1 << I965_FENCE_TILING_Y_SHIFT; | 2242 | val |= 1 << I965_FENCE_TILING_Y_SHIFT; |
2297 | val |= I965_FENCE_REG_VALID; | 2243 | val |= I965_FENCE_REG_VALID; |
2298 | 2244 | ||
2299 | I915_WRITE64(FENCE_REG_965_0 + (regnum * 8), val); | 2245 | if (pipelined) { |
2246 | int ret = intel_ring_begin(pipelined, 6); | ||
2247 | if (ret) | ||
2248 | return ret; | ||
2249 | |||
2250 | intel_ring_emit(pipelined, MI_NOOP); | ||
2251 | intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(2)); | ||
2252 | intel_ring_emit(pipelined, FENCE_REG_965_0 + regnum*8); | ||
2253 | intel_ring_emit(pipelined, (u32)val); | ||
2254 | intel_ring_emit(pipelined, FENCE_REG_965_0 + regnum*8 + 4); | ||
2255 | intel_ring_emit(pipelined, (u32)(val >> 32)); | ||
2256 | intel_ring_advance(pipelined); | ||
2257 | } else | ||
2258 | I915_WRITE64(FENCE_REG_965_0 + regnum * 8, val); | ||
2259 | |||
2260 | return 0; | ||
2300 | } | 2261 | } |
2301 | 2262 | ||
2302 | static void i915_write_fence_reg(struct drm_i915_fence_reg *reg) | 2263 | static int i915_write_fence_reg(struct drm_i915_gem_object *obj, |
2264 | struct intel_ring_buffer *pipelined) | ||
2303 | { | 2265 | { |
2304 | struct drm_gem_object *obj = reg->obj; | 2266 | struct drm_device *dev = obj->base.dev; |
2305 | struct drm_device *dev = obj->dev; | ||
2306 | drm_i915_private_t *dev_priv = dev->dev_private; | 2267 | drm_i915_private_t *dev_priv = dev->dev_private; |
2307 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2268 | u32 size = obj->gtt_space->size; |
2308 | int regnum = obj_priv->fence_reg; | 2269 | u32 fence_reg, val, pitch_val; |
2309 | int tile_width; | 2270 | int tile_width; |
2310 | uint32_t fence_reg, val; | ||
2311 | uint32_t pitch_val; | ||
2312 | 2271 | ||
2313 | if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) || | 2272 | if (WARN((obj->gtt_offset & ~I915_FENCE_START_MASK) || |
2314 | (obj_priv->gtt_offset & (obj->size - 1))) { | 2273 | (size & -size) != size || |
2315 | WARN(1, "%s: object 0x%08x not 1M or size (0x%zx) aligned\n", | 2274 | (obj->gtt_offset & (size - 1)), |
2316 | __func__, obj_priv->gtt_offset, obj->size); | 2275 | "object 0x%08x [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n", |
2317 | return; | 2276 | obj->gtt_offset, obj->map_and_fenceable, size)) |
2318 | } | 2277 | return -EINVAL; |
2319 | 2278 | ||
2320 | if (obj_priv->tiling_mode == I915_TILING_Y && | 2279 | if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) |
2321 | HAS_128_BYTE_Y_TILING(dev)) | ||
2322 | tile_width = 128; | 2280 | tile_width = 128; |
2323 | else | 2281 | else |
2324 | tile_width = 512; | 2282 | tile_width = 512; |
2325 | 2283 | ||
2326 | /* Note: pitch better be a power of two tile widths */ | 2284 | /* Note: pitch better be a power of two tile widths */ |
2327 | pitch_val = obj_priv->stride / tile_width; | 2285 | pitch_val = obj->stride / tile_width; |
2328 | pitch_val = ffs(pitch_val) - 1; | 2286 | pitch_val = ffs(pitch_val) - 1; |
2329 | 2287 | ||
2330 | if (obj_priv->tiling_mode == I915_TILING_Y && | 2288 | val = obj->gtt_offset; |
2331 | HAS_128_BYTE_Y_TILING(dev)) | 2289 | if (obj->tiling_mode == I915_TILING_Y) |
2332 | WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL); | ||
2333 | else | ||
2334 | WARN_ON(pitch_val > I915_FENCE_MAX_PITCH_VAL); | ||
2335 | |||
2336 | val = obj_priv->gtt_offset; | ||
2337 | if (obj_priv->tiling_mode == I915_TILING_Y) | ||
2338 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; | 2290 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; |
2339 | val |= I915_FENCE_SIZE_BITS(obj->size); | 2291 | val |= I915_FENCE_SIZE_BITS(size); |
2340 | val |= pitch_val << I830_FENCE_PITCH_SHIFT; | 2292 | val |= pitch_val << I830_FENCE_PITCH_SHIFT; |
2341 | val |= I830_FENCE_REG_VALID; | 2293 | val |= I830_FENCE_REG_VALID; |
2342 | 2294 | ||
2343 | if (regnum < 8) | 2295 | fence_reg = obj->fence_reg; |
2344 | fence_reg = FENCE_REG_830_0 + (regnum * 4); | 2296 | if (fence_reg < 8) |
2297 | fence_reg = FENCE_REG_830_0 + fence_reg * 4; | ||
2345 | else | 2298 | else |
2346 | fence_reg = FENCE_REG_945_8 + ((regnum - 8) * 4); | 2299 | fence_reg = FENCE_REG_945_8 + (fence_reg - 8) * 4; |
2347 | I915_WRITE(fence_reg, val); | 2300 | |
2301 | if (pipelined) { | ||
2302 | int ret = intel_ring_begin(pipelined, 4); | ||
2303 | if (ret) | ||
2304 | return ret; | ||
2305 | |||
2306 | intel_ring_emit(pipelined, MI_NOOP); | ||
2307 | intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(1)); | ||
2308 | intel_ring_emit(pipelined, fence_reg); | ||
2309 | intel_ring_emit(pipelined, val); | ||
2310 | intel_ring_advance(pipelined); | ||
2311 | } else | ||
2312 | I915_WRITE(fence_reg, val); | ||
2313 | |||
2314 | return 0; | ||
2348 | } | 2315 | } |
2349 | 2316 | ||
2350 | static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) | 2317 | static int i830_write_fence_reg(struct drm_i915_gem_object *obj, |
2318 | struct intel_ring_buffer *pipelined) | ||
2351 | { | 2319 | { |
2352 | struct drm_gem_object *obj = reg->obj; | 2320 | struct drm_device *dev = obj->base.dev; |
2353 | struct drm_device *dev = obj->dev; | ||
2354 | drm_i915_private_t *dev_priv = dev->dev_private; | 2321 | drm_i915_private_t *dev_priv = dev->dev_private; |
2355 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2322 | u32 size = obj->gtt_space->size; |
2356 | int regnum = obj_priv->fence_reg; | 2323 | int regnum = obj->fence_reg; |
2357 | uint32_t val; | 2324 | uint32_t val; |
2358 | uint32_t pitch_val; | 2325 | uint32_t pitch_val; |
2359 | uint32_t fence_size_bits; | ||
2360 | 2326 | ||
2361 | if ((obj_priv->gtt_offset & ~I830_FENCE_START_MASK) || | 2327 | if (WARN((obj->gtt_offset & ~I830_FENCE_START_MASK) || |
2362 | (obj_priv->gtt_offset & (obj->size - 1))) { | 2328 | (size & -size) != size || |
2363 | WARN(1, "%s: object 0x%08x not 512K or size aligned\n", | 2329 | (obj->gtt_offset & (size - 1)), |
2364 | __func__, obj_priv->gtt_offset); | 2330 | "object 0x%08x not 512K or pot-size 0x%08x aligned\n", |
2365 | return; | 2331 | obj->gtt_offset, size)) |
2366 | } | 2332 | return -EINVAL; |
2367 | 2333 | ||
2368 | pitch_val = obj_priv->stride / 128; | 2334 | pitch_val = obj->stride / 128; |
2369 | pitch_val = ffs(pitch_val) - 1; | 2335 | pitch_val = ffs(pitch_val) - 1; |
2370 | WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL); | ||
2371 | 2336 | ||
2372 | val = obj_priv->gtt_offset; | 2337 | val = obj->gtt_offset; |
2373 | if (obj_priv->tiling_mode == I915_TILING_Y) | 2338 | if (obj->tiling_mode == I915_TILING_Y) |
2374 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; | 2339 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; |
2375 | fence_size_bits = I830_FENCE_SIZE_BITS(obj->size); | 2340 | val |= I830_FENCE_SIZE_BITS(size); |
2376 | WARN_ON(fence_size_bits & ~0x00000f00); | ||
2377 | val |= fence_size_bits; | ||
2378 | val |= pitch_val << I830_FENCE_PITCH_SHIFT; | 2341 | val |= pitch_val << I830_FENCE_PITCH_SHIFT; |
2379 | val |= I830_FENCE_REG_VALID; | 2342 | val |= I830_FENCE_REG_VALID; |
2380 | 2343 | ||
2381 | I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val); | 2344 | if (pipelined) { |
2345 | int ret = intel_ring_begin(pipelined, 4); | ||
2346 | if (ret) | ||
2347 | return ret; | ||
2348 | |||
2349 | intel_ring_emit(pipelined, MI_NOOP); | ||
2350 | intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(1)); | ||
2351 | intel_ring_emit(pipelined, FENCE_REG_830_0 + regnum*4); | ||
2352 | intel_ring_emit(pipelined, val); | ||
2353 | intel_ring_advance(pipelined); | ||
2354 | } else | ||
2355 | I915_WRITE(FENCE_REG_830_0 + regnum * 4, val); | ||
2356 | |||
2357 | return 0; | ||
2382 | } | 2358 | } |
2383 | 2359 | ||
2384 | static int i915_find_fence_reg(struct drm_device *dev, | 2360 | static bool ring_passed_seqno(struct intel_ring_buffer *ring, u32 seqno) |
2385 | bool interruptible) | 2361 | { |
2362 | return i915_seqno_passed(ring->get_seqno(ring), seqno); | ||
2363 | } | ||
2364 | |||
2365 | static int | ||
2366 | i915_gem_object_flush_fence(struct drm_i915_gem_object *obj, | ||
2367 | struct intel_ring_buffer *pipelined, | ||
2368 | bool interruptible) | ||
2369 | { | ||
2370 | int ret; | ||
2371 | |||
2372 | if (obj->fenced_gpu_access) { | ||
2373 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) | ||
2374 | i915_gem_flush_ring(obj->base.dev, | ||
2375 | obj->last_fenced_ring, | ||
2376 | 0, obj->base.write_domain); | ||
2377 | |||
2378 | obj->fenced_gpu_access = false; | ||
2379 | } | ||
2380 | |||
2381 | if (obj->last_fenced_seqno && pipelined != obj->last_fenced_ring) { | ||
2382 | if (!ring_passed_seqno(obj->last_fenced_ring, | ||
2383 | obj->last_fenced_seqno)) { | ||
2384 | ret = i915_do_wait_request(obj->base.dev, | ||
2385 | obj->last_fenced_seqno, | ||
2386 | interruptible, | ||
2387 | obj->last_fenced_ring); | ||
2388 | if (ret) | ||
2389 | return ret; | ||
2390 | } | ||
2391 | |||
2392 | obj->last_fenced_seqno = 0; | ||
2393 | obj->last_fenced_ring = NULL; | ||
2394 | } | ||
2395 | |||
2396 | return 0; | ||
2397 | } | ||
2398 | |||
2399 | int | ||
2400 | i915_gem_object_put_fence(struct drm_i915_gem_object *obj) | ||
2401 | { | ||
2402 | int ret; | ||
2403 | |||
2404 | if (obj->tiling_mode) | ||
2405 | i915_gem_release_mmap(obj); | ||
2406 | |||
2407 | ret = i915_gem_object_flush_fence(obj, NULL, true); | ||
2408 | if (ret) | ||
2409 | return ret; | ||
2410 | |||
2411 | if (obj->fence_reg != I915_FENCE_REG_NONE) { | ||
2412 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
2413 | i915_gem_clear_fence_reg(obj->base.dev, | ||
2414 | &dev_priv->fence_regs[obj->fence_reg]); | ||
2415 | |||
2416 | obj->fence_reg = I915_FENCE_REG_NONE; | ||
2417 | } | ||
2418 | |||
2419 | return 0; | ||
2420 | } | ||
2421 | |||
2422 | static struct drm_i915_fence_reg * | ||
2423 | i915_find_fence_reg(struct drm_device *dev, | ||
2424 | struct intel_ring_buffer *pipelined) | ||
2386 | { | 2425 | { |
2387 | struct drm_i915_fence_reg *reg = NULL; | ||
2388 | struct drm_i915_gem_object *obj_priv = NULL; | ||
2389 | struct drm_i915_private *dev_priv = dev->dev_private; | 2426 | struct drm_i915_private *dev_priv = dev->dev_private; |
2390 | struct drm_gem_object *obj = NULL; | 2427 | struct drm_i915_fence_reg *reg, *first, *avail; |
2391 | int i, avail, ret; | 2428 | int i; |
2392 | 2429 | ||
2393 | /* First try to find a free reg */ | 2430 | /* First try to find a free reg */ |
2394 | avail = 0; | 2431 | avail = NULL; |
2395 | for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { | 2432 | for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { |
2396 | reg = &dev_priv->fence_regs[i]; | 2433 | reg = &dev_priv->fence_regs[i]; |
2397 | if (!reg->obj) | 2434 | if (!reg->obj) |
2398 | return i; | 2435 | return reg; |
2399 | 2436 | ||
2400 | obj_priv = to_intel_bo(reg->obj); | 2437 | if (!reg->obj->pin_count) |
2401 | if (!obj_priv->pin_count) | 2438 | avail = reg; |
2402 | avail++; | ||
2403 | } | 2439 | } |
2404 | 2440 | ||
2405 | if (avail == 0) | 2441 | if (avail == NULL) |
2406 | return -ENOSPC; | 2442 | return NULL; |
2407 | 2443 | ||
2408 | /* None available, try to steal one or wait for a user to finish */ | 2444 | /* None available, try to steal one or wait for a user to finish */ |
2409 | i = I915_FENCE_REG_NONE; | 2445 | avail = first = NULL; |
2410 | list_for_each_entry(reg, &dev_priv->mm.fence_list, | 2446 | list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) { |
2411 | lru_list) { | 2447 | if (reg->obj->pin_count) |
2412 | obj = reg->obj; | ||
2413 | obj_priv = to_intel_bo(obj); | ||
2414 | |||
2415 | if (obj_priv->pin_count) | ||
2416 | continue; | 2448 | continue; |
2417 | 2449 | ||
2418 | /* found one! */ | 2450 | if (first == NULL) |
2419 | i = obj_priv->fence_reg; | 2451 | first = reg; |
2420 | break; | 2452 | |
2453 | if (!pipelined || | ||
2454 | !reg->obj->last_fenced_ring || | ||
2455 | reg->obj->last_fenced_ring == pipelined) { | ||
2456 | avail = reg; | ||
2457 | break; | ||
2458 | } | ||
2421 | } | 2459 | } |
2422 | 2460 | ||
2423 | BUG_ON(i == I915_FENCE_REG_NONE); | 2461 | if (avail == NULL) |
2462 | avail = first; | ||
2424 | 2463 | ||
2425 | /* We only have a reference on obj from the active list. put_fence_reg | 2464 | return avail; |
2426 | * might drop that one, causing a use-after-free in it. So hold a | ||
2427 | * private reference to obj like the other callers of put_fence_reg | ||
2428 | * (set_tiling ioctl) do. */ | ||
2429 | drm_gem_object_reference(obj); | ||
2430 | ret = i915_gem_object_put_fence_reg(obj, interruptible); | ||
2431 | drm_gem_object_unreference(obj); | ||
2432 | if (ret != 0) | ||
2433 | return ret; | ||
2434 | |||
2435 | return i; | ||
2436 | } | 2465 | } |
2437 | 2466 | ||
2438 | /** | 2467 | /** |
2439 | * i915_gem_object_get_fence_reg - set up a fence reg for an object | 2468 | * i915_gem_object_get_fence - set up a fence reg for an object |
2440 | * @obj: object to map through a fence reg | 2469 | * @obj: object to map through a fence reg |
2470 | * @pipelined: ring on which to queue the change, or NULL for CPU access | ||
2471 | * @interruptible: must we wait uninterruptibly for the register to retire? | ||
2441 | * | 2472 | * |
2442 | * When mapping objects through the GTT, userspace wants to be able to write | 2473 | * When mapping objects through the GTT, userspace wants to be able to write |
2443 | * to them without having to worry about swizzling if the object is tiled. | 2474 | * to them without having to worry about swizzling if the object is tiled. |
@@ -2449,72 +2480,138 @@ static int i915_find_fence_reg(struct drm_device *dev, | |||
2449 | * and tiling format. | 2480 | * and tiling format. |
2450 | */ | 2481 | */ |
2451 | int | 2482 | int |
2452 | i915_gem_object_get_fence_reg(struct drm_gem_object *obj, | 2483 | i915_gem_object_get_fence(struct drm_i915_gem_object *obj, |
2453 | bool interruptible) | 2484 | struct intel_ring_buffer *pipelined, |
2485 | bool interruptible) | ||
2454 | { | 2486 | { |
2455 | struct drm_device *dev = obj->dev; | 2487 | struct drm_device *dev = obj->base.dev; |
2456 | struct drm_i915_private *dev_priv = dev->dev_private; | 2488 | struct drm_i915_private *dev_priv = dev->dev_private; |
2457 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2489 | struct drm_i915_fence_reg *reg; |
2458 | struct drm_i915_fence_reg *reg = NULL; | ||
2459 | int ret; | 2490 | int ret; |
2460 | 2491 | ||
2461 | /* Just update our place in the LRU if our fence is getting used. */ | 2492 | /* XXX disable pipelining. There are bugs. Shocking. */ |
2462 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { | 2493 | pipelined = NULL; |
2463 | reg = &dev_priv->fence_regs[obj_priv->fence_reg]; | 2494 | |
2495 | /* Just update our place in the LRU if our fence is getting reused. */ | ||
2496 | if (obj->fence_reg != I915_FENCE_REG_NONE) { | ||
2497 | reg = &dev_priv->fence_regs[obj->fence_reg]; | ||
2464 | list_move_tail(®->lru_list, &dev_priv->mm.fence_list); | 2498 | list_move_tail(®->lru_list, &dev_priv->mm.fence_list); |
2499 | |||
2500 | if (!obj->fenced_gpu_access && !obj->last_fenced_seqno) | ||
2501 | pipelined = NULL; | ||
2502 | |||
2503 | if (!pipelined) { | ||
2504 | if (reg->setup_seqno) { | ||
2505 | if (!ring_passed_seqno(obj->last_fenced_ring, | ||
2506 | reg->setup_seqno)) { | ||
2507 | ret = i915_do_wait_request(obj->base.dev, | ||
2508 | reg->setup_seqno, | ||
2509 | interruptible, | ||
2510 | obj->last_fenced_ring); | ||
2511 | if (ret) | ||
2512 | return ret; | ||
2513 | } | ||
2514 | |||
2515 | reg->setup_seqno = 0; | ||
2516 | } | ||
2517 | } else if (obj->last_fenced_ring && | ||
2518 | obj->last_fenced_ring != pipelined) { | ||
2519 | ret = i915_gem_object_flush_fence(obj, | ||
2520 | pipelined, | ||
2521 | interruptible); | ||
2522 | if (ret) | ||
2523 | return ret; | ||
2524 | } else if (obj->tiling_changed) { | ||
2525 | if (obj->fenced_gpu_access) { | ||
2526 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) | ||
2527 | i915_gem_flush_ring(obj->base.dev, obj->ring, | ||
2528 | 0, obj->base.write_domain); | ||
2529 | |||
2530 | obj->fenced_gpu_access = false; | ||
2531 | } | ||
2532 | } | ||
2533 | |||
2534 | if (!obj->fenced_gpu_access && !obj->last_fenced_seqno) | ||
2535 | pipelined = NULL; | ||
2536 | BUG_ON(!pipelined && reg->setup_seqno); | ||
2537 | |||
2538 | if (obj->tiling_changed) { | ||
2539 | if (pipelined) { | ||
2540 | reg->setup_seqno = | ||
2541 | i915_gem_next_request_seqno(dev, pipelined); | ||
2542 | obj->last_fenced_seqno = reg->setup_seqno; | ||
2543 | obj->last_fenced_ring = pipelined; | ||
2544 | } | ||
2545 | goto update; | ||
2546 | } | ||
2547 | |||
2465 | return 0; | 2548 | return 0; |
2466 | } | 2549 | } |
2467 | 2550 | ||
2468 | switch (obj_priv->tiling_mode) { | 2551 | reg = i915_find_fence_reg(dev, pipelined); |
2469 | case I915_TILING_NONE: | 2552 | if (reg == NULL) |
2470 | WARN(1, "allocating a fence for non-tiled object?\n"); | 2553 | return -ENOSPC; |
2471 | break; | ||
2472 | case I915_TILING_X: | ||
2473 | if (!obj_priv->stride) | ||
2474 | return -EINVAL; | ||
2475 | WARN((obj_priv->stride & (512 - 1)), | ||
2476 | "object 0x%08x is X tiled but has non-512B pitch\n", | ||
2477 | obj_priv->gtt_offset); | ||
2478 | break; | ||
2479 | case I915_TILING_Y: | ||
2480 | if (!obj_priv->stride) | ||
2481 | return -EINVAL; | ||
2482 | WARN((obj_priv->stride & (128 - 1)), | ||
2483 | "object 0x%08x is Y tiled but has non-128B pitch\n", | ||
2484 | obj_priv->gtt_offset); | ||
2485 | break; | ||
2486 | } | ||
2487 | 2554 | ||
2488 | ret = i915_find_fence_reg(dev, interruptible); | 2555 | ret = i915_gem_object_flush_fence(obj, pipelined, interruptible); |
2489 | if (ret < 0) | 2556 | if (ret) |
2490 | return ret; | 2557 | return ret; |
2491 | 2558 | ||
2492 | obj_priv->fence_reg = ret; | 2559 | if (reg->obj) { |
2493 | reg = &dev_priv->fence_regs[obj_priv->fence_reg]; | 2560 | struct drm_i915_gem_object *old = reg->obj; |
2494 | list_add_tail(®->lru_list, &dev_priv->mm.fence_list); | 2561 | |
2562 | drm_gem_object_reference(&old->base); | ||
2563 | |||
2564 | if (old->tiling_mode) | ||
2565 | i915_gem_release_mmap(old); | ||
2566 | |||
2567 | ret = i915_gem_object_flush_fence(old, | ||
2568 | pipelined, | ||
2569 | interruptible); | ||
2570 | if (ret) { | ||
2571 | drm_gem_object_unreference(&old->base); | ||
2572 | return ret; | ||
2573 | } | ||
2574 | |||
2575 | if (old->last_fenced_seqno == 0 && obj->last_fenced_seqno == 0) | ||
2576 | pipelined = NULL; | ||
2577 | |||
2578 | old->fence_reg = I915_FENCE_REG_NONE; | ||
2579 | old->last_fenced_ring = pipelined; | ||
2580 | old->last_fenced_seqno = | ||
2581 | pipelined ? i915_gem_next_request_seqno(dev, pipelined) : 0; | ||
2582 | |||
2583 | drm_gem_object_unreference(&old->base); | ||
2584 | } else if (obj->last_fenced_seqno == 0) | ||
2585 | pipelined = NULL; | ||
2495 | 2586 | ||
2496 | reg->obj = obj; | 2587 | reg->obj = obj; |
2588 | list_move_tail(®->lru_list, &dev_priv->mm.fence_list); | ||
2589 | obj->fence_reg = reg - dev_priv->fence_regs; | ||
2590 | obj->last_fenced_ring = pipelined; | ||
2591 | |||
2592 | reg->setup_seqno = | ||
2593 | pipelined ? i915_gem_next_request_seqno(dev, pipelined) : 0; | ||
2594 | obj->last_fenced_seqno = reg->setup_seqno; | ||
2497 | 2595 | ||
2596 | update: | ||
2597 | obj->tiling_changed = false; | ||
2498 | switch (INTEL_INFO(dev)->gen) { | 2598 | switch (INTEL_INFO(dev)->gen) { |
2499 | case 6: | 2599 | case 6: |
2500 | sandybridge_write_fence_reg(reg); | 2600 | ret = sandybridge_write_fence_reg(obj, pipelined); |
2501 | break; | 2601 | break; |
2502 | case 5: | 2602 | case 5: |
2503 | case 4: | 2603 | case 4: |
2504 | i965_write_fence_reg(reg); | 2604 | ret = i965_write_fence_reg(obj, pipelined); |
2505 | break; | 2605 | break; |
2506 | case 3: | 2606 | case 3: |
2507 | i915_write_fence_reg(reg); | 2607 | ret = i915_write_fence_reg(obj, pipelined); |
2508 | break; | 2608 | break; |
2509 | case 2: | 2609 | case 2: |
2510 | i830_write_fence_reg(reg); | 2610 | ret = i830_write_fence_reg(obj, pipelined); |
2511 | break; | 2611 | break; |
2512 | } | 2612 | } |
2513 | 2613 | ||
2514 | trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg, | 2614 | return ret; |
2515 | obj_priv->tiling_mode); | ||
2516 | |||
2517 | return 0; | ||
2518 | } | 2615 | } |
2519 | 2616 | ||
2520 | /** | 2617 | /** |
@@ -2522,154 +2619,127 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj, | |||
2522 | * @obj: object to clear | 2619 | * @obj: object to clear |
2523 | * | 2620 | * |
2524 | * Zeroes out the fence register itself and clears out the associated | 2621 | * Zeroes out the fence register itself and clears out the associated |
2525 | * data structures in dev_priv and obj_priv. | 2622 | * data structures in dev_priv and obj. |
2526 | */ | 2623 | */ |
2527 | static void | 2624 | static void |
2528 | i915_gem_clear_fence_reg(struct drm_gem_object *obj) | 2625 | i915_gem_clear_fence_reg(struct drm_device *dev, |
2626 | struct drm_i915_fence_reg *reg) | ||
2529 | { | 2627 | { |
2530 | struct drm_device *dev = obj->dev; | ||
2531 | drm_i915_private_t *dev_priv = dev->dev_private; | 2628 | drm_i915_private_t *dev_priv = dev->dev_private; |
2532 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2629 | uint32_t fence_reg = reg - dev_priv->fence_regs; |
2533 | struct drm_i915_fence_reg *reg = | ||
2534 | &dev_priv->fence_regs[obj_priv->fence_reg]; | ||
2535 | uint32_t fence_reg; | ||
2536 | 2630 | ||
2537 | switch (INTEL_INFO(dev)->gen) { | 2631 | switch (INTEL_INFO(dev)->gen) { |
2538 | case 6: | 2632 | case 6: |
2539 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + | 2633 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + fence_reg*8, 0); |
2540 | (obj_priv->fence_reg * 8), 0); | ||
2541 | break; | 2634 | break; |
2542 | case 5: | 2635 | case 5: |
2543 | case 4: | 2636 | case 4: |
2544 | I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0); | 2637 | I915_WRITE64(FENCE_REG_965_0 + fence_reg*8, 0); |
2545 | break; | 2638 | break; |
2546 | case 3: | 2639 | case 3: |
2547 | if (obj_priv->fence_reg >= 8) | 2640 | if (fence_reg >= 8) |
2548 | fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - 8) * 4; | 2641 | fence_reg = FENCE_REG_945_8 + (fence_reg - 8) * 4; |
2549 | else | 2642 | else |
2550 | case 2: | 2643 | case 2: |
2551 | fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4; | 2644 | fence_reg = FENCE_REG_830_0 + fence_reg * 4; |
2552 | 2645 | ||
2553 | I915_WRITE(fence_reg, 0); | 2646 | I915_WRITE(fence_reg, 0); |
2554 | break; | 2647 | break; |
2555 | } | 2648 | } |
2556 | 2649 | ||
2557 | reg->obj = NULL; | ||
2558 | obj_priv->fence_reg = I915_FENCE_REG_NONE; | ||
2559 | list_del_init(®->lru_list); | 2650 | list_del_init(®->lru_list); |
2560 | } | 2651 | reg->obj = NULL; |
2561 | 2652 | reg->setup_seqno = 0; | |
2562 | /** | ||
2563 | * i915_gem_object_put_fence_reg - waits on outstanding fenced access | ||
2564 | * to the buffer to finish, and then resets the fence register. | ||
2565 | * @obj: tiled object holding a fence register. | ||
2566 | * @bool: whether the wait upon the fence is interruptible | ||
2567 | * | ||
2568 | * Zeroes out the fence register itself and clears out the associated | ||
2569 | * data structures in dev_priv and obj_priv. | ||
2570 | */ | ||
2571 | int | ||
2572 | i915_gem_object_put_fence_reg(struct drm_gem_object *obj, | ||
2573 | bool interruptible) | ||
2574 | { | ||
2575 | struct drm_device *dev = obj->dev; | ||
2576 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2577 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
2578 | struct drm_i915_fence_reg *reg; | ||
2579 | |||
2580 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE) | ||
2581 | return 0; | ||
2582 | |||
2583 | /* If we've changed tiling, GTT-mappings of the object | ||
2584 | * need to re-fault to ensure that the correct fence register | ||
2585 | * setup is in place. | ||
2586 | */ | ||
2587 | i915_gem_release_mmap(obj); | ||
2588 | |||
2589 | /* On the i915, GPU access to tiled buffers is via a fence, | ||
2590 | * therefore we must wait for any outstanding access to complete | ||
2591 | * before clearing the fence. | ||
2592 | */ | ||
2593 | reg = &dev_priv->fence_regs[obj_priv->fence_reg]; | ||
2594 | if (reg->gpu) { | ||
2595 | int ret; | ||
2596 | |||
2597 | ret = i915_gem_object_flush_gpu_write_domain(obj, true); | ||
2598 | if (ret) | ||
2599 | return ret; | ||
2600 | |||
2601 | ret = i915_gem_object_wait_rendering(obj, interruptible); | ||
2602 | if (ret) | ||
2603 | return ret; | ||
2604 | |||
2605 | reg->gpu = false; | ||
2606 | } | ||
2607 | |||
2608 | i915_gem_object_flush_gtt_write_domain(obj); | ||
2609 | i915_gem_clear_fence_reg(obj); | ||
2610 | |||
2611 | return 0; | ||
2612 | } | 2653 | } |
2613 | 2654 | ||
2614 | /** | 2655 | /** |
2615 | * Finds free space in the GTT aperture and binds the object there. | 2656 | * Finds free space in the GTT aperture and binds the object there. |
2616 | */ | 2657 | */ |
2617 | static int | 2658 | static int |
2618 | i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | 2659 | i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, |
2660 | unsigned alignment, | ||
2661 | bool map_and_fenceable) | ||
2619 | { | 2662 | { |
2620 | struct drm_device *dev = obj->dev; | 2663 | struct drm_device *dev = obj->base.dev; |
2621 | drm_i915_private_t *dev_priv = dev->dev_private; | 2664 | drm_i915_private_t *dev_priv = dev->dev_private; |
2622 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
2623 | struct drm_mm_node *free_space; | 2665 | struct drm_mm_node *free_space; |
2624 | gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; | 2666 | gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; |
2667 | u32 size, fence_size, fence_alignment, unfenced_alignment; | ||
2668 | bool mappable, fenceable; | ||
2625 | int ret; | 2669 | int ret; |
2626 | 2670 | ||
2627 | if (obj_priv->madv != I915_MADV_WILLNEED) { | 2671 | if (obj->madv != I915_MADV_WILLNEED) { |
2628 | DRM_ERROR("Attempting to bind a purgeable object\n"); | 2672 | DRM_ERROR("Attempting to bind a purgeable object\n"); |
2629 | return -EINVAL; | 2673 | return -EINVAL; |
2630 | } | 2674 | } |
2631 | 2675 | ||
2676 | fence_size = i915_gem_get_gtt_size(obj); | ||
2677 | fence_alignment = i915_gem_get_gtt_alignment(obj); | ||
2678 | unfenced_alignment = i915_gem_get_unfenced_gtt_alignment(obj); | ||
2679 | |||
2632 | if (alignment == 0) | 2680 | if (alignment == 0) |
2633 | alignment = i915_gem_get_gtt_alignment(obj); | 2681 | alignment = map_and_fenceable ? fence_alignment : |
2634 | if (alignment & (i915_gem_get_gtt_alignment(obj) - 1)) { | 2682 | unfenced_alignment; |
2683 | if (map_and_fenceable && alignment & (fence_alignment - 1)) { | ||
2635 | DRM_ERROR("Invalid object alignment requested %u\n", alignment); | 2684 | DRM_ERROR("Invalid object alignment requested %u\n", alignment); |
2636 | return -EINVAL; | 2685 | return -EINVAL; |
2637 | } | 2686 | } |
2638 | 2687 | ||
2688 | size = map_and_fenceable ? fence_size : obj->base.size; | ||
2689 | |||
2639 | /* If the object is bigger than the entire aperture, reject it early | 2690 | /* If the object is bigger than the entire aperture, reject it early |
2640 | * before evicting everything in a vain attempt to find space. | 2691 | * before evicting everything in a vain attempt to find space. |
2641 | */ | 2692 | */ |
2642 | if (obj->size > dev_priv->mm.gtt_total) { | 2693 | if (obj->base.size > |
2694 | (map_and_fenceable ? dev_priv->mm.gtt_mappable_end : dev_priv->mm.gtt_total)) { | ||
2643 | DRM_ERROR("Attempting to bind an object larger than the aperture\n"); | 2695 | DRM_ERROR("Attempting to bind an object larger than the aperture\n"); |
2644 | return -E2BIG; | 2696 | return -E2BIG; |
2645 | } | 2697 | } |
2646 | 2698 | ||
2647 | search_free: | 2699 | search_free: |
2648 | free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, | 2700 | if (map_and_fenceable) |
2649 | obj->size, alignment, 0); | 2701 | free_space = |
2650 | if (free_space != NULL) | 2702 | drm_mm_search_free_in_range(&dev_priv->mm.gtt_space, |
2651 | obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size, | 2703 | size, alignment, 0, |
2652 | alignment); | 2704 | dev_priv->mm.gtt_mappable_end, |
2653 | if (obj_priv->gtt_space == NULL) { | 2705 | 0); |
2706 | else | ||
2707 | free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, | ||
2708 | size, alignment, 0); | ||
2709 | |||
2710 | if (free_space != NULL) { | ||
2711 | if (map_and_fenceable) | ||
2712 | obj->gtt_space = | ||
2713 | drm_mm_get_block_range_generic(free_space, | ||
2714 | size, alignment, 0, | ||
2715 | dev_priv->mm.gtt_mappable_end, | ||
2716 | 0); | ||
2717 | else | ||
2718 | obj->gtt_space = | ||
2719 | drm_mm_get_block(free_space, size, alignment); | ||
2720 | } | ||
2721 | if (obj->gtt_space == NULL) { | ||
2654 | /* If the gtt is empty and we're still having trouble | 2722 | /* If the gtt is empty and we're still having trouble |
2655 | * fitting our object in, we're out of memory. | 2723 | * fitting our object in, we're out of memory. |
2656 | */ | 2724 | */ |
2657 | ret = i915_gem_evict_something(dev, obj->size, alignment); | 2725 | ret = i915_gem_evict_something(dev, size, alignment, |
2726 | map_and_fenceable); | ||
2658 | if (ret) | 2727 | if (ret) |
2659 | return ret; | 2728 | return ret; |
2660 | 2729 | ||
2661 | goto search_free; | 2730 | goto search_free; |
2662 | } | 2731 | } |
2663 | 2732 | ||
2664 | ret = i915_gem_object_get_pages(obj, gfpmask); | 2733 | ret = i915_gem_object_get_pages_gtt(obj, gfpmask); |
2665 | if (ret) { | 2734 | if (ret) { |
2666 | drm_mm_put_block(obj_priv->gtt_space); | 2735 | drm_mm_put_block(obj->gtt_space); |
2667 | obj_priv->gtt_space = NULL; | 2736 | obj->gtt_space = NULL; |
2668 | 2737 | ||
2669 | if (ret == -ENOMEM) { | 2738 | if (ret == -ENOMEM) { |
2670 | /* first try to clear up some space from the GTT */ | 2739 | /* first try to clear up some space from the GTT */ |
2671 | ret = i915_gem_evict_something(dev, obj->size, | 2740 | ret = i915_gem_evict_something(dev, size, |
2672 | alignment); | 2741 | alignment, |
2742 | map_and_fenceable); | ||
2673 | if (ret) { | 2743 | if (ret) { |
2674 | /* now try to shrink everyone else */ | 2744 | /* now try to shrink everyone else */ |
2675 | if (gfpmask) { | 2745 | if (gfpmask) { |
@@ -2686,126 +2756,113 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2686 | return ret; | 2756 | return ret; |
2687 | } | 2757 | } |
2688 | 2758 | ||
2689 | /* Create an AGP memory structure pointing at our pages, and bind it | 2759 | ret = i915_gem_gtt_bind_object(obj); |
2690 | * into the GTT. | 2760 | if (ret) { |
2691 | */ | 2761 | i915_gem_object_put_pages_gtt(obj); |
2692 | obj_priv->agp_mem = drm_agp_bind_pages(dev, | 2762 | drm_mm_put_block(obj->gtt_space); |
2693 | obj_priv->pages, | 2763 | obj->gtt_space = NULL; |
2694 | obj->size >> PAGE_SHIFT, | 2764 | |
2695 | obj_priv->gtt_space->start, | 2765 | ret = i915_gem_evict_something(dev, size, |
2696 | obj_priv->agp_type); | 2766 | alignment, map_and_fenceable); |
2697 | if (obj_priv->agp_mem == NULL) { | ||
2698 | i915_gem_object_put_pages(obj); | ||
2699 | drm_mm_put_block(obj_priv->gtt_space); | ||
2700 | obj_priv->gtt_space = NULL; | ||
2701 | |||
2702 | ret = i915_gem_evict_something(dev, obj->size, alignment); | ||
2703 | if (ret) | 2767 | if (ret) |
2704 | return ret; | 2768 | return ret; |
2705 | 2769 | ||
2706 | goto search_free; | 2770 | goto search_free; |
2707 | } | 2771 | } |
2708 | 2772 | ||
2709 | /* keep track of bounds object by adding it to the inactive list */ | 2773 | list_add_tail(&obj->gtt_list, &dev_priv->mm.gtt_list); |
2710 | list_add_tail(&obj_priv->mm_list, &dev_priv->mm.inactive_list); | 2774 | list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); |
2711 | i915_gem_info_add_gtt(dev_priv, obj->size); | ||
2712 | 2775 | ||
2713 | /* Assert that the object is not currently in any GPU domain. As it | 2776 | /* Assert that the object is not currently in any GPU domain. As it |
2714 | * wasn't in the GTT, there shouldn't be any way it could have been in | 2777 | * wasn't in the GTT, there shouldn't be any way it could have been in |
2715 | * a GPU cache | 2778 | * a GPU cache |
2716 | */ | 2779 | */ |
2717 | BUG_ON(obj->read_domains & I915_GEM_GPU_DOMAINS); | 2780 | BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS); |
2718 | BUG_ON(obj->write_domain & I915_GEM_GPU_DOMAINS); | 2781 | BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS); |
2719 | 2782 | ||
2720 | obj_priv->gtt_offset = obj_priv->gtt_space->start; | 2783 | obj->gtt_offset = obj->gtt_space->start; |
2721 | trace_i915_gem_object_bind(obj, obj_priv->gtt_offset); | ||
2722 | 2784 | ||
2785 | fenceable = | ||
2786 | obj->gtt_space->size == fence_size && | ||
2787 | (obj->gtt_space->start & (fence_alignment -1)) == 0; | ||
2788 | |||
2789 | mappable = | ||
2790 | obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; | ||
2791 | |||
2792 | obj->map_and_fenceable = mappable && fenceable; | ||
2793 | |||
2794 | trace_i915_gem_object_bind(obj, obj->gtt_offset, map_and_fenceable); | ||
2723 | return 0; | 2795 | return 0; |
2724 | } | 2796 | } |
2725 | 2797 | ||
2726 | void | 2798 | void |
2727 | i915_gem_clflush_object(struct drm_gem_object *obj) | 2799 | i915_gem_clflush_object(struct drm_i915_gem_object *obj) |
2728 | { | 2800 | { |
2729 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
2730 | |||
2731 | /* If we don't have a page list set up, then we're not pinned | 2801 | /* If we don't have a page list set up, then we're not pinned |
2732 | * to GPU, and we can ignore the cache flush because it'll happen | 2802 | * to GPU, and we can ignore the cache flush because it'll happen |
2733 | * again at bind time. | 2803 | * again at bind time. |
2734 | */ | 2804 | */ |
2735 | if (obj_priv->pages == NULL) | 2805 | if (obj->pages == NULL) |
2736 | return; | 2806 | return; |
2737 | 2807 | ||
2738 | trace_i915_gem_object_clflush(obj); | 2808 | trace_i915_gem_object_clflush(obj); |
2739 | 2809 | ||
2740 | drm_clflush_pages(obj_priv->pages, obj->size / PAGE_SIZE); | 2810 | drm_clflush_pages(obj->pages, obj->base.size / PAGE_SIZE); |
2741 | } | 2811 | } |
2742 | 2812 | ||
2743 | /** Flushes any GPU write domain for the object if it's dirty. */ | 2813 | /** Flushes any GPU write domain for the object if it's dirty. */ |
2744 | static int | 2814 | static void |
2745 | i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj, | 2815 | i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj) |
2746 | bool pipelined) | ||
2747 | { | 2816 | { |
2748 | struct drm_device *dev = obj->dev; | 2817 | struct drm_device *dev = obj->base.dev; |
2749 | uint32_t old_write_domain; | ||
2750 | 2818 | ||
2751 | if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) | 2819 | if ((obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0) |
2752 | return 0; | 2820 | return; |
2753 | 2821 | ||
2754 | /* Queue the GPU write cache flushing we need. */ | 2822 | /* Queue the GPU write cache flushing we need. */ |
2755 | old_write_domain = obj->write_domain; | 2823 | i915_gem_flush_ring(dev, obj->ring, 0, obj->base.write_domain); |
2756 | i915_gem_flush_ring(dev, NULL, | 2824 | BUG_ON(obj->base.write_domain); |
2757 | to_intel_bo(obj)->ring, | ||
2758 | 0, obj->write_domain); | ||
2759 | BUG_ON(obj->write_domain); | ||
2760 | |||
2761 | trace_i915_gem_object_change_domain(obj, | ||
2762 | obj->read_domains, | ||
2763 | old_write_domain); | ||
2764 | |||
2765 | if (pipelined) | ||
2766 | return 0; | ||
2767 | |||
2768 | return i915_gem_object_wait_rendering(obj, true); | ||
2769 | } | 2825 | } |
2770 | 2826 | ||
2771 | /** Flushes the GTT write domain for the object if it's dirty. */ | 2827 | /** Flushes the GTT write domain for the object if it's dirty. */ |
2772 | static void | 2828 | static void |
2773 | i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj) | 2829 | i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj) |
2774 | { | 2830 | { |
2775 | uint32_t old_write_domain; | 2831 | uint32_t old_write_domain; |
2776 | 2832 | ||
2777 | if (obj->write_domain != I915_GEM_DOMAIN_GTT) | 2833 | if (obj->base.write_domain != I915_GEM_DOMAIN_GTT) |
2778 | return; | 2834 | return; |
2779 | 2835 | ||
2780 | /* No actual flushing is required for the GTT write domain. Writes | 2836 | /* No actual flushing is required for the GTT write domain. Writes |
2781 | * to it immediately go to main memory as far as we know, so there's | 2837 | * to it immediately go to main memory as far as we know, so there's |
2782 | * no chipset flush. It also doesn't land in render cache. | 2838 | * no chipset flush. It also doesn't land in render cache. |
2783 | */ | 2839 | */ |
2784 | old_write_domain = obj->write_domain; | 2840 | i915_gem_release_mmap(obj); |
2785 | obj->write_domain = 0; | 2841 | |
2842 | old_write_domain = obj->base.write_domain; | ||
2843 | obj->base.write_domain = 0; | ||
2786 | 2844 | ||
2787 | trace_i915_gem_object_change_domain(obj, | 2845 | trace_i915_gem_object_change_domain(obj, |
2788 | obj->read_domains, | 2846 | obj->base.read_domains, |
2789 | old_write_domain); | 2847 | old_write_domain); |
2790 | } | 2848 | } |
2791 | 2849 | ||
2792 | /** Flushes the CPU write domain for the object if it's dirty. */ | 2850 | /** Flushes the CPU write domain for the object if it's dirty. */ |
2793 | static void | 2851 | static void |
2794 | i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj) | 2852 | i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj) |
2795 | { | 2853 | { |
2796 | struct drm_device *dev = obj->dev; | ||
2797 | uint32_t old_write_domain; | 2854 | uint32_t old_write_domain; |
2798 | 2855 | ||
2799 | if (obj->write_domain != I915_GEM_DOMAIN_CPU) | 2856 | if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) |
2800 | return; | 2857 | return; |
2801 | 2858 | ||
2802 | i915_gem_clflush_object(obj); | 2859 | i915_gem_clflush_object(obj); |
2803 | drm_agp_chipset_flush(dev); | 2860 | intel_gtt_chipset_flush(); |
2804 | old_write_domain = obj->write_domain; | 2861 | old_write_domain = obj->base.write_domain; |
2805 | obj->write_domain = 0; | 2862 | obj->base.write_domain = 0; |
2806 | 2863 | ||
2807 | trace_i915_gem_object_change_domain(obj, | 2864 | trace_i915_gem_object_change_domain(obj, |
2808 | obj->read_domains, | 2865 | obj->base.read_domains, |
2809 | old_write_domain); | 2866 | old_write_domain); |
2810 | } | 2867 | } |
2811 | 2868 | ||
@@ -2816,40 +2873,36 @@ i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj) | |||
2816 | * flushes to occur. | 2873 | * flushes to occur. |
2817 | */ | 2874 | */ |
2818 | int | 2875 | int |
2819 | i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) | 2876 | i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) |
2820 | { | 2877 | { |
2821 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
2822 | uint32_t old_write_domain, old_read_domains; | 2878 | uint32_t old_write_domain, old_read_domains; |
2823 | int ret; | 2879 | int ret; |
2824 | 2880 | ||
2825 | /* Not valid to be called on unbound objects. */ | 2881 | /* Not valid to be called on unbound objects. */ |
2826 | if (obj_priv->gtt_space == NULL) | 2882 | if (obj->gtt_space == NULL) |
2827 | return -EINVAL; | 2883 | return -EINVAL; |
2828 | 2884 | ||
2829 | ret = i915_gem_object_flush_gpu_write_domain(obj, false); | 2885 | i915_gem_object_flush_gpu_write_domain(obj); |
2830 | if (ret != 0) | 2886 | if (obj->pending_gpu_write || write) { |
2831 | return ret; | ||
2832 | |||
2833 | i915_gem_object_flush_cpu_write_domain(obj); | ||
2834 | |||
2835 | if (write) { | ||
2836 | ret = i915_gem_object_wait_rendering(obj, true); | 2887 | ret = i915_gem_object_wait_rendering(obj, true); |
2837 | if (ret) | 2888 | if (ret) |
2838 | return ret; | 2889 | return ret; |
2839 | } | 2890 | } |
2840 | 2891 | ||
2841 | old_write_domain = obj->write_domain; | 2892 | i915_gem_object_flush_cpu_write_domain(obj); |
2842 | old_read_domains = obj->read_domains; | 2893 | |
2894 | old_write_domain = obj->base.write_domain; | ||
2895 | old_read_domains = obj->base.read_domains; | ||
2843 | 2896 | ||
2844 | /* It should now be out of any other write domains, and we can update | 2897 | /* It should now be out of any other write domains, and we can update |
2845 | * the domain values for our changes. | 2898 | * the domain values for our changes. |
2846 | */ | 2899 | */ |
2847 | BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0); | 2900 | BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) != 0); |
2848 | obj->read_domains |= I915_GEM_DOMAIN_GTT; | 2901 | obj->base.read_domains |= I915_GEM_DOMAIN_GTT; |
2849 | if (write) { | 2902 | if (write) { |
2850 | obj->read_domains = I915_GEM_DOMAIN_GTT; | 2903 | obj->base.read_domains = I915_GEM_DOMAIN_GTT; |
2851 | obj->write_domain = I915_GEM_DOMAIN_GTT; | 2904 | obj->base.write_domain = I915_GEM_DOMAIN_GTT; |
2852 | obj_priv->dirty = 1; | 2905 | obj->dirty = 1; |
2853 | } | 2906 | } |
2854 | 2907 | ||
2855 | trace_i915_gem_object_change_domain(obj, | 2908 | trace_i915_gem_object_change_domain(obj, |
@@ -2864,23 +2917,20 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) | |||
2864 | * wait, as in modesetting process we're not supposed to be interrupted. | 2917 | * wait, as in modesetting process we're not supposed to be interrupted. |
2865 | */ | 2918 | */ |
2866 | int | 2919 | int |
2867 | i915_gem_object_set_to_display_plane(struct drm_gem_object *obj, | 2920 | i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj, |
2868 | bool pipelined) | 2921 | struct intel_ring_buffer *pipelined) |
2869 | { | 2922 | { |
2870 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
2871 | uint32_t old_read_domains; | 2923 | uint32_t old_read_domains; |
2872 | int ret; | 2924 | int ret; |
2873 | 2925 | ||
2874 | /* Not valid to be called on unbound objects. */ | 2926 | /* Not valid to be called on unbound objects. */ |
2875 | if (obj_priv->gtt_space == NULL) | 2927 | if (obj->gtt_space == NULL) |
2876 | return -EINVAL; | 2928 | return -EINVAL; |
2877 | 2929 | ||
2878 | ret = i915_gem_object_flush_gpu_write_domain(obj, true); | 2930 | i915_gem_object_flush_gpu_write_domain(obj); |
2879 | if (ret) | ||
2880 | return ret; | ||
2881 | 2931 | ||
2882 | /* Currently, we are always called from an non-interruptible context. */ | 2932 | /* Currently, we are always called from an non-interruptible context. */ |
2883 | if (!pipelined) { | 2933 | if (pipelined != obj->ring) { |
2884 | ret = i915_gem_object_wait_rendering(obj, false); | 2934 | ret = i915_gem_object_wait_rendering(obj, false); |
2885 | if (ret) | 2935 | if (ret) |
2886 | return ret; | 2936 | return ret; |
@@ -2888,12 +2938,12 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj, | |||
2888 | 2938 | ||
2889 | i915_gem_object_flush_cpu_write_domain(obj); | 2939 | i915_gem_object_flush_cpu_write_domain(obj); |
2890 | 2940 | ||
2891 | old_read_domains = obj->read_domains; | 2941 | old_read_domains = obj->base.read_domains; |
2892 | obj->read_domains |= I915_GEM_DOMAIN_GTT; | 2942 | obj->base.read_domains |= I915_GEM_DOMAIN_GTT; |
2893 | 2943 | ||
2894 | trace_i915_gem_object_change_domain(obj, | 2944 | trace_i915_gem_object_change_domain(obj, |
2895 | old_read_domains, | 2945 | old_read_domains, |
2896 | obj->write_domain); | 2946 | obj->base.write_domain); |
2897 | 2947 | ||
2898 | return 0; | 2948 | return 0; |
2899 | } | 2949 | } |
@@ -2906,10 +2956,10 @@ i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj, | |||
2906 | return 0; | 2956 | return 0; |
2907 | 2957 | ||
2908 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) | 2958 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) |
2909 | i915_gem_flush_ring(obj->base.dev, NULL, obj->ring, | 2959 | i915_gem_flush_ring(obj->base.dev, obj->ring, |
2910 | 0, obj->base.write_domain); | 2960 | 0, obj->base.write_domain); |
2911 | 2961 | ||
2912 | return i915_gem_object_wait_rendering(&obj->base, interruptible); | 2962 | return i915_gem_object_wait_rendering(obj, interruptible); |
2913 | } | 2963 | } |
2914 | 2964 | ||
2915 | /** | 2965 | /** |
@@ -2919,13 +2969,14 @@ i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj, | |||
2919 | * flushes to occur. | 2969 | * flushes to occur. |
2920 | */ | 2970 | */ |
2921 | static int | 2971 | static int |
2922 | i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) | 2972 | i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) |
2923 | { | 2973 | { |
2924 | uint32_t old_write_domain, old_read_domains; | 2974 | uint32_t old_write_domain, old_read_domains; |
2925 | int ret; | 2975 | int ret; |
2926 | 2976 | ||
2927 | ret = i915_gem_object_flush_gpu_write_domain(obj, false); | 2977 | i915_gem_object_flush_gpu_write_domain(obj); |
2928 | if (ret != 0) | 2978 | ret = i915_gem_object_wait_rendering(obj, true); |
2979 | if (ret) | ||
2929 | return ret; | 2980 | return ret; |
2930 | 2981 | ||
2931 | i915_gem_object_flush_gtt_write_domain(obj); | 2982 | i915_gem_object_flush_gtt_write_domain(obj); |
@@ -2935,33 +2986,27 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) | |||
2935 | */ | 2986 | */ |
2936 | i915_gem_object_set_to_full_cpu_read_domain(obj); | 2987 | i915_gem_object_set_to_full_cpu_read_domain(obj); |
2937 | 2988 | ||
2938 | if (write) { | 2989 | old_write_domain = obj->base.write_domain; |
2939 | ret = i915_gem_object_wait_rendering(obj, true); | 2990 | old_read_domains = obj->base.read_domains; |
2940 | if (ret) | ||
2941 | return ret; | ||
2942 | } | ||
2943 | |||
2944 | old_write_domain = obj->write_domain; | ||
2945 | old_read_domains = obj->read_domains; | ||
2946 | 2991 | ||
2947 | /* Flush the CPU cache if it's still invalid. */ | 2992 | /* Flush the CPU cache if it's still invalid. */ |
2948 | if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) { | 2993 | if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) { |
2949 | i915_gem_clflush_object(obj); | 2994 | i915_gem_clflush_object(obj); |
2950 | 2995 | ||
2951 | obj->read_domains |= I915_GEM_DOMAIN_CPU; | 2996 | obj->base.read_domains |= I915_GEM_DOMAIN_CPU; |
2952 | } | 2997 | } |
2953 | 2998 | ||
2954 | /* It should now be out of any other write domains, and we can update | 2999 | /* It should now be out of any other write domains, and we can update |
2955 | * the domain values for our changes. | 3000 | * the domain values for our changes. |
2956 | */ | 3001 | */ |
2957 | BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_CPU) != 0); | 3002 | BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_CPU) != 0); |
2958 | 3003 | ||
2959 | /* If we're writing through the CPU, then the GPU read domains will | 3004 | /* If we're writing through the CPU, then the GPU read domains will |
2960 | * need to be invalidated at next use. | 3005 | * need to be invalidated at next use. |
2961 | */ | 3006 | */ |
2962 | if (write) { | 3007 | if (write) { |
2963 | obj->read_domains = I915_GEM_DOMAIN_CPU; | 3008 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; |
2964 | obj->write_domain = I915_GEM_DOMAIN_CPU; | 3009 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; |
2965 | } | 3010 | } |
2966 | 3011 | ||
2967 | trace_i915_gem_object_change_domain(obj, | 3012 | trace_i915_gem_object_change_domain(obj, |
@@ -2971,184 +3016,6 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) | |||
2971 | return 0; | 3016 | return 0; |
2972 | } | 3017 | } |
2973 | 3018 | ||
2974 | /* | ||
2975 | * Set the next domain for the specified object. This | ||
2976 | * may not actually perform the necessary flushing/invaliding though, | ||
2977 | * as that may want to be batched with other set_domain operations | ||
2978 | * | ||
2979 | * This is (we hope) the only really tricky part of gem. The goal | ||
2980 | * is fairly simple -- track which caches hold bits of the object | ||
2981 | * and make sure they remain coherent. A few concrete examples may | ||
2982 | * help to explain how it works. For shorthand, we use the notation | ||
2983 | * (read_domains, write_domain), e.g. (CPU, CPU) to indicate the | ||
2984 | * a pair of read and write domain masks. | ||
2985 | * | ||
2986 | * Case 1: the batch buffer | ||
2987 | * | ||
2988 | * 1. Allocated | ||
2989 | * 2. Written by CPU | ||
2990 | * 3. Mapped to GTT | ||
2991 | * 4. Read by GPU | ||
2992 | * 5. Unmapped from GTT | ||
2993 | * 6. Freed | ||
2994 | * | ||
2995 | * Let's take these a step at a time | ||
2996 | * | ||
2997 | * 1. Allocated | ||
2998 | * Pages allocated from the kernel may still have | ||
2999 | * cache contents, so we set them to (CPU, CPU) always. | ||
3000 | * 2. Written by CPU (using pwrite) | ||
3001 | * The pwrite function calls set_domain (CPU, CPU) and | ||
3002 | * this function does nothing (as nothing changes) | ||
3003 | * 3. Mapped by GTT | ||
3004 | * This function asserts that the object is not | ||
3005 | * currently in any GPU-based read or write domains | ||
3006 | * 4. Read by GPU | ||
3007 | * i915_gem_execbuffer calls set_domain (COMMAND, 0). | ||
3008 | * As write_domain is zero, this function adds in the | ||
3009 | * current read domains (CPU+COMMAND, 0). | ||
3010 | * flush_domains is set to CPU. | ||
3011 | * invalidate_domains is set to COMMAND | ||
3012 | * clflush is run to get data out of the CPU caches | ||
3013 | * then i915_dev_set_domain calls i915_gem_flush to | ||
3014 | * emit an MI_FLUSH and drm_agp_chipset_flush | ||
3015 | * 5. Unmapped from GTT | ||
3016 | * i915_gem_object_unbind calls set_domain (CPU, CPU) | ||
3017 | * flush_domains and invalidate_domains end up both zero | ||
3018 | * so no flushing/invalidating happens | ||
3019 | * 6. Freed | ||
3020 | * yay, done | ||
3021 | * | ||
3022 | * Case 2: The shared render buffer | ||
3023 | * | ||
3024 | * 1. Allocated | ||
3025 | * 2. Mapped to GTT | ||
3026 | * 3. Read/written by GPU | ||
3027 | * 4. set_domain to (CPU,CPU) | ||
3028 | * 5. Read/written by CPU | ||
3029 | * 6. Read/written by GPU | ||
3030 | * | ||
3031 | * 1. Allocated | ||
3032 | * Same as last example, (CPU, CPU) | ||
3033 | * 2. Mapped to GTT | ||
3034 | * Nothing changes (assertions find that it is not in the GPU) | ||
3035 | * 3. Read/written by GPU | ||
3036 | * execbuffer calls set_domain (RENDER, RENDER) | ||
3037 | * flush_domains gets CPU | ||
3038 | * invalidate_domains gets GPU | ||
3039 | * clflush (obj) | ||
3040 | * MI_FLUSH and drm_agp_chipset_flush | ||
3041 | * 4. set_domain (CPU, CPU) | ||
3042 | * flush_domains gets GPU | ||
3043 | * invalidate_domains gets CPU | ||
3044 | * wait_rendering (obj) to make sure all drawing is complete. | ||
3045 | * This will include an MI_FLUSH to get the data from GPU | ||
3046 | * to memory | ||
3047 | * clflush (obj) to invalidate the CPU cache | ||
3048 | * Another MI_FLUSH in i915_gem_flush (eliminate this somehow?) | ||
3049 | * 5. Read/written by CPU | ||
3050 | * cache lines are loaded and dirtied | ||
3051 | * 6. Read written by GPU | ||
3052 | * Same as last GPU access | ||
3053 | * | ||
3054 | * Case 3: The constant buffer | ||
3055 | * | ||
3056 | * 1. Allocated | ||
3057 | * 2. Written by CPU | ||
3058 | * 3. Read by GPU | ||
3059 | * 4. Updated (written) by CPU again | ||
3060 | * 5. Read by GPU | ||
3061 | * | ||
3062 | * 1. Allocated | ||
3063 | * (CPU, CPU) | ||
3064 | * 2. Written by CPU | ||
3065 | * (CPU, CPU) | ||
3066 | * 3. Read by GPU | ||
3067 | * (CPU+RENDER, 0) | ||
3068 | * flush_domains = CPU | ||
3069 | * invalidate_domains = RENDER | ||
3070 | * clflush (obj) | ||
3071 | * MI_FLUSH | ||
3072 | * drm_agp_chipset_flush | ||
3073 | * 4. Updated (written) by CPU again | ||
3074 | * (CPU, CPU) | ||
3075 | * flush_domains = 0 (no previous write domain) | ||
3076 | * invalidate_domains = 0 (no new read domains) | ||
3077 | * 5. Read by GPU | ||
3078 | * (CPU+RENDER, 0) | ||
3079 | * flush_domains = CPU | ||
3080 | * invalidate_domains = RENDER | ||
3081 | * clflush (obj) | ||
3082 | * MI_FLUSH | ||
3083 | * drm_agp_chipset_flush | ||
3084 | */ | ||
3085 | static void | ||
3086 | i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, | ||
3087 | struct intel_ring_buffer *ring) | ||
3088 | { | ||
3089 | struct drm_device *dev = obj->dev; | ||
3090 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3091 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
3092 | uint32_t invalidate_domains = 0; | ||
3093 | uint32_t flush_domains = 0; | ||
3094 | uint32_t old_read_domains; | ||
3095 | |||
3096 | intel_mark_busy(dev, obj); | ||
3097 | |||
3098 | /* | ||
3099 | * If the object isn't moving to a new write domain, | ||
3100 | * let the object stay in multiple read domains | ||
3101 | */ | ||
3102 | if (obj->pending_write_domain == 0) | ||
3103 | obj->pending_read_domains |= obj->read_domains; | ||
3104 | else | ||
3105 | obj_priv->dirty = 1; | ||
3106 | |||
3107 | /* | ||
3108 | * Flush the current write domain if | ||
3109 | * the new read domains don't match. Invalidate | ||
3110 | * any read domains which differ from the old | ||
3111 | * write domain | ||
3112 | */ | ||
3113 | if (obj->write_domain && | ||
3114 | (obj->write_domain != obj->pending_read_domains || | ||
3115 | obj_priv->ring != ring)) { | ||
3116 | flush_domains |= obj->write_domain; | ||
3117 | invalidate_domains |= | ||
3118 | obj->pending_read_domains & ~obj->write_domain; | ||
3119 | } | ||
3120 | /* | ||
3121 | * Invalidate any read caches which may have | ||
3122 | * stale data. That is, any new read domains. | ||
3123 | */ | ||
3124 | invalidate_domains |= obj->pending_read_domains & ~obj->read_domains; | ||
3125 | if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) | ||
3126 | i915_gem_clflush_object(obj); | ||
3127 | |||
3128 | old_read_domains = obj->read_domains; | ||
3129 | |||
3130 | /* The actual obj->write_domain will be updated with | ||
3131 | * pending_write_domain after we emit the accumulated flush for all | ||
3132 | * of our domain changes in execbuffers (which clears objects' | ||
3133 | * write_domains). So if we have a current write domain that we | ||
3134 | * aren't changing, set pending_write_domain to that. | ||
3135 | */ | ||
3136 | if (flush_domains == 0 && obj->pending_write_domain == 0) | ||
3137 | obj->pending_write_domain = obj->write_domain; | ||
3138 | obj->read_domains = obj->pending_read_domains; | ||
3139 | |||
3140 | dev->invalidate_domains |= invalidate_domains; | ||
3141 | dev->flush_domains |= flush_domains; | ||
3142 | if (flush_domains & I915_GEM_GPU_DOMAINS) | ||
3143 | dev_priv->mm.flush_rings |= obj_priv->ring->id; | ||
3144 | if (invalidate_domains & I915_GEM_GPU_DOMAINS) | ||
3145 | dev_priv->mm.flush_rings |= ring->id; | ||
3146 | |||
3147 | trace_i915_gem_object_change_domain(obj, | ||
3148 | old_read_domains, | ||
3149 | obj->write_domain); | ||
3150 | } | ||
3151 | |||
3152 | /** | 3019 | /** |
3153 | * Moves the object from a partially CPU read to a full one. | 3020 | * Moves the object from a partially CPU read to a full one. |
3154 | * | 3021 | * |
@@ -3156,30 +3023,28 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, | |||
3156 | * and doesn't handle transitioning from !(read_domains & I915_GEM_DOMAIN_CPU). | 3023 | * and doesn't handle transitioning from !(read_domains & I915_GEM_DOMAIN_CPU). |
3157 | */ | 3024 | */ |
3158 | static void | 3025 | static void |
3159 | i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj) | 3026 | i915_gem_object_set_to_full_cpu_read_domain(struct drm_i915_gem_object *obj) |
3160 | { | 3027 | { |
3161 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 3028 | if (!obj->page_cpu_valid) |
3162 | |||
3163 | if (!obj_priv->page_cpu_valid) | ||
3164 | return; | 3029 | return; |
3165 | 3030 | ||
3166 | /* If we're partially in the CPU read domain, finish moving it in. | 3031 | /* If we're partially in the CPU read domain, finish moving it in. |
3167 | */ | 3032 | */ |
3168 | if (obj->read_domains & I915_GEM_DOMAIN_CPU) { | 3033 | if (obj->base.read_domains & I915_GEM_DOMAIN_CPU) { |
3169 | int i; | 3034 | int i; |
3170 | 3035 | ||
3171 | for (i = 0; i <= (obj->size - 1) / PAGE_SIZE; i++) { | 3036 | for (i = 0; i <= (obj->base.size - 1) / PAGE_SIZE; i++) { |
3172 | if (obj_priv->page_cpu_valid[i]) | 3037 | if (obj->page_cpu_valid[i]) |
3173 | continue; | 3038 | continue; |
3174 | drm_clflush_pages(obj_priv->pages + i, 1); | 3039 | drm_clflush_pages(obj->pages + i, 1); |
3175 | } | 3040 | } |
3176 | } | 3041 | } |
3177 | 3042 | ||
3178 | /* Free the page_cpu_valid mappings which are now stale, whether | 3043 | /* Free the page_cpu_valid mappings which are now stale, whether |
3179 | * or not we've got I915_GEM_DOMAIN_CPU. | 3044 | * or not we've got I915_GEM_DOMAIN_CPU. |
3180 | */ | 3045 | */ |
3181 | kfree(obj_priv->page_cpu_valid); | 3046 | kfree(obj->page_cpu_valid); |
3182 | obj_priv->page_cpu_valid = NULL; | 3047 | obj->page_cpu_valid = NULL; |
3183 | } | 3048 | } |
3184 | 3049 | ||
3185 | /** | 3050 | /** |
@@ -3195,354 +3060,62 @@ i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj) | |||
3195 | * flushes to occur. | 3060 | * flushes to occur. |
3196 | */ | 3061 | */ |
3197 | static int | 3062 | static int |
3198 | i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, | 3063 | i915_gem_object_set_cpu_read_domain_range(struct drm_i915_gem_object *obj, |
3199 | uint64_t offset, uint64_t size) | 3064 | uint64_t offset, uint64_t size) |
3200 | { | 3065 | { |
3201 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
3202 | uint32_t old_read_domains; | 3066 | uint32_t old_read_domains; |
3203 | int i, ret; | 3067 | int i, ret; |
3204 | 3068 | ||
3205 | if (offset == 0 && size == obj->size) | 3069 | if (offset == 0 && size == obj->base.size) |
3206 | return i915_gem_object_set_to_cpu_domain(obj, 0); | 3070 | return i915_gem_object_set_to_cpu_domain(obj, 0); |
3207 | 3071 | ||
3208 | ret = i915_gem_object_flush_gpu_write_domain(obj, false); | 3072 | i915_gem_object_flush_gpu_write_domain(obj); |
3209 | if (ret != 0) | 3073 | ret = i915_gem_object_wait_rendering(obj, true); |
3074 | if (ret) | ||
3210 | return ret; | 3075 | return ret; |
3076 | |||
3211 | i915_gem_object_flush_gtt_write_domain(obj); | 3077 | i915_gem_object_flush_gtt_write_domain(obj); |
3212 | 3078 | ||
3213 | /* If we're already fully in the CPU read domain, we're done. */ | 3079 | /* If we're already fully in the CPU read domain, we're done. */ |
3214 | if (obj_priv->page_cpu_valid == NULL && | 3080 | if (obj->page_cpu_valid == NULL && |
3215 | (obj->read_domains & I915_GEM_DOMAIN_CPU) != 0) | 3081 | (obj->base.read_domains & I915_GEM_DOMAIN_CPU) != 0) |
3216 | return 0; | 3082 | return 0; |
3217 | 3083 | ||
3218 | /* Otherwise, create/clear the per-page CPU read domain flag if we're | 3084 | /* Otherwise, create/clear the per-page CPU read domain flag if we're |
3219 | * newly adding I915_GEM_DOMAIN_CPU | 3085 | * newly adding I915_GEM_DOMAIN_CPU |
3220 | */ | 3086 | */ |
3221 | if (obj_priv->page_cpu_valid == NULL) { | 3087 | if (obj->page_cpu_valid == NULL) { |
3222 | obj_priv->page_cpu_valid = kzalloc(obj->size / PAGE_SIZE, | 3088 | obj->page_cpu_valid = kzalloc(obj->base.size / PAGE_SIZE, |
3223 | GFP_KERNEL); | 3089 | GFP_KERNEL); |
3224 | if (obj_priv->page_cpu_valid == NULL) | 3090 | if (obj->page_cpu_valid == NULL) |
3225 | return -ENOMEM; | 3091 | return -ENOMEM; |
3226 | } else if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) | 3092 | } else if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) |
3227 | memset(obj_priv->page_cpu_valid, 0, obj->size / PAGE_SIZE); | 3093 | memset(obj->page_cpu_valid, 0, obj->base.size / PAGE_SIZE); |
3228 | 3094 | ||
3229 | /* Flush the cache on any pages that are still invalid from the CPU's | 3095 | /* Flush the cache on any pages that are still invalid from the CPU's |
3230 | * perspective. | 3096 | * perspective. |
3231 | */ | 3097 | */ |
3232 | for (i = offset / PAGE_SIZE; i <= (offset + size - 1) / PAGE_SIZE; | 3098 | for (i = offset / PAGE_SIZE; i <= (offset + size - 1) / PAGE_SIZE; |
3233 | i++) { | 3099 | i++) { |
3234 | if (obj_priv->page_cpu_valid[i]) | 3100 | if (obj->page_cpu_valid[i]) |
3235 | continue; | 3101 | continue; |
3236 | 3102 | ||
3237 | drm_clflush_pages(obj_priv->pages + i, 1); | 3103 | drm_clflush_pages(obj->pages + i, 1); |
3238 | 3104 | ||
3239 | obj_priv->page_cpu_valid[i] = 1; | 3105 | obj->page_cpu_valid[i] = 1; |
3240 | } | 3106 | } |
3241 | 3107 | ||
3242 | /* It should now be out of any other write domains, and we can update | 3108 | /* It should now be out of any other write domains, and we can update |
3243 | * the domain values for our changes. | 3109 | * the domain values for our changes. |
3244 | */ | 3110 | */ |
3245 | BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_CPU) != 0); | 3111 | BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_CPU) != 0); |
3246 | 3112 | ||
3247 | old_read_domains = obj->read_domains; | 3113 | old_read_domains = obj->base.read_domains; |
3248 | obj->read_domains |= I915_GEM_DOMAIN_CPU; | 3114 | obj->base.read_domains |= I915_GEM_DOMAIN_CPU; |
3249 | 3115 | ||
3250 | trace_i915_gem_object_change_domain(obj, | 3116 | trace_i915_gem_object_change_domain(obj, |
3251 | old_read_domains, | 3117 | old_read_domains, |
3252 | obj->write_domain); | 3118 | obj->base.write_domain); |
3253 | |||
3254 | return 0; | ||
3255 | } | ||
3256 | |||
3257 | /** | ||
3258 | * Pin an object to the GTT and evaluate the relocations landing in it. | ||
3259 | */ | ||
3260 | static int | ||
3261 | i915_gem_execbuffer_relocate(struct drm_i915_gem_object *obj, | ||
3262 | struct drm_file *file_priv, | ||
3263 | struct drm_i915_gem_exec_object2 *entry) | ||
3264 | { | ||
3265 | struct drm_device *dev = obj->base.dev; | ||
3266 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3267 | struct drm_i915_gem_relocation_entry __user *user_relocs; | ||
3268 | struct drm_gem_object *target_obj = NULL; | ||
3269 | uint32_t target_handle = 0; | ||
3270 | int i, ret = 0; | ||
3271 | |||
3272 | user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr; | ||
3273 | for (i = 0; i < entry->relocation_count; i++) { | ||
3274 | struct drm_i915_gem_relocation_entry reloc; | ||
3275 | uint32_t target_offset; | ||
3276 | |||
3277 | if (__copy_from_user_inatomic(&reloc, | ||
3278 | user_relocs+i, | ||
3279 | sizeof(reloc))) { | ||
3280 | ret = -EFAULT; | ||
3281 | break; | ||
3282 | } | ||
3283 | |||
3284 | if (reloc.target_handle != target_handle) { | ||
3285 | drm_gem_object_unreference(target_obj); | ||
3286 | |||
3287 | target_obj = drm_gem_object_lookup(dev, file_priv, | ||
3288 | reloc.target_handle); | ||
3289 | if (target_obj == NULL) { | ||
3290 | ret = -ENOENT; | ||
3291 | break; | ||
3292 | } | ||
3293 | |||
3294 | target_handle = reloc.target_handle; | ||
3295 | } | ||
3296 | target_offset = to_intel_bo(target_obj)->gtt_offset; | ||
3297 | |||
3298 | #if WATCH_RELOC | ||
3299 | DRM_INFO("%s: obj %p offset %08x target %d " | ||
3300 | "read %08x write %08x gtt %08x " | ||
3301 | "presumed %08x delta %08x\n", | ||
3302 | __func__, | ||
3303 | obj, | ||
3304 | (int) reloc.offset, | ||
3305 | (int) reloc.target_handle, | ||
3306 | (int) reloc.read_domains, | ||
3307 | (int) reloc.write_domain, | ||
3308 | (int) target_offset, | ||
3309 | (int) reloc.presumed_offset, | ||
3310 | reloc.delta); | ||
3311 | #endif | ||
3312 | |||
3313 | /* The target buffer should have appeared before us in the | ||
3314 | * exec_object list, so it should have a GTT space bound by now. | ||
3315 | */ | ||
3316 | if (target_offset == 0) { | ||
3317 | DRM_ERROR("No GTT space found for object %d\n", | ||
3318 | reloc.target_handle); | ||
3319 | ret = -EINVAL; | ||
3320 | break; | ||
3321 | } | ||
3322 | |||
3323 | /* Validate that the target is in a valid r/w GPU domain */ | ||
3324 | if (reloc.write_domain & (reloc.write_domain - 1)) { | ||
3325 | DRM_ERROR("reloc with multiple write domains: " | ||
3326 | "obj %p target %d offset %d " | ||
3327 | "read %08x write %08x", | ||
3328 | obj, reloc.target_handle, | ||
3329 | (int) reloc.offset, | ||
3330 | reloc.read_domains, | ||
3331 | reloc.write_domain); | ||
3332 | ret = -EINVAL; | ||
3333 | break; | ||
3334 | } | ||
3335 | if (reloc.write_domain & I915_GEM_DOMAIN_CPU || | ||
3336 | reloc.read_domains & I915_GEM_DOMAIN_CPU) { | ||
3337 | DRM_ERROR("reloc with read/write CPU domains: " | ||
3338 | "obj %p target %d offset %d " | ||
3339 | "read %08x write %08x", | ||
3340 | obj, reloc.target_handle, | ||
3341 | (int) reloc.offset, | ||
3342 | reloc.read_domains, | ||
3343 | reloc.write_domain); | ||
3344 | ret = -EINVAL; | ||
3345 | break; | ||
3346 | } | ||
3347 | if (reloc.write_domain && target_obj->pending_write_domain && | ||
3348 | reloc.write_domain != target_obj->pending_write_domain) { | ||
3349 | DRM_ERROR("Write domain conflict: " | ||
3350 | "obj %p target %d offset %d " | ||
3351 | "new %08x old %08x\n", | ||
3352 | obj, reloc.target_handle, | ||
3353 | (int) reloc.offset, | ||
3354 | reloc.write_domain, | ||
3355 | target_obj->pending_write_domain); | ||
3356 | ret = -EINVAL; | ||
3357 | break; | ||
3358 | } | ||
3359 | |||
3360 | target_obj->pending_read_domains |= reloc.read_domains; | ||
3361 | target_obj->pending_write_domain |= reloc.write_domain; | ||
3362 | |||
3363 | /* If the relocation already has the right value in it, no | ||
3364 | * more work needs to be done. | ||
3365 | */ | ||
3366 | if (target_offset == reloc.presumed_offset) | ||
3367 | continue; | ||
3368 | |||
3369 | /* Check that the relocation address is valid... */ | ||
3370 | if (reloc.offset > obj->base.size - 4) { | ||
3371 | DRM_ERROR("Relocation beyond object bounds: " | ||
3372 | "obj %p target %d offset %d size %d.\n", | ||
3373 | obj, reloc.target_handle, | ||
3374 | (int) reloc.offset, (int) obj->base.size); | ||
3375 | ret = -EINVAL; | ||
3376 | break; | ||
3377 | } | ||
3378 | if (reloc.offset & 3) { | ||
3379 | DRM_ERROR("Relocation not 4-byte aligned: " | ||
3380 | "obj %p target %d offset %d.\n", | ||
3381 | obj, reloc.target_handle, | ||
3382 | (int) reloc.offset); | ||
3383 | ret = -EINVAL; | ||
3384 | break; | ||
3385 | } | ||
3386 | |||
3387 | /* and points to somewhere within the target object. */ | ||
3388 | if (reloc.delta >= target_obj->size) { | ||
3389 | DRM_ERROR("Relocation beyond target object bounds: " | ||
3390 | "obj %p target %d delta %d size %d.\n", | ||
3391 | obj, reloc.target_handle, | ||
3392 | (int) reloc.delta, (int) target_obj->size); | ||
3393 | ret = -EINVAL; | ||
3394 | break; | ||
3395 | } | ||
3396 | |||
3397 | reloc.delta += target_offset; | ||
3398 | if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) { | ||
3399 | uint32_t page_offset = reloc.offset & ~PAGE_MASK; | ||
3400 | char *vaddr; | ||
3401 | |||
3402 | vaddr = kmap_atomic(obj->pages[reloc.offset >> PAGE_SHIFT]); | ||
3403 | *(uint32_t *)(vaddr + page_offset) = reloc.delta; | ||
3404 | kunmap_atomic(vaddr); | ||
3405 | } else { | ||
3406 | uint32_t __iomem *reloc_entry; | ||
3407 | void __iomem *reloc_page; | ||
3408 | |||
3409 | ret = i915_gem_object_set_to_gtt_domain(&obj->base, 1); | ||
3410 | if (ret) | ||
3411 | break; | ||
3412 | |||
3413 | /* Map the page containing the relocation we're going to perform. */ | ||
3414 | reloc.offset += obj->gtt_offset; | ||
3415 | reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, | ||
3416 | reloc.offset & PAGE_MASK); | ||
3417 | reloc_entry = (uint32_t __iomem *) | ||
3418 | (reloc_page + (reloc.offset & ~PAGE_MASK)); | ||
3419 | iowrite32(reloc.delta, reloc_entry); | ||
3420 | io_mapping_unmap_atomic(reloc_page); | ||
3421 | } | ||
3422 | |||
3423 | /* and update the user's relocation entry */ | ||
3424 | reloc.presumed_offset = target_offset; | ||
3425 | if (__copy_to_user_inatomic(&user_relocs[i].presumed_offset, | ||
3426 | &reloc.presumed_offset, | ||
3427 | sizeof(reloc.presumed_offset))) { | ||
3428 | ret = -EFAULT; | ||
3429 | break; | ||
3430 | } | ||
3431 | } | ||
3432 | |||
3433 | drm_gem_object_unreference(target_obj); | ||
3434 | return ret; | ||
3435 | } | ||
3436 | |||
3437 | static int | ||
3438 | i915_gem_execbuffer_pin(struct drm_device *dev, | ||
3439 | struct drm_file *file, | ||
3440 | struct drm_gem_object **object_list, | ||
3441 | struct drm_i915_gem_exec_object2 *exec_list, | ||
3442 | int count) | ||
3443 | { | ||
3444 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3445 | int ret, i, retry; | ||
3446 | |||
3447 | /* attempt to pin all of the buffers into the GTT */ | ||
3448 | for (retry = 0; retry < 2; retry++) { | ||
3449 | ret = 0; | ||
3450 | for (i = 0; i < count; i++) { | ||
3451 | struct drm_i915_gem_exec_object2 *entry = &exec_list[i]; | ||
3452 | struct drm_i915_gem_object *obj= to_intel_bo(object_list[i]); | ||
3453 | bool need_fence = | ||
3454 | entry->flags & EXEC_OBJECT_NEEDS_FENCE && | ||
3455 | obj->tiling_mode != I915_TILING_NONE; | ||
3456 | |||
3457 | /* Check fence reg constraints and rebind if necessary */ | ||
3458 | if (need_fence && | ||
3459 | !i915_gem_object_fence_offset_ok(&obj->base, | ||
3460 | obj->tiling_mode)) { | ||
3461 | ret = i915_gem_object_unbind(&obj->base); | ||
3462 | if (ret) | ||
3463 | break; | ||
3464 | } | ||
3465 | |||
3466 | ret = i915_gem_object_pin(&obj->base, entry->alignment); | ||
3467 | if (ret) | ||
3468 | break; | ||
3469 | |||
3470 | /* | ||
3471 | * Pre-965 chips need a fence register set up in order | ||
3472 | * to properly handle blits to/from tiled surfaces. | ||
3473 | */ | ||
3474 | if (need_fence) { | ||
3475 | ret = i915_gem_object_get_fence_reg(&obj->base, true); | ||
3476 | if (ret) { | ||
3477 | i915_gem_object_unpin(&obj->base); | ||
3478 | break; | ||
3479 | } | ||
3480 | |||
3481 | dev_priv->fence_regs[obj->fence_reg].gpu = true; | ||
3482 | } | ||
3483 | |||
3484 | entry->offset = obj->gtt_offset; | ||
3485 | } | ||
3486 | |||
3487 | while (i--) | ||
3488 | i915_gem_object_unpin(object_list[i]); | ||
3489 | |||
3490 | if (ret == 0) | ||
3491 | break; | ||
3492 | |||
3493 | if (ret != -ENOSPC || retry) | ||
3494 | return ret; | ||
3495 | |||
3496 | ret = i915_gem_evict_everything(dev); | ||
3497 | if (ret) | ||
3498 | return ret; | ||
3499 | } | ||
3500 | |||
3501 | return 0; | ||
3502 | } | ||
3503 | |||
3504 | static int | ||
3505 | i915_gem_execbuffer_move_to_gpu(struct drm_device *dev, | ||
3506 | struct drm_file *file, | ||
3507 | struct intel_ring_buffer *ring, | ||
3508 | struct drm_gem_object **objects, | ||
3509 | int count) | ||
3510 | { | ||
3511 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3512 | int ret, i; | ||
3513 | |||
3514 | /* Zero the global flush/invalidate flags. These | ||
3515 | * will be modified as new domains are computed | ||
3516 | * for each object | ||
3517 | */ | ||
3518 | dev->invalidate_domains = 0; | ||
3519 | dev->flush_domains = 0; | ||
3520 | dev_priv->mm.flush_rings = 0; | ||
3521 | for (i = 0; i < count; i++) | ||
3522 | i915_gem_object_set_to_gpu_domain(objects[i], ring); | ||
3523 | |||
3524 | if (dev->invalidate_domains | dev->flush_domains) { | ||
3525 | #if WATCH_EXEC | ||
3526 | DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", | ||
3527 | __func__, | ||
3528 | dev->invalidate_domains, | ||
3529 | dev->flush_domains); | ||
3530 | #endif | ||
3531 | i915_gem_flush(dev, file, | ||
3532 | dev->invalidate_domains, | ||
3533 | dev->flush_domains, | ||
3534 | dev_priv->mm.flush_rings); | ||
3535 | } | ||
3536 | |||
3537 | for (i = 0; i < count; i++) { | ||
3538 | struct drm_i915_gem_object *obj = to_intel_bo(objects[i]); | ||
3539 | /* XXX replace with semaphores */ | ||
3540 | if (obj->ring && ring != obj->ring) { | ||
3541 | ret = i915_gem_object_wait_rendering(&obj->base, true); | ||
3542 | if (ret) | ||
3543 | return ret; | ||
3544 | } | ||
3545 | } | ||
3546 | 3119 | ||
3547 | return 0; | 3120 | return 0; |
3548 | } | 3121 | } |
@@ -3582,586 +3155,129 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) | |||
3582 | return 0; | 3155 | return 0; |
3583 | 3156 | ||
3584 | ret = 0; | 3157 | ret = 0; |
3585 | if (!i915_seqno_passed(ring->get_seqno(dev, ring), seqno)) { | 3158 | if (!i915_seqno_passed(ring->get_seqno(ring), seqno)) { |
3586 | /* And wait for the seqno passing without holding any locks and | 3159 | /* And wait for the seqno passing without holding any locks and |
3587 | * causing extra latency for others. This is safe as the irq | 3160 | * causing extra latency for others. This is safe as the irq |
3588 | * generation is designed to be run atomically and so is | 3161 | * generation is designed to be run atomically and so is |
3589 | * lockless. | 3162 | * lockless. |
3590 | */ | 3163 | */ |
3591 | ring->user_irq_get(dev, ring); | 3164 | if (ring->irq_get(ring)) { |
3592 | ret = wait_event_interruptible(ring->irq_queue, | 3165 | ret = wait_event_interruptible(ring->irq_queue, |
3593 | i915_seqno_passed(ring->get_seqno(dev, ring), seqno) | 3166 | i915_seqno_passed(ring->get_seqno(ring), seqno) |
3594 | || atomic_read(&dev_priv->mm.wedged)); | 3167 | || atomic_read(&dev_priv->mm.wedged)); |
3595 | ring->user_irq_put(dev, ring); | 3168 | ring->irq_put(ring); |
3596 | |||
3597 | if (ret == 0 && atomic_read(&dev_priv->mm.wedged)) | ||
3598 | ret = -EIO; | ||
3599 | } | ||
3600 | |||
3601 | if (ret == 0) | ||
3602 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0); | ||
3603 | |||
3604 | return ret; | ||
3605 | } | ||
3606 | |||
3607 | static int | ||
3608 | i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec, | ||
3609 | uint64_t exec_offset) | ||
3610 | { | ||
3611 | uint32_t exec_start, exec_len; | ||
3612 | |||
3613 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | ||
3614 | exec_len = (uint32_t) exec->batch_len; | ||
3615 | |||
3616 | if ((exec_start | exec_len) & 0x7) | ||
3617 | return -EINVAL; | ||
3618 | |||
3619 | if (!exec_start) | ||
3620 | return -EINVAL; | ||
3621 | |||
3622 | return 0; | ||
3623 | } | ||
3624 | |||
3625 | static int | ||
3626 | validate_exec_list(struct drm_i915_gem_exec_object2 *exec, | ||
3627 | int count) | ||
3628 | { | ||
3629 | int i; | ||
3630 | |||
3631 | for (i = 0; i < count; i++) { | ||
3632 | char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr; | ||
3633 | size_t length = exec[i].relocation_count * sizeof(struct drm_i915_gem_relocation_entry); | ||
3634 | |||
3635 | if (!access_ok(VERIFY_READ, ptr, length)) | ||
3636 | return -EFAULT; | ||
3637 | |||
3638 | /* we may also need to update the presumed offsets */ | ||
3639 | if (!access_ok(VERIFY_WRITE, ptr, length)) | ||
3640 | return -EFAULT; | ||
3641 | |||
3642 | if (fault_in_pages_readable(ptr, length)) | ||
3643 | return -EFAULT; | ||
3644 | } | ||
3645 | |||
3646 | return 0; | ||
3647 | } | ||
3648 | |||
3649 | static int | ||
3650 | i915_gem_do_execbuffer(struct drm_device *dev, void *data, | ||
3651 | struct drm_file *file, | ||
3652 | struct drm_i915_gem_execbuffer2 *args, | ||
3653 | struct drm_i915_gem_exec_object2 *exec_list) | ||
3654 | { | ||
3655 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3656 | struct drm_gem_object **object_list = NULL; | ||
3657 | struct drm_gem_object *batch_obj; | ||
3658 | struct drm_i915_gem_object *obj_priv; | ||
3659 | struct drm_clip_rect *cliprects = NULL; | ||
3660 | struct drm_i915_gem_request *request = NULL; | ||
3661 | int ret, i, flips; | ||
3662 | uint64_t exec_offset; | ||
3663 | |||
3664 | struct intel_ring_buffer *ring = NULL; | ||
3665 | |||
3666 | ret = i915_gem_check_is_wedged(dev); | ||
3667 | if (ret) | ||
3668 | return ret; | ||
3669 | |||
3670 | ret = validate_exec_list(exec_list, args->buffer_count); | ||
3671 | if (ret) | ||
3672 | return ret; | ||
3673 | |||
3674 | #if WATCH_EXEC | ||
3675 | DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", | ||
3676 | (int) args->buffers_ptr, args->buffer_count, args->batch_len); | ||
3677 | #endif | ||
3678 | switch (args->flags & I915_EXEC_RING_MASK) { | ||
3679 | case I915_EXEC_DEFAULT: | ||
3680 | case I915_EXEC_RENDER: | ||
3681 | ring = &dev_priv->render_ring; | ||
3682 | break; | ||
3683 | case I915_EXEC_BSD: | ||
3684 | if (!HAS_BSD(dev)) { | ||
3685 | DRM_ERROR("execbuf with invalid ring (BSD)\n"); | ||
3686 | return -EINVAL; | ||
3687 | } | ||
3688 | ring = &dev_priv->bsd_ring; | ||
3689 | break; | ||
3690 | case I915_EXEC_BLT: | ||
3691 | if (!HAS_BLT(dev)) { | ||
3692 | DRM_ERROR("execbuf with invalid ring (BLT)\n"); | ||
3693 | return -EINVAL; | ||
3694 | } | ||
3695 | ring = &dev_priv->blt_ring; | ||
3696 | break; | ||
3697 | default: | ||
3698 | DRM_ERROR("execbuf with unknown ring: %d\n", | ||
3699 | (int)(args->flags & I915_EXEC_RING_MASK)); | ||
3700 | return -EINVAL; | ||
3701 | } | ||
3702 | |||
3703 | if (args->buffer_count < 1) { | ||
3704 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); | ||
3705 | return -EINVAL; | ||
3706 | } | ||
3707 | object_list = drm_malloc_ab(sizeof(*object_list), args->buffer_count); | ||
3708 | if (object_list == NULL) { | ||
3709 | DRM_ERROR("Failed to allocate object list for %d buffers\n", | ||
3710 | args->buffer_count); | ||
3711 | ret = -ENOMEM; | ||
3712 | goto pre_mutex_err; | ||
3713 | } | ||
3714 | |||
3715 | if (args->num_cliprects != 0) { | ||
3716 | cliprects = kcalloc(args->num_cliprects, sizeof(*cliprects), | ||
3717 | GFP_KERNEL); | ||
3718 | if (cliprects == NULL) { | ||
3719 | ret = -ENOMEM; | ||
3720 | goto pre_mutex_err; | ||
3721 | } | ||
3722 | |||
3723 | ret = copy_from_user(cliprects, | ||
3724 | (struct drm_clip_rect __user *) | ||
3725 | (uintptr_t) args->cliprects_ptr, | ||
3726 | sizeof(*cliprects) * args->num_cliprects); | ||
3727 | if (ret != 0) { | ||
3728 | DRM_ERROR("copy %d cliprects failed: %d\n", | ||
3729 | args->num_cliprects, ret); | ||
3730 | ret = -EFAULT; | ||
3731 | goto pre_mutex_err; | ||
3732 | } | ||
3733 | } | ||
3734 | |||
3735 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
3736 | if (request == NULL) { | ||
3737 | ret = -ENOMEM; | ||
3738 | goto pre_mutex_err; | ||
3739 | } | ||
3740 | |||
3741 | ret = i915_mutex_lock_interruptible(dev); | ||
3742 | if (ret) | ||
3743 | goto pre_mutex_err; | ||
3744 | |||
3745 | if (dev_priv->mm.suspended) { | ||
3746 | mutex_unlock(&dev->struct_mutex); | ||
3747 | ret = -EBUSY; | ||
3748 | goto pre_mutex_err; | ||
3749 | } | ||
3750 | |||
3751 | /* Look up object handles */ | ||
3752 | for (i = 0; i < args->buffer_count; i++) { | ||
3753 | object_list[i] = drm_gem_object_lookup(dev, file, | ||
3754 | exec_list[i].handle); | ||
3755 | if (object_list[i] == NULL) { | ||
3756 | DRM_ERROR("Invalid object handle %d at index %d\n", | ||
3757 | exec_list[i].handle, i); | ||
3758 | /* prevent error path from reading uninitialized data */ | ||
3759 | args->buffer_count = i + 1; | ||
3760 | ret = -ENOENT; | ||
3761 | goto err; | ||
3762 | } | ||
3763 | |||
3764 | obj_priv = to_intel_bo(object_list[i]); | ||
3765 | if (obj_priv->in_execbuffer) { | ||
3766 | DRM_ERROR("Object %p appears more than once in object list\n", | ||
3767 | object_list[i]); | ||
3768 | /* prevent error path from reading uninitialized data */ | ||
3769 | args->buffer_count = i + 1; | ||
3770 | ret = -EINVAL; | ||
3771 | goto err; | ||
3772 | } | ||
3773 | obj_priv->in_execbuffer = true; | ||
3774 | } | ||
3775 | |||
3776 | /* Move the objects en-masse into the GTT, evicting if necessary. */ | ||
3777 | ret = i915_gem_execbuffer_pin(dev, file, | ||
3778 | object_list, exec_list, | ||
3779 | args->buffer_count); | ||
3780 | if (ret) | ||
3781 | goto err; | ||
3782 | |||
3783 | /* The objects are in their final locations, apply the relocations. */ | ||
3784 | for (i = 0; i < args->buffer_count; i++) { | ||
3785 | struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]); | ||
3786 | obj->base.pending_read_domains = 0; | ||
3787 | obj->base.pending_write_domain = 0; | ||
3788 | ret = i915_gem_execbuffer_relocate(obj, file, &exec_list[i]); | ||
3789 | if (ret) | ||
3790 | goto err; | ||
3791 | } | ||
3792 | |||
3793 | /* Set the pending read domains for the batch buffer to COMMAND */ | ||
3794 | batch_obj = object_list[args->buffer_count-1]; | ||
3795 | if (batch_obj->pending_write_domain) { | ||
3796 | DRM_ERROR("Attempting to use self-modifying batch buffer\n"); | ||
3797 | ret = -EINVAL; | ||
3798 | goto err; | ||
3799 | } | ||
3800 | batch_obj->pending_read_domains |= I915_GEM_DOMAIN_COMMAND; | ||
3801 | |||
3802 | /* Sanity check the batch buffer */ | ||
3803 | exec_offset = to_intel_bo(batch_obj)->gtt_offset; | ||
3804 | ret = i915_gem_check_execbuffer(args, exec_offset); | ||
3805 | if (ret != 0) { | ||
3806 | DRM_ERROR("execbuf with invalid offset/length\n"); | ||
3807 | goto err; | ||
3808 | } | ||
3809 | |||
3810 | ret = i915_gem_execbuffer_move_to_gpu(dev, file, ring, | ||
3811 | object_list, args->buffer_count); | ||
3812 | if (ret) | ||
3813 | goto err; | ||
3814 | |||
3815 | for (i = 0; i < args->buffer_count; i++) { | ||
3816 | struct drm_gem_object *obj = object_list[i]; | ||
3817 | uint32_t old_write_domain = obj->write_domain; | ||
3818 | obj->write_domain = obj->pending_write_domain; | ||
3819 | trace_i915_gem_object_change_domain(obj, | ||
3820 | obj->read_domains, | ||
3821 | old_write_domain); | ||
3822 | } | ||
3823 | |||
3824 | #if WATCH_COHERENCY | ||
3825 | for (i = 0; i < args->buffer_count; i++) { | ||
3826 | i915_gem_object_check_coherency(object_list[i], | ||
3827 | exec_list[i].handle); | ||
3828 | } | ||
3829 | #endif | ||
3830 | |||
3831 | #if WATCH_EXEC | ||
3832 | i915_gem_dump_object(batch_obj, | ||
3833 | args->batch_len, | ||
3834 | __func__, | ||
3835 | ~0); | ||
3836 | #endif | ||
3837 | |||
3838 | /* Check for any pending flips. As we only maintain a flip queue depth | ||
3839 | * of 1, we can simply insert a WAIT for the next display flip prior | ||
3840 | * to executing the batch and avoid stalling the CPU. | ||
3841 | */ | ||
3842 | flips = 0; | ||
3843 | for (i = 0; i < args->buffer_count; i++) { | ||
3844 | if (object_list[i]->write_domain) | ||
3845 | flips |= atomic_read(&to_intel_bo(object_list[i])->pending_flip); | ||
3846 | } | ||
3847 | if (flips) { | ||
3848 | int plane, flip_mask; | ||
3849 | |||
3850 | for (plane = 0; flips >> plane; plane++) { | ||
3851 | if (((flips >> plane) & 1) == 0) | ||
3852 | continue; | ||
3853 | |||
3854 | if (plane) | ||
3855 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; | ||
3856 | else | ||
3857 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; | ||
3858 | |||
3859 | intel_ring_begin(dev, ring, 2); | ||
3860 | intel_ring_emit(dev, ring, | ||
3861 | MI_WAIT_FOR_EVENT | flip_mask); | ||
3862 | intel_ring_emit(dev, ring, MI_NOOP); | ||
3863 | intel_ring_advance(dev, ring); | ||
3864 | } | ||
3865 | } | ||
3866 | |||
3867 | /* Exec the batchbuffer */ | ||
3868 | ret = ring->dispatch_gem_execbuffer(dev, ring, args, | ||
3869 | cliprects, exec_offset); | ||
3870 | if (ret) { | ||
3871 | DRM_ERROR("dispatch failed %d\n", ret); | ||
3872 | goto err; | ||
3873 | } | ||
3874 | |||
3875 | /* | ||
3876 | * Ensure that the commands in the batch buffer are | ||
3877 | * finished before the interrupt fires | ||
3878 | */ | ||
3879 | i915_retire_commands(dev, ring); | ||
3880 | |||
3881 | for (i = 0; i < args->buffer_count; i++) { | ||
3882 | struct drm_gem_object *obj = object_list[i]; | ||
3883 | |||
3884 | i915_gem_object_move_to_active(obj, ring); | ||
3885 | if (obj->write_domain) | ||
3886 | list_move_tail(&to_intel_bo(obj)->gpu_write_list, | ||
3887 | &ring->gpu_write_list); | ||
3888 | } | ||
3889 | |||
3890 | i915_add_request(dev, file, request, ring); | ||
3891 | request = NULL; | ||
3892 | |||
3893 | err: | ||
3894 | for (i = 0; i < args->buffer_count; i++) { | ||
3895 | if (object_list[i]) { | ||
3896 | obj_priv = to_intel_bo(object_list[i]); | ||
3897 | obj_priv->in_execbuffer = false; | ||
3898 | } | ||
3899 | drm_gem_object_unreference(object_list[i]); | ||
3900 | } | ||
3901 | |||
3902 | mutex_unlock(&dev->struct_mutex); | ||
3903 | |||
3904 | pre_mutex_err: | ||
3905 | drm_free_large(object_list); | ||
3906 | kfree(cliprects); | ||
3907 | kfree(request); | ||
3908 | |||
3909 | return ret; | ||
3910 | } | ||
3911 | |||
3912 | /* | ||
3913 | * Legacy execbuffer just creates an exec2 list from the original exec object | ||
3914 | * list array and passes it to the real function. | ||
3915 | */ | ||
3916 | int | ||
3917 | i915_gem_execbuffer(struct drm_device *dev, void *data, | ||
3918 | struct drm_file *file_priv) | ||
3919 | { | ||
3920 | struct drm_i915_gem_execbuffer *args = data; | ||
3921 | struct drm_i915_gem_execbuffer2 exec2; | ||
3922 | struct drm_i915_gem_exec_object *exec_list = NULL; | ||
3923 | struct drm_i915_gem_exec_object2 *exec2_list = NULL; | ||
3924 | int ret, i; | ||
3925 | |||
3926 | #if WATCH_EXEC | ||
3927 | DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", | ||
3928 | (int) args->buffers_ptr, args->buffer_count, args->batch_len); | ||
3929 | #endif | ||
3930 | |||
3931 | if (args->buffer_count < 1) { | ||
3932 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); | ||
3933 | return -EINVAL; | ||
3934 | } | ||
3935 | |||
3936 | /* Copy in the exec list from userland */ | ||
3937 | exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count); | ||
3938 | exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); | ||
3939 | if (exec_list == NULL || exec2_list == NULL) { | ||
3940 | DRM_ERROR("Failed to allocate exec list for %d buffers\n", | ||
3941 | args->buffer_count); | ||
3942 | drm_free_large(exec_list); | ||
3943 | drm_free_large(exec2_list); | ||
3944 | return -ENOMEM; | ||
3945 | } | ||
3946 | ret = copy_from_user(exec_list, | ||
3947 | (struct drm_i915_relocation_entry __user *) | ||
3948 | (uintptr_t) args->buffers_ptr, | ||
3949 | sizeof(*exec_list) * args->buffer_count); | ||
3950 | if (ret != 0) { | ||
3951 | DRM_ERROR("copy %d exec entries failed %d\n", | ||
3952 | args->buffer_count, ret); | ||
3953 | drm_free_large(exec_list); | ||
3954 | drm_free_large(exec2_list); | ||
3955 | return -EFAULT; | ||
3956 | } | ||
3957 | |||
3958 | for (i = 0; i < args->buffer_count; i++) { | ||
3959 | exec2_list[i].handle = exec_list[i].handle; | ||
3960 | exec2_list[i].relocation_count = exec_list[i].relocation_count; | ||
3961 | exec2_list[i].relocs_ptr = exec_list[i].relocs_ptr; | ||
3962 | exec2_list[i].alignment = exec_list[i].alignment; | ||
3963 | exec2_list[i].offset = exec_list[i].offset; | ||
3964 | if (INTEL_INFO(dev)->gen < 4) | ||
3965 | exec2_list[i].flags = EXEC_OBJECT_NEEDS_FENCE; | ||
3966 | else | ||
3967 | exec2_list[i].flags = 0; | ||
3968 | } | ||
3969 | 3169 | ||
3970 | exec2.buffers_ptr = args->buffers_ptr; | 3170 | if (ret == 0 && atomic_read(&dev_priv->mm.wedged)) |
3971 | exec2.buffer_count = args->buffer_count; | 3171 | ret = -EIO; |
3972 | exec2.batch_start_offset = args->batch_start_offset; | ||
3973 | exec2.batch_len = args->batch_len; | ||
3974 | exec2.DR1 = args->DR1; | ||
3975 | exec2.DR4 = args->DR4; | ||
3976 | exec2.num_cliprects = args->num_cliprects; | ||
3977 | exec2.cliprects_ptr = args->cliprects_ptr; | ||
3978 | exec2.flags = I915_EXEC_RENDER; | ||
3979 | |||
3980 | ret = i915_gem_do_execbuffer(dev, data, file_priv, &exec2, exec2_list); | ||
3981 | if (!ret) { | ||
3982 | /* Copy the new buffer offsets back to the user's exec list. */ | ||
3983 | for (i = 0; i < args->buffer_count; i++) | ||
3984 | exec_list[i].offset = exec2_list[i].offset; | ||
3985 | /* ... and back out to userspace */ | ||
3986 | ret = copy_to_user((struct drm_i915_relocation_entry __user *) | ||
3987 | (uintptr_t) args->buffers_ptr, | ||
3988 | exec_list, | ||
3989 | sizeof(*exec_list) * args->buffer_count); | ||
3990 | if (ret) { | ||
3991 | ret = -EFAULT; | ||
3992 | DRM_ERROR("failed to copy %d exec entries " | ||
3993 | "back to user (%d)\n", | ||
3994 | args->buffer_count, ret); | ||
3995 | } | 3172 | } |
3996 | } | 3173 | } |
3997 | 3174 | ||
3998 | drm_free_large(exec_list); | 3175 | if (ret == 0) |
3999 | drm_free_large(exec2_list); | 3176 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0); |
4000 | return ret; | ||
4001 | } | ||
4002 | |||
4003 | int | ||
4004 | i915_gem_execbuffer2(struct drm_device *dev, void *data, | ||
4005 | struct drm_file *file_priv) | ||
4006 | { | ||
4007 | struct drm_i915_gem_execbuffer2 *args = data; | ||
4008 | struct drm_i915_gem_exec_object2 *exec2_list = NULL; | ||
4009 | int ret; | ||
4010 | |||
4011 | #if WATCH_EXEC | ||
4012 | DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", | ||
4013 | (int) args->buffers_ptr, args->buffer_count, args->batch_len); | ||
4014 | #endif | ||
4015 | |||
4016 | if (args->buffer_count < 1) { | ||
4017 | DRM_ERROR("execbuf2 with %d buffers\n", args->buffer_count); | ||
4018 | return -EINVAL; | ||
4019 | } | ||
4020 | |||
4021 | exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); | ||
4022 | if (exec2_list == NULL) { | ||
4023 | DRM_ERROR("Failed to allocate exec list for %d buffers\n", | ||
4024 | args->buffer_count); | ||
4025 | return -ENOMEM; | ||
4026 | } | ||
4027 | ret = copy_from_user(exec2_list, | ||
4028 | (struct drm_i915_relocation_entry __user *) | ||
4029 | (uintptr_t) args->buffers_ptr, | ||
4030 | sizeof(*exec2_list) * args->buffer_count); | ||
4031 | if (ret != 0) { | ||
4032 | DRM_ERROR("copy %d exec entries failed %d\n", | ||
4033 | args->buffer_count, ret); | ||
4034 | drm_free_large(exec2_list); | ||
4035 | return -EFAULT; | ||
4036 | } | ||
4037 | |||
4038 | ret = i915_gem_do_execbuffer(dev, data, file_priv, args, exec2_list); | ||
4039 | if (!ret) { | ||
4040 | /* Copy the new buffer offsets back to the user's exec list. */ | ||
4041 | ret = copy_to_user((struct drm_i915_relocation_entry __user *) | ||
4042 | (uintptr_t) args->buffers_ptr, | ||
4043 | exec2_list, | ||
4044 | sizeof(*exec2_list) * args->buffer_count); | ||
4045 | if (ret) { | ||
4046 | ret = -EFAULT; | ||
4047 | DRM_ERROR("failed to copy %d exec entries " | ||
4048 | "back to user (%d)\n", | ||
4049 | args->buffer_count, ret); | ||
4050 | } | ||
4051 | } | ||
4052 | 3177 | ||
4053 | drm_free_large(exec2_list); | ||
4054 | return ret; | 3178 | return ret; |
4055 | } | 3179 | } |
4056 | 3180 | ||
4057 | int | 3181 | int |
4058 | i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | 3182 | i915_gem_object_pin(struct drm_i915_gem_object *obj, |
3183 | uint32_t alignment, | ||
3184 | bool map_and_fenceable) | ||
4059 | { | 3185 | { |
4060 | struct drm_device *dev = obj->dev; | 3186 | struct drm_device *dev = obj->base.dev; |
4061 | struct drm_i915_private *dev_priv = dev->dev_private; | 3187 | struct drm_i915_private *dev_priv = dev->dev_private; |
4062 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
4063 | int ret; | 3188 | int ret; |
4064 | 3189 | ||
4065 | BUG_ON(obj_priv->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); | 3190 | BUG_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); |
4066 | WARN_ON(i915_verify_lists(dev)); | 3191 | WARN_ON(i915_verify_lists(dev)); |
4067 | 3192 | ||
4068 | if (obj_priv->gtt_space != NULL) { | 3193 | if (obj->gtt_space != NULL) { |
4069 | if (alignment == 0) | 3194 | if ((alignment && obj->gtt_offset & (alignment - 1)) || |
4070 | alignment = i915_gem_get_gtt_alignment(obj); | 3195 | (map_and_fenceable && !obj->map_and_fenceable)) { |
4071 | if (obj_priv->gtt_offset & (alignment - 1)) { | 3196 | WARN(obj->pin_count, |
4072 | WARN(obj_priv->pin_count, | 3197 | "bo is already pinned with incorrect alignment:" |
4073 | "bo is already pinned with incorrect alignment: offset=%x, req.alignment=%x\n", | 3198 | " offset=%x, req.alignment=%x, req.map_and_fenceable=%d," |
4074 | obj_priv->gtt_offset, alignment); | 3199 | " obj->map_and_fenceable=%d\n", |
3200 | obj->gtt_offset, alignment, | ||
3201 | map_and_fenceable, | ||
3202 | obj->map_and_fenceable); | ||
4075 | ret = i915_gem_object_unbind(obj); | 3203 | ret = i915_gem_object_unbind(obj); |
4076 | if (ret) | 3204 | if (ret) |
4077 | return ret; | 3205 | return ret; |
4078 | } | 3206 | } |
4079 | } | 3207 | } |
4080 | 3208 | ||
4081 | if (obj_priv->gtt_space == NULL) { | 3209 | if (obj->gtt_space == NULL) { |
4082 | ret = i915_gem_object_bind_to_gtt(obj, alignment); | 3210 | ret = i915_gem_object_bind_to_gtt(obj, alignment, |
3211 | map_and_fenceable); | ||
4083 | if (ret) | 3212 | if (ret) |
4084 | return ret; | 3213 | return ret; |
4085 | } | 3214 | } |
4086 | 3215 | ||
4087 | obj_priv->pin_count++; | 3216 | if (obj->pin_count++ == 0) { |
4088 | 3217 | if (!obj->active) | |
4089 | /* If the object is not active and not pending a flush, | 3218 | list_move_tail(&obj->mm_list, |
4090 | * remove it from the inactive list | ||
4091 | */ | ||
4092 | if (obj_priv->pin_count == 1) { | ||
4093 | i915_gem_info_add_pin(dev_priv, obj->size); | ||
4094 | if (!obj_priv->active) | ||
4095 | list_move_tail(&obj_priv->mm_list, | ||
4096 | &dev_priv->mm.pinned_list); | 3219 | &dev_priv->mm.pinned_list); |
4097 | } | 3220 | } |
3221 | obj->pin_mappable |= map_and_fenceable; | ||
4098 | 3222 | ||
4099 | WARN_ON(i915_verify_lists(dev)); | 3223 | WARN_ON(i915_verify_lists(dev)); |
4100 | return 0; | 3224 | return 0; |
4101 | } | 3225 | } |
4102 | 3226 | ||
4103 | void | 3227 | void |
4104 | i915_gem_object_unpin(struct drm_gem_object *obj) | 3228 | i915_gem_object_unpin(struct drm_i915_gem_object *obj) |
4105 | { | 3229 | { |
4106 | struct drm_device *dev = obj->dev; | 3230 | struct drm_device *dev = obj->base.dev; |
4107 | drm_i915_private_t *dev_priv = dev->dev_private; | 3231 | drm_i915_private_t *dev_priv = dev->dev_private; |
4108 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
4109 | 3232 | ||
4110 | WARN_ON(i915_verify_lists(dev)); | 3233 | WARN_ON(i915_verify_lists(dev)); |
4111 | obj_priv->pin_count--; | 3234 | BUG_ON(obj->pin_count == 0); |
4112 | BUG_ON(obj_priv->pin_count < 0); | 3235 | BUG_ON(obj->gtt_space == NULL); |
4113 | BUG_ON(obj_priv->gtt_space == NULL); | ||
4114 | 3236 | ||
4115 | /* If the object is no longer pinned, and is | 3237 | if (--obj->pin_count == 0) { |
4116 | * neither active nor being flushed, then stick it on | 3238 | if (!obj->active) |
4117 | * the inactive list | 3239 | list_move_tail(&obj->mm_list, |
4118 | */ | ||
4119 | if (obj_priv->pin_count == 0) { | ||
4120 | if (!obj_priv->active) | ||
4121 | list_move_tail(&obj_priv->mm_list, | ||
4122 | &dev_priv->mm.inactive_list); | 3240 | &dev_priv->mm.inactive_list); |
4123 | i915_gem_info_remove_pin(dev_priv, obj->size); | 3241 | obj->pin_mappable = false; |
4124 | } | 3242 | } |
4125 | WARN_ON(i915_verify_lists(dev)); | 3243 | WARN_ON(i915_verify_lists(dev)); |
4126 | } | 3244 | } |
4127 | 3245 | ||
4128 | int | 3246 | int |
4129 | i915_gem_pin_ioctl(struct drm_device *dev, void *data, | 3247 | i915_gem_pin_ioctl(struct drm_device *dev, void *data, |
4130 | struct drm_file *file_priv) | 3248 | struct drm_file *file) |
4131 | { | 3249 | { |
4132 | struct drm_i915_gem_pin *args = data; | 3250 | struct drm_i915_gem_pin *args = data; |
4133 | struct drm_gem_object *obj; | 3251 | struct drm_i915_gem_object *obj; |
4134 | struct drm_i915_gem_object *obj_priv; | ||
4135 | int ret; | 3252 | int ret; |
4136 | 3253 | ||
4137 | ret = i915_mutex_lock_interruptible(dev); | 3254 | ret = i915_mutex_lock_interruptible(dev); |
4138 | if (ret) | 3255 | if (ret) |
4139 | return ret; | 3256 | return ret; |
4140 | 3257 | ||
4141 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 3258 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); |
4142 | if (obj == NULL) { | 3259 | if (obj == NULL) { |
4143 | ret = -ENOENT; | 3260 | ret = -ENOENT; |
4144 | goto unlock; | 3261 | goto unlock; |
4145 | } | 3262 | } |
4146 | obj_priv = to_intel_bo(obj); | ||
4147 | 3263 | ||
4148 | if (obj_priv->madv != I915_MADV_WILLNEED) { | 3264 | if (obj->madv != I915_MADV_WILLNEED) { |
4149 | DRM_ERROR("Attempting to pin a purgeable buffer\n"); | 3265 | DRM_ERROR("Attempting to pin a purgeable buffer\n"); |
4150 | ret = -EINVAL; | 3266 | ret = -EINVAL; |
4151 | goto out; | 3267 | goto out; |
4152 | } | 3268 | } |
4153 | 3269 | ||
4154 | if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) { | 3270 | if (obj->pin_filp != NULL && obj->pin_filp != file) { |
4155 | DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n", | 3271 | DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n", |
4156 | args->handle); | 3272 | args->handle); |
4157 | ret = -EINVAL; | 3273 | ret = -EINVAL; |
4158 | goto out; | 3274 | goto out; |
4159 | } | 3275 | } |
4160 | 3276 | ||
4161 | obj_priv->user_pin_count++; | 3277 | obj->user_pin_count++; |
4162 | obj_priv->pin_filp = file_priv; | 3278 | obj->pin_filp = file; |
4163 | if (obj_priv->user_pin_count == 1) { | 3279 | if (obj->user_pin_count == 1) { |
4164 | ret = i915_gem_object_pin(obj, args->alignment); | 3280 | ret = i915_gem_object_pin(obj, args->alignment, true); |
4165 | if (ret) | 3281 | if (ret) |
4166 | goto out; | 3282 | goto out; |
4167 | } | 3283 | } |
@@ -4170,9 +3286,9 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, | |||
4170 | * as the X server doesn't manage domains yet | 3286 | * as the X server doesn't manage domains yet |
4171 | */ | 3287 | */ |
4172 | i915_gem_object_flush_cpu_write_domain(obj); | 3288 | i915_gem_object_flush_cpu_write_domain(obj); |
4173 | args->offset = obj_priv->gtt_offset; | 3289 | args->offset = obj->gtt_offset; |
4174 | out: | 3290 | out: |
4175 | drm_gem_object_unreference(obj); | 3291 | drm_gem_object_unreference(&obj->base); |
4176 | unlock: | 3292 | unlock: |
4177 | mutex_unlock(&dev->struct_mutex); | 3293 | mutex_unlock(&dev->struct_mutex); |
4178 | return ret; | 3294 | return ret; |
@@ -4180,38 +3296,36 @@ unlock: | |||
4180 | 3296 | ||
4181 | int | 3297 | int |
4182 | i915_gem_unpin_ioctl(struct drm_device *dev, void *data, | 3298 | i915_gem_unpin_ioctl(struct drm_device *dev, void *data, |
4183 | struct drm_file *file_priv) | 3299 | struct drm_file *file) |
4184 | { | 3300 | { |
4185 | struct drm_i915_gem_pin *args = data; | 3301 | struct drm_i915_gem_pin *args = data; |
4186 | struct drm_gem_object *obj; | 3302 | struct drm_i915_gem_object *obj; |
4187 | struct drm_i915_gem_object *obj_priv; | ||
4188 | int ret; | 3303 | int ret; |
4189 | 3304 | ||
4190 | ret = i915_mutex_lock_interruptible(dev); | 3305 | ret = i915_mutex_lock_interruptible(dev); |
4191 | if (ret) | 3306 | if (ret) |
4192 | return ret; | 3307 | return ret; |
4193 | 3308 | ||
4194 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 3309 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); |
4195 | if (obj == NULL) { | 3310 | if (obj == NULL) { |
4196 | ret = -ENOENT; | 3311 | ret = -ENOENT; |
4197 | goto unlock; | 3312 | goto unlock; |
4198 | } | 3313 | } |
4199 | obj_priv = to_intel_bo(obj); | ||
4200 | 3314 | ||
4201 | if (obj_priv->pin_filp != file_priv) { | 3315 | if (obj->pin_filp != file) { |
4202 | DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n", | 3316 | DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n", |
4203 | args->handle); | 3317 | args->handle); |
4204 | ret = -EINVAL; | 3318 | ret = -EINVAL; |
4205 | goto out; | 3319 | goto out; |
4206 | } | 3320 | } |
4207 | obj_priv->user_pin_count--; | 3321 | obj->user_pin_count--; |
4208 | if (obj_priv->user_pin_count == 0) { | 3322 | if (obj->user_pin_count == 0) { |
4209 | obj_priv->pin_filp = NULL; | 3323 | obj->pin_filp = NULL; |
4210 | i915_gem_object_unpin(obj); | 3324 | i915_gem_object_unpin(obj); |
4211 | } | 3325 | } |
4212 | 3326 | ||
4213 | out: | 3327 | out: |
4214 | drm_gem_object_unreference(obj); | 3328 | drm_gem_object_unreference(&obj->base); |
4215 | unlock: | 3329 | unlock: |
4216 | mutex_unlock(&dev->struct_mutex); | 3330 | mutex_unlock(&dev->struct_mutex); |
4217 | return ret; | 3331 | return ret; |
@@ -4219,52 +3333,64 @@ unlock: | |||
4219 | 3333 | ||
4220 | int | 3334 | int |
4221 | i915_gem_busy_ioctl(struct drm_device *dev, void *data, | 3335 | i915_gem_busy_ioctl(struct drm_device *dev, void *data, |
4222 | struct drm_file *file_priv) | 3336 | struct drm_file *file) |
4223 | { | 3337 | { |
4224 | struct drm_i915_gem_busy *args = data; | 3338 | struct drm_i915_gem_busy *args = data; |
4225 | struct drm_gem_object *obj; | 3339 | struct drm_i915_gem_object *obj; |
4226 | struct drm_i915_gem_object *obj_priv; | ||
4227 | int ret; | 3340 | int ret; |
4228 | 3341 | ||
4229 | ret = i915_mutex_lock_interruptible(dev); | 3342 | ret = i915_mutex_lock_interruptible(dev); |
4230 | if (ret) | 3343 | if (ret) |
4231 | return ret; | 3344 | return ret; |
4232 | 3345 | ||
4233 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 3346 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); |
4234 | if (obj == NULL) { | 3347 | if (obj == NULL) { |
4235 | ret = -ENOENT; | 3348 | ret = -ENOENT; |
4236 | goto unlock; | 3349 | goto unlock; |
4237 | } | 3350 | } |
4238 | obj_priv = to_intel_bo(obj); | ||
4239 | 3351 | ||
4240 | /* Count all active objects as busy, even if they are currently not used | 3352 | /* Count all active objects as busy, even if they are currently not used |
4241 | * by the gpu. Users of this interface expect objects to eventually | 3353 | * by the gpu. Users of this interface expect objects to eventually |
4242 | * become non-busy without any further actions, therefore emit any | 3354 | * become non-busy without any further actions, therefore emit any |
4243 | * necessary flushes here. | 3355 | * necessary flushes here. |
4244 | */ | 3356 | */ |
4245 | args->busy = obj_priv->active; | 3357 | args->busy = obj->active; |
4246 | if (args->busy) { | 3358 | if (args->busy) { |
4247 | /* Unconditionally flush objects, even when the gpu still uses this | 3359 | /* Unconditionally flush objects, even when the gpu still uses this |
4248 | * object. Userspace calling this function indicates that it wants to | 3360 | * object. Userspace calling this function indicates that it wants to |
4249 | * use this buffer rather sooner than later, so issuing the required | 3361 | * use this buffer rather sooner than later, so issuing the required |
4250 | * flush earlier is beneficial. | 3362 | * flush earlier is beneficial. |
4251 | */ | 3363 | */ |
4252 | if (obj->write_domain & I915_GEM_GPU_DOMAINS) | 3364 | if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { |
4253 | i915_gem_flush_ring(dev, file_priv, | 3365 | i915_gem_flush_ring(dev, obj->ring, |
4254 | obj_priv->ring, | 3366 | 0, obj->base.write_domain); |
4255 | 0, obj->write_domain); | 3367 | } else if (obj->ring->outstanding_lazy_request == |
3368 | obj->last_rendering_seqno) { | ||
3369 | struct drm_i915_gem_request *request; | ||
3370 | |||
3371 | /* This ring is not being cleared by active usage, | ||
3372 | * so emit a request to do so. | ||
3373 | */ | ||
3374 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
3375 | if (request) | ||
3376 | ret = i915_add_request(dev, | ||
3377 | NULL, request, | ||
3378 | obj->ring); | ||
3379 | else | ||
3380 | ret = -ENOMEM; | ||
3381 | } | ||
4256 | 3382 | ||
4257 | /* Update the active list for the hardware's current position. | 3383 | /* Update the active list for the hardware's current position. |
4258 | * Otherwise this only updates on a delayed timer or when irqs | 3384 | * Otherwise this only updates on a delayed timer or when irqs |
4259 | * are actually unmasked, and our working set ends up being | 3385 | * are actually unmasked, and our working set ends up being |
4260 | * larger than required. | 3386 | * larger than required. |
4261 | */ | 3387 | */ |
4262 | i915_gem_retire_requests_ring(dev, obj_priv->ring); | 3388 | i915_gem_retire_requests_ring(dev, obj->ring); |
4263 | 3389 | ||
4264 | args->busy = obj_priv->active; | 3390 | args->busy = obj->active; |
4265 | } | 3391 | } |
4266 | 3392 | ||
4267 | drm_gem_object_unreference(obj); | 3393 | drm_gem_object_unreference(&obj->base); |
4268 | unlock: | 3394 | unlock: |
4269 | mutex_unlock(&dev->struct_mutex); | 3395 | mutex_unlock(&dev->struct_mutex); |
4270 | return ret; | 3396 | return ret; |
@@ -4282,8 +3408,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, | |||
4282 | struct drm_file *file_priv) | 3408 | struct drm_file *file_priv) |
4283 | { | 3409 | { |
4284 | struct drm_i915_gem_madvise *args = data; | 3410 | struct drm_i915_gem_madvise *args = data; |
4285 | struct drm_gem_object *obj; | 3411 | struct drm_i915_gem_object *obj; |
4286 | struct drm_i915_gem_object *obj_priv; | ||
4287 | int ret; | 3412 | int ret; |
4288 | 3413 | ||
4289 | switch (args->madv) { | 3414 | switch (args->madv) { |
@@ -4298,37 +3423,36 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, | |||
4298 | if (ret) | 3423 | if (ret) |
4299 | return ret; | 3424 | return ret; |
4300 | 3425 | ||
4301 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 3426 | obj = to_intel_bo(drm_gem_object_lookup(dev, file_priv, args->handle)); |
4302 | if (obj == NULL) { | 3427 | if (obj == NULL) { |
4303 | ret = -ENOENT; | 3428 | ret = -ENOENT; |
4304 | goto unlock; | 3429 | goto unlock; |
4305 | } | 3430 | } |
4306 | obj_priv = to_intel_bo(obj); | ||
4307 | 3431 | ||
4308 | if (obj_priv->pin_count) { | 3432 | if (obj->pin_count) { |
4309 | ret = -EINVAL; | 3433 | ret = -EINVAL; |
4310 | goto out; | 3434 | goto out; |
4311 | } | 3435 | } |
4312 | 3436 | ||
4313 | if (obj_priv->madv != __I915_MADV_PURGED) | 3437 | if (obj->madv != __I915_MADV_PURGED) |
4314 | obj_priv->madv = args->madv; | 3438 | obj->madv = args->madv; |
4315 | 3439 | ||
4316 | /* if the object is no longer bound, discard its backing storage */ | 3440 | /* if the object is no longer bound, discard its backing storage */ |
4317 | if (i915_gem_object_is_purgeable(obj_priv) && | 3441 | if (i915_gem_object_is_purgeable(obj) && |
4318 | obj_priv->gtt_space == NULL) | 3442 | obj->gtt_space == NULL) |
4319 | i915_gem_object_truncate(obj); | 3443 | i915_gem_object_truncate(obj); |
4320 | 3444 | ||
4321 | args->retained = obj_priv->madv != __I915_MADV_PURGED; | 3445 | args->retained = obj->madv != __I915_MADV_PURGED; |
4322 | 3446 | ||
4323 | out: | 3447 | out: |
4324 | drm_gem_object_unreference(obj); | 3448 | drm_gem_object_unreference(&obj->base); |
4325 | unlock: | 3449 | unlock: |
4326 | mutex_unlock(&dev->struct_mutex); | 3450 | mutex_unlock(&dev->struct_mutex); |
4327 | return ret; | 3451 | return ret; |
4328 | } | 3452 | } |
4329 | 3453 | ||
4330 | struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, | 3454 | struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, |
4331 | size_t size) | 3455 | size_t size) |
4332 | { | 3456 | { |
4333 | struct drm_i915_private *dev_priv = dev->dev_private; | 3457 | struct drm_i915_private *dev_priv = dev->dev_private; |
4334 | struct drm_i915_gem_object *obj; | 3458 | struct drm_i915_gem_object *obj; |
@@ -4351,11 +3475,15 @@ struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, | |||
4351 | obj->base.driver_private = NULL; | 3475 | obj->base.driver_private = NULL; |
4352 | obj->fence_reg = I915_FENCE_REG_NONE; | 3476 | obj->fence_reg = I915_FENCE_REG_NONE; |
4353 | INIT_LIST_HEAD(&obj->mm_list); | 3477 | INIT_LIST_HEAD(&obj->mm_list); |
3478 | INIT_LIST_HEAD(&obj->gtt_list); | ||
4354 | INIT_LIST_HEAD(&obj->ring_list); | 3479 | INIT_LIST_HEAD(&obj->ring_list); |
3480 | INIT_LIST_HEAD(&obj->exec_list); | ||
4355 | INIT_LIST_HEAD(&obj->gpu_write_list); | 3481 | INIT_LIST_HEAD(&obj->gpu_write_list); |
4356 | obj->madv = I915_MADV_WILLNEED; | 3482 | obj->madv = I915_MADV_WILLNEED; |
3483 | /* Avoid an unnecessary call to unbind on the first bind. */ | ||
3484 | obj->map_and_fenceable = true; | ||
4357 | 3485 | ||
4358 | return &obj->base; | 3486 | return obj; |
4359 | } | 3487 | } |
4360 | 3488 | ||
4361 | int i915_gem_init_object(struct drm_gem_object *obj) | 3489 | int i915_gem_init_object(struct drm_gem_object *obj) |
@@ -4365,42 +3493,41 @@ int i915_gem_init_object(struct drm_gem_object *obj) | |||
4365 | return 0; | 3493 | return 0; |
4366 | } | 3494 | } |
4367 | 3495 | ||
4368 | static void i915_gem_free_object_tail(struct drm_gem_object *obj) | 3496 | static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj) |
4369 | { | 3497 | { |
4370 | struct drm_device *dev = obj->dev; | 3498 | struct drm_device *dev = obj->base.dev; |
4371 | drm_i915_private_t *dev_priv = dev->dev_private; | 3499 | drm_i915_private_t *dev_priv = dev->dev_private; |
4372 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
4373 | int ret; | 3500 | int ret; |
4374 | 3501 | ||
4375 | ret = i915_gem_object_unbind(obj); | 3502 | ret = i915_gem_object_unbind(obj); |
4376 | if (ret == -ERESTARTSYS) { | 3503 | if (ret == -ERESTARTSYS) { |
4377 | list_move(&obj_priv->mm_list, | 3504 | list_move(&obj->mm_list, |
4378 | &dev_priv->mm.deferred_free_list); | 3505 | &dev_priv->mm.deferred_free_list); |
4379 | return; | 3506 | return; |
4380 | } | 3507 | } |
4381 | 3508 | ||
4382 | if (obj_priv->mmap_offset) | 3509 | if (obj->base.map_list.map) |
4383 | i915_gem_free_mmap_offset(obj); | 3510 | i915_gem_free_mmap_offset(obj); |
4384 | 3511 | ||
4385 | drm_gem_object_release(obj); | 3512 | drm_gem_object_release(&obj->base); |
4386 | i915_gem_info_remove_obj(dev_priv, obj->size); | 3513 | i915_gem_info_remove_obj(dev_priv, obj->base.size); |
4387 | 3514 | ||
4388 | kfree(obj_priv->page_cpu_valid); | 3515 | kfree(obj->page_cpu_valid); |
4389 | kfree(obj_priv->bit_17); | 3516 | kfree(obj->bit_17); |
4390 | kfree(obj_priv); | 3517 | kfree(obj); |
4391 | } | 3518 | } |
4392 | 3519 | ||
4393 | void i915_gem_free_object(struct drm_gem_object *obj) | 3520 | void i915_gem_free_object(struct drm_gem_object *gem_obj) |
4394 | { | 3521 | { |
4395 | struct drm_device *dev = obj->dev; | 3522 | struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); |
4396 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 3523 | struct drm_device *dev = obj->base.dev; |
4397 | 3524 | ||
4398 | trace_i915_gem_object_destroy(obj); | 3525 | trace_i915_gem_object_destroy(obj); |
4399 | 3526 | ||
4400 | while (obj_priv->pin_count > 0) | 3527 | while (obj->pin_count > 0) |
4401 | i915_gem_object_unpin(obj); | 3528 | i915_gem_object_unpin(obj); |
4402 | 3529 | ||
4403 | if (obj_priv->phys_obj) | 3530 | if (obj->phys_obj) |
4404 | i915_gem_detach_phys_object(dev, obj); | 3531 | i915_gem_detach_phys_object(dev, obj); |
4405 | 3532 | ||
4406 | i915_gem_free_object_tail(obj); | 3533 | i915_gem_free_object_tail(obj); |
@@ -4427,13 +3554,15 @@ i915_gem_idle(struct drm_device *dev) | |||
4427 | 3554 | ||
4428 | /* Under UMS, be paranoid and evict. */ | 3555 | /* Under UMS, be paranoid and evict. */ |
4429 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) { | 3556 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) { |
4430 | ret = i915_gem_evict_inactive(dev); | 3557 | ret = i915_gem_evict_inactive(dev, false); |
4431 | if (ret) { | 3558 | if (ret) { |
4432 | mutex_unlock(&dev->struct_mutex); | 3559 | mutex_unlock(&dev->struct_mutex); |
4433 | return ret; | 3560 | return ret; |
4434 | } | 3561 | } |
4435 | } | 3562 | } |
4436 | 3563 | ||
3564 | i915_gem_reset_fences(dev); | ||
3565 | |||
4437 | /* Hack! Don't let anybody do execbuf while we don't control the chip. | 3566 | /* Hack! Don't let anybody do execbuf while we don't control the chip. |
4438 | * We need to replace this with a semaphore, or something. | 3567 | * We need to replace this with a semaphore, or something. |
4439 | * And not confound mm.suspended! | 3568 | * And not confound mm.suspended! |
@@ -4452,82 +3581,15 @@ i915_gem_idle(struct drm_device *dev) | |||
4452 | return 0; | 3581 | return 0; |
4453 | } | 3582 | } |
4454 | 3583 | ||
4455 | /* | ||
4456 | * 965+ support PIPE_CONTROL commands, which provide finer grained control | ||
4457 | * over cache flushing. | ||
4458 | */ | ||
4459 | static int | ||
4460 | i915_gem_init_pipe_control(struct drm_device *dev) | ||
4461 | { | ||
4462 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
4463 | struct drm_gem_object *obj; | ||
4464 | struct drm_i915_gem_object *obj_priv; | ||
4465 | int ret; | ||
4466 | |||
4467 | obj = i915_gem_alloc_object(dev, 4096); | ||
4468 | if (obj == NULL) { | ||
4469 | DRM_ERROR("Failed to allocate seqno page\n"); | ||
4470 | ret = -ENOMEM; | ||
4471 | goto err; | ||
4472 | } | ||
4473 | obj_priv = to_intel_bo(obj); | ||
4474 | obj_priv->agp_type = AGP_USER_CACHED_MEMORY; | ||
4475 | |||
4476 | ret = i915_gem_object_pin(obj, 4096); | ||
4477 | if (ret) | ||
4478 | goto err_unref; | ||
4479 | |||
4480 | dev_priv->seqno_gfx_addr = obj_priv->gtt_offset; | ||
4481 | dev_priv->seqno_page = kmap(obj_priv->pages[0]); | ||
4482 | if (dev_priv->seqno_page == NULL) | ||
4483 | goto err_unpin; | ||
4484 | |||
4485 | dev_priv->seqno_obj = obj; | ||
4486 | memset(dev_priv->seqno_page, 0, PAGE_SIZE); | ||
4487 | |||
4488 | return 0; | ||
4489 | |||
4490 | err_unpin: | ||
4491 | i915_gem_object_unpin(obj); | ||
4492 | err_unref: | ||
4493 | drm_gem_object_unreference(obj); | ||
4494 | err: | ||
4495 | return ret; | ||
4496 | } | ||
4497 | |||
4498 | |||
4499 | static void | ||
4500 | i915_gem_cleanup_pipe_control(struct drm_device *dev) | ||
4501 | { | ||
4502 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
4503 | struct drm_gem_object *obj; | ||
4504 | struct drm_i915_gem_object *obj_priv; | ||
4505 | |||
4506 | obj = dev_priv->seqno_obj; | ||
4507 | obj_priv = to_intel_bo(obj); | ||
4508 | kunmap(obj_priv->pages[0]); | ||
4509 | i915_gem_object_unpin(obj); | ||
4510 | drm_gem_object_unreference(obj); | ||
4511 | dev_priv->seqno_obj = NULL; | ||
4512 | |||
4513 | dev_priv->seqno_page = NULL; | ||
4514 | } | ||
4515 | |||
4516 | int | 3584 | int |
4517 | i915_gem_init_ringbuffer(struct drm_device *dev) | 3585 | i915_gem_init_ringbuffer(struct drm_device *dev) |
4518 | { | 3586 | { |
4519 | drm_i915_private_t *dev_priv = dev->dev_private; | 3587 | drm_i915_private_t *dev_priv = dev->dev_private; |
4520 | int ret; | 3588 | int ret; |
4521 | 3589 | ||
4522 | if (HAS_PIPE_CONTROL(dev)) { | ||
4523 | ret = i915_gem_init_pipe_control(dev); | ||
4524 | if (ret) | ||
4525 | return ret; | ||
4526 | } | ||
4527 | |||
4528 | ret = intel_init_render_ring_buffer(dev); | 3590 | ret = intel_init_render_ring_buffer(dev); |
4529 | if (ret) | 3591 | if (ret) |
4530 | goto cleanup_pipe_control; | 3592 | return ret; |
4531 | 3593 | ||
4532 | if (HAS_BSD(dev)) { | 3594 | if (HAS_BSD(dev)) { |
4533 | ret = intel_init_bsd_ring_buffer(dev); | 3595 | ret = intel_init_bsd_ring_buffer(dev); |
@@ -4546,12 +3608,9 @@ i915_gem_init_ringbuffer(struct drm_device *dev) | |||
4546 | return 0; | 3608 | return 0; |
4547 | 3609 | ||
4548 | cleanup_bsd_ring: | 3610 | cleanup_bsd_ring: |
4549 | intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); | 3611 | intel_cleanup_ring_buffer(&dev_priv->ring[VCS]); |
4550 | cleanup_render_ring: | 3612 | cleanup_render_ring: |
4551 | intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); | 3613 | intel_cleanup_ring_buffer(&dev_priv->ring[RCS]); |
4552 | cleanup_pipe_control: | ||
4553 | if (HAS_PIPE_CONTROL(dev)) | ||
4554 | i915_gem_cleanup_pipe_control(dev); | ||
4555 | return ret; | 3614 | return ret; |
4556 | } | 3615 | } |
4557 | 3616 | ||
@@ -4559,12 +3618,10 @@ void | |||
4559 | i915_gem_cleanup_ringbuffer(struct drm_device *dev) | 3618 | i915_gem_cleanup_ringbuffer(struct drm_device *dev) |
4560 | { | 3619 | { |
4561 | drm_i915_private_t *dev_priv = dev->dev_private; | 3620 | drm_i915_private_t *dev_priv = dev->dev_private; |
3621 | int i; | ||
4562 | 3622 | ||
4563 | intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); | 3623 | for (i = 0; i < I915_NUM_RINGS; i++) |
4564 | intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); | 3624 | intel_cleanup_ring_buffer(&dev_priv->ring[i]); |
4565 | intel_cleanup_ring_buffer(dev, &dev_priv->blt_ring); | ||
4566 | if (HAS_PIPE_CONTROL(dev)) | ||
4567 | i915_gem_cleanup_pipe_control(dev); | ||
4568 | } | 3625 | } |
4569 | 3626 | ||
4570 | int | 3627 | int |
@@ -4572,7 +3629,7 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, | |||
4572 | struct drm_file *file_priv) | 3629 | struct drm_file *file_priv) |
4573 | { | 3630 | { |
4574 | drm_i915_private_t *dev_priv = dev->dev_private; | 3631 | drm_i915_private_t *dev_priv = dev->dev_private; |
4575 | int ret; | 3632 | int ret, i; |
4576 | 3633 | ||
4577 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 3634 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
4578 | return 0; | 3635 | return 0; |
@@ -4592,14 +3649,12 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, | |||
4592 | } | 3649 | } |
4593 | 3650 | ||
4594 | BUG_ON(!list_empty(&dev_priv->mm.active_list)); | 3651 | BUG_ON(!list_empty(&dev_priv->mm.active_list)); |
4595 | BUG_ON(!list_empty(&dev_priv->render_ring.active_list)); | ||
4596 | BUG_ON(!list_empty(&dev_priv->bsd_ring.active_list)); | ||
4597 | BUG_ON(!list_empty(&dev_priv->blt_ring.active_list)); | ||
4598 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | 3652 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); |
4599 | BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); | 3653 | BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); |
4600 | BUG_ON(!list_empty(&dev_priv->render_ring.request_list)); | 3654 | for (i = 0; i < I915_NUM_RINGS; i++) { |
4601 | BUG_ON(!list_empty(&dev_priv->bsd_ring.request_list)); | 3655 | BUG_ON(!list_empty(&dev_priv->ring[i].active_list)); |
4602 | BUG_ON(!list_empty(&dev_priv->blt_ring.request_list)); | 3656 | BUG_ON(!list_empty(&dev_priv->ring[i].request_list)); |
3657 | } | ||
4603 | mutex_unlock(&dev->struct_mutex); | 3658 | mutex_unlock(&dev->struct_mutex); |
4604 | 3659 | ||
4605 | ret = drm_irq_install(dev); | 3660 | ret = drm_irq_install(dev); |
@@ -4661,17 +3716,14 @@ i915_gem_load(struct drm_device *dev) | |||
4661 | INIT_LIST_HEAD(&dev_priv->mm.pinned_list); | 3716 | INIT_LIST_HEAD(&dev_priv->mm.pinned_list); |
4662 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); | 3717 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); |
4663 | INIT_LIST_HEAD(&dev_priv->mm.deferred_free_list); | 3718 | INIT_LIST_HEAD(&dev_priv->mm.deferred_free_list); |
4664 | init_ring_lists(&dev_priv->render_ring); | 3719 | INIT_LIST_HEAD(&dev_priv->mm.gtt_list); |
4665 | init_ring_lists(&dev_priv->bsd_ring); | 3720 | for (i = 0; i < I915_NUM_RINGS; i++) |
4666 | init_ring_lists(&dev_priv->blt_ring); | 3721 | init_ring_lists(&dev_priv->ring[i]); |
4667 | for (i = 0; i < 16; i++) | 3722 | for (i = 0; i < 16; i++) |
4668 | INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); | 3723 | INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); |
4669 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, | 3724 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, |
4670 | i915_gem_retire_work_handler); | 3725 | i915_gem_retire_work_handler); |
4671 | init_completion(&dev_priv->error_completion); | 3726 | init_completion(&dev_priv->error_completion); |
4672 | spin_lock(&shrink_list_lock); | ||
4673 | list_add(&dev_priv->mm.shrink_list, &shrink_list); | ||
4674 | spin_unlock(&shrink_list_lock); | ||
4675 | 3727 | ||
4676 | /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ | 3728 | /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ |
4677 | if (IS_GEN3(dev)) { | 3729 | if (IS_GEN3(dev)) { |
@@ -4683,6 +3735,8 @@ i915_gem_load(struct drm_device *dev) | |||
4683 | } | 3735 | } |
4684 | } | 3736 | } |
4685 | 3737 | ||
3738 | dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL; | ||
3739 | |||
4686 | /* Old X drivers will take 0-2 for front, back, depth buffers */ | 3740 | /* Old X drivers will take 0-2 for front, back, depth buffers */ |
4687 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 3741 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
4688 | dev_priv->fence_reg_start = 3; | 3742 | dev_priv->fence_reg_start = 3; |
@@ -4714,6 +3768,10 @@ i915_gem_load(struct drm_device *dev) | |||
4714 | } | 3768 | } |
4715 | i915_gem_detect_bit_6_swizzle(dev); | 3769 | i915_gem_detect_bit_6_swizzle(dev); |
4716 | init_waitqueue_head(&dev_priv->pending_flip_queue); | 3770 | init_waitqueue_head(&dev_priv->pending_flip_queue); |
3771 | |||
3772 | dev_priv->mm.inactive_shrinker.shrink = i915_gem_inactive_shrink; | ||
3773 | dev_priv->mm.inactive_shrinker.seeks = DEFAULT_SEEKS; | ||
3774 | register_shrinker(&dev_priv->mm.inactive_shrinker); | ||
4717 | } | 3775 | } |
4718 | 3776 | ||
4719 | /* | 3777 | /* |
@@ -4783,47 +3841,47 @@ void i915_gem_free_all_phys_object(struct drm_device *dev) | |||
4783 | } | 3841 | } |
4784 | 3842 | ||
4785 | void i915_gem_detach_phys_object(struct drm_device *dev, | 3843 | void i915_gem_detach_phys_object(struct drm_device *dev, |
4786 | struct drm_gem_object *obj) | 3844 | struct drm_i915_gem_object *obj) |
4787 | { | 3845 | { |
4788 | struct drm_i915_gem_object *obj_priv; | 3846 | struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; |
3847 | char *vaddr; | ||
4789 | int i; | 3848 | int i; |
4790 | int ret; | ||
4791 | int page_count; | 3849 | int page_count; |
4792 | 3850 | ||
4793 | obj_priv = to_intel_bo(obj); | 3851 | if (!obj->phys_obj) |
4794 | if (!obj_priv->phys_obj) | ||
4795 | return; | 3852 | return; |
3853 | vaddr = obj->phys_obj->handle->vaddr; | ||
4796 | 3854 | ||
4797 | ret = i915_gem_object_get_pages(obj, 0); | 3855 | page_count = obj->base.size / PAGE_SIZE; |
4798 | if (ret) | ||
4799 | goto out; | ||
4800 | |||
4801 | page_count = obj->size / PAGE_SIZE; | ||
4802 | |||
4803 | for (i = 0; i < page_count; i++) { | 3856 | for (i = 0; i < page_count; i++) { |
4804 | char *dst = kmap_atomic(obj_priv->pages[i]); | 3857 | struct page *page = read_cache_page_gfp(mapping, i, |
4805 | char *src = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); | 3858 | GFP_HIGHUSER | __GFP_RECLAIMABLE); |
4806 | 3859 | if (!IS_ERR(page)) { | |
4807 | memcpy(dst, src, PAGE_SIZE); | 3860 | char *dst = kmap_atomic(page); |
4808 | kunmap_atomic(dst); | 3861 | memcpy(dst, vaddr + i*PAGE_SIZE, PAGE_SIZE); |
3862 | kunmap_atomic(dst); | ||
3863 | |||
3864 | drm_clflush_pages(&page, 1); | ||
3865 | |||
3866 | set_page_dirty(page); | ||
3867 | mark_page_accessed(page); | ||
3868 | page_cache_release(page); | ||
3869 | } | ||
4809 | } | 3870 | } |
4810 | drm_clflush_pages(obj_priv->pages, page_count); | 3871 | intel_gtt_chipset_flush(); |
4811 | drm_agp_chipset_flush(dev); | ||
4812 | 3872 | ||
4813 | i915_gem_object_put_pages(obj); | 3873 | obj->phys_obj->cur_obj = NULL; |
4814 | out: | 3874 | obj->phys_obj = NULL; |
4815 | obj_priv->phys_obj->cur_obj = NULL; | ||
4816 | obj_priv->phys_obj = NULL; | ||
4817 | } | 3875 | } |
4818 | 3876 | ||
4819 | int | 3877 | int |
4820 | i915_gem_attach_phys_object(struct drm_device *dev, | 3878 | i915_gem_attach_phys_object(struct drm_device *dev, |
4821 | struct drm_gem_object *obj, | 3879 | struct drm_i915_gem_object *obj, |
4822 | int id, | 3880 | int id, |
4823 | int align) | 3881 | int align) |
4824 | { | 3882 | { |
3883 | struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; | ||
4825 | drm_i915_private_t *dev_priv = dev->dev_private; | 3884 | drm_i915_private_t *dev_priv = dev->dev_private; |
4826 | struct drm_i915_gem_object *obj_priv; | ||
4827 | int ret = 0; | 3885 | int ret = 0; |
4828 | int page_count; | 3886 | int page_count; |
4829 | int i; | 3887 | int i; |
@@ -4831,10 +3889,8 @@ i915_gem_attach_phys_object(struct drm_device *dev, | |||
4831 | if (id > I915_MAX_PHYS_OBJECT) | 3889 | if (id > I915_MAX_PHYS_OBJECT) |
4832 | return -EINVAL; | 3890 | return -EINVAL; |
4833 | 3891 | ||
4834 | obj_priv = to_intel_bo(obj); | 3892 | if (obj->phys_obj) { |
4835 | 3893 | if (obj->phys_obj->id == id) | |
4836 | if (obj_priv->phys_obj) { | ||
4837 | if (obj_priv->phys_obj->id == id) | ||
4838 | return 0; | 3894 | return 0; |
4839 | i915_gem_detach_phys_object(dev, obj); | 3895 | i915_gem_detach_phys_object(dev, obj); |
4840 | } | 3896 | } |
@@ -4842,51 +3898,50 @@ i915_gem_attach_phys_object(struct drm_device *dev, | |||
4842 | /* create a new object */ | 3898 | /* create a new object */ |
4843 | if (!dev_priv->mm.phys_objs[id - 1]) { | 3899 | if (!dev_priv->mm.phys_objs[id - 1]) { |
4844 | ret = i915_gem_init_phys_object(dev, id, | 3900 | ret = i915_gem_init_phys_object(dev, id, |
4845 | obj->size, align); | 3901 | obj->base.size, align); |
4846 | if (ret) { | 3902 | if (ret) { |
4847 | DRM_ERROR("failed to init phys object %d size: %zu\n", id, obj->size); | 3903 | DRM_ERROR("failed to init phys object %d size: %zu\n", |
4848 | goto out; | 3904 | id, obj->base.size); |
3905 | return ret; | ||
4849 | } | 3906 | } |
4850 | } | 3907 | } |
4851 | 3908 | ||
4852 | /* bind to the object */ | 3909 | /* bind to the object */ |
4853 | obj_priv->phys_obj = dev_priv->mm.phys_objs[id - 1]; | 3910 | obj->phys_obj = dev_priv->mm.phys_objs[id - 1]; |
4854 | obj_priv->phys_obj->cur_obj = obj; | 3911 | obj->phys_obj->cur_obj = obj; |
4855 | |||
4856 | ret = i915_gem_object_get_pages(obj, 0); | ||
4857 | if (ret) { | ||
4858 | DRM_ERROR("failed to get page list\n"); | ||
4859 | goto out; | ||
4860 | } | ||
4861 | 3912 | ||
4862 | page_count = obj->size / PAGE_SIZE; | 3913 | page_count = obj->base.size / PAGE_SIZE; |
4863 | 3914 | ||
4864 | for (i = 0; i < page_count; i++) { | 3915 | for (i = 0; i < page_count; i++) { |
4865 | char *src = kmap_atomic(obj_priv->pages[i]); | 3916 | struct page *page; |
4866 | char *dst = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); | 3917 | char *dst, *src; |
4867 | 3918 | ||
3919 | page = read_cache_page_gfp(mapping, i, | ||
3920 | GFP_HIGHUSER | __GFP_RECLAIMABLE); | ||
3921 | if (IS_ERR(page)) | ||
3922 | return PTR_ERR(page); | ||
3923 | |||
3924 | src = kmap_atomic(page); | ||
3925 | dst = obj->phys_obj->handle->vaddr + (i * PAGE_SIZE); | ||
4868 | memcpy(dst, src, PAGE_SIZE); | 3926 | memcpy(dst, src, PAGE_SIZE); |
4869 | kunmap_atomic(src); | 3927 | kunmap_atomic(src); |
4870 | } | ||
4871 | 3928 | ||
4872 | i915_gem_object_put_pages(obj); | 3929 | mark_page_accessed(page); |
3930 | page_cache_release(page); | ||
3931 | } | ||
4873 | 3932 | ||
4874 | return 0; | 3933 | return 0; |
4875 | out: | ||
4876 | return ret; | ||
4877 | } | 3934 | } |
4878 | 3935 | ||
4879 | static int | 3936 | static int |
4880 | i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | 3937 | i915_gem_phys_pwrite(struct drm_device *dev, |
3938 | struct drm_i915_gem_object *obj, | ||
4881 | struct drm_i915_gem_pwrite *args, | 3939 | struct drm_i915_gem_pwrite *args, |
4882 | struct drm_file *file_priv) | 3940 | struct drm_file *file_priv) |
4883 | { | 3941 | { |
4884 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 3942 | void *vaddr = obj->phys_obj->handle->vaddr + args->offset; |
4885 | void *vaddr = obj_priv->phys_obj->handle->vaddr + args->offset; | ||
4886 | char __user *user_data = (char __user *) (uintptr_t) args->data_ptr; | 3943 | char __user *user_data = (char __user *) (uintptr_t) args->data_ptr; |
4887 | 3944 | ||
4888 | DRM_DEBUG_DRIVER("vaddr %p, %lld\n", vaddr, args->size); | ||
4889 | |||
4890 | if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) { | 3945 | if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) { |
4891 | unsigned long unwritten; | 3946 | unsigned long unwritten; |
4892 | 3947 | ||
@@ -4901,7 +3956,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | |||
4901 | return -EFAULT; | 3956 | return -EFAULT; |
4902 | } | 3957 | } |
4903 | 3958 | ||
4904 | drm_agp_chipset_flush(dev); | 3959 | intel_gtt_chipset_flush(); |
4905 | return 0; | 3960 | return 0; |
4906 | } | 3961 | } |
4907 | 3962 | ||
@@ -4939,144 +3994,68 @@ i915_gpu_is_active(struct drm_device *dev) | |||
4939 | } | 3994 | } |
4940 | 3995 | ||
4941 | static int | 3996 | static int |
4942 | i915_gem_shrink(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask) | 3997 | i915_gem_inactive_shrink(struct shrinker *shrinker, |
4943 | { | 3998 | int nr_to_scan, |
4944 | drm_i915_private_t *dev_priv, *next_dev; | 3999 | gfp_t gfp_mask) |
4945 | struct drm_i915_gem_object *obj_priv, *next_obj; | 4000 | { |
4946 | int cnt = 0; | 4001 | struct drm_i915_private *dev_priv = |
4947 | int would_deadlock = 1; | 4002 | container_of(shrinker, |
4003 | struct drm_i915_private, | ||
4004 | mm.inactive_shrinker); | ||
4005 | struct drm_device *dev = dev_priv->dev; | ||
4006 | struct drm_i915_gem_object *obj, *next; | ||
4007 | int cnt; | ||
4008 | |||
4009 | if (!mutex_trylock(&dev->struct_mutex)) | ||
4010 | return 0; | ||
4948 | 4011 | ||
4949 | /* "fast-path" to count number of available objects */ | 4012 | /* "fast-path" to count number of available objects */ |
4950 | if (nr_to_scan == 0) { | 4013 | if (nr_to_scan == 0) { |
4951 | spin_lock(&shrink_list_lock); | 4014 | cnt = 0; |
4952 | list_for_each_entry(dev_priv, &shrink_list, mm.shrink_list) { | 4015 | list_for_each_entry(obj, |
4953 | struct drm_device *dev = dev_priv->dev; | 4016 | &dev_priv->mm.inactive_list, |
4954 | 4017 | mm_list) | |
4955 | if (mutex_trylock(&dev->struct_mutex)) { | 4018 | cnt++; |
4956 | list_for_each_entry(obj_priv, | 4019 | mutex_unlock(&dev->struct_mutex); |
4957 | &dev_priv->mm.inactive_list, | 4020 | return cnt / 100 * sysctl_vfs_cache_pressure; |
4958 | mm_list) | ||
4959 | cnt++; | ||
4960 | mutex_unlock(&dev->struct_mutex); | ||
4961 | } | ||
4962 | } | ||
4963 | spin_unlock(&shrink_list_lock); | ||
4964 | |||
4965 | return (cnt / 100) * sysctl_vfs_cache_pressure; | ||
4966 | } | 4021 | } |
4967 | 4022 | ||
4968 | spin_lock(&shrink_list_lock); | ||
4969 | |||
4970 | rescan: | 4023 | rescan: |
4971 | /* first scan for clean buffers */ | 4024 | /* first scan for clean buffers */ |
4972 | list_for_each_entry_safe(dev_priv, next_dev, | 4025 | i915_gem_retire_requests(dev); |
4973 | &shrink_list, mm.shrink_list) { | ||
4974 | struct drm_device *dev = dev_priv->dev; | ||
4975 | |||
4976 | if (! mutex_trylock(&dev->struct_mutex)) | ||
4977 | continue; | ||
4978 | |||
4979 | spin_unlock(&shrink_list_lock); | ||
4980 | i915_gem_retire_requests(dev); | ||
4981 | 4026 | ||
4982 | list_for_each_entry_safe(obj_priv, next_obj, | 4027 | list_for_each_entry_safe(obj, next, |
4983 | &dev_priv->mm.inactive_list, | 4028 | &dev_priv->mm.inactive_list, |
4984 | mm_list) { | 4029 | mm_list) { |
4985 | if (i915_gem_object_is_purgeable(obj_priv)) { | 4030 | if (i915_gem_object_is_purgeable(obj)) { |
4986 | i915_gem_object_unbind(&obj_priv->base); | 4031 | if (i915_gem_object_unbind(obj) == 0 && |
4987 | if (--nr_to_scan <= 0) | 4032 | --nr_to_scan == 0) |
4988 | break; | 4033 | break; |
4989 | } | ||
4990 | } | 4034 | } |
4991 | |||
4992 | spin_lock(&shrink_list_lock); | ||
4993 | mutex_unlock(&dev->struct_mutex); | ||
4994 | |||
4995 | would_deadlock = 0; | ||
4996 | |||
4997 | if (nr_to_scan <= 0) | ||
4998 | break; | ||
4999 | } | 4035 | } |
5000 | 4036 | ||
5001 | /* second pass, evict/count anything still on the inactive list */ | 4037 | /* second pass, evict/count anything still on the inactive list */ |
5002 | list_for_each_entry_safe(dev_priv, next_dev, | 4038 | cnt = 0; |
5003 | &shrink_list, mm.shrink_list) { | 4039 | list_for_each_entry_safe(obj, next, |
5004 | struct drm_device *dev = dev_priv->dev; | 4040 | &dev_priv->mm.inactive_list, |
5005 | 4041 | mm_list) { | |
5006 | if (! mutex_trylock(&dev->struct_mutex)) | 4042 | if (nr_to_scan && |
5007 | continue; | 4043 | i915_gem_object_unbind(obj) == 0) |
5008 | 4044 | nr_to_scan--; | |
5009 | spin_unlock(&shrink_list_lock); | 4045 | else |
5010 | 4046 | cnt++; | |
5011 | list_for_each_entry_safe(obj_priv, next_obj, | ||
5012 | &dev_priv->mm.inactive_list, | ||
5013 | mm_list) { | ||
5014 | if (nr_to_scan > 0) { | ||
5015 | i915_gem_object_unbind(&obj_priv->base); | ||
5016 | nr_to_scan--; | ||
5017 | } else | ||
5018 | cnt++; | ||
5019 | } | ||
5020 | |||
5021 | spin_lock(&shrink_list_lock); | ||
5022 | mutex_unlock(&dev->struct_mutex); | ||
5023 | |||
5024 | would_deadlock = 0; | ||
5025 | } | 4047 | } |
5026 | 4048 | ||
5027 | if (nr_to_scan) { | 4049 | if (nr_to_scan && i915_gpu_is_active(dev)) { |
5028 | int active = 0; | ||
5029 | |||
5030 | /* | 4050 | /* |
5031 | * We are desperate for pages, so as a last resort, wait | 4051 | * We are desperate for pages, so as a last resort, wait |
5032 | * for the GPU to finish and discard whatever we can. | 4052 | * for the GPU to finish and discard whatever we can. |
5033 | * This has a dramatic impact to reduce the number of | 4053 | * This has a dramatic impact to reduce the number of |
5034 | * OOM-killer events whilst running the GPU aggressively. | 4054 | * OOM-killer events whilst running the GPU aggressively. |
5035 | */ | 4055 | */ |
5036 | list_for_each_entry(dev_priv, &shrink_list, mm.shrink_list) { | 4056 | if (i915_gpu_idle(dev) == 0) |
5037 | struct drm_device *dev = dev_priv->dev; | ||
5038 | |||
5039 | if (!mutex_trylock(&dev->struct_mutex)) | ||
5040 | continue; | ||
5041 | |||
5042 | spin_unlock(&shrink_list_lock); | ||
5043 | |||
5044 | if (i915_gpu_is_active(dev)) { | ||
5045 | i915_gpu_idle(dev); | ||
5046 | active++; | ||
5047 | } | ||
5048 | |||
5049 | spin_lock(&shrink_list_lock); | ||
5050 | mutex_unlock(&dev->struct_mutex); | ||
5051 | } | ||
5052 | |||
5053 | if (active) | ||
5054 | goto rescan; | 4057 | goto rescan; |
5055 | } | 4058 | } |
5056 | 4059 | mutex_unlock(&dev->struct_mutex); | |
5057 | spin_unlock(&shrink_list_lock); | 4060 | return cnt / 100 * sysctl_vfs_cache_pressure; |
5058 | |||
5059 | if (would_deadlock) | ||
5060 | return -1; | ||
5061 | else if (cnt > 0) | ||
5062 | return (cnt / 100) * sysctl_vfs_cache_pressure; | ||
5063 | else | ||
5064 | return 0; | ||
5065 | } | ||
5066 | |||
5067 | static struct shrinker shrinker = { | ||
5068 | .shrink = i915_gem_shrink, | ||
5069 | .seeks = DEFAULT_SEEKS, | ||
5070 | }; | ||
5071 | |||
5072 | __init void | ||
5073 | i915_gem_shrinker_init(void) | ||
5074 | { | ||
5075 | register_shrinker(&shrinker); | ||
5076 | } | ||
5077 | |||
5078 | __exit void | ||
5079 | i915_gem_shrinker_exit(void) | ||
5080 | { | ||
5081 | unregister_shrinker(&shrinker); | ||
5082 | } | 4061 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c index 48644b840a8..29d014c48ca 100644 --- a/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/drivers/gpu/drm/i915/i915_gem_debug.c | |||
@@ -152,13 +152,12 @@ i915_gem_dump_page(struct page *page, uint32_t start, uint32_t end, | |||
152 | } | 152 | } |
153 | 153 | ||
154 | void | 154 | void |
155 | i915_gem_dump_object(struct drm_gem_object *obj, int len, | 155 | i915_gem_dump_object(struct drm_i915_gem_object *obj, int len, |
156 | const char *where, uint32_t mark) | 156 | const char *where, uint32_t mark) |
157 | { | 157 | { |
158 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
159 | int page; | 158 | int page; |
160 | 159 | ||
161 | DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset); | 160 | DRM_INFO("%s: object at offset %08x\n", where, obj->gtt_offset); |
162 | for (page = 0; page < (len + PAGE_SIZE-1) / PAGE_SIZE; page++) { | 161 | for (page = 0; page < (len + PAGE_SIZE-1) / PAGE_SIZE; page++) { |
163 | int page_len, chunk, chunk_len; | 162 | int page_len, chunk, chunk_len; |
164 | 163 | ||
@@ -170,9 +169,9 @@ i915_gem_dump_object(struct drm_gem_object *obj, int len, | |||
170 | chunk_len = page_len - chunk; | 169 | chunk_len = page_len - chunk; |
171 | if (chunk_len > 128) | 170 | if (chunk_len > 128) |
172 | chunk_len = 128; | 171 | chunk_len = 128; |
173 | i915_gem_dump_page(obj_priv->pages[page], | 172 | i915_gem_dump_page(obj->pages[page], |
174 | chunk, chunk + chunk_len, | 173 | chunk, chunk + chunk_len, |
175 | obj_priv->gtt_offset + | 174 | obj->gtt_offset + |
176 | page * PAGE_SIZE, | 175 | page * PAGE_SIZE, |
177 | mark); | 176 | mark); |
178 | } | 177 | } |
@@ -182,21 +181,19 @@ i915_gem_dump_object(struct drm_gem_object *obj, int len, | |||
182 | 181 | ||
183 | #if WATCH_COHERENCY | 182 | #if WATCH_COHERENCY |
184 | void | 183 | void |
185 | i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) | 184 | i915_gem_object_check_coherency(struct drm_i915_gem_object *obj, int handle) |
186 | { | 185 | { |
187 | struct drm_device *dev = obj->dev; | 186 | struct drm_device *dev = obj->base.dev; |
188 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
189 | int page; | 187 | int page; |
190 | uint32_t *gtt_mapping; | 188 | uint32_t *gtt_mapping; |
191 | uint32_t *backing_map = NULL; | 189 | uint32_t *backing_map = NULL; |
192 | int bad_count = 0; | 190 | int bad_count = 0; |
193 | 191 | ||
194 | DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %zdkb):\n", | 192 | DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %zdkb):\n", |
195 | __func__, obj, obj_priv->gtt_offset, handle, | 193 | __func__, obj, obj->gtt_offset, handle, |
196 | obj->size / 1024); | 194 | obj->size / 1024); |
197 | 195 | ||
198 | gtt_mapping = ioremap(dev->agp->base + obj_priv->gtt_offset, | 196 | gtt_mapping = ioremap(dev->agp->base + obj->gtt_offset, obj->base.size); |
199 | obj->size); | ||
200 | if (gtt_mapping == NULL) { | 197 | if (gtt_mapping == NULL) { |
201 | DRM_ERROR("failed to map GTT space\n"); | 198 | DRM_ERROR("failed to map GTT space\n"); |
202 | return; | 199 | return; |
@@ -205,7 +202,7 @@ i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) | |||
205 | for (page = 0; page < obj->size / PAGE_SIZE; page++) { | 202 | for (page = 0; page < obj->size / PAGE_SIZE; page++) { |
206 | int i; | 203 | int i; |
207 | 204 | ||
208 | backing_map = kmap_atomic(obj_priv->pages[page], KM_USER0); | 205 | backing_map = kmap_atomic(obj->pages[page], KM_USER0); |
209 | 206 | ||
210 | if (backing_map == NULL) { | 207 | if (backing_map == NULL) { |
211 | DRM_ERROR("failed to map backing page\n"); | 208 | DRM_ERROR("failed to map backing page\n"); |
@@ -220,7 +217,7 @@ i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) | |||
220 | if (cpuval != gttval) { | 217 | if (cpuval != gttval) { |
221 | DRM_INFO("incoherent CPU vs GPU at 0x%08x: " | 218 | DRM_INFO("incoherent CPU vs GPU at 0x%08x: " |
222 | "0x%08x vs 0x%08x\n", | 219 | "0x%08x vs 0x%08x\n", |
223 | (int)(obj_priv->gtt_offset + | 220 | (int)(obj->gtt_offset + |
224 | page * PAGE_SIZE + i * 4), | 221 | page * PAGE_SIZE + i * 4), |
225 | cpuval, gttval); | 222 | cpuval, gttval); |
226 | if (bad_count++ >= 8) { | 223 | if (bad_count++ >= 8) { |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index d8ae7d1d0cc..78b8cf90c92 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -32,28 +32,36 @@ | |||
32 | #include "i915_drm.h" | 32 | #include "i915_drm.h" |
33 | 33 | ||
34 | static bool | 34 | static bool |
35 | mark_free(struct drm_i915_gem_object *obj_priv, | 35 | mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind) |
36 | struct list_head *unwind) | ||
37 | { | 36 | { |
38 | list_add(&obj_priv->evict_list, unwind); | 37 | list_add(&obj->exec_list, unwind); |
39 | drm_gem_object_reference(&obj_priv->base); | 38 | drm_gem_object_reference(&obj->base); |
40 | return drm_mm_scan_add_block(obj_priv->gtt_space); | 39 | return drm_mm_scan_add_block(obj->gtt_space); |
41 | } | 40 | } |
42 | 41 | ||
43 | int | 42 | int |
44 | i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment) | 43 | i915_gem_evict_something(struct drm_device *dev, int min_size, |
44 | unsigned alignment, bool mappable) | ||
45 | { | 45 | { |
46 | drm_i915_private_t *dev_priv = dev->dev_private; | 46 | drm_i915_private_t *dev_priv = dev->dev_private; |
47 | struct list_head eviction_list, unwind_list; | 47 | struct list_head eviction_list, unwind_list; |
48 | struct drm_i915_gem_object *obj_priv; | 48 | struct drm_i915_gem_object *obj; |
49 | int ret = 0; | 49 | int ret = 0; |
50 | 50 | ||
51 | i915_gem_retire_requests(dev); | 51 | i915_gem_retire_requests(dev); |
52 | 52 | ||
53 | /* Re-check for free space after retiring requests */ | 53 | /* Re-check for free space after retiring requests */ |
54 | if (drm_mm_search_free(&dev_priv->mm.gtt_space, | 54 | if (mappable) { |
55 | min_size, alignment, 0)) | 55 | if (drm_mm_search_free_in_range(&dev_priv->mm.gtt_space, |
56 | return 0; | 56 | min_size, alignment, 0, |
57 | dev_priv->mm.gtt_mappable_end, | ||
58 | 0)) | ||
59 | return 0; | ||
60 | } else { | ||
61 | if (drm_mm_search_free(&dev_priv->mm.gtt_space, | ||
62 | min_size, alignment, 0)) | ||
63 | return 0; | ||
64 | } | ||
57 | 65 | ||
58 | /* | 66 | /* |
59 | * The goal is to evict objects and amalgamate space in LRU order. | 67 | * The goal is to evict objects and amalgamate space in LRU order. |
@@ -79,45 +87,50 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen | |||
79 | */ | 87 | */ |
80 | 88 | ||
81 | INIT_LIST_HEAD(&unwind_list); | 89 | INIT_LIST_HEAD(&unwind_list); |
82 | drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment); | 90 | if (mappable) |
91 | drm_mm_init_scan_with_range(&dev_priv->mm.gtt_space, min_size, | ||
92 | alignment, 0, | ||
93 | dev_priv->mm.gtt_mappable_end); | ||
94 | else | ||
95 | drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment); | ||
83 | 96 | ||
84 | /* First see if there is a large enough contiguous idle region... */ | 97 | /* First see if there is a large enough contiguous idle region... */ |
85 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, mm_list) { | 98 | list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) { |
86 | if (mark_free(obj_priv, &unwind_list)) | 99 | if (mark_free(obj, &unwind_list)) |
87 | goto found; | 100 | goto found; |
88 | } | 101 | } |
89 | 102 | ||
90 | /* Now merge in the soon-to-be-expired objects... */ | 103 | /* Now merge in the soon-to-be-expired objects... */ |
91 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, mm_list) { | 104 | list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { |
92 | /* Does the object require an outstanding flush? */ | 105 | /* Does the object require an outstanding flush? */ |
93 | if (obj_priv->base.write_domain || obj_priv->pin_count) | 106 | if (obj->base.write_domain || obj->pin_count) |
94 | continue; | 107 | continue; |
95 | 108 | ||
96 | if (mark_free(obj_priv, &unwind_list)) | 109 | if (mark_free(obj, &unwind_list)) |
97 | goto found; | 110 | goto found; |
98 | } | 111 | } |
99 | 112 | ||
100 | /* Finally add anything with a pending flush (in order of retirement) */ | 113 | /* Finally add anything with a pending flush (in order of retirement) */ |
101 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, mm_list) { | 114 | list_for_each_entry(obj, &dev_priv->mm.flushing_list, mm_list) { |
102 | if (obj_priv->pin_count) | 115 | if (obj->pin_count) |
103 | continue; | 116 | continue; |
104 | 117 | ||
105 | if (mark_free(obj_priv, &unwind_list)) | 118 | if (mark_free(obj, &unwind_list)) |
106 | goto found; | 119 | goto found; |
107 | } | 120 | } |
108 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, mm_list) { | 121 | list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { |
109 | if (! obj_priv->base.write_domain || obj_priv->pin_count) | 122 | if (! obj->base.write_domain || obj->pin_count) |
110 | continue; | 123 | continue; |
111 | 124 | ||
112 | if (mark_free(obj_priv, &unwind_list)) | 125 | if (mark_free(obj, &unwind_list)) |
113 | goto found; | 126 | goto found; |
114 | } | 127 | } |
115 | 128 | ||
116 | /* Nothing found, clean up and bail out! */ | 129 | /* Nothing found, clean up and bail out! */ |
117 | list_for_each_entry(obj_priv, &unwind_list, evict_list) { | 130 | list_for_each_entry(obj, &unwind_list, exec_list) { |
118 | ret = drm_mm_scan_remove_block(obj_priv->gtt_space); | 131 | ret = drm_mm_scan_remove_block(obj->gtt_space); |
119 | BUG_ON(ret); | 132 | BUG_ON(ret); |
120 | drm_gem_object_unreference(&obj_priv->base); | 133 | drm_gem_object_unreference(&obj->base); |
121 | } | 134 | } |
122 | 135 | ||
123 | /* We expect the caller to unpin, evict all and try again, or give up. | 136 | /* We expect the caller to unpin, evict all and try again, or give up. |
@@ -131,33 +144,33 @@ found: | |||
131 | * temporary list. */ | 144 | * temporary list. */ |
132 | INIT_LIST_HEAD(&eviction_list); | 145 | INIT_LIST_HEAD(&eviction_list); |
133 | while (!list_empty(&unwind_list)) { | 146 | while (!list_empty(&unwind_list)) { |
134 | obj_priv = list_first_entry(&unwind_list, | 147 | obj = list_first_entry(&unwind_list, |
135 | struct drm_i915_gem_object, | 148 | struct drm_i915_gem_object, |
136 | evict_list); | 149 | exec_list); |
137 | if (drm_mm_scan_remove_block(obj_priv->gtt_space)) { | 150 | if (drm_mm_scan_remove_block(obj->gtt_space)) { |
138 | list_move(&obj_priv->evict_list, &eviction_list); | 151 | list_move(&obj->exec_list, &eviction_list); |
139 | continue; | 152 | continue; |
140 | } | 153 | } |
141 | list_del(&obj_priv->evict_list); | 154 | list_del_init(&obj->exec_list); |
142 | drm_gem_object_unreference(&obj_priv->base); | 155 | drm_gem_object_unreference(&obj->base); |
143 | } | 156 | } |
144 | 157 | ||
145 | /* Unbinding will emit any required flushes */ | 158 | /* Unbinding will emit any required flushes */ |
146 | while (!list_empty(&eviction_list)) { | 159 | while (!list_empty(&eviction_list)) { |
147 | obj_priv = list_first_entry(&eviction_list, | 160 | obj = list_first_entry(&eviction_list, |
148 | struct drm_i915_gem_object, | 161 | struct drm_i915_gem_object, |
149 | evict_list); | 162 | exec_list); |
150 | if (ret == 0) | 163 | if (ret == 0) |
151 | ret = i915_gem_object_unbind(&obj_priv->base); | 164 | ret = i915_gem_object_unbind(obj); |
152 | list_del(&obj_priv->evict_list); | 165 | list_del_init(&obj->exec_list); |
153 | drm_gem_object_unreference(&obj_priv->base); | 166 | drm_gem_object_unreference(&obj->base); |
154 | } | 167 | } |
155 | 168 | ||
156 | return ret; | 169 | return ret; |
157 | } | 170 | } |
158 | 171 | ||
159 | int | 172 | int |
160 | i915_gem_evict_everything(struct drm_device *dev) | 173 | i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only) |
161 | { | 174 | { |
162 | drm_i915_private_t *dev_priv = dev->dev_private; | 175 | drm_i915_private_t *dev_priv = dev->dev_private; |
163 | int ret; | 176 | int ret; |
@@ -176,36 +189,22 @@ i915_gem_evict_everything(struct drm_device *dev) | |||
176 | 189 | ||
177 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | 190 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); |
178 | 191 | ||
179 | ret = i915_gem_evict_inactive(dev); | 192 | return i915_gem_evict_inactive(dev, purgeable_only); |
180 | if (ret) | ||
181 | return ret; | ||
182 | |||
183 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
184 | list_empty(&dev_priv->mm.flushing_list) && | ||
185 | list_empty(&dev_priv->mm.active_list)); | ||
186 | BUG_ON(!lists_empty); | ||
187 | |||
188 | return 0; | ||
189 | } | 193 | } |
190 | 194 | ||
191 | /** Unbinds all inactive objects. */ | 195 | /** Unbinds all inactive objects. */ |
192 | int | 196 | int |
193 | i915_gem_evict_inactive(struct drm_device *dev) | 197 | i915_gem_evict_inactive(struct drm_device *dev, bool purgeable_only) |
194 | { | 198 | { |
195 | drm_i915_private_t *dev_priv = dev->dev_private; | 199 | drm_i915_private_t *dev_priv = dev->dev_private; |
196 | 200 | struct drm_i915_gem_object *obj, *next; | |
197 | while (!list_empty(&dev_priv->mm.inactive_list)) { | 201 | |
198 | struct drm_gem_object *obj; | 202 | list_for_each_entry_safe(obj, next, |
199 | int ret; | 203 | &dev_priv->mm.inactive_list, mm_list) { |
200 | 204 | if (!purgeable_only || obj->madv != I915_MADV_WILLNEED) { | |
201 | obj = &list_first_entry(&dev_priv->mm.inactive_list, | 205 | int ret = i915_gem_object_unbind(obj); |
202 | struct drm_i915_gem_object, | 206 | if (ret) |
203 | mm_list)->base; | 207 | return ret; |
204 | |||
205 | ret = i915_gem_object_unbind(obj); | ||
206 | if (ret != 0) { | ||
207 | DRM_ERROR("Error unbinding object: %d\n", ret); | ||
208 | return ret; | ||
209 | } | 208 | } |
210 | } | 209 | } |
211 | 210 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c new file mode 100644 index 00000000000..61129e6759e --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -0,0 +1,1343 @@ | |||
1 | /* | ||
2 | * Copyright © 2008,2010 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: | ||
24 | * Eric Anholt <eric@anholt.net> | ||
25 | * Chris Wilson <chris@chris-wilson.co.uk> | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #include "drmP.h" | ||
30 | #include "drm.h" | ||
31 | #include "i915_drm.h" | ||
32 | #include "i915_drv.h" | ||
33 | #include "i915_trace.h" | ||
34 | #include "intel_drv.h" | ||
35 | |||
36 | struct change_domains { | ||
37 | uint32_t invalidate_domains; | ||
38 | uint32_t flush_domains; | ||
39 | uint32_t flush_rings; | ||
40 | }; | ||
41 | |||
42 | /* | ||
43 | * Set the next domain for the specified object. This | ||
44 | * may not actually perform the necessary flushing/invaliding though, | ||
45 | * as that may want to be batched with other set_domain operations | ||
46 | * | ||
47 | * This is (we hope) the only really tricky part of gem. The goal | ||
48 | * is fairly simple -- track which caches hold bits of the object | ||
49 | * and make sure they remain coherent. A few concrete examples may | ||
50 | * help to explain how it works. For shorthand, we use the notation | ||
51 | * (read_domains, write_domain), e.g. (CPU, CPU) to indicate the | ||
52 | * a pair of read and write domain masks. | ||
53 | * | ||
54 | * Case 1: the batch buffer | ||
55 | * | ||
56 | * 1. Allocated | ||
57 | * 2. Written by CPU | ||
58 | * 3. Mapped to GTT | ||
59 | * 4. Read by GPU | ||
60 | * 5. Unmapped from GTT | ||
61 | * 6. Freed | ||
62 | * | ||
63 | * Let's take these a step at a time | ||
64 | * | ||
65 | * 1. Allocated | ||
66 | * Pages allocated from the kernel may still have | ||
67 | * cache contents, so we set them to (CPU, CPU) always. | ||
68 | * 2. Written by CPU (using pwrite) | ||
69 | * The pwrite function calls set_domain (CPU, CPU) and | ||
70 | * this function does nothing (as nothing changes) | ||
71 | * 3. Mapped by GTT | ||
72 | * This function asserts that the object is not | ||
73 | * currently in any GPU-based read or write domains | ||
74 | * 4. Read by GPU | ||
75 | * i915_gem_execbuffer calls set_domain (COMMAND, 0). | ||
76 | * As write_domain is zero, this function adds in the | ||
77 | * current read domains (CPU+COMMAND, 0). | ||
78 | * flush_domains is set to CPU. | ||
79 | * invalidate_domains is set to COMMAND | ||
80 | * clflush is run to get data out of the CPU caches | ||
81 | * then i915_dev_set_domain calls i915_gem_flush to | ||
82 | * emit an MI_FLUSH and drm_agp_chipset_flush | ||
83 | * 5. Unmapped from GTT | ||
84 | * i915_gem_object_unbind calls set_domain (CPU, CPU) | ||
85 | * flush_domains and invalidate_domains end up both zero | ||
86 | * so no flushing/invalidating happens | ||
87 | * 6. Freed | ||
88 | * yay, done | ||
89 | * | ||
90 | * Case 2: The shared render buffer | ||
91 | * | ||
92 | * 1. Allocated | ||
93 | * 2. Mapped to GTT | ||
94 | * 3. Read/written by GPU | ||
95 | * 4. set_domain to (CPU,CPU) | ||
96 | * 5. Read/written by CPU | ||
97 | * 6. Read/written by GPU | ||
98 | * | ||
99 | * 1. Allocated | ||
100 | * Same as last example, (CPU, CPU) | ||
101 | * 2. Mapped to GTT | ||
102 | * Nothing changes (assertions find that it is not in the GPU) | ||
103 | * 3. Read/written by GPU | ||
104 | * execbuffer calls set_domain (RENDER, RENDER) | ||
105 | * flush_domains gets CPU | ||
106 | * invalidate_domains gets GPU | ||
107 | * clflush (obj) | ||
108 | * MI_FLUSH and drm_agp_chipset_flush | ||
109 | * 4. set_domain (CPU, CPU) | ||
110 | * flush_domains gets GPU | ||
111 | * invalidate_domains gets CPU | ||
112 | * wait_rendering (obj) to make sure all drawing is complete. | ||
113 | * This will include an MI_FLUSH to get the data from GPU | ||
114 | * to memory | ||
115 | * clflush (obj) to invalidate the CPU cache | ||
116 | * Another MI_FLUSH in i915_gem_flush (eliminate this somehow?) | ||
117 | * 5. Read/written by CPU | ||
118 | * cache lines are loaded and dirtied | ||
119 | * 6. Read written by GPU | ||
120 | * Same as last GPU access | ||
121 | * | ||
122 | * Case 3: The constant buffer | ||
123 | * | ||
124 | * 1. Allocated | ||
125 | * 2. Written by CPU | ||
126 | * 3. Read by GPU | ||
127 | * 4. Updated (written) by CPU again | ||
128 | * 5. Read by GPU | ||
129 | * | ||
130 | * 1. Allocated | ||
131 | * (CPU, CPU) | ||
132 | * 2. Written by CPU | ||
133 | * (CPU, CPU) | ||
134 | * 3. Read by GPU | ||
135 | * (CPU+RENDER, 0) | ||
136 | * flush_domains = CPU | ||
137 | * invalidate_domains = RENDER | ||
138 | * clflush (obj) | ||
139 | * MI_FLUSH | ||
140 | * drm_agp_chipset_flush | ||
141 | * 4. Updated (written) by CPU again | ||
142 | * (CPU, CPU) | ||
143 | * flush_domains = 0 (no previous write domain) | ||
144 | * invalidate_domains = 0 (no new read domains) | ||
145 | * 5. Read by GPU | ||
146 | * (CPU+RENDER, 0) | ||
147 | * flush_domains = CPU | ||
148 | * invalidate_domains = RENDER | ||
149 | * clflush (obj) | ||
150 | * MI_FLUSH | ||
151 | * drm_agp_chipset_flush | ||
152 | */ | ||
153 | static void | ||
154 | i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj, | ||
155 | struct intel_ring_buffer *ring, | ||
156 | struct change_domains *cd) | ||
157 | { | ||
158 | uint32_t invalidate_domains = 0, flush_domains = 0; | ||
159 | |||
160 | /* | ||
161 | * If the object isn't moving to a new write domain, | ||
162 | * let the object stay in multiple read domains | ||
163 | */ | ||
164 | if (obj->base.pending_write_domain == 0) | ||
165 | obj->base.pending_read_domains |= obj->base.read_domains; | ||
166 | |||
167 | /* | ||
168 | * Flush the current write domain if | ||
169 | * the new read domains don't match. Invalidate | ||
170 | * any read domains which differ from the old | ||
171 | * write domain | ||
172 | */ | ||
173 | if (obj->base.write_domain && | ||
174 | (((obj->base.write_domain != obj->base.pending_read_domains || | ||
175 | obj->ring != ring)) || | ||
176 | (obj->fenced_gpu_access && !obj->pending_fenced_gpu_access))) { | ||
177 | flush_domains |= obj->base.write_domain; | ||
178 | invalidate_domains |= | ||
179 | obj->base.pending_read_domains & ~obj->base.write_domain; | ||
180 | } | ||
181 | /* | ||
182 | * Invalidate any read caches which may have | ||
183 | * stale data. That is, any new read domains. | ||
184 | */ | ||
185 | invalidate_domains |= obj->base.pending_read_domains & ~obj->base.read_domains; | ||
186 | if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) | ||
187 | i915_gem_clflush_object(obj); | ||
188 | |||
189 | /* blow away mappings if mapped through GTT */ | ||
190 | if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_GTT) | ||
191 | i915_gem_release_mmap(obj); | ||
192 | |||
193 | /* The actual obj->write_domain will be updated with | ||
194 | * pending_write_domain after we emit the accumulated flush for all | ||
195 | * of our domain changes in execbuffers (which clears objects' | ||
196 | * write_domains). So if we have a current write domain that we | ||
197 | * aren't changing, set pending_write_domain to that. | ||
198 | */ | ||
199 | if (flush_domains == 0 && obj->base.pending_write_domain == 0) | ||
200 | obj->base.pending_write_domain = obj->base.write_domain; | ||
201 | |||
202 | cd->invalidate_domains |= invalidate_domains; | ||
203 | cd->flush_domains |= flush_domains; | ||
204 | if (flush_domains & I915_GEM_GPU_DOMAINS) | ||
205 | cd->flush_rings |= obj->ring->id; | ||
206 | if (invalidate_domains & I915_GEM_GPU_DOMAINS) | ||
207 | cd->flush_rings |= ring->id; | ||
208 | } | ||
209 | |||
210 | struct eb_objects { | ||
211 | int and; | ||
212 | struct hlist_head buckets[0]; | ||
213 | }; | ||
214 | |||
215 | static struct eb_objects * | ||
216 | eb_create(int size) | ||
217 | { | ||
218 | struct eb_objects *eb; | ||
219 | int count = PAGE_SIZE / sizeof(struct hlist_head) / 2; | ||
220 | while (count > size) | ||
221 | count >>= 1; | ||
222 | eb = kzalloc(count*sizeof(struct hlist_head) + | ||
223 | sizeof(struct eb_objects), | ||
224 | GFP_KERNEL); | ||
225 | if (eb == NULL) | ||
226 | return eb; | ||
227 | |||
228 | eb->and = count - 1; | ||
229 | return eb; | ||
230 | } | ||
231 | |||
232 | static void | ||
233 | eb_reset(struct eb_objects *eb) | ||
234 | { | ||
235 | memset(eb->buckets, 0, (eb->and+1)*sizeof(struct hlist_head)); | ||
236 | } | ||
237 | |||
238 | static void | ||
239 | eb_add_object(struct eb_objects *eb, struct drm_i915_gem_object *obj) | ||
240 | { | ||
241 | hlist_add_head(&obj->exec_node, | ||
242 | &eb->buckets[obj->exec_handle & eb->and]); | ||
243 | } | ||
244 | |||
245 | static struct drm_i915_gem_object * | ||
246 | eb_get_object(struct eb_objects *eb, unsigned long handle) | ||
247 | { | ||
248 | struct hlist_head *head; | ||
249 | struct hlist_node *node; | ||
250 | struct drm_i915_gem_object *obj; | ||
251 | |||
252 | head = &eb->buckets[handle & eb->and]; | ||
253 | hlist_for_each(node, head) { | ||
254 | obj = hlist_entry(node, struct drm_i915_gem_object, exec_node); | ||
255 | if (obj->exec_handle == handle) | ||
256 | return obj; | ||
257 | } | ||
258 | |||
259 | return NULL; | ||
260 | } | ||
261 | |||
262 | static void | ||
263 | eb_destroy(struct eb_objects *eb) | ||
264 | { | ||
265 | kfree(eb); | ||
266 | } | ||
267 | |||
268 | static int | ||
269 | i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | ||
270 | struct eb_objects *eb, | ||
271 | struct drm_i915_gem_exec_object2 *entry, | ||
272 | struct drm_i915_gem_relocation_entry *reloc) | ||
273 | { | ||
274 | struct drm_device *dev = obj->base.dev; | ||
275 | struct drm_gem_object *target_obj; | ||
276 | uint32_t target_offset; | ||
277 | int ret = -EINVAL; | ||
278 | |||
279 | /* we've already hold a reference to all valid objects */ | ||
280 | target_obj = &eb_get_object(eb, reloc->target_handle)->base; | ||
281 | if (unlikely(target_obj == NULL)) | ||
282 | return -ENOENT; | ||
283 | |||
284 | target_offset = to_intel_bo(target_obj)->gtt_offset; | ||
285 | |||
286 | #if WATCH_RELOC | ||
287 | DRM_INFO("%s: obj %p offset %08x target %d " | ||
288 | "read %08x write %08x gtt %08x " | ||
289 | "presumed %08x delta %08x\n", | ||
290 | __func__, | ||
291 | obj, | ||
292 | (int) reloc->offset, | ||
293 | (int) reloc->target_handle, | ||
294 | (int) reloc->read_domains, | ||
295 | (int) reloc->write_domain, | ||
296 | (int) target_offset, | ||
297 | (int) reloc->presumed_offset, | ||
298 | reloc->delta); | ||
299 | #endif | ||
300 | |||
301 | /* The target buffer should have appeared before us in the | ||
302 | * exec_object list, so it should have a GTT space bound by now. | ||
303 | */ | ||
304 | if (unlikely(target_offset == 0)) { | ||
305 | DRM_ERROR("No GTT space found for object %d\n", | ||
306 | reloc->target_handle); | ||
307 | return ret; | ||
308 | } | ||
309 | |||
310 | /* Validate that the target is in a valid r/w GPU domain */ | ||
311 | if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) { | ||
312 | DRM_ERROR("reloc with multiple write domains: " | ||
313 | "obj %p target %d offset %d " | ||
314 | "read %08x write %08x", | ||
315 | obj, reloc->target_handle, | ||
316 | (int) reloc->offset, | ||
317 | reloc->read_domains, | ||
318 | reloc->write_domain); | ||
319 | return ret; | ||
320 | } | ||
321 | if (unlikely((reloc->write_domain | reloc->read_domains) & I915_GEM_DOMAIN_CPU)) { | ||
322 | DRM_ERROR("reloc with read/write CPU domains: " | ||
323 | "obj %p target %d offset %d " | ||
324 | "read %08x write %08x", | ||
325 | obj, reloc->target_handle, | ||
326 | (int) reloc->offset, | ||
327 | reloc->read_domains, | ||
328 | reloc->write_domain); | ||
329 | return ret; | ||
330 | } | ||
331 | if (unlikely(reloc->write_domain && target_obj->pending_write_domain && | ||
332 | reloc->write_domain != target_obj->pending_write_domain)) { | ||
333 | DRM_ERROR("Write domain conflict: " | ||
334 | "obj %p target %d offset %d " | ||
335 | "new %08x old %08x\n", | ||
336 | obj, reloc->target_handle, | ||
337 | (int) reloc->offset, | ||
338 | reloc->write_domain, | ||
339 | target_obj->pending_write_domain); | ||
340 | return ret; | ||
341 | } | ||
342 | |||
343 | target_obj->pending_read_domains |= reloc->read_domains; | ||
344 | target_obj->pending_write_domain |= reloc->write_domain; | ||
345 | |||
346 | /* If the relocation already has the right value in it, no | ||
347 | * more work needs to be done. | ||
348 | */ | ||
349 | if (target_offset == reloc->presumed_offset) | ||
350 | return 0; | ||
351 | |||
352 | /* Check that the relocation address is valid... */ | ||
353 | if (unlikely(reloc->offset > obj->base.size - 4)) { | ||
354 | DRM_ERROR("Relocation beyond object bounds: " | ||
355 | "obj %p target %d offset %d size %d.\n", | ||
356 | obj, reloc->target_handle, | ||
357 | (int) reloc->offset, | ||
358 | (int) obj->base.size); | ||
359 | return ret; | ||
360 | } | ||
361 | if (unlikely(reloc->offset & 3)) { | ||
362 | DRM_ERROR("Relocation not 4-byte aligned: " | ||
363 | "obj %p target %d offset %d.\n", | ||
364 | obj, reloc->target_handle, | ||
365 | (int) reloc->offset); | ||
366 | return ret; | ||
367 | } | ||
368 | |||
369 | /* and points to somewhere within the target object. */ | ||
370 | if (unlikely(reloc->delta >= target_obj->size)) { | ||
371 | DRM_ERROR("Relocation beyond target object bounds: " | ||
372 | "obj %p target %d delta %d size %d.\n", | ||
373 | obj, reloc->target_handle, | ||
374 | (int) reloc->delta, | ||
375 | (int) target_obj->size); | ||
376 | return ret; | ||
377 | } | ||
378 | |||
379 | reloc->delta += target_offset; | ||
380 | if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) { | ||
381 | uint32_t page_offset = reloc->offset & ~PAGE_MASK; | ||
382 | char *vaddr; | ||
383 | |||
384 | vaddr = kmap_atomic(obj->pages[reloc->offset >> PAGE_SHIFT]); | ||
385 | *(uint32_t *)(vaddr + page_offset) = reloc->delta; | ||
386 | kunmap_atomic(vaddr); | ||
387 | } else { | ||
388 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
389 | uint32_t __iomem *reloc_entry; | ||
390 | void __iomem *reloc_page; | ||
391 | |||
392 | ret = i915_gem_object_set_to_gtt_domain(obj, 1); | ||
393 | if (ret) | ||
394 | return ret; | ||
395 | |||
396 | /* Map the page containing the relocation we're going to perform. */ | ||
397 | reloc->offset += obj->gtt_offset; | ||
398 | reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, | ||
399 | reloc->offset & PAGE_MASK); | ||
400 | reloc_entry = (uint32_t __iomem *) | ||
401 | (reloc_page + (reloc->offset & ~PAGE_MASK)); | ||
402 | iowrite32(reloc->delta, reloc_entry); | ||
403 | io_mapping_unmap_atomic(reloc_page); | ||
404 | } | ||
405 | |||
406 | /* and update the user's relocation entry */ | ||
407 | reloc->presumed_offset = target_offset; | ||
408 | |||
409 | return 0; | ||
410 | } | ||
411 | |||
412 | static int | ||
413 | i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, | ||
414 | struct eb_objects *eb, | ||
415 | struct drm_i915_gem_exec_object2 *entry) | ||
416 | { | ||
417 | struct drm_i915_gem_relocation_entry __user *user_relocs; | ||
418 | int i, ret; | ||
419 | |||
420 | user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr; | ||
421 | for (i = 0; i < entry->relocation_count; i++) { | ||
422 | struct drm_i915_gem_relocation_entry reloc; | ||
423 | |||
424 | if (__copy_from_user_inatomic(&reloc, | ||
425 | user_relocs+i, | ||
426 | sizeof(reloc))) | ||
427 | return -EFAULT; | ||
428 | |||
429 | ret = i915_gem_execbuffer_relocate_entry(obj, eb, entry, &reloc); | ||
430 | if (ret) | ||
431 | return ret; | ||
432 | |||
433 | if (__copy_to_user_inatomic(&user_relocs[i].presumed_offset, | ||
434 | &reloc.presumed_offset, | ||
435 | sizeof(reloc.presumed_offset))) | ||
436 | return -EFAULT; | ||
437 | } | ||
438 | |||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | static int | ||
443 | i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, | ||
444 | struct eb_objects *eb, | ||
445 | struct drm_i915_gem_exec_object2 *entry, | ||
446 | struct drm_i915_gem_relocation_entry *relocs) | ||
447 | { | ||
448 | int i, ret; | ||
449 | |||
450 | for (i = 0; i < entry->relocation_count; i++) { | ||
451 | ret = i915_gem_execbuffer_relocate_entry(obj, eb, entry, &relocs[i]); | ||
452 | if (ret) | ||
453 | return ret; | ||
454 | } | ||
455 | |||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | static int | ||
460 | i915_gem_execbuffer_relocate(struct drm_device *dev, | ||
461 | struct eb_objects *eb, | ||
462 | struct list_head *objects, | ||
463 | struct drm_i915_gem_exec_object2 *exec) | ||
464 | { | ||
465 | struct drm_i915_gem_object *obj; | ||
466 | int ret; | ||
467 | |||
468 | list_for_each_entry(obj, objects, exec_list) { | ||
469 | obj->base.pending_read_domains = 0; | ||
470 | obj->base.pending_write_domain = 0; | ||
471 | ret = i915_gem_execbuffer_relocate_object(obj, eb, exec++); | ||
472 | if (ret) | ||
473 | return ret; | ||
474 | } | ||
475 | |||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | static int | ||
480 | i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, | ||
481 | struct drm_file *file, | ||
482 | struct list_head *objects, | ||
483 | struct drm_i915_gem_exec_object2 *exec) | ||
484 | { | ||
485 | struct drm_i915_gem_object *obj; | ||
486 | struct drm_i915_gem_exec_object2 *entry; | ||
487 | int ret, retry; | ||
488 | bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; | ||
489 | |||
490 | /* Attempt to pin all of the buffers into the GTT. | ||
491 | * This is done in 3 phases: | ||
492 | * | ||
493 | * 1a. Unbind all objects that do not match the GTT constraints for | ||
494 | * the execbuffer (fenceable, mappable, alignment etc). | ||
495 | * 1b. Increment pin count for already bound objects. | ||
496 | * 2. Bind new objects. | ||
497 | * 3. Decrement pin count. | ||
498 | * | ||
499 | * This avoid unnecessary unbinding of later objects in order to makr | ||
500 | * room for the earlier objects *unless* we need to defragment. | ||
501 | */ | ||
502 | retry = 0; | ||
503 | do { | ||
504 | ret = 0; | ||
505 | |||
506 | /* Unbind any ill-fitting objects or pin. */ | ||
507 | entry = exec; | ||
508 | list_for_each_entry(obj, objects, exec_list) { | ||
509 | bool need_fence, need_mappable; | ||
510 | |||
511 | if (!obj->gtt_space) { | ||
512 | entry++; | ||
513 | continue; | ||
514 | } | ||
515 | |||
516 | need_fence = | ||
517 | has_fenced_gpu_access && | ||
518 | entry->flags & EXEC_OBJECT_NEEDS_FENCE && | ||
519 | obj->tiling_mode != I915_TILING_NONE; | ||
520 | need_mappable = | ||
521 | entry->relocation_count ? true : need_fence; | ||
522 | |||
523 | if ((entry->alignment && obj->gtt_offset & (entry->alignment - 1)) || | ||
524 | (need_mappable && !obj->map_and_fenceable)) | ||
525 | ret = i915_gem_object_unbind(obj); | ||
526 | else | ||
527 | ret = i915_gem_object_pin(obj, | ||
528 | entry->alignment, | ||
529 | need_mappable); | ||
530 | if (ret) | ||
531 | goto err; | ||
532 | |||
533 | entry++; | ||
534 | } | ||
535 | |||
536 | /* Bind fresh objects */ | ||
537 | entry = exec; | ||
538 | list_for_each_entry(obj, objects, exec_list) { | ||
539 | bool need_fence; | ||
540 | |||
541 | need_fence = | ||
542 | has_fenced_gpu_access && | ||
543 | entry->flags & EXEC_OBJECT_NEEDS_FENCE && | ||
544 | obj->tiling_mode != I915_TILING_NONE; | ||
545 | |||
546 | if (!obj->gtt_space) { | ||
547 | bool need_mappable = | ||
548 | entry->relocation_count ? true : need_fence; | ||
549 | |||
550 | ret = i915_gem_object_pin(obj, | ||
551 | entry->alignment, | ||
552 | need_mappable); | ||
553 | if (ret) | ||
554 | break; | ||
555 | } | ||
556 | |||
557 | if (has_fenced_gpu_access) { | ||
558 | if (need_fence) { | ||
559 | ret = i915_gem_object_get_fence(obj, ring, 1); | ||
560 | if (ret) | ||
561 | break; | ||
562 | } else if (entry->flags & EXEC_OBJECT_NEEDS_FENCE && | ||
563 | obj->tiling_mode == I915_TILING_NONE) { | ||
564 | /* XXX pipelined! */ | ||
565 | ret = i915_gem_object_put_fence(obj); | ||
566 | if (ret) | ||
567 | break; | ||
568 | } | ||
569 | obj->pending_fenced_gpu_access = need_fence; | ||
570 | } | ||
571 | |||
572 | entry->offset = obj->gtt_offset; | ||
573 | entry++; | ||
574 | } | ||
575 | |||
576 | /* Decrement pin count for bound objects */ | ||
577 | list_for_each_entry(obj, objects, exec_list) { | ||
578 | if (obj->gtt_space) | ||
579 | i915_gem_object_unpin(obj); | ||
580 | } | ||
581 | |||
582 | if (ret != -ENOSPC || retry > 1) | ||
583 | return ret; | ||
584 | |||
585 | /* First attempt, just clear anything that is purgeable. | ||
586 | * Second attempt, clear the entire GTT. | ||
587 | */ | ||
588 | ret = i915_gem_evict_everything(ring->dev, retry == 0); | ||
589 | if (ret) | ||
590 | return ret; | ||
591 | |||
592 | retry++; | ||
593 | } while (1); | ||
594 | |||
595 | err: | ||
596 | obj = list_entry(obj->exec_list.prev, | ||
597 | struct drm_i915_gem_object, | ||
598 | exec_list); | ||
599 | while (objects != &obj->exec_list) { | ||
600 | if (obj->gtt_space) | ||
601 | i915_gem_object_unpin(obj); | ||
602 | |||
603 | obj = list_entry(obj->exec_list.prev, | ||
604 | struct drm_i915_gem_object, | ||
605 | exec_list); | ||
606 | } | ||
607 | |||
608 | return ret; | ||
609 | } | ||
610 | |||
611 | static int | ||
612 | i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | ||
613 | struct drm_file *file, | ||
614 | struct intel_ring_buffer *ring, | ||
615 | struct list_head *objects, | ||
616 | struct eb_objects *eb, | ||
617 | struct drm_i915_gem_exec_object2 *exec, | ||
618 | int count) | ||
619 | { | ||
620 | struct drm_i915_gem_relocation_entry *reloc; | ||
621 | struct drm_i915_gem_object *obj; | ||
622 | int i, total, ret; | ||
623 | |||
624 | /* We may process another execbuffer during the unlock... */ | ||
625 | while (list_empty(objects)) { | ||
626 | obj = list_first_entry(objects, | ||
627 | struct drm_i915_gem_object, | ||
628 | exec_list); | ||
629 | list_del_init(&obj->exec_list); | ||
630 | drm_gem_object_unreference(&obj->base); | ||
631 | } | ||
632 | |||
633 | mutex_unlock(&dev->struct_mutex); | ||
634 | |||
635 | total = 0; | ||
636 | for (i = 0; i < count; i++) | ||
637 | total += exec[i].relocation_count; | ||
638 | |||
639 | reloc = drm_malloc_ab(total, sizeof(*reloc)); | ||
640 | if (reloc == NULL) { | ||
641 | mutex_lock(&dev->struct_mutex); | ||
642 | return -ENOMEM; | ||
643 | } | ||
644 | |||
645 | total = 0; | ||
646 | for (i = 0; i < count; i++) { | ||
647 | struct drm_i915_gem_relocation_entry __user *user_relocs; | ||
648 | |||
649 | user_relocs = (void __user *)(uintptr_t)exec[i].relocs_ptr; | ||
650 | |||
651 | if (copy_from_user(reloc+total, user_relocs, | ||
652 | exec[i].relocation_count * sizeof(*reloc))) { | ||
653 | ret = -EFAULT; | ||
654 | mutex_lock(&dev->struct_mutex); | ||
655 | goto err; | ||
656 | } | ||
657 | |||
658 | total += exec[i].relocation_count; | ||
659 | } | ||
660 | |||
661 | ret = i915_mutex_lock_interruptible(dev); | ||
662 | if (ret) { | ||
663 | mutex_lock(&dev->struct_mutex); | ||
664 | goto err; | ||
665 | } | ||
666 | |||
667 | /* reacquire the objects */ | ||
668 | INIT_LIST_HEAD(objects); | ||
669 | eb_reset(eb); | ||
670 | for (i = 0; i < count; i++) { | ||
671 | struct drm_i915_gem_object *obj; | ||
672 | |||
673 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, | ||
674 | exec[i].handle)); | ||
675 | if (obj == NULL) { | ||
676 | DRM_ERROR("Invalid object handle %d at index %d\n", | ||
677 | exec[i].handle, i); | ||
678 | ret = -ENOENT; | ||
679 | goto err; | ||
680 | } | ||
681 | |||
682 | list_add_tail(&obj->exec_list, objects); | ||
683 | obj->exec_handle = exec[i].handle; | ||
684 | eb_add_object(eb, obj); | ||
685 | } | ||
686 | |||
687 | ret = i915_gem_execbuffer_reserve(ring, file, objects, exec); | ||
688 | if (ret) | ||
689 | goto err; | ||
690 | |||
691 | total = 0; | ||
692 | list_for_each_entry(obj, objects, exec_list) { | ||
693 | obj->base.pending_read_domains = 0; | ||
694 | obj->base.pending_write_domain = 0; | ||
695 | ret = i915_gem_execbuffer_relocate_object_slow(obj, eb, | ||
696 | exec, | ||
697 | reloc + total); | ||
698 | if (ret) | ||
699 | goto err; | ||
700 | |||
701 | total += exec->relocation_count; | ||
702 | exec++; | ||
703 | } | ||
704 | |||
705 | /* Leave the user relocations as are, this is the painfully slow path, | ||
706 | * and we want to avoid the complication of dropping the lock whilst | ||
707 | * having buffers reserved in the aperture and so causing spurious | ||
708 | * ENOSPC for random operations. | ||
709 | */ | ||
710 | |||
711 | err: | ||
712 | drm_free_large(reloc); | ||
713 | return ret; | ||
714 | } | ||
715 | |||
716 | static void | ||
717 | i915_gem_execbuffer_flush(struct drm_device *dev, | ||
718 | uint32_t invalidate_domains, | ||
719 | uint32_t flush_domains, | ||
720 | uint32_t flush_rings) | ||
721 | { | ||
722 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
723 | int i; | ||
724 | |||
725 | if (flush_domains & I915_GEM_DOMAIN_CPU) | ||
726 | intel_gtt_chipset_flush(); | ||
727 | |||
728 | if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) { | ||
729 | for (i = 0; i < I915_NUM_RINGS; i++) | ||
730 | if (flush_rings & (1 << i)) | ||
731 | i915_gem_flush_ring(dev, &dev_priv->ring[i], | ||
732 | invalidate_domains, | ||
733 | flush_domains); | ||
734 | } | ||
735 | } | ||
736 | |||
737 | static int | ||
738 | i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj, | ||
739 | struct intel_ring_buffer *to) | ||
740 | { | ||
741 | struct intel_ring_buffer *from = obj->ring; | ||
742 | u32 seqno; | ||
743 | int ret, idx; | ||
744 | |||
745 | if (from == NULL || to == from) | ||
746 | return 0; | ||
747 | |||
748 | if (INTEL_INFO(obj->base.dev)->gen < 6) | ||
749 | return i915_gem_object_wait_rendering(obj, true); | ||
750 | |||
751 | idx = intel_ring_sync_index(from, to); | ||
752 | |||
753 | seqno = obj->last_rendering_seqno; | ||
754 | if (seqno <= from->sync_seqno[idx]) | ||
755 | return 0; | ||
756 | |||
757 | if (seqno == from->outstanding_lazy_request) { | ||
758 | struct drm_i915_gem_request *request; | ||
759 | |||
760 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
761 | if (request == NULL) | ||
762 | return -ENOMEM; | ||
763 | |||
764 | ret = i915_add_request(obj->base.dev, NULL, request, from); | ||
765 | if (ret) { | ||
766 | kfree(request); | ||
767 | return ret; | ||
768 | } | ||
769 | |||
770 | seqno = request->seqno; | ||
771 | } | ||
772 | |||
773 | from->sync_seqno[idx] = seqno; | ||
774 | return intel_ring_sync(to, from, seqno - 1); | ||
775 | } | ||
776 | |||
777 | static int | ||
778 | i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, | ||
779 | struct list_head *objects) | ||
780 | { | ||
781 | struct drm_i915_gem_object *obj; | ||
782 | struct change_domains cd; | ||
783 | int ret; | ||
784 | |||
785 | cd.invalidate_domains = 0; | ||
786 | cd.flush_domains = 0; | ||
787 | cd.flush_rings = 0; | ||
788 | list_for_each_entry(obj, objects, exec_list) | ||
789 | i915_gem_object_set_to_gpu_domain(obj, ring, &cd); | ||
790 | |||
791 | if (cd.invalidate_domains | cd.flush_domains) { | ||
792 | #if WATCH_EXEC | ||
793 | DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", | ||
794 | __func__, | ||
795 | cd.invalidate_domains, | ||
796 | cd.flush_domains); | ||
797 | #endif | ||
798 | i915_gem_execbuffer_flush(ring->dev, | ||
799 | cd.invalidate_domains, | ||
800 | cd.flush_domains, | ||
801 | cd.flush_rings); | ||
802 | } | ||
803 | |||
804 | list_for_each_entry(obj, objects, exec_list) { | ||
805 | ret = i915_gem_execbuffer_sync_rings(obj, ring); | ||
806 | if (ret) | ||
807 | return ret; | ||
808 | } | ||
809 | |||
810 | return 0; | ||
811 | } | ||
812 | |||
813 | static bool | ||
814 | i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec) | ||
815 | { | ||
816 | return ((exec->batch_start_offset | exec->batch_len) & 0x7) == 0; | ||
817 | } | ||
818 | |||
819 | static int | ||
820 | validate_exec_list(struct drm_i915_gem_exec_object2 *exec, | ||
821 | int count) | ||
822 | { | ||
823 | int i; | ||
824 | |||
825 | for (i = 0; i < count; i++) { | ||
826 | char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr; | ||
827 | int length; /* limited by fault_in_pages_readable() */ | ||
828 | |||
829 | /* First check for malicious input causing overflow */ | ||
830 | if (exec[i].relocation_count > | ||
831 | INT_MAX / sizeof(struct drm_i915_gem_relocation_entry)) | ||
832 | return -EINVAL; | ||
833 | |||
834 | length = exec[i].relocation_count * | ||
835 | sizeof(struct drm_i915_gem_relocation_entry); | ||
836 | if (!access_ok(VERIFY_READ, ptr, length)) | ||
837 | return -EFAULT; | ||
838 | |||
839 | /* we may also need to update the presumed offsets */ | ||
840 | if (!access_ok(VERIFY_WRITE, ptr, length)) | ||
841 | return -EFAULT; | ||
842 | |||
843 | if (fault_in_pages_readable(ptr, length)) | ||
844 | return -EFAULT; | ||
845 | } | ||
846 | |||
847 | return 0; | ||
848 | } | ||
849 | |||
850 | static int | ||
851 | i915_gem_execbuffer_wait_for_flips(struct intel_ring_buffer *ring, | ||
852 | struct list_head *objects) | ||
853 | { | ||
854 | struct drm_i915_gem_object *obj; | ||
855 | int flips; | ||
856 | |||
857 | /* Check for any pending flips. As we only maintain a flip queue depth | ||
858 | * of 1, we can simply insert a WAIT for the next display flip prior | ||
859 | * to executing the batch and avoid stalling the CPU. | ||
860 | */ | ||
861 | flips = 0; | ||
862 | list_for_each_entry(obj, objects, exec_list) { | ||
863 | if (obj->base.write_domain) | ||
864 | flips |= atomic_read(&obj->pending_flip); | ||
865 | } | ||
866 | if (flips) { | ||
867 | int plane, flip_mask, ret; | ||
868 | |||
869 | for (plane = 0; flips >> plane; plane++) { | ||
870 | if (((flips >> plane) & 1) == 0) | ||
871 | continue; | ||
872 | |||
873 | if (plane) | ||
874 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; | ||
875 | else | ||
876 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; | ||
877 | |||
878 | ret = intel_ring_begin(ring, 2); | ||
879 | if (ret) | ||
880 | return ret; | ||
881 | |||
882 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask); | ||
883 | intel_ring_emit(ring, MI_NOOP); | ||
884 | intel_ring_advance(ring); | ||
885 | } | ||
886 | } | ||
887 | |||
888 | return 0; | ||
889 | } | ||
890 | |||
891 | static void | ||
892 | i915_gem_execbuffer_move_to_active(struct list_head *objects, | ||
893 | struct intel_ring_buffer *ring, | ||
894 | u32 seqno) | ||
895 | { | ||
896 | struct drm_i915_gem_object *obj; | ||
897 | |||
898 | list_for_each_entry(obj, objects, exec_list) { | ||
899 | obj->base.read_domains = obj->base.pending_read_domains; | ||
900 | obj->base.write_domain = obj->base.pending_write_domain; | ||
901 | obj->fenced_gpu_access = obj->pending_fenced_gpu_access; | ||
902 | |||
903 | i915_gem_object_move_to_active(obj, ring, seqno); | ||
904 | if (obj->base.write_domain) { | ||
905 | obj->dirty = 1; | ||
906 | obj->pending_gpu_write = true; | ||
907 | list_move_tail(&obj->gpu_write_list, | ||
908 | &ring->gpu_write_list); | ||
909 | intel_mark_busy(ring->dev, obj); | ||
910 | } | ||
911 | |||
912 | trace_i915_gem_object_change_domain(obj, | ||
913 | obj->base.read_domains, | ||
914 | obj->base.write_domain); | ||
915 | } | ||
916 | } | ||
917 | |||
918 | static void | ||
919 | i915_gem_execbuffer_retire_commands(struct drm_device *dev, | ||
920 | struct drm_file *file, | ||
921 | struct intel_ring_buffer *ring) | ||
922 | { | ||
923 | struct drm_i915_gem_request *request; | ||
924 | u32 flush_domains; | ||
925 | |||
926 | /* | ||
927 | * Ensure that the commands in the batch buffer are | ||
928 | * finished before the interrupt fires. | ||
929 | * | ||
930 | * The sampler always gets flushed on i965 (sigh). | ||
931 | */ | ||
932 | flush_domains = 0; | ||
933 | if (INTEL_INFO(dev)->gen >= 4) | ||
934 | flush_domains |= I915_GEM_DOMAIN_SAMPLER; | ||
935 | |||
936 | ring->flush(ring, I915_GEM_DOMAIN_COMMAND, flush_domains); | ||
937 | |||
938 | /* Add a breadcrumb for the completion of the batch buffer */ | ||
939 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
940 | if (request == NULL || i915_add_request(dev, file, request, ring)) { | ||
941 | i915_gem_next_request_seqno(dev, ring); | ||
942 | kfree(request); | ||
943 | } | ||
944 | } | ||
945 | |||
946 | static int | ||
947 | i915_gem_do_execbuffer(struct drm_device *dev, void *data, | ||
948 | struct drm_file *file, | ||
949 | struct drm_i915_gem_execbuffer2 *args, | ||
950 | struct drm_i915_gem_exec_object2 *exec) | ||
951 | { | ||
952 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
953 | struct list_head objects; | ||
954 | struct eb_objects *eb; | ||
955 | struct drm_i915_gem_object *batch_obj; | ||
956 | struct drm_clip_rect *cliprects = NULL; | ||
957 | struct intel_ring_buffer *ring; | ||
958 | u32 exec_start, exec_len; | ||
959 | u32 seqno; | ||
960 | int ret, mode, i; | ||
961 | |||
962 | if (!i915_gem_check_execbuffer(args)) { | ||
963 | DRM_ERROR("execbuf with invalid offset/length\n"); | ||
964 | return -EINVAL; | ||
965 | } | ||
966 | |||
967 | ret = validate_exec_list(exec, args->buffer_count); | ||
968 | if (ret) | ||
969 | return ret; | ||
970 | |||
971 | #if WATCH_EXEC | ||
972 | DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", | ||
973 | (int) args->buffers_ptr, args->buffer_count, args->batch_len); | ||
974 | #endif | ||
975 | switch (args->flags & I915_EXEC_RING_MASK) { | ||
976 | case I915_EXEC_DEFAULT: | ||
977 | case I915_EXEC_RENDER: | ||
978 | ring = &dev_priv->ring[RCS]; | ||
979 | break; | ||
980 | case I915_EXEC_BSD: | ||
981 | if (!HAS_BSD(dev)) { | ||
982 | DRM_ERROR("execbuf with invalid ring (BSD)\n"); | ||
983 | return -EINVAL; | ||
984 | } | ||
985 | ring = &dev_priv->ring[VCS]; | ||
986 | break; | ||
987 | case I915_EXEC_BLT: | ||
988 | if (!HAS_BLT(dev)) { | ||
989 | DRM_ERROR("execbuf with invalid ring (BLT)\n"); | ||
990 | return -EINVAL; | ||
991 | } | ||
992 | ring = &dev_priv->ring[BCS]; | ||
993 | break; | ||
994 | default: | ||
995 | DRM_ERROR("execbuf with unknown ring: %d\n", | ||
996 | (int)(args->flags & I915_EXEC_RING_MASK)); | ||
997 | return -EINVAL; | ||
998 | } | ||
999 | |||
1000 | mode = args->flags & I915_EXEC_CONSTANTS_MASK; | ||
1001 | switch (mode) { | ||
1002 | case I915_EXEC_CONSTANTS_REL_GENERAL: | ||
1003 | case I915_EXEC_CONSTANTS_ABSOLUTE: | ||
1004 | case I915_EXEC_CONSTANTS_REL_SURFACE: | ||
1005 | if (ring == &dev_priv->ring[RCS] && | ||
1006 | mode != dev_priv->relative_constants_mode) { | ||
1007 | if (INTEL_INFO(dev)->gen < 4) | ||
1008 | return -EINVAL; | ||
1009 | |||
1010 | if (INTEL_INFO(dev)->gen > 5 && | ||
1011 | mode == I915_EXEC_CONSTANTS_REL_SURFACE) | ||
1012 | return -EINVAL; | ||
1013 | |||
1014 | ret = intel_ring_begin(ring, 4); | ||
1015 | if (ret) | ||
1016 | return ret; | ||
1017 | |||
1018 | intel_ring_emit(ring, MI_NOOP); | ||
1019 | intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); | ||
1020 | intel_ring_emit(ring, INSTPM); | ||
1021 | intel_ring_emit(ring, | ||
1022 | I915_EXEC_CONSTANTS_MASK << 16 | mode); | ||
1023 | intel_ring_advance(ring); | ||
1024 | |||
1025 | dev_priv->relative_constants_mode = mode; | ||
1026 | } | ||
1027 | break; | ||
1028 | default: | ||
1029 | DRM_ERROR("execbuf with unknown constants: %d\n", mode); | ||
1030 | return -EINVAL; | ||
1031 | } | ||
1032 | |||
1033 | if (args->buffer_count < 1) { | ||
1034 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); | ||
1035 | return -EINVAL; | ||
1036 | } | ||
1037 | |||
1038 | if (args->num_cliprects != 0) { | ||
1039 | if (ring != &dev_priv->ring[RCS]) { | ||
1040 | DRM_ERROR("clip rectangles are only valid with the render ring\n"); | ||
1041 | return -EINVAL; | ||
1042 | } | ||
1043 | |||
1044 | cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects), | ||
1045 | GFP_KERNEL); | ||
1046 | if (cliprects == NULL) { | ||
1047 | ret = -ENOMEM; | ||
1048 | goto pre_mutex_err; | ||
1049 | } | ||
1050 | |||
1051 | if (copy_from_user(cliprects, | ||
1052 | (struct drm_clip_rect __user *)(uintptr_t) | ||
1053 | args->cliprects_ptr, | ||
1054 | sizeof(*cliprects)*args->num_cliprects)) { | ||
1055 | ret = -EFAULT; | ||
1056 | goto pre_mutex_err; | ||
1057 | } | ||
1058 | } | ||
1059 | |||
1060 | ret = i915_mutex_lock_interruptible(dev); | ||
1061 | if (ret) | ||
1062 | goto pre_mutex_err; | ||
1063 | |||
1064 | if (dev_priv->mm.suspended) { | ||
1065 | mutex_unlock(&dev->struct_mutex); | ||
1066 | ret = -EBUSY; | ||
1067 | goto pre_mutex_err; | ||
1068 | } | ||
1069 | |||
1070 | eb = eb_create(args->buffer_count); | ||
1071 | if (eb == NULL) { | ||
1072 | mutex_unlock(&dev->struct_mutex); | ||
1073 | ret = -ENOMEM; | ||
1074 | goto pre_mutex_err; | ||
1075 | } | ||
1076 | |||
1077 | /* Look up object handles */ | ||
1078 | INIT_LIST_HEAD(&objects); | ||
1079 | for (i = 0; i < args->buffer_count; i++) { | ||
1080 | struct drm_i915_gem_object *obj; | ||
1081 | |||
1082 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, | ||
1083 | exec[i].handle)); | ||
1084 | if (obj == NULL) { | ||
1085 | DRM_ERROR("Invalid object handle %d at index %d\n", | ||
1086 | exec[i].handle, i); | ||
1087 | /* prevent error path from reading uninitialized data */ | ||
1088 | ret = -ENOENT; | ||
1089 | goto err; | ||
1090 | } | ||
1091 | |||
1092 | if (!list_empty(&obj->exec_list)) { | ||
1093 | DRM_ERROR("Object %p [handle %d, index %d] appears more than once in object list\n", | ||
1094 | obj, exec[i].handle, i); | ||
1095 | ret = -EINVAL; | ||
1096 | goto err; | ||
1097 | } | ||
1098 | |||
1099 | list_add_tail(&obj->exec_list, &objects); | ||
1100 | obj->exec_handle = exec[i].handle; | ||
1101 | eb_add_object(eb, obj); | ||
1102 | } | ||
1103 | |||
1104 | /* Move the objects en-masse into the GTT, evicting if necessary. */ | ||
1105 | ret = i915_gem_execbuffer_reserve(ring, file, &objects, exec); | ||
1106 | if (ret) | ||
1107 | goto err; | ||
1108 | |||
1109 | /* The objects are in their final locations, apply the relocations. */ | ||
1110 | ret = i915_gem_execbuffer_relocate(dev, eb, &objects, exec); | ||
1111 | if (ret) { | ||
1112 | if (ret == -EFAULT) { | ||
1113 | ret = i915_gem_execbuffer_relocate_slow(dev, file, ring, | ||
1114 | &objects, eb, | ||
1115 | exec, | ||
1116 | args->buffer_count); | ||
1117 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); | ||
1118 | } | ||
1119 | if (ret) | ||
1120 | goto err; | ||
1121 | } | ||
1122 | |||
1123 | /* Set the pending read domains for the batch buffer to COMMAND */ | ||
1124 | batch_obj = list_entry(objects.prev, | ||
1125 | struct drm_i915_gem_object, | ||
1126 | exec_list); | ||
1127 | if (batch_obj->base.pending_write_domain) { | ||
1128 | DRM_ERROR("Attempting to use self-modifying batch buffer\n"); | ||
1129 | ret = -EINVAL; | ||
1130 | goto err; | ||
1131 | } | ||
1132 | batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND; | ||
1133 | |||
1134 | ret = i915_gem_execbuffer_move_to_gpu(ring, &objects); | ||
1135 | if (ret) | ||
1136 | goto err; | ||
1137 | |||
1138 | ret = i915_gem_execbuffer_wait_for_flips(ring, &objects); | ||
1139 | if (ret) | ||
1140 | goto err; | ||
1141 | |||
1142 | seqno = i915_gem_next_request_seqno(dev, ring); | ||
1143 | for (i = 0; i < I915_NUM_RINGS-1; i++) { | ||
1144 | if (seqno < ring->sync_seqno[i]) { | ||
1145 | /* The GPU can not handle its semaphore value wrapping, | ||
1146 | * so every billion or so execbuffers, we need to stall | ||
1147 | * the GPU in order to reset the counters. | ||
1148 | */ | ||
1149 | ret = i915_gpu_idle(dev); | ||
1150 | if (ret) | ||
1151 | goto err; | ||
1152 | |||
1153 | BUG_ON(ring->sync_seqno[i]); | ||
1154 | } | ||
1155 | } | ||
1156 | |||
1157 | exec_start = batch_obj->gtt_offset + args->batch_start_offset; | ||
1158 | exec_len = args->batch_len; | ||
1159 | if (cliprects) { | ||
1160 | for (i = 0; i < args->num_cliprects; i++) { | ||
1161 | ret = i915_emit_box(dev, &cliprects[i], | ||
1162 | args->DR1, args->DR4); | ||
1163 | if (ret) | ||
1164 | goto err; | ||
1165 | |||
1166 | ret = ring->dispatch_execbuffer(ring, | ||
1167 | exec_start, exec_len); | ||
1168 | if (ret) | ||
1169 | goto err; | ||
1170 | } | ||
1171 | } else { | ||
1172 | ret = ring->dispatch_execbuffer(ring, exec_start, exec_len); | ||
1173 | if (ret) | ||
1174 | goto err; | ||
1175 | } | ||
1176 | |||
1177 | i915_gem_execbuffer_move_to_active(&objects, ring, seqno); | ||
1178 | i915_gem_execbuffer_retire_commands(dev, file, ring); | ||
1179 | |||
1180 | err: | ||
1181 | eb_destroy(eb); | ||
1182 | while (!list_empty(&objects)) { | ||
1183 | struct drm_i915_gem_object *obj; | ||
1184 | |||
1185 | obj = list_first_entry(&objects, | ||
1186 | struct drm_i915_gem_object, | ||
1187 | exec_list); | ||
1188 | list_del_init(&obj->exec_list); | ||
1189 | drm_gem_object_unreference(&obj->base); | ||
1190 | } | ||
1191 | |||
1192 | mutex_unlock(&dev->struct_mutex); | ||
1193 | |||
1194 | pre_mutex_err: | ||
1195 | kfree(cliprects); | ||
1196 | return ret; | ||
1197 | } | ||
1198 | |||
1199 | /* | ||
1200 | * Legacy execbuffer just creates an exec2 list from the original exec object | ||
1201 | * list array and passes it to the real function. | ||
1202 | */ | ||
1203 | int | ||
1204 | i915_gem_execbuffer(struct drm_device *dev, void *data, | ||
1205 | struct drm_file *file) | ||
1206 | { | ||
1207 | struct drm_i915_gem_execbuffer *args = data; | ||
1208 | struct drm_i915_gem_execbuffer2 exec2; | ||
1209 | struct drm_i915_gem_exec_object *exec_list = NULL; | ||
1210 | struct drm_i915_gem_exec_object2 *exec2_list = NULL; | ||
1211 | int ret, i; | ||
1212 | |||
1213 | #if WATCH_EXEC | ||
1214 | DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", | ||
1215 | (int) args->buffers_ptr, args->buffer_count, args->batch_len); | ||
1216 | #endif | ||
1217 | |||
1218 | if (args->buffer_count < 1) { | ||
1219 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); | ||
1220 | return -EINVAL; | ||
1221 | } | ||
1222 | |||
1223 | /* Copy in the exec list from userland */ | ||
1224 | exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count); | ||
1225 | exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); | ||
1226 | if (exec_list == NULL || exec2_list == NULL) { | ||
1227 | DRM_ERROR("Failed to allocate exec list for %d buffers\n", | ||
1228 | args->buffer_count); | ||
1229 | drm_free_large(exec_list); | ||
1230 | drm_free_large(exec2_list); | ||
1231 | return -ENOMEM; | ||
1232 | } | ||
1233 | ret = copy_from_user(exec_list, | ||
1234 | (struct drm_i915_relocation_entry __user *) | ||
1235 | (uintptr_t) args->buffers_ptr, | ||
1236 | sizeof(*exec_list) * args->buffer_count); | ||
1237 | if (ret != 0) { | ||
1238 | DRM_ERROR("copy %d exec entries failed %d\n", | ||
1239 | args->buffer_count, ret); | ||
1240 | drm_free_large(exec_list); | ||
1241 | drm_free_large(exec2_list); | ||
1242 | return -EFAULT; | ||
1243 | } | ||
1244 | |||
1245 | for (i = 0; i < args->buffer_count; i++) { | ||
1246 | exec2_list[i].handle = exec_list[i].handle; | ||
1247 | exec2_list[i].relocation_count = exec_list[i].relocation_count; | ||
1248 | exec2_list[i].relocs_ptr = exec_list[i].relocs_ptr; | ||
1249 | exec2_list[i].alignment = exec_list[i].alignment; | ||
1250 | exec2_list[i].offset = exec_list[i].offset; | ||
1251 | if (INTEL_INFO(dev)->gen < 4) | ||
1252 | exec2_list[i].flags = EXEC_OBJECT_NEEDS_FENCE; | ||
1253 | else | ||
1254 | exec2_list[i].flags = 0; | ||
1255 | } | ||
1256 | |||
1257 | exec2.buffers_ptr = args->buffers_ptr; | ||
1258 | exec2.buffer_count = args->buffer_count; | ||
1259 | exec2.batch_start_offset = args->batch_start_offset; | ||
1260 | exec2.batch_len = args->batch_len; | ||
1261 | exec2.DR1 = args->DR1; | ||
1262 | exec2.DR4 = args->DR4; | ||
1263 | exec2.num_cliprects = args->num_cliprects; | ||
1264 | exec2.cliprects_ptr = args->cliprects_ptr; | ||
1265 | exec2.flags = I915_EXEC_RENDER; | ||
1266 | |||
1267 | ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list); | ||
1268 | if (!ret) { | ||
1269 | /* Copy the new buffer offsets back to the user's exec list. */ | ||
1270 | for (i = 0; i < args->buffer_count; i++) | ||
1271 | exec_list[i].offset = exec2_list[i].offset; | ||
1272 | /* ... and back out to userspace */ | ||
1273 | ret = copy_to_user((struct drm_i915_relocation_entry __user *) | ||
1274 | (uintptr_t) args->buffers_ptr, | ||
1275 | exec_list, | ||
1276 | sizeof(*exec_list) * args->buffer_count); | ||
1277 | if (ret) { | ||
1278 | ret = -EFAULT; | ||
1279 | DRM_ERROR("failed to copy %d exec entries " | ||
1280 | "back to user (%d)\n", | ||
1281 | args->buffer_count, ret); | ||
1282 | } | ||
1283 | } | ||
1284 | |||
1285 | drm_free_large(exec_list); | ||
1286 | drm_free_large(exec2_list); | ||
1287 | return ret; | ||
1288 | } | ||
1289 | |||
1290 | int | ||
1291 | i915_gem_execbuffer2(struct drm_device *dev, void *data, | ||
1292 | struct drm_file *file) | ||
1293 | { | ||
1294 | struct drm_i915_gem_execbuffer2 *args = data; | ||
1295 | struct drm_i915_gem_exec_object2 *exec2_list = NULL; | ||
1296 | int ret; | ||
1297 | |||
1298 | #if WATCH_EXEC | ||
1299 | DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", | ||
1300 | (int) args->buffers_ptr, args->buffer_count, args->batch_len); | ||
1301 | #endif | ||
1302 | |||
1303 | if (args->buffer_count < 1) { | ||
1304 | DRM_ERROR("execbuf2 with %d buffers\n", args->buffer_count); | ||
1305 | return -EINVAL; | ||
1306 | } | ||
1307 | |||
1308 | exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); | ||
1309 | if (exec2_list == NULL) { | ||
1310 | DRM_ERROR("Failed to allocate exec list for %d buffers\n", | ||
1311 | args->buffer_count); | ||
1312 | return -ENOMEM; | ||
1313 | } | ||
1314 | ret = copy_from_user(exec2_list, | ||
1315 | (struct drm_i915_relocation_entry __user *) | ||
1316 | (uintptr_t) args->buffers_ptr, | ||
1317 | sizeof(*exec2_list) * args->buffer_count); | ||
1318 | if (ret != 0) { | ||
1319 | DRM_ERROR("copy %d exec entries failed %d\n", | ||
1320 | args->buffer_count, ret); | ||
1321 | drm_free_large(exec2_list); | ||
1322 | return -EFAULT; | ||
1323 | } | ||
1324 | |||
1325 | ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list); | ||
1326 | if (!ret) { | ||
1327 | /* Copy the new buffer offsets back to the user's exec list. */ | ||
1328 | ret = copy_to_user((struct drm_i915_relocation_entry __user *) | ||
1329 | (uintptr_t) args->buffers_ptr, | ||
1330 | exec2_list, | ||
1331 | sizeof(*exec2_list) * args->buffer_count); | ||
1332 | if (ret) { | ||
1333 | ret = -EFAULT; | ||
1334 | DRM_ERROR("failed to copy %d exec entries " | ||
1335 | "back to user (%d)\n", | ||
1336 | args->buffer_count, ret); | ||
1337 | } | ||
1338 | } | ||
1339 | |||
1340 | drm_free_large(exec2_list); | ||
1341 | return ret; | ||
1342 | } | ||
1343 | |||
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c new file mode 100644 index 00000000000..86673e77d7c --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * Copyright © 2010 Daniel Vetter | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include "drmP.h" | ||
26 | #include "drm.h" | ||
27 | #include "i915_drm.h" | ||
28 | #include "i915_drv.h" | ||
29 | #include "i915_trace.h" | ||
30 | #include "intel_drv.h" | ||
31 | |||
32 | void i915_gem_restore_gtt_mappings(struct drm_device *dev) | ||
33 | { | ||
34 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
35 | struct drm_i915_gem_object *obj; | ||
36 | |||
37 | list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { | ||
38 | i915_gem_clflush_object(obj); | ||
39 | |||
40 | if (dev_priv->mm.gtt->needs_dmar) { | ||
41 | BUG_ON(!obj->sg_list); | ||
42 | |||
43 | intel_gtt_insert_sg_entries(obj->sg_list, | ||
44 | obj->num_sg, | ||
45 | obj->gtt_space->start | ||
46 | >> PAGE_SHIFT, | ||
47 | obj->agp_type); | ||
48 | } else | ||
49 | intel_gtt_insert_pages(obj->gtt_space->start | ||
50 | >> PAGE_SHIFT, | ||
51 | obj->base.size >> PAGE_SHIFT, | ||
52 | obj->pages, | ||
53 | obj->agp_type); | ||
54 | } | ||
55 | |||
56 | intel_gtt_chipset_flush(); | ||
57 | } | ||
58 | |||
59 | int i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj) | ||
60 | { | ||
61 | struct drm_device *dev = obj->base.dev; | ||
62 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
63 | int ret; | ||
64 | |||
65 | if (dev_priv->mm.gtt->needs_dmar) { | ||
66 | ret = intel_gtt_map_memory(obj->pages, | ||
67 | obj->base.size >> PAGE_SHIFT, | ||
68 | &obj->sg_list, | ||
69 | &obj->num_sg); | ||
70 | if (ret != 0) | ||
71 | return ret; | ||
72 | |||
73 | intel_gtt_insert_sg_entries(obj->sg_list, | ||
74 | obj->num_sg, | ||
75 | obj->gtt_space->start >> PAGE_SHIFT, | ||
76 | obj->agp_type); | ||
77 | } else | ||
78 | intel_gtt_insert_pages(obj->gtt_space->start >> PAGE_SHIFT, | ||
79 | obj->base.size >> PAGE_SHIFT, | ||
80 | obj->pages, | ||
81 | obj->agp_type); | ||
82 | |||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj) | ||
87 | { | ||
88 | struct drm_device *dev = obj->base.dev; | ||
89 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
90 | |||
91 | if (dev_priv->mm.gtt->needs_dmar) { | ||
92 | intel_gtt_unmap_memory(obj->sg_list, obj->num_sg); | ||
93 | obj->sg_list = NULL; | ||
94 | obj->num_sg = 0; | ||
95 | } | ||
96 | |||
97 | intel_gtt_clear_range(obj->gtt_space->start >> PAGE_SHIFT, | ||
98 | obj->base.size >> PAGE_SHIFT); | ||
99 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index af352de70be..22a32b9932c 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -181,7 +181,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) | |||
181 | } | 181 | } |
182 | 182 | ||
183 | /* Check pitch constriants for all chips & tiling formats */ | 183 | /* Check pitch constriants for all chips & tiling formats */ |
184 | bool | 184 | static bool |
185 | i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) | 185 | i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) |
186 | { | 186 | { |
187 | int tile_width; | 187 | int tile_width; |
@@ -232,32 +232,44 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) | |||
232 | return true; | 232 | return true; |
233 | } | 233 | } |
234 | 234 | ||
235 | bool | 235 | /* Is the current GTT allocation valid for the change in tiling? */ |
236 | i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode) | 236 | static bool |
237 | i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode) | ||
237 | { | 238 | { |
238 | struct drm_device *dev = obj->dev; | 239 | u32 size; |
239 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
240 | |||
241 | if (obj_priv->gtt_space == NULL) | ||
242 | return true; | ||
243 | 240 | ||
244 | if (tiling_mode == I915_TILING_NONE) | 241 | if (tiling_mode == I915_TILING_NONE) |
245 | return true; | 242 | return true; |
246 | 243 | ||
247 | if (INTEL_INFO(dev)->gen >= 4) | 244 | if (INTEL_INFO(obj->base.dev)->gen >= 4) |
248 | return true; | 245 | return true; |
249 | 246 | ||
250 | if (obj_priv->gtt_offset & (obj->size - 1)) | 247 | if (INTEL_INFO(obj->base.dev)->gen == 3) { |
251 | return false; | 248 | if (obj->gtt_offset & ~I915_FENCE_START_MASK) |
252 | |||
253 | if (IS_GEN3(dev)) { | ||
254 | if (obj_priv->gtt_offset & ~I915_FENCE_START_MASK) | ||
255 | return false; | 249 | return false; |
256 | } else { | 250 | } else { |
257 | if (obj_priv->gtt_offset & ~I830_FENCE_START_MASK) | 251 | if (obj->gtt_offset & ~I830_FENCE_START_MASK) |
258 | return false; | 252 | return false; |
259 | } | 253 | } |
260 | 254 | ||
255 | /* | ||
256 | * Previous chips need to be aligned to the size of the smallest | ||
257 | * fence register that can contain the object. | ||
258 | */ | ||
259 | if (INTEL_INFO(obj->base.dev)->gen == 3) | ||
260 | size = 1024*1024; | ||
261 | else | ||
262 | size = 512*1024; | ||
263 | |||
264 | while (size < obj->base.size) | ||
265 | size <<= 1; | ||
266 | |||
267 | if (obj->gtt_space->size != size) | ||
268 | return false; | ||
269 | |||
270 | if (obj->gtt_offset & (size - 1)) | ||
271 | return false; | ||
272 | |||
261 | return true; | 273 | return true; |
262 | } | 274 | } |
263 | 275 | ||
@@ -267,30 +279,29 @@ i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode) | |||
267 | */ | 279 | */ |
268 | int | 280 | int |
269 | i915_gem_set_tiling(struct drm_device *dev, void *data, | 281 | i915_gem_set_tiling(struct drm_device *dev, void *data, |
270 | struct drm_file *file_priv) | 282 | struct drm_file *file) |
271 | { | 283 | { |
272 | struct drm_i915_gem_set_tiling *args = data; | 284 | struct drm_i915_gem_set_tiling *args = data; |
273 | drm_i915_private_t *dev_priv = dev->dev_private; | 285 | drm_i915_private_t *dev_priv = dev->dev_private; |
274 | struct drm_gem_object *obj; | 286 | struct drm_i915_gem_object *obj; |
275 | struct drm_i915_gem_object *obj_priv; | ||
276 | int ret; | 287 | int ret; |
277 | 288 | ||
278 | ret = i915_gem_check_is_wedged(dev); | 289 | ret = i915_gem_check_is_wedged(dev); |
279 | if (ret) | 290 | if (ret) |
280 | return ret; | 291 | return ret; |
281 | 292 | ||
282 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 293 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); |
283 | if (obj == NULL) | 294 | if (obj == NULL) |
284 | return -ENOENT; | 295 | return -ENOENT; |
285 | obj_priv = to_intel_bo(obj); | ||
286 | 296 | ||
287 | if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) { | 297 | if (!i915_tiling_ok(dev, |
288 | drm_gem_object_unreference_unlocked(obj); | 298 | args->stride, obj->base.size, args->tiling_mode)) { |
299 | drm_gem_object_unreference_unlocked(&obj->base); | ||
289 | return -EINVAL; | 300 | return -EINVAL; |
290 | } | 301 | } |
291 | 302 | ||
292 | if (obj_priv->pin_count) { | 303 | if (obj->pin_count) { |
293 | drm_gem_object_unreference_unlocked(obj); | 304 | drm_gem_object_unreference_unlocked(&obj->base); |
294 | return -EBUSY; | 305 | return -EBUSY; |
295 | } | 306 | } |
296 | 307 | ||
@@ -324,34 +335,28 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
324 | } | 335 | } |
325 | 336 | ||
326 | mutex_lock(&dev->struct_mutex); | 337 | mutex_lock(&dev->struct_mutex); |
327 | if (args->tiling_mode != obj_priv->tiling_mode || | 338 | if (args->tiling_mode != obj->tiling_mode || |
328 | args->stride != obj_priv->stride) { | 339 | args->stride != obj->stride) { |
329 | /* We need to rebind the object if its current allocation | 340 | /* We need to rebind the object if its current allocation |
330 | * no longer meets the alignment restrictions for its new | 341 | * no longer meets the alignment restrictions for its new |
331 | * tiling mode. Otherwise we can just leave it alone, but | 342 | * tiling mode. Otherwise we can just leave it alone, but |
332 | * need to ensure that any fence register is cleared. | 343 | * need to ensure that any fence register is cleared. |
333 | */ | 344 | */ |
334 | if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode)) | 345 | i915_gem_release_mmap(obj); |
335 | ret = i915_gem_object_unbind(obj); | ||
336 | else if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | ||
337 | ret = i915_gem_object_put_fence_reg(obj, true); | ||
338 | else | ||
339 | i915_gem_release_mmap(obj); | ||
340 | 346 | ||
341 | if (ret != 0) { | 347 | obj->map_and_fenceable = |
342 | args->tiling_mode = obj_priv->tiling_mode; | 348 | obj->gtt_space == NULL || |
343 | args->stride = obj_priv->stride; | 349 | (obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end && |
344 | goto err; | 350 | i915_gem_object_fence_ok(obj, args->tiling_mode)); |
345 | } | ||
346 | 351 | ||
347 | obj_priv->tiling_mode = args->tiling_mode; | 352 | obj->tiling_changed = true; |
348 | obj_priv->stride = args->stride; | 353 | obj->tiling_mode = args->tiling_mode; |
354 | obj->stride = args->stride; | ||
349 | } | 355 | } |
350 | err: | 356 | drm_gem_object_unreference(&obj->base); |
351 | drm_gem_object_unreference(obj); | ||
352 | mutex_unlock(&dev->struct_mutex); | 357 | mutex_unlock(&dev->struct_mutex); |
353 | 358 | ||
354 | return ret; | 359 | return 0; |
355 | } | 360 | } |
356 | 361 | ||
357 | /** | 362 | /** |
@@ -359,22 +364,20 @@ err: | |||
359 | */ | 364 | */ |
360 | int | 365 | int |
361 | i915_gem_get_tiling(struct drm_device *dev, void *data, | 366 | i915_gem_get_tiling(struct drm_device *dev, void *data, |
362 | struct drm_file *file_priv) | 367 | struct drm_file *file) |
363 | { | 368 | { |
364 | struct drm_i915_gem_get_tiling *args = data; | 369 | struct drm_i915_gem_get_tiling *args = data; |
365 | drm_i915_private_t *dev_priv = dev->dev_private; | 370 | drm_i915_private_t *dev_priv = dev->dev_private; |
366 | struct drm_gem_object *obj; | 371 | struct drm_i915_gem_object *obj; |
367 | struct drm_i915_gem_object *obj_priv; | ||
368 | 372 | ||
369 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 373 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); |
370 | if (obj == NULL) | 374 | if (obj == NULL) |
371 | return -ENOENT; | 375 | return -ENOENT; |
372 | obj_priv = to_intel_bo(obj); | ||
373 | 376 | ||
374 | mutex_lock(&dev->struct_mutex); | 377 | mutex_lock(&dev->struct_mutex); |
375 | 378 | ||
376 | args->tiling_mode = obj_priv->tiling_mode; | 379 | args->tiling_mode = obj->tiling_mode; |
377 | switch (obj_priv->tiling_mode) { | 380 | switch (obj->tiling_mode) { |
378 | case I915_TILING_X: | 381 | case I915_TILING_X: |
379 | args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x; | 382 | args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x; |
380 | break; | 383 | break; |
@@ -394,7 +397,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, | |||
394 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17) | 397 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17) |
395 | args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10; | 398 | args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10; |
396 | 399 | ||
397 | drm_gem_object_unreference(obj); | 400 | drm_gem_object_unreference(&obj->base); |
398 | mutex_unlock(&dev->struct_mutex); | 401 | mutex_unlock(&dev->struct_mutex); |
399 | 402 | ||
400 | return 0; | 403 | return 0; |
@@ -424,46 +427,44 @@ i915_gem_swizzle_page(struct page *page) | |||
424 | } | 427 | } |
425 | 428 | ||
426 | void | 429 | void |
427 | i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj) | 430 | i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj) |
428 | { | 431 | { |
429 | struct drm_device *dev = obj->dev; | 432 | struct drm_device *dev = obj->base.dev; |
430 | drm_i915_private_t *dev_priv = dev->dev_private; | 433 | drm_i915_private_t *dev_priv = dev->dev_private; |
431 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 434 | int page_count = obj->base.size >> PAGE_SHIFT; |
432 | int page_count = obj->size >> PAGE_SHIFT; | ||
433 | int i; | 435 | int i; |
434 | 436 | ||
435 | if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17) | 437 | if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17) |
436 | return; | 438 | return; |
437 | 439 | ||
438 | if (obj_priv->bit_17 == NULL) | 440 | if (obj->bit_17 == NULL) |
439 | return; | 441 | return; |
440 | 442 | ||
441 | for (i = 0; i < page_count; i++) { | 443 | for (i = 0; i < page_count; i++) { |
442 | char new_bit_17 = page_to_phys(obj_priv->pages[i]) >> 17; | 444 | char new_bit_17 = page_to_phys(obj->pages[i]) >> 17; |
443 | if ((new_bit_17 & 0x1) != | 445 | if ((new_bit_17 & 0x1) != |
444 | (test_bit(i, obj_priv->bit_17) != 0)) { | 446 | (test_bit(i, obj->bit_17) != 0)) { |
445 | i915_gem_swizzle_page(obj_priv->pages[i]); | 447 | i915_gem_swizzle_page(obj->pages[i]); |
446 | set_page_dirty(obj_priv->pages[i]); | 448 | set_page_dirty(obj->pages[i]); |
447 | } | 449 | } |
448 | } | 450 | } |
449 | } | 451 | } |
450 | 452 | ||
451 | void | 453 | void |
452 | i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj) | 454 | i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj) |
453 | { | 455 | { |
454 | struct drm_device *dev = obj->dev; | 456 | struct drm_device *dev = obj->base.dev; |
455 | drm_i915_private_t *dev_priv = dev->dev_private; | 457 | drm_i915_private_t *dev_priv = dev->dev_private; |
456 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 458 | int page_count = obj->base.size >> PAGE_SHIFT; |
457 | int page_count = obj->size >> PAGE_SHIFT; | ||
458 | int i; | 459 | int i; |
459 | 460 | ||
460 | if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17) | 461 | if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17) |
461 | return; | 462 | return; |
462 | 463 | ||
463 | if (obj_priv->bit_17 == NULL) { | 464 | if (obj->bit_17 == NULL) { |
464 | obj_priv->bit_17 = kmalloc(BITS_TO_LONGS(page_count) * | 465 | obj->bit_17 = kmalloc(BITS_TO_LONGS(page_count) * |
465 | sizeof(long), GFP_KERNEL); | 466 | sizeof(long), GFP_KERNEL); |
466 | if (obj_priv->bit_17 == NULL) { | 467 | if (obj->bit_17 == NULL) { |
467 | DRM_ERROR("Failed to allocate memory for bit 17 " | 468 | DRM_ERROR("Failed to allocate memory for bit 17 " |
468 | "record\n"); | 469 | "record\n"); |
469 | return; | 470 | return; |
@@ -471,9 +472,9 @@ i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj) | |||
471 | } | 472 | } |
472 | 473 | ||
473 | for (i = 0; i < page_count; i++) { | 474 | for (i = 0; i < page_count; i++) { |
474 | if (page_to_phys(obj_priv->pages[i]) & (1 << 17)) | 475 | if (page_to_phys(obj->pages[i]) & (1 << 17)) |
475 | __set_bit(i, obj_priv->bit_17); | 476 | __set_bit(i, obj->bit_17); |
476 | else | 477 | else |
477 | __clear_bit(i, obj_priv->bit_17); | 478 | __clear_bit(i, obj->bit_17); |
478 | } | 479 | } |
479 | } | 480 | } |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 729fd0c91d7..0dadc025b77 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -67,20 +67,20 @@ | |||
67 | void | 67 | void |
68 | ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) | 68 | ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) |
69 | { | 69 | { |
70 | if ((dev_priv->gt_irq_mask_reg & mask) != 0) { | 70 | if ((dev_priv->gt_irq_mask & mask) != 0) { |
71 | dev_priv->gt_irq_mask_reg &= ~mask; | 71 | dev_priv->gt_irq_mask &= ~mask; |
72 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); | 72 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
73 | (void) I915_READ(GTIMR); | 73 | POSTING_READ(GTIMR); |
74 | } | 74 | } |
75 | } | 75 | } |
76 | 76 | ||
77 | void | 77 | void |
78 | ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) | 78 | ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) |
79 | { | 79 | { |
80 | if ((dev_priv->gt_irq_mask_reg & mask) != mask) { | 80 | if ((dev_priv->gt_irq_mask & mask) != mask) { |
81 | dev_priv->gt_irq_mask_reg |= mask; | 81 | dev_priv->gt_irq_mask |= mask; |
82 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); | 82 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
83 | (void) I915_READ(GTIMR); | 83 | POSTING_READ(GTIMR); |
84 | } | 84 | } |
85 | } | 85 | } |
86 | 86 | ||
@@ -88,40 +88,40 @@ ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) | |||
88 | static void | 88 | static void |
89 | ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) | 89 | ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) |
90 | { | 90 | { |
91 | if ((dev_priv->irq_mask_reg & mask) != 0) { | 91 | if ((dev_priv->irq_mask & mask) != 0) { |
92 | dev_priv->irq_mask_reg &= ~mask; | 92 | dev_priv->irq_mask &= ~mask; |
93 | I915_WRITE(DEIMR, dev_priv->irq_mask_reg); | 93 | I915_WRITE(DEIMR, dev_priv->irq_mask); |
94 | (void) I915_READ(DEIMR); | 94 | POSTING_READ(DEIMR); |
95 | } | 95 | } |
96 | } | 96 | } |
97 | 97 | ||
98 | static inline void | 98 | static inline void |
99 | ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) | 99 | ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) |
100 | { | 100 | { |
101 | if ((dev_priv->irq_mask_reg & mask) != mask) { | 101 | if ((dev_priv->irq_mask & mask) != mask) { |
102 | dev_priv->irq_mask_reg |= mask; | 102 | dev_priv->irq_mask |= mask; |
103 | I915_WRITE(DEIMR, dev_priv->irq_mask_reg); | 103 | I915_WRITE(DEIMR, dev_priv->irq_mask); |
104 | (void) I915_READ(DEIMR); | 104 | POSTING_READ(DEIMR); |
105 | } | 105 | } |
106 | } | 106 | } |
107 | 107 | ||
108 | void | 108 | void |
109 | i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) | 109 | i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) |
110 | { | 110 | { |
111 | if ((dev_priv->irq_mask_reg & mask) != 0) { | 111 | if ((dev_priv->irq_mask & mask) != 0) { |
112 | dev_priv->irq_mask_reg &= ~mask; | 112 | dev_priv->irq_mask &= ~mask; |
113 | I915_WRITE(IMR, dev_priv->irq_mask_reg); | 113 | I915_WRITE(IMR, dev_priv->irq_mask); |
114 | (void) I915_READ(IMR); | 114 | POSTING_READ(IMR); |
115 | } | 115 | } |
116 | } | 116 | } |
117 | 117 | ||
118 | void | 118 | void |
119 | i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) | 119 | i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) |
120 | { | 120 | { |
121 | if ((dev_priv->irq_mask_reg & mask) != mask) { | 121 | if ((dev_priv->irq_mask & mask) != mask) { |
122 | dev_priv->irq_mask_reg |= mask; | 122 | dev_priv->irq_mask |= mask; |
123 | I915_WRITE(IMR, dev_priv->irq_mask_reg); | 123 | I915_WRITE(IMR, dev_priv->irq_mask); |
124 | (void) I915_READ(IMR); | 124 | POSTING_READ(IMR); |
125 | } | 125 | } |
126 | } | 126 | } |
127 | 127 | ||
@@ -144,7 +144,7 @@ i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) | |||
144 | dev_priv->pipestat[pipe] |= mask; | 144 | dev_priv->pipestat[pipe] |= mask; |
145 | /* Enable the interrupt, clear any pending status */ | 145 | /* Enable the interrupt, clear any pending status */ |
146 | I915_WRITE(reg, dev_priv->pipestat[pipe] | (mask >> 16)); | 146 | I915_WRITE(reg, dev_priv->pipestat[pipe] | (mask >> 16)); |
147 | (void) I915_READ(reg); | 147 | POSTING_READ(reg); |
148 | } | 148 | } |
149 | } | 149 | } |
150 | 150 | ||
@@ -156,16 +156,19 @@ i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) | |||
156 | 156 | ||
157 | dev_priv->pipestat[pipe] &= ~mask; | 157 | dev_priv->pipestat[pipe] &= ~mask; |
158 | I915_WRITE(reg, dev_priv->pipestat[pipe]); | 158 | I915_WRITE(reg, dev_priv->pipestat[pipe]); |
159 | (void) I915_READ(reg); | 159 | POSTING_READ(reg); |
160 | } | 160 | } |
161 | } | 161 | } |
162 | 162 | ||
163 | /** | 163 | /** |
164 | * intel_enable_asle - enable ASLE interrupt for OpRegion | 164 | * intel_enable_asle - enable ASLE interrupt for OpRegion |
165 | */ | 165 | */ |
166 | void intel_enable_asle (struct drm_device *dev) | 166 | void intel_enable_asle(struct drm_device *dev) |
167 | { | 167 | { |
168 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 168 | drm_i915_private_t *dev_priv = dev->dev_private; |
169 | unsigned long irqflags; | ||
170 | |||
171 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | ||
169 | 172 | ||
170 | if (HAS_PCH_SPLIT(dev)) | 173 | if (HAS_PCH_SPLIT(dev)) |
171 | ironlake_enable_display_irq(dev_priv, DE_GSE); | 174 | ironlake_enable_display_irq(dev_priv, DE_GSE); |
@@ -176,6 +179,8 @@ void intel_enable_asle (struct drm_device *dev) | |||
176 | i915_enable_pipestat(dev_priv, 0, | 179 | i915_enable_pipestat(dev_priv, 0, |
177 | PIPE_LEGACY_BLC_EVENT_ENABLE); | 180 | PIPE_LEGACY_BLC_EVENT_ENABLE); |
178 | } | 181 | } |
182 | |||
183 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
179 | } | 184 | } |
180 | 185 | ||
181 | /** | 186 | /** |
@@ -243,6 +248,92 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) | |||
243 | return I915_READ(reg); | 248 | return I915_READ(reg); |
244 | } | 249 | } |
245 | 250 | ||
251 | int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, | ||
252 | int *vpos, int *hpos) | ||
253 | { | ||
254 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
255 | u32 vbl = 0, position = 0; | ||
256 | int vbl_start, vbl_end, htotal, vtotal; | ||
257 | bool in_vbl = true; | ||
258 | int ret = 0; | ||
259 | |||
260 | if (!i915_pipe_enabled(dev, pipe)) { | ||
261 | DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled " | ||
262 | "pipe %d\n", pipe); | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | /* Get vtotal. */ | ||
267 | vtotal = 1 + ((I915_READ(VTOTAL(pipe)) >> 16) & 0x1fff); | ||
268 | |||
269 | if (INTEL_INFO(dev)->gen >= 4) { | ||
270 | /* No obvious pixelcount register. Only query vertical | ||
271 | * scanout position from Display scan line register. | ||
272 | */ | ||
273 | position = I915_READ(PIPEDSL(pipe)); | ||
274 | |||
275 | /* Decode into vertical scanout position. Don't have | ||
276 | * horizontal scanout position. | ||
277 | */ | ||
278 | *vpos = position & 0x1fff; | ||
279 | *hpos = 0; | ||
280 | } else { | ||
281 | /* Have access to pixelcount since start of frame. | ||
282 | * We can split this into vertical and horizontal | ||
283 | * scanout position. | ||
284 | */ | ||
285 | position = (I915_READ(PIPEFRAMEPIXEL(pipe)) & PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT; | ||
286 | |||
287 | htotal = 1 + ((I915_READ(HTOTAL(pipe)) >> 16) & 0x1fff); | ||
288 | *vpos = position / htotal; | ||
289 | *hpos = position - (*vpos * htotal); | ||
290 | } | ||
291 | |||
292 | /* Query vblank area. */ | ||
293 | vbl = I915_READ(VBLANK(pipe)); | ||
294 | |||
295 | /* Test position against vblank region. */ | ||
296 | vbl_start = vbl & 0x1fff; | ||
297 | vbl_end = (vbl >> 16) & 0x1fff; | ||
298 | |||
299 | if ((*vpos < vbl_start) || (*vpos > vbl_end)) | ||
300 | in_vbl = false; | ||
301 | |||
302 | /* Inside "upper part" of vblank area? Apply corrective offset: */ | ||
303 | if (in_vbl && (*vpos >= vbl_start)) | ||
304 | *vpos = *vpos - vtotal; | ||
305 | |||
306 | /* Readouts valid? */ | ||
307 | if (vbl > 0) | ||
308 | ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; | ||
309 | |||
310 | /* In vblank? */ | ||
311 | if (in_vbl) | ||
312 | ret |= DRM_SCANOUTPOS_INVBL; | ||
313 | |||
314 | return ret; | ||
315 | } | ||
316 | |||
317 | int i915_get_vblank_timestamp(struct drm_device *dev, int crtc, | ||
318 | int *max_error, | ||
319 | struct timeval *vblank_time, | ||
320 | unsigned flags) | ||
321 | { | ||
322 | struct drm_crtc *drmcrtc; | ||
323 | |||
324 | if (crtc < 0 || crtc >= dev->num_crtcs) { | ||
325 | DRM_ERROR("Invalid crtc %d\n", crtc); | ||
326 | return -EINVAL; | ||
327 | } | ||
328 | |||
329 | /* Get drm_crtc to timestamp: */ | ||
330 | drmcrtc = intel_get_crtc_for_pipe(dev, crtc); | ||
331 | |||
332 | /* Helper routine in DRM core does all the work: */ | ||
333 | return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, | ||
334 | vblank_time, flags, drmcrtc); | ||
335 | } | ||
336 | |||
246 | /* | 337 | /* |
247 | * Handle hotplug events outside the interrupt handler proper. | 338 | * Handle hotplug events outside the interrupt handler proper. |
248 | */ | 339 | */ |
@@ -297,8 +388,8 @@ static void notify_ring(struct drm_device *dev, | |||
297 | struct intel_ring_buffer *ring) | 388 | struct intel_ring_buffer *ring) |
298 | { | 389 | { |
299 | struct drm_i915_private *dev_priv = dev->dev_private; | 390 | struct drm_i915_private *dev_priv = dev->dev_private; |
300 | u32 seqno = ring->get_seqno(dev, ring); | 391 | u32 seqno = ring->get_seqno(ring); |
301 | ring->irq_gem_seqno = seqno; | 392 | ring->irq_seqno = seqno; |
302 | trace_i915_gem_request_complete(dev, seqno); | 393 | trace_i915_gem_request_complete(dev, seqno); |
303 | wake_up_all(&ring->irq_queue); | 394 | wake_up_all(&ring->irq_queue); |
304 | dev_priv->hangcheck_count = 0; | 395 | dev_priv->hangcheck_count = 0; |
@@ -306,11 +397,49 @@ static void notify_ring(struct drm_device *dev, | |||
306 | jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); | 397 | jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); |
307 | } | 398 | } |
308 | 399 | ||
400 | static void gen6_pm_irq_handler(struct drm_device *dev) | ||
401 | { | ||
402 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
403 | u8 new_delay = dev_priv->cur_delay; | ||
404 | u32 pm_iir; | ||
405 | |||
406 | pm_iir = I915_READ(GEN6_PMIIR); | ||
407 | if (!pm_iir) | ||
408 | return; | ||
409 | |||
410 | if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) { | ||
411 | if (dev_priv->cur_delay != dev_priv->max_delay) | ||
412 | new_delay = dev_priv->cur_delay + 1; | ||
413 | if (new_delay > dev_priv->max_delay) | ||
414 | new_delay = dev_priv->max_delay; | ||
415 | } else if (pm_iir & (GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT)) { | ||
416 | if (dev_priv->cur_delay != dev_priv->min_delay) | ||
417 | new_delay = dev_priv->cur_delay - 1; | ||
418 | if (new_delay < dev_priv->min_delay) { | ||
419 | new_delay = dev_priv->min_delay; | ||
420 | I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, | ||
421 | I915_READ(GEN6_RP_INTERRUPT_LIMITS) | | ||
422 | ((new_delay << 16) & 0x3f0000)); | ||
423 | } else { | ||
424 | /* Make sure we continue to get down interrupts | ||
425 | * until we hit the minimum frequency */ | ||
426 | I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, | ||
427 | I915_READ(GEN6_RP_INTERRUPT_LIMITS) & ~0x3f0000); | ||
428 | } | ||
429 | |||
430 | } | ||
431 | |||
432 | gen6_set_rps(dev, new_delay); | ||
433 | dev_priv->cur_delay = new_delay; | ||
434 | |||
435 | I915_WRITE(GEN6_PMIIR, pm_iir); | ||
436 | } | ||
437 | |||
309 | static irqreturn_t ironlake_irq_handler(struct drm_device *dev) | 438 | static irqreturn_t ironlake_irq_handler(struct drm_device *dev) |
310 | { | 439 | { |
311 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 440 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
312 | int ret = IRQ_NONE; | 441 | int ret = IRQ_NONE; |
313 | u32 de_iir, gt_iir, de_ier, pch_iir; | 442 | u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir; |
314 | u32 hotplug_mask; | 443 | u32 hotplug_mask; |
315 | struct drm_i915_master_private *master_priv; | 444 | struct drm_i915_master_private *master_priv; |
316 | u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT; | 445 | u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT; |
@@ -321,13 +450,15 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
321 | /* disable master interrupt before clearing iir */ | 450 | /* disable master interrupt before clearing iir */ |
322 | de_ier = I915_READ(DEIER); | 451 | de_ier = I915_READ(DEIER); |
323 | I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); | 452 | I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); |
324 | (void)I915_READ(DEIER); | 453 | POSTING_READ(DEIER); |
325 | 454 | ||
326 | de_iir = I915_READ(DEIIR); | 455 | de_iir = I915_READ(DEIIR); |
327 | gt_iir = I915_READ(GTIIR); | 456 | gt_iir = I915_READ(GTIIR); |
328 | pch_iir = I915_READ(SDEIIR); | 457 | pch_iir = I915_READ(SDEIIR); |
458 | pm_iir = I915_READ(GEN6_PMIIR); | ||
329 | 459 | ||
330 | if (de_iir == 0 && gt_iir == 0 && pch_iir == 0) | 460 | if (de_iir == 0 && gt_iir == 0 && pch_iir == 0 && |
461 | (!IS_GEN6(dev) || pm_iir == 0)) | ||
331 | goto done; | 462 | goto done; |
332 | 463 | ||
333 | if (HAS_PCH_CPT(dev)) | 464 | if (HAS_PCH_CPT(dev)) |
@@ -344,12 +475,12 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
344 | READ_BREADCRUMB(dev_priv); | 475 | READ_BREADCRUMB(dev_priv); |
345 | } | 476 | } |
346 | 477 | ||
347 | if (gt_iir & GT_PIPE_NOTIFY) | 478 | if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) |
348 | notify_ring(dev, &dev_priv->render_ring); | 479 | notify_ring(dev, &dev_priv->ring[RCS]); |
349 | if (gt_iir & bsd_usr_interrupt) | 480 | if (gt_iir & bsd_usr_interrupt) |
350 | notify_ring(dev, &dev_priv->bsd_ring); | 481 | notify_ring(dev, &dev_priv->ring[VCS]); |
351 | if (HAS_BLT(dev) && gt_iir & GT_BLT_USER_INTERRUPT) | 482 | if (gt_iir & GT_BLT_USER_INTERRUPT) |
352 | notify_ring(dev, &dev_priv->blt_ring); | 483 | notify_ring(dev, &dev_priv->ring[BCS]); |
353 | 484 | ||
354 | if (de_iir & DE_GSE) | 485 | if (de_iir & DE_GSE) |
355 | intel_opregion_gse_intr(dev); | 486 | intel_opregion_gse_intr(dev); |
@@ -379,6 +510,9 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
379 | i915_handle_rps_change(dev); | 510 | i915_handle_rps_change(dev); |
380 | } | 511 | } |
381 | 512 | ||
513 | if (IS_GEN6(dev)) | ||
514 | gen6_pm_irq_handler(dev); | ||
515 | |||
382 | /* should clear PCH hotplug event before clear CPU irq */ | 516 | /* should clear PCH hotplug event before clear CPU irq */ |
383 | I915_WRITE(SDEIIR, pch_iir); | 517 | I915_WRITE(SDEIIR, pch_iir); |
384 | I915_WRITE(GTIIR, gt_iir); | 518 | I915_WRITE(GTIIR, gt_iir); |
@@ -386,7 +520,7 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
386 | 520 | ||
387 | done: | 521 | done: |
388 | I915_WRITE(DEIER, de_ier); | 522 | I915_WRITE(DEIER, de_ier); |
389 | (void)I915_READ(DEIER); | 523 | POSTING_READ(DEIER); |
390 | 524 | ||
391 | return ret; | 525 | return ret; |
392 | } | 526 | } |
@@ -423,28 +557,23 @@ static void i915_error_work_func(struct work_struct *work) | |||
423 | #ifdef CONFIG_DEBUG_FS | 557 | #ifdef CONFIG_DEBUG_FS |
424 | static struct drm_i915_error_object * | 558 | static struct drm_i915_error_object * |
425 | i915_error_object_create(struct drm_device *dev, | 559 | i915_error_object_create(struct drm_device *dev, |
426 | struct drm_gem_object *src) | 560 | struct drm_i915_gem_object *src) |
427 | { | 561 | { |
428 | drm_i915_private_t *dev_priv = dev->dev_private; | 562 | drm_i915_private_t *dev_priv = dev->dev_private; |
429 | struct drm_i915_error_object *dst; | 563 | struct drm_i915_error_object *dst; |
430 | struct drm_i915_gem_object *src_priv; | ||
431 | int page, page_count; | 564 | int page, page_count; |
432 | u32 reloc_offset; | 565 | u32 reloc_offset; |
433 | 566 | ||
434 | if (src == NULL) | 567 | if (src == NULL || src->pages == NULL) |
435 | return NULL; | ||
436 | |||
437 | src_priv = to_intel_bo(src); | ||
438 | if (src_priv->pages == NULL) | ||
439 | return NULL; | 568 | return NULL; |
440 | 569 | ||
441 | page_count = src->size / PAGE_SIZE; | 570 | page_count = src->base.size / PAGE_SIZE; |
442 | 571 | ||
443 | dst = kmalloc(sizeof(*dst) + page_count * sizeof (u32 *), GFP_ATOMIC); | 572 | dst = kmalloc(sizeof(*dst) + page_count * sizeof (u32 *), GFP_ATOMIC); |
444 | if (dst == NULL) | 573 | if (dst == NULL) |
445 | return NULL; | 574 | return NULL; |
446 | 575 | ||
447 | reloc_offset = src_priv->gtt_offset; | 576 | reloc_offset = src->gtt_offset; |
448 | for (page = 0; page < page_count; page++) { | 577 | for (page = 0; page < page_count; page++) { |
449 | unsigned long flags; | 578 | unsigned long flags; |
450 | void __iomem *s; | 579 | void __iomem *s; |
@@ -466,7 +595,7 @@ i915_error_object_create(struct drm_device *dev, | |||
466 | reloc_offset += PAGE_SIZE; | 595 | reloc_offset += PAGE_SIZE; |
467 | } | 596 | } |
468 | dst->page_count = page_count; | 597 | dst->page_count = page_count; |
469 | dst->gtt_offset = src_priv->gtt_offset; | 598 | dst->gtt_offset = src->gtt_offset; |
470 | 599 | ||
471 | return dst; | 600 | return dst; |
472 | 601 | ||
@@ -520,36 +649,96 @@ i915_get_bbaddr(struct drm_device *dev, u32 *ring) | |||
520 | } | 649 | } |
521 | 650 | ||
522 | static u32 | 651 | static u32 |
523 | i915_ringbuffer_last_batch(struct drm_device *dev) | 652 | i915_ringbuffer_last_batch(struct drm_device *dev, |
653 | struct intel_ring_buffer *ring) | ||
524 | { | 654 | { |
525 | struct drm_i915_private *dev_priv = dev->dev_private; | 655 | struct drm_i915_private *dev_priv = dev->dev_private; |
526 | u32 head, bbaddr; | 656 | u32 head, bbaddr; |
527 | u32 *ring; | 657 | u32 *val; |
528 | 658 | ||
529 | /* Locate the current position in the ringbuffer and walk back | 659 | /* Locate the current position in the ringbuffer and walk back |
530 | * to find the most recently dispatched batch buffer. | 660 | * to find the most recently dispatched batch buffer. |
531 | */ | 661 | */ |
532 | bbaddr = 0; | 662 | head = I915_READ_HEAD(ring) & HEAD_ADDR; |
533 | head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | ||
534 | ring = (u32 *)(dev_priv->render_ring.virtual_start + head); | ||
535 | 663 | ||
536 | while (--ring >= (u32 *)dev_priv->render_ring.virtual_start) { | 664 | val = (u32 *)(ring->virtual_start + head); |
537 | bbaddr = i915_get_bbaddr(dev, ring); | 665 | while (--val >= (u32 *)ring->virtual_start) { |
666 | bbaddr = i915_get_bbaddr(dev, val); | ||
538 | if (bbaddr) | 667 | if (bbaddr) |
539 | break; | 668 | return bbaddr; |
540 | } | 669 | } |
541 | 670 | ||
542 | if (bbaddr == 0) { | 671 | val = (u32 *)(ring->virtual_start + ring->size); |
543 | ring = (u32 *)(dev_priv->render_ring.virtual_start | 672 | while (--val >= (u32 *)ring->virtual_start) { |
544 | + dev_priv->render_ring.size); | 673 | bbaddr = i915_get_bbaddr(dev, val); |
545 | while (--ring >= (u32 *)dev_priv->render_ring.virtual_start) { | 674 | if (bbaddr) |
546 | bbaddr = i915_get_bbaddr(dev, ring); | 675 | return bbaddr; |
547 | if (bbaddr) | ||
548 | break; | ||
549 | } | ||
550 | } | 676 | } |
551 | 677 | ||
552 | return bbaddr; | 678 | return 0; |
679 | } | ||
680 | |||
681 | static u32 capture_bo_list(struct drm_i915_error_buffer *err, | ||
682 | int count, | ||
683 | struct list_head *head) | ||
684 | { | ||
685 | struct drm_i915_gem_object *obj; | ||
686 | int i = 0; | ||
687 | |||
688 | list_for_each_entry(obj, head, mm_list) { | ||
689 | err->size = obj->base.size; | ||
690 | err->name = obj->base.name; | ||
691 | err->seqno = obj->last_rendering_seqno; | ||
692 | err->gtt_offset = obj->gtt_offset; | ||
693 | err->read_domains = obj->base.read_domains; | ||
694 | err->write_domain = obj->base.write_domain; | ||
695 | err->fence_reg = obj->fence_reg; | ||
696 | err->pinned = 0; | ||
697 | if (obj->pin_count > 0) | ||
698 | err->pinned = 1; | ||
699 | if (obj->user_pin_count > 0) | ||
700 | err->pinned = -1; | ||
701 | err->tiling = obj->tiling_mode; | ||
702 | err->dirty = obj->dirty; | ||
703 | err->purgeable = obj->madv != I915_MADV_WILLNEED; | ||
704 | err->ring = obj->ring ? obj->ring->id : 0; | ||
705 | |||
706 | if (++i == count) | ||
707 | break; | ||
708 | |||
709 | err++; | ||
710 | } | ||
711 | |||
712 | return i; | ||
713 | } | ||
714 | |||
715 | static void i915_gem_record_fences(struct drm_device *dev, | ||
716 | struct drm_i915_error_state *error) | ||
717 | { | ||
718 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
719 | int i; | ||
720 | |||
721 | /* Fences */ | ||
722 | switch (INTEL_INFO(dev)->gen) { | ||
723 | case 6: | ||
724 | for (i = 0; i < 16; i++) | ||
725 | error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); | ||
726 | break; | ||
727 | case 5: | ||
728 | case 4: | ||
729 | for (i = 0; i < 16; i++) | ||
730 | error->fence[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); | ||
731 | break; | ||
732 | case 3: | ||
733 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | ||
734 | for (i = 0; i < 8; i++) | ||
735 | error->fence[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); | ||
736 | case 2: | ||
737 | for (i = 0; i < 8; i++) | ||
738 | error->fence[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); | ||
739 | break; | ||
740 | |||
741 | } | ||
553 | } | 742 | } |
554 | 743 | ||
555 | /** | 744 | /** |
@@ -564,9 +753,9 @@ i915_ringbuffer_last_batch(struct drm_device *dev) | |||
564 | static void i915_capture_error_state(struct drm_device *dev) | 753 | static void i915_capture_error_state(struct drm_device *dev) |
565 | { | 754 | { |
566 | struct drm_i915_private *dev_priv = dev->dev_private; | 755 | struct drm_i915_private *dev_priv = dev->dev_private; |
567 | struct drm_i915_gem_object *obj_priv; | 756 | struct drm_i915_gem_object *obj; |
568 | struct drm_i915_error_state *error; | 757 | struct drm_i915_error_state *error; |
569 | struct drm_gem_object *batchbuffer[2]; | 758 | struct drm_i915_gem_object *batchbuffer[2]; |
570 | unsigned long flags; | 759 | unsigned long flags; |
571 | u32 bbaddr; | 760 | u32 bbaddr; |
572 | int count; | 761 | int count; |
@@ -585,20 +774,33 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
585 | 774 | ||
586 | DRM_DEBUG_DRIVER("generating error event\n"); | 775 | DRM_DEBUG_DRIVER("generating error event\n"); |
587 | 776 | ||
588 | error->seqno = | 777 | error->seqno = dev_priv->ring[RCS].get_seqno(&dev_priv->ring[RCS]); |
589 | dev_priv->render_ring.get_seqno(dev, &dev_priv->render_ring); | ||
590 | error->eir = I915_READ(EIR); | 778 | error->eir = I915_READ(EIR); |
591 | error->pgtbl_er = I915_READ(PGTBL_ER); | 779 | error->pgtbl_er = I915_READ(PGTBL_ER); |
592 | error->pipeastat = I915_READ(PIPEASTAT); | 780 | error->pipeastat = I915_READ(PIPEASTAT); |
593 | error->pipebstat = I915_READ(PIPEBSTAT); | 781 | error->pipebstat = I915_READ(PIPEBSTAT); |
594 | error->instpm = I915_READ(INSTPM); | 782 | error->instpm = I915_READ(INSTPM); |
595 | if (INTEL_INFO(dev)->gen < 4) { | 783 | error->error = 0; |
596 | error->ipeir = I915_READ(IPEIR); | 784 | if (INTEL_INFO(dev)->gen >= 6) { |
597 | error->ipehr = I915_READ(IPEHR); | 785 | error->error = I915_READ(ERROR_GEN6); |
598 | error->instdone = I915_READ(INSTDONE); | 786 | |
599 | error->acthd = I915_READ(ACTHD); | 787 | error->bcs_acthd = I915_READ(BCS_ACTHD); |
600 | error->bbaddr = 0; | 788 | error->bcs_ipehr = I915_READ(BCS_IPEHR); |
601 | } else { | 789 | error->bcs_ipeir = I915_READ(BCS_IPEIR); |
790 | error->bcs_instdone = I915_READ(BCS_INSTDONE); | ||
791 | error->bcs_seqno = 0; | ||
792 | if (dev_priv->ring[BCS].get_seqno) | ||
793 | error->bcs_seqno = dev_priv->ring[BCS].get_seqno(&dev_priv->ring[BCS]); | ||
794 | |||
795 | error->vcs_acthd = I915_READ(VCS_ACTHD); | ||
796 | error->vcs_ipehr = I915_READ(VCS_IPEHR); | ||
797 | error->vcs_ipeir = I915_READ(VCS_IPEIR); | ||
798 | error->vcs_instdone = I915_READ(VCS_INSTDONE); | ||
799 | error->vcs_seqno = 0; | ||
800 | if (dev_priv->ring[VCS].get_seqno) | ||
801 | error->vcs_seqno = dev_priv->ring[VCS].get_seqno(&dev_priv->ring[VCS]); | ||
802 | } | ||
803 | if (INTEL_INFO(dev)->gen >= 4) { | ||
602 | error->ipeir = I915_READ(IPEIR_I965); | 804 | error->ipeir = I915_READ(IPEIR_I965); |
603 | error->ipehr = I915_READ(IPEHR_I965); | 805 | error->ipehr = I915_READ(IPEHR_I965); |
604 | error->instdone = I915_READ(INSTDONE_I965); | 806 | error->instdone = I915_READ(INSTDONE_I965); |
@@ -606,42 +808,45 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
606 | error->instdone1 = I915_READ(INSTDONE1); | 808 | error->instdone1 = I915_READ(INSTDONE1); |
607 | error->acthd = I915_READ(ACTHD_I965); | 809 | error->acthd = I915_READ(ACTHD_I965); |
608 | error->bbaddr = I915_READ64(BB_ADDR); | 810 | error->bbaddr = I915_READ64(BB_ADDR); |
811 | } else { | ||
812 | error->ipeir = I915_READ(IPEIR); | ||
813 | error->ipehr = I915_READ(IPEHR); | ||
814 | error->instdone = I915_READ(INSTDONE); | ||
815 | error->acthd = I915_READ(ACTHD); | ||
816 | error->bbaddr = 0; | ||
609 | } | 817 | } |
818 | i915_gem_record_fences(dev, error); | ||
610 | 819 | ||
611 | bbaddr = i915_ringbuffer_last_batch(dev); | 820 | bbaddr = i915_ringbuffer_last_batch(dev, &dev_priv->ring[RCS]); |
612 | 821 | ||
613 | /* Grab the current batchbuffer, most likely to have crashed. */ | 822 | /* Grab the current batchbuffer, most likely to have crashed. */ |
614 | batchbuffer[0] = NULL; | 823 | batchbuffer[0] = NULL; |
615 | batchbuffer[1] = NULL; | 824 | batchbuffer[1] = NULL; |
616 | count = 0; | 825 | count = 0; |
617 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, mm_list) { | 826 | list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { |
618 | struct drm_gem_object *obj = &obj_priv->base; | ||
619 | |||
620 | if (batchbuffer[0] == NULL && | 827 | if (batchbuffer[0] == NULL && |
621 | bbaddr >= obj_priv->gtt_offset && | 828 | bbaddr >= obj->gtt_offset && |
622 | bbaddr < obj_priv->gtt_offset + obj->size) | 829 | bbaddr < obj->gtt_offset + obj->base.size) |
623 | batchbuffer[0] = obj; | 830 | batchbuffer[0] = obj; |
624 | 831 | ||
625 | if (batchbuffer[1] == NULL && | 832 | if (batchbuffer[1] == NULL && |
626 | error->acthd >= obj_priv->gtt_offset && | 833 | error->acthd >= obj->gtt_offset && |
627 | error->acthd < obj_priv->gtt_offset + obj->size) | 834 | error->acthd < obj->gtt_offset + obj->base.size) |
628 | batchbuffer[1] = obj; | 835 | batchbuffer[1] = obj; |
629 | 836 | ||
630 | count++; | 837 | count++; |
631 | } | 838 | } |
632 | /* Scan the other lists for completeness for those bizarre errors. */ | 839 | /* Scan the other lists for completeness for those bizarre errors. */ |
633 | if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { | 840 | if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { |
634 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, mm_list) { | 841 | list_for_each_entry(obj, &dev_priv->mm.flushing_list, mm_list) { |
635 | struct drm_gem_object *obj = &obj_priv->base; | ||
636 | |||
637 | if (batchbuffer[0] == NULL && | 842 | if (batchbuffer[0] == NULL && |
638 | bbaddr >= obj_priv->gtt_offset && | 843 | bbaddr >= obj->gtt_offset && |
639 | bbaddr < obj_priv->gtt_offset + obj->size) | 844 | bbaddr < obj->gtt_offset + obj->base.size) |
640 | batchbuffer[0] = obj; | 845 | batchbuffer[0] = obj; |
641 | 846 | ||
642 | if (batchbuffer[1] == NULL && | 847 | if (batchbuffer[1] == NULL && |
643 | error->acthd >= obj_priv->gtt_offset && | 848 | error->acthd >= obj->gtt_offset && |
644 | error->acthd < obj_priv->gtt_offset + obj->size) | 849 | error->acthd < obj->gtt_offset + obj->base.size) |
645 | batchbuffer[1] = obj; | 850 | batchbuffer[1] = obj; |
646 | 851 | ||
647 | if (batchbuffer[0] && batchbuffer[1]) | 852 | if (batchbuffer[0] && batchbuffer[1]) |
@@ -649,17 +854,15 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
649 | } | 854 | } |
650 | } | 855 | } |
651 | if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { | 856 | if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { |
652 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, mm_list) { | 857 | list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) { |
653 | struct drm_gem_object *obj = &obj_priv->base; | ||
654 | |||
655 | if (batchbuffer[0] == NULL && | 858 | if (batchbuffer[0] == NULL && |
656 | bbaddr >= obj_priv->gtt_offset && | 859 | bbaddr >= obj->gtt_offset && |
657 | bbaddr < obj_priv->gtt_offset + obj->size) | 860 | bbaddr < obj->gtt_offset + obj->base.size) |
658 | batchbuffer[0] = obj; | 861 | batchbuffer[0] = obj; |
659 | 862 | ||
660 | if (batchbuffer[1] == NULL && | 863 | if (batchbuffer[1] == NULL && |
661 | error->acthd >= obj_priv->gtt_offset && | 864 | error->acthd >= obj->gtt_offset && |
662 | error->acthd < obj_priv->gtt_offset + obj->size) | 865 | error->acthd < obj->gtt_offset + obj->base.size) |
663 | batchbuffer[1] = obj; | 866 | batchbuffer[1] = obj; |
664 | 867 | ||
665 | if (batchbuffer[0] && batchbuffer[1]) | 868 | if (batchbuffer[0] && batchbuffer[1]) |
@@ -678,46 +881,41 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
678 | 881 | ||
679 | /* Record the ringbuffer */ | 882 | /* Record the ringbuffer */ |
680 | error->ringbuffer = i915_error_object_create(dev, | 883 | error->ringbuffer = i915_error_object_create(dev, |
681 | dev_priv->render_ring.gem_object); | 884 | dev_priv->ring[RCS].obj); |
682 | 885 | ||
683 | /* Record buffers on the active list. */ | 886 | /* Record buffers on the active and pinned lists. */ |
684 | error->active_bo = NULL; | 887 | error->active_bo = NULL; |
685 | error->active_bo_count = 0; | 888 | error->pinned_bo = NULL; |
686 | 889 | ||
687 | if (count) | 890 | error->active_bo_count = count; |
891 | list_for_each_entry(obj, &dev_priv->mm.pinned_list, mm_list) | ||
892 | count++; | ||
893 | error->pinned_bo_count = count - error->active_bo_count; | ||
894 | |||
895 | if (count) { | ||
688 | error->active_bo = kmalloc(sizeof(*error->active_bo)*count, | 896 | error->active_bo = kmalloc(sizeof(*error->active_bo)*count, |
689 | GFP_ATOMIC); | 897 | GFP_ATOMIC); |
690 | 898 | if (error->active_bo) | |
691 | if (error->active_bo) { | 899 | error->pinned_bo = |
692 | int i = 0; | 900 | error->active_bo + error->active_bo_count; |
693 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, mm_list) { | ||
694 | struct drm_gem_object *obj = &obj_priv->base; | ||
695 | |||
696 | error->active_bo[i].size = obj->size; | ||
697 | error->active_bo[i].name = obj->name; | ||
698 | error->active_bo[i].seqno = obj_priv->last_rendering_seqno; | ||
699 | error->active_bo[i].gtt_offset = obj_priv->gtt_offset; | ||
700 | error->active_bo[i].read_domains = obj->read_domains; | ||
701 | error->active_bo[i].write_domain = obj->write_domain; | ||
702 | error->active_bo[i].fence_reg = obj_priv->fence_reg; | ||
703 | error->active_bo[i].pinned = 0; | ||
704 | if (obj_priv->pin_count > 0) | ||
705 | error->active_bo[i].pinned = 1; | ||
706 | if (obj_priv->user_pin_count > 0) | ||
707 | error->active_bo[i].pinned = -1; | ||
708 | error->active_bo[i].tiling = obj_priv->tiling_mode; | ||
709 | error->active_bo[i].dirty = obj_priv->dirty; | ||
710 | error->active_bo[i].purgeable = obj_priv->madv != I915_MADV_WILLNEED; | ||
711 | |||
712 | if (++i == count) | ||
713 | break; | ||
714 | } | ||
715 | error->active_bo_count = i; | ||
716 | } | 901 | } |
717 | 902 | ||
903 | if (error->active_bo) | ||
904 | error->active_bo_count = | ||
905 | capture_bo_list(error->active_bo, | ||
906 | error->active_bo_count, | ||
907 | &dev_priv->mm.active_list); | ||
908 | |||
909 | if (error->pinned_bo) | ||
910 | error->pinned_bo_count = | ||
911 | capture_bo_list(error->pinned_bo, | ||
912 | error->pinned_bo_count, | ||
913 | &dev_priv->mm.pinned_list); | ||
914 | |||
718 | do_gettimeofday(&error->time); | 915 | do_gettimeofday(&error->time); |
719 | 916 | ||
720 | error->overlay = intel_overlay_capture_error_state(dev); | 917 | error->overlay = intel_overlay_capture_error_state(dev); |
918 | error->display = intel_display_capture_error_state(dev); | ||
721 | 919 | ||
722 | spin_lock_irqsave(&dev_priv->error_lock, flags); | 920 | spin_lock_irqsave(&dev_priv->error_lock, flags); |
723 | if (dev_priv->first_error == NULL) { | 921 | if (dev_priv->first_error == NULL) { |
@@ -775,7 +973,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev) | |||
775 | printk(KERN_ERR " ACTHD: 0x%08x\n", | 973 | printk(KERN_ERR " ACTHD: 0x%08x\n", |
776 | I915_READ(ACTHD_I965)); | 974 | I915_READ(ACTHD_I965)); |
777 | I915_WRITE(IPEIR_I965, ipeir); | 975 | I915_WRITE(IPEIR_I965, ipeir); |
778 | (void)I915_READ(IPEIR_I965); | 976 | POSTING_READ(IPEIR_I965); |
779 | } | 977 | } |
780 | if (eir & GM45_ERROR_PAGE_TABLE) { | 978 | if (eir & GM45_ERROR_PAGE_TABLE) { |
781 | u32 pgtbl_err = I915_READ(PGTBL_ER); | 979 | u32 pgtbl_err = I915_READ(PGTBL_ER); |
@@ -783,7 +981,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev) | |||
783 | printk(KERN_ERR " PGTBL_ER: 0x%08x\n", | 981 | printk(KERN_ERR " PGTBL_ER: 0x%08x\n", |
784 | pgtbl_err); | 982 | pgtbl_err); |
785 | I915_WRITE(PGTBL_ER, pgtbl_err); | 983 | I915_WRITE(PGTBL_ER, pgtbl_err); |
786 | (void)I915_READ(PGTBL_ER); | 984 | POSTING_READ(PGTBL_ER); |
787 | } | 985 | } |
788 | } | 986 | } |
789 | 987 | ||
@@ -794,7 +992,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev) | |||
794 | printk(KERN_ERR " PGTBL_ER: 0x%08x\n", | 992 | printk(KERN_ERR " PGTBL_ER: 0x%08x\n", |
795 | pgtbl_err); | 993 | pgtbl_err); |
796 | I915_WRITE(PGTBL_ER, pgtbl_err); | 994 | I915_WRITE(PGTBL_ER, pgtbl_err); |
797 | (void)I915_READ(PGTBL_ER); | 995 | POSTING_READ(PGTBL_ER); |
798 | } | 996 | } |
799 | } | 997 | } |
800 | 998 | ||
@@ -825,7 +1023,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev) | |||
825 | printk(KERN_ERR " ACTHD: 0x%08x\n", | 1023 | printk(KERN_ERR " ACTHD: 0x%08x\n", |
826 | I915_READ(ACTHD)); | 1024 | I915_READ(ACTHD)); |
827 | I915_WRITE(IPEIR, ipeir); | 1025 | I915_WRITE(IPEIR, ipeir); |
828 | (void)I915_READ(IPEIR); | 1026 | POSTING_READ(IPEIR); |
829 | } else { | 1027 | } else { |
830 | u32 ipeir = I915_READ(IPEIR_I965); | 1028 | u32 ipeir = I915_READ(IPEIR_I965); |
831 | 1029 | ||
@@ -842,12 +1040,12 @@ static void i915_report_and_clear_eir(struct drm_device *dev) | |||
842 | printk(KERN_ERR " ACTHD: 0x%08x\n", | 1040 | printk(KERN_ERR " ACTHD: 0x%08x\n", |
843 | I915_READ(ACTHD_I965)); | 1041 | I915_READ(ACTHD_I965)); |
844 | I915_WRITE(IPEIR_I965, ipeir); | 1042 | I915_WRITE(IPEIR_I965, ipeir); |
845 | (void)I915_READ(IPEIR_I965); | 1043 | POSTING_READ(IPEIR_I965); |
846 | } | 1044 | } |
847 | } | 1045 | } |
848 | 1046 | ||
849 | I915_WRITE(EIR, eir); | 1047 | I915_WRITE(EIR, eir); |
850 | (void)I915_READ(EIR); | 1048 | POSTING_READ(EIR); |
851 | eir = I915_READ(EIR); | 1049 | eir = I915_READ(EIR); |
852 | if (eir) { | 1050 | if (eir) { |
853 | /* | 1051 | /* |
@@ -870,7 +1068,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev) | |||
870 | * so userspace knows something bad happened (should trigger collection | 1068 | * so userspace knows something bad happened (should trigger collection |
871 | * of a ring dump etc.). | 1069 | * of a ring dump etc.). |
872 | */ | 1070 | */ |
873 | static void i915_handle_error(struct drm_device *dev, bool wedged) | 1071 | void i915_handle_error(struct drm_device *dev, bool wedged) |
874 | { | 1072 | { |
875 | struct drm_i915_private *dev_priv = dev->dev_private; | 1073 | struct drm_i915_private *dev_priv = dev->dev_private; |
876 | 1074 | ||
@@ -884,11 +1082,11 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) | |||
884 | /* | 1082 | /* |
885 | * Wakeup waiting processes so they don't hang | 1083 | * Wakeup waiting processes so they don't hang |
886 | */ | 1084 | */ |
887 | wake_up_all(&dev_priv->render_ring.irq_queue); | 1085 | wake_up_all(&dev_priv->ring[RCS].irq_queue); |
888 | if (HAS_BSD(dev)) | 1086 | if (HAS_BSD(dev)) |
889 | wake_up_all(&dev_priv->bsd_ring.irq_queue); | 1087 | wake_up_all(&dev_priv->ring[VCS].irq_queue); |
890 | if (HAS_BLT(dev)) | 1088 | if (HAS_BLT(dev)) |
891 | wake_up_all(&dev_priv->blt_ring.irq_queue); | 1089 | wake_up_all(&dev_priv->ring[BCS].irq_queue); |
892 | } | 1090 | } |
893 | 1091 | ||
894 | queue_work(dev_priv->wq, &dev_priv->error_work); | 1092 | queue_work(dev_priv->wq, &dev_priv->error_work); |
@@ -899,7 +1097,7 @@ static void i915_pageflip_stall_check(struct drm_device *dev, int pipe) | |||
899 | drm_i915_private_t *dev_priv = dev->dev_private; | 1097 | drm_i915_private_t *dev_priv = dev->dev_private; |
900 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | 1098 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; |
901 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1099 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
902 | struct drm_i915_gem_object *obj_priv; | 1100 | struct drm_i915_gem_object *obj; |
903 | struct intel_unpin_work *work; | 1101 | struct intel_unpin_work *work; |
904 | unsigned long flags; | 1102 | unsigned long flags; |
905 | bool stall_detected; | 1103 | bool stall_detected; |
@@ -918,13 +1116,13 @@ static void i915_pageflip_stall_check(struct drm_device *dev, int pipe) | |||
918 | } | 1116 | } |
919 | 1117 | ||
920 | /* Potential stall - if we see that the flip has happened, assume a missed interrupt */ | 1118 | /* Potential stall - if we see that the flip has happened, assume a missed interrupt */ |
921 | obj_priv = to_intel_bo(work->pending_flip_obj); | 1119 | obj = work->pending_flip_obj; |
922 | if (INTEL_INFO(dev)->gen >= 4) { | 1120 | if (INTEL_INFO(dev)->gen >= 4) { |
923 | int dspsurf = intel_crtc->plane == 0 ? DSPASURF : DSPBSURF; | 1121 | int dspsurf = intel_crtc->plane == 0 ? DSPASURF : DSPBSURF; |
924 | stall_detected = I915_READ(dspsurf) == obj_priv->gtt_offset; | 1122 | stall_detected = I915_READ(dspsurf) == obj->gtt_offset; |
925 | } else { | 1123 | } else { |
926 | int dspaddr = intel_crtc->plane == 0 ? DSPAADDR : DSPBADDR; | 1124 | int dspaddr = intel_crtc->plane == 0 ? DSPAADDR : DSPBADDR; |
927 | stall_detected = I915_READ(dspaddr) == (obj_priv->gtt_offset + | 1125 | stall_detected = I915_READ(dspaddr) == (obj->gtt_offset + |
928 | crtc->y * crtc->fb->pitch + | 1126 | crtc->y * crtc->fb->pitch + |
929 | crtc->x * crtc->fb->bits_per_pixel/8); | 1127 | crtc->x * crtc->fb->bits_per_pixel/8); |
930 | } | 1128 | } |
@@ -970,7 +1168,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
970 | * It doesn't set the bit in iir again, but it still produces | 1168 | * It doesn't set the bit in iir again, but it still produces |
971 | * interrupts (for non-MSI). | 1169 | * interrupts (for non-MSI). |
972 | */ | 1170 | */ |
973 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 1171 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
974 | pipea_stats = I915_READ(PIPEASTAT); | 1172 | pipea_stats = I915_READ(PIPEASTAT); |
975 | pipeb_stats = I915_READ(PIPEBSTAT); | 1173 | pipeb_stats = I915_READ(PIPEBSTAT); |
976 | 1174 | ||
@@ -993,7 +1191,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
993 | I915_WRITE(PIPEBSTAT, pipeb_stats); | 1191 | I915_WRITE(PIPEBSTAT, pipeb_stats); |
994 | irq_received = 1; | 1192 | irq_received = 1; |
995 | } | 1193 | } |
996 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | 1194 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
997 | 1195 | ||
998 | if (!irq_received) | 1196 | if (!irq_received) |
999 | break; | 1197 | break; |
@@ -1026,9 +1224,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
1026 | } | 1224 | } |
1027 | 1225 | ||
1028 | if (iir & I915_USER_INTERRUPT) | 1226 | if (iir & I915_USER_INTERRUPT) |
1029 | notify_ring(dev, &dev_priv->render_ring); | 1227 | notify_ring(dev, &dev_priv->ring[RCS]); |
1030 | if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT)) | 1228 | if (iir & I915_BSD_USER_INTERRUPT) |
1031 | notify_ring(dev, &dev_priv->bsd_ring); | 1229 | notify_ring(dev, &dev_priv->ring[VCS]); |
1032 | 1230 | ||
1033 | if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) { | 1231 | if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) { |
1034 | intel_prepare_page_flip(dev, 0); | 1232 | intel_prepare_page_flip(dev, 0); |
@@ -1101,12 +1299,13 @@ static int i915_emit_irq(struct drm_device * dev) | |||
1101 | if (master_priv->sarea_priv) | 1299 | if (master_priv->sarea_priv) |
1102 | master_priv->sarea_priv->last_enqueue = dev_priv->counter; | 1300 | master_priv->sarea_priv->last_enqueue = dev_priv->counter; |
1103 | 1301 | ||
1104 | BEGIN_LP_RING(4); | 1302 | if (BEGIN_LP_RING(4) == 0) { |
1105 | OUT_RING(MI_STORE_DWORD_INDEX); | 1303 | OUT_RING(MI_STORE_DWORD_INDEX); |
1106 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | 1304 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
1107 | OUT_RING(dev_priv->counter); | 1305 | OUT_RING(dev_priv->counter); |
1108 | OUT_RING(MI_USER_INTERRUPT); | 1306 | OUT_RING(MI_USER_INTERRUPT); |
1109 | ADVANCE_LP_RING(); | 1307 | ADVANCE_LP_RING(); |
1308 | } | ||
1110 | 1309 | ||
1111 | return dev_priv->counter; | 1310 | return dev_priv->counter; |
1112 | } | 1311 | } |
@@ -1114,12 +1313,11 @@ static int i915_emit_irq(struct drm_device * dev) | |||
1114 | void i915_trace_irq_get(struct drm_device *dev, u32 seqno) | 1313 | void i915_trace_irq_get(struct drm_device *dev, u32 seqno) |
1115 | { | 1314 | { |
1116 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1315 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1117 | struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | 1316 | struct intel_ring_buffer *ring = LP_RING(dev_priv); |
1118 | 1317 | ||
1119 | if (dev_priv->trace_irq_seqno == 0) | 1318 | if (dev_priv->trace_irq_seqno == 0 && |
1120 | render_ring->user_irq_get(dev, render_ring); | 1319 | ring->irq_get(ring)) |
1121 | 1320 | dev_priv->trace_irq_seqno = seqno; | |
1122 | dev_priv->trace_irq_seqno = seqno; | ||
1123 | } | 1321 | } |
1124 | 1322 | ||
1125 | static int i915_wait_irq(struct drm_device * dev, int irq_nr) | 1323 | static int i915_wait_irq(struct drm_device * dev, int irq_nr) |
@@ -1127,7 +1325,7 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) | |||
1127 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1325 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1128 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | 1326 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; |
1129 | int ret = 0; | 1327 | int ret = 0; |
1130 | struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | 1328 | struct intel_ring_buffer *ring = LP_RING(dev_priv); |
1131 | 1329 | ||
1132 | DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr, | 1330 | DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr, |
1133 | READ_BREADCRUMB(dev_priv)); | 1331 | READ_BREADCRUMB(dev_priv)); |
@@ -1141,10 +1339,12 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) | |||
1141 | if (master_priv->sarea_priv) | 1339 | if (master_priv->sarea_priv) |
1142 | master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; | 1340 | master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; |
1143 | 1341 | ||
1144 | render_ring->user_irq_get(dev, render_ring); | 1342 | ret = -ENODEV; |
1145 | DRM_WAIT_ON(ret, dev_priv->render_ring.irq_queue, 3 * DRM_HZ, | 1343 | if (ring->irq_get(ring)) { |
1146 | READ_BREADCRUMB(dev_priv) >= irq_nr); | 1344 | DRM_WAIT_ON(ret, ring->irq_queue, 3 * DRM_HZ, |
1147 | render_ring->user_irq_put(dev, render_ring); | 1345 | READ_BREADCRUMB(dev_priv) >= irq_nr); |
1346 | ring->irq_put(ring); | ||
1347 | } | ||
1148 | 1348 | ||
1149 | if (ret == -EBUSY) { | 1349 | if (ret == -EBUSY) { |
1150 | DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", | 1350 | DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", |
@@ -1163,7 +1363,7 @@ int i915_irq_emit(struct drm_device *dev, void *data, | |||
1163 | drm_i915_irq_emit_t *emit = data; | 1363 | drm_i915_irq_emit_t *emit = data; |
1164 | int result; | 1364 | int result; |
1165 | 1365 | ||
1166 | if (!dev_priv || !dev_priv->render_ring.virtual_start) { | 1366 | if (!dev_priv || !LP_RING(dev_priv)->virtual_start) { |
1167 | DRM_ERROR("called with no initialization\n"); | 1367 | DRM_ERROR("called with no initialization\n"); |
1168 | return -EINVAL; | 1368 | return -EINVAL; |
1169 | } | 1369 | } |
@@ -1209,9 +1409,9 @@ int i915_enable_vblank(struct drm_device *dev, int pipe) | |||
1209 | if (!i915_pipe_enabled(dev, pipe)) | 1409 | if (!i915_pipe_enabled(dev, pipe)) |
1210 | return -EINVAL; | 1410 | return -EINVAL; |
1211 | 1411 | ||
1212 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 1412 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
1213 | if (HAS_PCH_SPLIT(dev)) | 1413 | if (HAS_PCH_SPLIT(dev)) |
1214 | ironlake_enable_display_irq(dev_priv, (pipe == 0) ? | 1414 | ironlake_enable_display_irq(dev_priv, (pipe == 0) ? |
1215 | DE_PIPEA_VBLANK: DE_PIPEB_VBLANK); | 1415 | DE_PIPEA_VBLANK: DE_PIPEB_VBLANK); |
1216 | else if (INTEL_INFO(dev)->gen >= 4) | 1416 | else if (INTEL_INFO(dev)->gen >= 4) |
1217 | i915_enable_pipestat(dev_priv, pipe, | 1417 | i915_enable_pipestat(dev_priv, pipe, |
@@ -1219,7 +1419,7 @@ int i915_enable_vblank(struct drm_device *dev, int pipe) | |||
1219 | else | 1419 | else |
1220 | i915_enable_pipestat(dev_priv, pipe, | 1420 | i915_enable_pipestat(dev_priv, pipe, |
1221 | PIPE_VBLANK_INTERRUPT_ENABLE); | 1421 | PIPE_VBLANK_INTERRUPT_ENABLE); |
1222 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | 1422 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
1223 | return 0; | 1423 | return 0; |
1224 | } | 1424 | } |
1225 | 1425 | ||
@@ -1231,15 +1431,15 @@ void i915_disable_vblank(struct drm_device *dev, int pipe) | |||
1231 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1431 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1232 | unsigned long irqflags; | 1432 | unsigned long irqflags; |
1233 | 1433 | ||
1234 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 1434 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
1235 | if (HAS_PCH_SPLIT(dev)) | 1435 | if (HAS_PCH_SPLIT(dev)) |
1236 | ironlake_disable_display_irq(dev_priv, (pipe == 0) ? | 1436 | ironlake_disable_display_irq(dev_priv, (pipe == 0) ? |
1237 | DE_PIPEA_VBLANK: DE_PIPEB_VBLANK); | 1437 | DE_PIPEA_VBLANK: DE_PIPEB_VBLANK); |
1238 | else | 1438 | else |
1239 | i915_disable_pipestat(dev_priv, pipe, | 1439 | i915_disable_pipestat(dev_priv, pipe, |
1240 | PIPE_VBLANK_INTERRUPT_ENABLE | | 1440 | PIPE_VBLANK_INTERRUPT_ENABLE | |
1241 | PIPE_START_VBLANK_INTERRUPT_ENABLE); | 1441 | PIPE_START_VBLANK_INTERRUPT_ENABLE); |
1242 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | 1442 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
1243 | } | 1443 | } |
1244 | 1444 | ||
1245 | void i915_enable_interrupt (struct drm_device *dev) | 1445 | void i915_enable_interrupt (struct drm_device *dev) |
@@ -1306,12 +1506,50 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
1306 | return -EINVAL; | 1506 | return -EINVAL; |
1307 | } | 1507 | } |
1308 | 1508 | ||
1309 | static struct drm_i915_gem_request * | 1509 | static u32 |
1310 | i915_get_tail_request(struct drm_device *dev) | 1510 | ring_last_seqno(struct intel_ring_buffer *ring) |
1311 | { | 1511 | { |
1312 | drm_i915_private_t *dev_priv = dev->dev_private; | 1512 | return list_entry(ring->request_list.prev, |
1313 | return list_entry(dev_priv->render_ring.request_list.prev, | 1513 | struct drm_i915_gem_request, list)->seqno; |
1314 | struct drm_i915_gem_request, list); | 1514 | } |
1515 | |||
1516 | static bool i915_hangcheck_ring_idle(struct intel_ring_buffer *ring, bool *err) | ||
1517 | { | ||
1518 | if (list_empty(&ring->request_list) || | ||
1519 | i915_seqno_passed(ring->get_seqno(ring), ring_last_seqno(ring))) { | ||
1520 | /* Issue a wake-up to catch stuck h/w. */ | ||
1521 | if (ring->waiting_seqno && waitqueue_active(&ring->irq_queue)) { | ||
1522 | DRM_ERROR("Hangcheck timer elapsed... %s idle [waiting on %d, at %d], missed IRQ?\n", | ||
1523 | ring->name, | ||
1524 | ring->waiting_seqno, | ||
1525 | ring->get_seqno(ring)); | ||
1526 | wake_up_all(&ring->irq_queue); | ||
1527 | *err = true; | ||
1528 | } | ||
1529 | return true; | ||
1530 | } | ||
1531 | return false; | ||
1532 | } | ||
1533 | |||
1534 | static bool kick_ring(struct intel_ring_buffer *ring) | ||
1535 | { | ||
1536 | struct drm_device *dev = ring->dev; | ||
1537 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1538 | u32 tmp = I915_READ_CTL(ring); | ||
1539 | if (tmp & RING_WAIT) { | ||
1540 | DRM_ERROR("Kicking stuck wait on %s\n", | ||
1541 | ring->name); | ||
1542 | I915_WRITE_CTL(ring, tmp); | ||
1543 | return true; | ||
1544 | } | ||
1545 | if (IS_GEN6(dev) && | ||
1546 | (tmp & RING_WAIT_SEMAPHORE)) { | ||
1547 | DRM_ERROR("Kicking stuck semaphore on %s\n", | ||
1548 | ring->name); | ||
1549 | I915_WRITE_CTL(ring, tmp); | ||
1550 | return true; | ||
1551 | } | ||
1552 | return false; | ||
1315 | } | 1553 | } |
1316 | 1554 | ||
1317 | /** | 1555 | /** |
@@ -1325,6 +1563,17 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1325 | struct drm_device *dev = (struct drm_device *)data; | 1563 | struct drm_device *dev = (struct drm_device *)data; |
1326 | drm_i915_private_t *dev_priv = dev->dev_private; | 1564 | drm_i915_private_t *dev_priv = dev->dev_private; |
1327 | uint32_t acthd, instdone, instdone1; | 1565 | uint32_t acthd, instdone, instdone1; |
1566 | bool err = false; | ||
1567 | |||
1568 | /* If all work is done then ACTHD clearly hasn't advanced. */ | ||
1569 | if (i915_hangcheck_ring_idle(&dev_priv->ring[RCS], &err) && | ||
1570 | i915_hangcheck_ring_idle(&dev_priv->ring[VCS], &err) && | ||
1571 | i915_hangcheck_ring_idle(&dev_priv->ring[BCS], &err)) { | ||
1572 | dev_priv->hangcheck_count = 0; | ||
1573 | if (err) | ||
1574 | goto repeat; | ||
1575 | return; | ||
1576 | } | ||
1328 | 1577 | ||
1329 | if (INTEL_INFO(dev)->gen < 4) { | 1578 | if (INTEL_INFO(dev)->gen < 4) { |
1330 | acthd = I915_READ(ACTHD); | 1579 | acthd = I915_READ(ACTHD); |
@@ -1336,38 +1585,6 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1336 | instdone1 = I915_READ(INSTDONE1); | 1585 | instdone1 = I915_READ(INSTDONE1); |
1337 | } | 1586 | } |
1338 | 1587 | ||
1339 | /* If all work is done then ACTHD clearly hasn't advanced. */ | ||
1340 | if (list_empty(&dev_priv->render_ring.request_list) || | ||
1341 | i915_seqno_passed(dev_priv->render_ring.get_seqno(dev, &dev_priv->render_ring), | ||
1342 | i915_get_tail_request(dev)->seqno)) { | ||
1343 | bool missed_wakeup = false; | ||
1344 | |||
1345 | dev_priv->hangcheck_count = 0; | ||
1346 | |||
1347 | /* Issue a wake-up to catch stuck h/w. */ | ||
1348 | if (dev_priv->render_ring.waiting_gem_seqno && | ||
1349 | waitqueue_active(&dev_priv->render_ring.irq_queue)) { | ||
1350 | wake_up_all(&dev_priv->render_ring.irq_queue); | ||
1351 | missed_wakeup = true; | ||
1352 | } | ||
1353 | |||
1354 | if (dev_priv->bsd_ring.waiting_gem_seqno && | ||
1355 | waitqueue_active(&dev_priv->bsd_ring.irq_queue)) { | ||
1356 | wake_up_all(&dev_priv->bsd_ring.irq_queue); | ||
1357 | missed_wakeup = true; | ||
1358 | } | ||
1359 | |||
1360 | if (dev_priv->blt_ring.waiting_gem_seqno && | ||
1361 | waitqueue_active(&dev_priv->blt_ring.irq_queue)) { | ||
1362 | wake_up_all(&dev_priv->blt_ring.irq_queue); | ||
1363 | missed_wakeup = true; | ||
1364 | } | ||
1365 | |||
1366 | if (missed_wakeup) | ||
1367 | DRM_ERROR("Hangcheck timer elapsed... GPU idle, missed IRQ.\n"); | ||
1368 | return; | ||
1369 | } | ||
1370 | |||
1371 | if (dev_priv->last_acthd == acthd && | 1588 | if (dev_priv->last_acthd == acthd && |
1372 | dev_priv->last_instdone == instdone && | 1589 | dev_priv->last_instdone == instdone && |
1373 | dev_priv->last_instdone1 == instdone1) { | 1590 | dev_priv->last_instdone1 == instdone1) { |
@@ -1380,12 +1597,17 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1380 | * and break the hang. This should work on | 1597 | * and break the hang. This should work on |
1381 | * all but the second generation chipsets. | 1598 | * all but the second generation chipsets. |
1382 | */ | 1599 | */ |
1383 | u32 tmp = I915_READ(PRB0_CTL); | 1600 | |
1384 | if (tmp & RING_WAIT) { | 1601 | if (kick_ring(&dev_priv->ring[RCS])) |
1385 | I915_WRITE(PRB0_CTL, tmp); | 1602 | goto repeat; |
1386 | POSTING_READ(PRB0_CTL); | 1603 | |
1387 | goto out; | 1604 | if (HAS_BSD(dev) && |
1388 | } | 1605 | kick_ring(&dev_priv->ring[VCS])) |
1606 | goto repeat; | ||
1607 | |||
1608 | if (HAS_BLT(dev) && | ||
1609 | kick_ring(&dev_priv->ring[BCS])) | ||
1610 | goto repeat; | ||
1389 | } | 1611 | } |
1390 | 1612 | ||
1391 | i915_handle_error(dev, true); | 1613 | i915_handle_error(dev, true); |
@@ -1399,7 +1621,7 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1399 | dev_priv->last_instdone1 = instdone1; | 1621 | dev_priv->last_instdone1 = instdone1; |
1400 | } | 1622 | } |
1401 | 1623 | ||
1402 | out: | 1624 | repeat: |
1403 | /* Reset timer case chip hangs without another request being added */ | 1625 | /* Reset timer case chip hangs without another request being added */ |
1404 | mod_timer(&dev_priv->hangcheck_timer, | 1626 | mod_timer(&dev_priv->hangcheck_timer, |
1405 | jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); | 1627 | jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); |
@@ -1417,17 +1639,17 @@ static void ironlake_irq_preinstall(struct drm_device *dev) | |||
1417 | 1639 | ||
1418 | I915_WRITE(DEIMR, 0xffffffff); | 1640 | I915_WRITE(DEIMR, 0xffffffff); |
1419 | I915_WRITE(DEIER, 0x0); | 1641 | I915_WRITE(DEIER, 0x0); |
1420 | (void) I915_READ(DEIER); | 1642 | POSTING_READ(DEIER); |
1421 | 1643 | ||
1422 | /* and GT */ | 1644 | /* and GT */ |
1423 | I915_WRITE(GTIMR, 0xffffffff); | 1645 | I915_WRITE(GTIMR, 0xffffffff); |
1424 | I915_WRITE(GTIER, 0x0); | 1646 | I915_WRITE(GTIER, 0x0); |
1425 | (void) I915_READ(GTIER); | 1647 | POSTING_READ(GTIER); |
1426 | 1648 | ||
1427 | /* south display irq */ | 1649 | /* south display irq */ |
1428 | I915_WRITE(SDEIMR, 0xffffffff); | 1650 | I915_WRITE(SDEIMR, 0xffffffff); |
1429 | I915_WRITE(SDEIER, 0x0); | 1651 | I915_WRITE(SDEIER, 0x0); |
1430 | (void) I915_READ(SDEIER); | 1652 | POSTING_READ(SDEIER); |
1431 | } | 1653 | } |
1432 | 1654 | ||
1433 | static int ironlake_irq_postinstall(struct drm_device *dev) | 1655 | static int ironlake_irq_postinstall(struct drm_device *dev) |
@@ -1436,38 +1658,39 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
1436 | /* enable kind of interrupts always enabled */ | 1658 | /* enable kind of interrupts always enabled */ |
1437 | u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | | 1659 | u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | |
1438 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; | 1660 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; |
1439 | u32 render_mask = GT_PIPE_NOTIFY | GT_BSD_USER_INTERRUPT; | 1661 | u32 render_irqs; |
1440 | u32 hotplug_mask; | 1662 | u32 hotplug_mask; |
1441 | 1663 | ||
1442 | dev_priv->irq_mask_reg = ~display_mask; | 1664 | dev_priv->irq_mask = ~display_mask; |
1443 | dev_priv->de_irq_enable_reg = display_mask | DE_PIPEA_VBLANK | DE_PIPEB_VBLANK; | ||
1444 | 1665 | ||
1445 | /* should always can generate irq */ | 1666 | /* should always can generate irq */ |
1446 | I915_WRITE(DEIIR, I915_READ(DEIIR)); | 1667 | I915_WRITE(DEIIR, I915_READ(DEIIR)); |
1447 | I915_WRITE(DEIMR, dev_priv->irq_mask_reg); | 1668 | I915_WRITE(DEIMR, dev_priv->irq_mask); |
1448 | I915_WRITE(DEIER, dev_priv->de_irq_enable_reg); | 1669 | I915_WRITE(DEIER, display_mask | DE_PIPEA_VBLANK | DE_PIPEB_VBLANK); |
1449 | (void) I915_READ(DEIER); | 1670 | POSTING_READ(DEIER); |
1450 | 1671 | ||
1451 | if (IS_GEN6(dev)) { | 1672 | dev_priv->gt_irq_mask = ~0; |
1452 | render_mask = | ||
1453 | GT_PIPE_NOTIFY | | ||
1454 | GT_GEN6_BSD_USER_INTERRUPT | | ||
1455 | GT_BLT_USER_INTERRUPT; | ||
1456 | } | ||
1457 | |||
1458 | dev_priv->gt_irq_mask_reg = ~render_mask; | ||
1459 | dev_priv->gt_irq_enable_reg = render_mask; | ||
1460 | 1673 | ||
1461 | I915_WRITE(GTIIR, I915_READ(GTIIR)); | 1674 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
1462 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); | 1675 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
1463 | if (IS_GEN6(dev)) { | 1676 | if (IS_GEN6(dev)) { |
1464 | I915_WRITE(GEN6_RENDER_IMR, ~GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT); | 1677 | I915_WRITE(GEN6_RENDER_IMR, ~GEN6_RENDER_USER_INTERRUPT); |
1465 | I915_WRITE(GEN6_BSD_IMR, ~GEN6_BSD_IMR_USER_INTERRUPT); | 1678 | I915_WRITE(GEN6_BSD_IMR, ~GEN6_BSD_USER_INTERRUPT); |
1466 | I915_WRITE(GEN6_BLITTER_IMR, ~GEN6_BLITTER_USER_INTERRUPT); | 1679 | I915_WRITE(GEN6_BLITTER_IMR, ~GEN6_BLITTER_USER_INTERRUPT); |
1467 | } | 1680 | } |
1468 | 1681 | ||
1469 | I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); | 1682 | if (IS_GEN6(dev)) |
1470 | (void) I915_READ(GTIER); | 1683 | render_irqs = |
1684 | GT_USER_INTERRUPT | | ||
1685 | GT_GEN6_BSD_USER_INTERRUPT | | ||
1686 | GT_BLT_USER_INTERRUPT; | ||
1687 | else | ||
1688 | render_irqs = | ||
1689 | GT_USER_INTERRUPT | | ||
1690 | GT_PIPE_NOTIFY | | ||
1691 | GT_BSD_USER_INTERRUPT; | ||
1692 | I915_WRITE(GTIER, render_irqs); | ||
1693 | POSTING_READ(GTIER); | ||
1471 | 1694 | ||
1472 | if (HAS_PCH_CPT(dev)) { | 1695 | if (HAS_PCH_CPT(dev)) { |
1473 | hotplug_mask = SDE_CRT_HOTPLUG_CPT | SDE_PORTB_HOTPLUG_CPT | | 1696 | hotplug_mask = SDE_CRT_HOTPLUG_CPT | SDE_PORTB_HOTPLUG_CPT | |
@@ -1477,13 +1700,12 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
1477 | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; | 1700 | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; |
1478 | } | 1701 | } |
1479 | 1702 | ||
1480 | dev_priv->pch_irq_mask_reg = ~hotplug_mask; | 1703 | dev_priv->pch_irq_mask = ~hotplug_mask; |
1481 | dev_priv->pch_irq_enable_reg = hotplug_mask; | ||
1482 | 1704 | ||
1483 | I915_WRITE(SDEIIR, I915_READ(SDEIIR)); | 1705 | I915_WRITE(SDEIIR, I915_READ(SDEIIR)); |
1484 | I915_WRITE(SDEIMR, dev_priv->pch_irq_mask_reg); | 1706 | I915_WRITE(SDEIMR, dev_priv->pch_irq_mask); |
1485 | I915_WRITE(SDEIER, dev_priv->pch_irq_enable_reg); | 1707 | I915_WRITE(SDEIER, hotplug_mask); |
1486 | (void) I915_READ(SDEIER); | 1708 | POSTING_READ(SDEIER); |
1487 | 1709 | ||
1488 | if (IS_IRONLAKE_M(dev)) { | 1710 | if (IS_IRONLAKE_M(dev)) { |
1489 | /* Clear & enable PCU event interrupts */ | 1711 | /* Clear & enable PCU event interrupts */ |
@@ -1519,7 +1741,7 @@ void i915_driver_irq_preinstall(struct drm_device * dev) | |||
1519 | I915_WRITE(PIPEBSTAT, 0); | 1741 | I915_WRITE(PIPEBSTAT, 0); |
1520 | I915_WRITE(IMR, 0xffffffff); | 1742 | I915_WRITE(IMR, 0xffffffff); |
1521 | I915_WRITE(IER, 0x0); | 1743 | I915_WRITE(IER, 0x0); |
1522 | (void) I915_READ(IER); | 1744 | POSTING_READ(IER); |
1523 | } | 1745 | } |
1524 | 1746 | ||
1525 | /* | 1747 | /* |
@@ -1532,11 +1754,11 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
1532 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; | 1754 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; |
1533 | u32 error_mask; | 1755 | u32 error_mask; |
1534 | 1756 | ||
1535 | DRM_INIT_WAITQUEUE(&dev_priv->render_ring.irq_queue); | 1757 | DRM_INIT_WAITQUEUE(&dev_priv->ring[RCS].irq_queue); |
1536 | if (HAS_BSD(dev)) | 1758 | if (HAS_BSD(dev)) |
1537 | DRM_INIT_WAITQUEUE(&dev_priv->bsd_ring.irq_queue); | 1759 | DRM_INIT_WAITQUEUE(&dev_priv->ring[VCS].irq_queue); |
1538 | if (HAS_BLT(dev)) | 1760 | if (HAS_BLT(dev)) |
1539 | DRM_INIT_WAITQUEUE(&dev_priv->blt_ring.irq_queue); | 1761 | DRM_INIT_WAITQUEUE(&dev_priv->ring[BCS].irq_queue); |
1540 | 1762 | ||
1541 | dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; | 1763 | dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; |
1542 | 1764 | ||
@@ -1544,7 +1766,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
1544 | return ironlake_irq_postinstall(dev); | 1766 | return ironlake_irq_postinstall(dev); |
1545 | 1767 | ||
1546 | /* Unmask the interrupts that we always want on. */ | 1768 | /* Unmask the interrupts that we always want on. */ |
1547 | dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX; | 1769 | dev_priv->irq_mask = ~I915_INTERRUPT_ENABLE_FIX; |
1548 | 1770 | ||
1549 | dev_priv->pipestat[0] = 0; | 1771 | dev_priv->pipestat[0] = 0; |
1550 | dev_priv->pipestat[1] = 0; | 1772 | dev_priv->pipestat[1] = 0; |
@@ -1553,7 +1775,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
1553 | /* Enable in IER... */ | 1775 | /* Enable in IER... */ |
1554 | enable_mask |= I915_DISPLAY_PORT_INTERRUPT; | 1776 | enable_mask |= I915_DISPLAY_PORT_INTERRUPT; |
1555 | /* and unmask in IMR */ | 1777 | /* and unmask in IMR */ |
1556 | dev_priv->irq_mask_reg &= ~I915_DISPLAY_PORT_INTERRUPT; | 1778 | dev_priv->irq_mask &= ~I915_DISPLAY_PORT_INTERRUPT; |
1557 | } | 1779 | } |
1558 | 1780 | ||
1559 | /* | 1781 | /* |
@@ -1571,9 +1793,9 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
1571 | } | 1793 | } |
1572 | I915_WRITE(EMR, error_mask); | 1794 | I915_WRITE(EMR, error_mask); |
1573 | 1795 | ||
1574 | I915_WRITE(IMR, dev_priv->irq_mask_reg); | 1796 | I915_WRITE(IMR, dev_priv->irq_mask); |
1575 | I915_WRITE(IER, enable_mask); | 1797 | I915_WRITE(IER, enable_mask); |
1576 | (void) I915_READ(IER); | 1798 | POSTING_READ(IER); |
1577 | 1799 | ||
1578 | if (I915_HAS_HOTPLUG(dev)) { | 1800 | if (I915_HAS_HOTPLUG(dev)) { |
1579 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); | 1801 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 25ed911a311..d60860ec8cf 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -78,6 +78,12 @@ | |||
78 | #define GRDOM_RENDER (1<<2) | 78 | #define GRDOM_RENDER (1<<2) |
79 | #define GRDOM_MEDIA (3<<2) | 79 | #define GRDOM_MEDIA (3<<2) |
80 | 80 | ||
81 | #define GEN6_GDRST 0x941c | ||
82 | #define GEN6_GRDOM_FULL (1 << 0) | ||
83 | #define GEN6_GRDOM_RENDER (1 << 1) | ||
84 | #define GEN6_GRDOM_MEDIA (1 << 2) | ||
85 | #define GEN6_GRDOM_BLT (1 << 3) | ||
86 | |||
81 | /* VGA stuff */ | 87 | /* VGA stuff */ |
82 | 88 | ||
83 | #define VGA_ST01_MDA 0x3ba | 89 | #define VGA_ST01_MDA 0x3ba |
@@ -158,12 +164,23 @@ | |||
158 | #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ | 164 | #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ |
159 | #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) | 165 | #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) |
160 | #define MI_STORE_DWORD_INDEX_SHIFT 2 | 166 | #define MI_STORE_DWORD_INDEX_SHIFT 2 |
161 | #define MI_LOAD_REGISTER_IMM MI_INSTR(0x22, 1) | 167 | /* Official intel docs are somewhat sloppy concerning MI_LOAD_REGISTER_IMM: |
168 | * - Always issue a MI_NOOP _before_ the MI_LOAD_REGISTER_IMM - otherwise hw | ||
169 | * simply ignores the register load under certain conditions. | ||
170 | * - One can actually load arbitrary many arbitrary registers: Simply issue x | ||
171 | * address/value pairs. Don't overdue it, though, x <= 2^4 must hold! | ||
172 | */ | ||
173 | #define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*x-1) | ||
162 | #define MI_FLUSH_DW MI_INSTR(0x26, 2) /* for GEN6 */ | 174 | #define MI_FLUSH_DW MI_INSTR(0x26, 2) /* for GEN6 */ |
163 | #define MI_BATCH_BUFFER MI_INSTR(0x30, 1) | 175 | #define MI_BATCH_BUFFER MI_INSTR(0x30, 1) |
164 | #define MI_BATCH_NON_SECURE (1) | 176 | #define MI_BATCH_NON_SECURE (1) |
165 | #define MI_BATCH_NON_SECURE_I965 (1<<8) | 177 | #define MI_BATCH_NON_SECURE_I965 (1<<8) |
166 | #define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0) | 178 | #define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0) |
179 | #define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6+ */ | ||
180 | #define MI_SEMAPHORE_GLOBAL_GTT (1<<22) | ||
181 | #define MI_SEMAPHORE_UPDATE (1<<21) | ||
182 | #define MI_SEMAPHORE_COMPARE (1<<20) | ||
183 | #define MI_SEMAPHORE_REGISTER (1<<18) | ||
167 | /* | 184 | /* |
168 | * 3D instructions used by the kernel | 185 | * 3D instructions used by the kernel |
169 | */ | 186 | */ |
@@ -256,10 +273,6 @@ | |||
256 | * Instruction and interrupt control regs | 273 | * Instruction and interrupt control regs |
257 | */ | 274 | */ |
258 | #define PGTBL_ER 0x02024 | 275 | #define PGTBL_ER 0x02024 |
259 | #define PRB0_TAIL 0x02030 | ||
260 | #define PRB0_HEAD 0x02034 | ||
261 | #define PRB0_START 0x02038 | ||
262 | #define PRB0_CTL 0x0203c | ||
263 | #define RENDER_RING_BASE 0x02000 | 276 | #define RENDER_RING_BASE 0x02000 |
264 | #define BSD_RING_BASE 0x04000 | 277 | #define BSD_RING_BASE 0x04000 |
265 | #define GEN6_BSD_RING_BASE 0x12000 | 278 | #define GEN6_BSD_RING_BASE 0x12000 |
@@ -268,9 +281,13 @@ | |||
268 | #define RING_HEAD(base) ((base)+0x34) | 281 | #define RING_HEAD(base) ((base)+0x34) |
269 | #define RING_START(base) ((base)+0x38) | 282 | #define RING_START(base) ((base)+0x38) |
270 | #define RING_CTL(base) ((base)+0x3c) | 283 | #define RING_CTL(base) ((base)+0x3c) |
284 | #define RING_SYNC_0(base) ((base)+0x40) | ||
285 | #define RING_SYNC_1(base) ((base)+0x44) | ||
286 | #define RING_MAX_IDLE(base) ((base)+0x54) | ||
271 | #define RING_HWS_PGA(base) ((base)+0x80) | 287 | #define RING_HWS_PGA(base) ((base)+0x80) |
272 | #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) | 288 | #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) |
273 | #define RING_ACTHD(base) ((base)+0x74) | 289 | #define RING_ACTHD(base) ((base)+0x74) |
290 | #define RING_NOPID(base) ((base)+0x94) | ||
274 | #define TAIL_ADDR 0x001FFFF8 | 291 | #define TAIL_ADDR 0x001FFFF8 |
275 | #define HEAD_WRAP_COUNT 0xFFE00000 | 292 | #define HEAD_WRAP_COUNT 0xFFE00000 |
276 | #define HEAD_WRAP_ONE 0x00200000 | 293 | #define HEAD_WRAP_ONE 0x00200000 |
@@ -285,10 +302,17 @@ | |||
285 | #define RING_INVALID 0x00000000 | 302 | #define RING_INVALID 0x00000000 |
286 | #define RING_WAIT_I8XX (1<<0) /* gen2, PRBx_HEAD */ | 303 | #define RING_WAIT_I8XX (1<<0) /* gen2, PRBx_HEAD */ |
287 | #define RING_WAIT (1<<11) /* gen3+, PRBx_CTL */ | 304 | #define RING_WAIT (1<<11) /* gen3+, PRBx_CTL */ |
305 | #define RING_WAIT_SEMAPHORE (1<<10) /* gen6+ */ | ||
306 | #if 0 | ||
307 | #define PRB0_TAIL 0x02030 | ||
308 | #define PRB0_HEAD 0x02034 | ||
309 | #define PRB0_START 0x02038 | ||
310 | #define PRB0_CTL 0x0203c | ||
288 | #define PRB1_TAIL 0x02040 /* 915+ only */ | 311 | #define PRB1_TAIL 0x02040 /* 915+ only */ |
289 | #define PRB1_HEAD 0x02044 /* 915+ only */ | 312 | #define PRB1_HEAD 0x02044 /* 915+ only */ |
290 | #define PRB1_START 0x02048 /* 915+ only */ | 313 | #define PRB1_START 0x02048 /* 915+ only */ |
291 | #define PRB1_CTL 0x0204c /* 915+ only */ | 314 | #define PRB1_CTL 0x0204c /* 915+ only */ |
315 | #endif | ||
292 | #define IPEIR_I965 0x02064 | 316 | #define IPEIR_I965 0x02064 |
293 | #define IPEHR_I965 0x02068 | 317 | #define IPEHR_I965 0x02068 |
294 | #define INSTDONE_I965 0x0206c | 318 | #define INSTDONE_I965 0x0206c |
@@ -305,11 +329,42 @@ | |||
305 | #define INSTDONE 0x02090 | 329 | #define INSTDONE 0x02090 |
306 | #define NOPID 0x02094 | 330 | #define NOPID 0x02094 |
307 | #define HWSTAM 0x02098 | 331 | #define HWSTAM 0x02098 |
332 | #define VCS_INSTDONE 0x1206C | ||
333 | #define VCS_IPEIR 0x12064 | ||
334 | #define VCS_IPEHR 0x12068 | ||
335 | #define VCS_ACTHD 0x12074 | ||
336 | #define BCS_INSTDONE 0x2206C | ||
337 | #define BCS_IPEIR 0x22064 | ||
338 | #define BCS_IPEHR 0x22068 | ||
339 | #define BCS_ACTHD 0x22074 | ||
340 | |||
341 | #define ERROR_GEN6 0x040a0 | ||
342 | |||
343 | /* GM45+ chicken bits -- debug workaround bits that may be required | ||
344 | * for various sorts of correct behavior. The top 16 bits of each are | ||
345 | * the enables for writing to the corresponding low bit. | ||
346 | */ | ||
347 | #define _3D_CHICKEN 0x02084 | ||
348 | #define _3D_CHICKEN2 0x0208c | ||
349 | /* Disables pipelining of read flushes past the SF-WIZ interface. | ||
350 | * Required on all Ironlake steppings according to the B-Spec, but the | ||
351 | * particular danger of not doing so is not specified. | ||
352 | */ | ||
353 | # define _3D_CHICKEN2_WM_READ_PIPELINED (1 << 14) | ||
354 | #define _3D_CHICKEN3 0x02090 | ||
308 | 355 | ||
309 | #define MI_MODE 0x0209c | 356 | #define MI_MODE 0x0209c |
310 | # define VS_TIMER_DISPATCH (1 << 6) | 357 | # define VS_TIMER_DISPATCH (1 << 6) |
311 | # define MI_FLUSH_ENABLE (1 << 11) | 358 | # define MI_FLUSH_ENABLE (1 << 11) |
312 | 359 | ||
360 | #define GFX_MODE 0x02520 | ||
361 | #define GFX_RUN_LIST_ENABLE (1<<15) | ||
362 | #define GFX_TLB_INVALIDATE_ALWAYS (1<<13) | ||
363 | #define GFX_SURFACE_FAULT_ENABLE (1<<12) | ||
364 | #define GFX_REPLAY_MODE (1<<11) | ||
365 | #define GFX_PSMI_GRANULARITY (1<<10) | ||
366 | #define GFX_PPGTT_ENABLE (1<<9) | ||
367 | |||
313 | #define SCPD0 0x0209c /* 915+ only */ | 368 | #define SCPD0 0x0209c /* 915+ only */ |
314 | #define IER 0x020a0 | 369 | #define IER 0x020a0 |
315 | #define IIR 0x020a4 | 370 | #define IIR 0x020a4 |
@@ -461,7 +516,7 @@ | |||
461 | #define GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR (1 << 3) | 516 | #define GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR (1 << 3) |
462 | 517 | ||
463 | #define GEN6_BSD_IMR 0x120a8 | 518 | #define GEN6_BSD_IMR 0x120a8 |
464 | #define GEN6_BSD_IMR_USER_INTERRUPT (1 << 12) | 519 | #define GEN6_BSD_USER_INTERRUPT (1 << 12) |
465 | 520 | ||
466 | #define GEN6_BSD_RNCID 0x12198 | 521 | #define GEN6_BSD_RNCID 0x12198 |
467 | 522 | ||
@@ -541,6 +596,18 @@ | |||
541 | 596 | ||
542 | #define ILK_DISPLAY_CHICKEN1 0x42000 | 597 | #define ILK_DISPLAY_CHICKEN1 0x42000 |
543 | #define ILK_FBCQ_DIS (1<<22) | 598 | #define ILK_FBCQ_DIS (1<<22) |
599 | #define ILK_PABSTRETCH_DIS (1<<21) | ||
600 | |||
601 | |||
602 | /* | ||
603 | * Framebuffer compression for Sandybridge | ||
604 | * | ||
605 | * The following two registers are of type GTTMMADR | ||
606 | */ | ||
607 | #define SNB_DPFC_CTL_SA 0x100100 | ||
608 | #define SNB_CPU_FENCE_ENABLE (1<<29) | ||
609 | #define DPFC_CPU_FENCE_OFFSET 0x100104 | ||
610 | |||
544 | 611 | ||
545 | /* | 612 | /* |
546 | * GPIO regs | 613 | * GPIO regs |
@@ -900,6 +967,8 @@ | |||
900 | */ | 967 | */ |
901 | #define MCHBAR_MIRROR_BASE 0x10000 | 968 | #define MCHBAR_MIRROR_BASE 0x10000 |
902 | 969 | ||
970 | #define MCHBAR_MIRROR_BASE_SNB 0x140000 | ||
971 | |||
903 | /** 915-945 and GM965 MCH register controlling DRAM channel access */ | 972 | /** 915-945 and GM965 MCH register controlling DRAM channel access */ |
904 | #define DCC 0x10200 | 973 | #define DCC 0x10200 |
905 | #define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0) | 974 | #define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0) |
@@ -1119,6 +1188,10 @@ | |||
1119 | #define DDRMPLL1 0X12c20 | 1188 | #define DDRMPLL1 0X12c20 |
1120 | #define PEG_BAND_GAP_DATA 0x14d68 | 1189 | #define PEG_BAND_GAP_DATA 0x14d68 |
1121 | 1190 | ||
1191 | #define GEN6_GT_PERF_STATUS 0x145948 | ||
1192 | #define GEN6_RP_STATE_LIMITS 0x145994 | ||
1193 | #define GEN6_RP_STATE_CAP 0x145998 | ||
1194 | |||
1122 | /* | 1195 | /* |
1123 | * Logical Context regs | 1196 | * Logical Context regs |
1124 | */ | 1197 | */ |
@@ -1168,7 +1241,6 @@ | |||
1168 | #define VTOTAL(pipe) _PIPE(pipe, VTOTAL_A, VTOTAL_B) | 1241 | #define VTOTAL(pipe) _PIPE(pipe, VTOTAL_A, VTOTAL_B) |
1169 | #define VBLANK(pipe) _PIPE(pipe, VBLANK_A, VBLANK_B) | 1242 | #define VBLANK(pipe) _PIPE(pipe, VBLANK_A, VBLANK_B) |
1170 | #define VSYNC(pipe) _PIPE(pipe, VSYNC_A, VSYNC_B) | 1243 | #define VSYNC(pipe) _PIPE(pipe, VSYNC_A, VSYNC_B) |
1171 | #define PIPESRC(pipe) _PIPE(pipe, PIPEASRC, PIPEBSRC) | ||
1172 | #define BCLRPAT(pipe) _PIPE(pipe, BCLRPAT_A, BCLRPAT_B) | 1244 | #define BCLRPAT(pipe) _PIPE(pipe, BCLRPAT_A, BCLRPAT_B) |
1173 | 1245 | ||
1174 | /* VGA port control */ | 1246 | /* VGA port control */ |
@@ -2182,8 +2254,10 @@ | |||
2182 | #define PIPE_6BPC (2 << 5) | 2254 | #define PIPE_6BPC (2 << 5) |
2183 | #define PIPE_12BPC (3 << 5) | 2255 | #define PIPE_12BPC (3 << 5) |
2184 | 2256 | ||
2257 | #define PIPESRC(pipe) _PIPE(pipe, PIPEASRC, PIPEBSRC) | ||
2185 | #define PIPECONF(pipe) _PIPE(pipe, PIPEACONF, PIPEBCONF) | 2258 | #define PIPECONF(pipe) _PIPE(pipe, PIPEACONF, PIPEBCONF) |
2186 | #define PIPEDSL(pipe) _PIPE(pipe, PIPEADSL, PIPEBDSL) | 2259 | #define PIPEDSL(pipe) _PIPE(pipe, PIPEADSL, PIPEBDSL) |
2260 | #define PIPEFRAMEPIXEL(pipe) _PIPE(pipe, PIPEAFRAMEPIXEL, PIPEBFRAMEPIXEL) | ||
2187 | 2261 | ||
2188 | #define DSPARB 0x70030 | 2262 | #define DSPARB 0x70030 |
2189 | #define DSPARB_CSTART_MASK (0x7f << 7) | 2263 | #define DSPARB_CSTART_MASK (0x7f << 7) |
@@ -2291,6 +2365,40 @@ | |||
2291 | 2365 | ||
2292 | #define ILK_FIFO_LINE_SIZE 64 | 2366 | #define ILK_FIFO_LINE_SIZE 64 |
2293 | 2367 | ||
2368 | /* define the WM info on Sandybridge */ | ||
2369 | #define SNB_DISPLAY_FIFO 128 | ||
2370 | #define SNB_DISPLAY_MAXWM 0x7f /* bit 16:22 */ | ||
2371 | #define SNB_DISPLAY_DFTWM 8 | ||
2372 | #define SNB_CURSOR_FIFO 32 | ||
2373 | #define SNB_CURSOR_MAXWM 0x1f /* bit 4:0 */ | ||
2374 | #define SNB_CURSOR_DFTWM 8 | ||
2375 | |||
2376 | #define SNB_DISPLAY_SR_FIFO 512 | ||
2377 | #define SNB_DISPLAY_MAX_SRWM 0x1ff /* bit 16:8 */ | ||
2378 | #define SNB_DISPLAY_DFT_SRWM 0x3f | ||
2379 | #define SNB_CURSOR_SR_FIFO 64 | ||
2380 | #define SNB_CURSOR_MAX_SRWM 0x3f /* bit 5:0 */ | ||
2381 | #define SNB_CURSOR_DFT_SRWM 8 | ||
2382 | |||
2383 | #define SNB_FBC_MAX_SRWM 0xf /* bit 23:20 */ | ||
2384 | |||
2385 | #define SNB_FIFO_LINE_SIZE 64 | ||
2386 | |||
2387 | |||
2388 | /* the address where we get all kinds of latency value */ | ||
2389 | #define SSKPD 0x5d10 | ||
2390 | #define SSKPD_WM_MASK 0x3f | ||
2391 | #define SSKPD_WM0_SHIFT 0 | ||
2392 | #define SSKPD_WM1_SHIFT 8 | ||
2393 | #define SSKPD_WM2_SHIFT 16 | ||
2394 | #define SSKPD_WM3_SHIFT 24 | ||
2395 | |||
2396 | #define SNB_LATENCY(shift) (I915_READ(MCHBAR_MIRROR_BASE_SNB + SSKPD) >> (shift) & SSKPD_WM_MASK) | ||
2397 | #define SNB_READ_WM0_LATENCY() SNB_LATENCY(SSKPD_WM0_SHIFT) | ||
2398 | #define SNB_READ_WM1_LATENCY() SNB_LATENCY(SSKPD_WM1_SHIFT) | ||
2399 | #define SNB_READ_WM2_LATENCY() SNB_LATENCY(SSKPD_WM2_SHIFT) | ||
2400 | #define SNB_READ_WM3_LATENCY() SNB_LATENCY(SSKPD_WM3_SHIFT) | ||
2401 | |||
2294 | /* | 2402 | /* |
2295 | * The two pipe frame counter registers are not synchronized, so | 2403 | * The two pipe frame counter registers are not synchronized, so |
2296 | * reading a stable value is somewhat tricky. The following code | 2404 | * reading a stable value is somewhat tricky. The following code |
@@ -2351,6 +2459,10 @@ | |||
2351 | #define CURBBASE 0x700c4 | 2459 | #define CURBBASE 0x700c4 |
2352 | #define CURBPOS 0x700c8 | 2460 | #define CURBPOS 0x700c8 |
2353 | 2461 | ||
2462 | #define CURCNTR(pipe) _PIPE(pipe, CURACNTR, CURBCNTR) | ||
2463 | #define CURBASE(pipe) _PIPE(pipe, CURABASE, CURBBASE) | ||
2464 | #define CURPOS(pipe) _PIPE(pipe, CURAPOS, CURBPOS) | ||
2465 | |||
2354 | /* Display A control */ | 2466 | /* Display A control */ |
2355 | #define DSPACNTR 0x70180 | 2467 | #define DSPACNTR 0x70180 |
2356 | #define DISPLAY_PLANE_ENABLE (1<<31) | 2468 | #define DISPLAY_PLANE_ENABLE (1<<31) |
@@ -2586,10 +2698,14 @@ | |||
2586 | #define GTIER 0x4401c | 2698 | #define GTIER 0x4401c |
2587 | 2699 | ||
2588 | #define ILK_DISPLAY_CHICKEN2 0x42004 | 2700 | #define ILK_DISPLAY_CHICKEN2 0x42004 |
2701 | /* Required on all Ironlake and Sandybridge according to the B-Spec. */ | ||
2702 | #define ILK_ELPIN_409_SELECT (1 << 25) | ||
2589 | #define ILK_DPARB_GATE (1<<22) | 2703 | #define ILK_DPARB_GATE (1<<22) |
2590 | #define ILK_VSDPFD_FULL (1<<21) | 2704 | #define ILK_VSDPFD_FULL (1<<21) |
2591 | #define ILK_DSPCLK_GATE 0x42020 | 2705 | #define ILK_DSPCLK_GATE 0x42020 |
2592 | #define ILK_DPARB_CLK_GATE (1<<5) | 2706 | #define ILK_DPARB_CLK_GATE (1<<5) |
2707 | #define ILK_DPFD_CLK_GATE (1<<7) | ||
2708 | |||
2593 | /* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */ | 2709 | /* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */ |
2594 | #define ILK_CLK_FBC (1<<7) | 2710 | #define ILK_CLK_FBC (1<<7) |
2595 | #define ILK_DPFC_DIS1 (1<<8) | 2711 | #define ILK_DPFC_DIS1 (1<<8) |
@@ -2669,6 +2785,7 @@ | |||
2669 | #define PCH_DPLL(pipe) _PIPE(pipe, PCH_DPLL_A, PCH_DPLL_B) | 2785 | #define PCH_DPLL(pipe) _PIPE(pipe, PCH_DPLL_A, PCH_DPLL_B) |
2670 | 2786 | ||
2671 | #define PCH_FPA0 0xc6040 | 2787 | #define PCH_FPA0 0xc6040 |
2788 | #define FP_CB_TUNE (0x3<<22) | ||
2672 | #define PCH_FPA1 0xc6044 | 2789 | #define PCH_FPA1 0xc6044 |
2673 | #define PCH_FPB0 0xc6048 | 2790 | #define PCH_FPB0 0xc6048 |
2674 | #define PCH_FPB1 0xc604c | 2791 | #define PCH_FPB1 0xc604c |
@@ -3033,6 +3150,7 @@ | |||
3033 | #define TRANS_DP_10BPC (1<<9) | 3150 | #define TRANS_DP_10BPC (1<<9) |
3034 | #define TRANS_DP_6BPC (2<<9) | 3151 | #define TRANS_DP_6BPC (2<<9) |
3035 | #define TRANS_DP_12BPC (3<<9) | 3152 | #define TRANS_DP_12BPC (3<<9) |
3153 | #define TRANS_DP_BPC_MASK (3<<9) | ||
3036 | #define TRANS_DP_VSYNC_ACTIVE_HIGH (1<<4) | 3154 | #define TRANS_DP_VSYNC_ACTIVE_HIGH (1<<4) |
3037 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 | 3155 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 |
3038 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) | 3156 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) |
@@ -3052,4 +3170,66 @@ | |||
3052 | #define EDP_LINK_TRAIN_800MV_0DB_SNB_B (0x38<<22) | 3170 | #define EDP_LINK_TRAIN_800MV_0DB_SNB_B (0x38<<22) |
3053 | #define EDP_LINK_TRAIN_VOL_EMP_MASK_SNB (0x3f<<22) | 3171 | #define EDP_LINK_TRAIN_VOL_EMP_MASK_SNB (0x3f<<22) |
3054 | 3172 | ||
3173 | #define FORCEWAKE 0xA18C | ||
3174 | #define FORCEWAKE_ACK 0x130090 | ||
3175 | |||
3176 | #define GEN6_RPNSWREQ 0xA008 | ||
3177 | #define GEN6_TURBO_DISABLE (1<<31) | ||
3178 | #define GEN6_FREQUENCY(x) ((x)<<25) | ||
3179 | #define GEN6_OFFSET(x) ((x)<<19) | ||
3180 | #define GEN6_AGGRESSIVE_TURBO (0<<15) | ||
3181 | #define GEN6_RC_VIDEO_FREQ 0xA00C | ||
3182 | #define GEN6_RC_CONTROL 0xA090 | ||
3183 | #define GEN6_RC_CTL_RC6pp_ENABLE (1<<16) | ||
3184 | #define GEN6_RC_CTL_RC6p_ENABLE (1<<17) | ||
3185 | #define GEN6_RC_CTL_RC6_ENABLE (1<<18) | ||
3186 | #define GEN6_RC_CTL_RC1e_ENABLE (1<<20) | ||
3187 | #define GEN6_RC_CTL_RC7_ENABLE (1<<22) | ||
3188 | #define GEN6_RC_CTL_EI_MODE(x) ((x)<<27) | ||
3189 | #define GEN6_RC_CTL_HW_ENABLE (1<<31) | ||
3190 | #define GEN6_RP_DOWN_TIMEOUT 0xA010 | ||
3191 | #define GEN6_RP_INTERRUPT_LIMITS 0xA014 | ||
3192 | #define GEN6_RPSTAT1 0xA01C | ||
3193 | #define GEN6_RP_CONTROL 0xA024 | ||
3194 | #define GEN6_RP_MEDIA_TURBO (1<<11) | ||
3195 | #define GEN6_RP_USE_NORMAL_FREQ (1<<9) | ||
3196 | #define GEN6_RP_MEDIA_IS_GFX (1<<8) | ||
3197 | #define GEN6_RP_ENABLE (1<<7) | ||
3198 | #define GEN6_RP_UP_BUSY_MAX (0x2<<3) | ||
3199 | #define GEN6_RP_DOWN_BUSY_MIN (0x2<<0) | ||
3200 | #define GEN6_RP_UP_THRESHOLD 0xA02C | ||
3201 | #define GEN6_RP_DOWN_THRESHOLD 0xA030 | ||
3202 | #define GEN6_RP_UP_EI 0xA068 | ||
3203 | #define GEN6_RP_DOWN_EI 0xA06C | ||
3204 | #define GEN6_RP_IDLE_HYSTERSIS 0xA070 | ||
3205 | #define GEN6_RC_STATE 0xA094 | ||
3206 | #define GEN6_RC1_WAKE_RATE_LIMIT 0xA098 | ||
3207 | #define GEN6_RC6_WAKE_RATE_LIMIT 0xA09C | ||
3208 | #define GEN6_RC6pp_WAKE_RATE_LIMIT 0xA0A0 | ||
3209 | #define GEN6_RC_EVALUATION_INTERVAL 0xA0A8 | ||
3210 | #define GEN6_RC_IDLE_HYSTERSIS 0xA0AC | ||
3211 | #define GEN6_RC_SLEEP 0xA0B0 | ||
3212 | #define GEN6_RC1e_THRESHOLD 0xA0B4 | ||
3213 | #define GEN6_RC6_THRESHOLD 0xA0B8 | ||
3214 | #define GEN6_RC6p_THRESHOLD 0xA0BC | ||
3215 | #define GEN6_RC6pp_THRESHOLD 0xA0C0 | ||
3216 | #define GEN6_PMINTRMSK 0xA168 | ||
3217 | |||
3218 | #define GEN6_PMISR 0x44020 | ||
3219 | #define GEN6_PMIMR 0x44024 | ||
3220 | #define GEN6_PMIIR 0x44028 | ||
3221 | #define GEN6_PMIER 0x4402C | ||
3222 | #define GEN6_PM_MBOX_EVENT (1<<25) | ||
3223 | #define GEN6_PM_THERMAL_EVENT (1<<24) | ||
3224 | #define GEN6_PM_RP_DOWN_TIMEOUT (1<<6) | ||
3225 | #define GEN6_PM_RP_UP_THRESHOLD (1<<5) | ||
3226 | #define GEN6_PM_RP_DOWN_THRESHOLD (1<<4) | ||
3227 | #define GEN6_PM_RP_UP_EI_EXPIRED (1<<2) | ||
3228 | #define GEN6_PM_RP_DOWN_EI_EXPIRED (1<<1) | ||
3229 | |||
3230 | #define GEN6_PCODE_MAILBOX 0x138124 | ||
3231 | #define GEN6_PCODE_READY (1<<31) | ||
3232 | #define GEN6_PCODE_WRITE_MIN_FREQ_TABLE 0x9 | ||
3233 | #define GEN6_PCODE_DATA 0x138128 | ||
3234 | |||
3055 | #endif /* _I915_REG_H_ */ | 3235 | #endif /* _I915_REG_H_ */ |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 454c064f8ef..410772466fa 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -235,10 +235,21 @@ static void i915_restore_vga(struct drm_device *dev) | |||
235 | static void i915_save_modeset_reg(struct drm_device *dev) | 235 | static void i915_save_modeset_reg(struct drm_device *dev) |
236 | { | 236 | { |
237 | struct drm_i915_private *dev_priv = dev->dev_private; | 237 | struct drm_i915_private *dev_priv = dev->dev_private; |
238 | int i; | ||
238 | 239 | ||
239 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 240 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
240 | return; | 241 | return; |
241 | 242 | ||
243 | /* Cursor state */ | ||
244 | dev_priv->saveCURACNTR = I915_READ(CURACNTR); | ||
245 | dev_priv->saveCURAPOS = I915_READ(CURAPOS); | ||
246 | dev_priv->saveCURABASE = I915_READ(CURABASE); | ||
247 | dev_priv->saveCURBCNTR = I915_READ(CURBCNTR); | ||
248 | dev_priv->saveCURBPOS = I915_READ(CURBPOS); | ||
249 | dev_priv->saveCURBBASE = I915_READ(CURBBASE); | ||
250 | if (IS_GEN2(dev)) | ||
251 | dev_priv->saveCURSIZE = I915_READ(CURSIZE); | ||
252 | |||
242 | if (HAS_PCH_SPLIT(dev)) { | 253 | if (HAS_PCH_SPLIT(dev)) { |
243 | dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); | 254 | dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); |
244 | dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); | 255 | dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); |
@@ -357,6 +368,28 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
357 | } | 368 | } |
358 | i915_save_palette(dev, PIPE_B); | 369 | i915_save_palette(dev, PIPE_B); |
359 | dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); | 370 | dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); |
371 | |||
372 | /* Fences */ | ||
373 | switch (INTEL_INFO(dev)->gen) { | ||
374 | case 6: | ||
375 | for (i = 0; i < 16; i++) | ||
376 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); | ||
377 | break; | ||
378 | case 5: | ||
379 | case 4: | ||
380 | for (i = 0; i < 16; i++) | ||
381 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); | ||
382 | break; | ||
383 | case 3: | ||
384 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | ||
385 | for (i = 0; i < 8; i++) | ||
386 | dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); | ||
387 | case 2: | ||
388 | for (i = 0; i < 8; i++) | ||
389 | dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); | ||
390 | break; | ||
391 | } | ||
392 | |||
360 | return; | 393 | return; |
361 | } | 394 | } |
362 | 395 | ||
@@ -365,10 +398,33 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
365 | struct drm_i915_private *dev_priv = dev->dev_private; | 398 | struct drm_i915_private *dev_priv = dev->dev_private; |
366 | int dpll_a_reg, fpa0_reg, fpa1_reg; | 399 | int dpll_a_reg, fpa0_reg, fpa1_reg; |
367 | int dpll_b_reg, fpb0_reg, fpb1_reg; | 400 | int dpll_b_reg, fpb0_reg, fpb1_reg; |
401 | int i; | ||
368 | 402 | ||
369 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 403 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
370 | return; | 404 | return; |
371 | 405 | ||
406 | /* Fences */ | ||
407 | switch (INTEL_INFO(dev)->gen) { | ||
408 | case 6: | ||
409 | for (i = 0; i < 16; i++) | ||
410 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); | ||
411 | break; | ||
412 | case 5: | ||
413 | case 4: | ||
414 | for (i = 0; i < 16; i++) | ||
415 | I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); | ||
416 | break; | ||
417 | case 3: | ||
418 | case 2: | ||
419 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | ||
420 | for (i = 0; i < 8; i++) | ||
421 | I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); | ||
422 | for (i = 0; i < 8; i++) | ||
423 | I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); | ||
424 | break; | ||
425 | } | ||
426 | |||
427 | |||
372 | if (HAS_PCH_SPLIT(dev)) { | 428 | if (HAS_PCH_SPLIT(dev)) { |
373 | dpll_a_reg = PCH_DPLL_A; | 429 | dpll_a_reg = PCH_DPLL_A; |
374 | dpll_b_reg = PCH_DPLL_B; | 430 | dpll_b_reg = PCH_DPLL_B; |
@@ -529,6 +585,16 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
529 | I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); | 585 | I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); |
530 | I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); | 586 | I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); |
531 | 587 | ||
588 | /* Cursor state */ | ||
589 | I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); | ||
590 | I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); | ||
591 | I915_WRITE(CURABASE, dev_priv->saveCURABASE); | ||
592 | I915_WRITE(CURBPOS, dev_priv->saveCURBPOS); | ||
593 | I915_WRITE(CURBCNTR, dev_priv->saveCURBCNTR); | ||
594 | I915_WRITE(CURBBASE, dev_priv->saveCURBBASE); | ||
595 | if (IS_GEN2(dev)) | ||
596 | I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); | ||
597 | |||
532 | return; | 598 | return; |
533 | } | 599 | } |
534 | 600 | ||
@@ -543,16 +609,6 @@ void i915_save_display(struct drm_device *dev) | |||
543 | /* Don't save them in KMS mode */ | 609 | /* Don't save them in KMS mode */ |
544 | i915_save_modeset_reg(dev); | 610 | i915_save_modeset_reg(dev); |
545 | 611 | ||
546 | /* Cursor state */ | ||
547 | dev_priv->saveCURACNTR = I915_READ(CURACNTR); | ||
548 | dev_priv->saveCURAPOS = I915_READ(CURAPOS); | ||
549 | dev_priv->saveCURABASE = I915_READ(CURABASE); | ||
550 | dev_priv->saveCURBCNTR = I915_READ(CURBCNTR); | ||
551 | dev_priv->saveCURBPOS = I915_READ(CURBPOS); | ||
552 | dev_priv->saveCURBBASE = I915_READ(CURBBASE); | ||
553 | if (IS_GEN2(dev)) | ||
554 | dev_priv->saveCURSIZE = I915_READ(CURSIZE); | ||
555 | |||
556 | /* CRT state */ | 612 | /* CRT state */ |
557 | if (HAS_PCH_SPLIT(dev)) { | 613 | if (HAS_PCH_SPLIT(dev)) { |
558 | dev_priv->saveADPA = I915_READ(PCH_ADPA); | 614 | dev_priv->saveADPA = I915_READ(PCH_ADPA); |
@@ -657,16 +713,6 @@ void i915_restore_display(struct drm_device *dev) | |||
657 | /* Don't restore them in KMS mode */ | 713 | /* Don't restore them in KMS mode */ |
658 | i915_restore_modeset_reg(dev); | 714 | i915_restore_modeset_reg(dev); |
659 | 715 | ||
660 | /* Cursor state */ | ||
661 | I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); | ||
662 | I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); | ||
663 | I915_WRITE(CURABASE, dev_priv->saveCURABASE); | ||
664 | I915_WRITE(CURBPOS, dev_priv->saveCURBPOS); | ||
665 | I915_WRITE(CURBCNTR, dev_priv->saveCURBCNTR); | ||
666 | I915_WRITE(CURBBASE, dev_priv->saveCURBBASE); | ||
667 | if (IS_GEN2(dev)) | ||
668 | I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); | ||
669 | |||
670 | /* CRT state */ | 716 | /* CRT state */ |
671 | if (HAS_PCH_SPLIT(dev)) | 717 | if (HAS_PCH_SPLIT(dev)) |
672 | I915_WRITE(PCH_ADPA, dev_priv->saveADPA); | 718 | I915_WRITE(PCH_ADPA, dev_priv->saveADPA); |
@@ -771,8 +817,14 @@ int i915_save_state(struct drm_device *dev) | |||
771 | dev_priv->saveIMR = I915_READ(IMR); | 817 | dev_priv->saveIMR = I915_READ(IMR); |
772 | } | 818 | } |
773 | 819 | ||
774 | if (HAS_PCH_SPLIT(dev)) | 820 | if (IS_IRONLAKE_M(dev)) |
775 | ironlake_disable_drps(dev); | 821 | ironlake_disable_drps(dev); |
822 | if (IS_GEN6(dev)) | ||
823 | gen6_disable_rps(dev); | ||
824 | |||
825 | /* XXX disabling the clock gating breaks suspend on gm45 | ||
826 | intel_disable_clock_gating(dev); | ||
827 | */ | ||
776 | 828 | ||
777 | /* Cache mode state */ | 829 | /* Cache mode state */ |
778 | dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); | 830 | dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); |
@@ -788,28 +840,6 @@ int i915_save_state(struct drm_device *dev) | |||
788 | for (i = 0; i < 3; i++) | 840 | for (i = 0; i < 3; i++) |
789 | dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); | 841 | dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); |
790 | 842 | ||
791 | /* Fences */ | ||
792 | switch (INTEL_INFO(dev)->gen) { | ||
793 | case 6: | ||
794 | for (i = 0; i < 16; i++) | ||
795 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); | ||
796 | break; | ||
797 | case 5: | ||
798 | case 4: | ||
799 | for (i = 0; i < 16; i++) | ||
800 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); | ||
801 | break; | ||
802 | case 3: | ||
803 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | ||
804 | for (i = 0; i < 8; i++) | ||
805 | dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); | ||
806 | case 2: | ||
807 | for (i = 0; i < 8; i++) | ||
808 | dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); | ||
809 | break; | ||
810 | |||
811 | } | ||
812 | |||
813 | return 0; | 843 | return 0; |
814 | } | 844 | } |
815 | 845 | ||
@@ -823,27 +853,6 @@ int i915_restore_state(struct drm_device *dev) | |||
823 | /* Hardware status page */ | 853 | /* Hardware status page */ |
824 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); | 854 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); |
825 | 855 | ||
826 | /* Fences */ | ||
827 | switch (INTEL_INFO(dev)->gen) { | ||
828 | case 6: | ||
829 | for (i = 0; i < 16; i++) | ||
830 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); | ||
831 | break; | ||
832 | case 5: | ||
833 | case 4: | ||
834 | for (i = 0; i < 16; i++) | ||
835 | I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); | ||
836 | break; | ||
837 | case 3: | ||
838 | case 2: | ||
839 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | ||
840 | for (i = 0; i < 8; i++) | ||
841 | I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); | ||
842 | for (i = 0; i < 8; i++) | ||
843 | I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); | ||
844 | break; | ||
845 | } | ||
846 | |||
847 | i915_restore_display(dev); | 856 | i915_restore_display(dev); |
848 | 857 | ||
849 | /* Interrupt state */ | 858 | /* Interrupt state */ |
@@ -860,13 +869,16 @@ int i915_restore_state(struct drm_device *dev) | |||
860 | } | 869 | } |
861 | 870 | ||
862 | /* Clock gating state */ | 871 | /* Clock gating state */ |
863 | intel_init_clock_gating(dev); | 872 | intel_enable_clock_gating(dev); |
864 | 873 | ||
865 | if (HAS_PCH_SPLIT(dev)) { | 874 | if (IS_IRONLAKE_M(dev)) { |
866 | ironlake_enable_drps(dev); | 875 | ironlake_enable_drps(dev); |
867 | intel_init_emon(dev); | 876 | intel_init_emon(dev); |
868 | } | 877 | } |
869 | 878 | ||
879 | if (IS_GEN6(dev)) | ||
880 | gen6_enable_rps(dev_priv); | ||
881 | |||
870 | /* Cache mode state */ | 882 | /* Cache mode state */ |
871 | I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); | 883 | I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); |
872 | 884 | ||
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index fea97a21cc1..7f0fc3ed61a 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/tracepoint.h> | 6 | #include <linux/tracepoint.h> |
7 | 7 | ||
8 | #include <drm/drmP.h> | 8 | #include <drm/drmP.h> |
9 | #include "i915_drv.h" | ||
9 | 10 | ||
10 | #undef TRACE_SYSTEM | 11 | #undef TRACE_SYSTEM |
11 | #define TRACE_SYSTEM i915 | 12 | #define TRACE_SYSTEM i915 |
@@ -16,18 +17,18 @@ | |||
16 | 17 | ||
17 | TRACE_EVENT(i915_gem_object_create, | 18 | TRACE_EVENT(i915_gem_object_create, |
18 | 19 | ||
19 | TP_PROTO(struct drm_gem_object *obj), | 20 | TP_PROTO(struct drm_i915_gem_object *obj), |
20 | 21 | ||
21 | TP_ARGS(obj), | 22 | TP_ARGS(obj), |
22 | 23 | ||
23 | TP_STRUCT__entry( | 24 | TP_STRUCT__entry( |
24 | __field(struct drm_gem_object *, obj) | 25 | __field(struct drm_i915_gem_object *, obj) |
25 | __field(u32, size) | 26 | __field(u32, size) |
26 | ), | 27 | ), |
27 | 28 | ||
28 | TP_fast_assign( | 29 | TP_fast_assign( |
29 | __entry->obj = obj; | 30 | __entry->obj = obj; |
30 | __entry->size = obj->size; | 31 | __entry->size = obj->base.size; |
31 | ), | 32 | ), |
32 | 33 | ||
33 | TP_printk("obj=%p, size=%u", __entry->obj, __entry->size) | 34 | TP_printk("obj=%p, size=%u", __entry->obj, __entry->size) |
@@ -35,40 +36,43 @@ TRACE_EVENT(i915_gem_object_create, | |||
35 | 36 | ||
36 | TRACE_EVENT(i915_gem_object_bind, | 37 | TRACE_EVENT(i915_gem_object_bind, |
37 | 38 | ||
38 | TP_PROTO(struct drm_gem_object *obj, u32 gtt_offset), | 39 | TP_PROTO(struct drm_i915_gem_object *obj, u32 gtt_offset, bool mappable), |
39 | 40 | ||
40 | TP_ARGS(obj, gtt_offset), | 41 | TP_ARGS(obj, gtt_offset, mappable), |
41 | 42 | ||
42 | TP_STRUCT__entry( | 43 | TP_STRUCT__entry( |
43 | __field(struct drm_gem_object *, obj) | 44 | __field(struct drm_i915_gem_object *, obj) |
44 | __field(u32, gtt_offset) | 45 | __field(u32, gtt_offset) |
46 | __field(bool, mappable) | ||
45 | ), | 47 | ), |
46 | 48 | ||
47 | TP_fast_assign( | 49 | TP_fast_assign( |
48 | __entry->obj = obj; | 50 | __entry->obj = obj; |
49 | __entry->gtt_offset = gtt_offset; | 51 | __entry->gtt_offset = gtt_offset; |
52 | __entry->mappable = mappable; | ||
50 | ), | 53 | ), |
51 | 54 | ||
52 | TP_printk("obj=%p, gtt_offset=%08x", | 55 | TP_printk("obj=%p, gtt_offset=%08x%s", |
53 | __entry->obj, __entry->gtt_offset) | 56 | __entry->obj, __entry->gtt_offset, |
57 | __entry->mappable ? ", mappable" : "") | ||
54 | ); | 58 | ); |
55 | 59 | ||
56 | TRACE_EVENT(i915_gem_object_change_domain, | 60 | TRACE_EVENT(i915_gem_object_change_domain, |
57 | 61 | ||
58 | TP_PROTO(struct drm_gem_object *obj, uint32_t old_read_domains, uint32_t old_write_domain), | 62 | TP_PROTO(struct drm_i915_gem_object *obj, uint32_t old_read_domains, uint32_t old_write_domain), |
59 | 63 | ||
60 | TP_ARGS(obj, old_read_domains, old_write_domain), | 64 | TP_ARGS(obj, old_read_domains, old_write_domain), |
61 | 65 | ||
62 | TP_STRUCT__entry( | 66 | TP_STRUCT__entry( |
63 | __field(struct drm_gem_object *, obj) | 67 | __field(struct drm_i915_gem_object *, obj) |
64 | __field(u32, read_domains) | 68 | __field(u32, read_domains) |
65 | __field(u32, write_domain) | 69 | __field(u32, write_domain) |
66 | ), | 70 | ), |
67 | 71 | ||
68 | TP_fast_assign( | 72 | TP_fast_assign( |
69 | __entry->obj = obj; | 73 | __entry->obj = obj; |
70 | __entry->read_domains = obj->read_domains | (old_read_domains << 16); | 74 | __entry->read_domains = obj->base.read_domains | (old_read_domains << 16); |
71 | __entry->write_domain = obj->write_domain | (old_write_domain << 16); | 75 | __entry->write_domain = obj->base.write_domain | (old_write_domain << 16); |
72 | ), | 76 | ), |
73 | 77 | ||
74 | TP_printk("obj=%p, read=%04x, write=%04x", | 78 | TP_printk("obj=%p, read=%04x, write=%04x", |
@@ -76,36 +80,14 @@ TRACE_EVENT(i915_gem_object_change_domain, | |||
76 | __entry->read_domains, __entry->write_domain) | 80 | __entry->read_domains, __entry->write_domain) |
77 | ); | 81 | ); |
78 | 82 | ||
79 | TRACE_EVENT(i915_gem_object_get_fence, | ||
80 | |||
81 | TP_PROTO(struct drm_gem_object *obj, int fence, int tiling_mode), | ||
82 | |||
83 | TP_ARGS(obj, fence, tiling_mode), | ||
84 | |||
85 | TP_STRUCT__entry( | ||
86 | __field(struct drm_gem_object *, obj) | ||
87 | __field(int, fence) | ||
88 | __field(int, tiling_mode) | ||
89 | ), | ||
90 | |||
91 | TP_fast_assign( | ||
92 | __entry->obj = obj; | ||
93 | __entry->fence = fence; | ||
94 | __entry->tiling_mode = tiling_mode; | ||
95 | ), | ||
96 | |||
97 | TP_printk("obj=%p, fence=%d, tiling=%d", | ||
98 | __entry->obj, __entry->fence, __entry->tiling_mode) | ||
99 | ); | ||
100 | |||
101 | DECLARE_EVENT_CLASS(i915_gem_object, | 83 | DECLARE_EVENT_CLASS(i915_gem_object, |
102 | 84 | ||
103 | TP_PROTO(struct drm_gem_object *obj), | 85 | TP_PROTO(struct drm_i915_gem_object *obj), |
104 | 86 | ||
105 | TP_ARGS(obj), | 87 | TP_ARGS(obj), |
106 | 88 | ||
107 | TP_STRUCT__entry( | 89 | TP_STRUCT__entry( |
108 | __field(struct drm_gem_object *, obj) | 90 | __field(struct drm_i915_gem_object *, obj) |
109 | ), | 91 | ), |
110 | 92 | ||
111 | TP_fast_assign( | 93 | TP_fast_assign( |
@@ -117,21 +99,21 @@ DECLARE_EVENT_CLASS(i915_gem_object, | |||
117 | 99 | ||
118 | DEFINE_EVENT(i915_gem_object, i915_gem_object_clflush, | 100 | DEFINE_EVENT(i915_gem_object, i915_gem_object_clflush, |
119 | 101 | ||
120 | TP_PROTO(struct drm_gem_object *obj), | 102 | TP_PROTO(struct drm_i915_gem_object *obj), |
121 | 103 | ||
122 | TP_ARGS(obj) | 104 | TP_ARGS(obj) |
123 | ); | 105 | ); |
124 | 106 | ||
125 | DEFINE_EVENT(i915_gem_object, i915_gem_object_unbind, | 107 | DEFINE_EVENT(i915_gem_object, i915_gem_object_unbind, |
126 | 108 | ||
127 | TP_PROTO(struct drm_gem_object *obj), | 109 | TP_PROTO(struct drm_i915_gem_object *obj), |
128 | 110 | ||
129 | TP_ARGS(obj) | 111 | TP_ARGS(obj) |
130 | ); | 112 | ); |
131 | 113 | ||
132 | DEFINE_EVENT(i915_gem_object, i915_gem_object_destroy, | 114 | DEFINE_EVENT(i915_gem_object, i915_gem_object_destroy, |
133 | 115 | ||
134 | TP_PROTO(struct drm_gem_object *obj), | 116 | TP_PROTO(struct drm_i915_gem_object *obj), |
135 | 117 | ||
136 | TP_ARGS(obj) | 118 | TP_ARGS(obj) |
137 | ); | 119 | ); |
@@ -263,13 +245,13 @@ DEFINE_EVENT(i915_ring, i915_ring_wait_end, | |||
263 | ); | 245 | ); |
264 | 246 | ||
265 | TRACE_EVENT(i915_flip_request, | 247 | TRACE_EVENT(i915_flip_request, |
266 | TP_PROTO(int plane, struct drm_gem_object *obj), | 248 | TP_PROTO(int plane, struct drm_i915_gem_object *obj), |
267 | 249 | ||
268 | TP_ARGS(plane, obj), | 250 | TP_ARGS(plane, obj), |
269 | 251 | ||
270 | TP_STRUCT__entry( | 252 | TP_STRUCT__entry( |
271 | __field(int, plane) | 253 | __field(int, plane) |
272 | __field(struct drm_gem_object *, obj) | 254 | __field(struct drm_i915_gem_object *, obj) |
273 | ), | 255 | ), |
274 | 256 | ||
275 | TP_fast_assign( | 257 | TP_fast_assign( |
@@ -281,13 +263,13 @@ TRACE_EVENT(i915_flip_request, | |||
281 | ); | 263 | ); |
282 | 264 | ||
283 | TRACE_EVENT(i915_flip_complete, | 265 | TRACE_EVENT(i915_flip_complete, |
284 | TP_PROTO(int plane, struct drm_gem_object *obj), | 266 | TP_PROTO(int plane, struct drm_i915_gem_object *obj), |
285 | 267 | ||
286 | TP_ARGS(plane, obj), | 268 | TP_ARGS(plane, obj), |
287 | 269 | ||
288 | TP_STRUCT__entry( | 270 | TP_STRUCT__entry( |
289 | __field(int, plane) | 271 | __field(int, plane) |
290 | __field(struct drm_gem_object *, obj) | 272 | __field(struct drm_i915_gem_object *, obj) |
291 | ), | 273 | ), |
292 | 274 | ||
293 | TP_fast_assign( | 275 | TP_fast_assign( |
@@ -298,6 +280,29 @@ TRACE_EVENT(i915_flip_complete, | |||
298 | TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj) | 280 | TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj) |
299 | ); | 281 | ); |
300 | 282 | ||
283 | TRACE_EVENT(i915_reg_rw, | ||
284 | TP_PROTO(int cmd, uint32_t reg, uint64_t val, int len), | ||
285 | |||
286 | TP_ARGS(cmd, reg, val, len), | ||
287 | |||
288 | TP_STRUCT__entry( | ||
289 | __field(int, cmd) | ||
290 | __field(uint32_t, reg) | ||
291 | __field(uint64_t, val) | ||
292 | __field(int, len) | ||
293 | ), | ||
294 | |||
295 | TP_fast_assign( | ||
296 | __entry->cmd = cmd; | ||
297 | __entry->reg = reg; | ||
298 | __entry->val = (uint64_t)val; | ||
299 | __entry->len = len; | ||
300 | ), | ||
301 | |||
302 | TP_printk("cmd=%c, reg=0x%x, val=0x%llx, len=%d", | ||
303 | __entry->cmd, __entry->reg, __entry->val, __entry->len) | ||
304 | ); | ||
305 | |||
301 | #endif /* _I915_TRACE_H_ */ | 306 | #endif /* _I915_TRACE_H_ */ |
302 | 307 | ||
303 | /* This part must be outside protection */ | 308 | /* This part must be outside protection */ |
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c index 65c88f9ba12..2cb8e0b9f1e 100644 --- a/drivers/gpu/drm/i915/intel_acpi.c +++ b/drivers/gpu/drm/i915/intel_acpi.c | |||
@@ -190,37 +190,6 @@ out: | |||
190 | kfree(output.pointer); | 190 | kfree(output.pointer); |
191 | } | 191 | } |
192 | 192 | ||
193 | static int intel_dsm_switchto(enum vga_switcheroo_client_id id) | ||
194 | { | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static int intel_dsm_power_state(enum vga_switcheroo_client_id id, | ||
199 | enum vga_switcheroo_state state) | ||
200 | { | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int intel_dsm_init(void) | ||
205 | { | ||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static int intel_dsm_get_client_id(struct pci_dev *pdev) | ||
210 | { | ||
211 | if (intel_dsm_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev)) | ||
212 | return VGA_SWITCHEROO_IGD; | ||
213 | else | ||
214 | return VGA_SWITCHEROO_DIS; | ||
215 | } | ||
216 | |||
217 | static struct vga_switcheroo_handler intel_dsm_handler = { | ||
218 | .switchto = intel_dsm_switchto, | ||
219 | .power_state = intel_dsm_power_state, | ||
220 | .init = intel_dsm_init, | ||
221 | .get_client_id = intel_dsm_get_client_id, | ||
222 | }; | ||
223 | |||
224 | static bool intel_dsm_pci_probe(struct pci_dev *pdev) | 193 | static bool intel_dsm_pci_probe(struct pci_dev *pdev) |
225 | { | 194 | { |
226 | acpi_handle dhandle, intel_handle; | 195 | acpi_handle dhandle, intel_handle; |
@@ -276,11 +245,8 @@ void intel_register_dsm_handler(void) | |||
276 | { | 245 | { |
277 | if (!intel_dsm_detect()) | 246 | if (!intel_dsm_detect()) |
278 | return; | 247 | return; |
279 | |||
280 | vga_switcheroo_register_handler(&intel_dsm_handler); | ||
281 | } | 248 | } |
282 | 249 | ||
283 | void intel_unregister_dsm_handler(void) | 250 | void intel_unregister_dsm_handler(void) |
284 | { | 251 | { |
285 | vga_switcheroo_unregister_handler(); | ||
286 | } | 252 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bee24b1a58e..880659680d0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -642,26 +642,23 @@ static const intel_limit_t intel_limits_ironlake_display_port = { | |||
642 | .find_pll = intel_find_pll_ironlake_dp, | 642 | .find_pll = intel_find_pll_ironlake_dp, |
643 | }; | 643 | }; |
644 | 644 | ||
645 | static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc) | 645 | static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc, |
646 | int refclk) | ||
646 | { | 647 | { |
647 | struct drm_device *dev = crtc->dev; | 648 | struct drm_device *dev = crtc->dev; |
648 | struct drm_i915_private *dev_priv = dev->dev_private; | 649 | struct drm_i915_private *dev_priv = dev->dev_private; |
649 | const intel_limit_t *limit; | 650 | const intel_limit_t *limit; |
650 | int refclk = 120; | ||
651 | 651 | ||
652 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | 652 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
653 | if (dev_priv->lvds_use_ssc && dev_priv->lvds_ssc_freq == 100) | ||
654 | refclk = 100; | ||
655 | |||
656 | if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == | 653 | if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == |
657 | LVDS_CLKB_POWER_UP) { | 654 | LVDS_CLKB_POWER_UP) { |
658 | /* LVDS dual channel */ | 655 | /* LVDS dual channel */ |
659 | if (refclk == 100) | 656 | if (refclk == 100000) |
660 | limit = &intel_limits_ironlake_dual_lvds_100m; | 657 | limit = &intel_limits_ironlake_dual_lvds_100m; |
661 | else | 658 | else |
662 | limit = &intel_limits_ironlake_dual_lvds; | 659 | limit = &intel_limits_ironlake_dual_lvds; |
663 | } else { | 660 | } else { |
664 | if (refclk == 100) | 661 | if (refclk == 100000) |
665 | limit = &intel_limits_ironlake_single_lvds_100m; | 662 | limit = &intel_limits_ironlake_single_lvds_100m; |
666 | else | 663 | else |
667 | limit = &intel_limits_ironlake_single_lvds; | 664 | limit = &intel_limits_ironlake_single_lvds; |
@@ -702,13 +699,13 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc) | |||
702 | return limit; | 699 | return limit; |
703 | } | 700 | } |
704 | 701 | ||
705 | static const intel_limit_t *intel_limit(struct drm_crtc *crtc) | 702 | static const intel_limit_t *intel_limit(struct drm_crtc *crtc, int refclk) |
706 | { | 703 | { |
707 | struct drm_device *dev = crtc->dev; | 704 | struct drm_device *dev = crtc->dev; |
708 | const intel_limit_t *limit; | 705 | const intel_limit_t *limit; |
709 | 706 | ||
710 | if (HAS_PCH_SPLIT(dev)) | 707 | if (HAS_PCH_SPLIT(dev)) |
711 | limit = intel_ironlake_limit(crtc); | 708 | limit = intel_ironlake_limit(crtc, refclk); |
712 | else if (IS_G4X(dev)) { | 709 | else if (IS_G4X(dev)) { |
713 | limit = intel_g4x_limit(crtc); | 710 | limit = intel_g4x_limit(crtc); |
714 | } else if (IS_PINEVIEW(dev)) { | 711 | } else if (IS_PINEVIEW(dev)) { |
@@ -773,11 +770,10 @@ bool intel_pipe_has_type(struct drm_crtc *crtc, int type) | |||
773 | * the given connectors. | 770 | * the given connectors. |
774 | */ | 771 | */ |
775 | 772 | ||
776 | static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock) | 773 | static bool intel_PLL_is_valid(struct drm_device *dev, |
774 | const intel_limit_t *limit, | ||
775 | const intel_clock_t *clock) | ||
777 | { | 776 | { |
778 | const intel_limit_t *limit = intel_limit (crtc); | ||
779 | struct drm_device *dev = crtc->dev; | ||
780 | |||
781 | if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1) | 777 | if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1) |
782 | INTELPllInvalid ("p1 out of range\n"); | 778 | INTELPllInvalid ("p1 out of range\n"); |
783 | if (clock->p < limit->p.min || limit->p.max < clock->p) | 779 | if (clock->p < limit->p.min || limit->p.max < clock->p) |
@@ -849,8 +845,8 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
849 | int this_err; | 845 | int this_err; |
850 | 846 | ||
851 | intel_clock(dev, refclk, &clock); | 847 | intel_clock(dev, refclk, &clock); |
852 | 848 | if (!intel_PLL_is_valid(dev, limit, | |
853 | if (!intel_PLL_is_valid(crtc, &clock)) | 849 | &clock)) |
854 | continue; | 850 | continue; |
855 | 851 | ||
856 | this_err = abs(clock.dot - target); | 852 | this_err = abs(clock.dot - target); |
@@ -912,9 +908,11 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
912 | int this_err; | 908 | int this_err; |
913 | 909 | ||
914 | intel_clock(dev, refclk, &clock); | 910 | intel_clock(dev, refclk, &clock); |
915 | if (!intel_PLL_is_valid(crtc, &clock)) | 911 | if (!intel_PLL_is_valid(dev, limit, |
912 | &clock)) | ||
916 | continue; | 913 | continue; |
917 | this_err = abs(clock.dot - target) ; | 914 | |
915 | this_err = abs(clock.dot - target); | ||
918 | if (this_err < err_most) { | 916 | if (this_err < err_most) { |
919 | *best_clock = clock; | 917 | *best_clock = clock; |
920 | err_most = this_err; | 918 | err_most = this_err; |
@@ -1066,13 +1064,13 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1066 | struct drm_i915_private *dev_priv = dev->dev_private; | 1064 | struct drm_i915_private *dev_priv = dev->dev_private; |
1067 | struct drm_framebuffer *fb = crtc->fb; | 1065 | struct drm_framebuffer *fb = crtc->fb; |
1068 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | 1066 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
1069 | struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); | 1067 | struct drm_i915_gem_object *obj = intel_fb->obj; |
1070 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1068 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1071 | int plane, i; | 1069 | int plane, i; |
1072 | u32 fbc_ctl, fbc_ctl2; | 1070 | u32 fbc_ctl, fbc_ctl2; |
1073 | 1071 | ||
1074 | if (fb->pitch == dev_priv->cfb_pitch && | 1072 | if (fb->pitch == dev_priv->cfb_pitch && |
1075 | obj_priv->fence_reg == dev_priv->cfb_fence && | 1073 | obj->fence_reg == dev_priv->cfb_fence && |
1076 | intel_crtc->plane == dev_priv->cfb_plane && | 1074 | intel_crtc->plane == dev_priv->cfb_plane && |
1077 | I915_READ(FBC_CONTROL) & FBC_CTL_EN) | 1075 | I915_READ(FBC_CONTROL) & FBC_CTL_EN) |
1078 | return; | 1076 | return; |
@@ -1086,7 +1084,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1086 | 1084 | ||
1087 | /* FBC_CTL wants 64B units */ | 1085 | /* FBC_CTL wants 64B units */ |
1088 | dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; | 1086 | dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; |
1089 | dev_priv->cfb_fence = obj_priv->fence_reg; | 1087 | dev_priv->cfb_fence = obj->fence_reg; |
1090 | dev_priv->cfb_plane = intel_crtc->plane; | 1088 | dev_priv->cfb_plane = intel_crtc->plane; |
1091 | plane = dev_priv->cfb_plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB; | 1089 | plane = dev_priv->cfb_plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB; |
1092 | 1090 | ||
@@ -1096,7 +1094,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1096 | 1094 | ||
1097 | /* Set it up... */ | 1095 | /* Set it up... */ |
1098 | fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | plane; | 1096 | fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | plane; |
1099 | if (obj_priv->tiling_mode != I915_TILING_NONE) | 1097 | if (obj->tiling_mode != I915_TILING_NONE) |
1100 | fbc_ctl2 |= FBC_CTL_CPU_FENCE; | 1098 | fbc_ctl2 |= FBC_CTL_CPU_FENCE; |
1101 | I915_WRITE(FBC_CONTROL2, fbc_ctl2); | 1099 | I915_WRITE(FBC_CONTROL2, fbc_ctl2); |
1102 | I915_WRITE(FBC_FENCE_OFF, crtc->y); | 1100 | I915_WRITE(FBC_FENCE_OFF, crtc->y); |
@@ -1107,7 +1105,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1107 | fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */ | 1105 | fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */ |
1108 | fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; | 1106 | fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; |
1109 | fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT; | 1107 | fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT; |
1110 | if (obj_priv->tiling_mode != I915_TILING_NONE) | 1108 | if (obj->tiling_mode != I915_TILING_NONE) |
1111 | fbc_ctl |= dev_priv->cfb_fence; | 1109 | fbc_ctl |= dev_priv->cfb_fence; |
1112 | I915_WRITE(FBC_CONTROL, fbc_ctl); | 1110 | I915_WRITE(FBC_CONTROL, fbc_ctl); |
1113 | 1111 | ||
@@ -1150,7 +1148,7 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1150 | struct drm_i915_private *dev_priv = dev->dev_private; | 1148 | struct drm_i915_private *dev_priv = dev->dev_private; |
1151 | struct drm_framebuffer *fb = crtc->fb; | 1149 | struct drm_framebuffer *fb = crtc->fb; |
1152 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | 1150 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
1153 | struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); | 1151 | struct drm_i915_gem_object *obj = intel_fb->obj; |
1154 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1152 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1155 | int plane = intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB; | 1153 | int plane = intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB; |
1156 | unsigned long stall_watermark = 200; | 1154 | unsigned long stall_watermark = 200; |
@@ -1159,7 +1157,7 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1159 | dpfc_ctl = I915_READ(DPFC_CONTROL); | 1157 | dpfc_ctl = I915_READ(DPFC_CONTROL); |
1160 | if (dpfc_ctl & DPFC_CTL_EN) { | 1158 | if (dpfc_ctl & DPFC_CTL_EN) { |
1161 | if (dev_priv->cfb_pitch == dev_priv->cfb_pitch / 64 - 1 && | 1159 | if (dev_priv->cfb_pitch == dev_priv->cfb_pitch / 64 - 1 && |
1162 | dev_priv->cfb_fence == obj_priv->fence_reg && | 1160 | dev_priv->cfb_fence == obj->fence_reg && |
1163 | dev_priv->cfb_plane == intel_crtc->plane && | 1161 | dev_priv->cfb_plane == intel_crtc->plane && |
1164 | dev_priv->cfb_y == crtc->y) | 1162 | dev_priv->cfb_y == crtc->y) |
1165 | return; | 1163 | return; |
@@ -1170,12 +1168,12 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1170 | } | 1168 | } |
1171 | 1169 | ||
1172 | dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; | 1170 | dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; |
1173 | dev_priv->cfb_fence = obj_priv->fence_reg; | 1171 | dev_priv->cfb_fence = obj->fence_reg; |
1174 | dev_priv->cfb_plane = intel_crtc->plane; | 1172 | dev_priv->cfb_plane = intel_crtc->plane; |
1175 | dev_priv->cfb_y = crtc->y; | 1173 | dev_priv->cfb_y = crtc->y; |
1176 | 1174 | ||
1177 | dpfc_ctl = plane | DPFC_SR_EN | DPFC_CTL_LIMIT_1X; | 1175 | dpfc_ctl = plane | DPFC_SR_EN | DPFC_CTL_LIMIT_1X; |
1178 | if (obj_priv->tiling_mode != I915_TILING_NONE) { | 1176 | if (obj->tiling_mode != I915_TILING_NONE) { |
1179 | dpfc_ctl |= DPFC_CTL_FENCE_EN | dev_priv->cfb_fence; | 1177 | dpfc_ctl |= DPFC_CTL_FENCE_EN | dev_priv->cfb_fence; |
1180 | I915_WRITE(DPFC_CHICKEN, DPFC_HT_MODIFY); | 1178 | I915_WRITE(DPFC_CHICKEN, DPFC_HT_MODIFY); |
1181 | } else { | 1179 | } else { |
@@ -1221,7 +1219,7 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1221 | struct drm_i915_private *dev_priv = dev->dev_private; | 1219 | struct drm_i915_private *dev_priv = dev->dev_private; |
1222 | struct drm_framebuffer *fb = crtc->fb; | 1220 | struct drm_framebuffer *fb = crtc->fb; |
1223 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | 1221 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
1224 | struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); | 1222 | struct drm_i915_gem_object *obj = intel_fb->obj; |
1225 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1223 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1226 | int plane = intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB; | 1224 | int plane = intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB; |
1227 | unsigned long stall_watermark = 200; | 1225 | unsigned long stall_watermark = 200; |
@@ -1230,9 +1228,9 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1230 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); | 1228 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); |
1231 | if (dpfc_ctl & DPFC_CTL_EN) { | 1229 | if (dpfc_ctl & DPFC_CTL_EN) { |
1232 | if (dev_priv->cfb_pitch == dev_priv->cfb_pitch / 64 - 1 && | 1230 | if (dev_priv->cfb_pitch == dev_priv->cfb_pitch / 64 - 1 && |
1233 | dev_priv->cfb_fence == obj_priv->fence_reg && | 1231 | dev_priv->cfb_fence == obj->fence_reg && |
1234 | dev_priv->cfb_plane == intel_crtc->plane && | 1232 | dev_priv->cfb_plane == intel_crtc->plane && |
1235 | dev_priv->cfb_offset == obj_priv->gtt_offset && | 1233 | dev_priv->cfb_offset == obj->gtt_offset && |
1236 | dev_priv->cfb_y == crtc->y) | 1234 | dev_priv->cfb_y == crtc->y) |
1237 | return; | 1235 | return; |
1238 | 1236 | ||
@@ -1242,14 +1240,14 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1242 | } | 1240 | } |
1243 | 1241 | ||
1244 | dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; | 1242 | dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; |
1245 | dev_priv->cfb_fence = obj_priv->fence_reg; | 1243 | dev_priv->cfb_fence = obj->fence_reg; |
1246 | dev_priv->cfb_plane = intel_crtc->plane; | 1244 | dev_priv->cfb_plane = intel_crtc->plane; |
1247 | dev_priv->cfb_offset = obj_priv->gtt_offset; | 1245 | dev_priv->cfb_offset = obj->gtt_offset; |
1248 | dev_priv->cfb_y = crtc->y; | 1246 | dev_priv->cfb_y = crtc->y; |
1249 | 1247 | ||
1250 | dpfc_ctl &= DPFC_RESERVED; | 1248 | dpfc_ctl &= DPFC_RESERVED; |
1251 | dpfc_ctl |= (plane | DPFC_CTL_LIMIT_1X); | 1249 | dpfc_ctl |= (plane | DPFC_CTL_LIMIT_1X); |
1252 | if (obj_priv->tiling_mode != I915_TILING_NONE) { | 1250 | if (obj->tiling_mode != I915_TILING_NONE) { |
1253 | dpfc_ctl |= (DPFC_CTL_FENCE_EN | dev_priv->cfb_fence); | 1251 | dpfc_ctl |= (DPFC_CTL_FENCE_EN | dev_priv->cfb_fence); |
1254 | I915_WRITE(ILK_DPFC_CHICKEN, DPFC_HT_MODIFY); | 1252 | I915_WRITE(ILK_DPFC_CHICKEN, DPFC_HT_MODIFY); |
1255 | } else { | 1253 | } else { |
@@ -1260,10 +1258,16 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1260 | (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | | 1258 | (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | |
1261 | (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); | 1259 | (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); |
1262 | I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y); | 1260 | I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y); |
1263 | I915_WRITE(ILK_FBC_RT_BASE, obj_priv->gtt_offset | ILK_FBC_RT_VALID); | 1261 | I915_WRITE(ILK_FBC_RT_BASE, obj->gtt_offset | ILK_FBC_RT_VALID); |
1264 | /* enable it... */ | 1262 | /* enable it... */ |
1265 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); | 1263 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); |
1266 | 1264 | ||
1265 | if (IS_GEN6(dev)) { | ||
1266 | I915_WRITE(SNB_DPFC_CTL_SA, | ||
1267 | SNB_CPU_FENCE_ENABLE | dev_priv->cfb_fence); | ||
1268 | I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y); | ||
1269 | } | ||
1270 | |||
1267 | DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); | 1271 | DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); |
1268 | } | 1272 | } |
1269 | 1273 | ||
@@ -1345,7 +1349,7 @@ static void intel_update_fbc(struct drm_device *dev) | |||
1345 | struct intel_crtc *intel_crtc; | 1349 | struct intel_crtc *intel_crtc; |
1346 | struct drm_framebuffer *fb; | 1350 | struct drm_framebuffer *fb; |
1347 | struct intel_framebuffer *intel_fb; | 1351 | struct intel_framebuffer *intel_fb; |
1348 | struct drm_i915_gem_object *obj_priv; | 1352 | struct drm_i915_gem_object *obj; |
1349 | 1353 | ||
1350 | DRM_DEBUG_KMS("\n"); | 1354 | DRM_DEBUG_KMS("\n"); |
1351 | 1355 | ||
@@ -1384,9 +1388,9 @@ static void intel_update_fbc(struct drm_device *dev) | |||
1384 | intel_crtc = to_intel_crtc(crtc); | 1388 | intel_crtc = to_intel_crtc(crtc); |
1385 | fb = crtc->fb; | 1389 | fb = crtc->fb; |
1386 | intel_fb = to_intel_framebuffer(fb); | 1390 | intel_fb = to_intel_framebuffer(fb); |
1387 | obj_priv = to_intel_bo(intel_fb->obj); | 1391 | obj = intel_fb->obj; |
1388 | 1392 | ||
1389 | if (intel_fb->obj->size > dev_priv->cfb_size) { | 1393 | if (intel_fb->obj->base.size > dev_priv->cfb_size) { |
1390 | DRM_DEBUG_KMS("framebuffer too large, disabling " | 1394 | DRM_DEBUG_KMS("framebuffer too large, disabling " |
1391 | "compression\n"); | 1395 | "compression\n"); |
1392 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; | 1396 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; |
@@ -1410,7 +1414,7 @@ static void intel_update_fbc(struct drm_device *dev) | |||
1410 | dev_priv->no_fbc_reason = FBC_BAD_PLANE; | 1414 | dev_priv->no_fbc_reason = FBC_BAD_PLANE; |
1411 | goto out_disable; | 1415 | goto out_disable; |
1412 | } | 1416 | } |
1413 | if (obj_priv->tiling_mode != I915_TILING_X) { | 1417 | if (obj->tiling_mode != I915_TILING_X) { |
1414 | DRM_DEBUG_KMS("framebuffer not tiled, disabling compression\n"); | 1418 | DRM_DEBUG_KMS("framebuffer not tiled, disabling compression\n"); |
1415 | dev_priv->no_fbc_reason = FBC_NOT_TILED; | 1419 | dev_priv->no_fbc_reason = FBC_NOT_TILED; |
1416 | goto out_disable; | 1420 | goto out_disable; |
@@ -1433,14 +1437,13 @@ out_disable: | |||
1433 | 1437 | ||
1434 | int | 1438 | int |
1435 | intel_pin_and_fence_fb_obj(struct drm_device *dev, | 1439 | intel_pin_and_fence_fb_obj(struct drm_device *dev, |
1436 | struct drm_gem_object *obj, | 1440 | struct drm_i915_gem_object *obj, |
1437 | bool pipelined) | 1441 | struct intel_ring_buffer *pipelined) |
1438 | { | 1442 | { |
1439 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
1440 | u32 alignment; | 1443 | u32 alignment; |
1441 | int ret; | 1444 | int ret; |
1442 | 1445 | ||
1443 | switch (obj_priv->tiling_mode) { | 1446 | switch (obj->tiling_mode) { |
1444 | case I915_TILING_NONE: | 1447 | case I915_TILING_NONE: |
1445 | if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) | 1448 | if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) |
1446 | alignment = 128 * 1024; | 1449 | alignment = 128 * 1024; |
@@ -1461,7 +1464,7 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, | |||
1461 | BUG(); | 1464 | BUG(); |
1462 | } | 1465 | } |
1463 | 1466 | ||
1464 | ret = i915_gem_object_pin(obj, alignment); | 1467 | ret = i915_gem_object_pin(obj, alignment, true); |
1465 | if (ret) | 1468 | if (ret) |
1466 | return ret; | 1469 | return ret; |
1467 | 1470 | ||
@@ -1474,9 +1477,8 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, | |||
1474 | * framebuffer compression. For simplicity, we always install | 1477 | * framebuffer compression. For simplicity, we always install |
1475 | * a fence as the cost is not that onerous. | 1478 | * a fence as the cost is not that onerous. |
1476 | */ | 1479 | */ |
1477 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE && | 1480 | if (obj->tiling_mode != I915_TILING_NONE) { |
1478 | obj_priv->tiling_mode != I915_TILING_NONE) { | 1481 | ret = i915_gem_object_get_fence(obj, pipelined, false); |
1479 | ret = i915_gem_object_get_fence_reg(obj, false); | ||
1480 | if (ret) | 1482 | if (ret) |
1481 | goto err_unpin; | 1483 | goto err_unpin; |
1482 | } | 1484 | } |
@@ -1497,8 +1499,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
1497 | struct drm_i915_private *dev_priv = dev->dev_private; | 1499 | struct drm_i915_private *dev_priv = dev->dev_private; |
1498 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1500 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1499 | struct intel_framebuffer *intel_fb; | 1501 | struct intel_framebuffer *intel_fb; |
1500 | struct drm_i915_gem_object *obj_priv; | 1502 | struct drm_i915_gem_object *obj; |
1501 | struct drm_gem_object *obj; | ||
1502 | int plane = intel_crtc->plane; | 1503 | int plane = intel_crtc->plane; |
1503 | unsigned long Start, Offset; | 1504 | unsigned long Start, Offset; |
1504 | u32 dspcntr; | 1505 | u32 dspcntr; |
@@ -1515,7 +1516,6 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
1515 | 1516 | ||
1516 | intel_fb = to_intel_framebuffer(fb); | 1517 | intel_fb = to_intel_framebuffer(fb); |
1517 | obj = intel_fb->obj; | 1518 | obj = intel_fb->obj; |
1518 | obj_priv = to_intel_bo(obj); | ||
1519 | 1519 | ||
1520 | reg = DSPCNTR(plane); | 1520 | reg = DSPCNTR(plane); |
1521 | dspcntr = I915_READ(reg); | 1521 | dspcntr = I915_READ(reg); |
@@ -1540,7 +1540,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
1540 | return -EINVAL; | 1540 | return -EINVAL; |
1541 | } | 1541 | } |
1542 | if (INTEL_INFO(dev)->gen >= 4) { | 1542 | if (INTEL_INFO(dev)->gen >= 4) { |
1543 | if (obj_priv->tiling_mode != I915_TILING_NONE) | 1543 | if (obj->tiling_mode != I915_TILING_NONE) |
1544 | dspcntr |= DISPPLANE_TILED; | 1544 | dspcntr |= DISPPLANE_TILED; |
1545 | else | 1545 | else |
1546 | dspcntr &= ~DISPPLANE_TILED; | 1546 | dspcntr &= ~DISPPLANE_TILED; |
@@ -1552,7 +1552,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
1552 | 1552 | ||
1553 | I915_WRITE(reg, dspcntr); | 1553 | I915_WRITE(reg, dspcntr); |
1554 | 1554 | ||
1555 | Start = obj_priv->gtt_offset; | 1555 | Start = obj->gtt_offset; |
1556 | Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8); | 1556 | Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8); |
1557 | 1557 | ||
1558 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", | 1558 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", |
@@ -1598,7 +1598,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1598 | mutex_lock(&dev->struct_mutex); | 1598 | mutex_lock(&dev->struct_mutex); |
1599 | ret = intel_pin_and_fence_fb_obj(dev, | 1599 | ret = intel_pin_and_fence_fb_obj(dev, |
1600 | to_intel_framebuffer(crtc->fb)->obj, | 1600 | to_intel_framebuffer(crtc->fb)->obj, |
1601 | false); | 1601 | NULL); |
1602 | if (ret != 0) { | 1602 | if (ret != 0) { |
1603 | mutex_unlock(&dev->struct_mutex); | 1603 | mutex_unlock(&dev->struct_mutex); |
1604 | return ret; | 1604 | return ret; |
@@ -1606,18 +1606,17 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1606 | 1606 | ||
1607 | if (old_fb) { | 1607 | if (old_fb) { |
1608 | struct drm_i915_private *dev_priv = dev->dev_private; | 1608 | struct drm_i915_private *dev_priv = dev->dev_private; |
1609 | struct drm_gem_object *obj = to_intel_framebuffer(old_fb)->obj; | 1609 | struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj; |
1610 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
1611 | 1610 | ||
1612 | wait_event(dev_priv->pending_flip_queue, | 1611 | wait_event(dev_priv->pending_flip_queue, |
1613 | atomic_read(&obj_priv->pending_flip) == 0); | 1612 | atomic_read(&obj->pending_flip) == 0); |
1614 | 1613 | ||
1615 | /* Big Hammer, we also need to ensure that any pending | 1614 | /* Big Hammer, we also need to ensure that any pending |
1616 | * MI_WAIT_FOR_EVENT inside a user batch buffer on the | 1615 | * MI_WAIT_FOR_EVENT inside a user batch buffer on the |
1617 | * current scanout is retired before unpinning the old | 1616 | * current scanout is retired before unpinning the old |
1618 | * framebuffer. | 1617 | * framebuffer. |
1619 | */ | 1618 | */ |
1620 | ret = i915_gem_object_flush_gpu(obj_priv, false); | 1619 | ret = i915_gem_object_flush_gpu(obj, false); |
1621 | if (ret) { | 1620 | if (ret) { |
1622 | i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); | 1621 | i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); |
1623 | mutex_unlock(&dev->struct_mutex); | 1622 | mutex_unlock(&dev->struct_mutex); |
@@ -1633,8 +1632,10 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1633 | return ret; | 1632 | return ret; |
1634 | } | 1633 | } |
1635 | 1634 | ||
1636 | if (old_fb) | 1635 | if (old_fb) { |
1636 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
1637 | i915_gem_object_unpin(to_intel_framebuffer(old_fb)->obj); | 1637 | i915_gem_object_unpin(to_intel_framebuffer(old_fb)->obj); |
1638 | } | ||
1638 | 1639 | ||
1639 | mutex_unlock(&dev->struct_mutex); | 1640 | mutex_unlock(&dev->struct_mutex); |
1640 | 1641 | ||
@@ -1996,31 +1997,31 @@ static void intel_flush_display_plane(struct drm_device *dev, | |||
1996 | static void intel_clear_scanline_wait(struct drm_device *dev) | 1997 | static void intel_clear_scanline_wait(struct drm_device *dev) |
1997 | { | 1998 | { |
1998 | struct drm_i915_private *dev_priv = dev->dev_private; | 1999 | struct drm_i915_private *dev_priv = dev->dev_private; |
2000 | struct intel_ring_buffer *ring; | ||
1999 | u32 tmp; | 2001 | u32 tmp; |
2000 | 2002 | ||
2001 | if (IS_GEN2(dev)) | 2003 | if (IS_GEN2(dev)) |
2002 | /* Can't break the hang on i8xx */ | 2004 | /* Can't break the hang on i8xx */ |
2003 | return; | 2005 | return; |
2004 | 2006 | ||
2005 | tmp = I915_READ(PRB0_CTL); | 2007 | ring = LP_RING(dev_priv); |
2006 | if (tmp & RING_WAIT) { | 2008 | tmp = I915_READ_CTL(ring); |
2007 | I915_WRITE(PRB0_CTL, tmp); | 2009 | if (tmp & RING_WAIT) |
2008 | POSTING_READ(PRB0_CTL); | 2010 | I915_WRITE_CTL(ring, tmp); |
2009 | } | ||
2010 | } | 2011 | } |
2011 | 2012 | ||
2012 | static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) | 2013 | static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) |
2013 | { | 2014 | { |
2014 | struct drm_i915_gem_object *obj_priv; | 2015 | struct drm_i915_gem_object *obj; |
2015 | struct drm_i915_private *dev_priv; | 2016 | struct drm_i915_private *dev_priv; |
2016 | 2017 | ||
2017 | if (crtc->fb == NULL) | 2018 | if (crtc->fb == NULL) |
2018 | return; | 2019 | return; |
2019 | 2020 | ||
2020 | obj_priv = to_intel_bo(to_intel_framebuffer(crtc->fb)->obj); | 2021 | obj = to_intel_framebuffer(crtc->fb)->obj; |
2021 | dev_priv = crtc->dev->dev_private; | 2022 | dev_priv = crtc->dev->dev_private; |
2022 | wait_event(dev_priv->pending_flip_queue, | 2023 | wait_event(dev_priv->pending_flip_queue, |
2023 | atomic_read(&obj_priv->pending_flip) == 0); | 2024 | atomic_read(&obj->pending_flip) == 0); |
2024 | } | 2025 | } |
2025 | 2026 | ||
2026 | static void ironlake_crtc_enable(struct drm_crtc *crtc) | 2027 | static void ironlake_crtc_enable(struct drm_crtc *crtc) |
@@ -2120,9 +2121,11 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) | |||
2120 | reg = TRANS_DP_CTL(pipe); | 2121 | reg = TRANS_DP_CTL(pipe); |
2121 | temp = I915_READ(reg); | 2122 | temp = I915_READ(reg); |
2122 | temp &= ~(TRANS_DP_PORT_SEL_MASK | | 2123 | temp &= ~(TRANS_DP_PORT_SEL_MASK | |
2123 | TRANS_DP_SYNC_MASK); | 2124 | TRANS_DP_SYNC_MASK | |
2125 | TRANS_DP_BPC_MASK); | ||
2124 | temp |= (TRANS_DP_OUTPUT_ENABLE | | 2126 | temp |= (TRANS_DP_OUTPUT_ENABLE | |
2125 | TRANS_DP_ENH_FRAMING); | 2127 | TRANS_DP_ENH_FRAMING); |
2128 | temp |= TRANS_DP_8BPC; | ||
2126 | 2129 | ||
2127 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) | 2130 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) |
2128 | temp |= TRANS_DP_HSYNC_ACTIVE_HIGH; | 2131 | temp |= TRANS_DP_HSYNC_ACTIVE_HIGH; |
@@ -2712,27 +2715,19 @@ fdi_reduce_ratio(u32 *num, u32 *den) | |||
2712 | } | 2715 | } |
2713 | } | 2716 | } |
2714 | 2717 | ||
2715 | #define DATA_N 0x800000 | ||
2716 | #define LINK_N 0x80000 | ||
2717 | |||
2718 | static void | 2718 | static void |
2719 | ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock, | 2719 | ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock, |
2720 | int link_clock, struct fdi_m_n *m_n) | 2720 | int link_clock, struct fdi_m_n *m_n) |
2721 | { | 2721 | { |
2722 | u64 temp; | ||
2723 | |||
2724 | m_n->tu = 64; /* default size */ | 2722 | m_n->tu = 64; /* default size */ |
2725 | 2723 | ||
2726 | temp = (u64) DATA_N * pixel_clock; | 2724 | /* BUG_ON(pixel_clock > INT_MAX / 36); */ |
2727 | temp = div_u64(temp, link_clock); | 2725 | m_n->gmch_m = bits_per_pixel * pixel_clock; |
2728 | m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes); | 2726 | m_n->gmch_n = link_clock * nlanes * 8; |
2729 | m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */ | ||
2730 | m_n->gmch_n = DATA_N; | ||
2731 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); | 2727 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); |
2732 | 2728 | ||
2733 | temp = (u64) LINK_N * pixel_clock; | 2729 | m_n->link_m = pixel_clock; |
2734 | m_n->link_m = div_u64(temp, link_clock); | 2730 | m_n->link_n = link_clock; |
2735 | m_n->link_n = LINK_N; | ||
2736 | fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); | 2731 | fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); |
2737 | } | 2732 | } |
2738 | 2733 | ||
@@ -2856,6 +2851,39 @@ static struct intel_watermark_params ironlake_cursor_srwm_info = { | |||
2856 | ILK_FIFO_LINE_SIZE | 2851 | ILK_FIFO_LINE_SIZE |
2857 | }; | 2852 | }; |
2858 | 2853 | ||
2854 | static struct intel_watermark_params sandybridge_display_wm_info = { | ||
2855 | SNB_DISPLAY_FIFO, | ||
2856 | SNB_DISPLAY_MAXWM, | ||
2857 | SNB_DISPLAY_DFTWM, | ||
2858 | 2, | ||
2859 | SNB_FIFO_LINE_SIZE | ||
2860 | }; | ||
2861 | |||
2862 | static struct intel_watermark_params sandybridge_cursor_wm_info = { | ||
2863 | SNB_CURSOR_FIFO, | ||
2864 | SNB_CURSOR_MAXWM, | ||
2865 | SNB_CURSOR_DFTWM, | ||
2866 | 2, | ||
2867 | SNB_FIFO_LINE_SIZE | ||
2868 | }; | ||
2869 | |||
2870 | static struct intel_watermark_params sandybridge_display_srwm_info = { | ||
2871 | SNB_DISPLAY_SR_FIFO, | ||
2872 | SNB_DISPLAY_MAX_SRWM, | ||
2873 | SNB_DISPLAY_DFT_SRWM, | ||
2874 | 2, | ||
2875 | SNB_FIFO_LINE_SIZE | ||
2876 | }; | ||
2877 | |||
2878 | static struct intel_watermark_params sandybridge_cursor_srwm_info = { | ||
2879 | SNB_CURSOR_SR_FIFO, | ||
2880 | SNB_CURSOR_MAX_SRWM, | ||
2881 | SNB_CURSOR_DFT_SRWM, | ||
2882 | 2, | ||
2883 | SNB_FIFO_LINE_SIZE | ||
2884 | }; | ||
2885 | |||
2886 | |||
2859 | /** | 2887 | /** |
2860 | * intel_calculate_wm - calculate watermark level | 2888 | * intel_calculate_wm - calculate watermark level |
2861 | * @clock_in_khz: pixel clock | 2889 | * @clock_in_khz: pixel clock |
@@ -3389,6 +3417,10 @@ static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, | |||
3389 | 3417 | ||
3390 | static bool ironlake_compute_wm0(struct drm_device *dev, | 3418 | static bool ironlake_compute_wm0(struct drm_device *dev, |
3391 | int pipe, | 3419 | int pipe, |
3420 | const struct intel_watermark_params *display, | ||
3421 | int display_latency, | ||
3422 | const struct intel_watermark_params *cursor, | ||
3423 | int cursor_latency, | ||
3392 | int *plane_wm, | 3424 | int *plane_wm, |
3393 | int *cursor_wm) | 3425 | int *cursor_wm) |
3394 | { | 3426 | { |
@@ -3406,22 +3438,20 @@ static bool ironlake_compute_wm0(struct drm_device *dev, | |||
3406 | pixel_size = crtc->fb->bits_per_pixel / 8; | 3438 | pixel_size = crtc->fb->bits_per_pixel / 8; |
3407 | 3439 | ||
3408 | /* Use the small buffer method to calculate plane watermark */ | 3440 | /* Use the small buffer method to calculate plane watermark */ |
3409 | entries = ((clock * pixel_size / 1000) * ILK_LP0_PLANE_LATENCY) / 1000; | 3441 | entries = ((clock * pixel_size / 1000) * display_latency * 100) / 1000; |
3410 | entries = DIV_ROUND_UP(entries, | 3442 | entries = DIV_ROUND_UP(entries, display->cacheline_size); |
3411 | ironlake_display_wm_info.cacheline_size); | 3443 | *plane_wm = entries + display->guard_size; |
3412 | *plane_wm = entries + ironlake_display_wm_info.guard_size; | 3444 | if (*plane_wm > (int)display->max_wm) |
3413 | if (*plane_wm > (int)ironlake_display_wm_info.max_wm) | 3445 | *plane_wm = display->max_wm; |
3414 | *plane_wm = ironlake_display_wm_info.max_wm; | ||
3415 | 3446 | ||
3416 | /* Use the large buffer method to calculate cursor watermark */ | 3447 | /* Use the large buffer method to calculate cursor watermark */ |
3417 | line_time_us = ((htotal * 1000) / clock); | 3448 | line_time_us = ((htotal * 1000) / clock); |
3418 | line_count = (ILK_LP0_CURSOR_LATENCY / line_time_us + 1000) / 1000; | 3449 | line_count = (cursor_latency * 100 / line_time_us + 1000) / 1000; |
3419 | entries = line_count * 64 * pixel_size; | 3450 | entries = line_count * 64 * pixel_size; |
3420 | entries = DIV_ROUND_UP(entries, | 3451 | entries = DIV_ROUND_UP(entries, cursor->cacheline_size); |
3421 | ironlake_cursor_wm_info.cacheline_size); | 3452 | *cursor_wm = entries + cursor->guard_size; |
3422 | *cursor_wm = entries + ironlake_cursor_wm_info.guard_size; | 3453 | if (*cursor_wm > (int)cursor->max_wm) |
3423 | if (*cursor_wm > ironlake_cursor_wm_info.max_wm) | 3454 | *cursor_wm = (int)cursor->max_wm; |
3424 | *cursor_wm = ironlake_cursor_wm_info.max_wm; | ||
3425 | 3455 | ||
3426 | return true; | 3456 | return true; |
3427 | } | 3457 | } |
@@ -3436,7 +3466,12 @@ static void ironlake_update_wm(struct drm_device *dev, | |||
3436 | int tmp; | 3466 | int tmp; |
3437 | 3467 | ||
3438 | enabled = 0; | 3468 | enabled = 0; |
3439 | if (ironlake_compute_wm0(dev, 0, &plane_wm, &cursor_wm)) { | 3469 | if (ironlake_compute_wm0(dev, 0, |
3470 | &ironlake_display_wm_info, | ||
3471 | ILK_LP0_PLANE_LATENCY, | ||
3472 | &ironlake_cursor_wm_info, | ||
3473 | ILK_LP0_CURSOR_LATENCY, | ||
3474 | &plane_wm, &cursor_wm)) { | ||
3440 | I915_WRITE(WM0_PIPEA_ILK, | 3475 | I915_WRITE(WM0_PIPEA_ILK, |
3441 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | 3476 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); |
3442 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | 3477 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" |
@@ -3445,7 +3480,12 @@ static void ironlake_update_wm(struct drm_device *dev, | |||
3445 | enabled++; | 3480 | enabled++; |
3446 | } | 3481 | } |
3447 | 3482 | ||
3448 | if (ironlake_compute_wm0(dev, 1, &plane_wm, &cursor_wm)) { | 3483 | if (ironlake_compute_wm0(dev, 1, |
3484 | &ironlake_display_wm_info, | ||
3485 | ILK_LP0_PLANE_LATENCY, | ||
3486 | &ironlake_cursor_wm_info, | ||
3487 | ILK_LP0_CURSOR_LATENCY, | ||
3488 | &plane_wm, &cursor_wm)) { | ||
3449 | I915_WRITE(WM0_PIPEB_ILK, | 3489 | I915_WRITE(WM0_PIPEB_ILK, |
3450 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | 3490 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); |
3451 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | 3491 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" |
@@ -3459,7 +3499,7 @@ static void ironlake_update_wm(struct drm_device *dev, | |||
3459 | * display plane is used. | 3499 | * display plane is used. |
3460 | */ | 3500 | */ |
3461 | tmp = 0; | 3501 | tmp = 0; |
3462 | if (enabled == 1 && /* XXX disabled due to buggy implmentation? */ 0) { | 3502 | if (enabled == 1) { |
3463 | unsigned long line_time_us; | 3503 | unsigned long line_time_us; |
3464 | int small, large, plane_fbc; | 3504 | int small, large, plane_fbc; |
3465 | int sr_clock, entries; | 3505 | int sr_clock, entries; |
@@ -3511,6 +3551,197 @@ static void ironlake_update_wm(struct drm_device *dev, | |||
3511 | /* XXX setup WM2 and WM3 */ | 3551 | /* XXX setup WM2 and WM3 */ |
3512 | } | 3552 | } |
3513 | 3553 | ||
3554 | /* | ||
3555 | * Check the wm result. | ||
3556 | * | ||
3557 | * If any calculated watermark values is larger than the maximum value that | ||
3558 | * can be programmed into the associated watermark register, that watermark | ||
3559 | * must be disabled. | ||
3560 | * | ||
3561 | * Also return true if all of those watermark values is 0, which is set by | ||
3562 | * sandybridge_compute_srwm, to indicate the latency is ZERO. | ||
3563 | */ | ||
3564 | static bool sandybridge_check_srwm(struct drm_device *dev, int level, | ||
3565 | int fbc_wm, int display_wm, int cursor_wm) | ||
3566 | { | ||
3567 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3568 | |||
3569 | DRM_DEBUG_KMS("watermark %d: display plane %d, fbc lines %d," | ||
3570 | " cursor %d\n", level, display_wm, fbc_wm, cursor_wm); | ||
3571 | |||
3572 | if (fbc_wm > SNB_FBC_MAX_SRWM) { | ||
3573 | DRM_DEBUG_KMS("fbc watermark(%d) is too large(%d), disabling wm%d+\n", | ||
3574 | fbc_wm, SNB_FBC_MAX_SRWM, level); | ||
3575 | |||
3576 | /* fbc has it's own way to disable FBC WM */ | ||
3577 | I915_WRITE(DISP_ARB_CTL, | ||
3578 | I915_READ(DISP_ARB_CTL) | DISP_FBC_WM_DIS); | ||
3579 | return false; | ||
3580 | } | ||
3581 | |||
3582 | if (display_wm > SNB_DISPLAY_MAX_SRWM) { | ||
3583 | DRM_DEBUG_KMS("display watermark(%d) is too large(%d), disabling wm%d+\n", | ||
3584 | display_wm, SNB_DISPLAY_MAX_SRWM, level); | ||
3585 | return false; | ||
3586 | } | ||
3587 | |||
3588 | if (cursor_wm > SNB_CURSOR_MAX_SRWM) { | ||
3589 | DRM_DEBUG_KMS("cursor watermark(%d) is too large(%d), disabling wm%d+\n", | ||
3590 | cursor_wm, SNB_CURSOR_MAX_SRWM, level); | ||
3591 | return false; | ||
3592 | } | ||
3593 | |||
3594 | if (!(fbc_wm || display_wm || cursor_wm)) { | ||
3595 | DRM_DEBUG_KMS("latency %d is 0, disabling wm%d+\n", level, level); | ||
3596 | return false; | ||
3597 | } | ||
3598 | |||
3599 | return true; | ||
3600 | } | ||
3601 | |||
3602 | /* | ||
3603 | * Compute watermark values of WM[1-3], | ||
3604 | */ | ||
3605 | static bool sandybridge_compute_srwm(struct drm_device *dev, int level, | ||
3606 | int hdisplay, int htotal, int pixel_size, | ||
3607 | int clock, int latency_ns, int *fbc_wm, | ||
3608 | int *display_wm, int *cursor_wm) | ||
3609 | { | ||
3610 | |||
3611 | unsigned long line_time_us; | ||
3612 | int small, large; | ||
3613 | int entries; | ||
3614 | int line_count, line_size; | ||
3615 | |||
3616 | if (!latency_ns) { | ||
3617 | *fbc_wm = *display_wm = *cursor_wm = 0; | ||
3618 | return false; | ||
3619 | } | ||
3620 | |||
3621 | line_time_us = (htotal * 1000) / clock; | ||
3622 | line_count = (latency_ns / line_time_us + 1000) / 1000; | ||
3623 | line_size = hdisplay * pixel_size; | ||
3624 | |||
3625 | /* Use the minimum of the small and large buffer method for primary */ | ||
3626 | small = ((clock * pixel_size / 1000) * latency_ns) / 1000; | ||
3627 | large = line_count * line_size; | ||
3628 | |||
3629 | entries = DIV_ROUND_UP(min(small, large), | ||
3630 | sandybridge_display_srwm_info.cacheline_size); | ||
3631 | *display_wm = entries + sandybridge_display_srwm_info.guard_size; | ||
3632 | |||
3633 | /* | ||
3634 | * Spec said: | ||
3635 | * FBC WM = ((Final Primary WM * 64) / number of bytes per line) + 2 | ||
3636 | */ | ||
3637 | *fbc_wm = DIV_ROUND_UP(*display_wm * 64, line_size) + 2; | ||
3638 | |||
3639 | /* calculate the self-refresh watermark for display cursor */ | ||
3640 | entries = line_count * pixel_size * 64; | ||
3641 | entries = DIV_ROUND_UP(entries, | ||
3642 | sandybridge_cursor_srwm_info.cacheline_size); | ||
3643 | *cursor_wm = entries + sandybridge_cursor_srwm_info.guard_size; | ||
3644 | |||
3645 | return sandybridge_check_srwm(dev, level, | ||
3646 | *fbc_wm, *display_wm, *cursor_wm); | ||
3647 | } | ||
3648 | |||
3649 | static void sandybridge_update_wm(struct drm_device *dev, | ||
3650 | int planea_clock, int planeb_clock, | ||
3651 | int hdisplay, int htotal, | ||
3652 | int pixel_size) | ||
3653 | { | ||
3654 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3655 | int latency = SNB_READ_WM0_LATENCY(); | ||
3656 | int fbc_wm, plane_wm, cursor_wm, enabled; | ||
3657 | int clock; | ||
3658 | |||
3659 | enabled = 0; | ||
3660 | if (ironlake_compute_wm0(dev, 0, | ||
3661 | &sandybridge_display_wm_info, latency, | ||
3662 | &sandybridge_cursor_wm_info, latency, | ||
3663 | &plane_wm, &cursor_wm)) { | ||
3664 | I915_WRITE(WM0_PIPEA_ILK, | ||
3665 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | ||
3666 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | ||
3667 | " plane %d, " "cursor: %d\n", | ||
3668 | plane_wm, cursor_wm); | ||
3669 | enabled++; | ||
3670 | } | ||
3671 | |||
3672 | if (ironlake_compute_wm0(dev, 1, | ||
3673 | &sandybridge_display_wm_info, latency, | ||
3674 | &sandybridge_cursor_wm_info, latency, | ||
3675 | &plane_wm, &cursor_wm)) { | ||
3676 | I915_WRITE(WM0_PIPEB_ILK, | ||
3677 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | ||
3678 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | ||
3679 | " plane %d, cursor: %d\n", | ||
3680 | plane_wm, cursor_wm); | ||
3681 | enabled++; | ||
3682 | } | ||
3683 | |||
3684 | /* | ||
3685 | * Calculate and update the self-refresh watermark only when one | ||
3686 | * display plane is used. | ||
3687 | * | ||
3688 | * SNB support 3 levels of watermark. | ||
3689 | * | ||
3690 | * WM1/WM2/WM2 watermarks have to be enabled in the ascending order, | ||
3691 | * and disabled in the descending order | ||
3692 | * | ||
3693 | */ | ||
3694 | I915_WRITE(WM3_LP_ILK, 0); | ||
3695 | I915_WRITE(WM2_LP_ILK, 0); | ||
3696 | I915_WRITE(WM1_LP_ILK, 0); | ||
3697 | |||
3698 | if (enabled != 1) | ||
3699 | return; | ||
3700 | |||
3701 | clock = planea_clock ? planea_clock : planeb_clock; | ||
3702 | |||
3703 | /* WM1 */ | ||
3704 | if (!sandybridge_compute_srwm(dev, 1, hdisplay, htotal, pixel_size, | ||
3705 | clock, SNB_READ_WM1_LATENCY() * 500, | ||
3706 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
3707 | return; | ||
3708 | |||
3709 | I915_WRITE(WM1_LP_ILK, | ||
3710 | WM1_LP_SR_EN | | ||
3711 | (SNB_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
3712 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
3713 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
3714 | cursor_wm); | ||
3715 | |||
3716 | /* WM2 */ | ||
3717 | if (!sandybridge_compute_srwm(dev, 2, | ||
3718 | hdisplay, htotal, pixel_size, | ||
3719 | clock, SNB_READ_WM2_LATENCY() * 500, | ||
3720 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
3721 | return; | ||
3722 | |||
3723 | I915_WRITE(WM2_LP_ILK, | ||
3724 | WM2_LP_EN | | ||
3725 | (SNB_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
3726 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
3727 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
3728 | cursor_wm); | ||
3729 | |||
3730 | /* WM3 */ | ||
3731 | if (!sandybridge_compute_srwm(dev, 3, | ||
3732 | hdisplay, htotal, pixel_size, | ||
3733 | clock, SNB_READ_WM3_LATENCY() * 500, | ||
3734 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
3735 | return; | ||
3736 | |||
3737 | I915_WRITE(WM3_LP_ILK, | ||
3738 | WM3_LP_EN | | ||
3739 | (SNB_READ_WM3_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
3740 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
3741 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
3742 | cursor_wm); | ||
3743 | } | ||
3744 | |||
3514 | /** | 3745 | /** |
3515 | * intel_update_watermarks - update FIFO watermark values based on current modes | 3746 | * intel_update_watermarks - update FIFO watermark values based on current modes |
3516 | * | 3747 | * |
@@ -3666,7 +3897,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3666 | * refclk, or FALSE. The returned values represent the clock equation: | 3897 | * refclk, or FALSE. The returned values represent the clock equation: |
3667 | * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. | 3898 | * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. |
3668 | */ | 3899 | */ |
3669 | limit = intel_limit(crtc); | 3900 | limit = intel_limit(crtc, refclk); |
3670 | ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock); | 3901 | ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock); |
3671 | if (!ok) { | 3902 | if (!ok) { |
3672 | DRM_ERROR("Couldn't find PLL settings for mode!\n"); | 3903 | DRM_ERROR("Couldn't find PLL settings for mode!\n"); |
@@ -3716,6 +3947,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3716 | 3947 | ||
3717 | /* FDI link */ | 3948 | /* FDI link */ |
3718 | if (HAS_PCH_SPLIT(dev)) { | 3949 | if (HAS_PCH_SPLIT(dev)) { |
3950 | int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); | ||
3719 | int lane = 0, link_bw, bpp; | 3951 | int lane = 0, link_bw, bpp; |
3720 | /* CPU eDP doesn't require FDI link, so just set DP M/N | 3952 | /* CPU eDP doesn't require FDI link, so just set DP M/N |
3721 | according to current link config */ | 3953 | according to current link config */ |
@@ -3799,6 +4031,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3799 | 4031 | ||
3800 | intel_crtc->fdi_lanes = lane; | 4032 | intel_crtc->fdi_lanes = lane; |
3801 | 4033 | ||
4034 | if (pixel_multiplier > 1) | ||
4035 | link_bw *= pixel_multiplier; | ||
3802 | ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); | 4036 | ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); |
3803 | } | 4037 | } |
3804 | 4038 | ||
@@ -3860,6 +4094,22 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3860 | reduced_clock.m2; | 4094 | reduced_clock.m2; |
3861 | } | 4095 | } |
3862 | 4096 | ||
4097 | /* Enable autotuning of the PLL clock (if permissible) */ | ||
4098 | if (HAS_PCH_SPLIT(dev)) { | ||
4099 | int factor = 21; | ||
4100 | |||
4101 | if (is_lvds) { | ||
4102 | if ((dev_priv->lvds_use_ssc && | ||
4103 | dev_priv->lvds_ssc_freq == 100) || | ||
4104 | (I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) | ||
4105 | factor = 25; | ||
4106 | } else if (is_sdvo && is_tv) | ||
4107 | factor = 20; | ||
4108 | |||
4109 | if (clock.m1 < factor * clock.n) | ||
4110 | fp |= FP_CB_TUNE; | ||
4111 | } | ||
4112 | |||
3863 | dpll = 0; | 4113 | dpll = 0; |
3864 | if (!HAS_PCH_SPLIT(dev)) | 4114 | if (!HAS_PCH_SPLIT(dev)) |
3865 | dpll = DPLL_VGA_MODE_DIS; | 4115 | dpll = DPLL_VGA_MODE_DIS; |
@@ -4074,7 +4324,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
4074 | } | 4324 | } |
4075 | 4325 | ||
4076 | if (!has_edp_encoder || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { | 4326 | if (!has_edp_encoder || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { |
4077 | I915_WRITE(fp_reg, fp); | ||
4078 | I915_WRITE(dpll_reg, dpll); | 4327 | I915_WRITE(dpll_reg, dpll); |
4079 | 4328 | ||
4080 | /* Wait for the clocks to stabilize. */ | 4329 | /* Wait for the clocks to stabilize. */ |
@@ -4092,13 +4341,13 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
4092 | } | 4341 | } |
4093 | I915_WRITE(DPLL_MD(pipe), temp); | 4342 | I915_WRITE(DPLL_MD(pipe), temp); |
4094 | } else { | 4343 | } else { |
4095 | /* write it again -- the BIOS does, after all */ | 4344 | /* The pixel multiplier can only be updated once the |
4345 | * DPLL is enabled and the clocks are stable. | ||
4346 | * | ||
4347 | * So write it again. | ||
4348 | */ | ||
4096 | I915_WRITE(dpll_reg, dpll); | 4349 | I915_WRITE(dpll_reg, dpll); |
4097 | } | 4350 | } |
4098 | |||
4099 | /* Wait for the clocks to stabilize. */ | ||
4100 | POSTING_READ(dpll_reg); | ||
4101 | udelay(150); | ||
4102 | } | 4351 | } |
4103 | 4352 | ||
4104 | intel_crtc->lowfreq_avail = false; | 4353 | intel_crtc->lowfreq_avail = false; |
@@ -4334,15 +4583,14 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, | |||
4334 | } | 4583 | } |
4335 | 4584 | ||
4336 | static int intel_crtc_cursor_set(struct drm_crtc *crtc, | 4585 | static int intel_crtc_cursor_set(struct drm_crtc *crtc, |
4337 | struct drm_file *file_priv, | 4586 | struct drm_file *file, |
4338 | uint32_t handle, | 4587 | uint32_t handle, |
4339 | uint32_t width, uint32_t height) | 4588 | uint32_t width, uint32_t height) |
4340 | { | 4589 | { |
4341 | struct drm_device *dev = crtc->dev; | 4590 | struct drm_device *dev = crtc->dev; |
4342 | struct drm_i915_private *dev_priv = dev->dev_private; | 4591 | struct drm_i915_private *dev_priv = dev->dev_private; |
4343 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 4592 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
4344 | struct drm_gem_object *bo; | 4593 | struct drm_i915_gem_object *obj; |
4345 | struct drm_i915_gem_object *obj_priv; | ||
4346 | uint32_t addr; | 4594 | uint32_t addr; |
4347 | int ret; | 4595 | int ret; |
4348 | 4596 | ||
@@ -4352,7 +4600,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
4352 | if (!handle) { | 4600 | if (!handle) { |
4353 | DRM_DEBUG_KMS("cursor off\n"); | 4601 | DRM_DEBUG_KMS("cursor off\n"); |
4354 | addr = 0; | 4602 | addr = 0; |
4355 | bo = NULL; | 4603 | obj = NULL; |
4356 | mutex_lock(&dev->struct_mutex); | 4604 | mutex_lock(&dev->struct_mutex); |
4357 | goto finish; | 4605 | goto finish; |
4358 | } | 4606 | } |
@@ -4363,13 +4611,11 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
4363 | return -EINVAL; | 4611 | return -EINVAL; |
4364 | } | 4612 | } |
4365 | 4613 | ||
4366 | bo = drm_gem_object_lookup(dev, file_priv, handle); | 4614 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle)); |
4367 | if (!bo) | 4615 | if (!obj) |
4368 | return -ENOENT; | 4616 | return -ENOENT; |
4369 | 4617 | ||
4370 | obj_priv = to_intel_bo(bo); | 4618 | if (obj->base.size < width * height * 4) { |
4371 | |||
4372 | if (bo->size < width * height * 4) { | ||
4373 | DRM_ERROR("buffer is to small\n"); | 4619 | DRM_ERROR("buffer is to small\n"); |
4374 | ret = -ENOMEM; | 4620 | ret = -ENOMEM; |
4375 | goto fail; | 4621 | goto fail; |
@@ -4378,29 +4624,41 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
4378 | /* we only need to pin inside GTT if cursor is non-phy */ | 4624 | /* we only need to pin inside GTT if cursor is non-phy */ |
4379 | mutex_lock(&dev->struct_mutex); | 4625 | mutex_lock(&dev->struct_mutex); |
4380 | if (!dev_priv->info->cursor_needs_physical) { | 4626 | if (!dev_priv->info->cursor_needs_physical) { |
4381 | ret = i915_gem_object_pin(bo, PAGE_SIZE); | 4627 | if (obj->tiling_mode) { |
4628 | DRM_ERROR("cursor cannot be tiled\n"); | ||
4629 | ret = -EINVAL; | ||
4630 | goto fail_locked; | ||
4631 | } | ||
4632 | |||
4633 | ret = i915_gem_object_pin(obj, PAGE_SIZE, true); | ||
4382 | if (ret) { | 4634 | if (ret) { |
4383 | DRM_ERROR("failed to pin cursor bo\n"); | 4635 | DRM_ERROR("failed to pin cursor bo\n"); |
4384 | goto fail_locked; | 4636 | goto fail_locked; |
4385 | } | 4637 | } |
4386 | 4638 | ||
4387 | ret = i915_gem_object_set_to_gtt_domain(bo, 0); | 4639 | ret = i915_gem_object_set_to_gtt_domain(obj, 0); |
4388 | if (ret) { | 4640 | if (ret) { |
4389 | DRM_ERROR("failed to move cursor bo into the GTT\n"); | 4641 | DRM_ERROR("failed to move cursor bo into the GTT\n"); |
4390 | goto fail_unpin; | 4642 | goto fail_unpin; |
4391 | } | 4643 | } |
4392 | 4644 | ||
4393 | addr = obj_priv->gtt_offset; | 4645 | ret = i915_gem_object_put_fence(obj); |
4646 | if (ret) { | ||
4647 | DRM_ERROR("failed to move cursor bo into the GTT\n"); | ||
4648 | goto fail_unpin; | ||
4649 | } | ||
4650 | |||
4651 | addr = obj->gtt_offset; | ||
4394 | } else { | 4652 | } else { |
4395 | int align = IS_I830(dev) ? 16 * 1024 : 256; | 4653 | int align = IS_I830(dev) ? 16 * 1024 : 256; |
4396 | ret = i915_gem_attach_phys_object(dev, bo, | 4654 | ret = i915_gem_attach_phys_object(dev, obj, |
4397 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1, | 4655 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1, |
4398 | align); | 4656 | align); |
4399 | if (ret) { | 4657 | if (ret) { |
4400 | DRM_ERROR("failed to attach phys object\n"); | 4658 | DRM_ERROR("failed to attach phys object\n"); |
4401 | goto fail_locked; | 4659 | goto fail_locked; |
4402 | } | 4660 | } |
4403 | addr = obj_priv->phys_obj->handle->busaddr; | 4661 | addr = obj->phys_obj->handle->busaddr; |
4404 | } | 4662 | } |
4405 | 4663 | ||
4406 | if (IS_GEN2(dev)) | 4664 | if (IS_GEN2(dev)) |
@@ -4409,17 +4667,17 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
4409 | finish: | 4667 | finish: |
4410 | if (intel_crtc->cursor_bo) { | 4668 | if (intel_crtc->cursor_bo) { |
4411 | if (dev_priv->info->cursor_needs_physical) { | 4669 | if (dev_priv->info->cursor_needs_physical) { |
4412 | if (intel_crtc->cursor_bo != bo) | 4670 | if (intel_crtc->cursor_bo != obj) |
4413 | i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); | 4671 | i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); |
4414 | } else | 4672 | } else |
4415 | i915_gem_object_unpin(intel_crtc->cursor_bo); | 4673 | i915_gem_object_unpin(intel_crtc->cursor_bo); |
4416 | drm_gem_object_unreference(intel_crtc->cursor_bo); | 4674 | drm_gem_object_unreference(&intel_crtc->cursor_bo->base); |
4417 | } | 4675 | } |
4418 | 4676 | ||
4419 | mutex_unlock(&dev->struct_mutex); | 4677 | mutex_unlock(&dev->struct_mutex); |
4420 | 4678 | ||
4421 | intel_crtc->cursor_addr = addr; | 4679 | intel_crtc->cursor_addr = addr; |
4422 | intel_crtc->cursor_bo = bo; | 4680 | intel_crtc->cursor_bo = obj; |
4423 | intel_crtc->cursor_width = width; | 4681 | intel_crtc->cursor_width = width; |
4424 | intel_crtc->cursor_height = height; | 4682 | intel_crtc->cursor_height = height; |
4425 | 4683 | ||
@@ -4427,11 +4685,11 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
4427 | 4685 | ||
4428 | return 0; | 4686 | return 0; |
4429 | fail_unpin: | 4687 | fail_unpin: |
4430 | i915_gem_object_unpin(bo); | 4688 | i915_gem_object_unpin(obj); |
4431 | fail_locked: | 4689 | fail_locked: |
4432 | mutex_unlock(&dev->struct_mutex); | 4690 | mutex_unlock(&dev->struct_mutex); |
4433 | fail: | 4691 | fail: |
4434 | drm_gem_object_unreference_unlocked(bo); | 4692 | drm_gem_object_unreference_unlocked(&obj->base); |
4435 | return ret; | 4693 | return ret; |
4436 | } | 4694 | } |
4437 | 4695 | ||
@@ -4742,8 +5000,14 @@ static void intel_gpu_idle_timer(unsigned long arg) | |||
4742 | struct drm_device *dev = (struct drm_device *)arg; | 5000 | struct drm_device *dev = (struct drm_device *)arg; |
4743 | drm_i915_private_t *dev_priv = dev->dev_private; | 5001 | drm_i915_private_t *dev_priv = dev->dev_private; |
4744 | 5002 | ||
4745 | dev_priv->busy = false; | 5003 | if (!list_empty(&dev_priv->mm.active_list)) { |
5004 | /* Still processing requests, so just re-arm the timer. */ | ||
5005 | mod_timer(&dev_priv->idle_timer, jiffies + | ||
5006 | msecs_to_jiffies(GPU_IDLE_TIMEOUT)); | ||
5007 | return; | ||
5008 | } | ||
4746 | 5009 | ||
5010 | dev_priv->busy = false; | ||
4747 | queue_work(dev_priv->wq, &dev_priv->idle_work); | 5011 | queue_work(dev_priv->wq, &dev_priv->idle_work); |
4748 | } | 5012 | } |
4749 | 5013 | ||
@@ -4754,9 +5018,17 @@ static void intel_crtc_idle_timer(unsigned long arg) | |||
4754 | struct intel_crtc *intel_crtc = (struct intel_crtc *)arg; | 5018 | struct intel_crtc *intel_crtc = (struct intel_crtc *)arg; |
4755 | struct drm_crtc *crtc = &intel_crtc->base; | 5019 | struct drm_crtc *crtc = &intel_crtc->base; |
4756 | drm_i915_private_t *dev_priv = crtc->dev->dev_private; | 5020 | drm_i915_private_t *dev_priv = crtc->dev->dev_private; |
5021 | struct intel_framebuffer *intel_fb; | ||
4757 | 5022 | ||
4758 | intel_crtc->busy = false; | 5023 | intel_fb = to_intel_framebuffer(crtc->fb); |
5024 | if (intel_fb && intel_fb->obj->active) { | ||
5025 | /* The framebuffer is still being accessed by the GPU. */ | ||
5026 | mod_timer(&intel_crtc->idle_timer, jiffies + | ||
5027 | msecs_to_jiffies(CRTC_IDLE_TIMEOUT)); | ||
5028 | return; | ||
5029 | } | ||
4759 | 5030 | ||
5031 | intel_crtc->busy = false; | ||
4760 | queue_work(dev_priv->wq, &dev_priv->idle_work); | 5032 | queue_work(dev_priv->wq, &dev_priv->idle_work); |
4761 | } | 5033 | } |
4762 | 5034 | ||
@@ -4891,7 +5163,7 @@ static void intel_idle_update(struct work_struct *work) | |||
4891 | * buffer), we'll also mark the display as busy, so we know to increase its | 5163 | * buffer), we'll also mark the display as busy, so we know to increase its |
4892 | * clock frequency. | 5164 | * clock frequency. |
4893 | */ | 5165 | */ |
4894 | void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj) | 5166 | void intel_mark_busy(struct drm_device *dev, struct drm_i915_gem_object *obj) |
4895 | { | 5167 | { |
4896 | drm_i915_private_t *dev_priv = dev->dev_private; | 5168 | drm_i915_private_t *dev_priv = dev->dev_private; |
4897 | struct drm_crtc *crtc = NULL; | 5169 | struct drm_crtc *crtc = NULL; |
@@ -4972,8 +5244,9 @@ static void intel_unpin_work_fn(struct work_struct *__work) | |||
4972 | 5244 | ||
4973 | mutex_lock(&work->dev->struct_mutex); | 5245 | mutex_lock(&work->dev->struct_mutex); |
4974 | i915_gem_object_unpin(work->old_fb_obj); | 5246 | i915_gem_object_unpin(work->old_fb_obj); |
4975 | drm_gem_object_unreference(work->pending_flip_obj); | 5247 | drm_gem_object_unreference(&work->pending_flip_obj->base); |
4976 | drm_gem_object_unreference(work->old_fb_obj); | 5248 | drm_gem_object_unreference(&work->old_fb_obj->base); |
5249 | |||
4977 | mutex_unlock(&work->dev->struct_mutex); | 5250 | mutex_unlock(&work->dev->struct_mutex); |
4978 | kfree(work); | 5251 | kfree(work); |
4979 | } | 5252 | } |
@@ -4984,15 +5257,17 @@ static void do_intel_finish_page_flip(struct drm_device *dev, | |||
4984 | drm_i915_private_t *dev_priv = dev->dev_private; | 5257 | drm_i915_private_t *dev_priv = dev->dev_private; |
4985 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 5258 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
4986 | struct intel_unpin_work *work; | 5259 | struct intel_unpin_work *work; |
4987 | struct drm_i915_gem_object *obj_priv; | 5260 | struct drm_i915_gem_object *obj; |
4988 | struct drm_pending_vblank_event *e; | 5261 | struct drm_pending_vblank_event *e; |
4989 | struct timeval now; | 5262 | struct timeval tnow, tvbl; |
4990 | unsigned long flags; | 5263 | unsigned long flags; |
4991 | 5264 | ||
4992 | /* Ignore early vblank irqs */ | 5265 | /* Ignore early vblank irqs */ |
4993 | if (intel_crtc == NULL) | 5266 | if (intel_crtc == NULL) |
4994 | return; | 5267 | return; |
4995 | 5268 | ||
5269 | do_gettimeofday(&tnow); | ||
5270 | |||
4996 | spin_lock_irqsave(&dev->event_lock, flags); | 5271 | spin_lock_irqsave(&dev->event_lock, flags); |
4997 | work = intel_crtc->unpin_work; | 5272 | work = intel_crtc->unpin_work; |
4998 | if (work == NULL || !work->pending) { | 5273 | if (work == NULL || !work->pending) { |
@@ -5001,26 +5276,49 @@ static void do_intel_finish_page_flip(struct drm_device *dev, | |||
5001 | } | 5276 | } |
5002 | 5277 | ||
5003 | intel_crtc->unpin_work = NULL; | 5278 | intel_crtc->unpin_work = NULL; |
5004 | drm_vblank_put(dev, intel_crtc->pipe); | ||
5005 | 5279 | ||
5006 | if (work->event) { | 5280 | if (work->event) { |
5007 | e = work->event; | 5281 | e = work->event; |
5008 | do_gettimeofday(&now); | 5282 | e->event.sequence = drm_vblank_count_and_time(dev, intel_crtc->pipe, &tvbl); |
5009 | e->event.sequence = drm_vblank_count(dev, intel_crtc->pipe); | 5283 | |
5010 | e->event.tv_sec = now.tv_sec; | 5284 | /* Called before vblank count and timestamps have |
5011 | e->event.tv_usec = now.tv_usec; | 5285 | * been updated for the vblank interval of flip |
5286 | * completion? Need to increment vblank count and | ||
5287 | * add one videorefresh duration to returned timestamp | ||
5288 | * to account for this. We assume this happened if we | ||
5289 | * get called over 0.9 frame durations after the last | ||
5290 | * timestamped vblank. | ||
5291 | * | ||
5292 | * This calculation can not be used with vrefresh rates | ||
5293 | * below 5Hz (10Hz to be on the safe side) without | ||
5294 | * promoting to 64 integers. | ||
5295 | */ | ||
5296 | if (10 * (timeval_to_ns(&tnow) - timeval_to_ns(&tvbl)) > | ||
5297 | 9 * crtc->framedur_ns) { | ||
5298 | e->event.sequence++; | ||
5299 | tvbl = ns_to_timeval(timeval_to_ns(&tvbl) + | ||
5300 | crtc->framedur_ns); | ||
5301 | } | ||
5302 | |||
5303 | e->event.tv_sec = tvbl.tv_sec; | ||
5304 | e->event.tv_usec = tvbl.tv_usec; | ||
5305 | |||
5012 | list_add_tail(&e->base.link, | 5306 | list_add_tail(&e->base.link, |
5013 | &e->base.file_priv->event_list); | 5307 | &e->base.file_priv->event_list); |
5014 | wake_up_interruptible(&e->base.file_priv->event_wait); | 5308 | wake_up_interruptible(&e->base.file_priv->event_wait); |
5015 | } | 5309 | } |
5016 | 5310 | ||
5311 | drm_vblank_put(dev, intel_crtc->pipe); | ||
5312 | |||
5017 | spin_unlock_irqrestore(&dev->event_lock, flags); | 5313 | spin_unlock_irqrestore(&dev->event_lock, flags); |
5018 | 5314 | ||
5019 | obj_priv = to_intel_bo(work->old_fb_obj); | 5315 | obj = work->old_fb_obj; |
5316 | |||
5020 | atomic_clear_mask(1 << intel_crtc->plane, | 5317 | atomic_clear_mask(1 << intel_crtc->plane, |
5021 | &obj_priv->pending_flip.counter); | 5318 | &obj->pending_flip.counter); |
5022 | if (atomic_read(&obj_priv->pending_flip) == 0) | 5319 | if (atomic_read(&obj->pending_flip) == 0) |
5023 | wake_up(&dev_priv->pending_flip_queue); | 5320 | wake_up(&dev_priv->pending_flip_queue); |
5321 | |||
5024 | schedule_work(&work->work); | 5322 | schedule_work(&work->work); |
5025 | 5323 | ||
5026 | trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj); | 5324 | trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj); |
@@ -5066,8 +5364,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5066 | struct drm_device *dev = crtc->dev; | 5364 | struct drm_device *dev = crtc->dev; |
5067 | struct drm_i915_private *dev_priv = dev->dev_private; | 5365 | struct drm_i915_private *dev_priv = dev->dev_private; |
5068 | struct intel_framebuffer *intel_fb; | 5366 | struct intel_framebuffer *intel_fb; |
5069 | struct drm_i915_gem_object *obj_priv; | 5367 | struct drm_i915_gem_object *obj; |
5070 | struct drm_gem_object *obj; | ||
5071 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 5368 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
5072 | struct intel_unpin_work *work; | 5369 | struct intel_unpin_work *work; |
5073 | unsigned long flags, offset; | 5370 | unsigned long flags, offset; |
@@ -5101,13 +5398,13 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5101 | obj = intel_fb->obj; | 5398 | obj = intel_fb->obj; |
5102 | 5399 | ||
5103 | mutex_lock(&dev->struct_mutex); | 5400 | mutex_lock(&dev->struct_mutex); |
5104 | ret = intel_pin_and_fence_fb_obj(dev, obj, true); | 5401 | ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); |
5105 | if (ret) | 5402 | if (ret) |
5106 | goto cleanup_work; | 5403 | goto cleanup_work; |
5107 | 5404 | ||
5108 | /* Reference the objects for the scheduled work. */ | 5405 | /* Reference the objects for the scheduled work. */ |
5109 | drm_gem_object_reference(work->old_fb_obj); | 5406 | drm_gem_object_reference(&work->old_fb_obj->base); |
5110 | drm_gem_object_reference(obj); | 5407 | drm_gem_object_reference(&obj->base); |
5111 | 5408 | ||
5112 | crtc->fb = fb; | 5409 | crtc->fb = fb; |
5113 | 5410 | ||
@@ -5115,22 +5412,16 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5115 | if (ret) | 5412 | if (ret) |
5116 | goto cleanup_objs; | 5413 | goto cleanup_objs; |
5117 | 5414 | ||
5118 | /* Block clients from rendering to the new back buffer until | ||
5119 | * the flip occurs and the object is no longer visible. | ||
5120 | */ | ||
5121 | atomic_add(1 << intel_crtc->plane, | ||
5122 | &to_intel_bo(work->old_fb_obj)->pending_flip); | ||
5123 | |||
5124 | work->pending_flip_obj = obj; | ||
5125 | obj_priv = to_intel_bo(obj); | ||
5126 | |||
5127 | if (IS_GEN3(dev) || IS_GEN2(dev)) { | 5415 | if (IS_GEN3(dev) || IS_GEN2(dev)) { |
5128 | u32 flip_mask; | 5416 | u32 flip_mask; |
5129 | 5417 | ||
5130 | /* Can't queue multiple flips, so wait for the previous | 5418 | /* Can't queue multiple flips, so wait for the previous |
5131 | * one to finish before executing the next. | 5419 | * one to finish before executing the next. |
5132 | */ | 5420 | */ |
5133 | BEGIN_LP_RING(2); | 5421 | ret = BEGIN_LP_RING(2); |
5422 | if (ret) | ||
5423 | goto cleanup_objs; | ||
5424 | |||
5134 | if (intel_crtc->plane) | 5425 | if (intel_crtc->plane) |
5135 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; | 5426 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; |
5136 | else | 5427 | else |
@@ -5140,18 +5431,28 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5140 | ADVANCE_LP_RING(); | 5431 | ADVANCE_LP_RING(); |
5141 | } | 5432 | } |
5142 | 5433 | ||
5434 | work->pending_flip_obj = obj; | ||
5435 | |||
5143 | work->enable_stall_check = true; | 5436 | work->enable_stall_check = true; |
5144 | 5437 | ||
5145 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ | 5438 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ |
5146 | offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8; | 5439 | offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8; |
5147 | 5440 | ||
5148 | BEGIN_LP_RING(4); | 5441 | ret = BEGIN_LP_RING(4); |
5149 | switch(INTEL_INFO(dev)->gen) { | 5442 | if (ret) |
5443 | goto cleanup_objs; | ||
5444 | |||
5445 | /* Block clients from rendering to the new back buffer until | ||
5446 | * the flip occurs and the object is no longer visible. | ||
5447 | */ | ||
5448 | atomic_add(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip); | ||
5449 | |||
5450 | switch (INTEL_INFO(dev)->gen) { | ||
5150 | case 2: | 5451 | case 2: |
5151 | OUT_RING(MI_DISPLAY_FLIP | | 5452 | OUT_RING(MI_DISPLAY_FLIP | |
5152 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 5453 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
5153 | OUT_RING(fb->pitch); | 5454 | OUT_RING(fb->pitch); |
5154 | OUT_RING(obj_priv->gtt_offset + offset); | 5455 | OUT_RING(obj->gtt_offset + offset); |
5155 | OUT_RING(MI_NOOP); | 5456 | OUT_RING(MI_NOOP); |
5156 | break; | 5457 | break; |
5157 | 5458 | ||
@@ -5159,7 +5460,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5159 | OUT_RING(MI_DISPLAY_FLIP_I915 | | 5460 | OUT_RING(MI_DISPLAY_FLIP_I915 | |
5160 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 5461 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
5161 | OUT_RING(fb->pitch); | 5462 | OUT_RING(fb->pitch); |
5162 | OUT_RING(obj_priv->gtt_offset + offset); | 5463 | OUT_RING(obj->gtt_offset + offset); |
5163 | OUT_RING(MI_NOOP); | 5464 | OUT_RING(MI_NOOP); |
5164 | break; | 5465 | break; |
5165 | 5466 | ||
@@ -5172,7 +5473,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5172 | OUT_RING(MI_DISPLAY_FLIP | | 5473 | OUT_RING(MI_DISPLAY_FLIP | |
5173 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 5474 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
5174 | OUT_RING(fb->pitch); | 5475 | OUT_RING(fb->pitch); |
5175 | OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode); | 5476 | OUT_RING(obj->gtt_offset | obj->tiling_mode); |
5176 | 5477 | ||
5177 | /* XXX Enabling the panel-fitter across page-flip is so far | 5478 | /* XXX Enabling the panel-fitter across page-flip is so far |
5178 | * untested on non-native modes, so ignore it for now. | 5479 | * untested on non-native modes, so ignore it for now. |
@@ -5186,8 +5487,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5186 | case 6: | 5487 | case 6: |
5187 | OUT_RING(MI_DISPLAY_FLIP | | 5488 | OUT_RING(MI_DISPLAY_FLIP | |
5188 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 5489 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
5189 | OUT_RING(fb->pitch | obj_priv->tiling_mode); | 5490 | OUT_RING(fb->pitch | obj->tiling_mode); |
5190 | OUT_RING(obj_priv->gtt_offset); | 5491 | OUT_RING(obj->gtt_offset); |
5191 | 5492 | ||
5192 | pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE; | 5493 | pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE; |
5193 | pipesrc = I915_READ(pipe == 0 ? PIPEASRC : PIPEBSRC) & 0x0fff0fff; | 5494 | pipesrc = I915_READ(pipe == 0 ? PIPEASRC : PIPEBSRC) & 0x0fff0fff; |
@@ -5203,8 +5504,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5203 | return 0; | 5504 | return 0; |
5204 | 5505 | ||
5205 | cleanup_objs: | 5506 | cleanup_objs: |
5206 | drm_gem_object_unreference(work->old_fb_obj); | 5507 | drm_gem_object_unreference(&work->old_fb_obj->base); |
5207 | drm_gem_object_unreference(obj); | 5508 | drm_gem_object_unreference(&obj->base); |
5208 | cleanup_work: | 5509 | cleanup_work: |
5209 | mutex_unlock(&dev->struct_mutex); | 5510 | mutex_unlock(&dev->struct_mutex); |
5210 | 5511 | ||
@@ -5236,6 +5537,55 @@ static const struct drm_crtc_funcs intel_crtc_funcs = { | |||
5236 | .page_flip = intel_crtc_page_flip, | 5537 | .page_flip = intel_crtc_page_flip, |
5237 | }; | 5538 | }; |
5238 | 5539 | ||
5540 | static void intel_sanitize_modesetting(struct drm_device *dev, | ||
5541 | int pipe, int plane) | ||
5542 | { | ||
5543 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5544 | u32 reg, val; | ||
5545 | |||
5546 | if (HAS_PCH_SPLIT(dev)) | ||
5547 | return; | ||
5548 | |||
5549 | /* Who knows what state these registers were left in by the BIOS or | ||
5550 | * grub? | ||
5551 | * | ||
5552 | * If we leave the registers in a conflicting state (e.g. with the | ||
5553 | * display plane reading from the other pipe than the one we intend | ||
5554 | * to use) then when we attempt to teardown the active mode, we will | ||
5555 | * not disable the pipes and planes in the correct order -- leaving | ||
5556 | * a plane reading from a disabled pipe and possibly leading to | ||
5557 | * undefined behaviour. | ||
5558 | */ | ||
5559 | |||
5560 | reg = DSPCNTR(plane); | ||
5561 | val = I915_READ(reg); | ||
5562 | |||
5563 | if ((val & DISPLAY_PLANE_ENABLE) == 0) | ||
5564 | return; | ||
5565 | if (!!(val & DISPPLANE_SEL_PIPE_MASK) == pipe) | ||
5566 | return; | ||
5567 | |||
5568 | /* This display plane is active and attached to the other CPU pipe. */ | ||
5569 | pipe = !pipe; | ||
5570 | |||
5571 | /* Disable the plane and wait for it to stop reading from the pipe. */ | ||
5572 | I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE); | ||
5573 | intel_flush_display_plane(dev, plane); | ||
5574 | |||
5575 | if (IS_GEN2(dev)) | ||
5576 | intel_wait_for_vblank(dev, pipe); | ||
5577 | |||
5578 | if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) | ||
5579 | return; | ||
5580 | |||
5581 | /* Switch off the pipe. */ | ||
5582 | reg = PIPECONF(pipe); | ||
5583 | val = I915_READ(reg); | ||
5584 | if (val & PIPECONF_ENABLE) { | ||
5585 | I915_WRITE(reg, val & ~PIPECONF_ENABLE); | ||
5586 | intel_wait_for_pipe_off(dev, pipe); | ||
5587 | } | ||
5588 | } | ||
5239 | 5589 | ||
5240 | static void intel_crtc_init(struct drm_device *dev, int pipe) | 5590 | static void intel_crtc_init(struct drm_device *dev, int pipe) |
5241 | { | 5591 | { |
@@ -5287,10 +5637,12 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
5287 | 5637 | ||
5288 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, | 5638 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, |
5289 | (unsigned long)intel_crtc); | 5639 | (unsigned long)intel_crtc); |
5640 | |||
5641 | intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); | ||
5290 | } | 5642 | } |
5291 | 5643 | ||
5292 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 5644 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
5293 | struct drm_file *file_priv) | 5645 | struct drm_file *file) |
5294 | { | 5646 | { |
5295 | drm_i915_private_t *dev_priv = dev->dev_private; | 5647 | drm_i915_private_t *dev_priv = dev->dev_private; |
5296 | struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data; | 5648 | struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data; |
@@ -5336,9 +5688,14 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
5336 | struct drm_i915_private *dev_priv = dev->dev_private; | 5688 | struct drm_i915_private *dev_priv = dev->dev_private; |
5337 | struct intel_encoder *encoder; | 5689 | struct intel_encoder *encoder; |
5338 | bool dpd_is_edp = false; | 5690 | bool dpd_is_edp = false; |
5691 | bool has_lvds = false; | ||
5339 | 5692 | ||
5340 | if (IS_MOBILE(dev) && !IS_I830(dev)) | 5693 | if (IS_MOBILE(dev) && !IS_I830(dev)) |
5341 | intel_lvds_init(dev); | 5694 | has_lvds = intel_lvds_init(dev); |
5695 | if (!has_lvds && !HAS_PCH_SPLIT(dev)) { | ||
5696 | /* disable the panel fitter on everything but LVDS */ | ||
5697 | I915_WRITE(PFIT_CONTROL, 0); | ||
5698 | } | ||
5342 | 5699 | ||
5343 | if (HAS_PCH_SPLIT(dev)) { | 5700 | if (HAS_PCH_SPLIT(dev)) { |
5344 | dpd_is_edp = intel_dpd_is_edp(dev); | 5701 | dpd_is_edp = intel_dpd_is_edp(dev); |
@@ -5435,19 +5792,19 @@ static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) | |||
5435 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | 5792 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
5436 | 5793 | ||
5437 | drm_framebuffer_cleanup(fb); | 5794 | drm_framebuffer_cleanup(fb); |
5438 | drm_gem_object_unreference_unlocked(intel_fb->obj); | 5795 | drm_gem_object_unreference_unlocked(&intel_fb->obj->base); |
5439 | 5796 | ||
5440 | kfree(intel_fb); | 5797 | kfree(intel_fb); |
5441 | } | 5798 | } |
5442 | 5799 | ||
5443 | static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb, | 5800 | static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb, |
5444 | struct drm_file *file_priv, | 5801 | struct drm_file *file, |
5445 | unsigned int *handle) | 5802 | unsigned int *handle) |
5446 | { | 5803 | { |
5447 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | 5804 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
5448 | struct drm_gem_object *object = intel_fb->obj; | 5805 | struct drm_i915_gem_object *obj = intel_fb->obj; |
5449 | 5806 | ||
5450 | return drm_gem_handle_create(file_priv, object, handle); | 5807 | return drm_gem_handle_create(file, &obj->base, handle); |
5451 | } | 5808 | } |
5452 | 5809 | ||
5453 | static const struct drm_framebuffer_funcs intel_fb_funcs = { | 5810 | static const struct drm_framebuffer_funcs intel_fb_funcs = { |
@@ -5458,12 +5815,11 @@ static const struct drm_framebuffer_funcs intel_fb_funcs = { | |||
5458 | int intel_framebuffer_init(struct drm_device *dev, | 5815 | int intel_framebuffer_init(struct drm_device *dev, |
5459 | struct intel_framebuffer *intel_fb, | 5816 | struct intel_framebuffer *intel_fb, |
5460 | struct drm_mode_fb_cmd *mode_cmd, | 5817 | struct drm_mode_fb_cmd *mode_cmd, |
5461 | struct drm_gem_object *obj) | 5818 | struct drm_i915_gem_object *obj) |
5462 | { | 5819 | { |
5463 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
5464 | int ret; | 5820 | int ret; |
5465 | 5821 | ||
5466 | if (obj_priv->tiling_mode == I915_TILING_Y) | 5822 | if (obj->tiling_mode == I915_TILING_Y) |
5467 | return -EINVAL; | 5823 | return -EINVAL; |
5468 | 5824 | ||
5469 | if (mode_cmd->pitch & 63) | 5825 | if (mode_cmd->pitch & 63) |
@@ -5495,11 +5851,11 @@ intel_user_framebuffer_create(struct drm_device *dev, | |||
5495 | struct drm_file *filp, | 5851 | struct drm_file *filp, |
5496 | struct drm_mode_fb_cmd *mode_cmd) | 5852 | struct drm_mode_fb_cmd *mode_cmd) |
5497 | { | 5853 | { |
5498 | struct drm_gem_object *obj; | 5854 | struct drm_i915_gem_object *obj; |
5499 | struct intel_framebuffer *intel_fb; | 5855 | struct intel_framebuffer *intel_fb; |
5500 | int ret; | 5856 | int ret; |
5501 | 5857 | ||
5502 | obj = drm_gem_object_lookup(dev, filp, mode_cmd->handle); | 5858 | obj = to_intel_bo(drm_gem_object_lookup(dev, filp, mode_cmd->handle)); |
5503 | if (!obj) | 5859 | if (!obj) |
5504 | return ERR_PTR(-ENOENT); | 5860 | return ERR_PTR(-ENOENT); |
5505 | 5861 | ||
@@ -5507,10 +5863,9 @@ intel_user_framebuffer_create(struct drm_device *dev, | |||
5507 | if (!intel_fb) | 5863 | if (!intel_fb) |
5508 | return ERR_PTR(-ENOMEM); | 5864 | return ERR_PTR(-ENOMEM); |
5509 | 5865 | ||
5510 | ret = intel_framebuffer_init(dev, intel_fb, | 5866 | ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj); |
5511 | mode_cmd, obj); | ||
5512 | if (ret) { | 5867 | if (ret) { |
5513 | drm_gem_object_unreference_unlocked(obj); | 5868 | drm_gem_object_unreference_unlocked(&obj->base); |
5514 | kfree(intel_fb); | 5869 | kfree(intel_fb); |
5515 | return ERR_PTR(ret); | 5870 | return ERR_PTR(ret); |
5516 | } | 5871 | } |
@@ -5523,10 +5878,10 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { | |||
5523 | .output_poll_changed = intel_fb_output_poll_changed, | 5878 | .output_poll_changed = intel_fb_output_poll_changed, |
5524 | }; | 5879 | }; |
5525 | 5880 | ||
5526 | static struct drm_gem_object * | 5881 | static struct drm_i915_gem_object * |
5527 | intel_alloc_context_page(struct drm_device *dev) | 5882 | intel_alloc_context_page(struct drm_device *dev) |
5528 | { | 5883 | { |
5529 | struct drm_gem_object *ctx; | 5884 | struct drm_i915_gem_object *ctx; |
5530 | int ret; | 5885 | int ret; |
5531 | 5886 | ||
5532 | ctx = i915_gem_alloc_object(dev, 4096); | 5887 | ctx = i915_gem_alloc_object(dev, 4096); |
@@ -5536,7 +5891,7 @@ intel_alloc_context_page(struct drm_device *dev) | |||
5536 | } | 5891 | } |
5537 | 5892 | ||
5538 | mutex_lock(&dev->struct_mutex); | 5893 | mutex_lock(&dev->struct_mutex); |
5539 | ret = i915_gem_object_pin(ctx, 4096); | 5894 | ret = i915_gem_object_pin(ctx, 4096, true); |
5540 | if (ret) { | 5895 | if (ret) { |
5541 | DRM_ERROR("failed to pin power context: %d\n", ret); | 5896 | DRM_ERROR("failed to pin power context: %d\n", ret); |
5542 | goto err_unref; | 5897 | goto err_unref; |
@@ -5554,7 +5909,7 @@ intel_alloc_context_page(struct drm_device *dev) | |||
5554 | err_unpin: | 5909 | err_unpin: |
5555 | i915_gem_object_unpin(ctx); | 5910 | i915_gem_object_unpin(ctx); |
5556 | err_unref: | 5911 | err_unref: |
5557 | drm_gem_object_unreference(ctx); | 5912 | drm_gem_object_unreference(&ctx->base); |
5558 | mutex_unlock(&dev->struct_mutex); | 5913 | mutex_unlock(&dev->struct_mutex); |
5559 | return NULL; | 5914 | return NULL; |
5560 | } | 5915 | } |
@@ -5666,6 +6021,25 @@ void ironlake_disable_drps(struct drm_device *dev) | |||
5666 | 6021 | ||
5667 | } | 6022 | } |
5668 | 6023 | ||
6024 | void gen6_set_rps(struct drm_device *dev, u8 val) | ||
6025 | { | ||
6026 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
6027 | u32 swreq; | ||
6028 | |||
6029 | swreq = (val & 0x3ff) << 25; | ||
6030 | I915_WRITE(GEN6_RPNSWREQ, swreq); | ||
6031 | } | ||
6032 | |||
6033 | void gen6_disable_rps(struct drm_device *dev) | ||
6034 | { | ||
6035 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
6036 | |||
6037 | I915_WRITE(GEN6_RPNSWREQ, 1 << 31); | ||
6038 | I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); | ||
6039 | I915_WRITE(GEN6_PMIER, 0); | ||
6040 | I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); | ||
6041 | } | ||
6042 | |||
5669 | static unsigned long intel_pxfreq(u32 vidfreq) | 6043 | static unsigned long intel_pxfreq(u32 vidfreq) |
5670 | { | 6044 | { |
5671 | unsigned long freq; | 6045 | unsigned long freq; |
@@ -5752,7 +6126,96 @@ void intel_init_emon(struct drm_device *dev) | |||
5752 | dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); | 6126 | dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); |
5753 | } | 6127 | } |
5754 | 6128 | ||
5755 | void intel_init_clock_gating(struct drm_device *dev) | 6129 | void gen6_enable_rps(struct drm_i915_private *dev_priv) |
6130 | { | ||
6131 | int i; | ||
6132 | |||
6133 | /* Here begins a magic sequence of register writes to enable | ||
6134 | * auto-downclocking. | ||
6135 | * | ||
6136 | * Perhaps there might be some value in exposing these to | ||
6137 | * userspace... | ||
6138 | */ | ||
6139 | I915_WRITE(GEN6_RC_STATE, 0); | ||
6140 | __gen6_force_wake_get(dev_priv); | ||
6141 | |||
6142 | /* disable the counters and set deterministic thresholds */ | ||
6143 | I915_WRITE(GEN6_RC_CONTROL, 0); | ||
6144 | |||
6145 | I915_WRITE(GEN6_RC1_WAKE_RATE_LIMIT, 1000 << 16); | ||
6146 | I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16 | 30); | ||
6147 | I915_WRITE(GEN6_RC6pp_WAKE_RATE_LIMIT, 30); | ||
6148 | I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); | ||
6149 | I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); | ||
6150 | |||
6151 | for (i = 0; i < I915_NUM_RINGS; i++) | ||
6152 | I915_WRITE(RING_MAX_IDLE(dev_priv->ring[i].mmio_base), 10); | ||
6153 | |||
6154 | I915_WRITE(GEN6_RC_SLEEP, 0); | ||
6155 | I915_WRITE(GEN6_RC1e_THRESHOLD, 1000); | ||
6156 | I915_WRITE(GEN6_RC6_THRESHOLD, 50000); | ||
6157 | I915_WRITE(GEN6_RC6p_THRESHOLD, 100000); | ||
6158 | I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ | ||
6159 | |||
6160 | I915_WRITE(GEN6_RC_CONTROL, | ||
6161 | GEN6_RC_CTL_RC6p_ENABLE | | ||
6162 | GEN6_RC_CTL_RC6_ENABLE | | ||
6163 | GEN6_RC_CTL_EI_MODE(1) | | ||
6164 | GEN6_RC_CTL_HW_ENABLE); | ||
6165 | |||
6166 | I915_WRITE(GEN6_RPNSWREQ, | ||
6167 | GEN6_FREQUENCY(10) | | ||
6168 | GEN6_OFFSET(0) | | ||
6169 | GEN6_AGGRESSIVE_TURBO); | ||
6170 | I915_WRITE(GEN6_RC_VIDEO_FREQ, | ||
6171 | GEN6_FREQUENCY(12)); | ||
6172 | |||
6173 | I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); | ||
6174 | I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, | ||
6175 | 18 << 24 | | ||
6176 | 6 << 16); | ||
6177 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 90000); | ||
6178 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 100000); | ||
6179 | I915_WRITE(GEN6_RP_UP_EI, 100000); | ||
6180 | I915_WRITE(GEN6_RP_DOWN_EI, 300000); | ||
6181 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); | ||
6182 | I915_WRITE(GEN6_RP_CONTROL, | ||
6183 | GEN6_RP_MEDIA_TURBO | | ||
6184 | GEN6_RP_USE_NORMAL_FREQ | | ||
6185 | GEN6_RP_MEDIA_IS_GFX | | ||
6186 | GEN6_RP_ENABLE | | ||
6187 | GEN6_RP_UP_BUSY_MAX | | ||
6188 | GEN6_RP_DOWN_BUSY_MIN); | ||
6189 | |||
6190 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, | ||
6191 | 500)) | ||
6192 | DRM_ERROR("timeout waiting for pcode mailbox to become idle\n"); | ||
6193 | |||
6194 | I915_WRITE(GEN6_PCODE_DATA, 0); | ||
6195 | I915_WRITE(GEN6_PCODE_MAILBOX, | ||
6196 | GEN6_PCODE_READY | | ||
6197 | GEN6_PCODE_WRITE_MIN_FREQ_TABLE); | ||
6198 | if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, | ||
6199 | 500)) | ||
6200 | DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); | ||
6201 | |||
6202 | /* requires MSI enabled */ | ||
6203 | I915_WRITE(GEN6_PMIER, | ||
6204 | GEN6_PM_MBOX_EVENT | | ||
6205 | GEN6_PM_THERMAL_EVENT | | ||
6206 | GEN6_PM_RP_DOWN_TIMEOUT | | ||
6207 | GEN6_PM_RP_UP_THRESHOLD | | ||
6208 | GEN6_PM_RP_DOWN_THRESHOLD | | ||
6209 | GEN6_PM_RP_UP_EI_EXPIRED | | ||
6210 | GEN6_PM_RP_DOWN_EI_EXPIRED); | ||
6211 | I915_WRITE(GEN6_PMIMR, 0); | ||
6212 | /* enable all PM interrupts */ | ||
6213 | I915_WRITE(GEN6_PMINTRMSK, 0); | ||
6214 | |||
6215 | __gen6_force_wake_put(dev_priv); | ||
6216 | } | ||
6217 | |||
6218 | void intel_enable_clock_gating(struct drm_device *dev) | ||
5756 | { | 6219 | { |
5757 | struct drm_i915_private *dev_priv = dev->dev_private; | 6220 | struct drm_i915_private *dev_priv = dev->dev_private; |
5758 | 6221 | ||
@@ -5800,9 +6263,9 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5800 | I915_WRITE(DISP_ARB_CTL, | 6263 | I915_WRITE(DISP_ARB_CTL, |
5801 | (I915_READ(DISP_ARB_CTL) | | 6264 | (I915_READ(DISP_ARB_CTL) | |
5802 | DISP_FBC_WM_DIS)); | 6265 | DISP_FBC_WM_DIS)); |
5803 | I915_WRITE(WM3_LP_ILK, 0); | 6266 | I915_WRITE(WM3_LP_ILK, 0); |
5804 | I915_WRITE(WM2_LP_ILK, 0); | 6267 | I915_WRITE(WM2_LP_ILK, 0); |
5805 | I915_WRITE(WM1_LP_ILK, 0); | 6268 | I915_WRITE(WM1_LP_ILK, 0); |
5806 | } | 6269 | } |
5807 | /* | 6270 | /* |
5808 | * Based on the document from hardware guys the following bits | 6271 | * Based on the document from hardware guys the following bits |
@@ -5824,7 +6287,49 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5824 | ILK_DPFC_DIS2 | | 6287 | ILK_DPFC_DIS2 | |
5825 | ILK_CLK_FBC); | 6288 | ILK_CLK_FBC); |
5826 | } | 6289 | } |
5827 | return; | 6290 | |
6291 | I915_WRITE(ILK_DISPLAY_CHICKEN2, | ||
6292 | I915_READ(ILK_DISPLAY_CHICKEN2) | | ||
6293 | ILK_ELPIN_409_SELECT); | ||
6294 | |||
6295 | if (IS_GEN5(dev)) { | ||
6296 | I915_WRITE(_3D_CHICKEN2, | ||
6297 | _3D_CHICKEN2_WM_READ_PIPELINED << 16 | | ||
6298 | _3D_CHICKEN2_WM_READ_PIPELINED); | ||
6299 | } | ||
6300 | |||
6301 | if (IS_GEN6(dev)) { | ||
6302 | I915_WRITE(WM3_LP_ILK, 0); | ||
6303 | I915_WRITE(WM2_LP_ILK, 0); | ||
6304 | I915_WRITE(WM1_LP_ILK, 0); | ||
6305 | |||
6306 | /* | ||
6307 | * According to the spec the following bits should be | ||
6308 | * set in order to enable memory self-refresh and fbc: | ||
6309 | * The bit21 and bit22 of 0x42000 | ||
6310 | * The bit21 and bit22 of 0x42004 | ||
6311 | * The bit5 and bit7 of 0x42020 | ||
6312 | * The bit14 of 0x70180 | ||
6313 | * The bit14 of 0x71180 | ||
6314 | */ | ||
6315 | I915_WRITE(ILK_DISPLAY_CHICKEN1, | ||
6316 | I915_READ(ILK_DISPLAY_CHICKEN1) | | ||
6317 | ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS); | ||
6318 | I915_WRITE(ILK_DISPLAY_CHICKEN2, | ||
6319 | I915_READ(ILK_DISPLAY_CHICKEN2) | | ||
6320 | ILK_DPARB_GATE | ILK_VSDPFD_FULL); | ||
6321 | I915_WRITE(ILK_DSPCLK_GATE, | ||
6322 | I915_READ(ILK_DSPCLK_GATE) | | ||
6323 | ILK_DPARB_CLK_GATE | | ||
6324 | ILK_DPFD_CLK_GATE); | ||
6325 | |||
6326 | I915_WRITE(DSPACNTR, | ||
6327 | I915_READ(DSPACNTR) | | ||
6328 | DISPPLANE_TRICKLE_FEED_DISABLE); | ||
6329 | I915_WRITE(DSPBCNTR, | ||
6330 | I915_READ(DSPBCNTR) | | ||
6331 | DISPPLANE_TRICKLE_FEED_DISABLE); | ||
6332 | } | ||
5828 | } else if (IS_G4X(dev)) { | 6333 | } else if (IS_G4X(dev)) { |
5829 | uint32_t dspclk_gate; | 6334 | uint32_t dspclk_gate; |
5830 | I915_WRITE(RENCLK_GATE_D1, 0); | 6335 | I915_WRITE(RENCLK_GATE_D1, 0); |
@@ -5867,20 +6372,18 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5867 | * GPU can automatically power down the render unit if given a page | 6372 | * GPU can automatically power down the render unit if given a page |
5868 | * to save state. | 6373 | * to save state. |
5869 | */ | 6374 | */ |
5870 | if (IS_IRONLAKE_M(dev)) { | 6375 | if (IS_IRONLAKE_M(dev) && 0) { /* XXX causes a failure during suspend */ |
5871 | if (dev_priv->renderctx == NULL) | 6376 | if (dev_priv->renderctx == NULL) |
5872 | dev_priv->renderctx = intel_alloc_context_page(dev); | 6377 | dev_priv->renderctx = intel_alloc_context_page(dev); |
5873 | if (dev_priv->renderctx) { | 6378 | if (dev_priv->renderctx) { |
5874 | struct drm_i915_gem_object *obj_priv; | 6379 | struct drm_i915_gem_object *obj = dev_priv->renderctx; |
5875 | obj_priv = to_intel_bo(dev_priv->renderctx); | 6380 | if (BEGIN_LP_RING(4) == 0) { |
5876 | if (obj_priv) { | ||
5877 | BEGIN_LP_RING(4); | ||
5878 | OUT_RING(MI_SET_CONTEXT); | 6381 | OUT_RING(MI_SET_CONTEXT); |
5879 | OUT_RING(obj_priv->gtt_offset | | 6382 | OUT_RING(obj->gtt_offset | |
5880 | MI_MM_SPACE_GTT | | 6383 | MI_MM_SPACE_GTT | |
5881 | MI_SAVE_EXT_STATE_EN | | 6384 | MI_SAVE_EXT_STATE_EN | |
5882 | MI_RESTORE_EXT_STATE_EN | | 6385 | MI_RESTORE_EXT_STATE_EN | |
5883 | MI_RESTORE_INHIBIT); | 6386 | MI_RESTORE_INHIBIT); |
5884 | OUT_RING(MI_NOOP); | 6387 | OUT_RING(MI_NOOP); |
5885 | OUT_RING(MI_FLUSH); | 6388 | OUT_RING(MI_FLUSH); |
5886 | ADVANCE_LP_RING(); | 6389 | ADVANCE_LP_RING(); |
@@ -5890,29 +6393,45 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5890 | "Disable RC6\n"); | 6393 | "Disable RC6\n"); |
5891 | } | 6394 | } |
5892 | 6395 | ||
5893 | if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { | 6396 | if (IS_GEN4(dev) && IS_MOBILE(dev)) { |
5894 | struct drm_i915_gem_object *obj_priv = NULL; | 6397 | if (dev_priv->pwrctx == NULL) |
5895 | 6398 | dev_priv->pwrctx = intel_alloc_context_page(dev); | |
5896 | if (dev_priv->pwrctx) { | 6399 | if (dev_priv->pwrctx) { |
5897 | obj_priv = to_intel_bo(dev_priv->pwrctx); | 6400 | struct drm_i915_gem_object *obj = dev_priv->pwrctx; |
5898 | } else { | 6401 | I915_WRITE(PWRCTXA, obj->gtt_offset | PWRCTX_EN); |
5899 | struct drm_gem_object *pwrctx; | ||
5900 | |||
5901 | pwrctx = intel_alloc_context_page(dev); | ||
5902 | if (pwrctx) { | ||
5903 | dev_priv->pwrctx = pwrctx; | ||
5904 | obj_priv = to_intel_bo(pwrctx); | ||
5905 | } | ||
5906 | } | ||
5907 | |||
5908 | if (obj_priv) { | ||
5909 | I915_WRITE(PWRCTXA, obj_priv->gtt_offset | PWRCTX_EN); | ||
5910 | I915_WRITE(MCHBAR_RENDER_STANDBY, | 6402 | I915_WRITE(MCHBAR_RENDER_STANDBY, |
5911 | I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT); | 6403 | I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT); |
5912 | } | 6404 | } |
5913 | } | 6405 | } |
5914 | } | 6406 | } |
5915 | 6407 | ||
6408 | void intel_disable_clock_gating(struct drm_device *dev) | ||
6409 | { | ||
6410 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
6411 | |||
6412 | if (dev_priv->renderctx) { | ||
6413 | struct drm_i915_gem_object *obj = dev_priv->renderctx; | ||
6414 | |||
6415 | I915_WRITE(CCID, 0); | ||
6416 | POSTING_READ(CCID); | ||
6417 | |||
6418 | i915_gem_object_unpin(obj); | ||
6419 | drm_gem_object_unreference(&obj->base); | ||
6420 | dev_priv->renderctx = NULL; | ||
6421 | } | ||
6422 | |||
6423 | if (dev_priv->pwrctx) { | ||
6424 | struct drm_i915_gem_object *obj = dev_priv->pwrctx; | ||
6425 | |||
6426 | I915_WRITE(PWRCTXA, 0); | ||
6427 | POSTING_READ(PWRCTXA); | ||
6428 | |||
6429 | i915_gem_object_unpin(obj); | ||
6430 | drm_gem_object_unreference(&obj->base); | ||
6431 | dev_priv->pwrctx = NULL; | ||
6432 | } | ||
6433 | } | ||
6434 | |||
5916 | /* Set up chip specific display functions */ | 6435 | /* Set up chip specific display functions */ |
5917 | static void intel_init_display(struct drm_device *dev) | 6436 | static void intel_init_display(struct drm_device *dev) |
5918 | { | 6437 | { |
@@ -5925,7 +6444,7 @@ static void intel_init_display(struct drm_device *dev) | |||
5925 | dev_priv->display.dpms = i9xx_crtc_dpms; | 6444 | dev_priv->display.dpms = i9xx_crtc_dpms; |
5926 | 6445 | ||
5927 | if (I915_HAS_FBC(dev)) { | 6446 | if (I915_HAS_FBC(dev)) { |
5928 | if (IS_IRONLAKE_M(dev)) { | 6447 | if (HAS_PCH_SPLIT(dev)) { |
5929 | dev_priv->display.fbc_enabled = ironlake_fbc_enabled; | 6448 | dev_priv->display.fbc_enabled = ironlake_fbc_enabled; |
5930 | dev_priv->display.enable_fbc = ironlake_enable_fbc; | 6449 | dev_priv->display.enable_fbc = ironlake_enable_fbc; |
5931 | dev_priv->display.disable_fbc = ironlake_disable_fbc; | 6450 | dev_priv->display.disable_fbc = ironlake_disable_fbc; |
@@ -5974,6 +6493,14 @@ static void intel_init_display(struct drm_device *dev) | |||
5974 | "Disable CxSR\n"); | 6493 | "Disable CxSR\n"); |
5975 | dev_priv->display.update_wm = NULL; | 6494 | dev_priv->display.update_wm = NULL; |
5976 | } | 6495 | } |
6496 | } else if (IS_GEN6(dev)) { | ||
6497 | if (SNB_READ_WM0_LATENCY()) { | ||
6498 | dev_priv->display.update_wm = sandybridge_update_wm; | ||
6499 | } else { | ||
6500 | DRM_DEBUG_KMS("Failed to read display plane latency. " | ||
6501 | "Disable CxSR\n"); | ||
6502 | dev_priv->display.update_wm = NULL; | ||
6503 | } | ||
5977 | } else | 6504 | } else |
5978 | dev_priv->display.update_wm = NULL; | 6505 | dev_priv->display.update_wm = NULL; |
5979 | } else if (IS_PINEVIEW(dev)) { | 6506 | } else if (IS_PINEVIEW(dev)) { |
@@ -6139,7 +6666,7 @@ void intel_modeset_init(struct drm_device *dev) | |||
6139 | 6666 | ||
6140 | intel_setup_outputs(dev); | 6667 | intel_setup_outputs(dev); |
6141 | 6668 | ||
6142 | intel_init_clock_gating(dev); | 6669 | intel_enable_clock_gating(dev); |
6143 | 6670 | ||
6144 | /* Just disable it once at startup */ | 6671 | /* Just disable it once at startup */ |
6145 | i915_disable_vga(dev); | 6672 | i915_disable_vga(dev); |
@@ -6149,6 +6676,9 @@ void intel_modeset_init(struct drm_device *dev) | |||
6149 | intel_init_emon(dev); | 6676 | intel_init_emon(dev); |
6150 | } | 6677 | } |
6151 | 6678 | ||
6679 | if (IS_GEN6(dev)) | ||
6680 | gen6_enable_rps(dev_priv); | ||
6681 | |||
6152 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); | 6682 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); |
6153 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, | 6683 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, |
6154 | (unsigned long)dev); | 6684 | (unsigned long)dev); |
@@ -6180,28 +6710,12 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
6180 | if (dev_priv->display.disable_fbc) | 6710 | if (dev_priv->display.disable_fbc) |
6181 | dev_priv->display.disable_fbc(dev); | 6711 | dev_priv->display.disable_fbc(dev); |
6182 | 6712 | ||
6183 | if (dev_priv->renderctx) { | ||
6184 | struct drm_i915_gem_object *obj_priv; | ||
6185 | |||
6186 | obj_priv = to_intel_bo(dev_priv->renderctx); | ||
6187 | I915_WRITE(CCID, obj_priv->gtt_offset &~ CCID_EN); | ||
6188 | I915_READ(CCID); | ||
6189 | i915_gem_object_unpin(dev_priv->renderctx); | ||
6190 | drm_gem_object_unreference(dev_priv->renderctx); | ||
6191 | } | ||
6192 | |||
6193 | if (dev_priv->pwrctx) { | ||
6194 | struct drm_i915_gem_object *obj_priv; | ||
6195 | |||
6196 | obj_priv = to_intel_bo(dev_priv->pwrctx); | ||
6197 | I915_WRITE(PWRCTXA, obj_priv->gtt_offset &~ PWRCTX_EN); | ||
6198 | I915_READ(PWRCTXA); | ||
6199 | i915_gem_object_unpin(dev_priv->pwrctx); | ||
6200 | drm_gem_object_unreference(dev_priv->pwrctx); | ||
6201 | } | ||
6202 | |||
6203 | if (IS_IRONLAKE_M(dev)) | 6713 | if (IS_IRONLAKE_M(dev)) |
6204 | ironlake_disable_drps(dev); | 6714 | ironlake_disable_drps(dev); |
6715 | if (IS_GEN6(dev)) | ||
6716 | gen6_disable_rps(dev); | ||
6717 | |||
6718 | intel_disable_clock_gating(dev); | ||
6205 | 6719 | ||
6206 | mutex_unlock(&dev->struct_mutex); | 6720 | mutex_unlock(&dev->struct_mutex); |
6207 | 6721 | ||
@@ -6253,3 +6767,113 @@ int intel_modeset_vga_set_state(struct drm_device *dev, bool state) | |||
6253 | pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl); | 6767 | pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl); |
6254 | return 0; | 6768 | return 0; |
6255 | } | 6769 | } |
6770 | |||
6771 | #ifdef CONFIG_DEBUG_FS | ||
6772 | #include <linux/seq_file.h> | ||
6773 | |||
6774 | struct intel_display_error_state { | ||
6775 | struct intel_cursor_error_state { | ||
6776 | u32 control; | ||
6777 | u32 position; | ||
6778 | u32 base; | ||
6779 | u32 size; | ||
6780 | } cursor[2]; | ||
6781 | |||
6782 | struct intel_pipe_error_state { | ||
6783 | u32 conf; | ||
6784 | u32 source; | ||
6785 | |||
6786 | u32 htotal; | ||
6787 | u32 hblank; | ||
6788 | u32 hsync; | ||
6789 | u32 vtotal; | ||
6790 | u32 vblank; | ||
6791 | u32 vsync; | ||
6792 | } pipe[2]; | ||
6793 | |||
6794 | struct intel_plane_error_state { | ||
6795 | u32 control; | ||
6796 | u32 stride; | ||
6797 | u32 size; | ||
6798 | u32 pos; | ||
6799 | u32 addr; | ||
6800 | u32 surface; | ||
6801 | u32 tile_offset; | ||
6802 | } plane[2]; | ||
6803 | }; | ||
6804 | |||
6805 | struct intel_display_error_state * | ||
6806 | intel_display_capture_error_state(struct drm_device *dev) | ||
6807 | { | ||
6808 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
6809 | struct intel_display_error_state *error; | ||
6810 | int i; | ||
6811 | |||
6812 | error = kmalloc(sizeof(*error), GFP_ATOMIC); | ||
6813 | if (error == NULL) | ||
6814 | return NULL; | ||
6815 | |||
6816 | for (i = 0; i < 2; i++) { | ||
6817 | error->cursor[i].control = I915_READ(CURCNTR(i)); | ||
6818 | error->cursor[i].position = I915_READ(CURPOS(i)); | ||
6819 | error->cursor[i].base = I915_READ(CURBASE(i)); | ||
6820 | |||
6821 | error->plane[i].control = I915_READ(DSPCNTR(i)); | ||
6822 | error->plane[i].stride = I915_READ(DSPSTRIDE(i)); | ||
6823 | error->plane[i].size = I915_READ(DSPSIZE(i)); | ||
6824 | error->plane[i].pos= I915_READ(DSPPOS(i)); | ||
6825 | error->plane[i].addr = I915_READ(DSPADDR(i)); | ||
6826 | if (INTEL_INFO(dev)->gen >= 4) { | ||
6827 | error->plane[i].surface = I915_READ(DSPSURF(i)); | ||
6828 | error->plane[i].tile_offset = I915_READ(DSPTILEOFF(i)); | ||
6829 | } | ||
6830 | |||
6831 | error->pipe[i].conf = I915_READ(PIPECONF(i)); | ||
6832 | error->pipe[i].source = I915_READ(PIPESRC(i)); | ||
6833 | error->pipe[i].htotal = I915_READ(HTOTAL(i)); | ||
6834 | error->pipe[i].hblank = I915_READ(HBLANK(i)); | ||
6835 | error->pipe[i].hsync = I915_READ(HSYNC(i)); | ||
6836 | error->pipe[i].vtotal = I915_READ(VTOTAL(i)); | ||
6837 | error->pipe[i].vblank = I915_READ(VBLANK(i)); | ||
6838 | error->pipe[i].vsync = I915_READ(VSYNC(i)); | ||
6839 | } | ||
6840 | |||
6841 | return error; | ||
6842 | } | ||
6843 | |||
6844 | void | ||
6845 | intel_display_print_error_state(struct seq_file *m, | ||
6846 | struct drm_device *dev, | ||
6847 | struct intel_display_error_state *error) | ||
6848 | { | ||
6849 | int i; | ||
6850 | |||
6851 | for (i = 0; i < 2; i++) { | ||
6852 | seq_printf(m, "Pipe [%d]:\n", i); | ||
6853 | seq_printf(m, " CONF: %08x\n", error->pipe[i].conf); | ||
6854 | seq_printf(m, " SRC: %08x\n", error->pipe[i].source); | ||
6855 | seq_printf(m, " HTOTAL: %08x\n", error->pipe[i].htotal); | ||
6856 | seq_printf(m, " HBLANK: %08x\n", error->pipe[i].hblank); | ||
6857 | seq_printf(m, " HSYNC: %08x\n", error->pipe[i].hsync); | ||
6858 | seq_printf(m, " VTOTAL: %08x\n", error->pipe[i].vtotal); | ||
6859 | seq_printf(m, " VBLANK: %08x\n", error->pipe[i].vblank); | ||
6860 | seq_printf(m, " VSYNC: %08x\n", error->pipe[i].vsync); | ||
6861 | |||
6862 | seq_printf(m, "Plane [%d]:\n", i); | ||
6863 | seq_printf(m, " CNTR: %08x\n", error->plane[i].control); | ||
6864 | seq_printf(m, " STRIDE: %08x\n", error->plane[i].stride); | ||
6865 | seq_printf(m, " SIZE: %08x\n", error->plane[i].size); | ||
6866 | seq_printf(m, " POS: %08x\n", error->plane[i].pos); | ||
6867 | seq_printf(m, " ADDR: %08x\n", error->plane[i].addr); | ||
6868 | if (INTEL_INFO(dev)->gen >= 4) { | ||
6869 | seq_printf(m, " SURF: %08x\n", error->plane[i].surface); | ||
6870 | seq_printf(m, " TILEOFF: %08x\n", error->plane[i].tile_offset); | ||
6871 | } | ||
6872 | |||
6873 | seq_printf(m, "Cursor [%d]:\n", i); | ||
6874 | seq_printf(m, " CNTR: %08x\n", error->cursor[i].control); | ||
6875 | seq_printf(m, " POS: %08x\n", error->cursor[i].position); | ||
6876 | seq_printf(m, " BASE: %08x\n", error->cursor[i].base); | ||
6877 | } | ||
6878 | } | ||
6879 | #endif | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c8e00555331..1dc60408d5b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -479,6 +479,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
479 | uint16_t address = algo_data->address; | 479 | uint16_t address = algo_data->address; |
480 | uint8_t msg[5]; | 480 | uint8_t msg[5]; |
481 | uint8_t reply[2]; | 481 | uint8_t reply[2]; |
482 | unsigned retry; | ||
482 | int msg_bytes; | 483 | int msg_bytes; |
483 | int reply_bytes; | 484 | int reply_bytes; |
484 | int ret; | 485 | int ret; |
@@ -513,14 +514,33 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
513 | break; | 514 | break; |
514 | } | 515 | } |
515 | 516 | ||
516 | for (;;) { | 517 | for (retry = 0; retry < 5; retry++) { |
517 | ret = intel_dp_aux_ch(intel_dp, | 518 | ret = intel_dp_aux_ch(intel_dp, |
518 | msg, msg_bytes, | 519 | msg, msg_bytes, |
519 | reply, reply_bytes); | 520 | reply, reply_bytes); |
520 | if (ret < 0) { | 521 | if (ret < 0) { |
521 | DRM_DEBUG_KMS("aux_ch failed %d\n", ret); | 522 | DRM_DEBUG_KMS("aux_ch failed %d\n", ret); |
522 | return ret; | 523 | return ret; |
523 | } | 524 | } |
525 | |||
526 | switch (reply[0] & AUX_NATIVE_REPLY_MASK) { | ||
527 | case AUX_NATIVE_REPLY_ACK: | ||
528 | /* I2C-over-AUX Reply field is only valid | ||
529 | * when paired with AUX ACK. | ||
530 | */ | ||
531 | break; | ||
532 | case AUX_NATIVE_REPLY_NACK: | ||
533 | DRM_DEBUG_KMS("aux_ch native nack\n"); | ||
534 | return -EREMOTEIO; | ||
535 | case AUX_NATIVE_REPLY_DEFER: | ||
536 | udelay(100); | ||
537 | continue; | ||
538 | default: | ||
539 | DRM_ERROR("aux_ch invalid native reply 0x%02x\n", | ||
540 | reply[0]); | ||
541 | return -EREMOTEIO; | ||
542 | } | ||
543 | |||
524 | switch (reply[0] & AUX_I2C_REPLY_MASK) { | 544 | switch (reply[0] & AUX_I2C_REPLY_MASK) { |
525 | case AUX_I2C_REPLY_ACK: | 545 | case AUX_I2C_REPLY_ACK: |
526 | if (mode == MODE_I2C_READ) { | 546 | if (mode == MODE_I2C_READ) { |
@@ -528,17 +548,20 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
528 | } | 548 | } |
529 | return reply_bytes - 1; | 549 | return reply_bytes - 1; |
530 | case AUX_I2C_REPLY_NACK: | 550 | case AUX_I2C_REPLY_NACK: |
531 | DRM_DEBUG_KMS("aux_ch nack\n"); | 551 | DRM_DEBUG_KMS("aux_i2c nack\n"); |
532 | return -EREMOTEIO; | 552 | return -EREMOTEIO; |
533 | case AUX_I2C_REPLY_DEFER: | 553 | case AUX_I2C_REPLY_DEFER: |
534 | DRM_DEBUG_KMS("aux_ch defer\n"); | 554 | DRM_DEBUG_KMS("aux_i2c defer\n"); |
535 | udelay(100); | 555 | udelay(100); |
536 | break; | 556 | break; |
537 | default: | 557 | default: |
538 | DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]); | 558 | DRM_ERROR("aux_i2c invalid reply 0x%02x\n", reply[0]); |
539 | return -EREMOTEIO; | 559 | return -EREMOTEIO; |
540 | } | 560 | } |
541 | } | 561 | } |
562 | |||
563 | DRM_ERROR("too many retries, giving up\n"); | ||
564 | return -EREMOTEIO; | ||
542 | } | 565 | } |
543 | 566 | ||
544 | static int | 567 | static int |
@@ -584,17 +607,6 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
584 | mode->clock = dev_priv->panel_fixed_mode->clock; | 607 | mode->clock = dev_priv->panel_fixed_mode->clock; |
585 | } | 608 | } |
586 | 609 | ||
587 | /* Just use VBT values for eDP */ | ||
588 | if (is_edp(intel_dp)) { | ||
589 | intel_dp->lane_count = dev_priv->edp.lanes; | ||
590 | intel_dp->link_bw = dev_priv->edp.rate; | ||
591 | adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); | ||
592 | DRM_DEBUG_KMS("eDP link bw %02x lane count %d clock %d\n", | ||
593 | intel_dp->link_bw, intel_dp->lane_count, | ||
594 | adjusted_mode->clock); | ||
595 | return true; | ||
596 | } | ||
597 | |||
598 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { | 610 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { |
599 | for (clock = 0; clock <= max_clock; clock++) { | 611 | for (clock = 0; clock <= max_clock; clock++) { |
600 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); | 612 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); |
@@ -613,6 +625,19 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
613 | } | 625 | } |
614 | } | 626 | } |
615 | 627 | ||
628 | if (is_edp(intel_dp)) { | ||
629 | /* okay we failed just pick the highest */ | ||
630 | intel_dp->lane_count = max_lane_count; | ||
631 | intel_dp->link_bw = bws[max_clock]; | ||
632 | adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); | ||
633 | DRM_DEBUG_KMS("Force picking display port link bw %02x lane " | ||
634 | "count %d clock %d\n", | ||
635 | intel_dp->link_bw, intel_dp->lane_count, | ||
636 | adjusted_mode->clock); | ||
637 | |||
638 | return true; | ||
639 | } | ||
640 | |||
616 | return false; | 641 | return false; |
617 | } | 642 | } |
618 | 643 | ||
@@ -1087,21 +1112,11 @@ intel_get_adjust_train(struct intel_dp *intel_dp) | |||
1087 | } | 1112 | } |
1088 | 1113 | ||
1089 | static uint32_t | 1114 | static uint32_t |
1090 | intel_dp_signal_levels(struct intel_dp *intel_dp) | 1115 | intel_dp_signal_levels(uint8_t train_set, int lane_count) |
1091 | { | 1116 | { |
1092 | struct drm_device *dev = intel_dp->base.base.dev; | 1117 | uint32_t signal_levels = 0; |
1093 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1094 | uint32_t signal_levels = 0; | ||
1095 | u8 train_set = intel_dp->train_set[0]; | ||
1096 | u32 vswing = train_set & DP_TRAIN_VOLTAGE_SWING_MASK; | ||
1097 | u32 preemphasis = train_set & DP_TRAIN_PRE_EMPHASIS_MASK; | ||
1098 | 1118 | ||
1099 | if (is_edp(intel_dp)) { | 1119 | switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { |
1100 | vswing = dev_priv->edp.vswing; | ||
1101 | preemphasis = dev_priv->edp.preemphasis; | ||
1102 | } | ||
1103 | |||
1104 | switch (vswing) { | ||
1105 | case DP_TRAIN_VOLTAGE_SWING_400: | 1120 | case DP_TRAIN_VOLTAGE_SWING_400: |
1106 | default: | 1121 | default: |
1107 | signal_levels |= DP_VOLTAGE_0_4; | 1122 | signal_levels |= DP_VOLTAGE_0_4; |
@@ -1116,7 +1131,7 @@ intel_dp_signal_levels(struct intel_dp *intel_dp) | |||
1116 | signal_levels |= DP_VOLTAGE_1_2; | 1131 | signal_levels |= DP_VOLTAGE_1_2; |
1117 | break; | 1132 | break; |
1118 | } | 1133 | } |
1119 | switch (preemphasis) { | 1134 | switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) { |
1120 | case DP_TRAIN_PRE_EMPHASIS_0: | 1135 | case DP_TRAIN_PRE_EMPHASIS_0: |
1121 | default: | 1136 | default: |
1122 | signal_levels |= DP_PRE_EMPHASIS_0; | 1137 | signal_levels |= DP_PRE_EMPHASIS_0; |
@@ -1203,18 +1218,6 @@ intel_channel_eq_ok(struct intel_dp *intel_dp) | |||
1203 | } | 1218 | } |
1204 | 1219 | ||
1205 | static bool | 1220 | static bool |
1206 | intel_dp_aux_handshake_required(struct intel_dp *intel_dp) | ||
1207 | { | ||
1208 | struct drm_device *dev = intel_dp->base.base.dev; | ||
1209 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1210 | |||
1211 | if (is_edp(intel_dp) && dev_priv->no_aux_handshake) | ||
1212 | return false; | ||
1213 | |||
1214 | return true; | ||
1215 | } | ||
1216 | |||
1217 | static bool | ||
1218 | intel_dp_set_link_train(struct intel_dp *intel_dp, | 1221 | intel_dp_set_link_train(struct intel_dp *intel_dp, |
1219 | uint32_t dp_reg_value, | 1222 | uint32_t dp_reg_value, |
1220 | uint8_t dp_train_pat) | 1223 | uint8_t dp_train_pat) |
@@ -1226,9 +1229,6 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, | |||
1226 | I915_WRITE(intel_dp->output_reg, dp_reg_value); | 1229 | I915_WRITE(intel_dp->output_reg, dp_reg_value); |
1227 | POSTING_READ(intel_dp->output_reg); | 1230 | POSTING_READ(intel_dp->output_reg); |
1228 | 1231 | ||
1229 | if (!intel_dp_aux_handshake_required(intel_dp)) | ||
1230 | return true; | ||
1231 | |||
1232 | intel_dp_aux_native_write_1(intel_dp, | 1232 | intel_dp_aux_native_write_1(intel_dp, |
1233 | DP_TRAINING_PATTERN_SET, | 1233 | DP_TRAINING_PATTERN_SET, |
1234 | dp_train_pat); | 1234 | dp_train_pat); |
@@ -1261,11 +1261,10 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1261 | POSTING_READ(intel_dp->output_reg); | 1261 | POSTING_READ(intel_dp->output_reg); |
1262 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 1262 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1263 | 1263 | ||
1264 | if (intel_dp_aux_handshake_required(intel_dp)) | 1264 | /* Write the link configuration data */ |
1265 | /* Write the link configuration data */ | 1265 | intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, |
1266 | intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, | 1266 | intel_dp->link_configuration, |
1267 | intel_dp->link_configuration, | 1267 | DP_LINK_CONFIGURATION_SIZE); |
1268 | DP_LINK_CONFIGURATION_SIZE); | ||
1269 | 1268 | ||
1270 | DP |= DP_PORT_EN; | 1269 | DP |= DP_PORT_EN; |
1271 | if (HAS_PCH_CPT(dev) && !is_edp(intel_dp)) | 1270 | if (HAS_PCH_CPT(dev) && !is_edp(intel_dp)) |
@@ -1283,7 +1282,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1283 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); | 1282 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
1284 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1283 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1285 | } else { | 1284 | } else { |
1286 | signal_levels = intel_dp_signal_levels(intel_dp); | 1285 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); |
1287 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1286 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1288 | } | 1287 | } |
1289 | 1288 | ||
@@ -1297,37 +1296,33 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1297 | break; | 1296 | break; |
1298 | /* Set training pattern 1 */ | 1297 | /* Set training pattern 1 */ |
1299 | 1298 | ||
1300 | udelay(500); | 1299 | udelay(100); |
1301 | if (intel_dp_aux_handshake_required(intel_dp)) { | 1300 | if (!intel_dp_get_link_status(intel_dp)) |
1302 | break; | 1301 | break; |
1303 | } else { | ||
1304 | if (!intel_dp_get_link_status(intel_dp)) | ||
1305 | break; | ||
1306 | 1302 | ||
1307 | if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { | 1303 | if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { |
1308 | clock_recovery = true; | 1304 | clock_recovery = true; |
1309 | break; | 1305 | break; |
1310 | } | 1306 | } |
1311 | 1307 | ||
1312 | /* Check to see if we've tried the max voltage */ | 1308 | /* Check to see if we've tried the max voltage */ |
1313 | for (i = 0; i < intel_dp->lane_count; i++) | 1309 | for (i = 0; i < intel_dp->lane_count; i++) |
1314 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | 1310 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) |
1315 | break; | ||
1316 | if (i == intel_dp->lane_count) | ||
1317 | break; | 1311 | break; |
1312 | if (i == intel_dp->lane_count) | ||
1313 | break; | ||
1318 | 1314 | ||
1319 | /* Check to see if we've tried the same voltage 5 times */ | 1315 | /* Check to see if we've tried the same voltage 5 times */ |
1320 | if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { | 1316 | if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { |
1321 | ++tries; | 1317 | ++tries; |
1322 | if (tries == 5) | 1318 | if (tries == 5) |
1323 | break; | 1319 | break; |
1324 | } else | 1320 | } else |
1325 | tries = 0; | 1321 | tries = 0; |
1326 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | 1322 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; |
1327 | 1323 | ||
1328 | /* Compute new intel_dp->train_set as requested by target */ | 1324 | /* Compute new intel_dp->train_set as requested by target */ |
1329 | intel_get_adjust_train(intel_dp); | 1325 | intel_get_adjust_train(intel_dp); |
1330 | } | ||
1331 | } | 1326 | } |
1332 | 1327 | ||
1333 | intel_dp->DP = DP; | 1328 | intel_dp->DP = DP; |
@@ -1354,7 +1349,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1354 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); | 1349 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
1355 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1350 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1356 | } else { | 1351 | } else { |
1357 | signal_levels = intel_dp_signal_levels(intel_dp); | 1352 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); |
1358 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1353 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1359 | } | 1354 | } |
1360 | 1355 | ||
@@ -1368,28 +1363,24 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1368 | DP_TRAINING_PATTERN_2)) | 1363 | DP_TRAINING_PATTERN_2)) |
1369 | break; | 1364 | break; |
1370 | 1365 | ||
1371 | udelay(500); | 1366 | udelay(400); |
1372 | 1367 | if (!intel_dp_get_link_status(intel_dp)) | |
1373 | if (!intel_dp_aux_handshake_required(intel_dp)) { | ||
1374 | break; | 1368 | break; |
1375 | } else { | ||
1376 | if (!intel_dp_get_link_status(intel_dp)) | ||
1377 | break; | ||
1378 | 1369 | ||
1379 | if (intel_channel_eq_ok(intel_dp)) { | 1370 | if (intel_channel_eq_ok(intel_dp)) { |
1380 | channel_eq = true; | 1371 | channel_eq = true; |
1381 | break; | 1372 | break; |
1382 | } | 1373 | } |
1383 | 1374 | ||
1384 | /* Try 5 times */ | 1375 | /* Try 5 times */ |
1385 | if (tries > 5) | 1376 | if (tries > 5) |
1386 | break; | 1377 | break; |
1387 | 1378 | ||
1388 | /* Compute new intel_dp->train_set as requested by target */ | 1379 | /* Compute new intel_dp->train_set as requested by target */ |
1389 | intel_get_adjust_train(intel_dp); | 1380 | intel_get_adjust_train(intel_dp); |
1390 | ++tries; | 1381 | ++tries; |
1391 | } | ||
1392 | } | 1382 | } |
1383 | |||
1393 | if (HAS_PCH_CPT(dev) && !is_edp(intel_dp)) | 1384 | if (HAS_PCH_CPT(dev) && !is_edp(intel_dp)) |
1394 | reg = DP | DP_LINK_TRAIN_OFF_CPT; | 1385 | reg = DP | DP_LINK_TRAIN_OFF_CPT; |
1395 | else | 1386 | else |
@@ -1408,6 +1399,9 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1408 | struct drm_i915_private *dev_priv = dev->dev_private; | 1399 | struct drm_i915_private *dev_priv = dev->dev_private; |
1409 | uint32_t DP = intel_dp->DP; | 1400 | uint32_t DP = intel_dp->DP; |
1410 | 1401 | ||
1402 | if ((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0) | ||
1403 | return; | ||
1404 | |||
1411 | DRM_DEBUG_KMS("\n"); | 1405 | DRM_DEBUG_KMS("\n"); |
1412 | 1406 | ||
1413 | if (is_edp(intel_dp)) { | 1407 | if (is_edp(intel_dp)) { |
@@ -1430,6 +1424,27 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1430 | 1424 | ||
1431 | if (is_edp(intel_dp)) | 1425 | if (is_edp(intel_dp)) |
1432 | DP |= DP_LINK_TRAIN_OFF; | 1426 | DP |= DP_LINK_TRAIN_OFF; |
1427 | |||
1428 | if (!HAS_PCH_CPT(dev) && | ||
1429 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { | ||
1430 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); | ||
1431 | /* Hardware workaround: leaving our transcoder select | ||
1432 | * set to transcoder B while it's off will prevent the | ||
1433 | * corresponding HDMI output on transcoder A. | ||
1434 | * | ||
1435 | * Combine this with another hardware workaround: | ||
1436 | * transcoder select bit can only be cleared while the | ||
1437 | * port is enabled. | ||
1438 | */ | ||
1439 | DP &= ~DP_PIPEB_SELECT; | ||
1440 | I915_WRITE(intel_dp->output_reg, DP); | ||
1441 | |||
1442 | /* Changes to enable or select take place the vblank | ||
1443 | * after being written. | ||
1444 | */ | ||
1445 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
1446 | } | ||
1447 | |||
1433 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); | 1448 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); |
1434 | POSTING_READ(intel_dp->output_reg); | 1449 | POSTING_READ(intel_dp->output_reg); |
1435 | } | 1450 | } |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 21551fe7454..d782ad9fd6d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -127,7 +127,7 @@ intel_mode_get_pixel_multiplier(const struct drm_display_mode *mode) | |||
127 | 127 | ||
128 | struct intel_framebuffer { | 128 | struct intel_framebuffer { |
129 | struct drm_framebuffer base; | 129 | struct drm_framebuffer base; |
130 | struct drm_gem_object *obj; | 130 | struct drm_i915_gem_object *obj; |
131 | }; | 131 | }; |
132 | 132 | ||
133 | struct intel_fbdev { | 133 | struct intel_fbdev { |
@@ -166,7 +166,7 @@ struct intel_crtc { | |||
166 | struct intel_unpin_work *unpin_work; | 166 | struct intel_unpin_work *unpin_work; |
167 | int fdi_lanes; | 167 | int fdi_lanes; |
168 | 168 | ||
169 | struct drm_gem_object *cursor_bo; | 169 | struct drm_i915_gem_object *cursor_bo; |
170 | uint32_t cursor_addr; | 170 | uint32_t cursor_addr; |
171 | int16_t cursor_x, cursor_y; | 171 | int16_t cursor_x, cursor_y; |
172 | int16_t cursor_width, cursor_height; | 172 | int16_t cursor_width, cursor_height; |
@@ -220,8 +220,8 @@ intel_get_crtc_for_pipe(struct drm_device *dev, int pipe) | |||
220 | struct intel_unpin_work { | 220 | struct intel_unpin_work { |
221 | struct work_struct work; | 221 | struct work_struct work; |
222 | struct drm_device *dev; | 222 | struct drm_device *dev; |
223 | struct drm_gem_object *old_fb_obj; | 223 | struct drm_i915_gem_object *old_fb_obj; |
224 | struct drm_gem_object *pending_flip_obj; | 224 | struct drm_i915_gem_object *pending_flip_obj; |
225 | struct drm_pending_vblank_event *event; | 225 | struct drm_pending_vblank_event *event; |
226 | int pending; | 226 | int pending; |
227 | bool enable_stall_check; | 227 | bool enable_stall_check; |
@@ -236,8 +236,9 @@ void intel_dip_infoframe_csum(struct dip_infoframe *avi_if); | |||
236 | extern bool intel_sdvo_init(struct drm_device *dev, int output_device); | 236 | extern bool intel_sdvo_init(struct drm_device *dev, int output_device); |
237 | extern void intel_dvo_init(struct drm_device *dev); | 237 | extern void intel_dvo_init(struct drm_device *dev); |
238 | extern void intel_tv_init(struct drm_device *dev); | 238 | extern void intel_tv_init(struct drm_device *dev); |
239 | extern void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj); | 239 | extern void intel_mark_busy(struct drm_device *dev, |
240 | extern void intel_lvds_init(struct drm_device *dev); | 240 | struct drm_i915_gem_object *obj); |
241 | extern bool intel_lvds_init(struct drm_device *dev); | ||
241 | extern void intel_dp_init(struct drm_device *dev, int dp_reg); | 242 | extern void intel_dp_init(struct drm_device *dev, int dp_reg); |
242 | void | 243 | void |
243 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | 244 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, |
@@ -293,19 +294,22 @@ extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, | |||
293 | u16 blue, int regno); | 294 | u16 blue, int regno); |
294 | extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, | 295 | extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, |
295 | u16 *blue, int regno); | 296 | u16 *blue, int regno); |
296 | extern void intel_init_clock_gating(struct drm_device *dev); | 297 | extern void intel_enable_clock_gating(struct drm_device *dev); |
298 | extern void intel_disable_clock_gating(struct drm_device *dev); | ||
297 | extern void ironlake_enable_drps(struct drm_device *dev); | 299 | extern void ironlake_enable_drps(struct drm_device *dev); |
298 | extern void ironlake_disable_drps(struct drm_device *dev); | 300 | extern void ironlake_disable_drps(struct drm_device *dev); |
301 | extern void gen6_enable_rps(struct drm_i915_private *dev_priv); | ||
302 | extern void gen6_disable_rps(struct drm_device *dev); | ||
299 | extern void intel_init_emon(struct drm_device *dev); | 303 | extern void intel_init_emon(struct drm_device *dev); |
300 | 304 | ||
301 | extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, | 305 | extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, |
302 | struct drm_gem_object *obj, | 306 | struct drm_i915_gem_object *obj, |
303 | bool pipelined); | 307 | struct intel_ring_buffer *pipelined); |
304 | 308 | ||
305 | extern int intel_framebuffer_init(struct drm_device *dev, | 309 | extern int intel_framebuffer_init(struct drm_device *dev, |
306 | struct intel_framebuffer *ifb, | 310 | struct intel_framebuffer *ifb, |
307 | struct drm_mode_fb_cmd *mode_cmd, | 311 | struct drm_mode_fb_cmd *mode_cmd, |
308 | struct drm_gem_object *obj); | 312 | struct drm_i915_gem_object *obj); |
309 | extern int intel_fbdev_init(struct drm_device *dev); | 313 | extern int intel_fbdev_init(struct drm_device *dev); |
310 | extern void intel_fbdev_fini(struct drm_device *dev); | 314 | extern void intel_fbdev_fini(struct drm_device *dev); |
311 | 315 | ||
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index ced3eef8da0..67738f32dfd 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -65,8 +65,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
65 | struct fb_info *info; | 65 | struct fb_info *info; |
66 | struct drm_framebuffer *fb; | 66 | struct drm_framebuffer *fb; |
67 | struct drm_mode_fb_cmd mode_cmd; | 67 | struct drm_mode_fb_cmd mode_cmd; |
68 | struct drm_gem_object *fbo = NULL; | 68 | struct drm_i915_gem_object *obj; |
69 | struct drm_i915_gem_object *obj_priv; | ||
70 | struct device *device = &dev->pdev->dev; | 69 | struct device *device = &dev->pdev->dev; |
71 | int size, ret; | 70 | int size, ret; |
72 | 71 | ||
@@ -83,18 +82,17 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
83 | 82 | ||
84 | size = mode_cmd.pitch * mode_cmd.height; | 83 | size = mode_cmd.pitch * mode_cmd.height; |
85 | size = ALIGN(size, PAGE_SIZE); | 84 | size = ALIGN(size, PAGE_SIZE); |
86 | fbo = i915_gem_alloc_object(dev, size); | 85 | obj = i915_gem_alloc_object(dev, size); |
87 | if (!fbo) { | 86 | if (!obj) { |
88 | DRM_ERROR("failed to allocate framebuffer\n"); | 87 | DRM_ERROR("failed to allocate framebuffer\n"); |
89 | ret = -ENOMEM; | 88 | ret = -ENOMEM; |
90 | goto out; | 89 | goto out; |
91 | } | 90 | } |
92 | obj_priv = to_intel_bo(fbo); | ||
93 | 91 | ||
94 | mutex_lock(&dev->struct_mutex); | 92 | mutex_lock(&dev->struct_mutex); |
95 | 93 | ||
96 | /* Flush everything out, we'll be doing GTT only from now on */ | 94 | /* Flush everything out, we'll be doing GTT only from now on */ |
97 | ret = intel_pin_and_fence_fb_obj(dev, fbo, false); | 95 | ret = intel_pin_and_fence_fb_obj(dev, obj, false); |
98 | if (ret) { | 96 | if (ret) { |
99 | DRM_ERROR("failed to pin fb: %d\n", ret); | 97 | DRM_ERROR("failed to pin fb: %d\n", ret); |
100 | goto out_unref; | 98 | goto out_unref; |
@@ -108,7 +106,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
108 | 106 | ||
109 | info->par = ifbdev; | 107 | info->par = ifbdev; |
110 | 108 | ||
111 | ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, fbo); | 109 | ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj); |
112 | if (ret) | 110 | if (ret) |
113 | goto out_unpin; | 111 | goto out_unpin; |
114 | 112 | ||
@@ -134,11 +132,10 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
134 | else | 132 | else |
135 | info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0); | 133 | info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0); |
136 | 134 | ||
137 | info->fix.smem_start = dev->mode_config.fb_base + obj_priv->gtt_offset; | 135 | info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset; |
138 | info->fix.smem_len = size; | 136 | info->fix.smem_len = size; |
139 | 137 | ||
140 | info->screen_base = ioremap_wc(dev->agp->base + obj_priv->gtt_offset, | 138 | info->screen_base = ioremap_wc(dev->agp->base + obj->gtt_offset, size); |
141 | size); | ||
142 | if (!info->screen_base) { | 139 | if (!info->screen_base) { |
143 | ret = -ENOSPC; | 140 | ret = -ENOSPC; |
144 | goto out_unpin; | 141 | goto out_unpin; |
@@ -164,7 +161,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
164 | 161 | ||
165 | DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n", | 162 | DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n", |
166 | fb->width, fb->height, | 163 | fb->width, fb->height, |
167 | obj_priv->gtt_offset, fbo); | 164 | obj->gtt_offset, obj); |
168 | 165 | ||
169 | 166 | ||
170 | mutex_unlock(&dev->struct_mutex); | 167 | mutex_unlock(&dev->struct_mutex); |
@@ -172,9 +169,9 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
172 | return 0; | 169 | return 0; |
173 | 170 | ||
174 | out_unpin: | 171 | out_unpin: |
175 | i915_gem_object_unpin(fbo); | 172 | i915_gem_object_unpin(obj); |
176 | out_unref: | 173 | out_unref: |
177 | drm_gem_object_unreference(fbo); | 174 | drm_gem_object_unreference(&obj->base); |
178 | mutex_unlock(&dev->struct_mutex); | 175 | mutex_unlock(&dev->struct_mutex); |
179 | out: | 176 | out: |
180 | return ret; | 177 | return ret; |
@@ -221,7 +218,7 @@ static void intel_fbdev_destroy(struct drm_device *dev, | |||
221 | 218 | ||
222 | drm_framebuffer_cleanup(&ifb->base); | 219 | drm_framebuffer_cleanup(&ifb->base); |
223 | if (ifb->obj) { | 220 | if (ifb->obj) { |
224 | drm_gem_object_unreference_unlocked(ifb->obj); | 221 | drm_gem_object_unreference_unlocked(&ifb->obj->base); |
225 | ifb->obj = NULL; | 222 | ifb->obj = NULL; |
226 | } | 223 | } |
227 | } | 224 | } |
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 3dba086e7ee..58040f68ed7 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -85,8 +85,9 @@ static u32 get_reserved(struct intel_gpio *gpio) | |||
85 | 85 | ||
86 | /* On most chips, these bits must be preserved in software. */ | 86 | /* On most chips, these bits must be preserved in software. */ |
87 | if (!IS_I830(dev) && !IS_845G(dev)) | 87 | if (!IS_I830(dev) && !IS_845G(dev)) |
88 | reserved = I915_READ(gpio->reg) & (GPIO_DATA_PULLUP_DISABLE | | 88 | reserved = I915_READ_NOTRACE(gpio->reg) & |
89 | GPIO_CLOCK_PULLUP_DISABLE); | 89 | (GPIO_DATA_PULLUP_DISABLE | |
90 | GPIO_CLOCK_PULLUP_DISABLE); | ||
90 | 91 | ||
91 | return reserved; | 92 | return reserved; |
92 | } | 93 | } |
@@ -96,9 +97,9 @@ static int get_clock(void *data) | |||
96 | struct intel_gpio *gpio = data; | 97 | struct intel_gpio *gpio = data; |
97 | struct drm_i915_private *dev_priv = gpio->dev_priv; | 98 | struct drm_i915_private *dev_priv = gpio->dev_priv; |
98 | u32 reserved = get_reserved(gpio); | 99 | u32 reserved = get_reserved(gpio); |
99 | I915_WRITE(gpio->reg, reserved | GPIO_CLOCK_DIR_MASK); | 100 | I915_WRITE_NOTRACE(gpio->reg, reserved | GPIO_CLOCK_DIR_MASK); |
100 | I915_WRITE(gpio->reg, reserved); | 101 | I915_WRITE_NOTRACE(gpio->reg, reserved); |
101 | return (I915_READ(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0; | 102 | return (I915_READ_NOTRACE(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0; |
102 | } | 103 | } |
103 | 104 | ||
104 | static int get_data(void *data) | 105 | static int get_data(void *data) |
@@ -106,9 +107,9 @@ static int get_data(void *data) | |||
106 | struct intel_gpio *gpio = data; | 107 | struct intel_gpio *gpio = data; |
107 | struct drm_i915_private *dev_priv = gpio->dev_priv; | 108 | struct drm_i915_private *dev_priv = gpio->dev_priv; |
108 | u32 reserved = get_reserved(gpio); | 109 | u32 reserved = get_reserved(gpio); |
109 | I915_WRITE(gpio->reg, reserved | GPIO_DATA_DIR_MASK); | 110 | I915_WRITE_NOTRACE(gpio->reg, reserved | GPIO_DATA_DIR_MASK); |
110 | I915_WRITE(gpio->reg, reserved); | 111 | I915_WRITE_NOTRACE(gpio->reg, reserved); |
111 | return (I915_READ(gpio->reg) & GPIO_DATA_VAL_IN) != 0; | 112 | return (I915_READ_NOTRACE(gpio->reg) & GPIO_DATA_VAL_IN) != 0; |
112 | } | 113 | } |
113 | 114 | ||
114 | static void set_clock(void *data, int state_high) | 115 | static void set_clock(void *data, int state_high) |
@@ -124,7 +125,7 @@ static void set_clock(void *data, int state_high) | |||
124 | clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | | 125 | clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | |
125 | GPIO_CLOCK_VAL_MASK; | 126 | GPIO_CLOCK_VAL_MASK; |
126 | 127 | ||
127 | I915_WRITE(gpio->reg, reserved | clock_bits); | 128 | I915_WRITE_NOTRACE(gpio->reg, reserved | clock_bits); |
128 | POSTING_READ(gpio->reg); | 129 | POSTING_READ(gpio->reg); |
129 | } | 130 | } |
130 | 131 | ||
@@ -141,7 +142,7 @@ static void set_data(void *data, int state_high) | |||
141 | data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | | 142 | data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | |
142 | GPIO_DATA_VAL_MASK; | 143 | GPIO_DATA_VAL_MASK; |
143 | 144 | ||
144 | I915_WRITE(gpio->reg, reserved | data_bits); | 145 | I915_WRITE_NOTRACE(gpio->reg, reserved | data_bits); |
145 | POSTING_READ(gpio->reg); | 146 | POSTING_READ(gpio->reg); |
146 | } | 147 | } |
147 | 148 | ||
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 4324a326f98..aa2307080be 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -68,7 +68,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector) | |||
68 | /** | 68 | /** |
69 | * Sets the power state for the panel. | 69 | * Sets the power state for the panel. |
70 | */ | 70 | */ |
71 | static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on) | 71 | static void intel_lvds_enable(struct intel_lvds *intel_lvds) |
72 | { | 72 | { |
73 | struct drm_device *dev = intel_lvds->base.base.dev; | 73 | struct drm_device *dev = intel_lvds->base.base.dev; |
74 | struct drm_i915_private *dev_priv = dev->dev_private; | 74 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -82,26 +82,61 @@ static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on) | |||
82 | lvds_reg = LVDS; | 82 | lvds_reg = LVDS; |
83 | } | 83 | } |
84 | 84 | ||
85 | if (on) { | 85 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); |
86 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); | ||
87 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); | ||
88 | intel_panel_set_backlight(dev, dev_priv->backlight_level); | ||
89 | } else { | ||
90 | dev_priv->backlight_level = intel_panel_get_backlight(dev); | ||
91 | |||
92 | intel_panel_set_backlight(dev, 0); | ||
93 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); | ||
94 | 86 | ||
95 | if (intel_lvds->pfit_control) { | 87 | if (intel_lvds->pfit_dirty) { |
96 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) | 88 | /* |
97 | DRM_ERROR("timed out waiting for panel to power off\n"); | 89 | * Enable automatic panel scaling so that non-native modes |
98 | I915_WRITE(PFIT_CONTROL, 0); | 90 | * fill the screen. The panel fitter should only be |
99 | intel_lvds->pfit_control = 0; | 91 | * adjusted whilst the pipe is disabled, according to |
92 | * register description and PRM. | ||
93 | */ | ||
94 | DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", | ||
95 | intel_lvds->pfit_control, | ||
96 | intel_lvds->pfit_pgm_ratios); | ||
97 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) { | ||
98 | DRM_ERROR("timed out waiting for panel to power off\n"); | ||
99 | } else { | ||
100 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); | ||
101 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); | ||
100 | intel_lvds->pfit_dirty = false; | 102 | intel_lvds->pfit_dirty = false; |
101 | } | 103 | } |
104 | } | ||
105 | |||
106 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); | ||
107 | POSTING_READ(lvds_reg); | ||
102 | 108 | ||
103 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); | 109 | intel_panel_set_backlight(dev, dev_priv->backlight_level); |
110 | } | ||
111 | |||
112 | static void intel_lvds_disable(struct intel_lvds *intel_lvds) | ||
113 | { | ||
114 | struct drm_device *dev = intel_lvds->base.base.dev; | ||
115 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
116 | u32 ctl_reg, lvds_reg; | ||
117 | |||
118 | if (HAS_PCH_SPLIT(dev)) { | ||
119 | ctl_reg = PCH_PP_CONTROL; | ||
120 | lvds_reg = PCH_LVDS; | ||
121 | } else { | ||
122 | ctl_reg = PP_CONTROL; | ||
123 | lvds_reg = LVDS; | ||
104 | } | 124 | } |
125 | |||
126 | dev_priv->backlight_level = intel_panel_get_backlight(dev); | ||
127 | intel_panel_set_backlight(dev, 0); | ||
128 | |||
129 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); | ||
130 | |||
131 | if (intel_lvds->pfit_control) { | ||
132 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) | ||
133 | DRM_ERROR("timed out waiting for panel to power off\n"); | ||
134 | |||
135 | I915_WRITE(PFIT_CONTROL, 0); | ||
136 | intel_lvds->pfit_dirty = true; | ||
137 | } | ||
138 | |||
139 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); | ||
105 | POSTING_READ(lvds_reg); | 140 | POSTING_READ(lvds_reg); |
106 | } | 141 | } |
107 | 142 | ||
@@ -110,9 +145,9 @@ static void intel_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
110 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | 145 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
111 | 146 | ||
112 | if (mode == DRM_MODE_DPMS_ON) | 147 | if (mode == DRM_MODE_DPMS_ON) |
113 | intel_lvds_set_power(intel_lvds, true); | 148 | intel_lvds_enable(intel_lvds); |
114 | else | 149 | else |
115 | intel_lvds_set_power(intel_lvds, false); | 150 | intel_lvds_disable(intel_lvds); |
116 | 151 | ||
117 | /* XXX: We never power down the LVDS pairs. */ | 152 | /* XXX: We never power down the LVDS pairs. */ |
118 | } | 153 | } |
@@ -269,14 +304,13 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
269 | u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; | 304 | u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; |
270 | u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; | 305 | u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; |
271 | 306 | ||
272 | pfit_control |= PFIT_ENABLE; | ||
273 | /* 965+ is easy, it does everything in hw */ | 307 | /* 965+ is easy, it does everything in hw */ |
274 | if (scaled_width > scaled_height) | 308 | if (scaled_width > scaled_height) |
275 | pfit_control |= PFIT_SCALING_PILLAR; | 309 | pfit_control |= PFIT_ENABLE | PFIT_SCALING_PILLAR; |
276 | else if (scaled_width < scaled_height) | 310 | else if (scaled_width < scaled_height) |
277 | pfit_control |= PFIT_SCALING_LETTER; | 311 | pfit_control |= PFIT_ENABLE | PFIT_SCALING_LETTER; |
278 | else | 312 | else if (adjusted_mode->hdisplay != mode->hdisplay) |
279 | pfit_control |= PFIT_SCALING_AUTO; | 313 | pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; |
280 | } else { | 314 | } else { |
281 | u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; | 315 | u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; |
282 | u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; | 316 | u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; |
@@ -323,13 +357,17 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
323 | * Full scaling, even if it changes the aspect ratio. | 357 | * Full scaling, even if it changes the aspect ratio. |
324 | * Fortunately this is all done for us in hw. | 358 | * Fortunately this is all done for us in hw. |
325 | */ | 359 | */ |
326 | pfit_control |= PFIT_ENABLE; | 360 | if (mode->vdisplay != adjusted_mode->vdisplay || |
327 | if (INTEL_INFO(dev)->gen >= 4) | 361 | mode->hdisplay != adjusted_mode->hdisplay) { |
328 | pfit_control |= PFIT_SCALING_AUTO; | 362 | pfit_control |= PFIT_ENABLE; |
329 | else | 363 | if (INTEL_INFO(dev)->gen >= 4) |
330 | pfit_control |= (VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | | 364 | pfit_control |= PFIT_SCALING_AUTO; |
331 | VERT_INTERP_BILINEAR | | 365 | else |
332 | HORIZ_INTERP_BILINEAR); | 366 | pfit_control |= (VERT_AUTO_SCALE | |
367 | VERT_INTERP_BILINEAR | | ||
368 | HORIZ_AUTO_SCALE | | ||
369 | HORIZ_INTERP_BILINEAR); | ||
370 | } | ||
333 | break; | 371 | break; |
334 | 372 | ||
335 | default: | 373 | default: |
@@ -411,43 +449,18 @@ static void intel_lvds_commit(struct drm_encoder *encoder) | |||
411 | /* Always do a full power on as we do not know what state | 449 | /* Always do a full power on as we do not know what state |
412 | * we were left in. | 450 | * we were left in. |
413 | */ | 451 | */ |
414 | intel_lvds_set_power(intel_lvds, true); | 452 | intel_lvds_enable(intel_lvds); |
415 | } | 453 | } |
416 | 454 | ||
417 | static void intel_lvds_mode_set(struct drm_encoder *encoder, | 455 | static void intel_lvds_mode_set(struct drm_encoder *encoder, |
418 | struct drm_display_mode *mode, | 456 | struct drm_display_mode *mode, |
419 | struct drm_display_mode *adjusted_mode) | 457 | struct drm_display_mode *adjusted_mode) |
420 | { | 458 | { |
421 | struct drm_device *dev = encoder->dev; | ||
422 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
423 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | ||
424 | |||
425 | /* | 459 | /* |
426 | * The LVDS pin pair will already have been turned on in the | 460 | * The LVDS pin pair will already have been turned on in the |
427 | * intel_crtc_mode_set since it has a large impact on the DPLL | 461 | * intel_crtc_mode_set since it has a large impact on the DPLL |
428 | * settings. | 462 | * settings. |
429 | */ | 463 | */ |
430 | |||
431 | if (HAS_PCH_SPLIT(dev)) | ||
432 | return; | ||
433 | |||
434 | if (!intel_lvds->pfit_dirty) | ||
435 | return; | ||
436 | |||
437 | /* | ||
438 | * Enable automatic panel scaling so that non-native modes fill the | ||
439 | * screen. Should be enabled before the pipe is enabled, according to | ||
440 | * register description and PRM. | ||
441 | */ | ||
442 | DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", | ||
443 | intel_lvds->pfit_control, | ||
444 | intel_lvds->pfit_pgm_ratios); | ||
445 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) | ||
446 | DRM_ERROR("timed out waiting for panel to power off\n"); | ||
447 | |||
448 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); | ||
449 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); | ||
450 | intel_lvds->pfit_dirty = false; | ||
451 | } | 464 | } |
452 | 465 | ||
453 | /** | 466 | /** |
@@ -837,7 +850,7 @@ static bool intel_lvds_ddc_probe(struct drm_device *dev, u8 pin) | |||
837 | * Create the connector, register the LVDS DDC bus, and try to figure out what | 850 | * Create the connector, register the LVDS DDC bus, and try to figure out what |
838 | * modes we can display on the LVDS panel (if present). | 851 | * modes we can display on the LVDS panel (if present). |
839 | */ | 852 | */ |
840 | void intel_lvds_init(struct drm_device *dev) | 853 | bool intel_lvds_init(struct drm_device *dev) |
841 | { | 854 | { |
842 | struct drm_i915_private *dev_priv = dev->dev_private; | 855 | struct drm_i915_private *dev_priv = dev->dev_private; |
843 | struct intel_lvds *intel_lvds; | 856 | struct intel_lvds *intel_lvds; |
@@ -853,37 +866,37 @@ void intel_lvds_init(struct drm_device *dev) | |||
853 | 866 | ||
854 | /* Skip init on machines we know falsely report LVDS */ | 867 | /* Skip init on machines we know falsely report LVDS */ |
855 | if (dmi_check_system(intel_no_lvds)) | 868 | if (dmi_check_system(intel_no_lvds)) |
856 | return; | 869 | return false; |
857 | 870 | ||
858 | pin = GMBUS_PORT_PANEL; | 871 | pin = GMBUS_PORT_PANEL; |
859 | if (!lvds_is_present_in_vbt(dev, &pin)) { | 872 | if (!lvds_is_present_in_vbt(dev, &pin)) { |
860 | DRM_DEBUG_KMS("LVDS is not present in VBT\n"); | 873 | DRM_DEBUG_KMS("LVDS is not present in VBT\n"); |
861 | return; | 874 | return false; |
862 | } | 875 | } |
863 | 876 | ||
864 | if (HAS_PCH_SPLIT(dev)) { | 877 | if (HAS_PCH_SPLIT(dev)) { |
865 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) | 878 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) |
866 | return; | 879 | return false; |
867 | if (dev_priv->edp.support) { | 880 | if (dev_priv->edp.support) { |
868 | DRM_DEBUG_KMS("disable LVDS for eDP support\n"); | 881 | DRM_DEBUG_KMS("disable LVDS for eDP support\n"); |
869 | return; | 882 | return false; |
870 | } | 883 | } |
871 | } | 884 | } |
872 | 885 | ||
873 | if (!intel_lvds_ddc_probe(dev, pin)) { | 886 | if (!intel_lvds_ddc_probe(dev, pin)) { |
874 | DRM_DEBUG_KMS("LVDS did not respond to DDC probe\n"); | 887 | DRM_DEBUG_KMS("LVDS did not respond to DDC probe\n"); |
875 | return; | 888 | return false; |
876 | } | 889 | } |
877 | 890 | ||
878 | intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL); | 891 | intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL); |
879 | if (!intel_lvds) { | 892 | if (!intel_lvds) { |
880 | return; | 893 | return false; |
881 | } | 894 | } |
882 | 895 | ||
883 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 896 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
884 | if (!intel_connector) { | 897 | if (!intel_connector) { |
885 | kfree(intel_lvds); | 898 | kfree(intel_lvds); |
886 | return; | 899 | return false; |
887 | } | 900 | } |
888 | 901 | ||
889 | if (!HAS_PCH_SPLIT(dev)) { | 902 | if (!HAS_PCH_SPLIT(dev)) { |
@@ -904,6 +917,8 @@ void intel_lvds_init(struct drm_device *dev) | |||
904 | 917 | ||
905 | intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); | 918 | intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); |
906 | intel_encoder->crtc_mask = (1 << 1); | 919 | intel_encoder->crtc_mask = (1 << 1); |
920 | if (INTEL_INFO(dev)->gen >= 5) | ||
921 | intel_encoder->crtc_mask |= (1 << 0); | ||
907 | drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); | 922 | drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); |
908 | drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); | 923 | drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); |
909 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | 924 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; |
@@ -1009,10 +1024,18 @@ void intel_lvds_init(struct drm_device *dev) | |||
1009 | out: | 1024 | out: |
1010 | if (HAS_PCH_SPLIT(dev)) { | 1025 | if (HAS_PCH_SPLIT(dev)) { |
1011 | u32 pwm; | 1026 | u32 pwm; |
1012 | /* make sure PWM is enabled */ | 1027 | |
1028 | pipe = (I915_READ(PCH_LVDS) & LVDS_PIPEB_SELECT) ? 1 : 0; | ||
1029 | |||
1030 | /* make sure PWM is enabled and locked to the LVDS pipe */ | ||
1013 | pwm = I915_READ(BLC_PWM_CPU_CTL2); | 1031 | pwm = I915_READ(BLC_PWM_CPU_CTL2); |
1014 | pwm |= (PWM_ENABLE | PWM_PIPE_B); | 1032 | if (pipe == 0 && (pwm & PWM_PIPE_B)) |
1015 | I915_WRITE(BLC_PWM_CPU_CTL2, pwm); | 1033 | I915_WRITE(BLC_PWM_CPU_CTL2, pwm & ~PWM_ENABLE); |
1034 | if (pipe) | ||
1035 | pwm |= PWM_PIPE_B; | ||
1036 | else | ||
1037 | pwm &= ~PWM_PIPE_B; | ||
1038 | I915_WRITE(BLC_PWM_CPU_CTL2, pwm | PWM_ENABLE); | ||
1016 | 1039 | ||
1017 | pwm = I915_READ(BLC_PWM_PCH_CTL1); | 1040 | pwm = I915_READ(BLC_PWM_PCH_CTL1); |
1018 | pwm |= PWM_PCH_ENABLE; | 1041 | pwm |= PWM_PCH_ENABLE; |
@@ -1026,7 +1049,7 @@ out: | |||
1026 | /* keep the LVDS connector */ | 1049 | /* keep the LVDS connector */ |
1027 | dev_priv->int_lvds_connector = connector; | 1050 | dev_priv->int_lvds_connector = connector; |
1028 | drm_sysfs_connector_add(connector); | 1051 | drm_sysfs_connector_add(connector); |
1029 | return; | 1052 | return true; |
1030 | 1053 | ||
1031 | failed: | 1054 | failed: |
1032 | DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); | 1055 | DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); |
@@ -1034,4 +1057,5 @@ failed: | |||
1034 | drm_encoder_cleanup(encoder); | 1057 | drm_encoder_cleanup(encoder); |
1035 | kfree(intel_lvds); | 1058 | kfree(intel_lvds); |
1036 | kfree(intel_connector); | 1059 | kfree(intel_connector); |
1060 | return false; | ||
1037 | } | 1061 | } |
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 9b0d9a867ae..f295a7aaadf 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c | |||
@@ -273,14 +273,8 @@ void intel_opregion_enable_asle(struct drm_device *dev) | |||
273 | struct opregion_asle *asle = dev_priv->opregion.asle; | 273 | struct opregion_asle *asle = dev_priv->opregion.asle; |
274 | 274 | ||
275 | if (asle) { | 275 | if (asle) { |
276 | if (IS_MOBILE(dev)) { | 276 | if (IS_MOBILE(dev)) |
277 | unsigned long irqflags; | ||
278 | |||
279 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | ||
280 | intel_enable_asle(dev); | 277 | intel_enable_asle(dev); |
281 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, | ||
282 | irqflags); | ||
283 | } | ||
284 | 278 | ||
285 | asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN | | 279 | asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN | |
286 | ASLE_PFMB_EN; | 280 | ASLE_PFMB_EN; |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 02ff0a481f4..3fbb98b948d 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -221,15 +221,16 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, | |||
221 | int ret; | 221 | int ret; |
222 | 222 | ||
223 | BUG_ON(overlay->last_flip_req); | 223 | BUG_ON(overlay->last_flip_req); |
224 | overlay->last_flip_req = | 224 | ret = i915_add_request(dev, NULL, request, LP_RING(dev_priv)); |
225 | i915_add_request(dev, NULL, request, &dev_priv->render_ring); | 225 | if (ret) { |
226 | if (overlay->last_flip_req == 0) | 226 | kfree(request); |
227 | return -ENOMEM; | 227 | return ret; |
228 | 228 | } | |
229 | overlay->last_flip_req = request->seqno; | ||
229 | overlay->flip_tail = tail; | 230 | overlay->flip_tail = tail; |
230 | ret = i915_do_wait_request(dev, | 231 | ret = i915_do_wait_request(dev, |
231 | overlay->last_flip_req, true, | 232 | overlay->last_flip_req, true, |
232 | &dev_priv->render_ring); | 233 | LP_RING(dev_priv)); |
233 | if (ret) | 234 | if (ret) |
234 | return ret; | 235 | return ret; |
235 | 236 | ||
@@ -289,6 +290,7 @@ i830_deactivate_pipe_a(struct drm_device *dev) | |||
289 | static int intel_overlay_on(struct intel_overlay *overlay) | 290 | static int intel_overlay_on(struct intel_overlay *overlay) |
290 | { | 291 | { |
291 | struct drm_device *dev = overlay->dev; | 292 | struct drm_device *dev = overlay->dev; |
293 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
292 | struct drm_i915_gem_request *request; | 294 | struct drm_i915_gem_request *request; |
293 | int pipe_a_quirk = 0; | 295 | int pipe_a_quirk = 0; |
294 | int ret; | 296 | int ret; |
@@ -308,7 +310,12 @@ static int intel_overlay_on(struct intel_overlay *overlay) | |||
308 | goto out; | 310 | goto out; |
309 | } | 311 | } |
310 | 312 | ||
311 | BEGIN_LP_RING(4); | 313 | ret = BEGIN_LP_RING(4); |
314 | if (ret) { | ||
315 | kfree(request); | ||
316 | goto out; | ||
317 | } | ||
318 | |||
312 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON); | 319 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON); |
313 | OUT_RING(overlay->flip_addr | OFC_UPDATE); | 320 | OUT_RING(overlay->flip_addr | OFC_UPDATE); |
314 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | 321 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); |
@@ -332,6 +339,7 @@ static int intel_overlay_continue(struct intel_overlay *overlay, | |||
332 | struct drm_i915_gem_request *request; | 339 | struct drm_i915_gem_request *request; |
333 | u32 flip_addr = overlay->flip_addr; | 340 | u32 flip_addr = overlay->flip_addr; |
334 | u32 tmp; | 341 | u32 tmp; |
342 | int ret; | ||
335 | 343 | ||
336 | BUG_ON(!overlay->active); | 344 | BUG_ON(!overlay->active); |
337 | 345 | ||
@@ -347,36 +355,44 @@ static int intel_overlay_continue(struct intel_overlay *overlay, | |||
347 | if (tmp & (1 << 17)) | 355 | if (tmp & (1 << 17)) |
348 | DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); | 356 | DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); |
349 | 357 | ||
350 | BEGIN_LP_RING(2); | 358 | ret = BEGIN_LP_RING(2); |
359 | if (ret) { | ||
360 | kfree(request); | ||
361 | return ret; | ||
362 | } | ||
351 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); | 363 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); |
352 | OUT_RING(flip_addr); | 364 | OUT_RING(flip_addr); |
353 | ADVANCE_LP_RING(); | 365 | ADVANCE_LP_RING(); |
354 | 366 | ||
355 | overlay->last_flip_req = | 367 | ret = i915_add_request(dev, NULL, request, LP_RING(dev_priv)); |
356 | i915_add_request(dev, NULL, request, &dev_priv->render_ring); | 368 | if (ret) { |
369 | kfree(request); | ||
370 | return ret; | ||
371 | } | ||
372 | |||
373 | overlay->last_flip_req = request->seqno; | ||
357 | return 0; | 374 | return 0; |
358 | } | 375 | } |
359 | 376 | ||
360 | static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay) | 377 | static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay) |
361 | { | 378 | { |
362 | struct drm_gem_object *obj = &overlay->old_vid_bo->base; | 379 | struct drm_i915_gem_object *obj = overlay->old_vid_bo; |
363 | 380 | ||
364 | i915_gem_object_unpin(obj); | 381 | i915_gem_object_unpin(obj); |
365 | drm_gem_object_unreference(obj); | 382 | drm_gem_object_unreference(&obj->base); |
366 | 383 | ||
367 | overlay->old_vid_bo = NULL; | 384 | overlay->old_vid_bo = NULL; |
368 | } | 385 | } |
369 | 386 | ||
370 | static void intel_overlay_off_tail(struct intel_overlay *overlay) | 387 | static void intel_overlay_off_tail(struct intel_overlay *overlay) |
371 | { | 388 | { |
372 | struct drm_gem_object *obj; | 389 | struct drm_i915_gem_object *obj = overlay->vid_bo; |
373 | 390 | ||
374 | /* never have the overlay hw on without showing a frame */ | 391 | /* never have the overlay hw on without showing a frame */ |
375 | BUG_ON(!overlay->vid_bo); | 392 | BUG_ON(!overlay->vid_bo); |
376 | obj = &overlay->vid_bo->base; | ||
377 | 393 | ||
378 | i915_gem_object_unpin(obj); | 394 | i915_gem_object_unpin(obj); |
379 | drm_gem_object_unreference(obj); | 395 | drm_gem_object_unreference(&obj->base); |
380 | overlay->vid_bo = NULL; | 396 | overlay->vid_bo = NULL; |
381 | 397 | ||
382 | overlay->crtc->overlay = NULL; | 398 | overlay->crtc->overlay = NULL; |
@@ -389,8 +405,10 @@ static int intel_overlay_off(struct intel_overlay *overlay, | |||
389 | bool interruptible) | 405 | bool interruptible) |
390 | { | 406 | { |
391 | struct drm_device *dev = overlay->dev; | 407 | struct drm_device *dev = overlay->dev; |
408 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
392 | u32 flip_addr = overlay->flip_addr; | 409 | u32 flip_addr = overlay->flip_addr; |
393 | struct drm_i915_gem_request *request; | 410 | struct drm_i915_gem_request *request; |
411 | int ret; | ||
394 | 412 | ||
395 | BUG_ON(!overlay->active); | 413 | BUG_ON(!overlay->active); |
396 | 414 | ||
@@ -404,7 +422,11 @@ static int intel_overlay_off(struct intel_overlay *overlay, | |||
404 | * of the hw. Do it in both cases */ | 422 | * of the hw. Do it in both cases */ |
405 | flip_addr |= OFC_UPDATE; | 423 | flip_addr |= OFC_UPDATE; |
406 | 424 | ||
407 | BEGIN_LP_RING(6); | 425 | ret = BEGIN_LP_RING(6); |
426 | if (ret) { | ||
427 | kfree(request); | ||
428 | return ret; | ||
429 | } | ||
408 | /* wait for overlay to go idle */ | 430 | /* wait for overlay to go idle */ |
409 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); | 431 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); |
410 | OUT_RING(flip_addr); | 432 | OUT_RING(flip_addr); |
@@ -432,7 +454,7 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, | |||
432 | return 0; | 454 | return 0; |
433 | 455 | ||
434 | ret = i915_do_wait_request(dev, overlay->last_flip_req, | 456 | ret = i915_do_wait_request(dev, overlay->last_flip_req, |
435 | interruptible, &dev_priv->render_ring); | 457 | interruptible, LP_RING(dev_priv)); |
436 | if (ret) | 458 | if (ret) |
437 | return ret; | 459 | return ret; |
438 | 460 | ||
@@ -467,7 +489,12 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) | |||
467 | if (request == NULL) | 489 | if (request == NULL) |
468 | return -ENOMEM; | 490 | return -ENOMEM; |
469 | 491 | ||
470 | BEGIN_LP_RING(2); | 492 | ret = BEGIN_LP_RING(2); |
493 | if (ret) { | ||
494 | kfree(request); | ||
495 | return ret; | ||
496 | } | ||
497 | |||
471 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | 498 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); |
472 | OUT_RING(MI_NOOP); | 499 | OUT_RING(MI_NOOP); |
473 | ADVANCE_LP_RING(); | 500 | ADVANCE_LP_RING(); |
@@ -736,13 +763,12 @@ static u32 overlay_cmd_reg(struct put_image_params *params) | |||
736 | } | 763 | } |
737 | 764 | ||
738 | static int intel_overlay_do_put_image(struct intel_overlay *overlay, | 765 | static int intel_overlay_do_put_image(struct intel_overlay *overlay, |
739 | struct drm_gem_object *new_bo, | 766 | struct drm_i915_gem_object *new_bo, |
740 | struct put_image_params *params) | 767 | struct put_image_params *params) |
741 | { | 768 | { |
742 | int ret, tmp_width; | 769 | int ret, tmp_width; |
743 | struct overlay_registers *regs; | 770 | struct overlay_registers *regs; |
744 | bool scale_changed = false; | 771 | bool scale_changed = false; |
745 | struct drm_i915_gem_object *bo_priv = to_intel_bo(new_bo); | ||
746 | struct drm_device *dev = overlay->dev; | 772 | struct drm_device *dev = overlay->dev; |
747 | 773 | ||
748 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); | 774 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); |
@@ -753,7 +779,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
753 | if (ret != 0) | 779 | if (ret != 0) |
754 | return ret; | 780 | return ret; |
755 | 781 | ||
756 | ret = i915_gem_object_pin(new_bo, PAGE_SIZE); | 782 | ret = i915_gem_object_pin(new_bo, PAGE_SIZE, true); |
757 | if (ret != 0) | 783 | if (ret != 0) |
758 | return ret; | 784 | return ret; |
759 | 785 | ||
@@ -761,6 +787,10 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
761 | if (ret != 0) | 787 | if (ret != 0) |
762 | goto out_unpin; | 788 | goto out_unpin; |
763 | 789 | ||
790 | ret = i915_gem_object_put_fence(new_bo); | ||
791 | if (ret) | ||
792 | goto out_unpin; | ||
793 | |||
764 | if (!overlay->active) { | 794 | if (!overlay->active) { |
765 | regs = intel_overlay_map_regs(overlay); | 795 | regs = intel_overlay_map_regs(overlay); |
766 | if (!regs) { | 796 | if (!regs) { |
@@ -797,7 +827,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
797 | regs->SWIDTHSW = calc_swidthsw(overlay->dev, | 827 | regs->SWIDTHSW = calc_swidthsw(overlay->dev, |
798 | params->offset_Y, tmp_width); | 828 | params->offset_Y, tmp_width); |
799 | regs->SHEIGHT = params->src_h; | 829 | regs->SHEIGHT = params->src_h; |
800 | regs->OBUF_0Y = bo_priv->gtt_offset + params-> offset_Y; | 830 | regs->OBUF_0Y = new_bo->gtt_offset + params-> offset_Y; |
801 | regs->OSTRIDE = params->stride_Y; | 831 | regs->OSTRIDE = params->stride_Y; |
802 | 832 | ||
803 | if (params->format & I915_OVERLAY_YUV_PLANAR) { | 833 | if (params->format & I915_OVERLAY_YUV_PLANAR) { |
@@ -811,8 +841,8 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
811 | params->src_w/uv_hscale); | 841 | params->src_w/uv_hscale); |
812 | regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16; | 842 | regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16; |
813 | regs->SHEIGHT |= (params->src_h/uv_vscale) << 16; | 843 | regs->SHEIGHT |= (params->src_h/uv_vscale) << 16; |
814 | regs->OBUF_0U = bo_priv->gtt_offset + params->offset_U; | 844 | regs->OBUF_0U = new_bo->gtt_offset + params->offset_U; |
815 | regs->OBUF_0V = bo_priv->gtt_offset + params->offset_V; | 845 | regs->OBUF_0V = new_bo->gtt_offset + params->offset_V; |
816 | regs->OSTRIDE |= params->stride_UV << 16; | 846 | regs->OSTRIDE |= params->stride_UV << 16; |
817 | } | 847 | } |
818 | 848 | ||
@@ -829,7 +859,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
829 | goto out_unpin; | 859 | goto out_unpin; |
830 | 860 | ||
831 | overlay->old_vid_bo = overlay->vid_bo; | 861 | overlay->old_vid_bo = overlay->vid_bo; |
832 | overlay->vid_bo = to_intel_bo(new_bo); | 862 | overlay->vid_bo = new_bo; |
833 | 863 | ||
834 | return 0; | 864 | return 0; |
835 | 865 | ||
@@ -942,7 +972,7 @@ static int check_overlay_scaling(struct put_image_params *rec) | |||
942 | 972 | ||
943 | static int check_overlay_src(struct drm_device *dev, | 973 | static int check_overlay_src(struct drm_device *dev, |
944 | struct drm_intel_overlay_put_image *rec, | 974 | struct drm_intel_overlay_put_image *rec, |
945 | struct drm_gem_object *new_bo) | 975 | struct drm_i915_gem_object *new_bo) |
946 | { | 976 | { |
947 | int uv_hscale = uv_hsubsampling(rec->flags); | 977 | int uv_hscale = uv_hsubsampling(rec->flags); |
948 | int uv_vscale = uv_vsubsampling(rec->flags); | 978 | int uv_vscale = uv_vsubsampling(rec->flags); |
@@ -1027,7 +1057,7 @@ static int check_overlay_src(struct drm_device *dev, | |||
1027 | return -EINVAL; | 1057 | return -EINVAL; |
1028 | 1058 | ||
1029 | tmp = rec->stride_Y*rec->src_height; | 1059 | tmp = rec->stride_Y*rec->src_height; |
1030 | if (rec->offset_Y + tmp > new_bo->size) | 1060 | if (rec->offset_Y + tmp > new_bo->base.size) |
1031 | return -EINVAL; | 1061 | return -EINVAL; |
1032 | break; | 1062 | break; |
1033 | 1063 | ||
@@ -1038,12 +1068,12 @@ static int check_overlay_src(struct drm_device *dev, | |||
1038 | return -EINVAL; | 1068 | return -EINVAL; |
1039 | 1069 | ||
1040 | tmp = rec->stride_Y * rec->src_height; | 1070 | tmp = rec->stride_Y * rec->src_height; |
1041 | if (rec->offset_Y + tmp > new_bo->size) | 1071 | if (rec->offset_Y + tmp > new_bo->base.size) |
1042 | return -EINVAL; | 1072 | return -EINVAL; |
1043 | 1073 | ||
1044 | tmp = rec->stride_UV * (rec->src_height / uv_vscale); | 1074 | tmp = rec->stride_UV * (rec->src_height / uv_vscale); |
1045 | if (rec->offset_U + tmp > new_bo->size || | 1075 | if (rec->offset_U + tmp > new_bo->base.size || |
1046 | rec->offset_V + tmp > new_bo->size) | 1076 | rec->offset_V + tmp > new_bo->base.size) |
1047 | return -EINVAL; | 1077 | return -EINVAL; |
1048 | break; | 1078 | break; |
1049 | } | 1079 | } |
@@ -1086,7 +1116,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, | |||
1086 | struct intel_overlay *overlay; | 1116 | struct intel_overlay *overlay; |
1087 | struct drm_mode_object *drmmode_obj; | 1117 | struct drm_mode_object *drmmode_obj; |
1088 | struct intel_crtc *crtc; | 1118 | struct intel_crtc *crtc; |
1089 | struct drm_gem_object *new_bo; | 1119 | struct drm_i915_gem_object *new_bo; |
1090 | struct put_image_params *params; | 1120 | struct put_image_params *params; |
1091 | int ret; | 1121 | int ret; |
1092 | 1122 | ||
@@ -1125,8 +1155,8 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, | |||
1125 | } | 1155 | } |
1126 | crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); | 1156 | crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); |
1127 | 1157 | ||
1128 | new_bo = drm_gem_object_lookup(dev, file_priv, | 1158 | new_bo = to_intel_bo(drm_gem_object_lookup(dev, file_priv, |
1129 | put_image_rec->bo_handle); | 1159 | put_image_rec->bo_handle)); |
1130 | if (!new_bo) { | 1160 | if (!new_bo) { |
1131 | ret = -ENOENT; | 1161 | ret = -ENOENT; |
1132 | goto out_free; | 1162 | goto out_free; |
@@ -1135,6 +1165,12 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, | |||
1135 | mutex_lock(&dev->mode_config.mutex); | 1165 | mutex_lock(&dev->mode_config.mutex); |
1136 | mutex_lock(&dev->struct_mutex); | 1166 | mutex_lock(&dev->struct_mutex); |
1137 | 1167 | ||
1168 | if (new_bo->tiling_mode) { | ||
1169 | DRM_ERROR("buffer used for overlay image can not be tiled\n"); | ||
1170 | ret = -EINVAL; | ||
1171 | goto out_unlock; | ||
1172 | } | ||
1173 | |||
1138 | ret = intel_overlay_recover_from_interrupt(overlay, true); | 1174 | ret = intel_overlay_recover_from_interrupt(overlay, true); |
1139 | if (ret != 0) | 1175 | if (ret != 0) |
1140 | goto out_unlock; | 1176 | goto out_unlock; |
@@ -1217,7 +1253,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, | |||
1217 | out_unlock: | 1253 | out_unlock: |
1218 | mutex_unlock(&dev->struct_mutex); | 1254 | mutex_unlock(&dev->struct_mutex); |
1219 | mutex_unlock(&dev->mode_config.mutex); | 1255 | mutex_unlock(&dev->mode_config.mutex); |
1220 | drm_gem_object_unreference_unlocked(new_bo); | 1256 | drm_gem_object_unreference_unlocked(&new_bo->base); |
1221 | out_free: | 1257 | out_free: |
1222 | kfree(params); | 1258 | kfree(params); |
1223 | 1259 | ||
@@ -1370,7 +1406,7 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1370 | { | 1406 | { |
1371 | drm_i915_private_t *dev_priv = dev->dev_private; | 1407 | drm_i915_private_t *dev_priv = dev->dev_private; |
1372 | struct intel_overlay *overlay; | 1408 | struct intel_overlay *overlay; |
1373 | struct drm_gem_object *reg_bo; | 1409 | struct drm_i915_gem_object *reg_bo; |
1374 | struct overlay_registers *regs; | 1410 | struct overlay_registers *regs; |
1375 | int ret; | 1411 | int ret; |
1376 | 1412 | ||
@@ -1385,7 +1421,7 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1385 | reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE); | 1421 | reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE); |
1386 | if (!reg_bo) | 1422 | if (!reg_bo) |
1387 | goto out_free; | 1423 | goto out_free; |
1388 | overlay->reg_bo = to_intel_bo(reg_bo); | 1424 | overlay->reg_bo = reg_bo; |
1389 | 1425 | ||
1390 | if (OVERLAY_NEEDS_PHYSICAL(dev)) { | 1426 | if (OVERLAY_NEEDS_PHYSICAL(dev)) { |
1391 | ret = i915_gem_attach_phys_object(dev, reg_bo, | 1427 | ret = i915_gem_attach_phys_object(dev, reg_bo, |
@@ -1395,14 +1431,14 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1395 | DRM_ERROR("failed to attach phys overlay regs\n"); | 1431 | DRM_ERROR("failed to attach phys overlay regs\n"); |
1396 | goto out_free_bo; | 1432 | goto out_free_bo; |
1397 | } | 1433 | } |
1398 | overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr; | 1434 | overlay->flip_addr = reg_bo->phys_obj->handle->busaddr; |
1399 | } else { | 1435 | } else { |
1400 | ret = i915_gem_object_pin(reg_bo, PAGE_SIZE); | 1436 | ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true); |
1401 | if (ret) { | 1437 | if (ret) { |
1402 | DRM_ERROR("failed to pin overlay register bo\n"); | 1438 | DRM_ERROR("failed to pin overlay register bo\n"); |
1403 | goto out_free_bo; | 1439 | goto out_free_bo; |
1404 | } | 1440 | } |
1405 | overlay->flip_addr = overlay->reg_bo->gtt_offset; | 1441 | overlay->flip_addr = reg_bo->gtt_offset; |
1406 | 1442 | ||
1407 | ret = i915_gem_object_set_to_gtt_domain(reg_bo, true); | 1443 | ret = i915_gem_object_set_to_gtt_domain(reg_bo, true); |
1408 | if (ret) { | 1444 | if (ret) { |
@@ -1434,7 +1470,7 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1434 | out_unpin_bo: | 1470 | out_unpin_bo: |
1435 | i915_gem_object_unpin(reg_bo); | 1471 | i915_gem_object_unpin(reg_bo); |
1436 | out_free_bo: | 1472 | out_free_bo: |
1437 | drm_gem_object_unreference(reg_bo); | 1473 | drm_gem_object_unreference(®_bo->base); |
1438 | out_free: | 1474 | out_free: |
1439 | kfree(overlay); | 1475 | kfree(overlay); |
1440 | return; | 1476 | return; |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 92ff8f38527..7350ec2515c 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -125,15 +125,55 @@ static int is_backlight_combination_mode(struct drm_device *dev) | |||
125 | return 0; | 125 | return 0; |
126 | } | 126 | } |
127 | 127 | ||
128 | static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv) | ||
129 | { | ||
130 | u32 val; | ||
131 | |||
132 | /* Restore the CTL value if it lost, e.g. GPU reset */ | ||
133 | |||
134 | if (HAS_PCH_SPLIT(dev_priv->dev)) { | ||
135 | val = I915_READ(BLC_PWM_PCH_CTL2); | ||
136 | if (dev_priv->saveBLC_PWM_CTL2 == 0) { | ||
137 | dev_priv->saveBLC_PWM_CTL2 = val; | ||
138 | } else if (val == 0) { | ||
139 | I915_WRITE(BLC_PWM_PCH_CTL2, | ||
140 | dev_priv->saveBLC_PWM_CTL); | ||
141 | val = dev_priv->saveBLC_PWM_CTL; | ||
142 | } | ||
143 | } else { | ||
144 | val = I915_READ(BLC_PWM_CTL); | ||
145 | if (dev_priv->saveBLC_PWM_CTL == 0) { | ||
146 | dev_priv->saveBLC_PWM_CTL = val; | ||
147 | dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); | ||
148 | } else if (val == 0) { | ||
149 | I915_WRITE(BLC_PWM_CTL, | ||
150 | dev_priv->saveBLC_PWM_CTL); | ||
151 | I915_WRITE(BLC_PWM_CTL2, | ||
152 | dev_priv->saveBLC_PWM_CTL2); | ||
153 | val = dev_priv->saveBLC_PWM_CTL; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | return val; | ||
158 | } | ||
159 | |||
128 | u32 intel_panel_get_max_backlight(struct drm_device *dev) | 160 | u32 intel_panel_get_max_backlight(struct drm_device *dev) |
129 | { | 161 | { |
130 | struct drm_i915_private *dev_priv = dev->dev_private; | 162 | struct drm_i915_private *dev_priv = dev->dev_private; |
131 | u32 max; | 163 | u32 max; |
132 | 164 | ||
165 | max = i915_read_blc_pwm_ctl(dev_priv); | ||
166 | if (max == 0) { | ||
167 | /* XXX add code here to query mode clock or hardware clock | ||
168 | * and program max PWM appropriately. | ||
169 | */ | ||
170 | printk_once(KERN_WARNING "fixme: max PWM is zero.\n"); | ||
171 | return 1; | ||
172 | } | ||
173 | |||
133 | if (HAS_PCH_SPLIT(dev)) { | 174 | if (HAS_PCH_SPLIT(dev)) { |
134 | max = I915_READ(BLC_PWM_PCH_CTL2) >> 16; | 175 | max >>= 16; |
135 | } else { | 176 | } else { |
136 | max = I915_READ(BLC_PWM_CTL); | ||
137 | if (IS_PINEVIEW(dev)) { | 177 | if (IS_PINEVIEW(dev)) { |
138 | max >>= 17; | 178 | max >>= 17; |
139 | } else { | 179 | } else { |
@@ -146,14 +186,6 @@ u32 intel_panel_get_max_backlight(struct drm_device *dev) | |||
146 | max *= 0xff; | 186 | max *= 0xff; |
147 | } | 187 | } |
148 | 188 | ||
149 | if (max == 0) { | ||
150 | /* XXX add code here to query mode clock or hardware clock | ||
151 | * and program max PWM appropriately. | ||
152 | */ | ||
153 | DRM_ERROR("fixme: max PWM is zero.\n"); | ||
154 | max = 1; | ||
155 | } | ||
156 | |||
157 | DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); | 189 | DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); |
158 | return max; | 190 | return max; |
159 | } | 191 | } |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b83306f9244..56bc95c056d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -49,11 +49,11 @@ static u32 i915_gem_get_seqno(struct drm_device *dev) | |||
49 | } | 49 | } |
50 | 50 | ||
51 | static void | 51 | static void |
52 | render_ring_flush(struct drm_device *dev, | 52 | render_ring_flush(struct intel_ring_buffer *ring, |
53 | struct intel_ring_buffer *ring, | ||
54 | u32 invalidate_domains, | 53 | u32 invalidate_domains, |
55 | u32 flush_domains) | 54 | u32 flush_domains) |
56 | { | 55 | { |
56 | struct drm_device *dev = ring->dev; | ||
57 | drm_i915_private_t *dev_priv = dev->dev_private; | 57 | drm_i915_private_t *dev_priv = dev->dev_private; |
58 | u32 cmd; | 58 | u32 cmd; |
59 | 59 | ||
@@ -109,79 +109,83 @@ render_ring_flush(struct drm_device *dev, | |||
109 | if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION) | 109 | if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION) |
110 | cmd |= MI_EXE_FLUSH; | 110 | cmd |= MI_EXE_FLUSH; |
111 | 111 | ||
112 | if (invalidate_domains & I915_GEM_DOMAIN_COMMAND && | ||
113 | (IS_G4X(dev) || IS_GEN5(dev))) | ||
114 | cmd |= MI_INVALIDATE_ISP; | ||
115 | |||
112 | #if WATCH_EXEC | 116 | #if WATCH_EXEC |
113 | DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); | 117 | DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); |
114 | #endif | 118 | #endif |
115 | intel_ring_begin(dev, ring, 2); | 119 | if (intel_ring_begin(ring, 2) == 0) { |
116 | intel_ring_emit(dev, ring, cmd); | 120 | intel_ring_emit(ring, cmd); |
117 | intel_ring_emit(dev, ring, MI_NOOP); | 121 | intel_ring_emit(ring, MI_NOOP); |
118 | intel_ring_advance(dev, ring); | 122 | intel_ring_advance(ring); |
123 | } | ||
119 | } | 124 | } |
120 | } | 125 | } |
121 | 126 | ||
122 | static void ring_write_tail(struct drm_device *dev, | 127 | static void ring_write_tail(struct intel_ring_buffer *ring, |
123 | struct intel_ring_buffer *ring, | ||
124 | u32 value) | 128 | u32 value) |
125 | { | 129 | { |
126 | drm_i915_private_t *dev_priv = dev->dev_private; | 130 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
127 | I915_WRITE_TAIL(ring, value); | 131 | I915_WRITE_TAIL(ring, value); |
128 | } | 132 | } |
129 | 133 | ||
130 | u32 intel_ring_get_active_head(struct drm_device *dev, | 134 | u32 intel_ring_get_active_head(struct intel_ring_buffer *ring) |
131 | struct intel_ring_buffer *ring) | ||
132 | { | 135 | { |
133 | drm_i915_private_t *dev_priv = dev->dev_private; | 136 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
134 | u32 acthd_reg = INTEL_INFO(dev)->gen >= 4 ? | 137 | u32 acthd_reg = INTEL_INFO(ring->dev)->gen >= 4 ? |
135 | RING_ACTHD(ring->mmio_base) : ACTHD; | 138 | RING_ACTHD(ring->mmio_base) : ACTHD; |
136 | 139 | ||
137 | return I915_READ(acthd_reg); | 140 | return I915_READ(acthd_reg); |
138 | } | 141 | } |
139 | 142 | ||
140 | static int init_ring_common(struct drm_device *dev, | 143 | static int init_ring_common(struct intel_ring_buffer *ring) |
141 | struct intel_ring_buffer *ring) | ||
142 | { | 144 | { |
145 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | ||
146 | struct drm_i915_gem_object *obj = ring->obj; | ||
143 | u32 head; | 147 | u32 head; |
144 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
145 | struct drm_i915_gem_object *obj_priv; | ||
146 | obj_priv = to_intel_bo(ring->gem_object); | ||
147 | 148 | ||
148 | /* Stop the ring if it's running. */ | 149 | /* Stop the ring if it's running. */ |
149 | I915_WRITE_CTL(ring, 0); | 150 | I915_WRITE_CTL(ring, 0); |
150 | I915_WRITE_HEAD(ring, 0); | 151 | I915_WRITE_HEAD(ring, 0); |
151 | ring->write_tail(dev, ring, 0); | 152 | ring->write_tail(ring, 0); |
152 | 153 | ||
153 | /* Initialize the ring. */ | 154 | /* Initialize the ring. */ |
154 | I915_WRITE_START(ring, obj_priv->gtt_offset); | 155 | I915_WRITE_START(ring, obj->gtt_offset); |
155 | head = I915_READ_HEAD(ring) & HEAD_ADDR; | 156 | head = I915_READ_HEAD(ring) & HEAD_ADDR; |
156 | 157 | ||
157 | /* G45 ring initialization fails to reset head to zero */ | 158 | /* G45 ring initialization fails to reset head to zero */ |
158 | if (head != 0) { | 159 | if (head != 0) { |
159 | DRM_ERROR("%s head not reset to zero " | 160 | DRM_DEBUG_KMS("%s head not reset to zero " |
160 | "ctl %08x head %08x tail %08x start %08x\n", | 161 | "ctl %08x head %08x tail %08x start %08x\n", |
161 | ring->name, | 162 | ring->name, |
162 | I915_READ_CTL(ring), | 163 | I915_READ_CTL(ring), |
163 | I915_READ_HEAD(ring), | 164 | I915_READ_HEAD(ring), |
164 | I915_READ_TAIL(ring), | 165 | I915_READ_TAIL(ring), |
165 | I915_READ_START(ring)); | 166 | I915_READ_START(ring)); |
166 | 167 | ||
167 | I915_WRITE_HEAD(ring, 0); | 168 | I915_WRITE_HEAD(ring, 0); |
168 | 169 | ||
169 | DRM_ERROR("%s head forced to zero " | 170 | if (I915_READ_HEAD(ring) & HEAD_ADDR) { |
170 | "ctl %08x head %08x tail %08x start %08x\n", | 171 | DRM_ERROR("failed to set %s head to zero " |
171 | ring->name, | 172 | "ctl %08x head %08x tail %08x start %08x\n", |
172 | I915_READ_CTL(ring), | 173 | ring->name, |
173 | I915_READ_HEAD(ring), | 174 | I915_READ_CTL(ring), |
174 | I915_READ_TAIL(ring), | 175 | I915_READ_HEAD(ring), |
175 | I915_READ_START(ring)); | 176 | I915_READ_TAIL(ring), |
177 | I915_READ_START(ring)); | ||
178 | } | ||
176 | } | 179 | } |
177 | 180 | ||
178 | I915_WRITE_CTL(ring, | 181 | I915_WRITE_CTL(ring, |
179 | ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES) | 182 | ((ring->size - PAGE_SIZE) & RING_NR_PAGES) |
180 | | RING_REPORT_64K | RING_VALID); | 183 | | RING_REPORT_64K | RING_VALID); |
181 | 184 | ||
182 | head = I915_READ_HEAD(ring) & HEAD_ADDR; | ||
183 | /* If the head is still not zero, the ring is dead */ | 185 | /* If the head is still not zero, the ring is dead */ |
184 | if (head != 0) { | 186 | if ((I915_READ_CTL(ring) & RING_VALID) == 0 || |
187 | I915_READ_START(ring) != obj->gtt_offset || | ||
188 | (I915_READ_HEAD(ring) & HEAD_ADDR) != 0) { | ||
185 | DRM_ERROR("%s initialization failed " | 189 | DRM_ERROR("%s initialization failed " |
186 | "ctl %08x head %08x tail %08x start %08x\n", | 190 | "ctl %08x head %08x tail %08x start %08x\n", |
187 | ring->name, | 191 | ring->name, |
@@ -192,8 +196,8 @@ static int init_ring_common(struct drm_device *dev, | |||
192 | return -EIO; | 196 | return -EIO; |
193 | } | 197 | } |
194 | 198 | ||
195 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 199 | if (!drm_core_check_feature(ring->dev, DRIVER_MODESET)) |
196 | i915_kernel_lost_context(dev); | 200 | i915_kernel_lost_context(ring->dev); |
197 | else { | 201 | else { |
198 | ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; | 202 | ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; |
199 | ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; | 203 | ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; |
@@ -201,335 +205,500 @@ static int init_ring_common(struct drm_device *dev, | |||
201 | if (ring->space < 0) | 205 | if (ring->space < 0) |
202 | ring->space += ring->size; | 206 | ring->space += ring->size; |
203 | } | 207 | } |
208 | |||
204 | return 0; | 209 | return 0; |
205 | } | 210 | } |
206 | 211 | ||
207 | static int init_render_ring(struct drm_device *dev, | 212 | /* |
208 | struct intel_ring_buffer *ring) | 213 | * 965+ support PIPE_CONTROL commands, which provide finer grained control |
214 | * over cache flushing. | ||
215 | */ | ||
216 | struct pipe_control { | ||
217 | struct drm_i915_gem_object *obj; | ||
218 | volatile u32 *cpu_page; | ||
219 | u32 gtt_offset; | ||
220 | }; | ||
221 | |||
222 | static int | ||
223 | init_pipe_control(struct intel_ring_buffer *ring) | ||
209 | { | 224 | { |
210 | drm_i915_private_t *dev_priv = dev->dev_private; | 225 | struct pipe_control *pc; |
211 | int ret = init_ring_common(dev, ring); | 226 | struct drm_i915_gem_object *obj; |
212 | int mode; | 227 | int ret; |
228 | |||
229 | if (ring->private) | ||
230 | return 0; | ||
231 | |||
232 | pc = kmalloc(sizeof(*pc), GFP_KERNEL); | ||
233 | if (!pc) | ||
234 | return -ENOMEM; | ||
235 | |||
236 | obj = i915_gem_alloc_object(ring->dev, 4096); | ||
237 | if (obj == NULL) { | ||
238 | DRM_ERROR("Failed to allocate seqno page\n"); | ||
239 | ret = -ENOMEM; | ||
240 | goto err; | ||
241 | } | ||
242 | obj->agp_type = AGP_USER_CACHED_MEMORY; | ||
243 | |||
244 | ret = i915_gem_object_pin(obj, 4096, true); | ||
245 | if (ret) | ||
246 | goto err_unref; | ||
247 | |||
248 | pc->gtt_offset = obj->gtt_offset; | ||
249 | pc->cpu_page = kmap(obj->pages[0]); | ||
250 | if (pc->cpu_page == NULL) | ||
251 | goto err_unpin; | ||
252 | |||
253 | pc->obj = obj; | ||
254 | ring->private = pc; | ||
255 | return 0; | ||
256 | |||
257 | err_unpin: | ||
258 | i915_gem_object_unpin(obj); | ||
259 | err_unref: | ||
260 | drm_gem_object_unreference(&obj->base); | ||
261 | err: | ||
262 | kfree(pc); | ||
263 | return ret; | ||
264 | } | ||
265 | |||
266 | static void | ||
267 | cleanup_pipe_control(struct intel_ring_buffer *ring) | ||
268 | { | ||
269 | struct pipe_control *pc = ring->private; | ||
270 | struct drm_i915_gem_object *obj; | ||
271 | |||
272 | if (!ring->private) | ||
273 | return; | ||
274 | |||
275 | obj = pc->obj; | ||
276 | kunmap(obj->pages[0]); | ||
277 | i915_gem_object_unpin(obj); | ||
278 | drm_gem_object_unreference(&obj->base); | ||
279 | |||
280 | kfree(pc); | ||
281 | ring->private = NULL; | ||
282 | } | ||
283 | |||
284 | static int init_render_ring(struct intel_ring_buffer *ring) | ||
285 | { | ||
286 | struct drm_device *dev = ring->dev; | ||
287 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
288 | int ret = init_ring_common(ring); | ||
213 | 289 | ||
214 | if (INTEL_INFO(dev)->gen > 3) { | 290 | if (INTEL_INFO(dev)->gen > 3) { |
215 | mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH; | 291 | int mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH; |
216 | if (IS_GEN6(dev)) | 292 | if (IS_GEN6(dev)) |
217 | mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE; | 293 | mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE; |
218 | I915_WRITE(MI_MODE, mode); | 294 | I915_WRITE(MI_MODE, mode); |
219 | } | 295 | } |
296 | |||
297 | if (INTEL_INFO(dev)->gen >= 6) { | ||
298 | } else if (IS_GEN5(dev)) { | ||
299 | ret = init_pipe_control(ring); | ||
300 | if (ret) | ||
301 | return ret; | ||
302 | } | ||
303 | |||
220 | return ret; | 304 | return ret; |
221 | } | 305 | } |
222 | 306 | ||
223 | #define PIPE_CONTROL_FLUSH(addr) \ | 307 | static void render_ring_cleanup(struct intel_ring_buffer *ring) |
308 | { | ||
309 | if (!ring->private) | ||
310 | return; | ||
311 | |||
312 | cleanup_pipe_control(ring); | ||
313 | } | ||
314 | |||
315 | static void | ||
316 | update_semaphore(struct intel_ring_buffer *ring, int i, u32 seqno) | ||
317 | { | ||
318 | struct drm_device *dev = ring->dev; | ||
319 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
320 | int id; | ||
321 | |||
322 | /* | ||
323 | * cs -> 1 = vcs, 0 = bcs | ||
324 | * vcs -> 1 = bcs, 0 = cs, | ||
325 | * bcs -> 1 = cs, 0 = vcs. | ||
326 | */ | ||
327 | id = ring - dev_priv->ring; | ||
328 | id += 2 - i; | ||
329 | id %= 3; | ||
330 | |||
331 | intel_ring_emit(ring, | ||
332 | MI_SEMAPHORE_MBOX | | ||
333 | MI_SEMAPHORE_REGISTER | | ||
334 | MI_SEMAPHORE_UPDATE); | ||
335 | intel_ring_emit(ring, seqno); | ||
336 | intel_ring_emit(ring, | ||
337 | RING_SYNC_0(dev_priv->ring[id].mmio_base) + 4*i); | ||
338 | } | ||
339 | |||
340 | static int | ||
341 | gen6_add_request(struct intel_ring_buffer *ring, | ||
342 | u32 *result) | ||
343 | { | ||
344 | u32 seqno; | ||
345 | int ret; | ||
346 | |||
347 | ret = intel_ring_begin(ring, 10); | ||
348 | if (ret) | ||
349 | return ret; | ||
350 | |||
351 | seqno = i915_gem_get_seqno(ring->dev); | ||
352 | update_semaphore(ring, 0, seqno); | ||
353 | update_semaphore(ring, 1, seqno); | ||
354 | |||
355 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); | ||
356 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
357 | intel_ring_emit(ring, seqno); | ||
358 | intel_ring_emit(ring, MI_USER_INTERRUPT); | ||
359 | intel_ring_advance(ring); | ||
360 | |||
361 | *result = seqno; | ||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | int | ||
366 | intel_ring_sync(struct intel_ring_buffer *ring, | ||
367 | struct intel_ring_buffer *to, | ||
368 | u32 seqno) | ||
369 | { | ||
370 | int ret; | ||
371 | |||
372 | ret = intel_ring_begin(ring, 4); | ||
373 | if (ret) | ||
374 | return ret; | ||
375 | |||
376 | intel_ring_emit(ring, | ||
377 | MI_SEMAPHORE_MBOX | | ||
378 | MI_SEMAPHORE_REGISTER | | ||
379 | intel_ring_sync_index(ring, to) << 17 | | ||
380 | MI_SEMAPHORE_COMPARE); | ||
381 | intel_ring_emit(ring, seqno); | ||
382 | intel_ring_emit(ring, 0); | ||
383 | intel_ring_emit(ring, MI_NOOP); | ||
384 | intel_ring_advance(ring); | ||
385 | |||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | #define PIPE_CONTROL_FLUSH(ring__, addr__) \ | ||
224 | do { \ | 390 | do { \ |
225 | OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ | 391 | intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ |
226 | PIPE_CONTROL_DEPTH_STALL | 2); \ | 392 | PIPE_CONTROL_DEPTH_STALL | 2); \ |
227 | OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \ | 393 | intel_ring_emit(ring__, (addr__) | PIPE_CONTROL_GLOBAL_GTT); \ |
228 | OUT_RING(0); \ | 394 | intel_ring_emit(ring__, 0); \ |
229 | OUT_RING(0); \ | 395 | intel_ring_emit(ring__, 0); \ |
230 | } while (0) | 396 | } while (0) |
231 | 397 | ||
232 | /** | 398 | static int |
233 | * Creates a new sequence number, emitting a write of it to the status page | 399 | pc_render_add_request(struct intel_ring_buffer *ring, |
234 | * plus an interrupt, which will trigger i915_user_interrupt_handler. | 400 | u32 *result) |
235 | * | ||
236 | * Must be called with struct_lock held. | ||
237 | * | ||
238 | * Returned sequence numbers are nonzero on success. | ||
239 | */ | ||
240 | static u32 | ||
241 | render_ring_add_request(struct drm_device *dev, | ||
242 | struct intel_ring_buffer *ring, | ||
243 | u32 flush_domains) | ||
244 | { | 401 | { |
245 | drm_i915_private_t *dev_priv = dev->dev_private; | 402 | struct drm_device *dev = ring->dev; |
246 | u32 seqno; | 403 | u32 seqno = i915_gem_get_seqno(dev); |
404 | struct pipe_control *pc = ring->private; | ||
405 | u32 scratch_addr = pc->gtt_offset + 128; | ||
406 | int ret; | ||
247 | 407 | ||
248 | seqno = i915_gem_get_seqno(dev); | 408 | /* For Ironlake, MI_USER_INTERRUPT was deprecated and apparently |
249 | 409 | * incoherent with writes to memory, i.e. completely fubar, | |
250 | if (IS_GEN6(dev)) { | 410 | * so we need to use PIPE_NOTIFY instead. |
251 | BEGIN_LP_RING(6); | 411 | * |
252 | OUT_RING(GFX_OP_PIPE_CONTROL | 3); | 412 | * However, we also need to workaround the qword write |
253 | OUT_RING(PIPE_CONTROL_QW_WRITE | | 413 | * incoherence by flushing the 6 PIPE_NOTIFY buffers out to |
254 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH | | 414 | * memory before requesting an interrupt. |
255 | PIPE_CONTROL_NOTIFY); | 415 | */ |
256 | OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | 416 | ret = intel_ring_begin(ring, 32); |
257 | OUT_RING(seqno); | 417 | if (ret) |
258 | OUT_RING(0); | 418 | return ret; |
259 | OUT_RING(0); | 419 | |
260 | ADVANCE_LP_RING(); | 420 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | |
261 | } else if (HAS_PIPE_CONTROL(dev)) { | 421 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); |
262 | u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; | 422 | intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); |
423 | intel_ring_emit(ring, seqno); | ||
424 | intel_ring_emit(ring, 0); | ||
425 | PIPE_CONTROL_FLUSH(ring, scratch_addr); | ||
426 | scratch_addr += 128; /* write to separate cachelines */ | ||
427 | PIPE_CONTROL_FLUSH(ring, scratch_addr); | ||
428 | scratch_addr += 128; | ||
429 | PIPE_CONTROL_FLUSH(ring, scratch_addr); | ||
430 | scratch_addr += 128; | ||
431 | PIPE_CONTROL_FLUSH(ring, scratch_addr); | ||
432 | scratch_addr += 128; | ||
433 | PIPE_CONTROL_FLUSH(ring, scratch_addr); | ||
434 | scratch_addr += 128; | ||
435 | PIPE_CONTROL_FLUSH(ring, scratch_addr); | ||
436 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | ||
437 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | | ||
438 | PIPE_CONTROL_NOTIFY); | ||
439 | intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); | ||
440 | intel_ring_emit(ring, seqno); | ||
441 | intel_ring_emit(ring, 0); | ||
442 | intel_ring_advance(ring); | ||
443 | |||
444 | *result = seqno; | ||
445 | return 0; | ||
446 | } | ||
263 | 447 | ||
264 | /* | 448 | static int |
265 | * Workaround qword write incoherence by flushing the | 449 | render_ring_add_request(struct intel_ring_buffer *ring, |
266 | * PIPE_NOTIFY buffers out to memory before requesting | 450 | u32 *result) |
267 | * an interrupt. | 451 | { |
268 | */ | 452 | struct drm_device *dev = ring->dev; |
269 | BEGIN_LP_RING(32); | 453 | u32 seqno = i915_gem_get_seqno(dev); |
270 | OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | 454 | int ret; |
271 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); | ||
272 | OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | ||
273 | OUT_RING(seqno); | ||
274 | OUT_RING(0); | ||
275 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
276 | scratch_addr += 128; /* write to separate cachelines */ | ||
277 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
278 | scratch_addr += 128; | ||
279 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
280 | scratch_addr += 128; | ||
281 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
282 | scratch_addr += 128; | ||
283 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
284 | scratch_addr += 128; | ||
285 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
286 | OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | ||
287 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | | ||
288 | PIPE_CONTROL_NOTIFY); | ||
289 | OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | ||
290 | OUT_RING(seqno); | ||
291 | OUT_RING(0); | ||
292 | ADVANCE_LP_RING(); | ||
293 | } else { | ||
294 | BEGIN_LP_RING(4); | ||
295 | OUT_RING(MI_STORE_DWORD_INDEX); | ||
296 | OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
297 | OUT_RING(seqno); | ||
298 | 455 | ||
299 | OUT_RING(MI_USER_INTERRUPT); | 456 | ret = intel_ring_begin(ring, 4); |
300 | ADVANCE_LP_RING(); | 457 | if (ret) |
301 | } | 458 | return ret; |
302 | return seqno; | 459 | |
460 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); | ||
461 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
462 | intel_ring_emit(ring, seqno); | ||
463 | intel_ring_emit(ring, MI_USER_INTERRUPT); | ||
464 | intel_ring_advance(ring); | ||
465 | |||
466 | *result = seqno; | ||
467 | return 0; | ||
303 | } | 468 | } |
304 | 469 | ||
305 | static u32 | 470 | static u32 |
306 | render_ring_get_seqno(struct drm_device *dev, | 471 | ring_get_seqno(struct intel_ring_buffer *ring) |
307 | struct intel_ring_buffer *ring) | ||
308 | { | 472 | { |
309 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 473 | return intel_read_status_page(ring, I915_GEM_HWS_INDEX); |
310 | if (HAS_PIPE_CONTROL(dev)) | ||
311 | return ((volatile u32 *)(dev_priv->seqno_page))[0]; | ||
312 | else | ||
313 | return intel_read_status_page(ring, I915_GEM_HWS_INDEX); | ||
314 | } | 474 | } |
315 | 475 | ||
316 | static void | 476 | static u32 |
317 | render_ring_get_user_irq(struct drm_device *dev, | 477 | pc_render_get_seqno(struct intel_ring_buffer *ring) |
318 | struct intel_ring_buffer *ring) | ||
319 | { | 478 | { |
320 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 479 | struct pipe_control *pc = ring->private; |
321 | unsigned long irqflags; | 480 | return pc->cpu_page[0]; |
481 | } | ||
482 | |||
483 | static bool | ||
484 | render_ring_get_irq(struct intel_ring_buffer *ring) | ||
485 | { | ||
486 | struct drm_device *dev = ring->dev; | ||
487 | |||
488 | if (!dev->irq_enabled) | ||
489 | return false; | ||
322 | 490 | ||
323 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 491 | if (atomic_inc_return(&ring->irq_refcount) == 1) { |
324 | if (dev->irq_enabled && (++ring->user_irq_refcount == 1)) { | 492 | drm_i915_private_t *dev_priv = dev->dev_private; |
493 | unsigned long irqflags; | ||
494 | |||
495 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | ||
325 | if (HAS_PCH_SPLIT(dev)) | 496 | if (HAS_PCH_SPLIT(dev)) |
326 | ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); | 497 | ironlake_enable_graphics_irq(dev_priv, |
498 | GT_PIPE_NOTIFY | GT_USER_INTERRUPT); | ||
327 | else | 499 | else |
328 | i915_enable_irq(dev_priv, I915_USER_INTERRUPT); | 500 | i915_enable_irq(dev_priv, I915_USER_INTERRUPT); |
501 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
329 | } | 502 | } |
330 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | 503 | |
504 | return true; | ||
331 | } | 505 | } |
332 | 506 | ||
333 | static void | 507 | static void |
334 | render_ring_put_user_irq(struct drm_device *dev, | 508 | render_ring_put_irq(struct intel_ring_buffer *ring) |
335 | struct intel_ring_buffer *ring) | ||
336 | { | 509 | { |
337 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 510 | struct drm_device *dev = ring->dev; |
338 | unsigned long irqflags; | ||
339 | 511 | ||
340 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 512 | if (atomic_dec_and_test(&ring->irq_refcount)) { |
341 | BUG_ON(dev->irq_enabled && ring->user_irq_refcount <= 0); | 513 | drm_i915_private_t *dev_priv = dev->dev_private; |
342 | if (dev->irq_enabled && (--ring->user_irq_refcount == 0)) { | 514 | unsigned long irqflags; |
515 | |||
516 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | ||
343 | if (HAS_PCH_SPLIT(dev)) | 517 | if (HAS_PCH_SPLIT(dev)) |
344 | ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); | 518 | ironlake_disable_graphics_irq(dev_priv, |
519 | GT_USER_INTERRUPT | | ||
520 | GT_PIPE_NOTIFY); | ||
345 | else | 521 | else |
346 | i915_disable_irq(dev_priv, I915_USER_INTERRUPT); | 522 | i915_disable_irq(dev_priv, I915_USER_INTERRUPT); |
523 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
347 | } | 524 | } |
348 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | ||
349 | } | 525 | } |
350 | 526 | ||
351 | void intel_ring_setup_status_page(struct drm_device *dev, | 527 | void intel_ring_setup_status_page(struct intel_ring_buffer *ring) |
352 | struct intel_ring_buffer *ring) | ||
353 | { | 528 | { |
354 | drm_i915_private_t *dev_priv = dev->dev_private; | 529 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
355 | if (IS_GEN6(dev)) { | 530 | u32 mmio = IS_GEN6(ring->dev) ? |
356 | I915_WRITE(RING_HWS_PGA_GEN6(ring->mmio_base), | 531 | RING_HWS_PGA_GEN6(ring->mmio_base) : |
357 | ring->status_page.gfx_addr); | 532 | RING_HWS_PGA(ring->mmio_base); |
358 | I915_READ(RING_HWS_PGA_GEN6(ring->mmio_base)); /* posting read */ | 533 | I915_WRITE(mmio, (u32)ring->status_page.gfx_addr); |
359 | } else { | 534 | POSTING_READ(mmio); |
360 | I915_WRITE(RING_HWS_PGA(ring->mmio_base), | ||
361 | ring->status_page.gfx_addr); | ||
362 | I915_READ(RING_HWS_PGA(ring->mmio_base)); /* posting read */ | ||
363 | } | ||
364 | |||
365 | } | 535 | } |
366 | 536 | ||
367 | static void | 537 | static void |
368 | bsd_ring_flush(struct drm_device *dev, | 538 | bsd_ring_flush(struct intel_ring_buffer *ring, |
369 | struct intel_ring_buffer *ring, | 539 | u32 invalidate_domains, |
370 | u32 invalidate_domains, | 540 | u32 flush_domains) |
371 | u32 flush_domains) | ||
372 | { | 541 | { |
373 | intel_ring_begin(dev, ring, 2); | 542 | if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) |
374 | intel_ring_emit(dev, ring, MI_FLUSH); | 543 | return; |
375 | intel_ring_emit(dev, ring, MI_NOOP); | ||
376 | intel_ring_advance(dev, ring); | ||
377 | } | ||
378 | 544 | ||
379 | static int init_bsd_ring(struct drm_device *dev, | 545 | if (intel_ring_begin(ring, 2) == 0) { |
380 | struct intel_ring_buffer *ring) | 546 | intel_ring_emit(ring, MI_FLUSH); |
381 | { | 547 | intel_ring_emit(ring, MI_NOOP); |
382 | return init_ring_common(dev, ring); | 548 | intel_ring_advance(ring); |
549 | } | ||
383 | } | 550 | } |
384 | 551 | ||
385 | static u32 | 552 | static int |
386 | ring_add_request(struct drm_device *dev, | 553 | ring_add_request(struct intel_ring_buffer *ring, |
387 | struct intel_ring_buffer *ring, | 554 | u32 *result) |
388 | u32 flush_domains) | ||
389 | { | 555 | { |
390 | u32 seqno; | 556 | u32 seqno; |
557 | int ret; | ||
391 | 558 | ||
392 | seqno = i915_gem_get_seqno(dev); | 559 | ret = intel_ring_begin(ring, 4); |
560 | if (ret) | ||
561 | return ret; | ||
393 | 562 | ||
394 | intel_ring_begin(dev, ring, 4); | 563 | seqno = i915_gem_get_seqno(ring->dev); |
395 | intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); | ||
396 | intel_ring_emit(dev, ring, | ||
397 | I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
398 | intel_ring_emit(dev, ring, seqno); | ||
399 | intel_ring_emit(dev, ring, MI_USER_INTERRUPT); | ||
400 | intel_ring_advance(dev, ring); | ||
401 | 564 | ||
402 | DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); | 565 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); |
566 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
567 | intel_ring_emit(ring, seqno); | ||
568 | intel_ring_emit(ring, MI_USER_INTERRUPT); | ||
569 | intel_ring_advance(ring); | ||
403 | 570 | ||
404 | return seqno; | 571 | DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); |
572 | *result = seqno; | ||
573 | return 0; | ||
405 | } | 574 | } |
406 | 575 | ||
407 | static void | 576 | static bool |
408 | bsd_ring_get_user_irq(struct drm_device *dev, | 577 | ring_get_irq(struct intel_ring_buffer *ring, u32 flag) |
409 | struct intel_ring_buffer *ring) | ||
410 | { | 578 | { |
411 | /* do nothing */ | 579 | struct drm_device *dev = ring->dev; |
580 | |||
581 | if (!dev->irq_enabled) | ||
582 | return false; | ||
583 | |||
584 | if (atomic_inc_return(&ring->irq_refcount) == 1) { | ||
585 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
586 | unsigned long irqflags; | ||
587 | |||
588 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | ||
589 | ironlake_enable_graphics_irq(dev_priv, flag); | ||
590 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
591 | } | ||
592 | |||
593 | return true; | ||
412 | } | 594 | } |
595 | |||
413 | static void | 596 | static void |
414 | bsd_ring_put_user_irq(struct drm_device *dev, | 597 | ring_put_irq(struct intel_ring_buffer *ring, u32 flag) |
415 | struct intel_ring_buffer *ring) | ||
416 | { | 598 | { |
417 | /* do nothing */ | 599 | struct drm_device *dev = ring->dev; |
600 | |||
601 | if (atomic_dec_and_test(&ring->irq_refcount)) { | ||
602 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
603 | unsigned long irqflags; | ||
604 | |||
605 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | ||
606 | ironlake_disable_graphics_irq(dev_priv, flag); | ||
607 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
608 | } | ||
418 | } | 609 | } |
419 | 610 | ||
420 | static u32 | 611 | static bool |
421 | ring_status_page_get_seqno(struct drm_device *dev, | 612 | bsd_ring_get_irq(struct intel_ring_buffer *ring) |
422 | struct intel_ring_buffer *ring) | ||
423 | { | 613 | { |
424 | return intel_read_status_page(ring, I915_GEM_HWS_INDEX); | 614 | return ring_get_irq(ring, GT_BSD_USER_INTERRUPT); |
615 | } | ||
616 | static void | ||
617 | bsd_ring_put_irq(struct intel_ring_buffer *ring) | ||
618 | { | ||
619 | ring_put_irq(ring, GT_BSD_USER_INTERRUPT); | ||
425 | } | 620 | } |
426 | 621 | ||
427 | static int | 622 | static int |
428 | ring_dispatch_gem_execbuffer(struct drm_device *dev, | 623 | ring_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length) |
429 | struct intel_ring_buffer *ring, | ||
430 | struct drm_i915_gem_execbuffer2 *exec, | ||
431 | struct drm_clip_rect *cliprects, | ||
432 | uint64_t exec_offset) | ||
433 | { | 624 | { |
434 | uint32_t exec_start; | 625 | int ret; |
435 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | 626 | |
436 | intel_ring_begin(dev, ring, 2); | 627 | ret = intel_ring_begin(ring, 2); |
437 | intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START | | 628 | if (ret) |
438 | (2 << 6) | MI_BATCH_NON_SECURE_I965); | 629 | return ret; |
439 | intel_ring_emit(dev, ring, exec_start); | 630 | |
440 | intel_ring_advance(dev, ring); | 631 | intel_ring_emit(ring, |
632 | MI_BATCH_BUFFER_START | (2 << 6) | | ||
633 | MI_BATCH_NON_SECURE_I965); | ||
634 | intel_ring_emit(ring, offset); | ||
635 | intel_ring_advance(ring); | ||
636 | |||
441 | return 0; | 637 | return 0; |
442 | } | 638 | } |
443 | 639 | ||
444 | static int | 640 | static int |
445 | render_ring_dispatch_gem_execbuffer(struct drm_device *dev, | 641 | render_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, |
446 | struct intel_ring_buffer *ring, | 642 | u32 offset, u32 len) |
447 | struct drm_i915_gem_execbuffer2 *exec, | ||
448 | struct drm_clip_rect *cliprects, | ||
449 | uint64_t exec_offset) | ||
450 | { | 643 | { |
644 | struct drm_device *dev = ring->dev; | ||
451 | drm_i915_private_t *dev_priv = dev->dev_private; | 645 | drm_i915_private_t *dev_priv = dev->dev_private; |
452 | int nbox = exec->num_cliprects; | 646 | int ret; |
453 | int i = 0, count; | ||
454 | uint32_t exec_start, exec_len; | ||
455 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | ||
456 | exec_len = (uint32_t) exec->batch_len; | ||
457 | 647 | ||
458 | trace_i915_gem_request_submit(dev, dev_priv->next_seqno + 1); | 648 | trace_i915_gem_request_submit(dev, dev_priv->next_seqno + 1); |
459 | 649 | ||
460 | count = nbox ? nbox : 1; | 650 | if (IS_I830(dev) || IS_845G(dev)) { |
651 | ret = intel_ring_begin(ring, 4); | ||
652 | if (ret) | ||
653 | return ret; | ||
461 | 654 | ||
462 | for (i = 0; i < count; i++) { | 655 | intel_ring_emit(ring, MI_BATCH_BUFFER); |
463 | if (i < nbox) { | 656 | intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); |
464 | int ret = i915_emit_box(dev, cliprects, i, | 657 | intel_ring_emit(ring, offset + len - 8); |
465 | exec->DR1, exec->DR4); | 658 | intel_ring_emit(ring, 0); |
466 | if (ret) | 659 | } else { |
467 | return ret; | 660 | ret = intel_ring_begin(ring, 2); |
468 | } | 661 | if (ret) |
662 | return ret; | ||
469 | 663 | ||
470 | if (IS_I830(dev) || IS_845G(dev)) { | 664 | if (INTEL_INFO(dev)->gen >= 4) { |
471 | intel_ring_begin(dev, ring, 4); | 665 | intel_ring_emit(ring, |
472 | intel_ring_emit(dev, ring, MI_BATCH_BUFFER); | 666 | MI_BATCH_BUFFER_START | (2 << 6) | |
473 | intel_ring_emit(dev, ring, | 667 | MI_BATCH_NON_SECURE_I965); |
474 | exec_start | MI_BATCH_NON_SECURE); | 668 | intel_ring_emit(ring, offset); |
475 | intel_ring_emit(dev, ring, exec_start + exec_len - 4); | ||
476 | intel_ring_emit(dev, ring, 0); | ||
477 | } else { | 669 | } else { |
478 | intel_ring_begin(dev, ring, 2); | 670 | intel_ring_emit(ring, |
479 | if (INTEL_INFO(dev)->gen >= 4) { | 671 | MI_BATCH_BUFFER_START | (2 << 6)); |
480 | intel_ring_emit(dev, ring, | 672 | intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); |
481 | MI_BATCH_BUFFER_START | (2 << 6) | ||
482 | | MI_BATCH_NON_SECURE_I965); | ||
483 | intel_ring_emit(dev, ring, exec_start); | ||
484 | } else { | ||
485 | intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START | ||
486 | | (2 << 6)); | ||
487 | intel_ring_emit(dev, ring, exec_start | | ||
488 | MI_BATCH_NON_SECURE); | ||
489 | } | ||
490 | } | 673 | } |
491 | intel_ring_advance(dev, ring); | ||
492 | } | 674 | } |
493 | 675 | intel_ring_advance(ring); | |
494 | if (IS_G4X(dev) || IS_GEN5(dev)) { | ||
495 | intel_ring_begin(dev, ring, 2); | ||
496 | intel_ring_emit(dev, ring, MI_FLUSH | | ||
497 | MI_NO_WRITE_FLUSH | | ||
498 | MI_INVALIDATE_ISP ); | ||
499 | intel_ring_emit(dev, ring, MI_NOOP); | ||
500 | intel_ring_advance(dev, ring); | ||
501 | } | ||
502 | /* XXX breadcrumb */ | ||
503 | 676 | ||
504 | return 0; | 677 | return 0; |
505 | } | 678 | } |
506 | 679 | ||
507 | static void cleanup_status_page(struct drm_device *dev, | 680 | static void cleanup_status_page(struct intel_ring_buffer *ring) |
508 | struct intel_ring_buffer *ring) | ||
509 | { | 681 | { |
510 | drm_i915_private_t *dev_priv = dev->dev_private; | 682 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
511 | struct drm_gem_object *obj; | 683 | struct drm_i915_gem_object *obj; |
512 | struct drm_i915_gem_object *obj_priv; | ||
513 | 684 | ||
514 | obj = ring->status_page.obj; | 685 | obj = ring->status_page.obj; |
515 | if (obj == NULL) | 686 | if (obj == NULL) |
516 | return; | 687 | return; |
517 | obj_priv = to_intel_bo(obj); | ||
518 | 688 | ||
519 | kunmap(obj_priv->pages[0]); | 689 | kunmap(obj->pages[0]); |
520 | i915_gem_object_unpin(obj); | 690 | i915_gem_object_unpin(obj); |
521 | drm_gem_object_unreference(obj); | 691 | drm_gem_object_unreference(&obj->base); |
522 | ring->status_page.obj = NULL; | 692 | ring->status_page.obj = NULL; |
523 | 693 | ||
524 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | 694 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); |
525 | } | 695 | } |
526 | 696 | ||
527 | static int init_status_page(struct drm_device *dev, | 697 | static int init_status_page(struct intel_ring_buffer *ring) |
528 | struct intel_ring_buffer *ring) | ||
529 | { | 698 | { |
699 | struct drm_device *dev = ring->dev; | ||
530 | drm_i915_private_t *dev_priv = dev->dev_private; | 700 | drm_i915_private_t *dev_priv = dev->dev_private; |
531 | struct drm_gem_object *obj; | 701 | struct drm_i915_gem_object *obj; |
532 | struct drm_i915_gem_object *obj_priv; | ||
533 | int ret; | 702 | int ret; |
534 | 703 | ||
535 | obj = i915_gem_alloc_object(dev, 4096); | 704 | obj = i915_gem_alloc_object(dev, 4096); |
@@ -538,16 +707,15 @@ static int init_status_page(struct drm_device *dev, | |||
538 | ret = -ENOMEM; | 707 | ret = -ENOMEM; |
539 | goto err; | 708 | goto err; |
540 | } | 709 | } |
541 | obj_priv = to_intel_bo(obj); | 710 | obj->agp_type = AGP_USER_CACHED_MEMORY; |
542 | obj_priv->agp_type = AGP_USER_CACHED_MEMORY; | ||
543 | 711 | ||
544 | ret = i915_gem_object_pin(obj, 4096); | 712 | ret = i915_gem_object_pin(obj, 4096, true); |
545 | if (ret != 0) { | 713 | if (ret != 0) { |
546 | goto err_unref; | 714 | goto err_unref; |
547 | } | 715 | } |
548 | 716 | ||
549 | ring->status_page.gfx_addr = obj_priv->gtt_offset; | 717 | ring->status_page.gfx_addr = obj->gtt_offset; |
550 | ring->status_page.page_addr = kmap(obj_priv->pages[0]); | 718 | ring->status_page.page_addr = kmap(obj->pages[0]); |
551 | if (ring->status_page.page_addr == NULL) { | 719 | if (ring->status_page.page_addr == NULL) { |
552 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | 720 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); |
553 | goto err_unpin; | 721 | goto err_unpin; |
@@ -555,7 +723,7 @@ static int init_status_page(struct drm_device *dev, | |||
555 | ring->status_page.obj = obj; | 723 | ring->status_page.obj = obj; |
556 | memset(ring->status_page.page_addr, 0, PAGE_SIZE); | 724 | memset(ring->status_page.page_addr, 0, PAGE_SIZE); |
557 | 725 | ||
558 | intel_ring_setup_status_page(dev, ring); | 726 | intel_ring_setup_status_page(ring); |
559 | DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n", | 727 | DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n", |
560 | ring->name, ring->status_page.gfx_addr); | 728 | ring->name, ring->status_page.gfx_addr); |
561 | 729 | ||
@@ -564,7 +732,7 @@ static int init_status_page(struct drm_device *dev, | |||
564 | err_unpin: | 732 | err_unpin: |
565 | i915_gem_object_unpin(obj); | 733 | i915_gem_object_unpin(obj); |
566 | err_unref: | 734 | err_unref: |
567 | drm_gem_object_unreference(obj); | 735 | drm_gem_object_unreference(&obj->base); |
568 | err: | 736 | err: |
569 | return ret; | 737 | return ret; |
570 | } | 738 | } |
@@ -572,9 +740,7 @@ err: | |||
572 | int intel_init_ring_buffer(struct drm_device *dev, | 740 | int intel_init_ring_buffer(struct drm_device *dev, |
573 | struct intel_ring_buffer *ring) | 741 | struct intel_ring_buffer *ring) |
574 | { | 742 | { |
575 | struct drm_i915_private *dev_priv = dev->dev_private; | 743 | struct drm_i915_gem_object *obj; |
576 | struct drm_i915_gem_object *obj_priv; | ||
577 | struct drm_gem_object *obj; | ||
578 | int ret; | 744 | int ret; |
579 | 745 | ||
580 | ring->dev = dev; | 746 | ring->dev = dev; |
@@ -583,7 +749,7 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
583 | INIT_LIST_HEAD(&ring->gpu_write_list); | 749 | INIT_LIST_HEAD(&ring->gpu_write_list); |
584 | 750 | ||
585 | if (I915_NEED_GFX_HWS(dev)) { | 751 | if (I915_NEED_GFX_HWS(dev)) { |
586 | ret = init_status_page(dev, ring); | 752 | ret = init_status_page(ring); |
587 | if (ret) | 753 | if (ret) |
588 | return ret; | 754 | return ret; |
589 | } | 755 | } |
@@ -595,15 +761,14 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
595 | goto err_hws; | 761 | goto err_hws; |
596 | } | 762 | } |
597 | 763 | ||
598 | ring->gem_object = obj; | 764 | ring->obj = obj; |
599 | 765 | ||
600 | ret = i915_gem_object_pin(obj, PAGE_SIZE); | 766 | ret = i915_gem_object_pin(obj, PAGE_SIZE, true); |
601 | if (ret) | 767 | if (ret) |
602 | goto err_unref; | 768 | goto err_unref; |
603 | 769 | ||
604 | obj_priv = to_intel_bo(obj); | ||
605 | ring->map.size = ring->size; | 770 | ring->map.size = ring->size; |
606 | ring->map.offset = dev->agp->base + obj_priv->gtt_offset; | 771 | ring->map.offset = dev->agp->base + obj->gtt_offset; |
607 | ring->map.type = 0; | 772 | ring->map.type = 0; |
608 | ring->map.flags = 0; | 773 | ring->map.flags = 0; |
609 | ring->map.mtrr = 0; | 774 | ring->map.mtrr = 0; |
@@ -616,60 +781,57 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
616 | } | 781 | } |
617 | 782 | ||
618 | ring->virtual_start = ring->map.handle; | 783 | ring->virtual_start = ring->map.handle; |
619 | ret = ring->init(dev, ring); | 784 | ret = ring->init(ring); |
620 | if (ret) | 785 | if (ret) |
621 | goto err_unmap; | 786 | goto err_unmap; |
622 | 787 | ||
623 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 788 | return 0; |
624 | i915_kernel_lost_context(dev); | ||
625 | else { | ||
626 | ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; | ||
627 | ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; | ||
628 | ring->space = ring->head - (ring->tail + 8); | ||
629 | if (ring->space < 0) | ||
630 | ring->space += ring->size; | ||
631 | } | ||
632 | return ret; | ||
633 | 789 | ||
634 | err_unmap: | 790 | err_unmap: |
635 | drm_core_ioremapfree(&ring->map, dev); | 791 | drm_core_ioremapfree(&ring->map, dev); |
636 | err_unpin: | 792 | err_unpin: |
637 | i915_gem_object_unpin(obj); | 793 | i915_gem_object_unpin(obj); |
638 | err_unref: | 794 | err_unref: |
639 | drm_gem_object_unreference(obj); | 795 | drm_gem_object_unreference(&obj->base); |
640 | ring->gem_object = NULL; | 796 | ring->obj = NULL; |
641 | err_hws: | 797 | err_hws: |
642 | cleanup_status_page(dev, ring); | 798 | cleanup_status_page(ring); |
643 | return ret; | 799 | return ret; |
644 | } | 800 | } |
645 | 801 | ||
646 | void intel_cleanup_ring_buffer(struct drm_device *dev, | 802 | void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring) |
647 | struct intel_ring_buffer *ring) | ||
648 | { | 803 | { |
649 | if (ring->gem_object == NULL) | 804 | struct drm_i915_private *dev_priv; |
805 | int ret; | ||
806 | |||
807 | if (ring->obj == NULL) | ||
650 | return; | 808 | return; |
651 | 809 | ||
652 | drm_core_ioremapfree(&ring->map, dev); | 810 | /* Disable the ring buffer. The ring must be idle at this point */ |
811 | dev_priv = ring->dev->dev_private; | ||
812 | ret = intel_wait_ring_buffer(ring, ring->size - 8); | ||
813 | I915_WRITE_CTL(ring, 0); | ||
653 | 814 | ||
654 | i915_gem_object_unpin(ring->gem_object); | 815 | drm_core_ioremapfree(&ring->map, ring->dev); |
655 | drm_gem_object_unreference(ring->gem_object); | 816 | |
656 | ring->gem_object = NULL; | 817 | i915_gem_object_unpin(ring->obj); |
818 | drm_gem_object_unreference(&ring->obj->base); | ||
819 | ring->obj = NULL; | ||
657 | 820 | ||
658 | if (ring->cleanup) | 821 | if (ring->cleanup) |
659 | ring->cleanup(ring); | 822 | ring->cleanup(ring); |
660 | 823 | ||
661 | cleanup_status_page(dev, ring); | 824 | cleanup_status_page(ring); |
662 | } | 825 | } |
663 | 826 | ||
664 | static int intel_wrap_ring_buffer(struct drm_device *dev, | 827 | static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) |
665 | struct intel_ring_buffer *ring) | ||
666 | { | 828 | { |
667 | unsigned int *virt; | 829 | unsigned int *virt; |
668 | int rem; | 830 | int rem; |
669 | rem = ring->size - ring->tail; | 831 | rem = ring->size - ring->tail; |
670 | 832 | ||
671 | if (ring->space < rem) { | 833 | if (ring->space < rem) { |
672 | int ret = intel_wait_ring_buffer(dev, ring, rem); | 834 | int ret = intel_wait_ring_buffer(ring, rem); |
673 | if (ret) | 835 | if (ret) |
674 | return ret; | 836 | return ret; |
675 | } | 837 | } |
@@ -687,32 +849,29 @@ static int intel_wrap_ring_buffer(struct drm_device *dev, | |||
687 | return 0; | 849 | return 0; |
688 | } | 850 | } |
689 | 851 | ||
690 | int intel_wait_ring_buffer(struct drm_device *dev, | 852 | int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) |
691 | struct intel_ring_buffer *ring, int n) | ||
692 | { | 853 | { |
854 | struct drm_device *dev = ring->dev; | ||
855 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
693 | unsigned long end; | 856 | unsigned long end; |
694 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
695 | u32 head; | 857 | u32 head; |
696 | 858 | ||
697 | head = intel_read_status_page(ring, 4); | ||
698 | if (head) { | ||
699 | ring->head = head & HEAD_ADDR; | ||
700 | ring->space = ring->head - (ring->tail + 8); | ||
701 | if (ring->space < 0) | ||
702 | ring->space += ring->size; | ||
703 | if (ring->space >= n) | ||
704 | return 0; | ||
705 | } | ||
706 | |||
707 | trace_i915_ring_wait_begin (dev); | 859 | trace_i915_ring_wait_begin (dev); |
708 | end = jiffies + 3 * HZ; | 860 | end = jiffies + 3 * HZ; |
709 | do { | 861 | do { |
710 | ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; | 862 | /* If the reported head position has wrapped or hasn't advanced, |
863 | * fallback to the slow and accurate path. | ||
864 | */ | ||
865 | head = intel_read_status_page(ring, 4); | ||
866 | if (head < ring->actual_head) | ||
867 | head = I915_READ_HEAD(ring); | ||
868 | ring->actual_head = head; | ||
869 | ring->head = head & HEAD_ADDR; | ||
711 | ring->space = ring->head - (ring->tail + 8); | 870 | ring->space = ring->head - (ring->tail + 8); |
712 | if (ring->space < 0) | 871 | if (ring->space < 0) |
713 | ring->space += ring->size; | 872 | ring->space += ring->size; |
714 | if (ring->space >= n) { | 873 | if (ring->space >= n) { |
715 | trace_i915_ring_wait_end (dev); | 874 | trace_i915_ring_wait_end(dev); |
716 | return 0; | 875 | return 0; |
717 | } | 876 | } |
718 | 877 | ||
@@ -723,29 +882,39 @@ int intel_wait_ring_buffer(struct drm_device *dev, | |||
723 | } | 882 | } |
724 | 883 | ||
725 | msleep(1); | 884 | msleep(1); |
885 | if (atomic_read(&dev_priv->mm.wedged)) | ||
886 | return -EAGAIN; | ||
726 | } while (!time_after(jiffies, end)); | 887 | } while (!time_after(jiffies, end)); |
727 | trace_i915_ring_wait_end (dev); | 888 | trace_i915_ring_wait_end (dev); |
728 | return -EBUSY; | 889 | return -EBUSY; |
729 | } | 890 | } |
730 | 891 | ||
731 | void intel_ring_begin(struct drm_device *dev, | 892 | int intel_ring_begin(struct intel_ring_buffer *ring, |
732 | struct intel_ring_buffer *ring, | 893 | int num_dwords) |
733 | int num_dwords) | ||
734 | { | 894 | { |
735 | int n = 4*num_dwords; | 895 | int n = 4*num_dwords; |
736 | if (unlikely(ring->tail + n > ring->size)) | 896 | int ret; |
737 | intel_wrap_ring_buffer(dev, ring); | 897 | |
738 | if (unlikely(ring->space < n)) | 898 | if (unlikely(ring->tail + n > ring->size)) { |
739 | intel_wait_ring_buffer(dev, ring, n); | 899 | ret = intel_wrap_ring_buffer(ring); |
900 | if (unlikely(ret)) | ||
901 | return ret; | ||
902 | } | ||
903 | |||
904 | if (unlikely(ring->space < n)) { | ||
905 | ret = intel_wait_ring_buffer(ring, n); | ||
906 | if (unlikely(ret)) | ||
907 | return ret; | ||
908 | } | ||
740 | 909 | ||
741 | ring->space -= n; | 910 | ring->space -= n; |
911 | return 0; | ||
742 | } | 912 | } |
743 | 913 | ||
744 | void intel_ring_advance(struct drm_device *dev, | 914 | void intel_ring_advance(struct intel_ring_buffer *ring) |
745 | struct intel_ring_buffer *ring) | ||
746 | { | 915 | { |
747 | ring->tail &= ring->size - 1; | 916 | ring->tail &= ring->size - 1; |
748 | ring->write_tail(dev, ring, ring->tail); | 917 | ring->write_tail(ring, ring->tail); |
749 | } | 918 | } |
750 | 919 | ||
751 | static const struct intel_ring_buffer render_ring = { | 920 | static const struct intel_ring_buffer render_ring = { |
@@ -757,10 +926,11 @@ static const struct intel_ring_buffer render_ring = { | |||
757 | .write_tail = ring_write_tail, | 926 | .write_tail = ring_write_tail, |
758 | .flush = render_ring_flush, | 927 | .flush = render_ring_flush, |
759 | .add_request = render_ring_add_request, | 928 | .add_request = render_ring_add_request, |
760 | .get_seqno = render_ring_get_seqno, | 929 | .get_seqno = ring_get_seqno, |
761 | .user_irq_get = render_ring_get_user_irq, | 930 | .irq_get = render_ring_get_irq, |
762 | .user_irq_put = render_ring_put_user_irq, | 931 | .irq_put = render_ring_put_irq, |
763 | .dispatch_gem_execbuffer = render_ring_dispatch_gem_execbuffer, | 932 | .dispatch_execbuffer = render_ring_dispatch_execbuffer, |
933 | .cleanup = render_ring_cleanup, | ||
764 | }; | 934 | }; |
765 | 935 | ||
766 | /* ring buffer for bit-stream decoder */ | 936 | /* ring buffer for bit-stream decoder */ |
@@ -770,22 +940,21 @@ static const struct intel_ring_buffer bsd_ring = { | |||
770 | .id = RING_BSD, | 940 | .id = RING_BSD, |
771 | .mmio_base = BSD_RING_BASE, | 941 | .mmio_base = BSD_RING_BASE, |
772 | .size = 32 * PAGE_SIZE, | 942 | .size = 32 * PAGE_SIZE, |
773 | .init = init_bsd_ring, | 943 | .init = init_ring_common, |
774 | .write_tail = ring_write_tail, | 944 | .write_tail = ring_write_tail, |
775 | .flush = bsd_ring_flush, | 945 | .flush = bsd_ring_flush, |
776 | .add_request = ring_add_request, | 946 | .add_request = ring_add_request, |
777 | .get_seqno = ring_status_page_get_seqno, | 947 | .get_seqno = ring_get_seqno, |
778 | .user_irq_get = bsd_ring_get_user_irq, | 948 | .irq_get = bsd_ring_get_irq, |
779 | .user_irq_put = bsd_ring_put_user_irq, | 949 | .irq_put = bsd_ring_put_irq, |
780 | .dispatch_gem_execbuffer = ring_dispatch_gem_execbuffer, | 950 | .dispatch_execbuffer = ring_dispatch_execbuffer, |
781 | }; | 951 | }; |
782 | 952 | ||
783 | 953 | ||
784 | static void gen6_bsd_ring_write_tail(struct drm_device *dev, | 954 | static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring, |
785 | struct intel_ring_buffer *ring, | ||
786 | u32 value) | 955 | u32 value) |
787 | { | 956 | { |
788 | drm_i915_private_t *dev_priv = dev->dev_private; | 957 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
789 | 958 | ||
790 | /* Every tail move must follow the sequence below */ | 959 | /* Every tail move must follow the sequence below */ |
791 | I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, | 960 | I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, |
@@ -804,69 +973,80 @@ static void gen6_bsd_ring_write_tail(struct drm_device *dev, | |||
804 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE); | 973 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE); |
805 | } | 974 | } |
806 | 975 | ||
807 | static void gen6_ring_flush(struct drm_device *dev, | 976 | static void gen6_ring_flush(struct intel_ring_buffer *ring, |
808 | struct intel_ring_buffer *ring, | ||
809 | u32 invalidate_domains, | 977 | u32 invalidate_domains, |
810 | u32 flush_domains) | 978 | u32 flush_domains) |
811 | { | 979 | { |
812 | intel_ring_begin(dev, ring, 4); | 980 | if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) |
813 | intel_ring_emit(dev, ring, MI_FLUSH_DW); | 981 | return; |
814 | intel_ring_emit(dev, ring, 0); | 982 | |
815 | intel_ring_emit(dev, ring, 0); | 983 | if (intel_ring_begin(ring, 4) == 0) { |
816 | intel_ring_emit(dev, ring, 0); | 984 | intel_ring_emit(ring, MI_FLUSH_DW); |
817 | intel_ring_advance(dev, ring); | 985 | intel_ring_emit(ring, 0); |
986 | intel_ring_emit(ring, 0); | ||
987 | intel_ring_emit(ring, 0); | ||
988 | intel_ring_advance(ring); | ||
989 | } | ||
818 | } | 990 | } |
819 | 991 | ||
820 | static int | 992 | static int |
821 | gen6_ring_dispatch_gem_execbuffer(struct drm_device *dev, | 993 | gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, |
822 | struct intel_ring_buffer *ring, | 994 | u32 offset, u32 len) |
823 | struct drm_i915_gem_execbuffer2 *exec, | ||
824 | struct drm_clip_rect *cliprects, | ||
825 | uint64_t exec_offset) | ||
826 | { | 995 | { |
827 | uint32_t exec_start; | 996 | int ret; |
828 | 997 | ||
829 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | 998 | ret = intel_ring_begin(ring, 2); |
999 | if (ret) | ||
1000 | return ret; | ||
830 | 1001 | ||
831 | intel_ring_begin(dev, ring, 2); | 1002 | intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965); |
832 | intel_ring_emit(dev, ring, | ||
833 | MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965); | ||
834 | /* bit0-7 is the length on GEN6+ */ | 1003 | /* bit0-7 is the length on GEN6+ */ |
835 | intel_ring_emit(dev, ring, exec_start); | 1004 | intel_ring_emit(ring, offset); |
836 | intel_ring_advance(dev, ring); | 1005 | intel_ring_advance(ring); |
837 | 1006 | ||
838 | return 0; | 1007 | return 0; |
839 | } | 1008 | } |
840 | 1009 | ||
1010 | static bool | ||
1011 | gen6_bsd_ring_get_irq(struct intel_ring_buffer *ring) | ||
1012 | { | ||
1013 | return ring_get_irq(ring, GT_GEN6_BSD_USER_INTERRUPT); | ||
1014 | } | ||
1015 | |||
1016 | static void | ||
1017 | gen6_bsd_ring_put_irq(struct intel_ring_buffer *ring) | ||
1018 | { | ||
1019 | ring_put_irq(ring, GT_GEN6_BSD_USER_INTERRUPT); | ||
1020 | } | ||
1021 | |||
841 | /* ring buffer for Video Codec for Gen6+ */ | 1022 | /* ring buffer for Video Codec for Gen6+ */ |
842 | static const struct intel_ring_buffer gen6_bsd_ring = { | 1023 | static const struct intel_ring_buffer gen6_bsd_ring = { |
843 | .name = "gen6 bsd ring", | 1024 | .name = "gen6 bsd ring", |
844 | .id = RING_BSD, | 1025 | .id = RING_BSD, |
845 | .mmio_base = GEN6_BSD_RING_BASE, | 1026 | .mmio_base = GEN6_BSD_RING_BASE, |
846 | .size = 32 * PAGE_SIZE, | 1027 | .size = 32 * PAGE_SIZE, |
847 | .init = init_bsd_ring, | 1028 | .init = init_ring_common, |
848 | .write_tail = gen6_bsd_ring_write_tail, | 1029 | .write_tail = gen6_bsd_ring_write_tail, |
849 | .flush = gen6_ring_flush, | 1030 | .flush = gen6_ring_flush, |
850 | .add_request = ring_add_request, | 1031 | .add_request = gen6_add_request, |
851 | .get_seqno = ring_status_page_get_seqno, | 1032 | .get_seqno = ring_get_seqno, |
852 | .user_irq_get = bsd_ring_get_user_irq, | 1033 | .irq_get = gen6_bsd_ring_get_irq, |
853 | .user_irq_put = bsd_ring_put_user_irq, | 1034 | .irq_put = gen6_bsd_ring_put_irq, |
854 | .dispatch_gem_execbuffer = gen6_ring_dispatch_gem_execbuffer, | 1035 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, |
855 | }; | 1036 | }; |
856 | 1037 | ||
857 | /* Blitter support (SandyBridge+) */ | 1038 | /* Blitter support (SandyBridge+) */ |
858 | 1039 | ||
859 | static void | 1040 | static bool |
860 | blt_ring_get_user_irq(struct drm_device *dev, | 1041 | blt_ring_get_irq(struct intel_ring_buffer *ring) |
861 | struct intel_ring_buffer *ring) | ||
862 | { | 1042 | { |
863 | /* do nothing */ | 1043 | return ring_get_irq(ring, GT_BLT_USER_INTERRUPT); |
864 | } | 1044 | } |
1045 | |||
865 | static void | 1046 | static void |
866 | blt_ring_put_user_irq(struct drm_device *dev, | 1047 | blt_ring_put_irq(struct intel_ring_buffer *ring) |
867 | struct intel_ring_buffer *ring) | ||
868 | { | 1048 | { |
869 | /* do nothing */ | 1049 | ring_put_irq(ring, GT_BLT_USER_INTERRUPT); |
870 | } | 1050 | } |
871 | 1051 | ||
872 | 1052 | ||
@@ -884,32 +1064,31 @@ to_blt_workaround(struct intel_ring_buffer *ring) | |||
884 | return ring->private; | 1064 | return ring->private; |
885 | } | 1065 | } |
886 | 1066 | ||
887 | static int blt_ring_init(struct drm_device *dev, | 1067 | static int blt_ring_init(struct intel_ring_buffer *ring) |
888 | struct intel_ring_buffer *ring) | ||
889 | { | 1068 | { |
890 | if (NEED_BLT_WORKAROUND(dev)) { | 1069 | if (NEED_BLT_WORKAROUND(ring->dev)) { |
891 | struct drm_i915_gem_object *obj; | 1070 | struct drm_i915_gem_object *obj; |
892 | u32 __iomem *ptr; | 1071 | u32 *ptr; |
893 | int ret; | 1072 | int ret; |
894 | 1073 | ||
895 | obj = to_intel_bo(i915_gem_alloc_object(dev, 4096)); | 1074 | obj = i915_gem_alloc_object(ring->dev, 4096); |
896 | if (obj == NULL) | 1075 | if (obj == NULL) |
897 | return -ENOMEM; | 1076 | return -ENOMEM; |
898 | 1077 | ||
899 | ret = i915_gem_object_pin(&obj->base, 4096); | 1078 | ret = i915_gem_object_pin(obj, 4096, true); |
900 | if (ret) { | 1079 | if (ret) { |
901 | drm_gem_object_unreference(&obj->base); | 1080 | drm_gem_object_unreference(&obj->base); |
902 | return ret; | 1081 | return ret; |
903 | } | 1082 | } |
904 | 1083 | ||
905 | ptr = kmap(obj->pages[0]); | 1084 | ptr = kmap(obj->pages[0]); |
906 | iowrite32(MI_BATCH_BUFFER_END, ptr); | 1085 | *ptr++ = MI_BATCH_BUFFER_END; |
907 | iowrite32(MI_NOOP, ptr+1); | 1086 | *ptr++ = MI_NOOP; |
908 | kunmap(obj->pages[0]); | 1087 | kunmap(obj->pages[0]); |
909 | 1088 | ||
910 | ret = i915_gem_object_set_to_gtt_domain(&obj->base, false); | 1089 | ret = i915_gem_object_set_to_gtt_domain(obj, false); |
911 | if (ret) { | 1090 | if (ret) { |
912 | i915_gem_object_unpin(&obj->base); | 1091 | i915_gem_object_unpin(obj); |
913 | drm_gem_object_unreference(&obj->base); | 1092 | drm_gem_object_unreference(&obj->base); |
914 | return ret; | 1093 | return ret; |
915 | } | 1094 | } |
@@ -917,51 +1096,39 @@ static int blt_ring_init(struct drm_device *dev, | |||
917 | ring->private = obj; | 1096 | ring->private = obj; |
918 | } | 1097 | } |
919 | 1098 | ||
920 | return init_ring_common(dev, ring); | 1099 | return init_ring_common(ring); |
921 | } | 1100 | } |
922 | 1101 | ||
923 | static void blt_ring_begin(struct drm_device *dev, | 1102 | static int blt_ring_begin(struct intel_ring_buffer *ring, |
924 | struct intel_ring_buffer *ring, | ||
925 | int num_dwords) | 1103 | int num_dwords) |
926 | { | 1104 | { |
927 | if (ring->private) { | 1105 | if (ring->private) { |
928 | intel_ring_begin(dev, ring, num_dwords+2); | 1106 | int ret = intel_ring_begin(ring, num_dwords+2); |
929 | intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START); | 1107 | if (ret) |
930 | intel_ring_emit(dev, ring, to_blt_workaround(ring)->gtt_offset); | 1108 | return ret; |
1109 | |||
1110 | intel_ring_emit(ring, MI_BATCH_BUFFER_START); | ||
1111 | intel_ring_emit(ring, to_blt_workaround(ring)->gtt_offset); | ||
1112 | |||
1113 | return 0; | ||
931 | } else | 1114 | } else |
932 | intel_ring_begin(dev, ring, 4); | 1115 | return intel_ring_begin(ring, 4); |
933 | } | 1116 | } |
934 | 1117 | ||
935 | static void blt_ring_flush(struct drm_device *dev, | 1118 | static void blt_ring_flush(struct intel_ring_buffer *ring, |
936 | struct intel_ring_buffer *ring, | ||
937 | u32 invalidate_domains, | 1119 | u32 invalidate_domains, |
938 | u32 flush_domains) | 1120 | u32 flush_domains) |
939 | { | 1121 | { |
940 | blt_ring_begin(dev, ring, 4); | 1122 | if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) |
941 | intel_ring_emit(dev, ring, MI_FLUSH_DW); | 1123 | return; |
942 | intel_ring_emit(dev, ring, 0); | ||
943 | intel_ring_emit(dev, ring, 0); | ||
944 | intel_ring_emit(dev, ring, 0); | ||
945 | intel_ring_advance(dev, ring); | ||
946 | } | ||
947 | |||
948 | static u32 | ||
949 | blt_ring_add_request(struct drm_device *dev, | ||
950 | struct intel_ring_buffer *ring, | ||
951 | u32 flush_domains) | ||
952 | { | ||
953 | u32 seqno = i915_gem_get_seqno(dev); | ||
954 | |||
955 | blt_ring_begin(dev, ring, 4); | ||
956 | intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); | ||
957 | intel_ring_emit(dev, ring, | ||
958 | I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
959 | intel_ring_emit(dev, ring, seqno); | ||
960 | intel_ring_emit(dev, ring, MI_USER_INTERRUPT); | ||
961 | intel_ring_advance(dev, ring); | ||
962 | 1124 | ||
963 | DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); | 1125 | if (blt_ring_begin(ring, 4) == 0) { |
964 | return seqno; | 1126 | intel_ring_emit(ring, MI_FLUSH_DW); |
1127 | intel_ring_emit(ring, 0); | ||
1128 | intel_ring_emit(ring, 0); | ||
1129 | intel_ring_emit(ring, 0); | ||
1130 | intel_ring_advance(ring); | ||
1131 | } | ||
965 | } | 1132 | } |
966 | 1133 | ||
967 | static void blt_ring_cleanup(struct intel_ring_buffer *ring) | 1134 | static void blt_ring_cleanup(struct intel_ring_buffer *ring) |
@@ -982,47 +1149,54 @@ static const struct intel_ring_buffer gen6_blt_ring = { | |||
982 | .init = blt_ring_init, | 1149 | .init = blt_ring_init, |
983 | .write_tail = ring_write_tail, | 1150 | .write_tail = ring_write_tail, |
984 | .flush = blt_ring_flush, | 1151 | .flush = blt_ring_flush, |
985 | .add_request = blt_ring_add_request, | 1152 | .add_request = gen6_add_request, |
986 | .get_seqno = ring_status_page_get_seqno, | 1153 | .get_seqno = ring_get_seqno, |
987 | .user_irq_get = blt_ring_get_user_irq, | 1154 | .irq_get = blt_ring_get_irq, |
988 | .user_irq_put = blt_ring_put_user_irq, | 1155 | .irq_put = blt_ring_put_irq, |
989 | .dispatch_gem_execbuffer = gen6_ring_dispatch_gem_execbuffer, | 1156 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, |
990 | .cleanup = blt_ring_cleanup, | 1157 | .cleanup = blt_ring_cleanup, |
991 | }; | 1158 | }; |
992 | 1159 | ||
993 | int intel_init_render_ring_buffer(struct drm_device *dev) | 1160 | int intel_init_render_ring_buffer(struct drm_device *dev) |
994 | { | 1161 | { |
995 | drm_i915_private_t *dev_priv = dev->dev_private; | 1162 | drm_i915_private_t *dev_priv = dev->dev_private; |
996 | 1163 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; | |
997 | dev_priv->render_ring = render_ring; | 1164 | |
1165 | *ring = render_ring; | ||
1166 | if (INTEL_INFO(dev)->gen >= 6) { | ||
1167 | ring->add_request = gen6_add_request; | ||
1168 | } else if (IS_GEN5(dev)) { | ||
1169 | ring->add_request = pc_render_add_request; | ||
1170 | ring->get_seqno = pc_render_get_seqno; | ||
1171 | } | ||
998 | 1172 | ||
999 | if (!I915_NEED_GFX_HWS(dev)) { | 1173 | if (!I915_NEED_GFX_HWS(dev)) { |
1000 | dev_priv->render_ring.status_page.page_addr | 1174 | ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; |
1001 | = dev_priv->status_page_dmah->vaddr; | 1175 | memset(ring->status_page.page_addr, 0, PAGE_SIZE); |
1002 | memset(dev_priv->render_ring.status_page.page_addr, | ||
1003 | 0, PAGE_SIZE); | ||
1004 | } | 1176 | } |
1005 | 1177 | ||
1006 | return intel_init_ring_buffer(dev, &dev_priv->render_ring); | 1178 | return intel_init_ring_buffer(dev, ring); |
1007 | } | 1179 | } |
1008 | 1180 | ||
1009 | int intel_init_bsd_ring_buffer(struct drm_device *dev) | 1181 | int intel_init_bsd_ring_buffer(struct drm_device *dev) |
1010 | { | 1182 | { |
1011 | drm_i915_private_t *dev_priv = dev->dev_private; | 1183 | drm_i915_private_t *dev_priv = dev->dev_private; |
1184 | struct intel_ring_buffer *ring = &dev_priv->ring[VCS]; | ||
1012 | 1185 | ||
1013 | if (IS_GEN6(dev)) | 1186 | if (IS_GEN6(dev)) |
1014 | dev_priv->bsd_ring = gen6_bsd_ring; | 1187 | *ring = gen6_bsd_ring; |
1015 | else | 1188 | else |
1016 | dev_priv->bsd_ring = bsd_ring; | 1189 | *ring = bsd_ring; |
1017 | 1190 | ||
1018 | return intel_init_ring_buffer(dev, &dev_priv->bsd_ring); | 1191 | return intel_init_ring_buffer(dev, ring); |
1019 | } | 1192 | } |
1020 | 1193 | ||
1021 | int intel_init_blt_ring_buffer(struct drm_device *dev) | 1194 | int intel_init_blt_ring_buffer(struct drm_device *dev) |
1022 | { | 1195 | { |
1023 | drm_i915_private_t *dev_priv = dev->dev_private; | 1196 | drm_i915_private_t *dev_priv = dev->dev_private; |
1197 | struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; | ||
1024 | 1198 | ||
1025 | dev_priv->blt_ring = gen6_blt_ring; | 1199 | *ring = gen6_blt_ring; |
1026 | 1200 | ||
1027 | return intel_init_ring_buffer(dev, &dev_priv->blt_ring); | 1201 | return intel_init_ring_buffer(dev, ring); |
1028 | } | 1202 | } |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 3126c268198..8e2e357ad6e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -1,22 +1,37 @@ | |||
1 | #ifndef _INTEL_RINGBUFFER_H_ | 1 | #ifndef _INTEL_RINGBUFFER_H_ |
2 | #define _INTEL_RINGBUFFER_H_ | 2 | #define _INTEL_RINGBUFFER_H_ |
3 | 3 | ||
4 | enum { | ||
5 | RCS = 0x0, | ||
6 | VCS, | ||
7 | BCS, | ||
8 | I915_NUM_RINGS, | ||
9 | }; | ||
10 | |||
4 | struct intel_hw_status_page { | 11 | struct intel_hw_status_page { |
5 | void *page_addr; | 12 | u32 __iomem *page_addr; |
6 | unsigned int gfx_addr; | 13 | unsigned int gfx_addr; |
7 | struct drm_gem_object *obj; | 14 | struct drm_i915_gem_object *obj; |
8 | }; | 15 | }; |
9 | 16 | ||
10 | #define I915_READ_TAIL(ring) I915_READ(RING_TAIL(ring->mmio_base)) | 17 | #define I915_RING_READ(reg) i915_safe_read(dev_priv, reg) |
18 | |||
19 | #define I915_READ_TAIL(ring) I915_RING_READ(RING_TAIL(ring->mmio_base)) | ||
11 | #define I915_WRITE_TAIL(ring, val) I915_WRITE(RING_TAIL(ring->mmio_base), val) | 20 | #define I915_WRITE_TAIL(ring, val) I915_WRITE(RING_TAIL(ring->mmio_base), val) |
12 | #define I915_READ_START(ring) I915_READ(RING_START(ring->mmio_base)) | 21 | |
22 | #define I915_READ_START(ring) I915_RING_READ(RING_START(ring->mmio_base)) | ||
13 | #define I915_WRITE_START(ring, val) I915_WRITE(RING_START(ring->mmio_base), val) | 23 | #define I915_WRITE_START(ring, val) I915_WRITE(RING_START(ring->mmio_base), val) |
14 | #define I915_READ_HEAD(ring) I915_READ(RING_HEAD(ring->mmio_base)) | 24 | |
25 | #define I915_READ_HEAD(ring) I915_RING_READ(RING_HEAD(ring->mmio_base)) | ||
15 | #define I915_WRITE_HEAD(ring, val) I915_WRITE(RING_HEAD(ring->mmio_base), val) | 26 | #define I915_WRITE_HEAD(ring, val) I915_WRITE(RING_HEAD(ring->mmio_base), val) |
16 | #define I915_READ_CTL(ring) I915_READ(RING_CTL(ring->mmio_base)) | 27 | |
28 | #define I915_READ_CTL(ring) I915_RING_READ(RING_CTL(ring->mmio_base)) | ||
17 | #define I915_WRITE_CTL(ring, val) I915_WRITE(RING_CTL(ring->mmio_base), val) | 29 | #define I915_WRITE_CTL(ring, val) I915_WRITE(RING_CTL(ring->mmio_base), val) |
18 | 30 | ||
19 | struct drm_i915_gem_execbuffer2; | 31 | #define I915_READ_NOPID(ring) I915_RING_READ(RING_NOPID(ring->mmio_base)) |
32 | #define I915_READ_SYNC_0(ring) I915_RING_READ(RING_SYNC_0(ring->mmio_base)) | ||
33 | #define I915_READ_SYNC_1(ring) I915_RING_READ(RING_SYNC_1(ring->mmio_base)) | ||
34 | |||
20 | struct intel_ring_buffer { | 35 | struct intel_ring_buffer { |
21 | const char *name; | 36 | const char *name; |
22 | enum intel_ring_id { | 37 | enum intel_ring_id { |
@@ -25,44 +40,36 @@ struct intel_ring_buffer { | |||
25 | RING_BLT = 0x4, | 40 | RING_BLT = 0x4, |
26 | } id; | 41 | } id; |
27 | u32 mmio_base; | 42 | u32 mmio_base; |
28 | unsigned long size; | ||
29 | void *virtual_start; | 43 | void *virtual_start; |
30 | struct drm_device *dev; | 44 | struct drm_device *dev; |
31 | struct drm_gem_object *gem_object; | 45 | struct drm_i915_gem_object *obj; |
32 | 46 | ||
33 | unsigned int head; | 47 | u32 actual_head; |
34 | unsigned int tail; | 48 | u32 head; |
49 | u32 tail; | ||
35 | int space; | 50 | int space; |
51 | int size; | ||
36 | struct intel_hw_status_page status_page; | 52 | struct intel_hw_status_page status_page; |
37 | 53 | ||
38 | u32 irq_gem_seqno; /* last seq seem at irq time */ | 54 | u32 irq_seqno; /* last seq seem at irq time */ |
39 | u32 waiting_gem_seqno; | 55 | u32 waiting_seqno; |
40 | int user_irq_refcount; | 56 | u32 sync_seqno[I915_NUM_RINGS-1]; |
41 | void (*user_irq_get)(struct drm_device *dev, | 57 | atomic_t irq_refcount; |
42 | struct intel_ring_buffer *ring); | 58 | bool __must_check (*irq_get)(struct intel_ring_buffer *ring); |
43 | void (*user_irq_put)(struct drm_device *dev, | 59 | void (*irq_put)(struct intel_ring_buffer *ring); |
44 | struct intel_ring_buffer *ring); | ||
45 | 60 | ||
46 | int (*init)(struct drm_device *dev, | 61 | int (*init)(struct intel_ring_buffer *ring); |
47 | struct intel_ring_buffer *ring); | ||
48 | 62 | ||
49 | void (*write_tail)(struct drm_device *dev, | 63 | void (*write_tail)(struct intel_ring_buffer *ring, |
50 | struct intel_ring_buffer *ring, | ||
51 | u32 value); | 64 | u32 value); |
52 | void (*flush)(struct drm_device *dev, | 65 | void (*flush)(struct intel_ring_buffer *ring, |
53 | struct intel_ring_buffer *ring, | 66 | u32 invalidate_domains, |
54 | u32 invalidate_domains, | 67 | u32 flush_domains); |
55 | u32 flush_domains); | 68 | int (*add_request)(struct intel_ring_buffer *ring, |
56 | u32 (*add_request)(struct drm_device *dev, | 69 | u32 *seqno); |
57 | struct intel_ring_buffer *ring, | 70 | u32 (*get_seqno)(struct intel_ring_buffer *ring); |
58 | u32 flush_domains); | 71 | int (*dispatch_execbuffer)(struct intel_ring_buffer *ring, |
59 | u32 (*get_seqno)(struct drm_device *dev, | 72 | u32 offset, u32 length); |
60 | struct intel_ring_buffer *ring); | ||
61 | int (*dispatch_gem_execbuffer)(struct drm_device *dev, | ||
62 | struct intel_ring_buffer *ring, | ||
63 | struct drm_i915_gem_execbuffer2 *exec, | ||
64 | struct drm_clip_rect *cliprects, | ||
65 | uint64_t exec_offset); | ||
66 | void (*cleanup)(struct intel_ring_buffer *ring); | 73 | void (*cleanup)(struct intel_ring_buffer *ring); |
67 | 74 | ||
68 | /** | 75 | /** |
@@ -95,7 +102,7 @@ struct intel_ring_buffer { | |||
95 | /** | 102 | /** |
96 | * Do we have some not yet emitted requests outstanding? | 103 | * Do we have some not yet emitted requests outstanding? |
97 | */ | 104 | */ |
98 | bool outstanding_lazy_request; | 105 | u32 outstanding_lazy_request; |
99 | 106 | ||
100 | wait_queue_head_t irq_queue; | 107 | wait_queue_head_t irq_queue; |
101 | drm_local_map_t map; | 108 | drm_local_map_t map; |
@@ -104,44 +111,54 @@ struct intel_ring_buffer { | |||
104 | }; | 111 | }; |
105 | 112 | ||
106 | static inline u32 | 113 | static inline u32 |
114 | intel_ring_sync_index(struct intel_ring_buffer *ring, | ||
115 | struct intel_ring_buffer *other) | ||
116 | { | ||
117 | int idx; | ||
118 | |||
119 | /* | ||
120 | * cs -> 0 = vcs, 1 = bcs | ||
121 | * vcs -> 0 = bcs, 1 = cs, | ||
122 | * bcs -> 0 = cs, 1 = vcs. | ||
123 | */ | ||
124 | |||
125 | idx = (other - ring) - 1; | ||
126 | if (idx < 0) | ||
127 | idx += I915_NUM_RINGS; | ||
128 | |||
129 | return idx; | ||
130 | } | ||
131 | |||
132 | static inline u32 | ||
107 | intel_read_status_page(struct intel_ring_buffer *ring, | 133 | intel_read_status_page(struct intel_ring_buffer *ring, |
108 | int reg) | 134 | int reg) |
109 | { | 135 | { |
110 | u32 *regs = ring->status_page.page_addr; | 136 | return ioread32(ring->status_page.page_addr + reg); |
111 | return regs[reg]; | ||
112 | } | 137 | } |
113 | 138 | ||
114 | int intel_init_ring_buffer(struct drm_device *dev, | 139 | void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring); |
115 | struct intel_ring_buffer *ring); | 140 | int __must_check intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n); |
116 | void intel_cleanup_ring_buffer(struct drm_device *dev, | 141 | int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n); |
117 | struct intel_ring_buffer *ring); | 142 | |
118 | int intel_wait_ring_buffer(struct drm_device *dev, | 143 | static inline void intel_ring_emit(struct intel_ring_buffer *ring, |
119 | struct intel_ring_buffer *ring, int n); | 144 | u32 data) |
120 | void intel_ring_begin(struct drm_device *dev, | ||
121 | struct intel_ring_buffer *ring, int n); | ||
122 | |||
123 | static inline void intel_ring_emit(struct drm_device *dev, | ||
124 | struct intel_ring_buffer *ring, | ||
125 | unsigned int data) | ||
126 | { | 145 | { |
127 | unsigned int *virt = ring->virtual_start + ring->tail; | 146 | iowrite32(data, ring->virtual_start + ring->tail); |
128 | *virt = data; | ||
129 | ring->tail += 4; | 147 | ring->tail += 4; |
130 | } | 148 | } |
131 | 149 | ||
132 | void intel_ring_advance(struct drm_device *dev, | 150 | void intel_ring_advance(struct intel_ring_buffer *ring); |
133 | struct intel_ring_buffer *ring); | ||
134 | 151 | ||
135 | u32 intel_ring_get_seqno(struct drm_device *dev, | 152 | u32 intel_ring_get_seqno(struct intel_ring_buffer *ring); |
136 | struct intel_ring_buffer *ring); | 153 | int intel_ring_sync(struct intel_ring_buffer *ring, |
154 | struct intel_ring_buffer *to, | ||
155 | u32 seqno); | ||
137 | 156 | ||
138 | int intel_init_render_ring_buffer(struct drm_device *dev); | 157 | int intel_init_render_ring_buffer(struct drm_device *dev); |
139 | int intel_init_bsd_ring_buffer(struct drm_device *dev); | 158 | int intel_init_bsd_ring_buffer(struct drm_device *dev); |
140 | int intel_init_blt_ring_buffer(struct drm_device *dev); | 159 | int intel_init_blt_ring_buffer(struct drm_device *dev); |
141 | 160 | ||
142 | u32 intel_ring_get_active_head(struct drm_device *dev, | 161 | u32 intel_ring_get_active_head(struct intel_ring_buffer *ring); |
143 | struct intel_ring_buffer *ring); | 162 | void intel_ring_setup_status_page(struct intel_ring_buffer *ring); |
144 | void intel_ring_setup_status_page(struct drm_device *dev, | ||
145 | struct intel_ring_buffer *ring); | ||
146 | 163 | ||
147 | #endif /* _INTEL_RINGBUFFER_H_ */ | 164 | #endif /* _INTEL_RINGBUFFER_H_ */ |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index de158b76bcd..6c0bb18a26e 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -107,7 +107,8 @@ struct intel_sdvo { | |||
107 | * This is set if we treat the device as HDMI, instead of DVI. | 107 | * This is set if we treat the device as HDMI, instead of DVI. |
108 | */ | 108 | */ |
109 | bool is_hdmi; | 109 | bool is_hdmi; |
110 | bool has_audio; | 110 | bool has_hdmi_monitor; |
111 | bool has_hdmi_audio; | ||
111 | 112 | ||
112 | /** | 113 | /** |
113 | * This is set if we detect output of sdvo device as LVDS and | 114 | * This is set if we detect output of sdvo device as LVDS and |
@@ -1023,7 +1024,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1023 | if (!intel_sdvo_set_target_input(intel_sdvo)) | 1024 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
1024 | return; | 1025 | return; |
1025 | 1026 | ||
1026 | if (intel_sdvo->is_hdmi && | 1027 | if (intel_sdvo->has_hdmi_monitor && |
1027 | !intel_sdvo_set_avi_infoframe(intel_sdvo)) | 1028 | !intel_sdvo_set_avi_infoframe(intel_sdvo)) |
1028 | return; | 1029 | return; |
1029 | 1030 | ||
@@ -1044,7 +1045,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1044 | 1045 | ||
1045 | /* Set the SDVO control regs. */ | 1046 | /* Set the SDVO control regs. */ |
1046 | if (INTEL_INFO(dev)->gen >= 4) { | 1047 | if (INTEL_INFO(dev)->gen >= 4) { |
1047 | sdvox = SDVO_BORDER_ENABLE; | 1048 | sdvox = 0; |
1049 | if (INTEL_INFO(dev)->gen < 5) | ||
1050 | sdvox |= SDVO_BORDER_ENABLE; | ||
1048 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | 1051 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
1049 | sdvox |= SDVO_VSYNC_ACTIVE_HIGH; | 1052 | sdvox |= SDVO_VSYNC_ACTIVE_HIGH; |
1050 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 1053 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
@@ -1063,7 +1066,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1063 | } | 1066 | } |
1064 | if (intel_crtc->pipe == 1) | 1067 | if (intel_crtc->pipe == 1) |
1065 | sdvox |= SDVO_PIPE_B_SELECT; | 1068 | sdvox |= SDVO_PIPE_B_SELECT; |
1066 | if (intel_sdvo->has_audio) | 1069 | if (intel_sdvo->has_hdmi_audio) |
1067 | sdvox |= SDVO_AUDIO_ENABLE; | 1070 | sdvox |= SDVO_AUDIO_ENABLE; |
1068 | 1071 | ||
1069 | if (INTEL_INFO(dev)->gen >= 4) { | 1072 | if (INTEL_INFO(dev)->gen >= 4) { |
@@ -1074,7 +1077,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1074 | sdvox |= (pixel_multiplier - 1) << SDVO_PORT_MULTIPLY_SHIFT; | 1077 | sdvox |= (pixel_multiplier - 1) << SDVO_PORT_MULTIPLY_SHIFT; |
1075 | } | 1078 | } |
1076 | 1079 | ||
1077 | if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL) | 1080 | if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL && |
1081 | INTEL_INFO(dev)->gen < 5) | ||
1078 | sdvox |= SDVO_STALL_SELECT; | 1082 | sdvox |= SDVO_STALL_SELECT; |
1079 | intel_sdvo_write_sdvox(intel_sdvo, sdvox); | 1083 | intel_sdvo_write_sdvox(intel_sdvo, sdvox); |
1080 | } | 1084 | } |
@@ -1295,55 +1299,14 @@ intel_sdvo_get_edid(struct drm_connector *connector) | |||
1295 | return drm_get_edid(connector, &sdvo->ddc); | 1299 | return drm_get_edid(connector, &sdvo->ddc); |
1296 | } | 1300 | } |
1297 | 1301 | ||
1298 | static struct drm_connector * | ||
1299 | intel_find_analog_connector(struct drm_device *dev) | ||
1300 | { | ||
1301 | struct drm_connector *connector; | ||
1302 | struct intel_sdvo *encoder; | ||
1303 | |||
1304 | list_for_each_entry(encoder, | ||
1305 | &dev->mode_config.encoder_list, | ||
1306 | base.base.head) { | ||
1307 | if (encoder->base.type == INTEL_OUTPUT_ANALOG) { | ||
1308 | list_for_each_entry(connector, | ||
1309 | &dev->mode_config.connector_list, | ||
1310 | head) { | ||
1311 | if (&encoder->base == | ||
1312 | intel_attached_encoder(connector)) | ||
1313 | return connector; | ||
1314 | } | ||
1315 | } | ||
1316 | } | ||
1317 | |||
1318 | return NULL; | ||
1319 | } | ||
1320 | |||
1321 | static int | ||
1322 | intel_analog_is_connected(struct drm_device *dev) | ||
1323 | { | ||
1324 | struct drm_connector *analog_connector; | ||
1325 | |||
1326 | analog_connector = intel_find_analog_connector(dev); | ||
1327 | if (!analog_connector) | ||
1328 | return false; | ||
1329 | |||
1330 | if (analog_connector->funcs->detect(analog_connector, false) == | ||
1331 | connector_status_disconnected) | ||
1332 | return false; | ||
1333 | |||
1334 | return true; | ||
1335 | } | ||
1336 | |||
1337 | /* Mac mini hack -- use the same DDC as the analog connector */ | 1302 | /* Mac mini hack -- use the same DDC as the analog connector */ |
1338 | static struct edid * | 1303 | static struct edid * |
1339 | intel_sdvo_get_analog_edid(struct drm_connector *connector) | 1304 | intel_sdvo_get_analog_edid(struct drm_connector *connector) |
1340 | { | 1305 | { |
1341 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1306 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1342 | 1307 | ||
1343 | if (!intel_analog_is_connected(connector->dev)) | 1308 | return drm_get_edid(connector, |
1344 | return NULL; | 1309 | &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); |
1345 | |||
1346 | return drm_get_edid(connector, &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); | ||
1347 | } | 1310 | } |
1348 | 1311 | ||
1349 | enum drm_connector_status | 1312 | enum drm_connector_status |
@@ -1388,8 +1351,10 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
1388 | /* DDC bus is shared, match EDID to connector type */ | 1351 | /* DDC bus is shared, match EDID to connector type */ |
1389 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { | 1352 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { |
1390 | status = connector_status_connected; | 1353 | status = connector_status_connected; |
1391 | intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid); | 1354 | if (intel_sdvo->is_hdmi) { |
1392 | intel_sdvo->has_audio = drm_detect_monitor_audio(edid); | 1355 | intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); |
1356 | intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); | ||
1357 | } | ||
1393 | } | 1358 | } |
1394 | connector->display_info.raw_edid = NULL; | 1359 | connector->display_info.raw_edid = NULL; |
1395 | kfree(edid); | 1360 | kfree(edid); |
@@ -1398,7 +1363,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
1398 | if (status == connector_status_connected) { | 1363 | if (status == connector_status_connected) { |
1399 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); | 1364 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1400 | if (intel_sdvo_connector->force_audio) | 1365 | if (intel_sdvo_connector->force_audio) |
1401 | intel_sdvo->has_audio = intel_sdvo_connector->force_audio > 0; | 1366 | intel_sdvo->has_hdmi_audio = intel_sdvo_connector->force_audio > 0; |
1402 | } | 1367 | } |
1403 | 1368 | ||
1404 | return status; | 1369 | return status; |
@@ -1415,10 +1380,12 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) | |||
1415 | if (!intel_sdvo_write_cmd(intel_sdvo, | 1380 | if (!intel_sdvo_write_cmd(intel_sdvo, |
1416 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0)) | 1381 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0)) |
1417 | return connector_status_unknown; | 1382 | return connector_status_unknown; |
1418 | if (intel_sdvo->is_tv) { | 1383 | |
1419 | /* add 30ms delay when the output type is SDVO-TV */ | 1384 | /* add 30ms delay when the output type might be TV */ |
1385 | if (intel_sdvo->caps.output_flags & | ||
1386 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_CVBS0)) | ||
1420 | mdelay(30); | 1387 | mdelay(30); |
1421 | } | 1388 | |
1422 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) | 1389 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) |
1423 | return connector_status_unknown; | 1390 | return connector_status_unknown; |
1424 | 1391 | ||
@@ -1472,8 +1439,10 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | |||
1472 | edid = intel_sdvo_get_analog_edid(connector); | 1439 | edid = intel_sdvo_get_analog_edid(connector); |
1473 | 1440 | ||
1474 | if (edid != NULL) { | 1441 | if (edid != NULL) { |
1475 | drm_mode_connector_update_edid_property(connector, edid); | 1442 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { |
1476 | drm_add_edid_modes(connector, edid); | 1443 | drm_mode_connector_update_edid_property(connector, edid); |
1444 | drm_add_edid_modes(connector, edid); | ||
1445 | } | ||
1477 | connector->display_info.raw_edid = NULL; | 1446 | connector->display_info.raw_edid = NULL; |
1478 | kfree(edid); | 1447 | kfree(edid); |
1479 | } | 1448 | } |
@@ -1713,12 +1682,12 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
1713 | 1682 | ||
1714 | intel_sdvo_connector->force_audio = val; | 1683 | intel_sdvo_connector->force_audio = val; |
1715 | 1684 | ||
1716 | if (val > 0 && intel_sdvo->has_audio) | 1685 | if (val > 0 && intel_sdvo->has_hdmi_audio) |
1717 | return 0; | 1686 | return 0; |
1718 | if (val < 0 && !intel_sdvo->has_audio) | 1687 | if (val < 0 && !intel_sdvo->has_hdmi_audio) |
1719 | return 0; | 1688 | return 0; |
1720 | 1689 | ||
1721 | intel_sdvo->has_audio = val > 0; | 1690 | intel_sdvo->has_hdmi_audio = val > 0; |
1722 | goto done; | 1691 | goto done; |
1723 | } | 1692 | } |
1724 | 1693 | ||
@@ -1942,9 +1911,12 @@ intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv, | |||
1942 | speed = mapping->i2c_speed; | 1911 | speed = mapping->i2c_speed; |
1943 | } | 1912 | } |
1944 | 1913 | ||
1945 | sdvo->i2c = &dev_priv->gmbus[pin].adapter; | 1914 | if (pin < GMBUS_NUM_PORTS) { |
1946 | intel_gmbus_set_speed(sdvo->i2c, speed); | 1915 | sdvo->i2c = &dev_priv->gmbus[pin].adapter; |
1947 | intel_gmbus_force_bit(sdvo->i2c, true); | 1916 | intel_gmbus_set_speed(sdvo->i2c, speed); |
1917 | intel_gmbus_force_bit(sdvo->i2c, true); | ||
1918 | } else | ||
1919 | sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter; | ||
1948 | } | 1920 | } |
1949 | 1921 | ||
1950 | static bool | 1922 | static bool |
@@ -2070,6 +2042,8 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) | |||
2070 | intel_sdvo_set_colorimetry(intel_sdvo, | 2042 | intel_sdvo_set_colorimetry(intel_sdvo, |
2071 | SDVO_COLORIMETRY_RGB256); | 2043 | SDVO_COLORIMETRY_RGB256); |
2072 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | 2044 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
2045 | |||
2046 | intel_sdvo_add_hdmi_properties(intel_sdvo_connector); | ||
2073 | intel_sdvo->is_hdmi = true; | 2047 | intel_sdvo->is_hdmi = true; |
2074 | } | 2048 | } |
2075 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2049 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
@@ -2077,8 +2051,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) | |||
2077 | 2051 | ||
2078 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); | 2052 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
2079 | 2053 | ||
2080 | intel_sdvo_add_hdmi_properties(intel_sdvo_connector); | ||
2081 | |||
2082 | return true; | 2054 | return true; |
2083 | } | 2055 | } |
2084 | 2056 | ||
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 2f768198931..93206e4eaa6 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1245,10 +1245,11 @@ intel_tv_detect_type (struct intel_tv *intel_tv) | |||
1245 | int type; | 1245 | int type; |
1246 | 1246 | ||
1247 | /* Disable TV interrupts around load detect or we'll recurse */ | 1247 | /* Disable TV interrupts around load detect or we'll recurse */ |
1248 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 1248 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
1249 | i915_disable_pipestat(dev_priv, 0, PIPE_HOTPLUG_INTERRUPT_ENABLE | | 1249 | i915_disable_pipestat(dev_priv, 0, |
1250 | PIPE_HOTPLUG_INTERRUPT_ENABLE | | ||
1250 | PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); | 1251 | PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); |
1251 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | 1252 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
1252 | 1253 | ||
1253 | save_tv_dac = tv_dac = I915_READ(TV_DAC); | 1254 | save_tv_dac = tv_dac = I915_READ(TV_DAC); |
1254 | save_tv_ctl = tv_ctl = I915_READ(TV_CTL); | 1255 | save_tv_ctl = tv_ctl = I915_READ(TV_CTL); |
@@ -1301,10 +1302,11 @@ intel_tv_detect_type (struct intel_tv *intel_tv) | |||
1301 | I915_WRITE(TV_CTL, save_tv_ctl); | 1302 | I915_WRITE(TV_CTL, save_tv_ctl); |
1302 | 1303 | ||
1303 | /* Restore interrupt config */ | 1304 | /* Restore interrupt config */ |
1304 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 1305 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
1305 | i915_enable_pipestat(dev_priv, 0, PIPE_HOTPLUG_INTERRUPT_ENABLE | | 1306 | i915_enable_pipestat(dev_priv, 0, |
1307 | PIPE_HOTPLUG_INTERRUPT_ENABLE | | ||
1306 | PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); | 1308 | PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); |
1307 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | 1309 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
1308 | 1310 | ||
1309 | return type; | 1311 | return type; |
1310 | } | 1312 | } |
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 9b0773b75e8..258fa5e7a2d 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -112,6 +112,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, | |||
112 | base += 3; | 112 | base += 3; |
113 | break; | 113 | break; |
114 | case ATOM_IIO_WRITE: | 114 | case ATOM_IIO_WRITE: |
115 | (void)ctx->card->ioreg_read(ctx->card, CU16(base + 1)); | ||
115 | ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp); | 116 | ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp); |
116 | base += 3; | 117 | base += 3; |
117 | break; | 118 | break; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 53bfe3afb0f..c6a37e036f1 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -1198,8 +1198,10 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc | |||
1198 | mc->vram_end, mc->real_vram_size >> 20); | 1198 | mc->vram_end, mc->real_vram_size >> 20); |
1199 | } else { | 1199 | } else { |
1200 | u64 base = 0; | 1200 | u64 base = 0; |
1201 | if (rdev->flags & RADEON_IS_IGP) | 1201 | if (rdev->flags & RADEON_IS_IGP) { |
1202 | base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; | 1202 | base = RREG32(MC_VM_FB_LOCATION) & 0xFFFF; |
1203 | base <<= 24; | ||
1204 | } | ||
1203 | radeon_vram_location(rdev, &rdev->mc, base); | 1205 | radeon_vram_location(rdev, &rdev->mc, base); |
1204 | rdev->mc.gtt_base_align = 0; | 1206 | rdev->mc.gtt_base_align = 0; |
1205 | radeon_gtt_location(rdev, mc); | 1207 | radeon_gtt_location(rdev, mc); |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 9bebac1ec00..0f90fc3482c 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -315,7 +315,7 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
315 | if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { | 315 | if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { |
316 | /* the initial DDX does bad things with the CB size occasionally */ | 316 | /* the initial DDX does bad things with the CB size occasionally */ |
317 | /* it rounds up height too far for slice tile max but the BO is smaller */ | 317 | /* it rounds up height too far for slice tile max but the BO is smaller */ |
318 | tmp = (height - 7) * pitch * bpe; | 318 | tmp = (height - 7) * 8 * bpe; |
319 | if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { | 319 | if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { |
320 | dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i])); | 320 | dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i])); |
321 | return -EINVAL; | 321 | return -EINVAL; |
diff --git a/drivers/gpu/drm/radeon/r600_reg.h b/drivers/gpu/drm/radeon/r600_reg.h index d84612ae47e..33cda016b08 100644 --- a/drivers/gpu/drm/radeon/r600_reg.h +++ b/drivers/gpu/drm/radeon/r600_reg.h | |||
@@ -86,6 +86,7 @@ | |||
86 | #define R600_HDP_NONSURFACE_BASE 0x2c04 | 86 | #define R600_HDP_NONSURFACE_BASE 0x2c04 |
87 | 87 | ||
88 | #define R600_BUS_CNTL 0x5420 | 88 | #define R600_BUS_CNTL 0x5420 |
89 | # define R600_BIOS_ROM_DIS (1 << 1) | ||
89 | #define R600_CONFIG_CNTL 0x5424 | 90 | #define R600_CONFIG_CNTL 0x5424 |
90 | #define R600_CONFIG_MEMSIZE 0x5428 | 91 | #define R600_CONFIG_MEMSIZE 0x5428 |
91 | #define R600_CONFIG_F0_BASE 0x542C | 92 | #define R600_CONFIG_F0_BASE 0x542C |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index d6c611eee20..45bc750e9ae 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -98,6 +98,14 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev | |||
98 | } | 98 | } |
99 | } | 99 | } |
100 | 100 | ||
101 | /* some DCE3 boards have bad data for this entry */ | ||
102 | if (ASIC_IS_DCE3(rdev)) { | ||
103 | if ((i == 4) && | ||
104 | (gpio->usClkMaskRegisterIndex == 0x1fda) && | ||
105 | (gpio->sucI2cId.ucAccess == 0x94)) | ||
106 | gpio->sucI2cId.ucAccess = 0x14; | ||
107 | } | ||
108 | |||
101 | if (gpio->sucI2cId.ucAccess == id) { | 109 | if (gpio->sucI2cId.ucAccess == id) { |
102 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | 110 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; |
103 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | 111 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; |
@@ -174,6 +182,14 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) | |||
174 | } | 182 | } |
175 | } | 183 | } |
176 | 184 | ||
185 | /* some DCE3 boards have bad data for this entry */ | ||
186 | if (ASIC_IS_DCE3(rdev)) { | ||
187 | if ((i == 4) && | ||
188 | (gpio->usClkMaskRegisterIndex == 0x1fda) && | ||
189 | (gpio->sucI2cId.ucAccess == 0x94)) | ||
190 | gpio->sucI2cId.ucAccess = 0x14; | ||
191 | } | ||
192 | |||
177 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | 193 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; |
178 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | 194 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; |
179 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; | 195 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; |
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 654787ec43f..8f2c7b50dcf 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c | |||
@@ -130,6 +130,7 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev) | |||
130 | } | 130 | } |
131 | return true; | 131 | return true; |
132 | } | 132 | } |
133 | |||
133 | static bool r700_read_disabled_bios(struct radeon_device *rdev) | 134 | static bool r700_read_disabled_bios(struct radeon_device *rdev) |
134 | { | 135 | { |
135 | uint32_t viph_control; | 136 | uint32_t viph_control; |
@@ -143,7 +144,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev) | |||
143 | bool r; | 144 | bool r; |
144 | 145 | ||
145 | viph_control = RREG32(RADEON_VIPH_CONTROL); | 146 | viph_control = RREG32(RADEON_VIPH_CONTROL); |
146 | bus_cntl = RREG32(RADEON_BUS_CNTL); | 147 | bus_cntl = RREG32(R600_BUS_CNTL); |
147 | d1vga_control = RREG32(AVIVO_D1VGA_CONTROL); | 148 | d1vga_control = RREG32(AVIVO_D1VGA_CONTROL); |
148 | d2vga_control = RREG32(AVIVO_D2VGA_CONTROL); | 149 | d2vga_control = RREG32(AVIVO_D2VGA_CONTROL); |
149 | vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL); | 150 | vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL); |
@@ -152,7 +153,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev) | |||
152 | /* disable VIP */ | 153 | /* disable VIP */ |
153 | WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); | 154 | WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); |
154 | /* enable the rom */ | 155 | /* enable the rom */ |
155 | WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM)); | 156 | WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS)); |
156 | /* Disable VGA mode */ | 157 | /* Disable VGA mode */ |
157 | WREG32(AVIVO_D1VGA_CONTROL, | 158 | WREG32(AVIVO_D1VGA_CONTROL, |
158 | (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | | 159 | (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | |
@@ -191,7 +192,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev) | |||
191 | cg_spll_status = RREG32(R600_CG_SPLL_STATUS); | 192 | cg_spll_status = RREG32(R600_CG_SPLL_STATUS); |
192 | } | 193 | } |
193 | WREG32(RADEON_VIPH_CONTROL, viph_control); | 194 | WREG32(RADEON_VIPH_CONTROL, viph_control); |
194 | WREG32(RADEON_BUS_CNTL, bus_cntl); | 195 | WREG32(R600_BUS_CNTL, bus_cntl); |
195 | WREG32(AVIVO_D1VGA_CONTROL, d1vga_control); | 196 | WREG32(AVIVO_D1VGA_CONTROL, d1vga_control); |
196 | WREG32(AVIVO_D2VGA_CONTROL, d2vga_control); | 197 | WREG32(AVIVO_D2VGA_CONTROL, d2vga_control); |
197 | WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); | 198 | WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); |
@@ -216,7 +217,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev) | |||
216 | bool r; | 217 | bool r; |
217 | 218 | ||
218 | viph_control = RREG32(RADEON_VIPH_CONTROL); | 219 | viph_control = RREG32(RADEON_VIPH_CONTROL); |
219 | bus_cntl = RREG32(RADEON_BUS_CNTL); | 220 | bus_cntl = RREG32(R600_BUS_CNTL); |
220 | d1vga_control = RREG32(AVIVO_D1VGA_CONTROL); | 221 | d1vga_control = RREG32(AVIVO_D1VGA_CONTROL); |
221 | d2vga_control = RREG32(AVIVO_D2VGA_CONTROL); | 222 | d2vga_control = RREG32(AVIVO_D2VGA_CONTROL); |
222 | vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL); | 223 | vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL); |
@@ -231,7 +232,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev) | |||
231 | /* disable VIP */ | 232 | /* disable VIP */ |
232 | WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); | 233 | WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); |
233 | /* enable the rom */ | 234 | /* enable the rom */ |
234 | WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM)); | 235 | WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS)); |
235 | /* Disable VGA mode */ | 236 | /* Disable VGA mode */ |
236 | WREG32(AVIVO_D1VGA_CONTROL, | 237 | WREG32(AVIVO_D1VGA_CONTROL, |
237 | (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | | 238 | (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | |
@@ -262,7 +263,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev) | |||
262 | 263 | ||
263 | /* restore regs */ | 264 | /* restore regs */ |
264 | WREG32(RADEON_VIPH_CONTROL, viph_control); | 265 | WREG32(RADEON_VIPH_CONTROL, viph_control); |
265 | WREG32(RADEON_BUS_CNTL, bus_cntl); | 266 | WREG32(R600_BUS_CNTL, bus_cntl); |
266 | WREG32(AVIVO_D1VGA_CONTROL, d1vga_control); | 267 | WREG32(AVIVO_D1VGA_CONTROL, d1vga_control); |
267 | WREG32(AVIVO_D2VGA_CONTROL, d2vga_control); | 268 | WREG32(AVIVO_D2VGA_CONTROL, d2vga_control); |
268 | WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); | 269 | WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 111a844c1ec..591fcae8f22 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -730,7 +730,7 @@ void radeon_combios_i2c_init(struct radeon_device *rdev) | |||
730 | clk = RBIOS8(offset + 3 + (i * 5) + 3); | 730 | clk = RBIOS8(offset + 3 + (i * 5) + 3); |
731 | data = RBIOS8(offset + 3 + (i * 5) + 4); | 731 | data = RBIOS8(offset + 3 + (i * 5) + 4); |
732 | i2c = combios_setup_i2c_bus(rdev, DDC_MONID, | 732 | i2c = combios_setup_i2c_bus(rdev, DDC_MONID, |
733 | clk, data); | 733 | (1 << clk), (1 << data)); |
734 | rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); | 734 | rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); |
735 | break; | 735 | break; |
736 | } | 736 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index f3ba066ded2..5b00f92a50a 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -1178,6 +1178,8 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1178 | /* no HPD on analog connectors */ | 1178 | /* no HPD on analog connectors */ |
1179 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | 1179 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; |
1180 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | 1180 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
1181 | connector->interlace_allowed = true; | ||
1182 | connector->doublescan_allowed = true; | ||
1181 | break; | 1183 | break; |
1182 | case DRM_MODE_CONNECTOR_DVIA: | 1184 | case DRM_MODE_CONNECTOR_DVIA: |
1183 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); | 1185 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
@@ -1193,6 +1195,8 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1193 | 1); | 1195 | 1); |
1194 | /* no HPD on analog connectors */ | 1196 | /* no HPD on analog connectors */ |
1195 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | 1197 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; |
1198 | connector->interlace_allowed = true; | ||
1199 | connector->doublescan_allowed = true; | ||
1196 | break; | 1200 | break; |
1197 | case DRM_MODE_CONNECTOR_DVII: | 1201 | case DRM_MODE_CONNECTOR_DVII: |
1198 | case DRM_MODE_CONNECTOR_DVID: | 1202 | case DRM_MODE_CONNECTOR_DVID: |
@@ -1229,6 +1233,11 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1229 | rdev->mode_info.load_detect_property, | 1233 | rdev->mode_info.load_detect_property, |
1230 | 1); | 1234 | 1); |
1231 | } | 1235 | } |
1236 | connector->interlace_allowed = true; | ||
1237 | if (connector_type == DRM_MODE_CONNECTOR_DVII) | ||
1238 | connector->doublescan_allowed = true; | ||
1239 | else | ||
1240 | connector->doublescan_allowed = false; | ||
1232 | break; | 1241 | break; |
1233 | case DRM_MODE_CONNECTOR_HDMIA: | 1242 | case DRM_MODE_CONNECTOR_HDMIA: |
1234 | case DRM_MODE_CONNECTOR_HDMIB: | 1243 | case DRM_MODE_CONNECTOR_HDMIB: |
@@ -1259,6 +1268,11 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1259 | 0); | 1268 | 0); |
1260 | } | 1269 | } |
1261 | subpixel_order = SubPixelHorizontalRGB; | 1270 | subpixel_order = SubPixelHorizontalRGB; |
1271 | connector->interlace_allowed = true; | ||
1272 | if (connector_type == DRM_MODE_CONNECTOR_HDMIB) | ||
1273 | connector->doublescan_allowed = true; | ||
1274 | else | ||
1275 | connector->doublescan_allowed = false; | ||
1262 | break; | 1276 | break; |
1263 | case DRM_MODE_CONNECTOR_DisplayPort: | 1277 | case DRM_MODE_CONNECTOR_DisplayPort: |
1264 | case DRM_MODE_CONNECTOR_eDP: | 1278 | case DRM_MODE_CONNECTOR_eDP: |
@@ -1296,6 +1310,9 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1296 | rdev->mode_info.underscan_vborder_property, | 1310 | rdev->mode_info.underscan_vborder_property, |
1297 | 0); | 1311 | 0); |
1298 | } | 1312 | } |
1313 | connector->interlace_allowed = true; | ||
1314 | /* in theory with a DP to VGA converter... */ | ||
1315 | connector->doublescan_allowed = false; | ||
1299 | break; | 1316 | break; |
1300 | case DRM_MODE_CONNECTOR_SVIDEO: | 1317 | case DRM_MODE_CONNECTOR_SVIDEO: |
1301 | case DRM_MODE_CONNECTOR_Composite: | 1318 | case DRM_MODE_CONNECTOR_Composite: |
@@ -1311,6 +1328,8 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1311 | radeon_atombios_get_tv_info(rdev)); | 1328 | radeon_atombios_get_tv_info(rdev)); |
1312 | /* no HPD on analog connectors */ | 1329 | /* no HPD on analog connectors */ |
1313 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | 1330 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; |
1331 | connector->interlace_allowed = false; | ||
1332 | connector->doublescan_allowed = false; | ||
1314 | break; | 1333 | break; |
1315 | case DRM_MODE_CONNECTOR_LVDS: | 1334 | case DRM_MODE_CONNECTOR_LVDS: |
1316 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1335 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
@@ -1329,6 +1348,8 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1329 | dev->mode_config.scaling_mode_property, | 1348 | dev->mode_config.scaling_mode_property, |
1330 | DRM_MODE_SCALE_FULLSCREEN); | 1349 | DRM_MODE_SCALE_FULLSCREEN); |
1331 | subpixel_order = SubPixelHorizontalRGB; | 1350 | subpixel_order = SubPixelHorizontalRGB; |
1351 | connector->interlace_allowed = false; | ||
1352 | connector->doublescan_allowed = false; | ||
1332 | break; | 1353 | break; |
1333 | } | 1354 | } |
1334 | 1355 | ||
@@ -1406,6 +1427,8 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1406 | /* no HPD on analog connectors */ | 1427 | /* no HPD on analog connectors */ |
1407 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | 1428 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; |
1408 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | 1429 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
1430 | connector->interlace_allowed = true; | ||
1431 | connector->doublescan_allowed = true; | ||
1409 | break; | 1432 | break; |
1410 | case DRM_MODE_CONNECTOR_DVIA: | 1433 | case DRM_MODE_CONNECTOR_DVIA: |
1411 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); | 1434 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
@@ -1421,6 +1444,8 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1421 | 1); | 1444 | 1); |
1422 | /* no HPD on analog connectors */ | 1445 | /* no HPD on analog connectors */ |
1423 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | 1446 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; |
1447 | connector->interlace_allowed = true; | ||
1448 | connector->doublescan_allowed = true; | ||
1424 | break; | 1449 | break; |
1425 | case DRM_MODE_CONNECTOR_DVII: | 1450 | case DRM_MODE_CONNECTOR_DVII: |
1426 | case DRM_MODE_CONNECTOR_DVID: | 1451 | case DRM_MODE_CONNECTOR_DVID: |
@@ -1438,6 +1463,11 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1438 | 1); | 1463 | 1); |
1439 | } | 1464 | } |
1440 | subpixel_order = SubPixelHorizontalRGB; | 1465 | subpixel_order = SubPixelHorizontalRGB; |
1466 | connector->interlace_allowed = true; | ||
1467 | if (connector_type == DRM_MODE_CONNECTOR_DVII) | ||
1468 | connector->doublescan_allowed = true; | ||
1469 | else | ||
1470 | connector->doublescan_allowed = false; | ||
1441 | break; | 1471 | break; |
1442 | case DRM_MODE_CONNECTOR_SVIDEO: | 1472 | case DRM_MODE_CONNECTOR_SVIDEO: |
1443 | case DRM_MODE_CONNECTOR_Composite: | 1473 | case DRM_MODE_CONNECTOR_Composite: |
@@ -1460,6 +1490,8 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1460 | radeon_combios_get_tv_info(rdev)); | 1490 | radeon_combios_get_tv_info(rdev)); |
1461 | /* no HPD on analog connectors */ | 1491 | /* no HPD on analog connectors */ |
1462 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | 1492 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; |
1493 | connector->interlace_allowed = false; | ||
1494 | connector->doublescan_allowed = false; | ||
1463 | break; | 1495 | break; |
1464 | case DRM_MODE_CONNECTOR_LVDS: | 1496 | case DRM_MODE_CONNECTOR_LVDS: |
1465 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); | 1497 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); |
@@ -1473,6 +1505,8 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1473 | dev->mode_config.scaling_mode_property, | 1505 | dev->mode_config.scaling_mode_property, |
1474 | DRM_MODE_SCALE_FULLSCREEN); | 1506 | DRM_MODE_SCALE_FULLSCREEN); |
1475 | subpixel_order = SubPixelHorizontalRGB; | 1507 | subpixel_order = SubPixelHorizontalRGB; |
1508 | connector->interlace_allowed = false; | ||
1509 | connector->doublescan_allowed = false; | ||
1476 | break; | 1510 | break; |
1477 | } | 1511 | } |
1478 | 1512 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 3952cf3d0ee..86660cb425a 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -287,7 +287,7 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 | |||
287 | mc->mc_vram_size = mc->aper_size; | 287 | mc->mc_vram_size = mc->aper_size; |
288 | } | 288 | } |
289 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | 289 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; |
290 | dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", | 290 | dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n", |
291 | mc->mc_vram_size >> 20, mc->vram_start, | 291 | mc->mc_vram_size >> 20, mc->vram_start, |
292 | mc->vram_end, mc->real_vram_size >> 20); | 292 | mc->vram_end, mc->real_vram_size >> 20); |
293 | } | 293 | } |
@@ -324,7 +324,7 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | |||
324 | mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align; | 324 | mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align; |
325 | } | 325 | } |
326 | mc->gtt_end = mc->gtt_start + mc->gtt_size - 1; | 326 | mc->gtt_end = mc->gtt_start + mc->gtt_size - 1; |
327 | dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n", | 327 | dev_info(rdev->dev, "GTT: %lluM 0x%016llX - 0x%016llX\n", |
328 | mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end); | 328 | mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end); |
329 | } | 329 | } |
330 | 330 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 8bdf0ba2983..7d6b8e88f74 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -70,7 +70,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) | |||
70 | u32 c = 0; | 70 | u32 c = 0; |
71 | 71 | ||
72 | rbo->placement.fpfn = 0; | 72 | rbo->placement.fpfn = 0; |
73 | rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT; | 73 | rbo->placement.lpfn = 0; |
74 | rbo->placement.placement = rbo->placements; | 74 | rbo->placement.placement = rbo->placements; |
75 | rbo->placement.busy_placement = rbo->placements; | 75 | rbo->placement.busy_placement = rbo->placements; |
76 | if (domain & RADEON_GEM_DOMAIN_VRAM) | 76 | if (domain & RADEON_GEM_DOMAIN_VRAM) |
@@ -92,7 +92,8 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, | |||
92 | { | 92 | { |
93 | struct radeon_bo *bo; | 93 | struct radeon_bo *bo; |
94 | enum ttm_bo_type type; | 94 | enum ttm_bo_type type; |
95 | int page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; | 95 | unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; |
96 | unsigned long max_size = 0; | ||
96 | int r; | 97 | int r; |
97 | 98 | ||
98 | if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { | 99 | if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { |
@@ -105,6 +106,14 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, | |||
105 | } | 106 | } |
106 | *bo_ptr = NULL; | 107 | *bo_ptr = NULL; |
107 | 108 | ||
109 | /* maximun bo size is the minimun btw visible vram and gtt size */ | ||
110 | max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size); | ||
111 | if ((page_align << PAGE_SHIFT) >= max_size) { | ||
112 | printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n", | ||
113 | __func__, __LINE__, page_align >> (20 - PAGE_SHIFT), max_size >> 20); | ||
114 | return -ENOMEM; | ||
115 | } | ||
116 | |||
108 | retry: | 117 | retry: |
109 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); | 118 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); |
110 | if (bo == NULL) | 119 | if (bo == NULL) |