diff options
author | Dave Airlie <airlied@redhat.com> | 2019-02-22 00:56:35 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2019-02-22 00:56:42 -0500 |
commit | fbac3c48fa6b4cfa43eaae39d5a53269bff7ec5f (patch) | |
tree | dddd2843ec69dceda451de060d68ac21629d10ab | |
parent | a5f2fafece141ef3509e686cea576366d55cabb6 (diff) | |
parent | 767e06a9924162ce8ca5890533932174b04471f3 (diff) |
Merge branch 'drm-next-5.1' of git://people.freedesktop.org/~agd5f/linux into drm-next
Fixes for 5.1:
amdgpu:
- Fix missing fw declaration after dropping old CI DPM code
- Fix debugfs access to registers beyond the MMIO bar size
- Fix context priority handling
- Add missing license on some new files
- Various cleanups and bug fixes
radeon:
- Fix missing break in CS parser for evergreen
- Various cleanups and bug fixes
sched:
- Fix entities with 0 run queues
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexdeucher@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190221214134.3308-1-alexander.deucher@amd.com
60 files changed, 701 insertions, 612 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 9efa681d0878..8d0d7f3dd5fb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -411,6 +411,8 @@ struct amdgpu_fpriv { | |||
411 | struct amdgpu_ctx_mgr ctx_mgr; | 411 | struct amdgpu_ctx_mgr ctx_mgr; |
412 | }; | 412 | }; |
413 | 413 | ||
414 | int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv); | ||
415 | |||
414 | int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, | 416 | int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, |
415 | unsigned size, struct amdgpu_ib *ib); | 417 | unsigned size, struct amdgpu_ib *ib); |
416 | void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib, | 418 | void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index e957e42c539a..fe1d7368c1e6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | |||
@@ -131,7 +131,7 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev, | |||
131 | 131 | ||
132 | void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) | 132 | void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) |
133 | { | 133 | { |
134 | int i, n; | 134 | int i; |
135 | int last_valid_bit; | 135 | int last_valid_bit; |
136 | 136 | ||
137 | if (adev->kfd.dev) { | 137 | if (adev->kfd.dev) { |
@@ -142,7 +142,9 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) | |||
142 | .gpuvm_size = min(adev->vm_manager.max_pfn | 142 | .gpuvm_size = min(adev->vm_manager.max_pfn |
143 | << AMDGPU_GPU_PAGE_SHIFT, | 143 | << AMDGPU_GPU_PAGE_SHIFT, |
144 | AMDGPU_GMC_HOLE_START), | 144 | AMDGPU_GMC_HOLE_START), |
145 | .drm_render_minor = adev->ddev->render->index | 145 | .drm_render_minor = adev->ddev->render->index, |
146 | .sdma_doorbell_idx = adev->doorbell_index.sdma_engine, | ||
147 | |||
146 | }; | 148 | }; |
147 | 149 | ||
148 | /* this is going to have a few of the MSBs set that we need to | 150 | /* this is going to have a few of the MSBs set that we need to |
@@ -172,35 +174,20 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) | |||
172 | &gpu_resources.doorbell_aperture_size, | 174 | &gpu_resources.doorbell_aperture_size, |
173 | &gpu_resources.doorbell_start_offset); | 175 | &gpu_resources.doorbell_start_offset); |
174 | 176 | ||
175 | if (adev->asic_type < CHIP_VEGA10) { | 177 | /* Since SOC15, BIF starts to statically use the |
176 | kgd2kfd_device_init(adev->kfd.dev, &gpu_resources); | 178 | * lower 12 bits of doorbell addresses for routing |
177 | return; | 179 | * based on settings in registers like |
178 | } | 180 | * SDMA0_DOORBELL_RANGE etc.. |
179 | 181 | * In order to route a doorbell to CP engine, the lower | |
180 | n = (adev->asic_type < CHIP_VEGA20) ? 2 : 8; | 182 | * 12 bits of its address has to be outside the range |
181 | 183 | * set for SDMA, VCN, and IH blocks. | |
182 | for (i = 0; i < n; i += 2) { | ||
183 | /* On SOC15 the BIF is involved in routing | ||
184 | * doorbells using the low 12 bits of the | ||
185 | * address. Communicate the assignments to | ||
186 | * KFD. KFD uses two doorbell pages per | ||
187 | * process in case of 64-bit doorbells so we | ||
188 | * can use each doorbell assignment twice. | ||
189 | */ | ||
190 | gpu_resources.sdma_doorbell[0][i] = | ||
191 | adev->doorbell_index.sdma_engine[0] + (i >> 1); | ||
192 | gpu_resources.sdma_doorbell[0][i+1] = | ||
193 | adev->doorbell_index.sdma_engine[0] + 0x200 + (i >> 1); | ||
194 | gpu_resources.sdma_doorbell[1][i] = | ||
195 | adev->doorbell_index.sdma_engine[1] + (i >> 1); | ||
196 | gpu_resources.sdma_doorbell[1][i+1] = | ||
197 | adev->doorbell_index.sdma_engine[1] + 0x200 + (i >> 1); | ||
198 | } | ||
199 | /* Doorbells 0x0e0-0ff and 0x2e0-2ff are reserved for | ||
200 | * SDMA, IH and VCN. So don't use them for the CP. | ||
201 | */ | 184 | */ |
202 | gpu_resources.reserved_doorbell_mask = 0x1e0; | 185 | if (adev->asic_type >= CHIP_VEGA10) { |
203 | gpu_resources.reserved_doorbell_val = 0x0e0; | 186 | gpu_resources.non_cp_doorbells_start = |
187 | adev->doorbell_index.first_non_cp; | ||
188 | gpu_resources.non_cp_doorbells_end = | ||
189 | adev->doorbell_index.last_non_cp; | ||
190 | } | ||
204 | 191 | ||
205 | kgd2kfd_device_init(adev->kfd.dev, &gpu_resources); | 192 | kgd2kfd_device_init(adev->kfd.dev, &gpu_resources); |
206 | } | 193 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index d7b10d79f1de..1921dec3df7a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | |||
@@ -204,38 +204,25 @@ void amdgpu_amdkfd_unreserve_memory_limit(struct amdgpu_bo *bo) | |||
204 | } | 204 | } |
205 | 205 | ||
206 | 206 | ||
207 | /* amdgpu_amdkfd_remove_eviction_fence - Removes eviction fence(s) from BO's | 207 | /* amdgpu_amdkfd_remove_eviction_fence - Removes eviction fence from BO's |
208 | * reservation object. | 208 | * reservation object. |
209 | * | 209 | * |
210 | * @bo: [IN] Remove eviction fence(s) from this BO | 210 | * @bo: [IN] Remove eviction fence(s) from this BO |
211 | * @ef: [IN] If ef is specified, then this eviction fence is removed if it | 211 | * @ef: [IN] This eviction fence is removed if it |
212 | * is present in the shared list. | 212 | * is present in the shared list. |
213 | * @ef_list: [OUT] Returns list of eviction fences. These fences are removed | ||
214 | * from BO's reservation object shared list. | ||
215 | * @ef_count: [OUT] Number of fences in ef_list. | ||
216 | * | 213 | * |
217 | * NOTE: If called with ef_list, then amdgpu_amdkfd_add_eviction_fence must be | ||
218 | * called to restore the eviction fences and to avoid memory leak. This is | ||
219 | * useful for shared BOs. | ||
220 | * NOTE: Must be called with BO reserved i.e. bo->tbo.resv->lock held. | 214 | * NOTE: Must be called with BO reserved i.e. bo->tbo.resv->lock held. |
221 | */ | 215 | */ |
222 | static int amdgpu_amdkfd_remove_eviction_fence(struct amdgpu_bo *bo, | 216 | static int amdgpu_amdkfd_remove_eviction_fence(struct amdgpu_bo *bo, |
223 | struct amdgpu_amdkfd_fence *ef, | 217 | struct amdgpu_amdkfd_fence *ef) |
224 | struct amdgpu_amdkfd_fence ***ef_list, | ||
225 | unsigned int *ef_count) | ||
226 | { | 218 | { |
227 | struct reservation_object *resv = bo->tbo.resv; | 219 | struct reservation_object *resv = bo->tbo.resv; |
228 | struct reservation_object_list *old, *new; | 220 | struct reservation_object_list *old, *new; |
229 | unsigned int i, j, k; | 221 | unsigned int i, j, k; |
230 | 222 | ||
231 | if (!ef && !ef_list) | 223 | if (!ef) |
232 | return -EINVAL; | 224 | return -EINVAL; |
233 | 225 | ||
234 | if (ef_list) { | ||
235 | *ef_list = NULL; | ||
236 | *ef_count = 0; | ||
237 | } | ||
238 | |||
239 | old = reservation_object_get_list(resv); | 226 | old = reservation_object_get_list(resv); |
240 | if (!old) | 227 | if (!old) |
241 | return 0; | 228 | return 0; |
@@ -254,8 +241,7 @@ static int amdgpu_amdkfd_remove_eviction_fence(struct amdgpu_bo *bo, | |||
254 | f = rcu_dereference_protected(old->shared[i], | 241 | f = rcu_dereference_protected(old->shared[i], |
255 | reservation_object_held(resv)); | 242 | reservation_object_held(resv)); |
256 | 243 | ||
257 | if ((ef && f->context == ef->base.context) || | 244 | if (f->context == ef->base.context) |
258 | (!ef && to_amdgpu_amdkfd_fence(f))) | ||
259 | RCU_INIT_POINTER(new->shared[--j], f); | 245 | RCU_INIT_POINTER(new->shared[--j], f); |
260 | else | 246 | else |
261 | RCU_INIT_POINTER(new->shared[k++], f); | 247 | RCU_INIT_POINTER(new->shared[k++], f); |
@@ -263,21 +249,6 @@ static int amdgpu_amdkfd_remove_eviction_fence(struct amdgpu_bo *bo, | |||
263 | new->shared_max = old->shared_max; | 249 | new->shared_max = old->shared_max; |
264 | new->shared_count = k; | 250 | new->shared_count = k; |
265 | 251 | ||
266 | if (!ef) { | ||
267 | unsigned int count = old->shared_count - j; | ||
268 | |||
269 | /* Alloc memory for count number of eviction fence pointers. | ||
270 | * Fill the ef_list array and ef_count | ||
271 | */ | ||
272 | *ef_list = kcalloc(count, sizeof(**ef_list), GFP_KERNEL); | ||
273 | *ef_count = count; | ||
274 | |||
275 | if (!*ef_list) { | ||
276 | kfree(new); | ||
277 | return -ENOMEM; | ||
278 | } | ||
279 | } | ||
280 | |||
281 | /* Install the new fence list, seqcount provides the barriers */ | 252 | /* Install the new fence list, seqcount provides the barriers */ |
282 | preempt_disable(); | 253 | preempt_disable(); |
283 | write_seqcount_begin(&resv->seq); | 254 | write_seqcount_begin(&resv->seq); |
@@ -291,46 +262,13 @@ static int amdgpu_amdkfd_remove_eviction_fence(struct amdgpu_bo *bo, | |||
291 | 262 | ||
292 | f = rcu_dereference_protected(new->shared[i], | 263 | f = rcu_dereference_protected(new->shared[i], |
293 | reservation_object_held(resv)); | 264 | reservation_object_held(resv)); |
294 | if (!ef) | 265 | dma_fence_put(f); |
295 | (*ef_list)[k++] = to_amdgpu_amdkfd_fence(f); | ||
296 | else | ||
297 | dma_fence_put(f); | ||
298 | } | 266 | } |
299 | kfree_rcu(old, rcu); | 267 | kfree_rcu(old, rcu); |
300 | 268 | ||
301 | return 0; | 269 | return 0; |
302 | } | 270 | } |
303 | 271 | ||
304 | /* amdgpu_amdkfd_add_eviction_fence - Adds eviction fence(s) back into BO's | ||
305 | * reservation object. | ||
306 | * | ||
307 | * @bo: [IN] Add eviction fences to this BO | ||
308 | * @ef_list: [IN] List of eviction fences to be added | ||
309 | * @ef_count: [IN] Number of fences in ef_list. | ||
310 | * | ||
311 | * NOTE: Must call amdgpu_amdkfd_remove_eviction_fence before calling this | ||
312 | * function. | ||
313 | */ | ||
314 | static void amdgpu_amdkfd_add_eviction_fence(struct amdgpu_bo *bo, | ||
315 | struct amdgpu_amdkfd_fence **ef_list, | ||
316 | unsigned int ef_count) | ||
317 | { | ||
318 | int i; | ||
319 | |||
320 | if (!ef_list || !ef_count) | ||
321 | return; | ||
322 | |||
323 | for (i = 0; i < ef_count; i++) { | ||
324 | amdgpu_bo_fence(bo, &ef_list[i]->base, true); | ||
325 | /* Re-adding the fence takes an additional reference. Drop that | ||
326 | * reference. | ||
327 | */ | ||
328 | dma_fence_put(&ef_list[i]->base); | ||
329 | } | ||
330 | |||
331 | kfree(ef_list); | ||
332 | } | ||
333 | |||
334 | static int amdgpu_amdkfd_bo_validate(struct amdgpu_bo *bo, uint32_t domain, | 272 | static int amdgpu_amdkfd_bo_validate(struct amdgpu_bo *bo, uint32_t domain, |
335 | bool wait) | 273 | bool wait) |
336 | { | 274 | { |
@@ -346,18 +284,8 @@ static int amdgpu_amdkfd_bo_validate(struct amdgpu_bo *bo, uint32_t domain, | |||
346 | ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); | 284 | ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); |
347 | if (ret) | 285 | if (ret) |
348 | goto validate_fail; | 286 | goto validate_fail; |
349 | if (wait) { | 287 | if (wait) |
350 | struct amdgpu_amdkfd_fence **ef_list; | 288 | amdgpu_bo_sync_wait(bo, AMDGPU_FENCE_OWNER_KFD, false); |
351 | unsigned int ef_count; | ||
352 | |||
353 | ret = amdgpu_amdkfd_remove_eviction_fence(bo, NULL, &ef_list, | ||
354 | &ef_count); | ||
355 | if (ret) | ||
356 | goto validate_fail; | ||
357 | |||
358 | ttm_bo_wait(&bo->tbo, false, false); | ||
359 | amdgpu_amdkfd_add_eviction_fence(bo, ef_list, ef_count); | ||
360 | } | ||
361 | 289 | ||
362 | validate_fail: | 290 | validate_fail: |
363 | return ret; | 291 | return ret; |
@@ -444,7 +372,6 @@ static int add_bo_to_vm(struct amdgpu_device *adev, struct kgd_mem *mem, | |||
444 | { | 372 | { |
445 | int ret; | 373 | int ret; |
446 | struct kfd_bo_va_list *bo_va_entry; | 374 | struct kfd_bo_va_list *bo_va_entry; |
447 | struct amdgpu_bo *pd = vm->root.base.bo; | ||
448 | struct amdgpu_bo *bo = mem->bo; | 375 | struct amdgpu_bo *bo = mem->bo; |
449 | uint64_t va = mem->va; | 376 | uint64_t va = mem->va; |
450 | struct list_head *list_bo_va = &mem->bo_va_list; | 377 | struct list_head *list_bo_va = &mem->bo_va_list; |
@@ -484,14 +411,8 @@ static int add_bo_to_vm(struct amdgpu_device *adev, struct kgd_mem *mem, | |||
484 | *p_bo_va_entry = bo_va_entry; | 411 | *p_bo_va_entry = bo_va_entry; |
485 | 412 | ||
486 | /* Allocate new page tables if needed and validate | 413 | /* Allocate new page tables if needed and validate |
487 | * them. Clearing of new page tables and validate need to wait | 414 | * them. |
488 | * on move fences. We don't want that to trigger the eviction | ||
489 | * fence, so remove it temporarily. | ||
490 | */ | 415 | */ |
491 | amdgpu_amdkfd_remove_eviction_fence(pd, | ||
492 | vm->process_info->eviction_fence, | ||
493 | NULL, NULL); | ||
494 | |||
495 | ret = amdgpu_vm_alloc_pts(adev, vm, va, amdgpu_bo_size(bo)); | 416 | ret = amdgpu_vm_alloc_pts(adev, vm, va, amdgpu_bo_size(bo)); |
496 | if (ret) { | 417 | if (ret) { |
497 | pr_err("Failed to allocate pts, err=%d\n", ret); | 418 | pr_err("Failed to allocate pts, err=%d\n", ret); |
@@ -504,13 +425,9 @@ static int add_bo_to_vm(struct amdgpu_device *adev, struct kgd_mem *mem, | |||
504 | goto err_alloc_pts; | 425 | goto err_alloc_pts; |
505 | } | 426 | } |
506 | 427 | ||
507 | /* Add the eviction fence back */ | ||
508 | amdgpu_bo_fence(pd, &vm->process_info->eviction_fence->base, true); | ||
509 | |||
510 | return 0; | 428 | return 0; |
511 | 429 | ||
512 | err_alloc_pts: | 430 | err_alloc_pts: |
513 | amdgpu_bo_fence(pd, &vm->process_info->eviction_fence->base, true); | ||
514 | amdgpu_vm_bo_rmv(adev, bo_va_entry->bo_va); | 431 | amdgpu_vm_bo_rmv(adev, bo_va_entry->bo_va); |
515 | list_del(&bo_va_entry->bo_list); | 432 | list_del(&bo_va_entry->bo_list); |
516 | err_vmadd: | 433 | err_vmadd: |
@@ -809,24 +726,11 @@ static int unmap_bo_from_gpuvm(struct amdgpu_device *adev, | |||
809 | { | 726 | { |
810 | struct amdgpu_bo_va *bo_va = entry->bo_va; | 727 | struct amdgpu_bo_va *bo_va = entry->bo_va; |
811 | struct amdgpu_vm *vm = bo_va->base.vm; | 728 | struct amdgpu_vm *vm = bo_va->base.vm; |
812 | struct amdgpu_bo *pd = vm->root.base.bo; | ||
813 | 729 | ||
814 | /* Remove eviction fence from PD (and thereby from PTs too as | ||
815 | * they share the resv. object). Otherwise during PT update | ||
816 | * job (see amdgpu_vm_bo_update_mapping), eviction fence would | ||
817 | * get added to job->sync object and job execution would | ||
818 | * trigger the eviction fence. | ||
819 | */ | ||
820 | amdgpu_amdkfd_remove_eviction_fence(pd, | ||
821 | vm->process_info->eviction_fence, | ||
822 | NULL, NULL); | ||
823 | amdgpu_vm_bo_unmap(adev, bo_va, entry->va); | 730 | amdgpu_vm_bo_unmap(adev, bo_va, entry->va); |
824 | 731 | ||
825 | amdgpu_vm_clear_freed(adev, vm, &bo_va->last_pt_update); | 732 | amdgpu_vm_clear_freed(adev, vm, &bo_va->last_pt_update); |
826 | 733 | ||
827 | /* Add the eviction fence back */ | ||
828 | amdgpu_bo_fence(pd, &vm->process_info->eviction_fence->base, true); | ||
829 | |||
830 | amdgpu_sync_fence(NULL, sync, bo_va->last_pt_update, false); | 734 | amdgpu_sync_fence(NULL, sync, bo_va->last_pt_update, false); |
831 | 735 | ||
832 | return 0; | 736 | return 0; |
@@ -1002,7 +906,7 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info, | |||
1002 | pr_err("validate_pt_pd_bos() failed\n"); | 906 | pr_err("validate_pt_pd_bos() failed\n"); |
1003 | goto validate_pd_fail; | 907 | goto validate_pd_fail; |
1004 | } | 908 | } |
1005 | ret = ttm_bo_wait(&vm->root.base.bo->tbo, false, false); | 909 | amdgpu_bo_sync_wait(vm->root.base.bo, AMDGPU_FENCE_OWNER_KFD, false); |
1006 | if (ret) | 910 | if (ret) |
1007 | goto wait_pd_fail; | 911 | goto wait_pd_fail; |
1008 | amdgpu_bo_fence(vm->root.base.bo, | 912 | amdgpu_bo_fence(vm->root.base.bo, |
@@ -1389,8 +1293,7 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu( | |||
1389 | * attached | 1293 | * attached |
1390 | */ | 1294 | */ |
1391 | amdgpu_amdkfd_remove_eviction_fence(mem->bo, | 1295 | amdgpu_amdkfd_remove_eviction_fence(mem->bo, |
1392 | process_info->eviction_fence, | 1296 | process_info->eviction_fence); |
1393 | NULL, NULL); | ||
1394 | pr_debug("Release VA 0x%llx - 0x%llx\n", mem->va, | 1297 | pr_debug("Release VA 0x%llx - 0x%llx\n", mem->va, |
1395 | mem->va + bo_size * (1 + mem->aql_queue)); | 1298 | mem->va + bo_size * (1 + mem->aql_queue)); |
1396 | 1299 | ||
@@ -1617,8 +1520,7 @@ int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( | |||
1617 | if (mem->mapped_to_gpu_memory == 0 && | 1520 | if (mem->mapped_to_gpu_memory == 0 && |
1618 | !amdgpu_ttm_tt_get_usermm(mem->bo->tbo.ttm) && !mem->bo->pin_count) | 1521 | !amdgpu_ttm_tt_get_usermm(mem->bo->tbo.ttm) && !mem->bo->pin_count) |
1619 | amdgpu_amdkfd_remove_eviction_fence(mem->bo, | 1522 | amdgpu_amdkfd_remove_eviction_fence(mem->bo, |
1620 | process_info->eviction_fence, | 1523 | process_info->eviction_fence); |
1621 | NULL, NULL); | ||
1622 | 1524 | ||
1623 | unreserve_out: | 1525 | unreserve_out: |
1624 | unreserve_bo_and_vms(&ctx, false, false); | 1526 | unreserve_bo_and_vms(&ctx, false, false); |
@@ -1679,7 +1581,7 @@ int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_dev *kgd, | |||
1679 | } | 1581 | } |
1680 | 1582 | ||
1681 | amdgpu_amdkfd_remove_eviction_fence( | 1583 | amdgpu_amdkfd_remove_eviction_fence( |
1682 | bo, mem->process_info->eviction_fence, NULL, NULL); | 1584 | bo, mem->process_info->eviction_fence); |
1683 | list_del_init(&mem->validate_list.head); | 1585 | list_del_init(&mem->validate_list.head); |
1684 | 1586 | ||
1685 | if (size) | 1587 | if (size) |
@@ -1945,16 +1847,6 @@ static int validate_invalid_user_pages(struct amdkfd_process_info *process_info) | |||
1945 | 1847 | ||
1946 | amdgpu_sync_create(&sync); | 1848 | amdgpu_sync_create(&sync); |
1947 | 1849 | ||
1948 | /* Avoid triggering eviction fences when unmapping invalid | ||
1949 | * userptr BOs (waits for all fences, doesn't use | ||
1950 | * FENCE_OWNER_VM) | ||
1951 | */ | ||
1952 | list_for_each_entry(peer_vm, &process_info->vm_list_head, | ||
1953 | vm_list_node) | ||
1954 | amdgpu_amdkfd_remove_eviction_fence(peer_vm->root.base.bo, | ||
1955 | process_info->eviction_fence, | ||
1956 | NULL, NULL); | ||
1957 | |||
1958 | ret = process_validate_vms(process_info); | 1850 | ret = process_validate_vms(process_info); |
1959 | if (ret) | 1851 | if (ret) |
1960 | goto unreserve_out; | 1852 | goto unreserve_out; |
@@ -2015,10 +1907,6 @@ static int validate_invalid_user_pages(struct amdkfd_process_info *process_info) | |||
2015 | ret = process_update_pds(process_info, &sync); | 1907 | ret = process_update_pds(process_info, &sync); |
2016 | 1908 | ||
2017 | unreserve_out: | 1909 | unreserve_out: |
2018 | list_for_each_entry(peer_vm, &process_info->vm_list_head, | ||
2019 | vm_list_node) | ||
2020 | amdgpu_bo_fence(peer_vm->root.base.bo, | ||
2021 | &process_info->eviction_fence->base, true); | ||
2022 | ttm_eu_backoff_reservation(&ticket, &resv_list); | 1910 | ttm_eu_backoff_reservation(&ticket, &resv_list); |
2023 | amdgpu_sync_wait(&sync, false); | 1911 | amdgpu_sync_wait(&sync, false); |
2024 | amdgpu_sync_free(&sync); | 1912 | amdgpu_sync_free(&sync); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index d85184b5b35c..7b526593eb77 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | |||
@@ -124,6 +124,7 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, | |||
124 | struct amdgpu_ring *rings[AMDGPU_MAX_RINGS]; | 124 | struct amdgpu_ring *rings[AMDGPU_MAX_RINGS]; |
125 | struct drm_sched_rq *rqs[AMDGPU_MAX_RINGS]; | 125 | struct drm_sched_rq *rqs[AMDGPU_MAX_RINGS]; |
126 | unsigned num_rings; | 126 | unsigned num_rings; |
127 | unsigned num_rqs = 0; | ||
127 | 128 | ||
128 | switch (i) { | 129 | switch (i) { |
129 | case AMDGPU_HW_IP_GFX: | 130 | case AMDGPU_HW_IP_GFX: |
@@ -166,12 +167,16 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, | |||
166 | break; | 167 | break; |
167 | } | 168 | } |
168 | 169 | ||
169 | for (j = 0; j < num_rings; ++j) | 170 | for (j = 0; j < num_rings; ++j) { |
170 | rqs[j] = &rings[j]->sched.sched_rq[priority]; | 171 | if (!rings[j]->adev) |
172 | continue; | ||
173 | |||
174 | rqs[num_rqs++] = &rings[j]->sched.sched_rq[priority]; | ||
175 | } | ||
171 | 176 | ||
172 | for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) | 177 | for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) |
173 | r = drm_sched_entity_init(&ctx->entities[i][j].entity, | 178 | r = drm_sched_entity_init(&ctx->entities[i][j].entity, |
174 | rqs, num_rings, &ctx->guilty); | 179 | rqs, num_rqs, &ctx->guilty); |
175 | if (r) | 180 | if (r) |
176 | goto error_cleanup_entities; | 181 | goto error_cleanup_entities; |
177 | } | 182 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index dd9a4fb9ce39..4ae3ff9a1d4c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | |||
@@ -158,9 +158,6 @@ static int amdgpu_debugfs_process_reg_op(bool read, struct file *f, | |||
158 | while (size) { | 158 | while (size) { |
159 | uint32_t value; | 159 | uint32_t value; |
160 | 160 | ||
161 | if (*pos > adev->rmmio_size) | ||
162 | goto end; | ||
163 | |||
164 | if (read) { | 161 | if (read) { |
165 | value = RREG32(*pos >> 2); | 162 | value = RREG32(*pos >> 2); |
166 | r = put_user(value, (uint32_t *)buf); | 163 | r = put_user(value, (uint32_t *)buf); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h index 1cfec06f81d4..68959b923f89 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h | |||
@@ -71,6 +71,8 @@ struct amdgpu_doorbell_index { | |||
71 | uint32_t vce_ring6_7; | 71 | uint32_t vce_ring6_7; |
72 | } uvd_vce; | 72 | } uvd_vce; |
73 | }; | 73 | }; |
74 | uint32_t first_non_cp; | ||
75 | uint32_t last_non_cp; | ||
74 | uint32_t max_assignment; | 76 | uint32_t max_assignment; |
75 | /* Per engine SDMA doorbell size in dword */ | 77 | /* Per engine SDMA doorbell size in dword */ |
76 | uint32_t sdma_doorbell_range; | 78 | uint32_t sdma_doorbell_range; |
@@ -143,6 +145,10 @@ typedef enum _AMDGPU_VEGA20_DOORBELL_ASSIGNMENT | |||
143 | AMDGPU_VEGA20_DOORBELL64_VCE_RING2_3 = 0x18D, | 145 | AMDGPU_VEGA20_DOORBELL64_VCE_RING2_3 = 0x18D, |
144 | AMDGPU_VEGA20_DOORBELL64_VCE_RING4_5 = 0x18E, | 146 | AMDGPU_VEGA20_DOORBELL64_VCE_RING4_5 = 0x18E, |
145 | AMDGPU_VEGA20_DOORBELL64_VCE_RING6_7 = 0x18F, | 147 | AMDGPU_VEGA20_DOORBELL64_VCE_RING6_7 = 0x18F, |
148 | |||
149 | AMDGPU_VEGA20_DOORBELL64_FIRST_NON_CP = AMDGPU_VEGA20_DOORBELL_sDMA_ENGINE0, | ||
150 | AMDGPU_VEGA20_DOORBELL64_LAST_NON_CP = AMDGPU_VEGA20_DOORBELL64_VCE_RING6_7, | ||
151 | |||
146 | AMDGPU_VEGA20_DOORBELL_MAX_ASSIGNMENT = 0x18F, | 152 | AMDGPU_VEGA20_DOORBELL_MAX_ASSIGNMENT = 0x18F, |
147 | AMDGPU_VEGA20_DOORBELL_INVALID = 0xFFFF | 153 | AMDGPU_VEGA20_DOORBELL_INVALID = 0xFFFF |
148 | } AMDGPU_VEGA20_DOORBELL_ASSIGNMENT; | 154 | } AMDGPU_VEGA20_DOORBELL_ASSIGNMENT; |
@@ -222,6 +228,9 @@ typedef enum _AMDGPU_DOORBELL64_ASSIGNMENT | |||
222 | AMDGPU_DOORBELL64_VCE_RING4_5 = 0xFE, | 228 | AMDGPU_DOORBELL64_VCE_RING4_5 = 0xFE, |
223 | AMDGPU_DOORBELL64_VCE_RING6_7 = 0xFF, | 229 | AMDGPU_DOORBELL64_VCE_RING6_7 = 0xFF, |
224 | 230 | ||
231 | AMDGPU_DOORBELL64_FIRST_NON_CP = AMDGPU_DOORBELL64_sDMA_ENGINE0, | ||
232 | AMDGPU_DOORBELL64_LAST_NON_CP = AMDGPU_DOORBELL64_VCE_RING6_7, | ||
233 | |||
225 | AMDGPU_DOORBELL64_MAX_ASSIGNMENT = 0xFF, | 234 | AMDGPU_DOORBELL64_MAX_ASSIGNMENT = 0xFF, |
226 | AMDGPU_DOORBELL64_INVALID = 0xFFFF | 235 | AMDGPU_DOORBELL64_INVALID = 0xFFFF |
227 | } AMDGPU_DOORBELL64_ASSIGNMENT; | 236 | } AMDGPU_DOORBELL64_ASSIGNMENT; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c index 1c4595562f8f..344967df3137 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c | |||
@@ -184,61 +184,6 @@ u32 amdgpu_dpm_get_vrefresh(struct amdgpu_device *adev) | |||
184 | return vrefresh; | 184 | return vrefresh; |
185 | } | 185 | } |
186 | 186 | ||
187 | void amdgpu_calculate_u_and_p(u32 i, u32 r_c, u32 p_b, | ||
188 | u32 *p, u32 *u) | ||
189 | { | ||
190 | u32 b_c = 0; | ||
191 | u32 i_c; | ||
192 | u32 tmp; | ||
193 | |||
194 | i_c = (i * r_c) / 100; | ||
195 | tmp = i_c >> p_b; | ||
196 | |||
197 | while (tmp) { | ||
198 | b_c++; | ||
199 | tmp >>= 1; | ||
200 | } | ||
201 | |||
202 | *u = (b_c + 1) / 2; | ||
203 | *p = i_c / (1 << (2 * (*u))); | ||
204 | } | ||
205 | |||
206 | int amdgpu_calculate_at(u32 t, u32 h, u32 fh, u32 fl, u32 *tl, u32 *th) | ||
207 | { | ||
208 | u32 k, a, ah, al; | ||
209 | u32 t1; | ||
210 | |||
211 | if ((fl == 0) || (fh == 0) || (fl > fh)) | ||
212 | return -EINVAL; | ||
213 | |||
214 | k = (100 * fh) / fl; | ||
215 | t1 = (t * (k - 100)); | ||
216 | a = (1000 * (100 * h + t1)) / (10000 + (t1 / 100)); | ||
217 | a = (a + 5) / 10; | ||
218 | ah = ((a * t) + 5000) / 10000; | ||
219 | al = a - ah; | ||
220 | |||
221 | *th = t - ah; | ||
222 | *tl = t + al; | ||
223 | |||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | bool amdgpu_is_uvd_state(u32 class, u32 class2) | ||
228 | { | ||
229 | if (class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE) | ||
230 | return true; | ||
231 | if (class & ATOM_PPLIB_CLASSIFICATION_HD2STATE) | ||
232 | return true; | ||
233 | if (class & ATOM_PPLIB_CLASSIFICATION_HDSTATE) | ||
234 | return true; | ||
235 | if (class & ATOM_PPLIB_CLASSIFICATION_SDSTATE) | ||
236 | return true; | ||
237 | if (class2 & ATOM_PPLIB_CLASSIFICATION2_MVC) | ||
238 | return true; | ||
239 | return false; | ||
240 | } | ||
241 | |||
242 | bool amdgpu_is_internal_thermal_sensor(enum amdgpu_int_thermal_type sensor) | 187 | bool amdgpu_is_internal_thermal_sensor(enum amdgpu_int_thermal_type sensor) |
243 | { | 188 | { |
244 | switch (sensor) { | 189 | switch (sensor) { |
@@ -949,39 +894,6 @@ enum amdgpu_pcie_gen amdgpu_get_pcie_gen_support(struct amdgpu_device *adev, | |||
949 | return AMDGPU_PCIE_GEN1; | 894 | return AMDGPU_PCIE_GEN1; |
950 | } | 895 | } |
951 | 896 | ||
952 | u16 amdgpu_get_pcie_lane_support(struct amdgpu_device *adev, | ||
953 | u16 asic_lanes, | ||
954 | u16 default_lanes) | ||
955 | { | ||
956 | switch (asic_lanes) { | ||
957 | case 0: | ||
958 | default: | ||
959 | return default_lanes; | ||
960 | case 1: | ||
961 | return 1; | ||
962 | case 2: | ||
963 | return 2; | ||
964 | case 4: | ||
965 | return 4; | ||
966 | case 8: | ||
967 | return 8; | ||
968 | case 12: | ||
969 | return 12; | ||
970 | case 16: | ||
971 | return 16; | ||
972 | } | ||
973 | } | ||
974 | |||
975 | u8 amdgpu_encode_pci_lane_width(u32 lanes) | ||
976 | { | ||
977 | u8 encoded_lanes[] = { 0, 1, 2, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6 }; | ||
978 | |||
979 | if (lanes > 16) | ||
980 | return 0; | ||
981 | |||
982 | return encoded_lanes[lanes]; | ||
983 | } | ||
984 | |||
985 | struct amd_vce_state* | 897 | struct amd_vce_state* |
986 | amdgpu_get_vce_clock_state(void *handle, u32 idx) | 898 | amdgpu_get_vce_clock_state(void *handle, u32 idx) |
987 | { | 899 | { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h index 2f61e9edb1c1..e871e022c129 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h | |||
@@ -486,10 +486,6 @@ void amdgpu_dpm_print_ps_status(struct amdgpu_device *adev, | |||
486 | u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev); | 486 | u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev); |
487 | u32 amdgpu_dpm_get_vrefresh(struct amdgpu_device *adev); | 487 | u32 amdgpu_dpm_get_vrefresh(struct amdgpu_device *adev); |
488 | void amdgpu_dpm_get_active_displays(struct amdgpu_device *adev); | 488 | void amdgpu_dpm_get_active_displays(struct amdgpu_device *adev); |
489 | bool amdgpu_is_uvd_state(u32 class, u32 class2); | ||
490 | void amdgpu_calculate_u_and_p(u32 i, u32 r_c, u32 p_b, | ||
491 | u32 *p, u32 *u); | ||
492 | int amdgpu_calculate_at(u32 t, u32 h, u32 fh, u32 fl, u32 *tl, u32 *th); | ||
493 | 489 | ||
494 | bool amdgpu_is_internal_thermal_sensor(enum amdgpu_int_thermal_type sensor); | 490 | bool amdgpu_is_internal_thermal_sensor(enum amdgpu_int_thermal_type sensor); |
495 | 491 | ||
@@ -505,11 +501,6 @@ enum amdgpu_pcie_gen amdgpu_get_pcie_gen_support(struct amdgpu_device *adev, | |||
505 | enum amdgpu_pcie_gen asic_gen, | 501 | enum amdgpu_pcie_gen asic_gen, |
506 | enum amdgpu_pcie_gen default_gen); | 502 | enum amdgpu_pcie_gen default_gen); |
507 | 503 | ||
508 | u16 amdgpu_get_pcie_lane_support(struct amdgpu_device *adev, | ||
509 | u16 asic_lanes, | ||
510 | u16 default_lanes); | ||
511 | u8 amdgpu_encode_pci_lane_width(u32 lanes); | ||
512 | |||
513 | struct amd_vce_state* | 504 | struct amd_vce_state* |
514 | amdgpu_get_vce_clock_state(void *handle, u32 idx); | 505 | amdgpu_get_vce_clock_state(void *handle, u32 idx); |
515 | 506 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 7f3aa7b7e1d8..7419ea8a388b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | |||
@@ -73,9 +73,10 @@ | |||
73 | * - 3.27.0 - Add new chunk to to AMDGPU_CS to enable BO_LIST creation. | 73 | * - 3.27.0 - Add new chunk to to AMDGPU_CS to enable BO_LIST creation. |
74 | * - 3.28.0 - Add AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES | 74 | * - 3.28.0 - Add AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES |
75 | * - 3.29.0 - Add AMDGPU_IB_FLAG_RESET_GDS_MAX_WAVE_ID | 75 | * - 3.29.0 - Add AMDGPU_IB_FLAG_RESET_GDS_MAX_WAVE_ID |
76 | * - 3.30.0 - Add AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE. | ||
76 | */ | 77 | */ |
77 | #define KMS_DRIVER_MAJOR 3 | 78 | #define KMS_DRIVER_MAJOR 3 |
78 | #define KMS_DRIVER_MINOR 29 | 79 | #define KMS_DRIVER_MINOR 30 |
79 | #define KMS_DRIVER_PATCHLEVEL 0 | 80 | #define KMS_DRIVER_PATCHLEVEL 0 |
80 | 81 | ||
81 | int amdgpu_vram_limit = 0; | 82 | int amdgpu_vram_limit = 0; |
@@ -1178,6 +1179,22 @@ static const struct file_operations amdgpu_driver_kms_fops = { | |||
1178 | #endif | 1179 | #endif |
1179 | }; | 1180 | }; |
1180 | 1181 | ||
1182 | int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv) | ||
1183 | { | ||
1184 | struct drm_file *file; | ||
1185 | |||
1186 | if (!filp) | ||
1187 | return -EINVAL; | ||
1188 | |||
1189 | if (filp->f_op != &amdgpu_driver_kms_fops) { | ||
1190 | return -EINVAL; | ||
1191 | } | ||
1192 | |||
1193 | file = filp->private_data; | ||
1194 | *fpriv = file->driver_priv; | ||
1195 | return 0; | ||
1196 | } | ||
1197 | |||
1181 | static bool | 1198 | static bool |
1182 | amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, | 1199 | amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, |
1183 | bool in_vblank_irq, int *vpos, int *hpos, | 1200 | bool in_vblank_irq, int *vpos, int *hpos, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c index d0a5db777b6d..1c50be3ab8a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | |||
@@ -140,9 +140,7 @@ void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) | |||
140 | * Interrupt hander (VI), walk the IH ring. | 140 | * Interrupt hander (VI), walk the IH ring. |
141 | * Returns irq process return code. | 141 | * Returns irq process return code. |
142 | */ | 142 | */ |
143 | int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, | 143 | int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) |
144 | void (*callback)(struct amdgpu_device *adev, | ||
145 | struct amdgpu_ih_ring *ih)) | ||
146 | { | 144 | { |
147 | u32 wptr; | 145 | u32 wptr; |
148 | 146 | ||
@@ -162,7 +160,7 @@ restart_ih: | |||
162 | rmb(); | 160 | rmb(); |
163 | 161 | ||
164 | while (ih->rptr != wptr) { | 162 | while (ih->rptr != wptr) { |
165 | callback(adev, ih); | 163 | amdgpu_irq_dispatch(adev, ih); |
166 | ih->rptr &= ih->ptr_mask; | 164 | ih->rptr &= ih->ptr_mask; |
167 | } | 165 | } |
168 | 166 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h index 1ccb1831382a..113a1ba13d4a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | |||
@@ -69,8 +69,6 @@ struct amdgpu_ih_funcs { | |||
69 | int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, | 69 | int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, |
70 | unsigned ring_size, bool use_bus_addr); | 70 | unsigned ring_size, bool use_bus_addr); |
71 | void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); | 71 | void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); |
72 | int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, | 72 | int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); |
73 | void (*callback)(struct amdgpu_device *adev, | ||
74 | struct amdgpu_ih_ring *ih)); | ||
75 | 73 | ||
76 | #endif | 74 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 8bfb3dab46f7..af4c3b1af322 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | |||
@@ -131,29 +131,6 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev) | |||
131 | } | 131 | } |
132 | 132 | ||
133 | /** | 133 | /** |
134 | * amdgpu_irq_callback - callback from the IH ring | ||
135 | * | ||
136 | * @adev: amdgpu device pointer | ||
137 | * @ih: amdgpu ih ring | ||
138 | * | ||
139 | * Callback from IH ring processing to handle the entry at the current position | ||
140 | * and advance the read pointer. | ||
141 | */ | ||
142 | static void amdgpu_irq_callback(struct amdgpu_device *adev, | ||
143 | struct amdgpu_ih_ring *ih) | ||
144 | { | ||
145 | u32 ring_index = ih->rptr >> 2; | ||
146 | struct amdgpu_iv_entry entry; | ||
147 | |||
148 | entry.iv_entry = (const uint32_t *)&ih->ring[ring_index]; | ||
149 | amdgpu_ih_decode_iv(adev, &entry); | ||
150 | |||
151 | trace_amdgpu_iv(ih - &adev->irq.ih, &entry); | ||
152 | |||
153 | amdgpu_irq_dispatch(adev, &entry); | ||
154 | } | ||
155 | |||
156 | /** | ||
157 | * amdgpu_irq_handler - IRQ handler | 134 | * amdgpu_irq_handler - IRQ handler |
158 | * | 135 | * |
159 | * @irq: IRQ number (unused) | 136 | * @irq: IRQ number (unused) |
@@ -170,7 +147,7 @@ irqreturn_t amdgpu_irq_handler(int irq, void *arg) | |||
170 | struct amdgpu_device *adev = dev->dev_private; | 147 | struct amdgpu_device *adev = dev->dev_private; |
171 | irqreturn_t ret; | 148 | irqreturn_t ret; |
172 | 149 | ||
173 | ret = amdgpu_ih_process(adev, &adev->irq.ih, amdgpu_irq_callback); | 150 | ret = amdgpu_ih_process(adev, &adev->irq.ih); |
174 | if (ret == IRQ_HANDLED) | 151 | if (ret == IRQ_HANDLED) |
175 | pm_runtime_mark_last_busy(dev->dev); | 152 | pm_runtime_mark_last_busy(dev->dev); |
176 | return ret; | 153 | return ret; |
@@ -188,7 +165,7 @@ static void amdgpu_irq_handle_ih1(struct work_struct *work) | |||
188 | struct amdgpu_device *adev = container_of(work, struct amdgpu_device, | 165 | struct amdgpu_device *adev = container_of(work, struct amdgpu_device, |
189 | irq.ih1_work); | 166 | irq.ih1_work); |
190 | 167 | ||
191 | amdgpu_ih_process(adev, &adev->irq.ih1, amdgpu_irq_callback); | 168 | amdgpu_ih_process(adev, &adev->irq.ih1); |
192 | } | 169 | } |
193 | 170 | ||
194 | /** | 171 | /** |
@@ -203,7 +180,7 @@ static void amdgpu_irq_handle_ih2(struct work_struct *work) | |||
203 | struct amdgpu_device *adev = container_of(work, struct amdgpu_device, | 180 | struct amdgpu_device *adev = container_of(work, struct amdgpu_device, |
204 | irq.ih2_work); | 181 | irq.ih2_work); |
205 | 182 | ||
206 | amdgpu_ih_process(adev, &adev->irq.ih2, amdgpu_irq_callback); | 183 | amdgpu_ih_process(adev, &adev->irq.ih2); |
207 | } | 184 | } |
208 | 185 | ||
209 | /** | 186 | /** |
@@ -394,14 +371,23 @@ int amdgpu_irq_add_id(struct amdgpu_device *adev, | |||
394 | * Dispatches IRQ to IP blocks. | 371 | * Dispatches IRQ to IP blocks. |
395 | */ | 372 | */ |
396 | void amdgpu_irq_dispatch(struct amdgpu_device *adev, | 373 | void amdgpu_irq_dispatch(struct amdgpu_device *adev, |
397 | struct amdgpu_iv_entry *entry) | 374 | struct amdgpu_ih_ring *ih) |
398 | { | 375 | { |
399 | unsigned client_id = entry->client_id; | 376 | u32 ring_index = ih->rptr >> 2; |
400 | unsigned src_id = entry->src_id; | 377 | struct amdgpu_iv_entry entry; |
378 | unsigned client_id, src_id; | ||
401 | struct amdgpu_irq_src *src; | 379 | struct amdgpu_irq_src *src; |
402 | bool handled = false; | 380 | bool handled = false; |
403 | int r; | 381 | int r; |
404 | 382 | ||
383 | entry.iv_entry = (const uint32_t *)&ih->ring[ring_index]; | ||
384 | amdgpu_ih_decode_iv(adev, &entry); | ||
385 | |||
386 | trace_amdgpu_iv(ih - &adev->irq.ih, &entry); | ||
387 | |||
388 | client_id = entry.client_id; | ||
389 | src_id = entry.src_id; | ||
390 | |||
405 | if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) { | 391 | if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) { |
406 | DRM_DEBUG("Invalid client_id in IV: %d\n", client_id); | 392 | DRM_DEBUG("Invalid client_id in IV: %d\n", client_id); |
407 | 393 | ||
@@ -416,7 +402,7 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev, | |||
416 | client_id, src_id); | 402 | client_id, src_id); |
417 | 403 | ||
418 | } else if ((src = adev->irq.client[client_id].sources[src_id])) { | 404 | } else if ((src = adev->irq.client[client_id].sources[src_id])) { |
419 | r = src->funcs->process(adev, src, entry); | 405 | r = src->funcs->process(adev, src, &entry); |
420 | if (r < 0) | 406 | if (r < 0) |
421 | DRM_ERROR("error processing interrupt (%d)\n", r); | 407 | DRM_ERROR("error processing interrupt (%d)\n", r); |
422 | else if (r) | 408 | else if (r) |
@@ -428,7 +414,7 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev, | |||
428 | 414 | ||
429 | /* Send it to amdkfd as well if it isn't already handled */ | 415 | /* Send it to amdkfd as well if it isn't already handled */ |
430 | if (!handled) | 416 | if (!handled) |
431 | amdgpu_amdkfd_interrupt(adev, entry->iv_entry); | 417 | amdgpu_amdkfd_interrupt(adev, entry.iv_entry); |
432 | } | 418 | } |
433 | 419 | ||
434 | /** | 420 | /** |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h index c27decfda494..c718e94a55c9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | |||
@@ -108,7 +108,7 @@ int amdgpu_irq_add_id(struct amdgpu_device *adev, | |||
108 | unsigned client_id, unsigned src_id, | 108 | unsigned client_id, unsigned src_id, |
109 | struct amdgpu_irq_src *source); | 109 | struct amdgpu_irq_src *source); |
110 | void amdgpu_irq_dispatch(struct amdgpu_device *adev, | 110 | void amdgpu_irq_dispatch(struct amdgpu_device *adev, |
111 | struct amdgpu_iv_entry *entry); | 111 | struct amdgpu_ih_ring *ih); |
112 | int amdgpu_irq_update(struct amdgpu_device *adev, struct amdgpu_irq_src *src, | 112 | int amdgpu_irq_update(struct amdgpu_device *adev, struct amdgpu_irq_src *src, |
113 | unsigned type); | 113 | unsigned type); |
114 | int amdgpu_irq_get(struct amdgpu_device *adev, struct amdgpu_irq_src *src, | 114 | int amdgpu_irq_get(struct amdgpu_device *adev, struct amdgpu_irq_src *src, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index bc62bf41b7e9..b65e18101108 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |||
@@ -207,7 +207,7 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags) | |||
207 | if (!r) { | 207 | if (!r) { |
208 | acpi_status = amdgpu_acpi_init(adev); | 208 | acpi_status = amdgpu_acpi_init(adev); |
209 | if (acpi_status) | 209 | if (acpi_status) |
210 | dev_dbg(&dev->pdev->dev, | 210 | dev_dbg(&dev->pdev->dev, |
211 | "Error during ACPI methods call\n"); | 211 | "Error during ACPI methods call\n"); |
212 | } | 212 | } |
213 | 213 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index fd9c4beeaaa4..ec9e45004bff 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | |||
@@ -1285,6 +1285,30 @@ void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence, | |||
1285 | } | 1285 | } |
1286 | 1286 | ||
1287 | /** | 1287 | /** |
1288 | * amdgpu_sync_wait_resv - Wait for BO reservation fences | ||
1289 | * | ||
1290 | * @bo: buffer object | ||
1291 | * @owner: fence owner | ||
1292 | * @intr: Whether the wait is interruptible | ||
1293 | * | ||
1294 | * Returns: | ||
1295 | * 0 on success, errno otherwise. | ||
1296 | */ | ||
1297 | int amdgpu_bo_sync_wait(struct amdgpu_bo *bo, void *owner, bool intr) | ||
1298 | { | ||
1299 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); | ||
1300 | struct amdgpu_sync sync; | ||
1301 | int r; | ||
1302 | |||
1303 | amdgpu_sync_create(&sync); | ||
1304 | amdgpu_sync_resv(adev, &sync, bo->tbo.resv, owner, false); | ||
1305 | r = amdgpu_sync_wait(&sync, intr); | ||
1306 | amdgpu_sync_free(&sync); | ||
1307 | |||
1308 | return r; | ||
1309 | } | ||
1310 | |||
1311 | /** | ||
1288 | * amdgpu_bo_gpu_offset - return GPU offset of bo | 1312 | * amdgpu_bo_gpu_offset - return GPU offset of bo |
1289 | * @bo: amdgpu object for which we query the offset | 1313 | * @bo: amdgpu object for which we query the offset |
1290 | * | 1314 | * |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index 9291c2f837e9..220a6a7b1bc1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | |||
@@ -266,6 +266,7 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, | |||
266 | int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo); | 266 | int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo); |
267 | void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence, | 267 | void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence, |
268 | bool shared); | 268 | bool shared); |
269 | int amdgpu_bo_sync_wait(struct amdgpu_bo *bo, void *owner, bool intr); | ||
269 | u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo); | 270 | u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo); |
270 | int amdgpu_bo_validate(struct amdgpu_bo *bo); | 271 | int amdgpu_bo_validate(struct amdgpu_bo *bo); |
271 | int amdgpu_bo_restore_shadow(struct amdgpu_bo *shadow, | 272 | int amdgpu_bo_restore_shadow(struct amdgpu_bo *shadow, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index 1cafe8d83a4d..0767a93e4d91 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | |||
@@ -54,16 +54,20 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev, | |||
54 | enum drm_sched_priority priority) | 54 | enum drm_sched_priority priority) |
55 | { | 55 | { |
56 | struct file *filp = fget(fd); | 56 | struct file *filp = fget(fd); |
57 | struct drm_file *file; | ||
58 | struct amdgpu_fpriv *fpriv; | 57 | struct amdgpu_fpriv *fpriv; |
59 | struct amdgpu_ctx *ctx; | 58 | struct amdgpu_ctx *ctx; |
60 | uint32_t id; | 59 | uint32_t id; |
60 | int r; | ||
61 | 61 | ||
62 | if (!filp) | 62 | if (!filp) |
63 | return -EINVAL; | 63 | return -EINVAL; |
64 | 64 | ||
65 | file = filp->private_data; | 65 | r = amdgpu_file_to_fpriv(filp, &fpriv); |
66 | fpriv = file->driver_priv; | 66 | if (r) { |
67 | fput(filp); | ||
68 | return r; | ||
69 | } | ||
70 | |||
67 | idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id) | 71 | idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id) |
68 | amdgpu_ctx_priority_override(ctx, priority); | 72 | amdgpu_ctx_priority_override(ctx, priority); |
69 | 73 | ||
@@ -72,6 +76,39 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev, | |||
72 | return 0; | 76 | return 0; |
73 | } | 77 | } |
74 | 78 | ||
79 | static int amdgpu_sched_context_priority_override(struct amdgpu_device *adev, | ||
80 | int fd, | ||
81 | unsigned ctx_id, | ||
82 | enum drm_sched_priority priority) | ||
83 | { | ||
84 | struct file *filp = fget(fd); | ||
85 | struct amdgpu_fpriv *fpriv; | ||
86 | struct amdgpu_ctx *ctx; | ||
87 | int r; | ||
88 | |||
89 | if (!filp) | ||
90 | return -EINVAL; | ||
91 | |||
92 | r = amdgpu_file_to_fpriv(filp, &fpriv); | ||
93 | if (r) { | ||
94 | fput(filp); | ||
95 | return r; | ||
96 | } | ||
97 | |||
98 | ctx = amdgpu_ctx_get(fpriv, ctx_id); | ||
99 | |||
100 | if (!ctx) { | ||
101 | fput(filp); | ||
102 | return -EINVAL; | ||
103 | } | ||
104 | |||
105 | amdgpu_ctx_priority_override(ctx, priority); | ||
106 | amdgpu_ctx_put(ctx); | ||
107 | fput(filp); | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
75 | int amdgpu_sched_ioctl(struct drm_device *dev, void *data, | 112 | int amdgpu_sched_ioctl(struct drm_device *dev, void *data, |
76 | struct drm_file *filp) | 113 | struct drm_file *filp) |
77 | { | 114 | { |
@@ -81,7 +118,7 @@ int amdgpu_sched_ioctl(struct drm_device *dev, void *data, | |||
81 | int r; | 118 | int r; |
82 | 119 | ||
83 | priority = amdgpu_to_sched_priority(args->in.priority); | 120 | priority = amdgpu_to_sched_priority(args->in.priority); |
84 | if (args->in.flags || priority == DRM_SCHED_PRIORITY_INVALID) | 121 | if (priority == DRM_SCHED_PRIORITY_INVALID) |
85 | return -EINVAL; | 122 | return -EINVAL; |
86 | 123 | ||
87 | switch (args->in.op) { | 124 | switch (args->in.op) { |
@@ -90,6 +127,12 @@ int amdgpu_sched_ioctl(struct drm_device *dev, void *data, | |||
90 | args->in.fd, | 127 | args->in.fd, |
91 | priority); | 128 | priority); |
92 | break; | 129 | break; |
130 | case AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE: | ||
131 | r = amdgpu_sched_context_priority_override(adev, | ||
132 | args->in.fd, | ||
133 | args->in.ctx_id, | ||
134 | priority); | ||
135 | break; | ||
93 | default: | 136 | default: |
94 | DRM_ERROR("Invalid sched op specified: %d\n", args->in.op); | 137 | DRM_ERROR("Invalid sched op specified: %d\n", args->in.op); |
95 | r = -EINVAL; | 138 | r = -EINVAL; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 7cd2336e29ff..942b5ebc6dc2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -698,8 +698,6 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, | |||
698 | struct amdgpu_vm_bo_base *bo_base, *tmp; | 698 | struct amdgpu_vm_bo_base *bo_base, *tmp; |
699 | int r = 0; | 699 | int r = 0; |
700 | 700 | ||
701 | vm->bulk_moveable &= list_empty(&vm->evicted); | ||
702 | |||
703 | list_for_each_entry_safe(bo_base, tmp, &vm->evicted, vm_status) { | 701 | list_for_each_entry_safe(bo_base, tmp, &vm->evicted, vm_status) { |
704 | struct amdgpu_bo *bo = bo_base->bo; | 702 | struct amdgpu_bo *bo = bo_base->bo; |
705 | 703 | ||
@@ -828,7 +826,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, | |||
828 | 826 | ||
829 | WARN_ON(job->ibs[0].length_dw > 64); | 827 | WARN_ON(job->ibs[0].length_dw > 64); |
830 | r = amdgpu_sync_resv(adev, &job->sync, bo->tbo.resv, | 828 | r = amdgpu_sync_resv(adev, &job->sync, bo->tbo.resv, |
831 | AMDGPU_FENCE_OWNER_UNDEFINED, false); | 829 | AMDGPU_FENCE_OWNER_KFD, false); |
832 | if (r) | 830 | if (r) |
833 | goto error_free; | 831 | goto error_free; |
834 | 832 | ||
@@ -1332,31 +1330,6 @@ static void amdgpu_vm_cpu_set_ptes(struct amdgpu_pte_update_params *params, | |||
1332 | } | 1330 | } |
1333 | } | 1331 | } |
1334 | 1332 | ||
1335 | |||
1336 | /** | ||
1337 | * amdgpu_vm_wait_pd - Wait for PT BOs to be free. | ||
1338 | * | ||
1339 | * @adev: amdgpu_device pointer | ||
1340 | * @vm: related vm | ||
1341 | * @owner: fence owner | ||
1342 | * | ||
1343 | * Returns: | ||
1344 | * 0 on success, errno otherwise. | ||
1345 | */ | ||
1346 | static int amdgpu_vm_wait_pd(struct amdgpu_device *adev, struct amdgpu_vm *vm, | ||
1347 | void *owner) | ||
1348 | { | ||
1349 | struct amdgpu_sync sync; | ||
1350 | int r; | ||
1351 | |||
1352 | amdgpu_sync_create(&sync); | ||
1353 | amdgpu_sync_resv(adev, &sync, vm->root.base.bo->tbo.resv, owner, false); | ||
1354 | r = amdgpu_sync_wait(&sync, true); | ||
1355 | amdgpu_sync_free(&sync); | ||
1356 | |||
1357 | return r; | ||
1358 | } | ||
1359 | |||
1360 | /** | 1333 | /** |
1361 | * amdgpu_vm_update_func - helper to call update function | 1334 | * amdgpu_vm_update_func - helper to call update function |
1362 | * | 1335 | * |
@@ -1451,7 +1424,8 @@ restart: | |||
1451 | params.adev = adev; | 1424 | params.adev = adev; |
1452 | 1425 | ||
1453 | if (vm->use_cpu_for_update) { | 1426 | if (vm->use_cpu_for_update) { |
1454 | r = amdgpu_vm_wait_pd(adev, vm, AMDGPU_FENCE_OWNER_VM); | 1427 | r = amdgpu_bo_sync_wait(vm->root.base.bo, |
1428 | AMDGPU_FENCE_OWNER_VM, true); | ||
1455 | if (unlikely(r)) | 1429 | if (unlikely(r)) |
1456 | return r; | 1430 | return r; |
1457 | 1431 | ||
@@ -1772,9 +1746,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
1772 | params.adev = adev; | 1746 | params.adev = adev; |
1773 | params.vm = vm; | 1747 | params.vm = vm; |
1774 | 1748 | ||
1775 | /* sync to everything on unmapping */ | 1749 | /* sync to everything except eviction fences on unmapping */ |
1776 | if (!(flags & AMDGPU_PTE_VALID)) | 1750 | if (!(flags & AMDGPU_PTE_VALID)) |
1777 | owner = AMDGPU_FENCE_OWNER_UNDEFINED; | 1751 | owner = AMDGPU_FENCE_OWNER_KFD; |
1778 | 1752 | ||
1779 | if (vm->use_cpu_for_update) { | 1753 | if (vm->use_cpu_for_update) { |
1780 | /* params.src is used as flag to indicate system Memory */ | 1754 | /* params.src is used as flag to indicate system Memory */ |
@@ -1784,7 +1758,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
1784 | /* Wait for PT BOs to be idle. PTs share the same resv. object | 1758 | /* Wait for PT BOs to be idle. PTs share the same resv. object |
1785 | * as the root PD BO | 1759 | * as the root PD BO |
1786 | */ | 1760 | */ |
1787 | r = amdgpu_vm_wait_pd(adev, vm, owner); | 1761 | r = amdgpu_bo_sync_wait(vm->root.base.bo, owner, true); |
1788 | if (unlikely(r)) | 1762 | if (unlikely(r)) |
1789 | return r; | 1763 | return r; |
1790 | 1764 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c index db443ec53d3a..bea32f076b91 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | |||
@@ -2980,7 +2980,7 @@ static int dce_v6_0_pageflip_irq(struct amdgpu_device *adev, | |||
2980 | struct amdgpu_irq_src *source, | 2980 | struct amdgpu_irq_src *source, |
2981 | struct amdgpu_iv_entry *entry) | 2981 | struct amdgpu_iv_entry *entry) |
2982 | { | 2982 | { |
2983 | unsigned long flags; | 2983 | unsigned long flags; |
2984 | unsigned crtc_id; | 2984 | unsigned crtc_id; |
2985 | struct amdgpu_crtc *amdgpu_crtc; | 2985 | struct amdgpu_crtc *amdgpu_crtc; |
2986 | struct amdgpu_flip_work *works; | 2986 | struct amdgpu_flip_work *works; |
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c index b11a1c17a7f2..73851ebb3833 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c | |||
@@ -266,7 +266,8 @@ flr_done: | |||
266 | } | 266 | } |
267 | 267 | ||
268 | /* Trigger recovery for world switch failure if no TDR */ | 268 | /* Trigger recovery for world switch failure if no TDR */ |
269 | if (amdgpu_device_should_recover_gpu(adev)) | 269 | if (amdgpu_device_should_recover_gpu(adev) |
270 | && amdgpu_lockup_timeout == MAX_SCHEDULE_TIMEOUT) | ||
270 | amdgpu_device_gpu_recover(adev, NULL); | 271 | amdgpu_device_gpu_recover(adev, NULL); |
271 | } | 272 | } |
272 | 273 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c index 221f26e50322..c69d51598cfe 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | static u32 nbio_v7_4_get_rev_id(struct amdgpu_device *adev) | 33 | static u32 nbio_v7_4_get_rev_id(struct amdgpu_device *adev) |
34 | { | 34 | { |
35 | u32 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0); | 35 | u32 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0); |
36 | 36 | ||
37 | tmp &= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK; | 37 | tmp &= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK; |
38 | tmp >>= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT; | 38 | tmp >>= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT; |
diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c index 79c1a9bbcc21..9d8df68893b9 100644 --- a/drivers/gpu/drm/amd/amdgpu/si.c +++ b/drivers/gpu/drm/amd/amdgpu/si.c | |||
@@ -1436,7 +1436,7 @@ static int si_common_early_init(void *handle) | |||
1436 | AMD_CG_SUPPORT_UVD_MGCG | | 1436 | AMD_CG_SUPPORT_UVD_MGCG | |
1437 | AMD_CG_SUPPORT_HDP_LS | | 1437 | AMD_CG_SUPPORT_HDP_LS | |
1438 | AMD_CG_SUPPORT_HDP_MGCG; | 1438 | AMD_CG_SUPPORT_HDP_MGCG; |
1439 | adev->pg_flags = 0; | 1439 | adev->pg_flags = 0; |
1440 | adev->external_rev_id = (adev->rev_id == 0) ? 1 : | 1440 | adev->external_rev_id = (adev->rev_id == 0) ? 1 : |
1441 | (adev->rev_id == 1) ? 5 : 6; | 1441 | (adev->rev_id == 1) ? 5 : 6; |
1442 | break; | 1442 | break; |
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index da58040fdbdc..41e01a7f57a4 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c | |||
@@ -6216,10 +6216,12 @@ static void si_request_link_speed_change_before_state_change(struct amdgpu_devic | |||
6216 | si_pi->force_pcie_gen = AMDGPU_PCIE_GEN2; | 6216 | si_pi->force_pcie_gen = AMDGPU_PCIE_GEN2; |
6217 | if (current_link_speed == AMDGPU_PCIE_GEN2) | 6217 | if (current_link_speed == AMDGPU_PCIE_GEN2) |
6218 | break; | 6218 | break; |
6219 | /* fall through */ | ||
6219 | case AMDGPU_PCIE_GEN2: | 6220 | case AMDGPU_PCIE_GEN2: |
6220 | if (amdgpu_acpi_pcie_performance_request(adev, PCIE_PERF_REQ_PECI_GEN2, false) == 0) | 6221 | if (amdgpu_acpi_pcie_performance_request(adev, PCIE_PERF_REQ_PECI_GEN2, false) == 0) |
6221 | break; | 6222 | break; |
6222 | #endif | 6223 | #endif |
6224 | /* fall through */ | ||
6223 | default: | 6225 | default: |
6224 | si_pi->force_pcie_gen = si_get_current_pcie_speed(adev); | 6226 | si_pi->force_pcie_gen = si_get_current_pcie_speed(adev); |
6225 | break; | 6227 | break; |
diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_reg_init.c b/drivers/gpu/drm/amd/amdgpu/vega10_reg_init.c index 4b5d60ea3e78..a8e92638a2e8 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega10_reg_init.c +++ b/drivers/gpu/drm/amd/amdgpu/vega10_reg_init.c | |||
@@ -81,6 +81,10 @@ void vega10_doorbell_index_init(struct amdgpu_device *adev) | |||
81 | adev->doorbell_index.uvd_vce.vce_ring2_3 = AMDGPU_DOORBELL64_VCE_RING2_3; | 81 | adev->doorbell_index.uvd_vce.vce_ring2_3 = AMDGPU_DOORBELL64_VCE_RING2_3; |
82 | adev->doorbell_index.uvd_vce.vce_ring4_5 = AMDGPU_DOORBELL64_VCE_RING4_5; | 82 | adev->doorbell_index.uvd_vce.vce_ring4_5 = AMDGPU_DOORBELL64_VCE_RING4_5; |
83 | adev->doorbell_index.uvd_vce.vce_ring6_7 = AMDGPU_DOORBELL64_VCE_RING6_7; | 83 | adev->doorbell_index.uvd_vce.vce_ring6_7 = AMDGPU_DOORBELL64_VCE_RING6_7; |
84 | |||
85 | adev->doorbell_index.first_non_cp = AMDGPU_DOORBELL64_FIRST_NON_CP; | ||
86 | adev->doorbell_index.last_non_cp = AMDGPU_DOORBELL64_LAST_NON_CP; | ||
87 | |||
84 | /* In unit of dword doorbell */ | 88 | /* In unit of dword doorbell */ |
85 | adev->doorbell_index.max_assignment = AMDGPU_DOORBELL64_MAX_ASSIGNMENT << 1; | 89 | adev->doorbell_index.max_assignment = AMDGPU_DOORBELL64_MAX_ASSIGNMENT << 1; |
86 | adev->doorbell_index.sdma_doorbell_range = 4; | 90 | adev->doorbell_index.sdma_doorbell_range = 4; |
diff --git a/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c b/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c index 53716c593b2b..0db84386252a 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c +++ b/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c | |||
@@ -85,6 +85,10 @@ void vega20_doorbell_index_init(struct amdgpu_device *adev) | |||
85 | adev->doorbell_index.uvd_vce.vce_ring2_3 = AMDGPU_VEGA20_DOORBELL64_VCE_RING2_3; | 85 | adev->doorbell_index.uvd_vce.vce_ring2_3 = AMDGPU_VEGA20_DOORBELL64_VCE_RING2_3; |
86 | adev->doorbell_index.uvd_vce.vce_ring4_5 = AMDGPU_VEGA20_DOORBELL64_VCE_RING4_5; | 86 | adev->doorbell_index.uvd_vce.vce_ring4_5 = AMDGPU_VEGA20_DOORBELL64_VCE_RING4_5; |
87 | adev->doorbell_index.uvd_vce.vce_ring6_7 = AMDGPU_VEGA20_DOORBELL64_VCE_RING6_7; | 87 | adev->doorbell_index.uvd_vce.vce_ring6_7 = AMDGPU_VEGA20_DOORBELL64_VCE_RING6_7; |
88 | |||
89 | adev->doorbell_index.first_non_cp = AMDGPU_VEGA20_DOORBELL64_FIRST_NON_CP; | ||
90 | adev->doorbell_index.last_non_cp = AMDGPU_VEGA20_DOORBELL64_LAST_NON_CP; | ||
91 | |||
88 | adev->doorbell_index.max_assignment = AMDGPU_VEGA20_DOORBELL_MAX_ASSIGNMENT << 1; | 92 | adev->doorbell_index.max_assignment = AMDGPU_VEGA20_DOORBELL_MAX_ASSIGNMENT << 1; |
89 | adev->doorbell_index.sdma_doorbell_range = 20; | 93 | adev->doorbell_index.sdma_doorbell_range = 20; |
90 | } | 94 | } |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 8372556b52eb..c6c9530e704e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | |||
@@ -134,12 +134,18 @@ static int allocate_doorbell(struct qcm_process_device *qpd, struct queue *q) | |||
134 | */ | 134 | */ |
135 | q->doorbell_id = q->properties.queue_id; | 135 | q->doorbell_id = q->properties.queue_id; |
136 | } else if (q->properties.type == KFD_QUEUE_TYPE_SDMA) { | 136 | } else if (q->properties.type == KFD_QUEUE_TYPE_SDMA) { |
137 | /* For SDMA queues on SOC15, use static doorbell | 137 | /* For SDMA queues on SOC15 with 8-byte doorbell, use static |
138 | * assignments based on the engine and queue. | 138 | * doorbell assignments based on the engine and queue id. |
139 | * The doobell index distance between RLC (2*i) and (2*i+1) | ||
140 | * for a SDMA engine is 512. | ||
139 | */ | 141 | */ |
140 | q->doorbell_id = dev->shared_resources.sdma_doorbell | 142 | uint32_t *idx_offset = |
141 | [q->properties.sdma_engine_id] | 143 | dev->shared_resources.sdma_doorbell_idx; |
142 | [q->properties.sdma_queue_id]; | 144 | |
145 | q->doorbell_id = idx_offset[q->properties.sdma_engine_id] | ||
146 | + (q->properties.sdma_queue_id & 1) | ||
147 | * KFD_QUEUE_DOORBELL_MIRROR_OFFSET | ||
148 | + (q->properties.sdma_queue_id >> 1); | ||
143 | } else { | 149 | } else { |
144 | /* For CP queues on SOC15 reserve a free doorbell ID */ | 150 | /* For CP queues on SOC15 reserve a free doorbell ID */ |
145 | unsigned int found; | 151 | unsigned int found; |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 12b66330fc6d..0eeee3c6d6dc 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h | |||
@@ -97,17 +97,29 @@ | |||
97 | #define KFD_CWSR_TBA_TMA_SIZE (PAGE_SIZE * 2) | 97 | #define KFD_CWSR_TBA_TMA_SIZE (PAGE_SIZE * 2) |
98 | #define KFD_CWSR_TMA_OFFSET PAGE_SIZE | 98 | #define KFD_CWSR_TMA_OFFSET PAGE_SIZE |
99 | 99 | ||
100 | #define KFD_MAX_NUM_OF_QUEUES_PER_DEVICE \ | ||
101 | (KFD_MAX_NUM_OF_PROCESSES * \ | ||
102 | KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) | ||
103 | |||
104 | #define KFD_KERNEL_QUEUE_SIZE 2048 | ||
105 | |||
106 | /* | ||
107 | * 512 = 0x200 | ||
108 | * The doorbell index distance between SDMA RLC (2*i) and (2*i+1) in the | ||
109 | * same SDMA engine on SOC15, which has 8-byte doorbells for SDMA. | ||
110 | * 512 8-byte doorbell distance (i.e. one page away) ensures that SDMA RLC | ||
111 | * (2*i+1) doorbells (in terms of the lower 12 bit address) lie exactly in | ||
112 | * the OFFSET and SIZE set in registers like BIF_SDMA0_DOORBELL_RANGE. | ||
113 | */ | ||
114 | #define KFD_QUEUE_DOORBELL_MIRROR_OFFSET 512 | ||
115 | |||
116 | |||
100 | /* | 117 | /* |
101 | * Kernel module parameter to specify maximum number of supported queues per | 118 | * Kernel module parameter to specify maximum number of supported queues per |
102 | * device | 119 | * device |
103 | */ | 120 | */ |
104 | extern int max_num_of_queues_per_device; | 121 | extern int max_num_of_queues_per_device; |
105 | 122 | ||
106 | #define KFD_MAX_NUM_OF_QUEUES_PER_DEVICE \ | ||
107 | (KFD_MAX_NUM_OF_PROCESSES * \ | ||
108 | KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) | ||
109 | |||
110 | #define KFD_KERNEL_QUEUE_SIZE 2048 | ||
111 | 123 | ||
112 | /* Kernel module parameter to specify the scheduling policy */ | 124 | /* Kernel module parameter to specify the scheduling policy */ |
113 | extern int sched_policy; | 125 | extern int sched_policy; |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 80b36e860a0a..4bdae78bab8e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c | |||
@@ -607,13 +607,17 @@ static int init_doorbell_bitmap(struct qcm_process_device *qpd, | |||
607 | if (!qpd->doorbell_bitmap) | 607 | if (!qpd->doorbell_bitmap) |
608 | return -ENOMEM; | 608 | return -ENOMEM; |
609 | 609 | ||
610 | /* Mask out any reserved doorbells */ | 610 | /* Mask out doorbells reserved for SDMA, IH, and VCN on SOC15. */ |
611 | for (i = 0; i < KFD_MAX_NUM_OF_QUEUES_PER_PROCESS; i++) | 611 | for (i = 0; i < KFD_MAX_NUM_OF_QUEUES_PER_PROCESS / 2; i++) { |
612 | if ((dev->shared_resources.reserved_doorbell_mask & i) == | 612 | if (i >= dev->shared_resources.non_cp_doorbells_start |
613 | dev->shared_resources.reserved_doorbell_val) { | 613 | && i <= dev->shared_resources.non_cp_doorbells_end) { |
614 | set_bit(i, qpd->doorbell_bitmap); | 614 | set_bit(i, qpd->doorbell_bitmap); |
615 | pr_debug("reserved doorbell 0x%03x\n", i); | 615 | set_bit(i + KFD_QUEUE_DOORBELL_MIRROR_OFFSET, |
616 | qpd->doorbell_bitmap); | ||
617 | pr_debug("reserved doorbell 0x%03x and 0x%03x\n", i, | ||
618 | i + KFD_QUEUE_DOORBELL_MIRROR_OFFSET); | ||
616 | } | 619 | } |
620 | } | ||
617 | 621 | ||
618 | return 0; | 622 | return 0; |
619 | } | 623 | } |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 3a6f595f295e..c87fcda61b66 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | |||
@@ -3790,7 +3790,6 @@ static const struct drm_plane_helper_funcs dm_plane_helper_funcs = { | |||
3790 | * check will succeed, and let DC implement proper check | 3790 | * check will succeed, and let DC implement proper check |
3791 | */ | 3791 | */ |
3792 | static const uint32_t rgb_formats[] = { | 3792 | static const uint32_t rgb_formats[] = { |
3793 | DRM_FORMAT_RGB888, | ||
3794 | DRM_FORMAT_XRGB8888, | 3793 | DRM_FORMAT_XRGB8888, |
3795 | DRM_FORMAT_ARGB8888, | 3794 | DRM_FORMAT_ARGB8888, |
3796 | DRM_FORMAT_RGBA8888, | 3795 | DRM_FORMAT_RGBA8888, |
@@ -4678,10 +4677,9 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, | |||
4678 | struct dc_plane_state *dc_plane; | 4677 | struct dc_plane_state *dc_plane; |
4679 | struct dm_plane_state *dm_new_plane_state = to_dm_plane_state(new_plane_state); | 4678 | struct dm_plane_state *dm_new_plane_state = to_dm_plane_state(new_plane_state); |
4680 | 4679 | ||
4681 | if (plane->type == DRM_PLANE_TYPE_CURSOR) { | 4680 | /* Cursor plane is handled after stream updates */ |
4682 | handle_cursor_update(plane, old_plane_state); | 4681 | if (plane->type == DRM_PLANE_TYPE_CURSOR) |
4683 | continue; | 4682 | continue; |
4684 | } | ||
4685 | 4683 | ||
4686 | if (!fb || !crtc || pcrtc != crtc) | 4684 | if (!fb || !crtc || pcrtc != crtc) |
4687 | continue; | 4685 | continue; |
@@ -4712,14 +4710,21 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, | |||
4712 | */ | 4710 | */ |
4713 | abo = gem_to_amdgpu_bo(fb->obj[0]); | 4711 | abo = gem_to_amdgpu_bo(fb->obj[0]); |
4714 | r = amdgpu_bo_reserve(abo, true); | 4712 | r = amdgpu_bo_reserve(abo, true); |
4715 | if (unlikely(r != 0)) { | 4713 | if (unlikely(r != 0)) |
4716 | DRM_ERROR("failed to reserve buffer before flip\n"); | 4714 | DRM_ERROR("failed to reserve buffer before flip\n"); |
4717 | WARN_ON(1); | ||
4718 | } | ||
4719 | 4715 | ||
4720 | /* Wait for all fences on this FB */ | 4716 | /* |
4721 | WARN_ON(reservation_object_wait_timeout_rcu(abo->tbo.resv, true, false, | 4717 | * Wait for all fences on this FB. Do limited wait to avoid |
4722 | MAX_SCHEDULE_TIMEOUT) < 0); | 4718 | * deadlock during GPU reset when this fence will not signal |
4719 | * but we hold reservation lock for the BO. | ||
4720 | */ | ||
4721 | r = reservation_object_wait_timeout_rcu(abo->tbo.resv, | ||
4722 | true, false, | ||
4723 | msecs_to_jiffies(5000)); | ||
4724 | if (unlikely(r == 0)) | ||
4725 | DRM_ERROR("Waiting for fences timed out."); | ||
4726 | |||
4727 | |||
4723 | 4728 | ||
4724 | amdgpu_bo_get_tiling_flags(abo, &tiling_flags); | 4729 | amdgpu_bo_get_tiling_flags(abo, &tiling_flags); |
4725 | 4730 | ||
@@ -4874,6 +4879,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, | |||
4874 | mutex_unlock(&dm->dc_lock); | 4879 | mutex_unlock(&dm->dc_lock); |
4875 | } | 4880 | } |
4876 | 4881 | ||
4882 | for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) | ||
4883 | if (plane->type == DRM_PLANE_TYPE_CURSOR) | ||
4884 | handle_cursor_update(plane, old_plane_state); | ||
4885 | |||
4877 | cleanup: | 4886 | cleanup: |
4878 | kfree(flip); | 4887 | kfree(flip); |
4879 | kfree(full); | 4888 | kfree(full); |
@@ -5799,14 +5808,13 @@ dm_determine_update_type_for_commit(struct dc *dc, | |||
5799 | old_dm_crtc_state = to_dm_crtc_state(old_crtc_state); | 5808 | old_dm_crtc_state = to_dm_crtc_state(old_crtc_state); |
5800 | num_plane = 0; | 5809 | num_plane = 0; |
5801 | 5810 | ||
5802 | if (!new_dm_crtc_state->stream) { | 5811 | if (new_dm_crtc_state->stream != old_dm_crtc_state->stream) { |
5803 | if (!new_dm_crtc_state->stream && old_dm_crtc_state->stream) { | 5812 | update_type = UPDATE_TYPE_FULL; |
5804 | update_type = UPDATE_TYPE_FULL; | 5813 | goto cleanup; |
5805 | goto cleanup; | 5814 | } |
5806 | } | ||
5807 | 5815 | ||
5816 | if (!new_dm_crtc_state->stream) | ||
5808 | continue; | 5817 | continue; |
5809 | } | ||
5810 | 5818 | ||
5811 | for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, j) { | 5819 | for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, j) { |
5812 | new_plane_crtc = new_plane_state->crtc; | 5820 | new_plane_crtc = new_plane_state->crtc; |
@@ -5817,6 +5825,11 @@ dm_determine_update_type_for_commit(struct dc *dc, | |||
5817 | if (plane->type == DRM_PLANE_TYPE_CURSOR) | 5825 | if (plane->type == DRM_PLANE_TYPE_CURSOR) |
5818 | continue; | 5826 | continue; |
5819 | 5827 | ||
5828 | if (new_dm_plane_state->dc_state != old_dm_plane_state->dc_state) { | ||
5829 | update_type = UPDATE_TYPE_FULL; | ||
5830 | goto cleanup; | ||
5831 | } | ||
5832 | |||
5820 | if (!state->allow_modeset) | 5833 | if (!state->allow_modeset) |
5821 | continue; | 5834 | continue; |
5822 | 5835 | ||
@@ -5955,6 +5968,42 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, | |||
5955 | goto fail; | 5968 | goto fail; |
5956 | } | 5969 | } |
5957 | 5970 | ||
5971 | /* | ||
5972 | * Add all primary and overlay planes on the CRTC to the state | ||
5973 | * whenever a plane is enabled to maintain correct z-ordering | ||
5974 | * and to enable fast surface updates. | ||
5975 | */ | ||
5976 | drm_for_each_crtc(crtc, dev) { | ||
5977 | bool modified = false; | ||
5978 | |||
5979 | for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { | ||
5980 | if (plane->type == DRM_PLANE_TYPE_CURSOR) | ||
5981 | continue; | ||
5982 | |||
5983 | if (new_plane_state->crtc == crtc || | ||
5984 | old_plane_state->crtc == crtc) { | ||
5985 | modified = true; | ||
5986 | break; | ||
5987 | } | ||
5988 | } | ||
5989 | |||
5990 | if (!modified) | ||
5991 | continue; | ||
5992 | |||
5993 | drm_for_each_plane_mask(plane, state->dev, crtc->state->plane_mask) { | ||
5994 | if (plane->type == DRM_PLANE_TYPE_CURSOR) | ||
5995 | continue; | ||
5996 | |||
5997 | new_plane_state = | ||
5998 | drm_atomic_get_plane_state(state, plane); | ||
5999 | |||
6000 | if (IS_ERR(new_plane_state)) { | ||
6001 | ret = PTR_ERR(new_plane_state); | ||
6002 | goto fail; | ||
6003 | } | ||
6004 | } | ||
6005 | } | ||
6006 | |||
5958 | /* Remove exiting planes if they are modified */ | 6007 | /* Remove exiting planes if they are modified */ |
5959 | for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) { | 6008 | for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) { |
5960 | ret = dm_update_plane_state(dc, state, plane, | 6009 | ret = dm_update_plane_state(dc, state, plane, |
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index a1c56f29cfeb..fd5266a58297 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | |||
@@ -265,6 +265,7 @@ static struct atom_display_object_path_v2 *get_bios_object( | |||
265 | && id.enum_id == obj_id.enum_id) | 265 | && id.enum_id == obj_id.enum_id) |
266 | return &bp->object_info_tbl.v1_4->display_path[i]; | 266 | return &bp->object_info_tbl.v1_4->display_path[i]; |
267 | } | 267 | } |
268 | /* fall through */ | ||
268 | case OBJECT_TYPE_CONNECTOR: | 269 | case OBJECT_TYPE_CONNECTOR: |
269 | case OBJECT_TYPE_GENERIC: | 270 | case OBJECT_TYPE_GENERIC: |
270 | /* Both Generic and Connector Object ID | 271 | /* Both Generic and Connector Object ID |
@@ -277,6 +278,7 @@ static struct atom_display_object_path_v2 *get_bios_object( | |||
277 | && id.enum_id == obj_id.enum_id) | 278 | && id.enum_id == obj_id.enum_id) |
278 | return &bp->object_info_tbl.v1_4->display_path[i]; | 279 | return &bp->object_info_tbl.v1_4->display_path[i]; |
279 | } | 280 | } |
281 | /* fall through */ | ||
280 | default: | 282 | default: |
281 | return NULL; | 283 | return NULL; |
282 | } | 284 | } |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 52f838442e21..c68fbd55db3c 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c | |||
@@ -1138,6 +1138,9 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c | |||
1138 | /* pplib is notified if disp_num changed */ | 1138 | /* pplib is notified if disp_num changed */ |
1139 | dc->hwss.optimize_bandwidth(dc, context); | 1139 | dc->hwss.optimize_bandwidth(dc, context); |
1140 | 1140 | ||
1141 | for (i = 0; i < context->stream_count; i++) | ||
1142 | context->streams[i]->mode_changed = false; | ||
1143 | |||
1141 | dc_release_state(dc->current_state); | 1144 | dc_release_state(dc->current_state); |
1142 | 1145 | ||
1143 | dc->current_state = context; | 1146 | dc->current_state = context; |
@@ -1623,13 +1626,13 @@ static void commit_planes_do_stream_update(struct dc *dc, | |||
1623 | stream_update->adjust->v_total_min, | 1626 | stream_update->adjust->v_total_min, |
1624 | stream_update->adjust->v_total_max); | 1627 | stream_update->adjust->v_total_max); |
1625 | 1628 | ||
1626 | if (stream_update->periodic_vsync_config && pipe_ctx->stream_res.tg->funcs->program_vline_interrupt) | 1629 | if (stream_update->periodic_interrupt0 && |
1627 | pipe_ctx->stream_res.tg->funcs->program_vline_interrupt( | 1630 | dc->hwss.setup_periodic_interrupt) |
1628 | pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, VLINE0, &stream->periodic_vsync_config); | 1631 | dc->hwss.setup_periodic_interrupt(pipe_ctx, VLINE0); |
1629 | 1632 | ||
1630 | if (stream_update->enhanced_sync_config && pipe_ctx->stream_res.tg->funcs->program_vline_interrupt) | 1633 | if (stream_update->periodic_interrupt1 && |
1631 | pipe_ctx->stream_res.tg->funcs->program_vline_interrupt( | 1634 | dc->hwss.setup_periodic_interrupt) |
1632 | pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, VLINE1, &stream->enhanced_sync_config); | 1635 | dc->hwss.setup_periodic_interrupt(pipe_ctx, VLINE1); |
1633 | 1636 | ||
1634 | if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) || | 1637 | if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) || |
1635 | stream_update->vrr_infopacket || | 1638 | stream_update->vrr_infopacket || |
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index a798694992b9..5657cb3a2ad3 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h | |||
@@ -51,9 +51,19 @@ struct freesync_context { | |||
51 | bool dummy; | 51 | bool dummy; |
52 | }; | 52 | }; |
53 | 53 | ||
54 | union vline_config { | 54 | enum vertical_interrupt_ref_point { |
55 | unsigned int line_number; | 55 | START_V_UPDATE = 0, |
56 | unsigned long long delta_in_ns; | 56 | START_V_SYNC, |
57 | INVALID_POINT | ||
58 | |||
59 | //For now, only v_update interrupt is used. | ||
60 | //START_V_BLANK, | ||
61 | //START_V_ACTIVE | ||
62 | }; | ||
63 | |||
64 | struct periodic_interrupt_config { | ||
65 | enum vertical_interrupt_ref_point ref_point; | ||
66 | int lines_offset; | ||
57 | }; | 67 | }; |
58 | 68 | ||
59 | 69 | ||
@@ -106,8 +116,8 @@ struct dc_stream_state { | |||
106 | /* DMCU info */ | 116 | /* DMCU info */ |
107 | unsigned int abm_level; | 117 | unsigned int abm_level; |
108 | 118 | ||
109 | union vline_config periodic_vsync_config; | 119 | struct periodic_interrupt_config periodic_interrupt0; |
110 | union vline_config enhanced_sync_config; | 120 | struct periodic_interrupt_config periodic_interrupt1; |
111 | 121 | ||
112 | /* from core_stream struct */ | 122 | /* from core_stream struct */ |
113 | struct dc_context *ctx; | 123 | struct dc_context *ctx; |
@@ -158,8 +168,8 @@ struct dc_stream_update { | |||
158 | struct dc_info_packet *hdr_static_metadata; | 168 | struct dc_info_packet *hdr_static_metadata; |
159 | unsigned int *abm_level; | 169 | unsigned int *abm_level; |
160 | 170 | ||
161 | union vline_config *periodic_vsync_config; | 171 | struct periodic_interrupt_config *periodic_interrupt0; |
162 | union vline_config *enhanced_sync_config; | 172 | struct periodic_interrupt_config *periodic_interrupt1; |
163 | 173 | ||
164 | struct dc_crtc_timing_adjust *adjust; | 174 | struct dc_crtc_timing_adjust *adjust; |
165 | struct dc_info_packet *vrr_infopacket; | 175 | struct dc_info_packet *vrr_infopacket; |
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c index 01e56f1a9f34..da96229db53a 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c | |||
@@ -53,6 +53,27 @@ | |||
53 | 53 | ||
54 | #define MCP_DISABLE_ABM_IMMEDIATELY 255 | 54 | #define MCP_DISABLE_ABM_IMMEDIATELY 255 |
55 | 55 | ||
56 | static bool dce_abm_set_pipe(struct abm *abm, uint32_t controller_id) | ||
57 | { | ||
58 | struct dce_abm *abm_dce = TO_DCE_ABM(abm); | ||
59 | uint32_t rampingBoundary = 0xFFFF; | ||
60 | |||
61 | REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, | ||
62 | 1, 80000); | ||
63 | |||
64 | /* set ramping boundary */ | ||
65 | REG_WRITE(MASTER_COMM_DATA_REG1, rampingBoundary); | ||
66 | |||
67 | /* setDMCUParam_Pipe */ | ||
68 | REG_UPDATE_2(MASTER_COMM_CMD_REG, | ||
69 | MASTER_COMM_CMD_REG_BYTE0, MCP_ABM_PIPE_SET, | ||
70 | MASTER_COMM_CMD_REG_BYTE1, controller_id); | ||
71 | |||
72 | /* notifyDMCUMsg */ | ||
73 | REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); | ||
74 | |||
75 | return true; | ||
76 | } | ||
56 | 77 | ||
57 | static unsigned int calculate_16_bit_backlight_from_pwm(struct dce_abm *abm_dce) | 78 | static unsigned int calculate_16_bit_backlight_from_pwm(struct dce_abm *abm_dce) |
58 | { | 79 | { |
@@ -175,7 +196,6 @@ static void dmcu_set_backlight_level( | |||
175 | uint32_t controller_id) | 196 | uint32_t controller_id) |
176 | { | 197 | { |
177 | unsigned int backlight_8_bit = 0; | 198 | unsigned int backlight_8_bit = 0; |
178 | uint32_t rampingBoundary = 0xFFFF; | ||
179 | uint32_t s2; | 199 | uint32_t s2; |
180 | 200 | ||
181 | if (backlight_pwm_u16_16 & 0x10000) | 201 | if (backlight_pwm_u16_16 & 0x10000) |
@@ -185,16 +205,7 @@ static void dmcu_set_backlight_level( | |||
185 | // Take MSB of fractional part since backlight is not max | 205 | // Take MSB of fractional part since backlight is not max |
186 | backlight_8_bit = (backlight_pwm_u16_16 >> 8) & 0xFF; | 206 | backlight_8_bit = (backlight_pwm_u16_16 >> 8) & 0xFF; |
187 | 207 | ||
188 | /* set ramping boundary */ | 208 | dce_abm_set_pipe(&abm_dce->base, controller_id); |
189 | REG_WRITE(MASTER_COMM_DATA_REG1, rampingBoundary); | ||
190 | |||
191 | /* setDMCUParam_Pipe */ | ||
192 | REG_UPDATE_2(MASTER_COMM_CMD_REG, | ||
193 | MASTER_COMM_CMD_REG_BYTE0, MCP_ABM_PIPE_SET, | ||
194 | MASTER_COMM_CMD_REG_BYTE1, controller_id); | ||
195 | |||
196 | /* notifyDMCUMsg */ | ||
197 | REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); | ||
198 | 209 | ||
199 | /* waitDMCUReadyForCmd */ | 210 | /* waitDMCUReadyForCmd */ |
200 | REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, | 211 | REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, |
@@ -309,16 +320,7 @@ static bool dce_abm_immediate_disable(struct abm *abm) | |||
309 | { | 320 | { |
310 | struct dce_abm *abm_dce = TO_DCE_ABM(abm); | 321 | struct dce_abm *abm_dce = TO_DCE_ABM(abm); |
311 | 322 | ||
312 | REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, | 323 | dce_abm_set_pipe(abm, MCP_DISABLE_ABM_IMMEDIATELY); |
313 | 1, 80000); | ||
314 | |||
315 | /* setDMCUParam_ABMLevel */ | ||
316 | REG_UPDATE_2(MASTER_COMM_CMD_REG, | ||
317 | MASTER_COMM_CMD_REG_BYTE0, MCP_ABM_PIPE_SET, | ||
318 | MASTER_COMM_CMD_REG_BYTE1, MCP_DISABLE_ABM_IMMEDIATELY); | ||
319 | |||
320 | /* notifyDMCUMsg */ | ||
321 | REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); | ||
322 | 324 | ||
323 | abm->stored_backlight_registers.BL_PWM_CNTL = | 325 | abm->stored_backlight_registers.BL_PWM_CNTL = |
324 | REG_READ(BL_PWM_CNTL); | 326 | REG_READ(BL_PWM_CNTL); |
@@ -419,6 +421,7 @@ static const struct abm_funcs dce_funcs = { | |||
419 | .abm_init = dce_abm_init, | 421 | .abm_init = dce_abm_init, |
420 | .set_abm_level = dce_abm_set_level, | 422 | .set_abm_level = dce_abm_set_level, |
421 | .init_backlight = dce_abm_init_backlight, | 423 | .init_backlight = dce_abm_init_backlight, |
424 | .set_pipe = dce_abm_set_pipe, | ||
422 | .set_backlight_level_pwm = dce_abm_set_backlight_level_pwm, | 425 | .set_backlight_level_pwm = dce_abm_set_backlight_level_pwm, |
423 | .get_current_backlight = dce_abm_get_current_backlight, | 426 | .get_current_backlight = dce_abm_get_current_backlight, |
424 | .get_target_backlight = dce_abm_get_target_backlight, | 427 | .get_target_backlight = dce_abm_get_target_backlight, |
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c index 85686d917636..a24a2bda8656 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c | |||
@@ -479,7 +479,7 @@ static void program_grph_pixel_format( | |||
479 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: | 479 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: |
480 | sign = 1; | 480 | sign = 1; |
481 | floating = 1; | 481 | floating = 1; |
482 | /* no break */ | 482 | /* fall through */ |
483 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: /* shouldn't this get float too? */ | 483 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: /* shouldn't this get float too? */ |
484 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: | 484 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: |
485 | grph_depth = 3; | 485 | grph_depth = 3; |
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index e1b285ea01ac..5e4db3712eef 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | |||
@@ -1300,6 +1300,10 @@ static enum dc_status apply_single_controller_ctx_to_hw( | |||
1300 | struct drr_params params = {0}; | 1300 | struct drr_params params = {0}; |
1301 | unsigned int event_triggers = 0; | 1301 | unsigned int event_triggers = 0; |
1302 | 1302 | ||
1303 | if (dc->hwss.disable_stream_gating) { | ||
1304 | dc->hwss.disable_stream_gating(dc, pipe_ctx); | ||
1305 | } | ||
1306 | |||
1303 | if (pipe_ctx->stream_res.audio != NULL) { | 1307 | if (pipe_ctx->stream_res.audio != NULL) { |
1304 | struct audio_output audio_output; | 1308 | struct audio_output audio_output; |
1305 | 1309 | ||
@@ -1329,10 +1333,8 @@ static enum dc_status apply_single_controller_ctx_to_hw( | |||
1329 | if (!pipe_ctx->stream->apply_seamless_boot_optimization) | 1333 | if (!pipe_ctx->stream->apply_seamless_boot_optimization) |
1330 | dc->hwss.enable_stream_timing(pipe_ctx, context, dc); | 1334 | dc->hwss.enable_stream_timing(pipe_ctx, context, dc); |
1331 | 1335 | ||
1332 | if (pipe_ctx->stream_res.tg->funcs->program_vupdate_interrupt) | 1336 | if (dc->hwss.setup_vupdate_interrupt) |
1333 | pipe_ctx->stream_res.tg->funcs->program_vupdate_interrupt( | 1337 | dc->hwss.setup_vupdate_interrupt(pipe_ctx); |
1334 | pipe_ctx->stream_res.tg, | ||
1335 | &stream->timing); | ||
1336 | 1338 | ||
1337 | params.vertical_total_min = stream->adjust.v_total_min; | 1339 | params.vertical_total_min = stream->adjust.v_total_min; |
1338 | params.vertical_total_max = stream->adjust.v_total_max; | 1340 | params.vertical_total_max = stream->adjust.v_total_max; |
@@ -1521,6 +1523,14 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) | |||
1521 | struct dc_link *edp_link = get_link_for_edp(dc); | 1523 | struct dc_link *edp_link = get_link_for_edp(dc); |
1522 | bool can_edp_fast_boot_optimize = false; | 1524 | bool can_edp_fast_boot_optimize = false; |
1523 | bool apply_edp_fast_boot_optimization = false; | 1525 | bool apply_edp_fast_boot_optimization = false; |
1526 | bool can_apply_seamless_boot = false; | ||
1527 | |||
1528 | for (i = 0; i < context->stream_count; i++) { | ||
1529 | if (context->streams[i]->apply_seamless_boot_optimization) { | ||
1530 | can_apply_seamless_boot = true; | ||
1531 | break; | ||
1532 | } | ||
1533 | } | ||
1524 | 1534 | ||
1525 | if (edp_link) { | 1535 | if (edp_link) { |
1526 | /* this seems to cause blank screens on DCE8 */ | 1536 | /* this seems to cause blank screens on DCE8 */ |
@@ -1549,7 +1559,7 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) | |||
1549 | } | 1559 | } |
1550 | } | 1560 | } |
1551 | 1561 | ||
1552 | if (!apply_edp_fast_boot_optimization) { | 1562 | if (!apply_edp_fast_boot_optimization && !can_apply_seamless_boot) { |
1553 | if (edp_link_to_turnoff) { | 1563 | if (edp_link_to_turnoff) { |
1554 | /*turn off backlight before DP_blank and encoder powered down*/ | 1564 | /*turn off backlight before DP_blank and encoder powered down*/ |
1555 | dc->hwss.edp_backlight_control(edp_link_to_turnoff, false); | 1565 | dc->hwss.edp_backlight_control(edp_link_to_turnoff, false); |
@@ -2676,6 +2686,8 @@ static const struct hw_sequencer_funcs dce110_funcs = { | |||
2676 | .set_static_screen_control = set_static_screen_control, | 2686 | .set_static_screen_control = set_static_screen_control, |
2677 | .reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap, | 2687 | .reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap, |
2678 | .enable_stream_timing = dce110_enable_stream_timing, | 2688 | .enable_stream_timing = dce110_enable_stream_timing, |
2689 | .disable_stream_gating = NULL, | ||
2690 | .enable_stream_gating = NULL, | ||
2679 | .setup_stereo = NULL, | 2691 | .setup_stereo = NULL, |
2680 | .set_avmute = dce110_set_avmute, | 2692 | .set_avmute = dce110_set_avmute, |
2681 | .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect, | 2693 | .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect, |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 117d9d8227f7..8ba895c4b445 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | |||
@@ -959,9 +959,25 @@ static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx) | |||
959 | static void dcn10_init_pipes(struct dc *dc, struct dc_state *context) | 959 | static void dcn10_init_pipes(struct dc *dc, struct dc_state *context) |
960 | { | 960 | { |
961 | int i; | 961 | int i; |
962 | bool can_apply_seamless_boot = false; | ||
963 | |||
964 | for (i = 0; i < context->stream_count; i++) { | ||
965 | if (context->streams[i]->apply_seamless_boot_optimization) { | ||
966 | can_apply_seamless_boot = true; | ||
967 | break; | ||
968 | } | ||
969 | } | ||
962 | 970 | ||
963 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | 971 | for (i = 0; i < dc->res_pool->pipe_count; i++) { |
964 | struct timing_generator *tg = dc->res_pool->timing_generators[i]; | 972 | struct timing_generator *tg = dc->res_pool->timing_generators[i]; |
973 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | ||
974 | |||
975 | /* There is assumption that pipe_ctx is not mapping irregularly | ||
976 | * to non-preferred front end. If pipe_ctx->stream is not NULL, | ||
977 | * we will use the pipe, so don't disable | ||
978 | */ | ||
979 | if (pipe_ctx->stream != NULL) | ||
980 | continue; | ||
965 | 981 | ||
966 | if (tg->funcs->is_tg_enabled(tg)) | 982 | if (tg->funcs->is_tg_enabled(tg)) |
967 | tg->funcs->lock(tg); | 983 | tg->funcs->lock(tg); |
@@ -975,7 +991,9 @@ static void dcn10_init_pipes(struct dc *dc, struct dc_state *context) | |||
975 | } | 991 | } |
976 | } | 992 | } |
977 | 993 | ||
978 | dc->res_pool->mpc->funcs->mpc_init(dc->res_pool->mpc); | 994 | /* Cannot reset the MPC mux if seamless boot */ |
995 | if (!can_apply_seamless_boot) | ||
996 | dc->res_pool->mpc->funcs->mpc_init(dc->res_pool->mpc); | ||
979 | 997 | ||
980 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | 998 | for (i = 0; i < dc->res_pool->pipe_count; i++) { |
981 | struct timing_generator *tg = dc->res_pool->timing_generators[i]; | 999 | struct timing_generator *tg = dc->res_pool->timing_generators[i]; |
@@ -983,6 +1001,16 @@ static void dcn10_init_pipes(struct dc *dc, struct dc_state *context) | |||
983 | struct dpp *dpp = dc->res_pool->dpps[i]; | 1001 | struct dpp *dpp = dc->res_pool->dpps[i]; |
984 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | 1002 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; |
985 | 1003 | ||
1004 | // W/A for issue with dc_post_update_surfaces_to_stream | ||
1005 | hubp->power_gated = true; | ||
1006 | |||
1007 | /* There is assumption that pipe_ctx is not mapping irregularly | ||
1008 | * to non-preferred front end. If pipe_ctx->stream is not NULL, | ||
1009 | * we will use the pipe, so don't disable | ||
1010 | */ | ||
1011 | if (pipe_ctx->stream != NULL) | ||
1012 | continue; | ||
1013 | |||
986 | dpp->funcs->dpp_reset(dpp); | 1014 | dpp->funcs->dpp_reset(dpp); |
987 | 1015 | ||
988 | pipe_ctx->stream_res.tg = tg; | 1016 | pipe_ctx->stream_res.tg = tg; |
@@ -1137,11 +1165,13 @@ static void reset_hw_ctx_wrap( | |||
1137 | struct clock_source *old_clk = pipe_ctx_old->clock_source; | 1165 | struct clock_source *old_clk = pipe_ctx_old->clock_source; |
1138 | 1166 | ||
1139 | reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state); | 1167 | reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state); |
1168 | if (dc->hwss.enable_stream_gating) { | ||
1169 | dc->hwss.enable_stream_gating(dc, pipe_ctx); | ||
1170 | } | ||
1140 | if (old_clk) | 1171 | if (old_clk) |
1141 | old_clk->funcs->cs_power_down(old_clk); | 1172 | old_clk->funcs->cs_power_down(old_clk); |
1142 | } | 1173 | } |
1143 | } | 1174 | } |
1144 | |||
1145 | } | 1175 | } |
1146 | 1176 | ||
1147 | static bool patch_address_for_sbs_tb_stereo( | 1177 | static bool patch_address_for_sbs_tb_stereo( |
@@ -2162,8 +2192,10 @@ static void dcn10_blank_pixel_data( | |||
2162 | if (!blank) { | 2192 | if (!blank) { |
2163 | if (stream_res->tg->funcs->set_blank) | 2193 | if (stream_res->tg->funcs->set_blank) |
2164 | stream_res->tg->funcs->set_blank(stream_res->tg, blank); | 2194 | stream_res->tg->funcs->set_blank(stream_res->tg, blank); |
2165 | if (stream_res->abm) | 2195 | if (stream_res->abm) { |
2196 | stream_res->abm->funcs->set_pipe(stream_res->abm, stream_res->tg->inst + 1); | ||
2166 | stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level); | 2197 | stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level); |
2198 | } | ||
2167 | } else if (blank) { | 2199 | } else if (blank) { |
2168 | if (stream_res->abm) | 2200 | if (stream_res->abm) |
2169 | stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm); | 2201 | stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm); |
@@ -2709,6 +2741,147 @@ static void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx) | |||
2709 | pipe_ctx->plane_res.dpp, &opt_attr); | 2741 | pipe_ctx->plane_res.dpp, &opt_attr); |
2710 | } | 2742 | } |
2711 | 2743 | ||
2744 | /** | ||
2745 | * apply_front_porch_workaround TODO FPGA still need? | ||
2746 | * | ||
2747 | * This is a workaround for a bug that has existed since R5xx and has not been | ||
2748 | * fixed keep Front porch at minimum 2 for Interlaced mode or 1 for progressive. | ||
2749 | */ | ||
2750 | static void apply_front_porch_workaround( | ||
2751 | struct dc_crtc_timing *timing) | ||
2752 | { | ||
2753 | if (timing->flags.INTERLACE == 1) { | ||
2754 | if (timing->v_front_porch < 2) | ||
2755 | timing->v_front_porch = 2; | ||
2756 | } else { | ||
2757 | if (timing->v_front_porch < 1) | ||
2758 | timing->v_front_porch = 1; | ||
2759 | } | ||
2760 | } | ||
2761 | |||
2762 | int get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx) | ||
2763 | { | ||
2764 | struct timing_generator *optc = pipe_ctx->stream_res.tg; | ||
2765 | const struct dc_crtc_timing *dc_crtc_timing = &pipe_ctx->stream->timing; | ||
2766 | struct dc_crtc_timing patched_crtc_timing; | ||
2767 | int vesa_sync_start; | ||
2768 | int asic_blank_end; | ||
2769 | int interlace_factor; | ||
2770 | int vertical_line_start; | ||
2771 | |||
2772 | patched_crtc_timing = *dc_crtc_timing; | ||
2773 | apply_front_porch_workaround(&patched_crtc_timing); | ||
2774 | |||
2775 | interlace_factor = patched_crtc_timing.flags.INTERLACE ? 2 : 1; | ||
2776 | |||
2777 | vesa_sync_start = patched_crtc_timing.v_addressable + | ||
2778 | patched_crtc_timing.v_border_bottom + | ||
2779 | patched_crtc_timing.v_front_porch; | ||
2780 | |||
2781 | asic_blank_end = (patched_crtc_timing.v_total - | ||
2782 | vesa_sync_start - | ||
2783 | patched_crtc_timing.v_border_top) | ||
2784 | * interlace_factor; | ||
2785 | |||
2786 | vertical_line_start = asic_blank_end - | ||
2787 | optc->dlg_otg_param.vstartup_start + 1; | ||
2788 | |||
2789 | return vertical_line_start; | ||
2790 | } | ||
2791 | |||
2792 | static void calc_vupdate_position( | ||
2793 | struct pipe_ctx *pipe_ctx, | ||
2794 | uint32_t *start_line, | ||
2795 | uint32_t *end_line) | ||
2796 | { | ||
2797 | const struct dc_crtc_timing *dc_crtc_timing = &pipe_ctx->stream->timing; | ||
2798 | int vline_int_offset_from_vupdate = | ||
2799 | pipe_ctx->stream->periodic_interrupt0.lines_offset; | ||
2800 | int vupdate_offset_from_vsync = get_vupdate_offset_from_vsync(pipe_ctx); | ||
2801 | int start_position; | ||
2802 | |||
2803 | if (vline_int_offset_from_vupdate > 0) | ||
2804 | vline_int_offset_from_vupdate--; | ||
2805 | else if (vline_int_offset_from_vupdate < 0) | ||
2806 | vline_int_offset_from_vupdate++; | ||
2807 | |||
2808 | start_position = vline_int_offset_from_vupdate + vupdate_offset_from_vsync; | ||
2809 | |||
2810 | if (start_position >= 0) | ||
2811 | *start_line = start_position; | ||
2812 | else | ||
2813 | *start_line = dc_crtc_timing->v_total + start_position - 1; | ||
2814 | |||
2815 | *end_line = *start_line + 2; | ||
2816 | |||
2817 | if (*end_line >= dc_crtc_timing->v_total) | ||
2818 | *end_line = 2; | ||
2819 | } | ||
2820 | |||
2821 | static void cal_vline_position( | ||
2822 | struct pipe_ctx *pipe_ctx, | ||
2823 | enum vline_select vline, | ||
2824 | uint32_t *start_line, | ||
2825 | uint32_t *end_line) | ||
2826 | { | ||
2827 | enum vertical_interrupt_ref_point ref_point = INVALID_POINT; | ||
2828 | |||
2829 | if (vline == VLINE0) | ||
2830 | ref_point = pipe_ctx->stream->periodic_interrupt0.ref_point; | ||
2831 | else if (vline == VLINE1) | ||
2832 | ref_point = pipe_ctx->stream->periodic_interrupt1.ref_point; | ||
2833 | |||
2834 | switch (ref_point) { | ||
2835 | case START_V_UPDATE: | ||
2836 | calc_vupdate_position( | ||
2837 | pipe_ctx, | ||
2838 | start_line, | ||
2839 | end_line); | ||
2840 | break; | ||
2841 | case START_V_SYNC: | ||
2842 | // Suppose to do nothing because vsync is 0; | ||
2843 | break; | ||
2844 | default: | ||
2845 | ASSERT(0); | ||
2846 | break; | ||
2847 | } | ||
2848 | } | ||
2849 | |||
2850 | static void dcn10_setup_periodic_interrupt( | ||
2851 | struct pipe_ctx *pipe_ctx, | ||
2852 | enum vline_select vline) | ||
2853 | { | ||
2854 | struct timing_generator *tg = pipe_ctx->stream_res.tg; | ||
2855 | |||
2856 | if (vline == VLINE0) { | ||
2857 | uint32_t start_line = 0; | ||
2858 | uint32_t end_line = 0; | ||
2859 | |||
2860 | cal_vline_position(pipe_ctx, vline, &start_line, &end_line); | ||
2861 | |||
2862 | tg->funcs->setup_vertical_interrupt0(tg, start_line, end_line); | ||
2863 | |||
2864 | } else if (vline == VLINE1) { | ||
2865 | pipe_ctx->stream_res.tg->funcs->setup_vertical_interrupt1( | ||
2866 | tg, | ||
2867 | pipe_ctx->stream->periodic_interrupt1.lines_offset); | ||
2868 | } | ||
2869 | } | ||
2870 | |||
2871 | static void dcn10_setup_vupdate_interrupt(struct pipe_ctx *pipe_ctx) | ||
2872 | { | ||
2873 | struct timing_generator *tg = pipe_ctx->stream_res.tg; | ||
2874 | int start_line = get_vupdate_offset_from_vsync(pipe_ctx); | ||
2875 | |||
2876 | if (start_line < 0) { | ||
2877 | ASSERT(0); | ||
2878 | start_line = 0; | ||
2879 | } | ||
2880 | |||
2881 | if (tg->funcs->setup_vertical_interrupt2) | ||
2882 | tg->funcs->setup_vertical_interrupt2(tg, start_line); | ||
2883 | } | ||
2884 | |||
2712 | static const struct hw_sequencer_funcs dcn10_funcs = { | 2885 | static const struct hw_sequencer_funcs dcn10_funcs = { |
2713 | .program_gamut_remap = program_gamut_remap, | 2886 | .program_gamut_remap = program_gamut_remap, |
2714 | .init_hw = dcn10_init_hw, | 2887 | .init_hw = dcn10_init_hw, |
@@ -2756,7 +2929,11 @@ static const struct hw_sequencer_funcs dcn10_funcs = { | |||
2756 | .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, | 2929 | .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, |
2757 | .set_cursor_position = dcn10_set_cursor_position, | 2930 | .set_cursor_position = dcn10_set_cursor_position, |
2758 | .set_cursor_attribute = dcn10_set_cursor_attribute, | 2931 | .set_cursor_attribute = dcn10_set_cursor_attribute, |
2759 | .set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level | 2932 | .set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level, |
2933 | .disable_stream_gating = NULL, | ||
2934 | .enable_stream_gating = NULL, | ||
2935 | .setup_periodic_interrupt = dcn10_setup_periodic_interrupt, | ||
2936 | .setup_vupdate_interrupt = dcn10_setup_vupdate_interrupt | ||
2760 | }; | 2937 | }; |
2761 | 2938 | ||
2762 | 2939 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h index f8eea10e4c64..6d66084df55f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h | |||
@@ -81,4 +81,6 @@ struct pipe_ctx *find_top_pipe_for_stream( | |||
81 | struct dc_state *context, | 81 | struct dc_state *context, |
82 | const struct dc_stream_state *stream); | 82 | const struct dc_stream_state *stream); |
83 | 83 | ||
84 | int get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx); | ||
85 | |||
84 | #endif /* __DC_HWSS_DCN10_H__ */ | 86 | #endif /* __DC_HWSS_DCN10_H__ */ |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c index 2f78a84f0dcb..0345d51e9d6f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c | |||
@@ -92,134 +92,36 @@ static void optc1_disable_stereo(struct timing_generator *optc) | |||
92 | OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0); | 92 | OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0); |
93 | } | 93 | } |
94 | 94 | ||
95 | static uint32_t get_start_vline(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing) | 95 | void optc1_setup_vertical_interrupt0( |
96 | { | ||
97 | struct dc_crtc_timing patched_crtc_timing; | ||
98 | int vesa_sync_start; | ||
99 | int asic_blank_end; | ||
100 | int interlace_factor; | ||
101 | int vertical_line_start; | ||
102 | |||
103 | patched_crtc_timing = *dc_crtc_timing; | ||
104 | optc1_apply_front_porch_workaround(optc, &patched_crtc_timing); | ||
105 | |||
106 | vesa_sync_start = patched_crtc_timing.h_addressable + | ||
107 | patched_crtc_timing.h_border_right + | ||
108 | patched_crtc_timing.h_front_porch; | ||
109 | |||
110 | asic_blank_end = patched_crtc_timing.h_total - | ||
111 | vesa_sync_start - | ||
112 | patched_crtc_timing.h_border_left; | ||
113 | |||
114 | interlace_factor = patched_crtc_timing.flags.INTERLACE ? 2 : 1; | ||
115 | |||
116 | vesa_sync_start = patched_crtc_timing.v_addressable + | ||
117 | patched_crtc_timing.v_border_bottom + | ||
118 | patched_crtc_timing.v_front_porch; | ||
119 | |||
120 | asic_blank_end = (patched_crtc_timing.v_total - | ||
121 | vesa_sync_start - | ||
122 | patched_crtc_timing.v_border_top) | ||
123 | * interlace_factor; | ||
124 | |||
125 | vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1; | ||
126 | if (vertical_line_start < 0) { | ||
127 | ASSERT(0); | ||
128 | vertical_line_start = 0; | ||
129 | } | ||
130 | |||
131 | return vertical_line_start; | ||
132 | } | ||
133 | |||
134 | static void calc_vline_position( | ||
135 | struct timing_generator *optc, | 96 | struct timing_generator *optc, |
136 | const struct dc_crtc_timing *dc_crtc_timing, | 97 | uint32_t start_line, |
137 | unsigned long long vsync_delta, | 98 | uint32_t end_line) |
138 | uint32_t *start_line, | ||
139 | uint32_t *end_line) | ||
140 | { | 99 | { |
141 | unsigned long long req_delta_tens_of_usec = div64_u64((vsync_delta + 9999), 10000); | 100 | struct optc *optc1 = DCN10TG_FROM_TG(optc); |
142 | unsigned long long pix_clk_hundreds_khz = div64_u64((dc_crtc_timing->pix_clk_100hz + 999), 1000); | ||
143 | uint32_t req_delta_lines = (uint32_t) div64_u64( | ||
144 | (req_delta_tens_of_usec * pix_clk_hundreds_khz + dc_crtc_timing->h_total - 1), | ||
145 | dc_crtc_timing->h_total); | ||
146 | |||
147 | uint32_t vsync_line = get_start_vline(optc, dc_crtc_timing); | ||
148 | |||
149 | if (req_delta_lines != 0) | ||
150 | req_delta_lines--; | ||
151 | |||
152 | if (req_delta_lines > vsync_line) | ||
153 | *start_line = dc_crtc_timing->v_total - (req_delta_lines - vsync_line) - 1; | ||
154 | else | ||
155 | *start_line = vsync_line - req_delta_lines; | ||
156 | |||
157 | *end_line = *start_line + 2; | ||
158 | 101 | ||
159 | if (*end_line >= dc_crtc_timing->v_total) | 102 | REG_SET_2(OTG_VERTICAL_INTERRUPT0_POSITION, 0, |
160 | *end_line = 2; | 103 | OTG_VERTICAL_INTERRUPT0_LINE_START, start_line, |
104 | OTG_VERTICAL_INTERRUPT0_LINE_END, end_line); | ||
161 | } | 105 | } |
162 | 106 | ||
163 | void optc1_program_vline_interrupt( | 107 | void optc1_setup_vertical_interrupt1( |
164 | struct timing_generator *optc, | 108 | struct timing_generator *optc, |
165 | const struct dc_crtc_timing *dc_crtc_timing, | 109 | uint32_t start_line) |
166 | enum vline_select vline, | ||
167 | const union vline_config *vline_config) | ||
168 | { | 110 | { |
169 | struct optc *optc1 = DCN10TG_FROM_TG(optc); | 111 | struct optc *optc1 = DCN10TG_FROM_TG(optc); |
170 | uint32_t start_line = 0; | 112 | |
171 | uint32_t end_line = 0; | 113 | REG_SET(OTG_VERTICAL_INTERRUPT1_POSITION, 0, |
172 | 114 | OTG_VERTICAL_INTERRUPT1_LINE_START, start_line); | |
173 | switch (vline) { | ||
174 | case VLINE0: | ||
175 | calc_vline_position(optc, dc_crtc_timing, vline_config->delta_in_ns, &start_line, &end_line); | ||
176 | REG_SET_2(OTG_VERTICAL_INTERRUPT0_POSITION, 0, | ||
177 | OTG_VERTICAL_INTERRUPT0_LINE_START, start_line, | ||
178 | OTG_VERTICAL_INTERRUPT0_LINE_END, end_line); | ||
179 | break; | ||
180 | case VLINE1: | ||
181 | REG_SET(OTG_VERTICAL_INTERRUPT1_POSITION, 0, | ||
182 | OTG_VERTICAL_INTERRUPT1_LINE_START, vline_config->line_number); | ||
183 | break; | ||
184 | default: | ||
185 | break; | ||
186 | } | ||
187 | } | 115 | } |
188 | 116 | ||
189 | void optc1_program_vupdate_interrupt( | 117 | void optc1_setup_vertical_interrupt2( |
190 | struct timing_generator *optc, | 118 | struct timing_generator *optc, |
191 | const struct dc_crtc_timing *dc_crtc_timing) | 119 | uint32_t start_line) |
192 | { | 120 | { |
193 | struct optc *optc1 = DCN10TG_FROM_TG(optc); | 121 | struct optc *optc1 = DCN10TG_FROM_TG(optc); |
194 | int32_t vertical_line_start; | ||
195 | uint32_t asic_blank_end; | ||
196 | uint32_t vesa_sync_start; | ||
197 | struct dc_crtc_timing patched_crtc_timing; | ||
198 | |||
199 | patched_crtc_timing = *dc_crtc_timing; | ||
200 | optc1_apply_front_porch_workaround(optc, &patched_crtc_timing); | ||
201 | |||
202 | /* asic_h_blank_end = HsyncWidth + HbackPorch = | ||
203 | * vesa. usHorizontalTotal - vesa. usHorizontalSyncStart - | ||
204 | * vesa.h_left_border | ||
205 | */ | ||
206 | vesa_sync_start = patched_crtc_timing.h_addressable + | ||
207 | patched_crtc_timing.h_border_right + | ||
208 | patched_crtc_timing.h_front_porch; | ||
209 | |||
210 | asic_blank_end = patched_crtc_timing.h_total - | ||
211 | vesa_sync_start - | ||
212 | patched_crtc_timing.h_border_left; | ||
213 | |||
214 | /* Use OTG_VERTICAL_INTERRUPT2 replace VUPDATE interrupt, | ||
215 | * program the reg for interrupt postition. | ||
216 | */ | ||
217 | vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1; | ||
218 | if (vertical_line_start < 0) | ||
219 | vertical_line_start = 0; | ||
220 | 122 | ||
221 | REG_SET(OTG_VERTICAL_INTERRUPT2_POSITION, 0, | 123 | REG_SET(OTG_VERTICAL_INTERRUPT2_POSITION, 0, |
222 | OTG_VERTICAL_INTERRUPT2_LINE_START, vertical_line_start); | 124 | OTG_VERTICAL_INTERRUPT2_LINE_START, start_line); |
223 | } | 125 | } |
224 | 126 | ||
225 | /** | 127 | /** |
@@ -1480,8 +1382,9 @@ bool optc1_get_crc(struct timing_generator *optc, | |||
1480 | static const struct timing_generator_funcs dcn10_tg_funcs = { | 1382 | static const struct timing_generator_funcs dcn10_tg_funcs = { |
1481 | .validate_timing = optc1_validate_timing, | 1383 | .validate_timing = optc1_validate_timing, |
1482 | .program_timing = optc1_program_timing, | 1384 | .program_timing = optc1_program_timing, |
1483 | .program_vline_interrupt = optc1_program_vline_interrupt, | 1385 | .setup_vertical_interrupt0 = optc1_setup_vertical_interrupt0, |
1484 | .program_vupdate_interrupt = optc1_program_vupdate_interrupt, | 1386 | .setup_vertical_interrupt1 = optc1_setup_vertical_interrupt1, |
1387 | .setup_vertical_interrupt2 = optc1_setup_vertical_interrupt2, | ||
1485 | .program_global_sync = optc1_program_global_sync, | 1388 | .program_global_sync = optc1_program_global_sync, |
1486 | .enable_crtc = optc1_enable_crtc, | 1389 | .enable_crtc = optc1_enable_crtc, |
1487 | .disable_crtc = optc1_disable_crtc, | 1390 | .disable_crtc = optc1_disable_crtc, |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h index 24452f11c598..4eb9a898c237 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h | |||
@@ -483,11 +483,16 @@ void optc1_program_timing( | |||
483 | const struct dc_crtc_timing *dc_crtc_timing, | 483 | const struct dc_crtc_timing *dc_crtc_timing, |
484 | bool use_vbios); | 484 | bool use_vbios); |
485 | 485 | ||
486 | void optc1_program_vline_interrupt( | 486 | void optc1_setup_vertical_interrupt0( |
487 | struct timing_generator *optc, | 487 | struct timing_generator *optc, |
488 | const struct dc_crtc_timing *dc_crtc_timing, | 488 | uint32_t start_line, |
489 | enum vline_select vline, | 489 | uint32_t end_line); |
490 | const union vline_config *vline_config); | 490 | void optc1_setup_vertical_interrupt1( |
491 | struct timing_generator *optc, | ||
492 | uint32_t start_line); | ||
493 | void optc1_setup_vertical_interrupt2( | ||
494 | struct timing_generator *optc, | ||
495 | uint32_t start_line); | ||
491 | 496 | ||
492 | void optc1_program_global_sync( | 497 | void optc1_program_global_sync( |
493 | struct timing_generator *optc); | 498 | struct timing_generator *optc); |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h index abc961c0906e..86dc39a02408 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h | |||
@@ -46,6 +46,7 @@ struct abm_funcs { | |||
46 | void (*abm_init)(struct abm *abm); | 46 | void (*abm_init)(struct abm *abm); |
47 | bool (*set_abm_level)(struct abm *abm, unsigned int abm_level); | 47 | bool (*set_abm_level)(struct abm *abm, unsigned int abm_level); |
48 | bool (*set_abm_immediate_disable)(struct abm *abm); | 48 | bool (*set_abm_immediate_disable)(struct abm *abm); |
49 | bool (*set_pipe)(struct abm *abm, unsigned int controller_id); | ||
49 | bool (*init_backlight)(struct abm *abm); | 50 | bool (*init_backlight)(struct abm *abm); |
50 | 51 | ||
51 | /* backlight_pwm_u16_16 is unsigned 32 bit, | 52 | /* backlight_pwm_u16_16 is unsigned 32 bit, |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h index 03ae941895f3..c25f7df7b5e3 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h | |||
@@ -134,14 +134,6 @@ struct dc_crtc_timing; | |||
134 | 134 | ||
135 | struct drr_params; | 135 | struct drr_params; |
136 | 136 | ||
137 | union vline_config; | ||
138 | |||
139 | |||
140 | enum vline_select { | ||
141 | VLINE0, | ||
142 | VLINE1, | ||
143 | VLINE2 | ||
144 | }; | ||
145 | 137 | ||
146 | struct timing_generator_funcs { | 138 | struct timing_generator_funcs { |
147 | bool (*validate_timing)(struct timing_generator *tg, | 139 | bool (*validate_timing)(struct timing_generator *tg, |
@@ -149,14 +141,17 @@ struct timing_generator_funcs { | |||
149 | void (*program_timing)(struct timing_generator *tg, | 141 | void (*program_timing)(struct timing_generator *tg, |
150 | const struct dc_crtc_timing *timing, | 142 | const struct dc_crtc_timing *timing, |
151 | bool use_vbios); | 143 | bool use_vbios); |
152 | void (*program_vline_interrupt)( | 144 | void (*setup_vertical_interrupt0)( |
145 | struct timing_generator *optc, | ||
146 | uint32_t start_line, | ||
147 | uint32_t end_line); | ||
148 | void (*setup_vertical_interrupt1)( | ||
149 | struct timing_generator *optc, | ||
150 | uint32_t start_line); | ||
151 | void (*setup_vertical_interrupt2)( | ||
153 | struct timing_generator *optc, | 152 | struct timing_generator *optc, |
154 | const struct dc_crtc_timing *dc_crtc_timing, | 153 | uint32_t start_line); |
155 | enum vline_select vline, | ||
156 | const union vline_config *vline_config); | ||
157 | 154 | ||
158 | void (*program_vupdate_interrupt)(struct timing_generator *optc, | ||
159 | const struct dc_crtc_timing *dc_crtc_timing); | ||
160 | bool (*enable_crtc)(struct timing_generator *tg); | 155 | bool (*enable_crtc)(struct timing_generator *tg); |
161 | bool (*disable_crtc)(struct timing_generator *tg); | 156 | bool (*disable_crtc)(struct timing_generator *tg); |
162 | bool (*is_counter_moving)(struct timing_generator *tg); | 157 | bool (*is_counter_moving)(struct timing_generator *tg); |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index 341b4810288c..7676f25216b1 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h | |||
@@ -38,6 +38,11 @@ enum pipe_gating_control { | |||
38 | PIPE_GATING_CONTROL_INIT | 38 | PIPE_GATING_CONTROL_INIT |
39 | }; | 39 | }; |
40 | 40 | ||
41 | enum vline_select { | ||
42 | VLINE0, | ||
43 | VLINE1 | ||
44 | }; | ||
45 | |||
41 | struct dce_hwseq_wa { | 46 | struct dce_hwseq_wa { |
42 | bool blnd_crtc_trigger; | 47 | bool blnd_crtc_trigger; |
43 | bool DEGVIDCN10_253; | 48 | bool DEGVIDCN10_253; |
@@ -68,6 +73,10 @@ struct stream_resource; | |||
68 | 73 | ||
69 | struct hw_sequencer_funcs { | 74 | struct hw_sequencer_funcs { |
70 | 75 | ||
76 | void (*disable_stream_gating)(struct dc *dc, struct pipe_ctx *pipe_ctx); | ||
77 | |||
78 | void (*enable_stream_gating)(struct dc *dc, struct pipe_ctx *pipe_ctx); | ||
79 | |||
71 | void (*init_hw)(struct dc *dc); | 80 | void (*init_hw)(struct dc *dc); |
72 | 81 | ||
73 | void (*init_pipes)(struct dc *dc, struct dc_state *context); | 82 | void (*init_pipes)(struct dc *dc, struct dc_state *context); |
@@ -220,6 +229,9 @@ struct hw_sequencer_funcs { | |||
220 | void (*set_cursor_attribute)(struct pipe_ctx *pipe); | 229 | void (*set_cursor_attribute)(struct pipe_ctx *pipe); |
221 | void (*set_cursor_sdr_white_level)(struct pipe_ctx *pipe); | 230 | void (*set_cursor_sdr_white_level)(struct pipe_ctx *pipe); |
222 | 231 | ||
232 | void (*setup_periodic_interrupt)(struct pipe_ctx *pipe_ctx, enum vline_select vline); | ||
233 | void (*setup_vupdate_interrupt)(struct pipe_ctx *pipe_ctx); | ||
234 | |||
223 | }; | 235 | }; |
224 | 236 | ||
225 | void color_space_to_black_color( | 237 | void color_space_to_black_color( |
diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h index 4f501ddcfb8d..34d6fdcb32e2 100644 --- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h +++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h | |||
@@ -131,6 +131,7 @@ | |||
131 | #define INTERNAL_REV_RAVEN_A0 0x00 /* First spin of Raven */ | 131 | #define INTERNAL_REV_RAVEN_A0 0x00 /* First spin of Raven */ |
132 | #define RAVEN_A0 0x01 | 132 | #define RAVEN_A0 0x01 |
133 | #define RAVEN_B0 0x21 | 133 | #define RAVEN_B0 0x21 |
134 | #define PICASSO_A0 0x41 | ||
134 | #if defined(CONFIG_DRM_AMD_DC_DCN1_01) | 135 | #if defined(CONFIG_DRM_AMD_DC_DCN1_01) |
135 | /* DCN1_01 */ | 136 | /* DCN1_01 */ |
136 | #define RAVEN2_A0 0x81 | 137 | #define RAVEN2_A0 0x81 |
@@ -165,4 +166,6 @@ | |||
165 | 166 | ||
166 | #define FAMILY_UNKNOWN 0xFF | 167 | #define FAMILY_UNKNOWN 0xFF |
167 | 168 | ||
169 | |||
170 | |||
168 | #endif /* __DAL_ASIC_ID_H__ */ | 171 | #endif /* __DAL_ASIC_ID_H__ */ |
diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c index 3ba87b076287..038b88221c5f 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c | |||
@@ -165,18 +165,11 @@ struct iram_table_v_2_2 { | |||
165 | }; | 165 | }; |
166 | #pragma pack(pop) | 166 | #pragma pack(pop) |
167 | 167 | ||
168 | static uint16_t backlight_8_to_16(unsigned int backlight_8bit) | ||
169 | { | ||
170 | return (uint16_t)(backlight_8bit * 0x101); | ||
171 | } | ||
172 | |||
173 | static void fill_backlight_transform_table(struct dmcu_iram_parameters params, | 168 | static void fill_backlight_transform_table(struct dmcu_iram_parameters params, |
174 | struct iram_table_v_2 *table) | 169 | struct iram_table_v_2 *table) |
175 | { | 170 | { |
176 | unsigned int i; | 171 | unsigned int i; |
177 | unsigned int num_entries = NUM_BL_CURVE_SEGS; | 172 | unsigned int num_entries = NUM_BL_CURVE_SEGS; |
178 | unsigned int query_input_8bit; | ||
179 | unsigned int query_output_8bit; | ||
180 | unsigned int lut_index; | 173 | unsigned int lut_index; |
181 | 174 | ||
182 | table->backlight_thresholds[0] = 0; | 175 | table->backlight_thresholds[0] = 0; |
@@ -194,16 +187,13 @@ static void fill_backlight_transform_table(struct dmcu_iram_parameters params, | |||
194 | * format U4.10. | 187 | * format U4.10. |
195 | */ | 188 | */ |
196 | for (i = 1; i+1 < num_entries; i++) { | 189 | for (i = 1; i+1 < num_entries; i++) { |
197 | query_input_8bit = DIV_ROUNDUP((i * 256), num_entries); | ||
198 | |||
199 | lut_index = (params.backlight_lut_array_size - 1) * i / (num_entries - 1); | 190 | lut_index = (params.backlight_lut_array_size - 1) * i / (num_entries - 1); |
200 | ASSERT(lut_index < params.backlight_lut_array_size); | 191 | ASSERT(lut_index < params.backlight_lut_array_size); |
201 | query_output_8bit = params.backlight_lut_array[lut_index] >> 8; | ||
202 | 192 | ||
203 | table->backlight_thresholds[i] = | 193 | table->backlight_thresholds[i] = |
204 | backlight_8_to_16(query_input_8bit); | 194 | cpu_to_be16(DIV_ROUNDUP((i * 65536), num_entries)); |
205 | table->backlight_offsets[i] = | 195 | table->backlight_offsets[i] = |
206 | backlight_8_to_16(query_output_8bit); | 196 | cpu_to_be16(params.backlight_lut_array[lut_index]); |
207 | } | 197 | } |
208 | } | 198 | } |
209 | 199 | ||
@@ -212,8 +202,6 @@ static void fill_backlight_transform_table_v_2_2(struct dmcu_iram_parameters par | |||
212 | { | 202 | { |
213 | unsigned int i; | 203 | unsigned int i; |
214 | unsigned int num_entries = NUM_BL_CURVE_SEGS; | 204 | unsigned int num_entries = NUM_BL_CURVE_SEGS; |
215 | unsigned int query_input_8bit; | ||
216 | unsigned int query_output_8bit; | ||
217 | unsigned int lut_index; | 205 | unsigned int lut_index; |
218 | 206 | ||
219 | table->backlight_thresholds[0] = 0; | 207 | table->backlight_thresholds[0] = 0; |
@@ -231,16 +219,13 @@ static void fill_backlight_transform_table_v_2_2(struct dmcu_iram_parameters par | |||
231 | * format U4.10. | 219 | * format U4.10. |
232 | */ | 220 | */ |
233 | for (i = 1; i+1 < num_entries; i++) { | 221 | for (i = 1; i+1 < num_entries; i++) { |
234 | query_input_8bit = DIV_ROUNDUP((i * 256), num_entries); | ||
235 | |||
236 | lut_index = (params.backlight_lut_array_size - 1) * i / (num_entries - 1); | 222 | lut_index = (params.backlight_lut_array_size - 1) * i / (num_entries - 1); |
237 | ASSERT(lut_index < params.backlight_lut_array_size); | 223 | ASSERT(lut_index < params.backlight_lut_array_size); |
238 | query_output_8bit = params.backlight_lut_array[lut_index] >> 8; | ||
239 | 224 | ||
240 | table->backlight_thresholds[i] = | 225 | table->backlight_thresholds[i] = |
241 | backlight_8_to_16(query_input_8bit); | 226 | cpu_to_be16(DIV_ROUNDUP((i * 65536), num_entries)); |
242 | table->backlight_offsets[i] = | 227 | table->backlight_offsets[i] = |
243 | backlight_8_to_16(query_output_8bit); | 228 | cpu_to_be16(params.backlight_lut_array[lut_index]); |
244 | } | 229 | } |
245 | } | 230 | } |
246 | 231 | ||
diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h index 83d960110d23..5f3c10ebff08 100644 --- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h | |||
@@ -137,20 +137,17 @@ struct kgd2kfd_shared_resources { | |||
137 | /* Bit n == 1 means Queue n is available for KFD */ | 137 | /* Bit n == 1 means Queue n is available for KFD */ |
138 | DECLARE_BITMAP(queue_bitmap, KGD_MAX_QUEUES); | 138 | DECLARE_BITMAP(queue_bitmap, KGD_MAX_QUEUES); |
139 | 139 | ||
140 | /* Doorbell assignments (SOC15 and later chips only). Only | 140 | /* SDMA doorbell assignments (SOC15 and later chips only). Only |
141 | * specific doorbells are routed to each SDMA engine. Others | 141 | * specific doorbells are routed to each SDMA engine. Others |
142 | * are routed to IH and VCN. They are not usable by the CP. | 142 | * are routed to IH and VCN. They are not usable by the CP. |
143 | * | ||
144 | * Any doorbell number D that satisfies the following condition | ||
145 | * is reserved: (D & reserved_doorbell_mask) == reserved_doorbell_val | ||
146 | * | ||
147 | * KFD currently uses 1024 (= 0x3ff) doorbells per process. If | ||
148 | * doorbells 0x0e0-0x0ff and 0x2e0-0x2ff are reserved, that means | ||
149 | * mask would be set to 0x1e0 and val set to 0x0e0. | ||
150 | */ | 143 | */ |
151 | unsigned int sdma_doorbell[2][8]; | 144 | uint32_t *sdma_doorbell_idx; |
152 | unsigned int reserved_doorbell_mask; | 145 | |
153 | unsigned int reserved_doorbell_val; | 146 | /* From SOC15 onward, the doorbell index range not usable for CP |
147 | * queues. | ||
148 | */ | ||
149 | uint32_t non_cp_doorbells_start; | ||
150 | uint32_t non_cp_doorbells_end; | ||
154 | 151 | ||
155 | /* Base address of doorbell aperture. */ | 152 | /* Base address of doorbell aperture. */ |
156 | phys_addr_t doorbell_physical_address; | 153 | phys_addr_t doorbell_physical_address; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c index 5273de3c5b98..0ad8fe4a6277 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c | |||
@@ -139,12 +139,10 @@ static int smu10_construct_max_power_limits_table(struct pp_hwmgr *hwmgr, | |||
139 | static int smu10_init_dynamic_state_adjustment_rule_settings( | 139 | static int smu10_init_dynamic_state_adjustment_rule_settings( |
140 | struct pp_hwmgr *hwmgr) | 140 | struct pp_hwmgr *hwmgr) |
141 | { | 141 | { |
142 | uint32_t table_size = | 142 | struct phm_clock_voltage_dependency_table *table_clk_vlt; |
143 | sizeof(struct phm_clock_voltage_dependency_table) + | ||
144 | (7 * sizeof(struct phm_clock_voltage_dependency_record)); | ||
145 | 143 | ||
146 | struct phm_clock_voltage_dependency_table *table_clk_vlt = | 144 | table_clk_vlt = kzalloc(struct_size(table_clk_vlt, entries, 7), |
147 | kzalloc(table_size, GFP_KERNEL); | 145 | GFP_KERNEL); |
148 | 146 | ||
149 | if (NULL == table_clk_vlt) { | 147 | if (NULL == table_clk_vlt) { |
150 | pr_err("Can not allocate memory!\n"); | 148 | pr_err("Can not allocate memory!\n"); |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index c8f5c00dd1e7..48187acac59e 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | |||
@@ -3681,10 +3681,12 @@ static int smu7_request_link_speed_change_before_state_change( | |||
3681 | data->force_pcie_gen = PP_PCIEGen2; | 3681 | data->force_pcie_gen = PP_PCIEGen2; |
3682 | if (current_link_speed == PP_PCIEGen2) | 3682 | if (current_link_speed == PP_PCIEGen2) |
3683 | break; | 3683 | break; |
3684 | /* fall through */ | ||
3684 | case PP_PCIEGen2: | 3685 | case PP_PCIEGen2: |
3685 | if (0 == amdgpu_acpi_pcie_performance_request(hwmgr->adev, PCIE_PERF_REQ_GEN2, false)) | 3686 | if (0 == amdgpu_acpi_pcie_performance_request(hwmgr->adev, PCIE_PERF_REQ_GEN2, false)) |
3686 | break; | 3687 | break; |
3687 | #endif | 3688 | #endif |
3689 | /* fall through */ | ||
3688 | default: | 3690 | default: |
3689 | data->force_pcie_gen = smu7_get_current_pcie_speed(hwmgr); | 3691 | data->force_pcie_gen = smu7_get_current_pcie_speed(hwmgr); |
3690 | break; | 3692 | break; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c index d138ddae563d..58f5589aaf12 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c | |||
@@ -1211,7 +1211,7 @@ int smu7_power_control_set_level(struct pp_hwmgr *hwmgr) | |||
1211 | hwmgr->platform_descriptor.TDPAdjustment : | 1211 | hwmgr->platform_descriptor.TDPAdjustment : |
1212 | (-1 * hwmgr->platform_descriptor.TDPAdjustment); | 1212 | (-1 * hwmgr->platform_descriptor.TDPAdjustment); |
1213 | 1213 | ||
1214 | if (hwmgr->chip_id > CHIP_TONGA) | 1214 | if (hwmgr->chip_id > CHIP_TONGA) |
1215 | target_tdp = ((100 + adjust_percent) * (int)(cac_table->usTDP * 256)) / 100; | 1215 | target_tdp = ((100 + adjust_percent) * (int)(cac_table->usTDP * 256)) / 100; |
1216 | else | 1216 | else |
1217 | target_tdp = ((100 + adjust_percent) * (int)(cac_table->usConfigurableTDP * 256)) / 100; | 1217 | target_tdp = ((100 + adjust_percent) * (int)(cac_table->usConfigurableTDP * 256)) / 100; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c index 553a203ac47c..019d6a206492 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c | |||
@@ -272,12 +272,10 @@ static int smu8_init_dynamic_state_adjustment_rule_settings( | |||
272 | struct pp_hwmgr *hwmgr, | 272 | struct pp_hwmgr *hwmgr, |
273 | ATOM_CLK_VOLT_CAPABILITY *disp_voltage_table) | 273 | ATOM_CLK_VOLT_CAPABILITY *disp_voltage_table) |
274 | { | 274 | { |
275 | uint32_t table_size = | 275 | struct phm_clock_voltage_dependency_table *table_clk_vlt; |
276 | sizeof(struct phm_clock_voltage_dependency_table) + | ||
277 | (7 * sizeof(struct phm_clock_voltage_dependency_record)); | ||
278 | 276 | ||
279 | struct phm_clock_voltage_dependency_table *table_clk_vlt = | 277 | table_clk_vlt = kzalloc(struct_size(table_clk_vlt, entries, 7), |
280 | kzalloc(table_size, GFP_KERNEL); | 278 | GFP_KERNEL); |
281 | 279 | ||
282 | if (NULL == table_clk_vlt) { | 280 | if (NULL == table_clk_vlt) { |
283 | pr_err("Can not allocate memory!\n"); | 281 | pr_err("Can not allocate memory!\n"); |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_baco.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_baco.c index f94dab27f486..7337be5602e4 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_baco.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_baco.c | |||
@@ -1,3 +1,25 @@ | |||
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 | */ | ||
1 | #include "amdgpu.h" | 23 | #include "amdgpu.h" |
2 | #include "soc15.h" | 24 | #include "soc15.h" |
3 | #include "soc15_hw_ip.h" | 25 | #include "soc15_hw_ip.h" |
@@ -114,7 +136,7 @@ int vega10_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state) | |||
114 | if (soc15_baco_program_registers(hwmgr, pre_baco_tbl, | 136 | if (soc15_baco_program_registers(hwmgr, pre_baco_tbl, |
115 | ARRAY_SIZE(pre_baco_tbl))) { | 137 | ARRAY_SIZE(pre_baco_tbl))) { |
116 | if (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnterBaco)) | 138 | if (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnterBaco)) |
117 | return -1; | 139 | return -EINVAL; |
118 | 140 | ||
119 | if (soc15_baco_program_registers(hwmgr, enter_baco_tbl, | 141 | if (soc15_baco_program_registers(hwmgr, enter_baco_tbl, |
120 | ARRAY_SIZE(enter_baco_tbl))) | 142 | ARRAY_SIZE(enter_baco_tbl))) |
@@ -132,5 +154,5 @@ int vega10_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state) | |||
132 | } | 154 | } |
133 | } | 155 | } |
134 | 156 | ||
135 | return -1; | 157 | return -EINVAL; |
136 | } | 158 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_baco.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_baco.h index a93b1e6d1c66..f7a3ffa744b3 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_baco.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_baco.h | |||
@@ -20,8 +20,8 @@ | |||
20 | * OTHER DEALINGS IN THE SOFTWARE. | 20 | * OTHER DEALINGS IN THE SOFTWARE. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | #ifndef __VEGA10_BOCO_H__ | 23 | #ifndef __VEGA10_BACO_H__ |
24 | #define __VEGA10_BOCO_H__ | 24 | #define __VEGA10_BACO_H__ |
25 | #include "hwmgr.h" | 25 | #include "hwmgr.h" |
26 | #include "common_baco.h" | 26 | #include "common_baco.h" |
27 | 27 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.c index 0d883b358df2..5e8602a79b1c 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.c | |||
@@ -1,3 +1,25 @@ | |||
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 | */ | ||
1 | #include "amdgpu.h" | 23 | #include "amdgpu.h" |
2 | #include "soc15.h" | 24 | #include "soc15.h" |
3 | #include "soc15_hw_ip.h" | 25 | #include "soc15_hw_ip.h" |
@@ -67,14 +89,14 @@ int vega20_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state) | |||
67 | 89 | ||
68 | 90 | ||
69 | if(smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_EnterBaco, 0)) | 91 | if(smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_EnterBaco, 0)) |
70 | return -1; | 92 | return -EINVAL; |
71 | 93 | ||
72 | } else if (state == BACO_STATE_OUT) { | 94 | } else if (state == BACO_STATE_OUT) { |
73 | if (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ExitBaco)) | 95 | if (smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ExitBaco)) |
74 | return -1; | 96 | return -EINVAL; |
75 | if (!soc15_baco_program_registers(hwmgr, clean_baco_tbl, | 97 | if (!soc15_baco_program_registers(hwmgr, clean_baco_tbl, |
76 | ARRAY_SIZE(clean_baco_tbl))) | 98 | ARRAY_SIZE(clean_baco_tbl))) |
77 | return -1; | 99 | return -EINVAL; |
78 | } | 100 | } |
79 | 101 | ||
80 | return 0; | 102 | return 0; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.h index c51988a9ed77..51c7f8392925 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.h | |||
@@ -20,8 +20,8 @@ | |||
20 | * OTHER DEALINGS IN THE SOFTWARE. | 20 | * OTHER DEALINGS IN THE SOFTWARE. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | #ifndef __VEGA20_BOCO_H__ | 23 | #ifndef __VEGA20_BACO_H__ |
24 | #define __VEGA20_BOCO_H__ | 24 | #define __VEGA20_BACO_H__ |
25 | #include "hwmgr.h" | 25 | #include "hwmgr.h" |
26 | #include "common_baco.h" | 26 | #include "common_baco.h" |
27 | 27 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c index 0769b1ec562b..aad79affb081 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | |||
@@ -3456,7 +3456,7 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr) | |||
3456 | disable_mclk_switching = ((1 < hwmgr->display_config->num_display) && | 3456 | disable_mclk_switching = ((1 < hwmgr->display_config->num_display) && |
3457 | !hwmgr->display_config->multi_monitor_in_sync) || | 3457 | !hwmgr->display_config->multi_monitor_in_sync) || |
3458 | vblank_too_short; | 3458 | vblank_too_short; |
3459 | latency = hwmgr->display_config->dce_tolerable_mclk_in_active_latency; | 3459 | latency = hwmgr->display_config->dce_tolerable_mclk_in_active_latency; |
3460 | 3460 | ||
3461 | /* gfxclk */ | 3461 | /* gfxclk */ |
3462 | dpm_table = &(data->dpm_table.gfx_table); | 3462 | dpm_table = &(data->dpm_table.gfx_table); |
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c index a6edd5df33b0..4240aeec9000 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c | |||
@@ -29,6 +29,10 @@ | |||
29 | #include <drm/amdgpu_drm.h> | 29 | #include <drm/amdgpu_drm.h> |
30 | #include "smumgr.h" | 30 | #include "smumgr.h" |
31 | 31 | ||
32 | MODULE_FIRMWARE("amdgpu/bonaire_smc.bin"); | ||
33 | MODULE_FIRMWARE("amdgpu/bonaire_k_smc.bin"); | ||
34 | MODULE_FIRMWARE("amdgpu/hawaii_smc.bin"); | ||
35 | MODULE_FIRMWARE("amdgpu/hawaii_k_smc.bin"); | ||
32 | MODULE_FIRMWARE("amdgpu/topaz_smc.bin"); | 36 | MODULE_FIRMWARE("amdgpu/topaz_smc.bin"); |
33 | MODULE_FIRMWARE("amdgpu/topaz_k_smc.bin"); | 37 | MODULE_FIRMWARE("amdgpu/topaz_k_smc.bin"); |
34 | MODULE_FIRMWARE("amdgpu/tonga_smc.bin"); | 38 | MODULE_FIRMWARE("amdgpu/tonga_smc.bin"); |
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index a97294ac96d5..a12439266bb0 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c | |||
@@ -4869,10 +4869,12 @@ static void ci_request_link_speed_change_before_state_change(struct radeon_devic | |||
4869 | pi->force_pcie_gen = RADEON_PCIE_GEN2; | 4869 | pi->force_pcie_gen = RADEON_PCIE_GEN2; |
4870 | if (current_link_speed == RADEON_PCIE_GEN2) | 4870 | if (current_link_speed == RADEON_PCIE_GEN2) |
4871 | break; | 4871 | break; |
4872 | /* fall through */ | ||
4872 | case RADEON_PCIE_GEN2: | 4873 | case RADEON_PCIE_GEN2: |
4873 | if (radeon_acpi_pcie_performance_request(rdev, PCIE_PERF_REQ_PECI_GEN2, false) == 0) | 4874 | if (radeon_acpi_pcie_performance_request(rdev, PCIE_PERF_REQ_PECI_GEN2, false) == 0) |
4874 | break; | 4875 | break; |
4875 | #endif | 4876 | #endif |
4877 | /* fall through */ | ||
4876 | default: | 4878 | default: |
4877 | pi->force_pcie_gen = ci_get_current_pcie_speed(rdev); | 4879 | pi->force_pcie_gen = ci_get_current_pcie_speed(rdev); |
4878 | break; | 4880 | break; |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index f471537c852f..1e14c6921454 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -1299,6 +1299,7 @@ static int evergreen_cs_handle_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1299 | return -EINVAL; | 1299 | return -EINVAL; |
1300 | } | 1300 | } |
1301 | ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); | 1301 | ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); |
1302 | break; | ||
1302 | case CB_TARGET_MASK: | 1303 | case CB_TARGET_MASK: |
1303 | track->cb_target_mask = radeon_get_ib_value(p, idx); | 1304 | track->cb_target_mask = radeon_get_ib_value(p, idx); |
1304 | track->cb_dirty = true; | 1305 | track->cb_dirty = true; |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 0a785ef0ab66..c9f6cb77e857 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
@@ -5762,10 +5762,12 @@ static void si_request_link_speed_change_before_state_change(struct radeon_devic | |||
5762 | si_pi->force_pcie_gen = RADEON_PCIE_GEN2; | 5762 | si_pi->force_pcie_gen = RADEON_PCIE_GEN2; |
5763 | if (current_link_speed == RADEON_PCIE_GEN2) | 5763 | if (current_link_speed == RADEON_PCIE_GEN2) |
5764 | break; | 5764 | break; |
5765 | /* fall through */ | ||
5765 | case RADEON_PCIE_GEN2: | 5766 | case RADEON_PCIE_GEN2: |
5766 | if (radeon_acpi_pcie_performance_request(rdev, PCIE_PERF_REQ_PECI_GEN2, false) == 0) | 5767 | if (radeon_acpi_pcie_performance_request(rdev, PCIE_PERF_REQ_PECI_GEN2, false) == 0) |
5767 | break; | 5768 | break; |
5768 | #endif | 5769 | #endif |
5770 | /* fall through */ | ||
5769 | default: | 5771 | default: |
5770 | si_pi->force_pcie_gen = si_get_current_pcie_speed(rdev); | 5772 | si_pi->force_pcie_gen = si_get_current_pcie_speed(rdev); |
5771 | break; | 5773 | break; |
diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index e2942c9a11a7..35ddbec1375a 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c | |||
@@ -52,12 +52,12 @@ int drm_sched_entity_init(struct drm_sched_entity *entity, | |||
52 | { | 52 | { |
53 | int i; | 53 | int i; |
54 | 54 | ||
55 | if (!(entity && rq_list && num_rq_list > 0 && rq_list[0])) | 55 | if (!(entity && rq_list && (num_rq_list == 0 || rq_list[0]))) |
56 | return -EINVAL; | 56 | return -EINVAL; |
57 | 57 | ||
58 | memset(entity, 0, sizeof(struct drm_sched_entity)); | 58 | memset(entity, 0, sizeof(struct drm_sched_entity)); |
59 | INIT_LIST_HEAD(&entity->list); | 59 | INIT_LIST_HEAD(&entity->list); |
60 | entity->rq = rq_list[0]; | 60 | entity->rq = NULL; |
61 | entity->guilty = guilty; | 61 | entity->guilty = guilty; |
62 | entity->num_rq_list = num_rq_list; | 62 | entity->num_rq_list = num_rq_list; |
63 | entity->rq_list = kcalloc(num_rq_list, sizeof(struct drm_sched_rq *), | 63 | entity->rq_list = kcalloc(num_rq_list, sizeof(struct drm_sched_rq *), |
@@ -67,6 +67,10 @@ int drm_sched_entity_init(struct drm_sched_entity *entity, | |||
67 | 67 | ||
68 | for (i = 0; i < num_rq_list; ++i) | 68 | for (i = 0; i < num_rq_list; ++i) |
69 | entity->rq_list[i] = rq_list[i]; | 69 | entity->rq_list[i] = rq_list[i]; |
70 | |||
71 | if (num_rq_list) | ||
72 | entity->rq = rq_list[0]; | ||
73 | |||
70 | entity->last_scheduled = NULL; | 74 | entity->last_scheduled = NULL; |
71 | 75 | ||
72 | spin_lock_init(&entity->rq_lock); | 76 | spin_lock_init(&entity->rq_lock); |
@@ -165,6 +169,9 @@ long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout) | |||
165 | struct task_struct *last_user; | 169 | struct task_struct *last_user; |
166 | long ret = timeout; | 170 | long ret = timeout; |
167 | 171 | ||
172 | if (!entity->rq) | ||
173 | return 0; | ||
174 | |||
168 | sched = entity->rq->sched; | 175 | sched = entity->rq->sched; |
169 | /** | 176 | /** |
170 | * The client will not queue more IBs during this fini, consume existing | 177 | * The client will not queue more IBs during this fini, consume existing |
@@ -264,20 +271,24 @@ static void drm_sched_entity_kill_jobs(struct drm_sched_entity *entity) | |||
264 | */ | 271 | */ |
265 | void drm_sched_entity_fini(struct drm_sched_entity *entity) | 272 | void drm_sched_entity_fini(struct drm_sched_entity *entity) |
266 | { | 273 | { |
267 | struct drm_gpu_scheduler *sched; | 274 | struct drm_gpu_scheduler *sched = NULL; |
268 | 275 | ||
269 | sched = entity->rq->sched; | 276 | if (entity->rq) { |
270 | drm_sched_rq_remove_entity(entity->rq, entity); | 277 | sched = entity->rq->sched; |
278 | drm_sched_rq_remove_entity(entity->rq, entity); | ||
279 | } | ||
271 | 280 | ||
272 | /* Consumption of existing IBs wasn't completed. Forcefully | 281 | /* Consumption of existing IBs wasn't completed. Forcefully |
273 | * remove them here. | 282 | * remove them here. |
274 | */ | 283 | */ |
275 | if (spsc_queue_peek(&entity->job_queue)) { | 284 | if (spsc_queue_peek(&entity->job_queue)) { |
276 | /* Park the kernel for a moment to make sure it isn't processing | 285 | if (sched) { |
277 | * our enity. | 286 | /* Park the kernel for a moment to make sure it isn't processing |
278 | */ | 287 | * our enity. |
279 | kthread_park(sched->thread); | 288 | */ |
280 | kthread_unpark(sched->thread); | 289 | kthread_park(sched->thread); |
290 | kthread_unpark(sched->thread); | ||
291 | } | ||
281 | if (entity->dependency) { | 292 | if (entity->dependency) { |
282 | dma_fence_remove_callback(entity->dependency, | 293 | dma_fence_remove_callback(entity->dependency, |
283 | &entity->cb); | 294 | &entity->cb); |
@@ -362,9 +373,11 @@ void drm_sched_entity_set_priority(struct drm_sched_entity *entity, | |||
362 | for (i = 0; i < entity->num_rq_list; ++i) | 373 | for (i = 0; i < entity->num_rq_list; ++i) |
363 | drm_sched_entity_set_rq_priority(&entity->rq_list[i], priority); | 374 | drm_sched_entity_set_rq_priority(&entity->rq_list[i], priority); |
364 | 375 | ||
365 | drm_sched_rq_remove_entity(entity->rq, entity); | 376 | if (entity->rq) { |
366 | drm_sched_entity_set_rq_priority(&entity->rq, priority); | 377 | drm_sched_rq_remove_entity(entity->rq, entity); |
367 | drm_sched_rq_add_entity(entity->rq, entity); | 378 | drm_sched_entity_set_rq_priority(&entity->rq, priority); |
379 | drm_sched_rq_add_entity(entity->rq, entity); | ||
380 | } | ||
368 | 381 | ||
369 | spin_unlock(&entity->rq_lock); | 382 | spin_unlock(&entity->rq_lock); |
370 | } | 383 | } |
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 2acbc8bc465b..4a53f6cfa034 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h | |||
@@ -272,13 +272,14 @@ union drm_amdgpu_vm { | |||
272 | 272 | ||
273 | /* sched ioctl */ | 273 | /* sched ioctl */ |
274 | #define AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE 1 | 274 | #define AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE 1 |
275 | #define AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE 2 | ||
275 | 276 | ||
276 | struct drm_amdgpu_sched_in { | 277 | struct drm_amdgpu_sched_in { |
277 | /* AMDGPU_SCHED_OP_* */ | 278 | /* AMDGPU_SCHED_OP_* */ |
278 | __u32 op; | 279 | __u32 op; |
279 | __u32 fd; | 280 | __u32 fd; |
280 | __s32 priority; | 281 | __s32 priority; |
281 | __u32 flags; | 282 | __u32 ctx_id; |
282 | }; | 283 | }; |
283 | 284 | ||
284 | union drm_amdgpu_sched { | 285 | union drm_amdgpu_sched { |