diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 250 |
1 files changed, 171 insertions, 79 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index ecbc5c5dbbbc..2346b920bd86 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
| @@ -45,7 +45,7 @@ struct pipe_control { | |||
| 45 | 45 | ||
| 46 | static inline int ring_space(struct intel_ring_buffer *ring) | 46 | static inline int ring_space(struct intel_ring_buffer *ring) |
| 47 | { | 47 | { |
| 48 | int space = (ring->head & HEAD_ADDR) - (ring->tail + 8); | 48 | int space = (ring->head & HEAD_ADDR) - (ring->tail + I915_RING_FREE_SPACE); |
| 49 | if (space < 0) | 49 | if (space < 0) |
| 50 | space += ring->size; | 50 | space += ring->size; |
| 51 | return space; | 51 | return space; |
| @@ -245,7 +245,7 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring, | |||
| 245 | /* | 245 | /* |
| 246 | * TLB invalidate requires a post-sync write. | 246 | * TLB invalidate requires a post-sync write. |
| 247 | */ | 247 | */ |
| 248 | flags |= PIPE_CONTROL_QW_WRITE; | 248 | flags |= PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_CS_STALL; |
| 249 | } | 249 | } |
| 250 | 250 | ||
| 251 | ret = intel_ring_begin(ring, 4); | 251 | ret = intel_ring_begin(ring, 4); |
| @@ -555,15 +555,11 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring) | |||
| 555 | 555 | ||
| 556 | static void | 556 | static void |
| 557 | update_mboxes(struct intel_ring_buffer *ring, | 557 | update_mboxes(struct intel_ring_buffer *ring, |
| 558 | u32 seqno, | 558 | u32 mmio_offset) |
| 559 | u32 mmio_offset) | ||
| 560 | { | 559 | { |
| 561 | intel_ring_emit(ring, MI_SEMAPHORE_MBOX | | 560 | intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); |
| 562 | MI_SEMAPHORE_GLOBAL_GTT | | ||
| 563 | MI_SEMAPHORE_REGISTER | | ||
| 564 | MI_SEMAPHORE_UPDATE); | ||
| 565 | intel_ring_emit(ring, seqno); | ||
| 566 | intel_ring_emit(ring, mmio_offset); | 561 | intel_ring_emit(ring, mmio_offset); |
| 562 | intel_ring_emit(ring, ring->outstanding_lazy_request); | ||
| 567 | } | 563 | } |
| 568 | 564 | ||
| 569 | /** | 565 | /** |
| @@ -576,8 +572,7 @@ update_mboxes(struct intel_ring_buffer *ring, | |||
| 576 | * This acts like a signal in the canonical semaphore. | 572 | * This acts like a signal in the canonical semaphore. |
| 577 | */ | 573 | */ |
| 578 | static int | 574 | static int |
| 579 | gen6_add_request(struct intel_ring_buffer *ring, | 575 | gen6_add_request(struct intel_ring_buffer *ring) |
| 580 | u32 *seqno) | ||
| 581 | { | 576 | { |
| 582 | u32 mbox1_reg; | 577 | u32 mbox1_reg; |
| 583 | u32 mbox2_reg; | 578 | u32 mbox2_reg; |
| @@ -590,13 +585,11 @@ gen6_add_request(struct intel_ring_buffer *ring, | |||
| 590 | mbox1_reg = ring->signal_mbox[0]; | 585 | mbox1_reg = ring->signal_mbox[0]; |
| 591 | mbox2_reg = ring->signal_mbox[1]; | 586 | mbox2_reg = ring->signal_mbox[1]; |
| 592 | 587 | ||
| 593 | *seqno = i915_gem_next_request_seqno(ring); | 588 | update_mboxes(ring, mbox1_reg); |
| 594 | 589 | update_mboxes(ring, mbox2_reg); | |
| 595 | update_mboxes(ring, *seqno, mbox1_reg); | ||
| 596 | update_mboxes(ring, *seqno, mbox2_reg); | ||
| 597 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); | 590 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); |
| 598 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | 591 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
| 599 | intel_ring_emit(ring, *seqno); | 592 | intel_ring_emit(ring, ring->outstanding_lazy_request); |
| 600 | intel_ring_emit(ring, MI_USER_INTERRUPT); | 593 | intel_ring_emit(ring, MI_USER_INTERRUPT); |
| 601 | intel_ring_advance(ring); | 594 | intel_ring_advance(ring); |
| 602 | 595 | ||
| @@ -653,10 +646,8 @@ do { \ | |||
| 653 | } while (0) | 646 | } while (0) |
| 654 | 647 | ||
| 655 | static int | 648 | static int |
| 656 | pc_render_add_request(struct intel_ring_buffer *ring, | 649 | pc_render_add_request(struct intel_ring_buffer *ring) |
| 657 | u32 *result) | ||
| 658 | { | 650 | { |
| 659 | u32 seqno = i915_gem_next_request_seqno(ring); | ||
| 660 | struct pipe_control *pc = ring->private; | 651 | struct pipe_control *pc = ring->private; |
| 661 | u32 scratch_addr = pc->gtt_offset + 128; | 652 | u32 scratch_addr = pc->gtt_offset + 128; |
| 662 | int ret; | 653 | int ret; |
| @@ -677,7 +668,7 @@ pc_render_add_request(struct intel_ring_buffer *ring, | |||
| 677 | PIPE_CONTROL_WRITE_FLUSH | | 668 | PIPE_CONTROL_WRITE_FLUSH | |
| 678 | PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE); | 669 | PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE); |
| 679 | intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); | 670 | intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); |
| 680 | intel_ring_emit(ring, seqno); | 671 | intel_ring_emit(ring, ring->outstanding_lazy_request); |
| 681 | intel_ring_emit(ring, 0); | 672 | intel_ring_emit(ring, 0); |
| 682 | PIPE_CONTROL_FLUSH(ring, scratch_addr); | 673 | PIPE_CONTROL_FLUSH(ring, scratch_addr); |
| 683 | scratch_addr += 128; /* write to separate cachelines */ | 674 | scratch_addr += 128; /* write to separate cachelines */ |
| @@ -696,11 +687,10 @@ pc_render_add_request(struct intel_ring_buffer *ring, | |||
| 696 | PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | | 687 | PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | |
| 697 | PIPE_CONTROL_NOTIFY); | 688 | PIPE_CONTROL_NOTIFY); |
| 698 | intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); | 689 | intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); |
| 699 | intel_ring_emit(ring, seqno); | 690 | intel_ring_emit(ring, ring->outstanding_lazy_request); |
| 700 | intel_ring_emit(ring, 0); | 691 | intel_ring_emit(ring, 0); |
| 701 | intel_ring_advance(ring); | 692 | intel_ring_advance(ring); |
| 702 | 693 | ||
| 703 | *result = seqno; | ||
| 704 | return 0; | 694 | return 0; |
| 705 | } | 695 | } |
| 706 | 696 | ||
| @@ -888,25 +878,20 @@ bsd_ring_flush(struct intel_ring_buffer *ring, | |||
| 888 | } | 878 | } |
| 889 | 879 | ||
| 890 | static int | 880 | static int |
| 891 | i9xx_add_request(struct intel_ring_buffer *ring, | 881 | i9xx_add_request(struct intel_ring_buffer *ring) |
| 892 | u32 *result) | ||
| 893 | { | 882 | { |
| 894 | u32 seqno; | ||
| 895 | int ret; | 883 | int ret; |
| 896 | 884 | ||
| 897 | ret = intel_ring_begin(ring, 4); | 885 | ret = intel_ring_begin(ring, 4); |
| 898 | if (ret) | 886 | if (ret) |
| 899 | return ret; | 887 | return ret; |
| 900 | 888 | ||
| 901 | seqno = i915_gem_next_request_seqno(ring); | ||
| 902 | |||
| 903 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); | 889 | intel_ring_emit(ring, MI_STORE_DWORD_INDEX); |
| 904 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | 890 | intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
| 905 | intel_ring_emit(ring, seqno); | 891 | intel_ring_emit(ring, ring->outstanding_lazy_request); |
| 906 | intel_ring_emit(ring, MI_USER_INTERRUPT); | 892 | intel_ring_emit(ring, MI_USER_INTERRUPT); |
| 907 | intel_ring_advance(ring); | 893 | intel_ring_advance(ring); |
| 908 | 894 | ||
| 909 | *result = seqno; | ||
| 910 | return 0; | 895 | return 0; |
| 911 | } | 896 | } |
| 912 | 897 | ||
| @@ -964,7 +949,9 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring) | |||
| 964 | } | 949 | } |
| 965 | 950 | ||
| 966 | static int | 951 | static int |
| 967 | i965_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length) | 952 | i965_dispatch_execbuffer(struct intel_ring_buffer *ring, |
| 953 | u32 offset, u32 length, | ||
| 954 | unsigned flags) | ||
| 968 | { | 955 | { |
| 969 | int ret; | 956 | int ret; |
| 970 | 957 | ||
| @@ -975,7 +962,7 @@ i965_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length) | |||
| 975 | intel_ring_emit(ring, | 962 | intel_ring_emit(ring, |
| 976 | MI_BATCH_BUFFER_START | | 963 | MI_BATCH_BUFFER_START | |
| 977 | MI_BATCH_GTT | | 964 | MI_BATCH_GTT | |
| 978 | MI_BATCH_NON_SECURE_I965); | 965 | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE_I965)); |
| 979 | intel_ring_emit(ring, offset); | 966 | intel_ring_emit(ring, offset); |
| 980 | intel_ring_advance(ring); | 967 | intel_ring_advance(ring); |
| 981 | 968 | ||
| @@ -984,7 +971,8 @@ i965_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length) | |||
| 984 | 971 | ||
| 985 | static int | 972 | static int |
| 986 | i830_dispatch_execbuffer(struct intel_ring_buffer *ring, | 973 | i830_dispatch_execbuffer(struct intel_ring_buffer *ring, |
| 987 | u32 offset, u32 len) | 974 | u32 offset, u32 len, |
| 975 | unsigned flags) | ||
| 988 | { | 976 | { |
| 989 | int ret; | 977 | int ret; |
| 990 | 978 | ||
| @@ -993,7 +981,7 @@ i830_dispatch_execbuffer(struct intel_ring_buffer *ring, | |||
| 993 | return ret; | 981 | return ret; |
| 994 | 982 | ||
| 995 | intel_ring_emit(ring, MI_BATCH_BUFFER); | 983 | intel_ring_emit(ring, MI_BATCH_BUFFER); |
| 996 | intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); | 984 | intel_ring_emit(ring, offset | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE)); |
| 997 | intel_ring_emit(ring, offset + len - 8); | 985 | intel_ring_emit(ring, offset + len - 8); |
| 998 | intel_ring_emit(ring, 0); | 986 | intel_ring_emit(ring, 0); |
| 999 | intel_ring_advance(ring); | 987 | intel_ring_advance(ring); |
| @@ -1003,7 +991,8 @@ i830_dispatch_execbuffer(struct intel_ring_buffer *ring, | |||
| 1003 | 991 | ||
| 1004 | static int | 992 | static int |
| 1005 | i915_dispatch_execbuffer(struct intel_ring_buffer *ring, | 993 | i915_dispatch_execbuffer(struct intel_ring_buffer *ring, |
| 1006 | u32 offset, u32 len) | 994 | u32 offset, u32 len, |
| 995 | unsigned flags) | ||
| 1007 | { | 996 | { |
| 1008 | int ret; | 997 | int ret; |
| 1009 | 998 | ||
| @@ -1012,7 +1001,7 @@ i915_dispatch_execbuffer(struct intel_ring_buffer *ring, | |||
| 1012 | return ret; | 1001 | return ret; |
| 1013 | 1002 | ||
| 1014 | intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_GTT); | 1003 | intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_GTT); |
| 1015 | intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); | 1004 | intel_ring_emit(ring, offset | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE)); |
| 1016 | intel_ring_advance(ring); | 1005 | intel_ring_advance(ring); |
| 1017 | 1006 | ||
| 1018 | return 0; | 1007 | return 0; |
| @@ -1075,6 +1064,29 @@ err: | |||
| 1075 | return ret; | 1064 | return ret; |
| 1076 | } | 1065 | } |
| 1077 | 1066 | ||
| 1067 | static int init_phys_hws_pga(struct intel_ring_buffer *ring) | ||
| 1068 | { | ||
| 1069 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | ||
| 1070 | u32 addr; | ||
| 1071 | |||
| 1072 | if (!dev_priv->status_page_dmah) { | ||
| 1073 | dev_priv->status_page_dmah = | ||
| 1074 | drm_pci_alloc(ring->dev, PAGE_SIZE, PAGE_SIZE); | ||
| 1075 | if (!dev_priv->status_page_dmah) | ||
| 1076 | return -ENOMEM; | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | addr = dev_priv->status_page_dmah->busaddr; | ||
| 1080 | if (INTEL_INFO(ring->dev)->gen >= 4) | ||
| 1081 | addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0; | ||
| 1082 | I915_WRITE(HWS_PGA, addr); | ||
| 1083 | |||
| 1084 | ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; | ||
| 1085 | memset(ring->status_page.page_addr, 0, PAGE_SIZE); | ||
| 1086 | |||
| 1087 | return 0; | ||
| 1088 | } | ||
| 1089 | |||
| 1078 | static int intel_init_ring_buffer(struct drm_device *dev, | 1090 | static int intel_init_ring_buffer(struct drm_device *dev, |
| 1079 | struct intel_ring_buffer *ring) | 1091 | struct intel_ring_buffer *ring) |
| 1080 | { | 1092 | { |
| @@ -1086,6 +1098,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, | |||
| 1086 | INIT_LIST_HEAD(&ring->active_list); | 1098 | INIT_LIST_HEAD(&ring->active_list); |
| 1087 | INIT_LIST_HEAD(&ring->request_list); | 1099 | INIT_LIST_HEAD(&ring->request_list); |
| 1088 | ring->size = 32 * PAGE_SIZE; | 1100 | ring->size = 32 * PAGE_SIZE; |
| 1101 | memset(ring->sync_seqno, 0, sizeof(ring->sync_seqno)); | ||
| 1089 | 1102 | ||
| 1090 | init_waitqueue_head(&ring->irq_queue); | 1103 | init_waitqueue_head(&ring->irq_queue); |
| 1091 | 1104 | ||
| @@ -1093,6 +1106,11 @@ static int intel_init_ring_buffer(struct drm_device *dev, | |||
| 1093 | ret = init_status_page(ring); | 1106 | ret = init_status_page(ring); |
| 1094 | if (ret) | 1107 | if (ret) |
| 1095 | return ret; | 1108 | return ret; |
| 1109 | } else { | ||
| 1110 | BUG_ON(ring->id != RCS); | ||
| 1111 | ret = init_phys_hws_pga(ring); | ||
| 1112 | if (ret) | ||
| 1113 | return ret; | ||
| 1096 | } | 1114 | } |
| 1097 | 1115 | ||
| 1098 | obj = i915_gem_alloc_object(dev, ring->size); | 1116 | obj = i915_gem_alloc_object(dev, ring->size); |
| @@ -1157,7 +1175,7 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring) | |||
| 1157 | 1175 | ||
| 1158 | /* Disable the ring buffer. The ring must be idle at this point */ | 1176 | /* Disable the ring buffer. The ring must be idle at this point */ |
| 1159 | dev_priv = ring->dev->dev_private; | 1177 | dev_priv = ring->dev->dev_private; |
| 1160 | ret = intel_wait_ring_idle(ring); | 1178 | ret = intel_ring_idle(ring); |
| 1161 | if (ret) | 1179 | if (ret) |
| 1162 | DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n", | 1180 | DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n", |
| 1163 | ring->name, ret); | 1181 | ring->name, ret); |
| @@ -1176,28 +1194,6 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring) | |||
| 1176 | cleanup_status_page(ring); | 1194 | cleanup_status_page(ring); |
| 1177 | } | 1195 | } |
| 1178 | 1196 | ||
| 1179 | static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) | ||
| 1180 | { | ||
| 1181 | uint32_t __iomem *virt; | ||
| 1182 | int rem = ring->size - ring->tail; | ||
| 1183 | |||
| 1184 | if (ring->space < rem) { | ||
| 1185 | int ret = intel_wait_ring_buffer(ring, rem); | ||
| 1186 | if (ret) | ||
| 1187 | return ret; | ||
| 1188 | } | ||
| 1189 | |||
| 1190 | virt = ring->virtual_start + ring->tail; | ||
| 1191 | rem /= 4; | ||
| 1192 | while (rem--) | ||
| 1193 | iowrite32(MI_NOOP, virt++); | ||
| 1194 | |||
| 1195 | ring->tail = 0; | ||
| 1196 | ring->space = ring_space(ring); | ||
| 1197 | |||
| 1198 | return 0; | ||
| 1199 | } | ||
| 1200 | |||
| 1201 | static int intel_ring_wait_seqno(struct intel_ring_buffer *ring, u32 seqno) | 1197 | static int intel_ring_wait_seqno(struct intel_ring_buffer *ring, u32 seqno) |
| 1202 | { | 1198 | { |
| 1203 | int ret; | 1199 | int ret; |
| @@ -1231,7 +1227,7 @@ static int intel_ring_wait_request(struct intel_ring_buffer *ring, int n) | |||
| 1231 | if (request->tail == -1) | 1227 | if (request->tail == -1) |
| 1232 | continue; | 1228 | continue; |
| 1233 | 1229 | ||
| 1234 | space = request->tail - (ring->tail + 8); | 1230 | space = request->tail - (ring->tail + I915_RING_FREE_SPACE); |
| 1235 | if (space < 0) | 1231 | if (space < 0) |
| 1236 | space += ring->size; | 1232 | space += ring->size; |
| 1237 | if (space >= n) { | 1233 | if (space >= n) { |
| @@ -1266,7 +1262,7 @@ static int intel_ring_wait_request(struct intel_ring_buffer *ring, int n) | |||
| 1266 | return 0; | 1262 | return 0; |
| 1267 | } | 1263 | } |
| 1268 | 1264 | ||
| 1269 | int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) | 1265 | static int ring_wait_for_space(struct intel_ring_buffer *ring, int n) |
| 1270 | { | 1266 | { |
| 1271 | struct drm_device *dev = ring->dev; | 1267 | struct drm_device *dev = ring->dev; |
| 1272 | struct drm_i915_private *dev_priv = dev->dev_private; | 1268 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -1309,6 +1305,60 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) | |||
| 1309 | return -EBUSY; | 1305 | return -EBUSY; |
| 1310 | } | 1306 | } |
| 1311 | 1307 | ||
| 1308 | static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) | ||
| 1309 | { | ||
| 1310 | uint32_t __iomem *virt; | ||
| 1311 | int rem = ring->size - ring->tail; | ||
| 1312 | |||
| 1313 | if (ring->space < rem) { | ||
| 1314 | int ret = ring_wait_for_space(ring, rem); | ||
| 1315 | if (ret) | ||
| 1316 | return ret; | ||
| 1317 | } | ||
| 1318 | |||
| 1319 | virt = ring->virtual_start + ring->tail; | ||
| 1320 | rem /= 4; | ||
| 1321 | while (rem--) | ||
| 1322 | iowrite32(MI_NOOP, virt++); | ||
| 1323 | |||
| 1324 | ring->tail = 0; | ||
| 1325 | ring->space = ring_space(ring); | ||
| 1326 | |||
| 1327 | return 0; | ||
| 1328 | } | ||
| 1329 | |||
| 1330 | int intel_ring_idle(struct intel_ring_buffer *ring) | ||
| 1331 | { | ||
| 1332 | u32 seqno; | ||
| 1333 | int ret; | ||
| 1334 | |||
| 1335 | /* We need to add any requests required to flush the objects and ring */ | ||
| 1336 | if (ring->outstanding_lazy_request) { | ||
| 1337 | ret = i915_add_request(ring, NULL, NULL); | ||
| 1338 | if (ret) | ||
| 1339 | return ret; | ||
| 1340 | } | ||
| 1341 | |||
| 1342 | /* Wait upon the last request to be completed */ | ||
| 1343 | if (list_empty(&ring->request_list)) | ||
| 1344 | return 0; | ||
| 1345 | |||
| 1346 | seqno = list_entry(ring->request_list.prev, | ||
| 1347 | struct drm_i915_gem_request, | ||
| 1348 | list)->seqno; | ||
| 1349 | |||
| 1350 | return i915_wait_seqno(ring, seqno); | ||
| 1351 | } | ||
| 1352 | |||
| 1353 | static int | ||
| 1354 | intel_ring_alloc_seqno(struct intel_ring_buffer *ring) | ||
| 1355 | { | ||
| 1356 | if (ring->outstanding_lazy_request) | ||
| 1357 | return 0; | ||
| 1358 | |||
| 1359 | return i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_request); | ||
| 1360 | } | ||
| 1361 | |||
| 1312 | int intel_ring_begin(struct intel_ring_buffer *ring, | 1362 | int intel_ring_begin(struct intel_ring_buffer *ring, |
| 1313 | int num_dwords) | 1363 | int num_dwords) |
| 1314 | { | 1364 | { |
| @@ -1320,6 +1370,11 @@ int intel_ring_begin(struct intel_ring_buffer *ring, | |||
| 1320 | if (ret) | 1370 | if (ret) |
| 1321 | return ret; | 1371 | return ret; |
| 1322 | 1372 | ||
| 1373 | /* Preallocate the olr before touching the ring */ | ||
| 1374 | ret = intel_ring_alloc_seqno(ring); | ||
| 1375 | if (ret) | ||
| 1376 | return ret; | ||
| 1377 | |||
| 1323 | if (unlikely(ring->tail + n > ring->effective_size)) { | 1378 | if (unlikely(ring->tail + n > ring->effective_size)) { |
| 1324 | ret = intel_wrap_ring_buffer(ring); | 1379 | ret = intel_wrap_ring_buffer(ring); |
| 1325 | if (unlikely(ret)) | 1380 | if (unlikely(ret)) |
| @@ -1327,7 +1382,7 @@ int intel_ring_begin(struct intel_ring_buffer *ring, | |||
| 1327 | } | 1382 | } |
| 1328 | 1383 | ||
| 1329 | if (unlikely(ring->space < n)) { | 1384 | if (unlikely(ring->space < n)) { |
| 1330 | ret = intel_wait_ring_buffer(ring, n); | 1385 | ret = ring_wait_for_space(ring, n); |
| 1331 | if (unlikely(ret)) | 1386 | if (unlikely(ret)) |
| 1332 | return ret; | 1387 | return ret; |
| 1333 | } | 1388 | } |
| @@ -1391,10 +1446,17 @@ static int gen6_ring_flush(struct intel_ring_buffer *ring, | |||
| 1391 | return ret; | 1446 | return ret; |
| 1392 | 1447 | ||
| 1393 | cmd = MI_FLUSH_DW; | 1448 | cmd = MI_FLUSH_DW; |
| 1449 | /* | ||
| 1450 | * Bspec vol 1c.5 - video engine command streamer: | ||
| 1451 | * "If ENABLED, all TLBs will be invalidated once the flush | ||
| 1452 | * operation is complete. This bit is only valid when the | ||
| 1453 | * Post-Sync Operation field is a value of 1h or 3h." | ||
| 1454 | */ | ||
| 1394 | if (invalidate & I915_GEM_GPU_DOMAINS) | 1455 | if (invalidate & I915_GEM_GPU_DOMAINS) |
| 1395 | cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD; | 1456 | cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD | |
| 1457 | MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW; | ||
| 1396 | intel_ring_emit(ring, cmd); | 1458 | intel_ring_emit(ring, cmd); |
| 1397 | intel_ring_emit(ring, 0); | 1459 | intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT); |
| 1398 | intel_ring_emit(ring, 0); | 1460 | intel_ring_emit(ring, 0); |
| 1399 | intel_ring_emit(ring, MI_NOOP); | 1461 | intel_ring_emit(ring, MI_NOOP); |
| 1400 | intel_ring_advance(ring); | 1462 | intel_ring_advance(ring); |
| @@ -1402,8 +1464,30 @@ static int gen6_ring_flush(struct intel_ring_buffer *ring, | |||
| 1402 | } | 1464 | } |
| 1403 | 1465 | ||
| 1404 | static int | 1466 | static int |
| 1467 | hsw_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, | ||
| 1468 | u32 offset, u32 len, | ||
| 1469 | unsigned flags) | ||
| 1470 | { | ||
| 1471 | int ret; | ||
| 1472 | |||
| 1473 | ret = intel_ring_begin(ring, 2); | ||
| 1474 | if (ret) | ||
| 1475 | return ret; | ||
| 1476 | |||
| 1477 | intel_ring_emit(ring, | ||
| 1478 | MI_BATCH_BUFFER_START | MI_BATCH_PPGTT_HSW | | ||
| 1479 | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE_HSW)); | ||
| 1480 | /* bit0-7 is the length on GEN6+ */ | ||
| 1481 | intel_ring_emit(ring, offset); | ||
| 1482 | intel_ring_advance(ring); | ||
| 1483 | |||
| 1484 | return 0; | ||
| 1485 | } | ||
| 1486 | |||
| 1487 | static int | ||
| 1405 | gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, | 1488 | gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, |
| 1406 | u32 offset, u32 len) | 1489 | u32 offset, u32 len, |
| 1490 | unsigned flags) | ||
| 1407 | { | 1491 | { |
| 1408 | int ret; | 1492 | int ret; |
| 1409 | 1493 | ||
| @@ -1411,7 +1495,9 @@ gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, | |||
| 1411 | if (ret) | 1495 | if (ret) |
| 1412 | return ret; | 1496 | return ret; |
| 1413 | 1497 | ||
| 1414 | intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965); | 1498 | intel_ring_emit(ring, |
| 1499 | MI_BATCH_BUFFER_START | | ||
| 1500 | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE_I965)); | ||
| 1415 | /* bit0-7 is the length on GEN6+ */ | 1501 | /* bit0-7 is the length on GEN6+ */ |
| 1416 | intel_ring_emit(ring, offset); | 1502 | intel_ring_emit(ring, offset); |
| 1417 | intel_ring_advance(ring); | 1503 | intel_ring_advance(ring); |
| @@ -1432,10 +1518,17 @@ static int blt_ring_flush(struct intel_ring_buffer *ring, | |||
| 1432 | return ret; | 1518 | return ret; |
| 1433 | 1519 | ||
| 1434 | cmd = MI_FLUSH_DW; | 1520 | cmd = MI_FLUSH_DW; |
| 1521 | /* | ||
| 1522 | * Bspec vol 1c.3 - blitter engine command streamer: | ||
| 1523 | * "If ENABLED, all TLBs will be invalidated once the flush | ||
| 1524 | * operation is complete. This bit is only valid when the | ||
| 1525 | * Post-Sync Operation field is a value of 1h or 3h." | ||
| 1526 | */ | ||
| 1435 | if (invalidate & I915_GEM_DOMAIN_RENDER) | 1527 | if (invalidate & I915_GEM_DOMAIN_RENDER) |
| 1436 | cmd |= MI_INVALIDATE_TLB; | 1528 | cmd |= MI_INVALIDATE_TLB | MI_FLUSH_DW_STORE_INDEX | |
| 1529 | MI_FLUSH_DW_OP_STOREDW; | ||
| 1437 | intel_ring_emit(ring, cmd); | 1530 | intel_ring_emit(ring, cmd); |
| 1438 | intel_ring_emit(ring, 0); | 1531 | intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT); |
| 1439 | intel_ring_emit(ring, 0); | 1532 | intel_ring_emit(ring, 0); |
| 1440 | intel_ring_emit(ring, MI_NOOP); | 1533 | intel_ring_emit(ring, MI_NOOP); |
| 1441 | intel_ring_advance(ring); | 1534 | intel_ring_advance(ring); |
| @@ -1490,7 +1583,9 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
| 1490 | ring->irq_enable_mask = I915_USER_INTERRUPT; | 1583 | ring->irq_enable_mask = I915_USER_INTERRUPT; |
| 1491 | } | 1584 | } |
| 1492 | ring->write_tail = ring_write_tail; | 1585 | ring->write_tail = ring_write_tail; |
| 1493 | if (INTEL_INFO(dev)->gen >= 6) | 1586 | if (IS_HASWELL(dev)) |
| 1587 | ring->dispatch_execbuffer = hsw_ring_dispatch_execbuffer; | ||
| 1588 | else if (INTEL_INFO(dev)->gen >= 6) | ||
| 1494 | ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; | 1589 | ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; |
| 1495 | else if (INTEL_INFO(dev)->gen >= 4) | 1590 | else if (INTEL_INFO(dev)->gen >= 4) |
| 1496 | ring->dispatch_execbuffer = i965_dispatch_execbuffer; | 1591 | ring->dispatch_execbuffer = i965_dispatch_execbuffer; |
| @@ -1501,12 +1596,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
| 1501 | ring->init = init_render_ring; | 1596 | ring->init = init_render_ring; |
| 1502 | ring->cleanup = render_ring_cleanup; | 1597 | ring->cleanup = render_ring_cleanup; |
| 1503 | 1598 | ||
| 1504 | |||
| 1505 | if (!I915_NEED_GFX_HWS(dev)) { | ||
| 1506 | ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; | ||
| 1507 | memset(ring->status_page.page_addr, 0, PAGE_SIZE); | ||
| 1508 | } | ||
| 1509 | |||
| 1510 | return intel_init_ring_buffer(dev, ring); | 1599 | return intel_init_ring_buffer(dev, ring); |
| 1511 | } | 1600 | } |
| 1512 | 1601 | ||
| @@ -1514,6 +1603,7 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) | |||
| 1514 | { | 1603 | { |
| 1515 | drm_i915_private_t *dev_priv = dev->dev_private; | 1604 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 1516 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; | 1605 | struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; |
| 1606 | int ret; | ||
| 1517 | 1607 | ||
| 1518 | ring->name = "render ring"; | 1608 | ring->name = "render ring"; |
| 1519 | ring->id = RCS; | 1609 | ring->id = RCS; |
| @@ -1551,16 +1641,13 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) | |||
| 1551 | ring->init = init_render_ring; | 1641 | ring->init = init_render_ring; |
| 1552 | ring->cleanup = render_ring_cleanup; | 1642 | ring->cleanup = render_ring_cleanup; |
| 1553 | 1643 | ||
| 1554 | if (!I915_NEED_GFX_HWS(dev)) | ||
| 1555 | ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; | ||
| 1556 | |||
| 1557 | ring->dev = dev; | 1644 | ring->dev = dev; |
| 1558 | INIT_LIST_HEAD(&ring->active_list); | 1645 | INIT_LIST_HEAD(&ring->active_list); |
| 1559 | INIT_LIST_HEAD(&ring->request_list); | 1646 | INIT_LIST_HEAD(&ring->request_list); |
| 1560 | 1647 | ||
| 1561 | ring->size = size; | 1648 | ring->size = size; |
| 1562 | ring->effective_size = ring->size; | 1649 | ring->effective_size = ring->size; |
| 1563 | if (IS_I830(ring->dev)) | 1650 | if (IS_I830(ring->dev) || IS_845G(ring->dev)) |
| 1564 | ring->effective_size -= 128; | 1651 | ring->effective_size -= 128; |
| 1565 | 1652 | ||
| 1566 | ring->virtual_start = ioremap_wc(start, size); | 1653 | ring->virtual_start = ioremap_wc(start, size); |
| @@ -1570,6 +1657,12 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) | |||
| 1570 | return -ENOMEM; | 1657 | return -ENOMEM; |
| 1571 | } | 1658 | } |
| 1572 | 1659 | ||
| 1660 | if (!I915_NEED_GFX_HWS(dev)) { | ||
| 1661 | ret = init_phys_hws_pga(ring); | ||
| 1662 | if (ret) | ||
| 1663 | return ret; | ||
| 1664 | } | ||
| 1665 | |||
| 1573 | return 0; | 1666 | return 0; |
| 1574 | } | 1667 | } |
| 1575 | 1668 | ||
| @@ -1618,7 +1711,6 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) | |||
| 1618 | } | 1711 | } |
| 1619 | ring->init = init_ring_common; | 1712 | ring->init = init_ring_common; |
| 1620 | 1713 | ||
| 1621 | |||
| 1622 | return intel_init_ring_buffer(dev, ring); | 1714 | return intel_init_ring_buffer(dev, ring); |
| 1623 | } | 1715 | } |
| 1624 | 1716 | ||
