drm/i915: Prepare for GuC-based command submission
[deliverable/linux.git] / drivers / gpu / drm / i915 / i915_guc_submission.c
CommitLineData
bac427f8
AD
1/*
2 * Copyright © 2014 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24#include <linux/firmware.h>
25#include <linux/circ_buf.h>
26#include "i915_drv.h"
27#include "intel_guc.h"
28
29/**
30 * gem_allocate_guc_obj() - Allocate gem object for GuC usage
31 * @dev: drm device
32 * @size: size of object
33 *
34 * This is a wrapper to create a gem obj. In order to use it inside GuC, the
35 * object needs to be pinned lifetime. Also we must pin it to gtt space other
36 * than [0, GUC_WOPCM_TOP) because this range is reserved inside GuC.
37 *
38 * Return: A drm_i915_gem_object if successful, otherwise NULL.
39 */
40static struct drm_i915_gem_object *gem_allocate_guc_obj(struct drm_device *dev,
41 u32 size)
42{
43 struct drm_i915_private *dev_priv = dev->dev_private;
44 struct drm_i915_gem_object *obj;
45
46 obj = i915_gem_alloc_object(dev, size);
47 if (!obj)
48 return NULL;
49
50 if (i915_gem_object_get_pages(obj)) {
51 drm_gem_object_unreference(&obj->base);
52 return NULL;
53 }
54
55 if (i915_gem_obj_ggtt_pin(obj, PAGE_SIZE,
56 PIN_OFFSET_BIAS | GUC_WOPCM_TOP)) {
57 drm_gem_object_unreference(&obj->base);
58 return NULL;
59 }
60
61 /* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
62 I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
63
64 return obj;
65}
66
67/**
68 * gem_release_guc_obj() - Release gem object allocated for GuC usage
69 * @obj: gem obj to be released
70 */
71static void gem_release_guc_obj(struct drm_i915_gem_object *obj)
72{
73 if (!obj)
74 return;
75
76 if (i915_gem_obj_is_pinned(obj))
77 i915_gem_object_ggtt_unpin(obj);
78
79 drm_gem_object_unreference(&obj->base);
80}
81
82/*
83 * Set up the memory resources to be shared with the GuC. At this point,
84 * we require just one object that can be mapped through the GGTT.
85 */
86int i915_guc_submission_init(struct drm_device *dev)
87{
88 struct drm_i915_private *dev_priv = dev->dev_private;
89 const size_t ctxsize = sizeof(struct guc_context_desc);
90 const size_t poolsize = GUC_MAX_GPU_CONTEXTS * ctxsize;
91 const size_t gemsize = round_up(poolsize, PAGE_SIZE);
92 struct intel_guc *guc = &dev_priv->guc;
93
94 if (!i915.enable_guc_submission)
95 return 0; /* not enabled */
96
97 if (guc->ctx_pool_obj)
98 return 0; /* already allocated */
99
100 guc->ctx_pool_obj = gem_allocate_guc_obj(dev_priv->dev, gemsize);
101 if (!guc->ctx_pool_obj)
102 return -ENOMEM;
103
104 ida_init(&guc->ctx_ids);
105
106 return 0;
107}
108
109void i915_guc_submission_fini(struct drm_device *dev)
110{
111 struct drm_i915_private *dev_priv = dev->dev_private;
112 struct intel_guc *guc = &dev_priv->guc;
113
114 if (guc->ctx_pool_obj)
115 ida_destroy(&guc->ctx_ids);
116 gem_release_guc_obj(guc->ctx_pool_obj);
117 guc->ctx_pool_obj = NULL;
118}
This page took 0.029296 seconds and 5 git commands to generate.