diff options
author | Dave Airlie <airlied@redhat.com> | 2018-08-07 16:09:08 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2018-08-07 16:22:23 -0400 |
commit | 940fbcb73fd25b517fa10c5a9cc96ca0ce1a2fc4 (patch) | |
tree | c967fae5501fefe9258f9891371977833bd2a72c /drivers/gpu/drm/amd/amdgpu | |
parent | 569f0a8694d0ff13c5d296a594c7d8cec8d6f35f (diff) | |
parent | df36b2fb8390d98453fff1aae3927095fe9ff36c (diff) |
Merge branch 'drm-next-4.19' of git://people.freedesktop.org/~agd5f/linux into drm-next
Fixes for 4.19:
- Fix UVD 7.2 instance handling
- Fix UVD 7.2 harvesting
- GPU scheduler fix for when a process is killed
- TTM cleanups
- amdgpu CS bo_list fixes
- Powerplay fixes for polaris12 and CZ/ST
- DC fixes for link training certain HMDs
- DC fix for vega10 blank screen in certain cases
From: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180801222906.1016-1-alexander.deucher@amd.com
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 41 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 189 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h | 85 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 169 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 111 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 85 |
16 files changed, 454 insertions, 321 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 0283e2b3c851..447c4c7a36d6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -74,6 +74,7 @@ | |||
74 | #include "amdgpu_gart.h" | 74 | #include "amdgpu_gart.h" |
75 | #include "amdgpu_debugfs.h" | 75 | #include "amdgpu_debugfs.h" |
76 | #include "amdgpu_job.h" | 76 | #include "amdgpu_job.h" |
77 | #include "amdgpu_bo_list.h" | ||
77 | 78 | ||
78 | /* | 79 | /* |
79 | * Modules parameters. | 80 | * Modules parameters. |
@@ -690,45 +691,6 @@ struct amdgpu_fpriv { | |||
690 | }; | 691 | }; |
691 | 692 | ||
692 | /* | 693 | /* |
693 | * residency list | ||
694 | */ | ||
695 | struct amdgpu_bo_list_entry { | ||
696 | struct amdgpu_bo *robj; | ||
697 | struct ttm_validate_buffer tv; | ||
698 | struct amdgpu_bo_va *bo_va; | ||
699 | uint32_t priority; | ||
700 | struct page **user_pages; | ||
701 | int user_invalidated; | ||
702 | }; | ||
703 | |||
704 | struct amdgpu_bo_list { | ||
705 | struct mutex lock; | ||
706 | struct rcu_head rhead; | ||
707 | struct kref refcount; | ||
708 | struct amdgpu_bo *gds_obj; | ||
709 | struct amdgpu_bo *gws_obj; | ||
710 | struct amdgpu_bo *oa_obj; | ||
711 | unsigned first_userptr; | ||
712 | unsigned num_entries; | ||
713 | struct amdgpu_bo_list_entry *array; | ||
714 | }; | ||
715 | |||
716 | struct amdgpu_bo_list * | ||
717 | amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id); | ||
718 | void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list, | ||
719 | struct list_head *validated); | ||
720 | void amdgpu_bo_list_put(struct amdgpu_bo_list *list); | ||
721 | void amdgpu_bo_list_free(struct amdgpu_bo_list *list); | ||
722 | int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in, | ||
723 | struct drm_amdgpu_bo_list_entry **info_param); | ||
724 | |||
725 | int amdgpu_bo_list_create(struct amdgpu_device *adev, | ||
726 | struct drm_file *filp, | ||
727 | struct drm_amdgpu_bo_list_entry *info, | ||
728 | unsigned num_entries, | ||
729 | struct amdgpu_bo_list **list); | ||
730 | |||
731 | /* | ||
732 | * GFX stuff | 694 | * GFX stuff |
733 | */ | 695 | */ |
734 | #include "clearstate_defs.h" | 696 | #include "clearstate_defs.h" |
@@ -1748,6 +1710,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) | |||
1748 | #define amdgpu_vm_write_pte(adev, ib, pe, value, count, incr) ((adev)->vm_manager.vm_pte_funcs->write_pte((ib), (pe), (value), (count), (incr))) | 1710 | #define amdgpu_vm_write_pte(adev, ib, pe, value, count, incr) ((adev)->vm_manager.vm_pte_funcs->write_pte((ib), (pe), (value), (count), (incr))) |
1749 | #define amdgpu_vm_set_pte_pde(adev, ib, pe, addr, count, incr, flags) ((adev)->vm_manager.vm_pte_funcs->set_pte_pde((ib), (pe), (addr), (count), (incr), (flags))) | 1711 | #define amdgpu_vm_set_pte_pde(adev, ib, pe, addr, count, incr, flags) ((adev)->vm_manager.vm_pte_funcs->set_pte_pde((ib), (pe), (addr), (count), (incr), (flags))) |
1750 | #define amdgpu_ring_parse_cs(r, p, ib) ((r)->funcs->parse_cs((p), (ib))) | 1712 | #define amdgpu_ring_parse_cs(r, p, ib) ((r)->funcs->parse_cs((p), (ib))) |
1713 | #define amdgpu_ring_patch_cs_in_place(r, p, ib) ((r)->funcs->patch_cs_in_place((p), (ib))) | ||
1751 | #define amdgpu_ring_test_ring(r) (r)->funcs->test_ring((r)) | 1714 | #define amdgpu_ring_test_ring(r) (r)->funcs->test_ring((r)) |
1752 | #define amdgpu_ring_test_ib(r, t) (r)->funcs->test_ib((r), (t)) | 1715 | #define amdgpu_ring_test_ib(r, t) (r)->funcs->test_ib((r), (t)) |
1753 | #define amdgpu_ring_get_rptr(r) (r)->funcs->get_rptr((r)) | 1716 | #define amdgpu_ring_get_rptr(r) (r)->funcs->get_rptr((r)) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index 7679c068c89a..d472a2c8399f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | |||
@@ -35,83 +35,53 @@ | |||
35 | #define AMDGPU_BO_LIST_MAX_PRIORITY 32u | 35 | #define AMDGPU_BO_LIST_MAX_PRIORITY 32u |
36 | #define AMDGPU_BO_LIST_NUM_BUCKETS (AMDGPU_BO_LIST_MAX_PRIORITY + 1) | 36 | #define AMDGPU_BO_LIST_NUM_BUCKETS (AMDGPU_BO_LIST_MAX_PRIORITY + 1) |
37 | 37 | ||
38 | static int amdgpu_bo_list_set(struct amdgpu_device *adev, | 38 | static void amdgpu_bo_list_free_rcu(struct rcu_head *rcu) |
39 | struct drm_file *filp, | 39 | { |
40 | struct amdgpu_bo_list *list, | 40 | struct amdgpu_bo_list *list = container_of(rcu, struct amdgpu_bo_list, |
41 | struct drm_amdgpu_bo_list_entry *info, | 41 | rhead); |
42 | unsigned num_entries); | 42 | |
43 | kvfree(list); | ||
44 | } | ||
43 | 45 | ||
44 | static void amdgpu_bo_list_release_rcu(struct kref *ref) | 46 | static void amdgpu_bo_list_free(struct kref *ref) |
45 | { | 47 | { |
46 | unsigned i; | ||
47 | struct amdgpu_bo_list *list = container_of(ref, struct amdgpu_bo_list, | 48 | struct amdgpu_bo_list *list = container_of(ref, struct amdgpu_bo_list, |
48 | refcount); | 49 | refcount); |
50 | struct amdgpu_bo_list_entry *e; | ||
49 | 51 | ||
50 | for (i = 0; i < list->num_entries; ++i) | 52 | amdgpu_bo_list_for_each_entry(e, list) |
51 | amdgpu_bo_unref(&list->array[i].robj); | 53 | amdgpu_bo_unref(&e->robj); |
52 | 54 | ||
53 | mutex_destroy(&list->lock); | 55 | call_rcu(&list->rhead, amdgpu_bo_list_free_rcu); |
54 | kvfree(list->array); | ||
55 | kfree_rcu(list, rhead); | ||
56 | } | 56 | } |
57 | 57 | ||
58 | int amdgpu_bo_list_create(struct amdgpu_device *adev, | 58 | int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp, |
59 | struct drm_file *filp, | 59 | struct drm_amdgpu_bo_list_entry *info, |
60 | struct drm_amdgpu_bo_list_entry *info, | 60 | unsigned num_entries, struct amdgpu_bo_list **result) |
61 | unsigned num_entries, | ||
62 | struct amdgpu_bo_list **list_out) | ||
63 | { | 61 | { |
62 | unsigned last_entry = 0, first_userptr = num_entries; | ||
63 | struct amdgpu_bo_list_entry *array; | ||
64 | struct amdgpu_bo_list *list; | 64 | struct amdgpu_bo_list *list; |
65 | uint64_t total_size = 0; | ||
66 | size_t size; | ||
67 | unsigned i; | ||
65 | int r; | 68 | int r; |
66 | 69 | ||
70 | if (num_entries > SIZE_MAX / sizeof(struct amdgpu_bo_list_entry)) | ||
71 | return -EINVAL; | ||
67 | 72 | ||
68 | list = kzalloc(sizeof(struct amdgpu_bo_list), GFP_KERNEL); | 73 | size = sizeof(struct amdgpu_bo_list); |
74 | size += num_entries * sizeof(struct amdgpu_bo_list_entry); | ||
75 | list = kvmalloc(size, GFP_KERNEL); | ||
69 | if (!list) | 76 | if (!list) |
70 | return -ENOMEM; | 77 | return -ENOMEM; |
71 | 78 | ||
72 | /* initialize bo list*/ | ||
73 | mutex_init(&list->lock); | ||
74 | kref_init(&list->refcount); | 79 | kref_init(&list->refcount); |
75 | r = amdgpu_bo_list_set(adev, filp, list, info, num_entries); | 80 | list->gds_obj = adev->gds.gds_gfx_bo; |
76 | if (r) { | 81 | list->gws_obj = adev->gds.gws_gfx_bo; |
77 | kfree(list); | 82 | list->oa_obj = adev->gds.oa_gfx_bo; |
78 | return r; | ||
79 | } | ||
80 | |||
81 | *list_out = list; | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id) | ||
86 | { | ||
87 | struct amdgpu_bo_list *list; | ||
88 | 83 | ||
89 | mutex_lock(&fpriv->bo_list_lock); | 84 | array = amdgpu_bo_list_array_entry(list, 0); |
90 | list = idr_remove(&fpriv->bo_list_handles, id); | ||
91 | mutex_unlock(&fpriv->bo_list_lock); | ||
92 | if (list) | ||
93 | kref_put(&list->refcount, amdgpu_bo_list_release_rcu); | ||
94 | } | ||
95 | |||
96 | static int amdgpu_bo_list_set(struct amdgpu_device *adev, | ||
97 | struct drm_file *filp, | ||
98 | struct amdgpu_bo_list *list, | ||
99 | struct drm_amdgpu_bo_list_entry *info, | ||
100 | unsigned num_entries) | ||
101 | { | ||
102 | struct amdgpu_bo_list_entry *array; | ||
103 | struct amdgpu_bo *gds_obj = adev->gds.gds_gfx_bo; | ||
104 | struct amdgpu_bo *gws_obj = adev->gds.gws_gfx_bo; | ||
105 | struct amdgpu_bo *oa_obj = adev->gds.oa_gfx_bo; | ||
106 | |||
107 | unsigned last_entry = 0, first_userptr = num_entries; | ||
108 | unsigned i; | ||
109 | int r; | ||
110 | unsigned long total_size = 0; | ||
111 | |||
112 | array = kvmalloc_array(num_entries, sizeof(struct amdgpu_bo_list_entry), GFP_KERNEL); | ||
113 | if (!array) | ||
114 | return -ENOMEM; | ||
115 | memset(array, 0, num_entries * sizeof(struct amdgpu_bo_list_entry)); | 85 | memset(array, 0, num_entries * sizeof(struct amdgpu_bo_list_entry)); |
116 | 86 | ||
117 | for (i = 0; i < num_entries; ++i) { | 87 | for (i = 0; i < num_entries; ++i) { |
@@ -148,59 +118,56 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev, | |||
148 | entry->tv.shared = !entry->robj->prime_shared_count; | 118 | entry->tv.shared = !entry->robj->prime_shared_count; |
149 | 119 | ||
150 | if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GDS) | 120 | if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GDS) |
151 | gds_obj = entry->robj; | 121 | list->gds_obj = entry->robj; |
152 | if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GWS) | 122 | if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GWS) |
153 | gws_obj = entry->robj; | 123 | list->gws_obj = entry->robj; |
154 | if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_OA) | 124 | if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_OA) |
155 | oa_obj = entry->robj; | 125 | list->oa_obj = entry->robj; |
156 | 126 | ||
157 | total_size += amdgpu_bo_size(entry->robj); | 127 | total_size += amdgpu_bo_size(entry->robj); |
158 | trace_amdgpu_bo_list_set(list, entry->robj); | 128 | trace_amdgpu_bo_list_set(list, entry->robj); |
159 | } | 129 | } |
160 | 130 | ||
161 | for (i = 0; i < list->num_entries; ++i) | ||
162 | amdgpu_bo_unref(&list->array[i].robj); | ||
163 | |||
164 | kvfree(list->array); | ||
165 | |||
166 | list->gds_obj = gds_obj; | ||
167 | list->gws_obj = gws_obj; | ||
168 | list->oa_obj = oa_obj; | ||
169 | list->first_userptr = first_userptr; | 131 | list->first_userptr = first_userptr; |
170 | list->array = array; | ||
171 | list->num_entries = num_entries; | 132 | list->num_entries = num_entries; |
172 | 133 | ||
173 | trace_amdgpu_cs_bo_status(list->num_entries, total_size); | 134 | trace_amdgpu_cs_bo_status(list->num_entries, total_size); |
135 | |||
136 | *result = list; | ||
174 | return 0; | 137 | return 0; |
175 | 138 | ||
176 | error_free: | 139 | error_free: |
177 | while (i--) | 140 | while (i--) |
178 | amdgpu_bo_unref(&array[i].robj); | 141 | amdgpu_bo_unref(&array[i].robj); |
179 | kvfree(array); | 142 | kvfree(list); |
180 | return r; | 143 | return r; |
144 | |||
181 | } | 145 | } |
182 | 146 | ||
183 | struct amdgpu_bo_list * | 147 | static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id) |
184 | amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id) | ||
185 | { | 148 | { |
186 | struct amdgpu_bo_list *result; | 149 | struct amdgpu_bo_list *list; |
187 | 150 | ||
151 | mutex_lock(&fpriv->bo_list_lock); | ||
152 | list = idr_remove(&fpriv->bo_list_handles, id); | ||
153 | mutex_unlock(&fpriv->bo_list_lock); | ||
154 | if (list) | ||
155 | kref_put(&list->refcount, amdgpu_bo_list_free); | ||
156 | } | ||
157 | |||
158 | int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id, | ||
159 | struct amdgpu_bo_list **result) | ||
160 | { | ||
188 | rcu_read_lock(); | 161 | rcu_read_lock(); |
189 | result = idr_find(&fpriv->bo_list_handles, id); | 162 | *result = idr_find(&fpriv->bo_list_handles, id); |
190 | 163 | ||
191 | if (result) { | 164 | if (*result && kref_get_unless_zero(&(*result)->refcount)) { |
192 | if (kref_get_unless_zero(&result->refcount)) { | ||
193 | rcu_read_unlock(); | ||
194 | mutex_lock(&result->lock); | ||
195 | } else { | ||
196 | rcu_read_unlock(); | ||
197 | result = NULL; | ||
198 | } | ||
199 | } else { | ||
200 | rcu_read_unlock(); | 165 | rcu_read_unlock(); |
166 | return 0; | ||
201 | } | 167 | } |
202 | 168 | ||
203 | return result; | 169 | rcu_read_unlock(); |
170 | return -ENOENT; | ||
204 | } | 171 | } |
205 | 172 | ||
206 | void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list, | 173 | void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list, |
@@ -211,6 +178,7 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list, | |||
211 | * concatenated in descending order. | 178 | * concatenated in descending order. |
212 | */ | 179 | */ |
213 | struct list_head bucket[AMDGPU_BO_LIST_NUM_BUCKETS]; | 180 | struct list_head bucket[AMDGPU_BO_LIST_NUM_BUCKETS]; |
181 | struct amdgpu_bo_list_entry *e; | ||
214 | unsigned i; | 182 | unsigned i; |
215 | 183 | ||
216 | for (i = 0; i < AMDGPU_BO_LIST_NUM_BUCKETS; i++) | 184 | for (i = 0; i < AMDGPU_BO_LIST_NUM_BUCKETS; i++) |
@@ -221,14 +189,13 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list, | |||
221 | * in the list, the sort mustn't change the ordering of buffers | 189 | * in the list, the sort mustn't change the ordering of buffers |
222 | * with the same priority, i.e. it must be stable. | 190 | * with the same priority, i.e. it must be stable. |
223 | */ | 191 | */ |
224 | for (i = 0; i < list->num_entries; i++) { | 192 | amdgpu_bo_list_for_each_entry(e, list) { |
225 | unsigned priority = list->array[i].priority; | 193 | unsigned priority = e->priority; |
226 | 194 | ||
227 | if (!list->array[i].robj->parent) | 195 | if (!e->robj->parent) |
228 | list_add_tail(&list->array[i].tv.head, | 196 | list_add_tail(&e->tv.head, &bucket[priority]); |
229 | &bucket[priority]); | ||
230 | 197 | ||
231 | list->array[i].user_pages = NULL; | 198 | e->user_pages = NULL; |
232 | } | 199 | } |
233 | 200 | ||
234 | /* Connect the sorted buckets in the output list. */ | 201 | /* Connect the sorted buckets in the output list. */ |
@@ -238,20 +205,7 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list, | |||
238 | 205 | ||
239 | void amdgpu_bo_list_put(struct amdgpu_bo_list *list) | 206 | void amdgpu_bo_list_put(struct amdgpu_bo_list *list) |
240 | { | 207 | { |
241 | mutex_unlock(&list->lock); | 208 | kref_put(&list->refcount, amdgpu_bo_list_free); |
242 | kref_put(&list->refcount, amdgpu_bo_list_release_rcu); | ||
243 | } | ||
244 | |||
245 | void amdgpu_bo_list_free(struct amdgpu_bo_list *list) | ||
246 | { | ||
247 | unsigned i; | ||
248 | |||
249 | for (i = 0; i < list->num_entries; ++i) | ||
250 | amdgpu_bo_unref(&list->array[i].robj); | ||
251 | |||
252 | mutex_destroy(&list->lock); | ||
253 | kvfree(list->array); | ||
254 | kfree(list); | ||
255 | } | 209 | } |
256 | 210 | ||
257 | int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in, | 211 | int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in, |
@@ -304,7 +258,7 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data, | |||
304 | union drm_amdgpu_bo_list *args = data; | 258 | union drm_amdgpu_bo_list *args = data; |
305 | uint32_t handle = args->in.list_handle; | 259 | uint32_t handle = args->in.list_handle; |
306 | struct drm_amdgpu_bo_list_entry *info = NULL; | 260 | struct drm_amdgpu_bo_list_entry *info = NULL; |
307 | struct amdgpu_bo_list *list; | 261 | struct amdgpu_bo_list *list, *old; |
308 | int r; | 262 | int r; |
309 | 263 | ||
310 | r = amdgpu_bo_create_list_entry_array(&args->in, &info); | 264 | r = amdgpu_bo_create_list_entry_array(&args->in, &info); |
@@ -322,7 +276,7 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data, | |||
322 | r = idr_alloc(&fpriv->bo_list_handles, list, 1, 0, GFP_KERNEL); | 276 | r = idr_alloc(&fpriv->bo_list_handles, list, 1, 0, GFP_KERNEL); |
323 | mutex_unlock(&fpriv->bo_list_lock); | 277 | mutex_unlock(&fpriv->bo_list_lock); |
324 | if (r < 0) { | 278 | if (r < 0) { |
325 | amdgpu_bo_list_free(list); | 279 | amdgpu_bo_list_put(list); |
326 | return r; | 280 | return r; |
327 | } | 281 | } |
328 | 282 | ||
@@ -335,17 +289,22 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data, | |||
335 | break; | 289 | break; |
336 | 290 | ||
337 | case AMDGPU_BO_LIST_OP_UPDATE: | 291 | case AMDGPU_BO_LIST_OP_UPDATE: |
338 | r = -ENOENT; | 292 | r = amdgpu_bo_list_create(adev, filp, info, args->in.bo_number, |
339 | list = amdgpu_bo_list_get(fpriv, handle); | 293 | &list); |
340 | if (!list) | 294 | if (r) |
341 | goto error_free; | 295 | goto error_free; |
342 | 296 | ||
343 | r = amdgpu_bo_list_set(adev, filp, list, info, | 297 | mutex_lock(&fpriv->bo_list_lock); |
344 | args->in.bo_number); | 298 | old = idr_replace(&fpriv->bo_list_handles, list, handle); |
345 | amdgpu_bo_list_put(list); | 299 | mutex_unlock(&fpriv->bo_list_lock); |
346 | if (r) | 300 | |
301 | if (IS_ERR(old)) { | ||
302 | amdgpu_bo_list_put(list); | ||
303 | r = PTR_ERR(old); | ||
347 | goto error_free; | 304 | goto error_free; |
305 | } | ||
348 | 306 | ||
307 | amdgpu_bo_list_put(old); | ||
349 | break; | 308 | break; |
350 | 309 | ||
351 | default: | 310 | default: |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h new file mode 100644 index 000000000000..61b089768e1c --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * Copyright 2018 Advanced Micro Devices, Inc. | ||
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 shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | #ifndef __AMDGPU_BO_LIST_H__ | ||
24 | #define __AMDGPU_BO_LIST_H__ | ||
25 | |||
26 | #include <drm/ttm/ttm_execbuf_util.h> | ||
27 | #include <drm/amdgpu_drm.h> | ||
28 | |||
29 | struct amdgpu_device; | ||
30 | struct amdgpu_bo; | ||
31 | struct amdgpu_bo_va; | ||
32 | struct amdgpu_fpriv; | ||
33 | |||
34 | struct amdgpu_bo_list_entry { | ||
35 | struct amdgpu_bo *robj; | ||
36 | struct ttm_validate_buffer tv; | ||
37 | struct amdgpu_bo_va *bo_va; | ||
38 | uint32_t priority; | ||
39 | struct page **user_pages; | ||
40 | int user_invalidated; | ||
41 | }; | ||
42 | |||
43 | struct amdgpu_bo_list { | ||
44 | struct rcu_head rhead; | ||
45 | struct kref refcount; | ||
46 | struct amdgpu_bo *gds_obj; | ||
47 | struct amdgpu_bo *gws_obj; | ||
48 | struct amdgpu_bo *oa_obj; | ||
49 | unsigned first_userptr; | ||
50 | unsigned num_entries; | ||
51 | }; | ||
52 | |||
53 | int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id, | ||
54 | struct amdgpu_bo_list **result); | ||
55 | void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list, | ||
56 | struct list_head *validated); | ||
57 | void amdgpu_bo_list_put(struct amdgpu_bo_list *list); | ||
58 | int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in, | ||
59 | struct drm_amdgpu_bo_list_entry **info_param); | ||
60 | |||
61 | int amdgpu_bo_list_create(struct amdgpu_device *adev, | ||
62 | struct drm_file *filp, | ||
63 | struct drm_amdgpu_bo_list_entry *info, | ||
64 | unsigned num_entries, | ||
65 | struct amdgpu_bo_list **list); | ||
66 | |||
67 | static inline struct amdgpu_bo_list_entry * | ||
68 | amdgpu_bo_list_array_entry(struct amdgpu_bo_list *list, unsigned index) | ||
69 | { | ||
70 | struct amdgpu_bo_list_entry *array = (void *)&list[1]; | ||
71 | |||
72 | return &array[index]; | ||
73 | } | ||
74 | |||
75 | #define amdgpu_bo_list_for_each_entry(e, list) \ | ||
76 | for (e = amdgpu_bo_list_array_entry(list, 0); \ | ||
77 | e != amdgpu_bo_list_array_entry(list, (list)->num_entries); \ | ||
78 | ++e) | ||
79 | |||
80 | #define amdgpu_bo_list_for_each_userptr_entry(e, list) \ | ||
81 | for (e = amdgpu_bo_list_array_entry(list, (list)->first_userptr); \ | ||
82 | e != amdgpu_bo_list_array_entry(list, (list)->num_entries); \ | ||
83 | ++e) | ||
84 | |||
85 | #endif | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 178d9ce4eba1..502b94fb116a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -561,28 +561,38 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
561 | union drm_amdgpu_cs *cs) | 561 | union drm_amdgpu_cs *cs) |
562 | { | 562 | { |
563 | struct amdgpu_fpriv *fpriv = p->filp->driver_priv; | 563 | struct amdgpu_fpriv *fpriv = p->filp->driver_priv; |
564 | struct amdgpu_vm *vm = &fpriv->vm; | ||
564 | struct amdgpu_bo_list_entry *e; | 565 | struct amdgpu_bo_list_entry *e; |
565 | struct list_head duplicates; | 566 | struct list_head duplicates; |
566 | unsigned i, tries = 10; | ||
567 | struct amdgpu_bo *gds; | 567 | struct amdgpu_bo *gds; |
568 | struct amdgpu_bo *gws; | 568 | struct amdgpu_bo *gws; |
569 | struct amdgpu_bo *oa; | 569 | struct amdgpu_bo *oa; |
570 | unsigned tries = 10; | ||
570 | int r; | 571 | int r; |
571 | 572 | ||
572 | INIT_LIST_HEAD(&p->validated); | 573 | INIT_LIST_HEAD(&p->validated); |
573 | 574 | ||
574 | /* p->bo_list could already be assigned if AMDGPU_CHUNK_ID_BO_HANDLES is present */ | 575 | /* p->bo_list could already be assigned if AMDGPU_CHUNK_ID_BO_HANDLES is present */ |
575 | if (!p->bo_list) | 576 | if (cs->in.bo_list_handle) { |
576 | p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); | 577 | if (p->bo_list) |
577 | else | 578 | return -EINVAL; |
578 | mutex_lock(&p->bo_list->lock); | ||
579 | 579 | ||
580 | if (p->bo_list) { | 580 | r = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle, |
581 | amdgpu_bo_list_get_list(p->bo_list, &p->validated); | 581 | &p->bo_list); |
582 | if (p->bo_list->first_userptr != p->bo_list->num_entries) | 582 | if (r) |
583 | p->mn = amdgpu_mn_get(p->adev, AMDGPU_MN_TYPE_GFX); | 583 | return r; |
584 | } else if (!p->bo_list) { | ||
585 | /* Create a empty bo_list when no handle is provided */ | ||
586 | r = amdgpu_bo_list_create(p->adev, p->filp, NULL, 0, | ||
587 | &p->bo_list); | ||
588 | if (r) | ||
589 | return r; | ||
584 | } | 590 | } |
585 | 591 | ||
592 | amdgpu_bo_list_get_list(p->bo_list, &p->validated); | ||
593 | if (p->bo_list->first_userptr != p->bo_list->num_entries) | ||
594 | p->mn = amdgpu_mn_get(p->adev, AMDGPU_MN_TYPE_GFX); | ||
595 | |||
586 | INIT_LIST_HEAD(&duplicates); | 596 | INIT_LIST_HEAD(&duplicates); |
587 | amdgpu_vm_get_pd_bo(&fpriv->vm, &p->validated, &p->vm_pd); | 597 | amdgpu_vm_get_pd_bo(&fpriv->vm, &p->validated, &p->vm_pd); |
588 | 598 | ||
@@ -591,7 +601,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
591 | 601 | ||
592 | while (1) { | 602 | while (1) { |
593 | struct list_head need_pages; | 603 | struct list_head need_pages; |
594 | unsigned i; | ||
595 | 604 | ||
596 | r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true, | 605 | r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true, |
597 | &duplicates); | 606 | &duplicates); |
@@ -601,17 +610,9 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
601 | goto error_free_pages; | 610 | goto error_free_pages; |
602 | } | 611 | } |
603 | 612 | ||
604 | /* Without a BO list we don't have userptr BOs */ | ||
605 | if (!p->bo_list) | ||
606 | break; | ||
607 | |||
608 | INIT_LIST_HEAD(&need_pages); | 613 | INIT_LIST_HEAD(&need_pages); |
609 | for (i = p->bo_list->first_userptr; | 614 | amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { |
610 | i < p->bo_list->num_entries; ++i) { | 615 | struct amdgpu_bo *bo = e->robj; |
611 | struct amdgpu_bo *bo; | ||
612 | |||
613 | e = &p->bo_list->array[i]; | ||
614 | bo = e->robj; | ||
615 | 616 | ||
616 | if (amdgpu_ttm_tt_userptr_invalidated(bo->tbo.ttm, | 617 | if (amdgpu_ttm_tt_userptr_invalidated(bo->tbo.ttm, |
617 | &e->user_invalidated) && e->user_pages) { | 618 | &e->user_invalidated) && e->user_pages) { |
@@ -703,23 +704,12 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
703 | amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved, | 704 | amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved, |
704 | p->bytes_moved_vis); | 705 | p->bytes_moved_vis); |
705 | 706 | ||
706 | if (p->bo_list) { | 707 | gds = p->bo_list->gds_obj; |
707 | struct amdgpu_vm *vm = &fpriv->vm; | 708 | gws = p->bo_list->gws_obj; |
708 | unsigned i; | 709 | oa = p->bo_list->oa_obj; |
709 | |||
710 | gds = p->bo_list->gds_obj; | ||
711 | gws = p->bo_list->gws_obj; | ||
712 | oa = p->bo_list->oa_obj; | ||
713 | for (i = 0; i < p->bo_list->num_entries; i++) { | ||
714 | struct amdgpu_bo *bo = p->bo_list->array[i].robj; | ||
715 | 710 | ||
716 | p->bo_list->array[i].bo_va = amdgpu_vm_bo_find(vm, bo); | 711 | amdgpu_bo_list_for_each_entry(e, p->bo_list) |
717 | } | 712 | e->bo_va = amdgpu_vm_bo_find(vm, e->robj); |
718 | } else { | ||
719 | gds = p->adev->gds.gds_gfx_bo; | ||
720 | gws = p->adev->gds.gws_gfx_bo; | ||
721 | oa = p->adev->gds.oa_gfx_bo; | ||
722 | } | ||
723 | 713 | ||
724 | if (gds) { | 714 | if (gds) { |
725 | p->job->gds_base = amdgpu_bo_gpu_offset(gds); | 715 | p->job->gds_base = amdgpu_bo_gpu_offset(gds); |
@@ -747,18 +737,13 @@ error_validate: | |||
747 | 737 | ||
748 | error_free_pages: | 738 | error_free_pages: |
749 | 739 | ||
750 | if (p->bo_list) { | 740 | amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { |
751 | for (i = p->bo_list->first_userptr; | 741 | if (!e->user_pages) |
752 | i < p->bo_list->num_entries; ++i) { | 742 | continue; |
753 | e = &p->bo_list->array[i]; | ||
754 | |||
755 | if (!e->user_pages) | ||
756 | continue; | ||
757 | 743 | ||
758 | release_pages(e->user_pages, | 744 | release_pages(e->user_pages, |
759 | e->robj->tbo.ttm->num_pages); | 745 | e->robj->tbo.ttm->num_pages); |
760 | kvfree(e->user_pages); | 746 | kvfree(e->user_pages); |
761 | } | ||
762 | } | 747 | } |
763 | 748 | ||
764 | return r; | 749 | return r; |
@@ -820,12 +805,13 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, | |||
820 | 805 | ||
821 | static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p) | 806 | static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p) |
822 | { | 807 | { |
823 | struct amdgpu_device *adev = p->adev; | ||
824 | struct amdgpu_fpriv *fpriv = p->filp->driver_priv; | 808 | struct amdgpu_fpriv *fpriv = p->filp->driver_priv; |
809 | struct amdgpu_device *adev = p->adev; | ||
825 | struct amdgpu_vm *vm = &fpriv->vm; | 810 | struct amdgpu_vm *vm = &fpriv->vm; |
811 | struct amdgpu_bo_list_entry *e; | ||
826 | struct amdgpu_bo_va *bo_va; | 812 | struct amdgpu_bo_va *bo_va; |
827 | struct amdgpu_bo *bo; | 813 | struct amdgpu_bo *bo; |
828 | int i, r; | 814 | int r; |
829 | 815 | ||
830 | r = amdgpu_vm_clear_freed(adev, vm, NULL); | 816 | r = amdgpu_vm_clear_freed(adev, vm, NULL); |
831 | if (r) | 817 | if (r) |
@@ -855,29 +841,26 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p) | |||
855 | return r; | 841 | return r; |
856 | } | 842 | } |
857 | 843 | ||
858 | if (p->bo_list) { | 844 | amdgpu_bo_list_for_each_entry(e, p->bo_list) { |
859 | for (i = 0; i < p->bo_list->num_entries; i++) { | 845 | struct dma_fence *f; |
860 | struct dma_fence *f; | ||
861 | |||
862 | /* ignore duplicates */ | ||
863 | bo = p->bo_list->array[i].robj; | ||
864 | if (!bo) | ||
865 | continue; | ||
866 | 846 | ||
867 | bo_va = p->bo_list->array[i].bo_va; | 847 | /* ignore duplicates */ |
868 | if (bo_va == NULL) | 848 | bo = e->robj; |
869 | continue; | 849 | if (!bo) |
850 | continue; | ||
870 | 851 | ||
871 | r = amdgpu_vm_bo_update(adev, bo_va, false); | 852 | bo_va = e->bo_va; |
872 | if (r) | 853 | if (bo_va == NULL) |
873 | return r; | 854 | continue; |
874 | 855 | ||
875 | f = bo_va->last_pt_update; | 856 | r = amdgpu_vm_bo_update(adev, bo_va, false); |
876 | r = amdgpu_sync_fence(adev, &p->job->sync, f, false); | 857 | if (r) |
877 | if (r) | 858 | return r; |
878 | return r; | ||
879 | } | ||
880 | 859 | ||
860 | f = bo_va->last_pt_update; | ||
861 | r = amdgpu_sync_fence(adev, &p->job->sync, f, false); | ||
862 | if (r) | ||
863 | return r; | ||
881 | } | 864 | } |
882 | 865 | ||
883 | r = amdgpu_vm_handle_moved(adev, vm); | 866 | r = amdgpu_vm_handle_moved(adev, vm); |
@@ -892,15 +875,14 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p) | |||
892 | if (r) | 875 | if (r) |
893 | return r; | 876 | return r; |
894 | 877 | ||
895 | if (amdgpu_vm_debug && p->bo_list) { | 878 | if (amdgpu_vm_debug) { |
896 | /* Invalidate all BOs to test for userspace bugs */ | 879 | /* Invalidate all BOs to test for userspace bugs */ |
897 | for (i = 0; i < p->bo_list->num_entries; i++) { | 880 | amdgpu_bo_list_for_each_entry(e, p->bo_list) { |
898 | /* ignore duplicates */ | 881 | /* ignore duplicates */ |
899 | bo = p->bo_list->array[i].robj; | 882 | if (!e->robj) |
900 | if (!bo) | ||
901 | continue; | 883 | continue; |
902 | 884 | ||
903 | amdgpu_vm_bo_invalidate(adev, bo, false); | 885 | amdgpu_vm_bo_invalidate(adev, e->robj, false); |
904 | } | 886 | } |
905 | } | 887 | } |
906 | 888 | ||
@@ -916,7 +898,7 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, | |||
916 | int r; | 898 | int r; |
917 | 899 | ||
918 | /* Only for UVD/VCE VM emulation */ | 900 | /* Only for UVD/VCE VM emulation */ |
919 | if (p->ring->funcs->parse_cs) { | 901 | if (p->ring->funcs->parse_cs || p->ring->funcs->patch_cs_in_place) { |
920 | unsigned i, j; | 902 | unsigned i, j; |
921 | 903 | ||
922 | for (i = 0, j = 0; i < p->nchunks && j < p->job->num_ibs; i++) { | 904 | for (i = 0, j = 0; i < p->nchunks && j < p->job->num_ibs; i++) { |
@@ -957,12 +939,20 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, | |||
957 | offset = m->start * AMDGPU_GPU_PAGE_SIZE; | 939 | offset = m->start * AMDGPU_GPU_PAGE_SIZE; |
958 | kptr += va_start - offset; | 940 | kptr += va_start - offset; |
959 | 941 | ||
960 | memcpy(ib->ptr, kptr, chunk_ib->ib_bytes); | 942 | if (p->ring->funcs->parse_cs) { |
961 | amdgpu_bo_kunmap(aobj); | 943 | memcpy(ib->ptr, kptr, chunk_ib->ib_bytes); |
962 | 944 | amdgpu_bo_kunmap(aobj); | |
963 | r = amdgpu_ring_parse_cs(ring, p, j); | 945 | |
964 | if (r) | 946 | r = amdgpu_ring_parse_cs(ring, p, j); |
965 | return r; | 947 | if (r) |
948 | return r; | ||
949 | } else { | ||
950 | ib->ptr = (uint32_t *)kptr; | ||
951 | r = amdgpu_ring_patch_cs_in_place(ring, p, j); | ||
952 | amdgpu_bo_kunmap(aobj); | ||
953 | if (r) | ||
954 | return r; | ||
955 | } | ||
966 | 956 | ||
967 | j++; | 957 | j++; |
968 | } | 958 | } |
@@ -1207,25 +1197,23 @@ static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p) | |||
1207 | static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, | 1197 | static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, |
1208 | union drm_amdgpu_cs *cs) | 1198 | union drm_amdgpu_cs *cs) |
1209 | { | 1199 | { |
1200 | struct amdgpu_fpriv *fpriv = p->filp->driver_priv; | ||
1210 | struct amdgpu_ring *ring = p->ring; | 1201 | struct amdgpu_ring *ring = p->ring; |
1211 | struct drm_sched_entity *entity = &p->ctx->rings[ring->idx].entity; | 1202 | struct drm_sched_entity *entity = &p->ctx->rings[ring->idx].entity; |
1212 | enum drm_sched_priority priority; | 1203 | enum drm_sched_priority priority; |
1204 | struct amdgpu_bo_list_entry *e; | ||
1213 | struct amdgpu_job *job; | 1205 | struct amdgpu_job *job; |
1214 | unsigned i; | ||
1215 | uint64_t seq; | 1206 | uint64_t seq; |
1216 | 1207 | ||
1217 | int r; | 1208 | int r; |
1218 | 1209 | ||
1219 | amdgpu_mn_lock(p->mn); | 1210 | amdgpu_mn_lock(p->mn); |
1220 | if (p->bo_list) { | 1211 | amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { |
1221 | for (i = p->bo_list->first_userptr; | 1212 | struct amdgpu_bo *bo = e->robj; |
1222 | i < p->bo_list->num_entries; ++i) { | 1213 | |
1223 | struct amdgpu_bo *bo = p->bo_list->array[i].robj; | 1214 | if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) { |
1224 | 1215 | amdgpu_mn_unlock(p->mn); | |
1225 | if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) { | 1216 | return -ERESTARTSYS; |
1226 | amdgpu_mn_unlock(p->mn); | ||
1227 | return -ERESTARTSYS; | ||
1228 | } | ||
1229 | } | 1217 | } |
1230 | } | 1218 | } |
1231 | 1219 | ||
@@ -1259,6 +1247,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, | |||
1259 | amdgpu_job_free_resources(job); | 1247 | amdgpu_job_free_resources(job); |
1260 | 1248 | ||
1261 | trace_amdgpu_cs_ioctl(job); | 1249 | trace_amdgpu_cs_ioctl(job); |
1250 | amdgpu_vm_bo_trace_cs(&fpriv->vm, &p->ticket); | ||
1262 | priority = job->base.s_priority; | 1251 | priority = job->base.s_priority; |
1263 | drm_sched_entity_push_job(&job->base, entity); | 1252 | drm_sched_entity_push_job(&job->base, entity); |
1264 | 1253 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index c7dce14fd47d..bd98cc5fb97b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |||
@@ -286,7 +286,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
286 | struct drm_crtc *crtc; | 286 | struct drm_crtc *crtc; |
287 | uint32_t ui32 = 0; | 287 | uint32_t ui32 = 0; |
288 | uint64_t ui64 = 0; | 288 | uint64_t ui64 = 0; |
289 | int i, found; | 289 | int i, j, found; |
290 | int ui32_size = sizeof(ui32); | 290 | int ui32_size = sizeof(ui32); |
291 | 291 | ||
292 | if (!info->return_size || !info->return_pointer) | 292 | if (!info->return_size || !info->return_pointer) |
@@ -348,7 +348,11 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
348 | break; | 348 | break; |
349 | case AMDGPU_HW_IP_UVD: | 349 | case AMDGPU_HW_IP_UVD: |
350 | type = AMD_IP_BLOCK_TYPE_UVD; | 350 | type = AMD_IP_BLOCK_TYPE_UVD; |
351 | ring_mask |= adev->uvd.inst[0].ring.ready; | 351 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { |
352 | if (adev->uvd.harvest_config & (1 << i)) | ||
353 | continue; | ||
354 | ring_mask |= adev->uvd.inst[i].ring.ready; | ||
355 | } | ||
352 | ib_start_alignment = 64; | 356 | ib_start_alignment = 64; |
353 | ib_size_alignment = 64; | 357 | ib_size_alignment = 64; |
354 | break; | 358 | break; |
@@ -361,9 +365,12 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
361 | break; | 365 | break; |
362 | case AMDGPU_HW_IP_UVD_ENC: | 366 | case AMDGPU_HW_IP_UVD_ENC: |
363 | type = AMD_IP_BLOCK_TYPE_UVD; | 367 | type = AMD_IP_BLOCK_TYPE_UVD; |
364 | for (i = 0; i < adev->uvd.num_enc_rings; i++) | 368 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { |
365 | ring_mask |= | 369 | if (adev->uvd.harvest_config & (1 << i)) |
366 | adev->uvd.inst[0].ring_enc[i].ready << i; | 370 | continue; |
371 | for (j = 0; j < adev->uvd.num_enc_rings; j++) | ||
372 | ring_mask |= adev->uvd.inst[i].ring_enc[j].ready << j; | ||
373 | } | ||
367 | ib_start_alignment = 64; | 374 | ib_start_alignment = 64; |
368 | ib_size_alignment = 64; | 375 | ib_size_alignment = 64; |
369 | break; | 376 | break; |
@@ -960,7 +967,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev, | |||
960 | amdgpu_bo_unref(&pd); | 967 | amdgpu_bo_unref(&pd); |
961 | 968 | ||
962 | idr_for_each_entry(&fpriv->bo_list_handles, list, handle) | 969 | idr_for_each_entry(&fpriv->bo_list_handles, list, handle) |
963 | amdgpu_bo_list_free(list); | 970 | amdgpu_bo_list_put(list); |
964 | 971 | ||
965 | idr_destroy(&fpriv->bo_list_handles); | 972 | idr_destroy(&fpriv->bo_list_handles); |
966 | mutex_destroy(&fpriv->bo_list_lock); | 973 | mutex_destroy(&fpriv->bo_list_lock); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 21bfa2d8039e..b0e14a3d54ef 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | |||
@@ -825,7 +825,7 @@ struct amdgpu_bo *amdgpu_bo_ref(struct amdgpu_bo *bo) | |||
825 | if (bo == NULL) | 825 | if (bo == NULL) |
826 | return NULL; | 826 | return NULL; |
827 | 827 | ||
828 | ttm_bo_reference(&bo->tbo); | 828 | ttm_bo_get(&bo->tbo); |
829 | return bo; | 829 | return bo; |
830 | } | 830 | } |
831 | 831 | ||
@@ -843,9 +843,8 @@ void amdgpu_bo_unref(struct amdgpu_bo **bo) | |||
843 | return; | 843 | return; |
844 | 844 | ||
845 | tbo = &((*bo)->tbo); | 845 | tbo = &((*bo)->tbo); |
846 | ttm_bo_unref(&tbo); | 846 | ttm_bo_put(tbo); |
847 | if (tbo == NULL) | 847 | *bo = NULL; |
848 | *bo = NULL; | ||
849 | } | 848 | } |
850 | 849 | ||
851 | /** | 850 | /** |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 15a1192c1ec5..8f98629fbe59 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/power_supply.h> | 31 | #include <linux/power_supply.h> |
32 | #include <linux/hwmon.h> | 32 | #include <linux/hwmon.h> |
33 | #include <linux/hwmon-sysfs.h> | 33 | #include <linux/hwmon-sysfs.h> |
34 | 34 | #include <linux/nospec.h> | |
35 | 35 | ||
36 | static int amdgpu_debugfs_pm_init(struct amdgpu_device *adev); | 36 | static int amdgpu_debugfs_pm_init(struct amdgpu_device *adev); |
37 | 37 | ||
@@ -403,6 +403,7 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev, | |||
403 | count = -EINVAL; | 403 | count = -EINVAL; |
404 | goto fail; | 404 | goto fail; |
405 | } | 405 | } |
406 | idx = array_index_nospec(idx, ARRAY_SIZE(data.states)); | ||
406 | 407 | ||
407 | amdgpu_dpm_get_pp_num_states(adev, &data); | 408 | amdgpu_dpm_get_pp_num_states(adev, &data); |
408 | state = data.states[idx]; | 409 | state = data.states[idx]; |
@@ -1185,7 +1186,7 @@ static ssize_t amdgpu_hwmon_show_vddnb(struct device *dev, | |||
1185 | int r, size = sizeof(vddnb); | 1186 | int r, size = sizeof(vddnb); |
1186 | 1187 | ||
1187 | /* only APUs have vddnb */ | 1188 | /* only APUs have vddnb */ |
1188 | if (adev->flags & AMD_IS_APU) | 1189 | if (!(adev->flags & AMD_IS_APU)) |
1189 | return -EINVAL; | 1190 | return -EINVAL; |
1190 | 1191 | ||
1191 | /* Can't get voltage when the card is off */ | 1192 | /* Can't get voltage when the card is off */ |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c index d8357290ad09..a172bba32b45 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c | |||
@@ -214,7 +214,7 @@ int amdgpu_queue_mgr_map(struct amdgpu_device *adev, | |||
214 | u32 hw_ip, u32 instance, u32 ring, | 214 | u32 hw_ip, u32 instance, u32 ring, |
215 | struct amdgpu_ring **out_ring) | 215 | struct amdgpu_ring **out_ring) |
216 | { | 216 | { |
217 | int r, ip_num_rings; | 217 | int i, r, ip_num_rings = 0; |
218 | struct amdgpu_queue_mapper *mapper = &mgr->mapper[hw_ip]; | 218 | struct amdgpu_queue_mapper *mapper = &mgr->mapper[hw_ip]; |
219 | 219 | ||
220 | if (!adev || !mgr || !out_ring) | 220 | if (!adev || !mgr || !out_ring) |
@@ -243,14 +243,21 @@ int amdgpu_queue_mgr_map(struct amdgpu_device *adev, | |||
243 | ip_num_rings = adev->sdma.num_instances; | 243 | ip_num_rings = adev->sdma.num_instances; |
244 | break; | 244 | break; |
245 | case AMDGPU_HW_IP_UVD: | 245 | case AMDGPU_HW_IP_UVD: |
246 | ip_num_rings = adev->uvd.num_uvd_inst; | 246 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { |
247 | if (!(adev->uvd.harvest_config & (1 << i))) | ||
248 | ip_num_rings++; | ||
249 | } | ||
247 | break; | 250 | break; |
248 | case AMDGPU_HW_IP_VCE: | 251 | case AMDGPU_HW_IP_VCE: |
249 | ip_num_rings = adev->vce.num_rings; | 252 | ip_num_rings = adev->vce.num_rings; |
250 | break; | 253 | break; |
251 | case AMDGPU_HW_IP_UVD_ENC: | 254 | case AMDGPU_HW_IP_UVD_ENC: |
255 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { | ||
256 | if (!(adev->uvd.harvest_config & (1 << i))) | ||
257 | ip_num_rings++; | ||
258 | } | ||
252 | ip_num_rings = | 259 | ip_num_rings = |
253 | adev->uvd.num_enc_rings * adev->uvd.num_uvd_inst; | 260 | adev->uvd.num_enc_rings * ip_num_rings; |
254 | break; | 261 | break; |
255 | case AMDGPU_HW_IP_VCN_DEC: | 262 | case AMDGPU_HW_IP_VCN_DEC: |
256 | ip_num_rings = 1; | 263 | ip_num_rings = 1; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 5018c0b6bf1a..d242b9a51e90 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | |||
@@ -123,6 +123,7 @@ struct amdgpu_ring_funcs { | |||
123 | void (*set_wptr)(struct amdgpu_ring *ring); | 123 | void (*set_wptr)(struct amdgpu_ring *ring); |
124 | /* validating and patching of IBs */ | 124 | /* validating and patching of IBs */ |
125 | int (*parse_cs)(struct amdgpu_cs_parser *p, uint32_t ib_idx); | 125 | int (*parse_cs)(struct amdgpu_cs_parser *p, uint32_t ib_idx); |
126 | int (*patch_cs_in_place)(struct amdgpu_cs_parser *p, uint32_t ib_idx); | ||
126 | /* constants to calculate how many DW are needed for an emit */ | 127 | /* constants to calculate how many DW are needed for an emit */ |
127 | unsigned emit_frame_size; | 128 | unsigned emit_frame_size; |
128 | unsigned emit_ib_size; | 129 | unsigned emit_ib_size; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h index 11f262f15200..7206a0025b17 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h | |||
@@ -314,6 +314,11 @@ DEFINE_EVENT(amdgpu_vm_mapping, amdgpu_vm_bo_mapping, | |||
314 | TP_ARGS(mapping) | 314 | TP_ARGS(mapping) |
315 | ); | 315 | ); |
316 | 316 | ||
317 | DEFINE_EVENT(amdgpu_vm_mapping, amdgpu_vm_bo_cs, | ||
318 | TP_PROTO(struct amdgpu_bo_va_mapping *mapping), | ||
319 | TP_ARGS(mapping) | ||
320 | ); | ||
321 | |||
317 | TRACE_EVENT(amdgpu_vm_set_ptes, | 322 | TRACE_EVENT(amdgpu_vm_set_ptes, |
318 | TP_PROTO(uint64_t pe, uint64_t addr, unsigned count, | 323 | TP_PROTO(uint64_t pe, uint64_t addr, unsigned count, |
319 | uint32_t incr, uint64_t flags), | 324 | uint32_t incr, uint64_t flags), |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 8c4358e36c87..fcf421263fd9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | |||
@@ -92,11 +92,9 @@ static void amdgpu_ttm_mem_global_release(struct drm_global_reference *ref) | |||
92 | } | 92 | } |
93 | 93 | ||
94 | /** | 94 | /** |
95 | * amdgpu_ttm_global_init - Initialize global TTM memory reference | 95 | * amdgpu_ttm_global_init - Initialize global TTM memory reference structures. |
96 | * structures. | ||
97 | * | 96 | * |
98 | * @adev: AMDGPU device for which the global structures need to be | 97 | * @adev: AMDGPU device for which the global structures need to be registered. |
99 | * registered. | ||
100 | * | 98 | * |
101 | * This is called as part of the AMDGPU ttm init from amdgpu_ttm_init() | 99 | * This is called as part of the AMDGPU ttm init from amdgpu_ttm_init() |
102 | * during bring up. | 100 | * during bring up. |
@@ -162,13 +160,12 @@ static int amdgpu_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags) | |||
162 | } | 160 | } |
163 | 161 | ||
164 | /** | 162 | /** |
165 | * amdgpu_init_mem_type - Initialize a memory manager for a specific | 163 | * amdgpu_init_mem_type - Initialize a memory manager for a specific type of |
166 | * type of memory request. | 164 | * memory request. |
167 | * | 165 | * |
168 | * @bdev: The TTM BO device object (contains a reference to | 166 | * @bdev: The TTM BO device object (contains a reference to amdgpu_device) |
169 | * amdgpu_device) | 167 | * @type: The type of memory requested |
170 | * @type: The type of memory requested | 168 | * @man: The memory type manager for each domain |
171 | * @man: | ||
172 | * | 169 | * |
173 | * This is called by ttm_bo_init_mm() when a buffer object is being | 170 | * This is called by ttm_bo_init_mm() when a buffer object is being |
174 | * initialized. | 171 | * initialized. |
@@ -292,8 +289,8 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo, | |||
292 | /** | 289 | /** |
293 | * amdgpu_verify_access - Verify access for a mmap call | 290 | * amdgpu_verify_access - Verify access for a mmap call |
294 | * | 291 | * |
295 | * @bo: The buffer object to map | 292 | * @bo: The buffer object to map |
296 | * @filp: The file pointer from the process performing the mmap | 293 | * @filp: The file pointer from the process performing the mmap |
297 | * | 294 | * |
298 | * This is called by ttm_bo_mmap() to verify whether a process | 295 | * This is called by ttm_bo_mmap() to verify whether a process |
299 | * has the right to mmap a BO to their process space. | 296 | * has the right to mmap a BO to their process space. |
@@ -318,11 +315,10 @@ static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp) | |||
318 | /** | 315 | /** |
319 | * amdgpu_move_null - Register memory for a buffer object | 316 | * amdgpu_move_null - Register memory for a buffer object |
320 | * | 317 | * |
321 | * @bo: The bo to assign the memory to | 318 | * @bo: The bo to assign the memory to |
322 | * @new_mem: The memory to be assigned. | 319 | * @new_mem: The memory to be assigned. |
323 | * | 320 | * |
324 | * Assign the memory from new_mem to the memory of the buffer object | 321 | * Assign the memory from new_mem to the memory of the buffer object bo. |
325 | * bo. | ||
326 | */ | 322 | */ |
327 | static void amdgpu_move_null(struct ttm_buffer_object *bo, | 323 | static void amdgpu_move_null(struct ttm_buffer_object *bo, |
328 | struct ttm_mem_reg *new_mem) | 324 | struct ttm_mem_reg *new_mem) |
@@ -335,8 +331,12 @@ static void amdgpu_move_null(struct ttm_buffer_object *bo, | |||
335 | } | 331 | } |
336 | 332 | ||
337 | /** | 333 | /** |
338 | * amdgpu_mm_node_addr - Compute the GPU relative offset of a GTT | 334 | * amdgpu_mm_node_addr - Compute the GPU relative offset of a GTT buffer. |
339 | * buffer. | 335 | * |
336 | * @bo: The bo to assign the memory to. | ||
337 | * @mm_node: Memory manager node for drm allocator. | ||
338 | * @mem: The region where the bo resides. | ||
339 | * | ||
340 | */ | 340 | */ |
341 | static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo, | 341 | static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo, |
342 | struct drm_mm_node *mm_node, | 342 | struct drm_mm_node *mm_node, |
@@ -352,10 +352,12 @@ static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo, | |||
352 | } | 352 | } |
353 | 353 | ||
354 | /** | 354 | /** |
355 | * amdgpu_find_mm_node - Helper function finds the drm_mm_node | 355 | * amdgpu_find_mm_node - Helper function finds the drm_mm_node corresponding to |
356 | * corresponding to @offset. It also modifies | 356 | * @offset. It also modifies the offset to be within the drm_mm_node returned |
357 | * the offset to be within the drm_mm_node | 357 | * |
358 | * returned | 358 | * @mem: The region where the bo resides. |
359 | * @offset: The offset that drm_mm_node is used for finding. | ||
360 | * | ||
359 | */ | 361 | */ |
360 | static struct drm_mm_node *amdgpu_find_mm_node(struct ttm_mem_reg *mem, | 362 | static struct drm_mm_node *amdgpu_find_mm_node(struct ttm_mem_reg *mem, |
361 | unsigned long *offset) | 363 | unsigned long *offset) |
@@ -497,8 +499,8 @@ error: | |||
497 | /** | 499 | /** |
498 | * amdgpu_move_blit - Copy an entire buffer to another buffer | 500 | * amdgpu_move_blit - Copy an entire buffer to another buffer |
499 | * | 501 | * |
500 | * This is a helper called by amdgpu_bo_move() and | 502 | * This is a helper called by amdgpu_bo_move() and amdgpu_move_vram_ram() to |
501 | * amdgpu_move_vram_ram() to help move buffers to and from VRAM. | 503 | * help move buffers to and from VRAM. |
502 | */ | 504 | */ |
503 | static int amdgpu_move_blit(struct ttm_buffer_object *bo, | 505 | static int amdgpu_move_blit(struct ttm_buffer_object *bo, |
504 | bool evict, bool no_wait_gpu, | 506 | bool evict, bool no_wait_gpu, |
@@ -580,7 +582,7 @@ static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict, | |||
580 | } | 582 | } |
581 | 583 | ||
582 | /* blit VRAM to GTT */ | 584 | /* blit VRAM to GTT */ |
583 | r = amdgpu_move_blit(bo, true, ctx->no_wait_gpu, &tmp_mem, old_mem); | 585 | r = amdgpu_move_blit(bo, evict, ctx->no_wait_gpu, &tmp_mem, old_mem); |
584 | if (unlikely(r)) { | 586 | if (unlikely(r)) { |
585 | goto out_cleanup; | 587 | goto out_cleanup; |
586 | } | 588 | } |
@@ -632,7 +634,7 @@ static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, bool evict, | |||
632 | } | 634 | } |
633 | 635 | ||
634 | /* copy to VRAM */ | 636 | /* copy to VRAM */ |
635 | r = amdgpu_move_blit(bo, true, ctx->no_wait_gpu, new_mem, old_mem); | 637 | r = amdgpu_move_blit(bo, evict, ctx->no_wait_gpu, new_mem, old_mem); |
636 | if (unlikely(r)) { | 638 | if (unlikely(r)) { |
637 | goto out_cleanup; | 639 | goto out_cleanup; |
638 | } | 640 | } |
@@ -794,8 +796,8 @@ struct amdgpu_ttm_tt { | |||
794 | }; | 796 | }; |
795 | 797 | ||
796 | /** | 798 | /** |
797 | * amdgpu_ttm_tt_get_user_pages - Pin pages of memory pointed to | 799 | * amdgpu_ttm_tt_get_user_pages - Pin pages of memory pointed to by a USERPTR |
798 | * by a USERPTR pointer to memory | 800 | * pointer to memory |
799 | * | 801 | * |
800 | * Called by amdgpu_gem_userptr_ioctl() and amdgpu_cs_parser_bos(). | 802 | * Called by amdgpu_gem_userptr_ioctl() and amdgpu_cs_parser_bos(). |
801 | * This provides a wrapper around the get_user_pages() call to provide | 803 | * This provides a wrapper around the get_user_pages() call to provide |
@@ -818,8 +820,10 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages) | |||
818 | down_read(&mm->mmap_sem); | 820 | down_read(&mm->mmap_sem); |
819 | 821 | ||
820 | if (gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) { | 822 | if (gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) { |
821 | /* check that we only use anonymous memory | 823 | /* |
822 | to prevent problems with writeback */ | 824 | * check that we only use anonymous memory to prevent problems |
825 | * with writeback | ||
826 | */ | ||
823 | unsigned long end = gtt->userptr + ttm->num_pages * PAGE_SIZE; | 827 | unsigned long end = gtt->userptr + ttm->num_pages * PAGE_SIZE; |
824 | struct vm_area_struct *vma; | 828 | struct vm_area_struct *vma; |
825 | 829 | ||
@@ -870,10 +874,9 @@ release_pages: | |||
870 | } | 874 | } |
871 | 875 | ||
872 | /** | 876 | /** |
873 | * amdgpu_ttm_tt_set_user_pages - Copy pages in, putting old pages | 877 | * amdgpu_ttm_tt_set_user_pages - Copy pages in, putting old pages as necessary. |
874 | * as necessary. | ||
875 | * | 878 | * |
876 | * Called by amdgpu_cs_list_validate(). This creates the page list | 879 | * Called by amdgpu_cs_list_validate(). This creates the page list |
877 | * that backs user memory and will ultimately be mapped into the device | 880 | * that backs user memory and will ultimately be mapped into the device |
878 | * address space. | 881 | * address space. |
879 | */ | 882 | */ |
@@ -915,8 +918,7 @@ void amdgpu_ttm_tt_mark_user_pages(struct ttm_tt *ttm) | |||
915 | } | 918 | } |
916 | 919 | ||
917 | /** | 920 | /** |
918 | * amdgpu_ttm_tt_pin_userptr - prepare the sg table with the | 921 | * amdgpu_ttm_tt_pin_userptr - prepare the sg table with the user pages |
919 | * user pages | ||
920 | * | 922 | * |
921 | * Called by amdgpu_ttm_backend_bind() | 923 | * Called by amdgpu_ttm_backend_bind() |
922 | **/ | 924 | **/ |
@@ -1295,8 +1297,8 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) | |||
1295 | } | 1297 | } |
1296 | 1298 | ||
1297 | /** | 1299 | /** |
1298 | * amdgpu_ttm_tt_set_userptr - Initialize userptr GTT ttm_tt | 1300 | * amdgpu_ttm_tt_set_userptr - Initialize userptr GTT ttm_tt for the current |
1299 | * for the current task | 1301 | * task |
1300 | * | 1302 | * |
1301 | * @ttm: The ttm_tt object to bind this userptr object to | 1303 | * @ttm: The ttm_tt object to bind this userptr object to |
1302 | * @addr: The address in the current tasks VM space to use | 1304 | * @addr: The address in the current tasks VM space to use |
@@ -1346,9 +1348,8 @@ struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm) | |||
1346 | } | 1348 | } |
1347 | 1349 | ||
1348 | /** | 1350 | /** |
1349 | * amdgpu_ttm_tt_affect_userptr - Determine if a ttm_tt object lays | 1351 | * amdgpu_ttm_tt_affect_userptr - Determine if a ttm_tt object lays inside an |
1350 | * inside an address range for the | 1352 | * address range for the current task. |
1351 | * current task. | ||
1352 | * | 1353 | * |
1353 | */ | 1354 | */ |
1354 | bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, | 1355 | bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, |
@@ -1386,8 +1387,7 @@ bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, | |||
1386 | } | 1387 | } |
1387 | 1388 | ||
1388 | /** | 1389 | /** |
1389 | * amdgpu_ttm_tt_userptr_invalidated - Has the ttm_tt object been | 1390 | * amdgpu_ttm_tt_userptr_invalidated - Has the ttm_tt object been invalidated? |
1390 | * invalidated? | ||
1391 | */ | 1391 | */ |
1392 | bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, | 1392 | bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, |
1393 | int *last_invalidated) | 1393 | int *last_invalidated) |
@@ -1400,10 +1400,8 @@ bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, | |||
1400 | } | 1400 | } |
1401 | 1401 | ||
1402 | /** | 1402 | /** |
1403 | * amdgpu_ttm_tt_userptr_needs_pages - Have the pages backing this | 1403 | * amdgpu_ttm_tt_userptr_needs_pages - Have the pages backing this ttm_tt object |
1404 | * ttm_tt object been invalidated | 1404 | * been invalidated since the last time they've been set? |
1405 | * since the last time they've | ||
1406 | * been set? | ||
1407 | */ | 1405 | */ |
1408 | bool amdgpu_ttm_tt_userptr_needs_pages(struct ttm_tt *ttm) | 1406 | bool amdgpu_ttm_tt_userptr_needs_pages(struct ttm_tt *ttm) |
1409 | { | 1407 | { |
@@ -1459,13 +1457,12 @@ uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, | |||
1459 | } | 1457 | } |
1460 | 1458 | ||
1461 | /** | 1459 | /** |
1462 | * amdgpu_ttm_bo_eviction_valuable - Check to see if we can evict | 1460 | * amdgpu_ttm_bo_eviction_valuable - Check to see if we can evict a buffer |
1463 | * a buffer object. | 1461 | * object. |
1464 | * | 1462 | * |
1465 | * Return true if eviction is sensible. Called by | 1463 | * Return true if eviction is sensible. Called by ttm_mem_evict_first() on |
1466 | * ttm_mem_evict_first() on behalf of ttm_bo_mem_force_space() | 1464 | * behalf of ttm_bo_mem_force_space() which tries to evict buffer objects until |
1467 | * which tries to evict buffer objects until it can find space | 1465 | * it can find space for a new object and by ttm_bo_force_list_clean() which is |
1468 | * for a new object and by ttm_bo_force_list_clean() which is | ||
1469 | * used to clean out a memory space. | 1466 | * used to clean out a memory space. |
1470 | */ | 1467 | */ |
1471 | static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, | 1468 | static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, |
@@ -1515,8 +1512,7 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, | |||
1515 | } | 1512 | } |
1516 | 1513 | ||
1517 | /** | 1514 | /** |
1518 | * amdgpu_ttm_access_memory - Read or Write memory that backs a | 1515 | * amdgpu_ttm_access_memory - Read or Write memory that backs a buffer object. |
1519 | * buffer object. | ||
1520 | * | 1516 | * |
1521 | * @bo: The buffer object to read/write | 1517 | * @bo: The buffer object to read/write |
1522 | * @offset: Offset into buffer object | 1518 | * @offset: Offset into buffer object |
@@ -1704,8 +1700,8 @@ error_create: | |||
1704 | return r; | 1700 | return r; |
1705 | } | 1701 | } |
1706 | /** | 1702 | /** |
1707 | * amdgpu_ttm_init - Init the memory management (ttm) as well as | 1703 | * amdgpu_ttm_init - Init the memory management (ttm) as well as various |
1708 | * various gtt/vram related fields. | 1704 | * gtt/vram related fields. |
1709 | * | 1705 | * |
1710 | * This initializes all of the memory space pools that the TTM layer | 1706 | * This initializes all of the memory space pools that the TTM layer |
1711 | * will need such as the GTT space (system memory mapped to the device), | 1707 | * will need such as the GTT space (system memory mapped to the device), |
@@ -1856,8 +1852,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) | |||
1856 | } | 1852 | } |
1857 | 1853 | ||
1858 | /** | 1854 | /** |
1859 | * amdgpu_ttm_late_init - Handle any late initialization for | 1855 | * amdgpu_ttm_late_init - Handle any late initialization for amdgpu_ttm |
1860 | * amdgpu_ttm | ||
1861 | */ | 1856 | */ |
1862 | void amdgpu_ttm_late_init(struct amdgpu_device *adev) | 1857 | void amdgpu_ttm_late_init(struct amdgpu_device *adev) |
1863 | { | 1858 | { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index fca86d71fafc..632fa5980ff4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | |||
@@ -255,7 +255,8 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) | |||
255 | bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); | 255 | bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); |
256 | 256 | ||
257 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { | 257 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { |
258 | 258 | if (adev->uvd.harvest_config & (1 << j)) | |
259 | continue; | ||
259 | r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE, | 260 | r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE, |
260 | AMDGPU_GEM_DOMAIN_VRAM, &adev->uvd.inst[j].vcpu_bo, | 261 | AMDGPU_GEM_DOMAIN_VRAM, &adev->uvd.inst[j].vcpu_bo, |
261 | &adev->uvd.inst[j].gpu_addr, &adev->uvd.inst[j].cpu_addr); | 262 | &adev->uvd.inst[j].gpu_addr, &adev->uvd.inst[j].cpu_addr); |
@@ -308,6 +309,8 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) | |||
308 | drm_sched_entity_destroy(&adev->uvd.entity); | 309 | drm_sched_entity_destroy(&adev->uvd.entity); |
309 | 310 | ||
310 | for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { | 311 | for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { |
312 | if (adev->uvd.harvest_config & (1 << j)) | ||
313 | continue; | ||
311 | kfree(adev->uvd.inst[j].saved_bo); | 314 | kfree(adev->uvd.inst[j].saved_bo); |
312 | 315 | ||
313 | amdgpu_bo_free_kernel(&adev->uvd.inst[j].vcpu_bo, | 316 | amdgpu_bo_free_kernel(&adev->uvd.inst[j].vcpu_bo, |
@@ -343,6 +346,8 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev) | |||
343 | } | 346 | } |
344 | 347 | ||
345 | for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { | 348 | for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { |
349 | if (adev->uvd.harvest_config & (1 << j)) | ||
350 | continue; | ||
346 | if (adev->uvd.inst[j].vcpu_bo == NULL) | 351 | if (adev->uvd.inst[j].vcpu_bo == NULL) |
347 | continue; | 352 | continue; |
348 | 353 | ||
@@ -365,6 +370,8 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) | |||
365 | int i; | 370 | int i; |
366 | 371 | ||
367 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { | 372 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { |
373 | if (adev->uvd.harvest_config & (1 << i)) | ||
374 | continue; | ||
368 | if (adev->uvd.inst[i].vcpu_bo == NULL) | 375 | if (adev->uvd.inst[i].vcpu_bo == NULL) |
369 | return -EINVAL; | 376 | return -EINVAL; |
370 | 377 | ||
@@ -1159,6 +1166,8 @@ static void amdgpu_uvd_idle_work_handler(struct work_struct *work) | |||
1159 | unsigned fences = 0, i, j; | 1166 | unsigned fences = 0, i, j; |
1160 | 1167 | ||
1161 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { | 1168 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { |
1169 | if (adev->uvd.harvest_config & (1 << i)) | ||
1170 | continue; | ||
1162 | fences += amdgpu_fence_count_emitted(&adev->uvd.inst[i].ring); | 1171 | fences += amdgpu_fence_count_emitted(&adev->uvd.inst[i].ring); |
1163 | for (j = 0; j < adev->uvd.num_enc_rings; ++j) { | 1172 | for (j = 0; j < adev->uvd.num_enc_rings; ++j) { |
1164 | fences += amdgpu_fence_count_emitted(&adev->uvd.inst[i].ring_enc[j]); | 1173 | fences += amdgpu_fence_count_emitted(&adev->uvd.inst[i].ring_enc[j]); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h index 66872286ab12..33c5f806f925 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h | |||
@@ -48,6 +48,9 @@ struct amdgpu_uvd_inst { | |||
48 | uint32_t srbm_soft_reset; | 48 | uint32_t srbm_soft_reset; |
49 | }; | 49 | }; |
50 | 50 | ||
51 | #define AMDGPU_UVD_HARVEST_UVD0 (1 << 0) | ||
52 | #define AMDGPU_UVD_HARVEST_UVD1 (1 << 1) | ||
53 | |||
51 | struct amdgpu_uvd { | 54 | struct amdgpu_uvd { |
52 | const struct firmware *fw; /* UVD firmware */ | 55 | const struct firmware *fw; /* UVD firmware */ |
53 | unsigned fw_version; | 56 | unsigned fw_version; |
@@ -61,6 +64,7 @@ struct amdgpu_uvd { | |||
61 | atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; | 64 | atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; |
62 | struct drm_sched_entity entity; | 65 | struct drm_sched_entity entity; |
63 | struct delayed_work idle_work; | 66 | struct delayed_work idle_work; |
67 | unsigned harvest_config; | ||
64 | }; | 68 | }; |
65 | 69 | ||
66 | int amdgpu_uvd_sw_init(struct amdgpu_device *adev); | 70 | int amdgpu_uvd_sw_init(struct amdgpu_device *adev); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 9eedc9810004..ece0ac703e27 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -2345,6 +2345,35 @@ struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm, | |||
2345 | } | 2345 | } |
2346 | 2346 | ||
2347 | /** | 2347 | /** |
2348 | * amdgpu_vm_bo_trace_cs - trace all reserved mappings | ||
2349 | * | ||
2350 | * @vm: the requested vm | ||
2351 | * @ticket: CS ticket | ||
2352 | * | ||
2353 | * Trace all mappings of BOs reserved during a command submission. | ||
2354 | */ | ||
2355 | void amdgpu_vm_bo_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket) | ||
2356 | { | ||
2357 | struct amdgpu_bo_va_mapping *mapping; | ||
2358 | |||
2359 | if (!trace_amdgpu_vm_bo_cs_enabled()) | ||
2360 | return; | ||
2361 | |||
2362 | for (mapping = amdgpu_vm_it_iter_first(&vm->va, 0, U64_MAX); mapping; | ||
2363 | mapping = amdgpu_vm_it_iter_next(mapping, 0, U64_MAX)) { | ||
2364 | if (mapping->bo_va && mapping->bo_va->base.bo) { | ||
2365 | struct amdgpu_bo *bo; | ||
2366 | |||
2367 | bo = mapping->bo_va->base.bo; | ||
2368 | if (READ_ONCE(bo->tbo.resv->lock.ctx) != ticket) | ||
2369 | continue; | ||
2370 | } | ||
2371 | |||
2372 | trace_amdgpu_vm_bo_cs(mapping); | ||
2373 | } | ||
2374 | } | ||
2375 | |||
2376 | /** | ||
2348 | * amdgpu_vm_bo_rmv - remove a bo to a specific vm | 2377 | * amdgpu_vm_bo_rmv - remove a bo to a specific vm |
2349 | * | 2378 | * |
2350 | * @adev: amdgpu_device pointer | 2379 | * @adev: amdgpu_device pointer |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index d416f895233d..67a15d439ac0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | |||
@@ -318,6 +318,7 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev, | |||
318 | uint64_t saddr, uint64_t size); | 318 | uint64_t saddr, uint64_t size); |
319 | struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm, | 319 | struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm, |
320 | uint64_t addr); | 320 | uint64_t addr); |
321 | void amdgpu_vm_bo_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket); | ||
321 | void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, | 322 | void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, |
322 | struct amdgpu_bo_va *bo_va); | 323 | struct amdgpu_bo_va *bo_va); |
323 | void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size, | 324 | void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size, |
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index db5f3d78ab12..5fab3560a71d 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | |||
@@ -41,6 +41,12 @@ | |||
41 | #include "mmhub/mmhub_1_0_sh_mask.h" | 41 | #include "mmhub/mmhub_1_0_sh_mask.h" |
42 | #include "ivsrcid/uvd/irqsrcs_uvd_7_0.h" | 42 | #include "ivsrcid/uvd/irqsrcs_uvd_7_0.h" |
43 | 43 | ||
44 | #define mmUVD_PG0_CC_UVD_HARVESTING 0x00c7 | ||
45 | #define mmUVD_PG0_CC_UVD_HARVESTING_BASE_IDX 1 | ||
46 | //UVD_PG0_CC_UVD_HARVESTING | ||
47 | #define UVD_PG0_CC_UVD_HARVESTING__UVD_DISABLE__SHIFT 0x1 | ||
48 | #define UVD_PG0_CC_UVD_HARVESTING__UVD_DISABLE_MASK 0x00000002L | ||
49 | |||
44 | #define UVD7_MAX_HW_INSTANCES_VEGA20 2 | 50 | #define UVD7_MAX_HW_INSTANCES_VEGA20 2 |
45 | 51 | ||
46 | static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev); | 52 | static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev); |
@@ -370,10 +376,25 @@ error: | |||
370 | static int uvd_v7_0_early_init(void *handle) | 376 | static int uvd_v7_0_early_init(void *handle) |
371 | { | 377 | { |
372 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 378 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
373 | if (adev->asic_type == CHIP_VEGA20) | 379 | |
380 | if (adev->asic_type == CHIP_VEGA20) { | ||
381 | u32 harvest; | ||
382 | int i; | ||
383 | |||
374 | adev->uvd.num_uvd_inst = UVD7_MAX_HW_INSTANCES_VEGA20; | 384 | adev->uvd.num_uvd_inst = UVD7_MAX_HW_INSTANCES_VEGA20; |
375 | else | 385 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { |
386 | harvest = RREG32_SOC15(UVD, i, mmUVD_PG0_CC_UVD_HARVESTING); | ||
387 | if (harvest & UVD_PG0_CC_UVD_HARVESTING__UVD_DISABLE_MASK) { | ||
388 | adev->uvd.harvest_config |= 1 << i; | ||
389 | } | ||
390 | } | ||
391 | if (adev->uvd.harvest_config == (AMDGPU_UVD_HARVEST_UVD0 | | ||
392 | AMDGPU_UVD_HARVEST_UVD1)) | ||
393 | /* both instances are harvested, disable the block */ | ||
394 | return -ENOENT; | ||
395 | } else { | ||
376 | adev->uvd.num_uvd_inst = 1; | 396 | adev->uvd.num_uvd_inst = 1; |
397 | } | ||
377 | 398 | ||
378 | if (amdgpu_sriov_vf(adev)) | 399 | if (amdgpu_sriov_vf(adev)) |
379 | adev->uvd.num_enc_rings = 1; | 400 | adev->uvd.num_enc_rings = 1; |
@@ -393,6 +414,8 @@ static int uvd_v7_0_sw_init(void *handle) | |||
393 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 414 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
394 | 415 | ||
395 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { | 416 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { |
417 | if (adev->uvd.harvest_config & (1 << j)) | ||
418 | continue; | ||
396 | /* UVD TRAP */ | 419 | /* UVD TRAP */ |
397 | r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_uvds[j], UVD_7_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->uvd.inst[j].irq); | 420 | r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_uvds[j], UVD_7_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->uvd.inst[j].irq); |
398 | if (r) | 421 | if (r) |
@@ -425,6 +448,8 @@ static int uvd_v7_0_sw_init(void *handle) | |||
425 | return r; | 448 | return r; |
426 | 449 | ||
427 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { | 450 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { |
451 | if (adev->uvd.harvest_config & (1 << j)) | ||
452 | continue; | ||
428 | if (!amdgpu_sriov_vf(adev)) { | 453 | if (!amdgpu_sriov_vf(adev)) { |
429 | ring = &adev->uvd.inst[j].ring; | 454 | ring = &adev->uvd.inst[j].ring; |
430 | sprintf(ring->name, "uvd<%d>", j); | 455 | sprintf(ring->name, "uvd<%d>", j); |
@@ -472,6 +497,8 @@ static int uvd_v7_0_sw_fini(void *handle) | |||
472 | return r; | 497 | return r; |
473 | 498 | ||
474 | for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { | 499 | for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { |
500 | if (adev->uvd.harvest_config & (1 << j)) | ||
501 | continue; | ||
475 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) | 502 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) |
476 | amdgpu_ring_fini(&adev->uvd.inst[j].ring_enc[i]); | 503 | amdgpu_ring_fini(&adev->uvd.inst[j].ring_enc[i]); |
477 | } | 504 | } |
@@ -500,6 +527,8 @@ static int uvd_v7_0_hw_init(void *handle) | |||
500 | goto done; | 527 | goto done; |
501 | 528 | ||
502 | for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { | 529 | for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { |
530 | if (adev->uvd.harvest_config & (1 << j)) | ||
531 | continue; | ||
503 | ring = &adev->uvd.inst[j].ring; | 532 | ring = &adev->uvd.inst[j].ring; |
504 | 533 | ||
505 | if (!amdgpu_sriov_vf(adev)) { | 534 | if (!amdgpu_sriov_vf(adev)) { |
@@ -579,8 +608,11 @@ static int uvd_v7_0_hw_fini(void *handle) | |||
579 | DRM_DEBUG("For SRIOV client, shouldn't do anything.\n"); | 608 | DRM_DEBUG("For SRIOV client, shouldn't do anything.\n"); |
580 | } | 609 | } |
581 | 610 | ||
582 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) | 611 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { |
612 | if (adev->uvd.harvest_config & (1 << i)) | ||
613 | continue; | ||
583 | adev->uvd.inst[i].ring.ready = false; | 614 | adev->uvd.inst[i].ring.ready = false; |
615 | } | ||
584 | 616 | ||
585 | return 0; | 617 | return 0; |
586 | } | 618 | } |
@@ -623,6 +655,8 @@ static void uvd_v7_0_mc_resume(struct amdgpu_device *adev) | |||
623 | int i; | 655 | int i; |
624 | 656 | ||
625 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { | 657 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { |
658 | if (adev->uvd.harvest_config & (1 << i)) | ||
659 | continue; | ||
626 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { | 660 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { |
627 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, | 661 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, |
628 | lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); | 662 | lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); |
@@ -695,6 +729,8 @@ static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev, | |||
695 | WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP, 0); | 729 | WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP, 0); |
696 | 730 | ||
697 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { | 731 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { |
732 | if (adev->uvd.harvest_config & (1 << i)) | ||
733 | continue; | ||
698 | WDOORBELL32(adev->uvd.inst[i].ring_enc[0].doorbell_index, 0); | 734 | WDOORBELL32(adev->uvd.inst[i].ring_enc[0].doorbell_index, 0); |
699 | adev->wb.wb[adev->uvd.inst[i].ring_enc[0].wptr_offs] = 0; | 735 | adev->wb.wb[adev->uvd.inst[i].ring_enc[0].wptr_offs] = 0; |
700 | adev->uvd.inst[i].ring_enc[0].wptr = 0; | 736 | adev->uvd.inst[i].ring_enc[0].wptr = 0; |
@@ -751,6 +787,8 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev) | |||
751 | init_table += header->uvd_table_offset; | 787 | init_table += header->uvd_table_offset; |
752 | 788 | ||
753 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { | 789 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { |
790 | if (adev->uvd.harvest_config & (1 << i)) | ||
791 | continue; | ||
754 | ring = &adev->uvd.inst[i].ring; | 792 | ring = &adev->uvd.inst[i].ring; |
755 | ring->wptr = 0; | 793 | ring->wptr = 0; |
756 | size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4); | 794 | size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4); |
@@ -890,6 +928,8 @@ static int uvd_v7_0_start(struct amdgpu_device *adev) | |||
890 | int i, j, k, r; | 928 | int i, j, k, r; |
891 | 929 | ||
892 | for (k = 0; k < adev->uvd.num_uvd_inst; ++k) { | 930 | for (k = 0; k < adev->uvd.num_uvd_inst; ++k) { |
931 | if (adev->uvd.harvest_config & (1 << k)) | ||
932 | continue; | ||
893 | /* disable DPG */ | 933 | /* disable DPG */ |
894 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_POWER_STATUS), 0, | 934 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_POWER_STATUS), 0, |
895 | ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); | 935 | ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); |
@@ -902,6 +942,8 @@ static int uvd_v7_0_start(struct amdgpu_device *adev) | |||
902 | uvd_v7_0_mc_resume(adev); | 942 | uvd_v7_0_mc_resume(adev); |
903 | 943 | ||
904 | for (k = 0; k < adev->uvd.num_uvd_inst; ++k) { | 944 | for (k = 0; k < adev->uvd.num_uvd_inst; ++k) { |
945 | if (adev->uvd.harvest_config & (1 << k)) | ||
946 | continue; | ||
905 | ring = &adev->uvd.inst[k].ring; | 947 | ring = &adev->uvd.inst[k].ring; |
906 | /* disable clock gating */ | 948 | /* disable clock gating */ |
907 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_CGC_CTRL), 0, | 949 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_CGC_CTRL), 0, |
@@ -1069,6 +1111,8 @@ static void uvd_v7_0_stop(struct amdgpu_device *adev) | |||
1069 | uint8_t i = 0; | 1111 | uint8_t i = 0; |
1070 | 1112 | ||
1071 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { | 1113 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { |
1114 | if (adev->uvd.harvest_config & (1 << i)) | ||
1115 | continue; | ||
1072 | /* force RBC into idle state */ | 1116 | /* force RBC into idle state */ |
1073 | WREG32_SOC15(UVD, i, mmUVD_RBC_RB_CNTL, 0x11010101); | 1117 | WREG32_SOC15(UVD, i, mmUVD_RBC_RB_CNTL, 0x11010101); |
1074 | 1118 | ||
@@ -1206,6 +1250,34 @@ static int uvd_v7_0_ring_test_ring(struct amdgpu_ring *ring) | |||
1206 | } | 1250 | } |
1207 | 1251 | ||
1208 | /** | 1252 | /** |
1253 | * uvd_v7_0_ring_patch_cs_in_place - Patch the IB for command submission. | ||
1254 | * | ||
1255 | * @p: the CS parser with the IBs | ||
1256 | * @ib_idx: which IB to patch | ||
1257 | * | ||
1258 | */ | ||
1259 | static int uvd_v7_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p, | ||
1260 | uint32_t ib_idx) | ||
1261 | { | ||
1262 | struct amdgpu_ib *ib = &p->job->ibs[ib_idx]; | ||
1263 | unsigned i; | ||
1264 | |||
1265 | /* No patching necessary for the first instance */ | ||
1266 | if (!p->ring->me) | ||
1267 | return 0; | ||
1268 | |||
1269 | for (i = 0; i < ib->length_dw; i += 2) { | ||
1270 | uint32_t reg = amdgpu_get_ib_value(p, ib_idx, i); | ||
1271 | |||
1272 | reg -= p->adev->reg_offset[UVD_HWIP][0][1]; | ||
1273 | reg += p->adev->reg_offset[UVD_HWIP][1][1]; | ||
1274 | |||
1275 | amdgpu_set_ib_value(p, ib_idx, i, reg); | ||
1276 | } | ||
1277 | return 0; | ||
1278 | } | ||
1279 | |||
1280 | /** | ||
1209 | * uvd_v7_0_ring_emit_ib - execute indirect buffer | 1281 | * uvd_v7_0_ring_emit_ib - execute indirect buffer |
1210 | * | 1282 | * |
1211 | * @ring: amdgpu_ring pointer | 1283 | * @ring: amdgpu_ring pointer |
@@ -1697,6 +1769,7 @@ static const struct amdgpu_ring_funcs uvd_v7_0_ring_vm_funcs = { | |||
1697 | .get_rptr = uvd_v7_0_ring_get_rptr, | 1769 | .get_rptr = uvd_v7_0_ring_get_rptr, |
1698 | .get_wptr = uvd_v7_0_ring_get_wptr, | 1770 | .get_wptr = uvd_v7_0_ring_get_wptr, |
1699 | .set_wptr = uvd_v7_0_ring_set_wptr, | 1771 | .set_wptr = uvd_v7_0_ring_set_wptr, |
1772 | .patch_cs_in_place = uvd_v7_0_ring_patch_cs_in_place, | ||
1700 | .emit_frame_size = | 1773 | .emit_frame_size = |
1701 | 6 + /* hdp invalidate */ | 1774 | 6 + /* hdp invalidate */ |
1702 | SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + | 1775 | SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + |
@@ -1756,6 +1829,8 @@ static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev) | |||
1756 | int i; | 1829 | int i; |
1757 | 1830 | ||
1758 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { | 1831 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { |
1832 | if (adev->uvd.harvest_config & (1 << i)) | ||
1833 | continue; | ||
1759 | adev->uvd.inst[i].ring.funcs = &uvd_v7_0_ring_vm_funcs; | 1834 | adev->uvd.inst[i].ring.funcs = &uvd_v7_0_ring_vm_funcs; |
1760 | adev->uvd.inst[i].ring.me = i; | 1835 | adev->uvd.inst[i].ring.me = i; |
1761 | DRM_INFO("UVD(%d) is enabled in VM mode\n", i); | 1836 | DRM_INFO("UVD(%d) is enabled in VM mode\n", i); |
@@ -1767,6 +1842,8 @@ static void uvd_v7_0_set_enc_ring_funcs(struct amdgpu_device *adev) | |||
1767 | int i, j; | 1842 | int i, j; |
1768 | 1843 | ||
1769 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { | 1844 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { |
1845 | if (adev->uvd.harvest_config & (1 << j)) | ||
1846 | continue; | ||
1770 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | 1847 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { |
1771 | adev->uvd.inst[j].ring_enc[i].funcs = &uvd_v7_0_enc_ring_vm_funcs; | 1848 | adev->uvd.inst[j].ring_enc[i].funcs = &uvd_v7_0_enc_ring_vm_funcs; |
1772 | adev->uvd.inst[j].ring_enc[i].me = j; | 1849 | adev->uvd.inst[j].ring_enc[i].me = j; |
@@ -1786,6 +1863,8 @@ static void uvd_v7_0_set_irq_funcs(struct amdgpu_device *adev) | |||
1786 | int i; | 1863 | int i; |
1787 | 1864 | ||
1788 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { | 1865 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { |
1866 | if (adev->uvd.harvest_config & (1 << i)) | ||
1867 | continue; | ||
1789 | adev->uvd.inst[i].irq.num_types = adev->uvd.num_enc_rings + 1; | 1868 | adev->uvd.inst[i].irq.num_types = adev->uvd.num_enc_rings + 1; |
1790 | adev->uvd.inst[i].irq.funcs = &uvd_v7_0_irq_funcs; | 1869 | adev->uvd.inst[i].irq.funcs = &uvd_v7_0_irq_funcs; |
1791 | } | 1870 | } |