forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/gpu/drm/i915/selftests/i915_vma.c
....@@ -24,10 +24,14 @@
2424
2525 #include <linux/prime_numbers.h>
2626
27
-#include "../i915_selftest.h"
27
+#include "gem/i915_gem_context.h"
28
+#include "gem/selftests/mock_context.h"
29
+
30
+#include "i915_scatterlist.h"
31
+#include "i915_selftest.h"
2832
2933 #include "mock_gem_device.h"
30
-#include "mock_context.h"
34
+#include "mock_gtt.h"
3135
3236 static bool assert_vma(struct i915_vma *vma,
3337 struct drm_i915_gem_object *obj,
....@@ -35,7 +39,7 @@
3539 {
3640 bool ok = true;
3741
38
- if (vma->vm != &ctx->ppgtt->vm) {
42
+ if (vma->vm != rcu_access_pointer(ctx->vm)) {
3943 pr_err("VMA created with wrong VM\n");
4044 ok = false;
4145 }
....@@ -58,7 +62,7 @@
5862 static struct i915_vma *
5963 checked_vma_instance(struct drm_i915_gem_object *obj,
6064 struct i915_address_space *vm,
61
- struct i915_ggtt_view *view)
65
+ const struct i915_ggtt_view *view)
6266 {
6367 struct i915_vma *vma;
6468 bool ok = true;
....@@ -110,11 +114,13 @@
110114 list_for_each_entry(obj, objects, st_link) {
111115 for (pinned = 0; pinned <= 1; pinned++) {
112116 list_for_each_entry(ctx, contexts, link) {
113
- struct i915_address_space *vm = &ctx->ppgtt->vm;
117
+ struct i915_address_space *vm;
114118 struct i915_vma *vma;
115119 int err;
116120
121
+ vm = i915_gem_context_get_vm_rcu(ctx);
117122 vma = checked_vma_instance(obj, vm, NULL);
123
+ i915_vm_put(vm);
118124 if (IS_ERR(vma))
119125 return PTR_ERR(vma);
120126
....@@ -141,7 +147,8 @@
141147
142148 static int igt_vma_create(void *arg)
143149 {
144
- struct drm_i915_private *i915 = arg;
150
+ struct i915_ggtt *ggtt = arg;
151
+ struct drm_i915_private *i915 = ggtt->vm.i915;
145152 struct drm_i915_gem_object *obj, *on;
146153 struct i915_gem_context *ctx, *cn;
147154 unsigned long num_obj, num_ctx;
....@@ -166,7 +173,7 @@
166173 }
167174
168175 nc = 0;
169
- for_each_prime_number(num_ctx, MAX_CONTEXT_HW_ID) {
176
+ for_each_prime_number(num_ctx, 2 * BITS_PER_LONG) {
170177 for (; nc < num_ctx; nc++) {
171178 ctx = mock_context(i915, "mock");
172179 if (!ctx)
....@@ -189,6 +196,8 @@
189196 list_del_init(&ctx->link);
190197 mock_context_close(ctx);
191198 }
199
+
200
+ cond_resched();
192201 }
193202
194203 end:
....@@ -245,7 +254,7 @@
245254
246255 static int igt_vma_pin1(void *arg)
247256 {
248
- struct drm_i915_private *i915 = arg;
257
+ struct i915_ggtt *ggtt = arg;
249258 const struct pin_mode modes[] = {
250259 #define VALID(sz, fl) { .size = (sz), .flags = (fl), .assert = assert_pin_valid, .string = #sz ", " #fl ", (valid) " }
251260 #define __INVALID(sz, fl, check, eval) { .size = (sz), .flags = (fl), .assert = (check), .string = #sz ", " #fl ", (invalid " #eval ")" }
....@@ -256,30 +265,30 @@
256265
257266 VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | 4096),
258267 VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | 8192),
259
- VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | (i915->ggtt.mappable_end - 4096)),
260
- VALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_BIAS | (i915->ggtt.mappable_end - 4096)),
261
- VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | (i915->ggtt.vm.total - 4096)),
268
+ VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | (ggtt->mappable_end - 4096)),
269
+ VALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_BIAS | (ggtt->mappable_end - 4096)),
270
+ VALID(0, PIN_GLOBAL | PIN_OFFSET_BIAS | (ggtt->vm.total - 4096)),
262271
263
- VALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | (i915->ggtt.mappable_end - 4096)),
264
- INVALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | i915->ggtt.mappable_end),
265
- VALID(0, PIN_GLOBAL | PIN_OFFSET_FIXED | (i915->ggtt.vm.total - 4096)),
266
- INVALID(0, PIN_GLOBAL | PIN_OFFSET_FIXED | i915->ggtt.vm.total),
272
+ VALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | (ggtt->mappable_end - 4096)),
273
+ INVALID(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | ggtt->mappable_end),
274
+ VALID(0, PIN_GLOBAL | PIN_OFFSET_FIXED | (ggtt->vm.total - 4096)),
275
+ INVALID(0, PIN_GLOBAL | PIN_OFFSET_FIXED | ggtt->vm.total),
267276 INVALID(0, PIN_GLOBAL | PIN_OFFSET_FIXED | round_down(U64_MAX, PAGE_SIZE)),
268277
269278 VALID(4096, PIN_GLOBAL),
270279 VALID(8192, PIN_GLOBAL),
271
- VALID(i915->ggtt.mappable_end - 4096, PIN_GLOBAL | PIN_MAPPABLE),
272
- VALID(i915->ggtt.mappable_end, PIN_GLOBAL | PIN_MAPPABLE),
273
- NOSPACE(i915->ggtt.mappable_end + 4096, PIN_GLOBAL | PIN_MAPPABLE),
274
- VALID(i915->ggtt.vm.total - 4096, PIN_GLOBAL),
275
- VALID(i915->ggtt.vm.total, PIN_GLOBAL),
276
- NOSPACE(i915->ggtt.vm.total + 4096, PIN_GLOBAL),
280
+ VALID(ggtt->mappable_end - 4096, PIN_GLOBAL | PIN_MAPPABLE),
281
+ VALID(ggtt->mappable_end, PIN_GLOBAL | PIN_MAPPABLE),
282
+ NOSPACE(ggtt->mappable_end + 4096, PIN_GLOBAL | PIN_MAPPABLE),
283
+ VALID(ggtt->vm.total - 4096, PIN_GLOBAL),
284
+ VALID(ggtt->vm.total, PIN_GLOBAL),
285
+ NOSPACE(ggtt->vm.total + 4096, PIN_GLOBAL),
277286 NOSPACE(round_down(U64_MAX, PAGE_SIZE), PIN_GLOBAL),
278
- INVALID(8192, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | (i915->ggtt.mappable_end - 4096)),
279
- INVALID(8192, PIN_GLOBAL | PIN_OFFSET_FIXED | (i915->ggtt.vm.total - 4096)),
287
+ INVALID(8192, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_FIXED | (ggtt->mappable_end - 4096)),
288
+ INVALID(8192, PIN_GLOBAL | PIN_OFFSET_FIXED | (ggtt->vm.total - 4096)),
280289 INVALID(8192, PIN_GLOBAL | PIN_OFFSET_FIXED | (round_down(U64_MAX, PAGE_SIZE) - 4096)),
281290
282
- VALID(8192, PIN_GLOBAL | PIN_OFFSET_BIAS | (i915->ggtt.mappable_end - 4096)),
291
+ VALID(8192, PIN_GLOBAL | PIN_OFFSET_BIAS | (ggtt->mappable_end - 4096)),
283292
284293 #if !IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
285294 /* Misusing BIAS is a programming error (it is not controllable
....@@ -287,10 +296,10 @@
287296 * However, the tests are still quite interesting for checking
288297 * variable start, end and size.
289298 */
290
- NOSPACE(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_BIAS | i915->ggtt.mappable_end),
291
- NOSPACE(0, PIN_GLOBAL | PIN_OFFSET_BIAS | i915->ggtt.vm.total),
292
- NOSPACE(8192, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_BIAS | (i915->ggtt.mappable_end - 4096)),
293
- NOSPACE(8192, PIN_GLOBAL | PIN_OFFSET_BIAS | (i915->ggtt.vm.total - 4096)),
299
+ NOSPACE(0, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_BIAS | ggtt->mappable_end),
300
+ NOSPACE(0, PIN_GLOBAL | PIN_OFFSET_BIAS | ggtt->vm.total),
301
+ NOSPACE(8192, PIN_GLOBAL | PIN_MAPPABLE | PIN_OFFSET_BIAS | (ggtt->mappable_end - 4096)),
302
+ NOSPACE(8192, PIN_GLOBAL | PIN_OFFSET_BIAS | (ggtt->vm.total - 4096)),
294303 #endif
295304 { },
296305 #undef NOSPACE
....@@ -306,13 +315,13 @@
306315 * focusing on error handling of boundary conditions.
307316 */
308317
309
- GEM_BUG_ON(!drm_mm_clean(&i915->ggtt.vm.mm));
318
+ GEM_BUG_ON(!drm_mm_clean(&ggtt->vm.mm));
310319
311
- obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
320
+ obj = i915_gem_object_create_internal(ggtt->vm.i915, PAGE_SIZE);
312321 if (IS_ERR(obj))
313322 return PTR_ERR(obj);
314323
315
- vma = checked_vma_instance(obj, &i915->ggtt.vm, NULL);
324
+ vma = checked_vma_instance(obj, &ggtt->vm, NULL);
316325 if (IS_ERR(vma))
317326 goto out;
318327
....@@ -337,6 +346,8 @@
337346 goto out;
338347 }
339348 }
349
+
350
+ cond_resched();
340351 }
341352
342353 err = 0;
....@@ -395,18 +406,79 @@
395406 return sg;
396407 }
397408
398
-static unsigned int rotated_size(const struct intel_rotation_plane_info *a,
399
- const struct intel_rotation_plane_info *b)
409
+static unsigned long remapped_index(const struct intel_remapped_info *r,
410
+ unsigned int n,
411
+ unsigned int x,
412
+ unsigned int y)
413
+{
414
+ return (r->plane[n].stride * y +
415
+ r->plane[n].offset + x);
416
+}
417
+
418
+static struct scatterlist *
419
+assert_remapped(struct drm_i915_gem_object *obj,
420
+ const struct intel_remapped_info *r, unsigned int n,
421
+ struct scatterlist *sg)
422
+{
423
+ unsigned int x, y;
424
+ unsigned int left = 0;
425
+ unsigned int offset;
426
+
427
+ for (y = 0; y < r->plane[n].height; y++) {
428
+ for (x = 0; x < r->plane[n].width; x++) {
429
+ unsigned long src_idx;
430
+ dma_addr_t src;
431
+
432
+ if (!sg) {
433
+ pr_err("Invalid sg table: too short at plane %d, (%d, %d)!\n",
434
+ n, x, y);
435
+ return ERR_PTR(-EINVAL);
436
+ }
437
+ if (!left) {
438
+ offset = 0;
439
+ left = sg_dma_len(sg);
440
+ }
441
+
442
+ src_idx = remapped_index(r, n, x, y);
443
+ src = i915_gem_object_get_dma_address(obj, src_idx);
444
+
445
+ if (left < PAGE_SIZE || left & (PAGE_SIZE-1)) {
446
+ pr_err("Invalid sg.length, found %d, expected %lu for remapped page (%d, %d) [src index %lu]\n",
447
+ sg_dma_len(sg), PAGE_SIZE,
448
+ x, y, src_idx);
449
+ return ERR_PTR(-EINVAL);
450
+ }
451
+
452
+ if (sg_dma_address(sg) + offset != src) {
453
+ pr_err("Invalid address for remapped page (%d, %d) [src index %lu]\n",
454
+ x, y, src_idx);
455
+ return ERR_PTR(-EINVAL);
456
+ }
457
+
458
+ left -= PAGE_SIZE;
459
+ offset += PAGE_SIZE;
460
+
461
+
462
+ if (!left)
463
+ sg = sg_next(sg);
464
+ }
465
+ }
466
+
467
+ return sg;
468
+}
469
+
470
+static unsigned int rotated_size(const struct intel_remapped_plane_info *a,
471
+ const struct intel_remapped_plane_info *b)
400472 {
401473 return a->width * a->height + b->width * b->height;
402474 }
403475
404
-static int igt_vma_rotate(void *arg)
476
+static int igt_vma_rotate_remap(void *arg)
405477 {
406
- struct drm_i915_private *i915 = arg;
407
- struct i915_address_space *vm = &i915->ggtt.vm;
478
+ struct i915_ggtt *ggtt = arg;
479
+ struct i915_address_space *vm = &ggtt->vm;
408480 struct drm_i915_gem_object *obj;
409
- const struct intel_rotation_plane_info planes[] = {
481
+ const struct intel_remapped_plane_info planes[] = {
410482 { .width = 1, .height = 1, .stride = 1 },
411483 { .width = 2, .height = 2, .stride = 2 },
412484 { .width = 4, .height = 4, .stride = 4 },
....@@ -424,6 +496,11 @@
424496 { .width = 6, .height = 4, .stride = 6 },
425497 { }
426498 }, *a, *b;
499
+ enum i915_ggtt_view_type types[] = {
500
+ I915_GGTT_VIEW_ROTATED,
501
+ I915_GGTT_VIEW_REMAPPED,
502
+ 0,
503
+ }, *t;
427504 const unsigned int max_pages = 64;
428505 int err = -ENOMEM;
429506
....@@ -431,10 +508,11 @@
431508 * that the page layout within the rotated VMA match our expectations.
432509 */
433510
434
- obj = i915_gem_object_create_internal(i915, max_pages * PAGE_SIZE);
511
+ obj = i915_gem_object_create_internal(vm->i915, max_pages * PAGE_SIZE);
435512 if (IS_ERR(obj))
436513 goto out;
437514
515
+ for (t = types; *t; t++) {
438516 for (a = planes; a->width; a++) {
439517 for (b = planes + ARRAY_SIZE(planes); b-- != planes; ) {
440518 struct i915_ggtt_view view;
....@@ -445,7 +523,7 @@
445523 GEM_BUG_ON(max_offset > max_pages);
446524 max_offset = max_pages - max_offset;
447525
448
- view.type = I915_GGTT_VIEW_ROTATED;
526
+ view.type = *t;
449527 view.rotated.plane[0] = *a;
450528 view.rotated.plane[1] = *b;
451529
....@@ -466,14 +544,23 @@
466544 goto out_object;
467545 }
468546
469
- if (vma->size != rotated_size(a, b) * PAGE_SIZE) {
547
+ if (view.type == I915_GGTT_VIEW_ROTATED &&
548
+ vma->size != rotated_size(a, b) * PAGE_SIZE) {
470549 pr_err("VMA is wrong size, expected %lu, found %llu\n",
471550 PAGE_SIZE * rotated_size(a, b), vma->size);
472551 err = -EINVAL;
473552 goto out_object;
474553 }
475554
476
- if (vma->pages->nents != rotated_size(a, b)) {
555
+ if (view.type == I915_GGTT_VIEW_REMAPPED &&
556
+ vma->size > rotated_size(a, b) * PAGE_SIZE) {
557
+ pr_err("VMA is wrong size, expected %lu, found %llu\n",
558
+ PAGE_SIZE * rotated_size(a, b), vma->size);
559
+ err = -EINVAL;
560
+ goto out_object;
561
+ }
562
+
563
+ if (vma->pages->nents > rotated_size(a, b)) {
477564 pr_err("sg table is wrong sizeo, expected %u, found %u nents\n",
478565 rotated_size(a, b), vma->pages->nents);
479566 err = -EINVAL;
....@@ -495,9 +582,14 @@
495582
496583 sg = vma->pages->sgl;
497584 for (n = 0; n < ARRAY_SIZE(view.rotated.plane); n++) {
498
- sg = assert_rotated(obj, &view.rotated, n, sg);
585
+ if (view.type == I915_GGTT_VIEW_ROTATED)
586
+ sg = assert_rotated(obj, &view.rotated, n, sg);
587
+ else
588
+ sg = assert_remapped(obj, &view.remapped, n, sg);
499589 if (IS_ERR(sg)) {
500
- pr_err("Inconsistent VMA pages for plane %d: [(%d, %d, %d, %d), (%d, %d, %d, %d)]\n", n,
590
+ pr_err("Inconsistent %s VMA pages for plane %d: [(%d, %d, %d, %d), (%d, %d, %d, %d)]\n",
591
+ view.type == I915_GGTT_VIEW_ROTATED ?
592
+ "rotated" : "remapped", n,
501593 view.rotated.plane[0].width,
502594 view.rotated.plane[0].height,
503595 view.rotated.plane[0].stride,
....@@ -512,9 +604,12 @@
512604 }
513605
514606 i915_vma_unpin(vma);
607
+
608
+ cond_resched();
515609 }
516610 }
517611 }
612
+ }
518613 }
519614
520615 out_object:
....@@ -531,7 +626,7 @@
531626 struct sgt_iter sgt;
532627 dma_addr_t dma;
533628
534
- for_each_sgt_dma(dma, sgt, vma->pages) {
629
+ for_each_sgt_daddr(dma, sgt, vma->pages) {
535630 dma_addr_t src;
536631
537632 if (!size) {
....@@ -602,8 +697,8 @@
602697
603698 static int igt_vma_partial(void *arg)
604699 {
605
- struct drm_i915_private *i915 = arg;
606
- struct i915_address_space *vm = &i915->ggtt.vm;
700
+ struct i915_ggtt *ggtt = arg;
701
+ struct i915_address_space *vm = &ggtt->vm;
607702 const unsigned int npages = 1021; /* prime! */
608703 struct drm_i915_gem_object *obj;
609704 const struct phase {
....@@ -621,7 +716,7 @@
621716 * we are returned the same VMA when we later request the same range.
622717 */
623718
624
- obj = i915_gem_object_create_internal(i915, npages*PAGE_SIZE);
719
+ obj = i915_gem_object_create_internal(vm->i915, npages * PAGE_SIZE);
625720 if (IS_ERR(obj))
626721 goto out;
627722
....@@ -666,11 +761,13 @@
666761
667762 i915_vma_unpin(vma);
668763 nvma++;
764
+
765
+ cond_resched();
669766 }
670767 }
671768
672769 count = 0;
673
- list_for_each_entry(vma, &obj->vma_list, obj_link)
770
+ list_for_each_entry(vma, &obj->vma.list, obj_link)
674771 count++;
675772 if (count != nvma) {
676773 pr_err("(%s) All partial vma were not recorded on the obj->vma_list: found %u, expected %u\n",
....@@ -699,7 +796,7 @@
699796 i915_vma_unpin(vma);
700797
701798 count = 0;
702
- list_for_each_entry(vma, &obj->vma_list, obj_link)
799
+ list_for_each_entry(vma, &obj->vma.list, obj_link)
703800 count++;
704801 if (count != nvma) {
705802 pr_err("(%s) allocated an extra full vma!\n", p->name);
....@@ -719,21 +816,174 @@
719816 static const struct i915_subtest tests[] = {
720817 SUBTEST(igt_vma_create),
721818 SUBTEST(igt_vma_pin1),
722
- SUBTEST(igt_vma_rotate),
819
+ SUBTEST(igt_vma_rotate_remap),
723820 SUBTEST(igt_vma_partial),
724821 };
725822 struct drm_i915_private *i915;
823
+ struct i915_ggtt *ggtt;
726824 int err;
727825
728826 i915 = mock_gem_device();
729827 if (!i915)
730828 return -ENOMEM;
731829
732
- mutex_lock(&i915->drm.struct_mutex);
733
- err = i915_subtests(tests, i915);
734
- mutex_unlock(&i915->drm.struct_mutex);
830
+ ggtt = kmalloc(sizeof(*ggtt), GFP_KERNEL);
831
+ if (!ggtt) {
832
+ err = -ENOMEM;
833
+ goto out_put;
834
+ }
835
+ mock_init_ggtt(i915, ggtt);
735836
736
- drm_dev_put(&i915->drm);
837
+ err = i915_subtests(tests, ggtt);
838
+
839
+ mock_device_flush(i915);
840
+ i915_gem_drain_freed_objects(i915);
841
+ mock_fini_ggtt(ggtt);
842
+ kfree(ggtt);
843
+out_put:
844
+ mock_destroy_device(i915);
737845 return err;
738846 }
739847
848
+static int igt_vma_remapped_gtt(void *arg)
849
+{
850
+ struct drm_i915_private *i915 = arg;
851
+ const struct intel_remapped_plane_info planes[] = {
852
+ { .width = 1, .height = 1, .stride = 1 },
853
+ { .width = 2, .height = 2, .stride = 2 },
854
+ { .width = 4, .height = 4, .stride = 4 },
855
+ { .width = 8, .height = 8, .stride = 8 },
856
+
857
+ { .width = 3, .height = 5, .stride = 3 },
858
+ { .width = 3, .height = 5, .stride = 4 },
859
+ { .width = 3, .height = 5, .stride = 5 },
860
+
861
+ { .width = 5, .height = 3, .stride = 5 },
862
+ { .width = 5, .height = 3, .stride = 7 },
863
+ { .width = 5, .height = 3, .stride = 9 },
864
+
865
+ { .width = 4, .height = 6, .stride = 6 },
866
+ { .width = 6, .height = 4, .stride = 6 },
867
+ { }
868
+ }, *p;
869
+ enum i915_ggtt_view_type types[] = {
870
+ I915_GGTT_VIEW_ROTATED,
871
+ I915_GGTT_VIEW_REMAPPED,
872
+ 0,
873
+ }, *t;
874
+ struct drm_i915_gem_object *obj;
875
+ intel_wakeref_t wakeref;
876
+ int err = 0;
877
+
878
+ obj = i915_gem_object_create_internal(i915, 10 * 10 * PAGE_SIZE);
879
+ if (IS_ERR(obj))
880
+ return PTR_ERR(obj);
881
+
882
+ wakeref = intel_runtime_pm_get(&i915->runtime_pm);
883
+
884
+ for (t = types; *t; t++) {
885
+ for (p = planes; p->width; p++) {
886
+ struct i915_ggtt_view view = {
887
+ .type = *t,
888
+ .rotated.plane[0] = *p,
889
+ };
890
+ struct i915_vma *vma;
891
+ u32 __iomem *map;
892
+ unsigned int x, y;
893
+ int err;
894
+
895
+ i915_gem_object_lock(obj, NULL);
896
+ err = i915_gem_object_set_to_gtt_domain(obj, true);
897
+ i915_gem_object_unlock(obj);
898
+ if (err)
899
+ goto out;
900
+
901
+ vma = i915_gem_object_ggtt_pin(obj, &view, 0, 0, PIN_MAPPABLE);
902
+ if (IS_ERR(vma)) {
903
+ err = PTR_ERR(vma);
904
+ goto out;
905
+ }
906
+
907
+ GEM_BUG_ON(vma->ggtt_view.type != *t);
908
+
909
+ map = i915_vma_pin_iomap(vma);
910
+ i915_vma_unpin(vma);
911
+ if (IS_ERR(map)) {
912
+ err = PTR_ERR(map);
913
+ goto out;
914
+ }
915
+
916
+ for (y = 0 ; y < p->height; y++) {
917
+ for (x = 0 ; x < p->width; x++) {
918
+ unsigned int offset;
919
+ u32 val = y << 16 | x;
920
+
921
+ if (*t == I915_GGTT_VIEW_ROTATED)
922
+ offset = (x * p->height + y) * PAGE_SIZE;
923
+ else
924
+ offset = (y * p->width + x) * PAGE_SIZE;
925
+
926
+ iowrite32(val, &map[offset / sizeof(*map)]);
927
+ }
928
+ }
929
+
930
+ i915_vma_unpin_iomap(vma);
931
+
932
+ vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE);
933
+ if (IS_ERR(vma)) {
934
+ err = PTR_ERR(vma);
935
+ goto out;
936
+ }
937
+
938
+ GEM_BUG_ON(vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL);
939
+
940
+ map = i915_vma_pin_iomap(vma);
941
+ i915_vma_unpin(vma);
942
+ if (IS_ERR(map)) {
943
+ err = PTR_ERR(map);
944
+ goto out;
945
+ }
946
+
947
+ for (y = 0 ; y < p->height; y++) {
948
+ for (x = 0 ; x < p->width; x++) {
949
+ unsigned int offset, src_idx;
950
+ u32 exp = y << 16 | x;
951
+ u32 val;
952
+
953
+ if (*t == I915_GGTT_VIEW_ROTATED)
954
+ src_idx = rotated_index(&view.rotated, 0, x, y);
955
+ else
956
+ src_idx = remapped_index(&view.remapped, 0, x, y);
957
+ offset = src_idx * PAGE_SIZE;
958
+
959
+ val = ioread32(&map[offset / sizeof(*map)]);
960
+ if (val != exp) {
961
+ pr_err("%s VMA write test failed, expected 0x%x, found 0x%x\n",
962
+ *t == I915_GGTT_VIEW_ROTATED ? "Rotated" : "Remapped",
963
+ val, exp);
964
+ i915_vma_unpin_iomap(vma);
965
+ goto out;
966
+ }
967
+ }
968
+ }
969
+ i915_vma_unpin_iomap(vma);
970
+
971
+ cond_resched();
972
+ }
973
+ }
974
+
975
+out:
976
+ intel_runtime_pm_put(&i915->runtime_pm, wakeref);
977
+ i915_gem_object_put(obj);
978
+
979
+ return err;
980
+}
981
+
982
+int i915_vma_live_selftests(struct drm_i915_private *i915)
983
+{
984
+ static const struct i915_subtest tests[] = {
985
+ SUBTEST(igt_vma_remapped_gtt),
986
+ };
987
+
988
+ return i915_subtests(tests, i915);
989
+}