1
2
3
4
5
6#include "i915_drv.h"
7#include "i915_scatterlist.h"
8#include "i915_pvinfo.h"
9#include "i915_vgpu.h"
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41#define pipelined 0
42
43static struct drm_i915_private *fence_to_i915(struct i915_fence_reg *fence)
44{
45 return fence->ggtt->vm.i915;
46}
47
48static struct intel_uncore *fence_to_uncore(struct i915_fence_reg *fence)
49{
50 return fence->ggtt->vm.gt->uncore;
51}
52
53static void i965_write_fence_reg(struct i915_fence_reg *fence)
54{
55 i915_reg_t fence_reg_lo, fence_reg_hi;
56 int fence_pitch_shift;
57 u64 val;
58
59 if (GRAPHICS_VER(fence_to_i915(fence)) >= 6) {
60 fence_reg_lo = FENCE_REG_GEN6_LO(fence->id);
61 fence_reg_hi = FENCE_REG_GEN6_HI(fence->id);
62 fence_pitch_shift = GEN6_FENCE_PITCH_SHIFT;
63
64 } else {
65 fence_reg_lo = FENCE_REG_965_LO(fence->id);
66 fence_reg_hi = FENCE_REG_965_HI(fence->id);
67 fence_pitch_shift = I965_FENCE_PITCH_SHIFT;
68 }
69
70 val = 0;
71 if (fence->tiling) {
72 unsigned int stride = fence->stride;
73
74 GEM_BUG_ON(!IS_ALIGNED(stride, 128));
75
76 val = fence->start + fence->size - I965_FENCE_PAGE;
77 val <<= 32;
78 val |= fence->start;
79 val |= (u64)((stride / 128) - 1) << fence_pitch_shift;
80 if (fence->tiling == I915_TILING_Y)
81 val |= BIT(I965_FENCE_TILING_Y_SHIFT);
82 val |= I965_FENCE_REG_VALID;
83 }
84
85 if (!pipelined) {
86 struct intel_uncore *uncore = fence_to_uncore(fence);
87
88
89
90
91
92
93
94
95
96
97
98 intel_uncore_write_fw(uncore, fence_reg_lo, 0);
99 intel_uncore_posting_read_fw(uncore, fence_reg_lo);
100
101 intel_uncore_write_fw(uncore, fence_reg_hi, upper_32_bits(val));
102 intel_uncore_write_fw(uncore, fence_reg_lo, lower_32_bits(val));
103 intel_uncore_posting_read_fw(uncore, fence_reg_lo);
104 }
105}
106
107static void i915_write_fence_reg(struct i915_fence_reg *fence)
108{
109 u32 val;
110
111 val = 0;
112 if (fence->tiling) {
113 unsigned int stride = fence->stride;
114 unsigned int tiling = fence->tiling;
115 bool is_y_tiled = tiling == I915_TILING_Y;
116
117 if (is_y_tiled && HAS_128_BYTE_Y_TILING(fence_to_i915(fence)))
118 stride /= 128;
119 else
120 stride /= 512;
121 GEM_BUG_ON(!is_power_of_2(stride));
122
123 val = fence->start;
124 if (is_y_tiled)
125 val |= BIT(I830_FENCE_TILING_Y_SHIFT);
126 val |= I915_FENCE_SIZE_BITS(fence->size);
127 val |= ilog2(stride) << I830_FENCE_PITCH_SHIFT;
128
129 val |= I830_FENCE_REG_VALID;
130 }
131
132 if (!pipelined) {
133 struct intel_uncore *uncore = fence_to_uncore(fence);
134 i915_reg_t reg = FENCE_REG(fence->id);
135
136 intel_uncore_write_fw(uncore, reg, val);
137 intel_uncore_posting_read_fw(uncore, reg);
138 }
139}
140
141static void i830_write_fence_reg(struct i915_fence_reg *fence)
142{
143 u32 val;
144
145 val = 0;
146 if (fence->tiling) {
147 unsigned int stride = fence->stride;
148
149 val = fence->start;
150 if (fence->tiling == I915_TILING_Y)
151 val |= BIT(I830_FENCE_TILING_Y_SHIFT);
152 val |= I830_FENCE_SIZE_BITS(fence->size);
153 val |= ilog2(stride / 128) << I830_FENCE_PITCH_SHIFT;
154 val |= I830_FENCE_REG_VALID;
155 }
156
157 if (!pipelined) {
158 struct intel_uncore *uncore = fence_to_uncore(fence);
159 i915_reg_t reg = FENCE_REG(fence->id);
160
161 intel_uncore_write_fw(uncore, reg, val);
162 intel_uncore_posting_read_fw(uncore, reg);
163 }
164}
165
166static void fence_write(struct i915_fence_reg *fence)
167{
168 struct drm_i915_private *i915 = fence_to_i915(fence);
169
170
171
172
173
174
175
176 if (GRAPHICS_VER(i915) == 2)
177 i830_write_fence_reg(fence);
178 else if (GRAPHICS_VER(i915) == 3)
179 i915_write_fence_reg(fence);
180 else
181 i965_write_fence_reg(fence);
182
183
184
185
186
187}
188
189static bool gpu_uses_fence_registers(struct i915_fence_reg *fence)
190{
191 return GRAPHICS_VER(fence_to_i915(fence)) < 4;
192}
193
194static int fence_update(struct i915_fence_reg *fence,
195 struct i915_vma *vma)
196{
197 struct i915_ggtt *ggtt = fence->ggtt;
198 struct intel_uncore *uncore = fence_to_uncore(fence);
199 intel_wakeref_t wakeref;
200 struct i915_vma *old;
201 int ret;
202
203 fence->tiling = 0;
204 if (vma) {
205 GEM_BUG_ON(!i915_gem_object_get_stride(vma->obj) ||
206 !i915_gem_object_get_tiling(vma->obj));
207
208 if (!i915_vma_is_map_and_fenceable(vma))
209 return -EINVAL;
210
211 if (gpu_uses_fence_registers(fence)) {
212
213 ret = i915_vma_sync(vma);
214 if (ret)
215 return ret;
216 }
217
218 fence->start = vma->node.start;
219 fence->size = vma->fence_size;
220 fence->stride = i915_gem_object_get_stride(vma->obj);
221 fence->tiling = i915_gem_object_get_tiling(vma->obj);
222 }
223 WRITE_ONCE(fence->dirty, false);
224
225 old = xchg(&fence->vma, NULL);
226 if (old) {
227
228 ret = i915_active_wait(&fence->active);
229 if (ret) {
230 fence->vma = old;
231 return ret;
232 }
233
234 i915_vma_flush_writes(old);
235
236
237
238
239
240 if (old != vma) {
241 GEM_BUG_ON(old->fence != fence);
242 i915_vma_revoke_mmap(old);
243 old->fence = NULL;
244 }
245
246 list_move(&fence->link, &ggtt->fence_list);
247 }
248
249
250
251
252
253
254
255
256
257
258
259 wakeref = intel_runtime_pm_get_if_in_use(uncore->rpm);
260 if (!wakeref) {
261 GEM_BUG_ON(vma);
262 return 0;
263 }
264
265 WRITE_ONCE(fence->vma, vma);
266 fence_write(fence);
267
268 if (vma) {
269 vma->fence = fence;
270 list_move_tail(&fence->link, &ggtt->fence_list);
271 }
272
273 intel_runtime_pm_put(uncore->rpm, wakeref);
274 return 0;
275}
276
277
278
279
280
281
282
283
284void i915_vma_revoke_fence(struct i915_vma *vma)
285{
286 struct i915_fence_reg *fence = vma->fence;
287 intel_wakeref_t wakeref;
288
289 lockdep_assert_held(&vma->vm->mutex);
290 if (!fence)
291 return;
292
293 GEM_BUG_ON(fence->vma != vma);
294 GEM_BUG_ON(!i915_active_is_idle(&fence->active));
295 GEM_BUG_ON(atomic_read(&fence->pin_count));
296
297 fence->tiling = 0;
298 WRITE_ONCE(fence->vma, NULL);
299 vma->fence = NULL;
300
301
302
303
304
305
306
307
308
309
310
311
312 with_intel_runtime_pm_if_active(fence_to_uncore(fence)->rpm, wakeref)
313 fence_write(fence);
314}
315
316static bool fence_is_active(const struct i915_fence_reg *fence)
317{
318 return fence->vma && i915_vma_is_active(fence->vma);
319}
320
321static struct i915_fence_reg *fence_find(struct i915_ggtt *ggtt)
322{
323 struct i915_fence_reg *active = NULL;
324 struct i915_fence_reg *fence, *fn;
325
326 list_for_each_entry_safe(fence, fn, &ggtt->fence_list, link) {
327 GEM_BUG_ON(fence->vma && fence->vma->fence != fence);
328
329 if (fence == active)
330 active = ERR_PTR(-EAGAIN);
331
332
333 if (active != ERR_PTR(-EAGAIN) && fence_is_active(fence)) {
334 if (!active)
335 active = fence;
336
337 list_move_tail(&fence->link, &ggtt->fence_list);
338 continue;
339 }
340
341 if (atomic_read(&fence->pin_count))
342 continue;
343
344 return fence;
345 }
346
347
348 if (intel_has_pending_fb_unpin(ggtt->vm.i915))
349 return ERR_PTR(-EAGAIN);
350
351 return ERR_PTR(-ENOBUFS);
352}
353
354int __i915_vma_pin_fence(struct i915_vma *vma)
355{
356 struct i915_ggtt *ggtt = i915_vm_to_ggtt(vma->vm);
357 struct i915_fence_reg *fence;
358 struct i915_vma *set = i915_gem_object_is_tiled(vma->obj) ? vma : NULL;
359 int err;
360
361 lockdep_assert_held(&vma->vm->mutex);
362
363
364 if (vma->fence) {
365 fence = vma->fence;
366 GEM_BUG_ON(fence->vma != vma);
367 atomic_inc(&fence->pin_count);
368 if (!fence->dirty) {
369 list_move_tail(&fence->link, &ggtt->fence_list);
370 return 0;
371 }
372 } else if (set) {
373 fence = fence_find(ggtt);
374 if (IS_ERR(fence))
375 return PTR_ERR(fence);
376
377 GEM_BUG_ON(atomic_read(&fence->pin_count));
378 atomic_inc(&fence->pin_count);
379 } else {
380 return 0;
381 }
382
383 err = fence_update(fence, set);
384 if (err)
385 goto out_unpin;
386
387 GEM_BUG_ON(fence->vma != set);
388 GEM_BUG_ON(vma->fence != (set ? fence : NULL));
389
390 if (set)
391 return 0;
392
393out_unpin:
394 atomic_dec(&fence->pin_count);
395 return err;
396}
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416int i915_vma_pin_fence(struct i915_vma *vma)
417{
418 int err;
419
420 if (!vma->fence && !i915_gem_object_is_tiled(vma->obj))
421 return 0;
422
423
424
425
426
427 assert_rpm_wakelock_held(vma->vm->gt->uncore->rpm);
428 GEM_BUG_ON(!i915_vma_is_pinned(vma));
429 GEM_BUG_ON(!i915_vma_is_ggtt(vma));
430
431 err = mutex_lock_interruptible(&vma->vm->mutex);
432 if (err)
433 return err;
434
435 err = __i915_vma_pin_fence(vma);
436 mutex_unlock(&vma->vm->mutex);
437
438 return err;
439}
440
441
442
443
444
445
446
447
448struct i915_fence_reg *i915_reserve_fence(struct i915_ggtt *ggtt)
449{
450 struct i915_fence_reg *fence;
451 int count;
452 int ret;
453
454 lockdep_assert_held(&ggtt->vm.mutex);
455
456
457 count = 0;
458 list_for_each_entry(fence, &ggtt->fence_list, link)
459 count += !atomic_read(&fence->pin_count);
460 if (count <= 1)
461 return ERR_PTR(-ENOSPC);
462
463 fence = fence_find(ggtt);
464 if (IS_ERR(fence))
465 return fence;
466
467 if (fence->vma) {
468
469 ret = fence_update(fence, NULL);
470 if (ret)
471 return ERR_PTR(ret);
472 }
473
474 list_del(&fence->link);
475
476 return fence;
477}
478
479
480
481
482
483
484
485void i915_unreserve_fence(struct i915_fence_reg *fence)
486{
487 struct i915_ggtt *ggtt = fence->ggtt;
488
489 lockdep_assert_held(&ggtt->vm.mutex);
490
491 list_add(&fence->link, &ggtt->fence_list);
492}
493
494
495
496
497
498
499
500
501
502void intel_ggtt_restore_fences(struct i915_ggtt *ggtt)
503{
504 int i;
505
506 for (i = 0; i < ggtt->num_fences; i++)
507 fence_write(&ggtt->fence_regs[i]);
508}
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565static void detect_bit_6_swizzle(struct i915_ggtt *ggtt)
566{
567 struct intel_uncore *uncore = ggtt->vm.gt->uncore;
568 struct drm_i915_private *i915 = ggtt->vm.i915;
569 u32 swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
570 u32 swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
571
572 if (GRAPHICS_VER(i915) >= 8 || IS_VALLEYVIEW(i915)) {
573
574
575
576
577
578
579
580 swizzle_x = I915_BIT_6_SWIZZLE_NONE;
581 swizzle_y = I915_BIT_6_SWIZZLE_NONE;
582 } else if (GRAPHICS_VER(i915) >= 6) {
583 if (i915->preserve_bios_swizzle) {
584 if (intel_uncore_read(uncore, DISP_ARB_CTL) &
585 DISP_TILE_SURFACE_SWIZZLING) {
586 swizzle_x = I915_BIT_6_SWIZZLE_9_10;
587 swizzle_y = I915_BIT_6_SWIZZLE_9;
588 } else {
589 swizzle_x = I915_BIT_6_SWIZZLE_NONE;
590 swizzle_y = I915_BIT_6_SWIZZLE_NONE;
591 }
592 } else {
593 u32 dimm_c0, dimm_c1;
594
595 dimm_c0 = intel_uncore_read(uncore, MAD_DIMM_C0);
596 dimm_c1 = intel_uncore_read(uncore, MAD_DIMM_C1);
597 dimm_c0 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK;
598 dimm_c1 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK;
599
600
601
602
603
604
605
606 if (dimm_c0 == dimm_c1) {
607 swizzle_x = I915_BIT_6_SWIZZLE_9_10;
608 swizzle_y = I915_BIT_6_SWIZZLE_9;
609 } else {
610 swizzle_x = I915_BIT_6_SWIZZLE_NONE;
611 swizzle_y = I915_BIT_6_SWIZZLE_NONE;
612 }
613 }
614 } else if (GRAPHICS_VER(i915) == 5) {
615
616
617
618
619 swizzle_x = I915_BIT_6_SWIZZLE_9_10;
620 swizzle_y = I915_BIT_6_SWIZZLE_9;
621 } else if (GRAPHICS_VER(i915) == 2) {
622
623
624
625
626 swizzle_x = I915_BIT_6_SWIZZLE_NONE;
627 swizzle_y = I915_BIT_6_SWIZZLE_NONE;
628 } else if (IS_G45(i915) || IS_I965G(i915) || IS_G33(i915)) {
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656 if (intel_uncore_read16(uncore, C0DRB3_BW) ==
657 intel_uncore_read16(uncore, C1DRB3_BW)) {
658 swizzle_x = I915_BIT_6_SWIZZLE_9_10;
659 swizzle_y = I915_BIT_6_SWIZZLE_9;
660 }
661 } else {
662 u32 dcc = intel_uncore_read(uncore, DCC);
663
664
665
666
667
668
669
670
671
672
673 switch (dcc & DCC_ADDRESSING_MODE_MASK) {
674 case DCC_ADDRESSING_MODE_SINGLE_CHANNEL:
675 case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC:
676 swizzle_x = I915_BIT_6_SWIZZLE_NONE;
677 swizzle_y = I915_BIT_6_SWIZZLE_NONE;
678 break;
679 case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED:
680 if (dcc & DCC_CHANNEL_XOR_DISABLE) {
681
682
683
684
685 swizzle_x = I915_BIT_6_SWIZZLE_9_10;
686 swizzle_y = I915_BIT_6_SWIZZLE_9;
687 } else if ((dcc & DCC_CHANNEL_XOR_BIT_17) == 0) {
688
689 swizzle_x = I915_BIT_6_SWIZZLE_9_10_11;
690 swizzle_y = I915_BIT_6_SWIZZLE_9_11;
691 } else {
692
693 swizzle_x = I915_BIT_6_SWIZZLE_9_10_17;
694 swizzle_y = I915_BIT_6_SWIZZLE_9_17;
695 }
696 break;
697 }
698
699
700 if (GRAPHICS_VER(i915) == 4 &&
701 !(intel_uncore_read(uncore, DCC2) & DCC2_MODIFIED_ENHANCED_DISABLE)) {
702 swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
703 swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
704 }
705
706 if (dcc == 0xffffffff) {
707 drm_err(&i915->drm, "Couldn't read from MCHBAR. "
708 "Disabling tiling.\n");
709 swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
710 swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
711 }
712 }
713
714 if (swizzle_x == I915_BIT_6_SWIZZLE_UNKNOWN ||
715 swizzle_y == I915_BIT_6_SWIZZLE_UNKNOWN) {
716
717
718
719
720
721
722
723
724
725
726 i915->quirks |= QUIRK_PIN_SWIZZLED_PAGES;
727 swizzle_x = I915_BIT_6_SWIZZLE_NONE;
728 swizzle_y = I915_BIT_6_SWIZZLE_NONE;
729 }
730
731 i915->ggtt.bit_6_swizzle_x = swizzle_x;
732 i915->ggtt.bit_6_swizzle_y = swizzle_y;
733}
734
735
736
737
738
739
740static void swizzle_page(struct page *page)
741{
742 char temp[64];
743 char *vaddr;
744 int i;
745
746 vaddr = kmap(page);
747
748 for (i = 0; i < PAGE_SIZE; i += 128) {
749 memcpy(temp, &vaddr[i], 64);
750 memcpy(&vaddr[i], &vaddr[i + 64], 64);
751 memcpy(&vaddr[i + 64], temp, 64);
752 }
753
754 kunmap(page);
755}
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770void
771i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj,
772 struct sg_table *pages)
773{
774 struct sgt_iter sgt_iter;
775 struct page *page;
776 int i;
777
778 if (obj->bit_17 == NULL)
779 return;
780
781 i = 0;
782 for_each_sgt_page(page, sgt_iter, pages) {
783 char new_bit_17 = page_to_phys(page) >> 17;
784
785 if ((new_bit_17 & 0x1) != (test_bit(i, obj->bit_17) != 0)) {
786 swizzle_page(page);
787 set_page_dirty(page);
788 }
789
790 i++;
791 }
792}
793
794
795
796
797
798
799
800
801
802
803void
804i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
805 struct sg_table *pages)
806{
807 const unsigned int page_count = obj->base.size >> PAGE_SHIFT;
808 struct sgt_iter sgt_iter;
809 struct page *page;
810 int i;
811
812 if (obj->bit_17 == NULL) {
813 obj->bit_17 = bitmap_zalloc(page_count, GFP_KERNEL);
814 if (obj->bit_17 == NULL) {
815 DRM_ERROR("Failed to allocate memory for bit 17 "
816 "record\n");
817 return;
818 }
819 }
820
821 i = 0;
822
823 for_each_sgt_page(page, sgt_iter, pages) {
824 if (page_to_phys(page) & (1 << 17))
825 __set_bit(i, obj->bit_17);
826 else
827 __clear_bit(i, obj->bit_17);
828 i++;
829 }
830}
831
832void intel_ggtt_init_fences(struct i915_ggtt *ggtt)
833{
834 struct drm_i915_private *i915 = ggtt->vm.i915;
835 struct intel_uncore *uncore = ggtt->vm.gt->uncore;
836 int num_fences;
837 int i;
838
839 INIT_LIST_HEAD(&ggtt->fence_list);
840 INIT_LIST_HEAD(&ggtt->userfault_list);
841 intel_wakeref_auto_init(&ggtt->userfault_wakeref, uncore->rpm);
842
843 detect_bit_6_swizzle(ggtt);
844
845 if (!i915_ggtt_has_aperture(ggtt))
846 num_fences = 0;
847 else if (GRAPHICS_VER(i915) >= 7 &&
848 !(IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)))
849 num_fences = 32;
850 else if (GRAPHICS_VER(i915) >= 4 ||
851 IS_I945G(i915) || IS_I945GM(i915) ||
852 IS_G33(i915) || IS_PINEVIEW(i915))
853 num_fences = 16;
854 else
855 num_fences = 8;
856
857 if (intel_vgpu_active(i915))
858 num_fences = intel_uncore_read(uncore,
859 vgtif_reg(avail_rs.fence_num));
860 ggtt->fence_regs = kcalloc(num_fences,
861 sizeof(*ggtt->fence_regs),
862 GFP_KERNEL);
863 if (!ggtt->fence_regs)
864 num_fences = 0;
865
866
867 for (i = 0; i < num_fences; i++) {
868 struct i915_fence_reg *fence = &ggtt->fence_regs[i];
869
870 i915_active_init(&fence->active, NULL, NULL, 0);
871 fence->ggtt = ggtt;
872 fence->id = i;
873 list_add_tail(&fence->link, &ggtt->fence_list);
874 }
875 ggtt->num_fences = num_fences;
876
877 intel_ggtt_restore_fences(ggtt);
878}
879
880void intel_ggtt_fini_fences(struct i915_ggtt *ggtt)
881{
882 int i;
883
884 for (i = 0; i < ggtt->num_fences; i++) {
885 struct i915_fence_reg *fence = &ggtt->fence_regs[i];
886
887 i915_active_fini(&fence->active);
888 }
889
890 kfree(ggtt->fence_regs);
891}
892
893void intel_gt_init_swizzling(struct intel_gt *gt)
894{
895 struct drm_i915_private *i915 = gt->i915;
896 struct intel_uncore *uncore = gt->uncore;
897
898 if (GRAPHICS_VER(i915) < 5 ||
899 i915->ggtt.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_NONE)
900 return;
901
902 intel_uncore_rmw(uncore, DISP_ARB_CTL, 0, DISP_TILE_SURFACE_SWIZZLING);
903
904 if (GRAPHICS_VER(i915) == 5)
905 return;
906
907 intel_uncore_rmw(uncore, TILECTL, 0, TILECTL_SWZCTL);
908
909 if (GRAPHICS_VER(i915) == 6)
910 intel_uncore_write(uncore,
911 ARB_MODE,
912 _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_SNB));
913 else if (GRAPHICS_VER(i915) == 7)
914 intel_uncore_write(uncore,
915 ARB_MODE,
916 _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_IVB));
917 else if (GRAPHICS_VER(i915) == 8)
918 intel_uncore_write(uncore,
919 GAMTARBMODE,
920 _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_BDW));
921 else
922 MISSING_CASE(GRAPHICS_VER(i915));
923}
924