diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
108 files changed, 5447 insertions, 2306 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig b/drivers/gpu/drm/amd/amdgpu/Kconfig index 26682454a446..e8af1f5e8a79 100644 --- a/drivers/gpu/drm/amd/amdgpu/Kconfig +++ b/drivers/gpu/drm/amd/amdgpu/Kconfig | |||
@@ -41,3 +41,4 @@ config DRM_AMDGPU_GART_DEBUGFS | |||
41 | pages. Uses more memory for housekeeping, enable only for debugging. | 41 | pages. Uses more memory for housekeeping, enable only for debugging. |
42 | 42 | ||
43 | source "drivers/gpu/drm/amd/acp/Kconfig" | 43 | source "drivers/gpu/drm/amd/acp/Kconfig" |
44 | source "drivers/gpu/drm/amd/display/Kconfig" | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index 567b0377e1e2..78d609123420 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile | |||
@@ -4,13 +4,19 @@ | |||
4 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. | 4 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. |
5 | 5 | ||
6 | FULL_AMD_PATH=$(src)/.. | 6 | FULL_AMD_PATH=$(src)/.. |
7 | DISPLAY_FOLDER_NAME=display | ||
8 | FULL_AMD_DISPLAY_PATH = $(FULL_AMD_PATH)/$(DISPLAY_FOLDER_NAME) | ||
7 | 9 | ||
8 | ccflags-y := -I$(FULL_AMD_PATH)/include/asic_reg \ | 10 | ccflags-y := -I$(FULL_AMD_PATH)/include/asic_reg \ |
9 | -I$(FULL_AMD_PATH)/include \ | 11 | -I$(FULL_AMD_PATH)/include \ |
10 | -I$(FULL_AMD_PATH)/amdgpu \ | 12 | -I$(FULL_AMD_PATH)/amdgpu \ |
11 | -I$(FULL_AMD_PATH)/scheduler \ | 13 | -I$(FULL_AMD_PATH)/scheduler \ |
12 | -I$(FULL_AMD_PATH)/powerplay/inc \ | 14 | -I$(FULL_AMD_PATH)/powerplay/inc \ |
13 | -I$(FULL_AMD_PATH)/acp/include | 15 | -I$(FULL_AMD_PATH)/acp/include \ |
16 | -I$(FULL_AMD_DISPLAY_PATH) \ | ||
17 | -I$(FULL_AMD_DISPLAY_PATH)/include \ | ||
18 | -I$(FULL_AMD_DISPLAY_PATH)/dc \ | ||
19 | -I$(FULL_AMD_DISPLAY_PATH)/amdgpu_dm | ||
14 | 20 | ||
15 | amdgpu-y := amdgpu_drv.o | 21 | amdgpu-y := amdgpu_drv.o |
16 | 22 | ||
@@ -26,7 +32,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \ | |||
26 | amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \ | 32 | amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \ |
27 | amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \ | 33 | amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \ |
28 | amdgpu_gtt_mgr.o amdgpu_vram_mgr.o amdgpu_virt.o amdgpu_atomfirmware.o \ | 34 | amdgpu_gtt_mgr.o amdgpu_vram_mgr.o amdgpu_virt.o amdgpu_atomfirmware.o \ |
29 | amdgpu_queue_mgr.o amdgpu_vf_error.o | 35 | amdgpu_queue_mgr.o amdgpu_vf_error.o amdgpu_sched.o |
30 | 36 | ||
31 | # add asic specific block | 37 | # add asic specific block |
32 | amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ | 38 | amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ |
@@ -133,6 +139,13 @@ include $(FULL_AMD_PATH)/powerplay/Makefile | |||
133 | 139 | ||
134 | amdgpu-y += $(AMD_POWERPLAY_FILES) | 140 | amdgpu-y += $(AMD_POWERPLAY_FILES) |
135 | 141 | ||
136 | obj-$(CONFIG_DRM_AMDGPU)+= amdgpu.o | 142 | ifneq ($(CONFIG_DRM_AMD_DC),) |
143 | |||
144 | RELATIVE_AMD_DISPLAY_PATH = ../$(DISPLAY_FOLDER_NAME) | ||
145 | include $(FULL_AMD_DISPLAY_PATH)/Makefile | ||
146 | |||
147 | amdgpu-y += $(AMD_DISPLAY_FILES) | ||
137 | 148 | ||
138 | CFLAGS_amdgpu_trace_points.o := -I$(src) | 149 | endif |
150 | |||
151 | obj-$(CONFIG_DRM_AMDGPU)+= amdgpu.o | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 103635ab784c..5afaf6016b4a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -65,6 +65,8 @@ | |||
65 | #include "amdgpu_uvd.h" | 65 | #include "amdgpu_uvd.h" |
66 | #include "amdgpu_vce.h" | 66 | #include "amdgpu_vce.h" |
67 | #include "amdgpu_vcn.h" | 67 | #include "amdgpu_vcn.h" |
68 | #include "amdgpu_mn.h" | ||
69 | #include "amdgpu_dm.h" | ||
68 | 70 | ||
69 | #include "gpu_scheduler.h" | 71 | #include "gpu_scheduler.h" |
70 | #include "amdgpu_virt.h" | 72 | #include "amdgpu_virt.h" |
@@ -91,7 +93,7 @@ extern int amdgpu_dpm; | |||
91 | extern int amdgpu_fw_load_type; | 93 | extern int amdgpu_fw_load_type; |
92 | extern int amdgpu_aspm; | 94 | extern int amdgpu_aspm; |
93 | extern int amdgpu_runtime_pm; | 95 | extern int amdgpu_runtime_pm; |
94 | extern unsigned amdgpu_ip_block_mask; | 96 | extern uint amdgpu_ip_block_mask; |
95 | extern int amdgpu_bapm; | 97 | extern int amdgpu_bapm; |
96 | extern int amdgpu_deep_color; | 98 | extern int amdgpu_deep_color; |
97 | extern int amdgpu_vm_size; | 99 | extern int amdgpu_vm_size; |
@@ -100,18 +102,20 @@ extern int amdgpu_vm_fragment_size; | |||
100 | extern int amdgpu_vm_fault_stop; | 102 | extern int amdgpu_vm_fault_stop; |
101 | extern int amdgpu_vm_debug; | 103 | extern int amdgpu_vm_debug; |
102 | extern int amdgpu_vm_update_mode; | 104 | extern int amdgpu_vm_update_mode; |
105 | extern int amdgpu_dc; | ||
106 | extern int amdgpu_dc_log; | ||
103 | extern int amdgpu_sched_jobs; | 107 | extern int amdgpu_sched_jobs; |
104 | extern int amdgpu_sched_hw_submission; | 108 | extern int amdgpu_sched_hw_submission; |
105 | extern int amdgpu_no_evict; | 109 | extern int amdgpu_no_evict; |
106 | extern int amdgpu_direct_gma_size; | 110 | extern int amdgpu_direct_gma_size; |
107 | extern unsigned amdgpu_pcie_gen_cap; | 111 | extern uint amdgpu_pcie_gen_cap; |
108 | extern unsigned amdgpu_pcie_lane_cap; | 112 | extern uint amdgpu_pcie_lane_cap; |
109 | extern unsigned amdgpu_cg_mask; | 113 | extern uint amdgpu_cg_mask; |
110 | extern unsigned amdgpu_pg_mask; | 114 | extern uint amdgpu_pg_mask; |
111 | extern unsigned amdgpu_sdma_phase_quantum; | 115 | extern uint amdgpu_sdma_phase_quantum; |
112 | extern char *amdgpu_disable_cu; | 116 | extern char *amdgpu_disable_cu; |
113 | extern char *amdgpu_virtual_display; | 117 | extern char *amdgpu_virtual_display; |
114 | extern unsigned amdgpu_pp_feature_mask; | 118 | extern uint amdgpu_pp_feature_mask; |
115 | extern int amdgpu_vram_page_split; | 119 | extern int amdgpu_vram_page_split; |
116 | extern int amdgpu_ngg; | 120 | extern int amdgpu_ngg; |
117 | extern int amdgpu_prim_buf_per_se; | 121 | extern int amdgpu_prim_buf_per_se; |
@@ -120,6 +124,7 @@ extern int amdgpu_cntl_sb_buf_per_se; | |||
120 | extern int amdgpu_param_buf_per_se; | 124 | extern int amdgpu_param_buf_per_se; |
121 | extern int amdgpu_job_hang_limit; | 125 | extern int amdgpu_job_hang_limit; |
122 | extern int amdgpu_lbpw; | 126 | extern int amdgpu_lbpw; |
127 | extern int amdgpu_compute_multipipe; | ||
123 | 128 | ||
124 | #ifdef CONFIG_DRM_AMDGPU_SI | 129 | #ifdef CONFIG_DRM_AMDGPU_SI |
125 | extern int amdgpu_si_support; | 130 | extern int amdgpu_si_support; |
@@ -178,6 +183,7 @@ struct amdgpu_cs_parser; | |||
178 | struct amdgpu_job; | 183 | struct amdgpu_job; |
179 | struct amdgpu_irq_src; | 184 | struct amdgpu_irq_src; |
180 | struct amdgpu_fpriv; | 185 | struct amdgpu_fpriv; |
186 | struct amdgpu_bo_va_mapping; | ||
181 | 187 | ||
182 | enum amdgpu_cp_irq { | 188 | enum amdgpu_cp_irq { |
183 | AMDGPU_CP_IRQ_GFX_EOP = 0, | 189 | AMDGPU_CP_IRQ_GFX_EOP = 0, |
@@ -292,14 +298,25 @@ struct amdgpu_buffer_funcs { | |||
292 | 298 | ||
293 | /* provided by hw blocks that can write ptes, e.g., sdma */ | 299 | /* provided by hw blocks that can write ptes, e.g., sdma */ |
294 | struct amdgpu_vm_pte_funcs { | 300 | struct amdgpu_vm_pte_funcs { |
301 | /* number of dw to reserve per operation */ | ||
302 | unsigned copy_pte_num_dw; | ||
303 | |||
295 | /* copy pte entries from GART */ | 304 | /* copy pte entries from GART */ |
296 | void (*copy_pte)(struct amdgpu_ib *ib, | 305 | void (*copy_pte)(struct amdgpu_ib *ib, |
297 | uint64_t pe, uint64_t src, | 306 | uint64_t pe, uint64_t src, |
298 | unsigned count); | 307 | unsigned count); |
308 | |||
299 | /* write pte one entry at a time with addr mapping */ | 309 | /* write pte one entry at a time with addr mapping */ |
300 | void (*write_pte)(struct amdgpu_ib *ib, uint64_t pe, | 310 | void (*write_pte)(struct amdgpu_ib *ib, uint64_t pe, |
301 | uint64_t value, unsigned count, | 311 | uint64_t value, unsigned count, |
302 | uint32_t incr); | 312 | uint32_t incr); |
313 | |||
314 | /* maximum nums of PTEs/PDEs in a single operation */ | ||
315 | uint32_t set_max_nums_pte_pde; | ||
316 | |||
317 | /* number of dw to reserve per operation */ | ||
318 | unsigned set_pte_pde_num_dw; | ||
319 | |||
303 | /* for linear pte/pde updates without addr mapping */ | 320 | /* for linear pte/pde updates without addr mapping */ |
304 | void (*set_pte_pde)(struct amdgpu_ib *ib, | 321 | void (*set_pte_pde)(struct amdgpu_ib *ib, |
305 | uint64_t pe, | 322 | uint64_t pe, |
@@ -332,6 +349,7 @@ struct amdgpu_gart_funcs { | |||
332 | struct amdgpu_ih_funcs { | 349 | struct amdgpu_ih_funcs { |
333 | /* ring read/write ptr handling, called from interrupt context */ | 350 | /* ring read/write ptr handling, called from interrupt context */ |
334 | u32 (*get_wptr)(struct amdgpu_device *adev); | 351 | u32 (*get_wptr)(struct amdgpu_device *adev); |
352 | bool (*prescreen_iv)(struct amdgpu_device *adev); | ||
335 | void (*decode_iv)(struct amdgpu_device *adev, | 353 | void (*decode_iv)(struct amdgpu_device *adev, |
336 | struct amdgpu_iv_entry *entry); | 354 | struct amdgpu_iv_entry *entry); |
337 | void (*set_rptr)(struct amdgpu_device *adev); | 355 | void (*set_rptr)(struct amdgpu_device *adev); |
@@ -399,6 +417,7 @@ void amdgpu_gem_prime_unpin(struct drm_gem_object *obj); | |||
399 | struct reservation_object *amdgpu_gem_prime_res_obj(struct drm_gem_object *); | 417 | struct reservation_object *amdgpu_gem_prime_res_obj(struct drm_gem_object *); |
400 | void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj); | 418 | void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj); |
401 | void amdgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); | 419 | void amdgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); |
420 | int amdgpu_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); | ||
402 | int amdgpu_gem_debugfs_init(struct amdgpu_device *adev); | 421 | int amdgpu_gem_debugfs_init(struct amdgpu_device *adev); |
403 | 422 | ||
404 | /* sub-allocation manager, it has to be protected by another lock. | 423 | /* sub-allocation manager, it has to be protected by another lock. |
@@ -455,9 +474,10 @@ struct amdgpu_sa_bo { | |||
455 | */ | 474 | */ |
456 | void amdgpu_gem_force_release(struct amdgpu_device *adev); | 475 | void amdgpu_gem_force_release(struct amdgpu_device *adev); |
457 | int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size, | 476 | int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size, |
458 | int alignment, u32 initial_domain, | 477 | int alignment, u32 initial_domain, |
459 | u64 flags, bool kernel, | 478 | u64 flags, bool kernel, |
460 | struct drm_gem_object **obj); | 479 | struct reservation_object *resv, |
480 | struct drm_gem_object **obj); | ||
461 | 481 | ||
462 | int amdgpu_mode_dumb_create(struct drm_file *file_priv, | 482 | int amdgpu_mode_dumb_create(struct drm_file *file_priv, |
463 | struct drm_device *dev, | 483 | struct drm_device *dev, |
@@ -715,10 +735,14 @@ struct amdgpu_ctx { | |||
715 | struct amdgpu_device *adev; | 735 | struct amdgpu_device *adev; |
716 | struct amdgpu_queue_mgr queue_mgr; | 736 | struct amdgpu_queue_mgr queue_mgr; |
717 | unsigned reset_counter; | 737 | unsigned reset_counter; |
738 | uint32_t vram_lost_counter; | ||
718 | spinlock_t ring_lock; | 739 | spinlock_t ring_lock; |
719 | struct dma_fence **fences; | 740 | struct dma_fence **fences; |
720 | struct amdgpu_ctx_ring rings[AMDGPU_MAX_RINGS]; | 741 | struct amdgpu_ctx_ring rings[AMDGPU_MAX_RINGS]; |
721 | bool preamble_presented; | 742 | bool preamble_presented; |
743 | enum amd_sched_priority init_priority; | ||
744 | enum amd_sched_priority override_priority; | ||
745 | struct mutex lock; | ||
722 | }; | 746 | }; |
723 | 747 | ||
724 | struct amdgpu_ctx_mgr { | 748 | struct amdgpu_ctx_mgr { |
@@ -731,17 +755,22 @@ struct amdgpu_ctx_mgr { | |||
731 | struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id); | 755 | struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id); |
732 | int amdgpu_ctx_put(struct amdgpu_ctx *ctx); | 756 | int amdgpu_ctx_put(struct amdgpu_ctx *ctx); |
733 | 757 | ||
734 | uint64_t amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, | 758 | int amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, |
735 | struct dma_fence *fence); | 759 | struct dma_fence *fence, uint64_t *seq); |
736 | struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx, | 760 | struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx, |
737 | struct amdgpu_ring *ring, uint64_t seq); | 761 | struct amdgpu_ring *ring, uint64_t seq); |
762 | void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx, | ||
763 | enum amd_sched_priority priority); | ||
738 | 764 | ||
739 | int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, | 765 | int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, |
740 | struct drm_file *filp); | 766 | struct drm_file *filp); |
741 | 767 | ||
768 | int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx, unsigned ring_id); | ||
769 | |||
742 | void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr); | 770 | void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr); |
743 | void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr); | 771 | void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr); |
744 | 772 | ||
773 | |||
745 | /* | 774 | /* |
746 | * file private structure | 775 | * file private structure |
747 | */ | 776 | */ |
@@ -753,7 +782,6 @@ struct amdgpu_fpriv { | |||
753 | struct mutex bo_list_lock; | 782 | struct mutex bo_list_lock; |
754 | struct idr bo_list_handles; | 783 | struct idr bo_list_handles; |
755 | struct amdgpu_ctx_mgr ctx_mgr; | 784 | struct amdgpu_ctx_mgr ctx_mgr; |
756 | u32 vram_lost_counter; | ||
757 | }; | 785 | }; |
758 | 786 | ||
759 | /* | 787 | /* |
@@ -854,7 +882,7 @@ struct amdgpu_mec { | |||
854 | struct amdgpu_kiq { | 882 | struct amdgpu_kiq { |
855 | u64 eop_gpu_addr; | 883 | u64 eop_gpu_addr; |
856 | struct amdgpu_bo *eop_obj; | 884 | struct amdgpu_bo *eop_obj; |
857 | struct mutex ring_mutex; | 885 | spinlock_t ring_lock; |
858 | struct amdgpu_ring ring; | 886 | struct amdgpu_ring ring; |
859 | struct amdgpu_irq_src irq; | 887 | struct amdgpu_irq_src irq; |
860 | }; | 888 | }; |
@@ -1014,11 +1042,14 @@ struct amdgpu_gfx { | |||
1014 | /* reset mask */ | 1042 | /* reset mask */ |
1015 | uint32_t grbm_soft_reset; | 1043 | uint32_t grbm_soft_reset; |
1016 | uint32_t srbm_soft_reset; | 1044 | uint32_t srbm_soft_reset; |
1017 | bool in_reset; | ||
1018 | /* s3/s4 mask */ | 1045 | /* s3/s4 mask */ |
1019 | bool in_suspend; | 1046 | bool in_suspend; |
1020 | /* NGG */ | 1047 | /* NGG */ |
1021 | struct amdgpu_ngg ngg; | 1048 | struct amdgpu_ngg ngg; |
1049 | |||
1050 | /* pipe reservation */ | ||
1051 | struct mutex pipe_reserve_mutex; | ||
1052 | DECLARE_BITMAP (pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES); | ||
1022 | }; | 1053 | }; |
1023 | 1054 | ||
1024 | int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, | 1055 | int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, |
@@ -1056,6 +1087,7 @@ struct amdgpu_cs_parser { | |||
1056 | /* buffer objects */ | 1087 | /* buffer objects */ |
1057 | struct ww_acquire_ctx ticket; | 1088 | struct ww_acquire_ctx ticket; |
1058 | struct amdgpu_bo_list *bo_list; | 1089 | struct amdgpu_bo_list *bo_list; |
1090 | struct amdgpu_mn *mn; | ||
1059 | struct amdgpu_bo_list_entry vm_pd; | 1091 | struct amdgpu_bo_list_entry vm_pd; |
1060 | struct list_head validated; | 1092 | struct list_head validated; |
1061 | struct dma_fence *fence; | 1093 | struct dma_fence *fence; |
@@ -1096,6 +1128,7 @@ struct amdgpu_job { | |||
1096 | uint32_t gds_base, gds_size; | 1128 | uint32_t gds_base, gds_size; |
1097 | uint32_t gws_base, gws_size; | 1129 | uint32_t gws_base, gws_size; |
1098 | uint32_t oa_base, oa_size; | 1130 | uint32_t oa_base, oa_size; |
1131 | uint32_t vram_lost_counter; | ||
1099 | 1132 | ||
1100 | /* user fence handling */ | 1133 | /* user fence handling */ |
1101 | uint64_t uf_addr; | 1134 | uint64_t uf_addr; |
@@ -1121,7 +1154,7 @@ static inline void amdgpu_set_ib_value(struct amdgpu_cs_parser *p, | |||
1121 | /* | 1154 | /* |
1122 | * Writeback | 1155 | * Writeback |
1123 | */ | 1156 | */ |
1124 | #define AMDGPU_MAX_WB 1024 /* Reserve at most 1024 WB slots for amdgpu-owned rings. */ | 1157 | #define AMDGPU_MAX_WB 512 /* Reserve at most 512 WB slots for amdgpu-owned rings. */ |
1125 | 1158 | ||
1126 | struct amdgpu_wb { | 1159 | struct amdgpu_wb { |
1127 | struct amdgpu_bo *wb_obj; | 1160 | struct amdgpu_bo *wb_obj; |
@@ -1183,6 +1216,9 @@ struct amdgpu_firmware { | |||
1183 | 1216 | ||
1184 | /* gpu info firmware data pointer */ | 1217 | /* gpu info firmware data pointer */ |
1185 | const struct firmware *gpu_info_fw; | 1218 | const struct firmware *gpu_info_fw; |
1219 | |||
1220 | void *fw_buf_ptr; | ||
1221 | uint64_t fw_buf_mc; | ||
1186 | }; | 1222 | }; |
1187 | 1223 | ||
1188 | /* | 1224 | /* |
@@ -1197,20 +1233,6 @@ void amdgpu_benchmark(struct amdgpu_device *adev, int test_number); | |||
1197 | void amdgpu_test_moves(struct amdgpu_device *adev); | 1233 | void amdgpu_test_moves(struct amdgpu_device *adev); |
1198 | 1234 | ||
1199 | /* | 1235 | /* |
1200 | * MMU Notifier | ||
1201 | */ | ||
1202 | #if defined(CONFIG_MMU_NOTIFIER) | ||
1203 | int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr); | ||
1204 | void amdgpu_mn_unregister(struct amdgpu_bo *bo); | ||
1205 | #else | ||
1206 | static inline int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr) | ||
1207 | { | ||
1208 | return -ENODEV; | ||
1209 | } | ||
1210 | static inline void amdgpu_mn_unregister(struct amdgpu_bo *bo) {} | ||
1211 | #endif | ||
1212 | |||
1213 | /* | ||
1214 | * Debugfs | 1236 | * Debugfs |
1215 | */ | 1237 | */ |
1216 | struct amdgpu_debugfs { | 1238 | struct amdgpu_debugfs { |
@@ -1305,6 +1327,8 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | |||
1305 | int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, | 1327 | int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, |
1306 | struct drm_file *filp); | 1328 | struct drm_file *filp); |
1307 | int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); | 1329 | int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); |
1330 | int amdgpu_cs_fence_to_handle_ioctl(struct drm_device *dev, void *data, | ||
1331 | struct drm_file *filp); | ||
1308 | int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); | 1332 | int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); |
1309 | int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data, | 1333 | int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data, |
1310 | struct drm_file *filp); | 1334 | struct drm_file *filp); |
@@ -1371,6 +1395,18 @@ struct amdgpu_atcs { | |||
1371 | }; | 1395 | }; |
1372 | 1396 | ||
1373 | /* | 1397 | /* |
1398 | * Firmware VRAM reservation | ||
1399 | */ | ||
1400 | struct amdgpu_fw_vram_usage { | ||
1401 | u64 start_offset; | ||
1402 | u64 size; | ||
1403 | struct amdgpu_bo *reserved_bo; | ||
1404 | void *va; | ||
1405 | }; | ||
1406 | |||
1407 | int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev); | ||
1408 | |||
1409 | /* | ||
1374 | * CGS | 1410 | * CGS |
1375 | */ | 1411 | */ |
1376 | struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev); | 1412 | struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev); |
@@ -1502,6 +1538,7 @@ struct amdgpu_device { | |||
1502 | /* display */ | 1538 | /* display */ |
1503 | bool enable_virtual_display; | 1539 | bool enable_virtual_display; |
1504 | struct amdgpu_mode_info mode_info; | 1540 | struct amdgpu_mode_info mode_info; |
1541 | /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */ | ||
1505 | struct work_struct hotplug_work; | 1542 | struct work_struct hotplug_work; |
1506 | struct amdgpu_irq_src crtc_irq; | 1543 | struct amdgpu_irq_src crtc_irq; |
1507 | struct amdgpu_irq_src pageflip_irq; | 1544 | struct amdgpu_irq_src pageflip_irq; |
@@ -1519,7 +1556,6 @@ struct amdgpu_device { | |||
1519 | 1556 | ||
1520 | /* powerplay */ | 1557 | /* powerplay */ |
1521 | struct amd_powerplay powerplay; | 1558 | struct amd_powerplay powerplay; |
1522 | bool pp_enabled; | ||
1523 | bool pp_force_state_enabled; | 1559 | bool pp_force_state_enabled; |
1524 | 1560 | ||
1525 | /* dpm */ | 1561 | /* dpm */ |
@@ -1558,6 +1594,9 @@ struct amdgpu_device { | |||
1558 | /* GDS */ | 1594 | /* GDS */ |
1559 | struct amdgpu_gds gds; | 1595 | struct amdgpu_gds gds; |
1560 | 1596 | ||
1597 | /* display related functionality */ | ||
1598 | struct amdgpu_display_manager dm; | ||
1599 | |||
1561 | struct amdgpu_ip_block ip_blocks[AMDGPU_MAX_IP_NUM]; | 1600 | struct amdgpu_ip_block ip_blocks[AMDGPU_MAX_IP_NUM]; |
1562 | int num_ip_blocks; | 1601 | int num_ip_blocks; |
1563 | struct mutex mn_lock; | 1602 | struct mutex mn_lock; |
@@ -1575,6 +1614,8 @@ struct amdgpu_device { | |||
1575 | struct delayed_work late_init_work; | 1614 | struct delayed_work late_init_work; |
1576 | 1615 | ||
1577 | struct amdgpu_virt virt; | 1616 | struct amdgpu_virt virt; |
1617 | /* firmware VRAM reservation */ | ||
1618 | struct amdgpu_fw_vram_usage fw_vram_usage; | ||
1578 | 1619 | ||
1579 | /* link all shadow bo */ | 1620 | /* link all shadow bo */ |
1580 | struct list_head shadow_list; | 1621 | struct list_head shadow_list; |
@@ -1592,6 +1633,7 @@ struct amdgpu_device { | |||
1592 | 1633 | ||
1593 | /* record last mm index being written through WREG32*/ | 1634 | /* record last mm index being written through WREG32*/ |
1594 | unsigned long last_mm_index; | 1635 | unsigned long last_mm_index; |
1636 | bool in_sriov_reset; | ||
1595 | }; | 1637 | }; |
1596 | 1638 | ||
1597 | static inline struct amdgpu_device *amdgpu_ttm_adev(struct ttm_bo_device *bdev) | 1639 | static inline struct amdgpu_device *amdgpu_ttm_adev(struct ttm_bo_device *bdev) |
@@ -1618,6 +1660,9 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v); | |||
1618 | u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index); | 1660 | u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index); |
1619 | void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v); | 1661 | void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v); |
1620 | 1662 | ||
1663 | bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type); | ||
1664 | bool amdgpu_device_has_dc_support(struct amdgpu_device *adev); | ||
1665 | |||
1621 | /* | 1666 | /* |
1622 | * Registers read & write functions. | 1667 | * Registers read & write functions. |
1623 | */ | 1668 | */ |
@@ -1759,6 +1804,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) | |||
1759 | #define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r)) | 1804 | #define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r)) |
1760 | #define amdgpu_ring_patch_cond_exec(r,o) (r)->funcs->patch_cond_exec((r),(o)) | 1805 | #define amdgpu_ring_patch_cond_exec(r,o) (r)->funcs->patch_cond_exec((r),(o)) |
1761 | #define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev)) | 1806 | #define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev)) |
1807 | #define amdgpu_ih_prescreen_iv(adev) (adev)->irq.ih_funcs->prescreen_iv((adev)) | ||
1762 | #define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv)) | 1808 | #define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv)) |
1763 | #define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev)) | 1809 | #define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev)) |
1764 | #define amdgpu_display_vblank_get_counter(adev, crtc) (adev)->mode_info.funcs->vblank_get_counter((adev), (crtc)) | 1810 | #define amdgpu_display_vblank_get_counter(adev, crtc) (adev)->mode_info.funcs->vblank_get_counter((adev), (crtc)) |
@@ -1791,18 +1837,6 @@ void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes, | |||
1791 | u64 num_vis_bytes); | 1837 | u64 num_vis_bytes); |
1792 | void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain); | 1838 | void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain); |
1793 | bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo); | 1839 | bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo); |
1794 | int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages); | ||
1795 | int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, | ||
1796 | uint32_t flags); | ||
1797 | bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm); | ||
1798 | struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm); | ||
1799 | bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, | ||
1800 | unsigned long end); | ||
1801 | bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, | ||
1802 | int *last_invalidated); | ||
1803 | bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm); | ||
1804 | uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, | ||
1805 | struct ttm_mem_reg *mem); | ||
1806 | void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64 base); | 1840 | void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64 base); |
1807 | void amdgpu_gart_location(struct amdgpu_device *adev, struct amdgpu_mc *mc); | 1841 | void amdgpu_gart_location(struct amdgpu_device *adev, struct amdgpu_mc *mc); |
1808 | void amdgpu_ttm_set_active_vram_size(struct amdgpu_device *adev, u64 size); | 1842 | void amdgpu_ttm_set_active_vram_size(struct amdgpu_device *adev, u64 size); |
@@ -1836,8 +1870,6 @@ static inline bool amdgpu_has_atpx(void) { return false; } | |||
1836 | extern const struct drm_ioctl_desc amdgpu_ioctls_kms[]; | 1870 | extern const struct drm_ioctl_desc amdgpu_ioctls_kms[]; |
1837 | extern const int amdgpu_max_kms_ioctl; | 1871 | extern const int amdgpu_max_kms_ioctl; |
1838 | 1872 | ||
1839 | bool amdgpu_kms_vram_lost(struct amdgpu_device *adev, | ||
1840 | struct amdgpu_fpriv *fpriv); | ||
1841 | int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags); | 1873 | int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags); |
1842 | void amdgpu_driver_unload_kms(struct drm_device *dev); | 1874 | void amdgpu_driver_unload_kms(struct drm_device *dev); |
1843 | void amdgpu_driver_lastclose_kms(struct drm_device *dev); | 1875 | void amdgpu_driver_lastclose_kms(struct drm_device *dev); |
@@ -1885,10 +1917,15 @@ static inline int amdgpu_acpi_init(struct amdgpu_device *adev) { return 0; } | |||
1885 | static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { } | 1917 | static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { } |
1886 | #endif | 1918 | #endif |
1887 | 1919 | ||
1888 | struct amdgpu_bo_va_mapping * | 1920 | int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser, |
1889 | amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser, | 1921 | uint64_t addr, struct amdgpu_bo **bo, |
1890 | uint64_t addr, struct amdgpu_bo **bo); | 1922 | struct amdgpu_bo_va_mapping **mapping); |
1891 | int amdgpu_cs_sysvm_access_required(struct amdgpu_cs_parser *parser); | 1923 | |
1924 | #if defined(CONFIG_DRM_AMD_DC) | ||
1925 | int amdgpu_dm_display_resume(struct amdgpu_device *adev ); | ||
1926 | #else | ||
1927 | static inline int amdgpu_dm_display_resume(struct amdgpu_device *adev) { return 0; } | ||
1928 | #endif | ||
1892 | 1929 | ||
1893 | #include "amdgpu_object.h" | 1930 | #include "amdgpu_object.h" |
1894 | #endif | 1931 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c index a52795d9b458..c04f44a90392 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | |||
@@ -35,41 +35,50 @@ | |||
35 | 35 | ||
36 | #include "acp_gfx_if.h" | 36 | #include "acp_gfx_if.h" |
37 | 37 | ||
38 | #define ACP_TILE_ON_MASK 0x03 | 38 | #define ACP_TILE_ON_MASK 0x03 |
39 | #define ACP_TILE_OFF_MASK 0x02 | 39 | #define ACP_TILE_OFF_MASK 0x02 |
40 | #define ACP_TILE_ON_RETAIN_REG_MASK 0x1f | 40 | #define ACP_TILE_ON_RETAIN_REG_MASK 0x1f |
41 | #define ACP_TILE_OFF_RETAIN_REG_MASK 0x20 | 41 | #define ACP_TILE_OFF_RETAIN_REG_MASK 0x20 |
42 | 42 | ||
43 | #define ACP_TILE_P1_MASK 0x3e | 43 | #define ACP_TILE_P1_MASK 0x3e |
44 | #define ACP_TILE_P2_MASK 0x3d | 44 | #define ACP_TILE_P2_MASK 0x3d |
45 | #define ACP_TILE_DSP0_MASK 0x3b | 45 | #define ACP_TILE_DSP0_MASK 0x3b |
46 | #define ACP_TILE_DSP1_MASK 0x37 | 46 | #define ACP_TILE_DSP1_MASK 0x37 |
47 | 47 | ||
48 | #define ACP_TILE_DSP2_MASK 0x2f | 48 | #define ACP_TILE_DSP2_MASK 0x2f |
49 | 49 | ||
50 | #define ACP_DMA_REGS_END 0x146c0 | 50 | #define ACP_DMA_REGS_END 0x146c0 |
51 | #define ACP_I2S_PLAY_REGS_START 0x14840 | 51 | #define ACP_I2S_PLAY_REGS_START 0x14840 |
52 | #define ACP_I2S_PLAY_REGS_END 0x148b4 | 52 | #define ACP_I2S_PLAY_REGS_END 0x148b4 |
53 | #define ACP_I2S_CAP_REGS_START 0x148b8 | 53 | #define ACP_I2S_CAP_REGS_START 0x148b8 |
54 | #define ACP_I2S_CAP_REGS_END 0x1496c | 54 | #define ACP_I2S_CAP_REGS_END 0x1496c |
55 | 55 | ||
56 | #define ACP_I2S_COMP1_CAP_REG_OFFSET 0xac | 56 | #define ACP_I2S_COMP1_CAP_REG_OFFSET 0xac |
57 | #define ACP_I2S_COMP2_CAP_REG_OFFSET 0xa8 | 57 | #define ACP_I2S_COMP2_CAP_REG_OFFSET 0xa8 |
58 | #define ACP_I2S_COMP1_PLAY_REG_OFFSET 0x6c | 58 | #define ACP_I2S_COMP1_PLAY_REG_OFFSET 0x6c |
59 | #define ACP_I2S_COMP2_PLAY_REG_OFFSET 0x68 | 59 | #define ACP_I2S_COMP2_PLAY_REG_OFFSET 0x68 |
60 | 60 | ||
61 | #define mmACP_PGFSM_RETAIN_REG 0x51c9 | 61 | #define mmACP_PGFSM_RETAIN_REG 0x51c9 |
62 | #define mmACP_PGFSM_CONFIG_REG 0x51ca | 62 | #define mmACP_PGFSM_CONFIG_REG 0x51ca |
63 | #define mmACP_PGFSM_READ_REG_0 0x51cc | 63 | #define mmACP_PGFSM_READ_REG_0 0x51cc |
64 | 64 | ||
65 | #define mmACP_MEM_SHUT_DOWN_REQ_LO 0x51f8 | 65 | #define mmACP_MEM_SHUT_DOWN_REQ_LO 0x51f8 |
66 | #define mmACP_MEM_SHUT_DOWN_REQ_HI 0x51f9 | 66 | #define mmACP_MEM_SHUT_DOWN_REQ_HI 0x51f9 |
67 | #define mmACP_MEM_SHUT_DOWN_STS_LO 0x51fa | 67 | #define mmACP_MEM_SHUT_DOWN_STS_LO 0x51fa |
68 | #define mmACP_MEM_SHUT_DOWN_STS_HI 0x51fb | 68 | #define mmACP_MEM_SHUT_DOWN_STS_HI 0x51fb |
69 | 69 | ||
70 | #define ACP_TIMEOUT_LOOP 0x000000FF | 70 | #define mmACP_CONTROL 0x5131 |
71 | #define ACP_DEVS 3 | 71 | #define mmACP_STATUS 0x5133 |
72 | #define ACP_SRC_ID 162 | 72 | #define mmACP_SOFT_RESET 0x5134 |
73 | #define ACP_CONTROL__ClkEn_MASK 0x1 | ||
74 | #define ACP_SOFT_RESET__SoftResetAud_MASK 0x100 | ||
75 | #define ACP_SOFT_RESET__SoftResetAudDone_MASK 0x1000000 | ||
76 | #define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF | ||
77 | #define ACP_SOFT_RESET_DONE_TIME_OUT_VALUE 0x000000FF | ||
78 | |||
79 | #define ACP_TIMEOUT_LOOP 0x000000FF | ||
80 | #define ACP_DEVS 3 | ||
81 | #define ACP_SRC_ID 162 | ||
73 | 82 | ||
74 | enum { | 83 | enum { |
75 | ACP_TILE_P1 = 0, | 84 | ACP_TILE_P1 = 0, |
@@ -260,6 +269,8 @@ static int acp_hw_init(void *handle) | |||
260 | { | 269 | { |
261 | int r, i; | 270 | int r, i; |
262 | uint64_t acp_base; | 271 | uint64_t acp_base; |
272 | u32 val = 0; | ||
273 | u32 count = 0; | ||
263 | struct device *dev; | 274 | struct device *dev; |
264 | struct i2s_platform_data *i2s_pdata; | 275 | struct i2s_platform_data *i2s_pdata; |
265 | 276 | ||
@@ -371,6 +382,8 @@ static int acp_hw_init(void *handle) | |||
371 | adev->acp.acp_cell[0].name = "acp_audio_dma"; | 382 | adev->acp.acp_cell[0].name = "acp_audio_dma"; |
372 | adev->acp.acp_cell[0].num_resources = 4; | 383 | adev->acp.acp_cell[0].num_resources = 4; |
373 | adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0]; | 384 | adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0]; |
385 | adev->acp.acp_cell[0].platform_data = &adev->asic_type; | ||
386 | adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type); | ||
374 | 387 | ||
375 | adev->acp.acp_cell[1].name = "designware-i2s"; | 388 | adev->acp.acp_cell[1].name = "designware-i2s"; |
376 | adev->acp.acp_cell[1].num_resources = 1; | 389 | adev->acp.acp_cell[1].num_resources = 1; |
@@ -400,6 +413,46 @@ static int acp_hw_init(void *handle) | |||
400 | } | 413 | } |
401 | } | 414 | } |
402 | 415 | ||
416 | /* Assert Soft reset of ACP */ | ||
417 | val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); | ||
418 | |||
419 | val |= ACP_SOFT_RESET__SoftResetAud_MASK; | ||
420 | cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); | ||
421 | |||
422 | count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE; | ||
423 | while (true) { | ||
424 | val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); | ||
425 | if (ACP_SOFT_RESET__SoftResetAudDone_MASK == | ||
426 | (val & ACP_SOFT_RESET__SoftResetAudDone_MASK)) | ||
427 | break; | ||
428 | if (--count == 0) { | ||
429 | dev_err(&adev->pdev->dev, "Failed to reset ACP\n"); | ||
430 | return -ETIMEDOUT; | ||
431 | } | ||
432 | udelay(100); | ||
433 | } | ||
434 | /* Enable clock to ACP and wait until the clock is enabled */ | ||
435 | val = cgs_read_register(adev->acp.cgs_device, mmACP_CONTROL); | ||
436 | val = val | ACP_CONTROL__ClkEn_MASK; | ||
437 | cgs_write_register(adev->acp.cgs_device, mmACP_CONTROL, val); | ||
438 | |||
439 | count = ACP_CLOCK_EN_TIME_OUT_VALUE; | ||
440 | |||
441 | while (true) { | ||
442 | val = cgs_read_register(adev->acp.cgs_device, mmACP_STATUS); | ||
443 | if (val & (u32) 0x1) | ||
444 | break; | ||
445 | if (--count == 0) { | ||
446 | dev_err(&adev->pdev->dev, "Failed to reset ACP\n"); | ||
447 | return -ETIMEDOUT; | ||
448 | } | ||
449 | udelay(100); | ||
450 | } | ||
451 | /* Deassert the SOFT RESET flags */ | ||
452 | val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); | ||
453 | val &= ~ACP_SOFT_RESET__SoftResetAud_MASK; | ||
454 | cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); | ||
455 | |||
403 | return 0; | 456 | return 0; |
404 | } | 457 | } |
405 | 458 | ||
@@ -412,6 +465,8 @@ static int acp_hw_init(void *handle) | |||
412 | static int acp_hw_fini(void *handle) | 465 | static int acp_hw_fini(void *handle) |
413 | { | 466 | { |
414 | int i, ret; | 467 | int i, ret; |
468 | u32 val = 0; | ||
469 | u32 count = 0; | ||
415 | struct device *dev; | 470 | struct device *dev; |
416 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 471 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
417 | 472 | ||
@@ -419,6 +474,42 @@ static int acp_hw_fini(void *handle) | |||
419 | if (!adev->acp.acp_cell) | 474 | if (!adev->acp.acp_cell) |
420 | return 0; | 475 | return 0; |
421 | 476 | ||
477 | /* Assert Soft reset of ACP */ | ||
478 | val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); | ||
479 | |||
480 | val |= ACP_SOFT_RESET__SoftResetAud_MASK; | ||
481 | cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); | ||
482 | |||
483 | count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE; | ||
484 | while (true) { | ||
485 | val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); | ||
486 | if (ACP_SOFT_RESET__SoftResetAudDone_MASK == | ||
487 | (val & ACP_SOFT_RESET__SoftResetAudDone_MASK)) | ||
488 | break; | ||
489 | if (--count == 0) { | ||
490 | dev_err(&adev->pdev->dev, "Failed to reset ACP\n"); | ||
491 | return -ETIMEDOUT; | ||
492 | } | ||
493 | udelay(100); | ||
494 | } | ||
495 | /* Disable ACP clock */ | ||
496 | val = cgs_read_register(adev->acp.cgs_device, mmACP_CONTROL); | ||
497 | val &= ~ACP_CONTROL__ClkEn_MASK; | ||
498 | cgs_write_register(adev->acp.cgs_device, mmACP_CONTROL, val); | ||
499 | |||
500 | count = ACP_CLOCK_EN_TIME_OUT_VALUE; | ||
501 | |||
502 | while (true) { | ||
503 | val = cgs_read_register(adev->acp.cgs_device, mmACP_STATUS); | ||
504 | if (val & (u32) 0x1) | ||
505 | break; | ||
506 | if (--count == 0) { | ||
507 | dev_err(&adev->pdev->dev, "Failed to reset ACP\n"); | ||
508 | return -ETIMEDOUT; | ||
509 | } | ||
510 | udelay(100); | ||
511 | } | ||
512 | |||
422 | if (adev->acp.acp_genpd) { | 513 | if (adev->acp.acp_genpd) { |
423 | for (i = 0; i < ACP_DEVS ; i++) { | 514 | for (i = 0; i < ACP_DEVS ; i++) { |
424 | dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); | 515 | dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c index b9dbbf9cb8b0..47d1c132ac40 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | |||
@@ -169,6 +169,8 @@ static const struct kfd2kgd_calls kfd2kgd = { | |||
169 | .get_vmem_size = get_vmem_size, | 169 | .get_vmem_size = get_vmem_size, |
170 | .get_gpu_clock_counter = get_gpu_clock_counter, | 170 | .get_gpu_clock_counter = get_gpu_clock_counter, |
171 | .get_max_engine_clock_in_mhz = get_max_engine_clock_in_mhz, | 171 | .get_max_engine_clock_in_mhz = get_max_engine_clock_in_mhz, |
172 | .alloc_pasid = amdgpu_vm_alloc_pasid, | ||
173 | .free_pasid = amdgpu_vm_free_pasid, | ||
172 | .program_sh_mem_settings = kgd_program_sh_mem_settings, | 174 | .program_sh_mem_settings = kgd_program_sh_mem_settings, |
173 | .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping, | 175 | .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping, |
174 | .init_pipeline = kgd_init_pipeline, | 176 | .init_pipeline = kgd_init_pipeline, |
@@ -336,6 +338,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, | |||
336 | struct cik_mqd *m; | 338 | struct cik_mqd *m; |
337 | uint32_t *mqd_hqd; | 339 | uint32_t *mqd_hqd; |
338 | uint32_t reg, wptr_val, data; | 340 | uint32_t reg, wptr_val, data; |
341 | bool valid_wptr = false; | ||
339 | 342 | ||
340 | m = get_mqd(mqd); | 343 | m = get_mqd(mqd); |
341 | 344 | ||
@@ -354,7 +357,14 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, | |||
354 | CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1); | 357 | CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1); |
355 | WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, data); | 358 | WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, data); |
356 | 359 | ||
357 | if (read_user_wptr(mm, wptr, wptr_val)) | 360 | /* read_user_ptr may take the mm->mmap_sem. |
361 | * release srbm_mutex to avoid circular dependency between | ||
362 | * srbm_mutex->mm_sem->reservation_ww_class_mutex->srbm_mutex. | ||
363 | */ | ||
364 | release_queue(kgd); | ||
365 | valid_wptr = read_user_wptr(mm, wptr, wptr_val); | ||
366 | acquire_queue(kgd, pipe_id, queue_id); | ||
367 | if (valid_wptr) | ||
358 | WREG32(mmCP_HQD_PQ_WPTR, (wptr_val << wptr_shift) & wptr_mask); | 368 | WREG32(mmCP_HQD_PQ_WPTR, (wptr_val << wptr_shift) & wptr_mask); |
359 | 369 | ||
360 | data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1); | 370 | data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c index 309f2419c6d8..056929b8ccd0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | |||
@@ -128,6 +128,8 @@ static const struct kfd2kgd_calls kfd2kgd = { | |||
128 | .get_vmem_size = get_vmem_size, | 128 | .get_vmem_size = get_vmem_size, |
129 | .get_gpu_clock_counter = get_gpu_clock_counter, | 129 | .get_gpu_clock_counter = get_gpu_clock_counter, |
130 | .get_max_engine_clock_in_mhz = get_max_engine_clock_in_mhz, | 130 | .get_max_engine_clock_in_mhz = get_max_engine_clock_in_mhz, |
131 | .alloc_pasid = amdgpu_vm_alloc_pasid, | ||
132 | .free_pasid = amdgpu_vm_free_pasid, | ||
131 | .program_sh_mem_settings = kgd_program_sh_mem_settings, | 133 | .program_sh_mem_settings = kgd_program_sh_mem_settings, |
132 | .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping, | 134 | .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping, |
133 | .init_pipeline = kgd_init_pipeline, | 135 | .init_pipeline = kgd_init_pipeline, |
@@ -290,6 +292,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, | |||
290 | struct vi_mqd *m; | 292 | struct vi_mqd *m; |
291 | uint32_t *mqd_hqd; | 293 | uint32_t *mqd_hqd; |
292 | uint32_t reg, wptr_val, data; | 294 | uint32_t reg, wptr_val, data; |
295 | bool valid_wptr = false; | ||
293 | 296 | ||
294 | m = get_mqd(mqd); | 297 | m = get_mqd(mqd); |
295 | 298 | ||
@@ -337,7 +340,14 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, | |||
337 | CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1); | 340 | CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1); |
338 | WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, data); | 341 | WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, data); |
339 | 342 | ||
340 | if (read_user_wptr(mm, wptr, wptr_val)) | 343 | /* read_user_ptr may take the mm->mmap_sem. |
344 | * release srbm_mutex to avoid circular dependency between | ||
345 | * srbm_mutex->mm_sem->reservation_ww_class_mutex->srbm_mutex. | ||
346 | */ | ||
347 | release_queue(kgd); | ||
348 | valid_wptr = read_user_wptr(mm, wptr, wptr_val); | ||
349 | acquire_queue(kgd, pipe_id, queue_id); | ||
350 | if (valid_wptr) | ||
341 | WREG32(mmCP_HQD_PQ_WPTR, (wptr_val << wptr_shift) & wptr_mask); | 351 | WREG32(mmCP_HQD_PQ_WPTR, (wptr_val << wptr_shift) & wptr_mask); |
342 | 352 | ||
343 | data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1); | 353 | data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c index ce443586a0c7..f450b69323fa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | |||
@@ -1766,34 +1766,32 @@ bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev) | |||
1766 | return true; | 1766 | return true; |
1767 | } | 1767 | } |
1768 | 1768 | ||
1769 | /* Atom needs data in little endian format | 1769 | /* Atom needs data in little endian format so swap as appropriate when copying |
1770 | * so swap as appropriate when copying data to | 1770 | * data to or from atom. Note that atom operates on dw units. |
1771 | * or from atom. Note that atom operates on | 1771 | * |
1772 | * dw units. | 1772 | * Use to_le=true when sending data to atom and provide at least |
1773 | * ALIGN(num_bytes,4) bytes in the dst buffer. | ||
1774 | * | ||
1775 | * Use to_le=false when receiving data from atom and provide ALIGN(num_bytes,4) | ||
1776 | * byes in the src buffer. | ||
1773 | */ | 1777 | */ |
1774 | void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le) | 1778 | void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le) |
1775 | { | 1779 | { |
1776 | #ifdef __BIG_ENDIAN | 1780 | #ifdef __BIG_ENDIAN |
1777 | u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */ | 1781 | u32 src_tmp[5], dst_tmp[5]; |
1778 | u32 *dst32, *src32; | ||
1779 | int i; | 1782 | int i; |
1783 | u8 align_num_bytes = ALIGN(num_bytes, 4); | ||
1780 | 1784 | ||
1781 | memcpy(src_tmp, src, num_bytes); | ||
1782 | src32 = (u32 *)src_tmp; | ||
1783 | dst32 = (u32 *)dst_tmp; | ||
1784 | if (to_le) { | 1785 | if (to_le) { |
1785 | for (i = 0; i < ((num_bytes + 3) / 4); i++) | 1786 | memcpy(src_tmp, src, num_bytes); |
1786 | dst32[i] = cpu_to_le32(src32[i]); | 1787 | for (i = 0; i < align_num_bytes / 4; i++) |
1787 | memcpy(dst, dst_tmp, num_bytes); | 1788 | dst_tmp[i] = cpu_to_le32(src_tmp[i]); |
1789 | memcpy(dst, dst_tmp, align_num_bytes); | ||
1788 | } else { | 1790 | } else { |
1789 | u8 dws = num_bytes & ~3; | 1791 | memcpy(src_tmp, src, align_num_bytes); |
1790 | for (i = 0; i < ((num_bytes + 3) / 4); i++) | 1792 | for (i = 0; i < align_num_bytes / 4; i++) |
1791 | dst32[i] = le32_to_cpu(src32[i]); | 1793 | dst_tmp[i] = le32_to_cpu(src_tmp[i]); |
1792 | memcpy(dst, dst_tmp, dws); | 1794 | memcpy(dst, dst_tmp, num_bytes); |
1793 | if (num_bytes % 4) { | ||
1794 | for (i = 0; i < (num_bytes % 4); i++) | ||
1795 | dst[dws+i] = dst_tmp[dws+i]; | ||
1796 | } | ||
1797 | } | 1795 | } |
1798 | #else | 1796 | #else |
1799 | memcpy(dst, src, num_bytes); | 1797 | memcpy(dst, src, num_bytes); |
@@ -1807,6 +1805,8 @@ int amdgpu_atombios_allocate_fb_scratch(struct amdgpu_device *adev) | |||
1807 | uint16_t data_offset; | 1805 | uint16_t data_offset; |
1808 | int usage_bytes = 0; | 1806 | int usage_bytes = 0; |
1809 | struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage; | 1807 | struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage; |
1808 | u64 start_addr; | ||
1809 | u64 size; | ||
1810 | 1810 | ||
1811 | if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) { | 1811 | if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) { |
1812 | firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset); | 1812 | firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset); |
@@ -1815,7 +1815,21 @@ int amdgpu_atombios_allocate_fb_scratch(struct amdgpu_device *adev) | |||
1815 | le32_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware), | 1815 | le32_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware), |
1816 | le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb)); | 1816 | le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb)); |
1817 | 1817 | ||
1818 | usage_bytes = le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb) * 1024; | 1818 | start_addr = firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware; |
1819 | size = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb; | ||
1820 | |||
1821 | if ((uint32_t)(start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) == | ||
1822 | (uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION << | ||
1823 | ATOM_VRAM_OPERATION_FLAGS_SHIFT)) { | ||
1824 | /* Firmware request VRAM reservation for SR-IOV */ | ||
1825 | adev->fw_vram_usage.start_offset = (start_addr & | ||
1826 | (~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10; | ||
1827 | adev->fw_vram_usage.size = size << 10; | ||
1828 | /* Use the default scratch size */ | ||
1829 | usage_bytes = 0; | ||
1830 | } else { | ||
1831 | usage_bytes = le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb) * 1024; | ||
1832 | } | ||
1819 | } | 1833 | } |
1820 | ctx->scratch_size_bytes = 0; | 1834 | ctx->scratch_size_bytes = 0; |
1821 | if (usage_bytes == 0) | 1835 | if (usage_bytes == 0) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c index f9ffe8ef0cd6..ff8efd0f8fd5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c | |||
@@ -71,19 +71,33 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev) | |||
71 | struct atom_context *ctx = adev->mode_info.atom_context; | 71 | struct atom_context *ctx = adev->mode_info.atom_context; |
72 | int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, | 72 | int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, |
73 | vram_usagebyfirmware); | 73 | vram_usagebyfirmware); |
74 | struct vram_usagebyfirmware_v2_1 * firmware_usage; | ||
75 | uint32_t start_addr, size; | ||
74 | uint16_t data_offset; | 76 | uint16_t data_offset; |
75 | int usage_bytes = 0; | 77 | int usage_bytes = 0; |
76 | 78 | ||
77 | if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) { | 79 | if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) { |
78 | struct vram_usagebyfirmware_v2_1 *firmware_usage = | 80 | firmware_usage = (struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset); |
79 | (struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset); | ||
80 | |||
81 | DRM_DEBUG("atom firmware requested %08x %dkb fw %dkb drv\n", | 81 | DRM_DEBUG("atom firmware requested %08x %dkb fw %dkb drv\n", |
82 | le32_to_cpu(firmware_usage->start_address_in_kb), | 82 | le32_to_cpu(firmware_usage->start_address_in_kb), |
83 | le16_to_cpu(firmware_usage->used_by_firmware_in_kb), | 83 | le16_to_cpu(firmware_usage->used_by_firmware_in_kb), |
84 | le16_to_cpu(firmware_usage->used_by_driver_in_kb)); | 84 | le16_to_cpu(firmware_usage->used_by_driver_in_kb)); |
85 | 85 | ||
86 | usage_bytes = le16_to_cpu(firmware_usage->used_by_driver_in_kb) * 1024; | 86 | start_addr = le32_to_cpu(firmware_usage->start_address_in_kb); |
87 | size = le16_to_cpu(firmware_usage->used_by_firmware_in_kb); | ||
88 | |||
89 | if ((uint32_t)(start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) == | ||
90 | (uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION << | ||
91 | ATOM_VRAM_OPERATION_FLAGS_SHIFT)) { | ||
92 | /* Firmware request VRAM reservation for SR-IOV */ | ||
93 | adev->fw_vram_usage.start_offset = (start_addr & | ||
94 | (~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10; | ||
95 | adev->fw_vram_usage.size = size << 10; | ||
96 | /* Use the default scratch size */ | ||
97 | usage_bytes = 0; | ||
98 | } else { | ||
99 | usage_bytes = le16_to_cpu(firmware_usage->used_by_driver_in_kb) << 10; | ||
100 | } | ||
87 | } | 101 | } |
88 | ctx->scratch_size_bytes = 0; | 102 | ctx->scratch_size_bytes = 0; |
89 | if (usage_bytes == 0) | 103 | if (usage_bytes == 0) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c index c21adf60a7f2..057e1ecd83ce 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c | |||
@@ -59,12 +59,6 @@ static bool check_atom_bios(uint8_t *bios, size_t size) | |||
59 | return false; | 59 | return false; |
60 | } | 60 | } |
61 | 61 | ||
62 | tmp = bios[0x18] | (bios[0x19] << 8); | ||
63 | if (bios[tmp + 0x14] != 0x0) { | ||
64 | DRM_INFO("Not an x86 BIOS ROM\n"); | ||
65 | return false; | ||
66 | } | ||
67 | |||
68 | bios_header_start = bios[0x48] | (bios[0x49] << 8); | 62 | bios_header_start = bios[0x48] | (bios[0x49] << 8); |
69 | if (!bios_header_start) { | 63 | if (!bios_header_start) { |
70 | DRM_INFO("Can't locate bios header\n"); | 64 | DRM_INFO("Can't locate bios header\n"); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index fd435a96481c..f2b72c7c6857 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | |||
@@ -42,10 +42,31 @@ struct amdgpu_cgs_device { | |||
42 | struct amdgpu_device *adev = \ | 42 | struct amdgpu_device *adev = \ |
43 | ((struct amdgpu_cgs_device *)cgs_device)->adev | 43 | ((struct amdgpu_cgs_device *)cgs_device)->adev |
44 | 44 | ||
45 | static void *amdgpu_cgs_register_pp_handle(struct cgs_device *cgs_device, | ||
46 | int (*call_back_func)(struct amd_pp_init *, void **)) | ||
47 | { | ||
48 | CGS_FUNC_ADEV; | ||
49 | struct amd_pp_init pp_init; | ||
50 | struct amd_powerplay *amd_pp; | ||
51 | |||
52 | if (call_back_func == NULL) | ||
53 | return NULL; | ||
54 | |||
55 | amd_pp = &(adev->powerplay); | ||
56 | pp_init.chip_family = adev->family; | ||
57 | pp_init.chip_id = adev->asic_type; | ||
58 | pp_init.pm_en = (amdgpu_dpm != 0 && !amdgpu_sriov_vf(adev)) ? true : false; | ||
59 | pp_init.feature_mask = amdgpu_pp_feature_mask; | ||
60 | pp_init.device = cgs_device; | ||
61 | if (call_back_func(&pp_init, &(amd_pp->pp_handle))) | ||
62 | return NULL; | ||
63 | |||
64 | return adev->powerplay.pp_handle; | ||
65 | } | ||
66 | |||
45 | static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device, | 67 | static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device, |
46 | enum cgs_gpu_mem_type type, | 68 | enum cgs_gpu_mem_type type, |
47 | uint64_t size, uint64_t align, | 69 | uint64_t size, uint64_t align, |
48 | uint64_t min_offset, uint64_t max_offset, | ||
49 | cgs_handle_t *handle) | 70 | cgs_handle_t *handle) |
50 | { | 71 | { |
51 | CGS_FUNC_ADEV; | 72 | CGS_FUNC_ADEV; |
@@ -53,13 +74,6 @@ static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device, | |||
53 | int ret = 0; | 74 | int ret = 0; |
54 | uint32_t domain = 0; | 75 | uint32_t domain = 0; |
55 | struct amdgpu_bo *obj; | 76 | struct amdgpu_bo *obj; |
56 | struct ttm_placement placement; | ||
57 | struct ttm_place place; | ||
58 | |||
59 | if (min_offset > max_offset) { | ||
60 | BUG_ON(1); | ||
61 | return -EINVAL; | ||
62 | } | ||
63 | 77 | ||
64 | /* fail if the alignment is not a power of 2 */ | 78 | /* fail if the alignment is not a power of 2 */ |
65 | if (((align != 1) && (align & (align - 1))) | 79 | if (((align != 1) && (align & (align - 1))) |
@@ -73,41 +87,19 @@ static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device, | |||
73 | flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | | 87 | flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | |
74 | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; | 88 | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; |
75 | domain = AMDGPU_GEM_DOMAIN_VRAM; | 89 | domain = AMDGPU_GEM_DOMAIN_VRAM; |
76 | if (max_offset > adev->mc.real_vram_size) | ||
77 | return -EINVAL; | ||
78 | place.fpfn = min_offset >> PAGE_SHIFT; | ||
79 | place.lpfn = max_offset >> PAGE_SHIFT; | ||
80 | place.flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | | ||
81 | TTM_PL_FLAG_VRAM; | ||
82 | break; | 90 | break; |
83 | case CGS_GPU_MEM_TYPE__INVISIBLE_CONTIG_FB: | 91 | case CGS_GPU_MEM_TYPE__INVISIBLE_CONTIG_FB: |
84 | case CGS_GPU_MEM_TYPE__INVISIBLE_FB: | 92 | case CGS_GPU_MEM_TYPE__INVISIBLE_FB: |
85 | flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS | | 93 | flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS | |
86 | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; | 94 | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; |
87 | domain = AMDGPU_GEM_DOMAIN_VRAM; | 95 | domain = AMDGPU_GEM_DOMAIN_VRAM; |
88 | if (adev->mc.visible_vram_size < adev->mc.real_vram_size) { | ||
89 | place.fpfn = | ||
90 | max(min_offset, adev->mc.visible_vram_size) >> PAGE_SHIFT; | ||
91 | place.lpfn = | ||
92 | min(max_offset, adev->mc.real_vram_size) >> PAGE_SHIFT; | ||
93 | place.flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | | ||
94 | TTM_PL_FLAG_VRAM; | ||
95 | } | ||
96 | |||
97 | break; | 96 | break; |
98 | case CGS_GPU_MEM_TYPE__GART_CACHEABLE: | 97 | case CGS_GPU_MEM_TYPE__GART_CACHEABLE: |
99 | domain = AMDGPU_GEM_DOMAIN_GTT; | 98 | domain = AMDGPU_GEM_DOMAIN_GTT; |
100 | place.fpfn = min_offset >> PAGE_SHIFT; | ||
101 | place.lpfn = max_offset >> PAGE_SHIFT; | ||
102 | place.flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_TT; | ||
103 | break; | 99 | break; |
104 | case CGS_GPU_MEM_TYPE__GART_WRITECOMBINE: | 100 | case CGS_GPU_MEM_TYPE__GART_WRITECOMBINE: |
105 | flags = AMDGPU_GEM_CREATE_CPU_GTT_USWC; | 101 | flags = AMDGPU_GEM_CREATE_CPU_GTT_USWC; |
106 | domain = AMDGPU_GEM_DOMAIN_GTT; | 102 | domain = AMDGPU_GEM_DOMAIN_GTT; |
107 | place.fpfn = min_offset >> PAGE_SHIFT; | ||
108 | place.lpfn = max_offset >> PAGE_SHIFT; | ||
109 | place.flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_TT | | ||
110 | TTM_PL_FLAG_UNCACHED; | ||
111 | break; | 103 | break; |
112 | default: | 104 | default: |
113 | return -EINVAL; | 105 | return -EINVAL; |
@@ -116,15 +108,8 @@ static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device, | |||
116 | 108 | ||
117 | *handle = 0; | 109 | *handle = 0; |
118 | 110 | ||
119 | placement.placement = &place; | 111 | ret = amdgpu_bo_create(adev, size, align, true, domain, flags, |
120 | placement.num_placement = 1; | 112 | NULL, NULL, 0, &obj); |
121 | placement.busy_placement = &place; | ||
122 | placement.num_busy_placement = 1; | ||
123 | |||
124 | ret = amdgpu_bo_create_restricted(adev, size, PAGE_SIZE, | ||
125 | true, domain, flags, | ||
126 | NULL, &placement, NULL, | ||
127 | 0, &obj); | ||
128 | if (ret) { | 113 | if (ret) { |
129 | DRM_ERROR("(%d) bo create failed\n", ret); | 114 | DRM_ERROR("(%d) bo create failed\n", ret); |
130 | return ret; | 115 | return ret; |
@@ -155,19 +140,14 @@ static int amdgpu_cgs_gmap_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t h | |||
155 | uint64_t *mcaddr) | 140 | uint64_t *mcaddr) |
156 | { | 141 | { |
157 | int r; | 142 | int r; |
158 | u64 min_offset, max_offset; | ||
159 | struct amdgpu_bo *obj = (struct amdgpu_bo *)handle; | 143 | struct amdgpu_bo *obj = (struct amdgpu_bo *)handle; |
160 | 144 | ||
161 | WARN_ON_ONCE(obj->placement.num_placement > 1); | 145 | WARN_ON_ONCE(obj->placement.num_placement > 1); |
162 | 146 | ||
163 | min_offset = obj->placements[0].fpfn << PAGE_SHIFT; | ||
164 | max_offset = obj->placements[0].lpfn << PAGE_SHIFT; | ||
165 | |||
166 | r = amdgpu_bo_reserve(obj, true); | 147 | r = amdgpu_bo_reserve(obj, true); |
167 | if (unlikely(r != 0)) | 148 | if (unlikely(r != 0)) |
168 | return r; | 149 | return r; |
169 | r = amdgpu_bo_pin_restricted(obj, obj->preferred_domains, | 150 | r = amdgpu_bo_pin(obj, obj->preferred_domains, mcaddr); |
170 | min_offset, max_offset, mcaddr); | ||
171 | amdgpu_bo_unreserve(obj); | 151 | amdgpu_bo_unreserve(obj); |
172 | return r; | 152 | return r; |
173 | } | 153 | } |
@@ -675,6 +655,85 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, | |||
675 | 655 | ||
676 | if (!adev->pm.fw) { | 656 | if (!adev->pm.fw) { |
677 | switch (adev->asic_type) { | 657 | switch (adev->asic_type) { |
658 | case CHIP_TAHITI: | ||
659 | strcpy(fw_name, "radeon/tahiti_smc.bin"); | ||
660 | break; | ||
661 | case CHIP_PITCAIRN: | ||
662 | if ((adev->pdev->revision == 0x81) && | ||
663 | ((adev->pdev->device == 0x6810) || | ||
664 | (adev->pdev->device == 0x6811))) { | ||
665 | info->is_kicker = true; | ||
666 | strcpy(fw_name, "radeon/pitcairn_k_smc.bin"); | ||
667 | } else { | ||
668 | strcpy(fw_name, "radeon/pitcairn_smc.bin"); | ||
669 | } | ||
670 | break; | ||
671 | case CHIP_VERDE: | ||
672 | if (((adev->pdev->device == 0x6820) && | ||
673 | ((adev->pdev->revision == 0x81) || | ||
674 | (adev->pdev->revision == 0x83))) || | ||
675 | ((adev->pdev->device == 0x6821) && | ||
676 | ((adev->pdev->revision == 0x83) || | ||
677 | (adev->pdev->revision == 0x87))) || | ||
678 | ((adev->pdev->revision == 0x87) && | ||
679 | ((adev->pdev->device == 0x6823) || | ||
680 | (adev->pdev->device == 0x682b)))) { | ||
681 | info->is_kicker = true; | ||
682 | strcpy(fw_name, "radeon/verde_k_smc.bin"); | ||
683 | } else { | ||
684 | strcpy(fw_name, "radeon/verde_smc.bin"); | ||
685 | } | ||
686 | break; | ||
687 | case CHIP_OLAND: | ||
688 | if (((adev->pdev->revision == 0x81) && | ||
689 | ((adev->pdev->device == 0x6600) || | ||
690 | (adev->pdev->device == 0x6604) || | ||
691 | (adev->pdev->device == 0x6605) || | ||
692 | (adev->pdev->device == 0x6610))) || | ||
693 | ((adev->pdev->revision == 0x83) && | ||
694 | (adev->pdev->device == 0x6610))) { | ||
695 | info->is_kicker = true; | ||
696 | strcpy(fw_name, "radeon/oland_k_smc.bin"); | ||
697 | } else { | ||
698 | strcpy(fw_name, "radeon/oland_smc.bin"); | ||
699 | } | ||
700 | break; | ||
701 | case CHIP_HAINAN: | ||
702 | if (((adev->pdev->revision == 0x81) && | ||
703 | (adev->pdev->device == 0x6660)) || | ||
704 | ((adev->pdev->revision == 0x83) && | ||
705 | ((adev->pdev->device == 0x6660) || | ||
706 | (adev->pdev->device == 0x6663) || | ||
707 | (adev->pdev->device == 0x6665) || | ||
708 | (adev->pdev->device == 0x6667)))) { | ||
709 | info->is_kicker = true; | ||
710 | strcpy(fw_name, "radeon/hainan_k_smc.bin"); | ||
711 | } else if ((adev->pdev->revision == 0xc3) && | ||
712 | (adev->pdev->device == 0x6665)) { | ||
713 | info->is_kicker = true; | ||
714 | strcpy(fw_name, "radeon/banks_k_2_smc.bin"); | ||
715 | } else { | ||
716 | strcpy(fw_name, "radeon/hainan_smc.bin"); | ||
717 | } | ||
718 | break; | ||
719 | case CHIP_BONAIRE: | ||
720 | if ((adev->pdev->revision == 0x80) || | ||
721 | (adev->pdev->revision == 0x81) || | ||
722 | (adev->pdev->device == 0x665f)) { | ||
723 | info->is_kicker = true; | ||
724 | strcpy(fw_name, "radeon/bonaire_k_smc.bin"); | ||
725 | } else { | ||
726 | strcpy(fw_name, "radeon/bonaire_smc.bin"); | ||
727 | } | ||
728 | break; | ||
729 | case CHIP_HAWAII: | ||
730 | if (adev->pdev->revision == 0x80) { | ||
731 | info->is_kicker = true; | ||
732 | strcpy(fw_name, "radeon/hawaii_k_smc.bin"); | ||
733 | } else { | ||
734 | strcpy(fw_name, "radeon/hawaii_smc.bin"); | ||
735 | } | ||
736 | break; | ||
678 | case CHIP_TOPAZ: | 737 | case CHIP_TOPAZ: |
679 | if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) || | 738 | if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) || |
680 | ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) || | 739 | ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) || |
@@ -838,6 +897,9 @@ static int amdgpu_cgs_query_system_info(struct cgs_device *cgs_device, | |||
838 | case CGS_SYSTEM_INFO_PCIE_SUB_SYS_VENDOR_ID: | 897 | case CGS_SYSTEM_INFO_PCIE_SUB_SYS_VENDOR_ID: |
839 | sys_info->value = adev->pdev->subsystem_vendor; | 898 | sys_info->value = adev->pdev->subsystem_vendor; |
840 | break; | 899 | break; |
900 | case CGS_SYSTEM_INFO_PCIE_BUS_DEVFN: | ||
901 | sys_info->value = adev->pdev->devfn; | ||
902 | break; | ||
841 | default: | 903 | default: |
842 | return -ENODEV; | 904 | return -ENODEV; |
843 | } | 905 | } |
@@ -849,10 +911,6 @@ static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device, | |||
849 | struct cgs_display_info *info) | 911 | struct cgs_display_info *info) |
850 | { | 912 | { |
851 | CGS_FUNC_ADEV; | 913 | CGS_FUNC_ADEV; |
852 | struct amdgpu_crtc *amdgpu_crtc; | ||
853 | struct drm_device *ddev = adev->ddev; | ||
854 | struct drm_crtc *crtc; | ||
855 | uint32_t line_time_us, vblank_lines; | ||
856 | struct cgs_mode_info *mode_info; | 914 | struct cgs_mode_info *mode_info; |
857 | 915 | ||
858 | if (info == NULL) | 916 | if (info == NULL) |
@@ -866,30 +924,43 @@ static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device, | |||
866 | mode_info->ref_clock = adev->clock.spll.reference_freq; | 924 | mode_info->ref_clock = adev->clock.spll.reference_freq; |
867 | } | 925 | } |
868 | 926 | ||
869 | if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) { | 927 | if (!amdgpu_device_has_dc_support(adev)) { |
870 | list_for_each_entry(crtc, | 928 | struct amdgpu_crtc *amdgpu_crtc; |
871 | &ddev->mode_config.crtc_list, head) { | 929 | struct drm_device *ddev = adev->ddev; |
872 | amdgpu_crtc = to_amdgpu_crtc(crtc); | 930 | struct drm_crtc *crtc; |
873 | if (crtc->enabled) { | 931 | uint32_t line_time_us, vblank_lines; |
874 | info->active_display_mask |= (1 << amdgpu_crtc->crtc_id); | 932 | |
875 | info->display_count++; | 933 | if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) { |
876 | } | 934 | list_for_each_entry(crtc, |
877 | if (mode_info != NULL && | 935 | &ddev->mode_config.crtc_list, head) { |
878 | crtc->enabled && amdgpu_crtc->enabled && | 936 | amdgpu_crtc = to_amdgpu_crtc(crtc); |
879 | amdgpu_crtc->hw_mode.clock) { | 937 | if (crtc->enabled) { |
880 | line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) / | 938 | info->active_display_mask |= (1 << amdgpu_crtc->crtc_id); |
881 | amdgpu_crtc->hw_mode.clock; | 939 | info->display_count++; |
882 | vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end - | 940 | } |
883 | amdgpu_crtc->hw_mode.crtc_vdisplay + | 941 | if (mode_info != NULL && |
884 | (amdgpu_crtc->v_border * 2); | 942 | crtc->enabled && amdgpu_crtc->enabled && |
885 | mode_info->vblank_time_us = vblank_lines * line_time_us; | 943 | amdgpu_crtc->hw_mode.clock) { |
886 | mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode); | 944 | line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) / |
887 | mode_info->ref_clock = adev->clock.spll.reference_freq; | 945 | amdgpu_crtc->hw_mode.clock; |
888 | mode_info = NULL; | 946 | vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end - |
947 | amdgpu_crtc->hw_mode.crtc_vdisplay + | ||
948 | (amdgpu_crtc->v_border * 2); | ||
949 | mode_info->vblank_time_us = vblank_lines * line_time_us; | ||
950 | mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode); | ||
951 | mode_info->ref_clock = adev->clock.spll.reference_freq; | ||
952 | mode_info = NULL; | ||
953 | } | ||
889 | } | 954 | } |
890 | } | 955 | } |
956 | } else { | ||
957 | info->display_count = adev->pm.pm_display_cfg.num_display; | ||
958 | if (mode_info != NULL) { | ||
959 | mode_info->vblank_time_us = adev->pm.pm_display_cfg.min_vblank_time; | ||
960 | mode_info->refresh_rate = adev->pm.pm_display_cfg.vrefresh; | ||
961 | mode_info->ref_clock = adev->clock.spll.reference_freq; | ||
962 | } | ||
891 | } | 963 | } |
892 | |||
893 | return 0; | 964 | return 0; |
894 | } | 965 | } |
895 | 966 | ||
@@ -1139,6 +1210,7 @@ static const struct cgs_ops amdgpu_cgs_ops = { | |||
1139 | .is_virtualization_enabled = amdgpu_cgs_is_virtualization_enabled, | 1210 | .is_virtualization_enabled = amdgpu_cgs_is_virtualization_enabled, |
1140 | .enter_safe_mode = amdgpu_cgs_enter_safe_mode, | 1211 | .enter_safe_mode = amdgpu_cgs_enter_safe_mode, |
1141 | .lock_grbm_idx = amdgpu_cgs_lock_grbm_idx, | 1212 | .lock_grbm_idx = amdgpu_cgs_lock_grbm_idx, |
1213 | .register_pp_handle = amdgpu_cgs_register_pp_handle, | ||
1142 | }; | 1214 | }; |
1143 | 1215 | ||
1144 | static const struct cgs_os_ops amdgpu_cgs_os_ops = { | 1216 | static const struct cgs_os_ops amdgpu_cgs_os_ops = { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index 8d1cf2d3e663..df9cbc78e168 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | |||
@@ -231,7 +231,7 @@ amdgpu_connector_update_scratch_regs(struct drm_connector *connector, | |||
231 | if (connector->encoder_ids[i] == 0) | 231 | if (connector->encoder_ids[i] == 0) |
232 | break; | 232 | break; |
233 | 233 | ||
234 | encoder = drm_encoder_find(connector->dev, | 234 | encoder = drm_encoder_find(connector->dev, NULL, |
235 | connector->encoder_ids[i]); | 235 | connector->encoder_ids[i]); |
236 | if (!encoder) | 236 | if (!encoder) |
237 | continue; | 237 | continue; |
@@ -256,7 +256,7 @@ amdgpu_connector_find_encoder(struct drm_connector *connector, | |||
256 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { | 256 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
257 | if (connector->encoder_ids[i] == 0) | 257 | if (connector->encoder_ids[i] == 0) |
258 | break; | 258 | break; |
259 | encoder = drm_encoder_find(connector->dev, | 259 | encoder = drm_encoder_find(connector->dev, NULL, |
260 | connector->encoder_ids[i]); | 260 | connector->encoder_ids[i]); |
261 | if (!encoder) | 261 | if (!encoder) |
262 | continue; | 262 | continue; |
@@ -346,10 +346,8 @@ static void amdgpu_connector_free_edid(struct drm_connector *connector) | |||
346 | { | 346 | { |
347 | struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); | 347 | struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); |
348 | 348 | ||
349 | if (amdgpu_connector->edid) { | 349 | kfree(amdgpu_connector->edid); |
350 | kfree(amdgpu_connector->edid); | 350 | amdgpu_connector->edid = NULL; |
351 | amdgpu_connector->edid = NULL; | ||
352 | } | ||
353 | } | 351 | } |
354 | 352 | ||
355 | static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector) | 353 | static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector) |
@@ -374,7 +372,7 @@ amdgpu_connector_best_single_encoder(struct drm_connector *connector) | |||
374 | 372 | ||
375 | /* pick the encoder ids */ | 373 | /* pick the encoder ids */ |
376 | if (enc_id) | 374 | if (enc_id) |
377 | return drm_encoder_find(connector->dev, enc_id); | 375 | return drm_encoder_find(connector->dev, NULL, enc_id); |
378 | return NULL; | 376 | return NULL; |
379 | } | 377 | } |
380 | 378 | ||
@@ -1079,7 +1077,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force) | |||
1079 | if (connector->encoder_ids[i] == 0) | 1077 | if (connector->encoder_ids[i] == 0) |
1080 | break; | 1078 | break; |
1081 | 1079 | ||
1082 | encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]); | 1080 | encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]); |
1083 | if (!encoder) | 1081 | if (!encoder) |
1084 | continue; | 1082 | continue; |
1085 | 1083 | ||
@@ -1136,7 +1134,7 @@ amdgpu_connector_dvi_encoder(struct drm_connector *connector) | |||
1136 | if (connector->encoder_ids[i] == 0) | 1134 | if (connector->encoder_ids[i] == 0) |
1137 | break; | 1135 | break; |
1138 | 1136 | ||
1139 | encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]); | 1137 | encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]); |
1140 | if (!encoder) | 1138 | if (!encoder) |
1141 | continue; | 1139 | continue; |
1142 | 1140 | ||
@@ -1155,7 +1153,7 @@ amdgpu_connector_dvi_encoder(struct drm_connector *connector) | |||
1155 | /* then check use digitial */ | 1153 | /* then check use digitial */ |
1156 | /* pick the first one */ | 1154 | /* pick the first one */ |
1157 | if (enc_id) | 1155 | if (enc_id) |
1158 | return drm_encoder_find(connector->dev, enc_id); | 1156 | return drm_encoder_find(connector->dev, NULL, enc_id); |
1159 | return NULL; | 1157 | return NULL; |
1160 | } | 1158 | } |
1161 | 1159 | ||
@@ -1296,7 +1294,7 @@ u16 amdgpu_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *conn | |||
1296 | if (connector->encoder_ids[i] == 0) | 1294 | if (connector->encoder_ids[i] == 0) |
1297 | break; | 1295 | break; |
1298 | 1296 | ||
1299 | encoder = drm_encoder_find(connector->dev, | 1297 | encoder = drm_encoder_find(connector->dev, NULL, |
1300 | connector->encoder_ids[i]); | 1298 | connector->encoder_ids[i]); |
1301 | if (!encoder) | 1299 | if (!encoder) |
1302 | continue; | 1300 | continue; |
@@ -1325,7 +1323,7 @@ static bool amdgpu_connector_encoder_is_hbr2(struct drm_connector *connector) | |||
1325 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { | 1323 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
1326 | if (connector->encoder_ids[i] == 0) | 1324 | if (connector->encoder_ids[i] == 0) |
1327 | break; | 1325 | break; |
1328 | encoder = drm_encoder_find(connector->dev, | 1326 | encoder = drm_encoder_find(connector->dev, NULL, |
1329 | connector->encoder_ids[i]); | 1327 | connector->encoder_ids[i]); |
1330 | if (!encoder) | 1328 | if (!encoder) |
1331 | continue; | 1329 | continue; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 60d8bedb694d..a57cec737c18 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -25,6 +25,7 @@ | |||
25 | * Jerome Glisse <glisse@freedesktop.org> | 25 | * Jerome Glisse <glisse@freedesktop.org> |
26 | */ | 26 | */ |
27 | #include <linux/pagemap.h> | 27 | #include <linux/pagemap.h> |
28 | #include <linux/sync_file.h> | ||
28 | #include <drm/drmP.h> | 29 | #include <drm/drmP.h> |
29 | #include <drm/amdgpu_drm.h> | 30 | #include <drm/amdgpu_drm.h> |
30 | #include <drm/drm_syncobj.h> | 31 | #include <drm/drm_syncobj.h> |
@@ -89,12 +90,14 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | |||
89 | goto free_chunk; | 90 | goto free_chunk; |
90 | } | 91 | } |
91 | 92 | ||
93 | mutex_lock(&p->ctx->lock); | ||
94 | |||
92 | /* get chunks */ | 95 | /* get chunks */ |
93 | chunk_array_user = u64_to_user_ptr(cs->in.chunks); | 96 | chunk_array_user = u64_to_user_ptr(cs->in.chunks); |
94 | if (copy_from_user(chunk_array, chunk_array_user, | 97 | if (copy_from_user(chunk_array, chunk_array_user, |
95 | sizeof(uint64_t)*cs->in.num_chunks)) { | 98 | sizeof(uint64_t)*cs->in.num_chunks)) { |
96 | ret = -EFAULT; | 99 | ret = -EFAULT; |
97 | goto put_ctx; | 100 | goto free_chunk; |
98 | } | 101 | } |
99 | 102 | ||
100 | p->nchunks = cs->in.num_chunks; | 103 | p->nchunks = cs->in.num_chunks; |
@@ -102,7 +105,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | |||
102 | GFP_KERNEL); | 105 | GFP_KERNEL); |
103 | if (!p->chunks) { | 106 | if (!p->chunks) { |
104 | ret = -ENOMEM; | 107 | ret = -ENOMEM; |
105 | goto put_ctx; | 108 | goto free_chunk; |
106 | } | 109 | } |
107 | 110 | ||
108 | for (i = 0; i < p->nchunks; i++) { | 111 | for (i = 0; i < p->nchunks; i++) { |
@@ -169,6 +172,11 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | |||
169 | if (ret) | 172 | if (ret) |
170 | goto free_all_kdata; | 173 | goto free_all_kdata; |
171 | 174 | ||
175 | if (p->ctx->vram_lost_counter != p->job->vram_lost_counter) { | ||
176 | ret = -ECANCELED; | ||
177 | goto free_all_kdata; | ||
178 | } | ||
179 | |||
172 | if (p->uf_entry.robj) | 180 | if (p->uf_entry.robj) |
173 | p->job->uf_addr = uf_offset; | 181 | p->job->uf_addr = uf_offset; |
174 | kfree(chunk_array); | 182 | kfree(chunk_array); |
@@ -182,8 +190,6 @@ free_partial_kdata: | |||
182 | kfree(p->chunks); | 190 | kfree(p->chunks); |
183 | p->chunks = NULL; | 191 | p->chunks = NULL; |
184 | p->nchunks = 0; | 192 | p->nchunks = 0; |
185 | put_ctx: | ||
186 | amdgpu_ctx_put(p->ctx); | ||
187 | free_chunk: | 193 | free_chunk: |
188 | kfree(chunk_array); | 194 | kfree(chunk_array); |
189 | 195 | ||
@@ -473,11 +479,16 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, | |||
473 | return -EPERM; | 479 | return -EPERM; |
474 | 480 | ||
475 | /* Check if we have user pages and nobody bound the BO already */ | 481 | /* Check if we have user pages and nobody bound the BO already */ |
476 | if (lobj->user_pages && bo->tbo.ttm->state != tt_bound) { | 482 | if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm) && |
477 | size_t size = sizeof(struct page *); | 483 | lobj->user_pages) { |
478 | 484 | amdgpu_ttm_placement_from_domain(bo, | |
479 | size *= bo->tbo.ttm->num_pages; | 485 | AMDGPU_GEM_DOMAIN_CPU); |
480 | memcpy(bo->tbo.ttm->pages, lobj->user_pages, size); | 486 | r = ttm_bo_validate(&bo->tbo, &bo->placement, true, |
487 | false); | ||
488 | if (r) | ||
489 | return r; | ||
490 | amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, | ||
491 | lobj->user_pages); | ||
481 | binding_userptr = true; | 492 | binding_userptr = true; |
482 | } | 493 | } |
483 | 494 | ||
@@ -502,7 +513,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
502 | struct amdgpu_fpriv *fpriv = p->filp->driver_priv; | 513 | struct amdgpu_fpriv *fpriv = p->filp->driver_priv; |
503 | struct amdgpu_bo_list_entry *e; | 514 | struct amdgpu_bo_list_entry *e; |
504 | struct list_head duplicates; | 515 | struct list_head duplicates; |
505 | bool need_mmap_lock = false; | ||
506 | unsigned i, tries = 10; | 516 | unsigned i, tries = 10; |
507 | int r; | 517 | int r; |
508 | 518 | ||
@@ -510,9 +520,9 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
510 | 520 | ||
511 | p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); | 521 | p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); |
512 | if (p->bo_list) { | 522 | if (p->bo_list) { |
513 | need_mmap_lock = p->bo_list->first_userptr != | ||
514 | p->bo_list->num_entries; | ||
515 | amdgpu_bo_list_get_list(p->bo_list, &p->validated); | 523 | amdgpu_bo_list_get_list(p->bo_list, &p->validated); |
524 | if (p->bo_list->first_userptr != p->bo_list->num_entries) | ||
525 | p->mn = amdgpu_mn_get(p->adev); | ||
516 | } | 526 | } |
517 | 527 | ||
518 | INIT_LIST_HEAD(&duplicates); | 528 | INIT_LIST_HEAD(&duplicates); |
@@ -521,9 +531,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
521 | if (p->uf_entry.robj) | 531 | if (p->uf_entry.robj) |
522 | list_add(&p->uf_entry.tv.head, &p->validated); | 532 | list_add(&p->uf_entry.tv.head, &p->validated); |
523 | 533 | ||
524 | if (need_mmap_lock) | ||
525 | down_read(¤t->mm->mmap_sem); | ||
526 | |||
527 | while (1) { | 534 | while (1) { |
528 | struct list_head need_pages; | 535 | struct list_head need_pages; |
529 | unsigned i; | 536 | unsigned i; |
@@ -543,23 +550,24 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
543 | INIT_LIST_HEAD(&need_pages); | 550 | INIT_LIST_HEAD(&need_pages); |
544 | for (i = p->bo_list->first_userptr; | 551 | for (i = p->bo_list->first_userptr; |
545 | i < p->bo_list->num_entries; ++i) { | 552 | i < p->bo_list->num_entries; ++i) { |
553 | struct amdgpu_bo *bo; | ||
546 | 554 | ||
547 | e = &p->bo_list->array[i]; | 555 | e = &p->bo_list->array[i]; |
556 | bo = e->robj; | ||
548 | 557 | ||
549 | if (amdgpu_ttm_tt_userptr_invalidated(e->robj->tbo.ttm, | 558 | if (amdgpu_ttm_tt_userptr_invalidated(bo->tbo.ttm, |
550 | &e->user_invalidated) && e->user_pages) { | 559 | &e->user_invalidated) && e->user_pages) { |
551 | 560 | ||
552 | /* We acquired a page array, but somebody | 561 | /* We acquired a page array, but somebody |
553 | * invalidated it. Free it and try again | 562 | * invalidated it. Free it and try again |
554 | */ | 563 | */ |
555 | release_pages(e->user_pages, | 564 | release_pages(e->user_pages, |
556 | e->robj->tbo.ttm->num_pages, | 565 | bo->tbo.ttm->num_pages); |
557 | false); | ||
558 | kvfree(e->user_pages); | 566 | kvfree(e->user_pages); |
559 | e->user_pages = NULL; | 567 | e->user_pages = NULL; |
560 | } | 568 | } |
561 | 569 | ||
562 | if (e->robj->tbo.ttm->state != tt_bound && | 570 | if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm) && |
563 | !e->user_pages) { | 571 | !e->user_pages) { |
564 | list_del(&e->tv.head); | 572 | list_del(&e->tv.head); |
565 | list_add(&e->tv.head, &need_pages); | 573 | list_add(&e->tv.head, &need_pages); |
@@ -636,9 +644,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
636 | 644 | ||
637 | amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved, | 645 | amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved, |
638 | p->bytes_moved_vis); | 646 | p->bytes_moved_vis); |
639 | fpriv->vm.last_eviction_counter = | ||
640 | atomic64_read(&p->adev->num_evictions); | ||
641 | |||
642 | if (p->bo_list) { | 647 | if (p->bo_list) { |
643 | struct amdgpu_bo *gds = p->bo_list->gds_obj; | 648 | struct amdgpu_bo *gds = p->bo_list->gds_obj; |
644 | struct amdgpu_bo *gws = p->bo_list->gws_obj; | 649 | struct amdgpu_bo *gws = p->bo_list->gws_obj; |
@@ -679,9 +684,6 @@ error_validate: | |||
679 | 684 | ||
680 | error_free_pages: | 685 | error_free_pages: |
681 | 686 | ||
682 | if (need_mmap_lock) | ||
683 | up_read(¤t->mm->mmap_sem); | ||
684 | |||
685 | if (p->bo_list) { | 687 | if (p->bo_list) { |
686 | for (i = p->bo_list->first_userptr; | 688 | for (i = p->bo_list->first_userptr; |
687 | i < p->bo_list->num_entries; ++i) { | 689 | i < p->bo_list->num_entries; ++i) { |
@@ -691,8 +693,7 @@ error_free_pages: | |||
691 | continue; | 693 | continue; |
692 | 694 | ||
693 | release_pages(e->user_pages, | 695 | release_pages(e->user_pages, |
694 | e->robj->tbo.ttm->num_pages, | 696 | e->robj->tbo.ttm->num_pages); |
695 | false); | ||
696 | kvfree(e->user_pages); | 697 | kvfree(e->user_pages); |
697 | } | 698 | } |
698 | } | 699 | } |
@@ -707,7 +708,8 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p) | |||
707 | 708 | ||
708 | list_for_each_entry(e, &p->validated, tv.head) { | 709 | list_for_each_entry(e, &p->validated, tv.head) { |
709 | struct reservation_object *resv = e->robj->tbo.resv; | 710 | struct reservation_object *resv = e->robj->tbo.resv; |
710 | r = amdgpu_sync_resv(p->adev, &p->job->sync, resv, p->filp); | 711 | r = amdgpu_sync_resv(p->adev, &p->job->sync, resv, p->filp, |
712 | amdgpu_bo_explicit_sync(e->robj)); | ||
711 | 713 | ||
712 | if (r) | 714 | if (r) |
713 | return r; | 715 | return r; |
@@ -728,11 +730,7 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, | |||
728 | { | 730 | { |
729 | unsigned i; | 731 | unsigned i; |
730 | 732 | ||
731 | if (!error) | 733 | if (error && backoff) |
732 | ttm_eu_fence_buffer_objects(&parser->ticket, | ||
733 | &parser->validated, | ||
734 | parser->fence); | ||
735 | else if (backoff) | ||
736 | ttm_eu_backoff_reservation(&parser->ticket, | 734 | ttm_eu_backoff_reservation(&parser->ticket, |
737 | &parser->validated); | 735 | &parser->validated); |
738 | 736 | ||
@@ -742,8 +740,10 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, | |||
742 | 740 | ||
743 | dma_fence_put(parser->fence); | 741 | dma_fence_put(parser->fence); |
744 | 742 | ||
745 | if (parser->ctx) | 743 | if (parser->ctx) { |
744 | mutex_unlock(&parser->ctx->lock); | ||
746 | amdgpu_ctx_put(parser->ctx); | 745 | amdgpu_ctx_put(parser->ctx); |
746 | } | ||
747 | if (parser->bo_list) | 747 | if (parser->bo_list) |
748 | amdgpu_bo_list_put(parser->bo_list); | 748 | amdgpu_bo_list_put(parser->bo_list); |
749 | 749 | ||
@@ -768,10 +768,6 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p) | |||
768 | if (r) | 768 | if (r) |
769 | return r; | 769 | return r; |
770 | 770 | ||
771 | r = amdgpu_sync_fence(adev, &p->job->sync, vm->last_dir_update); | ||
772 | if (r) | ||
773 | return r; | ||
774 | |||
775 | r = amdgpu_vm_clear_freed(adev, vm, NULL); | 771 | r = amdgpu_vm_clear_freed(adev, vm, NULL); |
776 | if (r) | 772 | if (r) |
777 | return r; | 773 | return r; |
@@ -825,7 +821,13 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p) | |||
825 | 821 | ||
826 | } | 822 | } |
827 | 823 | ||
828 | r = amdgpu_vm_clear_moved(adev, vm, &p->job->sync); | 824 | r = amdgpu_vm_handle_moved(adev, vm); |
825 | if (r) | ||
826 | return r; | ||
827 | |||
828 | r = amdgpu_sync_fence(adev, &p->job->sync, vm->last_update); | ||
829 | if (r) | ||
830 | return r; | ||
829 | 831 | ||
830 | if (amdgpu_vm_debug && p->bo_list) { | 832 | if (amdgpu_vm_debug && p->bo_list) { |
831 | /* Invalidate all BOs to test for userspace bugs */ | 833 | /* Invalidate all BOs to test for userspace bugs */ |
@@ -835,7 +837,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p) | |||
835 | if (!bo) | 837 | if (!bo) |
836 | continue; | 838 | continue; |
837 | 839 | ||
838 | amdgpu_vm_bo_invalidate(adev, bo); | 840 | amdgpu_vm_bo_invalidate(adev, bo, false); |
839 | } | 841 | } |
840 | } | 842 | } |
841 | 843 | ||
@@ -848,19 +850,63 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, | |||
848 | struct amdgpu_fpriv *fpriv = p->filp->driver_priv; | 850 | struct amdgpu_fpriv *fpriv = p->filp->driver_priv; |
849 | struct amdgpu_vm *vm = &fpriv->vm; | 851 | struct amdgpu_vm *vm = &fpriv->vm; |
850 | struct amdgpu_ring *ring = p->job->ring; | 852 | struct amdgpu_ring *ring = p->job->ring; |
851 | int i, r; | 853 | int r; |
852 | 854 | ||
853 | /* Only for UVD/VCE VM emulation */ | 855 | /* Only for UVD/VCE VM emulation */ |
854 | if (ring->funcs->parse_cs) { | 856 | if (p->job->ring->funcs->parse_cs) { |
855 | for (i = 0; i < p->job->num_ibs; i++) { | 857 | unsigned i, j; |
856 | r = amdgpu_ring_parse_cs(ring, p, i); | 858 | |
859 | for (i = 0, j = 0; i < p->nchunks && j < p->job->num_ibs; i++) { | ||
860 | struct drm_amdgpu_cs_chunk_ib *chunk_ib; | ||
861 | struct amdgpu_bo_va_mapping *m; | ||
862 | struct amdgpu_bo *aobj = NULL; | ||
863 | struct amdgpu_cs_chunk *chunk; | ||
864 | struct amdgpu_ib *ib; | ||
865 | uint64_t offset; | ||
866 | uint8_t *kptr; | ||
867 | |||
868 | chunk = &p->chunks[i]; | ||
869 | ib = &p->job->ibs[j]; | ||
870 | chunk_ib = chunk->kdata; | ||
871 | |||
872 | if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB) | ||
873 | continue; | ||
874 | |||
875 | r = amdgpu_cs_find_mapping(p, chunk_ib->va_start, | ||
876 | &aobj, &m); | ||
877 | if (r) { | ||
878 | DRM_ERROR("IB va_start is invalid\n"); | ||
879 | return r; | ||
880 | } | ||
881 | |||
882 | if ((chunk_ib->va_start + chunk_ib->ib_bytes) > | ||
883 | (m->last + 1) * AMDGPU_GPU_PAGE_SIZE) { | ||
884 | DRM_ERROR("IB va_start+ib_bytes is invalid\n"); | ||
885 | return -EINVAL; | ||
886 | } | ||
887 | |||
888 | /* the IB should be reserved at this point */ | ||
889 | r = amdgpu_bo_kmap(aobj, (void **)&kptr); | ||
890 | if (r) { | ||
891 | return r; | ||
892 | } | ||
893 | |||
894 | offset = m->start * AMDGPU_GPU_PAGE_SIZE; | ||
895 | kptr += chunk_ib->va_start - offset; | ||
896 | |||
897 | memcpy(ib->ptr, kptr, chunk_ib->ib_bytes); | ||
898 | amdgpu_bo_kunmap(aobj); | ||
899 | |||
900 | r = amdgpu_ring_parse_cs(ring, p, j); | ||
857 | if (r) | 901 | if (r) |
858 | return r; | 902 | return r; |
903 | |||
904 | j++; | ||
859 | } | 905 | } |
860 | } | 906 | } |
861 | 907 | ||
862 | if (p->job->vm) { | 908 | if (p->job->vm) { |
863 | p->job->vm_pd_addr = amdgpu_bo_gpu_offset(vm->root.bo); | 909 | p->job->vm_pd_addr = amdgpu_bo_gpu_offset(vm->root.base.bo); |
864 | 910 | ||
865 | r = amdgpu_bo_vm_update_pte(p); | 911 | r = amdgpu_bo_vm_update_pte(p); |
866 | if (r) | 912 | if (r) |
@@ -922,54 +968,18 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, | |||
922 | 968 | ||
923 | parser->job->ring = ring; | 969 | parser->job->ring = ring; |
924 | 970 | ||
925 | if (ring->funcs->parse_cs) { | 971 | r = amdgpu_ib_get(adev, vm, |
926 | struct amdgpu_bo_va_mapping *m; | 972 | ring->funcs->parse_cs ? chunk_ib->ib_bytes : 0, |
927 | struct amdgpu_bo *aobj = NULL; | 973 | ib); |
928 | uint64_t offset; | 974 | if (r) { |
929 | uint8_t *kptr; | 975 | DRM_ERROR("Failed to get ib !\n"); |
930 | 976 | return r; | |
931 | m = amdgpu_cs_find_mapping(parser, chunk_ib->va_start, | ||
932 | &aobj); | ||
933 | if (!aobj) { | ||
934 | DRM_ERROR("IB va_start is invalid\n"); | ||
935 | return -EINVAL; | ||
936 | } | ||
937 | |||
938 | if ((chunk_ib->va_start + chunk_ib->ib_bytes) > | ||
939 | (m->last + 1) * AMDGPU_GPU_PAGE_SIZE) { | ||
940 | DRM_ERROR("IB va_start+ib_bytes is invalid\n"); | ||
941 | return -EINVAL; | ||
942 | } | ||
943 | |||
944 | /* the IB should be reserved at this point */ | ||
945 | r = amdgpu_bo_kmap(aobj, (void **)&kptr); | ||
946 | if (r) { | ||
947 | return r; | ||
948 | } | ||
949 | |||
950 | offset = m->start * AMDGPU_GPU_PAGE_SIZE; | ||
951 | kptr += chunk_ib->va_start - offset; | ||
952 | |||
953 | r = amdgpu_ib_get(adev, vm, chunk_ib->ib_bytes, ib); | ||
954 | if (r) { | ||
955 | DRM_ERROR("Failed to get ib !\n"); | ||
956 | return r; | ||
957 | } | ||
958 | |||
959 | memcpy(ib->ptr, kptr, chunk_ib->ib_bytes); | ||
960 | amdgpu_bo_kunmap(aobj); | ||
961 | } else { | ||
962 | r = amdgpu_ib_get(adev, vm, 0, ib); | ||
963 | if (r) { | ||
964 | DRM_ERROR("Failed to get ib !\n"); | ||
965 | return r; | ||
966 | } | ||
967 | |||
968 | } | 977 | } |
969 | 978 | ||
970 | ib->gpu_addr = chunk_ib->va_start; | 979 | ib->gpu_addr = chunk_ib->va_start; |
971 | ib->length_dw = chunk_ib->ib_bytes / 4; | 980 | ib->length_dw = chunk_ib->ib_bytes / 4; |
972 | ib->flags = chunk_ib->flags; | 981 | ib->flags = chunk_ib->flags; |
982 | |||
973 | j++; | 983 | j++; |
974 | } | 984 | } |
975 | 985 | ||
@@ -979,7 +989,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, | |||
979 | parser->job->ring->funcs->type == AMDGPU_RING_TYPE_VCE)) | 989 | parser->job->ring->funcs->type == AMDGPU_RING_TYPE_VCE)) |
980 | return -EINVAL; | 990 | return -EINVAL; |
981 | 991 | ||
982 | return 0; | 992 | return amdgpu_ctx_wait_prev_fence(parser->ctx, parser->job->ring->idx); |
983 | } | 993 | } |
984 | 994 | ||
985 | static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p, | 995 | static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p, |
@@ -1133,14 +1143,31 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, | |||
1133 | struct amdgpu_ring *ring = p->job->ring; | 1143 | struct amdgpu_ring *ring = p->job->ring; |
1134 | struct amd_sched_entity *entity = &p->ctx->rings[ring->idx].entity; | 1144 | struct amd_sched_entity *entity = &p->ctx->rings[ring->idx].entity; |
1135 | struct amdgpu_job *job; | 1145 | struct amdgpu_job *job; |
1146 | unsigned i; | ||
1147 | uint64_t seq; | ||
1148 | |||
1136 | int r; | 1149 | int r; |
1137 | 1150 | ||
1151 | amdgpu_mn_lock(p->mn); | ||
1152 | if (p->bo_list) { | ||
1153 | for (i = p->bo_list->first_userptr; | ||
1154 | i < p->bo_list->num_entries; ++i) { | ||
1155 | struct amdgpu_bo *bo = p->bo_list->array[i].robj; | ||
1156 | |||
1157 | if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) { | ||
1158 | amdgpu_mn_unlock(p->mn); | ||
1159 | return -ERESTARTSYS; | ||
1160 | } | ||
1161 | } | ||
1162 | } | ||
1163 | |||
1138 | job = p->job; | 1164 | job = p->job; |
1139 | p->job = NULL; | 1165 | p->job = NULL; |
1140 | 1166 | ||
1141 | r = amd_sched_job_init(&job->base, &ring->sched, entity, p->filp); | 1167 | r = amd_sched_job_init(&job->base, &ring->sched, entity, p->filp); |
1142 | if (r) { | 1168 | if (r) { |
1143 | amdgpu_job_free(job); | 1169 | amdgpu_job_free(job); |
1170 | amdgpu_mn_unlock(p->mn); | ||
1144 | return r; | 1171 | return r; |
1145 | } | 1172 | } |
1146 | 1173 | ||
@@ -1148,21 +1175,36 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, | |||
1148 | job->fence_ctx = entity->fence_context; | 1175 | job->fence_ctx = entity->fence_context; |
1149 | p->fence = dma_fence_get(&job->base.s_fence->finished); | 1176 | p->fence = dma_fence_get(&job->base.s_fence->finished); |
1150 | 1177 | ||
1178 | r = amdgpu_ctx_add_fence(p->ctx, ring, p->fence, &seq); | ||
1179 | if (r) { | ||
1180 | dma_fence_put(p->fence); | ||
1181 | dma_fence_put(&job->base.s_fence->finished); | ||
1182 | amdgpu_job_free(job); | ||
1183 | amdgpu_mn_unlock(p->mn); | ||
1184 | return r; | ||
1185 | } | ||
1186 | |||
1151 | amdgpu_cs_post_dependencies(p); | 1187 | amdgpu_cs_post_dependencies(p); |
1152 | 1188 | ||
1153 | cs->out.handle = amdgpu_ctx_add_fence(p->ctx, ring, p->fence); | 1189 | cs->out.handle = seq; |
1154 | job->uf_sequence = cs->out.handle; | 1190 | job->uf_sequence = seq; |
1191 | |||
1155 | amdgpu_job_free_resources(job); | 1192 | amdgpu_job_free_resources(job); |
1193 | amdgpu_ring_priority_get(job->ring, | ||
1194 | amd_sched_get_job_priority(&job->base)); | ||
1156 | 1195 | ||
1157 | trace_amdgpu_cs_ioctl(job); | 1196 | trace_amdgpu_cs_ioctl(job); |
1158 | amd_sched_entity_push_job(&job->base); | 1197 | amd_sched_entity_push_job(&job->base); |
1198 | |||
1199 | ttm_eu_fence_buffer_objects(&p->ticket, &p->validated, p->fence); | ||
1200 | amdgpu_mn_unlock(p->mn); | ||
1201 | |||
1159 | return 0; | 1202 | return 0; |
1160 | } | 1203 | } |
1161 | 1204 | ||
1162 | int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | 1205 | int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) |
1163 | { | 1206 | { |
1164 | struct amdgpu_device *adev = dev->dev_private; | 1207 | struct amdgpu_device *adev = dev->dev_private; |
1165 | struct amdgpu_fpriv *fpriv = filp->driver_priv; | ||
1166 | union drm_amdgpu_cs *cs = data; | 1208 | union drm_amdgpu_cs *cs = data; |
1167 | struct amdgpu_cs_parser parser = {}; | 1209 | struct amdgpu_cs_parser parser = {}; |
1168 | bool reserved_buffers = false; | 1210 | bool reserved_buffers = false; |
@@ -1170,8 +1212,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
1170 | 1212 | ||
1171 | if (!adev->accel_working) | 1213 | if (!adev->accel_working) |
1172 | return -EBUSY; | 1214 | return -EBUSY; |
1173 | if (amdgpu_kms_vram_lost(adev, fpriv)) | ||
1174 | return -ENODEV; | ||
1175 | 1215 | ||
1176 | parser.adev = adev; | 1216 | parser.adev = adev; |
1177 | parser.filp = filp; | 1217 | parser.filp = filp; |
@@ -1182,6 +1222,10 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
1182 | goto out; | 1222 | goto out; |
1183 | } | 1223 | } |
1184 | 1224 | ||
1225 | r = amdgpu_cs_ib_fill(adev, &parser); | ||
1226 | if (r) | ||
1227 | goto out; | ||
1228 | |||
1185 | r = amdgpu_cs_parser_bos(&parser, data); | 1229 | r = amdgpu_cs_parser_bos(&parser, data); |
1186 | if (r) { | 1230 | if (r) { |
1187 | if (r == -ENOMEM) | 1231 | if (r == -ENOMEM) |
@@ -1192,9 +1236,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
1192 | } | 1236 | } |
1193 | 1237 | ||
1194 | reserved_buffers = true; | 1238 | reserved_buffers = true; |
1195 | r = amdgpu_cs_ib_fill(adev, &parser); | ||
1196 | if (r) | ||
1197 | goto out; | ||
1198 | 1239 | ||
1199 | r = amdgpu_cs_dependencies(adev, &parser); | 1240 | r = amdgpu_cs_dependencies(adev, &parser); |
1200 | if (r) { | 1241 | if (r) { |
@@ -1230,16 +1271,12 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, | |||
1230 | { | 1271 | { |
1231 | union drm_amdgpu_wait_cs *wait = data; | 1272 | union drm_amdgpu_wait_cs *wait = data; |
1232 | struct amdgpu_device *adev = dev->dev_private; | 1273 | struct amdgpu_device *adev = dev->dev_private; |
1233 | struct amdgpu_fpriv *fpriv = filp->driver_priv; | ||
1234 | unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout); | 1274 | unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout); |
1235 | struct amdgpu_ring *ring = NULL; | 1275 | struct amdgpu_ring *ring = NULL; |
1236 | struct amdgpu_ctx *ctx; | 1276 | struct amdgpu_ctx *ctx; |
1237 | struct dma_fence *fence; | 1277 | struct dma_fence *fence; |
1238 | long r; | 1278 | long r; |
1239 | 1279 | ||
1240 | if (amdgpu_kms_vram_lost(adev, fpriv)) | ||
1241 | return -ENODEV; | ||
1242 | |||
1243 | ctx = amdgpu_ctx_get(filp->driver_priv, wait->in.ctx_id); | 1280 | ctx = amdgpu_ctx_get(filp->driver_priv, wait->in.ctx_id); |
1244 | if (ctx == NULL) | 1281 | if (ctx == NULL) |
1245 | return -EINVAL; | 1282 | return -EINVAL; |
@@ -1257,6 +1294,8 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, | |||
1257 | r = PTR_ERR(fence); | 1294 | r = PTR_ERR(fence); |
1258 | else if (fence) { | 1295 | else if (fence) { |
1259 | r = dma_fence_wait_timeout(fence, true, timeout); | 1296 | r = dma_fence_wait_timeout(fence, true, timeout); |
1297 | if (r > 0 && fence->error) | ||
1298 | r = fence->error; | ||
1260 | dma_fence_put(fence); | 1299 | dma_fence_put(fence); |
1261 | } else | 1300 | } else |
1262 | r = 1; | 1301 | r = 1; |
@@ -1304,6 +1343,62 @@ static struct dma_fence *amdgpu_cs_get_fence(struct amdgpu_device *adev, | |||
1304 | return fence; | 1343 | return fence; |
1305 | } | 1344 | } |
1306 | 1345 | ||
1346 | int amdgpu_cs_fence_to_handle_ioctl(struct drm_device *dev, void *data, | ||
1347 | struct drm_file *filp) | ||
1348 | { | ||
1349 | struct amdgpu_device *adev = dev->dev_private; | ||
1350 | union drm_amdgpu_fence_to_handle *info = data; | ||
1351 | struct dma_fence *fence; | ||
1352 | struct drm_syncobj *syncobj; | ||
1353 | struct sync_file *sync_file; | ||
1354 | int fd, r; | ||
1355 | |||
1356 | fence = amdgpu_cs_get_fence(adev, filp, &info->in.fence); | ||
1357 | if (IS_ERR(fence)) | ||
1358 | return PTR_ERR(fence); | ||
1359 | |||
1360 | switch (info->in.what) { | ||
1361 | case AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ: | ||
1362 | r = drm_syncobj_create(&syncobj, 0, fence); | ||
1363 | dma_fence_put(fence); | ||
1364 | if (r) | ||
1365 | return r; | ||
1366 | r = drm_syncobj_get_handle(filp, syncobj, &info->out.handle); | ||
1367 | drm_syncobj_put(syncobj); | ||
1368 | return r; | ||
1369 | |||
1370 | case AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD: | ||
1371 | r = drm_syncobj_create(&syncobj, 0, fence); | ||
1372 | dma_fence_put(fence); | ||
1373 | if (r) | ||
1374 | return r; | ||
1375 | r = drm_syncobj_get_fd(syncobj, (int*)&info->out.handle); | ||
1376 | drm_syncobj_put(syncobj); | ||
1377 | return r; | ||
1378 | |||
1379 | case AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD: | ||
1380 | fd = get_unused_fd_flags(O_CLOEXEC); | ||
1381 | if (fd < 0) { | ||
1382 | dma_fence_put(fence); | ||
1383 | return fd; | ||
1384 | } | ||
1385 | |||
1386 | sync_file = sync_file_create(fence); | ||
1387 | dma_fence_put(fence); | ||
1388 | if (!sync_file) { | ||
1389 | put_unused_fd(fd); | ||
1390 | return -ENOMEM; | ||
1391 | } | ||
1392 | |||
1393 | fd_install(fd, sync_file->file); | ||
1394 | info->out.handle = fd; | ||
1395 | return 0; | ||
1396 | |||
1397 | default: | ||
1398 | return -EINVAL; | ||
1399 | } | ||
1400 | } | ||
1401 | |||
1307 | /** | 1402 | /** |
1308 | * amdgpu_cs_wait_all_fence - wait on all fences to signal | 1403 | * amdgpu_cs_wait_all_fence - wait on all fences to signal |
1309 | * | 1404 | * |
@@ -1338,6 +1433,9 @@ static int amdgpu_cs_wait_all_fences(struct amdgpu_device *adev, | |||
1338 | 1433 | ||
1339 | if (r == 0) | 1434 | if (r == 0) |
1340 | break; | 1435 | break; |
1436 | |||
1437 | if (fence->error) | ||
1438 | return fence->error; | ||
1341 | } | 1439 | } |
1342 | 1440 | ||
1343 | memset(wait, 0, sizeof(*wait)); | 1441 | memset(wait, 0, sizeof(*wait)); |
@@ -1383,6 +1481,7 @@ static int amdgpu_cs_wait_any_fence(struct amdgpu_device *adev, | |||
1383 | array[i] = fence; | 1481 | array[i] = fence; |
1384 | } else { /* NULL, the fence has been already signaled */ | 1482 | } else { /* NULL, the fence has been already signaled */ |
1385 | r = 1; | 1483 | r = 1; |
1484 | first = i; | ||
1386 | goto out; | 1485 | goto out; |
1387 | } | 1486 | } |
1388 | } | 1487 | } |
@@ -1396,8 +1495,11 @@ out: | |||
1396 | memset(wait, 0, sizeof(*wait)); | 1495 | memset(wait, 0, sizeof(*wait)); |
1397 | wait->out.status = (r > 0); | 1496 | wait->out.status = (r > 0); |
1398 | wait->out.first_signaled = first; | 1497 | wait->out.first_signaled = first; |
1399 | /* set return value 0 to indicate success */ | 1498 | |
1400 | r = 0; | 1499 | if (first < fence_count && array[first]) |
1500 | r = array[first]->error; | ||
1501 | else | ||
1502 | r = 0; | ||
1401 | 1503 | ||
1402 | err_free_fence_array: | 1504 | err_free_fence_array: |
1403 | for (i = 0; i < fence_count; i++) | 1505 | for (i = 0; i < fence_count; i++) |
@@ -1418,15 +1520,12 @@ int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data, | |||
1418 | struct drm_file *filp) | 1520 | struct drm_file *filp) |
1419 | { | 1521 | { |
1420 | struct amdgpu_device *adev = dev->dev_private; | 1522 | struct amdgpu_device *adev = dev->dev_private; |
1421 | struct amdgpu_fpriv *fpriv = filp->driver_priv; | ||
1422 | union drm_amdgpu_wait_fences *wait = data; | 1523 | union drm_amdgpu_wait_fences *wait = data; |
1423 | uint32_t fence_count = wait->in.fence_count; | 1524 | uint32_t fence_count = wait->in.fence_count; |
1424 | struct drm_amdgpu_fence *fences_user; | 1525 | struct drm_amdgpu_fence *fences_user; |
1425 | struct drm_amdgpu_fence *fences; | 1526 | struct drm_amdgpu_fence *fences; |
1426 | int r; | 1527 | int r; |
1427 | 1528 | ||
1428 | if (amdgpu_kms_vram_lost(adev, fpriv)) | ||
1429 | return -ENODEV; | ||
1430 | /* Get the fences from userspace */ | 1529 | /* Get the fences from userspace */ |
1431 | fences = kmalloc_array(fence_count, sizeof(struct drm_amdgpu_fence), | 1530 | fences = kmalloc_array(fence_count, sizeof(struct drm_amdgpu_fence), |
1432 | GFP_KERNEL); | 1531 | GFP_KERNEL); |
@@ -1462,78 +1561,36 @@ err_free_fences: | |||
1462 | * virtual memory address. Returns allocation structure when found, NULL | 1561 | * virtual memory address. Returns allocation structure when found, NULL |
1463 | * otherwise. | 1562 | * otherwise. |
1464 | */ | 1563 | */ |
1465 | struct amdgpu_bo_va_mapping * | 1564 | int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser, |
1466 | amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser, | 1565 | uint64_t addr, struct amdgpu_bo **bo, |
1467 | uint64_t addr, struct amdgpu_bo **bo) | 1566 | struct amdgpu_bo_va_mapping **map) |
1468 | { | 1567 | { |
1568 | struct amdgpu_fpriv *fpriv = parser->filp->driver_priv; | ||
1569 | struct amdgpu_vm *vm = &fpriv->vm; | ||
1469 | struct amdgpu_bo_va_mapping *mapping; | 1570 | struct amdgpu_bo_va_mapping *mapping; |
1470 | unsigned i; | ||
1471 | |||
1472 | if (!parser->bo_list) | ||
1473 | return NULL; | ||
1474 | |||
1475 | addr /= AMDGPU_GPU_PAGE_SIZE; | ||
1476 | |||
1477 | for (i = 0; i < parser->bo_list->num_entries; i++) { | ||
1478 | struct amdgpu_bo_list_entry *lobj; | ||
1479 | |||
1480 | lobj = &parser->bo_list->array[i]; | ||
1481 | if (!lobj->bo_va) | ||
1482 | continue; | ||
1483 | |||
1484 | list_for_each_entry(mapping, &lobj->bo_va->valids, list) { | ||
1485 | if (mapping->start > addr || | ||
1486 | addr > mapping->last) | ||
1487 | continue; | ||
1488 | |||
1489 | *bo = lobj->bo_va->base.bo; | ||
1490 | return mapping; | ||
1491 | } | ||
1492 | |||
1493 | list_for_each_entry(mapping, &lobj->bo_va->invalids, list) { | ||
1494 | if (mapping->start > addr || | ||
1495 | addr > mapping->last) | ||
1496 | continue; | ||
1497 | |||
1498 | *bo = lobj->bo_va->base.bo; | ||
1499 | return mapping; | ||
1500 | } | ||
1501 | } | ||
1502 | |||
1503 | return NULL; | ||
1504 | } | ||
1505 | |||
1506 | /** | ||
1507 | * amdgpu_cs_sysvm_access_required - make BOs accessible by the system VM | ||
1508 | * | ||
1509 | * @parser: command submission parser context | ||
1510 | * | ||
1511 | * Helper for UVD/VCE VM emulation, make sure BOs are accessible by the system VM. | ||
1512 | */ | ||
1513 | int amdgpu_cs_sysvm_access_required(struct amdgpu_cs_parser *parser) | ||
1514 | { | ||
1515 | unsigned i; | ||
1516 | int r; | 1571 | int r; |
1517 | 1572 | ||
1518 | if (!parser->bo_list) | 1573 | addr /= AMDGPU_GPU_PAGE_SIZE; |
1519 | return 0; | ||
1520 | 1574 | ||
1521 | for (i = 0; i < parser->bo_list->num_entries; i++) { | 1575 | mapping = amdgpu_vm_bo_lookup_mapping(vm, addr); |
1522 | struct amdgpu_bo *bo = parser->bo_list->array[i].robj; | 1576 | if (!mapping || !mapping->bo_va || !mapping->bo_va->base.bo) |
1577 | return -EINVAL; | ||
1523 | 1578 | ||
1524 | r = amdgpu_ttm_bind(&bo->tbo, &bo->tbo.mem); | 1579 | *bo = mapping->bo_va->base.bo; |
1525 | if (unlikely(r)) | 1580 | *map = mapping; |
1526 | return r; | ||
1527 | 1581 | ||
1528 | if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS) | 1582 | /* Double check that the BO is reserved by this CS */ |
1529 | continue; | 1583 | if (READ_ONCE((*bo)->tbo.resv->lock.ctx) != &parser->ticket) |
1584 | return -EINVAL; | ||
1530 | 1585 | ||
1531 | bo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; | 1586 | if (!((*bo)->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)) { |
1532 | amdgpu_ttm_placement_from_domain(bo, bo->allowed_domains); | 1587 | (*bo)->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; |
1533 | r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); | 1588 | amdgpu_ttm_placement_from_domain(*bo, (*bo)->allowed_domains); |
1534 | if (unlikely(r)) | 1589 | r = ttm_bo_validate(&(*bo)->tbo, &(*bo)->placement, false, |
1590 | false); | ||
1591 | if (r) | ||
1535 | return r; | 1592 | return r; |
1536 | } | 1593 | } |
1537 | 1594 | ||
1538 | return 0; | 1595 | return amdgpu_ttm_bind(&(*bo)->tbo, &(*bo)->tbo.mem); |
1539 | } | 1596 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index a11e44340b23..c184468e2b2b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | |||
@@ -23,13 +23,41 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <drm/drmP.h> | 25 | #include <drm/drmP.h> |
26 | #include <drm/drm_auth.h> | ||
26 | #include "amdgpu.h" | 27 | #include "amdgpu.h" |
28 | #include "amdgpu_sched.h" | ||
27 | 29 | ||
28 | static int amdgpu_ctx_init(struct amdgpu_device *adev, struct amdgpu_ctx *ctx) | 30 | static int amdgpu_ctx_priority_permit(struct drm_file *filp, |
31 | enum amd_sched_priority priority) | ||
32 | { | ||
33 | /* NORMAL and below are accessible by everyone */ | ||
34 | if (priority <= AMD_SCHED_PRIORITY_NORMAL) | ||
35 | return 0; | ||
36 | |||
37 | if (capable(CAP_SYS_NICE)) | ||
38 | return 0; | ||
39 | |||
40 | if (drm_is_current_master(filp)) | ||
41 | return 0; | ||
42 | |||
43 | return -EACCES; | ||
44 | } | ||
45 | |||
46 | static int amdgpu_ctx_init(struct amdgpu_device *adev, | ||
47 | enum amd_sched_priority priority, | ||
48 | struct drm_file *filp, | ||
49 | struct amdgpu_ctx *ctx) | ||
29 | { | 50 | { |
30 | unsigned i, j; | 51 | unsigned i, j; |
31 | int r; | 52 | int r; |
32 | 53 | ||
54 | if (priority < 0 || priority >= AMD_SCHED_PRIORITY_MAX) | ||
55 | return -EINVAL; | ||
56 | |||
57 | r = amdgpu_ctx_priority_permit(filp, priority); | ||
58 | if (r) | ||
59 | return r; | ||
60 | |||
33 | memset(ctx, 0, sizeof(*ctx)); | 61 | memset(ctx, 0, sizeof(*ctx)); |
34 | ctx->adev = adev; | 62 | ctx->adev = adev; |
35 | kref_init(&ctx->refcount); | 63 | kref_init(&ctx->refcount); |
@@ -39,19 +67,24 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, struct amdgpu_ctx *ctx) | |||
39 | if (!ctx->fences) | 67 | if (!ctx->fences) |
40 | return -ENOMEM; | 68 | return -ENOMEM; |
41 | 69 | ||
70 | mutex_init(&ctx->lock); | ||
71 | |||
42 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 72 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
43 | ctx->rings[i].sequence = 1; | 73 | ctx->rings[i].sequence = 1; |
44 | ctx->rings[i].fences = &ctx->fences[amdgpu_sched_jobs * i]; | 74 | ctx->rings[i].fences = &ctx->fences[amdgpu_sched_jobs * i]; |
45 | } | 75 | } |
46 | 76 | ||
47 | ctx->reset_counter = atomic_read(&adev->gpu_reset_counter); | 77 | ctx->reset_counter = atomic_read(&adev->gpu_reset_counter); |
78 | ctx->vram_lost_counter = atomic_read(&adev->vram_lost_counter); | ||
79 | ctx->init_priority = priority; | ||
80 | ctx->override_priority = AMD_SCHED_PRIORITY_UNSET; | ||
48 | 81 | ||
49 | /* create context entity for each ring */ | 82 | /* create context entity for each ring */ |
50 | for (i = 0; i < adev->num_rings; i++) { | 83 | for (i = 0; i < adev->num_rings; i++) { |
51 | struct amdgpu_ring *ring = adev->rings[i]; | 84 | struct amdgpu_ring *ring = adev->rings[i]; |
52 | struct amd_sched_rq *rq; | 85 | struct amd_sched_rq *rq; |
53 | 86 | ||
54 | rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL]; | 87 | rq = &ring->sched.sched_rq[priority]; |
55 | 88 | ||
56 | if (ring == &adev->gfx.kiq.ring) | 89 | if (ring == &adev->gfx.kiq.ring) |
57 | continue; | 90 | continue; |
@@ -96,10 +129,14 @@ static void amdgpu_ctx_fini(struct amdgpu_ctx *ctx) | |||
96 | &ctx->rings[i].entity); | 129 | &ctx->rings[i].entity); |
97 | 130 | ||
98 | amdgpu_queue_mgr_fini(adev, &ctx->queue_mgr); | 131 | amdgpu_queue_mgr_fini(adev, &ctx->queue_mgr); |
132 | |||
133 | mutex_destroy(&ctx->lock); | ||
99 | } | 134 | } |
100 | 135 | ||
101 | static int amdgpu_ctx_alloc(struct amdgpu_device *adev, | 136 | static int amdgpu_ctx_alloc(struct amdgpu_device *adev, |
102 | struct amdgpu_fpriv *fpriv, | 137 | struct amdgpu_fpriv *fpriv, |
138 | struct drm_file *filp, | ||
139 | enum amd_sched_priority priority, | ||
103 | uint32_t *id) | 140 | uint32_t *id) |
104 | { | 141 | { |
105 | struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; | 142 | struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; |
@@ -117,8 +154,9 @@ static int amdgpu_ctx_alloc(struct amdgpu_device *adev, | |||
117 | kfree(ctx); | 154 | kfree(ctx); |
118 | return r; | 155 | return r; |
119 | } | 156 | } |
157 | |||
120 | *id = (uint32_t)r; | 158 | *id = (uint32_t)r; |
121 | r = amdgpu_ctx_init(adev, ctx); | 159 | r = amdgpu_ctx_init(adev, priority, filp, ctx); |
122 | if (r) { | 160 | if (r) { |
123 | idr_remove(&mgr->ctx_handles, *id); | 161 | idr_remove(&mgr->ctx_handles, *id); |
124 | *id = 0; | 162 | *id = 0; |
@@ -193,6 +231,7 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, | |||
193 | { | 231 | { |
194 | int r; | 232 | int r; |
195 | uint32_t id; | 233 | uint32_t id; |
234 | enum amd_sched_priority priority; | ||
196 | 235 | ||
197 | union drm_amdgpu_ctx *args = data; | 236 | union drm_amdgpu_ctx *args = data; |
198 | struct amdgpu_device *adev = dev->dev_private; | 237 | struct amdgpu_device *adev = dev->dev_private; |
@@ -200,10 +239,16 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, | |||
200 | 239 | ||
201 | r = 0; | 240 | r = 0; |
202 | id = args->in.ctx_id; | 241 | id = args->in.ctx_id; |
242 | priority = amdgpu_to_sched_priority(args->in.priority); | ||
243 | |||
244 | /* For backwards compatibility reasons, we need to accept | ||
245 | * ioctls with garbage in the priority field */ | ||
246 | if (priority == AMD_SCHED_PRIORITY_INVALID) | ||
247 | priority = AMD_SCHED_PRIORITY_NORMAL; | ||
203 | 248 | ||
204 | switch (args->in.op) { | 249 | switch (args->in.op) { |
205 | case AMDGPU_CTX_OP_ALLOC_CTX: | 250 | case AMDGPU_CTX_OP_ALLOC_CTX: |
206 | r = amdgpu_ctx_alloc(adev, fpriv, &id); | 251 | r = amdgpu_ctx_alloc(adev, fpriv, filp, priority, &id); |
207 | args->out.alloc.ctx_id = id; | 252 | args->out.alloc.ctx_id = id; |
208 | break; | 253 | break; |
209 | case AMDGPU_CTX_OP_FREE_CTX: | 254 | case AMDGPU_CTX_OP_FREE_CTX: |
@@ -246,8 +291,8 @@ int amdgpu_ctx_put(struct amdgpu_ctx *ctx) | |||
246 | return 0; | 291 | return 0; |
247 | } | 292 | } |
248 | 293 | ||
249 | uint64_t amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, | 294 | int amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, |
250 | struct dma_fence *fence) | 295 | struct dma_fence *fence, uint64_t* handler) |
251 | { | 296 | { |
252 | struct amdgpu_ctx_ring *cring = & ctx->rings[ring->idx]; | 297 | struct amdgpu_ctx_ring *cring = & ctx->rings[ring->idx]; |
253 | uint64_t seq = cring->sequence; | 298 | uint64_t seq = cring->sequence; |
@@ -256,12 +301,8 @@ uint64_t amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, | |||
256 | 301 | ||
257 | idx = seq & (amdgpu_sched_jobs - 1); | 302 | idx = seq & (amdgpu_sched_jobs - 1); |
258 | other = cring->fences[idx]; | 303 | other = cring->fences[idx]; |
259 | if (other) { | 304 | if (other) |
260 | signed long r; | 305 | BUG_ON(!dma_fence_is_signaled(other)); |
261 | r = dma_fence_wait_timeout(other, false, MAX_SCHEDULE_TIMEOUT); | ||
262 | if (r < 0) | ||
263 | DRM_ERROR("Error (%ld) waiting for fence!\n", r); | ||
264 | } | ||
265 | 306 | ||
266 | dma_fence_get(fence); | 307 | dma_fence_get(fence); |
267 | 308 | ||
@@ -271,8 +312,10 @@ uint64_t amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, | |||
271 | spin_unlock(&ctx->ring_lock); | 312 | spin_unlock(&ctx->ring_lock); |
272 | 313 | ||
273 | dma_fence_put(other); | 314 | dma_fence_put(other); |
315 | if (handler) | ||
316 | *handler = seq; | ||
274 | 317 | ||
275 | return seq; | 318 | return 0; |
276 | } | 319 | } |
277 | 320 | ||
278 | struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx, | 321 | struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx, |
@@ -303,6 +346,51 @@ struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx, | |||
303 | return fence; | 346 | return fence; |
304 | } | 347 | } |
305 | 348 | ||
349 | void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx, | ||
350 | enum amd_sched_priority priority) | ||
351 | { | ||
352 | int i; | ||
353 | struct amdgpu_device *adev = ctx->adev; | ||
354 | struct amd_sched_rq *rq; | ||
355 | struct amd_sched_entity *entity; | ||
356 | struct amdgpu_ring *ring; | ||
357 | enum amd_sched_priority ctx_prio; | ||
358 | |||
359 | ctx->override_priority = priority; | ||
360 | |||
361 | ctx_prio = (ctx->override_priority == AMD_SCHED_PRIORITY_UNSET) ? | ||
362 | ctx->init_priority : ctx->override_priority; | ||
363 | |||
364 | for (i = 0; i < adev->num_rings; i++) { | ||
365 | ring = adev->rings[i]; | ||
366 | entity = &ctx->rings[i].entity; | ||
367 | rq = &ring->sched.sched_rq[ctx_prio]; | ||
368 | |||
369 | if (ring->funcs->type == AMDGPU_RING_TYPE_KIQ) | ||
370 | continue; | ||
371 | |||
372 | amd_sched_entity_set_rq(entity, rq); | ||
373 | } | ||
374 | } | ||
375 | |||
376 | int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx, unsigned ring_id) | ||
377 | { | ||
378 | struct amdgpu_ctx_ring *cring = &ctx->rings[ring_id]; | ||
379 | unsigned idx = cring->sequence & (amdgpu_sched_jobs - 1); | ||
380 | struct dma_fence *other = cring->fences[idx]; | ||
381 | |||
382 | if (other) { | ||
383 | signed long r; | ||
384 | r = dma_fence_wait_timeout(other, false, MAX_SCHEDULE_TIMEOUT); | ||
385 | if (r < 0) { | ||
386 | DRM_ERROR("Error (%ld) waiting for fence!\n", r); | ||
387 | return r; | ||
388 | } | ||
389 | } | ||
390 | |||
391 | return 0; | ||
392 | } | ||
393 | |||
306 | void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr) | 394 | void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr) |
307 | { | 395 | { |
308 | mutex_init(&mgr->lock); | 396 | mutex_init(&mgr->lock); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index e630d918fefc..2c574374d9b6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/debugfs.h> | 31 | #include <linux/debugfs.h> |
32 | #include <drm/drmP.h> | 32 | #include <drm/drmP.h> |
33 | #include <drm/drm_crtc_helper.h> | 33 | #include <drm/drm_crtc_helper.h> |
34 | #include <drm/drm_atomic_helper.h> | ||
34 | #include <drm/amdgpu_drm.h> | 35 | #include <drm/amdgpu_drm.h> |
35 | #include <linux/vgaarb.h> | 36 | #include <linux/vgaarb.h> |
36 | #include <linux/vga_switcheroo.h> | 37 | #include <linux/vga_switcheroo.h> |
@@ -56,6 +57,7 @@ | |||
56 | #include "amdgpu_vf_error.h" | 57 | #include "amdgpu_vf_error.h" |
57 | 58 | ||
58 | #include "amdgpu_amdkfd.h" | 59 | #include "amdgpu_amdkfd.h" |
60 | #include "amdgpu_pm.h" | ||
59 | 61 | ||
60 | MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin"); | 62 | MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin"); |
61 | MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin"); | 63 | MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin"); |
@@ -65,6 +67,7 @@ MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin"); | |||
65 | static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev); | 67 | static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev); |
66 | static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev); | 68 | static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev); |
67 | static int amdgpu_debugfs_test_ib_ring_init(struct amdgpu_device *adev); | 69 | static int amdgpu_debugfs_test_ib_ring_init(struct amdgpu_device *adev); |
70 | static int amdgpu_debugfs_vbios_dump_init(struct amdgpu_device *adev); | ||
68 | 71 | ||
69 | static const char *amdgpu_asic_name[] = { | 72 | static const char *amdgpu_asic_name[] = { |
70 | "TAHITI", | 73 | "TAHITI", |
@@ -107,10 +110,8 @@ uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg, | |||
107 | { | 110 | { |
108 | uint32_t ret; | 111 | uint32_t ret; |
109 | 112 | ||
110 | if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)) { | 113 | if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)) |
111 | BUG_ON(in_interrupt()); | ||
112 | return amdgpu_virt_kiq_rreg(adev, reg); | 114 | return amdgpu_virt_kiq_rreg(adev, reg); |
113 | } | ||
114 | 115 | ||
115 | if ((reg * 4) < adev->rmmio_size && !(acc_flags & AMDGPU_REGS_IDX)) | 116 | if ((reg * 4) < adev->rmmio_size && !(acc_flags & AMDGPU_REGS_IDX)) |
116 | ret = readl(((void __iomem *)adev->rmmio) + (reg * 4)); | 117 | ret = readl(((void __iomem *)adev->rmmio) + (reg * 4)); |
@@ -135,10 +136,8 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, | |||
135 | adev->last_mm_index = v; | 136 | adev->last_mm_index = v; |
136 | } | 137 | } |
137 | 138 | ||
138 | if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)) { | 139 | if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)) |
139 | BUG_ON(in_interrupt()); | ||
140 | return amdgpu_virt_kiq_wreg(adev, reg, v); | 140 | return amdgpu_virt_kiq_wreg(adev, reg, v); |
141 | } | ||
142 | 141 | ||
143 | if ((reg * 4) < adev->rmmio_size && !(acc_flags & AMDGPU_REGS_IDX)) | 142 | if ((reg * 4) < adev->rmmio_size && !(acc_flags & AMDGPU_REGS_IDX)) |
144 | writel(v, ((void __iomem *)adev->rmmio) + (reg * 4)); | 143 | writel(v, ((void __iomem *)adev->rmmio) + (reg * 4)); |
@@ -402,6 +401,15 @@ void amdgpu_pci_config_reset(struct amdgpu_device *adev) | |||
402 | */ | 401 | */ |
403 | static int amdgpu_doorbell_init(struct amdgpu_device *adev) | 402 | static int amdgpu_doorbell_init(struct amdgpu_device *adev) |
404 | { | 403 | { |
404 | /* No doorbell on SI hardware generation */ | ||
405 | if (adev->asic_type < CHIP_BONAIRE) { | ||
406 | adev->doorbell.base = 0; | ||
407 | adev->doorbell.size = 0; | ||
408 | adev->doorbell.num_doorbells = 0; | ||
409 | adev->doorbell.ptr = NULL; | ||
410 | return 0; | ||
411 | } | ||
412 | |||
405 | /* doorbell bar mapping */ | 413 | /* doorbell bar mapping */ |
406 | adev->doorbell.base = pci_resource_start(adev->pdev, 2); | 414 | adev->doorbell.base = pci_resource_start(adev->pdev, 2); |
407 | adev->doorbell.size = pci_resource_len(adev->pdev, 2); | 415 | adev->doorbell.size = pci_resource_len(adev->pdev, 2); |
@@ -539,7 +547,7 @@ int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb) | |||
539 | 547 | ||
540 | if (offset < adev->wb.num_wb) { | 548 | if (offset < adev->wb.num_wb) { |
541 | __set_bit(offset, adev->wb.used); | 549 | __set_bit(offset, adev->wb.used); |
542 | *wb = offset * 8; /* convert to dw offset */ | 550 | *wb = offset << 3; /* convert to dw offset */ |
543 | return 0; | 551 | return 0; |
544 | } else { | 552 | } else { |
545 | return -EINVAL; | 553 | return -EINVAL; |
@@ -557,7 +565,7 @@ int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb) | |||
557 | void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb) | 565 | void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb) |
558 | { | 566 | { |
559 | if (wb < adev->wb.num_wb) | 567 | if (wb < adev->wb.num_wb) |
560 | __clear_bit(wb, adev->wb.used); | 568 | __clear_bit(wb >> 3, adev->wb.used); |
561 | } | 569 | } |
562 | 570 | ||
563 | /** | 571 | /** |
@@ -647,42 +655,96 @@ void amdgpu_gart_location(struct amdgpu_device *adev, struct amdgpu_mc *mc) | |||
647 | } | 655 | } |
648 | 656 | ||
649 | /* | 657 | /* |
650 | * GPU helpers function. | 658 | * Firmware Reservation functions |
651 | */ | 659 | */ |
652 | /** | 660 | /** |
653 | * amdgpu_need_post - check if the hw need post or not | 661 | * amdgpu_fw_reserve_vram_fini - free fw reserved vram |
654 | * | 662 | * |
655 | * @adev: amdgpu_device pointer | 663 | * @adev: amdgpu_device pointer |
656 | * | 664 | * |
657 | * Check if the asic has been initialized (all asics) at driver startup | 665 | * free fw reserved vram if it has been reserved. |
658 | * or post is needed if hw reset is performed. | ||
659 | * Returns true if need or false if not. | ||
660 | */ | 666 | */ |
661 | bool amdgpu_need_post(struct amdgpu_device *adev) | 667 | void amdgpu_fw_reserve_vram_fini(struct amdgpu_device *adev) |
662 | { | 668 | { |
663 | uint32_t reg; | 669 | amdgpu_bo_free_kernel(&adev->fw_vram_usage.reserved_bo, |
670 | NULL, &adev->fw_vram_usage.va); | ||
671 | } | ||
664 | 672 | ||
665 | if (adev->has_hw_reset) { | 673 | /** |
666 | adev->has_hw_reset = false; | 674 | * amdgpu_fw_reserve_vram_init - create bo vram reservation from fw |
667 | return true; | 675 | * |
668 | } | 676 | * @adev: amdgpu_device pointer |
677 | * | ||
678 | * create bo vram reservation from fw. | ||
679 | */ | ||
680 | int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev) | ||
681 | { | ||
682 | int r = 0; | ||
683 | u64 gpu_addr; | ||
684 | u64 vram_size = adev->mc.visible_vram_size; | ||
669 | 685 | ||
670 | /* bios scratch used on CIK+ */ | 686 | adev->fw_vram_usage.va = NULL; |
671 | if (adev->asic_type >= CHIP_BONAIRE) | 687 | adev->fw_vram_usage.reserved_bo = NULL; |
672 | return amdgpu_atombios_scratch_need_asic_init(adev); | ||
673 | 688 | ||
674 | /* check MEM_SIZE for older asics */ | 689 | if (adev->fw_vram_usage.size > 0 && |
675 | reg = amdgpu_asic_get_config_memsize(adev); | 690 | adev->fw_vram_usage.size <= vram_size) { |
676 | 691 | ||
677 | if ((reg != 0) && (reg != 0xffffffff)) | 692 | r = amdgpu_bo_create(adev, adev->fw_vram_usage.size, |
678 | return false; | 693 | PAGE_SIZE, true, 0, |
694 | AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | | ||
695 | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, 0, | ||
696 | &adev->fw_vram_usage.reserved_bo); | ||
697 | if (r) | ||
698 | goto error_create; | ||
679 | 699 | ||
680 | return true; | 700 | r = amdgpu_bo_reserve(adev->fw_vram_usage.reserved_bo, false); |
701 | if (r) | ||
702 | goto error_reserve; | ||
703 | r = amdgpu_bo_pin_restricted(adev->fw_vram_usage.reserved_bo, | ||
704 | AMDGPU_GEM_DOMAIN_VRAM, | ||
705 | adev->fw_vram_usage.start_offset, | ||
706 | (adev->fw_vram_usage.start_offset + | ||
707 | adev->fw_vram_usage.size), &gpu_addr); | ||
708 | if (r) | ||
709 | goto error_pin; | ||
710 | r = amdgpu_bo_kmap(adev->fw_vram_usage.reserved_bo, | ||
711 | &adev->fw_vram_usage.va); | ||
712 | if (r) | ||
713 | goto error_kmap; | ||
714 | |||
715 | amdgpu_bo_unreserve(adev->fw_vram_usage.reserved_bo); | ||
716 | } | ||
717 | return r; | ||
681 | 718 | ||
719 | error_kmap: | ||
720 | amdgpu_bo_unpin(adev->fw_vram_usage.reserved_bo); | ||
721 | error_pin: | ||
722 | amdgpu_bo_unreserve(adev->fw_vram_usage.reserved_bo); | ||
723 | error_reserve: | ||
724 | amdgpu_bo_unref(&adev->fw_vram_usage.reserved_bo); | ||
725 | error_create: | ||
726 | adev->fw_vram_usage.va = NULL; | ||
727 | adev->fw_vram_usage.reserved_bo = NULL; | ||
728 | return r; | ||
682 | } | 729 | } |
683 | 730 | ||
684 | static bool amdgpu_vpost_needed(struct amdgpu_device *adev) | 731 | |
732 | /* | ||
733 | * GPU helpers function. | ||
734 | */ | ||
735 | /** | ||
736 | * amdgpu_need_post - check if the hw need post or not | ||
737 | * | ||
738 | * @adev: amdgpu_device pointer | ||
739 | * | ||
740 | * Check if the asic has been initialized (all asics) at driver startup | ||
741 | * or post is needed if hw reset is performed. | ||
742 | * Returns true if need or false if not. | ||
743 | */ | ||
744 | bool amdgpu_need_post(struct amdgpu_device *adev) | ||
685 | { | 745 | { |
746 | uint32_t reg; | ||
747 | |||
686 | if (amdgpu_sriov_vf(adev)) | 748 | if (amdgpu_sriov_vf(adev)) |
687 | return false; | 749 | return false; |
688 | 750 | ||
@@ -705,7 +767,23 @@ static bool amdgpu_vpost_needed(struct amdgpu_device *adev) | |||
705 | return true; | 767 | return true; |
706 | } | 768 | } |
707 | } | 769 | } |
708 | return amdgpu_need_post(adev); | 770 | |
771 | if (adev->has_hw_reset) { | ||
772 | adev->has_hw_reset = false; | ||
773 | return true; | ||
774 | } | ||
775 | |||
776 | /* bios scratch used on CIK+ */ | ||
777 | if (adev->asic_type >= CHIP_BONAIRE) | ||
778 | return amdgpu_atombios_scratch_need_asic_init(adev); | ||
779 | |||
780 | /* check MEM_SIZE for older asics */ | ||
781 | reg = amdgpu_asic_get_config_memsize(adev); | ||
782 | |||
783 | if ((reg != 0) && (reg != 0xffffffff)) | ||
784 | return false; | ||
785 | |||
786 | return true; | ||
709 | } | 787 | } |
710 | 788 | ||
711 | /** | 789 | /** |
@@ -887,6 +965,20 @@ static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg) | |||
887 | return r; | 965 | return r; |
888 | } | 966 | } |
889 | 967 | ||
968 | static ssize_t amdgpu_atombios_get_vbios_version(struct device *dev, | ||
969 | struct device_attribute *attr, | ||
970 | char *buf) | ||
971 | { | ||
972 | struct drm_device *ddev = dev_get_drvdata(dev); | ||
973 | struct amdgpu_device *adev = ddev->dev_private; | ||
974 | struct atom_context *ctx = adev->mode_info.atom_context; | ||
975 | |||
976 | return snprintf(buf, PAGE_SIZE, "%s\n", ctx->vbios_version); | ||
977 | } | ||
978 | |||
979 | static DEVICE_ATTR(vbios_version, 0444, amdgpu_atombios_get_vbios_version, | ||
980 | NULL); | ||
981 | |||
890 | /** | 982 | /** |
891 | * amdgpu_atombios_fini - free the driver info and callbacks for atombios | 983 | * amdgpu_atombios_fini - free the driver info and callbacks for atombios |
892 | * | 984 | * |
@@ -906,6 +998,7 @@ static void amdgpu_atombios_fini(struct amdgpu_device *adev) | |||
906 | adev->mode_info.atom_context = NULL; | 998 | adev->mode_info.atom_context = NULL; |
907 | kfree(adev->mode_info.atom_card_info); | 999 | kfree(adev->mode_info.atom_card_info); |
908 | adev->mode_info.atom_card_info = NULL; | 1000 | adev->mode_info.atom_card_info = NULL; |
1001 | device_remove_file(adev->dev, &dev_attr_vbios_version); | ||
909 | } | 1002 | } |
910 | 1003 | ||
911 | /** | 1004 | /** |
@@ -922,6 +1015,7 @@ static int amdgpu_atombios_init(struct amdgpu_device *adev) | |||
922 | { | 1015 | { |
923 | struct card_info *atom_card_info = | 1016 | struct card_info *atom_card_info = |
924 | kzalloc(sizeof(struct card_info), GFP_KERNEL); | 1017 | kzalloc(sizeof(struct card_info), GFP_KERNEL); |
1018 | int ret; | ||
925 | 1019 | ||
926 | if (!atom_card_info) | 1020 | if (!atom_card_info) |
927 | return -ENOMEM; | 1021 | return -ENOMEM; |
@@ -958,6 +1052,13 @@ static int amdgpu_atombios_init(struct amdgpu_device *adev) | |||
958 | amdgpu_atombios_scratch_regs_init(adev); | 1052 | amdgpu_atombios_scratch_regs_init(adev); |
959 | amdgpu_atombios_allocate_fb_scratch(adev); | 1053 | amdgpu_atombios_allocate_fb_scratch(adev); |
960 | } | 1054 | } |
1055 | |||
1056 | ret = device_create_file(adev->dev, &dev_attr_vbios_version); | ||
1057 | if (ret) { | ||
1058 | DRM_ERROR("Failed to create device file for VBIOS version\n"); | ||
1059 | return ret; | ||
1060 | } | ||
1061 | |||
961 | return 0; | 1062 | return 0; |
962 | } | 1063 | } |
963 | 1064 | ||
@@ -1736,6 +1837,9 @@ static int amdgpu_fini(struct amdgpu_device *adev) | |||
1736 | adev->ip_blocks[i].status.hw = false; | 1837 | adev->ip_blocks[i].status.hw = false; |
1737 | } | 1838 | } |
1738 | 1839 | ||
1840 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) | ||
1841 | amdgpu_ucode_fini_bo(adev); | ||
1842 | |||
1739 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { | 1843 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { |
1740 | if (!adev->ip_blocks[i].status.sw) | 1844 | if (!adev->ip_blocks[i].status.sw) |
1741 | continue; | 1845 | continue; |
@@ -1757,10 +1861,8 @@ static int amdgpu_fini(struct amdgpu_device *adev) | |||
1757 | adev->ip_blocks[i].status.late_initialized = false; | 1861 | adev->ip_blocks[i].status.late_initialized = false; |
1758 | } | 1862 | } |
1759 | 1863 | ||
1760 | if (amdgpu_sriov_vf(adev)) { | 1864 | if (amdgpu_sriov_vf(adev)) |
1761 | amdgpu_bo_free_kernel(&adev->virt.csa_obj, &adev->virt.csa_vmid0_addr, NULL); | ||
1762 | amdgpu_virt_release_full_gpu(adev, false); | 1865 | amdgpu_virt_release_full_gpu(adev, false); |
1763 | } | ||
1764 | 1866 | ||
1765 | return 0; | 1867 | return 0; |
1766 | } | 1868 | } |
@@ -1848,6 +1950,7 @@ static int amdgpu_sriov_reinit_late(struct amdgpu_device *adev) | |||
1848 | 1950 | ||
1849 | static enum amd_ip_block_type ip_order[] = { | 1951 | static enum amd_ip_block_type ip_order[] = { |
1850 | AMD_IP_BLOCK_TYPE_SMC, | 1952 | AMD_IP_BLOCK_TYPE_SMC, |
1953 | AMD_IP_BLOCK_TYPE_PSP, | ||
1851 | AMD_IP_BLOCK_TYPE_DCE, | 1954 | AMD_IP_BLOCK_TYPE_DCE, |
1852 | AMD_IP_BLOCK_TYPE_GFX, | 1955 | AMD_IP_BLOCK_TYPE_GFX, |
1853 | AMD_IP_BLOCK_TYPE_SDMA, | 1956 | AMD_IP_BLOCK_TYPE_SDMA, |
@@ -1933,16 +2036,67 @@ static int amdgpu_resume(struct amdgpu_device *adev) | |||
1933 | 2036 | ||
1934 | static void amdgpu_device_detect_sriov_bios(struct amdgpu_device *adev) | 2037 | static void amdgpu_device_detect_sriov_bios(struct amdgpu_device *adev) |
1935 | { | 2038 | { |
1936 | if (adev->is_atom_fw) { | 2039 | if (amdgpu_sriov_vf(adev)) { |
1937 | if (amdgpu_atomfirmware_gpu_supports_virtualization(adev)) | 2040 | if (adev->is_atom_fw) { |
1938 | adev->virt.caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS; | 2041 | if (amdgpu_atomfirmware_gpu_supports_virtualization(adev)) |
1939 | } else { | 2042 | adev->virt.caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS; |
1940 | if (amdgpu_atombios_has_gpu_virtualization_table(adev)) | 2043 | } else { |
1941 | adev->virt.caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS; | 2044 | if (amdgpu_atombios_has_gpu_virtualization_table(adev)) |
2045 | adev->virt.caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS; | ||
2046 | } | ||
2047 | |||
2048 | if (!(adev->virt.caps & AMDGPU_SRIOV_CAPS_SRIOV_VBIOS)) | ||
2049 | amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_NO_VBIOS, 0, 0); | ||
2050 | } | ||
2051 | } | ||
2052 | |||
2053 | bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) | ||
2054 | { | ||
2055 | switch (asic_type) { | ||
2056 | #if defined(CONFIG_DRM_AMD_DC) | ||
2057 | case CHIP_BONAIRE: | ||
2058 | case CHIP_HAWAII: | ||
2059 | case CHIP_KAVERI: | ||
2060 | case CHIP_CARRIZO: | ||
2061 | case CHIP_STONEY: | ||
2062 | case CHIP_POLARIS11: | ||
2063 | case CHIP_POLARIS10: | ||
2064 | case CHIP_POLARIS12: | ||
2065 | case CHIP_TONGA: | ||
2066 | case CHIP_FIJI: | ||
2067 | #if defined(CONFIG_DRM_AMD_DC_PRE_VEGA) | ||
2068 | return amdgpu_dc != 0; | ||
2069 | #endif | ||
2070 | case CHIP_KABINI: | ||
2071 | case CHIP_MULLINS: | ||
2072 | return amdgpu_dc > 0; | ||
2073 | case CHIP_VEGA10: | ||
2074 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) | ||
2075 | case CHIP_RAVEN: | ||
2076 | #endif | ||
2077 | return amdgpu_dc != 0; | ||
2078 | #endif | ||
2079 | default: | ||
2080 | return false; | ||
1942 | } | 2081 | } |
1943 | } | 2082 | } |
1944 | 2083 | ||
1945 | /** | 2084 | /** |
2085 | * amdgpu_device_has_dc_support - check if dc is supported | ||
2086 | * | ||
2087 | * @adev: amdgpu_device_pointer | ||
2088 | * | ||
2089 | * Returns true for supported, false for not supported | ||
2090 | */ | ||
2091 | bool amdgpu_device_has_dc_support(struct amdgpu_device *adev) | ||
2092 | { | ||
2093 | if (amdgpu_sriov_vf(adev)) | ||
2094 | return false; | ||
2095 | |||
2096 | return amdgpu_device_asic_has_dc_support(adev->asic_type); | ||
2097 | } | ||
2098 | |||
2099 | /** | ||
1946 | * amdgpu_device_init - initialize the driver | 2100 | * amdgpu_device_init - initialize the driver |
1947 | * | 2101 | * |
1948 | * @adev: amdgpu_device pointer | 2102 | * @adev: amdgpu_device pointer |
@@ -1979,6 +2133,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1979 | adev->vm_manager.vm_pte_num_rings = 0; | 2133 | adev->vm_manager.vm_pte_num_rings = 0; |
1980 | adev->gart.gart_funcs = NULL; | 2134 | adev->gart.gart_funcs = NULL; |
1981 | adev->fence_context = dma_fence_context_alloc(AMDGPU_MAX_RINGS); | 2135 | adev->fence_context = dma_fence_context_alloc(AMDGPU_MAX_RINGS); |
2136 | bitmap_zero(adev->gfx.pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES); | ||
1982 | 2137 | ||
1983 | adev->smc_rreg = &amdgpu_invalid_rreg; | 2138 | adev->smc_rreg = &amdgpu_invalid_rreg; |
1984 | adev->smc_wreg = &amdgpu_invalid_wreg; | 2139 | adev->smc_wreg = &amdgpu_invalid_wreg; |
@@ -1995,7 +2150,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1995 | adev->audio_endpt_rreg = &amdgpu_block_invalid_rreg; | 2150 | adev->audio_endpt_rreg = &amdgpu_block_invalid_rreg; |
1996 | adev->audio_endpt_wreg = &amdgpu_block_invalid_wreg; | 2151 | adev->audio_endpt_wreg = &amdgpu_block_invalid_wreg; |
1997 | 2152 | ||
1998 | |||
1999 | DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X 0x%02X).\n", | 2153 | DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X 0x%02X).\n", |
2000 | amdgpu_asic_name[adev->asic_type], pdev->vendor, pdev->device, | 2154 | amdgpu_asic_name[adev->asic_type], pdev->vendor, pdev->device, |
2001 | pdev->subsystem_vendor, pdev->subsystem_device, pdev->revision); | 2155 | pdev->subsystem_vendor, pdev->subsystem_device, pdev->revision); |
@@ -2007,8 +2161,10 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
2007 | mutex_init(&adev->pm.mutex); | 2161 | mutex_init(&adev->pm.mutex); |
2008 | mutex_init(&adev->gfx.gpu_clock_mutex); | 2162 | mutex_init(&adev->gfx.gpu_clock_mutex); |
2009 | mutex_init(&adev->srbm_mutex); | 2163 | mutex_init(&adev->srbm_mutex); |
2164 | mutex_init(&adev->gfx.pipe_reserve_mutex); | ||
2010 | mutex_init(&adev->grbm_idx_mutex); | 2165 | mutex_init(&adev->grbm_idx_mutex); |
2011 | mutex_init(&adev->mn_lock); | 2166 | mutex_init(&adev->mn_lock); |
2167 | mutex_init(&adev->virt.vf_errors.lock); | ||
2012 | hash_init(adev->mn_hash); | 2168 | hash_init(adev->mn_hash); |
2013 | 2169 | ||
2014 | amdgpu_check_arguments(adev); | 2170 | amdgpu_check_arguments(adev); |
@@ -2051,9 +2207,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
2051 | DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)adev->rmmio_base); | 2207 | DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)adev->rmmio_base); |
2052 | DRM_INFO("register mmio size: %u\n", (unsigned)adev->rmmio_size); | 2208 | DRM_INFO("register mmio size: %u\n", (unsigned)adev->rmmio_size); |
2053 | 2209 | ||
2054 | if (adev->asic_type >= CHIP_BONAIRE) | 2210 | /* doorbell bar mapping */ |
2055 | /* doorbell bar mapping */ | 2211 | amdgpu_doorbell_init(adev); |
2056 | amdgpu_doorbell_init(adev); | ||
2057 | 2212 | ||
2058 | /* io port mapping */ | 2213 | /* io port mapping */ |
2059 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 2214 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
@@ -2095,7 +2250,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
2095 | r = amdgpu_atombios_init(adev); | 2250 | r = amdgpu_atombios_init(adev); |
2096 | if (r) { | 2251 | if (r) { |
2097 | dev_err(adev->dev, "amdgpu_atombios_init failed\n"); | 2252 | dev_err(adev->dev, "amdgpu_atombios_init failed\n"); |
2098 | amdgpu_vf_error_put(AMDGIM_ERROR_VF_ATOMBIOS_INIT_FAIL, 0, 0); | 2253 | amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_ATOMBIOS_INIT_FAIL, 0, 0); |
2099 | goto failed; | 2254 | goto failed; |
2100 | } | 2255 | } |
2101 | 2256 | ||
@@ -2103,10 +2258,9 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
2103 | amdgpu_device_detect_sriov_bios(adev); | 2258 | amdgpu_device_detect_sriov_bios(adev); |
2104 | 2259 | ||
2105 | /* Post card if necessary */ | 2260 | /* Post card if necessary */ |
2106 | if (amdgpu_vpost_needed(adev)) { | 2261 | if (amdgpu_need_post(adev)) { |
2107 | if (!adev->bios) { | 2262 | if (!adev->bios) { |
2108 | dev_err(adev->dev, "no vBIOS found\n"); | 2263 | dev_err(adev->dev, "no vBIOS found\n"); |
2109 | amdgpu_vf_error_put(AMDGIM_ERROR_VF_NO_VBIOS, 0, 0); | ||
2110 | r = -EINVAL; | 2264 | r = -EINVAL; |
2111 | goto failed; | 2265 | goto failed; |
2112 | } | 2266 | } |
@@ -2114,7 +2268,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
2114 | r = amdgpu_atom_asic_init(adev->mode_info.atom_context); | 2268 | r = amdgpu_atom_asic_init(adev->mode_info.atom_context); |
2115 | if (r) { | 2269 | if (r) { |
2116 | dev_err(adev->dev, "gpu post error!\n"); | 2270 | dev_err(adev->dev, "gpu post error!\n"); |
2117 | amdgpu_vf_error_put(AMDGIM_ERROR_VF_GPU_POST_ERROR, 0, 0); | ||
2118 | goto failed; | 2271 | goto failed; |
2119 | } | 2272 | } |
2120 | } else { | 2273 | } else { |
@@ -2126,7 +2279,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
2126 | r = amdgpu_atomfirmware_get_clock_info(adev); | 2279 | r = amdgpu_atomfirmware_get_clock_info(adev); |
2127 | if (r) { | 2280 | if (r) { |
2128 | dev_err(adev->dev, "amdgpu_atomfirmware_get_clock_info failed\n"); | 2281 | dev_err(adev->dev, "amdgpu_atomfirmware_get_clock_info failed\n"); |
2129 | amdgpu_vf_error_put(AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL, 0, 0); | 2282 | amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL, 0, 0); |
2130 | goto failed; | 2283 | goto failed; |
2131 | } | 2284 | } |
2132 | } else { | 2285 | } else { |
@@ -2134,18 +2287,19 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
2134 | r = amdgpu_atombios_get_clock_info(adev); | 2287 | r = amdgpu_atombios_get_clock_info(adev); |
2135 | if (r) { | 2288 | if (r) { |
2136 | dev_err(adev->dev, "amdgpu_atombios_get_clock_info failed\n"); | 2289 | dev_err(adev->dev, "amdgpu_atombios_get_clock_info failed\n"); |
2137 | amdgpu_vf_error_put(AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL, 0, 0); | 2290 | amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL, 0, 0); |
2138 | goto failed; | 2291 | goto failed; |
2139 | } | 2292 | } |
2140 | /* init i2c buses */ | 2293 | /* init i2c buses */ |
2141 | amdgpu_atombios_i2c_init(adev); | 2294 | if (!amdgpu_device_has_dc_support(adev)) |
2295 | amdgpu_atombios_i2c_init(adev); | ||
2142 | } | 2296 | } |
2143 | 2297 | ||
2144 | /* Fence driver */ | 2298 | /* Fence driver */ |
2145 | r = amdgpu_fence_driver_init(adev); | 2299 | r = amdgpu_fence_driver_init(adev); |
2146 | if (r) { | 2300 | if (r) { |
2147 | dev_err(adev->dev, "amdgpu_fence_driver_init failed\n"); | 2301 | dev_err(adev->dev, "amdgpu_fence_driver_init failed\n"); |
2148 | amdgpu_vf_error_put(AMDGIM_ERROR_VF_FENCE_INIT_FAIL, 0, 0); | 2302 | amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_FENCE_INIT_FAIL, 0, 0); |
2149 | goto failed; | 2303 | goto failed; |
2150 | } | 2304 | } |
2151 | 2305 | ||
@@ -2155,7 +2309,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
2155 | r = amdgpu_init(adev); | 2309 | r = amdgpu_init(adev); |
2156 | if (r) { | 2310 | if (r) { |
2157 | dev_err(adev->dev, "amdgpu_init failed\n"); | 2311 | dev_err(adev->dev, "amdgpu_init failed\n"); |
2158 | amdgpu_vf_error_put(AMDGIM_ERROR_VF_AMDGPU_INIT_FAIL, 0, 0); | 2312 | amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_AMDGPU_INIT_FAIL, 0, 0); |
2159 | amdgpu_fini(adev); | 2313 | amdgpu_fini(adev); |
2160 | goto failed; | 2314 | goto failed; |
2161 | } | 2315 | } |
@@ -2175,7 +2329,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
2175 | r = amdgpu_ib_pool_init(adev); | 2329 | r = amdgpu_ib_pool_init(adev); |
2176 | if (r) { | 2330 | if (r) { |
2177 | dev_err(adev->dev, "IB initialization failed (%d).\n", r); | 2331 | dev_err(adev->dev, "IB initialization failed (%d).\n", r); |
2178 | amdgpu_vf_error_put(AMDGIM_ERROR_VF_IB_INIT_FAIL, 0, r); | 2332 | amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_IB_INIT_FAIL, 0, r); |
2179 | goto failed; | 2333 | goto failed; |
2180 | } | 2334 | } |
2181 | 2335 | ||
@@ -2183,8 +2337,15 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
2183 | if (r) | 2337 | if (r) |
2184 | DRM_ERROR("ib ring test failed (%d).\n", r); | 2338 | DRM_ERROR("ib ring test failed (%d).\n", r); |
2185 | 2339 | ||
2340 | if (amdgpu_sriov_vf(adev)) | ||
2341 | amdgpu_virt_init_data_exchange(adev); | ||
2342 | |||
2186 | amdgpu_fbdev_init(adev); | 2343 | amdgpu_fbdev_init(adev); |
2187 | 2344 | ||
2345 | r = amdgpu_pm_sysfs_init(adev); | ||
2346 | if (r) | ||
2347 | DRM_ERROR("registering pm debugfs failed (%d).\n", r); | ||
2348 | |||
2188 | r = amdgpu_gem_debugfs_init(adev); | 2349 | r = amdgpu_gem_debugfs_init(adev); |
2189 | if (r) | 2350 | if (r) |
2190 | DRM_ERROR("registering gem debugfs failed (%d).\n", r); | 2351 | DRM_ERROR("registering gem debugfs failed (%d).\n", r); |
@@ -2201,6 +2362,10 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
2201 | if (r) | 2362 | if (r) |
2202 | DRM_ERROR("registering firmware debugfs failed (%d).\n", r); | 2363 | DRM_ERROR("registering firmware debugfs failed (%d).\n", r); |
2203 | 2364 | ||
2365 | r = amdgpu_debugfs_vbios_dump_init(adev); | ||
2366 | if (r) | ||
2367 | DRM_ERROR("Creating vbios dump debugfs failed (%d).\n", r); | ||
2368 | |||
2204 | if ((amdgpu_testing & 1)) { | 2369 | if ((amdgpu_testing & 1)) { |
2205 | if (adev->accel_working) | 2370 | if (adev->accel_working) |
2206 | amdgpu_test_moves(adev); | 2371 | amdgpu_test_moves(adev); |
@@ -2220,7 +2385,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
2220 | r = amdgpu_late_init(adev); | 2385 | r = amdgpu_late_init(adev); |
2221 | if (r) { | 2386 | if (r) { |
2222 | dev_err(adev->dev, "amdgpu_late_init failed\n"); | 2387 | dev_err(adev->dev, "amdgpu_late_init failed\n"); |
2223 | amdgpu_vf_error_put(AMDGIM_ERROR_VF_AMDGPU_LATE_INIT_FAIL, 0, r); | 2388 | amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_AMDGPU_LATE_INIT_FAIL, 0, r); |
2224 | goto failed; | 2389 | goto failed; |
2225 | } | 2390 | } |
2226 | 2391 | ||
@@ -2252,6 +2417,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev) | |||
2252 | /* evict vram memory */ | 2417 | /* evict vram memory */ |
2253 | amdgpu_bo_evict_vram(adev); | 2418 | amdgpu_bo_evict_vram(adev); |
2254 | amdgpu_ib_pool_fini(adev); | 2419 | amdgpu_ib_pool_fini(adev); |
2420 | amdgpu_fw_reserve_vram_fini(adev); | ||
2255 | amdgpu_fence_driver_fini(adev); | 2421 | amdgpu_fence_driver_fini(adev); |
2256 | amdgpu_fbdev_fini(adev); | 2422 | amdgpu_fbdev_fini(adev); |
2257 | r = amdgpu_fini(adev); | 2423 | r = amdgpu_fini(adev); |
@@ -2262,7 +2428,8 @@ void amdgpu_device_fini(struct amdgpu_device *adev) | |||
2262 | adev->accel_working = false; | 2428 | adev->accel_working = false; |
2263 | cancel_delayed_work_sync(&adev->late_init_work); | 2429 | cancel_delayed_work_sync(&adev->late_init_work); |
2264 | /* free i2c buses */ | 2430 | /* free i2c buses */ |
2265 | amdgpu_i2c_fini(adev); | 2431 | if (!amdgpu_device_has_dc_support(adev)) |
2432 | amdgpu_i2c_fini(adev); | ||
2266 | amdgpu_atombios_fini(adev); | 2433 | amdgpu_atombios_fini(adev); |
2267 | kfree(adev->bios); | 2434 | kfree(adev->bios); |
2268 | adev->bios = NULL; | 2435 | adev->bios = NULL; |
@@ -2276,8 +2443,8 @@ void amdgpu_device_fini(struct amdgpu_device *adev) | |||
2276 | adev->rio_mem = NULL; | 2443 | adev->rio_mem = NULL; |
2277 | iounmap(adev->rmmio); | 2444 | iounmap(adev->rmmio); |
2278 | adev->rmmio = NULL; | 2445 | adev->rmmio = NULL; |
2279 | if (adev->asic_type >= CHIP_BONAIRE) | 2446 | amdgpu_doorbell_fini(adev); |
2280 | amdgpu_doorbell_fini(adev); | 2447 | amdgpu_pm_sysfs_fini(adev); |
2281 | amdgpu_debugfs_regs_cleanup(adev); | 2448 | amdgpu_debugfs_regs_cleanup(adev); |
2282 | } | 2449 | } |
2283 | 2450 | ||
@@ -2313,12 +2480,14 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) | |||
2313 | 2480 | ||
2314 | drm_kms_helper_poll_disable(dev); | 2481 | drm_kms_helper_poll_disable(dev); |
2315 | 2482 | ||
2316 | /* turn off display hw */ | 2483 | if (!amdgpu_device_has_dc_support(adev)) { |
2317 | drm_modeset_lock_all(dev); | 2484 | /* turn off display hw */ |
2318 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 2485 | drm_modeset_lock_all(dev); |
2319 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); | 2486 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
2487 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); | ||
2488 | } | ||
2489 | drm_modeset_unlock_all(dev); | ||
2320 | } | 2490 | } |
2321 | drm_modeset_unlock_all(dev); | ||
2322 | 2491 | ||
2323 | amdgpu_amdkfd_suspend(adev); | 2492 | amdgpu_amdkfd_suspend(adev); |
2324 | 2493 | ||
@@ -2461,13 +2630,25 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) | |||
2461 | 2630 | ||
2462 | /* blat the mode back in */ | 2631 | /* blat the mode back in */ |
2463 | if (fbcon) { | 2632 | if (fbcon) { |
2464 | drm_helper_resume_force_mode(dev); | 2633 | if (!amdgpu_device_has_dc_support(adev)) { |
2465 | /* turn on display hw */ | 2634 | /* pre DCE11 */ |
2466 | drm_modeset_lock_all(dev); | 2635 | drm_helper_resume_force_mode(dev); |
2467 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 2636 | |
2468 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); | 2637 | /* turn on display hw */ |
2638 | drm_modeset_lock_all(dev); | ||
2639 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
2640 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); | ||
2641 | } | ||
2642 | drm_modeset_unlock_all(dev); | ||
2643 | } else { | ||
2644 | /* | ||
2645 | * There is no equivalent atomic helper to turn on | ||
2646 | * display, so we defined our own function for this, | ||
2647 | * once suspend resume is supported by the atomic | ||
2648 | * framework this will be reworked | ||
2649 | */ | ||
2650 | amdgpu_dm_display_resume(adev); | ||
2469 | } | 2651 | } |
2470 | drm_modeset_unlock_all(dev); | ||
2471 | } | 2652 | } |
2472 | 2653 | ||
2473 | drm_kms_helper_poll_enable(dev); | 2654 | drm_kms_helper_poll_enable(dev); |
@@ -2484,7 +2665,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) | |||
2484 | #ifdef CONFIG_PM | 2665 | #ifdef CONFIG_PM |
2485 | dev->dev->power.disable_depth++; | 2666 | dev->dev->power.disable_depth++; |
2486 | #endif | 2667 | #endif |
2487 | drm_helper_hpd_irq_event(dev); | 2668 | if (!amdgpu_device_has_dc_support(adev)) |
2669 | drm_helper_hpd_irq_event(dev); | ||
2670 | else | ||
2671 | drm_kms_helper_hotplug_event(dev); | ||
2488 | #ifdef CONFIG_PM | 2672 | #ifdef CONFIG_PM |
2489 | dev->dev->power.disable_depth--; | 2673 | dev->dev->power.disable_depth--; |
2490 | #endif | 2674 | #endif |
@@ -2504,6 +2688,9 @@ static bool amdgpu_check_soft_reset(struct amdgpu_device *adev) | |||
2504 | int i; | 2688 | int i; |
2505 | bool asic_hang = false; | 2689 | bool asic_hang = false; |
2506 | 2690 | ||
2691 | if (amdgpu_sriov_vf(adev)) | ||
2692 | return true; | ||
2693 | |||
2507 | for (i = 0; i < adev->num_ip_blocks; i++) { | 2694 | for (i = 0; i < adev->num_ip_blocks; i++) { |
2508 | if (!adev->ip_blocks[i].status.valid) | 2695 | if (!adev->ip_blocks[i].status.valid) |
2509 | continue; | 2696 | continue; |
@@ -2546,7 +2733,8 @@ static bool amdgpu_need_full_reset(struct amdgpu_device *adev) | |||
2546 | if ((adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) || | 2733 | if ((adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) || |
2547 | (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) || | 2734 | (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) || |
2548 | (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_ACP) || | 2735 | (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_ACP) || |
2549 | (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE)) { | 2736 | (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE) || |
2737 | adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP) { | ||
2550 | if (adev->ip_blocks[i].status.hang) { | 2738 | if (adev->ip_blocks[i].status.hang) { |
2551 | DRM_INFO("Some block need full reset!\n"); | 2739 | DRM_INFO("Some block need full reset!\n"); |
2552 | return true; | 2740 | return true; |
@@ -2654,7 +2842,7 @@ int amdgpu_sriov_gpu_reset(struct amdgpu_device *adev, struct amdgpu_job *job) | |||
2654 | 2842 | ||
2655 | mutex_lock(&adev->virt.lock_reset); | 2843 | mutex_lock(&adev->virt.lock_reset); |
2656 | atomic_inc(&adev->gpu_reset_counter); | 2844 | atomic_inc(&adev->gpu_reset_counter); |
2657 | adev->gfx.in_reset = true; | 2845 | adev->in_sriov_reset = true; |
2658 | 2846 | ||
2659 | /* block TTM */ | 2847 | /* block TTM */ |
2660 | resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev); | 2848 | resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev); |
@@ -2765,7 +2953,7 @@ give_up_reset: | |||
2765 | dev_info(adev->dev, "GPU reset successed!\n"); | 2953 | dev_info(adev->dev, "GPU reset successed!\n"); |
2766 | } | 2954 | } |
2767 | 2955 | ||
2768 | adev->gfx.in_reset = false; | 2956 | adev->in_sriov_reset = false; |
2769 | mutex_unlock(&adev->virt.lock_reset); | 2957 | mutex_unlock(&adev->virt.lock_reset); |
2770 | return r; | 2958 | return r; |
2771 | } | 2959 | } |
@@ -2780,6 +2968,7 @@ give_up_reset: | |||
2780 | */ | 2968 | */ |
2781 | int amdgpu_gpu_reset(struct amdgpu_device *adev) | 2969 | int amdgpu_gpu_reset(struct amdgpu_device *adev) |
2782 | { | 2970 | { |
2971 | struct drm_atomic_state *state = NULL; | ||
2783 | int i, r; | 2972 | int i, r; |
2784 | int resched; | 2973 | int resched; |
2785 | bool need_full_reset, vram_lost = false; | 2974 | bool need_full_reset, vram_lost = false; |
@@ -2793,6 +2982,9 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev) | |||
2793 | 2982 | ||
2794 | /* block TTM */ | 2983 | /* block TTM */ |
2795 | resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev); | 2984 | resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev); |
2985 | /* store modesetting */ | ||
2986 | if (amdgpu_device_has_dc_support(adev)) | ||
2987 | state = drm_atomic_helper_suspend(adev->ddev); | ||
2796 | 2988 | ||
2797 | /* block scheduler */ | 2989 | /* block scheduler */ |
2798 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 2990 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
@@ -2902,7 +3094,6 @@ out: | |||
2902 | } | 3094 | } |
2903 | } else { | 3095 | } else { |
2904 | dev_err(adev->dev, "asic resume failed (%d).\n", r); | 3096 | dev_err(adev->dev, "asic resume failed (%d).\n", r); |
2905 | amdgpu_vf_error_put(AMDGIM_ERROR_VF_ASIC_RESUME_FAIL, 0, r); | ||
2906 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 3097 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
2907 | if (adev->rings[i] && adev->rings[i]->sched.thread) { | 3098 | if (adev->rings[i] && adev->rings[i]->sched.thread) { |
2908 | kthread_unpark(adev->rings[i]->sched.thread); | 3099 | kthread_unpark(adev->rings[i]->sched.thread); |
@@ -2910,13 +3101,16 @@ out: | |||
2910 | } | 3101 | } |
2911 | } | 3102 | } |
2912 | 3103 | ||
2913 | drm_helper_resume_force_mode(adev->ddev); | 3104 | if (amdgpu_device_has_dc_support(adev)) { |
3105 | r = drm_atomic_helper_resume(adev->ddev, state); | ||
3106 | amdgpu_dm_display_resume(adev); | ||
3107 | } else | ||
3108 | drm_helper_resume_force_mode(adev->ddev); | ||
2914 | 3109 | ||
2915 | ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched); | 3110 | ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched); |
2916 | if (r) { | 3111 | if (r) { |
2917 | /* bad news, how to tell it to userspace ? */ | 3112 | /* bad news, how to tell it to userspace ? */ |
2918 | dev_info(adev->dev, "GPU reset failed\n"); | 3113 | dev_info(adev->dev, "GPU reset failed\n"); |
2919 | amdgpu_vf_error_put(AMDGIM_ERROR_VF_GPU_RESET_FAIL, 0, r); | ||
2920 | } | 3114 | } |
2921 | else { | 3115 | else { |
2922 | dev_info(adev->dev, "GPU reset successed!\n"); | 3116 | dev_info(adev->dev, "GPU reset successed!\n"); |
@@ -3070,9 +3264,9 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf, | |||
3070 | pm_pg_lock = (*pos >> 23) & 1; | 3264 | pm_pg_lock = (*pos >> 23) & 1; |
3071 | 3265 | ||
3072 | if (*pos & (1ULL << 62)) { | 3266 | if (*pos & (1ULL << 62)) { |
3073 | se_bank = (*pos >> 24) & 0x3FF; | 3267 | se_bank = (*pos & GENMASK_ULL(33, 24)) >> 24; |
3074 | sh_bank = (*pos >> 34) & 0x3FF; | 3268 | sh_bank = (*pos & GENMASK_ULL(43, 34)) >> 34; |
3075 | instance_bank = (*pos >> 44) & 0x3FF; | 3269 | instance_bank = (*pos & GENMASK_ULL(53, 44)) >> 44; |
3076 | 3270 | ||
3077 | if (se_bank == 0x3FF) | 3271 | if (se_bank == 0x3FF) |
3078 | se_bank = 0xFFFFFFFF; | 3272 | se_bank = 0xFFFFFFFF; |
@@ -3146,9 +3340,9 @@ static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf, | |||
3146 | pm_pg_lock = (*pos >> 23) & 1; | 3340 | pm_pg_lock = (*pos >> 23) & 1; |
3147 | 3341 | ||
3148 | if (*pos & (1ULL << 62)) { | 3342 | if (*pos & (1ULL << 62)) { |
3149 | se_bank = (*pos >> 24) & 0x3FF; | 3343 | se_bank = (*pos & GENMASK_ULL(33, 24)) >> 24; |
3150 | sh_bank = (*pos >> 34) & 0x3FF; | 3344 | sh_bank = (*pos & GENMASK_ULL(43, 34)) >> 34; |
3151 | instance_bank = (*pos >> 44) & 0x3FF; | 3345 | instance_bank = (*pos & GENMASK_ULL(53, 44)) >> 44; |
3152 | 3346 | ||
3153 | if (se_bank == 0x3FF) | 3347 | if (se_bank == 0x3FF) |
3154 | se_bank = 0xFFFFFFFF; | 3348 | se_bank = 0xFFFFFFFF; |
@@ -3463,10 +3657,7 @@ static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf, | |||
3463 | 3657 | ||
3464 | valuesize = sizeof(values); | 3658 | valuesize = sizeof(values); |
3465 | if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->read_sensor) | 3659 | if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->read_sensor) |
3466 | r = adev->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle, idx, &values[0], &valuesize); | 3660 | r = amdgpu_dpm_read_sensor(adev, idx, &values[0], &valuesize); |
3467 | else if (adev->pm.funcs && adev->pm.funcs->read_sensor) | ||
3468 | r = adev->pm.funcs->read_sensor(adev, idx, &values[0], | ||
3469 | &valuesize); | ||
3470 | else | 3661 | else |
3471 | return -EINVAL; | 3662 | return -EINVAL; |
3472 | 3663 | ||
@@ -3499,12 +3690,12 @@ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf, | |||
3499 | return -EINVAL; | 3690 | return -EINVAL; |
3500 | 3691 | ||
3501 | /* decode offset */ | 3692 | /* decode offset */ |
3502 | offset = (*pos & 0x7F); | 3693 | offset = (*pos & GENMASK_ULL(6, 0)); |
3503 | se = ((*pos >> 7) & 0xFF); | 3694 | se = (*pos & GENMASK_ULL(14, 7)) >> 7; |
3504 | sh = ((*pos >> 15) & 0xFF); | 3695 | sh = (*pos & GENMASK_ULL(22, 15)) >> 15; |
3505 | cu = ((*pos >> 23) & 0xFF); | 3696 | cu = (*pos & GENMASK_ULL(30, 23)) >> 23; |
3506 | wave = ((*pos >> 31) & 0xFF); | 3697 | wave = (*pos & GENMASK_ULL(36, 31)) >> 31; |
3507 | simd = ((*pos >> 37) & 0xFF); | 3698 | simd = (*pos & GENMASK_ULL(44, 37)) >> 37; |
3508 | 3699 | ||
3509 | /* switch to the specific se/sh/cu */ | 3700 | /* switch to the specific se/sh/cu */ |
3510 | mutex_lock(&adev->grbm_idx_mutex); | 3701 | mutex_lock(&adev->grbm_idx_mutex); |
@@ -3549,14 +3740,14 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf, | |||
3549 | return -EINVAL; | 3740 | return -EINVAL; |
3550 | 3741 | ||
3551 | /* decode offset */ | 3742 | /* decode offset */ |
3552 | offset = (*pos & 0xFFF); /* in dwords */ | 3743 | offset = *pos & GENMASK_ULL(11, 0); |
3553 | se = ((*pos >> 12) & 0xFF); | 3744 | se = (*pos & GENMASK_ULL(19, 12)) >> 12; |
3554 | sh = ((*pos >> 20) & 0xFF); | 3745 | sh = (*pos & GENMASK_ULL(27, 20)) >> 20; |
3555 | cu = ((*pos >> 28) & 0xFF); | 3746 | cu = (*pos & GENMASK_ULL(35, 28)) >> 28; |
3556 | wave = ((*pos >> 36) & 0xFF); | 3747 | wave = (*pos & GENMASK_ULL(43, 36)) >> 36; |
3557 | simd = ((*pos >> 44) & 0xFF); | 3748 | simd = (*pos & GENMASK_ULL(51, 44)) >> 44; |
3558 | thread = ((*pos >> 52) & 0xFF); | 3749 | thread = (*pos & GENMASK_ULL(59, 52)) >> 52; |
3559 | bank = ((*pos >> 60) & 1); | 3750 | bank = (*pos & GENMASK_ULL(61, 60)) >> 60; |
3560 | 3751 | ||
3561 | data = kmalloc_array(1024, sizeof(*data), GFP_KERNEL); | 3752 | data = kmalloc_array(1024, sizeof(*data), GFP_KERNEL); |
3562 | if (!data) | 3753 | if (!data) |
@@ -3754,6 +3945,28 @@ int amdgpu_debugfs_init(struct drm_minor *minor) | |||
3754 | { | 3945 | { |
3755 | return 0; | 3946 | return 0; |
3756 | } | 3947 | } |
3948 | |||
3949 | static int amdgpu_debugfs_get_vbios_dump(struct seq_file *m, void *data) | ||
3950 | { | ||
3951 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
3952 | struct drm_device *dev = node->minor->dev; | ||
3953 | struct amdgpu_device *adev = dev->dev_private; | ||
3954 | |||
3955 | seq_write(m, adev->bios, adev->bios_size); | ||
3956 | return 0; | ||
3957 | } | ||
3958 | |||
3959 | static const struct drm_info_list amdgpu_vbios_dump_list[] = { | ||
3960 | {"amdgpu_vbios", | ||
3961 | amdgpu_debugfs_get_vbios_dump, | ||
3962 | 0, NULL}, | ||
3963 | }; | ||
3964 | |||
3965 | static int amdgpu_debugfs_vbios_dump_init(struct amdgpu_device *adev) | ||
3966 | { | ||
3967 | return amdgpu_debugfs_add_files(adev, | ||
3968 | amdgpu_vbios_dump_list, 1); | ||
3969 | } | ||
3757 | #else | 3970 | #else |
3758 | static int amdgpu_debugfs_test_ib_ring_init(struct amdgpu_device *adev) | 3971 | static int amdgpu_debugfs_test_ib_ring_init(struct amdgpu_device *adev) |
3759 | { | 3972 | { |
@@ -3763,5 +3976,9 @@ static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) | |||
3763 | { | 3976 | { |
3764 | return 0; | 3977 | return 0; |
3765 | } | 3978 | } |
3979 | static int amdgpu_debugfs_vbios_dump_init(struct amdgpu_device *adev) | ||
3980 | { | ||
3981 | return 0; | ||
3982 | } | ||
3766 | static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev) { } | 3983 | static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev) { } |
3767 | #endif | 3984 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 6ad243293a78..138beb550a58 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | |||
@@ -518,7 +518,7 @@ amdgpu_framebuffer_init(struct drm_device *dev, | |||
518 | return 0; | 518 | return 0; |
519 | } | 519 | } |
520 | 520 | ||
521 | static struct drm_framebuffer * | 521 | struct drm_framebuffer * |
522 | amdgpu_user_framebuffer_create(struct drm_device *dev, | 522 | amdgpu_user_framebuffer_create(struct drm_device *dev, |
523 | struct drm_file *file_priv, | 523 | struct drm_file *file_priv, |
524 | const struct drm_mode_fb_cmd2 *mode_cmd) | 524 | const struct drm_mode_fb_cmd2 *mode_cmd) |
@@ -556,7 +556,7 @@ amdgpu_user_framebuffer_create(struct drm_device *dev, | |||
556 | return &amdgpu_fb->base; | 556 | return &amdgpu_fb->base; |
557 | } | 557 | } |
558 | 558 | ||
559 | static void amdgpu_output_poll_changed(struct drm_device *dev) | 559 | void amdgpu_output_poll_changed(struct drm_device *dev) |
560 | { | 560 | { |
561 | struct amdgpu_device *adev = dev->dev_private; | 561 | struct amdgpu_device *adev = dev->dev_private; |
562 | amdgpu_fb_output_poll_changed(adev); | 562 | amdgpu_fb_output_poll_changed(adev); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.h new file mode 100644 index 000000000000..3cc0ef0c055e --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * Copyright 2017 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | #ifndef __AMDGPU_DISPLAY_H__ | ||
24 | #define __AMDGPU_DISPLAY_H__ | ||
25 | |||
26 | struct drm_framebuffer * | ||
27 | amdgpu_user_framebuffer_create(struct drm_device *dev, | ||
28 | struct drm_file *file_priv, | ||
29 | const struct drm_mode_fb_cmd2 *mode_cmd); | ||
30 | |||
31 | void amdgpu_output_poll_changed(struct drm_device *dev); | ||
32 | |||
33 | #endif | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c index 1cb52fd19060..e997ebbe43ea 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c | |||
@@ -960,8 +960,10 @@ u8 amdgpu_encode_pci_lane_width(u32 lanes) | |||
960 | } | 960 | } |
961 | 961 | ||
962 | struct amd_vce_state* | 962 | struct amd_vce_state* |
963 | amdgpu_get_vce_clock_state(struct amdgpu_device *adev, unsigned idx) | 963 | amdgpu_get_vce_clock_state(void *handle, u32 idx) |
964 | { | 964 | { |
965 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
966 | |||
965 | if (idx < adev->pm.dpm.num_of_vce_states) | 967 | if (idx < adev->pm.dpm.num_of_vce_states) |
966 | return &adev->pm.dpm.vce_states[idx]; | 968 | return &adev->pm.dpm.vce_states[idx]; |
967 | 969 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h index 8c96a4caa715..56caaeee6fea 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h | |||
@@ -241,179 +241,125 @@ enum amdgpu_pcie_gen { | |||
241 | AMDGPU_PCIE_GEN_INVALID = 0xffff | 241 | AMDGPU_PCIE_GEN_INVALID = 0xffff |
242 | }; | 242 | }; |
243 | 243 | ||
244 | struct amdgpu_dpm_funcs { | 244 | #define amdgpu_dpm_pre_set_power_state(adev) \ |
245 | int (*get_temperature)(struct amdgpu_device *adev); | 245 | ((adev)->powerplay.pp_funcs->pre_set_power_state((adev)->powerplay.pp_handle)) |
246 | int (*pre_set_power_state)(struct amdgpu_device *adev); | 246 | |
247 | int (*set_power_state)(struct amdgpu_device *adev); | 247 | #define amdgpu_dpm_set_power_state(adev) \ |
248 | void (*post_set_power_state)(struct amdgpu_device *adev); | 248 | ((adev)->powerplay.pp_funcs->set_power_state((adev)->powerplay.pp_handle)) |
249 | void (*display_configuration_changed)(struct amdgpu_device *adev); | 249 | |
250 | u32 (*get_sclk)(struct amdgpu_device *adev, bool low); | 250 | #define amdgpu_dpm_post_set_power_state(adev) \ |
251 | u32 (*get_mclk)(struct amdgpu_device *adev, bool low); | 251 | ((adev)->powerplay.pp_funcs->post_set_power_state((adev)->powerplay.pp_handle)) |
252 | void (*print_power_state)(struct amdgpu_device *adev, struct amdgpu_ps *ps); | 252 | |
253 | void (*debugfs_print_current_performance_level)(struct amdgpu_device *adev, struct seq_file *m); | 253 | #define amdgpu_dpm_display_configuration_changed(adev) \ |
254 | int (*force_performance_level)(struct amdgpu_device *adev, enum amd_dpm_forced_level level); | 254 | ((adev)->powerplay.pp_funcs->display_configuration_changed((adev)->powerplay.pp_handle)) |
255 | bool (*vblank_too_short)(struct amdgpu_device *adev); | ||
256 | void (*powergate_uvd)(struct amdgpu_device *adev, bool gate); | ||
257 | void (*powergate_vce)(struct amdgpu_device *adev, bool gate); | ||
258 | void (*enable_bapm)(struct amdgpu_device *adev, bool enable); | ||
259 | void (*set_fan_control_mode)(struct amdgpu_device *adev, u32 mode); | ||
260 | u32 (*get_fan_control_mode)(struct amdgpu_device *adev); | ||
261 | int (*set_fan_speed_percent)(struct amdgpu_device *adev, u32 speed); | ||
262 | int (*get_fan_speed_percent)(struct amdgpu_device *adev, u32 *speed); | ||
263 | int (*force_clock_level)(struct amdgpu_device *adev, enum pp_clock_type type, uint32_t mask); | ||
264 | int (*print_clock_levels)(struct amdgpu_device *adev, enum pp_clock_type type, char *buf); | ||
265 | int (*get_sclk_od)(struct amdgpu_device *adev); | ||
266 | int (*set_sclk_od)(struct amdgpu_device *adev, uint32_t value); | ||
267 | int (*get_mclk_od)(struct amdgpu_device *adev); | ||
268 | int (*set_mclk_od)(struct amdgpu_device *adev, uint32_t value); | ||
269 | int (*check_state_equal)(struct amdgpu_device *adev, | ||
270 | struct amdgpu_ps *cps, | ||
271 | struct amdgpu_ps *rps, | ||
272 | bool *equal); | ||
273 | int (*read_sensor)(struct amdgpu_device *adev, int idx, void *value, | ||
274 | int *size); | ||
275 | |||
276 | struct amd_vce_state* (*get_vce_clock_state)(struct amdgpu_device *adev, unsigned idx); | ||
277 | int (*reset_power_profile_state)(struct amdgpu_device *adev, | ||
278 | struct amd_pp_profile *request); | ||
279 | int (*get_power_profile_state)(struct amdgpu_device *adev, | ||
280 | struct amd_pp_profile *query); | ||
281 | int (*set_power_profile_state)(struct amdgpu_device *adev, | ||
282 | struct amd_pp_profile *request); | ||
283 | int (*switch_power_profile)(struct amdgpu_device *adev, | ||
284 | enum amd_pp_profile_type type); | ||
285 | }; | ||
286 | 255 | ||
287 | #define amdgpu_dpm_pre_set_power_state(adev) (adev)->pm.funcs->pre_set_power_state((adev)) | 256 | #define amdgpu_dpm_print_power_state(adev, ps) \ |
288 | #define amdgpu_dpm_set_power_state(adev) (adev)->pm.funcs->set_power_state((adev)) | 257 | ((adev)->powerplay.pp_funcs->print_power_state((adev)->powerplay.pp_handle, (ps))) |
289 | #define amdgpu_dpm_post_set_power_state(adev) (adev)->pm.funcs->post_set_power_state((adev)) | 258 | |
290 | #define amdgpu_dpm_display_configuration_changed(adev) (adev)->pm.funcs->display_configuration_changed((adev)) | 259 | #define amdgpu_dpm_vblank_too_short(adev) \ |
291 | #define amdgpu_dpm_print_power_state(adev, ps) (adev)->pm.funcs->print_power_state((adev), (ps)) | 260 | ((adev)->powerplay.pp_funcs->vblank_too_short((adev)->powerplay.pp_handle)) |
292 | #define amdgpu_dpm_vblank_too_short(adev) (adev)->pm.funcs->vblank_too_short((adev)) | 261 | |
293 | #define amdgpu_dpm_enable_bapm(adev, e) (adev)->pm.funcs->enable_bapm((adev), (e)) | 262 | #define amdgpu_dpm_enable_bapm(adev, e) \ |
263 | ((adev)->powerplay.pp_funcs->enable_bapm((adev)->powerplay.pp_handle, (e))) | ||
294 | 264 | ||
295 | #define amdgpu_dpm_read_sensor(adev, idx, value, size) \ | 265 | #define amdgpu_dpm_read_sensor(adev, idx, value, size) \ |
296 | ((adev)->pp_enabled ? \ | 266 | ((adev)->powerplay.pp_funcs->read_sensor((adev)->powerplay.pp_handle, (idx), (value), (size))) |
297 | (adev)->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle, (idx), (value), (size)) : \ | ||
298 | (adev)->pm.funcs->read_sensor((adev), (idx), (value), (size))) | ||
299 | 267 | ||
300 | #define amdgpu_dpm_get_temperature(adev) \ | 268 | #define amdgpu_dpm_get_temperature(adev) \ |
301 | ((adev)->pp_enabled ? \ | 269 | ((adev)->powerplay.pp_funcs->get_temperature((adev)->powerplay.pp_handle)) |
302 | (adev)->powerplay.pp_funcs->get_temperature((adev)->powerplay.pp_handle) : \ | ||
303 | (adev)->pm.funcs->get_temperature((adev))) | ||
304 | 270 | ||
305 | #define amdgpu_dpm_set_fan_control_mode(adev, m) \ | 271 | #define amdgpu_dpm_set_fan_control_mode(adev, m) \ |
306 | ((adev)->pp_enabled ? \ | 272 | ((adev)->powerplay.pp_funcs->set_fan_control_mode((adev)->powerplay.pp_handle, (m))) |
307 | (adev)->powerplay.pp_funcs->set_fan_control_mode((adev)->powerplay.pp_handle, (m)) : \ | ||
308 | (adev)->pm.funcs->set_fan_control_mode((adev), (m))) | ||
309 | 273 | ||
310 | #define amdgpu_dpm_get_fan_control_mode(adev) \ | 274 | #define amdgpu_dpm_get_fan_control_mode(adev) \ |
311 | ((adev)->pp_enabled ? \ | 275 | ((adev)->powerplay.pp_funcs->get_fan_control_mode((adev)->powerplay.pp_handle)) |
312 | (adev)->powerplay.pp_funcs->get_fan_control_mode((adev)->powerplay.pp_handle) : \ | ||
313 | (adev)->pm.funcs->get_fan_control_mode((adev))) | ||
314 | 276 | ||
315 | #define amdgpu_dpm_set_fan_speed_percent(adev, s) \ | 277 | #define amdgpu_dpm_set_fan_speed_percent(adev, s) \ |
316 | ((adev)->pp_enabled ? \ | 278 | ((adev)->powerplay.pp_funcs->set_fan_speed_percent((adev)->powerplay.pp_handle, (s))) |
317 | (adev)->powerplay.pp_funcs->set_fan_speed_percent((adev)->powerplay.pp_handle, (s)) : \ | ||
318 | (adev)->pm.funcs->set_fan_speed_percent((adev), (s))) | ||
319 | 279 | ||
320 | #define amdgpu_dpm_get_fan_speed_percent(adev, s) \ | 280 | #define amdgpu_dpm_get_fan_speed_percent(adev, s) \ |
321 | ((adev)->pp_enabled ? \ | 281 | ((adev)->powerplay.pp_funcs->get_fan_speed_percent((adev)->powerplay.pp_handle, (s))) |
322 | (adev)->powerplay.pp_funcs->get_fan_speed_percent((adev)->powerplay.pp_handle, (s)) : \ | ||
323 | (adev)->pm.funcs->get_fan_speed_percent((adev), (s))) | ||
324 | 282 | ||
325 | #define amdgpu_dpm_get_fan_speed_rpm(adev, s) \ | 283 | #define amdgpu_dpm_get_fan_speed_rpm(adev, s) \ |
326 | ((adev)->pp_enabled ? \ | 284 | ((adev)->powerplay.pp_funcs->get_fan_speed_rpm)((adev)->powerplay.pp_handle, (s)) |
327 | (adev)->powerplay.pp_funcs->get_fan_speed_rpm((adev)->powerplay.pp_handle, (s)) : \ | ||
328 | -EINVAL) | ||
329 | 285 | ||
330 | #define amdgpu_dpm_get_sclk(adev, l) \ | 286 | #define amdgpu_dpm_get_sclk(adev, l) \ |
331 | ((adev)->pp_enabled ? \ | 287 | ((adev)->powerplay.pp_funcs->get_sclk((adev)->powerplay.pp_handle, (l))) |
332 | (adev)->powerplay.pp_funcs->get_sclk((adev)->powerplay.pp_handle, (l)) : \ | ||
333 | (adev)->pm.funcs->get_sclk((adev), (l))) | ||
334 | 288 | ||
335 | #define amdgpu_dpm_get_mclk(adev, l) \ | 289 | #define amdgpu_dpm_get_mclk(adev, l) \ |
336 | ((adev)->pp_enabled ? \ | 290 | ((adev)->powerplay.pp_funcs->get_mclk((adev)->powerplay.pp_handle, (l))) |
337 | (adev)->powerplay.pp_funcs->get_mclk((adev)->powerplay.pp_handle, (l)) : \ | ||
338 | (adev)->pm.funcs->get_mclk((adev), (l))) | ||
339 | |||
340 | 291 | ||
341 | #define amdgpu_dpm_force_performance_level(adev, l) \ | 292 | #define amdgpu_dpm_force_performance_level(adev, l) \ |
342 | ((adev)->pp_enabled ? \ | 293 | ((adev)->powerplay.pp_funcs->force_performance_level((adev)->powerplay.pp_handle, (l))) |
343 | (adev)->powerplay.pp_funcs->force_performance_level((adev)->powerplay.pp_handle, (l)) : \ | ||
344 | (adev)->pm.funcs->force_performance_level((adev), (l))) | ||
345 | 294 | ||
346 | #define amdgpu_dpm_powergate_uvd(adev, g) \ | 295 | #define amdgpu_dpm_powergate_uvd(adev, g) \ |
347 | ((adev)->pp_enabled ? \ | 296 | ((adev)->powerplay.pp_funcs->powergate_uvd((adev)->powerplay.pp_handle, (g))) |
348 | (adev)->powerplay.pp_funcs->powergate_uvd((adev)->powerplay.pp_handle, (g)) : \ | ||
349 | (adev)->pm.funcs->powergate_uvd((adev), (g))) | ||
350 | 297 | ||
351 | #define amdgpu_dpm_powergate_vce(adev, g) \ | 298 | #define amdgpu_dpm_powergate_vce(adev, g) \ |
352 | ((adev)->pp_enabled ? \ | 299 | ((adev)->powerplay.pp_funcs->powergate_vce((adev)->powerplay.pp_handle, (g))) |
353 | (adev)->powerplay.pp_funcs->powergate_vce((adev)->powerplay.pp_handle, (g)) : \ | ||
354 | (adev)->pm.funcs->powergate_vce((adev), (g))) | ||
355 | 300 | ||
356 | #define amdgpu_dpm_get_current_power_state(adev) \ | 301 | #define amdgpu_dpm_get_current_power_state(adev) \ |
357 | (adev)->powerplay.pp_funcs->get_current_power_state((adev)->powerplay.pp_handle) | 302 | ((adev)->powerplay.pp_funcs->get_current_power_state((adev)->powerplay.pp_handle)) |
358 | 303 | ||
359 | #define amdgpu_dpm_get_pp_num_states(adev, data) \ | 304 | #define amdgpu_dpm_get_pp_num_states(adev, data) \ |
360 | (adev)->powerplay.pp_funcs->get_pp_num_states((adev)->powerplay.pp_handle, data) | 305 | ((adev)->powerplay.pp_funcs->get_pp_num_states((adev)->powerplay.pp_handle, data)) |
361 | 306 | ||
362 | #define amdgpu_dpm_get_pp_table(adev, table) \ | 307 | #define amdgpu_dpm_get_pp_table(adev, table) \ |
363 | (adev)->powerplay.pp_funcs->get_pp_table((adev)->powerplay.pp_handle, table) | 308 | ((adev)->powerplay.pp_funcs->get_pp_table((adev)->powerplay.pp_handle, table)) |
364 | 309 | ||
365 | #define amdgpu_dpm_set_pp_table(adev, buf, size) \ | 310 | #define amdgpu_dpm_set_pp_table(adev, buf, size) \ |
366 | (adev)->powerplay.pp_funcs->set_pp_table((adev)->powerplay.pp_handle, buf, size) | 311 | ((adev)->powerplay.pp_funcs->set_pp_table((adev)->powerplay.pp_handle, buf, size)) |
367 | 312 | ||
368 | #define amdgpu_dpm_print_clock_levels(adev, type, buf) \ | 313 | #define amdgpu_dpm_print_clock_levels(adev, type, buf) \ |
369 | (adev)->powerplay.pp_funcs->print_clock_levels((adev)->powerplay.pp_handle, type, buf) | 314 | ((adev)->powerplay.pp_funcs->print_clock_levels((adev)->powerplay.pp_handle, type, buf)) |
370 | 315 | ||
371 | #define amdgpu_dpm_force_clock_level(adev, type, level) \ | 316 | #define amdgpu_dpm_force_clock_level(adev, type, level) \ |
372 | (adev)->powerplay.pp_funcs->force_clock_level((adev)->powerplay.pp_handle, type, level) | 317 | ((adev)->powerplay.pp_funcs->force_clock_level((adev)->powerplay.pp_handle, type, level)) |
373 | 318 | ||
374 | #define amdgpu_dpm_get_sclk_od(adev) \ | 319 | #define amdgpu_dpm_get_sclk_od(adev) \ |
375 | (adev)->powerplay.pp_funcs->get_sclk_od((adev)->powerplay.pp_handle) | 320 | ((adev)->powerplay.pp_funcs->get_sclk_od((adev)->powerplay.pp_handle)) |
376 | 321 | ||
377 | #define amdgpu_dpm_set_sclk_od(adev, value) \ | 322 | #define amdgpu_dpm_set_sclk_od(adev, value) \ |
378 | (adev)->powerplay.pp_funcs->set_sclk_od((adev)->powerplay.pp_handle, value) | 323 | ((adev)->powerplay.pp_funcs->set_sclk_od((adev)->powerplay.pp_handle, value)) |
379 | 324 | ||
380 | #define amdgpu_dpm_get_mclk_od(adev) \ | 325 | #define amdgpu_dpm_get_mclk_od(adev) \ |
381 | ((adev)->powerplay.pp_funcs->get_mclk_od((adev)->powerplay.pp_handle)) | 326 | ((adev)->powerplay.pp_funcs->get_mclk_od((adev)->powerplay.pp_handle)) |
382 | 327 | ||
383 | #define amdgpu_dpm_set_mclk_od(adev, value) \ | 328 | #define amdgpu_dpm_set_mclk_od(adev, value) \ |
384 | ((adev)->powerplay.pp_funcs->set_mclk_od((adev)->powerplay.pp_handle, value)) | 329 | ((adev)->powerplay.pp_funcs->set_mclk_od((adev)->powerplay.pp_handle, value)) |
385 | 330 | ||
386 | #define amdgpu_dpm_dispatch_task(adev, event_id, input, output) \ | 331 | #define amdgpu_dpm_dispatch_task(adev, task_id, input, output) \ |
387 | (adev)->powerplay.pp_funcs->dispatch_tasks((adev)->powerplay.pp_handle, (event_id), (input), (output)) | 332 | ((adev)->powerplay.pp_funcs->dispatch_tasks)((adev)->powerplay.pp_handle, (task_id), (input), (output)) |
388 | 333 | ||
389 | #define amgdpu_dpm_check_state_equal(adev, cps, rps, equal) (adev)->pm.funcs->check_state_equal((adev), (cps),(rps),(equal)) | 334 | #define amdgpu_dpm_check_state_equal(adev, cps, rps, equal) \ |
335 | ((adev)->powerplay.pp_funcs->check_state_equal((adev)->powerplay.pp_handle, (cps), (rps), (equal))) | ||
390 | 336 | ||
391 | #define amdgpu_dpm_get_vce_clock_state(adev, i) \ | 337 | #define amdgpu_dpm_get_vce_clock_state(adev, i) \ |
392 | ((adev)->pp_enabled ? \ | 338 | ((adev)->powerplay.pp_funcs->get_vce_clock_state((adev)->powerplay.pp_handle, (i))) |
393 | (adev)->powerplay.pp_funcs->get_vce_clock_state((adev)->powerplay.pp_handle, (i)) : \ | ||
394 | (adev)->pm.funcs->get_vce_clock_state((adev), (i))) | ||
395 | 339 | ||
396 | #define amdgpu_dpm_get_performance_level(adev) \ | 340 | #define amdgpu_dpm_get_performance_level(adev) \ |
397 | ((adev)->pp_enabled ? \ | 341 | ((adev)->powerplay.pp_funcs->get_performance_level((adev)->powerplay.pp_handle)) |
398 | (adev)->powerplay.pp_funcs->get_performance_level((adev)->powerplay.pp_handle) : \ | ||
399 | (adev)->pm.dpm.forced_level) | ||
400 | 342 | ||
401 | #define amdgpu_dpm_reset_power_profile_state(adev, request) \ | 343 | #define amdgpu_dpm_reset_power_profile_state(adev, request) \ |
402 | ((adev)->powerplay.pp_funcs->reset_power_profile_state(\ | 344 | ((adev)->powerplay.pp_funcs->reset_power_profile_state(\ |
403 | (adev)->powerplay.pp_handle, request)) | 345 | (adev)->powerplay.pp_handle, request)) |
404 | 346 | ||
405 | #define amdgpu_dpm_get_power_profile_state(adev, query) \ | 347 | #define amdgpu_dpm_get_power_profile_state(adev, query) \ |
406 | ((adev)->powerplay.pp_funcs->get_power_profile_state(\ | 348 | ((adev)->powerplay.pp_funcs->get_power_profile_state(\ |
407 | (adev)->powerplay.pp_handle, query)) | 349 | (adev)->powerplay.pp_handle, query)) |
408 | 350 | ||
409 | #define amdgpu_dpm_set_power_profile_state(adev, request) \ | 351 | #define amdgpu_dpm_set_power_profile_state(adev, request) \ |
410 | ((adev)->powerplay.pp_funcs->set_power_profile_state(\ | 352 | ((adev)->powerplay.pp_funcs->set_power_profile_state(\ |
411 | (adev)->powerplay.pp_handle, request)) | 353 | (adev)->powerplay.pp_handle, request)) |
412 | 354 | ||
413 | #define amdgpu_dpm_switch_power_profile(adev, type) \ | 355 | #define amdgpu_dpm_switch_power_profile(adev, type) \ |
414 | ((adev)->powerplay.pp_funcs->switch_power_profile(\ | 356 | ((adev)->powerplay.pp_funcs->switch_power_profile(\ |
415 | (adev)->powerplay.pp_handle, type)) | 357 | (adev)->powerplay.pp_handle, type)) |
416 | 358 | ||
359 | #define amdgpu_dpm_set_clockgating_by_smu(adev, msg_id) \ | ||
360 | ((adev)->powerplay.pp_funcs->set_clockgating_by_smu(\ | ||
361 | (adev)->powerplay.pp_handle, msg_id)) | ||
362 | |||
417 | struct amdgpu_dpm { | 363 | struct amdgpu_dpm { |
418 | struct amdgpu_ps *ps; | 364 | struct amdgpu_ps *ps; |
419 | /* number of valid power states */ | 365 | /* number of valid power states */ |
@@ -485,10 +431,9 @@ struct amdgpu_pm { | |||
485 | struct amdgpu_dpm dpm; | 431 | struct amdgpu_dpm dpm; |
486 | const struct firmware *fw; /* SMC firmware */ | 432 | const struct firmware *fw; /* SMC firmware */ |
487 | uint32_t fw_version; | 433 | uint32_t fw_version; |
488 | const struct amdgpu_dpm_funcs *funcs; | ||
489 | uint32_t pcie_gen_mask; | 434 | uint32_t pcie_gen_mask; |
490 | uint32_t pcie_mlw_mask; | 435 | uint32_t pcie_mlw_mask; |
491 | struct amd_pp_display_configuration pm_display_cfg;/* set by DAL */ | 436 | struct amd_pp_display_configuration pm_display_cfg;/* set by dc */ |
492 | }; | 437 | }; |
493 | 438 | ||
494 | #define R600_SSTU_DFLT 0 | 439 | #define R600_SSTU_DFLT 0 |
@@ -551,6 +496,6 @@ u16 amdgpu_get_pcie_lane_support(struct amdgpu_device *adev, | |||
551 | u8 amdgpu_encode_pci_lane_width(u32 lanes); | 496 | u8 amdgpu_encode_pci_lane_width(u32 lanes); |
552 | 497 | ||
553 | struct amd_vce_state* | 498 | struct amd_vce_state* |
554 | amdgpu_get_vce_clock_state(struct amdgpu_device *adev, unsigned idx); | 499 | amdgpu_get_vce_clock_state(void *handle, u32 idx); |
555 | 500 | ||
556 | #endif | 501 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 0f16986ec5bc..ec96bb1f9eaf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | |||
@@ -69,9 +69,13 @@ | |||
69 | * - 3.17.0 - Add AMDGPU_NUM_VRAM_CPU_PAGE_FAULTS. | 69 | * - 3.17.0 - Add AMDGPU_NUM_VRAM_CPU_PAGE_FAULTS. |
70 | * - 3.18.0 - Export gpu always on cu bitmap | 70 | * - 3.18.0 - Export gpu always on cu bitmap |
71 | * - 3.19.0 - Add support for UVD MJPEG decode | 71 | * - 3.19.0 - Add support for UVD MJPEG decode |
72 | * - 3.20.0 - Add support for local BOs | ||
73 | * - 3.21.0 - Add DRM_AMDGPU_FENCE_TO_HANDLE ioctl | ||
74 | * - 3.22.0 - Add DRM_AMDGPU_SCHED ioctl | ||
75 | * - 3.23.0 - Add query for VRAM lost counter | ||
72 | */ | 76 | */ |
73 | #define KMS_DRIVER_MAJOR 3 | 77 | #define KMS_DRIVER_MAJOR 3 |
74 | #define KMS_DRIVER_MINOR 19 | 78 | #define KMS_DRIVER_MINOR 23 |
75 | #define KMS_DRIVER_PATCHLEVEL 0 | 79 | #define KMS_DRIVER_PATCHLEVEL 0 |
76 | 80 | ||
77 | int amdgpu_vram_limit = 0; | 81 | int amdgpu_vram_limit = 0; |
@@ -91,7 +95,7 @@ int amdgpu_dpm = -1; | |||
91 | int amdgpu_fw_load_type = -1; | 95 | int amdgpu_fw_load_type = -1; |
92 | int amdgpu_aspm = -1; | 96 | int amdgpu_aspm = -1; |
93 | int amdgpu_runtime_pm = -1; | 97 | int amdgpu_runtime_pm = -1; |
94 | unsigned amdgpu_ip_block_mask = 0xffffffff; | 98 | uint amdgpu_ip_block_mask = 0xffffffff; |
95 | int amdgpu_bapm = -1; | 99 | int amdgpu_bapm = -1; |
96 | int amdgpu_deep_color = 0; | 100 | int amdgpu_deep_color = 0; |
97 | int amdgpu_vm_size = -1; | 101 | int amdgpu_vm_size = -1; |
@@ -102,18 +106,20 @@ int amdgpu_vm_debug = 0; | |||
102 | int amdgpu_vram_page_split = 512; | 106 | int amdgpu_vram_page_split = 512; |
103 | int amdgpu_vm_update_mode = -1; | 107 | int amdgpu_vm_update_mode = -1; |
104 | int amdgpu_exp_hw_support = 0; | 108 | int amdgpu_exp_hw_support = 0; |
109 | int amdgpu_dc = -1; | ||
110 | int amdgpu_dc_log = 0; | ||
105 | int amdgpu_sched_jobs = 32; | 111 | int amdgpu_sched_jobs = 32; |
106 | int amdgpu_sched_hw_submission = 2; | 112 | int amdgpu_sched_hw_submission = 2; |
107 | int amdgpu_no_evict = 0; | 113 | int amdgpu_no_evict = 0; |
108 | int amdgpu_direct_gma_size = 0; | 114 | int amdgpu_direct_gma_size = 0; |
109 | unsigned amdgpu_pcie_gen_cap = 0; | 115 | uint amdgpu_pcie_gen_cap = 0; |
110 | unsigned amdgpu_pcie_lane_cap = 0; | 116 | uint amdgpu_pcie_lane_cap = 0; |
111 | unsigned amdgpu_cg_mask = 0xffffffff; | 117 | uint amdgpu_cg_mask = 0xffffffff; |
112 | unsigned amdgpu_pg_mask = 0xffffffff; | 118 | uint amdgpu_pg_mask = 0xffffffff; |
113 | unsigned amdgpu_sdma_phase_quantum = 32; | 119 | uint amdgpu_sdma_phase_quantum = 32; |
114 | char *amdgpu_disable_cu = NULL; | 120 | char *amdgpu_disable_cu = NULL; |
115 | char *amdgpu_virtual_display = NULL; | 121 | char *amdgpu_virtual_display = NULL; |
116 | unsigned amdgpu_pp_feature_mask = 0xffffffff; | 122 | uint amdgpu_pp_feature_mask = 0xffffffff; |
117 | int amdgpu_ngg = 0; | 123 | int amdgpu_ngg = 0; |
118 | int amdgpu_prim_buf_per_se = 0; | 124 | int amdgpu_prim_buf_per_se = 0; |
119 | int amdgpu_pos_buf_per_se = 0; | 125 | int amdgpu_pos_buf_per_se = 0; |
@@ -121,6 +127,7 @@ int amdgpu_cntl_sb_buf_per_se = 0; | |||
121 | int amdgpu_param_buf_per_se = 0; | 127 | int amdgpu_param_buf_per_se = 0; |
122 | int amdgpu_job_hang_limit = 0; | 128 | int amdgpu_job_hang_limit = 0; |
123 | int amdgpu_lbpw = -1; | 129 | int amdgpu_lbpw = -1; |
130 | int amdgpu_compute_multipipe = -1; | ||
124 | 131 | ||
125 | MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes"); | 132 | MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes"); |
126 | module_param_named(vramlimit, amdgpu_vram_limit, int, 0600); | 133 | module_param_named(vramlimit, amdgpu_vram_limit, int, 0600); |
@@ -206,6 +213,12 @@ module_param_named(vram_page_split, amdgpu_vram_page_split, int, 0444); | |||
206 | MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))"); | 213 | MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))"); |
207 | module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444); | 214 | module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444); |
208 | 215 | ||
216 | MODULE_PARM_DESC(dc, "Display Core driver (1 = enable, 0 = disable, -1 = auto (default))"); | ||
217 | module_param_named(dc, amdgpu_dc, int, 0444); | ||
218 | |||
219 | MODULE_PARM_DESC(dc, "Display Core Log Level (0 = minimal (default), 1 = chatty"); | ||
220 | module_param_named(dc_log, amdgpu_dc_log, int, 0444); | ||
221 | |||
209 | MODULE_PARM_DESC(sched_jobs, "the max number of jobs supported in the sw queue (default 32)"); | 222 | MODULE_PARM_DESC(sched_jobs, "the max number of jobs supported in the sw queue (default 32)"); |
210 | module_param_named(sched_jobs, amdgpu_sched_jobs, int, 0444); | 223 | module_param_named(sched_jobs, amdgpu_sched_jobs, int, 0444); |
211 | 224 | ||
@@ -264,6 +277,9 @@ module_param_named(job_hang_limit, amdgpu_job_hang_limit, int ,0444); | |||
264 | MODULE_PARM_DESC(lbpw, "Load Balancing Per Watt (LBPW) support (1 = enable, 0 = disable, -1 = auto)"); | 277 | MODULE_PARM_DESC(lbpw, "Load Balancing Per Watt (LBPW) support (1 = enable, 0 = disable, -1 = auto)"); |
265 | module_param_named(lbpw, amdgpu_lbpw, int, 0444); | 278 | module_param_named(lbpw, amdgpu_lbpw, int, 0444); |
266 | 279 | ||
280 | MODULE_PARM_DESC(compute_multipipe, "Force compute queues to be spread across pipes (1 = enable, 0 = disable, -1 = auto)"); | ||
281 | module_param_named(compute_multipipe, amdgpu_compute_multipipe, int, 0444); | ||
282 | |||
267 | #ifdef CONFIG_DRM_AMDGPU_SI | 283 | #ifdef CONFIG_DRM_AMDGPU_SI |
268 | 284 | ||
269 | #if defined(CONFIG_DRM_RADEON) || defined(CONFIG_DRM_RADEON_MODULE) | 285 | #if defined(CONFIG_DRM_RADEON) || defined(CONFIG_DRM_RADEON_MODULE) |
@@ -510,15 +526,15 @@ static const struct pci_device_id pciidlist[] = { | |||
510 | {0x1002, 0x6997, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12}, | 526 | {0x1002, 0x6997, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12}, |
511 | {0x1002, 0x699F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12}, | 527 | {0x1002, 0x699F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12}, |
512 | /* Vega 10 */ | 528 | /* Vega 10 */ |
513 | {0x1002, 0x6860, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10|AMD_EXP_HW_SUPPORT}, | 529 | {0x1002, 0x6860, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, |
514 | {0x1002, 0x6861, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10|AMD_EXP_HW_SUPPORT}, | 530 | {0x1002, 0x6861, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, |
515 | {0x1002, 0x6862, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10|AMD_EXP_HW_SUPPORT}, | 531 | {0x1002, 0x6862, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, |
516 | {0x1002, 0x6863, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10|AMD_EXP_HW_SUPPORT}, | 532 | {0x1002, 0x6863, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, |
517 | {0x1002, 0x6864, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10|AMD_EXP_HW_SUPPORT}, | 533 | {0x1002, 0x6864, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, |
518 | {0x1002, 0x6867, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10|AMD_EXP_HW_SUPPORT}, | 534 | {0x1002, 0x6867, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, |
519 | {0x1002, 0x6868, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10|AMD_EXP_HW_SUPPORT}, | 535 | {0x1002, 0x6868, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, |
520 | {0x1002, 0x686c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10|AMD_EXP_HW_SUPPORT}, | 536 | {0x1002, 0x686c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, |
521 | {0x1002, 0x687f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10|AMD_EXP_HW_SUPPORT}, | 537 | {0x1002, 0x687f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, |
522 | /* Raven */ | 538 | /* Raven */ |
523 | {0x1002, 0x15dd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RAVEN|AMD_IS_APU|AMD_EXP_HW_SUPPORT}, | 539 | {0x1002, 0x15dd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RAVEN|AMD_IS_APU|AMD_EXP_HW_SUPPORT}, |
524 | 540 | ||
@@ -608,6 +624,8 @@ amdgpu_pci_remove(struct pci_dev *pdev) | |||
608 | 624 | ||
609 | drm_dev_unregister(dev); | 625 | drm_dev_unregister(dev); |
610 | drm_dev_unref(dev); | 626 | drm_dev_unref(dev); |
627 | pci_disable_device(pdev); | ||
628 | pci_set_drvdata(pdev, NULL); | ||
611 | } | 629 | } |
612 | 630 | ||
613 | static void | 631 | static void |
@@ -852,6 +870,7 @@ static struct drm_driver kms_driver = { | |||
852 | .gem_prime_import_sg_table = amdgpu_gem_prime_import_sg_table, | 870 | .gem_prime_import_sg_table = amdgpu_gem_prime_import_sg_table, |
853 | .gem_prime_vmap = amdgpu_gem_prime_vmap, | 871 | .gem_prime_vmap = amdgpu_gem_prime_vmap, |
854 | .gem_prime_vunmap = amdgpu_gem_prime_vunmap, | 872 | .gem_prime_vunmap = amdgpu_gem_prime_vunmap, |
873 | .gem_prime_mmap = amdgpu_gem_prime_mmap, | ||
855 | 874 | ||
856 | .name = DRIVER_NAME, | 875 | .name = DRIVER_NAME, |
857 | .desc = DRIVER_DESC, | 876 | .desc = DRIVER_DESC, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index 9afa9c097e1f..90fa8e8bc6fb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | |||
@@ -42,11 +42,6 @@ | |||
42 | this contains a helper + a amdgpu fb | 42 | this contains a helper + a amdgpu fb |
43 | the helper contains a pointer to amdgpu framebuffer baseclass. | 43 | the helper contains a pointer to amdgpu framebuffer baseclass. |
44 | */ | 44 | */ |
45 | struct amdgpu_fbdev { | ||
46 | struct drm_fb_helper helper; | ||
47 | struct amdgpu_framebuffer rfb; | ||
48 | struct amdgpu_device *adev; | ||
49 | }; | ||
50 | 45 | ||
51 | static int | 46 | static int |
52 | amdgpufb_open(struct fb_info *info, int user) | 47 | amdgpufb_open(struct fb_info *info, int user) |
@@ -149,7 +144,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, | |||
149 | AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | | 144 | AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | |
150 | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | | 145 | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | |
151 | AMDGPU_GEM_CREATE_VRAM_CLEARED, | 146 | AMDGPU_GEM_CREATE_VRAM_CLEARED, |
152 | true, &gobj); | 147 | true, NULL, &gobj); |
153 | if (ret) { | 148 | if (ret) { |
154 | pr_err("failed to allocate framebuffer (%d)\n", aligned_size); | 149 | pr_err("failed to allocate framebuffer (%d)\n", aligned_size); |
155 | return -ENOMEM; | 150 | return -ENOMEM; |
@@ -303,10 +298,10 @@ static int amdgpu_fbdev_destroy(struct drm_device *dev, struct amdgpu_fbdev *rfb | |||
303 | if (rfb->obj) { | 298 | if (rfb->obj) { |
304 | amdgpufb_destroy_pinned_object(rfb->obj); | 299 | amdgpufb_destroy_pinned_object(rfb->obj); |
305 | rfb->obj = NULL; | 300 | rfb->obj = NULL; |
301 | drm_framebuffer_unregister_private(&rfb->base); | ||
302 | drm_framebuffer_cleanup(&rfb->base); | ||
306 | } | 303 | } |
307 | drm_fb_helper_fini(&rfbdev->helper); | 304 | drm_fb_helper_fini(&rfbdev->helper); |
308 | drm_framebuffer_unregister_private(&rfb->base); | ||
309 | drm_framebuffer_cleanup(&rfb->base); | ||
310 | 305 | ||
311 | return 0; | 306 | return 0; |
312 | } | 307 | } |
@@ -353,7 +348,8 @@ int amdgpu_fbdev_init(struct amdgpu_device *adev) | |||
353 | drm_fb_helper_single_add_all_connectors(&rfbdev->helper); | 348 | drm_fb_helper_single_add_all_connectors(&rfbdev->helper); |
354 | 349 | ||
355 | /* disable all the possible outputs/crtcs before entering KMS mode */ | 350 | /* disable all the possible outputs/crtcs before entering KMS mode */ |
356 | drm_helper_disable_unused_functions(adev->ddev); | 351 | if (!amdgpu_device_has_dc_support(adev)) |
352 | drm_helper_disable_unused_functions(adev->ddev); | ||
357 | 353 | ||
358 | drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel); | 354 | drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel); |
359 | return 0; | 355 | return 0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 303b5e099a98..2fa95aef74d5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | |||
@@ -169,6 +169,32 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f) | |||
169 | } | 169 | } |
170 | 170 | ||
171 | /** | 171 | /** |
172 | * amdgpu_fence_emit_polling - emit a fence on the requeste ring | ||
173 | * | ||
174 | * @ring: ring the fence is associated with | ||
175 | * @s: resulting sequence number | ||
176 | * | ||
177 | * Emits a fence command on the requested ring (all asics). | ||
178 | * Used For polling fence. | ||
179 | * Returns 0 on success, -ENOMEM on failure. | ||
180 | */ | ||
181 | int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s) | ||
182 | { | ||
183 | uint32_t seq; | ||
184 | |||
185 | if (!s) | ||
186 | return -EINVAL; | ||
187 | |||
188 | seq = ++ring->fence_drv.sync_seq; | ||
189 | amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr, | ||
190 | seq, AMDGPU_FENCE_FLAG_INT); | ||
191 | |||
192 | *s = seq; | ||
193 | |||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | /** | ||
172 | * amdgpu_fence_schedule_fallback - schedule fallback check | 198 | * amdgpu_fence_schedule_fallback - schedule fallback check |
173 | * | 199 | * |
174 | * @ring: pointer to struct amdgpu_ring | 200 | * @ring: pointer to struct amdgpu_ring |
@@ -242,9 +268,10 @@ void amdgpu_fence_process(struct amdgpu_ring *ring) | |||
242 | * | 268 | * |
243 | * Checks for fence activity. | 269 | * Checks for fence activity. |
244 | */ | 270 | */ |
245 | static void amdgpu_fence_fallback(unsigned long arg) | 271 | static void amdgpu_fence_fallback(struct timer_list *t) |
246 | { | 272 | { |
247 | struct amdgpu_ring *ring = (void *)arg; | 273 | struct amdgpu_ring *ring = from_timer(ring, t, |
274 | fence_drv.fallback_timer); | ||
248 | 275 | ||
249 | amdgpu_fence_process(ring); | 276 | amdgpu_fence_process(ring); |
250 | } | 277 | } |
@@ -282,6 +309,30 @@ int amdgpu_fence_wait_empty(struct amdgpu_ring *ring) | |||
282 | } | 309 | } |
283 | 310 | ||
284 | /** | 311 | /** |
312 | * amdgpu_fence_wait_polling - busy wait for givn sequence number | ||
313 | * | ||
314 | * @ring: ring index the fence is associated with | ||
315 | * @wait_seq: sequence number to wait | ||
316 | * @timeout: the timeout for waiting in usecs | ||
317 | * | ||
318 | * Wait for all fences on the requested ring to signal (all asics). | ||
319 | * Returns left time if no timeout, 0 or minus if timeout. | ||
320 | */ | ||
321 | signed long amdgpu_fence_wait_polling(struct amdgpu_ring *ring, | ||
322 | uint32_t wait_seq, | ||
323 | signed long timeout) | ||
324 | { | ||
325 | uint32_t seq; | ||
326 | |||
327 | do { | ||
328 | seq = amdgpu_fence_read(ring); | ||
329 | udelay(5); | ||
330 | timeout -= 5; | ||
331 | } while ((int32_t)(wait_seq - seq) > 0 && timeout > 0); | ||
332 | |||
333 | return timeout > 0 ? timeout : 0; | ||
334 | } | ||
335 | /** | ||
285 | * amdgpu_fence_count_emitted - get the count of emitted fences | 336 | * amdgpu_fence_count_emitted - get the count of emitted fences |
286 | * | 337 | * |
287 | * @ring: ring the fence is associated with | 338 | * @ring: ring the fence is associated with |
@@ -372,8 +423,7 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring, | |||
372 | atomic_set(&ring->fence_drv.last_seq, 0); | 423 | atomic_set(&ring->fence_drv.last_seq, 0); |
373 | ring->fence_drv.initialized = false; | 424 | ring->fence_drv.initialized = false; |
374 | 425 | ||
375 | setup_timer(&ring->fence_drv.fallback_timer, amdgpu_fence_fallback, | 426 | timer_setup(&ring->fence_drv.fallback_timer, amdgpu_fence_fallback, 0); |
376 | (unsigned long)ring); | ||
377 | 427 | ||
378 | ring->fence_drv.num_fences_mask = num_hw_submission * 2 - 1; | 428 | ring->fence_drv.num_fences_mask = num_hw_submission * 2 - 1; |
379 | spin_lock_init(&ring->fence_drv.lock); | 429 | spin_lock_init(&ring->fence_drv.lock); |
@@ -641,6 +691,19 @@ static int amdgpu_debugfs_fence_info(struct seq_file *m, void *data) | |||
641 | atomic_read(&ring->fence_drv.last_seq)); | 691 | atomic_read(&ring->fence_drv.last_seq)); |
642 | seq_printf(m, "Last emitted 0x%08x\n", | 692 | seq_printf(m, "Last emitted 0x%08x\n", |
643 | ring->fence_drv.sync_seq); | 693 | ring->fence_drv.sync_seq); |
694 | |||
695 | if (ring->funcs->type != AMDGPU_RING_TYPE_GFX) | ||
696 | continue; | ||
697 | |||
698 | /* set in CP_VMID_PREEMPT and preemption occurred */ | ||
699 | seq_printf(m, "Last preempted 0x%08x\n", | ||
700 | le32_to_cpu(*(ring->fence_drv.cpu_addr + 2))); | ||
701 | /* set in CP_VMID_RESET and reset occurred */ | ||
702 | seq_printf(m, "Last reset 0x%08x\n", | ||
703 | le32_to_cpu(*(ring->fence_drv.cpu_addr + 4))); | ||
704 | /* Both preemption and reset occurred */ | ||
705 | seq_printf(m, "Last both 0x%08x\n", | ||
706 | le32_to_cpu(*(ring->fence_drv.cpu_addr + 6))); | ||
644 | } | 707 | } |
645 | return 0; | 708 | return 0; |
646 | } | 709 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index f4370081f6e6..fe818501c520 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | |||
@@ -332,12 +332,13 @@ int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset, | |||
332 | adev->gart.pages[p] = pagelist[i]; | 332 | adev->gart.pages[p] = pagelist[i]; |
333 | #endif | 333 | #endif |
334 | 334 | ||
335 | if (adev->gart.ptr) { | 335 | if (!adev->gart.ptr) |
336 | r = amdgpu_gart_map(adev, offset, pages, dma_addr, flags, | 336 | return 0; |
337 | adev->gart.ptr); | 337 | |
338 | if (r) | 338 | r = amdgpu_gart_map(adev, offset, pages, dma_addr, flags, |
339 | return r; | 339 | adev->gart.ptr); |
340 | } | 340 | if (r) |
341 | return r; | ||
341 | 342 | ||
342 | mb(); | 343 | mb(); |
343 | amdgpu_gart_flush_gpu_tlb(adev, 0); | 344 | amdgpu_gart_flush_gpu_tlb(adev, 0); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 6149a47fe63d..e87eedcc0da9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | |||
@@ -44,11 +44,12 @@ void amdgpu_gem_object_free(struct drm_gem_object *gobj) | |||
44 | } | 44 | } |
45 | 45 | ||
46 | int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size, | 46 | int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size, |
47 | int alignment, u32 initial_domain, | 47 | int alignment, u32 initial_domain, |
48 | u64 flags, bool kernel, | 48 | u64 flags, bool kernel, |
49 | struct drm_gem_object **obj) | 49 | struct reservation_object *resv, |
50 | struct drm_gem_object **obj) | ||
50 | { | 51 | { |
51 | struct amdgpu_bo *robj; | 52 | struct amdgpu_bo *bo; |
52 | int r; | 53 | int r; |
53 | 54 | ||
54 | *obj = NULL; | 55 | *obj = NULL; |
@@ -59,9 +60,14 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size, | |||
59 | 60 | ||
60 | retry: | 61 | retry: |
61 | r = amdgpu_bo_create(adev, size, alignment, kernel, initial_domain, | 62 | r = amdgpu_bo_create(adev, size, alignment, kernel, initial_domain, |
62 | flags, NULL, NULL, 0, &robj); | 63 | flags, NULL, resv, 0, &bo); |
63 | if (r) { | 64 | if (r) { |
64 | if (r != -ERESTARTSYS) { | 65 | if (r != -ERESTARTSYS) { |
66 | if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) { | ||
67 | flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; | ||
68 | goto retry; | ||
69 | } | ||
70 | |||
65 | if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) { | 71 | if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) { |
66 | initial_domain |= AMDGPU_GEM_DOMAIN_GTT; | 72 | initial_domain |= AMDGPU_GEM_DOMAIN_GTT; |
67 | goto retry; | 73 | goto retry; |
@@ -71,7 +77,7 @@ retry: | |||
71 | } | 77 | } |
72 | return r; | 78 | return r; |
73 | } | 79 | } |
74 | *obj = &robj->gem_base; | 80 | *obj = &bo->gem_base; |
75 | 81 | ||
76 | return 0; | 82 | return 0; |
77 | } | 83 | } |
@@ -112,7 +118,17 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj, | |||
112 | struct amdgpu_fpriv *fpriv = file_priv->driver_priv; | 118 | struct amdgpu_fpriv *fpriv = file_priv->driver_priv; |
113 | struct amdgpu_vm *vm = &fpriv->vm; | 119 | struct amdgpu_vm *vm = &fpriv->vm; |
114 | struct amdgpu_bo_va *bo_va; | 120 | struct amdgpu_bo_va *bo_va; |
121 | struct mm_struct *mm; | ||
115 | int r; | 122 | int r; |
123 | |||
124 | mm = amdgpu_ttm_tt_get_usermm(abo->tbo.ttm); | ||
125 | if (mm && mm != current->mm) | ||
126 | return -EPERM; | ||
127 | |||
128 | if (abo->flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID && | ||
129 | abo->tbo.resv != vm->root.base.bo->tbo.resv) | ||
130 | return -EPERM; | ||
131 | |||
116 | r = amdgpu_bo_reserve(abo, false); | 132 | r = amdgpu_bo_reserve(abo, false); |
117 | if (r) | 133 | if (r) |
118 | return r; | 134 | return r; |
@@ -127,35 +143,6 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj, | |||
127 | return 0; | 143 | return 0; |
128 | } | 144 | } |
129 | 145 | ||
130 | static int amdgpu_gem_vm_check(void *param, struct amdgpu_bo *bo) | ||
131 | { | ||
132 | /* if anything is swapped out don't swap it in here, | ||
133 | just abort and wait for the next CS */ | ||
134 | if (!amdgpu_bo_gpu_accessible(bo)) | ||
135 | return -ERESTARTSYS; | ||
136 | |||
137 | if (bo->shadow && !amdgpu_bo_gpu_accessible(bo->shadow)) | ||
138 | return -ERESTARTSYS; | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static bool amdgpu_gem_vm_ready(struct amdgpu_device *adev, | ||
144 | struct amdgpu_vm *vm, | ||
145 | struct list_head *list) | ||
146 | { | ||
147 | struct ttm_validate_buffer *entry; | ||
148 | |||
149 | list_for_each_entry(entry, list, head) { | ||
150 | struct amdgpu_bo *bo = | ||
151 | container_of(entry->bo, struct amdgpu_bo, tbo); | ||
152 | if (amdgpu_gem_vm_check(NULL, bo)) | ||
153 | return false; | ||
154 | } | ||
155 | |||
156 | return !amdgpu_vm_validate_pt_bos(adev, vm, amdgpu_gem_vm_check, NULL); | ||
157 | } | ||
158 | |||
159 | void amdgpu_gem_object_close(struct drm_gem_object *obj, | 146 | void amdgpu_gem_object_close(struct drm_gem_object *obj, |
160 | struct drm_file *file_priv) | 147 | struct drm_file *file_priv) |
161 | { | 148 | { |
@@ -165,13 +152,14 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj, | |||
165 | struct amdgpu_vm *vm = &fpriv->vm; | 152 | struct amdgpu_vm *vm = &fpriv->vm; |
166 | 153 | ||
167 | struct amdgpu_bo_list_entry vm_pd; | 154 | struct amdgpu_bo_list_entry vm_pd; |
168 | struct list_head list; | 155 | struct list_head list, duplicates; |
169 | struct ttm_validate_buffer tv; | 156 | struct ttm_validate_buffer tv; |
170 | struct ww_acquire_ctx ticket; | 157 | struct ww_acquire_ctx ticket; |
171 | struct amdgpu_bo_va *bo_va; | 158 | struct amdgpu_bo_va *bo_va; |
172 | int r; | 159 | int r; |
173 | 160 | ||
174 | INIT_LIST_HEAD(&list); | 161 | INIT_LIST_HEAD(&list); |
162 | INIT_LIST_HEAD(&duplicates); | ||
175 | 163 | ||
176 | tv.bo = &bo->tbo; | 164 | tv.bo = &bo->tbo; |
177 | tv.shared = true; | 165 | tv.shared = true; |
@@ -179,7 +167,7 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj, | |||
179 | 167 | ||
180 | amdgpu_vm_get_pd_bo(vm, &list, &vm_pd); | 168 | amdgpu_vm_get_pd_bo(vm, &list, &vm_pd); |
181 | 169 | ||
182 | r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL); | 170 | r = ttm_eu_reserve_buffers(&ticket, &list, false, &duplicates); |
183 | if (r) { | 171 | if (r) { |
184 | dev_err(adev->dev, "leaking bo va because " | 172 | dev_err(adev->dev, "leaking bo va because " |
185 | "we fail to reserve bo (%d)\n", r); | 173 | "we fail to reserve bo (%d)\n", r); |
@@ -189,7 +177,7 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj, | |||
189 | if (bo_va && --bo_va->ref_count == 0) { | 177 | if (bo_va && --bo_va->ref_count == 0) { |
190 | amdgpu_vm_bo_rmv(adev, bo_va); | 178 | amdgpu_vm_bo_rmv(adev, bo_va); |
191 | 179 | ||
192 | if (amdgpu_gem_vm_ready(adev, vm, &list)) { | 180 | if (amdgpu_vm_ready(vm)) { |
193 | struct dma_fence *fence = NULL; | 181 | struct dma_fence *fence = NULL; |
194 | 182 | ||
195 | r = amdgpu_vm_clear_freed(adev, vm, &fence); | 183 | r = amdgpu_vm_clear_freed(adev, vm, &fence); |
@@ -214,18 +202,24 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data, | |||
214 | struct drm_file *filp) | 202 | struct drm_file *filp) |
215 | { | 203 | { |
216 | struct amdgpu_device *adev = dev->dev_private; | 204 | struct amdgpu_device *adev = dev->dev_private; |
205 | struct amdgpu_fpriv *fpriv = filp->driver_priv; | ||
206 | struct amdgpu_vm *vm = &fpriv->vm; | ||
217 | union drm_amdgpu_gem_create *args = data; | 207 | union drm_amdgpu_gem_create *args = data; |
208 | uint64_t flags = args->in.domain_flags; | ||
218 | uint64_t size = args->in.bo_size; | 209 | uint64_t size = args->in.bo_size; |
210 | struct reservation_object *resv = NULL; | ||
219 | struct drm_gem_object *gobj; | 211 | struct drm_gem_object *gobj; |
220 | uint32_t handle; | 212 | uint32_t handle; |
221 | bool kernel = false; | ||
222 | int r; | 213 | int r; |
223 | 214 | ||
224 | /* reject invalid gem flags */ | 215 | /* reject invalid gem flags */ |
225 | if (args->in.domain_flags & ~(AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | | 216 | if (flags & ~(AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | |
226 | AMDGPU_GEM_CREATE_NO_CPU_ACCESS | | 217 | AMDGPU_GEM_CREATE_NO_CPU_ACCESS | |
227 | AMDGPU_GEM_CREATE_CPU_GTT_USWC | | 218 | AMDGPU_GEM_CREATE_CPU_GTT_USWC | |
228 | AMDGPU_GEM_CREATE_VRAM_CLEARED)) | 219 | AMDGPU_GEM_CREATE_VRAM_CLEARED | |
220 | AMDGPU_GEM_CREATE_VM_ALWAYS_VALID | | ||
221 | AMDGPU_GEM_CREATE_EXPLICIT_SYNC)) | ||
222 | |||
229 | return -EINVAL; | 223 | return -EINVAL; |
230 | 224 | ||
231 | /* reject invalid gem domains */ | 225 | /* reject invalid gem domains */ |
@@ -240,7 +234,7 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data, | |||
240 | /* create a gem object to contain this object in */ | 234 | /* create a gem object to contain this object in */ |
241 | if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS | | 235 | if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS | |
242 | AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) { | 236 | AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) { |
243 | kernel = true; | 237 | flags |= AMDGPU_GEM_CREATE_NO_CPU_ACCESS; |
244 | if (args->in.domains == AMDGPU_GEM_DOMAIN_GDS) | 238 | if (args->in.domains == AMDGPU_GEM_DOMAIN_GDS) |
245 | size = size << AMDGPU_GDS_SHIFT; | 239 | size = size << AMDGPU_GDS_SHIFT; |
246 | else if (args->in.domains == AMDGPU_GEM_DOMAIN_GWS) | 240 | else if (args->in.domains == AMDGPU_GEM_DOMAIN_GWS) |
@@ -252,10 +246,25 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data, | |||
252 | } | 246 | } |
253 | size = roundup(size, PAGE_SIZE); | 247 | size = roundup(size, PAGE_SIZE); |
254 | 248 | ||
249 | if (flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) { | ||
250 | r = amdgpu_bo_reserve(vm->root.base.bo, false); | ||
251 | if (r) | ||
252 | return r; | ||
253 | |||
254 | resv = vm->root.base.bo->tbo.resv; | ||
255 | } | ||
256 | |||
255 | r = amdgpu_gem_object_create(adev, size, args->in.alignment, | 257 | r = amdgpu_gem_object_create(adev, size, args->in.alignment, |
256 | (u32)(0xffffffff & args->in.domains), | 258 | (u32)(0xffffffff & args->in.domains), |
257 | args->in.domain_flags, | 259 | flags, false, resv, &gobj); |
258 | kernel, &gobj); | 260 | if (flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) { |
261 | if (!r) { | ||
262 | struct amdgpu_bo *abo = gem_to_amdgpu_bo(gobj); | ||
263 | |||
264 | abo->parent = amdgpu_bo_ref(vm->root.base.bo); | ||
265 | } | ||
266 | amdgpu_bo_unreserve(vm->root.base.bo); | ||
267 | } | ||
259 | if (r) | 268 | if (r) |
260 | return r; | 269 | return r; |
261 | 270 | ||
@@ -297,9 +306,8 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, | |||
297 | } | 306 | } |
298 | 307 | ||
299 | /* create a gem object to contain this object in */ | 308 | /* create a gem object to contain this object in */ |
300 | r = amdgpu_gem_object_create(adev, args->size, 0, | 309 | r = amdgpu_gem_object_create(adev, args->size, 0, AMDGPU_GEM_DOMAIN_CPU, |
301 | AMDGPU_GEM_DOMAIN_CPU, 0, | 310 | 0, 0, NULL, &gobj); |
302 | 0, &gobj); | ||
303 | if (r) | 311 | if (r) |
304 | return r; | 312 | return r; |
305 | 313 | ||
@@ -317,12 +325,10 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, | |||
317 | } | 325 | } |
318 | 326 | ||
319 | if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) { | 327 | if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) { |
320 | down_read(¤t->mm->mmap_sem); | ||
321 | |||
322 | r = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, | 328 | r = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, |
323 | bo->tbo.ttm->pages); | 329 | bo->tbo.ttm->pages); |
324 | if (r) | 330 | if (r) |
325 | goto unlock_mmap_sem; | 331 | goto release_object; |
326 | 332 | ||
327 | r = amdgpu_bo_reserve(bo, true); | 333 | r = amdgpu_bo_reserve(bo, true); |
328 | if (r) | 334 | if (r) |
@@ -333,8 +339,6 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, | |||
333 | amdgpu_bo_unreserve(bo); | 339 | amdgpu_bo_unreserve(bo); |
334 | if (r) | 340 | if (r) |
335 | goto free_pages; | 341 | goto free_pages; |
336 | |||
337 | up_read(¤t->mm->mmap_sem); | ||
338 | } | 342 | } |
339 | 343 | ||
340 | r = drm_gem_handle_create(filp, gobj, &handle); | 344 | r = drm_gem_handle_create(filp, gobj, &handle); |
@@ -347,10 +351,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, | |||
347 | return 0; | 351 | return 0; |
348 | 352 | ||
349 | free_pages: | 353 | free_pages: |
350 | release_pages(bo->tbo.ttm->pages, bo->tbo.ttm->num_pages, false); | 354 | release_pages(bo->tbo.ttm->pages, bo->tbo.ttm->num_pages); |
351 | |||
352 | unlock_mmap_sem: | ||
353 | up_read(¤t->mm->mmap_sem); | ||
354 | 355 | ||
355 | release_object: | 356 | release_object: |
356 | drm_gem_object_put_unlocked(gobj); | 357 | drm_gem_object_put_unlocked(gobj); |
@@ -511,10 +512,10 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, | |||
511 | struct list_head *list, | 512 | struct list_head *list, |
512 | uint32_t operation) | 513 | uint32_t operation) |
513 | { | 514 | { |
514 | int r = -ERESTARTSYS; | 515 | int r; |
515 | 516 | ||
516 | if (!amdgpu_gem_vm_ready(adev, vm, list)) | 517 | if (!amdgpu_vm_ready(vm)) |
517 | goto error; | 518 | return; |
518 | 519 | ||
519 | r = amdgpu_vm_update_directories(adev, vm); | 520 | r = amdgpu_vm_update_directories(adev, vm); |
520 | if (r) | 521 | if (r) |
@@ -551,15 +552,14 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | |||
551 | struct amdgpu_bo_list_entry vm_pd; | 552 | struct amdgpu_bo_list_entry vm_pd; |
552 | struct ttm_validate_buffer tv; | 553 | struct ttm_validate_buffer tv; |
553 | struct ww_acquire_ctx ticket; | 554 | struct ww_acquire_ctx ticket; |
554 | struct list_head list; | 555 | struct list_head list, duplicates; |
555 | uint64_t va_flags; | 556 | uint64_t va_flags; |
556 | int r = 0; | 557 | int r = 0; |
557 | 558 | ||
558 | if (args->va_address < AMDGPU_VA_RESERVED_SIZE) { | 559 | if (args->va_address < AMDGPU_VA_RESERVED_SIZE) { |
559 | dev_err(&dev->pdev->dev, | 560 | dev_err(&dev->pdev->dev, |
560 | "va_address 0x%lX is in reserved area 0x%X\n", | 561 | "va_address 0x%LX is in reserved area 0x%LX\n", |
561 | (unsigned long)args->va_address, | 562 | args->va_address, AMDGPU_VA_RESERVED_SIZE); |
562 | AMDGPU_VA_RESERVED_SIZE); | ||
563 | return -EINVAL; | 563 | return -EINVAL; |
564 | } | 564 | } |
565 | 565 | ||
@@ -580,13 +580,9 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | |||
580 | args->operation); | 580 | args->operation); |
581 | return -EINVAL; | 581 | return -EINVAL; |
582 | } | 582 | } |
583 | if ((args->operation == AMDGPU_VA_OP_MAP) || | ||
584 | (args->operation == AMDGPU_VA_OP_REPLACE)) { | ||
585 | if (amdgpu_kms_vram_lost(adev, fpriv)) | ||
586 | return -ENODEV; | ||
587 | } | ||
588 | 583 | ||
589 | INIT_LIST_HEAD(&list); | 584 | INIT_LIST_HEAD(&list); |
585 | INIT_LIST_HEAD(&duplicates); | ||
590 | if ((args->operation != AMDGPU_VA_OP_CLEAR) && | 586 | if ((args->operation != AMDGPU_VA_OP_CLEAR) && |
591 | !(args->flags & AMDGPU_VM_PAGE_PRT)) { | 587 | !(args->flags & AMDGPU_VM_PAGE_PRT)) { |
592 | gobj = drm_gem_object_lookup(filp, args->handle); | 588 | gobj = drm_gem_object_lookup(filp, args->handle); |
@@ -603,7 +599,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | |||
603 | 599 | ||
604 | amdgpu_vm_get_pd_bo(&fpriv->vm, &list, &vm_pd); | 600 | amdgpu_vm_get_pd_bo(&fpriv->vm, &list, &vm_pd); |
605 | 601 | ||
606 | r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL); | 602 | r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates); |
607 | if (r) | 603 | if (r) |
608 | goto error_unref; | 604 | goto error_unref; |
609 | 605 | ||
@@ -669,6 +665,7 @@ error_unref: | |||
669 | int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, | 665 | int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, |
670 | struct drm_file *filp) | 666 | struct drm_file *filp) |
671 | { | 667 | { |
668 | struct amdgpu_device *adev = dev->dev_private; | ||
672 | struct drm_amdgpu_gem_op *args = data; | 669 | struct drm_amdgpu_gem_op *args = data; |
673 | struct drm_gem_object *gobj; | 670 | struct drm_gem_object *gobj; |
674 | struct amdgpu_bo *robj; | 671 | struct amdgpu_bo *robj; |
@@ -716,6 +713,9 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, | |||
716 | if (robj->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM) | 713 | if (robj->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM) |
717 | robj->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT; | 714 | robj->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT; |
718 | 715 | ||
716 | if (robj->flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) | ||
717 | amdgpu_vm_bo_invalidate(adev, robj, true); | ||
718 | |||
719 | amdgpu_bo_unreserve(robj); | 719 | amdgpu_bo_unreserve(robj); |
720 | break; | 720 | break; |
721 | default: | 721 | default: |
@@ -745,8 +745,7 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv, | |||
745 | r = amdgpu_gem_object_create(adev, args->size, 0, | 745 | r = amdgpu_gem_object_create(adev, args->size, 0, |
746 | AMDGPU_GEM_DOMAIN_VRAM, | 746 | AMDGPU_GEM_DOMAIN_VRAM, |
747 | AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, | 747 | AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, |
748 | ttm_bo_type_device, | 748 | false, NULL, &gobj); |
749 | &gobj); | ||
750 | if (r) | 749 | if (r) |
751 | return -ENOMEM; | 750 | return -ENOMEM; |
752 | 751 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index 4f6c68fc1dd9..ef043361009f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | |||
@@ -109,9 +109,26 @@ void amdgpu_gfx_parse_disable_cu(unsigned *mask, unsigned max_se, unsigned max_s | |||
109 | } | 109 | } |
110 | } | 110 | } |
111 | 111 | ||
112 | static bool amdgpu_gfx_is_multipipe_capable(struct amdgpu_device *adev) | ||
113 | { | ||
114 | if (amdgpu_compute_multipipe != -1) { | ||
115 | DRM_INFO("amdgpu: forcing compute pipe policy %d\n", | ||
116 | amdgpu_compute_multipipe); | ||
117 | return amdgpu_compute_multipipe == 1; | ||
118 | } | ||
119 | |||
120 | /* FIXME: spreading the queues across pipes causes perf regressions | ||
121 | * on POLARIS11 compute workloads */ | ||
122 | if (adev->asic_type == CHIP_POLARIS11) | ||
123 | return false; | ||
124 | |||
125 | return adev->gfx.mec.num_mec > 1; | ||
126 | } | ||
127 | |||
112 | void amdgpu_gfx_compute_queue_acquire(struct amdgpu_device *adev) | 128 | void amdgpu_gfx_compute_queue_acquire(struct amdgpu_device *adev) |
113 | { | 129 | { |
114 | int i, queue, pipe, mec; | 130 | int i, queue, pipe, mec; |
131 | bool multipipe_policy = amdgpu_gfx_is_multipipe_capable(adev); | ||
115 | 132 | ||
116 | /* policy for amdgpu compute queue ownership */ | 133 | /* policy for amdgpu compute queue ownership */ |
117 | for (i = 0; i < AMDGPU_MAX_COMPUTE_QUEUES; ++i) { | 134 | for (i = 0; i < AMDGPU_MAX_COMPUTE_QUEUES; ++i) { |
@@ -125,8 +142,7 @@ void amdgpu_gfx_compute_queue_acquire(struct amdgpu_device *adev) | |||
125 | if (mec >= adev->gfx.mec.num_mec) | 142 | if (mec >= adev->gfx.mec.num_mec) |
126 | break; | 143 | break; |
127 | 144 | ||
128 | /* FIXME: spreading the queues across pipes causes perf regressions */ | 145 | if (multipipe_policy) { |
129 | if (0) { | ||
130 | /* policy: amdgpu owns the first two queues of the first MEC */ | 146 | /* policy: amdgpu owns the first two queues of the first MEC */ |
131 | if (mec == 0 && queue < 2) | 147 | if (mec == 0 && queue < 2) |
132 | set_bit(i, adev->gfx.mec.queue_bitmap); | 148 | set_bit(i, adev->gfx.mec.queue_bitmap); |
@@ -185,7 +201,7 @@ int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev, | |||
185 | struct amdgpu_kiq *kiq = &adev->gfx.kiq; | 201 | struct amdgpu_kiq *kiq = &adev->gfx.kiq; |
186 | int r = 0; | 202 | int r = 0; |
187 | 203 | ||
188 | mutex_init(&kiq->ring_mutex); | 204 | spin_lock_init(&kiq->ring_lock); |
189 | 205 | ||
190 | r = amdgpu_wb_get(adev, &adev->virt.reg_val_offs); | 206 | r = amdgpu_wb_get(adev, &adev->virt.reg_val_offs); |
191 | if (r) | 207 | if (r) |
@@ -260,8 +276,13 @@ int amdgpu_gfx_compute_mqd_sw_init(struct amdgpu_device *adev, | |||
260 | /* create MQD for KIQ */ | 276 | /* create MQD for KIQ */ |
261 | ring = &adev->gfx.kiq.ring; | 277 | ring = &adev->gfx.kiq.ring; |
262 | if (!ring->mqd_obj) { | 278 | if (!ring->mqd_obj) { |
279 | /* originaly the KIQ MQD is put in GTT domain, but for SRIOV VRAM domain is a must | ||
280 | * otherwise hypervisor trigger SAVE_VF fail after driver unloaded which mean MQD | ||
281 | * deallocated and gart_unbind, to strict diverage we decide to use VRAM domain for | ||
282 | * KIQ MQD no matter SRIOV or Bare-metal | ||
283 | */ | ||
263 | r = amdgpu_bo_create_kernel(adev, mqd_size, PAGE_SIZE, | 284 | r = amdgpu_bo_create_kernel(adev, mqd_size, PAGE_SIZE, |
264 | AMDGPU_GEM_DOMAIN_GTT, &ring->mqd_obj, | 285 | AMDGPU_GEM_DOMAIN_VRAM, &ring->mqd_obj, |
265 | &ring->mqd_gpu_addr, &ring->mqd_ptr); | 286 | &ring->mqd_gpu_addr, &ring->mqd_ptr); |
266 | if (r) { | 287 | if (r) { |
267 | dev_warn(adev->dev, "failed to create ring mqd ob (%d)", r); | 288 | dev_warn(adev->dev, "failed to create ring mqd ob (%d)", r); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c index 0d15eb7d31d7..00e0ce10862f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c | |||
@@ -71,12 +71,6 @@ static int amdgpu_gtt_mgr_fini(struct ttm_mem_type_manager *man) | |||
71 | { | 71 | { |
72 | struct amdgpu_gtt_mgr *mgr = man->priv; | 72 | struct amdgpu_gtt_mgr *mgr = man->priv; |
73 | 73 | ||
74 | spin_lock(&mgr->lock); | ||
75 | if (!drm_mm_clean(&mgr->mm)) { | ||
76 | spin_unlock(&mgr->lock); | ||
77 | return -EBUSY; | ||
78 | } | ||
79 | |||
80 | drm_mm_takedown(&mgr->mm); | 74 | drm_mm_takedown(&mgr->mm); |
81 | spin_unlock(&mgr->lock); | 75 | spin_unlock(&mgr->lock); |
82 | kfree(mgr); | 76 | kfree(mgr); |
@@ -169,7 +163,8 @@ static int amdgpu_gtt_mgr_new(struct ttm_mem_type_manager *man, | |||
169 | int r; | 163 | int r; |
170 | 164 | ||
171 | spin_lock(&mgr->lock); | 165 | spin_lock(&mgr->lock); |
172 | if (atomic64_read(&mgr->available) < mem->num_pages) { | 166 | if ((&tbo->mem == mem || tbo->mem.mem_type != TTM_PL_TT) && |
167 | atomic64_read(&mgr->available) < mem->num_pages) { | ||
173 | spin_unlock(&mgr->lock); | 168 | spin_unlock(&mgr->lock); |
174 | return 0; | 169 | return 0; |
175 | } | 170 | } |
@@ -244,8 +239,9 @@ static void amdgpu_gtt_mgr_del(struct ttm_mem_type_manager *man, | |||
244 | uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man) | 239 | uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man) |
245 | { | 240 | { |
246 | struct amdgpu_gtt_mgr *mgr = man->priv; | 241 | struct amdgpu_gtt_mgr *mgr = man->priv; |
242 | s64 result = man->size - atomic64_read(&mgr->available); | ||
247 | 243 | ||
248 | return (u64)(man->size - atomic64_read(&mgr->available)) * PAGE_SIZE; | 244 | return (result > 0 ? result : 0) * PAGE_SIZE; |
249 | } | 245 | } |
250 | 246 | ||
251 | /** | 247 | /** |
@@ -265,7 +261,7 @@ static void amdgpu_gtt_mgr_debug(struct ttm_mem_type_manager *man, | |||
265 | drm_mm_print(&mgr->mm, printer); | 261 | drm_mm_print(&mgr->mm, printer); |
266 | spin_unlock(&mgr->lock); | 262 | spin_unlock(&mgr->lock); |
267 | 263 | ||
268 | drm_printf(printer, "man size:%llu pages, gtt available:%llu pages, usage:%lluMB\n", | 264 | drm_printf(printer, "man size:%llu pages, gtt available:%lld pages, usage:%lluMB\n", |
269 | man->size, (u64)atomic64_read(&mgr->available), | 265 | man->size, (u64)atomic64_read(&mgr->available), |
270 | amdgpu_gtt_mgr_usage(man) >> 20); | 266 | amdgpu_gtt_mgr_usage(man) >> 20); |
271 | } | 267 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c index 3ab4c65ecc8b..f5f27e4f0f7f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | |||
@@ -169,6 +169,12 @@ restart_ih: | |||
169 | while (adev->irq.ih.rptr != wptr) { | 169 | while (adev->irq.ih.rptr != wptr) { |
170 | u32 ring_index = adev->irq.ih.rptr >> 2; | 170 | u32 ring_index = adev->irq.ih.rptr >> 2; |
171 | 171 | ||
172 | /* Prescreening of high-frequency interrupts */ | ||
173 | if (!amdgpu_ih_prescreen_iv(adev)) { | ||
174 | adev->irq.ih.rptr &= adev->irq.ih.ptr_mask; | ||
175 | continue; | ||
176 | } | ||
177 | |||
172 | /* Before dispatching irq to IP blocks, send it to amdkfd */ | 178 | /* Before dispatching irq to IP blocks, send it to amdkfd */ |
173 | amdgpu_amdkfd_interrupt(adev, | 179 | amdgpu_amdkfd_interrupt(adev, |
174 | (const void *) &adev->irq.ih.ring[ring_index]); | 180 | (const void *) &adev->irq.ih.ring[ring_index]); |
@@ -190,3 +196,79 @@ restart_ih: | |||
190 | 196 | ||
191 | return IRQ_HANDLED; | 197 | return IRQ_HANDLED; |
192 | } | 198 | } |
199 | |||
200 | /** | ||
201 | * amdgpu_ih_add_fault - Add a page fault record | ||
202 | * | ||
203 | * @adev: amdgpu device pointer | ||
204 | * @key: 64-bit encoding of PASID and address | ||
205 | * | ||
206 | * This should be called when a retry page fault interrupt is | ||
207 | * received. If this is a new page fault, it will be added to a hash | ||
208 | * table. The return value indicates whether this is a new fault, or | ||
209 | * a fault that was already known and is already being handled. | ||
210 | * | ||
211 | * If there are too many pending page faults, this will fail. Retry | ||
212 | * interrupts should be ignored in this case until there is enough | ||
213 | * free space. | ||
214 | * | ||
215 | * Returns 0 if the fault was added, 1 if the fault was already known, | ||
216 | * -ENOSPC if there are too many pending faults. | ||
217 | */ | ||
218 | int amdgpu_ih_add_fault(struct amdgpu_device *adev, u64 key) | ||
219 | { | ||
220 | unsigned long flags; | ||
221 | int r = -ENOSPC; | ||
222 | |||
223 | if (WARN_ON_ONCE(!adev->irq.ih.faults)) | ||
224 | /* Should be allocated in <IP>_ih_sw_init on GPUs that | ||
225 | * support retry faults and require retry filtering. | ||
226 | */ | ||
227 | return r; | ||
228 | |||
229 | spin_lock_irqsave(&adev->irq.ih.faults->lock, flags); | ||
230 | |||
231 | /* Only let the hash table fill up to 50% for best performance */ | ||
232 | if (adev->irq.ih.faults->count >= (1 << (AMDGPU_PAGEFAULT_HASH_BITS-1))) | ||
233 | goto unlock_out; | ||
234 | |||
235 | r = chash_table_copy_in(&adev->irq.ih.faults->hash, key, NULL); | ||
236 | if (!r) | ||
237 | adev->irq.ih.faults->count++; | ||
238 | |||
239 | /* chash_table_copy_in should never fail unless we're losing count */ | ||
240 | WARN_ON_ONCE(r < 0); | ||
241 | |||
242 | unlock_out: | ||
243 | spin_unlock_irqrestore(&adev->irq.ih.faults->lock, flags); | ||
244 | return r; | ||
245 | } | ||
246 | |||
247 | /** | ||
248 | * amdgpu_ih_clear_fault - Remove a page fault record | ||
249 | * | ||
250 | * @adev: amdgpu device pointer | ||
251 | * @key: 64-bit encoding of PASID and address | ||
252 | * | ||
253 | * This should be called when a page fault has been handled. Any | ||
254 | * future interrupt with this key will be processed as a new | ||
255 | * page fault. | ||
256 | */ | ||
257 | void amdgpu_ih_clear_fault(struct amdgpu_device *adev, u64 key) | ||
258 | { | ||
259 | unsigned long flags; | ||
260 | int r; | ||
261 | |||
262 | if (!adev->irq.ih.faults) | ||
263 | return; | ||
264 | |||
265 | spin_lock_irqsave(&adev->irq.ih.faults->lock, flags); | ||
266 | |||
267 | r = chash_table_remove(&adev->irq.ih.faults->hash, key, NULL); | ||
268 | if (!WARN_ON_ONCE(r < 0)) { | ||
269 | adev->irq.ih.faults->count--; | ||
270 | WARN_ON_ONCE(adev->irq.ih.faults->count < 0); | ||
271 | } | ||
272 | |||
273 | spin_unlock_irqrestore(&adev->irq.ih.faults->lock, flags); | ||
274 | } | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h index 3de8e74e5b3a..ada89358e220 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | |||
@@ -24,6 +24,8 @@ | |||
24 | #ifndef __AMDGPU_IH_H__ | 24 | #ifndef __AMDGPU_IH_H__ |
25 | #define __AMDGPU_IH_H__ | 25 | #define __AMDGPU_IH_H__ |
26 | 26 | ||
27 | #include <linux/chash.h> | ||
28 | |||
27 | struct amdgpu_device; | 29 | struct amdgpu_device; |
28 | /* | 30 | /* |
29 | * vega10+ IH clients | 31 | * vega10+ IH clients |
@@ -69,6 +71,13 @@ enum amdgpu_ih_clientid | |||
69 | 71 | ||
70 | #define AMDGPU_IH_CLIENTID_LEGACY 0 | 72 | #define AMDGPU_IH_CLIENTID_LEGACY 0 |
71 | 73 | ||
74 | #define AMDGPU_PAGEFAULT_HASH_BITS 8 | ||
75 | struct amdgpu_retryfault_hashtable { | ||
76 | DECLARE_CHASH_TABLE(hash, AMDGPU_PAGEFAULT_HASH_BITS, 8, 0); | ||
77 | spinlock_t lock; | ||
78 | int count; | ||
79 | }; | ||
80 | |||
72 | /* | 81 | /* |
73 | * R6xx+ IH ring | 82 | * R6xx+ IH ring |
74 | */ | 83 | */ |
@@ -87,6 +96,7 @@ struct amdgpu_ih_ring { | |||
87 | bool use_doorbell; | 96 | bool use_doorbell; |
88 | bool use_bus_addr; | 97 | bool use_bus_addr; |
89 | dma_addr_t rb_dma_addr; /* only used when use_bus_addr = true */ | 98 | dma_addr_t rb_dma_addr; /* only used when use_bus_addr = true */ |
99 | struct amdgpu_retryfault_hashtable *faults; | ||
90 | }; | 100 | }; |
91 | 101 | ||
92 | #define AMDGPU_IH_SRC_DATA_MAX_SIZE_DW 4 | 102 | #define AMDGPU_IH_SRC_DATA_MAX_SIZE_DW 4 |
@@ -109,5 +119,7 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size, | |||
109 | bool use_bus_addr); | 119 | bool use_bus_addr); |
110 | void amdgpu_ih_ring_fini(struct amdgpu_device *adev); | 120 | void amdgpu_ih_ring_fini(struct amdgpu_device *adev); |
111 | int amdgpu_ih_process(struct amdgpu_device *adev); | 121 | int amdgpu_ih_process(struct amdgpu_device *adev); |
122 | int amdgpu_ih_add_fault(struct amdgpu_device *adev, u64 key); | ||
123 | void amdgpu_ih_clear_fault(struct amdgpu_device *adev, u64 key); | ||
112 | 124 | ||
113 | #endif | 125 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 538e5f27d120..47c5ce9807db 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | |||
@@ -37,6 +37,10 @@ | |||
37 | 37 | ||
38 | #include <linux/pm_runtime.h> | 38 | #include <linux/pm_runtime.h> |
39 | 39 | ||
40 | #ifdef CONFIG_DRM_AMD_DC | ||
41 | #include "amdgpu_dm_irq.h" | ||
42 | #endif | ||
43 | |||
40 | #define AMDGPU_WAIT_IDLE_TIMEOUT 200 | 44 | #define AMDGPU_WAIT_IDLE_TIMEOUT 200 |
41 | 45 | ||
42 | /* | 46 | /* |
@@ -221,15 +225,6 @@ int amdgpu_irq_init(struct amdgpu_device *adev) | |||
221 | 225 | ||
222 | spin_lock_init(&adev->irq.lock); | 226 | spin_lock_init(&adev->irq.lock); |
223 | 227 | ||
224 | if (!adev->enable_virtual_display) | ||
225 | /* Disable vblank irqs aggressively for power-saving */ | ||
226 | adev->ddev->vblank_disable_immediate = true; | ||
227 | |||
228 | r = drm_vblank_init(adev->ddev, adev->mode_info.num_crtc); | ||
229 | if (r) { | ||
230 | return r; | ||
231 | } | ||
232 | |||
233 | /* enable msi */ | 228 | /* enable msi */ |
234 | adev->irq.msi_enabled = false; | 229 | adev->irq.msi_enabled = false; |
235 | 230 | ||
@@ -241,7 +236,21 @@ int amdgpu_irq_init(struct amdgpu_device *adev) | |||
241 | } | 236 | } |
242 | } | 237 | } |
243 | 238 | ||
244 | INIT_WORK(&adev->hotplug_work, amdgpu_hotplug_work_func); | 239 | if (!amdgpu_device_has_dc_support(adev)) { |
240 | if (!adev->enable_virtual_display) | ||
241 | /* Disable vblank irqs aggressively for power-saving */ | ||
242 | /* XXX: can this be enabled for DC? */ | ||
243 | adev->ddev->vblank_disable_immediate = true; | ||
244 | |||
245 | r = drm_vblank_init(adev->ddev, adev->mode_info.num_crtc); | ||
246 | if (r) | ||
247 | return r; | ||
248 | |||
249 | /* pre DCE11 */ | ||
250 | INIT_WORK(&adev->hotplug_work, | ||
251 | amdgpu_hotplug_work_func); | ||
252 | } | ||
253 | |||
245 | INIT_WORK(&adev->reset_work, amdgpu_irq_reset_work_func); | 254 | INIT_WORK(&adev->reset_work, amdgpu_irq_reset_work_func); |
246 | 255 | ||
247 | adev->irq.installed = true; | 256 | adev->irq.installed = true; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 4510627ae83e..0cfc68db575b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | |||
@@ -65,6 +65,7 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, | |||
65 | amdgpu_sync_create(&(*job)->sync); | 65 | amdgpu_sync_create(&(*job)->sync); |
66 | amdgpu_sync_create(&(*job)->dep_sync); | 66 | amdgpu_sync_create(&(*job)->dep_sync); |
67 | amdgpu_sync_create(&(*job)->sched_sync); | 67 | amdgpu_sync_create(&(*job)->sched_sync); |
68 | (*job)->vram_lost_counter = atomic_read(&adev->vram_lost_counter); | ||
68 | 69 | ||
69 | return 0; | 70 | return 0; |
70 | } | 71 | } |
@@ -103,6 +104,7 @@ static void amdgpu_job_free_cb(struct amd_sched_job *s_job) | |||
103 | { | 104 | { |
104 | struct amdgpu_job *job = container_of(s_job, struct amdgpu_job, base); | 105 | struct amdgpu_job *job = container_of(s_job, struct amdgpu_job, base); |
105 | 106 | ||
107 | amdgpu_ring_priority_put(job->ring, amd_sched_get_job_priority(s_job)); | ||
106 | dma_fence_put(job->fence); | 108 | dma_fence_put(job->fence); |
107 | amdgpu_sync_free(&job->sync); | 109 | amdgpu_sync_free(&job->sync); |
108 | amdgpu_sync_free(&job->dep_sync); | 110 | amdgpu_sync_free(&job->dep_sync); |
@@ -139,6 +141,8 @@ int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, | |||
139 | job->fence_ctx = entity->fence_context; | 141 | job->fence_ctx = entity->fence_context; |
140 | *f = dma_fence_get(&job->base.s_fence->finished); | 142 | *f = dma_fence_get(&job->base.s_fence->finished); |
141 | amdgpu_job_free_resources(job); | 143 | amdgpu_job_free_resources(job); |
144 | amdgpu_ring_priority_get(job->ring, | ||
145 | amd_sched_get_job_priority(&job->base)); | ||
142 | amd_sched_entity_push_job(&job->base); | 146 | amd_sched_entity_push_job(&job->base); |
143 | 147 | ||
144 | return 0; | 148 | return 0; |
@@ -177,8 +181,8 @@ static struct dma_fence *amdgpu_job_dependency(struct amd_sched_job *sched_job) | |||
177 | static struct dma_fence *amdgpu_job_run(struct amd_sched_job *sched_job) | 181 | static struct dma_fence *amdgpu_job_run(struct amd_sched_job *sched_job) |
178 | { | 182 | { |
179 | struct dma_fence *fence = NULL; | 183 | struct dma_fence *fence = NULL; |
184 | struct amdgpu_device *adev; | ||
180 | struct amdgpu_job *job; | 185 | struct amdgpu_job *job; |
181 | struct amdgpu_fpriv *fpriv = NULL; | ||
182 | int r; | 186 | int r; |
183 | 187 | ||
184 | if (!sched_job) { | 188 | if (!sched_job) { |
@@ -186,23 +190,25 @@ static struct dma_fence *amdgpu_job_run(struct amd_sched_job *sched_job) | |||
186 | return NULL; | 190 | return NULL; |
187 | } | 191 | } |
188 | job = to_amdgpu_job(sched_job); | 192 | job = to_amdgpu_job(sched_job); |
193 | adev = job->adev; | ||
189 | 194 | ||
190 | BUG_ON(amdgpu_sync_peek_fence(&job->sync, NULL)); | 195 | BUG_ON(amdgpu_sync_peek_fence(&job->sync, NULL)); |
191 | 196 | ||
192 | trace_amdgpu_sched_run_job(job); | 197 | trace_amdgpu_sched_run_job(job); |
193 | if (job->vm) | ||
194 | fpriv = container_of(job->vm, struct amdgpu_fpriv, vm); | ||
195 | /* skip ib schedule when vram is lost */ | 198 | /* skip ib schedule when vram is lost */ |
196 | if (fpriv && amdgpu_kms_vram_lost(job->adev, fpriv)) | 199 | if (job->vram_lost_counter != atomic_read(&adev->vram_lost_counter)) { |
200 | dma_fence_set_error(&job->base.s_fence->finished, -ECANCELED); | ||
197 | DRM_ERROR("Skip scheduling IBs!\n"); | 201 | DRM_ERROR("Skip scheduling IBs!\n"); |
198 | else { | 202 | } else { |
199 | r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, job, &fence); | 203 | r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, job, |
204 | &fence); | ||
200 | if (r) | 205 | if (r) |
201 | DRM_ERROR("Error scheduling IBs (%d)\n", r); | 206 | DRM_ERROR("Error scheduling IBs (%d)\n", r); |
202 | } | 207 | } |
203 | /* if gpu reset, hw fence will be replaced here */ | 208 | /* if gpu reset, hw fence will be replaced here */ |
204 | dma_fence_put(job->fence); | 209 | dma_fence_put(job->fence); |
205 | job->fence = dma_fence_get(fence); | 210 | job->fence = dma_fence_get(fence); |
211 | |||
206 | amdgpu_job_free_resources(job); | 212 | amdgpu_job_free_resources(job); |
207 | return fence; | 213 | return fence; |
208 | } | 214 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index e16229000a98..720139e182a3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <drm/drmP.h> | 28 | #include <drm/drmP.h> |
29 | #include "amdgpu.h" | 29 | #include "amdgpu.h" |
30 | #include <drm/amdgpu_drm.h> | 30 | #include <drm/amdgpu_drm.h> |
31 | #include "amdgpu_sched.h" | ||
31 | #include "amdgpu_uvd.h" | 32 | #include "amdgpu_uvd.h" |
32 | #include "amdgpu_vce.h" | 33 | #include "amdgpu_vce.h" |
33 | 34 | ||
@@ -269,7 +270,6 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info, | |||
269 | static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | 270 | static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) |
270 | { | 271 | { |
271 | struct amdgpu_device *adev = dev->dev_private; | 272 | struct amdgpu_device *adev = dev->dev_private; |
272 | struct amdgpu_fpriv *fpriv = filp->driver_priv; | ||
273 | struct drm_amdgpu_info *info = data; | 273 | struct drm_amdgpu_info *info = data; |
274 | struct amdgpu_mode_info *minfo = &adev->mode_info; | 274 | struct amdgpu_mode_info *minfo = &adev->mode_info; |
275 | void __user *out = (void __user *)(uintptr_t)info->return_pointer; | 275 | void __user *out = (void __user *)(uintptr_t)info->return_pointer; |
@@ -282,8 +282,6 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
282 | 282 | ||
283 | if (!info->return_size || !info->return_pointer) | 283 | if (!info->return_size || !info->return_pointer) |
284 | return -EINVAL; | 284 | return -EINVAL; |
285 | if (amdgpu_kms_vram_lost(adev, fpriv)) | ||
286 | return -ENODEV; | ||
287 | 285 | ||
288 | switch (info->query) { | 286 | switch (info->query) { |
289 | case AMDGPU_INFO_ACCEL_WORKING: | 287 | case AMDGPU_INFO_ACCEL_WORKING: |
@@ -765,6 +763,9 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
765 | } | 763 | } |
766 | return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0; | 764 | return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0; |
767 | } | 765 | } |
766 | case AMDGPU_INFO_VRAM_LOST_COUNTER: | ||
767 | ui32 = atomic_read(&adev->vram_lost_counter); | ||
768 | return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0; | ||
768 | default: | 769 | default: |
769 | DRM_DEBUG_KMS("Invalid request %d\n", info->query); | 770 | DRM_DEBUG_KMS("Invalid request %d\n", info->query); |
770 | return -EINVAL; | 771 | return -EINVAL; |
@@ -791,12 +792,6 @@ void amdgpu_driver_lastclose_kms(struct drm_device *dev) | |||
791 | vga_switcheroo_process_delayed_switch(); | 792 | vga_switcheroo_process_delayed_switch(); |
792 | } | 793 | } |
793 | 794 | ||
794 | bool amdgpu_kms_vram_lost(struct amdgpu_device *adev, | ||
795 | struct amdgpu_fpriv *fpriv) | ||
796 | { | ||
797 | return fpriv->vram_lost_counter != atomic_read(&adev->vram_lost_counter); | ||
798 | } | ||
799 | |||
800 | /** | 795 | /** |
801 | * amdgpu_driver_open_kms - drm callback for open | 796 | * amdgpu_driver_open_kms - drm callback for open |
802 | * | 797 | * |
@@ -825,7 +820,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | |||
825 | } | 820 | } |
826 | 821 | ||
827 | r = amdgpu_vm_init(adev, &fpriv->vm, | 822 | r = amdgpu_vm_init(adev, &fpriv->vm, |
828 | AMDGPU_VM_CONTEXT_GFX); | 823 | AMDGPU_VM_CONTEXT_GFX, 0); |
829 | if (r) { | 824 | if (r) { |
830 | kfree(fpriv); | 825 | kfree(fpriv); |
831 | goto out_suspend; | 826 | goto out_suspend; |
@@ -841,8 +836,11 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | |||
841 | 836 | ||
842 | if (amdgpu_sriov_vf(adev)) { | 837 | if (amdgpu_sriov_vf(adev)) { |
843 | r = amdgpu_map_static_csa(adev, &fpriv->vm, &fpriv->csa_va); | 838 | r = amdgpu_map_static_csa(adev, &fpriv->vm, &fpriv->csa_va); |
844 | if (r) | 839 | if (r) { |
840 | amdgpu_vm_fini(adev, &fpriv->vm); | ||
841 | kfree(fpriv); | ||
845 | goto out_suspend; | 842 | goto out_suspend; |
843 | } | ||
846 | } | 844 | } |
847 | 845 | ||
848 | mutex_init(&fpriv->bo_list_lock); | 846 | mutex_init(&fpriv->bo_list_lock); |
@@ -850,7 +848,6 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | |||
850 | 848 | ||
851 | amdgpu_ctx_mgr_init(&fpriv->ctx_mgr); | 849 | amdgpu_ctx_mgr_init(&fpriv->ctx_mgr); |
852 | 850 | ||
853 | fpriv->vram_lost_counter = atomic_read(&adev->vram_lost_counter); | ||
854 | file_priv->driver_priv = fpriv; | 851 | file_priv->driver_priv = fpriv; |
855 | 852 | ||
856 | out_suspend: | 853 | out_suspend: |
@@ -1020,7 +1017,9 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { | |||
1020 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_CREATE, amdgpu_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), | 1017 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_CREATE, amdgpu_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), |
1021 | DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), | 1018 | DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), |
1022 | DRM_IOCTL_DEF_DRV(AMDGPU_VM, amdgpu_vm_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), | 1019 | DRM_IOCTL_DEF_DRV(AMDGPU_VM, amdgpu_vm_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), |
1020 | DRM_IOCTL_DEF_DRV(AMDGPU_SCHED, amdgpu_sched_ioctl, DRM_MASTER), | ||
1023 | DRM_IOCTL_DEF_DRV(AMDGPU_BO_LIST, amdgpu_bo_list_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), | 1021 | DRM_IOCTL_DEF_DRV(AMDGPU_BO_LIST, amdgpu_bo_list_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), |
1022 | DRM_IOCTL_DEF_DRV(AMDGPU_FENCE_TO_HANDLE, amdgpu_cs_fence_to_handle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), | ||
1024 | /* KMS */ | 1023 | /* KMS */ |
1025 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_MMAP, amdgpu_gem_mmap_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), | 1024 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_MMAP, amdgpu_gem_mmap_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), |
1026 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_WAIT_IDLE, amdgpu_gem_wait_idle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), | 1025 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_WAIT_IDLE, amdgpu_gem_wait_idle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), |
@@ -1031,7 +1030,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { | |||
1031 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_METADATA, amdgpu_gem_metadata_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), | 1030 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_METADATA, amdgpu_gem_metadata_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), |
1032 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_VA, amdgpu_gem_va_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), | 1031 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_VA, amdgpu_gem_va_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), |
1033 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), | 1032 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), |
1034 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_USERPTR, amdgpu_gem_userptr_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), | 1033 | DRM_IOCTL_DEF_DRV(AMDGPU_GEM_USERPTR, amdgpu_gem_userptr_ioctl, DRM_AUTH|DRM_RENDER_ALLOW) |
1035 | }; | 1034 | }; |
1036 | const int amdgpu_max_kms_ioctl = ARRAY_SIZE(amdgpu_ioctls_kms); | 1035 | const int amdgpu_max_kms_ioctl = ARRAY_SIZE(amdgpu_ioctls_kms); |
1037 | 1036 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c index 3b0f2ec6eec7..bd67f4cb8e6c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | |||
@@ -50,8 +50,10 @@ struct amdgpu_mn { | |||
50 | struct hlist_node node; | 50 | struct hlist_node node; |
51 | 51 | ||
52 | /* objects protected by lock */ | 52 | /* objects protected by lock */ |
53 | struct mutex lock; | 53 | struct rw_semaphore lock; |
54 | struct rb_root_cached objects; | 54 | struct rb_root_cached objects; |
55 | struct mutex read_lock; | ||
56 | atomic_t recursion; | ||
55 | }; | 57 | }; |
56 | 58 | ||
57 | struct amdgpu_mn_node { | 59 | struct amdgpu_mn_node { |
@@ -74,7 +76,7 @@ static void amdgpu_mn_destroy(struct work_struct *work) | |||
74 | struct amdgpu_bo *bo, *next_bo; | 76 | struct amdgpu_bo *bo, *next_bo; |
75 | 77 | ||
76 | mutex_lock(&adev->mn_lock); | 78 | mutex_lock(&adev->mn_lock); |
77 | mutex_lock(&rmn->lock); | 79 | down_write(&rmn->lock); |
78 | hash_del(&rmn->node); | 80 | hash_del(&rmn->node); |
79 | rbtree_postorder_for_each_entry_safe(node, next_node, | 81 | rbtree_postorder_for_each_entry_safe(node, next_node, |
80 | &rmn->objects.rb_root, it.rb) { | 82 | &rmn->objects.rb_root, it.rb) { |
@@ -84,7 +86,7 @@ static void amdgpu_mn_destroy(struct work_struct *work) | |||
84 | } | 86 | } |
85 | kfree(node); | 87 | kfree(node); |
86 | } | 88 | } |
87 | mutex_unlock(&rmn->lock); | 89 | up_write(&rmn->lock); |
88 | mutex_unlock(&adev->mn_lock); | 90 | mutex_unlock(&adev->mn_lock); |
89 | mmu_notifier_unregister_no_release(&rmn->mn, rmn->mm); | 91 | mmu_notifier_unregister_no_release(&rmn->mn, rmn->mm); |
90 | kfree(rmn); | 92 | kfree(rmn); |
@@ -106,6 +108,53 @@ static void amdgpu_mn_release(struct mmu_notifier *mn, | |||
106 | schedule_work(&rmn->work); | 108 | schedule_work(&rmn->work); |
107 | } | 109 | } |
108 | 110 | ||
111 | |||
112 | /** | ||
113 | * amdgpu_mn_lock - take the write side lock for this mn | ||
114 | */ | ||
115 | void amdgpu_mn_lock(struct amdgpu_mn *mn) | ||
116 | { | ||
117 | if (mn) | ||
118 | down_write(&mn->lock); | ||
119 | } | ||
120 | |||
121 | /** | ||
122 | * amdgpu_mn_unlock - drop the write side lock for this mn | ||
123 | */ | ||
124 | void amdgpu_mn_unlock(struct amdgpu_mn *mn) | ||
125 | { | ||
126 | if (mn) | ||
127 | up_write(&mn->lock); | ||
128 | } | ||
129 | |||
130 | /** | ||
131 | * amdgpu_mn_read_lock - take the rmn read lock | ||
132 | * | ||
133 | * @rmn: our notifier | ||
134 | * | ||
135 | * Take the rmn read side lock. | ||
136 | */ | ||
137 | static void amdgpu_mn_read_lock(struct amdgpu_mn *rmn) | ||
138 | { | ||
139 | mutex_lock(&rmn->read_lock); | ||
140 | if (atomic_inc_return(&rmn->recursion) == 1) | ||
141 | down_read_non_owner(&rmn->lock); | ||
142 | mutex_unlock(&rmn->read_lock); | ||
143 | } | ||
144 | |||
145 | /** | ||
146 | * amdgpu_mn_read_unlock - drop the rmn read lock | ||
147 | * | ||
148 | * @rmn: our notifier | ||
149 | * | ||
150 | * Drop the rmn read side lock. | ||
151 | */ | ||
152 | static void amdgpu_mn_read_unlock(struct amdgpu_mn *rmn) | ||
153 | { | ||
154 | if (atomic_dec_return(&rmn->recursion) == 0) | ||
155 | up_read_non_owner(&rmn->lock); | ||
156 | } | ||
157 | |||
109 | /** | 158 | /** |
110 | * amdgpu_mn_invalidate_node - unmap all BOs of a node | 159 | * amdgpu_mn_invalidate_node - unmap all BOs of a node |
111 | * | 160 | * |
@@ -126,23 +175,12 @@ static void amdgpu_mn_invalidate_node(struct amdgpu_mn_node *node, | |||
126 | if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, start, end)) | 175 | if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, start, end)) |
127 | continue; | 176 | continue; |
128 | 177 | ||
129 | r = amdgpu_bo_reserve(bo, true); | ||
130 | if (r) { | ||
131 | DRM_ERROR("(%ld) failed to reserve user bo\n", r); | ||
132 | continue; | ||
133 | } | ||
134 | |||
135 | r = reservation_object_wait_timeout_rcu(bo->tbo.resv, | 178 | r = reservation_object_wait_timeout_rcu(bo->tbo.resv, |
136 | true, false, MAX_SCHEDULE_TIMEOUT); | 179 | true, false, MAX_SCHEDULE_TIMEOUT); |
137 | if (r <= 0) | 180 | if (r <= 0) |
138 | DRM_ERROR("(%ld) failed to wait for user bo\n", r); | 181 | DRM_ERROR("(%ld) failed to wait for user bo\n", r); |
139 | 182 | ||
140 | amdgpu_ttm_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_CPU); | 183 | amdgpu_ttm_tt_mark_user_pages(bo->tbo.ttm); |
141 | r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); | ||
142 | if (r) | ||
143 | DRM_ERROR("(%ld) failed to validate user bo\n", r); | ||
144 | |||
145 | amdgpu_bo_unreserve(bo); | ||
146 | } | 184 | } |
147 | } | 185 | } |
148 | 186 | ||
@@ -168,7 +206,7 @@ static void amdgpu_mn_invalidate_range_start(struct mmu_notifier *mn, | |||
168 | /* notification is exclusive, but interval is inclusive */ | 206 | /* notification is exclusive, but interval is inclusive */ |
169 | end -= 1; | 207 | end -= 1; |
170 | 208 | ||
171 | mutex_lock(&rmn->lock); | 209 | amdgpu_mn_read_lock(rmn); |
172 | 210 | ||
173 | it = interval_tree_iter_first(&rmn->objects, start, end); | 211 | it = interval_tree_iter_first(&rmn->objects, start, end); |
174 | while (it) { | 212 | while (it) { |
@@ -179,13 +217,32 @@ static void amdgpu_mn_invalidate_range_start(struct mmu_notifier *mn, | |||
179 | 217 | ||
180 | amdgpu_mn_invalidate_node(node, start, end); | 218 | amdgpu_mn_invalidate_node(node, start, end); |
181 | } | 219 | } |
220 | } | ||
182 | 221 | ||
183 | mutex_unlock(&rmn->lock); | 222 | /** |
223 | * amdgpu_mn_invalidate_range_end - callback to notify about mm change | ||
224 | * | ||
225 | * @mn: our notifier | ||
226 | * @mn: the mm this callback is about | ||
227 | * @start: start of updated range | ||
228 | * @end: end of updated range | ||
229 | * | ||
230 | * Release the lock again to allow new command submissions. | ||
231 | */ | ||
232 | static void amdgpu_mn_invalidate_range_end(struct mmu_notifier *mn, | ||
233 | struct mm_struct *mm, | ||
234 | unsigned long start, | ||
235 | unsigned long end) | ||
236 | { | ||
237 | struct amdgpu_mn *rmn = container_of(mn, struct amdgpu_mn, mn); | ||
238 | |||
239 | amdgpu_mn_read_unlock(rmn); | ||
184 | } | 240 | } |
185 | 241 | ||
186 | static const struct mmu_notifier_ops amdgpu_mn_ops = { | 242 | static const struct mmu_notifier_ops amdgpu_mn_ops = { |
187 | .release = amdgpu_mn_release, | 243 | .release = amdgpu_mn_release, |
188 | .invalidate_range_start = amdgpu_mn_invalidate_range_start, | 244 | .invalidate_range_start = amdgpu_mn_invalidate_range_start, |
245 | .invalidate_range_end = amdgpu_mn_invalidate_range_end, | ||
189 | }; | 246 | }; |
190 | 247 | ||
191 | /** | 248 | /** |
@@ -195,7 +252,7 @@ static const struct mmu_notifier_ops amdgpu_mn_ops = { | |||
195 | * | 252 | * |
196 | * Creates a notifier context for current->mm. | 253 | * Creates a notifier context for current->mm. |
197 | */ | 254 | */ |
198 | static struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev) | 255 | struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev) |
199 | { | 256 | { |
200 | struct mm_struct *mm = current->mm; | 257 | struct mm_struct *mm = current->mm; |
201 | struct amdgpu_mn *rmn; | 258 | struct amdgpu_mn *rmn; |
@@ -220,8 +277,10 @@ static struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev) | |||
220 | rmn->adev = adev; | 277 | rmn->adev = adev; |
221 | rmn->mm = mm; | 278 | rmn->mm = mm; |
222 | rmn->mn.ops = &amdgpu_mn_ops; | 279 | rmn->mn.ops = &amdgpu_mn_ops; |
223 | mutex_init(&rmn->lock); | 280 | init_rwsem(&rmn->lock); |
224 | rmn->objects = RB_ROOT_CACHED; | 281 | rmn->objects = RB_ROOT_CACHED; |
282 | mutex_init(&rmn->read_lock); | ||
283 | atomic_set(&rmn->recursion, 0); | ||
225 | 284 | ||
226 | r = __mmu_notifier_register(&rmn->mn, mm); | 285 | r = __mmu_notifier_register(&rmn->mn, mm); |
227 | if (r) | 286 | if (r) |
@@ -267,7 +326,7 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr) | |||
267 | 326 | ||
268 | INIT_LIST_HEAD(&bos); | 327 | INIT_LIST_HEAD(&bos); |
269 | 328 | ||
270 | mutex_lock(&rmn->lock); | 329 | down_write(&rmn->lock); |
271 | 330 | ||
272 | while ((it = interval_tree_iter_first(&rmn->objects, addr, end))) { | 331 | while ((it = interval_tree_iter_first(&rmn->objects, addr, end))) { |
273 | kfree(node); | 332 | kfree(node); |
@@ -281,7 +340,7 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr) | |||
281 | if (!node) { | 340 | if (!node) { |
282 | node = kmalloc(sizeof(struct amdgpu_mn_node), GFP_KERNEL); | 341 | node = kmalloc(sizeof(struct amdgpu_mn_node), GFP_KERNEL); |
283 | if (!node) { | 342 | if (!node) { |
284 | mutex_unlock(&rmn->lock); | 343 | up_write(&rmn->lock); |
285 | return -ENOMEM; | 344 | return -ENOMEM; |
286 | } | 345 | } |
287 | } | 346 | } |
@@ -296,7 +355,7 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr) | |||
296 | 355 | ||
297 | interval_tree_insert(&node->it, &rmn->objects); | 356 | interval_tree_insert(&node->it, &rmn->objects); |
298 | 357 | ||
299 | mutex_unlock(&rmn->lock); | 358 | up_write(&rmn->lock); |
300 | 359 | ||
301 | return 0; | 360 | return 0; |
302 | } | 361 | } |
@@ -322,7 +381,7 @@ void amdgpu_mn_unregister(struct amdgpu_bo *bo) | |||
322 | return; | 381 | return; |
323 | } | 382 | } |
324 | 383 | ||
325 | mutex_lock(&rmn->lock); | 384 | down_write(&rmn->lock); |
326 | 385 | ||
327 | /* save the next list entry for later */ | 386 | /* save the next list entry for later */ |
328 | head = bo->mn_list.next; | 387 | head = bo->mn_list.next; |
@@ -337,6 +396,7 @@ void amdgpu_mn_unregister(struct amdgpu_bo *bo) | |||
337 | kfree(node); | 396 | kfree(node); |
338 | } | 397 | } |
339 | 398 | ||
340 | mutex_unlock(&rmn->lock); | 399 | up_write(&rmn->lock); |
341 | mutex_unlock(&adev->mn_lock); | 400 | mutex_unlock(&adev->mn_lock); |
342 | } | 401 | } |
402 | |||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h new file mode 100644 index 000000000000..d0095a3793b8 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * Copyright 2017 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 | * Authors: Christian König | ||
23 | */ | ||
24 | #ifndef __AMDGPU_MN_H__ | ||
25 | #define __AMDGPU_MN_H__ | ||
26 | |||
27 | /* | ||
28 | * MMU Notifier | ||
29 | */ | ||
30 | struct amdgpu_mn; | ||
31 | |||
32 | #if defined(CONFIG_MMU_NOTIFIER) | ||
33 | void amdgpu_mn_lock(struct amdgpu_mn *mn); | ||
34 | void amdgpu_mn_unlock(struct amdgpu_mn *mn); | ||
35 | struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev); | ||
36 | int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr); | ||
37 | void amdgpu_mn_unregister(struct amdgpu_bo *bo); | ||
38 | #else | ||
39 | static inline void amdgpu_mn_lock(struct amdgpu_mn *mn) {} | ||
40 | static inline void amdgpu_mn_unlock(struct amdgpu_mn *mn) {} | ||
41 | static inline struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev) | ||
42 | { | ||
43 | return NULL; | ||
44 | } | ||
45 | static inline int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr) | ||
46 | { | ||
47 | return -ENODEV; | ||
48 | } | ||
49 | static inline void amdgpu_mn_unregister(struct amdgpu_bo *bo) {} | ||
50 | #endif | ||
51 | |||
52 | #endif | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 2af2678ddaf6..ffde1e9666e8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | |||
@@ -38,11 +38,15 @@ | |||
38 | #include <drm/drm_crtc_helper.h> | 38 | #include <drm/drm_crtc_helper.h> |
39 | #include <drm/drm_fb_helper.h> | 39 | #include <drm/drm_fb_helper.h> |
40 | #include <drm/drm_plane_helper.h> | 40 | #include <drm/drm_plane_helper.h> |
41 | #include <drm/drm_fb_helper.h> | ||
41 | #include <linux/i2c.h> | 42 | #include <linux/i2c.h> |
42 | #include <linux/i2c-algo-bit.h> | 43 | #include <linux/i2c-algo-bit.h> |
43 | #include <linux/hrtimer.h> | 44 | #include <linux/hrtimer.h> |
44 | #include "amdgpu_irq.h" | 45 | #include "amdgpu_irq.h" |
45 | 46 | ||
47 | #include <drm/drm_dp_mst_helper.h> | ||
48 | #include "modules/inc/mod_freesync.h" | ||
49 | |||
46 | struct amdgpu_bo; | 50 | struct amdgpu_bo; |
47 | struct amdgpu_device; | 51 | struct amdgpu_device; |
48 | struct amdgpu_encoder; | 52 | struct amdgpu_encoder; |
@@ -53,9 +57,13 @@ struct amdgpu_hpd; | |||
53 | #define to_amdgpu_connector(x) container_of(x, struct amdgpu_connector, base) | 57 | #define to_amdgpu_connector(x) container_of(x, struct amdgpu_connector, base) |
54 | #define to_amdgpu_encoder(x) container_of(x, struct amdgpu_encoder, base) | 58 | #define to_amdgpu_encoder(x) container_of(x, struct amdgpu_encoder, base) |
55 | #define to_amdgpu_framebuffer(x) container_of(x, struct amdgpu_framebuffer, base) | 59 | #define to_amdgpu_framebuffer(x) container_of(x, struct amdgpu_framebuffer, base) |
60 | #define to_amdgpu_plane(x) container_of(x, struct amdgpu_plane, base) | ||
61 | |||
62 | #define to_dm_plane_state(x) container_of(x, struct dm_plane_state, base); | ||
56 | 63 | ||
57 | #define AMDGPU_MAX_HPD_PINS 6 | 64 | #define AMDGPU_MAX_HPD_PINS 6 |
58 | #define AMDGPU_MAX_CRTCS 6 | 65 | #define AMDGPU_MAX_CRTCS 6 |
66 | #define AMDGPU_MAX_PLANES 6 | ||
59 | #define AMDGPU_MAX_AFMT_BLOCKS 9 | 67 | #define AMDGPU_MAX_AFMT_BLOCKS 9 |
60 | 68 | ||
61 | enum amdgpu_rmx_type { | 69 | enum amdgpu_rmx_type { |
@@ -292,6 +300,30 @@ struct amdgpu_display_funcs { | |||
292 | uint16_t connector_object_id, | 300 | uint16_t connector_object_id, |
293 | struct amdgpu_hpd *hpd, | 301 | struct amdgpu_hpd *hpd, |
294 | struct amdgpu_router *router); | 302 | struct amdgpu_router *router); |
303 | /* it is used to enter or exit into free sync mode */ | ||
304 | int (*notify_freesync)(struct drm_device *dev, void *data, | ||
305 | struct drm_file *filp); | ||
306 | /* it is used to allow enablement of freesync mode */ | ||
307 | int (*set_freesync_property)(struct drm_connector *connector, | ||
308 | struct drm_property *property, | ||
309 | uint64_t val); | ||
310 | |||
311 | |||
312 | }; | ||
313 | |||
314 | struct amdgpu_framebuffer { | ||
315 | struct drm_framebuffer base; | ||
316 | struct drm_gem_object *obj; | ||
317 | |||
318 | /* caching for later use */ | ||
319 | uint64_t address; | ||
320 | }; | ||
321 | |||
322 | struct amdgpu_fbdev { | ||
323 | struct drm_fb_helper helper; | ||
324 | struct amdgpu_framebuffer rfb; | ||
325 | struct list_head fbdev_list; | ||
326 | struct amdgpu_device *adev; | ||
295 | }; | 327 | }; |
296 | 328 | ||
297 | struct amdgpu_mode_info { | 329 | struct amdgpu_mode_info { |
@@ -299,6 +331,7 @@ struct amdgpu_mode_info { | |||
299 | struct card_info *atom_card_info; | 331 | struct card_info *atom_card_info; |
300 | bool mode_config_initialized; | 332 | bool mode_config_initialized; |
301 | struct amdgpu_crtc *crtcs[AMDGPU_MAX_CRTCS]; | 333 | struct amdgpu_crtc *crtcs[AMDGPU_MAX_CRTCS]; |
334 | struct amdgpu_plane *planes[AMDGPU_MAX_PLANES]; | ||
302 | struct amdgpu_afmt *afmt[AMDGPU_MAX_AFMT_BLOCKS]; | 335 | struct amdgpu_afmt *afmt[AMDGPU_MAX_AFMT_BLOCKS]; |
303 | /* DVI-I properties */ | 336 | /* DVI-I properties */ |
304 | struct drm_property *coherent_mode_property; | 337 | struct drm_property *coherent_mode_property; |
@@ -328,6 +361,7 @@ struct amdgpu_mode_info { | |||
328 | int num_dig; /* number of dig blocks */ | 361 | int num_dig; /* number of dig blocks */ |
329 | int disp_priority; | 362 | int disp_priority; |
330 | const struct amdgpu_display_funcs *funcs; | 363 | const struct amdgpu_display_funcs *funcs; |
364 | const enum drm_plane_type *plane_type; | ||
331 | }; | 365 | }; |
332 | 366 | ||
333 | #define AMDGPU_MAX_BL_LEVEL 0xFF | 367 | #define AMDGPU_MAX_BL_LEVEL 0xFF |
@@ -400,6 +434,14 @@ struct amdgpu_crtc { | |||
400 | /* for virtual dce */ | 434 | /* for virtual dce */ |
401 | struct hrtimer vblank_timer; | 435 | struct hrtimer vblank_timer; |
402 | enum amdgpu_interrupt_state vsync_timer_enabled; | 436 | enum amdgpu_interrupt_state vsync_timer_enabled; |
437 | |||
438 | int otg_inst; | ||
439 | struct drm_pending_vblank_event *event; | ||
440 | }; | ||
441 | |||
442 | struct amdgpu_plane { | ||
443 | struct drm_plane base; | ||
444 | enum drm_plane_type plane_type; | ||
403 | }; | 445 | }; |
404 | 446 | ||
405 | struct amdgpu_encoder_atom_dig { | 447 | struct amdgpu_encoder_atom_dig { |
@@ -489,6 +531,19 @@ enum amdgpu_connector_dither { | |||
489 | AMDGPU_FMT_DITHER_ENABLE = 1, | 531 | AMDGPU_FMT_DITHER_ENABLE = 1, |
490 | }; | 532 | }; |
491 | 533 | ||
534 | struct amdgpu_dm_dp_aux { | ||
535 | struct drm_dp_aux aux; | ||
536 | struct ddc_service *ddc_service; | ||
537 | }; | ||
538 | |||
539 | struct amdgpu_i2c_adapter { | ||
540 | struct i2c_adapter base; | ||
541 | |||
542 | struct ddc_service *ddc_service; | ||
543 | }; | ||
544 | |||
545 | #define TO_DM_AUX(x) container_of((x), struct amdgpu_dm_dp_aux, aux) | ||
546 | |||
492 | struct amdgpu_connector { | 547 | struct amdgpu_connector { |
493 | struct drm_connector base; | 548 | struct drm_connector base; |
494 | uint32_t connector_id; | 549 | uint32_t connector_id; |
@@ -500,6 +555,14 @@ struct amdgpu_connector { | |||
500 | /* we need to mind the EDID between detect | 555 | /* we need to mind the EDID between detect |
501 | and get modes due to analog/digital/tvencoder */ | 556 | and get modes due to analog/digital/tvencoder */ |
502 | struct edid *edid; | 557 | struct edid *edid; |
558 | /* number of modes generated from EDID at 'dc_sink' */ | ||
559 | int num_modes; | ||
560 | /* The 'old' sink - before an HPD. | ||
561 | * The 'current' sink is in dc_link->sink. */ | ||
562 | struct dc_sink *dc_sink; | ||
563 | struct dc_link *dc_link; | ||
564 | struct dc_sink *dc_em_sink; | ||
565 | const struct dc_stream *stream; | ||
503 | void *con_priv; | 566 | void *con_priv; |
504 | bool dac_load_detect; | 567 | bool dac_load_detect; |
505 | bool detected_by_load; /* if the connection status was determined by load */ | 568 | bool detected_by_load; /* if the connection status was determined by load */ |
@@ -510,11 +573,39 @@ struct amdgpu_connector { | |||
510 | enum amdgpu_connector_audio audio; | 573 | enum amdgpu_connector_audio audio; |
511 | enum amdgpu_connector_dither dither; | 574 | enum amdgpu_connector_dither dither; |
512 | unsigned pixelclock_for_modeset; | 575 | unsigned pixelclock_for_modeset; |
576 | |||
577 | struct drm_dp_mst_topology_mgr mst_mgr; | ||
578 | struct amdgpu_dm_dp_aux dm_dp_aux; | ||
579 | struct drm_dp_mst_port *port; | ||
580 | struct amdgpu_connector *mst_port; | ||
581 | struct amdgpu_encoder *mst_encoder; | ||
582 | struct semaphore mst_sem; | ||
583 | |||
584 | /* TODO see if we can merge with ddc_bus or make a dm_connector */ | ||
585 | struct amdgpu_i2c_adapter *i2c; | ||
586 | |||
587 | /* Monitor range limits */ | ||
588 | int min_vfreq ; | ||
589 | int max_vfreq ; | ||
590 | int pixel_clock_mhz; | ||
591 | |||
592 | /*freesync caps*/ | ||
593 | struct mod_freesync_caps caps; | ||
594 | |||
595 | struct mutex hpd_lock; | ||
596 | |||
513 | }; | 597 | }; |
514 | 598 | ||
515 | struct amdgpu_framebuffer { | 599 | /* TODO: start to use this struct and remove same field from base one */ |
516 | struct drm_framebuffer base; | 600 | struct amdgpu_mst_connector { |
517 | struct drm_gem_object *obj; | 601 | struct amdgpu_connector base; |
602 | |||
603 | struct drm_dp_mst_topology_mgr mst_mgr; | ||
604 | struct amdgpu_dm_dp_aux dm_dp_aux; | ||
605 | struct drm_dp_mst_port *port; | ||
606 | struct amdgpu_connector *mst_port; | ||
607 | bool is_mst_connector; | ||
608 | struct amdgpu_encoder *mst_encoder; | ||
518 | }; | 609 | }; |
519 | 610 | ||
520 | #define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \ | 611 | #define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \ |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 9e495da0bb03..ea25164e7f4b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | |||
@@ -40,9 +40,7 @@ | |||
40 | static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) | 40 | static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) |
41 | { | 41 | { |
42 | struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev); | 42 | struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev); |
43 | struct amdgpu_bo *bo; | 43 | struct amdgpu_bo *bo = ttm_to_amdgpu_bo(tbo); |
44 | |||
45 | bo = container_of(tbo, struct amdgpu_bo, tbo); | ||
46 | 44 | ||
47 | amdgpu_bo_kunmap(bo); | 45 | amdgpu_bo_kunmap(bo); |
48 | 46 | ||
@@ -64,11 +62,12 @@ bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo) | |||
64 | return false; | 62 | return false; |
65 | } | 63 | } |
66 | 64 | ||
67 | static void amdgpu_ttm_placement_init(struct amdgpu_device *adev, | 65 | void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain) |
68 | struct ttm_placement *placement, | ||
69 | struct ttm_place *places, | ||
70 | u32 domain, u64 flags) | ||
71 | { | 66 | { |
67 | struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev); | ||
68 | struct ttm_placement *placement = &abo->placement; | ||
69 | struct ttm_place *places = abo->placements; | ||
70 | u64 flags = abo->flags; | ||
72 | u32 c = 0; | 71 | u32 c = 0; |
73 | 72 | ||
74 | if (domain & AMDGPU_GEM_DOMAIN_VRAM) { | 73 | if (domain & AMDGPU_GEM_DOMAIN_VRAM) { |
@@ -151,27 +150,6 @@ static void amdgpu_ttm_placement_init(struct amdgpu_device *adev, | |||
151 | placement->busy_placement = places; | 150 | placement->busy_placement = places; |
152 | } | 151 | } |
153 | 152 | ||
154 | void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain) | ||
155 | { | ||
156 | struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev); | ||
157 | |||
158 | amdgpu_ttm_placement_init(adev, &abo->placement, abo->placements, | ||
159 | domain, abo->flags); | ||
160 | } | ||
161 | |||
162 | static void amdgpu_fill_placement_to_bo(struct amdgpu_bo *bo, | ||
163 | struct ttm_placement *placement) | ||
164 | { | ||
165 | BUG_ON(placement->num_placement > (AMDGPU_GEM_DOMAIN_MAX + 1)); | ||
166 | |||
167 | memcpy(bo->placements, placement->placement, | ||
168 | placement->num_placement * sizeof(struct ttm_place)); | ||
169 | bo->placement.num_placement = placement->num_placement; | ||
170 | bo->placement.num_busy_placement = placement->num_busy_placement; | ||
171 | bo->placement.placement = bo->placements; | ||
172 | bo->placement.busy_placement = bo->placements; | ||
173 | } | ||
174 | |||
175 | /** | 153 | /** |
176 | * amdgpu_bo_create_reserved - create reserved BO for kernel use | 154 | * amdgpu_bo_create_reserved - create reserved BO for kernel use |
177 | * | 155 | * |
@@ -303,14 +281,13 @@ void amdgpu_bo_free_kernel(struct amdgpu_bo **bo, u64 *gpu_addr, | |||
303 | *cpu_addr = NULL; | 281 | *cpu_addr = NULL; |
304 | } | 282 | } |
305 | 283 | ||
306 | int amdgpu_bo_create_restricted(struct amdgpu_device *adev, | 284 | static int amdgpu_bo_do_create(struct amdgpu_device *adev, |
307 | unsigned long size, int byte_align, | 285 | unsigned long size, int byte_align, |
308 | bool kernel, u32 domain, u64 flags, | 286 | bool kernel, u32 domain, u64 flags, |
309 | struct sg_table *sg, | 287 | struct sg_table *sg, |
310 | struct ttm_placement *placement, | 288 | struct reservation_object *resv, |
311 | struct reservation_object *resv, | 289 | uint64_t init_value, |
312 | uint64_t init_value, | 290 | struct amdgpu_bo **bo_ptr) |
313 | struct amdgpu_bo **bo_ptr) | ||
314 | { | 291 | { |
315 | struct amdgpu_bo *bo; | 292 | struct amdgpu_bo *bo; |
316 | enum ttm_bo_type type; | 293 | enum ttm_bo_type type; |
@@ -384,13 +361,17 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev, | |||
384 | bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC; | 361 | bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC; |
385 | #endif | 362 | #endif |
386 | 363 | ||
387 | amdgpu_fill_placement_to_bo(bo, placement); | 364 | bo->tbo.bdev = &adev->mman.bdev; |
388 | /* Kernel allocation are uninterruptible */ | 365 | amdgpu_ttm_placement_from_domain(bo, domain); |
389 | 366 | ||
390 | initial_bytes_moved = atomic64_read(&adev->num_bytes_moved); | 367 | initial_bytes_moved = atomic64_read(&adev->num_bytes_moved); |
368 | /* Kernel allocation are uninterruptible */ | ||
391 | r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, type, | 369 | r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, type, |
392 | &bo->placement, page_align, !kernel, NULL, | 370 | &bo->placement, page_align, !kernel, NULL, |
393 | acc_size, sg, resv, &amdgpu_ttm_bo_destroy); | 371 | acc_size, sg, resv, &amdgpu_ttm_bo_destroy); |
372 | if (unlikely(r != 0)) | ||
373 | return r; | ||
374 | |||
394 | bytes_moved = atomic64_read(&adev->num_bytes_moved) - | 375 | bytes_moved = atomic64_read(&adev->num_bytes_moved) - |
395 | initial_bytes_moved; | 376 | initial_bytes_moved; |
396 | if (adev->mc.visible_vram_size < adev->mc.real_vram_size && | 377 | if (adev->mc.visible_vram_size < adev->mc.real_vram_size && |
@@ -400,9 +381,6 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev, | |||
400 | else | 381 | else |
401 | amdgpu_cs_report_moved_bytes(adev, bytes_moved, 0); | 382 | amdgpu_cs_report_moved_bytes(adev, bytes_moved, 0); |
402 | 383 | ||
403 | if (unlikely(r != 0)) | ||
404 | return r; | ||
405 | |||
406 | if (kernel) | 384 | if (kernel) |
407 | bo->tbo.priority = 1; | 385 | bo->tbo.priority = 1; |
408 | 386 | ||
@@ -442,27 +420,17 @@ static int amdgpu_bo_create_shadow(struct amdgpu_device *adev, | |||
442 | unsigned long size, int byte_align, | 420 | unsigned long size, int byte_align, |
443 | struct amdgpu_bo *bo) | 421 | struct amdgpu_bo *bo) |
444 | { | 422 | { |
445 | struct ttm_placement placement = {0}; | ||
446 | struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1]; | ||
447 | int r; | 423 | int r; |
448 | 424 | ||
449 | if (bo->shadow) | 425 | if (bo->shadow) |
450 | return 0; | 426 | return 0; |
451 | 427 | ||
452 | memset(&placements, 0, sizeof(placements)); | 428 | r = amdgpu_bo_do_create(adev, size, byte_align, true, |
453 | amdgpu_ttm_placement_init(adev, &placement, placements, | 429 | AMDGPU_GEM_DOMAIN_GTT, |
454 | AMDGPU_GEM_DOMAIN_GTT, | 430 | AMDGPU_GEM_CREATE_CPU_GTT_USWC | |
455 | AMDGPU_GEM_CREATE_CPU_GTT_USWC | | 431 | AMDGPU_GEM_CREATE_SHADOW, |
456 | AMDGPU_GEM_CREATE_SHADOW); | 432 | NULL, bo->tbo.resv, 0, |
457 | 433 | &bo->shadow); | |
458 | r = amdgpu_bo_create_restricted(adev, size, byte_align, true, | ||
459 | AMDGPU_GEM_DOMAIN_GTT, | ||
460 | AMDGPU_GEM_CREATE_CPU_GTT_USWC | | ||
461 | AMDGPU_GEM_CREATE_SHADOW, | ||
462 | NULL, &placement, | ||
463 | bo->tbo.resv, | ||
464 | 0, | ||
465 | &bo->shadow); | ||
466 | if (!r) { | 434 | if (!r) { |
467 | bo->shadow->parent = amdgpu_bo_ref(bo); | 435 | bo->shadow->parent = amdgpu_bo_ref(bo); |
468 | mutex_lock(&adev->shadow_list_lock); | 436 | mutex_lock(&adev->shadow_list_lock); |
@@ -484,18 +452,11 @@ int amdgpu_bo_create(struct amdgpu_device *adev, | |||
484 | uint64_t init_value, | 452 | uint64_t init_value, |
485 | struct amdgpu_bo **bo_ptr) | 453 | struct amdgpu_bo **bo_ptr) |
486 | { | 454 | { |
487 | struct ttm_placement placement = {0}; | ||
488 | struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1]; | ||
489 | uint64_t parent_flags = flags & ~AMDGPU_GEM_CREATE_SHADOW; | 455 | uint64_t parent_flags = flags & ~AMDGPU_GEM_CREATE_SHADOW; |
490 | int r; | 456 | int r; |
491 | 457 | ||
492 | memset(&placements, 0, sizeof(placements)); | 458 | r = amdgpu_bo_do_create(adev, size, byte_align, kernel, domain, |
493 | amdgpu_ttm_placement_init(adev, &placement, placements, | 459 | parent_flags, sg, resv, init_value, bo_ptr); |
494 | domain, parent_flags); | ||
495 | |||
496 | r = amdgpu_bo_create_restricted(adev, size, byte_align, kernel, domain, | ||
497 | parent_flags, sg, &placement, resv, | ||
498 | init_value, bo_ptr); | ||
499 | if (r) | 460 | if (r) |
500 | return r; | 461 | return r; |
501 | 462 | ||
@@ -672,7 +633,6 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, | |||
672 | { | 633 | { |
673 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); | 634 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); |
674 | int r, i; | 635 | int r, i; |
675 | unsigned fpfn, lpfn; | ||
676 | 636 | ||
677 | if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) | 637 | if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) |
678 | return -EPERM; | 638 | return -EPERM; |
@@ -704,22 +664,16 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, | |||
704 | } | 664 | } |
705 | 665 | ||
706 | bo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; | 666 | bo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; |
667 | /* force to pin into visible video ram */ | ||
668 | if (!(bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)) | ||
669 | bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; | ||
707 | amdgpu_ttm_placement_from_domain(bo, domain); | 670 | amdgpu_ttm_placement_from_domain(bo, domain); |
708 | for (i = 0; i < bo->placement.num_placement; i++) { | 671 | for (i = 0; i < bo->placement.num_placement; i++) { |
709 | /* force to pin into visible video ram */ | 672 | unsigned fpfn, lpfn; |
710 | if ((bo->placements[i].flags & TTM_PL_FLAG_VRAM) && | 673 | |
711 | !(bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) && | 674 | fpfn = min_offset >> PAGE_SHIFT; |
712 | (!max_offset || max_offset > | 675 | lpfn = max_offset >> PAGE_SHIFT; |
713 | adev->mc.visible_vram_size)) { | 676 | |
714 | if (WARN_ON_ONCE(min_offset > | ||
715 | adev->mc.visible_vram_size)) | ||
716 | return -EINVAL; | ||
717 | fpfn = min_offset >> PAGE_SHIFT; | ||
718 | lpfn = adev->mc.visible_vram_size >> PAGE_SHIFT; | ||
719 | } else { | ||
720 | fpfn = min_offset >> PAGE_SHIFT; | ||
721 | lpfn = max_offset >> PAGE_SHIFT; | ||
722 | } | ||
723 | if (fpfn > bo->placements[i].fpfn) | 677 | if (fpfn > bo->placements[i].fpfn) |
724 | bo->placements[i].fpfn = fpfn; | 678 | bo->placements[i].fpfn = fpfn; |
725 | if (!bo->placements[i].lpfn || | 679 | if (!bo->placements[i].lpfn || |
@@ -928,8 +882,8 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, | |||
928 | if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) | 882 | if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) |
929 | return; | 883 | return; |
930 | 884 | ||
931 | abo = container_of(bo, struct amdgpu_bo, tbo); | 885 | abo = ttm_to_amdgpu_bo(bo); |
932 | amdgpu_vm_bo_invalidate(adev, abo); | 886 | amdgpu_vm_bo_invalidate(adev, abo, evict); |
933 | 887 | ||
934 | amdgpu_bo_kunmap(abo); | 888 | amdgpu_bo_kunmap(abo); |
935 | 889 | ||
@@ -955,7 +909,7 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) | |||
955 | if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) | 909 | if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) |
956 | return 0; | 910 | return 0; |
957 | 911 | ||
958 | abo = container_of(bo, struct amdgpu_bo, tbo); | 912 | abo = ttm_to_amdgpu_bo(bo); |
959 | 913 | ||
960 | /* Remember that this BO was accessed by the CPU */ | 914 | /* Remember that this BO was accessed by the CPU */ |
961 | abo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; | 915 | abo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index a288fa6d72c8..428aae048f4b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | /* bo virtual addresses in a vm */ | 36 | /* bo virtual addresses in a vm */ |
37 | struct amdgpu_bo_va_mapping { | 37 | struct amdgpu_bo_va_mapping { |
38 | struct amdgpu_bo_va *bo_va; | ||
38 | struct list_head list; | 39 | struct list_head list; |
39 | struct rb_node rb; | 40 | struct rb_node rb; |
40 | uint64_t start; | 41 | uint64_t start; |
@@ -49,12 +50,17 @@ struct amdgpu_bo_va { | |||
49 | struct amdgpu_vm_bo_base base; | 50 | struct amdgpu_vm_bo_base base; |
50 | 51 | ||
51 | /* protected by bo being reserved */ | 52 | /* protected by bo being reserved */ |
52 | struct dma_fence *last_pt_update; | ||
53 | unsigned ref_count; | 53 | unsigned ref_count; |
54 | 54 | ||
55 | /* all other members protected by the VM PD being reserved */ | ||
56 | struct dma_fence *last_pt_update; | ||
57 | |||
55 | /* mappings for this bo_va */ | 58 | /* mappings for this bo_va */ |
56 | struct list_head invalids; | 59 | struct list_head invalids; |
57 | struct list_head valids; | 60 | struct list_head valids; |
61 | |||
62 | /* If the mappings are cleared or filled */ | ||
63 | bool cleared; | ||
58 | }; | 64 | }; |
59 | 65 | ||
60 | struct amdgpu_bo { | 66 | struct amdgpu_bo { |
@@ -88,6 +94,11 @@ struct amdgpu_bo { | |||
88 | }; | 94 | }; |
89 | }; | 95 | }; |
90 | 96 | ||
97 | static inline struct amdgpu_bo *ttm_to_amdgpu_bo(struct ttm_buffer_object *tbo) | ||
98 | { | ||
99 | return container_of(tbo, struct amdgpu_bo, tbo); | ||
100 | } | ||
101 | |||
91 | /** | 102 | /** |
92 | * amdgpu_mem_type_to_domain - return domain corresponding to mem_type | 103 | * amdgpu_mem_type_to_domain - return domain corresponding to mem_type |
93 | * @mem_type: ttm memory type | 104 | * @mem_type: ttm memory type |
@@ -182,6 +193,14 @@ static inline bool amdgpu_bo_gpu_accessible(struct amdgpu_bo *bo) | |||
182 | } | 193 | } |
183 | } | 194 | } |
184 | 195 | ||
196 | /** | ||
197 | * amdgpu_bo_explicit_sync - return whether the bo is explicitly synced | ||
198 | */ | ||
199 | static inline bool amdgpu_bo_explicit_sync(struct amdgpu_bo *bo) | ||
200 | { | ||
201 | return bo->flags & AMDGPU_GEM_CREATE_EXPLICIT_SYNC; | ||
202 | } | ||
203 | |||
185 | int amdgpu_bo_create(struct amdgpu_device *adev, | 204 | int amdgpu_bo_create(struct amdgpu_device *adev, |
186 | unsigned long size, int byte_align, | 205 | unsigned long size, int byte_align, |
187 | bool kernel, u32 domain, u64 flags, | 206 | bool kernel, u32 domain, u64 flags, |
@@ -189,14 +208,6 @@ int amdgpu_bo_create(struct amdgpu_device *adev, | |||
189 | struct reservation_object *resv, | 208 | struct reservation_object *resv, |
190 | uint64_t init_value, | 209 | uint64_t init_value, |
191 | struct amdgpu_bo **bo_ptr); | 210 | struct amdgpu_bo **bo_ptr); |
192 | int amdgpu_bo_create_restricted(struct amdgpu_device *adev, | ||
193 | unsigned long size, int byte_align, | ||
194 | bool kernel, u32 domain, u64 flags, | ||
195 | struct sg_table *sg, | ||
196 | struct ttm_placement *placement, | ||
197 | struct reservation_object *resv, | ||
198 | uint64_t init_value, | ||
199 | struct amdgpu_bo **bo_ptr); | ||
200 | int amdgpu_bo_create_reserved(struct amdgpu_device *adev, | 211 | int amdgpu_bo_create_reserved(struct amdgpu_device *adev, |
201 | unsigned long size, int align, | 212 | unsigned long size, int align, |
202 | u32 domain, struct amdgpu_bo **bo_ptr, | 213 | u32 domain, struct amdgpu_bo **bo_ptr, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 7df503aedb69..6c570d4e4516 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | |||
@@ -64,17 +64,13 @@ static const struct cg_flag_name clocks[] = { | |||
64 | 64 | ||
65 | void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev) | 65 | void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev) |
66 | { | 66 | { |
67 | if (adev->pp_enabled) | ||
68 | /* TODO */ | ||
69 | return; | ||
70 | |||
71 | if (adev->pm.dpm_enabled) { | 67 | if (adev->pm.dpm_enabled) { |
72 | mutex_lock(&adev->pm.mutex); | 68 | mutex_lock(&adev->pm.mutex); |
73 | if (power_supply_is_system_supplied() > 0) | 69 | if (power_supply_is_system_supplied() > 0) |
74 | adev->pm.dpm.ac_power = true; | 70 | adev->pm.dpm.ac_power = true; |
75 | else | 71 | else |
76 | adev->pm.dpm.ac_power = false; | 72 | adev->pm.dpm.ac_power = false; |
77 | if (adev->pm.funcs->enable_bapm) | 73 | if (adev->powerplay.pp_funcs->enable_bapm) |
78 | amdgpu_dpm_enable_bapm(adev, adev->pm.dpm.ac_power); | 74 | amdgpu_dpm_enable_bapm(adev, adev->pm.dpm.ac_power); |
79 | mutex_unlock(&adev->pm.mutex); | 75 | mutex_unlock(&adev->pm.mutex); |
80 | } | 76 | } |
@@ -88,9 +84,9 @@ static ssize_t amdgpu_get_dpm_state(struct device *dev, | |||
88 | struct amdgpu_device *adev = ddev->dev_private; | 84 | struct amdgpu_device *adev = ddev->dev_private; |
89 | enum amd_pm_state_type pm; | 85 | enum amd_pm_state_type pm; |
90 | 86 | ||
91 | if (adev->pp_enabled) { | 87 | if (adev->powerplay.pp_funcs->get_current_power_state) |
92 | pm = amdgpu_dpm_get_current_power_state(adev); | 88 | pm = amdgpu_dpm_get_current_power_state(adev); |
93 | } else | 89 | else |
94 | pm = adev->pm.dpm.user_state; | 90 | pm = adev->pm.dpm.user_state; |
95 | 91 | ||
96 | return snprintf(buf, PAGE_SIZE, "%s\n", | 92 | return snprintf(buf, PAGE_SIZE, "%s\n", |
@@ -118,8 +114,8 @@ static ssize_t amdgpu_set_dpm_state(struct device *dev, | |||
118 | goto fail; | 114 | goto fail; |
119 | } | 115 | } |
120 | 116 | ||
121 | if (adev->pp_enabled) { | 117 | if (adev->powerplay.pp_funcs->dispatch_tasks) { |
122 | amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL); | 118 | amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_ENABLE_USER_STATE, &state, NULL); |
123 | } else { | 119 | } else { |
124 | mutex_lock(&adev->pm.mutex); | 120 | mutex_lock(&adev->pm.mutex); |
125 | adev->pm.dpm.user_state = state; | 121 | adev->pm.dpm.user_state = state; |
@@ -140,13 +136,17 @@ static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev, | |||
140 | { | 136 | { |
141 | struct drm_device *ddev = dev_get_drvdata(dev); | 137 | struct drm_device *ddev = dev_get_drvdata(dev); |
142 | struct amdgpu_device *adev = ddev->dev_private; | 138 | struct amdgpu_device *adev = ddev->dev_private; |
143 | enum amd_dpm_forced_level level; | 139 | enum amd_dpm_forced_level level = 0xff; |
144 | 140 | ||
145 | if ((adev->flags & AMD_IS_PX) && | 141 | if ((adev->flags & AMD_IS_PX) && |
146 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) | 142 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) |
147 | return snprintf(buf, PAGE_SIZE, "off\n"); | 143 | return snprintf(buf, PAGE_SIZE, "off\n"); |
148 | 144 | ||
149 | level = amdgpu_dpm_get_performance_level(adev); | 145 | if (adev->powerplay.pp_funcs->get_performance_level) |
146 | level = amdgpu_dpm_get_performance_level(adev); | ||
147 | else | ||
148 | level = adev->pm.dpm.forced_level; | ||
149 | |||
150 | return snprintf(buf, PAGE_SIZE, "%s\n", | 150 | return snprintf(buf, PAGE_SIZE, "%s\n", |
151 | (level == AMD_DPM_FORCED_LEVEL_AUTO) ? "auto" : | 151 | (level == AMD_DPM_FORCED_LEVEL_AUTO) ? "auto" : |
152 | (level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" : | 152 | (level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" : |
@@ -167,7 +167,7 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, | |||
167 | struct drm_device *ddev = dev_get_drvdata(dev); | 167 | struct drm_device *ddev = dev_get_drvdata(dev); |
168 | struct amdgpu_device *adev = ddev->dev_private; | 168 | struct amdgpu_device *adev = ddev->dev_private; |
169 | enum amd_dpm_forced_level level; | 169 | enum amd_dpm_forced_level level; |
170 | enum amd_dpm_forced_level current_level; | 170 | enum amd_dpm_forced_level current_level = 0xff; |
171 | int ret = 0; | 171 | int ret = 0; |
172 | 172 | ||
173 | /* Can't force performance level when the card is off */ | 173 | /* Can't force performance level when the card is off */ |
@@ -175,7 +175,8 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, | |||
175 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) | 175 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) |
176 | return -EINVAL; | 176 | return -EINVAL; |
177 | 177 | ||
178 | current_level = amdgpu_dpm_get_performance_level(adev); | 178 | if (adev->powerplay.pp_funcs->get_performance_level) |
179 | current_level = amdgpu_dpm_get_performance_level(adev); | ||
179 | 180 | ||
180 | if (strncmp("low", buf, strlen("low")) == 0) { | 181 | if (strncmp("low", buf, strlen("low")) == 0) { |
181 | level = AMD_DPM_FORCED_LEVEL_LOW; | 182 | level = AMD_DPM_FORCED_LEVEL_LOW; |
@@ -203,9 +204,7 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, | |||
203 | if (current_level == level) | 204 | if (current_level == level) |
204 | return count; | 205 | return count; |
205 | 206 | ||
206 | if (adev->pp_enabled) | 207 | if (adev->powerplay.pp_funcs->force_performance_level) { |
207 | amdgpu_dpm_force_performance_level(adev, level); | ||
208 | else { | ||
209 | mutex_lock(&adev->pm.mutex); | 208 | mutex_lock(&adev->pm.mutex); |
210 | if (adev->pm.dpm.thermal_active) { | 209 | if (adev->pm.dpm.thermal_active) { |
211 | count = -EINVAL; | 210 | count = -EINVAL; |
@@ -233,7 +232,7 @@ static ssize_t amdgpu_get_pp_num_states(struct device *dev, | |||
233 | struct pp_states_info data; | 232 | struct pp_states_info data; |
234 | int i, buf_len; | 233 | int i, buf_len; |
235 | 234 | ||
236 | if (adev->pp_enabled) | 235 | if (adev->powerplay.pp_funcs->get_pp_num_states) |
237 | amdgpu_dpm_get_pp_num_states(adev, &data); | 236 | amdgpu_dpm_get_pp_num_states(adev, &data); |
238 | 237 | ||
239 | buf_len = snprintf(buf, PAGE_SIZE, "states: %d\n", data.nums); | 238 | buf_len = snprintf(buf, PAGE_SIZE, "states: %d\n", data.nums); |
@@ -257,8 +256,8 @@ static ssize_t amdgpu_get_pp_cur_state(struct device *dev, | |||
257 | enum amd_pm_state_type pm = 0; | 256 | enum amd_pm_state_type pm = 0; |
258 | int i = 0; | 257 | int i = 0; |
259 | 258 | ||
260 | if (adev->pp_enabled) { | 259 | if (adev->powerplay.pp_funcs->get_current_power_state |
261 | 260 | && adev->powerplay.pp_funcs->get_pp_num_states) { | |
262 | pm = amdgpu_dpm_get_current_power_state(adev); | 261 | pm = amdgpu_dpm_get_current_power_state(adev); |
263 | amdgpu_dpm_get_pp_num_states(adev, &data); | 262 | amdgpu_dpm_get_pp_num_states(adev, &data); |
264 | 263 | ||
@@ -280,25 +279,10 @@ static ssize_t amdgpu_get_pp_force_state(struct device *dev, | |||
280 | { | 279 | { |
281 | struct drm_device *ddev = dev_get_drvdata(dev); | 280 | struct drm_device *ddev = dev_get_drvdata(dev); |
282 | struct amdgpu_device *adev = ddev->dev_private; | 281 | struct amdgpu_device *adev = ddev->dev_private; |
283 | struct pp_states_info data; | ||
284 | enum amd_pm_state_type pm = 0; | ||
285 | int i; | ||
286 | |||
287 | if (adev->pp_force_state_enabled && adev->pp_enabled) { | ||
288 | pm = amdgpu_dpm_get_current_power_state(adev); | ||
289 | amdgpu_dpm_get_pp_num_states(adev, &data); | ||
290 | 282 | ||
291 | for (i = 0; i < data.nums; i++) { | 283 | if (adev->pp_force_state_enabled) |
292 | if (pm == data.states[i]) | 284 | return amdgpu_get_pp_cur_state(dev, attr, buf); |
293 | break; | 285 | else |
294 | } | ||
295 | |||
296 | if (i == data.nums) | ||
297 | i = -EINVAL; | ||
298 | |||
299 | return snprintf(buf, PAGE_SIZE, "%d\n", i); | ||
300 | |||
301 | } else | ||
302 | return snprintf(buf, PAGE_SIZE, "\n"); | 286 | return snprintf(buf, PAGE_SIZE, "\n"); |
303 | } | 287 | } |
304 | 288 | ||
@@ -315,7 +299,8 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev, | |||
315 | 299 | ||
316 | if (strlen(buf) == 1) | 300 | if (strlen(buf) == 1) |
317 | adev->pp_force_state_enabled = false; | 301 | adev->pp_force_state_enabled = false; |
318 | else if (adev->pp_enabled) { | 302 | else if (adev->powerplay.pp_funcs->dispatch_tasks && |
303 | adev->powerplay.pp_funcs->get_pp_num_states) { | ||
319 | struct pp_states_info data; | 304 | struct pp_states_info data; |
320 | 305 | ||
321 | ret = kstrtoul(buf, 0, &idx); | 306 | ret = kstrtoul(buf, 0, &idx); |
@@ -330,7 +315,7 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev, | |||
330 | if (state != POWER_STATE_TYPE_INTERNAL_BOOT && | 315 | if (state != POWER_STATE_TYPE_INTERNAL_BOOT && |
331 | state != POWER_STATE_TYPE_DEFAULT) { | 316 | state != POWER_STATE_TYPE_DEFAULT) { |
332 | amdgpu_dpm_dispatch_task(adev, | 317 | amdgpu_dpm_dispatch_task(adev, |
333 | AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL); | 318 | AMD_PP_TASK_ENABLE_USER_STATE, &state, NULL); |
334 | adev->pp_force_state_enabled = true; | 319 | adev->pp_force_state_enabled = true; |
335 | } | 320 | } |
336 | } | 321 | } |
@@ -347,7 +332,7 @@ static ssize_t amdgpu_get_pp_table(struct device *dev, | |||
347 | char *table = NULL; | 332 | char *table = NULL; |
348 | int size; | 333 | int size; |
349 | 334 | ||
350 | if (adev->pp_enabled) | 335 | if (adev->powerplay.pp_funcs->get_pp_table) |
351 | size = amdgpu_dpm_get_pp_table(adev, &table); | 336 | size = amdgpu_dpm_get_pp_table(adev, &table); |
352 | else | 337 | else |
353 | return 0; | 338 | return 0; |
@@ -368,7 +353,7 @@ static ssize_t amdgpu_set_pp_table(struct device *dev, | |||
368 | struct drm_device *ddev = dev_get_drvdata(dev); | 353 | struct drm_device *ddev = dev_get_drvdata(dev); |
369 | struct amdgpu_device *adev = ddev->dev_private; | 354 | struct amdgpu_device *adev = ddev->dev_private; |
370 | 355 | ||
371 | if (adev->pp_enabled) | 356 | if (adev->powerplay.pp_funcs->set_pp_table) |
372 | amdgpu_dpm_set_pp_table(adev, buf, count); | 357 | amdgpu_dpm_set_pp_table(adev, buf, count); |
373 | 358 | ||
374 | return count; | 359 | return count; |
@@ -380,14 +365,11 @@ static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev, | |||
380 | { | 365 | { |
381 | struct drm_device *ddev = dev_get_drvdata(dev); | 366 | struct drm_device *ddev = dev_get_drvdata(dev); |
382 | struct amdgpu_device *adev = ddev->dev_private; | 367 | struct amdgpu_device *adev = ddev->dev_private; |
383 | ssize_t size = 0; | ||
384 | |||
385 | if (adev->pp_enabled) | ||
386 | size = amdgpu_dpm_print_clock_levels(adev, PP_SCLK, buf); | ||
387 | else if (adev->pm.funcs->print_clock_levels) | ||
388 | size = adev->pm.funcs->print_clock_levels(adev, PP_SCLK, buf); | ||
389 | 368 | ||
390 | return size; | 369 | if (adev->powerplay.pp_funcs->print_clock_levels) |
370 | return amdgpu_dpm_print_clock_levels(adev, PP_SCLK, buf); | ||
371 | else | ||
372 | return snprintf(buf, PAGE_SIZE, "\n"); | ||
391 | } | 373 | } |
392 | 374 | ||
393 | static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev, | 375 | static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev, |
@@ -416,10 +398,9 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev, | |||
416 | mask |= 1 << level; | 398 | mask |= 1 << level; |
417 | } | 399 | } |
418 | 400 | ||
419 | if (adev->pp_enabled) | 401 | if (adev->powerplay.pp_funcs->force_clock_level) |
420 | amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask); | 402 | amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask); |
421 | else if (adev->pm.funcs->force_clock_level) | 403 | |
422 | adev->pm.funcs->force_clock_level(adev, PP_SCLK, mask); | ||
423 | fail: | 404 | fail: |
424 | return count; | 405 | return count; |
425 | } | 406 | } |
@@ -430,14 +411,11 @@ static ssize_t amdgpu_get_pp_dpm_mclk(struct device *dev, | |||
430 | { | 411 | { |
431 | struct drm_device *ddev = dev_get_drvdata(dev); | 412 | struct drm_device *ddev = dev_get_drvdata(dev); |
432 | struct amdgpu_device *adev = ddev->dev_private; | 413 | struct amdgpu_device *adev = ddev->dev_private; |
433 | ssize_t size = 0; | ||
434 | |||
435 | if (adev->pp_enabled) | ||
436 | size = amdgpu_dpm_print_clock_levels(adev, PP_MCLK, buf); | ||
437 | else if (adev->pm.funcs->print_clock_levels) | ||
438 | size = adev->pm.funcs->print_clock_levels(adev, PP_MCLK, buf); | ||
439 | 414 | ||
440 | return size; | 415 | if (adev->powerplay.pp_funcs->print_clock_levels) |
416 | return amdgpu_dpm_print_clock_levels(adev, PP_MCLK, buf); | ||
417 | else | ||
418 | return snprintf(buf, PAGE_SIZE, "\n"); | ||
441 | } | 419 | } |
442 | 420 | ||
443 | static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev, | 421 | static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev, |
@@ -465,11 +443,9 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev, | |||
465 | } | 443 | } |
466 | mask |= 1 << level; | 444 | mask |= 1 << level; |
467 | } | 445 | } |
468 | 446 | if (adev->powerplay.pp_funcs->force_clock_level) | |
469 | if (adev->pp_enabled) | ||
470 | amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask); | 447 | amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask); |
471 | else if (adev->pm.funcs->force_clock_level) | 448 | |
472 | adev->pm.funcs->force_clock_level(adev, PP_MCLK, mask); | ||
473 | fail: | 449 | fail: |
474 | return count; | 450 | return count; |
475 | } | 451 | } |
@@ -480,14 +456,11 @@ static ssize_t amdgpu_get_pp_dpm_pcie(struct device *dev, | |||
480 | { | 456 | { |
481 | struct drm_device *ddev = dev_get_drvdata(dev); | 457 | struct drm_device *ddev = dev_get_drvdata(dev); |
482 | struct amdgpu_device *adev = ddev->dev_private; | 458 | struct amdgpu_device *adev = ddev->dev_private; |
483 | ssize_t size = 0; | ||
484 | |||
485 | if (adev->pp_enabled) | ||
486 | size = amdgpu_dpm_print_clock_levels(adev, PP_PCIE, buf); | ||
487 | else if (adev->pm.funcs->print_clock_levels) | ||
488 | size = adev->pm.funcs->print_clock_levels(adev, PP_PCIE, buf); | ||
489 | 459 | ||
490 | return size; | 460 | if (adev->powerplay.pp_funcs->print_clock_levels) |
461 | return amdgpu_dpm_print_clock_levels(adev, PP_PCIE, buf); | ||
462 | else | ||
463 | return snprintf(buf, PAGE_SIZE, "\n"); | ||
491 | } | 464 | } |
492 | 465 | ||
493 | static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev, | 466 | static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev, |
@@ -515,11 +488,9 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev, | |||
515 | } | 488 | } |
516 | mask |= 1 << level; | 489 | mask |= 1 << level; |
517 | } | 490 | } |
518 | 491 | if (adev->powerplay.pp_funcs->force_clock_level) | |
519 | if (adev->pp_enabled) | ||
520 | amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask); | 492 | amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask); |
521 | else if (adev->pm.funcs->force_clock_level) | 493 | |
522 | adev->pm.funcs->force_clock_level(adev, PP_PCIE, mask); | ||
523 | fail: | 494 | fail: |
524 | return count; | 495 | return count; |
525 | } | 496 | } |
@@ -532,10 +503,8 @@ static ssize_t amdgpu_get_pp_sclk_od(struct device *dev, | |||
532 | struct amdgpu_device *adev = ddev->dev_private; | 503 | struct amdgpu_device *adev = ddev->dev_private; |
533 | uint32_t value = 0; | 504 | uint32_t value = 0; |
534 | 505 | ||
535 | if (adev->pp_enabled) | 506 | if (adev->powerplay.pp_funcs->get_sclk_od) |
536 | value = amdgpu_dpm_get_sclk_od(adev); | 507 | value = amdgpu_dpm_get_sclk_od(adev); |
537 | else if (adev->pm.funcs->get_sclk_od) | ||
538 | value = adev->pm.funcs->get_sclk_od(adev); | ||
539 | 508 | ||
540 | return snprintf(buf, PAGE_SIZE, "%d\n", value); | 509 | return snprintf(buf, PAGE_SIZE, "%d\n", value); |
541 | } | 510 | } |
@@ -556,12 +525,12 @@ static ssize_t amdgpu_set_pp_sclk_od(struct device *dev, | |||
556 | count = -EINVAL; | 525 | count = -EINVAL; |
557 | goto fail; | 526 | goto fail; |
558 | } | 527 | } |
559 | 528 | if (adev->powerplay.pp_funcs->set_sclk_od) | |
560 | if (adev->pp_enabled) { | ||
561 | amdgpu_dpm_set_sclk_od(adev, (uint32_t)value); | 529 | amdgpu_dpm_set_sclk_od(adev, (uint32_t)value); |
562 | amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_READJUST_POWER_STATE, NULL, NULL); | 530 | |
563 | } else if (adev->pm.funcs->set_sclk_od) { | 531 | if (adev->powerplay.pp_funcs->dispatch_tasks) { |
564 | adev->pm.funcs->set_sclk_od(adev, (uint32_t)value); | 532 | amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_READJUST_POWER_STATE, NULL, NULL); |
533 | } else { | ||
565 | adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps; | 534 | adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps; |
566 | amdgpu_pm_compute_clocks(adev); | 535 | amdgpu_pm_compute_clocks(adev); |
567 | } | 536 | } |
@@ -578,10 +547,8 @@ static ssize_t amdgpu_get_pp_mclk_od(struct device *dev, | |||
578 | struct amdgpu_device *adev = ddev->dev_private; | 547 | struct amdgpu_device *adev = ddev->dev_private; |
579 | uint32_t value = 0; | 548 | uint32_t value = 0; |
580 | 549 | ||
581 | if (adev->pp_enabled) | 550 | if (adev->powerplay.pp_funcs->get_mclk_od) |
582 | value = amdgpu_dpm_get_mclk_od(adev); | 551 | value = amdgpu_dpm_get_mclk_od(adev); |
583 | else if (adev->pm.funcs->get_mclk_od) | ||
584 | value = adev->pm.funcs->get_mclk_od(adev); | ||
585 | 552 | ||
586 | return snprintf(buf, PAGE_SIZE, "%d\n", value); | 553 | return snprintf(buf, PAGE_SIZE, "%d\n", value); |
587 | } | 554 | } |
@@ -602,12 +569,12 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev, | |||
602 | count = -EINVAL; | 569 | count = -EINVAL; |
603 | goto fail; | 570 | goto fail; |
604 | } | 571 | } |
605 | 572 | if (adev->powerplay.pp_funcs->set_mclk_od) | |
606 | if (adev->pp_enabled) { | ||
607 | amdgpu_dpm_set_mclk_od(adev, (uint32_t)value); | 573 | amdgpu_dpm_set_mclk_od(adev, (uint32_t)value); |
608 | amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_READJUST_POWER_STATE, NULL, NULL); | 574 | |
609 | } else if (adev->pm.funcs->set_mclk_od) { | 575 | if (adev->powerplay.pp_funcs->dispatch_tasks) { |
610 | adev->pm.funcs->set_mclk_od(adev, (uint32_t)value); | 576 | amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_READJUST_POWER_STATE, NULL, NULL); |
577 | } else { | ||
611 | adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps; | 578 | adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps; |
612 | amdgpu_pm_compute_clocks(adev); | 579 | amdgpu_pm_compute_clocks(adev); |
613 | } | 580 | } |
@@ -621,14 +588,11 @@ static ssize_t amdgpu_get_pp_power_profile(struct device *dev, | |||
621 | { | 588 | { |
622 | struct drm_device *ddev = dev_get_drvdata(dev); | 589 | struct drm_device *ddev = dev_get_drvdata(dev); |
623 | struct amdgpu_device *adev = ddev->dev_private; | 590 | struct amdgpu_device *adev = ddev->dev_private; |
624 | int ret = 0; | 591 | int ret = 0xff; |
625 | 592 | ||
626 | if (adev->pp_enabled) | 593 | if (adev->powerplay.pp_funcs->get_power_profile_state) |
627 | ret = amdgpu_dpm_get_power_profile_state( | 594 | ret = amdgpu_dpm_get_power_profile_state( |
628 | adev, query); | 595 | adev, query); |
629 | else if (adev->pm.funcs->get_power_profile_state) | ||
630 | ret = adev->pm.funcs->get_power_profile_state( | ||
631 | adev, query); | ||
632 | 596 | ||
633 | if (ret) | 597 | if (ret) |
634 | return ret; | 598 | return ret; |
@@ -675,15 +639,12 @@ static ssize_t amdgpu_set_pp_power_profile(struct device *dev, | |||
675 | char *sub_str, buf_cpy[128], *tmp_str; | 639 | char *sub_str, buf_cpy[128], *tmp_str; |
676 | const char delimiter[3] = {' ', '\n', '\0'}; | 640 | const char delimiter[3] = {' ', '\n', '\0'}; |
677 | long int value; | 641 | long int value; |
678 | int ret = 0; | 642 | int ret = 0xff; |
679 | 643 | ||
680 | if (strncmp("reset", buf, strlen("reset")) == 0) { | 644 | if (strncmp("reset", buf, strlen("reset")) == 0) { |
681 | if (adev->pp_enabled) | 645 | if (adev->powerplay.pp_funcs->reset_power_profile_state) |
682 | ret = amdgpu_dpm_reset_power_profile_state( | 646 | ret = amdgpu_dpm_reset_power_profile_state( |
683 | adev, request); | 647 | adev, request); |
684 | else if (adev->pm.funcs->reset_power_profile_state) | ||
685 | ret = adev->pm.funcs->reset_power_profile_state( | ||
686 | adev, request); | ||
687 | if (ret) { | 648 | if (ret) { |
688 | count = -EINVAL; | 649 | count = -EINVAL; |
689 | goto fail; | 650 | goto fail; |
@@ -692,12 +653,10 @@ static ssize_t amdgpu_set_pp_power_profile(struct device *dev, | |||
692 | } | 653 | } |
693 | 654 | ||
694 | if (strncmp("set", buf, strlen("set")) == 0) { | 655 | if (strncmp("set", buf, strlen("set")) == 0) { |
695 | if (adev->pp_enabled) | 656 | if (adev->powerplay.pp_funcs->set_power_profile_state) |
696 | ret = amdgpu_dpm_set_power_profile_state( | 657 | ret = amdgpu_dpm_set_power_profile_state( |
697 | adev, request); | 658 | adev, request); |
698 | else if (adev->pm.funcs->set_power_profile_state) | 659 | |
699 | ret = adev->pm.funcs->set_power_profile_state( | ||
700 | adev, request); | ||
701 | if (ret) { | 660 | if (ret) { |
702 | count = -EINVAL; | 661 | count = -EINVAL; |
703 | goto fail; | 662 | goto fail; |
@@ -745,13 +704,8 @@ static ssize_t amdgpu_set_pp_power_profile(struct device *dev, | |||
745 | 704 | ||
746 | loop++; | 705 | loop++; |
747 | } | 706 | } |
748 | 707 | if (adev->powerplay.pp_funcs->set_power_profile_state) | |
749 | if (adev->pp_enabled) | 708 | ret = amdgpu_dpm_set_power_profile_state(adev, request); |
750 | ret = amdgpu_dpm_set_power_profile_state( | ||
751 | adev, request); | ||
752 | else if (adev->pm.funcs->set_power_profile_state) | ||
753 | ret = adev->pm.funcs->set_power_profile_state( | ||
754 | adev, request); | ||
755 | 709 | ||
756 | if (ret) | 710 | if (ret) |
757 | count = -EINVAL; | 711 | count = -EINVAL; |
@@ -831,7 +785,7 @@ static ssize_t amdgpu_hwmon_show_temp(struct device *dev, | |||
831 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) | 785 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) |
832 | return -EINVAL; | 786 | return -EINVAL; |
833 | 787 | ||
834 | if (!adev->pp_enabled && !adev->pm.funcs->get_temperature) | 788 | if (!adev->powerplay.pp_funcs->get_temperature) |
835 | temp = 0; | 789 | temp = 0; |
836 | else | 790 | else |
837 | temp = amdgpu_dpm_get_temperature(adev); | 791 | temp = amdgpu_dpm_get_temperature(adev); |
@@ -862,7 +816,7 @@ static ssize_t amdgpu_hwmon_get_pwm1_enable(struct device *dev, | |||
862 | struct amdgpu_device *adev = dev_get_drvdata(dev); | 816 | struct amdgpu_device *adev = dev_get_drvdata(dev); |
863 | u32 pwm_mode = 0; | 817 | u32 pwm_mode = 0; |
864 | 818 | ||
865 | if (!adev->pp_enabled && !adev->pm.funcs->get_fan_control_mode) | 819 | if (!adev->powerplay.pp_funcs->get_fan_control_mode) |
866 | return -EINVAL; | 820 | return -EINVAL; |
867 | 821 | ||
868 | pwm_mode = amdgpu_dpm_get_fan_control_mode(adev); | 822 | pwm_mode = amdgpu_dpm_get_fan_control_mode(adev); |
@@ -879,7 +833,7 @@ static ssize_t amdgpu_hwmon_set_pwm1_enable(struct device *dev, | |||
879 | int err; | 833 | int err; |
880 | int value; | 834 | int value; |
881 | 835 | ||
882 | if (!adev->pp_enabled && !adev->pm.funcs->set_fan_control_mode) | 836 | if (!adev->powerplay.pp_funcs->set_fan_control_mode) |
883 | return -EINVAL; | 837 | return -EINVAL; |
884 | 838 | ||
885 | err = kstrtoint(buf, 10, &value); | 839 | err = kstrtoint(buf, 10, &value); |
@@ -919,9 +873,11 @@ static ssize_t amdgpu_hwmon_set_pwm1(struct device *dev, | |||
919 | 873 | ||
920 | value = (value * 100) / 255; | 874 | value = (value * 100) / 255; |
921 | 875 | ||
922 | err = amdgpu_dpm_set_fan_speed_percent(adev, value); | 876 | if (adev->powerplay.pp_funcs->set_fan_speed_percent) { |
923 | if (err) | 877 | err = amdgpu_dpm_set_fan_speed_percent(adev, value); |
924 | return err; | 878 | if (err) |
879 | return err; | ||
880 | } | ||
925 | 881 | ||
926 | return count; | 882 | return count; |
927 | } | 883 | } |
@@ -932,11 +888,13 @@ static ssize_t amdgpu_hwmon_get_pwm1(struct device *dev, | |||
932 | { | 888 | { |
933 | struct amdgpu_device *adev = dev_get_drvdata(dev); | 889 | struct amdgpu_device *adev = dev_get_drvdata(dev); |
934 | int err; | 890 | int err; |
935 | u32 speed; | 891 | u32 speed = 0; |
936 | 892 | ||
937 | err = amdgpu_dpm_get_fan_speed_percent(adev, &speed); | 893 | if (adev->powerplay.pp_funcs->get_fan_speed_percent) { |
938 | if (err) | 894 | err = amdgpu_dpm_get_fan_speed_percent(adev, &speed); |
939 | return err; | 895 | if (err) |
896 | return err; | ||
897 | } | ||
940 | 898 | ||
941 | speed = (speed * 255) / 100; | 899 | speed = (speed * 255) / 100; |
942 | 900 | ||
@@ -949,11 +907,13 @@ static ssize_t amdgpu_hwmon_get_fan1_input(struct device *dev, | |||
949 | { | 907 | { |
950 | struct amdgpu_device *adev = dev_get_drvdata(dev); | 908 | struct amdgpu_device *adev = dev_get_drvdata(dev); |
951 | int err; | 909 | int err; |
952 | u32 speed; | 910 | u32 speed = 0; |
953 | 911 | ||
954 | err = amdgpu_dpm_get_fan_speed_rpm(adev, &speed); | 912 | if (adev->powerplay.pp_funcs->get_fan_speed_rpm) { |
955 | if (err) | 913 | err = amdgpu_dpm_get_fan_speed_rpm(adev, &speed); |
956 | return err; | 914 | if (err) |
915 | return err; | ||
916 | } | ||
957 | 917 | ||
958 | return sprintf(buf, "%i\n", speed); | 918 | return sprintf(buf, "%i\n", speed); |
959 | } | 919 | } |
@@ -986,6 +946,10 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, | |||
986 | struct amdgpu_device *adev = dev_get_drvdata(dev); | 946 | struct amdgpu_device *adev = dev_get_drvdata(dev); |
987 | umode_t effective_mode = attr->mode; | 947 | umode_t effective_mode = attr->mode; |
988 | 948 | ||
949 | /* no skipping for powerplay */ | ||
950 | if (adev->powerplay.cgs_device) | ||
951 | return effective_mode; | ||
952 | |||
989 | /* Skip limit attributes if DPM is not enabled */ | 953 | /* Skip limit attributes if DPM is not enabled */ |
990 | if (!adev->pm.dpm_enabled && | 954 | if (!adev->pm.dpm_enabled && |
991 | (attr == &sensor_dev_attr_temp1_crit.dev_attr.attr || | 955 | (attr == &sensor_dev_attr_temp1_crit.dev_attr.attr || |
@@ -996,9 +960,6 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, | |||
996 | attr == &sensor_dev_attr_pwm1_min.dev_attr.attr)) | 960 | attr == &sensor_dev_attr_pwm1_min.dev_attr.attr)) |
997 | return 0; | 961 | return 0; |
998 | 962 | ||
999 | if (adev->pp_enabled) | ||
1000 | return effective_mode; | ||
1001 | |||
1002 | /* Skip fan attributes if fan is not present */ | 963 | /* Skip fan attributes if fan is not present */ |
1003 | if (adev->pm.no_fan && | 964 | if (adev->pm.no_fan && |
1004 | (attr == &sensor_dev_attr_pwm1.dev_attr.attr || | 965 | (attr == &sensor_dev_attr_pwm1.dev_attr.attr || |
@@ -1008,21 +969,21 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, | |||
1008 | return 0; | 969 | return 0; |
1009 | 970 | ||
1010 | /* mask fan attributes if we have no bindings for this asic to expose */ | 971 | /* mask fan attributes if we have no bindings for this asic to expose */ |
1011 | if ((!adev->pm.funcs->get_fan_speed_percent && | 972 | if ((!adev->powerplay.pp_funcs->get_fan_speed_percent && |
1012 | attr == &sensor_dev_attr_pwm1.dev_attr.attr) || /* can't query fan */ | 973 | attr == &sensor_dev_attr_pwm1.dev_attr.attr) || /* can't query fan */ |
1013 | (!adev->pm.funcs->get_fan_control_mode && | 974 | (!adev->powerplay.pp_funcs->get_fan_control_mode && |
1014 | attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr)) /* can't query state */ | 975 | attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr)) /* can't query state */ |
1015 | effective_mode &= ~S_IRUGO; | 976 | effective_mode &= ~S_IRUGO; |
1016 | 977 | ||
1017 | if ((!adev->pm.funcs->set_fan_speed_percent && | 978 | if ((!adev->powerplay.pp_funcs->set_fan_speed_percent && |
1018 | attr == &sensor_dev_attr_pwm1.dev_attr.attr) || /* can't manage fan */ | 979 | attr == &sensor_dev_attr_pwm1.dev_attr.attr) || /* can't manage fan */ |
1019 | (!adev->pm.funcs->set_fan_control_mode && | 980 | (!adev->powerplay.pp_funcs->set_fan_control_mode && |
1020 | attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr)) /* can't manage state */ | 981 | attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr)) /* can't manage state */ |
1021 | effective_mode &= ~S_IWUSR; | 982 | effective_mode &= ~S_IWUSR; |
1022 | 983 | ||
1023 | /* hide max/min values if we can't both query and manage the fan */ | 984 | /* hide max/min values if we can't both query and manage the fan */ |
1024 | if ((!adev->pm.funcs->set_fan_speed_percent && | 985 | if ((!adev->powerplay.pp_funcs->set_fan_speed_percent && |
1025 | !adev->pm.funcs->get_fan_speed_percent) && | 986 | !adev->powerplay.pp_funcs->get_fan_speed_percent) && |
1026 | (attr == &sensor_dev_attr_pwm1_max.dev_attr.attr || | 987 | (attr == &sensor_dev_attr_pwm1_max.dev_attr.attr || |
1027 | attr == &sensor_dev_attr_pwm1_min.dev_attr.attr)) | 988 | attr == &sensor_dev_attr_pwm1_min.dev_attr.attr)) |
1028 | return 0; | 989 | return 0; |
@@ -1055,7 +1016,7 @@ void amdgpu_dpm_thermal_work_handler(struct work_struct *work) | |||
1055 | if (!adev->pm.dpm_enabled) | 1016 | if (!adev->pm.dpm_enabled) |
1056 | return; | 1017 | return; |
1057 | 1018 | ||
1058 | if (adev->pm.funcs->get_temperature) { | 1019 | if (adev->powerplay.pp_funcs->get_temperature) { |
1059 | int temp = amdgpu_dpm_get_temperature(adev); | 1020 | int temp = amdgpu_dpm_get_temperature(adev); |
1060 | 1021 | ||
1061 | if (temp < adev->pm.dpm.thermal.min_temp) | 1022 | if (temp < adev->pm.dpm.thermal.min_temp) |
@@ -1087,7 +1048,7 @@ static struct amdgpu_ps *amdgpu_dpm_pick_power_state(struct amdgpu_device *adev, | |||
1087 | true : false; | 1048 | true : false; |
1088 | 1049 | ||
1089 | /* check if the vblank period is too short to adjust the mclk */ | 1050 | /* check if the vblank period is too short to adjust the mclk */ |
1090 | if (single_display && adev->pm.funcs->vblank_too_short) { | 1051 | if (single_display && adev->powerplay.pp_funcs->vblank_too_short) { |
1091 | if (amdgpu_dpm_vblank_too_short(adev)) | 1052 | if (amdgpu_dpm_vblank_too_short(adev)) |
1092 | single_display = false; | 1053 | single_display = false; |
1093 | } | 1054 | } |
@@ -1216,7 +1177,7 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev) | |||
1216 | struct amdgpu_ps *ps; | 1177 | struct amdgpu_ps *ps; |
1217 | enum amd_pm_state_type dpm_state; | 1178 | enum amd_pm_state_type dpm_state; |
1218 | int ret; | 1179 | int ret; |
1219 | bool equal; | 1180 | bool equal = false; |
1220 | 1181 | ||
1221 | /* if dpm init failed */ | 1182 | /* if dpm init failed */ |
1222 | if (!adev->pm.dpm_enabled) | 1183 | if (!adev->pm.dpm_enabled) |
@@ -1236,7 +1197,7 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev) | |||
1236 | else | 1197 | else |
1237 | return; | 1198 | return; |
1238 | 1199 | ||
1239 | if (amdgpu_dpm == 1) { | 1200 | if (amdgpu_dpm == 1 && adev->powerplay.pp_funcs->print_power_state) { |
1240 | printk("switching from power state:\n"); | 1201 | printk("switching from power state:\n"); |
1241 | amdgpu_dpm_print_power_state(adev, adev->pm.dpm.current_ps); | 1202 | amdgpu_dpm_print_power_state(adev, adev->pm.dpm.current_ps); |
1242 | printk("switching to power state:\n"); | 1203 | printk("switching to power state:\n"); |
@@ -1245,15 +1206,17 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev) | |||
1245 | 1206 | ||
1246 | /* update whether vce is active */ | 1207 | /* update whether vce is active */ |
1247 | ps->vce_active = adev->pm.dpm.vce_active; | 1208 | ps->vce_active = adev->pm.dpm.vce_active; |
1248 | 1209 | if (adev->powerplay.pp_funcs->display_configuration_changed) | |
1249 | amdgpu_dpm_display_configuration_changed(adev); | 1210 | amdgpu_dpm_display_configuration_changed(adev); |
1250 | 1211 | ||
1251 | ret = amdgpu_dpm_pre_set_power_state(adev); | 1212 | ret = amdgpu_dpm_pre_set_power_state(adev); |
1252 | if (ret) | 1213 | if (ret) |
1253 | return; | 1214 | return; |
1254 | 1215 | ||
1255 | if ((0 != amgdpu_dpm_check_state_equal(adev, adev->pm.dpm.current_ps, adev->pm.dpm.requested_ps, &equal))) | 1216 | if (adev->powerplay.pp_funcs->check_state_equal) { |
1256 | equal = false; | 1217 | if (0 != amdgpu_dpm_check_state_equal(adev, adev->pm.dpm.current_ps, adev->pm.dpm.requested_ps, &equal)) |
1218 | equal = false; | ||
1219 | } | ||
1257 | 1220 | ||
1258 | if (equal) | 1221 | if (equal) |
1259 | return; | 1222 | return; |
@@ -1264,7 +1227,7 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev) | |||
1264 | adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs; | 1227 | adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs; |
1265 | adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count; | 1228 | adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count; |
1266 | 1229 | ||
1267 | if (adev->pm.funcs->force_performance_level) { | 1230 | if (adev->powerplay.pp_funcs->force_performance_level) { |
1268 | if (adev->pm.dpm.thermal_active) { | 1231 | if (adev->pm.dpm.thermal_active) { |
1269 | enum amd_dpm_forced_level level = adev->pm.dpm.forced_level; | 1232 | enum amd_dpm_forced_level level = adev->pm.dpm.forced_level; |
1270 | /* force low perf level for thermal */ | 1233 | /* force low perf level for thermal */ |
@@ -1280,7 +1243,7 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev) | |||
1280 | 1243 | ||
1281 | void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable) | 1244 | void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable) |
1282 | { | 1245 | { |
1283 | if (adev->pp_enabled || adev->pm.funcs->powergate_uvd) { | 1246 | if (adev->powerplay.pp_funcs->powergate_uvd) { |
1284 | /* enable/disable UVD */ | 1247 | /* enable/disable UVD */ |
1285 | mutex_lock(&adev->pm.mutex); | 1248 | mutex_lock(&adev->pm.mutex); |
1286 | amdgpu_dpm_powergate_uvd(adev, !enable); | 1249 | amdgpu_dpm_powergate_uvd(adev, !enable); |
@@ -1302,7 +1265,7 @@ void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable) | |||
1302 | 1265 | ||
1303 | void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable) | 1266 | void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable) |
1304 | { | 1267 | { |
1305 | if (adev->pp_enabled || adev->pm.funcs->powergate_vce) { | 1268 | if (adev->powerplay.pp_funcs->powergate_vce) { |
1306 | /* enable/disable VCE */ | 1269 | /* enable/disable VCE */ |
1307 | mutex_lock(&adev->pm.mutex); | 1270 | mutex_lock(&adev->pm.mutex); |
1308 | amdgpu_dpm_powergate_vce(adev, !enable); | 1271 | amdgpu_dpm_powergate_vce(adev, !enable); |
@@ -1337,8 +1300,7 @@ void amdgpu_pm_print_power_states(struct amdgpu_device *adev) | |||
1337 | { | 1300 | { |
1338 | int i; | 1301 | int i; |
1339 | 1302 | ||
1340 | if (adev->pp_enabled) | 1303 | if (adev->powerplay.pp_funcs->print_power_state == NULL) |
1341 | /* TO DO */ | ||
1342 | return; | 1304 | return; |
1343 | 1305 | ||
1344 | for (i = 0; i < adev->pm.dpm.num_ps; i++) | 1306 | for (i = 0; i < adev->pm.dpm.num_ps; i++) |
@@ -1353,10 +1315,11 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) | |||
1353 | if (adev->pm.sysfs_initialized) | 1315 | if (adev->pm.sysfs_initialized) |
1354 | return 0; | 1316 | return 0; |
1355 | 1317 | ||
1356 | if (!adev->pp_enabled) { | 1318 | if (adev->pm.dpm_enabled == 0) |
1357 | if (adev->pm.funcs->get_temperature == NULL) | 1319 | return 0; |
1358 | return 0; | 1320 | |
1359 | } | 1321 | if (adev->powerplay.pp_funcs->get_temperature == NULL) |
1322 | return 0; | ||
1360 | 1323 | ||
1361 | adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev, | 1324 | adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev, |
1362 | DRIVER_NAME, adev, | 1325 | DRIVER_NAME, adev, |
@@ -1379,27 +1342,26 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) | |||
1379 | return ret; | 1342 | return ret; |
1380 | } | 1343 | } |
1381 | 1344 | ||
1382 | if (adev->pp_enabled) { | 1345 | |
1383 | ret = device_create_file(adev->dev, &dev_attr_pp_num_states); | 1346 | ret = device_create_file(adev->dev, &dev_attr_pp_num_states); |
1384 | if (ret) { | 1347 | if (ret) { |
1385 | DRM_ERROR("failed to create device file pp_num_states\n"); | 1348 | DRM_ERROR("failed to create device file pp_num_states\n"); |
1386 | return ret; | 1349 | return ret; |
1387 | } | 1350 | } |
1388 | ret = device_create_file(adev->dev, &dev_attr_pp_cur_state); | 1351 | ret = device_create_file(adev->dev, &dev_attr_pp_cur_state); |
1389 | if (ret) { | 1352 | if (ret) { |
1390 | DRM_ERROR("failed to create device file pp_cur_state\n"); | 1353 | DRM_ERROR("failed to create device file pp_cur_state\n"); |
1391 | return ret; | 1354 | return ret; |
1392 | } | 1355 | } |
1393 | ret = device_create_file(adev->dev, &dev_attr_pp_force_state); | 1356 | ret = device_create_file(adev->dev, &dev_attr_pp_force_state); |
1394 | if (ret) { | 1357 | if (ret) { |
1395 | DRM_ERROR("failed to create device file pp_force_state\n"); | 1358 | DRM_ERROR("failed to create device file pp_force_state\n"); |
1396 | return ret; | 1359 | return ret; |
1397 | } | 1360 | } |
1398 | ret = device_create_file(adev->dev, &dev_attr_pp_table); | 1361 | ret = device_create_file(adev->dev, &dev_attr_pp_table); |
1399 | if (ret) { | 1362 | if (ret) { |
1400 | DRM_ERROR("failed to create device file pp_table\n"); | 1363 | DRM_ERROR("failed to create device file pp_table\n"); |
1401 | return ret; | 1364 | return ret; |
1402 | } | ||
1403 | } | 1365 | } |
1404 | 1366 | ||
1405 | ret = device_create_file(adev->dev, &dev_attr_pp_dpm_sclk); | 1367 | ret = device_create_file(adev->dev, &dev_attr_pp_dpm_sclk); |
@@ -1455,16 +1417,19 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) | |||
1455 | 1417 | ||
1456 | void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev) | 1418 | void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev) |
1457 | { | 1419 | { |
1420 | if (adev->pm.dpm_enabled == 0) | ||
1421 | return; | ||
1422 | |||
1458 | if (adev->pm.int_hwmon_dev) | 1423 | if (adev->pm.int_hwmon_dev) |
1459 | hwmon_device_unregister(adev->pm.int_hwmon_dev); | 1424 | hwmon_device_unregister(adev->pm.int_hwmon_dev); |
1460 | device_remove_file(adev->dev, &dev_attr_power_dpm_state); | 1425 | device_remove_file(adev->dev, &dev_attr_power_dpm_state); |
1461 | device_remove_file(adev->dev, &dev_attr_power_dpm_force_performance_level); | 1426 | device_remove_file(adev->dev, &dev_attr_power_dpm_force_performance_level); |
1462 | if (adev->pp_enabled) { | 1427 | |
1463 | device_remove_file(adev->dev, &dev_attr_pp_num_states); | 1428 | device_remove_file(adev->dev, &dev_attr_pp_num_states); |
1464 | device_remove_file(adev->dev, &dev_attr_pp_cur_state); | 1429 | device_remove_file(adev->dev, &dev_attr_pp_cur_state); |
1465 | device_remove_file(adev->dev, &dev_attr_pp_force_state); | 1430 | device_remove_file(adev->dev, &dev_attr_pp_force_state); |
1466 | device_remove_file(adev->dev, &dev_attr_pp_table); | 1431 | device_remove_file(adev->dev, &dev_attr_pp_table); |
1467 | } | 1432 | |
1468 | device_remove_file(adev->dev, &dev_attr_pp_dpm_sclk); | 1433 | device_remove_file(adev->dev, &dev_attr_pp_dpm_sclk); |
1469 | device_remove_file(adev->dev, &dev_attr_pp_dpm_mclk); | 1434 | device_remove_file(adev->dev, &dev_attr_pp_dpm_mclk); |
1470 | device_remove_file(adev->dev, &dev_attr_pp_dpm_pcie); | 1435 | device_remove_file(adev->dev, &dev_attr_pp_dpm_pcie); |
@@ -1495,8 +1460,8 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) | |||
1495 | amdgpu_fence_wait_empty(ring); | 1460 | amdgpu_fence_wait_empty(ring); |
1496 | } | 1461 | } |
1497 | 1462 | ||
1498 | if (adev->pp_enabled) { | 1463 | if (adev->powerplay.pp_funcs->dispatch_tasks) { |
1499 | amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE, NULL, NULL); | 1464 | amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_DISPLAY_CONFIG_CHANGE, NULL, NULL); |
1500 | } else { | 1465 | } else { |
1501 | mutex_lock(&adev->pm.mutex); | 1466 | mutex_lock(&adev->pm.mutex); |
1502 | adev->pm.dpm.new_active_crtcs = 0; | 1467 | adev->pm.dpm.new_active_crtcs = 0; |
@@ -1505,7 +1470,7 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) | |||
1505 | list_for_each_entry(crtc, | 1470 | list_for_each_entry(crtc, |
1506 | &ddev->mode_config.crtc_list, head) { | 1471 | &ddev->mode_config.crtc_list, head) { |
1507 | amdgpu_crtc = to_amdgpu_crtc(crtc); | 1472 | amdgpu_crtc = to_amdgpu_crtc(crtc); |
1508 | if (crtc->enabled) { | 1473 | if (amdgpu_crtc->enabled) { |
1509 | adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id); | 1474 | adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id); |
1510 | adev->pm.dpm.new_active_crtc_count++; | 1475 | adev->pm.dpm.new_active_crtc_count++; |
1511 | } | 1476 | } |
@@ -1630,15 +1595,15 @@ static int amdgpu_debugfs_pm_info(struct seq_file *m, void *data) | |||
1630 | if ((adev->flags & AMD_IS_PX) && | 1595 | if ((adev->flags & AMD_IS_PX) && |
1631 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) { | 1596 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) { |
1632 | seq_printf(m, "PX asic powered off\n"); | 1597 | seq_printf(m, "PX asic powered off\n"); |
1633 | } else if (adev->pp_enabled) { | 1598 | } else if (adev->powerplay.pp_funcs->debugfs_print_current_performance_level) { |
1634 | return amdgpu_debugfs_pm_info_pp(m, adev); | ||
1635 | } else { | ||
1636 | mutex_lock(&adev->pm.mutex); | 1599 | mutex_lock(&adev->pm.mutex); |
1637 | if (adev->pm.funcs->debugfs_print_current_performance_level) | 1600 | if (adev->powerplay.pp_funcs->debugfs_print_current_performance_level) |
1638 | adev->pm.funcs->debugfs_print_current_performance_level(adev, m); | 1601 | adev->powerplay.pp_funcs->debugfs_print_current_performance_level(adev, m); |
1639 | else | 1602 | else |
1640 | seq_printf(m, "Debugfs support not implemented for this asic\n"); | 1603 | seq_printf(m, "Debugfs support not implemented for this asic\n"); |
1641 | mutex_unlock(&adev->pm.mutex); | 1604 | mutex_unlock(&adev->pm.mutex); |
1605 | } else { | ||
1606 | return amdgpu_debugfs_pm_info_pp(m, adev); | ||
1642 | } | 1607 | } |
1643 | 1608 | ||
1644 | return 0; | 1609 | return 0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index b7e1c026c0c8..033fba2def6f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | |||
@@ -34,24 +34,6 @@ | |||
34 | #include "cik_dpm.h" | 34 | #include "cik_dpm.h" |
35 | #include "vi_dpm.h" | 35 | #include "vi_dpm.h" |
36 | 36 | ||
37 | static int amdgpu_create_pp_handle(struct amdgpu_device *adev) | ||
38 | { | ||
39 | struct amd_pp_init pp_init; | ||
40 | struct amd_powerplay *amd_pp; | ||
41 | int ret; | ||
42 | |||
43 | amd_pp = &(adev->powerplay); | ||
44 | pp_init.chip_family = adev->family; | ||
45 | pp_init.chip_id = adev->asic_type; | ||
46 | pp_init.pm_en = (amdgpu_dpm != 0 && !amdgpu_sriov_vf(adev)) ? true : false; | ||
47 | pp_init.feature_mask = amdgpu_pp_feature_mask; | ||
48 | pp_init.device = amdgpu_cgs_create_device(adev); | ||
49 | ret = amd_powerplay_create(&pp_init, &(amd_pp->pp_handle)); | ||
50 | if (ret) | ||
51 | return -EINVAL; | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static int amdgpu_pp_early_init(void *handle) | 37 | static int amdgpu_pp_early_init(void *handle) |
56 | { | 38 | { |
57 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 39 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
@@ -59,7 +41,6 @@ static int amdgpu_pp_early_init(void *handle) | |||
59 | int ret = 0; | 41 | int ret = 0; |
60 | 42 | ||
61 | amd_pp = &(adev->powerplay); | 43 | amd_pp = &(adev->powerplay); |
62 | adev->pp_enabled = false; | ||
63 | amd_pp->pp_handle = (void *)adev; | 44 | amd_pp->pp_handle = (void *)adev; |
64 | 45 | ||
65 | switch (adev->asic_type) { | 46 | switch (adev->asic_type) { |
@@ -73,9 +54,7 @@ static int amdgpu_pp_early_init(void *handle) | |||
73 | case CHIP_STONEY: | 54 | case CHIP_STONEY: |
74 | case CHIP_VEGA10: | 55 | case CHIP_VEGA10: |
75 | case CHIP_RAVEN: | 56 | case CHIP_RAVEN: |
76 | adev->pp_enabled = true; | 57 | amd_pp->cgs_device = amdgpu_cgs_create_device(adev); |
77 | if (amdgpu_create_pp_handle(adev)) | ||
78 | return -EINVAL; | ||
79 | amd_pp->ip_funcs = &pp_ip_funcs; | 58 | amd_pp->ip_funcs = &pp_ip_funcs; |
80 | amd_pp->pp_funcs = &pp_dpm_funcs; | 59 | amd_pp->pp_funcs = &pp_dpm_funcs; |
81 | break; | 60 | break; |
@@ -87,17 +66,26 @@ static int amdgpu_pp_early_init(void *handle) | |||
87 | case CHIP_OLAND: | 66 | case CHIP_OLAND: |
88 | case CHIP_HAINAN: | 67 | case CHIP_HAINAN: |
89 | amd_pp->ip_funcs = &si_dpm_ip_funcs; | 68 | amd_pp->ip_funcs = &si_dpm_ip_funcs; |
69 | amd_pp->pp_funcs = &si_dpm_funcs; | ||
90 | break; | 70 | break; |
91 | #endif | 71 | #endif |
92 | #ifdef CONFIG_DRM_AMDGPU_CIK | 72 | #ifdef CONFIG_DRM_AMDGPU_CIK |
93 | case CHIP_BONAIRE: | 73 | case CHIP_BONAIRE: |
94 | case CHIP_HAWAII: | 74 | case CHIP_HAWAII: |
95 | amd_pp->ip_funcs = &ci_dpm_ip_funcs; | 75 | if (amdgpu_dpm == -1) { |
76 | amd_pp->ip_funcs = &ci_dpm_ip_funcs; | ||
77 | amd_pp->pp_funcs = &ci_dpm_funcs; | ||
78 | } else { | ||
79 | amd_pp->cgs_device = amdgpu_cgs_create_device(adev); | ||
80 | amd_pp->ip_funcs = &pp_ip_funcs; | ||
81 | amd_pp->pp_funcs = &pp_dpm_funcs; | ||
82 | } | ||
96 | break; | 83 | break; |
97 | case CHIP_KABINI: | 84 | case CHIP_KABINI: |
98 | case CHIP_MULLINS: | 85 | case CHIP_MULLINS: |
99 | case CHIP_KAVERI: | 86 | case CHIP_KAVERI: |
100 | amd_pp->ip_funcs = &kv_dpm_ip_funcs; | 87 | amd_pp->ip_funcs = &kv_dpm_ip_funcs; |
88 | amd_pp->pp_funcs = &kv_dpm_funcs; | ||
101 | break; | 89 | break; |
102 | #endif | 90 | #endif |
103 | default: | 91 | default: |
@@ -107,12 +95,9 @@ static int amdgpu_pp_early_init(void *handle) | |||
107 | 95 | ||
108 | if (adev->powerplay.ip_funcs->early_init) | 96 | if (adev->powerplay.ip_funcs->early_init) |
109 | ret = adev->powerplay.ip_funcs->early_init( | 97 | ret = adev->powerplay.ip_funcs->early_init( |
110 | adev->powerplay.pp_handle); | 98 | amd_pp->cgs_device ? amd_pp->cgs_device : |
99 | amd_pp->pp_handle); | ||
111 | 100 | ||
112 | if (ret == PP_DPM_DISABLED) { | ||
113 | adev->pm.dpm_enabled = false; | ||
114 | return 0; | ||
115 | } | ||
116 | return ret; | 101 | return ret; |
117 | } | 102 | } |
118 | 103 | ||
@@ -126,11 +111,6 @@ static int amdgpu_pp_late_init(void *handle) | |||
126 | ret = adev->powerplay.ip_funcs->late_init( | 111 | ret = adev->powerplay.ip_funcs->late_init( |
127 | adev->powerplay.pp_handle); | 112 | adev->powerplay.pp_handle); |
128 | 113 | ||
129 | if (adev->pp_enabled && adev->pm.dpm_enabled) { | ||
130 | amdgpu_pm_sysfs_init(adev); | ||
131 | amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_COMPLETE_INIT, NULL, NULL); | ||
132 | } | ||
133 | |||
134 | return ret; | 114 | return ret; |
135 | } | 115 | } |
136 | 116 | ||
@@ -165,21 +145,13 @@ static int amdgpu_pp_hw_init(void *handle) | |||
165 | int ret = 0; | 145 | int ret = 0; |
166 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 146 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
167 | 147 | ||
168 | if (adev->pp_enabled && adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) | 148 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) |
169 | amdgpu_ucode_init_bo(adev); | 149 | amdgpu_ucode_init_bo(adev); |
170 | 150 | ||
171 | if (adev->powerplay.ip_funcs->hw_init) | 151 | if (adev->powerplay.ip_funcs->hw_init) |
172 | ret = adev->powerplay.ip_funcs->hw_init( | 152 | ret = adev->powerplay.ip_funcs->hw_init( |
173 | adev->powerplay.pp_handle); | 153 | adev->powerplay.pp_handle); |
174 | 154 | ||
175 | if (ret == PP_DPM_DISABLED) { | ||
176 | adev->pm.dpm_enabled = false; | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | if ((amdgpu_dpm != 0) && !amdgpu_sriov_vf(adev)) | ||
181 | adev->pm.dpm_enabled = true; | ||
182 | |||
183 | return ret; | 155 | return ret; |
184 | } | 156 | } |
185 | 157 | ||
@@ -188,16 +160,10 @@ static int amdgpu_pp_hw_fini(void *handle) | |||
188 | int ret = 0; | 160 | int ret = 0; |
189 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 161 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
190 | 162 | ||
191 | if (adev->pp_enabled && adev->pm.dpm_enabled) | ||
192 | amdgpu_pm_sysfs_fini(adev); | ||
193 | |||
194 | if (adev->powerplay.ip_funcs->hw_fini) | 163 | if (adev->powerplay.ip_funcs->hw_fini) |
195 | ret = adev->powerplay.ip_funcs->hw_fini( | 164 | ret = adev->powerplay.ip_funcs->hw_fini( |
196 | adev->powerplay.pp_handle); | 165 | adev->powerplay.pp_handle); |
197 | 166 | ||
198 | if (adev->pp_enabled && adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) | ||
199 | amdgpu_ucode_fini_bo(adev); | ||
200 | |||
201 | return ret; | 167 | return ret; |
202 | } | 168 | } |
203 | 169 | ||
@@ -209,9 +175,8 @@ static void amdgpu_pp_late_fini(void *handle) | |||
209 | adev->powerplay.ip_funcs->late_fini( | 175 | adev->powerplay.ip_funcs->late_fini( |
210 | adev->powerplay.pp_handle); | 176 | adev->powerplay.pp_handle); |
211 | 177 | ||
212 | 178 | if (adev->powerplay.cgs_device) | |
213 | if (adev->pp_enabled) | 179 | amdgpu_cgs_destroy_device(adev->powerplay.cgs_device); |
214 | amd_powerplay_destroy(adev->powerplay.pp_handle); | ||
215 | } | 180 | } |
216 | 181 | ||
217 | static int amdgpu_pp_suspend(void *handle) | 182 | static int amdgpu_pp_suspend(void *handle) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c index 5b3f92891f89..ae9c106979d7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c | |||
@@ -57,6 +57,40 @@ void amdgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) | |||
57 | ttm_bo_kunmap(&bo->dma_buf_vmap); | 57 | ttm_bo_kunmap(&bo->dma_buf_vmap); |
58 | } | 58 | } |
59 | 59 | ||
60 | int amdgpu_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) | ||
61 | { | ||
62 | struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); | ||
63 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); | ||
64 | unsigned asize = amdgpu_bo_size(bo); | ||
65 | int ret; | ||
66 | |||
67 | if (!vma->vm_file) | ||
68 | return -ENODEV; | ||
69 | |||
70 | if (adev == NULL) | ||
71 | return -ENODEV; | ||
72 | |||
73 | /* Check for valid size. */ | ||
74 | if (asize < vma->vm_end - vma->vm_start) | ||
75 | return -EINVAL; | ||
76 | |||
77 | if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm) || | ||
78 | (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)) { | ||
79 | return -EPERM; | ||
80 | } | ||
81 | vma->vm_pgoff += amdgpu_bo_mmap_offset(bo) >> PAGE_SHIFT; | ||
82 | |||
83 | /* prime mmap does not need to check access, so allow here */ | ||
84 | ret = drm_vma_node_allow(&obj->vma_node, vma->vm_file->private_data); | ||
85 | if (ret) | ||
86 | return ret; | ||
87 | |||
88 | ret = ttm_bo_mmap(vma->vm_file, vma, &adev->mman.bdev); | ||
89 | drm_vma_node_revoke(&obj->vma_node, vma->vm_file->private_data); | ||
90 | |||
91 | return ret; | ||
92 | } | ||
93 | |||
60 | struct drm_gem_object * | 94 | struct drm_gem_object * |
61 | amdgpu_gem_prime_import_sg_table(struct drm_device *dev, | 95 | amdgpu_gem_prime_import_sg_table(struct drm_device *dev, |
62 | struct dma_buf_attachment *attach, | 96 | struct dma_buf_attachment *attach, |
@@ -135,9 +169,14 @@ struct dma_buf *amdgpu_gem_prime_export(struct drm_device *dev, | |||
135 | int flags) | 169 | int flags) |
136 | { | 170 | { |
137 | struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj); | 171 | struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj); |
172 | struct dma_buf *buf; | ||
138 | 173 | ||
139 | if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) | 174 | if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm) || |
175 | bo->flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) | ||
140 | return ERR_PTR(-EPERM); | 176 | return ERR_PTR(-EPERM); |
141 | 177 | ||
142 | return drm_gem_prime_export(dev, gobj, flags); | 178 | buf = drm_gem_prime_export(dev, gobj, flags); |
179 | if (!IS_ERR(buf)) | ||
180 | buf->file->f_mapping = dev->anon_inode->i_mapping; | ||
181 | return buf; | ||
143 | } | 182 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 8c2204c7b384..7714f4a6c8b0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | |||
@@ -57,21 +57,23 @@ static int psp_sw_init(void *handle) | |||
57 | psp->prep_cmd_buf = psp_v3_1_prep_cmd_buf; | 57 | psp->prep_cmd_buf = psp_v3_1_prep_cmd_buf; |
58 | psp->ring_init = psp_v3_1_ring_init; | 58 | psp->ring_init = psp_v3_1_ring_init; |
59 | psp->ring_create = psp_v3_1_ring_create; | 59 | psp->ring_create = psp_v3_1_ring_create; |
60 | psp->ring_stop = psp_v3_1_ring_stop; | ||
60 | psp->ring_destroy = psp_v3_1_ring_destroy; | 61 | psp->ring_destroy = psp_v3_1_ring_destroy; |
61 | psp->cmd_submit = psp_v3_1_cmd_submit; | 62 | psp->cmd_submit = psp_v3_1_cmd_submit; |
62 | psp->compare_sram_data = psp_v3_1_compare_sram_data; | 63 | psp->compare_sram_data = psp_v3_1_compare_sram_data; |
63 | psp->smu_reload_quirk = psp_v3_1_smu_reload_quirk; | 64 | psp->smu_reload_quirk = psp_v3_1_smu_reload_quirk; |
65 | psp->mode1_reset = psp_v3_1_mode1_reset; | ||
64 | break; | 66 | break; |
65 | case CHIP_RAVEN: | 67 | case CHIP_RAVEN: |
66 | #if 0 | ||
67 | psp->init_microcode = psp_v10_0_init_microcode; | 68 | psp->init_microcode = psp_v10_0_init_microcode; |
68 | #endif | ||
69 | psp->prep_cmd_buf = psp_v10_0_prep_cmd_buf; | 69 | psp->prep_cmd_buf = psp_v10_0_prep_cmd_buf; |
70 | psp->ring_init = psp_v10_0_ring_init; | 70 | psp->ring_init = psp_v10_0_ring_init; |
71 | psp->ring_create = psp_v10_0_ring_create; | 71 | psp->ring_create = psp_v10_0_ring_create; |
72 | psp->ring_stop = psp_v10_0_ring_stop; | ||
72 | psp->ring_destroy = psp_v10_0_ring_destroy; | 73 | psp->ring_destroy = psp_v10_0_ring_destroy; |
73 | psp->cmd_submit = psp_v10_0_cmd_submit; | 74 | psp->cmd_submit = psp_v10_0_cmd_submit; |
74 | psp->compare_sram_data = psp_v10_0_compare_sram_data; | 75 | psp->compare_sram_data = psp_v10_0_compare_sram_data; |
76 | psp->mode1_reset = psp_v10_0_mode1_reset; | ||
75 | break; | 77 | break; |
76 | default: | 78 | default: |
77 | return -EINVAL; | 79 | return -EINVAL; |
@@ -90,6 +92,12 @@ static int psp_sw_init(void *handle) | |||
90 | 92 | ||
91 | static int psp_sw_fini(void *handle) | 93 | static int psp_sw_fini(void *handle) |
92 | { | 94 | { |
95 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
96 | |||
97 | release_firmware(adev->psp.sos_fw); | ||
98 | adev->psp.sos_fw = NULL; | ||
99 | release_firmware(adev->psp.asd_fw); | ||
100 | adev->psp.asd_fw = NULL; | ||
93 | return 0; | 101 | return 0; |
94 | } | 102 | } |
95 | 103 | ||
@@ -253,15 +261,18 @@ static int psp_asd_load(struct psp_context *psp) | |||
253 | 261 | ||
254 | static int psp_hw_start(struct psp_context *psp) | 262 | static int psp_hw_start(struct psp_context *psp) |
255 | { | 263 | { |
264 | struct amdgpu_device *adev = psp->adev; | ||
256 | int ret; | 265 | int ret; |
257 | 266 | ||
258 | ret = psp_bootloader_load_sysdrv(psp); | 267 | if (!amdgpu_sriov_vf(adev) || !adev->in_sriov_reset) { |
259 | if (ret) | 268 | ret = psp_bootloader_load_sysdrv(psp); |
260 | return ret; | 269 | if (ret) |
270 | return ret; | ||
261 | 271 | ||
262 | ret = psp_bootloader_load_sos(psp); | 272 | ret = psp_bootloader_load_sos(psp); |
263 | if (ret) | 273 | if (ret) |
264 | return ret; | 274 | return ret; |
275 | } | ||
265 | 276 | ||
266 | ret = psp_ring_create(psp, PSP_RING_TYPE__KM); | 277 | ret = psp_ring_create(psp, PSP_RING_TYPE__KM); |
267 | if (ret) | 278 | if (ret) |
@@ -431,8 +442,6 @@ static int psp_hw_fini(void *handle) | |||
431 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) | 442 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) |
432 | return 0; | 443 | return 0; |
433 | 444 | ||
434 | amdgpu_ucode_fini_bo(adev); | ||
435 | |||
436 | psp_ring_destroy(psp, PSP_RING_TYPE__KM); | 445 | psp_ring_destroy(psp, PSP_RING_TYPE__KM); |
437 | 446 | ||
438 | amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); | 447 | amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); |
@@ -453,6 +462,16 @@ static int psp_hw_fini(void *handle) | |||
453 | 462 | ||
454 | static int psp_suspend(void *handle) | 463 | static int psp_suspend(void *handle) |
455 | { | 464 | { |
465 | int ret; | ||
466 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
467 | struct psp_context *psp = &adev->psp; | ||
468 | |||
469 | ret = psp_ring_stop(psp, PSP_RING_TYPE__KM); | ||
470 | if (ret) { | ||
471 | DRM_ERROR("PSP ring stop failed\n"); | ||
472 | return ret; | ||
473 | } | ||
474 | |||
456 | return 0; | 475 | return 0; |
457 | } | 476 | } |
458 | 477 | ||
@@ -487,6 +506,22 @@ failed: | |||
487 | return ret; | 506 | return ret; |
488 | } | 507 | } |
489 | 508 | ||
509 | static bool psp_check_reset(void* handle) | ||
510 | { | ||
511 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
512 | |||
513 | if (adev->flags & AMD_IS_APU) | ||
514 | return true; | ||
515 | |||
516 | return false; | ||
517 | } | ||
518 | |||
519 | static int psp_reset(void* handle) | ||
520 | { | ||
521 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
522 | return psp_mode1_reset(&adev->psp); | ||
523 | } | ||
524 | |||
490 | static bool psp_check_fw_loading_status(struct amdgpu_device *adev, | 525 | static bool psp_check_fw_loading_status(struct amdgpu_device *adev, |
491 | enum AMDGPU_UCODE_ID ucode_type) | 526 | enum AMDGPU_UCODE_ID ucode_type) |
492 | { | 527 | { |
@@ -530,8 +565,9 @@ const struct amd_ip_funcs psp_ip_funcs = { | |||
530 | .suspend = psp_suspend, | 565 | .suspend = psp_suspend, |
531 | .resume = psp_resume, | 566 | .resume = psp_resume, |
532 | .is_idle = NULL, | 567 | .is_idle = NULL, |
568 | .check_soft_reset = psp_check_reset, | ||
533 | .wait_for_idle = NULL, | 569 | .wait_for_idle = NULL, |
534 | .soft_reset = NULL, | 570 | .soft_reset = psp_reset, |
535 | .set_clockgating_state = psp_set_clockgating_state, | 571 | .set_clockgating_state = psp_set_clockgating_state, |
536 | .set_powergating_state = psp_set_powergating_state, | 572 | .set_powergating_state = psp_set_powergating_state, |
537 | }; | 573 | }; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h index 538fa9dbfb21..ce4654550416 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | |||
@@ -66,6 +66,8 @@ struct psp_context | |||
66 | struct psp_gfx_cmd_resp *cmd); | 66 | struct psp_gfx_cmd_resp *cmd); |
67 | int (*ring_init)(struct psp_context *psp, enum psp_ring_type ring_type); | 67 | int (*ring_init)(struct psp_context *psp, enum psp_ring_type ring_type); |
68 | int (*ring_create)(struct psp_context *psp, enum psp_ring_type ring_type); | 68 | int (*ring_create)(struct psp_context *psp, enum psp_ring_type ring_type); |
69 | int (*ring_stop)(struct psp_context *psp, | ||
70 | enum psp_ring_type ring_type); | ||
69 | int (*ring_destroy)(struct psp_context *psp, | 71 | int (*ring_destroy)(struct psp_context *psp, |
70 | enum psp_ring_type ring_type); | 72 | enum psp_ring_type ring_type); |
71 | int (*cmd_submit)(struct psp_context *psp, struct amdgpu_firmware_info *ucode, | 73 | int (*cmd_submit)(struct psp_context *psp, struct amdgpu_firmware_info *ucode, |
@@ -74,6 +76,7 @@ struct psp_context | |||
74 | struct amdgpu_firmware_info *ucode, | 76 | struct amdgpu_firmware_info *ucode, |
75 | enum AMDGPU_UCODE_ID ucode_type); | 77 | enum AMDGPU_UCODE_ID ucode_type); |
76 | bool (*smu_reload_quirk)(struct psp_context *psp); | 78 | bool (*smu_reload_quirk)(struct psp_context *psp); |
79 | int (*mode1_reset)(struct psp_context *psp); | ||
77 | 80 | ||
78 | /* fence buffer */ | 81 | /* fence buffer */ |
79 | struct amdgpu_bo *fw_pri_bo; | 82 | struct amdgpu_bo *fw_pri_bo; |
@@ -123,6 +126,7 @@ struct amdgpu_psp_funcs { | |||
123 | #define psp_prep_cmd_buf(ucode, type) (psp)->prep_cmd_buf((ucode), (type)) | 126 | #define psp_prep_cmd_buf(ucode, type) (psp)->prep_cmd_buf((ucode), (type)) |
124 | #define psp_ring_init(psp, type) (psp)->ring_init((psp), (type)) | 127 | #define psp_ring_init(psp, type) (psp)->ring_init((psp), (type)) |
125 | #define psp_ring_create(psp, type) (psp)->ring_create((psp), (type)) | 128 | #define psp_ring_create(psp, type) (psp)->ring_create((psp), (type)) |
129 | #define psp_ring_stop(psp, type) (psp)->ring_stop((psp), (type)) | ||
126 | #define psp_ring_destroy(psp, type) ((psp)->ring_destroy((psp), (type))) | 130 | #define psp_ring_destroy(psp, type) ((psp)->ring_destroy((psp), (type))) |
127 | #define psp_cmd_submit(psp, ucode, cmd_mc, fence_mc, index) \ | 131 | #define psp_cmd_submit(psp, ucode, cmd_mc, fence_mc, index) \ |
128 | (psp)->cmd_submit((psp), (ucode), (cmd_mc), (fence_mc), (index)) | 132 | (psp)->cmd_submit((psp), (ucode), (cmd_mc), (fence_mc), (index)) |
@@ -136,6 +140,8 @@ struct amdgpu_psp_funcs { | |||
136 | ((psp)->bootloader_load_sos ? (psp)->bootloader_load_sos((psp)) : 0) | 140 | ((psp)->bootloader_load_sos ? (psp)->bootloader_load_sos((psp)) : 0) |
137 | #define psp_smu_reload_quirk(psp) \ | 141 | #define psp_smu_reload_quirk(psp) \ |
138 | ((psp)->smu_reload_quirk ? (psp)->smu_reload_quirk((psp)) : false) | 142 | ((psp)->smu_reload_quirk ? (psp)->smu_reload_quirk((psp)) : false) |
143 | #define psp_mode1_reset(psp) \ | ||
144 | ((psp)->mode1_reset ? (psp)->mode1_reset((psp)) : false) | ||
139 | 145 | ||
140 | extern const struct amd_ip_funcs psp_ip_funcs; | 146 | extern const struct amd_ip_funcs psp_ip_funcs; |
141 | 147 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c index befc09b68543..190e28cb827e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c | |||
@@ -121,7 +121,7 @@ static enum amdgpu_ring_type amdgpu_hw_ip_to_ring_type(int hw_ip) | |||
121 | 121 | ||
122 | static int amdgpu_lru_map(struct amdgpu_device *adev, | 122 | static int amdgpu_lru_map(struct amdgpu_device *adev, |
123 | struct amdgpu_queue_mapper *mapper, | 123 | struct amdgpu_queue_mapper *mapper, |
124 | int user_ring, | 124 | int user_ring, bool lru_pipe_order, |
125 | struct amdgpu_ring **out_ring) | 125 | struct amdgpu_ring **out_ring) |
126 | { | 126 | { |
127 | int r, i, j; | 127 | int r, i, j; |
@@ -139,7 +139,7 @@ static int amdgpu_lru_map(struct amdgpu_device *adev, | |||
139 | } | 139 | } |
140 | 140 | ||
141 | r = amdgpu_ring_lru_get(adev, ring_type, ring_blacklist, | 141 | r = amdgpu_ring_lru_get(adev, ring_type, ring_blacklist, |
142 | j, out_ring); | 142 | j, lru_pipe_order, out_ring); |
143 | if (r) | 143 | if (r) |
144 | return r; | 144 | return r; |
145 | 145 | ||
@@ -284,8 +284,10 @@ int amdgpu_queue_mgr_map(struct amdgpu_device *adev, | |||
284 | r = amdgpu_identity_map(adev, mapper, ring, out_ring); | 284 | r = amdgpu_identity_map(adev, mapper, ring, out_ring); |
285 | break; | 285 | break; |
286 | case AMDGPU_HW_IP_DMA: | 286 | case AMDGPU_HW_IP_DMA: |
287 | r = amdgpu_lru_map(adev, mapper, ring, false, out_ring); | ||
288 | break; | ||
287 | case AMDGPU_HW_IP_COMPUTE: | 289 | case AMDGPU_HW_IP_COMPUTE: |
288 | r = amdgpu_lru_map(adev, mapper, ring, out_ring); | 290 | r = amdgpu_lru_map(adev, mapper, ring, true, out_ring); |
289 | break; | 291 | break; |
290 | default: | 292 | default: |
291 | *out_ring = NULL; | 293 | *out_ring = NULL; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 5ce65280b396..a98fbbb4739f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | |||
@@ -136,7 +136,8 @@ void amdgpu_ring_commit(struct amdgpu_ring *ring) | |||
136 | if (ring->funcs->end_use) | 136 | if (ring->funcs->end_use) |
137 | ring->funcs->end_use(ring); | 137 | ring->funcs->end_use(ring); |
138 | 138 | ||
139 | amdgpu_ring_lru_touch(ring->adev, ring); | 139 | if (ring->funcs->type != AMDGPU_RING_TYPE_KIQ) |
140 | amdgpu_ring_lru_touch(ring->adev, ring); | ||
140 | } | 141 | } |
141 | 142 | ||
142 | /** | 143 | /** |
@@ -155,6 +156,75 @@ void amdgpu_ring_undo(struct amdgpu_ring *ring) | |||
155 | } | 156 | } |
156 | 157 | ||
157 | /** | 158 | /** |
159 | * amdgpu_ring_priority_put - restore a ring's priority | ||
160 | * | ||
161 | * @ring: amdgpu_ring structure holding the information | ||
162 | * @priority: target priority | ||
163 | * | ||
164 | * Release a request for executing at @priority | ||
165 | */ | ||
166 | void amdgpu_ring_priority_put(struct amdgpu_ring *ring, | ||
167 | enum amd_sched_priority priority) | ||
168 | { | ||
169 | int i; | ||
170 | |||
171 | if (!ring->funcs->set_priority) | ||
172 | return; | ||
173 | |||
174 | if (atomic_dec_return(&ring->num_jobs[priority]) > 0) | ||
175 | return; | ||
176 | |||
177 | /* no need to restore if the job is already at the lowest priority */ | ||
178 | if (priority == AMD_SCHED_PRIORITY_NORMAL) | ||
179 | return; | ||
180 | |||
181 | mutex_lock(&ring->priority_mutex); | ||
182 | /* something higher prio is executing, no need to decay */ | ||
183 | if (ring->priority > priority) | ||
184 | goto out_unlock; | ||
185 | |||
186 | /* decay priority to the next level with a job available */ | ||
187 | for (i = priority; i >= AMD_SCHED_PRIORITY_MIN; i--) { | ||
188 | if (i == AMD_SCHED_PRIORITY_NORMAL | ||
189 | || atomic_read(&ring->num_jobs[i])) { | ||
190 | ring->priority = i; | ||
191 | ring->funcs->set_priority(ring, i); | ||
192 | break; | ||
193 | } | ||
194 | } | ||
195 | |||
196 | out_unlock: | ||
197 | mutex_unlock(&ring->priority_mutex); | ||
198 | } | ||
199 | |||
200 | /** | ||
201 | * amdgpu_ring_priority_get - change the ring's priority | ||
202 | * | ||
203 | * @ring: amdgpu_ring structure holding the information | ||
204 | * @priority: target priority | ||
205 | * | ||
206 | * Request a ring's priority to be raised to @priority (refcounted). | ||
207 | */ | ||
208 | void amdgpu_ring_priority_get(struct amdgpu_ring *ring, | ||
209 | enum amd_sched_priority priority) | ||
210 | { | ||
211 | if (!ring->funcs->set_priority) | ||
212 | return; | ||
213 | |||
214 | atomic_inc(&ring->num_jobs[priority]); | ||
215 | |||
216 | mutex_lock(&ring->priority_mutex); | ||
217 | if (priority <= ring->priority) | ||
218 | goto out_unlock; | ||
219 | |||
220 | ring->priority = priority; | ||
221 | ring->funcs->set_priority(ring, priority); | ||
222 | |||
223 | out_unlock: | ||
224 | mutex_unlock(&ring->priority_mutex); | ||
225 | } | ||
226 | |||
227 | /** | ||
158 | * amdgpu_ring_init - init driver ring struct. | 228 | * amdgpu_ring_init - init driver ring struct. |
159 | * | 229 | * |
160 | * @adev: amdgpu_device pointer | 230 | * @adev: amdgpu_device pointer |
@@ -169,7 +239,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, | |||
169 | unsigned max_dw, struct amdgpu_irq_src *irq_src, | 239 | unsigned max_dw, struct amdgpu_irq_src *irq_src, |
170 | unsigned irq_type) | 240 | unsigned irq_type) |
171 | { | 241 | { |
172 | int r; | 242 | int r, i; |
173 | int sched_hw_submission = amdgpu_sched_hw_submission; | 243 | int sched_hw_submission = amdgpu_sched_hw_submission; |
174 | 244 | ||
175 | /* Set the hw submission limit higher for KIQ because | 245 | /* Set the hw submission limit higher for KIQ because |
@@ -247,9 +317,14 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, | |||
247 | } | 317 | } |
248 | 318 | ||
249 | ring->max_dw = max_dw; | 319 | ring->max_dw = max_dw; |
320 | ring->priority = AMD_SCHED_PRIORITY_NORMAL; | ||
321 | mutex_init(&ring->priority_mutex); | ||
250 | INIT_LIST_HEAD(&ring->lru_list); | 322 | INIT_LIST_HEAD(&ring->lru_list); |
251 | amdgpu_ring_lru_touch(adev, ring); | 323 | amdgpu_ring_lru_touch(adev, ring); |
252 | 324 | ||
325 | for (i = 0; i < AMD_SCHED_PRIORITY_MAX; ++i) | ||
326 | atomic_set(&ring->num_jobs[i], 0); | ||
327 | |||
253 | if (amdgpu_debugfs_ring_init(adev, ring)) { | 328 | if (amdgpu_debugfs_ring_init(adev, ring)) { |
254 | DRM_ERROR("Failed to register debugfs file for rings !\n"); | 329 | DRM_ERROR("Failed to register debugfs file for rings !\n"); |
255 | } | 330 | } |
@@ -315,14 +390,16 @@ static bool amdgpu_ring_is_blacklisted(struct amdgpu_ring *ring, | |||
315 | * @type: amdgpu_ring_type enum | 390 | * @type: amdgpu_ring_type enum |
316 | * @blacklist: blacklisted ring ids array | 391 | * @blacklist: blacklisted ring ids array |
317 | * @num_blacklist: number of entries in @blacklist | 392 | * @num_blacklist: number of entries in @blacklist |
393 | * @lru_pipe_order: find a ring from the least recently used pipe | ||
318 | * @ring: output ring | 394 | * @ring: output ring |
319 | * | 395 | * |
320 | * Retrieve the amdgpu_ring structure for the least recently used ring of | 396 | * Retrieve the amdgpu_ring structure for the least recently used ring of |
321 | * a specific IP block (all asics). | 397 | * a specific IP block (all asics). |
322 | * Returns 0 on success, error on failure. | 398 | * Returns 0 on success, error on failure. |
323 | */ | 399 | */ |
324 | int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, int *blacklist, | 400 | int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, |
325 | int num_blacklist, struct amdgpu_ring **ring) | 401 | int *blacklist, int num_blacklist, |
402 | bool lru_pipe_order, struct amdgpu_ring **ring) | ||
326 | { | 403 | { |
327 | struct amdgpu_ring *entry; | 404 | struct amdgpu_ring *entry; |
328 | 405 | ||
@@ -337,10 +414,23 @@ int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, int *blacklist, | |||
337 | if (amdgpu_ring_is_blacklisted(entry, blacklist, num_blacklist)) | 414 | if (amdgpu_ring_is_blacklisted(entry, blacklist, num_blacklist)) |
338 | continue; | 415 | continue; |
339 | 416 | ||
340 | *ring = entry; | 417 | if (!*ring) { |
341 | amdgpu_ring_lru_touch_locked(adev, *ring); | 418 | *ring = entry; |
342 | break; | 419 | |
420 | /* We are done for ring LRU */ | ||
421 | if (!lru_pipe_order) | ||
422 | break; | ||
423 | } | ||
424 | |||
425 | /* Move all rings on the same pipe to the end of the list */ | ||
426 | if (entry->pipe == (*ring)->pipe) | ||
427 | amdgpu_ring_lru_touch_locked(adev, entry); | ||
343 | } | 428 | } |
429 | |||
430 | /* Move the ring we found to the end of the list */ | ||
431 | if (*ring) | ||
432 | amdgpu_ring_lru_touch_locked(adev, *ring); | ||
433 | |||
344 | spin_unlock(&adev->ring_lru_list_lock); | 434 | spin_unlock(&adev->ring_lru_list_lock); |
345 | 435 | ||
346 | if (!*ring) { | 436 | if (!*ring) { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 322d25299a00..b18c2b96691f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #ifndef __AMDGPU_RING_H__ | 24 | #ifndef __AMDGPU_RING_H__ |
25 | #define __AMDGPU_RING_H__ | 25 | #define __AMDGPU_RING_H__ |
26 | 26 | ||
27 | #include <drm/amdgpu_drm.h> | ||
27 | #include "gpu_scheduler.h" | 28 | #include "gpu_scheduler.h" |
28 | 29 | ||
29 | /* max number of rings */ | 30 | /* max number of rings */ |
@@ -56,6 +57,7 @@ struct amdgpu_device; | |||
56 | struct amdgpu_ring; | 57 | struct amdgpu_ring; |
57 | struct amdgpu_ib; | 58 | struct amdgpu_ib; |
58 | struct amdgpu_cs_parser; | 59 | struct amdgpu_cs_parser; |
60 | struct amdgpu_job; | ||
59 | 61 | ||
60 | /* | 62 | /* |
61 | * Fences. | 63 | * Fences. |
@@ -88,8 +90,12 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring, | |||
88 | void amdgpu_fence_driver_suspend(struct amdgpu_device *adev); | 90 | void amdgpu_fence_driver_suspend(struct amdgpu_device *adev); |
89 | void amdgpu_fence_driver_resume(struct amdgpu_device *adev); | 91 | void amdgpu_fence_driver_resume(struct amdgpu_device *adev); |
90 | int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **fence); | 92 | int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **fence); |
93 | int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s); | ||
91 | void amdgpu_fence_process(struct amdgpu_ring *ring); | 94 | void amdgpu_fence_process(struct amdgpu_ring *ring); |
92 | int amdgpu_fence_wait_empty(struct amdgpu_ring *ring); | 95 | int amdgpu_fence_wait_empty(struct amdgpu_ring *ring); |
96 | signed long amdgpu_fence_wait_polling(struct amdgpu_ring *ring, | ||
97 | uint32_t wait_seq, | ||
98 | signed long timeout); | ||
93 | unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring); | 99 | unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring); |
94 | 100 | ||
95 | /* | 101 | /* |
@@ -147,6 +153,9 @@ struct amdgpu_ring_funcs { | |||
147 | void (*emit_rreg)(struct amdgpu_ring *ring, uint32_t reg); | 153 | void (*emit_rreg)(struct amdgpu_ring *ring, uint32_t reg); |
148 | void (*emit_wreg)(struct amdgpu_ring *ring, uint32_t reg, uint32_t val); | 154 | void (*emit_wreg)(struct amdgpu_ring *ring, uint32_t reg, uint32_t val); |
149 | void (*emit_tmz)(struct amdgpu_ring *ring, bool start); | 155 | void (*emit_tmz)(struct amdgpu_ring *ring, bool start); |
156 | /* priority functions */ | ||
157 | void (*set_priority) (struct amdgpu_ring *ring, | ||
158 | enum amd_sched_priority priority); | ||
150 | }; | 159 | }; |
151 | 160 | ||
152 | struct amdgpu_ring { | 161 | struct amdgpu_ring { |
@@ -187,6 +196,12 @@ struct amdgpu_ring { | |||
187 | volatile u32 *cond_exe_cpu_addr; | 196 | volatile u32 *cond_exe_cpu_addr; |
188 | unsigned vm_inv_eng; | 197 | unsigned vm_inv_eng; |
189 | bool has_compute_vm_bug; | 198 | bool has_compute_vm_bug; |
199 | |||
200 | atomic_t num_jobs[AMD_SCHED_PRIORITY_MAX]; | ||
201 | struct mutex priority_mutex; | ||
202 | /* protected by priority_mutex */ | ||
203 | int priority; | ||
204 | |||
190 | #if defined(CONFIG_DEBUG_FS) | 205 | #if defined(CONFIG_DEBUG_FS) |
191 | struct dentry *ent; | 206 | struct dentry *ent; |
192 | #endif | 207 | #endif |
@@ -197,12 +212,17 @@ void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count); | |||
197 | void amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib); | 212 | void amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib); |
198 | void amdgpu_ring_commit(struct amdgpu_ring *ring); | 213 | void amdgpu_ring_commit(struct amdgpu_ring *ring); |
199 | void amdgpu_ring_undo(struct amdgpu_ring *ring); | 214 | void amdgpu_ring_undo(struct amdgpu_ring *ring); |
215 | void amdgpu_ring_priority_get(struct amdgpu_ring *ring, | ||
216 | enum amd_sched_priority priority); | ||
217 | void amdgpu_ring_priority_put(struct amdgpu_ring *ring, | ||
218 | enum amd_sched_priority priority); | ||
200 | int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, | 219 | int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, |
201 | unsigned ring_size, struct amdgpu_irq_src *irq_src, | 220 | unsigned ring_size, struct amdgpu_irq_src *irq_src, |
202 | unsigned irq_type); | 221 | unsigned irq_type); |
203 | void amdgpu_ring_fini(struct amdgpu_ring *ring); | 222 | void amdgpu_ring_fini(struct amdgpu_ring *ring); |
204 | int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, int *blacklist, | 223 | int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, |
205 | int num_blacklist, struct amdgpu_ring **ring); | 224 | int *blacklist, int num_blacklist, |
225 | bool lru_pipe_order, struct amdgpu_ring **ring); | ||
206 | void amdgpu_ring_lru_touch(struct amdgpu_device *adev, struct amdgpu_ring *ring); | 226 | void amdgpu_ring_lru_touch(struct amdgpu_device *adev, struct amdgpu_ring *ring); |
207 | static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring) | 227 | static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring) |
208 | { | 228 | { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c new file mode 100644 index 000000000000..290cc3f9c433 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | |||
@@ -0,0 +1,109 @@ | |||
1 | /* | ||
2 | * Copyright 2017 Valve Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice 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 | * Authors: Andres Rodriguez <andresx7@gmail.com> | ||
23 | */ | ||
24 | |||
25 | #include <linux/fdtable.h> | ||
26 | #include <linux/pid.h> | ||
27 | #include <drm/amdgpu_drm.h> | ||
28 | #include "amdgpu.h" | ||
29 | |||
30 | #include "amdgpu_vm.h" | ||
31 | |||
32 | enum amd_sched_priority amdgpu_to_sched_priority(int amdgpu_priority) | ||
33 | { | ||
34 | switch (amdgpu_priority) { | ||
35 | case AMDGPU_CTX_PRIORITY_VERY_HIGH: | ||
36 | return AMD_SCHED_PRIORITY_HIGH_HW; | ||
37 | case AMDGPU_CTX_PRIORITY_HIGH: | ||
38 | return AMD_SCHED_PRIORITY_HIGH_SW; | ||
39 | case AMDGPU_CTX_PRIORITY_NORMAL: | ||
40 | return AMD_SCHED_PRIORITY_NORMAL; | ||
41 | case AMDGPU_CTX_PRIORITY_LOW: | ||
42 | case AMDGPU_CTX_PRIORITY_VERY_LOW: | ||
43 | return AMD_SCHED_PRIORITY_LOW; | ||
44 | case AMDGPU_CTX_PRIORITY_UNSET: | ||
45 | return AMD_SCHED_PRIORITY_UNSET; | ||
46 | default: | ||
47 | WARN(1, "Invalid context priority %d\n", amdgpu_priority); | ||
48 | return AMD_SCHED_PRIORITY_INVALID; | ||
49 | } | ||
50 | } | ||
51 | |||
52 | static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev, | ||
53 | int fd, | ||
54 | enum amd_sched_priority priority) | ||
55 | { | ||
56 | struct file *filp = fcheck(fd); | ||
57 | struct drm_file *file; | ||
58 | struct pid *pid; | ||
59 | struct amdgpu_fpriv *fpriv; | ||
60 | struct amdgpu_ctx *ctx; | ||
61 | uint32_t id; | ||
62 | |||
63 | if (!filp) | ||
64 | return -EINVAL; | ||
65 | |||
66 | pid = get_pid(((struct drm_file *)filp->private_data)->pid); | ||
67 | |||
68 | mutex_lock(&adev->ddev->filelist_mutex); | ||
69 | list_for_each_entry(file, &adev->ddev->filelist, lhead) { | ||
70 | if (file->pid != pid) | ||
71 | continue; | ||
72 | |||
73 | fpriv = file->driver_priv; | ||
74 | idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id) | ||
75 | amdgpu_ctx_priority_override(ctx, priority); | ||
76 | } | ||
77 | mutex_unlock(&adev->ddev->filelist_mutex); | ||
78 | |||
79 | put_pid(pid); | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | int amdgpu_sched_ioctl(struct drm_device *dev, void *data, | ||
85 | struct drm_file *filp) | ||
86 | { | ||
87 | union drm_amdgpu_sched *args = data; | ||
88 | struct amdgpu_device *adev = dev->dev_private; | ||
89 | enum amd_sched_priority priority; | ||
90 | int r; | ||
91 | |||
92 | priority = amdgpu_to_sched_priority(args->in.priority); | ||
93 | if (args->in.flags || priority == AMD_SCHED_PRIORITY_INVALID) | ||
94 | return -EINVAL; | ||
95 | |||
96 | switch (args->in.op) { | ||
97 | case AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE: | ||
98 | r = amdgpu_sched_process_priority_override(adev, | ||
99 | args->in.fd, | ||
100 | priority); | ||
101 | break; | ||
102 | default: | ||
103 | DRM_ERROR("Invalid sched op specified: %d\n", args->in.op); | ||
104 | r = -EINVAL; | ||
105 | break; | ||
106 | } | ||
107 | |||
108 | return r; | ||
109 | } | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.h new file mode 100644 index 000000000000..b28c067d3822 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * Copyright 2017 Valve Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice 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 | * Authors: Andres Rodriguez <andresx7@gmail.com> | ||
23 | */ | ||
24 | |||
25 | #ifndef __AMDGPU_SCHED_H__ | ||
26 | #define __AMDGPU_SCHED_H__ | ||
27 | |||
28 | #include <drm/drmP.h> | ||
29 | |||
30 | enum amd_sched_priority amdgpu_to_sched_priority(int amdgpu_priority); | ||
31 | int amdgpu_sched_ioctl(struct drm_device *dev, void *data, | ||
32 | struct drm_file *filp); | ||
33 | |||
34 | #endif // __AMDGPU_SCHED_H__ | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c index c586f44312f9..a4bf21f8f1c1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | |||
@@ -169,14 +169,14 @@ int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync, | |||
169 | * | 169 | * |
170 | * @sync: sync object to add fences from reservation object to | 170 | * @sync: sync object to add fences from reservation object to |
171 | * @resv: reservation object with embedded fence | 171 | * @resv: reservation object with embedded fence |
172 | * @shared: true if we should only sync to the exclusive fence | 172 | * @explicit_sync: true if we should only sync to the exclusive fence |
173 | * | 173 | * |
174 | * Sync to the fence | 174 | * Sync to the fence |
175 | */ | 175 | */ |
176 | int amdgpu_sync_resv(struct amdgpu_device *adev, | 176 | int amdgpu_sync_resv(struct amdgpu_device *adev, |
177 | struct amdgpu_sync *sync, | 177 | struct amdgpu_sync *sync, |
178 | struct reservation_object *resv, | 178 | struct reservation_object *resv, |
179 | void *owner) | 179 | void *owner, bool explicit_sync) |
180 | { | 180 | { |
181 | struct reservation_object_list *flist; | 181 | struct reservation_object_list *flist; |
182 | struct dma_fence *f; | 182 | struct dma_fence *f; |
@@ -191,6 +191,9 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, | |||
191 | f = reservation_object_get_excl(resv); | 191 | f = reservation_object_get_excl(resv); |
192 | r = amdgpu_sync_fence(adev, sync, f); | 192 | r = amdgpu_sync_fence(adev, sync, f); |
193 | 193 | ||
194 | if (explicit_sync) | ||
195 | return r; | ||
196 | |||
194 | flist = reservation_object_get_list(resv); | 197 | flist = reservation_object_get_list(resv); |
195 | if (!flist || r) | 198 | if (!flist || r) |
196 | return r; | 199 | return r; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h index dc7687993317..70d7e3a279a0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h | |||
@@ -45,7 +45,8 @@ int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync, | |||
45 | int amdgpu_sync_resv(struct amdgpu_device *adev, | 45 | int amdgpu_sync_resv(struct amdgpu_device *adev, |
46 | struct amdgpu_sync *sync, | 46 | struct amdgpu_sync *sync, |
47 | struct reservation_object *resv, | 47 | struct reservation_object *resv, |
48 | void *owner); | 48 | void *owner, |
49 | bool explicit_sync); | ||
49 | struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync, | 50 | struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync, |
50 | struct amdgpu_ring *ring); | 51 | struct amdgpu_ring *ring); |
51 | struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync); | 52 | struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h index 34c99a3c8d2d..f337c316ec2c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h | |||
@@ -15,62 +15,6 @@ | |||
15 | #define AMDGPU_JOB_GET_TIMELINE_NAME(job) \ | 15 | #define AMDGPU_JOB_GET_TIMELINE_NAME(job) \ |
16 | job->base.s_fence->finished.ops->get_timeline_name(&job->base.s_fence->finished) | 16 | job->base.s_fence->finished.ops->get_timeline_name(&job->base.s_fence->finished) |
17 | 17 | ||
18 | TRACE_EVENT(amdgpu_ttm_tt_populate, | ||
19 | TP_PROTO(struct amdgpu_device *adev, uint64_t dma_address, uint64_t phys_address), | ||
20 | TP_ARGS(adev, dma_address, phys_address), | ||
21 | TP_STRUCT__entry( | ||
22 | __field(uint16_t, domain) | ||
23 | __field(uint8_t, bus) | ||
24 | __field(uint8_t, slot) | ||
25 | __field(uint8_t, func) | ||
26 | __field(uint64_t, dma) | ||
27 | __field(uint64_t, phys) | ||
28 | ), | ||
29 | TP_fast_assign( | ||
30 | __entry->domain = pci_domain_nr(adev->pdev->bus); | ||
31 | __entry->bus = adev->pdev->bus->number; | ||
32 | __entry->slot = PCI_SLOT(adev->pdev->devfn); | ||
33 | __entry->func = PCI_FUNC(adev->pdev->devfn); | ||
34 | __entry->dma = dma_address; | ||
35 | __entry->phys = phys_address; | ||
36 | ), | ||
37 | TP_printk("%04x:%02x:%02x.%x: 0x%llx => 0x%llx", | ||
38 | (unsigned)__entry->domain, | ||
39 | (unsigned)__entry->bus, | ||
40 | (unsigned)__entry->slot, | ||
41 | (unsigned)__entry->func, | ||
42 | (unsigned long long)__entry->dma, | ||
43 | (unsigned long long)__entry->phys) | ||
44 | ); | ||
45 | |||
46 | TRACE_EVENT(amdgpu_ttm_tt_unpopulate, | ||
47 | TP_PROTO(struct amdgpu_device *adev, uint64_t dma_address, uint64_t phys_address), | ||
48 | TP_ARGS(adev, dma_address, phys_address), | ||
49 | TP_STRUCT__entry( | ||
50 | __field(uint16_t, domain) | ||
51 | __field(uint8_t, bus) | ||
52 | __field(uint8_t, slot) | ||
53 | __field(uint8_t, func) | ||
54 | __field(uint64_t, dma) | ||
55 | __field(uint64_t, phys) | ||
56 | ), | ||
57 | TP_fast_assign( | ||
58 | __entry->domain = pci_domain_nr(adev->pdev->bus); | ||
59 | __entry->bus = adev->pdev->bus->number; | ||
60 | __entry->slot = PCI_SLOT(adev->pdev->devfn); | ||
61 | __entry->func = PCI_FUNC(adev->pdev->devfn); | ||
62 | __entry->dma = dma_address; | ||
63 | __entry->phys = phys_address; | ||
64 | ), | ||
65 | TP_printk("%04x:%02x:%02x.%x: 0x%llx => 0x%llx", | ||
66 | (unsigned)__entry->domain, | ||
67 | (unsigned)__entry->bus, | ||
68 | (unsigned)__entry->slot, | ||
69 | (unsigned)__entry->func, | ||
70 | (unsigned long long)__entry->dma, | ||
71 | (unsigned long long)__entry->phys) | ||
72 | ); | ||
73 | |||
74 | TRACE_EVENT(amdgpu_mm_rreg, | 18 | TRACE_EVENT(amdgpu_mm_rreg, |
75 | TP_PROTO(unsigned did, uint32_t reg, uint32_t value), | 19 | TP_PROTO(unsigned did, uint32_t reg, uint32_t value), |
76 | TP_ARGS(did, reg, value), | 20 | TP_ARGS(did, reg, value), |
@@ -474,5 +418,5 @@ TRACE_EVENT(amdgpu_ttm_bo_move, | |||
474 | 418 | ||
475 | /* This part must be outside protection */ | 419 | /* This part must be outside protection */ |
476 | #undef TRACE_INCLUDE_PATH | 420 | #undef TRACE_INCLUDE_PATH |
477 | #define TRACE_INCLUDE_PATH . | 421 | #define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/amd/amdgpu |
478 | #include <trace/define_trace.h> | 422 | #include <trace/define_trace.h> |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace_points.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace_points.c index 89680d554ed8..b160b958e5fe 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace_points.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace_points.c | |||
@@ -1,5 +1,24 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Copyright Red Hat Inc 2010. | 2 | /* Copyright Red Hat Inc 2010. |
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 | * | ||
3 | * Author : Dave Airlie <airlied@redhat.com> | 22 | * Author : Dave Airlie <airlied@redhat.com> |
4 | */ | 23 | */ |
5 | #include <drm/drmP.h> | 24 | #include <drm/drmP.h> |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index bc746131987f..ad5bf86ee8a3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | |||
@@ -42,7 +42,9 @@ | |||
42 | #include <linux/swap.h> | 42 | #include <linux/swap.h> |
43 | #include <linux/pagemap.h> | 43 | #include <linux/pagemap.h> |
44 | #include <linux/debugfs.h> | 44 | #include <linux/debugfs.h> |
45 | #include <linux/iommu.h> | ||
45 | #include "amdgpu.h" | 46 | #include "amdgpu.h" |
47 | #include "amdgpu_object.h" | ||
46 | #include "amdgpu_trace.h" | 48 | #include "amdgpu_trace.h" |
47 | #include "bif/bif_4_1_d.h" | 49 | #include "bif/bif_4_1_d.h" |
48 | 50 | ||
@@ -208,7 +210,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo, | |||
208 | placement->num_busy_placement = 1; | 210 | placement->num_busy_placement = 1; |
209 | return; | 211 | return; |
210 | } | 212 | } |
211 | abo = container_of(bo, struct amdgpu_bo, tbo); | 213 | abo = ttm_to_amdgpu_bo(bo); |
212 | switch (bo->mem.mem_type) { | 214 | switch (bo->mem.mem_type) { |
213 | case TTM_PL_VRAM: | 215 | case TTM_PL_VRAM: |
214 | if (adev->mman.buffer_funcs && | 216 | if (adev->mman.buffer_funcs && |
@@ -256,7 +258,7 @@ gtt: | |||
256 | 258 | ||
257 | static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp) | 259 | static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp) |
258 | { | 260 | { |
259 | struct amdgpu_bo *abo = container_of(bo, struct amdgpu_bo, tbo); | 261 | struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo); |
260 | 262 | ||
261 | if (amdgpu_ttm_tt_get_usermm(bo->ttm)) | 263 | if (amdgpu_ttm_tt_get_usermm(bo->ttm)) |
262 | return -EPERM; | 264 | return -EPERM; |
@@ -288,97 +290,177 @@ static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo, | |||
288 | return addr; | 290 | return addr; |
289 | } | 291 | } |
290 | 292 | ||
291 | static int amdgpu_move_blit(struct ttm_buffer_object *bo, | 293 | /** |
292 | bool evict, bool no_wait_gpu, | 294 | * amdgpu_find_mm_node - Helper function finds the drm_mm_node |
293 | struct ttm_mem_reg *new_mem, | 295 | * corresponding to @offset. It also modifies the offset to be |
294 | struct ttm_mem_reg *old_mem) | 296 | * within the drm_mm_node returned |
297 | */ | ||
298 | static struct drm_mm_node *amdgpu_find_mm_node(struct ttm_mem_reg *mem, | ||
299 | unsigned long *offset) | ||
295 | { | 300 | { |
296 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); | 301 | struct drm_mm_node *mm_node = mem->mm_node; |
297 | struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring; | ||
298 | 302 | ||
299 | struct drm_mm_node *old_mm, *new_mm; | 303 | while (*offset >= (mm_node->size << PAGE_SHIFT)) { |
300 | uint64_t old_start, old_size, new_start, new_size; | 304 | *offset -= (mm_node->size << PAGE_SHIFT); |
301 | unsigned long num_pages; | 305 | ++mm_node; |
302 | struct dma_fence *fence = NULL; | 306 | } |
303 | int r; | 307 | return mm_node; |
308 | } | ||
304 | 309 | ||
305 | BUILD_BUG_ON((PAGE_SIZE % AMDGPU_GPU_PAGE_SIZE) != 0); | 310 | /** |
311 | * amdgpu_copy_ttm_mem_to_mem - Helper function for copy | ||
312 | * | ||
313 | * The function copies @size bytes from {src->mem + src->offset} to | ||
314 | * {dst->mem + dst->offset}. src->bo and dst->bo could be same BO for a | ||
315 | * move and different for a BO to BO copy. | ||
316 | * | ||
317 | * @f: Returns the last fence if multiple jobs are submitted. | ||
318 | */ | ||
319 | int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev, | ||
320 | struct amdgpu_copy_mem *src, | ||
321 | struct amdgpu_copy_mem *dst, | ||
322 | uint64_t size, | ||
323 | struct reservation_object *resv, | ||
324 | struct dma_fence **f) | ||
325 | { | ||
326 | struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring; | ||
327 | struct drm_mm_node *src_mm, *dst_mm; | ||
328 | uint64_t src_node_start, dst_node_start, src_node_size, | ||
329 | dst_node_size, src_page_offset, dst_page_offset; | ||
330 | struct dma_fence *fence = NULL; | ||
331 | int r = 0; | ||
332 | const uint64_t GTT_MAX_BYTES = (AMDGPU_GTT_MAX_TRANSFER_SIZE * | ||
333 | AMDGPU_GPU_PAGE_SIZE); | ||
306 | 334 | ||
307 | if (!ring->ready) { | 335 | if (!ring->ready) { |
308 | DRM_ERROR("Trying to move memory with ring turned off.\n"); | 336 | DRM_ERROR("Trying to move memory with ring turned off.\n"); |
309 | return -EINVAL; | 337 | return -EINVAL; |
310 | } | 338 | } |
311 | 339 | ||
312 | old_mm = old_mem->mm_node; | 340 | src_mm = amdgpu_find_mm_node(src->mem, &src->offset); |
313 | old_size = old_mm->size; | 341 | src_node_start = amdgpu_mm_node_addr(src->bo, src_mm, src->mem) + |
314 | old_start = amdgpu_mm_node_addr(bo, old_mm, old_mem); | 342 | src->offset; |
343 | src_node_size = (src_mm->size << PAGE_SHIFT) - src->offset; | ||
344 | src_page_offset = src_node_start & (PAGE_SIZE - 1); | ||
315 | 345 | ||
316 | new_mm = new_mem->mm_node; | 346 | dst_mm = amdgpu_find_mm_node(dst->mem, &dst->offset); |
317 | new_size = new_mm->size; | 347 | dst_node_start = amdgpu_mm_node_addr(dst->bo, dst_mm, dst->mem) + |
318 | new_start = amdgpu_mm_node_addr(bo, new_mm, new_mem); | 348 | dst->offset; |
349 | dst_node_size = (dst_mm->size << PAGE_SHIFT) - dst->offset; | ||
350 | dst_page_offset = dst_node_start & (PAGE_SIZE - 1); | ||
319 | 351 | ||
320 | num_pages = new_mem->num_pages; | ||
321 | mutex_lock(&adev->mman.gtt_window_lock); | 352 | mutex_lock(&adev->mman.gtt_window_lock); |
322 | while (num_pages) { | 353 | |
323 | unsigned long cur_pages = min(min(old_size, new_size), | 354 | while (size) { |
324 | (u64)AMDGPU_GTT_MAX_TRANSFER_SIZE); | 355 | unsigned long cur_size; |
325 | uint64_t from = old_start, to = new_start; | 356 | uint64_t from = src_node_start, to = dst_node_start; |
326 | struct dma_fence *next; | 357 | struct dma_fence *next; |
327 | 358 | ||
328 | if (old_mem->mem_type == TTM_PL_TT && | 359 | /* Copy size cannot exceed GTT_MAX_BYTES. So if src or dst |
329 | !amdgpu_gtt_mgr_is_allocated(old_mem)) { | 360 | * begins at an offset, then adjust the size accordingly |
330 | r = amdgpu_map_buffer(bo, old_mem, cur_pages, | 361 | */ |
331 | old_start, 0, ring, &from); | 362 | cur_size = min3(min(src_node_size, dst_node_size), size, |
363 | GTT_MAX_BYTES); | ||
364 | if (cur_size + src_page_offset > GTT_MAX_BYTES || | ||
365 | cur_size + dst_page_offset > GTT_MAX_BYTES) | ||
366 | cur_size -= max(src_page_offset, dst_page_offset); | ||
367 | |||
368 | /* Map only what needs to be accessed. Map src to window 0 and | ||
369 | * dst to window 1 | ||
370 | */ | ||
371 | if (src->mem->mem_type == TTM_PL_TT && | ||
372 | !amdgpu_gtt_mgr_is_allocated(src->mem)) { | ||
373 | r = amdgpu_map_buffer(src->bo, src->mem, | ||
374 | PFN_UP(cur_size + src_page_offset), | ||
375 | src_node_start, 0, ring, | ||
376 | &from); | ||
332 | if (r) | 377 | if (r) |
333 | goto error; | 378 | goto error; |
379 | /* Adjust the offset because amdgpu_map_buffer returns | ||
380 | * start of mapped page | ||
381 | */ | ||
382 | from += src_page_offset; | ||
334 | } | 383 | } |
335 | 384 | ||
336 | if (new_mem->mem_type == TTM_PL_TT && | 385 | if (dst->mem->mem_type == TTM_PL_TT && |
337 | !amdgpu_gtt_mgr_is_allocated(new_mem)) { | 386 | !amdgpu_gtt_mgr_is_allocated(dst->mem)) { |
338 | r = amdgpu_map_buffer(bo, new_mem, cur_pages, | 387 | r = amdgpu_map_buffer(dst->bo, dst->mem, |
339 | new_start, 1, ring, &to); | 388 | PFN_UP(cur_size + dst_page_offset), |
389 | dst_node_start, 1, ring, | ||
390 | &to); | ||
340 | if (r) | 391 | if (r) |
341 | goto error; | 392 | goto error; |
393 | to += dst_page_offset; | ||
342 | } | 394 | } |
343 | 395 | ||
344 | r = amdgpu_copy_buffer(ring, from, to, | 396 | r = amdgpu_copy_buffer(ring, from, to, cur_size, |
345 | cur_pages * PAGE_SIZE, | 397 | resv, &next, false, true); |
346 | bo->resv, &next, false, true); | ||
347 | if (r) | 398 | if (r) |
348 | goto error; | 399 | goto error; |
349 | 400 | ||
350 | dma_fence_put(fence); | 401 | dma_fence_put(fence); |
351 | fence = next; | 402 | fence = next; |
352 | 403 | ||
353 | num_pages -= cur_pages; | 404 | size -= cur_size; |
354 | if (!num_pages) | 405 | if (!size) |
355 | break; | 406 | break; |
356 | 407 | ||
357 | old_size -= cur_pages; | 408 | src_node_size -= cur_size; |
358 | if (!old_size) { | 409 | if (!src_node_size) { |
359 | old_start = amdgpu_mm_node_addr(bo, ++old_mm, old_mem); | 410 | src_node_start = amdgpu_mm_node_addr(src->bo, ++src_mm, |
360 | old_size = old_mm->size; | 411 | src->mem); |
412 | src_node_size = (src_mm->size << PAGE_SHIFT); | ||
361 | } else { | 413 | } else { |
362 | old_start += cur_pages * PAGE_SIZE; | 414 | src_node_start += cur_size; |
415 | src_page_offset = src_node_start & (PAGE_SIZE - 1); | ||
363 | } | 416 | } |
364 | 417 | dst_node_size -= cur_size; | |
365 | new_size -= cur_pages; | 418 | if (!dst_node_size) { |
366 | if (!new_size) { | 419 | dst_node_start = amdgpu_mm_node_addr(dst->bo, ++dst_mm, |
367 | new_start = amdgpu_mm_node_addr(bo, ++new_mm, new_mem); | 420 | dst->mem); |
368 | new_size = new_mm->size; | 421 | dst_node_size = (dst_mm->size << PAGE_SHIFT); |
369 | } else { | 422 | } else { |
370 | new_start += cur_pages * PAGE_SIZE; | 423 | dst_node_start += cur_size; |
424 | dst_page_offset = dst_node_start & (PAGE_SIZE - 1); | ||
371 | } | 425 | } |
372 | } | 426 | } |
427 | error: | ||
373 | mutex_unlock(&adev->mman.gtt_window_lock); | 428 | mutex_unlock(&adev->mman.gtt_window_lock); |
429 | if (f) | ||
430 | *f = dma_fence_get(fence); | ||
431 | dma_fence_put(fence); | ||
432 | return r; | ||
433 | } | ||
434 | |||
435 | |||
436 | static int amdgpu_move_blit(struct ttm_buffer_object *bo, | ||
437 | bool evict, bool no_wait_gpu, | ||
438 | struct ttm_mem_reg *new_mem, | ||
439 | struct ttm_mem_reg *old_mem) | ||
440 | { | ||
441 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); | ||
442 | struct amdgpu_copy_mem src, dst; | ||
443 | struct dma_fence *fence = NULL; | ||
444 | int r; | ||
445 | |||
446 | src.bo = bo; | ||
447 | dst.bo = bo; | ||
448 | src.mem = old_mem; | ||
449 | dst.mem = new_mem; | ||
450 | src.offset = 0; | ||
451 | dst.offset = 0; | ||
452 | |||
453 | r = amdgpu_ttm_copy_mem_to_mem(adev, &src, &dst, | ||
454 | new_mem->num_pages << PAGE_SHIFT, | ||
455 | bo->resv, &fence); | ||
456 | if (r) | ||
457 | goto error; | ||
374 | 458 | ||
375 | r = ttm_bo_pipeline_move(bo, fence, evict, new_mem); | 459 | r = ttm_bo_pipeline_move(bo, fence, evict, new_mem); |
376 | dma_fence_put(fence); | 460 | dma_fence_put(fence); |
377 | return r; | 461 | return r; |
378 | 462 | ||
379 | error: | 463 | error: |
380 | mutex_unlock(&adev->mman.gtt_window_lock); | ||
381 | |||
382 | if (fence) | 464 | if (fence) |
383 | dma_fence_wait(fence, false); | 465 | dma_fence_wait(fence, false); |
384 | dma_fence_put(fence); | 466 | dma_fence_put(fence); |
@@ -483,7 +565,7 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, | |||
483 | int r; | 565 | int r; |
484 | 566 | ||
485 | /* Can't move a pinned BO */ | 567 | /* Can't move a pinned BO */ |
486 | abo = container_of(bo, struct amdgpu_bo, tbo); | 568 | abo = ttm_to_amdgpu_bo(bo); |
487 | if (WARN_ON_ONCE(abo->pin_count > 0)) | 569 | if (WARN_ON_ONCE(abo->pin_count > 0)) |
488 | return -EINVAL; | 570 | return -EINVAL; |
489 | 571 | ||
@@ -581,13 +663,12 @@ static void amdgpu_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_re | |||
581 | static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo, | 663 | static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo, |
582 | unsigned long page_offset) | 664 | unsigned long page_offset) |
583 | { | 665 | { |
584 | struct drm_mm_node *mm = bo->mem.mm_node; | 666 | struct drm_mm_node *mm; |
585 | uint64_t size = mm->size; | 667 | unsigned long offset = (page_offset << PAGE_SHIFT); |
586 | uint64_t offset = page_offset; | ||
587 | 668 | ||
588 | page_offset = do_div(offset, size); | 669 | mm = amdgpu_find_mm_node(&bo->mem, &offset); |
589 | mm += offset; | 670 | return (bo->mem.bus.base >> PAGE_SHIFT) + mm->start + |
590 | return (bo->mem.bus.base >> PAGE_SHIFT) + mm->start + page_offset; | 671 | (offset >> PAGE_SHIFT); |
591 | } | 672 | } |
592 | 673 | ||
593 | /* | 674 | /* |
@@ -608,6 +689,7 @@ struct amdgpu_ttm_tt { | |||
608 | spinlock_t guptasklock; | 689 | spinlock_t guptasklock; |
609 | struct list_head guptasks; | 690 | struct list_head guptasks; |
610 | atomic_t mmu_invalidations; | 691 | atomic_t mmu_invalidations; |
692 | uint32_t last_set_pages; | ||
611 | struct list_head list; | 693 | struct list_head list; |
612 | }; | 694 | }; |
613 | 695 | ||
@@ -621,6 +703,8 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages) | |||
621 | if (!(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY)) | 703 | if (!(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY)) |
622 | flags |= FOLL_WRITE; | 704 | flags |= FOLL_WRITE; |
623 | 705 | ||
706 | down_read(¤t->mm->mmap_sem); | ||
707 | |||
624 | if (gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) { | 708 | if (gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) { |
625 | /* check that we only use anonymous memory | 709 | /* check that we only use anonymous memory |
626 | to prevent problems with writeback */ | 710 | to prevent problems with writeback */ |
@@ -628,8 +712,10 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages) | |||
628 | struct vm_area_struct *vma; | 712 | struct vm_area_struct *vma; |
629 | 713 | ||
630 | vma = find_vma(gtt->usermm, gtt->userptr); | 714 | vma = find_vma(gtt->usermm, gtt->userptr); |
631 | if (!vma || vma->vm_file || vma->vm_end < end) | 715 | if (!vma || vma->vm_file || vma->vm_end < end) { |
716 | up_read(¤t->mm->mmap_sem); | ||
632 | return -EPERM; | 717 | return -EPERM; |
718 | } | ||
633 | } | 719 | } |
634 | 720 | ||
635 | do { | 721 | do { |
@@ -656,42 +742,44 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages) | |||
656 | 742 | ||
657 | } while (pinned < ttm->num_pages); | 743 | } while (pinned < ttm->num_pages); |
658 | 744 | ||
745 | up_read(¤t->mm->mmap_sem); | ||
659 | return 0; | 746 | return 0; |
660 | 747 | ||
661 | release_pages: | 748 | release_pages: |
662 | release_pages(pages, pinned, 0); | 749 | release_pages(pages, pinned); |
750 | up_read(¤t->mm->mmap_sem); | ||
663 | return r; | 751 | return r; |
664 | } | 752 | } |
665 | 753 | ||
666 | static void amdgpu_trace_dma_map(struct ttm_tt *ttm) | 754 | void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages) |
667 | { | 755 | { |
668 | struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); | ||
669 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | 756 | struct amdgpu_ttm_tt *gtt = (void *)ttm; |
670 | unsigned i; | 757 | unsigned i; |
671 | 758 | ||
672 | if (unlikely(trace_amdgpu_ttm_tt_populate_enabled())) { | 759 | gtt->last_set_pages = atomic_read(>t->mmu_invalidations); |
673 | for (i = 0; i < ttm->num_pages; i++) { | 760 | for (i = 0; i < ttm->num_pages; ++i) { |
674 | trace_amdgpu_ttm_tt_populate( | 761 | if (ttm->pages[i]) |
675 | adev, | 762 | put_page(ttm->pages[i]); |
676 | gtt->ttm.dma_address[i], | 763 | |
677 | page_to_phys(ttm->pages[i])); | 764 | ttm->pages[i] = pages ? pages[i] : NULL; |
678 | } | ||
679 | } | 765 | } |
680 | } | 766 | } |
681 | 767 | ||
682 | static void amdgpu_trace_dma_unmap(struct ttm_tt *ttm) | 768 | void amdgpu_ttm_tt_mark_user_pages(struct ttm_tt *ttm) |
683 | { | 769 | { |
684 | struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); | ||
685 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | 770 | struct amdgpu_ttm_tt *gtt = (void *)ttm; |
686 | unsigned i; | 771 | unsigned i; |
687 | 772 | ||
688 | if (unlikely(trace_amdgpu_ttm_tt_unpopulate_enabled())) { | 773 | for (i = 0; i < ttm->num_pages; ++i) { |
689 | for (i = 0; i < ttm->num_pages; i++) { | 774 | struct page *page = ttm->pages[i]; |
690 | trace_amdgpu_ttm_tt_unpopulate( | 775 | |
691 | adev, | 776 | if (!page) |
692 | gtt->ttm.dma_address[i], | 777 | continue; |
693 | page_to_phys(ttm->pages[i])); | 778 | |
694 | } | 779 | if (!(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY)) |
780 | set_page_dirty(page); | ||
781 | |||
782 | mark_page_accessed(page); | ||
695 | } | 783 | } |
696 | } | 784 | } |
697 | 785 | ||
@@ -721,8 +809,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm) | |||
721 | drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, | 809 | drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, |
722 | gtt->ttm.dma_address, ttm->num_pages); | 810 | gtt->ttm.dma_address, ttm->num_pages); |
723 | 811 | ||
724 | amdgpu_trace_dma_map(ttm); | ||
725 | |||
726 | return 0; | 812 | return 0; |
727 | 813 | ||
728 | release_sg: | 814 | release_sg: |
@@ -734,7 +820,6 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm) | |||
734 | { | 820 | { |
735 | struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); | 821 | struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); |
736 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | 822 | struct amdgpu_ttm_tt *gtt = (void *)ttm; |
737 | struct sg_page_iter sg_iter; | ||
738 | 823 | ||
739 | int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY); | 824 | int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY); |
740 | enum dma_data_direction direction = write ? | 825 | enum dma_data_direction direction = write ? |
@@ -747,16 +832,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm) | |||
747 | /* free the sg table and pages again */ | 832 | /* free the sg table and pages again */ |
748 | dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction); | 833 | dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction); |
749 | 834 | ||
750 | for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) { | 835 | amdgpu_ttm_tt_mark_user_pages(ttm); |
751 | struct page *page = sg_page_iter_page(&sg_iter); | ||
752 | if (!(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY)) | ||
753 | set_page_dirty(page); | ||
754 | |||
755 | mark_page_accessed(page); | ||
756 | put_page(page); | ||
757 | } | ||
758 | |||
759 | amdgpu_trace_dma_unmap(ttm); | ||
760 | 836 | ||
761 | sg_free_table(ttm->sg); | 837 | sg_free_table(ttm->sg); |
762 | } | 838 | } |
@@ -818,7 +894,6 @@ int amdgpu_ttm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *bo_mem) | |||
818 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); | 894 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); |
819 | struct ttm_tt *ttm = bo->ttm; | 895 | struct ttm_tt *ttm = bo->ttm; |
820 | struct ttm_mem_reg tmp; | 896 | struct ttm_mem_reg tmp; |
821 | |||
822 | struct ttm_placement placement; | 897 | struct ttm_placement placement; |
823 | struct ttm_place placements; | 898 | struct ttm_place placements; |
824 | int r; | 899 | int r; |
@@ -834,7 +909,8 @@ int amdgpu_ttm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *bo_mem) | |||
834 | placement.busy_placement = &placements; | 909 | placement.busy_placement = &placements; |
835 | placements.fpfn = 0; | 910 | placements.fpfn = 0; |
836 | placements.lpfn = adev->mc.gart_size >> PAGE_SHIFT; | 911 | placements.lpfn = adev->mc.gart_size >> PAGE_SHIFT; |
837 | placements.flags = bo->mem.placement | TTM_PL_FLAG_TT; | 912 | placements.flags = (bo->mem.placement & ~TTM_PL_MASK_MEM) | |
913 | TTM_PL_FLAG_TT; | ||
838 | 914 | ||
839 | r = ttm_bo_mem_space(bo, &placement, &tmp, true, false); | 915 | r = ttm_bo_mem_space(bo, &placement, &tmp, true, false); |
840 | if (unlikely(r)) | 916 | if (unlikely(r)) |
@@ -941,8 +1017,6 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm) | |||
941 | { | 1017 | { |
942 | struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); | 1018 | struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); |
943 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | 1019 | struct amdgpu_ttm_tt *gtt = (void *)ttm; |
944 | unsigned i; | ||
945 | int r; | ||
946 | bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); | 1020 | bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); |
947 | 1021 | ||
948 | if (ttm->state != tt_unpopulated) | 1022 | if (ttm->state != tt_unpopulated) |
@@ -962,52 +1036,26 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm) | |||
962 | drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, | 1036 | drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, |
963 | gtt->ttm.dma_address, ttm->num_pages); | 1037 | gtt->ttm.dma_address, ttm->num_pages); |
964 | ttm->state = tt_unbound; | 1038 | ttm->state = tt_unbound; |
965 | r = 0; | 1039 | return 0; |
966 | goto trace_mappings; | ||
967 | } | 1040 | } |
968 | 1041 | ||
969 | #ifdef CONFIG_SWIOTLB | 1042 | #ifdef CONFIG_SWIOTLB |
970 | if (swiotlb_nr_tbl()) { | 1043 | if (swiotlb_nr_tbl()) { |
971 | r = ttm_dma_populate(>t->ttm, adev->dev); | 1044 | return ttm_dma_populate(>t->ttm, adev->dev); |
972 | goto trace_mappings; | ||
973 | } | 1045 | } |
974 | #endif | 1046 | #endif |
975 | 1047 | ||
976 | r = ttm_pool_populate(ttm); | 1048 | return ttm_populate_and_map_pages(adev->dev, >t->ttm); |
977 | if (r) { | ||
978 | return r; | ||
979 | } | ||
980 | |||
981 | for (i = 0; i < ttm->num_pages; i++) { | ||
982 | gtt->ttm.dma_address[i] = pci_map_page(adev->pdev, ttm->pages[i], | ||
983 | 0, PAGE_SIZE, | ||
984 | PCI_DMA_BIDIRECTIONAL); | ||
985 | if (pci_dma_mapping_error(adev->pdev, gtt->ttm.dma_address[i])) { | ||
986 | while (i--) { | ||
987 | pci_unmap_page(adev->pdev, gtt->ttm.dma_address[i], | ||
988 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
989 | gtt->ttm.dma_address[i] = 0; | ||
990 | } | ||
991 | ttm_pool_unpopulate(ttm); | ||
992 | return -EFAULT; | ||
993 | } | ||
994 | } | ||
995 | |||
996 | r = 0; | ||
997 | trace_mappings: | ||
998 | if (likely(!r)) | ||
999 | amdgpu_trace_dma_map(ttm); | ||
1000 | return r; | ||
1001 | } | 1049 | } |
1002 | 1050 | ||
1003 | static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) | 1051 | static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) |
1004 | { | 1052 | { |
1005 | struct amdgpu_device *adev; | 1053 | struct amdgpu_device *adev; |
1006 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | 1054 | struct amdgpu_ttm_tt *gtt = (void *)ttm; |
1007 | unsigned i; | ||
1008 | bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); | 1055 | bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); |
1009 | 1056 | ||
1010 | if (gtt && gtt->userptr) { | 1057 | if (gtt && gtt->userptr) { |
1058 | amdgpu_ttm_tt_set_user_pages(ttm, NULL); | ||
1011 | kfree(ttm->sg); | 1059 | kfree(ttm->sg); |
1012 | ttm->page_flags &= ~TTM_PAGE_FLAG_SG; | 1060 | ttm->page_flags &= ~TTM_PAGE_FLAG_SG; |
1013 | return; | 1061 | return; |
@@ -1018,8 +1066,6 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) | |||
1018 | 1066 | ||
1019 | adev = amdgpu_ttm_adev(ttm->bdev); | 1067 | adev = amdgpu_ttm_adev(ttm->bdev); |
1020 | 1068 | ||
1021 | amdgpu_trace_dma_unmap(ttm); | ||
1022 | |||
1023 | #ifdef CONFIG_SWIOTLB | 1069 | #ifdef CONFIG_SWIOTLB |
1024 | if (swiotlb_nr_tbl()) { | 1070 | if (swiotlb_nr_tbl()) { |
1025 | ttm_dma_unpopulate(>t->ttm, adev->dev); | 1071 | ttm_dma_unpopulate(>t->ttm, adev->dev); |
@@ -1027,14 +1073,7 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) | |||
1027 | } | 1073 | } |
1028 | #endif | 1074 | #endif |
1029 | 1075 | ||
1030 | for (i = 0; i < ttm->num_pages; i++) { | 1076 | ttm_unmap_and_unpopulate_pages(adev->dev, >t->ttm); |
1031 | if (gtt->ttm.dma_address[i]) { | ||
1032 | pci_unmap_page(adev->pdev, gtt->ttm.dma_address[i], | ||
1033 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
1034 | } | ||
1035 | } | ||
1036 | |||
1037 | ttm_pool_unpopulate(ttm); | ||
1038 | } | 1077 | } |
1039 | 1078 | ||
1040 | int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, | 1079 | int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, |
@@ -1051,6 +1090,7 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, | |||
1051 | spin_lock_init(>t->guptasklock); | 1090 | spin_lock_init(>t->guptasklock); |
1052 | INIT_LIST_HEAD(>t->guptasks); | 1091 | INIT_LIST_HEAD(>t->guptasks); |
1053 | atomic_set(>t->mmu_invalidations, 0); | 1092 | atomic_set(>t->mmu_invalidations, 0); |
1093 | gtt->last_set_pages = 0; | ||
1054 | 1094 | ||
1055 | return 0; | 1095 | return 0; |
1056 | } | 1096 | } |
@@ -1103,6 +1143,16 @@ bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, | |||
1103 | return prev_invalidated != *last_invalidated; | 1143 | return prev_invalidated != *last_invalidated; |
1104 | } | 1144 | } |
1105 | 1145 | ||
1146 | bool amdgpu_ttm_tt_userptr_needs_pages(struct ttm_tt *ttm) | ||
1147 | { | ||
1148 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | ||
1149 | |||
1150 | if (gtt == NULL || !gtt->userptr) | ||
1151 | return false; | ||
1152 | |||
1153 | return atomic_read(>t->mmu_invalidations) != gtt->last_set_pages; | ||
1154 | } | ||
1155 | |||
1106 | bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm) | 1156 | bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm) |
1107 | { | 1157 | { |
1108 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | 1158 | struct amdgpu_ttm_tt *gtt = (void *)ttm; |
@@ -1143,9 +1193,6 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, | |||
1143 | unsigned long num_pages = bo->mem.num_pages; | 1193 | unsigned long num_pages = bo->mem.num_pages; |
1144 | struct drm_mm_node *node = bo->mem.mm_node; | 1194 | struct drm_mm_node *node = bo->mem.mm_node; |
1145 | 1195 | ||
1146 | if (bo->mem.start != AMDGPU_BO_INVALID_OFFSET) | ||
1147 | return ttm_bo_eviction_valuable(bo, place); | ||
1148 | |||
1149 | switch (bo->mem.mem_type) { | 1196 | switch (bo->mem.mem_type) { |
1150 | case TTM_PL_TT: | 1197 | case TTM_PL_TT: |
1151 | return true; | 1198 | return true; |
@@ -1160,7 +1207,7 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, | |||
1160 | num_pages -= node->size; | 1207 | num_pages -= node->size; |
1161 | ++node; | 1208 | ++node; |
1162 | } | 1209 | } |
1163 | break; | 1210 | return false; |
1164 | 1211 | ||
1165 | default: | 1212 | default: |
1166 | break; | 1213 | break; |
@@ -1173,9 +1220,9 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo, | |||
1173 | unsigned long offset, | 1220 | unsigned long offset, |
1174 | void *buf, int len, int write) | 1221 | void *buf, int len, int write) |
1175 | { | 1222 | { |
1176 | struct amdgpu_bo *abo = container_of(bo, struct amdgpu_bo, tbo); | 1223 | struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo); |
1177 | struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev); | 1224 | struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev); |
1178 | struct drm_mm_node *nodes = abo->tbo.mem.mm_node; | 1225 | struct drm_mm_node *nodes; |
1179 | uint32_t value = 0; | 1226 | uint32_t value = 0; |
1180 | int ret = 0; | 1227 | int ret = 0; |
1181 | uint64_t pos; | 1228 | uint64_t pos; |
@@ -1184,10 +1231,7 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo, | |||
1184 | if (bo->mem.mem_type != TTM_PL_VRAM) | 1231 | if (bo->mem.mem_type != TTM_PL_VRAM) |
1185 | return -EIO; | 1232 | return -EIO; |
1186 | 1233 | ||
1187 | while (offset >= (nodes->size << PAGE_SHIFT)) { | 1234 | nodes = amdgpu_find_mm_node(&abo->tbo.mem, &offset); |
1188 | offset -= nodes->size << PAGE_SHIFT; | ||
1189 | ++nodes; | ||
1190 | } | ||
1191 | pos = (nodes->start << PAGE_SHIFT) + offset; | 1235 | pos = (nodes->start << PAGE_SHIFT) + offset; |
1192 | 1236 | ||
1193 | while (len && pos < adev->mc.mc_vram_size) { | 1237 | while (len && pos < adev->mc.mc_vram_size) { |
@@ -1202,14 +1246,14 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo, | |||
1202 | } | 1246 | } |
1203 | 1247 | ||
1204 | spin_lock_irqsave(&adev->mmio_idx_lock, flags); | 1248 | spin_lock_irqsave(&adev->mmio_idx_lock, flags); |
1205 | WREG32(mmMM_INDEX, ((uint32_t)aligned_pos) | 0x80000000); | 1249 | WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)aligned_pos) | 0x80000000); |
1206 | WREG32(mmMM_INDEX_HI, aligned_pos >> 31); | 1250 | WREG32_NO_KIQ(mmMM_INDEX_HI, aligned_pos >> 31); |
1207 | if (!write || mask != 0xffffffff) | 1251 | if (!write || mask != 0xffffffff) |
1208 | value = RREG32(mmMM_DATA); | 1252 | value = RREG32_NO_KIQ(mmMM_DATA); |
1209 | if (write) { | 1253 | if (write) { |
1210 | value &= ~mask; | 1254 | value &= ~mask; |
1211 | value |= (*(uint32_t *)buf << shift) & mask; | 1255 | value |= (*(uint32_t *)buf << shift) & mask; |
1212 | WREG32(mmMM_DATA, value); | 1256 | WREG32_NO_KIQ(mmMM_DATA, value); |
1213 | } | 1257 | } |
1214 | spin_unlock_irqrestore(&adev->mmio_idx_lock, flags); | 1258 | spin_unlock_irqrestore(&adev->mmio_idx_lock, flags); |
1215 | if (!write) { | 1259 | if (!write) { |
@@ -1286,6 +1330,15 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) | |||
1286 | /* Change the size here instead of the init above so only lpfn is affected */ | 1330 | /* Change the size here instead of the init above so only lpfn is affected */ |
1287 | amdgpu_ttm_set_active_vram_size(adev, adev->mc.visible_vram_size); | 1331 | amdgpu_ttm_set_active_vram_size(adev, adev->mc.visible_vram_size); |
1288 | 1332 | ||
1333 | /* | ||
1334 | *The reserved vram for firmware must be pinned to the specified | ||
1335 | *place on the VRAM, so reserve it early. | ||
1336 | */ | ||
1337 | r = amdgpu_fw_reserve_vram_init(adev); | ||
1338 | if (r) { | ||
1339 | return r; | ||
1340 | } | ||
1341 | |||
1289 | r = amdgpu_bo_create_kernel(adev, adev->mc.stolen_size, PAGE_SIZE, | 1342 | r = amdgpu_bo_create_kernel(adev, adev->mc.stolen_size, PAGE_SIZE, |
1290 | AMDGPU_GEM_DOMAIN_VRAM, | 1343 | AMDGPU_GEM_DOMAIN_VRAM, |
1291 | &adev->stolen_vga_memory, | 1344 | &adev->stolen_vga_memory, |
@@ -1510,7 +1563,8 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset, | |||
1510 | job->vm_needs_flush = vm_needs_flush; | 1563 | job->vm_needs_flush = vm_needs_flush; |
1511 | if (resv) { | 1564 | if (resv) { |
1512 | r = amdgpu_sync_resv(adev, &job->sync, resv, | 1565 | r = amdgpu_sync_resv(adev, &job->sync, resv, |
1513 | AMDGPU_FENCE_OWNER_UNDEFINED); | 1566 | AMDGPU_FENCE_OWNER_UNDEFINED, |
1567 | false); | ||
1514 | if (r) { | 1568 | if (r) { |
1515 | DRM_ERROR("sync failed (%d).\n", r); | 1569 | DRM_ERROR("sync failed (%d).\n", r); |
1516 | goto error_free; | 1570 | goto error_free; |
@@ -1557,8 +1611,8 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo, | |||
1557 | struct dma_fence **fence) | 1611 | struct dma_fence **fence) |
1558 | { | 1612 | { |
1559 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); | 1613 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); |
1560 | /* max_bytes applies to SDMA_OP_PTEPDE as well as SDMA_OP_CONST_FILL*/ | 1614 | uint32_t max_bytes = 8 * |
1561 | uint32_t max_bytes = adev->mman.buffer_funcs->fill_max_bytes; | 1615 | adev->vm_manager.vm_pte_funcs->set_max_nums_pte_pde; |
1562 | struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring; | 1616 | struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring; |
1563 | 1617 | ||
1564 | struct drm_mm_node *mm_node; | 1618 | struct drm_mm_node *mm_node; |
@@ -1590,8 +1644,8 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo, | |||
1590 | ++mm_node; | 1644 | ++mm_node; |
1591 | } | 1645 | } |
1592 | 1646 | ||
1593 | /* 10 double words for each SDMA_OP_PTEPDE cmd */ | 1647 | /* num of dwords for each SDMA_OP_PTEPDE cmd */ |
1594 | num_dw = num_loops * 10; | 1648 | num_dw = num_loops * adev->vm_manager.vm_pte_funcs->set_pte_pde_num_dw; |
1595 | 1649 | ||
1596 | /* for IB padding */ | 1650 | /* for IB padding */ |
1597 | num_dw += 64; | 1651 | num_dw += 64; |
@@ -1602,7 +1656,7 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo, | |||
1602 | 1656 | ||
1603 | if (resv) { | 1657 | if (resv) { |
1604 | r = amdgpu_sync_resv(adev, &job->sync, resv, | 1658 | r = amdgpu_sync_resv(adev, &job->sync, resv, |
1605 | AMDGPU_FENCE_OWNER_UNDEFINED); | 1659 | AMDGPU_FENCE_OWNER_UNDEFINED, false); |
1606 | if (r) { | 1660 | if (r) { |
1607 | DRM_ERROR("sync failed (%d).\n", r); | 1661 | DRM_ERROR("sync failed (%d).\n", r); |
1608 | goto error_free; | 1662 | goto error_free; |
@@ -1697,9 +1751,9 @@ static ssize_t amdgpu_ttm_vram_read(struct file *f, char __user *buf, | |||
1697 | return result; | 1751 | return result; |
1698 | 1752 | ||
1699 | spin_lock_irqsave(&adev->mmio_idx_lock, flags); | 1753 | spin_lock_irqsave(&adev->mmio_idx_lock, flags); |
1700 | WREG32(mmMM_INDEX, ((uint32_t)*pos) | 0x80000000); | 1754 | WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)*pos) | 0x80000000); |
1701 | WREG32(mmMM_INDEX_HI, *pos >> 31); | 1755 | WREG32_NO_KIQ(mmMM_INDEX_HI, *pos >> 31); |
1702 | value = RREG32(mmMM_DATA); | 1756 | value = RREG32_NO_KIQ(mmMM_DATA); |
1703 | spin_unlock_irqrestore(&adev->mmio_idx_lock, flags); | 1757 | spin_unlock_irqrestore(&adev->mmio_idx_lock, flags); |
1704 | 1758 | ||
1705 | r = put_user(value, (uint32_t *)buf); | 1759 | r = put_user(value, (uint32_t *)buf); |
@@ -1715,10 +1769,50 @@ static ssize_t amdgpu_ttm_vram_read(struct file *f, char __user *buf, | |||
1715 | return result; | 1769 | return result; |
1716 | } | 1770 | } |
1717 | 1771 | ||
1772 | static ssize_t amdgpu_ttm_vram_write(struct file *f, const char __user *buf, | ||
1773 | size_t size, loff_t *pos) | ||
1774 | { | ||
1775 | struct amdgpu_device *adev = file_inode(f)->i_private; | ||
1776 | ssize_t result = 0; | ||
1777 | int r; | ||
1778 | |||
1779 | if (size & 0x3 || *pos & 0x3) | ||
1780 | return -EINVAL; | ||
1781 | |||
1782 | if (*pos >= adev->mc.mc_vram_size) | ||
1783 | return -ENXIO; | ||
1784 | |||
1785 | while (size) { | ||
1786 | unsigned long flags; | ||
1787 | uint32_t value; | ||
1788 | |||
1789 | if (*pos >= adev->mc.mc_vram_size) | ||
1790 | return result; | ||
1791 | |||
1792 | r = get_user(value, (uint32_t *)buf); | ||
1793 | if (r) | ||
1794 | return r; | ||
1795 | |||
1796 | spin_lock_irqsave(&adev->mmio_idx_lock, flags); | ||
1797 | WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)*pos) | 0x80000000); | ||
1798 | WREG32_NO_KIQ(mmMM_INDEX_HI, *pos >> 31); | ||
1799 | WREG32_NO_KIQ(mmMM_DATA, value); | ||
1800 | spin_unlock_irqrestore(&adev->mmio_idx_lock, flags); | ||
1801 | |||
1802 | result += 4; | ||
1803 | buf += 4; | ||
1804 | *pos += 4; | ||
1805 | size -= 4; | ||
1806 | } | ||
1807 | |||
1808 | return result; | ||
1809 | } | ||
1810 | |||
1718 | static const struct file_operations amdgpu_ttm_vram_fops = { | 1811 | static const struct file_operations amdgpu_ttm_vram_fops = { |
1719 | .owner = THIS_MODULE, | 1812 | .owner = THIS_MODULE, |
1720 | .read = amdgpu_ttm_vram_read, | 1813 | .read = amdgpu_ttm_vram_read, |
1721 | .llseek = default_llseek | 1814 | .write = amdgpu_ttm_vram_write, |
1815 | .llseek = default_llseek, | ||
1722 | }; | 1816 | }; |
1723 | 1817 | ||
1724 | #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS | 1818 | #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS |
@@ -1770,6 +1864,53 @@ static const struct file_operations amdgpu_ttm_gtt_fops = { | |||
1770 | 1864 | ||
1771 | #endif | 1865 | #endif |
1772 | 1866 | ||
1867 | static ssize_t amdgpu_iova_to_phys_read(struct file *f, char __user *buf, | ||
1868 | size_t size, loff_t *pos) | ||
1869 | { | ||
1870 | struct amdgpu_device *adev = file_inode(f)->i_private; | ||
1871 | int r; | ||
1872 | uint64_t phys; | ||
1873 | struct iommu_domain *dom; | ||
1874 | |||
1875 | // always return 8 bytes | ||
1876 | if (size != 8) | ||
1877 | return -EINVAL; | ||
1878 | |||
1879 | // only accept page addresses | ||
1880 | if (*pos & 0xFFF) | ||
1881 | return -EINVAL; | ||
1882 | |||
1883 | dom = iommu_get_domain_for_dev(adev->dev); | ||
1884 | if (dom) | ||
1885 | phys = iommu_iova_to_phys(dom, *pos); | ||
1886 | else | ||
1887 | phys = *pos; | ||
1888 | |||
1889 | r = copy_to_user(buf, &phys, 8); | ||
1890 | if (r) | ||
1891 | return -EFAULT; | ||
1892 | |||
1893 | return 8; | ||
1894 | } | ||
1895 | |||
1896 | static const struct file_operations amdgpu_ttm_iova_fops = { | ||
1897 | .owner = THIS_MODULE, | ||
1898 | .read = amdgpu_iova_to_phys_read, | ||
1899 | .llseek = default_llseek | ||
1900 | }; | ||
1901 | |||
1902 | static const struct { | ||
1903 | char *name; | ||
1904 | const struct file_operations *fops; | ||
1905 | int domain; | ||
1906 | } ttm_debugfs_entries[] = { | ||
1907 | { "amdgpu_vram", &amdgpu_ttm_vram_fops, TTM_PL_VRAM }, | ||
1908 | #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS | ||
1909 | { "amdgpu_gtt", &amdgpu_ttm_gtt_fops, TTM_PL_TT }, | ||
1910 | #endif | ||
1911 | { "amdgpu_iova", &amdgpu_ttm_iova_fops, TTM_PL_SYSTEM }, | ||
1912 | }; | ||
1913 | |||
1773 | #endif | 1914 | #endif |
1774 | 1915 | ||
1775 | static int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev) | 1916 | static int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev) |
@@ -1780,22 +1921,21 @@ static int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev) | |||
1780 | struct drm_minor *minor = adev->ddev->primary; | 1921 | struct drm_minor *minor = adev->ddev->primary; |
1781 | struct dentry *ent, *root = minor->debugfs_root; | 1922 | struct dentry *ent, *root = minor->debugfs_root; |
1782 | 1923 | ||
1783 | ent = debugfs_create_file("amdgpu_vram", S_IFREG | S_IRUGO, root, | 1924 | for (count = 0; count < ARRAY_SIZE(ttm_debugfs_entries); count++) { |
1784 | adev, &amdgpu_ttm_vram_fops); | 1925 | ent = debugfs_create_file( |
1785 | if (IS_ERR(ent)) | 1926 | ttm_debugfs_entries[count].name, |
1786 | return PTR_ERR(ent); | 1927 | S_IFREG | S_IRUGO, root, |
1787 | i_size_write(ent->d_inode, adev->mc.mc_vram_size); | 1928 | adev, |
1788 | adev->mman.vram = ent; | 1929 | ttm_debugfs_entries[count].fops); |
1789 | 1930 | if (IS_ERR(ent)) | |
1790 | #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS | 1931 | return PTR_ERR(ent); |
1791 | ent = debugfs_create_file("amdgpu_gtt", S_IFREG | S_IRUGO, root, | 1932 | if (ttm_debugfs_entries[count].domain == TTM_PL_VRAM) |
1792 | adev, &amdgpu_ttm_gtt_fops); | 1933 | i_size_write(ent->d_inode, adev->mc.mc_vram_size); |
1793 | if (IS_ERR(ent)) | 1934 | else if (ttm_debugfs_entries[count].domain == TTM_PL_TT) |
1794 | return PTR_ERR(ent); | 1935 | i_size_write(ent->d_inode, adev->mc.gart_size); |
1795 | i_size_write(ent->d_inode, adev->mc.gart_size); | 1936 | adev->mman.debugfs_entries[count] = ent; |
1796 | adev->mman.gtt = ent; | 1937 | } |
1797 | 1938 | ||
1798 | #endif | ||
1799 | count = ARRAY_SIZE(amdgpu_ttm_debugfs_list); | 1939 | count = ARRAY_SIZE(amdgpu_ttm_debugfs_list); |
1800 | 1940 | ||
1801 | #ifdef CONFIG_SWIOTLB | 1941 | #ifdef CONFIG_SWIOTLB |
@@ -1805,7 +1945,6 @@ static int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev) | |||
1805 | 1945 | ||
1806 | return amdgpu_debugfs_add_files(adev, amdgpu_ttm_debugfs_list, count); | 1946 | return amdgpu_debugfs_add_files(adev, amdgpu_ttm_debugfs_list, count); |
1807 | #else | 1947 | #else |
1808 | |||
1809 | return 0; | 1948 | return 0; |
1810 | #endif | 1949 | #endif |
1811 | } | 1950 | } |
@@ -1813,14 +1952,9 @@ static int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev) | |||
1813 | static void amdgpu_ttm_debugfs_fini(struct amdgpu_device *adev) | 1952 | static void amdgpu_ttm_debugfs_fini(struct amdgpu_device *adev) |
1814 | { | 1953 | { |
1815 | #if defined(CONFIG_DEBUG_FS) | 1954 | #if defined(CONFIG_DEBUG_FS) |
1955 | unsigned i; | ||
1816 | 1956 | ||
1817 | debugfs_remove(adev->mman.vram); | 1957 | for (i = 0; i < ARRAY_SIZE(ttm_debugfs_entries); i++) |
1818 | adev->mman.vram = NULL; | 1958 | debugfs_remove(adev->mman.debugfs_entries[i]); |
1819 | |||
1820 | #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS | ||
1821 | debugfs_remove(adev->mman.gtt); | ||
1822 | adev->mman.gtt = NULL; | ||
1823 | #endif | ||
1824 | |||
1825 | #endif | 1959 | #endif |
1826 | } | 1960 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h index 43093bffa2cf..abd4084982a3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #ifndef __AMDGPU_TTM_H__ | 24 | #ifndef __AMDGPU_TTM_H__ |
25 | #define __AMDGPU_TTM_H__ | 25 | #define __AMDGPU_TTM_H__ |
26 | 26 | ||
27 | #include "amdgpu.h" | ||
27 | #include "gpu_scheduler.h" | 28 | #include "gpu_scheduler.h" |
28 | 29 | ||
29 | #define AMDGPU_PL_GDS (TTM_PL_PRIV + 0) | 30 | #define AMDGPU_PL_GDS (TTM_PL_PRIV + 0) |
@@ -45,8 +46,7 @@ struct amdgpu_mman { | |||
45 | bool initialized; | 46 | bool initialized; |
46 | 47 | ||
47 | #if defined(CONFIG_DEBUG_FS) | 48 | #if defined(CONFIG_DEBUG_FS) |
48 | struct dentry *vram; | 49 | struct dentry *debugfs_entries[8]; |
49 | struct dentry *gtt; | ||
50 | #endif | 50 | #endif |
51 | 51 | ||
52 | /* buffer handling */ | 52 | /* buffer handling */ |
@@ -58,6 +58,12 @@ struct amdgpu_mman { | |||
58 | struct amd_sched_entity entity; | 58 | struct amd_sched_entity entity; |
59 | }; | 59 | }; |
60 | 60 | ||
61 | struct amdgpu_copy_mem { | ||
62 | struct ttm_buffer_object *bo; | ||
63 | struct ttm_mem_reg *mem; | ||
64 | unsigned long offset; | ||
65 | }; | ||
66 | |||
61 | extern const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func; | 67 | extern const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func; |
62 | extern const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func; | 68 | extern const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func; |
63 | 69 | ||
@@ -72,6 +78,12 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset, | |||
72 | struct reservation_object *resv, | 78 | struct reservation_object *resv, |
73 | struct dma_fence **fence, bool direct_submit, | 79 | struct dma_fence **fence, bool direct_submit, |
74 | bool vm_needs_flush); | 80 | bool vm_needs_flush); |
81 | int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev, | ||
82 | struct amdgpu_copy_mem *src, | ||
83 | struct amdgpu_copy_mem *dst, | ||
84 | uint64_t size, | ||
85 | struct reservation_object *resv, | ||
86 | struct dma_fence **f); | ||
75 | int amdgpu_fill_buffer(struct amdgpu_bo *bo, | 87 | int amdgpu_fill_buffer(struct amdgpu_bo *bo, |
76 | uint64_t src_data, | 88 | uint64_t src_data, |
77 | struct reservation_object *resv, | 89 | struct reservation_object *resv, |
@@ -82,4 +94,20 @@ bool amdgpu_ttm_is_bound(struct ttm_tt *ttm); | |||
82 | int amdgpu_ttm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *bo_mem); | 94 | int amdgpu_ttm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *bo_mem); |
83 | int amdgpu_ttm_recover_gart(struct amdgpu_device *adev); | 95 | int amdgpu_ttm_recover_gart(struct amdgpu_device *adev); |
84 | 96 | ||
97 | int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages); | ||
98 | void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages); | ||
99 | void amdgpu_ttm_tt_mark_user_pages(struct ttm_tt *ttm); | ||
100 | int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, | ||
101 | uint32_t flags); | ||
102 | bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm); | ||
103 | struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm); | ||
104 | bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, | ||
105 | unsigned long end); | ||
106 | bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, | ||
107 | int *last_invalidated); | ||
108 | bool amdgpu_ttm_tt_userptr_needs_pages(struct ttm_tt *ttm); | ||
109 | bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm); | ||
110 | uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, | ||
111 | struct ttm_mem_reg *mem); | ||
112 | |||
85 | #endif | 113 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index 36c763310df5..65649026b836 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | |||
@@ -270,12 +270,8 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type) | |||
270 | else | 270 | else |
271 | return AMDGPU_FW_LOAD_SMU; | 271 | return AMDGPU_FW_LOAD_SMU; |
272 | case CHIP_VEGA10: | 272 | case CHIP_VEGA10: |
273 | if (!load_type) | ||
274 | return AMDGPU_FW_LOAD_DIRECT; | ||
275 | else | ||
276 | return AMDGPU_FW_LOAD_PSP; | ||
277 | case CHIP_RAVEN: | 273 | case CHIP_RAVEN: |
278 | if (load_type != 2) | 274 | if (!load_type) |
279 | return AMDGPU_FW_LOAD_DIRECT; | 275 | return AMDGPU_FW_LOAD_DIRECT; |
280 | else | 276 | else |
281 | return AMDGPU_FW_LOAD_PSP; | 277 | return AMDGPU_FW_LOAD_PSP; |
@@ -364,8 +360,6 @@ static int amdgpu_ucode_patch_jt(struct amdgpu_firmware_info *ucode, | |||
364 | int amdgpu_ucode_init_bo(struct amdgpu_device *adev) | 360 | int amdgpu_ucode_init_bo(struct amdgpu_device *adev) |
365 | { | 361 | { |
366 | struct amdgpu_bo **bo = &adev->firmware.fw_buf; | 362 | struct amdgpu_bo **bo = &adev->firmware.fw_buf; |
367 | uint64_t fw_mc_addr; | ||
368 | void *fw_buf_ptr = NULL; | ||
369 | uint64_t fw_offset = 0; | 363 | uint64_t fw_offset = 0; |
370 | int i, err; | 364 | int i, err; |
371 | struct amdgpu_firmware_info *ucode = NULL; | 365 | struct amdgpu_firmware_info *ucode = NULL; |
@@ -376,37 +370,39 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev) | |||
376 | return 0; | 370 | return 0; |
377 | } | 371 | } |
378 | 372 | ||
379 | err = amdgpu_bo_create(adev, adev->firmware.fw_size, PAGE_SIZE, true, | 373 | if (!amdgpu_sriov_vf(adev) || !adev->in_sriov_reset) { |
380 | amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT, | 374 | err = amdgpu_bo_create(adev, adev->firmware.fw_size, PAGE_SIZE, true, |
381 | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, | 375 | amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT, |
382 | NULL, NULL, 0, bo); | 376 | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, |
383 | if (err) { | 377 | NULL, NULL, 0, bo); |
384 | dev_err(adev->dev, "(%d) Firmware buffer allocate failed\n", err); | 378 | if (err) { |
385 | goto failed; | 379 | dev_err(adev->dev, "(%d) Firmware buffer allocate failed\n", err); |
386 | } | 380 | goto failed; |
381 | } | ||
387 | 382 | ||
388 | err = amdgpu_bo_reserve(*bo, false); | 383 | err = amdgpu_bo_reserve(*bo, false); |
389 | if (err) { | 384 | if (err) { |
390 | dev_err(adev->dev, "(%d) Firmware buffer reserve failed\n", err); | 385 | dev_err(adev->dev, "(%d) Firmware buffer reserve failed\n", err); |
391 | goto failed_reserve; | 386 | goto failed_reserve; |
392 | } | 387 | } |
393 | 388 | ||
394 | err = amdgpu_bo_pin(*bo, amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT, | 389 | err = amdgpu_bo_pin(*bo, amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT, |
395 | &fw_mc_addr); | 390 | &adev->firmware.fw_buf_mc); |
396 | if (err) { | 391 | if (err) { |
397 | dev_err(adev->dev, "(%d) Firmware buffer pin failed\n", err); | 392 | dev_err(adev->dev, "(%d) Firmware buffer pin failed\n", err); |
398 | goto failed_pin; | 393 | goto failed_pin; |
399 | } | 394 | } |
400 | 395 | ||
401 | err = amdgpu_bo_kmap(*bo, &fw_buf_ptr); | 396 | err = amdgpu_bo_kmap(*bo, &adev->firmware.fw_buf_ptr); |
402 | if (err) { | 397 | if (err) { |
403 | dev_err(adev->dev, "(%d) Firmware buffer kmap failed\n", err); | 398 | dev_err(adev->dev, "(%d) Firmware buffer kmap failed\n", err); |
404 | goto failed_kmap; | 399 | goto failed_kmap; |
405 | } | 400 | } |
406 | 401 | ||
407 | amdgpu_bo_unreserve(*bo); | 402 | amdgpu_bo_unreserve(*bo); |
403 | } | ||
408 | 404 | ||
409 | memset(fw_buf_ptr, 0, adev->firmware.fw_size); | 405 | memset(adev->firmware.fw_buf_ptr, 0, adev->firmware.fw_size); |
410 | 406 | ||
411 | /* | 407 | /* |
412 | * if SMU loaded firmware, it needn't add SMC, UVD, and VCE | 408 | * if SMU loaded firmware, it needn't add SMC, UVD, and VCE |
@@ -425,14 +421,14 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev) | |||
425 | ucode = &adev->firmware.ucode[i]; | 421 | ucode = &adev->firmware.ucode[i]; |
426 | if (ucode->fw) { | 422 | if (ucode->fw) { |
427 | header = (const struct common_firmware_header *)ucode->fw->data; | 423 | header = (const struct common_firmware_header *)ucode->fw->data; |
428 | amdgpu_ucode_init_single_fw(adev, ucode, fw_mc_addr + fw_offset, | 424 | amdgpu_ucode_init_single_fw(adev, ucode, adev->firmware.fw_buf_mc + fw_offset, |
429 | (void *)((uint8_t *)fw_buf_ptr + fw_offset)); | 425 | adev->firmware.fw_buf_ptr + fw_offset); |
430 | if (i == AMDGPU_UCODE_ID_CP_MEC1 && | 426 | if (i == AMDGPU_UCODE_ID_CP_MEC1 && |
431 | adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { | 427 | adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { |
432 | const struct gfx_firmware_header_v1_0 *cp_hdr; | 428 | const struct gfx_firmware_header_v1_0 *cp_hdr; |
433 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; | 429 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; |
434 | amdgpu_ucode_patch_jt(ucode, fw_mc_addr + fw_offset, | 430 | amdgpu_ucode_patch_jt(ucode, adev->firmware.fw_buf_mc + fw_offset, |
435 | fw_buf_ptr + fw_offset); | 431 | adev->firmware.fw_buf_ptr + fw_offset); |
436 | fw_offset += ALIGN(le32_to_cpu(cp_hdr->jt_size) << 2, PAGE_SIZE); | 432 | fw_offset += ALIGN(le32_to_cpu(cp_hdr->jt_size) << 2, PAGE_SIZE); |
437 | } | 433 | } |
438 | fw_offset += ALIGN(ucode->ucode_size, PAGE_SIZE); | 434 | fw_offset += ALIGN(ucode->ucode_size, PAGE_SIZE); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index e19928dae8e3..e8bd50cf9785 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | |||
@@ -269,6 +269,7 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) | |||
269 | 269 | ||
270 | int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) | 270 | int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) |
271 | { | 271 | { |
272 | int i; | ||
272 | kfree(adev->uvd.saved_bo); | 273 | kfree(adev->uvd.saved_bo); |
273 | 274 | ||
274 | amd_sched_entity_fini(&adev->uvd.ring.sched, &adev->uvd.entity); | 275 | amd_sched_entity_fini(&adev->uvd.ring.sched, &adev->uvd.entity); |
@@ -279,6 +280,9 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) | |||
279 | 280 | ||
280 | amdgpu_ring_fini(&adev->uvd.ring); | 281 | amdgpu_ring_fini(&adev->uvd.ring); |
281 | 282 | ||
283 | for (i = 0; i < AMDGPU_MAX_UVD_ENC_RINGS; ++i) | ||
284 | amdgpu_ring_fini(&adev->uvd.ring_enc[i]); | ||
285 | |||
282 | release_firmware(adev->uvd.fw); | 286 | release_firmware(adev->uvd.fw); |
283 | 287 | ||
284 | return 0; | 288 | return 0; |
@@ -410,10 +414,10 @@ static int amdgpu_uvd_cs_pass1(struct amdgpu_uvd_cs_ctx *ctx) | |||
410 | uint64_t addr = amdgpu_uvd_get_addr_from_ctx(ctx); | 414 | uint64_t addr = amdgpu_uvd_get_addr_from_ctx(ctx); |
411 | int r = 0; | 415 | int r = 0; |
412 | 416 | ||
413 | mapping = amdgpu_cs_find_mapping(ctx->parser, addr, &bo); | 417 | r = amdgpu_cs_find_mapping(ctx->parser, addr, &bo, &mapping); |
414 | if (mapping == NULL) { | 418 | if (r) { |
415 | DRM_ERROR("Can't find BO for addr 0x%08Lx\n", addr); | 419 | DRM_ERROR("Can't find BO for addr 0x%08Lx\n", addr); |
416 | return -EINVAL; | 420 | return r; |
417 | } | 421 | } |
418 | 422 | ||
419 | if (!ctx->parser->adev->uvd.address_64_bit) { | 423 | if (!ctx->parser->adev->uvd.address_64_bit) { |
@@ -737,10 +741,10 @@ static int amdgpu_uvd_cs_pass2(struct amdgpu_uvd_cs_ctx *ctx) | |||
737 | uint64_t addr = amdgpu_uvd_get_addr_from_ctx(ctx); | 741 | uint64_t addr = amdgpu_uvd_get_addr_from_ctx(ctx); |
738 | int r; | 742 | int r; |
739 | 743 | ||
740 | mapping = amdgpu_cs_find_mapping(ctx->parser, addr, &bo); | 744 | r = amdgpu_cs_find_mapping(ctx->parser, addr, &bo, &mapping); |
741 | if (mapping == NULL) { | 745 | if (r) { |
742 | DRM_ERROR("Can't find BO for addr 0x%08Lx\n", addr); | 746 | DRM_ERROR("Can't find BO for addr 0x%08Lx\n", addr); |
743 | return -EINVAL; | 747 | return r; |
744 | } | 748 | } |
745 | 749 | ||
746 | start = amdgpu_bo_gpu_offset(bo); | 750 | start = amdgpu_bo_gpu_offset(bo); |
@@ -917,10 +921,6 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx) | |||
917 | return -EINVAL; | 921 | return -EINVAL; |
918 | } | 922 | } |
919 | 923 | ||
920 | r = amdgpu_cs_sysvm_access_required(parser); | ||
921 | if (r) | ||
922 | return r; | ||
923 | |||
924 | ctx.parser = parser; | 924 | ctx.parser = parser; |
925 | ctx.buf_sizes = buf_sizes; | 925 | ctx.buf_sizes = buf_sizes; |
926 | ctx.ib_idx = ib_idx; | 926 | ctx.ib_idx = ib_idx; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index c855366521ab..2918de2f39ec 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | |||
@@ -559,6 +559,7 @@ static int amdgpu_vce_cs_reloc(struct amdgpu_cs_parser *p, uint32_t ib_idx, | |||
559 | struct amdgpu_bo_va_mapping *mapping; | 559 | struct amdgpu_bo_va_mapping *mapping; |
560 | struct amdgpu_bo *bo; | 560 | struct amdgpu_bo *bo; |
561 | uint64_t addr; | 561 | uint64_t addr; |
562 | int r; | ||
562 | 563 | ||
563 | if (index == 0xffffffff) | 564 | if (index == 0xffffffff) |
564 | index = 0; | 565 | index = 0; |
@@ -567,11 +568,11 @@ static int amdgpu_vce_cs_reloc(struct amdgpu_cs_parser *p, uint32_t ib_idx, | |||
567 | ((uint64_t)amdgpu_get_ib_value(p, ib_idx, hi)) << 32; | 568 | ((uint64_t)amdgpu_get_ib_value(p, ib_idx, hi)) << 32; |
568 | addr += ((uint64_t)size) * ((uint64_t)index); | 569 | addr += ((uint64_t)size) * ((uint64_t)index); |
569 | 570 | ||
570 | mapping = amdgpu_cs_find_mapping(p, addr, &bo); | 571 | r = amdgpu_cs_find_mapping(p, addr, &bo, &mapping); |
571 | if (mapping == NULL) { | 572 | if (r) { |
572 | DRM_ERROR("Can't find BO for addr 0x%010Lx %d %d %d %d\n", | 573 | DRM_ERROR("Can't find BO for addr 0x%010Lx %d %d %d %d\n", |
573 | addr, lo, hi, size, index); | 574 | addr, lo, hi, size, index); |
574 | return -EINVAL; | 575 | return r; |
575 | } | 576 | } |
576 | 577 | ||
577 | if ((addr + (uint64_t)size) > | 578 | if ((addr + (uint64_t)size) > |
@@ -647,15 +648,11 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx) | |||
647 | uint32_t allocated = 0; | 648 | uint32_t allocated = 0; |
648 | uint32_t tmp, handle = 0; | 649 | uint32_t tmp, handle = 0; |
649 | uint32_t *size = &tmp; | 650 | uint32_t *size = &tmp; |
650 | int i, r, idx = 0; | 651 | int i, r = 0, idx = 0; |
651 | 652 | ||
652 | p->job->vm = NULL; | 653 | p->job->vm = NULL; |
653 | ib->gpu_addr = amdgpu_sa_bo_gpu_addr(ib->sa_bo); | 654 | ib->gpu_addr = amdgpu_sa_bo_gpu_addr(ib->sa_bo); |
654 | 655 | ||
655 | r = amdgpu_cs_sysvm_access_required(p); | ||
656 | if (r) | ||
657 | return r; | ||
658 | |||
659 | while (idx < ib->length_dw) { | 656 | while (idx < ib->length_dw) { |
660 | uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx); | 657 | uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx); |
661 | uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1); | 658 | uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c index 45ac91861965..7f7097931c6f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c | |||
@@ -25,30 +25,26 @@ | |||
25 | #include "amdgpu_vf_error.h" | 25 | #include "amdgpu_vf_error.h" |
26 | #include "mxgpu_ai.h" | 26 | #include "mxgpu_ai.h" |
27 | 27 | ||
28 | #define AMDGPU_VF_ERROR_ENTRY_SIZE 16 | 28 | void amdgpu_vf_error_put(struct amdgpu_device *adev, |
29 | 29 | uint16_t sub_error_code, | |
30 | /* struct error_entry - amdgpu VF error information. */ | 30 | uint16_t error_flags, |
31 | struct amdgpu_vf_error_buffer { | 31 | uint64_t error_data) |
32 | int read_count; | ||
33 | int write_count; | ||
34 | uint16_t code[AMDGPU_VF_ERROR_ENTRY_SIZE]; | ||
35 | uint16_t flags[AMDGPU_VF_ERROR_ENTRY_SIZE]; | ||
36 | uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE]; | ||
37 | }; | ||
38 | |||
39 | struct amdgpu_vf_error_buffer admgpu_vf_errors; | ||
40 | |||
41 | |||
42 | void amdgpu_vf_error_put(uint16_t sub_error_code, uint16_t error_flags, uint64_t error_data) | ||
43 | { | 32 | { |
44 | int index; | 33 | int index; |
45 | uint16_t error_code = AMDGIM_ERROR_CODE(AMDGIM_ERROR_CATEGORY_VF, sub_error_code); | 34 | uint16_t error_code; |
46 | 35 | ||
47 | index = admgpu_vf_errors.write_count % AMDGPU_VF_ERROR_ENTRY_SIZE; | 36 | if (!amdgpu_sriov_vf(adev)) |
48 | admgpu_vf_errors.code [index] = error_code; | 37 | return; |
49 | admgpu_vf_errors.flags [index] = error_flags; | 38 | |
50 | admgpu_vf_errors.data [index] = error_data; | 39 | error_code = AMDGIM_ERROR_CODE(AMDGIM_ERROR_CATEGORY_VF, sub_error_code); |
51 | admgpu_vf_errors.write_count ++; | 40 | |
41 | mutex_lock(&adev->virt.vf_errors.lock); | ||
42 | index = adev->virt.vf_errors.write_count % AMDGPU_VF_ERROR_ENTRY_SIZE; | ||
43 | adev->virt.vf_errors.code [index] = error_code; | ||
44 | adev->virt.vf_errors.flags [index] = error_flags; | ||
45 | adev->virt.vf_errors.data [index] = error_data; | ||
46 | adev->virt.vf_errors.write_count ++; | ||
47 | mutex_unlock(&adev->virt.vf_errors.lock); | ||
52 | } | 48 | } |
53 | 49 | ||
54 | 50 | ||
@@ -58,7 +54,8 @@ void amdgpu_vf_error_trans_all(struct amdgpu_device *adev) | |||
58 | u32 data1, data2, data3; | 54 | u32 data1, data2, data3; |
59 | int index; | 55 | int index; |
60 | 56 | ||
61 | if ((NULL == adev) || (!amdgpu_sriov_vf(adev)) || (!adev->virt.ops) || (!adev->virt.ops->trans_msg)) { | 57 | if ((NULL == adev) || (!amdgpu_sriov_vf(adev)) || |
58 | (!adev->virt.ops) || (!adev->virt.ops->trans_msg)) { | ||
62 | return; | 59 | return; |
63 | } | 60 | } |
64 | /* | 61 | /* |
@@ -68,18 +65,22 @@ void amdgpu_vf_error_trans_all(struct amdgpu_device *adev) | |||
68 | return; | 65 | return; |
69 | } | 66 | } |
70 | */ | 67 | */ |
68 | |||
69 | mutex_lock(&adev->virt.vf_errors.lock); | ||
71 | /* The errors are overlay of array, correct read_count as full. */ | 70 | /* The errors are overlay of array, correct read_count as full. */ |
72 | if (admgpu_vf_errors.write_count - admgpu_vf_errors.read_count > AMDGPU_VF_ERROR_ENTRY_SIZE) { | 71 | if (adev->virt.vf_errors.write_count - adev->virt.vf_errors.read_count > AMDGPU_VF_ERROR_ENTRY_SIZE) { |
73 | admgpu_vf_errors.read_count = admgpu_vf_errors.write_count - AMDGPU_VF_ERROR_ENTRY_SIZE; | 72 | adev->virt.vf_errors.read_count = adev->virt.vf_errors.write_count - AMDGPU_VF_ERROR_ENTRY_SIZE; |
74 | } | 73 | } |
75 | 74 | ||
76 | while (admgpu_vf_errors.read_count < admgpu_vf_errors.write_count) { | 75 | while (adev->virt.vf_errors.read_count < adev->virt.vf_errors.write_count) { |
77 | index =admgpu_vf_errors.read_count % AMDGPU_VF_ERROR_ENTRY_SIZE; | 76 | index =adev->virt.vf_errors.read_count % AMDGPU_VF_ERROR_ENTRY_SIZE; |
78 | data1 = AMDGIM_ERROR_CODE_FLAGS_TO_MAILBOX (admgpu_vf_errors.code[index], admgpu_vf_errors.flags[index]); | 77 | data1 = AMDGIM_ERROR_CODE_FLAGS_TO_MAILBOX(adev->virt.vf_errors.code[index], |
79 | data2 = admgpu_vf_errors.data[index] & 0xFFFFFFFF; | 78 | adev->virt.vf_errors.flags[index]); |
80 | data3 = (admgpu_vf_errors.data[index] >> 32) & 0xFFFFFFFF; | 79 | data2 = adev->virt.vf_errors.data[index] & 0xFFFFFFFF; |
80 | data3 = (adev->virt.vf_errors.data[index] >> 32) & 0xFFFFFFFF; | ||
81 | 81 | ||
82 | adev->virt.ops->trans_msg(adev, IDH_LOG_VF_ERROR, data1, data2, data3); | 82 | adev->virt.ops->trans_msg(adev, IDH_LOG_VF_ERROR, data1, data2, data3); |
83 | admgpu_vf_errors.read_count ++; | 83 | adev->virt.vf_errors.read_count ++; |
84 | } | 84 | } |
85 | mutex_unlock(&adev->virt.vf_errors.lock); | ||
85 | } | 86 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h index 2a3278ec76ba..6436bd053325 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h | |||
@@ -56,7 +56,10 @@ enum AMDGIM_ERROR_CATEGORY { | |||
56 | AMDGIM_ERROR_CATEGORY_MAX | 56 | AMDGIM_ERROR_CATEGORY_MAX |
57 | }; | 57 | }; |
58 | 58 | ||
59 | void amdgpu_vf_error_put(uint16_t sub_error_code, uint16_t error_flags, uint64_t error_data); | 59 | void amdgpu_vf_error_put(struct amdgpu_device *adev, |
60 | uint16_t sub_error_code, | ||
61 | uint16_t error_flags, | ||
62 | uint64_t error_data); | ||
60 | void amdgpu_vf_error_trans_all (struct amdgpu_device *adev); | 63 | void amdgpu_vf_error_trans_all (struct amdgpu_device *adev); |
61 | 64 | ||
62 | #endif /* __VF_ERROR_H__ */ | 65 | #endif /* __VF_ERROR_H__ */ |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index ab05121b9272..6738df836a70 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | |||
@@ -22,7 +22,7 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include "amdgpu.h" | 24 | #include "amdgpu.h" |
25 | #define MAX_KIQ_REG_WAIT 100000 | 25 | #define MAX_KIQ_REG_WAIT 100000000 /* in usecs */ |
26 | 26 | ||
27 | int amdgpu_allocate_static_csa(struct amdgpu_device *adev) | 27 | int amdgpu_allocate_static_csa(struct amdgpu_device *adev) |
28 | { | 28 | { |
@@ -114,27 +114,25 @@ void amdgpu_virt_init_setting(struct amdgpu_device *adev) | |||
114 | uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg) | 114 | uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg) |
115 | { | 115 | { |
116 | signed long r; | 116 | signed long r; |
117 | uint32_t val; | 117 | unsigned long flags; |
118 | struct dma_fence *f; | 118 | uint32_t val, seq; |
119 | struct amdgpu_kiq *kiq = &adev->gfx.kiq; | 119 | struct amdgpu_kiq *kiq = &adev->gfx.kiq; |
120 | struct amdgpu_ring *ring = &kiq->ring; | 120 | struct amdgpu_ring *ring = &kiq->ring; |
121 | 121 | ||
122 | BUG_ON(!ring->funcs->emit_rreg); | 122 | BUG_ON(!ring->funcs->emit_rreg); |
123 | 123 | ||
124 | mutex_lock(&kiq->ring_mutex); | 124 | spin_lock_irqsave(&kiq->ring_lock, flags); |
125 | amdgpu_ring_alloc(ring, 32); | 125 | amdgpu_ring_alloc(ring, 32); |
126 | amdgpu_ring_emit_rreg(ring, reg); | 126 | amdgpu_ring_emit_rreg(ring, reg); |
127 | amdgpu_fence_emit(ring, &f); | 127 | amdgpu_fence_emit_polling(ring, &seq); |
128 | amdgpu_ring_commit(ring); | 128 | amdgpu_ring_commit(ring); |
129 | mutex_unlock(&kiq->ring_mutex); | 129 | spin_unlock_irqrestore(&kiq->ring_lock, flags); |
130 | 130 | ||
131 | r = dma_fence_wait_timeout(f, false, msecs_to_jiffies(MAX_KIQ_REG_WAIT)); | 131 | r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); |
132 | dma_fence_put(f); | ||
133 | if (r < 1) { | 132 | if (r < 1) { |
134 | DRM_ERROR("wait for kiq fence error: %ld.\n", r); | 133 | DRM_ERROR("wait for kiq fence error: %ld\n", r); |
135 | return ~0; | 134 | return ~0; |
136 | } | 135 | } |
137 | |||
138 | val = adev->wb.wb[adev->virt.reg_val_offs]; | 136 | val = adev->wb.wb[adev->virt.reg_val_offs]; |
139 | 137 | ||
140 | return val; | 138 | return val; |
@@ -143,23 +141,23 @@ uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg) | |||
143 | void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v) | 141 | void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v) |
144 | { | 142 | { |
145 | signed long r; | 143 | signed long r; |
146 | struct dma_fence *f; | 144 | unsigned long flags; |
145 | uint32_t seq; | ||
147 | struct amdgpu_kiq *kiq = &adev->gfx.kiq; | 146 | struct amdgpu_kiq *kiq = &adev->gfx.kiq; |
148 | struct amdgpu_ring *ring = &kiq->ring; | 147 | struct amdgpu_ring *ring = &kiq->ring; |
149 | 148 | ||
150 | BUG_ON(!ring->funcs->emit_wreg); | 149 | BUG_ON(!ring->funcs->emit_wreg); |
151 | 150 | ||
152 | mutex_lock(&kiq->ring_mutex); | 151 | spin_lock_irqsave(&kiq->ring_lock, flags); |
153 | amdgpu_ring_alloc(ring, 32); | 152 | amdgpu_ring_alloc(ring, 32); |
154 | amdgpu_ring_emit_wreg(ring, reg, v); | 153 | amdgpu_ring_emit_wreg(ring, reg, v); |
155 | amdgpu_fence_emit(ring, &f); | 154 | amdgpu_fence_emit_polling(ring, &seq); |
156 | amdgpu_ring_commit(ring); | 155 | amdgpu_ring_commit(ring); |
157 | mutex_unlock(&kiq->ring_mutex); | 156 | spin_unlock_irqrestore(&kiq->ring_lock, flags); |
158 | 157 | ||
159 | r = dma_fence_wait_timeout(f, false, msecs_to_jiffies(MAX_KIQ_REG_WAIT)); | 158 | r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); |
160 | if (r < 1) | 159 | if (r < 1) |
161 | DRM_ERROR("wait for kiq fence error: %ld.\n", r); | 160 | DRM_ERROR("wait for kiq fence error: %ld\n", r); |
162 | dma_fence_put(f); | ||
163 | } | 161 | } |
164 | 162 | ||
165 | /** | 163 | /** |
@@ -274,3 +272,80 @@ void amdgpu_virt_free_mm_table(struct amdgpu_device *adev) | |||
274 | (void *)&adev->virt.mm_table.cpu_addr); | 272 | (void *)&adev->virt.mm_table.cpu_addr); |
275 | adev->virt.mm_table.gpu_addr = 0; | 273 | adev->virt.mm_table.gpu_addr = 0; |
276 | } | 274 | } |
275 | |||
276 | |||
277 | int amdgpu_virt_fw_reserve_get_checksum(void *obj, | ||
278 | unsigned long obj_size, | ||
279 | unsigned int key, | ||
280 | unsigned int chksum) | ||
281 | { | ||
282 | unsigned int ret = key; | ||
283 | unsigned long i = 0; | ||
284 | unsigned char *pos; | ||
285 | |||
286 | pos = (char *)obj; | ||
287 | /* calculate checksum */ | ||
288 | for (i = 0; i < obj_size; ++i) | ||
289 | ret += *(pos + i); | ||
290 | /* minus the chksum itself */ | ||
291 | pos = (char *)&chksum; | ||
292 | for (i = 0; i < sizeof(chksum); ++i) | ||
293 | ret -= *(pos + i); | ||
294 | return ret; | ||
295 | } | ||
296 | |||
297 | void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev) | ||
298 | { | ||
299 | uint32_t pf2vf_ver = 0; | ||
300 | uint32_t pf2vf_size = 0; | ||
301 | uint32_t checksum = 0; | ||
302 | uint32_t checkval; | ||
303 | char *str; | ||
304 | |||
305 | adev->virt.fw_reserve.p_pf2vf = NULL; | ||
306 | adev->virt.fw_reserve.p_vf2pf = NULL; | ||
307 | |||
308 | if (adev->fw_vram_usage.va != NULL) { | ||
309 | adev->virt.fw_reserve.p_pf2vf = | ||
310 | (struct amdgim_pf2vf_info_header *)( | ||
311 | adev->fw_vram_usage.va + AMDGIM_DATAEXCHANGE_OFFSET); | ||
312 | pf2vf_ver = adev->virt.fw_reserve.p_pf2vf->version; | ||
313 | AMDGPU_FW_VRAM_PF2VF_READ(adev, header.size, &pf2vf_size); | ||
314 | AMDGPU_FW_VRAM_PF2VF_READ(adev, checksum, &checksum); | ||
315 | |||
316 | /* pf2vf message must be in 4K */ | ||
317 | if (pf2vf_size > 0 && pf2vf_size < 4096) { | ||
318 | checkval = amdgpu_virt_fw_reserve_get_checksum( | ||
319 | adev->virt.fw_reserve.p_pf2vf, pf2vf_size, | ||
320 | adev->virt.fw_reserve.checksum_key, checksum); | ||
321 | if (checkval == checksum) { | ||
322 | adev->virt.fw_reserve.p_vf2pf = | ||
323 | ((void *)adev->virt.fw_reserve.p_pf2vf + | ||
324 | pf2vf_size); | ||
325 | memset((void *)adev->virt.fw_reserve.p_vf2pf, 0, | ||
326 | sizeof(amdgim_vf2pf_info)); | ||
327 | AMDGPU_FW_VRAM_VF2PF_WRITE(adev, header.version, | ||
328 | AMDGPU_FW_VRAM_VF2PF_VER); | ||
329 | AMDGPU_FW_VRAM_VF2PF_WRITE(adev, header.size, | ||
330 | sizeof(amdgim_vf2pf_info)); | ||
331 | AMDGPU_FW_VRAM_VF2PF_READ(adev, driver_version, | ||
332 | &str); | ||
333 | #ifdef MODULE | ||
334 | if (THIS_MODULE->version != NULL) | ||
335 | strcpy(str, THIS_MODULE->version); | ||
336 | else | ||
337 | #endif | ||
338 | strcpy(str, "N/A"); | ||
339 | AMDGPU_FW_VRAM_VF2PF_WRITE(adev, driver_cert, | ||
340 | 0); | ||
341 | AMDGPU_FW_VRAM_VF2PF_WRITE(adev, checksum, | ||
342 | amdgpu_virt_fw_reserve_get_checksum( | ||
343 | adev->virt.fw_reserve.p_vf2pf, | ||
344 | pf2vf_size, | ||
345 | adev->virt.fw_reserve.checksum_key, 0)); | ||
346 | } | ||
347 | } | ||
348 | } | ||
349 | } | ||
350 | |||
351 | |||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h index afcfb8bcfb65..b89d37fc406f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | |||
@@ -36,6 +36,18 @@ struct amdgpu_mm_table { | |||
36 | uint64_t gpu_addr; | 36 | uint64_t gpu_addr; |
37 | }; | 37 | }; |
38 | 38 | ||
39 | #define AMDGPU_VF_ERROR_ENTRY_SIZE 16 | ||
40 | |||
41 | /* struct error_entry - amdgpu VF error information. */ | ||
42 | struct amdgpu_vf_error_buffer { | ||
43 | struct mutex lock; | ||
44 | int read_count; | ||
45 | int write_count; | ||
46 | uint16_t code[AMDGPU_VF_ERROR_ENTRY_SIZE]; | ||
47 | uint16_t flags[AMDGPU_VF_ERROR_ENTRY_SIZE]; | ||
48 | uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE]; | ||
49 | }; | ||
50 | |||
39 | /** | 51 | /** |
40 | * struct amdgpu_virt_ops - amdgpu device virt operations | 52 | * struct amdgpu_virt_ops - amdgpu device virt operations |
41 | */ | 53 | */ |
@@ -46,6 +58,179 @@ struct amdgpu_virt_ops { | |||
46 | void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3); | 58 | void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3); |
47 | }; | 59 | }; |
48 | 60 | ||
61 | /* | ||
62 | * Firmware Reserve Frame buffer | ||
63 | */ | ||
64 | struct amdgpu_virt_fw_reserve { | ||
65 | struct amdgim_pf2vf_info_header *p_pf2vf; | ||
66 | struct amdgim_vf2pf_info_header *p_vf2pf; | ||
67 | unsigned int checksum_key; | ||
68 | }; | ||
69 | /* | ||
70 | * Defination between PF and VF | ||
71 | * Structures forcibly aligned to 4 to keep the same style as PF. | ||
72 | */ | ||
73 | #define AMDGIM_DATAEXCHANGE_OFFSET (64 * 1024) | ||
74 | |||
75 | #define AMDGIM_GET_STRUCTURE_RESERVED_SIZE(total, u8, u16, u32, u64) \ | ||
76 | (total - (((u8)+3) / 4 + ((u16)+1) / 2 + (u32) + (u64)*2)) | ||
77 | |||
78 | enum AMDGIM_FEATURE_FLAG { | ||
79 | /* GIM supports feature of Error log collecting */ | ||
80 | AMDGIM_FEATURE_ERROR_LOG_COLLECT = 0x1, | ||
81 | /* GIM supports feature of loading uCodes */ | ||
82 | AMDGIM_FEATURE_GIM_LOAD_UCODES = 0x2, | ||
83 | }; | ||
84 | |||
85 | struct amdgim_pf2vf_info_header { | ||
86 | /* the total structure size in byte. */ | ||
87 | uint32_t size; | ||
88 | /* version of this structure, written by the GIM */ | ||
89 | uint32_t version; | ||
90 | } __aligned(4); | ||
91 | struct amdgim_pf2vf_info_v1 { | ||
92 | /* header contains size and version */ | ||
93 | struct amdgim_pf2vf_info_header header; | ||
94 | /* max_width * max_height */ | ||
95 | unsigned int uvd_enc_max_pixels_count; | ||
96 | /* 16x16 pixels/sec, codec independent */ | ||
97 | unsigned int uvd_enc_max_bandwidth; | ||
98 | /* max_width * max_height */ | ||
99 | unsigned int vce_enc_max_pixels_count; | ||
100 | /* 16x16 pixels/sec, codec independent */ | ||
101 | unsigned int vce_enc_max_bandwidth; | ||
102 | /* MEC FW position in kb from the start of visible frame buffer */ | ||
103 | unsigned int mecfw_kboffset; | ||
104 | /* The features flags of the GIM driver supports. */ | ||
105 | unsigned int feature_flags; | ||
106 | /* use private key from mailbox 2 to create chueksum */ | ||
107 | unsigned int checksum; | ||
108 | } __aligned(4); | ||
109 | |||
110 | struct amdgim_pf2vf_info_v2 { | ||
111 | /* header contains size and version */ | ||
112 | struct amdgim_pf2vf_info_header header; | ||
113 | /* use private key from mailbox 2 to create chueksum */ | ||
114 | uint32_t checksum; | ||
115 | /* The features flags of the GIM driver supports. */ | ||
116 | uint32_t feature_flags; | ||
117 | /* max_width * max_height */ | ||
118 | uint32_t uvd_enc_max_pixels_count; | ||
119 | /* 16x16 pixels/sec, codec independent */ | ||
120 | uint32_t uvd_enc_max_bandwidth; | ||
121 | /* max_width * max_height */ | ||
122 | uint32_t vce_enc_max_pixels_count; | ||
123 | /* 16x16 pixels/sec, codec independent */ | ||
124 | uint32_t vce_enc_max_bandwidth; | ||
125 | /* MEC FW position in kb from the start of VF visible frame buffer */ | ||
126 | uint64_t mecfw_kboffset; | ||
127 | /* MEC FW size in KB */ | ||
128 | uint32_t mecfw_ksize; | ||
129 | /* UVD FW position in kb from the start of VF visible frame buffer */ | ||
130 | uint64_t uvdfw_kboffset; | ||
131 | /* UVD FW size in KB */ | ||
132 | uint32_t uvdfw_ksize; | ||
133 | /* VCE FW position in kb from the start of VF visible frame buffer */ | ||
134 | uint64_t vcefw_kboffset; | ||
135 | /* VCE FW size in KB */ | ||
136 | uint32_t vcefw_ksize; | ||
137 | uint32_t reserved[AMDGIM_GET_STRUCTURE_RESERVED_SIZE(256, 0, 0, (9 + sizeof(struct amdgim_pf2vf_info_header)/sizeof(uint32_t)), 3)]; | ||
138 | } __aligned(4); | ||
139 | |||
140 | |||
141 | struct amdgim_vf2pf_info_header { | ||
142 | /* the total structure size in byte. */ | ||
143 | uint32_t size; | ||
144 | /*version of this structure, written by the guest */ | ||
145 | uint32_t version; | ||
146 | } __aligned(4); | ||
147 | |||
148 | struct amdgim_vf2pf_info_v1 { | ||
149 | /* header contains size and version */ | ||
150 | struct amdgim_vf2pf_info_header header; | ||
151 | /* driver version */ | ||
152 | char driver_version[64]; | ||
153 | /* driver certification, 1=WHQL, 0=None */ | ||
154 | unsigned int driver_cert; | ||
155 | /* guest OS type and version: need a define */ | ||
156 | unsigned int os_info; | ||
157 | /* in the unit of 1M */ | ||
158 | unsigned int fb_usage; | ||
159 | /* guest gfx engine usage percentage */ | ||
160 | unsigned int gfx_usage; | ||
161 | /* guest gfx engine health percentage */ | ||
162 | unsigned int gfx_health; | ||
163 | /* guest compute engine usage percentage */ | ||
164 | unsigned int compute_usage; | ||
165 | /* guest compute engine health percentage */ | ||
166 | unsigned int compute_health; | ||
167 | /* guest vce engine usage percentage. 0xffff means N/A. */ | ||
168 | unsigned int vce_enc_usage; | ||
169 | /* guest vce engine health percentage. 0xffff means N/A. */ | ||
170 | unsigned int vce_enc_health; | ||
171 | /* guest uvd engine usage percentage. 0xffff means N/A. */ | ||
172 | unsigned int uvd_enc_usage; | ||
173 | /* guest uvd engine usage percentage. 0xffff means N/A. */ | ||
174 | unsigned int uvd_enc_health; | ||
175 | unsigned int checksum; | ||
176 | } __aligned(4); | ||
177 | |||
178 | struct amdgim_vf2pf_info_v2 { | ||
179 | /* header contains size and version */ | ||
180 | struct amdgim_vf2pf_info_header header; | ||
181 | uint32_t checksum; | ||
182 | /* driver version */ | ||
183 | uint8_t driver_version[64]; | ||
184 | /* driver certification, 1=WHQL, 0=None */ | ||
185 | uint32_t driver_cert; | ||
186 | /* guest OS type and version: need a define */ | ||
187 | uint32_t os_info; | ||
188 | /* in the unit of 1M */ | ||
189 | uint32_t fb_usage; | ||
190 | /* guest gfx engine usage percentage */ | ||
191 | uint32_t gfx_usage; | ||
192 | /* guest gfx engine health percentage */ | ||
193 | uint32_t gfx_health; | ||
194 | /* guest compute engine usage percentage */ | ||
195 | uint32_t compute_usage; | ||
196 | /* guest compute engine health percentage */ | ||
197 | uint32_t compute_health; | ||
198 | /* guest vce engine usage percentage. 0xffff means N/A. */ | ||
199 | uint32_t vce_enc_usage; | ||
200 | /* guest vce engine health percentage. 0xffff means N/A. */ | ||
201 | uint32_t vce_enc_health; | ||
202 | /* guest uvd engine usage percentage. 0xffff means N/A. */ | ||
203 | uint32_t uvd_enc_usage; | ||
204 | /* guest uvd engine usage percentage. 0xffff means N/A. */ | ||
205 | uint32_t uvd_enc_health; | ||
206 | uint32_t reserved[AMDGIM_GET_STRUCTURE_RESERVED_SIZE(256, 64, 0, (12 + sizeof(struct amdgim_vf2pf_info_header)/sizeof(uint32_t)), 0)]; | ||
207 | } __aligned(4); | ||
208 | |||
209 | #define AMDGPU_FW_VRAM_VF2PF_VER 2 | ||
210 | typedef struct amdgim_vf2pf_info_v2 amdgim_vf2pf_info ; | ||
211 | |||
212 | #define AMDGPU_FW_VRAM_VF2PF_WRITE(adev, field, val) \ | ||
213 | do { \ | ||
214 | ((amdgim_vf2pf_info *)adev->virt.fw_reserve.p_vf2pf)->field = (val); \ | ||
215 | } while (0) | ||
216 | |||
217 | #define AMDGPU_FW_VRAM_VF2PF_READ(adev, field, val) \ | ||
218 | do { \ | ||
219 | (*val) = ((amdgim_vf2pf_info *)adev->virt.fw_reserve.p_vf2pf)->field; \ | ||
220 | } while (0) | ||
221 | |||
222 | #define AMDGPU_FW_VRAM_PF2VF_READ(adev, field, val) \ | ||
223 | do { \ | ||
224 | if (!adev->virt.fw_reserve.p_pf2vf) \ | ||
225 | *(val) = 0; \ | ||
226 | else { \ | ||
227 | if (adev->virt.fw_reserve.p_pf2vf->version == 1) \ | ||
228 | *(val) = ((struct amdgim_pf2vf_info_v1 *)adev->virt.fw_reserve.p_pf2vf)->field; \ | ||
229 | if (adev->virt.fw_reserve.p_pf2vf->version == 2) \ | ||
230 | *(val) = ((struct amdgim_pf2vf_info_v2 *)adev->virt.fw_reserve.p_pf2vf)->field; \ | ||
231 | } \ | ||
232 | } while (0) | ||
233 | |||
49 | /* GPU virtualization */ | 234 | /* GPU virtualization */ |
50 | struct amdgpu_virt { | 235 | struct amdgpu_virt { |
51 | uint32_t caps; | 236 | uint32_t caps; |
@@ -59,6 +244,8 @@ struct amdgpu_virt { | |||
59 | struct work_struct flr_work; | 244 | struct work_struct flr_work; |
60 | struct amdgpu_mm_table mm_table; | 245 | struct amdgpu_mm_table mm_table; |
61 | const struct amdgpu_virt_ops *ops; | 246 | const struct amdgpu_virt_ops *ops; |
247 | struct amdgpu_vf_error_buffer vf_errors; | ||
248 | struct amdgpu_virt_fw_reserve fw_reserve; | ||
62 | }; | 249 | }; |
63 | 250 | ||
64 | #define AMDGPU_CSA_SIZE (8 * 1024) | 251 | #define AMDGPU_CSA_SIZE (8 * 1024) |
@@ -101,5 +288,9 @@ int amdgpu_virt_reset_gpu(struct amdgpu_device *adev); | |||
101 | int amdgpu_sriov_gpu_reset(struct amdgpu_device *adev, struct amdgpu_job *job); | 288 | int amdgpu_sriov_gpu_reset(struct amdgpu_device *adev, struct amdgpu_job *job); |
102 | int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev); | 289 | int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev); |
103 | void amdgpu_virt_free_mm_table(struct amdgpu_device *adev); | 290 | void amdgpu_virt_free_mm_table(struct amdgpu_device *adev); |
291 | int amdgpu_virt_fw_reserve_get_checksum(void *obj, unsigned long obj_size, | ||
292 | unsigned int key, | ||
293 | unsigned int chksum); | ||
294 | void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev); | ||
104 | 295 | ||
105 | #endif | 296 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index bd20ff018512..c8c26f21993c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -27,12 +27,59 @@ | |||
27 | */ | 27 | */ |
28 | #include <linux/dma-fence-array.h> | 28 | #include <linux/dma-fence-array.h> |
29 | #include <linux/interval_tree_generic.h> | 29 | #include <linux/interval_tree_generic.h> |
30 | #include <linux/idr.h> | ||
30 | #include <drm/drmP.h> | 31 | #include <drm/drmP.h> |
31 | #include <drm/amdgpu_drm.h> | 32 | #include <drm/amdgpu_drm.h> |
32 | #include "amdgpu.h" | 33 | #include "amdgpu.h" |
33 | #include "amdgpu_trace.h" | 34 | #include "amdgpu_trace.h" |
34 | 35 | ||
35 | /* | 36 | /* |
37 | * PASID manager | ||
38 | * | ||
39 | * PASIDs are global address space identifiers that can be shared | ||
40 | * between the GPU, an IOMMU and the driver. VMs on different devices | ||
41 | * may use the same PASID if they share the same address | ||
42 | * space. Therefore PASIDs are allocated using a global IDA. VMs are | ||
43 | * looked up from the PASID per amdgpu_device. | ||
44 | */ | ||
45 | static DEFINE_IDA(amdgpu_vm_pasid_ida); | ||
46 | |||
47 | /** | ||
48 | * amdgpu_vm_alloc_pasid - Allocate a PASID | ||
49 | * @bits: Maximum width of the PASID in bits, must be at least 1 | ||
50 | * | ||
51 | * Allocates a PASID of the given width while keeping smaller PASIDs | ||
52 | * available if possible. | ||
53 | * | ||
54 | * Returns a positive integer on success. Returns %-EINVAL if bits==0. | ||
55 | * Returns %-ENOSPC if no PASID was available. Returns %-ENOMEM on | ||
56 | * memory allocation failure. | ||
57 | */ | ||
58 | int amdgpu_vm_alloc_pasid(unsigned int bits) | ||
59 | { | ||
60 | int pasid = -EINVAL; | ||
61 | |||
62 | for (bits = min(bits, 31U); bits > 0; bits--) { | ||
63 | pasid = ida_simple_get(&amdgpu_vm_pasid_ida, | ||
64 | 1U << (bits - 1), 1U << bits, | ||
65 | GFP_KERNEL); | ||
66 | if (pasid != -ENOSPC) | ||
67 | break; | ||
68 | } | ||
69 | |||
70 | return pasid; | ||
71 | } | ||
72 | |||
73 | /** | ||
74 | * amdgpu_vm_free_pasid - Free a PASID | ||
75 | * @pasid: PASID to free | ||
76 | */ | ||
77 | void amdgpu_vm_free_pasid(unsigned int pasid) | ||
78 | { | ||
79 | ida_simple_remove(&amdgpu_vm_pasid_ida, pasid); | ||
80 | } | ||
81 | |||
82 | /* | ||
36 | * GPUVM | 83 | * GPUVM |
37 | * GPUVM is similar to the legacy gart on older asics, however | 84 | * GPUVM is similar to the legacy gart on older asics, however |
38 | * rather than there being a single global gart table | 85 | * rather than there being a single global gart table |
@@ -140,7 +187,7 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, | |||
140 | struct list_head *validated, | 187 | struct list_head *validated, |
141 | struct amdgpu_bo_list_entry *entry) | 188 | struct amdgpu_bo_list_entry *entry) |
142 | { | 189 | { |
143 | entry->robj = vm->root.bo; | 190 | entry->robj = vm->root.base.bo; |
144 | entry->priority = 0; | 191 | entry->priority = 0; |
145 | entry->tv.bo = &entry->robj->tbo; | 192 | entry->tv.bo = &entry->robj->tbo; |
146 | entry->tv.shared = true; | 193 | entry->tv.shared = true; |
@@ -149,86 +196,80 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, | |||
149 | } | 196 | } |
150 | 197 | ||
151 | /** | 198 | /** |
152 | * amdgpu_vm_validate_layer - validate a single page table level | 199 | * amdgpu_vm_validate_pt_bos - validate the page table BOs |
153 | * | 200 | * |
154 | * @parent: parent page table level | 201 | * @adev: amdgpu device pointer |
202 | * @vm: vm providing the BOs | ||
155 | * @validate: callback to do the validation | 203 | * @validate: callback to do the validation |
156 | * @param: parameter for the validation callback | 204 | * @param: parameter for the validation callback |
157 | * | 205 | * |
158 | * Validate the page table BOs on command submission if neccessary. | 206 | * Validate the page table BOs on command submission if neccessary. |
159 | */ | 207 | */ |
160 | static int amdgpu_vm_validate_level(struct amdgpu_vm_pt *parent, | 208 | int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, |
161 | int (*validate)(void *, struct amdgpu_bo *), | 209 | int (*validate)(void *p, struct amdgpu_bo *bo), |
162 | void *param, bool use_cpu_for_update, | 210 | void *param) |
163 | struct ttm_bo_global *glob) | ||
164 | { | 211 | { |
165 | unsigned i; | 212 | struct ttm_bo_global *glob = adev->mman.bdev.glob; |
166 | int r; | 213 | int r; |
167 | 214 | ||
168 | if (use_cpu_for_update) { | 215 | spin_lock(&vm->status_lock); |
169 | r = amdgpu_bo_kmap(parent->bo, NULL); | 216 | while (!list_empty(&vm->evicted)) { |
170 | if (r) | 217 | struct amdgpu_vm_bo_base *bo_base; |
171 | return r; | 218 | struct amdgpu_bo *bo; |
172 | } | ||
173 | |||
174 | if (!parent->entries) | ||
175 | return 0; | ||
176 | 219 | ||
177 | for (i = 0; i <= parent->last_entry_used; ++i) { | 220 | bo_base = list_first_entry(&vm->evicted, |
178 | struct amdgpu_vm_pt *entry = &parent->entries[i]; | 221 | struct amdgpu_vm_bo_base, |
222 | vm_status); | ||
223 | spin_unlock(&vm->status_lock); | ||
179 | 224 | ||
180 | if (!entry->bo) | 225 | bo = bo_base->bo; |
181 | continue; | 226 | BUG_ON(!bo); |
227 | if (bo->parent) { | ||
228 | r = validate(param, bo); | ||
229 | if (r) | ||
230 | return r; | ||
182 | 231 | ||
183 | r = validate(param, entry->bo); | 232 | spin_lock(&glob->lru_lock); |
184 | if (r) | 233 | ttm_bo_move_to_lru_tail(&bo->tbo); |
185 | return r; | 234 | if (bo->shadow) |
235 | ttm_bo_move_to_lru_tail(&bo->shadow->tbo); | ||
236 | spin_unlock(&glob->lru_lock); | ||
237 | } | ||
186 | 238 | ||
187 | spin_lock(&glob->lru_lock); | 239 | if (bo->tbo.type == ttm_bo_type_kernel && |
188 | ttm_bo_move_to_lru_tail(&entry->bo->tbo); | 240 | vm->use_cpu_for_update) { |
189 | if (entry->bo->shadow) | 241 | r = amdgpu_bo_kmap(bo, NULL); |
190 | ttm_bo_move_to_lru_tail(&entry->bo->shadow->tbo); | 242 | if (r) |
191 | spin_unlock(&glob->lru_lock); | 243 | return r; |
244 | } | ||
192 | 245 | ||
193 | /* | 246 | spin_lock(&vm->status_lock); |
194 | * Recurse into the sub directory. This is harmless because we | 247 | if (bo->tbo.type != ttm_bo_type_kernel) |
195 | * have only a maximum of 5 layers. | 248 | list_move(&bo_base->vm_status, &vm->moved); |
196 | */ | 249 | else |
197 | r = amdgpu_vm_validate_level(entry, validate, param, | 250 | list_move(&bo_base->vm_status, &vm->relocated); |
198 | use_cpu_for_update, glob); | ||
199 | if (r) | ||
200 | return r; | ||
201 | } | 251 | } |
252 | spin_unlock(&vm->status_lock); | ||
202 | 253 | ||
203 | return r; | 254 | return 0; |
204 | } | 255 | } |
205 | 256 | ||
206 | /** | 257 | /** |
207 | * amdgpu_vm_validate_pt_bos - validate the page table BOs | 258 | * amdgpu_vm_ready - check VM is ready for updates |
208 | * | 259 | * |
209 | * @adev: amdgpu device pointer | 260 | * @vm: VM to check |
210 | * @vm: vm providing the BOs | ||
211 | * @validate: callback to do the validation | ||
212 | * @param: parameter for the validation callback | ||
213 | * | 261 | * |
214 | * Validate the page table BOs on command submission if neccessary. | 262 | * Check if all VM PDs/PTs are ready for updates |
215 | */ | 263 | */ |
216 | int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, | 264 | bool amdgpu_vm_ready(struct amdgpu_vm *vm) |
217 | int (*validate)(void *p, struct amdgpu_bo *bo), | ||
218 | void *param) | ||
219 | { | 265 | { |
220 | uint64_t num_evictions; | 266 | bool ready; |
221 | 267 | ||
222 | /* We only need to validate the page tables | 268 | spin_lock(&vm->status_lock); |
223 | * if they aren't already valid. | 269 | ready = list_empty(&vm->evicted); |
224 | */ | 270 | spin_unlock(&vm->status_lock); |
225 | num_evictions = atomic64_read(&adev->num_evictions); | ||
226 | if (num_evictions == vm->last_eviction_counter) | ||
227 | return 0; | ||
228 | 271 | ||
229 | return amdgpu_vm_validate_level(&vm->root, validate, param, | 272 | return ready; |
230 | vm->use_cpu_for_update, | ||
231 | adev->mman.bdev.glob); | ||
232 | } | 273 | } |
233 | 274 | ||
234 | /** | 275 | /** |
@@ -287,18 +328,19 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev, | |||
287 | AMDGPU_GEM_CREATE_SHADOW); | 328 | AMDGPU_GEM_CREATE_SHADOW); |
288 | 329 | ||
289 | if (vm->pte_support_ats) { | 330 | if (vm->pte_support_ats) { |
290 | init_value = AMDGPU_PTE_SYSTEM; | 331 | init_value = AMDGPU_PTE_DEFAULT_ATC; |
291 | if (level != adev->vm_manager.num_level - 1) | 332 | if (level != adev->vm_manager.num_level - 1) |
292 | init_value |= AMDGPU_PDE_PTE; | 333 | init_value |= AMDGPU_PDE_PTE; |
334 | |||
293 | } | 335 | } |
294 | 336 | ||
295 | /* walk over the address space and allocate the page tables */ | 337 | /* walk over the address space and allocate the page tables */ |
296 | for (pt_idx = from; pt_idx <= to; ++pt_idx) { | 338 | for (pt_idx = from; pt_idx <= to; ++pt_idx) { |
297 | struct reservation_object *resv = vm->root.bo->tbo.resv; | 339 | struct reservation_object *resv = vm->root.base.bo->tbo.resv; |
298 | struct amdgpu_vm_pt *entry = &parent->entries[pt_idx]; | 340 | struct amdgpu_vm_pt *entry = &parent->entries[pt_idx]; |
299 | struct amdgpu_bo *pt; | 341 | struct amdgpu_bo *pt; |
300 | 342 | ||
301 | if (!entry->bo) { | 343 | if (!entry->base.bo) { |
302 | r = amdgpu_bo_create(adev, | 344 | r = amdgpu_bo_create(adev, |
303 | amdgpu_vm_bo_size(adev, level), | 345 | amdgpu_vm_bo_size(adev, level), |
304 | AMDGPU_GPU_PAGE_SIZE, true, | 346 | AMDGPU_GPU_PAGE_SIZE, true, |
@@ -319,9 +361,14 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev, | |||
319 | /* Keep a reference to the root directory to avoid | 361 | /* Keep a reference to the root directory to avoid |
320 | * freeing them up in the wrong order. | 362 | * freeing them up in the wrong order. |
321 | */ | 363 | */ |
322 | pt->parent = amdgpu_bo_ref(vm->root.bo); | 364 | pt->parent = amdgpu_bo_ref(parent->base.bo); |
323 | 365 | ||
324 | entry->bo = pt; | 366 | entry->base.vm = vm; |
367 | entry->base.bo = pt; | ||
368 | list_add_tail(&entry->base.bo_list, &pt->va); | ||
369 | spin_lock(&vm->status_lock); | ||
370 | list_add(&entry->base.vm_status, &vm->relocated); | ||
371 | spin_unlock(&vm->status_lock); | ||
325 | entry->addr = 0; | 372 | entry->addr = 0; |
326 | } | 373 | } |
327 | 374 | ||
@@ -988,7 +1035,7 @@ static int amdgpu_vm_wait_pd(struct amdgpu_device *adev, struct amdgpu_vm *vm, | |||
988 | int r; | 1035 | int r; |
989 | 1036 | ||
990 | amdgpu_sync_create(&sync); | 1037 | amdgpu_sync_create(&sync); |
991 | amdgpu_sync_resv(adev, &sync, vm->root.bo->tbo.resv, owner); | 1038 | amdgpu_sync_resv(adev, &sync, vm->root.base.bo->tbo.resv, owner, false); |
992 | r = amdgpu_sync_wait(&sync, true); | 1039 | r = amdgpu_sync_wait(&sync, true); |
993 | amdgpu_sync_free(&sync); | 1040 | amdgpu_sync_free(&sync); |
994 | 1041 | ||
@@ -1007,18 +1054,17 @@ static int amdgpu_vm_wait_pd(struct amdgpu_device *adev, struct amdgpu_vm *vm, | |||
1007 | */ | 1054 | */ |
1008 | static int amdgpu_vm_update_level(struct amdgpu_device *adev, | 1055 | static int amdgpu_vm_update_level(struct amdgpu_device *adev, |
1009 | struct amdgpu_vm *vm, | 1056 | struct amdgpu_vm *vm, |
1010 | struct amdgpu_vm_pt *parent, | 1057 | struct amdgpu_vm_pt *parent) |
1011 | unsigned level) | ||
1012 | { | 1058 | { |
1013 | struct amdgpu_bo *shadow; | 1059 | struct amdgpu_bo *shadow; |
1014 | struct amdgpu_ring *ring = NULL; | 1060 | struct amdgpu_ring *ring = NULL; |
1015 | uint64_t pd_addr, shadow_addr = 0; | 1061 | uint64_t pd_addr, shadow_addr = 0; |
1016 | uint32_t incr = amdgpu_vm_bo_size(adev, level + 1); | ||
1017 | uint64_t last_pde = ~0, last_pt = ~0, last_shadow = ~0; | 1062 | uint64_t last_pde = ~0, last_pt = ~0, last_shadow = ~0; |
1018 | unsigned count = 0, pt_idx, ndw = 0; | 1063 | unsigned count = 0, pt_idx, ndw = 0; |
1019 | struct amdgpu_job *job; | 1064 | struct amdgpu_job *job; |
1020 | struct amdgpu_pte_update_params params; | 1065 | struct amdgpu_pte_update_params params; |
1021 | struct dma_fence *fence = NULL; | 1066 | struct dma_fence *fence = NULL; |
1067 | uint32_t incr; | ||
1022 | 1068 | ||
1023 | int r; | 1069 | int r; |
1024 | 1070 | ||
@@ -1027,10 +1073,10 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev, | |||
1027 | 1073 | ||
1028 | memset(¶ms, 0, sizeof(params)); | 1074 | memset(¶ms, 0, sizeof(params)); |
1029 | params.adev = adev; | 1075 | params.adev = adev; |
1030 | shadow = parent->bo->shadow; | 1076 | shadow = parent->base.bo->shadow; |
1031 | 1077 | ||
1032 | if (vm->use_cpu_for_update) { | 1078 | if (vm->use_cpu_for_update) { |
1033 | pd_addr = (unsigned long)amdgpu_bo_kptr(parent->bo); | 1079 | pd_addr = (unsigned long)amdgpu_bo_kptr(parent->base.bo); |
1034 | r = amdgpu_vm_wait_pd(adev, vm, AMDGPU_FENCE_OWNER_VM); | 1080 | r = amdgpu_vm_wait_pd(adev, vm, AMDGPU_FENCE_OWNER_VM); |
1035 | if (unlikely(r)) | 1081 | if (unlikely(r)) |
1036 | return r; | 1082 | return r; |
@@ -1046,7 +1092,7 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev, | |||
1046 | /* assume the worst case */ | 1092 | /* assume the worst case */ |
1047 | ndw += parent->last_entry_used * 6; | 1093 | ndw += parent->last_entry_used * 6; |
1048 | 1094 | ||
1049 | pd_addr = amdgpu_bo_gpu_offset(parent->bo); | 1095 | pd_addr = amdgpu_bo_gpu_offset(parent->base.bo); |
1050 | 1096 | ||
1051 | if (shadow) { | 1097 | if (shadow) { |
1052 | shadow_addr = amdgpu_bo_gpu_offset(shadow); | 1098 | shadow_addr = amdgpu_bo_gpu_offset(shadow); |
@@ -1066,12 +1112,17 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev, | |||
1066 | 1112 | ||
1067 | /* walk over the address space and update the directory */ | 1113 | /* walk over the address space and update the directory */ |
1068 | for (pt_idx = 0; pt_idx <= parent->last_entry_used; ++pt_idx) { | 1114 | for (pt_idx = 0; pt_idx <= parent->last_entry_used; ++pt_idx) { |
1069 | struct amdgpu_bo *bo = parent->entries[pt_idx].bo; | 1115 | struct amdgpu_vm_pt *entry = &parent->entries[pt_idx]; |
1116 | struct amdgpu_bo *bo = entry->base.bo; | ||
1070 | uint64_t pde, pt; | 1117 | uint64_t pde, pt; |
1071 | 1118 | ||
1072 | if (bo == NULL) | 1119 | if (bo == NULL) |
1073 | continue; | 1120 | continue; |
1074 | 1121 | ||
1122 | spin_lock(&vm->status_lock); | ||
1123 | list_del_init(&entry->base.vm_status); | ||
1124 | spin_unlock(&vm->status_lock); | ||
1125 | |||
1075 | pt = amdgpu_bo_gpu_offset(bo); | 1126 | pt = amdgpu_bo_gpu_offset(bo); |
1076 | pt = amdgpu_gart_get_vm_pde(adev, pt); | 1127 | pt = amdgpu_gart_get_vm_pde(adev, pt); |
1077 | /* Don't update huge pages here */ | 1128 | /* Don't update huge pages here */ |
@@ -1082,6 +1133,7 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev, | |||
1082 | parent->entries[pt_idx].addr = pt | AMDGPU_PTE_VALID; | 1133 | parent->entries[pt_idx].addr = pt | AMDGPU_PTE_VALID; |
1083 | 1134 | ||
1084 | pde = pd_addr + pt_idx * 8; | 1135 | pde = pd_addr + pt_idx * 8; |
1136 | incr = amdgpu_bo_size(bo); | ||
1085 | if (((last_pde + 8 * count) != pde) || | 1137 | if (((last_pde + 8 * count) != pde) || |
1086 | ((last_pt + incr * count) != pt) || | 1138 | ((last_pt + incr * count) != pt) || |
1087 | (count == AMDGPU_VM_MAX_UPDATE_SIZE)) { | 1139 | (count == AMDGPU_VM_MAX_UPDATE_SIZE)) { |
@@ -1109,7 +1161,7 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev, | |||
1109 | } | 1161 | } |
1110 | 1162 | ||
1111 | if (count) { | 1163 | if (count) { |
1112 | if (vm->root.bo->shadow) | 1164 | if (vm->root.base.bo->shadow) |
1113 | params.func(¶ms, last_shadow, last_pt, | 1165 | params.func(¶ms, last_shadow, last_pt, |
1114 | count, incr, AMDGPU_PTE_VALID); | 1166 | count, incr, AMDGPU_PTE_VALID); |
1115 | 1167 | ||
@@ -1122,12 +1174,13 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev, | |||
1122 | amdgpu_job_free(job); | 1174 | amdgpu_job_free(job); |
1123 | } else { | 1175 | } else { |
1124 | amdgpu_ring_pad_ib(ring, params.ib); | 1176 | amdgpu_ring_pad_ib(ring, params.ib); |
1125 | amdgpu_sync_resv(adev, &job->sync, parent->bo->tbo.resv, | 1177 | amdgpu_sync_resv(adev, &job->sync, |
1126 | AMDGPU_FENCE_OWNER_VM); | 1178 | parent->base.bo->tbo.resv, |
1179 | AMDGPU_FENCE_OWNER_VM, false); | ||
1127 | if (shadow) | 1180 | if (shadow) |
1128 | amdgpu_sync_resv(adev, &job->sync, | 1181 | amdgpu_sync_resv(adev, &job->sync, |
1129 | shadow->tbo.resv, | 1182 | shadow->tbo.resv, |
1130 | AMDGPU_FENCE_OWNER_VM); | 1183 | AMDGPU_FENCE_OWNER_VM, false); |
1131 | 1184 | ||
1132 | WARN_ON(params.ib->length_dw > ndw); | 1185 | WARN_ON(params.ib->length_dw > ndw); |
1133 | r = amdgpu_job_submit(job, ring, &vm->entity, | 1186 | r = amdgpu_job_submit(job, ring, &vm->entity, |
@@ -1135,26 +1188,11 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev, | |||
1135 | if (r) | 1188 | if (r) |
1136 | goto error_free; | 1189 | goto error_free; |
1137 | 1190 | ||
1138 | amdgpu_bo_fence(parent->bo, fence, true); | 1191 | amdgpu_bo_fence(parent->base.bo, fence, true); |
1139 | dma_fence_put(vm->last_dir_update); | 1192 | dma_fence_put(vm->last_update); |
1140 | vm->last_dir_update = dma_fence_get(fence); | 1193 | vm->last_update = fence; |
1141 | dma_fence_put(fence); | ||
1142 | } | 1194 | } |
1143 | } | 1195 | } |
1144 | /* | ||
1145 | * Recurse into the subdirectories. This recursion is harmless because | ||
1146 | * we only have a maximum of 5 layers. | ||
1147 | */ | ||
1148 | for (pt_idx = 0; pt_idx <= parent->last_entry_used; ++pt_idx) { | ||
1149 | struct amdgpu_vm_pt *entry = &parent->entries[pt_idx]; | ||
1150 | |||
1151 | if (!entry->bo) | ||
1152 | continue; | ||
1153 | |||
1154 | r = amdgpu_vm_update_level(adev, vm, entry, level + 1); | ||
1155 | if (r) | ||
1156 | return r; | ||
1157 | } | ||
1158 | 1196 | ||
1159 | return 0; | 1197 | return 0; |
1160 | 1198 | ||
@@ -1170,7 +1208,8 @@ error_free: | |||
1170 | * | 1208 | * |
1171 | * Mark all PD level as invalid after an error. | 1209 | * Mark all PD level as invalid after an error. |
1172 | */ | 1210 | */ |
1173 | static void amdgpu_vm_invalidate_level(struct amdgpu_vm_pt *parent) | 1211 | static void amdgpu_vm_invalidate_level(struct amdgpu_vm *vm, |
1212 | struct amdgpu_vm_pt *parent) | ||
1174 | { | 1213 | { |
1175 | unsigned pt_idx; | 1214 | unsigned pt_idx; |
1176 | 1215 | ||
@@ -1181,11 +1220,15 @@ static void amdgpu_vm_invalidate_level(struct amdgpu_vm_pt *parent) | |||
1181 | for (pt_idx = 0; pt_idx <= parent->last_entry_used; ++pt_idx) { | 1220 | for (pt_idx = 0; pt_idx <= parent->last_entry_used; ++pt_idx) { |
1182 | struct amdgpu_vm_pt *entry = &parent->entries[pt_idx]; | 1221 | struct amdgpu_vm_pt *entry = &parent->entries[pt_idx]; |
1183 | 1222 | ||
1184 | if (!entry->bo) | 1223 | if (!entry->base.bo) |
1185 | continue; | 1224 | continue; |
1186 | 1225 | ||
1187 | entry->addr = ~0ULL; | 1226 | entry->addr = ~0ULL; |
1188 | amdgpu_vm_invalidate_level(entry); | 1227 | spin_lock(&vm->status_lock); |
1228 | if (list_empty(&entry->base.vm_status)) | ||
1229 | list_add(&entry->base.vm_status, &vm->relocated); | ||
1230 | spin_unlock(&vm->status_lock); | ||
1231 | amdgpu_vm_invalidate_level(vm, entry); | ||
1189 | } | 1232 | } |
1190 | } | 1233 | } |
1191 | 1234 | ||
@@ -1201,11 +1244,40 @@ static void amdgpu_vm_invalidate_level(struct amdgpu_vm_pt *parent) | |||
1201 | int amdgpu_vm_update_directories(struct amdgpu_device *adev, | 1244 | int amdgpu_vm_update_directories(struct amdgpu_device *adev, |
1202 | struct amdgpu_vm *vm) | 1245 | struct amdgpu_vm *vm) |
1203 | { | 1246 | { |
1204 | int r; | 1247 | int r = 0; |
1205 | 1248 | ||
1206 | r = amdgpu_vm_update_level(adev, vm, &vm->root, 0); | 1249 | spin_lock(&vm->status_lock); |
1207 | if (r) | 1250 | while (!list_empty(&vm->relocated)) { |
1208 | amdgpu_vm_invalidate_level(&vm->root); | 1251 | struct amdgpu_vm_bo_base *bo_base; |
1252 | struct amdgpu_bo *bo; | ||
1253 | |||
1254 | bo_base = list_first_entry(&vm->relocated, | ||
1255 | struct amdgpu_vm_bo_base, | ||
1256 | vm_status); | ||
1257 | spin_unlock(&vm->status_lock); | ||
1258 | |||
1259 | bo = bo_base->bo->parent; | ||
1260 | if (bo) { | ||
1261 | struct amdgpu_vm_bo_base *parent; | ||
1262 | struct amdgpu_vm_pt *pt; | ||
1263 | |||
1264 | parent = list_first_entry(&bo->va, | ||
1265 | struct amdgpu_vm_bo_base, | ||
1266 | bo_list); | ||
1267 | pt = container_of(parent, struct amdgpu_vm_pt, base); | ||
1268 | |||
1269 | r = amdgpu_vm_update_level(adev, vm, pt); | ||
1270 | if (r) { | ||
1271 | amdgpu_vm_invalidate_level(vm, &vm->root); | ||
1272 | return r; | ||
1273 | } | ||
1274 | spin_lock(&vm->status_lock); | ||
1275 | } else { | ||
1276 | spin_lock(&vm->status_lock); | ||
1277 | list_del_init(&bo_base->vm_status); | ||
1278 | } | ||
1279 | } | ||
1280 | spin_unlock(&vm->status_lock); | ||
1209 | 1281 | ||
1210 | if (vm->use_cpu_for_update) { | 1282 | if (vm->use_cpu_for_update) { |
1211 | /* Flush HDP */ | 1283 | /* Flush HDP */ |
@@ -1236,7 +1308,7 @@ void amdgpu_vm_get_entry(struct amdgpu_pte_update_params *p, uint64_t addr, | |||
1236 | *entry = &p->vm->root; | 1308 | *entry = &p->vm->root; |
1237 | while ((*entry)->entries) { | 1309 | while ((*entry)->entries) { |
1238 | idx = addr >> (p->adev->vm_manager.block_size * level--); | 1310 | idx = addr >> (p->adev->vm_manager.block_size * level--); |
1239 | idx %= amdgpu_bo_size((*entry)->bo) / 8; | 1311 | idx %= amdgpu_bo_size((*entry)->base.bo) / 8; |
1240 | *parent = *entry; | 1312 | *parent = *entry; |
1241 | *entry = &(*entry)->entries[idx]; | 1313 | *entry = &(*entry)->entries[idx]; |
1242 | } | 1314 | } |
@@ -1272,7 +1344,7 @@ static void amdgpu_vm_handle_huge_pages(struct amdgpu_pte_update_params *p, | |||
1272 | p->src || | 1344 | p->src || |
1273 | !(flags & AMDGPU_PTE_VALID)) { | 1345 | !(flags & AMDGPU_PTE_VALID)) { |
1274 | 1346 | ||
1275 | dst = amdgpu_bo_gpu_offset(entry->bo); | 1347 | dst = amdgpu_bo_gpu_offset(entry->base.bo); |
1276 | dst = amdgpu_gart_get_vm_pde(p->adev, dst); | 1348 | dst = amdgpu_gart_get_vm_pde(p->adev, dst); |
1277 | flags = AMDGPU_PTE_VALID; | 1349 | flags = AMDGPU_PTE_VALID; |
1278 | } else { | 1350 | } else { |
@@ -1298,18 +1370,18 @@ static void amdgpu_vm_handle_huge_pages(struct amdgpu_pte_update_params *p, | |||
1298 | tmp = p->pages_addr; | 1370 | tmp = p->pages_addr; |
1299 | p->pages_addr = NULL; | 1371 | p->pages_addr = NULL; |
1300 | 1372 | ||
1301 | pd_addr = (unsigned long)amdgpu_bo_kptr(parent->bo); | 1373 | pd_addr = (unsigned long)amdgpu_bo_kptr(parent->base.bo); |
1302 | pde = pd_addr + (entry - parent->entries) * 8; | 1374 | pde = pd_addr + (entry - parent->entries) * 8; |
1303 | amdgpu_vm_cpu_set_ptes(p, pde, dst, 1, 0, flags); | 1375 | amdgpu_vm_cpu_set_ptes(p, pde, dst, 1, 0, flags); |
1304 | 1376 | ||
1305 | p->pages_addr = tmp; | 1377 | p->pages_addr = tmp; |
1306 | } else { | 1378 | } else { |
1307 | if (parent->bo->shadow) { | 1379 | if (parent->base.bo->shadow) { |
1308 | pd_addr = amdgpu_bo_gpu_offset(parent->bo->shadow); | 1380 | pd_addr = amdgpu_bo_gpu_offset(parent->base.bo->shadow); |
1309 | pde = pd_addr + (entry - parent->entries) * 8; | 1381 | pde = pd_addr + (entry - parent->entries) * 8; |
1310 | amdgpu_vm_do_set_ptes(p, pde, dst, 1, 0, flags); | 1382 | amdgpu_vm_do_set_ptes(p, pde, dst, 1, 0, flags); |
1311 | } | 1383 | } |
1312 | pd_addr = amdgpu_bo_gpu_offset(parent->bo); | 1384 | pd_addr = amdgpu_bo_gpu_offset(parent->base.bo); |
1313 | pde = pd_addr + (entry - parent->entries) * 8; | 1385 | pde = pd_addr + (entry - parent->entries) * 8; |
1314 | amdgpu_vm_do_set_ptes(p, pde, dst, 1, 0, flags); | 1386 | amdgpu_vm_do_set_ptes(p, pde, dst, 1, 0, flags); |
1315 | } | 1387 | } |
@@ -1360,7 +1432,7 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params, | |||
1360 | if (entry->addr & AMDGPU_PDE_PTE) | 1432 | if (entry->addr & AMDGPU_PDE_PTE) |
1361 | continue; | 1433 | continue; |
1362 | 1434 | ||
1363 | pt = entry->bo; | 1435 | pt = entry->base.bo; |
1364 | if (use_cpu_update) { | 1436 | if (use_cpu_update) { |
1365 | pe_start = (unsigned long)amdgpu_bo_kptr(pt); | 1437 | pe_start = (unsigned long)amdgpu_bo_kptr(pt); |
1366 | } else { | 1438 | } else { |
@@ -1396,8 +1468,6 @@ static int amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params, | |||
1396 | uint64_t start, uint64_t end, | 1468 | uint64_t start, uint64_t end, |
1397 | uint64_t dst, uint64_t flags) | 1469 | uint64_t dst, uint64_t flags) |
1398 | { | 1470 | { |
1399 | int r; | ||
1400 | |||
1401 | /** | 1471 | /** |
1402 | * The MC L1 TLB supports variable sized pages, based on a fragment | 1472 | * The MC L1 TLB supports variable sized pages, based on a fragment |
1403 | * field in the PTE. When this field is set to a non-zero value, page | 1473 | * field in the PTE. When this field is set to a non-zero value, page |
@@ -1416,39 +1486,38 @@ static int amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params, | |||
1416 | * Userspace can support this by aligning virtual base address and | 1486 | * Userspace can support this by aligning virtual base address and |
1417 | * allocation size to the fragment size. | 1487 | * allocation size to the fragment size. |
1418 | */ | 1488 | */ |
1419 | unsigned pages_per_frag = params->adev->vm_manager.fragment_size; | 1489 | unsigned max_frag = params->adev->vm_manager.fragment_size; |
1420 | uint64_t frag_flags = AMDGPU_PTE_FRAG(pages_per_frag); | 1490 | int r; |
1421 | uint64_t frag_align = 1 << pages_per_frag; | ||
1422 | |||
1423 | uint64_t frag_start = ALIGN(start, frag_align); | ||
1424 | uint64_t frag_end = end & ~(frag_align - 1); | ||
1425 | 1491 | ||
1426 | /* system pages are non continuously */ | 1492 | /* system pages are non continuously */ |
1427 | if (params->src || !(flags & AMDGPU_PTE_VALID) || | 1493 | if (params->src || !(flags & AMDGPU_PTE_VALID)) |
1428 | (frag_start >= frag_end)) | ||
1429 | return amdgpu_vm_update_ptes(params, start, end, dst, flags); | 1494 | return amdgpu_vm_update_ptes(params, start, end, dst, flags); |
1430 | 1495 | ||
1431 | /* handle the 4K area at the beginning */ | 1496 | while (start != end) { |
1432 | if (start != frag_start) { | 1497 | uint64_t frag_flags, frag_end; |
1433 | r = amdgpu_vm_update_ptes(params, start, frag_start, | 1498 | unsigned frag; |
1434 | dst, flags); | 1499 | |
1500 | /* This intentionally wraps around if no bit is set */ | ||
1501 | frag = min((unsigned)ffs(start) - 1, | ||
1502 | (unsigned)fls64(end - start) - 1); | ||
1503 | if (frag >= max_frag) { | ||
1504 | frag_flags = AMDGPU_PTE_FRAG(max_frag); | ||
1505 | frag_end = end & ~((1ULL << max_frag) - 1); | ||
1506 | } else { | ||
1507 | frag_flags = AMDGPU_PTE_FRAG(frag); | ||
1508 | frag_end = start + (1 << frag); | ||
1509 | } | ||
1510 | |||
1511 | r = amdgpu_vm_update_ptes(params, start, frag_end, dst, | ||
1512 | flags | frag_flags); | ||
1435 | if (r) | 1513 | if (r) |
1436 | return r; | 1514 | return r; |
1437 | dst += (frag_start - start) * AMDGPU_GPU_PAGE_SIZE; | ||
1438 | } | ||
1439 | 1515 | ||
1440 | /* handle the area in the middle */ | 1516 | dst += (frag_end - start) * AMDGPU_GPU_PAGE_SIZE; |
1441 | r = amdgpu_vm_update_ptes(params, frag_start, frag_end, dst, | 1517 | start = frag_end; |
1442 | flags | frag_flags); | ||
1443 | if (r) | ||
1444 | return r; | ||
1445 | |||
1446 | /* handle the 4K area at the end */ | ||
1447 | if (frag_end != end) { | ||
1448 | dst += (frag_end - frag_start) * AMDGPU_GPU_PAGE_SIZE; | ||
1449 | r = amdgpu_vm_update_ptes(params, frag_end, end, dst, flags); | ||
1450 | } | 1518 | } |
1451 | return r; | 1519 | |
1520 | return 0; | ||
1452 | } | 1521 | } |
1453 | 1522 | ||
1454 | /** | 1523 | /** |
@@ -1456,7 +1525,6 @@ static int amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params, | |||
1456 | * | 1525 | * |
1457 | * @adev: amdgpu_device pointer | 1526 | * @adev: amdgpu_device pointer |
1458 | * @exclusive: fence we need to sync to | 1527 | * @exclusive: fence we need to sync to |
1459 | * @src: address where to copy page table entries from | ||
1460 | * @pages_addr: DMA addresses to use for mapping | 1528 | * @pages_addr: DMA addresses to use for mapping |
1461 | * @vm: requested vm | 1529 | * @vm: requested vm |
1462 | * @start: start of mapped range | 1530 | * @start: start of mapped range |
@@ -1470,7 +1538,6 @@ static int amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params, | |||
1470 | */ | 1538 | */ |
1471 | static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | 1539 | static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, |
1472 | struct dma_fence *exclusive, | 1540 | struct dma_fence *exclusive, |
1473 | uint64_t src, | ||
1474 | dma_addr_t *pages_addr, | 1541 | dma_addr_t *pages_addr, |
1475 | struct amdgpu_vm *vm, | 1542 | struct amdgpu_vm *vm, |
1476 | uint64_t start, uint64_t last, | 1543 | uint64_t start, uint64_t last, |
@@ -1488,7 +1555,6 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
1488 | memset(¶ms, 0, sizeof(params)); | 1555 | memset(¶ms, 0, sizeof(params)); |
1489 | params.adev = adev; | 1556 | params.adev = adev; |
1490 | params.vm = vm; | 1557 | params.vm = vm; |
1491 | params.src = src; | ||
1492 | 1558 | ||
1493 | /* sync to everything on unmapping */ | 1559 | /* sync to everything on unmapping */ |
1494 | if (!(flags & AMDGPU_PTE_VALID)) | 1560 | if (!(flags & AMDGPU_PTE_VALID)) |
@@ -1517,10 +1583,12 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
1517 | nptes = last - start + 1; | 1583 | nptes = last - start + 1; |
1518 | 1584 | ||
1519 | /* | 1585 | /* |
1520 | * reserve space for one command every (1 << BLOCK_SIZE) | 1586 | * reserve space for two commands every (1 << BLOCK_SIZE) |
1521 | * entries or 2k dwords (whatever is smaller) | 1587 | * entries or 2k dwords (whatever is smaller) |
1588 | * | ||
1589 | * The second command is for the shadow pagetables. | ||
1522 | */ | 1590 | */ |
1523 | ncmds = (nptes >> min(adev->vm_manager.block_size, 11u)) + 1; | 1591 | ncmds = ((nptes >> min(adev->vm_manager.block_size, 11u)) + 1) * 2; |
1524 | 1592 | ||
1525 | /* padding, etc. */ | 1593 | /* padding, etc. */ |
1526 | ndw = 64; | 1594 | ndw = 64; |
@@ -1528,15 +1596,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
1528 | /* one PDE write for each huge page */ | 1596 | /* one PDE write for each huge page */ |
1529 | ndw += ((nptes >> adev->vm_manager.block_size) + 1) * 6; | 1597 | ndw += ((nptes >> adev->vm_manager.block_size) + 1) * 6; |
1530 | 1598 | ||
1531 | if (src) { | 1599 | if (pages_addr) { |
1532 | /* only copy commands needed */ | ||
1533 | ndw += ncmds * 7; | ||
1534 | |||
1535 | params.func = amdgpu_vm_do_copy_ptes; | ||
1536 | |||
1537 | } else if (pages_addr) { | ||
1538 | /* copy commands needed */ | 1600 | /* copy commands needed */ |
1539 | ndw += ncmds * 7; | 1601 | ndw += ncmds * adev->vm_manager.vm_pte_funcs->copy_pte_num_dw; |
1540 | 1602 | ||
1541 | /* and also PTEs */ | 1603 | /* and also PTEs */ |
1542 | ndw += nptes * 2; | 1604 | ndw += nptes * 2; |
@@ -1545,10 +1607,11 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
1545 | 1607 | ||
1546 | } else { | 1608 | } else { |
1547 | /* set page commands needed */ | 1609 | /* set page commands needed */ |
1548 | ndw += ncmds * 10; | 1610 | ndw += ncmds * adev->vm_manager.vm_pte_funcs->set_pte_pde_num_dw; |
1549 | 1611 | ||
1550 | /* two extra commands for begin/end of fragment */ | 1612 | /* extra commands for begin/end fragments */ |
1551 | ndw += 2 * 10; | 1613 | ndw += 2 * adev->vm_manager.vm_pte_funcs->set_pte_pde_num_dw |
1614 | * adev->vm_manager.fragment_size; | ||
1552 | 1615 | ||
1553 | params.func = amdgpu_vm_do_set_ptes; | 1616 | params.func = amdgpu_vm_do_set_ptes; |
1554 | } | 1617 | } |
@@ -1559,7 +1622,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
1559 | 1622 | ||
1560 | params.ib = &job->ibs[0]; | 1623 | params.ib = &job->ibs[0]; |
1561 | 1624 | ||
1562 | if (!src && pages_addr) { | 1625 | if (pages_addr) { |
1563 | uint64_t *pte; | 1626 | uint64_t *pte; |
1564 | unsigned i; | 1627 | unsigned i; |
1565 | 1628 | ||
@@ -1580,12 +1643,12 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
1580 | if (r) | 1643 | if (r) |
1581 | goto error_free; | 1644 | goto error_free; |
1582 | 1645 | ||
1583 | r = amdgpu_sync_resv(adev, &job->sync, vm->root.bo->tbo.resv, | 1646 | r = amdgpu_sync_resv(adev, &job->sync, vm->root.base.bo->tbo.resv, |
1584 | owner); | 1647 | owner, false); |
1585 | if (r) | 1648 | if (r) |
1586 | goto error_free; | 1649 | goto error_free; |
1587 | 1650 | ||
1588 | r = reservation_object_reserve_shared(vm->root.bo->tbo.resv); | 1651 | r = reservation_object_reserve_shared(vm->root.base.bo->tbo.resv); |
1589 | if (r) | 1652 | if (r) |
1590 | goto error_free; | 1653 | goto error_free; |
1591 | 1654 | ||
@@ -1600,14 +1663,14 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
1600 | if (r) | 1663 | if (r) |
1601 | goto error_free; | 1664 | goto error_free; |
1602 | 1665 | ||
1603 | amdgpu_bo_fence(vm->root.bo, f, true); | 1666 | amdgpu_bo_fence(vm->root.base.bo, f, true); |
1604 | dma_fence_put(*fence); | 1667 | dma_fence_put(*fence); |
1605 | *fence = f; | 1668 | *fence = f; |
1606 | return 0; | 1669 | return 0; |
1607 | 1670 | ||
1608 | error_free: | 1671 | error_free: |
1609 | amdgpu_job_free(job); | 1672 | amdgpu_job_free(job); |
1610 | amdgpu_vm_invalidate_level(&vm->root); | 1673 | amdgpu_vm_invalidate_level(vm, &vm->root); |
1611 | return r; | 1674 | return r; |
1612 | } | 1675 | } |
1613 | 1676 | ||
@@ -1636,7 +1699,8 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, | |||
1636 | struct drm_mm_node *nodes, | 1699 | struct drm_mm_node *nodes, |
1637 | struct dma_fence **fence) | 1700 | struct dma_fence **fence) |
1638 | { | 1701 | { |
1639 | uint64_t pfn, src = 0, start = mapping->start; | 1702 | unsigned min_linear_pages = 1 << adev->vm_manager.fragment_size; |
1703 | uint64_t pfn, start = mapping->start; | ||
1640 | int r; | 1704 | int r; |
1641 | 1705 | ||
1642 | /* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here | 1706 | /* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here |
@@ -1670,6 +1734,7 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, | |||
1670 | } | 1734 | } |
1671 | 1735 | ||
1672 | do { | 1736 | do { |
1737 | dma_addr_t *dma_addr = NULL; | ||
1673 | uint64_t max_entries; | 1738 | uint64_t max_entries; |
1674 | uint64_t addr, last; | 1739 | uint64_t addr, last; |
1675 | 1740 | ||
@@ -1683,16 +1748,32 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, | |||
1683 | } | 1748 | } |
1684 | 1749 | ||
1685 | if (pages_addr) { | 1750 | if (pages_addr) { |
1751 | uint64_t count; | ||
1752 | |||
1686 | max_entries = min(max_entries, 16ull * 1024ull); | 1753 | max_entries = min(max_entries, 16ull * 1024ull); |
1687 | addr = 0; | 1754 | for (count = 1; count < max_entries; ++count) { |
1755 | uint64_t idx = pfn + count; | ||
1756 | |||
1757 | if (pages_addr[idx] != | ||
1758 | (pages_addr[idx - 1] + PAGE_SIZE)) | ||
1759 | break; | ||
1760 | } | ||
1761 | |||
1762 | if (count < min_linear_pages) { | ||
1763 | addr = pfn << PAGE_SHIFT; | ||
1764 | dma_addr = pages_addr; | ||
1765 | } else { | ||
1766 | addr = pages_addr[pfn]; | ||
1767 | max_entries = count; | ||
1768 | } | ||
1769 | |||
1688 | } else if (flags & AMDGPU_PTE_VALID) { | 1770 | } else if (flags & AMDGPU_PTE_VALID) { |
1689 | addr += adev->vm_manager.vram_base_offset; | 1771 | addr += adev->vm_manager.vram_base_offset; |
1772 | addr += pfn << PAGE_SHIFT; | ||
1690 | } | 1773 | } |
1691 | addr += pfn << PAGE_SHIFT; | ||
1692 | 1774 | ||
1693 | last = min((uint64_t)mapping->last, start + max_entries - 1); | 1775 | last = min((uint64_t)mapping->last, start + max_entries - 1); |
1694 | r = amdgpu_vm_bo_update_mapping(adev, exclusive, | 1776 | r = amdgpu_vm_bo_update_mapping(adev, exclusive, dma_addr, vm, |
1695 | src, pages_addr, vm, | ||
1696 | start, last, flags, addr, | 1777 | start, last, flags, addr, |
1697 | fence); | 1778 | fence); |
1698 | if (r) | 1779 | if (r) |
@@ -1730,7 +1811,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, | |||
1730 | dma_addr_t *pages_addr = NULL; | 1811 | dma_addr_t *pages_addr = NULL; |
1731 | struct ttm_mem_reg *mem; | 1812 | struct ttm_mem_reg *mem; |
1732 | struct drm_mm_node *nodes; | 1813 | struct drm_mm_node *nodes; |
1733 | struct dma_fence *exclusive; | 1814 | struct dma_fence *exclusive, **last_update; |
1734 | uint64_t flags; | 1815 | uint64_t flags; |
1735 | int r; | 1816 | int r; |
1736 | 1817 | ||
@@ -1756,38 +1837,43 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, | |||
1756 | else | 1837 | else |
1757 | flags = 0x0; | 1838 | flags = 0x0; |
1758 | 1839 | ||
1759 | spin_lock(&vm->status_lock); | 1840 | if (clear || (bo && bo->tbo.resv == vm->root.base.bo->tbo.resv)) |
1760 | if (!list_empty(&bo_va->base.vm_status)) | 1841 | last_update = &vm->last_update; |
1842 | else | ||
1843 | last_update = &bo_va->last_pt_update; | ||
1844 | |||
1845 | if (!clear && bo_va->base.moved) { | ||
1846 | bo_va->base.moved = false; | ||
1761 | list_splice_init(&bo_va->valids, &bo_va->invalids); | 1847 | list_splice_init(&bo_va->valids, &bo_va->invalids); |
1762 | spin_unlock(&vm->status_lock); | 1848 | |
1849 | } else if (bo_va->cleared != clear) { | ||
1850 | list_splice_init(&bo_va->valids, &bo_va->invalids); | ||
1851 | } | ||
1763 | 1852 | ||
1764 | list_for_each_entry(mapping, &bo_va->invalids, list) { | 1853 | list_for_each_entry(mapping, &bo_va->invalids, list) { |
1765 | r = amdgpu_vm_bo_split_mapping(adev, exclusive, pages_addr, vm, | 1854 | r = amdgpu_vm_bo_split_mapping(adev, exclusive, pages_addr, vm, |
1766 | mapping, flags, nodes, | 1855 | mapping, flags, nodes, |
1767 | &bo_va->last_pt_update); | 1856 | last_update); |
1768 | if (r) | 1857 | if (r) |
1769 | return r; | 1858 | return r; |
1770 | } | 1859 | } |
1771 | 1860 | ||
1772 | if (trace_amdgpu_vm_bo_mapping_enabled()) { | 1861 | if (vm->use_cpu_for_update) { |
1773 | list_for_each_entry(mapping, &bo_va->valids, list) | 1862 | /* Flush HDP */ |
1774 | trace_amdgpu_vm_bo_mapping(mapping); | 1863 | mb(); |
1775 | 1864 | amdgpu_gart_flush_gpu_tlb(adev, 0); | |
1776 | list_for_each_entry(mapping, &bo_va->invalids, list) | ||
1777 | trace_amdgpu_vm_bo_mapping(mapping); | ||
1778 | } | 1865 | } |
1779 | 1866 | ||
1780 | spin_lock(&vm->status_lock); | 1867 | spin_lock(&vm->status_lock); |
1781 | list_splice_init(&bo_va->invalids, &bo_va->valids); | ||
1782 | list_del_init(&bo_va->base.vm_status); | 1868 | list_del_init(&bo_va->base.vm_status); |
1783 | if (clear) | ||
1784 | list_add(&bo_va->base.vm_status, &vm->cleared); | ||
1785 | spin_unlock(&vm->status_lock); | 1869 | spin_unlock(&vm->status_lock); |
1786 | 1870 | ||
1787 | if (vm->use_cpu_for_update) { | 1871 | list_splice_init(&bo_va->invalids, &bo_va->valids); |
1788 | /* Flush HDP */ | 1872 | bo_va->cleared = clear; |
1789 | mb(); | 1873 | |
1790 | amdgpu_gart_flush_gpu_tlb(adev, 0); | 1874 | if (trace_amdgpu_vm_bo_mapping_enabled()) { |
1875 | list_for_each_entry(mapping, &bo_va->valids, list) | ||
1876 | trace_amdgpu_vm_bo_mapping(mapping); | ||
1791 | } | 1877 | } |
1792 | 1878 | ||
1793 | return 0; | 1879 | return 0; |
@@ -1895,7 +1981,7 @@ static void amdgpu_vm_free_mapping(struct amdgpu_device *adev, | |||
1895 | */ | 1981 | */ |
1896 | static void amdgpu_vm_prt_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) | 1982 | static void amdgpu_vm_prt_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) |
1897 | { | 1983 | { |
1898 | struct reservation_object *resv = vm->root.bo->tbo.resv; | 1984 | struct reservation_object *resv = vm->root.base.bo->tbo.resv; |
1899 | struct dma_fence *excl, **shared; | 1985 | struct dma_fence *excl, **shared; |
1900 | unsigned i, shared_count; | 1986 | unsigned i, shared_count; |
1901 | int r; | 1987 | int r; |
@@ -1951,9 +2037,9 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, | |||
1951 | list_del(&mapping->list); | 2037 | list_del(&mapping->list); |
1952 | 2038 | ||
1953 | if (vm->pte_support_ats) | 2039 | if (vm->pte_support_ats) |
1954 | init_pte_value = AMDGPU_PTE_SYSTEM; | 2040 | init_pte_value = AMDGPU_PTE_DEFAULT_ATC; |
1955 | 2041 | ||
1956 | r = amdgpu_vm_bo_update_mapping(adev, NULL, 0, NULL, vm, | 2042 | r = amdgpu_vm_bo_update_mapping(adev, NULL, NULL, vm, |
1957 | mapping->start, mapping->last, | 2043 | mapping->start, mapping->last, |
1958 | init_pte_value, 0, &f); | 2044 | init_pte_value, 0, &f); |
1959 | amdgpu_vm_free_mapping(adev, vm, mapping, f); | 2045 | amdgpu_vm_free_mapping(adev, vm, mapping, f); |
@@ -1975,29 +2061,35 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, | |||
1975 | } | 2061 | } |
1976 | 2062 | ||
1977 | /** | 2063 | /** |
1978 | * amdgpu_vm_clear_moved - clear moved BOs in the PT | 2064 | * amdgpu_vm_handle_moved - handle moved BOs in the PT |
1979 | * | 2065 | * |
1980 | * @adev: amdgpu_device pointer | 2066 | * @adev: amdgpu_device pointer |
1981 | * @vm: requested vm | 2067 | * @vm: requested vm |
2068 | * @sync: sync object to add fences to | ||
1982 | * | 2069 | * |
1983 | * Make sure all moved BOs are cleared in the PT. | 2070 | * Make sure all BOs which are moved are updated in the PTs. |
1984 | * Returns 0 for success. | 2071 | * Returns 0 for success. |
1985 | * | 2072 | * |
1986 | * PTs have to be reserved and mutex must be locked! | 2073 | * PTs have to be reserved! |
1987 | */ | 2074 | */ |
1988 | int amdgpu_vm_clear_moved(struct amdgpu_device *adev, struct amdgpu_vm *vm, | 2075 | int amdgpu_vm_handle_moved(struct amdgpu_device *adev, |
1989 | struct amdgpu_sync *sync) | 2076 | struct amdgpu_vm *vm) |
1990 | { | 2077 | { |
1991 | struct amdgpu_bo_va *bo_va = NULL; | 2078 | bool clear; |
1992 | int r = 0; | 2079 | int r = 0; |
1993 | 2080 | ||
1994 | spin_lock(&vm->status_lock); | 2081 | spin_lock(&vm->status_lock); |
1995 | while (!list_empty(&vm->moved)) { | 2082 | while (!list_empty(&vm->moved)) { |
2083 | struct amdgpu_bo_va *bo_va; | ||
2084 | |||
1996 | bo_va = list_first_entry(&vm->moved, | 2085 | bo_va = list_first_entry(&vm->moved, |
1997 | struct amdgpu_bo_va, base.vm_status); | 2086 | struct amdgpu_bo_va, base.vm_status); |
1998 | spin_unlock(&vm->status_lock); | 2087 | spin_unlock(&vm->status_lock); |
1999 | 2088 | ||
2000 | r = amdgpu_vm_bo_update(adev, bo_va, true); | 2089 | /* Per VM BOs never need to bo cleared in the page tables */ |
2090 | clear = bo_va->base.bo->tbo.resv != vm->root.base.bo->tbo.resv; | ||
2091 | |||
2092 | r = amdgpu_vm_bo_update(adev, bo_va, clear); | ||
2001 | if (r) | 2093 | if (r) |
2002 | return r; | 2094 | return r; |
2003 | 2095 | ||
@@ -2005,9 +2097,6 @@ int amdgpu_vm_clear_moved(struct amdgpu_device *adev, struct amdgpu_vm *vm, | |||
2005 | } | 2097 | } |
2006 | spin_unlock(&vm->status_lock); | 2098 | spin_unlock(&vm->status_lock); |
2007 | 2099 | ||
2008 | if (bo_va) | ||
2009 | r = amdgpu_sync_fence(adev, sync, bo_va->last_pt_update); | ||
2010 | |||
2011 | return r; | 2100 | return r; |
2012 | } | 2101 | } |
2013 | 2102 | ||
@@ -2049,6 +2138,39 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, | |||
2049 | return bo_va; | 2138 | return bo_va; |
2050 | } | 2139 | } |
2051 | 2140 | ||
2141 | |||
2142 | /** | ||
2143 | * amdgpu_vm_bo_insert_mapping - insert a new mapping | ||
2144 | * | ||
2145 | * @adev: amdgpu_device pointer | ||
2146 | * @bo_va: bo_va to store the address | ||
2147 | * @mapping: the mapping to insert | ||
2148 | * | ||
2149 | * Insert a new mapping into all structures. | ||
2150 | */ | ||
2151 | static void amdgpu_vm_bo_insert_map(struct amdgpu_device *adev, | ||
2152 | struct amdgpu_bo_va *bo_va, | ||
2153 | struct amdgpu_bo_va_mapping *mapping) | ||
2154 | { | ||
2155 | struct amdgpu_vm *vm = bo_va->base.vm; | ||
2156 | struct amdgpu_bo *bo = bo_va->base.bo; | ||
2157 | |||
2158 | mapping->bo_va = bo_va; | ||
2159 | list_add(&mapping->list, &bo_va->invalids); | ||
2160 | amdgpu_vm_it_insert(mapping, &vm->va); | ||
2161 | |||
2162 | if (mapping->flags & AMDGPU_PTE_PRT) | ||
2163 | amdgpu_vm_prt_get(adev); | ||
2164 | |||
2165 | if (bo && bo->tbo.resv == vm->root.base.bo->tbo.resv) { | ||
2166 | spin_lock(&vm->status_lock); | ||
2167 | if (list_empty(&bo_va->base.vm_status)) | ||
2168 | list_add(&bo_va->base.vm_status, &vm->moved); | ||
2169 | spin_unlock(&vm->status_lock); | ||
2170 | } | ||
2171 | trace_amdgpu_vm_bo_map(bo_va, mapping); | ||
2172 | } | ||
2173 | |||
2052 | /** | 2174 | /** |
2053 | * amdgpu_vm_bo_map - map bo inside a vm | 2175 | * amdgpu_vm_bo_map - map bo inside a vm |
2054 | * | 2176 | * |
@@ -2100,17 +2222,12 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, | |||
2100 | if (!mapping) | 2222 | if (!mapping) |
2101 | return -ENOMEM; | 2223 | return -ENOMEM; |
2102 | 2224 | ||
2103 | INIT_LIST_HEAD(&mapping->list); | ||
2104 | mapping->start = saddr; | 2225 | mapping->start = saddr; |
2105 | mapping->last = eaddr; | 2226 | mapping->last = eaddr; |
2106 | mapping->offset = offset; | 2227 | mapping->offset = offset; |
2107 | mapping->flags = flags; | 2228 | mapping->flags = flags; |
2108 | 2229 | ||
2109 | list_add(&mapping->list, &bo_va->invalids); | 2230 | amdgpu_vm_bo_insert_map(adev, bo_va, mapping); |
2110 | amdgpu_vm_it_insert(mapping, &vm->va); | ||
2111 | |||
2112 | if (flags & AMDGPU_PTE_PRT) | ||
2113 | amdgpu_vm_prt_get(adev); | ||
2114 | 2231 | ||
2115 | return 0; | 2232 | return 0; |
2116 | } | 2233 | } |
@@ -2137,7 +2254,6 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev, | |||
2137 | { | 2254 | { |
2138 | struct amdgpu_bo_va_mapping *mapping; | 2255 | struct amdgpu_bo_va_mapping *mapping; |
2139 | struct amdgpu_bo *bo = bo_va->base.bo; | 2256 | struct amdgpu_bo *bo = bo_va->base.bo; |
2140 | struct amdgpu_vm *vm = bo_va->base.vm; | ||
2141 | uint64_t eaddr; | 2257 | uint64_t eaddr; |
2142 | int r; | 2258 | int r; |
2143 | 2259 | ||
@@ -2171,11 +2287,7 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev, | |||
2171 | mapping->offset = offset; | 2287 | mapping->offset = offset; |
2172 | mapping->flags = flags; | 2288 | mapping->flags = flags; |
2173 | 2289 | ||
2174 | list_add(&mapping->list, &bo_va->invalids); | 2290 | amdgpu_vm_bo_insert_map(adev, bo_va, mapping); |
2175 | amdgpu_vm_it_insert(mapping, &vm->va); | ||
2176 | |||
2177 | if (flags & AMDGPU_PTE_PRT) | ||
2178 | amdgpu_vm_prt_get(adev); | ||
2179 | 2291 | ||
2180 | return 0; | 2292 | return 0; |
2181 | } | 2293 | } |
@@ -2221,6 +2333,7 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, | |||
2221 | 2333 | ||
2222 | list_del(&mapping->list); | 2334 | list_del(&mapping->list); |
2223 | amdgpu_vm_it_remove(mapping, &vm->va); | 2335 | amdgpu_vm_it_remove(mapping, &vm->va); |
2336 | mapping->bo_va = NULL; | ||
2224 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); | 2337 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); |
2225 | 2338 | ||
2226 | if (valid) | 2339 | if (valid) |
@@ -2306,6 +2419,7 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev, | |||
2306 | if (tmp->last > eaddr) | 2419 | if (tmp->last > eaddr) |
2307 | tmp->last = eaddr; | 2420 | tmp->last = eaddr; |
2308 | 2421 | ||
2422 | tmp->bo_va = NULL; | ||
2309 | list_add(&tmp->list, &vm->freed); | 2423 | list_add(&tmp->list, &vm->freed); |
2310 | trace_amdgpu_vm_bo_unmap(NULL, tmp); | 2424 | trace_amdgpu_vm_bo_unmap(NULL, tmp); |
2311 | } | 2425 | } |
@@ -2332,6 +2446,19 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev, | |||
2332 | } | 2446 | } |
2333 | 2447 | ||
2334 | /** | 2448 | /** |
2449 | * amdgpu_vm_bo_lookup_mapping - find mapping by address | ||
2450 | * | ||
2451 | * @vm: the requested VM | ||
2452 | * | ||
2453 | * Find a mapping by it's address. | ||
2454 | */ | ||
2455 | struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm, | ||
2456 | uint64_t addr) | ||
2457 | { | ||
2458 | return amdgpu_vm_it_iter_first(&vm->va, addr, addr); | ||
2459 | } | ||
2460 | |||
2461 | /** | ||
2335 | * amdgpu_vm_bo_rmv - remove a bo to a specific vm | 2462 | * amdgpu_vm_bo_rmv - remove a bo to a specific vm |
2336 | * | 2463 | * |
2337 | * @adev: amdgpu_device pointer | 2464 | * @adev: amdgpu_device pointer |
@@ -2356,6 +2483,7 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, | |||
2356 | list_for_each_entry_safe(mapping, next, &bo_va->valids, list) { | 2483 | list_for_each_entry_safe(mapping, next, &bo_va->valids, list) { |
2357 | list_del(&mapping->list); | 2484 | list_del(&mapping->list); |
2358 | amdgpu_vm_it_remove(mapping, &vm->va); | 2485 | amdgpu_vm_it_remove(mapping, &vm->va); |
2486 | mapping->bo_va = NULL; | ||
2359 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); | 2487 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); |
2360 | list_add(&mapping->list, &vm->freed); | 2488 | list_add(&mapping->list, &vm->freed); |
2361 | } | 2489 | } |
@@ -2380,15 +2508,36 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, | |||
2380 | * Mark @bo as invalid. | 2508 | * Mark @bo as invalid. |
2381 | */ | 2509 | */ |
2382 | void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev, | 2510 | void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev, |
2383 | struct amdgpu_bo *bo) | 2511 | struct amdgpu_bo *bo, bool evicted) |
2384 | { | 2512 | { |
2385 | struct amdgpu_vm_bo_base *bo_base; | 2513 | struct amdgpu_vm_bo_base *bo_base; |
2386 | 2514 | ||
2387 | list_for_each_entry(bo_base, &bo->va, bo_list) { | 2515 | list_for_each_entry(bo_base, &bo->va, bo_list) { |
2516 | struct amdgpu_vm *vm = bo_base->vm; | ||
2517 | |||
2518 | bo_base->moved = true; | ||
2519 | if (evicted && bo->tbo.resv == vm->root.base.bo->tbo.resv) { | ||
2520 | spin_lock(&bo_base->vm->status_lock); | ||
2521 | if (bo->tbo.type == ttm_bo_type_kernel) | ||
2522 | list_move(&bo_base->vm_status, &vm->evicted); | ||
2523 | else | ||
2524 | list_move_tail(&bo_base->vm_status, | ||
2525 | &vm->evicted); | ||
2526 | spin_unlock(&bo_base->vm->status_lock); | ||
2527 | continue; | ||
2528 | } | ||
2529 | |||
2530 | if (bo->tbo.type == ttm_bo_type_kernel) { | ||
2531 | spin_lock(&bo_base->vm->status_lock); | ||
2532 | if (list_empty(&bo_base->vm_status)) | ||
2533 | list_add(&bo_base->vm_status, &vm->relocated); | ||
2534 | spin_unlock(&bo_base->vm->status_lock); | ||
2535 | continue; | ||
2536 | } | ||
2537 | |||
2388 | spin_lock(&bo_base->vm->status_lock); | 2538 | spin_lock(&bo_base->vm->status_lock); |
2389 | if (list_empty(&bo_base->vm_status)) | 2539 | if (list_empty(&bo_base->vm_status)) |
2390 | list_add(&bo_base->vm_status, | 2540 | list_add(&bo_base->vm_status, &vm->moved); |
2391 | &bo_base->vm->moved); | ||
2392 | spin_unlock(&bo_base->vm->status_lock); | 2541 | spin_unlock(&bo_base->vm->status_lock); |
2393 | } | 2542 | } |
2394 | } | 2543 | } |
@@ -2412,7 +2561,8 @@ static uint32_t amdgpu_vm_get_block_size(uint64_t vm_size) | |||
2412 | * @adev: amdgpu_device pointer | 2561 | * @adev: amdgpu_device pointer |
2413 | * @fragment_size_default: the default fragment size if it's set auto | 2562 | * @fragment_size_default: the default fragment size if it's set auto |
2414 | */ | 2563 | */ |
2415 | void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev, uint32_t fragment_size_default) | 2564 | void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev, |
2565 | uint32_t fragment_size_default) | ||
2416 | { | 2566 | { |
2417 | if (amdgpu_vm_fragment_size == -1) | 2567 | if (amdgpu_vm_fragment_size == -1) |
2418 | adev->vm_manager.fragment_size = fragment_size_default; | 2568 | adev->vm_manager.fragment_size = fragment_size_default; |
@@ -2426,7 +2576,8 @@ void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev, uint32_t fragment_s | |||
2426 | * @adev: amdgpu_device pointer | 2576 | * @adev: amdgpu_device pointer |
2427 | * @vm_size: the default vm size if it's set auto | 2577 | * @vm_size: the default vm size if it's set auto |
2428 | */ | 2578 | */ |
2429 | void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size, uint32_t fragment_size_default) | 2579 | void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size, |
2580 | uint32_t fragment_size_default) | ||
2430 | { | 2581 | { |
2431 | /* adjust vm size firstly */ | 2582 | /* adjust vm size firstly */ |
2432 | if (amdgpu_vm_size == -1) | 2583 | if (amdgpu_vm_size == -1) |
@@ -2458,7 +2609,7 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size, uint32_ | |||
2458 | * Init @vm fields. | 2609 | * Init @vm fields. |
2459 | */ | 2610 | */ |
2460 | int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, | 2611 | int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, |
2461 | int vm_context) | 2612 | int vm_context, unsigned int pasid) |
2462 | { | 2613 | { |
2463 | const unsigned align = min(AMDGPU_VM_PTB_ALIGN_SIZE, | 2614 | const unsigned align = min(AMDGPU_VM_PTB_ALIGN_SIZE, |
2464 | AMDGPU_VM_PTE_COUNT(adev) * 8); | 2615 | AMDGPU_VM_PTE_COUNT(adev) * 8); |
@@ -2474,8 +2625,9 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, | |||
2474 | for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) | 2625 | for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) |
2475 | vm->reserved_vmid[i] = NULL; | 2626 | vm->reserved_vmid[i] = NULL; |
2476 | spin_lock_init(&vm->status_lock); | 2627 | spin_lock_init(&vm->status_lock); |
2628 | INIT_LIST_HEAD(&vm->evicted); | ||
2629 | INIT_LIST_HEAD(&vm->relocated); | ||
2477 | INIT_LIST_HEAD(&vm->moved); | 2630 | INIT_LIST_HEAD(&vm->moved); |
2478 | INIT_LIST_HEAD(&vm->cleared); | ||
2479 | INIT_LIST_HEAD(&vm->freed); | 2631 | INIT_LIST_HEAD(&vm->freed); |
2480 | 2632 | ||
2481 | /* create scheduler entity for page table updates */ | 2633 | /* create scheduler entity for page table updates */ |
@@ -2497,7 +2649,9 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, | |||
2497 | 2649 | ||
2498 | if (adev->asic_type == CHIP_RAVEN) { | 2650 | if (adev->asic_type == CHIP_RAVEN) { |
2499 | vm->pte_support_ats = true; | 2651 | vm->pte_support_ats = true; |
2500 | init_pde_value = AMDGPU_PTE_SYSTEM | AMDGPU_PDE_PTE; | 2652 | init_pde_value = AMDGPU_PTE_DEFAULT_ATC |
2653 | | AMDGPU_PDE_PTE; | ||
2654 | |||
2501 | } | 2655 | } |
2502 | } else | 2656 | } else |
2503 | vm->use_cpu_for_update = !!(adev->vm_manager.vm_update_mode & | 2657 | vm->use_cpu_for_update = !!(adev->vm_manager.vm_update_mode & |
@@ -2506,7 +2660,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, | |||
2506 | vm->use_cpu_for_update ? "CPU" : "SDMA"); | 2660 | vm->use_cpu_for_update ? "CPU" : "SDMA"); |
2507 | WARN_ONCE((vm->use_cpu_for_update & !amdgpu_vm_is_large_bar(adev)), | 2661 | WARN_ONCE((vm->use_cpu_for_update & !amdgpu_vm_is_large_bar(adev)), |
2508 | "CPU update of VM recommended only for large BAR system\n"); | 2662 | "CPU update of VM recommended only for large BAR system\n"); |
2509 | vm->last_dir_update = NULL; | 2663 | vm->last_update = NULL; |
2510 | 2664 | ||
2511 | flags = AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | | 2665 | flags = AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | |
2512 | AMDGPU_GEM_CREATE_VRAM_CLEARED; | 2666 | AMDGPU_GEM_CREATE_VRAM_CLEARED; |
@@ -2519,30 +2673,47 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, | |||
2519 | r = amdgpu_bo_create(adev, amdgpu_vm_bo_size(adev, 0), align, true, | 2673 | r = amdgpu_bo_create(adev, amdgpu_vm_bo_size(adev, 0), align, true, |
2520 | AMDGPU_GEM_DOMAIN_VRAM, | 2674 | AMDGPU_GEM_DOMAIN_VRAM, |
2521 | flags, | 2675 | flags, |
2522 | NULL, NULL, init_pde_value, &vm->root.bo); | 2676 | NULL, NULL, init_pde_value, &vm->root.base.bo); |
2523 | if (r) | 2677 | if (r) |
2524 | goto error_free_sched_entity; | 2678 | goto error_free_sched_entity; |
2525 | 2679 | ||
2526 | r = amdgpu_bo_reserve(vm->root.bo, false); | 2680 | vm->root.base.vm = vm; |
2527 | if (r) | 2681 | list_add_tail(&vm->root.base.bo_list, &vm->root.base.bo->va); |
2528 | goto error_free_root; | 2682 | INIT_LIST_HEAD(&vm->root.base.vm_status); |
2529 | |||
2530 | vm->last_eviction_counter = atomic64_read(&adev->num_evictions); | ||
2531 | 2683 | ||
2532 | if (vm->use_cpu_for_update) { | 2684 | if (vm->use_cpu_for_update) { |
2533 | r = amdgpu_bo_kmap(vm->root.bo, NULL); | 2685 | r = amdgpu_bo_reserve(vm->root.base.bo, false); |
2686 | if (r) | ||
2687 | goto error_free_root; | ||
2688 | |||
2689 | r = amdgpu_bo_kmap(vm->root.base.bo, NULL); | ||
2690 | amdgpu_bo_unreserve(vm->root.base.bo); | ||
2534 | if (r) | 2691 | if (r) |
2535 | goto error_free_root; | 2692 | goto error_free_root; |
2536 | } | 2693 | } |
2537 | 2694 | ||
2538 | amdgpu_bo_unreserve(vm->root.bo); | 2695 | if (pasid) { |
2696 | unsigned long flags; | ||
2697 | |||
2698 | spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags); | ||
2699 | r = idr_alloc(&adev->vm_manager.pasid_idr, vm, pasid, pasid + 1, | ||
2700 | GFP_ATOMIC); | ||
2701 | spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags); | ||
2702 | if (r < 0) | ||
2703 | goto error_free_root; | ||
2704 | |||
2705 | vm->pasid = pasid; | ||
2706 | } | ||
2707 | |||
2708 | INIT_KFIFO(vm->faults); | ||
2709 | vm->fault_credit = 16; | ||
2539 | 2710 | ||
2540 | return 0; | 2711 | return 0; |
2541 | 2712 | ||
2542 | error_free_root: | 2713 | error_free_root: |
2543 | amdgpu_bo_unref(&vm->root.bo->shadow); | 2714 | amdgpu_bo_unref(&vm->root.base.bo->shadow); |
2544 | amdgpu_bo_unref(&vm->root.bo); | 2715 | amdgpu_bo_unref(&vm->root.base.bo); |
2545 | vm->root.bo = NULL; | 2716 | vm->root.base.bo = NULL; |
2546 | 2717 | ||
2547 | error_free_sched_entity: | 2718 | error_free_sched_entity: |
2548 | amd_sched_entity_fini(&ring->sched, &vm->entity); | 2719 | amd_sched_entity_fini(&ring->sched, &vm->entity); |
@@ -2561,9 +2732,11 @@ static void amdgpu_vm_free_levels(struct amdgpu_vm_pt *level) | |||
2561 | { | 2732 | { |
2562 | unsigned i; | 2733 | unsigned i; |
2563 | 2734 | ||
2564 | if (level->bo) { | 2735 | if (level->base.bo) { |
2565 | amdgpu_bo_unref(&level->bo->shadow); | 2736 | list_del(&level->base.bo_list); |
2566 | amdgpu_bo_unref(&level->bo); | 2737 | list_del(&level->base.vm_status); |
2738 | amdgpu_bo_unref(&level->base.bo->shadow); | ||
2739 | amdgpu_bo_unref(&level->base.bo); | ||
2567 | } | 2740 | } |
2568 | 2741 | ||
2569 | if (level->entries) | 2742 | if (level->entries) |
@@ -2586,7 +2759,21 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
2586 | { | 2759 | { |
2587 | struct amdgpu_bo_va_mapping *mapping, *tmp; | 2760 | struct amdgpu_bo_va_mapping *mapping, *tmp; |
2588 | bool prt_fini_needed = !!adev->gart.gart_funcs->set_prt; | 2761 | bool prt_fini_needed = !!adev->gart.gart_funcs->set_prt; |
2589 | int i; | 2762 | struct amdgpu_bo *root; |
2763 | u64 fault; | ||
2764 | int i, r; | ||
2765 | |||
2766 | /* Clear pending page faults from IH when the VM is destroyed */ | ||
2767 | while (kfifo_get(&vm->faults, &fault)) | ||
2768 | amdgpu_ih_clear_fault(adev, fault); | ||
2769 | |||
2770 | if (vm->pasid) { | ||
2771 | unsigned long flags; | ||
2772 | |||
2773 | spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags); | ||
2774 | idr_remove(&adev->vm_manager.pasid_idr, vm->pasid); | ||
2775 | spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags); | ||
2776 | } | ||
2590 | 2777 | ||
2591 | amd_sched_entity_fini(vm->entity.sched, &vm->entity); | 2778 | amd_sched_entity_fini(vm->entity.sched, &vm->entity); |
2592 | 2779 | ||
@@ -2609,13 +2796,51 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
2609 | amdgpu_vm_free_mapping(adev, vm, mapping, NULL); | 2796 | amdgpu_vm_free_mapping(adev, vm, mapping, NULL); |
2610 | } | 2797 | } |
2611 | 2798 | ||
2612 | amdgpu_vm_free_levels(&vm->root); | 2799 | root = amdgpu_bo_ref(vm->root.base.bo); |
2613 | dma_fence_put(vm->last_dir_update); | 2800 | r = amdgpu_bo_reserve(root, true); |
2801 | if (r) { | ||
2802 | dev_err(adev->dev, "Leaking page tables because BO reservation failed\n"); | ||
2803 | } else { | ||
2804 | amdgpu_vm_free_levels(&vm->root); | ||
2805 | amdgpu_bo_unreserve(root); | ||
2806 | } | ||
2807 | amdgpu_bo_unref(&root); | ||
2808 | dma_fence_put(vm->last_update); | ||
2614 | for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) | 2809 | for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) |
2615 | amdgpu_vm_free_reserved_vmid(adev, vm, i); | 2810 | amdgpu_vm_free_reserved_vmid(adev, vm, i); |
2616 | } | 2811 | } |
2617 | 2812 | ||
2618 | /** | 2813 | /** |
2814 | * amdgpu_vm_pasid_fault_credit - Check fault credit for given PASID | ||
2815 | * | ||
2816 | * @adev: amdgpu_device pointer | ||
2817 | * @pasid: PASID do identify the VM | ||
2818 | * | ||
2819 | * This function is expected to be called in interrupt context. Returns | ||
2820 | * true if there was fault credit, false otherwise | ||
2821 | */ | ||
2822 | bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev, | ||
2823 | unsigned int pasid) | ||
2824 | { | ||
2825 | struct amdgpu_vm *vm; | ||
2826 | |||
2827 | spin_lock(&adev->vm_manager.pasid_lock); | ||
2828 | vm = idr_find(&adev->vm_manager.pasid_idr, pasid); | ||
2829 | spin_unlock(&adev->vm_manager.pasid_lock); | ||
2830 | if (!vm) | ||
2831 | /* VM not found, can't track fault credit */ | ||
2832 | return true; | ||
2833 | |||
2834 | /* No lock needed. only accessed by IRQ handler */ | ||
2835 | if (!vm->fault_credit) | ||
2836 | /* Too many faults in this VM */ | ||
2837 | return false; | ||
2838 | |||
2839 | vm->fault_credit--; | ||
2840 | return true; | ||
2841 | } | ||
2842 | |||
2843 | /** | ||
2619 | * amdgpu_vm_manager_init - init the VM manager | 2844 | * amdgpu_vm_manager_init - init the VM manager |
2620 | * | 2845 | * |
2621 | * @adev: amdgpu_device pointer | 2846 | * @adev: amdgpu_device pointer |
@@ -2668,6 +2893,8 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev) | |||
2668 | adev->vm_manager.vm_update_mode = 0; | 2893 | adev->vm_manager.vm_update_mode = 0; |
2669 | #endif | 2894 | #endif |
2670 | 2895 | ||
2896 | idr_init(&adev->vm_manager.pasid_idr); | ||
2897 | spin_lock_init(&adev->vm_manager.pasid_lock); | ||
2671 | } | 2898 | } |
2672 | 2899 | ||
2673 | /** | 2900 | /** |
@@ -2681,6 +2908,9 @@ void amdgpu_vm_manager_fini(struct amdgpu_device *adev) | |||
2681 | { | 2908 | { |
2682 | unsigned i, j; | 2909 | unsigned i, j; |
2683 | 2910 | ||
2911 | WARN_ON(!idr_is_empty(&adev->vm_manager.pasid_idr)); | ||
2912 | idr_destroy(&adev->vm_manager.pasid_idr); | ||
2913 | |||
2684 | for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) { | 2914 | for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) { |
2685 | struct amdgpu_vm_id_manager *id_mgr = | 2915 | struct amdgpu_vm_id_manager *id_mgr = |
2686 | &adev->vm_manager.id_mgr[i]; | 2916 | &adev->vm_manager.id_mgr[i]; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index 6716355403ec..bae77353447b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define __AMDGPU_VM_H__ | 25 | #define __AMDGPU_VM_H__ |
26 | 26 | ||
27 | #include <linux/rbtree.h> | 27 | #include <linux/rbtree.h> |
28 | #include <linux/idr.h> | ||
28 | 29 | ||
29 | #include "gpu_scheduler.h" | 30 | #include "gpu_scheduler.h" |
30 | #include "amdgpu_sync.h" | 31 | #include "amdgpu_sync.h" |
@@ -72,6 +73,16 @@ struct amdgpu_bo_list_entry; | |||
72 | #define AMDGPU_PTE_MTYPE(a) ((uint64_t)a << 57) | 73 | #define AMDGPU_PTE_MTYPE(a) ((uint64_t)a << 57) |
73 | #define AMDGPU_PTE_MTYPE_MASK AMDGPU_PTE_MTYPE(3ULL) | 74 | #define AMDGPU_PTE_MTYPE_MASK AMDGPU_PTE_MTYPE(3ULL) |
74 | 75 | ||
76 | /* For Raven */ | ||
77 | #define AMDGPU_MTYPE_CC 2 | ||
78 | |||
79 | #define AMDGPU_PTE_DEFAULT_ATC (AMDGPU_PTE_SYSTEM \ | ||
80 | | AMDGPU_PTE_SNOOPED \ | ||
81 | | AMDGPU_PTE_EXECUTABLE \ | ||
82 | | AMDGPU_PTE_READABLE \ | ||
83 | | AMDGPU_PTE_WRITEABLE \ | ||
84 | | AMDGPU_PTE_MTYPE(AMDGPU_MTYPE_CC)) | ||
85 | |||
75 | /* How to programm VM fault handling */ | 86 | /* How to programm VM fault handling */ |
76 | #define AMDGPU_VM_FAULT_STOP_NEVER 0 | 87 | #define AMDGPU_VM_FAULT_STOP_NEVER 0 |
77 | #define AMDGPU_VM_FAULT_STOP_FIRST 1 | 88 | #define AMDGPU_VM_FAULT_STOP_FIRST 1 |
@@ -83,7 +94,8 @@ struct amdgpu_bo_list_entry; | |||
83 | #define AMDGPU_MMHUB 1 | 94 | #define AMDGPU_MMHUB 1 |
84 | 95 | ||
85 | /* hardcode that limit for now */ | 96 | /* hardcode that limit for now */ |
86 | #define AMDGPU_VA_RESERVED_SIZE (8 << 20) | 97 | #define AMDGPU_VA_RESERVED_SIZE (8ULL << 20) |
98 | |||
87 | /* max vmids dedicated for process */ | 99 | /* max vmids dedicated for process */ |
88 | #define AMDGPU_VM_MAX_RESERVED_VMID 1 | 100 | #define AMDGPU_VM_MAX_RESERVED_VMID 1 |
89 | 101 | ||
@@ -105,17 +117,24 @@ struct amdgpu_vm_bo_base { | |||
105 | 117 | ||
106 | /* protected by spinlock */ | 118 | /* protected by spinlock */ |
107 | struct list_head vm_status; | 119 | struct list_head vm_status; |
120 | |||
121 | /* protected by the BO being reserved */ | ||
122 | bool moved; | ||
108 | }; | 123 | }; |
109 | 124 | ||
110 | struct amdgpu_vm_pt { | 125 | struct amdgpu_vm_pt { |
111 | struct amdgpu_bo *bo; | 126 | struct amdgpu_vm_bo_base base; |
112 | uint64_t addr; | 127 | uint64_t addr; |
113 | 128 | ||
114 | /* array of page tables, one for each directory entry */ | 129 | /* array of page tables, one for each directory entry */ |
115 | struct amdgpu_vm_pt *entries; | 130 | struct amdgpu_vm_pt *entries; |
116 | unsigned last_entry_used; | 131 | unsigned last_entry_used; |
117 | }; | 132 | }; |
118 | 133 | ||
134 | #define AMDGPU_VM_FAULT(pasid, addr) (((u64)(pasid) << 48) | (addr)) | ||
135 | #define AMDGPU_VM_FAULT_PASID(fault) ((u64)(fault) >> 48) | ||
136 | #define AMDGPU_VM_FAULT_ADDR(fault) ((u64)(fault) & 0xfffffffff000ULL) | ||
137 | |||
119 | struct amdgpu_vm { | 138 | struct amdgpu_vm { |
120 | /* tree of virtual addresses mapped */ | 139 | /* tree of virtual addresses mapped */ |
121 | struct rb_root_cached va; | 140 | struct rb_root_cached va; |
@@ -123,19 +142,21 @@ struct amdgpu_vm { | |||
123 | /* protecting invalidated */ | 142 | /* protecting invalidated */ |
124 | spinlock_t status_lock; | 143 | spinlock_t status_lock; |
125 | 144 | ||
145 | /* BOs who needs a validation */ | ||
146 | struct list_head evicted; | ||
147 | |||
148 | /* PT BOs which relocated and their parent need an update */ | ||
149 | struct list_head relocated; | ||
150 | |||
126 | /* BOs moved, but not yet updated in the PT */ | 151 | /* BOs moved, but not yet updated in the PT */ |
127 | struct list_head moved; | 152 | struct list_head moved; |
128 | 153 | ||
129 | /* BOs cleared in the PT because of a move */ | ||
130 | struct list_head cleared; | ||
131 | |||
132 | /* BO mappings freed, but not yet updated in the PT */ | 154 | /* BO mappings freed, but not yet updated in the PT */ |
133 | struct list_head freed; | 155 | struct list_head freed; |
134 | 156 | ||
135 | /* contains the page directory */ | 157 | /* contains the page directory */ |
136 | struct amdgpu_vm_pt root; | 158 | struct amdgpu_vm_pt root; |
137 | struct dma_fence *last_dir_update; | 159 | struct dma_fence *last_update; |
138 | uint64_t last_eviction_counter; | ||
139 | 160 | ||
140 | /* protecting freed */ | 161 | /* protecting freed */ |
141 | spinlock_t freed_lock; | 162 | spinlock_t freed_lock; |
@@ -143,8 +164,9 @@ struct amdgpu_vm { | |||
143 | /* Scheduler entity for page table updates */ | 164 | /* Scheduler entity for page table updates */ |
144 | struct amd_sched_entity entity; | 165 | struct amd_sched_entity entity; |
145 | 166 | ||
146 | /* client id */ | 167 | /* client id and PASID (TODO: replace client_id with PASID) */ |
147 | u64 client_id; | 168 | u64 client_id; |
169 | unsigned int pasid; | ||
148 | /* dedicated to vm */ | 170 | /* dedicated to vm */ |
149 | struct amdgpu_vm_id *reserved_vmid[AMDGPU_MAX_VMHUBS]; | 171 | struct amdgpu_vm_id *reserved_vmid[AMDGPU_MAX_VMHUBS]; |
150 | 172 | ||
@@ -153,6 +175,12 @@ struct amdgpu_vm { | |||
153 | 175 | ||
154 | /* Flag to indicate ATS support from PTE for GFX9 */ | 176 | /* Flag to indicate ATS support from PTE for GFX9 */ |
155 | bool pte_support_ats; | 177 | bool pte_support_ats; |
178 | |||
179 | /* Up to 128 pending retry page faults */ | ||
180 | DECLARE_KFIFO(faults, u64, 128); | ||
181 | |||
182 | /* Limit non-retry fault storms */ | ||
183 | unsigned int fault_credit; | ||
156 | }; | 184 | }; |
157 | 185 | ||
158 | struct amdgpu_vm_id { | 186 | struct amdgpu_vm_id { |
@@ -215,16 +243,27 @@ struct amdgpu_vm_manager { | |||
215 | * BIT1[= 0] Compute updated by SDMA [= 1] by CPU | 243 | * BIT1[= 0] Compute updated by SDMA [= 1] by CPU |
216 | */ | 244 | */ |
217 | int vm_update_mode; | 245 | int vm_update_mode; |
246 | |||
247 | /* PASID to VM mapping, will be used in interrupt context to | ||
248 | * look up VM of a page fault | ||
249 | */ | ||
250 | struct idr pasid_idr; | ||
251 | spinlock_t pasid_lock; | ||
218 | }; | 252 | }; |
219 | 253 | ||
254 | int amdgpu_vm_alloc_pasid(unsigned int bits); | ||
255 | void amdgpu_vm_free_pasid(unsigned int pasid); | ||
220 | void amdgpu_vm_manager_init(struct amdgpu_device *adev); | 256 | void amdgpu_vm_manager_init(struct amdgpu_device *adev); |
221 | void amdgpu_vm_manager_fini(struct amdgpu_device *adev); | 257 | void amdgpu_vm_manager_fini(struct amdgpu_device *adev); |
222 | int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, | 258 | int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, |
223 | int vm_context); | 259 | int vm_context, unsigned int pasid); |
224 | void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); | 260 | void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); |
261 | bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev, | ||
262 | unsigned int pasid); | ||
225 | void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, | 263 | void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, |
226 | struct list_head *validated, | 264 | struct list_head *validated, |
227 | struct amdgpu_bo_list_entry *entry); | 265 | struct amdgpu_bo_list_entry *entry); |
266 | bool amdgpu_vm_ready(struct amdgpu_vm *vm); | ||
228 | int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, | 267 | int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, |
229 | int (*callback)(void *p, struct amdgpu_bo *bo), | 268 | int (*callback)(void *p, struct amdgpu_bo *bo), |
230 | void *param); | 269 | void *param); |
@@ -243,13 +282,13 @@ int amdgpu_vm_update_directories(struct amdgpu_device *adev, | |||
243 | int amdgpu_vm_clear_freed(struct amdgpu_device *adev, | 282 | int amdgpu_vm_clear_freed(struct amdgpu_device *adev, |
244 | struct amdgpu_vm *vm, | 283 | struct amdgpu_vm *vm, |
245 | struct dma_fence **fence); | 284 | struct dma_fence **fence); |
246 | int amdgpu_vm_clear_moved(struct amdgpu_device *adev, struct amdgpu_vm *vm, | 285 | int amdgpu_vm_handle_moved(struct amdgpu_device *adev, |
247 | struct amdgpu_sync *sync); | 286 | struct amdgpu_vm *vm); |
248 | int amdgpu_vm_bo_update(struct amdgpu_device *adev, | 287 | int amdgpu_vm_bo_update(struct amdgpu_device *adev, |
249 | struct amdgpu_bo_va *bo_va, | 288 | struct amdgpu_bo_va *bo_va, |
250 | bool clear); | 289 | bool clear); |
251 | void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev, | 290 | void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev, |
252 | struct amdgpu_bo *bo); | 291 | struct amdgpu_bo *bo, bool evicted); |
253 | struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm, | 292 | struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm, |
254 | struct amdgpu_bo *bo); | 293 | struct amdgpu_bo *bo); |
255 | struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, | 294 | struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, |
@@ -269,6 +308,8 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, | |||
269 | int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev, | 308 | int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev, |
270 | struct amdgpu_vm *vm, | 309 | struct amdgpu_vm *vm, |
271 | uint64_t saddr, uint64_t size); | 310 | uint64_t saddr, uint64_t size); |
311 | struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm, | ||
312 | uint64_t addr); | ||
272 | void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, | 313 | void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, |
273 | struct amdgpu_bo_va *bo_va); | 314 | struct amdgpu_bo_va *bo_va); |
274 | void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev, | 315 | void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c index 26e900627971..4acca92f6a52 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | |||
@@ -68,11 +68,6 @@ static int amdgpu_vram_mgr_fini(struct ttm_mem_type_manager *man) | |||
68 | struct amdgpu_vram_mgr *mgr = man->priv; | 68 | struct amdgpu_vram_mgr *mgr = man->priv; |
69 | 69 | ||
70 | spin_lock(&mgr->lock); | 70 | spin_lock(&mgr->lock); |
71 | if (!drm_mm_clean(&mgr->mm)) { | ||
72 | spin_unlock(&mgr->lock); | ||
73 | return -EBUSY; | ||
74 | } | ||
75 | |||
76 | drm_mm_takedown(&mgr->mm); | 71 | drm_mm_takedown(&mgr->mm); |
77 | spin_unlock(&mgr->lock); | 72 | spin_unlock(&mgr->lock); |
78 | kfree(mgr); | 73 | kfree(mgr); |
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c index d69aa2e179bb..69500a8b4e2d 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.c +++ b/drivers/gpu/drm/amd/amdgpu/atom.c | |||
@@ -1343,8 +1343,11 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios) | |||
1343 | idx = 0x80; | 1343 | idx = 0x80; |
1344 | 1344 | ||
1345 | str = CSTR(idx); | 1345 | str = CSTR(idx); |
1346 | if (*str != '\0') | 1346 | if (*str != '\0') { |
1347 | pr_info("ATOM BIOS: %s\n", str); | 1347 | pr_info("ATOM BIOS: %s\n", str); |
1348 | strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version)); | ||
1349 | } | ||
1350 | |||
1348 | 1351 | ||
1349 | return ctx; | 1352 | return ctx; |
1350 | } | 1353 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h index ddd8045accf3..a39170991afe 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.h +++ b/drivers/gpu/drm/amd/amdgpu/atom.h | |||
@@ -140,6 +140,7 @@ struct atom_context { | |||
140 | int io_mode; | 140 | int io_mode; |
141 | uint32_t *scratch; | 141 | uint32_t *scratch; |
142 | int scratch_size_bytes; | 142 | int scratch_size_bytes; |
143 | char vbios_version[20]; | ||
143 | }; | 144 | }; |
144 | 145 | ||
145 | extern int amdgpu_atom_debug; | 146 | extern int amdgpu_atom_debug; |
diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index cb508a211b2f..68b505c768ad 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c | |||
@@ -307,7 +307,6 @@ static int ci_set_power_limit(struct amdgpu_device *adev, u32 n); | |||
307 | static int ci_set_overdrive_target_tdp(struct amdgpu_device *adev, | 307 | static int ci_set_overdrive_target_tdp(struct amdgpu_device *adev, |
308 | u32 target_tdp); | 308 | u32 target_tdp); |
309 | static int ci_update_uvd_dpm(struct amdgpu_device *adev, bool gate); | 309 | static int ci_update_uvd_dpm(struct amdgpu_device *adev, bool gate); |
310 | static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev); | ||
311 | static void ci_dpm_set_irq_funcs(struct amdgpu_device *adev); | 310 | static void ci_dpm_set_irq_funcs(struct amdgpu_device *adev); |
312 | 311 | ||
313 | static PPSMC_Result amdgpu_ci_send_msg_to_smc_with_parameter(struct amdgpu_device *adev, | 312 | static PPSMC_Result amdgpu_ci_send_msg_to_smc_with_parameter(struct amdgpu_device *adev, |
@@ -883,8 +882,9 @@ static int ci_power_control_set_level(struct amdgpu_device *adev) | |||
883 | return ret; | 882 | return ret; |
884 | } | 883 | } |
885 | 884 | ||
886 | static void ci_dpm_powergate_uvd(struct amdgpu_device *adev, bool gate) | 885 | static void ci_dpm_powergate_uvd(void *handle, bool gate) |
887 | { | 886 | { |
887 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
888 | struct ci_power_info *pi = ci_get_pi(adev); | 888 | struct ci_power_info *pi = ci_get_pi(adev); |
889 | 889 | ||
890 | pi->uvd_power_gated = gate; | 890 | pi->uvd_power_gated = gate; |
@@ -901,8 +901,9 @@ static void ci_dpm_powergate_uvd(struct amdgpu_device *adev, bool gate) | |||
901 | } | 901 | } |
902 | } | 902 | } |
903 | 903 | ||
904 | static bool ci_dpm_vblank_too_short(struct amdgpu_device *adev) | 904 | static bool ci_dpm_vblank_too_short(void *handle) |
905 | { | 905 | { |
906 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
906 | u32 vblank_time = amdgpu_dpm_get_vblank_time(adev); | 907 | u32 vblank_time = amdgpu_dpm_get_vblank_time(adev); |
907 | u32 switch_limit = adev->mc.vram_type == AMDGPU_VRAM_TYPE_GDDR5 ? 450 : 300; | 908 | u32 switch_limit = adev->mc.vram_type == AMDGPU_VRAM_TYPE_GDDR5 ? 450 : 300; |
908 | 909 | ||
@@ -1210,11 +1211,12 @@ static int ci_fan_ctrl_stop_smc_fan_control(struct amdgpu_device *adev) | |||
1210 | } | 1211 | } |
1211 | } | 1212 | } |
1212 | 1213 | ||
1213 | static int ci_dpm_get_fan_speed_percent(struct amdgpu_device *adev, | 1214 | static int ci_dpm_get_fan_speed_percent(void *handle, |
1214 | u32 *speed) | 1215 | u32 *speed) |
1215 | { | 1216 | { |
1216 | u32 duty, duty100; | 1217 | u32 duty, duty100; |
1217 | u64 tmp64; | 1218 | u64 tmp64; |
1219 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
1218 | 1220 | ||
1219 | if (adev->pm.no_fan) | 1221 | if (adev->pm.no_fan) |
1220 | return -ENOENT; | 1222 | return -ENOENT; |
@@ -1237,12 +1239,13 @@ static int ci_dpm_get_fan_speed_percent(struct amdgpu_device *adev, | |||
1237 | return 0; | 1239 | return 0; |
1238 | } | 1240 | } |
1239 | 1241 | ||
1240 | static int ci_dpm_set_fan_speed_percent(struct amdgpu_device *adev, | 1242 | static int ci_dpm_set_fan_speed_percent(void *handle, |
1241 | u32 speed) | 1243 | u32 speed) |
1242 | { | 1244 | { |
1243 | u32 tmp; | 1245 | u32 tmp; |
1244 | u32 duty, duty100; | 1246 | u32 duty, duty100; |
1245 | u64 tmp64; | 1247 | u64 tmp64; |
1248 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
1246 | struct ci_power_info *pi = ci_get_pi(adev); | 1249 | struct ci_power_info *pi = ci_get_pi(adev); |
1247 | 1250 | ||
1248 | if (adev->pm.no_fan) | 1251 | if (adev->pm.no_fan) |
@@ -1271,8 +1274,10 @@ static int ci_dpm_set_fan_speed_percent(struct amdgpu_device *adev, | |||
1271 | return 0; | 1274 | return 0; |
1272 | } | 1275 | } |
1273 | 1276 | ||
1274 | static void ci_dpm_set_fan_control_mode(struct amdgpu_device *adev, u32 mode) | 1277 | static void ci_dpm_set_fan_control_mode(void *handle, u32 mode) |
1275 | { | 1278 | { |
1279 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
1280 | |||
1276 | switch (mode) { | 1281 | switch (mode) { |
1277 | case AMD_FAN_CTRL_NONE: | 1282 | case AMD_FAN_CTRL_NONE: |
1278 | if (adev->pm.dpm.fan.ucode_fan_control) | 1283 | if (adev->pm.dpm.fan.ucode_fan_control) |
@@ -1292,8 +1297,9 @@ static void ci_dpm_set_fan_control_mode(struct amdgpu_device *adev, u32 mode) | |||
1292 | } | 1297 | } |
1293 | } | 1298 | } |
1294 | 1299 | ||
1295 | static u32 ci_dpm_get_fan_control_mode(struct amdgpu_device *adev) | 1300 | static u32 ci_dpm_get_fan_control_mode(void *handle) |
1296 | { | 1301 | { |
1302 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
1297 | struct ci_power_info *pi = ci_get_pi(adev); | 1303 | struct ci_power_info *pi = ci_get_pi(adev); |
1298 | 1304 | ||
1299 | if (pi->fan_is_controlled_by_smc) | 1305 | if (pi->fan_is_controlled_by_smc) |
@@ -4378,9 +4384,10 @@ static u32 ci_get_lowest_enabled_level(struct amdgpu_device *adev, | |||
4378 | } | 4384 | } |
4379 | 4385 | ||
4380 | 4386 | ||
4381 | static int ci_dpm_force_performance_level(struct amdgpu_device *adev, | 4387 | static int ci_dpm_force_performance_level(void *handle, |
4382 | enum amd_dpm_forced_level level) | 4388 | enum amd_dpm_forced_level level) |
4383 | { | 4389 | { |
4390 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
4384 | struct ci_power_info *pi = ci_get_pi(adev); | 4391 | struct ci_power_info *pi = ci_get_pi(adev); |
4385 | u32 tmp, levels, i; | 4392 | u32 tmp, levels, i; |
4386 | int ret; | 4393 | int ret; |
@@ -5291,8 +5298,9 @@ static void ci_update_requested_ps(struct amdgpu_device *adev, | |||
5291 | adev->pm.dpm.requested_ps = &pi->requested_rps; | 5298 | adev->pm.dpm.requested_ps = &pi->requested_rps; |
5292 | } | 5299 | } |
5293 | 5300 | ||
5294 | static int ci_dpm_pre_set_power_state(struct amdgpu_device *adev) | 5301 | static int ci_dpm_pre_set_power_state(void *handle) |
5295 | { | 5302 | { |
5303 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
5296 | struct ci_power_info *pi = ci_get_pi(adev); | 5304 | struct ci_power_info *pi = ci_get_pi(adev); |
5297 | struct amdgpu_ps requested_ps = *adev->pm.dpm.requested_ps; | 5305 | struct amdgpu_ps requested_ps = *adev->pm.dpm.requested_ps; |
5298 | struct amdgpu_ps *new_ps = &requested_ps; | 5306 | struct amdgpu_ps *new_ps = &requested_ps; |
@@ -5304,8 +5312,9 @@ static int ci_dpm_pre_set_power_state(struct amdgpu_device *adev) | |||
5304 | return 0; | 5312 | return 0; |
5305 | } | 5313 | } |
5306 | 5314 | ||
5307 | static void ci_dpm_post_set_power_state(struct amdgpu_device *adev) | 5315 | static void ci_dpm_post_set_power_state(void *handle) |
5308 | { | 5316 | { |
5317 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
5309 | struct ci_power_info *pi = ci_get_pi(adev); | 5318 | struct ci_power_info *pi = ci_get_pi(adev); |
5310 | struct amdgpu_ps *new_ps = &pi->requested_rps; | 5319 | struct amdgpu_ps *new_ps = &pi->requested_rps; |
5311 | 5320 | ||
@@ -5479,8 +5488,9 @@ static void ci_dpm_disable(struct amdgpu_device *adev) | |||
5479 | ci_update_current_ps(adev, boot_ps); | 5488 | ci_update_current_ps(adev, boot_ps); |
5480 | } | 5489 | } |
5481 | 5490 | ||
5482 | static int ci_dpm_set_power_state(struct amdgpu_device *adev) | 5491 | static int ci_dpm_set_power_state(void *handle) |
5483 | { | 5492 | { |
5493 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
5484 | struct ci_power_info *pi = ci_get_pi(adev); | 5494 | struct ci_power_info *pi = ci_get_pi(adev); |
5485 | struct amdgpu_ps *new_ps = &pi->requested_rps; | 5495 | struct amdgpu_ps *new_ps = &pi->requested_rps; |
5486 | struct amdgpu_ps *old_ps = &pi->current_rps; | 5496 | struct amdgpu_ps *old_ps = &pi->current_rps; |
@@ -5551,8 +5561,10 @@ static void ci_dpm_reset_asic(struct amdgpu_device *adev) | |||
5551 | } | 5561 | } |
5552 | #endif | 5562 | #endif |
5553 | 5563 | ||
5554 | static void ci_dpm_display_configuration_changed(struct amdgpu_device *adev) | 5564 | static void ci_dpm_display_configuration_changed(void *handle) |
5555 | { | 5565 | { |
5566 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
5567 | |||
5556 | ci_program_display_gap(adev); | 5568 | ci_program_display_gap(adev); |
5557 | } | 5569 | } |
5558 | 5570 | ||
@@ -6105,9 +6117,10 @@ static int ci_dpm_init(struct amdgpu_device *adev) | |||
6105 | } | 6117 | } |
6106 | 6118 | ||
6107 | static void | 6119 | static void |
6108 | ci_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev, | 6120 | ci_dpm_debugfs_print_current_performance_level(void *handle, |
6109 | struct seq_file *m) | 6121 | struct seq_file *m) |
6110 | { | 6122 | { |
6123 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6111 | struct ci_power_info *pi = ci_get_pi(adev); | 6124 | struct ci_power_info *pi = ci_get_pi(adev); |
6112 | struct amdgpu_ps *rps = &pi->current_rps; | 6125 | struct amdgpu_ps *rps = &pi->current_rps; |
6113 | u32 sclk = ci_get_average_sclk_freq(adev); | 6126 | u32 sclk = ci_get_average_sclk_freq(adev); |
@@ -6131,12 +6144,13 @@ ci_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev, | |||
6131 | seq_printf(m, "GPU load: %u %%\n", activity_percent); | 6144 | seq_printf(m, "GPU load: %u %%\n", activity_percent); |
6132 | } | 6145 | } |
6133 | 6146 | ||
6134 | static void ci_dpm_print_power_state(struct amdgpu_device *adev, | 6147 | static void ci_dpm_print_power_state(void *handle, void *current_ps) |
6135 | struct amdgpu_ps *rps) | ||
6136 | { | 6148 | { |
6149 | struct amdgpu_ps *rps = (struct amdgpu_ps *)current_ps; | ||
6137 | struct ci_ps *ps = ci_get_ps(rps); | 6150 | struct ci_ps *ps = ci_get_ps(rps); |
6138 | struct ci_pl *pl; | 6151 | struct ci_pl *pl; |
6139 | int i; | 6152 | int i; |
6153 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6140 | 6154 | ||
6141 | amdgpu_dpm_print_class_info(rps->class, rps->class2); | 6155 | amdgpu_dpm_print_class_info(rps->class, rps->class2); |
6142 | amdgpu_dpm_print_cap_info(rps->caps); | 6156 | amdgpu_dpm_print_cap_info(rps->caps); |
@@ -6158,20 +6172,23 @@ static inline bool ci_are_power_levels_equal(const struct ci_pl *ci_cpl1, | |||
6158 | (ci_cpl1->pcie_lane == ci_cpl2->pcie_lane)); | 6172 | (ci_cpl1->pcie_lane == ci_cpl2->pcie_lane)); |
6159 | } | 6173 | } |
6160 | 6174 | ||
6161 | static int ci_check_state_equal(struct amdgpu_device *adev, | 6175 | static int ci_check_state_equal(void *handle, |
6162 | struct amdgpu_ps *cps, | 6176 | void *current_ps, |
6163 | struct amdgpu_ps *rps, | 6177 | void *request_ps, |
6164 | bool *equal) | 6178 | bool *equal) |
6165 | { | 6179 | { |
6166 | struct ci_ps *ci_cps; | 6180 | struct ci_ps *ci_cps; |
6167 | struct ci_ps *ci_rps; | 6181 | struct ci_ps *ci_rps; |
6168 | int i; | 6182 | int i; |
6183 | struct amdgpu_ps *cps = (struct amdgpu_ps *)current_ps; | ||
6184 | struct amdgpu_ps *rps = (struct amdgpu_ps *)request_ps; | ||
6185 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6169 | 6186 | ||
6170 | if (adev == NULL || cps == NULL || rps == NULL || equal == NULL) | 6187 | if (adev == NULL || cps == NULL || rps == NULL || equal == NULL) |
6171 | return -EINVAL; | 6188 | return -EINVAL; |
6172 | 6189 | ||
6173 | ci_cps = ci_get_ps(cps); | 6190 | ci_cps = ci_get_ps((struct amdgpu_ps *)cps); |
6174 | ci_rps = ci_get_ps(rps); | 6191 | ci_rps = ci_get_ps((struct amdgpu_ps *)rps); |
6175 | 6192 | ||
6176 | if (ci_cps == NULL) { | 6193 | if (ci_cps == NULL) { |
6177 | *equal = false; | 6194 | *equal = false; |
@@ -6199,8 +6216,9 @@ static int ci_check_state_equal(struct amdgpu_device *adev, | |||
6199 | return 0; | 6216 | return 0; |
6200 | } | 6217 | } |
6201 | 6218 | ||
6202 | static u32 ci_dpm_get_sclk(struct amdgpu_device *adev, bool low) | 6219 | static u32 ci_dpm_get_sclk(void *handle, bool low) |
6203 | { | 6220 | { |
6221 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6204 | struct ci_power_info *pi = ci_get_pi(adev); | 6222 | struct ci_power_info *pi = ci_get_pi(adev); |
6205 | struct ci_ps *requested_state = ci_get_ps(&pi->requested_rps); | 6223 | struct ci_ps *requested_state = ci_get_ps(&pi->requested_rps); |
6206 | 6224 | ||
@@ -6210,8 +6228,9 @@ static u32 ci_dpm_get_sclk(struct amdgpu_device *adev, bool low) | |||
6210 | return requested_state->performance_levels[requested_state->performance_level_count - 1].sclk; | 6228 | return requested_state->performance_levels[requested_state->performance_level_count - 1].sclk; |
6211 | } | 6229 | } |
6212 | 6230 | ||
6213 | static u32 ci_dpm_get_mclk(struct amdgpu_device *adev, bool low) | 6231 | static u32 ci_dpm_get_mclk(void *handle, bool low) |
6214 | { | 6232 | { |
6233 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6215 | struct ci_power_info *pi = ci_get_pi(adev); | 6234 | struct ci_power_info *pi = ci_get_pi(adev); |
6216 | struct ci_ps *requested_state = ci_get_ps(&pi->requested_rps); | 6235 | struct ci_ps *requested_state = ci_get_ps(&pi->requested_rps); |
6217 | 6236 | ||
@@ -6222,10 +6241,11 @@ static u32 ci_dpm_get_mclk(struct amdgpu_device *adev, bool low) | |||
6222 | } | 6241 | } |
6223 | 6242 | ||
6224 | /* get temperature in millidegrees */ | 6243 | /* get temperature in millidegrees */ |
6225 | static int ci_dpm_get_temp(struct amdgpu_device *adev) | 6244 | static int ci_dpm_get_temp(void *handle) |
6226 | { | 6245 | { |
6227 | u32 temp; | 6246 | u32 temp; |
6228 | int actual_temp = 0; | 6247 | int actual_temp = 0; |
6248 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6229 | 6249 | ||
6230 | temp = (RREG32_SMC(ixCG_MULT_THERMAL_STATUS) & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >> | 6250 | temp = (RREG32_SMC(ixCG_MULT_THERMAL_STATUS) & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >> |
6231 | CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT; | 6251 | CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT; |
@@ -6261,7 +6281,6 @@ static int ci_dpm_early_init(void *handle) | |||
6261 | { | 6281 | { |
6262 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 6282 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
6263 | 6283 | ||
6264 | ci_dpm_set_dpm_funcs(adev); | ||
6265 | ci_dpm_set_irq_funcs(adev); | 6284 | ci_dpm_set_irq_funcs(adev); |
6266 | 6285 | ||
6267 | return 0; | 6286 | return 0; |
@@ -6346,7 +6365,6 @@ static int ci_dpm_sw_fini(void *handle) | |||
6346 | flush_work(&adev->pm.dpm.thermal.work); | 6365 | flush_work(&adev->pm.dpm.thermal.work); |
6347 | 6366 | ||
6348 | mutex_lock(&adev->pm.mutex); | 6367 | mutex_lock(&adev->pm.mutex); |
6349 | amdgpu_pm_sysfs_fini(adev); | ||
6350 | ci_dpm_fini(adev); | 6368 | ci_dpm_fini(adev); |
6351 | mutex_unlock(&adev->pm.mutex); | 6369 | mutex_unlock(&adev->pm.mutex); |
6352 | 6370 | ||
@@ -6551,9 +6569,10 @@ static int ci_dpm_set_powergating_state(void *handle, | |||
6551 | return 0; | 6569 | return 0; |
6552 | } | 6570 | } |
6553 | 6571 | ||
6554 | static int ci_dpm_print_clock_levels(struct amdgpu_device *adev, | 6572 | static int ci_dpm_print_clock_levels(void *handle, |
6555 | enum pp_clock_type type, char *buf) | 6573 | enum pp_clock_type type, char *buf) |
6556 | { | 6574 | { |
6575 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6557 | struct ci_power_info *pi = ci_get_pi(adev); | 6576 | struct ci_power_info *pi = ci_get_pi(adev); |
6558 | struct ci_single_dpm_table *sclk_table = &pi->dpm_table.sclk_table; | 6577 | struct ci_single_dpm_table *sclk_table = &pi->dpm_table.sclk_table; |
6559 | struct ci_single_dpm_table *mclk_table = &pi->dpm_table.mclk_table; | 6578 | struct ci_single_dpm_table *mclk_table = &pi->dpm_table.mclk_table; |
@@ -6618,9 +6637,10 @@ static int ci_dpm_print_clock_levels(struct amdgpu_device *adev, | |||
6618 | return size; | 6637 | return size; |
6619 | } | 6638 | } |
6620 | 6639 | ||
6621 | static int ci_dpm_force_clock_level(struct amdgpu_device *adev, | 6640 | static int ci_dpm_force_clock_level(void *handle, |
6622 | enum pp_clock_type type, uint32_t mask) | 6641 | enum pp_clock_type type, uint32_t mask) |
6623 | { | 6642 | { |
6643 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6624 | struct ci_power_info *pi = ci_get_pi(adev); | 6644 | struct ci_power_info *pi = ci_get_pi(adev); |
6625 | 6645 | ||
6626 | if (adev->pm.dpm.forced_level & (AMD_DPM_FORCED_LEVEL_AUTO | | 6646 | if (adev->pm.dpm.forced_level & (AMD_DPM_FORCED_LEVEL_AUTO | |
@@ -6664,8 +6684,9 @@ static int ci_dpm_force_clock_level(struct amdgpu_device *adev, | |||
6664 | return 0; | 6684 | return 0; |
6665 | } | 6685 | } |
6666 | 6686 | ||
6667 | static int ci_dpm_get_sclk_od(struct amdgpu_device *adev) | 6687 | static int ci_dpm_get_sclk_od(void *handle) |
6668 | { | 6688 | { |
6689 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6669 | struct ci_power_info *pi = ci_get_pi(adev); | 6690 | struct ci_power_info *pi = ci_get_pi(adev); |
6670 | struct ci_single_dpm_table *sclk_table = &(pi->dpm_table.sclk_table); | 6691 | struct ci_single_dpm_table *sclk_table = &(pi->dpm_table.sclk_table); |
6671 | struct ci_single_dpm_table *golden_sclk_table = | 6692 | struct ci_single_dpm_table *golden_sclk_table = |
@@ -6680,8 +6701,9 @@ static int ci_dpm_get_sclk_od(struct amdgpu_device *adev) | |||
6680 | return value; | 6701 | return value; |
6681 | } | 6702 | } |
6682 | 6703 | ||
6683 | static int ci_dpm_set_sclk_od(struct amdgpu_device *adev, uint32_t value) | 6704 | static int ci_dpm_set_sclk_od(void *handle, uint32_t value) |
6684 | { | 6705 | { |
6706 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6685 | struct ci_power_info *pi = ci_get_pi(adev); | 6707 | struct ci_power_info *pi = ci_get_pi(adev); |
6686 | struct ci_ps *ps = ci_get_ps(adev->pm.dpm.requested_ps); | 6708 | struct ci_ps *ps = ci_get_ps(adev->pm.dpm.requested_ps); |
6687 | struct ci_single_dpm_table *golden_sclk_table = | 6709 | struct ci_single_dpm_table *golden_sclk_table = |
@@ -6698,8 +6720,9 @@ static int ci_dpm_set_sclk_od(struct amdgpu_device *adev, uint32_t value) | |||
6698 | return 0; | 6720 | return 0; |
6699 | } | 6721 | } |
6700 | 6722 | ||
6701 | static int ci_dpm_get_mclk_od(struct amdgpu_device *adev) | 6723 | static int ci_dpm_get_mclk_od(void *handle) |
6702 | { | 6724 | { |
6725 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6703 | struct ci_power_info *pi = ci_get_pi(adev); | 6726 | struct ci_power_info *pi = ci_get_pi(adev); |
6704 | struct ci_single_dpm_table *mclk_table = &(pi->dpm_table.mclk_table); | 6727 | struct ci_single_dpm_table *mclk_table = &(pi->dpm_table.mclk_table); |
6705 | struct ci_single_dpm_table *golden_mclk_table = | 6728 | struct ci_single_dpm_table *golden_mclk_table = |
@@ -6714,8 +6737,9 @@ static int ci_dpm_get_mclk_od(struct amdgpu_device *adev) | |||
6714 | return value; | 6737 | return value; |
6715 | } | 6738 | } |
6716 | 6739 | ||
6717 | static int ci_dpm_set_mclk_od(struct amdgpu_device *adev, uint32_t value) | 6740 | static int ci_dpm_set_mclk_od(void *handle, uint32_t value) |
6718 | { | 6741 | { |
6742 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6719 | struct ci_power_info *pi = ci_get_pi(adev); | 6743 | struct ci_power_info *pi = ci_get_pi(adev); |
6720 | struct ci_ps *ps = ci_get_ps(adev->pm.dpm.requested_ps); | 6744 | struct ci_ps *ps = ci_get_ps(adev->pm.dpm.requested_ps); |
6721 | struct ci_single_dpm_table *golden_mclk_table = | 6745 | struct ci_single_dpm_table *golden_mclk_table = |
@@ -6732,9 +6756,10 @@ static int ci_dpm_set_mclk_od(struct amdgpu_device *adev, uint32_t value) | |||
6732 | return 0; | 6756 | return 0; |
6733 | } | 6757 | } |
6734 | 6758 | ||
6735 | static int ci_dpm_get_power_profile_state(struct amdgpu_device *adev, | 6759 | static int ci_dpm_get_power_profile_state(void *handle, |
6736 | struct amd_pp_profile *query) | 6760 | struct amd_pp_profile *query) |
6737 | { | 6761 | { |
6762 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6738 | struct ci_power_info *pi = ci_get_pi(adev); | 6763 | struct ci_power_info *pi = ci_get_pi(adev); |
6739 | 6764 | ||
6740 | if (!pi || !query) | 6765 | if (!pi || !query) |
@@ -6851,9 +6876,10 @@ static int ci_set_power_profile_state(struct amdgpu_device *adev, | |||
6851 | return result; | 6876 | return result; |
6852 | } | 6877 | } |
6853 | 6878 | ||
6854 | static int ci_dpm_set_power_profile_state(struct amdgpu_device *adev, | 6879 | static int ci_dpm_set_power_profile_state(void *handle, |
6855 | struct amd_pp_profile *request) | 6880 | struct amd_pp_profile *request) |
6856 | { | 6881 | { |
6882 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6857 | struct ci_power_info *pi = ci_get_pi(adev); | 6883 | struct ci_power_info *pi = ci_get_pi(adev); |
6858 | int ret = -1; | 6884 | int ret = -1; |
6859 | 6885 | ||
@@ -6906,9 +6932,10 @@ static int ci_dpm_set_power_profile_state(struct amdgpu_device *adev, | |||
6906 | return 0; | 6932 | return 0; |
6907 | } | 6933 | } |
6908 | 6934 | ||
6909 | static int ci_dpm_reset_power_profile_state(struct amdgpu_device *adev, | 6935 | static int ci_dpm_reset_power_profile_state(void *handle, |
6910 | struct amd_pp_profile *request) | 6936 | struct amd_pp_profile *request) |
6911 | { | 6937 | { |
6938 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6912 | struct ci_power_info *pi = ci_get_pi(adev); | 6939 | struct ci_power_info *pi = ci_get_pi(adev); |
6913 | 6940 | ||
6914 | if (!pi || !request) | 6941 | if (!pi || !request) |
@@ -6927,9 +6954,10 @@ static int ci_dpm_reset_power_profile_state(struct amdgpu_device *adev, | |||
6927 | return -EINVAL; | 6954 | return -EINVAL; |
6928 | } | 6955 | } |
6929 | 6956 | ||
6930 | static int ci_dpm_switch_power_profile(struct amdgpu_device *adev, | 6957 | static int ci_dpm_switch_power_profile(void *handle, |
6931 | enum amd_pp_profile_type type) | 6958 | enum amd_pp_profile_type type) |
6932 | { | 6959 | { |
6960 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6933 | struct ci_power_info *pi = ci_get_pi(adev); | 6961 | struct ci_power_info *pi = ci_get_pi(adev); |
6934 | struct amd_pp_profile request = {0}; | 6962 | struct amd_pp_profile request = {0}; |
6935 | 6963 | ||
@@ -6944,11 +6972,12 @@ static int ci_dpm_switch_power_profile(struct amdgpu_device *adev, | |||
6944 | return 0; | 6972 | return 0; |
6945 | } | 6973 | } |
6946 | 6974 | ||
6947 | static int ci_dpm_read_sensor(struct amdgpu_device *adev, int idx, | 6975 | static int ci_dpm_read_sensor(void *handle, int idx, |
6948 | void *value, int *size) | 6976 | void *value, int *size) |
6949 | { | 6977 | { |
6950 | u32 activity_percent = 50; | 6978 | u32 activity_percent = 50; |
6951 | int ret; | 6979 | int ret; |
6980 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6952 | 6981 | ||
6953 | /* size must be at least 4 bytes for all sensors */ | 6982 | /* size must be at least 4 bytes for all sensors */ |
6954 | if (*size < 4) | 6983 | if (*size < 4) |
@@ -7003,7 +7032,7 @@ const struct amd_ip_funcs ci_dpm_ip_funcs = { | |||
7003 | .set_powergating_state = ci_dpm_set_powergating_state, | 7032 | .set_powergating_state = ci_dpm_set_powergating_state, |
7004 | }; | 7033 | }; |
7005 | 7034 | ||
7006 | static const struct amdgpu_dpm_funcs ci_dpm_funcs = { | 7035 | const struct amd_pm_funcs ci_dpm_funcs = { |
7007 | .get_temperature = &ci_dpm_get_temp, | 7036 | .get_temperature = &ci_dpm_get_temp, |
7008 | .pre_set_power_state = &ci_dpm_pre_set_power_state, | 7037 | .pre_set_power_state = &ci_dpm_pre_set_power_state, |
7009 | .set_power_state = &ci_dpm_set_power_state, | 7038 | .set_power_state = &ci_dpm_set_power_state, |
@@ -7035,12 +7064,6 @@ static const struct amdgpu_dpm_funcs ci_dpm_funcs = { | |||
7035 | .read_sensor = ci_dpm_read_sensor, | 7064 | .read_sensor = ci_dpm_read_sensor, |
7036 | }; | 7065 | }; |
7037 | 7066 | ||
7038 | static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev) | ||
7039 | { | ||
7040 | if (adev->pm.funcs == NULL) | ||
7041 | adev->pm.funcs = &ci_dpm_funcs; | ||
7042 | } | ||
7043 | |||
7044 | static const struct amdgpu_irq_src_funcs ci_dpm_irq_funcs = { | 7067 | static const struct amdgpu_irq_src_funcs ci_dpm_irq_funcs = { |
7045 | .set = ci_dpm_set_interrupt_state, | 7068 | .set = ci_dpm_set_interrupt_state, |
7046 | .process = ci_dpm_process_interrupt, | 7069 | .process = ci_dpm_process_interrupt, |
diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c index 567c4a5cf90c..793b1470284d 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik.c +++ b/drivers/gpu/drm/amd/amdgpu/cik.c | |||
@@ -65,6 +65,7 @@ | |||
65 | #include "oss/oss_2_0_d.h" | 65 | #include "oss/oss_2_0_d.h" |
66 | #include "oss/oss_2_0_sh_mask.h" | 66 | #include "oss/oss_2_0_sh_mask.h" |
67 | 67 | ||
68 | #include "amdgpu_dm.h" | ||
68 | #include "amdgpu_amdkfd.h" | 69 | #include "amdgpu_amdkfd.h" |
69 | #include "amdgpu_powerplay.h" | 70 | #include "amdgpu_powerplay.h" |
70 | #include "dce_virtual.h" | 71 | #include "dce_virtual.h" |
@@ -1900,6 +1901,10 @@ int cik_set_ip_blocks(struct amdgpu_device *adev) | |||
1900 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); | 1901 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); |
1901 | if (adev->enable_virtual_display) | 1902 | if (adev->enable_virtual_display) |
1902 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); | 1903 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); |
1904 | #if defined(CONFIG_DRM_AMD_DC) | ||
1905 | else if (amdgpu_device_has_dc_support(adev)) | ||
1906 | amdgpu_ip_block_add(adev, &dm_ip_block); | ||
1907 | #endif | ||
1903 | else | 1908 | else |
1904 | amdgpu_ip_block_add(adev, &dce_v8_2_ip_block); | 1909 | amdgpu_ip_block_add(adev, &dce_v8_2_ip_block); |
1905 | amdgpu_ip_block_add(adev, &gfx_v7_2_ip_block); | 1910 | amdgpu_ip_block_add(adev, &gfx_v7_2_ip_block); |
@@ -1914,6 +1919,10 @@ int cik_set_ip_blocks(struct amdgpu_device *adev) | |||
1914 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); | 1919 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); |
1915 | if (adev->enable_virtual_display) | 1920 | if (adev->enable_virtual_display) |
1916 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); | 1921 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); |
1922 | #if defined(CONFIG_DRM_AMD_DC) | ||
1923 | else if (amdgpu_device_has_dc_support(adev)) | ||
1924 | amdgpu_ip_block_add(adev, &dm_ip_block); | ||
1925 | #endif | ||
1917 | else | 1926 | else |
1918 | amdgpu_ip_block_add(adev, &dce_v8_5_ip_block); | 1927 | amdgpu_ip_block_add(adev, &dce_v8_5_ip_block); |
1919 | amdgpu_ip_block_add(adev, &gfx_v7_3_ip_block); | 1928 | amdgpu_ip_block_add(adev, &gfx_v7_3_ip_block); |
@@ -1928,6 +1937,10 @@ int cik_set_ip_blocks(struct amdgpu_device *adev) | |||
1928 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); | 1937 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); |
1929 | if (adev->enable_virtual_display) | 1938 | if (adev->enable_virtual_display) |
1930 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); | 1939 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); |
1940 | #if defined(CONFIG_DRM_AMD_DC) | ||
1941 | else if (amdgpu_device_has_dc_support(adev)) | ||
1942 | amdgpu_ip_block_add(adev, &dm_ip_block); | ||
1943 | #endif | ||
1931 | else | 1944 | else |
1932 | amdgpu_ip_block_add(adev, &dce_v8_1_ip_block); | 1945 | amdgpu_ip_block_add(adev, &dce_v8_1_ip_block); |
1933 | amdgpu_ip_block_add(adev, &gfx_v7_1_ip_block); | 1946 | amdgpu_ip_block_add(adev, &gfx_v7_1_ip_block); |
@@ -1943,6 +1956,10 @@ int cik_set_ip_blocks(struct amdgpu_device *adev) | |||
1943 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); | 1956 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); |
1944 | if (adev->enable_virtual_display) | 1957 | if (adev->enable_virtual_display) |
1945 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); | 1958 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); |
1959 | #if defined(CONFIG_DRM_AMD_DC) | ||
1960 | else if (amdgpu_device_has_dc_support(adev)) | ||
1961 | amdgpu_ip_block_add(adev, &dm_ip_block); | ||
1962 | #endif | ||
1946 | else | 1963 | else |
1947 | amdgpu_ip_block_add(adev, &dce_v8_3_ip_block); | 1964 | amdgpu_ip_block_add(adev, &dce_v8_3_ip_block); |
1948 | amdgpu_ip_block_add(adev, &gfx_v7_2_ip_block); | 1965 | amdgpu_ip_block_add(adev, &gfx_v7_2_ip_block); |
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_dpm.h b/drivers/gpu/drm/amd/amdgpu/cik_dpm.h index b1c8e7b446ea..c7b4349f6319 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_dpm.h +++ b/drivers/gpu/drm/amd/amdgpu/cik_dpm.h | |||
@@ -26,5 +26,6 @@ | |||
26 | 26 | ||
27 | extern const struct amd_ip_funcs ci_dpm_ip_funcs; | 27 | extern const struct amd_ip_funcs ci_dpm_ip_funcs; |
28 | extern const struct amd_ip_funcs kv_dpm_ip_funcs; | 28 | extern const struct amd_ip_funcs kv_dpm_ip_funcs; |
29 | 29 | extern const struct amd_pm_funcs ci_dpm_funcs; | |
30 | extern const struct amd_pm_funcs kv_dpm_funcs; | ||
30 | #endif | 31 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c index b8918432c572..a870b354e3f7 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c | |||
@@ -228,6 +228,34 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev) | |||
228 | * [127:96] - reserved | 228 | * [127:96] - reserved |
229 | */ | 229 | */ |
230 | 230 | ||
231 | /** | ||
232 | * cik_ih_prescreen_iv - prescreen an interrupt vector | ||
233 | * | ||
234 | * @adev: amdgpu_device pointer | ||
235 | * | ||
236 | * Returns true if the interrupt vector should be further processed. | ||
237 | */ | ||
238 | static bool cik_ih_prescreen_iv(struct amdgpu_device *adev) | ||
239 | { | ||
240 | u32 ring_index = adev->irq.ih.rptr >> 2; | ||
241 | u16 pasid; | ||
242 | |||
243 | switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) { | ||
244 | case 146: | ||
245 | case 147: | ||
246 | pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16; | ||
247 | if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid)) | ||
248 | return true; | ||
249 | break; | ||
250 | default: | ||
251 | /* Not a VM fault */ | ||
252 | return true; | ||
253 | } | ||
254 | |||
255 | adev->irq.ih.rptr += 16; | ||
256 | return false; | ||
257 | } | ||
258 | |||
231 | /** | 259 | /** |
232 | * cik_ih_decode_iv - decode an interrupt vector | 260 | * cik_ih_decode_iv - decode an interrupt vector |
233 | * | 261 | * |
@@ -433,6 +461,7 @@ static const struct amd_ip_funcs cik_ih_ip_funcs = { | |||
433 | 461 | ||
434 | static const struct amdgpu_ih_funcs cik_ih_funcs = { | 462 | static const struct amdgpu_ih_funcs cik_ih_funcs = { |
435 | .get_wptr = cik_ih_get_wptr, | 463 | .get_wptr = cik_ih_get_wptr, |
464 | .prescreen_iv = cik_ih_prescreen_iv, | ||
436 | .decode_iv = cik_ih_decode_iv, | 465 | .decode_iv = cik_ih_decode_iv, |
437 | .set_rptr = cik_ih_set_rptr | 466 | .set_rptr = cik_ih_set_rptr |
438 | }; | 467 | }; |
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index f508f4d01e4a..60cecd117705 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c | |||
@@ -1387,8 +1387,13 @@ static void cik_sdma_set_buffer_funcs(struct amdgpu_device *adev) | |||
1387 | } | 1387 | } |
1388 | 1388 | ||
1389 | static const struct amdgpu_vm_pte_funcs cik_sdma_vm_pte_funcs = { | 1389 | static const struct amdgpu_vm_pte_funcs cik_sdma_vm_pte_funcs = { |
1390 | .copy_pte_num_dw = 7, | ||
1390 | .copy_pte = cik_sdma_vm_copy_pte, | 1391 | .copy_pte = cik_sdma_vm_copy_pte, |
1392 | |||
1391 | .write_pte = cik_sdma_vm_write_pte, | 1393 | .write_pte = cik_sdma_vm_write_pte, |
1394 | |||
1395 | .set_max_nums_pte_pde = 0x1fffff >> 3, | ||
1396 | .set_pte_pde_num_dw = 10, | ||
1392 | .set_pte_pde = cik_sdma_vm_set_pte_pde, | 1397 | .set_pte_pde = cik_sdma_vm_set_pte_pde, |
1393 | }; | 1398 | }; |
1394 | 1399 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c index 0c1209cdd1cb..fa61d649bb44 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c | |||
@@ -208,6 +208,34 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev) | |||
208 | } | 208 | } |
209 | 209 | ||
210 | /** | 210 | /** |
211 | * cz_ih_prescreen_iv - prescreen an interrupt vector | ||
212 | * | ||
213 | * @adev: amdgpu_device pointer | ||
214 | * | ||
215 | * Returns true if the interrupt vector should be further processed. | ||
216 | */ | ||
217 | static bool cz_ih_prescreen_iv(struct amdgpu_device *adev) | ||
218 | { | ||
219 | u32 ring_index = adev->irq.ih.rptr >> 2; | ||
220 | u16 pasid; | ||
221 | |||
222 | switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) { | ||
223 | case 146: | ||
224 | case 147: | ||
225 | pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16; | ||
226 | if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid)) | ||
227 | return true; | ||
228 | break; | ||
229 | default: | ||
230 | /* Not a VM fault */ | ||
231 | return true; | ||
232 | } | ||
233 | |||
234 | adev->irq.ih.rptr += 16; | ||
235 | return false; | ||
236 | } | ||
237 | |||
238 | /** | ||
211 | * cz_ih_decode_iv - decode an interrupt vector | 239 | * cz_ih_decode_iv - decode an interrupt vector |
212 | * | 240 | * |
213 | * @adev: amdgpu_device pointer | 241 | * @adev: amdgpu_device pointer |
@@ -414,6 +442,7 @@ static const struct amd_ip_funcs cz_ih_ip_funcs = { | |||
414 | 442 | ||
415 | static const struct amdgpu_ih_funcs cz_ih_funcs = { | 443 | static const struct amdgpu_ih_funcs cz_ih_funcs = { |
416 | .get_wptr = cz_ih_get_wptr, | 444 | .get_wptr = cz_ih_get_wptr, |
445 | .prescreen_iv = cz_ih_prescreen_iv, | ||
417 | .decode_iv = cz_ih_decode_iv, | 446 | .decode_iv = cz_ih_decode_iv, |
418 | .set_rptr = cz_ih_set_rptr | 447 | .set_rptr = cz_ih_set_rptr |
419 | }; | 448 | }; |
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c index b9ee9073cb0d..a8829af120c1 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c | |||
@@ -288,7 +288,7 @@ dce_virtual_encoder(struct drm_connector *connector) | |||
288 | if (connector->encoder_ids[i] == 0) | 288 | if (connector->encoder_ids[i] == 0) |
289 | break; | 289 | break; |
290 | 290 | ||
291 | encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]); | 291 | encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]); |
292 | if (!encoder) | 292 | if (!encoder) |
293 | continue; | 293 | continue; |
294 | 294 | ||
@@ -298,7 +298,7 @@ dce_virtual_encoder(struct drm_connector *connector) | |||
298 | 298 | ||
299 | /* pick the first one */ | 299 | /* pick the first one */ |
300 | if (enc_id) | 300 | if (enc_id) |
301 | return drm_encoder_find(connector->dev, enc_id); | 301 | return drm_encoder_find(connector->dev, NULL, enc_id); |
302 | return NULL; | 302 | return NULL; |
303 | } | 303 | } |
304 | 304 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index 00868764a0dd..5c8a7a48a4ad 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | |||
@@ -4670,6 +4670,14 @@ static int gfx_v7_0_sw_fini(void *handle) | |||
4670 | gfx_v7_0_cp_compute_fini(adev); | 4670 | gfx_v7_0_cp_compute_fini(adev); |
4671 | gfx_v7_0_rlc_fini(adev); | 4671 | gfx_v7_0_rlc_fini(adev); |
4672 | gfx_v7_0_mec_fini(adev); | 4672 | gfx_v7_0_mec_fini(adev); |
4673 | amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, | ||
4674 | &adev->gfx.rlc.clear_state_gpu_addr, | ||
4675 | (void **)&adev->gfx.rlc.cs_ptr); | ||
4676 | if (adev->gfx.rlc.cp_table_size) { | ||
4677 | amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj, | ||
4678 | &adev->gfx.rlc.cp_table_gpu_addr, | ||
4679 | (void **)&adev->gfx.rlc.cp_table_ptr); | ||
4680 | } | ||
4673 | gfx_v7_0_free_microcode(adev); | 4681 | gfx_v7_0_free_microcode(adev); |
4674 | 4682 | ||
4675 | return 0; | 4683 | return 0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index fc260c13b1da..9ecdf621a74a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | |||
@@ -20,6 +20,7 @@ | |||
20 | * OTHER DEALINGS IN THE SOFTWARE. | 20 | * OTHER DEALINGS IN THE SOFTWARE. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | #include <linux/kernel.h> | ||
23 | #include <linux/firmware.h> | 24 | #include <linux/firmware.h> |
24 | #include <drm/drmP.h> | 25 | #include <drm/drmP.h> |
25 | #include "amdgpu.h" | 26 | #include "amdgpu.h" |
@@ -125,24 +126,39 @@ MODULE_FIRMWARE("amdgpu/fiji_mec2.bin"); | |||
125 | MODULE_FIRMWARE("amdgpu/fiji_rlc.bin"); | 126 | MODULE_FIRMWARE("amdgpu/fiji_rlc.bin"); |
126 | 127 | ||
127 | MODULE_FIRMWARE("amdgpu/polaris11_ce.bin"); | 128 | MODULE_FIRMWARE("amdgpu/polaris11_ce.bin"); |
129 | MODULE_FIRMWARE("amdgpu/polaris11_ce_2.bin"); | ||
128 | MODULE_FIRMWARE("amdgpu/polaris11_pfp.bin"); | 130 | MODULE_FIRMWARE("amdgpu/polaris11_pfp.bin"); |
131 | MODULE_FIRMWARE("amdgpu/polaris11_pfp_2.bin"); | ||
129 | MODULE_FIRMWARE("amdgpu/polaris11_me.bin"); | 132 | MODULE_FIRMWARE("amdgpu/polaris11_me.bin"); |
133 | MODULE_FIRMWARE("amdgpu/polaris11_me_2.bin"); | ||
130 | MODULE_FIRMWARE("amdgpu/polaris11_mec.bin"); | 134 | MODULE_FIRMWARE("amdgpu/polaris11_mec.bin"); |
135 | MODULE_FIRMWARE("amdgpu/polaris11_mec_2.bin"); | ||
131 | MODULE_FIRMWARE("amdgpu/polaris11_mec2.bin"); | 136 | MODULE_FIRMWARE("amdgpu/polaris11_mec2.bin"); |
137 | MODULE_FIRMWARE("amdgpu/polaris11_mec2_2.bin"); | ||
132 | MODULE_FIRMWARE("amdgpu/polaris11_rlc.bin"); | 138 | MODULE_FIRMWARE("amdgpu/polaris11_rlc.bin"); |
133 | 139 | ||
134 | MODULE_FIRMWARE("amdgpu/polaris10_ce.bin"); | 140 | MODULE_FIRMWARE("amdgpu/polaris10_ce.bin"); |
141 | MODULE_FIRMWARE("amdgpu/polaris10_ce_2.bin"); | ||
135 | MODULE_FIRMWARE("amdgpu/polaris10_pfp.bin"); | 142 | MODULE_FIRMWARE("amdgpu/polaris10_pfp.bin"); |
143 | MODULE_FIRMWARE("amdgpu/polaris10_pfp_2.bin"); | ||
136 | MODULE_FIRMWARE("amdgpu/polaris10_me.bin"); | 144 | MODULE_FIRMWARE("amdgpu/polaris10_me.bin"); |
145 | MODULE_FIRMWARE("amdgpu/polaris10_me_2.bin"); | ||
137 | MODULE_FIRMWARE("amdgpu/polaris10_mec.bin"); | 146 | MODULE_FIRMWARE("amdgpu/polaris10_mec.bin"); |
147 | MODULE_FIRMWARE("amdgpu/polaris10_mec_2.bin"); | ||
138 | MODULE_FIRMWARE("amdgpu/polaris10_mec2.bin"); | 148 | MODULE_FIRMWARE("amdgpu/polaris10_mec2.bin"); |
149 | MODULE_FIRMWARE("amdgpu/polaris10_mec2_2.bin"); | ||
139 | MODULE_FIRMWARE("amdgpu/polaris10_rlc.bin"); | 150 | MODULE_FIRMWARE("amdgpu/polaris10_rlc.bin"); |
140 | 151 | ||
141 | MODULE_FIRMWARE("amdgpu/polaris12_ce.bin"); | 152 | MODULE_FIRMWARE("amdgpu/polaris12_ce.bin"); |
153 | MODULE_FIRMWARE("amdgpu/polaris12_ce_2.bin"); | ||
142 | MODULE_FIRMWARE("amdgpu/polaris12_pfp.bin"); | 154 | MODULE_FIRMWARE("amdgpu/polaris12_pfp.bin"); |
155 | MODULE_FIRMWARE("amdgpu/polaris12_pfp_2.bin"); | ||
143 | MODULE_FIRMWARE("amdgpu/polaris12_me.bin"); | 156 | MODULE_FIRMWARE("amdgpu/polaris12_me.bin"); |
157 | MODULE_FIRMWARE("amdgpu/polaris12_me_2.bin"); | ||
144 | MODULE_FIRMWARE("amdgpu/polaris12_mec.bin"); | 158 | MODULE_FIRMWARE("amdgpu/polaris12_mec.bin"); |
159 | MODULE_FIRMWARE("amdgpu/polaris12_mec_2.bin"); | ||
145 | MODULE_FIRMWARE("amdgpu/polaris12_mec2.bin"); | 160 | MODULE_FIRMWARE("amdgpu/polaris12_mec2.bin"); |
161 | MODULE_FIRMWARE("amdgpu/polaris12_mec2_2.bin"); | ||
146 | MODULE_FIRMWARE("amdgpu/polaris12_rlc.bin"); | 162 | MODULE_FIRMWARE("amdgpu/polaris12_rlc.bin"); |
147 | 163 | ||
148 | static const struct amdgpu_gds_reg_offset amdgpu_gds_reg_offset[] = | 164 | static const struct amdgpu_gds_reg_offset amdgpu_gds_reg_offset[] = |
@@ -918,8 +934,17 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) | |||
918 | BUG(); | 934 | BUG(); |
919 | } | 935 | } |
920 | 936 | ||
921 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp.bin", chip_name); | 937 | if (adev->asic_type >= CHIP_POLARIS10 && adev->asic_type <= CHIP_POLARIS12) { |
922 | err = request_firmware(&adev->gfx.pfp_fw, fw_name, adev->dev); | 938 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp_2.bin", chip_name); |
939 | err = request_firmware(&adev->gfx.pfp_fw, fw_name, adev->dev); | ||
940 | if (err == -ENOENT) { | ||
941 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp.bin", chip_name); | ||
942 | err = request_firmware(&adev->gfx.pfp_fw, fw_name, adev->dev); | ||
943 | } | ||
944 | } else { | ||
945 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_pfp.bin", chip_name); | ||
946 | err = request_firmware(&adev->gfx.pfp_fw, fw_name, adev->dev); | ||
947 | } | ||
923 | if (err) | 948 | if (err) |
924 | goto out; | 949 | goto out; |
925 | err = amdgpu_ucode_validate(adev->gfx.pfp_fw); | 950 | err = amdgpu_ucode_validate(adev->gfx.pfp_fw); |
@@ -929,8 +954,17 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) | |||
929 | adev->gfx.pfp_fw_version = le32_to_cpu(cp_hdr->header.ucode_version); | 954 | adev->gfx.pfp_fw_version = le32_to_cpu(cp_hdr->header.ucode_version); |
930 | adev->gfx.pfp_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version); | 955 | adev->gfx.pfp_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version); |
931 | 956 | ||
932 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", chip_name); | 957 | if (adev->asic_type >= CHIP_POLARIS10 && adev->asic_type <= CHIP_POLARIS12) { |
933 | err = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev); | 958 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me_2.bin", chip_name); |
959 | err = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev); | ||
960 | if (err == -ENOENT) { | ||
961 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", chip_name); | ||
962 | err = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev); | ||
963 | } | ||
964 | } else { | ||
965 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", chip_name); | ||
966 | err = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev); | ||
967 | } | ||
934 | if (err) | 968 | if (err) |
935 | goto out; | 969 | goto out; |
936 | err = amdgpu_ucode_validate(adev->gfx.me_fw); | 970 | err = amdgpu_ucode_validate(adev->gfx.me_fw); |
@@ -941,8 +975,17 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) | |||
941 | 975 | ||
942 | adev->gfx.me_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version); | 976 | adev->gfx.me_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version); |
943 | 977 | ||
944 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce.bin", chip_name); | 978 | if (adev->asic_type >= CHIP_POLARIS10 && adev->asic_type <= CHIP_POLARIS12) { |
945 | err = request_firmware(&adev->gfx.ce_fw, fw_name, adev->dev); | 979 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce_2.bin", chip_name); |
980 | err = request_firmware(&adev->gfx.ce_fw, fw_name, adev->dev); | ||
981 | if (err == -ENOENT) { | ||
982 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce.bin", chip_name); | ||
983 | err = request_firmware(&adev->gfx.ce_fw, fw_name, adev->dev); | ||
984 | } | ||
985 | } else { | ||
986 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce.bin", chip_name); | ||
987 | err = request_firmware(&adev->gfx.ce_fw, fw_name, adev->dev); | ||
988 | } | ||
946 | if (err) | 989 | if (err) |
947 | goto out; | 990 | goto out; |
948 | err = amdgpu_ucode_validate(adev->gfx.ce_fw); | 991 | err = amdgpu_ucode_validate(adev->gfx.ce_fw); |
@@ -1012,8 +1055,17 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) | |||
1012 | for (i = 0 ; i < (rlc_hdr->reg_list_size_bytes >> 2); i++) | 1055 | for (i = 0 ; i < (rlc_hdr->reg_list_size_bytes >> 2); i++) |
1013 | adev->gfx.rlc.register_restore[i] = le32_to_cpu(tmp[i]); | 1056 | adev->gfx.rlc.register_restore[i] = le32_to_cpu(tmp[i]); |
1014 | 1057 | ||
1015 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name); | 1058 | if (adev->asic_type >= CHIP_POLARIS10 && adev->asic_type <= CHIP_POLARIS12) { |
1016 | err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev); | 1059 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec_2.bin", chip_name); |
1060 | err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev); | ||
1061 | if (err == -ENOENT) { | ||
1062 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name); | ||
1063 | err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev); | ||
1064 | } | ||
1065 | } else { | ||
1066 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name); | ||
1067 | err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev); | ||
1068 | } | ||
1017 | if (err) | 1069 | if (err) |
1018 | goto out; | 1070 | goto out; |
1019 | err = amdgpu_ucode_validate(adev->gfx.mec_fw); | 1071 | err = amdgpu_ucode_validate(adev->gfx.mec_fw); |
@@ -1025,8 +1077,17 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) | |||
1025 | 1077 | ||
1026 | if ((adev->asic_type != CHIP_STONEY) && | 1078 | if ((adev->asic_type != CHIP_STONEY) && |
1027 | (adev->asic_type != CHIP_TOPAZ)) { | 1079 | (adev->asic_type != CHIP_TOPAZ)) { |
1028 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name); | 1080 | if (adev->asic_type >= CHIP_POLARIS10 && adev->asic_type <= CHIP_POLARIS12) { |
1029 | err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev); | 1081 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2_2.bin", chip_name); |
1082 | err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev); | ||
1083 | if (err == -ENOENT) { | ||
1084 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name); | ||
1085 | err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev); | ||
1086 | } | ||
1087 | } else { | ||
1088 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name); | ||
1089 | err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev); | ||
1090 | } | ||
1030 | if (!err) { | 1091 | if (!err) { |
1031 | err = amdgpu_ucode_validate(adev->gfx.mec2_fw); | 1092 | err = amdgpu_ucode_validate(adev->gfx.mec2_fw); |
1032 | if (err) | 1093 | if (err) |
@@ -2053,9 +2114,19 @@ static int gfx_v8_0_sw_fini(void *handle) | |||
2053 | amdgpu_gfx_compute_mqd_sw_fini(adev); | 2114 | amdgpu_gfx_compute_mqd_sw_fini(adev); |
2054 | amdgpu_gfx_kiq_free_ring(&adev->gfx.kiq.ring, &adev->gfx.kiq.irq); | 2115 | amdgpu_gfx_kiq_free_ring(&adev->gfx.kiq.ring, &adev->gfx.kiq.irq); |
2055 | amdgpu_gfx_kiq_fini(adev); | 2116 | amdgpu_gfx_kiq_fini(adev); |
2117 | amdgpu_bo_free_kernel(&adev->virt.csa_obj, &adev->virt.csa_vmid0_addr, NULL); | ||
2056 | 2118 | ||
2057 | gfx_v8_0_mec_fini(adev); | 2119 | gfx_v8_0_mec_fini(adev); |
2058 | gfx_v8_0_rlc_fini(adev); | 2120 | gfx_v8_0_rlc_fini(adev); |
2121 | amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, | ||
2122 | &adev->gfx.rlc.clear_state_gpu_addr, | ||
2123 | (void **)&adev->gfx.rlc.cs_ptr); | ||
2124 | if ((adev->asic_type == CHIP_CARRIZO) || | ||
2125 | (adev->asic_type == CHIP_STONEY)) { | ||
2126 | amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj, | ||
2127 | &adev->gfx.rlc.cp_table_gpu_addr, | ||
2128 | (void **)&adev->gfx.rlc.cp_table_ptr); | ||
2129 | } | ||
2059 | gfx_v8_0_free_microcode(adev); | 2130 | gfx_v8_0_free_microcode(adev); |
2060 | 2131 | ||
2061 | return 0; | 2132 | return 0; |
@@ -3891,10 +3962,10 @@ static int gfx_v8_0_init_save_restore_list(struct amdgpu_device *adev) | |||
3891 | adev->gfx.rlc.reg_list_format_size_bytes >> 2, | 3962 | adev->gfx.rlc.reg_list_format_size_bytes >> 2, |
3892 | unique_indices, | 3963 | unique_indices, |
3893 | &indices_count, | 3964 | &indices_count, |
3894 | sizeof(unique_indices) / sizeof(int), | 3965 | ARRAY_SIZE(unique_indices), |
3895 | indirect_start_offsets, | 3966 | indirect_start_offsets, |
3896 | &offset_count, | 3967 | &offset_count, |
3897 | sizeof(indirect_start_offsets)/sizeof(int)); | 3968 | ARRAY_SIZE(indirect_start_offsets)); |
3898 | 3969 | ||
3899 | /* save and restore list */ | 3970 | /* save and restore list */ |
3900 | WREG32_FIELD(RLC_SRM_CNTL, AUTO_INCR_ADDR, 1); | 3971 | WREG32_FIELD(RLC_SRM_CNTL, AUTO_INCR_ADDR, 1); |
@@ -3916,14 +3987,14 @@ static int gfx_v8_0_init_save_restore_list(struct amdgpu_device *adev) | |||
3916 | /* starting offsets starts */ | 3987 | /* starting offsets starts */ |
3917 | WREG32(mmRLC_GPM_SCRATCH_ADDR, | 3988 | WREG32(mmRLC_GPM_SCRATCH_ADDR, |
3918 | adev->gfx.rlc.starting_offsets_start); | 3989 | adev->gfx.rlc.starting_offsets_start); |
3919 | for (i = 0; i < sizeof(indirect_start_offsets)/sizeof(int); i++) | 3990 | for (i = 0; i < ARRAY_SIZE(indirect_start_offsets); i++) |
3920 | WREG32(mmRLC_GPM_SCRATCH_DATA, | 3991 | WREG32(mmRLC_GPM_SCRATCH_DATA, |
3921 | indirect_start_offsets[i]); | 3992 | indirect_start_offsets[i]); |
3922 | 3993 | ||
3923 | /* unique indices */ | 3994 | /* unique indices */ |
3924 | temp = mmRLC_SRM_INDEX_CNTL_ADDR_0; | 3995 | temp = mmRLC_SRM_INDEX_CNTL_ADDR_0; |
3925 | data = mmRLC_SRM_INDEX_CNTL_DATA_0; | 3996 | data = mmRLC_SRM_INDEX_CNTL_DATA_0; |
3926 | for (i = 0; i < sizeof(unique_indices) / sizeof(int); i++) { | 3997 | for (i = 0; i < ARRAY_SIZE(unique_indices); i++) { |
3927 | if (unique_indices[i] != 0) { | 3998 | if (unique_indices[i] != 0) { |
3928 | WREG32(temp + i, unique_indices[i] & 0x3FFFF); | 3999 | WREG32(temp + i, unique_indices[i] & 0x3FFFF); |
3929 | WREG32(data + i, unique_indices[i] >> 20); | 4000 | WREG32(data + i, unique_indices[i] >> 20); |
@@ -4071,18 +4142,12 @@ static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev) | |||
4071 | gfx_v8_0_rlc_reset(adev); | 4142 | gfx_v8_0_rlc_reset(adev); |
4072 | gfx_v8_0_init_pg(adev); | 4143 | gfx_v8_0_init_pg(adev); |
4073 | 4144 | ||
4074 | if (!adev->pp_enabled) { | 4145 | |
4075 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_SMU) { | 4146 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { |
4076 | /* legacy rlc firmware loading */ | 4147 | /* legacy rlc firmware loading */ |
4077 | r = gfx_v8_0_rlc_load_microcode(adev); | 4148 | r = gfx_v8_0_rlc_load_microcode(adev); |
4078 | if (r) | 4149 | if (r) |
4079 | return r; | 4150 | return r; |
4080 | } else { | ||
4081 | r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, | ||
4082 | AMDGPU_UCODE_ID_RLC_G); | ||
4083 | if (r) | ||
4084 | return -EINVAL; | ||
4085 | } | ||
4086 | } | 4151 | } |
4087 | 4152 | ||
4088 | gfx_v8_0_rlc_start(adev); | 4153 | gfx_v8_0_rlc_start(adev); |
@@ -4577,12 +4642,10 @@ static int gfx_v8_0_mqd_init(struct amdgpu_ring *ring) | |||
4577 | mqd->compute_static_thread_mgmt_se2 = 0xffffffff; | 4642 | mqd->compute_static_thread_mgmt_se2 = 0xffffffff; |
4578 | mqd->compute_static_thread_mgmt_se3 = 0xffffffff; | 4643 | mqd->compute_static_thread_mgmt_se3 = 0xffffffff; |
4579 | mqd->compute_misc_reserved = 0x00000003; | 4644 | mqd->compute_misc_reserved = 0x00000003; |
4580 | if (!(adev->flags & AMD_IS_APU)) { | 4645 | mqd->dynamic_cu_mask_addr_lo = lower_32_bits(ring->mqd_gpu_addr |
4581 | mqd->dynamic_cu_mask_addr_lo = lower_32_bits(ring->mqd_gpu_addr | 4646 | + offsetof(struct vi_mqd_allocation, dynamic_cu_mask)); |
4582 | + offsetof(struct vi_mqd_allocation, dynamic_cu_mask)); | 4647 | mqd->dynamic_cu_mask_addr_hi = upper_32_bits(ring->mqd_gpu_addr |
4583 | mqd->dynamic_cu_mask_addr_hi = upper_32_bits(ring->mqd_gpu_addr | 4648 | + offsetof(struct vi_mqd_allocation, dynamic_cu_mask)); |
4584 | + offsetof(struct vi_mqd_allocation, dynamic_cu_mask)); | ||
4585 | } | ||
4586 | eop_base_addr = ring->eop_gpu_addr >> 8; | 4649 | eop_base_addr = ring->eop_gpu_addr >> 8; |
4587 | mqd->cp_hqd_eop_base_addr_lo = eop_base_addr; | 4650 | mqd->cp_hqd_eop_base_addr_lo = eop_base_addr; |
4588 | mqd->cp_hqd_eop_base_addr_hi = upper_32_bits(eop_base_addr); | 4651 | mqd->cp_hqd_eop_base_addr_hi = upper_32_bits(eop_base_addr); |
@@ -4753,7 +4816,7 @@ static int gfx_v8_0_kiq_init_queue(struct amdgpu_ring *ring) | |||
4753 | 4816 | ||
4754 | gfx_v8_0_kiq_setting(ring); | 4817 | gfx_v8_0_kiq_setting(ring); |
4755 | 4818 | ||
4756 | if (adev->gfx.in_reset) { /* for GPU_RESET case */ | 4819 | if (adev->in_sriov_reset) { /* for GPU_RESET case */ |
4757 | /* reset MQD to a clean status */ | 4820 | /* reset MQD to a clean status */ |
4758 | if (adev->gfx.mec.mqd_backup[mqd_idx]) | 4821 | if (adev->gfx.mec.mqd_backup[mqd_idx]) |
4759 | memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(struct vi_mqd_allocation)); | 4822 | memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(struct vi_mqd_allocation)); |
@@ -4790,7 +4853,7 @@ static int gfx_v8_0_kcq_init_queue(struct amdgpu_ring *ring) | |||
4790 | struct vi_mqd *mqd = ring->mqd_ptr; | 4853 | struct vi_mqd *mqd = ring->mqd_ptr; |
4791 | int mqd_idx = ring - &adev->gfx.compute_ring[0]; | 4854 | int mqd_idx = ring - &adev->gfx.compute_ring[0]; |
4792 | 4855 | ||
4793 | if (!adev->gfx.in_reset && !adev->gfx.in_suspend) { | 4856 | if (!adev->in_sriov_reset && !adev->gfx.in_suspend) { |
4794 | memset((void *)mqd, 0, sizeof(struct vi_mqd_allocation)); | 4857 | memset((void *)mqd, 0, sizeof(struct vi_mqd_allocation)); |
4795 | ((struct vi_mqd_allocation *)mqd)->dynamic_cu_mask = 0xFFFFFFFF; | 4858 | ((struct vi_mqd_allocation *)mqd)->dynamic_cu_mask = 0xFFFFFFFF; |
4796 | ((struct vi_mqd_allocation *)mqd)->dynamic_rb_mask = 0xFFFFFFFF; | 4859 | ((struct vi_mqd_allocation *)mqd)->dynamic_rb_mask = 0xFFFFFFFF; |
@@ -4802,7 +4865,7 @@ static int gfx_v8_0_kcq_init_queue(struct amdgpu_ring *ring) | |||
4802 | 4865 | ||
4803 | if (adev->gfx.mec.mqd_backup[mqd_idx]) | 4866 | if (adev->gfx.mec.mqd_backup[mqd_idx]) |
4804 | memcpy(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(struct vi_mqd_allocation)); | 4867 | memcpy(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(struct vi_mqd_allocation)); |
4805 | } else if (adev->gfx.in_reset) { /* for GPU_RESET case */ | 4868 | } else if (adev->in_sriov_reset) { /* for GPU_RESET case */ |
4806 | /* reset MQD to a clean status */ | 4869 | /* reset MQD to a clean status */ |
4807 | if (adev->gfx.mec.mqd_backup[mqd_idx]) | 4870 | if (adev->gfx.mec.mqd_backup[mqd_idx]) |
4808 | memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(struct vi_mqd_allocation)); | 4871 | memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(struct vi_mqd_allocation)); |
@@ -4900,43 +4963,15 @@ static int gfx_v8_0_cp_resume(struct amdgpu_device *adev) | |||
4900 | if (!(adev->flags & AMD_IS_APU)) | 4963 | if (!(adev->flags & AMD_IS_APU)) |
4901 | gfx_v8_0_enable_gui_idle_interrupt(adev, false); | 4964 | gfx_v8_0_enable_gui_idle_interrupt(adev, false); |
4902 | 4965 | ||
4903 | if (!adev->pp_enabled) { | 4966 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { |
4904 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_SMU) { | ||
4905 | /* legacy firmware loading */ | 4967 | /* legacy firmware loading */ |
4906 | r = gfx_v8_0_cp_gfx_load_microcode(adev); | 4968 | r = gfx_v8_0_cp_gfx_load_microcode(adev); |
4907 | if (r) | 4969 | if (r) |
4908 | return r; | 4970 | return r; |
4909 | 4971 | ||
4910 | r = gfx_v8_0_cp_compute_load_microcode(adev); | 4972 | r = gfx_v8_0_cp_compute_load_microcode(adev); |
4911 | if (r) | 4973 | if (r) |
4912 | return r; | 4974 | return r; |
4913 | } else { | ||
4914 | r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, | ||
4915 | AMDGPU_UCODE_ID_CP_CE); | ||
4916 | if (r) | ||
4917 | return -EINVAL; | ||
4918 | |||
4919 | r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, | ||
4920 | AMDGPU_UCODE_ID_CP_PFP); | ||
4921 | if (r) | ||
4922 | return -EINVAL; | ||
4923 | |||
4924 | r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, | ||
4925 | AMDGPU_UCODE_ID_CP_ME); | ||
4926 | if (r) | ||
4927 | return -EINVAL; | ||
4928 | |||
4929 | if (adev->asic_type == CHIP_TOPAZ) { | ||
4930 | r = gfx_v8_0_cp_compute_load_microcode(adev); | ||
4931 | if (r) | ||
4932 | return r; | ||
4933 | } else { | ||
4934 | r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, | ||
4935 | AMDGPU_UCODE_ID_CP_MEC1); | ||
4936 | if (r) | ||
4937 | return -EINVAL; | ||
4938 | } | ||
4939 | } | ||
4940 | } | 4975 | } |
4941 | 4976 | ||
4942 | r = gfx_v8_0_cp_gfx_resume(adev); | 4977 | r = gfx_v8_0_cp_gfx_resume(adev); |
@@ -4975,12 +5010,69 @@ static int gfx_v8_0_hw_init(void *handle) | |||
4975 | return r; | 5010 | return r; |
4976 | } | 5011 | } |
4977 | 5012 | ||
5013 | static int gfx_v8_0_kcq_disable(struct amdgpu_ring *kiq_ring,struct amdgpu_ring *ring) | ||
5014 | { | ||
5015 | struct amdgpu_device *adev = kiq_ring->adev; | ||
5016 | uint32_t scratch, tmp = 0; | ||
5017 | int r, i; | ||
5018 | |||
5019 | r = amdgpu_gfx_scratch_get(adev, &scratch); | ||
5020 | if (r) { | ||
5021 | DRM_ERROR("Failed to get scratch reg (%d).\n", r); | ||
5022 | return r; | ||
5023 | } | ||
5024 | WREG32(scratch, 0xCAFEDEAD); | ||
5025 | |||
5026 | r = amdgpu_ring_alloc(kiq_ring, 10); | ||
5027 | if (r) { | ||
5028 | DRM_ERROR("Failed to lock KIQ (%d).\n", r); | ||
5029 | amdgpu_gfx_scratch_free(adev, scratch); | ||
5030 | return r; | ||
5031 | } | ||
5032 | |||
5033 | /* unmap queues */ | ||
5034 | amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_UNMAP_QUEUES, 4)); | ||
5035 | amdgpu_ring_write(kiq_ring, /* Q_sel: 0, vmid: 0, engine: 0, num_Q: 1 */ | ||
5036 | PACKET3_UNMAP_QUEUES_ACTION(1) | /* RESET_QUEUES */ | ||
5037 | PACKET3_UNMAP_QUEUES_QUEUE_SEL(0) | | ||
5038 | PACKET3_UNMAP_QUEUES_ENGINE_SEL(0) | | ||
5039 | PACKET3_UNMAP_QUEUES_NUM_QUEUES(1)); | ||
5040 | amdgpu_ring_write(kiq_ring, PACKET3_UNMAP_QUEUES_DOORBELL_OFFSET0(ring->doorbell_index)); | ||
5041 | amdgpu_ring_write(kiq_ring, 0); | ||
5042 | amdgpu_ring_write(kiq_ring, 0); | ||
5043 | amdgpu_ring_write(kiq_ring, 0); | ||
5044 | /* write to scratch for completion */ | ||
5045 | amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1)); | ||
5046 | amdgpu_ring_write(kiq_ring, (scratch - PACKET3_SET_UCONFIG_REG_START)); | ||
5047 | amdgpu_ring_write(kiq_ring, 0xDEADBEEF); | ||
5048 | amdgpu_ring_commit(kiq_ring); | ||
5049 | |||
5050 | for (i = 0; i < adev->usec_timeout; i++) { | ||
5051 | tmp = RREG32(scratch); | ||
5052 | if (tmp == 0xDEADBEEF) | ||
5053 | break; | ||
5054 | DRM_UDELAY(1); | ||
5055 | } | ||
5056 | if (i >= adev->usec_timeout) { | ||
5057 | DRM_ERROR("KCQ disabled failed (scratch(0x%04X)=0x%08X)\n", scratch, tmp); | ||
5058 | r = -EINVAL; | ||
5059 | } | ||
5060 | amdgpu_gfx_scratch_free(adev, scratch); | ||
5061 | return r; | ||
5062 | } | ||
5063 | |||
4978 | static int gfx_v8_0_hw_fini(void *handle) | 5064 | static int gfx_v8_0_hw_fini(void *handle) |
4979 | { | 5065 | { |
4980 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 5066 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
5067 | int i; | ||
4981 | 5068 | ||
4982 | amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0); | 5069 | amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0); |
4983 | amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0); | 5070 | amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0); |
5071 | |||
5072 | /* disable KCQ to avoid CPC touch memory not valid anymore */ | ||
5073 | for (i = 0; i < adev->gfx.num_compute_rings; i++) | ||
5074 | gfx_v8_0_kcq_disable(&adev->gfx.kiq.ring, &adev->gfx.compute_ring[i]); | ||
5075 | |||
4984 | if (amdgpu_sriov_vf(adev)) { | 5076 | if (amdgpu_sriov_vf(adev)) { |
4985 | pr_debug("For SRIOV client, shouldn't do anything.\n"); | 5077 | pr_debug("For SRIOV client, shouldn't do anything.\n"); |
4986 | return 0; | 5078 | return 0; |
@@ -5902,7 +5994,6 @@ static int gfx_v8_0_tonga_update_gfx_clock_gating(struct amdgpu_device *adev, | |||
5902 | { | 5994 | { |
5903 | uint32_t msg_id, pp_state = 0; | 5995 | uint32_t msg_id, pp_state = 0; |
5904 | uint32_t pp_support_state = 0; | 5996 | uint32_t pp_support_state = 0; |
5905 | void *pp_handle = adev->powerplay.pp_handle; | ||
5906 | 5997 | ||
5907 | if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS)) { | 5998 | if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS)) { |
5908 | if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGLS) { | 5999 | if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGLS) { |
@@ -5920,7 +6011,8 @@ static int gfx_v8_0_tonga_update_gfx_clock_gating(struct amdgpu_device *adev, | |||
5920 | PP_BLOCK_GFX_CG, | 6011 | PP_BLOCK_GFX_CG, |
5921 | pp_support_state, | 6012 | pp_support_state, |
5922 | pp_state); | 6013 | pp_state); |
5923 | amd_set_clockgating_by_smu(pp_handle, msg_id); | 6014 | if (adev->powerplay.pp_funcs->set_clockgating_by_smu) |
6015 | amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); | ||
5924 | } | 6016 | } |
5925 | 6017 | ||
5926 | if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS)) { | 6018 | if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS)) { |
@@ -5941,7 +6033,8 @@ static int gfx_v8_0_tonga_update_gfx_clock_gating(struct amdgpu_device *adev, | |||
5941 | PP_BLOCK_GFX_MG, | 6033 | PP_BLOCK_GFX_MG, |
5942 | pp_support_state, | 6034 | pp_support_state, |
5943 | pp_state); | 6035 | pp_state); |
5944 | amd_set_clockgating_by_smu(pp_handle, msg_id); | 6036 | if (adev->powerplay.pp_funcs->set_clockgating_by_smu) |
6037 | amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); | ||
5945 | } | 6038 | } |
5946 | 6039 | ||
5947 | return 0; | 6040 | return 0; |
@@ -5953,7 +6046,6 @@ static int gfx_v8_0_polaris_update_gfx_clock_gating(struct amdgpu_device *adev, | |||
5953 | 6046 | ||
5954 | uint32_t msg_id, pp_state = 0; | 6047 | uint32_t msg_id, pp_state = 0; |
5955 | uint32_t pp_support_state = 0; | 6048 | uint32_t pp_support_state = 0; |
5956 | void *pp_handle = adev->powerplay.pp_handle; | ||
5957 | 6049 | ||
5958 | if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS)) { | 6050 | if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS)) { |
5959 | if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGLS) { | 6051 | if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGLS) { |
@@ -5971,7 +6063,8 @@ static int gfx_v8_0_polaris_update_gfx_clock_gating(struct amdgpu_device *adev, | |||
5971 | PP_BLOCK_GFX_CG, | 6063 | PP_BLOCK_GFX_CG, |
5972 | pp_support_state, | 6064 | pp_support_state, |
5973 | pp_state); | 6065 | pp_state); |
5974 | amd_set_clockgating_by_smu(pp_handle, msg_id); | 6066 | if (adev->powerplay.pp_funcs->set_clockgating_by_smu) |
6067 | amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); | ||
5975 | } | 6068 | } |
5976 | 6069 | ||
5977 | if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_3D_CGCG | AMD_CG_SUPPORT_GFX_3D_CGLS)) { | 6070 | if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_3D_CGCG | AMD_CG_SUPPORT_GFX_3D_CGLS)) { |
@@ -5990,7 +6083,8 @@ static int gfx_v8_0_polaris_update_gfx_clock_gating(struct amdgpu_device *adev, | |||
5990 | PP_BLOCK_GFX_3D, | 6083 | PP_BLOCK_GFX_3D, |
5991 | pp_support_state, | 6084 | pp_support_state, |
5992 | pp_state); | 6085 | pp_state); |
5993 | amd_set_clockgating_by_smu(pp_handle, msg_id); | 6086 | if (adev->powerplay.pp_funcs->set_clockgating_by_smu) |
6087 | amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); | ||
5994 | } | 6088 | } |
5995 | 6089 | ||
5996 | if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS)) { | 6090 | if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS)) { |
@@ -6011,7 +6105,8 @@ static int gfx_v8_0_polaris_update_gfx_clock_gating(struct amdgpu_device *adev, | |||
6011 | PP_BLOCK_GFX_MG, | 6105 | PP_BLOCK_GFX_MG, |
6012 | pp_support_state, | 6106 | pp_support_state, |
6013 | pp_state); | 6107 | pp_state); |
6014 | amd_set_clockgating_by_smu(pp_handle, msg_id); | 6108 | if (adev->powerplay.pp_funcs->set_clockgating_by_smu) |
6109 | amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); | ||
6015 | } | 6110 | } |
6016 | 6111 | ||
6017 | if (adev->cg_flags & AMD_CG_SUPPORT_GFX_RLC_LS) { | 6112 | if (adev->cg_flags & AMD_CG_SUPPORT_GFX_RLC_LS) { |
@@ -6026,7 +6121,8 @@ static int gfx_v8_0_polaris_update_gfx_clock_gating(struct amdgpu_device *adev, | |||
6026 | PP_BLOCK_GFX_RLC, | 6121 | PP_BLOCK_GFX_RLC, |
6027 | pp_support_state, | 6122 | pp_support_state, |
6028 | pp_state); | 6123 | pp_state); |
6029 | amd_set_clockgating_by_smu(pp_handle, msg_id); | 6124 | if (adev->powerplay.pp_funcs->set_clockgating_by_smu) |
6125 | amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); | ||
6030 | } | 6126 | } |
6031 | 6127 | ||
6032 | if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CP_LS) { | 6128 | if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CP_LS) { |
@@ -6040,7 +6136,8 @@ static int gfx_v8_0_polaris_update_gfx_clock_gating(struct amdgpu_device *adev, | |||
6040 | PP_BLOCK_GFX_CP, | 6136 | PP_BLOCK_GFX_CP, |
6041 | pp_support_state, | 6137 | pp_support_state, |
6042 | pp_state); | 6138 | pp_state); |
6043 | amd_set_clockgating_by_smu(pp_handle, msg_id); | 6139 | if (adev->powerplay.pp_funcs->set_clockgating_by_smu) |
6140 | amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); | ||
6044 | } | 6141 | } |
6045 | 6142 | ||
6046 | return 0; | 6143 | return 0; |
@@ -6307,6 +6404,104 @@ static void gfx_v8_0_ring_set_wptr_compute(struct amdgpu_ring *ring) | |||
6307 | WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); | 6404 | WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); |
6308 | } | 6405 | } |
6309 | 6406 | ||
6407 | static void gfx_v8_0_ring_set_pipe_percent(struct amdgpu_ring *ring, | ||
6408 | bool acquire) | ||
6409 | { | ||
6410 | struct amdgpu_device *adev = ring->adev; | ||
6411 | int pipe_num, tmp, reg; | ||
6412 | int pipe_percent = acquire ? SPI_WCL_PIPE_PERCENT_GFX__VALUE_MASK : 0x1; | ||
6413 | |||
6414 | pipe_num = ring->me * adev->gfx.mec.num_pipe_per_mec + ring->pipe; | ||
6415 | |||
6416 | /* first me only has 2 entries, GFX and HP3D */ | ||
6417 | if (ring->me > 0) | ||
6418 | pipe_num -= 2; | ||
6419 | |||
6420 | reg = mmSPI_WCL_PIPE_PERCENT_GFX + pipe_num; | ||
6421 | tmp = RREG32(reg); | ||
6422 | tmp = REG_SET_FIELD(tmp, SPI_WCL_PIPE_PERCENT_GFX, VALUE, pipe_percent); | ||
6423 | WREG32(reg, tmp); | ||
6424 | } | ||
6425 | |||
6426 | static void gfx_v8_0_pipe_reserve_resources(struct amdgpu_device *adev, | ||
6427 | struct amdgpu_ring *ring, | ||
6428 | bool acquire) | ||
6429 | { | ||
6430 | int i, pipe; | ||
6431 | bool reserve; | ||
6432 | struct amdgpu_ring *iring; | ||
6433 | |||
6434 | mutex_lock(&adev->gfx.pipe_reserve_mutex); | ||
6435 | pipe = amdgpu_gfx_queue_to_bit(adev, ring->me, ring->pipe, 0); | ||
6436 | if (acquire) | ||
6437 | set_bit(pipe, adev->gfx.pipe_reserve_bitmap); | ||
6438 | else | ||
6439 | clear_bit(pipe, adev->gfx.pipe_reserve_bitmap); | ||
6440 | |||
6441 | if (!bitmap_weight(adev->gfx.pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES)) { | ||
6442 | /* Clear all reservations - everyone reacquires all resources */ | ||
6443 | for (i = 0; i < adev->gfx.num_gfx_rings; ++i) | ||
6444 | gfx_v8_0_ring_set_pipe_percent(&adev->gfx.gfx_ring[i], | ||
6445 | true); | ||
6446 | |||
6447 | for (i = 0; i < adev->gfx.num_compute_rings; ++i) | ||
6448 | gfx_v8_0_ring_set_pipe_percent(&adev->gfx.compute_ring[i], | ||
6449 | true); | ||
6450 | } else { | ||
6451 | /* Lower all pipes without a current reservation */ | ||
6452 | for (i = 0; i < adev->gfx.num_gfx_rings; ++i) { | ||
6453 | iring = &adev->gfx.gfx_ring[i]; | ||
6454 | pipe = amdgpu_gfx_queue_to_bit(adev, | ||
6455 | iring->me, | ||
6456 | iring->pipe, | ||
6457 | 0); | ||
6458 | reserve = test_bit(pipe, adev->gfx.pipe_reserve_bitmap); | ||
6459 | gfx_v8_0_ring_set_pipe_percent(iring, reserve); | ||
6460 | } | ||
6461 | |||
6462 | for (i = 0; i < adev->gfx.num_compute_rings; ++i) { | ||
6463 | iring = &adev->gfx.compute_ring[i]; | ||
6464 | pipe = amdgpu_gfx_queue_to_bit(adev, | ||
6465 | iring->me, | ||
6466 | iring->pipe, | ||
6467 | 0); | ||
6468 | reserve = test_bit(pipe, adev->gfx.pipe_reserve_bitmap); | ||
6469 | gfx_v8_0_ring_set_pipe_percent(iring, reserve); | ||
6470 | } | ||
6471 | } | ||
6472 | |||
6473 | mutex_unlock(&adev->gfx.pipe_reserve_mutex); | ||
6474 | } | ||
6475 | |||
6476 | static void gfx_v8_0_hqd_set_priority(struct amdgpu_device *adev, | ||
6477 | struct amdgpu_ring *ring, | ||
6478 | bool acquire) | ||
6479 | { | ||
6480 | uint32_t pipe_priority = acquire ? 0x2 : 0x0; | ||
6481 | uint32_t queue_priority = acquire ? 0xf : 0x0; | ||
6482 | |||
6483 | mutex_lock(&adev->srbm_mutex); | ||
6484 | vi_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0); | ||
6485 | |||
6486 | WREG32(mmCP_HQD_PIPE_PRIORITY, pipe_priority); | ||
6487 | WREG32(mmCP_HQD_QUEUE_PRIORITY, queue_priority); | ||
6488 | |||
6489 | vi_srbm_select(adev, 0, 0, 0, 0); | ||
6490 | mutex_unlock(&adev->srbm_mutex); | ||
6491 | } | ||
6492 | static void gfx_v8_0_ring_set_priority_compute(struct amdgpu_ring *ring, | ||
6493 | enum amd_sched_priority priority) | ||
6494 | { | ||
6495 | struct amdgpu_device *adev = ring->adev; | ||
6496 | bool acquire = priority == AMD_SCHED_PRIORITY_HIGH_HW; | ||
6497 | |||
6498 | if (ring->funcs->type != AMDGPU_RING_TYPE_COMPUTE) | ||
6499 | return; | ||
6500 | |||
6501 | gfx_v8_0_hqd_set_priority(adev, ring, acquire); | ||
6502 | gfx_v8_0_pipe_reserve_resources(adev, ring, acquire); | ||
6503 | } | ||
6504 | |||
6310 | static void gfx_v8_0_ring_emit_fence_compute(struct amdgpu_ring *ring, | 6505 | static void gfx_v8_0_ring_emit_fence_compute(struct amdgpu_ring *ring, |
6311 | u64 addr, u64 seq, | 6506 | u64 addr, u64 seq, |
6312 | unsigned flags) | 6507 | unsigned flags) |
@@ -6752,6 +6947,7 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_compute = { | |||
6752 | .test_ib = gfx_v8_0_ring_test_ib, | 6947 | .test_ib = gfx_v8_0_ring_test_ib, |
6753 | .insert_nop = amdgpu_ring_insert_nop, | 6948 | .insert_nop = amdgpu_ring_insert_nop, |
6754 | .pad_ib = amdgpu_ring_generic_pad_ib, | 6949 | .pad_ib = amdgpu_ring_generic_pad_ib, |
6950 | .set_priority = gfx_v8_0_ring_set_priority_compute, | ||
6755 | }; | 6951 | }; |
6756 | 6952 | ||
6757 | static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_kiq = { | 6953 | static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_kiq = { |
@@ -6960,7 +7156,7 @@ static void gfx_v8_0_ring_emit_ce_meta(struct amdgpu_ring *ring) | |||
6960 | { | 7156 | { |
6961 | uint64_t ce_payload_addr; | 7157 | uint64_t ce_payload_addr; |
6962 | int cnt_ce; | 7158 | int cnt_ce; |
6963 | static union { | 7159 | union { |
6964 | struct vi_ce_ib_state regular; | 7160 | struct vi_ce_ib_state regular; |
6965 | struct vi_ce_ib_state_chained_ib chained; | 7161 | struct vi_ce_ib_state_chained_ib chained; |
6966 | } ce_payload = {}; | 7162 | } ce_payload = {}; |
@@ -6989,7 +7185,7 @@ static void gfx_v8_0_ring_emit_de_meta(struct amdgpu_ring *ring) | |||
6989 | { | 7185 | { |
6990 | uint64_t de_payload_addr, gds_addr, csa_addr; | 7186 | uint64_t de_payload_addr, gds_addr, csa_addr; |
6991 | int cnt_de; | 7187 | int cnt_de; |
6992 | static union { | 7188 | union { |
6993 | struct vi_de_ib_state regular; | 7189 | struct vi_de_ib_state regular; |
6994 | struct vi_de_ib_state_chained_ib chained; | 7190 | struct vi_de_ib_state_chained_ib chained; |
6995 | } de_payload = {}; | 7191 | } de_payload = {}; |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 69182eeca264..da43813d67a4 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | |||
@@ -20,6 +20,7 @@ | |||
20 | * OTHER DEALINGS IN THE SOFTWARE. | 20 | * OTHER DEALINGS IN THE SOFTWARE. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | #include <linux/kernel.h> | ||
23 | #include <linux/firmware.h> | 24 | #include <linux/firmware.h> |
24 | #include <drm/drmP.h> | 25 | #include <drm/drmP.h> |
25 | #include "amdgpu.h" | 26 | #include "amdgpu.h" |
@@ -66,38 +67,70 @@ MODULE_FIRMWARE("amdgpu/raven_rlc.bin"); | |||
66 | 67 | ||
67 | static const struct amdgpu_gds_reg_offset amdgpu_gds_reg_offset[] = | 68 | static const struct amdgpu_gds_reg_offset amdgpu_gds_reg_offset[] = |
68 | { | 69 | { |
69 | {SOC15_REG_OFFSET(GC, 0, mmGDS_VMID0_BASE), SOC15_REG_OFFSET(GC, 0, mmGDS_VMID0_SIZE), | 70 | { SOC15_REG_OFFSET(GC, 0, mmGDS_VMID0_BASE), |
70 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID0), SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID0)}, | 71 | SOC15_REG_OFFSET(GC, 0, mmGDS_VMID0_SIZE), |
71 | {SOC15_REG_OFFSET(GC, 0, mmGDS_VMID1_BASE), SOC15_REG_OFFSET(GC, 0, mmGDS_VMID1_SIZE), | 72 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID0), |
72 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID1), SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID1)}, | 73 | SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID0) }, |
73 | {SOC15_REG_OFFSET(GC, 0, mmGDS_VMID2_BASE), SOC15_REG_OFFSET(GC, 0, mmGDS_VMID2_SIZE), | 74 | { SOC15_REG_OFFSET(GC, 0, mmGDS_VMID1_BASE), |
74 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID2), SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID2)}, | 75 | SOC15_REG_OFFSET(GC, 0, mmGDS_VMID1_SIZE), |
75 | {SOC15_REG_OFFSET(GC, 0, mmGDS_VMID3_BASE), SOC15_REG_OFFSET(GC, 0, mmGDS_VMID3_SIZE), | 76 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID1), |
76 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID3), SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID3)}, | 77 | SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID1) }, |
77 | {SOC15_REG_OFFSET(GC, 0, mmGDS_VMID4_BASE), SOC15_REG_OFFSET(GC, 0, mmGDS_VMID4_SIZE), | 78 | { SOC15_REG_OFFSET(GC, 0, mmGDS_VMID2_BASE), |
78 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID4), SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID4)}, | 79 | SOC15_REG_OFFSET(GC, 0, mmGDS_VMID2_SIZE), |
79 | {SOC15_REG_OFFSET(GC, 0, mmGDS_VMID5_BASE), SOC15_REG_OFFSET(GC, 0, mmGDS_VMID5_SIZE), | 80 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID2), |
80 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID5), SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID5)}, | 81 | SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID2) }, |
81 | {SOC15_REG_OFFSET(GC, 0, mmGDS_VMID6_BASE), SOC15_REG_OFFSET(GC, 0, mmGDS_VMID6_SIZE), | 82 | { SOC15_REG_OFFSET(GC, 0, mmGDS_VMID3_BASE), |
82 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID6), SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID6)}, | 83 | SOC15_REG_OFFSET(GC, 0, mmGDS_VMID3_SIZE), |
83 | {SOC15_REG_OFFSET(GC, 0, mmGDS_VMID7_BASE), SOC15_REG_OFFSET(GC, 0, mmGDS_VMID7_SIZE), | 84 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID3), |
84 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID7), SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID7)}, | 85 | SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID3) }, |
85 | {SOC15_REG_OFFSET(GC, 0, mmGDS_VMID8_BASE), SOC15_REG_OFFSET(GC, 0, mmGDS_VMID8_SIZE), | 86 | { SOC15_REG_OFFSET(GC, 0, mmGDS_VMID4_BASE), |
86 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID8), SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID8)}, | 87 | SOC15_REG_OFFSET(GC, 0, mmGDS_VMID4_SIZE), |
87 | {SOC15_REG_OFFSET(GC, 0, mmGDS_VMID9_BASE), SOC15_REG_OFFSET(GC, 0, mmGDS_VMID9_SIZE), | 88 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID4), |
88 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID9), SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID9)}, | 89 | SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID4) }, |
89 | {SOC15_REG_OFFSET(GC, 0, mmGDS_VMID10_BASE), SOC15_REG_OFFSET(GC, 0, mmGDS_VMID10_SIZE), | 90 | { SOC15_REG_OFFSET(GC, 0, mmGDS_VMID5_BASE), |
90 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID10), SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID10)}, | 91 | SOC15_REG_OFFSET(GC, 0, mmGDS_VMID5_SIZE), |
91 | {SOC15_REG_OFFSET(GC, 0, mmGDS_VMID11_BASE), SOC15_REG_OFFSET(GC, 0, mmGDS_VMID11_SIZE), | 92 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID5), |
92 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID11), SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID11)}, | 93 | SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID5) }, |
93 | {SOC15_REG_OFFSET(GC, 0, mmGDS_VMID12_BASE), SOC15_REG_OFFSET(GC, 0, mmGDS_VMID12_SIZE), | 94 | { SOC15_REG_OFFSET(GC, 0, mmGDS_VMID6_BASE), |
94 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID12), SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID12)}, | 95 | SOC15_REG_OFFSET(GC, 0, mmGDS_VMID6_SIZE), |
95 | {SOC15_REG_OFFSET(GC, 0, mmGDS_VMID13_BASE), SOC15_REG_OFFSET(GC, 0, mmGDS_VMID13_SIZE), | 96 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID6), |
96 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID13), SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID13)}, | 97 | SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID6) }, |
97 | {SOC15_REG_OFFSET(GC, 0, mmGDS_VMID14_BASE), SOC15_REG_OFFSET(GC, 0, mmGDS_VMID14_SIZE), | 98 | { SOC15_REG_OFFSET(GC, 0, mmGDS_VMID7_BASE), |
98 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID14), SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID14)}, | 99 | SOC15_REG_OFFSET(GC, 0, mmGDS_VMID7_SIZE), |
99 | {SOC15_REG_OFFSET(GC, 0, mmGDS_VMID15_BASE), SOC15_REG_OFFSET(GC, 0, mmGDS_VMID15_SIZE), | 100 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID7), |
100 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID15), SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID15)} | 101 | SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID7) }, |
102 | { SOC15_REG_OFFSET(GC, 0, mmGDS_VMID8_BASE), | ||
103 | SOC15_REG_OFFSET(GC, 0, mmGDS_VMID8_SIZE), | ||
104 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID8), | ||
105 | SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID8) }, | ||
106 | { SOC15_REG_OFFSET(GC, 0, mmGDS_VMID9_BASE), | ||
107 | SOC15_REG_OFFSET(GC, 0, mmGDS_VMID9_SIZE), | ||
108 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID9), | ||
109 | SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID9) }, | ||
110 | { SOC15_REG_OFFSET(GC, 0, mmGDS_VMID10_BASE), | ||
111 | SOC15_REG_OFFSET(GC, 0, mmGDS_VMID10_SIZE), | ||
112 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID10), | ||
113 | SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID10) }, | ||
114 | { SOC15_REG_OFFSET(GC, 0, mmGDS_VMID11_BASE), | ||
115 | SOC15_REG_OFFSET(GC, 0, mmGDS_VMID11_SIZE), | ||
116 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID11), | ||
117 | SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID11) }, | ||
118 | { SOC15_REG_OFFSET(GC, 0, mmGDS_VMID12_BASE), | ||
119 | SOC15_REG_OFFSET(GC, 0, mmGDS_VMID12_SIZE), | ||
120 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID12), | ||
121 | SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID12)}, | ||
122 | { SOC15_REG_OFFSET(GC, 0, mmGDS_VMID13_BASE), | ||
123 | SOC15_REG_OFFSET(GC, 0, mmGDS_VMID13_SIZE), | ||
124 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID13), | ||
125 | SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID13) }, | ||
126 | { SOC15_REG_OFFSET(GC, 0, mmGDS_VMID14_BASE), | ||
127 | SOC15_REG_OFFSET(GC, 0, mmGDS_VMID14_SIZE), | ||
128 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID14), | ||
129 | SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID14) }, | ||
130 | { SOC15_REG_OFFSET(GC, 0, mmGDS_VMID15_BASE), | ||
131 | SOC15_REG_OFFSET(GC, 0, mmGDS_VMID15_SIZE), | ||
132 | SOC15_REG_OFFSET(GC, 0, mmGDS_GWS_VMID15), | ||
133 | SOC15_REG_OFFSET(GC, 0, mmGDS_OA_VMID15) } | ||
101 | }; | 134 | }; |
102 | 135 | ||
103 | static const u32 golden_settings_gc_9_0[] = | 136 | static const u32 golden_settings_gc_9_0[] = |
@@ -174,6 +207,12 @@ static const u32 golden_settings_gc_9_1_rv1[] = | |||
174 | SOC15_REG_OFFSET(GC, 0, mmTD_CNTL), 0x01bd9f33, 0x00000800 | 207 | SOC15_REG_OFFSET(GC, 0, mmTD_CNTL), 0x01bd9f33, 0x00000800 |
175 | }; | 208 | }; |
176 | 209 | ||
210 | static const u32 golden_settings_gc_9_x_common[] = | ||
211 | { | ||
212 | SOC15_REG_OFFSET(GC, 0, mmGRBM_CAM_INDEX), 0xffffffff, 0x00000000, | ||
213 | SOC15_REG_OFFSET(GC, 0, mmGRBM_CAM_DATA), 0xffffffff, 0x2544c382 | ||
214 | }; | ||
215 | |||
177 | #define VEGA10_GB_ADDR_CONFIG_GOLDEN 0x2a114042 | 216 | #define VEGA10_GB_ADDR_CONFIG_GOLDEN 0x2a114042 |
178 | #define RAVEN_GB_ADDR_CONFIG_GOLDEN 0x24000042 | 217 | #define RAVEN_GB_ADDR_CONFIG_GOLDEN 0x24000042 |
179 | 218 | ||
@@ -209,6 +248,9 @@ static void gfx_v9_0_init_golden_registers(struct amdgpu_device *adev) | |||
209 | default: | 248 | default: |
210 | break; | 249 | break; |
211 | } | 250 | } |
251 | |||
252 | amdgpu_program_register_sequence(adev, golden_settings_gc_9_x_common, | ||
253 | (const u32)ARRAY_SIZE(golden_settings_gc_9_x_common)); | ||
212 | } | 254 | } |
213 | 255 | ||
214 | static void gfx_v9_0_scratch_init(struct amdgpu_device *adev) | 256 | static void gfx_v9_0_scratch_init(struct amdgpu_device *adev) |
@@ -352,6 +394,25 @@ err1: | |||
352 | return r; | 394 | return r; |
353 | } | 395 | } |
354 | 396 | ||
397 | |||
398 | static void gfx_v9_0_free_microcode(struct amdgpu_device *adev) | ||
399 | { | ||
400 | release_firmware(adev->gfx.pfp_fw); | ||
401 | adev->gfx.pfp_fw = NULL; | ||
402 | release_firmware(adev->gfx.me_fw); | ||
403 | adev->gfx.me_fw = NULL; | ||
404 | release_firmware(adev->gfx.ce_fw); | ||
405 | adev->gfx.ce_fw = NULL; | ||
406 | release_firmware(adev->gfx.rlc_fw); | ||
407 | adev->gfx.rlc_fw = NULL; | ||
408 | release_firmware(adev->gfx.mec_fw); | ||
409 | adev->gfx.mec_fw = NULL; | ||
410 | release_firmware(adev->gfx.mec2_fw); | ||
411 | adev->gfx.mec2_fw = NULL; | ||
412 | |||
413 | kfree(adev->gfx.rlc.register_list_format); | ||
414 | } | ||
415 | |||
355 | static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) | 416 | static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) |
356 | { | 417 | { |
357 | const char *chip_name; | 418 | const char *chip_name; |
@@ -936,12 +997,22 @@ static void gfx_v9_0_read_wave_sgprs(struct amdgpu_device *adev, uint32_t simd, | |||
936 | start + SQIND_WAVE_SGPRS_OFFSET, size, dst); | 997 | start + SQIND_WAVE_SGPRS_OFFSET, size, dst); |
937 | } | 998 | } |
938 | 999 | ||
1000 | static void gfx_v9_0_read_wave_vgprs(struct amdgpu_device *adev, uint32_t simd, | ||
1001 | uint32_t wave, uint32_t thread, | ||
1002 | uint32_t start, uint32_t size, | ||
1003 | uint32_t *dst) | ||
1004 | { | ||
1005 | wave_read_regs( | ||
1006 | adev, simd, wave, thread, | ||
1007 | start + SQIND_WAVE_VGPRS_OFFSET, size, dst); | ||
1008 | } | ||
939 | 1009 | ||
940 | static const struct amdgpu_gfx_funcs gfx_v9_0_gfx_funcs = { | 1010 | static const struct amdgpu_gfx_funcs gfx_v9_0_gfx_funcs = { |
941 | .get_gpu_clock_counter = &gfx_v9_0_get_gpu_clock_counter, | 1011 | .get_gpu_clock_counter = &gfx_v9_0_get_gpu_clock_counter, |
942 | .select_se_sh = &gfx_v9_0_select_se_sh, | 1012 | .select_se_sh = &gfx_v9_0_select_se_sh, |
943 | .read_wave_data = &gfx_v9_0_read_wave_data, | 1013 | .read_wave_data = &gfx_v9_0_read_wave_data, |
944 | .read_wave_sgprs = &gfx_v9_0_read_wave_sgprs, | 1014 | .read_wave_sgprs = &gfx_v9_0_read_wave_sgprs, |
1015 | .read_wave_vgprs = &gfx_v9_0_read_wave_vgprs, | ||
945 | }; | 1016 | }; |
946 | 1017 | ||
947 | static void gfx_v9_0_gpu_early_init(struct amdgpu_device *adev) | 1018 | static void gfx_v9_0_gpu_early_init(struct amdgpu_device *adev) |
@@ -1120,30 +1191,22 @@ static int gfx_v9_0_ngg_en(struct amdgpu_device *adev) | |||
1120 | { | 1191 | { |
1121 | struct amdgpu_ring *ring = &adev->gfx.gfx_ring[0]; | 1192 | struct amdgpu_ring *ring = &adev->gfx.gfx_ring[0]; |
1122 | int r; | 1193 | int r; |
1123 | u32 data; | 1194 | u32 data, base; |
1124 | u32 size; | ||
1125 | u32 base; | ||
1126 | 1195 | ||
1127 | if (!amdgpu_ngg) | 1196 | if (!amdgpu_ngg) |
1128 | return 0; | 1197 | return 0; |
1129 | 1198 | ||
1130 | /* Program buffer size */ | 1199 | /* Program buffer size */ |
1131 | data = 0; | 1200 | data = REG_SET_FIELD(0, WD_BUF_RESOURCE_1, INDEX_BUF_SIZE, |
1132 | size = adev->gfx.ngg.buf[NGG_PRIM].size / 256; | 1201 | adev->gfx.ngg.buf[NGG_PRIM].size >> 8); |
1133 | data = REG_SET_FIELD(data, WD_BUF_RESOURCE_1, INDEX_BUF_SIZE, size); | 1202 | data = REG_SET_FIELD(data, WD_BUF_RESOURCE_1, POS_BUF_SIZE, |
1134 | 1203 | adev->gfx.ngg.buf[NGG_POS].size >> 8); | |
1135 | size = adev->gfx.ngg.buf[NGG_POS].size / 256; | ||
1136 | data = REG_SET_FIELD(data, WD_BUF_RESOURCE_1, POS_BUF_SIZE, size); | ||
1137 | |||
1138 | WREG32_SOC15(GC, 0, mmWD_BUF_RESOURCE_1, data); | 1204 | WREG32_SOC15(GC, 0, mmWD_BUF_RESOURCE_1, data); |
1139 | 1205 | ||
1140 | data = 0; | 1206 | data = REG_SET_FIELD(0, WD_BUF_RESOURCE_2, CNTL_SB_BUF_SIZE, |
1141 | size = adev->gfx.ngg.buf[NGG_CNTL].size / 256; | 1207 | adev->gfx.ngg.buf[NGG_CNTL].size >> 8); |
1142 | data = REG_SET_FIELD(data, WD_BUF_RESOURCE_2, CNTL_SB_BUF_SIZE, size); | 1208 | data = REG_SET_FIELD(data, WD_BUF_RESOURCE_2, PARAM_BUF_SIZE, |
1143 | 1209 | adev->gfx.ngg.buf[NGG_PARAM].size >> 10); | |
1144 | size = adev->gfx.ngg.buf[NGG_PARAM].size / 1024; | ||
1145 | data = REG_SET_FIELD(data, WD_BUF_RESOURCE_2, PARAM_BUF_SIZE, size); | ||
1146 | |||
1147 | WREG32_SOC15(GC, 0, mmWD_BUF_RESOURCE_2, data); | 1210 | WREG32_SOC15(GC, 0, mmWD_BUF_RESOURCE_2, data); |
1148 | 1211 | ||
1149 | /* Program buffer base address */ | 1212 | /* Program buffer base address */ |
@@ -1306,7 +1369,10 @@ static int gfx_v9_0_sw_init(void *handle) | |||
1306 | for (i = 0; i < adev->gfx.num_gfx_rings; i++) { | 1369 | for (i = 0; i < adev->gfx.num_gfx_rings; i++) { |
1307 | ring = &adev->gfx.gfx_ring[i]; | 1370 | ring = &adev->gfx.gfx_ring[i]; |
1308 | ring->ring_obj = NULL; | 1371 | ring->ring_obj = NULL; |
1309 | sprintf(ring->name, "gfx"); | 1372 | if (!i) |
1373 | sprintf(ring->name, "gfx"); | ||
1374 | else | ||
1375 | sprintf(ring->name, "gfx_%d", i); | ||
1310 | ring->use_doorbell = true; | 1376 | ring->use_doorbell = true; |
1311 | ring->doorbell_index = AMDGPU_DOORBELL64_GFX_RING0 << 1; | 1377 | ring->doorbell_index = AMDGPU_DOORBELL64_GFX_RING0 << 1; |
1312 | r = amdgpu_ring_init(adev, ring, 1024, | 1378 | r = amdgpu_ring_init(adev, ring, 1024, |
@@ -1346,7 +1412,7 @@ static int gfx_v9_0_sw_init(void *handle) | |||
1346 | return r; | 1412 | return r; |
1347 | 1413 | ||
1348 | /* create MQD for all compute queues as wel as KIQ for SRIOV case */ | 1414 | /* create MQD for all compute queues as wel as KIQ for SRIOV case */ |
1349 | r = amdgpu_gfx_compute_mqd_sw_init(adev, sizeof(struct v9_mqd)); | 1415 | r = amdgpu_gfx_compute_mqd_sw_init(adev, sizeof(struct v9_mqd_allocation)); |
1350 | if (r) | 1416 | if (r) |
1351 | return r; | 1417 | return r; |
1352 | 1418 | ||
@@ -1398,9 +1464,19 @@ static int gfx_v9_0_sw_fini(void *handle) | |||
1398 | amdgpu_gfx_compute_mqd_sw_fini(adev); | 1464 | amdgpu_gfx_compute_mqd_sw_fini(adev); |
1399 | amdgpu_gfx_kiq_free_ring(&adev->gfx.kiq.ring, &adev->gfx.kiq.irq); | 1465 | amdgpu_gfx_kiq_free_ring(&adev->gfx.kiq.ring, &adev->gfx.kiq.irq); |
1400 | amdgpu_gfx_kiq_fini(adev); | 1466 | amdgpu_gfx_kiq_fini(adev); |
1467 | amdgpu_bo_free_kernel(&adev->virt.csa_obj, &adev->virt.csa_vmid0_addr, NULL); | ||
1401 | 1468 | ||
1402 | gfx_v9_0_mec_fini(adev); | 1469 | gfx_v9_0_mec_fini(adev); |
1403 | gfx_v9_0_ngg_fini(adev); | 1470 | gfx_v9_0_ngg_fini(adev); |
1471 | amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, | ||
1472 | &adev->gfx.rlc.clear_state_gpu_addr, | ||
1473 | (void **)&adev->gfx.rlc.cs_ptr); | ||
1474 | if (adev->asic_type == CHIP_RAVEN) { | ||
1475 | amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj, | ||
1476 | &adev->gfx.rlc.cp_table_gpu_addr, | ||
1477 | (void **)&adev->gfx.rlc.cp_table_ptr); | ||
1478 | } | ||
1479 | gfx_v9_0_free_microcode(adev); | ||
1404 | 1480 | ||
1405 | return 0; | 1481 | return 0; |
1406 | } | 1482 | } |
@@ -1682,10 +1758,10 @@ static int gfx_v9_0_init_rlc_save_restore_list(struct amdgpu_device *adev) | |||
1682 | adev->gfx.rlc.reg_list_format_size_bytes >> 2, | 1758 | adev->gfx.rlc.reg_list_format_size_bytes >> 2, |
1683 | unique_indirect_regs, | 1759 | unique_indirect_regs, |
1684 | &unique_indirect_reg_count, | 1760 | &unique_indirect_reg_count, |
1685 | sizeof(unique_indirect_regs)/sizeof(int), | 1761 | ARRAY_SIZE(unique_indirect_regs), |
1686 | indirect_start_offsets, | 1762 | indirect_start_offsets, |
1687 | &indirect_start_offsets_count, | 1763 | &indirect_start_offsets_count, |
1688 | sizeof(indirect_start_offsets)/sizeof(int)); | 1764 | ARRAY_SIZE(indirect_start_offsets)); |
1689 | 1765 | ||
1690 | /* enable auto inc in case it is disabled */ | 1766 | /* enable auto inc in case it is disabled */ |
1691 | tmp = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_CNTL)); | 1767 | tmp = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_CNTL)); |
@@ -1722,12 +1798,12 @@ static int gfx_v9_0_init_rlc_save_restore_list(struct amdgpu_device *adev) | |||
1722 | /* write the starting offsets to RLC scratch ram */ | 1798 | /* write the starting offsets to RLC scratch ram */ |
1723 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_SCRATCH_ADDR), | 1799 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_SCRATCH_ADDR), |
1724 | adev->gfx.rlc.starting_offsets_start); | 1800 | adev->gfx.rlc.starting_offsets_start); |
1725 | for (i = 0; i < sizeof(indirect_start_offsets)/sizeof(int); i++) | 1801 | for (i = 0; i < ARRAY_SIZE(indirect_start_offsets); i++) |
1726 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_SCRATCH_DATA), | 1802 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_SCRATCH_DATA), |
1727 | indirect_start_offsets[i]); | 1803 | indirect_start_offsets[i]); |
1728 | 1804 | ||
1729 | /* load unique indirect regs*/ | 1805 | /* load unique indirect regs*/ |
1730 | for (i = 0; i < sizeof(unique_indirect_regs)/sizeof(int); i++) { | 1806 | for (i = 0; i < ARRAY_SIZE(unique_indirect_regs); i++) { |
1731 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_INDEX_CNTL_ADDR_0) + i, | 1807 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_INDEX_CNTL_ADDR_0) + i, |
1732 | unique_indirect_regs[i] & 0x3FFFF); | 1808 | unique_indirect_regs[i] & 0x3FFFF); |
1733 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_INDEX_CNTL_DATA_0) + i, | 1809 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_INDEX_CNTL_DATA_0) + i, |
@@ -1740,11 +1816,7 @@ static int gfx_v9_0_init_rlc_save_restore_list(struct amdgpu_device *adev) | |||
1740 | 1816 | ||
1741 | static void gfx_v9_0_enable_save_restore_machine(struct amdgpu_device *adev) | 1817 | static void gfx_v9_0_enable_save_restore_machine(struct amdgpu_device *adev) |
1742 | { | 1818 | { |
1743 | u32 tmp = 0; | 1819 | WREG32_FIELD15(GC, 0, RLC_SRM_CNTL, SRM_ENABLE, 1); |
1744 | |||
1745 | tmp = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_CNTL)); | ||
1746 | tmp |= RLC_SRM_CNTL__SRM_ENABLE_MASK; | ||
1747 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_SRM_CNTL), tmp); | ||
1748 | } | 1820 | } |
1749 | 1821 | ||
1750 | static void pwr_10_0_gfxip_control_over_cgpg(struct amdgpu_device *adev, | 1822 | static void pwr_10_0_gfxip_control_over_cgpg(struct amdgpu_device *adev, |
@@ -1822,16 +1894,11 @@ static void gfx_v9_0_enable_sck_slow_down_on_power_up(struct amdgpu_device *adev | |||
1822 | uint32_t default_data = 0; | 1894 | uint32_t default_data = 0; |
1823 | 1895 | ||
1824 | default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); | 1896 | default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); |
1825 | 1897 | data = REG_SET_FIELD(data, RLC_PG_CNTL, | |
1826 | if (enable == true) { | 1898 | SMU_CLK_SLOWDOWN_ON_PU_ENABLE, |
1827 | data |= RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PU_ENABLE_MASK; | 1899 | enable ? 1 : 0); |
1828 | if (default_data != data) | 1900 | if (default_data != data) |
1829 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); | 1901 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); |
1830 | } else { | ||
1831 | data &= ~RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PU_ENABLE_MASK; | ||
1832 | if(default_data != data) | ||
1833 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); | ||
1834 | } | ||
1835 | } | 1902 | } |
1836 | 1903 | ||
1837 | static void gfx_v9_0_enable_sck_slow_down_on_power_down(struct amdgpu_device *adev, | 1904 | static void gfx_v9_0_enable_sck_slow_down_on_power_down(struct amdgpu_device *adev, |
@@ -1841,16 +1908,11 @@ static void gfx_v9_0_enable_sck_slow_down_on_power_down(struct amdgpu_device *ad | |||
1841 | uint32_t default_data = 0; | 1908 | uint32_t default_data = 0; |
1842 | 1909 | ||
1843 | default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); | 1910 | default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); |
1844 | 1911 | data = REG_SET_FIELD(data, RLC_PG_CNTL, | |
1845 | if (enable == true) { | 1912 | SMU_CLK_SLOWDOWN_ON_PD_ENABLE, |
1846 | data |= RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PD_ENABLE_MASK; | 1913 | enable ? 1 : 0); |
1847 | if(default_data != data) | 1914 | if(default_data != data) |
1848 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); | 1915 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); |
1849 | } else { | ||
1850 | data &= ~RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PD_ENABLE_MASK; | ||
1851 | if(default_data != data) | ||
1852 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); | ||
1853 | } | ||
1854 | } | 1916 | } |
1855 | 1917 | ||
1856 | static void gfx_v9_0_enable_cp_power_gating(struct amdgpu_device *adev, | 1918 | static void gfx_v9_0_enable_cp_power_gating(struct amdgpu_device *adev, |
@@ -1860,16 +1922,11 @@ static void gfx_v9_0_enable_cp_power_gating(struct amdgpu_device *adev, | |||
1860 | uint32_t default_data = 0; | 1922 | uint32_t default_data = 0; |
1861 | 1923 | ||
1862 | default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); | 1924 | default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); |
1863 | 1925 | data = REG_SET_FIELD(data, RLC_PG_CNTL, | |
1864 | if (enable == true) { | 1926 | CP_PG_DISABLE, |
1865 | data &= ~RLC_PG_CNTL__CP_PG_DISABLE_MASK; | 1927 | enable ? 0 : 1); |
1866 | if(default_data != data) | 1928 | if(default_data != data) |
1867 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); | 1929 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); |
1868 | } else { | ||
1869 | data |= RLC_PG_CNTL__CP_PG_DISABLE_MASK; | ||
1870 | if(default_data != data) | ||
1871 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); | ||
1872 | } | ||
1873 | } | 1930 | } |
1874 | 1931 | ||
1875 | static void gfx_v9_0_enable_gfx_cg_power_gating(struct amdgpu_device *adev, | 1932 | static void gfx_v9_0_enable_gfx_cg_power_gating(struct amdgpu_device *adev, |
@@ -1878,10 +1935,9 @@ static void gfx_v9_0_enable_gfx_cg_power_gating(struct amdgpu_device *adev, | |||
1878 | uint32_t data, default_data; | 1935 | uint32_t data, default_data; |
1879 | 1936 | ||
1880 | default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); | 1937 | default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); |
1881 | if (enable == true) | 1938 | data = REG_SET_FIELD(data, RLC_PG_CNTL, |
1882 | data |= RLC_PG_CNTL__GFX_POWER_GATING_ENABLE_MASK; | 1939 | GFX_POWER_GATING_ENABLE, |
1883 | else | 1940 | enable ? 1 : 0); |
1884 | data &= ~RLC_PG_CNTL__GFX_POWER_GATING_ENABLE_MASK; | ||
1885 | if(default_data != data) | 1941 | if(default_data != data) |
1886 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); | 1942 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); |
1887 | } | 1943 | } |
@@ -1892,10 +1948,9 @@ static void gfx_v9_0_enable_gfx_pipeline_powergating(struct amdgpu_device *adev, | |||
1892 | uint32_t data, default_data; | 1948 | uint32_t data, default_data; |
1893 | 1949 | ||
1894 | default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); | 1950 | default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); |
1895 | if (enable == true) | 1951 | data = REG_SET_FIELD(data, RLC_PG_CNTL, |
1896 | data |= RLC_PG_CNTL__GFX_PIPELINE_PG_ENABLE_MASK; | 1952 | GFX_PIPELINE_PG_ENABLE, |
1897 | else | 1953 | enable ? 1 : 0); |
1898 | data &= ~RLC_PG_CNTL__GFX_PIPELINE_PG_ENABLE_MASK; | ||
1899 | if(default_data != data) | 1954 | if(default_data != data) |
1900 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); | 1955 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); |
1901 | 1956 | ||
@@ -1910,10 +1965,9 @@ static void gfx_v9_0_enable_gfx_static_mg_power_gating(struct amdgpu_device *ade | |||
1910 | uint32_t data, default_data; | 1965 | uint32_t data, default_data; |
1911 | 1966 | ||
1912 | default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); | 1967 | default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); |
1913 | if (enable == true) | 1968 | data = REG_SET_FIELD(data, RLC_PG_CNTL, |
1914 | data |= RLC_PG_CNTL__STATIC_PER_CU_PG_ENABLE_MASK; | 1969 | STATIC_PER_CU_PG_ENABLE, |
1915 | else | 1970 | enable ? 1 : 0); |
1916 | data &= ~RLC_PG_CNTL__STATIC_PER_CU_PG_ENABLE_MASK; | ||
1917 | if(default_data != data) | 1971 | if(default_data != data) |
1918 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); | 1972 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); |
1919 | } | 1973 | } |
@@ -1924,10 +1978,9 @@ static void gfx_v9_0_enable_gfx_dynamic_mg_power_gating(struct amdgpu_device *ad | |||
1924 | uint32_t data, default_data; | 1978 | uint32_t data, default_data; |
1925 | 1979 | ||
1926 | default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); | 1980 | default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); |
1927 | if (enable == true) | 1981 | data = REG_SET_FIELD(data, RLC_PG_CNTL, |
1928 | data |= RLC_PG_CNTL__DYN_PER_CU_PG_ENABLE_MASK; | 1982 | DYN_PER_CU_PG_ENABLE, |
1929 | else | 1983 | enable ? 1 : 0); |
1930 | data &= ~RLC_PG_CNTL__DYN_PER_CU_PG_ENABLE_MASK; | ||
1931 | if(default_data != data) | 1984 | if(default_data != data) |
1932 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); | 1985 | WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); |
1933 | } | 1986 | } |
@@ -1967,13 +2020,8 @@ static void gfx_v9_0_init_pg(struct amdgpu_device *adev) | |||
1967 | 2020 | ||
1968 | void gfx_v9_0_rlc_stop(struct amdgpu_device *adev) | 2021 | void gfx_v9_0_rlc_stop(struct amdgpu_device *adev) |
1969 | { | 2022 | { |
1970 | u32 tmp = RREG32_SOC15(GC, 0, mmRLC_CNTL); | 2023 | WREG32_FIELD15(GC, 0, RLC_CNTL, RLC_ENABLE_F32, 0); |
1971 | |||
1972 | tmp = REG_SET_FIELD(tmp, RLC_CNTL, RLC_ENABLE_F32, 0); | ||
1973 | WREG32_SOC15(GC, 0, mmRLC_CNTL, tmp); | ||
1974 | |||
1975 | gfx_v9_0_enable_gui_idle_interrupt(adev, false); | 2024 | gfx_v9_0_enable_gui_idle_interrupt(adev, false); |
1976 | |||
1977 | gfx_v9_0_wait_for_rlc_serdes(adev); | 2025 | gfx_v9_0_wait_for_rlc_serdes(adev); |
1978 | } | 2026 | } |
1979 | 2027 | ||
@@ -2045,8 +2093,10 @@ static int gfx_v9_0_rlc_resume(struct amdgpu_device *adev) | |||
2045 | { | 2093 | { |
2046 | int r; | 2094 | int r; |
2047 | 2095 | ||
2048 | if (amdgpu_sriov_vf(adev)) | 2096 | if (amdgpu_sriov_vf(adev)) { |
2097 | gfx_v9_0_init_csb(adev); | ||
2049 | return 0; | 2098 | return 0; |
2099 | } | ||
2050 | 2100 | ||
2051 | gfx_v9_0_rlc_stop(adev); | 2101 | gfx_v9_0_rlc_stop(adev); |
2052 | 2102 | ||
@@ -2463,6 +2513,13 @@ static int gfx_v9_0_mqd_init(struct amdgpu_ring *ring) | |||
2463 | mqd->compute_static_thread_mgmt_se3 = 0xffffffff; | 2513 | mqd->compute_static_thread_mgmt_se3 = 0xffffffff; |
2464 | mqd->compute_misc_reserved = 0x00000003; | 2514 | mqd->compute_misc_reserved = 0x00000003; |
2465 | 2515 | ||
2516 | mqd->dynamic_cu_mask_addr_lo = | ||
2517 | lower_32_bits(ring->mqd_gpu_addr | ||
2518 | + offsetof(struct v9_mqd_allocation, dynamic_cu_mask)); | ||
2519 | mqd->dynamic_cu_mask_addr_hi = | ||
2520 | upper_32_bits(ring->mqd_gpu_addr | ||
2521 | + offsetof(struct v9_mqd_allocation, dynamic_cu_mask)); | ||
2522 | |||
2466 | eop_base_addr = ring->eop_gpu_addr >> 8; | 2523 | eop_base_addr = ring->eop_gpu_addr >> 8; |
2467 | mqd->cp_hqd_eop_base_addr_lo = eop_base_addr; | 2524 | mqd->cp_hqd_eop_base_addr_lo = eop_base_addr; |
2468 | mqd->cp_hqd_eop_base_addr_hi = upper_32_bits(eop_base_addr); | 2525 | mqd->cp_hqd_eop_base_addr_hi = upper_32_bits(eop_base_addr); |
@@ -2486,10 +2543,10 @@ static int gfx_v9_0_mqd_init(struct amdgpu_ring *ring) | |||
2486 | DOORBELL_SOURCE, 0); | 2543 | DOORBELL_SOURCE, 0); |
2487 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL, | 2544 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL, |
2488 | DOORBELL_HIT, 0); | 2545 | DOORBELL_HIT, 0); |
2489 | } | 2546 | } else { |
2490 | else | ||
2491 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL, | 2547 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL, |
2492 | DOORBELL_EN, 0); | 2548 | DOORBELL_EN, 0); |
2549 | } | ||
2493 | 2550 | ||
2494 | mqd->cp_hqd_pq_doorbell_control = tmp; | 2551 | mqd->cp_hqd_pq_doorbell_control = tmp; |
2495 | 2552 | ||
@@ -2692,10 +2749,10 @@ static int gfx_v9_0_kiq_init_queue(struct amdgpu_ring *ring) | |||
2692 | 2749 | ||
2693 | gfx_v9_0_kiq_setting(ring); | 2750 | gfx_v9_0_kiq_setting(ring); |
2694 | 2751 | ||
2695 | if (adev->gfx.in_reset) { /* for GPU_RESET case */ | 2752 | if (adev->in_sriov_reset) { /* for GPU_RESET case */ |
2696 | /* reset MQD to a clean status */ | 2753 | /* reset MQD to a clean status */ |
2697 | if (adev->gfx.mec.mqd_backup[mqd_idx]) | 2754 | if (adev->gfx.mec.mqd_backup[mqd_idx]) |
2698 | memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(*mqd)); | 2755 | memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(struct v9_mqd_allocation)); |
2699 | 2756 | ||
2700 | /* reset ring buffer */ | 2757 | /* reset ring buffer */ |
2701 | ring->wptr = 0; | 2758 | ring->wptr = 0; |
@@ -2707,7 +2764,9 @@ static int gfx_v9_0_kiq_init_queue(struct amdgpu_ring *ring) | |||
2707 | soc15_grbm_select(adev, 0, 0, 0, 0); | 2764 | soc15_grbm_select(adev, 0, 0, 0, 0); |
2708 | mutex_unlock(&adev->srbm_mutex); | 2765 | mutex_unlock(&adev->srbm_mutex); |
2709 | } else { | 2766 | } else { |
2710 | memset((void *)mqd, 0, sizeof(*mqd)); | 2767 | memset((void *)mqd, 0, sizeof(struct v9_mqd_allocation)); |
2768 | ((struct v9_mqd_allocation *)mqd)->dynamic_cu_mask = 0xFFFFFFFF; | ||
2769 | ((struct v9_mqd_allocation *)mqd)->dynamic_rb_mask = 0xFFFFFFFF; | ||
2711 | mutex_lock(&adev->srbm_mutex); | 2770 | mutex_lock(&adev->srbm_mutex); |
2712 | soc15_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0); | 2771 | soc15_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0); |
2713 | gfx_v9_0_mqd_init(ring); | 2772 | gfx_v9_0_mqd_init(ring); |
@@ -2716,7 +2775,7 @@ static int gfx_v9_0_kiq_init_queue(struct amdgpu_ring *ring) | |||
2716 | mutex_unlock(&adev->srbm_mutex); | 2775 | mutex_unlock(&adev->srbm_mutex); |
2717 | 2776 | ||
2718 | if (adev->gfx.mec.mqd_backup[mqd_idx]) | 2777 | if (adev->gfx.mec.mqd_backup[mqd_idx]) |
2719 | memcpy(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(*mqd)); | 2778 | memcpy(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(struct v9_mqd_allocation)); |
2720 | } | 2779 | } |
2721 | 2780 | ||
2722 | return 0; | 2781 | return 0; |
@@ -2728,8 +2787,10 @@ static int gfx_v9_0_kcq_init_queue(struct amdgpu_ring *ring) | |||
2728 | struct v9_mqd *mqd = ring->mqd_ptr; | 2787 | struct v9_mqd *mqd = ring->mqd_ptr; |
2729 | int mqd_idx = ring - &adev->gfx.compute_ring[0]; | 2788 | int mqd_idx = ring - &adev->gfx.compute_ring[0]; |
2730 | 2789 | ||
2731 | if (!adev->gfx.in_reset && !adev->gfx.in_suspend) { | 2790 | if (!adev->in_sriov_reset && !adev->gfx.in_suspend) { |
2732 | memset((void *)mqd, 0, sizeof(*mqd)); | 2791 | memset((void *)mqd, 0, sizeof(struct v9_mqd_allocation)); |
2792 | ((struct v9_mqd_allocation *)mqd)->dynamic_cu_mask = 0xFFFFFFFF; | ||
2793 | ((struct v9_mqd_allocation *)mqd)->dynamic_rb_mask = 0xFFFFFFFF; | ||
2733 | mutex_lock(&adev->srbm_mutex); | 2794 | mutex_lock(&adev->srbm_mutex); |
2734 | soc15_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0); | 2795 | soc15_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0); |
2735 | gfx_v9_0_mqd_init(ring); | 2796 | gfx_v9_0_mqd_init(ring); |
@@ -2737,11 +2798,11 @@ static int gfx_v9_0_kcq_init_queue(struct amdgpu_ring *ring) | |||
2737 | mutex_unlock(&adev->srbm_mutex); | 2798 | mutex_unlock(&adev->srbm_mutex); |
2738 | 2799 | ||
2739 | if (adev->gfx.mec.mqd_backup[mqd_idx]) | 2800 | if (adev->gfx.mec.mqd_backup[mqd_idx]) |
2740 | memcpy(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(*mqd)); | 2801 | memcpy(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(struct v9_mqd_allocation)); |
2741 | } else if (adev->gfx.in_reset) { /* for GPU_RESET case */ | 2802 | } else if (adev->in_sriov_reset) { /* for GPU_RESET case */ |
2742 | /* reset MQD to a clean status */ | 2803 | /* reset MQD to a clean status */ |
2743 | if (adev->gfx.mec.mqd_backup[mqd_idx]) | 2804 | if (adev->gfx.mec.mqd_backup[mqd_idx]) |
2744 | memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(*mqd)); | 2805 | memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(struct v9_mqd_allocation)); |
2745 | 2806 | ||
2746 | /* reset ring buffer */ | 2807 | /* reset ring buffer */ |
2747 | ring->wptr = 0; | 2808 | ring->wptr = 0; |
@@ -2882,12 +2943,70 @@ static int gfx_v9_0_hw_init(void *handle) | |||
2882 | return r; | 2943 | return r; |
2883 | } | 2944 | } |
2884 | 2945 | ||
2946 | static int gfx_v9_0_kcq_disable(struct amdgpu_ring *kiq_ring,struct amdgpu_ring *ring) | ||
2947 | { | ||
2948 | struct amdgpu_device *adev = kiq_ring->adev; | ||
2949 | uint32_t scratch, tmp = 0; | ||
2950 | int r, i; | ||
2951 | |||
2952 | r = amdgpu_gfx_scratch_get(adev, &scratch); | ||
2953 | if (r) { | ||
2954 | DRM_ERROR("Failed to get scratch reg (%d).\n", r); | ||
2955 | return r; | ||
2956 | } | ||
2957 | WREG32(scratch, 0xCAFEDEAD); | ||
2958 | |||
2959 | r = amdgpu_ring_alloc(kiq_ring, 10); | ||
2960 | if (r) { | ||
2961 | DRM_ERROR("Failed to lock KIQ (%d).\n", r); | ||
2962 | amdgpu_gfx_scratch_free(adev, scratch); | ||
2963 | return r; | ||
2964 | } | ||
2965 | |||
2966 | /* unmap queues */ | ||
2967 | amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_UNMAP_QUEUES, 4)); | ||
2968 | amdgpu_ring_write(kiq_ring, /* Q_sel: 0, vmid: 0, engine: 0, num_Q: 1 */ | ||
2969 | PACKET3_UNMAP_QUEUES_ACTION(1) | /* RESET_QUEUES */ | ||
2970 | PACKET3_UNMAP_QUEUES_QUEUE_SEL(0) | | ||
2971 | PACKET3_UNMAP_QUEUES_ENGINE_SEL(0) | | ||
2972 | PACKET3_UNMAP_QUEUES_NUM_QUEUES(1)); | ||
2973 | amdgpu_ring_write(kiq_ring, PACKET3_UNMAP_QUEUES_DOORBELL_OFFSET0(ring->doorbell_index)); | ||
2974 | amdgpu_ring_write(kiq_ring, 0); | ||
2975 | amdgpu_ring_write(kiq_ring, 0); | ||
2976 | amdgpu_ring_write(kiq_ring, 0); | ||
2977 | /* write to scratch for completion */ | ||
2978 | amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1)); | ||
2979 | amdgpu_ring_write(kiq_ring, (scratch - PACKET3_SET_UCONFIG_REG_START)); | ||
2980 | amdgpu_ring_write(kiq_ring, 0xDEADBEEF); | ||
2981 | amdgpu_ring_commit(kiq_ring); | ||
2982 | |||
2983 | for (i = 0; i < adev->usec_timeout; i++) { | ||
2984 | tmp = RREG32(scratch); | ||
2985 | if (tmp == 0xDEADBEEF) | ||
2986 | break; | ||
2987 | DRM_UDELAY(1); | ||
2988 | } | ||
2989 | if (i >= adev->usec_timeout) { | ||
2990 | DRM_ERROR("KCQ disabled failed (scratch(0x%04X)=0x%08X)\n", scratch, tmp); | ||
2991 | r = -EINVAL; | ||
2992 | } | ||
2993 | amdgpu_gfx_scratch_free(adev, scratch); | ||
2994 | return r; | ||
2995 | } | ||
2996 | |||
2997 | |||
2885 | static int gfx_v9_0_hw_fini(void *handle) | 2998 | static int gfx_v9_0_hw_fini(void *handle) |
2886 | { | 2999 | { |
2887 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 3000 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
3001 | int i; | ||
2888 | 3002 | ||
2889 | amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0); | 3003 | amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0); |
2890 | amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0); | 3004 | amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0); |
3005 | |||
3006 | /* disable KCQ to avoid CPC touch memory not valid anymore */ | ||
3007 | for (i = 0; i < adev->gfx.num_compute_rings; i++) | ||
3008 | gfx_v9_0_kcq_disable(&adev->gfx.kiq.ring, &adev->gfx.compute_ring[i]); | ||
3009 | |||
2891 | if (amdgpu_sriov_vf(adev)) { | 3010 | if (amdgpu_sriov_vf(adev)) { |
2892 | pr_debug("For SRIOV client, shouldn't do anything.\n"); | 3011 | pr_debug("For SRIOV client, shouldn't do anything.\n"); |
2893 | return 0; | 3012 | return 0; |
@@ -2930,15 +3049,10 @@ static bool gfx_v9_0_is_idle(void *handle) | |||
2930 | static int gfx_v9_0_wait_for_idle(void *handle) | 3049 | static int gfx_v9_0_wait_for_idle(void *handle) |
2931 | { | 3050 | { |
2932 | unsigned i; | 3051 | unsigned i; |
2933 | u32 tmp; | ||
2934 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 3052 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
2935 | 3053 | ||
2936 | for (i = 0; i < adev->usec_timeout; i++) { | 3054 | for (i = 0; i < adev->usec_timeout; i++) { |
2937 | /* read MC_STATUS */ | 3055 | if (gfx_v9_0_is_idle(handle)) |
2938 | tmp = RREG32_SOC15(GC, 0, mmGRBM_STATUS) & | ||
2939 | GRBM_STATUS__GUI_ACTIVE_MASK; | ||
2940 | |||
2941 | if (!REG_GET_FIELD(tmp, GRBM_STATUS, GUI_ACTIVE)) | ||
2942 | return 0; | 3056 | return 0; |
2943 | udelay(1); | 3057 | udelay(1); |
2944 | } | 3058 | } |
@@ -3497,9 +3611,11 @@ static void gfx_v9_0_ring_set_wptr_gfx(struct amdgpu_ring *ring) | |||
3497 | static void gfx_v9_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) | 3611 | static void gfx_v9_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) |
3498 | { | 3612 | { |
3499 | u32 ref_and_mask, reg_mem_engine; | 3613 | u32 ref_and_mask, reg_mem_engine; |
3500 | struct nbio_hdp_flush_reg *nbio_hf_reg; | 3614 | const struct nbio_hdp_flush_reg *nbio_hf_reg; |
3501 | 3615 | ||
3502 | if (ring->adev->asic_type == CHIP_VEGA10) | 3616 | if (ring->adev->flags & AMD_IS_APU) |
3617 | nbio_hf_reg = &nbio_v7_0_hdp_flush_reg; | ||
3618 | else | ||
3503 | nbio_hf_reg = &nbio_v6_1_hdp_flush_reg; | 3619 | nbio_hf_reg = &nbio_v6_1_hdp_flush_reg; |
3504 | 3620 | ||
3505 | if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) { | 3621 | if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) { |
@@ -3528,7 +3644,7 @@ static void gfx_v9_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) | |||
3528 | static void gfx_v9_0_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) | 3644 | static void gfx_v9_0_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) |
3529 | { | 3645 | { |
3530 | gfx_v9_0_write_data_to_reg(ring, 0, true, | 3646 | gfx_v9_0_write_data_to_reg(ring, 0, true, |
3531 | SOC15_REG_OFFSET(HDP, 0, mmHDP_DEBUG0), 1); | 3647 | SOC15_REG_OFFSET(HDP, 0, mmHDP_READ_CACHE_INVALIDATE), 1); |
3532 | } | 3648 | } |
3533 | 3649 | ||
3534 | static void gfx_v9_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, | 3650 | static void gfx_v9_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, |
@@ -3718,7 +3834,7 @@ static void gfx_v9_ring_emit_sb(struct amdgpu_ring *ring) | |||
3718 | 3834 | ||
3719 | static void gfx_v9_0_ring_emit_ce_meta(struct amdgpu_ring *ring) | 3835 | static void gfx_v9_0_ring_emit_ce_meta(struct amdgpu_ring *ring) |
3720 | { | 3836 | { |
3721 | static struct v9_ce_ib_state ce_payload = {0}; | 3837 | struct v9_ce_ib_state ce_payload = {0}; |
3722 | uint64_t csa_addr; | 3838 | uint64_t csa_addr; |
3723 | int cnt; | 3839 | int cnt; |
3724 | 3840 | ||
@@ -3737,7 +3853,7 @@ static void gfx_v9_0_ring_emit_ce_meta(struct amdgpu_ring *ring) | |||
3737 | 3853 | ||
3738 | static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring) | 3854 | static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring) |
3739 | { | 3855 | { |
3740 | static struct v9_de_ib_state de_payload = {0}; | 3856 | struct v9_de_ib_state de_payload = {0}; |
3741 | uint64_t csa_addr, gds_addr; | 3857 | uint64_t csa_addr, gds_addr; |
3742 | int cnt; | 3858 | int cnt; |
3743 | 3859 | ||
@@ -3757,6 +3873,12 @@ static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring) | |||
3757 | amdgpu_ring_write_multiple(ring, (void *)&de_payload, sizeof(de_payload) >> 2); | 3873 | amdgpu_ring_write_multiple(ring, (void *)&de_payload, sizeof(de_payload) >> 2); |
3758 | } | 3874 | } |
3759 | 3875 | ||
3876 | static void gfx_v9_0_ring_emit_tmz(struct amdgpu_ring *ring, bool start) | ||
3877 | { | ||
3878 | amdgpu_ring_write(ring, PACKET3(PACKET3_FRAME_CONTROL, 0)); | ||
3879 | amdgpu_ring_write(ring, FRAME_CMD(start ? 0 : 1)); /* frame_end */ | ||
3880 | } | ||
3881 | |||
3760 | static void gfx_v9_ring_emit_cntxcntl(struct amdgpu_ring *ring, uint32_t flags) | 3882 | static void gfx_v9_ring_emit_cntxcntl(struct amdgpu_ring *ring, uint32_t flags) |
3761 | { | 3883 | { |
3762 | uint32_t dw2 = 0; | 3884 | uint32_t dw2 = 0; |
@@ -3764,6 +3886,8 @@ static void gfx_v9_ring_emit_cntxcntl(struct amdgpu_ring *ring, uint32_t flags) | |||
3764 | if (amdgpu_sriov_vf(ring->adev)) | 3886 | if (amdgpu_sriov_vf(ring->adev)) |
3765 | gfx_v9_0_ring_emit_ce_meta(ring); | 3887 | gfx_v9_0_ring_emit_ce_meta(ring); |
3766 | 3888 | ||
3889 | gfx_v9_0_ring_emit_tmz(ring, true); | ||
3890 | |||
3767 | dw2 |= 0x80000000; /* set load_enable otherwise this package is just NOPs */ | 3891 | dw2 |= 0x80000000; /* set load_enable otherwise this package is just NOPs */ |
3768 | if (flags & AMDGPU_HAVE_CTX_SWITCH) { | 3892 | if (flags & AMDGPU_HAVE_CTX_SWITCH) { |
3769 | /* set load_global_config & load_global_uconfig */ | 3893 | /* set load_global_config & load_global_uconfig */ |
@@ -3814,12 +3938,6 @@ static void gfx_v9_0_ring_emit_patch_cond_exec(struct amdgpu_ring *ring, unsigne | |||
3814 | ring->ring[offset] = (ring->ring_size>>2) - offset + cur; | 3938 | ring->ring[offset] = (ring->ring_size>>2) - offset + cur; |
3815 | } | 3939 | } |
3816 | 3940 | ||
3817 | static void gfx_v9_0_ring_emit_tmz(struct amdgpu_ring *ring, bool start) | ||
3818 | { | ||
3819 | amdgpu_ring_write(ring, PACKET3(PACKET3_FRAME_CONTROL, 0)); | ||
3820 | amdgpu_ring_write(ring, FRAME_CMD(start ? 0 : 1)); /* frame_end */ | ||
3821 | } | ||
3822 | |||
3823 | static void gfx_v9_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg) | 3941 | static void gfx_v9_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg) |
3824 | { | 3942 | { |
3825 | struct amdgpu_device *adev = ring->adev; | 3943 | struct amdgpu_device *adev = ring->adev; |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c index 6c8040e616c4..c17996e18086 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c | |||
@@ -319,6 +319,12 @@ void gfxhub_v1_0_set_fault_enable_default(struct amdgpu_device *adev, | |||
319 | WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value); | 319 | WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value); |
320 | tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL, | 320 | tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL, |
321 | EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value); | 321 | EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value); |
322 | if (!value) { | ||
323 | tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL, | ||
324 | CRASH_ON_NO_RETRY_FAULT, 1); | ||
325 | tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL, | ||
326 | CRASH_ON_RETRY_FAULT, 1); | ||
327 | } | ||
322 | WREG32_SOC15(GC, 0, mmVM_L2_PROTECTION_FAULT_CNTL, tmp); | 328 | WREG32_SOC15(GC, 0, mmVM_L2_PROTECTION_FAULT_CNTL, tmp); |
323 | } | 329 | } |
324 | 330 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c index 5be9c83dfcf7..f4603a7c8ef3 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | |||
@@ -831,7 +831,7 @@ static int gmc_v6_0_sw_init(void *handle) | |||
831 | if (r) | 831 | if (r) |
832 | return r; | 832 | return r; |
833 | 833 | ||
834 | amdgpu_vm_adjust_size(adev, 64, 4); | 834 | amdgpu_vm_adjust_size(adev, 64, 9); |
835 | adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18; | 835 | adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18; |
836 | 836 | ||
837 | adev->mc.mc_mask = 0xffffffffffULL; | 837 | adev->mc.mc_mask = 0xffffffffffULL; |
@@ -901,6 +901,8 @@ static int gmc_v6_0_sw_fini(void *handle) | |||
901 | gmc_v6_0_gart_fini(adev); | 901 | gmc_v6_0_gart_fini(adev); |
902 | amdgpu_gem_force_release(adev); | 902 | amdgpu_gem_force_release(adev); |
903 | amdgpu_bo_fini(adev); | 903 | amdgpu_bo_fini(adev); |
904 | release_firmware(adev->mc.fw); | ||
905 | adev->mc.fw = NULL; | ||
904 | 906 | ||
905 | return 0; | 907 | return 0; |
906 | } | 908 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index eace9e7182c8..b0528ca9207b 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | |||
@@ -970,7 +970,7 @@ static int gmc_v7_0_sw_init(void *handle) | |||
970 | * Currently set to 4GB ((1 << 20) 4k pages). | 970 | * Currently set to 4GB ((1 << 20) 4k pages). |
971 | * Max GPUVM size for cayman and SI is 40 bits. | 971 | * Max GPUVM size for cayman and SI is 40 bits. |
972 | */ | 972 | */ |
973 | amdgpu_vm_adjust_size(adev, 64, 4); | 973 | amdgpu_vm_adjust_size(adev, 64, 9); |
974 | adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18; | 974 | adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18; |
975 | 975 | ||
976 | /* Set the internal MC address mask | 976 | /* Set the internal MC address mask |
@@ -1050,6 +1050,8 @@ static int gmc_v7_0_sw_fini(void *handle) | |||
1050 | gmc_v7_0_gart_fini(adev); | 1050 | gmc_v7_0_gart_fini(adev); |
1051 | amdgpu_gem_force_release(adev); | 1051 | amdgpu_gem_force_release(adev); |
1052 | amdgpu_bo_fini(adev); | 1052 | amdgpu_bo_fini(adev); |
1053 | release_firmware(adev->mc.fw); | ||
1054 | adev->mc.fw = NULL; | ||
1053 | 1055 | ||
1054 | return 0; | 1056 | return 0; |
1055 | } | 1057 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 3b3326daf32b..f368cfe2f585 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | |||
@@ -1067,7 +1067,7 @@ static int gmc_v8_0_sw_init(void *handle) | |||
1067 | * Currently set to 4GB ((1 << 20) 4k pages). | 1067 | * Currently set to 4GB ((1 << 20) 4k pages). |
1068 | * Max GPUVM size for cayman and SI is 40 bits. | 1068 | * Max GPUVM size for cayman and SI is 40 bits. |
1069 | */ | 1069 | */ |
1070 | amdgpu_vm_adjust_size(adev, 64, 4); | 1070 | amdgpu_vm_adjust_size(adev, 64, 9); |
1071 | adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18; | 1071 | adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18; |
1072 | 1072 | ||
1073 | /* Set the internal MC address mask | 1073 | /* Set the internal MC address mask |
@@ -1147,6 +1147,8 @@ static int gmc_v8_0_sw_fini(void *handle) | |||
1147 | gmc_v8_0_gart_fini(adev); | 1147 | gmc_v8_0_gart_fini(adev); |
1148 | amdgpu_gem_force_release(adev); | 1148 | amdgpu_gem_force_release(adev); |
1149 | amdgpu_bo_fini(adev); | 1149 | amdgpu_bo_fini(adev); |
1150 | release_firmware(adev->mc.fw); | ||
1151 | adev->mc.fw = NULL; | ||
1150 | 1152 | ||
1151 | return 0; | 1153 | return 0; |
1152 | } | 1154 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index d04d0b123212..c8f1aebeac7a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #include "vega10/DC/dce_12_0_offset.h" | 32 | #include "vega10/DC/dce_12_0_offset.h" |
33 | #include "vega10/DC/dce_12_0_sh_mask.h" | 33 | #include "vega10/DC/dce_12_0_sh_mask.h" |
34 | #include "vega10/vega10_enum.h" | 34 | #include "vega10/vega10_enum.h" |
35 | #include "vega10/MMHUB/mmhub_1_0_offset.h" | ||
36 | #include "vega10/ATHUB/athub_1_0_offset.h" | ||
35 | 37 | ||
36 | #include "soc15_common.h" | 38 | #include "soc15_common.h" |
37 | 39 | ||
@@ -71,13 +73,25 @@ static const u32 golden_settings_vega10_hdp[] = | |||
71 | 0xf6e, 0x0fffffff, 0x00000000, | 73 | 0xf6e, 0x0fffffff, 0x00000000, |
72 | }; | 74 | }; |
73 | 75 | ||
76 | static const u32 golden_settings_mmhub_1_0_0[] = | ||
77 | { | ||
78 | SOC15_REG_OFFSET(MMHUB, 0, mmDAGB1_WRCLI2), 0x00000007, 0xfe5fe0fa, | ||
79 | SOC15_REG_OFFSET(MMHUB, 0, mmMMEA1_DRAM_WR_CLI2GRP_MAP0), 0x00000030, 0x55555565 | ||
80 | }; | ||
81 | |||
82 | static const u32 golden_settings_athub_1_0_0[] = | ||
83 | { | ||
84 | SOC15_REG_OFFSET(ATHUB, 0, mmRPB_ARB_CNTL), 0x0000ff00, 0x00000800, | ||
85 | SOC15_REG_OFFSET(ATHUB, 0, mmRPB_ARB_CNTL2), 0x00ff00ff, 0x00080008 | ||
86 | }; | ||
87 | |||
74 | static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev, | 88 | static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev, |
75 | struct amdgpu_irq_src *src, | 89 | struct amdgpu_irq_src *src, |
76 | unsigned type, | 90 | unsigned type, |
77 | enum amdgpu_interrupt_state state) | 91 | enum amdgpu_interrupt_state state) |
78 | { | 92 | { |
79 | struct amdgpu_vmhub *hub; | 93 | struct amdgpu_vmhub *hub; |
80 | u32 tmp, reg, bits, i; | 94 | u32 tmp, reg, bits, i, j; |
81 | 95 | ||
82 | bits = VM_CONTEXT1_CNTL__RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | | 96 | bits = VM_CONTEXT1_CNTL__RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | |
83 | VM_CONTEXT1_CNTL__DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | | 97 | VM_CONTEXT1_CNTL__DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | |
@@ -89,43 +103,26 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev, | |||
89 | 103 | ||
90 | switch (state) { | 104 | switch (state) { |
91 | case AMDGPU_IRQ_STATE_DISABLE: | 105 | case AMDGPU_IRQ_STATE_DISABLE: |
92 | /* MM HUB */ | 106 | for (j = 0; j < AMDGPU_MAX_VMHUBS; j++) { |
93 | hub = &adev->vmhub[AMDGPU_MMHUB]; | 107 | hub = &adev->vmhub[j]; |
94 | for (i = 0; i< 16; i++) { | 108 | for (i = 0; i < 16; i++) { |
95 | reg = hub->vm_context0_cntl + i; | 109 | reg = hub->vm_context0_cntl + i; |
96 | tmp = RREG32(reg); | 110 | tmp = RREG32(reg); |
97 | tmp &= ~bits; | 111 | tmp &= ~bits; |
98 | WREG32(reg, tmp); | 112 | WREG32(reg, tmp); |
99 | } | 113 | } |
100 | |||
101 | /* GFX HUB */ | ||
102 | hub = &adev->vmhub[AMDGPU_GFXHUB]; | ||
103 | for (i = 0; i < 16; i++) { | ||
104 | reg = hub->vm_context0_cntl + i; | ||
105 | tmp = RREG32(reg); | ||
106 | tmp &= ~bits; | ||
107 | WREG32(reg, tmp); | ||
108 | } | 114 | } |
109 | break; | 115 | break; |
110 | case AMDGPU_IRQ_STATE_ENABLE: | 116 | case AMDGPU_IRQ_STATE_ENABLE: |
111 | /* MM HUB */ | 117 | for (j = 0; j < AMDGPU_MAX_VMHUBS; j++) { |
112 | hub = &adev->vmhub[AMDGPU_MMHUB]; | 118 | hub = &adev->vmhub[j]; |
113 | for (i = 0; i< 16; i++) { | 119 | for (i = 0; i < 16; i++) { |
114 | reg = hub->vm_context0_cntl + i; | 120 | reg = hub->vm_context0_cntl + i; |
115 | tmp = RREG32(reg); | 121 | tmp = RREG32(reg); |
116 | tmp |= bits; | 122 | tmp |= bits; |
117 | WREG32(reg, tmp); | 123 | WREG32(reg, tmp); |
118 | } | 124 | } |
119 | |||
120 | /* GFX HUB */ | ||
121 | hub = &adev->vmhub[AMDGPU_GFXHUB]; | ||
122 | for (i = 0; i < 16; i++) { | ||
123 | reg = hub->vm_context0_cntl + i; | ||
124 | tmp = RREG32(reg); | ||
125 | tmp |= bits; | ||
126 | WREG32(reg, tmp); | ||
127 | } | 125 | } |
128 | break; | ||
129 | default: | 126 | default: |
130 | break; | 127 | break; |
131 | } | 128 | } |
@@ -395,7 +392,16 @@ static int gmc_v9_0_early_init(void *handle) | |||
395 | static int gmc_v9_0_late_init(void *handle) | 392 | static int gmc_v9_0_late_init(void *handle) |
396 | { | 393 | { |
397 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 394 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
398 | unsigned vm_inv_eng[AMDGPU_MAX_VMHUBS] = { 3, 3 }; | 395 | /* |
396 | * The latest engine allocation on gfx9 is: | ||
397 | * Engine 0, 1: idle | ||
398 | * Engine 2, 3: firmware | ||
399 | * Engine 4~13: amdgpu ring, subject to change when ring number changes | ||
400 | * Engine 14~15: idle | ||
401 | * Engine 16: kfd tlb invalidation | ||
402 | * Engine 17: Gart flushes | ||
403 | */ | ||
404 | unsigned vm_inv_eng[AMDGPU_MAX_VMHUBS] = { 4, 4 }; | ||
399 | unsigned i; | 405 | unsigned i; |
400 | 406 | ||
401 | for(i = 0; i < adev->num_rings; ++i) { | 407 | for(i = 0; i < adev->num_rings; ++i) { |
@@ -408,9 +414,9 @@ static int gmc_v9_0_late_init(void *handle) | |||
408 | ring->funcs->vmhub); | 414 | ring->funcs->vmhub); |
409 | } | 415 | } |
410 | 416 | ||
411 | /* Engine 17 is used for GART flushes */ | 417 | /* Engine 16 is used for KFD and 17 for GART flushes */ |
412 | for(i = 0; i < AMDGPU_MAX_VMHUBS; ++i) | 418 | for(i = 0; i < AMDGPU_MAX_VMHUBS; ++i) |
413 | BUG_ON(vm_inv_eng[i] > 17); | 419 | BUG_ON(vm_inv_eng[i] > 16); |
414 | 420 | ||
415 | return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); | 421 | return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); |
416 | } | 422 | } |
@@ -682,8 +688,17 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev) | |||
682 | { | 688 | { |
683 | switch (adev->asic_type) { | 689 | switch (adev->asic_type) { |
684 | case CHIP_VEGA10: | 690 | case CHIP_VEGA10: |
691 | amdgpu_program_register_sequence(adev, | ||
692 | golden_settings_mmhub_1_0_0, | ||
693 | (const u32)ARRAY_SIZE(golden_settings_mmhub_1_0_0)); | ||
694 | amdgpu_program_register_sequence(adev, | ||
695 | golden_settings_athub_1_0_0, | ||
696 | (const u32)ARRAY_SIZE(golden_settings_athub_1_0_0)); | ||
685 | break; | 697 | break; |
686 | case CHIP_RAVEN: | 698 | case CHIP_RAVEN: |
699 | amdgpu_program_register_sequence(adev, | ||
700 | golden_settings_athub_1_0_0, | ||
701 | (const u32)ARRAY_SIZE(golden_settings_athub_1_0_0)); | ||
687 | break; | 702 | break; |
688 | default: | 703 | default: |
689 | break; | 704 | break; |
@@ -713,12 +728,6 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) | |||
713 | if (r) | 728 | if (r) |
714 | return r; | 729 | return r; |
715 | 730 | ||
716 | /* After HDP is initialized, flush HDP.*/ | ||
717 | if (adev->flags & AMD_IS_APU) | ||
718 | nbio_v7_0_hdp_flush(adev); | ||
719 | else | ||
720 | nbio_v6_1_hdp_flush(adev); | ||
721 | |||
722 | switch (adev->asic_type) { | 731 | switch (adev->asic_type) { |
723 | case CHIP_RAVEN: | 732 | case CHIP_RAVEN: |
724 | mmhub_v1_0_initialize_power_gating(adev); | 733 | mmhub_v1_0_initialize_power_gating(adev); |
@@ -736,13 +745,16 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) | |||
736 | if (r) | 745 | if (r) |
737 | return r; | 746 | return r; |
738 | 747 | ||
739 | tmp = RREG32_SOC15(HDP, 0, mmHDP_MISC_CNTL); | 748 | WREG32_FIELD15(HDP, 0, HDP_MISC_CNTL, FLUSH_INVALIDATE_CACHE, 1); |
740 | tmp |= HDP_MISC_CNTL__FLUSH_INVALIDATE_CACHE_MASK; | ||
741 | WREG32_SOC15(HDP, 0, mmHDP_MISC_CNTL, tmp); | ||
742 | 749 | ||
743 | tmp = RREG32_SOC15(HDP, 0, mmHDP_HOST_PATH_CNTL); | 750 | tmp = RREG32_SOC15(HDP, 0, mmHDP_HOST_PATH_CNTL); |
744 | WREG32_SOC15(HDP, 0, mmHDP_HOST_PATH_CNTL, tmp); | 751 | WREG32_SOC15(HDP, 0, mmHDP_HOST_PATH_CNTL, tmp); |
745 | 752 | ||
753 | /* After HDP is initialized, flush HDP.*/ | ||
754 | if (adev->flags & AMD_IS_APU) | ||
755 | nbio_v7_0_hdp_flush(adev); | ||
756 | else | ||
757 | nbio_v6_1_hdp_flush(adev); | ||
746 | 758 | ||
747 | if (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) | 759 | if (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) |
748 | value = false; | 760 | value = false; |
@@ -751,7 +763,6 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) | |||
751 | 763 | ||
752 | gfxhub_v1_0_set_fault_enable_default(adev, value); | 764 | gfxhub_v1_0_set_fault_enable_default(adev, value); |
753 | mmhub_v1_0_set_fault_enable_default(adev, value); | 765 | mmhub_v1_0_set_fault_enable_default(adev, value); |
754 | |||
755 | gmc_v9_0_gart_flush_gpu_tlb(adev, 0); | 766 | gmc_v9_0_gart_flush_gpu_tlb(adev, 0); |
756 | 767 | ||
757 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", | 768 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", |
@@ -770,17 +781,11 @@ static int gmc_v9_0_hw_init(void *handle) | |||
770 | gmc_v9_0_init_golden_registers(adev); | 781 | gmc_v9_0_init_golden_registers(adev); |
771 | 782 | ||
772 | if (adev->mode_info.num_crtc) { | 783 | if (adev->mode_info.num_crtc) { |
773 | u32 tmp; | ||
774 | |||
775 | /* Lockout access through VGA aperture*/ | 784 | /* Lockout access through VGA aperture*/ |
776 | tmp = RREG32_SOC15(DCE, 0, mmVGA_HDP_CONTROL); | 785 | WREG32_FIELD15(DCE, 0, VGA_HDP_CONTROL, VGA_MEMORY_DISABLE, 1); |
777 | tmp = REG_SET_FIELD(tmp, VGA_HDP_CONTROL, VGA_MEMORY_DISABLE, 1); | ||
778 | WREG32_SOC15(DCE, 0, mmVGA_HDP_CONTROL, tmp); | ||
779 | 786 | ||
780 | /* disable VGA render */ | 787 | /* disable VGA render */ |
781 | tmp = RREG32_SOC15(DCE, 0, mmVGA_RENDER_CONTROL); | 788 | WREG32_FIELD15(DCE, 0, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0); |
782 | tmp = REG_SET_FIELD(tmp, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0); | ||
783 | WREG32_SOC15(DCE, 0, mmVGA_RENDER_CONTROL, tmp); | ||
784 | } | 789 | } |
785 | 790 | ||
786 | r = gmc_v9_0_gart_enable(adev); | 791 | r = gmc_v9_0_gart_enable(adev); |
@@ -822,9 +827,7 @@ static int gmc_v9_0_suspend(void *handle) | |||
822 | { | 827 | { |
823 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 828 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
824 | 829 | ||
825 | gmc_v9_0_hw_fini(adev); | 830 | return gmc_v9_0_hw_fini(adev); |
826 | |||
827 | return 0; | ||
828 | } | 831 | } |
829 | 832 | ||
830 | static int gmc_v9_0_resume(void *handle) | 833 | static int gmc_v9_0_resume(void *handle) |
diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c index 7a0ea27ac429..bd592cb39f37 100644 --- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c | |||
@@ -208,6 +208,34 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev) | |||
208 | } | 208 | } |
209 | 209 | ||
210 | /** | 210 | /** |
211 | * iceland_ih_prescreen_iv - prescreen an interrupt vector | ||
212 | * | ||
213 | * @adev: amdgpu_device pointer | ||
214 | * | ||
215 | * Returns true if the interrupt vector should be further processed. | ||
216 | */ | ||
217 | static bool iceland_ih_prescreen_iv(struct amdgpu_device *adev) | ||
218 | { | ||
219 | u32 ring_index = adev->irq.ih.rptr >> 2; | ||
220 | u16 pasid; | ||
221 | |||
222 | switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) { | ||
223 | case 146: | ||
224 | case 147: | ||
225 | pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16; | ||
226 | if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid)) | ||
227 | return true; | ||
228 | break; | ||
229 | default: | ||
230 | /* Not a VM fault */ | ||
231 | return true; | ||
232 | } | ||
233 | |||
234 | adev->irq.ih.rptr += 16; | ||
235 | return false; | ||
236 | } | ||
237 | |||
238 | /** | ||
211 | * iceland_ih_decode_iv - decode an interrupt vector | 239 | * iceland_ih_decode_iv - decode an interrupt vector |
212 | * | 240 | * |
213 | * @adev: amdgpu_device pointer | 241 | * @adev: amdgpu_device pointer |
@@ -412,6 +440,7 @@ static const struct amd_ip_funcs iceland_ih_ip_funcs = { | |||
412 | 440 | ||
413 | static const struct amdgpu_ih_funcs iceland_ih_funcs = { | 441 | static const struct amdgpu_ih_funcs iceland_ih_funcs = { |
414 | .get_wptr = iceland_ih_get_wptr, | 442 | .get_wptr = iceland_ih_get_wptr, |
443 | .prescreen_iv = iceland_ih_prescreen_iv, | ||
415 | .decode_iv = iceland_ih_decode_iv, | 444 | .decode_iv = iceland_ih_decode_iv, |
416 | .set_rptr = iceland_ih_set_rptr | 445 | .set_rptr = iceland_ih_set_rptr |
417 | }; | 446 | }; |
diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c index 3bbf2ccfca89..f33d1ffdb20b 100644 --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #define KV_MINIMUM_ENGINE_CLOCK 800 | 42 | #define KV_MINIMUM_ENGINE_CLOCK 800 |
43 | #define SMC_RAM_END 0x40000 | 43 | #define SMC_RAM_END 0x40000 |
44 | 44 | ||
45 | static void kv_dpm_set_dpm_funcs(struct amdgpu_device *adev); | ||
46 | static void kv_dpm_set_irq_funcs(struct amdgpu_device *adev); | 45 | static void kv_dpm_set_irq_funcs(struct amdgpu_device *adev); |
47 | static int kv_enable_nb_dpm(struct amdgpu_device *adev, | 46 | static int kv_enable_nb_dpm(struct amdgpu_device *adev, |
48 | bool enable); | 47 | bool enable); |
@@ -64,7 +63,7 @@ static int kv_set_thermal_temperature_range(struct amdgpu_device *adev, | |||
64 | int min_temp, int max_temp); | 63 | int min_temp, int max_temp); |
65 | static int kv_init_fps_limits(struct amdgpu_device *adev); | 64 | static int kv_init_fps_limits(struct amdgpu_device *adev); |
66 | 65 | ||
67 | static void kv_dpm_powergate_uvd(struct amdgpu_device *adev, bool gate); | 66 | static void kv_dpm_powergate_uvd(void *handle, bool gate); |
68 | static void kv_dpm_powergate_vce(struct amdgpu_device *adev, bool gate); | 67 | static void kv_dpm_powergate_vce(struct amdgpu_device *adev, bool gate); |
69 | static void kv_dpm_powergate_samu(struct amdgpu_device *adev, bool gate); | 68 | static void kv_dpm_powergate_samu(struct amdgpu_device *adev, bool gate); |
70 | static void kv_dpm_powergate_acp(struct amdgpu_device *adev, bool gate); | 69 | static void kv_dpm_powergate_acp(struct amdgpu_device *adev, bool gate); |
@@ -1245,8 +1244,9 @@ static void kv_update_requested_ps(struct amdgpu_device *adev, | |||
1245 | adev->pm.dpm.requested_ps = &pi->requested_rps; | 1244 | adev->pm.dpm.requested_ps = &pi->requested_rps; |
1246 | } | 1245 | } |
1247 | 1246 | ||
1248 | static void kv_dpm_enable_bapm(struct amdgpu_device *adev, bool enable) | 1247 | static void kv_dpm_enable_bapm(void *handle, bool enable) |
1249 | { | 1248 | { |
1249 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
1250 | struct kv_power_info *pi = kv_get_pi(adev); | 1250 | struct kv_power_info *pi = kv_get_pi(adev); |
1251 | int ret; | 1251 | int ret; |
1252 | 1252 | ||
@@ -1672,8 +1672,9 @@ static int kv_update_acp_dpm(struct amdgpu_device *adev, bool gate) | |||
1672 | return kv_enable_acp_dpm(adev, !gate); | 1672 | return kv_enable_acp_dpm(adev, !gate); |
1673 | } | 1673 | } |
1674 | 1674 | ||
1675 | static void kv_dpm_powergate_uvd(struct amdgpu_device *adev, bool gate) | 1675 | static void kv_dpm_powergate_uvd(void *handle, bool gate) |
1676 | { | 1676 | { |
1677 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
1677 | struct kv_power_info *pi = kv_get_pi(adev); | 1678 | struct kv_power_info *pi = kv_get_pi(adev); |
1678 | int ret; | 1679 | int ret; |
1679 | 1680 | ||
@@ -1868,10 +1869,11 @@ static int kv_enable_nb_dpm(struct amdgpu_device *adev, | |||
1868 | return ret; | 1869 | return ret; |
1869 | } | 1870 | } |
1870 | 1871 | ||
1871 | static int kv_dpm_force_performance_level(struct amdgpu_device *adev, | 1872 | static int kv_dpm_force_performance_level(void *handle, |
1872 | enum amd_dpm_forced_level level) | 1873 | enum amd_dpm_forced_level level) |
1873 | { | 1874 | { |
1874 | int ret; | 1875 | int ret; |
1876 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
1875 | 1877 | ||
1876 | if (level == AMD_DPM_FORCED_LEVEL_HIGH) { | 1878 | if (level == AMD_DPM_FORCED_LEVEL_HIGH) { |
1877 | ret = kv_force_dpm_highest(adev); | 1879 | ret = kv_force_dpm_highest(adev); |
@@ -1892,8 +1894,9 @@ static int kv_dpm_force_performance_level(struct amdgpu_device *adev, | |||
1892 | return 0; | 1894 | return 0; |
1893 | } | 1895 | } |
1894 | 1896 | ||
1895 | static int kv_dpm_pre_set_power_state(struct amdgpu_device *adev) | 1897 | static int kv_dpm_pre_set_power_state(void *handle) |
1896 | { | 1898 | { |
1899 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
1897 | struct kv_power_info *pi = kv_get_pi(adev); | 1900 | struct kv_power_info *pi = kv_get_pi(adev); |
1898 | struct amdgpu_ps requested_ps = *adev->pm.dpm.requested_ps; | 1901 | struct amdgpu_ps requested_ps = *adev->pm.dpm.requested_ps; |
1899 | struct amdgpu_ps *new_ps = &requested_ps; | 1902 | struct amdgpu_ps *new_ps = &requested_ps; |
@@ -1907,8 +1910,9 @@ static int kv_dpm_pre_set_power_state(struct amdgpu_device *adev) | |||
1907 | return 0; | 1910 | return 0; |
1908 | } | 1911 | } |
1909 | 1912 | ||
1910 | static int kv_dpm_set_power_state(struct amdgpu_device *adev) | 1913 | static int kv_dpm_set_power_state(void *handle) |
1911 | { | 1914 | { |
1915 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
1912 | struct kv_power_info *pi = kv_get_pi(adev); | 1916 | struct kv_power_info *pi = kv_get_pi(adev); |
1913 | struct amdgpu_ps *new_ps = &pi->requested_rps; | 1917 | struct amdgpu_ps *new_ps = &pi->requested_rps; |
1914 | struct amdgpu_ps *old_ps = &pi->current_rps; | 1918 | struct amdgpu_ps *old_ps = &pi->current_rps; |
@@ -1981,8 +1985,9 @@ static int kv_dpm_set_power_state(struct amdgpu_device *adev) | |||
1981 | return 0; | 1985 | return 0; |
1982 | } | 1986 | } |
1983 | 1987 | ||
1984 | static void kv_dpm_post_set_power_state(struct amdgpu_device *adev) | 1988 | static void kv_dpm_post_set_power_state(void *handle) |
1985 | { | 1989 | { |
1990 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
1986 | struct kv_power_info *pi = kv_get_pi(adev); | 1991 | struct kv_power_info *pi = kv_get_pi(adev); |
1987 | struct amdgpu_ps *new_ps = &pi->requested_rps; | 1992 | struct amdgpu_ps *new_ps = &pi->requested_rps; |
1988 | 1993 | ||
@@ -2848,9 +2853,10 @@ static int kv_dpm_init(struct amdgpu_device *adev) | |||
2848 | } | 2853 | } |
2849 | 2854 | ||
2850 | static void | 2855 | static void |
2851 | kv_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev, | 2856 | kv_dpm_debugfs_print_current_performance_level(void *handle, |
2852 | struct seq_file *m) | 2857 | struct seq_file *m) |
2853 | { | 2858 | { |
2859 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
2854 | struct kv_power_info *pi = kv_get_pi(adev); | 2860 | struct kv_power_info *pi = kv_get_pi(adev); |
2855 | u32 current_index = | 2861 | u32 current_index = |
2856 | (RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX) & | 2862 | (RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX) & |
@@ -2875,11 +2881,12 @@ kv_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev, | |||
2875 | } | 2881 | } |
2876 | 2882 | ||
2877 | static void | 2883 | static void |
2878 | kv_dpm_print_power_state(struct amdgpu_device *adev, | 2884 | kv_dpm_print_power_state(void *handle, void *request_ps) |
2879 | struct amdgpu_ps *rps) | ||
2880 | { | 2885 | { |
2881 | int i; | 2886 | int i; |
2887 | struct amdgpu_ps *rps = (struct amdgpu_ps *)request_ps; | ||
2882 | struct kv_ps *ps = kv_get_ps(rps); | 2888 | struct kv_ps *ps = kv_get_ps(rps); |
2889 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
2883 | 2890 | ||
2884 | amdgpu_dpm_print_class_info(rps->class, rps->class2); | 2891 | amdgpu_dpm_print_class_info(rps->class, rps->class2); |
2885 | amdgpu_dpm_print_cap_info(rps->caps); | 2892 | amdgpu_dpm_print_cap_info(rps->caps); |
@@ -2905,13 +2912,14 @@ static void kv_dpm_fini(struct amdgpu_device *adev) | |||
2905 | amdgpu_free_extended_power_table(adev); | 2912 | amdgpu_free_extended_power_table(adev); |
2906 | } | 2913 | } |
2907 | 2914 | ||
2908 | static void kv_dpm_display_configuration_changed(struct amdgpu_device *adev) | 2915 | static void kv_dpm_display_configuration_changed(void *handle) |
2909 | { | 2916 | { |
2910 | 2917 | ||
2911 | } | 2918 | } |
2912 | 2919 | ||
2913 | static u32 kv_dpm_get_sclk(struct amdgpu_device *adev, bool low) | 2920 | static u32 kv_dpm_get_sclk(void *handle, bool low) |
2914 | { | 2921 | { |
2922 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
2915 | struct kv_power_info *pi = kv_get_pi(adev); | 2923 | struct kv_power_info *pi = kv_get_pi(adev); |
2916 | struct kv_ps *requested_state = kv_get_ps(&pi->requested_rps); | 2924 | struct kv_ps *requested_state = kv_get_ps(&pi->requested_rps); |
2917 | 2925 | ||
@@ -2921,18 +2929,20 @@ static u32 kv_dpm_get_sclk(struct amdgpu_device *adev, bool low) | |||
2921 | return requested_state->levels[requested_state->num_levels - 1].sclk; | 2929 | return requested_state->levels[requested_state->num_levels - 1].sclk; |
2922 | } | 2930 | } |
2923 | 2931 | ||
2924 | static u32 kv_dpm_get_mclk(struct amdgpu_device *adev, bool low) | 2932 | static u32 kv_dpm_get_mclk(void *handle, bool low) |
2925 | { | 2933 | { |
2934 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
2926 | struct kv_power_info *pi = kv_get_pi(adev); | 2935 | struct kv_power_info *pi = kv_get_pi(adev); |
2927 | 2936 | ||
2928 | return pi->sys_info.bootup_uma_clk; | 2937 | return pi->sys_info.bootup_uma_clk; |
2929 | } | 2938 | } |
2930 | 2939 | ||
2931 | /* get temperature in millidegrees */ | 2940 | /* get temperature in millidegrees */ |
2932 | static int kv_dpm_get_temp(struct amdgpu_device *adev) | 2941 | static int kv_dpm_get_temp(void *handle) |
2933 | { | 2942 | { |
2934 | u32 temp; | 2943 | u32 temp; |
2935 | int actual_temp = 0; | 2944 | int actual_temp = 0; |
2945 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
2936 | 2946 | ||
2937 | temp = RREG32_SMC(0xC0300E0C); | 2947 | temp = RREG32_SMC(0xC0300E0C); |
2938 | 2948 | ||
@@ -2950,7 +2960,6 @@ static int kv_dpm_early_init(void *handle) | |||
2950 | { | 2960 | { |
2951 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 2961 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
2952 | 2962 | ||
2953 | kv_dpm_set_dpm_funcs(adev); | ||
2954 | kv_dpm_set_irq_funcs(adev); | 2963 | kv_dpm_set_irq_funcs(adev); |
2955 | 2964 | ||
2956 | return 0; | 2965 | return 0; |
@@ -2960,16 +2969,10 @@ static int kv_dpm_late_init(void *handle) | |||
2960 | { | 2969 | { |
2961 | /* powerdown unused blocks for now */ | 2970 | /* powerdown unused blocks for now */ |
2962 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 2971 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
2963 | int ret; | ||
2964 | 2972 | ||
2965 | if (!amdgpu_dpm) | 2973 | if (!amdgpu_dpm) |
2966 | return 0; | 2974 | return 0; |
2967 | 2975 | ||
2968 | /* init the sysfs and debugfs files late */ | ||
2969 | ret = amdgpu_pm_sysfs_init(adev); | ||
2970 | if (ret) | ||
2971 | return ret; | ||
2972 | |||
2973 | kv_dpm_powergate_acp(adev, true); | 2976 | kv_dpm_powergate_acp(adev, true); |
2974 | kv_dpm_powergate_samu(adev, true); | 2977 | kv_dpm_powergate_samu(adev, true); |
2975 | 2978 | ||
@@ -3031,7 +3034,6 @@ static int kv_dpm_sw_fini(void *handle) | |||
3031 | flush_work(&adev->pm.dpm.thermal.work); | 3034 | flush_work(&adev->pm.dpm.thermal.work); |
3032 | 3035 | ||
3033 | mutex_lock(&adev->pm.mutex); | 3036 | mutex_lock(&adev->pm.mutex); |
3034 | amdgpu_pm_sysfs_fini(adev); | ||
3035 | kv_dpm_fini(adev); | 3037 | kv_dpm_fini(adev); |
3036 | mutex_unlock(&adev->pm.mutex); | 3038 | mutex_unlock(&adev->pm.mutex); |
3037 | 3039 | ||
@@ -3222,14 +3224,17 @@ static inline bool kv_are_power_levels_equal(const struct kv_pl *kv_cpl1, | |||
3222 | (kv_cpl1->force_nbp_state == kv_cpl2->force_nbp_state)); | 3224 | (kv_cpl1->force_nbp_state == kv_cpl2->force_nbp_state)); |
3223 | } | 3225 | } |
3224 | 3226 | ||
3225 | static int kv_check_state_equal(struct amdgpu_device *adev, | 3227 | static int kv_check_state_equal(void *handle, |
3226 | struct amdgpu_ps *cps, | 3228 | void *current_ps, |
3227 | struct amdgpu_ps *rps, | 3229 | void *request_ps, |
3228 | bool *equal) | 3230 | bool *equal) |
3229 | { | 3231 | { |
3230 | struct kv_ps *kv_cps; | 3232 | struct kv_ps *kv_cps; |
3231 | struct kv_ps *kv_rps; | 3233 | struct kv_ps *kv_rps; |
3232 | int i; | 3234 | int i; |
3235 | struct amdgpu_ps *cps = (struct amdgpu_ps *)current_ps; | ||
3236 | struct amdgpu_ps *rps = (struct amdgpu_ps *)request_ps; | ||
3237 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
3233 | 3238 | ||
3234 | if (adev == NULL || cps == NULL || rps == NULL || equal == NULL) | 3239 | if (adev == NULL || cps == NULL || rps == NULL || equal == NULL) |
3235 | return -EINVAL; | 3240 | return -EINVAL; |
@@ -3262,9 +3267,10 @@ static int kv_check_state_equal(struct amdgpu_device *adev, | |||
3262 | return 0; | 3267 | return 0; |
3263 | } | 3268 | } |
3264 | 3269 | ||
3265 | static int kv_dpm_read_sensor(struct amdgpu_device *adev, int idx, | 3270 | static int kv_dpm_read_sensor(void *handle, int idx, |
3266 | void *value, int *size) | 3271 | void *value, int *size) |
3267 | { | 3272 | { |
3273 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
3268 | struct kv_power_info *pi = kv_get_pi(adev); | 3274 | struct kv_power_info *pi = kv_get_pi(adev); |
3269 | uint32_t sclk; | 3275 | uint32_t sclk; |
3270 | u32 pl_index = | 3276 | u32 pl_index = |
@@ -3312,7 +3318,7 @@ const struct amd_ip_funcs kv_dpm_ip_funcs = { | |||
3312 | .set_powergating_state = kv_dpm_set_powergating_state, | 3318 | .set_powergating_state = kv_dpm_set_powergating_state, |
3313 | }; | 3319 | }; |
3314 | 3320 | ||
3315 | static const struct amdgpu_dpm_funcs kv_dpm_funcs = { | 3321 | const struct amd_pm_funcs kv_dpm_funcs = { |
3316 | .get_temperature = &kv_dpm_get_temp, | 3322 | .get_temperature = &kv_dpm_get_temp, |
3317 | .pre_set_power_state = &kv_dpm_pre_set_power_state, | 3323 | .pre_set_power_state = &kv_dpm_pre_set_power_state, |
3318 | .set_power_state = &kv_dpm_set_power_state, | 3324 | .set_power_state = &kv_dpm_set_power_state, |
@@ -3330,12 +3336,6 @@ static const struct amdgpu_dpm_funcs kv_dpm_funcs = { | |||
3330 | .read_sensor = &kv_dpm_read_sensor, | 3336 | .read_sensor = &kv_dpm_read_sensor, |
3331 | }; | 3337 | }; |
3332 | 3338 | ||
3333 | static void kv_dpm_set_dpm_funcs(struct amdgpu_device *adev) | ||
3334 | { | ||
3335 | if (adev->pm.funcs == NULL) | ||
3336 | adev->pm.funcs = &kv_dpm_funcs; | ||
3337 | } | ||
3338 | |||
3339 | static const struct amdgpu_irq_src_funcs kv_dpm_irq_funcs = { | 3339 | static const struct amdgpu_irq_src_funcs kv_dpm_irq_funcs = { |
3340 | .set = kv_dpm_set_interrupt_state, | 3340 | .set = kv_dpm_set_interrupt_state, |
3341 | .process = kv_dpm_process_interrupt, | 3341 | .process = kv_dpm_process_interrupt, |
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c index 74cb647da30e..cc21c4bdec27 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c | |||
@@ -273,7 +273,7 @@ static const struct pctl_data pctl0_data[] = { | |||
273 | {0x135, 0x12a810}, | 273 | {0x135, 0x12a810}, |
274 | {0x149, 0x7a82c} | 274 | {0x149, 0x7a82c} |
275 | }; | 275 | }; |
276 | #define PCTL0_DATA_LEN (sizeof(pctl0_data)/sizeof(pctl0_data[0])) | 276 | #define PCTL0_DATA_LEN (ARRAY_SIZE(pctl0_data)) |
277 | 277 | ||
278 | #define PCTL0_RENG_EXEC_END_PTR 0x151 | 278 | #define PCTL0_RENG_EXEC_END_PTR 0x151 |
279 | #define PCTL0_STCTRL_REG_SAVE_RANGE0_BASE 0xa640 | 279 | #define PCTL0_STCTRL_REG_SAVE_RANGE0_BASE 0xa640 |
@@ -309,7 +309,7 @@ static const struct pctl_data pctl1_data[] = { | |||
309 | {0x1f0, 0x5000a7f6}, | 309 | {0x1f0, 0x5000a7f6}, |
310 | {0x1f1, 0x5000a7e4} | 310 | {0x1f1, 0x5000a7e4} |
311 | }; | 311 | }; |
312 | #define PCTL1_DATA_LEN (sizeof(pctl1_data)/sizeof(pctl1_data[0])) | 312 | #define PCTL1_DATA_LEN (ARRAY_SIZE(pctl1_data)) |
313 | 313 | ||
314 | #define PCTL1_RENG_EXEC_END_PTR 0x1f1 | 314 | #define PCTL1_RENG_EXEC_END_PTR 0x1f1 |
315 | #define PCTL1_STCTRL_REG_SAVE_RANGE0_BASE 0xa000 | 315 | #define PCTL1_STCTRL_REG_SAVE_RANGE0_BASE 0xa000 |
@@ -561,6 +561,13 @@ void mmhub_v1_0_set_fault_enable_default(struct amdgpu_device *adev, bool value) | |||
561 | WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value); | 561 | WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value); |
562 | tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL, | 562 | tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL, |
563 | EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value); | 563 | EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value); |
564 | if (!value) { | ||
565 | tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL, | ||
566 | CRASH_ON_NO_RETRY_FAULT, 1); | ||
567 | tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL, | ||
568 | CRASH_ON_RETRY_FAULT, 1); | ||
569 | } | ||
570 | |||
564 | WREG32_SOC15(MMHUB, 0, mmVM_L2_PROTECTION_FAULT_CNTL, tmp); | 571 | WREG32_SOC15(MMHUB, 0, mmVM_L2_PROTECTION_FAULT_CNTL, tmp); |
565 | } | 572 | } |
566 | 573 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c index 2812d88a8bdd..b4906d2f30d3 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c | |||
@@ -183,6 +183,12 @@ static int xgpu_ai_send_access_requests(struct amdgpu_device *adev, | |||
183 | pr_err("Doesn't get READY_TO_ACCESS_GPU from pf, give up\n"); | 183 | pr_err("Doesn't get READY_TO_ACCESS_GPU from pf, give up\n"); |
184 | return r; | 184 | return r; |
185 | } | 185 | } |
186 | /* Retrieve checksum from mailbox2 */ | ||
187 | if (req == IDH_REQ_GPU_INIT_ACCESS) { | ||
188 | adev->virt.fw_reserve.checksum_key = | ||
189 | RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, | ||
190 | mmBIF_BX_PF0_MAILBOX_MSGBUF_RCV_DW2)); | ||
191 | } | ||
186 | } | 192 | } |
187 | 193 | ||
188 | return 0; | 194 | return 0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h index 1e91b9a1c591..67e78576a9eb 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h | |||
@@ -24,7 +24,7 @@ | |||
24 | #ifndef __MXGPU_AI_H__ | 24 | #ifndef __MXGPU_AI_H__ |
25 | #define __MXGPU_AI_H__ | 25 | #define __MXGPU_AI_H__ |
26 | 26 | ||
27 | #define AI_MAILBOX_TIMEDOUT 5000 | 27 | #define AI_MAILBOX_TIMEDOUT 12000 |
28 | 28 | ||
29 | enum idh_request { | 29 | enum idh_request { |
30 | IDH_REQ_GPU_INIT_ACCESS = 1, | 30 | IDH_REQ_GPU_INIT_ACCESS = 1, |
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h index c791d73d2d54..f13dc6cc158f 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h | |||
@@ -23,7 +23,7 @@ | |||
23 | #ifndef __MXGPU_VI_H__ | 23 | #ifndef __MXGPU_VI_H__ |
24 | #define __MXGPU_VI_H__ | 24 | #define __MXGPU_VI_H__ |
25 | 25 | ||
26 | #define VI_MAILBOX_TIMEDOUT 5000 | 26 | #define VI_MAILBOX_TIMEDOUT 12000 |
27 | #define VI_MAILBOX_RESET_TIME 12 | 27 | #define VI_MAILBOX_RESET_TIME 12 |
28 | 28 | ||
29 | /* VI mailbox messages request */ | 29 | /* VI mailbox messages request */ |
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c index 045988b18bc3..904a1bab9b9f 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c | |||
@@ -215,31 +215,27 @@ void nbio_v6_1_get_clockgating_state(struct amdgpu_device *adev, u32 *flags) | |||
215 | *flags |= AMD_CG_SUPPORT_BIF_LS; | 215 | *flags |= AMD_CG_SUPPORT_BIF_LS; |
216 | } | 216 | } |
217 | 217 | ||
218 | struct nbio_hdp_flush_reg nbio_v6_1_hdp_flush_reg; | 218 | const struct nbio_hdp_flush_reg nbio_v6_1_hdp_flush_reg = { |
219 | struct nbio_pcie_index_data nbio_v6_1_pcie_index_data; | 219 | .hdp_flush_req_offset = SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_GPU_HDP_FLUSH_REQ), |
220 | .hdp_flush_done_offset = SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_GPU_HDP_FLUSH_DONE), | ||
221 | .ref_and_mask_cp0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP0_MASK, | ||
222 | .ref_and_mask_cp1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP1_MASK, | ||
223 | .ref_and_mask_cp2 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP2_MASK, | ||
224 | .ref_and_mask_cp3 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP3_MASK, | ||
225 | .ref_and_mask_cp4 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP4_MASK, | ||
226 | .ref_and_mask_cp5 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP5_MASK, | ||
227 | .ref_and_mask_cp6 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP6_MASK, | ||
228 | .ref_and_mask_cp7 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP7_MASK, | ||
229 | .ref_and_mask_cp8 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP8_MASK, | ||
230 | .ref_and_mask_cp9 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP9_MASK, | ||
231 | .ref_and_mask_sdma0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA0_MASK, | ||
232 | .ref_and_mask_sdma1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA1_MASK | ||
233 | }; | ||
220 | 234 | ||
221 | int nbio_v6_1_init(struct amdgpu_device *adev) | 235 | const struct nbio_pcie_index_data nbio_v6_1_pcie_index_data = { |
222 | { | 236 | .index_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_INDEX), |
223 | nbio_v6_1_hdp_flush_reg.hdp_flush_req_offset = SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_GPU_HDP_FLUSH_REQ); | 237 | .data_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_DATA), |
224 | nbio_v6_1_hdp_flush_reg.hdp_flush_done_offset = SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_GPU_HDP_FLUSH_DONE); | 238 | }; |
225 | nbio_v6_1_hdp_flush_reg.ref_and_mask_cp0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP0_MASK; | ||
226 | nbio_v6_1_hdp_flush_reg.ref_and_mask_cp1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP1_MASK; | ||
227 | nbio_v6_1_hdp_flush_reg.ref_and_mask_cp2 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP2_MASK; | ||
228 | nbio_v6_1_hdp_flush_reg.ref_and_mask_cp3 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP3_MASK; | ||
229 | nbio_v6_1_hdp_flush_reg.ref_and_mask_cp4 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP4_MASK; | ||
230 | nbio_v6_1_hdp_flush_reg.ref_and_mask_cp5 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP5_MASK; | ||
231 | nbio_v6_1_hdp_flush_reg.ref_and_mask_cp6 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP6_MASK; | ||
232 | nbio_v6_1_hdp_flush_reg.ref_and_mask_cp7 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP7_MASK; | ||
233 | nbio_v6_1_hdp_flush_reg.ref_and_mask_cp8 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP8_MASK; | ||
234 | nbio_v6_1_hdp_flush_reg.ref_and_mask_cp9 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP9_MASK; | ||
235 | nbio_v6_1_hdp_flush_reg.ref_and_mask_sdma0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA0_MASK; | ||
236 | nbio_v6_1_hdp_flush_reg.ref_and_mask_sdma1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA1_MASK; | ||
237 | |||
238 | nbio_v6_1_pcie_index_data.index_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_INDEX); | ||
239 | nbio_v6_1_pcie_index_data.data_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_DATA); | ||
240 | |||
241 | return 0; | ||
242 | } | ||
243 | 239 | ||
244 | void nbio_v6_1_detect_hw_virt(struct amdgpu_device *adev) | 240 | void nbio_v6_1_detect_hw_virt(struct amdgpu_device *adev) |
245 | { | 241 | { |
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h index 686e4b4d296a..14ca8d45a46c 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h | |||
@@ -26,8 +26,8 @@ | |||
26 | 26 | ||
27 | #include "soc15_common.h" | 27 | #include "soc15_common.h" |
28 | 28 | ||
29 | extern struct nbio_hdp_flush_reg nbio_v6_1_hdp_flush_reg; | 29 | extern const struct nbio_hdp_flush_reg nbio_v6_1_hdp_flush_reg; |
30 | extern struct nbio_pcie_index_data nbio_v6_1_pcie_index_data; | 30 | extern const struct nbio_pcie_index_data nbio_v6_1_pcie_index_data; |
31 | int nbio_v6_1_init(struct amdgpu_device *adev); | 31 | int nbio_v6_1_init(struct amdgpu_device *adev); |
32 | u32 nbio_v6_1_get_atombios_scratch_regs(struct amdgpu_device *adev, | 32 | u32 nbio_v6_1_get_atombios_scratch_regs(struct amdgpu_device *adev, |
33 | uint32_t idx); | 33 | uint32_t idx); |
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c index 11b70d601922..f802b973410a 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c | |||
@@ -185,28 +185,24 @@ void nbio_v7_0_ih_control(struct amdgpu_device *adev) | |||
185 | WREG32_SOC15(NBIO, 0, mmINTERRUPT_CNTL, interrupt_cntl); | 185 | WREG32_SOC15(NBIO, 0, mmINTERRUPT_CNTL, interrupt_cntl); |
186 | } | 186 | } |
187 | 187 | ||
188 | struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg; | 188 | const struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg = { |
189 | struct nbio_pcie_index_data nbio_v7_0_pcie_index_data; | 189 | .hdp_flush_req_offset = SOC15_REG_OFFSET(NBIO, 0, mmGPU_HDP_FLUSH_REQ), |
190 | .hdp_flush_done_offset = SOC15_REG_OFFSET(NBIO, 0, mmGPU_HDP_FLUSH_DONE), | ||
191 | .ref_and_mask_cp0 = GPU_HDP_FLUSH_DONE__CP0_MASK, | ||
192 | .ref_and_mask_cp1 = GPU_HDP_FLUSH_DONE__CP1_MASK, | ||
193 | .ref_and_mask_cp2 = GPU_HDP_FLUSH_DONE__CP2_MASK, | ||
194 | .ref_and_mask_cp3 = GPU_HDP_FLUSH_DONE__CP3_MASK, | ||
195 | .ref_and_mask_cp4 = GPU_HDP_FLUSH_DONE__CP4_MASK, | ||
196 | .ref_and_mask_cp5 = GPU_HDP_FLUSH_DONE__CP5_MASK, | ||
197 | .ref_and_mask_cp6 = GPU_HDP_FLUSH_DONE__CP6_MASK, | ||
198 | .ref_and_mask_cp7 = GPU_HDP_FLUSH_DONE__CP7_MASK, | ||
199 | .ref_and_mask_cp8 = GPU_HDP_FLUSH_DONE__CP8_MASK, | ||
200 | .ref_and_mask_cp9 = GPU_HDP_FLUSH_DONE__CP9_MASK, | ||
201 | .ref_and_mask_sdma0 = GPU_HDP_FLUSH_DONE__SDMA0_MASK, | ||
202 | .ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__SDMA1_MASK, | ||
203 | }; | ||
190 | 204 | ||
191 | int nbio_v7_0_init(struct amdgpu_device *adev) | 205 | const struct nbio_pcie_index_data nbio_v7_0_pcie_index_data = { |
192 | { | 206 | .index_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_INDEX2), |
193 | nbio_v7_0_hdp_flush_reg.hdp_flush_req_offset = SOC15_REG_OFFSET(NBIO, 0, mmGPU_HDP_FLUSH_REQ); | 207 | .data_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_DATA2) |
194 | nbio_v7_0_hdp_flush_reg.hdp_flush_done_offset = SOC15_REG_OFFSET(NBIO, 0, mmGPU_HDP_FLUSH_DONE); | 208 | }; |
195 | nbio_v7_0_hdp_flush_reg.ref_and_mask_cp0 = GPU_HDP_FLUSH_DONE__CP0_MASK; | ||
196 | nbio_v7_0_hdp_flush_reg.ref_and_mask_cp1 = GPU_HDP_FLUSH_DONE__CP1_MASK; | ||
197 | nbio_v7_0_hdp_flush_reg.ref_and_mask_cp2 = GPU_HDP_FLUSH_DONE__CP2_MASK; | ||
198 | nbio_v7_0_hdp_flush_reg.ref_and_mask_cp3 = GPU_HDP_FLUSH_DONE__CP3_MASK; | ||
199 | nbio_v7_0_hdp_flush_reg.ref_and_mask_cp4 = GPU_HDP_FLUSH_DONE__CP4_MASK; | ||
200 | nbio_v7_0_hdp_flush_reg.ref_and_mask_cp5 = GPU_HDP_FLUSH_DONE__CP5_MASK; | ||
201 | nbio_v7_0_hdp_flush_reg.ref_and_mask_cp6 = GPU_HDP_FLUSH_DONE__CP6_MASK; | ||
202 | nbio_v7_0_hdp_flush_reg.ref_and_mask_cp7 = GPU_HDP_FLUSH_DONE__CP7_MASK; | ||
203 | nbio_v7_0_hdp_flush_reg.ref_and_mask_cp8 = GPU_HDP_FLUSH_DONE__CP8_MASK; | ||
204 | nbio_v7_0_hdp_flush_reg.ref_and_mask_cp9 = GPU_HDP_FLUSH_DONE__CP9_MASK; | ||
205 | nbio_v7_0_hdp_flush_reg.ref_and_mask_sdma0 = GPU_HDP_FLUSH_DONE__SDMA0_MASK; | ||
206 | nbio_v7_0_hdp_flush_reg.ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__SDMA1_MASK; | ||
207 | |||
208 | nbio_v7_0_pcie_index_data.index_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_INDEX2); | ||
209 | nbio_v7_0_pcie_index_data.data_offset = SOC15_REG_OFFSET(NBIO, 0, mmPCIE_DATA2); | ||
210 | |||
211 | return 0; | ||
212 | } | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.h b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.h index 054ff49427e6..df8fa90f40d7 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.h +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.h | |||
@@ -26,8 +26,8 @@ | |||
26 | 26 | ||
27 | #include "soc15_common.h" | 27 | #include "soc15_common.h" |
28 | 28 | ||
29 | extern struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg; | 29 | extern const struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg; |
30 | extern struct nbio_pcie_index_data nbio_v7_0_pcie_index_data; | 30 | extern const struct nbio_pcie_index_data nbio_v7_0_pcie_index_data; |
31 | int nbio_v7_0_init(struct amdgpu_device *adev); | 31 | int nbio_v7_0_init(struct amdgpu_device *adev); |
32 | u32 nbio_v7_0_get_atombios_scratch_regs(struct amdgpu_device *adev, | 32 | u32 nbio_v7_0_get_atombios_scratch_regs(struct amdgpu_device *adev, |
33 | uint32_t idx); | 33 | uint32_t idx); |
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c index f7cf994b1da2..4e20d91d5d50 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c | |||
@@ -35,6 +35,8 @@ | |||
35 | #include "raven1/GC/gc_9_1_offset.h" | 35 | #include "raven1/GC/gc_9_1_offset.h" |
36 | #include "raven1/SDMA0/sdma0_4_1_offset.h" | 36 | #include "raven1/SDMA0/sdma0_4_1_offset.h" |
37 | 37 | ||
38 | MODULE_FIRMWARE("amdgpu/raven_asd.bin"); | ||
39 | |||
38 | static int | 40 | static int |
39 | psp_v10_0_get_fw_type(struct amdgpu_firmware_info *ucode, enum psp_gfx_fw_type *type) | 41 | psp_v10_0_get_fw_type(struct amdgpu_firmware_info *ucode, enum psp_gfx_fw_type *type) |
40 | { | 42 | { |
@@ -136,15 +138,13 @@ int psp_v10_0_prep_cmd_buf(struct amdgpu_firmware_info *ucode, struct psp_gfx_cm | |||
136 | { | 138 | { |
137 | int ret; | 139 | int ret; |
138 | uint64_t fw_mem_mc_addr = ucode->mc_addr; | 140 | uint64_t fw_mem_mc_addr = ucode->mc_addr; |
139 | struct common_firmware_header *header; | ||
140 | 141 | ||
141 | memset(cmd, 0, sizeof(struct psp_gfx_cmd_resp)); | 142 | memset(cmd, 0, sizeof(struct psp_gfx_cmd_resp)); |
142 | header = (struct common_firmware_header *)ucode->fw; | ||
143 | 143 | ||
144 | cmd->cmd_id = GFX_CMD_ID_LOAD_IP_FW; | 144 | cmd->cmd_id = GFX_CMD_ID_LOAD_IP_FW; |
145 | cmd->cmd.cmd_load_ip_fw.fw_phy_addr_lo = lower_32_bits(fw_mem_mc_addr); | 145 | cmd->cmd.cmd_load_ip_fw.fw_phy_addr_lo = lower_32_bits(fw_mem_mc_addr); |
146 | cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = upper_32_bits(fw_mem_mc_addr); | 146 | cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = upper_32_bits(fw_mem_mc_addr); |
147 | cmd->cmd.cmd_load_ip_fw.fw_size = le32_to_cpu(header->ucode_size_bytes); | 147 | cmd->cmd.cmd_load_ip_fw.fw_size = ucode->ucode_size; |
148 | 148 | ||
149 | ret = psp_v10_0_get_fw_type(ucode, &cmd->cmd.cmd_load_ip_fw.fw_type); | 149 | ret = psp_v10_0_get_fw_type(ucode, &cmd->cmd.cmd_load_ip_fw.fw_type); |
150 | if (ret) | 150 | if (ret) |
@@ -209,7 +209,7 @@ int psp_v10_0_ring_create(struct psp_context *psp, enum psp_ring_type ring_type) | |||
209 | return ret; | 209 | return ret; |
210 | } | 210 | } |
211 | 211 | ||
212 | int psp_v10_0_ring_destroy(struct psp_context *psp, enum psp_ring_type ring_type) | 212 | int psp_v10_0_ring_stop(struct psp_context *psp, enum psp_ring_type ring_type) |
213 | { | 213 | { |
214 | int ret = 0; | 214 | int ret = 0; |
215 | struct psp_ring *ring; | 215 | struct psp_ring *ring; |
@@ -229,6 +229,19 @@ int psp_v10_0_ring_destroy(struct psp_context *psp, enum psp_ring_type ring_type | |||
229 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64), | 229 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64), |
230 | 0x80000000, 0x80000000, false); | 230 | 0x80000000, 0x80000000, false); |
231 | 231 | ||
232 | return ret; | ||
233 | } | ||
234 | |||
235 | int psp_v10_0_ring_destroy(struct psp_context *psp, enum psp_ring_type ring_type) | ||
236 | { | ||
237 | int ret = 0; | ||
238 | struct psp_ring *ring = &psp->km_ring; | ||
239 | struct amdgpu_device *adev = psp->adev; | ||
240 | |||
241 | ret = psp_v10_0_ring_stop(psp, ring_type); | ||
242 | if (ret) | ||
243 | DRM_ERROR("Fail to stop psp ring\n"); | ||
244 | |||
232 | amdgpu_bo_free_kernel(&adev->firmware.rbuf, | 245 | amdgpu_bo_free_kernel(&adev->firmware.rbuf, |
233 | &ring->ring_mem_mc_addr, | 246 | &ring->ring_mem_mc_addr, |
234 | (void **)&ring->ring_mem); | 247 | (void **)&ring->ring_mem); |
@@ -244,16 +257,31 @@ int psp_v10_0_cmd_submit(struct psp_context *psp, | |||
244 | unsigned int psp_write_ptr_reg = 0; | 257 | unsigned int psp_write_ptr_reg = 0; |
245 | struct psp_gfx_rb_frame * write_frame = psp->km_ring.ring_mem; | 258 | struct psp_gfx_rb_frame * write_frame = psp->km_ring.ring_mem; |
246 | struct psp_ring *ring = &psp->km_ring; | 259 | struct psp_ring *ring = &psp->km_ring; |
260 | struct psp_gfx_rb_frame *ring_buffer_start = ring->ring_mem; | ||
261 | struct psp_gfx_rb_frame *ring_buffer_end = ring_buffer_start + | ||
262 | ring->ring_size / sizeof(struct psp_gfx_rb_frame) - 1; | ||
247 | struct amdgpu_device *adev = psp->adev; | 263 | struct amdgpu_device *adev = psp->adev; |
264 | uint32_t ring_size_dw = ring->ring_size / 4; | ||
265 | uint32_t rb_frame_size_dw = sizeof(struct psp_gfx_rb_frame) / 4; | ||
248 | 266 | ||
249 | /* KM (GPCOM) prepare write pointer */ | 267 | /* KM (GPCOM) prepare write pointer */ |
250 | psp_write_ptr_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67); | 268 | psp_write_ptr_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67); |
251 | 269 | ||
252 | /* Update KM RB frame pointer to new frame */ | 270 | /* Update KM RB frame pointer to new frame */ |
253 | if ((psp_write_ptr_reg % ring->ring_size) == 0) | 271 | if ((psp_write_ptr_reg % ring_size_dw) == 0) |
254 | write_frame = ring->ring_mem; | 272 | write_frame = ring_buffer_start; |
255 | else | 273 | else |
256 | write_frame = ring->ring_mem + (psp_write_ptr_reg / (sizeof(struct psp_gfx_rb_frame) / 4)); | 274 | write_frame = ring_buffer_start + (psp_write_ptr_reg / rb_frame_size_dw); |
275 | /* Check invalid write_frame ptr address */ | ||
276 | if ((write_frame < ring_buffer_start) || (ring_buffer_end < write_frame)) { | ||
277 | DRM_ERROR("ring_buffer_start = %p; ring_buffer_end = %p; write_frame = %p\n", | ||
278 | ring_buffer_start, ring_buffer_end, write_frame); | ||
279 | DRM_ERROR("write_frame is pointing to address out of bounds\n"); | ||
280 | return -EINVAL; | ||
281 | } | ||
282 | |||
283 | /* Initialize KM RB frame */ | ||
284 | memset(write_frame, 0, sizeof(struct psp_gfx_rb_frame)); | ||
257 | 285 | ||
258 | /* Update KM RB frame */ | 286 | /* Update KM RB frame */ |
259 | write_frame->cmd_buf_addr_hi = upper_32_bits(cmd_buf_mc_addr); | 287 | write_frame->cmd_buf_addr_hi = upper_32_bits(cmd_buf_mc_addr); |
@@ -263,8 +291,7 @@ int psp_v10_0_cmd_submit(struct psp_context *psp, | |||
263 | write_frame->fence_value = index; | 291 | write_frame->fence_value = index; |
264 | 292 | ||
265 | /* Update the write Pointer in DWORDs */ | 293 | /* Update the write Pointer in DWORDs */ |
266 | psp_write_ptr_reg += sizeof(struct psp_gfx_rb_frame) / 4; | 294 | psp_write_ptr_reg = (psp_write_ptr_reg + rb_frame_size_dw) % ring_size_dw; |
267 | psp_write_ptr_reg = (psp_write_ptr_reg >= ring->ring_size) ? 0 : psp_write_ptr_reg; | ||
268 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67, psp_write_ptr_reg); | 295 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67, psp_write_ptr_reg); |
269 | 296 | ||
270 | return 0; | 297 | return 0; |
@@ -390,3 +417,10 @@ bool psp_v10_0_compare_sram_data(struct psp_context *psp, | |||
390 | 417 | ||
391 | return true; | 418 | return true; |
392 | } | 419 | } |
420 | |||
421 | |||
422 | int psp_v10_0_mode1_reset(struct psp_context *psp) | ||
423 | { | ||
424 | DRM_INFO("psp mode 1 reset not supported now! \n"); | ||
425 | return -EINVAL; | ||
426 | } | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.h b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.h index e76cde2f01f9..451e8308303f 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.h +++ b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.h | |||
@@ -34,6 +34,8 @@ extern int psp_v10_0_ring_init(struct psp_context *psp, | |||
34 | enum psp_ring_type ring_type); | 34 | enum psp_ring_type ring_type); |
35 | extern int psp_v10_0_ring_create(struct psp_context *psp, | 35 | extern int psp_v10_0_ring_create(struct psp_context *psp, |
36 | enum psp_ring_type ring_type); | 36 | enum psp_ring_type ring_type); |
37 | extern int psp_v10_0_ring_stop(struct psp_context *psp, | ||
38 | enum psp_ring_type ring_type); | ||
37 | extern int psp_v10_0_ring_destroy(struct psp_context *psp, | 39 | extern int psp_v10_0_ring_destroy(struct psp_context *psp, |
38 | enum psp_ring_type ring_type); | 40 | enum psp_ring_type ring_type); |
39 | extern int psp_v10_0_cmd_submit(struct psp_context *psp, | 41 | extern int psp_v10_0_cmd_submit(struct psp_context *psp, |
@@ -43,4 +45,6 @@ extern int psp_v10_0_cmd_submit(struct psp_context *psp, | |||
43 | extern bool psp_v10_0_compare_sram_data(struct psp_context *psp, | 45 | extern bool psp_v10_0_compare_sram_data(struct psp_context *psp, |
44 | struct amdgpu_firmware_info *ucode, | 46 | struct amdgpu_firmware_info *ucode, |
45 | enum AMDGPU_UCODE_ID ucode_type); | 47 | enum AMDGPU_UCODE_ID ucode_type); |
48 | |||
49 | extern int psp_v10_0_mode1_reset(struct psp_context *psp); | ||
46 | #endif | 50 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c index 2a535a4b8d5b..c7bcfe8e286c 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c | |||
@@ -319,7 +319,7 @@ int psp_v3_1_ring_create(struct psp_context *psp, enum psp_ring_type ring_type) | |||
319 | return ret; | 319 | return ret; |
320 | } | 320 | } |
321 | 321 | ||
322 | int psp_v3_1_ring_destroy(struct psp_context *psp, enum psp_ring_type ring_type) | 322 | int psp_v3_1_ring_stop(struct psp_context *psp, enum psp_ring_type ring_type) |
323 | { | 323 | { |
324 | int ret = 0; | 324 | int ret = 0; |
325 | struct psp_ring *ring; | 325 | struct psp_ring *ring; |
@@ -339,6 +339,19 @@ int psp_v3_1_ring_destroy(struct psp_context *psp, enum psp_ring_type ring_type) | |||
339 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64), | 339 | ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64), |
340 | 0x80000000, 0x80000000, false); | 340 | 0x80000000, 0x80000000, false); |
341 | 341 | ||
342 | return ret; | ||
343 | } | ||
344 | |||
345 | int psp_v3_1_ring_destroy(struct psp_context *psp, enum psp_ring_type ring_type) | ||
346 | { | ||
347 | int ret = 0; | ||
348 | struct psp_ring *ring = &psp->km_ring; | ||
349 | struct amdgpu_device *adev = psp->adev; | ||
350 | |||
351 | ret = psp_v3_1_ring_stop(psp, ring_type); | ||
352 | if (ret) | ||
353 | DRM_ERROR("Fail to stop psp ring\n"); | ||
354 | |||
342 | amdgpu_bo_free_kernel(&adev->firmware.rbuf, | 355 | amdgpu_bo_free_kernel(&adev->firmware.rbuf, |
343 | &ring->ring_mem_mc_addr, | 356 | &ring->ring_mem_mc_addr, |
344 | (void **)&ring->ring_mem); | 357 | (void **)&ring->ring_mem); |
@@ -354,6 +367,9 @@ int psp_v3_1_cmd_submit(struct psp_context *psp, | |||
354 | unsigned int psp_write_ptr_reg = 0; | 367 | unsigned int psp_write_ptr_reg = 0; |
355 | struct psp_gfx_rb_frame * write_frame = psp->km_ring.ring_mem; | 368 | struct psp_gfx_rb_frame * write_frame = psp->km_ring.ring_mem; |
356 | struct psp_ring *ring = &psp->km_ring; | 369 | struct psp_ring *ring = &psp->km_ring; |
370 | struct psp_gfx_rb_frame *ring_buffer_start = ring->ring_mem; | ||
371 | struct psp_gfx_rb_frame *ring_buffer_end = ring_buffer_start + | ||
372 | ring->ring_size / sizeof(struct psp_gfx_rb_frame) - 1; | ||
357 | struct amdgpu_device *adev = psp->adev; | 373 | struct amdgpu_device *adev = psp->adev; |
358 | uint32_t ring_size_dw = ring->ring_size / 4; | 374 | uint32_t ring_size_dw = ring->ring_size / 4; |
359 | uint32_t rb_frame_size_dw = sizeof(struct psp_gfx_rb_frame) / 4; | 375 | uint32_t rb_frame_size_dw = sizeof(struct psp_gfx_rb_frame) / 4; |
@@ -365,9 +381,16 @@ int psp_v3_1_cmd_submit(struct psp_context *psp, | |||
365 | /* write_frame ptr increments by size of rb_frame in bytes */ | 381 | /* write_frame ptr increments by size of rb_frame in bytes */ |
366 | /* psp_write_ptr_reg increments by size of rb_frame in DWORDs */ | 382 | /* psp_write_ptr_reg increments by size of rb_frame in DWORDs */ |
367 | if ((psp_write_ptr_reg % ring_size_dw) == 0) | 383 | if ((psp_write_ptr_reg % ring_size_dw) == 0) |
368 | write_frame = ring->ring_mem; | 384 | write_frame = ring_buffer_start; |
369 | else | 385 | else |
370 | write_frame = ring->ring_mem + (psp_write_ptr_reg / rb_frame_size_dw); | 386 | write_frame = ring_buffer_start + (psp_write_ptr_reg / rb_frame_size_dw); |
387 | /* Check invalid write_frame ptr address */ | ||
388 | if ((write_frame < ring_buffer_start) || (ring_buffer_end < write_frame)) { | ||
389 | DRM_ERROR("ring_buffer_start = %p; ring_buffer_end = %p; write_frame = %p\n", | ||
390 | ring_buffer_start, ring_buffer_end, write_frame); | ||
391 | DRM_ERROR("write_frame is pointing to address out of bounds\n"); | ||
392 | return -EINVAL; | ||
393 | } | ||
371 | 394 | ||
372 | /* Initialize KM RB frame */ | 395 | /* Initialize KM RB frame */ |
373 | memset(write_frame, 0, sizeof(struct psp_gfx_rb_frame)); | 396 | memset(write_frame, 0, sizeof(struct psp_gfx_rb_frame)); |
@@ -517,3 +540,37 @@ bool psp_v3_1_smu_reload_quirk(struct psp_context *psp) | |||
517 | reg = RREG32_SOC15(NBIO, 0, mmPCIE_DATA2); | 540 | reg = RREG32_SOC15(NBIO, 0, mmPCIE_DATA2); |
518 | return (reg & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) ? true : false; | 541 | return (reg & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) ? true : false; |
519 | } | 542 | } |
543 | |||
544 | int psp_v3_1_mode1_reset(struct psp_context *psp) | ||
545 | { | ||
546 | int ret; | ||
547 | uint32_t offset; | ||
548 | struct amdgpu_device *adev = psp->adev; | ||
549 | |||
550 | offset = SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64); | ||
551 | |||
552 | ret = psp_wait_for(psp, offset, 0x80000000, 0x8000FFFF, false); | ||
553 | |||
554 | if (ret) { | ||
555 | DRM_INFO("psp is not working correctly before mode1 reset!\n"); | ||
556 | return -EINVAL; | ||
557 | } | ||
558 | |||
559 | /*send the mode 1 reset command*/ | ||
560 | WREG32(offset, 0x70000); | ||
561 | |||
562 | mdelay(1000); | ||
563 | |||
564 | offset = SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_33); | ||
565 | |||
566 | ret = psp_wait_for(psp, offset, 0x80000000, 0x80000000, false); | ||
567 | |||
568 | if (ret) { | ||
569 | DRM_INFO("psp mode 1 reset failed!\n"); | ||
570 | return -EINVAL; | ||
571 | } | ||
572 | |||
573 | DRM_INFO("psp mode1 reset succeed \n"); | ||
574 | |||
575 | return 0; | ||
576 | } | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.h b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.h index 9dcd0b25c4c6..b05dbada7751 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.h +++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.h | |||
@@ -41,6 +41,8 @@ extern int psp_v3_1_ring_init(struct psp_context *psp, | |||
41 | enum psp_ring_type ring_type); | 41 | enum psp_ring_type ring_type); |
42 | extern int psp_v3_1_ring_create(struct psp_context *psp, | 42 | extern int psp_v3_1_ring_create(struct psp_context *psp, |
43 | enum psp_ring_type ring_type); | 43 | enum psp_ring_type ring_type); |
44 | extern int psp_v3_1_ring_stop(struct psp_context *psp, | ||
45 | enum psp_ring_type ring_type); | ||
44 | extern int psp_v3_1_ring_destroy(struct psp_context *psp, | 46 | extern int psp_v3_1_ring_destroy(struct psp_context *psp, |
45 | enum psp_ring_type ring_type); | 47 | enum psp_ring_type ring_type); |
46 | extern int psp_v3_1_cmd_submit(struct psp_context *psp, | 48 | extern int psp_v3_1_cmd_submit(struct psp_context *psp, |
@@ -51,4 +53,5 @@ extern bool psp_v3_1_compare_sram_data(struct psp_context *psp, | |||
51 | struct amdgpu_firmware_info *ucode, | 53 | struct amdgpu_firmware_info *ucode, |
52 | enum AMDGPU_UCODE_ID ucode_type); | 54 | enum AMDGPU_UCODE_ID ucode_type); |
53 | extern bool psp_v3_1_smu_reload_quirk(struct psp_context *psp); | 55 | extern bool psp_v3_1_smu_reload_quirk(struct psp_context *psp); |
56 | extern int psp_v3_1_mode1_reset(struct psp_context *psp); | ||
54 | #endif | 57 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index f2d0710258cb..67f375bfe452 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | |||
@@ -561,21 +561,11 @@ static int sdma_v2_4_start(struct amdgpu_device *adev) | |||
561 | { | 561 | { |
562 | int r; | 562 | int r; |
563 | 563 | ||
564 | if (!adev->pp_enabled) { | 564 | |
565 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_SMU) { | 565 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { |
566 | r = sdma_v2_4_load_microcode(adev); | 566 | r = sdma_v2_4_load_microcode(adev); |
567 | if (r) | 567 | if (r) |
568 | return r; | 568 | return r; |
569 | } else { | ||
570 | r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, | ||
571 | AMDGPU_UCODE_ID_SDMA0); | ||
572 | if (r) | ||
573 | return -EINVAL; | ||
574 | r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, | ||
575 | AMDGPU_UCODE_ID_SDMA1); | ||
576 | if (r) | ||
577 | return -EINVAL; | ||
578 | } | ||
579 | } | 569 | } |
580 | 570 | ||
581 | /* halt the engine before programing */ | 571 | /* halt the engine before programing */ |
@@ -1324,8 +1314,13 @@ static void sdma_v2_4_set_buffer_funcs(struct amdgpu_device *adev) | |||
1324 | } | 1314 | } |
1325 | 1315 | ||
1326 | static const struct amdgpu_vm_pte_funcs sdma_v2_4_vm_pte_funcs = { | 1316 | static const struct amdgpu_vm_pte_funcs sdma_v2_4_vm_pte_funcs = { |
1317 | .copy_pte_num_dw = 7, | ||
1327 | .copy_pte = sdma_v2_4_vm_copy_pte, | 1318 | .copy_pte = sdma_v2_4_vm_copy_pte, |
1319 | |||
1328 | .write_pte = sdma_v2_4_vm_write_pte, | 1320 | .write_pte = sdma_v2_4_vm_write_pte, |
1321 | |||
1322 | .set_max_nums_pte_pde = 0x1fffff >> 3, | ||
1323 | .set_pte_pde_num_dw = 10, | ||
1329 | .set_pte_pde = sdma_v2_4_vm_set_pte_pde, | 1324 | .set_pte_pde = sdma_v2_4_vm_set_pte_pde, |
1330 | }; | 1325 | }; |
1331 | 1326 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index b1de44f22824..6d06f8eb659f 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | |||
@@ -379,8 +379,10 @@ static void sdma_v3_0_ring_set_wptr(struct amdgpu_ring *ring) | |||
379 | struct amdgpu_device *adev = ring->adev; | 379 | struct amdgpu_device *adev = ring->adev; |
380 | 380 | ||
381 | if (ring->use_doorbell) { | 381 | if (ring->use_doorbell) { |
382 | u32 *wb = (u32 *)&adev->wb.wb[ring->wptr_offs]; | ||
383 | |||
382 | /* XXX check if swapping is necessary on BE */ | 384 | /* XXX check if swapping is necessary on BE */ |
383 | adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr) << 2; | 385 | WRITE_ONCE(*wb, (lower_32_bits(ring->wptr) << 2)); |
384 | WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr) << 2); | 386 | WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr) << 2); |
385 | } else { | 387 | } else { |
386 | int me = (ring == &ring->adev->sdma.instance[0].ring) ? 0 : 1; | 388 | int me = (ring == &ring->adev->sdma.instance[0].ring) ? 0 : 1; |
@@ -641,10 +643,11 @@ static void sdma_v3_0_enable(struct amdgpu_device *adev, bool enable) | |||
641 | static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) | 643 | static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) |
642 | { | 644 | { |
643 | struct amdgpu_ring *ring; | 645 | struct amdgpu_ring *ring; |
644 | u32 rb_cntl, ib_cntl; | 646 | u32 rb_cntl, ib_cntl, wptr_poll_cntl; |
645 | u32 rb_bufsz; | 647 | u32 rb_bufsz; |
646 | u32 wb_offset; | 648 | u32 wb_offset; |
647 | u32 doorbell; | 649 | u32 doorbell; |
650 | u64 wptr_gpu_addr; | ||
648 | int i, j, r; | 651 | int i, j, r; |
649 | 652 | ||
650 | for (i = 0; i < adev->sdma.num_instances; i++) { | 653 | for (i = 0; i < adev->sdma.num_instances; i++) { |
@@ -707,6 +710,20 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) | |||
707 | } | 710 | } |
708 | WREG32(mmSDMA0_GFX_DOORBELL + sdma_offsets[i], doorbell); | 711 | WREG32(mmSDMA0_GFX_DOORBELL + sdma_offsets[i], doorbell); |
709 | 712 | ||
713 | /* setup the wptr shadow polling */ | ||
714 | wptr_gpu_addr = adev->wb.gpu_addr + (ring->wptr_offs * 4); | ||
715 | |||
716 | WREG32(mmSDMA0_GFX_RB_WPTR_POLL_ADDR_LO + sdma_offsets[i], | ||
717 | lower_32_bits(wptr_gpu_addr)); | ||
718 | WREG32(mmSDMA0_GFX_RB_WPTR_POLL_ADDR_HI + sdma_offsets[i], | ||
719 | upper_32_bits(wptr_gpu_addr)); | ||
720 | wptr_poll_cntl = RREG32(mmSDMA0_GFX_RB_WPTR_POLL_CNTL + sdma_offsets[i]); | ||
721 | if (amdgpu_sriov_vf(adev)) | ||
722 | wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, SDMA0_GFX_RB_WPTR_POLL_CNTL, F32_POLL_ENABLE, 1); | ||
723 | else | ||
724 | wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, SDMA0_GFX_RB_WPTR_POLL_CNTL, F32_POLL_ENABLE, 0); | ||
725 | WREG32(mmSDMA0_GFX_RB_WPTR_POLL_CNTL + sdma_offsets[i], wptr_poll_cntl); | ||
726 | |||
710 | /* enable DMA RB */ | 727 | /* enable DMA RB */ |
711 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 1); | 728 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 1); |
712 | WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i], rb_cntl); | 729 | WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i], rb_cntl); |
@@ -802,23 +819,12 @@ static int sdma_v3_0_load_microcode(struct amdgpu_device *adev) | |||
802 | */ | 819 | */ |
803 | static int sdma_v3_0_start(struct amdgpu_device *adev) | 820 | static int sdma_v3_0_start(struct amdgpu_device *adev) |
804 | { | 821 | { |
805 | int r, i; | 822 | int r; |
806 | 823 | ||
807 | if (!adev->pp_enabled) { | 824 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { |
808 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_SMU) { | 825 | r = sdma_v3_0_load_microcode(adev); |
809 | r = sdma_v3_0_load_microcode(adev); | 826 | if (r) |
810 | if (r) | 827 | return r; |
811 | return r; | ||
812 | } else { | ||
813 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
814 | r = adev->smu.smumgr_funcs->check_fw_load_finish(adev, | ||
815 | (i == 0) ? | ||
816 | AMDGPU_UCODE_ID_SDMA0 : | ||
817 | AMDGPU_UCODE_ID_SDMA1); | ||
818 | if (r) | ||
819 | return -EINVAL; | ||
820 | } | ||
821 | } | ||
822 | } | 828 | } |
823 | 829 | ||
824 | /* disable sdma engine before programing it */ | 830 | /* disable sdma engine before programing it */ |
@@ -1713,11 +1719,11 @@ static void sdma_v3_0_emit_fill_buffer(struct amdgpu_ib *ib, | |||
1713 | } | 1719 | } |
1714 | 1720 | ||
1715 | static const struct amdgpu_buffer_funcs sdma_v3_0_buffer_funcs = { | 1721 | static const struct amdgpu_buffer_funcs sdma_v3_0_buffer_funcs = { |
1716 | .copy_max_bytes = 0x1fffff, | 1722 | .copy_max_bytes = 0x3fffe0, /* not 0x3fffff due to HW limitation */ |
1717 | .copy_num_dw = 7, | 1723 | .copy_num_dw = 7, |
1718 | .emit_copy_buffer = sdma_v3_0_emit_copy_buffer, | 1724 | .emit_copy_buffer = sdma_v3_0_emit_copy_buffer, |
1719 | 1725 | ||
1720 | .fill_max_bytes = 0x1fffff, | 1726 | .fill_max_bytes = 0x3fffe0, /* not 0x3fffff due to HW limitation */ |
1721 | .fill_num_dw = 5, | 1727 | .fill_num_dw = 5, |
1722 | .emit_fill_buffer = sdma_v3_0_emit_fill_buffer, | 1728 | .emit_fill_buffer = sdma_v3_0_emit_fill_buffer, |
1723 | }; | 1729 | }; |
@@ -1731,8 +1737,14 @@ static void sdma_v3_0_set_buffer_funcs(struct amdgpu_device *adev) | |||
1731 | } | 1737 | } |
1732 | 1738 | ||
1733 | static const struct amdgpu_vm_pte_funcs sdma_v3_0_vm_pte_funcs = { | 1739 | static const struct amdgpu_vm_pte_funcs sdma_v3_0_vm_pte_funcs = { |
1740 | .copy_pte_num_dw = 7, | ||
1734 | .copy_pte = sdma_v3_0_vm_copy_pte, | 1741 | .copy_pte = sdma_v3_0_vm_copy_pte, |
1742 | |||
1735 | .write_pte = sdma_v3_0_vm_write_pte, | 1743 | .write_pte = sdma_v3_0_vm_write_pte, |
1744 | |||
1745 | /* not 0x3fffff due to HW limitation */ | ||
1746 | .set_max_nums_pte_pde = 0x3fffe0 >> 3, | ||
1747 | .set_pte_pde_num_dw = 10, | ||
1736 | .set_pte_pde = sdma_v3_0_vm_set_pte_pde, | 1748 | .set_pte_pde = sdma_v3_0_vm_set_pte_pde, |
1737 | }; | 1749 | }; |
1738 | 1750 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index fd7c72aaafa6..46009db3d195 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | |||
@@ -54,7 +54,7 @@ static void sdma_v4_0_set_vm_pte_funcs(struct amdgpu_device *adev); | |||
54 | static void sdma_v4_0_set_irq_funcs(struct amdgpu_device *adev); | 54 | static void sdma_v4_0_set_irq_funcs(struct amdgpu_device *adev); |
55 | 55 | ||
56 | static const u32 golden_settings_sdma_4[] = { | 56 | static const u32 golden_settings_sdma_4[] = { |
57 | SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_CHICKEN_BITS), 0xfe931f07, 0x02831f07, | 57 | SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_CHICKEN_BITS), 0xfe931f07, 0x02831d07, |
58 | SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_CLK_CTRL), 0xff000ff0, 0x3f000100, | 58 | SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_CLK_CTRL), 0xff000ff0, 0x3f000100, |
59 | SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_GFX_IB_CNTL), 0x800f0100, 0x00000100, | 59 | SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_GFX_IB_CNTL), 0x800f0100, 0x00000100, |
60 | SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_GFX_RB_WPTR_POLL_CNTL), 0xfffffff7, 0x00403000, | 60 | SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_GFX_RB_WPTR_POLL_CNTL), 0xfffffff7, 0x00403000, |
@@ -89,7 +89,7 @@ static const u32 golden_settings_sdma_vg10[] = { | |||
89 | 89 | ||
90 | static const u32 golden_settings_sdma_4_1[] = | 90 | static const u32 golden_settings_sdma_4_1[] = |
91 | { | 91 | { |
92 | SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_CHICKEN_BITS), 0xfe931f07, 0x02831f07, | 92 | SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_CHICKEN_BITS), 0xfe931f07, 0x02831d07, |
93 | SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_CLK_CTRL), 0xffffffff, 0x3f000100, | 93 | SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_CLK_CTRL), 0xffffffff, 0x3f000100, |
94 | SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_GFX_IB_CNTL), 0x800f0111, 0x00000100, | 94 | SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_GFX_IB_CNTL), 0x800f0111, 0x00000100, |
95 | SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_GFX_RB_WPTR_POLL_CNTL), 0xfffffff7, 0x00403000, | 95 | SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_GFX_RB_WPTR_POLL_CNTL), 0xfffffff7, 0x00403000, |
@@ -371,7 +371,7 @@ static void sdma_v4_0_ring_emit_ib(struct amdgpu_ring *ring, | |||
371 | static void sdma_v4_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) | 371 | static void sdma_v4_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) |
372 | { | 372 | { |
373 | u32 ref_and_mask = 0; | 373 | u32 ref_and_mask = 0; |
374 | struct nbio_hdp_flush_reg *nbio_hf_reg; | 374 | const struct nbio_hdp_flush_reg *nbio_hf_reg; |
375 | 375 | ||
376 | if (ring->adev->flags & AMD_IS_APU) | 376 | if (ring->adev->flags & AMD_IS_APU) |
377 | nbio_hf_reg = &nbio_v7_0_hdp_flush_reg; | 377 | nbio_hf_reg = &nbio_v7_0_hdp_flush_reg; |
@@ -398,7 +398,7 @@ static void sdma_v4_0_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) | |||
398 | { | 398 | { |
399 | amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_SRBM_WRITE) | | 399 | amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_SRBM_WRITE) | |
400 | SDMA_PKT_SRBM_WRITE_HEADER_BYTE_EN(0xf)); | 400 | SDMA_PKT_SRBM_WRITE_HEADER_BYTE_EN(0xf)); |
401 | amdgpu_ring_write(ring, SOC15_REG_OFFSET(HDP, 0, mmHDP_DEBUG0)); | 401 | amdgpu_ring_write(ring, SOC15_REG_OFFSET(HDP, 0, mmHDP_READ_CACHE_INVALIDATE)); |
402 | amdgpu_ring_write(ring, 1); | 402 | amdgpu_ring_write(ring, 1); |
403 | } | 403 | } |
404 | 404 | ||
@@ -1264,6 +1264,11 @@ static int sdma_v4_0_sw_fini(void *handle) | |||
1264 | for (i = 0; i < adev->sdma.num_instances; i++) | 1264 | for (i = 0; i < adev->sdma.num_instances; i++) |
1265 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); | 1265 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); |
1266 | 1266 | ||
1267 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
1268 | release_firmware(adev->sdma.instance[i].fw); | ||
1269 | adev->sdma.instance[i].fw = NULL; | ||
1270 | } | ||
1271 | |||
1267 | return 0; | 1272 | return 0; |
1268 | } | 1273 | } |
1269 | 1274 | ||
@@ -1714,8 +1719,13 @@ static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev) | |||
1714 | } | 1719 | } |
1715 | 1720 | ||
1716 | static const struct amdgpu_vm_pte_funcs sdma_v4_0_vm_pte_funcs = { | 1721 | static const struct amdgpu_vm_pte_funcs sdma_v4_0_vm_pte_funcs = { |
1722 | .copy_pte_num_dw = 7, | ||
1717 | .copy_pte = sdma_v4_0_vm_copy_pte, | 1723 | .copy_pte = sdma_v4_0_vm_copy_pte, |
1724 | |||
1718 | .write_pte = sdma_v4_0_vm_write_pte, | 1725 | .write_pte = sdma_v4_0_vm_write_pte, |
1726 | |||
1727 | .set_max_nums_pte_pde = 0x400000 >> 3, | ||
1728 | .set_pte_pde_num_dw = 10, | ||
1719 | .set_pte_pde = sdma_v4_0_vm_set_pte_pde, | 1729 | .set_pte_pde = sdma_v4_0_vm_set_pte_pde, |
1720 | }; | 1730 | }; |
1721 | 1731 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dma.c b/drivers/gpu/drm/amd/amdgpu/si_dma.c index 112969f3301a..3fa2fbf8c9a1 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dma.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dma.c | |||
@@ -887,8 +887,13 @@ static void si_dma_set_buffer_funcs(struct amdgpu_device *adev) | |||
887 | } | 887 | } |
888 | 888 | ||
889 | static const struct amdgpu_vm_pte_funcs si_dma_vm_pte_funcs = { | 889 | static const struct amdgpu_vm_pte_funcs si_dma_vm_pte_funcs = { |
890 | .copy_pte_num_dw = 5, | ||
890 | .copy_pte = si_dma_vm_copy_pte, | 891 | .copy_pte = si_dma_vm_copy_pte, |
892 | |||
891 | .write_pte = si_dma_vm_write_pte, | 893 | .write_pte = si_dma_vm_write_pte, |
894 | |||
895 | .set_max_nums_pte_pde = 0xffff8 >> 3, | ||
896 | .set_pte_pde_num_dw = 9, | ||
892 | .set_pte_pde = si_dma_vm_set_pte_pde, | 897 | .set_pte_pde = si_dma_vm_set_pte_pde, |
893 | }; | 898 | }; |
894 | 899 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index d63873f3f574..51fd0c9a20a5 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c | |||
@@ -1847,7 +1847,6 @@ static int si_calculate_sclk_params(struct amdgpu_device *adev, | |||
1847 | 1847 | ||
1848 | static void si_thermal_start_smc_fan_control(struct amdgpu_device *adev); | 1848 | static void si_thermal_start_smc_fan_control(struct amdgpu_device *adev); |
1849 | static void si_fan_ctrl_set_default_mode(struct amdgpu_device *adev); | 1849 | static void si_fan_ctrl_set_default_mode(struct amdgpu_device *adev); |
1850 | static void si_dpm_set_dpm_funcs(struct amdgpu_device *adev); | ||
1851 | static void si_dpm_set_irq_funcs(struct amdgpu_device *adev); | 1850 | static void si_dpm_set_irq_funcs(struct amdgpu_device *adev); |
1852 | 1851 | ||
1853 | static struct si_power_info *si_get_pi(struct amdgpu_device *adev) | 1852 | static struct si_power_info *si_get_pi(struct amdgpu_device *adev) |
@@ -3060,9 +3059,9 @@ static int si_get_vce_clock_voltage(struct amdgpu_device *adev, | |||
3060 | return ret; | 3059 | return ret; |
3061 | } | 3060 | } |
3062 | 3061 | ||
3063 | static bool si_dpm_vblank_too_short(struct amdgpu_device *adev) | 3062 | static bool si_dpm_vblank_too_short(void *handle) |
3064 | { | 3063 | { |
3065 | 3064 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
3066 | u32 vblank_time = amdgpu_dpm_get_vblank_time(adev); | 3065 | u32 vblank_time = amdgpu_dpm_get_vblank_time(adev); |
3067 | /* we never hit the non-gddr5 limit so disable it */ | 3066 | /* we never hit the non-gddr5 limit so disable it */ |
3068 | u32 switch_limit = adev->mc.vram_type == AMDGPU_VRAM_TYPE_GDDR5 ? 450 : 0; | 3067 | u32 switch_limit = adev->mc.vram_type == AMDGPU_VRAM_TYPE_GDDR5 ? 450 : 0; |
@@ -3871,9 +3870,10 @@ static int si_restrict_performance_levels_before_switch(struct amdgpu_device *ad | |||
3871 | 0 : -EINVAL; | 3870 | 0 : -EINVAL; |
3872 | } | 3871 | } |
3873 | 3872 | ||
3874 | static int si_dpm_force_performance_level(struct amdgpu_device *adev, | 3873 | static int si_dpm_force_performance_level(void *handle, |
3875 | enum amd_dpm_forced_level level) | 3874 | enum amd_dpm_forced_level level) |
3876 | { | 3875 | { |
3876 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
3877 | struct amdgpu_ps *rps = adev->pm.dpm.current_ps; | 3877 | struct amdgpu_ps *rps = adev->pm.dpm.current_ps; |
3878 | struct si_ps *ps = si_get_ps(rps); | 3878 | struct si_ps *ps = si_get_ps(rps); |
3879 | u32 levels = ps->performance_level_count; | 3879 | u32 levels = ps->performance_level_count; |
@@ -6575,11 +6575,12 @@ static int si_fan_ctrl_stop_smc_fan_control(struct amdgpu_device *adev) | |||
6575 | } | 6575 | } |
6576 | } | 6576 | } |
6577 | 6577 | ||
6578 | static int si_dpm_get_fan_speed_percent(struct amdgpu_device *adev, | 6578 | static int si_dpm_get_fan_speed_percent(void *handle, |
6579 | u32 *speed) | 6579 | u32 *speed) |
6580 | { | 6580 | { |
6581 | u32 duty, duty100; | 6581 | u32 duty, duty100; |
6582 | u64 tmp64; | 6582 | u64 tmp64; |
6583 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6583 | 6584 | ||
6584 | if (adev->pm.no_fan) | 6585 | if (adev->pm.no_fan) |
6585 | return -ENOENT; | 6586 | return -ENOENT; |
@@ -6600,9 +6601,10 @@ static int si_dpm_get_fan_speed_percent(struct amdgpu_device *adev, | |||
6600 | return 0; | 6601 | return 0; |
6601 | } | 6602 | } |
6602 | 6603 | ||
6603 | static int si_dpm_set_fan_speed_percent(struct amdgpu_device *adev, | 6604 | static int si_dpm_set_fan_speed_percent(void *handle, |
6604 | u32 speed) | 6605 | u32 speed) |
6605 | { | 6606 | { |
6607 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6606 | struct si_power_info *si_pi = si_get_pi(adev); | 6608 | struct si_power_info *si_pi = si_get_pi(adev); |
6607 | u32 tmp; | 6609 | u32 tmp; |
6608 | u32 duty, duty100; | 6610 | u32 duty, duty100; |
@@ -6633,8 +6635,10 @@ static int si_dpm_set_fan_speed_percent(struct amdgpu_device *adev, | |||
6633 | return 0; | 6635 | return 0; |
6634 | } | 6636 | } |
6635 | 6637 | ||
6636 | static void si_dpm_set_fan_control_mode(struct amdgpu_device *adev, u32 mode) | 6638 | static void si_dpm_set_fan_control_mode(void *handle, u32 mode) |
6637 | { | 6639 | { |
6640 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6641 | |||
6638 | if (mode) { | 6642 | if (mode) { |
6639 | /* stop auto-manage */ | 6643 | /* stop auto-manage */ |
6640 | if (adev->pm.dpm.fan.ucode_fan_control) | 6644 | if (adev->pm.dpm.fan.ucode_fan_control) |
@@ -6649,8 +6653,9 @@ static void si_dpm_set_fan_control_mode(struct amdgpu_device *adev, u32 mode) | |||
6649 | } | 6653 | } |
6650 | } | 6654 | } |
6651 | 6655 | ||
6652 | static u32 si_dpm_get_fan_control_mode(struct amdgpu_device *adev) | 6656 | static u32 si_dpm_get_fan_control_mode(void *handle) |
6653 | { | 6657 | { |
6658 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6654 | struct si_power_info *si_pi = si_get_pi(adev); | 6659 | struct si_power_info *si_pi = si_get_pi(adev); |
6655 | u32 tmp; | 6660 | u32 tmp; |
6656 | 6661 | ||
@@ -6946,8 +6951,9 @@ static void si_dpm_disable(struct amdgpu_device *adev) | |||
6946 | ni_update_current_ps(adev, boot_ps); | 6951 | ni_update_current_ps(adev, boot_ps); |
6947 | } | 6952 | } |
6948 | 6953 | ||
6949 | static int si_dpm_pre_set_power_state(struct amdgpu_device *adev) | 6954 | static int si_dpm_pre_set_power_state(void *handle) |
6950 | { | 6955 | { |
6956 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6951 | struct evergreen_power_info *eg_pi = evergreen_get_pi(adev); | 6957 | struct evergreen_power_info *eg_pi = evergreen_get_pi(adev); |
6952 | struct amdgpu_ps requested_ps = *adev->pm.dpm.requested_ps; | 6958 | struct amdgpu_ps requested_ps = *adev->pm.dpm.requested_ps; |
6953 | struct amdgpu_ps *new_ps = &requested_ps; | 6959 | struct amdgpu_ps *new_ps = &requested_ps; |
@@ -6984,8 +6990,9 @@ static int si_power_control_set_level(struct amdgpu_device *adev) | |||
6984 | return 0; | 6990 | return 0; |
6985 | } | 6991 | } |
6986 | 6992 | ||
6987 | static int si_dpm_set_power_state(struct amdgpu_device *adev) | 6993 | static int si_dpm_set_power_state(void *handle) |
6988 | { | 6994 | { |
6995 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
6989 | struct evergreen_power_info *eg_pi = evergreen_get_pi(adev); | 6996 | struct evergreen_power_info *eg_pi = evergreen_get_pi(adev); |
6990 | struct amdgpu_ps *new_ps = &eg_pi->requested_rps; | 6997 | struct amdgpu_ps *new_ps = &eg_pi->requested_rps; |
6991 | struct amdgpu_ps *old_ps = &eg_pi->current_rps; | 6998 | struct amdgpu_ps *old_ps = &eg_pi->current_rps; |
@@ -7086,8 +7093,9 @@ static int si_dpm_set_power_state(struct amdgpu_device *adev) | |||
7086 | return 0; | 7093 | return 0; |
7087 | } | 7094 | } |
7088 | 7095 | ||
7089 | static void si_dpm_post_set_power_state(struct amdgpu_device *adev) | 7096 | static void si_dpm_post_set_power_state(void *handle) |
7090 | { | 7097 | { |
7098 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
7091 | struct evergreen_power_info *eg_pi = evergreen_get_pi(adev); | 7099 | struct evergreen_power_info *eg_pi = evergreen_get_pi(adev); |
7092 | struct amdgpu_ps *new_ps = &eg_pi->requested_rps; | 7100 | struct amdgpu_ps *new_ps = &eg_pi->requested_rps; |
7093 | 7101 | ||
@@ -7103,8 +7111,10 @@ void si_dpm_reset_asic(struct amdgpu_device *adev) | |||
7103 | } | 7111 | } |
7104 | #endif | 7112 | #endif |
7105 | 7113 | ||
7106 | static void si_dpm_display_configuration_changed(struct amdgpu_device *adev) | 7114 | static void si_dpm_display_configuration_changed(void *handle) |
7107 | { | 7115 | { |
7116 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
7117 | |||
7108 | si_program_display_gap(adev); | 7118 | si_program_display_gap(adev); |
7109 | } | 7119 | } |
7110 | 7120 | ||
@@ -7486,9 +7496,10 @@ static void si_dpm_fini(struct amdgpu_device *adev) | |||
7486 | amdgpu_free_extended_power_table(adev); | 7496 | amdgpu_free_extended_power_table(adev); |
7487 | } | 7497 | } |
7488 | 7498 | ||
7489 | static void si_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev, | 7499 | static void si_dpm_debugfs_print_current_performance_level(void *handle, |
7490 | struct seq_file *m) | 7500 | struct seq_file *m) |
7491 | { | 7501 | { |
7502 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
7492 | struct evergreen_power_info *eg_pi = evergreen_get_pi(adev); | 7503 | struct evergreen_power_info *eg_pi = evergreen_get_pi(adev); |
7493 | struct amdgpu_ps *rps = &eg_pi->current_rps; | 7504 | struct amdgpu_ps *rps = &eg_pi->current_rps; |
7494 | struct si_ps *ps = si_get_ps(rps); | 7505 | struct si_ps *ps = si_get_ps(rps); |
@@ -7593,11 +7604,6 @@ static int si_dpm_late_init(void *handle) | |||
7593 | if (!amdgpu_dpm) | 7604 | if (!amdgpu_dpm) |
7594 | return 0; | 7605 | return 0; |
7595 | 7606 | ||
7596 | /* init the sysfs and debugfs files late */ | ||
7597 | ret = amdgpu_pm_sysfs_init(adev); | ||
7598 | if (ret) | ||
7599 | return ret; | ||
7600 | |||
7601 | ret = si_set_temperature_range(adev); | 7607 | ret = si_set_temperature_range(adev); |
7602 | if (ret) | 7608 | if (ret) |
7603 | return ret; | 7609 | return ret; |
@@ -7753,7 +7759,6 @@ static int si_dpm_sw_fini(void *handle) | |||
7753 | flush_work(&adev->pm.dpm.thermal.work); | 7759 | flush_work(&adev->pm.dpm.thermal.work); |
7754 | 7760 | ||
7755 | mutex_lock(&adev->pm.mutex); | 7761 | mutex_lock(&adev->pm.mutex); |
7756 | amdgpu_pm_sysfs_fini(adev); | ||
7757 | si_dpm_fini(adev); | 7762 | si_dpm_fini(adev); |
7758 | mutex_unlock(&adev->pm.mutex); | 7763 | mutex_unlock(&adev->pm.mutex); |
7759 | 7764 | ||
@@ -7860,10 +7865,11 @@ static int si_dpm_set_powergating_state(void *handle, | |||
7860 | } | 7865 | } |
7861 | 7866 | ||
7862 | /* get temperature in millidegrees */ | 7867 | /* get temperature in millidegrees */ |
7863 | static int si_dpm_get_temp(struct amdgpu_device *adev) | 7868 | static int si_dpm_get_temp(void *handle) |
7864 | { | 7869 | { |
7865 | u32 temp; | 7870 | u32 temp; |
7866 | int actual_temp = 0; | 7871 | int actual_temp = 0; |
7872 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
7867 | 7873 | ||
7868 | temp = (RREG32(CG_MULT_THERMAL_STATUS) & CTF_TEMP_MASK) >> | 7874 | temp = (RREG32(CG_MULT_THERMAL_STATUS) & CTF_TEMP_MASK) >> |
7869 | CTF_TEMP_SHIFT; | 7875 | CTF_TEMP_SHIFT; |
@@ -7878,8 +7884,9 @@ static int si_dpm_get_temp(struct amdgpu_device *adev) | |||
7878 | return actual_temp; | 7884 | return actual_temp; |
7879 | } | 7885 | } |
7880 | 7886 | ||
7881 | static u32 si_dpm_get_sclk(struct amdgpu_device *adev, bool low) | 7887 | static u32 si_dpm_get_sclk(void *handle, bool low) |
7882 | { | 7888 | { |
7889 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
7883 | struct evergreen_power_info *eg_pi = evergreen_get_pi(adev); | 7890 | struct evergreen_power_info *eg_pi = evergreen_get_pi(adev); |
7884 | struct si_ps *requested_state = si_get_ps(&eg_pi->requested_rps); | 7891 | struct si_ps *requested_state = si_get_ps(&eg_pi->requested_rps); |
7885 | 7892 | ||
@@ -7889,8 +7896,9 @@ static u32 si_dpm_get_sclk(struct amdgpu_device *adev, bool low) | |||
7889 | return requested_state->performance_levels[requested_state->performance_level_count - 1].sclk; | 7896 | return requested_state->performance_levels[requested_state->performance_level_count - 1].sclk; |
7890 | } | 7897 | } |
7891 | 7898 | ||
7892 | static u32 si_dpm_get_mclk(struct amdgpu_device *adev, bool low) | 7899 | static u32 si_dpm_get_mclk(void *handle, bool low) |
7893 | { | 7900 | { |
7901 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
7894 | struct evergreen_power_info *eg_pi = evergreen_get_pi(adev); | 7902 | struct evergreen_power_info *eg_pi = evergreen_get_pi(adev); |
7895 | struct si_ps *requested_state = si_get_ps(&eg_pi->requested_rps); | 7903 | struct si_ps *requested_state = si_get_ps(&eg_pi->requested_rps); |
7896 | 7904 | ||
@@ -7900,9 +7908,11 @@ static u32 si_dpm_get_mclk(struct amdgpu_device *adev, bool low) | |||
7900 | return requested_state->performance_levels[requested_state->performance_level_count - 1].mclk; | 7908 | return requested_state->performance_levels[requested_state->performance_level_count - 1].mclk; |
7901 | } | 7909 | } |
7902 | 7910 | ||
7903 | static void si_dpm_print_power_state(struct amdgpu_device *adev, | 7911 | static void si_dpm_print_power_state(void *handle, |
7904 | struct amdgpu_ps *rps) | 7912 | void *current_ps) |
7905 | { | 7913 | { |
7914 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
7915 | struct amdgpu_ps *rps = (struct amdgpu_ps *)current_ps; | ||
7906 | struct si_ps *ps = si_get_ps(rps); | 7916 | struct si_ps *ps = si_get_ps(rps); |
7907 | struct rv7xx_pl *pl; | 7917 | struct rv7xx_pl *pl; |
7908 | int i; | 7918 | int i; |
@@ -7927,7 +7937,6 @@ static int si_dpm_early_init(void *handle) | |||
7927 | 7937 | ||
7928 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 7938 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
7929 | 7939 | ||
7930 | si_dpm_set_dpm_funcs(adev); | ||
7931 | si_dpm_set_irq_funcs(adev); | 7940 | si_dpm_set_irq_funcs(adev); |
7932 | return 0; | 7941 | return 0; |
7933 | } | 7942 | } |
@@ -7942,20 +7951,23 @@ static inline bool si_are_power_levels_equal(const struct rv7xx_pl *si_cpl1, | |||
7942 | (si_cpl1->vddci == si_cpl2->vddci)); | 7951 | (si_cpl1->vddci == si_cpl2->vddci)); |
7943 | } | 7952 | } |
7944 | 7953 | ||
7945 | static int si_check_state_equal(struct amdgpu_device *adev, | 7954 | static int si_check_state_equal(void *handle, |
7946 | struct amdgpu_ps *cps, | 7955 | void *current_ps, |
7947 | struct amdgpu_ps *rps, | 7956 | void *request_ps, |
7948 | bool *equal) | 7957 | bool *equal) |
7949 | { | 7958 | { |
7950 | struct si_ps *si_cps; | 7959 | struct si_ps *si_cps; |
7951 | struct si_ps *si_rps; | 7960 | struct si_ps *si_rps; |
7952 | int i; | 7961 | int i; |
7962 | struct amdgpu_ps *cps = (struct amdgpu_ps *)current_ps; | ||
7963 | struct amdgpu_ps *rps = (struct amdgpu_ps *)request_ps; | ||
7964 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
7953 | 7965 | ||
7954 | if (adev == NULL || cps == NULL || rps == NULL || equal == NULL) | 7966 | if (adev == NULL || cps == NULL || rps == NULL || equal == NULL) |
7955 | return -EINVAL; | 7967 | return -EINVAL; |
7956 | 7968 | ||
7957 | si_cps = si_get_ps(cps); | 7969 | si_cps = si_get_ps((struct amdgpu_ps *)cps); |
7958 | si_rps = si_get_ps(rps); | 7970 | si_rps = si_get_ps((struct amdgpu_ps *)rps); |
7959 | 7971 | ||
7960 | if (si_cps == NULL) { | 7972 | if (si_cps == NULL) { |
7961 | printk("si_cps is NULL\n"); | 7973 | printk("si_cps is NULL\n"); |
@@ -7983,9 +7995,10 @@ static int si_check_state_equal(struct amdgpu_device *adev, | |||
7983 | return 0; | 7995 | return 0; |
7984 | } | 7996 | } |
7985 | 7997 | ||
7986 | static int si_dpm_read_sensor(struct amdgpu_device *adev, int idx, | 7998 | static int si_dpm_read_sensor(void *handle, int idx, |
7987 | void *value, int *size) | 7999 | void *value, int *size) |
7988 | { | 8000 | { |
8001 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
7989 | struct evergreen_power_info *eg_pi = evergreen_get_pi(adev); | 8002 | struct evergreen_power_info *eg_pi = evergreen_get_pi(adev); |
7990 | struct amdgpu_ps *rps = &eg_pi->current_rps; | 8003 | struct amdgpu_ps *rps = &eg_pi->current_rps; |
7991 | struct si_ps *ps = si_get_ps(rps); | 8004 | struct si_ps *ps = si_get_ps(rps); |
@@ -8041,7 +8054,7 @@ const struct amd_ip_funcs si_dpm_ip_funcs = { | |||
8041 | .set_powergating_state = si_dpm_set_powergating_state, | 8054 | .set_powergating_state = si_dpm_set_powergating_state, |
8042 | }; | 8055 | }; |
8043 | 8056 | ||
8044 | static const struct amdgpu_dpm_funcs si_dpm_funcs = { | 8057 | const struct amd_pm_funcs si_dpm_funcs = { |
8045 | .get_temperature = &si_dpm_get_temp, | 8058 | .get_temperature = &si_dpm_get_temp, |
8046 | .pre_set_power_state = &si_dpm_pre_set_power_state, | 8059 | .pre_set_power_state = &si_dpm_pre_set_power_state, |
8047 | .set_power_state = &si_dpm_set_power_state, | 8060 | .set_power_state = &si_dpm_set_power_state, |
@@ -8062,12 +8075,6 @@ static const struct amdgpu_dpm_funcs si_dpm_funcs = { | |||
8062 | .read_sensor = &si_dpm_read_sensor, | 8075 | .read_sensor = &si_dpm_read_sensor, |
8063 | }; | 8076 | }; |
8064 | 8077 | ||
8065 | static void si_dpm_set_dpm_funcs(struct amdgpu_device *adev) | ||
8066 | { | ||
8067 | if (adev->pm.funcs == NULL) | ||
8068 | adev->pm.funcs = &si_dpm_funcs; | ||
8069 | } | ||
8070 | |||
8071 | static const struct amdgpu_irq_src_funcs si_dpm_irq_funcs = { | 8078 | static const struct amdgpu_irq_src_funcs si_dpm_irq_funcs = { |
8072 | .set = si_dpm_set_interrupt_state, | 8079 | .set = si_dpm_set_interrupt_state, |
8073 | .process = si_dpm_process_interrupt, | 8080 | .process = si_dpm_process_interrupt, |
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.h b/drivers/gpu/drm/amd/amdgpu/si_dpm.h index 51ce21c5f4fb..9fe343de3477 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.h +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.h | |||
@@ -246,6 +246,7 @@ enum si_display_gap | |||
246 | }; | 246 | }; |
247 | 247 | ||
248 | extern const struct amd_ip_funcs si_dpm_ip_funcs; | 248 | extern const struct amd_ip_funcs si_dpm_ip_funcs; |
249 | extern const struct amd_pm_funcs si_dpm_funcs; | ||
249 | 250 | ||
250 | struct ni_leakage_coeffients | 251 | struct ni_leakage_coeffients |
251 | { | 252 | { |
diff --git a/drivers/gpu/drm/amd/amdgpu/si_ih.c b/drivers/gpu/drm/amd/amdgpu/si_ih.c index ce25e03a077d..d2c6b80309c8 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/si_ih.c | |||
@@ -118,6 +118,19 @@ static u32 si_ih_get_wptr(struct amdgpu_device *adev) | |||
118 | return (wptr & adev->irq.ih.ptr_mask); | 118 | return (wptr & adev->irq.ih.ptr_mask); |
119 | } | 119 | } |
120 | 120 | ||
121 | /** | ||
122 | * si_ih_prescreen_iv - prescreen an interrupt vector | ||
123 | * | ||
124 | * @adev: amdgpu_device pointer | ||
125 | * | ||
126 | * Returns true if the interrupt vector should be further processed. | ||
127 | */ | ||
128 | static bool si_ih_prescreen_iv(struct amdgpu_device *adev) | ||
129 | { | ||
130 | /* Process all interrupts */ | ||
131 | return true; | ||
132 | } | ||
133 | |||
121 | static void si_ih_decode_iv(struct amdgpu_device *adev, | 134 | static void si_ih_decode_iv(struct amdgpu_device *adev, |
122 | struct amdgpu_iv_entry *entry) | 135 | struct amdgpu_iv_entry *entry) |
123 | { | 136 | { |
@@ -288,6 +301,7 @@ static const struct amd_ip_funcs si_ih_ip_funcs = { | |||
288 | 301 | ||
289 | static const struct amdgpu_ih_funcs si_ih_funcs = { | 302 | static const struct amdgpu_ih_funcs si_ih_funcs = { |
290 | .get_wptr = si_ih_get_wptr, | 303 | .get_wptr = si_ih_get_wptr, |
304 | .prescreen_iv = si_ih_prescreen_iv, | ||
291 | .decode_iv = si_ih_decode_iv, | 305 | .decode_iv = si_ih_decode_iv, |
292 | .set_rptr = si_ih_set_rptr | 306 | .set_rptr = si_ih_set_rptr |
293 | }; | 307 | }; |
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index f2c3a49f73a0..4e67fe1e7955 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c | |||
@@ -101,7 +101,7 @@ static u32 soc15_pcie_rreg(struct amdgpu_device *adev, u32 reg) | |||
101 | { | 101 | { |
102 | unsigned long flags, address, data; | 102 | unsigned long flags, address, data; |
103 | u32 r; | 103 | u32 r; |
104 | struct nbio_pcie_index_data *nbio_pcie_id; | 104 | const struct nbio_pcie_index_data *nbio_pcie_id; |
105 | 105 | ||
106 | if (adev->flags & AMD_IS_APU) | 106 | if (adev->flags & AMD_IS_APU) |
107 | nbio_pcie_id = &nbio_v7_0_pcie_index_data; | 107 | nbio_pcie_id = &nbio_v7_0_pcie_index_data; |
@@ -122,7 +122,7 @@ static u32 soc15_pcie_rreg(struct amdgpu_device *adev, u32 reg) | |||
122 | static void soc15_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v) | 122 | static void soc15_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v) |
123 | { | 123 | { |
124 | unsigned long flags, address, data; | 124 | unsigned long flags, address, data; |
125 | struct nbio_pcie_index_data *nbio_pcie_id; | 125 | const struct nbio_pcie_index_data *nbio_pcie_id; |
126 | 126 | ||
127 | if (adev->flags & AMD_IS_APU) | 127 | if (adev->flags & AMD_IS_APU) |
128 | nbio_pcie_id = &nbio_v7_0_pcie_index_data; | 128 | nbio_pcie_id = &nbio_v7_0_pcie_index_data; |
@@ -279,10 +279,7 @@ static void soc15_init_golden_registers(struct amdgpu_device *adev) | |||
279 | } | 279 | } |
280 | static u32 soc15_get_xclk(struct amdgpu_device *adev) | 280 | static u32 soc15_get_xclk(struct amdgpu_device *adev) |
281 | { | 281 | { |
282 | if (adev->asic_type == CHIP_VEGA10) | 282 | return adev->clock.spll.reference_freq; |
283 | return adev->clock.spll.reference_freq/4; | ||
284 | else | ||
285 | return adev->clock.spll.reference_freq; | ||
286 | } | 283 | } |
287 | 284 | ||
288 | 285 | ||
@@ -407,18 +404,27 @@ static int soc15_read_register(struct amdgpu_device *adev, u32 se_num, | |||
407 | return -EINVAL; | 404 | return -EINVAL; |
408 | } | 405 | } |
409 | 406 | ||
410 | static void soc15_gpu_pci_config_reset(struct amdgpu_device *adev) | 407 | static int soc15_asic_reset(struct amdgpu_device *adev) |
411 | { | 408 | { |
412 | u32 i; | 409 | u32 i; |
413 | 410 | ||
414 | dev_info(adev->dev, "GPU pci config reset\n"); | 411 | amdgpu_atombios_scratch_regs_engine_hung(adev, true); |
412 | |||
413 | dev_info(adev->dev, "GPU reset\n"); | ||
415 | 414 | ||
416 | /* disable BM */ | 415 | /* disable BM */ |
417 | pci_clear_master(adev->pdev); | 416 | pci_clear_master(adev->pdev); |
418 | /* reset */ | ||
419 | amdgpu_pci_config_reset(adev); | ||
420 | 417 | ||
421 | udelay(100); | 418 | pci_save_state(adev->pdev); |
419 | |||
420 | for (i = 0; i < AMDGPU_MAX_IP_NUM; i++) { | ||
421 | if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP){ | ||
422 | adev->ip_blocks[i].version->funcs->soft_reset((void *)adev); | ||
423 | break; | ||
424 | } | ||
425 | } | ||
426 | |||
427 | pci_restore_state(adev->pdev); | ||
422 | 428 | ||
423 | /* wait for asic to come out of reset */ | 429 | /* wait for asic to come out of reset */ |
424 | for (i = 0; i < adev->usec_timeout; i++) { | 430 | for (i = 0; i < adev->usec_timeout; i++) { |
@@ -430,14 +436,6 @@ static void soc15_gpu_pci_config_reset(struct amdgpu_device *adev) | |||
430 | udelay(1); | 436 | udelay(1); |
431 | } | 437 | } |
432 | 438 | ||
433 | } | ||
434 | |||
435 | static int soc15_asic_reset(struct amdgpu_device *adev) | ||
436 | { | ||
437 | amdgpu_atombios_scratch_regs_engine_hung(adev, true); | ||
438 | |||
439 | soc15_gpu_pci_config_reset(adev); | ||
440 | |||
441 | amdgpu_atombios_scratch_regs_engine_hung(adev, false); | 439 | amdgpu_atombios_scratch_regs_engine_hung(adev, false); |
442 | 440 | ||
443 | return 0; | 441 | return 0; |
@@ -534,6 +532,12 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev) | |||
534 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); | 532 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); |
535 | if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) | 533 | if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) |
536 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); | 534 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); |
535 | #if defined(CONFIG_DRM_AMD_DC) | ||
536 | else if (amdgpu_device_has_dc_support(adev)) | ||
537 | amdgpu_ip_block_add(adev, &dm_ip_block); | ||
538 | #else | ||
539 | # warning "Enable CONFIG_DRM_AMD_DC for display support on SOC15." | ||
540 | #endif | ||
537 | amdgpu_ip_block_add(adev, &gfx_v9_0_ip_block); | 541 | amdgpu_ip_block_add(adev, &gfx_v9_0_ip_block); |
538 | amdgpu_ip_block_add(adev, &sdma_v4_0_ip_block); | 542 | amdgpu_ip_block_add(adev, &sdma_v4_0_ip_block); |
539 | amdgpu_ip_block_add(adev, &uvd_v7_0_ip_block); | 543 | amdgpu_ip_block_add(adev, &uvd_v7_0_ip_block); |
@@ -547,6 +551,12 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev) | |||
547 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); | 551 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); |
548 | if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) | 552 | if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) |
549 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); | 553 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); |
554 | #if defined(CONFIG_DRM_AMD_DC) | ||
555 | else if (amdgpu_device_has_dc_support(adev)) | ||
556 | amdgpu_ip_block_add(adev, &dm_ip_block); | ||
557 | #else | ||
558 | # warning "Enable CONFIG_DRM_AMD_DC for display support on SOC15." | ||
559 | #endif | ||
550 | amdgpu_ip_block_add(adev, &gfx_v9_0_ip_block); | 560 | amdgpu_ip_block_add(adev, &gfx_v9_0_ip_block); |
551 | amdgpu_ip_block_add(adev, &sdma_v4_0_ip_block); | 561 | amdgpu_ip_block_add(adev, &sdma_v4_0_ip_block); |
552 | amdgpu_ip_block_add(adev, &vcn_v1_0_ip_block); | 562 | amdgpu_ip_block_add(adev, &vcn_v1_0_ip_block); |
@@ -603,21 +613,6 @@ static int soc15_common_early_init(void *handle) | |||
603 | (amdgpu_ip_block_mask & (1 << AMD_IP_BLOCK_TYPE_PSP))) | 613 | (amdgpu_ip_block_mask & (1 << AMD_IP_BLOCK_TYPE_PSP))) |
604 | psp_enabled = true; | 614 | psp_enabled = true; |
605 | 615 | ||
606 | /* | ||
607 | * nbio need be used for both sdma and gfx9, but only | ||
608 | * initializes once | ||
609 | */ | ||
610 | switch(adev->asic_type) { | ||
611 | case CHIP_VEGA10: | ||
612 | nbio_v6_1_init(adev); | ||
613 | break; | ||
614 | case CHIP_RAVEN: | ||
615 | nbio_v7_0_init(adev); | ||
616 | break; | ||
617 | default: | ||
618 | return -EINVAL; | ||
619 | } | ||
620 | |||
621 | adev->rev_id = soc15_get_rev_id(adev); | 616 | adev->rev_id = soc15_get_rev_id(adev); |
622 | adev->external_rev_id = 0xFF; | 617 | adev->external_rev_id = 0xFF; |
623 | switch (adev->asic_type) { | 618 | switch (adev->asic_type) { |
diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c index 923df2c0e535..aa4e320e31f8 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c | |||
@@ -219,6 +219,34 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev) | |||
219 | } | 219 | } |
220 | 220 | ||
221 | /** | 221 | /** |
222 | * tonga_ih_prescreen_iv - prescreen an interrupt vector | ||
223 | * | ||
224 | * @adev: amdgpu_device pointer | ||
225 | * | ||
226 | * Returns true if the interrupt vector should be further processed. | ||
227 | */ | ||
228 | static bool tonga_ih_prescreen_iv(struct amdgpu_device *adev) | ||
229 | { | ||
230 | u32 ring_index = adev->irq.ih.rptr >> 2; | ||
231 | u16 pasid; | ||
232 | |||
233 | switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) { | ||
234 | case 146: | ||
235 | case 147: | ||
236 | pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16; | ||
237 | if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid)) | ||
238 | return true; | ||
239 | break; | ||
240 | default: | ||
241 | /* Not a VM fault */ | ||
242 | return true; | ||
243 | } | ||
244 | |||
245 | adev->irq.ih.rptr += 16; | ||
246 | return false; | ||
247 | } | ||
248 | |||
249 | /** | ||
222 | * tonga_ih_decode_iv - decode an interrupt vector | 250 | * tonga_ih_decode_iv - decode an interrupt vector |
223 | * | 251 | * |
224 | * @adev: amdgpu_device pointer | 252 | * @adev: amdgpu_device pointer |
@@ -478,6 +506,7 @@ static const struct amd_ip_funcs tonga_ih_ip_funcs = { | |||
478 | 506 | ||
479 | static const struct amdgpu_ih_funcs tonga_ih_funcs = { | 507 | static const struct amdgpu_ih_funcs tonga_ih_funcs = { |
480 | .get_wptr = tonga_ih_get_wptr, | 508 | .get_wptr = tonga_ih_get_wptr, |
509 | .prescreen_iv = tonga_ih_prescreen_iv, | ||
481 | .decode_iv = tonga_ih_decode_iv, | 510 | .decode_iv = tonga_ih_decode_iv, |
482 | .set_rptr = tonga_ih_set_rptr | 511 | .set_rptr = tonga_ih_set_rptr |
483 | }; | 512 | }; |
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 62cd16a23921..920910ac8663 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | |||
@@ -38,6 +38,8 @@ | |||
38 | #include "vi.h" | 38 | #include "vi.h" |
39 | 39 | ||
40 | static void uvd_v6_0_set_ring_funcs(struct amdgpu_device *adev); | 40 | static void uvd_v6_0_set_ring_funcs(struct amdgpu_device *adev); |
41 | static void uvd_v6_0_set_enc_ring_funcs(struct amdgpu_device *adev); | ||
42 | |||
41 | static void uvd_v6_0_set_irq_funcs(struct amdgpu_device *adev); | 43 | static void uvd_v6_0_set_irq_funcs(struct amdgpu_device *adev); |
42 | static int uvd_v6_0_start(struct amdgpu_device *adev); | 44 | static int uvd_v6_0_start(struct amdgpu_device *adev); |
43 | static void uvd_v6_0_stop(struct amdgpu_device *adev); | 45 | static void uvd_v6_0_stop(struct amdgpu_device *adev); |
@@ -48,6 +50,18 @@ static void uvd_v6_0_enable_mgcg(struct amdgpu_device *adev, | |||
48 | bool enable); | 50 | bool enable); |
49 | 51 | ||
50 | /** | 52 | /** |
53 | * uvd_v6_0_enc_support - get encode support status | ||
54 | * | ||
55 | * @adev: amdgpu_device pointer | ||
56 | * | ||
57 | * Returns the current hardware encode support status | ||
58 | */ | ||
59 | static inline bool uvd_v6_0_enc_support(struct amdgpu_device *adev) | ||
60 | { | ||
61 | return ((adev->asic_type >= CHIP_POLARIS10) && (adev->asic_type <= CHIP_POLARIS12)); | ||
62 | } | ||
63 | |||
64 | /** | ||
51 | * uvd_v6_0_ring_get_rptr - get read pointer | 65 | * uvd_v6_0_ring_get_rptr - get read pointer |
52 | * | 66 | * |
53 | * @ring: amdgpu_ring pointer | 67 | * @ring: amdgpu_ring pointer |
@@ -62,6 +76,22 @@ static uint64_t uvd_v6_0_ring_get_rptr(struct amdgpu_ring *ring) | |||
62 | } | 76 | } |
63 | 77 | ||
64 | /** | 78 | /** |
79 | * uvd_v6_0_enc_ring_get_rptr - get enc read pointer | ||
80 | * | ||
81 | * @ring: amdgpu_ring pointer | ||
82 | * | ||
83 | * Returns the current hardware enc read pointer | ||
84 | */ | ||
85 | static uint64_t uvd_v6_0_enc_ring_get_rptr(struct amdgpu_ring *ring) | ||
86 | { | ||
87 | struct amdgpu_device *adev = ring->adev; | ||
88 | |||
89 | if (ring == &adev->uvd.ring_enc[0]) | ||
90 | return RREG32(mmUVD_RB_RPTR); | ||
91 | else | ||
92 | return RREG32(mmUVD_RB_RPTR2); | ||
93 | } | ||
94 | /** | ||
65 | * uvd_v6_0_ring_get_wptr - get write pointer | 95 | * uvd_v6_0_ring_get_wptr - get write pointer |
66 | * | 96 | * |
67 | * @ring: amdgpu_ring pointer | 97 | * @ring: amdgpu_ring pointer |
@@ -76,6 +106,23 @@ static uint64_t uvd_v6_0_ring_get_wptr(struct amdgpu_ring *ring) | |||
76 | } | 106 | } |
77 | 107 | ||
78 | /** | 108 | /** |
109 | * uvd_v6_0_enc_ring_get_wptr - get enc write pointer | ||
110 | * | ||
111 | * @ring: amdgpu_ring pointer | ||
112 | * | ||
113 | * Returns the current hardware enc write pointer | ||
114 | */ | ||
115 | static uint64_t uvd_v6_0_enc_ring_get_wptr(struct amdgpu_ring *ring) | ||
116 | { | ||
117 | struct amdgpu_device *adev = ring->adev; | ||
118 | |||
119 | if (ring == &adev->uvd.ring_enc[0]) | ||
120 | return RREG32(mmUVD_RB_WPTR); | ||
121 | else | ||
122 | return RREG32(mmUVD_RB_WPTR2); | ||
123 | } | ||
124 | |||
125 | /** | ||
79 | * uvd_v6_0_ring_set_wptr - set write pointer | 126 | * uvd_v6_0_ring_set_wptr - set write pointer |
80 | * | 127 | * |
81 | * @ring: amdgpu_ring pointer | 128 | * @ring: amdgpu_ring pointer |
@@ -89,6 +136,237 @@ static void uvd_v6_0_ring_set_wptr(struct amdgpu_ring *ring) | |||
89 | WREG32(mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr)); | 136 | WREG32(mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr)); |
90 | } | 137 | } |
91 | 138 | ||
139 | /** | ||
140 | * uvd_v6_0_enc_ring_set_wptr - set enc write pointer | ||
141 | * | ||
142 | * @ring: amdgpu_ring pointer | ||
143 | * | ||
144 | * Commits the enc write pointer to the hardware | ||
145 | */ | ||
146 | static void uvd_v6_0_enc_ring_set_wptr(struct amdgpu_ring *ring) | ||
147 | { | ||
148 | struct amdgpu_device *adev = ring->adev; | ||
149 | |||
150 | if (ring == &adev->uvd.ring_enc[0]) | ||
151 | WREG32(mmUVD_RB_WPTR, | ||
152 | lower_32_bits(ring->wptr)); | ||
153 | else | ||
154 | WREG32(mmUVD_RB_WPTR2, | ||
155 | lower_32_bits(ring->wptr)); | ||
156 | } | ||
157 | |||
158 | /** | ||
159 | * uvd_v6_0_enc_ring_test_ring - test if UVD ENC ring is working | ||
160 | * | ||
161 | * @ring: the engine to test on | ||
162 | * | ||
163 | */ | ||
164 | static int uvd_v6_0_enc_ring_test_ring(struct amdgpu_ring *ring) | ||
165 | { | ||
166 | struct amdgpu_device *adev = ring->adev; | ||
167 | uint32_t rptr = amdgpu_ring_get_rptr(ring); | ||
168 | unsigned i; | ||
169 | int r; | ||
170 | |||
171 | r = amdgpu_ring_alloc(ring, 16); | ||
172 | if (r) { | ||
173 | DRM_ERROR("amdgpu: uvd enc failed to lock ring %d (%d).\n", | ||
174 | ring->idx, r); | ||
175 | return r; | ||
176 | } | ||
177 | amdgpu_ring_write(ring, HEVC_ENC_CMD_END); | ||
178 | amdgpu_ring_commit(ring); | ||
179 | |||
180 | for (i = 0; i < adev->usec_timeout; i++) { | ||
181 | if (amdgpu_ring_get_rptr(ring) != rptr) | ||
182 | break; | ||
183 | DRM_UDELAY(1); | ||
184 | } | ||
185 | |||
186 | if (i < adev->usec_timeout) { | ||
187 | DRM_INFO("ring test on %d succeeded in %d usecs\n", | ||
188 | ring->idx, i); | ||
189 | } else { | ||
190 | DRM_ERROR("amdgpu: ring %d test failed\n", | ||
191 | ring->idx); | ||
192 | r = -ETIMEDOUT; | ||
193 | } | ||
194 | |||
195 | return r; | ||
196 | } | ||
197 | |||
198 | /** | ||
199 | * uvd_v6_0_enc_get_create_msg - generate a UVD ENC create msg | ||
200 | * | ||
201 | * @adev: amdgpu_device pointer | ||
202 | * @ring: ring we should submit the msg to | ||
203 | * @handle: session handle to use | ||
204 | * @fence: optional fence to return | ||
205 | * | ||
206 | * Open up a stream for HW test | ||
207 | */ | ||
208 | static int uvd_v6_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, | ||
209 | struct dma_fence **fence) | ||
210 | { | ||
211 | const unsigned ib_size_dw = 16; | ||
212 | struct amdgpu_job *job; | ||
213 | struct amdgpu_ib *ib; | ||
214 | struct dma_fence *f = NULL; | ||
215 | uint64_t dummy; | ||
216 | int i, r; | ||
217 | |||
218 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); | ||
219 | if (r) | ||
220 | return r; | ||
221 | |||
222 | ib = &job->ibs[0]; | ||
223 | dummy = ib->gpu_addr + 1024; | ||
224 | |||
225 | ib->length_dw = 0; | ||
226 | ib->ptr[ib->length_dw++] = 0x00000018; | ||
227 | ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ | ||
228 | ib->ptr[ib->length_dw++] = handle; | ||
229 | ib->ptr[ib->length_dw++] = 0x00010000; | ||
230 | ib->ptr[ib->length_dw++] = upper_32_bits(dummy); | ||
231 | ib->ptr[ib->length_dw++] = dummy; | ||
232 | |||
233 | ib->ptr[ib->length_dw++] = 0x00000014; | ||
234 | ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ | ||
235 | ib->ptr[ib->length_dw++] = 0x0000001c; | ||
236 | ib->ptr[ib->length_dw++] = 0x00000001; | ||
237 | ib->ptr[ib->length_dw++] = 0x00000000; | ||
238 | |||
239 | ib->ptr[ib->length_dw++] = 0x00000008; | ||
240 | ib->ptr[ib->length_dw++] = 0x08000001; /* op initialize */ | ||
241 | |||
242 | for (i = ib->length_dw; i < ib_size_dw; ++i) | ||
243 | ib->ptr[i] = 0x0; | ||
244 | |||
245 | r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); | ||
246 | job->fence = dma_fence_get(f); | ||
247 | if (r) | ||
248 | goto err; | ||
249 | |||
250 | amdgpu_job_free(job); | ||
251 | if (fence) | ||
252 | *fence = dma_fence_get(f); | ||
253 | dma_fence_put(f); | ||
254 | return 0; | ||
255 | |||
256 | err: | ||
257 | amdgpu_job_free(job); | ||
258 | return r; | ||
259 | } | ||
260 | |||
261 | /** | ||
262 | * uvd_v6_0_enc_get_destroy_msg - generate a UVD ENC destroy msg | ||
263 | * | ||
264 | * @adev: amdgpu_device pointer | ||
265 | * @ring: ring we should submit the msg to | ||
266 | * @handle: session handle to use | ||
267 | * @fence: optional fence to return | ||
268 | * | ||
269 | * Close up a stream for HW test or if userspace failed to do so | ||
270 | */ | ||
271 | static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, | ||
272 | uint32_t handle, | ||
273 | bool direct, struct dma_fence **fence) | ||
274 | { | ||
275 | const unsigned ib_size_dw = 16; | ||
276 | struct amdgpu_job *job; | ||
277 | struct amdgpu_ib *ib; | ||
278 | struct dma_fence *f = NULL; | ||
279 | uint64_t dummy; | ||
280 | int i, r; | ||
281 | |||
282 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); | ||
283 | if (r) | ||
284 | return r; | ||
285 | |||
286 | ib = &job->ibs[0]; | ||
287 | dummy = ib->gpu_addr + 1024; | ||
288 | |||
289 | ib->length_dw = 0; | ||
290 | ib->ptr[ib->length_dw++] = 0x00000018; | ||
291 | ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ | ||
292 | ib->ptr[ib->length_dw++] = handle; | ||
293 | ib->ptr[ib->length_dw++] = 0x00010000; | ||
294 | ib->ptr[ib->length_dw++] = upper_32_bits(dummy); | ||
295 | ib->ptr[ib->length_dw++] = dummy; | ||
296 | |||
297 | ib->ptr[ib->length_dw++] = 0x00000014; | ||
298 | ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ | ||
299 | ib->ptr[ib->length_dw++] = 0x0000001c; | ||
300 | ib->ptr[ib->length_dw++] = 0x00000001; | ||
301 | ib->ptr[ib->length_dw++] = 0x00000000; | ||
302 | |||
303 | ib->ptr[ib->length_dw++] = 0x00000008; | ||
304 | ib->ptr[ib->length_dw++] = 0x08000002; /* op close session */ | ||
305 | |||
306 | for (i = ib->length_dw; i < ib_size_dw; ++i) | ||
307 | ib->ptr[i] = 0x0; | ||
308 | |||
309 | if (direct) { | ||
310 | r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); | ||
311 | job->fence = dma_fence_get(f); | ||
312 | if (r) | ||
313 | goto err; | ||
314 | |||
315 | amdgpu_job_free(job); | ||
316 | } else { | ||
317 | r = amdgpu_job_submit(job, ring, &ring->adev->vce.entity, | ||
318 | AMDGPU_FENCE_OWNER_UNDEFINED, &f); | ||
319 | if (r) | ||
320 | goto err; | ||
321 | } | ||
322 | |||
323 | if (fence) | ||
324 | *fence = dma_fence_get(f); | ||
325 | dma_fence_put(f); | ||
326 | return 0; | ||
327 | |||
328 | err: | ||
329 | amdgpu_job_free(job); | ||
330 | return r; | ||
331 | } | ||
332 | |||
333 | /** | ||
334 | * uvd_v6_0_enc_ring_test_ib - test if UVD ENC IBs are working | ||
335 | * | ||
336 | * @ring: the engine to test on | ||
337 | * | ||
338 | */ | ||
339 | static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) | ||
340 | { | ||
341 | struct dma_fence *fence = NULL; | ||
342 | long r; | ||
343 | |||
344 | r = uvd_v6_0_enc_get_create_msg(ring, 1, NULL); | ||
345 | if (r) { | ||
346 | DRM_ERROR("amdgpu: failed to get create msg (%ld).\n", r); | ||
347 | goto error; | ||
348 | } | ||
349 | |||
350 | r = uvd_v6_0_enc_get_destroy_msg(ring, 1, true, &fence); | ||
351 | if (r) { | ||
352 | DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r); | ||
353 | goto error; | ||
354 | } | ||
355 | |||
356 | r = dma_fence_wait_timeout(fence, false, timeout); | ||
357 | if (r == 0) { | ||
358 | DRM_ERROR("amdgpu: IB test timed out.\n"); | ||
359 | r = -ETIMEDOUT; | ||
360 | } else if (r < 0) { | ||
361 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | ||
362 | } else { | ||
363 | DRM_INFO("ib test on ring %d succeeded\n", ring->idx); | ||
364 | r = 0; | ||
365 | } | ||
366 | error: | ||
367 | dma_fence_put(fence); | ||
368 | return r; | ||
369 | } | ||
92 | static int uvd_v6_0_early_init(void *handle) | 370 | static int uvd_v6_0_early_init(void *handle) |
93 | { | 371 | { |
94 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 372 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
@@ -98,6 +376,12 @@ static int uvd_v6_0_early_init(void *handle) | |||
98 | return -ENOENT; | 376 | return -ENOENT; |
99 | 377 | ||
100 | uvd_v6_0_set_ring_funcs(adev); | 378 | uvd_v6_0_set_ring_funcs(adev); |
379 | |||
380 | if (uvd_v6_0_enc_support(adev)) { | ||
381 | adev->uvd.num_enc_rings = 2; | ||
382 | uvd_v6_0_set_enc_ring_funcs(adev); | ||
383 | } | ||
384 | |||
101 | uvd_v6_0_set_irq_funcs(adev); | 385 | uvd_v6_0_set_irq_funcs(adev); |
102 | 386 | ||
103 | return 0; | 387 | return 0; |
@@ -106,7 +390,7 @@ static int uvd_v6_0_early_init(void *handle) | |||
106 | static int uvd_v6_0_sw_init(void *handle) | 390 | static int uvd_v6_0_sw_init(void *handle) |
107 | { | 391 | { |
108 | struct amdgpu_ring *ring; | 392 | struct amdgpu_ring *ring; |
109 | int r; | 393 | int i, r; |
110 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 394 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
111 | 395 | ||
112 | /* UVD TRAP */ | 396 | /* UVD TRAP */ |
@@ -114,10 +398,31 @@ static int uvd_v6_0_sw_init(void *handle) | |||
114 | if (r) | 398 | if (r) |
115 | return r; | 399 | return r; |
116 | 400 | ||
401 | /* UVD ENC TRAP */ | ||
402 | if (uvd_v6_0_enc_support(adev)) { | ||
403 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | ||
404 | r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i + 119, &adev->uvd.irq); | ||
405 | if (r) | ||
406 | return r; | ||
407 | } | ||
408 | } | ||
409 | |||
117 | r = amdgpu_uvd_sw_init(adev); | 410 | r = amdgpu_uvd_sw_init(adev); |
118 | if (r) | 411 | if (r) |
119 | return r; | 412 | return r; |
120 | 413 | ||
414 | if (uvd_v6_0_enc_support(adev)) { | ||
415 | struct amd_sched_rq *rq; | ||
416 | ring = &adev->uvd.ring_enc[0]; | ||
417 | rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL]; | ||
418 | r = amd_sched_entity_init(&ring->sched, &adev->uvd.entity_enc, | ||
419 | rq, amdgpu_sched_jobs); | ||
420 | if (r) { | ||
421 | DRM_ERROR("Failed setting up UVD ENC run queue.\n"); | ||
422 | return r; | ||
423 | } | ||
424 | } | ||
425 | |||
121 | r = amdgpu_uvd_resume(adev); | 426 | r = amdgpu_uvd_resume(adev); |
122 | if (r) | 427 | if (r) |
123 | return r; | 428 | return r; |
@@ -125,19 +430,38 @@ static int uvd_v6_0_sw_init(void *handle) | |||
125 | ring = &adev->uvd.ring; | 430 | ring = &adev->uvd.ring; |
126 | sprintf(ring->name, "uvd"); | 431 | sprintf(ring->name, "uvd"); |
127 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0); | 432 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0); |
433 | if (r) | ||
434 | return r; | ||
435 | |||
436 | if (uvd_v6_0_enc_support(adev)) { | ||
437 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | ||
438 | ring = &adev->uvd.ring_enc[i]; | ||
439 | sprintf(ring->name, "uvd_enc%d", i); | ||
440 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0); | ||
441 | if (r) | ||
442 | return r; | ||
443 | } | ||
444 | } | ||
128 | 445 | ||
129 | return r; | 446 | return r; |
130 | } | 447 | } |
131 | 448 | ||
132 | static int uvd_v6_0_sw_fini(void *handle) | 449 | static int uvd_v6_0_sw_fini(void *handle) |
133 | { | 450 | { |
134 | int r; | 451 | int i, r; |
135 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 452 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
136 | 453 | ||
137 | r = amdgpu_uvd_suspend(adev); | 454 | r = amdgpu_uvd_suspend(adev); |
138 | if (r) | 455 | if (r) |
139 | return r; | 456 | return r; |
140 | 457 | ||
458 | if (uvd_v6_0_enc_support(adev)) { | ||
459 | amd_sched_entity_fini(&adev->uvd.ring_enc[0].sched, &adev->uvd.entity_enc); | ||
460 | |||
461 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) | ||
462 | amdgpu_ring_fini(&adev->uvd.ring_enc[i]); | ||
463 | } | ||
464 | |||
141 | return amdgpu_uvd_sw_fini(adev); | 465 | return amdgpu_uvd_sw_fini(adev); |
142 | } | 466 | } |
143 | 467 | ||
@@ -153,7 +477,7 @@ static int uvd_v6_0_hw_init(void *handle) | |||
153 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 477 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
154 | struct amdgpu_ring *ring = &adev->uvd.ring; | 478 | struct amdgpu_ring *ring = &adev->uvd.ring; |
155 | uint32_t tmp; | 479 | uint32_t tmp; |
156 | int r; | 480 | int i, r; |
157 | 481 | ||
158 | amdgpu_asic_set_uvd_clocks(adev, 10000, 10000); | 482 | amdgpu_asic_set_uvd_clocks(adev, 10000, 10000); |
159 | uvd_v6_0_set_clockgating_state(adev, AMD_CG_STATE_UNGATE); | 483 | uvd_v6_0_set_clockgating_state(adev, AMD_CG_STATE_UNGATE); |
@@ -193,9 +517,25 @@ static int uvd_v6_0_hw_init(void *handle) | |||
193 | 517 | ||
194 | amdgpu_ring_commit(ring); | 518 | amdgpu_ring_commit(ring); |
195 | 519 | ||
520 | if (uvd_v6_0_enc_support(adev)) { | ||
521 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | ||
522 | ring = &adev->uvd.ring_enc[i]; | ||
523 | ring->ready = true; | ||
524 | r = amdgpu_ring_test_ring(ring); | ||
525 | if (r) { | ||
526 | ring->ready = false; | ||
527 | goto done; | ||
528 | } | ||
529 | } | ||
530 | } | ||
531 | |||
196 | done: | 532 | done: |
197 | if (!r) | 533 | if (!r) { |
198 | DRM_INFO("UVD initialized successfully.\n"); | 534 | if (uvd_v6_0_enc_support(adev)) |
535 | DRM_INFO("UVD and UVD ENC initialized successfully.\n"); | ||
536 | else | ||
537 | DRM_INFO("UVD initialized successfully.\n"); | ||
538 | } | ||
199 | 539 | ||
200 | return r; | 540 | return r; |
201 | } | 541 | } |
@@ -512,6 +852,22 @@ static int uvd_v6_0_start(struct amdgpu_device *adev) | |||
512 | 852 | ||
513 | WREG32_FIELD(UVD_RBC_RB_CNTL, RB_NO_FETCH, 0); | 853 | WREG32_FIELD(UVD_RBC_RB_CNTL, RB_NO_FETCH, 0); |
514 | 854 | ||
855 | if (uvd_v6_0_enc_support(adev)) { | ||
856 | ring = &adev->uvd.ring_enc[0]; | ||
857 | WREG32(mmUVD_RB_RPTR, lower_32_bits(ring->wptr)); | ||
858 | WREG32(mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); | ||
859 | WREG32(mmUVD_RB_BASE_LO, ring->gpu_addr); | ||
860 | WREG32(mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); | ||
861 | WREG32(mmUVD_RB_SIZE, ring->ring_size / 4); | ||
862 | |||
863 | ring = &adev->uvd.ring_enc[1]; | ||
864 | WREG32(mmUVD_RB_RPTR2, lower_32_bits(ring->wptr)); | ||
865 | WREG32(mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); | ||
866 | WREG32(mmUVD_RB_BASE_LO2, ring->gpu_addr); | ||
867 | WREG32(mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); | ||
868 | WREG32(mmUVD_RB_SIZE2, ring->ring_size / 4); | ||
869 | } | ||
870 | |||
515 | return 0; | 871 | return 0; |
516 | } | 872 | } |
517 | 873 | ||
@@ -575,6 +931,26 @@ static void uvd_v6_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq | |||
575 | } | 931 | } |
576 | 932 | ||
577 | /** | 933 | /** |
934 | * uvd_v6_0_enc_ring_emit_fence - emit an enc fence & trap command | ||
935 | * | ||
936 | * @ring: amdgpu_ring pointer | ||
937 | * @fence: fence to emit | ||
938 | * | ||
939 | * Write enc a fence and a trap command to the ring. | ||
940 | */ | ||
941 | static void uvd_v6_0_enc_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, | ||
942 | u64 seq, unsigned flags) | ||
943 | { | ||
944 | WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); | ||
945 | |||
946 | amdgpu_ring_write(ring, HEVC_ENC_CMD_FENCE); | ||
947 | amdgpu_ring_write(ring, addr); | ||
948 | amdgpu_ring_write(ring, upper_32_bits(addr)); | ||
949 | amdgpu_ring_write(ring, seq); | ||
950 | amdgpu_ring_write(ring, HEVC_ENC_CMD_TRAP); | ||
951 | } | ||
952 | |||
953 | /** | ||
578 | * uvd_v6_0_ring_emit_hdp_flush - emit an hdp flush | 954 | * uvd_v6_0_ring_emit_hdp_flush - emit an hdp flush |
579 | * | 955 | * |
580 | * @ring: amdgpu_ring pointer | 956 | * @ring: amdgpu_ring pointer |
@@ -665,6 +1041,24 @@ static void uvd_v6_0_ring_emit_ib(struct amdgpu_ring *ring, | |||
665 | amdgpu_ring_write(ring, ib->length_dw); | 1041 | amdgpu_ring_write(ring, ib->length_dw); |
666 | } | 1042 | } |
667 | 1043 | ||
1044 | /** | ||
1045 | * uvd_v6_0_enc_ring_emit_ib - enc execute indirect buffer | ||
1046 | * | ||
1047 | * @ring: amdgpu_ring pointer | ||
1048 | * @ib: indirect buffer to execute | ||
1049 | * | ||
1050 | * Write enc ring commands to execute the indirect buffer | ||
1051 | */ | ||
1052 | static void uvd_v6_0_enc_ring_emit_ib(struct amdgpu_ring *ring, | ||
1053 | struct amdgpu_ib *ib, unsigned int vm_id, bool ctx_switch) | ||
1054 | { | ||
1055 | amdgpu_ring_write(ring, HEVC_ENC_CMD_IB_VM); | ||
1056 | amdgpu_ring_write(ring, vm_id); | ||
1057 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); | ||
1058 | amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); | ||
1059 | amdgpu_ring_write(ring, ib->length_dw); | ||
1060 | } | ||
1061 | |||
668 | static void uvd_v6_0_ring_emit_vm_flush(struct amdgpu_ring *ring, | 1062 | static void uvd_v6_0_ring_emit_vm_flush(struct amdgpu_ring *ring, |
669 | unsigned vm_id, uint64_t pd_addr) | 1063 | unsigned vm_id, uint64_t pd_addr) |
670 | { | 1064 | { |
@@ -716,6 +1110,33 @@ static void uvd_v6_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring) | |||
716 | amdgpu_ring_write(ring, 0xE); | 1110 | amdgpu_ring_write(ring, 0xE); |
717 | } | 1111 | } |
718 | 1112 | ||
1113 | static void uvd_v6_0_enc_ring_emit_pipeline_sync(struct amdgpu_ring *ring) | ||
1114 | { | ||
1115 | uint32_t seq = ring->fence_drv.sync_seq; | ||
1116 | uint64_t addr = ring->fence_drv.gpu_addr; | ||
1117 | |||
1118 | amdgpu_ring_write(ring, HEVC_ENC_CMD_WAIT_GE); | ||
1119 | amdgpu_ring_write(ring, lower_32_bits(addr)); | ||
1120 | amdgpu_ring_write(ring, upper_32_bits(addr)); | ||
1121 | amdgpu_ring_write(ring, seq); | ||
1122 | } | ||
1123 | |||
1124 | static void uvd_v6_0_enc_ring_insert_end(struct amdgpu_ring *ring) | ||
1125 | { | ||
1126 | amdgpu_ring_write(ring, HEVC_ENC_CMD_END); | ||
1127 | } | ||
1128 | |||
1129 | static void uvd_v6_0_enc_ring_emit_vm_flush(struct amdgpu_ring *ring, | ||
1130 | unsigned int vm_id, uint64_t pd_addr) | ||
1131 | { | ||
1132 | amdgpu_ring_write(ring, HEVC_ENC_CMD_UPDATE_PTB); | ||
1133 | amdgpu_ring_write(ring, vm_id); | ||
1134 | amdgpu_ring_write(ring, pd_addr >> 12); | ||
1135 | |||
1136 | amdgpu_ring_write(ring, HEVC_ENC_CMD_FLUSH_TLB); | ||
1137 | amdgpu_ring_write(ring, vm_id); | ||
1138 | } | ||
1139 | |||
719 | static bool uvd_v6_0_is_idle(void *handle) | 1140 | static bool uvd_v6_0_is_idle(void *handle) |
720 | { | 1141 | { |
721 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1142 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
@@ -823,8 +1244,31 @@ static int uvd_v6_0_process_interrupt(struct amdgpu_device *adev, | |||
823 | struct amdgpu_irq_src *source, | 1244 | struct amdgpu_irq_src *source, |
824 | struct amdgpu_iv_entry *entry) | 1245 | struct amdgpu_iv_entry *entry) |
825 | { | 1246 | { |
1247 | bool int_handled = true; | ||
826 | DRM_DEBUG("IH: UVD TRAP\n"); | 1248 | DRM_DEBUG("IH: UVD TRAP\n"); |
827 | amdgpu_fence_process(&adev->uvd.ring); | 1249 | |
1250 | switch (entry->src_id) { | ||
1251 | case 124: | ||
1252 | amdgpu_fence_process(&adev->uvd.ring); | ||
1253 | break; | ||
1254 | case 119: | ||
1255 | if (likely(uvd_v6_0_enc_support(adev))) | ||
1256 | amdgpu_fence_process(&adev->uvd.ring_enc[0]); | ||
1257 | else | ||
1258 | int_handled = false; | ||
1259 | break; | ||
1260 | case 120: | ||
1261 | if (likely(uvd_v6_0_enc_support(adev))) | ||
1262 | amdgpu_fence_process(&adev->uvd.ring_enc[1]); | ||
1263 | else | ||
1264 | int_handled = false; | ||
1265 | break; | ||
1266 | } | ||
1267 | |||
1268 | if (false == int_handled) | ||
1269 | DRM_ERROR("Unhandled interrupt: %d %d\n", | ||
1270 | entry->src_id, entry->src_data[0]); | ||
1271 | |||
828 | return 0; | 1272 | return 0; |
829 | } | 1273 | } |
830 | 1274 | ||
@@ -1151,6 +1595,33 @@ static const struct amdgpu_ring_funcs uvd_v6_0_ring_vm_funcs = { | |||
1151 | .end_use = amdgpu_uvd_ring_end_use, | 1595 | .end_use = amdgpu_uvd_ring_end_use, |
1152 | }; | 1596 | }; |
1153 | 1597 | ||
1598 | static const struct amdgpu_ring_funcs uvd_v6_0_enc_ring_vm_funcs = { | ||
1599 | .type = AMDGPU_RING_TYPE_UVD_ENC, | ||
1600 | .align_mask = 0x3f, | ||
1601 | .nop = HEVC_ENC_CMD_NO_OP, | ||
1602 | .support_64bit_ptrs = false, | ||
1603 | .get_rptr = uvd_v6_0_enc_ring_get_rptr, | ||
1604 | .get_wptr = uvd_v6_0_enc_ring_get_wptr, | ||
1605 | .set_wptr = uvd_v6_0_enc_ring_set_wptr, | ||
1606 | .emit_frame_size = | ||
1607 | 4 + /* uvd_v6_0_enc_ring_emit_pipeline_sync */ | ||
1608 | 6 + /* uvd_v6_0_enc_ring_emit_vm_flush */ | ||
1609 | 5 + 5 + /* uvd_v6_0_enc_ring_emit_fence x2 vm fence */ | ||
1610 | 1, /* uvd_v6_0_enc_ring_insert_end */ | ||
1611 | .emit_ib_size = 5, /* uvd_v6_0_enc_ring_emit_ib */ | ||
1612 | .emit_ib = uvd_v6_0_enc_ring_emit_ib, | ||
1613 | .emit_fence = uvd_v6_0_enc_ring_emit_fence, | ||
1614 | .emit_vm_flush = uvd_v6_0_enc_ring_emit_vm_flush, | ||
1615 | .emit_pipeline_sync = uvd_v6_0_enc_ring_emit_pipeline_sync, | ||
1616 | .test_ring = uvd_v6_0_enc_ring_test_ring, | ||
1617 | .test_ib = uvd_v6_0_enc_ring_test_ib, | ||
1618 | .insert_nop = amdgpu_ring_insert_nop, | ||
1619 | .insert_end = uvd_v6_0_enc_ring_insert_end, | ||
1620 | .pad_ib = amdgpu_ring_generic_pad_ib, | ||
1621 | .begin_use = amdgpu_uvd_ring_begin_use, | ||
1622 | .end_use = amdgpu_uvd_ring_end_use, | ||
1623 | }; | ||
1624 | |||
1154 | static void uvd_v6_0_set_ring_funcs(struct amdgpu_device *adev) | 1625 | static void uvd_v6_0_set_ring_funcs(struct amdgpu_device *adev) |
1155 | { | 1626 | { |
1156 | if (adev->asic_type >= CHIP_POLARIS10) { | 1627 | if (adev->asic_type >= CHIP_POLARIS10) { |
@@ -1162,6 +1633,16 @@ static void uvd_v6_0_set_ring_funcs(struct amdgpu_device *adev) | |||
1162 | } | 1633 | } |
1163 | } | 1634 | } |
1164 | 1635 | ||
1636 | static void uvd_v6_0_set_enc_ring_funcs(struct amdgpu_device *adev) | ||
1637 | { | ||
1638 | int i; | ||
1639 | |||
1640 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) | ||
1641 | adev->uvd.ring_enc[i].funcs = &uvd_v6_0_enc_ring_vm_funcs; | ||
1642 | |||
1643 | DRM_INFO("UVD ENC is enabled in VM mode\n"); | ||
1644 | } | ||
1645 | |||
1165 | static const struct amdgpu_irq_src_funcs uvd_v6_0_irq_funcs = { | 1646 | static const struct amdgpu_irq_src_funcs uvd_v6_0_irq_funcs = { |
1166 | .set = uvd_v6_0_set_interrupt_state, | 1647 | .set = uvd_v6_0_set_interrupt_state, |
1167 | .process = uvd_v6_0_process_interrupt, | 1648 | .process = uvd_v6_0_process_interrupt, |
@@ -1169,7 +1650,11 @@ static const struct amdgpu_irq_src_funcs uvd_v6_0_irq_funcs = { | |||
1169 | 1650 | ||
1170 | static void uvd_v6_0_set_irq_funcs(struct amdgpu_device *adev) | 1651 | static void uvd_v6_0_set_irq_funcs(struct amdgpu_device *adev) |
1171 | { | 1652 | { |
1172 | adev->uvd.irq.num_types = 1; | 1653 | if (uvd_v6_0_enc_support(adev)) |
1654 | adev->uvd.irq.num_types = adev->uvd.num_enc_rings + 1; | ||
1655 | else | ||
1656 | adev->uvd.irq.num_types = 1; | ||
1657 | |||
1173 | adev->uvd.irq.funcs = &uvd_v6_0_irq_funcs; | 1658 | adev->uvd.irq.funcs = &uvd_v6_0_irq_funcs; |
1174 | } | 1659 | } |
1175 | 1660 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index 23a85750edd6..6634545060fd 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | |||
@@ -592,11 +592,7 @@ static int uvd_v7_0_suspend(void *handle) | |||
592 | if (r) | 592 | if (r) |
593 | return r; | 593 | return r; |
594 | 594 | ||
595 | /* Skip this for APU for now */ | 595 | return amdgpu_uvd_suspend(adev); |
596 | if (!(adev->flags & AMD_IS_APU)) | ||
597 | r = amdgpu_uvd_suspend(adev); | ||
598 | |||
599 | return r; | ||
600 | } | 596 | } |
601 | 597 | ||
602 | static int uvd_v7_0_resume(void *handle) | 598 | static int uvd_v7_0_resume(void *handle) |
@@ -604,12 +600,10 @@ static int uvd_v7_0_resume(void *handle) | |||
604 | int r; | 600 | int r; |
605 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 601 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
606 | 602 | ||
607 | /* Skip this for APU for now */ | 603 | r = amdgpu_uvd_resume(adev); |
608 | if (!(adev->flags & AMD_IS_APU)) { | 604 | if (r) |
609 | r = amdgpu_uvd_resume(adev); | 605 | return r; |
610 | if (r) | 606 | |
611 | return r; | ||
612 | } | ||
613 | return uvd_v7_0_hw_init(adev); | 607 | return uvd_v7_0_hw_init(adev); |
614 | } | 608 | } |
615 | 609 | ||
@@ -1161,7 +1155,7 @@ static void uvd_v7_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) | |||
1161 | */ | 1155 | */ |
1162 | static void uvd_v7_0_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) | 1156 | static void uvd_v7_0_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) |
1163 | { | 1157 | { |
1164 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(HDP, 0, mmHDP_DEBUG0), 0)); | 1158 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(HDP, 0, mmHDP_READ_CACHE_INVALIDATE), 0)); |
1165 | amdgpu_ring_write(ring, 1); | 1159 | amdgpu_ring_write(ring, 1); |
1166 | } | 1160 | } |
1167 | 1161 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c index 11134d5f7443..75745544600a 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c | |||
@@ -1011,10 +1011,6 @@ static int vce_v4_0_process_interrupt(struct amdgpu_device *adev, | |||
1011 | { | 1011 | { |
1012 | DRM_DEBUG("IH: VCE\n"); | 1012 | DRM_DEBUG("IH: VCE\n"); |
1013 | 1013 | ||
1014 | WREG32_P(SOC15_REG_OFFSET(VCE, 0, mmVCE_SYS_INT_STATUS), | ||
1015 | VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK, | ||
1016 | ~VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK); | ||
1017 | |||
1018 | switch (entry->src_data[0]) { | 1014 | switch (entry->src_data[0]) { |
1019 | case 0: | 1015 | case 0: |
1020 | case 1: | 1016 | case 1: |
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index 21e7b88401e1..1eb4d79d6e30 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | |||
@@ -812,7 +812,7 @@ static void vcn_v1_0_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 | |||
812 | */ | 812 | */ |
813 | static void vcn_v1_0_dec_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) | 813 | static void vcn_v1_0_dec_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) |
814 | { | 814 | { |
815 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(HDP, 0, mmHDP_DEBUG0), 0)); | 815 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(HDP, 0, mmHDP_READ_CACHE_INVALIDATE), 0)); |
816 | amdgpu_ring_write(ring, 1); | 816 | amdgpu_ring_write(ring, 1); |
817 | } | 817 | } |
818 | 818 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c index 56150e8d1ed2..697325737ba8 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c | |||
@@ -219,14 +219,95 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev) | |||
219 | wptr, adev->irq.ih.rptr, tmp); | 219 | wptr, adev->irq.ih.rptr, tmp); |
220 | adev->irq.ih.rptr = tmp; | 220 | adev->irq.ih.rptr = tmp; |
221 | 221 | ||
222 | tmp = RREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL)); | 222 | tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL)); |
223 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); | 223 | tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); |
224 | WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL), tmp); | 224 | WREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL), tmp); |
225 | } | 225 | } |
226 | return (wptr & adev->irq.ih.ptr_mask); | 226 | return (wptr & adev->irq.ih.ptr_mask); |
227 | } | 227 | } |
228 | 228 | ||
229 | /** | 229 | /** |
230 | * vega10_ih_prescreen_iv - prescreen an interrupt vector | ||
231 | * | ||
232 | * @adev: amdgpu_device pointer | ||
233 | * | ||
234 | * Returns true if the interrupt vector should be further processed. | ||
235 | */ | ||
236 | static bool vega10_ih_prescreen_iv(struct amdgpu_device *adev) | ||
237 | { | ||
238 | u32 ring_index = adev->irq.ih.rptr >> 2; | ||
239 | u32 dw0, dw3, dw4, dw5; | ||
240 | u16 pasid; | ||
241 | u64 addr, key; | ||
242 | struct amdgpu_vm *vm; | ||
243 | int r; | ||
244 | |||
245 | dw0 = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]); | ||
246 | dw3 = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]); | ||
247 | dw4 = le32_to_cpu(adev->irq.ih.ring[ring_index + 4]); | ||
248 | dw5 = le32_to_cpu(adev->irq.ih.ring[ring_index + 5]); | ||
249 | |||
250 | /* Filter retry page faults, let only the first one pass. If | ||
251 | * there are too many outstanding faults, ignore them until | ||
252 | * some faults get cleared. | ||
253 | */ | ||
254 | switch (dw0 & 0xff) { | ||
255 | case AMDGPU_IH_CLIENTID_VMC: | ||
256 | case AMDGPU_IH_CLIENTID_UTCL2: | ||
257 | break; | ||
258 | default: | ||
259 | /* Not a VM fault */ | ||
260 | return true; | ||
261 | } | ||
262 | |||
263 | pasid = dw3 & 0xffff; | ||
264 | /* No PASID, can't identify faulting process */ | ||
265 | if (!pasid) | ||
266 | return true; | ||
267 | |||
268 | /* Not a retry fault, check fault credit */ | ||
269 | if (!(dw5 & 0x80)) { | ||
270 | if (!amdgpu_vm_pasid_fault_credit(adev, pasid)) | ||
271 | goto ignore_iv; | ||
272 | return true; | ||
273 | } | ||
274 | |||
275 | addr = ((u64)(dw5 & 0xf) << 44) | ((u64)dw4 << 12); | ||
276 | key = AMDGPU_VM_FAULT(pasid, addr); | ||
277 | r = amdgpu_ih_add_fault(adev, key); | ||
278 | |||
279 | /* Hash table is full or the fault is already being processed, | ||
280 | * ignore further page faults | ||
281 | */ | ||
282 | if (r != 0) | ||
283 | goto ignore_iv; | ||
284 | |||
285 | /* Track retry faults in per-VM fault FIFO. */ | ||
286 | spin_lock(&adev->vm_manager.pasid_lock); | ||
287 | vm = idr_find(&adev->vm_manager.pasid_idr, pasid); | ||
288 | spin_unlock(&adev->vm_manager.pasid_lock); | ||
289 | if (WARN_ON_ONCE(!vm)) { | ||
290 | /* VM not found, process it normally */ | ||
291 | amdgpu_ih_clear_fault(adev, key); | ||
292 | return true; | ||
293 | } | ||
294 | /* No locking required with single writer and single reader */ | ||
295 | r = kfifo_put(&vm->faults, key); | ||
296 | if (!r) { | ||
297 | /* FIFO is full. Ignore it until there is space */ | ||
298 | amdgpu_ih_clear_fault(adev, key); | ||
299 | goto ignore_iv; | ||
300 | } | ||
301 | |||
302 | /* It's the first fault for this address, process it normally */ | ||
303 | return true; | ||
304 | |||
305 | ignore_iv: | ||
306 | adev->irq.ih.rptr += 32; | ||
307 | return false; | ||
308 | } | ||
309 | |||
310 | /** | ||
230 | * vega10_ih_decode_iv - decode an interrupt vector | 311 | * vega10_ih_decode_iv - decode an interrupt vector |
231 | * | 312 | * |
232 | * @adev: amdgpu_device pointer | 313 | * @adev: amdgpu_device pointer |
@@ -310,6 +391,14 @@ static int vega10_ih_sw_init(void *handle) | |||
310 | adev->irq.ih.use_doorbell = true; | 391 | adev->irq.ih.use_doorbell = true; |
311 | adev->irq.ih.doorbell_index = AMDGPU_DOORBELL64_IH << 1; | 392 | adev->irq.ih.doorbell_index = AMDGPU_DOORBELL64_IH << 1; |
312 | 393 | ||
394 | adev->irq.ih.faults = kmalloc(sizeof(*adev->irq.ih.faults), GFP_KERNEL); | ||
395 | if (!adev->irq.ih.faults) | ||
396 | return -ENOMEM; | ||
397 | INIT_CHASH_TABLE(adev->irq.ih.faults->hash, | ||
398 | AMDGPU_PAGEFAULT_HASH_BITS, 8, 0); | ||
399 | spin_lock_init(&adev->irq.ih.faults->lock); | ||
400 | adev->irq.ih.faults->count = 0; | ||
401 | |||
313 | r = amdgpu_irq_init(adev); | 402 | r = amdgpu_irq_init(adev); |
314 | 403 | ||
315 | return r; | 404 | return r; |
@@ -322,6 +411,9 @@ static int vega10_ih_sw_fini(void *handle) | |||
322 | amdgpu_irq_fini(adev); | 411 | amdgpu_irq_fini(adev); |
323 | amdgpu_ih_ring_fini(adev); | 412 | amdgpu_ih_ring_fini(adev); |
324 | 413 | ||
414 | kfree(adev->irq.ih.faults); | ||
415 | adev->irq.ih.faults = NULL; | ||
416 | |||
325 | return 0; | 417 | return 0; |
326 | } | 418 | } |
327 | 419 | ||
@@ -410,6 +502,7 @@ const struct amd_ip_funcs vega10_ih_ip_funcs = { | |||
410 | 502 | ||
411 | static const struct amdgpu_ih_funcs vega10_ih_funcs = { | 503 | static const struct amdgpu_ih_funcs vega10_ih_funcs = { |
412 | .get_wptr = vega10_ih_get_wptr, | 504 | .get_wptr = vega10_ih_get_wptr, |
505 | .prescreen_iv = vega10_ih_prescreen_iv, | ||
413 | .decode_iv = vega10_ih_decode_iv, | 506 | .decode_iv = vega10_ih_decode_iv, |
414 | .set_rptr = vega10_ih_set_rptr | 507 | .set_rptr = vega10_ih_set_rptr |
415 | }; | 508 | }; |
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 9ff69b90df36..3a4c2fa7e36d 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c | |||
@@ -77,6 +77,7 @@ | |||
77 | #endif | 77 | #endif |
78 | #include "dce_virtual.h" | 78 | #include "dce_virtual.h" |
79 | #include "mxgpu_vi.h" | 79 | #include "mxgpu_vi.h" |
80 | #include "amdgpu_dm.h" | ||
80 | 81 | ||
81 | /* | 82 | /* |
82 | * Indirect registers accessor | 83 | * Indirect registers accessor |
@@ -1254,7 +1255,6 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, | |||
1254 | uint32_t msg_id, pp_state = 0; | 1255 | uint32_t msg_id, pp_state = 0; |
1255 | uint32_t pp_support_state = 0; | 1256 | uint32_t pp_support_state = 0; |
1256 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1257 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1257 | void *pp_handle = adev->powerplay.pp_handle; | ||
1258 | 1258 | ||
1259 | if (adev->cg_flags & (AMD_CG_SUPPORT_MC_LS | AMD_CG_SUPPORT_MC_MGCG)) { | 1259 | if (adev->cg_flags & (AMD_CG_SUPPORT_MC_LS | AMD_CG_SUPPORT_MC_MGCG)) { |
1260 | if (adev->cg_flags & AMD_CG_SUPPORT_MC_LS) { | 1260 | if (adev->cg_flags & AMD_CG_SUPPORT_MC_LS) { |
@@ -1271,7 +1271,8 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, | |||
1271 | PP_BLOCK_SYS_MC, | 1271 | PP_BLOCK_SYS_MC, |
1272 | pp_support_state, | 1272 | pp_support_state, |
1273 | pp_state); | 1273 | pp_state); |
1274 | amd_set_clockgating_by_smu(pp_handle, msg_id); | 1274 | if (adev->powerplay.pp_funcs->set_clockgating_by_smu) |
1275 | amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); | ||
1275 | } | 1276 | } |
1276 | 1277 | ||
1277 | if (adev->cg_flags & (AMD_CG_SUPPORT_SDMA_LS | AMD_CG_SUPPORT_SDMA_MGCG)) { | 1278 | if (adev->cg_flags & (AMD_CG_SUPPORT_SDMA_LS | AMD_CG_SUPPORT_SDMA_MGCG)) { |
@@ -1289,7 +1290,8 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, | |||
1289 | PP_BLOCK_SYS_SDMA, | 1290 | PP_BLOCK_SYS_SDMA, |
1290 | pp_support_state, | 1291 | pp_support_state, |
1291 | pp_state); | 1292 | pp_state); |
1292 | amd_set_clockgating_by_smu(pp_handle, msg_id); | 1293 | if (adev->powerplay.pp_funcs->set_clockgating_by_smu) |
1294 | amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); | ||
1293 | } | 1295 | } |
1294 | 1296 | ||
1295 | if (adev->cg_flags & (AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_HDP_MGCG)) { | 1297 | if (adev->cg_flags & (AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_HDP_MGCG)) { |
@@ -1307,7 +1309,8 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, | |||
1307 | PP_BLOCK_SYS_HDP, | 1309 | PP_BLOCK_SYS_HDP, |
1308 | pp_support_state, | 1310 | pp_support_state, |
1309 | pp_state); | 1311 | pp_state); |
1310 | amd_set_clockgating_by_smu(pp_handle, msg_id); | 1312 | if (adev->powerplay.pp_funcs->set_clockgating_by_smu) |
1313 | amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); | ||
1311 | } | 1314 | } |
1312 | 1315 | ||
1313 | 1316 | ||
@@ -1321,7 +1324,8 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, | |||
1321 | PP_BLOCK_SYS_BIF, | 1324 | PP_BLOCK_SYS_BIF, |
1322 | PP_STATE_SUPPORT_LS, | 1325 | PP_STATE_SUPPORT_LS, |
1323 | pp_state); | 1326 | pp_state); |
1324 | amd_set_clockgating_by_smu(pp_handle, msg_id); | 1327 | if (adev->powerplay.pp_funcs->set_clockgating_by_smu) |
1328 | amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); | ||
1325 | } | 1329 | } |
1326 | if (adev->cg_flags & AMD_CG_SUPPORT_BIF_MGCG) { | 1330 | if (adev->cg_flags & AMD_CG_SUPPORT_BIF_MGCG) { |
1327 | if (state == AMD_CG_STATE_UNGATE) | 1331 | if (state == AMD_CG_STATE_UNGATE) |
@@ -1333,7 +1337,8 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, | |||
1333 | PP_BLOCK_SYS_BIF, | 1337 | PP_BLOCK_SYS_BIF, |
1334 | PP_STATE_SUPPORT_CG, | 1338 | PP_STATE_SUPPORT_CG, |
1335 | pp_state); | 1339 | pp_state); |
1336 | amd_set_clockgating_by_smu(pp_handle, msg_id); | 1340 | if (adev->powerplay.pp_funcs->set_clockgating_by_smu) |
1341 | amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); | ||
1337 | } | 1342 | } |
1338 | 1343 | ||
1339 | if (adev->cg_flags & AMD_CG_SUPPORT_DRM_LS) { | 1344 | if (adev->cg_flags & AMD_CG_SUPPORT_DRM_LS) { |
@@ -1347,7 +1352,8 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, | |||
1347 | PP_BLOCK_SYS_DRM, | 1352 | PP_BLOCK_SYS_DRM, |
1348 | PP_STATE_SUPPORT_LS, | 1353 | PP_STATE_SUPPORT_LS, |
1349 | pp_state); | 1354 | pp_state); |
1350 | amd_set_clockgating_by_smu(pp_handle, msg_id); | 1355 | if (adev->powerplay.pp_funcs->set_clockgating_by_smu) |
1356 | amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); | ||
1351 | } | 1357 | } |
1352 | 1358 | ||
1353 | if (adev->cg_flags & AMD_CG_SUPPORT_ROM_MGCG) { | 1359 | if (adev->cg_flags & AMD_CG_SUPPORT_ROM_MGCG) { |
@@ -1361,7 +1367,8 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, | |||
1361 | PP_BLOCK_SYS_ROM, | 1367 | PP_BLOCK_SYS_ROM, |
1362 | PP_STATE_SUPPORT_CG, | 1368 | PP_STATE_SUPPORT_CG, |
1363 | pp_state); | 1369 | pp_state); |
1364 | amd_set_clockgating_by_smu(pp_handle, msg_id); | 1370 | if (adev->powerplay.pp_funcs->set_clockgating_by_smu) |
1371 | amdgpu_dpm_set_clockgating_by_smu(adev, msg_id); | ||
1365 | } | 1372 | } |
1366 | return 0; | 1373 | return 0; |
1367 | } | 1374 | } |
@@ -1496,6 +1503,10 @@ int vi_set_ip_blocks(struct amdgpu_device *adev) | |||
1496 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); | 1503 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); |
1497 | if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) | 1504 | if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) |
1498 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); | 1505 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); |
1506 | #if defined(CONFIG_DRM_AMD_DC) | ||
1507 | else if (amdgpu_device_has_dc_support(adev)) | ||
1508 | amdgpu_ip_block_add(adev, &dm_ip_block); | ||
1509 | #endif | ||
1499 | else | 1510 | else |
1500 | amdgpu_ip_block_add(adev, &dce_v10_1_ip_block); | 1511 | amdgpu_ip_block_add(adev, &dce_v10_1_ip_block); |
1501 | amdgpu_ip_block_add(adev, &gfx_v8_0_ip_block); | 1512 | amdgpu_ip_block_add(adev, &gfx_v8_0_ip_block); |
@@ -1512,6 +1523,10 @@ int vi_set_ip_blocks(struct amdgpu_device *adev) | |||
1512 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); | 1523 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); |
1513 | if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) | 1524 | if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) |
1514 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); | 1525 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); |
1526 | #if defined(CONFIG_DRM_AMD_DC) | ||
1527 | else if (amdgpu_device_has_dc_support(adev)) | ||
1528 | amdgpu_ip_block_add(adev, &dm_ip_block); | ||
1529 | #endif | ||
1515 | else | 1530 | else |
1516 | amdgpu_ip_block_add(adev, &dce_v10_0_ip_block); | 1531 | amdgpu_ip_block_add(adev, &dce_v10_0_ip_block); |
1517 | amdgpu_ip_block_add(adev, &gfx_v8_0_ip_block); | 1532 | amdgpu_ip_block_add(adev, &gfx_v8_0_ip_block); |
@@ -1530,6 +1545,10 @@ int vi_set_ip_blocks(struct amdgpu_device *adev) | |||
1530 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); | 1545 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); |
1531 | if (adev->enable_virtual_display) | 1546 | if (adev->enable_virtual_display) |
1532 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); | 1547 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); |
1548 | #if defined(CONFIG_DRM_AMD_DC) | ||
1549 | else if (amdgpu_device_has_dc_support(adev)) | ||
1550 | amdgpu_ip_block_add(adev, &dm_ip_block); | ||
1551 | #endif | ||
1533 | else | 1552 | else |
1534 | amdgpu_ip_block_add(adev, &dce_v11_2_ip_block); | 1553 | amdgpu_ip_block_add(adev, &dce_v11_2_ip_block); |
1535 | amdgpu_ip_block_add(adev, &gfx_v8_0_ip_block); | 1554 | amdgpu_ip_block_add(adev, &gfx_v8_0_ip_block); |
@@ -1544,6 +1563,10 @@ int vi_set_ip_blocks(struct amdgpu_device *adev) | |||
1544 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); | 1563 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); |
1545 | if (adev->enable_virtual_display) | 1564 | if (adev->enable_virtual_display) |
1546 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); | 1565 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); |
1566 | #if defined(CONFIG_DRM_AMD_DC) | ||
1567 | else if (amdgpu_device_has_dc_support(adev)) | ||
1568 | amdgpu_ip_block_add(adev, &dm_ip_block); | ||
1569 | #endif | ||
1547 | else | 1570 | else |
1548 | amdgpu_ip_block_add(adev, &dce_v11_0_ip_block); | 1571 | amdgpu_ip_block_add(adev, &dce_v11_0_ip_block); |
1549 | amdgpu_ip_block_add(adev, &gfx_v8_0_ip_block); | 1572 | amdgpu_ip_block_add(adev, &gfx_v8_0_ip_block); |
@@ -1561,6 +1584,10 @@ int vi_set_ip_blocks(struct amdgpu_device *adev) | |||
1561 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); | 1584 | amdgpu_ip_block_add(adev, &amdgpu_pp_ip_block); |
1562 | if (adev->enable_virtual_display) | 1585 | if (adev->enable_virtual_display) |
1563 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); | 1586 | amdgpu_ip_block_add(adev, &dce_virtual_ip_block); |
1587 | #if defined(CONFIG_DRM_AMD_DC) | ||
1588 | else if (amdgpu_device_has_dc_support(adev)) | ||
1589 | amdgpu_ip_block_add(adev, &dm_ip_block); | ||
1590 | #endif | ||
1564 | else | 1591 | else |
1565 | amdgpu_ip_block_add(adev, &dce_v11_0_ip_block); | 1592 | amdgpu_ip_block_add(adev, &dce_v11_0_ip_block); |
1566 | amdgpu_ip_block_add(adev, &gfx_v8_1_ip_block); | 1593 | amdgpu_ip_block_add(adev, &gfx_v8_1_ip_block); |
diff --git a/drivers/gpu/drm/amd/amdgpu/vid.h b/drivers/gpu/drm/amd/amdgpu/vid.h index a6485254a169..dbf3703cbd1b 100644 --- a/drivers/gpu/drm/amd/amdgpu/vid.h +++ b/drivers/gpu/drm/amd/amdgpu/vid.h | |||
@@ -465,6 +465,16 @@ | |||
465 | #define VCE_CMD_UPDATE_PTB 0x00000107 | 465 | #define VCE_CMD_UPDATE_PTB 0x00000107 |
466 | #define VCE_CMD_FLUSH_TLB 0x00000108 | 466 | #define VCE_CMD_FLUSH_TLB 0x00000108 |
467 | 467 | ||
468 | /* HEVC ENC */ | ||
469 | #define HEVC_ENC_CMD_NO_OP 0x00000000 | ||
470 | #define HEVC_ENC_CMD_END 0x00000001 | ||
471 | #define HEVC_ENC_CMD_FENCE 0x00000003 | ||
472 | #define HEVC_ENC_CMD_TRAP 0x00000004 | ||
473 | #define HEVC_ENC_CMD_IB_VM 0x00000102 | ||
474 | #define HEVC_ENC_CMD_WAIT_GE 0x00000106 | ||
475 | #define HEVC_ENC_CMD_UPDATE_PTB 0x00000107 | ||
476 | #define HEVC_ENC_CMD_FLUSH_TLB 0x00000108 | ||
477 | |||
468 | /* mmPA_SC_RASTER_CONFIG mask */ | 478 | /* mmPA_SC_RASTER_CONFIG mask */ |
469 | #define RB_MAP_PKR0(x) ((x) << 0) | 479 | #define RB_MAP_PKR0(x) ((x) << 0) |
470 | #define RB_MAP_PKR0_MASK (0x3 << 0) | 480 | #define RB_MAP_PKR0_MASK (0x3 << 0) |