summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/selftests
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/selftests')
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_active.c2
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_buddy.c789
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem.c20
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_gtt.c14
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_mock_selftests.h1
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_perf.c9
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_request.c8
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_vma.c3
-rw-r--r--drivers/gpu/drm/i915/selftests/igt_spinner.c16
-rw-r--r--drivers/gpu/drm/i915/selftests/intel_memory_region.c220
-rw-r--r--drivers/gpu/drm/i915/selftests/intel_uncore.c10
-rw-r--r--drivers/gpu/drm/i915/selftests/librapl.c10
-rw-r--r--drivers/gpu/drm/i915/selftests/librapl.h4
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_gem_device.c13
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_region.c70
15 files changed, 256 insertions, 933 deletions
diff --git a/drivers/gpu/drm/i915/selftests/i915_active.c b/drivers/gpu/drm/i915/selftests/i915_active.c
index 4002c984c2e0..61bf4560d8af 100644
--- a/drivers/gpu/drm/i915/selftests/i915_active.c
+++ b/drivers/gpu/drm/i915/selftests/i915_active.c
@@ -68,7 +68,7 @@ static struct live_active *__live_alloc(struct drm_i915_private *i915)
return NULL;
kref_init(&active->ref);
- i915_active_init(&active->base, __live_active, __live_retire);
+ i915_active_init(&active->base, __live_active, __live_retire, 0);
return active;
}
diff --git a/drivers/gpu/drm/i915/selftests/i915_buddy.c b/drivers/gpu/drm/i915/selftests/i915_buddy.c
deleted file mode 100644
index f0f5c4df8dbc..000000000000
--- a/drivers/gpu/drm/i915/selftests/i915_buddy.c
+++ /dev/null
@@ -1,789 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2019 Intel Corporation
- */
-
-#include <linux/prime_numbers.h>
-
-#include "../i915_selftest.h"
-#include "i915_random.h"
-
-static void __igt_dump_block(struct i915_buddy_mm *mm,
- struct i915_buddy_block *block,
- bool buddy)
-{
- pr_err("block info: header=%llx, state=%u, order=%d, offset=%llx size=%llx root=%s buddy=%s\n",
- block->header,
- i915_buddy_block_state(block),
- i915_buddy_block_order(block),
- i915_buddy_block_offset(block),
- i915_buddy_block_size(mm, block),
- yesno(!block->parent),
- yesno(buddy));
-}
-
-static void igt_dump_block(struct i915_buddy_mm *mm,
- struct i915_buddy_block *block)
-{
- struct i915_buddy_block *buddy;
-
- __igt_dump_block(mm, block, false);
-
- buddy = get_buddy(block);
- if (buddy)
- __igt_dump_block(mm, buddy, true);
-}
-
-static int igt_check_block(struct i915_buddy_mm *mm,
- struct i915_buddy_block *block)
-{
- struct i915_buddy_block *buddy;
- unsigned int block_state;
- u64 block_size;
- u64 offset;
- int err = 0;
-
- block_state = i915_buddy_block_state(block);
-
- if (block_state != I915_BUDDY_ALLOCATED &&
- block_state != I915_BUDDY_FREE &&
- block_state != I915_BUDDY_SPLIT) {
- pr_err("block state mismatch\n");
- err = -EINVAL;
- }
-
- block_size = i915_buddy_block_size(mm, block);
- offset = i915_buddy_block_offset(block);
-
- if (block_size < mm->chunk_size) {
- pr_err("block size smaller than min size\n");
- err = -EINVAL;
- }
-
- if (!is_power_of_2(block_size)) {
- pr_err("block size not power of two\n");
- err = -EINVAL;
- }
-
- if (!IS_ALIGNED(block_size, mm->chunk_size)) {
- pr_err("block size not aligned to min size\n");
- err = -EINVAL;
- }
-
- if (!IS_ALIGNED(offset, mm->chunk_size)) {
- pr_err("block offset not aligned to min size\n");
- err = -EINVAL;
- }
-
- if (!IS_ALIGNED(offset, block_size)) {
- pr_err("block offset not aligned to block size\n");
- err = -EINVAL;
- }
-
- buddy = get_buddy(block);
-
- if (!buddy && block->parent) {
- pr_err("buddy has gone fishing\n");
- err = -EINVAL;
- }
-
- if (buddy) {
- if (i915_buddy_block_offset(buddy) != (offset ^ block_size)) {
- pr_err("buddy has wrong offset\n");
- err = -EINVAL;
- }
-
- if (i915_buddy_block_size(mm, buddy) != block_size) {
- pr_err("buddy size mismatch\n");
- err = -EINVAL;
- }
-
- if (i915_buddy_block_state(buddy) == block_state &&
- block_state == I915_BUDDY_FREE) {
- pr_err("block and its buddy are free\n");
- err = -EINVAL;
- }
- }
-
- return err;
-}
-
-static int igt_check_blocks(struct i915_buddy_mm *mm,
- struct list_head *blocks,
- u64 expected_size,
- bool is_contiguous)
-{
- struct i915_buddy_block *block;
- struct i915_buddy_block *prev;
- u64 total;
- int err = 0;
-
- block = NULL;
- prev = NULL;
- total = 0;
-
- list_for_each_entry(block, blocks, link) {
- err = igt_check_block(mm, block);
-
- if (!i915_buddy_block_is_allocated(block)) {
- pr_err("block not allocated\n"),
- err = -EINVAL;
- }
-
- if (is_contiguous && prev) {
- u64 prev_block_size;
- u64 prev_offset;
- u64 offset;
-
- prev_offset = i915_buddy_block_offset(prev);
- prev_block_size = i915_buddy_block_size(mm, prev);
- offset = i915_buddy_block_offset(block);
-
- if (offset != (prev_offset + prev_block_size)) {
- pr_err("block offset mismatch\n");
- err = -EINVAL;
- }
- }
-
- if (err)
- break;
-
- total += i915_buddy_block_size(mm, block);
- prev = block;
- }
-
- if (!err) {
- if (total != expected_size) {
- pr_err("size mismatch, expected=%llx, found=%llx\n",
- expected_size, total);
- err = -EINVAL;
- }
- return err;
- }
-
- if (prev) {
- pr_err("prev block, dump:\n");
- igt_dump_block(mm, prev);
- }
-
- if (block) {
- pr_err("bad block, dump:\n");
- igt_dump_block(mm, block);
- }
-
- return err;
-}
-
-static int igt_check_mm(struct i915_buddy_mm *mm)
-{
- struct i915_buddy_block *root;
- struct i915_buddy_block *prev;
- unsigned int i;
- u64 total;
- int err = 0;
-
- if (!mm->n_roots) {
- pr_err("n_roots is zero\n");
- return -EINVAL;
- }
-
- if (mm->n_roots != hweight64(mm->size)) {
- pr_err("n_roots mismatch, n_roots=%u, expected=%lu\n",
- mm->n_roots, hweight64(mm->size));
- return -EINVAL;
- }
-
- root = NULL;
- prev = NULL;
- total = 0;
-
- for (i = 0; i < mm->n_roots; ++i) {
- struct i915_buddy_block *block;
- unsigned int order;
-
- root = mm->roots[i];
- if (!root) {
- pr_err("root(%u) is NULL\n", i);
- err = -EINVAL;
- break;
- }
-
- err = igt_check_block(mm, root);
-
- if (!i915_buddy_block_is_free(root)) {
- pr_err("root not free\n");
- err = -EINVAL;
- }
-
- order = i915_buddy_block_order(root);
-
- if (!i) {
- if (order != mm->max_order) {
- pr_err("max order root missing\n");
- err = -EINVAL;
- }
- }
-
- if (prev) {
- u64 prev_block_size;
- u64 prev_offset;
- u64 offset;
-
- prev_offset = i915_buddy_block_offset(prev);
- prev_block_size = i915_buddy_block_size(mm, prev);
- offset = i915_buddy_block_offset(root);
-
- if (offset != (prev_offset + prev_block_size)) {
- pr_err("root offset mismatch\n");
- err = -EINVAL;
- }
- }
-
- block = list_first_entry_or_null(&mm->free_list[order],
- struct i915_buddy_block,
- link);
- if (block != root) {
- pr_err("root mismatch at order=%u\n", order);
- err = -EINVAL;
- }
-
- if (err)
- break;
-
- prev = root;
- total += i915_buddy_block_size(mm, root);
- }
-
- if (!err) {
- if (total != mm->size) {
- pr_err("expected mm size=%llx, found=%llx\n", mm->size,
- total);
- err = -EINVAL;
- }
- return err;
- }
-
- if (prev) {
- pr_err("prev root(%u), dump:\n", i - 1);
- igt_dump_block(mm, prev);
- }
-
- if (root) {
- pr_err("bad root(%u), dump:\n", i);
- igt_dump_block(mm, root);
- }
-
- return err;
-}
-
-static void igt_mm_config(u64 *size, u64 *chunk_size)
-{
- I915_RND_STATE(prng);
- u32 s, ms;
-
- /* Nothing fancy, just try to get an interesting bit pattern */
-
- prandom_seed_state(&prng, i915_selftest.random_seed);
-
- /* Let size be a random number of pages up to 8 GB (2M pages) */
- s = 1 + i915_prandom_u32_max_state((BIT(33 - 12)) - 1, &prng);
- /* Let the chunk size be a random power of 2 less than size */
- ms = BIT(i915_prandom_u32_max_state(ilog2(s), &prng));
- /* Round size down to the chunk size */
- s &= -ms;
-
- /* Convert from pages to bytes */
- *chunk_size = (u64)ms << 12;
- *size = (u64)s << 12;
-}
-
-static int igt_buddy_alloc_smoke(void *arg)
-{
- struct i915_buddy_mm mm;
- IGT_TIMEOUT(end_time);
- I915_RND_STATE(prng);
- u64 chunk_size;
- u64 mm_size;
- int *order;
- int err, i;
-
- igt_mm_config(&mm_size, &chunk_size);
-
- pr_info("buddy_init with size=%llx, chunk_size=%llx\n", mm_size, chunk_size);
-
- err = i915_buddy_init(&mm, mm_size, chunk_size);
- if (err) {
- pr_err("buddy_init failed(%d)\n", err);
- return err;
- }
-
- order = i915_random_order(mm.max_order + 1, &prng);
- if (!order)
- goto out_fini;
-
- for (i = 0; i <= mm.max_order; ++i) {
- struct i915_buddy_block *block;
- int max_order = order[i];
- bool timeout = false;
- LIST_HEAD(blocks);
- int order;
- u64 total;
-
- err = igt_check_mm(&mm);
- if (err) {
- pr_err("pre-mm check failed, abort\n");
- break;
- }
-
- pr_info("filling from max_order=%u\n", max_order);
-
- order = max_order;
- total = 0;
-
- do {
-retry:
- block = i915_buddy_alloc(&mm, order);
- if (IS_ERR(block)) {
- err = PTR_ERR(block);
- if (err == -ENOMEM) {
- pr_info("buddy_alloc hit -ENOMEM with order=%d\n",
- order);
- } else {
- if (order--) {
- err = 0;
- goto retry;
- }
-
- pr_err("buddy_alloc with order=%d failed(%d)\n",
- order, err);
- }
-
- break;
- }
-
- list_add_tail(&block->link, &blocks);
-
- if (i915_buddy_block_order(block) != order) {
- pr_err("buddy_alloc order mismatch\n");
- err = -EINVAL;
- break;
- }
-
- total += i915_buddy_block_size(&mm, block);
-
- if (__igt_timeout(end_time, NULL)) {
- timeout = true;
- break;
- }
- } while (total < mm.size);
-
- if (!err)
- err = igt_check_blocks(&mm, &blocks, total, false);
-
- i915_buddy_free_list(&mm, &blocks);
-
- if (!err) {
- err = igt_check_mm(&mm);
- if (err)
- pr_err("post-mm check failed\n");
- }
-
- if (err || timeout)
- break;
-
- cond_resched();
- }
-
- if (err == -ENOMEM)
- err = 0;
-
- kfree(order);
-out_fini:
- i915_buddy_fini(&mm);
-
- return err;
-}
-
-static int igt_buddy_alloc_pessimistic(void *arg)
-{
- const unsigned int max_order = 16;
- struct i915_buddy_block *block, *bn;
- struct i915_buddy_mm mm;
- unsigned int order;
- LIST_HEAD(blocks);
- int err;
-
- /*
- * Create a pot-sized mm, then allocate one of each possible
- * order within. This should leave the mm with exactly one
- * page left.
- */
-
- err = i915_buddy_init(&mm, PAGE_SIZE << max_order, PAGE_SIZE);
- if (err) {
- pr_err("buddy_init failed(%d)\n", err);
- return err;
- }
- GEM_BUG_ON(mm.max_order != max_order);
-
- for (order = 0; order < max_order; order++) {
- block = i915_buddy_alloc(&mm, order);
- if (IS_ERR(block)) {
- pr_info("buddy_alloc hit -ENOMEM with order=%d\n",
- order);
- err = PTR_ERR(block);
- goto err;
- }
-
- list_add_tail(&block->link, &blocks);
- }
-
- /* And now the last remaining block available */
- block = i915_buddy_alloc(&mm, 0);
- if (IS_ERR(block)) {
- pr_info("buddy_alloc hit -ENOMEM on final alloc\n");
- err = PTR_ERR(block);
- goto err;
- }
- list_add_tail(&block->link, &blocks);
-
- /* Should be completely full! */
- for (order = max_order; order--; ) {
- block = i915_buddy_alloc(&mm, order);
- if (!IS_ERR(block)) {
- pr_info("buddy_alloc unexpectedly succeeded at order %d, it should be full!",
- order);
- list_add_tail(&block->link, &blocks);
- err = -EINVAL;
- goto err;
- }
- }
-
- block = list_last_entry(&blocks, typeof(*block), link);
- list_del(&block->link);
- i915_buddy_free(&mm, block);
-
- /* As we free in increasing size, we make available larger blocks */
- order = 1;
- list_for_each_entry_safe(block, bn, &blocks, link) {
- list_del(&block->link);
- i915_buddy_free(&mm, block);
-
- block = i915_buddy_alloc(&mm, order);
- if (IS_ERR(block)) {
- pr_info("buddy_alloc (realloc) hit -ENOMEM with order=%d\n",
- order);
- err = PTR_ERR(block);
- goto err;
- }
- i915_buddy_free(&mm, block);
- order++;
- }
-
- /* To confirm, now the whole mm should be available */
- block = i915_buddy_alloc(&mm, max_order);
- if (IS_ERR(block)) {
- pr_info("buddy_alloc (realloc) hit -ENOMEM with order=%d\n",
- max_order);
- err = PTR_ERR(block);
- goto err;
- }
- i915_buddy_free(&mm, block);
-
-err:
- i915_buddy_free_list(&mm, &blocks);
- i915_buddy_fini(&mm);
- return err;
-}
-
-static int igt_buddy_alloc_optimistic(void *arg)
-{
- const int max_order = 16;
- struct i915_buddy_block *block;
- struct i915_buddy_mm mm;
- LIST_HEAD(blocks);
- int order;
- int err;
-
- /*
- * Create a mm with one block of each order available, and
- * try to allocate them all.
- */
-
- err = i915_buddy_init(&mm,
- PAGE_SIZE * ((1 << (max_order + 1)) - 1),
- PAGE_SIZE);
- if (err) {
- pr_err("buddy_init failed(%d)\n", err);
- return err;
- }
- GEM_BUG_ON(mm.max_order != max_order);
-
- for (order = 0; order <= max_order; order++) {
- block = i915_buddy_alloc(&mm, order);
- if (IS_ERR(block)) {
- pr_info("buddy_alloc hit -ENOMEM with order=%d\n",
- order);
- err = PTR_ERR(block);
- goto err;
- }
-
- list_add_tail(&block->link, &blocks);
- }
-
- /* Should be completely full! */
- block = i915_buddy_alloc(&mm, 0);
- if (!IS_ERR(block)) {
- pr_info("buddy_alloc unexpectedly succeeded, it should be full!");
- list_add_tail(&block->link, &blocks);
- err = -EINVAL;
- goto err;
- }
-
-err:
- i915_buddy_free_list(&mm, &blocks);
- i915_buddy_fini(&mm);
- return err;
-}
-
-static int igt_buddy_alloc_pathological(void *arg)
-{
- const int max_order = 16;
- struct i915_buddy_block *block;
- struct i915_buddy_mm mm;
- LIST_HEAD(blocks);
- LIST_HEAD(holes);
- int order, top;
- int err;
-
- /*
- * Create a pot-sized mm, then allocate one of each possible
- * order within. This should leave the mm with exactly one
- * page left. Free the largest block, then whittle down again.
- * Eventually we will have a fully 50% fragmented mm.
- */
-
- err = i915_buddy_init(&mm, PAGE_SIZE << max_order, PAGE_SIZE);
- if (err) {
- pr_err("buddy_init failed(%d)\n", err);
- return err;
- }
- GEM_BUG_ON(mm.max_order != max_order);
-
- for (top = max_order; top; top--) {
- /* Make room by freeing the largest allocated block */
- block = list_first_entry_or_null(&blocks, typeof(*block), link);
- if (block) {
- list_del(&block->link);
- i915_buddy_free(&mm, block);
- }
-
- for (order = top; order--; ) {
- block = i915_buddy_alloc(&mm, order);
- if (IS_ERR(block)) {
- pr_info("buddy_alloc hit -ENOMEM with order=%d, top=%d\n",
- order, top);
- err = PTR_ERR(block);
- goto err;
- }
- list_add_tail(&block->link, &blocks);
- }
-
- /* There should be one final page for this sub-allocation */
- block = i915_buddy_alloc(&mm, 0);
- if (IS_ERR(block)) {
- pr_info("buddy_alloc hit -ENOMEM for hole\n");
- err = PTR_ERR(block);
- goto err;
- }
- list_add_tail(&block->link, &holes);
-
- block = i915_buddy_alloc(&mm, top);
- if (!IS_ERR(block)) {
- pr_info("buddy_alloc unexpectedly succeeded at top-order %d/%d, it should be full!",
- top, max_order);
- list_add_tail(&block->link, &blocks);
- err = -EINVAL;
- goto err;
- }
- }
-
- i915_buddy_free_list(&mm, &holes);
-
- /* Nothing larger than blocks of chunk_size now available */
- for (order = 1; order <= max_order; order++) {
- block = i915_buddy_alloc(&mm, order);
- if (!IS_ERR(block)) {
- pr_info("buddy_alloc unexpectedly succeeded at order %d, it should be full!",
- order);
- list_add_tail(&block->link, &blocks);
- err = -EINVAL;
- goto err;
- }
- }
-
-err:
- list_splice_tail(&holes, &blocks);
- i915_buddy_free_list(&mm, &blocks);
- i915_buddy_fini(&mm);
- return err;
-}
-
-static int igt_buddy_alloc_range(void *arg)
-{
- struct i915_buddy_mm mm;
- unsigned long page_num;
- LIST_HEAD(blocks);
- u64 chunk_size;
- u64 offset;
- u64 size;
- u64 rem;
- int err;
-
- igt_mm_config(&size, &chunk_size);
-
- pr_info("buddy_init with size=%llx, chunk_size=%llx\n", size, chunk_size);
-
- err = i915_buddy_init(&mm, size, chunk_size);
- if (err) {
- pr_err("buddy_init failed(%d)\n", err);
- return err;
- }
-
- err = igt_check_mm(&mm);
- if (err) {
- pr_err("pre-mm check failed, abort, abort, abort!\n");
- goto err_fini;
- }
-
- rem = mm.size;
- offset = 0;
-
- for_each_prime_number_from(page_num, 1, ULONG_MAX - 1) {
- struct i915_buddy_block *block;
- LIST_HEAD(tmp);
-
- size = min(page_num * mm.chunk_size, rem);
-
- err = i915_buddy_alloc_range(&mm, &tmp, offset, size);
- if (err) {
- if (err == -ENOMEM) {
- pr_info("alloc_range hit -ENOMEM with size=%llx\n",
- size);
- } else {
- pr_err("alloc_range with offset=%llx, size=%llx failed(%d)\n",
- offset, size, err);
- }
-
- break;
- }
-
- block = list_first_entry_or_null(&tmp,
- struct i915_buddy_block,
- link);
- if (!block) {
- pr_err("alloc_range has no blocks\n");
- err = -EINVAL;
- break;
- }
-
- if (i915_buddy_block_offset(block) != offset) {
- pr_err("alloc_range start offset mismatch, found=%llx, expected=%llx\n",
- i915_buddy_block_offset(block), offset);
- err = -EINVAL;
- }
-
- if (!err)
- err = igt_check_blocks(&mm, &tmp, size, true);
-
- list_splice_tail(&tmp, &blocks);
-
- if (err)
- break;
-
- offset += size;
-
- rem -= size;
- if (!rem)
- break;
-
- cond_resched();
- }
-
- if (err == -ENOMEM)
- err = 0;
-
- i915_buddy_free_list(&mm, &blocks);
-
- if (!err) {
- err = igt_check_mm(&mm);
- if (err)
- pr_err("post-mm check failed\n");
- }
-
-err_fini:
- i915_buddy_fini(&mm);
-
- return err;
-}
-
-static int igt_buddy_alloc_limit(void *arg)
-{
- struct i915_buddy_block *block;
- struct i915_buddy_mm mm;
- const u64 size = U64_MAX;
- int err;
-
- err = i915_buddy_init(&mm, size, PAGE_SIZE);
- if (err)
- return err;
-
- if (mm.max_order != I915_BUDDY_MAX_ORDER) {
- pr_err("mm.max_order(%d) != %d\n",
- mm.max_order, I915_BUDDY_MAX_ORDER);
- err = -EINVAL;
- goto out_fini;
- }
-
- block = i915_buddy_alloc(&mm, mm.max_order);
- if (IS_ERR(block)) {
- err = PTR_ERR(block);
- goto out_fini;
- }
-
- if (i915_buddy_block_order(block) != mm.max_order) {
- pr_err("block order(%d) != %d\n",
- i915_buddy_block_order(block), mm.max_order);
- err = -EINVAL;
- goto out_free;
- }
-
- if (i915_buddy_block_size(&mm, block) !=
- BIT_ULL(mm.max_order) * PAGE_SIZE) {
- pr_err("block size(%llu) != %llu\n",
- i915_buddy_block_size(&mm, block),
- BIT_ULL(mm.max_order) * PAGE_SIZE);
- err = -EINVAL;
- goto out_free;
- }
-
-out_free:
- i915_buddy_free(&mm, block);
-out_fini:
- i915_buddy_fini(&mm);
- return err;
-}
-
-int i915_buddy_mock_selftests(void)
-{
- static const struct i915_subtest tests[] = {
- SUBTEST(igt_buddy_alloc_pessimistic),
- SUBTEST(igt_buddy_alloc_optimistic),
- SUBTEST(igt_buddy_alloc_pathological),
- SUBTEST(igt_buddy_alloc_smoke),
- SUBTEST(igt_buddy_alloc_range),
- SUBTEST(igt_buddy_alloc_limit),
- };
-
- return i915_subtests(tests, NULL);
-}
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem.c b/drivers/gpu/drm/i915/selftests/i915_gem.c
index dc394fb7ccfa..152d9ab135b1 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem.c
@@ -87,14 +87,14 @@ static void simulate_hibernate(struct drm_i915_private *i915)
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
}
-static int pm_prepare(struct drm_i915_private *i915)
+static int igt_pm_prepare(struct drm_i915_private *i915)
{
i915_gem_suspend(i915);
return 0;
}
-static void pm_suspend(struct drm_i915_private *i915)
+static void igt_pm_suspend(struct drm_i915_private *i915)
{
intel_wakeref_t wakeref;
@@ -104,7 +104,7 @@ static void pm_suspend(struct drm_i915_private *i915)
}
}
-static void pm_hibernate(struct drm_i915_private *i915)
+static void igt_pm_hibernate(struct drm_i915_private *i915)
{
intel_wakeref_t wakeref;
@@ -116,7 +116,7 @@ static void pm_hibernate(struct drm_i915_private *i915)
}
}
-static void pm_resume(struct drm_i915_private *i915)
+static void igt_pm_resume(struct drm_i915_private *i915)
{
intel_wakeref_t wakeref;
@@ -148,16 +148,16 @@ static int igt_gem_suspend(void *arg)
if (err)
goto out;
- err = pm_prepare(i915);
+ err = igt_pm_prepare(i915);
if (err)
goto out;
- pm_suspend(i915);
+ igt_pm_suspend(i915);
/* Here be dragons! Note that with S3RST any S3 may become S4! */
simulate_hibernate(i915);
- pm_resume(i915);
+ igt_pm_resume(i915);
err = switch_to_context(ctx);
out:
@@ -183,16 +183,16 @@ static int igt_gem_hibernate(void *arg)
if (err)
goto out;
- err = pm_prepare(i915);
+ err = igt_pm_prepare(i915);
if (err)
goto out;
- pm_hibernate(i915);
+ igt_pm_hibernate(i915);
/* Here be dragons! */
simulate_hibernate(i915);
- pm_resume(i915);
+ igt_pm_resume(i915);
err = switch_to_context(ctx);
out:
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 45c6c0107c7c..f843a5040706 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -186,7 +186,7 @@ retry:
if (err)
goto err_ppgtt_cleanup;
- err = i915_vm_pin_pt_stash(&ppgtt->vm, &stash);
+ err = i915_vm_map_pt_stash(&ppgtt->vm, &stash);
if (err) {
i915_vm_free_pt_stash(&ppgtt->vm, &stash);
goto err_ppgtt_cleanup;
@@ -208,7 +208,7 @@ retry:
if (err)
goto err_ppgtt_cleanup;
- err = i915_vm_pin_pt_stash(&ppgtt->vm, &stash);
+ err = i915_vm_map_pt_stash(&ppgtt->vm, &stash);
if (err) {
i915_vm_free_pt_stash(&ppgtt->vm, &stash);
goto err_ppgtt_cleanup;
@@ -325,11 +325,10 @@ retry:
BIT_ULL(size)))
goto alloc_vm_end;
- err = i915_vm_pin_pt_stash(vm, &stash);
+ err = i915_vm_map_pt_stash(vm, &stash);
if (!err)
vm->allocate_va_range(vm, &stash,
addr, BIT_ULL(size));
-
i915_vm_free_pt_stash(vm, &stash);
alloc_vm_end:
if (err == -EDEADLK) {
@@ -1885,9 +1884,9 @@ static int igt_cs_tlb(void *arg)
u32 *cs = batch + i * 64 / sizeof(*cs);
u64 addr = (vm->total - PAGE_SIZE) + i * sizeof(u32);
- GEM_BUG_ON(INTEL_GEN(i915) < 6);
+ GEM_BUG_ON(GRAPHICS_VER(i915) < 6);
cs[0] = MI_STORE_DWORD_IMM_GEN4;
- if (INTEL_GEN(i915) >= 8) {
+ if (GRAPHICS_VER(i915) >= 8) {
cs[1] = lower_32_bits(addr);
cs[2] = upper_32_bits(addr);
cs[3] = i;
@@ -1968,10 +1967,9 @@ retry:
if (err)
goto end_ww;
- err = i915_vm_pin_pt_stash(vm, &stash);
+ err = i915_vm_map_pt_stash(vm, &stash);
if (!err)
vm->allocate_va_range(vm, &stash, offset, chunk_size);
-
i915_vm_free_pt_stash(vm, &stash);
end_ww:
if (err == -EDEADLK) {
diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
index 3db34d3eea58..34e5caf38093 100644
--- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
@@ -33,5 +33,4 @@ selftest(evict, i915_gem_evict_mock_selftests)
selftest(gtt, i915_gem_gtt_mock_selftests)
selftest(hugepages, i915_gem_huge_page_mock_selftests)
selftest(contexts, i915_gem_context_mock_selftests)
-selftest(buddy, i915_buddy_mock_selftests)
selftest(memory_region, intel_memory_region_mock_selftests)
diff --git a/drivers/gpu/drm/i915/selftests/i915_perf.c b/drivers/gpu/drm/i915/selftests/i915_perf.c
index e9d86dab8677..9e9a6cb1d9e5 100644
--- a/drivers/gpu/drm/i915/selftests/i915_perf.c
+++ b/drivers/gpu/drm/i915/selftests/i915_perf.c
@@ -98,7 +98,7 @@ test_stream(struct i915_perf *perf)
I915_ENGINE_CLASS_RENDER,
0),
.sample_flags = SAMPLE_OA_REPORT,
- .oa_format = IS_GEN(perf->i915, 12) ?
+ .oa_format = GRAPHICS_VER(perf->i915) == 12 ?
I915_OA_FORMAT_A32u40_A4u32_B8_C8 : I915_OA_FORMAT_C4_B8,
};
struct i915_perf_stream *stream;
@@ -162,7 +162,7 @@ static int write_timestamp(struct i915_request *rq, int slot)
return PTR_ERR(cs);
len = 5;
- if (INTEL_GEN(rq->engine->i915) >= 8)
+ if (GRAPHICS_VER(rq->engine->i915) >= 8)
len++;
*cs++ = GFX_OP_PIPE_CONTROL(len);
@@ -307,7 +307,7 @@ static int live_noa_gpr(void *arg)
}
/* Poison the ce->vm so we detect writes not to the GGTT gt->scratch */
- scratch = kmap(__px_page(ce->vm->scratch[0]));
+ scratch = __px_vaddr(ce->vm->scratch[0]);
memset(scratch, POISON_FREE, PAGE_SIZE);
rq = intel_context_create_request(ce);
@@ -363,7 +363,7 @@ static int live_noa_gpr(void *arg)
}
cmd = MI_STORE_REGISTER_MEM;
- if (INTEL_GEN(i915) >= 8)
+ if (GRAPHICS_VER(i915) >= 8)
cmd++;
cmd |= MI_USE_GGTT;
@@ -405,7 +405,6 @@ static int live_noa_gpr(void *arg)
out_rq:
i915_request_put(rq);
out_ce:
- kunmap(__px_page(ce->vm->scratch[0]));
intel_context_put(ce);
out:
stream_destroy(stream);
diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c
index eae0abd614cb..bd5c96a77ba3 100644
--- a/drivers/gpu/drm/i915/selftests/i915_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_request.c
@@ -963,7 +963,7 @@ out_batch:
static struct i915_vma *recursive_batch(struct drm_i915_private *i915)
{
struct drm_i915_gem_object *obj;
- const int gen = INTEL_GEN(i915);
+ const int ver = GRAPHICS_VER(i915);
struct i915_vma *vma;
u32 *cmd;
int err;
@@ -988,11 +988,11 @@ static struct i915_vma *recursive_batch(struct drm_i915_private *i915)
goto err;
}
- if (gen >= 8) {
+ if (ver >= 8) {
*cmd++ = MI_BATCH_BUFFER_START | 1 << 8 | 1;
*cmd++ = lower_32_bits(vma->node.start);
*cmd++ = upper_32_bits(vma->node.start);
- } else if (gen >= 6) {
+ } else if (ver >= 6) {
*cmd++ = MI_BATCH_BUFFER_START | 1 << 8;
*cmd++ = lower_32_bits(vma->node.start);
} else {
@@ -2482,7 +2482,7 @@ static int perf_request_latency(void *arg)
struct pm_qos_request qos;
int err = 0;
- if (INTEL_GEN(i915) < 8) /* per-engine CS timestamp, semaphores */
+ if (GRAPHICS_VER(i915) < 8) /* per-engine CS timestamp, semaphores */
return 0;
cpu_latency_qos_add_request(&qos, 0); /* disable cstates */
diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
index 5fe7b80ca0bd..dd0607254a95 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -967,6 +967,9 @@ static int igt_vma_remapped_gtt(void *arg)
intel_wakeref_t wakeref;
int err = 0;
+ if (!i915_ggtt_has_aperture(&i915->ggtt))
+ return 0;
+
obj = i915_gem_object_create_internal(i915, 10 * 10 * PAGE_SIZE);
if (IS_ERR(obj))
return PTR_ERR(obj);
diff --git a/drivers/gpu/drm/i915/selftests/igt_spinner.c b/drivers/gpu/drm/i915/selftests/igt_spinner.c
index cfbbe415b57c..24d87d0fc747 100644
--- a/drivers/gpu/drm/i915/selftests/igt_spinner.c
+++ b/drivers/gpu/drm/i915/selftests/igt_spinner.c
@@ -94,9 +94,9 @@ int igt_spinner_pin(struct igt_spinner *spin,
}
if (!spin->batch) {
- unsigned int mode =
- i915_coherent_map_type(spin->gt->i915);
+ unsigned int mode;
+ mode = i915_coherent_map_type(spin->gt->i915, spin->obj, false);
vaddr = igt_spinner_pin_obj(ce, ww, spin->obj, mode, &spin->batch_vma);
if (IS_ERR(vaddr))
return PTR_ERR(vaddr);
@@ -174,15 +174,15 @@ igt_spinner_create_request(struct igt_spinner *spin,
batch = spin->batch;
- if (INTEL_GEN(rq->engine->i915) >= 8) {
+ if (GRAPHICS_VER(rq->engine->i915) >= 8) {
*batch++ = MI_STORE_DWORD_IMM_GEN4;
*batch++ = lower_32_bits(hws_address(hws, rq));
*batch++ = upper_32_bits(hws_address(hws, rq));
- } else if (INTEL_GEN(rq->engine->i915) >= 6) {
+ } else if (GRAPHICS_VER(rq->engine->i915) >= 6) {
*batch++ = MI_STORE_DWORD_IMM_GEN4;
*batch++ = 0;
*batch++ = hws_address(hws, rq);
- } else if (INTEL_GEN(rq->engine->i915) >= 4) {
+ } else if (GRAPHICS_VER(rq->engine->i915) >= 4) {
*batch++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
*batch++ = 0;
*batch++ = hws_address(hws, rq);
@@ -194,11 +194,11 @@ igt_spinner_create_request(struct igt_spinner *spin,
*batch++ = arbitration_command;
- if (INTEL_GEN(rq->engine->i915) >= 8)
+ if (GRAPHICS_VER(rq->engine->i915) >= 8)
*batch++ = MI_BATCH_BUFFER_START | BIT(8) | 1;
else if (IS_HASWELL(rq->engine->i915))
*batch++ = MI_BATCH_BUFFER_START | MI_BATCH_PPGTT_HSW;
- else if (INTEL_GEN(rq->engine->i915) >= 6)
+ else if (GRAPHICS_VER(rq->engine->i915) >= 6)
*batch++ = MI_BATCH_BUFFER_START;
else
*batch++ = MI_BATCH_BUFFER_START | MI_BATCH_GTT;
@@ -216,7 +216,7 @@ igt_spinner_create_request(struct igt_spinner *spin,
}
flags = 0;
- if (INTEL_GEN(rq->engine->i915) <= 5)
+ if (GRAPHICS_VER(rq->engine->i915) <= 5)
flags |= I915_DISPATCH_SECURE;
err = engine->emit_bb_start(rq, vma->node.start, PAGE_SIZE, flags);
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index a5fc0bf3feb9..c85d516b85cd 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -57,9 +57,10 @@ static int igt_mock_fill(void *arg)
LIST_HEAD(objects);
int err = 0;
- page_size = mem->mm.chunk_size;
- max_pages = div64_u64(total, page_size);
+ page_size = mem->chunk_size;
rem = total;
+retry:
+ max_pages = div64_u64(rem, page_size);
for_each_prime_number_from(page_num, 1, max_pages) {
resource_size_t size = page_num * page_size;
@@ -85,6 +86,11 @@ static int igt_mock_fill(void *arg)
err = 0;
if (err == -ENXIO) {
if (page_num * page_size <= rem) {
+ if (mem->is_range_manager && max_pages > 1) {
+ max_pages >>= 1;
+ goto retry;
+ }
+
pr_err("%s failed, space still left in region\n",
__func__);
err = -EINVAL;
@@ -199,12 +205,18 @@ static int igt_mock_reserve(void *arg)
do {
u32 size = i915_prandom_u32_max_state(cur_avail, &prng);
+retry:
size = max_t(u32, round_up(size, PAGE_SIZE), PAGE_SIZE);
obj = igt_object_create(mem, &objects, size, 0);
if (IS_ERR(obj)) {
- if (PTR_ERR(obj) == -ENXIO)
+ if (PTR_ERR(obj) == -ENXIO) {
+ if (mem->is_range_manager &&
+ size > mem->chunk_size) {
+ size >>= 1;
+ goto retry;
+ }
break;
-
+ }
err = PTR_ERR(obj);
goto out_close;
}
@@ -220,7 +232,7 @@ static int igt_mock_reserve(void *arg)
out_close:
kfree(order);
close_objects(mem, &objects);
- i915_buddy_free_list(&mem->mm, &mem->reserved);
+ intel_memory_region_unreserve(mem);
return err;
}
@@ -240,7 +252,7 @@ static int igt_mock_contiguous(void *arg)
total = resource_size(&mem->region);
/* Min size */
- obj = igt_object_create(mem, &objects, mem->mm.chunk_size,
+ obj = igt_object_create(mem, &objects, mem->chunk_size,
I915_BO_ALLOC_CONTIGUOUS);
if (IS_ERR(obj))
return PTR_ERR(obj);
@@ -321,14 +333,16 @@ static int igt_mock_contiguous(void *arg)
min = target;
target = total >> 1;
- /* Make sure we can still allocate all the fragmented space */
- obj = igt_object_create(mem, &objects, target, 0);
- if (IS_ERR(obj)) {
- err = PTR_ERR(obj);
- goto err_close_objects;
- }
+ if (!mem->is_range_manager) {
+ /* Make sure we can still allocate all the fragmented space */
+ obj = igt_object_create(mem, &objects, target, 0);
+ if (IS_ERR(obj)) {
+ err = PTR_ERR(obj);
+ goto err_close_objects;
+ }
- igt_object_release(obj);
+ igt_object_release(obj);
+ }
/*
* Even though we have enough free space, we don't have a big enough
@@ -348,7 +362,7 @@ static int igt_mock_contiguous(void *arg)
}
target >>= 1;
- } while (target >= mem->mm.chunk_size);
+ } while (target >= mem->chunk_size);
err_close_objects:
list_splice_tail(&holes, &objects);
@@ -368,7 +382,7 @@ static int igt_mock_splintered_region(void *arg)
/*
* Sanity check we can still allocate everything even if the
- * mm.max_order != mm.size. i.e our starting address space size is not a
+ * max_order != mm.size. i.e our starting address space size is not a
* power-of-two.
*/
@@ -377,17 +391,10 @@ static int igt_mock_splintered_region(void *arg)
if (IS_ERR(mem))
return PTR_ERR(mem);
- if (mem->mm.size != size) {
- pr_err("%s size mismatch(%llu != %llu)\n",
- __func__, mem->mm.size, size);
- err = -EINVAL;
- goto out_put;
- }
-
expected_order = get_order(rounddown_pow_of_two(size));
- if (mem->mm.max_order != expected_order) {
+ if (mem->max_order != expected_order) {
pr_err("%s order mismatch(%u != %u)\n",
- __func__, mem->mm.max_order, expected_order);
+ __func__, mem->max_order, expected_order);
err = -EINVAL;
goto out_put;
}
@@ -408,12 +415,15 @@ static int igt_mock_splintered_region(void *arg)
* sure that does indeed hold true.
*/
- obj = igt_object_create(mem, &objects, size, I915_BO_ALLOC_CONTIGUOUS);
- if (!IS_ERR(obj)) {
- pr_err("%s too large contiguous allocation was not rejected\n",
- __func__);
- err = -EINVAL;
- goto out_close;
+ if (!mem->is_range_manager) {
+ obj = igt_object_create(mem, &objects, size,
+ I915_BO_ALLOC_CONTIGUOUS);
+ if (!IS_ERR(obj)) {
+ pr_err("%s too large contiguous allocation was not rejected\n",
+ __func__);
+ err = -EINVAL;
+ goto out_close;
+ }
}
obj = igt_object_create(mem, &objects, rounddown_pow_of_two(size),
@@ -432,68 +442,6 @@ out_put:
return err;
}
-#ifndef SZ_8G
-#define SZ_8G BIT_ULL(33)
-#endif
-
-static int igt_mock_max_segment(void *arg)
-{
- const unsigned int max_segment = i915_sg_segment_size();
- struct intel_memory_region *mem = arg;
- struct drm_i915_private *i915 = mem->i915;
- struct drm_i915_gem_object *obj;
- struct i915_buddy_block *block;
- struct scatterlist *sg;
- LIST_HEAD(objects);
- u64 size;
- int err = 0;
-
- /*
- * While we may create very large contiguous blocks, we may need
- * to break those down for consumption elsewhere. In particular,
- * dma-mapping with scatterlist elements have an implicit limit of
- * UINT_MAX on each element.
- */
-
- size = SZ_8G;
- mem = mock_region_create(i915, 0, size, PAGE_SIZE, 0);
- if (IS_ERR(mem))
- return PTR_ERR(mem);
-
- obj = igt_object_create(mem, &objects, size, 0);
- if (IS_ERR(obj)) {
- err = PTR_ERR(obj);
- goto out_put;
- }
-
- size = 0;
- list_for_each_entry(block, &obj->mm.blocks, link) {
- if (i915_buddy_block_size(&mem->mm, block) > size)
- size = i915_buddy_block_size(&mem->mm, block);
- }
- if (size < max_segment) {
- pr_err("%s: Failed to create a huge contiguous block [> %u], largest block %lld\n",
- __func__, max_segment, size);
- err = -EINVAL;
- goto out_close;
- }
-
- for (sg = obj->mm.pages->sgl; sg; sg = sg_next(sg)) {
- if (sg->length > max_segment) {
- pr_err("%s: Created an oversized scatterlist entry, %u > %u\n",
- __func__, sg->length, max_segment);
- err = -EINVAL;
- goto out_close;
- }
- }
-
-out_close:
- close_objects(mem, &objects);
-out_put:
- intel_memory_region_put(mem);
- return err;
-}
-
static int igt_gpu_write_dw(struct intel_context *ce,
struct i915_vma *vma,
u32 dword,
@@ -513,7 +461,7 @@ static int igt_cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val)
if (err)
return err;
- ptr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WC);
+ ptr = i915_gem_object_pin_map(obj, I915_MAP_WC);
if (IS_ERR(ptr))
return PTR_ERR(ptr);
@@ -593,7 +541,9 @@ static int igt_gpu_write(struct i915_gem_context *ctx,
if (err)
break;
+ i915_gem_object_lock(obj, NULL);
err = igt_cpu_check(obj, dword, rng);
+ i915_gem_object_unlock(obj);
if (err)
break;
} while (!__igt_timeout(end_time, NULL));
@@ -629,6 +579,88 @@ out_put:
return err;
}
+static int igt_lmem_create_cleared_cpu(void *arg)
+{
+ struct drm_i915_private *i915 = arg;
+ I915_RND_STATE(prng);
+ IGT_TIMEOUT(end_time);
+ u32 size, i;
+ int err;
+
+ i915_gem_drain_freed_objects(i915);
+
+ size = max_t(u32, PAGE_SIZE, i915_prandom_u32_max_state(SZ_32M, &prng));
+ size = round_up(size, PAGE_SIZE);
+ i = 0;
+
+ do {
+ struct drm_i915_gem_object *obj;
+ unsigned int flags;
+ u32 dword, val;
+ void *vaddr;
+
+ /*
+ * Alternate between cleared and uncleared allocations, while
+ * also dirtying the pages each time to check that the pages are
+ * always cleared if requested, since we should get some overlap
+ * of the underlying pages, if not all, since we are the only
+ * user.
+ */
+
+ flags = I915_BO_ALLOC_CPU_CLEAR;
+ if (i & 1)
+ flags = 0;
+
+ obj = i915_gem_object_create_lmem(i915, size, flags);
+ if (IS_ERR(obj))
+ return PTR_ERR(obj);
+
+ i915_gem_object_lock(obj, NULL);
+ err = i915_gem_object_pin_pages(obj);
+ if (err)
+ goto out_put;
+
+ dword = i915_prandom_u32_max_state(PAGE_SIZE / sizeof(u32),
+ &prng);
+
+ if (flags & I915_BO_ALLOC_CPU_CLEAR) {
+ err = igt_cpu_check(obj, dword, 0);
+ if (err) {
+ pr_err("%s failed with size=%u, flags=%u\n",
+ __func__, size, flags);
+ goto out_unpin;
+ }
+ }
+
+ vaddr = i915_gem_object_pin_map(obj, I915_MAP_WC);
+ if (IS_ERR(vaddr)) {
+ err = PTR_ERR(vaddr);
+ goto out_unpin;
+ }
+
+ val = prandom_u32_state(&prng);
+
+ memset32(vaddr, val, obj->base.size / sizeof(u32));
+
+ i915_gem_object_flush_map(obj);
+ i915_gem_object_unpin_map(obj);
+out_unpin:
+ i915_gem_object_unpin_pages(obj);
+ __i915_gem_object_put_pages(obj);
+out_put:
+ i915_gem_object_unlock(obj);
+ i915_gem_object_put(obj);
+
+ if (err)
+ break;
+ ++i;
+ } while (!__igt_timeout(end_time, NULL));
+
+ pr_info("%s completed (%u) iterations\n", __func__, i);
+
+ return err;
+}
+
static int igt_lmem_write_gpu(void *arg)
{
struct drm_i915_private *i915 = arg;
@@ -1014,7 +1046,6 @@ int intel_memory_region_mock_selftests(void)
SUBTEST(igt_mock_fill),
SUBTEST(igt_mock_contiguous),
SUBTEST(igt_mock_splintered_region),
- SUBTEST(igt_mock_max_segment),
};
struct intel_memory_region *mem;
struct drm_i915_private *i915;
@@ -1043,6 +1074,7 @@ int intel_memory_region_live_selftests(struct drm_i915_private *i915)
{
static const struct i915_subtest tests[] = {
SUBTEST(igt_lmem_create),
+ SUBTEST(igt_lmem_create_cleared_cpu),
SUBTEST(igt_lmem_write_cpu),
SUBTEST(igt_lmem_write_gpu),
};
diff --git a/drivers/gpu/drm/i915/selftests/intel_uncore.c b/drivers/gpu/drm/i915/selftests/intel_uncore.c
index 0e4e6be0101d..8ef9e6a4ad05 100644
--- a/drivers/gpu/drm/i915/selftests/intel_uncore.c
+++ b/drivers/gpu/drm/i915/selftests/intel_uncore.c
@@ -125,17 +125,19 @@ static int live_forcewake_ops(void *arg)
{
static const struct reg {
const char *name;
+ u8 min_graphics_ver;
+ u8 max_graphics_ver;
unsigned long platforms;
unsigned int offset;
} registers[] = {
{
"RING_START",
- INTEL_GEN_MASK(6, 7),
+ 6, 7,
0x38,
},
{
"RING_MI_MODE",
- INTEL_GEN_MASK(8, BITS_PER_LONG),
+ 8, U8_MAX,
0x9c,
}
};
@@ -170,7 +172,7 @@ static int live_forcewake_ops(void *arg)
/* We have to pick carefully to get the exact behaviour we need */
for (r = registers; r->name; r++)
- if (r->platforms & INTEL_INFO(gt->i915)->gen_mask)
+ if (IS_GRAPHICS_VER(gt->i915, r->min_graphics_ver, r->max_graphics_ver))
break;
if (!r->name) {
pr_debug("Forcewaked register not known for %s; skipping\n",
@@ -319,7 +321,7 @@ static int live_fw_table(void *arg)
/* Confirm the table we load is still valid */
return intel_fw_table_check(gt->uncore->fw_domains_table,
gt->uncore->fw_domains_table_entries,
- INTEL_GEN(gt->i915) >= 9);
+ GRAPHICS_VER(gt->i915) >= 9);
}
int intel_uncore_live_selftests(struct drm_i915_private *i915)
diff --git a/drivers/gpu/drm/i915/selftests/librapl.c b/drivers/gpu/drm/i915/selftests/librapl.c
index 58710ac3f979..eb03b5b28bad 100644
--- a/drivers/gpu/drm/i915/selftests/librapl.c
+++ b/drivers/gpu/drm/i915/selftests/librapl.c
@@ -5,8 +5,18 @@
#include <asm/msr.h>
+#include "i915_drv.h"
#include "librapl.h"
+bool librapl_supported(const struct drm_i915_private *i915)
+{
+ /* Discrete cards require hwmon integration */
+ if (IS_DGFX(i915))
+ return false;
+
+ return librapl_energy_uJ();
+}
+
u64 librapl_energy_uJ(void)
{
unsigned long long power;
diff --git a/drivers/gpu/drm/i915/selftests/librapl.h b/drivers/gpu/drm/i915/selftests/librapl.h
index 887f3e91dd05..e3b24fad0a7a 100644
--- a/drivers/gpu/drm/i915/selftests/librapl.h
+++ b/drivers/gpu/drm/i915/selftests/librapl.h
@@ -8,6 +8,10 @@
#include <linux/types.h>
+struct drm_i915_private;
+
+bool librapl_supported(const struct drm_i915_private *i915);
+
u64 librapl_energy_uJ(void);
#endif /* SELFTEST_LIBRAPL_H */
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 0188f877cab2..d189c4bd4bef 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -32,6 +32,7 @@
#include "gt/intel_gt_requests.h"
#include "gt/mock_engine.h"
#include "intel_memory_region.h"
+#include "intel_region_ttm.h"
#include "mock_request.h"
#include "mock_gem_device.h"
@@ -70,6 +71,7 @@ static void mock_device_release(struct drm_device *dev)
mock_fini_ggtt(&i915->ggtt);
destroy_workqueue(i915->wq);
+ intel_region_ttm_device_fini(i915);
intel_gt_driver_late_release(&i915->gt);
intel_memory_regions_driver_release(i915);
@@ -116,6 +118,7 @@ struct drm_i915_private *mock_gem_device(void)
#endif
struct drm_i915_private *i915;
struct pci_dev *pdev;
+ int ret;
pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
if (!pdev)
@@ -146,7 +149,6 @@ struct drm_i915_private *mock_gem_device(void)
}
pci_set_drvdata(pdev, i915);
- i915->drm.pdev = pdev;
dev_pm_domain_set(&pdev->dev, &pm_domain);
pm_runtime_enable(&pdev->dev);
@@ -162,7 +164,7 @@ struct drm_i915_private *mock_gem_device(void)
/* Using the global GTT may ask questions about KMS users, so prepare */
drm_mode_config_init(&i915->drm);
- mkwrite_device_info(i915)->gen = -1;
+ mkwrite_device_info(i915)->graphics_ver = -1;
mkwrite_device_info(i915)->page_sizes =
I915_GTT_PAGE_SIZE_4K |
@@ -179,6 +181,10 @@ struct drm_i915_private *mock_gem_device(void)
atomic_inc(&i915->gt.wakeref.count); /* disable; no hw support */
i915->gt.awake = -ENODEV;
+ ret = intel_region_ttm_device_init(i915);
+ if (ret)
+ goto err_ttm;
+
i915->wq = alloc_ordered_workqueue("mock", 0);
if (!i915->wq)
goto err_drv;
@@ -202,6 +208,7 @@ struct drm_i915_private *mock_gem_device(void)
intel_engines_driver_register(i915);
i915->do_release = true;
+ ida_init(&i915->selftest.mock_region_instances);
return i915;
@@ -210,6 +217,8 @@ err_context:
err_unlock:
destroy_workqueue(i915->wq);
err_drv:
+ intel_region_ttm_device_fini(i915);
+err_ttm:
intel_gt_driver_late_release(&i915->gt);
intel_memory_regions_driver_release(i915);
drm_mode_config_cleanup(&i915->drm);
diff --git a/drivers/gpu/drm/i915/selftests/mock_region.c b/drivers/gpu/drm/i915/selftests/mock_region.c
index 5d2d010a1e22..eafc5a04975c 100644
--- a/drivers/gpu/drm/i915/selftests/mock_region.c
+++ b/drivers/gpu/drm/i915/selftests/mock_region.c
@@ -1,17 +1,56 @@
// SPDX-License-Identifier: MIT
/*
- * Copyright © 2019 Intel Corporation
+ * Copyright © 2019-2021 Intel Corporation
*/
+#include <linux/scatterlist.h>
+
+#include <drm/ttm/ttm_placement.h>
+
#include "gem/i915_gem_region.h"
#include "intel_memory_region.h"
+#include "intel_region_ttm.h"
#include "mock_region.h"
+static void mock_region_put_pages(struct drm_i915_gem_object *obj,
+ struct sg_table *pages)
+{
+ intel_region_ttm_node_free(obj->mm.region, obj->mm.st_mm_node);
+ sg_free_table(pages);
+ kfree(pages);
+}
+
+static int mock_region_get_pages(struct drm_i915_gem_object *obj)
+{
+ unsigned int flags;
+ struct sg_table *pages;
+
+ flags = I915_ALLOC_MIN_PAGE_SIZE;
+ if (obj->flags & I915_BO_ALLOC_CONTIGUOUS)
+ flags |= I915_ALLOC_CONTIGUOUS;
+
+ obj->mm.st_mm_node = intel_region_ttm_node_alloc(obj->mm.region,
+ obj->base.size,
+ flags);
+ if (IS_ERR(obj->mm.st_mm_node))
+ return PTR_ERR(obj->mm.st_mm_node);
+
+ pages = intel_region_ttm_node_to_st(obj->mm.region, obj->mm.st_mm_node);
+ if (IS_ERR(pages)) {
+ intel_region_ttm_node_free(obj->mm.region, obj->mm.st_mm_node);
+ return PTR_ERR(pages);
+ }
+
+ __i915_gem_object_set_pages(obj, pages, i915_sg_dma_sizes(pages->sgl));
+
+ return 0;
+}
+
static const struct drm_i915_gem_object_ops mock_region_obj_ops = {
.name = "mock-region",
- .get_pages = i915_gem_object_get_pages_buddy,
- .put_pages = i915_gem_object_put_pages_buddy,
+ .get_pages = mock_region_get_pages,
+ .put_pages = mock_region_put_pages,
.release = i915_gem_object_release_memory_region,
};
@@ -23,7 +62,7 @@ static int mock_object_init(struct intel_memory_region *mem,
static struct lock_class_key lock_class;
struct drm_i915_private *i915 = mem->i915;
- if (size > mem->mm.size)
+ if (size > resource_size(&mem->region))
return -E2BIG;
drm_gem_private_object_init(&i915->drm, &obj->base, size);
@@ -38,9 +77,18 @@ static int mock_object_init(struct intel_memory_region *mem,
return 0;
}
+static void mock_region_fini(struct intel_memory_region *mem)
+{
+ struct drm_i915_private *i915 = mem->i915;
+ int instance = mem->instance;
+
+ intel_region_ttm_fini(mem);
+ ida_free(&i915->selftest.mock_region_instances, instance);
+}
+
static const struct intel_memory_region_ops mock_region_ops = {
- .init = intel_memory_region_init_buddy,
- .release = intel_memory_region_release_buddy,
+ .init = intel_region_ttm_init,
+ .release = mock_region_fini,
.init_object = mock_object_init,
};
@@ -51,6 +99,14 @@ mock_region_create(struct drm_i915_private *i915,
resource_size_t min_page_size,
resource_size_t io_start)
{
+ int instance = ida_alloc_max(&i915->selftest.mock_region_instances,
+ TTM_NUM_MEM_TYPES - TTM_PL_PRIV - 1,
+ GFP_KERNEL);
+
+ if (instance < 0)
+ return ERR_PTR(instance);
+
return intel_memory_region_create(i915, start, size, min_page_size,
- io_start, &mock_region_ops);
+ io_start, INTEL_MEMORY_MOCK, instance,
+ &mock_region_ops);
}