Commit | Line | Data |
---|---|---|
c8afe684 RC |
1 | /* |
2 | * Copyright (C) 2013 Red Hat | |
3 | * Author: Rob Clark <robdclark@gmail.com> | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify it | |
6 | * under the terms of the GNU General Public License version 2 as published by | |
7 | * the Free Software Foundation. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
12 | * more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License along with | |
15 | * this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | */ | |
17 | ||
18 | #ifndef __MSM_GEM_H__ | |
19 | #define __MSM_GEM_H__ | |
20 | ||
ee546cd3 | 21 | #include <linux/kref.h> |
7198e6b0 | 22 | #include <linux/reservation.h> |
c8afe684 RC |
23 | #include "msm_drv.h" |
24 | ||
072f1f91 RC |
25 | /* Additional internal-use only BO flags: */ |
26 | #define MSM_BO_STOLEN 0x10000000 /* try to use stolen/splash memory */ | |
27 | ||
667ce33e RC |
28 | struct msm_gem_address_space { |
29 | const char *name; | |
30 | /* NOTE: mm managed at the page level, size is in # of pages | |
31 | * and position mm_node->start is in # of pages: | |
32 | */ | |
33 | struct drm_mm mm; | |
0e08270a | 34 | spinlock_t lock; /* Protects drm_mm node allocation/removal */ |
667ce33e | 35 | struct msm_mmu *mmu; |
ee546cd3 | 36 | struct kref kref; |
667ce33e RC |
37 | }; |
38 | ||
39 | struct msm_gem_vma { | |
40 | struct drm_mm_node node; | |
41 | uint64_t iova; | |
4b85f7f5 RC |
42 | struct msm_gem_address_space *aspace; |
43 | struct list_head list; /* node in msm_gem_object::vmas */ | |
667ce33e RC |
44 | }; |
45 | ||
c8afe684 RC |
46 | struct msm_gem_object { |
47 | struct drm_gem_object base; | |
48 | ||
49 | uint32_t flags; | |
50 | ||
4cd33c48 RC |
51 | /** |
52 | * Advice: are the backing pages purgeable? | |
53 | */ | |
54 | uint8_t madv; | |
55 | ||
e1e9db2c RC |
56 | /** |
57 | * count of active vmap'ing | |
58 | */ | |
59 | uint8_t vmap_count; | |
60 | ||
7198e6b0 RC |
61 | /* And object is either: |
62 | * inactive - on priv->inactive_list | |
63 | * active - on one one of the gpu's active_list.. well, at | |
64 | * least for now we don't have (I don't think) hw sync between | |
65 | * 2d and 3d one devices which have both, meaning we need to | |
66 | * block on submit if a bo is already on other ring | |
67 | * | |
68 | */ | |
c8afe684 | 69 | struct list_head mm_list; |
7198e6b0 | 70 | struct msm_gpu *gpu; /* non-null if active */ |
7198e6b0 RC |
71 | |
72 | /* Transiently in the process of submit ioctl, objects associated | |
73 | * with the submit are on submit->bo_list.. this only lasts for | |
74 | * the duration of the ioctl, so one bo can never be on multiple | |
75 | * submit lists. | |
76 | */ | |
77 | struct list_head submit_entry; | |
78 | ||
c8afe684 RC |
79 | struct page **pages; |
80 | struct sg_table *sgt; | |
81 | void *vaddr; | |
82 | ||
4b85f7f5 | 83 | struct list_head vmas; /* list of msm_gem_vma */ |
7198e6b0 RC |
84 | |
85 | /* normally (resv == &_resv) except for imported bo's */ | |
86 | struct reservation_object *resv; | |
87 | struct reservation_object _resv; | |
871d812a RC |
88 | |
89 | /* For physically contiguous buffers. Used when we don't have | |
072f1f91 | 90 | * an IOMMU. Also used for stolen/splashscreen buffer. |
871d812a RC |
91 | */ |
92 | struct drm_mm_node *vram_node; | |
0e08270a | 93 | struct mutex lock; /* Protects resources associated with bo */ |
c8afe684 RC |
94 | }; |
95 | #define to_msm_bo(x) container_of(x, struct msm_gem_object, base) | |
96 | ||
7198e6b0 RC |
97 | static inline bool is_active(struct msm_gem_object *msm_obj) |
98 | { | |
99 | return msm_obj->gpu != NULL; | |
100 | } | |
101 | ||
68209390 RC |
102 | static inline bool is_purgeable(struct msm_gem_object *msm_obj) |
103 | { | |
0e08270a | 104 | WARN_ON(!mutex_is_locked(&msm_obj->base.dev->struct_mutex)); |
68209390 RC |
105 | return (msm_obj->madv == MSM_MADV_DONTNEED) && msm_obj->sgt && |
106 | !msm_obj->base.dma_buf && !msm_obj->base.import_attach; | |
107 | } | |
108 | ||
e1e9db2c RC |
109 | static inline bool is_vunmapable(struct msm_gem_object *msm_obj) |
110 | { | |
111 | return (msm_obj->vmap_count == 0) && msm_obj->vaddr; | |
112 | } | |
113 | ||
0e08270a SS |
114 | /* The shrinker can be triggered while we hold objA->lock, and need |
115 | * to grab objB->lock to purge it. Lockdep just sees these as a single | |
116 | * class of lock, so we use subclasses to teach it the difference. | |
117 | * | |
118 | * OBJ_LOCK_NORMAL is implicit (ie. normal mutex_lock() call), and | |
119 | * OBJ_LOCK_SHRINKER is used by shrinker. | |
120 | * | |
121 | * It is *essential* that we never go down paths that could trigger the | |
122 | * shrinker for a purgable object. This is ensured by checking that | |
123 | * msm_obj->madv == MSM_MADV_WILLNEED. | |
124 | */ | |
125 | enum msm_gem_lock { | |
126 | OBJ_LOCK_NORMAL, | |
127 | OBJ_LOCK_SHRINKER, | |
128 | }; | |
129 | ||
130 | void msm_gem_purge(struct drm_gem_object *obj, enum msm_gem_lock subclass); | |
131 | void msm_gem_vunmap(struct drm_gem_object *obj, enum msm_gem_lock subclass); | |
132 | ||
7198e6b0 RC |
133 | /* Created per submit-ioctl, to track bo's and cmdstream bufs, etc, |
134 | * associated with the cmdstream submission for synchronization (and | |
135 | * make it easier to unwind when things go wrong, etc). This only | |
136 | * lasts for the duration of the submit-ioctl. | |
137 | */ | |
138 | struct msm_gem_submit { | |
139 | struct drm_device *dev; | |
140 | struct msm_gpu *gpu; | |
1a370be9 | 141 | struct list_head node; /* node in gpu submit_list */ |
7198e6b0 RC |
142 | struct list_head bo_list; |
143 | struct ww_acquire_ctx ticket; | |
f54d1867 | 144 | struct dma_fence *fence; |
4816b626 | 145 | struct pid *pid; /* submitting process */ |
340faef2 | 146 | bool valid; /* true if no cmdstream patching needed */ |
7198e6b0 RC |
147 | unsigned int nr_cmds; |
148 | unsigned int nr_bos; | |
149 | struct { | |
150 | uint32_t type; | |
151 | uint32_t size; /* in dwords */ | |
78babc16 | 152 | uint64_t iova; |
a7d3c950 | 153 | uint32_t idx; /* cmdstream buffer idx in bos[] */ |
6b597ce2 | 154 | } *cmd; /* array of size nr_cmds */ |
7198e6b0 RC |
155 | struct { |
156 | uint32_t flags; | |
157 | struct msm_gem_object *obj; | |
78babc16 | 158 | uint64_t iova; |
7198e6b0 RC |
159 | } bos[0]; |
160 | }; | |
161 | ||
c8afe684 | 162 | #endif /* __MSM_GEM_H__ */ |