Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/gpu/drm/i915/i915_gem_gtt.c
15113 views
1
/*
2
* Copyright © 2010 Daniel Vetter
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
25
#include "drmP.h"
26
#include "drm.h"
27
#include "i915_drm.h"
28
#include "i915_drv.h"
29
#include "i915_trace.h"
30
#include "intel_drv.h"
31
32
/* XXX kill agp_type! */
33
static unsigned int cache_level_to_agp_type(struct drm_device *dev,
34
enum i915_cache_level cache_level)
35
{
36
switch (cache_level) {
37
case I915_CACHE_LLC_MLC:
38
if (INTEL_INFO(dev)->gen >= 6)
39
return AGP_USER_CACHED_MEMORY_LLC_MLC;
40
/* Older chipsets do not have this extra level of CPU
41
* cacheing, so fallthrough and request the PTE simply
42
* as cached.
43
*/
44
case I915_CACHE_LLC:
45
return AGP_USER_CACHED_MEMORY;
46
default:
47
case I915_CACHE_NONE:
48
return AGP_USER_MEMORY;
49
}
50
}
51
52
void i915_gem_restore_gtt_mappings(struct drm_device *dev)
53
{
54
struct drm_i915_private *dev_priv = dev->dev_private;
55
struct drm_i915_gem_object *obj;
56
57
/* First fill our portion of the GTT with scratch pages */
58
intel_gtt_clear_range(dev_priv->mm.gtt_start / PAGE_SIZE,
59
(dev_priv->mm.gtt_end - dev_priv->mm.gtt_start) / PAGE_SIZE);
60
61
list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) {
62
unsigned int agp_type =
63
cache_level_to_agp_type(dev, obj->cache_level);
64
65
i915_gem_clflush_object(obj);
66
67
if (dev_priv->mm.gtt->needs_dmar) {
68
BUG_ON(!obj->sg_list);
69
70
intel_gtt_insert_sg_entries(obj->sg_list,
71
obj->num_sg,
72
obj->gtt_space->start >> PAGE_SHIFT,
73
agp_type);
74
} else
75
intel_gtt_insert_pages(obj->gtt_space->start
76
>> PAGE_SHIFT,
77
obj->base.size >> PAGE_SHIFT,
78
obj->pages,
79
agp_type);
80
}
81
82
intel_gtt_chipset_flush();
83
}
84
85
int i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj)
86
{
87
struct drm_device *dev = obj->base.dev;
88
struct drm_i915_private *dev_priv = dev->dev_private;
89
unsigned int agp_type = cache_level_to_agp_type(dev, obj->cache_level);
90
int ret;
91
92
if (dev_priv->mm.gtt->needs_dmar) {
93
ret = intel_gtt_map_memory(obj->pages,
94
obj->base.size >> PAGE_SHIFT,
95
&obj->sg_list,
96
&obj->num_sg);
97
if (ret != 0)
98
return ret;
99
100
intel_gtt_insert_sg_entries(obj->sg_list,
101
obj->num_sg,
102
obj->gtt_space->start >> PAGE_SHIFT,
103
agp_type);
104
} else
105
intel_gtt_insert_pages(obj->gtt_space->start >> PAGE_SHIFT,
106
obj->base.size >> PAGE_SHIFT,
107
obj->pages,
108
agp_type);
109
110
return 0;
111
}
112
113
void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj)
114
{
115
intel_gtt_clear_range(obj->gtt_space->start >> PAGE_SHIFT,
116
obj->base.size >> PAGE_SHIFT);
117
118
if (obj->sg_list) {
119
intel_gtt_unmap_memory(obj->sg_list, obj->num_sg);
120
obj->sg_list = NULL;
121
}
122
}
123
124