linux/drivers/gpu/drm/i915/gem/selftests/igt_gem_utils.c
<<
>>
Prefs
   1/*
   2 * SPDX-License-Identifier: MIT
   3 *
   4 * Copyright © 2018 Intel Corporation
   5 */
   6
   7#include "igt_gem_utils.h"
   8
   9#include "gem/i915_gem_context.h"
  10#include "gem/i915_gem_pm.h"
  11#include "gt/intel_context.h"
  12#include "gt/intel_gt.h"
  13#include "i915_vma.h"
  14#include "i915_drv.h"
  15
  16#include "i915_request.h"
  17
  18struct i915_request *
  19igt_request_alloc(struct i915_gem_context *ctx, struct intel_engine_cs *engine)
  20{
  21        struct intel_context *ce;
  22        struct i915_request *rq;
  23
  24        /*
  25         * Pinning the contexts may generate requests in order to acquire
  26         * GGTT space, so do this first before we reserve a seqno for
  27         * ourselves.
  28         */
  29        ce = i915_gem_context_get_engine(ctx, engine->legacy_idx);
  30        if (IS_ERR(ce))
  31                return ERR_CAST(ce);
  32
  33        rq = intel_context_create_request(ce);
  34        intel_context_put(ce);
  35
  36        return rq;
  37}
  38
  39struct i915_vma *
  40igt_emit_store_dw(struct i915_vma *vma,
  41                  u64 offset,
  42                  unsigned long count,
  43                  u32 val)
  44{
  45        struct drm_i915_gem_object *obj;
  46        const int gen = INTEL_GEN(vma->vm->i915);
  47        unsigned long n, size;
  48        u32 *cmd;
  49        int err;
  50
  51        size = (4 * count + 1) * sizeof(u32);
  52        size = round_up(size, PAGE_SIZE);
  53        obj = i915_gem_object_create_internal(vma->vm->i915, size);
  54        if (IS_ERR(obj))
  55                return ERR_CAST(obj);
  56
  57        cmd = i915_gem_object_pin_map(obj, I915_MAP_WC);
  58        if (IS_ERR(cmd)) {
  59                err = PTR_ERR(cmd);
  60                goto err;
  61        }
  62
  63        GEM_BUG_ON(offset + (count - 1) * PAGE_SIZE > vma->node.size);
  64        offset += vma->node.start;
  65
  66        for (n = 0; n < count; n++) {
  67                if (gen >= 8) {
  68                        *cmd++ = MI_STORE_DWORD_IMM_GEN4;
  69                        *cmd++ = lower_32_bits(offset);
  70                        *cmd++ = upper_32_bits(offset);
  71                        *cmd++ = val;
  72                } else if (gen >= 4) {
  73                        *cmd++ = MI_STORE_DWORD_IMM_GEN4 |
  74                                (gen < 6 ? MI_USE_GGTT : 0);
  75                        *cmd++ = 0;
  76                        *cmd++ = offset;
  77                        *cmd++ = val;
  78                } else {
  79                        *cmd++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL;
  80                        *cmd++ = offset;
  81                        *cmd++ = val;
  82                }
  83                offset += PAGE_SIZE;
  84        }
  85        *cmd = MI_BATCH_BUFFER_END;
  86
  87        i915_gem_object_flush_map(obj);
  88        i915_gem_object_unpin_map(obj);
  89
  90        intel_gt_chipset_flush(vma->vm->gt);
  91
  92        vma = i915_vma_instance(obj, vma->vm, NULL);
  93        if (IS_ERR(vma)) {
  94                err = PTR_ERR(vma);
  95                goto err;
  96        }
  97
  98        err = i915_vma_pin(vma, 0, 0, PIN_USER);
  99        if (err)
 100                goto err;
 101
 102        return vma;
 103
 104err:
 105        i915_gem_object_put(obj);
 106        return ERR_PTR(err);
 107}
 108
 109int igt_gpu_fill_dw(struct intel_context *ce,
 110                    struct i915_vma *vma, u64 offset,
 111                    unsigned long count, u32 val)
 112{
 113        struct i915_request *rq;
 114        struct i915_vma *batch;
 115        unsigned int flags;
 116        int err;
 117
 118        GEM_BUG_ON(!intel_engine_can_store_dword(ce->engine));
 119        GEM_BUG_ON(!i915_vma_is_pinned(vma));
 120
 121        batch = igt_emit_store_dw(vma, offset, count, val);
 122        if (IS_ERR(batch))
 123                return PTR_ERR(batch);
 124
 125        rq = intel_context_create_request(ce);
 126        if (IS_ERR(rq)) {
 127                err = PTR_ERR(rq);
 128                goto err_batch;
 129        }
 130
 131        i915_vma_lock(batch);
 132        err = i915_request_await_object(rq, batch->obj, false);
 133        if (err == 0)
 134                err = i915_vma_move_to_active(batch, rq, 0);
 135        i915_vma_unlock(batch);
 136        if (err)
 137                goto skip_request;
 138
 139        i915_vma_lock(vma);
 140        err = i915_request_await_object(rq, vma->obj, true);
 141        if (err == 0)
 142                err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);
 143        i915_vma_unlock(vma);
 144        if (err)
 145                goto skip_request;
 146
 147        flags = 0;
 148        if (INTEL_GEN(ce->vm->i915) <= 5)
 149                flags |= I915_DISPATCH_SECURE;
 150
 151        err = rq->engine->emit_bb_start(rq,
 152                                        batch->node.start, batch->node.size,
 153                                        flags);
 154
 155skip_request:
 156        if (err)
 157                i915_request_set_error_once(rq, err);
 158        i915_request_add(rq);
 159err_batch:
 160        i915_vma_unpin_and_release(&batch, 0);
 161        return err;
 162}
 163