diff options
Diffstat (limited to 'drivers/gpu/drm/amd')
172 files changed, 5548 insertions, 4610 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index 138cb787d27e..f76bcb9c45e4 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile | |||
@@ -53,7 +53,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \ | |||
53 | amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \ | 53 | amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \ |
54 | amdgpu_gtt_mgr.o amdgpu_vram_mgr.o amdgpu_virt.o amdgpu_atomfirmware.o \ | 54 | amdgpu_gtt_mgr.o amdgpu_vram_mgr.o amdgpu_virt.o amdgpu_atomfirmware.o \ |
55 | amdgpu_vf_error.o amdgpu_sched.o amdgpu_debugfs.o amdgpu_ids.o \ | 55 | amdgpu_vf_error.o amdgpu_sched.o amdgpu_debugfs.o amdgpu_ids.o \ |
56 | amdgpu_gmc.o amdgpu_xgmi.o | 56 | amdgpu_gmc.o amdgpu_xgmi.o amdgpu_csa.o |
57 | 57 | ||
58 | # add asic specific block | 58 | # add asic specific block |
59 | amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ | 59 | amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ |
@@ -105,6 +105,7 @@ amdgpu-y += \ | |||
105 | # add GFX block | 105 | # add GFX block |
106 | amdgpu-y += \ | 106 | amdgpu-y += \ |
107 | amdgpu_gfx.o \ | 107 | amdgpu_gfx.o \ |
108 | amdgpu_rlc.o \ | ||
108 | gfx_v8_0.o \ | 109 | gfx_v8_0.o \ |
109 | gfx_v9_0.o | 110 | gfx_v9_0.o |
110 | 111 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index d0102cfc8efb..42f882c633ee 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -75,6 +75,7 @@ | |||
75 | #include "amdgpu_sdma.h" | 75 | #include "amdgpu_sdma.h" |
76 | #include "amdgpu_dm.h" | 76 | #include "amdgpu_dm.h" |
77 | #include "amdgpu_virt.h" | 77 | #include "amdgpu_virt.h" |
78 | #include "amdgpu_csa.h" | ||
78 | #include "amdgpu_gart.h" | 79 | #include "amdgpu_gart.h" |
79 | #include "amdgpu_debugfs.h" | 80 | #include "amdgpu_debugfs.h" |
80 | #include "amdgpu_job.h" | 81 | #include "amdgpu_job.h" |
@@ -151,6 +152,7 @@ extern int amdgpu_compute_multipipe; | |||
151 | extern int amdgpu_gpu_recovery; | 152 | extern int amdgpu_gpu_recovery; |
152 | extern int amdgpu_emu_mode; | 153 | extern int amdgpu_emu_mode; |
153 | extern uint amdgpu_smu_memory_pool_size; | 154 | extern uint amdgpu_smu_memory_pool_size; |
155 | extern uint amdgpu_dc_feature_mask; | ||
154 | extern struct amdgpu_mgpu_info mgpu_info; | 156 | extern struct amdgpu_mgpu_info mgpu_info; |
155 | 157 | ||
156 | #ifdef CONFIG_DRM_AMDGPU_SI | 158 | #ifdef CONFIG_DRM_AMDGPU_SI |
@@ -432,7 +434,7 @@ typedef enum _AMDGPU_DOORBELL64_ASSIGNMENT | |||
432 | * default non-graphics QWORD index is 0xe0 - 0xFF inclusive | 434 | * default non-graphics QWORD index is 0xe0 - 0xFF inclusive |
433 | */ | 435 | */ |
434 | 436 | ||
435 | /* sDMA engines reserved from 0xe0 -oxef */ | 437 | /* sDMA engines reserved from 0xe0 -0xef */ |
436 | AMDGPU_DOORBELL64_sDMA_ENGINE0 = 0xE0, | 438 | AMDGPU_DOORBELL64_sDMA_ENGINE0 = 0xE0, |
437 | AMDGPU_DOORBELL64_sDMA_HI_PRI_ENGINE0 = 0xE1, | 439 | AMDGPU_DOORBELL64_sDMA_HI_PRI_ENGINE0 = 0xE1, |
438 | AMDGPU_DOORBELL64_sDMA_ENGINE1 = 0xE8, | 440 | AMDGPU_DOORBELL64_sDMA_ENGINE1 = 0xE8, |
@@ -830,7 +832,6 @@ struct amdgpu_device { | |||
830 | bool need_dma32; | 832 | bool need_dma32; |
831 | bool need_swiotlb; | 833 | bool need_swiotlb; |
832 | bool accel_working; | 834 | bool accel_working; |
833 | struct work_struct reset_work; | ||
834 | struct notifier_block acpi_nb; | 835 | struct notifier_block acpi_nb; |
835 | struct amdgpu_i2c_chan *i2c_bus[AMDGPU_MAX_I2C_BUS]; | 836 | struct amdgpu_i2c_chan *i2c_bus[AMDGPU_MAX_I2C_BUS]; |
836 | struct amdgpu_debugfs debugfs[AMDGPU_DEBUGFS_MAX_COMPONENTS]; | 837 | struct amdgpu_debugfs debugfs[AMDGPU_DEBUGFS_MAX_COMPONENTS]; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index c31a8849e9f8..60f9a87e9c74 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | |||
@@ -144,7 +144,7 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) | |||
144 | KGD_MAX_QUEUES); | 144 | KGD_MAX_QUEUES); |
145 | 145 | ||
146 | /* remove the KIQ bit as well */ | 146 | /* remove the KIQ bit as well */ |
147 | if (adev->gfx.kiq.ring.ready) | 147 | if (adev->gfx.kiq.ring.sched.ready) |
148 | clear_bit(amdgpu_gfx_queue_to_bit(adev, | 148 | clear_bit(amdgpu_gfx_queue_to_bit(adev, |
149 | adev->gfx.kiq.ring.me - 1, | 149 | adev->gfx.kiq.ring.me - 1, |
150 | adev->gfx.kiq.ring.pipe, | 150 | adev->gfx.kiq.ring.pipe, |
@@ -268,9 +268,9 @@ void amdgpu_amdkfd_gpu_reset(struct kgd_dev *kgd) | |||
268 | amdgpu_device_gpu_recover(adev, NULL); | 268 | amdgpu_device_gpu_recover(adev, NULL); |
269 | } | 269 | } |
270 | 270 | ||
271 | int alloc_gtt_mem(struct kgd_dev *kgd, size_t size, | 271 | int amdgpu_amdkfd_alloc_gtt_mem(struct kgd_dev *kgd, size_t size, |
272 | void **mem_obj, uint64_t *gpu_addr, | 272 | void **mem_obj, uint64_t *gpu_addr, |
273 | void **cpu_ptr, bool mqd_gfx9) | 273 | void **cpu_ptr, bool mqd_gfx9) |
274 | { | 274 | { |
275 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; | 275 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; |
276 | struct amdgpu_bo *bo = NULL; | 276 | struct amdgpu_bo *bo = NULL; |
@@ -340,7 +340,7 @@ allocate_mem_reserve_bo_failed: | |||
340 | return r; | 340 | return r; |
341 | } | 341 | } |
342 | 342 | ||
343 | void free_gtt_mem(struct kgd_dev *kgd, void *mem_obj) | 343 | void amdgpu_amdkfd_free_gtt_mem(struct kgd_dev *kgd, void *mem_obj) |
344 | { | 344 | { |
345 | struct amdgpu_bo *bo = (struct amdgpu_bo *) mem_obj; | 345 | struct amdgpu_bo *bo = (struct amdgpu_bo *) mem_obj; |
346 | 346 | ||
@@ -351,8 +351,8 @@ void free_gtt_mem(struct kgd_dev *kgd, void *mem_obj) | |||
351 | amdgpu_bo_unref(&(bo)); | 351 | amdgpu_bo_unref(&(bo)); |
352 | } | 352 | } |
353 | 353 | ||
354 | void get_local_mem_info(struct kgd_dev *kgd, | 354 | void amdgpu_amdkfd_get_local_mem_info(struct kgd_dev *kgd, |
355 | struct kfd_local_mem_info *mem_info) | 355 | struct kfd_local_mem_info *mem_info) |
356 | { | 356 | { |
357 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; | 357 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; |
358 | uint64_t address_mask = adev->dev->dma_mask ? ~*adev->dev->dma_mask : | 358 | uint64_t address_mask = adev->dev->dma_mask ? ~*adev->dev->dma_mask : |
@@ -383,7 +383,7 @@ void get_local_mem_info(struct kgd_dev *kgd, | |||
383 | mem_info->mem_clk_max = 100; | 383 | mem_info->mem_clk_max = 100; |
384 | } | 384 | } |
385 | 385 | ||
386 | uint64_t get_gpu_clock_counter(struct kgd_dev *kgd) | 386 | uint64_t amdgpu_amdkfd_get_gpu_clock_counter(struct kgd_dev *kgd) |
387 | { | 387 | { |
388 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; | 388 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; |
389 | 389 | ||
@@ -392,7 +392,7 @@ uint64_t get_gpu_clock_counter(struct kgd_dev *kgd) | |||
392 | return 0; | 392 | return 0; |
393 | } | 393 | } |
394 | 394 | ||
395 | uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd) | 395 | uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct kgd_dev *kgd) |
396 | { | 396 | { |
397 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; | 397 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; |
398 | 398 | ||
@@ -405,7 +405,7 @@ uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd) | |||
405 | return 100; | 405 | return 100; |
406 | } | 406 | } |
407 | 407 | ||
408 | void get_cu_info(struct kgd_dev *kgd, struct kfd_cu_info *cu_info) | 408 | void amdgpu_amdkfd_get_cu_info(struct kgd_dev *kgd, struct kfd_cu_info *cu_info) |
409 | { | 409 | { |
410 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; | 410 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; |
411 | struct amdgpu_cu_info acu_info = adev->gfx.cu_info; | 411 | struct amdgpu_cu_info acu_info = adev->gfx.cu_info; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h index 8e0d4f7196b4..bcf587b4ba98 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | |||
@@ -134,16 +134,16 @@ int amdgpu_amdkfd_post_reset(struct amdgpu_device *adev); | |||
134 | void amdgpu_amdkfd_gpu_reset(struct kgd_dev *kgd); | 134 | void amdgpu_amdkfd_gpu_reset(struct kgd_dev *kgd); |
135 | 135 | ||
136 | /* Shared API */ | 136 | /* Shared API */ |
137 | int alloc_gtt_mem(struct kgd_dev *kgd, size_t size, | 137 | int amdgpu_amdkfd_alloc_gtt_mem(struct kgd_dev *kgd, size_t size, |
138 | void **mem_obj, uint64_t *gpu_addr, | 138 | void **mem_obj, uint64_t *gpu_addr, |
139 | void **cpu_ptr, bool mqd_gfx9); | 139 | void **cpu_ptr, bool mqd_gfx9); |
140 | void free_gtt_mem(struct kgd_dev *kgd, void *mem_obj); | 140 | void amdgpu_amdkfd_free_gtt_mem(struct kgd_dev *kgd, void *mem_obj); |
141 | void get_local_mem_info(struct kgd_dev *kgd, | 141 | void amdgpu_amdkfd_get_local_mem_info(struct kgd_dev *kgd, |
142 | struct kfd_local_mem_info *mem_info); | 142 | struct kfd_local_mem_info *mem_info); |
143 | uint64_t get_gpu_clock_counter(struct kgd_dev *kgd); | 143 | uint64_t amdgpu_amdkfd_get_gpu_clock_counter(struct kgd_dev *kgd); |
144 | 144 | ||
145 | uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd); | 145 | uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct kgd_dev *kgd); |
146 | void get_cu_info(struct kgd_dev *kgd, struct kfd_cu_info *cu_info); | 146 | void amdgpu_amdkfd_get_cu_info(struct kgd_dev *kgd, struct kfd_cu_info *cu_info); |
147 | uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd); | 147 | uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd); |
148 | uint64_t amdgpu_amdkfd_get_hive_id(struct kgd_dev *kgd); | 148 | uint64_t amdgpu_amdkfd_get_hive_id(struct kgd_dev *kgd); |
149 | 149 | ||
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 244d9834a381..72a357dae070 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | |||
@@ -173,13 +173,6 @@ static int get_tile_config(struct kgd_dev *kgd, | |||
173 | } | 173 | } |
174 | 174 | ||
175 | static const struct kfd2kgd_calls kfd2kgd = { | 175 | static const struct kfd2kgd_calls kfd2kgd = { |
176 | .init_gtt_mem_allocation = alloc_gtt_mem, | ||
177 | .free_gtt_mem = free_gtt_mem, | ||
178 | .get_local_mem_info = get_local_mem_info, | ||
179 | .get_gpu_clock_counter = get_gpu_clock_counter, | ||
180 | .get_max_engine_clock_in_mhz = get_max_engine_clock_in_mhz, | ||
181 | .alloc_pasid = amdgpu_pasid_alloc, | ||
182 | .free_pasid = amdgpu_pasid_free, | ||
183 | .program_sh_mem_settings = kgd_program_sh_mem_settings, | 176 | .program_sh_mem_settings = kgd_program_sh_mem_settings, |
184 | .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping, | 177 | .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping, |
185 | .init_interrupts = kgd_init_interrupts, | 178 | .init_interrupts = kgd_init_interrupts, |
@@ -200,28 +193,10 @@ static const struct kfd2kgd_calls kfd2kgd = { | |||
200 | .get_fw_version = get_fw_version, | 193 | .get_fw_version = get_fw_version, |
201 | .set_scratch_backing_va = set_scratch_backing_va, | 194 | .set_scratch_backing_va = set_scratch_backing_va, |
202 | .get_tile_config = get_tile_config, | 195 | .get_tile_config = get_tile_config, |
203 | .get_cu_info = get_cu_info, | ||
204 | .get_vram_usage = amdgpu_amdkfd_get_vram_usage, | ||
205 | .create_process_vm = amdgpu_amdkfd_gpuvm_create_process_vm, | ||
206 | .acquire_process_vm = amdgpu_amdkfd_gpuvm_acquire_process_vm, | ||
207 | .destroy_process_vm = amdgpu_amdkfd_gpuvm_destroy_process_vm, | ||
208 | .release_process_vm = amdgpu_amdkfd_gpuvm_release_process_vm, | ||
209 | .get_process_page_dir = amdgpu_amdkfd_gpuvm_get_process_page_dir, | ||
210 | .set_vm_context_page_table_base = set_vm_context_page_table_base, | 196 | .set_vm_context_page_table_base = set_vm_context_page_table_base, |
211 | .alloc_memory_of_gpu = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu, | ||
212 | .free_memory_of_gpu = amdgpu_amdkfd_gpuvm_free_memory_of_gpu, | ||
213 | .map_memory_to_gpu = amdgpu_amdkfd_gpuvm_map_memory_to_gpu, | ||
214 | .unmap_memory_to_gpu = amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu, | ||
215 | .sync_memory = amdgpu_amdkfd_gpuvm_sync_memory, | ||
216 | .map_gtt_bo_to_kernel = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel, | ||
217 | .restore_process_bos = amdgpu_amdkfd_gpuvm_restore_process_bos, | ||
218 | .invalidate_tlbs = invalidate_tlbs, | 197 | .invalidate_tlbs = invalidate_tlbs, |
219 | .invalidate_tlbs_vmid = invalidate_tlbs_vmid, | 198 | .invalidate_tlbs_vmid = invalidate_tlbs_vmid, |
220 | .submit_ib = amdgpu_amdkfd_submit_ib, | ||
221 | .get_vm_fault_info = amdgpu_amdkfd_gpuvm_get_vm_fault_info, | ||
222 | .read_vmid_from_vmfault_reg = read_vmid_from_vmfault_reg, | 199 | .read_vmid_from_vmfault_reg = read_vmid_from_vmfault_reg, |
223 | .gpu_recover = amdgpu_amdkfd_gpu_reset, | ||
224 | .set_compute_idle = amdgpu_amdkfd_set_compute_idle | ||
225 | }; | 200 | }; |
226 | 201 | ||
227 | struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void) | 202 | struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void) |
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 9f149914ad6c..0e2a56b6a9b6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | |||
@@ -128,13 +128,6 @@ static int get_tile_config(struct kgd_dev *kgd, | |||
128 | } | 128 | } |
129 | 129 | ||
130 | static const struct kfd2kgd_calls kfd2kgd = { | 130 | static const struct kfd2kgd_calls kfd2kgd = { |
131 | .init_gtt_mem_allocation = alloc_gtt_mem, | ||
132 | .free_gtt_mem = free_gtt_mem, | ||
133 | .get_local_mem_info = get_local_mem_info, | ||
134 | .get_gpu_clock_counter = get_gpu_clock_counter, | ||
135 | .get_max_engine_clock_in_mhz = get_max_engine_clock_in_mhz, | ||
136 | .alloc_pasid = amdgpu_pasid_alloc, | ||
137 | .free_pasid = amdgpu_pasid_free, | ||
138 | .program_sh_mem_settings = kgd_program_sh_mem_settings, | 131 | .program_sh_mem_settings = kgd_program_sh_mem_settings, |
139 | .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping, | 132 | .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping, |
140 | .init_interrupts = kgd_init_interrupts, | 133 | .init_interrupts = kgd_init_interrupts, |
@@ -157,27 +150,9 @@ static const struct kfd2kgd_calls kfd2kgd = { | |||
157 | .get_fw_version = get_fw_version, | 150 | .get_fw_version = get_fw_version, |
158 | .set_scratch_backing_va = set_scratch_backing_va, | 151 | .set_scratch_backing_va = set_scratch_backing_va, |
159 | .get_tile_config = get_tile_config, | 152 | .get_tile_config = get_tile_config, |
160 | .get_cu_info = get_cu_info, | ||
161 | .get_vram_usage = amdgpu_amdkfd_get_vram_usage, | ||
162 | .create_process_vm = amdgpu_amdkfd_gpuvm_create_process_vm, | ||
163 | .acquire_process_vm = amdgpu_amdkfd_gpuvm_acquire_process_vm, | ||
164 | .destroy_process_vm = amdgpu_amdkfd_gpuvm_destroy_process_vm, | ||
165 | .release_process_vm = amdgpu_amdkfd_gpuvm_release_process_vm, | ||
166 | .get_process_page_dir = amdgpu_amdkfd_gpuvm_get_process_page_dir, | ||
167 | .set_vm_context_page_table_base = set_vm_context_page_table_base, | 153 | .set_vm_context_page_table_base = set_vm_context_page_table_base, |
168 | .alloc_memory_of_gpu = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu, | ||
169 | .free_memory_of_gpu = amdgpu_amdkfd_gpuvm_free_memory_of_gpu, | ||
170 | .map_memory_to_gpu = amdgpu_amdkfd_gpuvm_map_memory_to_gpu, | ||
171 | .unmap_memory_to_gpu = amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu, | ||
172 | .sync_memory = amdgpu_amdkfd_gpuvm_sync_memory, | ||
173 | .map_gtt_bo_to_kernel = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel, | ||
174 | .restore_process_bos = amdgpu_amdkfd_gpuvm_restore_process_bos, | ||
175 | .invalidate_tlbs = invalidate_tlbs, | 154 | .invalidate_tlbs = invalidate_tlbs, |
176 | .invalidate_tlbs_vmid = invalidate_tlbs_vmid, | 155 | .invalidate_tlbs_vmid = invalidate_tlbs_vmid, |
177 | .submit_ib = amdgpu_amdkfd_submit_ib, | ||
178 | .get_vm_fault_info = amdgpu_amdkfd_gpuvm_get_vm_fault_info, | ||
179 | .gpu_recover = amdgpu_amdkfd_gpu_reset, | ||
180 | .set_compute_idle = amdgpu_amdkfd_set_compute_idle | ||
181 | }; | 156 | }; |
182 | 157 | ||
183 | struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void) | 158 | struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c index 42cb4c4e0929..03b604c96d94 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c | |||
@@ -46,38 +46,9 @@ | |||
46 | #include "v9_structs.h" | 46 | #include "v9_structs.h" |
47 | #include "soc15.h" | 47 | #include "soc15.h" |
48 | #include "soc15d.h" | 48 | #include "soc15d.h" |
49 | #include "mmhub_v1_0.h" | ||
50 | #include "gfxhub_v1_0.h" | ||
49 | 51 | ||
50 | /* HACK: MMHUB and GC both have VM-related register with the same | ||
51 | * names but different offsets. Define the MMHUB register we need here | ||
52 | * with a prefix. A proper solution would be to move the functions | ||
53 | * programming these registers into gfx_v9_0.c and mmhub_v1_0.c | ||
54 | * respectively. | ||
55 | */ | ||
56 | #define mmMMHUB_VM_INVALIDATE_ENG16_REQ 0x06f3 | ||
57 | #define mmMMHUB_VM_INVALIDATE_ENG16_REQ_BASE_IDX 0 | ||
58 | |||
59 | #define mmMMHUB_VM_INVALIDATE_ENG16_ACK 0x0705 | ||
60 | #define mmMMHUB_VM_INVALIDATE_ENG16_ACK_BASE_IDX 0 | ||
61 | |||
62 | #define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32 0x072b | ||
63 | #define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32_BASE_IDX 0 | ||
64 | #define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32 0x072c | ||
65 | #define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32_BASE_IDX 0 | ||
66 | |||
67 | #define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32 0x074b | ||
68 | #define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32_BASE_IDX 0 | ||
69 | #define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32 0x074c | ||
70 | #define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32_BASE_IDX 0 | ||
71 | |||
72 | #define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32 0x076b | ||
73 | #define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32_BASE_IDX 0 | ||
74 | #define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32 0x076c | ||
75 | #define mmMMHUB_VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32_BASE_IDX 0 | ||
76 | |||
77 | #define mmMMHUB_VM_INVALIDATE_ENG16_ADDR_RANGE_LO32 0x0727 | ||
78 | #define mmMMHUB_VM_INVALIDATE_ENG16_ADDR_RANGE_LO32_BASE_IDX 0 | ||
79 | #define mmMMHUB_VM_INVALIDATE_ENG16_ADDR_RANGE_HI32 0x0728 | ||
80 | #define mmMMHUB_VM_INVALIDATE_ENG16_ADDR_RANGE_HI32_BASE_IDX 0 | ||
81 | 52 | ||
82 | #define V9_PIPE_PER_MEC (4) | 53 | #define V9_PIPE_PER_MEC (4) |
83 | #define V9_QUEUES_PER_PIPE_MEC (8) | 54 | #define V9_QUEUES_PER_PIPE_MEC (8) |
@@ -167,13 +138,6 @@ static int amdgpu_amdkfd_get_tile_config(struct kgd_dev *kgd, | |||
167 | } | 138 | } |
168 | 139 | ||
169 | static const struct kfd2kgd_calls kfd2kgd = { | 140 | static const struct kfd2kgd_calls kfd2kgd = { |
170 | .init_gtt_mem_allocation = alloc_gtt_mem, | ||
171 | .free_gtt_mem = free_gtt_mem, | ||
172 | .get_local_mem_info = get_local_mem_info, | ||
173 | .get_gpu_clock_counter = get_gpu_clock_counter, | ||
174 | .get_max_engine_clock_in_mhz = get_max_engine_clock_in_mhz, | ||
175 | .alloc_pasid = amdgpu_pasid_alloc, | ||
176 | .free_pasid = amdgpu_pasid_free, | ||
177 | .program_sh_mem_settings = kgd_program_sh_mem_settings, | 141 | .program_sh_mem_settings = kgd_program_sh_mem_settings, |
178 | .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping, | 142 | .set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping, |
179 | .init_interrupts = kgd_init_interrupts, | 143 | .init_interrupts = kgd_init_interrupts, |
@@ -196,26 +160,9 @@ static const struct kfd2kgd_calls kfd2kgd = { | |||
196 | .get_fw_version = get_fw_version, | 160 | .get_fw_version = get_fw_version, |
197 | .set_scratch_backing_va = set_scratch_backing_va, | 161 | .set_scratch_backing_va = set_scratch_backing_va, |
198 | .get_tile_config = amdgpu_amdkfd_get_tile_config, | 162 | .get_tile_config = amdgpu_amdkfd_get_tile_config, |
199 | .get_cu_info = get_cu_info, | ||
200 | .get_vram_usage = amdgpu_amdkfd_get_vram_usage, | ||
201 | .create_process_vm = amdgpu_amdkfd_gpuvm_create_process_vm, | ||
202 | .acquire_process_vm = amdgpu_amdkfd_gpuvm_acquire_process_vm, | ||
203 | .destroy_process_vm = amdgpu_amdkfd_gpuvm_destroy_process_vm, | ||
204 | .release_process_vm = amdgpu_amdkfd_gpuvm_release_process_vm, | ||
205 | .get_process_page_dir = amdgpu_amdkfd_gpuvm_get_process_page_dir, | ||
206 | .set_vm_context_page_table_base = set_vm_context_page_table_base, | 163 | .set_vm_context_page_table_base = set_vm_context_page_table_base, |
207 | .alloc_memory_of_gpu = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu, | ||
208 | .free_memory_of_gpu = amdgpu_amdkfd_gpuvm_free_memory_of_gpu, | ||
209 | .map_memory_to_gpu = amdgpu_amdkfd_gpuvm_map_memory_to_gpu, | ||
210 | .unmap_memory_to_gpu = amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu, | ||
211 | .sync_memory = amdgpu_amdkfd_gpuvm_sync_memory, | ||
212 | .map_gtt_bo_to_kernel = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel, | ||
213 | .restore_process_bos = amdgpu_amdkfd_gpuvm_restore_process_bos, | ||
214 | .invalidate_tlbs = invalidate_tlbs, | 164 | .invalidate_tlbs = invalidate_tlbs, |
215 | .invalidate_tlbs_vmid = invalidate_tlbs_vmid, | 165 | .invalidate_tlbs_vmid = invalidate_tlbs_vmid, |
216 | .submit_ib = amdgpu_amdkfd_submit_ib, | ||
217 | .gpu_recover = amdgpu_amdkfd_gpu_reset, | ||
218 | .set_compute_idle = amdgpu_amdkfd_set_compute_idle, | ||
219 | .get_hive_id = amdgpu_amdkfd_get_hive_id, | 166 | .get_hive_id = amdgpu_amdkfd_get_hive_id, |
220 | }; | 167 | }; |
221 | 168 | ||
@@ -785,15 +732,6 @@ static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd, | |||
785 | static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid) | 732 | static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid) |
786 | { | 733 | { |
787 | struct amdgpu_device *adev = (struct amdgpu_device *) kgd; | 734 | struct amdgpu_device *adev = (struct amdgpu_device *) kgd; |
788 | uint32_t req = (1 << vmid) | | ||
789 | (0 << VM_INVALIDATE_ENG16_REQ__FLUSH_TYPE__SHIFT) | /* legacy */ | ||
790 | VM_INVALIDATE_ENG16_REQ__INVALIDATE_L2_PTES_MASK | | ||
791 | VM_INVALIDATE_ENG16_REQ__INVALIDATE_L2_PDE0_MASK | | ||
792 | VM_INVALIDATE_ENG16_REQ__INVALIDATE_L2_PDE1_MASK | | ||
793 | VM_INVALIDATE_ENG16_REQ__INVALIDATE_L2_PDE2_MASK | | ||
794 | VM_INVALIDATE_ENG16_REQ__INVALIDATE_L1_PTES_MASK; | ||
795 | |||
796 | mutex_lock(&adev->srbm_mutex); | ||
797 | 735 | ||
798 | /* Use legacy mode tlb invalidation. | 736 | /* Use legacy mode tlb invalidation. |
799 | * | 737 | * |
@@ -810,34 +748,7 @@ static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid) | |||
810 | * TODO 2: support range-based invalidation, requires kfg2kgd | 748 | * TODO 2: support range-based invalidation, requires kfg2kgd |
811 | * interface change | 749 | * interface change |
812 | */ | 750 | */ |
813 | WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_INVALIDATE_ENG16_ADDR_RANGE_LO32), | 751 | amdgpu_gmc_flush_gpu_tlb(adev, vmid, 0); |
814 | 0xffffffff); | ||
815 | WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_INVALIDATE_ENG16_ADDR_RANGE_HI32), | ||
816 | 0x0000001f); | ||
817 | |||
818 | WREG32(SOC15_REG_OFFSET(MMHUB, 0, | ||
819 | mmMMHUB_VM_INVALIDATE_ENG16_ADDR_RANGE_LO32), | ||
820 | 0xffffffff); | ||
821 | WREG32(SOC15_REG_OFFSET(MMHUB, 0, | ||
822 | mmMMHUB_VM_INVALIDATE_ENG16_ADDR_RANGE_HI32), | ||
823 | 0x0000001f); | ||
824 | |||
825 | WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_INVALIDATE_ENG16_REQ), req); | ||
826 | |||
827 | WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmMMHUB_VM_INVALIDATE_ENG16_REQ), | ||
828 | req); | ||
829 | |||
830 | while (!(RREG32(SOC15_REG_OFFSET(GC, 0, mmVM_INVALIDATE_ENG16_ACK)) & | ||
831 | (1 << vmid))) | ||
832 | cpu_relax(); | ||
833 | |||
834 | while (!(RREG32(SOC15_REG_OFFSET(MMHUB, 0, | ||
835 | mmMMHUB_VM_INVALIDATE_ENG16_ACK)) & | ||
836 | (1 << vmid))) | ||
837 | cpu_relax(); | ||
838 | |||
839 | mutex_unlock(&adev->srbm_mutex); | ||
840 | |||
841 | } | 752 | } |
842 | 753 | ||
843 | static int invalidate_tlbs_with_kiq(struct amdgpu_device *adev, uint16_t pasid) | 754 | static int invalidate_tlbs_with_kiq(struct amdgpu_device *adev, uint16_t pasid) |
@@ -876,7 +787,7 @@ static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid) | |||
876 | if (adev->in_gpu_reset) | 787 | if (adev->in_gpu_reset) |
877 | return -EIO; | 788 | return -EIO; |
878 | 789 | ||
879 | if (ring->ready) | 790 | if (ring->sched.ready) |
880 | return invalidate_tlbs_with_kiq(adev, pasid); | 791 | return invalidate_tlbs_with_kiq(adev, pasid); |
881 | 792 | ||
882 | for (vmid = 0; vmid < 16; vmid++) { | 793 | for (vmid = 0; vmid < 16; vmid++) { |
@@ -1016,7 +927,6 @@ static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid, | |||
1016 | uint64_t page_table_base) | 927 | uint64_t page_table_base) |
1017 | { | 928 | { |
1018 | struct amdgpu_device *adev = get_amdgpu_device(kgd); | 929 | struct amdgpu_device *adev = get_amdgpu_device(kgd); |
1019 | uint64_t base = page_table_base | AMDGPU_PTE_VALID; | ||
1020 | 930 | ||
1021 | if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) { | 931 | if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) { |
1022 | pr_err("trying to set page table base for wrong VMID %u\n", | 932 | pr_err("trying to set page table base for wrong VMID %u\n", |
@@ -1028,25 +938,7 @@ static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid, | |||
1028 | * now, all processes share the same address space size, like | 938 | * now, all processes share the same address space size, like |
1029 | * on GFX8 and older. | 939 | * on GFX8 and older. |
1030 | */ | 940 | */ |
1031 | WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmMMHUB_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32) + (vmid*2), 0); | 941 | mmhub_v1_0_setup_vm_pt_regs(adev, vmid, page_table_base); |
1032 | WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmMMHUB_VM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32) + (vmid*2), 0); | ||
1033 | |||
1034 | WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmMMHUB_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32) + (vmid*2), | ||
1035 | lower_32_bits(adev->vm_manager.max_pfn - 1)); | ||
1036 | WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmMMHUB_VM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32) + (vmid*2), | ||
1037 | upper_32_bits(adev->vm_manager.max_pfn - 1)); | ||
1038 | |||
1039 | WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmMMHUB_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32) + (vmid*2), lower_32_bits(base)); | ||
1040 | WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmMMHUB_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32) + (vmid*2), upper_32_bits(base)); | ||
1041 | |||
1042 | WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32) + (vmid*2), 0); | ||
1043 | WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32) + (vmid*2), 0); | ||
1044 | |||
1045 | WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32) + (vmid*2), | ||
1046 | lower_32_bits(adev->vm_manager.max_pfn - 1)); | ||
1047 | WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32) + (vmid*2), | ||
1048 | upper_32_bits(adev->vm_manager.max_pfn - 1)); | ||
1049 | 942 | ||
1050 | WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32) + (vmid*2), lower_32_bits(base)); | 943 | gfxhub_v1_0_setup_vm_pt_regs(adev, vmid, page_table_base); |
1051 | WREG32(SOC15_REG_OFFSET(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32) + (vmid*2), upper_32_bits(base)); | ||
1052 | } | 944 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 8816c697b205..ceadeeadfa56 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | |||
@@ -330,7 +330,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, | |||
330 | case CHIP_TOPAZ: | 330 | case CHIP_TOPAZ: |
331 | if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) || | 331 | if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) || |
332 | ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) || | 332 | ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) || |
333 | ((adev->pdev->device == 0x6907) && (adev->pdev->revision == 0x87))) { | 333 | ((adev->pdev->device == 0x6907) && (adev->pdev->revision == 0x87)) || |
334 | ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD1)) || | ||
335 | ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD3))) { | ||
334 | info->is_kicker = true; | 336 | info->is_kicker = true; |
335 | strcpy(fw_name, "amdgpu/topaz_k_smc.bin"); | 337 | strcpy(fw_name, "amdgpu/topaz_k_smc.bin"); |
336 | } else | 338 | } else |
@@ -351,7 +353,6 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, | |||
351 | if (type == CGS_UCODE_ID_SMU) { | 353 | if (type == CGS_UCODE_ID_SMU) { |
352 | if (((adev->pdev->device == 0x67ef) && | 354 | if (((adev->pdev->device == 0x67ef) && |
353 | ((adev->pdev->revision == 0xe0) || | 355 | ((adev->pdev->revision == 0xe0) || |
354 | (adev->pdev->revision == 0xe2) || | ||
355 | (adev->pdev->revision == 0xe5))) || | 356 | (adev->pdev->revision == 0xe5))) || |
356 | ((adev->pdev->device == 0x67ff) && | 357 | ((adev->pdev->device == 0x67ff) && |
357 | ((adev->pdev->revision == 0xcf) || | 358 | ((adev->pdev->revision == 0xcf) || |
@@ -359,8 +360,13 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, | |||
359 | (adev->pdev->revision == 0xff)))) { | 360 | (adev->pdev->revision == 0xff)))) { |
360 | info->is_kicker = true; | 361 | info->is_kicker = true; |
361 | strcpy(fw_name, "amdgpu/polaris11_k_smc.bin"); | 362 | strcpy(fw_name, "amdgpu/polaris11_k_smc.bin"); |
362 | } else | 363 | } else if ((adev->pdev->device == 0x67ef) && |
364 | (adev->pdev->revision == 0xe2)) { | ||
365 | info->is_kicker = true; | ||
366 | strcpy(fw_name, "amdgpu/polaris11_k2_smc.bin"); | ||
367 | } else { | ||
363 | strcpy(fw_name, "amdgpu/polaris11_smc.bin"); | 368 | strcpy(fw_name, "amdgpu/polaris11_smc.bin"); |
369 | } | ||
364 | } else if (type == CGS_UCODE_ID_SMU_SK) { | 370 | } else if (type == CGS_UCODE_ID_SMU_SK) { |
365 | strcpy(fw_name, "amdgpu/polaris11_smc_sk.bin"); | 371 | strcpy(fw_name, "amdgpu/polaris11_smc_sk.bin"); |
366 | } | 372 | } |
@@ -378,14 +384,31 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, | |||
378 | (adev->pdev->revision == 0xef))) { | 384 | (adev->pdev->revision == 0xef))) { |
379 | info->is_kicker = true; | 385 | info->is_kicker = true; |
380 | strcpy(fw_name, "amdgpu/polaris10_k_smc.bin"); | 386 | strcpy(fw_name, "amdgpu/polaris10_k_smc.bin"); |
381 | } else | 387 | } else if ((adev->pdev->device == 0x67df) && |
388 | ((adev->pdev->revision == 0xe1) || | ||
389 | (adev->pdev->revision == 0xf7))) { | ||
390 | info->is_kicker = true; | ||
391 | strcpy(fw_name, "amdgpu/polaris10_k2_smc.bin"); | ||
392 | } else { | ||
382 | strcpy(fw_name, "amdgpu/polaris10_smc.bin"); | 393 | strcpy(fw_name, "amdgpu/polaris10_smc.bin"); |
394 | } | ||
383 | } else if (type == CGS_UCODE_ID_SMU_SK) { | 395 | } else if (type == CGS_UCODE_ID_SMU_SK) { |
384 | strcpy(fw_name, "amdgpu/polaris10_smc_sk.bin"); | 396 | strcpy(fw_name, "amdgpu/polaris10_smc_sk.bin"); |
385 | } | 397 | } |
386 | break; | 398 | break; |
387 | case CHIP_POLARIS12: | 399 | case CHIP_POLARIS12: |
388 | strcpy(fw_name, "amdgpu/polaris12_smc.bin"); | 400 | if (((adev->pdev->device == 0x6987) && |
401 | ((adev->pdev->revision == 0xc0) || | ||
402 | (adev->pdev->revision == 0xc3))) || | ||
403 | ((adev->pdev->device == 0x6981) && | ||
404 | ((adev->pdev->revision == 0x00) || | ||
405 | (adev->pdev->revision == 0x01) || | ||
406 | (adev->pdev->revision == 0x10)))) { | ||
407 | info->is_kicker = true; | ||
408 | strcpy(fw_name, "amdgpu/polaris12_k_smc.bin"); | ||
409 | } else { | ||
410 | strcpy(fw_name, "amdgpu/polaris12_smc.bin"); | ||
411 | } | ||
389 | break; | 412 | break; |
390 | case CHIP_VEGAM: | 413 | case CHIP_VEGAM: |
391 | strcpy(fw_name, "amdgpu/vegam_smc.bin"); | 414 | strcpy(fw_name, "amdgpu/vegam_smc.bin"); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 35bc8fc3bc70..024dfbd87f11 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -1260,8 +1260,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, | |||
1260 | return 0; | 1260 | return 0; |
1261 | 1261 | ||
1262 | error_abort: | 1262 | error_abort: |
1263 | dma_fence_put(&job->base.s_fence->finished); | 1263 | drm_sched_job_cleanup(&job->base); |
1264 | job->base.s_fence = NULL; | ||
1265 | amdgpu_mn_unlock(p->mn); | 1264 | amdgpu_mn_unlock(p->mn); |
1266 | 1265 | ||
1267 | error_unlock: | 1266 | error_unlock: |
@@ -1285,7 +1284,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
1285 | 1284 | ||
1286 | r = amdgpu_cs_parser_init(&parser, data); | 1285 | r = amdgpu_cs_parser_init(&parser, data); |
1287 | if (r) { | 1286 | if (r) { |
1288 | DRM_ERROR("Failed to initialize parser !\n"); | 1287 | DRM_ERROR("Failed to initialize parser %d!\n", r); |
1289 | goto out; | 1288 | goto out; |
1290 | } | 1289 | } |
1291 | 1290 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c new file mode 100644 index 000000000000..0c590ddf250a --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | |||
@@ -0,0 +1,117 @@ | |||
1 | /* | ||
2 | * Copyright 2016 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 | * * Author: Monk.liu@amd.com | ||
23 | */ | ||
24 | |||
25 | #include "amdgpu.h" | ||
26 | |||
27 | uint64_t amdgpu_csa_vaddr(struct amdgpu_device *adev) | ||
28 | { | ||
29 | uint64_t addr = adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT; | ||
30 | |||
31 | addr -= AMDGPU_VA_RESERVED_SIZE; | ||
32 | addr = amdgpu_gmc_sign_extend(addr); | ||
33 | |||
34 | return addr; | ||
35 | } | ||
36 | |||
37 | int amdgpu_allocate_static_csa(struct amdgpu_device *adev, struct amdgpu_bo **bo, | ||
38 | u32 domain, uint32_t size) | ||
39 | { | ||
40 | int r; | ||
41 | void *ptr; | ||
42 | |||
43 | r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE, | ||
44 | domain, bo, | ||
45 | NULL, &ptr); | ||
46 | if (!bo) | ||
47 | return -ENOMEM; | ||
48 | |||
49 | memset(ptr, 0, size); | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | void amdgpu_free_static_csa(struct amdgpu_bo **bo) | ||
54 | { | ||
55 | amdgpu_bo_free_kernel(bo, NULL, NULL); | ||
56 | } | ||
57 | |||
58 | /* | ||
59 | * amdgpu_map_static_csa should be called during amdgpu_vm_init | ||
60 | * it maps virtual address amdgpu_csa_vaddr() to this VM, and each command | ||
61 | * submission of GFX should use this virtual address within META_DATA init | ||
62 | * package to support SRIOV gfx preemption. | ||
63 | */ | ||
64 | int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, | ||
65 | struct amdgpu_bo *bo, struct amdgpu_bo_va **bo_va, | ||
66 | uint64_t csa_addr, uint32_t size) | ||
67 | { | ||
68 | struct ww_acquire_ctx ticket; | ||
69 | struct list_head list; | ||
70 | struct amdgpu_bo_list_entry pd; | ||
71 | struct ttm_validate_buffer csa_tv; | ||
72 | int r; | ||
73 | |||
74 | INIT_LIST_HEAD(&list); | ||
75 | INIT_LIST_HEAD(&csa_tv.head); | ||
76 | csa_tv.bo = &bo->tbo; | ||
77 | csa_tv.shared = true; | ||
78 | |||
79 | list_add(&csa_tv.head, &list); | ||
80 | amdgpu_vm_get_pd_bo(vm, &list, &pd); | ||
81 | |||
82 | r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL); | ||
83 | if (r) { | ||
84 | DRM_ERROR("failed to reserve CSA,PD BOs: err=%d\n", r); | ||
85 | return r; | ||
86 | } | ||
87 | |||
88 | *bo_va = amdgpu_vm_bo_add(adev, vm, bo); | ||
89 | if (!*bo_va) { | ||
90 | ttm_eu_backoff_reservation(&ticket, &list); | ||
91 | DRM_ERROR("failed to create bo_va for static CSA\n"); | ||
92 | return -ENOMEM; | ||
93 | } | ||
94 | |||
95 | r = amdgpu_vm_alloc_pts(adev, (*bo_va)->base.vm, csa_addr, | ||
96 | size); | ||
97 | if (r) { | ||
98 | DRM_ERROR("failed to allocate pts for static CSA, err=%d\n", r); | ||
99 | amdgpu_vm_bo_rmv(adev, *bo_va); | ||
100 | ttm_eu_backoff_reservation(&ticket, &list); | ||
101 | return r; | ||
102 | } | ||
103 | |||
104 | r = amdgpu_vm_bo_map(adev, *bo_va, csa_addr, 0, size, | ||
105 | AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE | | ||
106 | AMDGPU_PTE_EXECUTABLE); | ||
107 | |||
108 | if (r) { | ||
109 | DRM_ERROR("failed to do bo_map on static CSA, err=%d\n", r); | ||
110 | amdgpu_vm_bo_rmv(adev, *bo_va); | ||
111 | ttm_eu_backoff_reservation(&ticket, &list); | ||
112 | return r; | ||
113 | } | ||
114 | |||
115 | ttm_eu_backoff_reservation(&ticket, &list); | ||
116 | return 0; | ||
117 | } | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.h new file mode 100644 index 000000000000..524b4437a021 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * Copyright 2016 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 | * Author: Monk.liu@amd.com | ||
23 | */ | ||
24 | |||
25 | #ifndef AMDGPU_CSA_MANAGER_H | ||
26 | #define AMDGPU_CSA_MANAGER_H | ||
27 | |||
28 | #define AMDGPU_CSA_SIZE (128 * 1024) | ||
29 | |||
30 | uint32_t amdgpu_get_total_csa_size(struct amdgpu_device *adev); | ||
31 | uint64_t amdgpu_csa_vaddr(struct amdgpu_device *adev); | ||
32 | int amdgpu_allocate_static_csa(struct amdgpu_device *adev, struct amdgpu_bo **bo, | ||
33 | u32 domain, uint32_t size); | ||
34 | int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, | ||
35 | struct amdgpu_bo *bo, struct amdgpu_bo_va **bo_va, | ||
36 | uint64_t csa_addr, uint32_t size); | ||
37 | void amdgpu_free_static_csa(struct amdgpu_bo **bo); | ||
38 | |||
39 | #endif | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 30bc345d6fdf..590588a82471 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -1656,7 +1656,9 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) | |||
1656 | 1656 | ||
1657 | /* right after GMC hw init, we create CSA */ | 1657 | /* right after GMC hw init, we create CSA */ |
1658 | if (amdgpu_sriov_vf(adev)) { | 1658 | if (amdgpu_sriov_vf(adev)) { |
1659 | r = amdgpu_allocate_static_csa(adev); | 1659 | r = amdgpu_allocate_static_csa(adev, &adev->virt.csa_obj, |
1660 | AMDGPU_GEM_DOMAIN_VRAM, | ||
1661 | AMDGPU_CSA_SIZE); | ||
1660 | if (r) { | 1662 | if (r) { |
1661 | DRM_ERROR("allocate CSA failed %d\n", r); | 1663 | DRM_ERROR("allocate CSA failed %d\n", r); |
1662 | return r; | 1664 | return r; |
@@ -1681,7 +1683,8 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) | |||
1681 | if (r) | 1683 | if (r) |
1682 | return r; | 1684 | return r; |
1683 | 1685 | ||
1684 | amdgpu_xgmi_add_device(adev); | 1686 | if (adev->gmc.xgmi.num_physical_nodes > 1) |
1687 | amdgpu_xgmi_add_device(adev); | ||
1685 | amdgpu_amdkfd_device_init(adev); | 1688 | amdgpu_amdkfd_device_init(adev); |
1686 | 1689 | ||
1687 | if (amdgpu_sriov_vf(adev)) | 1690 | if (amdgpu_sriov_vf(adev)) |
@@ -1890,7 +1893,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) | |||
1890 | 1893 | ||
1891 | if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) { | 1894 | if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) { |
1892 | amdgpu_ucode_free_bo(adev); | 1895 | amdgpu_ucode_free_bo(adev); |
1893 | amdgpu_free_static_csa(adev); | 1896 | amdgpu_free_static_csa(&adev->virt.csa_obj); |
1894 | amdgpu_device_wb_fini(adev); | 1897 | amdgpu_device_wb_fini(adev); |
1895 | amdgpu_device_vram_scratch_fini(adev); | 1898 | amdgpu_device_vram_scratch_fini(adev); |
1896 | } | 1899 | } |
@@ -3295,13 +3298,35 @@ bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev) | |||
3295 | return false; | 3298 | return false; |
3296 | } | 3299 | } |
3297 | 3300 | ||
3298 | if (amdgpu_gpu_recovery == 0 || (amdgpu_gpu_recovery == -1 && | 3301 | if (amdgpu_gpu_recovery == 0) |
3299 | !amdgpu_sriov_vf(adev))) { | 3302 | goto disabled; |
3300 | DRM_INFO("GPU recovery disabled.\n"); | 3303 | |
3301 | return false; | 3304 | if (amdgpu_sriov_vf(adev)) |
3305 | return true; | ||
3306 | |||
3307 | if (amdgpu_gpu_recovery == -1) { | ||
3308 | switch (adev->asic_type) { | ||
3309 | case CHIP_TOPAZ: | ||
3310 | case CHIP_TONGA: | ||
3311 | case CHIP_FIJI: | ||
3312 | case CHIP_POLARIS10: | ||
3313 | case CHIP_POLARIS11: | ||
3314 | case CHIP_POLARIS12: | ||
3315 | case CHIP_VEGAM: | ||
3316 | case CHIP_VEGA20: | ||
3317 | case CHIP_VEGA10: | ||
3318 | case CHIP_VEGA12: | ||
3319 | break; | ||
3320 | default: | ||
3321 | goto disabled; | ||
3322 | } | ||
3302 | } | 3323 | } |
3303 | 3324 | ||
3304 | return true; | 3325 | return true; |
3326 | |||
3327 | disabled: | ||
3328 | DRM_INFO("GPU recovery disabled.\n"); | ||
3329 | return false; | ||
3305 | } | 3330 | } |
3306 | 3331 | ||
3307 | /** | 3332 | /** |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 943dbf3c5da1..8de55f7f1a3a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | |||
@@ -127,6 +127,9 @@ int amdgpu_compute_multipipe = -1; | |||
127 | int amdgpu_gpu_recovery = -1; /* auto */ | 127 | int amdgpu_gpu_recovery = -1; /* auto */ |
128 | int amdgpu_emu_mode = 0; | 128 | int amdgpu_emu_mode = 0; |
129 | uint amdgpu_smu_memory_pool_size = 0; | 129 | uint amdgpu_smu_memory_pool_size = 0; |
130 | /* FBC (bit 0) disabled by default*/ | ||
131 | uint amdgpu_dc_feature_mask = 0; | ||
132 | |||
130 | struct amdgpu_mgpu_info mgpu_info = { | 133 | struct amdgpu_mgpu_info mgpu_info = { |
131 | .mutex = __MUTEX_INITIALIZER(mgpu_info.mutex), | 134 | .mutex = __MUTEX_INITIALIZER(mgpu_info.mutex), |
132 | }; | 135 | }; |
@@ -631,6 +634,14 @@ module_param(halt_if_hws_hang, int, 0644); | |||
631 | MODULE_PARM_DESC(halt_if_hws_hang, "Halt if HWS hang is detected (0 = off (default), 1 = on)"); | 634 | MODULE_PARM_DESC(halt_if_hws_hang, "Halt if HWS hang is detected (0 = off (default), 1 = on)"); |
632 | #endif | 635 | #endif |
633 | 636 | ||
637 | /** | ||
638 | * DOC: dcfeaturemask (uint) | ||
639 | * Override display features enabled. See enum DC_FEATURE_MASK in drivers/gpu/drm/amd/include/amd_shared.h. | ||
640 | * The default is the current set of stable display features. | ||
641 | */ | ||
642 | MODULE_PARM_DESC(dcfeaturemask, "all stable DC features enabled (default))"); | ||
643 | module_param_named(dcfeaturemask, amdgpu_dc_feature_mask, uint, 0444); | ||
644 | |||
634 | static const struct pci_device_id pciidlist[] = { | 645 | static const struct pci_device_id pciidlist[] = { |
635 | #ifdef CONFIG_DRM_AMDGPU_SI | 646 | #ifdef CONFIG_DRM_AMDGPU_SI |
636 | {0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI}, | 647 | {0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI}, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 5448cf27654e..ee47c11e92ce 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | |||
@@ -398,9 +398,9 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring, | |||
398 | ring->fence_drv.irq_type = irq_type; | 398 | ring->fence_drv.irq_type = irq_type; |
399 | ring->fence_drv.initialized = true; | 399 | ring->fence_drv.initialized = true; |
400 | 400 | ||
401 | dev_dbg(adev->dev, "fence driver on ring %d use gpu addr 0x%016llx, " | 401 | DRM_DEV_DEBUG(adev->dev, "fence driver on ring %s use gpu addr " |
402 | "cpu addr 0x%p\n", ring->idx, | 402 | "0x%016llx, cpu addr 0x%p\n", ring->name, |
403 | ring->fence_drv.gpu_addr, ring->fence_drv.cpu_addr); | 403 | ring->fence_drv.gpu_addr, ring->fence_drv.cpu_addr); |
404 | return 0; | 404 | return 0; |
405 | } | 405 | } |
406 | 406 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index 11fea28f8ad3..6d11e1721147 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | |||
@@ -248,7 +248,7 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset, | |||
248 | } | 248 | } |
249 | mb(); | 249 | mb(); |
250 | amdgpu_asic_flush_hdp(adev, NULL); | 250 | amdgpu_asic_flush_hdp(adev, NULL); |
251 | amdgpu_gmc_flush_gpu_tlb(adev, 0); | 251 | amdgpu_gmc_flush_gpu_tlb(adev, 0, 0); |
252 | return 0; | 252 | return 0; |
253 | } | 253 | } |
254 | 254 | ||
@@ -259,6 +259,8 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset, | |||
259 | * @offset: offset into the GPU's gart aperture | 259 | * @offset: offset into the GPU's gart aperture |
260 | * @pages: number of pages to bind | 260 | * @pages: number of pages to bind |
261 | * @dma_addr: DMA addresses of pages | 261 | * @dma_addr: DMA addresses of pages |
262 | * @flags: page table entry flags | ||
263 | * @dst: CPU address of the gart table | ||
262 | * | 264 | * |
263 | * Map the dma_addresses into GART entries (all asics). | 265 | * Map the dma_addresses into GART entries (all asics). |
264 | * Returns 0 for success, -EINVAL for failure. | 266 | * Returns 0 for success, -EINVAL for failure. |
@@ -331,7 +333,7 @@ int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset, | |||
331 | 333 | ||
332 | mb(); | 334 | mb(); |
333 | amdgpu_asic_flush_hdp(adev, NULL); | 335 | amdgpu_asic_flush_hdp(adev, NULL); |
334 | amdgpu_gmc_flush_gpu_tlb(adev, 0); | 336 | amdgpu_gmc_flush_gpu_tlb(adev, 0, 0); |
335 | return 0; | 337 | return 0; |
336 | } | 338 | } |
337 | 339 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h index 9ff62887e4e3..afa2e2877d87 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h | |||
@@ -41,6 +41,7 @@ struct amdgpu_bo; | |||
41 | 41 | ||
42 | struct amdgpu_gart { | 42 | struct amdgpu_gart { |
43 | struct amdgpu_bo *bo; | 43 | struct amdgpu_bo *bo; |
44 | /* CPU kmapped address of gart table */ | ||
44 | void *ptr; | 45 | void *ptr; |
45 | unsigned num_gpu_pages; | 46 | unsigned num_gpu_pages; |
46 | unsigned num_cpu_pages; | 47 | unsigned num_cpu_pages; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index 1a656b8657f7..6a70c0b7105f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <drm/drmP.h> | 25 | #include <drm/drmP.h> |
26 | #include "amdgpu.h" | 26 | #include "amdgpu.h" |
27 | #include "amdgpu_gfx.h" | 27 | #include "amdgpu_gfx.h" |
28 | #include "amdgpu_rlc.h" | ||
28 | 29 | ||
29 | /* delay 0.1 second to enable gfx off feature */ | 30 | /* delay 0.1 second to enable gfx off feature */ |
30 | #define GFX_OFF_DELAY_ENABLE msecs_to_jiffies(100) | 31 | #define GFX_OFF_DELAY_ENABLE msecs_to_jiffies(100) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h index b61b5c11aead..f790e15bcd08 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h | |||
@@ -29,6 +29,7 @@ | |||
29 | */ | 29 | */ |
30 | #include "clearstate_defs.h" | 30 | #include "clearstate_defs.h" |
31 | #include "amdgpu_ring.h" | 31 | #include "amdgpu_ring.h" |
32 | #include "amdgpu_rlc.h" | ||
32 | 33 | ||
33 | /* GFX current status */ | 34 | /* GFX current status */ |
34 | #define AMDGPU_GFX_NORMAL_MODE 0x00000000L | 35 | #define AMDGPU_GFX_NORMAL_MODE 0x00000000L |
@@ -37,59 +38,6 @@ | |||
37 | #define AMDGPU_GFX_CG_DISABLED_MODE 0x00000004L | 38 | #define AMDGPU_GFX_CG_DISABLED_MODE 0x00000004L |
38 | #define AMDGPU_GFX_LBPW_DISABLED_MODE 0x00000008L | 39 | #define AMDGPU_GFX_LBPW_DISABLED_MODE 0x00000008L |
39 | 40 | ||
40 | |||
41 | struct amdgpu_rlc_funcs { | ||
42 | void (*enter_safe_mode)(struct amdgpu_device *adev); | ||
43 | void (*exit_safe_mode)(struct amdgpu_device *adev); | ||
44 | }; | ||
45 | |||
46 | struct amdgpu_rlc { | ||
47 | /* for power gating */ | ||
48 | struct amdgpu_bo *save_restore_obj; | ||
49 | uint64_t save_restore_gpu_addr; | ||
50 | volatile uint32_t *sr_ptr; | ||
51 | const u32 *reg_list; | ||
52 | u32 reg_list_size; | ||
53 | /* for clear state */ | ||
54 | struct amdgpu_bo *clear_state_obj; | ||
55 | uint64_t clear_state_gpu_addr; | ||
56 | volatile uint32_t *cs_ptr; | ||
57 | const struct cs_section_def *cs_data; | ||
58 | u32 clear_state_size; | ||
59 | /* for cp tables */ | ||
60 | struct amdgpu_bo *cp_table_obj; | ||
61 | uint64_t cp_table_gpu_addr; | ||
62 | volatile uint32_t *cp_table_ptr; | ||
63 | u32 cp_table_size; | ||
64 | |||
65 | /* safe mode for updating CG/PG state */ | ||
66 | bool in_safe_mode; | ||
67 | const struct amdgpu_rlc_funcs *funcs; | ||
68 | |||
69 | /* for firmware data */ | ||
70 | u32 save_and_restore_offset; | ||
71 | u32 clear_state_descriptor_offset; | ||
72 | u32 avail_scratch_ram_locations; | ||
73 | u32 reg_restore_list_size; | ||
74 | u32 reg_list_format_start; | ||
75 | u32 reg_list_format_separate_start; | ||
76 | u32 starting_offsets_start; | ||
77 | u32 reg_list_format_size_bytes; | ||
78 | u32 reg_list_size_bytes; | ||
79 | u32 reg_list_format_direct_reg_list_length; | ||
80 | u32 save_restore_list_cntl_size_bytes; | ||
81 | u32 save_restore_list_gpm_size_bytes; | ||
82 | u32 save_restore_list_srm_size_bytes; | ||
83 | |||
84 | u32 *register_list_format; | ||
85 | u32 *register_restore; | ||
86 | u8 *save_restore_list_cntl; | ||
87 | u8 *save_restore_list_gpm; | ||
88 | u8 *save_restore_list_srm; | ||
89 | |||
90 | bool is_rlc_v2_1; | ||
91 | }; | ||
92 | |||
93 | #define AMDGPU_MAX_COMPUTE_QUEUES KGD_MAX_QUEUES | 41 | #define AMDGPU_MAX_COMPUTE_QUEUES KGD_MAX_QUEUES |
94 | 42 | ||
95 | struct amdgpu_mec { | 43 | struct amdgpu_mec { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h index 6fa7ef446e46..8c57924c075f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h | |||
@@ -64,7 +64,7 @@ struct amdgpu_vmhub { | |||
64 | struct amdgpu_gmc_funcs { | 64 | struct amdgpu_gmc_funcs { |
65 | /* flush the vm tlb via mmio */ | 65 | /* flush the vm tlb via mmio */ |
66 | void (*flush_gpu_tlb)(struct amdgpu_device *adev, | 66 | void (*flush_gpu_tlb)(struct amdgpu_device *adev, |
67 | uint32_t vmid); | 67 | uint32_t vmid, uint32_t flush_type); |
68 | /* flush the vm tlb via ring */ | 68 | /* flush the vm tlb via ring */ |
69 | uint64_t (*emit_flush_gpu_tlb)(struct amdgpu_ring *ring, unsigned vmid, | 69 | uint64_t (*emit_flush_gpu_tlb)(struct amdgpu_ring *ring, unsigned vmid, |
70 | uint64_t pd_addr); | 70 | uint64_t pd_addr); |
@@ -89,7 +89,7 @@ struct amdgpu_gmc_funcs { | |||
89 | 89 | ||
90 | struct amdgpu_xgmi { | 90 | struct amdgpu_xgmi { |
91 | /* from psp */ | 91 | /* from psp */ |
92 | u64 device_id; | 92 | u64 node_id; |
93 | u64 hive_id; | 93 | u64 hive_id; |
94 | /* fixed per family */ | 94 | /* fixed per family */ |
95 | u64 node_segment_size; | 95 | u64 node_segment_size; |
@@ -151,7 +151,7 @@ struct amdgpu_gmc { | |||
151 | struct amdgpu_xgmi xgmi; | 151 | struct amdgpu_xgmi xgmi; |
152 | }; | 152 | }; |
153 | 153 | ||
154 | #define amdgpu_gmc_flush_gpu_tlb(adev, vmid) (adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid)) | 154 | #define amdgpu_gmc_flush_gpu_tlb(adev, vmid, type) (adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid), (type)) |
155 | #define amdgpu_gmc_emit_flush_gpu_tlb(r, vmid, addr) (r)->adev->gmc.gmc_funcs->emit_flush_gpu_tlb((r), (vmid), (addr)) | 155 | #define amdgpu_gmc_emit_flush_gpu_tlb(r, vmid, addr) (r)->adev->gmc.gmc_funcs->emit_flush_gpu_tlb((r), (vmid), (addr)) |
156 | #define amdgpu_gmc_emit_pasid_mapping(r, vmid, pasid) (r)->adev->gmc.gmc_funcs->emit_pasid_mapping((r), (vmid), (pasid)) | 156 | #define amdgpu_gmc_emit_pasid_mapping(r, vmid, pasid) (r)->adev->gmc.gmc_funcs->emit_pasid_mapping((r), (vmid), (pasid)) |
157 | #define amdgpu_gmc_set_pte_pde(adev, pt, idx, addr, flags) (adev)->gmc.gmc_funcs->set_pte_pde((adev), (pt), (idx), (addr), (flags)) | 157 | #define amdgpu_gmc_set_pte_pde(adev, pt, idx, addr, flags) (adev)->gmc.gmc_funcs->set_pte_pde((adev), (pt), (idx), (addr), (flags)) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index b8963b725dfa..c48207b377bc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | |||
@@ -146,7 +146,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
146 | fence_ctx = 0; | 146 | fence_ctx = 0; |
147 | } | 147 | } |
148 | 148 | ||
149 | if (!ring->ready) { | 149 | if (!ring->sched.ready) { |
150 | dev_err(adev->dev, "couldn't schedule ib on ring <%s>\n", ring->name); | 150 | dev_err(adev->dev, "couldn't schedule ib on ring <%s>\n", ring->name); |
151 | return -EINVAL; | 151 | return -EINVAL; |
152 | } | 152 | } |
@@ -221,8 +221,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
221 | !amdgpu_sriov_vf(adev)) /* for SRIOV preemption, Preamble CE ib must be inserted anyway */ | 221 | !amdgpu_sriov_vf(adev)) /* for SRIOV preemption, Preamble CE ib must be inserted anyway */ |
222 | continue; | 222 | continue; |
223 | 223 | ||
224 | amdgpu_ring_emit_ib(ring, ib, job ? job->vmid : 0, | 224 | amdgpu_ring_emit_ib(ring, job, ib, need_ctx_switch); |
225 | need_ctx_switch); | ||
226 | need_ctx_switch = false; | 225 | need_ctx_switch = false; |
227 | } | 226 | } |
228 | 227 | ||
@@ -347,19 +346,14 @@ int amdgpu_ib_ring_tests(struct amdgpu_device *adev) | |||
347 | tmo_gfx = 8 * AMDGPU_IB_TEST_TIMEOUT; | 346 | tmo_gfx = 8 * AMDGPU_IB_TEST_TIMEOUT; |
348 | } | 347 | } |
349 | 348 | ||
350 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 349 | for (i = 0; i < adev->num_rings; ++i) { |
351 | struct amdgpu_ring *ring = adev->rings[i]; | 350 | struct amdgpu_ring *ring = adev->rings[i]; |
352 | long tmo; | 351 | long tmo; |
353 | 352 | ||
354 | if (!ring || !ring->ready) | 353 | /* KIQ rings don't have an IB test because we never submit IBs |
355 | continue; | 354 | * to them and they have no interrupt support. |
356 | |||
357 | /* skip IB tests for KIQ in general for the below reasons: | ||
358 | * 1. We never submit IBs to the KIQ | ||
359 | * 2. KIQ doesn't use the EOP interrupts, | ||
360 | * we use some other CP interrupt. | ||
361 | */ | 355 | */ |
362 | if (ring->funcs->type == AMDGPU_RING_TYPE_KIQ) | 356 | if (!ring->sched.ready || !ring->funcs->test_ib) |
363 | continue; | 357 | continue; |
364 | 358 | ||
365 | /* MM engine need more time */ | 359 | /* MM engine need more time */ |
@@ -374,20 +368,23 @@ int amdgpu_ib_ring_tests(struct amdgpu_device *adev) | |||
374 | tmo = tmo_gfx; | 368 | tmo = tmo_gfx; |
375 | 369 | ||
376 | r = amdgpu_ring_test_ib(ring, tmo); | 370 | r = amdgpu_ring_test_ib(ring, tmo); |
377 | if (r) { | 371 | if (!r) { |
378 | ring->ready = false; | 372 | DRM_DEV_DEBUG(adev->dev, "ib test on %s succeeded\n", |
379 | 373 | ring->name); | |
380 | if (ring == &adev->gfx.gfx_ring[0]) { | 374 | continue; |
381 | /* oh, oh, that's really bad */ | 375 | } |
382 | DRM_ERROR("amdgpu: failed testing IB on GFX ring (%d).\n", r); | 376 | |
383 | adev->accel_working = false; | 377 | ring->sched.ready = false; |
384 | return r; | 378 | DRM_DEV_ERROR(adev->dev, "IB test failed on %s (%d).\n", |
385 | 379 | ring->name, r); | |
386 | } else { | 380 | |
387 | /* still not good, but we can live with it */ | 381 | if (ring == &adev->gfx.gfx_ring[0]) { |
388 | DRM_ERROR("amdgpu: failed testing IB on ring %d (%d).\n", i, r); | 382 | /* oh, oh, that's really bad */ |
389 | ret = r; | 383 | adev->accel_working = false; |
390 | } | 384 | return r; |
385 | |||
386 | } else { | ||
387 | ret = r; | ||
391 | } | 388 | } |
392 | } | 389 | } |
393 | return ret; | 390 | return ret; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 52c17f6219a7..6b6524f04ce0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | |||
@@ -94,23 +94,6 @@ static void amdgpu_hotplug_work_func(struct work_struct *work) | |||
94 | } | 94 | } |
95 | 95 | ||
96 | /** | 96 | /** |
97 | * amdgpu_irq_reset_work_func - execute GPU reset | ||
98 | * | ||
99 | * @work: work struct pointer | ||
100 | * | ||
101 | * Execute scheduled GPU reset (Cayman+). | ||
102 | * This function is called when the IRQ handler thinks we need a GPU reset. | ||
103 | */ | ||
104 | static void amdgpu_irq_reset_work_func(struct work_struct *work) | ||
105 | { | ||
106 | struct amdgpu_device *adev = container_of(work, struct amdgpu_device, | ||
107 | reset_work); | ||
108 | |||
109 | if (!amdgpu_sriov_vf(adev) && amdgpu_device_should_recover_gpu(adev)) | ||
110 | amdgpu_device_gpu_recover(adev, NULL); | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * amdgpu_irq_disable_all - disable *all* interrupts | 97 | * amdgpu_irq_disable_all - disable *all* interrupts |
115 | * | 98 | * |
116 | * @adev: amdgpu device pointer | 99 | * @adev: amdgpu device pointer |
@@ -262,15 +245,12 @@ int amdgpu_irq_init(struct amdgpu_device *adev) | |||
262 | amdgpu_hotplug_work_func); | 245 | amdgpu_hotplug_work_func); |
263 | } | 246 | } |
264 | 247 | ||
265 | INIT_WORK(&adev->reset_work, amdgpu_irq_reset_work_func); | ||
266 | |||
267 | adev->irq.installed = true; | 248 | adev->irq.installed = true; |
268 | r = drm_irq_install(adev->ddev, adev->ddev->pdev->irq); | 249 | r = drm_irq_install(adev->ddev, adev->ddev->pdev->irq); |
269 | if (r) { | 250 | if (r) { |
270 | adev->irq.installed = false; | 251 | adev->irq.installed = false; |
271 | if (!amdgpu_device_has_dc_support(adev)) | 252 | if (!amdgpu_device_has_dc_support(adev)) |
272 | flush_work(&adev->hotplug_work); | 253 | flush_work(&adev->hotplug_work); |
273 | cancel_work_sync(&adev->reset_work); | ||
274 | return r; | 254 | return r; |
275 | } | 255 | } |
276 | adev->ddev->max_vblank_count = 0x00ffffff; | 256 | adev->ddev->max_vblank_count = 0x00ffffff; |
@@ -299,7 +279,6 @@ void amdgpu_irq_fini(struct amdgpu_device *adev) | |||
299 | pci_disable_msi(adev->pdev); | 279 | pci_disable_msi(adev->pdev); |
300 | if (!amdgpu_device_has_dc_support(adev)) | 280 | if (!amdgpu_device_has_dc_support(adev)) |
301 | flush_work(&adev->hotplug_work); | 281 | flush_work(&adev->hotplug_work); |
302 | cancel_work_sync(&adev->reset_work); | ||
303 | } | 282 | } |
304 | 283 | ||
305 | for (i = 0; i < AMDGPU_IRQ_CLIENTID_MAX; ++i) { | 284 | for (i = 0; i < AMDGPU_IRQ_CLIENTID_MAX; ++i) { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 755f733bf0d9..e0af44fd6a0c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | |||
@@ -112,6 +112,8 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job) | |||
112 | struct amdgpu_ring *ring = to_amdgpu_ring(s_job->sched); | 112 | struct amdgpu_ring *ring = to_amdgpu_ring(s_job->sched); |
113 | struct amdgpu_job *job = to_amdgpu_job(s_job); | 113 | struct amdgpu_job *job = to_amdgpu_job(s_job); |
114 | 114 | ||
115 | drm_sched_job_cleanup(s_job); | ||
116 | |||
115 | amdgpu_ring_priority_put(ring, s_job->s_priority); | 117 | amdgpu_ring_priority_put(ring, s_job->s_priority); |
116 | dma_fence_put(job->fence); | 118 | dma_fence_put(job->fence); |
117 | amdgpu_sync_free(&job->sync); | 119 | amdgpu_sync_free(&job->sync); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h index 57cfe78a262b..e1b46a6703de 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h | |||
@@ -33,6 +33,8 @@ | |||
33 | #define to_amdgpu_job(sched_job) \ | 33 | #define to_amdgpu_job(sched_job) \ |
34 | container_of((sched_job), struct amdgpu_job, base) | 34 | container_of((sched_job), struct amdgpu_job, base) |
35 | 35 | ||
36 | #define AMDGPU_JOB_GET_VMID(job) ((job) ? (job)->vmid : 0) | ||
37 | |||
36 | struct amdgpu_fence; | 38 | struct amdgpu_fence; |
37 | 39 | ||
38 | struct amdgpu_job { | 40 | struct amdgpu_job { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 81732a84c2ab..9b3164c0f861 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |||
@@ -336,7 +336,7 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, | |||
336 | case AMDGPU_HW_IP_GFX: | 336 | case AMDGPU_HW_IP_GFX: |
337 | type = AMD_IP_BLOCK_TYPE_GFX; | 337 | type = AMD_IP_BLOCK_TYPE_GFX; |
338 | for (i = 0; i < adev->gfx.num_gfx_rings; i++) | 338 | for (i = 0; i < adev->gfx.num_gfx_rings; i++) |
339 | if (adev->gfx.gfx_ring[i].ready) | 339 | if (adev->gfx.gfx_ring[i].sched.ready) |
340 | ++num_rings; | 340 | ++num_rings; |
341 | ib_start_alignment = 32; | 341 | ib_start_alignment = 32; |
342 | ib_size_alignment = 32; | 342 | ib_size_alignment = 32; |
@@ -344,7 +344,7 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, | |||
344 | case AMDGPU_HW_IP_COMPUTE: | 344 | case AMDGPU_HW_IP_COMPUTE: |
345 | type = AMD_IP_BLOCK_TYPE_GFX; | 345 | type = AMD_IP_BLOCK_TYPE_GFX; |
346 | for (i = 0; i < adev->gfx.num_compute_rings; i++) | 346 | for (i = 0; i < adev->gfx.num_compute_rings; i++) |
347 | if (adev->gfx.compute_ring[i].ready) | 347 | if (adev->gfx.compute_ring[i].sched.ready) |
348 | ++num_rings; | 348 | ++num_rings; |
349 | ib_start_alignment = 32; | 349 | ib_start_alignment = 32; |
350 | ib_size_alignment = 32; | 350 | ib_size_alignment = 32; |
@@ -352,7 +352,7 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, | |||
352 | case AMDGPU_HW_IP_DMA: | 352 | case AMDGPU_HW_IP_DMA: |
353 | type = AMD_IP_BLOCK_TYPE_SDMA; | 353 | type = AMD_IP_BLOCK_TYPE_SDMA; |
354 | for (i = 0; i < adev->sdma.num_instances; i++) | 354 | for (i = 0; i < adev->sdma.num_instances; i++) |
355 | if (adev->sdma.instance[i].ring.ready) | 355 | if (adev->sdma.instance[i].ring.sched.ready) |
356 | ++num_rings; | 356 | ++num_rings; |
357 | ib_start_alignment = 256; | 357 | ib_start_alignment = 256; |
358 | ib_size_alignment = 4; | 358 | ib_size_alignment = 4; |
@@ -363,7 +363,7 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, | |||
363 | if (adev->uvd.harvest_config & (1 << i)) | 363 | if (adev->uvd.harvest_config & (1 << i)) |
364 | continue; | 364 | continue; |
365 | 365 | ||
366 | if (adev->uvd.inst[i].ring.ready) | 366 | if (adev->uvd.inst[i].ring.sched.ready) |
367 | ++num_rings; | 367 | ++num_rings; |
368 | } | 368 | } |
369 | ib_start_alignment = 64; | 369 | ib_start_alignment = 64; |
@@ -372,7 +372,7 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, | |||
372 | case AMDGPU_HW_IP_VCE: | 372 | case AMDGPU_HW_IP_VCE: |
373 | type = AMD_IP_BLOCK_TYPE_VCE; | 373 | type = AMD_IP_BLOCK_TYPE_VCE; |
374 | for (i = 0; i < adev->vce.num_rings; i++) | 374 | for (i = 0; i < adev->vce.num_rings; i++) |
375 | if (adev->vce.ring[i].ready) | 375 | if (adev->vce.ring[i].sched.ready) |
376 | ++num_rings; | 376 | ++num_rings; |
377 | ib_start_alignment = 4; | 377 | ib_start_alignment = 4; |
378 | ib_size_alignment = 1; | 378 | ib_size_alignment = 1; |
@@ -384,7 +384,7 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, | |||
384 | continue; | 384 | continue; |
385 | 385 | ||
386 | for (j = 0; j < adev->uvd.num_enc_rings; j++) | 386 | for (j = 0; j < adev->uvd.num_enc_rings; j++) |
387 | if (adev->uvd.inst[i].ring_enc[j].ready) | 387 | if (adev->uvd.inst[i].ring_enc[j].sched.ready) |
388 | ++num_rings; | 388 | ++num_rings; |
389 | } | 389 | } |
390 | ib_start_alignment = 64; | 390 | ib_start_alignment = 64; |
@@ -392,7 +392,7 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, | |||
392 | break; | 392 | break; |
393 | case AMDGPU_HW_IP_VCN_DEC: | 393 | case AMDGPU_HW_IP_VCN_DEC: |
394 | type = AMD_IP_BLOCK_TYPE_VCN; | 394 | type = AMD_IP_BLOCK_TYPE_VCN; |
395 | if (adev->vcn.ring_dec.ready) | 395 | if (adev->vcn.ring_dec.sched.ready) |
396 | ++num_rings; | 396 | ++num_rings; |
397 | ib_start_alignment = 16; | 397 | ib_start_alignment = 16; |
398 | ib_size_alignment = 16; | 398 | ib_size_alignment = 16; |
@@ -400,14 +400,14 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, | |||
400 | case AMDGPU_HW_IP_VCN_ENC: | 400 | case AMDGPU_HW_IP_VCN_ENC: |
401 | type = AMD_IP_BLOCK_TYPE_VCN; | 401 | type = AMD_IP_BLOCK_TYPE_VCN; |
402 | for (i = 0; i < adev->vcn.num_enc_rings; i++) | 402 | for (i = 0; i < adev->vcn.num_enc_rings; i++) |
403 | if (adev->vcn.ring_enc[i].ready) | 403 | if (adev->vcn.ring_enc[i].sched.ready) |
404 | ++num_rings; | 404 | ++num_rings; |
405 | ib_start_alignment = 64; | 405 | ib_start_alignment = 64; |
406 | ib_size_alignment = 1; | 406 | ib_size_alignment = 1; |
407 | break; | 407 | break; |
408 | case AMDGPU_HW_IP_VCN_JPEG: | 408 | case AMDGPU_HW_IP_VCN_JPEG: |
409 | type = AMD_IP_BLOCK_TYPE_VCN; | 409 | type = AMD_IP_BLOCK_TYPE_VCN; |
410 | if (adev->vcn.ring_jpeg.ready) | 410 | if (adev->vcn.ring_jpeg.sched.ready) |
411 | ++num_rings; | 411 | ++num_rings; |
412 | ib_start_alignment = 16; | 412 | ib_start_alignment = 16; |
413 | ib_size_alignment = 16; | 413 | ib_size_alignment = 16; |
@@ -978,7 +978,10 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | |||
978 | } | 978 | } |
979 | 979 | ||
980 | if (amdgpu_sriov_vf(adev)) { | 980 | if (amdgpu_sriov_vf(adev)) { |
981 | r = amdgpu_map_static_csa(adev, &fpriv->vm, &fpriv->csa_va); | 981 | uint64_t csa_addr = amdgpu_csa_vaddr(adev) & AMDGPU_GMC_HOLE_MASK; |
982 | |||
983 | r = amdgpu_map_static_csa(adev, &fpriv->vm, adev->virt.csa_obj, | ||
984 | &fpriv->csa_va, csa_addr, AMDGPU_CSA_SIZE); | ||
982 | if (r) | 985 | if (r) |
983 | goto error_vm; | 986 | goto error_vm; |
984 | } | 987 | } |
@@ -1048,8 +1051,8 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev, | |||
1048 | pasid = fpriv->vm.pasid; | 1051 | pasid = fpriv->vm.pasid; |
1049 | pd = amdgpu_bo_ref(fpriv->vm.root.base.bo); | 1052 | pd = amdgpu_bo_ref(fpriv->vm.root.base.bo); |
1050 | 1053 | ||
1051 | amdgpu_vm_fini(adev, &fpriv->vm); | ||
1052 | amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr); | 1054 | amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr); |
1055 | amdgpu_vm_fini(adev, &fpriv->vm); | ||
1053 | 1056 | ||
1054 | if (pasid) | 1057 | if (pasid) |
1055 | amdgpu_pasid_free_delayed(pd->tbo.resv, pasid); | 1058 | amdgpu_pasid_free_delayed(pd->tbo.resv, pasid); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index b9e9e8b02fb7..11723d8fffbd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | |||
@@ -57,7 +57,6 @@ struct amdgpu_hpd; | |||
57 | #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) |
58 | #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) |
59 | #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 | 60 | ||
62 | #define to_dm_plane_state(x) container_of(x, struct dm_plane_state, base); | 61 | #define to_dm_plane_state(x) container_of(x, struct dm_plane_state, base); |
63 | 62 | ||
@@ -325,7 +324,7 @@ struct amdgpu_mode_info { | |||
325 | struct card_info *atom_card_info; | 324 | struct card_info *atom_card_info; |
326 | bool mode_config_initialized; | 325 | bool mode_config_initialized; |
327 | struct amdgpu_crtc *crtcs[AMDGPU_MAX_CRTCS]; | 326 | struct amdgpu_crtc *crtcs[AMDGPU_MAX_CRTCS]; |
328 | struct amdgpu_plane *planes[AMDGPU_MAX_PLANES]; | 327 | struct drm_plane *planes[AMDGPU_MAX_PLANES]; |
329 | struct amdgpu_afmt *afmt[AMDGPU_MAX_AFMT_BLOCKS]; | 328 | struct amdgpu_afmt *afmt[AMDGPU_MAX_AFMT_BLOCKS]; |
330 | /* DVI-I properties */ | 329 | /* DVI-I properties */ |
331 | struct drm_property *coherent_mode_property; | 330 | struct drm_property *coherent_mode_property; |
@@ -434,11 +433,6 @@ struct amdgpu_crtc { | |||
434 | struct drm_pending_vblank_event *event; | 433 | struct drm_pending_vblank_event *event; |
435 | }; | 434 | }; |
436 | 435 | ||
437 | struct amdgpu_plane { | ||
438 | struct drm_plane base; | ||
439 | enum drm_plane_type plane_type; | ||
440 | }; | ||
441 | |||
442 | struct amdgpu_encoder_atom_dig { | 436 | struct amdgpu_encoder_atom_dig { |
443 | bool linkb; | 437 | bool linkb; |
444 | /* atom dig */ | 438 | /* atom dig */ |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 59cc678de8c1..7235cd0b0fa9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | |||
@@ -2129,7 +2129,7 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) | |||
2129 | 2129 | ||
2130 | for (i = 0; i < AMDGPU_MAX_RINGS; i++) { | 2130 | for (i = 0; i < AMDGPU_MAX_RINGS; i++) { |
2131 | struct amdgpu_ring *ring = adev->rings[i]; | 2131 | struct amdgpu_ring *ring = adev->rings[i]; |
2132 | if (ring && ring->ready) | 2132 | if (ring && ring->sched.ready) |
2133 | amdgpu_fence_wait_empty(ring); | 2133 | amdgpu_fence_wait_empty(ring); |
2134 | } | 2134 | } |
2135 | 2135 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 25d2f3e757f1..e05dc66b1090 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | |||
@@ -90,6 +90,8 @@ static int psp_sw_fini(void *handle) | |||
90 | adev->psp.sos_fw = NULL; | 90 | adev->psp.sos_fw = NULL; |
91 | release_firmware(adev->psp.asd_fw); | 91 | release_firmware(adev->psp.asd_fw); |
92 | adev->psp.asd_fw = NULL; | 92 | adev->psp.asd_fw = NULL; |
93 | release_firmware(adev->psp.ta_fw); | ||
94 | adev->psp.ta_fw = NULL; | ||
93 | return 0; | 95 | return 0; |
94 | } | 96 | } |
95 | 97 | ||
@@ -118,21 +120,25 @@ int psp_wait_for(struct psp_context *psp, uint32_t reg_index, | |||
118 | static int | 120 | static int |
119 | psp_cmd_submit_buf(struct psp_context *psp, | 121 | psp_cmd_submit_buf(struct psp_context *psp, |
120 | struct amdgpu_firmware_info *ucode, | 122 | struct amdgpu_firmware_info *ucode, |
121 | struct psp_gfx_cmd_resp *cmd, uint64_t fence_mc_addr, | 123 | struct psp_gfx_cmd_resp *cmd, uint64_t fence_mc_addr) |
122 | int index) | ||
123 | { | 124 | { |
124 | int ret; | 125 | int ret; |
126 | int index; | ||
125 | 127 | ||
126 | memset(psp->cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE); | 128 | memset(psp->cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE); |
127 | 129 | ||
128 | memcpy(psp->cmd_buf_mem, cmd, sizeof(struct psp_gfx_cmd_resp)); | 130 | memcpy(psp->cmd_buf_mem, cmd, sizeof(struct psp_gfx_cmd_resp)); |
129 | 131 | ||
132 | index = atomic_inc_return(&psp->fence_value); | ||
130 | ret = psp_cmd_submit(psp, ucode, psp->cmd_buf_mc_addr, | 133 | ret = psp_cmd_submit(psp, ucode, psp->cmd_buf_mc_addr, |
131 | fence_mc_addr, index); | 134 | fence_mc_addr, index); |
135 | if (ret) { | ||
136 | atomic_dec(&psp->fence_value); | ||
137 | return ret; | ||
138 | } | ||
132 | 139 | ||
133 | while (*((unsigned int *)psp->fence_buf) != index) { | 140 | while (*((unsigned int *)psp->fence_buf) != index) |
134 | msleep(1); | 141 | msleep(1); |
135 | } | ||
136 | 142 | ||
137 | /* the status field must be 0 after FW is loaded */ | 143 | /* the status field must be 0 after FW is loaded */ |
138 | if (ucode && psp->cmd_buf_mem->resp.status) { | 144 | if (ucode && psp->cmd_buf_mem->resp.status) { |
@@ -191,7 +197,7 @@ static int psp_tmr_load(struct psp_context *psp) | |||
191 | PSP_TMR_SIZE, psp->tmr_mc_addr); | 197 | PSP_TMR_SIZE, psp->tmr_mc_addr); |
192 | 198 | ||
193 | ret = psp_cmd_submit_buf(psp, NULL, cmd, | 199 | ret = psp_cmd_submit_buf(psp, NULL, cmd, |
194 | psp->fence_buf_mc_addr, 1); | 200 | psp->fence_buf_mc_addr); |
195 | if (ret) | 201 | if (ret) |
196 | goto failed; | 202 | goto failed; |
197 | 203 | ||
@@ -258,13 +264,194 @@ static int psp_asd_load(struct psp_context *psp) | |||
258 | psp->asd_ucode_size, PSP_ASD_SHARED_MEM_SIZE); | 264 | psp->asd_ucode_size, PSP_ASD_SHARED_MEM_SIZE); |
259 | 265 | ||
260 | ret = psp_cmd_submit_buf(psp, NULL, cmd, | 266 | ret = psp_cmd_submit_buf(psp, NULL, cmd, |
261 | psp->fence_buf_mc_addr, 2); | 267 | psp->fence_buf_mc_addr); |
268 | |||
269 | kfree(cmd); | ||
270 | |||
271 | return ret; | ||
272 | } | ||
273 | |||
274 | static void psp_prep_xgmi_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd, | ||
275 | uint64_t xgmi_ta_mc, uint64_t xgmi_mc_shared, | ||
276 | uint32_t xgmi_ta_size, uint32_t shared_size) | ||
277 | { | ||
278 | cmd->cmd_id = GFX_CMD_ID_LOAD_TA; | ||
279 | cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(xgmi_ta_mc); | ||
280 | cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(xgmi_ta_mc); | ||
281 | cmd->cmd.cmd_load_ta.app_len = xgmi_ta_size; | ||
282 | |||
283 | cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(xgmi_mc_shared); | ||
284 | cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(xgmi_mc_shared); | ||
285 | cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size; | ||
286 | } | ||
287 | |||
288 | static int psp_xgmi_init_shared_buf(struct psp_context *psp) | ||
289 | { | ||
290 | int ret; | ||
291 | |||
292 | /* | ||
293 | * Allocate 16k memory aligned to 4k from Frame Buffer (local | ||
294 | * physical) for xgmi ta <-> Driver | ||
295 | */ | ||
296 | ret = amdgpu_bo_create_kernel(psp->adev, PSP_XGMI_SHARED_MEM_SIZE, | ||
297 | PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, | ||
298 | &psp->xgmi_context.xgmi_shared_bo, | ||
299 | &psp->xgmi_context.xgmi_shared_mc_addr, | ||
300 | &psp->xgmi_context.xgmi_shared_buf); | ||
301 | |||
302 | return ret; | ||
303 | } | ||
304 | |||
305 | static int psp_xgmi_load(struct psp_context *psp) | ||
306 | { | ||
307 | int ret; | ||
308 | struct psp_gfx_cmd_resp *cmd; | ||
309 | |||
310 | /* | ||
311 | * TODO: bypass the loading in sriov for now | ||
312 | */ | ||
313 | if (amdgpu_sriov_vf(psp->adev)) | ||
314 | return 0; | ||
315 | |||
316 | cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); | ||
317 | if (!cmd) | ||
318 | return -ENOMEM; | ||
319 | |||
320 | memset(psp->fw_pri_buf, 0, PSP_1_MEG); | ||
321 | memcpy(psp->fw_pri_buf, psp->ta_xgmi_start_addr, psp->ta_xgmi_ucode_size); | ||
322 | |||
323 | psp_prep_xgmi_ta_load_cmd_buf(cmd, psp->fw_pri_mc_addr, | ||
324 | psp->xgmi_context.xgmi_shared_mc_addr, | ||
325 | psp->ta_xgmi_ucode_size, PSP_XGMI_SHARED_MEM_SIZE); | ||
326 | |||
327 | ret = psp_cmd_submit_buf(psp, NULL, cmd, | ||
328 | psp->fence_buf_mc_addr); | ||
329 | |||
330 | if (!ret) { | ||
331 | psp->xgmi_context.initialized = 1; | ||
332 | psp->xgmi_context.session_id = cmd->resp.session_id; | ||
333 | } | ||
334 | |||
335 | kfree(cmd); | ||
336 | |||
337 | return ret; | ||
338 | } | ||
339 | |||
340 | static void psp_prep_xgmi_ta_unload_cmd_buf(struct psp_gfx_cmd_resp *cmd, | ||
341 | uint32_t xgmi_session_id) | ||
342 | { | ||
343 | cmd->cmd_id = GFX_CMD_ID_UNLOAD_TA; | ||
344 | cmd->cmd.cmd_unload_ta.session_id = xgmi_session_id; | ||
345 | } | ||
346 | |||
347 | static int psp_xgmi_unload(struct psp_context *psp) | ||
348 | { | ||
349 | int ret; | ||
350 | struct psp_gfx_cmd_resp *cmd; | ||
351 | |||
352 | /* | ||
353 | * TODO: bypass the unloading in sriov for now | ||
354 | */ | ||
355 | if (amdgpu_sriov_vf(psp->adev)) | ||
356 | return 0; | ||
357 | |||
358 | cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); | ||
359 | if (!cmd) | ||
360 | return -ENOMEM; | ||
361 | |||
362 | psp_prep_xgmi_ta_unload_cmd_buf(cmd, psp->xgmi_context.session_id); | ||
363 | |||
364 | ret = psp_cmd_submit_buf(psp, NULL, cmd, | ||
365 | psp->fence_buf_mc_addr); | ||
262 | 366 | ||
263 | kfree(cmd); | 367 | kfree(cmd); |
264 | 368 | ||
265 | return ret; | 369 | return ret; |
266 | } | 370 | } |
267 | 371 | ||
372 | static void psp_prep_xgmi_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd, | ||
373 | uint32_t ta_cmd_id, | ||
374 | uint32_t xgmi_session_id) | ||
375 | { | ||
376 | cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD; | ||
377 | cmd->cmd.cmd_invoke_cmd.session_id = xgmi_session_id; | ||
378 | cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id; | ||
379 | /* Note: cmd_invoke_cmd.buf is not used for now */ | ||
380 | } | ||
381 | |||
382 | int psp_xgmi_invoke(struct psp_context *psp, uint32_t ta_cmd_id) | ||
383 | { | ||
384 | int ret; | ||
385 | struct psp_gfx_cmd_resp *cmd; | ||
386 | |||
387 | /* | ||
388 | * TODO: bypass the loading in sriov for now | ||
389 | */ | ||
390 | if (amdgpu_sriov_vf(psp->adev)) | ||
391 | return 0; | ||
392 | |||
393 | cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); | ||
394 | if (!cmd) | ||
395 | return -ENOMEM; | ||
396 | |||
397 | psp_prep_xgmi_ta_invoke_cmd_buf(cmd, ta_cmd_id, | ||
398 | psp->xgmi_context.session_id); | ||
399 | |||
400 | ret = psp_cmd_submit_buf(psp, NULL, cmd, | ||
401 | psp->fence_buf_mc_addr); | ||
402 | |||
403 | kfree(cmd); | ||
404 | |||
405 | return ret; | ||
406 | } | ||
407 | |||
408 | static int psp_xgmi_terminate(struct psp_context *psp) | ||
409 | { | ||
410 | int ret; | ||
411 | |||
412 | if (!psp->xgmi_context.initialized) | ||
413 | return 0; | ||
414 | |||
415 | ret = psp_xgmi_unload(psp); | ||
416 | if (ret) | ||
417 | return ret; | ||
418 | |||
419 | psp->xgmi_context.initialized = 0; | ||
420 | |||
421 | /* free xgmi shared memory */ | ||
422 | amdgpu_bo_free_kernel(&psp->xgmi_context.xgmi_shared_bo, | ||
423 | &psp->xgmi_context.xgmi_shared_mc_addr, | ||
424 | &psp->xgmi_context.xgmi_shared_buf); | ||
425 | |||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | static int psp_xgmi_initialize(struct psp_context *psp) | ||
430 | { | ||
431 | struct ta_xgmi_shared_memory *xgmi_cmd; | ||
432 | int ret; | ||
433 | |||
434 | if (!psp->xgmi_context.initialized) { | ||
435 | ret = psp_xgmi_init_shared_buf(psp); | ||
436 | if (ret) | ||
437 | return ret; | ||
438 | } | ||
439 | |||
440 | /* Load XGMI TA */ | ||
441 | ret = psp_xgmi_load(psp); | ||
442 | if (ret) | ||
443 | return ret; | ||
444 | |||
445 | /* Initialize XGMI session */ | ||
446 | xgmi_cmd = (struct ta_xgmi_shared_memory *)(psp->xgmi_context.xgmi_shared_buf); | ||
447 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); | ||
448 | xgmi_cmd->cmd_id = TA_COMMAND_XGMI__INITIALIZE; | ||
449 | |||
450 | ret = psp_xgmi_invoke(psp, xgmi_cmd->cmd_id); | ||
451 | |||
452 | return ret; | ||
453 | } | ||
454 | |||
268 | static int psp_hw_start(struct psp_context *psp) | 455 | static int psp_hw_start(struct psp_context *psp) |
269 | { | 456 | { |
270 | struct amdgpu_device *adev = psp->adev; | 457 | struct amdgpu_device *adev = psp->adev; |
@@ -292,6 +479,15 @@ static int psp_hw_start(struct psp_context *psp) | |||
292 | if (ret) | 479 | if (ret) |
293 | return ret; | 480 | return ret; |
294 | 481 | ||
482 | if (adev->gmc.xgmi.num_physical_nodes > 1) { | ||
483 | ret = psp_xgmi_initialize(psp); | ||
484 | /* Warning the XGMI seesion initialize failure | ||
485 | * Instead of stop driver initialization | ||
486 | */ | ||
487 | if (ret) | ||
488 | dev_err(psp->adev->dev, | ||
489 | "XGMI: Failed to initialize XGMI session\n"); | ||
490 | } | ||
295 | return 0; | 491 | return 0; |
296 | } | 492 | } |
297 | 493 | ||
@@ -321,7 +517,7 @@ static int psp_np_fw_load(struct psp_context *psp) | |||
321 | return ret; | 517 | return ret; |
322 | 518 | ||
323 | ret = psp_cmd_submit_buf(psp, ucode, psp->cmd, | 519 | ret = psp_cmd_submit_buf(psp, ucode, psp->cmd, |
324 | psp->fence_buf_mc_addr, i + 3); | 520 | psp->fence_buf_mc_addr); |
325 | if (ret) | 521 | if (ret) |
326 | return ret; | 522 | return ret; |
327 | 523 | ||
@@ -452,6 +648,10 @@ static int psp_hw_fini(void *handle) | |||
452 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) | 648 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) |
453 | return 0; | 649 | return 0; |
454 | 650 | ||
651 | if (adev->gmc.xgmi.num_physical_nodes > 1 && | ||
652 | psp->xgmi_context.initialized == 1) | ||
653 | psp_xgmi_terminate(psp); | ||
654 | |||
455 | psp_ring_destroy(psp, PSP_RING_TYPE__KM); | 655 | psp_ring_destroy(psp, PSP_RING_TYPE__KM); |
456 | 656 | ||
457 | amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); | 657 | amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); |
@@ -479,6 +679,15 @@ static int psp_suspend(void *handle) | |||
479 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) | 679 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) |
480 | return 0; | 680 | return 0; |
481 | 681 | ||
682 | if (adev->gmc.xgmi.num_physical_nodes > 1 && | ||
683 | psp->xgmi_context.initialized == 1) { | ||
684 | ret = psp_xgmi_terminate(psp); | ||
685 | if (ret) { | ||
686 | DRM_ERROR("Failed to terminate xgmi ta\n"); | ||
687 | return ret; | ||
688 | } | ||
689 | } | ||
690 | |||
482 | ret = psp_ring_stop(psp, PSP_RING_TYPE__KM); | 691 | ret = psp_ring_stop(psp, PSP_RING_TYPE__KM); |
483 | if (ret) { | 692 | if (ret) { |
484 | DRM_ERROR("PSP ring stop failed\n"); | 693 | DRM_ERROR("PSP ring stop failed\n"); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h index 8b8720e9c3f0..9ec5d1a666a6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | |||
@@ -27,14 +27,17 @@ | |||
27 | 27 | ||
28 | #include "amdgpu.h" | 28 | #include "amdgpu.h" |
29 | #include "psp_gfx_if.h" | 29 | #include "psp_gfx_if.h" |
30 | #include "ta_xgmi_if.h" | ||
30 | 31 | ||
31 | #define PSP_FENCE_BUFFER_SIZE 0x1000 | 32 | #define PSP_FENCE_BUFFER_SIZE 0x1000 |
32 | #define PSP_CMD_BUFFER_SIZE 0x1000 | 33 | #define PSP_CMD_BUFFER_SIZE 0x1000 |
33 | #define PSP_ASD_SHARED_MEM_SIZE 0x4000 | 34 | #define PSP_ASD_SHARED_MEM_SIZE 0x4000 |
35 | #define PSP_XGMI_SHARED_MEM_SIZE 0x4000 | ||
34 | #define PSP_1_MEG 0x100000 | 36 | #define PSP_1_MEG 0x100000 |
35 | #define PSP_TMR_SIZE 0x400000 | 37 | #define PSP_TMR_SIZE 0x400000 |
36 | 38 | ||
37 | struct psp_context; | 39 | struct psp_context; |
40 | struct psp_xgmi_node_info; | ||
38 | struct psp_xgmi_topology_info; | 41 | struct psp_xgmi_topology_info; |
39 | 42 | ||
40 | enum psp_ring_type | 43 | enum psp_ring_type |
@@ -80,12 +83,20 @@ struct psp_funcs | |||
80 | enum AMDGPU_UCODE_ID ucode_type); | 83 | enum AMDGPU_UCODE_ID ucode_type); |
81 | bool (*smu_reload_quirk)(struct psp_context *psp); | 84 | bool (*smu_reload_quirk)(struct psp_context *psp); |
82 | int (*mode1_reset)(struct psp_context *psp); | 85 | int (*mode1_reset)(struct psp_context *psp); |
83 | uint64_t (*xgmi_get_device_id)(struct psp_context *psp); | 86 | uint64_t (*xgmi_get_node_id)(struct psp_context *psp); |
84 | uint64_t (*xgmi_get_hive_id)(struct psp_context *psp); | 87 | uint64_t (*xgmi_get_hive_id)(struct psp_context *psp); |
85 | int (*xgmi_get_topology_info)(struct psp_context *psp, int number_devices, | 88 | int (*xgmi_get_topology_info)(struct psp_context *psp, int number_devices, |
86 | struct psp_xgmi_topology_info *topology); | 89 | struct psp_xgmi_topology_info *topology); |
87 | int (*xgmi_set_topology_info)(struct psp_context *psp, int number_devices, | 90 | int (*xgmi_set_topology_info)(struct psp_context *psp, int number_devices, |
88 | struct psp_xgmi_topology_info *topology); | 91 | struct psp_xgmi_topology_info *topology); |
92 | }; | ||
93 | |||
94 | struct psp_xgmi_context { | ||
95 | uint8_t initialized; | ||
96 | uint32_t session_id; | ||
97 | struct amdgpu_bo *xgmi_shared_bo; | ||
98 | uint64_t xgmi_shared_mc_addr; | ||
99 | void *xgmi_shared_buf; | ||
89 | }; | 100 | }; |
90 | 101 | ||
91 | struct psp_context | 102 | struct psp_context |
@@ -96,7 +107,7 @@ struct psp_context | |||
96 | 107 | ||
97 | const struct psp_funcs *funcs; | 108 | const struct psp_funcs *funcs; |
98 | 109 | ||
99 | /* fence buffer */ | 110 | /* firmware buffer */ |
100 | struct amdgpu_bo *fw_pri_bo; | 111 | struct amdgpu_bo *fw_pri_bo; |
101 | uint64_t fw_pri_mc_addr; | 112 | uint64_t fw_pri_mc_addr; |
102 | void *fw_pri_buf; | 113 | void *fw_pri_buf; |
@@ -134,6 +145,16 @@ struct psp_context | |||
134 | struct amdgpu_bo *cmd_buf_bo; | 145 | struct amdgpu_bo *cmd_buf_bo; |
135 | uint64_t cmd_buf_mc_addr; | 146 | uint64_t cmd_buf_mc_addr; |
136 | struct psp_gfx_cmd_resp *cmd_buf_mem; | 147 | struct psp_gfx_cmd_resp *cmd_buf_mem; |
148 | |||
149 | /* fence value associated with cmd buffer */ | ||
150 | atomic_t fence_value; | ||
151 | |||
152 | /* xgmi ta firmware and buffer */ | ||
153 | const struct firmware *ta_fw; | ||
154 | uint32_t ta_xgmi_ucode_version; | ||
155 | uint32_t ta_xgmi_ucode_size; | ||
156 | uint8_t *ta_xgmi_start_addr; | ||
157 | struct psp_xgmi_context xgmi_context; | ||
137 | }; | 158 | }; |
138 | 159 | ||
139 | struct amdgpu_psp_funcs { | 160 | struct amdgpu_psp_funcs { |
@@ -141,21 +162,17 @@ struct amdgpu_psp_funcs { | |||
141 | enum AMDGPU_UCODE_ID); | 162 | enum AMDGPU_UCODE_ID); |
142 | }; | 163 | }; |
143 | 164 | ||
165 | #define AMDGPU_XGMI_MAX_CONNECTED_NODES 64 | ||
166 | struct psp_xgmi_node_info { | ||
167 | uint64_t node_id; | ||
168 | uint8_t num_hops; | ||
169 | uint8_t is_sharing_enabled; | ||
170 | enum ta_xgmi_assigned_sdma_engine sdma_engine; | ||
171 | }; | ||
172 | |||
144 | struct psp_xgmi_topology_info { | 173 | struct psp_xgmi_topology_info { |
145 | /* Generated by PSP to identify the GPU instance within xgmi connection */ | 174 | uint32_t num_nodes; |
146 | uint64_t device_id; | 175 | struct psp_xgmi_node_info nodes[AMDGPU_XGMI_MAX_CONNECTED_NODES]; |
147 | /* | ||
148 | * If all bits set to 0 , driver indicates it wants to retrieve the xgmi | ||
149 | * connection vector topology, but not access enable the connections | ||
150 | * if some or all bits are set to 1, driver indicates it want to retrieve the | ||
151 | * current xgmi topology and access enable the link to GPU[i] associated | ||
152 | * with the bit position in the vector. | ||
153 | * On return,: bits indicated which xgmi links are present/active depending | ||
154 | * on the value passed in. The relative bit offset for the relative GPU index | ||
155 | * within the hive is always marked active. | ||
156 | */ | ||
157 | uint32_t connection_mask; | ||
158 | uint32_t reserved; /* must be 0 */ | ||
159 | }; | 176 | }; |
160 | 177 | ||
161 | #define psp_prep_cmd_buf(ucode, type) (psp)->funcs->prep_cmd_buf((ucode), (type)) | 178 | #define psp_prep_cmd_buf(ucode, type) (psp)->funcs->prep_cmd_buf((ucode), (type)) |
@@ -177,8 +194,8 @@ struct psp_xgmi_topology_info { | |||
177 | ((psp)->funcs->smu_reload_quirk ? (psp)->funcs->smu_reload_quirk((psp)) : false) | 194 | ((psp)->funcs->smu_reload_quirk ? (psp)->funcs->smu_reload_quirk((psp)) : false) |
178 | #define psp_mode1_reset(psp) \ | 195 | #define psp_mode1_reset(psp) \ |
179 | ((psp)->funcs->mode1_reset ? (psp)->funcs->mode1_reset((psp)) : false) | 196 | ((psp)->funcs->mode1_reset ? (psp)->funcs->mode1_reset((psp)) : false) |
180 | #define psp_xgmi_get_device_id(psp) \ | 197 | #define psp_xgmi_get_node_id(psp) \ |
181 | ((psp)->funcs->xgmi_get_device_id ? (psp)->funcs->xgmi_get_device_id((psp)) : 0) | 198 | ((psp)->funcs->xgmi_get_node_id ? (psp)->funcs->xgmi_get_node_id((psp)) : 0) |
182 | #define psp_xgmi_get_hive_id(psp) \ | 199 | #define psp_xgmi_get_hive_id(psp) \ |
183 | ((psp)->funcs->xgmi_get_hive_id ? (psp)->funcs->xgmi_get_hive_id((psp)) : 0) | 200 | ((psp)->funcs->xgmi_get_hive_id ? (psp)->funcs->xgmi_get_hive_id((psp)) : 0) |
184 | #define psp_xgmi_get_topology_info(psp, num_device, topology) \ | 201 | #define psp_xgmi_get_topology_info(psp, num_device, topology) \ |
@@ -199,6 +216,8 @@ extern int psp_wait_for(struct psp_context *psp, uint32_t reg_index, | |||
199 | extern const struct amdgpu_ip_block_version psp_v10_0_ip_block; | 216 | extern const struct amdgpu_ip_block_version psp_v10_0_ip_block; |
200 | 217 | ||
201 | int psp_gpu_reset(struct amdgpu_device *adev); | 218 | int psp_gpu_reset(struct amdgpu_device *adev); |
219 | int psp_xgmi_invoke(struct psp_context *psp, uint32_t ta_cmd_id); | ||
220 | |||
202 | extern const struct amdgpu_ip_block_version psp_v11_0_ip_block; | 221 | extern const struct amdgpu_ip_block_version psp_v11_0_ip_block; |
203 | 222 | ||
204 | #endif | 223 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index b70e85ec147d..5b75bdc8dc28 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | |||
@@ -338,7 +338,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, | |||
338 | */ | 338 | */ |
339 | void amdgpu_ring_fini(struct amdgpu_ring *ring) | 339 | void amdgpu_ring_fini(struct amdgpu_ring *ring) |
340 | { | 340 | { |
341 | ring->ready = false; | 341 | ring->sched.ready = false; |
342 | 342 | ||
343 | /* Not to finish a ring which is not initialized */ | 343 | /* Not to finish a ring which is not initialized */ |
344 | if (!(ring->adev) || !(ring->adev->rings[ring->idx])) | 344 | if (!(ring->adev) || !(ring->adev->rings[ring->idx])) |
@@ -500,3 +500,29 @@ static void amdgpu_debugfs_ring_fini(struct amdgpu_ring *ring) | |||
500 | debugfs_remove(ring->ent); | 500 | debugfs_remove(ring->ent); |
501 | #endif | 501 | #endif |
502 | } | 502 | } |
503 | |||
504 | /** | ||
505 | * amdgpu_ring_test_helper - tests ring and set sched readiness status | ||
506 | * | ||
507 | * @ring: ring to try the recovery on | ||
508 | * | ||
509 | * Tests ring and set sched readiness status | ||
510 | * | ||
511 | * Returns 0 on success, error on failure. | ||
512 | */ | ||
513 | int amdgpu_ring_test_helper(struct amdgpu_ring *ring) | ||
514 | { | ||
515 | struct amdgpu_device *adev = ring->adev; | ||
516 | int r; | ||
517 | |||
518 | r = amdgpu_ring_test_ring(ring); | ||
519 | if (r) | ||
520 | DRM_DEV_ERROR(adev->dev, "ring %s test failed (%d)\n", | ||
521 | ring->name, r); | ||
522 | else | ||
523 | DRM_DEV_DEBUG(adev->dev, "ring test on %s succeeded\n", | ||
524 | ring->name); | ||
525 | |||
526 | ring->sched.ready = !r; | ||
527 | return r; | ||
528 | } | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 4caa301ce454..0beb01fef83f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | |||
@@ -129,8 +129,9 @@ struct amdgpu_ring_funcs { | |||
129 | unsigned emit_ib_size; | 129 | unsigned emit_ib_size; |
130 | /* command emit functions */ | 130 | /* command emit functions */ |
131 | void (*emit_ib)(struct amdgpu_ring *ring, | 131 | void (*emit_ib)(struct amdgpu_ring *ring, |
132 | struct amdgpu_job *job, | ||
132 | struct amdgpu_ib *ib, | 133 | struct amdgpu_ib *ib, |
133 | unsigned vmid, bool ctx_switch); | 134 | bool ctx_switch); |
134 | void (*emit_fence)(struct amdgpu_ring *ring, uint64_t addr, | 135 | void (*emit_fence)(struct amdgpu_ring *ring, uint64_t addr, |
135 | uint64_t seq, unsigned flags); | 136 | uint64_t seq, unsigned flags); |
136 | void (*emit_pipeline_sync)(struct amdgpu_ring *ring); | 137 | void (*emit_pipeline_sync)(struct amdgpu_ring *ring); |
@@ -189,7 +190,6 @@ struct amdgpu_ring { | |||
189 | uint64_t gpu_addr; | 190 | uint64_t gpu_addr; |
190 | uint64_t ptr_mask; | 191 | uint64_t ptr_mask; |
191 | uint32_t buf_mask; | 192 | uint32_t buf_mask; |
192 | bool ready; | ||
193 | u32 idx; | 193 | u32 idx; |
194 | u32 me; | 194 | u32 me; |
195 | u32 pipe; | 195 | u32 pipe; |
@@ -229,7 +229,7 @@ struct amdgpu_ring { | |||
229 | #define amdgpu_ring_get_rptr(r) (r)->funcs->get_rptr((r)) | 229 | #define amdgpu_ring_get_rptr(r) (r)->funcs->get_rptr((r)) |
230 | #define amdgpu_ring_get_wptr(r) (r)->funcs->get_wptr((r)) | 230 | #define amdgpu_ring_get_wptr(r) (r)->funcs->get_wptr((r)) |
231 | #define amdgpu_ring_set_wptr(r) (r)->funcs->set_wptr((r)) | 231 | #define amdgpu_ring_set_wptr(r) (r)->funcs->set_wptr((r)) |
232 | #define amdgpu_ring_emit_ib(r, ib, vmid, c) (r)->funcs->emit_ib((r), (ib), (vmid), (c)) | 232 | #define amdgpu_ring_emit_ib(r, job, ib, c) ((r)->funcs->emit_ib((r), (job), (ib), (c))) |
233 | #define amdgpu_ring_emit_pipeline_sync(r) (r)->funcs->emit_pipeline_sync((r)) | 233 | #define amdgpu_ring_emit_pipeline_sync(r) (r)->funcs->emit_pipeline_sync((r)) |
234 | #define amdgpu_ring_emit_vm_flush(r, vmid, addr) (r)->funcs->emit_vm_flush((r), (vmid), (addr)) | 234 | #define amdgpu_ring_emit_vm_flush(r, vmid, addr) (r)->funcs->emit_vm_flush((r), (vmid), (addr)) |
235 | #define amdgpu_ring_emit_fence(r, addr, seq, flags) (r)->funcs->emit_fence((r), (addr), (seq), (flags)) | 235 | #define amdgpu_ring_emit_fence(r, addr, seq, flags) (r)->funcs->emit_fence((r), (addr), (seq), (flags)) |
@@ -313,4 +313,6 @@ static inline void amdgpu_ring_write_multiple(struct amdgpu_ring *ring, | |||
313 | ring->count_dw -= count_dw; | 313 | ring->count_dw -= count_dw; |
314 | } | 314 | } |
315 | 315 | ||
316 | int amdgpu_ring_test_helper(struct amdgpu_ring *ring); | ||
317 | |||
316 | #endif | 318 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c new file mode 100644 index 000000000000..c8793e6cc3c5 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c | |||
@@ -0,0 +1,282 @@ | |||
1 | /* | ||
2 | * Copyright 2014 Advanced Micro Devices, Inc. | ||
3 | * Copyright 2008 Red Hat Inc. | ||
4 | * Copyright 2009 Jerome Glisse. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the "Software"), | ||
8 | * to deal in the Software without restriction, including without limitation | ||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
11 | * Software is furnished to do so, subject to the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice shall be included in | ||
14 | * all copies or substantial portions of the Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
19 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
22 | * OTHER DEALINGS IN THE SOFTWARE. | ||
23 | * | ||
24 | */ | ||
25 | #include <linux/firmware.h> | ||
26 | #include "amdgpu.h" | ||
27 | #include "amdgpu_gfx.h" | ||
28 | #include "amdgpu_rlc.h" | ||
29 | |||
30 | /** | ||
31 | * amdgpu_gfx_rlc_enter_safe_mode - Set RLC into safe mode | ||
32 | * | ||
33 | * @adev: amdgpu_device pointer | ||
34 | * | ||
35 | * Set RLC enter into safe mode if RLC is enabled and haven't in safe mode. | ||
36 | */ | ||
37 | void amdgpu_gfx_rlc_enter_safe_mode(struct amdgpu_device *adev) | ||
38 | { | ||
39 | if (adev->gfx.rlc.in_safe_mode) | ||
40 | return; | ||
41 | |||
42 | /* if RLC is not enabled, do nothing */ | ||
43 | if (!adev->gfx.rlc.funcs->is_rlc_enabled(adev)) | ||
44 | return; | ||
45 | |||
46 | if (adev->cg_flags & | ||
47 | (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_MGCG | | ||
48 | AMD_CG_SUPPORT_GFX_3D_CGCG)) { | ||
49 | adev->gfx.rlc.funcs->set_safe_mode(adev); | ||
50 | adev->gfx.rlc.in_safe_mode = true; | ||
51 | } | ||
52 | } | ||
53 | |||
54 | /** | ||
55 | * amdgpu_gfx_rlc_exit_safe_mode - Set RLC out of safe mode | ||
56 | * | ||
57 | * @adev: amdgpu_device pointer | ||
58 | * | ||
59 | * Set RLC exit safe mode if RLC is enabled and have entered into safe mode. | ||
60 | */ | ||
61 | void amdgpu_gfx_rlc_exit_safe_mode(struct amdgpu_device *adev) | ||
62 | { | ||
63 | if (!(adev->gfx.rlc.in_safe_mode)) | ||
64 | return; | ||
65 | |||
66 | /* if RLC is not enabled, do nothing */ | ||
67 | if (!adev->gfx.rlc.funcs->is_rlc_enabled(adev)) | ||
68 | return; | ||
69 | |||
70 | if (adev->cg_flags & | ||
71 | (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_MGCG | | ||
72 | AMD_CG_SUPPORT_GFX_3D_CGCG)) { | ||
73 | adev->gfx.rlc.funcs->unset_safe_mode(adev); | ||
74 | adev->gfx.rlc.in_safe_mode = false; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | /** | ||
79 | * amdgpu_gfx_rlc_init_sr - Init save restore block | ||
80 | * | ||
81 | * @adev: amdgpu_device pointer | ||
82 | * @dws: the size of save restore block | ||
83 | * | ||
84 | * Allocate and setup value to save restore block of rlc. | ||
85 | * Returns 0 on succeess or negative error code if allocate failed. | ||
86 | */ | ||
87 | int amdgpu_gfx_rlc_init_sr(struct amdgpu_device *adev, u32 dws) | ||
88 | { | ||
89 | const u32 *src_ptr; | ||
90 | volatile u32 *dst_ptr; | ||
91 | u32 i; | ||
92 | int r; | ||
93 | |||
94 | /* allocate save restore block */ | ||
95 | r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE, | ||
96 | AMDGPU_GEM_DOMAIN_VRAM, | ||
97 | &adev->gfx.rlc.save_restore_obj, | ||
98 | &adev->gfx.rlc.save_restore_gpu_addr, | ||
99 | (void **)&adev->gfx.rlc.sr_ptr); | ||
100 | if (r) { | ||
101 | dev_warn(adev->dev, "(%d) create RLC sr bo failed\n", r); | ||
102 | amdgpu_gfx_rlc_fini(adev); | ||
103 | return r; | ||
104 | } | ||
105 | |||
106 | /* write the sr buffer */ | ||
107 | src_ptr = adev->gfx.rlc.reg_list; | ||
108 | dst_ptr = adev->gfx.rlc.sr_ptr; | ||
109 | for (i = 0; i < adev->gfx.rlc.reg_list_size; i++) | ||
110 | dst_ptr[i] = cpu_to_le32(src_ptr[i]); | ||
111 | amdgpu_bo_kunmap(adev->gfx.rlc.save_restore_obj); | ||
112 | amdgpu_bo_unreserve(adev->gfx.rlc.save_restore_obj); | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | /** | ||
118 | * amdgpu_gfx_rlc_init_csb - Init clear state block | ||
119 | * | ||
120 | * @adev: amdgpu_device pointer | ||
121 | * | ||
122 | * Allocate and setup value to clear state block of rlc. | ||
123 | * Returns 0 on succeess or negative error code if allocate failed. | ||
124 | */ | ||
125 | int amdgpu_gfx_rlc_init_csb(struct amdgpu_device *adev) | ||
126 | { | ||
127 | volatile u32 *dst_ptr; | ||
128 | u32 dws; | ||
129 | int r; | ||
130 | |||
131 | /* allocate clear state block */ | ||
132 | adev->gfx.rlc.clear_state_size = dws = adev->gfx.rlc.funcs->get_csb_size(adev); | ||
133 | r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE, | ||
134 | AMDGPU_GEM_DOMAIN_VRAM, | ||
135 | &adev->gfx.rlc.clear_state_obj, | ||
136 | &adev->gfx.rlc.clear_state_gpu_addr, | ||
137 | (void **)&adev->gfx.rlc.cs_ptr); | ||
138 | if (r) { | ||
139 | dev_err(adev->dev, "(%d) failed to create rlc csb bo\n", r); | ||
140 | amdgpu_gfx_rlc_fini(adev); | ||
141 | return r; | ||
142 | } | ||
143 | |||
144 | /* set up the cs buffer */ | ||
145 | dst_ptr = adev->gfx.rlc.cs_ptr; | ||
146 | adev->gfx.rlc.funcs->get_csb_buffer(adev, dst_ptr); | ||
147 | amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj); | ||
148 | amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj); | ||
149 | amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); | ||
150 | |||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | /** | ||
155 | * amdgpu_gfx_rlc_init_cpt - Init cp table | ||
156 | * | ||
157 | * @adev: amdgpu_device pointer | ||
158 | * | ||
159 | * Allocate and setup value to cp table of rlc. | ||
160 | * Returns 0 on succeess or negative error code if allocate failed. | ||
161 | */ | ||
162 | int amdgpu_gfx_rlc_init_cpt(struct amdgpu_device *adev) | ||
163 | { | ||
164 | int r; | ||
165 | |||
166 | r = amdgpu_bo_create_reserved(adev, adev->gfx.rlc.cp_table_size, | ||
167 | PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, | ||
168 | &adev->gfx.rlc.cp_table_obj, | ||
169 | &adev->gfx.rlc.cp_table_gpu_addr, | ||
170 | (void **)&adev->gfx.rlc.cp_table_ptr); | ||
171 | if (r) { | ||
172 | dev_err(adev->dev, "(%d) failed to create cp table bo\n", r); | ||
173 | amdgpu_gfx_rlc_fini(adev); | ||
174 | return r; | ||
175 | } | ||
176 | |||
177 | /* set up the cp table */ | ||
178 | amdgpu_gfx_rlc_setup_cp_table(adev); | ||
179 | amdgpu_bo_kunmap(adev->gfx.rlc.cp_table_obj); | ||
180 | amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj); | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | /** | ||
186 | * amdgpu_gfx_rlc_setup_cp_table - setup cp the buffer of cp table | ||
187 | * | ||
188 | * @adev: amdgpu_device pointer | ||
189 | * | ||
190 | * Write cp firmware data into cp table. | ||
191 | */ | ||
192 | void amdgpu_gfx_rlc_setup_cp_table(struct amdgpu_device *adev) | ||
193 | { | ||
194 | const __le32 *fw_data; | ||
195 | volatile u32 *dst_ptr; | ||
196 | int me, i, max_me; | ||
197 | u32 bo_offset = 0; | ||
198 | u32 table_offset, table_size; | ||
199 | |||
200 | max_me = adev->gfx.rlc.funcs->get_cp_table_num(adev); | ||
201 | |||
202 | /* write the cp table buffer */ | ||
203 | dst_ptr = adev->gfx.rlc.cp_table_ptr; | ||
204 | for (me = 0; me < max_me; me++) { | ||
205 | if (me == 0) { | ||
206 | const struct gfx_firmware_header_v1_0 *hdr = | ||
207 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.ce_fw->data; | ||
208 | fw_data = (const __le32 *) | ||
209 | (adev->gfx.ce_fw->data + | ||
210 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
211 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
212 | table_size = le32_to_cpu(hdr->jt_size); | ||
213 | } else if (me == 1) { | ||
214 | const struct gfx_firmware_header_v1_0 *hdr = | ||
215 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.pfp_fw->data; | ||
216 | fw_data = (const __le32 *) | ||
217 | (adev->gfx.pfp_fw->data + | ||
218 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
219 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
220 | table_size = le32_to_cpu(hdr->jt_size); | ||
221 | } else if (me == 2) { | ||
222 | const struct gfx_firmware_header_v1_0 *hdr = | ||
223 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.me_fw->data; | ||
224 | fw_data = (const __le32 *) | ||
225 | (adev->gfx.me_fw->data + | ||
226 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
227 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
228 | table_size = le32_to_cpu(hdr->jt_size); | ||
229 | } else if (me == 3) { | ||
230 | const struct gfx_firmware_header_v1_0 *hdr = | ||
231 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data; | ||
232 | fw_data = (const __le32 *) | ||
233 | (adev->gfx.mec_fw->data + | ||
234 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
235 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
236 | table_size = le32_to_cpu(hdr->jt_size); | ||
237 | } else if (me == 4) { | ||
238 | const struct gfx_firmware_header_v1_0 *hdr = | ||
239 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec2_fw->data; | ||
240 | fw_data = (const __le32 *) | ||
241 | (adev->gfx.mec2_fw->data + | ||
242 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
243 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
244 | table_size = le32_to_cpu(hdr->jt_size); | ||
245 | } | ||
246 | |||
247 | for (i = 0; i < table_size; i ++) { | ||
248 | dst_ptr[bo_offset + i] = | ||
249 | cpu_to_le32(le32_to_cpu(fw_data[table_offset + i])); | ||
250 | } | ||
251 | |||
252 | bo_offset += table_size; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | /** | ||
257 | * amdgpu_gfx_rlc_fini - Free BO which used for RLC | ||
258 | * | ||
259 | * @adev: amdgpu_device pointer | ||
260 | * | ||
261 | * Free three BO which is used for rlc_save_restore_block, rlc_clear_state_block | ||
262 | * and rlc_jump_table_block. | ||
263 | */ | ||
264 | void amdgpu_gfx_rlc_fini(struct amdgpu_device *adev) | ||
265 | { | ||
266 | /* save restore block */ | ||
267 | if (adev->gfx.rlc.save_restore_obj) { | ||
268 | amdgpu_bo_free_kernel(&adev->gfx.rlc.save_restore_obj, | ||
269 | &adev->gfx.rlc.save_restore_gpu_addr, | ||
270 | (void **)&adev->gfx.rlc.sr_ptr); | ||
271 | } | ||
272 | |||
273 | /* clear state block */ | ||
274 | amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, | ||
275 | &adev->gfx.rlc.clear_state_gpu_addr, | ||
276 | (void **)&adev->gfx.rlc.cs_ptr); | ||
277 | |||
278 | /* jump table block */ | ||
279 | amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj, | ||
280 | &adev->gfx.rlc.cp_table_gpu_addr, | ||
281 | (void **)&adev->gfx.rlc.cp_table_ptr); | ||
282 | } | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h new file mode 100644 index 000000000000..49a8ab52113b --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * Copyright 2014 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 | |||
24 | #ifndef __AMDGPU_RLC_H__ | ||
25 | #define __AMDGPU_RLC_H__ | ||
26 | |||
27 | #include "clearstate_defs.h" | ||
28 | |||
29 | struct amdgpu_rlc_funcs { | ||
30 | bool (*is_rlc_enabled)(struct amdgpu_device *adev); | ||
31 | void (*set_safe_mode)(struct amdgpu_device *adev); | ||
32 | void (*unset_safe_mode)(struct amdgpu_device *adev); | ||
33 | int (*init)(struct amdgpu_device *adev); | ||
34 | u32 (*get_csb_size)(struct amdgpu_device *adev); | ||
35 | void (*get_csb_buffer)(struct amdgpu_device *adev, volatile u32 *buffer); | ||
36 | int (*get_cp_table_num)(struct amdgpu_device *adev); | ||
37 | int (*resume)(struct amdgpu_device *adev); | ||
38 | void (*stop)(struct amdgpu_device *adev); | ||
39 | void (*reset)(struct amdgpu_device *adev); | ||
40 | void (*start)(struct amdgpu_device *adev); | ||
41 | }; | ||
42 | |||
43 | struct amdgpu_rlc { | ||
44 | /* for power gating */ | ||
45 | struct amdgpu_bo *save_restore_obj; | ||
46 | uint64_t save_restore_gpu_addr; | ||
47 | volatile uint32_t *sr_ptr; | ||
48 | const u32 *reg_list; | ||
49 | u32 reg_list_size; | ||
50 | /* for clear state */ | ||
51 | struct amdgpu_bo *clear_state_obj; | ||
52 | uint64_t clear_state_gpu_addr; | ||
53 | volatile uint32_t *cs_ptr; | ||
54 | const struct cs_section_def *cs_data; | ||
55 | u32 clear_state_size; | ||
56 | /* for cp tables */ | ||
57 | struct amdgpu_bo *cp_table_obj; | ||
58 | uint64_t cp_table_gpu_addr; | ||
59 | volatile uint32_t *cp_table_ptr; | ||
60 | u32 cp_table_size; | ||
61 | |||
62 | /* safe mode for updating CG/PG state */ | ||
63 | bool in_safe_mode; | ||
64 | const struct amdgpu_rlc_funcs *funcs; | ||
65 | |||
66 | /* for firmware data */ | ||
67 | u32 save_and_restore_offset; | ||
68 | u32 clear_state_descriptor_offset; | ||
69 | u32 avail_scratch_ram_locations; | ||
70 | u32 reg_restore_list_size; | ||
71 | u32 reg_list_format_start; | ||
72 | u32 reg_list_format_separate_start; | ||
73 | u32 starting_offsets_start; | ||
74 | u32 reg_list_format_size_bytes; | ||
75 | u32 reg_list_size_bytes; | ||
76 | u32 reg_list_format_direct_reg_list_length; | ||
77 | u32 save_restore_list_cntl_size_bytes; | ||
78 | u32 save_restore_list_gpm_size_bytes; | ||
79 | u32 save_restore_list_srm_size_bytes; | ||
80 | |||
81 | u32 *register_list_format; | ||
82 | u32 *register_restore; | ||
83 | u8 *save_restore_list_cntl; | ||
84 | u8 *save_restore_list_gpm; | ||
85 | u8 *save_restore_list_srm; | ||
86 | |||
87 | bool is_rlc_v2_1; | ||
88 | }; | ||
89 | |||
90 | void amdgpu_gfx_rlc_enter_safe_mode(struct amdgpu_device *adev); | ||
91 | void amdgpu_gfx_rlc_exit_safe_mode(struct amdgpu_device *adev); | ||
92 | int amdgpu_gfx_rlc_init_sr(struct amdgpu_device *adev, u32 dws); | ||
93 | int amdgpu_gfx_rlc_init_csb(struct amdgpu_device *adev); | ||
94 | int amdgpu_gfx_rlc_init_cpt(struct amdgpu_device *adev); | ||
95 | void amdgpu_gfx_rlc_setup_cp_table(struct amdgpu_device *adev); | ||
96 | void amdgpu_gfx_rlc_fini(struct amdgpu_device *adev); | ||
97 | |||
98 | #endif | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c index bc9244b429ef..115bb0c99b0f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c | |||
@@ -28,17 +28,31 @@ | |||
28 | * GPU SDMA IP block helpers function. | 28 | * GPU SDMA IP block helpers function. |
29 | */ | 29 | */ |
30 | 30 | ||
31 | struct amdgpu_sdma_instance * amdgpu_get_sdma_instance(struct amdgpu_ring *ring) | 31 | struct amdgpu_sdma_instance *amdgpu_sdma_get_instance_from_ring(struct amdgpu_ring *ring) |
32 | { | 32 | { |
33 | struct amdgpu_device *adev = ring->adev; | 33 | struct amdgpu_device *adev = ring->adev; |
34 | int i; | 34 | int i; |
35 | 35 | ||
36 | for (i = 0; i < adev->sdma.num_instances; i++) | 36 | for (i = 0; i < adev->sdma.num_instances; i++) |
37 | if (&adev->sdma.instance[i].ring == ring) | 37 | if (ring == &adev->sdma.instance[i].ring || |
38 | break; | 38 | ring == &adev->sdma.instance[i].page) |
39 | return &adev->sdma.instance[i]; | ||
39 | 40 | ||
40 | if (i < AMDGPU_MAX_SDMA_INSTANCES) | 41 | return NULL; |
41 | return &adev->sdma.instance[i]; | 42 | } |
42 | else | 43 | |
43 | return NULL; | 44 | int amdgpu_sdma_get_index_from_ring(struct amdgpu_ring *ring, uint32_t *index) |
45 | { | ||
46 | struct amdgpu_device *adev = ring->adev; | ||
47 | int i; | ||
48 | |||
49 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
50 | if (ring == &adev->sdma.instance[i].ring || | ||
51 | ring == &adev->sdma.instance[i].page) { | ||
52 | *index = i; | ||
53 | return 0; | ||
54 | } | ||
55 | } | ||
56 | |||
57 | return -EINVAL; | ||
44 | } | 58 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h index 500113ec65ca..16b1a6ae5ba6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h | |||
@@ -41,6 +41,7 @@ struct amdgpu_sdma_instance { | |||
41 | uint32_t feature_version; | 41 | uint32_t feature_version; |
42 | 42 | ||
43 | struct amdgpu_ring ring; | 43 | struct amdgpu_ring ring; |
44 | struct amdgpu_ring page; | ||
44 | bool burst_nop; | 45 | bool burst_nop; |
45 | }; | 46 | }; |
46 | 47 | ||
@@ -50,6 +51,7 @@ struct amdgpu_sdma { | |||
50 | struct amdgpu_irq_src illegal_inst_irq; | 51 | struct amdgpu_irq_src illegal_inst_irq; |
51 | int num_instances; | 52 | int num_instances; |
52 | uint32_t srbm_soft_reset; | 53 | uint32_t srbm_soft_reset; |
54 | bool has_page_queue; | ||
53 | }; | 55 | }; |
54 | 56 | ||
55 | /* | 57 | /* |
@@ -92,6 +94,7 @@ struct amdgpu_buffer_funcs { | |||
92 | #define amdgpu_emit_fill_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_fill_buffer((ib), (s), (d), (b)) | 94 | #define amdgpu_emit_fill_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_fill_buffer((ib), (s), (d), (b)) |
93 | 95 | ||
94 | struct amdgpu_sdma_instance * | 96 | struct amdgpu_sdma_instance * |
95 | amdgpu_get_sdma_instance(struct amdgpu_ring *ring); | 97 | amdgpu_sdma_get_instance_from_ring(struct amdgpu_ring *ring); |
98 | int amdgpu_sdma_get_index_from_ring(struct amdgpu_ring *ring, uint32_t *index); | ||
96 | 99 | ||
97 | #endif | 100 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h index e9bf70e2ac51..626abca770a0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h | |||
@@ -218,6 +218,7 @@ TRACE_EVENT(amdgpu_vm_grab_id, | |||
218 | TP_ARGS(vm, ring, job), | 218 | TP_ARGS(vm, ring, job), |
219 | TP_STRUCT__entry( | 219 | TP_STRUCT__entry( |
220 | __field(u32, pasid) | 220 | __field(u32, pasid) |
221 | __string(ring, ring->name) | ||
221 | __field(u32, ring) | 222 | __field(u32, ring) |
222 | __field(u32, vmid) | 223 | __field(u32, vmid) |
223 | __field(u32, vm_hub) | 224 | __field(u32, vm_hub) |
@@ -227,14 +228,14 @@ TRACE_EVENT(amdgpu_vm_grab_id, | |||
227 | 228 | ||
228 | TP_fast_assign( | 229 | TP_fast_assign( |
229 | __entry->pasid = vm->pasid; | 230 | __entry->pasid = vm->pasid; |
230 | __entry->ring = ring->idx; | 231 | __assign_str(ring, ring->name) |
231 | __entry->vmid = job->vmid; | 232 | __entry->vmid = job->vmid; |
232 | __entry->vm_hub = ring->funcs->vmhub, | 233 | __entry->vm_hub = ring->funcs->vmhub, |
233 | __entry->pd_addr = job->vm_pd_addr; | 234 | __entry->pd_addr = job->vm_pd_addr; |
234 | __entry->needs_flush = job->vm_needs_flush; | 235 | __entry->needs_flush = job->vm_needs_flush; |
235 | ), | 236 | ), |
236 | TP_printk("pasid=%d, ring=%u, id=%u, hub=%u, pd_addr=%010Lx needs_flush=%u", | 237 | TP_printk("pasid=%d, ring=%s, id=%u, hub=%u, pd_addr=%010Lx needs_flush=%u", |
237 | __entry->pasid, __entry->ring, __entry->vmid, | 238 | __entry->pasid, __get_str(ring), __entry->vmid, |
238 | __entry->vm_hub, __entry->pd_addr, __entry->needs_flush) | 239 | __entry->vm_hub, __entry->pd_addr, __entry->needs_flush) |
239 | ); | 240 | ); |
240 | 241 | ||
@@ -366,20 +367,20 @@ TRACE_EVENT(amdgpu_vm_flush, | |||
366 | uint64_t pd_addr), | 367 | uint64_t pd_addr), |
367 | TP_ARGS(ring, vmid, pd_addr), | 368 | TP_ARGS(ring, vmid, pd_addr), |
368 | TP_STRUCT__entry( | 369 | TP_STRUCT__entry( |
369 | __field(u32, ring) | 370 | __string(ring, ring->name) |
370 | __field(u32, vmid) | 371 | __field(u32, vmid) |
371 | __field(u32, vm_hub) | 372 | __field(u32, vm_hub) |
372 | __field(u64, pd_addr) | 373 | __field(u64, pd_addr) |
373 | ), | 374 | ), |
374 | 375 | ||
375 | TP_fast_assign( | 376 | TP_fast_assign( |
376 | __entry->ring = ring->idx; | 377 | __assign_str(ring, ring->name) |
377 | __entry->vmid = vmid; | 378 | __entry->vmid = vmid; |
378 | __entry->vm_hub = ring->funcs->vmhub; | 379 | __entry->vm_hub = ring->funcs->vmhub; |
379 | __entry->pd_addr = pd_addr; | 380 | __entry->pd_addr = pd_addr; |
380 | ), | 381 | ), |
381 | TP_printk("ring=%u, id=%u, hub=%u, pd_addr=%010Lx", | 382 | TP_printk("ring=%s, id=%u, hub=%u, pd_addr=%010Lx", |
382 | __entry->ring, __entry->vmid, | 383 | __get_str(ring), __entry->vmid, |
383 | __entry->vm_hub,__entry->pd_addr) | 384 | __entry->vm_hub,__entry->pd_addr) |
384 | ); | 385 | ); |
385 | 386 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index a44fc12ae1f9..c91ec3101d00 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | |||
@@ -61,100 +61,6 @@ static int amdgpu_map_buffer(struct ttm_buffer_object *bo, | |||
61 | static int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev); | 61 | static int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev); |
62 | static void amdgpu_ttm_debugfs_fini(struct amdgpu_device *adev); | 62 | static void amdgpu_ttm_debugfs_fini(struct amdgpu_device *adev); |
63 | 63 | ||
64 | /* | ||
65 | * Global memory. | ||
66 | */ | ||
67 | |||
68 | /** | ||
69 | * amdgpu_ttm_mem_global_init - Initialize and acquire reference to | ||
70 | * memory object | ||
71 | * | ||
72 | * @ref: Object for initialization. | ||
73 | * | ||
74 | * This is called by drm_global_item_ref() when an object is being | ||
75 | * initialized. | ||
76 | */ | ||
77 | static int amdgpu_ttm_mem_global_init(struct drm_global_reference *ref) | ||
78 | { | ||
79 | return ttm_mem_global_init(ref->object); | ||
80 | } | ||
81 | |||
82 | /** | ||
83 | * amdgpu_ttm_mem_global_release - Drop reference to a memory object | ||
84 | * | ||
85 | * @ref: Object being removed | ||
86 | * | ||
87 | * This is called by drm_global_item_unref() when an object is being | ||
88 | * released. | ||
89 | */ | ||
90 | static void amdgpu_ttm_mem_global_release(struct drm_global_reference *ref) | ||
91 | { | ||
92 | ttm_mem_global_release(ref->object); | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * amdgpu_ttm_global_init - Initialize global TTM memory reference structures. | ||
97 | * | ||
98 | * @adev: AMDGPU device for which the global structures need to be registered. | ||
99 | * | ||
100 | * This is called as part of the AMDGPU ttm init from amdgpu_ttm_init() | ||
101 | * during bring up. | ||
102 | */ | ||
103 | static int amdgpu_ttm_global_init(struct amdgpu_device *adev) | ||
104 | { | ||
105 | struct drm_global_reference *global_ref; | ||
106 | int r; | ||
107 | |||
108 | /* ensure reference is false in case init fails */ | ||
109 | adev->mman.mem_global_referenced = false; | ||
110 | |||
111 | global_ref = &adev->mman.mem_global_ref; | ||
112 | global_ref->global_type = DRM_GLOBAL_TTM_MEM; | ||
113 | global_ref->size = sizeof(struct ttm_mem_global); | ||
114 | global_ref->init = &amdgpu_ttm_mem_global_init; | ||
115 | global_ref->release = &amdgpu_ttm_mem_global_release; | ||
116 | r = drm_global_item_ref(global_ref); | ||
117 | if (r) { | ||
118 | DRM_ERROR("Failed setting up TTM memory accounting " | ||
119 | "subsystem.\n"); | ||
120 | goto error_mem; | ||
121 | } | ||
122 | |||
123 | adev->mman.bo_global_ref.mem_glob = | ||
124 | adev->mman.mem_global_ref.object; | ||
125 | global_ref = &adev->mman.bo_global_ref.ref; | ||
126 | global_ref->global_type = DRM_GLOBAL_TTM_BO; | ||
127 | global_ref->size = sizeof(struct ttm_bo_global); | ||
128 | global_ref->init = &ttm_bo_global_init; | ||
129 | global_ref->release = &ttm_bo_global_release; | ||
130 | r = drm_global_item_ref(global_ref); | ||
131 | if (r) { | ||
132 | DRM_ERROR("Failed setting up TTM BO subsystem.\n"); | ||
133 | goto error_bo; | ||
134 | } | ||
135 | |||
136 | mutex_init(&adev->mman.gtt_window_lock); | ||
137 | |||
138 | adev->mman.mem_global_referenced = true; | ||
139 | |||
140 | return 0; | ||
141 | |||
142 | error_bo: | ||
143 | drm_global_item_unref(&adev->mman.mem_global_ref); | ||
144 | error_mem: | ||
145 | return r; | ||
146 | } | ||
147 | |||
148 | static void amdgpu_ttm_global_fini(struct amdgpu_device *adev) | ||
149 | { | ||
150 | if (adev->mman.mem_global_referenced) { | ||
151 | mutex_destroy(&adev->mman.gtt_window_lock); | ||
152 | drm_global_item_unref(&adev->mman.bo_global_ref.ref); | ||
153 | drm_global_item_unref(&adev->mman.mem_global_ref); | ||
154 | adev->mman.mem_global_referenced = false; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | static int amdgpu_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags) | 64 | static int amdgpu_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags) |
159 | { | 65 | { |
160 | return 0; | 66 | return 0; |
@@ -1758,14 +1664,10 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) | |||
1758 | int r; | 1664 | int r; |
1759 | u64 vis_vram_limit; | 1665 | u64 vis_vram_limit; |
1760 | 1666 | ||
1761 | /* initialize global references for vram/gtt */ | 1667 | mutex_init(&adev->mman.gtt_window_lock); |
1762 | r = amdgpu_ttm_global_init(adev); | 1668 | |
1763 | if (r) { | ||
1764 | return r; | ||
1765 | } | ||
1766 | /* No others user of address space so set it to 0 */ | 1669 | /* No others user of address space so set it to 0 */ |
1767 | r = ttm_bo_device_init(&adev->mman.bdev, | 1670 | r = ttm_bo_device_init(&adev->mman.bdev, |
1768 | adev->mman.bo_global_ref.ref.object, | ||
1769 | &amdgpu_bo_driver, | 1671 | &amdgpu_bo_driver, |
1770 | adev->ddev->anon_inode->i_mapping, | 1672 | adev->ddev->anon_inode->i_mapping, |
1771 | DRM_FILE_PAGE_OFFSET, | 1673 | DRM_FILE_PAGE_OFFSET, |
@@ -1922,7 +1824,6 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev) | |||
1922 | ttm_bo_clean_mm(&adev->mman.bdev, AMDGPU_PL_GWS); | 1824 | ttm_bo_clean_mm(&adev->mman.bdev, AMDGPU_PL_GWS); |
1923 | ttm_bo_clean_mm(&adev->mman.bdev, AMDGPU_PL_OA); | 1825 | ttm_bo_clean_mm(&adev->mman.bdev, AMDGPU_PL_OA); |
1924 | ttm_bo_device_release(&adev->mman.bdev); | 1826 | ttm_bo_device_release(&adev->mman.bdev); |
1925 | amdgpu_ttm_global_fini(adev); | ||
1926 | adev->mman.initialized = false; | 1827 | adev->mman.initialized = false; |
1927 | DRM_INFO("amdgpu: ttm finalized\n"); | 1828 | DRM_INFO("amdgpu: ttm finalized\n"); |
1928 | } | 1829 | } |
@@ -2069,7 +1970,7 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset, | |||
2069 | unsigned i; | 1970 | unsigned i; |
2070 | int r; | 1971 | int r; |
2071 | 1972 | ||
2072 | if (direct_submit && !ring->ready) { | 1973 | if (direct_submit && !ring->sched.ready) { |
2073 | DRM_ERROR("Trying to move memory with ring turned off.\n"); | 1974 | DRM_ERROR("Trying to move memory with ring turned off.\n"); |
2074 | return -EINVAL; | 1975 | return -EINVAL; |
2075 | } | 1976 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h index fe8f276e9811..b5b2d101f7db 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | |||
@@ -39,8 +39,6 @@ | |||
39 | #define AMDGPU_GTT_NUM_TRANSFER_WINDOWS 2 | 39 | #define AMDGPU_GTT_NUM_TRANSFER_WINDOWS 2 |
40 | 40 | ||
41 | struct amdgpu_mman { | 41 | struct amdgpu_mman { |
42 | struct ttm_bo_global_ref bo_global_ref; | ||
43 | struct drm_global_reference mem_global_ref; | ||
44 | struct ttm_bo_device bdev; | 42 | struct ttm_bo_device bdev; |
45 | bool mem_global_referenced; | 43 | bool mem_global_referenced; |
46 | bool initialized; | 44 | bool initialized; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h index aa6641b944a0..7ac25a1c7853 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | |||
@@ -58,6 +58,17 @@ struct psp_firmware_header_v1_0 { | |||
58 | }; | 58 | }; |
59 | 59 | ||
60 | /* version_major=1, version_minor=0 */ | 60 | /* version_major=1, version_minor=0 */ |
61 | struct ta_firmware_header_v1_0 { | ||
62 | struct common_firmware_header header; | ||
63 | uint32_t ta_xgmi_ucode_version; | ||
64 | uint32_t ta_xgmi_offset_bytes; | ||
65 | uint32_t ta_xgmi_size_bytes; | ||
66 | uint32_t ta_ras_ucode_version; | ||
67 | uint32_t ta_ras_offset_bytes; | ||
68 | uint32_t ta_ras_size_bytes; | ||
69 | }; | ||
70 | |||
71 | /* version_major=1, version_minor=0 */ | ||
61 | struct gfx_firmware_header_v1_0 { | 72 | struct gfx_firmware_header_v1_0 { |
62 | struct common_firmware_header header; | 73 | struct common_firmware_header header; |
63 | uint32_t ucode_feature_version; | 74 | uint32_t ucode_feature_version; |
@@ -170,6 +181,7 @@ union amdgpu_firmware_header { | |||
170 | struct mc_firmware_header_v1_0 mc; | 181 | struct mc_firmware_header_v1_0 mc; |
171 | struct smc_firmware_header_v1_0 smc; | 182 | struct smc_firmware_header_v1_0 smc; |
172 | struct psp_firmware_header_v1_0 psp; | 183 | struct psp_firmware_header_v1_0 psp; |
184 | struct ta_firmware_header_v1_0 ta; | ||
173 | struct gfx_firmware_header_v1_0 gfx; | 185 | struct gfx_firmware_header_v1_0 gfx; |
174 | struct rlc_firmware_header_v1_0 rlc; | 186 | struct rlc_firmware_header_v1_0 rlc; |
175 | struct rlc_firmware_header_v2_0 rlc_v2_0; | 187 | struct rlc_firmware_header_v2_0 rlc_v2_0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index e5a6db6beab7..69896f451e8a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | |||
@@ -1243,30 +1243,20 @@ int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
1243 | { | 1243 | { |
1244 | struct dma_fence *fence; | 1244 | struct dma_fence *fence; |
1245 | long r; | 1245 | long r; |
1246 | uint32_t ip_instance = ring->me; | ||
1247 | 1246 | ||
1248 | r = amdgpu_uvd_get_create_msg(ring, 1, NULL); | 1247 | r = amdgpu_uvd_get_create_msg(ring, 1, NULL); |
1249 | if (r) { | 1248 | if (r) |
1250 | DRM_ERROR("amdgpu: (%d)failed to get create msg (%ld).\n", ip_instance, r); | ||
1251 | goto error; | 1249 | goto error; |
1252 | } | ||
1253 | 1250 | ||
1254 | r = amdgpu_uvd_get_destroy_msg(ring, 1, true, &fence); | 1251 | r = amdgpu_uvd_get_destroy_msg(ring, 1, true, &fence); |
1255 | if (r) { | 1252 | if (r) |
1256 | DRM_ERROR("amdgpu: (%d)failed to get destroy ib (%ld).\n", ip_instance, r); | ||
1257 | goto error; | 1253 | goto error; |
1258 | } | ||
1259 | 1254 | ||
1260 | r = dma_fence_wait_timeout(fence, false, timeout); | 1255 | r = dma_fence_wait_timeout(fence, false, timeout); |
1261 | if (r == 0) { | 1256 | if (r == 0) |
1262 | DRM_ERROR("amdgpu: (%d)IB test timed out.\n", ip_instance); | ||
1263 | r = -ETIMEDOUT; | 1257 | r = -ETIMEDOUT; |
1264 | } else if (r < 0) { | 1258 | else if (r > 0) |
1265 | DRM_ERROR("amdgpu: (%d)fence wait failed (%ld).\n", ip_instance, r); | ||
1266 | } else { | ||
1267 | DRM_DEBUG("ib test on (%d)ring %d succeeded\n", ip_instance, ring->idx); | ||
1268 | r = 0; | 1259 | r = 0; |
1269 | } | ||
1270 | 1260 | ||
1271 | dma_fence_put(fence); | 1261 | dma_fence_put(fence); |
1272 | 1262 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 5f3f54073818..98a1b2ce2b9d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | |||
@@ -1032,8 +1032,10 @@ out: | |||
1032 | * @ib: the IB to execute | 1032 | * @ib: the IB to execute |
1033 | * | 1033 | * |
1034 | */ | 1034 | */ |
1035 | void amdgpu_vce_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib, | 1035 | void amdgpu_vce_ring_emit_ib(struct amdgpu_ring *ring, |
1036 | unsigned vmid, bool ctx_switch) | 1036 | struct amdgpu_job *job, |
1037 | struct amdgpu_ib *ib, | ||
1038 | bool ctx_switch) | ||
1037 | { | 1039 | { |
1038 | amdgpu_ring_write(ring, VCE_CMD_IB); | 1040 | amdgpu_ring_write(ring, VCE_CMD_IB); |
1039 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); | 1041 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); |
@@ -1079,11 +1081,9 @@ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring) | |||
1079 | return 0; | 1081 | return 0; |
1080 | 1082 | ||
1081 | r = amdgpu_ring_alloc(ring, 16); | 1083 | r = amdgpu_ring_alloc(ring, 16); |
1082 | if (r) { | 1084 | if (r) |
1083 | DRM_ERROR("amdgpu: vce failed to lock ring %d (%d).\n", | ||
1084 | ring->idx, r); | ||
1085 | return r; | 1085 | return r; |
1086 | } | 1086 | |
1087 | amdgpu_ring_write(ring, VCE_CMD_END); | 1087 | amdgpu_ring_write(ring, VCE_CMD_END); |
1088 | amdgpu_ring_commit(ring); | 1088 | amdgpu_ring_commit(ring); |
1089 | 1089 | ||
@@ -1093,14 +1093,8 @@ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring) | |||
1093 | DRM_UDELAY(1); | 1093 | DRM_UDELAY(1); |
1094 | } | 1094 | } |
1095 | 1095 | ||
1096 | if (i < timeout) { | 1096 | if (i >= timeout) |
1097 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", | ||
1098 | ring->idx, i); | ||
1099 | } else { | ||
1100 | DRM_ERROR("amdgpu: ring %d test failed\n", | ||
1101 | ring->idx); | ||
1102 | r = -ETIMEDOUT; | 1097 | r = -ETIMEDOUT; |
1103 | } | ||
1104 | 1098 | ||
1105 | return r; | 1099 | return r; |
1106 | } | 1100 | } |
@@ -1121,27 +1115,19 @@ int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
1121 | return 0; | 1115 | return 0; |
1122 | 1116 | ||
1123 | r = amdgpu_vce_get_create_msg(ring, 1, NULL); | 1117 | r = amdgpu_vce_get_create_msg(ring, 1, NULL); |
1124 | if (r) { | 1118 | if (r) |
1125 | DRM_ERROR("amdgpu: failed to get create msg (%ld).\n", r); | ||
1126 | goto error; | 1119 | goto error; |
1127 | } | ||
1128 | 1120 | ||
1129 | r = amdgpu_vce_get_destroy_msg(ring, 1, true, &fence); | 1121 | r = amdgpu_vce_get_destroy_msg(ring, 1, true, &fence); |
1130 | if (r) { | 1122 | if (r) |
1131 | DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r); | ||
1132 | goto error; | 1123 | goto error; |
1133 | } | ||
1134 | 1124 | ||
1135 | r = dma_fence_wait_timeout(fence, false, timeout); | 1125 | r = dma_fence_wait_timeout(fence, false, timeout); |
1136 | if (r == 0) { | 1126 | if (r == 0) |
1137 | DRM_ERROR("amdgpu: IB test timed out.\n"); | ||
1138 | r = -ETIMEDOUT; | 1127 | r = -ETIMEDOUT; |
1139 | } else if (r < 0) { | 1128 | else if (r > 0) |
1140 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | ||
1141 | } else { | ||
1142 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | ||
1143 | r = 0; | 1129 | r = 0; |
1144 | } | 1130 | |
1145 | error: | 1131 | error: |
1146 | dma_fence_put(fence); | 1132 | dma_fence_put(fence); |
1147 | return r; | 1133 | return r; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h index a1f209eed4c4..50293652af14 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h | |||
@@ -65,8 +65,8 @@ int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, | |||
65 | void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp); | 65 | void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp); |
66 | int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx); | 66 | int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx); |
67 | int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p, uint32_t ib_idx); | 67 | int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p, uint32_t ib_idx); |
68 | void amdgpu_vce_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib, | 68 | void amdgpu_vce_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_job *job, |
69 | unsigned vmid, bool ctx_switch); | 69 | struct amdgpu_ib *ib, bool ctx_switch); |
70 | void amdgpu_vce_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, | 70 | void amdgpu_vce_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, |
71 | unsigned flags); | 71 | unsigned flags); |
72 | int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring); | 72 | int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 27da13df2f11..e2e42e3fbcf3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | |||
@@ -425,11 +425,9 @@ int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring) | |||
425 | 425 | ||
426 | WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0xCAFEDEAD); | 426 | WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0xCAFEDEAD); |
427 | r = amdgpu_ring_alloc(ring, 3); | 427 | r = amdgpu_ring_alloc(ring, 3); |
428 | if (r) { | 428 | if (r) |
429 | DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", | ||
430 | ring->idx, r); | ||
431 | return r; | 429 | return r; |
432 | } | 430 | |
433 | amdgpu_ring_write(ring, | 431 | amdgpu_ring_write(ring, |
434 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0)); | 432 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0)); |
435 | amdgpu_ring_write(ring, 0xDEADBEEF); | 433 | amdgpu_ring_write(ring, 0xDEADBEEF); |
@@ -441,14 +439,9 @@ int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring) | |||
441 | DRM_UDELAY(1); | 439 | DRM_UDELAY(1); |
442 | } | 440 | } |
443 | 441 | ||
444 | if (i < adev->usec_timeout) { | 442 | if (i >= adev->usec_timeout) |
445 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", | 443 | r = -ETIMEDOUT; |
446 | ring->idx, i); | 444 | |
447 | } else { | ||
448 | DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", | ||
449 | ring->idx, tmp); | ||
450 | r = -EINVAL; | ||
451 | } | ||
452 | return r; | 445 | return r; |
453 | } | 446 | } |
454 | 447 | ||
@@ -570,30 +563,20 @@ int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
570 | long r; | 563 | long r; |
571 | 564 | ||
572 | r = amdgpu_vcn_dec_get_create_msg(ring, 1, NULL); | 565 | r = amdgpu_vcn_dec_get_create_msg(ring, 1, NULL); |
573 | if (r) { | 566 | if (r) |
574 | DRM_ERROR("amdgpu: failed to get create msg (%ld).\n", r); | ||
575 | goto error; | 567 | goto error; |
576 | } | ||
577 | 568 | ||
578 | r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &fence); | 569 | r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &fence); |
579 | if (r) { | 570 | if (r) |
580 | DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r); | ||
581 | goto error; | 571 | goto error; |
582 | } | ||
583 | 572 | ||
584 | r = dma_fence_wait_timeout(fence, false, timeout); | 573 | r = dma_fence_wait_timeout(fence, false, timeout); |
585 | if (r == 0) { | 574 | if (r == 0) |
586 | DRM_ERROR("amdgpu: IB test timed out.\n"); | ||
587 | r = -ETIMEDOUT; | 575 | r = -ETIMEDOUT; |
588 | } else if (r < 0) { | 576 | else if (r > 0) |
589 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | ||
590 | } else { | ||
591 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | ||
592 | r = 0; | 577 | r = 0; |
593 | } | ||
594 | 578 | ||
595 | dma_fence_put(fence); | 579 | dma_fence_put(fence); |
596 | |||
597 | error: | 580 | error: |
598 | return r; | 581 | return r; |
599 | } | 582 | } |
@@ -606,11 +589,9 @@ int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring) | |||
606 | int r; | 589 | int r; |
607 | 590 | ||
608 | r = amdgpu_ring_alloc(ring, 16); | 591 | r = amdgpu_ring_alloc(ring, 16); |
609 | if (r) { | 592 | if (r) |
610 | DRM_ERROR("amdgpu: vcn enc failed to lock ring %d (%d).\n", | ||
611 | ring->idx, r); | ||
612 | return r; | 593 | return r; |
613 | } | 594 | |
614 | amdgpu_ring_write(ring, VCN_ENC_CMD_END); | 595 | amdgpu_ring_write(ring, VCN_ENC_CMD_END); |
615 | amdgpu_ring_commit(ring); | 596 | amdgpu_ring_commit(ring); |
616 | 597 | ||
@@ -620,14 +601,8 @@ int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring) | |||
620 | DRM_UDELAY(1); | 601 | DRM_UDELAY(1); |
621 | } | 602 | } |
622 | 603 | ||
623 | if (i < adev->usec_timeout) { | 604 | if (i >= adev->usec_timeout) |
624 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", | ||
625 | ring->idx, i); | ||
626 | } else { | ||
627 | DRM_ERROR("amdgpu: ring %d test failed\n", | ||
628 | ring->idx); | ||
629 | r = -ETIMEDOUT; | 605 | r = -ETIMEDOUT; |
630 | } | ||
631 | 606 | ||
632 | return r; | 607 | return r; |
633 | } | 608 | } |
@@ -742,27 +717,19 @@ int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
742 | long r; | 717 | long r; |
743 | 718 | ||
744 | r = amdgpu_vcn_enc_get_create_msg(ring, 1, NULL); | 719 | r = amdgpu_vcn_enc_get_create_msg(ring, 1, NULL); |
745 | if (r) { | 720 | if (r) |
746 | DRM_ERROR("amdgpu: failed to get create msg (%ld).\n", r); | ||
747 | goto error; | 721 | goto error; |
748 | } | ||
749 | 722 | ||
750 | r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, &fence); | 723 | r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, &fence); |
751 | if (r) { | 724 | if (r) |
752 | DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r); | ||
753 | goto error; | 725 | goto error; |
754 | } | ||
755 | 726 | ||
756 | r = dma_fence_wait_timeout(fence, false, timeout); | 727 | r = dma_fence_wait_timeout(fence, false, timeout); |
757 | if (r == 0) { | 728 | if (r == 0) |
758 | DRM_ERROR("amdgpu: IB test timed out.\n"); | ||
759 | r = -ETIMEDOUT; | 729 | r = -ETIMEDOUT; |
760 | } else if (r < 0) { | 730 | else if (r > 0) |
761 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | ||
762 | } else { | ||
763 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | ||
764 | r = 0; | 731 | r = 0; |
765 | } | 732 | |
766 | error: | 733 | error: |
767 | dma_fence_put(fence); | 734 | dma_fence_put(fence); |
768 | return r; | 735 | return r; |
@@ -778,11 +745,8 @@ int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring) | |||
778 | WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0xCAFEDEAD); | 745 | WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0xCAFEDEAD); |
779 | r = amdgpu_ring_alloc(ring, 3); | 746 | r = amdgpu_ring_alloc(ring, 3); |
780 | 747 | ||
781 | if (r) { | 748 | if (r) |
782 | DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", | ||
783 | ring->idx, r); | ||
784 | return r; | 749 | return r; |
785 | } | ||
786 | 750 | ||
787 | amdgpu_ring_write(ring, | 751 | amdgpu_ring_write(ring, |
788 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0, 0, 0)); | 752 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0, 0, 0)); |
@@ -796,14 +760,8 @@ int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring) | |||
796 | DRM_UDELAY(1); | 760 | DRM_UDELAY(1); |
797 | } | 761 | } |
798 | 762 | ||
799 | if (i < adev->usec_timeout) { | 763 | if (i >= adev->usec_timeout) |
800 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", | 764 | r = -ETIMEDOUT; |
801 | ring->idx, i); | ||
802 | } else { | ||
803 | DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", | ||
804 | ring->idx, tmp); | ||
805 | r = -EINVAL; | ||
806 | } | ||
807 | 765 | ||
808 | return r; | 766 | return r; |
809 | } | 767 | } |
@@ -856,21 +814,18 @@ int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
856 | long r = 0; | 814 | long r = 0; |
857 | 815 | ||
858 | r = amdgpu_vcn_jpeg_set_reg(ring, 1, &fence); | 816 | r = amdgpu_vcn_jpeg_set_reg(ring, 1, &fence); |
859 | if (r) { | 817 | if (r) |
860 | DRM_ERROR("amdgpu: failed to set jpeg register (%ld).\n", r); | ||
861 | goto error; | 818 | goto error; |
862 | } | ||
863 | 819 | ||
864 | r = dma_fence_wait_timeout(fence, false, timeout); | 820 | r = dma_fence_wait_timeout(fence, false, timeout); |
865 | if (r == 0) { | 821 | if (r == 0) { |
866 | DRM_ERROR("amdgpu: IB test timed out.\n"); | ||
867 | r = -ETIMEDOUT; | 822 | r = -ETIMEDOUT; |
868 | goto error; | 823 | goto error; |
869 | } else if (r < 0) { | 824 | } else if (r < 0) { |
870 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | ||
871 | goto error; | 825 | goto error; |
872 | } else | 826 | } else { |
873 | r = 0; | 827 | r = 0; |
828 | } | ||
874 | 829 | ||
875 | for (i = 0; i < adev->usec_timeout; i++) { | 830 | for (i = 0; i < adev->usec_timeout; i++) { |
876 | tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9)); | 831 | tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9)); |
@@ -879,15 +834,10 @@ int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
879 | DRM_UDELAY(1); | 834 | DRM_UDELAY(1); |
880 | } | 835 | } |
881 | 836 | ||
882 | if (i < adev->usec_timeout) | 837 | if (i >= adev->usec_timeout) |
883 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | 838 | r = -ETIMEDOUT; |
884 | else { | ||
885 | DRM_ERROR("ib test failed (0x%08X)\n", tmp); | ||
886 | r = -EINVAL; | ||
887 | } | ||
888 | 839 | ||
889 | dma_fence_put(fence); | 840 | dma_fence_put(fence); |
890 | |||
891 | error: | 841 | error: |
892 | return r; | 842 | return r; |
893 | } | 843 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index f2f358aa0597..cfee74732edb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | |||
@@ -23,16 +23,6 @@ | |||
23 | 23 | ||
24 | #include "amdgpu.h" | 24 | #include "amdgpu.h" |
25 | 25 | ||
26 | uint64_t amdgpu_csa_vaddr(struct amdgpu_device *adev) | ||
27 | { | ||
28 | uint64_t addr = adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT; | ||
29 | |||
30 | addr -= AMDGPU_VA_RESERVED_SIZE; | ||
31 | addr = amdgpu_gmc_sign_extend(addr); | ||
32 | |||
33 | return addr; | ||
34 | } | ||
35 | |||
36 | bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev) | 26 | bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev) |
37 | { | 27 | { |
38 | /* By now all MMIO pages except mailbox are blocked */ | 28 | /* By now all MMIO pages except mailbox are blocked */ |
@@ -41,88 +31,6 @@ bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev) | |||
41 | return RREG32_NO_KIQ(0xc040) == 0xffffffff; | 31 | return RREG32_NO_KIQ(0xc040) == 0xffffffff; |
42 | } | 32 | } |
43 | 33 | ||
44 | int amdgpu_allocate_static_csa(struct amdgpu_device *adev) | ||
45 | { | ||
46 | int r; | ||
47 | void *ptr; | ||
48 | |||
49 | r = amdgpu_bo_create_kernel(adev, AMDGPU_CSA_SIZE, PAGE_SIZE, | ||
50 | AMDGPU_GEM_DOMAIN_VRAM, &adev->virt.csa_obj, | ||
51 | &adev->virt.csa_vmid0_addr, &ptr); | ||
52 | if (r) | ||
53 | return r; | ||
54 | |||
55 | memset(ptr, 0, AMDGPU_CSA_SIZE); | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | void amdgpu_free_static_csa(struct amdgpu_device *adev) { | ||
60 | amdgpu_bo_free_kernel(&adev->virt.csa_obj, | ||
61 | &adev->virt.csa_vmid0_addr, | ||
62 | NULL); | ||
63 | } | ||
64 | |||
65 | /* | ||
66 | * amdgpu_map_static_csa should be called during amdgpu_vm_init | ||
67 | * it maps virtual address amdgpu_csa_vaddr() to this VM, and each command | ||
68 | * submission of GFX should use this virtual address within META_DATA init | ||
69 | * package to support SRIOV gfx preemption. | ||
70 | */ | ||
71 | int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, | ||
72 | struct amdgpu_bo_va **bo_va) | ||
73 | { | ||
74 | uint64_t csa_addr = amdgpu_csa_vaddr(adev) & AMDGPU_GMC_HOLE_MASK; | ||
75 | struct ww_acquire_ctx ticket; | ||
76 | struct list_head list; | ||
77 | struct amdgpu_bo_list_entry pd; | ||
78 | struct ttm_validate_buffer csa_tv; | ||
79 | int r; | ||
80 | |||
81 | INIT_LIST_HEAD(&list); | ||
82 | INIT_LIST_HEAD(&csa_tv.head); | ||
83 | csa_tv.bo = &adev->virt.csa_obj->tbo; | ||
84 | csa_tv.shared = true; | ||
85 | |||
86 | list_add(&csa_tv.head, &list); | ||
87 | amdgpu_vm_get_pd_bo(vm, &list, &pd); | ||
88 | |||
89 | r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL); | ||
90 | if (r) { | ||
91 | DRM_ERROR("failed to reserve CSA,PD BOs: err=%d\n", r); | ||
92 | return r; | ||
93 | } | ||
94 | |||
95 | *bo_va = amdgpu_vm_bo_add(adev, vm, adev->virt.csa_obj); | ||
96 | if (!*bo_va) { | ||
97 | ttm_eu_backoff_reservation(&ticket, &list); | ||
98 | DRM_ERROR("failed to create bo_va for static CSA\n"); | ||
99 | return -ENOMEM; | ||
100 | } | ||
101 | |||
102 | r = amdgpu_vm_alloc_pts(adev, (*bo_va)->base.vm, csa_addr, | ||
103 | AMDGPU_CSA_SIZE); | ||
104 | if (r) { | ||
105 | DRM_ERROR("failed to allocate pts for static CSA, err=%d\n", r); | ||
106 | amdgpu_vm_bo_rmv(adev, *bo_va); | ||
107 | ttm_eu_backoff_reservation(&ticket, &list); | ||
108 | return r; | ||
109 | } | ||
110 | |||
111 | r = amdgpu_vm_bo_map(adev, *bo_va, csa_addr, 0, AMDGPU_CSA_SIZE, | ||
112 | AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE | | ||
113 | AMDGPU_PTE_EXECUTABLE); | ||
114 | |||
115 | if (r) { | ||
116 | DRM_ERROR("failed to do bo_map on static CSA, err=%d\n", r); | ||
117 | amdgpu_vm_bo_rmv(adev, *bo_va); | ||
118 | ttm_eu_backoff_reservation(&ticket, &list); | ||
119 | return r; | ||
120 | } | ||
121 | |||
122 | ttm_eu_backoff_reservation(&ticket, &list); | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | void amdgpu_virt_init_setting(struct amdgpu_device *adev) | 34 | void amdgpu_virt_init_setting(struct amdgpu_device *adev) |
127 | { | 35 | { |
128 | /* enable virtual display */ | 36 | /* enable virtual display */ |
@@ -162,9 +70,7 @@ uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg) | |||
162 | if (r < 1 && (adev->in_gpu_reset || in_interrupt())) | 70 | if (r < 1 && (adev->in_gpu_reset || in_interrupt())) |
163 | goto failed_kiq_read; | 71 | goto failed_kiq_read; |
164 | 72 | ||
165 | if (in_interrupt()) | 73 | might_sleep(); |
166 | might_sleep(); | ||
167 | |||
168 | while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) { | 74 | while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) { |
169 | msleep(MAX_KIQ_REG_BAILOUT_INTERVAL); | 75 | msleep(MAX_KIQ_REG_BAILOUT_INTERVAL); |
170 | r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); | 76 | r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); |
@@ -210,9 +116,7 @@ void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v) | |||
210 | if (r < 1 && (adev->in_gpu_reset || in_interrupt())) | 116 | if (r < 1 && (adev->in_gpu_reset || in_interrupt())) |
211 | goto failed_kiq_write; | 117 | goto failed_kiq_write; |
212 | 118 | ||
213 | if (in_interrupt()) | 119 | might_sleep(); |
214 | might_sleep(); | ||
215 | |||
216 | while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) { | 120 | while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) { |
217 | 121 | ||
218 | msleep(MAX_KIQ_REG_BAILOUT_INTERVAL); | 122 | msleep(MAX_KIQ_REG_BAILOUT_INTERVAL); |
@@ -228,6 +132,46 @@ failed_kiq_write: | |||
228 | pr_err("failed to write reg:%x\n", reg); | 132 | pr_err("failed to write reg:%x\n", reg); |
229 | } | 133 | } |
230 | 134 | ||
135 | void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev, | ||
136 | uint32_t reg0, uint32_t reg1, | ||
137 | uint32_t ref, uint32_t mask) | ||
138 | { | ||
139 | struct amdgpu_kiq *kiq = &adev->gfx.kiq; | ||
140 | struct amdgpu_ring *ring = &kiq->ring; | ||
141 | signed long r, cnt = 0; | ||
142 | unsigned long flags; | ||
143 | uint32_t seq; | ||
144 | |||
145 | spin_lock_irqsave(&kiq->ring_lock, flags); | ||
146 | amdgpu_ring_alloc(ring, 32); | ||
147 | amdgpu_ring_emit_reg_write_reg_wait(ring, reg0, reg1, | ||
148 | ref, mask); | ||
149 | amdgpu_fence_emit_polling(ring, &seq); | ||
150 | amdgpu_ring_commit(ring); | ||
151 | spin_unlock_irqrestore(&kiq->ring_lock, flags); | ||
152 | |||
153 | r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); | ||
154 | |||
155 | /* don't wait anymore for IRQ context */ | ||
156 | if (r < 1 && in_interrupt()) | ||
157 | goto failed_kiq; | ||
158 | |||
159 | might_sleep(); | ||
160 | while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) { | ||
161 | |||
162 | msleep(MAX_KIQ_REG_BAILOUT_INTERVAL); | ||
163 | r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); | ||
164 | } | ||
165 | |||
166 | if (cnt > MAX_KIQ_REG_TRY) | ||
167 | goto failed_kiq; | ||
168 | |||
169 | return; | ||
170 | |||
171 | failed_kiq: | ||
172 | pr_err("failed to write reg %x wait reg %x\n", reg0, reg1); | ||
173 | } | ||
174 | |||
231 | /** | 175 | /** |
232 | * amdgpu_virt_request_full_gpu() - request full gpu access | 176 | * amdgpu_virt_request_full_gpu() - request full gpu access |
233 | * @amdgpu: amdgpu device. | 177 | * @amdgpu: amdgpu device. |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h index 880ac113a3a9..0728fbc9a692 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | |||
@@ -238,7 +238,6 @@ typedef struct amdgim_vf2pf_info_v2 amdgim_vf2pf_info ; | |||
238 | struct amdgpu_virt { | 238 | struct amdgpu_virt { |
239 | uint32_t caps; | 239 | uint32_t caps; |
240 | struct amdgpu_bo *csa_obj; | 240 | struct amdgpu_bo *csa_obj; |
241 | uint64_t csa_vmid0_addr; | ||
242 | bool chained_ib_support; | 241 | bool chained_ib_support; |
243 | uint32_t reg_val_offs; | 242 | uint32_t reg_val_offs; |
244 | struct amdgpu_irq_src ack_irq; | 243 | struct amdgpu_irq_src ack_irq; |
@@ -251,8 +250,6 @@ struct amdgpu_virt { | |||
251 | uint32_t gim_feature; | 250 | uint32_t gim_feature; |
252 | }; | 251 | }; |
253 | 252 | ||
254 | #define AMDGPU_CSA_SIZE (8 * 1024) | ||
255 | |||
256 | #define amdgpu_sriov_enabled(adev) \ | 253 | #define amdgpu_sriov_enabled(adev) \ |
257 | ((adev)->virt.caps & AMDGPU_SRIOV_CAPS_ENABLE_IOV) | 254 | ((adev)->virt.caps & AMDGPU_SRIOV_CAPS_ENABLE_IOV) |
258 | 255 | ||
@@ -277,17 +274,13 @@ static inline bool is_virtual_machine(void) | |||
277 | #endif | 274 | #endif |
278 | } | 275 | } |
279 | 276 | ||
280 | struct amdgpu_vm; | ||
281 | |||
282 | uint64_t amdgpu_csa_vaddr(struct amdgpu_device *adev); | ||
283 | bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev); | 277 | bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev); |
284 | int amdgpu_allocate_static_csa(struct amdgpu_device *adev); | ||
285 | int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, | ||
286 | struct amdgpu_bo_va **bo_va); | ||
287 | void amdgpu_free_static_csa(struct amdgpu_device *adev); | ||
288 | void amdgpu_virt_init_setting(struct amdgpu_device *adev); | 278 | void amdgpu_virt_init_setting(struct amdgpu_device *adev); |
289 | uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg); | 279 | uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg); |
290 | void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v); | 280 | void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v); |
281 | void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev, | ||
282 | uint32_t reg0, uint32_t rreg1, | ||
283 | uint32_t ref, uint32_t mask); | ||
291 | int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init); | 284 | int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init); |
292 | int amdgpu_virt_release_full_gpu(struct amdgpu_device *adev, bool init); | 285 | int amdgpu_virt_release_full_gpu(struct amdgpu_device *adev, bool init); |
293 | int amdgpu_virt_reset_gpu(struct amdgpu_device *adev); | 286 | int amdgpu_virt_reset_gpu(struct amdgpu_device *adev); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index d6c47972062a..58a2363040dd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -1632,13 +1632,6 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params, | |||
1632 | continue; | 1632 | continue; |
1633 | } | 1633 | } |
1634 | 1634 | ||
1635 | /* First check if the entry is already handled */ | ||
1636 | if (cursor.pfn < frag_start) { | ||
1637 | cursor.entry->huge = true; | ||
1638 | amdgpu_vm_pt_next(adev, &cursor); | ||
1639 | continue; | ||
1640 | } | ||
1641 | |||
1642 | /* If it isn't already handled it can't be a huge page */ | 1635 | /* If it isn't already handled it can't be a huge page */ |
1643 | if (cursor.entry->huge) { | 1636 | if (cursor.entry->huge) { |
1644 | /* Add the entry to the relocated list to update it. */ | 1637 | /* Add the entry to the relocated list to update it. */ |
@@ -1701,8 +1694,17 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params, | |||
1701 | } | 1694 | } |
1702 | } while (frag_start < entry_end); | 1695 | } while (frag_start < entry_end); |
1703 | 1696 | ||
1704 | if (frag >= shift) | 1697 | if (amdgpu_vm_pt_descendant(adev, &cursor)) { |
1698 | /* Mark all child entries as huge */ | ||
1699 | while (cursor.pfn < frag_start) { | ||
1700 | cursor.entry->huge = true; | ||
1701 | amdgpu_vm_pt_next(adev, &cursor); | ||
1702 | } | ||
1703 | |||
1704 | } else if (frag >= shift) { | ||
1705 | /* or just move on to the next on the same level. */ | ||
1705 | amdgpu_vm_pt_next(adev, &cursor); | 1706 | amdgpu_vm_pt_next(adev, &cursor); |
1707 | } | ||
1706 | } | 1708 | } |
1707 | 1709 | ||
1708 | return 0; | 1710 | return 0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c index 897afbb348c1..909216a9b447 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | |||
@@ -63,7 +63,7 @@ static struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev) | |||
63 | 63 | ||
64 | int amdgpu_xgmi_add_device(struct amdgpu_device *adev) | 64 | int amdgpu_xgmi_add_device(struct amdgpu_device *adev) |
65 | { | 65 | { |
66 | struct psp_xgmi_topology_info tmp_topology[AMDGPU_MAX_XGMI_DEVICE_PER_HIVE]; | 66 | struct psp_xgmi_topology_info *tmp_topology; |
67 | struct amdgpu_hive_info *hive; | 67 | struct amdgpu_hive_info *hive; |
68 | struct amdgpu_xgmi *entry; | 68 | struct amdgpu_xgmi *entry; |
69 | struct amdgpu_device *tmp_adev; | 69 | struct amdgpu_device *tmp_adev; |
@@ -73,10 +73,12 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev) | |||
73 | if ((adev->asic_type < CHIP_VEGA20) || | 73 | if ((adev->asic_type < CHIP_VEGA20) || |
74 | (adev->flags & AMD_IS_APU) ) | 74 | (adev->flags & AMD_IS_APU) ) |
75 | return 0; | 75 | return 0; |
76 | adev->gmc.xgmi.device_id = psp_xgmi_get_device_id(&adev->psp); | 76 | adev->gmc.xgmi.node_id = psp_xgmi_get_node_id(&adev->psp); |
77 | adev->gmc.xgmi.hive_id = psp_xgmi_get_hive_id(&adev->psp); | 77 | adev->gmc.xgmi.hive_id = psp_xgmi_get_hive_id(&adev->psp); |
78 | 78 | ||
79 | memset(&tmp_topology[0], 0, sizeof(tmp_topology)); | 79 | tmp_topology = kzalloc(sizeof(struct psp_xgmi_topology_info), GFP_KERNEL); |
80 | if (!tmp_topology) | ||
81 | return -ENOMEM; | ||
80 | mutex_lock(&xgmi_mutex); | 82 | mutex_lock(&xgmi_mutex); |
81 | hive = amdgpu_get_xgmi_hive(adev); | 83 | hive = amdgpu_get_xgmi_hive(adev); |
82 | if (!hive) | 84 | if (!hive) |
@@ -84,23 +86,28 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev) | |||
84 | 86 | ||
85 | list_add_tail(&adev->gmc.xgmi.head, &hive->device_list); | 87 | list_add_tail(&adev->gmc.xgmi.head, &hive->device_list); |
86 | list_for_each_entry(entry, &hive->device_list, head) | 88 | list_for_each_entry(entry, &hive->device_list, head) |
87 | tmp_topology[count++].device_id = entry->device_id; | 89 | tmp_topology->nodes[count++].node_id = entry->node_id; |
88 | 90 | ||
89 | ret = psp_xgmi_get_topology_info(&adev->psp, count, tmp_topology); | 91 | /* Each psp need to get the latest topology */ |
90 | if (ret) { | 92 | list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) { |
91 | dev_err(adev->dev, | 93 | ret = psp_xgmi_get_topology_info(&tmp_adev->psp, count, tmp_topology); |
92 | "XGMI: Get topology failure on device %llx, hive %llx, ret %d", | 94 | if (ret) { |
93 | adev->gmc.xgmi.device_id, | 95 | dev_err(tmp_adev->dev, |
94 | adev->gmc.xgmi.hive_id, ret); | 96 | "XGMI: Get topology failure on device %llx, hive %llx, ret %d", |
95 | goto exit; | 97 | tmp_adev->gmc.xgmi.node_id, |
98 | tmp_adev->gmc.xgmi.hive_id, ret); | ||
99 | /* To do : continue with some node failed or disable the whole hive */ | ||
100 | break; | ||
101 | } | ||
96 | } | 102 | } |
103 | |||
97 | /* Each psp need to set the latest topology */ | 104 | /* Each psp need to set the latest topology */ |
98 | list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) { | 105 | list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) { |
99 | ret = psp_xgmi_set_topology_info(&tmp_adev->psp, count, tmp_topology); | 106 | ret = psp_xgmi_set_topology_info(&tmp_adev->psp, count, tmp_topology); |
100 | if (ret) { | 107 | if (ret) { |
101 | dev_err(tmp_adev->dev, | 108 | dev_err(tmp_adev->dev, |
102 | "XGMI: Set topology failure on device %llx, hive %llx, ret %d", | 109 | "XGMI: Set topology failure on device %llx, hive %llx, ret %d", |
103 | tmp_adev->gmc.xgmi.device_id, | 110 | tmp_adev->gmc.xgmi.node_id, |
104 | tmp_adev->gmc.xgmi.hive_id, ret); | 111 | tmp_adev->gmc.xgmi.hive_id, ret); |
105 | /* To do : continue with some node failed or disable the whole hive */ | 112 | /* To do : continue with some node failed or disable the whole hive */ |
106 | break; | 113 | break; |
@@ -113,7 +120,6 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev) | |||
113 | 120 | ||
114 | exit: | 121 | exit: |
115 | mutex_unlock(&xgmi_mutex); | 122 | mutex_unlock(&xgmi_mutex); |
123 | kfree(tmp_topology); | ||
116 | return ret; | 124 | return ret; |
117 | } | 125 | } |
118 | |||
119 | |||
diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index 79220a91abe3..86e14c754dd4 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c | |||
@@ -743,19 +743,19 @@ static int ci_enable_didt(struct amdgpu_device *adev, bool enable) | |||
743 | 743 | ||
744 | if (pi->caps_sq_ramping || pi->caps_db_ramping || | 744 | if (pi->caps_sq_ramping || pi->caps_db_ramping || |
745 | pi->caps_td_ramping || pi->caps_tcp_ramping) { | 745 | pi->caps_td_ramping || pi->caps_tcp_ramping) { |
746 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 746 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
747 | 747 | ||
748 | if (enable) { | 748 | if (enable) { |
749 | ret = ci_program_pt_config_registers(adev, didt_config_ci); | 749 | ret = ci_program_pt_config_registers(adev, didt_config_ci); |
750 | if (ret) { | 750 | if (ret) { |
751 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 751 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
752 | return ret; | 752 | return ret; |
753 | } | 753 | } |
754 | } | 754 | } |
755 | 755 | ||
756 | ci_do_enable_didt(adev, enable); | 756 | ci_do_enable_didt(adev, enable); |
757 | 757 | ||
758 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 758 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
759 | } | 759 | } |
760 | 760 | ||
761 | return 0; | 761 | return 0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index b918c8886b75..45795191de1f 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c | |||
@@ -198,7 +198,7 @@ static void cik_sdma_ring_set_wptr(struct amdgpu_ring *ring) | |||
198 | 198 | ||
199 | static void cik_sdma_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) | 199 | static void cik_sdma_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) |
200 | { | 200 | { |
201 | struct amdgpu_sdma_instance *sdma = amdgpu_get_sdma_instance(ring); | 201 | struct amdgpu_sdma_instance *sdma = amdgpu_sdma_get_instance_from_ring(ring); |
202 | int i; | 202 | int i; |
203 | 203 | ||
204 | for (i = 0; i < count; i++) | 204 | for (i = 0; i < count; i++) |
@@ -218,9 +218,11 @@ static void cik_sdma_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) | |||
218 | * Schedule an IB in the DMA ring (CIK). | 218 | * Schedule an IB in the DMA ring (CIK). |
219 | */ | 219 | */ |
220 | static void cik_sdma_ring_emit_ib(struct amdgpu_ring *ring, | 220 | static void cik_sdma_ring_emit_ib(struct amdgpu_ring *ring, |
221 | struct amdgpu_job *job, | ||
221 | struct amdgpu_ib *ib, | 222 | struct amdgpu_ib *ib, |
222 | unsigned vmid, bool ctx_switch) | 223 | bool ctx_switch) |
223 | { | 224 | { |
225 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
224 | u32 extra_bits = vmid & 0xf; | 226 | u32 extra_bits = vmid & 0xf; |
225 | 227 | ||
226 | /* IB packet must end on a 8 DW boundary */ | 228 | /* IB packet must end on a 8 DW boundary */ |
@@ -316,8 +318,8 @@ static void cik_sdma_gfx_stop(struct amdgpu_device *adev) | |||
316 | WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i], rb_cntl); | 318 | WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i], rb_cntl); |
317 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], 0); | 319 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], 0); |
318 | } | 320 | } |
319 | sdma0->ready = false; | 321 | sdma0->sched.ready = false; |
320 | sdma1->ready = false; | 322 | sdma1->sched.ready = false; |
321 | } | 323 | } |
322 | 324 | ||
323 | /** | 325 | /** |
@@ -494,18 +496,16 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev) | |||
494 | /* enable DMA IBs */ | 496 | /* enable DMA IBs */ |
495 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); | 497 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
496 | 498 | ||
497 | ring->ready = true; | 499 | ring->sched.ready = true; |
498 | } | 500 | } |
499 | 501 | ||
500 | cik_sdma_enable(adev, true); | 502 | cik_sdma_enable(adev, true); |
501 | 503 | ||
502 | for (i = 0; i < adev->sdma.num_instances; i++) { | 504 | for (i = 0; i < adev->sdma.num_instances; i++) { |
503 | ring = &adev->sdma.instance[i].ring; | 505 | ring = &adev->sdma.instance[i].ring; |
504 | r = amdgpu_ring_test_ring(ring); | 506 | r = amdgpu_ring_test_helper(ring); |
505 | if (r) { | 507 | if (r) |
506 | ring->ready = false; | ||
507 | return r; | 508 | return r; |
508 | } | ||
509 | 509 | ||
510 | if (adev->mman.buffer_funcs_ring == ring) | 510 | if (adev->mman.buffer_funcs_ring == ring) |
511 | amdgpu_ttm_set_buffer_funcs_status(adev, true); | 511 | amdgpu_ttm_set_buffer_funcs_status(adev, true); |
@@ -618,21 +618,17 @@ static int cik_sdma_ring_test_ring(struct amdgpu_ring *ring) | |||
618 | u64 gpu_addr; | 618 | u64 gpu_addr; |
619 | 619 | ||
620 | r = amdgpu_device_wb_get(adev, &index); | 620 | r = amdgpu_device_wb_get(adev, &index); |
621 | if (r) { | 621 | if (r) |
622 | dev_err(adev->dev, "(%d) failed to allocate wb slot\n", r); | ||
623 | return r; | 622 | return r; |
624 | } | ||
625 | 623 | ||
626 | gpu_addr = adev->wb.gpu_addr + (index * 4); | 624 | gpu_addr = adev->wb.gpu_addr + (index * 4); |
627 | tmp = 0xCAFEDEAD; | 625 | tmp = 0xCAFEDEAD; |
628 | adev->wb.wb[index] = cpu_to_le32(tmp); | 626 | adev->wb.wb[index] = cpu_to_le32(tmp); |
629 | 627 | ||
630 | r = amdgpu_ring_alloc(ring, 5); | 628 | r = amdgpu_ring_alloc(ring, 5); |
631 | if (r) { | 629 | if (r) |
632 | DRM_ERROR("amdgpu: dma failed to lock ring %d (%d).\n", ring->idx, r); | 630 | goto error_free_wb; |
633 | amdgpu_device_wb_free(adev, index); | 631 | |
634 | return r; | ||
635 | } | ||
636 | amdgpu_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0)); | 632 | amdgpu_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0)); |
637 | amdgpu_ring_write(ring, lower_32_bits(gpu_addr)); | 633 | amdgpu_ring_write(ring, lower_32_bits(gpu_addr)); |
638 | amdgpu_ring_write(ring, upper_32_bits(gpu_addr)); | 634 | amdgpu_ring_write(ring, upper_32_bits(gpu_addr)); |
@@ -647,15 +643,11 @@ static int cik_sdma_ring_test_ring(struct amdgpu_ring *ring) | |||
647 | DRM_UDELAY(1); | 643 | DRM_UDELAY(1); |
648 | } | 644 | } |
649 | 645 | ||
650 | if (i < adev->usec_timeout) { | 646 | if (i >= adev->usec_timeout) |
651 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", ring->idx, i); | 647 | r = -ETIMEDOUT; |
652 | } else { | ||
653 | DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", | ||
654 | ring->idx, tmp); | ||
655 | r = -EINVAL; | ||
656 | } | ||
657 | amdgpu_device_wb_free(adev, index); | ||
658 | 648 | ||
649 | error_free_wb: | ||
650 | amdgpu_device_wb_free(adev, index); | ||
659 | return r; | 651 | return r; |
660 | } | 652 | } |
661 | 653 | ||
@@ -678,20 +670,16 @@ static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
678 | long r; | 670 | long r; |
679 | 671 | ||
680 | r = amdgpu_device_wb_get(adev, &index); | 672 | r = amdgpu_device_wb_get(adev, &index); |
681 | if (r) { | 673 | if (r) |
682 | dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r); | ||
683 | return r; | 674 | return r; |
684 | } | ||
685 | 675 | ||
686 | gpu_addr = adev->wb.gpu_addr + (index * 4); | 676 | gpu_addr = adev->wb.gpu_addr + (index * 4); |
687 | tmp = 0xCAFEDEAD; | 677 | tmp = 0xCAFEDEAD; |
688 | adev->wb.wb[index] = cpu_to_le32(tmp); | 678 | adev->wb.wb[index] = cpu_to_le32(tmp); |
689 | memset(&ib, 0, sizeof(ib)); | 679 | memset(&ib, 0, sizeof(ib)); |
690 | r = amdgpu_ib_get(adev, NULL, 256, &ib); | 680 | r = amdgpu_ib_get(adev, NULL, 256, &ib); |
691 | if (r) { | 681 | if (r) |
692 | DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r); | ||
693 | goto err0; | 682 | goto err0; |
694 | } | ||
695 | 683 | ||
696 | ib.ptr[0] = SDMA_PACKET(SDMA_OPCODE_WRITE, | 684 | ib.ptr[0] = SDMA_PACKET(SDMA_OPCODE_WRITE, |
697 | SDMA_WRITE_SUB_OPCODE_LINEAR, 0); | 685 | SDMA_WRITE_SUB_OPCODE_LINEAR, 0); |
@@ -706,21 +694,16 @@ static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
706 | 694 | ||
707 | r = dma_fence_wait_timeout(f, false, timeout); | 695 | r = dma_fence_wait_timeout(f, false, timeout); |
708 | if (r == 0) { | 696 | if (r == 0) { |
709 | DRM_ERROR("amdgpu: IB test timed out\n"); | ||
710 | r = -ETIMEDOUT; | 697 | r = -ETIMEDOUT; |
711 | goto err1; | 698 | goto err1; |
712 | } else if (r < 0) { | 699 | } else if (r < 0) { |
713 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | ||
714 | goto err1; | 700 | goto err1; |
715 | } | 701 | } |
716 | tmp = le32_to_cpu(adev->wb.wb[index]); | 702 | tmp = le32_to_cpu(adev->wb.wb[index]); |
717 | if (tmp == 0xDEADBEEF) { | 703 | if (tmp == 0xDEADBEEF) |
718 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | ||
719 | r = 0; | 704 | r = 0; |
720 | } else { | 705 | else |
721 | DRM_ERROR("amdgpu: ib test failed (0x%08X)\n", tmp); | ||
722 | r = -EINVAL; | 706 | r = -EINVAL; |
723 | } | ||
724 | 707 | ||
725 | err1: | 708 | err1: |
726 | amdgpu_ib_free(adev, &ib, NULL); | 709 | amdgpu_ib_free(adev, &ib, NULL); |
@@ -822,7 +805,7 @@ static void cik_sdma_vm_set_pte_pde(struct amdgpu_ib *ib, uint64_t pe, | |||
822 | */ | 805 | */ |
823 | static void cik_sdma_ring_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) | 806 | static void cik_sdma_ring_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) |
824 | { | 807 | { |
825 | struct amdgpu_sdma_instance *sdma = amdgpu_get_sdma_instance(ring); | 808 | struct amdgpu_sdma_instance *sdma = amdgpu_sdma_get_instance_from_ring(ring); |
826 | u32 pad_count; | 809 | u32 pad_count; |
827 | int i; | 810 | int i; |
828 | 811 | ||
@@ -1214,8 +1197,11 @@ static int cik_sdma_process_illegal_inst_irq(struct amdgpu_device *adev, | |||
1214 | struct amdgpu_irq_src *source, | 1197 | struct amdgpu_irq_src *source, |
1215 | struct amdgpu_iv_entry *entry) | 1198 | struct amdgpu_iv_entry *entry) |
1216 | { | 1199 | { |
1200 | u8 instance_id; | ||
1201 | |||
1217 | DRM_ERROR("Illegal instruction in SDMA command stream\n"); | 1202 | DRM_ERROR("Illegal instruction in SDMA command stream\n"); |
1218 | schedule_work(&adev->reset_work); | 1203 | instance_id = (entry->ring_id & 0x3) >> 0; |
1204 | drm_sched_fault(&adev->sdma.instance[instance_id].ring.sched); | ||
1219 | return 0; | 1205 | return 0; |
1220 | } | 1206 | } |
1221 | 1207 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c index d76eb27945dc..1dc3013ea1d5 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c | |||
@@ -1775,18 +1775,15 @@ static int gfx_v6_0_ring_test_ring(struct amdgpu_ring *ring) | |||
1775 | int r; | 1775 | int r; |
1776 | 1776 | ||
1777 | r = amdgpu_gfx_scratch_get(adev, &scratch); | 1777 | r = amdgpu_gfx_scratch_get(adev, &scratch); |
1778 | if (r) { | 1778 | if (r) |
1779 | DRM_ERROR("amdgpu: cp failed to get scratch reg (%d).\n", r); | ||
1780 | return r; | 1779 | return r; |
1781 | } | 1780 | |
1782 | WREG32(scratch, 0xCAFEDEAD); | 1781 | WREG32(scratch, 0xCAFEDEAD); |
1783 | 1782 | ||
1784 | r = amdgpu_ring_alloc(ring, 3); | 1783 | r = amdgpu_ring_alloc(ring, 3); |
1785 | if (r) { | 1784 | if (r) |
1786 | DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", ring->idx, r); | 1785 | goto error_free_scratch; |
1787 | amdgpu_gfx_scratch_free(adev, scratch); | 1786 | |
1788 | return r; | ||
1789 | } | ||
1790 | amdgpu_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 1787 | amdgpu_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
1791 | amdgpu_ring_write(ring, (scratch - PACKET3_SET_CONFIG_REG_START)); | 1788 | amdgpu_ring_write(ring, (scratch - PACKET3_SET_CONFIG_REG_START)); |
1792 | amdgpu_ring_write(ring, 0xDEADBEEF); | 1789 | amdgpu_ring_write(ring, 0xDEADBEEF); |
@@ -1798,13 +1795,11 @@ static int gfx_v6_0_ring_test_ring(struct amdgpu_ring *ring) | |||
1798 | break; | 1795 | break; |
1799 | DRM_UDELAY(1); | 1796 | DRM_UDELAY(1); |
1800 | } | 1797 | } |
1801 | if (i < adev->usec_timeout) { | 1798 | |
1802 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", ring->idx, i); | 1799 | if (i >= adev->usec_timeout) |
1803 | } else { | 1800 | r = -ETIMEDOUT; |
1804 | DRM_ERROR("amdgpu: ring %d test failed (scratch(0x%04X)=0x%08X)\n", | 1801 | |
1805 | ring->idx, scratch, tmp); | 1802 | error_free_scratch: |
1806 | r = -EINVAL; | ||
1807 | } | ||
1808 | amdgpu_gfx_scratch_free(adev, scratch); | 1803 | amdgpu_gfx_scratch_free(adev, scratch); |
1809 | return r; | 1804 | return r; |
1810 | } | 1805 | } |
@@ -1845,9 +1840,11 @@ static void gfx_v6_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, | |||
1845 | } | 1840 | } |
1846 | 1841 | ||
1847 | static void gfx_v6_0_ring_emit_ib(struct amdgpu_ring *ring, | 1842 | static void gfx_v6_0_ring_emit_ib(struct amdgpu_ring *ring, |
1843 | struct amdgpu_job *job, | ||
1848 | struct amdgpu_ib *ib, | 1844 | struct amdgpu_ib *ib, |
1849 | unsigned vmid, bool ctx_switch) | 1845 | bool ctx_switch) |
1850 | { | 1846 | { |
1847 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
1851 | u32 header, control = 0; | 1848 | u32 header, control = 0; |
1852 | 1849 | ||
1853 | /* insert SWITCH_BUFFER packet before first IB in the ring frame */ | 1850 | /* insert SWITCH_BUFFER packet before first IB in the ring frame */ |
@@ -1892,17 +1889,15 @@ static int gfx_v6_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
1892 | long r; | 1889 | long r; |
1893 | 1890 | ||
1894 | r = amdgpu_gfx_scratch_get(adev, &scratch); | 1891 | r = amdgpu_gfx_scratch_get(adev, &scratch); |
1895 | if (r) { | 1892 | if (r) |
1896 | DRM_ERROR("amdgpu: failed to get scratch reg (%ld).\n", r); | ||
1897 | return r; | 1893 | return r; |
1898 | } | 1894 | |
1899 | WREG32(scratch, 0xCAFEDEAD); | 1895 | WREG32(scratch, 0xCAFEDEAD); |
1900 | memset(&ib, 0, sizeof(ib)); | 1896 | memset(&ib, 0, sizeof(ib)); |
1901 | r = amdgpu_ib_get(adev, NULL, 256, &ib); | 1897 | r = amdgpu_ib_get(adev, NULL, 256, &ib); |
1902 | if (r) { | 1898 | if (r) |
1903 | DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r); | ||
1904 | goto err1; | 1899 | goto err1; |
1905 | } | 1900 | |
1906 | ib.ptr[0] = PACKET3(PACKET3_SET_CONFIG_REG, 1); | 1901 | ib.ptr[0] = PACKET3(PACKET3_SET_CONFIG_REG, 1); |
1907 | ib.ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_START)); | 1902 | ib.ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_START)); |
1908 | ib.ptr[2] = 0xDEADBEEF; | 1903 | ib.ptr[2] = 0xDEADBEEF; |
@@ -1914,22 +1909,16 @@ static int gfx_v6_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
1914 | 1909 | ||
1915 | r = dma_fence_wait_timeout(f, false, timeout); | 1910 | r = dma_fence_wait_timeout(f, false, timeout); |
1916 | if (r == 0) { | 1911 | if (r == 0) { |
1917 | DRM_ERROR("amdgpu: IB test timed out\n"); | ||
1918 | r = -ETIMEDOUT; | 1912 | r = -ETIMEDOUT; |
1919 | goto err2; | 1913 | goto err2; |
1920 | } else if (r < 0) { | 1914 | } else if (r < 0) { |
1921 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | ||
1922 | goto err2; | 1915 | goto err2; |
1923 | } | 1916 | } |
1924 | tmp = RREG32(scratch); | 1917 | tmp = RREG32(scratch); |
1925 | if (tmp == 0xDEADBEEF) { | 1918 | if (tmp == 0xDEADBEEF) |
1926 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | ||
1927 | r = 0; | 1919 | r = 0; |
1928 | } else { | 1920 | else |
1929 | DRM_ERROR("amdgpu: ib test failed (scratch(0x%04X)=0x%08X)\n", | ||
1930 | scratch, tmp); | ||
1931 | r = -EINVAL; | 1921 | r = -EINVAL; |
1932 | } | ||
1933 | 1922 | ||
1934 | err2: | 1923 | err2: |
1935 | amdgpu_ib_free(adev, &ib, NULL); | 1924 | amdgpu_ib_free(adev, &ib, NULL); |
@@ -1950,9 +1939,9 @@ static void gfx_v6_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable) | |||
1950 | CP_ME_CNTL__CE_HALT_MASK)); | 1939 | CP_ME_CNTL__CE_HALT_MASK)); |
1951 | WREG32(mmSCRATCH_UMSK, 0); | 1940 | WREG32(mmSCRATCH_UMSK, 0); |
1952 | for (i = 0; i < adev->gfx.num_gfx_rings; i++) | 1941 | for (i = 0; i < adev->gfx.num_gfx_rings; i++) |
1953 | adev->gfx.gfx_ring[i].ready = false; | 1942 | adev->gfx.gfx_ring[i].sched.ready = false; |
1954 | for (i = 0; i < adev->gfx.num_compute_rings; i++) | 1943 | for (i = 0; i < adev->gfx.num_compute_rings; i++) |
1955 | adev->gfx.compute_ring[i].ready = false; | 1944 | adev->gfx.compute_ring[i].sched.ready = false; |
1956 | } | 1945 | } |
1957 | udelay(50); | 1946 | udelay(50); |
1958 | } | 1947 | } |
@@ -2124,12 +2113,9 @@ static int gfx_v6_0_cp_gfx_resume(struct amdgpu_device *adev) | |||
2124 | 2113 | ||
2125 | /* start the rings */ | 2114 | /* start the rings */ |
2126 | gfx_v6_0_cp_gfx_start(adev); | 2115 | gfx_v6_0_cp_gfx_start(adev); |
2127 | ring->ready = true; | 2116 | r = amdgpu_ring_test_helper(ring); |
2128 | r = amdgpu_ring_test_ring(ring); | 2117 | if (r) |
2129 | if (r) { | ||
2130 | ring->ready = false; | ||
2131 | return r; | 2118 | return r; |
2132 | } | ||
2133 | 2119 | ||
2134 | return 0; | 2120 | return 0; |
2135 | } | 2121 | } |
@@ -2227,14 +2213,11 @@ static int gfx_v6_0_cp_compute_resume(struct amdgpu_device *adev) | |||
2227 | WREG32(mmCP_RB2_CNTL, tmp); | 2213 | WREG32(mmCP_RB2_CNTL, tmp); |
2228 | WREG32(mmCP_RB2_BASE, ring->gpu_addr >> 8); | 2214 | WREG32(mmCP_RB2_BASE, ring->gpu_addr >> 8); |
2229 | 2215 | ||
2230 | adev->gfx.compute_ring[0].ready = false; | ||
2231 | adev->gfx.compute_ring[1].ready = false; | ||
2232 | 2216 | ||
2233 | for (i = 0; i < 2; i++) { | 2217 | for (i = 0; i < 2; i++) { |
2234 | r = amdgpu_ring_test_ring(&adev->gfx.compute_ring[i]); | 2218 | r = amdgpu_ring_test_helper(&adev->gfx.compute_ring[i]); |
2235 | if (r) | 2219 | if (r) |
2236 | return r; | 2220 | return r; |
2237 | adev->gfx.compute_ring[i].ready = true; | ||
2238 | } | 2221 | } |
2239 | 2222 | ||
2240 | return 0; | 2223 | return 0; |
@@ -2368,18 +2351,11 @@ static void gfx_v6_0_ring_emit_wreg(struct amdgpu_ring *ring, | |||
2368 | amdgpu_ring_write(ring, val); | 2351 | amdgpu_ring_write(ring, val); |
2369 | } | 2352 | } |
2370 | 2353 | ||
2371 | static void gfx_v6_0_rlc_fini(struct amdgpu_device *adev) | ||
2372 | { | ||
2373 | amdgpu_bo_free_kernel(&adev->gfx.rlc.save_restore_obj, NULL, NULL); | ||
2374 | amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, NULL, NULL); | ||
2375 | amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj, NULL, NULL); | ||
2376 | } | ||
2377 | |||
2378 | static int gfx_v6_0_rlc_init(struct amdgpu_device *adev) | 2354 | static int gfx_v6_0_rlc_init(struct amdgpu_device *adev) |
2379 | { | 2355 | { |
2380 | const u32 *src_ptr; | 2356 | const u32 *src_ptr; |
2381 | volatile u32 *dst_ptr; | 2357 | volatile u32 *dst_ptr; |
2382 | u32 dws, i; | 2358 | u32 dws; |
2383 | u64 reg_list_mc_addr; | 2359 | u64 reg_list_mc_addr; |
2384 | const struct cs_section_def *cs_data; | 2360 | const struct cs_section_def *cs_data; |
2385 | int r; | 2361 | int r; |
@@ -2394,26 +2370,10 @@ static int gfx_v6_0_rlc_init(struct amdgpu_device *adev) | |||
2394 | cs_data = adev->gfx.rlc.cs_data; | 2370 | cs_data = adev->gfx.rlc.cs_data; |
2395 | 2371 | ||
2396 | if (src_ptr) { | 2372 | if (src_ptr) { |
2397 | /* save restore block */ | 2373 | /* init save restore block */ |
2398 | r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE, | 2374 | r = amdgpu_gfx_rlc_init_sr(adev, dws); |
2399 | AMDGPU_GEM_DOMAIN_VRAM, | 2375 | if (r) |
2400 | &adev->gfx.rlc.save_restore_obj, | ||
2401 | &adev->gfx.rlc.save_restore_gpu_addr, | ||
2402 | (void **)&adev->gfx.rlc.sr_ptr); | ||
2403 | if (r) { | ||
2404 | dev_warn(adev->dev, "(%d) create RLC sr bo failed\n", | ||
2405 | r); | ||
2406 | gfx_v6_0_rlc_fini(adev); | ||
2407 | return r; | 2376 | return r; |
2408 | } | ||
2409 | |||
2410 | /* write the sr buffer */ | ||
2411 | dst_ptr = adev->gfx.rlc.sr_ptr; | ||
2412 | for (i = 0; i < adev->gfx.rlc.reg_list_size; i++) | ||
2413 | dst_ptr[i] = cpu_to_le32(src_ptr[i]); | ||
2414 | |||
2415 | amdgpu_bo_kunmap(adev->gfx.rlc.save_restore_obj); | ||
2416 | amdgpu_bo_unreserve(adev->gfx.rlc.save_restore_obj); | ||
2417 | } | 2377 | } |
2418 | 2378 | ||
2419 | if (cs_data) { | 2379 | if (cs_data) { |
@@ -2428,7 +2388,7 @@ static int gfx_v6_0_rlc_init(struct amdgpu_device *adev) | |||
2428 | (void **)&adev->gfx.rlc.cs_ptr); | 2388 | (void **)&adev->gfx.rlc.cs_ptr); |
2429 | if (r) { | 2389 | if (r) { |
2430 | dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r); | 2390 | dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r); |
2431 | gfx_v6_0_rlc_fini(adev); | 2391 | amdgpu_gfx_rlc_fini(adev); |
2432 | return r; | 2392 | return r; |
2433 | } | 2393 | } |
2434 | 2394 | ||
@@ -2549,8 +2509,8 @@ static int gfx_v6_0_rlc_resume(struct amdgpu_device *adev) | |||
2549 | if (!adev->gfx.rlc_fw) | 2509 | if (!adev->gfx.rlc_fw) |
2550 | return -EINVAL; | 2510 | return -EINVAL; |
2551 | 2511 | ||
2552 | gfx_v6_0_rlc_stop(adev); | 2512 | adev->gfx.rlc.funcs->stop(adev); |
2553 | gfx_v6_0_rlc_reset(adev); | 2513 | adev->gfx.rlc.funcs->reset(adev); |
2554 | gfx_v6_0_init_pg(adev); | 2514 | gfx_v6_0_init_pg(adev); |
2555 | gfx_v6_0_init_cg(adev); | 2515 | gfx_v6_0_init_cg(adev); |
2556 | 2516 | ||
@@ -2578,7 +2538,7 @@ static int gfx_v6_0_rlc_resume(struct amdgpu_device *adev) | |||
2578 | WREG32(mmRLC_UCODE_ADDR, 0); | 2538 | WREG32(mmRLC_UCODE_ADDR, 0); |
2579 | 2539 | ||
2580 | gfx_v6_0_enable_lbpw(adev, gfx_v6_0_lbpw_supported(adev)); | 2540 | gfx_v6_0_enable_lbpw(adev, gfx_v6_0_lbpw_supported(adev)); |
2581 | gfx_v6_0_rlc_start(adev); | 2541 | adev->gfx.rlc.funcs->start(adev); |
2582 | 2542 | ||
2583 | return 0; | 2543 | return 0; |
2584 | } | 2544 | } |
@@ -3075,6 +3035,14 @@ static const struct amdgpu_gfx_funcs gfx_v6_0_gfx_funcs = { | |||
3075 | .select_me_pipe_q = &gfx_v6_0_select_me_pipe_q | 3035 | .select_me_pipe_q = &gfx_v6_0_select_me_pipe_q |
3076 | }; | 3036 | }; |
3077 | 3037 | ||
3038 | static const struct amdgpu_rlc_funcs gfx_v6_0_rlc_funcs = { | ||
3039 | .init = gfx_v6_0_rlc_init, | ||
3040 | .resume = gfx_v6_0_rlc_resume, | ||
3041 | .stop = gfx_v6_0_rlc_stop, | ||
3042 | .reset = gfx_v6_0_rlc_reset, | ||
3043 | .start = gfx_v6_0_rlc_start | ||
3044 | }; | ||
3045 | |||
3078 | static int gfx_v6_0_early_init(void *handle) | 3046 | static int gfx_v6_0_early_init(void *handle) |
3079 | { | 3047 | { |
3080 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 3048 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
@@ -3082,6 +3050,7 @@ static int gfx_v6_0_early_init(void *handle) | |||
3082 | adev->gfx.num_gfx_rings = GFX6_NUM_GFX_RINGS; | 3050 | adev->gfx.num_gfx_rings = GFX6_NUM_GFX_RINGS; |
3083 | adev->gfx.num_compute_rings = GFX6_NUM_COMPUTE_RINGS; | 3051 | adev->gfx.num_compute_rings = GFX6_NUM_COMPUTE_RINGS; |
3084 | adev->gfx.funcs = &gfx_v6_0_gfx_funcs; | 3052 | adev->gfx.funcs = &gfx_v6_0_gfx_funcs; |
3053 | adev->gfx.rlc.funcs = &gfx_v6_0_rlc_funcs; | ||
3085 | gfx_v6_0_set_ring_funcs(adev); | 3054 | gfx_v6_0_set_ring_funcs(adev); |
3086 | gfx_v6_0_set_irq_funcs(adev); | 3055 | gfx_v6_0_set_irq_funcs(adev); |
3087 | 3056 | ||
@@ -3114,7 +3083,7 @@ static int gfx_v6_0_sw_init(void *handle) | |||
3114 | return r; | 3083 | return r; |
3115 | } | 3084 | } |
3116 | 3085 | ||
3117 | r = gfx_v6_0_rlc_init(adev); | 3086 | r = adev->gfx.rlc.funcs->init(adev); |
3118 | if (r) { | 3087 | if (r) { |
3119 | DRM_ERROR("Failed to init rlc BOs!\n"); | 3088 | DRM_ERROR("Failed to init rlc BOs!\n"); |
3120 | return r; | 3089 | return r; |
@@ -3165,7 +3134,7 @@ static int gfx_v6_0_sw_fini(void *handle) | |||
3165 | for (i = 0; i < adev->gfx.num_compute_rings; i++) | 3134 | for (i = 0; i < adev->gfx.num_compute_rings; i++) |
3166 | amdgpu_ring_fini(&adev->gfx.compute_ring[i]); | 3135 | amdgpu_ring_fini(&adev->gfx.compute_ring[i]); |
3167 | 3136 | ||
3168 | gfx_v6_0_rlc_fini(adev); | 3137 | amdgpu_gfx_rlc_fini(adev); |
3169 | 3138 | ||
3170 | return 0; | 3139 | return 0; |
3171 | } | 3140 | } |
@@ -3177,7 +3146,7 @@ static int gfx_v6_0_hw_init(void *handle) | |||
3177 | 3146 | ||
3178 | gfx_v6_0_constants_init(adev); | 3147 | gfx_v6_0_constants_init(adev); |
3179 | 3148 | ||
3180 | r = gfx_v6_0_rlc_resume(adev); | 3149 | r = adev->gfx.rlc.funcs->resume(adev); |
3181 | if (r) | 3150 | if (r) |
3182 | return r; | 3151 | return r; |
3183 | 3152 | ||
@@ -3195,7 +3164,7 @@ static int gfx_v6_0_hw_fini(void *handle) | |||
3195 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 3164 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
3196 | 3165 | ||
3197 | gfx_v6_0_cp_enable(adev, false); | 3166 | gfx_v6_0_cp_enable(adev, false); |
3198 | gfx_v6_0_rlc_stop(adev); | 3167 | adev->gfx.rlc.funcs->stop(adev); |
3199 | gfx_v6_0_fini_pg(adev); | 3168 | gfx_v6_0_fini_pg(adev); |
3200 | 3169 | ||
3201 | return 0; | 3170 | return 0; |
@@ -3393,12 +3362,31 @@ static int gfx_v6_0_eop_irq(struct amdgpu_device *adev, | |||
3393 | return 0; | 3362 | return 0; |
3394 | } | 3363 | } |
3395 | 3364 | ||
3365 | static void gfx_v6_0_fault(struct amdgpu_device *adev, | ||
3366 | struct amdgpu_iv_entry *entry) | ||
3367 | { | ||
3368 | struct amdgpu_ring *ring; | ||
3369 | |||
3370 | switch (entry->ring_id) { | ||
3371 | case 0: | ||
3372 | ring = &adev->gfx.gfx_ring[0]; | ||
3373 | break; | ||
3374 | case 1: | ||
3375 | case 2: | ||
3376 | ring = &adev->gfx.compute_ring[entry->ring_id - 1]; | ||
3377 | break; | ||
3378 | default: | ||
3379 | return; | ||
3380 | } | ||
3381 | drm_sched_fault(&ring->sched); | ||
3382 | } | ||
3383 | |||
3396 | static int gfx_v6_0_priv_reg_irq(struct amdgpu_device *adev, | 3384 | static int gfx_v6_0_priv_reg_irq(struct amdgpu_device *adev, |
3397 | struct amdgpu_irq_src *source, | 3385 | struct amdgpu_irq_src *source, |
3398 | struct amdgpu_iv_entry *entry) | 3386 | struct amdgpu_iv_entry *entry) |
3399 | { | 3387 | { |
3400 | DRM_ERROR("Illegal register access in command stream\n"); | 3388 | DRM_ERROR("Illegal register access in command stream\n"); |
3401 | schedule_work(&adev->reset_work); | 3389 | gfx_v6_0_fault(adev, entry); |
3402 | return 0; | 3390 | return 0; |
3403 | } | 3391 | } |
3404 | 3392 | ||
@@ -3407,7 +3395,7 @@ static int gfx_v6_0_priv_inst_irq(struct amdgpu_device *adev, | |||
3407 | struct amdgpu_iv_entry *entry) | 3395 | struct amdgpu_iv_entry *entry) |
3408 | { | 3396 | { |
3409 | DRM_ERROR("Illegal instruction in command stream\n"); | 3397 | DRM_ERROR("Illegal instruction in command stream\n"); |
3410 | schedule_work(&adev->reset_work); | 3398 | gfx_v6_0_fault(adev, entry); |
3411 | return 0; | 3399 | return 0; |
3412 | } | 3400 | } |
3413 | 3401 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index 0e72bc09939a..f467b9bd090d 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | |||
@@ -882,7 +882,6 @@ static const u32 kalindi_rlc_save_restore_register_list[] = | |||
882 | 882 | ||
883 | static u32 gfx_v7_0_get_csb_size(struct amdgpu_device *adev); | 883 | static u32 gfx_v7_0_get_csb_size(struct amdgpu_device *adev); |
884 | static void gfx_v7_0_get_csb_buffer(struct amdgpu_device *adev, volatile u32 *buffer); | 884 | static void gfx_v7_0_get_csb_buffer(struct amdgpu_device *adev, volatile u32 *buffer); |
885 | static void gfx_v7_0_init_cp_pg_table(struct amdgpu_device *adev); | ||
886 | static void gfx_v7_0_init_pg(struct amdgpu_device *adev); | 885 | static void gfx_v7_0_init_pg(struct amdgpu_device *adev); |
887 | static void gfx_v7_0_get_cu_info(struct amdgpu_device *adev); | 886 | static void gfx_v7_0_get_cu_info(struct amdgpu_device *adev); |
888 | 887 | ||
@@ -2064,17 +2063,14 @@ static int gfx_v7_0_ring_test_ring(struct amdgpu_ring *ring) | |||
2064 | int r; | 2063 | int r; |
2065 | 2064 | ||
2066 | r = amdgpu_gfx_scratch_get(adev, &scratch); | 2065 | r = amdgpu_gfx_scratch_get(adev, &scratch); |
2067 | if (r) { | 2066 | if (r) |
2068 | DRM_ERROR("amdgpu: cp failed to get scratch reg (%d).\n", r); | ||
2069 | return r; | 2067 | return r; |
2070 | } | 2068 | |
2071 | WREG32(scratch, 0xCAFEDEAD); | 2069 | WREG32(scratch, 0xCAFEDEAD); |
2072 | r = amdgpu_ring_alloc(ring, 3); | 2070 | r = amdgpu_ring_alloc(ring, 3); |
2073 | if (r) { | 2071 | if (r) |
2074 | DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", ring->idx, r); | 2072 | goto error_free_scratch; |
2075 | amdgpu_gfx_scratch_free(adev, scratch); | 2073 | |
2076 | return r; | ||
2077 | } | ||
2078 | amdgpu_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1)); | 2074 | amdgpu_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1)); |
2079 | amdgpu_ring_write(ring, (scratch - PACKET3_SET_UCONFIG_REG_START)); | 2075 | amdgpu_ring_write(ring, (scratch - PACKET3_SET_UCONFIG_REG_START)); |
2080 | amdgpu_ring_write(ring, 0xDEADBEEF); | 2076 | amdgpu_ring_write(ring, 0xDEADBEEF); |
@@ -2086,13 +2082,10 @@ static int gfx_v7_0_ring_test_ring(struct amdgpu_ring *ring) | |||
2086 | break; | 2082 | break; |
2087 | DRM_UDELAY(1); | 2083 | DRM_UDELAY(1); |
2088 | } | 2084 | } |
2089 | if (i < adev->usec_timeout) { | 2085 | if (i >= adev->usec_timeout) |
2090 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", ring->idx, i); | 2086 | r = -ETIMEDOUT; |
2091 | } else { | 2087 | |
2092 | DRM_ERROR("amdgpu: ring %d test failed (scratch(0x%04X)=0x%08X)\n", | 2088 | error_free_scratch: |
2093 | ring->idx, scratch, tmp); | ||
2094 | r = -EINVAL; | ||
2095 | } | ||
2096 | amdgpu_gfx_scratch_free(adev, scratch); | 2089 | amdgpu_gfx_scratch_free(adev, scratch); |
2097 | return r; | 2090 | return r; |
2098 | } | 2091 | } |
@@ -2233,9 +2226,11 @@ static void gfx_v7_0_ring_emit_fence_compute(struct amdgpu_ring *ring, | |||
2233 | * on the gfx ring for execution by the GPU. | 2226 | * on the gfx ring for execution by the GPU. |
2234 | */ | 2227 | */ |
2235 | static void gfx_v7_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, | 2228 | static void gfx_v7_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, |
2236 | struct amdgpu_ib *ib, | 2229 | struct amdgpu_job *job, |
2237 | unsigned vmid, bool ctx_switch) | 2230 | struct amdgpu_ib *ib, |
2231 | bool ctx_switch) | ||
2238 | { | 2232 | { |
2233 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
2239 | u32 header, control = 0; | 2234 | u32 header, control = 0; |
2240 | 2235 | ||
2241 | /* insert SWITCH_BUFFER packet before first IB in the ring frame */ | 2236 | /* insert SWITCH_BUFFER packet before first IB in the ring frame */ |
@@ -2262,9 +2257,11 @@ static void gfx_v7_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, | |||
2262 | } | 2257 | } |
2263 | 2258 | ||
2264 | static void gfx_v7_0_ring_emit_ib_compute(struct amdgpu_ring *ring, | 2259 | static void gfx_v7_0_ring_emit_ib_compute(struct amdgpu_ring *ring, |
2260 | struct amdgpu_job *job, | ||
2265 | struct amdgpu_ib *ib, | 2261 | struct amdgpu_ib *ib, |
2266 | unsigned vmid, bool ctx_switch) | 2262 | bool ctx_switch) |
2267 | { | 2263 | { |
2264 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
2268 | u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vmid << 24); | 2265 | u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vmid << 24); |
2269 | 2266 | ||
2270 | amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); | 2267 | amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); |
@@ -2316,17 +2313,15 @@ static int gfx_v7_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
2316 | long r; | 2313 | long r; |
2317 | 2314 | ||
2318 | r = amdgpu_gfx_scratch_get(adev, &scratch); | 2315 | r = amdgpu_gfx_scratch_get(adev, &scratch); |
2319 | if (r) { | 2316 | if (r) |
2320 | DRM_ERROR("amdgpu: failed to get scratch reg (%ld).\n", r); | ||
2321 | return r; | 2317 | return r; |
2322 | } | 2318 | |
2323 | WREG32(scratch, 0xCAFEDEAD); | 2319 | WREG32(scratch, 0xCAFEDEAD); |
2324 | memset(&ib, 0, sizeof(ib)); | 2320 | memset(&ib, 0, sizeof(ib)); |
2325 | r = amdgpu_ib_get(adev, NULL, 256, &ib); | 2321 | r = amdgpu_ib_get(adev, NULL, 256, &ib); |
2326 | if (r) { | 2322 | if (r) |
2327 | DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r); | ||
2328 | goto err1; | 2323 | goto err1; |
2329 | } | 2324 | |
2330 | ib.ptr[0] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); | 2325 | ib.ptr[0] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); |
2331 | ib.ptr[1] = ((scratch - PACKET3_SET_UCONFIG_REG_START)); | 2326 | ib.ptr[1] = ((scratch - PACKET3_SET_UCONFIG_REG_START)); |
2332 | ib.ptr[2] = 0xDEADBEEF; | 2327 | ib.ptr[2] = 0xDEADBEEF; |
@@ -2338,22 +2333,16 @@ static int gfx_v7_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
2338 | 2333 | ||
2339 | r = dma_fence_wait_timeout(f, false, timeout); | 2334 | r = dma_fence_wait_timeout(f, false, timeout); |
2340 | if (r == 0) { | 2335 | if (r == 0) { |
2341 | DRM_ERROR("amdgpu: IB test timed out\n"); | ||
2342 | r = -ETIMEDOUT; | 2336 | r = -ETIMEDOUT; |
2343 | goto err2; | 2337 | goto err2; |
2344 | } else if (r < 0) { | 2338 | } else if (r < 0) { |
2345 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | ||
2346 | goto err2; | 2339 | goto err2; |
2347 | } | 2340 | } |
2348 | tmp = RREG32(scratch); | 2341 | tmp = RREG32(scratch); |
2349 | if (tmp == 0xDEADBEEF) { | 2342 | if (tmp == 0xDEADBEEF) |
2350 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | ||
2351 | r = 0; | 2343 | r = 0; |
2352 | } else { | 2344 | else |
2353 | DRM_ERROR("amdgpu: ib test failed (scratch(0x%04X)=0x%08X)\n", | ||
2354 | scratch, tmp); | ||
2355 | r = -EINVAL; | 2345 | r = -EINVAL; |
2356 | } | ||
2357 | 2346 | ||
2358 | err2: | 2347 | err2: |
2359 | amdgpu_ib_free(adev, &ib, NULL); | 2348 | amdgpu_ib_free(adev, &ib, NULL); |
@@ -2403,7 +2392,7 @@ static void gfx_v7_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable) | |||
2403 | } else { | 2392 | } else { |
2404 | WREG32(mmCP_ME_CNTL, (CP_ME_CNTL__ME_HALT_MASK | CP_ME_CNTL__PFP_HALT_MASK | CP_ME_CNTL__CE_HALT_MASK)); | 2393 | WREG32(mmCP_ME_CNTL, (CP_ME_CNTL__ME_HALT_MASK | CP_ME_CNTL__PFP_HALT_MASK | CP_ME_CNTL__CE_HALT_MASK)); |
2405 | for (i = 0; i < adev->gfx.num_gfx_rings; i++) | 2394 | for (i = 0; i < adev->gfx.num_gfx_rings; i++) |
2406 | adev->gfx.gfx_ring[i].ready = false; | 2395 | adev->gfx.gfx_ring[i].sched.ready = false; |
2407 | } | 2396 | } |
2408 | udelay(50); | 2397 | udelay(50); |
2409 | } | 2398 | } |
@@ -2613,12 +2602,9 @@ static int gfx_v7_0_cp_gfx_resume(struct amdgpu_device *adev) | |||
2613 | 2602 | ||
2614 | /* start the ring */ | 2603 | /* start the ring */ |
2615 | gfx_v7_0_cp_gfx_start(adev); | 2604 | gfx_v7_0_cp_gfx_start(adev); |
2616 | ring->ready = true; | 2605 | r = amdgpu_ring_test_helper(ring); |
2617 | r = amdgpu_ring_test_ring(ring); | 2606 | if (r) |
2618 | if (r) { | ||
2619 | ring->ready = false; | ||
2620 | return r; | 2607 | return r; |
2621 | } | ||
2622 | 2608 | ||
2623 | return 0; | 2609 | return 0; |
2624 | } | 2610 | } |
@@ -2675,7 +2661,7 @@ static void gfx_v7_0_cp_compute_enable(struct amdgpu_device *adev, bool enable) | |||
2675 | } else { | 2661 | } else { |
2676 | WREG32(mmCP_MEC_CNTL, (CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK)); | 2662 | WREG32(mmCP_MEC_CNTL, (CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK)); |
2677 | for (i = 0; i < adev->gfx.num_compute_rings; i++) | 2663 | for (i = 0; i < adev->gfx.num_compute_rings; i++) |
2678 | adev->gfx.compute_ring[i].ready = false; | 2664 | adev->gfx.compute_ring[i].sched.ready = false; |
2679 | } | 2665 | } |
2680 | udelay(50); | 2666 | udelay(50); |
2681 | } | 2667 | } |
@@ -2781,7 +2767,7 @@ static int gfx_v7_0_mec_init(struct amdgpu_device *adev) | |||
2781 | * GFX7_MEC_HPD_SIZE * 2; | 2767 | * GFX7_MEC_HPD_SIZE * 2; |
2782 | 2768 | ||
2783 | r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE, | 2769 | r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE, |
2784 | AMDGPU_GEM_DOMAIN_GTT, | 2770 | AMDGPU_GEM_DOMAIN_VRAM, |
2785 | &adev->gfx.mec.hpd_eop_obj, | 2771 | &adev->gfx.mec.hpd_eop_obj, |
2786 | &adev->gfx.mec.hpd_eop_gpu_addr, | 2772 | &adev->gfx.mec.hpd_eop_gpu_addr, |
2787 | (void **)&hpd); | 2773 | (void **)&hpd); |
@@ -3106,10 +3092,7 @@ static int gfx_v7_0_cp_compute_resume(struct amdgpu_device *adev) | |||
3106 | 3092 | ||
3107 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { | 3093 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { |
3108 | ring = &adev->gfx.compute_ring[i]; | 3094 | ring = &adev->gfx.compute_ring[i]; |
3109 | ring->ready = true; | 3095 | amdgpu_ring_test_helper(ring); |
3110 | r = amdgpu_ring_test_ring(ring); | ||
3111 | if (r) | ||
3112 | ring->ready = false; | ||
3113 | } | 3096 | } |
3114 | 3097 | ||
3115 | return 0; | 3098 | return 0; |
@@ -3268,18 +3251,10 @@ static void gfx_v7_0_ring_emit_wreg(struct amdgpu_ring *ring, | |||
3268 | * The RLC is a multi-purpose microengine that handles a | 3251 | * The RLC is a multi-purpose microengine that handles a |
3269 | * variety of functions. | 3252 | * variety of functions. |
3270 | */ | 3253 | */ |
3271 | static void gfx_v7_0_rlc_fini(struct amdgpu_device *adev) | ||
3272 | { | ||
3273 | amdgpu_bo_free_kernel(&adev->gfx.rlc.save_restore_obj, NULL, NULL); | ||
3274 | amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, NULL, NULL); | ||
3275 | amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj, NULL, NULL); | ||
3276 | } | ||
3277 | |||
3278 | static int gfx_v7_0_rlc_init(struct amdgpu_device *adev) | 3254 | static int gfx_v7_0_rlc_init(struct amdgpu_device *adev) |
3279 | { | 3255 | { |
3280 | const u32 *src_ptr; | 3256 | const u32 *src_ptr; |
3281 | volatile u32 *dst_ptr; | 3257 | u32 dws; |
3282 | u32 dws, i; | ||
3283 | const struct cs_section_def *cs_data; | 3258 | const struct cs_section_def *cs_data; |
3284 | int r; | 3259 | int r; |
3285 | 3260 | ||
@@ -3306,66 +3281,23 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev) | |||
3306 | cs_data = adev->gfx.rlc.cs_data; | 3281 | cs_data = adev->gfx.rlc.cs_data; |
3307 | 3282 | ||
3308 | if (src_ptr) { | 3283 | if (src_ptr) { |
3309 | /* save restore block */ | 3284 | /* init save restore block */ |
3310 | r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE, | 3285 | r = amdgpu_gfx_rlc_init_sr(adev, dws); |
3311 | AMDGPU_GEM_DOMAIN_VRAM, | 3286 | if (r) |
3312 | &adev->gfx.rlc.save_restore_obj, | ||
3313 | &adev->gfx.rlc.save_restore_gpu_addr, | ||
3314 | (void **)&adev->gfx.rlc.sr_ptr); | ||
3315 | if (r) { | ||
3316 | dev_warn(adev->dev, "(%d) create, pin or map of RLC sr bo failed\n", r); | ||
3317 | gfx_v7_0_rlc_fini(adev); | ||
3318 | return r; | 3287 | return r; |
3319 | } | ||
3320 | |||
3321 | /* write the sr buffer */ | ||
3322 | dst_ptr = adev->gfx.rlc.sr_ptr; | ||
3323 | for (i = 0; i < adev->gfx.rlc.reg_list_size; i++) | ||
3324 | dst_ptr[i] = cpu_to_le32(src_ptr[i]); | ||
3325 | amdgpu_bo_kunmap(adev->gfx.rlc.save_restore_obj); | ||
3326 | amdgpu_bo_unreserve(adev->gfx.rlc.save_restore_obj); | ||
3327 | } | 3288 | } |
3328 | 3289 | ||
3329 | if (cs_data) { | 3290 | if (cs_data) { |
3330 | /* clear state block */ | 3291 | /* init clear state block */ |
3331 | adev->gfx.rlc.clear_state_size = dws = gfx_v7_0_get_csb_size(adev); | 3292 | r = amdgpu_gfx_rlc_init_csb(adev); |
3332 | 3293 | if (r) | |
3333 | r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE, | ||
3334 | AMDGPU_GEM_DOMAIN_VRAM, | ||
3335 | &adev->gfx.rlc.clear_state_obj, | ||
3336 | &adev->gfx.rlc.clear_state_gpu_addr, | ||
3337 | (void **)&adev->gfx.rlc.cs_ptr); | ||
3338 | if (r) { | ||
3339 | dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r); | ||
3340 | gfx_v7_0_rlc_fini(adev); | ||
3341 | return r; | 3294 | return r; |
3342 | } | ||
3343 | |||
3344 | /* set up the cs buffer */ | ||
3345 | dst_ptr = adev->gfx.rlc.cs_ptr; | ||
3346 | gfx_v7_0_get_csb_buffer(adev, dst_ptr); | ||
3347 | amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj); | ||
3348 | amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); | ||
3349 | } | 3295 | } |
3350 | 3296 | ||
3351 | if (adev->gfx.rlc.cp_table_size) { | 3297 | if (adev->gfx.rlc.cp_table_size) { |
3352 | 3298 | r = amdgpu_gfx_rlc_init_cpt(adev); | |
3353 | r = amdgpu_bo_create_reserved(adev, adev->gfx.rlc.cp_table_size, | 3299 | if (r) |
3354 | PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, | ||
3355 | &adev->gfx.rlc.cp_table_obj, | ||
3356 | &adev->gfx.rlc.cp_table_gpu_addr, | ||
3357 | (void **)&adev->gfx.rlc.cp_table_ptr); | ||
3358 | if (r) { | ||
3359 | dev_warn(adev->dev, "(%d) create RLC cp table bo failed\n", r); | ||
3360 | gfx_v7_0_rlc_fini(adev); | ||
3361 | return r; | 3300 | return r; |
3362 | } | ||
3363 | |||
3364 | gfx_v7_0_init_cp_pg_table(adev); | ||
3365 | |||
3366 | amdgpu_bo_kunmap(adev->gfx.rlc.cp_table_obj); | ||
3367 | amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj); | ||
3368 | |||
3369 | } | 3301 | } |
3370 | 3302 | ||
3371 | return 0; | 3303 | return 0; |
@@ -3446,7 +3378,12 @@ static u32 gfx_v7_0_halt_rlc(struct amdgpu_device *adev) | |||
3446 | return orig; | 3378 | return orig; |
3447 | } | 3379 | } |
3448 | 3380 | ||
3449 | static void gfx_v7_0_enter_rlc_safe_mode(struct amdgpu_device *adev) | 3381 | static bool gfx_v7_0_is_rlc_enabled(struct amdgpu_device *adev) |
3382 | { | ||
3383 | return true; | ||
3384 | } | ||
3385 | |||
3386 | static void gfx_v7_0_set_safe_mode(struct amdgpu_device *adev) | ||
3450 | { | 3387 | { |
3451 | u32 tmp, i, mask; | 3388 | u32 tmp, i, mask; |
3452 | 3389 | ||
@@ -3468,7 +3405,7 @@ static void gfx_v7_0_enter_rlc_safe_mode(struct amdgpu_device *adev) | |||
3468 | } | 3405 | } |
3469 | } | 3406 | } |
3470 | 3407 | ||
3471 | static void gfx_v7_0_exit_rlc_safe_mode(struct amdgpu_device *adev) | 3408 | static void gfx_v7_0_unset_safe_mode(struct amdgpu_device *adev) |
3472 | { | 3409 | { |
3473 | u32 tmp; | 3410 | u32 tmp; |
3474 | 3411 | ||
@@ -3545,13 +3482,13 @@ static int gfx_v7_0_rlc_resume(struct amdgpu_device *adev) | |||
3545 | adev->gfx.rlc_feature_version = le32_to_cpu( | 3482 | adev->gfx.rlc_feature_version = le32_to_cpu( |
3546 | hdr->ucode_feature_version); | 3483 | hdr->ucode_feature_version); |
3547 | 3484 | ||
3548 | gfx_v7_0_rlc_stop(adev); | 3485 | adev->gfx.rlc.funcs->stop(adev); |
3549 | 3486 | ||
3550 | /* disable CG */ | 3487 | /* disable CG */ |
3551 | tmp = RREG32(mmRLC_CGCG_CGLS_CTRL) & 0xfffffffc; | 3488 | tmp = RREG32(mmRLC_CGCG_CGLS_CTRL) & 0xfffffffc; |
3552 | WREG32(mmRLC_CGCG_CGLS_CTRL, tmp); | 3489 | WREG32(mmRLC_CGCG_CGLS_CTRL, tmp); |
3553 | 3490 | ||
3554 | gfx_v7_0_rlc_reset(adev); | 3491 | adev->gfx.rlc.funcs->reset(adev); |
3555 | 3492 | ||
3556 | gfx_v7_0_init_pg(adev); | 3493 | gfx_v7_0_init_pg(adev); |
3557 | 3494 | ||
@@ -3582,7 +3519,7 @@ static int gfx_v7_0_rlc_resume(struct amdgpu_device *adev) | |||
3582 | if (adev->asic_type == CHIP_BONAIRE) | 3519 | if (adev->asic_type == CHIP_BONAIRE) |
3583 | WREG32(mmRLC_DRIVER_CPDMA_STATUS, 0); | 3520 | WREG32(mmRLC_DRIVER_CPDMA_STATUS, 0); |
3584 | 3521 | ||
3585 | gfx_v7_0_rlc_start(adev); | 3522 | adev->gfx.rlc.funcs->start(adev); |
3586 | 3523 | ||
3587 | return 0; | 3524 | return 0; |
3588 | } | 3525 | } |
@@ -3784,72 +3721,12 @@ static void gfx_v7_0_enable_gds_pg(struct amdgpu_device *adev, bool enable) | |||
3784 | WREG32(mmRLC_PG_CNTL, data); | 3721 | WREG32(mmRLC_PG_CNTL, data); |
3785 | } | 3722 | } |
3786 | 3723 | ||
3787 | static void gfx_v7_0_init_cp_pg_table(struct amdgpu_device *adev) | 3724 | static int gfx_v7_0_cp_pg_table_num(struct amdgpu_device *adev) |
3788 | { | 3725 | { |
3789 | const __le32 *fw_data; | ||
3790 | volatile u32 *dst_ptr; | ||
3791 | int me, i, max_me = 4; | ||
3792 | u32 bo_offset = 0; | ||
3793 | u32 table_offset, table_size; | ||
3794 | |||
3795 | if (adev->asic_type == CHIP_KAVERI) | 3726 | if (adev->asic_type == CHIP_KAVERI) |
3796 | max_me = 5; | 3727 | return 5; |
3797 | 3728 | else | |
3798 | if (adev->gfx.rlc.cp_table_ptr == NULL) | 3729 | return 4; |
3799 | return; | ||
3800 | |||
3801 | /* write the cp table buffer */ | ||
3802 | dst_ptr = adev->gfx.rlc.cp_table_ptr; | ||
3803 | for (me = 0; me < max_me; me++) { | ||
3804 | if (me == 0) { | ||
3805 | const struct gfx_firmware_header_v1_0 *hdr = | ||
3806 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.ce_fw->data; | ||
3807 | fw_data = (const __le32 *) | ||
3808 | (adev->gfx.ce_fw->data + | ||
3809 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
3810 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
3811 | table_size = le32_to_cpu(hdr->jt_size); | ||
3812 | } else if (me == 1) { | ||
3813 | const struct gfx_firmware_header_v1_0 *hdr = | ||
3814 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.pfp_fw->data; | ||
3815 | fw_data = (const __le32 *) | ||
3816 | (adev->gfx.pfp_fw->data + | ||
3817 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
3818 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
3819 | table_size = le32_to_cpu(hdr->jt_size); | ||
3820 | } else if (me == 2) { | ||
3821 | const struct gfx_firmware_header_v1_0 *hdr = | ||
3822 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.me_fw->data; | ||
3823 | fw_data = (const __le32 *) | ||
3824 | (adev->gfx.me_fw->data + | ||
3825 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
3826 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
3827 | table_size = le32_to_cpu(hdr->jt_size); | ||
3828 | } else if (me == 3) { | ||
3829 | const struct gfx_firmware_header_v1_0 *hdr = | ||
3830 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data; | ||
3831 | fw_data = (const __le32 *) | ||
3832 | (adev->gfx.mec_fw->data + | ||
3833 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
3834 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
3835 | table_size = le32_to_cpu(hdr->jt_size); | ||
3836 | } else { | ||
3837 | const struct gfx_firmware_header_v1_0 *hdr = | ||
3838 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec2_fw->data; | ||
3839 | fw_data = (const __le32 *) | ||
3840 | (adev->gfx.mec2_fw->data + | ||
3841 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
3842 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
3843 | table_size = le32_to_cpu(hdr->jt_size); | ||
3844 | } | ||
3845 | |||
3846 | for (i = 0; i < table_size; i ++) { | ||
3847 | dst_ptr[bo_offset + i] = | ||
3848 | cpu_to_le32(le32_to_cpu(fw_data[table_offset + i])); | ||
3849 | } | ||
3850 | |||
3851 | bo_offset += table_size; | ||
3852 | } | ||
3853 | } | 3730 | } |
3854 | 3731 | ||
3855 | static void gfx_v7_0_enable_gfx_cgpg(struct amdgpu_device *adev, | 3732 | static void gfx_v7_0_enable_gfx_cgpg(struct amdgpu_device *adev, |
@@ -4288,8 +4165,17 @@ static const struct amdgpu_gfx_funcs gfx_v7_0_gfx_funcs = { | |||
4288 | }; | 4165 | }; |
4289 | 4166 | ||
4290 | static const struct amdgpu_rlc_funcs gfx_v7_0_rlc_funcs = { | 4167 | static const struct amdgpu_rlc_funcs gfx_v7_0_rlc_funcs = { |
4291 | .enter_safe_mode = gfx_v7_0_enter_rlc_safe_mode, | 4168 | .is_rlc_enabled = gfx_v7_0_is_rlc_enabled, |
4292 | .exit_safe_mode = gfx_v7_0_exit_rlc_safe_mode | 4169 | .set_safe_mode = gfx_v7_0_set_safe_mode, |
4170 | .unset_safe_mode = gfx_v7_0_unset_safe_mode, | ||
4171 | .init = gfx_v7_0_rlc_init, | ||
4172 | .get_csb_size = gfx_v7_0_get_csb_size, | ||
4173 | .get_csb_buffer = gfx_v7_0_get_csb_buffer, | ||
4174 | .get_cp_table_num = gfx_v7_0_cp_pg_table_num, | ||
4175 | .resume = gfx_v7_0_rlc_resume, | ||
4176 | .stop = gfx_v7_0_rlc_stop, | ||
4177 | .reset = gfx_v7_0_rlc_reset, | ||
4178 | .start = gfx_v7_0_rlc_start | ||
4293 | }; | 4179 | }; |
4294 | 4180 | ||
4295 | static int gfx_v7_0_early_init(void *handle) | 4181 | static int gfx_v7_0_early_init(void *handle) |
@@ -4540,7 +4426,7 @@ static int gfx_v7_0_sw_init(void *handle) | |||
4540 | return r; | 4426 | return r; |
4541 | } | 4427 | } |
4542 | 4428 | ||
4543 | r = gfx_v7_0_rlc_init(adev); | 4429 | r = adev->gfx.rlc.funcs->init(adev); |
4544 | if (r) { | 4430 | if (r) { |
4545 | DRM_ERROR("Failed to init rlc BOs!\n"); | 4431 | DRM_ERROR("Failed to init rlc BOs!\n"); |
4546 | return r; | 4432 | return r; |
@@ -4604,7 +4490,7 @@ static int gfx_v7_0_sw_fini(void *handle) | |||
4604 | amdgpu_ring_fini(&adev->gfx.compute_ring[i]); | 4490 | amdgpu_ring_fini(&adev->gfx.compute_ring[i]); |
4605 | 4491 | ||
4606 | gfx_v7_0_cp_compute_fini(adev); | 4492 | gfx_v7_0_cp_compute_fini(adev); |
4607 | gfx_v7_0_rlc_fini(adev); | 4493 | amdgpu_gfx_rlc_fini(adev); |
4608 | gfx_v7_0_mec_fini(adev); | 4494 | gfx_v7_0_mec_fini(adev); |
4609 | amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, | 4495 | amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, |
4610 | &adev->gfx.rlc.clear_state_gpu_addr, | 4496 | &adev->gfx.rlc.clear_state_gpu_addr, |
@@ -4627,7 +4513,7 @@ static int gfx_v7_0_hw_init(void *handle) | |||
4627 | gfx_v7_0_constants_init(adev); | 4513 | gfx_v7_0_constants_init(adev); |
4628 | 4514 | ||
4629 | /* init rlc */ | 4515 | /* init rlc */ |
4630 | r = gfx_v7_0_rlc_resume(adev); | 4516 | r = adev->gfx.rlc.funcs->resume(adev); |
4631 | if (r) | 4517 | if (r) |
4632 | return r; | 4518 | return r; |
4633 | 4519 | ||
@@ -4645,7 +4531,7 @@ static int gfx_v7_0_hw_fini(void *handle) | |||
4645 | amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0); | 4531 | amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0); |
4646 | amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0); | 4532 | amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0); |
4647 | gfx_v7_0_cp_enable(adev, false); | 4533 | gfx_v7_0_cp_enable(adev, false); |
4648 | gfx_v7_0_rlc_stop(adev); | 4534 | adev->gfx.rlc.funcs->stop(adev); |
4649 | gfx_v7_0_fini_pg(adev); | 4535 | gfx_v7_0_fini_pg(adev); |
4650 | 4536 | ||
4651 | return 0; | 4537 | return 0; |
@@ -4730,7 +4616,7 @@ static int gfx_v7_0_soft_reset(void *handle) | |||
4730 | gfx_v7_0_update_cg(adev, false); | 4616 | gfx_v7_0_update_cg(adev, false); |
4731 | 4617 | ||
4732 | /* stop the rlc */ | 4618 | /* stop the rlc */ |
4733 | gfx_v7_0_rlc_stop(adev); | 4619 | adev->gfx.rlc.funcs->stop(adev); |
4734 | 4620 | ||
4735 | /* Disable GFX parsing/prefetching */ | 4621 | /* Disable GFX parsing/prefetching */ |
4736 | WREG32(mmCP_ME_CNTL, CP_ME_CNTL__ME_HALT_MASK | CP_ME_CNTL__PFP_HALT_MASK | CP_ME_CNTL__CE_HALT_MASK); | 4622 | WREG32(mmCP_ME_CNTL, CP_ME_CNTL__ME_HALT_MASK | CP_ME_CNTL__PFP_HALT_MASK | CP_ME_CNTL__CE_HALT_MASK); |
@@ -4959,12 +4845,36 @@ static int gfx_v7_0_eop_irq(struct amdgpu_device *adev, | |||
4959 | return 0; | 4845 | return 0; |
4960 | } | 4846 | } |
4961 | 4847 | ||
4848 | static void gfx_v7_0_fault(struct amdgpu_device *adev, | ||
4849 | struct amdgpu_iv_entry *entry) | ||
4850 | { | ||
4851 | struct amdgpu_ring *ring; | ||
4852 | u8 me_id, pipe_id; | ||
4853 | int i; | ||
4854 | |||
4855 | me_id = (entry->ring_id & 0x0c) >> 2; | ||
4856 | pipe_id = (entry->ring_id & 0x03) >> 0; | ||
4857 | switch (me_id) { | ||
4858 | case 0: | ||
4859 | drm_sched_fault(&adev->gfx.gfx_ring[0].sched); | ||
4860 | break; | ||
4861 | case 1: | ||
4862 | case 2: | ||
4863 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { | ||
4864 | ring = &adev->gfx.compute_ring[i]; | ||
4865 | if ((ring->me == me_id) && (ring->pipe == pipe_id)) | ||
4866 | drm_sched_fault(&ring->sched); | ||
4867 | } | ||
4868 | break; | ||
4869 | } | ||
4870 | } | ||
4871 | |||
4962 | static int gfx_v7_0_priv_reg_irq(struct amdgpu_device *adev, | 4872 | static int gfx_v7_0_priv_reg_irq(struct amdgpu_device *adev, |
4963 | struct amdgpu_irq_src *source, | 4873 | struct amdgpu_irq_src *source, |
4964 | struct amdgpu_iv_entry *entry) | 4874 | struct amdgpu_iv_entry *entry) |
4965 | { | 4875 | { |
4966 | DRM_ERROR("Illegal register access in command stream\n"); | 4876 | DRM_ERROR("Illegal register access in command stream\n"); |
4967 | schedule_work(&adev->reset_work); | 4877 | gfx_v7_0_fault(adev, entry); |
4968 | return 0; | 4878 | return 0; |
4969 | } | 4879 | } |
4970 | 4880 | ||
@@ -4974,7 +4884,7 @@ static int gfx_v7_0_priv_inst_irq(struct amdgpu_device *adev, | |||
4974 | { | 4884 | { |
4975 | DRM_ERROR("Illegal instruction in command stream\n"); | 4885 | DRM_ERROR("Illegal instruction in command stream\n"); |
4976 | // XXX soft reset the gfx block only | 4886 | // XXX soft reset the gfx block only |
4977 | schedule_work(&adev->reset_work); | 4887 | gfx_v7_0_fault(adev, entry); |
4978 | return 0; | 4888 | return 0; |
4979 | } | 4889 | } |
4980 | 4890 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 617b0c8908a3..cb066a8dccd7 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | |||
@@ -54,7 +54,7 @@ | |||
54 | #include "ivsrcid/ivsrcid_vislands30.h" | 54 | #include "ivsrcid/ivsrcid_vislands30.h" |
55 | 55 | ||
56 | #define GFX8_NUM_GFX_RINGS 1 | 56 | #define GFX8_NUM_GFX_RINGS 1 |
57 | #define GFX8_MEC_HPD_SIZE 2048 | 57 | #define GFX8_MEC_HPD_SIZE 4096 |
58 | 58 | ||
59 | #define TOPAZ_GB_ADDR_CONFIG_GOLDEN 0x22010001 | 59 | #define TOPAZ_GB_ADDR_CONFIG_GOLDEN 0x22010001 |
60 | #define CARRIZO_GB_ADDR_CONFIG_GOLDEN 0x22010001 | 60 | #define CARRIZO_GB_ADDR_CONFIG_GOLDEN 0x22010001 |
@@ -839,18 +839,14 @@ static int gfx_v8_0_ring_test_ring(struct amdgpu_ring *ring) | |||
839 | int r; | 839 | int r; |
840 | 840 | ||
841 | r = amdgpu_gfx_scratch_get(adev, &scratch); | 841 | r = amdgpu_gfx_scratch_get(adev, &scratch); |
842 | if (r) { | 842 | if (r) |
843 | DRM_ERROR("amdgpu: cp failed to get scratch reg (%d).\n", r); | ||
844 | return r; | 843 | return r; |
845 | } | 844 | |
846 | WREG32(scratch, 0xCAFEDEAD); | 845 | WREG32(scratch, 0xCAFEDEAD); |
847 | r = amdgpu_ring_alloc(ring, 3); | 846 | r = amdgpu_ring_alloc(ring, 3); |
848 | if (r) { | 847 | if (r) |
849 | DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", | 848 | goto error_free_scratch; |
850 | ring->idx, r); | 849 | |
851 | amdgpu_gfx_scratch_free(adev, scratch); | ||
852 | return r; | ||
853 | } | ||
854 | amdgpu_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1)); | 850 | amdgpu_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1)); |
855 | amdgpu_ring_write(ring, (scratch - PACKET3_SET_UCONFIG_REG_START)); | 851 | amdgpu_ring_write(ring, (scratch - PACKET3_SET_UCONFIG_REG_START)); |
856 | amdgpu_ring_write(ring, 0xDEADBEEF); | 852 | amdgpu_ring_write(ring, 0xDEADBEEF); |
@@ -862,14 +858,11 @@ static int gfx_v8_0_ring_test_ring(struct amdgpu_ring *ring) | |||
862 | break; | 858 | break; |
863 | DRM_UDELAY(1); | 859 | DRM_UDELAY(1); |
864 | } | 860 | } |
865 | if (i < adev->usec_timeout) { | 861 | |
866 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", | 862 | if (i >= adev->usec_timeout) |
867 | ring->idx, i); | 863 | r = -ETIMEDOUT; |
868 | } else { | 864 | |
869 | DRM_ERROR("amdgpu: ring %d test failed (scratch(0x%04X)=0x%08X)\n", | 865 | error_free_scratch: |
870 | ring->idx, scratch, tmp); | ||
871 | r = -EINVAL; | ||
872 | } | ||
873 | amdgpu_gfx_scratch_free(adev, scratch); | 866 | amdgpu_gfx_scratch_free(adev, scratch); |
874 | return r; | 867 | return r; |
875 | } | 868 | } |
@@ -886,19 +879,16 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
886 | long r; | 879 | long r; |
887 | 880 | ||
888 | r = amdgpu_device_wb_get(adev, &index); | 881 | r = amdgpu_device_wb_get(adev, &index); |
889 | if (r) { | 882 | if (r) |
890 | dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r); | ||
891 | return r; | 883 | return r; |
892 | } | ||
893 | 884 | ||
894 | gpu_addr = adev->wb.gpu_addr + (index * 4); | 885 | gpu_addr = adev->wb.gpu_addr + (index * 4); |
895 | adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); | 886 | adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); |
896 | memset(&ib, 0, sizeof(ib)); | 887 | memset(&ib, 0, sizeof(ib)); |
897 | r = amdgpu_ib_get(adev, NULL, 16, &ib); | 888 | r = amdgpu_ib_get(adev, NULL, 16, &ib); |
898 | if (r) { | 889 | if (r) |
899 | DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r); | ||
900 | goto err1; | 890 | goto err1; |
901 | } | 891 | |
902 | ib.ptr[0] = PACKET3(PACKET3_WRITE_DATA, 3); | 892 | ib.ptr[0] = PACKET3(PACKET3_WRITE_DATA, 3); |
903 | ib.ptr[1] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM; | 893 | ib.ptr[1] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM; |
904 | ib.ptr[2] = lower_32_bits(gpu_addr); | 894 | ib.ptr[2] = lower_32_bits(gpu_addr); |
@@ -912,22 +902,17 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
912 | 902 | ||
913 | r = dma_fence_wait_timeout(f, false, timeout); | 903 | r = dma_fence_wait_timeout(f, false, timeout); |
914 | if (r == 0) { | 904 | if (r == 0) { |
915 | DRM_ERROR("amdgpu: IB test timed out.\n"); | ||
916 | r = -ETIMEDOUT; | 905 | r = -ETIMEDOUT; |
917 | goto err2; | 906 | goto err2; |
918 | } else if (r < 0) { | 907 | } else if (r < 0) { |
919 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | ||
920 | goto err2; | 908 | goto err2; |
921 | } | 909 | } |
922 | 910 | ||
923 | tmp = adev->wb.wb[index]; | 911 | tmp = adev->wb.wb[index]; |
924 | if (tmp == 0xDEADBEEF) { | 912 | if (tmp == 0xDEADBEEF) |
925 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | ||
926 | r = 0; | 913 | r = 0; |
927 | } else { | 914 | else |
928 | DRM_ERROR("ib test on ring %d failed\n", ring->idx); | ||
929 | r = -EINVAL; | 915 | r = -EINVAL; |
930 | } | ||
931 | 916 | ||
932 | err2: | 917 | err2: |
933 | amdgpu_ib_free(adev, &ib, NULL); | 918 | amdgpu_ib_free(adev, &ib, NULL); |
@@ -1298,81 +1283,16 @@ static void gfx_v8_0_get_csb_buffer(struct amdgpu_device *adev, | |||
1298 | buffer[count++] = cpu_to_le32(0); | 1283 | buffer[count++] = cpu_to_le32(0); |
1299 | } | 1284 | } |
1300 | 1285 | ||
1301 | static void cz_init_cp_jump_table(struct amdgpu_device *adev) | 1286 | static int gfx_v8_0_cp_jump_table_num(struct amdgpu_device *adev) |
1302 | { | 1287 | { |
1303 | const __le32 *fw_data; | ||
1304 | volatile u32 *dst_ptr; | ||
1305 | int me, i, max_me = 4; | ||
1306 | u32 bo_offset = 0; | ||
1307 | u32 table_offset, table_size; | ||
1308 | |||
1309 | if (adev->asic_type == CHIP_CARRIZO) | 1288 | if (adev->asic_type == CHIP_CARRIZO) |
1310 | max_me = 5; | 1289 | return 5; |
1311 | 1290 | else | |
1312 | /* write the cp table buffer */ | 1291 | return 4; |
1313 | dst_ptr = adev->gfx.rlc.cp_table_ptr; | ||
1314 | for (me = 0; me < max_me; me++) { | ||
1315 | if (me == 0) { | ||
1316 | const struct gfx_firmware_header_v1_0 *hdr = | ||
1317 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.ce_fw->data; | ||
1318 | fw_data = (const __le32 *) | ||
1319 | (adev->gfx.ce_fw->data + | ||
1320 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
1321 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
1322 | table_size = le32_to_cpu(hdr->jt_size); | ||
1323 | } else if (me == 1) { | ||
1324 | const struct gfx_firmware_header_v1_0 *hdr = | ||
1325 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.pfp_fw->data; | ||
1326 | fw_data = (const __le32 *) | ||
1327 | (adev->gfx.pfp_fw->data + | ||
1328 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
1329 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
1330 | table_size = le32_to_cpu(hdr->jt_size); | ||
1331 | } else if (me == 2) { | ||
1332 | const struct gfx_firmware_header_v1_0 *hdr = | ||
1333 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.me_fw->data; | ||
1334 | fw_data = (const __le32 *) | ||
1335 | (adev->gfx.me_fw->data + | ||
1336 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
1337 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
1338 | table_size = le32_to_cpu(hdr->jt_size); | ||
1339 | } else if (me == 3) { | ||
1340 | const struct gfx_firmware_header_v1_0 *hdr = | ||
1341 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data; | ||
1342 | fw_data = (const __le32 *) | ||
1343 | (adev->gfx.mec_fw->data + | ||
1344 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
1345 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
1346 | table_size = le32_to_cpu(hdr->jt_size); | ||
1347 | } else if (me == 4) { | ||
1348 | const struct gfx_firmware_header_v1_0 *hdr = | ||
1349 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec2_fw->data; | ||
1350 | fw_data = (const __le32 *) | ||
1351 | (adev->gfx.mec2_fw->data + | ||
1352 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
1353 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
1354 | table_size = le32_to_cpu(hdr->jt_size); | ||
1355 | } | ||
1356 | |||
1357 | for (i = 0; i < table_size; i ++) { | ||
1358 | dst_ptr[bo_offset + i] = | ||
1359 | cpu_to_le32(le32_to_cpu(fw_data[table_offset + i])); | ||
1360 | } | ||
1361 | |||
1362 | bo_offset += table_size; | ||
1363 | } | ||
1364 | } | ||
1365 | |||
1366 | static void gfx_v8_0_rlc_fini(struct amdgpu_device *adev) | ||
1367 | { | ||
1368 | amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, NULL, NULL); | ||
1369 | amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj, NULL, NULL); | ||
1370 | } | 1292 | } |
1371 | 1293 | ||
1372 | static int gfx_v8_0_rlc_init(struct amdgpu_device *adev) | 1294 | static int gfx_v8_0_rlc_init(struct amdgpu_device *adev) |
1373 | { | 1295 | { |
1374 | volatile u32 *dst_ptr; | ||
1375 | u32 dws; | ||
1376 | const struct cs_section_def *cs_data; | 1296 | const struct cs_section_def *cs_data; |
1377 | int r; | 1297 | int r; |
1378 | 1298 | ||
@@ -1381,44 +1301,18 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev) | |||
1381 | cs_data = adev->gfx.rlc.cs_data; | 1301 | cs_data = adev->gfx.rlc.cs_data; |
1382 | 1302 | ||
1383 | if (cs_data) { | 1303 | if (cs_data) { |
1384 | /* clear state block */ | 1304 | /* init clear state block */ |
1385 | adev->gfx.rlc.clear_state_size = dws = gfx_v8_0_get_csb_size(adev); | 1305 | r = amdgpu_gfx_rlc_init_csb(adev); |
1386 | 1306 | if (r) | |
1387 | r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE, | ||
1388 | AMDGPU_GEM_DOMAIN_VRAM, | ||
1389 | &adev->gfx.rlc.clear_state_obj, | ||
1390 | &adev->gfx.rlc.clear_state_gpu_addr, | ||
1391 | (void **)&adev->gfx.rlc.cs_ptr); | ||
1392 | if (r) { | ||
1393 | dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r); | ||
1394 | gfx_v8_0_rlc_fini(adev); | ||
1395 | return r; | 1307 | return r; |
1396 | } | ||
1397 | |||
1398 | /* set up the cs buffer */ | ||
1399 | dst_ptr = adev->gfx.rlc.cs_ptr; | ||
1400 | gfx_v8_0_get_csb_buffer(adev, dst_ptr); | ||
1401 | amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj); | ||
1402 | amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); | ||
1403 | } | 1308 | } |
1404 | 1309 | ||
1405 | if ((adev->asic_type == CHIP_CARRIZO) || | 1310 | if ((adev->asic_type == CHIP_CARRIZO) || |
1406 | (adev->asic_type == CHIP_STONEY)) { | 1311 | (adev->asic_type == CHIP_STONEY)) { |
1407 | adev->gfx.rlc.cp_table_size = ALIGN(96 * 5 * 4, 2048) + (64 * 1024); /* JT + GDS */ | 1312 | adev->gfx.rlc.cp_table_size = ALIGN(96 * 5 * 4, 2048) + (64 * 1024); /* JT + GDS */ |
1408 | r = amdgpu_bo_create_reserved(adev, adev->gfx.rlc.cp_table_size, | 1313 | r = amdgpu_gfx_rlc_init_cpt(adev); |
1409 | PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, | 1314 | if (r) |
1410 | &adev->gfx.rlc.cp_table_obj, | ||
1411 | &adev->gfx.rlc.cp_table_gpu_addr, | ||
1412 | (void **)&adev->gfx.rlc.cp_table_ptr); | ||
1413 | if (r) { | ||
1414 | dev_warn(adev->dev, "(%d) create RLC cp table bo failed\n", r); | ||
1415 | return r; | 1315 | return r; |
1416 | } | ||
1417 | |||
1418 | cz_init_cp_jump_table(adev); | ||
1419 | |||
1420 | amdgpu_bo_kunmap(adev->gfx.rlc.cp_table_obj); | ||
1421 | amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj); | ||
1422 | } | 1316 | } |
1423 | 1317 | ||
1424 | return 0; | 1318 | return 0; |
@@ -1443,7 +1337,7 @@ static int gfx_v8_0_mec_init(struct amdgpu_device *adev) | |||
1443 | mec_hpd_size = adev->gfx.num_compute_rings * GFX8_MEC_HPD_SIZE; | 1337 | mec_hpd_size = adev->gfx.num_compute_rings * GFX8_MEC_HPD_SIZE; |
1444 | 1338 | ||
1445 | r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE, | 1339 | r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE, |
1446 | AMDGPU_GEM_DOMAIN_GTT, | 1340 | AMDGPU_GEM_DOMAIN_VRAM, |
1447 | &adev->gfx.mec.hpd_eop_obj, | 1341 | &adev->gfx.mec.hpd_eop_obj, |
1448 | &adev->gfx.mec.hpd_eop_gpu_addr, | 1342 | &adev->gfx.mec.hpd_eop_gpu_addr, |
1449 | (void **)&hpd); | 1343 | (void **)&hpd); |
@@ -1629,7 +1523,7 @@ static int gfx_v8_0_do_edc_gpr_workarounds(struct amdgpu_device *adev) | |||
1629 | return 0; | 1523 | return 0; |
1630 | 1524 | ||
1631 | /* bail if the compute ring is not ready */ | 1525 | /* bail if the compute ring is not ready */ |
1632 | if (!ring->ready) | 1526 | if (!ring->sched.ready) |
1633 | return 0; | 1527 | return 0; |
1634 | 1528 | ||
1635 | tmp = RREG32(mmGB_EDC_MODE); | 1529 | tmp = RREG32(mmGB_EDC_MODE); |
@@ -2088,7 +1982,7 @@ static int gfx_v8_0_sw_init(void *handle) | |||
2088 | return r; | 1982 | return r; |
2089 | } | 1983 | } |
2090 | 1984 | ||
2091 | r = gfx_v8_0_rlc_init(adev); | 1985 | r = adev->gfx.rlc.funcs->init(adev); |
2092 | if (r) { | 1986 | if (r) { |
2093 | DRM_ERROR("Failed to init rlc BOs!\n"); | 1987 | DRM_ERROR("Failed to init rlc BOs!\n"); |
2094 | return r; | 1988 | return r; |
@@ -2181,7 +2075,7 @@ static int gfx_v8_0_sw_fini(void *handle) | |||
2181 | amdgpu_gfx_kiq_fini(adev); | 2075 | amdgpu_gfx_kiq_fini(adev); |
2182 | 2076 | ||
2183 | gfx_v8_0_mec_fini(adev); | 2077 | gfx_v8_0_mec_fini(adev); |
2184 | gfx_v8_0_rlc_fini(adev); | 2078 | amdgpu_gfx_rlc_fini(adev); |
2185 | amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, | 2079 | amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, |
2186 | &adev->gfx.rlc.clear_state_gpu_addr, | 2080 | &adev->gfx.rlc.clear_state_gpu_addr, |
2187 | (void **)&adev->gfx.rlc.cs_ptr); | 2081 | (void **)&adev->gfx.rlc.cs_ptr); |
@@ -4175,10 +4069,10 @@ static void gfx_v8_0_rlc_start(struct amdgpu_device *adev) | |||
4175 | 4069 | ||
4176 | static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev) | 4070 | static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev) |
4177 | { | 4071 | { |
4178 | gfx_v8_0_rlc_stop(adev); | 4072 | adev->gfx.rlc.funcs->stop(adev); |
4179 | gfx_v8_0_rlc_reset(adev); | 4073 | adev->gfx.rlc.funcs->reset(adev); |
4180 | gfx_v8_0_init_pg(adev); | 4074 | gfx_v8_0_init_pg(adev); |
4181 | gfx_v8_0_rlc_start(adev); | 4075 | adev->gfx.rlc.funcs->start(adev); |
4182 | 4076 | ||
4183 | return 0; | 4077 | return 0; |
4184 | } | 4078 | } |
@@ -4197,7 +4091,7 @@ static void gfx_v8_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable) | |||
4197 | tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, PFP_HALT, 1); | 4091 | tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, PFP_HALT, 1); |
4198 | tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_HALT, 1); | 4092 | tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_HALT, 1); |
4199 | for (i = 0; i < adev->gfx.num_gfx_rings; i++) | 4093 | for (i = 0; i < adev->gfx.num_gfx_rings; i++) |
4200 | adev->gfx.gfx_ring[i].ready = false; | 4094 | adev->gfx.gfx_ring[i].sched.ready = false; |
4201 | } | 4095 | } |
4202 | WREG32(mmCP_ME_CNTL, tmp); | 4096 | WREG32(mmCP_ME_CNTL, tmp); |
4203 | udelay(50); | 4097 | udelay(50); |
@@ -4379,10 +4273,8 @@ static int gfx_v8_0_cp_gfx_resume(struct amdgpu_device *adev) | |||
4379 | /* start the ring */ | 4273 | /* start the ring */ |
4380 | amdgpu_ring_clear_ring(ring); | 4274 | amdgpu_ring_clear_ring(ring); |
4381 | gfx_v8_0_cp_gfx_start(adev); | 4275 | gfx_v8_0_cp_gfx_start(adev); |
4382 | ring->ready = true; | 4276 | ring->sched.ready = true; |
4383 | r = amdgpu_ring_test_ring(ring); | 4277 | r = amdgpu_ring_test_helper(ring); |
4384 | if (r) | ||
4385 | ring->ready = false; | ||
4386 | 4278 | ||
4387 | return r; | 4279 | return r; |
4388 | } | 4280 | } |
@@ -4396,8 +4288,8 @@ static void gfx_v8_0_cp_compute_enable(struct amdgpu_device *adev, bool enable) | |||
4396 | } else { | 4288 | } else { |
4397 | WREG32(mmCP_MEC_CNTL, (CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK)); | 4289 | WREG32(mmCP_MEC_CNTL, (CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK)); |
4398 | for (i = 0; i < adev->gfx.num_compute_rings; i++) | 4290 | for (i = 0; i < adev->gfx.num_compute_rings; i++) |
4399 | adev->gfx.compute_ring[i].ready = false; | 4291 | adev->gfx.compute_ring[i].sched.ready = false; |
4400 | adev->gfx.kiq.ring.ready = false; | 4292 | adev->gfx.kiq.ring.sched.ready = false; |
4401 | } | 4293 | } |
4402 | udelay(50); | 4294 | udelay(50); |
4403 | } | 4295 | } |
@@ -4473,11 +4365,9 @@ static int gfx_v8_0_kiq_kcq_enable(struct amdgpu_device *adev) | |||
4473 | amdgpu_ring_write(kiq_ring, upper_32_bits(wptr_addr)); | 4365 | amdgpu_ring_write(kiq_ring, upper_32_bits(wptr_addr)); |
4474 | } | 4366 | } |
4475 | 4367 | ||
4476 | r = amdgpu_ring_test_ring(kiq_ring); | 4368 | r = amdgpu_ring_test_helper(kiq_ring); |
4477 | if (r) { | 4369 | if (r) |
4478 | DRM_ERROR("KCQ enable failed\n"); | 4370 | DRM_ERROR("KCQ enable failed\n"); |
4479 | kiq_ring->ready = false; | ||
4480 | } | ||
4481 | return r; | 4371 | return r; |
4482 | } | 4372 | } |
4483 | 4373 | ||
@@ -4781,7 +4671,7 @@ static int gfx_v8_0_kiq_resume(struct amdgpu_device *adev) | |||
4781 | amdgpu_bo_kunmap(ring->mqd_obj); | 4671 | amdgpu_bo_kunmap(ring->mqd_obj); |
4782 | ring->mqd_ptr = NULL; | 4672 | ring->mqd_ptr = NULL; |
4783 | amdgpu_bo_unreserve(ring->mqd_obj); | 4673 | amdgpu_bo_unreserve(ring->mqd_obj); |
4784 | ring->ready = true; | 4674 | ring->sched.ready = true; |
4785 | return 0; | 4675 | return 0; |
4786 | } | 4676 | } |
4787 | 4677 | ||
@@ -4820,10 +4710,7 @@ static int gfx_v8_0_kcq_resume(struct amdgpu_device *adev) | |||
4820 | */ | 4710 | */ |
4821 | for (i = adev->gfx.num_compute_rings - 1; i >= 0; i--) { | 4711 | for (i = adev->gfx.num_compute_rings - 1; i >= 0; i--) { |
4822 | ring = &adev->gfx.compute_ring[i]; | 4712 | ring = &adev->gfx.compute_ring[i]; |
4823 | ring->ready = true; | 4713 | r = amdgpu_ring_test_helper(ring); |
4824 | r = amdgpu_ring_test_ring(ring); | ||
4825 | if (r) | ||
4826 | ring->ready = false; | ||
4827 | } | 4714 | } |
4828 | 4715 | ||
4829 | done: | 4716 | done: |
@@ -4867,7 +4754,7 @@ static int gfx_v8_0_hw_init(void *handle) | |||
4867 | gfx_v8_0_init_golden_registers(adev); | 4754 | gfx_v8_0_init_golden_registers(adev); |
4868 | gfx_v8_0_constants_init(adev); | 4755 | gfx_v8_0_constants_init(adev); |
4869 | 4756 | ||
4870 | r = gfx_v8_0_rlc_resume(adev); | 4757 | r = adev->gfx.rlc.funcs->resume(adev); |
4871 | if (r) | 4758 | if (r) |
4872 | return r; | 4759 | return r; |
4873 | 4760 | ||
@@ -4899,7 +4786,7 @@ static int gfx_v8_0_kcq_disable(struct amdgpu_device *adev) | |||
4899 | amdgpu_ring_write(kiq_ring, 0); | 4786 | amdgpu_ring_write(kiq_ring, 0); |
4900 | amdgpu_ring_write(kiq_ring, 0); | 4787 | amdgpu_ring_write(kiq_ring, 0); |
4901 | } | 4788 | } |
4902 | r = amdgpu_ring_test_ring(kiq_ring); | 4789 | r = amdgpu_ring_test_helper(kiq_ring); |
4903 | if (r) | 4790 | if (r) |
4904 | DRM_ERROR("KCQ disable failed\n"); | 4791 | DRM_ERROR("KCQ disable failed\n"); |
4905 | 4792 | ||
@@ -4973,16 +4860,16 @@ static int gfx_v8_0_hw_fini(void *handle) | |||
4973 | pr_debug("For SRIOV client, shouldn't do anything.\n"); | 4860 | pr_debug("For SRIOV client, shouldn't do anything.\n"); |
4974 | return 0; | 4861 | return 0; |
4975 | } | 4862 | } |
4976 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 4863 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
4977 | if (!gfx_v8_0_wait_for_idle(adev)) | 4864 | if (!gfx_v8_0_wait_for_idle(adev)) |
4978 | gfx_v8_0_cp_enable(adev, false); | 4865 | gfx_v8_0_cp_enable(adev, false); |
4979 | else | 4866 | else |
4980 | pr_err("cp is busy, skip halt cp\n"); | 4867 | pr_err("cp is busy, skip halt cp\n"); |
4981 | if (!gfx_v8_0_wait_for_rlc_idle(adev)) | 4868 | if (!gfx_v8_0_wait_for_rlc_idle(adev)) |
4982 | gfx_v8_0_rlc_stop(adev); | 4869 | adev->gfx.rlc.funcs->stop(adev); |
4983 | else | 4870 | else |
4984 | pr_err("rlc is busy, skip halt rlc\n"); | 4871 | pr_err("rlc is busy, skip halt rlc\n"); |
4985 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 4872 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
4986 | return 0; | 4873 | return 0; |
4987 | } | 4874 | } |
4988 | 4875 | ||
@@ -5071,7 +4958,7 @@ static int gfx_v8_0_pre_soft_reset(void *handle) | |||
5071 | srbm_soft_reset = adev->gfx.srbm_soft_reset; | 4958 | srbm_soft_reset = adev->gfx.srbm_soft_reset; |
5072 | 4959 | ||
5073 | /* stop the rlc */ | 4960 | /* stop the rlc */ |
5074 | gfx_v8_0_rlc_stop(adev); | 4961 | adev->gfx.rlc.funcs->stop(adev); |
5075 | 4962 | ||
5076 | if (REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CP) || | 4963 | if (REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CP) || |
5077 | REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_GFX)) | 4964 | REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_GFX)) |
@@ -5197,7 +5084,7 @@ static int gfx_v8_0_post_soft_reset(void *handle) | |||
5197 | REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_GFX)) | 5084 | REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_GFX)) |
5198 | gfx_v8_0_cp_gfx_resume(adev); | 5085 | gfx_v8_0_cp_gfx_resume(adev); |
5199 | 5086 | ||
5200 | gfx_v8_0_rlc_start(adev); | 5087 | adev->gfx.rlc.funcs->start(adev); |
5201 | 5088 | ||
5202 | return 0; | 5089 | return 0; |
5203 | } | 5090 | } |
@@ -5445,7 +5332,7 @@ static int gfx_v8_0_set_powergating_state(void *handle, | |||
5445 | AMD_PG_SUPPORT_RLC_SMU_HS | | 5332 | AMD_PG_SUPPORT_RLC_SMU_HS | |
5446 | AMD_PG_SUPPORT_CP | | 5333 | AMD_PG_SUPPORT_CP | |
5447 | AMD_PG_SUPPORT_GFX_DMG)) | 5334 | AMD_PG_SUPPORT_GFX_DMG)) |
5448 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 5335 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
5449 | switch (adev->asic_type) { | 5336 | switch (adev->asic_type) { |
5450 | case CHIP_CARRIZO: | 5337 | case CHIP_CARRIZO: |
5451 | case CHIP_STONEY: | 5338 | case CHIP_STONEY: |
@@ -5499,7 +5386,7 @@ static int gfx_v8_0_set_powergating_state(void *handle, | |||
5499 | AMD_PG_SUPPORT_RLC_SMU_HS | | 5386 | AMD_PG_SUPPORT_RLC_SMU_HS | |
5500 | AMD_PG_SUPPORT_CP | | 5387 | AMD_PG_SUPPORT_CP | |
5501 | AMD_PG_SUPPORT_GFX_DMG)) | 5388 | AMD_PG_SUPPORT_GFX_DMG)) |
5502 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 5389 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
5503 | return 0; | 5390 | return 0; |
5504 | } | 5391 | } |
5505 | 5392 | ||
@@ -5593,57 +5480,53 @@ static void gfx_v8_0_send_serdes_cmd(struct amdgpu_device *adev, | |||
5593 | #define RLC_GPR_REG2__MESSAGE__SHIFT 0x00000001 | 5480 | #define RLC_GPR_REG2__MESSAGE__SHIFT 0x00000001 |
5594 | #define RLC_GPR_REG2__MESSAGE_MASK 0x0000001e | 5481 | #define RLC_GPR_REG2__MESSAGE_MASK 0x0000001e |
5595 | 5482 | ||
5596 | static void iceland_enter_rlc_safe_mode(struct amdgpu_device *adev) | 5483 | static bool gfx_v8_0_is_rlc_enabled(struct amdgpu_device *adev) |
5597 | { | 5484 | { |
5598 | u32 data; | 5485 | uint32_t rlc_setting; |
5599 | unsigned i; | ||
5600 | 5486 | ||
5601 | data = RREG32(mmRLC_CNTL); | 5487 | rlc_setting = RREG32(mmRLC_CNTL); |
5602 | if (!(data & RLC_CNTL__RLC_ENABLE_F32_MASK)) | 5488 | if (!(rlc_setting & RLC_CNTL__RLC_ENABLE_F32_MASK)) |
5603 | return; | 5489 | return false; |
5604 | 5490 | ||
5605 | if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_MGCG)) { | 5491 | return true; |
5606 | data |= RLC_SAFE_MODE__CMD_MASK; | 5492 | } |
5607 | data &= ~RLC_SAFE_MODE__MESSAGE_MASK; | ||
5608 | data |= (1 << RLC_SAFE_MODE__MESSAGE__SHIFT); | ||
5609 | WREG32(mmRLC_SAFE_MODE, data); | ||
5610 | 5493 | ||
5611 | for (i = 0; i < adev->usec_timeout; i++) { | 5494 | static void gfx_v8_0_set_safe_mode(struct amdgpu_device *adev) |
5612 | if ((RREG32(mmRLC_GPM_STAT) & | 5495 | { |
5613 | (RLC_GPM_STAT__GFX_CLOCK_STATUS_MASK | | 5496 | uint32_t data; |
5614 | RLC_GPM_STAT__GFX_POWER_STATUS_MASK)) == | 5497 | unsigned i; |
5615 | (RLC_GPM_STAT__GFX_CLOCK_STATUS_MASK | | 5498 | data = RREG32(mmRLC_CNTL); |
5616 | RLC_GPM_STAT__GFX_POWER_STATUS_MASK)) | 5499 | data |= RLC_SAFE_MODE__CMD_MASK; |
5617 | break; | 5500 | data &= ~RLC_SAFE_MODE__MESSAGE_MASK; |
5618 | udelay(1); | 5501 | data |= (1 << RLC_SAFE_MODE__MESSAGE__SHIFT); |
5619 | } | 5502 | WREG32(mmRLC_SAFE_MODE, data); |
5620 | 5503 | ||
5621 | for (i = 0; i < adev->usec_timeout; i++) { | 5504 | /* wait for RLC_SAFE_MODE */ |
5622 | if (!REG_GET_FIELD(RREG32(mmRLC_SAFE_MODE), RLC_SAFE_MODE, CMD)) | 5505 | for (i = 0; i < adev->usec_timeout; i++) { |
5623 | break; | 5506 | if ((RREG32(mmRLC_GPM_STAT) & |
5624 | udelay(1); | 5507 | (RLC_GPM_STAT__GFX_CLOCK_STATUS_MASK | |
5625 | } | 5508 | RLC_GPM_STAT__GFX_POWER_STATUS_MASK)) == |
5626 | adev->gfx.rlc.in_safe_mode = true; | 5509 | (RLC_GPM_STAT__GFX_CLOCK_STATUS_MASK | |
5510 | RLC_GPM_STAT__GFX_POWER_STATUS_MASK)) | ||
5511 | break; | ||
5512 | udelay(1); | ||
5513 | } | ||
5514 | for (i = 0; i < adev->usec_timeout; i++) { | ||
5515 | if (!REG_GET_FIELD(RREG32(mmRLC_SAFE_MODE), RLC_SAFE_MODE, CMD)) | ||
5516 | break; | ||
5517 | udelay(1); | ||
5627 | } | 5518 | } |
5628 | } | 5519 | } |
5629 | 5520 | ||
5630 | static void iceland_exit_rlc_safe_mode(struct amdgpu_device *adev) | 5521 | static void gfx_v8_0_unset_safe_mode(struct amdgpu_device *adev) |
5631 | { | 5522 | { |
5632 | u32 data = 0; | 5523 | uint32_t data; |
5633 | unsigned i; | 5524 | unsigned i; |
5634 | 5525 | ||
5635 | data = RREG32(mmRLC_CNTL); | 5526 | data = RREG32(mmRLC_CNTL); |
5636 | if (!(data & RLC_CNTL__RLC_ENABLE_F32_MASK)) | 5527 | data |= RLC_SAFE_MODE__CMD_MASK; |
5637 | return; | 5528 | data &= ~RLC_SAFE_MODE__MESSAGE_MASK; |
5638 | 5529 | WREG32(mmRLC_SAFE_MODE, data); | |
5639 | if (adev->cg_flags & (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_MGCG)) { | ||
5640 | if (adev->gfx.rlc.in_safe_mode) { | ||
5641 | data |= RLC_SAFE_MODE__CMD_MASK; | ||
5642 | data &= ~RLC_SAFE_MODE__MESSAGE_MASK; | ||
5643 | WREG32(mmRLC_SAFE_MODE, data); | ||
5644 | adev->gfx.rlc.in_safe_mode = false; | ||
5645 | } | ||
5646 | } | ||
5647 | 5530 | ||
5648 | for (i = 0; i < adev->usec_timeout; i++) { | 5531 | for (i = 0; i < adev->usec_timeout; i++) { |
5649 | if (!REG_GET_FIELD(RREG32(mmRLC_SAFE_MODE), RLC_SAFE_MODE, CMD)) | 5532 | if (!REG_GET_FIELD(RREG32(mmRLC_SAFE_MODE), RLC_SAFE_MODE, CMD)) |
@@ -5653,8 +5536,17 @@ static void iceland_exit_rlc_safe_mode(struct amdgpu_device *adev) | |||
5653 | } | 5536 | } |
5654 | 5537 | ||
5655 | static const struct amdgpu_rlc_funcs iceland_rlc_funcs = { | 5538 | static const struct amdgpu_rlc_funcs iceland_rlc_funcs = { |
5656 | .enter_safe_mode = iceland_enter_rlc_safe_mode, | 5539 | .is_rlc_enabled = gfx_v8_0_is_rlc_enabled, |
5657 | .exit_safe_mode = iceland_exit_rlc_safe_mode | 5540 | .set_safe_mode = gfx_v8_0_set_safe_mode, |
5541 | .unset_safe_mode = gfx_v8_0_unset_safe_mode, | ||
5542 | .init = gfx_v8_0_rlc_init, | ||
5543 | .get_csb_size = gfx_v8_0_get_csb_size, | ||
5544 | .get_csb_buffer = gfx_v8_0_get_csb_buffer, | ||
5545 | .get_cp_table_num = gfx_v8_0_cp_jump_table_num, | ||
5546 | .resume = gfx_v8_0_rlc_resume, | ||
5547 | .stop = gfx_v8_0_rlc_stop, | ||
5548 | .reset = gfx_v8_0_rlc_reset, | ||
5549 | .start = gfx_v8_0_rlc_start | ||
5658 | }; | 5550 | }; |
5659 | 5551 | ||
5660 | static void gfx_v8_0_update_medium_grain_clock_gating(struct amdgpu_device *adev, | 5552 | static void gfx_v8_0_update_medium_grain_clock_gating(struct amdgpu_device *adev, |
@@ -5662,7 +5554,7 @@ static void gfx_v8_0_update_medium_grain_clock_gating(struct amdgpu_device *adev | |||
5662 | { | 5554 | { |
5663 | uint32_t temp, data; | 5555 | uint32_t temp, data; |
5664 | 5556 | ||
5665 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 5557 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
5666 | 5558 | ||
5667 | /* It is disabled by HW by default */ | 5559 | /* It is disabled by HW by default */ |
5668 | if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_MGCG)) { | 5560 | if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_MGCG)) { |
@@ -5758,7 +5650,7 @@ static void gfx_v8_0_update_medium_grain_clock_gating(struct amdgpu_device *adev | |||
5758 | gfx_v8_0_wait_for_rlc_serdes(adev); | 5650 | gfx_v8_0_wait_for_rlc_serdes(adev); |
5759 | } | 5651 | } |
5760 | 5652 | ||
5761 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 5653 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
5762 | } | 5654 | } |
5763 | 5655 | ||
5764 | static void gfx_v8_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev, | 5656 | static void gfx_v8_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev, |
@@ -5768,7 +5660,7 @@ static void gfx_v8_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev | |||
5768 | 5660 | ||
5769 | temp = data = RREG32(mmRLC_CGCG_CGLS_CTRL); | 5661 | temp = data = RREG32(mmRLC_CGCG_CGLS_CTRL); |
5770 | 5662 | ||
5771 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 5663 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
5772 | 5664 | ||
5773 | if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGCG)) { | 5665 | if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGCG)) { |
5774 | temp1 = data1 = RREG32(mmRLC_CGTT_MGCG_OVERRIDE); | 5666 | temp1 = data1 = RREG32(mmRLC_CGTT_MGCG_OVERRIDE); |
@@ -5851,7 +5743,7 @@ static void gfx_v8_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev | |||
5851 | 5743 | ||
5852 | gfx_v8_0_wait_for_rlc_serdes(adev); | 5744 | gfx_v8_0_wait_for_rlc_serdes(adev); |
5853 | 5745 | ||
5854 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 5746 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
5855 | } | 5747 | } |
5856 | static int gfx_v8_0_update_gfx_clock_gating(struct amdgpu_device *adev, | 5748 | static int gfx_v8_0_update_gfx_clock_gating(struct amdgpu_device *adev, |
5857 | bool enable) | 5749 | bool enable) |
@@ -6131,9 +6023,11 @@ static void gfx_v8_0_ring_emit_vgt_flush(struct amdgpu_ring *ring) | |||
6131 | } | 6023 | } |
6132 | 6024 | ||
6133 | static void gfx_v8_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, | 6025 | static void gfx_v8_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, |
6134 | struct amdgpu_ib *ib, | 6026 | struct amdgpu_job *job, |
6135 | unsigned vmid, bool ctx_switch) | 6027 | struct amdgpu_ib *ib, |
6028 | bool ctx_switch) | ||
6136 | { | 6029 | { |
6030 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
6137 | u32 header, control = 0; | 6031 | u32 header, control = 0; |
6138 | 6032 | ||
6139 | if (ib->flags & AMDGPU_IB_FLAG_CE) | 6033 | if (ib->flags & AMDGPU_IB_FLAG_CE) |
@@ -6161,9 +6055,11 @@ static void gfx_v8_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, | |||
6161 | } | 6055 | } |
6162 | 6056 | ||
6163 | static void gfx_v8_0_ring_emit_ib_compute(struct amdgpu_ring *ring, | 6057 | static void gfx_v8_0_ring_emit_ib_compute(struct amdgpu_ring *ring, |
6058 | struct amdgpu_job *job, | ||
6164 | struct amdgpu_ib *ib, | 6059 | struct amdgpu_ib *ib, |
6165 | unsigned vmid, bool ctx_switch) | 6060 | bool ctx_switch) |
6166 | { | 6061 | { |
6062 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
6167 | u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vmid << 24); | 6063 | u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vmid << 24); |
6168 | 6064 | ||
6169 | amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); | 6065 | amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); |
@@ -6738,12 +6634,39 @@ static int gfx_v8_0_eop_irq(struct amdgpu_device *adev, | |||
6738 | return 0; | 6634 | return 0; |
6739 | } | 6635 | } |
6740 | 6636 | ||
6637 | static void gfx_v8_0_fault(struct amdgpu_device *adev, | ||
6638 | struct amdgpu_iv_entry *entry) | ||
6639 | { | ||
6640 | u8 me_id, pipe_id, queue_id; | ||
6641 | struct amdgpu_ring *ring; | ||
6642 | int i; | ||
6643 | |||
6644 | me_id = (entry->ring_id & 0x0c) >> 2; | ||
6645 | pipe_id = (entry->ring_id & 0x03) >> 0; | ||
6646 | queue_id = (entry->ring_id & 0x70) >> 4; | ||
6647 | |||
6648 | switch (me_id) { | ||
6649 | case 0: | ||
6650 | drm_sched_fault(&adev->gfx.gfx_ring[0].sched); | ||
6651 | break; | ||
6652 | case 1: | ||
6653 | case 2: | ||
6654 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { | ||
6655 | ring = &adev->gfx.compute_ring[i]; | ||
6656 | if (ring->me == me_id && ring->pipe == pipe_id && | ||
6657 | ring->queue == queue_id) | ||
6658 | drm_sched_fault(&ring->sched); | ||
6659 | } | ||
6660 | break; | ||
6661 | } | ||
6662 | } | ||
6663 | |||
6741 | static int gfx_v8_0_priv_reg_irq(struct amdgpu_device *adev, | 6664 | static int gfx_v8_0_priv_reg_irq(struct amdgpu_device *adev, |
6742 | struct amdgpu_irq_src *source, | 6665 | struct amdgpu_irq_src *source, |
6743 | struct amdgpu_iv_entry *entry) | 6666 | struct amdgpu_iv_entry *entry) |
6744 | { | 6667 | { |
6745 | DRM_ERROR("Illegal register access in command stream\n"); | 6668 | DRM_ERROR("Illegal register access in command stream\n"); |
6746 | schedule_work(&adev->reset_work); | 6669 | gfx_v8_0_fault(adev, entry); |
6747 | return 0; | 6670 | return 0; |
6748 | } | 6671 | } |
6749 | 6672 | ||
@@ -6752,7 +6675,7 @@ static int gfx_v8_0_priv_inst_irq(struct amdgpu_device *adev, | |||
6752 | struct amdgpu_iv_entry *entry) | 6675 | struct amdgpu_iv_entry *entry) |
6753 | { | 6676 | { |
6754 | DRM_ERROR("Illegal instruction in command stream\n"); | 6677 | DRM_ERROR("Illegal instruction in command stream\n"); |
6755 | schedule_work(&adev->reset_work); | 6678 | gfx_v8_0_fault(adev, entry); |
6756 | return 0; | 6679 | return 0; |
6757 | } | 6680 | } |
6758 | 6681 | ||
@@ -6976,10 +6899,8 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_kiq = { | |||
6976 | 17 + /* gfx_v8_0_ring_emit_vm_flush */ | 6899 | 17 + /* gfx_v8_0_ring_emit_vm_flush */ |
6977 | 7 + 7 + 7, /* gfx_v8_0_ring_emit_fence_kiq x3 for user fence, vm fence */ | 6900 | 7 + 7 + 7, /* gfx_v8_0_ring_emit_fence_kiq x3 for user fence, vm fence */ |
6978 | .emit_ib_size = 4, /* gfx_v8_0_ring_emit_ib_compute */ | 6901 | .emit_ib_size = 4, /* gfx_v8_0_ring_emit_ib_compute */ |
6979 | .emit_ib = gfx_v8_0_ring_emit_ib_compute, | ||
6980 | .emit_fence = gfx_v8_0_ring_emit_fence_kiq, | 6902 | .emit_fence = gfx_v8_0_ring_emit_fence_kiq, |
6981 | .test_ring = gfx_v8_0_ring_test_ring, | 6903 | .test_ring = gfx_v8_0_ring_test_ring, |
6982 | .test_ib = gfx_v8_0_ring_test_ib, | ||
6983 | .insert_nop = amdgpu_ring_insert_nop, | 6904 | .insert_nop = amdgpu_ring_insert_nop, |
6984 | .pad_ib = amdgpu_ring_generic_pad_ib, | 6905 | .pad_ib = amdgpu_ring_generic_pad_ib, |
6985 | .emit_rreg = gfx_v8_0_ring_emit_rreg, | 6906 | .emit_rreg = gfx_v8_0_ring_emit_rreg, |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 6d7baf59d6e1..c27caa144c57 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #include "ivsrcid/gfx/irqsrcs_gfx_9_0.h" | 41 | #include "ivsrcid/gfx/irqsrcs_gfx_9_0.h" |
42 | 42 | ||
43 | #define GFX9_NUM_GFX_RINGS 1 | 43 | #define GFX9_NUM_GFX_RINGS 1 |
44 | #define GFX9_MEC_HPD_SIZE 2048 | 44 | #define GFX9_MEC_HPD_SIZE 4096 |
45 | #define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L | 45 | #define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L |
46 | #define RLC_SAVE_RESTORE_ADDR_STARTING_OFFSET 0x00000000L | 46 | #define RLC_SAVE_RESTORE_ADDR_STARTING_OFFSET 0x00000000L |
47 | 47 | ||
@@ -396,18 +396,14 @@ static int gfx_v9_0_ring_test_ring(struct amdgpu_ring *ring) | |||
396 | int r; | 396 | int r; |
397 | 397 | ||
398 | r = amdgpu_gfx_scratch_get(adev, &scratch); | 398 | r = amdgpu_gfx_scratch_get(adev, &scratch); |
399 | if (r) { | 399 | if (r) |
400 | DRM_ERROR("amdgpu: cp failed to get scratch reg (%d).\n", r); | ||
401 | return r; | 400 | return r; |
402 | } | 401 | |
403 | WREG32(scratch, 0xCAFEDEAD); | 402 | WREG32(scratch, 0xCAFEDEAD); |
404 | r = amdgpu_ring_alloc(ring, 3); | 403 | r = amdgpu_ring_alloc(ring, 3); |
405 | if (r) { | 404 | if (r) |
406 | DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", | 405 | goto error_free_scratch; |
407 | ring->idx, r); | 406 | |
408 | amdgpu_gfx_scratch_free(adev, scratch); | ||
409 | return r; | ||
410 | } | ||
411 | amdgpu_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1)); | 407 | amdgpu_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1)); |
412 | amdgpu_ring_write(ring, (scratch - PACKET3_SET_UCONFIG_REG_START)); | 408 | amdgpu_ring_write(ring, (scratch - PACKET3_SET_UCONFIG_REG_START)); |
413 | amdgpu_ring_write(ring, 0xDEADBEEF); | 409 | amdgpu_ring_write(ring, 0xDEADBEEF); |
@@ -419,14 +415,11 @@ static int gfx_v9_0_ring_test_ring(struct amdgpu_ring *ring) | |||
419 | break; | 415 | break; |
420 | DRM_UDELAY(1); | 416 | DRM_UDELAY(1); |
421 | } | 417 | } |
422 | if (i < adev->usec_timeout) { | 418 | |
423 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", | 419 | if (i >= adev->usec_timeout) |
424 | ring->idx, i); | 420 | r = -ETIMEDOUT; |
425 | } else { | 421 | |
426 | DRM_ERROR("amdgpu: ring %d test failed (scratch(0x%04X)=0x%08X)\n", | 422 | error_free_scratch: |
427 | ring->idx, scratch, tmp); | ||
428 | r = -EINVAL; | ||
429 | } | ||
430 | amdgpu_gfx_scratch_free(adev, scratch); | 423 | amdgpu_gfx_scratch_free(adev, scratch); |
431 | return r; | 424 | return r; |
432 | } | 425 | } |
@@ -443,19 +436,16 @@ static int gfx_v9_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
443 | long r; | 436 | long r; |
444 | 437 | ||
445 | r = amdgpu_device_wb_get(adev, &index); | 438 | r = amdgpu_device_wb_get(adev, &index); |
446 | if (r) { | 439 | if (r) |
447 | dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r); | ||
448 | return r; | 440 | return r; |
449 | } | ||
450 | 441 | ||
451 | gpu_addr = adev->wb.gpu_addr + (index * 4); | 442 | gpu_addr = adev->wb.gpu_addr + (index * 4); |
452 | adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); | 443 | adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); |
453 | memset(&ib, 0, sizeof(ib)); | 444 | memset(&ib, 0, sizeof(ib)); |
454 | r = amdgpu_ib_get(adev, NULL, 16, &ib); | 445 | r = amdgpu_ib_get(adev, NULL, 16, &ib); |
455 | if (r) { | 446 | if (r) |
456 | DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r); | ||
457 | goto err1; | 447 | goto err1; |
458 | } | 448 | |
459 | ib.ptr[0] = PACKET3(PACKET3_WRITE_DATA, 3); | 449 | ib.ptr[0] = PACKET3(PACKET3_WRITE_DATA, 3); |
460 | ib.ptr[1] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM; | 450 | ib.ptr[1] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM; |
461 | ib.ptr[2] = lower_32_bits(gpu_addr); | 451 | ib.ptr[2] = lower_32_bits(gpu_addr); |
@@ -469,22 +459,17 @@ static int gfx_v9_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
469 | 459 | ||
470 | r = dma_fence_wait_timeout(f, false, timeout); | 460 | r = dma_fence_wait_timeout(f, false, timeout); |
471 | if (r == 0) { | 461 | if (r == 0) { |
472 | DRM_ERROR("amdgpu: IB test timed out.\n"); | 462 | r = -ETIMEDOUT; |
473 | r = -ETIMEDOUT; | 463 | goto err2; |
474 | goto err2; | ||
475 | } else if (r < 0) { | 464 | } else if (r < 0) { |
476 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | 465 | goto err2; |
477 | goto err2; | ||
478 | } | 466 | } |
479 | 467 | ||
480 | tmp = adev->wb.wb[index]; | 468 | tmp = adev->wb.wb[index]; |
481 | if (tmp == 0xDEADBEEF) { | 469 | if (tmp == 0xDEADBEEF) |
482 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | 470 | r = 0; |
483 | r = 0; | 471 | else |
484 | } else { | 472 | r = -EINVAL; |
485 | DRM_ERROR("ib test on ring %d failed\n", ring->idx); | ||
486 | r = -EINVAL; | ||
487 | } | ||
488 | 473 | ||
489 | err2: | 474 | err2: |
490 | amdgpu_ib_free(adev, &ib, NULL); | 475 | amdgpu_ib_free(adev, &ib, NULL); |
@@ -1065,85 +1050,13 @@ static void gfx_v9_0_enable_lbpw(struct amdgpu_device *adev, bool enable) | |||
1065 | WREG32_FIELD15(GC, 0, RLC_LB_CNTL, LOAD_BALANCE_ENABLE, enable ? 1 : 0); | 1050 | WREG32_FIELD15(GC, 0, RLC_LB_CNTL, LOAD_BALANCE_ENABLE, enable ? 1 : 0); |
1066 | } | 1051 | } |
1067 | 1052 | ||
1068 | static void rv_init_cp_jump_table(struct amdgpu_device *adev) | 1053 | static int gfx_v9_0_cp_jump_table_num(struct amdgpu_device *adev) |
1069 | { | ||
1070 | const __le32 *fw_data; | ||
1071 | volatile u32 *dst_ptr; | ||
1072 | int me, i, max_me = 5; | ||
1073 | u32 bo_offset = 0; | ||
1074 | u32 table_offset, table_size; | ||
1075 | |||
1076 | /* write the cp table buffer */ | ||
1077 | dst_ptr = adev->gfx.rlc.cp_table_ptr; | ||
1078 | for (me = 0; me < max_me; me++) { | ||
1079 | if (me == 0) { | ||
1080 | const struct gfx_firmware_header_v1_0 *hdr = | ||
1081 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.ce_fw->data; | ||
1082 | fw_data = (const __le32 *) | ||
1083 | (adev->gfx.ce_fw->data + | ||
1084 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
1085 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
1086 | table_size = le32_to_cpu(hdr->jt_size); | ||
1087 | } else if (me == 1) { | ||
1088 | const struct gfx_firmware_header_v1_0 *hdr = | ||
1089 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.pfp_fw->data; | ||
1090 | fw_data = (const __le32 *) | ||
1091 | (adev->gfx.pfp_fw->data + | ||
1092 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
1093 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
1094 | table_size = le32_to_cpu(hdr->jt_size); | ||
1095 | } else if (me == 2) { | ||
1096 | const struct gfx_firmware_header_v1_0 *hdr = | ||
1097 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.me_fw->data; | ||
1098 | fw_data = (const __le32 *) | ||
1099 | (adev->gfx.me_fw->data + | ||
1100 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
1101 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
1102 | table_size = le32_to_cpu(hdr->jt_size); | ||
1103 | } else if (me == 3) { | ||
1104 | const struct gfx_firmware_header_v1_0 *hdr = | ||
1105 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data; | ||
1106 | fw_data = (const __le32 *) | ||
1107 | (adev->gfx.mec_fw->data + | ||
1108 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
1109 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
1110 | table_size = le32_to_cpu(hdr->jt_size); | ||
1111 | } else if (me == 4) { | ||
1112 | const struct gfx_firmware_header_v1_0 *hdr = | ||
1113 | (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec2_fw->data; | ||
1114 | fw_data = (const __le32 *) | ||
1115 | (adev->gfx.mec2_fw->data + | ||
1116 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | ||
1117 | table_offset = le32_to_cpu(hdr->jt_offset); | ||
1118 | table_size = le32_to_cpu(hdr->jt_size); | ||
1119 | } | ||
1120 | |||
1121 | for (i = 0; i < table_size; i ++) { | ||
1122 | dst_ptr[bo_offset + i] = | ||
1123 | cpu_to_le32(le32_to_cpu(fw_data[table_offset + i])); | ||
1124 | } | ||
1125 | |||
1126 | bo_offset += table_size; | ||
1127 | } | ||
1128 | } | ||
1129 | |||
1130 | static void gfx_v9_0_rlc_fini(struct amdgpu_device *adev) | ||
1131 | { | 1054 | { |
1132 | /* clear state block */ | 1055 | return 5; |
1133 | amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, | ||
1134 | &adev->gfx.rlc.clear_state_gpu_addr, | ||
1135 | (void **)&adev->gfx.rlc.cs_ptr); | ||
1136 | |||
1137 | /* jump table block */ | ||
1138 | amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj, | ||
1139 | &adev->gfx.rlc.cp_table_gpu_addr, | ||
1140 | (void **)&adev->gfx.rlc.cp_table_ptr); | ||
1141 | } | 1056 | } |
1142 | 1057 | ||
1143 | static int gfx_v9_0_rlc_init(struct amdgpu_device *adev) | 1058 | static int gfx_v9_0_rlc_init(struct amdgpu_device *adev) |
1144 | { | 1059 | { |
1145 | volatile u32 *dst_ptr; | ||
1146 | u32 dws; | ||
1147 | const struct cs_section_def *cs_data; | 1060 | const struct cs_section_def *cs_data; |
1148 | int r; | 1061 | int r; |
1149 | 1062 | ||
@@ -1152,45 +1065,18 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev) | |||
1152 | cs_data = adev->gfx.rlc.cs_data; | 1065 | cs_data = adev->gfx.rlc.cs_data; |
1153 | 1066 | ||
1154 | if (cs_data) { | 1067 | if (cs_data) { |
1155 | /* clear state block */ | 1068 | /* init clear state block */ |
1156 | adev->gfx.rlc.clear_state_size = dws = gfx_v9_0_get_csb_size(adev); | 1069 | r = amdgpu_gfx_rlc_init_csb(adev); |
1157 | r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE, | 1070 | if (r) |
1158 | AMDGPU_GEM_DOMAIN_VRAM, | ||
1159 | &adev->gfx.rlc.clear_state_obj, | ||
1160 | &adev->gfx.rlc.clear_state_gpu_addr, | ||
1161 | (void **)&adev->gfx.rlc.cs_ptr); | ||
1162 | if (r) { | ||
1163 | dev_err(adev->dev, "(%d) failed to create rlc csb bo\n", | ||
1164 | r); | ||
1165 | gfx_v9_0_rlc_fini(adev); | ||
1166 | return r; | 1071 | return r; |
1167 | } | ||
1168 | /* set up the cs buffer */ | ||
1169 | dst_ptr = adev->gfx.rlc.cs_ptr; | ||
1170 | gfx_v9_0_get_csb_buffer(adev, dst_ptr); | ||
1171 | amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj); | ||
1172 | amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj); | ||
1173 | amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); | ||
1174 | } | 1072 | } |
1175 | 1073 | ||
1176 | if (adev->asic_type == CHIP_RAVEN) { | 1074 | if (adev->asic_type == CHIP_RAVEN) { |
1177 | /* TODO: double check the cp_table_size for RV */ | 1075 | /* TODO: double check the cp_table_size for RV */ |
1178 | adev->gfx.rlc.cp_table_size = ALIGN(96 * 5 * 4, 2048) + (64 * 1024); /* JT + GDS */ | 1076 | adev->gfx.rlc.cp_table_size = ALIGN(96 * 5 * 4, 2048) + (64 * 1024); /* JT + GDS */ |
1179 | r = amdgpu_bo_create_reserved(adev, adev->gfx.rlc.cp_table_size, | 1077 | r = amdgpu_gfx_rlc_init_cpt(adev); |
1180 | PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, | 1078 | if (r) |
1181 | &adev->gfx.rlc.cp_table_obj, | ||
1182 | &adev->gfx.rlc.cp_table_gpu_addr, | ||
1183 | (void **)&adev->gfx.rlc.cp_table_ptr); | ||
1184 | if (r) { | ||
1185 | dev_err(adev->dev, | ||
1186 | "(%d) failed to create cp table bo\n", r); | ||
1187 | gfx_v9_0_rlc_fini(adev); | ||
1188 | return r; | 1079 | return r; |
1189 | } | ||
1190 | |||
1191 | rv_init_cp_jump_table(adev); | ||
1192 | amdgpu_bo_kunmap(adev->gfx.rlc.cp_table_obj); | ||
1193 | amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj); | ||
1194 | } | 1080 | } |
1195 | 1081 | ||
1196 | switch (adev->asic_type) { | 1082 | switch (adev->asic_type) { |
@@ -1264,7 +1150,7 @@ static int gfx_v9_0_mec_init(struct amdgpu_device *adev) | |||
1264 | mec_hpd_size = adev->gfx.num_compute_rings * GFX9_MEC_HPD_SIZE; | 1150 | mec_hpd_size = adev->gfx.num_compute_rings * GFX9_MEC_HPD_SIZE; |
1265 | 1151 | ||
1266 | r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE, | 1152 | r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE, |
1267 | AMDGPU_GEM_DOMAIN_GTT, | 1153 | AMDGPU_GEM_DOMAIN_VRAM, |
1268 | &adev->gfx.mec.hpd_eop_obj, | 1154 | &adev->gfx.mec.hpd_eop_obj, |
1269 | &adev->gfx.mec.hpd_eop_gpu_addr, | 1155 | &adev->gfx.mec.hpd_eop_gpu_addr, |
1270 | (void **)&hpd); | 1156 | (void **)&hpd); |
@@ -1635,8 +1521,8 @@ static int gfx_v9_0_ngg_en(struct amdgpu_device *adev) | |||
1635 | /* Clear GDS reserved memory */ | 1521 | /* Clear GDS reserved memory */ |
1636 | r = amdgpu_ring_alloc(ring, 17); | 1522 | r = amdgpu_ring_alloc(ring, 17); |
1637 | if (r) { | 1523 | if (r) { |
1638 | DRM_ERROR("amdgpu: NGG failed to lock ring %d (%d).\n", | 1524 | DRM_ERROR("amdgpu: NGG failed to lock ring %s (%d).\n", |
1639 | ring->idx, r); | 1525 | ring->name, r); |
1640 | return r; | 1526 | return r; |
1641 | } | 1527 | } |
1642 | 1528 | ||
@@ -1748,7 +1634,7 @@ static int gfx_v9_0_sw_init(void *handle) | |||
1748 | return r; | 1634 | return r; |
1749 | } | 1635 | } |
1750 | 1636 | ||
1751 | r = gfx_v9_0_rlc_init(adev); | 1637 | r = adev->gfx.rlc.funcs->init(adev); |
1752 | if (r) { | 1638 | if (r) { |
1753 | DRM_ERROR("Failed to init rlc BOs!\n"); | 1639 | DRM_ERROR("Failed to init rlc BOs!\n"); |
1754 | return r; | 1640 | return r; |
@@ -2498,12 +2384,12 @@ static int gfx_v9_0_rlc_resume(struct amdgpu_device *adev) | |||
2498 | return 0; | 2384 | return 0; |
2499 | } | 2385 | } |
2500 | 2386 | ||
2501 | gfx_v9_0_rlc_stop(adev); | 2387 | adev->gfx.rlc.funcs->stop(adev); |
2502 | 2388 | ||
2503 | /* disable CG */ | 2389 | /* disable CG */ |
2504 | WREG32_SOC15(GC, 0, mmRLC_CGCG_CGLS_CTRL, 0); | 2390 | WREG32_SOC15(GC, 0, mmRLC_CGCG_CGLS_CTRL, 0); |
2505 | 2391 | ||
2506 | gfx_v9_0_rlc_reset(adev); | 2392 | adev->gfx.rlc.funcs->reset(adev); |
2507 | 2393 | ||
2508 | gfx_v9_0_init_pg(adev); | 2394 | gfx_v9_0_init_pg(adev); |
2509 | 2395 | ||
@@ -2514,15 +2400,24 @@ static int gfx_v9_0_rlc_resume(struct amdgpu_device *adev) | |||
2514 | return r; | 2400 | return r; |
2515 | } | 2401 | } |
2516 | 2402 | ||
2517 | if (adev->asic_type == CHIP_RAVEN || | 2403 | switch (adev->asic_type) { |
2518 | adev->asic_type == CHIP_VEGA20) { | 2404 | case CHIP_RAVEN: |
2519 | if (amdgpu_lbpw != 0) | 2405 | if (amdgpu_lbpw == 0) |
2406 | gfx_v9_0_enable_lbpw(adev, false); | ||
2407 | else | ||
2408 | gfx_v9_0_enable_lbpw(adev, true); | ||
2409 | break; | ||
2410 | case CHIP_VEGA20: | ||
2411 | if (amdgpu_lbpw > 0) | ||
2520 | gfx_v9_0_enable_lbpw(adev, true); | 2412 | gfx_v9_0_enable_lbpw(adev, true); |
2521 | else | 2413 | else |
2522 | gfx_v9_0_enable_lbpw(adev, false); | 2414 | gfx_v9_0_enable_lbpw(adev, false); |
2415 | break; | ||
2416 | default: | ||
2417 | break; | ||
2523 | } | 2418 | } |
2524 | 2419 | ||
2525 | gfx_v9_0_rlc_start(adev); | 2420 | adev->gfx.rlc.funcs->start(adev); |
2526 | 2421 | ||
2527 | return 0; | 2422 | return 0; |
2528 | } | 2423 | } |
@@ -2537,7 +2432,7 @@ static void gfx_v9_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable) | |||
2537 | tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_HALT, enable ? 0 : 1); | 2432 | tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_HALT, enable ? 0 : 1); |
2538 | if (!enable) { | 2433 | if (!enable) { |
2539 | for (i = 0; i < adev->gfx.num_gfx_rings; i++) | 2434 | for (i = 0; i < adev->gfx.num_gfx_rings; i++) |
2540 | adev->gfx.gfx_ring[i].ready = false; | 2435 | adev->gfx.gfx_ring[i].sched.ready = false; |
2541 | } | 2436 | } |
2542 | WREG32_SOC15(GC, 0, mmCP_ME_CNTL, tmp); | 2437 | WREG32_SOC15(GC, 0, mmCP_ME_CNTL, tmp); |
2543 | udelay(50); | 2438 | udelay(50); |
@@ -2727,7 +2622,7 @@ static int gfx_v9_0_cp_gfx_resume(struct amdgpu_device *adev) | |||
2727 | 2622 | ||
2728 | /* start the ring */ | 2623 | /* start the ring */ |
2729 | gfx_v9_0_cp_gfx_start(adev); | 2624 | gfx_v9_0_cp_gfx_start(adev); |
2730 | ring->ready = true; | 2625 | ring->sched.ready = true; |
2731 | 2626 | ||
2732 | return 0; | 2627 | return 0; |
2733 | } | 2628 | } |
@@ -2742,8 +2637,8 @@ static void gfx_v9_0_cp_compute_enable(struct amdgpu_device *adev, bool enable) | |||
2742 | WREG32_SOC15(GC, 0, mmCP_MEC_CNTL, | 2637 | WREG32_SOC15(GC, 0, mmCP_MEC_CNTL, |
2743 | (CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK)); | 2638 | (CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK)); |
2744 | for (i = 0; i < adev->gfx.num_compute_rings; i++) | 2639 | for (i = 0; i < adev->gfx.num_compute_rings; i++) |
2745 | adev->gfx.compute_ring[i].ready = false; | 2640 | adev->gfx.compute_ring[i].sched.ready = false; |
2746 | adev->gfx.kiq.ring.ready = false; | 2641 | adev->gfx.kiq.ring.sched.ready = false; |
2747 | } | 2642 | } |
2748 | udelay(50); | 2643 | udelay(50); |
2749 | } | 2644 | } |
@@ -2866,11 +2761,9 @@ static int gfx_v9_0_kiq_kcq_enable(struct amdgpu_device *adev) | |||
2866 | amdgpu_ring_write(kiq_ring, upper_32_bits(wptr_addr)); | 2761 | amdgpu_ring_write(kiq_ring, upper_32_bits(wptr_addr)); |
2867 | } | 2762 | } |
2868 | 2763 | ||
2869 | r = amdgpu_ring_test_ring(kiq_ring); | 2764 | r = amdgpu_ring_test_helper(kiq_ring); |
2870 | if (r) { | 2765 | if (r) |
2871 | DRM_ERROR("KCQ enable failed\n"); | 2766 | DRM_ERROR("KCQ enable failed\n"); |
2872 | kiq_ring->ready = false; | ||
2873 | } | ||
2874 | 2767 | ||
2875 | return r; | 2768 | return r; |
2876 | } | 2769 | } |
@@ -3249,7 +3142,7 @@ static int gfx_v9_0_kiq_resume(struct amdgpu_device *adev) | |||
3249 | amdgpu_bo_kunmap(ring->mqd_obj); | 3142 | amdgpu_bo_kunmap(ring->mqd_obj); |
3250 | ring->mqd_ptr = NULL; | 3143 | ring->mqd_ptr = NULL; |
3251 | amdgpu_bo_unreserve(ring->mqd_obj); | 3144 | amdgpu_bo_unreserve(ring->mqd_obj); |
3252 | ring->ready = true; | 3145 | ring->sched.ready = true; |
3253 | return 0; | 3146 | return 0; |
3254 | } | 3147 | } |
3255 | 3148 | ||
@@ -3314,19 +3207,13 @@ static int gfx_v9_0_cp_resume(struct amdgpu_device *adev) | |||
3314 | return r; | 3207 | return r; |
3315 | 3208 | ||
3316 | ring = &adev->gfx.gfx_ring[0]; | 3209 | ring = &adev->gfx.gfx_ring[0]; |
3317 | r = amdgpu_ring_test_ring(ring); | 3210 | r = amdgpu_ring_test_helper(ring); |
3318 | if (r) { | 3211 | if (r) |
3319 | ring->ready = false; | ||
3320 | return r; | 3212 | return r; |
3321 | } | ||
3322 | 3213 | ||
3323 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { | 3214 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { |
3324 | ring = &adev->gfx.compute_ring[i]; | 3215 | ring = &adev->gfx.compute_ring[i]; |
3325 | 3216 | amdgpu_ring_test_helper(ring); | |
3326 | ring->ready = true; | ||
3327 | r = amdgpu_ring_test_ring(ring); | ||
3328 | if (r) | ||
3329 | ring->ready = false; | ||
3330 | } | 3217 | } |
3331 | 3218 | ||
3332 | gfx_v9_0_enable_gui_idle_interrupt(adev, true); | 3219 | gfx_v9_0_enable_gui_idle_interrupt(adev, true); |
@@ -3353,7 +3240,7 @@ static int gfx_v9_0_hw_init(void *handle) | |||
3353 | if (r) | 3240 | if (r) |
3354 | return r; | 3241 | return r; |
3355 | 3242 | ||
3356 | r = gfx_v9_0_rlc_resume(adev); | 3243 | r = adev->gfx.rlc.funcs->resume(adev); |
3357 | if (r) | 3244 | if (r) |
3358 | return r; | 3245 | return r; |
3359 | 3246 | ||
@@ -3391,7 +3278,7 @@ static int gfx_v9_0_kcq_disable(struct amdgpu_device *adev) | |||
3391 | amdgpu_ring_write(kiq_ring, 0); | 3278 | amdgpu_ring_write(kiq_ring, 0); |
3392 | amdgpu_ring_write(kiq_ring, 0); | 3279 | amdgpu_ring_write(kiq_ring, 0); |
3393 | } | 3280 | } |
3394 | r = amdgpu_ring_test_ring(kiq_ring); | 3281 | r = amdgpu_ring_test_helper(kiq_ring); |
3395 | if (r) | 3282 | if (r) |
3396 | DRM_ERROR("KCQ disable failed\n"); | 3283 | DRM_ERROR("KCQ disable failed\n"); |
3397 | 3284 | ||
@@ -3433,7 +3320,7 @@ static int gfx_v9_0_hw_fini(void *handle) | |||
3433 | } | 3320 | } |
3434 | 3321 | ||
3435 | gfx_v9_0_cp_enable(adev, false); | 3322 | gfx_v9_0_cp_enable(adev, false); |
3436 | gfx_v9_0_rlc_stop(adev); | 3323 | adev->gfx.rlc.funcs->stop(adev); |
3437 | 3324 | ||
3438 | gfx_v9_0_csb_vram_unpin(adev); | 3325 | gfx_v9_0_csb_vram_unpin(adev); |
3439 | 3326 | ||
@@ -3508,7 +3395,7 @@ static int gfx_v9_0_soft_reset(void *handle) | |||
3508 | 3395 | ||
3509 | if (grbm_soft_reset) { | 3396 | if (grbm_soft_reset) { |
3510 | /* stop the rlc */ | 3397 | /* stop the rlc */ |
3511 | gfx_v9_0_rlc_stop(adev); | 3398 | adev->gfx.rlc.funcs->stop(adev); |
3512 | 3399 | ||
3513 | /* Disable GFX parsing/prefetching */ | 3400 | /* Disable GFX parsing/prefetching */ |
3514 | gfx_v9_0_cp_gfx_enable(adev, false); | 3401 | gfx_v9_0_cp_gfx_enable(adev, false); |
@@ -3607,64 +3494,47 @@ static int gfx_v9_0_late_init(void *handle) | |||
3607 | return 0; | 3494 | return 0; |
3608 | } | 3495 | } |
3609 | 3496 | ||
3610 | static void gfx_v9_0_enter_rlc_safe_mode(struct amdgpu_device *adev) | 3497 | static bool gfx_v9_0_is_rlc_enabled(struct amdgpu_device *adev) |
3611 | { | 3498 | { |
3612 | uint32_t rlc_setting, data; | 3499 | uint32_t rlc_setting; |
3613 | unsigned i; | ||
3614 | |||
3615 | if (adev->gfx.rlc.in_safe_mode) | ||
3616 | return; | ||
3617 | 3500 | ||
3618 | /* if RLC is not enabled, do nothing */ | 3501 | /* if RLC is not enabled, do nothing */ |
3619 | rlc_setting = RREG32_SOC15(GC, 0, mmRLC_CNTL); | 3502 | rlc_setting = RREG32_SOC15(GC, 0, mmRLC_CNTL); |
3620 | if (!(rlc_setting & RLC_CNTL__RLC_ENABLE_F32_MASK)) | 3503 | if (!(rlc_setting & RLC_CNTL__RLC_ENABLE_F32_MASK)) |
3621 | return; | 3504 | return false; |
3622 | |||
3623 | if (adev->cg_flags & | ||
3624 | (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_MGCG | | ||
3625 | AMD_CG_SUPPORT_GFX_3D_CGCG)) { | ||
3626 | data = RLC_SAFE_MODE__CMD_MASK; | ||
3627 | data |= (1 << RLC_SAFE_MODE__MESSAGE__SHIFT); | ||
3628 | WREG32_SOC15(GC, 0, mmRLC_SAFE_MODE, data); | ||
3629 | 3505 | ||
3630 | /* wait for RLC_SAFE_MODE */ | 3506 | return true; |
3631 | for (i = 0; i < adev->usec_timeout; i++) { | ||
3632 | if (!REG_GET_FIELD(RREG32_SOC15(GC, 0, mmRLC_SAFE_MODE), RLC_SAFE_MODE, CMD)) | ||
3633 | break; | ||
3634 | udelay(1); | ||
3635 | } | ||
3636 | adev->gfx.rlc.in_safe_mode = true; | ||
3637 | } | ||
3638 | } | 3507 | } |
3639 | 3508 | ||
3640 | static void gfx_v9_0_exit_rlc_safe_mode(struct amdgpu_device *adev) | 3509 | static void gfx_v9_0_set_safe_mode(struct amdgpu_device *adev) |
3641 | { | 3510 | { |
3642 | uint32_t rlc_setting, data; | 3511 | uint32_t data; |
3643 | 3512 | unsigned i; | |
3644 | if (!adev->gfx.rlc.in_safe_mode) | ||
3645 | return; | ||
3646 | 3513 | ||
3647 | /* if RLC is not enabled, do nothing */ | 3514 | data = RLC_SAFE_MODE__CMD_MASK; |
3648 | rlc_setting = RREG32_SOC15(GC, 0, mmRLC_CNTL); | 3515 | data |= (1 << RLC_SAFE_MODE__MESSAGE__SHIFT); |
3649 | if (!(rlc_setting & RLC_CNTL__RLC_ENABLE_F32_MASK)) | 3516 | WREG32_SOC15(GC, 0, mmRLC_SAFE_MODE, data); |
3650 | return; | ||
3651 | 3517 | ||
3652 | if (adev->cg_flags & | 3518 | /* wait for RLC_SAFE_MODE */ |
3653 | (AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_MGCG)) { | 3519 | for (i = 0; i < adev->usec_timeout; i++) { |
3654 | /* | 3520 | if (!REG_GET_FIELD(RREG32_SOC15(GC, 0, mmRLC_SAFE_MODE), RLC_SAFE_MODE, CMD)) |
3655 | * Try to exit safe mode only if it is already in safe | 3521 | break; |
3656 | * mode. | 3522 | udelay(1); |
3657 | */ | ||
3658 | data = RLC_SAFE_MODE__CMD_MASK; | ||
3659 | WREG32_SOC15(GC, 0, mmRLC_SAFE_MODE, data); | ||
3660 | adev->gfx.rlc.in_safe_mode = false; | ||
3661 | } | 3523 | } |
3662 | } | 3524 | } |
3663 | 3525 | ||
3526 | static void gfx_v9_0_unset_safe_mode(struct amdgpu_device *adev) | ||
3527 | { | ||
3528 | uint32_t data; | ||
3529 | |||
3530 | data = RLC_SAFE_MODE__CMD_MASK; | ||
3531 | WREG32_SOC15(GC, 0, mmRLC_SAFE_MODE, data); | ||
3532 | } | ||
3533 | |||
3664 | static void gfx_v9_0_update_gfx_cg_power_gating(struct amdgpu_device *adev, | 3534 | static void gfx_v9_0_update_gfx_cg_power_gating(struct amdgpu_device *adev, |
3665 | bool enable) | 3535 | bool enable) |
3666 | { | 3536 | { |
3667 | gfx_v9_0_enter_rlc_safe_mode(adev); | 3537 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
3668 | 3538 | ||
3669 | if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_PG) && enable) { | 3539 | if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_PG) && enable) { |
3670 | gfx_v9_0_enable_gfx_cg_power_gating(adev, true); | 3540 | gfx_v9_0_enable_gfx_cg_power_gating(adev, true); |
@@ -3675,7 +3545,7 @@ static void gfx_v9_0_update_gfx_cg_power_gating(struct amdgpu_device *adev, | |||
3675 | gfx_v9_0_enable_gfx_pipeline_powergating(adev, false); | 3545 | gfx_v9_0_enable_gfx_pipeline_powergating(adev, false); |
3676 | } | 3546 | } |
3677 | 3547 | ||
3678 | gfx_v9_0_exit_rlc_safe_mode(adev); | 3548 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
3679 | } | 3549 | } |
3680 | 3550 | ||
3681 | static void gfx_v9_0_update_gfx_mg_power_gating(struct amdgpu_device *adev, | 3551 | static void gfx_v9_0_update_gfx_mg_power_gating(struct amdgpu_device *adev, |
@@ -3773,7 +3643,7 @@ static void gfx_v9_0_update_3d_clock_gating(struct amdgpu_device *adev, | |||
3773 | { | 3643 | { |
3774 | uint32_t data, def; | 3644 | uint32_t data, def; |
3775 | 3645 | ||
3776 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 3646 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
3777 | 3647 | ||
3778 | /* Enable 3D CGCG/CGLS */ | 3648 | /* Enable 3D CGCG/CGLS */ |
3779 | if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_3D_CGCG)) { | 3649 | if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_3D_CGCG)) { |
@@ -3813,7 +3683,7 @@ static void gfx_v9_0_update_3d_clock_gating(struct amdgpu_device *adev, | |||
3813 | WREG32_SOC15(GC, 0, mmRLC_CGCG_CGLS_CTRL_3D, data); | 3683 | WREG32_SOC15(GC, 0, mmRLC_CGCG_CGLS_CTRL_3D, data); |
3814 | } | 3684 | } |
3815 | 3685 | ||
3816 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 3686 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
3817 | } | 3687 | } |
3818 | 3688 | ||
3819 | static void gfx_v9_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev, | 3689 | static void gfx_v9_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev, |
@@ -3821,7 +3691,7 @@ static void gfx_v9_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev | |||
3821 | { | 3691 | { |
3822 | uint32_t def, data; | 3692 | uint32_t def, data; |
3823 | 3693 | ||
3824 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 3694 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
3825 | 3695 | ||
3826 | if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGCG)) { | 3696 | if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGCG)) { |
3827 | def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE); | 3697 | def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE); |
@@ -3861,7 +3731,7 @@ static void gfx_v9_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev | |||
3861 | WREG32_SOC15(GC, 0, mmRLC_CGCG_CGLS_CTRL, data); | 3731 | WREG32_SOC15(GC, 0, mmRLC_CGCG_CGLS_CTRL, data); |
3862 | } | 3732 | } |
3863 | 3733 | ||
3864 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 3734 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
3865 | } | 3735 | } |
3866 | 3736 | ||
3867 | static int gfx_v9_0_update_gfx_clock_gating(struct amdgpu_device *adev, | 3737 | static int gfx_v9_0_update_gfx_clock_gating(struct amdgpu_device *adev, |
@@ -3890,8 +3760,17 @@ static int gfx_v9_0_update_gfx_clock_gating(struct amdgpu_device *adev, | |||
3890 | } | 3760 | } |
3891 | 3761 | ||
3892 | static const struct amdgpu_rlc_funcs gfx_v9_0_rlc_funcs = { | 3762 | static const struct amdgpu_rlc_funcs gfx_v9_0_rlc_funcs = { |
3893 | .enter_safe_mode = gfx_v9_0_enter_rlc_safe_mode, | 3763 | .is_rlc_enabled = gfx_v9_0_is_rlc_enabled, |
3894 | .exit_safe_mode = gfx_v9_0_exit_rlc_safe_mode | 3764 | .set_safe_mode = gfx_v9_0_set_safe_mode, |
3765 | .unset_safe_mode = gfx_v9_0_unset_safe_mode, | ||
3766 | .init = gfx_v9_0_rlc_init, | ||
3767 | .get_csb_size = gfx_v9_0_get_csb_size, | ||
3768 | .get_csb_buffer = gfx_v9_0_get_csb_buffer, | ||
3769 | .get_cp_table_num = gfx_v9_0_cp_jump_table_num, | ||
3770 | .resume = gfx_v9_0_rlc_resume, | ||
3771 | .stop = gfx_v9_0_rlc_stop, | ||
3772 | .reset = gfx_v9_0_rlc_reset, | ||
3773 | .start = gfx_v9_0_rlc_start | ||
3895 | }; | 3774 | }; |
3896 | 3775 | ||
3897 | static int gfx_v9_0_set_powergating_state(void *handle, | 3776 | static int gfx_v9_0_set_powergating_state(void *handle, |
@@ -4072,9 +3951,11 @@ static void gfx_v9_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) | |||
4072 | } | 3951 | } |
4073 | 3952 | ||
4074 | static void gfx_v9_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, | 3953 | static void gfx_v9_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, |
4075 | struct amdgpu_ib *ib, | 3954 | struct amdgpu_job *job, |
4076 | unsigned vmid, bool ctx_switch) | 3955 | struct amdgpu_ib *ib, |
3956 | bool ctx_switch) | ||
4077 | { | 3957 | { |
3958 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
4078 | u32 header, control = 0; | 3959 | u32 header, control = 0; |
4079 | 3960 | ||
4080 | if (ib->flags & AMDGPU_IB_FLAG_CE) | 3961 | if (ib->flags & AMDGPU_IB_FLAG_CE) |
@@ -4103,20 +3984,22 @@ static void gfx_v9_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, | |||
4103 | } | 3984 | } |
4104 | 3985 | ||
4105 | static void gfx_v9_0_ring_emit_ib_compute(struct amdgpu_ring *ring, | 3986 | static void gfx_v9_0_ring_emit_ib_compute(struct amdgpu_ring *ring, |
4106 | struct amdgpu_ib *ib, | 3987 | struct amdgpu_job *job, |
4107 | unsigned vmid, bool ctx_switch) | 3988 | struct amdgpu_ib *ib, |
3989 | bool ctx_switch) | ||
4108 | { | 3990 | { |
4109 | u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vmid << 24); | 3991 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); |
3992 | u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vmid << 24); | ||
4110 | 3993 | ||
4111 | amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); | 3994 | amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); |
4112 | BUG_ON(ib->gpu_addr & 0x3); /* Dword align */ | 3995 | BUG_ON(ib->gpu_addr & 0x3); /* Dword align */ |
4113 | amdgpu_ring_write(ring, | 3996 | amdgpu_ring_write(ring, |
4114 | #ifdef __BIG_ENDIAN | 3997 | #ifdef __BIG_ENDIAN |
4115 | (2 << 0) | | 3998 | (2 << 0) | |
4116 | #endif | 3999 | #endif |
4117 | lower_32_bits(ib->gpu_addr)); | 4000 | lower_32_bits(ib->gpu_addr)); |
4118 | amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); | 4001 | amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); |
4119 | amdgpu_ring_write(ring, control); | 4002 | amdgpu_ring_write(ring, control); |
4120 | } | 4003 | } |
4121 | 4004 | ||
4122 | static void gfx_v9_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, | 4005 | static void gfx_v9_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, |
@@ -4695,12 +4578,39 @@ static int gfx_v9_0_eop_irq(struct amdgpu_device *adev, | |||
4695 | return 0; | 4578 | return 0; |
4696 | } | 4579 | } |
4697 | 4580 | ||
4581 | static void gfx_v9_0_fault(struct amdgpu_device *adev, | ||
4582 | struct amdgpu_iv_entry *entry) | ||
4583 | { | ||
4584 | u8 me_id, pipe_id, queue_id; | ||
4585 | struct amdgpu_ring *ring; | ||
4586 | int i; | ||
4587 | |||
4588 | me_id = (entry->ring_id & 0x0c) >> 2; | ||
4589 | pipe_id = (entry->ring_id & 0x03) >> 0; | ||
4590 | queue_id = (entry->ring_id & 0x70) >> 4; | ||
4591 | |||
4592 | switch (me_id) { | ||
4593 | case 0: | ||
4594 | drm_sched_fault(&adev->gfx.gfx_ring[0].sched); | ||
4595 | break; | ||
4596 | case 1: | ||
4597 | case 2: | ||
4598 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { | ||
4599 | ring = &adev->gfx.compute_ring[i]; | ||
4600 | if (ring->me == me_id && ring->pipe == pipe_id && | ||
4601 | ring->queue == queue_id) | ||
4602 | drm_sched_fault(&ring->sched); | ||
4603 | } | ||
4604 | break; | ||
4605 | } | ||
4606 | } | ||
4607 | |||
4698 | static int gfx_v9_0_priv_reg_irq(struct amdgpu_device *adev, | 4608 | static int gfx_v9_0_priv_reg_irq(struct amdgpu_device *adev, |
4699 | struct amdgpu_irq_src *source, | 4609 | struct amdgpu_irq_src *source, |
4700 | struct amdgpu_iv_entry *entry) | 4610 | struct amdgpu_iv_entry *entry) |
4701 | { | 4611 | { |
4702 | DRM_ERROR("Illegal register access in command stream\n"); | 4612 | DRM_ERROR("Illegal register access in command stream\n"); |
4703 | schedule_work(&adev->reset_work); | 4613 | gfx_v9_0_fault(adev, entry); |
4704 | return 0; | 4614 | return 0; |
4705 | } | 4615 | } |
4706 | 4616 | ||
@@ -4709,7 +4619,7 @@ static int gfx_v9_0_priv_inst_irq(struct amdgpu_device *adev, | |||
4709 | struct amdgpu_iv_entry *entry) | 4619 | struct amdgpu_iv_entry *entry) |
4710 | { | 4620 | { |
4711 | DRM_ERROR("Illegal instruction in command stream\n"); | 4621 | DRM_ERROR("Illegal instruction in command stream\n"); |
4712 | schedule_work(&adev->reset_work); | 4622 | gfx_v9_0_fault(adev, entry); |
4713 | return 0; | 4623 | return 0; |
4714 | } | 4624 | } |
4715 | 4625 | ||
@@ -4836,10 +4746,8 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_kiq = { | |||
4836 | 2 + /* gfx_v9_0_ring_emit_vm_flush */ | 4746 | 2 + /* gfx_v9_0_ring_emit_vm_flush */ |
4837 | 8 + 8 + 8, /* gfx_v9_0_ring_emit_fence_kiq x3 for user fence, vm fence */ | 4747 | 8 + 8 + 8, /* gfx_v9_0_ring_emit_fence_kiq x3 for user fence, vm fence */ |
4838 | .emit_ib_size = 4, /* gfx_v9_0_ring_emit_ib_compute */ | 4748 | .emit_ib_size = 4, /* gfx_v9_0_ring_emit_ib_compute */ |
4839 | .emit_ib = gfx_v9_0_ring_emit_ib_compute, | ||
4840 | .emit_fence = gfx_v9_0_ring_emit_fence_kiq, | 4749 | .emit_fence = gfx_v9_0_ring_emit_fence_kiq, |
4841 | .test_ring = gfx_v9_0_ring_test_ring, | 4750 | .test_ring = gfx_v9_0_ring_test_ring, |
4842 | .test_ib = gfx_v9_0_ring_test_ib, | ||
4843 | .insert_nop = amdgpu_ring_insert_nop, | 4751 | .insert_nop = amdgpu_ring_insert_nop, |
4844 | .pad_ib = amdgpu_ring_generic_pad_ib, | 4752 | .pad_ib = amdgpu_ring_generic_pad_ib, |
4845 | .emit_rreg = gfx_v9_0_ring_emit_rreg, | 4753 | .emit_rreg = gfx_v9_0_ring_emit_rreg, |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c index ceb7847b504f..f5edddf3b29d 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c | |||
@@ -35,20 +35,25 @@ u64 gfxhub_v1_0_get_mc_fb_offset(struct amdgpu_device *adev) | |||
35 | return (u64)RREG32_SOC15(GC, 0, mmMC_VM_FB_OFFSET) << 24; | 35 | return (u64)RREG32_SOC15(GC, 0, mmMC_VM_FB_OFFSET) << 24; |
36 | } | 36 | } |
37 | 37 | ||
38 | static void gfxhub_v1_0_init_gart_pt_regs(struct amdgpu_device *adev) | 38 | void gfxhub_v1_0_setup_vm_pt_regs(struct amdgpu_device *adev, uint32_t vmid, |
39 | uint64_t page_table_base) | ||
39 | { | 40 | { |
40 | uint64_t value = amdgpu_gmc_pd_addr(adev->gart.bo); | 41 | /* two registers distance between mmVM_CONTEXT0_* to mmVM_CONTEXT1_* */ |
42 | int offset = mmVM_CONTEXT1_PAGE_TABLE_BASE_ADDR_LO32 | ||
43 | - mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32; | ||
41 | 44 | ||
42 | WREG32_SOC15(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, | 45 | WREG32_SOC15_OFFSET(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, |
43 | lower_32_bits(value)); | 46 | offset * vmid, lower_32_bits(page_table_base)); |
44 | 47 | ||
45 | WREG32_SOC15(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, | 48 | WREG32_SOC15_OFFSET(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, |
46 | upper_32_bits(value)); | 49 | offset * vmid, upper_32_bits(page_table_base)); |
47 | } | 50 | } |
48 | 51 | ||
49 | static void gfxhub_v1_0_init_gart_aperture_regs(struct amdgpu_device *adev) | 52 | static void gfxhub_v1_0_init_gart_aperture_regs(struct amdgpu_device *adev) |
50 | { | 53 | { |
51 | gfxhub_v1_0_init_gart_pt_regs(adev); | 54 | uint64_t pt_base = amdgpu_gmc_pd_addr(adev->gart.bo); |
55 | |||
56 | gfxhub_v1_0_setup_vm_pt_regs(adev, 0, pt_base); | ||
52 | 57 | ||
53 | WREG32_SOC15(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, | 58 | WREG32_SOC15(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, |
54 | (u32)(adev->gmc.gart_start >> 12)); | 59 | (u32)(adev->gmc.gart_start >> 12)); |
@@ -72,7 +77,7 @@ static void gfxhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev) | |||
72 | 77 | ||
73 | /* Program the system aperture low logical page number. */ | 78 | /* Program the system aperture low logical page number. */ |
74 | WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR, | 79 | WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR, |
75 | min(adev->gmc.vram_start, adev->gmc.agp_start) >> 18); | 80 | min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18); |
76 | 81 | ||
77 | if (adev->asic_type == CHIP_RAVEN && adev->rev_id >= 0x8) | 82 | if (adev->asic_type == CHIP_RAVEN && adev->rev_id >= 0x8) |
78 | /* | 83 | /* |
@@ -82,11 +87,11 @@ static void gfxhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev) | |||
82 | * to get rid of the VM fault and hardware hang. | 87 | * to get rid of the VM fault and hardware hang. |
83 | */ | 88 | */ |
84 | WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR, | 89 | WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR, |
85 | max((adev->gmc.vram_end >> 18) + 0x1, | 90 | max((adev->gmc.fb_end >> 18) + 0x1, |
86 | adev->gmc.agp_end >> 18)); | 91 | adev->gmc.agp_end >> 18)); |
87 | else | 92 | else |
88 | WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR, | 93 | WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR, |
89 | max(adev->gmc.vram_end, adev->gmc.agp_end) >> 18); | 94 | max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18); |
90 | 95 | ||
91 | /* Set default page address. */ | 96 | /* Set default page address. */ |
92 | value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start | 97 | value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.h b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.h index 206e29cad753..92d3a70cd9b1 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.h +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.h | |||
@@ -30,5 +30,7 @@ void gfxhub_v1_0_set_fault_enable_default(struct amdgpu_device *adev, | |||
30 | bool value); | 30 | bool value); |
31 | void gfxhub_v1_0_init(struct amdgpu_device *adev); | 31 | void gfxhub_v1_0_init(struct amdgpu_device *adev); |
32 | u64 gfxhub_v1_0_get_mc_fb_offset(struct amdgpu_device *adev); | 32 | u64 gfxhub_v1_0_get_mc_fb_offset(struct amdgpu_device *adev); |
33 | void gfxhub_v1_0_setup_vm_pt_regs(struct amdgpu_device *adev, uint32_t vmid, | ||
34 | uint64_t page_table_base); | ||
33 | 35 | ||
34 | #endif | 36 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c index e1c2b4e9c7b2..2821d1d846e4 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | |||
@@ -358,7 +358,8 @@ static int gmc_v6_0_mc_init(struct amdgpu_device *adev) | |||
358 | return 0; | 358 | return 0; |
359 | } | 359 | } |
360 | 360 | ||
361 | static void gmc_v6_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid) | 361 | static void gmc_v6_0_flush_gpu_tlb(struct amdgpu_device *adev, |
362 | uint32_t vmid, uint32_t flush_type) | ||
362 | { | 363 | { |
363 | WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid); | 364 | WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid); |
364 | } | 365 | } |
@@ -580,7 +581,7 @@ static int gmc_v6_0_gart_enable(struct amdgpu_device *adev) | |||
580 | else | 581 | else |
581 | gmc_v6_0_set_fault_enable_default(adev, true); | 582 | gmc_v6_0_set_fault_enable_default(adev, true); |
582 | 583 | ||
583 | gmc_v6_0_flush_gpu_tlb(adev, 0); | 584 | gmc_v6_0_flush_gpu_tlb(adev, 0, 0); |
584 | dev_info(adev->dev, "PCIE GART of %uM enabled (table at 0x%016llX).\n", | 585 | dev_info(adev->dev, "PCIE GART of %uM enabled (table at 0x%016llX).\n", |
585 | (unsigned)(adev->gmc.gart_size >> 20), | 586 | (unsigned)(adev->gmc.gart_size >> 20), |
586 | (unsigned long long)table_addr); | 587 | (unsigned long long)table_addr); |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 910c4ce19cb3..761dcfb2fec0 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | |||
@@ -430,7 +430,8 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev) | |||
430 | * | 430 | * |
431 | * Flush the TLB for the requested page table (CIK). | 431 | * Flush the TLB for the requested page table (CIK). |
432 | */ | 432 | */ |
433 | static void gmc_v7_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid) | 433 | static void gmc_v7_0_flush_gpu_tlb(struct amdgpu_device *adev, |
434 | uint32_t vmid, uint32_t flush_type) | ||
434 | { | 435 | { |
435 | /* bits 0-15 are the VM contexts0-15 */ | 436 | /* bits 0-15 are the VM contexts0-15 */ |
436 | WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid); | 437 | WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid); |
@@ -698,7 +699,7 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev) | |||
698 | WREG32(mmCHUB_CONTROL, tmp); | 699 | WREG32(mmCHUB_CONTROL, tmp); |
699 | } | 700 | } |
700 | 701 | ||
701 | gmc_v7_0_flush_gpu_tlb(adev, 0); | 702 | gmc_v7_0_flush_gpu_tlb(adev, 0, 0); |
702 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", | 703 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", |
703 | (unsigned)(adev->gmc.gart_size >> 20), | 704 | (unsigned)(adev->gmc.gart_size >> 20), |
704 | (unsigned long long)table_addr); | 705 | (unsigned long long)table_addr); |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 1d3265c97b70..531aaf377592 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | |||
@@ -611,7 +611,7 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev) | |||
611 | * Flush the TLB for the requested page table (CIK). | 611 | * Flush the TLB for the requested page table (CIK). |
612 | */ | 612 | */ |
613 | static void gmc_v8_0_flush_gpu_tlb(struct amdgpu_device *adev, | 613 | static void gmc_v8_0_flush_gpu_tlb(struct amdgpu_device *adev, |
614 | uint32_t vmid) | 614 | uint32_t vmid, uint32_t flush_type) |
615 | { | 615 | { |
616 | /* bits 0-15 are the VM contexts0-15 */ | 616 | /* bits 0-15 are the VM contexts0-15 */ |
617 | WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid); | 617 | WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid); |
@@ -920,7 +920,7 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev) | |||
920 | else | 920 | else |
921 | gmc_v8_0_set_fault_enable_default(adev, true); | 921 | gmc_v8_0_set_fault_enable_default(adev, true); |
922 | 922 | ||
923 | gmc_v8_0_flush_gpu_tlb(adev, 0); | 923 | gmc_v8_0_flush_gpu_tlb(adev, 0, 0); |
924 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", | 924 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", |
925 | (unsigned)(adev->gmc.gart_size >> 20), | 925 | (unsigned)(adev->gmc.gart_size >> 20), |
926 | (unsigned long long)table_addr); | 926 | (unsigned long long)table_addr); |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index f35d7a554ad5..811231e4ec53 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | |||
@@ -293,14 +293,14 @@ static void gmc_v9_0_set_irq_funcs(struct amdgpu_device *adev) | |||
293 | adev->gmc.vm_fault.funcs = &gmc_v9_0_irq_funcs; | 293 | adev->gmc.vm_fault.funcs = &gmc_v9_0_irq_funcs; |
294 | } | 294 | } |
295 | 295 | ||
296 | static uint32_t gmc_v9_0_get_invalidate_req(unsigned int vmid) | 296 | static uint32_t gmc_v9_0_get_invalidate_req(unsigned int vmid, |
297 | uint32_t flush_type) | ||
297 | { | 298 | { |
298 | u32 req = 0; | 299 | u32 req = 0; |
299 | 300 | ||
300 | /* invalidate using legacy mode on vmid*/ | ||
301 | req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, | 301 | req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, |
302 | PER_VMID_INVALIDATE_REQ, 1 << vmid); | 302 | PER_VMID_INVALIDATE_REQ, 1 << vmid); |
303 | req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, FLUSH_TYPE, 0); | 303 | req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, FLUSH_TYPE, flush_type); |
304 | req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PTES, 1); | 304 | req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PTES, 1); |
305 | req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE0, 1); | 305 | req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE0, 1); |
306 | req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE1, 1); | 306 | req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE1, 1); |
@@ -312,48 +312,6 @@ static uint32_t gmc_v9_0_get_invalidate_req(unsigned int vmid) | |||
312 | return req; | 312 | return req; |
313 | } | 313 | } |
314 | 314 | ||
315 | static signed long amdgpu_kiq_reg_write_reg_wait(struct amdgpu_device *adev, | ||
316 | uint32_t reg0, uint32_t reg1, | ||
317 | uint32_t ref, uint32_t mask) | ||
318 | { | ||
319 | signed long r, cnt = 0; | ||
320 | unsigned long flags; | ||
321 | uint32_t seq; | ||
322 | struct amdgpu_kiq *kiq = &adev->gfx.kiq; | ||
323 | struct amdgpu_ring *ring = &kiq->ring; | ||
324 | |||
325 | spin_lock_irqsave(&kiq->ring_lock, flags); | ||
326 | |||
327 | amdgpu_ring_alloc(ring, 32); | ||
328 | amdgpu_ring_emit_reg_write_reg_wait(ring, reg0, reg1, | ||
329 | ref, mask); | ||
330 | amdgpu_fence_emit_polling(ring, &seq); | ||
331 | amdgpu_ring_commit(ring); | ||
332 | spin_unlock_irqrestore(&kiq->ring_lock, flags); | ||
333 | |||
334 | r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); | ||
335 | |||
336 | /* don't wait anymore for IRQ context */ | ||
337 | if (r < 1 && in_interrupt()) | ||
338 | goto failed_kiq; | ||
339 | |||
340 | might_sleep(); | ||
341 | |||
342 | while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) { | ||
343 | msleep(MAX_KIQ_REG_BAILOUT_INTERVAL); | ||
344 | r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); | ||
345 | } | ||
346 | |||
347 | if (cnt > MAX_KIQ_REG_TRY) | ||
348 | goto failed_kiq; | ||
349 | |||
350 | return 0; | ||
351 | |||
352 | failed_kiq: | ||
353 | pr_err("failed to invalidate tlb with kiq\n"); | ||
354 | return r; | ||
355 | } | ||
356 | |||
357 | /* | 315 | /* |
358 | * GART | 316 | * GART |
359 | * VMID 0 is the physical GPU addresses as used by the kernel. | 317 | * VMID 0 is the physical GPU addresses as used by the kernel. |
@@ -362,64 +320,47 @@ failed_kiq: | |||
362 | */ | 320 | */ |
363 | 321 | ||
364 | /** | 322 | /** |
365 | * gmc_v9_0_flush_gpu_tlb - gart tlb flush callback | 323 | * gmc_v9_0_flush_gpu_tlb - tlb flush with certain type |
366 | * | 324 | * |
367 | * @adev: amdgpu_device pointer | 325 | * @adev: amdgpu_device pointer |
368 | * @vmid: vm instance to flush | 326 | * @vmid: vm instance to flush |
327 | * @flush_type: the flush type | ||
369 | * | 328 | * |
370 | * Flush the TLB for the requested page table. | 329 | * Flush the TLB for the requested page table using certain type. |
371 | */ | 330 | */ |
372 | static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, | 331 | static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, |
373 | uint32_t vmid) | 332 | uint32_t vmid, uint32_t flush_type) |
374 | { | 333 | { |
375 | /* Use register 17 for GART */ | ||
376 | const unsigned eng = 17; | 334 | const unsigned eng = 17; |
377 | unsigned i, j; | 335 | unsigned i, j; |
378 | int r; | ||
379 | 336 | ||
380 | for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) { | 337 | for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) { |
381 | struct amdgpu_vmhub *hub = &adev->vmhub[i]; | 338 | struct amdgpu_vmhub *hub = &adev->vmhub[i]; |
382 | u32 tmp = gmc_v9_0_get_invalidate_req(vmid); | 339 | u32 tmp = gmc_v9_0_get_invalidate_req(vmid, flush_type); |
383 | |||
384 | if (adev->gfx.kiq.ring.ready && | ||
385 | (amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev)) && | ||
386 | !adev->in_gpu_reset) { | ||
387 | r = amdgpu_kiq_reg_write_reg_wait(adev, hub->vm_inv_eng0_req + eng, | ||
388 | hub->vm_inv_eng0_ack + eng, tmp, 1 << vmid); | ||
389 | if (!r) | ||
390 | continue; | ||
391 | } | ||
392 | 340 | ||
393 | spin_lock(&adev->gmc.invalidate_lock); | 341 | if (i == AMDGPU_GFXHUB && !adev->in_gpu_reset && |
342 | adev->gfx.kiq.ring.sched.ready && | ||
343 | (amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) { | ||
344 | uint32_t req = hub->vm_inv_eng0_req + eng; | ||
345 | uint32_t ack = hub->vm_inv_eng0_ack + eng; | ||
394 | 346 | ||
395 | WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp); | 347 | amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, tmp, |
396 | 348 | 1 << vmid); | |
397 | /* Busy wait for ACK.*/ | ||
398 | for (j = 0; j < 100; j++) { | ||
399 | tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_ack + eng); | ||
400 | tmp &= 1 << vmid; | ||
401 | if (tmp) | ||
402 | break; | ||
403 | cpu_relax(); | ||
404 | } | ||
405 | if (j < 100) { | ||
406 | spin_unlock(&adev->gmc.invalidate_lock); | ||
407 | continue; | 349 | continue; |
408 | } | 350 | } |
409 | 351 | ||
410 | /* Wait for ACK with a delay.*/ | 352 | spin_lock(&adev->gmc.invalidate_lock); |
353 | WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp); | ||
411 | for (j = 0; j < adev->usec_timeout; j++) { | 354 | for (j = 0; j < adev->usec_timeout; j++) { |
412 | tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_ack + eng); | 355 | tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_ack + eng); |
413 | tmp &= 1 << vmid; | 356 | if (tmp & (1 << vmid)) |
414 | if (tmp) | ||
415 | break; | 357 | break; |
416 | udelay(1); | 358 | udelay(1); |
417 | } | 359 | } |
418 | if (j < adev->usec_timeout) { | ||
419 | spin_unlock(&adev->gmc.invalidate_lock); | ||
420 | continue; | ||
421 | } | ||
422 | spin_unlock(&adev->gmc.invalidate_lock); | 360 | spin_unlock(&adev->gmc.invalidate_lock); |
361 | if (j < adev->usec_timeout) | ||
362 | continue; | ||
363 | |||
423 | DRM_ERROR("Timeout waiting for VM flush ACK!\n"); | 364 | DRM_ERROR("Timeout waiting for VM flush ACK!\n"); |
424 | } | 365 | } |
425 | } | 366 | } |
@@ -429,7 +370,7 @@ static uint64_t gmc_v9_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring, | |||
429 | { | 370 | { |
430 | struct amdgpu_device *adev = ring->adev; | 371 | struct amdgpu_device *adev = ring->adev; |
431 | struct amdgpu_vmhub *hub = &adev->vmhub[ring->funcs->vmhub]; | 372 | struct amdgpu_vmhub *hub = &adev->vmhub[ring->funcs->vmhub]; |
432 | uint32_t req = gmc_v9_0_get_invalidate_req(vmid); | 373 | uint32_t req = gmc_v9_0_get_invalidate_req(vmid, 0); |
433 | unsigned eng = ring->vm_inv_eng; | 374 | unsigned eng = ring->vm_inv_eng; |
434 | 375 | ||
435 | amdgpu_ring_emit_wreg(ring, hub->ctx0_ptb_addr_lo32 + (2 * vmid), | 376 | amdgpu_ring_emit_wreg(ring, hub->ctx0_ptb_addr_lo32 + (2 * vmid), |
@@ -739,9 +680,8 @@ static int gmc_v9_0_late_init(void *handle) | |||
739 | unsigned vmhub = ring->funcs->vmhub; | 680 | unsigned vmhub = ring->funcs->vmhub; |
740 | 681 | ||
741 | ring->vm_inv_eng = vm_inv_eng[vmhub]++; | 682 | ring->vm_inv_eng = vm_inv_eng[vmhub]++; |
742 | dev_info(adev->dev, "ring %u(%s) uses VM inv eng %u on hub %u\n", | 683 | dev_info(adev->dev, "ring %s uses VM inv eng %u on hub %u\n", |
743 | ring->idx, ring->name, ring->vm_inv_eng, | 684 | ring->name, ring->vm_inv_eng, ring->funcs->vmhub); |
744 | ring->funcs->vmhub); | ||
745 | } | 685 | } |
746 | 686 | ||
747 | /* Engine 16 is used for KFD and 17 for GART flushes */ | 687 | /* Engine 16 is used for KFD and 17 for GART flushes */ |
@@ -1122,7 +1062,7 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) | |||
1122 | 1062 | ||
1123 | gfxhub_v1_0_set_fault_enable_default(adev, value); | 1063 | gfxhub_v1_0_set_fault_enable_default(adev, value); |
1124 | mmhub_v1_0_set_fault_enable_default(adev, value); | 1064 | mmhub_v1_0_set_fault_enable_default(adev, value); |
1125 | gmc_v9_0_flush_gpu_tlb(adev, 0); | 1065 | gmc_v9_0_flush_gpu_tlb(adev, 0, 0); |
1126 | 1066 | ||
1127 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", | 1067 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", |
1128 | (unsigned)(adev->gmc.gart_size >> 20), | 1068 | (unsigned)(adev->gmc.gart_size >> 20), |
diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c index d0e478f43443..0c9a2c03504e 100644 --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c | |||
@@ -508,19 +508,19 @@ static int kv_enable_didt(struct amdgpu_device *adev, bool enable) | |||
508 | pi->caps_db_ramping || | 508 | pi->caps_db_ramping || |
509 | pi->caps_td_ramping || | 509 | pi->caps_td_ramping || |
510 | pi->caps_tcp_ramping) { | 510 | pi->caps_tcp_ramping) { |
511 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 511 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
512 | 512 | ||
513 | if (enable) { | 513 | if (enable) { |
514 | ret = kv_program_pt_config_registers(adev, didt_config_kv); | 514 | ret = kv_program_pt_config_registers(adev, didt_config_kv); |
515 | if (ret) { | 515 | if (ret) { |
516 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 516 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
517 | return ret; | 517 | return ret; |
518 | } | 518 | } |
519 | } | 519 | } |
520 | 520 | ||
521 | kv_do_enable_didt(adev, enable); | 521 | kv_do_enable_didt(adev, enable); |
522 | 522 | ||
523 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 523 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
524 | } | 524 | } |
525 | 525 | ||
526 | return 0; | 526 | return 0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c index fd23ba1226a5..d0d966d6080a 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c | |||
@@ -52,20 +52,25 @@ u64 mmhub_v1_0_get_fb_location(struct amdgpu_device *adev) | |||
52 | return base; | 52 | return base; |
53 | } | 53 | } |
54 | 54 | ||
55 | static void mmhub_v1_0_init_gart_pt_regs(struct amdgpu_device *adev) | 55 | void mmhub_v1_0_setup_vm_pt_regs(struct amdgpu_device *adev, uint32_t vmid, |
56 | uint64_t page_table_base) | ||
56 | { | 57 | { |
57 | uint64_t value = amdgpu_gmc_pd_addr(adev->gart.bo); | 58 | /* two registers distance between mmVM_CONTEXT0_* to mmVM_CONTEXT1_* */ |
59 | int offset = mmVM_CONTEXT1_PAGE_TABLE_BASE_ADDR_LO32 | ||
60 | - mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32; | ||
58 | 61 | ||
59 | WREG32_SOC15(MMHUB, 0, mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, | 62 | WREG32_SOC15_OFFSET(MMHUB, 0, mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, |
60 | lower_32_bits(value)); | 63 | offset * vmid, lower_32_bits(page_table_base)); |
61 | 64 | ||
62 | WREG32_SOC15(MMHUB, 0, mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, | 65 | WREG32_SOC15_OFFSET(MMHUB, 0, mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, |
63 | upper_32_bits(value)); | 66 | offset * vmid, upper_32_bits(page_table_base)); |
64 | } | 67 | } |
65 | 68 | ||
66 | static void mmhub_v1_0_init_gart_aperture_regs(struct amdgpu_device *adev) | 69 | static void mmhub_v1_0_init_gart_aperture_regs(struct amdgpu_device *adev) |
67 | { | 70 | { |
68 | mmhub_v1_0_init_gart_pt_regs(adev); | 71 | uint64_t pt_base = amdgpu_gmc_pd_addr(adev->gart.bo); |
72 | |||
73 | mmhub_v1_0_setup_vm_pt_regs(adev, 0, pt_base); | ||
69 | 74 | ||
70 | WREG32_SOC15(MMHUB, 0, mmVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, | 75 | WREG32_SOC15(MMHUB, 0, mmVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, |
71 | (u32)(adev->gmc.gart_start >> 12)); | 76 | (u32)(adev->gmc.gart_start >> 12)); |
@@ -90,7 +95,7 @@ static void mmhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev) | |||
90 | 95 | ||
91 | /* Program the system aperture low logical page number. */ | 96 | /* Program the system aperture low logical page number. */ |
92 | WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR, | 97 | WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR, |
93 | min(adev->gmc.vram_start, adev->gmc.agp_start) >> 18); | 98 | min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18); |
94 | 99 | ||
95 | if (adev->asic_type == CHIP_RAVEN && adev->rev_id >= 0x8) | 100 | if (adev->asic_type == CHIP_RAVEN && adev->rev_id >= 0x8) |
96 | /* | 101 | /* |
@@ -100,11 +105,11 @@ static void mmhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev) | |||
100 | * to get rid of the VM fault and hardware hang. | 105 | * to get rid of the VM fault and hardware hang. |
101 | */ | 106 | */ |
102 | WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR, | 107 | WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR, |
103 | max((adev->gmc.vram_end >> 18) + 0x1, | 108 | max((adev->gmc.fb_end >> 18) + 0x1, |
104 | adev->gmc.agp_end >> 18)); | 109 | adev->gmc.agp_end >> 18)); |
105 | else | 110 | else |
106 | WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR, | 111 | WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR, |
107 | max(adev->gmc.vram_end, adev->gmc.agp_end) >> 18); | 112 | max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18); |
108 | 113 | ||
109 | /* Set default page address. */ | 114 | /* Set default page address. */ |
110 | value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start + | 115 | value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start + |
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h index bef3d0c0c117..0de0fdf98c00 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h | |||
@@ -34,5 +34,7 @@ int mmhub_v1_0_set_clockgating(struct amdgpu_device *adev, | |||
34 | void mmhub_v1_0_get_clockgating(struct amdgpu_device *adev, u32 *flags); | 34 | void mmhub_v1_0_get_clockgating(struct amdgpu_device *adev, u32 *flags); |
35 | void mmhub_v1_0_update_power_gating(struct amdgpu_device *adev, | 35 | void mmhub_v1_0_update_power_gating(struct amdgpu_device *adev, |
36 | bool enable); | 36 | bool enable); |
37 | void mmhub_v1_0_setup_vm_pt_regs(struct amdgpu_device *adev, uint32_t vmid, | ||
38 | uint64_t page_table_base); | ||
37 | 39 | ||
38 | #endif | 40 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c index 3f3fac2d50cd..e5dd052d9e06 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "nbio/nbio_7_4_offset.h" | 34 | #include "nbio/nbio_7_4_offset.h" |
35 | 35 | ||
36 | MODULE_FIRMWARE("amdgpu/vega20_sos.bin"); | 36 | MODULE_FIRMWARE("amdgpu/vega20_sos.bin"); |
37 | MODULE_FIRMWARE("amdgpu/vega20_ta.bin"); | ||
37 | 38 | ||
38 | /* address block */ | 39 | /* address block */ |
39 | #define smnMP1_FIRMWARE_FLAGS 0x3010024 | 40 | #define smnMP1_FIRMWARE_FLAGS 0x3010024 |
@@ -98,7 +99,8 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) | |||
98 | const char *chip_name; | 99 | const char *chip_name; |
99 | char fw_name[30]; | 100 | char fw_name[30]; |
100 | int err = 0; | 101 | int err = 0; |
101 | const struct psp_firmware_header_v1_0 *hdr; | 102 | const struct psp_firmware_header_v1_0 *sos_hdr; |
103 | const struct ta_firmware_header_v1_0 *ta_hdr; | ||
102 | 104 | ||
103 | DRM_DEBUG("\n"); | 105 | DRM_DEBUG("\n"); |
104 | 106 | ||
@@ -119,16 +121,32 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) | |||
119 | if (err) | 121 | if (err) |
120 | goto out; | 122 | goto out; |
121 | 123 | ||
122 | hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.sos_fw->data; | 124 | sos_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.sos_fw->data; |
123 | adev->psp.sos_fw_version = le32_to_cpu(hdr->header.ucode_version); | 125 | adev->psp.sos_fw_version = le32_to_cpu(sos_hdr->header.ucode_version); |
124 | adev->psp.sos_feature_version = le32_to_cpu(hdr->ucode_feature_version); | 126 | adev->psp.sos_feature_version = le32_to_cpu(sos_hdr->ucode_feature_version); |
125 | adev->psp.sos_bin_size = le32_to_cpu(hdr->sos_size_bytes); | 127 | adev->psp.sos_bin_size = le32_to_cpu(sos_hdr->sos_size_bytes); |
126 | adev->psp.sys_bin_size = le32_to_cpu(hdr->header.ucode_size_bytes) - | 128 | adev->psp.sys_bin_size = le32_to_cpu(sos_hdr->header.ucode_size_bytes) - |
127 | le32_to_cpu(hdr->sos_size_bytes); | 129 | le32_to_cpu(sos_hdr->sos_size_bytes); |
128 | adev->psp.sys_start_addr = (uint8_t *)hdr + | 130 | adev->psp.sys_start_addr = (uint8_t *)sos_hdr + |
129 | le32_to_cpu(hdr->header.ucode_array_offset_bytes); | 131 | le32_to_cpu(sos_hdr->header.ucode_array_offset_bytes); |
130 | adev->psp.sos_start_addr = (uint8_t *)adev->psp.sys_start_addr + | 132 | adev->psp.sos_start_addr = (uint8_t *)adev->psp.sys_start_addr + |
131 | le32_to_cpu(hdr->sos_offset_bytes); | 133 | le32_to_cpu(sos_hdr->sos_offset_bytes); |
134 | |||
135 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name); | ||
136 | err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev); | ||
137 | if (err) | ||
138 | goto out; | ||
139 | |||
140 | err = amdgpu_ucode_validate(adev->psp.ta_fw); | ||
141 | if (err) | ||
142 | goto out; | ||
143 | |||
144 | ta_hdr = (const struct ta_firmware_header_v1_0 *)adev->psp.ta_fw->data; | ||
145 | adev->psp.ta_xgmi_ucode_version = le32_to_cpu(ta_hdr->ta_xgmi_ucode_version); | ||
146 | adev->psp.ta_xgmi_ucode_size = le32_to_cpu(ta_hdr->ta_xgmi_size_bytes); | ||
147 | adev->psp.ta_xgmi_start_addr = (uint8_t *)ta_hdr + | ||
148 | le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes); | ||
149 | |||
132 | return 0; | 150 | return 0; |
133 | out: | 151 | out: |
134 | if (err) { | 152 | if (err) { |
@@ -167,7 +185,7 @@ static int psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp) | |||
167 | /* Copy PSP System Driver binary to memory */ | 185 | /* Copy PSP System Driver binary to memory */ |
168 | memcpy(psp->fw_pri_buf, psp->sys_start_addr, psp->sys_bin_size); | 186 | memcpy(psp->fw_pri_buf, psp->sys_start_addr, psp->sys_bin_size); |
169 | 187 | ||
170 | /* Provide the sys driver to bootrom */ | 188 | /* Provide the sys driver to bootloader */ |
171 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, | 189 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, |
172 | (uint32_t)(psp->fw_pri_mc_addr >> 20)); | 190 | (uint32_t)(psp->fw_pri_mc_addr >> 20)); |
173 | psp_gfxdrv_command_reg = 1 << 16; | 191 | psp_gfxdrv_command_reg = 1 << 16; |
@@ -208,7 +226,7 @@ static int psp_v11_0_bootloader_load_sos(struct psp_context *psp) | |||
208 | /* Copy Secure OS binary to PSP memory */ | 226 | /* Copy Secure OS binary to PSP memory */ |
209 | memcpy(psp->fw_pri_buf, psp->sos_start_addr, psp->sos_bin_size); | 227 | memcpy(psp->fw_pri_buf, psp->sos_start_addr, psp->sos_bin_size); |
210 | 228 | ||
211 | /* Provide the PSP secure OS to bootrom */ | 229 | /* Provide the PSP secure OS to bootloader */ |
212 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, | 230 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, |
213 | (uint32_t)(psp->fw_pri_mc_addr >> 20)); | 231 | (uint32_t)(psp->fw_pri_mc_addr >> 20)); |
214 | psp_gfxdrv_command_reg = 2 << 16; | 232 | psp_gfxdrv_command_reg = 2 << 16; |
@@ -552,24 +570,110 @@ static int psp_v11_0_mode1_reset(struct psp_context *psp) | |||
552 | static int psp_v11_0_xgmi_get_topology_info(struct psp_context *psp, | 570 | static int psp_v11_0_xgmi_get_topology_info(struct psp_context *psp, |
553 | int number_devices, struct psp_xgmi_topology_info *topology) | 571 | int number_devices, struct psp_xgmi_topology_info *topology) |
554 | { | 572 | { |
573 | struct ta_xgmi_shared_memory *xgmi_cmd; | ||
574 | struct ta_xgmi_cmd_get_topology_info_input *topology_info_input; | ||
575 | struct ta_xgmi_cmd_get_topology_info_output *topology_info_output; | ||
576 | int i; | ||
577 | int ret; | ||
578 | |||
579 | if (!topology || topology->num_nodes > TA_XGMI__MAX_CONNECTED_NODES) | ||
580 | return -EINVAL; | ||
581 | |||
582 | xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf; | ||
583 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); | ||
584 | |||
585 | /* Fill in the shared memory with topology information as input */ | ||
586 | topology_info_input = &xgmi_cmd->xgmi_in_message.get_topology_info; | ||
587 | xgmi_cmd->cmd_id = TA_COMMAND_XGMI__GET_GET_TOPOLOGY_INFO; | ||
588 | topology_info_input->num_nodes = number_devices; | ||
589 | |||
590 | for (i = 0; i < topology_info_input->num_nodes; i++) { | ||
591 | topology_info_input->nodes[i].node_id = topology->nodes[i].node_id; | ||
592 | topology_info_input->nodes[i].num_hops = topology->nodes[i].num_hops; | ||
593 | topology_info_input->nodes[i].is_sharing_enabled = topology->nodes[i].is_sharing_enabled; | ||
594 | topology_info_input->nodes[i].sdma_engine = topology->nodes[i].sdma_engine; | ||
595 | } | ||
596 | |||
597 | /* Invoke xgmi ta to get the topology information */ | ||
598 | ret = psp_xgmi_invoke(psp, TA_COMMAND_XGMI__GET_GET_TOPOLOGY_INFO); | ||
599 | if (ret) | ||
600 | return ret; | ||
601 | |||
602 | /* Read the output topology information from the shared memory */ | ||
603 | topology_info_output = &xgmi_cmd->xgmi_out_message.get_topology_info; | ||
604 | topology->num_nodes = xgmi_cmd->xgmi_out_message.get_topology_info.num_nodes; | ||
605 | for (i = 0; i < topology->num_nodes; i++) { | ||
606 | topology->nodes[i].node_id = topology_info_output->nodes[i].node_id; | ||
607 | topology->nodes[i].num_hops = topology_info_output->nodes[i].num_hops; | ||
608 | topology->nodes[i].is_sharing_enabled = topology_info_output->nodes[i].is_sharing_enabled; | ||
609 | topology->nodes[i].sdma_engine = topology_info_output->nodes[i].sdma_engine; | ||
610 | } | ||
611 | |||
555 | return 0; | 612 | return 0; |
556 | } | 613 | } |
557 | 614 | ||
558 | static int psp_v11_0_xgmi_set_topology_info(struct psp_context *psp, | 615 | static int psp_v11_0_xgmi_set_topology_info(struct psp_context *psp, |
559 | int number_devices, struct psp_xgmi_topology_info *topology) | 616 | int number_devices, struct psp_xgmi_topology_info *topology) |
560 | { | 617 | { |
561 | return 0; | 618 | struct ta_xgmi_shared_memory *xgmi_cmd; |
619 | struct ta_xgmi_cmd_get_topology_info_input *topology_info_input; | ||
620 | int i; | ||
621 | |||
622 | if (!topology || topology->num_nodes > TA_XGMI__MAX_CONNECTED_NODES) | ||
623 | return -EINVAL; | ||
624 | |||
625 | xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf; | ||
626 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); | ||
627 | |||
628 | topology_info_input = &xgmi_cmd->xgmi_in_message.get_topology_info; | ||
629 | xgmi_cmd->cmd_id = TA_COMMAND_XGMI__SET_TOPOLOGY_INFO; | ||
630 | topology_info_input->num_nodes = number_devices; | ||
631 | |||
632 | for (i = 0; i < topology_info_input->num_nodes; i++) { | ||
633 | topology_info_input->nodes[i].node_id = topology->nodes[i].node_id; | ||
634 | topology_info_input->nodes[i].num_hops = topology->nodes[i].num_hops; | ||
635 | topology_info_input->nodes[i].is_sharing_enabled = topology->nodes[i].is_sharing_enabled; | ||
636 | topology_info_input->nodes[i].sdma_engine = topology->nodes[i].sdma_engine; | ||
637 | } | ||
638 | |||
639 | /* Invoke xgmi ta to set topology information */ | ||
640 | return psp_xgmi_invoke(psp, TA_COMMAND_XGMI__SET_TOPOLOGY_INFO); | ||
562 | } | 641 | } |
563 | 642 | ||
564 | static u64 psp_v11_0_xgmi_get_hive_id(struct psp_context *psp) | 643 | static u64 psp_v11_0_xgmi_get_hive_id(struct psp_context *psp) |
565 | { | 644 | { |
566 | u64 hive_id = 0; | 645 | struct ta_xgmi_shared_memory *xgmi_cmd; |
646 | int ret; | ||
647 | |||
648 | xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf; | ||
649 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); | ||
650 | |||
651 | xgmi_cmd->cmd_id = TA_COMMAND_XGMI__GET_HIVE_ID; | ||
652 | |||
653 | /* Invoke xgmi ta to get hive id */ | ||
654 | ret = psp_xgmi_invoke(psp, xgmi_cmd->cmd_id); | ||
655 | if (ret) | ||
656 | return 0; | ||
657 | else | ||
658 | return xgmi_cmd->xgmi_out_message.get_hive_id.hive_id; | ||
659 | } | ||
660 | |||
661 | static u64 psp_v11_0_xgmi_get_node_id(struct psp_context *psp) | ||
662 | { | ||
663 | struct ta_xgmi_shared_memory *xgmi_cmd; | ||
664 | int ret; | ||
665 | |||
666 | xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf; | ||
667 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); | ||
567 | 668 | ||
568 | /* Remove me when we can get correct hive_id through PSP */ | 669 | xgmi_cmd->cmd_id = TA_COMMAND_XGMI__GET_NODE_ID; |
569 | if (psp->adev->gmc.xgmi.num_physical_nodes) | ||
570 | hive_id = 0x123456789abcdef; | ||
571 | 670 | ||
572 | return hive_id; | 671 | /* Invoke xgmi ta to get the node id */ |
672 | ret = psp_xgmi_invoke(psp, xgmi_cmd->cmd_id); | ||
673 | if (ret) | ||
674 | return 0; | ||
675 | else | ||
676 | return xgmi_cmd->xgmi_out_message.get_node_id.node_id; | ||
573 | } | 677 | } |
574 | 678 | ||
575 | static const struct psp_funcs psp_v11_0_funcs = { | 679 | static const struct psp_funcs psp_v11_0_funcs = { |
@@ -587,6 +691,7 @@ static const struct psp_funcs psp_v11_0_funcs = { | |||
587 | .xgmi_get_topology_info = psp_v11_0_xgmi_get_topology_info, | 691 | .xgmi_get_topology_info = psp_v11_0_xgmi_get_topology_info, |
588 | .xgmi_set_topology_info = psp_v11_0_xgmi_set_topology_info, | 692 | .xgmi_set_topology_info = psp_v11_0_xgmi_set_topology_info, |
589 | .xgmi_get_hive_id = psp_v11_0_xgmi_get_hive_id, | 693 | .xgmi_get_hive_id = psp_v11_0_xgmi_get_hive_id, |
694 | .xgmi_get_node_id = psp_v11_0_xgmi_get_node_id, | ||
590 | }; | 695 | }; |
591 | 696 | ||
592 | void psp_v11_0_set_psp_funcs(struct psp_context *psp) | 697 | void psp_v11_0_set_psp_funcs(struct psp_context *psp) |
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c index e1ebf770c303..9cea0bbe4525 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c | |||
@@ -194,7 +194,7 @@ static int psp_v3_1_bootloader_load_sysdrv(struct psp_context *psp) | |||
194 | /* Copy PSP System Driver binary to memory */ | 194 | /* Copy PSP System Driver binary to memory */ |
195 | memcpy(psp->fw_pri_buf, psp->sys_start_addr, psp->sys_bin_size); | 195 | memcpy(psp->fw_pri_buf, psp->sys_start_addr, psp->sys_bin_size); |
196 | 196 | ||
197 | /* Provide the sys driver to bootrom */ | 197 | /* Provide the sys driver to bootloader */ |
198 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, | 198 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, |
199 | (uint32_t)(psp->fw_pri_mc_addr >> 20)); | 199 | (uint32_t)(psp->fw_pri_mc_addr >> 20)); |
200 | psp_gfxdrv_command_reg = 1 << 16; | 200 | psp_gfxdrv_command_reg = 1 << 16; |
@@ -254,7 +254,7 @@ static int psp_v3_1_bootloader_load_sos(struct psp_context *psp) | |||
254 | /* Copy Secure OS binary to PSP memory */ | 254 | /* Copy Secure OS binary to PSP memory */ |
255 | memcpy(psp->fw_pri_buf, psp->sos_start_addr, psp->sos_bin_size); | 255 | memcpy(psp->fw_pri_buf, psp->sos_start_addr, psp->sos_bin_size); |
256 | 256 | ||
257 | /* Provide the PSP secure OS to bootrom */ | 257 | /* Provide the PSP secure OS to bootloader */ |
258 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, | 258 | WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, |
259 | (uint32_t)(psp->fw_pri_mc_addr >> 20)); | 259 | (uint32_t)(psp->fw_pri_mc_addr >> 20)); |
260 | psp_gfxdrv_command_reg = 2 << 16; | 260 | psp_gfxdrv_command_reg = 2 << 16; |
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index 2d4770e173dd..9f3cb2aec7c2 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | |||
@@ -225,7 +225,7 @@ static void sdma_v2_4_ring_set_wptr(struct amdgpu_ring *ring) | |||
225 | 225 | ||
226 | static void sdma_v2_4_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) | 226 | static void sdma_v2_4_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) |
227 | { | 227 | { |
228 | struct amdgpu_sdma_instance *sdma = amdgpu_get_sdma_instance(ring); | 228 | struct amdgpu_sdma_instance *sdma = amdgpu_sdma_get_instance_from_ring(ring); |
229 | int i; | 229 | int i; |
230 | 230 | ||
231 | for (i = 0; i < count; i++) | 231 | for (i = 0; i < count; i++) |
@@ -245,9 +245,12 @@ static void sdma_v2_4_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) | |||
245 | * Schedule an IB in the DMA ring (VI). | 245 | * Schedule an IB in the DMA ring (VI). |
246 | */ | 246 | */ |
247 | static void sdma_v2_4_ring_emit_ib(struct amdgpu_ring *ring, | 247 | static void sdma_v2_4_ring_emit_ib(struct amdgpu_ring *ring, |
248 | struct amdgpu_job *job, | ||
248 | struct amdgpu_ib *ib, | 249 | struct amdgpu_ib *ib, |
249 | unsigned vmid, bool ctx_switch) | 250 | bool ctx_switch) |
250 | { | 251 | { |
252 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
253 | |||
251 | /* IB packet must end on a 8 DW boundary */ | 254 | /* IB packet must end on a 8 DW boundary */ |
252 | sdma_v2_4_ring_insert_nop(ring, (10 - (lower_32_bits(ring->wptr) & 7)) % 8); | 255 | sdma_v2_4_ring_insert_nop(ring, (10 - (lower_32_bits(ring->wptr) & 7)) % 8); |
253 | 256 | ||
@@ -349,8 +352,8 @@ static void sdma_v2_4_gfx_stop(struct amdgpu_device *adev) | |||
349 | ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0); | 352 | ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0); |
350 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); | 353 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
351 | } | 354 | } |
352 | sdma0->ready = false; | 355 | sdma0->sched.ready = false; |
353 | sdma1->ready = false; | 356 | sdma1->sched.ready = false; |
354 | } | 357 | } |
355 | 358 | ||
356 | /** | 359 | /** |
@@ -471,17 +474,15 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev) | |||
471 | /* enable DMA IBs */ | 474 | /* enable DMA IBs */ |
472 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); | 475 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
473 | 476 | ||
474 | ring->ready = true; | 477 | ring->sched.ready = true; |
475 | } | 478 | } |
476 | 479 | ||
477 | sdma_v2_4_enable(adev, true); | 480 | sdma_v2_4_enable(adev, true); |
478 | for (i = 0; i < adev->sdma.num_instances; i++) { | 481 | for (i = 0; i < adev->sdma.num_instances; i++) { |
479 | ring = &adev->sdma.instance[i].ring; | 482 | ring = &adev->sdma.instance[i].ring; |
480 | r = amdgpu_ring_test_ring(ring); | 483 | r = amdgpu_ring_test_helper(ring); |
481 | if (r) { | 484 | if (r) |
482 | ring->ready = false; | ||
483 | return r; | 485 | return r; |
484 | } | ||
485 | 486 | ||
486 | if (adev->mman.buffer_funcs_ring == ring) | 487 | if (adev->mman.buffer_funcs_ring == ring) |
487 | amdgpu_ttm_set_buffer_funcs_status(adev, true); | 488 | amdgpu_ttm_set_buffer_funcs_status(adev, true); |
@@ -550,21 +551,16 @@ static int sdma_v2_4_ring_test_ring(struct amdgpu_ring *ring) | |||
550 | u64 gpu_addr; | 551 | u64 gpu_addr; |
551 | 552 | ||
552 | r = amdgpu_device_wb_get(adev, &index); | 553 | r = amdgpu_device_wb_get(adev, &index); |
553 | if (r) { | 554 | if (r) |
554 | dev_err(adev->dev, "(%d) failed to allocate wb slot\n", r); | ||
555 | return r; | 555 | return r; |
556 | } | ||
557 | 556 | ||
558 | gpu_addr = adev->wb.gpu_addr + (index * 4); | 557 | gpu_addr = adev->wb.gpu_addr + (index * 4); |
559 | tmp = 0xCAFEDEAD; | 558 | tmp = 0xCAFEDEAD; |
560 | adev->wb.wb[index] = cpu_to_le32(tmp); | 559 | adev->wb.wb[index] = cpu_to_le32(tmp); |
561 | 560 | ||
562 | r = amdgpu_ring_alloc(ring, 5); | 561 | r = amdgpu_ring_alloc(ring, 5); |
563 | if (r) { | 562 | if (r) |
564 | DRM_ERROR("amdgpu: dma failed to lock ring %d (%d).\n", ring->idx, r); | 563 | goto error_free_wb; |
565 | amdgpu_device_wb_free(adev, index); | ||
566 | return r; | ||
567 | } | ||
568 | 564 | ||
569 | amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) | | 565 | amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) | |
570 | SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_WRITE_LINEAR)); | 566 | SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_WRITE_LINEAR)); |
@@ -581,15 +577,11 @@ static int sdma_v2_4_ring_test_ring(struct amdgpu_ring *ring) | |||
581 | DRM_UDELAY(1); | 577 | DRM_UDELAY(1); |
582 | } | 578 | } |
583 | 579 | ||
584 | if (i < adev->usec_timeout) { | 580 | if (i >= adev->usec_timeout) |
585 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", ring->idx, i); | 581 | r = -ETIMEDOUT; |
586 | } else { | ||
587 | DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", | ||
588 | ring->idx, tmp); | ||
589 | r = -EINVAL; | ||
590 | } | ||
591 | amdgpu_device_wb_free(adev, index); | ||
592 | 582 | ||
583 | error_free_wb: | ||
584 | amdgpu_device_wb_free(adev, index); | ||
593 | return r; | 585 | return r; |
594 | } | 586 | } |
595 | 587 | ||
@@ -612,20 +604,16 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
612 | long r; | 604 | long r; |
613 | 605 | ||
614 | r = amdgpu_device_wb_get(adev, &index); | 606 | r = amdgpu_device_wb_get(adev, &index); |
615 | if (r) { | 607 | if (r) |
616 | dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r); | ||
617 | return r; | 608 | return r; |
618 | } | ||
619 | 609 | ||
620 | gpu_addr = adev->wb.gpu_addr + (index * 4); | 610 | gpu_addr = adev->wb.gpu_addr + (index * 4); |
621 | tmp = 0xCAFEDEAD; | 611 | tmp = 0xCAFEDEAD; |
622 | adev->wb.wb[index] = cpu_to_le32(tmp); | 612 | adev->wb.wb[index] = cpu_to_le32(tmp); |
623 | memset(&ib, 0, sizeof(ib)); | 613 | memset(&ib, 0, sizeof(ib)); |
624 | r = amdgpu_ib_get(adev, NULL, 256, &ib); | 614 | r = amdgpu_ib_get(adev, NULL, 256, &ib); |
625 | if (r) { | 615 | if (r) |
626 | DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r); | ||
627 | goto err0; | 616 | goto err0; |
628 | } | ||
629 | 617 | ||
630 | ib.ptr[0] = SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) | | 618 | ib.ptr[0] = SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) | |
631 | SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_WRITE_LINEAR); | 619 | SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_WRITE_LINEAR); |
@@ -644,21 +632,16 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
644 | 632 | ||
645 | r = dma_fence_wait_timeout(f, false, timeout); | 633 | r = dma_fence_wait_timeout(f, false, timeout); |
646 | if (r == 0) { | 634 | if (r == 0) { |
647 | DRM_ERROR("amdgpu: IB test timed out\n"); | ||
648 | r = -ETIMEDOUT; | 635 | r = -ETIMEDOUT; |
649 | goto err1; | 636 | goto err1; |
650 | } else if (r < 0) { | 637 | } else if (r < 0) { |
651 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | ||
652 | goto err1; | 638 | goto err1; |
653 | } | 639 | } |
654 | tmp = le32_to_cpu(adev->wb.wb[index]); | 640 | tmp = le32_to_cpu(adev->wb.wb[index]); |
655 | if (tmp == 0xDEADBEEF) { | 641 | if (tmp == 0xDEADBEEF) |
656 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | ||
657 | r = 0; | 642 | r = 0; |
658 | } else { | 643 | else |
659 | DRM_ERROR("amdgpu: ib test failed (0x%08X)\n", tmp); | ||
660 | r = -EINVAL; | 644 | r = -EINVAL; |
661 | } | ||
662 | 645 | ||
663 | err1: | 646 | err1: |
664 | amdgpu_ib_free(adev, &ib, NULL); | 647 | amdgpu_ib_free(adev, &ib, NULL); |
@@ -760,7 +743,7 @@ static void sdma_v2_4_vm_set_pte_pde(struct amdgpu_ib *ib, uint64_t pe, | |||
760 | */ | 743 | */ |
761 | static void sdma_v2_4_ring_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) | 744 | static void sdma_v2_4_ring_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) |
762 | { | 745 | { |
763 | struct amdgpu_sdma_instance *sdma = amdgpu_get_sdma_instance(ring); | 746 | struct amdgpu_sdma_instance *sdma = amdgpu_sdma_get_instance_from_ring(ring); |
764 | u32 pad_count; | 747 | u32 pad_count; |
765 | int i; | 748 | int i; |
766 | 749 | ||
@@ -1105,8 +1088,14 @@ static int sdma_v2_4_process_illegal_inst_irq(struct amdgpu_device *adev, | |||
1105 | struct amdgpu_irq_src *source, | 1088 | struct amdgpu_irq_src *source, |
1106 | struct amdgpu_iv_entry *entry) | 1089 | struct amdgpu_iv_entry *entry) |
1107 | { | 1090 | { |
1091 | u8 instance_id, queue_id; | ||
1092 | |||
1108 | DRM_ERROR("Illegal instruction in SDMA command stream\n"); | 1093 | DRM_ERROR("Illegal instruction in SDMA command stream\n"); |
1109 | schedule_work(&adev->reset_work); | 1094 | instance_id = (entry->ring_id & 0x3) >> 0; |
1095 | queue_id = (entry->ring_id & 0xc) >> 2; | ||
1096 | |||
1097 | if (instance_id <= 1 && queue_id == 0) | ||
1098 | drm_sched_fault(&adev->sdma.instance[instance_id].ring.sched); | ||
1110 | return 0; | 1099 | return 0; |
1111 | } | 1100 | } |
1112 | 1101 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index 6fb3edaba0ec..b6a25f92d566 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | |||
@@ -399,7 +399,7 @@ static void sdma_v3_0_ring_set_wptr(struct amdgpu_ring *ring) | |||
399 | 399 | ||
400 | static void sdma_v3_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) | 400 | static void sdma_v3_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) |
401 | { | 401 | { |
402 | struct amdgpu_sdma_instance *sdma = amdgpu_get_sdma_instance(ring); | 402 | struct amdgpu_sdma_instance *sdma = amdgpu_sdma_get_instance_from_ring(ring); |
403 | int i; | 403 | int i; |
404 | 404 | ||
405 | for (i = 0; i < count; i++) | 405 | for (i = 0; i < count; i++) |
@@ -419,9 +419,12 @@ static void sdma_v3_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) | |||
419 | * Schedule an IB in the DMA ring (VI). | 419 | * Schedule an IB in the DMA ring (VI). |
420 | */ | 420 | */ |
421 | static void sdma_v3_0_ring_emit_ib(struct amdgpu_ring *ring, | 421 | static void sdma_v3_0_ring_emit_ib(struct amdgpu_ring *ring, |
422 | struct amdgpu_job *job, | ||
422 | struct amdgpu_ib *ib, | 423 | struct amdgpu_ib *ib, |
423 | unsigned vmid, bool ctx_switch) | 424 | bool ctx_switch) |
424 | { | 425 | { |
426 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
427 | |||
425 | /* IB packet must end on a 8 DW boundary */ | 428 | /* IB packet must end on a 8 DW boundary */ |
426 | sdma_v3_0_ring_insert_nop(ring, (10 - (lower_32_bits(ring->wptr) & 7)) % 8); | 429 | sdma_v3_0_ring_insert_nop(ring, (10 - (lower_32_bits(ring->wptr) & 7)) % 8); |
427 | 430 | ||
@@ -523,8 +526,8 @@ static void sdma_v3_0_gfx_stop(struct amdgpu_device *adev) | |||
523 | ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0); | 526 | ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0); |
524 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); | 527 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
525 | } | 528 | } |
526 | sdma0->ready = false; | 529 | sdma0->sched.ready = false; |
527 | sdma1->ready = false; | 530 | sdma1->sched.ready = false; |
528 | } | 531 | } |
529 | 532 | ||
530 | /** | 533 | /** |
@@ -739,7 +742,7 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) | |||
739 | /* enable DMA IBs */ | 742 | /* enable DMA IBs */ |
740 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); | 743 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
741 | 744 | ||
742 | ring->ready = true; | 745 | ring->sched.ready = true; |
743 | } | 746 | } |
744 | 747 | ||
745 | /* unhalt the MEs */ | 748 | /* unhalt the MEs */ |
@@ -749,11 +752,9 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) | |||
749 | 752 | ||
750 | for (i = 0; i < adev->sdma.num_instances; i++) { | 753 | for (i = 0; i < adev->sdma.num_instances; i++) { |
751 | ring = &adev->sdma.instance[i].ring; | 754 | ring = &adev->sdma.instance[i].ring; |
752 | r = amdgpu_ring_test_ring(ring); | 755 | r = amdgpu_ring_test_helper(ring); |
753 | if (r) { | 756 | if (r) |
754 | ring->ready = false; | ||
755 | return r; | 757 | return r; |
756 | } | ||
757 | 758 | ||
758 | if (adev->mman.buffer_funcs_ring == ring) | 759 | if (adev->mman.buffer_funcs_ring == ring) |
759 | amdgpu_ttm_set_buffer_funcs_status(adev, true); | 760 | amdgpu_ttm_set_buffer_funcs_status(adev, true); |
@@ -822,21 +823,16 @@ static int sdma_v3_0_ring_test_ring(struct amdgpu_ring *ring) | |||
822 | u64 gpu_addr; | 823 | u64 gpu_addr; |
823 | 824 | ||
824 | r = amdgpu_device_wb_get(adev, &index); | 825 | r = amdgpu_device_wb_get(adev, &index); |
825 | if (r) { | 826 | if (r) |
826 | dev_err(adev->dev, "(%d) failed to allocate wb slot\n", r); | ||
827 | return r; | 827 | return r; |
828 | } | ||
829 | 828 | ||
830 | gpu_addr = adev->wb.gpu_addr + (index * 4); | 829 | gpu_addr = adev->wb.gpu_addr + (index * 4); |
831 | tmp = 0xCAFEDEAD; | 830 | tmp = 0xCAFEDEAD; |
832 | adev->wb.wb[index] = cpu_to_le32(tmp); | 831 | adev->wb.wb[index] = cpu_to_le32(tmp); |
833 | 832 | ||
834 | r = amdgpu_ring_alloc(ring, 5); | 833 | r = amdgpu_ring_alloc(ring, 5); |
835 | if (r) { | 834 | if (r) |
836 | DRM_ERROR("amdgpu: dma failed to lock ring %d (%d).\n", ring->idx, r); | 835 | goto error_free_wb; |
837 | amdgpu_device_wb_free(adev, index); | ||
838 | return r; | ||
839 | } | ||
840 | 836 | ||
841 | amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) | | 837 | amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) | |
842 | SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_WRITE_LINEAR)); | 838 | SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_WRITE_LINEAR)); |
@@ -853,15 +849,11 @@ static int sdma_v3_0_ring_test_ring(struct amdgpu_ring *ring) | |||
853 | DRM_UDELAY(1); | 849 | DRM_UDELAY(1); |
854 | } | 850 | } |
855 | 851 | ||
856 | if (i < adev->usec_timeout) { | 852 | if (i >= adev->usec_timeout) |
857 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", ring->idx, i); | 853 | r = -ETIMEDOUT; |
858 | } else { | ||
859 | DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", | ||
860 | ring->idx, tmp); | ||
861 | r = -EINVAL; | ||
862 | } | ||
863 | amdgpu_device_wb_free(adev, index); | ||
864 | 854 | ||
855 | error_free_wb: | ||
856 | amdgpu_device_wb_free(adev, index); | ||
865 | return r; | 857 | return r; |
866 | } | 858 | } |
867 | 859 | ||
@@ -884,20 +876,16 @@ static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
884 | long r; | 876 | long r; |
885 | 877 | ||
886 | r = amdgpu_device_wb_get(adev, &index); | 878 | r = amdgpu_device_wb_get(adev, &index); |
887 | if (r) { | 879 | if (r) |
888 | dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r); | ||
889 | return r; | 880 | return r; |
890 | } | ||
891 | 881 | ||
892 | gpu_addr = adev->wb.gpu_addr + (index * 4); | 882 | gpu_addr = adev->wb.gpu_addr + (index * 4); |
893 | tmp = 0xCAFEDEAD; | 883 | tmp = 0xCAFEDEAD; |
894 | adev->wb.wb[index] = cpu_to_le32(tmp); | 884 | adev->wb.wb[index] = cpu_to_le32(tmp); |
895 | memset(&ib, 0, sizeof(ib)); | 885 | memset(&ib, 0, sizeof(ib)); |
896 | r = amdgpu_ib_get(adev, NULL, 256, &ib); | 886 | r = amdgpu_ib_get(adev, NULL, 256, &ib); |
897 | if (r) { | 887 | if (r) |
898 | DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r); | ||
899 | goto err0; | 888 | goto err0; |
900 | } | ||
901 | 889 | ||
902 | ib.ptr[0] = SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) | | 890 | ib.ptr[0] = SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) | |
903 | SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_WRITE_LINEAR); | 891 | SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_WRITE_LINEAR); |
@@ -916,21 +904,16 @@ static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
916 | 904 | ||
917 | r = dma_fence_wait_timeout(f, false, timeout); | 905 | r = dma_fence_wait_timeout(f, false, timeout); |
918 | if (r == 0) { | 906 | if (r == 0) { |
919 | DRM_ERROR("amdgpu: IB test timed out\n"); | ||
920 | r = -ETIMEDOUT; | 907 | r = -ETIMEDOUT; |
921 | goto err1; | 908 | goto err1; |
922 | } else if (r < 0) { | 909 | } else if (r < 0) { |
923 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | ||
924 | goto err1; | 910 | goto err1; |
925 | } | 911 | } |
926 | tmp = le32_to_cpu(adev->wb.wb[index]); | 912 | tmp = le32_to_cpu(adev->wb.wb[index]); |
927 | if (tmp == 0xDEADBEEF) { | 913 | if (tmp == 0xDEADBEEF) |
928 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | ||
929 | r = 0; | 914 | r = 0; |
930 | } else { | 915 | else |
931 | DRM_ERROR("amdgpu: ib test failed (0x%08X)\n", tmp); | ||
932 | r = -EINVAL; | 916 | r = -EINVAL; |
933 | } | ||
934 | err1: | 917 | err1: |
935 | amdgpu_ib_free(adev, &ib, NULL); | 918 | amdgpu_ib_free(adev, &ib, NULL); |
936 | dma_fence_put(f); | 919 | dma_fence_put(f); |
@@ -1031,7 +1014,7 @@ static void sdma_v3_0_vm_set_pte_pde(struct amdgpu_ib *ib, uint64_t pe, | |||
1031 | */ | 1014 | */ |
1032 | static void sdma_v3_0_ring_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) | 1015 | static void sdma_v3_0_ring_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) |
1033 | { | 1016 | { |
1034 | struct amdgpu_sdma_instance *sdma = amdgpu_get_sdma_instance(ring); | 1017 | struct amdgpu_sdma_instance *sdma = amdgpu_sdma_get_instance_from_ring(ring); |
1035 | u32 pad_count; | 1018 | u32 pad_count; |
1036 | int i; | 1019 | int i; |
1037 | 1020 | ||
@@ -1440,8 +1423,14 @@ static int sdma_v3_0_process_illegal_inst_irq(struct amdgpu_device *adev, | |||
1440 | struct amdgpu_irq_src *source, | 1423 | struct amdgpu_irq_src *source, |
1441 | struct amdgpu_iv_entry *entry) | 1424 | struct amdgpu_iv_entry *entry) |
1442 | { | 1425 | { |
1426 | u8 instance_id, queue_id; | ||
1427 | |||
1443 | DRM_ERROR("Illegal instruction in SDMA command stream\n"); | 1428 | DRM_ERROR("Illegal instruction in SDMA command stream\n"); |
1444 | schedule_work(&adev->reset_work); | 1429 | instance_id = (entry->ring_id & 0x3) >> 0; |
1430 | queue_id = (entry->ring_id & 0xc) >> 2; | ||
1431 | |||
1432 | if (instance_id <= 1 && queue_id == 0) | ||
1433 | drm_sched_fault(&adev->sdma.instance[instance_id].ring.sched); | ||
1445 | return 0; | 1434 | return 0; |
1446 | } | 1435 | } |
1447 | 1436 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 7a8c9172d30a..f4490cdd9804 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | |||
@@ -54,6 +54,11 @@ MODULE_FIRMWARE("amdgpu/raven2_sdma.bin"); | |||
54 | #define SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK 0x000000F8L | 54 | #define SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK 0x000000F8L |
55 | #define SDMA0_POWER_CNTL__ON_OFF_STATUS_DURATION_TIME_MASK 0xFC000000L | 55 | #define SDMA0_POWER_CNTL__ON_OFF_STATUS_DURATION_TIME_MASK 0xFC000000L |
56 | 56 | ||
57 | #define WREG32_SDMA(instance, offset, value) \ | ||
58 | WREG32(sdma_v4_0_get_reg_offset(adev, (instance), (offset)), value) | ||
59 | #define RREG32_SDMA(instance, offset) \ | ||
60 | RREG32(sdma_v4_0_get_reg_offset(adev, (instance), (offset))) | ||
61 | |||
57 | static void sdma_v4_0_set_ring_funcs(struct amdgpu_device *adev); | 62 | static void sdma_v4_0_set_ring_funcs(struct amdgpu_device *adev); |
58 | static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev); | 63 | static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev); |
59 | static void sdma_v4_0_set_vm_pte_funcs(struct amdgpu_device *adev); | 64 | static void sdma_v4_0_set_vm_pte_funcs(struct amdgpu_device *adev); |
@@ -367,16 +372,11 @@ static uint64_t sdma_v4_0_ring_get_wptr(struct amdgpu_ring *ring) | |||
367 | wptr = READ_ONCE(*((u64 *)&adev->wb.wb[ring->wptr_offs])); | 372 | wptr = READ_ONCE(*((u64 *)&adev->wb.wb[ring->wptr_offs])); |
368 | DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", wptr); | 373 | DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", wptr); |
369 | } else { | 374 | } else { |
370 | u32 lowbit, highbit; | 375 | wptr = RREG32_SDMA(ring->me, mmSDMA0_GFX_RB_WPTR_HI); |
371 | |||
372 | lowbit = RREG32(sdma_v4_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR)) >> 2; | ||
373 | highbit = RREG32(sdma_v4_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI)) >> 2; | ||
374 | |||
375 | DRM_DEBUG("wptr [%i]high== 0x%08x low==0x%08x\n", | ||
376 | ring->me, highbit, lowbit); | ||
377 | wptr = highbit; | ||
378 | wptr = wptr << 32; | 376 | wptr = wptr << 32; |
379 | wptr |= lowbit; | 377 | wptr |= RREG32_SDMA(ring->me, mmSDMA0_GFX_RB_WPTR); |
378 | DRM_DEBUG("wptr before shift [%i] wptr == 0x%016llx\n", | ||
379 | ring->me, wptr); | ||
380 | } | 380 | } |
381 | 381 | ||
382 | return wptr >> 2; | 382 | return wptr >> 2; |
@@ -417,14 +417,67 @@ static void sdma_v4_0_ring_set_wptr(struct amdgpu_ring *ring) | |||
417 | lower_32_bits(ring->wptr << 2), | 417 | lower_32_bits(ring->wptr << 2), |
418 | ring->me, | 418 | ring->me, |
419 | upper_32_bits(ring->wptr << 2)); | 419 | upper_32_bits(ring->wptr << 2)); |
420 | WREG32(sdma_v4_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR), lower_32_bits(ring->wptr << 2)); | 420 | WREG32_SDMA(ring->me, mmSDMA0_GFX_RB_WPTR, |
421 | WREG32(sdma_v4_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI), upper_32_bits(ring->wptr << 2)); | 421 | lower_32_bits(ring->wptr << 2)); |
422 | WREG32_SDMA(ring->me, mmSDMA0_GFX_RB_WPTR_HI, | ||
423 | upper_32_bits(ring->wptr << 2)); | ||
424 | } | ||
425 | } | ||
426 | |||
427 | /** | ||
428 | * sdma_v4_0_page_ring_get_wptr - get the current write pointer | ||
429 | * | ||
430 | * @ring: amdgpu ring pointer | ||
431 | * | ||
432 | * Get the current wptr from the hardware (VEGA10+). | ||
433 | */ | ||
434 | static uint64_t sdma_v4_0_page_ring_get_wptr(struct amdgpu_ring *ring) | ||
435 | { | ||
436 | struct amdgpu_device *adev = ring->adev; | ||
437 | u64 wptr; | ||
438 | |||
439 | if (ring->use_doorbell) { | ||
440 | /* XXX check if swapping is necessary on BE */ | ||
441 | wptr = READ_ONCE(*((u64 *)&adev->wb.wb[ring->wptr_offs])); | ||
442 | } else { | ||
443 | wptr = RREG32_SDMA(ring->me, mmSDMA0_PAGE_RB_WPTR_HI); | ||
444 | wptr = wptr << 32; | ||
445 | wptr |= RREG32_SDMA(ring->me, mmSDMA0_PAGE_RB_WPTR); | ||
446 | } | ||
447 | |||
448 | return wptr >> 2; | ||
449 | } | ||
450 | |||
451 | /** | ||
452 | * sdma_v4_0_ring_set_wptr - commit the write pointer | ||
453 | * | ||
454 | * @ring: amdgpu ring pointer | ||
455 | * | ||
456 | * Write the wptr back to the hardware (VEGA10+). | ||
457 | */ | ||
458 | static void sdma_v4_0_page_ring_set_wptr(struct amdgpu_ring *ring) | ||
459 | { | ||
460 | struct amdgpu_device *adev = ring->adev; | ||
461 | |||
462 | if (ring->use_doorbell) { | ||
463 | u64 *wb = (u64 *)&adev->wb.wb[ring->wptr_offs]; | ||
464 | |||
465 | /* XXX check if swapping is necessary on BE */ | ||
466 | WRITE_ONCE(*wb, (ring->wptr << 2)); | ||
467 | WDOORBELL64(ring->doorbell_index, ring->wptr << 2); | ||
468 | } else { | ||
469 | uint64_t wptr = ring->wptr << 2; | ||
470 | |||
471 | WREG32_SDMA(ring->me, mmSDMA0_PAGE_RB_WPTR, | ||
472 | lower_32_bits(wptr)); | ||
473 | WREG32_SDMA(ring->me, mmSDMA0_PAGE_RB_WPTR_HI, | ||
474 | upper_32_bits(wptr)); | ||
422 | } | 475 | } |
423 | } | 476 | } |
424 | 477 | ||
425 | static void sdma_v4_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) | 478 | static void sdma_v4_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) |
426 | { | 479 | { |
427 | struct amdgpu_sdma_instance *sdma = amdgpu_get_sdma_instance(ring); | 480 | struct amdgpu_sdma_instance *sdma = amdgpu_sdma_get_instance_from_ring(ring); |
428 | int i; | 481 | int i; |
429 | 482 | ||
430 | for (i = 0; i < count; i++) | 483 | for (i = 0; i < count; i++) |
@@ -444,9 +497,12 @@ static void sdma_v4_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) | |||
444 | * Schedule an IB in the DMA ring (VEGA10). | 497 | * Schedule an IB in the DMA ring (VEGA10). |
445 | */ | 498 | */ |
446 | static void sdma_v4_0_ring_emit_ib(struct amdgpu_ring *ring, | 499 | static void sdma_v4_0_ring_emit_ib(struct amdgpu_ring *ring, |
447 | struct amdgpu_ib *ib, | 500 | struct amdgpu_job *job, |
448 | unsigned vmid, bool ctx_switch) | 501 | struct amdgpu_ib *ib, |
502 | bool ctx_switch) | ||
449 | { | 503 | { |
504 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
505 | |||
450 | /* IB packet must end on a 8 DW boundary */ | 506 | /* IB packet must end on a 8 DW boundary */ |
451 | sdma_v4_0_ring_insert_nop(ring, (10 - (lower_32_bits(ring->wptr) & 7)) % 8); | 507 | sdma_v4_0_ring_insert_nop(ring, (10 - (lower_32_bits(ring->wptr) & 7)) % 8); |
452 | 508 | ||
@@ -568,16 +624,16 @@ static void sdma_v4_0_gfx_stop(struct amdgpu_device *adev) | |||
568 | amdgpu_ttm_set_buffer_funcs_status(adev, false); | 624 | amdgpu_ttm_set_buffer_funcs_status(adev, false); |
569 | 625 | ||
570 | for (i = 0; i < adev->sdma.num_instances; i++) { | 626 | for (i = 0; i < adev->sdma.num_instances; i++) { |
571 | rb_cntl = RREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_CNTL)); | 627 | rb_cntl = RREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL); |
572 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0); | 628 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0); |
573 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_CNTL), rb_cntl); | 629 | WREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL, rb_cntl); |
574 | ib_cntl = RREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_IB_CNTL)); | 630 | ib_cntl = RREG32_SDMA(i, mmSDMA0_GFX_IB_CNTL); |
575 | ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0); | 631 | ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0); |
576 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_IB_CNTL), ib_cntl); | 632 | WREG32_SDMA(i, mmSDMA0_GFX_IB_CNTL, ib_cntl); |
577 | } | 633 | } |
578 | 634 | ||
579 | sdma0->ready = false; | 635 | sdma0->sched.ready = false; |
580 | sdma1->ready = false; | 636 | sdma1->sched.ready = false; |
581 | } | 637 | } |
582 | 638 | ||
583 | /** | 639 | /** |
@@ -593,6 +649,39 @@ static void sdma_v4_0_rlc_stop(struct amdgpu_device *adev) | |||
593 | } | 649 | } |
594 | 650 | ||
595 | /** | 651 | /** |
652 | * sdma_v4_0_page_stop - stop the page async dma engines | ||
653 | * | ||
654 | * @adev: amdgpu_device pointer | ||
655 | * | ||
656 | * Stop the page async dma ring buffers (VEGA10). | ||
657 | */ | ||
658 | static void sdma_v4_0_page_stop(struct amdgpu_device *adev) | ||
659 | { | ||
660 | struct amdgpu_ring *sdma0 = &adev->sdma.instance[0].page; | ||
661 | struct amdgpu_ring *sdma1 = &adev->sdma.instance[1].page; | ||
662 | u32 rb_cntl, ib_cntl; | ||
663 | int i; | ||
664 | |||
665 | if ((adev->mman.buffer_funcs_ring == sdma0) || | ||
666 | (adev->mman.buffer_funcs_ring == sdma1)) | ||
667 | amdgpu_ttm_set_buffer_funcs_status(adev, false); | ||
668 | |||
669 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
670 | rb_cntl = RREG32_SDMA(i, mmSDMA0_PAGE_RB_CNTL); | ||
671 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_PAGE_RB_CNTL, | ||
672 | RB_ENABLE, 0); | ||
673 | WREG32_SDMA(i, mmSDMA0_PAGE_RB_CNTL, rb_cntl); | ||
674 | ib_cntl = RREG32_SDMA(i, mmSDMA0_PAGE_IB_CNTL); | ||
675 | ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_PAGE_IB_CNTL, | ||
676 | IB_ENABLE, 0); | ||
677 | WREG32_SDMA(i, mmSDMA0_PAGE_IB_CNTL, ib_cntl); | ||
678 | } | ||
679 | |||
680 | sdma0->sched.ready = false; | ||
681 | sdma1->sched.ready = false; | ||
682 | } | ||
683 | |||
684 | /** | ||
596 | * sdma_v_0_ctx_switch_enable - stop the async dma engines context switch | 685 | * sdma_v_0_ctx_switch_enable - stop the async dma engines context switch |
597 | * | 686 | * |
598 | * @adev: amdgpu_device pointer | 687 | * @adev: amdgpu_device pointer |
@@ -630,18 +719,15 @@ static void sdma_v4_0_ctx_switch_enable(struct amdgpu_device *adev, bool enable) | |||
630 | } | 719 | } |
631 | 720 | ||
632 | for (i = 0; i < adev->sdma.num_instances; i++) { | 721 | for (i = 0; i < adev->sdma.num_instances; i++) { |
633 | f32_cntl = RREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_CNTL)); | 722 | f32_cntl = RREG32_SDMA(i, mmSDMA0_CNTL); |
634 | f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL, | 723 | f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL, |
635 | AUTO_CTXSW_ENABLE, enable ? 1 : 0); | 724 | AUTO_CTXSW_ENABLE, enable ? 1 : 0); |
636 | if (enable && amdgpu_sdma_phase_quantum) { | 725 | if (enable && amdgpu_sdma_phase_quantum) { |
637 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_PHASE0_QUANTUM), | 726 | WREG32_SDMA(i, mmSDMA0_PHASE0_QUANTUM, phase_quantum); |
638 | phase_quantum); | 727 | WREG32_SDMA(i, mmSDMA0_PHASE1_QUANTUM, phase_quantum); |
639 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_PHASE1_QUANTUM), | 728 | WREG32_SDMA(i, mmSDMA0_PHASE2_QUANTUM, phase_quantum); |
640 | phase_quantum); | ||
641 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_PHASE2_QUANTUM), | ||
642 | phase_quantum); | ||
643 | } | 729 | } |
644 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_CNTL), f32_cntl); | 730 | WREG32_SDMA(i, mmSDMA0_CNTL, f32_cntl); |
645 | } | 731 | } |
646 | 732 | ||
647 | } | 733 | } |
@@ -662,156 +748,217 @@ static void sdma_v4_0_enable(struct amdgpu_device *adev, bool enable) | |||
662 | if (enable == false) { | 748 | if (enable == false) { |
663 | sdma_v4_0_gfx_stop(adev); | 749 | sdma_v4_0_gfx_stop(adev); |
664 | sdma_v4_0_rlc_stop(adev); | 750 | sdma_v4_0_rlc_stop(adev); |
751 | if (adev->sdma.has_page_queue) | ||
752 | sdma_v4_0_page_stop(adev); | ||
665 | } | 753 | } |
666 | 754 | ||
667 | for (i = 0; i < adev->sdma.num_instances; i++) { | 755 | for (i = 0; i < adev->sdma.num_instances; i++) { |
668 | f32_cntl = RREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_F32_CNTL)); | 756 | f32_cntl = RREG32_SDMA(i, mmSDMA0_F32_CNTL); |
669 | f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_F32_CNTL, HALT, enable ? 0 : 1); | 757 | f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_F32_CNTL, HALT, enable ? 0 : 1); |
670 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_F32_CNTL), f32_cntl); | 758 | WREG32_SDMA(i, mmSDMA0_F32_CNTL, f32_cntl); |
671 | } | 759 | } |
672 | } | 760 | } |
673 | 761 | ||
674 | /** | 762 | /** |
763 | * sdma_v4_0_rb_cntl - get parameters for rb_cntl | ||
764 | */ | ||
765 | static uint32_t sdma_v4_0_rb_cntl(struct amdgpu_ring *ring, uint32_t rb_cntl) | ||
766 | { | ||
767 | /* Set ring buffer size in dwords */ | ||
768 | uint32_t rb_bufsz = order_base_2(ring->ring_size / 4); | ||
769 | |||
770 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_SIZE, rb_bufsz); | ||
771 | #ifdef __BIG_ENDIAN | ||
772 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_SWAP_ENABLE, 1); | ||
773 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, | ||
774 | RPTR_WRITEBACK_SWAP_ENABLE, 1); | ||
775 | #endif | ||
776 | return rb_cntl; | ||
777 | } | ||
778 | |||
779 | /** | ||
675 | * sdma_v4_0_gfx_resume - setup and start the async dma engines | 780 | * sdma_v4_0_gfx_resume - setup and start the async dma engines |
676 | * | 781 | * |
677 | * @adev: amdgpu_device pointer | 782 | * @adev: amdgpu_device pointer |
783 | * @i: instance to resume | ||
678 | * | 784 | * |
679 | * Set up the gfx DMA ring buffers and enable them (VEGA10). | 785 | * Set up the gfx DMA ring buffers and enable them (VEGA10). |
680 | * Returns 0 for success, error for failure. | 786 | * Returns 0 for success, error for failure. |
681 | */ | 787 | */ |
682 | static int sdma_v4_0_gfx_resume(struct amdgpu_device *adev) | 788 | static void sdma_v4_0_gfx_resume(struct amdgpu_device *adev, unsigned int i) |
683 | { | 789 | { |
684 | struct amdgpu_ring *ring; | 790 | struct amdgpu_ring *ring = &adev->sdma.instance[i].ring; |
685 | u32 rb_cntl, ib_cntl, wptr_poll_cntl; | 791 | u32 rb_cntl, ib_cntl, wptr_poll_cntl; |
686 | u32 rb_bufsz; | ||
687 | u32 wb_offset; | 792 | u32 wb_offset; |
688 | u32 doorbell; | 793 | u32 doorbell; |
689 | u32 doorbell_offset; | 794 | u32 doorbell_offset; |
690 | u32 temp; | ||
691 | u64 wptr_gpu_addr; | 795 | u64 wptr_gpu_addr; |
692 | int i, r; | ||
693 | |||
694 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
695 | ring = &adev->sdma.instance[i].ring; | ||
696 | wb_offset = (ring->rptr_offs * 4); | ||
697 | 796 | ||
698 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL), 0); | 797 | wb_offset = (ring->rptr_offs * 4); |
699 | 798 | ||
700 | /* Set ring buffer size in dwords */ | 799 | rb_cntl = RREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL); |
701 | rb_bufsz = order_base_2(ring->ring_size / 4); | 800 | rb_cntl = sdma_v4_0_rb_cntl(ring, rb_cntl); |
702 | rb_cntl = RREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_CNTL)); | 801 | WREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL, rb_cntl); |
703 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_SIZE, rb_bufsz); | ||
704 | #ifdef __BIG_ENDIAN | ||
705 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_SWAP_ENABLE, 1); | ||
706 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, | ||
707 | RPTR_WRITEBACK_SWAP_ENABLE, 1); | ||
708 | #endif | ||
709 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_CNTL), rb_cntl); | ||
710 | 802 | ||
711 | /* Initialize the ring buffer's read and write pointers */ | 803 | /* Initialize the ring buffer's read and write pointers */ |
712 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_RPTR), 0); | 804 | WREG32_SDMA(i, mmSDMA0_GFX_RB_RPTR, 0); |
713 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_RPTR_HI), 0); | 805 | WREG32_SDMA(i, mmSDMA0_GFX_RB_RPTR_HI, 0); |
714 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_WPTR), 0); | 806 | WREG32_SDMA(i, mmSDMA0_GFX_RB_WPTR, 0); |
715 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_WPTR_HI), 0); | 807 | WREG32_SDMA(i, mmSDMA0_GFX_RB_WPTR_HI, 0); |
716 | 808 | ||
717 | /* set the wb address whether it's enabled or not */ | 809 | /* set the wb address whether it's enabled or not */ |
718 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_RPTR_ADDR_HI), | 810 | WREG32_SDMA(i, mmSDMA0_GFX_RB_RPTR_ADDR_HI, |
719 | upper_32_bits(adev->wb.gpu_addr + wb_offset) & 0xFFFFFFFF); | 811 | upper_32_bits(adev->wb.gpu_addr + wb_offset) & 0xFFFFFFFF); |
720 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_RPTR_ADDR_LO), | 812 | WREG32_SDMA(i, mmSDMA0_GFX_RB_RPTR_ADDR_LO, |
721 | lower_32_bits(adev->wb.gpu_addr + wb_offset) & 0xFFFFFFFC); | 813 | lower_32_bits(adev->wb.gpu_addr + wb_offset) & 0xFFFFFFFC); |
722 | 814 | ||
723 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RPTR_WRITEBACK_ENABLE, 1); | 815 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, |
816 | RPTR_WRITEBACK_ENABLE, 1); | ||
724 | 817 | ||
725 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_BASE), ring->gpu_addr >> 8); | 818 | WREG32_SDMA(i, mmSDMA0_GFX_RB_BASE, ring->gpu_addr >> 8); |
726 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_BASE_HI), ring->gpu_addr >> 40); | 819 | WREG32_SDMA(i, mmSDMA0_GFX_RB_BASE_HI, ring->gpu_addr >> 40); |
727 | 820 | ||
728 | ring->wptr = 0; | 821 | ring->wptr = 0; |
729 | 822 | ||
730 | /* before programing wptr to a less value, need set minor_ptr_update first */ | 823 | /* before programing wptr to a less value, need set minor_ptr_update first */ |
731 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_MINOR_PTR_UPDATE), 1); | 824 | WREG32_SDMA(i, mmSDMA0_GFX_MINOR_PTR_UPDATE, 1); |
732 | 825 | ||
733 | if (!amdgpu_sriov_vf(adev)) { /* only bare-metal use register write for wptr */ | 826 | doorbell = RREG32_SDMA(i, mmSDMA0_GFX_DOORBELL); |
734 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_WPTR), lower_32_bits(ring->wptr) << 2); | 827 | doorbell_offset = RREG32_SDMA(i, mmSDMA0_GFX_DOORBELL_OFFSET); |
735 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_WPTR_HI), upper_32_bits(ring->wptr) << 2); | ||
736 | } | ||
737 | 828 | ||
738 | doorbell = RREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_DOORBELL)); | 829 | doorbell = REG_SET_FIELD(doorbell, SDMA0_GFX_DOORBELL, ENABLE, |
739 | doorbell_offset = RREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_DOORBELL_OFFSET)); | 830 | ring->use_doorbell); |
740 | 831 | doorbell_offset = REG_SET_FIELD(doorbell_offset, | |
741 | if (ring->use_doorbell) { | 832 | SDMA0_GFX_DOORBELL_OFFSET, |
742 | doorbell = REG_SET_FIELD(doorbell, SDMA0_GFX_DOORBELL, ENABLE, 1); | ||
743 | doorbell_offset = REG_SET_FIELD(doorbell_offset, SDMA0_GFX_DOORBELL_OFFSET, | ||
744 | OFFSET, ring->doorbell_index); | 833 | OFFSET, ring->doorbell_index); |
745 | } else { | 834 | WREG32_SDMA(i, mmSDMA0_GFX_DOORBELL, doorbell); |
746 | doorbell = REG_SET_FIELD(doorbell, SDMA0_GFX_DOORBELL, ENABLE, 0); | 835 | WREG32_SDMA(i, mmSDMA0_GFX_DOORBELL_OFFSET, doorbell_offset); |
747 | } | 836 | adev->nbio_funcs->sdma_doorbell_range(adev, i, ring->use_doorbell, |
748 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_DOORBELL), doorbell); | 837 | ring->doorbell_index); |
749 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_DOORBELL_OFFSET), doorbell_offset); | 838 | |
750 | adev->nbio_funcs->sdma_doorbell_range(adev, i, ring->use_doorbell, | 839 | sdma_v4_0_ring_set_wptr(ring); |
751 | ring->doorbell_index); | 840 | |
841 | /* set minor_ptr_update to 0 after wptr programed */ | ||
842 | WREG32_SDMA(i, mmSDMA0_GFX_MINOR_PTR_UPDATE, 0); | ||
843 | |||
844 | /* setup the wptr shadow polling */ | ||
845 | wptr_gpu_addr = adev->wb.gpu_addr + (ring->wptr_offs * 4); | ||
846 | WREG32_SDMA(i, mmSDMA0_GFX_RB_WPTR_POLL_ADDR_LO, | ||
847 | lower_32_bits(wptr_gpu_addr)); | ||
848 | WREG32_SDMA(i, mmSDMA0_GFX_RB_WPTR_POLL_ADDR_HI, | ||
849 | upper_32_bits(wptr_gpu_addr)); | ||
850 | wptr_poll_cntl = RREG32_SDMA(i, mmSDMA0_GFX_RB_WPTR_POLL_CNTL); | ||
851 | wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, | ||
852 | SDMA0_GFX_RB_WPTR_POLL_CNTL, | ||
853 | F32_POLL_ENABLE, amdgpu_sriov_vf(adev)); | ||
854 | WREG32_SDMA(i, mmSDMA0_GFX_RB_WPTR_POLL_CNTL, wptr_poll_cntl); | ||
855 | |||
856 | /* enable DMA RB */ | ||
857 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 1); | ||
858 | WREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL, rb_cntl); | ||
859 | |||
860 | ib_cntl = RREG32_SDMA(i, mmSDMA0_GFX_IB_CNTL); | ||
861 | ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 1); | ||
862 | #ifdef __BIG_ENDIAN | ||
863 | ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_SWAP_ENABLE, 1); | ||
864 | #endif | ||
865 | /* enable DMA IBs */ | ||
866 | WREG32_SDMA(i, mmSDMA0_GFX_IB_CNTL, ib_cntl); | ||
752 | 867 | ||
753 | if (amdgpu_sriov_vf(adev)) | 868 | ring->sched.ready = true; |
754 | sdma_v4_0_ring_set_wptr(ring); | 869 | } |
755 | 870 | ||
756 | /* set minor_ptr_update to 0 after wptr programed */ | 871 | /** |
757 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_MINOR_PTR_UPDATE), 0); | 872 | * sdma_v4_0_page_resume - setup and start the async dma engines |
873 | * | ||
874 | * @adev: amdgpu_device pointer | ||
875 | * @i: instance to resume | ||
876 | * | ||
877 | * Set up the page DMA ring buffers and enable them (VEGA10). | ||
878 | * Returns 0 for success, error for failure. | ||
879 | */ | ||
880 | static void sdma_v4_0_page_resume(struct amdgpu_device *adev, unsigned int i) | ||
881 | { | ||
882 | struct amdgpu_ring *ring = &adev->sdma.instance[i].page; | ||
883 | u32 rb_cntl, ib_cntl, wptr_poll_cntl; | ||
884 | u32 wb_offset; | ||
885 | u32 doorbell; | ||
886 | u32 doorbell_offset; | ||
887 | u64 wptr_gpu_addr; | ||
758 | 888 | ||
759 | /* set utc l1 enable flag always to 1 */ | 889 | wb_offset = (ring->rptr_offs * 4); |
760 | temp = RREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_CNTL)); | ||
761 | temp = REG_SET_FIELD(temp, SDMA0_CNTL, UTC_L1_ENABLE, 1); | ||
762 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_CNTL), temp); | ||
763 | 890 | ||
764 | if (!amdgpu_sriov_vf(adev)) { | 891 | rb_cntl = RREG32_SDMA(i, mmSDMA0_PAGE_RB_CNTL); |
765 | /* unhalt engine */ | 892 | rb_cntl = sdma_v4_0_rb_cntl(ring, rb_cntl); |
766 | temp = RREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_F32_CNTL)); | 893 | WREG32_SDMA(i, mmSDMA0_PAGE_RB_CNTL, rb_cntl); |
767 | temp = REG_SET_FIELD(temp, SDMA0_F32_CNTL, HALT, 0); | ||
768 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_F32_CNTL), temp); | ||
769 | } | ||
770 | 894 | ||
771 | /* setup the wptr shadow polling */ | 895 | /* Initialize the ring buffer's read and write pointers */ |
772 | wptr_gpu_addr = adev->wb.gpu_addr + (ring->wptr_offs * 4); | 896 | WREG32_SDMA(i, mmSDMA0_PAGE_RB_RPTR, 0); |
773 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_WPTR_POLL_ADDR_LO), | 897 | WREG32_SDMA(i, mmSDMA0_PAGE_RB_RPTR_HI, 0); |
774 | lower_32_bits(wptr_gpu_addr)); | 898 | WREG32_SDMA(i, mmSDMA0_PAGE_RB_WPTR, 0); |
775 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_WPTR_POLL_ADDR_HI), | 899 | WREG32_SDMA(i, mmSDMA0_PAGE_RB_WPTR_HI, 0); |
776 | upper_32_bits(wptr_gpu_addr)); | ||
777 | wptr_poll_cntl = RREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_WPTR_POLL_CNTL)); | ||
778 | if (amdgpu_sriov_vf(adev)) | ||
779 | wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, SDMA0_GFX_RB_WPTR_POLL_CNTL, F32_POLL_ENABLE, 1); | ||
780 | else | ||
781 | wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, SDMA0_GFX_RB_WPTR_POLL_CNTL, F32_POLL_ENABLE, 0); | ||
782 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_WPTR_POLL_CNTL), wptr_poll_cntl); | ||
783 | 900 | ||
784 | /* enable DMA RB */ | 901 | /* set the wb address whether it's enabled or not */ |
785 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 1); | 902 | WREG32_SDMA(i, mmSDMA0_PAGE_RB_RPTR_ADDR_HI, |
786 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_CNTL), rb_cntl); | 903 | upper_32_bits(adev->wb.gpu_addr + wb_offset) & 0xFFFFFFFF); |
904 | WREG32_SDMA(i, mmSDMA0_PAGE_RB_RPTR_ADDR_LO, | ||
905 | lower_32_bits(adev->wb.gpu_addr + wb_offset) & 0xFFFFFFFC); | ||
787 | 906 | ||
788 | ib_cntl = RREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_IB_CNTL)); | 907 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_PAGE_RB_CNTL, |
789 | ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 1); | 908 | RPTR_WRITEBACK_ENABLE, 1); |
790 | #ifdef __BIG_ENDIAN | ||
791 | ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_SWAP_ENABLE, 1); | ||
792 | #endif | ||
793 | /* enable DMA IBs */ | ||
794 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_GFX_IB_CNTL), ib_cntl); | ||
795 | 909 | ||
796 | ring->ready = true; | 910 | WREG32_SDMA(i, mmSDMA0_PAGE_RB_BASE, ring->gpu_addr >> 8); |
911 | WREG32_SDMA(i, mmSDMA0_PAGE_RB_BASE_HI, ring->gpu_addr >> 40); | ||
797 | 912 | ||
798 | if (amdgpu_sriov_vf(adev)) { /* bare-metal sequence doesn't need below to lines */ | 913 | ring->wptr = 0; |
799 | sdma_v4_0_ctx_switch_enable(adev, true); | ||
800 | sdma_v4_0_enable(adev, true); | ||
801 | } | ||
802 | 914 | ||
803 | r = amdgpu_ring_test_ring(ring); | 915 | /* before programing wptr to a less value, need set minor_ptr_update first */ |
804 | if (r) { | 916 | WREG32_SDMA(i, mmSDMA0_PAGE_MINOR_PTR_UPDATE, 1); |
805 | ring->ready = false; | ||
806 | return r; | ||
807 | } | ||
808 | 917 | ||
809 | if (adev->mman.buffer_funcs_ring == ring) | 918 | doorbell = RREG32_SDMA(i, mmSDMA0_PAGE_DOORBELL); |
810 | amdgpu_ttm_set_buffer_funcs_status(adev, true); | 919 | doorbell_offset = RREG32_SDMA(i, mmSDMA0_PAGE_DOORBELL_OFFSET); |
811 | 920 | ||
812 | } | 921 | doorbell = REG_SET_FIELD(doorbell, SDMA0_PAGE_DOORBELL, ENABLE, |
922 | ring->use_doorbell); | ||
923 | doorbell_offset = REG_SET_FIELD(doorbell_offset, | ||
924 | SDMA0_PAGE_DOORBELL_OFFSET, | ||
925 | OFFSET, ring->doorbell_index); | ||
926 | WREG32_SDMA(i, mmSDMA0_PAGE_DOORBELL, doorbell); | ||
927 | WREG32_SDMA(i, mmSDMA0_PAGE_DOORBELL_OFFSET, doorbell_offset); | ||
928 | /* TODO: enable doorbell support */ | ||
929 | /*adev->nbio_funcs->sdma_doorbell_range(adev, i, ring->use_doorbell, | ||
930 | ring->doorbell_index);*/ | ||
931 | |||
932 | sdma_v4_0_ring_set_wptr(ring); | ||
933 | |||
934 | /* set minor_ptr_update to 0 after wptr programed */ | ||
935 | WREG32_SDMA(i, mmSDMA0_PAGE_MINOR_PTR_UPDATE, 0); | ||
936 | |||
937 | /* setup the wptr shadow polling */ | ||
938 | wptr_gpu_addr = adev->wb.gpu_addr + (ring->wptr_offs * 4); | ||
939 | WREG32_SDMA(i, mmSDMA0_PAGE_RB_WPTR_POLL_ADDR_LO, | ||
940 | lower_32_bits(wptr_gpu_addr)); | ||
941 | WREG32_SDMA(i, mmSDMA0_PAGE_RB_WPTR_POLL_ADDR_HI, | ||
942 | upper_32_bits(wptr_gpu_addr)); | ||
943 | wptr_poll_cntl = RREG32_SDMA(i, mmSDMA0_PAGE_RB_WPTR_POLL_CNTL); | ||
944 | wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, | ||
945 | SDMA0_PAGE_RB_WPTR_POLL_CNTL, | ||
946 | F32_POLL_ENABLE, amdgpu_sriov_vf(adev)); | ||
947 | WREG32_SDMA(i, mmSDMA0_PAGE_RB_WPTR_POLL_CNTL, wptr_poll_cntl); | ||
948 | |||
949 | /* enable DMA RB */ | ||
950 | rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_PAGE_RB_CNTL, RB_ENABLE, 1); | ||
951 | WREG32_SDMA(i, mmSDMA0_PAGE_RB_CNTL, rb_cntl); | ||
952 | |||
953 | ib_cntl = RREG32_SDMA(i, mmSDMA0_PAGE_IB_CNTL); | ||
954 | ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_PAGE_IB_CNTL, IB_ENABLE, 1); | ||
955 | #ifdef __BIG_ENDIAN | ||
956 | ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_PAGE_IB_CNTL, IB_SWAP_ENABLE, 1); | ||
957 | #endif | ||
958 | /* enable DMA IBs */ | ||
959 | WREG32_SDMA(i, mmSDMA0_PAGE_IB_CNTL, ib_cntl); | ||
813 | 960 | ||
814 | return 0; | 961 | ring->sched.ready = true; |
815 | } | 962 | } |
816 | 963 | ||
817 | static void | 964 | static void |
@@ -922,12 +1069,14 @@ static int sdma_v4_0_load_microcode(struct amdgpu_device *adev) | |||
922 | (adev->sdma.instance[i].fw->data + | 1069 | (adev->sdma.instance[i].fw->data + |
923 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | 1070 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); |
924 | 1071 | ||
925 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_UCODE_ADDR), 0); | 1072 | WREG32_SDMA(i, mmSDMA0_UCODE_ADDR, 0); |
926 | 1073 | ||
927 | for (j = 0; j < fw_size; j++) | 1074 | for (j = 0; j < fw_size; j++) |
928 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_UCODE_DATA), le32_to_cpup(fw_data++)); | 1075 | WREG32_SDMA(i, mmSDMA0_UCODE_DATA, |
1076 | le32_to_cpup(fw_data++)); | ||
929 | 1077 | ||
930 | WREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_UCODE_ADDR), adev->sdma.instance[i].fw_version); | 1078 | WREG32_SDMA(i, mmSDMA0_UCODE_ADDR, |
1079 | adev->sdma.instance[i].fw_version); | ||
931 | } | 1080 | } |
932 | 1081 | ||
933 | return 0; | 1082 | return 0; |
@@ -943,33 +1092,78 @@ static int sdma_v4_0_load_microcode(struct amdgpu_device *adev) | |||
943 | */ | 1092 | */ |
944 | static int sdma_v4_0_start(struct amdgpu_device *adev) | 1093 | static int sdma_v4_0_start(struct amdgpu_device *adev) |
945 | { | 1094 | { |
946 | int r = 0; | 1095 | struct amdgpu_ring *ring; |
1096 | int i, r; | ||
947 | 1097 | ||
948 | if (amdgpu_sriov_vf(adev)) { | 1098 | if (amdgpu_sriov_vf(adev)) { |
949 | sdma_v4_0_ctx_switch_enable(adev, false); | 1099 | sdma_v4_0_ctx_switch_enable(adev, false); |
950 | sdma_v4_0_enable(adev, false); | 1100 | sdma_v4_0_enable(adev, false); |
1101 | } else { | ||
951 | 1102 | ||
952 | /* set RB registers */ | 1103 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { |
953 | r = sdma_v4_0_gfx_resume(adev); | 1104 | r = sdma_v4_0_load_microcode(adev); |
954 | return r; | 1105 | if (r) |
1106 | return r; | ||
1107 | } | ||
1108 | |||
1109 | /* unhalt the MEs */ | ||
1110 | sdma_v4_0_enable(adev, true); | ||
1111 | /* enable sdma ring preemption */ | ||
1112 | sdma_v4_0_ctx_switch_enable(adev, true); | ||
1113 | } | ||
1114 | |||
1115 | /* start the gfx rings and rlc compute queues */ | ||
1116 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
1117 | uint32_t temp; | ||
1118 | |||
1119 | WREG32_SDMA(i, mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL, 0); | ||
1120 | sdma_v4_0_gfx_resume(adev, i); | ||
1121 | if (adev->sdma.has_page_queue) | ||
1122 | sdma_v4_0_page_resume(adev, i); | ||
1123 | |||
1124 | /* set utc l1 enable flag always to 1 */ | ||
1125 | temp = RREG32_SDMA(i, mmSDMA0_CNTL); | ||
1126 | temp = REG_SET_FIELD(temp, SDMA0_CNTL, UTC_L1_ENABLE, 1); | ||
1127 | WREG32_SDMA(i, mmSDMA0_CNTL, temp); | ||
1128 | |||
1129 | if (!amdgpu_sriov_vf(adev)) { | ||
1130 | /* unhalt engine */ | ||
1131 | temp = RREG32_SDMA(i, mmSDMA0_F32_CNTL); | ||
1132 | temp = REG_SET_FIELD(temp, SDMA0_F32_CNTL, HALT, 0); | ||
1133 | WREG32_SDMA(i, mmSDMA0_F32_CNTL, temp); | ||
1134 | } | ||
955 | } | 1135 | } |
956 | 1136 | ||
957 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { | 1137 | if (amdgpu_sriov_vf(adev)) { |
958 | r = sdma_v4_0_load_microcode(adev); | 1138 | sdma_v4_0_ctx_switch_enable(adev, true); |
1139 | sdma_v4_0_enable(adev, true); | ||
1140 | } else { | ||
1141 | r = sdma_v4_0_rlc_resume(adev); | ||
959 | if (r) | 1142 | if (r) |
960 | return r; | 1143 | return r; |
961 | } | 1144 | } |
962 | 1145 | ||
963 | /* unhalt the MEs */ | 1146 | for (i = 0; i < adev->sdma.num_instances; i++) { |
964 | sdma_v4_0_enable(adev, true); | 1147 | ring = &adev->sdma.instance[i].ring; |
965 | /* enable sdma ring preemption */ | ||
966 | sdma_v4_0_ctx_switch_enable(adev, true); | ||
967 | 1148 | ||
968 | /* start the gfx rings and rlc compute queues */ | 1149 | r = amdgpu_ring_test_helper(ring); |
969 | r = sdma_v4_0_gfx_resume(adev); | 1150 | if (r) |
970 | if (r) | 1151 | return r; |
971 | return r; | 1152 | |
972 | r = sdma_v4_0_rlc_resume(adev); | 1153 | if (adev->sdma.has_page_queue) { |
1154 | struct amdgpu_ring *page = &adev->sdma.instance[i].page; | ||
1155 | |||
1156 | r = amdgpu_ring_test_helper(page); | ||
1157 | if (r) | ||
1158 | return r; | ||
1159 | |||
1160 | if (adev->mman.buffer_funcs_ring == page) | ||
1161 | amdgpu_ttm_set_buffer_funcs_status(adev, true); | ||
1162 | } | ||
1163 | |||
1164 | if (adev->mman.buffer_funcs_ring == ring) | ||
1165 | amdgpu_ttm_set_buffer_funcs_status(adev, true); | ||
1166 | } | ||
973 | 1167 | ||
974 | return r; | 1168 | return r; |
975 | } | 1169 | } |
@@ -993,21 +1187,16 @@ static int sdma_v4_0_ring_test_ring(struct amdgpu_ring *ring) | |||
993 | u64 gpu_addr; | 1187 | u64 gpu_addr; |
994 | 1188 | ||
995 | r = amdgpu_device_wb_get(adev, &index); | 1189 | r = amdgpu_device_wb_get(adev, &index); |
996 | if (r) { | 1190 | if (r) |
997 | dev_err(adev->dev, "(%d) failed to allocate wb slot\n", r); | ||
998 | return r; | 1191 | return r; |
999 | } | ||
1000 | 1192 | ||
1001 | gpu_addr = adev->wb.gpu_addr + (index * 4); | 1193 | gpu_addr = adev->wb.gpu_addr + (index * 4); |
1002 | tmp = 0xCAFEDEAD; | 1194 | tmp = 0xCAFEDEAD; |
1003 | adev->wb.wb[index] = cpu_to_le32(tmp); | 1195 | adev->wb.wb[index] = cpu_to_le32(tmp); |
1004 | 1196 | ||
1005 | r = amdgpu_ring_alloc(ring, 5); | 1197 | r = amdgpu_ring_alloc(ring, 5); |
1006 | if (r) { | 1198 | if (r) |
1007 | DRM_ERROR("amdgpu: dma failed to lock ring %d (%d).\n", ring->idx, r); | 1199 | goto error_free_wb; |
1008 | amdgpu_device_wb_free(adev, index); | ||
1009 | return r; | ||
1010 | } | ||
1011 | 1200 | ||
1012 | amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) | | 1201 | amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) | |
1013 | SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_WRITE_LINEAR)); | 1202 | SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_WRITE_LINEAR)); |
@@ -1024,15 +1213,11 @@ static int sdma_v4_0_ring_test_ring(struct amdgpu_ring *ring) | |||
1024 | DRM_UDELAY(1); | 1213 | DRM_UDELAY(1); |
1025 | } | 1214 | } |
1026 | 1215 | ||
1027 | if (i < adev->usec_timeout) { | 1216 | if (i >= adev->usec_timeout) |
1028 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", ring->idx, i); | 1217 | r = -ETIMEDOUT; |
1029 | } else { | ||
1030 | DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", | ||
1031 | ring->idx, tmp); | ||
1032 | r = -EINVAL; | ||
1033 | } | ||
1034 | amdgpu_device_wb_free(adev, index); | ||
1035 | 1218 | ||
1219 | error_free_wb: | ||
1220 | amdgpu_device_wb_free(adev, index); | ||
1036 | return r; | 1221 | return r; |
1037 | } | 1222 | } |
1038 | 1223 | ||
@@ -1055,20 +1240,16 @@ static int sdma_v4_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
1055 | u64 gpu_addr; | 1240 | u64 gpu_addr; |
1056 | 1241 | ||
1057 | r = amdgpu_device_wb_get(adev, &index); | 1242 | r = amdgpu_device_wb_get(adev, &index); |
1058 | if (r) { | 1243 | if (r) |
1059 | dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r); | ||
1060 | return r; | 1244 | return r; |
1061 | } | ||
1062 | 1245 | ||
1063 | gpu_addr = adev->wb.gpu_addr + (index * 4); | 1246 | gpu_addr = adev->wb.gpu_addr + (index * 4); |
1064 | tmp = 0xCAFEDEAD; | 1247 | tmp = 0xCAFEDEAD; |
1065 | adev->wb.wb[index] = cpu_to_le32(tmp); | 1248 | adev->wb.wb[index] = cpu_to_le32(tmp); |
1066 | memset(&ib, 0, sizeof(ib)); | 1249 | memset(&ib, 0, sizeof(ib)); |
1067 | r = amdgpu_ib_get(adev, NULL, 256, &ib); | 1250 | r = amdgpu_ib_get(adev, NULL, 256, &ib); |
1068 | if (r) { | 1251 | if (r) |
1069 | DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r); | ||
1070 | goto err0; | 1252 | goto err0; |
1071 | } | ||
1072 | 1253 | ||
1073 | ib.ptr[0] = SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) | | 1254 | ib.ptr[0] = SDMA_PKT_HEADER_OP(SDMA_OP_WRITE) | |
1074 | SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_WRITE_LINEAR); | 1255 | SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_WRITE_LINEAR); |
@@ -1087,21 +1268,17 @@ static int sdma_v4_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
1087 | 1268 | ||
1088 | r = dma_fence_wait_timeout(f, false, timeout); | 1269 | r = dma_fence_wait_timeout(f, false, timeout); |
1089 | if (r == 0) { | 1270 | if (r == 0) { |
1090 | DRM_ERROR("amdgpu: IB test timed out\n"); | ||
1091 | r = -ETIMEDOUT; | 1271 | r = -ETIMEDOUT; |
1092 | goto err1; | 1272 | goto err1; |
1093 | } else if (r < 0) { | 1273 | } else if (r < 0) { |
1094 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | ||
1095 | goto err1; | 1274 | goto err1; |
1096 | } | 1275 | } |
1097 | tmp = le32_to_cpu(adev->wb.wb[index]); | 1276 | tmp = le32_to_cpu(adev->wb.wb[index]); |
1098 | if (tmp == 0xDEADBEEF) { | 1277 | if (tmp == 0xDEADBEEF) |
1099 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | ||
1100 | r = 0; | 1278 | r = 0; |
1101 | } else { | 1279 | else |
1102 | DRM_ERROR("amdgpu: ib test failed (0x%08X)\n", tmp); | ||
1103 | r = -EINVAL; | 1280 | r = -EINVAL; |
1104 | } | 1281 | |
1105 | err1: | 1282 | err1: |
1106 | amdgpu_ib_free(adev, &ib, NULL); | 1283 | amdgpu_ib_free(adev, &ib, NULL); |
1107 | dma_fence_put(f); | 1284 | dma_fence_put(f); |
@@ -1206,7 +1383,7 @@ static void sdma_v4_0_vm_set_pte_pde(struct amdgpu_ib *ib, | |||
1206 | */ | 1383 | */ |
1207 | static void sdma_v4_0_ring_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) | 1384 | static void sdma_v4_0_ring_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) |
1208 | { | 1385 | { |
1209 | struct amdgpu_sdma_instance *sdma = amdgpu_get_sdma_instance(ring); | 1386 | struct amdgpu_sdma_instance *sdma = amdgpu_sdma_get_instance_from_ring(ring); |
1210 | u32 pad_count; | 1387 | u32 pad_count; |
1211 | int i; | 1388 | int i; |
1212 | 1389 | ||
@@ -1276,10 +1453,18 @@ static int sdma_v4_0_early_init(void *handle) | |||
1276 | { | 1453 | { |
1277 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1454 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1278 | 1455 | ||
1279 | if (adev->asic_type == CHIP_RAVEN) | 1456 | if (adev->asic_type == CHIP_RAVEN) { |
1280 | adev->sdma.num_instances = 1; | 1457 | adev->sdma.num_instances = 1; |
1281 | else | 1458 | adev->sdma.has_page_queue = false; |
1459 | } else { | ||
1282 | adev->sdma.num_instances = 2; | 1460 | adev->sdma.num_instances = 2; |
1461 | /* TODO: Page queue breaks driver reload under SRIOV */ | ||
1462 | if ((adev->asic_type == CHIP_VEGA10) && amdgpu_sriov_vf((adev))) | ||
1463 | adev->sdma.has_page_queue = false; | ||
1464 | else if (adev->asic_type != CHIP_VEGA20 && | ||
1465 | adev->asic_type != CHIP_VEGA12) | ||
1466 | adev->sdma.has_page_queue = true; | ||
1467 | } | ||
1283 | 1468 | ||
1284 | sdma_v4_0_set_ring_funcs(adev); | 1469 | sdma_v4_0_set_ring_funcs(adev); |
1285 | sdma_v4_0_set_buffer_funcs(adev); | 1470 | sdma_v4_0_set_buffer_funcs(adev); |
@@ -1340,6 +1525,21 @@ static int sdma_v4_0_sw_init(void *handle) | |||
1340 | AMDGPU_SDMA_IRQ_TRAP1); | 1525 | AMDGPU_SDMA_IRQ_TRAP1); |
1341 | if (r) | 1526 | if (r) |
1342 | return r; | 1527 | return r; |
1528 | |||
1529 | if (adev->sdma.has_page_queue) { | ||
1530 | ring = &adev->sdma.instance[i].page; | ||
1531 | ring->ring_obj = NULL; | ||
1532 | ring->use_doorbell = false; | ||
1533 | |||
1534 | sprintf(ring->name, "page%d", i); | ||
1535 | r = amdgpu_ring_init(adev, ring, 1024, | ||
1536 | &adev->sdma.trap_irq, | ||
1537 | (i == 0) ? | ||
1538 | AMDGPU_SDMA_IRQ_TRAP0 : | ||
1539 | AMDGPU_SDMA_IRQ_TRAP1); | ||
1540 | if (r) | ||
1541 | return r; | ||
1542 | } | ||
1343 | } | 1543 | } |
1344 | 1544 | ||
1345 | return r; | 1545 | return r; |
@@ -1350,8 +1550,11 @@ static int sdma_v4_0_sw_fini(void *handle) | |||
1350 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1550 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1351 | int i; | 1551 | int i; |
1352 | 1552 | ||
1353 | for (i = 0; i < adev->sdma.num_instances; i++) | 1553 | for (i = 0; i < adev->sdma.num_instances; i++) { |
1354 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); | 1554 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); |
1555 | if (adev->sdma.has_page_queue) | ||
1556 | amdgpu_ring_fini(&adev->sdma.instance[i].page); | ||
1557 | } | ||
1355 | 1558 | ||
1356 | for (i = 0; i < adev->sdma.num_instances; i++) { | 1559 | for (i = 0; i < adev->sdma.num_instances; i++) { |
1357 | release_firmware(adev->sdma.instance[i].fw); | 1560 | release_firmware(adev->sdma.instance[i].fw); |
@@ -1414,7 +1617,7 @@ static bool sdma_v4_0_is_idle(void *handle) | |||
1414 | u32 i; | 1617 | u32 i; |
1415 | 1618 | ||
1416 | for (i = 0; i < adev->sdma.num_instances; i++) { | 1619 | for (i = 0; i < adev->sdma.num_instances; i++) { |
1417 | u32 tmp = RREG32(sdma_v4_0_get_reg_offset(adev, i, mmSDMA0_STATUS_REG)); | 1620 | u32 tmp = RREG32_SDMA(i, mmSDMA0_STATUS_REG); |
1418 | 1621 | ||
1419 | if (!(tmp & SDMA0_STATUS_REG__IDLE_MASK)) | 1622 | if (!(tmp & SDMA0_STATUS_REG__IDLE_MASK)) |
1420 | return false; | 1623 | return false; |
@@ -1430,8 +1633,8 @@ static int sdma_v4_0_wait_for_idle(void *handle) | |||
1430 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1633 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1431 | 1634 | ||
1432 | for (i = 0; i < adev->usec_timeout; i++) { | 1635 | for (i = 0; i < adev->usec_timeout; i++) { |
1433 | sdma0 = RREG32(sdma_v4_0_get_reg_offset(adev, 0, mmSDMA0_STATUS_REG)); | 1636 | sdma0 = RREG32_SDMA(0, mmSDMA0_STATUS_REG); |
1434 | sdma1 = RREG32(sdma_v4_0_get_reg_offset(adev, 1, mmSDMA0_STATUS_REG)); | 1637 | sdma1 = RREG32_SDMA(1, mmSDMA0_STATUS_REG); |
1435 | 1638 | ||
1436 | if (sdma0 & sdma1 & SDMA0_STATUS_REG__IDLE_MASK) | 1639 | if (sdma0 & sdma1 & SDMA0_STATUS_REG__IDLE_MASK) |
1437 | return 0; | 1640 | return 0; |
@@ -1452,16 +1655,13 @@ static int sdma_v4_0_set_trap_irq_state(struct amdgpu_device *adev, | |||
1452 | unsigned type, | 1655 | unsigned type, |
1453 | enum amdgpu_interrupt_state state) | 1656 | enum amdgpu_interrupt_state state) |
1454 | { | 1657 | { |
1658 | unsigned int instance = (type == AMDGPU_SDMA_IRQ_TRAP0) ? 0 : 1; | ||
1455 | u32 sdma_cntl; | 1659 | u32 sdma_cntl; |
1456 | 1660 | ||
1457 | u32 reg_offset = (type == AMDGPU_SDMA_IRQ_TRAP0) ? | 1661 | sdma_cntl = RREG32_SDMA(instance, mmSDMA0_CNTL); |
1458 | sdma_v4_0_get_reg_offset(adev, 0, mmSDMA0_CNTL) : | ||
1459 | sdma_v4_0_get_reg_offset(adev, 1, mmSDMA0_CNTL); | ||
1460 | |||
1461 | sdma_cntl = RREG32(reg_offset); | ||
1462 | sdma_cntl = REG_SET_FIELD(sdma_cntl, SDMA0_CNTL, TRAP_ENABLE, | 1662 | sdma_cntl = REG_SET_FIELD(sdma_cntl, SDMA0_CNTL, TRAP_ENABLE, |
1463 | state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0); | 1663 | state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0); |
1464 | WREG32(reg_offset, sdma_cntl); | 1664 | WREG32_SDMA(instance, mmSDMA0_CNTL, sdma_cntl); |
1465 | 1665 | ||
1466 | return 0; | 1666 | return 0; |
1467 | } | 1667 | } |
@@ -1470,39 +1670,32 @@ static int sdma_v4_0_process_trap_irq(struct amdgpu_device *adev, | |||
1470 | struct amdgpu_irq_src *source, | 1670 | struct amdgpu_irq_src *source, |
1471 | struct amdgpu_iv_entry *entry) | 1671 | struct amdgpu_iv_entry *entry) |
1472 | { | 1672 | { |
1673 | uint32_t instance; | ||
1674 | |||
1473 | DRM_DEBUG("IH: SDMA trap\n"); | 1675 | DRM_DEBUG("IH: SDMA trap\n"); |
1474 | switch (entry->client_id) { | 1676 | switch (entry->client_id) { |
1475 | case SOC15_IH_CLIENTID_SDMA0: | 1677 | case SOC15_IH_CLIENTID_SDMA0: |
1476 | switch (entry->ring_id) { | 1678 | instance = 0; |
1477 | case 0: | ||
1478 | amdgpu_fence_process(&adev->sdma.instance[0].ring); | ||
1479 | break; | ||
1480 | case 1: | ||
1481 | /* XXX compute */ | ||
1482 | break; | ||
1483 | case 2: | ||
1484 | /* XXX compute */ | ||
1485 | break; | ||
1486 | case 3: | ||
1487 | /* XXX page queue*/ | ||
1488 | break; | ||
1489 | } | ||
1490 | break; | 1679 | break; |
1491 | case SOC15_IH_CLIENTID_SDMA1: | 1680 | case SOC15_IH_CLIENTID_SDMA1: |
1492 | switch (entry->ring_id) { | 1681 | instance = 1; |
1493 | case 0: | 1682 | break; |
1494 | amdgpu_fence_process(&adev->sdma.instance[1].ring); | 1683 | default: |
1495 | break; | 1684 | return 0; |
1496 | case 1: | 1685 | } |
1497 | /* XXX compute */ | 1686 | |
1498 | break; | 1687 | switch (entry->ring_id) { |
1499 | case 2: | 1688 | case 0: |
1500 | /* XXX compute */ | 1689 | amdgpu_fence_process(&adev->sdma.instance[instance].ring); |
1501 | break; | 1690 | break; |
1502 | case 3: | 1691 | case 1: |
1503 | /* XXX page queue*/ | 1692 | /* XXX compute */ |
1504 | break; | 1693 | break; |
1505 | } | 1694 | case 2: |
1695 | /* XXX compute */ | ||
1696 | break; | ||
1697 | case 3: | ||
1698 | amdgpu_fence_process(&adev->sdma.instance[instance].page); | ||
1506 | break; | 1699 | break; |
1507 | } | 1700 | } |
1508 | return 0; | 1701 | return 0; |
@@ -1512,12 +1705,29 @@ static int sdma_v4_0_process_illegal_inst_irq(struct amdgpu_device *adev, | |||
1512 | struct amdgpu_irq_src *source, | 1705 | struct amdgpu_irq_src *source, |
1513 | struct amdgpu_iv_entry *entry) | 1706 | struct amdgpu_iv_entry *entry) |
1514 | { | 1707 | { |
1708 | int instance; | ||
1709 | |||
1515 | DRM_ERROR("Illegal instruction in SDMA command stream\n"); | 1710 | DRM_ERROR("Illegal instruction in SDMA command stream\n"); |
1516 | schedule_work(&adev->reset_work); | 1711 | |
1712 | switch (entry->client_id) { | ||
1713 | case SOC15_IH_CLIENTID_SDMA0: | ||
1714 | instance = 0; | ||
1715 | break; | ||
1716 | case SOC15_IH_CLIENTID_SDMA1: | ||
1717 | instance = 1; | ||
1718 | break; | ||
1719 | default: | ||
1720 | return 0; | ||
1721 | } | ||
1722 | |||
1723 | switch (entry->ring_id) { | ||
1724 | case 0: | ||
1725 | drm_sched_fault(&adev->sdma.instance[instance].ring.sched); | ||
1726 | break; | ||
1727 | } | ||
1517 | return 0; | 1728 | return 0; |
1518 | } | 1729 | } |
1519 | 1730 | ||
1520 | |||
1521 | static void sdma_v4_0_update_medium_grain_clock_gating( | 1731 | static void sdma_v4_0_update_medium_grain_clock_gating( |
1522 | struct amdgpu_device *adev, | 1732 | struct amdgpu_device *adev, |
1523 | bool enable) | 1733 | bool enable) |
@@ -1730,6 +1940,38 @@ static const struct amdgpu_ring_funcs sdma_v4_0_ring_funcs = { | |||
1730 | .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, | 1940 | .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, |
1731 | }; | 1941 | }; |
1732 | 1942 | ||
1943 | static const struct amdgpu_ring_funcs sdma_v4_0_page_ring_funcs = { | ||
1944 | .type = AMDGPU_RING_TYPE_SDMA, | ||
1945 | .align_mask = 0xf, | ||
1946 | .nop = SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP), | ||
1947 | .support_64bit_ptrs = true, | ||
1948 | .vmhub = AMDGPU_MMHUB, | ||
1949 | .get_rptr = sdma_v4_0_ring_get_rptr, | ||
1950 | .get_wptr = sdma_v4_0_page_ring_get_wptr, | ||
1951 | .set_wptr = sdma_v4_0_page_ring_set_wptr, | ||
1952 | .emit_frame_size = | ||
1953 | 6 + /* sdma_v4_0_ring_emit_hdp_flush */ | ||
1954 | 3 + /* hdp invalidate */ | ||
1955 | 6 + /* sdma_v4_0_ring_emit_pipeline_sync */ | ||
1956 | /* sdma_v4_0_ring_emit_vm_flush */ | ||
1957 | SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 + | ||
1958 | SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 + | ||
1959 | 10 + 10 + 10, /* sdma_v4_0_ring_emit_fence x3 for user fence, vm fence */ | ||
1960 | .emit_ib_size = 7 + 6, /* sdma_v4_0_ring_emit_ib */ | ||
1961 | .emit_ib = sdma_v4_0_ring_emit_ib, | ||
1962 | .emit_fence = sdma_v4_0_ring_emit_fence, | ||
1963 | .emit_pipeline_sync = sdma_v4_0_ring_emit_pipeline_sync, | ||
1964 | .emit_vm_flush = sdma_v4_0_ring_emit_vm_flush, | ||
1965 | .emit_hdp_flush = sdma_v4_0_ring_emit_hdp_flush, | ||
1966 | .test_ring = sdma_v4_0_ring_test_ring, | ||
1967 | .test_ib = sdma_v4_0_ring_test_ib, | ||
1968 | .insert_nop = sdma_v4_0_ring_insert_nop, | ||
1969 | .pad_ib = sdma_v4_0_ring_pad_ib, | ||
1970 | .emit_wreg = sdma_v4_0_ring_emit_wreg, | ||
1971 | .emit_reg_wait = sdma_v4_0_ring_emit_reg_wait, | ||
1972 | .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, | ||
1973 | }; | ||
1974 | |||
1733 | static void sdma_v4_0_set_ring_funcs(struct amdgpu_device *adev) | 1975 | static void sdma_v4_0_set_ring_funcs(struct amdgpu_device *adev) |
1734 | { | 1976 | { |
1735 | int i; | 1977 | int i; |
@@ -1737,6 +1979,10 @@ static void sdma_v4_0_set_ring_funcs(struct amdgpu_device *adev) | |||
1737 | for (i = 0; i < adev->sdma.num_instances; i++) { | 1979 | for (i = 0; i < adev->sdma.num_instances; i++) { |
1738 | adev->sdma.instance[i].ring.funcs = &sdma_v4_0_ring_funcs; | 1980 | adev->sdma.instance[i].ring.funcs = &sdma_v4_0_ring_funcs; |
1739 | adev->sdma.instance[i].ring.me = i; | 1981 | adev->sdma.instance[i].ring.me = i; |
1982 | if (adev->sdma.has_page_queue) { | ||
1983 | adev->sdma.instance[i].page.funcs = &sdma_v4_0_page_ring_funcs; | ||
1984 | adev->sdma.instance[i].page.me = i; | ||
1985 | } | ||
1740 | } | 1986 | } |
1741 | } | 1987 | } |
1742 | 1988 | ||
@@ -1818,7 +2064,10 @@ static const struct amdgpu_buffer_funcs sdma_v4_0_buffer_funcs = { | |||
1818 | static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev) | 2064 | static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev) |
1819 | { | 2065 | { |
1820 | adev->mman.buffer_funcs = &sdma_v4_0_buffer_funcs; | 2066 | adev->mman.buffer_funcs = &sdma_v4_0_buffer_funcs; |
1821 | adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring; | 2067 | if (adev->sdma.has_page_queue) |
2068 | adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].page; | ||
2069 | else | ||
2070 | adev->mman.buffer_funcs_ring = &adev->sdma.instance[0].ring; | ||
1822 | } | 2071 | } |
1823 | 2072 | ||
1824 | static const struct amdgpu_vm_pte_funcs sdma_v4_0_vm_pte_funcs = { | 2073 | static const struct amdgpu_vm_pte_funcs sdma_v4_0_vm_pte_funcs = { |
@@ -1836,7 +2085,10 @@ static void sdma_v4_0_set_vm_pte_funcs(struct amdgpu_device *adev) | |||
1836 | 2085 | ||
1837 | adev->vm_manager.vm_pte_funcs = &sdma_v4_0_vm_pte_funcs; | 2086 | adev->vm_manager.vm_pte_funcs = &sdma_v4_0_vm_pte_funcs; |
1838 | for (i = 0; i < adev->sdma.num_instances; i++) { | 2087 | for (i = 0; i < adev->sdma.num_instances; i++) { |
1839 | sched = &adev->sdma.instance[i].ring.sched; | 2088 | if (adev->sdma.has_page_queue) |
2089 | sched = &adev->sdma.instance[i].page.sched; | ||
2090 | else | ||
2091 | sched = &adev->sdma.instance[i].ring.sched; | ||
1840 | adev->vm_manager.vm_pte_rqs[i] = | 2092 | adev->vm_manager.vm_pte_rqs[i] = |
1841 | &sched->sched_rq[DRM_SCHED_PRIORITY_KERNEL]; | 2093 | &sched->sched_rq[DRM_SCHED_PRIORITY_KERNEL]; |
1842 | } | 2094 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dma.c b/drivers/gpu/drm/amd/amdgpu/si_dma.c index adbaea6da0d7..b6e473134e19 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dma.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dma.c | |||
@@ -61,9 +61,11 @@ static void si_dma_ring_set_wptr(struct amdgpu_ring *ring) | |||
61 | } | 61 | } |
62 | 62 | ||
63 | static void si_dma_ring_emit_ib(struct amdgpu_ring *ring, | 63 | static void si_dma_ring_emit_ib(struct amdgpu_ring *ring, |
64 | struct amdgpu_job *job, | ||
64 | struct amdgpu_ib *ib, | 65 | struct amdgpu_ib *ib, |
65 | unsigned vmid, bool ctx_switch) | 66 | bool ctx_switch) |
66 | { | 67 | { |
68 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
67 | /* The indirect buffer packet must end on an 8 DW boundary in the DMA ring. | 69 | /* The indirect buffer packet must end on an 8 DW boundary in the DMA ring. |
68 | * Pad as necessary with NOPs. | 70 | * Pad as necessary with NOPs. |
69 | */ | 71 | */ |
@@ -122,7 +124,7 @@ static void si_dma_stop(struct amdgpu_device *adev) | |||
122 | 124 | ||
123 | if (adev->mman.buffer_funcs_ring == ring) | 125 | if (adev->mman.buffer_funcs_ring == ring) |
124 | amdgpu_ttm_set_buffer_funcs_status(adev, false); | 126 | amdgpu_ttm_set_buffer_funcs_status(adev, false); |
125 | ring->ready = false; | 127 | ring->sched.ready = false; |
126 | } | 128 | } |
127 | } | 129 | } |
128 | 130 | ||
@@ -175,13 +177,11 @@ static int si_dma_start(struct amdgpu_device *adev) | |||
175 | WREG32(DMA_RB_WPTR + sdma_offsets[i], lower_32_bits(ring->wptr) << 2); | 177 | WREG32(DMA_RB_WPTR + sdma_offsets[i], lower_32_bits(ring->wptr) << 2); |
176 | WREG32(DMA_RB_CNTL + sdma_offsets[i], rb_cntl | DMA_RB_ENABLE); | 178 | WREG32(DMA_RB_CNTL + sdma_offsets[i], rb_cntl | DMA_RB_ENABLE); |
177 | 179 | ||
178 | ring->ready = true; | 180 | ring->sched.ready = true; |
179 | 181 | ||
180 | r = amdgpu_ring_test_ring(ring); | 182 | r = amdgpu_ring_test_helper(ring); |
181 | if (r) { | 183 | if (r) |
182 | ring->ready = false; | ||
183 | return r; | 184 | return r; |
184 | } | ||
185 | 185 | ||
186 | if (adev->mman.buffer_funcs_ring == ring) | 186 | if (adev->mman.buffer_funcs_ring == ring) |
187 | amdgpu_ttm_set_buffer_funcs_status(adev, true); | 187 | amdgpu_ttm_set_buffer_funcs_status(adev, true); |
@@ -209,21 +209,16 @@ static int si_dma_ring_test_ring(struct amdgpu_ring *ring) | |||
209 | u64 gpu_addr; | 209 | u64 gpu_addr; |
210 | 210 | ||
211 | r = amdgpu_device_wb_get(adev, &index); | 211 | r = amdgpu_device_wb_get(adev, &index); |
212 | if (r) { | 212 | if (r) |
213 | dev_err(adev->dev, "(%d) failed to allocate wb slot\n", r); | ||
214 | return r; | 213 | return r; |
215 | } | ||
216 | 214 | ||
217 | gpu_addr = adev->wb.gpu_addr + (index * 4); | 215 | gpu_addr = adev->wb.gpu_addr + (index * 4); |
218 | tmp = 0xCAFEDEAD; | 216 | tmp = 0xCAFEDEAD; |
219 | adev->wb.wb[index] = cpu_to_le32(tmp); | 217 | adev->wb.wb[index] = cpu_to_le32(tmp); |
220 | 218 | ||
221 | r = amdgpu_ring_alloc(ring, 4); | 219 | r = amdgpu_ring_alloc(ring, 4); |
222 | if (r) { | 220 | if (r) |
223 | DRM_ERROR("amdgpu: dma failed to lock ring %d (%d).\n", ring->idx, r); | 221 | goto error_free_wb; |
224 | amdgpu_device_wb_free(adev, index); | ||
225 | return r; | ||
226 | } | ||
227 | 222 | ||
228 | amdgpu_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 0, 1)); | 223 | amdgpu_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 0, 1)); |
229 | amdgpu_ring_write(ring, lower_32_bits(gpu_addr)); | 224 | amdgpu_ring_write(ring, lower_32_bits(gpu_addr)); |
@@ -238,15 +233,11 @@ static int si_dma_ring_test_ring(struct amdgpu_ring *ring) | |||
238 | DRM_UDELAY(1); | 233 | DRM_UDELAY(1); |
239 | } | 234 | } |
240 | 235 | ||
241 | if (i < adev->usec_timeout) { | 236 | if (i >= adev->usec_timeout) |
242 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", ring->idx, i); | 237 | r = -ETIMEDOUT; |
243 | } else { | ||
244 | DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", | ||
245 | ring->idx, tmp); | ||
246 | r = -EINVAL; | ||
247 | } | ||
248 | amdgpu_device_wb_free(adev, index); | ||
249 | 238 | ||
239 | error_free_wb: | ||
240 | amdgpu_device_wb_free(adev, index); | ||
250 | return r; | 241 | return r; |
251 | } | 242 | } |
252 | 243 | ||
@@ -269,20 +260,16 @@ static int si_dma_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
269 | long r; | 260 | long r; |
270 | 261 | ||
271 | r = amdgpu_device_wb_get(adev, &index); | 262 | r = amdgpu_device_wb_get(adev, &index); |
272 | if (r) { | 263 | if (r) |
273 | dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r); | ||
274 | return r; | 264 | return r; |
275 | } | ||
276 | 265 | ||
277 | gpu_addr = adev->wb.gpu_addr + (index * 4); | 266 | gpu_addr = adev->wb.gpu_addr + (index * 4); |
278 | tmp = 0xCAFEDEAD; | 267 | tmp = 0xCAFEDEAD; |
279 | adev->wb.wb[index] = cpu_to_le32(tmp); | 268 | adev->wb.wb[index] = cpu_to_le32(tmp); |
280 | memset(&ib, 0, sizeof(ib)); | 269 | memset(&ib, 0, sizeof(ib)); |
281 | r = amdgpu_ib_get(adev, NULL, 256, &ib); | 270 | r = amdgpu_ib_get(adev, NULL, 256, &ib); |
282 | if (r) { | 271 | if (r) |
283 | DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r); | ||
284 | goto err0; | 272 | goto err0; |
285 | } | ||
286 | 273 | ||
287 | ib.ptr[0] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 0, 1); | 274 | ib.ptr[0] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 0, 1); |
288 | ib.ptr[1] = lower_32_bits(gpu_addr); | 275 | ib.ptr[1] = lower_32_bits(gpu_addr); |
@@ -295,21 +282,16 @@ static int si_dma_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
295 | 282 | ||
296 | r = dma_fence_wait_timeout(f, false, timeout); | 283 | r = dma_fence_wait_timeout(f, false, timeout); |
297 | if (r == 0) { | 284 | if (r == 0) { |
298 | DRM_ERROR("amdgpu: IB test timed out\n"); | ||
299 | r = -ETIMEDOUT; | 285 | r = -ETIMEDOUT; |
300 | goto err1; | 286 | goto err1; |
301 | } else if (r < 0) { | 287 | } else if (r < 0) { |
302 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | ||
303 | goto err1; | 288 | goto err1; |
304 | } | 289 | } |
305 | tmp = le32_to_cpu(adev->wb.wb[index]); | 290 | tmp = le32_to_cpu(adev->wb.wb[index]); |
306 | if (tmp == 0xDEADBEEF) { | 291 | if (tmp == 0xDEADBEEF) |
307 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | ||
308 | r = 0; | 292 | r = 0; |
309 | } else { | 293 | else |
310 | DRM_ERROR("amdgpu: ib test failed (0x%08X)\n", tmp); | ||
311 | r = -EINVAL; | 294 | r = -EINVAL; |
312 | } | ||
313 | 295 | ||
314 | err1: | 296 | err1: |
315 | amdgpu_ib_free(adev, &ib, NULL); | 297 | amdgpu_ib_free(adev, &ib, NULL); |
@@ -658,15 +640,6 @@ static int si_dma_process_trap_irq(struct amdgpu_device *adev, | |||
658 | return 0; | 640 | return 0; |
659 | } | 641 | } |
660 | 642 | ||
661 | static int si_dma_process_illegal_inst_irq(struct amdgpu_device *adev, | ||
662 | struct amdgpu_irq_src *source, | ||
663 | struct amdgpu_iv_entry *entry) | ||
664 | { | ||
665 | DRM_ERROR("Illegal instruction in SDMA command stream\n"); | ||
666 | schedule_work(&adev->reset_work); | ||
667 | return 0; | ||
668 | } | ||
669 | |||
670 | static int si_dma_set_clockgating_state(void *handle, | 643 | static int si_dma_set_clockgating_state(void *handle, |
671 | enum amd_clockgating_state state) | 644 | enum amd_clockgating_state state) |
672 | { | 645 | { |
@@ -781,15 +754,10 @@ static const struct amdgpu_irq_src_funcs si_dma_trap_irq_funcs = { | |||
781 | .process = si_dma_process_trap_irq, | 754 | .process = si_dma_process_trap_irq, |
782 | }; | 755 | }; |
783 | 756 | ||
784 | static const struct amdgpu_irq_src_funcs si_dma_illegal_inst_irq_funcs = { | ||
785 | .process = si_dma_process_illegal_inst_irq, | ||
786 | }; | ||
787 | |||
788 | static void si_dma_set_irq_funcs(struct amdgpu_device *adev) | 757 | static void si_dma_set_irq_funcs(struct amdgpu_device *adev) |
789 | { | 758 | { |
790 | adev->sdma.trap_irq.num_types = AMDGPU_SDMA_IRQ_LAST; | 759 | adev->sdma.trap_irq.num_types = AMDGPU_SDMA_IRQ_LAST; |
791 | adev->sdma.trap_irq.funcs = &si_dma_trap_irq_funcs; | 760 | adev->sdma.trap_irq.funcs = &si_dma_trap_irq_funcs; |
792 | adev->sdma.illegal_inst_irq.funcs = &si_dma_illegal_inst_irq_funcs; | ||
793 | } | 761 | } |
794 | 762 | ||
795 | /** | 763 | /** |
diff --git a/drivers/gpu/drm/amd/amdgpu/ta_xgmi_if.h b/drivers/gpu/drm/amd/amdgpu/ta_xgmi_if.h new file mode 100644 index 000000000000..ac2c27b7630c --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/ta_xgmi_if.h | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | * Copyright 2018 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #ifndef _TA_XGMI_IF_H | ||
25 | #define _TA_XGMI_IF_H | ||
26 | |||
27 | /* Responses have bit 31 set */ | ||
28 | #define RSP_ID_MASK (1U << 31) | ||
29 | #define RSP_ID(cmdId) (((uint32_t)(cmdId)) | RSP_ID_MASK) | ||
30 | |||
31 | enum ta_command_xgmi { | ||
32 | TA_COMMAND_XGMI__INITIALIZE = 0x00, | ||
33 | TA_COMMAND_XGMI__GET_NODE_ID = 0x01, | ||
34 | TA_COMMAND_XGMI__GET_HIVE_ID = 0x02, | ||
35 | TA_COMMAND_XGMI__GET_GET_TOPOLOGY_INFO = 0x03, | ||
36 | TA_COMMAND_XGMI__SET_TOPOLOGY_INFO = 0x04 | ||
37 | }; | ||
38 | |||
39 | /* XGMI related enumerations */ | ||
40 | /**********************************************************/; | ||
41 | enum ta_xgmi_connected_nodes { | ||
42 | TA_XGMI__MAX_CONNECTED_NODES = 64 | ||
43 | }; | ||
44 | |||
45 | enum ta_xgmi_status { | ||
46 | TA_XGMI_STATUS__SUCCESS = 0x00, | ||
47 | TA_XGMI_STATUS__GENERIC_FAILURE = 0x01, | ||
48 | TA_XGMI_STATUS__NULL_POINTER = 0x02, | ||
49 | TA_XGMI_STATUS__INVALID_PARAMETER = 0x03, | ||
50 | TA_XGMI_STATUS__NOT_INITIALIZED = 0x04, | ||
51 | TA_XGMI_STATUS__INVALID_NODE_NUM = 0x05, | ||
52 | TA_XGMI_STATUS__INVALID_NODE_ID = 0x06, | ||
53 | TA_XGMI_STATUS__INVALID_TOPOLOGY = 0x07, | ||
54 | TA_XGMI_STATUS__FAILED_ID_GEN = 0x08, | ||
55 | TA_XGMI_STATUS__FAILED_TOPOLOGY_INIT = 0x09, | ||
56 | TA_XGMI_STATUS__SET_SHARING_ERROR = 0x0A | ||
57 | }; | ||
58 | |||
59 | enum ta_xgmi_assigned_sdma_engine { | ||
60 | TA_XGMI_ASSIGNED_SDMA_ENGINE__NOT_ASSIGNED = -1, | ||
61 | TA_XGMI_ASSIGNED_SDMA_ENGINE__SDMA0 = 0, | ||
62 | TA_XGMI_ASSIGNED_SDMA_ENGINE__SDMA1 = 1, | ||
63 | TA_XGMI_ASSIGNED_SDMA_ENGINE__SDMA2 = 2, | ||
64 | TA_XGMI_ASSIGNED_SDMA_ENGINE__SDMA3 = 3, | ||
65 | TA_XGMI_ASSIGNED_SDMA_ENGINE__SDMA4 = 4, | ||
66 | TA_XGMI_ASSIGNED_SDMA_ENGINE__SDMA5 = 5 | ||
67 | }; | ||
68 | |||
69 | /* input/output structures for XGMI commands */ | ||
70 | /**********************************************************/ | ||
71 | struct ta_xgmi_node_info { | ||
72 | uint64_t node_id; | ||
73 | uint8_t num_hops; | ||
74 | uint8_t is_sharing_enabled; | ||
75 | enum ta_xgmi_assigned_sdma_engine sdma_engine; | ||
76 | }; | ||
77 | |||
78 | struct ta_xgmi_cmd_initialize_output { | ||
79 | uint32_t status; | ||
80 | }; | ||
81 | |||
82 | struct ta_xgmi_cmd_get_node_id_output { | ||
83 | uint64_t node_id; | ||
84 | }; | ||
85 | |||
86 | struct ta_xgmi_cmd_get_hive_id_output { | ||
87 | uint64_t hive_id; | ||
88 | }; | ||
89 | |||
90 | struct ta_xgmi_cmd_get_topology_info_input { | ||
91 | uint32_t num_nodes; | ||
92 | struct ta_xgmi_node_info nodes[TA_XGMI__MAX_CONNECTED_NODES]; | ||
93 | }; | ||
94 | |||
95 | struct ta_xgmi_cmd_get_topology_info_output { | ||
96 | uint32_t num_nodes; | ||
97 | struct ta_xgmi_node_info nodes[TA_XGMI__MAX_CONNECTED_NODES]; | ||
98 | }; | ||
99 | |||
100 | struct ta_xgmi_cmd_set_topology_info_input { | ||
101 | uint32_t num_nodes; | ||
102 | struct ta_xgmi_node_info nodes[TA_XGMI__MAX_CONNECTED_NODES]; | ||
103 | }; | ||
104 | |||
105 | /**********************************************************/ | ||
106 | /* Common input structure for XGMI callbacks */ | ||
107 | union ta_xgmi_cmd_input { | ||
108 | struct ta_xgmi_cmd_get_topology_info_input get_topology_info; | ||
109 | struct ta_xgmi_cmd_set_topology_info_input set_topology_info; | ||
110 | }; | ||
111 | |||
112 | /* Common output structure for XGMI callbacks */ | ||
113 | union ta_xgmi_cmd_output { | ||
114 | struct ta_xgmi_cmd_initialize_output initialize; | ||
115 | struct ta_xgmi_cmd_get_node_id_output get_node_id; | ||
116 | struct ta_xgmi_cmd_get_hive_id_output get_hive_id; | ||
117 | struct ta_xgmi_cmd_get_topology_info_output get_topology_info; | ||
118 | }; | ||
119 | /**********************************************************/ | ||
120 | |||
121 | struct ta_xgmi_shared_memory { | ||
122 | uint32_t cmd_id; | ||
123 | uint32_t resp_id; | ||
124 | enum ta_xgmi_status xgmi_status; | ||
125 | uint32_t reserved; | ||
126 | union ta_xgmi_cmd_input xgmi_in_message; | ||
127 | union ta_xgmi_cmd_output xgmi_out_message; | ||
128 | }; | ||
129 | |||
130 | #endif //_TA_XGMI_IF_H | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c index 1fc17bf39fed..90bbcee00f28 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | |||
@@ -162,12 +162,9 @@ static int uvd_v4_2_hw_init(void *handle) | |||
162 | uvd_v4_2_enable_mgcg(adev, true); | 162 | uvd_v4_2_enable_mgcg(adev, true); |
163 | amdgpu_asic_set_uvd_clocks(adev, 10000, 10000); | 163 | amdgpu_asic_set_uvd_clocks(adev, 10000, 10000); |
164 | 164 | ||
165 | ring->ready = true; | 165 | r = amdgpu_ring_test_helper(ring); |
166 | r = amdgpu_ring_test_ring(ring); | 166 | if (r) |
167 | if (r) { | ||
168 | ring->ready = false; | ||
169 | goto done; | 167 | goto done; |
170 | } | ||
171 | 168 | ||
172 | r = amdgpu_ring_alloc(ring, 10); | 169 | r = amdgpu_ring_alloc(ring, 10); |
173 | if (r) { | 170 | if (r) { |
@@ -218,7 +215,7 @@ static int uvd_v4_2_hw_fini(void *handle) | |||
218 | if (RREG32(mmUVD_STATUS) != 0) | 215 | if (RREG32(mmUVD_STATUS) != 0) |
219 | uvd_v4_2_stop(adev); | 216 | uvd_v4_2_stop(adev); |
220 | 217 | ||
221 | ring->ready = false; | 218 | ring->sched.ready = false; |
222 | 219 | ||
223 | return 0; | 220 | return 0; |
224 | } | 221 | } |
@@ -484,11 +481,9 @@ static int uvd_v4_2_ring_test_ring(struct amdgpu_ring *ring) | |||
484 | 481 | ||
485 | WREG32(mmUVD_CONTEXT_ID, 0xCAFEDEAD); | 482 | WREG32(mmUVD_CONTEXT_ID, 0xCAFEDEAD); |
486 | r = amdgpu_ring_alloc(ring, 3); | 483 | r = amdgpu_ring_alloc(ring, 3); |
487 | if (r) { | 484 | if (r) |
488 | DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", | ||
489 | ring->idx, r); | ||
490 | return r; | 485 | return r; |
491 | } | 486 | |
492 | amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0)); | 487 | amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0)); |
493 | amdgpu_ring_write(ring, 0xDEADBEEF); | 488 | amdgpu_ring_write(ring, 0xDEADBEEF); |
494 | amdgpu_ring_commit(ring); | 489 | amdgpu_ring_commit(ring); |
@@ -499,14 +494,9 @@ static int uvd_v4_2_ring_test_ring(struct amdgpu_ring *ring) | |||
499 | DRM_UDELAY(1); | 494 | DRM_UDELAY(1); |
500 | } | 495 | } |
501 | 496 | ||
502 | if (i < adev->usec_timeout) { | 497 | if (i >= adev->usec_timeout) |
503 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", | 498 | r = -ETIMEDOUT; |
504 | ring->idx, i); | 499 | |
505 | } else { | ||
506 | DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", | ||
507 | ring->idx, tmp); | ||
508 | r = -EINVAL; | ||
509 | } | ||
510 | return r; | 500 | return r; |
511 | } | 501 | } |
512 | 502 | ||
@@ -519,8 +509,9 @@ static int uvd_v4_2_ring_test_ring(struct amdgpu_ring *ring) | |||
519 | * Write ring commands to execute the indirect buffer | 509 | * Write ring commands to execute the indirect buffer |
520 | */ | 510 | */ |
521 | static void uvd_v4_2_ring_emit_ib(struct amdgpu_ring *ring, | 511 | static void uvd_v4_2_ring_emit_ib(struct amdgpu_ring *ring, |
512 | struct amdgpu_job *job, | ||
522 | struct amdgpu_ib *ib, | 513 | struct amdgpu_ib *ib, |
523 | unsigned vmid, bool ctx_switch) | 514 | bool ctx_switch) |
524 | { | 515 | { |
525 | amdgpu_ring_write(ring, PACKET0(mmUVD_RBC_IB_BASE, 0)); | 516 | amdgpu_ring_write(ring, PACKET0(mmUVD_RBC_IB_BASE, 0)); |
526 | amdgpu_ring_write(ring, ib->gpu_addr); | 517 | amdgpu_ring_write(ring, ib->gpu_addr); |
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c index fde6ad5ac9ab..1c5e12703103 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | |||
@@ -158,12 +158,9 @@ static int uvd_v5_0_hw_init(void *handle) | |||
158 | uvd_v5_0_set_clockgating_state(adev, AMD_CG_STATE_UNGATE); | 158 | uvd_v5_0_set_clockgating_state(adev, AMD_CG_STATE_UNGATE); |
159 | uvd_v5_0_enable_mgcg(adev, true); | 159 | uvd_v5_0_enable_mgcg(adev, true); |
160 | 160 | ||
161 | ring->ready = true; | 161 | r = amdgpu_ring_test_helper(ring); |
162 | r = amdgpu_ring_test_ring(ring); | 162 | if (r) |
163 | if (r) { | ||
164 | ring->ready = false; | ||
165 | goto done; | 163 | goto done; |
166 | } | ||
167 | 164 | ||
168 | r = amdgpu_ring_alloc(ring, 10); | 165 | r = amdgpu_ring_alloc(ring, 10); |
169 | if (r) { | 166 | if (r) { |
@@ -215,7 +212,7 @@ static int uvd_v5_0_hw_fini(void *handle) | |||
215 | if (RREG32(mmUVD_STATUS) != 0) | 212 | if (RREG32(mmUVD_STATUS) != 0) |
216 | uvd_v5_0_stop(adev); | 213 | uvd_v5_0_stop(adev); |
217 | 214 | ||
218 | ring->ready = false; | 215 | ring->sched.ready = false; |
219 | 216 | ||
220 | return 0; | 217 | return 0; |
221 | } | 218 | } |
@@ -500,11 +497,8 @@ static int uvd_v5_0_ring_test_ring(struct amdgpu_ring *ring) | |||
500 | 497 | ||
501 | WREG32(mmUVD_CONTEXT_ID, 0xCAFEDEAD); | 498 | WREG32(mmUVD_CONTEXT_ID, 0xCAFEDEAD); |
502 | r = amdgpu_ring_alloc(ring, 3); | 499 | r = amdgpu_ring_alloc(ring, 3); |
503 | if (r) { | 500 | if (r) |
504 | DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", | ||
505 | ring->idx, r); | ||
506 | return r; | 501 | return r; |
507 | } | ||
508 | amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0)); | 502 | amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0)); |
509 | amdgpu_ring_write(ring, 0xDEADBEEF); | 503 | amdgpu_ring_write(ring, 0xDEADBEEF); |
510 | amdgpu_ring_commit(ring); | 504 | amdgpu_ring_commit(ring); |
@@ -515,14 +509,9 @@ static int uvd_v5_0_ring_test_ring(struct amdgpu_ring *ring) | |||
515 | DRM_UDELAY(1); | 509 | DRM_UDELAY(1); |
516 | } | 510 | } |
517 | 511 | ||
518 | if (i < adev->usec_timeout) { | 512 | if (i >= adev->usec_timeout) |
519 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", | 513 | r = -ETIMEDOUT; |
520 | ring->idx, i); | 514 | |
521 | } else { | ||
522 | DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", | ||
523 | ring->idx, tmp); | ||
524 | r = -EINVAL; | ||
525 | } | ||
526 | return r; | 515 | return r; |
527 | } | 516 | } |
528 | 517 | ||
@@ -535,8 +524,9 @@ static int uvd_v5_0_ring_test_ring(struct amdgpu_ring *ring) | |||
535 | * Write ring commands to execute the indirect buffer | 524 | * Write ring commands to execute the indirect buffer |
536 | */ | 525 | */ |
537 | static void uvd_v5_0_ring_emit_ib(struct amdgpu_ring *ring, | 526 | static void uvd_v5_0_ring_emit_ib(struct amdgpu_ring *ring, |
527 | struct amdgpu_job *job, | ||
538 | struct amdgpu_ib *ib, | 528 | struct amdgpu_ib *ib, |
539 | unsigned vmid, bool ctx_switch) | 529 | bool ctx_switch) |
540 | { | 530 | { |
541 | amdgpu_ring_write(ring, PACKET0(mmUVD_LMI_RBC_IB_64BIT_BAR_LOW, 0)); | 531 | amdgpu_ring_write(ring, PACKET0(mmUVD_LMI_RBC_IB_64BIT_BAR_LOW, 0)); |
542 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); | 532 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); |
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 7a5b40275e8e..f184842ef2a2 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | |||
@@ -175,11 +175,8 @@ static int uvd_v6_0_enc_ring_test_ring(struct amdgpu_ring *ring) | |||
175 | int r; | 175 | int r; |
176 | 176 | ||
177 | r = amdgpu_ring_alloc(ring, 16); | 177 | r = amdgpu_ring_alloc(ring, 16); |
178 | if (r) { | 178 | if (r) |
179 | DRM_ERROR("amdgpu: uvd enc failed to lock ring %d (%d).\n", | ||
180 | ring->idx, r); | ||
181 | return r; | 179 | return r; |
182 | } | ||
183 | amdgpu_ring_write(ring, HEVC_ENC_CMD_END); | 180 | amdgpu_ring_write(ring, HEVC_ENC_CMD_END); |
184 | amdgpu_ring_commit(ring); | 181 | amdgpu_ring_commit(ring); |
185 | 182 | ||
@@ -189,14 +186,8 @@ static int uvd_v6_0_enc_ring_test_ring(struct amdgpu_ring *ring) | |||
189 | DRM_UDELAY(1); | 186 | DRM_UDELAY(1); |
190 | } | 187 | } |
191 | 188 | ||
192 | if (i < adev->usec_timeout) { | 189 | if (i >= adev->usec_timeout) |
193 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", | ||
194 | ring->idx, i); | ||
195 | } else { | ||
196 | DRM_ERROR("amdgpu: ring %d test failed\n", | ||
197 | ring->idx); | ||
198 | r = -ETIMEDOUT; | 190 | r = -ETIMEDOUT; |
199 | } | ||
200 | 191 | ||
201 | return r; | 192 | return r; |
202 | } | 193 | } |
@@ -336,31 +327,24 @@ static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
336 | long r; | 327 | long r; |
337 | 328 | ||
338 | r = uvd_v6_0_enc_get_create_msg(ring, 1, NULL); | 329 | r = uvd_v6_0_enc_get_create_msg(ring, 1, NULL); |
339 | if (r) { | 330 | if (r) |
340 | DRM_ERROR("amdgpu: failed to get create msg (%ld).\n", r); | ||
341 | goto error; | 331 | goto error; |
342 | } | ||
343 | 332 | ||
344 | r = uvd_v6_0_enc_get_destroy_msg(ring, 1, &fence); | 333 | r = uvd_v6_0_enc_get_destroy_msg(ring, 1, &fence); |
345 | if (r) { | 334 | if (r) |
346 | DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r); | ||
347 | goto error; | 335 | goto error; |
348 | } | ||
349 | 336 | ||
350 | r = dma_fence_wait_timeout(fence, false, timeout); | 337 | r = dma_fence_wait_timeout(fence, false, timeout); |
351 | if (r == 0) { | 338 | if (r == 0) |
352 | DRM_ERROR("amdgpu: IB test timed out.\n"); | ||
353 | r = -ETIMEDOUT; | 339 | r = -ETIMEDOUT; |
354 | } else if (r < 0) { | 340 | else if (r > 0) |
355 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | ||
356 | } else { | ||
357 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | ||
358 | r = 0; | 341 | r = 0; |
359 | } | 342 | |
360 | error: | 343 | error: |
361 | dma_fence_put(fence); | 344 | dma_fence_put(fence); |
362 | return r; | 345 | return r; |
363 | } | 346 | } |
347 | |||
364 | static int uvd_v6_0_early_init(void *handle) | 348 | static int uvd_v6_0_early_init(void *handle) |
365 | { | 349 | { |
366 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 350 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
@@ -476,12 +460,9 @@ static int uvd_v6_0_hw_init(void *handle) | |||
476 | uvd_v6_0_set_clockgating_state(adev, AMD_CG_STATE_UNGATE); | 460 | uvd_v6_0_set_clockgating_state(adev, AMD_CG_STATE_UNGATE); |
477 | uvd_v6_0_enable_mgcg(adev, true); | 461 | uvd_v6_0_enable_mgcg(adev, true); |
478 | 462 | ||
479 | ring->ready = true; | 463 | r = amdgpu_ring_test_helper(ring); |
480 | r = amdgpu_ring_test_ring(ring); | 464 | if (r) |
481 | if (r) { | ||
482 | ring->ready = false; | ||
483 | goto done; | 465 | goto done; |
484 | } | ||
485 | 466 | ||
486 | r = amdgpu_ring_alloc(ring, 10); | 467 | r = amdgpu_ring_alloc(ring, 10); |
487 | if (r) { | 468 | if (r) { |
@@ -513,12 +494,9 @@ static int uvd_v6_0_hw_init(void *handle) | |||
513 | if (uvd_v6_0_enc_support(adev)) { | 494 | if (uvd_v6_0_enc_support(adev)) { |
514 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | 495 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { |
515 | ring = &adev->uvd.inst->ring_enc[i]; | 496 | ring = &adev->uvd.inst->ring_enc[i]; |
516 | ring->ready = true; | 497 | r = amdgpu_ring_test_helper(ring); |
517 | r = amdgpu_ring_test_ring(ring); | 498 | if (r) |
518 | if (r) { | ||
519 | ring->ready = false; | ||
520 | goto done; | 499 | goto done; |
521 | } | ||
522 | } | 500 | } |
523 | } | 501 | } |
524 | 502 | ||
@@ -548,7 +526,7 @@ static int uvd_v6_0_hw_fini(void *handle) | |||
548 | if (RREG32(mmUVD_STATUS) != 0) | 526 | if (RREG32(mmUVD_STATUS) != 0) |
549 | uvd_v6_0_stop(adev); | 527 | uvd_v6_0_stop(adev); |
550 | 528 | ||
551 | ring->ready = false; | 529 | ring->sched.ready = false; |
552 | 530 | ||
553 | return 0; | 531 | return 0; |
554 | } | 532 | } |
@@ -969,11 +947,9 @@ static int uvd_v6_0_ring_test_ring(struct amdgpu_ring *ring) | |||
969 | 947 | ||
970 | WREG32(mmUVD_CONTEXT_ID, 0xCAFEDEAD); | 948 | WREG32(mmUVD_CONTEXT_ID, 0xCAFEDEAD); |
971 | r = amdgpu_ring_alloc(ring, 3); | 949 | r = amdgpu_ring_alloc(ring, 3); |
972 | if (r) { | 950 | if (r) |
973 | DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", | ||
974 | ring->idx, r); | ||
975 | return r; | 951 | return r; |
976 | } | 952 | |
977 | amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0)); | 953 | amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0)); |
978 | amdgpu_ring_write(ring, 0xDEADBEEF); | 954 | amdgpu_ring_write(ring, 0xDEADBEEF); |
979 | amdgpu_ring_commit(ring); | 955 | amdgpu_ring_commit(ring); |
@@ -984,14 +960,9 @@ static int uvd_v6_0_ring_test_ring(struct amdgpu_ring *ring) | |||
984 | DRM_UDELAY(1); | 960 | DRM_UDELAY(1); |
985 | } | 961 | } |
986 | 962 | ||
987 | if (i < adev->usec_timeout) { | 963 | if (i >= adev->usec_timeout) |
988 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", | 964 | r = -ETIMEDOUT; |
989 | ring->idx, i); | 965 | |
990 | } else { | ||
991 | DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", | ||
992 | ring->idx, tmp); | ||
993 | r = -EINVAL; | ||
994 | } | ||
995 | return r; | 966 | return r; |
996 | } | 967 | } |
997 | 968 | ||
@@ -1004,9 +975,12 @@ static int uvd_v6_0_ring_test_ring(struct amdgpu_ring *ring) | |||
1004 | * Write ring commands to execute the indirect buffer | 975 | * Write ring commands to execute the indirect buffer |
1005 | */ | 976 | */ |
1006 | static void uvd_v6_0_ring_emit_ib(struct amdgpu_ring *ring, | 977 | static void uvd_v6_0_ring_emit_ib(struct amdgpu_ring *ring, |
978 | struct amdgpu_job *job, | ||
1007 | struct amdgpu_ib *ib, | 979 | struct amdgpu_ib *ib, |
1008 | unsigned vmid, bool ctx_switch) | 980 | bool ctx_switch) |
1009 | { | 981 | { |
982 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
983 | |||
1010 | amdgpu_ring_write(ring, PACKET0(mmUVD_LMI_RBC_IB_VMID, 0)); | 984 | amdgpu_ring_write(ring, PACKET0(mmUVD_LMI_RBC_IB_VMID, 0)); |
1011 | amdgpu_ring_write(ring, vmid); | 985 | amdgpu_ring_write(ring, vmid); |
1012 | 986 | ||
@@ -1027,8 +1001,12 @@ static void uvd_v6_0_ring_emit_ib(struct amdgpu_ring *ring, | |||
1027 | * Write enc ring commands to execute the indirect buffer | 1001 | * Write enc ring commands to execute the indirect buffer |
1028 | */ | 1002 | */ |
1029 | static void uvd_v6_0_enc_ring_emit_ib(struct amdgpu_ring *ring, | 1003 | static void uvd_v6_0_enc_ring_emit_ib(struct amdgpu_ring *ring, |
1030 | struct amdgpu_ib *ib, unsigned int vmid, bool ctx_switch) | 1004 | struct amdgpu_job *job, |
1005 | struct amdgpu_ib *ib, | ||
1006 | bool ctx_switch) | ||
1031 | { | 1007 | { |
1008 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
1009 | |||
1032 | amdgpu_ring_write(ring, HEVC_ENC_CMD_IB_VM); | 1010 | amdgpu_ring_write(ring, HEVC_ENC_CMD_IB_VM); |
1033 | amdgpu_ring_write(ring, vmid); | 1011 | amdgpu_ring_write(ring, vmid); |
1034 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); | 1012 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); |
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index 58b39afcfb86..8a4595968d98 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | |||
@@ -183,11 +183,8 @@ static int uvd_v7_0_enc_ring_test_ring(struct amdgpu_ring *ring) | |||
183 | return 0; | 183 | return 0; |
184 | 184 | ||
185 | r = amdgpu_ring_alloc(ring, 16); | 185 | r = amdgpu_ring_alloc(ring, 16); |
186 | if (r) { | 186 | if (r) |
187 | DRM_ERROR("amdgpu: uvd enc failed to lock (%d)ring %d (%d).\n", | ||
188 | ring->me, ring->idx, r); | ||
189 | return r; | 187 | return r; |
190 | } | ||
191 | amdgpu_ring_write(ring, HEVC_ENC_CMD_END); | 188 | amdgpu_ring_write(ring, HEVC_ENC_CMD_END); |
192 | amdgpu_ring_commit(ring); | 189 | amdgpu_ring_commit(ring); |
193 | 190 | ||
@@ -197,14 +194,8 @@ static int uvd_v7_0_enc_ring_test_ring(struct amdgpu_ring *ring) | |||
197 | DRM_UDELAY(1); | 194 | DRM_UDELAY(1); |
198 | } | 195 | } |
199 | 196 | ||
200 | if (i < adev->usec_timeout) { | 197 | if (i >= adev->usec_timeout) |
201 | DRM_DEBUG("(%d)ring test on %d succeeded in %d usecs\n", | ||
202 | ring->me, ring->idx, i); | ||
203 | } else { | ||
204 | DRM_ERROR("amdgpu: (%d)ring %d test failed\n", | ||
205 | ring->me, ring->idx); | ||
206 | r = -ETIMEDOUT; | 198 | r = -ETIMEDOUT; |
207 | } | ||
208 | 199 | ||
209 | return r; | 200 | return r; |
210 | } | 201 | } |
@@ -343,27 +334,19 @@ static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
343 | long r; | 334 | long r; |
344 | 335 | ||
345 | r = uvd_v7_0_enc_get_create_msg(ring, 1, NULL); | 336 | r = uvd_v7_0_enc_get_create_msg(ring, 1, NULL); |
346 | if (r) { | 337 | if (r) |
347 | DRM_ERROR("amdgpu: (%d)failed to get create msg (%ld).\n", ring->me, r); | ||
348 | goto error; | 338 | goto error; |
349 | } | ||
350 | 339 | ||
351 | r = uvd_v7_0_enc_get_destroy_msg(ring, 1, &fence); | 340 | r = uvd_v7_0_enc_get_destroy_msg(ring, 1, &fence); |
352 | if (r) { | 341 | if (r) |
353 | DRM_ERROR("amdgpu: (%d)failed to get destroy ib (%ld).\n", ring->me, r); | ||
354 | goto error; | 342 | goto error; |
355 | } | ||
356 | 343 | ||
357 | r = dma_fence_wait_timeout(fence, false, timeout); | 344 | r = dma_fence_wait_timeout(fence, false, timeout); |
358 | if (r == 0) { | 345 | if (r == 0) |
359 | DRM_ERROR("amdgpu: (%d)IB test timed out.\n", ring->me); | ||
360 | r = -ETIMEDOUT; | 346 | r = -ETIMEDOUT; |
361 | } else if (r < 0) { | 347 | else if (r > 0) |
362 | DRM_ERROR("amdgpu: (%d)fence wait failed (%ld).\n", ring->me, r); | ||
363 | } else { | ||
364 | DRM_DEBUG("ib test on (%d)ring %d succeeded\n", ring->me, ring->idx); | ||
365 | r = 0; | 348 | r = 0; |
366 | } | 349 | |
367 | error: | 350 | error: |
368 | dma_fence_put(fence); | 351 | dma_fence_put(fence); |
369 | return r; | 352 | return r; |
@@ -540,12 +523,9 @@ static int uvd_v7_0_hw_init(void *handle) | |||
540 | ring = &adev->uvd.inst[j].ring; | 523 | ring = &adev->uvd.inst[j].ring; |
541 | 524 | ||
542 | if (!amdgpu_sriov_vf(adev)) { | 525 | if (!amdgpu_sriov_vf(adev)) { |
543 | ring->ready = true; | 526 | r = amdgpu_ring_test_helper(ring); |
544 | r = amdgpu_ring_test_ring(ring); | 527 | if (r) |
545 | if (r) { | ||
546 | ring->ready = false; | ||
547 | goto done; | 528 | goto done; |
548 | } | ||
549 | 529 | ||
550 | r = amdgpu_ring_alloc(ring, 10); | 530 | r = amdgpu_ring_alloc(ring, 10); |
551 | if (r) { | 531 | if (r) { |
@@ -582,12 +562,9 @@ static int uvd_v7_0_hw_init(void *handle) | |||
582 | 562 | ||
583 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | 563 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { |
584 | ring = &adev->uvd.inst[j].ring_enc[i]; | 564 | ring = &adev->uvd.inst[j].ring_enc[i]; |
585 | ring->ready = true; | 565 | r = amdgpu_ring_test_helper(ring); |
586 | r = amdgpu_ring_test_ring(ring); | 566 | if (r) |
587 | if (r) { | ||
588 | ring->ready = false; | ||
589 | goto done; | 567 | goto done; |
590 | } | ||
591 | } | 568 | } |
592 | } | 569 | } |
593 | done: | 570 | done: |
@@ -619,7 +596,7 @@ static int uvd_v7_0_hw_fini(void *handle) | |||
619 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { | 596 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { |
620 | if (adev->uvd.harvest_config & (1 << i)) | 597 | if (adev->uvd.harvest_config & (1 << i)) |
621 | continue; | 598 | continue; |
622 | adev->uvd.inst[i].ring.ready = false; | 599 | adev->uvd.inst[i].ring.sched.ready = false; |
623 | } | 600 | } |
624 | 601 | ||
625 | return 0; | 602 | return 0; |
@@ -1235,11 +1212,9 @@ static int uvd_v7_0_ring_test_ring(struct amdgpu_ring *ring) | |||
1235 | 1212 | ||
1236 | WREG32_SOC15(UVD, ring->me, mmUVD_CONTEXT_ID, 0xCAFEDEAD); | 1213 | WREG32_SOC15(UVD, ring->me, mmUVD_CONTEXT_ID, 0xCAFEDEAD); |
1237 | r = amdgpu_ring_alloc(ring, 3); | 1214 | r = amdgpu_ring_alloc(ring, 3); |
1238 | if (r) { | 1215 | if (r) |
1239 | DRM_ERROR("amdgpu: (%d)cp failed to lock ring %d (%d).\n", | ||
1240 | ring->me, ring->idx, r); | ||
1241 | return r; | 1216 | return r; |
1242 | } | 1217 | |
1243 | amdgpu_ring_write(ring, | 1218 | amdgpu_ring_write(ring, |
1244 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_CONTEXT_ID), 0)); | 1219 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_CONTEXT_ID), 0)); |
1245 | amdgpu_ring_write(ring, 0xDEADBEEF); | 1220 | amdgpu_ring_write(ring, 0xDEADBEEF); |
@@ -1251,14 +1226,9 @@ static int uvd_v7_0_ring_test_ring(struct amdgpu_ring *ring) | |||
1251 | DRM_UDELAY(1); | 1226 | DRM_UDELAY(1); |
1252 | } | 1227 | } |
1253 | 1228 | ||
1254 | if (i < adev->usec_timeout) { | 1229 | if (i >= adev->usec_timeout) |
1255 | DRM_DEBUG("(%d)ring test on %d succeeded in %d usecs\n", | 1230 | r = -ETIMEDOUT; |
1256 | ring->me, ring->idx, i); | 1231 | |
1257 | } else { | ||
1258 | DRM_ERROR("(%d)amdgpu: ring %d test failed (0x%08X)\n", | ||
1259 | ring->me, ring->idx, tmp); | ||
1260 | r = -EINVAL; | ||
1261 | } | ||
1262 | return r; | 1232 | return r; |
1263 | } | 1233 | } |
1264 | 1234 | ||
@@ -1300,10 +1270,12 @@ static int uvd_v7_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p, | |||
1300 | * Write ring commands to execute the indirect buffer | 1270 | * Write ring commands to execute the indirect buffer |
1301 | */ | 1271 | */ |
1302 | static void uvd_v7_0_ring_emit_ib(struct amdgpu_ring *ring, | 1272 | static void uvd_v7_0_ring_emit_ib(struct amdgpu_ring *ring, |
1273 | struct amdgpu_job *job, | ||
1303 | struct amdgpu_ib *ib, | 1274 | struct amdgpu_ib *ib, |
1304 | unsigned vmid, bool ctx_switch) | 1275 | bool ctx_switch) |
1305 | { | 1276 | { |
1306 | struct amdgpu_device *adev = ring->adev; | 1277 | struct amdgpu_device *adev = ring->adev; |
1278 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
1307 | 1279 | ||
1308 | amdgpu_ring_write(ring, | 1280 | amdgpu_ring_write(ring, |
1309 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_LMI_RBC_IB_VMID), 0)); | 1281 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_LMI_RBC_IB_VMID), 0)); |
@@ -1329,8 +1301,12 @@ static void uvd_v7_0_ring_emit_ib(struct amdgpu_ring *ring, | |||
1329 | * Write enc ring commands to execute the indirect buffer | 1301 | * Write enc ring commands to execute the indirect buffer |
1330 | */ | 1302 | */ |
1331 | static void uvd_v7_0_enc_ring_emit_ib(struct amdgpu_ring *ring, | 1303 | static void uvd_v7_0_enc_ring_emit_ib(struct amdgpu_ring *ring, |
1332 | struct amdgpu_ib *ib, unsigned int vmid, bool ctx_switch) | 1304 | struct amdgpu_job *job, |
1305 | struct amdgpu_ib *ib, | ||
1306 | bool ctx_switch) | ||
1333 | { | 1307 | { |
1308 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
1309 | |||
1334 | amdgpu_ring_write(ring, HEVC_ENC_CMD_IB_VM); | 1310 | amdgpu_ring_write(ring, HEVC_ENC_CMD_IB_VM); |
1335 | amdgpu_ring_write(ring, vmid); | 1311 | amdgpu_ring_write(ring, vmid); |
1336 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); | 1312 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); |
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c index ea28828360d3..bed78a778e3f 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c | |||
@@ -463,15 +463,11 @@ static int vce_v2_0_hw_init(void *handle) | |||
463 | 463 | ||
464 | amdgpu_asic_set_vce_clocks(adev, 10000, 10000); | 464 | amdgpu_asic_set_vce_clocks(adev, 10000, 10000); |
465 | vce_v2_0_enable_mgcg(adev, true, false); | 465 | vce_v2_0_enable_mgcg(adev, true, false); |
466 | for (i = 0; i < adev->vce.num_rings; i++) | ||
467 | adev->vce.ring[i].ready = false; | ||
468 | 466 | ||
469 | for (i = 0; i < adev->vce.num_rings; i++) { | 467 | for (i = 0; i < adev->vce.num_rings; i++) { |
470 | r = amdgpu_ring_test_ring(&adev->vce.ring[i]); | 468 | r = amdgpu_ring_test_helper(&adev->vce.ring[i]); |
471 | if (r) | 469 | if (r) |
472 | return r; | 470 | return r; |
473 | else | ||
474 | adev->vce.ring[i].ready = true; | ||
475 | } | 471 | } |
476 | 472 | ||
477 | DRM_INFO("VCE initialized successfully.\n"); | 473 | DRM_INFO("VCE initialized successfully.\n"); |
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index 6dbd39730070..3e84840859a7 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | |||
@@ -474,15 +474,10 @@ static int vce_v3_0_hw_init(void *handle) | |||
474 | 474 | ||
475 | amdgpu_asic_set_vce_clocks(adev, 10000, 10000); | 475 | amdgpu_asic_set_vce_clocks(adev, 10000, 10000); |
476 | 476 | ||
477 | for (i = 0; i < adev->vce.num_rings; i++) | ||
478 | adev->vce.ring[i].ready = false; | ||
479 | |||
480 | for (i = 0; i < adev->vce.num_rings; i++) { | 477 | for (i = 0; i < adev->vce.num_rings; i++) { |
481 | r = amdgpu_ring_test_ring(&adev->vce.ring[i]); | 478 | r = amdgpu_ring_test_helper(&adev->vce.ring[i]); |
482 | if (r) | 479 | if (r) |
483 | return r; | 480 | return r; |
484 | else | ||
485 | adev->vce.ring[i].ready = true; | ||
486 | } | 481 | } |
487 | 482 | ||
488 | DRM_INFO("VCE initialized successfully.\n"); | 483 | DRM_INFO("VCE initialized successfully.\n"); |
@@ -838,8 +833,12 @@ out: | |||
838 | } | 833 | } |
839 | 834 | ||
840 | static void vce_v3_0_ring_emit_ib(struct amdgpu_ring *ring, | 835 | static void vce_v3_0_ring_emit_ib(struct amdgpu_ring *ring, |
841 | struct amdgpu_ib *ib, unsigned int vmid, bool ctx_switch) | 836 | struct amdgpu_job *job, |
837 | struct amdgpu_ib *ib, | ||
838 | bool ctx_switch) | ||
842 | { | 839 | { |
840 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
841 | |||
843 | amdgpu_ring_write(ring, VCE_CMD_IB_VM); | 842 | amdgpu_ring_write(ring, VCE_CMD_IB_VM); |
844 | amdgpu_ring_write(ring, vmid); | 843 | amdgpu_ring_write(ring, vmid); |
845 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); | 844 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); |
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c index 1c9471890bf7..0054ba1b9a68 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c | |||
@@ -519,15 +519,10 @@ static int vce_v4_0_hw_init(void *handle) | |||
519 | if (r) | 519 | if (r) |
520 | return r; | 520 | return r; |
521 | 521 | ||
522 | for (i = 0; i < adev->vce.num_rings; i++) | ||
523 | adev->vce.ring[i].ready = false; | ||
524 | |||
525 | for (i = 0; i < adev->vce.num_rings; i++) { | 522 | for (i = 0; i < adev->vce.num_rings; i++) { |
526 | r = amdgpu_ring_test_ring(&adev->vce.ring[i]); | 523 | r = amdgpu_ring_test_helper(&adev->vce.ring[i]); |
527 | if (r) | 524 | if (r) |
528 | return r; | 525 | return r; |
529 | else | ||
530 | adev->vce.ring[i].ready = true; | ||
531 | } | 526 | } |
532 | 527 | ||
533 | DRM_INFO("VCE initialized successfully.\n"); | 528 | DRM_INFO("VCE initialized successfully.\n"); |
@@ -549,7 +544,7 @@ static int vce_v4_0_hw_fini(void *handle) | |||
549 | } | 544 | } |
550 | 545 | ||
551 | for (i = 0; i < adev->vce.num_rings; i++) | 546 | for (i = 0; i < adev->vce.num_rings; i++) |
552 | adev->vce.ring[i].ready = false; | 547 | adev->vce.ring[i].sched.ready = false; |
553 | 548 | ||
554 | return 0; | 549 | return 0; |
555 | } | 550 | } |
@@ -951,9 +946,11 @@ static int vce_v4_0_set_powergating_state(void *handle, | |||
951 | } | 946 | } |
952 | #endif | 947 | #endif |
953 | 948 | ||
954 | static void vce_v4_0_ring_emit_ib(struct amdgpu_ring *ring, | 949 | static void vce_v4_0_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_job *job, |
955 | struct amdgpu_ib *ib, unsigned int vmid, bool ctx_switch) | 950 | struct amdgpu_ib *ib, bool ctx_switch) |
956 | { | 951 | { |
952 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
953 | |||
957 | amdgpu_ring_write(ring, VCE_CMD_IB_VM); | 954 | amdgpu_ring_write(ring, VCE_CMD_IB_VM); |
958 | amdgpu_ring_write(ring, vmid); | 955 | amdgpu_ring_write(ring, vmid); |
959 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); | 956 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); |
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index eae90922fdbe..c1a03505f956 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | |||
@@ -176,30 +176,22 @@ static int vcn_v1_0_hw_init(void *handle) | |||
176 | struct amdgpu_ring *ring = &adev->vcn.ring_dec; | 176 | struct amdgpu_ring *ring = &adev->vcn.ring_dec; |
177 | int i, r; | 177 | int i, r; |
178 | 178 | ||
179 | ring->ready = true; | 179 | r = amdgpu_ring_test_helper(ring); |
180 | r = amdgpu_ring_test_ring(ring); | 180 | if (r) |
181 | if (r) { | ||
182 | ring->ready = false; | ||
183 | goto done; | 181 | goto done; |
184 | } | ||
185 | 182 | ||
186 | for (i = 0; i < adev->vcn.num_enc_rings; ++i) { | 183 | for (i = 0; i < adev->vcn.num_enc_rings; ++i) { |
187 | ring = &adev->vcn.ring_enc[i]; | 184 | ring = &adev->vcn.ring_enc[i]; |
188 | ring->ready = true; | 185 | ring->sched.ready = true; |
189 | r = amdgpu_ring_test_ring(ring); | 186 | r = amdgpu_ring_test_helper(ring); |
190 | if (r) { | 187 | if (r) |
191 | ring->ready = false; | ||
192 | goto done; | 188 | goto done; |
193 | } | ||
194 | } | 189 | } |
195 | 190 | ||
196 | ring = &adev->vcn.ring_jpeg; | 191 | ring = &adev->vcn.ring_jpeg; |
197 | ring->ready = true; | 192 | r = amdgpu_ring_test_helper(ring); |
198 | r = amdgpu_ring_test_ring(ring); | 193 | if (r) |
199 | if (r) { | ||
200 | ring->ready = false; | ||
201 | goto done; | 194 | goto done; |
202 | } | ||
203 | 195 | ||
204 | done: | 196 | done: |
205 | if (!r) | 197 | if (!r) |
@@ -224,7 +216,7 @@ static int vcn_v1_0_hw_fini(void *handle) | |||
224 | if (RREG32_SOC15(VCN, 0, mmUVD_STATUS)) | 216 | if (RREG32_SOC15(VCN, 0, mmUVD_STATUS)) |
225 | vcn_v1_0_stop(adev); | 217 | vcn_v1_0_stop(adev); |
226 | 218 | ||
227 | ring->ready = false; | 219 | ring->sched.ready = false; |
228 | 220 | ||
229 | return 0; | 221 | return 0; |
230 | } | 222 | } |
@@ -1366,10 +1358,12 @@ static void vcn_v1_0_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 | |||
1366 | * Write ring commands to execute the indirect buffer | 1358 | * Write ring commands to execute the indirect buffer |
1367 | */ | 1359 | */ |
1368 | static void vcn_v1_0_dec_ring_emit_ib(struct amdgpu_ring *ring, | 1360 | static void vcn_v1_0_dec_ring_emit_ib(struct amdgpu_ring *ring, |
1369 | struct amdgpu_ib *ib, | 1361 | struct amdgpu_job *job, |
1370 | unsigned vmid, bool ctx_switch) | 1362 | struct amdgpu_ib *ib, |
1363 | bool ctx_switch) | ||
1371 | { | 1364 | { |
1372 | struct amdgpu_device *adev = ring->adev; | 1365 | struct amdgpu_device *adev = ring->adev; |
1366 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
1373 | 1367 | ||
1374 | amdgpu_ring_write(ring, | 1368 | amdgpu_ring_write(ring, |
1375 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_VMID), 0)); | 1369 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_VMID), 0)); |
@@ -1524,8 +1518,12 @@ static void vcn_v1_0_enc_ring_insert_end(struct amdgpu_ring *ring) | |||
1524 | * Write enc ring commands to execute the indirect buffer | 1518 | * Write enc ring commands to execute the indirect buffer |
1525 | */ | 1519 | */ |
1526 | static void vcn_v1_0_enc_ring_emit_ib(struct amdgpu_ring *ring, | 1520 | static void vcn_v1_0_enc_ring_emit_ib(struct amdgpu_ring *ring, |
1527 | struct amdgpu_ib *ib, unsigned int vmid, bool ctx_switch) | 1521 | struct amdgpu_job *job, |
1522 | struct amdgpu_ib *ib, | ||
1523 | bool ctx_switch) | ||
1528 | { | 1524 | { |
1525 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
1526 | |||
1529 | amdgpu_ring_write(ring, VCN_ENC_CMD_IB); | 1527 | amdgpu_ring_write(ring, VCN_ENC_CMD_IB); |
1530 | amdgpu_ring_write(ring, vmid); | 1528 | amdgpu_ring_write(ring, vmid); |
1531 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); | 1529 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); |
@@ -1725,10 +1723,12 @@ static void vcn_v1_0_jpeg_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u6 | |||
1725 | * Write ring commands to execute the indirect buffer. | 1723 | * Write ring commands to execute the indirect buffer. |
1726 | */ | 1724 | */ |
1727 | static void vcn_v1_0_jpeg_ring_emit_ib(struct amdgpu_ring *ring, | 1725 | static void vcn_v1_0_jpeg_ring_emit_ib(struct amdgpu_ring *ring, |
1728 | struct amdgpu_ib *ib, | 1726 | struct amdgpu_job *job, |
1729 | unsigned vmid, bool ctx_switch) | 1727 | struct amdgpu_ib *ib, |
1728 | bool ctx_switch) | ||
1730 | { | 1729 | { |
1731 | struct amdgpu_device *adev = ring->adev; | 1730 | struct amdgpu_device *adev = ring->adev; |
1731 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | ||
1732 | 1732 | ||
1733 | amdgpu_ring_write(ring, | 1733 | amdgpu_ring_write(ring, |
1734 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_IB_VMID), 0, 0, PACKETJ_TYPE0)); | 1734 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_IB_VMID), 0, 0, PACKETJ_TYPE0)); |
diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c index a99f71797aa3..a0fda6f9252a 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c | |||
@@ -129,7 +129,7 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev) | |||
129 | else | 129 | else |
130 | wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4); | 130 | wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4); |
131 | WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off)); | 131 | WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off)); |
132 | WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF); | 132 | WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFFFF); |
133 | 133 | ||
134 | /* set rptr, wptr to 0 */ | 134 | /* set rptr, wptr to 0 */ |
135 | WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0); | 135 | WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0); |
diff --git a/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c b/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c index 2d4473557b0d..d13fc4fcb517 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c +++ b/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c | |||
@@ -49,6 +49,7 @@ int vega20_reg_base_init(struct amdgpu_device *adev) | |||
49 | adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i])); | 49 | adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i])); |
50 | adev->reg_offset[NBIF_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i])); | 50 | adev->reg_offset[NBIF_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i])); |
51 | adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i])); | 51 | adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i])); |
52 | adev->reg_offset[CLK_HWIP][i] = (uint32_t *)(&(CLK_BASE.instance[i])); | ||
52 | } | 53 | } |
53 | return 0; | 54 | return 0; |
54 | } | 55 | } |
diff --git a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c index 5d2475d5392c..177d1e5329a5 100644 --- a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c +++ b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "kfd_priv.h" | 23 | #include "kfd_priv.h" |
24 | #include "kfd_events.h" | 24 | #include "kfd_events.h" |
25 | #include "cik_int.h" | 25 | #include "cik_int.h" |
26 | #include "amdgpu_amdkfd.h" | ||
26 | 27 | ||
27 | static bool cik_event_interrupt_isr(struct kfd_dev *dev, | 28 | static bool cik_event_interrupt_isr(struct kfd_dev *dev, |
28 | const uint32_t *ih_ring_entry, | 29 | const uint32_t *ih_ring_entry, |
@@ -107,7 +108,7 @@ static void cik_event_interrupt_wq(struct kfd_dev *dev, | |||
107 | kfd_process_vm_fault(dev->dqm, pasid); | 108 | kfd_process_vm_fault(dev->dqm, pasid); |
108 | 109 | ||
109 | memset(&info, 0, sizeof(info)); | 110 | memset(&info, 0, sizeof(info)); |
110 | dev->kfd2kgd->get_vm_fault_info(dev->kgd, &info); | 111 | amdgpu_amdkfd_gpuvm_get_vm_fault_info(dev->kgd, &info); |
111 | if (!info.page_addr && !info.status) | 112 | if (!info.page_addr && !info.status) |
112 | return; | 113 | return; |
113 | 114 | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/cik_regs.h b/drivers/gpu/drm/amd/amdkfd/cik_regs.h index 37ce6dd65391..8e2a1663c4db 100644 --- a/drivers/gpu/drm/amd/amdkfd/cik_regs.h +++ b/drivers/gpu/drm/amd/amdkfd/cik_regs.h | |||
@@ -68,6 +68,4 @@ | |||
68 | 68 | ||
69 | #define GRBM_GFX_INDEX 0x30800 | 69 | #define GRBM_GFX_INDEX 0x30800 |
70 | 70 | ||
71 | #define ATC_VMID_PASID_MAPPING_VALID (1U << 31) | ||
72 | |||
73 | #endif | 71 | #endif |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 14d5b5fa822d..5f4062b41add 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "kfd_priv.h" | 37 | #include "kfd_priv.h" |
38 | #include "kfd_device_queue_manager.h" | 38 | #include "kfd_device_queue_manager.h" |
39 | #include "kfd_dbgmgr.h" | 39 | #include "kfd_dbgmgr.h" |
40 | #include "amdgpu_amdkfd.h" | ||
40 | 41 | ||
41 | static long kfd_ioctl(struct file *, unsigned int, unsigned long); | 42 | static long kfd_ioctl(struct file *, unsigned int, unsigned long); |
42 | static int kfd_open(struct inode *, struct file *); | 43 | static int kfd_open(struct inode *, struct file *); |
@@ -834,8 +835,7 @@ static int kfd_ioctl_get_clock_counters(struct file *filep, | |||
834 | dev = kfd_device_by_id(args->gpu_id); | 835 | dev = kfd_device_by_id(args->gpu_id); |
835 | if (dev) | 836 | if (dev) |
836 | /* Reading GPU clock counter from KGD */ | 837 | /* Reading GPU clock counter from KGD */ |
837 | args->gpu_clock_counter = | 838 | args->gpu_clock_counter = amdgpu_amdkfd_get_gpu_clock_counter(dev->kgd); |
838 | dev->kfd2kgd->get_gpu_clock_counter(dev->kgd); | ||
839 | else | 839 | else |
840 | /* Node without GPU resource */ | 840 | /* Node without GPU resource */ |
841 | args->gpu_clock_counter = 0; | 841 | args->gpu_clock_counter = 0; |
@@ -1042,7 +1042,7 @@ static int kfd_ioctl_create_event(struct file *filp, struct kfd_process *p, | |||
1042 | } | 1042 | } |
1043 | mutex_unlock(&p->mutex); | 1043 | mutex_unlock(&p->mutex); |
1044 | 1044 | ||
1045 | err = kfd->kfd2kgd->map_gtt_bo_to_kernel(kfd->kgd, | 1045 | err = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(kfd->kgd, |
1046 | mem, &kern_addr, &size); | 1046 | mem, &kern_addr, &size); |
1047 | if (err) { | 1047 | if (err) { |
1048 | pr_err("Failed to map event page to kernel\n"); | 1048 | pr_err("Failed to map event page to kernel\n"); |
@@ -1240,7 +1240,7 @@ bool kfd_dev_is_large_bar(struct kfd_dev *dev) | |||
1240 | if (dev->device_info->needs_iommu_device) | 1240 | if (dev->device_info->needs_iommu_device) |
1241 | return false; | 1241 | return false; |
1242 | 1242 | ||
1243 | dev->kfd2kgd->get_local_mem_info(dev->kgd, &mem_info); | 1243 | amdgpu_amdkfd_get_local_mem_info(dev->kgd, &mem_info); |
1244 | if (mem_info.local_mem_size_private == 0 && | 1244 | if (mem_info.local_mem_size_private == 0 && |
1245 | mem_info.local_mem_size_public > 0) | 1245 | mem_info.local_mem_size_public > 0) |
1246 | return true; | 1246 | return true; |
@@ -1281,7 +1281,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep, | |||
1281 | goto err_unlock; | 1281 | goto err_unlock; |
1282 | } | 1282 | } |
1283 | 1283 | ||
1284 | err = dev->kfd2kgd->alloc_memory_of_gpu( | 1284 | err = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( |
1285 | dev->kgd, args->va_addr, args->size, | 1285 | dev->kgd, args->va_addr, args->size, |
1286 | pdd->vm, (struct kgd_mem **) &mem, &offset, | 1286 | pdd->vm, (struct kgd_mem **) &mem, &offset, |
1287 | flags); | 1287 | flags); |
@@ -1303,7 +1303,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep, | |||
1303 | return 0; | 1303 | return 0; |
1304 | 1304 | ||
1305 | err_free: | 1305 | err_free: |
1306 | dev->kfd2kgd->free_memory_of_gpu(dev->kgd, (struct kgd_mem *)mem); | 1306 | amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->kgd, (struct kgd_mem *)mem); |
1307 | err_unlock: | 1307 | err_unlock: |
1308 | mutex_unlock(&p->mutex); | 1308 | mutex_unlock(&p->mutex); |
1309 | return err; | 1309 | return err; |
@@ -1338,7 +1338,8 @@ static int kfd_ioctl_free_memory_of_gpu(struct file *filep, | |||
1338 | goto err_unlock; | 1338 | goto err_unlock; |
1339 | } | 1339 | } |
1340 | 1340 | ||
1341 | ret = dev->kfd2kgd->free_memory_of_gpu(dev->kgd, (struct kgd_mem *)mem); | 1341 | ret = amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->kgd, |
1342 | (struct kgd_mem *)mem); | ||
1342 | 1343 | ||
1343 | /* If freeing the buffer failed, leave the handle in place for | 1344 | /* If freeing the buffer failed, leave the handle in place for |
1344 | * clean-up during process tear-down. | 1345 | * clean-up during process tear-down. |
@@ -1418,7 +1419,7 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep, | |||
1418 | err = PTR_ERR(peer_pdd); | 1419 | err = PTR_ERR(peer_pdd); |
1419 | goto get_mem_obj_from_handle_failed; | 1420 | goto get_mem_obj_from_handle_failed; |
1420 | } | 1421 | } |
1421 | err = peer->kfd2kgd->map_memory_to_gpu( | 1422 | err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu( |
1422 | peer->kgd, (struct kgd_mem *)mem, peer_pdd->vm); | 1423 | peer->kgd, (struct kgd_mem *)mem, peer_pdd->vm); |
1423 | if (err) { | 1424 | if (err) { |
1424 | pr_err("Failed to map to gpu %d/%d\n", | 1425 | pr_err("Failed to map to gpu %d/%d\n", |
@@ -1430,7 +1431,7 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep, | |||
1430 | 1431 | ||
1431 | mutex_unlock(&p->mutex); | 1432 | mutex_unlock(&p->mutex); |
1432 | 1433 | ||
1433 | err = dev->kfd2kgd->sync_memory(dev->kgd, (struct kgd_mem *) mem, true); | 1434 | err = amdgpu_amdkfd_gpuvm_sync_memory(dev->kgd, (struct kgd_mem *) mem, true); |
1434 | if (err) { | 1435 | if (err) { |
1435 | pr_debug("Sync memory failed, wait interrupted by user signal\n"); | 1436 | pr_debug("Sync memory failed, wait interrupted by user signal\n"); |
1436 | goto sync_memory_failed; | 1437 | goto sync_memory_failed; |
@@ -1525,7 +1526,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep, | |||
1525 | err = -ENODEV; | 1526 | err = -ENODEV; |
1526 | goto get_mem_obj_from_handle_failed; | 1527 | goto get_mem_obj_from_handle_failed; |
1527 | } | 1528 | } |
1528 | err = dev->kfd2kgd->unmap_memory_to_gpu( | 1529 | err = amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( |
1529 | peer->kgd, (struct kgd_mem *)mem, peer_pdd->vm); | 1530 | peer->kgd, (struct kgd_mem *)mem, peer_pdd->vm); |
1530 | if (err) { | 1531 | if (err) { |
1531 | pr_err("Failed to unmap from gpu %d/%d\n", | 1532 | pr_err("Failed to unmap from gpu %d/%d\n", |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c index 56412b0e7e1c..3783d122f283 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "kfd_priv.h" | 26 | #include "kfd_priv.h" |
27 | #include "kfd_topology.h" | 27 | #include "kfd_topology.h" |
28 | #include "kfd_iommu.h" | 28 | #include "kfd_iommu.h" |
29 | #include "amdgpu_amdkfd.h" | ||
29 | 30 | ||
30 | /* GPU Processor ID base for dGPUs for which VCRAT needs to be created. | 31 | /* GPU Processor ID base for dGPUs for which VCRAT needs to be created. |
31 | * GPU processor ID are expressed with Bit[31]=1. | 32 | * GPU processor ID are expressed with Bit[31]=1. |
@@ -753,12 +754,10 @@ int kfd_create_crat_image_acpi(void **crat_image, size_t *size) | |||
753 | return -ENODATA; | 754 | return -ENODATA; |
754 | } | 755 | } |
755 | 756 | ||
756 | pcrat_image = kmalloc(crat_table->length, GFP_KERNEL); | 757 | pcrat_image = kmemdup(crat_table, crat_table->length, GFP_KERNEL); |
757 | if (!pcrat_image) | 758 | if (!pcrat_image) |
758 | return -ENOMEM; | 759 | return -ENOMEM; |
759 | 760 | ||
760 | memcpy(pcrat_image, crat_table, crat_table->length); | ||
761 | |||
762 | *crat_image = pcrat_image; | 761 | *crat_image = pcrat_image; |
763 | *size = crat_table->length; | 762 | *size = crat_table->length; |
764 | 763 | ||
@@ -1161,7 +1160,7 @@ static int kfd_create_vcrat_image_gpu(void *pcrat_image, | |||
1161 | cu->flags |= CRAT_CU_FLAGS_GPU_PRESENT; | 1160 | cu->flags |= CRAT_CU_FLAGS_GPU_PRESENT; |
1162 | cu->proximity_domain = proximity_domain; | 1161 | cu->proximity_domain = proximity_domain; |
1163 | 1162 | ||
1164 | kdev->kfd2kgd->get_cu_info(kdev->kgd, &cu_info); | 1163 | amdgpu_amdkfd_get_cu_info(kdev->kgd, &cu_info); |
1165 | cu->num_simd_per_cu = cu_info.simd_per_cu; | 1164 | cu->num_simd_per_cu = cu_info.simd_per_cu; |
1166 | cu->num_simd_cores = cu_info.simd_per_cu * cu_info.cu_active_number; | 1165 | cu->num_simd_cores = cu_info.simd_per_cu * cu_info.cu_active_number; |
1167 | cu->max_waves_simd = cu_info.max_waves_per_simd; | 1166 | cu->max_waves_simd = cu_info.max_waves_per_simd; |
@@ -1192,7 +1191,7 @@ static int kfd_create_vcrat_image_gpu(void *pcrat_image, | |||
1192 | * report the total FB size (public+private) as a single | 1191 | * report the total FB size (public+private) as a single |
1193 | * private heap. | 1192 | * private heap. |
1194 | */ | 1193 | */ |
1195 | kdev->kfd2kgd->get_local_mem_info(kdev->kgd, &local_mem_info); | 1194 | amdgpu_amdkfd_get_local_mem_info(kdev->kgd, &local_mem_info); |
1196 | sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr + | 1195 | sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr + |
1197 | sub_type_hdr->length); | 1196 | sub_type_hdr->length); |
1198 | 1197 | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index a9f18ea7e354..c004647c8cb4 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "kfd_pm4_headers_vi.h" | 28 | #include "kfd_pm4_headers_vi.h" |
29 | #include "cwsr_trap_handler.h" | 29 | #include "cwsr_trap_handler.h" |
30 | #include "kfd_iommu.h" | 30 | #include "kfd_iommu.h" |
31 | #include "amdgpu_amdkfd.h" | ||
31 | 32 | ||
32 | #define MQD_SIZE_ALIGNED 768 | 33 | #define MQD_SIZE_ALIGNED 768 |
33 | 34 | ||
@@ -478,7 +479,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, | |||
478 | /* add another 512KB for all other allocations on gart (HPD, fences) */ | 479 | /* add another 512KB for all other allocations on gart (HPD, fences) */ |
479 | size += 512 * 1024; | 480 | size += 512 * 1024; |
480 | 481 | ||
481 | if (kfd->kfd2kgd->init_gtt_mem_allocation( | 482 | if (amdgpu_amdkfd_alloc_gtt_mem( |
482 | kfd->kgd, size, &kfd->gtt_mem, | 483 | kfd->kgd, size, &kfd->gtt_mem, |
483 | &kfd->gtt_start_gpu_addr, &kfd->gtt_start_cpu_ptr, | 484 | &kfd->gtt_start_gpu_addr, &kfd->gtt_start_cpu_ptr, |
484 | false)) { | 485 | false)) { |
@@ -552,7 +553,7 @@ kfd_topology_add_device_error: | |||
552 | kfd_doorbell_error: | 553 | kfd_doorbell_error: |
553 | kfd_gtt_sa_fini(kfd); | 554 | kfd_gtt_sa_fini(kfd); |
554 | kfd_gtt_sa_init_error: | 555 | kfd_gtt_sa_init_error: |
555 | kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem); | 556 | amdgpu_amdkfd_free_gtt_mem(kfd->kgd, kfd->gtt_mem); |
556 | dev_err(kfd_device, | 557 | dev_err(kfd_device, |
557 | "device %x:%x NOT added due to errors\n", | 558 | "device %x:%x NOT added due to errors\n", |
558 | kfd->pdev->vendor, kfd->pdev->device); | 559 | kfd->pdev->vendor, kfd->pdev->device); |
@@ -569,7 +570,7 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd) | |||
569 | kfd_topology_remove_device(kfd); | 570 | kfd_topology_remove_device(kfd); |
570 | kfd_doorbell_fini(kfd); | 571 | kfd_doorbell_fini(kfd); |
571 | kfd_gtt_sa_fini(kfd); | 572 | kfd_gtt_sa_fini(kfd); |
572 | kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem); | 573 | amdgpu_amdkfd_free_gtt_mem(kfd->kgd, kfd->gtt_mem); |
573 | } | 574 | } |
574 | 575 | ||
575 | kfree(kfd); | 576 | kfree(kfd); |
@@ -681,6 +682,7 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry) | |||
681 | { | 682 | { |
682 | uint32_t patched_ihre[KFD_MAX_RING_ENTRY_SIZE]; | 683 | uint32_t patched_ihre[KFD_MAX_RING_ENTRY_SIZE]; |
683 | bool is_patched = false; | 684 | bool is_patched = false; |
685 | unsigned long flags; | ||
684 | 686 | ||
685 | if (!kfd->init_complete) | 687 | if (!kfd->init_complete) |
686 | return; | 688 | return; |
@@ -690,7 +692,7 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry) | |||
690 | return; | 692 | return; |
691 | } | 693 | } |
692 | 694 | ||
693 | spin_lock(&kfd->interrupt_lock); | 695 | spin_lock_irqsave(&kfd->interrupt_lock, flags); |
694 | 696 | ||
695 | if (kfd->interrupts_active | 697 | if (kfd->interrupts_active |
696 | && interrupt_is_wanted(kfd, ih_ring_entry, | 698 | && interrupt_is_wanted(kfd, ih_ring_entry, |
@@ -699,7 +701,7 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry) | |||
699 | is_patched ? patched_ihre : ih_ring_entry)) | 701 | is_patched ? patched_ihre : ih_ring_entry)) |
700 | queue_work(kfd->ih_wq, &kfd->interrupt_work); | 702 | queue_work(kfd->ih_wq, &kfd->interrupt_work); |
701 | 703 | ||
702 | spin_unlock(&kfd->interrupt_lock); | 704 | spin_unlock_irqrestore(&kfd->interrupt_lock, flags); |
703 | } | 705 | } |
704 | 706 | ||
705 | int kgd2kfd_quiesce_mm(struct mm_struct *mm) | 707 | int kgd2kfd_quiesce_mm(struct mm_struct *mm) |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index a3b933967171..fb9d66ea13b7 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "kfd_mqd_manager.h" | 33 | #include "kfd_mqd_manager.h" |
34 | #include "cik_regs.h" | 34 | #include "cik_regs.h" |
35 | #include "kfd_kernel_queue.h" | 35 | #include "kfd_kernel_queue.h" |
36 | #include "amdgpu_amdkfd.h" | ||
36 | 37 | ||
37 | /* Size of the per-pipe EOP queue */ | 38 | /* Size of the per-pipe EOP queue */ |
38 | #define CIK_HPD_EOP_BYTES_LOG2 11 | 39 | #define CIK_HPD_EOP_BYTES_LOG2 11 |
@@ -219,7 +220,7 @@ static int flush_texture_cache_nocpsch(struct kfd_dev *kdev, | |||
219 | if (ret) | 220 | if (ret) |
220 | return ret; | 221 | return ret; |
221 | 222 | ||
222 | return kdev->kfd2kgd->submit_ib(kdev->kgd, KGD_ENGINE_MEC1, qpd->vmid, | 223 | return amdgpu_amdkfd_submit_ib(kdev->kgd, KGD_ENGINE_MEC1, qpd->vmid, |
223 | qpd->ib_base, (uint32_t *)qpd->ib_kaddr, | 224 | qpd->ib_base, (uint32_t *)qpd->ib_kaddr, |
224 | pmf->release_mem_size / sizeof(uint32_t)); | 225 | pmf->release_mem_size / sizeof(uint32_t)); |
225 | } | 226 | } |
@@ -672,7 +673,7 @@ static int restore_process_queues_nocpsch(struct device_queue_manager *dqm, | |||
672 | 673 | ||
673 | pdd = qpd_to_pdd(qpd); | 674 | pdd = qpd_to_pdd(qpd); |
674 | /* Retrieve PD base */ | 675 | /* Retrieve PD base */ |
675 | pd_base = dqm->dev->kfd2kgd->get_process_page_dir(pdd->vm); | 676 | pd_base = amdgpu_amdkfd_gpuvm_get_process_page_dir(pdd->vm); |
676 | 677 | ||
677 | dqm_lock(dqm); | 678 | dqm_lock(dqm); |
678 | if (WARN_ON_ONCE(!qpd->evicted)) /* already restored, do nothing */ | 679 | if (WARN_ON_ONCE(!qpd->evicted)) /* already restored, do nothing */ |
@@ -743,7 +744,7 @@ static int restore_process_queues_cpsch(struct device_queue_manager *dqm, | |||
743 | 744 | ||
744 | pdd = qpd_to_pdd(qpd); | 745 | pdd = qpd_to_pdd(qpd); |
745 | /* Retrieve PD base */ | 746 | /* Retrieve PD base */ |
746 | pd_base = dqm->dev->kfd2kgd->get_process_page_dir(pdd->vm); | 747 | pd_base = amdgpu_amdkfd_gpuvm_get_process_page_dir(pdd->vm); |
747 | 748 | ||
748 | dqm_lock(dqm); | 749 | dqm_lock(dqm); |
749 | if (WARN_ON_ONCE(!qpd->evicted)) /* already restored, do nothing */ | 750 | if (WARN_ON_ONCE(!qpd->evicted)) /* already restored, do nothing */ |
@@ -793,7 +794,7 @@ static int register_process(struct device_queue_manager *dqm, | |||
793 | 794 | ||
794 | pdd = qpd_to_pdd(qpd); | 795 | pdd = qpd_to_pdd(qpd); |
795 | /* Retrieve PD base */ | 796 | /* Retrieve PD base */ |
796 | pd_base = dqm->dev->kfd2kgd->get_process_page_dir(pdd->vm); | 797 | pd_base = amdgpu_amdkfd_gpuvm_get_process_page_dir(pdd->vm); |
797 | 798 | ||
798 | dqm_lock(dqm); | 799 | dqm_lock(dqm); |
799 | list_add(&n->list, &dqm->queues); | 800 | list_add(&n->list, &dqm->queues); |
@@ -805,7 +806,7 @@ static int register_process(struct device_queue_manager *dqm, | |||
805 | retval = dqm->asic_ops.update_qpd(dqm, qpd); | 806 | retval = dqm->asic_ops.update_qpd(dqm, qpd); |
806 | 807 | ||
807 | if (dqm->processes_count++ == 0) | 808 | if (dqm->processes_count++ == 0) |
808 | dqm->dev->kfd2kgd->set_compute_idle(dqm->dev->kgd, false); | 809 | amdgpu_amdkfd_set_compute_idle(dqm->dev->kgd, false); |
809 | 810 | ||
810 | dqm_unlock(dqm); | 811 | dqm_unlock(dqm); |
811 | 812 | ||
@@ -829,7 +830,7 @@ static int unregister_process(struct device_queue_manager *dqm, | |||
829 | list_del(&cur->list); | 830 | list_del(&cur->list); |
830 | kfree(cur); | 831 | kfree(cur); |
831 | if (--dqm->processes_count == 0) | 832 | if (--dqm->processes_count == 0) |
832 | dqm->dev->kfd2kgd->set_compute_idle( | 833 | amdgpu_amdkfd_set_compute_idle( |
833 | dqm->dev->kgd, true); | 834 | dqm->dev->kgd, true); |
834 | goto out; | 835 | goto out; |
835 | } | 836 | } |
@@ -845,15 +846,8 @@ static int | |||
845 | set_pasid_vmid_mapping(struct device_queue_manager *dqm, unsigned int pasid, | 846 | set_pasid_vmid_mapping(struct device_queue_manager *dqm, unsigned int pasid, |
846 | unsigned int vmid) | 847 | unsigned int vmid) |
847 | { | 848 | { |
848 | uint32_t pasid_mapping; | ||
849 | |||
850 | pasid_mapping = (pasid == 0) ? 0 : | ||
851 | (uint32_t)pasid | | ||
852 | ATC_VMID_PASID_MAPPING_VALID; | ||
853 | |||
854 | return dqm->dev->kfd2kgd->set_pasid_vmid_mapping( | 849 | return dqm->dev->kfd2kgd->set_pasid_vmid_mapping( |
855 | dqm->dev->kgd, pasid_mapping, | 850 | dqm->dev->kgd, pasid, vmid); |
856 | vmid); | ||
857 | } | 851 | } |
858 | 852 | ||
859 | static void init_interrupts(struct device_queue_manager *dqm) | 853 | static void init_interrupts(struct device_queue_manager *dqm) |
@@ -1796,7 +1790,7 @@ static void kfd_process_hw_exception(struct work_struct *work) | |||
1796 | { | 1790 | { |
1797 | struct device_queue_manager *dqm = container_of(work, | 1791 | struct device_queue_manager *dqm = container_of(work, |
1798 | struct device_queue_manager, hw_exception_work); | 1792 | struct device_queue_manager, hw_exception_work); |
1799 | dqm->dev->kfd2kgd->gpu_recover(dqm->dev->kgd); | 1793 | amdgpu_amdkfd_gpu_reset(dqm->dev->kgd); |
1800 | } | 1794 | } |
1801 | 1795 | ||
1802 | #if defined(CONFIG_DEBUG_FS) | 1796 | #if defined(CONFIG_DEBUG_FS) |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c index e33019a7a883..6910028010d6 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c | |||
@@ -22,6 +22,7 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include "kfd_mqd_manager.h" | 24 | #include "kfd_mqd_manager.h" |
25 | #include "amdgpu_amdkfd.h" | ||
25 | 26 | ||
26 | struct mqd_manager *mqd_manager_init(enum KFD_MQD_TYPE type, | 27 | struct mqd_manager *mqd_manager_init(enum KFD_MQD_TYPE type, |
27 | struct kfd_dev *dev) | 28 | struct kfd_dev *dev) |
@@ -58,7 +59,7 @@ void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm, | |||
58 | uint32_t cu_per_sh[4] = {0}; | 59 | uint32_t cu_per_sh[4] = {0}; |
59 | int i, se, cu = 0; | 60 | int i, se, cu = 0; |
60 | 61 | ||
61 | mm->dev->kfd2kgd->get_cu_info(mm->dev->kgd, &cu_info); | 62 | amdgpu_amdkfd_get_cu_info(mm->dev->kgd, &cu_info); |
62 | 63 | ||
63 | if (cu_mask_count > cu_info.cu_active_number) | 64 | if (cu_mask_count > cu_info.cu_active_number) |
64 | cu_mask_count = cu_info.cu_active_number; | 65 | cu_mask_count = cu_info.cu_active_number; |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c index f381c1cb27bd..9dbba609450e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "gc/gc_9_0_offset.h" | 30 | #include "gc/gc_9_0_offset.h" |
31 | #include "gc/gc_9_0_sh_mask.h" | 31 | #include "gc/gc_9_0_sh_mask.h" |
32 | #include "sdma0/sdma0_4_0_sh_mask.h" | 32 | #include "sdma0/sdma0_4_0_sh_mask.h" |
33 | #include "amdgpu_amdkfd.h" | ||
33 | 34 | ||
34 | static inline struct v9_mqd *get_mqd(void *mqd) | 35 | static inline struct v9_mqd *get_mqd(void *mqd) |
35 | { | 36 | { |
@@ -83,7 +84,7 @@ static int init_mqd(struct mqd_manager *mm, void **mqd, | |||
83 | *mqd_mem_obj = kzalloc(sizeof(struct kfd_mem_obj), GFP_KERNEL); | 84 | *mqd_mem_obj = kzalloc(sizeof(struct kfd_mem_obj), GFP_KERNEL); |
84 | if (!*mqd_mem_obj) | 85 | if (!*mqd_mem_obj) |
85 | return -ENOMEM; | 86 | return -ENOMEM; |
86 | retval = kfd->kfd2kgd->init_gtt_mem_allocation(kfd->kgd, | 87 | retval = amdgpu_amdkfd_alloc_gtt_mem(kfd->kgd, |
87 | ALIGN(q->ctl_stack_size, PAGE_SIZE) + | 88 | ALIGN(q->ctl_stack_size, PAGE_SIZE) + |
88 | ALIGN(sizeof(struct v9_mqd), PAGE_SIZE), | 89 | ALIGN(sizeof(struct v9_mqd), PAGE_SIZE), |
89 | &((*mqd_mem_obj)->gtt_mem), | 90 | &((*mqd_mem_obj)->gtt_mem), |
@@ -250,7 +251,7 @@ static void uninit_mqd(struct mqd_manager *mm, void *mqd, | |||
250 | struct kfd_dev *kfd = mm->dev; | 251 | struct kfd_dev *kfd = mm->dev; |
251 | 252 | ||
252 | if (mqd_mem_obj->gtt_mem) { | 253 | if (mqd_mem_obj->gtt_mem) { |
253 | kfd->kfd2kgd->free_gtt_mem(kfd->kgd, mqd_mem_obj->gtt_mem); | 254 | amdgpu_amdkfd_free_gtt_mem(kfd->kgd, mqd_mem_obj->gtt_mem); |
254 | kfree(mqd_mem_obj); | 255 | kfree(mqd_mem_obj); |
255 | } else { | 256 | } else { |
256 | kfd_gtt_sa_free(mm->dev, mqd_mem_obj); | 257 | kfd_gtt_sa_free(mm->dev, mqd_mem_obj); |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c index 15fff4420e53..33b08ff00b50 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c | |||
@@ -22,6 +22,7 @@ | |||
22 | 22 | ||
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include "kfd_priv.h" | 24 | #include "kfd_priv.h" |
25 | #include "amdgpu_ids.h" | ||
25 | 26 | ||
26 | static unsigned int pasid_bits = 16; | 27 | static unsigned int pasid_bits = 16; |
27 | static const struct kfd2kgd_calls *kfd2kgd; | 28 | static const struct kfd2kgd_calls *kfd2kgd; |
@@ -71,7 +72,7 @@ unsigned int kfd_pasid_alloc(void) | |||
71 | return false; | 72 | return false; |
72 | } | 73 | } |
73 | 74 | ||
74 | r = kfd2kgd->alloc_pasid(pasid_bits); | 75 | r = amdgpu_pasid_alloc(pasid_bits); |
75 | 76 | ||
76 | return r > 0 ? r : 0; | 77 | return r > 0 ? r : 0; |
77 | } | 78 | } |
@@ -79,5 +80,5 @@ unsigned int kfd_pasid_alloc(void) | |||
79 | void kfd_pasid_free(unsigned int pasid) | 80 | void kfd_pasid_free(unsigned int pasid) |
80 | { | 81 | { |
81 | if (kfd2kgd) | 82 | if (kfd2kgd) |
82 | kfd2kgd->free_pasid(pasid); | 83 | amdgpu_pasid_free(pasid); |
83 | } | 84 | } |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 53ff86d45d91..dec8e64f36bd 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h | |||
@@ -507,6 +507,7 @@ struct qcm_process_device { | |||
507 | * All the memory management data should be here too | 507 | * All the memory management data should be here too |
508 | */ | 508 | */ |
509 | uint64_t gds_context_area; | 509 | uint64_t gds_context_area; |
510 | /* Contains page table flags such as AMDGPU_PTE_VALID since gfx9 */ | ||
510 | uint64_t page_table_base; | 511 | uint64_t page_table_base; |
511 | uint32_t sh_mem_config; | 512 | uint32_t sh_mem_config; |
512 | uint32_t sh_mem_bases; | 513 | uint32_t sh_mem_bases; |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 0039e451d9af..80b36e860a0a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/compat.h> | 31 | #include <linux/compat.h> |
32 | #include <linux/mman.h> | 32 | #include <linux/mman.h> |
33 | #include <linux/file.h> | 33 | #include <linux/file.h> |
34 | #include "amdgpu_amdkfd.h" | ||
34 | 35 | ||
35 | struct mm_struct; | 36 | struct mm_struct; |
36 | 37 | ||
@@ -100,8 +101,8 @@ static void kfd_process_free_gpuvm(struct kgd_mem *mem, | |||
100 | { | 101 | { |
101 | struct kfd_dev *dev = pdd->dev; | 102 | struct kfd_dev *dev = pdd->dev; |
102 | 103 | ||
103 | dev->kfd2kgd->unmap_memory_to_gpu(dev->kgd, mem, pdd->vm); | 104 | amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(dev->kgd, mem, pdd->vm); |
104 | dev->kfd2kgd->free_memory_of_gpu(dev->kgd, mem); | 105 | amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->kgd, mem); |
105 | } | 106 | } |
106 | 107 | ||
107 | /* kfd_process_alloc_gpuvm - Allocate GPU VM for the KFD process | 108 | /* kfd_process_alloc_gpuvm - Allocate GPU VM for the KFD process |
@@ -119,16 +120,16 @@ static int kfd_process_alloc_gpuvm(struct kfd_process_device *pdd, | |||
119 | int handle; | 120 | int handle; |
120 | int err; | 121 | int err; |
121 | 122 | ||
122 | err = kdev->kfd2kgd->alloc_memory_of_gpu(kdev->kgd, gpu_va, size, | 123 | err = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(kdev->kgd, gpu_va, size, |
123 | pdd->vm, &mem, NULL, flags); | 124 | pdd->vm, &mem, NULL, flags); |
124 | if (err) | 125 | if (err) |
125 | goto err_alloc_mem; | 126 | goto err_alloc_mem; |
126 | 127 | ||
127 | err = kdev->kfd2kgd->map_memory_to_gpu(kdev->kgd, mem, pdd->vm); | 128 | err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu(kdev->kgd, mem, pdd->vm); |
128 | if (err) | 129 | if (err) |
129 | goto err_map_mem; | 130 | goto err_map_mem; |
130 | 131 | ||
131 | err = kdev->kfd2kgd->sync_memory(kdev->kgd, mem, true); | 132 | err = amdgpu_amdkfd_gpuvm_sync_memory(kdev->kgd, mem, true); |
132 | if (err) { | 133 | if (err) { |
133 | pr_debug("Sync memory failed, wait interrupted by user signal\n"); | 134 | pr_debug("Sync memory failed, wait interrupted by user signal\n"); |
134 | goto sync_memory_failed; | 135 | goto sync_memory_failed; |
@@ -147,7 +148,7 @@ static int kfd_process_alloc_gpuvm(struct kfd_process_device *pdd, | |||
147 | } | 148 | } |
148 | 149 | ||
149 | if (kptr) { | 150 | if (kptr) { |
150 | err = kdev->kfd2kgd->map_gtt_bo_to_kernel(kdev->kgd, | 151 | err = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(kdev->kgd, |
151 | (struct kgd_mem *)mem, kptr, NULL); | 152 | (struct kgd_mem *)mem, kptr, NULL); |
152 | if (err) { | 153 | if (err) { |
153 | pr_debug("Map GTT BO to kernel failed\n"); | 154 | pr_debug("Map GTT BO to kernel failed\n"); |
@@ -165,7 +166,7 @@ sync_memory_failed: | |||
165 | return err; | 166 | return err; |
166 | 167 | ||
167 | err_map_mem: | 168 | err_map_mem: |
168 | kdev->kfd2kgd->free_memory_of_gpu(kdev->kgd, mem); | 169 | amdgpu_amdkfd_gpuvm_free_memory_of_gpu(kdev->kgd, mem); |
169 | err_alloc_mem: | 170 | err_alloc_mem: |
170 | *kptr = NULL; | 171 | *kptr = NULL; |
171 | return err; | 172 | return err; |
@@ -296,11 +297,11 @@ static void kfd_process_device_free_bos(struct kfd_process_device *pdd) | |||
296 | per_device_list) { | 297 | per_device_list) { |
297 | if (!peer_pdd->vm) | 298 | if (!peer_pdd->vm) |
298 | continue; | 299 | continue; |
299 | peer_pdd->dev->kfd2kgd->unmap_memory_to_gpu( | 300 | amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( |
300 | peer_pdd->dev->kgd, mem, peer_pdd->vm); | 301 | peer_pdd->dev->kgd, mem, peer_pdd->vm); |
301 | } | 302 | } |
302 | 303 | ||
303 | pdd->dev->kfd2kgd->free_memory_of_gpu(pdd->dev->kgd, mem); | 304 | amdgpu_amdkfd_gpuvm_free_memory_of_gpu(pdd->dev->kgd, mem); |
304 | kfd_process_device_remove_obj_handle(pdd, id); | 305 | kfd_process_device_remove_obj_handle(pdd, id); |
305 | } | 306 | } |
306 | } | 307 | } |
@@ -323,11 +324,12 @@ static void kfd_process_destroy_pdds(struct kfd_process *p) | |||
323 | pdd->dev->id, p->pasid); | 324 | pdd->dev->id, p->pasid); |
324 | 325 | ||
325 | if (pdd->drm_file) { | 326 | if (pdd->drm_file) { |
326 | pdd->dev->kfd2kgd->release_process_vm(pdd->dev->kgd, pdd->vm); | 327 | amdgpu_amdkfd_gpuvm_release_process_vm( |
328 | pdd->dev->kgd, pdd->vm); | ||
327 | fput(pdd->drm_file); | 329 | fput(pdd->drm_file); |
328 | } | 330 | } |
329 | else if (pdd->vm) | 331 | else if (pdd->vm) |
330 | pdd->dev->kfd2kgd->destroy_process_vm( | 332 | amdgpu_amdkfd_gpuvm_destroy_process_vm( |
331 | pdd->dev->kgd, pdd->vm); | 333 | pdd->dev->kgd, pdd->vm); |
332 | 334 | ||
333 | list_del(&pdd->per_device_list); | 335 | list_del(&pdd->per_device_list); |
@@ -688,12 +690,12 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd, | |||
688 | dev = pdd->dev; | 690 | dev = pdd->dev; |
689 | 691 | ||
690 | if (drm_file) | 692 | if (drm_file) |
691 | ret = dev->kfd2kgd->acquire_process_vm( | 693 | ret = amdgpu_amdkfd_gpuvm_acquire_process_vm( |
692 | dev->kgd, drm_file, p->pasid, | 694 | dev->kgd, drm_file, p->pasid, |
693 | &pdd->vm, &p->kgd_process_info, &p->ef); | 695 | &pdd->vm, &p->kgd_process_info, &p->ef); |
694 | else | 696 | else |
695 | ret = dev->kfd2kgd->create_process_vm( | 697 | ret = amdgpu_amdkfd_gpuvm_create_process_vm(dev->kgd, p->pasid, |
696 | dev->kgd, p->pasid, &pdd->vm, &p->kgd_process_info, &p->ef); | 698 | &pdd->vm, &p->kgd_process_info, &p->ef); |
697 | if (ret) { | 699 | if (ret) { |
698 | pr_err("Failed to create process VM object\n"); | 700 | pr_err("Failed to create process VM object\n"); |
699 | return ret; | 701 | return ret; |
@@ -714,7 +716,7 @@ err_init_cwsr: | |||
714 | err_reserve_ib_mem: | 716 | err_reserve_ib_mem: |
715 | kfd_process_device_free_bos(pdd); | 717 | kfd_process_device_free_bos(pdd); |
716 | if (!drm_file) | 718 | if (!drm_file) |
717 | dev->kfd2kgd->destroy_process_vm(dev->kgd, pdd->vm); | 719 | amdgpu_amdkfd_gpuvm_destroy_process_vm(dev->kgd, pdd->vm); |
718 | pdd->vm = NULL; | 720 | pdd->vm = NULL; |
719 | 721 | ||
720 | return ret; | 722 | return ret; |
@@ -972,7 +974,7 @@ static void restore_process_worker(struct work_struct *work) | |||
972 | */ | 974 | */ |
973 | 975 | ||
974 | p->last_restore_timestamp = get_jiffies_64(); | 976 | p->last_restore_timestamp = get_jiffies_64(); |
975 | ret = pdd->dev->kfd2kgd->restore_process_bos(p->kgd_process_info, | 977 | ret = amdgpu_amdkfd_gpuvm_restore_process_bos(p->kgd_process_info, |
976 | &p->ef); | 978 | &p->ef); |
977 | if (ret) { | 979 | if (ret) { |
978 | pr_debug("Failed to restore BOs of pasid %d, retry after %d ms\n", | 980 | pr_debug("Failed to restore BOs of pasid %d, retry after %d ms\n", |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index e3843c5929ed..c73b4ff61f99 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "kfd_topology.h" | 36 | #include "kfd_topology.h" |
37 | #include "kfd_device_queue_manager.h" | 37 | #include "kfd_device_queue_manager.h" |
38 | #include "kfd_iommu.h" | 38 | #include "kfd_iommu.h" |
39 | #include "amdgpu_amdkfd.h" | ||
39 | 40 | ||
40 | /* topology_device_list - Master list of all topology devices */ | 41 | /* topology_device_list - Master list of all topology devices */ |
41 | static struct list_head topology_device_list; | 42 | static struct list_head topology_device_list; |
@@ -1052,7 +1053,7 @@ static uint32_t kfd_generate_gpu_id(struct kfd_dev *gpu) | |||
1052 | if (!gpu) | 1053 | if (!gpu) |
1053 | return 0; | 1054 | return 0; |
1054 | 1055 | ||
1055 | gpu->kfd2kgd->get_local_mem_info(gpu->kgd, &local_mem_info); | 1056 | amdgpu_amdkfd_get_local_mem_info(gpu->kgd, &local_mem_info); |
1056 | 1057 | ||
1057 | local_mem_size = local_mem_info.local_mem_size_private + | 1058 | local_mem_size = local_mem_info.local_mem_size_private + |
1058 | local_mem_info.local_mem_size_public; | 1059 | local_mem_info.local_mem_size_public; |
@@ -1118,8 +1119,7 @@ static void kfd_fill_mem_clk_max_info(struct kfd_topology_device *dev) | |||
1118 | * for APUs - If CRAT from ACPI reports more than one bank, then | 1119 | * for APUs - If CRAT from ACPI reports more than one bank, then |
1119 | * all the banks will report the same mem_clk_max information | 1120 | * all the banks will report the same mem_clk_max information |
1120 | */ | 1121 | */ |
1121 | dev->gpu->kfd2kgd->get_local_mem_info(dev->gpu->kgd, | 1122 | amdgpu_amdkfd_get_local_mem_info(dev->gpu->kgd, &local_mem_info); |
1122 | &local_mem_info); | ||
1123 | 1123 | ||
1124 | list_for_each_entry(mem, &dev->mem_props, list) | 1124 | list_for_each_entry(mem, &dev->mem_props, list) |
1125 | mem->mem_clk_max = local_mem_info.mem_clk_max; | 1125 | mem->mem_clk_max = local_mem_info.mem_clk_max; |
@@ -1240,7 +1240,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu) | |||
1240 | * needed for the topology | 1240 | * needed for the topology |
1241 | */ | 1241 | */ |
1242 | 1242 | ||
1243 | dev->gpu->kfd2kgd->get_cu_info(dev->gpu->kgd, &cu_info); | 1243 | amdgpu_amdkfd_get_cu_info(dev->gpu->kgd, &cu_info); |
1244 | dev->node_props.simd_arrays_per_engine = | 1244 | dev->node_props.simd_arrays_per_engine = |
1245 | cu_info.num_shader_arrays_per_engine; | 1245 | cu_info.num_shader_arrays_per_engine; |
1246 | 1246 | ||
@@ -1249,7 +1249,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu) | |||
1249 | dev->node_props.location_id = PCI_DEVID(gpu->pdev->bus->number, | 1249 | dev->node_props.location_id = PCI_DEVID(gpu->pdev->bus->number, |
1250 | gpu->pdev->devfn); | 1250 | gpu->pdev->devfn); |
1251 | dev->node_props.max_engine_clk_fcompute = | 1251 | dev->node_props.max_engine_clk_fcompute = |
1252 | dev->gpu->kfd2kgd->get_max_engine_clock_in_mhz(dev->gpu->kgd); | 1252 | amdgpu_amdkfd_get_max_engine_clock_in_mhz(dev->gpu->kgd); |
1253 | dev->node_props.max_engine_clk_ccompute = | 1253 | dev->node_props.max_engine_clk_ccompute = |
1254 | cpufreq_quick_get_max(0) / 1000; | 1254 | cpufreq_quick_get_max(0) / 1000; |
1255 | dev->node_props.drm_render_minor = | 1255 | dev->node_props.drm_render_minor = |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index dd688cfed6aa..aa43bb253ea2 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | |||
@@ -76,6 +76,16 @@ | |||
76 | #define FIRMWARE_RAVEN_DMCU "amdgpu/raven_dmcu.bin" | 76 | #define FIRMWARE_RAVEN_DMCU "amdgpu/raven_dmcu.bin" |
77 | MODULE_FIRMWARE(FIRMWARE_RAVEN_DMCU); | 77 | MODULE_FIRMWARE(FIRMWARE_RAVEN_DMCU); |
78 | 78 | ||
79 | /** | ||
80 | * DOC: overview | ||
81 | * | ||
82 | * The AMDgpu display manager, **amdgpu_dm** (or even simpler, | ||
83 | * **dm**) sits between DRM and DC. It acts as a liason, converting DRM | ||
84 | * requests into DC requests, and DC responses into DRM responses. | ||
85 | * | ||
86 | * The root control structure is &struct amdgpu_display_manager. | ||
87 | */ | ||
88 | |||
79 | /* basic init/fini API */ | 89 | /* basic init/fini API */ |
80 | static int amdgpu_dm_init(struct amdgpu_device *adev); | 90 | static int amdgpu_dm_init(struct amdgpu_device *adev); |
81 | static void amdgpu_dm_fini(struct amdgpu_device *adev); | 91 | static void amdgpu_dm_fini(struct amdgpu_device *adev); |
@@ -95,7 +105,7 @@ static void | |||
95 | amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector); | 105 | amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector); |
96 | 106 | ||
97 | static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, | 107 | static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, |
98 | struct amdgpu_plane *aplane, | 108 | struct drm_plane *plane, |
99 | unsigned long possible_crtcs); | 109 | unsigned long possible_crtcs); |
100 | static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, | 110 | static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, |
101 | struct drm_plane *plane, | 111 | struct drm_plane *plane, |
@@ -379,11 +389,6 @@ static void amdgpu_dm_fbc_init(struct drm_connector *connector) | |||
379 | 389 | ||
380 | } | 390 | } |
381 | 391 | ||
382 | /* | ||
383 | * Init display KMS | ||
384 | * | ||
385 | * Returns 0 on success | ||
386 | */ | ||
387 | static int amdgpu_dm_init(struct amdgpu_device *adev) | 392 | static int amdgpu_dm_init(struct amdgpu_device *adev) |
388 | { | 393 | { |
389 | struct dc_init_data init_data; | 394 | struct dc_init_data init_data; |
@@ -429,6 +434,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) | |||
429 | adev->asic_type < CHIP_RAVEN) | 434 | adev->asic_type < CHIP_RAVEN) |
430 | init_data.flags.gpu_vm_support = true; | 435 | init_data.flags.gpu_vm_support = true; |
431 | 436 | ||
437 | if (amdgpu_dc_feature_mask & DC_FBC_MASK) | ||
438 | init_data.flags.fbc_support = true; | ||
439 | |||
432 | /* Display Core create. */ | 440 | /* Display Core create. */ |
433 | adev->dm.dc = dc_create(&init_data); | 441 | adev->dm.dc = dc_create(&init_data); |
434 | 442 | ||
@@ -660,6 +668,26 @@ static void s3_handle_mst(struct drm_device *dev, bool suspend) | |||
660 | drm_modeset_unlock(&dev->mode_config.connection_mutex); | 668 | drm_modeset_unlock(&dev->mode_config.connection_mutex); |
661 | } | 669 | } |
662 | 670 | ||
671 | /** | ||
672 | * dm_hw_init() - Initialize DC device | ||
673 | * @handle: The base driver device containing the amdpgu_dm device. | ||
674 | * | ||
675 | * Initialize the &struct amdgpu_display_manager device. This involves calling | ||
676 | * the initializers of each DM component, then populating the struct with them. | ||
677 | * | ||
678 | * Although the function implies hardware initialization, both hardware and | ||
679 | * software are initialized here. Splitting them out to their relevant init | ||
680 | * hooks is a future TODO item. | ||
681 | * | ||
682 | * Some notable things that are initialized here: | ||
683 | * | ||
684 | * - Display Core, both software and hardware | ||
685 | * - DC modules that we need (freesync and color management) | ||
686 | * - DRM software states | ||
687 | * - Interrupt sources and handlers | ||
688 | * - Vblank support | ||
689 | * - Debug FS entries, if enabled | ||
690 | */ | ||
663 | static int dm_hw_init(void *handle) | 691 | static int dm_hw_init(void *handle) |
664 | { | 692 | { |
665 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 693 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
@@ -670,6 +698,14 @@ static int dm_hw_init(void *handle) | |||
670 | return 0; | 698 | return 0; |
671 | } | 699 | } |
672 | 700 | ||
701 | /** | ||
702 | * dm_hw_fini() - Teardown DC device | ||
703 | * @handle: The base driver device containing the amdpgu_dm device. | ||
704 | * | ||
705 | * Teardown components within &struct amdgpu_display_manager that require | ||
706 | * cleanup. This involves cleaning up the DRM device, DC, and any modules that | ||
707 | * were loaded. Also flush IRQ workqueues and disable them. | ||
708 | */ | ||
673 | static int dm_hw_fini(void *handle) | 709 | static int dm_hw_fini(void *handle) |
674 | { | 710 | { |
675 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 711 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
@@ -895,6 +931,16 @@ static int dm_resume(void *handle) | |||
895 | return ret; | 931 | return ret; |
896 | } | 932 | } |
897 | 933 | ||
934 | /** | ||
935 | * DOC: DM Lifecycle | ||
936 | * | ||
937 | * DM (and consequently DC) is registered in the amdgpu base driver as a IP | ||
938 | * block. When CONFIG_DRM_AMD_DC is enabled, the DM device IP block is added to | ||
939 | * the base driver's device list to be initialized and torn down accordingly. | ||
940 | * | ||
941 | * The functions to do so are provided as hooks in &struct amd_ip_funcs. | ||
942 | */ | ||
943 | |||
898 | static const struct amd_ip_funcs amdgpu_dm_funcs = { | 944 | static const struct amd_ip_funcs amdgpu_dm_funcs = { |
899 | .name = "dm", | 945 | .name = "dm", |
900 | .early_init = dm_early_init, | 946 | .early_init = dm_early_init, |
@@ -962,6 +1008,12 @@ dm_atomic_state_alloc_free(struct drm_atomic_state *state) | |||
962 | kfree(dm_state); | 1008 | kfree(dm_state); |
963 | } | 1009 | } |
964 | 1010 | ||
1011 | /** | ||
1012 | * DOC: atomic | ||
1013 | * | ||
1014 | * *WIP* | ||
1015 | */ | ||
1016 | |||
965 | static const struct drm_mode_config_funcs amdgpu_dm_mode_funcs = { | 1017 | static const struct drm_mode_config_funcs amdgpu_dm_mode_funcs = { |
966 | .fb_create = amdgpu_display_user_framebuffer_create, | 1018 | .fb_create = amdgpu_display_user_framebuffer_create, |
967 | .output_poll_changed = drm_fb_helper_output_poll_changed, | 1019 | .output_poll_changed = drm_fb_helper_output_poll_changed, |
@@ -1524,15 +1576,23 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd) | |||
1524 | { | 1576 | { |
1525 | struct amdgpu_display_manager *dm = bl_get_data(bd); | 1577 | struct amdgpu_display_manager *dm = bl_get_data(bd); |
1526 | 1578 | ||
1579 | /* backlight_pwm_u16_16 parameter is in unsigned 32 bit, 16 bit integer | ||
1580 | * and 16 bit fractional, where 1.0 is max backlight value. | ||
1581 | * bd->props.brightness is 8 bit format and needs to be converted by | ||
1582 | * scaling via copy lower byte to upper byte of 16 bit value. | ||
1583 | */ | ||
1584 | uint32_t brightness = bd->props.brightness * 0x101; | ||
1585 | |||
1527 | /* | 1586 | /* |
1528 | * PWM interperts 0 as 100% rather than 0% because of HW | 1587 | * PWM interperts 0 as 100% rather than 0% because of HW |
1529 | * limitation for level 0.So limiting minimum brightness level | 1588 | * limitation for level 0. So limiting minimum brightness level |
1530 | * to 1. | 1589 | * to 1. |
1531 | */ | 1590 | */ |
1532 | if (bd->props.brightness < 1) | 1591 | if (bd->props.brightness < 1) |
1533 | return 1; | 1592 | brightness = 0x101; |
1593 | |||
1534 | if (dc_link_set_backlight_level(dm->backlight_link, | 1594 | if (dc_link_set_backlight_level(dm->backlight_link, |
1535 | bd->props.brightness, 0, 0)) | 1595 | brightness, 0, 0)) |
1536 | return 0; | 1596 | return 0; |
1537 | else | 1597 | else |
1538 | return 1; | 1598 | return 1; |
@@ -1584,18 +1644,18 @@ static int initialize_plane(struct amdgpu_display_manager *dm, | |||
1584 | struct amdgpu_mode_info *mode_info, | 1644 | struct amdgpu_mode_info *mode_info, |
1585 | int plane_id) | 1645 | int plane_id) |
1586 | { | 1646 | { |
1587 | struct amdgpu_plane *plane; | 1647 | struct drm_plane *plane; |
1588 | unsigned long possible_crtcs; | 1648 | unsigned long possible_crtcs; |
1589 | int ret = 0; | 1649 | int ret = 0; |
1590 | 1650 | ||
1591 | plane = kzalloc(sizeof(struct amdgpu_plane), GFP_KERNEL); | 1651 | plane = kzalloc(sizeof(struct drm_plane), GFP_KERNEL); |
1592 | mode_info->planes[plane_id] = plane; | 1652 | mode_info->planes[plane_id] = plane; |
1593 | 1653 | ||
1594 | if (!plane) { | 1654 | if (!plane) { |
1595 | DRM_ERROR("KMS: Failed to allocate plane\n"); | 1655 | DRM_ERROR("KMS: Failed to allocate plane\n"); |
1596 | return -ENOMEM; | 1656 | return -ENOMEM; |
1597 | } | 1657 | } |
1598 | plane->base.type = mode_info->plane_type[plane_id]; | 1658 | plane->type = mode_info->plane_type[plane_id]; |
1599 | 1659 | ||
1600 | /* | 1660 | /* |
1601 | * HACK: IGT tests expect that each plane can only have | 1661 | * HACK: IGT tests expect that each plane can only have |
@@ -1686,7 +1746,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) | |||
1686 | } | 1746 | } |
1687 | 1747 | ||
1688 | for (i = 0; i < dm->dc->caps.max_streams; i++) | 1748 | for (i = 0; i < dm->dc->caps.max_streams; i++) |
1689 | if (amdgpu_dm_crtc_init(dm, &mode_info->planes[i]->base, i)) { | 1749 | if (amdgpu_dm_crtc_init(dm, mode_info->planes[i], i)) { |
1690 | DRM_ERROR("KMS: Failed to initialize crtc\n"); | 1750 | DRM_ERROR("KMS: Failed to initialize crtc\n"); |
1691 | goto fail; | 1751 | goto fail; |
1692 | } | 1752 | } |
@@ -2707,18 +2767,11 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, | |||
2707 | drm_connector = &aconnector->base; | 2767 | drm_connector = &aconnector->base; |
2708 | 2768 | ||
2709 | if (!aconnector->dc_sink) { | 2769 | if (!aconnector->dc_sink) { |
2710 | /* | 2770 | if (!aconnector->mst_port) { |
2711 | * Create dc_sink when necessary to MST | 2771 | sink = create_fake_sink(aconnector); |
2712 | * Don't apply fake_sink to MST | 2772 | if (!sink) |
2713 | */ | 2773 | return stream; |
2714 | if (aconnector->mst_port) { | ||
2715 | dm_dp_mst_dc_sink_create(drm_connector); | ||
2716 | return stream; | ||
2717 | } | 2774 | } |
2718 | |||
2719 | sink = create_fake_sink(aconnector); | ||
2720 | if (!sink) | ||
2721 | return stream; | ||
2722 | } else { | 2775 | } else { |
2723 | sink = aconnector->dc_sink; | 2776 | sink = aconnector->dc_sink; |
2724 | } | 2777 | } |
@@ -3307,7 +3360,7 @@ void dm_drm_plane_destroy_state(struct drm_plane *plane, | |||
3307 | static const struct drm_plane_funcs dm_plane_funcs = { | 3360 | static const struct drm_plane_funcs dm_plane_funcs = { |
3308 | .update_plane = drm_atomic_helper_update_plane, | 3361 | .update_plane = drm_atomic_helper_update_plane, |
3309 | .disable_plane = drm_atomic_helper_disable_plane, | 3362 | .disable_plane = drm_atomic_helper_disable_plane, |
3310 | .destroy = drm_plane_cleanup, | 3363 | .destroy = drm_primary_helper_destroy, |
3311 | .reset = dm_drm_plane_reset, | 3364 | .reset = dm_drm_plane_reset, |
3312 | .atomic_duplicate_state = dm_drm_plane_duplicate_state, | 3365 | .atomic_duplicate_state = dm_drm_plane_duplicate_state, |
3313 | .atomic_destroy_state = dm_drm_plane_destroy_state, | 3366 | .atomic_destroy_state = dm_drm_plane_destroy_state, |
@@ -3468,49 +3521,49 @@ static const u32 cursor_formats[] = { | |||
3468 | }; | 3521 | }; |
3469 | 3522 | ||
3470 | static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, | 3523 | static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, |
3471 | struct amdgpu_plane *aplane, | 3524 | struct drm_plane *plane, |
3472 | unsigned long possible_crtcs) | 3525 | unsigned long possible_crtcs) |
3473 | { | 3526 | { |
3474 | int res = -EPERM; | 3527 | int res = -EPERM; |
3475 | 3528 | ||
3476 | switch (aplane->base.type) { | 3529 | switch (plane->type) { |
3477 | case DRM_PLANE_TYPE_PRIMARY: | 3530 | case DRM_PLANE_TYPE_PRIMARY: |
3478 | res = drm_universal_plane_init( | 3531 | res = drm_universal_plane_init( |
3479 | dm->adev->ddev, | 3532 | dm->adev->ddev, |
3480 | &aplane->base, | 3533 | plane, |
3481 | possible_crtcs, | 3534 | possible_crtcs, |
3482 | &dm_plane_funcs, | 3535 | &dm_plane_funcs, |
3483 | rgb_formats, | 3536 | rgb_formats, |
3484 | ARRAY_SIZE(rgb_formats), | 3537 | ARRAY_SIZE(rgb_formats), |
3485 | NULL, aplane->base.type, NULL); | 3538 | NULL, plane->type, NULL); |
3486 | break; | 3539 | break; |
3487 | case DRM_PLANE_TYPE_OVERLAY: | 3540 | case DRM_PLANE_TYPE_OVERLAY: |
3488 | res = drm_universal_plane_init( | 3541 | res = drm_universal_plane_init( |
3489 | dm->adev->ddev, | 3542 | dm->adev->ddev, |
3490 | &aplane->base, | 3543 | plane, |
3491 | possible_crtcs, | 3544 | possible_crtcs, |
3492 | &dm_plane_funcs, | 3545 | &dm_plane_funcs, |
3493 | yuv_formats, | 3546 | yuv_formats, |
3494 | ARRAY_SIZE(yuv_formats), | 3547 | ARRAY_SIZE(yuv_formats), |
3495 | NULL, aplane->base.type, NULL); | 3548 | NULL, plane->type, NULL); |
3496 | break; | 3549 | break; |
3497 | case DRM_PLANE_TYPE_CURSOR: | 3550 | case DRM_PLANE_TYPE_CURSOR: |
3498 | res = drm_universal_plane_init( | 3551 | res = drm_universal_plane_init( |
3499 | dm->adev->ddev, | 3552 | dm->adev->ddev, |
3500 | &aplane->base, | 3553 | plane, |
3501 | possible_crtcs, | 3554 | possible_crtcs, |
3502 | &dm_plane_funcs, | 3555 | &dm_plane_funcs, |
3503 | cursor_formats, | 3556 | cursor_formats, |
3504 | ARRAY_SIZE(cursor_formats), | 3557 | ARRAY_SIZE(cursor_formats), |
3505 | NULL, aplane->base.type, NULL); | 3558 | NULL, plane->type, NULL); |
3506 | break; | 3559 | break; |
3507 | } | 3560 | } |
3508 | 3561 | ||
3509 | drm_plane_helper_add(&aplane->base, &dm_plane_helper_funcs); | 3562 | drm_plane_helper_add(plane, &dm_plane_helper_funcs); |
3510 | 3563 | ||
3511 | /* Create (reset) the plane state */ | 3564 | /* Create (reset) the plane state */ |
3512 | if (aplane->base.funcs->reset) | 3565 | if (plane->funcs->reset) |
3513 | aplane->base.funcs->reset(&aplane->base); | 3566 | plane->funcs->reset(plane); |
3514 | 3567 | ||
3515 | 3568 | ||
3516 | return res; | 3569 | return res; |
@@ -3521,7 +3574,7 @@ static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, | |||
3521 | uint32_t crtc_index) | 3574 | uint32_t crtc_index) |
3522 | { | 3575 | { |
3523 | struct amdgpu_crtc *acrtc = NULL; | 3576 | struct amdgpu_crtc *acrtc = NULL; |
3524 | struct amdgpu_plane *cursor_plane; | 3577 | struct drm_plane *cursor_plane; |
3525 | 3578 | ||
3526 | int res = -ENOMEM; | 3579 | int res = -ENOMEM; |
3527 | 3580 | ||
@@ -3529,7 +3582,7 @@ static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, | |||
3529 | if (!cursor_plane) | 3582 | if (!cursor_plane) |
3530 | goto fail; | 3583 | goto fail; |
3531 | 3584 | ||
3532 | cursor_plane->base.type = DRM_PLANE_TYPE_CURSOR; | 3585 | cursor_plane->type = DRM_PLANE_TYPE_CURSOR; |
3533 | res = amdgpu_dm_plane_init(dm, cursor_plane, 0); | 3586 | res = amdgpu_dm_plane_init(dm, cursor_plane, 0); |
3534 | 3587 | ||
3535 | acrtc = kzalloc(sizeof(struct amdgpu_crtc), GFP_KERNEL); | 3588 | acrtc = kzalloc(sizeof(struct amdgpu_crtc), GFP_KERNEL); |
@@ -3540,7 +3593,7 @@ static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, | |||
3540 | dm->ddev, | 3593 | dm->ddev, |
3541 | &acrtc->base, | 3594 | &acrtc->base, |
3542 | plane, | 3595 | plane, |
3543 | &cursor_plane->base, | 3596 | cursor_plane, |
3544 | &amdgpu_dm_crtc_funcs, NULL); | 3597 | &amdgpu_dm_crtc_funcs, NULL); |
3545 | 3598 | ||
3546 | if (res) | 3599 | if (res) |
@@ -3779,12 +3832,12 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, | |||
3779 | case DRM_MODE_CONNECTOR_HDMIA: | 3832 | case DRM_MODE_CONNECTOR_HDMIA: |
3780 | aconnector->base.polled = DRM_CONNECTOR_POLL_HPD; | 3833 | aconnector->base.polled = DRM_CONNECTOR_POLL_HPD; |
3781 | aconnector->base.ycbcr_420_allowed = | 3834 | aconnector->base.ycbcr_420_allowed = |
3782 | link->link_enc->features.ycbcr420_supported ? true : false; | 3835 | link->link_enc->features.hdmi_ycbcr420_supported ? true : false; |
3783 | break; | 3836 | break; |
3784 | case DRM_MODE_CONNECTOR_DisplayPort: | 3837 | case DRM_MODE_CONNECTOR_DisplayPort: |
3785 | aconnector->base.polled = DRM_CONNECTOR_POLL_HPD; | 3838 | aconnector->base.polled = DRM_CONNECTOR_POLL_HPD; |
3786 | aconnector->base.ycbcr_420_allowed = | 3839 | aconnector->base.ycbcr_420_allowed = |
3787 | link->link_enc->features.ycbcr420_supported ? true : false; | 3840 | link->link_enc->features.dp_ycbcr420_supported ? true : false; |
3788 | break; | 3841 | break; |
3789 | case DRM_MODE_CONNECTOR_DVID: | 3842 | case DRM_MODE_CONNECTOR_DVID: |
3790 | aconnector->base.polled = DRM_CONNECTOR_POLL_HPD; | 3843 | aconnector->base.polled = DRM_CONNECTOR_POLL_HPD; |
@@ -4542,6 +4595,14 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev, | |||
4542 | /*TODO Handle EINTR, reenable IRQ*/ | 4595 | /*TODO Handle EINTR, reenable IRQ*/ |
4543 | } | 4596 | } |
4544 | 4597 | ||
4598 | /** | ||
4599 | * amdgpu_dm_atomic_commit_tail() - AMDgpu DM's commit tail implementation. | ||
4600 | * @state: The atomic state to commit | ||
4601 | * | ||
4602 | * This will tell DC to commit the constructed DC state from atomic_check, | ||
4603 | * programming the hardware. Any failures here implies a hardware failure, since | ||
4604 | * atomic check should have filtered anything non-kosher. | ||
4605 | */ | ||
4545 | static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) | 4606 | static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) |
4546 | { | 4607 | { |
4547 | struct drm_device *dev = state->dev; | 4608 | struct drm_device *dev = state->dev; |
@@ -5313,6 +5374,12 @@ enum surface_update_type dm_determine_update_type_for_commit(struct dc *dc, stru | |||
5313 | struct dc_stream_update stream_update; | 5374 | struct dc_stream_update stream_update; |
5314 | enum surface_update_type update_type = UPDATE_TYPE_FAST; | 5375 | enum surface_update_type update_type = UPDATE_TYPE_FAST; |
5315 | 5376 | ||
5377 | if (!updates || !surface) { | ||
5378 | DRM_ERROR("Plane or surface update failed to allocate"); | ||
5379 | /* Set type to FULL to avoid crashing in DC*/ | ||
5380 | update_type = UPDATE_TYPE_FULL; | ||
5381 | goto ret; | ||
5382 | } | ||
5316 | 5383 | ||
5317 | for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { | 5384 | for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { |
5318 | new_dm_crtc_state = to_dm_crtc_state(new_crtc_state); | 5385 | new_dm_crtc_state = to_dm_crtc_state(new_crtc_state); |
@@ -5388,6 +5455,31 @@ ret: | |||
5388 | return update_type; | 5455 | return update_type; |
5389 | } | 5456 | } |
5390 | 5457 | ||
5458 | /** | ||
5459 | * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM. | ||
5460 | * @dev: The DRM device | ||
5461 | * @state: The atomic state to commit | ||
5462 | * | ||
5463 | * Validate that the given atomic state is programmable by DC into hardware. | ||
5464 | * This involves constructing a &struct dc_state reflecting the new hardware | ||
5465 | * state we wish to commit, then querying DC to see if it is programmable. It's | ||
5466 | * important not to modify the existing DC state. Otherwise, atomic_check | ||
5467 | * may unexpectedly commit hardware changes. | ||
5468 | * | ||
5469 | * When validating the DC state, it's important that the right locks are | ||
5470 | * acquired. For full updates case which removes/adds/updates streams on one | ||
5471 | * CRTC while flipping on another CRTC, acquiring global lock will guarantee | ||
5472 | * that any such full update commit will wait for completion of any outstanding | ||
5473 | * flip using DRMs synchronization events. See | ||
5474 | * dm_determine_update_type_for_commit() | ||
5475 | * | ||
5476 | * Note that DM adds the affected connectors for all CRTCs in state, when that | ||
5477 | * might not seem necessary. This is because DC stream creation requires the | ||
5478 | * DC sink, which is tied to the DRM connector state. Cleaning this up should | ||
5479 | * be possible but non-trivial - a possible TODO item. | ||
5480 | * | ||
5481 | * Return: -Error code if validation failed. | ||
5482 | */ | ||
5391 | static int amdgpu_dm_atomic_check(struct drm_device *dev, | 5483 | static int amdgpu_dm_atomic_check(struct drm_device *dev, |
5392 | struct drm_atomic_state *state) | 5484 | struct drm_atomic_state *state) |
5393 | { | 5485 | { |
@@ -5490,15 +5582,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, | |||
5490 | lock_and_validation_needed = true; | 5582 | lock_and_validation_needed = true; |
5491 | } | 5583 | } |
5492 | 5584 | ||
5493 | /* | ||
5494 | * For full updates case when | ||
5495 | * removing/adding/updating streams on one CRTC while flipping | ||
5496 | * on another CRTC, | ||
5497 | * acquiring global lock will guarantee that any such full | ||
5498 | * update commit | ||
5499 | * will wait for completion of any outstanding flip using DRMs | ||
5500 | * synchronization events. | ||
5501 | */ | ||
5502 | update_type = dm_determine_update_type_for_commit(dc, state); | 5585 | update_type = dm_determine_update_type_for_commit(dc, state); |
5503 | 5586 | ||
5504 | if (overall_update_type < update_type) | 5587 | if (overall_update_type < update_type) |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 978b34a5011c..d6960644d714 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | |||
@@ -59,49 +59,100 @@ struct common_irq_params { | |||
59 | enum dc_irq_source irq_src; | 59 | enum dc_irq_source irq_src; |
60 | }; | 60 | }; |
61 | 61 | ||
62 | /** | ||
63 | * struct irq_list_head - Linked-list for low context IRQ handlers. | ||
64 | * | ||
65 | * @head: The list_head within &struct handler_data | ||
66 | * @work: A work_struct containing the deferred handler work | ||
67 | */ | ||
62 | struct irq_list_head { | 68 | struct irq_list_head { |
63 | struct list_head head; | 69 | struct list_head head; |
64 | /* In case this interrupt needs post-processing, 'work' will be queued*/ | 70 | /* In case this interrupt needs post-processing, 'work' will be queued*/ |
65 | struct work_struct work; | 71 | struct work_struct work; |
66 | }; | 72 | }; |
67 | 73 | ||
74 | /** | ||
75 | * struct dm_compressor_info - Buffer info used by frame buffer compression | ||
76 | * @cpu_addr: MMIO cpu addr | ||
77 | * @bo_ptr: Pointer to the buffer object | ||
78 | * @gpu_addr: MMIO gpu addr | ||
79 | */ | ||
68 | struct dm_comressor_info { | 80 | struct dm_comressor_info { |
69 | void *cpu_addr; | 81 | void *cpu_addr; |
70 | struct amdgpu_bo *bo_ptr; | 82 | struct amdgpu_bo *bo_ptr; |
71 | uint64_t gpu_addr; | 83 | uint64_t gpu_addr; |
72 | }; | 84 | }; |
73 | 85 | ||
86 | /** | ||
87 | * struct amdgpu_display_manager - Central amdgpu display manager device | ||
88 | * | ||
89 | * @dc: Display Core control structure | ||
90 | * @adev: AMDGPU base driver structure | ||
91 | * @ddev: DRM base driver structure | ||
92 | * @display_indexes_num: Max number of display streams supported | ||
93 | * @irq_handler_list_table_lock: Synchronizes access to IRQ tables | ||
94 | * @backlight_dev: Backlight control device | ||
95 | * @cached_state: Caches device atomic state for suspend/resume | ||
96 | * @compressor: Frame buffer compression buffer. See &struct dm_comressor_info | ||
97 | */ | ||
74 | struct amdgpu_display_manager { | 98 | struct amdgpu_display_manager { |
99 | |||
75 | struct dc *dc; | 100 | struct dc *dc; |
101 | |||
102 | /** | ||
103 | * @cgs_device: | ||
104 | * | ||
105 | * The Common Graphics Services device. It provides an interface for | ||
106 | * accessing registers. | ||
107 | */ | ||
76 | struct cgs_device *cgs_device; | 108 | struct cgs_device *cgs_device; |
77 | 109 | ||
78 | struct amdgpu_device *adev; /*AMD base driver*/ | 110 | struct amdgpu_device *adev; |
79 | struct drm_device *ddev; /*DRM base driver*/ | 111 | struct drm_device *ddev; |
80 | u16 display_indexes_num; | 112 | u16 display_indexes_num; |
81 | 113 | ||
82 | /* | 114 | /** |
83 | * 'irq_source_handler_table' holds a list of handlers | 115 | * @irq_handler_list_low_tab: |
84 | * per (DAL) IRQ source. | 116 | * |
117 | * Low priority IRQ handler table. | ||
85 | * | 118 | * |
86 | * Each IRQ source may need to be handled at different contexts. | 119 | * It is a n*m table consisting of n IRQ sources, and m handlers per IRQ |
87 | * By 'context' we mean, for example: | 120 | * source. Low priority IRQ handlers are deferred to a workqueue to be |
88 | * - The ISR context, which is the direct interrupt handler. | 121 | * processed. Hence, they can sleep. |
89 | * - The 'deferred' context - this is the post-processing of the | ||
90 | * interrupt, but at a lower priority. | ||
91 | * | 122 | * |
92 | * Note that handlers are called in the same order as they were | 123 | * Note that handlers are called in the same order as they were |
93 | * registered (FIFO). | 124 | * registered (FIFO). |
94 | */ | 125 | */ |
95 | struct irq_list_head irq_handler_list_low_tab[DAL_IRQ_SOURCES_NUMBER]; | 126 | struct irq_list_head irq_handler_list_low_tab[DAL_IRQ_SOURCES_NUMBER]; |
127 | |||
128 | /** | ||
129 | * @irq_handler_list_high_tab: | ||
130 | * | ||
131 | * High priority IRQ handler table. | ||
132 | * | ||
133 | * It is a n*m table, same as &irq_handler_list_low_tab. However, | ||
134 | * handlers in this table are not deferred and are called immediately. | ||
135 | */ | ||
96 | struct list_head irq_handler_list_high_tab[DAL_IRQ_SOURCES_NUMBER]; | 136 | struct list_head irq_handler_list_high_tab[DAL_IRQ_SOURCES_NUMBER]; |
97 | 137 | ||
138 | /** | ||
139 | * @pflip_params: | ||
140 | * | ||
141 | * Page flip IRQ parameters, passed to registered handlers when | ||
142 | * triggered. | ||
143 | */ | ||
98 | struct common_irq_params | 144 | struct common_irq_params |
99 | pflip_params[DC_IRQ_SOURCE_PFLIP_LAST - DC_IRQ_SOURCE_PFLIP_FIRST + 1]; | 145 | pflip_params[DC_IRQ_SOURCE_PFLIP_LAST - DC_IRQ_SOURCE_PFLIP_FIRST + 1]; |
100 | 146 | ||
147 | /** | ||
148 | * @vblank_params: | ||
149 | * | ||
150 | * Vertical blanking IRQ parameters, passed to registered handlers when | ||
151 | * triggered. | ||
152 | */ | ||
101 | struct common_irq_params | 153 | struct common_irq_params |
102 | vblank_params[DC_IRQ_SOURCE_VBLANK6 - DC_IRQ_SOURCE_VBLANK1 + 1]; | 154 | vblank_params[DC_IRQ_SOURCE_VBLANK6 - DC_IRQ_SOURCE_VBLANK1 + 1]; |
103 | 155 | ||
104 | /* this spin lock synchronizes access to 'irq_handler_list_table' */ | ||
105 | spinlock_t irq_handler_list_table_lock; | 156 | spinlock_t irq_handler_list_table_lock; |
106 | 157 | ||
107 | struct backlight_device *backlight_dev; | 158 | struct backlight_device *backlight_dev; |
@@ -110,9 +161,6 @@ struct amdgpu_display_manager { | |||
110 | 161 | ||
111 | struct mod_freesync *freesync_module; | 162 | struct mod_freesync *freesync_module; |
112 | 163 | ||
113 | /** | ||
114 | * Caches device atomic state for suspend/resume | ||
115 | */ | ||
116 | struct drm_atomic_state *cached_state; | 164 | struct drm_atomic_state *cached_state; |
117 | 165 | ||
118 | struct dm_comressor_info compressor; | 166 | struct dm_comressor_info compressor; |
@@ -160,8 +208,6 @@ struct amdgpu_dm_connector { | |||
160 | struct mutex hpd_lock; | 208 | struct mutex hpd_lock; |
161 | 209 | ||
162 | bool fake_enable; | 210 | bool fake_enable; |
163 | |||
164 | bool mst_connected; | ||
165 | }; | 211 | }; |
166 | 212 | ||
167 | #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base) | 213 | #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base) |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c index be19e6861189..216e48cec716 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | |||
@@ -164,7 +164,7 @@ int amdgpu_dm_set_regamma_lut(struct dm_crtc_state *crtc) | |||
164 | */ | 164 | */ |
165 | stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS; | 165 | stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS; |
166 | ret = mod_color_calculate_regamma_params(stream->out_transfer_func, | 166 | ret = mod_color_calculate_regamma_params(stream->out_transfer_func, |
167 | gamma, true, adev->asic_type <= CHIP_RAVEN); | 167 | gamma, true, adev->asic_type <= CHIP_RAVEN, NULL); |
168 | dc_gamma_release(&gamma); | 168 | dc_gamma_release(&gamma); |
169 | if (!ret) { | 169 | if (!ret) { |
170 | stream->out_transfer_func->type = old_type; | 170 | stream->out_transfer_func->type = old_type; |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c index 01fc5717b657..f088ac585978 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | |||
@@ -75,6 +75,11 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) | |||
75 | return -EINVAL; | 75 | return -EINVAL; |
76 | } | 76 | } |
77 | 77 | ||
78 | if (!stream_state) { | ||
79 | DRM_ERROR("No stream state for CRTC%d\n", crtc->index); | ||
80 | return -EINVAL; | ||
81 | } | ||
82 | |||
78 | /* When enabling CRC, we should also disable dithering. */ | 83 | /* When enabling CRC, we should also disable dithering. */ |
79 | if (source == AMDGPU_DM_PIPE_CRC_SOURCE_AUTO) { | 84 | if (source == AMDGPU_DM_PIPE_CRC_SOURCE_AUTO) { |
80 | if (dc_stream_configure_crc(stream_state->ctx->dc, | 85 | if (dc_stream_configure_crc(stream_state->ctx->dc, |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c index a212178f2edc..cd10f77cdeb0 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | |||
@@ -32,16 +32,55 @@ | |||
32 | #include "amdgpu_dm.h" | 32 | #include "amdgpu_dm.h" |
33 | #include "amdgpu_dm_irq.h" | 33 | #include "amdgpu_dm_irq.h" |
34 | 34 | ||
35 | /** | ||
36 | * DOC: overview | ||
37 | * | ||
38 | * DM provides another layer of IRQ management on top of what the base driver | ||
39 | * already provides. This is something that could be cleaned up, and is a | ||
40 | * future TODO item. | ||
41 | * | ||
42 | * The base driver provides IRQ source registration with DRM, handler | ||
43 | * registration into the base driver's IRQ table, and a handler callback | ||
44 | * amdgpu_irq_handler(), with which DRM calls on interrupts. This generic | ||
45 | * handler looks up the IRQ table, and calls the respective | ||
46 | * &amdgpu_irq_src_funcs.process hookups. | ||
47 | * | ||
48 | * What DM provides on top are two IRQ tables specifically for top-half and | ||
49 | * bottom-half IRQ handling, with the bottom-half implementing workqueues: | ||
50 | * | ||
51 | * - &amdgpu_display_manager.irq_handler_list_high_tab | ||
52 | * - &amdgpu_display_manager.irq_handler_list_low_tab | ||
53 | * | ||
54 | * They override the base driver's IRQ table, and the effect can be seen | ||
55 | * in the hooks that DM provides for &amdgpu_irq_src_funcs.process. They | ||
56 | * are all set to the DM generic handler amdgpu_dm_irq_handler(), which looks up | ||
57 | * DM's IRQ tables. However, in order for base driver to recognize this hook, DM | ||
58 | * still needs to register the IRQ with the base driver. See | ||
59 | * dce110_register_irq_handlers() and dcn10_register_irq_handlers(). | ||
60 | * | ||
61 | * To expose DC's hardware interrupt toggle to the base driver, DM implements | ||
62 | * &amdgpu_irq_src_funcs.set hooks. Base driver calls it through | ||
63 | * amdgpu_irq_update() to enable or disable the interrupt. | ||
64 | */ | ||
65 | |||
35 | /****************************************************************************** | 66 | /****************************************************************************** |
36 | * Private declarations. | 67 | * Private declarations. |
37 | *****************************************************************************/ | 68 | *****************************************************************************/ |
38 | 69 | ||
70 | /** | ||
71 | * struct amdgpu_dm_irq_handler_data - Data for DM interrupt handlers. | ||
72 | * | ||
73 | * @list: Linked list entry referencing the next/previous handler | ||
74 | * @handler: Handler function | ||
75 | * @handler_arg: Argument passed to the handler when triggered | ||
76 | * @dm: DM which this handler belongs to | ||
77 | * @irq_source: DC interrupt source that this handler is registered for | ||
78 | */ | ||
39 | struct amdgpu_dm_irq_handler_data { | 79 | struct amdgpu_dm_irq_handler_data { |
40 | struct list_head list; | 80 | struct list_head list; |
41 | interrupt_handler handler; | 81 | interrupt_handler handler; |
42 | void *handler_arg; | 82 | void *handler_arg; |
43 | 83 | ||
44 | /* DM which this handler belongs to */ | ||
45 | struct amdgpu_display_manager *dm; | 84 | struct amdgpu_display_manager *dm; |
46 | /* DAL irq source which registered for this interrupt. */ | 85 | /* DAL irq source which registered for this interrupt. */ |
47 | enum dc_irq_source irq_source; | 86 | enum dc_irq_source irq_source; |
@@ -68,7 +107,7 @@ static void init_handler_common_data(struct amdgpu_dm_irq_handler_data *hcd, | |||
68 | } | 107 | } |
69 | 108 | ||
70 | /** | 109 | /** |
71 | * dm_irq_work_func - Handle an IRQ outside of the interrupt handler proper. | 110 | * dm_irq_work_func() - Handle an IRQ outside of the interrupt handler proper. |
72 | * | 111 | * |
73 | * @work: work struct | 112 | * @work: work struct |
74 | */ | 113 | */ |
@@ -99,8 +138,8 @@ static void dm_irq_work_func(struct work_struct *work) | |||
99 | * (The most common use is HPD interrupt) */ | 138 | * (The most common use is HPD interrupt) */ |
100 | } | 139 | } |
101 | 140 | ||
102 | /** | 141 | /* |
103 | * Remove a handler and return a pointer to hander list from which the | 142 | * Remove a handler and return a pointer to handler list from which the |
104 | * handler was removed. | 143 | * handler was removed. |
105 | */ | 144 | */ |
106 | static struct list_head *remove_irq_handler(struct amdgpu_device *adev, | 145 | static struct list_head *remove_irq_handler(struct amdgpu_device *adev, |
@@ -203,6 +242,24 @@ static bool validate_irq_unregistration_params(enum dc_irq_source irq_source, | |||
203 | * Note: caller is responsible for input validation. | 242 | * Note: caller is responsible for input validation. |
204 | *****************************************************************************/ | 243 | *****************************************************************************/ |
205 | 244 | ||
245 | /** | ||
246 | * amdgpu_dm_irq_register_interrupt() - Register a handler within DM. | ||
247 | * @adev: The base driver device containing the DM device. | ||
248 | * @int_params: Interrupt parameters containing the source, and handler context | ||
249 | * @ih: Function pointer to the interrupt handler to register | ||
250 | * @handler_args: Arguments passed to the handler when the interrupt occurs | ||
251 | * | ||
252 | * Register an interrupt handler for the given IRQ source, under the given | ||
253 | * context. The context can either be high or low. High context handlers are | ||
254 | * executed directly within ISR context, while low context is executed within a | ||
255 | * workqueue, thereby allowing operations that sleep. | ||
256 | * | ||
257 | * Registered handlers are called in a FIFO manner, i.e. the most recently | ||
258 | * registered handler will be called first. | ||
259 | * | ||
260 | * Return: Handler data &struct amdgpu_dm_irq_handler_data containing the IRQ | ||
261 | * source, handler function, and args | ||
262 | */ | ||
206 | void *amdgpu_dm_irq_register_interrupt(struct amdgpu_device *adev, | 263 | void *amdgpu_dm_irq_register_interrupt(struct amdgpu_device *adev, |
207 | struct dc_interrupt_params *int_params, | 264 | struct dc_interrupt_params *int_params, |
208 | void (*ih)(void *), | 265 | void (*ih)(void *), |
@@ -261,6 +318,15 @@ void *amdgpu_dm_irq_register_interrupt(struct amdgpu_device *adev, | |||
261 | return handler_data; | 318 | return handler_data; |
262 | } | 319 | } |
263 | 320 | ||
321 | /** | ||
322 | * amdgpu_dm_irq_unregister_interrupt() - Remove a handler from the DM IRQ table | ||
323 | * @adev: The base driver device containing the DM device | ||
324 | * @irq_source: IRQ source to remove the given handler from | ||
325 | * @ih: Function pointer to the interrupt handler to unregister | ||
326 | * | ||
327 | * Go through both low and high context IRQ tables, and find the given handler | ||
328 | * for the given irq source. If found, remove it. Otherwise, do nothing. | ||
329 | */ | ||
264 | void amdgpu_dm_irq_unregister_interrupt(struct amdgpu_device *adev, | 330 | void amdgpu_dm_irq_unregister_interrupt(struct amdgpu_device *adev, |
265 | enum dc_irq_source irq_source, | 331 | enum dc_irq_source irq_source, |
266 | void *ih) | 332 | void *ih) |
@@ -295,6 +361,20 @@ void amdgpu_dm_irq_unregister_interrupt(struct amdgpu_device *adev, | |||
295 | } | 361 | } |
296 | } | 362 | } |
297 | 363 | ||
364 | /** | ||
365 | * amdgpu_dm_irq_init() - Initialize DM IRQ management | ||
366 | * @adev: The base driver device containing the DM device | ||
367 | * | ||
368 | * Initialize DM's high and low context IRQ tables. | ||
369 | * | ||
370 | * The N by M table contains N IRQ sources, with M | ||
371 | * &struct amdgpu_dm_irq_handler_data hooked together in a linked list. The | ||
372 | * list_heads are initialized here. When an interrupt n is triggered, all m | ||
373 | * handlers are called in sequence, FIFO according to registration order. | ||
374 | * | ||
375 | * The low context table requires special steps to initialize, since handlers | ||
376 | * will be deferred to a workqueue. See &struct irq_list_head. | ||
377 | */ | ||
298 | int amdgpu_dm_irq_init(struct amdgpu_device *adev) | 378 | int amdgpu_dm_irq_init(struct amdgpu_device *adev) |
299 | { | 379 | { |
300 | int src; | 380 | int src; |
@@ -317,7 +397,12 @@ int amdgpu_dm_irq_init(struct amdgpu_device *adev) | |||
317 | return 0; | 397 | return 0; |
318 | } | 398 | } |
319 | 399 | ||
320 | /* DM IRQ and timer resource release */ | 400 | /** |
401 | * amdgpu_dm_irq_fini() - Tear down DM IRQ management | ||
402 | * @adev: The base driver device containing the DM device | ||
403 | * | ||
404 | * Flush all work within the low context IRQ table. | ||
405 | */ | ||
321 | void amdgpu_dm_irq_fini(struct amdgpu_device *adev) | 406 | void amdgpu_dm_irq_fini(struct amdgpu_device *adev) |
322 | { | 407 | { |
323 | int src; | 408 | int src; |
@@ -414,7 +499,7 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev) | |||
414 | return 0; | 499 | return 0; |
415 | } | 500 | } |
416 | 501 | ||
417 | /** | 502 | /* |
418 | * amdgpu_dm_irq_schedule_work - schedule all work items registered for the | 503 | * amdgpu_dm_irq_schedule_work - schedule all work items registered for the |
419 | * "irq_source". | 504 | * "irq_source". |
420 | */ | 505 | */ |
@@ -439,8 +524,9 @@ static void amdgpu_dm_irq_schedule_work(struct amdgpu_device *adev, | |||
439 | 524 | ||
440 | } | 525 | } |
441 | 526 | ||
442 | /** amdgpu_dm_irq_immediate_work | 527 | /* |
443 | * Callback high irq work immediately, don't send to work queue | 528 | * amdgpu_dm_irq_immediate_work |
529 | * Callback high irq work immediately, don't send to work queue | ||
444 | */ | 530 | */ |
445 | static void amdgpu_dm_irq_immediate_work(struct amdgpu_device *adev, | 531 | static void amdgpu_dm_irq_immediate_work(struct amdgpu_device *adev, |
446 | enum dc_irq_source irq_source) | 532 | enum dc_irq_source irq_source) |
@@ -467,11 +553,14 @@ static void amdgpu_dm_irq_immediate_work(struct amdgpu_device *adev, | |||
467 | DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); | 553 | DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); |
468 | } | 554 | } |
469 | 555 | ||
470 | /* | 556 | /** |
471 | * amdgpu_dm_irq_handler | 557 | * amdgpu_dm_irq_handler - Generic DM IRQ handler |
558 | * @adev: amdgpu base driver device containing the DM device | ||
559 | * @source: Unused | ||
560 | * @entry: Data about the triggered interrupt | ||
472 | * | 561 | * |
473 | * Generic IRQ handler, calls all registered high irq work immediately, and | 562 | * Calls all registered high irq work immediately, and schedules work for low |
474 | * schedules work for low irq | 563 | * irq. The DM IRQ table is used to find the corresponding handlers. |
475 | */ | 564 | */ |
476 | static int amdgpu_dm_irq_handler(struct amdgpu_device *adev, | 565 | static int amdgpu_dm_irq_handler(struct amdgpu_device *adev, |
477 | struct amdgpu_irq_src *source, | 566 | struct amdgpu_irq_src *source, |
@@ -613,7 +702,7 @@ void amdgpu_dm_set_irq_funcs(struct amdgpu_device *adev) | |||
613 | adev->hpd_irq.funcs = &dm_hpd_irq_funcs; | 702 | adev->hpd_irq.funcs = &dm_hpd_irq_funcs; |
614 | } | 703 | } |
615 | 704 | ||
616 | /* | 705 | /** |
617 | * amdgpu_dm_hpd_init - hpd setup callback. | 706 | * amdgpu_dm_hpd_init - hpd setup callback. |
618 | * | 707 | * |
619 | * @adev: amdgpu_device pointer | 708 | * @adev: amdgpu_device pointer |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 03601d717fed..d02c32a1039c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | |||
@@ -205,40 +205,6 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = { | |||
205 | .atomic_get_property = amdgpu_dm_connector_atomic_get_property | 205 | .atomic_get_property = amdgpu_dm_connector_atomic_get_property |
206 | }; | 206 | }; |
207 | 207 | ||
208 | void dm_dp_mst_dc_sink_create(struct drm_connector *connector) | ||
209 | { | ||
210 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | ||
211 | struct dc_sink *dc_sink; | ||
212 | struct dc_sink_init_data init_params = { | ||
213 | .link = aconnector->dc_link, | ||
214 | .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST }; | ||
215 | |||
216 | /* FIXME none of this is safe. we shouldn't touch aconnector here in | ||
217 | * atomic_check | ||
218 | */ | ||
219 | |||
220 | /* | ||
221 | * TODO: Need to further figure out why ddc.algo is NULL while MST port exists | ||
222 | */ | ||
223 | if (!aconnector->port || !aconnector->port->aux.ddc.algo) | ||
224 | return; | ||
225 | |||
226 | ASSERT(aconnector->edid); | ||
227 | |||
228 | dc_sink = dc_link_add_remote_sink( | ||
229 | aconnector->dc_link, | ||
230 | (uint8_t *)aconnector->edid, | ||
231 | (aconnector->edid->extensions + 1) * EDID_LENGTH, | ||
232 | &init_params); | ||
233 | |||
234 | dc_sink->priv = aconnector; | ||
235 | aconnector->dc_sink = dc_sink; | ||
236 | |||
237 | if (aconnector->dc_sink) | ||
238 | amdgpu_dm_update_freesync_caps( | ||
239 | connector, aconnector->edid); | ||
240 | } | ||
241 | |||
242 | static int dm_dp_mst_get_modes(struct drm_connector *connector) | 208 | static int dm_dp_mst_get_modes(struct drm_connector *connector) |
243 | { | 209 | { |
244 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | 210 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); |
@@ -319,12 +285,7 @@ dm_dp_create_fake_mst_encoder(struct amdgpu_dm_connector *connector) | |||
319 | struct amdgpu_device *adev = dev->dev_private; | 285 | struct amdgpu_device *adev = dev->dev_private; |
320 | struct amdgpu_encoder *amdgpu_encoder; | 286 | struct amdgpu_encoder *amdgpu_encoder; |
321 | struct drm_encoder *encoder; | 287 | struct drm_encoder *encoder; |
322 | const struct drm_connector_helper_funcs *connector_funcs = | ||
323 | connector->base.helper_private; | ||
324 | struct drm_encoder *enc_master = | ||
325 | connector_funcs->best_encoder(&connector->base); | ||
326 | 288 | ||
327 | DRM_DEBUG_KMS("enc master is %p\n", enc_master); | ||
328 | amdgpu_encoder = kzalloc(sizeof(*amdgpu_encoder), GFP_KERNEL); | 289 | amdgpu_encoder = kzalloc(sizeof(*amdgpu_encoder), GFP_KERNEL); |
329 | if (!amdgpu_encoder) | 290 | if (!amdgpu_encoder) |
330 | return NULL; | 291 | return NULL; |
@@ -354,25 +315,6 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
354 | struct amdgpu_device *adev = dev->dev_private; | 315 | struct amdgpu_device *adev = dev->dev_private; |
355 | struct amdgpu_dm_connector *aconnector; | 316 | struct amdgpu_dm_connector *aconnector; |
356 | struct drm_connector *connector; | 317 | struct drm_connector *connector; |
357 | struct drm_connector_list_iter conn_iter; | ||
358 | |||
359 | drm_connector_list_iter_begin(dev, &conn_iter); | ||
360 | drm_for_each_connector_iter(connector, &conn_iter) { | ||
361 | aconnector = to_amdgpu_dm_connector(connector); | ||
362 | if (aconnector->mst_port == master | ||
363 | && !aconnector->port) { | ||
364 | DRM_INFO("DM_MST: reusing connector: %p [id: %d] [master: %p]\n", | ||
365 | aconnector, connector->base.id, aconnector->mst_port); | ||
366 | |||
367 | aconnector->port = port; | ||
368 | drm_connector_set_path_property(connector, pathprop); | ||
369 | |||
370 | drm_connector_list_iter_end(&conn_iter); | ||
371 | aconnector->mst_connected = true; | ||
372 | return &aconnector->base; | ||
373 | } | ||
374 | } | ||
375 | drm_connector_list_iter_end(&conn_iter); | ||
376 | 318 | ||
377 | aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL); | 319 | aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL); |
378 | if (!aconnector) | 320 | if (!aconnector) |
@@ -421,8 +363,6 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
421 | */ | 363 | */ |
422 | amdgpu_dm_connector_funcs_reset(connector); | 364 | amdgpu_dm_connector_funcs_reset(connector); |
423 | 365 | ||
424 | aconnector->mst_connected = true; | ||
425 | |||
426 | DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n", | 366 | DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n", |
427 | aconnector, connector->base.id, aconnector->mst_port); | 367 | aconnector, connector->base.id, aconnector->mst_port); |
428 | 368 | ||
@@ -434,6 +374,9 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
434 | static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | 374 | static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, |
435 | struct drm_connector *connector) | 375 | struct drm_connector *connector) |
436 | { | 376 | { |
377 | struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr); | ||
378 | struct drm_device *dev = master->base.dev; | ||
379 | struct amdgpu_device *adev = dev->dev_private; | ||
437 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | 380 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); |
438 | 381 | ||
439 | DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n", | 382 | DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n", |
@@ -447,7 +390,10 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
447 | aconnector->dc_sink = NULL; | 390 | aconnector->dc_sink = NULL; |
448 | } | 391 | } |
449 | 392 | ||
450 | aconnector->mst_connected = false; | 393 | drm_connector_unregister(connector); |
394 | if (adev->mode_info.rfbdev) | ||
395 | drm_fb_helper_remove_one_connector(&adev->mode_info.rfbdev->helper, connector); | ||
396 | drm_connector_put(connector); | ||
451 | } | 397 | } |
452 | 398 | ||
453 | static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) | 399 | static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) |
@@ -458,18 +404,10 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) | |||
458 | drm_kms_helper_hotplug_event(dev); | 404 | drm_kms_helper_hotplug_event(dev); |
459 | } | 405 | } |
460 | 406 | ||
461 | static void dm_dp_mst_link_status_reset(struct drm_connector *connector) | ||
462 | { | ||
463 | mutex_lock(&connector->dev->mode_config.mutex); | ||
464 | drm_connector_set_link_status_property(connector, DRM_MODE_LINK_STATUS_BAD); | ||
465 | mutex_unlock(&connector->dev->mode_config.mutex); | ||
466 | } | ||
467 | |||
468 | static void dm_dp_mst_register_connector(struct drm_connector *connector) | 407 | static void dm_dp_mst_register_connector(struct drm_connector *connector) |
469 | { | 408 | { |
470 | struct drm_device *dev = connector->dev; | 409 | struct drm_device *dev = connector->dev; |
471 | struct amdgpu_device *adev = dev->dev_private; | 410 | struct amdgpu_device *adev = dev->dev_private; |
472 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); | ||
473 | 411 | ||
474 | if (adev->mode_info.rfbdev) | 412 | if (adev->mode_info.rfbdev) |
475 | drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); | 413 | drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); |
@@ -477,9 +415,6 @@ static void dm_dp_mst_register_connector(struct drm_connector *connector) | |||
477 | DRM_ERROR("adev->mode_info.rfbdev is NULL\n"); | 415 | DRM_ERROR("adev->mode_info.rfbdev is NULL\n"); |
478 | 416 | ||
479 | drm_connector_register(connector); | 417 | drm_connector_register(connector); |
480 | |||
481 | if (aconnector->mst_connected) | ||
482 | dm_dp_mst_link_status_reset(connector); | ||
483 | } | 418 | } |
484 | 419 | ||
485 | static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { | 420 | static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h index 8cf51da26657..2da851b40042 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h | |||
@@ -31,6 +31,5 @@ struct amdgpu_dm_connector; | |||
31 | 31 | ||
32 | void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, | 32 | void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, |
33 | struct amdgpu_dm_connector *aconnector); | 33 | struct amdgpu_dm_connector *aconnector); |
34 | void dm_dp_mst_dc_sink_create(struct drm_connector *connector); | ||
35 | 34 | ||
36 | #endif | 35 | #endif |
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c index 12001a006b2d..9d2d6986b983 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c | |||
@@ -485,11 +485,11 @@ void pp_rv_set_display_requirement(struct pp_smu *pp, | |||
485 | return; | 485 | return; |
486 | 486 | ||
487 | clock.clock_type = amd_pp_dcf_clock; | 487 | clock.clock_type = amd_pp_dcf_clock; |
488 | clock.clock_freq_in_khz = req->hard_min_dcefclk_khz; | 488 | clock.clock_freq_in_khz = req->hard_min_dcefclk_mhz * 1000; |
489 | pp_funcs->display_clock_voltage_request(pp_handle, &clock); | 489 | pp_funcs->display_clock_voltage_request(pp_handle, &clock); |
490 | 490 | ||
491 | clock.clock_type = amd_pp_f_clock; | 491 | clock.clock_type = amd_pp_f_clock; |
492 | clock.clock_freq_in_khz = req->hard_min_fclk_khz; | 492 | clock.clock_freq_in_khz = req->hard_min_fclk_mhz * 1000; |
493 | pp_funcs->display_clock_voltage_request(pp_handle, &clock); | 493 | pp_funcs->display_clock_voltage_request(pp_handle, &clock); |
494 | } | 494 | } |
495 | 495 | ||
@@ -518,13 +518,13 @@ void pp_rv_set_wm_ranges(struct pp_smu *pp, | |||
518 | wm_dce_clocks[i].wm_set_id = | 518 | wm_dce_clocks[i].wm_set_id = |
519 | ranges->reader_wm_sets[i].wm_inst; | 519 | ranges->reader_wm_sets[i].wm_inst; |
520 | wm_dce_clocks[i].wm_max_dcfclk_clk_in_khz = | 520 | wm_dce_clocks[i].wm_max_dcfclk_clk_in_khz = |
521 | ranges->reader_wm_sets[i].max_drain_clk_khz; | 521 | ranges->reader_wm_sets[i].max_drain_clk_mhz * 1000; |
522 | wm_dce_clocks[i].wm_min_dcfclk_clk_in_khz = | 522 | wm_dce_clocks[i].wm_min_dcfclk_clk_in_khz = |
523 | ranges->reader_wm_sets[i].min_drain_clk_khz; | 523 | ranges->reader_wm_sets[i].min_drain_clk_mhz * 1000; |
524 | wm_dce_clocks[i].wm_max_mem_clk_in_khz = | 524 | wm_dce_clocks[i].wm_max_mem_clk_in_khz = |
525 | ranges->reader_wm_sets[i].max_fill_clk_khz; | 525 | ranges->reader_wm_sets[i].max_fill_clk_mhz * 1000; |
526 | wm_dce_clocks[i].wm_min_mem_clk_in_khz = | 526 | wm_dce_clocks[i].wm_min_mem_clk_in_khz = |
527 | ranges->reader_wm_sets[i].min_fill_clk_khz; | 527 | ranges->reader_wm_sets[i].min_fill_clk_mhz * 1000; |
528 | } | 528 | } |
529 | 529 | ||
530 | for (i = 0; i < wm_with_clock_ranges.num_wm_mcif_sets; i++) { | 530 | for (i = 0; i < wm_with_clock_ranges.num_wm_mcif_sets; i++) { |
@@ -534,13 +534,13 @@ void pp_rv_set_wm_ranges(struct pp_smu *pp, | |||
534 | wm_soc_clocks[i].wm_set_id = | 534 | wm_soc_clocks[i].wm_set_id = |
535 | ranges->writer_wm_sets[i].wm_inst; | 535 | ranges->writer_wm_sets[i].wm_inst; |
536 | wm_soc_clocks[i].wm_max_socclk_clk_in_khz = | 536 | wm_soc_clocks[i].wm_max_socclk_clk_in_khz = |
537 | ranges->writer_wm_sets[i].max_fill_clk_khz; | 537 | ranges->writer_wm_sets[i].max_fill_clk_mhz * 1000; |
538 | wm_soc_clocks[i].wm_min_socclk_clk_in_khz = | 538 | wm_soc_clocks[i].wm_min_socclk_clk_in_khz = |
539 | ranges->writer_wm_sets[i].min_fill_clk_khz; | 539 | ranges->writer_wm_sets[i].min_fill_clk_mhz * 1000; |
540 | wm_soc_clocks[i].wm_max_mem_clk_in_khz = | 540 | wm_soc_clocks[i].wm_max_mem_clk_in_khz = |
541 | ranges->writer_wm_sets[i].max_drain_clk_khz; | 541 | ranges->writer_wm_sets[i].max_drain_clk_mhz * 1000; |
542 | wm_soc_clocks[i].wm_min_mem_clk_in_khz = | 542 | wm_soc_clocks[i].wm_min_mem_clk_in_khz = |
543 | ranges->writer_wm_sets[i].min_drain_clk_khz; | 543 | ranges->writer_wm_sets[i].min_drain_clk_mhz * 1000; |
544 | } | 544 | } |
545 | 545 | ||
546 | pp_funcs->set_watermarks_for_clocks_ranges(pp_handle, &wm_with_clock_ranges); | 546 | pp_funcs->set_watermarks_for_clocks_ranges(pp_handle, &wm_with_clock_ranges); |
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c index 0e1dc1b1a48d..c2ab026aee91 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c | |||
@@ -2030,7 +2030,7 @@ static uint32_t get_src_obj_list(struct bios_parser *bp, ATOM_OBJECT *object, | |||
2030 | static struct device_id device_type_from_device_id(uint16_t device_id) | 2030 | static struct device_id device_type_from_device_id(uint16_t device_id) |
2031 | { | 2031 | { |
2032 | 2032 | ||
2033 | struct device_id result_device_id; | 2033 | struct device_id result_device_id = {0}; |
2034 | 2034 | ||
2035 | switch (device_id) { | 2035 | switch (device_id) { |
2036 | case ATOM_DEVICE_LCD1_SUPPORT: | 2036 | case ATOM_DEVICE_LCD1_SUPPORT: |
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index ff764da21b6f..751bb614fc0e 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | |||
@@ -1884,6 +1884,8 @@ static const struct dc_vbios_funcs vbios_funcs = { | |||
1884 | 1884 | ||
1885 | .is_accelerated_mode = bios_parser_is_accelerated_mode, | 1885 | .is_accelerated_mode = bios_parser_is_accelerated_mode, |
1886 | 1886 | ||
1887 | .is_active_display = bios_is_active_display, | ||
1888 | |||
1887 | .set_scratch_critical_state = bios_parser_set_scratch_critical_state, | 1889 | .set_scratch_critical_state = bios_parser_set_scratch_critical_state, |
1888 | 1890 | ||
1889 | 1891 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c index d4589470985c..fdda8aa8e303 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c | |||
@@ -88,3 +88,96 @@ uint32_t bios_get_vga_enabled_displays( | |||
88 | return active_disp; | 88 | return active_disp; |
89 | } | 89 | } |
90 | 90 | ||
91 | bool bios_is_active_display( | ||
92 | struct dc_bios *bios, | ||
93 | enum signal_type signal, | ||
94 | const struct connector_device_tag_info *device_tag) | ||
95 | { | ||
96 | uint32_t active = 0; | ||
97 | uint32_t connected = 0; | ||
98 | uint32_t bios_scratch_0 = 0; | ||
99 | uint32_t bios_scratch_3 = 0; | ||
100 | |||
101 | switch (signal) { | ||
102 | case SIGNAL_TYPE_DVI_SINGLE_LINK: | ||
103 | case SIGNAL_TYPE_DVI_DUAL_LINK: | ||
104 | case SIGNAL_TYPE_HDMI_TYPE_A: | ||
105 | case SIGNAL_TYPE_DISPLAY_PORT: | ||
106 | case SIGNAL_TYPE_DISPLAY_PORT_MST: | ||
107 | { | ||
108 | if (device_tag->dev_id.device_type == DEVICE_TYPE_DFP) { | ||
109 | switch (device_tag->dev_id.enum_id) { | ||
110 | case 1: | ||
111 | { | ||
112 | active = ATOM_S3_DFP1_ACTIVE; | ||
113 | connected = 0x0008; //ATOM_DISPLAY_DFP1_CONNECT | ||
114 | } | ||
115 | break; | ||
116 | |||
117 | case 2: | ||
118 | { | ||
119 | active = ATOM_S3_DFP2_ACTIVE; | ||
120 | connected = 0x0080; //ATOM_DISPLAY_DFP2_CONNECT | ||
121 | } | ||
122 | break; | ||
123 | |||
124 | case 3: | ||
125 | { | ||
126 | active = ATOM_S3_DFP3_ACTIVE; | ||
127 | connected = 0x0200; //ATOM_DISPLAY_DFP3_CONNECT | ||
128 | } | ||
129 | break; | ||
130 | |||
131 | case 4: | ||
132 | { | ||
133 | active = ATOM_S3_DFP4_ACTIVE; | ||
134 | connected = 0x0400; //ATOM_DISPLAY_DFP4_CONNECT | ||
135 | } | ||
136 | break; | ||
137 | |||
138 | case 5: | ||
139 | { | ||
140 | active = ATOM_S3_DFP5_ACTIVE; | ||
141 | connected = 0x0800; //ATOM_DISPLAY_DFP5_CONNECT | ||
142 | } | ||
143 | break; | ||
144 | |||
145 | case 6: | ||
146 | { | ||
147 | active = ATOM_S3_DFP6_ACTIVE; | ||
148 | connected = 0x0040; //ATOM_DISPLAY_DFP6_CONNECT | ||
149 | } | ||
150 | break; | ||
151 | |||
152 | default: | ||
153 | break; | ||
154 | } | ||
155 | } | ||
156 | } | ||
157 | break; | ||
158 | |||
159 | case SIGNAL_TYPE_LVDS: | ||
160 | case SIGNAL_TYPE_EDP: | ||
161 | { | ||
162 | active = ATOM_S3_LCD1_ACTIVE; | ||
163 | connected = 0x0002; //ATOM_DISPLAY_LCD1_CONNECT | ||
164 | } | ||
165 | break; | ||
166 | |||
167 | default: | ||
168 | break; | ||
169 | } | ||
170 | |||
171 | |||
172 | if (bios->regs->BIOS_SCRATCH_0) /*follow up with other asic, todo*/ | ||
173 | bios_scratch_0 = REG_READ(BIOS_SCRATCH_0); | ||
174 | if (bios->regs->BIOS_SCRATCH_3) /*follow up with other asic, todo*/ | ||
175 | bios_scratch_3 = REG_READ(BIOS_SCRATCH_3); | ||
176 | |||
177 | bios_scratch_3 &= ATOM_S3_DEVICE_ACTIVE_MASK; | ||
178 | if ((active & bios_scratch_3) && (connected & bios_scratch_0)) | ||
179 | return true; | ||
180 | |||
181 | return false; | ||
182 | } | ||
183 | |||
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h index 75a29e68fb27..f33cac2147e3 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h | |||
@@ -35,6 +35,10 @@ bool bios_is_accelerated_mode(struct dc_bios *bios); | |||
35 | void bios_set_scratch_acc_mode_change(struct dc_bios *bios); | 35 | void bios_set_scratch_acc_mode_change(struct dc_bios *bios); |
36 | void bios_set_scratch_critical_state(struct dc_bios *bios, bool state); | 36 | void bios_set_scratch_critical_state(struct dc_bios *bios, bool state); |
37 | uint32_t bios_get_vga_enabled_displays(struct dc_bios *bios); | 37 | uint32_t bios_get_vga_enabled_displays(struct dc_bios *bios); |
38 | bool bios_is_active_display( | ||
39 | struct dc_bios *bios, | ||
40 | enum signal_type signal, | ||
41 | const struct connector_device_tag_info *device_tag); | ||
38 | 42 | ||
39 | #define GET_IMAGE(type, offset) ((type *) bios_get_image(&bp->base, offset, sizeof(type))) | 43 | #define GET_IMAGE(type, offset) ((type *) bios_get_image(&bp->base, offset, sizeof(type))) |
40 | 44 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 3208188b7ed4..43e4a2be0fa6 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c | |||
@@ -1423,27 +1423,27 @@ void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc) | |||
1423 | ranges.num_reader_wm_sets = WM_SET_COUNT; | 1423 | ranges.num_reader_wm_sets = WM_SET_COUNT; |
1424 | ranges.num_writer_wm_sets = WM_SET_COUNT; | 1424 | ranges.num_writer_wm_sets = WM_SET_COUNT; |
1425 | ranges.reader_wm_sets[0].wm_inst = WM_A; | 1425 | ranges.reader_wm_sets[0].wm_inst = WM_A; |
1426 | ranges.reader_wm_sets[0].min_drain_clk_khz = min_dcfclk_khz; | 1426 | ranges.reader_wm_sets[0].min_drain_clk_mhz = min_dcfclk_khz / 1000; |
1427 | ranges.reader_wm_sets[0].max_drain_clk_khz = overdrive; | 1427 | ranges.reader_wm_sets[0].max_drain_clk_mhz = overdrive / 1000; |
1428 | ranges.reader_wm_sets[0].min_fill_clk_khz = min_fclk_khz; | 1428 | ranges.reader_wm_sets[0].min_fill_clk_mhz = min_fclk_khz / 1000; |
1429 | ranges.reader_wm_sets[0].max_fill_clk_khz = overdrive; | 1429 | ranges.reader_wm_sets[0].max_fill_clk_mhz = overdrive / 1000; |
1430 | ranges.writer_wm_sets[0].wm_inst = WM_A; | 1430 | ranges.writer_wm_sets[0].wm_inst = WM_A; |
1431 | ranges.writer_wm_sets[0].min_fill_clk_khz = socclk_khz; | 1431 | ranges.writer_wm_sets[0].min_fill_clk_mhz = socclk_khz / 1000; |
1432 | ranges.writer_wm_sets[0].max_fill_clk_khz = overdrive; | 1432 | ranges.writer_wm_sets[0].max_fill_clk_mhz = overdrive / 1000; |
1433 | ranges.writer_wm_sets[0].min_drain_clk_khz = min_fclk_khz; | 1433 | ranges.writer_wm_sets[0].min_drain_clk_mhz = min_fclk_khz / 1000; |
1434 | ranges.writer_wm_sets[0].max_drain_clk_khz = overdrive; | 1434 | ranges.writer_wm_sets[0].max_drain_clk_mhz = overdrive / 1000; |
1435 | 1435 | ||
1436 | if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) { | 1436 | if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) { |
1437 | ranges.reader_wm_sets[0].wm_inst = WM_A; | 1437 | ranges.reader_wm_sets[0].wm_inst = WM_A; |
1438 | ranges.reader_wm_sets[0].min_drain_clk_khz = 300000; | 1438 | ranges.reader_wm_sets[0].min_drain_clk_mhz = 300; |
1439 | ranges.reader_wm_sets[0].max_drain_clk_khz = 5000000; | 1439 | ranges.reader_wm_sets[0].max_drain_clk_mhz = 5000; |
1440 | ranges.reader_wm_sets[0].min_fill_clk_khz = 800000; | 1440 | ranges.reader_wm_sets[0].min_fill_clk_mhz = 800; |
1441 | ranges.reader_wm_sets[0].max_fill_clk_khz = 5000000; | 1441 | ranges.reader_wm_sets[0].max_fill_clk_mhz = 5000; |
1442 | ranges.writer_wm_sets[0].wm_inst = WM_A; | 1442 | ranges.writer_wm_sets[0].wm_inst = WM_A; |
1443 | ranges.writer_wm_sets[0].min_fill_clk_khz = 200000; | 1443 | ranges.writer_wm_sets[0].min_fill_clk_mhz = 200; |
1444 | ranges.writer_wm_sets[0].max_fill_clk_khz = 5000000; | 1444 | ranges.writer_wm_sets[0].max_fill_clk_mhz = 5000; |
1445 | ranges.writer_wm_sets[0].min_drain_clk_khz = 800000; | 1445 | ranges.writer_wm_sets[0].min_drain_clk_mhz = 800; |
1446 | ranges.writer_wm_sets[0].max_drain_clk_khz = 5000000; | 1446 | ranges.writer_wm_sets[0].max_drain_clk_mhz = 5000; |
1447 | } | 1447 | } |
1448 | 1448 | ||
1449 | ranges.reader_wm_sets[1] = ranges.writer_wm_sets[0]; | 1449 | ranges.reader_wm_sets[1] = ranges.writer_wm_sets[0]; |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 7c491c91465f..3279e26c3440 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c | |||
@@ -391,9 +391,11 @@ bool dc_stream_program_csc_matrix(struct dc *dc, struct dc_stream_state *stream) | |||
391 | == stream) { | 391 | == stream) { |
392 | 392 | ||
393 | pipes = &dc->current_state->res_ctx.pipe_ctx[i]; | 393 | pipes = &dc->current_state->res_ctx.pipe_ctx[i]; |
394 | dc->hwss.program_csc_matrix(pipes, | 394 | dc->hwss.program_output_csc(dc, |
395 | stream->output_color_space, | 395 | pipes, |
396 | stream->csc_color_matrix.matrix); | 396 | stream->output_color_space, |
397 | stream->csc_color_matrix.matrix, | ||
398 | pipes->plane_res.hubp->opp_id); | ||
397 | ret = true; | 399 | ret = true; |
398 | } | 400 | } |
399 | } | 401 | } |
@@ -941,7 +943,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c | |||
941 | if (!dcb->funcs->is_accelerated_mode(dcb)) | 943 | if (!dcb->funcs->is_accelerated_mode(dcb)) |
942 | dc->hwss.enable_accelerated_mode(dc, context); | 944 | dc->hwss.enable_accelerated_mode(dc, context); |
943 | 945 | ||
944 | dc->hwss.set_bandwidth(dc, context, false); | 946 | dc->hwss.prepare_bandwidth(dc, context); |
945 | 947 | ||
946 | /* re-program planes for existing stream, in case we need to | 948 | /* re-program planes for existing stream, in case we need to |
947 | * free up plane resource for later use | 949 | * free up plane resource for later use |
@@ -957,8 +959,6 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c | |||
957 | } | 959 | } |
958 | 960 | ||
959 | /* Program hardware */ | 961 | /* Program hardware */ |
960 | dc->hwss.ready_shared_resources(dc, context); | ||
961 | |||
962 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | 962 | for (i = 0; i < dc->res_pool->pipe_count; i++) { |
963 | pipe = &context->res_ctx.pipe_ctx[i]; | 963 | pipe = &context->res_ctx.pipe_ctx[i]; |
964 | dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe); | 964 | dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe); |
@@ -1012,7 +1012,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c | |||
1012 | dc_enable_stereo(dc, context, dc_streams, context->stream_count); | 1012 | dc_enable_stereo(dc, context, dc_streams, context->stream_count); |
1013 | 1013 | ||
1014 | /* pplib is notified if disp_num changed */ | 1014 | /* pplib is notified if disp_num changed */ |
1015 | dc->hwss.set_bandwidth(dc, context, true); | 1015 | dc->hwss.optimize_bandwidth(dc, context); |
1016 | 1016 | ||
1017 | dc_release_state(dc->current_state); | 1017 | dc_release_state(dc->current_state); |
1018 | 1018 | ||
@@ -1020,8 +1020,6 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c | |||
1020 | 1020 | ||
1021 | dc_retain_state(dc->current_state); | 1021 | dc_retain_state(dc->current_state); |
1022 | 1022 | ||
1023 | dc->hwss.optimize_shared_resources(dc); | ||
1024 | |||
1025 | return result; | 1023 | return result; |
1026 | } | 1024 | } |
1027 | 1025 | ||
@@ -1063,7 +1061,7 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc) | |||
1063 | 1061 | ||
1064 | dc->optimized_required = false; | 1062 | dc->optimized_required = false; |
1065 | 1063 | ||
1066 | dc->hwss.set_bandwidth(dc, context, true); | 1064 | dc->hwss.optimize_bandwidth(dc, context); |
1067 | return true; | 1065 | return true; |
1068 | } | 1066 | } |
1069 | 1067 | ||
@@ -1369,35 +1367,6 @@ static struct dc_stream_status *stream_get_status( | |||
1369 | 1367 | ||
1370 | static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL; | 1368 | static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL; |
1371 | 1369 | ||
1372 | static void notify_display_count_to_smu( | ||
1373 | struct dc *dc, | ||
1374 | struct dc_state *context) | ||
1375 | { | ||
1376 | int i, display_count; | ||
1377 | struct pp_smu_funcs_rv *pp_smu = dc->res_pool->pp_smu; | ||
1378 | |||
1379 | /* | ||
1380 | * if function pointer not set up, this message is | ||
1381 | * sent as part of pplib_apply_display_requirements. | ||
1382 | * So just return. | ||
1383 | */ | ||
1384 | if (!pp_smu || !pp_smu->set_display_count) | ||
1385 | return; | ||
1386 | |||
1387 | display_count = 0; | ||
1388 | for (i = 0; i < context->stream_count; i++) { | ||
1389 | const struct dc_stream_state *stream = context->streams[i]; | ||
1390 | |||
1391 | /* only notify active stream */ | ||
1392 | if (stream->dpms_off) | ||
1393 | continue; | ||
1394 | |||
1395 | display_count++; | ||
1396 | } | ||
1397 | |||
1398 | pp_smu->set_display_count(&pp_smu->pp_smu, display_count); | ||
1399 | } | ||
1400 | |||
1401 | static void commit_planes_do_stream_update(struct dc *dc, | 1370 | static void commit_planes_do_stream_update(struct dc *dc, |
1402 | struct dc_stream_state *stream, | 1371 | struct dc_stream_state *stream, |
1403 | struct dc_stream_update *stream_update, | 1372 | struct dc_stream_update *stream_update, |
@@ -1422,7 +1391,6 @@ static void commit_planes_do_stream_update(struct dc *dc, | |||
1422 | stream_update->adjust->v_total_max); | 1391 | stream_update->adjust->v_total_max); |
1423 | 1392 | ||
1424 | if (stream_update->periodic_fn_vsync_delta && | 1393 | if (stream_update->periodic_fn_vsync_delta && |
1425 | pipe_ctx->stream_res.tg && | ||
1426 | pipe_ctx->stream_res.tg->funcs->program_vline_interrupt) | 1394 | pipe_ctx->stream_res.tg->funcs->program_vline_interrupt) |
1427 | pipe_ctx->stream_res.tg->funcs->program_vline_interrupt( | 1395 | pipe_ctx->stream_res.tg->funcs->program_vline_interrupt( |
1428 | pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, | 1396 | pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, |
@@ -1448,19 +1416,13 @@ static void commit_planes_do_stream_update(struct dc *dc, | |||
1448 | if (stream_update->dpms_off) { | 1416 | if (stream_update->dpms_off) { |
1449 | if (*stream_update->dpms_off) { | 1417 | if (*stream_update->dpms_off) { |
1450 | core_link_disable_stream(pipe_ctx, KEEP_ACQUIRED_RESOURCE); | 1418 | core_link_disable_stream(pipe_ctx, KEEP_ACQUIRED_RESOURCE); |
1451 | dc->hwss.pplib_apply_display_requirements( | 1419 | dc->hwss.optimize_bandwidth(dc, dc->current_state); |
1452 | dc, dc->current_state); | ||
1453 | notify_display_count_to_smu(dc, dc->current_state); | ||
1454 | } else { | 1420 | } else { |
1455 | dc->hwss.pplib_apply_display_requirements( | 1421 | dc->hwss.prepare_bandwidth(dc, dc->current_state); |
1456 | dc, dc->current_state); | ||
1457 | notify_display_count_to_smu(dc, dc->current_state); | ||
1458 | core_link_enable_stream(dc->current_state, pipe_ctx); | 1422 | core_link_enable_stream(dc->current_state, pipe_ctx); |
1459 | } | 1423 | } |
1460 | } | 1424 | } |
1461 | 1425 | ||
1462 | |||
1463 | |||
1464 | if (stream_update->abm_level && pipe_ctx->stream_res.abm) { | 1426 | if (stream_update->abm_level && pipe_ctx->stream_res.abm) { |
1465 | if (pipe_ctx->stream_res.tg->funcs->is_blanked) { | 1427 | if (pipe_ctx->stream_res.tg->funcs->is_blanked) { |
1466 | // if otg funcs defined check if blanked before programming | 1428 | // if otg funcs defined check if blanked before programming |
@@ -1487,7 +1449,7 @@ static void commit_planes_for_stream(struct dc *dc, | |||
1487 | struct pipe_ctx *top_pipe_to_program = NULL; | 1449 | struct pipe_ctx *top_pipe_to_program = NULL; |
1488 | 1450 | ||
1489 | if (update_type == UPDATE_TYPE_FULL) { | 1451 | if (update_type == UPDATE_TYPE_FULL) { |
1490 | dc->hwss.set_bandwidth(dc, context, false); | 1452 | dc->hwss.prepare_bandwidth(dc, context); |
1491 | context_clock_trace(dc, context); | 1453 | context_clock_trace(dc, context); |
1492 | } | 1454 | } |
1493 | 1455 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c index e1ebdf7b5eaf..73d049506618 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c | |||
@@ -311,7 +311,7 @@ void context_timing_trace( | |||
311 | { | 311 | { |
312 | int i; | 312 | int i; |
313 | struct dc *core_dc = dc; | 313 | struct dc *core_dc = dc; |
314 | int h_pos[MAX_PIPES], v_pos[MAX_PIPES]; | 314 | int h_pos[MAX_PIPES] = {0}, v_pos[MAX_PIPES] = {0}; |
315 | struct crtc_position position; | 315 | struct crtc_position position; |
316 | unsigned int underlay_idx = core_dc->res_pool->underlay_pipe_index; | 316 | unsigned int underlay_idx = core_dc->res_pool->underlay_pipe_index; |
317 | DC_LOGGER_INIT(dc->ctx->logger); | 317 | DC_LOGGER_INIT(dc->ctx->logger); |
@@ -322,8 +322,7 @@ void context_timing_trace( | |||
322 | /* get_position() returns CRTC vertical/horizontal counter | 322 | /* get_position() returns CRTC vertical/horizontal counter |
323 | * hence not applicable for underlay pipe | 323 | * hence not applicable for underlay pipe |
324 | */ | 324 | */ |
325 | if (pipe_ctx->stream == NULL | 325 | if (pipe_ctx->stream == NULL || pipe_ctx->pipe_idx == underlay_idx) |
326 | || pipe_ctx->pipe_idx == underlay_idx) | ||
327 | continue; | 326 | continue; |
328 | 327 | ||
329 | pipe_ctx->stream_res.tg->funcs->get_position(pipe_ctx->stream_res.tg, &position); | 328 | pipe_ctx->stream_res.tg->funcs->get_position(pipe_ctx->stream_res.tg, &position); |
@@ -333,7 +332,7 @@ void context_timing_trace( | |||
333 | for (i = 0; i < core_dc->res_pool->pipe_count; i++) { | 332 | for (i = 0; i < core_dc->res_pool->pipe_count; i++) { |
334 | struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; | 333 | struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; |
335 | 334 | ||
336 | if (pipe_ctx->stream == NULL) | 335 | if (pipe_ctx->stream == NULL || pipe_ctx->pipe_idx == underlay_idx) |
337 | continue; | 336 | continue; |
338 | 337 | ||
339 | TIMING_TRACE("OTG_%d H_tot:%d V_tot:%d H_pos:%d V_pos:%d\n", | 338 | TIMING_TRACE("OTG_%d H_tot:%d V_tot:%d H_pos:%d V_pos:%d\n", |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index fb04a4ad141f..7ee9c033acbd 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c | |||
@@ -1357,28 +1357,13 @@ static enum dc_status enable_link_dp( | |||
1357 | struct dc_link *link = stream->sink->link; | 1357 | struct dc_link *link = stream->sink->link; |
1358 | struct dc_link_settings link_settings = {0}; | 1358 | struct dc_link_settings link_settings = {0}; |
1359 | enum dp_panel_mode panel_mode; | 1359 | enum dp_panel_mode panel_mode; |
1360 | enum dc_link_rate max_link_rate = LINK_RATE_HIGH2; | ||
1361 | 1360 | ||
1362 | /* get link settings for video mode timing */ | 1361 | /* get link settings for video mode timing */ |
1363 | decide_link_settings(stream, &link_settings); | 1362 | decide_link_settings(stream, &link_settings); |
1364 | 1363 | ||
1365 | /* raise clock state for HBR3 if required. Confirmed with HW DCE/DPCS | 1364 | pipe_ctx->stream_res.pix_clk_params.requested_sym_clk = |
1366 | * logic for HBR3 still needs Nominal (0.8V) on VDDC rail | 1365 | link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ; |
1367 | */ | 1366 | state->dccg->funcs->update_clocks(state->dccg, state, false); |
1368 | if (link->link_enc->features.flags.bits.IS_HBR3_CAPABLE) | ||
1369 | max_link_rate = LINK_RATE_HIGH3; | ||
1370 | |||
1371 | if (link_settings.link_rate == max_link_rate) { | ||
1372 | struct dc_clocks clocks = state->bw.dcn.clk; | ||
1373 | |||
1374 | /* dce/dcn compat, do not update dispclk */ | ||
1375 | clocks.dispclk_khz = 0; | ||
1376 | /* 27mhz = 27000000hz= 27000khz */ | ||
1377 | clocks.phyclk_khz = link_settings.link_rate * 27000; | ||
1378 | |||
1379 | state->dis_clk->funcs->update_clocks( | ||
1380 | state->dis_clk, &clocks, false); | ||
1381 | } | ||
1382 | 1367 | ||
1383 | dp_enable_link_phy( | 1368 | dp_enable_link_phy( |
1384 | link, | 1369 | link, |
@@ -1722,7 +1707,7 @@ static void write_i2c_retimer_setting( | |||
1722 | i2c_success = i2c_write(pipe_ctx, slave_address, | 1707 | i2c_success = i2c_write(pipe_ctx, slave_address, |
1723 | buffer, sizeof(buffer)); | 1708 | buffer, sizeof(buffer)); |
1724 | RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\ | 1709 | RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\ |
1725 | offset = 0x%d, reg_val = 0x%d, i2c_success = %d\n", | 1710 | offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n", |
1726 | slave_address, buffer[0], buffer[1], i2c_success?1:0); | 1711 | slave_address, buffer[0], buffer[1], i2c_success?1:0); |
1727 | if (!i2c_success) | 1712 | if (!i2c_success) |
1728 | /* Write failure */ | 1713 | /* Write failure */ |
@@ -1734,7 +1719,7 @@ static void write_i2c_retimer_setting( | |||
1734 | i2c_success = i2c_write(pipe_ctx, slave_address, | 1719 | i2c_success = i2c_write(pipe_ctx, slave_address, |
1735 | buffer, sizeof(buffer)); | 1720 | buffer, sizeof(buffer)); |
1736 | RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\ | 1721 | RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\ |
1737 | offset = 0x%d, reg_val = 0x%d, i2c_success = %d\n", | 1722 | offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n", |
1738 | slave_address, buffer[0], buffer[1], i2c_success?1:0); | 1723 | slave_address, buffer[0], buffer[1], i2c_success?1:0); |
1739 | if (!i2c_success) | 1724 | if (!i2c_success) |
1740 | /* Write failure */ | 1725 | /* Write failure */ |
@@ -2156,14 +2141,16 @@ int dc_link_get_backlight_level(const struct dc_link *link) | |||
2156 | { | 2141 | { |
2157 | struct abm *abm = link->ctx->dc->res_pool->abm; | 2142 | struct abm *abm = link->ctx->dc->res_pool->abm; |
2158 | 2143 | ||
2159 | if (abm == NULL || abm->funcs->get_current_backlight_8_bit == NULL) | 2144 | if (abm == NULL || abm->funcs->get_current_backlight == NULL) |
2160 | return DC_ERROR_UNEXPECTED; | 2145 | return DC_ERROR_UNEXPECTED; |
2161 | 2146 | ||
2162 | return (int) abm->funcs->get_current_backlight_8_bit(abm); | 2147 | return (int) abm->funcs->get_current_backlight(abm); |
2163 | } | 2148 | } |
2164 | 2149 | ||
2165 | bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level, | 2150 | bool dc_link_set_backlight_level(const struct dc_link *link, |
2166 | uint32_t frame_ramp, const struct dc_stream_state *stream) | 2151 | uint32_t backlight_pwm_u16_16, |
2152 | uint32_t frame_ramp, | ||
2153 | const struct dc_stream_state *stream) | ||
2167 | { | 2154 | { |
2168 | struct dc *core_dc = link->ctx->dc; | 2155 | struct dc *core_dc = link->ctx->dc; |
2169 | struct abm *abm = core_dc->res_pool->abm; | 2156 | struct abm *abm = core_dc->res_pool->abm; |
@@ -2175,19 +2162,17 @@ bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level, | |||
2175 | 2162 | ||
2176 | if ((dmcu == NULL) || | 2163 | if ((dmcu == NULL) || |
2177 | (abm == NULL) || | 2164 | (abm == NULL) || |
2178 | (abm->funcs->set_backlight_level == NULL)) | 2165 | (abm->funcs->set_backlight_level_pwm == NULL)) |
2179 | return false; | 2166 | return false; |
2180 | 2167 | ||
2181 | if (stream) { | 2168 | if (stream) |
2182 | if (stream->bl_pwm_level == EDP_BACKLIGHT_RAMP_DISABLE_LEVEL) | 2169 | ((struct dc_stream_state *)stream)->bl_pwm_level = |
2183 | frame_ramp = 0; | 2170 | backlight_pwm_u16_16; |
2184 | |||
2185 | ((struct dc_stream_state *)stream)->bl_pwm_level = level; | ||
2186 | } | ||
2187 | 2171 | ||
2188 | use_smooth_brightness = dmcu->funcs->is_dmcu_initialized(dmcu); | 2172 | use_smooth_brightness = dmcu->funcs->is_dmcu_initialized(dmcu); |
2189 | 2173 | ||
2190 | DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n", level, level); | 2174 | DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n", |
2175 | backlight_pwm_u16_16, backlight_pwm_u16_16); | ||
2191 | 2176 | ||
2192 | if (dc_is_embedded_signal(link->connector_signal)) { | 2177 | if (dc_is_embedded_signal(link->connector_signal)) { |
2193 | if (stream != NULL) { | 2178 | if (stream != NULL) { |
@@ -2204,9 +2189,9 @@ bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level, | |||
2204 | 1; | 2189 | 1; |
2205 | } | 2190 | } |
2206 | } | 2191 | } |
2207 | abm->funcs->set_backlight_level( | 2192 | abm->funcs->set_backlight_level_pwm( |
2208 | abm, | 2193 | abm, |
2209 | level, | 2194 | backlight_pwm_u16_16, |
2210 | frame_ramp, | 2195 | frame_ramp, |
2211 | controller_id, | 2196 | controller_id, |
2212 | use_smooth_brightness); | 2197 | use_smooth_brightness); |
@@ -2220,7 +2205,7 @@ bool dc_link_set_abm_disable(const struct dc_link *link) | |||
2220 | struct dc *core_dc = link->ctx->dc; | 2205 | struct dc *core_dc = link->ctx->dc; |
2221 | struct abm *abm = core_dc->res_pool->abm; | 2206 | struct abm *abm = core_dc->res_pool->abm; |
2222 | 2207 | ||
2223 | if ((abm == NULL) || (abm->funcs->set_backlight_level == NULL)) | 2208 | if ((abm == NULL) || (abm->funcs->set_backlight_level_pwm == NULL)) |
2224 | return false; | 2209 | return false; |
2225 | 2210 | ||
2226 | abm->funcs->set_abm_immediate_disable(abm); | 2211 | abm->funcs->set_abm_immediate_disable(abm); |
@@ -2609,6 +2594,10 @@ void core_link_enable_stream( | |||
2609 | core_dc->hwss.unblank_stream(pipe_ctx, | 2594 | core_dc->hwss.unblank_stream(pipe_ctx, |
2610 | &pipe_ctx->stream->sink->link->cur_link_settings); | 2595 | &pipe_ctx->stream->sink->link->cur_link_settings); |
2611 | 2596 | ||
2597 | dc_link_set_backlight_level(pipe_ctx->stream->sink->link, | ||
2598 | pipe_ctx->stream->bl_pwm_level, | ||
2599 | 0, | ||
2600 | pipe_ctx->stream); | ||
2612 | } | 2601 | } |
2613 | 2602 | ||
2614 | } | 2603 | } |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index b6fe29b9fb65..fc65b0055167 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c | |||
@@ -499,8 +499,13 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx) | |||
499 | pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state; | 499 | pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state; |
500 | bool flip_vert_scan_dir = false, flip_horz_scan_dir = false; | 500 | bool flip_vert_scan_dir = false, flip_horz_scan_dir = false; |
501 | 501 | ||
502 | |||
502 | /* | 503 | /* |
503 | * Need to calculate the scan direction for viewport to properly determine offset | 504 | * We need take horizontal mirror into account. On an unrotated surface this means |
505 | * that the viewport offset is actually the offset from the other side of source | ||
506 | * image so we have to subtract the right edge of the viewport from the right edge of | ||
507 | * the source window. Similar to mirror we need to take into account how offset is | ||
508 | * affected for 270/180 rotations | ||
504 | */ | 509 | */ |
505 | if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_180) { | 510 | if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_180) { |
506 | flip_vert_scan_dir = true; | 511 | flip_vert_scan_dir = true; |
@@ -510,6 +515,9 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx) | |||
510 | else if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) | 515 | else if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) |
511 | flip_horz_scan_dir = true; | 516 | flip_horz_scan_dir = true; |
512 | 517 | ||
518 | if (pipe_ctx->plane_state->horizontal_mirror) | ||
519 | flip_horz_scan_dir = !flip_horz_scan_dir; | ||
520 | |||
513 | if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE || | 521 | if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE || |
514 | stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) { | 522 | stream->view_format == VIEW_3D_FORMAT_TOP_AND_BOTTOM) { |
515 | pri_split = false; | 523 | pri_split = false; |
@@ -540,45 +548,27 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx) | |||
540 | plane_state->clip_rect.y + plane_state->clip_rect.height - clip.y ; | 548 | plane_state->clip_rect.y + plane_state->clip_rect.height - clip.y ; |
541 | 549 | ||
542 | /* offset = surf_src.ofs + (clip.ofs - surface->dst_rect.ofs) * scl_ratio | 550 | /* offset = surf_src.ofs + (clip.ofs - surface->dst_rect.ofs) * scl_ratio |
551 | * note: surf_src.ofs should be added after rotation/mirror offset direction | ||
552 | * adjustment since it is already in viewport space | ||
543 | * num_pixels = clip.num_pix * scl_ratio | 553 | * num_pixels = clip.num_pix * scl_ratio |
544 | */ | 554 | */ |
545 | data->viewport.x = surf_src.x + (clip.x - plane_state->dst_rect.x) * | 555 | data->viewport.x = (clip.x - plane_state->dst_rect.x) * |
546 | surf_src.width / plane_state->dst_rect.width; | 556 | surf_src.width / plane_state->dst_rect.width; |
547 | data->viewport.width = clip.width * | 557 | data->viewport.width = clip.width * |
548 | surf_src.width / plane_state->dst_rect.width; | 558 | surf_src.width / plane_state->dst_rect.width; |
549 | 559 | ||
550 | data->viewport.y = surf_src.y + (clip.y - plane_state->dst_rect.y) * | 560 | data->viewport.y = (clip.y - plane_state->dst_rect.y) * |
551 | surf_src.height / plane_state->dst_rect.height; | 561 | surf_src.height / plane_state->dst_rect.height; |
552 | data->viewport.height = clip.height * | 562 | data->viewport.height = clip.height * |
553 | surf_src.height / plane_state->dst_rect.height; | 563 | surf_src.height / plane_state->dst_rect.height; |
554 | 564 | ||
555 | /* To transfer the x, y to correct coordinate on mirror image (camera). | 565 | if (flip_vert_scan_dir) |
556 | * deg 0 : transfer x, | 566 | data->viewport.y = surf_src.height - data->viewport.y - data->viewport.height; |
557 | * deg 90 : don't need to transfer, | 567 | if (flip_horz_scan_dir) |
558 | * deg180 : transfer y, | 568 | data->viewport.x = surf_src.width - data->viewport.x - data->viewport.width; |
559 | * deg270 : transfer x and y. | 569 | |
560 | * To transfer the x, y to correct coordinate on non-mirror image (video). | 570 | data->viewport.x += surf_src.x; |
561 | * deg 0 : don't need to transfer, | 571 | data->viewport.y += surf_src.y; |
562 | * deg 90 : transfer y, | ||
563 | * deg180 : transfer x and y, | ||
564 | * deg270 : transfer x. | ||
565 | */ | ||
566 | if (pipe_ctx->plane_state->horizontal_mirror) { | ||
567 | if (flip_horz_scan_dir && !flip_vert_scan_dir) { | ||
568 | data->viewport.y = surf_src.height - data->viewport.y - data->viewport.height; | ||
569 | data->viewport.x = surf_src.width - data->viewport.x - data->viewport.width; | ||
570 | } else if (flip_horz_scan_dir && flip_vert_scan_dir) | ||
571 | data->viewport.y = surf_src.height - data->viewport.y - data->viewport.height; | ||
572 | else { | ||
573 | if (!flip_horz_scan_dir && !flip_vert_scan_dir) | ||
574 | data->viewport.x = surf_src.width - data->viewport.x - data->viewport.width; | ||
575 | } | ||
576 | } else { | ||
577 | if (flip_horz_scan_dir) | ||
578 | data->viewport.x = surf_src.width - data->viewport.x - data->viewport.width; | ||
579 | if (flip_vert_scan_dir) | ||
580 | data->viewport.y = surf_src.height - data->viewport.y - data->viewport.height; | ||
581 | } | ||
582 | 572 | ||
583 | /* Round down, compensate in init */ | 573 | /* Round down, compensate in init */ |
584 | data->viewport_c.x = data->viewport.x / vpc_div; | 574 | data->viewport_c.x = data->viewport.x / vpc_div; |
@@ -773,22 +763,15 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct rect *r | |||
773 | else if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) | 763 | else if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) |
774 | flip_horz_scan_dir = true; | 764 | flip_horz_scan_dir = true; |
775 | 765 | ||
766 | if (pipe_ctx->plane_state->horizontal_mirror) | ||
767 | flip_horz_scan_dir = !flip_horz_scan_dir; | ||
768 | |||
776 | if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 || | 769 | if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 || |
777 | pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) { | 770 | pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) { |
778 | rect_swap_helper(&src); | 771 | rect_swap_helper(&src); |
779 | rect_swap_helper(&data->viewport_c); | 772 | rect_swap_helper(&data->viewport_c); |
780 | rect_swap_helper(&data->viewport); | 773 | rect_swap_helper(&data->viewport); |
781 | 774 | } | |
782 | if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270 && | ||
783 | pipe_ctx->plane_state->horizontal_mirror) { | ||
784 | flip_vert_scan_dir = true; | ||
785 | } | ||
786 | if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 && | ||
787 | pipe_ctx->plane_state->horizontal_mirror) { | ||
788 | flip_vert_scan_dir = false; | ||
789 | } | ||
790 | } else if (pipe_ctx->plane_state->horizontal_mirror) | ||
791 | flip_horz_scan_dir = !flip_horz_scan_dir; | ||
792 | 775 | ||
793 | /* | 776 | /* |
794 | * Init calculated according to formula: | 777 | * Init calculated according to formula: |
@@ -1115,9 +1098,6 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) | |||
1115 | pipe_ctx->plane_res.scl_data.format = convert_pixel_format_to_dalsurface( | 1098 | pipe_ctx->plane_res.scl_data.format = convert_pixel_format_to_dalsurface( |
1116 | pipe_ctx->plane_state->format); | 1099 | pipe_ctx->plane_state->format); |
1117 | 1100 | ||
1118 | if (pipe_ctx->stream->timing.flags.INTERLACE) | ||
1119 | pipe_ctx->stream->dst.height *= 2; | ||
1120 | |||
1121 | calculate_scaling_ratios(pipe_ctx); | 1101 | calculate_scaling_ratios(pipe_ctx); |
1122 | 1102 | ||
1123 | calculate_viewport(pipe_ctx); | 1103 | calculate_viewport(pipe_ctx); |
@@ -1138,9 +1118,6 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) | |||
1138 | 1118 | ||
1139 | pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable + timing->h_border_left + timing->h_border_right; | 1119 | pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable + timing->h_border_left + timing->h_border_right; |
1140 | pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable + timing->v_border_top + timing->v_border_bottom; | 1120 | pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable + timing->v_border_top + timing->v_border_bottom; |
1141 | if (pipe_ctx->stream->timing.flags.INTERLACE) | ||
1142 | pipe_ctx->plane_res.scl_data.v_active *= 2; | ||
1143 | |||
1144 | 1121 | ||
1145 | /* Taps calculations */ | 1122 | /* Taps calculations */ |
1146 | if (pipe_ctx->plane_res.xfm != NULL) | 1123 | if (pipe_ctx->plane_res.xfm != NULL) |
@@ -1185,9 +1162,6 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) | |||
1185 | plane_state->dst_rect.x, | 1162 | plane_state->dst_rect.x, |
1186 | plane_state->dst_rect.y); | 1163 | plane_state->dst_rect.y); |
1187 | 1164 | ||
1188 | if (pipe_ctx->stream->timing.flags.INTERLACE) | ||
1189 | pipe_ctx->stream->dst.height /= 2; | ||
1190 | |||
1191 | return res; | 1165 | return res; |
1192 | } | 1166 | } |
1193 | 1167 | ||
@@ -2071,7 +2045,7 @@ void dc_resource_state_construct( | |||
2071 | const struct dc *dc, | 2045 | const struct dc *dc, |
2072 | struct dc_state *dst_ctx) | 2046 | struct dc_state *dst_ctx) |
2073 | { | 2047 | { |
2074 | dst_ctx->dis_clk = dc->res_pool->dccg; | 2048 | dst_ctx->dccg = dc->res_pool->clk_mgr; |
2075 | } | 2049 | } |
2076 | 2050 | ||
2077 | enum dc_status dc_validate_global_state( | 2051 | enum dc_status dc_validate_global_state( |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 2ac848a106ba..e113439aaa86 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c | |||
@@ -106,6 +106,7 @@ static void construct(struct dc_stream_state *stream, | |||
106 | 106 | ||
107 | stream->out_transfer_func = dc_create_transfer_func(); | 107 | stream->out_transfer_func = dc_create_transfer_func(); |
108 | stream->out_transfer_func->type = TF_TYPE_BYPASS; | 108 | stream->out_transfer_func->type = TF_TYPE_BYPASS; |
109 | stream->out_transfer_func->ctx = stream->ctx; | ||
109 | } | 110 | } |
110 | 111 | ||
111 | static void destruct(struct dc_stream_state *stream) | 112 | static void destruct(struct dc_stream_state *stream) |
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c index 8fb3aefd195c..c60c9b4c3075 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c | |||
@@ -44,6 +44,7 @@ static void construct(struct dc_context *ctx, struct dc_plane_state *plane_state | |||
44 | 44 | ||
45 | plane_state->in_transfer_func = dc_create_transfer_func(); | 45 | plane_state->in_transfer_func = dc_create_transfer_func(); |
46 | plane_state->in_transfer_func->type = TF_TYPE_BYPASS; | 46 | plane_state->in_transfer_func->type = TF_TYPE_BYPASS; |
47 | plane_state->in_transfer_func->ctx = ctx; | ||
47 | } | 48 | } |
48 | 49 | ||
49 | static void destruct(struct dc_plane_state *plane_state) | 50 | static void destruct(struct dc_plane_state *plane_state) |
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 199527171100..d16a20c84792 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h | |||
@@ -38,7 +38,7 @@ | |||
38 | #include "inc/compressor.h" | 38 | #include "inc/compressor.h" |
39 | #include "dml/display_mode_lib.h" | 39 | #include "dml/display_mode_lib.h" |
40 | 40 | ||
41 | #define DC_VER "3.1.68" | 41 | #define DC_VER "3.2.04" |
42 | 42 | ||
43 | #define MAX_SURFACES 3 | 43 | #define MAX_SURFACES 3 |
44 | #define MAX_STREAMS 6 | 44 | #define MAX_STREAMS 6 |
@@ -169,6 +169,7 @@ struct link_training_settings; | |||
169 | struct dc_config { | 169 | struct dc_config { |
170 | bool gpu_vm_support; | 170 | bool gpu_vm_support; |
171 | bool disable_disp_pll_sharing; | 171 | bool disable_disp_pll_sharing; |
172 | bool fbc_support; | ||
172 | }; | 173 | }; |
173 | 174 | ||
174 | enum visual_confirm { | 175 | enum visual_confirm { |
@@ -249,8 +250,6 @@ struct dc_debug_options { | |||
249 | bool disable_dmcu; | 250 | bool disable_dmcu; |
250 | bool disable_psr; | 251 | bool disable_psr; |
251 | bool force_abm_enable; | 252 | bool force_abm_enable; |
252 | bool disable_hbup_pg; | ||
253 | bool disable_dpp_pg; | ||
254 | bool disable_stereo_support; | 253 | bool disable_stereo_support; |
255 | bool vsr_support; | 254 | bool vsr_support; |
256 | bool performance_trace; | 255 | bool performance_trace; |
@@ -304,11 +303,6 @@ struct dc { | |||
304 | struct hw_sequencer_funcs hwss; | 303 | struct hw_sequencer_funcs hwss; |
305 | struct dce_hwseq *hwseq; | 304 | struct dce_hwseq *hwseq; |
306 | 305 | ||
307 | /* temp store of dm_pp_display_configuration | ||
308 | * to compare to see if display config changed | ||
309 | */ | ||
310 | struct dm_pp_display_configuration prev_display_config; | ||
311 | |||
312 | bool optimized_required; | 306 | bool optimized_required; |
313 | 307 | ||
314 | /* FBC compressor */ | 308 | /* FBC compressor */ |
diff --git a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h index 8130b95ccc53..a8b3cedf9431 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h | |||
@@ -86,6 +86,10 @@ struct dc_vbios_funcs { | |||
86 | 86 | ||
87 | bool (*is_accelerated_mode)( | 87 | bool (*is_accelerated_mode)( |
88 | struct dc_bios *bios); | 88 | struct dc_bios *bios); |
89 | bool (*is_active_display)( | ||
90 | struct dc_bios *bios, | ||
91 | enum signal_type signal, | ||
92 | const struct connector_device_tag_info *device_tag); | ||
89 | void (*set_scratch_critical_state)( | 93 | void (*set_scratch_critical_state)( |
90 | struct dc_bios *bios, | 94 | struct dc_bios *bios, |
91 | bool state); | 95 | bool state); |
@@ -141,6 +145,7 @@ struct dc_vbios_funcs { | |||
141 | }; | 145 | }; |
142 | 146 | ||
143 | struct bios_registers { | 147 | struct bios_registers { |
148 | uint32_t BIOS_SCRATCH_0; | ||
144 | uint32_t BIOS_SCRATCH_3; | 149 | uint32_t BIOS_SCRATCH_3; |
145 | uint32_t BIOS_SCRATCH_6; | 150 | uint32_t BIOS_SCRATCH_6; |
146 | }; | 151 | }; |
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index 3bfdccceb524..8738f27a8708 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h | |||
@@ -138,9 +138,14 @@ static inline struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_ | |||
138 | return dc->links[link_index]; | 138 | return dc->links[link_index]; |
139 | } | 139 | } |
140 | 140 | ||
141 | /* Set backlight level of an embedded panel (eDP, LVDS). */ | 141 | /* Set backlight level of an embedded panel (eDP, LVDS). |
142 | bool dc_link_set_backlight_level(const struct dc_link *dc_link, uint32_t level, | 142 | * backlight_pwm_u16_16 is unsigned 32 bit with 16 bit integer |
143 | uint32_t frame_ramp, const struct dc_stream_state *stream); | 143 | * and 16 bit fractional, where 1.0 is max backlight value. |
144 | */ | ||
145 | bool dc_link_set_backlight_level(const struct dc_link *dc_link, | ||
146 | uint32_t backlight_pwm_u16_16, | ||
147 | uint32_t frame_ramp, | ||
148 | const struct dc_stream_state *stream); | ||
144 | 149 | ||
145 | int dc_link_get_backlight_level(const struct dc_link *dc_link); | 150 | int dc_link_get_backlight_level(const struct dc_link *dc_link); |
146 | 151 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dce/Makefile b/drivers/gpu/drm/amd/display/dc/dce/Makefile index 8f7f0e8b341f..6d7b64a743ca 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dce/Makefile | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | DCE = dce_audio.o dce_stream_encoder.o dce_link_encoder.o dce_hwseq.o \ | 29 | DCE = dce_audio.o dce_stream_encoder.o dce_link_encoder.o dce_hwseq.o \ |
30 | dce_mem_input.o dce_clock_source.o dce_scl_filters.o dce_transform.o \ | 30 | dce_mem_input.o dce_clock_source.o dce_scl_filters.o dce_transform.o \ |
31 | dce_clocks.o dce_opp.o dce_dmcu.o dce_abm.o dce_ipp.o dce_aux.o \ | 31 | dce_clk_mgr.o dce_opp.o dce_dmcu.o dce_abm.o dce_ipp.o dce_aux.o \ |
32 | dce_i2c.o dce_i2c_hw.o dce_i2c_sw.o | 32 | dce_i2c.o dce_i2c_hw.o dce_i2c_sw.o |
33 | 33 | ||
34 | AMD_DAL_DCE = $(addprefix $(AMDDALPATH)/dc/dce/,$(DCE)) | 34 | AMD_DAL_DCE = $(addprefix $(AMDDALPATH)/dc/dce/,$(DCE)) |
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c index 29294db1a96b..2a342eae80fd 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c | |||
@@ -54,7 +54,7 @@ | |||
54 | #define MCP_DISABLE_ABM_IMMEDIATELY 255 | 54 | #define MCP_DISABLE_ABM_IMMEDIATELY 255 |
55 | 55 | ||
56 | 56 | ||
57 | static unsigned int get_current_backlight_16_bit(struct dce_abm *abm_dce) | 57 | static unsigned int calculate_16_bit_backlight_from_pwm(struct dce_abm *abm_dce) |
58 | { | 58 | { |
59 | uint64_t current_backlight; | 59 | uint64_t current_backlight; |
60 | uint32_t round_result; | 60 | uint32_t round_result; |
@@ -103,45 +103,21 @@ static unsigned int get_current_backlight_16_bit(struct dce_abm *abm_dce) | |||
103 | return (uint32_t)(current_backlight); | 103 | return (uint32_t)(current_backlight); |
104 | } | 104 | } |
105 | 105 | ||
106 | static void driver_set_backlight_level(struct dce_abm *abm_dce, uint32_t level) | 106 | static void driver_set_backlight_level(struct dce_abm *abm_dce, |
107 | uint32_t backlight_pwm_u16_16) | ||
107 | { | 108 | { |
108 | uint32_t backlight_24bit; | ||
109 | uint32_t backlight_17bit; | ||
110 | uint32_t backlight_16bit; | 109 | uint32_t backlight_16bit; |
111 | uint32_t masked_pwm_period; | 110 | uint32_t masked_pwm_period; |
112 | uint8_t rounding_bit; | ||
113 | uint8_t bit_count; | 111 | uint8_t bit_count; |
114 | uint64_t active_duty_cycle; | 112 | uint64_t active_duty_cycle; |
115 | uint32_t pwm_period_bitcnt; | 113 | uint32_t pwm_period_bitcnt; |
116 | 114 | ||
117 | /* | 115 | /* |
118 | * 1. Convert 8-bit value to 17 bit U1.16 format | 116 | * 1. Find 16 bit backlight active duty cycle, where 0 <= backlight |
119 | * (1 integer, 16 fractional bits) | ||
120 | */ | ||
121 | |||
122 | /* 1.1 multiply 8 bit value by 0x10101 to get a 24 bit value, | ||
123 | * effectively multiplying value by 256/255 | ||
124 | * eg. for a level of 0xEF, backlight_24bit = 0xEF * 0x10101 = 0xEFEFEF | ||
125 | */ | ||
126 | backlight_24bit = level * 0x10101; | ||
127 | |||
128 | /* 1.2 The upper 16 bits of the 24 bit value is the fraction, lower 8 | ||
129 | * used for rounding, take most significant bit of fraction for | ||
130 | * rounding, e.g. for 0xEFEFEF, rounding bit is 1 | ||
131 | */ | ||
132 | rounding_bit = (backlight_24bit >> 7) & 1; | ||
133 | |||
134 | /* 1.3 Add the upper 16 bits of the 24 bit value with the rounding bit | ||
135 | * resulting in a 17 bit value e.g. 0xEFF0 = (0xEFEFEF >> 8) + 1 | ||
136 | */ | ||
137 | backlight_17bit = (backlight_24bit >> 8) + rounding_bit; | ||
138 | |||
139 | /* | ||
140 | * 2. Find 16 bit backlight active duty cycle, where 0 <= backlight | ||
141 | * active duty cycle <= backlight period | 117 | * active duty cycle <= backlight period |
142 | */ | 118 | */ |
143 | 119 | ||
144 | /* 2.1 Apply bitmask for backlight period value based on value of BITCNT | 120 | /* 1.1 Apply bitmask for backlight period value based on value of BITCNT |
145 | */ | 121 | */ |
146 | REG_GET_2(BL_PWM_PERIOD_CNTL, | 122 | REG_GET_2(BL_PWM_PERIOD_CNTL, |
147 | BL_PWM_PERIOD_BITCNT, &pwm_period_bitcnt, | 123 | BL_PWM_PERIOD_BITCNT, &pwm_period_bitcnt, |
@@ -155,13 +131,13 @@ static void driver_set_backlight_level(struct dce_abm *abm_dce, uint32_t level) | |||
155 | /* e.g. maskedPwmPeriod = 0x24 when bitCount is 6 */ | 131 | /* e.g. maskedPwmPeriod = 0x24 when bitCount is 6 */ |
156 | masked_pwm_period = masked_pwm_period & ((1 << bit_count) - 1); | 132 | masked_pwm_period = masked_pwm_period & ((1 << bit_count) - 1); |
157 | 133 | ||
158 | /* 2.2 Calculate integer active duty cycle required upper 16 bits | 134 | /* 1.2 Calculate integer active duty cycle required upper 16 bits |
159 | * contain integer component, lower 16 bits contain fractional component | 135 | * contain integer component, lower 16 bits contain fractional component |
160 | * of active duty cycle e.g. 0x21BDC0 = 0xEFF0 * 0x24 | 136 | * of active duty cycle e.g. 0x21BDC0 = 0xEFF0 * 0x24 |
161 | */ | 137 | */ |
162 | active_duty_cycle = backlight_17bit * masked_pwm_period; | 138 | active_duty_cycle = backlight_pwm_u16_16 * masked_pwm_period; |
163 | 139 | ||
164 | /* 2.3 Calculate 16 bit active duty cycle from integer and fractional | 140 | /* 1.3 Calculate 16 bit active duty cycle from integer and fractional |
165 | * components shift by bitCount then mask 16 bits and add rounding bit | 141 | * components shift by bitCount then mask 16 bits and add rounding bit |
166 | * from MSB of fraction e.g. 0x86F7 = ((0x21BDC0 >> 6) & 0xFFF) + 0 | 142 | * from MSB of fraction e.g. 0x86F7 = ((0x21BDC0 >> 6) & 0xFFF) + 0 |
167 | */ | 143 | */ |
@@ -170,23 +146,23 @@ static void driver_set_backlight_level(struct dce_abm *abm_dce, uint32_t level) | |||
170 | backlight_16bit += (active_duty_cycle >> (bit_count - 1)) & 0x1; | 146 | backlight_16bit += (active_duty_cycle >> (bit_count - 1)) & 0x1; |
171 | 147 | ||
172 | /* | 148 | /* |
173 | * 3. Program register with updated value | 149 | * 2. Program register with updated value |
174 | */ | 150 | */ |
175 | 151 | ||
176 | /* 3.1 Lock group 2 backlight registers */ | 152 | /* 2.1 Lock group 2 backlight registers */ |
177 | 153 | ||
178 | REG_UPDATE_2(BL_PWM_GRP1_REG_LOCK, | 154 | REG_UPDATE_2(BL_PWM_GRP1_REG_LOCK, |
179 | BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN, 1, | 155 | BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN, 1, |
180 | BL_PWM_GRP1_REG_LOCK, 1); | 156 | BL_PWM_GRP1_REG_LOCK, 1); |
181 | 157 | ||
182 | // 3.2 Write new active duty cycle | 158 | // 2.2 Write new active duty cycle |
183 | REG_UPDATE(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, backlight_16bit); | 159 | REG_UPDATE(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, backlight_16bit); |
184 | 160 | ||
185 | /* 3.3 Unlock group 2 backlight registers */ | 161 | /* 2.3 Unlock group 2 backlight registers */ |
186 | REG_UPDATE(BL_PWM_GRP1_REG_LOCK, | 162 | REG_UPDATE(BL_PWM_GRP1_REG_LOCK, |
187 | BL_PWM_GRP1_REG_LOCK, 0); | 163 | BL_PWM_GRP1_REG_LOCK, 0); |
188 | 164 | ||
189 | /* 5.4.4 Wait for pending bit to be cleared */ | 165 | /* 3 Wait for pending bit to be cleared */ |
190 | REG_WAIT(BL_PWM_GRP1_REG_LOCK, | 166 | REG_WAIT(BL_PWM_GRP1_REG_LOCK, |
191 | BL_PWM_GRP1_REG_UPDATE_PENDING, 0, | 167 | BL_PWM_GRP1_REG_UPDATE_PENDING, 0, |
192 | 1, 10000); | 168 | 1, 10000); |
@@ -194,16 +170,21 @@ static void driver_set_backlight_level(struct dce_abm *abm_dce, uint32_t level) | |||
194 | 170 | ||
195 | static void dmcu_set_backlight_level( | 171 | static void dmcu_set_backlight_level( |
196 | struct dce_abm *abm_dce, | 172 | struct dce_abm *abm_dce, |
197 | uint32_t level, | 173 | uint32_t backlight_pwm_u16_16, |
198 | uint32_t frame_ramp, | 174 | uint32_t frame_ramp, |
199 | uint32_t controller_id) | 175 | uint32_t controller_id) |
200 | { | 176 | { |
201 | unsigned int backlight_16_bit = (level * 0x10101) >> 8; | 177 | unsigned int backlight_8_bit = 0; |
202 | unsigned int backlight_17_bit = backlight_16_bit + | ||
203 | (((backlight_16_bit & 0x80) >> 7) & 1); | ||
204 | uint32_t rampingBoundary = 0xFFFF; | 178 | uint32_t rampingBoundary = 0xFFFF; |
205 | uint32_t s2; | 179 | uint32_t s2; |
206 | 180 | ||
181 | if (backlight_pwm_u16_16 & 0x10000) | ||
182 | // Check for max backlight condition | ||
183 | backlight_8_bit = 0xFF; | ||
184 | else | ||
185 | // Take MSB of fractional part since backlight is not max | ||
186 | backlight_8_bit = (backlight_pwm_u16_16 >> 8) & 0xFF; | ||
187 | |||
207 | /* set ramping boundary */ | 188 | /* set ramping boundary */ |
208 | REG_WRITE(MASTER_COMM_DATA_REG1, rampingBoundary); | 189 | REG_WRITE(MASTER_COMM_DATA_REG1, rampingBoundary); |
209 | 190 | ||
@@ -220,7 +201,7 @@ static void dmcu_set_backlight_level( | |||
220 | 0, 1, 80000); | 201 | 0, 1, 80000); |
221 | 202 | ||
222 | /* setDMCUParam_BL */ | 203 | /* setDMCUParam_BL */ |
223 | REG_UPDATE(BL1_PWM_USER_LEVEL, BL1_PWM_USER_LEVEL, backlight_17_bit); | 204 | REG_UPDATE(BL1_PWM_USER_LEVEL, BL1_PWM_USER_LEVEL, backlight_pwm_u16_16); |
224 | 205 | ||
225 | /* write ramp */ | 206 | /* write ramp */ |
226 | if (controller_id == 0) | 207 | if (controller_id == 0) |
@@ -237,9 +218,9 @@ static void dmcu_set_backlight_level( | |||
237 | s2 = REG_READ(BIOS_SCRATCH_2); | 218 | s2 = REG_READ(BIOS_SCRATCH_2); |
238 | 219 | ||
239 | s2 &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK; | 220 | s2 &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK; |
240 | level &= (ATOM_S2_CURRENT_BL_LEVEL_MASK >> | 221 | backlight_8_bit &= (ATOM_S2_CURRENT_BL_LEVEL_MASK >> |
241 | ATOM_S2_CURRENT_BL_LEVEL_SHIFT); | 222 | ATOM_S2_CURRENT_BL_LEVEL_SHIFT); |
242 | s2 |= (level << ATOM_S2_CURRENT_BL_LEVEL_SHIFT); | 223 | s2 |= (backlight_8_bit << ATOM_S2_CURRENT_BL_LEVEL_SHIFT); |
243 | 224 | ||
244 | REG_WRITE(BIOS_SCRATCH_2, s2); | 225 | REG_WRITE(BIOS_SCRATCH_2, s2); |
245 | } | 226 | } |
@@ -247,7 +228,7 @@ static void dmcu_set_backlight_level( | |||
247 | static void dce_abm_init(struct abm *abm) | 228 | static void dce_abm_init(struct abm *abm) |
248 | { | 229 | { |
249 | struct dce_abm *abm_dce = TO_DCE_ABM(abm); | 230 | struct dce_abm *abm_dce = TO_DCE_ABM(abm); |
250 | unsigned int backlight = get_current_backlight_16_bit(abm_dce); | 231 | unsigned int backlight = calculate_16_bit_backlight_from_pwm(abm_dce); |
251 | 232 | ||
252 | REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x103); | 233 | REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x103); |
253 | REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x101); | 234 | REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x101); |
@@ -284,12 +265,26 @@ static void dce_abm_init(struct abm *abm) | |||
284 | ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, 1); | 265 | ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, 1); |
285 | } | 266 | } |
286 | 267 | ||
287 | static unsigned int dce_abm_get_current_backlight_8_bit(struct abm *abm) | 268 | static unsigned int dce_abm_get_current_backlight(struct abm *abm) |
288 | { | 269 | { |
289 | struct dce_abm *abm_dce = TO_DCE_ABM(abm); | 270 | struct dce_abm *abm_dce = TO_DCE_ABM(abm); |
290 | unsigned int backlight = REG_READ(BL1_PWM_CURRENT_ABM_LEVEL); | 271 | unsigned int backlight = REG_READ(BL1_PWM_CURRENT_ABM_LEVEL); |
291 | 272 | ||
292 | return (backlight >> 8); | 273 | /* return backlight in hardware format which is unsigned 17 bits, with |
274 | * 1 bit integer and 16 bit fractional | ||
275 | */ | ||
276 | return backlight; | ||
277 | } | ||
278 | |||
279 | static unsigned int dce_abm_get_target_backlight(struct abm *abm) | ||
280 | { | ||
281 | struct dce_abm *abm_dce = TO_DCE_ABM(abm); | ||
282 | unsigned int backlight = REG_READ(BL1_PWM_TARGET_ABM_LEVEL); | ||
283 | |||
284 | /* return backlight in hardware format which is unsigned 17 bits, with | ||
285 | * 1 bit integer and 16 bit fractional | ||
286 | */ | ||
287 | return backlight; | ||
293 | } | 288 | } |
294 | 289 | ||
295 | static bool dce_abm_set_level(struct abm *abm, uint32_t level) | 290 | static bool dce_abm_set_level(struct abm *abm, uint32_t level) |
@@ -396,9 +391,9 @@ static bool dce_abm_init_backlight(struct abm *abm) | |||
396 | return true; | 391 | return true; |
397 | } | 392 | } |
398 | 393 | ||
399 | static bool dce_abm_set_backlight_level( | 394 | static bool dce_abm_set_backlight_level_pwm( |
400 | struct abm *abm, | 395 | struct abm *abm, |
401 | unsigned int backlight_level, | 396 | unsigned int backlight_pwm_u16_16, |
402 | unsigned int frame_ramp, | 397 | unsigned int frame_ramp, |
403 | unsigned int controller_id, | 398 | unsigned int controller_id, |
404 | bool use_smooth_brightness) | 399 | bool use_smooth_brightness) |
@@ -406,16 +401,16 @@ static bool dce_abm_set_backlight_level( | |||
406 | struct dce_abm *abm_dce = TO_DCE_ABM(abm); | 401 | struct dce_abm *abm_dce = TO_DCE_ABM(abm); |
407 | 402 | ||
408 | DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n", | 403 | DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n", |
409 | backlight_level, backlight_level); | 404 | backlight_pwm_u16_16, backlight_pwm_u16_16); |
410 | 405 | ||
411 | /* If DMCU is in reset state, DMCU is uninitialized */ | 406 | /* If DMCU is in reset state, DMCU is uninitialized */ |
412 | if (use_smooth_brightness) | 407 | if (use_smooth_brightness) |
413 | dmcu_set_backlight_level(abm_dce, | 408 | dmcu_set_backlight_level(abm_dce, |
414 | backlight_level, | 409 | backlight_pwm_u16_16, |
415 | frame_ramp, | 410 | frame_ramp, |
416 | controller_id); | 411 | controller_id); |
417 | else | 412 | else |
418 | driver_set_backlight_level(abm_dce, backlight_level); | 413 | driver_set_backlight_level(abm_dce, backlight_pwm_u16_16); |
419 | 414 | ||
420 | return true; | 415 | return true; |
421 | } | 416 | } |
@@ -424,8 +419,9 @@ static const struct abm_funcs dce_funcs = { | |||
424 | .abm_init = dce_abm_init, | 419 | .abm_init = dce_abm_init, |
425 | .set_abm_level = dce_abm_set_level, | 420 | .set_abm_level = dce_abm_set_level, |
426 | .init_backlight = dce_abm_init_backlight, | 421 | .init_backlight = dce_abm_init_backlight, |
427 | .set_backlight_level = dce_abm_set_backlight_level, | 422 | .set_backlight_level_pwm = dce_abm_set_backlight_level_pwm, |
428 | .get_current_backlight_8_bit = dce_abm_get_current_backlight_8_bit, | 423 | .get_current_backlight = dce_abm_get_current_backlight, |
424 | .get_target_backlight = dce_abm_get_target_backlight, | ||
429 | .set_abm_immediate_disable = dce_abm_immediate_disable | 425 | .set_abm_immediate_disable = dce_abm_immediate_disable |
430 | }; | 426 | }; |
431 | 427 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c new file mode 100644 index 000000000000..9a28a04417d1 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c | |||
@@ -0,0 +1,879 @@ | |||
1 | /* | ||
2 | * Copyright 2012-16 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: AMD | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #include "dce_clk_mgr.h" | ||
27 | |||
28 | #include "reg_helper.h" | ||
29 | #include "dmcu.h" | ||
30 | #include "core_types.h" | ||
31 | #include "dal_asic_id.h" | ||
32 | |||
33 | #define TO_DCE_CLK_MGR(clocks)\ | ||
34 | container_of(clocks, struct dce_clk_mgr, base) | ||
35 | |||
36 | #define REG(reg) \ | ||
37 | (clk_mgr_dce->regs->reg) | ||
38 | |||
39 | #undef FN | ||
40 | #define FN(reg_name, field_name) \ | ||
41 | clk_mgr_dce->clk_mgr_shift->field_name, clk_mgr_dce->clk_mgr_mask->field_name | ||
42 | |||
43 | #define CTX \ | ||
44 | clk_mgr_dce->base.ctx | ||
45 | #define DC_LOGGER \ | ||
46 | clk_mgr->ctx->logger | ||
47 | |||
48 | /* Max clock values for each state indexed by "enum clocks_state": */ | ||
49 | static const struct state_dependent_clocks dce80_max_clks_by_state[] = { | ||
50 | /* ClocksStateInvalid - should not be used */ | ||
51 | { .display_clk_khz = 0, .pixel_clk_khz = 0 }, | ||
52 | /* ClocksStateUltraLow - not expected to be used for DCE 8.0 */ | ||
53 | { .display_clk_khz = 0, .pixel_clk_khz = 0 }, | ||
54 | /* ClocksStateLow */ | ||
55 | { .display_clk_khz = 352000, .pixel_clk_khz = 330000}, | ||
56 | /* ClocksStateNominal */ | ||
57 | { .display_clk_khz = 600000, .pixel_clk_khz = 400000 }, | ||
58 | /* ClocksStatePerformance */ | ||
59 | { .display_clk_khz = 600000, .pixel_clk_khz = 400000 } }; | ||
60 | |||
61 | static const struct state_dependent_clocks dce110_max_clks_by_state[] = { | ||
62 | /*ClocksStateInvalid - should not be used*/ | ||
63 | { .display_clk_khz = 0, .pixel_clk_khz = 0 }, | ||
64 | /*ClocksStateUltraLow - currently by HW design team not supposed to be used*/ | ||
65 | { .display_clk_khz = 352000, .pixel_clk_khz = 330000 }, | ||
66 | /*ClocksStateLow*/ | ||
67 | { .display_clk_khz = 352000, .pixel_clk_khz = 330000 }, | ||
68 | /*ClocksStateNominal*/ | ||
69 | { .display_clk_khz = 467000, .pixel_clk_khz = 400000 }, | ||
70 | /*ClocksStatePerformance*/ | ||
71 | { .display_clk_khz = 643000, .pixel_clk_khz = 400000 } }; | ||
72 | |||
73 | static const struct state_dependent_clocks dce112_max_clks_by_state[] = { | ||
74 | /*ClocksStateInvalid - should not be used*/ | ||
75 | { .display_clk_khz = 0, .pixel_clk_khz = 0 }, | ||
76 | /*ClocksStateUltraLow - currently by HW design team not supposed to be used*/ | ||
77 | { .display_clk_khz = 389189, .pixel_clk_khz = 346672 }, | ||
78 | /*ClocksStateLow*/ | ||
79 | { .display_clk_khz = 459000, .pixel_clk_khz = 400000 }, | ||
80 | /*ClocksStateNominal*/ | ||
81 | { .display_clk_khz = 667000, .pixel_clk_khz = 600000 }, | ||
82 | /*ClocksStatePerformance*/ | ||
83 | { .display_clk_khz = 1132000, .pixel_clk_khz = 600000 } }; | ||
84 | |||
85 | static const struct state_dependent_clocks dce120_max_clks_by_state[] = { | ||
86 | /*ClocksStateInvalid - should not be used*/ | ||
87 | { .display_clk_khz = 0, .pixel_clk_khz = 0 }, | ||
88 | /*ClocksStateUltraLow - currently by HW design team not supposed to be used*/ | ||
89 | { .display_clk_khz = 0, .pixel_clk_khz = 0 }, | ||
90 | /*ClocksStateLow*/ | ||
91 | { .display_clk_khz = 460000, .pixel_clk_khz = 400000 }, | ||
92 | /*ClocksStateNominal*/ | ||
93 | { .display_clk_khz = 670000, .pixel_clk_khz = 600000 }, | ||
94 | /*ClocksStatePerformance*/ | ||
95 | { .display_clk_khz = 1133000, .pixel_clk_khz = 600000 } }; | ||
96 | |||
97 | static int dentist_get_divider_from_did(int did) | ||
98 | { | ||
99 | if (did < DENTIST_BASE_DID_1) | ||
100 | did = DENTIST_BASE_DID_1; | ||
101 | if (did > DENTIST_MAX_DID) | ||
102 | did = DENTIST_MAX_DID; | ||
103 | |||
104 | if (did < DENTIST_BASE_DID_2) { | ||
105 | return DENTIST_DIVIDER_RANGE_1_START + DENTIST_DIVIDER_RANGE_1_STEP | ||
106 | * (did - DENTIST_BASE_DID_1); | ||
107 | } else if (did < DENTIST_BASE_DID_3) { | ||
108 | return DENTIST_DIVIDER_RANGE_2_START + DENTIST_DIVIDER_RANGE_2_STEP | ||
109 | * (did - DENTIST_BASE_DID_2); | ||
110 | } else if (did < DENTIST_BASE_DID_4) { | ||
111 | return DENTIST_DIVIDER_RANGE_3_START + DENTIST_DIVIDER_RANGE_3_STEP | ||
112 | * (did - DENTIST_BASE_DID_3); | ||
113 | } else { | ||
114 | return DENTIST_DIVIDER_RANGE_4_START + DENTIST_DIVIDER_RANGE_4_STEP | ||
115 | * (did - DENTIST_BASE_DID_4); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | /* SW will adjust DP REF Clock average value for all purposes | ||
120 | * (DP DTO / DP Audio DTO and DP GTC) | ||
121 | if clock is spread for all cases: | ||
122 | -if SS enabled on DP Ref clock and HW de-spreading enabled with SW | ||
123 | calculations for DS_INCR/DS_MODULO (this is planned to be default case) | ||
124 | -if SS enabled on DP Ref clock and HW de-spreading enabled with HW | ||
125 | calculations (not planned to be used, but average clock should still | ||
126 | be valid) | ||
127 | -if SS enabled on DP Ref clock and HW de-spreading disabled | ||
128 | (should not be case with CIK) then SW should program all rates | ||
129 | generated according to average value (case as with previous ASICs) | ||
130 | */ | ||
131 | static int clk_mgr_adjust_dp_ref_freq_for_ss(struct dce_clk_mgr *clk_mgr_dce, int dp_ref_clk_khz) | ||
132 | { | ||
133 | if (clk_mgr_dce->ss_on_dprefclk && clk_mgr_dce->dprefclk_ss_divider != 0) { | ||
134 | struct fixed31_32 ss_percentage = dc_fixpt_div_int( | ||
135 | dc_fixpt_from_fraction(clk_mgr_dce->dprefclk_ss_percentage, | ||
136 | clk_mgr_dce->dprefclk_ss_divider), 200); | ||
137 | struct fixed31_32 adj_dp_ref_clk_khz; | ||
138 | |||
139 | ss_percentage = dc_fixpt_sub(dc_fixpt_one, ss_percentage); | ||
140 | adj_dp_ref_clk_khz = dc_fixpt_mul_int(ss_percentage, dp_ref_clk_khz); | ||
141 | dp_ref_clk_khz = dc_fixpt_floor(adj_dp_ref_clk_khz); | ||
142 | } | ||
143 | return dp_ref_clk_khz; | ||
144 | } | ||
145 | |||
146 | static int dce_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr) | ||
147 | { | ||
148 | struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); | ||
149 | int dprefclk_wdivider; | ||
150 | int dprefclk_src_sel; | ||
151 | int dp_ref_clk_khz = 600000; | ||
152 | int target_div; | ||
153 | |||
154 | /* ASSERT DP Reference Clock source is from DFS*/ | ||
155 | REG_GET(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, &dprefclk_src_sel); | ||
156 | ASSERT(dprefclk_src_sel == 0); | ||
157 | |||
158 | /* Read the mmDENTIST_DISPCLK_CNTL to get the currently | ||
159 | * programmed DID DENTIST_DPREFCLK_WDIVIDER*/ | ||
160 | REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, &dprefclk_wdivider); | ||
161 | |||
162 | /* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/ | ||
163 | target_div = dentist_get_divider_from_did(dprefclk_wdivider); | ||
164 | |||
165 | /* Calculate the current DFS clock, in kHz.*/ | ||
166 | dp_ref_clk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR | ||
167 | * clk_mgr_dce->dentist_vco_freq_khz) / target_div; | ||
168 | |||
169 | return clk_mgr_adjust_dp_ref_freq_for_ss(clk_mgr_dce, dp_ref_clk_khz); | ||
170 | } | ||
171 | |||
172 | int dce12_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr) | ||
173 | { | ||
174 | struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); | ||
175 | |||
176 | return clk_mgr_adjust_dp_ref_freq_for_ss(clk_mgr_dce, clk_mgr_dce->dprefclk_khz); | ||
177 | } | ||
178 | |||
179 | /* unit: in_khz before mode set, get pixel clock from context. ASIC register | ||
180 | * may not be programmed yet | ||
181 | */ | ||
182 | static uint32_t get_max_pixel_clock_for_all_paths(struct dc_state *context) | ||
183 | { | ||
184 | uint32_t max_pix_clk = 0; | ||
185 | int i; | ||
186 | |||
187 | for (i = 0; i < MAX_PIPES; i++) { | ||
188 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | ||
189 | |||
190 | if (pipe_ctx->stream == NULL) | ||
191 | continue; | ||
192 | |||
193 | /* do not check under lay */ | ||
194 | if (pipe_ctx->top_pipe) | ||
195 | continue; | ||
196 | |||
197 | if (pipe_ctx->stream_res.pix_clk_params.requested_pix_clk > max_pix_clk) | ||
198 | max_pix_clk = pipe_ctx->stream_res.pix_clk_params.requested_pix_clk; | ||
199 | |||
200 | /* raise clock state for HBR3/2 if required. Confirmed with HW DCE/DPCS | ||
201 | * logic for HBR3 still needs Nominal (0.8V) on VDDC rail | ||
202 | */ | ||
203 | if (dc_is_dp_signal(pipe_ctx->stream->signal) && | ||
204 | pipe_ctx->stream_res.pix_clk_params.requested_sym_clk > max_pix_clk) | ||
205 | max_pix_clk = pipe_ctx->stream_res.pix_clk_params.requested_sym_clk; | ||
206 | } | ||
207 | |||
208 | return max_pix_clk; | ||
209 | } | ||
210 | |||
211 | static enum dm_pp_clocks_state dce_get_required_clocks_state( | ||
212 | struct clk_mgr *clk_mgr, | ||
213 | struct dc_state *context) | ||
214 | { | ||
215 | struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); | ||
216 | int i; | ||
217 | enum dm_pp_clocks_state low_req_clk; | ||
218 | int max_pix_clk = get_max_pixel_clock_for_all_paths(context); | ||
219 | |||
220 | /* Iterate from highest supported to lowest valid state, and update | ||
221 | * lowest RequiredState with the lowest state that satisfies | ||
222 | * all required clocks | ||
223 | */ | ||
224 | for (i = clk_mgr_dce->max_clks_state; i >= DM_PP_CLOCKS_STATE_ULTRA_LOW; i--) | ||
225 | if (context->bw.dce.dispclk_khz > | ||
226 | clk_mgr_dce->max_clks_by_state[i].display_clk_khz | ||
227 | || max_pix_clk > | ||
228 | clk_mgr_dce->max_clks_by_state[i].pixel_clk_khz) | ||
229 | break; | ||
230 | |||
231 | low_req_clk = i + 1; | ||
232 | if (low_req_clk > clk_mgr_dce->max_clks_state) { | ||
233 | /* set max clock state for high phyclock, invalid on exceeding display clock */ | ||
234 | if (clk_mgr_dce->max_clks_by_state[clk_mgr_dce->max_clks_state].display_clk_khz | ||
235 | < context->bw.dce.dispclk_khz) | ||
236 | low_req_clk = DM_PP_CLOCKS_STATE_INVALID; | ||
237 | else | ||
238 | low_req_clk = clk_mgr_dce->max_clks_state; | ||
239 | } | ||
240 | |||
241 | return low_req_clk; | ||
242 | } | ||
243 | |||
244 | static int dce_set_clock( | ||
245 | struct clk_mgr *clk_mgr, | ||
246 | int requested_clk_khz) | ||
247 | { | ||
248 | struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); | ||
249 | struct bp_pixel_clock_parameters pxl_clk_params = { 0 }; | ||
250 | struct dc_bios *bp = clk_mgr->ctx->dc_bios; | ||
251 | int actual_clock = requested_clk_khz; | ||
252 | struct dmcu *dmcu = clk_mgr_dce->base.ctx->dc->res_pool->dmcu; | ||
253 | |||
254 | /* Make sure requested clock isn't lower than minimum threshold*/ | ||
255 | if (requested_clk_khz > 0) | ||
256 | requested_clk_khz = max(requested_clk_khz, | ||
257 | clk_mgr_dce->dentist_vco_freq_khz / 64); | ||
258 | |||
259 | /* Prepare to program display clock*/ | ||
260 | pxl_clk_params.target_pixel_clock = requested_clk_khz; | ||
261 | pxl_clk_params.pll_id = CLOCK_SOURCE_ID_DFS; | ||
262 | |||
263 | if (clk_mgr_dce->dfs_bypass_active) | ||
264 | pxl_clk_params.flags.SET_DISPCLK_DFS_BYPASS = true; | ||
265 | |||
266 | bp->funcs->program_display_engine_pll(bp, &pxl_clk_params); | ||
267 | |||
268 | if (clk_mgr_dce->dfs_bypass_active) { | ||
269 | /* Cache the fixed display clock*/ | ||
270 | clk_mgr_dce->dfs_bypass_disp_clk = | ||
271 | pxl_clk_params.dfs_bypass_display_clock; | ||
272 | actual_clock = pxl_clk_params.dfs_bypass_display_clock; | ||
273 | } | ||
274 | |||
275 | /* from power down, we need mark the clock state as ClocksStateNominal | ||
276 | * from HWReset, so when resume we will call pplib voltage regulator.*/ | ||
277 | if (requested_clk_khz == 0) | ||
278 | clk_mgr_dce->cur_min_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; | ||
279 | |||
280 | dmcu->funcs->set_psr_wait_loop(dmcu, actual_clock / 1000 / 7); | ||
281 | |||
282 | return actual_clock; | ||
283 | } | ||
284 | |||
285 | int dce112_set_clock(struct clk_mgr *clk_mgr, int requested_clk_khz) | ||
286 | { | ||
287 | struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); | ||
288 | struct bp_set_dce_clock_parameters dce_clk_params; | ||
289 | struct dc_bios *bp = clk_mgr->ctx->dc_bios; | ||
290 | struct dc *core_dc = clk_mgr->ctx->dc; | ||
291 | struct dmcu *dmcu = core_dc->res_pool->dmcu; | ||
292 | int actual_clock = requested_clk_khz; | ||
293 | /* Prepare to program display clock*/ | ||
294 | memset(&dce_clk_params, 0, sizeof(dce_clk_params)); | ||
295 | |||
296 | /* Make sure requested clock isn't lower than minimum threshold*/ | ||
297 | if (requested_clk_khz > 0) | ||
298 | requested_clk_khz = max(requested_clk_khz, | ||
299 | clk_mgr_dce->dentist_vco_freq_khz / 62); | ||
300 | |||
301 | dce_clk_params.target_clock_frequency = requested_clk_khz; | ||
302 | dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS; | ||
303 | dce_clk_params.clock_type = DCECLOCK_TYPE_DISPLAY_CLOCK; | ||
304 | |||
305 | bp->funcs->set_dce_clock(bp, &dce_clk_params); | ||
306 | actual_clock = dce_clk_params.target_clock_frequency; | ||
307 | |||
308 | /* from power down, we need mark the clock state as ClocksStateNominal | ||
309 | * from HWReset, so when resume we will call pplib voltage regulator.*/ | ||
310 | if (requested_clk_khz == 0) | ||
311 | clk_mgr_dce->cur_min_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; | ||
312 | |||
313 | /*Program DP ref Clock*/ | ||
314 | /*VBIOS will determine DPREFCLK frequency, so we don't set it*/ | ||
315 | dce_clk_params.target_clock_frequency = 0; | ||
316 | dce_clk_params.clock_type = DCECLOCK_TYPE_DPREFCLK; | ||
317 | if (!ASICREV_IS_VEGA20_P(clk_mgr->ctx->asic_id.hw_internal_rev)) | ||
318 | dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = | ||
319 | (dce_clk_params.pll_id == | ||
320 | CLOCK_SOURCE_COMBO_DISPLAY_PLL0); | ||
321 | else | ||
322 | dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = false; | ||
323 | |||
324 | bp->funcs->set_dce_clock(bp, &dce_clk_params); | ||
325 | |||
326 | if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) { | ||
327 | if (clk_mgr_dce->dfs_bypass_disp_clk != actual_clock) | ||
328 | dmcu->funcs->set_psr_wait_loop(dmcu, | ||
329 | actual_clock / 1000 / 7); | ||
330 | } | ||
331 | |||
332 | clk_mgr_dce->dfs_bypass_disp_clk = actual_clock; | ||
333 | return actual_clock; | ||
334 | } | ||
335 | |||
336 | static void dce_clock_read_integrated_info(struct dce_clk_mgr *clk_mgr_dce) | ||
337 | { | ||
338 | struct dc_debug_options *debug = &clk_mgr_dce->base.ctx->dc->debug; | ||
339 | struct dc_bios *bp = clk_mgr_dce->base.ctx->dc_bios; | ||
340 | struct integrated_info info = { { { 0 } } }; | ||
341 | struct dc_firmware_info fw_info = { { 0 } }; | ||
342 | int i; | ||
343 | |||
344 | if (bp->integrated_info) | ||
345 | info = *bp->integrated_info; | ||
346 | |||
347 | clk_mgr_dce->dentist_vco_freq_khz = info.dentist_vco_freq; | ||
348 | if (clk_mgr_dce->dentist_vco_freq_khz == 0) { | ||
349 | bp->funcs->get_firmware_info(bp, &fw_info); | ||
350 | clk_mgr_dce->dentist_vco_freq_khz = | ||
351 | fw_info.smu_gpu_pll_output_freq; | ||
352 | if (clk_mgr_dce->dentist_vco_freq_khz == 0) | ||
353 | clk_mgr_dce->dentist_vco_freq_khz = 3600000; | ||
354 | } | ||
355 | |||
356 | /*update the maximum display clock for each power state*/ | ||
357 | for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { | ||
358 | enum dm_pp_clocks_state clk_state = DM_PP_CLOCKS_STATE_INVALID; | ||
359 | |||
360 | switch (i) { | ||
361 | case 0: | ||
362 | clk_state = DM_PP_CLOCKS_STATE_ULTRA_LOW; | ||
363 | break; | ||
364 | |||
365 | case 1: | ||
366 | clk_state = DM_PP_CLOCKS_STATE_LOW; | ||
367 | break; | ||
368 | |||
369 | case 2: | ||
370 | clk_state = DM_PP_CLOCKS_STATE_NOMINAL; | ||
371 | break; | ||
372 | |||
373 | case 3: | ||
374 | clk_state = DM_PP_CLOCKS_STATE_PERFORMANCE; | ||
375 | break; | ||
376 | |||
377 | default: | ||
378 | clk_state = DM_PP_CLOCKS_STATE_INVALID; | ||
379 | break; | ||
380 | } | ||
381 | |||
382 | /*Do not allow bad VBIOS/SBIOS to override with invalid values, | ||
383 | * check for > 100MHz*/ | ||
384 | if (info.disp_clk_voltage[i].max_supported_clk >= 100000) | ||
385 | clk_mgr_dce->max_clks_by_state[clk_state].display_clk_khz = | ||
386 | info.disp_clk_voltage[i].max_supported_clk; | ||
387 | } | ||
388 | |||
389 | if (!debug->disable_dfs_bypass && bp->integrated_info) | ||
390 | if (bp->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE) | ||
391 | clk_mgr_dce->dfs_bypass_enabled = true; | ||
392 | } | ||
393 | |||
394 | void dce_clock_read_ss_info(struct dce_clk_mgr *clk_mgr_dce) | ||
395 | { | ||
396 | struct dc_bios *bp = clk_mgr_dce->base.ctx->dc_bios; | ||
397 | int ss_info_num = bp->funcs->get_ss_entry_number( | ||
398 | bp, AS_SIGNAL_TYPE_GPU_PLL); | ||
399 | |||
400 | if (ss_info_num) { | ||
401 | struct spread_spectrum_info info = { { 0 } }; | ||
402 | enum bp_result result = bp->funcs->get_spread_spectrum_info( | ||
403 | bp, AS_SIGNAL_TYPE_GPU_PLL, 0, &info); | ||
404 | |||
405 | /* Based on VBIOS, VBIOS will keep entry for GPU PLL SS | ||
406 | * even if SS not enabled and in that case | ||
407 | * SSInfo.spreadSpectrumPercentage !=0 would be sign | ||
408 | * that SS is enabled | ||
409 | */ | ||
410 | if (result == BP_RESULT_OK && | ||
411 | info.spread_spectrum_percentage != 0) { | ||
412 | clk_mgr_dce->ss_on_dprefclk = true; | ||
413 | clk_mgr_dce->dprefclk_ss_divider = info.spread_percentage_divider; | ||
414 | |||
415 | if (info.type.CENTER_MODE == 0) { | ||
416 | /* TODO: Currently for DP Reference clock we | ||
417 | * need only SS percentage for | ||
418 | * downspread */ | ||
419 | clk_mgr_dce->dprefclk_ss_percentage = | ||
420 | info.spread_spectrum_percentage; | ||
421 | } | ||
422 | |||
423 | return; | ||
424 | } | ||
425 | |||
426 | result = bp->funcs->get_spread_spectrum_info( | ||
427 | bp, AS_SIGNAL_TYPE_DISPLAY_PORT, 0, &info); | ||
428 | |||
429 | /* Based on VBIOS, VBIOS will keep entry for DPREFCLK SS | ||
430 | * even if SS not enabled and in that case | ||
431 | * SSInfo.spreadSpectrumPercentage !=0 would be sign | ||
432 | * that SS is enabled | ||
433 | */ | ||
434 | if (result == BP_RESULT_OK && | ||
435 | info.spread_spectrum_percentage != 0) { | ||
436 | clk_mgr_dce->ss_on_dprefclk = true; | ||
437 | clk_mgr_dce->dprefclk_ss_divider = info.spread_percentage_divider; | ||
438 | |||
439 | if (info.type.CENTER_MODE == 0) { | ||
440 | /* Currently for DP Reference clock we | ||
441 | * need only SS percentage for | ||
442 | * downspread */ | ||
443 | clk_mgr_dce->dprefclk_ss_percentage = | ||
444 | info.spread_spectrum_percentage; | ||
445 | } | ||
446 | } | ||
447 | } | ||
448 | } | ||
449 | |||
450 | void dce110_fill_display_configs( | ||
451 | const struct dc_state *context, | ||
452 | struct dm_pp_display_configuration *pp_display_cfg) | ||
453 | { | ||
454 | int j; | ||
455 | int num_cfgs = 0; | ||
456 | |||
457 | for (j = 0; j < context->stream_count; j++) { | ||
458 | int k; | ||
459 | |||
460 | const struct dc_stream_state *stream = context->streams[j]; | ||
461 | struct dm_pp_single_disp_config *cfg = | ||
462 | &pp_display_cfg->disp_configs[num_cfgs]; | ||
463 | const struct pipe_ctx *pipe_ctx = NULL; | ||
464 | |||
465 | for (k = 0; k < MAX_PIPES; k++) | ||
466 | if (stream == context->res_ctx.pipe_ctx[k].stream) { | ||
467 | pipe_ctx = &context->res_ctx.pipe_ctx[k]; | ||
468 | break; | ||
469 | } | ||
470 | |||
471 | ASSERT(pipe_ctx != NULL); | ||
472 | |||
473 | /* only notify active stream */ | ||
474 | if (stream->dpms_off) | ||
475 | continue; | ||
476 | |||
477 | num_cfgs++; | ||
478 | cfg->signal = pipe_ctx->stream->signal; | ||
479 | cfg->pipe_idx = pipe_ctx->stream_res.tg->inst; | ||
480 | cfg->src_height = stream->src.height; | ||
481 | cfg->src_width = stream->src.width; | ||
482 | cfg->ddi_channel_mapping = | ||
483 | stream->sink->link->ddi_channel_mapping.raw; | ||
484 | cfg->transmitter = | ||
485 | stream->sink->link->link_enc->transmitter; | ||
486 | cfg->link_settings.lane_count = | ||
487 | stream->sink->link->cur_link_settings.lane_count; | ||
488 | cfg->link_settings.link_rate = | ||
489 | stream->sink->link->cur_link_settings.link_rate; | ||
490 | cfg->link_settings.link_spread = | ||
491 | stream->sink->link->cur_link_settings.link_spread; | ||
492 | cfg->sym_clock = stream->phy_pix_clk; | ||
493 | /* Round v_refresh*/ | ||
494 | cfg->v_refresh = stream->timing.pix_clk_khz * 1000; | ||
495 | cfg->v_refresh /= stream->timing.h_total; | ||
496 | cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total / 2) | ||
497 | / stream->timing.v_total; | ||
498 | } | ||
499 | |||
500 | pp_display_cfg->display_count = num_cfgs; | ||
501 | } | ||
502 | |||
503 | static uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context) | ||
504 | { | ||
505 | uint8_t j; | ||
506 | uint32_t min_vertical_blank_time = -1; | ||
507 | |||
508 | for (j = 0; j < context->stream_count; j++) { | ||
509 | struct dc_stream_state *stream = context->streams[j]; | ||
510 | uint32_t vertical_blank_in_pixels = 0; | ||
511 | uint32_t vertical_blank_time = 0; | ||
512 | |||
513 | vertical_blank_in_pixels = stream->timing.h_total * | ||
514 | (stream->timing.v_total | ||
515 | - stream->timing.v_addressable); | ||
516 | |||
517 | vertical_blank_time = vertical_blank_in_pixels | ||
518 | * 1000 / stream->timing.pix_clk_khz; | ||
519 | |||
520 | if (min_vertical_blank_time > vertical_blank_time) | ||
521 | min_vertical_blank_time = vertical_blank_time; | ||
522 | } | ||
523 | |||
524 | return min_vertical_blank_time; | ||
525 | } | ||
526 | |||
527 | static int determine_sclk_from_bounding_box( | ||
528 | const struct dc *dc, | ||
529 | int required_sclk) | ||
530 | { | ||
531 | int i; | ||
532 | |||
533 | /* | ||
534 | * Some asics do not give us sclk levels, so we just report the actual | ||
535 | * required sclk | ||
536 | */ | ||
537 | if (dc->sclk_lvls.num_levels == 0) | ||
538 | return required_sclk; | ||
539 | |||
540 | for (i = 0; i < dc->sclk_lvls.num_levels; i++) { | ||
541 | if (dc->sclk_lvls.clocks_in_khz[i] >= required_sclk) | ||
542 | return dc->sclk_lvls.clocks_in_khz[i]; | ||
543 | } | ||
544 | /* | ||
545 | * even maximum level could not satisfy requirement, this | ||
546 | * is unexpected at this stage, should have been caught at | ||
547 | * validation time | ||
548 | */ | ||
549 | ASSERT(0); | ||
550 | return dc->sclk_lvls.clocks_in_khz[dc->sclk_lvls.num_levels - 1]; | ||
551 | } | ||
552 | |||
553 | static void dce_pplib_apply_display_requirements( | ||
554 | struct dc *dc, | ||
555 | struct dc_state *context) | ||
556 | { | ||
557 | struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; | ||
558 | |||
559 | pp_display_cfg->avail_mclk_switch_time_us = dce110_get_min_vblank_time_us(context); | ||
560 | |||
561 | dce110_fill_display_configs(context, pp_display_cfg); | ||
562 | |||
563 | if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0) | ||
564 | dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); | ||
565 | } | ||
566 | |||
567 | static void dce11_pplib_apply_display_requirements( | ||
568 | struct dc *dc, | ||
569 | struct dc_state *context) | ||
570 | { | ||
571 | struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; | ||
572 | |||
573 | pp_display_cfg->all_displays_in_sync = | ||
574 | context->bw.dce.all_displays_in_sync; | ||
575 | pp_display_cfg->nb_pstate_switch_disable = | ||
576 | context->bw.dce.nbp_state_change_enable == false; | ||
577 | pp_display_cfg->cpu_cc6_disable = | ||
578 | context->bw.dce.cpuc_state_change_enable == false; | ||
579 | pp_display_cfg->cpu_pstate_disable = | ||
580 | context->bw.dce.cpup_state_change_enable == false; | ||
581 | pp_display_cfg->cpu_pstate_separation_time = | ||
582 | context->bw.dce.blackout_recovery_time_us; | ||
583 | |||
584 | pp_display_cfg->min_memory_clock_khz = context->bw.dce.yclk_khz | ||
585 | / MEMORY_TYPE_MULTIPLIER_CZ; | ||
586 | |||
587 | pp_display_cfg->min_engine_clock_khz = determine_sclk_from_bounding_box( | ||
588 | dc, | ||
589 | context->bw.dce.sclk_khz); | ||
590 | |||
591 | pp_display_cfg->min_engine_clock_deep_sleep_khz | ||
592 | = context->bw.dce.sclk_deep_sleep_khz; | ||
593 | |||
594 | pp_display_cfg->avail_mclk_switch_time_us = | ||
595 | dce110_get_min_vblank_time_us(context); | ||
596 | /* TODO: dce11.2*/ | ||
597 | pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0; | ||
598 | |||
599 | pp_display_cfg->disp_clk_khz = dc->res_pool->clk_mgr->clks.dispclk_khz; | ||
600 | |||
601 | dce110_fill_display_configs(context, pp_display_cfg); | ||
602 | |||
603 | /* TODO: is this still applicable?*/ | ||
604 | if (pp_display_cfg->display_count == 1) { | ||
605 | const struct dc_crtc_timing *timing = | ||
606 | &context->streams[0]->timing; | ||
607 | |||
608 | pp_display_cfg->crtc_index = | ||
609 | pp_display_cfg->disp_configs[0].pipe_idx; | ||
610 | pp_display_cfg->line_time_in_us = timing->h_total * 1000 / timing->pix_clk_khz; | ||
611 | } | ||
612 | |||
613 | if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0) | ||
614 | dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); | ||
615 | } | ||
616 | |||
617 | static void dce_update_clocks(struct clk_mgr *clk_mgr, | ||
618 | struct dc_state *context, | ||
619 | bool safe_to_lower) | ||
620 | { | ||
621 | struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); | ||
622 | struct dm_pp_power_level_change_request level_change_req; | ||
623 | int unpatched_disp_clk = context->bw.dce.dispclk_khz; | ||
624 | |||
625 | /*TODO: W/A for dal3 linux, investigate why this works */ | ||
626 | if (!clk_mgr_dce->dfs_bypass_active) | ||
627 | context->bw.dce.dispclk_khz = context->bw.dce.dispclk_khz * 115 / 100; | ||
628 | |||
629 | level_change_req.power_level = dce_get_required_clocks_state(clk_mgr, context); | ||
630 | /* get max clock state from PPLIB */ | ||
631 | if ((level_change_req.power_level < clk_mgr_dce->cur_min_clks_state && safe_to_lower) | ||
632 | || level_change_req.power_level > clk_mgr_dce->cur_min_clks_state) { | ||
633 | if (dm_pp_apply_power_level_change_request(clk_mgr->ctx, &level_change_req)) | ||
634 | clk_mgr_dce->cur_min_clks_state = level_change_req.power_level; | ||
635 | } | ||
636 | |||
637 | if (should_set_clock(safe_to_lower, context->bw.dce.dispclk_khz, clk_mgr->clks.dispclk_khz)) { | ||
638 | context->bw.dce.dispclk_khz = dce_set_clock(clk_mgr, context->bw.dce.dispclk_khz); | ||
639 | clk_mgr->clks.dispclk_khz = context->bw.dce.dispclk_khz; | ||
640 | } | ||
641 | dce_pplib_apply_display_requirements(clk_mgr->ctx->dc, context); | ||
642 | |||
643 | context->bw.dce.dispclk_khz = unpatched_disp_clk; | ||
644 | } | ||
645 | |||
646 | static void dce11_update_clocks(struct clk_mgr *clk_mgr, | ||
647 | struct dc_state *context, | ||
648 | bool safe_to_lower) | ||
649 | { | ||
650 | struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); | ||
651 | struct dm_pp_power_level_change_request level_change_req; | ||
652 | |||
653 | level_change_req.power_level = dce_get_required_clocks_state(clk_mgr, context); | ||
654 | /* get max clock state from PPLIB */ | ||
655 | if ((level_change_req.power_level < clk_mgr_dce->cur_min_clks_state && safe_to_lower) | ||
656 | || level_change_req.power_level > clk_mgr_dce->cur_min_clks_state) { | ||
657 | if (dm_pp_apply_power_level_change_request(clk_mgr->ctx, &level_change_req)) | ||
658 | clk_mgr_dce->cur_min_clks_state = level_change_req.power_level; | ||
659 | } | ||
660 | |||
661 | if (should_set_clock(safe_to_lower, context->bw.dce.dispclk_khz, clk_mgr->clks.dispclk_khz)) { | ||
662 | context->bw.dce.dispclk_khz = dce_set_clock(clk_mgr, context->bw.dce.dispclk_khz); | ||
663 | clk_mgr->clks.dispclk_khz = context->bw.dce.dispclk_khz; | ||
664 | } | ||
665 | dce11_pplib_apply_display_requirements(clk_mgr->ctx->dc, context); | ||
666 | } | ||
667 | |||
668 | static void dce112_update_clocks(struct clk_mgr *clk_mgr, | ||
669 | struct dc_state *context, | ||
670 | bool safe_to_lower) | ||
671 | { | ||
672 | struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); | ||
673 | struct dm_pp_power_level_change_request level_change_req; | ||
674 | |||
675 | level_change_req.power_level = dce_get_required_clocks_state(clk_mgr, context); | ||
676 | /* get max clock state from PPLIB */ | ||
677 | if ((level_change_req.power_level < clk_mgr_dce->cur_min_clks_state && safe_to_lower) | ||
678 | || level_change_req.power_level > clk_mgr_dce->cur_min_clks_state) { | ||
679 | if (dm_pp_apply_power_level_change_request(clk_mgr->ctx, &level_change_req)) | ||
680 | clk_mgr_dce->cur_min_clks_state = level_change_req.power_level; | ||
681 | } | ||
682 | |||
683 | if (should_set_clock(safe_to_lower, context->bw.dce.dispclk_khz, clk_mgr->clks.dispclk_khz)) { | ||
684 | context->bw.dce.dispclk_khz = dce112_set_clock(clk_mgr, context->bw.dce.dispclk_khz); | ||
685 | clk_mgr->clks.dispclk_khz = context->bw.dce.dispclk_khz; | ||
686 | } | ||
687 | dce11_pplib_apply_display_requirements(clk_mgr->ctx->dc, context); | ||
688 | } | ||
689 | |||
690 | static void dce12_update_clocks(struct clk_mgr *clk_mgr, | ||
691 | struct dc_state *context, | ||
692 | bool safe_to_lower) | ||
693 | { | ||
694 | struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); | ||
695 | struct dm_pp_clock_for_voltage_req clock_voltage_req = {0}; | ||
696 | int max_pix_clk = get_max_pixel_clock_for_all_paths(context); | ||
697 | int unpatched_disp_clk = context->bw.dce.dispclk_khz; | ||
698 | |||
699 | /*TODO: W/A for dal3 linux, investigate why this works */ | ||
700 | if (!clk_mgr_dce->dfs_bypass_active) | ||
701 | context->bw.dce.dispclk_khz = context->bw.dce.dispclk_khz * 115 / 100; | ||
702 | |||
703 | if (should_set_clock(safe_to_lower, context->bw.dce.dispclk_khz, clk_mgr->clks.dispclk_khz)) { | ||
704 | clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAY_CLK; | ||
705 | clock_voltage_req.clocks_in_khz = context->bw.dce.dispclk_khz; | ||
706 | context->bw.dce.dispclk_khz = dce112_set_clock(clk_mgr, context->bw.dce.dispclk_khz); | ||
707 | clk_mgr->clks.dispclk_khz = context->bw.dce.dispclk_khz; | ||
708 | |||
709 | dm_pp_apply_clock_for_voltage_request(clk_mgr->ctx, &clock_voltage_req); | ||
710 | } | ||
711 | |||
712 | if (should_set_clock(safe_to_lower, max_pix_clk, clk_mgr->clks.phyclk_khz)) { | ||
713 | clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAYPHYCLK; | ||
714 | clock_voltage_req.clocks_in_khz = max_pix_clk; | ||
715 | clk_mgr->clks.phyclk_khz = max_pix_clk; | ||
716 | |||
717 | dm_pp_apply_clock_for_voltage_request(clk_mgr->ctx, &clock_voltage_req); | ||
718 | } | ||
719 | dce11_pplib_apply_display_requirements(clk_mgr->ctx->dc, context); | ||
720 | |||
721 | context->bw.dce.dispclk_khz = unpatched_disp_clk; | ||
722 | } | ||
723 | |||
724 | static const struct clk_mgr_funcs dce120_funcs = { | ||
725 | .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, | ||
726 | .update_clocks = dce12_update_clocks | ||
727 | }; | ||
728 | |||
729 | static const struct clk_mgr_funcs dce112_funcs = { | ||
730 | .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, | ||
731 | .update_clocks = dce112_update_clocks | ||
732 | }; | ||
733 | |||
734 | static const struct clk_mgr_funcs dce110_funcs = { | ||
735 | .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, | ||
736 | .update_clocks = dce11_update_clocks, | ||
737 | }; | ||
738 | |||
739 | static const struct clk_mgr_funcs dce_funcs = { | ||
740 | .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, | ||
741 | .update_clocks = dce_update_clocks | ||
742 | }; | ||
743 | |||
744 | static void dce_clk_mgr_construct( | ||
745 | struct dce_clk_mgr *clk_mgr_dce, | ||
746 | struct dc_context *ctx, | ||
747 | const struct clk_mgr_registers *regs, | ||
748 | const struct clk_mgr_shift *clk_shift, | ||
749 | const struct clk_mgr_mask *clk_mask) | ||
750 | { | ||
751 | struct clk_mgr *base = &clk_mgr_dce->base; | ||
752 | struct dm_pp_static_clock_info static_clk_info = {0}; | ||
753 | |||
754 | base->ctx = ctx; | ||
755 | base->funcs = &dce_funcs; | ||
756 | |||
757 | clk_mgr_dce->regs = regs; | ||
758 | clk_mgr_dce->clk_mgr_shift = clk_shift; | ||
759 | clk_mgr_dce->clk_mgr_mask = clk_mask; | ||
760 | |||
761 | clk_mgr_dce->dfs_bypass_disp_clk = 0; | ||
762 | |||
763 | clk_mgr_dce->dprefclk_ss_percentage = 0; | ||
764 | clk_mgr_dce->dprefclk_ss_divider = 1000; | ||
765 | clk_mgr_dce->ss_on_dprefclk = false; | ||
766 | |||
767 | |||
768 | if (dm_pp_get_static_clocks(ctx, &static_clk_info)) | ||
769 | clk_mgr_dce->max_clks_state = static_clk_info.max_clocks_state; | ||
770 | else | ||
771 | clk_mgr_dce->max_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; | ||
772 | clk_mgr_dce->cur_min_clks_state = DM_PP_CLOCKS_STATE_INVALID; | ||
773 | |||
774 | dce_clock_read_integrated_info(clk_mgr_dce); | ||
775 | dce_clock_read_ss_info(clk_mgr_dce); | ||
776 | } | ||
777 | |||
778 | struct clk_mgr *dce_clk_mgr_create( | ||
779 | struct dc_context *ctx, | ||
780 | const struct clk_mgr_registers *regs, | ||
781 | const struct clk_mgr_shift *clk_shift, | ||
782 | const struct clk_mgr_mask *clk_mask) | ||
783 | { | ||
784 | struct dce_clk_mgr *clk_mgr_dce = kzalloc(sizeof(*clk_mgr_dce), GFP_KERNEL); | ||
785 | |||
786 | if (clk_mgr_dce == NULL) { | ||
787 | BREAK_TO_DEBUGGER(); | ||
788 | return NULL; | ||
789 | } | ||
790 | |||
791 | memcpy(clk_mgr_dce->max_clks_by_state, | ||
792 | dce80_max_clks_by_state, | ||
793 | sizeof(dce80_max_clks_by_state)); | ||
794 | |||
795 | dce_clk_mgr_construct( | ||
796 | clk_mgr_dce, ctx, regs, clk_shift, clk_mask); | ||
797 | |||
798 | return &clk_mgr_dce->base; | ||
799 | } | ||
800 | |||
801 | struct clk_mgr *dce110_clk_mgr_create( | ||
802 | struct dc_context *ctx, | ||
803 | const struct clk_mgr_registers *regs, | ||
804 | const struct clk_mgr_shift *clk_shift, | ||
805 | const struct clk_mgr_mask *clk_mask) | ||
806 | { | ||
807 | struct dce_clk_mgr *clk_mgr_dce = kzalloc(sizeof(*clk_mgr_dce), GFP_KERNEL); | ||
808 | |||
809 | if (clk_mgr_dce == NULL) { | ||
810 | BREAK_TO_DEBUGGER(); | ||
811 | return NULL; | ||
812 | } | ||
813 | |||
814 | memcpy(clk_mgr_dce->max_clks_by_state, | ||
815 | dce110_max_clks_by_state, | ||
816 | sizeof(dce110_max_clks_by_state)); | ||
817 | |||
818 | dce_clk_mgr_construct( | ||
819 | clk_mgr_dce, ctx, regs, clk_shift, clk_mask); | ||
820 | |||
821 | clk_mgr_dce->base.funcs = &dce110_funcs; | ||
822 | |||
823 | return &clk_mgr_dce->base; | ||
824 | } | ||
825 | |||
826 | struct clk_mgr *dce112_clk_mgr_create( | ||
827 | struct dc_context *ctx, | ||
828 | const struct clk_mgr_registers *regs, | ||
829 | const struct clk_mgr_shift *clk_shift, | ||
830 | const struct clk_mgr_mask *clk_mask) | ||
831 | { | ||
832 | struct dce_clk_mgr *clk_mgr_dce = kzalloc(sizeof(*clk_mgr_dce), GFP_KERNEL); | ||
833 | |||
834 | if (clk_mgr_dce == NULL) { | ||
835 | BREAK_TO_DEBUGGER(); | ||
836 | return NULL; | ||
837 | } | ||
838 | |||
839 | memcpy(clk_mgr_dce->max_clks_by_state, | ||
840 | dce112_max_clks_by_state, | ||
841 | sizeof(dce112_max_clks_by_state)); | ||
842 | |||
843 | dce_clk_mgr_construct( | ||
844 | clk_mgr_dce, ctx, regs, clk_shift, clk_mask); | ||
845 | |||
846 | clk_mgr_dce->base.funcs = &dce112_funcs; | ||
847 | |||
848 | return &clk_mgr_dce->base; | ||
849 | } | ||
850 | |||
851 | struct clk_mgr *dce120_clk_mgr_create(struct dc_context *ctx) | ||
852 | { | ||
853 | struct dce_clk_mgr *clk_mgr_dce = kzalloc(sizeof(*clk_mgr_dce), GFP_KERNEL); | ||
854 | |||
855 | if (clk_mgr_dce == NULL) { | ||
856 | BREAK_TO_DEBUGGER(); | ||
857 | return NULL; | ||
858 | } | ||
859 | |||
860 | memcpy(clk_mgr_dce->max_clks_by_state, | ||
861 | dce120_max_clks_by_state, | ||
862 | sizeof(dce120_max_clks_by_state)); | ||
863 | |||
864 | dce_clk_mgr_construct( | ||
865 | clk_mgr_dce, ctx, NULL, NULL, NULL); | ||
866 | |||
867 | clk_mgr_dce->dprefclk_khz = 600000; | ||
868 | clk_mgr_dce->base.funcs = &dce120_funcs; | ||
869 | |||
870 | return &clk_mgr_dce->base; | ||
871 | } | ||
872 | |||
873 | void dce_clk_mgr_destroy(struct clk_mgr **clk_mgr) | ||
874 | { | ||
875 | struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(*clk_mgr); | ||
876 | |||
877 | kfree(clk_mgr_dce); | ||
878 | *clk_mgr = NULL; | ||
879 | } | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.h index 34fdb386c884..046077797416 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.h | |||
@@ -24,10 +24,13 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | 26 | ||
27 | #ifndef _DCE_CLOCKS_H_ | 27 | #ifndef _DCE_CLK_MGR_H_ |
28 | #define _DCE_CLOCKS_H_ | 28 | #define _DCE_CLK_MGR_H_ |
29 | 29 | ||
30 | #include "display_clock.h" | 30 | #include "clk_mgr.h" |
31 | #include "dccg.h" | ||
32 | |||
33 | #define MEMORY_TYPE_MULTIPLIER_CZ 4 | ||
31 | 34 | ||
32 | #define CLK_COMMON_REG_LIST_DCE_BASE() \ | 35 | #define CLK_COMMON_REG_LIST_DCE_BASE() \ |
33 | .DPREFCLK_CNTL = mmDPREFCLK_CNTL, \ | 36 | .DPREFCLK_CNTL = mmDPREFCLK_CNTL, \ |
@@ -53,24 +56,31 @@ | |||
53 | type DENTIST_DISPCLK_WDIVIDER; \ | 56 | type DENTIST_DISPCLK_WDIVIDER; \ |
54 | type DENTIST_DISPCLK_CHG_DONE; | 57 | type DENTIST_DISPCLK_CHG_DONE; |
55 | 58 | ||
56 | struct dccg_shift { | 59 | struct clk_mgr_shift { |
57 | CLK_REG_FIELD_LIST(uint8_t) | 60 | CLK_REG_FIELD_LIST(uint8_t) |
58 | }; | 61 | }; |
59 | 62 | ||
60 | struct dccg_mask { | 63 | struct clk_mgr_mask { |
61 | CLK_REG_FIELD_LIST(uint32_t) | 64 | CLK_REG_FIELD_LIST(uint32_t) |
62 | }; | 65 | }; |
63 | 66 | ||
64 | struct dccg_registers { | 67 | struct clk_mgr_registers { |
65 | uint32_t DPREFCLK_CNTL; | 68 | uint32_t DPREFCLK_CNTL; |
66 | uint32_t DENTIST_DISPCLK_CNTL; | 69 | uint32_t DENTIST_DISPCLK_CNTL; |
67 | }; | 70 | }; |
68 | 71 | ||
69 | struct dce_dccg { | 72 | struct state_dependent_clocks { |
70 | struct dccg base; | 73 | int display_clk_khz; |
71 | const struct dccg_registers *regs; | 74 | int pixel_clk_khz; |
72 | const struct dccg_shift *clk_shift; | 75 | }; |
73 | const struct dccg_mask *clk_mask; | 76 | |
77 | struct dce_clk_mgr { | ||
78 | struct clk_mgr base; | ||
79 | const struct clk_mgr_registers *regs; | ||
80 | const struct clk_mgr_shift *clk_mgr_shift; | ||
81 | const struct clk_mgr_mask *clk_mgr_mask; | ||
82 | |||
83 | struct dccg *dccg; | ||
74 | 84 | ||
75 | struct state_dependent_clocks max_clks_by_state[DM_PP_CLOCKS_MAX_STATES]; | 85 | struct state_dependent_clocks max_clks_by_state[DM_PP_CLOCKS_MAX_STATES]; |
76 | 86 | ||
@@ -91,33 +101,68 @@ struct dce_dccg { | |||
91 | /* DPREFCLK SS percentage Divider (100 or 1000) */ | 101 | /* DPREFCLK SS percentage Divider (100 or 1000) */ |
92 | int dprefclk_ss_divider; | 102 | int dprefclk_ss_divider; |
93 | int dprefclk_khz; | 103 | int dprefclk_khz; |
104 | |||
105 | enum dm_pp_clocks_state max_clks_state; | ||
106 | enum dm_pp_clocks_state cur_min_clks_state; | ||
94 | }; | 107 | }; |
95 | 108 | ||
109 | /* Starting DID for each range */ | ||
110 | enum dentist_base_divider_id { | ||
111 | DENTIST_BASE_DID_1 = 0x08, | ||
112 | DENTIST_BASE_DID_2 = 0x40, | ||
113 | DENTIST_BASE_DID_3 = 0x60, | ||
114 | DENTIST_BASE_DID_4 = 0x7e, | ||
115 | DENTIST_MAX_DID = 0x7f | ||
116 | }; | ||
96 | 117 | ||
97 | struct dccg *dce_dccg_create( | 118 | /* Starting point and step size for each divider range.*/ |
98 | struct dc_context *ctx, | 119 | enum dentist_divider_range { |
99 | const struct dccg_registers *regs, | 120 | DENTIST_DIVIDER_RANGE_1_START = 8, /* 2.00 */ |
100 | const struct dccg_shift *clk_shift, | 121 | DENTIST_DIVIDER_RANGE_1_STEP = 1, /* 0.25 */ |
101 | const struct dccg_mask *clk_mask); | 122 | DENTIST_DIVIDER_RANGE_2_START = 64, /* 16.00 */ |
123 | DENTIST_DIVIDER_RANGE_2_STEP = 2, /* 0.50 */ | ||
124 | DENTIST_DIVIDER_RANGE_3_START = 128, /* 32.00 */ | ||
125 | DENTIST_DIVIDER_RANGE_3_STEP = 4, /* 1.00 */ | ||
126 | DENTIST_DIVIDER_RANGE_4_START = 248, /* 62.00 */ | ||
127 | DENTIST_DIVIDER_RANGE_4_STEP = 264, /* 66.00 */ | ||
128 | DENTIST_DIVIDER_RANGE_SCALE_FACTOR = 4 | ||
129 | }; | ||
130 | |||
131 | static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_clk) | ||
132 | { | ||
133 | return ((safe_to_lower && calc_clk < cur_clk) || calc_clk > cur_clk); | ||
134 | } | ||
135 | |||
136 | void dce_clock_read_ss_info(struct dce_clk_mgr *dccg_dce); | ||
137 | |||
138 | int dce12_get_dp_ref_freq_khz(struct clk_mgr *dccg); | ||
102 | 139 | ||
103 | struct dccg *dce110_dccg_create( | 140 | void dce110_fill_display_configs( |
141 | const struct dc_state *context, | ||
142 | struct dm_pp_display_configuration *pp_display_cfg); | ||
143 | |||
144 | int dce112_set_clock(struct clk_mgr *dccg, int requested_clk_khz); | ||
145 | |||
146 | struct clk_mgr *dce_clk_mgr_create( | ||
104 | struct dc_context *ctx, | 147 | struct dc_context *ctx, |
105 | const struct dccg_registers *regs, | 148 | const struct clk_mgr_registers *regs, |
106 | const struct dccg_shift *clk_shift, | 149 | const struct clk_mgr_shift *clk_shift, |
107 | const struct dccg_mask *clk_mask); | 150 | const struct clk_mgr_mask *clk_mask); |
108 | 151 | ||
109 | struct dccg *dce112_dccg_create( | 152 | struct clk_mgr *dce110_clk_mgr_create( |
110 | struct dc_context *ctx, | 153 | struct dc_context *ctx, |
111 | const struct dccg_registers *regs, | 154 | const struct clk_mgr_registers *regs, |
112 | const struct dccg_shift *clk_shift, | 155 | const struct clk_mgr_shift *clk_shift, |
113 | const struct dccg_mask *clk_mask); | 156 | const struct clk_mgr_mask *clk_mask); |
114 | 157 | ||
115 | struct dccg *dce120_dccg_create(struct dc_context *ctx); | 158 | struct clk_mgr *dce112_clk_mgr_create( |
159 | struct dc_context *ctx, | ||
160 | const struct clk_mgr_registers *regs, | ||
161 | const struct clk_mgr_shift *clk_shift, | ||
162 | const struct clk_mgr_mask *clk_mask); | ||
116 | 163 | ||
117 | #ifdef CONFIG_DRM_AMD_DC_DCN1_0 | 164 | struct clk_mgr *dce120_clk_mgr_create(struct dc_context *ctx); |
118 | struct dccg *dcn1_dccg_create(struct dc_context *ctx); | ||
119 | #endif | ||
120 | 165 | ||
121 | void dce_dccg_destroy(struct dccg **dccg); | 166 | void dce_clk_mgr_destroy(struct clk_mgr **clk_mgr); |
122 | 167 | ||
123 | #endif /* _DCE_CLOCKS_H_ */ | 168 | #endif /* _DCE_CLK_MGR_H_ */ |
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c deleted file mode 100644 index d89a097ba936..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ /dev/null | |||
@@ -1,947 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2012-16 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: AMD | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #include "dce_clocks.h" | ||
27 | #include "dm_services.h" | ||
28 | #include "reg_helper.h" | ||
29 | #include "fixed31_32.h" | ||
30 | #include "bios_parser_interface.h" | ||
31 | #include "dc.h" | ||
32 | #include "dmcu.h" | ||
33 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) | ||
34 | #include "dcn_calcs.h" | ||
35 | #endif | ||
36 | #include "core_types.h" | ||
37 | #include "dc_types.h" | ||
38 | #include "dal_asic_id.h" | ||
39 | |||
40 | #define TO_DCE_CLOCKS(clocks)\ | ||
41 | container_of(clocks, struct dce_dccg, base) | ||
42 | |||
43 | #define REG(reg) \ | ||
44 | (clk_dce->regs->reg) | ||
45 | |||
46 | #undef FN | ||
47 | #define FN(reg_name, field_name) \ | ||
48 | clk_dce->clk_shift->field_name, clk_dce->clk_mask->field_name | ||
49 | |||
50 | #define CTX \ | ||
51 | clk_dce->base.ctx | ||
52 | #define DC_LOGGER \ | ||
53 | clk->ctx->logger | ||
54 | |||
55 | /* Max clock values for each state indexed by "enum clocks_state": */ | ||
56 | static const struct state_dependent_clocks dce80_max_clks_by_state[] = { | ||
57 | /* ClocksStateInvalid - should not be used */ | ||
58 | { .display_clk_khz = 0, .pixel_clk_khz = 0 }, | ||
59 | /* ClocksStateUltraLow - not expected to be used for DCE 8.0 */ | ||
60 | { .display_clk_khz = 0, .pixel_clk_khz = 0 }, | ||
61 | /* ClocksStateLow */ | ||
62 | { .display_clk_khz = 352000, .pixel_clk_khz = 330000}, | ||
63 | /* ClocksStateNominal */ | ||
64 | { .display_clk_khz = 600000, .pixel_clk_khz = 400000 }, | ||
65 | /* ClocksStatePerformance */ | ||
66 | { .display_clk_khz = 600000, .pixel_clk_khz = 400000 } }; | ||
67 | |||
68 | static const struct state_dependent_clocks dce110_max_clks_by_state[] = { | ||
69 | /*ClocksStateInvalid - should not be used*/ | ||
70 | { .display_clk_khz = 0, .pixel_clk_khz = 0 }, | ||
71 | /*ClocksStateUltraLow - currently by HW design team not supposed to be used*/ | ||
72 | { .display_clk_khz = 352000, .pixel_clk_khz = 330000 }, | ||
73 | /*ClocksStateLow*/ | ||
74 | { .display_clk_khz = 352000, .pixel_clk_khz = 330000 }, | ||
75 | /*ClocksStateNominal*/ | ||
76 | { .display_clk_khz = 467000, .pixel_clk_khz = 400000 }, | ||
77 | /*ClocksStatePerformance*/ | ||
78 | { .display_clk_khz = 643000, .pixel_clk_khz = 400000 } }; | ||
79 | |||
80 | static const struct state_dependent_clocks dce112_max_clks_by_state[] = { | ||
81 | /*ClocksStateInvalid - should not be used*/ | ||
82 | { .display_clk_khz = 0, .pixel_clk_khz = 0 }, | ||
83 | /*ClocksStateUltraLow - currently by HW design team not supposed to be used*/ | ||
84 | { .display_clk_khz = 389189, .pixel_clk_khz = 346672 }, | ||
85 | /*ClocksStateLow*/ | ||
86 | { .display_clk_khz = 459000, .pixel_clk_khz = 400000 }, | ||
87 | /*ClocksStateNominal*/ | ||
88 | { .display_clk_khz = 667000, .pixel_clk_khz = 600000 }, | ||
89 | /*ClocksStatePerformance*/ | ||
90 | { .display_clk_khz = 1132000, .pixel_clk_khz = 600000 } }; | ||
91 | |||
92 | static const struct state_dependent_clocks dce120_max_clks_by_state[] = { | ||
93 | /*ClocksStateInvalid - should not be used*/ | ||
94 | { .display_clk_khz = 0, .pixel_clk_khz = 0 }, | ||
95 | /*ClocksStateUltraLow - currently by HW design team not supposed to be used*/ | ||
96 | { .display_clk_khz = 0, .pixel_clk_khz = 0 }, | ||
97 | /*ClocksStateLow*/ | ||
98 | { .display_clk_khz = 460000, .pixel_clk_khz = 400000 }, | ||
99 | /*ClocksStateNominal*/ | ||
100 | { .display_clk_khz = 670000, .pixel_clk_khz = 600000 }, | ||
101 | /*ClocksStatePerformance*/ | ||
102 | { .display_clk_khz = 1133000, .pixel_clk_khz = 600000 } }; | ||
103 | |||
104 | /* Starting DID for each range */ | ||
105 | enum dentist_base_divider_id { | ||
106 | DENTIST_BASE_DID_1 = 0x08, | ||
107 | DENTIST_BASE_DID_2 = 0x40, | ||
108 | DENTIST_BASE_DID_3 = 0x60, | ||
109 | DENTIST_BASE_DID_4 = 0x7e, | ||
110 | DENTIST_MAX_DID = 0x7f | ||
111 | }; | ||
112 | |||
113 | /* Starting point and step size for each divider range.*/ | ||
114 | enum dentist_divider_range { | ||
115 | DENTIST_DIVIDER_RANGE_1_START = 8, /* 2.00 */ | ||
116 | DENTIST_DIVIDER_RANGE_1_STEP = 1, /* 0.25 */ | ||
117 | DENTIST_DIVIDER_RANGE_2_START = 64, /* 16.00 */ | ||
118 | DENTIST_DIVIDER_RANGE_2_STEP = 2, /* 0.50 */ | ||
119 | DENTIST_DIVIDER_RANGE_3_START = 128, /* 32.00 */ | ||
120 | DENTIST_DIVIDER_RANGE_3_STEP = 4, /* 1.00 */ | ||
121 | DENTIST_DIVIDER_RANGE_4_START = 248, /* 62.00 */ | ||
122 | DENTIST_DIVIDER_RANGE_4_STEP = 264, /* 66.00 */ | ||
123 | DENTIST_DIVIDER_RANGE_SCALE_FACTOR = 4 | ||
124 | }; | ||
125 | |||
126 | static int dentist_get_divider_from_did(int did) | ||
127 | { | ||
128 | if (did < DENTIST_BASE_DID_1) | ||
129 | did = DENTIST_BASE_DID_1; | ||
130 | if (did > DENTIST_MAX_DID) | ||
131 | did = DENTIST_MAX_DID; | ||
132 | |||
133 | if (did < DENTIST_BASE_DID_2) { | ||
134 | return DENTIST_DIVIDER_RANGE_1_START + DENTIST_DIVIDER_RANGE_1_STEP | ||
135 | * (did - DENTIST_BASE_DID_1); | ||
136 | } else if (did < DENTIST_BASE_DID_3) { | ||
137 | return DENTIST_DIVIDER_RANGE_2_START + DENTIST_DIVIDER_RANGE_2_STEP | ||
138 | * (did - DENTIST_BASE_DID_2); | ||
139 | } else if (did < DENTIST_BASE_DID_4) { | ||
140 | return DENTIST_DIVIDER_RANGE_3_START + DENTIST_DIVIDER_RANGE_3_STEP | ||
141 | * (did - DENTIST_BASE_DID_3); | ||
142 | } else { | ||
143 | return DENTIST_DIVIDER_RANGE_4_START + DENTIST_DIVIDER_RANGE_4_STEP | ||
144 | * (did - DENTIST_BASE_DID_4); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | /* SW will adjust DP REF Clock average value for all purposes | ||
149 | * (DP DTO / DP Audio DTO and DP GTC) | ||
150 | if clock is spread for all cases: | ||
151 | -if SS enabled on DP Ref clock and HW de-spreading enabled with SW | ||
152 | calculations for DS_INCR/DS_MODULO (this is planned to be default case) | ||
153 | -if SS enabled on DP Ref clock and HW de-spreading enabled with HW | ||
154 | calculations (not planned to be used, but average clock should still | ||
155 | be valid) | ||
156 | -if SS enabled on DP Ref clock and HW de-spreading disabled | ||
157 | (should not be case with CIK) then SW should program all rates | ||
158 | generated according to average value (case as with previous ASICs) | ||
159 | */ | ||
160 | static int dccg_adjust_dp_ref_freq_for_ss(struct dce_dccg *clk_dce, int dp_ref_clk_khz) | ||
161 | { | ||
162 | if (clk_dce->ss_on_dprefclk && clk_dce->dprefclk_ss_divider != 0) { | ||
163 | struct fixed31_32 ss_percentage = dc_fixpt_div_int( | ||
164 | dc_fixpt_from_fraction(clk_dce->dprefclk_ss_percentage, | ||
165 | clk_dce->dprefclk_ss_divider), 200); | ||
166 | struct fixed31_32 adj_dp_ref_clk_khz; | ||
167 | |||
168 | ss_percentage = dc_fixpt_sub(dc_fixpt_one, ss_percentage); | ||
169 | adj_dp_ref_clk_khz = dc_fixpt_mul_int(ss_percentage, dp_ref_clk_khz); | ||
170 | dp_ref_clk_khz = dc_fixpt_floor(adj_dp_ref_clk_khz); | ||
171 | } | ||
172 | return dp_ref_clk_khz; | ||
173 | } | ||
174 | |||
175 | static int dce_get_dp_ref_freq_khz(struct dccg *clk) | ||
176 | { | ||
177 | struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); | ||
178 | int dprefclk_wdivider; | ||
179 | int dprefclk_src_sel; | ||
180 | int dp_ref_clk_khz = 600000; | ||
181 | int target_div; | ||
182 | |||
183 | /* ASSERT DP Reference Clock source is from DFS*/ | ||
184 | REG_GET(DPREFCLK_CNTL, DPREFCLK_SRC_SEL, &dprefclk_src_sel); | ||
185 | ASSERT(dprefclk_src_sel == 0); | ||
186 | |||
187 | /* Read the mmDENTIST_DISPCLK_CNTL to get the currently | ||
188 | * programmed DID DENTIST_DPREFCLK_WDIVIDER*/ | ||
189 | REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, &dprefclk_wdivider); | ||
190 | |||
191 | /* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/ | ||
192 | target_div = dentist_get_divider_from_did(dprefclk_wdivider); | ||
193 | |||
194 | /* Calculate the current DFS clock, in kHz.*/ | ||
195 | dp_ref_clk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR | ||
196 | * clk_dce->dentist_vco_freq_khz) / target_div; | ||
197 | |||
198 | return dccg_adjust_dp_ref_freq_for_ss(clk_dce, dp_ref_clk_khz); | ||
199 | } | ||
200 | |||
201 | static int dce12_get_dp_ref_freq_khz(struct dccg *clk) | ||
202 | { | ||
203 | struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); | ||
204 | |||
205 | return dccg_adjust_dp_ref_freq_for_ss(clk_dce, clk_dce->dprefclk_khz); | ||
206 | } | ||
207 | |||
208 | static enum dm_pp_clocks_state dce_get_required_clocks_state( | ||
209 | struct dccg *clk, | ||
210 | struct dc_clocks *req_clocks) | ||
211 | { | ||
212 | struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); | ||
213 | int i; | ||
214 | enum dm_pp_clocks_state low_req_clk; | ||
215 | |||
216 | /* Iterate from highest supported to lowest valid state, and update | ||
217 | * lowest RequiredState with the lowest state that satisfies | ||
218 | * all required clocks | ||
219 | */ | ||
220 | for (i = clk->max_clks_state; i >= DM_PP_CLOCKS_STATE_ULTRA_LOW; i--) | ||
221 | if (req_clocks->dispclk_khz > | ||
222 | clk_dce->max_clks_by_state[i].display_clk_khz | ||
223 | || req_clocks->phyclk_khz > | ||
224 | clk_dce->max_clks_by_state[i].pixel_clk_khz) | ||
225 | break; | ||
226 | |||
227 | low_req_clk = i + 1; | ||
228 | if (low_req_clk > clk->max_clks_state) { | ||
229 | /* set max clock state for high phyclock, invalid on exceeding display clock */ | ||
230 | if (clk_dce->max_clks_by_state[clk->max_clks_state].display_clk_khz | ||
231 | < req_clocks->dispclk_khz) | ||
232 | low_req_clk = DM_PP_CLOCKS_STATE_INVALID; | ||
233 | else | ||
234 | low_req_clk = clk->max_clks_state; | ||
235 | } | ||
236 | |||
237 | return low_req_clk; | ||
238 | } | ||
239 | |||
240 | static int dce_set_clock( | ||
241 | struct dccg *clk, | ||
242 | int requested_clk_khz) | ||
243 | { | ||
244 | struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); | ||
245 | struct bp_pixel_clock_parameters pxl_clk_params = { 0 }; | ||
246 | struct dc_bios *bp = clk->ctx->dc_bios; | ||
247 | int actual_clock = requested_clk_khz; | ||
248 | |||
249 | /* Make sure requested clock isn't lower than minimum threshold*/ | ||
250 | if (requested_clk_khz > 0) | ||
251 | requested_clk_khz = max(requested_clk_khz, | ||
252 | clk_dce->dentist_vco_freq_khz / 64); | ||
253 | |||
254 | /* Prepare to program display clock*/ | ||
255 | pxl_clk_params.target_pixel_clock = requested_clk_khz; | ||
256 | pxl_clk_params.pll_id = CLOCK_SOURCE_ID_DFS; | ||
257 | |||
258 | if (clk_dce->dfs_bypass_active) | ||
259 | pxl_clk_params.flags.SET_DISPCLK_DFS_BYPASS = true; | ||
260 | |||
261 | bp->funcs->program_display_engine_pll(bp, &pxl_clk_params); | ||
262 | |||
263 | if (clk_dce->dfs_bypass_active) { | ||
264 | /* Cache the fixed display clock*/ | ||
265 | clk_dce->dfs_bypass_disp_clk = | ||
266 | pxl_clk_params.dfs_bypass_display_clock; | ||
267 | actual_clock = pxl_clk_params.dfs_bypass_display_clock; | ||
268 | } | ||
269 | |||
270 | /* from power down, we need mark the clock state as ClocksStateNominal | ||
271 | * from HWReset, so when resume we will call pplib voltage regulator.*/ | ||
272 | if (requested_clk_khz == 0) | ||
273 | clk->cur_min_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; | ||
274 | return actual_clock; | ||
275 | } | ||
276 | |||
277 | static int dce_psr_set_clock( | ||
278 | struct dccg *clk, | ||
279 | int requested_clk_khz) | ||
280 | { | ||
281 | struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); | ||
282 | struct dc_context *ctx = clk_dce->base.ctx; | ||
283 | struct dc *core_dc = ctx->dc; | ||
284 | struct dmcu *dmcu = core_dc->res_pool->dmcu; | ||
285 | int actual_clk_khz = requested_clk_khz; | ||
286 | |||
287 | actual_clk_khz = dce_set_clock(clk, requested_clk_khz); | ||
288 | |||
289 | dmcu->funcs->set_psr_wait_loop(dmcu, actual_clk_khz / 1000 / 7); | ||
290 | return actual_clk_khz; | ||
291 | } | ||
292 | |||
293 | static int dce112_set_clock( | ||
294 | struct dccg *clk, | ||
295 | int requested_clk_khz) | ||
296 | { | ||
297 | struct dce_dccg *clk_dce = TO_DCE_CLOCKS(clk); | ||
298 | struct bp_set_dce_clock_parameters dce_clk_params; | ||
299 | struct dc_bios *bp = clk->ctx->dc_bios; | ||
300 | struct dc *core_dc = clk->ctx->dc; | ||
301 | struct dmcu *dmcu = core_dc->res_pool->dmcu; | ||
302 | int actual_clock = requested_clk_khz; | ||
303 | /* Prepare to program display clock*/ | ||
304 | memset(&dce_clk_params, 0, sizeof(dce_clk_params)); | ||
305 | |||
306 | /* Make sure requested clock isn't lower than minimum threshold*/ | ||
307 | if (requested_clk_khz > 0) | ||
308 | requested_clk_khz = max(requested_clk_khz, | ||
309 | clk_dce->dentist_vco_freq_khz / 62); | ||
310 | |||
311 | dce_clk_params.target_clock_frequency = requested_clk_khz; | ||
312 | dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS; | ||
313 | dce_clk_params.clock_type = DCECLOCK_TYPE_DISPLAY_CLOCK; | ||
314 | |||
315 | bp->funcs->set_dce_clock(bp, &dce_clk_params); | ||
316 | actual_clock = dce_clk_params.target_clock_frequency; | ||
317 | |||
318 | /* from power down, we need mark the clock state as ClocksStateNominal | ||
319 | * from HWReset, so when resume we will call pplib voltage regulator.*/ | ||
320 | if (requested_clk_khz == 0) | ||
321 | clk->cur_min_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; | ||
322 | |||
323 | /*Program DP ref Clock*/ | ||
324 | /*VBIOS will determine DPREFCLK frequency, so we don't set it*/ | ||
325 | dce_clk_params.target_clock_frequency = 0; | ||
326 | dce_clk_params.clock_type = DCECLOCK_TYPE_DPREFCLK; | ||
327 | if (!ASICREV_IS_VEGA20_P(clk->ctx->asic_id.hw_internal_rev)) | ||
328 | dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = | ||
329 | (dce_clk_params.pll_id == | ||
330 | CLOCK_SOURCE_COMBO_DISPLAY_PLL0); | ||
331 | else | ||
332 | dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = false; | ||
333 | |||
334 | bp->funcs->set_dce_clock(bp, &dce_clk_params); | ||
335 | |||
336 | if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) { | ||
337 | if (clk_dce->dfs_bypass_disp_clk != actual_clock) | ||
338 | dmcu->funcs->set_psr_wait_loop(dmcu, | ||
339 | actual_clock / 1000 / 7); | ||
340 | } | ||
341 | |||
342 | clk_dce->dfs_bypass_disp_clk = actual_clock; | ||
343 | return actual_clock; | ||
344 | } | ||
345 | |||
346 | static void dce_clock_read_integrated_info(struct dce_dccg *clk_dce) | ||
347 | { | ||
348 | struct dc_debug_options *debug = &clk_dce->base.ctx->dc->debug; | ||
349 | struct dc_bios *bp = clk_dce->base.ctx->dc_bios; | ||
350 | struct integrated_info info = { { { 0 } } }; | ||
351 | struct dc_firmware_info fw_info = { { 0 } }; | ||
352 | int i; | ||
353 | |||
354 | if (bp->integrated_info) | ||
355 | info = *bp->integrated_info; | ||
356 | |||
357 | clk_dce->dentist_vco_freq_khz = info.dentist_vco_freq; | ||
358 | if (clk_dce->dentist_vco_freq_khz == 0) { | ||
359 | bp->funcs->get_firmware_info(bp, &fw_info); | ||
360 | clk_dce->dentist_vco_freq_khz = | ||
361 | fw_info.smu_gpu_pll_output_freq; | ||
362 | if (clk_dce->dentist_vco_freq_khz == 0) | ||
363 | clk_dce->dentist_vco_freq_khz = 3600000; | ||
364 | } | ||
365 | |||
366 | /*update the maximum display clock for each power state*/ | ||
367 | for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { | ||
368 | enum dm_pp_clocks_state clk_state = DM_PP_CLOCKS_STATE_INVALID; | ||
369 | |||
370 | switch (i) { | ||
371 | case 0: | ||
372 | clk_state = DM_PP_CLOCKS_STATE_ULTRA_LOW; | ||
373 | break; | ||
374 | |||
375 | case 1: | ||
376 | clk_state = DM_PP_CLOCKS_STATE_LOW; | ||
377 | break; | ||
378 | |||
379 | case 2: | ||
380 | clk_state = DM_PP_CLOCKS_STATE_NOMINAL; | ||
381 | break; | ||
382 | |||
383 | case 3: | ||
384 | clk_state = DM_PP_CLOCKS_STATE_PERFORMANCE; | ||
385 | break; | ||
386 | |||
387 | default: | ||
388 | clk_state = DM_PP_CLOCKS_STATE_INVALID; | ||
389 | break; | ||
390 | } | ||
391 | |||
392 | /*Do not allow bad VBIOS/SBIOS to override with invalid values, | ||
393 | * check for > 100MHz*/ | ||
394 | if (info.disp_clk_voltage[i].max_supported_clk >= 100000) | ||
395 | clk_dce->max_clks_by_state[clk_state].display_clk_khz = | ||
396 | info.disp_clk_voltage[i].max_supported_clk; | ||
397 | } | ||
398 | |||
399 | if (!debug->disable_dfs_bypass && bp->integrated_info) | ||
400 | if (bp->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE) | ||
401 | clk_dce->dfs_bypass_enabled = true; | ||
402 | } | ||
403 | |||
404 | static void dce_clock_read_ss_info(struct dce_dccg *clk_dce) | ||
405 | { | ||
406 | struct dc_bios *bp = clk_dce->base.ctx->dc_bios; | ||
407 | int ss_info_num = bp->funcs->get_ss_entry_number( | ||
408 | bp, AS_SIGNAL_TYPE_GPU_PLL); | ||
409 | |||
410 | if (ss_info_num) { | ||
411 | struct spread_spectrum_info info = { { 0 } }; | ||
412 | enum bp_result result = bp->funcs->get_spread_spectrum_info( | ||
413 | bp, AS_SIGNAL_TYPE_GPU_PLL, 0, &info); | ||
414 | |||
415 | /* Based on VBIOS, VBIOS will keep entry for GPU PLL SS | ||
416 | * even if SS not enabled and in that case | ||
417 | * SSInfo.spreadSpectrumPercentage !=0 would be sign | ||
418 | * that SS is enabled | ||
419 | */ | ||
420 | if (result == BP_RESULT_OK && | ||
421 | info.spread_spectrum_percentage != 0) { | ||
422 | clk_dce->ss_on_dprefclk = true; | ||
423 | clk_dce->dprefclk_ss_divider = info.spread_percentage_divider; | ||
424 | |||
425 | if (info.type.CENTER_MODE == 0) { | ||
426 | /* TODO: Currently for DP Reference clock we | ||
427 | * need only SS percentage for | ||
428 | * downspread */ | ||
429 | clk_dce->dprefclk_ss_percentage = | ||
430 | info.spread_spectrum_percentage; | ||
431 | } | ||
432 | |||
433 | return; | ||
434 | } | ||
435 | |||
436 | result = bp->funcs->get_spread_spectrum_info( | ||
437 | bp, AS_SIGNAL_TYPE_DISPLAY_PORT, 0, &info); | ||
438 | |||
439 | /* Based on VBIOS, VBIOS will keep entry for DPREFCLK SS | ||
440 | * even if SS not enabled and in that case | ||
441 | * SSInfo.spreadSpectrumPercentage !=0 would be sign | ||
442 | * that SS is enabled | ||
443 | */ | ||
444 | if (result == BP_RESULT_OK && | ||
445 | info.spread_spectrum_percentage != 0) { | ||
446 | clk_dce->ss_on_dprefclk = true; | ||
447 | clk_dce->dprefclk_ss_divider = info.spread_percentage_divider; | ||
448 | |||
449 | if (info.type.CENTER_MODE == 0) { | ||
450 | /* Currently for DP Reference clock we | ||
451 | * need only SS percentage for | ||
452 | * downspread */ | ||
453 | clk_dce->dprefclk_ss_percentage = | ||
454 | info.spread_spectrum_percentage; | ||
455 | } | ||
456 | } | ||
457 | } | ||
458 | } | ||
459 | |||
460 | static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_clk) | ||
461 | { | ||
462 | return ((safe_to_lower && calc_clk < cur_clk) || calc_clk > cur_clk); | ||
463 | } | ||
464 | |||
465 | static void dce12_update_clocks(struct dccg *dccg, | ||
466 | struct dc_clocks *new_clocks, | ||
467 | bool safe_to_lower) | ||
468 | { | ||
469 | struct dm_pp_clock_for_voltage_req clock_voltage_req = {0}; | ||
470 | |||
471 | /* TODO: Investigate why this is needed to fix display corruption. */ | ||
472 | new_clocks->dispclk_khz = new_clocks->dispclk_khz * 115 / 100; | ||
473 | |||
474 | if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) { | ||
475 | clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAY_CLK; | ||
476 | clock_voltage_req.clocks_in_khz = new_clocks->dispclk_khz; | ||
477 | new_clocks->dispclk_khz = dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz); | ||
478 | dccg->clks.dispclk_khz = new_clocks->dispclk_khz; | ||
479 | |||
480 | dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); | ||
481 | } | ||
482 | |||
483 | if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, dccg->clks.phyclk_khz)) { | ||
484 | clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAYPHYCLK; | ||
485 | clock_voltage_req.clocks_in_khz = new_clocks->phyclk_khz; | ||
486 | dccg->clks.phyclk_khz = new_clocks->phyclk_khz; | ||
487 | |||
488 | dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); | ||
489 | } | ||
490 | } | ||
491 | |||
492 | #ifdef CONFIG_DRM_AMD_DC_DCN1_0 | ||
493 | static int dcn1_determine_dppclk_threshold(struct dccg *dccg, struct dc_clocks *new_clocks) | ||
494 | { | ||
495 | bool request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz; | ||
496 | bool dispclk_increase = new_clocks->dispclk_khz > dccg->clks.dispclk_khz; | ||
497 | int disp_clk_threshold = new_clocks->max_supported_dppclk_khz; | ||
498 | bool cur_dpp_div = dccg->clks.dispclk_khz > dccg->clks.dppclk_khz; | ||
499 | |||
500 | /* increase clock, looking for div is 0 for current, request div is 1*/ | ||
501 | if (dispclk_increase) { | ||
502 | /* already divided by 2, no need to reach target clk with 2 steps*/ | ||
503 | if (cur_dpp_div) | ||
504 | return new_clocks->dispclk_khz; | ||
505 | |||
506 | /* request disp clk is lower than maximum supported dpp clk, | ||
507 | * no need to reach target clk with two steps. | ||
508 | */ | ||
509 | if (new_clocks->dispclk_khz <= disp_clk_threshold) | ||
510 | return new_clocks->dispclk_khz; | ||
511 | |||
512 | /* target dpp clk not request divided by 2, still within threshold */ | ||
513 | if (!request_dpp_div) | ||
514 | return new_clocks->dispclk_khz; | ||
515 | |||
516 | } else { | ||
517 | /* decrease clock, looking for current dppclk divided by 2, | ||
518 | * request dppclk not divided by 2. | ||
519 | */ | ||
520 | |||
521 | /* current dpp clk not divided by 2, no need to ramp*/ | ||
522 | if (!cur_dpp_div) | ||
523 | return new_clocks->dispclk_khz; | ||
524 | |||
525 | /* current disp clk is lower than current maximum dpp clk, | ||
526 | * no need to ramp | ||
527 | */ | ||
528 | if (dccg->clks.dispclk_khz <= disp_clk_threshold) | ||
529 | return new_clocks->dispclk_khz; | ||
530 | |||
531 | /* request dpp clk need to be divided by 2 */ | ||
532 | if (request_dpp_div) | ||
533 | return new_clocks->dispclk_khz; | ||
534 | } | ||
535 | |||
536 | return disp_clk_threshold; | ||
537 | } | ||
538 | |||
539 | static void dcn1_ramp_up_dispclk_with_dpp(struct dccg *dccg, struct dc_clocks *new_clocks) | ||
540 | { | ||
541 | struct dc *dc = dccg->ctx->dc; | ||
542 | int dispclk_to_dpp_threshold = dcn1_determine_dppclk_threshold(dccg, new_clocks); | ||
543 | bool request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz; | ||
544 | int i; | ||
545 | |||
546 | /* set disp clk to dpp clk threshold */ | ||
547 | dccg->funcs->set_dispclk(dccg, dispclk_to_dpp_threshold); | ||
548 | |||
549 | /* update request dpp clk division option */ | ||
550 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | ||
551 | struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; | ||
552 | |||
553 | if (!pipe_ctx->plane_state) | ||
554 | continue; | ||
555 | |||
556 | pipe_ctx->plane_res.dpp->funcs->dpp_dppclk_control( | ||
557 | pipe_ctx->plane_res.dpp, | ||
558 | request_dpp_div, | ||
559 | true); | ||
560 | } | ||
561 | |||
562 | /* If target clk not same as dppclk threshold, set to target clock */ | ||
563 | if (dispclk_to_dpp_threshold != new_clocks->dispclk_khz) | ||
564 | dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz); | ||
565 | |||
566 | dccg->clks.dispclk_khz = new_clocks->dispclk_khz; | ||
567 | dccg->clks.dppclk_khz = new_clocks->dppclk_khz; | ||
568 | dccg->clks.max_supported_dppclk_khz = new_clocks->max_supported_dppclk_khz; | ||
569 | } | ||
570 | |||
571 | static void dcn1_update_clocks(struct dccg *dccg, | ||
572 | struct dc_clocks *new_clocks, | ||
573 | bool safe_to_lower) | ||
574 | { | ||
575 | struct dc *dc = dccg->ctx->dc; | ||
576 | struct pp_smu_display_requirement_rv *smu_req_cur = | ||
577 | &dc->res_pool->pp_smu_req; | ||
578 | struct pp_smu_display_requirement_rv smu_req = *smu_req_cur; | ||
579 | struct pp_smu_funcs_rv *pp_smu = dc->res_pool->pp_smu; | ||
580 | struct dm_pp_clock_for_voltage_req clock_voltage_req = {0}; | ||
581 | bool send_request_to_increase = false; | ||
582 | bool send_request_to_lower = false; | ||
583 | |||
584 | if (new_clocks->phyclk_khz) | ||
585 | smu_req.display_count = 1; | ||
586 | else | ||
587 | smu_req.display_count = 0; | ||
588 | |||
589 | if (new_clocks->dispclk_khz > dccg->clks.dispclk_khz | ||
590 | || new_clocks->phyclk_khz > dccg->clks.phyclk_khz | ||
591 | || new_clocks->fclk_khz > dccg->clks.fclk_khz | ||
592 | || new_clocks->dcfclk_khz > dccg->clks.dcfclk_khz) | ||
593 | send_request_to_increase = true; | ||
594 | |||
595 | if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, dccg->clks.phyclk_khz)) { | ||
596 | dccg->clks.phyclk_khz = new_clocks->phyclk_khz; | ||
597 | |||
598 | send_request_to_lower = true; | ||
599 | } | ||
600 | |||
601 | if (should_set_clock(safe_to_lower, new_clocks->fclk_khz, dccg->clks.fclk_khz)) { | ||
602 | dccg->clks.fclk_khz = new_clocks->fclk_khz; | ||
603 | clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_FCLK; | ||
604 | clock_voltage_req.clocks_in_khz = new_clocks->fclk_khz; | ||
605 | smu_req.hard_min_fclk_khz = new_clocks->fclk_khz; | ||
606 | |||
607 | dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); | ||
608 | send_request_to_lower = true; | ||
609 | } | ||
610 | |||
611 | if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, dccg->clks.dcfclk_khz)) { | ||
612 | dccg->clks.dcfclk_khz = new_clocks->dcfclk_khz; | ||
613 | smu_req.hard_min_dcefclk_khz = new_clocks->dcfclk_khz; | ||
614 | |||
615 | send_request_to_lower = true; | ||
616 | } | ||
617 | |||
618 | if (should_set_clock(safe_to_lower, | ||
619 | new_clocks->dcfclk_deep_sleep_khz, dccg->clks.dcfclk_deep_sleep_khz)) { | ||
620 | dccg->clks.dcfclk_deep_sleep_khz = new_clocks->dcfclk_deep_sleep_khz; | ||
621 | smu_req.min_deep_sleep_dcefclk_mhz = new_clocks->dcfclk_deep_sleep_khz; | ||
622 | |||
623 | send_request_to_lower = true; | ||
624 | } | ||
625 | |||
626 | /* make sure dcf clk is before dpp clk to | ||
627 | * make sure we have enough voltage to run dpp clk | ||
628 | */ | ||
629 | if (send_request_to_increase) { | ||
630 | /*use dcfclk to request voltage*/ | ||
631 | clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; | ||
632 | clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(dc, new_clocks); | ||
633 | dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); | ||
634 | if (pp_smu->set_display_requirement) | ||
635 | pp_smu->set_display_requirement(&pp_smu->pp_smu, &smu_req); | ||
636 | } | ||
637 | |||
638 | /* dcn1 dppclk is tied to dispclk */ | ||
639 | /* program dispclk on = as a w/a for sleep resume clock ramping issues */ | ||
640 | if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz) | ||
641 | || new_clocks->dispclk_khz == dccg->clks.dispclk_khz) { | ||
642 | dcn1_ramp_up_dispclk_with_dpp(dccg, new_clocks); | ||
643 | dccg->clks.dispclk_khz = new_clocks->dispclk_khz; | ||
644 | |||
645 | send_request_to_lower = true; | ||
646 | } | ||
647 | |||
648 | if (!send_request_to_increase && send_request_to_lower) { | ||
649 | /*use dcfclk to request voltage*/ | ||
650 | clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; | ||
651 | clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(dc, new_clocks); | ||
652 | dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req); | ||
653 | if (pp_smu->set_display_requirement) | ||
654 | pp_smu->set_display_requirement(&pp_smu->pp_smu, &smu_req); | ||
655 | } | ||
656 | |||
657 | |||
658 | *smu_req_cur = smu_req; | ||
659 | } | ||
660 | #endif | ||
661 | |||
662 | static void dce_update_clocks(struct dccg *dccg, | ||
663 | struct dc_clocks *new_clocks, | ||
664 | bool safe_to_lower) | ||
665 | { | ||
666 | struct dm_pp_power_level_change_request level_change_req; | ||
667 | struct dce_dccg *clk_dce = TO_DCE_CLOCKS(dccg); | ||
668 | |||
669 | /* TODO: Investigate why this is needed to fix display corruption. */ | ||
670 | if (!clk_dce->dfs_bypass_active) | ||
671 | new_clocks->dispclk_khz = new_clocks->dispclk_khz * 115 / 100; | ||
672 | |||
673 | level_change_req.power_level = dce_get_required_clocks_state(dccg, new_clocks); | ||
674 | /* get max clock state from PPLIB */ | ||
675 | if ((level_change_req.power_level < dccg->cur_min_clks_state && safe_to_lower) | ||
676 | || level_change_req.power_level > dccg->cur_min_clks_state) { | ||
677 | if (dm_pp_apply_power_level_change_request(dccg->ctx, &level_change_req)) | ||
678 | dccg->cur_min_clks_state = level_change_req.power_level; | ||
679 | } | ||
680 | |||
681 | if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) { | ||
682 | new_clocks->dispclk_khz = dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz); | ||
683 | dccg->clks.dispclk_khz = new_clocks->dispclk_khz; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | static bool dce_update_dfs_bypass( | ||
688 | struct dccg *dccg, | ||
689 | struct dc *dc, | ||
690 | struct dc_state *context, | ||
691 | int requested_clock_khz) | ||
692 | { | ||
693 | struct dce_dccg *clk_dce = TO_DCE_CLOCKS(dccg); | ||
694 | struct resource_context *res_ctx = &context->res_ctx; | ||
695 | enum signal_type signal_type = SIGNAL_TYPE_NONE; | ||
696 | bool was_active = clk_dce->dfs_bypass_active; | ||
697 | int i; | ||
698 | |||
699 | /* Disable DFS bypass by default. */ | ||
700 | clk_dce->dfs_bypass_active = false; | ||
701 | |||
702 | /* Check that DFS bypass is available. */ | ||
703 | if (!clk_dce->dfs_bypass_enabled) | ||
704 | goto update; | ||
705 | |||
706 | /* Check if the requested display clock is below the threshold. */ | ||
707 | if (requested_clock_khz >= 400000) | ||
708 | goto update; | ||
709 | |||
710 | /* DFS-bypass should only be enabled on single stream setups */ | ||
711 | if (context->stream_count != 1) | ||
712 | goto update; | ||
713 | |||
714 | /* Check that the stream's signal type is an embedded panel */ | ||
715 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | ||
716 | if (res_ctx->pipe_ctx[i].stream) { | ||
717 | struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; | ||
718 | |||
719 | signal_type = pipe_ctx->stream->sink->link->connector_signal; | ||
720 | break; | ||
721 | } | ||
722 | } | ||
723 | |||
724 | if (signal_type == SIGNAL_TYPE_EDP || | ||
725 | signal_type == SIGNAL_TYPE_LVDS) | ||
726 | clk_dce->dfs_bypass_active = true; | ||
727 | |||
728 | update: | ||
729 | /* Update the clock state. We don't need to respect safe_to_lower | ||
730 | * because DFS bypass should always be greater than the current | ||
731 | * display clock frequency. | ||
732 | */ | ||
733 | if (was_active != clk_dce->dfs_bypass_active) { | ||
734 | dccg->clks.dispclk_khz = | ||
735 | dccg->funcs->set_dispclk(dccg, dccg->clks.dispclk_khz); | ||
736 | return true; | ||
737 | } | ||
738 | |||
739 | return false; | ||
740 | } | ||
741 | |||
742 | #ifdef CONFIG_DRM_AMD_DC_DCN1_0 | ||
743 | static const struct display_clock_funcs dcn1_funcs = { | ||
744 | .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, | ||
745 | .set_dispclk = dce112_set_clock, | ||
746 | .update_clocks = dcn1_update_clocks | ||
747 | }; | ||
748 | #endif | ||
749 | |||
750 | static const struct display_clock_funcs dce120_funcs = { | ||
751 | .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, | ||
752 | .set_dispclk = dce112_set_clock, | ||
753 | .update_clocks = dce12_update_clocks | ||
754 | }; | ||
755 | |||
756 | static const struct display_clock_funcs dce112_funcs = { | ||
757 | .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, | ||
758 | .set_dispclk = dce112_set_clock, | ||
759 | .update_clocks = dce_update_clocks | ||
760 | }; | ||
761 | |||
762 | static const struct display_clock_funcs dce110_funcs = { | ||
763 | .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, | ||
764 | .set_dispclk = dce_psr_set_clock, | ||
765 | .update_clocks = dce_update_clocks, | ||
766 | .update_dfs_bypass = dce_update_dfs_bypass | ||
767 | }; | ||
768 | |||
769 | static const struct display_clock_funcs dce_funcs = { | ||
770 | .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, | ||
771 | .set_dispclk = dce_set_clock, | ||
772 | .update_clocks = dce_update_clocks | ||
773 | }; | ||
774 | |||
775 | static void dce_dccg_construct( | ||
776 | struct dce_dccg *clk_dce, | ||
777 | struct dc_context *ctx, | ||
778 | const struct dccg_registers *regs, | ||
779 | const struct dccg_shift *clk_shift, | ||
780 | const struct dccg_mask *clk_mask) | ||
781 | { | ||
782 | struct dccg *base = &clk_dce->base; | ||
783 | |||
784 | base->ctx = ctx; | ||
785 | base->funcs = &dce_funcs; | ||
786 | |||
787 | clk_dce->regs = regs; | ||
788 | clk_dce->clk_shift = clk_shift; | ||
789 | clk_dce->clk_mask = clk_mask; | ||
790 | |||
791 | clk_dce->dfs_bypass_disp_clk = 0; | ||
792 | |||
793 | clk_dce->dprefclk_ss_percentage = 0; | ||
794 | clk_dce->dprefclk_ss_divider = 1000; | ||
795 | clk_dce->ss_on_dprefclk = false; | ||
796 | |||
797 | base->max_clks_state = DM_PP_CLOCKS_STATE_NOMINAL; | ||
798 | base->cur_min_clks_state = DM_PP_CLOCKS_STATE_INVALID; | ||
799 | |||
800 | dce_clock_read_integrated_info(clk_dce); | ||
801 | dce_clock_read_ss_info(clk_dce); | ||
802 | } | ||
803 | |||
804 | struct dccg *dce_dccg_create( | ||
805 | struct dc_context *ctx, | ||
806 | const struct dccg_registers *regs, | ||
807 | const struct dccg_shift *clk_shift, | ||
808 | const struct dccg_mask *clk_mask) | ||
809 | { | ||
810 | struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); | ||
811 | |||
812 | if (clk_dce == NULL) { | ||
813 | BREAK_TO_DEBUGGER(); | ||
814 | return NULL; | ||
815 | } | ||
816 | |||
817 | memcpy(clk_dce->max_clks_by_state, | ||
818 | dce80_max_clks_by_state, | ||
819 | sizeof(dce80_max_clks_by_state)); | ||
820 | |||
821 | dce_dccg_construct( | ||
822 | clk_dce, ctx, regs, clk_shift, clk_mask); | ||
823 | |||
824 | return &clk_dce->base; | ||
825 | } | ||
826 | |||
827 | struct dccg *dce110_dccg_create( | ||
828 | struct dc_context *ctx, | ||
829 | const struct dccg_registers *regs, | ||
830 | const struct dccg_shift *clk_shift, | ||
831 | const struct dccg_mask *clk_mask) | ||
832 | { | ||
833 | struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); | ||
834 | |||
835 | if (clk_dce == NULL) { | ||
836 | BREAK_TO_DEBUGGER(); | ||
837 | return NULL; | ||
838 | } | ||
839 | |||
840 | memcpy(clk_dce->max_clks_by_state, | ||
841 | dce110_max_clks_by_state, | ||
842 | sizeof(dce110_max_clks_by_state)); | ||
843 | |||
844 | dce_dccg_construct( | ||
845 | clk_dce, ctx, regs, clk_shift, clk_mask); | ||
846 | |||
847 | clk_dce->base.funcs = &dce110_funcs; | ||
848 | |||
849 | return &clk_dce->base; | ||
850 | } | ||
851 | |||
852 | struct dccg *dce112_dccg_create( | ||
853 | struct dc_context *ctx, | ||
854 | const struct dccg_registers *regs, | ||
855 | const struct dccg_shift *clk_shift, | ||
856 | const struct dccg_mask *clk_mask) | ||
857 | { | ||
858 | struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); | ||
859 | |||
860 | if (clk_dce == NULL) { | ||
861 | BREAK_TO_DEBUGGER(); | ||
862 | return NULL; | ||
863 | } | ||
864 | |||
865 | memcpy(clk_dce->max_clks_by_state, | ||
866 | dce112_max_clks_by_state, | ||
867 | sizeof(dce112_max_clks_by_state)); | ||
868 | |||
869 | dce_dccg_construct( | ||
870 | clk_dce, ctx, regs, clk_shift, clk_mask); | ||
871 | |||
872 | clk_dce->base.funcs = &dce112_funcs; | ||
873 | |||
874 | return &clk_dce->base; | ||
875 | } | ||
876 | |||
877 | struct dccg *dce120_dccg_create(struct dc_context *ctx) | ||
878 | { | ||
879 | struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); | ||
880 | |||
881 | if (clk_dce == NULL) { | ||
882 | BREAK_TO_DEBUGGER(); | ||
883 | return NULL; | ||
884 | } | ||
885 | |||
886 | memcpy(clk_dce->max_clks_by_state, | ||
887 | dce120_max_clks_by_state, | ||
888 | sizeof(dce120_max_clks_by_state)); | ||
889 | |||
890 | dce_dccg_construct( | ||
891 | clk_dce, ctx, NULL, NULL, NULL); | ||
892 | |||
893 | clk_dce->dprefclk_khz = 600000; | ||
894 | clk_dce->base.funcs = &dce120_funcs; | ||
895 | |||
896 | return &clk_dce->base; | ||
897 | } | ||
898 | |||
899 | #ifdef CONFIG_DRM_AMD_DC_DCN1_0 | ||
900 | struct dccg *dcn1_dccg_create(struct dc_context *ctx) | ||
901 | { | ||
902 | struct dc_debug_options *debug = &ctx->dc->debug; | ||
903 | struct dc_bios *bp = ctx->dc_bios; | ||
904 | struct dc_firmware_info fw_info = { { 0 } }; | ||
905 | struct dce_dccg *clk_dce = kzalloc(sizeof(*clk_dce), GFP_KERNEL); | ||
906 | |||
907 | if (clk_dce == NULL) { | ||
908 | BREAK_TO_DEBUGGER(); | ||
909 | return NULL; | ||
910 | } | ||
911 | |||
912 | clk_dce->base.ctx = ctx; | ||
913 | clk_dce->base.funcs = &dcn1_funcs; | ||
914 | |||
915 | clk_dce->dfs_bypass_disp_clk = 0; | ||
916 | |||
917 | clk_dce->dprefclk_ss_percentage = 0; | ||
918 | clk_dce->dprefclk_ss_divider = 1000; | ||
919 | clk_dce->ss_on_dprefclk = false; | ||
920 | |||
921 | clk_dce->dprefclk_khz = 600000; | ||
922 | if (bp->integrated_info) | ||
923 | clk_dce->dentist_vco_freq_khz = bp->integrated_info->dentist_vco_freq; | ||
924 | if (clk_dce->dentist_vco_freq_khz == 0) { | ||
925 | bp->funcs->get_firmware_info(bp, &fw_info); | ||
926 | clk_dce->dentist_vco_freq_khz = fw_info.smu_gpu_pll_output_freq; | ||
927 | if (clk_dce->dentist_vco_freq_khz == 0) | ||
928 | clk_dce->dentist_vco_freq_khz = 3600000; | ||
929 | } | ||
930 | |||
931 | if (!debug->disable_dfs_bypass && bp->integrated_info) | ||
932 | if (bp->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE) | ||
933 | clk_dce->dfs_bypass_enabled = true; | ||
934 | |||
935 | dce_clock_read_ss_info(clk_dce); | ||
936 | |||
937 | return &clk_dce->base; | ||
938 | } | ||
939 | #endif | ||
940 | |||
941 | void dce_dccg_destroy(struct dccg **dccg) | ||
942 | { | ||
943 | struct dce_dccg *clk_dce = TO_DCE_CLOCKS(*dccg); | ||
944 | |||
945 | kfree(clk_dce); | ||
946 | *dccg = NULL; | ||
947 | } | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index 64dc75378541..c83a7f05f14c 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h | |||
@@ -233,6 +233,16 @@ struct dce_hwseq_registers { | |||
233 | uint32_t DOMAIN5_PG_CONFIG; | 233 | uint32_t DOMAIN5_PG_CONFIG; |
234 | uint32_t DOMAIN6_PG_CONFIG; | 234 | uint32_t DOMAIN6_PG_CONFIG; |
235 | uint32_t DOMAIN7_PG_CONFIG; | 235 | uint32_t DOMAIN7_PG_CONFIG; |
236 | uint32_t DOMAIN8_PG_CONFIG; | ||
237 | uint32_t DOMAIN9_PG_CONFIG; | ||
238 | uint32_t DOMAIN10_PG_CONFIG; | ||
239 | uint32_t DOMAIN11_PG_CONFIG; | ||
240 | uint32_t DOMAIN16_PG_CONFIG; | ||
241 | uint32_t DOMAIN17_PG_CONFIG; | ||
242 | uint32_t DOMAIN18_PG_CONFIG; | ||
243 | uint32_t DOMAIN19_PG_CONFIG; | ||
244 | uint32_t DOMAIN20_PG_CONFIG; | ||
245 | uint32_t DOMAIN21_PG_CONFIG; | ||
236 | uint32_t DOMAIN0_PG_STATUS; | 246 | uint32_t DOMAIN0_PG_STATUS; |
237 | uint32_t DOMAIN1_PG_STATUS; | 247 | uint32_t DOMAIN1_PG_STATUS; |
238 | uint32_t DOMAIN2_PG_STATUS; | 248 | uint32_t DOMAIN2_PG_STATUS; |
@@ -241,6 +251,16 @@ struct dce_hwseq_registers { | |||
241 | uint32_t DOMAIN5_PG_STATUS; | 251 | uint32_t DOMAIN5_PG_STATUS; |
242 | uint32_t DOMAIN6_PG_STATUS; | 252 | uint32_t DOMAIN6_PG_STATUS; |
243 | uint32_t DOMAIN7_PG_STATUS; | 253 | uint32_t DOMAIN7_PG_STATUS; |
254 | uint32_t DOMAIN8_PG_STATUS; | ||
255 | uint32_t DOMAIN9_PG_STATUS; | ||
256 | uint32_t DOMAIN10_PG_STATUS; | ||
257 | uint32_t DOMAIN11_PG_STATUS; | ||
258 | uint32_t DOMAIN16_PG_STATUS; | ||
259 | uint32_t DOMAIN17_PG_STATUS; | ||
260 | uint32_t DOMAIN18_PG_STATUS; | ||
261 | uint32_t DOMAIN19_PG_STATUS; | ||
262 | uint32_t DOMAIN20_PG_STATUS; | ||
263 | uint32_t DOMAIN21_PG_STATUS; | ||
244 | uint32_t DIO_MEM_PWR_CTRL; | 264 | uint32_t DIO_MEM_PWR_CTRL; |
245 | uint32_t DCCG_GATE_DISABLE_CNTL; | 265 | uint32_t DCCG_GATE_DISABLE_CNTL; |
246 | uint32_t DCCG_GATE_DISABLE_CNTL2; | 266 | uint32_t DCCG_GATE_DISABLE_CNTL2; |
@@ -262,6 +282,8 @@ struct dce_hwseq_registers { | |||
262 | uint32_t D2VGA_CONTROL; | 282 | uint32_t D2VGA_CONTROL; |
263 | uint32_t D3VGA_CONTROL; | 283 | uint32_t D3VGA_CONTROL; |
264 | uint32_t D4VGA_CONTROL; | 284 | uint32_t D4VGA_CONTROL; |
285 | uint32_t D5VGA_CONTROL; | ||
286 | uint32_t D6VGA_CONTROL; | ||
265 | uint32_t VGA_TEST_CONTROL; | 287 | uint32_t VGA_TEST_CONTROL; |
266 | /* MMHUB registers. read only. temporary hack */ | 288 | /* MMHUB registers. read only. temporary hack */ |
267 | uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32; | 289 | uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32; |
@@ -489,6 +511,26 @@ struct dce_hwseq_registers { | |||
489 | type DOMAIN6_POWER_GATE; \ | 511 | type DOMAIN6_POWER_GATE; \ |
490 | type DOMAIN7_POWER_FORCEON; \ | 512 | type DOMAIN7_POWER_FORCEON; \ |
491 | type DOMAIN7_POWER_GATE; \ | 513 | type DOMAIN7_POWER_GATE; \ |
514 | type DOMAIN8_POWER_FORCEON; \ | ||
515 | type DOMAIN8_POWER_GATE; \ | ||
516 | type DOMAIN9_POWER_FORCEON; \ | ||
517 | type DOMAIN9_POWER_GATE; \ | ||
518 | type DOMAIN10_POWER_FORCEON; \ | ||
519 | type DOMAIN10_POWER_GATE; \ | ||
520 | type DOMAIN11_POWER_FORCEON; \ | ||
521 | type DOMAIN11_POWER_GATE; \ | ||
522 | type DOMAIN16_POWER_FORCEON; \ | ||
523 | type DOMAIN16_POWER_GATE; \ | ||
524 | type DOMAIN17_POWER_FORCEON; \ | ||
525 | type DOMAIN17_POWER_GATE; \ | ||
526 | type DOMAIN18_POWER_FORCEON; \ | ||
527 | type DOMAIN18_POWER_GATE; \ | ||
528 | type DOMAIN19_POWER_FORCEON; \ | ||
529 | type DOMAIN19_POWER_GATE; \ | ||
530 | type DOMAIN20_POWER_FORCEON; \ | ||
531 | type DOMAIN20_POWER_GATE; \ | ||
532 | type DOMAIN21_POWER_FORCEON; \ | ||
533 | type DOMAIN21_POWER_GATE; \ | ||
492 | type DOMAIN0_PGFSM_PWR_STATUS; \ | 534 | type DOMAIN0_PGFSM_PWR_STATUS; \ |
493 | type DOMAIN1_PGFSM_PWR_STATUS; \ | 535 | type DOMAIN1_PGFSM_PWR_STATUS; \ |
494 | type DOMAIN2_PGFSM_PWR_STATUS; \ | 536 | type DOMAIN2_PGFSM_PWR_STATUS; \ |
@@ -497,6 +539,16 @@ struct dce_hwseq_registers { | |||
497 | type DOMAIN5_PGFSM_PWR_STATUS; \ | 539 | type DOMAIN5_PGFSM_PWR_STATUS; \ |
498 | type DOMAIN6_PGFSM_PWR_STATUS; \ | 540 | type DOMAIN6_PGFSM_PWR_STATUS; \ |
499 | type DOMAIN7_PGFSM_PWR_STATUS; \ | 541 | type DOMAIN7_PGFSM_PWR_STATUS; \ |
542 | type DOMAIN8_PGFSM_PWR_STATUS; \ | ||
543 | type DOMAIN9_PGFSM_PWR_STATUS; \ | ||
544 | type DOMAIN10_PGFSM_PWR_STATUS; \ | ||
545 | type DOMAIN11_PGFSM_PWR_STATUS; \ | ||
546 | type DOMAIN16_PGFSM_PWR_STATUS; \ | ||
547 | type DOMAIN17_PGFSM_PWR_STATUS; \ | ||
548 | type DOMAIN18_PGFSM_PWR_STATUS; \ | ||
549 | type DOMAIN19_PGFSM_PWR_STATUS; \ | ||
550 | type DOMAIN20_PGFSM_PWR_STATUS; \ | ||
551 | type DOMAIN21_PGFSM_PWR_STATUS; \ | ||
500 | type DCFCLK_GATE_DIS; \ | 552 | type DCFCLK_GATE_DIS; \ |
501 | type DCHUBBUB_GLOBAL_TIMER_REFDIV; \ | 553 | type DCHUBBUB_GLOBAL_TIMER_REFDIV; \ |
502 | type VGA_TEST_ENABLE; \ | 554 | type VGA_TEST_ENABLE; \ |
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index 366bc8c2c643..3e18ea84b1f9 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c | |||
@@ -645,7 +645,7 @@ static bool dce110_link_encoder_validate_hdmi_output( | |||
645 | return false; | 645 | return false; |
646 | 646 | ||
647 | /* DCE11 HW does not support 420 */ | 647 | /* DCE11 HW does not support 420 */ |
648 | if (!enc110->base.features.ycbcr420_supported && | 648 | if (!enc110->base.features.hdmi_ycbcr420_supported && |
649 | crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) | 649 | crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) |
650 | return false; | 650 | return false; |
651 | 651 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c index 74c05e878807..bc50a8e25f4f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c | |||
@@ -105,74 +105,18 @@ bool dce100_enable_display_power_gating( | |||
105 | return false; | 105 | return false; |
106 | } | 106 | } |
107 | 107 | ||
108 | static void dce100_pplib_apply_display_requirements( | 108 | void dce100_prepare_bandwidth( |
109 | struct dc *dc, | ||
110 | struct dc_state *context) | ||
111 | { | ||
112 | struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; | ||
113 | |||
114 | pp_display_cfg->avail_mclk_switch_time_us = | ||
115 | dce110_get_min_vblank_time_us(context); | ||
116 | /*pp_display_cfg->min_memory_clock_khz = context->bw.dce.yclk_khz | ||
117 | / MEMORY_TYPE_MULTIPLIER;*/ | ||
118 | |||
119 | dce110_fill_display_configs(context, pp_display_cfg); | ||
120 | |||
121 | if (memcmp(&dc->prev_display_config, pp_display_cfg, sizeof( | ||
122 | struct dm_pp_display_configuration)) != 0) | ||
123 | dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); | ||
124 | |||
125 | dc->prev_display_config = *pp_display_cfg; | ||
126 | } | ||
127 | |||
128 | /* unit: in_khz before mode set, get pixel clock from context. ASIC register | ||
129 | * may not be programmed yet | ||
130 | */ | ||
131 | static uint32_t get_max_pixel_clock_for_all_paths( | ||
132 | struct dc *dc, | ||
133 | struct dc_state *context) | ||
134 | { | ||
135 | uint32_t max_pix_clk = 0; | ||
136 | int i; | ||
137 | |||
138 | for (i = 0; i < MAX_PIPES; i++) { | ||
139 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | ||
140 | |||
141 | if (pipe_ctx->stream == NULL) | ||
142 | continue; | ||
143 | |||
144 | /* do not check under lay */ | ||
145 | if (pipe_ctx->top_pipe) | ||
146 | continue; | ||
147 | |||
148 | if (pipe_ctx->stream_res.pix_clk_params.requested_pix_clk > max_pix_clk) | ||
149 | max_pix_clk = | ||
150 | pipe_ctx->stream_res.pix_clk_params.requested_pix_clk; | ||
151 | } | ||
152 | return max_pix_clk; | ||
153 | } | ||
154 | |||
155 | void dce100_set_bandwidth( | ||
156 | struct dc *dc, | 109 | struct dc *dc, |
157 | struct dc_state *context, | 110 | struct dc_state *context) |
158 | bool decrease_allowed) | ||
159 | { | 111 | { |
160 | struct dc_clocks req_clks; | ||
161 | |||
162 | req_clks.dispclk_khz = context->bw.dce.dispclk_khz * 115 / 100; | ||
163 | req_clks.phyclk_khz = get_max_pixel_clock_for_all_paths(dc, context); | ||
164 | |||
165 | dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); | 112 | dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); |
166 | 113 | ||
167 | dc->res_pool->dccg->funcs->update_clocks( | 114 | dc->res_pool->clk_mgr->funcs->update_clocks( |
168 | dc->res_pool->dccg, | 115 | dc->res_pool->clk_mgr, |
169 | &req_clks, | 116 | context, |
170 | decrease_allowed); | 117 | false); |
171 | |||
172 | dce100_pplib_apply_display_requirements(dc, context); | ||
173 | } | 118 | } |
174 | 119 | ||
175 | |||
176 | /**************************************************************************/ | 120 | /**************************************************************************/ |
177 | 121 | ||
178 | void dce100_hw_sequencer_construct(struct dc *dc) | 122 | void dce100_hw_sequencer_construct(struct dc *dc) |
@@ -180,8 +124,7 @@ void dce100_hw_sequencer_construct(struct dc *dc) | |||
180 | dce110_hw_sequencer_construct(dc); | 124 | dce110_hw_sequencer_construct(dc); |
181 | 125 | ||
182 | dc->hwss.enable_display_power_gating = dce100_enable_display_power_gating; | 126 | dc->hwss.enable_display_power_gating = dce100_enable_display_power_gating; |
183 | dc->hwss.set_bandwidth = dce100_set_bandwidth; | 127 | dc->hwss.prepare_bandwidth = dce100_prepare_bandwidth; |
184 | dc->hwss.pplib_apply_display_requirements = | 128 | dc->hwss.optimize_bandwidth = dce100_prepare_bandwidth; |
185 | dce100_pplib_apply_display_requirements; | ||
186 | } | 129 | } |
187 | 130 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.h index c6ec0ed6ec3d..acd418515346 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.h | |||
@@ -33,10 +33,9 @@ struct dc_state; | |||
33 | 33 | ||
34 | void dce100_hw_sequencer_construct(struct dc *dc); | 34 | void dce100_hw_sequencer_construct(struct dc *dc); |
35 | 35 | ||
36 | void dce100_set_bandwidth( | 36 | void dce100_prepare_bandwidth( |
37 | struct dc *dc, | 37 | struct dc *dc, |
38 | struct dc_state *context, | 38 | struct dc_state *context); |
39 | bool decrease_allowed); | ||
40 | 39 | ||
41 | bool dce100_enable_display_power_gating(struct dc *dc, uint8_t controller_id, | 40 | bool dce100_enable_display_power_gating(struct dc *dc, uint8_t controller_id, |
42 | struct dc_bios *dcb, | 41 | struct dc_bios *dcb, |
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c index 14754a87156c..6ae51a5dfc04 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c | |||
@@ -36,11 +36,11 @@ | |||
36 | #include "dce/dce_link_encoder.h" | 36 | #include "dce/dce_link_encoder.h" |
37 | #include "dce/dce_stream_encoder.h" | 37 | #include "dce/dce_stream_encoder.h" |
38 | 38 | ||
39 | #include "dce/dce_clk_mgr.h" | ||
39 | #include "dce/dce_mem_input.h" | 40 | #include "dce/dce_mem_input.h" |
40 | #include "dce/dce_ipp.h" | 41 | #include "dce/dce_ipp.h" |
41 | #include "dce/dce_transform.h" | 42 | #include "dce/dce_transform.h" |
42 | #include "dce/dce_opp.h" | 43 | #include "dce/dce_opp.h" |
43 | #include "dce/dce_clocks.h" | ||
44 | #include "dce/dce_clock_source.h" | 44 | #include "dce/dce_clock_source.h" |
45 | #include "dce/dce_audio.h" | 45 | #include "dce/dce_audio.h" |
46 | #include "dce/dce_hwseq.h" | 46 | #include "dce/dce_hwseq.h" |
@@ -137,15 +137,15 @@ static const struct dce110_timing_generator_offsets dce100_tg_offsets[] = { | |||
137 | .reg_name = mm ## block ## id ## _ ## reg_name | 137 | .reg_name = mm ## block ## id ## _ ## reg_name |
138 | 138 | ||
139 | 139 | ||
140 | static const struct dccg_registers disp_clk_regs = { | 140 | static const struct clk_mgr_registers disp_clk_regs = { |
141 | CLK_COMMON_REG_LIST_DCE_BASE() | 141 | CLK_COMMON_REG_LIST_DCE_BASE() |
142 | }; | 142 | }; |
143 | 143 | ||
144 | static const struct dccg_shift disp_clk_shift = { | 144 | static const struct clk_mgr_shift disp_clk_shift = { |
145 | CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) | 145 | CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) |
146 | }; | 146 | }; |
147 | 147 | ||
148 | static const struct dccg_mask disp_clk_mask = { | 148 | static const struct clk_mgr_mask disp_clk_mask = { |
149 | CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) | 149 | CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) |
150 | }; | 150 | }; |
151 | 151 | ||
@@ -722,8 +722,8 @@ static void destruct(struct dce110_resource_pool *pool) | |||
722 | dce_aud_destroy(&pool->base.audios[i]); | 722 | dce_aud_destroy(&pool->base.audios[i]); |
723 | } | 723 | } |
724 | 724 | ||
725 | if (pool->base.dccg != NULL) | 725 | if (pool->base.clk_mgr != NULL) |
726 | dce_dccg_destroy(&pool->base.dccg); | 726 | dce_clk_mgr_destroy(&pool->base.clk_mgr); |
727 | 727 | ||
728 | if (pool->base.abm != NULL) | 728 | if (pool->base.abm != NULL) |
729 | dce_abm_destroy(&pool->base.abm); | 729 | dce_abm_destroy(&pool->base.abm); |
@@ -767,7 +767,7 @@ bool dce100_validate_bandwidth( | |||
767 | if (at_least_one_pipe) { | 767 | if (at_least_one_pipe) { |
768 | /* TODO implement when needed but for now hardcode max value*/ | 768 | /* TODO implement when needed but for now hardcode max value*/ |
769 | context->bw.dce.dispclk_khz = 681000; | 769 | context->bw.dce.dispclk_khz = 681000; |
770 | context->bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER; | 770 | context->bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER_CZ; |
771 | } else { | 771 | } else { |
772 | context->bw.dce.dispclk_khz = 0; | 772 | context->bw.dce.dispclk_khz = 0; |
773 | context->bw.dce.yclk_khz = 0; | 773 | context->bw.dce.yclk_khz = 0; |
@@ -860,7 +860,6 @@ static bool construct( | |||
860 | struct dc_context *ctx = dc->ctx; | 860 | struct dc_context *ctx = dc->ctx; |
861 | struct dc_firmware_info info; | 861 | struct dc_firmware_info info; |
862 | struct dc_bios *bp; | 862 | struct dc_bios *bp; |
863 | struct dm_pp_static_clock_info static_clk_info = {0}; | ||
864 | 863 | ||
865 | ctx->dc_bios->regs = &bios_regs; | 864 | ctx->dc_bios->regs = &bios_regs; |
866 | 865 | ||
@@ -908,11 +907,11 @@ static bool construct( | |||
908 | } | 907 | } |
909 | } | 908 | } |
910 | 909 | ||
911 | pool->base.dccg = dce_dccg_create(ctx, | 910 | pool->base.clk_mgr = dce_clk_mgr_create(ctx, |
912 | &disp_clk_regs, | 911 | &disp_clk_regs, |
913 | &disp_clk_shift, | 912 | &disp_clk_shift, |
914 | &disp_clk_mask); | 913 | &disp_clk_mask); |
915 | if (pool->base.dccg == NULL) { | 914 | if (pool->base.clk_mgr == NULL) { |
916 | dm_error("DC: failed to create display clock!\n"); | 915 | dm_error("DC: failed to create display clock!\n"); |
917 | BREAK_TO_DEBUGGER(); | 916 | BREAK_TO_DEBUGGER(); |
918 | goto res_create_fail; | 917 | goto res_create_fail; |
@@ -938,12 +937,6 @@ static bool construct( | |||
938 | goto res_create_fail; | 937 | goto res_create_fail; |
939 | } | 938 | } |
940 | 939 | ||
941 | /* get static clock information for PPLIB or firmware, save | ||
942 | * max_clock_state | ||
943 | */ | ||
944 | if (dm_pp_get_static_clocks(ctx, &static_clk_info)) | ||
945 | pool->base.dccg->max_clks_state = | ||
946 | static_clk_info.max_clocks_state; | ||
947 | { | 940 | { |
948 | struct irq_service_init_data init_data; | 941 | struct irq_service_init_data init_data; |
949 | init_data.ctx = dc->ctx; | 942 | init_data.ctx = dc->ctx; |
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index b75ede5f84f7..9724a17e352b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | |||
@@ -548,14 +548,14 @@ dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf, | |||
548 | 548 | ||
549 | regamma_params->hw_points_num = hw_points; | 549 | regamma_params->hw_points_num = hw_points; |
550 | 550 | ||
551 | i = 1; | 551 | k = 0; |
552 | for (k = 0; k < 16 && i < 16; k++) { | 552 | for (i = 1; i < 16; i++) { |
553 | if (seg_distr[k] != -1) { | 553 | if (seg_distr[k] != -1) { |
554 | regamma_params->arr_curve_points[k].segments_num = seg_distr[k]; | 554 | regamma_params->arr_curve_points[k].segments_num = seg_distr[k]; |
555 | regamma_params->arr_curve_points[i].offset = | 555 | regamma_params->arr_curve_points[i].offset = |
556 | regamma_params->arr_curve_points[k].offset + (1 << seg_distr[k]); | 556 | regamma_params->arr_curve_points[k].offset + (1 << seg_distr[k]); |
557 | } | 557 | } |
558 | i++; | 558 | k++; |
559 | } | 559 | } |
560 | 560 | ||
561 | if (seg_distr[k] != -1) | 561 | if (seg_distr[k] != -1) |
@@ -1085,7 +1085,6 @@ void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, | |||
1085 | 1085 | ||
1086 | if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { | 1086 | if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { |
1087 | link->dc->hwss.edp_backlight_control(link, true); | 1087 | link->dc->hwss.edp_backlight_control(link, true); |
1088 | stream->bl_pwm_level = EDP_BACKLIGHT_RAMP_DISABLE_LEVEL; | ||
1089 | } | 1088 | } |
1090 | } | 1089 | } |
1091 | void dce110_blank_stream(struct pipe_ctx *pipe_ctx) | 1090 | void dce110_blank_stream(struct pipe_ctx *pipe_ctx) |
@@ -1192,8 +1191,8 @@ static void build_audio_output( | |||
1192 | if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT || | 1191 | if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT || |
1193 | pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { | 1192 | pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { |
1194 | audio_output->pll_info.dp_dto_source_clock_in_khz = | 1193 | audio_output->pll_info.dp_dto_source_clock_in_khz = |
1195 | state->dis_clk->funcs->get_dp_ref_clk_frequency( | 1194 | state->dccg->funcs->get_dp_ref_clk_frequency( |
1196 | state->dis_clk); | 1195 | state->dccg); |
1197 | } | 1196 | } |
1198 | 1197 | ||
1199 | audio_output->pll_info.feed_back_divider = | 1198 | audio_output->pll_info.feed_back_divider = |
@@ -1547,6 +1546,7 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) | |||
1547 | int i; | 1546 | int i; |
1548 | struct dc_link *edp_link_to_turnoff = NULL; | 1547 | struct dc_link *edp_link_to_turnoff = NULL; |
1549 | struct dc_link *edp_link = get_link_for_edp(dc); | 1548 | struct dc_link *edp_link = get_link_for_edp(dc); |
1549 | struct dc_bios *bios = dc->ctx->dc_bios; | ||
1550 | bool can_edp_fast_boot_optimize = false; | 1550 | bool can_edp_fast_boot_optimize = false; |
1551 | bool apply_edp_fast_boot_optimization = false; | 1551 | bool apply_edp_fast_boot_optimization = false; |
1552 | 1552 | ||
@@ -1573,6 +1573,20 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) | |||
1573 | if (context->streams[i]->signal == SIGNAL_TYPE_EDP) { | 1573 | if (context->streams[i]->signal == SIGNAL_TYPE_EDP) { |
1574 | context->streams[i]->apply_edp_fast_boot_optimization = true; | 1574 | context->streams[i]->apply_edp_fast_boot_optimization = true; |
1575 | apply_edp_fast_boot_optimization = true; | 1575 | apply_edp_fast_boot_optimization = true; |
1576 | |||
1577 | /* When after S4 and S5, vbios may post edp and previous dpms_off | ||
1578 | * doesn't make sense. | ||
1579 | * Update dpms_off state to align hw and sw state via check | ||
1580 | * vBios scratch register. | ||
1581 | */ | ||
1582 | if (bios->funcs->is_active_display) { | ||
1583 | const struct connector_device_tag_info *device_tag = &(edp_link->device_tag); | ||
1584 | |||
1585 | if (bios->funcs->is_active_display(bios, | ||
1586 | context->streams[i]->signal, | ||
1587 | device_tag)) | ||
1588 | context->streams[i]->dpms_off = false; | ||
1589 | } | ||
1576 | } | 1590 | } |
1577 | } | 1591 | } |
1578 | } | 1592 | } |
@@ -1736,41 +1750,18 @@ static void set_static_screen_control(struct pipe_ctx **pipe_ctx, | |||
1736 | if (events->force_trigger) | 1750 | if (events->force_trigger) |
1737 | value |= 0x1; | 1751 | value |= 0x1; |
1738 | 1752 | ||
1739 | value |= 0x84; | 1753 | if (num_pipes) { |
1754 | struct dc *dc = pipe_ctx[0]->stream->ctx->dc; | ||
1755 | |||
1756 | if (dc->fbc_compressor) | ||
1757 | value |= 0x84; | ||
1758 | } | ||
1740 | 1759 | ||
1741 | for (i = 0; i < num_pipes; i++) | 1760 | for (i = 0; i < num_pipes; i++) |
1742 | pipe_ctx[i]->stream_res.tg->funcs-> | 1761 | pipe_ctx[i]->stream_res.tg->funcs-> |
1743 | set_static_screen_control(pipe_ctx[i]->stream_res.tg, value); | 1762 | set_static_screen_control(pipe_ctx[i]->stream_res.tg, value); |
1744 | } | 1763 | } |
1745 | 1764 | ||
1746 | /* unit: in_khz before mode set, get pixel clock from context. ASIC register | ||
1747 | * may not be programmed yet | ||
1748 | */ | ||
1749 | static uint32_t get_max_pixel_clock_for_all_paths( | ||
1750 | struct dc *dc, | ||
1751 | struct dc_state *context) | ||
1752 | { | ||
1753 | uint32_t max_pix_clk = 0; | ||
1754 | int i; | ||
1755 | |||
1756 | for (i = 0; i < MAX_PIPES; i++) { | ||
1757 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | ||
1758 | |||
1759 | if (pipe_ctx->stream == NULL) | ||
1760 | continue; | ||
1761 | |||
1762 | /* do not check under lay */ | ||
1763 | if (pipe_ctx->top_pipe) | ||
1764 | continue; | ||
1765 | |||
1766 | if (pipe_ctx->stream_res.pix_clk_params.requested_pix_clk > max_pix_clk) | ||
1767 | max_pix_clk = | ||
1768 | pipe_ctx->stream_res.pix_clk_params.requested_pix_clk; | ||
1769 | } | ||
1770 | |||
1771 | return max_pix_clk; | ||
1772 | } | ||
1773 | |||
1774 | /* | 1765 | /* |
1775 | * Check if FBC can be enabled | 1766 | * Check if FBC can be enabled |
1776 | */ | 1767 | */ |
@@ -2380,191 +2371,33 @@ static void init_hw(struct dc *dc) | |||
2380 | 2371 | ||
2381 | } | 2372 | } |
2382 | 2373 | ||
2383 | void dce110_fill_display_configs( | ||
2384 | const struct dc_state *context, | ||
2385 | struct dm_pp_display_configuration *pp_display_cfg) | ||
2386 | { | ||
2387 | int j; | ||
2388 | int num_cfgs = 0; | ||
2389 | |||
2390 | for (j = 0; j < context->stream_count; j++) { | ||
2391 | int k; | ||
2392 | |||
2393 | const struct dc_stream_state *stream = context->streams[j]; | ||
2394 | struct dm_pp_single_disp_config *cfg = | ||
2395 | &pp_display_cfg->disp_configs[num_cfgs]; | ||
2396 | const struct pipe_ctx *pipe_ctx = NULL; | ||
2397 | |||
2398 | for (k = 0; k < MAX_PIPES; k++) | ||
2399 | if (stream == context->res_ctx.pipe_ctx[k].stream) { | ||
2400 | pipe_ctx = &context->res_ctx.pipe_ctx[k]; | ||
2401 | break; | ||
2402 | } | ||
2403 | |||
2404 | ASSERT(pipe_ctx != NULL); | ||
2405 | |||
2406 | /* only notify active stream */ | ||
2407 | if (stream->dpms_off) | ||
2408 | continue; | ||
2409 | |||
2410 | num_cfgs++; | ||
2411 | cfg->signal = pipe_ctx->stream->signal; | ||
2412 | cfg->pipe_idx = pipe_ctx->stream_res.tg->inst; | ||
2413 | cfg->src_height = stream->src.height; | ||
2414 | cfg->src_width = stream->src.width; | ||
2415 | cfg->ddi_channel_mapping = | ||
2416 | stream->sink->link->ddi_channel_mapping.raw; | ||
2417 | cfg->transmitter = | ||
2418 | stream->sink->link->link_enc->transmitter; | ||
2419 | cfg->link_settings.lane_count = | ||
2420 | stream->sink->link->cur_link_settings.lane_count; | ||
2421 | cfg->link_settings.link_rate = | ||
2422 | stream->sink->link->cur_link_settings.link_rate; | ||
2423 | cfg->link_settings.link_spread = | ||
2424 | stream->sink->link->cur_link_settings.link_spread; | ||
2425 | cfg->sym_clock = stream->phy_pix_clk; | ||
2426 | /* Round v_refresh*/ | ||
2427 | cfg->v_refresh = stream->timing.pix_clk_khz * 1000; | ||
2428 | cfg->v_refresh /= stream->timing.h_total; | ||
2429 | cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total / 2) | ||
2430 | / stream->timing.v_total; | ||
2431 | } | ||
2432 | |||
2433 | pp_display_cfg->display_count = num_cfgs; | ||
2434 | } | ||
2435 | |||
2436 | uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context) | ||
2437 | { | ||
2438 | uint8_t j; | ||
2439 | uint32_t min_vertical_blank_time = -1; | ||
2440 | |||
2441 | for (j = 0; j < context->stream_count; j++) { | ||
2442 | struct dc_stream_state *stream = context->streams[j]; | ||
2443 | uint32_t vertical_blank_in_pixels = 0; | ||
2444 | uint32_t vertical_blank_time = 0; | ||
2445 | |||
2446 | vertical_blank_in_pixels = stream->timing.h_total * | ||
2447 | (stream->timing.v_total | ||
2448 | - stream->timing.v_addressable); | ||
2449 | |||
2450 | vertical_blank_time = vertical_blank_in_pixels | ||
2451 | * 1000 / stream->timing.pix_clk_khz; | ||
2452 | |||
2453 | if (min_vertical_blank_time > vertical_blank_time) | ||
2454 | min_vertical_blank_time = vertical_blank_time; | ||
2455 | } | ||
2456 | |||
2457 | return min_vertical_blank_time; | ||
2458 | } | ||
2459 | |||
2460 | static int determine_sclk_from_bounding_box( | ||
2461 | const struct dc *dc, | ||
2462 | int required_sclk) | ||
2463 | { | ||
2464 | int i; | ||
2465 | 2374 | ||
2466 | /* | 2375 | void dce110_prepare_bandwidth( |
2467 | * Some asics do not give us sclk levels, so we just report the actual | 2376 | struct dc *dc, |
2468 | * required sclk | 2377 | struct dc_state *context) |
2469 | */ | ||
2470 | if (dc->sclk_lvls.num_levels == 0) | ||
2471 | return required_sclk; | ||
2472 | |||
2473 | for (i = 0; i < dc->sclk_lvls.num_levels; i++) { | ||
2474 | if (dc->sclk_lvls.clocks_in_khz[i] >= required_sclk) | ||
2475 | return dc->sclk_lvls.clocks_in_khz[i]; | ||
2476 | } | ||
2477 | /* | ||
2478 | * even maximum level could not satisfy requirement, this | ||
2479 | * is unexpected at this stage, should have been caught at | ||
2480 | * validation time | ||
2481 | */ | ||
2482 | ASSERT(0); | ||
2483 | return dc->sclk_lvls.clocks_in_khz[dc->sclk_lvls.num_levels - 1]; | ||
2484 | } | ||
2485 | |||
2486 | static void pplib_apply_display_requirements( | ||
2487 | struct dc *dc, | ||
2488 | struct dc_state *context) | ||
2489 | { | 2378 | { |
2490 | struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; | 2379 | struct clk_mgr *dccg = dc->res_pool->clk_mgr; |
2491 | 2380 | ||
2492 | pp_display_cfg->all_displays_in_sync = | 2381 | dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); |
2493 | context->bw.dce.all_displays_in_sync; | ||
2494 | pp_display_cfg->nb_pstate_switch_disable = | ||
2495 | context->bw.dce.nbp_state_change_enable == false; | ||
2496 | pp_display_cfg->cpu_cc6_disable = | ||
2497 | context->bw.dce.cpuc_state_change_enable == false; | ||
2498 | pp_display_cfg->cpu_pstate_disable = | ||
2499 | context->bw.dce.cpup_state_change_enable == false; | ||
2500 | pp_display_cfg->cpu_pstate_separation_time = | ||
2501 | context->bw.dce.blackout_recovery_time_us; | ||
2502 | 2382 | ||
2503 | pp_display_cfg->min_memory_clock_khz = context->bw.dce.yclk_khz | 2383 | dccg->funcs->update_clocks( |
2504 | / MEMORY_TYPE_MULTIPLIER; | 2384 | dccg, |
2505 | 2385 | context, | |
2506 | pp_display_cfg->min_engine_clock_khz = determine_sclk_from_bounding_box( | 2386 | false); |
2507 | dc, | ||
2508 | context->bw.dce.sclk_khz); | ||
2509 | |||
2510 | pp_display_cfg->min_engine_clock_deep_sleep_khz | ||
2511 | = context->bw.dce.sclk_deep_sleep_khz; | ||
2512 | |||
2513 | pp_display_cfg->avail_mclk_switch_time_us = | ||
2514 | dce110_get_min_vblank_time_us(context); | ||
2515 | /* TODO: dce11.2*/ | ||
2516 | pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0; | ||
2517 | |||
2518 | pp_display_cfg->disp_clk_khz = dc->res_pool->dccg->clks.dispclk_khz; | ||
2519 | |||
2520 | dce110_fill_display_configs(context, pp_display_cfg); | ||
2521 | |||
2522 | /* TODO: is this still applicable?*/ | ||
2523 | if (pp_display_cfg->display_count == 1) { | ||
2524 | const struct dc_crtc_timing *timing = | ||
2525 | &context->streams[0]->timing; | ||
2526 | |||
2527 | pp_display_cfg->crtc_index = | ||
2528 | pp_display_cfg->disp_configs[0].pipe_idx; | ||
2529 | pp_display_cfg->line_time_in_us = timing->h_total * 1000 | ||
2530 | / timing->pix_clk_khz; | ||
2531 | } | ||
2532 | |||
2533 | if (memcmp(&dc->prev_display_config, pp_display_cfg, sizeof( | ||
2534 | struct dm_pp_display_configuration)) != 0) | ||
2535 | dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); | ||
2536 | |||
2537 | dc->prev_display_config = *pp_display_cfg; | ||
2538 | } | 2387 | } |
2539 | 2388 | ||
2540 | static void dce110_set_bandwidth( | 2389 | void dce110_optimize_bandwidth( |
2541 | struct dc *dc, | 2390 | struct dc *dc, |
2542 | struct dc_state *context, | 2391 | struct dc_state *context) |
2543 | bool decrease_allowed) | ||
2544 | { | 2392 | { |
2545 | struct dc_clocks req_clks; | 2393 | struct clk_mgr *dccg = dc->res_pool->clk_mgr; |
2546 | struct dccg *dccg = dc->res_pool->dccg; | ||
2547 | |||
2548 | req_clks.dispclk_khz = context->bw.dce.dispclk_khz; | ||
2549 | req_clks.phyclk_khz = get_max_pixel_clock_for_all_paths(dc, context); | ||
2550 | |||
2551 | if (decrease_allowed) | ||
2552 | dce110_set_displaymarks(dc, context); | ||
2553 | else | ||
2554 | dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); | ||
2555 | 2394 | ||
2556 | if (dccg->funcs->update_dfs_bypass) | 2395 | dce110_set_displaymarks(dc, context); |
2557 | dccg->funcs->update_dfs_bypass( | ||
2558 | dccg, | ||
2559 | dc, | ||
2560 | context, | ||
2561 | req_clks.dispclk_khz); | ||
2562 | 2396 | ||
2563 | dccg->funcs->update_clocks( | 2397 | dccg->funcs->update_clocks( |
2564 | dccg, | 2398 | dccg, |
2565 | &req_clks, | 2399 | context, |
2566 | decrease_allowed); | 2400 | true); |
2567 | pplib_apply_display_requirements(dc, context); | ||
2568 | } | 2401 | } |
2569 | 2402 | ||
2570 | static void dce110_program_front_end_for_pipe( | 2403 | static void dce110_program_front_end_for_pipe( |
@@ -2769,28 +2602,6 @@ static void dce110_wait_for_mpcc_disconnect( | |||
2769 | /* do nothing*/ | 2602 | /* do nothing*/ |
2770 | } | 2603 | } |
2771 | 2604 | ||
2772 | static void program_csc_matrix(struct pipe_ctx *pipe_ctx, | ||
2773 | enum dc_color_space colorspace, | ||
2774 | uint16_t *matrix) | ||
2775 | { | ||
2776 | int i; | ||
2777 | struct out_csc_color_matrix tbl_entry; | ||
2778 | |||
2779 | if (pipe_ctx->stream->csc_color_matrix.enable_adjustment | ||
2780 | == true) { | ||
2781 | enum dc_color_space color_space = | ||
2782 | pipe_ctx->stream->output_color_space; | ||
2783 | |||
2784 | //uint16_t matrix[12]; | ||
2785 | for (i = 0; i < 12; i++) | ||
2786 | tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i]; | ||
2787 | |||
2788 | tbl_entry.color_space = color_space; | ||
2789 | //tbl_entry.regval = matrix; | ||
2790 | pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.xfm, &tbl_entry); | ||
2791 | } | ||
2792 | } | ||
2793 | |||
2794 | void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx) | 2605 | void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx) |
2795 | { | 2606 | { |
2796 | struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; | 2607 | struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; |
@@ -2839,13 +2650,8 @@ void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx) | |||
2839 | pipe_ctx->plane_res.xfm, attributes); | 2650 | pipe_ctx->plane_res.xfm, attributes); |
2840 | } | 2651 | } |
2841 | 2652 | ||
2842 | static void ready_shared_resources(struct dc *dc, struct dc_state *context) {} | ||
2843 | |||
2844 | static void optimize_shared_resources(struct dc *dc) {} | ||
2845 | |||
2846 | static const struct hw_sequencer_funcs dce110_funcs = { | 2653 | static const struct hw_sequencer_funcs dce110_funcs = { |
2847 | .program_gamut_remap = program_gamut_remap, | 2654 | .program_gamut_remap = program_gamut_remap, |
2848 | .program_csc_matrix = program_csc_matrix, | ||
2849 | .init_hw = init_hw, | 2655 | .init_hw = init_hw, |
2850 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, | 2656 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, |
2851 | .apply_ctx_for_surface = dce110_apply_ctx_for_surface, | 2657 | .apply_ctx_for_surface = dce110_apply_ctx_for_surface, |
@@ -2868,7 +2674,8 @@ static const struct hw_sequencer_funcs dce110_funcs = { | |||
2868 | .enable_display_power_gating = dce110_enable_display_power_gating, | 2674 | .enable_display_power_gating = dce110_enable_display_power_gating, |
2869 | .disable_plane = dce110_power_down_fe, | 2675 | .disable_plane = dce110_power_down_fe, |
2870 | .pipe_control_lock = dce_pipe_control_lock, | 2676 | .pipe_control_lock = dce_pipe_control_lock, |
2871 | .set_bandwidth = dce110_set_bandwidth, | 2677 | .prepare_bandwidth = dce110_prepare_bandwidth, |
2678 | .optimize_bandwidth = dce110_optimize_bandwidth, | ||
2872 | .set_drr = set_drr, | 2679 | .set_drr = set_drr, |
2873 | .get_position = get_position, | 2680 | .get_position = get_position, |
2874 | .set_static_screen_control = set_static_screen_control, | 2681 | .set_static_screen_control = set_static_screen_control, |
@@ -2877,9 +2684,6 @@ static const struct hw_sequencer_funcs dce110_funcs = { | |||
2877 | .setup_stereo = NULL, | 2684 | .setup_stereo = NULL, |
2878 | .set_avmute = dce110_set_avmute, | 2685 | .set_avmute = dce110_set_avmute, |
2879 | .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect, | 2686 | .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect, |
2880 | .ready_shared_resources = ready_shared_resources, | ||
2881 | .optimize_shared_resources = optimize_shared_resources, | ||
2882 | .pplib_apply_display_requirements = pplib_apply_display_requirements, | ||
2883 | .edp_backlight_control = hwss_edp_backlight_control, | 2687 | .edp_backlight_control = hwss_edp_backlight_control, |
2884 | .edp_power_control = hwss_edp_power_control, | 2688 | .edp_power_control = hwss_edp_power_control, |
2885 | .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, | 2689 | .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, |
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h index d6db3dbd9015..cd3e36d52a52 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h | |||
@@ -40,7 +40,6 @@ enum dc_status dce110_apply_ctx_to_hw( | |||
40 | struct dc_state *context); | 40 | struct dc_state *context); |
41 | 41 | ||
42 | 42 | ||
43 | |||
44 | void dce110_enable_stream(struct pipe_ctx *pipe_ctx); | 43 | void dce110_enable_stream(struct pipe_ctx *pipe_ctx); |
45 | 44 | ||
46 | void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option); | 45 | void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option); |
@@ -64,11 +63,13 @@ void dce110_set_safe_displaymarks( | |||
64 | struct resource_context *res_ctx, | 63 | struct resource_context *res_ctx, |
65 | const struct resource_pool *pool); | 64 | const struct resource_pool *pool); |
66 | 65 | ||
67 | void dce110_fill_display_configs( | 66 | void dce110_prepare_bandwidth( |
68 | const struct dc_state *context, | 67 | struct dc *dc, |
69 | struct dm_pp_display_configuration *pp_display_cfg); | 68 | struct dc_state *context); |
70 | 69 | ||
71 | uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context); | 70 | void dce110_optimize_bandwidth( |
71 | struct dc *dc, | ||
72 | struct dc_state *context); | ||
72 | 73 | ||
73 | void dp_receiver_power_ctrl(struct dc_link *link, bool on); | 74 | void dp_receiver_power_ctrl(struct dc_link *link, bool on); |
74 | 75 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index e3624ca24574..e33d11785b1f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "resource.h" | 31 | #include "resource.h" |
32 | #include "dce110/dce110_resource.h" | 32 | #include "dce110/dce110_resource.h" |
33 | 33 | ||
34 | #include "dce/dce_clk_mgr.h" | ||
34 | #include "include/irq_service_interface.h" | 35 | #include "include/irq_service_interface.h" |
35 | #include "dce/dce_audio.h" | 36 | #include "dce/dce_audio.h" |
36 | #include "dce110/dce110_timing_generator.h" | 37 | #include "dce110/dce110_timing_generator.h" |
@@ -45,7 +46,6 @@ | |||
45 | #include "dce110/dce110_transform_v.h" | 46 | #include "dce110/dce110_transform_v.h" |
46 | #include "dce/dce_opp.h" | 47 | #include "dce/dce_opp.h" |
47 | #include "dce110/dce110_opp_v.h" | 48 | #include "dce110/dce110_opp_v.h" |
48 | #include "dce/dce_clocks.h" | ||
49 | #include "dce/dce_clock_source.h" | 49 | #include "dce/dce_clock_source.h" |
50 | #include "dce/dce_hwseq.h" | 50 | #include "dce/dce_hwseq.h" |
51 | #include "dce110/dce110_hw_sequencer.h" | 51 | #include "dce110/dce110_hw_sequencer.h" |
@@ -148,15 +148,15 @@ static const struct dce110_timing_generator_offsets dce110_tg_offsets[] = { | |||
148 | #define SRI(reg_name, block, id)\ | 148 | #define SRI(reg_name, block, id)\ |
149 | .reg_name = mm ## block ## id ## _ ## reg_name | 149 | .reg_name = mm ## block ## id ## _ ## reg_name |
150 | 150 | ||
151 | static const struct dccg_registers disp_clk_regs = { | 151 | static const struct clk_mgr_registers disp_clk_regs = { |
152 | CLK_COMMON_REG_LIST_DCE_BASE() | 152 | CLK_COMMON_REG_LIST_DCE_BASE() |
153 | }; | 153 | }; |
154 | 154 | ||
155 | static const struct dccg_shift disp_clk_shift = { | 155 | static const struct clk_mgr_shift disp_clk_shift = { |
156 | CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) | 156 | CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) |
157 | }; | 157 | }; |
158 | 158 | ||
159 | static const struct dccg_mask disp_clk_mask = { | 159 | static const struct clk_mgr_mask disp_clk_mask = { |
160 | CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) | 160 | CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) |
161 | }; | 161 | }; |
162 | 162 | ||
@@ -760,8 +760,8 @@ static void destruct(struct dce110_resource_pool *pool) | |||
760 | if (pool->base.dmcu != NULL) | 760 | if (pool->base.dmcu != NULL) |
761 | dce_dmcu_destroy(&pool->base.dmcu); | 761 | dce_dmcu_destroy(&pool->base.dmcu); |
762 | 762 | ||
763 | if (pool->base.dccg != NULL) | 763 | if (pool->base.clk_mgr != NULL) |
764 | dce_dccg_destroy(&pool->base.dccg); | 764 | dce_clk_mgr_destroy(&pool->base.clk_mgr); |
765 | 765 | ||
766 | if (pool->base.irqs != NULL) { | 766 | if (pool->base.irqs != NULL) { |
767 | dal_irq_service_destroy(&pool->base.irqs); | 767 | dal_irq_service_destroy(&pool->base.irqs); |
@@ -1173,12 +1173,12 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc) | |||
1173 | &clks); | 1173 | &clks); |
1174 | 1174 | ||
1175 | dc->bw_vbios->low_yclk = bw_frc_to_fixed( | 1175 | dc->bw_vbios->low_yclk = bw_frc_to_fixed( |
1176 | clks.clocks_in_khz[0] * MEMORY_TYPE_MULTIPLIER, 1000); | 1176 | clks.clocks_in_khz[0] * MEMORY_TYPE_MULTIPLIER_CZ, 1000); |
1177 | dc->bw_vbios->mid_yclk = bw_frc_to_fixed( | 1177 | dc->bw_vbios->mid_yclk = bw_frc_to_fixed( |
1178 | clks.clocks_in_khz[clks.num_levels>>1] * MEMORY_TYPE_MULTIPLIER, | 1178 | clks.clocks_in_khz[clks.num_levels>>1] * MEMORY_TYPE_MULTIPLIER_CZ, |
1179 | 1000); | 1179 | 1000); |
1180 | dc->bw_vbios->high_yclk = bw_frc_to_fixed( | 1180 | dc->bw_vbios->high_yclk = bw_frc_to_fixed( |
1181 | clks.clocks_in_khz[clks.num_levels-1] * MEMORY_TYPE_MULTIPLIER, | 1181 | clks.clocks_in_khz[clks.num_levels-1] * MEMORY_TYPE_MULTIPLIER_CZ, |
1182 | 1000); | 1182 | 1000); |
1183 | } | 1183 | } |
1184 | 1184 | ||
@@ -1201,7 +1201,6 @@ static bool construct( | |||
1201 | struct dc_context *ctx = dc->ctx; | 1201 | struct dc_context *ctx = dc->ctx; |
1202 | struct dc_firmware_info info; | 1202 | struct dc_firmware_info info; |
1203 | struct dc_bios *bp; | 1203 | struct dc_bios *bp; |
1204 | struct dm_pp_static_clock_info static_clk_info = {0}; | ||
1205 | 1204 | ||
1206 | ctx->dc_bios->regs = &bios_regs; | 1205 | ctx->dc_bios->regs = &bios_regs; |
1207 | 1206 | ||
@@ -1257,11 +1256,11 @@ static bool construct( | |||
1257 | } | 1256 | } |
1258 | } | 1257 | } |
1259 | 1258 | ||
1260 | pool->base.dccg = dce110_dccg_create(ctx, | 1259 | pool->base.clk_mgr = dce110_clk_mgr_create(ctx, |
1261 | &disp_clk_regs, | 1260 | &disp_clk_regs, |
1262 | &disp_clk_shift, | 1261 | &disp_clk_shift, |
1263 | &disp_clk_mask); | 1262 | &disp_clk_mask); |
1264 | if (pool->base.dccg == NULL) { | 1263 | if (pool->base.clk_mgr == NULL) { |
1265 | dm_error("DC: failed to create display clock!\n"); | 1264 | dm_error("DC: failed to create display clock!\n"); |
1266 | BREAK_TO_DEBUGGER(); | 1265 | BREAK_TO_DEBUGGER(); |
1267 | goto res_create_fail; | 1266 | goto res_create_fail; |
@@ -1287,13 +1286,6 @@ static bool construct( | |||
1287 | goto res_create_fail; | 1286 | goto res_create_fail; |
1288 | } | 1287 | } |
1289 | 1288 | ||
1290 | /* get static clock information for PPLIB or firmware, save | ||
1291 | * max_clock_state | ||
1292 | */ | ||
1293 | if (dm_pp_get_static_clocks(ctx, &static_clk_info)) | ||
1294 | pool->base.dccg->max_clks_state = | ||
1295 | static_clk_info.max_clocks_state; | ||
1296 | |||
1297 | { | 1289 | { |
1298 | struct irq_service_init_data init_data; | 1290 | struct irq_service_init_data init_data; |
1299 | init_data.ctx = dc->ctx; | 1291 | init_data.ctx = dc->ctx; |
@@ -1362,7 +1354,8 @@ static bool construct( | |||
1362 | pool->base.sw_i2cs[i] = NULL; | 1354 | pool->base.sw_i2cs[i] = NULL; |
1363 | } | 1355 | } |
1364 | 1356 | ||
1365 | dc->fbc_compressor = dce110_compressor_create(ctx); | 1357 | if (dc->config.fbc_support) |
1358 | dc->fbc_compressor = dce110_compressor_create(ctx); | ||
1366 | 1359 | ||
1367 | if (!underlay_create(ctx, &pool->base)) | 1360 | if (!underlay_create(ctx, &pool->base)) |
1368 | goto res_create_fail; | 1361 | goto res_create_fail; |
diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c index 3ce79c208ddf..969d4e72dc94 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include "irq/dce110/irq_service_dce110.h" | 36 | #include "irq/dce110/irq_service_dce110.h" |
37 | 37 | ||
38 | #include "dce/dce_clk_mgr.h" | ||
38 | #include "dce/dce_mem_input.h" | 39 | #include "dce/dce_mem_input.h" |
39 | #include "dce/dce_transform.h" | 40 | #include "dce/dce_transform.h" |
40 | #include "dce/dce_link_encoder.h" | 41 | #include "dce/dce_link_encoder.h" |
@@ -42,7 +43,6 @@ | |||
42 | #include "dce/dce_audio.h" | 43 | #include "dce/dce_audio.h" |
43 | #include "dce/dce_opp.h" | 44 | #include "dce/dce_opp.h" |
44 | #include "dce/dce_ipp.h" | 45 | #include "dce/dce_ipp.h" |
45 | #include "dce/dce_clocks.h" | ||
46 | #include "dce/dce_clock_source.h" | 46 | #include "dce/dce_clock_source.h" |
47 | 47 | ||
48 | #include "dce/dce_hwseq.h" | 48 | #include "dce/dce_hwseq.h" |
@@ -148,15 +148,15 @@ static const struct dce110_timing_generator_offsets dce112_tg_offsets[] = { | |||
148 | .reg_name = mm ## block ## id ## _ ## reg_name | 148 | .reg_name = mm ## block ## id ## _ ## reg_name |
149 | 149 | ||
150 | 150 | ||
151 | static const struct dccg_registers disp_clk_regs = { | 151 | static const struct clk_mgr_registers disp_clk_regs = { |
152 | CLK_COMMON_REG_LIST_DCE_BASE() | 152 | CLK_COMMON_REG_LIST_DCE_BASE() |
153 | }; | 153 | }; |
154 | 154 | ||
155 | static const struct dccg_shift disp_clk_shift = { | 155 | static const struct clk_mgr_shift disp_clk_shift = { |
156 | CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) | 156 | CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) |
157 | }; | 157 | }; |
158 | 158 | ||
159 | static const struct dccg_mask disp_clk_mask = { | 159 | static const struct clk_mgr_mask disp_clk_mask = { |
160 | CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) | 160 | CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) |
161 | }; | 161 | }; |
162 | 162 | ||
@@ -551,7 +551,8 @@ static struct transform *dce112_transform_create( | |||
551 | static const struct encoder_feature_support link_enc_feature = { | 551 | static const struct encoder_feature_support link_enc_feature = { |
552 | .max_hdmi_deep_color = COLOR_DEPTH_121212, | 552 | .max_hdmi_deep_color = COLOR_DEPTH_121212, |
553 | .max_hdmi_pixel_clock = 600000, | 553 | .max_hdmi_pixel_clock = 600000, |
554 | .ycbcr420_supported = true, | 554 | .hdmi_ycbcr420_supported = true, |
555 | .dp_ycbcr420_supported = false, | ||
555 | .flags.bits.IS_HBR2_CAPABLE = true, | 556 | .flags.bits.IS_HBR2_CAPABLE = true, |
556 | .flags.bits.IS_HBR3_CAPABLE = true, | 557 | .flags.bits.IS_HBR3_CAPABLE = true, |
557 | .flags.bits.IS_TPS3_CAPABLE = true, | 558 | .flags.bits.IS_TPS3_CAPABLE = true, |
@@ -749,8 +750,8 @@ static void destruct(struct dce110_resource_pool *pool) | |||
749 | if (pool->base.dmcu != NULL) | 750 | if (pool->base.dmcu != NULL) |
750 | dce_dmcu_destroy(&pool->base.dmcu); | 751 | dce_dmcu_destroy(&pool->base.dmcu); |
751 | 752 | ||
752 | if (pool->base.dccg != NULL) | 753 | if (pool->base.clk_mgr != NULL) |
753 | dce_dccg_destroy(&pool->base.dccg); | 754 | dce_clk_mgr_destroy(&pool->base.clk_mgr); |
754 | 755 | ||
755 | if (pool->base.irqs != NULL) { | 756 | if (pool->base.irqs != NULL) { |
756 | dal_irq_service_destroy(&pool->base.irqs); | 757 | dal_irq_service_destroy(&pool->base.irqs); |
@@ -1015,12 +1016,12 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc) | |||
1015 | &clks); | 1016 | &clks); |
1016 | 1017 | ||
1017 | dc->bw_vbios->low_yclk = bw_frc_to_fixed( | 1018 | dc->bw_vbios->low_yclk = bw_frc_to_fixed( |
1018 | clks.clocks_in_khz[0] * MEMORY_TYPE_MULTIPLIER, 1000); | 1019 | clks.clocks_in_khz[0] * MEMORY_TYPE_MULTIPLIER_CZ, 1000); |
1019 | dc->bw_vbios->mid_yclk = bw_frc_to_fixed( | 1020 | dc->bw_vbios->mid_yclk = bw_frc_to_fixed( |
1020 | clks.clocks_in_khz[clks.num_levels>>1] * MEMORY_TYPE_MULTIPLIER, | 1021 | clks.clocks_in_khz[clks.num_levels>>1] * MEMORY_TYPE_MULTIPLIER_CZ, |
1021 | 1000); | 1022 | 1000); |
1022 | dc->bw_vbios->high_yclk = bw_frc_to_fixed( | 1023 | dc->bw_vbios->high_yclk = bw_frc_to_fixed( |
1023 | clks.clocks_in_khz[clks.num_levels-1] * MEMORY_TYPE_MULTIPLIER, | 1024 | clks.clocks_in_khz[clks.num_levels-1] * MEMORY_TYPE_MULTIPLIER_CZ, |
1024 | 1000); | 1025 | 1000); |
1025 | 1026 | ||
1026 | return; | 1027 | return; |
@@ -1056,12 +1057,12 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc) | |||
1056 | * YCLK = UMACLK*m_memoryTypeMultiplier | 1057 | * YCLK = UMACLK*m_memoryTypeMultiplier |
1057 | */ | 1058 | */ |
1058 | dc->bw_vbios->low_yclk = bw_frc_to_fixed( | 1059 | dc->bw_vbios->low_yclk = bw_frc_to_fixed( |
1059 | mem_clks.data[0].clocks_in_khz * MEMORY_TYPE_MULTIPLIER, 1000); | 1060 | mem_clks.data[0].clocks_in_khz * MEMORY_TYPE_MULTIPLIER_CZ, 1000); |
1060 | dc->bw_vbios->mid_yclk = bw_frc_to_fixed( | 1061 | dc->bw_vbios->mid_yclk = bw_frc_to_fixed( |
1061 | mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER, | 1062 | mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER_CZ, |
1062 | 1000); | 1063 | 1000); |
1063 | dc->bw_vbios->high_yclk = bw_frc_to_fixed( | 1064 | dc->bw_vbios->high_yclk = bw_frc_to_fixed( |
1064 | mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER, | 1065 | mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER_CZ, |
1065 | 1000); | 1066 | 1000); |
1066 | 1067 | ||
1067 | /* Now notify PPLib/SMU about which Watermarks sets they should select | 1068 | /* Now notify PPLib/SMU about which Watermarks sets they should select |
@@ -1131,7 +1132,6 @@ static bool construct( | |||
1131 | { | 1132 | { |
1132 | unsigned int i; | 1133 | unsigned int i; |
1133 | struct dc_context *ctx = dc->ctx; | 1134 | struct dc_context *ctx = dc->ctx; |
1134 | struct dm_pp_static_clock_info static_clk_info = {0}; | ||
1135 | 1135 | ||
1136 | ctx->dc_bios->regs = &bios_regs; | 1136 | ctx->dc_bios->regs = &bios_regs; |
1137 | 1137 | ||
@@ -1199,11 +1199,11 @@ static bool construct( | |||
1199 | } | 1199 | } |
1200 | } | 1200 | } |
1201 | 1201 | ||
1202 | pool->base.dccg = dce112_dccg_create(ctx, | 1202 | pool->base.clk_mgr = dce112_clk_mgr_create(ctx, |
1203 | &disp_clk_regs, | 1203 | &disp_clk_regs, |
1204 | &disp_clk_shift, | 1204 | &disp_clk_shift, |
1205 | &disp_clk_mask); | 1205 | &disp_clk_mask); |
1206 | if (pool->base.dccg == NULL) { | 1206 | if (pool->base.clk_mgr == NULL) { |
1207 | dm_error("DC: failed to create display clock!\n"); | 1207 | dm_error("DC: failed to create display clock!\n"); |
1208 | BREAK_TO_DEBUGGER(); | 1208 | BREAK_TO_DEBUGGER(); |
1209 | goto res_create_fail; | 1209 | goto res_create_fail; |
@@ -1229,13 +1229,6 @@ static bool construct( | |||
1229 | goto res_create_fail; | 1229 | goto res_create_fail; |
1230 | } | 1230 | } |
1231 | 1231 | ||
1232 | /* get static clock information for PPLIB or firmware, save | ||
1233 | * max_clock_state | ||
1234 | */ | ||
1235 | if (dm_pp_get_static_clocks(ctx, &static_clk_info)) | ||
1236 | pool->base.dccg->max_clks_state = | ||
1237 | static_clk_info.max_clocks_state; | ||
1238 | |||
1239 | { | 1232 | { |
1240 | struct irq_service_init_data init_data; | 1233 | struct irq_service_init_data init_data; |
1241 | init_data.ctx = dc->ctx; | 1234 | init_data.ctx = dc->ctx; |
diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c index 79ab5f9f9115..f12696674eb0 100644 --- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "resource.h" | 31 | #include "resource.h" |
32 | #include "include/irq_service_interface.h" | 32 | #include "include/irq_service_interface.h" |
33 | #include "dce120_resource.h" | 33 | #include "dce120_resource.h" |
34 | |||
34 | #include "dce112/dce112_resource.h" | 35 | #include "dce112/dce112_resource.h" |
35 | 36 | ||
36 | #include "dce110/dce110_resource.h" | 37 | #include "dce110/dce110_resource.h" |
@@ -39,7 +40,6 @@ | |||
39 | #include "irq/dce120/irq_service_dce120.h" | 40 | #include "irq/dce120/irq_service_dce120.h" |
40 | #include "dce/dce_opp.h" | 41 | #include "dce/dce_opp.h" |
41 | #include "dce/dce_clock_source.h" | 42 | #include "dce/dce_clock_source.h" |
42 | #include "dce/dce_clocks.h" | ||
43 | #include "dce/dce_ipp.h" | 43 | #include "dce/dce_ipp.h" |
44 | #include "dce/dce_mem_input.h" | 44 | #include "dce/dce_mem_input.h" |
45 | 45 | ||
@@ -47,6 +47,7 @@ | |||
47 | #include "dce120/dce120_hw_sequencer.h" | 47 | #include "dce120/dce120_hw_sequencer.h" |
48 | #include "dce/dce_transform.h" | 48 | #include "dce/dce_transform.h" |
49 | 49 | ||
50 | #include "dce/dce_clk_mgr.h" | ||
50 | #include "dce/dce_audio.h" | 51 | #include "dce/dce_audio.h" |
51 | #include "dce/dce_link_encoder.h" | 52 | #include "dce/dce_link_encoder.h" |
52 | #include "dce/dce_stream_encoder.h" | 53 | #include "dce/dce_stream_encoder.h" |
@@ -573,8 +574,8 @@ static void destruct(struct dce110_resource_pool *pool) | |||
573 | if (pool->base.dmcu != NULL) | 574 | if (pool->base.dmcu != NULL) |
574 | dce_dmcu_destroy(&pool->base.dmcu); | 575 | dce_dmcu_destroy(&pool->base.dmcu); |
575 | 576 | ||
576 | if (pool->base.dccg != NULL) | 577 | if (pool->base.clk_mgr != NULL) |
577 | dce_dccg_destroy(&pool->base.dccg); | 578 | dce_clk_mgr_destroy(&pool->base.clk_mgr); |
578 | } | 579 | } |
579 | 580 | ||
580 | static void read_dce_straps( | 581 | static void read_dce_straps( |
@@ -606,7 +607,8 @@ static struct audio *create_audio( | |||
606 | static const struct encoder_feature_support link_enc_feature = { | 607 | static const struct encoder_feature_support link_enc_feature = { |
607 | .max_hdmi_deep_color = COLOR_DEPTH_121212, | 608 | .max_hdmi_deep_color = COLOR_DEPTH_121212, |
608 | .max_hdmi_pixel_clock = 600000, | 609 | .max_hdmi_pixel_clock = 600000, |
609 | .ycbcr420_supported = true, | 610 | .hdmi_ycbcr420_supported = true, |
611 | .dp_ycbcr420_supported = false, | ||
610 | .flags.bits.IS_HBR2_CAPABLE = true, | 612 | .flags.bits.IS_HBR2_CAPABLE = true, |
611 | .flags.bits.IS_HBR3_CAPABLE = true, | 613 | .flags.bits.IS_HBR3_CAPABLE = true, |
612 | .flags.bits.IS_TPS3_CAPABLE = true, | 614 | .flags.bits.IS_TPS3_CAPABLE = true, |
@@ -834,12 +836,12 @@ static void bw_calcs_data_update_from_pplib(struct dc *dc) | |||
834 | * YCLK = UMACLK*m_memoryTypeMultiplier | 836 | * YCLK = UMACLK*m_memoryTypeMultiplier |
835 | */ | 837 | */ |
836 | dc->bw_vbios->low_yclk = bw_frc_to_fixed( | 838 | dc->bw_vbios->low_yclk = bw_frc_to_fixed( |
837 | mem_clks.data[0].clocks_in_khz * MEMORY_TYPE_MULTIPLIER, 1000); | 839 | mem_clks.data[0].clocks_in_khz * MEMORY_TYPE_MULTIPLIER_CZ, 1000); |
838 | dc->bw_vbios->mid_yclk = bw_frc_to_fixed( | 840 | dc->bw_vbios->mid_yclk = bw_frc_to_fixed( |
839 | mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER, | 841 | mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER_CZ, |
840 | 1000); | 842 | 1000); |
841 | dc->bw_vbios->high_yclk = bw_frc_to_fixed( | 843 | dc->bw_vbios->high_yclk = bw_frc_to_fixed( |
842 | mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER, | 844 | mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER_CZ, |
843 | 1000); | 845 | 1000); |
844 | 846 | ||
845 | /* Now notify PPLib/SMU about which Watermarks sets they should select | 847 | /* Now notify PPLib/SMU about which Watermarks sets they should select |
@@ -973,8 +975,8 @@ static bool construct( | |||
973 | } | 975 | } |
974 | } | 976 | } |
975 | 977 | ||
976 | pool->base.dccg = dce120_dccg_create(ctx); | 978 | pool->base.clk_mgr = dce120_clk_mgr_create(ctx); |
977 | if (pool->base.dccg == NULL) { | 979 | if (pool->base.clk_mgr == NULL) { |
978 | dm_error("DC: failed to create display clock!\n"); | 980 | dm_error("DC: failed to create display clock!\n"); |
979 | BREAK_TO_DEBUGGER(); | 981 | BREAK_TO_DEBUGGER(); |
980 | goto dccg_create_fail; | 982 | goto dccg_create_fail; |
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.c index 6c6a1a16af19..a60a90e68d91 100644 --- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.c | |||
@@ -76,6 +76,7 @@ void dce80_hw_sequencer_construct(struct dc *dc) | |||
76 | 76 | ||
77 | dc->hwss.enable_display_power_gating = dce100_enable_display_power_gating; | 77 | dc->hwss.enable_display_power_gating = dce100_enable_display_power_gating; |
78 | dc->hwss.pipe_control_lock = dce_pipe_control_lock; | 78 | dc->hwss.pipe_control_lock = dce_pipe_control_lock; |
79 | dc->hwss.set_bandwidth = dce100_set_bandwidth; | 79 | dc->hwss.prepare_bandwidth = dce100_prepare_bandwidth; |
80 | dc->hwss.optimize_bandwidth = dce100_prepare_bandwidth; | ||
80 | } | 81 | } |
81 | 82 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c index d68f951f9869..6d40b3d54ac1 100644 --- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "dce110/dce110_timing_generator.h" | 37 | #include "dce110/dce110_timing_generator.h" |
38 | #include "dce110/dce110_resource.h" | 38 | #include "dce110/dce110_resource.h" |
39 | #include "dce80/dce80_timing_generator.h" | 39 | #include "dce80/dce80_timing_generator.h" |
40 | #include "dce/dce_clk_mgr.h" | ||
40 | #include "dce/dce_mem_input.h" | 41 | #include "dce/dce_mem_input.h" |
41 | #include "dce/dce_link_encoder.h" | 42 | #include "dce/dce_link_encoder.h" |
42 | #include "dce/dce_stream_encoder.h" | 43 | #include "dce/dce_stream_encoder.h" |
@@ -44,7 +45,6 @@ | |||
44 | #include "dce/dce_ipp.h" | 45 | #include "dce/dce_ipp.h" |
45 | #include "dce/dce_transform.h" | 46 | #include "dce/dce_transform.h" |
46 | #include "dce/dce_opp.h" | 47 | #include "dce/dce_opp.h" |
47 | #include "dce/dce_clocks.h" | ||
48 | #include "dce/dce_clock_source.h" | 48 | #include "dce/dce_clock_source.h" |
49 | #include "dce/dce_audio.h" | 49 | #include "dce/dce_audio.h" |
50 | #include "dce/dce_hwseq.h" | 50 | #include "dce/dce_hwseq.h" |
@@ -155,15 +155,15 @@ static const struct dce110_timing_generator_offsets dce80_tg_offsets[] = { | |||
155 | .reg_name = mm ## block ## id ## _ ## reg_name | 155 | .reg_name = mm ## block ## id ## _ ## reg_name |
156 | 156 | ||
157 | 157 | ||
158 | static const struct dccg_registers disp_clk_regs = { | 158 | static const struct clk_mgr_registers disp_clk_regs = { |
159 | CLK_COMMON_REG_LIST_DCE_BASE() | 159 | CLK_COMMON_REG_LIST_DCE_BASE() |
160 | }; | 160 | }; |
161 | 161 | ||
162 | static const struct dccg_shift disp_clk_shift = { | 162 | static const struct clk_mgr_shift disp_clk_shift = { |
163 | CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) | 163 | CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) |
164 | }; | 164 | }; |
165 | 165 | ||
166 | static const struct dccg_mask disp_clk_mask = { | 166 | static const struct clk_mgr_mask disp_clk_mask = { |
167 | CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) | 167 | CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) |
168 | }; | 168 | }; |
169 | 169 | ||
@@ -779,8 +779,8 @@ static void destruct(struct dce110_resource_pool *pool) | |||
779 | } | 779 | } |
780 | } | 780 | } |
781 | 781 | ||
782 | if (pool->base.dccg != NULL) | 782 | if (pool->base.clk_mgr != NULL) |
783 | dce_dccg_destroy(&pool->base.dccg); | 783 | dce_clk_mgr_destroy(&pool->base.clk_mgr); |
784 | 784 | ||
785 | if (pool->base.irqs != NULL) { | 785 | if (pool->base.irqs != NULL) { |
786 | dal_irq_service_destroy(&pool->base.irqs); | 786 | dal_irq_service_destroy(&pool->base.irqs); |
@@ -793,7 +793,7 @@ bool dce80_validate_bandwidth( | |||
793 | { | 793 | { |
794 | /* TODO implement when needed but for now hardcode max value*/ | 794 | /* TODO implement when needed but for now hardcode max value*/ |
795 | context->bw.dce.dispclk_khz = 681000; | 795 | context->bw.dce.dispclk_khz = 681000; |
796 | context->bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER; | 796 | context->bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER_CZ; |
797 | 797 | ||
798 | return true; | 798 | return true; |
799 | } | 799 | } |
@@ -855,7 +855,6 @@ static bool dce80_construct( | |||
855 | struct dc_context *ctx = dc->ctx; | 855 | struct dc_context *ctx = dc->ctx; |
856 | struct dc_firmware_info info; | 856 | struct dc_firmware_info info; |
857 | struct dc_bios *bp; | 857 | struct dc_bios *bp; |
858 | struct dm_pp_static_clock_info static_clk_info = {0}; | ||
859 | 858 | ||
860 | ctx->dc_bios->regs = &bios_regs; | 859 | ctx->dc_bios->regs = &bios_regs; |
861 | 860 | ||
@@ -918,11 +917,11 @@ static bool dce80_construct( | |||
918 | } | 917 | } |
919 | } | 918 | } |
920 | 919 | ||
921 | pool->base.dccg = dce_dccg_create(ctx, | 920 | pool->base.clk_mgr = dce_clk_mgr_create(ctx, |
922 | &disp_clk_regs, | 921 | &disp_clk_regs, |
923 | &disp_clk_shift, | 922 | &disp_clk_shift, |
924 | &disp_clk_mask); | 923 | &disp_clk_mask); |
925 | if (pool->base.dccg == NULL) { | 924 | if (pool->base.clk_mgr == NULL) { |
926 | dm_error("DC: failed to create display clock!\n"); | 925 | dm_error("DC: failed to create display clock!\n"); |
927 | BREAK_TO_DEBUGGER(); | 926 | BREAK_TO_DEBUGGER(); |
928 | goto res_create_fail; | 927 | goto res_create_fail; |
@@ -948,10 +947,6 @@ static bool dce80_construct( | |||
948 | goto res_create_fail; | 947 | goto res_create_fail; |
949 | } | 948 | } |
950 | 949 | ||
951 | if (dm_pp_get_static_clocks(ctx, &static_clk_info)) | ||
952 | pool->base.dccg->max_clks_state = | ||
953 | static_clk_info.max_clocks_state; | ||
954 | |||
955 | { | 950 | { |
956 | struct irq_service_init_data init_data; | 951 | struct irq_service_init_data init_data; |
957 | init_data.ctx = dc->ctx; | 952 | init_data.ctx = dc->ctx; |
@@ -1065,7 +1060,6 @@ static bool dce81_construct( | |||
1065 | struct dc_context *ctx = dc->ctx; | 1060 | struct dc_context *ctx = dc->ctx; |
1066 | struct dc_firmware_info info; | 1061 | struct dc_firmware_info info; |
1067 | struct dc_bios *bp; | 1062 | struct dc_bios *bp; |
1068 | struct dm_pp_static_clock_info static_clk_info = {0}; | ||
1069 | 1063 | ||
1070 | ctx->dc_bios->regs = &bios_regs; | 1064 | ctx->dc_bios->regs = &bios_regs; |
1071 | 1065 | ||
@@ -1128,11 +1122,11 @@ static bool dce81_construct( | |||
1128 | } | 1122 | } |
1129 | } | 1123 | } |
1130 | 1124 | ||
1131 | pool->base.dccg = dce_dccg_create(ctx, | 1125 | pool->base.clk_mgr = dce_clk_mgr_create(ctx, |
1132 | &disp_clk_regs, | 1126 | &disp_clk_regs, |
1133 | &disp_clk_shift, | 1127 | &disp_clk_shift, |
1134 | &disp_clk_mask); | 1128 | &disp_clk_mask); |
1135 | if (pool->base.dccg == NULL) { | 1129 | if (pool->base.clk_mgr == NULL) { |
1136 | dm_error("DC: failed to create display clock!\n"); | 1130 | dm_error("DC: failed to create display clock!\n"); |
1137 | BREAK_TO_DEBUGGER(); | 1131 | BREAK_TO_DEBUGGER(); |
1138 | goto res_create_fail; | 1132 | goto res_create_fail; |
@@ -1158,10 +1152,6 @@ static bool dce81_construct( | |||
1158 | goto res_create_fail; | 1152 | goto res_create_fail; |
1159 | } | 1153 | } |
1160 | 1154 | ||
1161 | if (dm_pp_get_static_clocks(ctx, &static_clk_info)) | ||
1162 | pool->base.dccg->max_clks_state = | ||
1163 | static_clk_info.max_clocks_state; | ||
1164 | |||
1165 | { | 1155 | { |
1166 | struct irq_service_init_data init_data; | 1156 | struct irq_service_init_data init_data; |
1167 | init_data.ctx = dc->ctx; | 1157 | init_data.ctx = dc->ctx; |
@@ -1275,7 +1265,6 @@ static bool dce83_construct( | |||
1275 | struct dc_context *ctx = dc->ctx; | 1265 | struct dc_context *ctx = dc->ctx; |
1276 | struct dc_firmware_info info; | 1266 | struct dc_firmware_info info; |
1277 | struct dc_bios *bp; | 1267 | struct dc_bios *bp; |
1278 | struct dm_pp_static_clock_info static_clk_info = {0}; | ||
1279 | 1268 | ||
1280 | ctx->dc_bios->regs = &bios_regs; | 1269 | ctx->dc_bios->regs = &bios_regs; |
1281 | 1270 | ||
@@ -1334,11 +1323,11 @@ static bool dce83_construct( | |||
1334 | } | 1323 | } |
1335 | } | 1324 | } |
1336 | 1325 | ||
1337 | pool->base.dccg = dce_dccg_create(ctx, | 1326 | pool->base.clk_mgr = dce_clk_mgr_create(ctx, |
1338 | &disp_clk_regs, | 1327 | &disp_clk_regs, |
1339 | &disp_clk_shift, | 1328 | &disp_clk_shift, |
1340 | &disp_clk_mask); | 1329 | &disp_clk_mask); |
1341 | if (pool->base.dccg == NULL) { | 1330 | if (pool->base.clk_mgr == NULL) { |
1342 | dm_error("DC: failed to create display clock!\n"); | 1331 | dm_error("DC: failed to create display clock!\n"); |
1343 | BREAK_TO_DEBUGGER(); | 1332 | BREAK_TO_DEBUGGER(); |
1344 | goto res_create_fail; | 1333 | goto res_create_fail; |
@@ -1364,10 +1353,6 @@ static bool dce83_construct( | |||
1364 | goto res_create_fail; | 1353 | goto res_create_fail; |
1365 | } | 1354 | } |
1366 | 1355 | ||
1367 | if (dm_pp_get_static_clocks(ctx, &static_clk_info)) | ||
1368 | pool->base.dccg->max_clks_state = | ||
1369 | static_clk_info.max_clocks_state; | ||
1370 | |||
1371 | { | 1356 | { |
1372 | struct irq_service_init_data init_data; | 1357 | struct irq_service_init_data init_data; |
1373 | init_data.ctx = dc->ctx; | 1358 | init_data.ctx = dc->ctx; |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile index 032f872be89c..55f293c8a3c0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | DCN10 = dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o dcn10_hw_sequencer_debug.o \ | 25 | DCN10 = dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o dcn10_hw_sequencer_debug.o \ |
26 | dcn10_dpp.o dcn10_opp.o dcn10_optc.o \ | 26 | dcn10_dpp.o dcn10_opp.o dcn10_optc.o \ |
27 | dcn10_hubp.o dcn10_mpc.o \ | 27 | dcn10_hubp.o dcn10_mpc.o dcn10_clk_mgr.o \ |
28 | dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_cm_common.o \ | 28 | dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_cm_common.o \ |
29 | dcn10_hubbub.o dcn10_stream_encoder.o dcn10_link_encoder.o | 29 | dcn10_hubbub.o dcn10_stream_encoder.o dcn10_link_encoder.o |
30 | 30 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_clk_mgr.c new file mode 100644 index 000000000000..20f531d27e2b --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_clk_mgr.c | |||
@@ -0,0 +1,379 @@ | |||
1 | /* | ||
2 | * Copyright 2018 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: AMD | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #include "dcn10_clk_mgr.h" | ||
27 | |||
28 | #include "reg_helper.h" | ||
29 | #include "core_types.h" | ||
30 | |||
31 | #define TO_DCE_CLK_MGR(clocks)\ | ||
32 | container_of(clocks, struct dce_clk_mgr, base) | ||
33 | |||
34 | #define REG(reg) \ | ||
35 | (clk_mgr_dce->regs->reg) | ||
36 | |||
37 | #undef FN | ||
38 | #define FN(reg_name, field_name) \ | ||
39 | clk_mgr_dce->clk_mgr_shift->field_name, clk_mgr_dce->clk_mgr_mask->field_name | ||
40 | |||
41 | #define CTX \ | ||
42 | clk_mgr_dce->base.ctx | ||
43 | #define DC_LOGGER \ | ||
44 | clk_mgr->ctx->logger | ||
45 | |||
46 | void dcn1_pplib_apply_display_requirements( | ||
47 | struct dc *dc, | ||
48 | struct dc_state *context) | ||
49 | { | ||
50 | struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; | ||
51 | |||
52 | pp_display_cfg->min_engine_clock_khz = dc->res_pool->clk_mgr->clks.dcfclk_khz; | ||
53 | pp_display_cfg->min_memory_clock_khz = dc->res_pool->clk_mgr->clks.fclk_khz; | ||
54 | pp_display_cfg->min_engine_clock_deep_sleep_khz = dc->res_pool->clk_mgr->clks.dcfclk_deep_sleep_khz; | ||
55 | pp_display_cfg->min_dcfc_deep_sleep_clock_khz = dc->res_pool->clk_mgr->clks.dcfclk_deep_sleep_khz; | ||
56 | pp_display_cfg->min_dcfclock_khz = dc->res_pool->clk_mgr->clks.dcfclk_khz; | ||
57 | pp_display_cfg->disp_clk_khz = dc->res_pool->clk_mgr->clks.dispclk_khz; | ||
58 | dce110_fill_display_configs(context, pp_display_cfg); | ||
59 | |||
60 | dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); | ||
61 | } | ||
62 | |||
63 | static int dcn1_determine_dppclk_threshold(struct clk_mgr *clk_mgr, struct dc_clocks *new_clocks) | ||
64 | { | ||
65 | bool request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz; | ||
66 | bool dispclk_increase = new_clocks->dispclk_khz > clk_mgr->clks.dispclk_khz; | ||
67 | int disp_clk_threshold = new_clocks->max_supported_dppclk_khz; | ||
68 | bool cur_dpp_div = clk_mgr->clks.dispclk_khz > clk_mgr->clks.dppclk_khz; | ||
69 | |||
70 | /* increase clock, looking for div is 0 for current, request div is 1*/ | ||
71 | if (dispclk_increase) { | ||
72 | /* already divided by 2, no need to reach target clk with 2 steps*/ | ||
73 | if (cur_dpp_div) | ||
74 | return new_clocks->dispclk_khz; | ||
75 | |||
76 | /* request disp clk is lower than maximum supported dpp clk, | ||
77 | * no need to reach target clk with two steps. | ||
78 | */ | ||
79 | if (new_clocks->dispclk_khz <= disp_clk_threshold) | ||
80 | return new_clocks->dispclk_khz; | ||
81 | |||
82 | /* target dpp clk not request divided by 2, still within threshold */ | ||
83 | if (!request_dpp_div) | ||
84 | return new_clocks->dispclk_khz; | ||
85 | |||
86 | } else { | ||
87 | /* decrease clock, looking for current dppclk divided by 2, | ||
88 | * request dppclk not divided by 2. | ||
89 | */ | ||
90 | |||
91 | /* current dpp clk not divided by 2, no need to ramp*/ | ||
92 | if (!cur_dpp_div) | ||
93 | return new_clocks->dispclk_khz; | ||
94 | |||
95 | /* current disp clk is lower than current maximum dpp clk, | ||
96 | * no need to ramp | ||
97 | */ | ||
98 | if (clk_mgr->clks.dispclk_khz <= disp_clk_threshold) | ||
99 | return new_clocks->dispclk_khz; | ||
100 | |||
101 | /* request dpp clk need to be divided by 2 */ | ||
102 | if (request_dpp_div) | ||
103 | return new_clocks->dispclk_khz; | ||
104 | } | ||
105 | |||
106 | return disp_clk_threshold; | ||
107 | } | ||
108 | |||
109 | static void dcn1_ramp_up_dispclk_with_dpp(struct clk_mgr *clk_mgr, struct dc_clocks *new_clocks) | ||
110 | { | ||
111 | struct dc *dc = clk_mgr->ctx->dc; | ||
112 | int dispclk_to_dpp_threshold = dcn1_determine_dppclk_threshold(clk_mgr, new_clocks); | ||
113 | bool request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz; | ||
114 | int i; | ||
115 | |||
116 | /* set disp clk to dpp clk threshold */ | ||
117 | dce112_set_clock(clk_mgr, dispclk_to_dpp_threshold); | ||
118 | |||
119 | /* update request dpp clk division option */ | ||
120 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | ||
121 | struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; | ||
122 | |||
123 | if (!pipe_ctx->plane_state) | ||
124 | continue; | ||
125 | |||
126 | pipe_ctx->plane_res.dpp->funcs->dpp_dppclk_control( | ||
127 | pipe_ctx->plane_res.dpp, | ||
128 | request_dpp_div, | ||
129 | true); | ||
130 | } | ||
131 | |||
132 | /* If target clk not same as dppclk threshold, set to target clock */ | ||
133 | if (dispclk_to_dpp_threshold != new_clocks->dispclk_khz) | ||
134 | dce112_set_clock(clk_mgr, new_clocks->dispclk_khz); | ||
135 | |||
136 | clk_mgr->clks.dispclk_khz = new_clocks->dispclk_khz; | ||
137 | clk_mgr->clks.dppclk_khz = new_clocks->dppclk_khz; | ||
138 | clk_mgr->clks.max_supported_dppclk_khz = new_clocks->max_supported_dppclk_khz; | ||
139 | } | ||
140 | |||
141 | static int get_active_display_cnt( | ||
142 | struct dc *dc, | ||
143 | struct dc_state *context) | ||
144 | { | ||
145 | int i, display_count; | ||
146 | |||
147 | display_count = 0; | ||
148 | for (i = 0; i < context->stream_count; i++) { | ||
149 | const struct dc_stream_state *stream = context->streams[i]; | ||
150 | |||
151 | /* | ||
152 | * Only notify active stream or virtual stream. | ||
153 | * Need to notify virtual stream to work around | ||
154 | * headless case. HPD does not fire when system is in | ||
155 | * S0i2. | ||
156 | */ | ||
157 | if (!stream->dpms_off || stream->signal == SIGNAL_TYPE_VIRTUAL) | ||
158 | display_count++; | ||
159 | } | ||
160 | |||
161 | return display_count; | ||
162 | } | ||
163 | |||
164 | static void notify_deep_sleep_dcfclk_to_smu( | ||
165 | struct pp_smu_funcs_rv *pp_smu, int min_dcef_deep_sleep_clk_khz) | ||
166 | { | ||
167 | int min_dcef_deep_sleep_clk_mhz; //minimum required DCEF Deep Sleep clock in mhz | ||
168 | /* | ||
169 | * if function pointer not set up, this message is | ||
170 | * sent as part of pplib_apply_display_requirements. | ||
171 | * So just return. | ||
172 | */ | ||
173 | if (!pp_smu || !pp_smu->set_min_deep_sleep_dcfclk) | ||
174 | return; | ||
175 | |||
176 | min_dcef_deep_sleep_clk_mhz = (min_dcef_deep_sleep_clk_khz + 999) / 1000; //Round up | ||
177 | pp_smu->set_min_deep_sleep_dcfclk(&pp_smu->pp_smu, min_dcef_deep_sleep_clk_mhz); | ||
178 | } | ||
179 | |||
180 | static void notify_hard_min_dcfclk_to_smu( | ||
181 | struct pp_smu_funcs_rv *pp_smu, int min_dcf_clk_khz) | ||
182 | { | ||
183 | int min_dcf_clk_mhz; //minimum required DCF clock in mhz | ||
184 | |||
185 | /* | ||
186 | * if function pointer not set up, this message is | ||
187 | * sent as part of pplib_apply_display_requirements. | ||
188 | * So just return. | ||
189 | */ | ||
190 | if (!pp_smu || !pp_smu->set_hard_min_dcfclk_by_freq) | ||
191 | return; | ||
192 | |||
193 | min_dcf_clk_mhz = min_dcf_clk_khz / 1000; | ||
194 | |||
195 | pp_smu->set_hard_min_dcfclk_by_freq(&pp_smu->pp_smu, min_dcf_clk_mhz); | ||
196 | } | ||
197 | |||
198 | static void notify_hard_min_fclk_to_smu( | ||
199 | struct pp_smu_funcs_rv *pp_smu, int min_f_clk_khz) | ||
200 | { | ||
201 | int min_f_clk_mhz; //minimum required F clock in mhz | ||
202 | |||
203 | /* | ||
204 | * if function pointer not set up, this message is | ||
205 | * sent as part of pplib_apply_display_requirements. | ||
206 | * So just return. | ||
207 | */ | ||
208 | if (!pp_smu || !pp_smu->set_hard_min_fclk_by_freq) | ||
209 | return; | ||
210 | |||
211 | min_f_clk_mhz = min_f_clk_khz / 1000; | ||
212 | |||
213 | pp_smu->set_hard_min_fclk_by_freq(&pp_smu->pp_smu, min_f_clk_mhz); | ||
214 | } | ||
215 | |||
216 | static void dcn1_update_clocks(struct clk_mgr *clk_mgr, | ||
217 | struct dc_state *context, | ||
218 | bool safe_to_lower) | ||
219 | { | ||
220 | struct dc *dc = clk_mgr->ctx->dc; | ||
221 | struct dc_clocks *new_clocks = &context->bw.dcn.clk; | ||
222 | struct pp_smu_display_requirement_rv *smu_req_cur = | ||
223 | &dc->res_pool->pp_smu_req; | ||
224 | struct pp_smu_display_requirement_rv smu_req = *smu_req_cur; | ||
225 | struct pp_smu_funcs_rv *pp_smu = dc->res_pool->pp_smu; | ||
226 | struct dm_pp_clock_for_voltage_req clock_voltage_req = {0}; | ||
227 | bool send_request_to_increase = false; | ||
228 | bool send_request_to_lower = false; | ||
229 | int display_count; | ||
230 | |||
231 | bool enter_display_off = false; | ||
232 | |||
233 | display_count = get_active_display_cnt(dc, context); | ||
234 | |||
235 | if (display_count == 0) | ||
236 | enter_display_off = true; | ||
237 | |||
238 | if (enter_display_off == safe_to_lower) { | ||
239 | /* | ||
240 | * Notify SMU active displays | ||
241 | * if function pointer not set up, this message is | ||
242 | * sent as part of pplib_apply_display_requirements. | ||
243 | */ | ||
244 | if (pp_smu->set_display_count) | ||
245 | pp_smu->set_display_count(&pp_smu->pp_smu, display_count); | ||
246 | else | ||
247 | smu_req.display_count = display_count; | ||
248 | |||
249 | } | ||
250 | |||
251 | if (new_clocks->dispclk_khz > clk_mgr->clks.dispclk_khz | ||
252 | || new_clocks->phyclk_khz > clk_mgr->clks.phyclk_khz | ||
253 | || new_clocks->fclk_khz > clk_mgr->clks.fclk_khz | ||
254 | || new_clocks->dcfclk_khz > clk_mgr->clks.dcfclk_khz) | ||
255 | send_request_to_increase = true; | ||
256 | |||
257 | if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, clk_mgr->clks.phyclk_khz)) { | ||
258 | clk_mgr->clks.phyclk_khz = new_clocks->phyclk_khz; | ||
259 | |||
260 | send_request_to_lower = true; | ||
261 | } | ||
262 | |||
263 | // F Clock | ||
264 | if (should_set_clock(safe_to_lower, new_clocks->fclk_khz, clk_mgr->clks.fclk_khz)) { | ||
265 | clk_mgr->clks.fclk_khz = new_clocks->fclk_khz; | ||
266 | clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_FCLK; | ||
267 | clock_voltage_req.clocks_in_khz = new_clocks->fclk_khz; | ||
268 | smu_req.hard_min_fclk_mhz = new_clocks->fclk_khz / 1000; | ||
269 | |||
270 | notify_hard_min_fclk_to_smu(pp_smu, new_clocks->fclk_khz); | ||
271 | |||
272 | send_request_to_lower = true; | ||
273 | } | ||
274 | |||
275 | //DCF Clock | ||
276 | if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, clk_mgr->clks.dcfclk_khz)) { | ||
277 | clk_mgr->clks.dcfclk_khz = new_clocks->dcfclk_khz; | ||
278 | smu_req.hard_min_dcefclk_mhz = new_clocks->dcfclk_khz / 1000; | ||
279 | |||
280 | send_request_to_lower = true; | ||
281 | } | ||
282 | |||
283 | if (should_set_clock(safe_to_lower, | ||
284 | new_clocks->dcfclk_deep_sleep_khz, clk_mgr->clks.dcfclk_deep_sleep_khz)) { | ||
285 | clk_mgr->clks.dcfclk_deep_sleep_khz = new_clocks->dcfclk_deep_sleep_khz; | ||
286 | smu_req.min_deep_sleep_dcefclk_mhz = new_clocks->dcfclk_deep_sleep_khz / 1000; | ||
287 | |||
288 | send_request_to_lower = true; | ||
289 | } | ||
290 | |||
291 | /* make sure dcf clk is before dpp clk to | ||
292 | * make sure we have enough voltage to run dpp clk | ||
293 | */ | ||
294 | if (send_request_to_increase) { | ||
295 | /*use dcfclk to request voltage*/ | ||
296 | clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; | ||
297 | clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(dc, new_clocks); | ||
298 | |||
299 | notify_hard_min_dcfclk_to_smu(pp_smu, clock_voltage_req.clocks_in_khz); | ||
300 | |||
301 | if (pp_smu->set_display_requirement) | ||
302 | pp_smu->set_display_requirement(&pp_smu->pp_smu, &smu_req); | ||
303 | |||
304 | notify_deep_sleep_dcfclk_to_smu(pp_smu, clk_mgr->clks.dcfclk_deep_sleep_khz); | ||
305 | dcn1_pplib_apply_display_requirements(dc, context); | ||
306 | } | ||
307 | |||
308 | /* dcn1 dppclk is tied to dispclk */ | ||
309 | /* program dispclk on = as a w/a for sleep resume clock ramping issues */ | ||
310 | if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr->clks.dispclk_khz) | ||
311 | || new_clocks->dispclk_khz == clk_mgr->clks.dispclk_khz) { | ||
312 | dcn1_ramp_up_dispclk_with_dpp(clk_mgr, new_clocks); | ||
313 | clk_mgr->clks.dispclk_khz = new_clocks->dispclk_khz; | ||
314 | |||
315 | send_request_to_lower = true; | ||
316 | } | ||
317 | |||
318 | if (!send_request_to_increase && send_request_to_lower) { | ||
319 | /*use dcfclk to request voltage*/ | ||
320 | clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; | ||
321 | clock_voltage_req.clocks_in_khz = dcn_find_dcfclk_suits_all(dc, new_clocks); | ||
322 | |||
323 | notify_hard_min_dcfclk_to_smu(pp_smu, clock_voltage_req.clocks_in_khz); | ||
324 | |||
325 | if (pp_smu->set_display_requirement) | ||
326 | pp_smu->set_display_requirement(&pp_smu->pp_smu, &smu_req); | ||
327 | |||
328 | notify_deep_sleep_dcfclk_to_smu(pp_smu, clk_mgr->clks.dcfclk_deep_sleep_khz); | ||
329 | dcn1_pplib_apply_display_requirements(dc, context); | ||
330 | } | ||
331 | |||
332 | |||
333 | *smu_req_cur = smu_req; | ||
334 | } | ||
335 | |||
336 | static const struct clk_mgr_funcs dcn1_funcs = { | ||
337 | .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, | ||
338 | .update_clocks = dcn1_update_clocks | ||
339 | }; | ||
340 | |||
341 | struct clk_mgr *dcn1_clk_mgr_create(struct dc_context *ctx) | ||
342 | { | ||
343 | struct dc_debug_options *debug = &ctx->dc->debug; | ||
344 | struct dc_bios *bp = ctx->dc_bios; | ||
345 | struct dc_firmware_info fw_info = { { 0 } }; | ||
346 | struct dce_clk_mgr *clk_mgr_dce = kzalloc(sizeof(*clk_mgr_dce), GFP_KERNEL); | ||
347 | |||
348 | if (clk_mgr_dce == NULL) { | ||
349 | BREAK_TO_DEBUGGER(); | ||
350 | return NULL; | ||
351 | } | ||
352 | |||
353 | clk_mgr_dce->base.ctx = ctx; | ||
354 | clk_mgr_dce->base.funcs = &dcn1_funcs; | ||
355 | |||
356 | clk_mgr_dce->dfs_bypass_disp_clk = 0; | ||
357 | |||
358 | clk_mgr_dce->dprefclk_ss_percentage = 0; | ||
359 | clk_mgr_dce->dprefclk_ss_divider = 1000; | ||
360 | clk_mgr_dce->ss_on_dprefclk = false; | ||
361 | |||
362 | clk_mgr_dce->dprefclk_khz = 600000; | ||
363 | if (bp->integrated_info) | ||
364 | clk_mgr_dce->dentist_vco_freq_khz = bp->integrated_info->dentist_vco_freq; | ||
365 | if (clk_mgr_dce->dentist_vco_freq_khz == 0) { | ||
366 | bp->funcs->get_firmware_info(bp, &fw_info); | ||
367 | clk_mgr_dce->dentist_vco_freq_khz = fw_info.smu_gpu_pll_output_freq; | ||
368 | if (clk_mgr_dce->dentist_vco_freq_khz == 0) | ||
369 | clk_mgr_dce->dentist_vco_freq_khz = 3600000; | ||
370 | } | ||
371 | |||
372 | if (!debug->disable_dfs_bypass && bp->integrated_info) | ||
373 | if (bp->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE) | ||
374 | clk_mgr_dce->dfs_bypass_enabled = true; | ||
375 | |||
376 | dce_clock_read_ss_info(clk_mgr_dce); | ||
377 | |||
378 | return &clk_mgr_dce->base; | ||
379 | } | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_clk_mgr.h new file mode 100644 index 000000000000..9dbaf6578006 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_clk_mgr.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * Copyright 2018 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: AMD | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #ifndef __DCN10_CLK_MGR_H__ | ||
27 | #define __DCN10_CLK_MGR_H__ | ||
28 | |||
29 | #include "../dce/dce_clk_mgr.h" | ||
30 | |||
31 | void dcn1_pplib_apply_display_requirements( | ||
32 | struct dc *dc, | ||
33 | struct dc_state *context); | ||
34 | |||
35 | struct clk_mgr *dcn1_clk_mgr_create(struct dc_context *ctx); | ||
36 | |||
37 | #endif //__DCN10_CLK_MGR_H__ | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c index 5d95a997fd9f..3eea44092a04 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c | |||
@@ -71,39 +71,39 @@ void cm_helper_program_xfer_func( | |||
71 | unsigned int i = 0; | 71 | unsigned int i = 0; |
72 | 72 | ||
73 | REG_SET_2(reg->start_cntl_b, 0, | 73 | REG_SET_2(reg->start_cntl_b, 0, |
74 | exp_region_start, params->arr_points[0].custom_float_x, | 74 | exp_region_start, params->corner_points[0].blue.custom_float_x, |
75 | exp_resion_start_segment, 0); | 75 | exp_resion_start_segment, 0); |
76 | REG_SET_2(reg->start_cntl_g, 0, | 76 | REG_SET_2(reg->start_cntl_g, 0, |
77 | exp_region_start, params->arr_points[0].custom_float_x, | 77 | exp_region_start, params->corner_points[0].green.custom_float_x, |
78 | exp_resion_start_segment, 0); | 78 | exp_resion_start_segment, 0); |
79 | REG_SET_2(reg->start_cntl_r, 0, | 79 | REG_SET_2(reg->start_cntl_r, 0, |
80 | exp_region_start, params->arr_points[0].custom_float_x, | 80 | exp_region_start, params->corner_points[0].red.custom_float_x, |
81 | exp_resion_start_segment, 0); | 81 | exp_resion_start_segment, 0); |
82 | 82 | ||
83 | REG_SET(reg->start_slope_cntl_b, 0, | 83 | REG_SET(reg->start_slope_cntl_b, 0, |
84 | field_region_linear_slope, params->arr_points[0].custom_float_slope); | 84 | field_region_linear_slope, params->corner_points[0].blue.custom_float_slope); |
85 | REG_SET(reg->start_slope_cntl_g, 0, | 85 | REG_SET(reg->start_slope_cntl_g, 0, |
86 | field_region_linear_slope, params->arr_points[0].custom_float_slope); | 86 | field_region_linear_slope, params->corner_points[0].green.custom_float_slope); |
87 | REG_SET(reg->start_slope_cntl_r, 0, | 87 | REG_SET(reg->start_slope_cntl_r, 0, |
88 | field_region_linear_slope, params->arr_points[0].custom_float_slope); | 88 | field_region_linear_slope, params->corner_points[0].red.custom_float_slope); |
89 | 89 | ||
90 | REG_SET(reg->start_end_cntl1_b, 0, | 90 | REG_SET(reg->start_end_cntl1_b, 0, |
91 | field_region_end, params->arr_points[1].custom_float_x); | 91 | field_region_end, params->corner_points[1].blue.custom_float_x); |
92 | REG_SET_2(reg->start_end_cntl2_b, 0, | 92 | REG_SET_2(reg->start_end_cntl2_b, 0, |
93 | field_region_end_slope, params->arr_points[1].custom_float_slope, | 93 | field_region_end_slope, params->corner_points[1].blue.custom_float_slope, |
94 | field_region_end_base, params->arr_points[1].custom_float_y); | 94 | field_region_end_base, params->corner_points[1].blue.custom_float_y); |
95 | 95 | ||
96 | REG_SET(reg->start_end_cntl1_g, 0, | 96 | REG_SET(reg->start_end_cntl1_g, 0, |
97 | field_region_end, params->arr_points[1].custom_float_x); | 97 | field_region_end, params->corner_points[1].green.custom_float_x); |
98 | REG_SET_2(reg->start_end_cntl2_g, 0, | 98 | REG_SET_2(reg->start_end_cntl2_g, 0, |
99 | field_region_end_slope, params->arr_points[1].custom_float_slope, | 99 | field_region_end_slope, params->corner_points[1].green.custom_float_slope, |
100 | field_region_end_base, params->arr_points[1].custom_float_y); | 100 | field_region_end_base, params->corner_points[1].green.custom_float_y); |
101 | 101 | ||
102 | REG_SET(reg->start_end_cntl1_r, 0, | 102 | REG_SET(reg->start_end_cntl1_r, 0, |
103 | field_region_end, params->arr_points[1].custom_float_x); | 103 | field_region_end, params->corner_points[1].red.custom_float_x); |
104 | REG_SET_2(reg->start_end_cntl2_r, 0, | 104 | REG_SET_2(reg->start_end_cntl2_r, 0, |
105 | field_region_end_slope, params->arr_points[1].custom_float_slope, | 105 | field_region_end_slope, params->corner_points[1].red.custom_float_slope, |
106 | field_region_end_base, params->arr_points[1].custom_float_y); | 106 | field_region_end_base, params->corner_points[1].red.custom_float_y); |
107 | 107 | ||
108 | for (reg_region_cur = reg->region_start; | 108 | for (reg_region_cur = reg->region_start; |
109 | reg_region_cur <= reg->region_end; | 109 | reg_region_cur <= reg->region_end; |
@@ -127,7 +127,7 @@ void cm_helper_program_xfer_func( | |||
127 | 127 | ||
128 | bool cm_helper_convert_to_custom_float( | 128 | bool cm_helper_convert_to_custom_float( |
129 | struct pwl_result_data *rgb_resulted, | 129 | struct pwl_result_data *rgb_resulted, |
130 | struct curve_points *arr_points, | 130 | struct curve_points3 *corner_points, |
131 | uint32_t hw_points_num, | 131 | uint32_t hw_points_num, |
132 | bool fixpoint) | 132 | bool fixpoint) |
133 | { | 133 | { |
@@ -141,20 +141,53 @@ bool cm_helper_convert_to_custom_float( | |||
141 | fmt.mantissa_bits = 12; | 141 | fmt.mantissa_bits = 12; |
142 | fmt.sign = false; | 142 | fmt.sign = false; |
143 | 143 | ||
144 | if (!convert_to_custom_float_format(arr_points[0].x, &fmt, | 144 | /* corner_points[0] - beginning base, slope offset for R,G,B |
145 | &arr_points[0].custom_float_x)) { | 145 | * corner_points[1] - end base, slope offset for R,G,B |
146 | */ | ||
147 | if (!convert_to_custom_float_format(corner_points[0].red.x, &fmt, | ||
148 | &corner_points[0].red.custom_float_x)) { | ||
149 | BREAK_TO_DEBUGGER(); | ||
150 | return false; | ||
151 | } | ||
152 | if (!convert_to_custom_float_format(corner_points[0].green.x, &fmt, | ||
153 | &corner_points[0].green.custom_float_x)) { | ||
154 | BREAK_TO_DEBUGGER(); | ||
155 | return false; | ||
156 | } | ||
157 | if (!convert_to_custom_float_format(corner_points[0].blue.x, &fmt, | ||
158 | &corner_points[0].blue.custom_float_x)) { | ||
146 | BREAK_TO_DEBUGGER(); | 159 | BREAK_TO_DEBUGGER(); |
147 | return false; | 160 | return false; |
148 | } | 161 | } |
149 | 162 | ||
150 | if (!convert_to_custom_float_format(arr_points[0].offset, &fmt, | 163 | if (!convert_to_custom_float_format(corner_points[0].red.offset, &fmt, |
151 | &arr_points[0].custom_float_offset)) { | 164 | &corner_points[0].red.custom_float_offset)) { |
165 | BREAK_TO_DEBUGGER(); | ||
166 | return false; | ||
167 | } | ||
168 | if (!convert_to_custom_float_format(corner_points[0].green.offset, &fmt, | ||
169 | &corner_points[0].green.custom_float_offset)) { | ||
170 | BREAK_TO_DEBUGGER(); | ||
171 | return false; | ||
172 | } | ||
173 | if (!convert_to_custom_float_format(corner_points[0].blue.offset, &fmt, | ||
174 | &corner_points[0].blue.custom_float_offset)) { | ||
152 | BREAK_TO_DEBUGGER(); | 175 | BREAK_TO_DEBUGGER(); |
153 | return false; | 176 | return false; |
154 | } | 177 | } |
155 | 178 | ||
156 | if (!convert_to_custom_float_format(arr_points[0].slope, &fmt, | 179 | if (!convert_to_custom_float_format(corner_points[0].red.slope, &fmt, |
157 | &arr_points[0].custom_float_slope)) { | 180 | &corner_points[0].red.custom_float_slope)) { |
181 | BREAK_TO_DEBUGGER(); | ||
182 | return false; | ||
183 | } | ||
184 | if (!convert_to_custom_float_format(corner_points[0].green.slope, &fmt, | ||
185 | &corner_points[0].green.custom_float_slope)) { | ||
186 | BREAK_TO_DEBUGGER(); | ||
187 | return false; | ||
188 | } | ||
189 | if (!convert_to_custom_float_format(corner_points[0].blue.slope, &fmt, | ||
190 | &corner_points[0].blue.custom_float_slope)) { | ||
158 | BREAK_TO_DEBUGGER(); | 191 | BREAK_TO_DEBUGGER(); |
159 | return false; | 192 | return false; |
160 | } | 193 | } |
@@ -162,22 +195,59 @@ bool cm_helper_convert_to_custom_float( | |||
162 | fmt.mantissa_bits = 10; | 195 | fmt.mantissa_bits = 10; |
163 | fmt.sign = false; | 196 | fmt.sign = false; |
164 | 197 | ||
165 | if (!convert_to_custom_float_format(arr_points[1].x, &fmt, | 198 | if (!convert_to_custom_float_format(corner_points[1].red.x, &fmt, |
166 | &arr_points[1].custom_float_x)) { | 199 | &corner_points[1].red.custom_float_x)) { |
167 | BREAK_TO_DEBUGGER(); | 200 | BREAK_TO_DEBUGGER(); |
168 | return false; | 201 | return false; |
169 | } | 202 | } |
170 | 203 | if (!convert_to_custom_float_format(corner_points[1].green.x, &fmt, | |
171 | if (fixpoint == true) | 204 | &corner_points[1].green.custom_float_x)) { |
172 | arr_points[1].custom_float_y = dc_fixpt_clamp_u0d14(arr_points[1].y); | 205 | BREAK_TO_DEBUGGER(); |
173 | else if (!convert_to_custom_float_format(arr_points[1].y, &fmt, | 206 | return false; |
174 | &arr_points[1].custom_float_y)) { | 207 | } |
208 | if (!convert_to_custom_float_format(corner_points[1].blue.x, &fmt, | ||
209 | &corner_points[1].blue.custom_float_x)) { | ||
175 | BREAK_TO_DEBUGGER(); | 210 | BREAK_TO_DEBUGGER(); |
176 | return false; | 211 | return false; |
177 | } | 212 | } |
178 | 213 | ||
179 | if (!convert_to_custom_float_format(arr_points[1].slope, &fmt, | 214 | if (fixpoint == true) { |
180 | &arr_points[1].custom_float_slope)) { | 215 | corner_points[1].red.custom_float_y = |
216 | dc_fixpt_clamp_u0d14(corner_points[1].red.y); | ||
217 | corner_points[1].green.custom_float_y = | ||
218 | dc_fixpt_clamp_u0d14(corner_points[1].green.y); | ||
219 | corner_points[1].blue.custom_float_y = | ||
220 | dc_fixpt_clamp_u0d14(corner_points[1].blue.y); | ||
221 | } else { | ||
222 | if (!convert_to_custom_float_format(corner_points[1].red.y, | ||
223 | &fmt, &corner_points[1].red.custom_float_y)) { | ||
224 | BREAK_TO_DEBUGGER(); | ||
225 | return false; | ||
226 | } | ||
227 | if (!convert_to_custom_float_format(corner_points[1].green.y, | ||
228 | &fmt, &corner_points[1].green.custom_float_y)) { | ||
229 | BREAK_TO_DEBUGGER(); | ||
230 | return false; | ||
231 | } | ||
232 | if (!convert_to_custom_float_format(corner_points[1].blue.y, | ||
233 | &fmt, &corner_points[1].blue.custom_float_y)) { | ||
234 | BREAK_TO_DEBUGGER(); | ||
235 | return false; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | if (!convert_to_custom_float_format(corner_points[1].red.slope, &fmt, | ||
240 | &corner_points[1].red.custom_float_slope)) { | ||
241 | BREAK_TO_DEBUGGER(); | ||
242 | return false; | ||
243 | } | ||
244 | if (!convert_to_custom_float_format(corner_points[1].green.slope, &fmt, | ||
245 | &corner_points[1].green.custom_float_slope)) { | ||
246 | BREAK_TO_DEBUGGER(); | ||
247 | return false; | ||
248 | } | ||
249 | if (!convert_to_custom_float_format(corner_points[1].blue.slope, &fmt, | ||
250 | &corner_points[1].blue.custom_float_slope)) { | ||
181 | BREAK_TO_DEBUGGER(); | 251 | BREAK_TO_DEBUGGER(); |
182 | return false; | 252 | return false; |
183 | } | 253 | } |
@@ -242,15 +312,10 @@ bool cm_helper_translate_curve_to_hw_format( | |||
242 | const struct dc_transfer_func *output_tf, | 312 | const struct dc_transfer_func *output_tf, |
243 | struct pwl_params *lut_params, bool fixpoint) | 313 | struct pwl_params *lut_params, bool fixpoint) |
244 | { | 314 | { |
245 | struct curve_points *arr_points; | 315 | struct curve_points3 *corner_points; |
246 | struct pwl_result_data *rgb_resulted; | 316 | struct pwl_result_data *rgb_resulted; |
247 | struct pwl_result_data *rgb; | 317 | struct pwl_result_data *rgb; |
248 | struct pwl_result_data *rgb_plus_1; | 318 | struct pwl_result_data *rgb_plus_1; |
249 | struct fixed31_32 y_r; | ||
250 | struct fixed31_32 y_g; | ||
251 | struct fixed31_32 y_b; | ||
252 | struct fixed31_32 y1_min; | ||
253 | struct fixed31_32 y3_max; | ||
254 | 319 | ||
255 | int32_t region_start, region_end; | 320 | int32_t region_start, region_end; |
256 | int32_t i; | 321 | int32_t i; |
@@ -261,14 +326,14 @@ bool cm_helper_translate_curve_to_hw_format( | |||
261 | 326 | ||
262 | PERF_TRACE(); | 327 | PERF_TRACE(); |
263 | 328 | ||
264 | arr_points = lut_params->arr_points; | 329 | corner_points = lut_params->corner_points; |
265 | rgb_resulted = lut_params->rgb_resulted; | 330 | rgb_resulted = lut_params->rgb_resulted; |
266 | hw_points = 0; | 331 | hw_points = 0; |
267 | 332 | ||
268 | memset(lut_params, 0, sizeof(struct pwl_params)); | 333 | memset(lut_params, 0, sizeof(struct pwl_params)); |
269 | memset(seg_distr, 0, sizeof(seg_distr)); | 334 | memset(seg_distr, 0, sizeof(seg_distr)); |
270 | 335 | ||
271 | if (output_tf->tf == TRANSFER_FUNCTION_PQ) { | 336 | if (output_tf->tf == TRANSFER_FUNCTION_PQ || output_tf->tf == TRANSFER_FUNCTION_GAMMA22) { |
272 | /* 32 segments | 337 | /* 32 segments |
273 | * segments are from 2^-25 to 2^7 | 338 | * segments are from 2^-25 to 2^7 |
274 | */ | 339 | */ |
@@ -327,31 +392,37 @@ bool cm_helper_translate_curve_to_hw_format( | |||
327 | rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; | 392 | rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; |
328 | rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; | 393 | rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; |
329 | 394 | ||
330 | arr_points[0].x = dc_fixpt_pow(dc_fixpt_from_int(2), | 395 | // All 3 color channels have same x |
396 | corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2), | ||
331 | dc_fixpt_from_int(region_start)); | 397 | dc_fixpt_from_int(region_start)); |
332 | arr_points[1].x = dc_fixpt_pow(dc_fixpt_from_int(2), | 398 | corner_points[0].green.x = corner_points[0].red.x; |
333 | dc_fixpt_from_int(region_end)); | 399 | corner_points[0].blue.x = corner_points[0].red.x; |
334 | 400 | ||
335 | y_r = rgb_resulted[0].red; | 401 | corner_points[1].red.x = dc_fixpt_pow(dc_fixpt_from_int(2), |
336 | y_g = rgb_resulted[0].green; | 402 | dc_fixpt_from_int(region_end)); |
337 | y_b = rgb_resulted[0].blue; | 403 | corner_points[1].green.x = corner_points[1].red.x; |
404 | corner_points[1].blue.x = corner_points[1].red.x; | ||
338 | 405 | ||
339 | y1_min = dc_fixpt_min(y_r, dc_fixpt_min(y_g, y_b)); | 406 | corner_points[0].red.y = rgb_resulted[0].red; |
407 | corner_points[0].green.y = rgb_resulted[0].green; | ||
408 | corner_points[0].blue.y = rgb_resulted[0].blue; | ||
340 | 409 | ||
341 | arr_points[0].y = y1_min; | 410 | corner_points[0].red.slope = dc_fixpt_div(corner_points[0].red.y, |
342 | arr_points[0].slope = dc_fixpt_div(arr_points[0].y, arr_points[0].x); | 411 | corner_points[0].red.x); |
343 | y_r = rgb_resulted[hw_points - 1].red; | 412 | corner_points[0].green.slope = dc_fixpt_div(corner_points[0].green.y, |
344 | y_g = rgb_resulted[hw_points - 1].green; | 413 | corner_points[0].green.x); |
345 | y_b = rgb_resulted[hw_points - 1].blue; | 414 | corner_points[0].blue.slope = dc_fixpt_div(corner_points[0].blue.y, |
415 | corner_points[0].blue.x); | ||
346 | 416 | ||
347 | /* see comment above, m_arrPoints[1].y should be the Y value for the | 417 | /* see comment above, m_arrPoints[1].y should be the Y value for the |
348 | * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) | 418 | * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) |
349 | */ | 419 | */ |
350 | y3_max = dc_fixpt_max(y_r, dc_fixpt_max(y_g, y_b)); | 420 | corner_points[1].red.y = rgb_resulted[hw_points - 1].red; |
351 | 421 | corner_points[1].green.y = rgb_resulted[hw_points - 1].green; | |
352 | arr_points[1].y = y3_max; | 422 | corner_points[1].blue.y = rgb_resulted[hw_points - 1].blue; |
353 | 423 | corner_points[1].red.slope = dc_fixpt_zero; | |
354 | arr_points[1].slope = dc_fixpt_zero; | 424 | corner_points[1].green.slope = dc_fixpt_zero; |
425 | corner_points[1].blue.slope = dc_fixpt_zero; | ||
355 | 426 | ||
356 | if (output_tf->tf == TRANSFER_FUNCTION_PQ) { | 427 | if (output_tf->tf == TRANSFER_FUNCTION_PQ) { |
357 | /* for PQ, we want to have a straight line from last HW X point, | 428 | /* for PQ, we want to have a straight line from last HW X point, |
@@ -360,9 +431,15 @@ bool cm_helper_translate_curve_to_hw_format( | |||
360 | const struct fixed31_32 end_value = | 431 | const struct fixed31_32 end_value = |
361 | dc_fixpt_from_int(125); | 432 | dc_fixpt_from_int(125); |
362 | 433 | ||
363 | arr_points[1].slope = dc_fixpt_div( | 434 | corner_points[1].red.slope = dc_fixpt_div( |
364 | dc_fixpt_sub(dc_fixpt_one, arr_points[1].y), | 435 | dc_fixpt_sub(dc_fixpt_one, corner_points[1].red.y), |
365 | dc_fixpt_sub(end_value, arr_points[1].x)); | 436 | dc_fixpt_sub(end_value, corner_points[1].red.x)); |
437 | corner_points[1].green.slope = dc_fixpt_div( | ||
438 | dc_fixpt_sub(dc_fixpt_one, corner_points[1].green.y), | ||
439 | dc_fixpt_sub(end_value, corner_points[1].green.x)); | ||
440 | corner_points[1].blue.slope = dc_fixpt_div( | ||
441 | dc_fixpt_sub(dc_fixpt_one, corner_points[1].blue.y), | ||
442 | dc_fixpt_sub(end_value, corner_points[1].blue.x)); | ||
366 | } | 443 | } |
367 | 444 | ||
368 | lut_params->hw_points_num = hw_points; | 445 | lut_params->hw_points_num = hw_points; |
@@ -411,7 +488,7 @@ bool cm_helper_translate_curve_to_hw_format( | |||
411 | ++i; | 488 | ++i; |
412 | } | 489 | } |
413 | cm_helper_convert_to_custom_float(rgb_resulted, | 490 | cm_helper_convert_to_custom_float(rgb_resulted, |
414 | lut_params->arr_points, | 491 | lut_params->corner_points, |
415 | hw_points, fixpoint); | 492 | hw_points, fixpoint); |
416 | 493 | ||
417 | return true; | 494 | return true; |
@@ -424,15 +501,10 @@ bool cm_helper_translate_curve_to_degamma_hw_format( | |||
424 | const struct dc_transfer_func *output_tf, | 501 | const struct dc_transfer_func *output_tf, |
425 | struct pwl_params *lut_params) | 502 | struct pwl_params *lut_params) |
426 | { | 503 | { |
427 | struct curve_points *arr_points; | 504 | struct curve_points3 *corner_points; |
428 | struct pwl_result_data *rgb_resulted; | 505 | struct pwl_result_data *rgb_resulted; |
429 | struct pwl_result_data *rgb; | 506 | struct pwl_result_data *rgb; |
430 | struct pwl_result_data *rgb_plus_1; | 507 | struct pwl_result_data *rgb_plus_1; |
431 | struct fixed31_32 y_r; | ||
432 | struct fixed31_32 y_g; | ||
433 | struct fixed31_32 y_b; | ||
434 | struct fixed31_32 y1_min; | ||
435 | struct fixed31_32 y3_max; | ||
436 | 508 | ||
437 | int32_t region_start, region_end; | 509 | int32_t region_start, region_end; |
438 | int32_t i; | 510 | int32_t i; |
@@ -443,7 +515,7 @@ bool cm_helper_translate_curve_to_degamma_hw_format( | |||
443 | 515 | ||
444 | PERF_TRACE(); | 516 | PERF_TRACE(); |
445 | 517 | ||
446 | arr_points = lut_params->arr_points; | 518 | corner_points = lut_params->corner_points; |
447 | rgb_resulted = lut_params->rgb_resulted; | 519 | rgb_resulted = lut_params->rgb_resulted; |
448 | hw_points = 0; | 520 | hw_points = 0; |
449 | 521 | ||
@@ -489,31 +561,28 @@ bool cm_helper_translate_curve_to_degamma_hw_format( | |||
489 | rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; | 561 | rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; |
490 | rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; | 562 | rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; |
491 | 563 | ||
492 | arr_points[0].x = dc_fixpt_pow(dc_fixpt_from_int(2), | 564 | corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2), |
493 | dc_fixpt_from_int(region_start)); | 565 | dc_fixpt_from_int(region_start)); |
494 | arr_points[1].x = dc_fixpt_pow(dc_fixpt_from_int(2), | 566 | corner_points[0].green.x = corner_points[0].red.x; |
567 | corner_points[0].blue.x = corner_points[0].red.x; | ||
568 | corner_points[1].red.x = dc_fixpt_pow(dc_fixpt_from_int(2), | ||
495 | dc_fixpt_from_int(region_end)); | 569 | dc_fixpt_from_int(region_end)); |
570 | corner_points[1].green.x = corner_points[1].red.x; | ||
571 | corner_points[1].blue.x = corner_points[1].red.x; | ||
496 | 572 | ||
497 | y_r = rgb_resulted[0].red; | 573 | corner_points[0].red.y = rgb_resulted[0].red; |
498 | y_g = rgb_resulted[0].green; | 574 | corner_points[0].green.y = rgb_resulted[0].green; |
499 | y_b = rgb_resulted[0].blue; | 575 | corner_points[0].blue.y = rgb_resulted[0].blue; |
500 | |||
501 | y1_min = dc_fixpt_min(y_r, dc_fixpt_min(y_g, y_b)); | ||
502 | |||
503 | arr_points[0].y = y1_min; | ||
504 | arr_points[0].slope = dc_fixpt_div(arr_points[0].y, arr_points[0].x); | ||
505 | y_r = rgb_resulted[hw_points - 1].red; | ||
506 | y_g = rgb_resulted[hw_points - 1].green; | ||
507 | y_b = rgb_resulted[hw_points - 1].blue; | ||
508 | 576 | ||
509 | /* see comment above, m_arrPoints[1].y should be the Y value for the | 577 | /* see comment above, m_arrPoints[1].y should be the Y value for the |
510 | * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) | 578 | * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) |
511 | */ | 579 | */ |
512 | y3_max = dc_fixpt_max(y_r, dc_fixpt_max(y_g, y_b)); | 580 | corner_points[1].red.y = rgb_resulted[hw_points - 1].red; |
513 | 581 | corner_points[1].green.y = rgb_resulted[hw_points - 1].green; | |
514 | arr_points[1].y = y3_max; | 582 | corner_points[1].blue.y = rgb_resulted[hw_points - 1].blue; |
515 | 583 | corner_points[1].red.slope = dc_fixpt_zero; | |
516 | arr_points[1].slope = dc_fixpt_zero; | 584 | corner_points[1].green.slope = dc_fixpt_zero; |
585 | corner_points[1].blue.slope = dc_fixpt_zero; | ||
517 | 586 | ||
518 | if (output_tf->tf == TRANSFER_FUNCTION_PQ) { | 587 | if (output_tf->tf == TRANSFER_FUNCTION_PQ) { |
519 | /* for PQ, we want to have a straight line from last HW X point, | 588 | /* for PQ, we want to have a straight line from last HW X point, |
@@ -522,9 +591,15 @@ bool cm_helper_translate_curve_to_degamma_hw_format( | |||
522 | const struct fixed31_32 end_value = | 591 | const struct fixed31_32 end_value = |
523 | dc_fixpt_from_int(125); | 592 | dc_fixpt_from_int(125); |
524 | 593 | ||
525 | arr_points[1].slope = dc_fixpt_div( | 594 | corner_points[1].red.slope = dc_fixpt_div( |
526 | dc_fixpt_sub(dc_fixpt_one, arr_points[1].y), | 595 | dc_fixpt_sub(dc_fixpt_one, corner_points[1].red.y), |
527 | dc_fixpt_sub(end_value, arr_points[1].x)); | 596 | dc_fixpt_sub(end_value, corner_points[1].red.x)); |
597 | corner_points[1].green.slope = dc_fixpt_div( | ||
598 | dc_fixpt_sub(dc_fixpt_one, corner_points[1].green.y), | ||
599 | dc_fixpt_sub(end_value, corner_points[1].green.x)); | ||
600 | corner_points[1].blue.slope = dc_fixpt_div( | ||
601 | dc_fixpt_sub(dc_fixpt_one, corner_points[1].blue.y), | ||
602 | dc_fixpt_sub(end_value, corner_points[1].blue.x)); | ||
528 | } | 603 | } |
529 | 604 | ||
530 | lut_params->hw_points_num = hw_points; | 605 | lut_params->hw_points_num = hw_points; |
@@ -564,7 +639,7 @@ bool cm_helper_translate_curve_to_degamma_hw_format( | |||
564 | ++i; | 639 | ++i; |
565 | } | 640 | } |
566 | cm_helper_convert_to_custom_float(rgb_resulted, | 641 | cm_helper_convert_to_custom_float(rgb_resulted, |
567 | lut_params->arr_points, | 642 | lut_params->corner_points, |
568 | hw_points, false); | 643 | hw_points, false); |
569 | 644 | ||
570 | return true; | 645 | return true; |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h index 7a531b02871f..5ae4d69391a5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h | |||
@@ -98,7 +98,7 @@ void cm_helper_program_xfer_func( | |||
98 | 98 | ||
99 | bool cm_helper_convert_to_custom_float( | 99 | bool cm_helper_convert_to_custom_float( |
100 | struct pwl_result_data *rgb_resulted, | 100 | struct pwl_result_data *rgb_resulted, |
101 | struct curve_points *arr_points, | 101 | struct curve_points3 *corner_points, |
102 | uint32_t hw_points_num, | 102 | uint32_t hw_points_num, |
103 | bool fixpoint); | 103 | bool fixpoint); |
104 | 104 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 193184affefb..87495dea45ec 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include "dcn10_hubbub.h" | 45 | #include "dcn10_hubbub.h" |
46 | #include "dcn10_cm_common.h" | 46 | #include "dcn10_cm_common.h" |
47 | #include "dc_link_dp.h" | 47 | #include "dc_link_dp.h" |
48 | #include "dccg.h" | ||
48 | 49 | ||
49 | #define DC_LOGGER_INIT(logger) | 50 | #define DC_LOGGER_INIT(logger) |
50 | 51 | ||
@@ -786,7 +787,7 @@ static bool dcn10_hw_wa_force_recovery(struct dc *dc) | |||
786 | &dc->current_state->res_ctx.pipe_ctx[i]; | 787 | &dc->current_state->res_ctx.pipe_ctx[i]; |
787 | if (pipe_ctx != NULL) { | 788 | if (pipe_ctx != NULL) { |
788 | hubp = pipe_ctx->plane_res.hubp; | 789 | hubp = pipe_ctx->plane_res.hubp; |
789 | if (hubp != NULL) { | 790 | if (hubp != NULL && hubp->funcs->hubp_get_underflow_status) { |
790 | if (hubp->funcs->hubp_get_underflow_status(hubp) != 0) { | 791 | if (hubp->funcs->hubp_get_underflow_status(hubp) != 0) { |
791 | /* one pipe underflow, we will reset all the pipes*/ | 792 | /* one pipe underflow, we will reset all the pipes*/ |
792 | need_recover = true; | 793 | need_recover = true; |
@@ -812,7 +813,7 @@ static bool dcn10_hw_wa_force_recovery(struct dc *dc) | |||
812 | if (pipe_ctx != NULL) { | 813 | if (pipe_ctx != NULL) { |
813 | hubp = pipe_ctx->plane_res.hubp; | 814 | hubp = pipe_ctx->plane_res.hubp; |
814 | /*DCHUBP_CNTL:HUBP_BLANK_EN=1*/ | 815 | /*DCHUBP_CNTL:HUBP_BLANK_EN=1*/ |
815 | if (hubp != NULL) | 816 | if (hubp != NULL && hubp->funcs->set_hubp_blank_en) |
816 | hubp->funcs->set_hubp_blank_en(hubp, true); | 817 | hubp->funcs->set_hubp_blank_en(hubp, true); |
817 | } | 818 | } |
818 | } | 819 | } |
@@ -825,7 +826,7 @@ static bool dcn10_hw_wa_force_recovery(struct dc *dc) | |||
825 | if (pipe_ctx != NULL) { | 826 | if (pipe_ctx != NULL) { |
826 | hubp = pipe_ctx->plane_res.hubp; | 827 | hubp = pipe_ctx->plane_res.hubp; |
827 | /*DCHUBP_CNTL:HUBP_DISABLE=1*/ | 828 | /*DCHUBP_CNTL:HUBP_DISABLE=1*/ |
828 | if (hubp != NULL) | 829 | if (hubp != NULL && hubp->funcs->hubp_disable_control) |
829 | hubp->funcs->hubp_disable_control(hubp, true); | 830 | hubp->funcs->hubp_disable_control(hubp, true); |
830 | } | 831 | } |
831 | } | 832 | } |
@@ -835,7 +836,7 @@ static bool dcn10_hw_wa_force_recovery(struct dc *dc) | |||
835 | if (pipe_ctx != NULL) { | 836 | if (pipe_ctx != NULL) { |
836 | hubp = pipe_ctx->plane_res.hubp; | 837 | hubp = pipe_ctx->plane_res.hubp; |
837 | /*DCHUBP_CNTL:HUBP_DISABLE=0*/ | 838 | /*DCHUBP_CNTL:HUBP_DISABLE=0*/ |
838 | if (hubp != NULL) | 839 | if (hubp != NULL && hubp->funcs->hubp_disable_control) |
839 | hubp->funcs->hubp_disable_control(hubp, true); | 840 | hubp->funcs->hubp_disable_control(hubp, true); |
840 | } | 841 | } |
841 | } | 842 | } |
@@ -847,7 +848,7 @@ static bool dcn10_hw_wa_force_recovery(struct dc *dc) | |||
847 | if (pipe_ctx != NULL) { | 848 | if (pipe_ctx != NULL) { |
848 | hubp = pipe_ctx->plane_res.hubp; | 849 | hubp = pipe_ctx->plane_res.hubp; |
849 | /*DCHUBP_CNTL:HUBP_BLANK_EN=0*/ | 850 | /*DCHUBP_CNTL:HUBP_BLANK_EN=0*/ |
850 | if (hubp != NULL) | 851 | if (hubp != NULL && hubp->funcs->set_hubp_blank_en) |
851 | hubp->funcs->set_hubp_blank_en(hubp, true); | 852 | hubp->funcs->set_hubp_blank_en(hubp, true); |
852 | } | 853 | } |
853 | } | 854 | } |
@@ -1126,7 +1127,7 @@ static void dcn10_init_hw(struct dc *dc) | |||
1126 | 1127 | ||
1127 | enable_power_gating_plane(dc->hwseq, true); | 1128 | enable_power_gating_plane(dc->hwseq, true); |
1128 | 1129 | ||
1129 | memset(&dc->res_pool->dccg->clks, 0, sizeof(dc->res_pool->dccg->clks)); | 1130 | memset(&dc->res_pool->clk_mgr->clks, 0, sizeof(dc->res_pool->clk_mgr->clks)); |
1130 | } | 1131 | } |
1131 | 1132 | ||
1132 | static void reset_hw_ctx_wrap( | 1133 | static void reset_hw_ctx_wrap( |
@@ -1603,7 +1604,7 @@ static void mmhub_read_vm_context0_settings(struct dcn10_hubp *hubp1, | |||
1603 | } | 1604 | } |
1604 | 1605 | ||
1605 | 1606 | ||
1606 | static void dcn10_program_pte_vm(struct dce_hwseq *hws, struct hubp *hubp) | 1607 | void dcn10_program_pte_vm(struct dce_hwseq *hws, struct hubp *hubp) |
1607 | { | 1608 | { |
1608 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); | 1609 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
1609 | struct vm_system_aperture_param apt = { {{ 0 } } }; | 1610 | struct vm_system_aperture_param apt = { {{ 0 } } }; |
@@ -1703,33 +1704,22 @@ static void program_gamut_remap(struct pipe_ctx *pipe_ctx) | |||
1703 | pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp, &adjust); | 1704 | pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp, &adjust); |
1704 | } | 1705 | } |
1705 | 1706 | ||
1706 | 1707 | static void dcn10_program_output_csc(struct dc *dc, | |
1707 | static void program_csc_matrix(struct pipe_ctx *pipe_ctx, | 1708 | struct pipe_ctx *pipe_ctx, |
1708 | enum dc_color_space colorspace, | 1709 | enum dc_color_space colorspace, |
1709 | uint16_t *matrix) | 1710 | uint16_t *matrix, |
1711 | int opp_id) | ||
1710 | { | 1712 | { |
1711 | if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) { | 1713 | if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) { |
1712 | if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment != NULL) | 1714 | if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment != NULL) |
1713 | pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix); | 1715 | pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix); |
1714 | } else { | 1716 | } else { |
1715 | if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default != NULL) | 1717 | if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default != NULL) |
1716 | pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default(pipe_ctx->plane_res.dpp, colorspace); | 1718 | pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default(pipe_ctx->plane_res.dpp, colorspace); |
1717 | } | 1719 | } |
1718 | } | 1720 | } |
1719 | 1721 | ||
1720 | static void dcn10_program_output_csc(struct dc *dc, | 1722 | bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx) |
1721 | struct pipe_ctx *pipe_ctx, | ||
1722 | enum dc_color_space colorspace, | ||
1723 | uint16_t *matrix, | ||
1724 | int opp_id) | ||
1725 | { | ||
1726 | if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment != NULL) | ||
1727 | program_csc_matrix(pipe_ctx, | ||
1728 | colorspace, | ||
1729 | matrix); | ||
1730 | } | ||
1731 | |||
1732 | static bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx) | ||
1733 | { | 1723 | { |
1734 | if (pipe_ctx->plane_state->visible) | 1724 | if (pipe_ctx->plane_state->visible) |
1735 | return true; | 1725 | return true; |
@@ -1738,7 +1728,7 @@ static bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx) | |||
1738 | return false; | 1728 | return false; |
1739 | } | 1729 | } |
1740 | 1730 | ||
1741 | static bool is_upper_pipe_tree_visible(struct pipe_ctx *pipe_ctx) | 1731 | bool is_upper_pipe_tree_visible(struct pipe_ctx *pipe_ctx) |
1742 | { | 1732 | { |
1743 | if (pipe_ctx->plane_state->visible) | 1733 | if (pipe_ctx->plane_state->visible) |
1744 | return true; | 1734 | return true; |
@@ -1747,7 +1737,7 @@ static bool is_upper_pipe_tree_visible(struct pipe_ctx *pipe_ctx) | |||
1747 | return false; | 1737 | return false; |
1748 | } | 1738 | } |
1749 | 1739 | ||
1750 | static bool is_pipe_tree_visible(struct pipe_ctx *pipe_ctx) | 1740 | bool is_pipe_tree_visible(struct pipe_ctx *pipe_ctx) |
1751 | { | 1741 | { |
1752 | if (pipe_ctx->plane_state->visible) | 1742 | if (pipe_ctx->plane_state->visible) |
1753 | return true; | 1743 | return true; |
@@ -1943,10 +1933,6 @@ static void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) | |||
1943 | struct mpc *mpc = dc->res_pool->mpc; | 1933 | struct mpc *mpc = dc->res_pool->mpc; |
1944 | struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params); | 1934 | struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params); |
1945 | 1935 | ||
1946 | |||
1947 | |||
1948 | /* TODO: proper fix once fpga works */ | ||
1949 | |||
1950 | if (dc->debug.visual_confirm == VISUAL_CONFIRM_HDR) { | 1936 | if (dc->debug.visual_confirm == VISUAL_CONFIRM_HDR) { |
1951 | dcn10_get_hdr_visual_confirm_color( | 1937 | dcn10_get_hdr_visual_confirm_color( |
1952 | pipe_ctx, &blnd_cfg.black_color); | 1938 | pipe_ctx, &blnd_cfg.black_color); |
@@ -2026,8 +2012,6 @@ static void update_scaler(struct pipe_ctx *pipe_ctx) | |||
2026 | bool per_pixel_alpha = | 2012 | bool per_pixel_alpha = |
2027 | pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe; | 2013 | pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe; |
2028 | 2014 | ||
2029 | /* TODO: proper fix once fpga works */ | ||
2030 | |||
2031 | pipe_ctx->plane_res.scl_data.lb_params.alpha_en = per_pixel_alpha; | 2015 | pipe_ctx->plane_res.scl_data.lb_params.alpha_en = per_pixel_alpha; |
2032 | pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP; | 2016 | pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP; |
2033 | /* scaler configuration */ | 2017 | /* scaler configuration */ |
@@ -2035,7 +2019,7 @@ static void update_scaler(struct pipe_ctx *pipe_ctx) | |||
2035 | pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data); | 2019 | pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data); |
2036 | } | 2020 | } |
2037 | 2021 | ||
2038 | static void update_dchubp_dpp( | 2022 | void update_dchubp_dpp( |
2039 | struct dc *dc, | 2023 | struct dc *dc, |
2040 | struct pipe_ctx *pipe_ctx, | 2024 | struct pipe_ctx *pipe_ctx, |
2041 | struct dc_state *context) | 2025 | struct dc_state *context) |
@@ -2052,16 +2036,22 @@ static void update_dchubp_dpp( | |||
2052 | */ | 2036 | */ |
2053 | if (plane_state->update_flags.bits.full_update) { | 2037 | if (plane_state->update_flags.bits.full_update) { |
2054 | bool should_divided_by_2 = context->bw.dcn.clk.dppclk_khz <= | 2038 | bool should_divided_by_2 = context->bw.dcn.clk.dppclk_khz <= |
2055 | dc->res_pool->dccg->clks.dispclk_khz / 2; | 2039 | dc->res_pool->clk_mgr->clks.dispclk_khz / 2; |
2056 | 2040 | ||
2057 | dpp->funcs->dpp_dppclk_control( | 2041 | dpp->funcs->dpp_dppclk_control( |
2058 | dpp, | 2042 | dpp, |
2059 | should_divided_by_2, | 2043 | should_divided_by_2, |
2060 | true); | 2044 | true); |
2061 | 2045 | ||
2062 | dc->res_pool->dccg->clks.dppclk_khz = should_divided_by_2 ? | 2046 | if (dc->res_pool->dccg) |
2063 | dc->res_pool->dccg->clks.dispclk_khz / 2 : | 2047 | dc->res_pool->dccg->funcs->update_dpp_dto( |
2064 | dc->res_pool->dccg->clks.dispclk_khz; | 2048 | dc->res_pool->dccg, |
2049 | dpp->inst, | ||
2050 | pipe_ctx->plane_res.bw.calc.dppclk_khz); | ||
2051 | else | ||
2052 | dc->res_pool->clk_mgr->clks.dppclk_khz = should_divided_by_2 ? | ||
2053 | dc->res_pool->clk_mgr->clks.dispclk_khz / 2 : | ||
2054 | dc->res_pool->clk_mgr->clks.dispclk_khz; | ||
2065 | } | 2055 | } |
2066 | 2056 | ||
2067 | /* TODO: Need input parameter to tell current DCHUB pipe tie to which OTG | 2057 | /* TODO: Need input parameter to tell current DCHUB pipe tie to which OTG |
@@ -2182,7 +2172,7 @@ static void dcn10_blank_pixel_data( | |||
2182 | } | 2172 | } |
2183 | } | 2173 | } |
2184 | 2174 | ||
2185 | static void set_hdr_multiplier(struct pipe_ctx *pipe_ctx) | 2175 | void set_hdr_multiplier(struct pipe_ctx *pipe_ctx) |
2186 | { | 2176 | { |
2187 | struct fixed31_32 multiplier = dc_fixpt_from_fraction( | 2177 | struct fixed31_32 multiplier = dc_fixpt_from_fraction( |
2188 | pipe_ctx->plane_state->sdr_white_level, 80); | 2178 | pipe_ctx->plane_state->sdr_white_level, 80); |
@@ -2257,47 +2247,7 @@ static void program_all_pipe_in_tree( | |||
2257 | } | 2247 | } |
2258 | } | 2248 | } |
2259 | 2249 | ||
2260 | static void dcn10_pplib_apply_display_requirements( | 2250 | struct pipe_ctx *find_top_pipe_for_stream( |
2261 | struct dc *dc, | ||
2262 | struct dc_state *context) | ||
2263 | { | ||
2264 | struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; | ||
2265 | |||
2266 | pp_display_cfg->min_engine_clock_khz = dc->res_pool->dccg->clks.dcfclk_khz; | ||
2267 | pp_display_cfg->min_memory_clock_khz = dc->res_pool->dccg->clks.fclk_khz; | ||
2268 | pp_display_cfg->min_engine_clock_deep_sleep_khz = dc->res_pool->dccg->clks.dcfclk_deep_sleep_khz; | ||
2269 | pp_display_cfg->min_dcfc_deep_sleep_clock_khz = dc->res_pool->dccg->clks.dcfclk_deep_sleep_khz; | ||
2270 | pp_display_cfg->min_dcfclock_khz = dc->res_pool->dccg->clks.dcfclk_khz; | ||
2271 | pp_display_cfg->disp_clk_khz = dc->res_pool->dccg->clks.dispclk_khz; | ||
2272 | dce110_fill_display_configs(context, pp_display_cfg); | ||
2273 | |||
2274 | if (memcmp(&dc->prev_display_config, pp_display_cfg, sizeof( | ||
2275 | struct dm_pp_display_configuration)) != 0) | ||
2276 | dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); | ||
2277 | |||
2278 | dc->prev_display_config = *pp_display_cfg; | ||
2279 | } | ||
2280 | |||
2281 | static void optimize_shared_resources(struct dc *dc) | ||
2282 | { | ||
2283 | if (dc->current_state->stream_count == 0) { | ||
2284 | /* S0i2 message */ | ||
2285 | dcn10_pplib_apply_display_requirements(dc, dc->current_state); | ||
2286 | } | ||
2287 | |||
2288 | if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) | ||
2289 | dcn_bw_notify_pplib_of_wm_ranges(dc); | ||
2290 | } | ||
2291 | |||
2292 | static void ready_shared_resources(struct dc *dc, struct dc_state *context) | ||
2293 | { | ||
2294 | /* S0i2 message */ | ||
2295 | if (dc->current_state->stream_count == 0 && | ||
2296 | context->stream_count != 0) | ||
2297 | dcn10_pplib_apply_display_requirements(dc, context); | ||
2298 | } | ||
2299 | |||
2300 | static struct pipe_ctx *find_top_pipe_for_stream( | ||
2301 | struct dc *dc, | 2251 | struct dc *dc, |
2302 | struct dc_state *context, | 2252 | struct dc_state *context, |
2303 | const struct dc_stream_state *stream) | 2253 | const struct dc_stream_state *stream) |
@@ -2398,10 +2348,9 @@ static void dcn10_apply_ctx_for_surface( | |||
2398 | hubbub1_wm_change_req_wa(dc->res_pool->hubbub); | 2348 | hubbub1_wm_change_req_wa(dc->res_pool->hubbub); |
2399 | } | 2349 | } |
2400 | 2350 | ||
2401 | static void dcn10_set_bandwidth( | 2351 | static void dcn10_prepare_bandwidth( |
2402 | struct dc *dc, | 2352 | struct dc *dc, |
2403 | struct dc_state *context, | 2353 | struct dc_state *context) |
2404 | bool safe_to_lower) | ||
2405 | { | 2354 | { |
2406 | if (dc->debug.sanity_checks) | 2355 | if (dc->debug.sanity_checks) |
2407 | dcn10_verify_allow_pstate_change_high(dc); | 2356 | dcn10_verify_allow_pstate_change_high(dc); |
@@ -2410,12 +2359,39 @@ static void dcn10_set_bandwidth( | |||
2410 | if (context->stream_count == 0) | 2359 | if (context->stream_count == 0) |
2411 | context->bw.dcn.clk.phyclk_khz = 0; | 2360 | context->bw.dcn.clk.phyclk_khz = 0; |
2412 | 2361 | ||
2413 | dc->res_pool->dccg->funcs->update_clocks( | 2362 | dc->res_pool->clk_mgr->funcs->update_clocks( |
2414 | dc->res_pool->dccg, | 2363 | dc->res_pool->clk_mgr, |
2415 | &context->bw.dcn.clk, | 2364 | context, |
2416 | safe_to_lower); | 2365 | false); |
2366 | } | ||
2417 | 2367 | ||
2418 | dcn10_pplib_apply_display_requirements(dc, context); | 2368 | hubbub1_program_watermarks(dc->res_pool->hubbub, |
2369 | &context->bw.dcn.watermarks, | ||
2370 | dc->res_pool->ref_clock_inKhz / 1000, | ||
2371 | true); | ||
2372 | |||
2373 | if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) | ||
2374 | dcn_bw_notify_pplib_of_wm_ranges(dc); | ||
2375 | |||
2376 | if (dc->debug.sanity_checks) | ||
2377 | dcn10_verify_allow_pstate_change_high(dc); | ||
2378 | } | ||
2379 | |||
2380 | static void dcn10_optimize_bandwidth( | ||
2381 | struct dc *dc, | ||
2382 | struct dc_state *context) | ||
2383 | { | ||
2384 | if (dc->debug.sanity_checks) | ||
2385 | dcn10_verify_allow_pstate_change_high(dc); | ||
2386 | |||
2387 | if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { | ||
2388 | if (context->stream_count == 0) | ||
2389 | context->bw.dcn.clk.phyclk_khz = 0; | ||
2390 | |||
2391 | dc->res_pool->clk_mgr->funcs->update_clocks( | ||
2392 | dc->res_pool->clk_mgr, | ||
2393 | context, | ||
2394 | true); | ||
2419 | } | 2395 | } |
2420 | 2396 | ||
2421 | hubbub1_program_watermarks(dc->res_pool->hubbub, | 2397 | hubbub1_program_watermarks(dc->res_pool->hubbub, |
@@ -2423,6 +2399,9 @@ static void dcn10_set_bandwidth( | |||
2423 | dc->res_pool->ref_clock_inKhz / 1000, | 2399 | dc->res_pool->ref_clock_inKhz / 1000, |
2424 | true); | 2400 | true); |
2425 | 2401 | ||
2402 | if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) | ||
2403 | dcn_bw_notify_pplib_of_wm_ranges(dc); | ||
2404 | |||
2426 | if (dc->debug.sanity_checks) | 2405 | if (dc->debug.sanity_checks) |
2427 | dcn10_verify_allow_pstate_change_high(dc); | 2406 | dcn10_verify_allow_pstate_change_high(dc); |
2428 | } | 2407 | } |
@@ -2694,7 +2673,6 @@ static void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx) | |||
2694 | 2673 | ||
2695 | static const struct hw_sequencer_funcs dcn10_funcs = { | 2674 | static const struct hw_sequencer_funcs dcn10_funcs = { |
2696 | .program_gamut_remap = program_gamut_remap, | 2675 | .program_gamut_remap = program_gamut_remap, |
2697 | .program_csc_matrix = program_csc_matrix, | ||
2698 | .init_hw = dcn10_init_hw, | 2676 | .init_hw = dcn10_init_hw, |
2699 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, | 2677 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, |
2700 | .apply_ctx_for_surface = dcn10_apply_ctx_for_surface, | 2678 | .apply_ctx_for_surface = dcn10_apply_ctx_for_surface, |
@@ -2721,7 +2699,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = { | |||
2721 | .disable_plane = dcn10_disable_plane, | 2699 | .disable_plane = dcn10_disable_plane, |
2722 | .blank_pixel_data = dcn10_blank_pixel_data, | 2700 | .blank_pixel_data = dcn10_blank_pixel_data, |
2723 | .pipe_control_lock = dcn10_pipe_control_lock, | 2701 | .pipe_control_lock = dcn10_pipe_control_lock, |
2724 | .set_bandwidth = dcn10_set_bandwidth, | 2702 | .prepare_bandwidth = dcn10_prepare_bandwidth, |
2703 | .optimize_bandwidth = dcn10_optimize_bandwidth, | ||
2725 | .reset_hw_ctx_wrap = reset_hw_ctx_wrap, | 2704 | .reset_hw_ctx_wrap = reset_hw_ctx_wrap, |
2726 | .enable_stream_timing = dcn10_enable_stream_timing, | 2705 | .enable_stream_timing = dcn10_enable_stream_timing, |
2727 | .set_drr = set_drr, | 2706 | .set_drr = set_drr, |
@@ -2732,10 +2711,6 @@ static const struct hw_sequencer_funcs dcn10_funcs = { | |||
2732 | .log_hw_state = dcn10_log_hw_state, | 2711 | .log_hw_state = dcn10_log_hw_state, |
2733 | .get_hw_state = dcn10_get_hw_state, | 2712 | .get_hw_state = dcn10_get_hw_state, |
2734 | .wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect, | 2713 | .wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect, |
2735 | .ready_shared_resources = ready_shared_resources, | ||
2736 | .optimize_shared_resources = optimize_shared_resources, | ||
2737 | .pplib_apply_display_requirements = | ||
2738 | dcn10_pplib_apply_display_requirements, | ||
2739 | .edp_backlight_control = hwss_edp_backlight_control, | 2714 | .edp_backlight_control = hwss_edp_backlight_control, |
2740 | .edp_power_control = hwss_edp_power_control, | 2715 | .edp_power_control = hwss_edp_power_control, |
2741 | .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, | 2716 | .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h index 84d461e0ed3e..5e5610c9e600 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h | |||
@@ -51,4 +51,24 @@ void dcn10_get_hw_state( | |||
51 | char *pBuf, unsigned int bufSize, | 51 | char *pBuf, unsigned int bufSize, |
52 | unsigned int mask); | 52 | unsigned int mask); |
53 | 53 | ||
54 | bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx); | ||
55 | |||
56 | bool is_upper_pipe_tree_visible(struct pipe_ctx *pipe_ctx); | ||
57 | |||
58 | bool is_pipe_tree_visible(struct pipe_ctx *pipe_ctx); | ||
59 | |||
60 | void dcn10_program_pte_vm(struct dce_hwseq *hws, struct hubp *hubp); | ||
61 | |||
62 | void set_hdr_multiplier(struct pipe_ctx *pipe_ctx); | ||
63 | |||
64 | void update_dchubp_dpp( | ||
65 | struct dc *dc, | ||
66 | struct pipe_ctx *pipe_ctx, | ||
67 | struct dc_state *context); | ||
68 | |||
69 | struct pipe_ctx *find_top_pipe_for_stream( | ||
70 | struct dc *dc, | ||
71 | struct dc_state *context, | ||
72 | const struct dc_stream_state *stream); | ||
73 | |||
54 | #endif /* __DC_HWSS_DCN10_H__ */ | 74 | #endif /* __DC_HWSS_DCN10_H__ */ |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c index ba6a8686062f..477ab9222216 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c | |||
@@ -589,7 +589,7 @@ static bool dcn10_link_encoder_validate_hdmi_output( | |||
589 | return false; | 589 | return false; |
590 | 590 | ||
591 | /* DCE11 HW does not support 420 */ | 591 | /* DCE11 HW does not support 420 */ |
592 | if (!enc10->base.features.ycbcr420_supported && | 592 | if (!enc10->base.features.hdmi_ycbcr420_supported && |
593 | crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) | 593 | crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) |
594 | return false; | 594 | return false; |
595 | 595 | ||
@@ -606,8 +606,10 @@ bool dcn10_link_encoder_validate_dp_output( | |||
606 | const struct dcn10_link_encoder *enc10, | 606 | const struct dcn10_link_encoder *enc10, |
607 | const struct dc_crtc_timing *crtc_timing) | 607 | const struct dc_crtc_timing *crtc_timing) |
608 | { | 608 | { |
609 | if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) | 609 | if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) { |
610 | return false; | 610 | if (!enc10->base.features.dp_ycbcr420_supported) |
611 | return false; | ||
612 | } | ||
611 | 613 | ||
612 | return true; | 614 | return true; |
613 | } | 615 | } |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c index 54626682bab2..7d1f66797cb3 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c | |||
@@ -87,9 +87,8 @@ static void optc1_disable_stereo(struct timing_generator *optc) | |||
87 | REG_SET(OTG_STEREO_CONTROL, 0, | 87 | REG_SET(OTG_STEREO_CONTROL, 0, |
88 | OTG_STEREO_EN, 0); | 88 | OTG_STEREO_EN, 0); |
89 | 89 | ||
90 | REG_SET_3(OTG_3D_STRUCTURE_CONTROL, 0, | 90 | REG_SET_2(OTG_3D_STRUCTURE_CONTROL, 0, |
91 | OTG_3D_STRUCTURE_EN, 0, | 91 | OTG_3D_STRUCTURE_EN, 0, |
92 | OTG_3D_STRUCTURE_V_UPDATE_MODE, 0, | ||
93 | OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0); | 92 | OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0); |
94 | } | 93 | } |
95 | 94 | ||
@@ -274,10 +273,12 @@ void optc1_program_timing( | |||
274 | * program the reg for interrupt postition. | 273 | * program the reg for interrupt postition. |
275 | */ | 274 | */ |
276 | vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1; | 275 | vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1; |
277 | if (vertical_line_start < 0) { | 276 | v_fp2 = 0; |
278 | ASSERT(0); | 277 | if (vertical_line_start < 0) |
278 | v_fp2 = -vertical_line_start; | ||
279 | if (vertical_line_start < 0) | ||
279 | vertical_line_start = 0; | 280 | vertical_line_start = 0; |
280 | } | 281 | |
281 | REG_SET(OTG_VERTICAL_INTERRUPT2_POSITION, 0, | 282 | REG_SET(OTG_VERTICAL_INTERRUPT2_POSITION, 0, |
282 | OTG_VERTICAL_INTERRUPT2_LINE_START, vertical_line_start); | 283 | OTG_VERTICAL_INTERRUPT2_LINE_START, vertical_line_start); |
283 | 284 | ||
@@ -296,9 +297,6 @@ void optc1_program_timing( | |||
296 | if (patched_crtc_timing.flags.INTERLACE == 1) | 297 | if (patched_crtc_timing.flags.INTERLACE == 1) |
297 | field_num = 1; | 298 | field_num = 1; |
298 | } | 299 | } |
299 | v_fp2 = 0; | ||
300 | if (optc->dlg_otg_param.vstartup_start > asic_blank_end) | ||
301 | v_fp2 = optc->dlg_otg_param.vstartup_start > asic_blank_end; | ||
302 | 300 | ||
303 | /* Interlace */ | 301 | /* Interlace */ |
304 | if (patched_crtc_timing.flags.INTERLACE == 1) { | 302 | if (patched_crtc_timing.flags.INTERLACE == 1) { |
@@ -1155,9 +1153,8 @@ static void optc1_enable_stereo(struct timing_generator *optc, | |||
1155 | OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, 1); | 1153 | OTG_DISABLE_STEREOSYNC_OUTPUT_FOR_DP, 1); |
1156 | 1154 | ||
1157 | if (flags->PROGRAM_STEREO) | 1155 | if (flags->PROGRAM_STEREO) |
1158 | REG_UPDATE_3(OTG_3D_STRUCTURE_CONTROL, | 1156 | REG_UPDATE_2(OTG_3D_STRUCTURE_CONTROL, |
1159 | OTG_3D_STRUCTURE_EN, flags->FRAME_PACKED, | 1157 | OTG_3D_STRUCTURE_EN, flags->FRAME_PACKED, |
1160 | OTG_3D_STRUCTURE_V_UPDATE_MODE, flags->FRAME_PACKED, | ||
1161 | OTG_3D_STRUCTURE_STEREO_SEL_OVR, flags->FRAME_PACKED); | 1158 | OTG_3D_STRUCTURE_STEREO_SEL_OVR, flags->FRAME_PACKED); |
1162 | 1159 | ||
1163 | } | 1160 | } |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index a71453a15ae3..47dbe4bb294a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | |||
@@ -28,23 +28,23 @@ | |||
28 | 28 | ||
29 | #include "resource.h" | 29 | #include "resource.h" |
30 | #include "include/irq_service_interface.h" | 30 | #include "include/irq_service_interface.h" |
31 | #include "dcn10/dcn10_resource.h" | 31 | #include "dcn10_resource.h" |
32 | 32 | ||
33 | #include "dcn10/dcn10_ipp.h" | 33 | #include "dcn10_ipp.h" |
34 | #include "dcn10/dcn10_mpc.h" | 34 | #include "dcn10_mpc.h" |
35 | #include "irq/dcn10/irq_service_dcn10.h" | 35 | #include "irq/dcn10/irq_service_dcn10.h" |
36 | #include "dcn10/dcn10_dpp.h" | 36 | #include "dcn10_dpp.h" |
37 | #include "dcn10_optc.h" | 37 | #include "dcn10_optc.h" |
38 | #include "dcn10/dcn10_hw_sequencer.h" | 38 | #include "dcn10_hw_sequencer.h" |
39 | #include "dce110/dce110_hw_sequencer.h" | 39 | #include "dce110/dce110_hw_sequencer.h" |
40 | #include "dcn10/dcn10_opp.h" | 40 | #include "dcn10_opp.h" |
41 | #include "dcn10/dcn10_link_encoder.h" | 41 | #include "dcn10_link_encoder.h" |
42 | #include "dcn10/dcn10_stream_encoder.h" | 42 | #include "dcn10_stream_encoder.h" |
43 | #include "dce/dce_clocks.h" | 43 | #include "dcn10_clk_mgr.h" |
44 | #include "dce/dce_clock_source.h" | 44 | #include "dce/dce_clock_source.h" |
45 | #include "dce/dce_audio.h" | 45 | #include "dce/dce_audio.h" |
46 | #include "dce/dce_hwseq.h" | 46 | #include "dce/dce_hwseq.h" |
47 | #include "../virtual/virtual_stream_encoder.h" | 47 | #include "virtual/virtual_stream_encoder.h" |
48 | #include "dce110/dce110_resource.h" | 48 | #include "dce110/dce110_resource.h" |
49 | #include "dce112/dce112_resource.h" | 49 | #include "dce112/dce112_resource.h" |
50 | #include "dcn10_hubp.h" | 50 | #include "dcn10_hubp.h" |
@@ -438,6 +438,7 @@ static const struct dcn_optc_mask tg_mask = { | |||
438 | 438 | ||
439 | 439 | ||
440 | static const struct bios_registers bios_regs = { | 440 | static const struct bios_registers bios_regs = { |
441 | NBIO_SR(BIOS_SCRATCH_0), | ||
441 | NBIO_SR(BIOS_SCRATCH_3), | 442 | NBIO_SR(BIOS_SCRATCH_3), |
442 | NBIO_SR(BIOS_SCRATCH_6) | 443 | NBIO_SR(BIOS_SCRATCH_6) |
443 | }; | 444 | }; |
@@ -719,7 +720,8 @@ static struct timing_generator *dcn10_timing_generator_create( | |||
719 | static const struct encoder_feature_support link_enc_feature = { | 720 | static const struct encoder_feature_support link_enc_feature = { |
720 | .max_hdmi_deep_color = COLOR_DEPTH_121212, | 721 | .max_hdmi_deep_color = COLOR_DEPTH_121212, |
721 | .max_hdmi_pixel_clock = 600000, | 722 | .max_hdmi_pixel_clock = 600000, |
722 | .ycbcr420_supported = true, | 723 | .hdmi_ycbcr420_supported = true, |
724 | .dp_ycbcr420_supported = false, | ||
723 | .flags.bits.IS_HBR2_CAPABLE = true, | 725 | .flags.bits.IS_HBR2_CAPABLE = true, |
724 | .flags.bits.IS_HBR3_CAPABLE = true, | 726 | .flags.bits.IS_HBR3_CAPABLE = true, |
725 | .flags.bits.IS_TPS3_CAPABLE = true, | 727 | .flags.bits.IS_TPS3_CAPABLE = true, |
@@ -949,8 +951,8 @@ static void destruct(struct dcn10_resource_pool *pool) | |||
949 | if (pool->base.dmcu != NULL) | 951 | if (pool->base.dmcu != NULL) |
950 | dce_dmcu_destroy(&pool->base.dmcu); | 952 | dce_dmcu_destroy(&pool->base.dmcu); |
951 | 953 | ||
952 | if (pool->base.dccg != NULL) | 954 | if (pool->base.clk_mgr != NULL) |
953 | dce_dccg_destroy(&pool->base.dccg); | 955 | dce_clk_mgr_destroy(&pool->base.clk_mgr); |
954 | 956 | ||
955 | kfree(pool->base.pp_smu); | 957 | kfree(pool->base.pp_smu); |
956 | } | 958 | } |
@@ -1276,8 +1278,8 @@ static bool construct( | |||
1276 | } | 1278 | } |
1277 | } | 1279 | } |
1278 | 1280 | ||
1279 | pool->base.dccg = dcn1_dccg_create(ctx); | 1281 | pool->base.clk_mgr = dcn1_clk_mgr_create(ctx); |
1280 | if (pool->base.dccg == NULL) { | 1282 | if (pool->base.clk_mgr == NULL) { |
1281 | dm_error("DC: failed to create display clock!\n"); | 1283 | dm_error("DC: failed to create display clock!\n"); |
1282 | BREAK_TO_DEBUGGER(); | 1284 | BREAK_TO_DEBUGGER(); |
1283 | goto fail; | 1285 | goto fail; |
diff --git a/drivers/gpu/drm/amd/display/dc/dm_pp_smu.h b/drivers/gpu/drm/amd/display/dc/dm_pp_smu.h index f2ea8452d48f..beb08fd12b1d 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_pp_smu.h +++ b/drivers/gpu/drm/amd/display/dc/dm_pp_smu.h | |||
@@ -55,10 +55,10 @@ struct pp_smu { | |||
55 | 55 | ||
56 | struct pp_smu_wm_set_range { | 56 | struct pp_smu_wm_set_range { |
57 | unsigned int wm_inst; | 57 | unsigned int wm_inst; |
58 | uint32_t min_fill_clk_khz; | 58 | uint32_t min_fill_clk_mhz; |
59 | uint32_t max_fill_clk_khz; | 59 | uint32_t max_fill_clk_mhz; |
60 | uint32_t min_drain_clk_khz; | 60 | uint32_t min_drain_clk_mhz; |
61 | uint32_t max_drain_clk_khz; | 61 | uint32_t max_drain_clk_mhz; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | #define MAX_WATERMARK_SETS 4 | 64 | #define MAX_WATERMARK_SETS 4 |
@@ -77,15 +77,15 @@ struct pp_smu_display_requirement_rv { | |||
77 | */ | 77 | */ |
78 | unsigned int display_count; | 78 | unsigned int display_count; |
79 | 79 | ||
80 | /* PPSMC_MSG_SetHardMinFclkByFreq: khz | 80 | /* PPSMC_MSG_SetHardMinFclkByFreq: mhz |
81 | * FCLK will vary with DPM, but never below requested hard min | 81 | * FCLK will vary with DPM, but never below requested hard min |
82 | */ | 82 | */ |
83 | unsigned int hard_min_fclk_khz; | 83 | unsigned int hard_min_fclk_mhz; |
84 | 84 | ||
85 | /* PPSMC_MSG_SetHardMinDcefclkByFreq: khz | 85 | /* PPSMC_MSG_SetHardMinDcefclkByFreq: mhz |
86 | * fixed clock at requested freq, either from FCH bypass or DFS | 86 | * fixed clock at requested freq, either from FCH bypass or DFS |
87 | */ | 87 | */ |
88 | unsigned int hard_min_dcefclk_khz; | 88 | unsigned int hard_min_dcefclk_mhz; |
89 | 89 | ||
90 | /* PPSMC_MSG_SetMinDeepSleepDcefclk: mhz | 90 | /* PPSMC_MSG_SetMinDeepSleepDcefclk: mhz |
91 | * when DF is in cstate, dcf clock is further divided down | 91 | * when DF is in cstate, dcf clock is further divided down |
@@ -103,13 +103,19 @@ struct pp_smu_funcs_rv { | |||
103 | void (*set_display_count)(struct pp_smu *pp, int count); | 103 | void (*set_display_count)(struct pp_smu *pp, int count); |
104 | 104 | ||
105 | /* which SMU message? are reader and writer WM separate SMU msg? */ | 105 | /* which SMU message? are reader and writer WM separate SMU msg? */ |
106 | /* | ||
107 | * PPSMC_MSG_SetDriverDramAddrHigh | ||
108 | * PPSMC_MSG_SetDriverDramAddrLow | ||
109 | * PPSMC_MSG_TransferTableDram2Smu | ||
110 | * | ||
111 | * */ | ||
106 | void (*set_wm_ranges)(struct pp_smu *pp, | 112 | void (*set_wm_ranges)(struct pp_smu *pp, |
107 | struct pp_smu_wm_range_sets *ranges); | 113 | struct pp_smu_wm_range_sets *ranges); |
108 | 114 | ||
109 | /* PPSMC_MSG_SetHardMinDcfclkByFreq | 115 | /* PPSMC_MSG_SetHardMinDcfclkByFreq |
110 | * fixed clock at requested freq, either from FCH bypass or DFS | 116 | * fixed clock at requested freq, either from FCH bypass or DFS |
111 | */ | 117 | */ |
112 | void (*set_hard_min_dcfclk_by_freq)(struct pp_smu *pp, int khz); | 118 | void (*set_hard_min_dcfclk_by_freq)(struct pp_smu *pp, int mhz); |
113 | 119 | ||
114 | /* PPSMC_MSG_SetMinDeepSleepDcfclk | 120 | /* PPSMC_MSG_SetMinDeepSleepDcfclk |
115 | * when DF is in cstate, dcf clock is further divided down | 121 | * when DF is in cstate, dcf clock is further divided down |
@@ -120,12 +126,12 @@ struct pp_smu_funcs_rv { | |||
120 | /* PPSMC_MSG_SetHardMinFclkByFreq | 126 | /* PPSMC_MSG_SetHardMinFclkByFreq |
121 | * FCLK will vary with DPM, but never below requested hard min | 127 | * FCLK will vary with DPM, but never below requested hard min |
122 | */ | 128 | */ |
123 | void (*set_hard_min_fclk_by_freq)(struct pp_smu *pp, int khz); | 129 | void (*set_hard_min_fclk_by_freq)(struct pp_smu *pp, int mhz); |
124 | 130 | ||
125 | /* PPSMC_MSG_SetHardMinSocclkByFreq | 131 | /* PPSMC_MSG_SetHardMinSocclkByFreq |
126 | * Needed for DWB support | 132 | * Needed for DWB support |
127 | */ | 133 | */ |
128 | void (*set_hard_min_socclk_by_freq)(struct pp_smu *pp, int khz); | 134 | void (*set_hard_min_socclk_by_freq)(struct pp_smu *pp, int mhz); |
129 | 135 | ||
130 | /* PME w/a */ | 136 | /* PME w/a */ |
131 | void (*set_pme_wa_enable)(struct pp_smu *pp); | 137 | void (*set_pme_wa_enable)(struct pp_smu *pp); |
diff --git a/drivers/gpu/drm/amd/display/dc/dm_services_types.h b/drivers/gpu/drm/amd/display/dc/dm_services_types.h index 2b83f922ac02..1af8c777b3ac 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_services_types.h +++ b/drivers/gpu/drm/amd/display/dc/dm_services_types.h | |||
@@ -208,22 +208,20 @@ struct dm_bl_data_point { | |||
208 | /* Brightness level as effective value in range 0-255, | 208 | /* Brightness level as effective value in range 0-255, |
209 | * corresponding to above percentage | 209 | * corresponding to above percentage |
210 | */ | 210 | */ |
211 | uint8_t signalLevel; | 211 | uint8_t signal_level; |
212 | }; | 212 | }; |
213 | 213 | ||
214 | /* Total size of the structure should not exceed 256 bytes */ | 214 | /* Total size of the structure should not exceed 256 bytes */ |
215 | struct dm_acpi_atif_backlight_caps { | 215 | struct dm_acpi_atif_backlight_caps { |
216 | |||
217 | |||
218 | uint16_t size; /* Bytes 0-1 (2 bytes) */ | 216 | uint16_t size; /* Bytes 0-1 (2 bytes) */ |
219 | uint16_t flags; /* Byted 2-3 (2 bytes) */ | 217 | uint16_t flags; /* Byted 2-3 (2 bytes) */ |
220 | uint8_t errorCode; /* Byte 4 */ | 218 | uint8_t error_code; /* Byte 4 */ |
221 | uint8_t acLevelPercentage; /* Byte 5 */ | 219 | uint8_t ac_level_percentage; /* Byte 5 */ |
222 | uint8_t dcLevelPercentage; /* Byte 6 */ | 220 | uint8_t dc_level_percentage; /* Byte 6 */ |
223 | uint8_t minInputSignal; /* Byte 7 */ | 221 | uint8_t min_input_signal; /* Byte 7 */ |
224 | uint8_t maxInputSignal; /* Byte 8 */ | 222 | uint8_t max_input_signal; /* Byte 8 */ |
225 | uint8_t numOfDataPoints; /* Byte 9 */ | 223 | uint8_t num_data_points; /* Byte 9 */ |
226 | struct dm_bl_data_point dataPoints[99]; /* Bytes 10-207 (198 bytes)*/ | 224 | struct dm_bl_data_point data_points[99]; /* Bytes 10-207 (198 bytes)*/ |
227 | }; | 225 | }; |
228 | 226 | ||
229 | enum dm_acpi_display_type { | 227 | enum dm_acpi_display_type { |
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h index cbafce649e33..5dd04520ceca 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h | |||
@@ -113,7 +113,8 @@ struct _vcs_dpi_soc_bounding_box_st { | |||
113 | int use_urgent_burst_bw; | 113 | int use_urgent_burst_bw; |
114 | double max_hscl_ratio; | 114 | double max_hscl_ratio; |
115 | double max_vscl_ratio; | 115 | double max_vscl_ratio; |
116 | struct _vcs_dpi_voltage_scaling_st clock_limits[7]; | 116 | unsigned int num_states; |
117 | struct _vcs_dpi_voltage_scaling_st clock_limits[8]; | ||
117 | }; | 118 | }; |
118 | 119 | ||
119 | struct _vcs_dpi_ip_params_st { | 120 | struct _vcs_dpi_ip_params_st { |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/bw_fixed.h b/drivers/gpu/drm/amd/display/dc/inc/bw_fixed.h index 39ee8eba3c31..d1656c9d50df 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/bw_fixed.h +++ b/drivers/gpu/drm/amd/display/dc/inc/bw_fixed.h | |||
@@ -126,7 +126,7 @@ static inline struct bw_fixed bw_div(const struct bw_fixed arg1, const struct bw | |||
126 | static inline struct bw_fixed bw_mod(const struct bw_fixed arg1, const struct bw_fixed arg2) | 126 | static inline struct bw_fixed bw_mod(const struct bw_fixed arg1, const struct bw_fixed arg2) |
127 | { | 127 | { |
128 | struct bw_fixed res; | 128 | struct bw_fixed res; |
129 | div64_u64_rem(arg1.value, arg2.value, &res.value); | 129 | div64_u64_rem(arg1.value, arg2.value, (uint64_t *)&res.value); |
130 | return res; | 130 | return res; |
131 | } | 131 | } |
132 | 132 | ||
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index c1976c175b57..e3ee96afa60e 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h | |||
@@ -82,7 +82,7 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option); | |||
82 | 82 | ||
83 | void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable); | 83 | void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable); |
84 | /********** DAL Core*********************/ | 84 | /********** DAL Core*********************/ |
85 | #include "display_clock.h" | 85 | #include "hw/clk_mgr.h" |
86 | #include "transform.h" | 86 | #include "transform.h" |
87 | #include "dpp.h" | 87 | #include "dpp.h" |
88 | 88 | ||
@@ -169,6 +169,7 @@ struct resource_pool { | |||
169 | unsigned int audio_count; | 169 | unsigned int audio_count; |
170 | struct audio_support audio_support; | 170 | struct audio_support audio_support; |
171 | 171 | ||
172 | struct clk_mgr *clk_mgr; | ||
172 | struct dccg *dccg; | 173 | struct dccg *dccg; |
173 | struct irq_service *irqs; | 174 | struct irq_service *irqs; |
174 | 175 | ||
@@ -287,7 +288,7 @@ struct dc_state { | |||
287 | struct dcn_bw_internal_vars dcn_bw_vars; | 288 | struct dcn_bw_internal_vars dcn_bw_vars; |
288 | #endif | 289 | #endif |
289 | 290 | ||
290 | struct dccg *dis_clk; | 291 | struct clk_mgr *dccg; |
291 | 292 | ||
292 | struct kref refcount; | 293 | struct kref refcount; |
293 | }; | 294 | }; |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h index e688eb9b975c..ece954a40a8e 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h | |||
@@ -31,8 +31,8 @@ | |||
31 | #define __DCN_CALCS_H__ | 31 | #define __DCN_CALCS_H__ |
32 | 32 | ||
33 | #include "bw_fixed.h" | 33 | #include "bw_fixed.h" |
34 | #include "display_clock.h" | ||
35 | #include "../dml/display_mode_lib.h" | 34 | #include "../dml/display_mode_lib.h" |
35 | #include "hw/clk_mgr.h" | ||
36 | 36 | ||
37 | struct dc; | 37 | struct dc; |
38 | struct dc_state; | 38 | struct dc_state; |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h index a83a48494613..abc961c0906e 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h | |||
@@ -47,12 +47,18 @@ struct abm_funcs { | |||
47 | bool (*set_abm_level)(struct abm *abm, unsigned int abm_level); | 47 | bool (*set_abm_level)(struct abm *abm, unsigned int abm_level); |
48 | bool (*set_abm_immediate_disable)(struct abm *abm); | 48 | bool (*set_abm_immediate_disable)(struct abm *abm); |
49 | bool (*init_backlight)(struct abm *abm); | 49 | bool (*init_backlight)(struct abm *abm); |
50 | bool (*set_backlight_level)(struct abm *abm, | 50 | |
51 | unsigned int backlight_level, | 51 | /* backlight_pwm_u16_16 is unsigned 32 bit, |
52 | * 16 bit integer + 16 fractional, where 1.0 is max backlight value. | ||
53 | */ | ||
54 | bool (*set_backlight_level_pwm)(struct abm *abm, | ||
55 | unsigned int backlight_pwm_u16_16, | ||
52 | unsigned int frame_ramp, | 56 | unsigned int frame_ramp, |
53 | unsigned int controller_id, | 57 | unsigned int controller_id, |
54 | bool use_smooth_brightness); | 58 | bool use_smooth_brightness); |
55 | unsigned int (*get_current_backlight_8_bit)(struct abm *abm); | 59 | |
60 | unsigned int (*get_current_backlight)(struct abm *abm); | ||
61 | unsigned int (*get_target_backlight)(struct abm *abm); | ||
56 | }; | 62 | }; |
57 | 63 | ||
58 | #endif | 64 | #endif |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h index 689faa16c0ae..23a4b18e5fee 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h | |||
@@ -23,41 +23,25 @@ | |||
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #ifndef __DISPLAY_CLOCK_H__ | 26 | #ifndef __DAL_CLK_MGR_H__ |
27 | #define __DISPLAY_CLOCK_H__ | 27 | #define __DAL_CLK_MGR_H__ |
28 | 28 | ||
29 | #include "dm_services_types.h" | 29 | #include "dm_services_types.h" |
30 | #include "dc.h" | 30 | #include "dc.h" |
31 | 31 | ||
32 | /* Structure containing all state-dependent clocks | 32 | struct clk_mgr { |
33 | * (dependent on "enum clocks_state") */ | ||
34 | struct state_dependent_clocks { | ||
35 | int display_clk_khz; | ||
36 | int pixel_clk_khz; | ||
37 | }; | ||
38 | |||
39 | struct dccg { | ||
40 | struct dc_context *ctx; | 33 | struct dc_context *ctx; |
41 | const struct display_clock_funcs *funcs; | 34 | const struct clk_mgr_funcs *funcs; |
42 | 35 | ||
43 | enum dm_pp_clocks_state max_clks_state; | ||
44 | enum dm_pp_clocks_state cur_min_clks_state; | ||
45 | struct dc_clocks clks; | 36 | struct dc_clocks clks; |
46 | }; | 37 | }; |
47 | 38 | ||
48 | struct display_clock_funcs { | 39 | struct clk_mgr_funcs { |
49 | void (*update_clocks)(struct dccg *dccg, | 40 | void (*update_clocks)(struct clk_mgr *clk_mgr, |
50 | struct dc_clocks *new_clocks, | 41 | struct dc_state *context, |
51 | bool safe_to_lower); | 42 | bool safe_to_lower); |
52 | int (*set_dispclk)(struct dccg *dccg, | ||
53 | int requested_clock_khz); | ||
54 | |||
55 | int (*get_dp_ref_clk_frequency)(struct dccg *dccg); | ||
56 | 43 | ||
57 | bool (*update_dfs_bypass)(struct dccg *dccg, | 44 | int (*get_dp_ref_clk_frequency)(struct clk_mgr *clk_mgr); |
58 | struct dc *dc, | ||
59 | struct dc_state *context, | ||
60 | int requested_clock_khz); | ||
61 | }; | 45 | }; |
62 | 46 | ||
63 | #endif /* __DISPLAY_CLOCK_H__ */ | 47 | #endif /* __DAL_CLK_MGR_H__ */ |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h new file mode 100644 index 000000000000..95a56d012626 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * Copyright 2018 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: AMD | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #ifndef __DAL_DCCG_H__ | ||
27 | #define __DAL_DCCG_H__ | ||
28 | |||
29 | #include "dc_types.h" | ||
30 | |||
31 | struct dccg { | ||
32 | struct dc_context *ctx; | ||
33 | const struct dccg_funcs *funcs; | ||
34 | |||
35 | int ref_dppclk; | ||
36 | }; | ||
37 | |||
38 | struct dccg_funcs { | ||
39 | void (*update_dpp_dto)(struct dccg *dccg, | ||
40 | int dpp_inst, | ||
41 | int req_dppclk); | ||
42 | }; | ||
43 | |||
44 | #endif //__DAL_DCCG_H__ | ||
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h index cf7433ebf91a..da85537a4488 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h | |||
@@ -53,6 +53,12 @@ struct curve_points { | |||
53 | uint32_t custom_float_slope; | 53 | uint32_t custom_float_slope; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | struct curve_points3 { | ||
57 | struct curve_points red; | ||
58 | struct curve_points green; | ||
59 | struct curve_points blue; | ||
60 | }; | ||
61 | |||
56 | struct pwl_result_data { | 62 | struct pwl_result_data { |
57 | struct fixed31_32 red; | 63 | struct fixed31_32 red; |
58 | struct fixed31_32 green; | 64 | struct fixed31_32 green; |
@@ -71,9 +77,17 @@ struct pwl_result_data { | |||
71 | uint32_t delta_blue_reg; | 77 | uint32_t delta_blue_reg; |
72 | }; | 78 | }; |
73 | 79 | ||
80 | /* arr_curve_points - regamma regions/segments specification | ||
81 | * arr_points - beginning and end point specified separately (only one on DCE) | ||
82 | * corner_points - beginning and end point for all 3 colors (DCN) | ||
83 | * rgb_resulted - final curve | ||
84 | */ | ||
74 | struct pwl_params { | 85 | struct pwl_params { |
75 | struct gamma_curve arr_curve_points[34]; | 86 | struct gamma_curve arr_curve_points[34]; |
76 | struct curve_points arr_points[2]; | 87 | union { |
88 | struct curve_points arr_points[2]; | ||
89 | struct curve_points3 corner_points[2]; | ||
90 | }; | ||
77 | struct pwl_result_data rgb_resulted[256 + 3]; | 91 | struct pwl_result_data rgb_resulted[256 + 3]; |
78 | uint32_t hw_points_num; | 92 | uint32_t hw_points_num; |
79 | }; | 93 | }; |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h index e28e9770e0a3..c20fdcaac53b 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h | |||
@@ -65,7 +65,8 @@ struct encoder_feature_support { | |||
65 | 65 | ||
66 | enum dc_color_depth max_hdmi_deep_color; | 66 | enum dc_color_depth max_hdmi_deep_color; |
67 | unsigned int max_hdmi_pixel_clock; | 67 | unsigned int max_hdmi_pixel_clock; |
68 | bool ycbcr420_supported; | 68 | bool hdmi_ycbcr420_supported; |
69 | bool dp_ycbcr420_supported; | ||
69 | }; | 70 | }; |
70 | 71 | ||
71 | union dpcd_psr_configuration { | 72 | union dpcd_psr_configuration { |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h index da89c2edb07c..06df02ddff6a 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h | |||
@@ -31,7 +31,7 @@ | |||
31 | #include "dml/display_mode_structs.h" | 31 | #include "dml/display_mode_structs.h" |
32 | 32 | ||
33 | struct dchub_init_data; | 33 | struct dchub_init_data; |
34 | struct cstate_pstate_watermarks_st { | 34 | struct cstate_pstate_watermarks_st1 { |
35 | uint32_t cstate_exit_ns; | 35 | uint32_t cstate_exit_ns; |
36 | uint32_t cstate_enter_plus_exit_ns; | 36 | uint32_t cstate_enter_plus_exit_ns; |
37 | uint32_t pstate_change_ns; | 37 | uint32_t pstate_change_ns; |
@@ -40,7 +40,7 @@ struct cstate_pstate_watermarks_st { | |||
40 | struct dcn_watermarks { | 40 | struct dcn_watermarks { |
41 | uint32_t pte_meta_urgent_ns; | 41 | uint32_t pte_meta_urgent_ns; |
42 | uint32_t urgent_ns; | 42 | uint32_t urgent_ns; |
43 | struct cstate_pstate_watermarks_st cstate_pstate; | 43 | struct cstate_pstate_watermarks_st1 cstate_pstate; |
44 | }; | 44 | }; |
45 | 45 | ||
46 | struct dcn_watermark_set { | 46 | struct dcn_watermark_set { |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index 26f29d5da3d8..e9b702ce02dd 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h | |||
@@ -32,8 +32,6 @@ | |||
32 | #include "inc/hw/link_encoder.h" | 32 | #include "inc/hw/link_encoder.h" |
33 | #include "core_status.h" | 33 | #include "core_status.h" |
34 | 34 | ||
35 | #define EDP_BACKLIGHT_RAMP_DISABLE_LEVEL 0xFFFFFFFF | ||
36 | |||
37 | enum pipe_gating_control { | 35 | enum pipe_gating_control { |
38 | PIPE_GATING_CONTROL_DISABLE = 0, | 36 | PIPE_GATING_CONTROL_DISABLE = 0, |
39 | PIPE_GATING_CONTROL_ENABLE, | 37 | PIPE_GATING_CONTROL_ENABLE, |
@@ -87,11 +85,6 @@ struct hw_sequencer_funcs { | |||
87 | void (*program_gamut_remap)( | 85 | void (*program_gamut_remap)( |
88 | struct pipe_ctx *pipe_ctx); | 86 | struct pipe_ctx *pipe_ctx); |
89 | 87 | ||
90 | void (*program_csc_matrix)( | ||
91 | struct pipe_ctx *pipe_ctx, | ||
92 | enum dc_color_space colorspace, | ||
93 | uint16_t *matrix); | ||
94 | |||
95 | void (*program_output_csc)(struct dc *dc, | 88 | void (*program_output_csc)(struct dc *dc, |
96 | struct pipe_ctx *pipe_ctx, | 89 | struct pipe_ctx *pipe_ctx, |
97 | enum dc_color_space colorspace, | 90 | enum dc_color_space colorspace, |
@@ -177,10 +170,12 @@ struct hw_sequencer_funcs { | |||
177 | struct pipe_ctx *pipe_ctx, | 170 | struct pipe_ctx *pipe_ctx, |
178 | bool blank); | 171 | bool blank); |
179 | 172 | ||
180 | void (*set_bandwidth)( | 173 | void (*prepare_bandwidth)( |
181 | struct dc *dc, | 174 | struct dc *dc, |
182 | struct dc_state *context, | 175 | struct dc_state *context); |
183 | bool safe_to_lower); | 176 | void (*optimize_bandwidth)( |
177 | struct dc *dc, | ||
178 | struct dc_state *context); | ||
184 | 179 | ||
185 | void (*set_drr)(struct pipe_ctx **pipe_ctx, int num_pipes, | 180 | void (*set_drr)(struct pipe_ctx **pipe_ctx, int num_pipes, |
186 | int vmin, int vmax); | 181 | int vmin, int vmax); |
@@ -210,11 +205,6 @@ struct hw_sequencer_funcs { | |||
210 | struct resource_pool *res_pool, | 205 | struct resource_pool *res_pool, |
211 | struct pipe_ctx *pipe_ctx); | 206 | struct pipe_ctx *pipe_ctx); |
212 | 207 | ||
213 | void (*ready_shared_resources)(struct dc *dc, struct dc_state *context); | ||
214 | void (*optimize_shared_resources)(struct dc *dc); | ||
215 | void (*pplib_apply_display_requirements)( | ||
216 | struct dc *dc, | ||
217 | struct dc_state *context); | ||
218 | void (*edp_power_control)( | 208 | void (*edp_power_control)( |
219 | struct dc_link *link, | 209 | struct dc_link *link, |
220 | bool enable); | 210 | bool enable); |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h index 33b99e3ab10d..0086a2f1d21a 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h | |||
@@ -30,9 +30,6 @@ | |||
30 | #include "dal_asic_id.h" | 30 | #include "dal_asic_id.h" |
31 | #include "dm_pp_smu.h" | 31 | #include "dm_pp_smu.h" |
32 | 32 | ||
33 | /* TODO unhardcode, 4 for CZ*/ | ||
34 | #define MEMORY_TYPE_MULTIPLIER 4 | ||
35 | |||
36 | enum dce_version resource_parse_asic_id( | 33 | enum dce_version resource_parse_asic_id( |
37 | struct hw_asic_id asic_id); | 34 | struct hw_asic_id asic_id); |
38 | 35 | ||
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c index cdcefd087487..7480f072c375 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c | |||
@@ -306,6 +306,18 @@ static struct fixed31_32 translate_from_linear_space( | |||
306 | a1); | 306 | a1); |
307 | } | 307 | } |
308 | 308 | ||
309 | static struct fixed31_32 calculate_gamma22(struct fixed31_32 arg) | ||
310 | { | ||
311 | struct fixed31_32 gamma = dc_fixpt_from_fraction(22, 10); | ||
312 | |||
313 | return translate_from_linear_space(arg, | ||
314 | dc_fixpt_zero, | ||
315 | dc_fixpt_zero, | ||
316 | dc_fixpt_zero, | ||
317 | dc_fixpt_zero, | ||
318 | gamma); | ||
319 | } | ||
320 | |||
309 | static struct fixed31_32 translate_to_linear_space( | 321 | static struct fixed31_32 translate_to_linear_space( |
310 | struct fixed31_32 arg, | 322 | struct fixed31_32 arg, |
311 | struct fixed31_32 a0, | 323 | struct fixed31_32 a0, |
@@ -709,6 +721,169 @@ static void build_regamma(struct pwl_float_data_ex *rgb_regamma, | |||
709 | } | 721 | } |
710 | } | 722 | } |
711 | 723 | ||
724 | static void hermite_spline_eetf(struct fixed31_32 input_x, | ||
725 | struct fixed31_32 max_display, | ||
726 | struct fixed31_32 min_display, | ||
727 | struct fixed31_32 max_content, | ||
728 | struct fixed31_32 *out_x) | ||
729 | { | ||
730 | struct fixed31_32 min_lum_pq; | ||
731 | struct fixed31_32 max_lum_pq; | ||
732 | struct fixed31_32 max_content_pq; | ||
733 | struct fixed31_32 ks; | ||
734 | struct fixed31_32 E1; | ||
735 | struct fixed31_32 E2; | ||
736 | struct fixed31_32 E3; | ||
737 | struct fixed31_32 t; | ||
738 | struct fixed31_32 t2; | ||
739 | struct fixed31_32 t3; | ||
740 | struct fixed31_32 two; | ||
741 | struct fixed31_32 three; | ||
742 | struct fixed31_32 temp1; | ||
743 | struct fixed31_32 temp2; | ||
744 | struct fixed31_32 a = dc_fixpt_from_fraction(15, 10); | ||
745 | struct fixed31_32 b = dc_fixpt_from_fraction(5, 10); | ||
746 | struct fixed31_32 epsilon = dc_fixpt_from_fraction(1, 1000000); // dc_fixpt_epsilon is a bit too small | ||
747 | |||
748 | if (dc_fixpt_eq(max_content, dc_fixpt_zero)) { | ||
749 | *out_x = dc_fixpt_zero; | ||
750 | return; | ||
751 | } | ||
752 | |||
753 | compute_pq(input_x, &E1); | ||
754 | compute_pq(dc_fixpt_div(min_display, max_content), &min_lum_pq); | ||
755 | compute_pq(dc_fixpt_div(max_display, max_content), &max_lum_pq); | ||
756 | compute_pq(dc_fixpt_one, &max_content_pq); // always 1? DAL2 code is weird | ||
757 | a = dc_fixpt_div(dc_fixpt_add(dc_fixpt_one, b), max_content_pq); // (1+b)/maxContent | ||
758 | ks = dc_fixpt_sub(dc_fixpt_mul(a, max_lum_pq), b); // a * max_lum_pq - b | ||
759 | |||
760 | if (dc_fixpt_lt(E1, ks)) | ||
761 | E2 = E1; | ||
762 | else if (dc_fixpt_le(ks, E1) && dc_fixpt_le(E1, dc_fixpt_one)) { | ||
763 | if (dc_fixpt_lt(epsilon, dc_fixpt_sub(dc_fixpt_one, ks))) | ||
764 | // t = (E1 - ks) / (1 - ks) | ||
765 | t = dc_fixpt_div(dc_fixpt_sub(E1, ks), | ||
766 | dc_fixpt_sub(dc_fixpt_one, ks)); | ||
767 | else | ||
768 | t = dc_fixpt_zero; | ||
769 | |||
770 | two = dc_fixpt_from_int(2); | ||
771 | three = dc_fixpt_from_int(3); | ||
772 | |||
773 | t2 = dc_fixpt_mul(t, t); | ||
774 | t3 = dc_fixpt_mul(t2, t); | ||
775 | temp1 = dc_fixpt_mul(two, t3); | ||
776 | temp2 = dc_fixpt_mul(three, t2); | ||
777 | |||
778 | // (2t^3 - 3t^2 + 1) * ks | ||
779 | E2 = dc_fixpt_mul(ks, dc_fixpt_add(dc_fixpt_one, | ||
780 | dc_fixpt_sub(temp1, temp2))); | ||
781 | |||
782 | // (-2t^3 + 3t^2) * max_lum_pq | ||
783 | E2 = dc_fixpt_add(E2, dc_fixpt_mul(max_lum_pq, | ||
784 | dc_fixpt_sub(temp2, temp1))); | ||
785 | |||
786 | temp1 = dc_fixpt_mul(two, t2); | ||
787 | temp2 = dc_fixpt_sub(dc_fixpt_one, ks); | ||
788 | |||
789 | // (t^3 - 2t^2 + t) * (1-ks) | ||
790 | E2 = dc_fixpt_add(E2, dc_fixpt_mul(temp2, | ||
791 | dc_fixpt_add(t, dc_fixpt_sub(t3, temp1)))); | ||
792 | } else | ||
793 | E2 = dc_fixpt_one; | ||
794 | |||
795 | temp1 = dc_fixpt_sub(dc_fixpt_one, E2); | ||
796 | temp2 = dc_fixpt_mul(temp1, temp1); | ||
797 | temp2 = dc_fixpt_mul(temp2, temp2); | ||
798 | // temp2 = (1-E2)^4 | ||
799 | |||
800 | E3 = dc_fixpt_add(E2, dc_fixpt_mul(min_lum_pq, temp2)); | ||
801 | compute_de_pq(E3, out_x); | ||
802 | |||
803 | *out_x = dc_fixpt_div(*out_x, dc_fixpt_div(max_display, max_content)); | ||
804 | } | ||
805 | |||
806 | static bool build_freesync_hdr(struct pwl_float_data_ex *rgb_regamma, | ||
807 | uint32_t hw_points_num, | ||
808 | const struct hw_x_point *coordinate_x, | ||
809 | const struct freesync_hdr_tf_params *fs_params) | ||
810 | { | ||
811 | uint32_t i; | ||
812 | struct pwl_float_data_ex *rgb = rgb_regamma; | ||
813 | const struct hw_x_point *coord_x = coordinate_x; | ||
814 | struct fixed31_32 scaledX = dc_fixpt_zero; | ||
815 | struct fixed31_32 scaledX1 = dc_fixpt_zero; | ||
816 | struct fixed31_32 max_display = dc_fixpt_from_int(fs_params->max_display); | ||
817 | struct fixed31_32 min_display = dc_fixpt_from_fraction(fs_params->min_display, 10000); | ||
818 | struct fixed31_32 max_content = dc_fixpt_from_int(fs_params->max_content); | ||
819 | struct fixed31_32 min_content = dc_fixpt_from_fraction(fs_params->min_content, 10000); | ||
820 | struct fixed31_32 clip = dc_fixpt_one; | ||
821 | struct fixed31_32 output; | ||
822 | bool use_eetf = false; | ||
823 | bool is_clipped = false; | ||
824 | struct fixed31_32 sdr_white_level = dc_fixpt_from_int(fs_params->sdr_white_level); | ||
825 | |||
826 | if (fs_params == NULL || fs_params->max_content == 0 || | ||
827 | fs_params->max_display == 0) | ||
828 | return false; | ||
829 | |||
830 | if (fs_params->min_display > 1000) // cap at 0.1 at the bottom | ||
831 | min_display = dc_fixpt_from_fraction(1, 10); | ||
832 | if (fs_params->max_display < 100) // cap at 100 at the top | ||
833 | max_display = dc_fixpt_from_int(100); | ||
834 | |||
835 | if (fs_params->min_content < fs_params->min_display) | ||
836 | use_eetf = true; | ||
837 | else | ||
838 | min_content = min_display; | ||
839 | |||
840 | if (fs_params->max_content > fs_params->max_display) | ||
841 | use_eetf = true; | ||
842 | else | ||
843 | max_content = max_display; | ||
844 | |||
845 | rgb += 32; // first 32 points have problems with fixed point, too small | ||
846 | coord_x += 32; | ||
847 | for (i = 32; i <= hw_points_num; i++) { | ||
848 | if (!is_clipped) { | ||
849 | if (use_eetf) { | ||
850 | /*max content is equal 1 */ | ||
851 | scaledX1 = dc_fixpt_div(coord_x->x, | ||
852 | dc_fixpt_div(max_content, sdr_white_level)); | ||
853 | hermite_spline_eetf(scaledX1, max_display, min_display, | ||
854 | max_content, &scaledX); | ||
855 | } else | ||
856 | scaledX = dc_fixpt_div(coord_x->x, | ||
857 | dc_fixpt_div(max_display, sdr_white_level)); | ||
858 | |||
859 | if (dc_fixpt_lt(scaledX, clip)) { | ||
860 | if (dc_fixpt_lt(scaledX, dc_fixpt_zero)) | ||
861 | output = dc_fixpt_zero; | ||
862 | else | ||
863 | output = calculate_gamma22(scaledX); | ||
864 | |||
865 | rgb->r = output; | ||
866 | rgb->g = output; | ||
867 | rgb->b = output; | ||
868 | } else { | ||
869 | is_clipped = true; | ||
870 | rgb->r = clip; | ||
871 | rgb->g = clip; | ||
872 | rgb->b = clip; | ||
873 | } | ||
874 | } else { | ||
875 | rgb->r = clip; | ||
876 | rgb->g = clip; | ||
877 | rgb->b = clip; | ||
878 | } | ||
879 | |||
880 | ++coord_x; | ||
881 | ++rgb; | ||
882 | } | ||
883 | |||
884 | return true; | ||
885 | } | ||
886 | |||
712 | static void build_degamma(struct pwl_float_data_ex *curve, | 887 | static void build_degamma(struct pwl_float_data_ex *curve, |
713 | uint32_t hw_points_num, | 888 | uint32_t hw_points_num, |
714 | const struct hw_x_point *coordinate_x, bool is_2_4) | 889 | const struct hw_x_point *coordinate_x, bool is_2_4) |
@@ -1356,7 +1531,8 @@ static bool map_regamma_hw_to_x_user( | |||
1356 | #define _EXTRA_POINTS 3 | 1531 | #define _EXTRA_POINTS 3 |
1357 | 1532 | ||
1358 | bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf, | 1533 | bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf, |
1359 | const struct dc_gamma *ramp, bool mapUserRamp, bool canRomBeUsed) | 1534 | const struct dc_gamma *ramp, bool mapUserRamp, bool canRomBeUsed, |
1535 | const struct freesync_hdr_tf_params *fs_params) | ||
1360 | { | 1536 | { |
1361 | struct dc_transfer_func_distributed_points *tf_pts = &output_tf->tf_pts; | 1537 | struct dc_transfer_func_distributed_points *tf_pts = &output_tf->tf_pts; |
1362 | struct dividers dividers; | 1538 | struct dividers dividers; |
@@ -1374,7 +1550,7 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf, | |||
1374 | /* we can use hardcoded curve for plain SRGB TF */ | 1550 | /* we can use hardcoded curve for plain SRGB TF */ |
1375 | if (output_tf->type == TF_TYPE_PREDEFINED && canRomBeUsed == true && | 1551 | if (output_tf->type == TF_TYPE_PREDEFINED && canRomBeUsed == true && |
1376 | output_tf->tf == TRANSFER_FUNCTION_SRGB && | 1552 | output_tf->tf == TRANSFER_FUNCTION_SRGB && |
1377 | (!mapUserRamp && ramp->type == GAMMA_RGB_256)) | 1553 | (ramp->is_identity || (!mapUserRamp && ramp->type == GAMMA_RGB_256))) |
1378 | return true; | 1554 | return true; |
1379 | 1555 | ||
1380 | output_tf->type = TF_TYPE_DISTRIBUTED_POINTS; | 1556 | output_tf->type = TF_TYPE_DISTRIBUTED_POINTS; |
@@ -1424,6 +1600,12 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf, | |||
1424 | MAX_HW_POINTS, | 1600 | MAX_HW_POINTS, |
1425 | coordinates_x, | 1601 | coordinates_x, |
1426 | output_tf->sdr_ref_white_level); | 1602 | output_tf->sdr_ref_white_level); |
1603 | } else if (tf == TRANSFER_FUNCTION_GAMMA22 && | ||
1604 | fs_params != NULL) { | ||
1605 | build_freesync_hdr(rgb_regamma, | ||
1606 | MAX_HW_POINTS, | ||
1607 | coordinates_x, | ||
1608 | fs_params); | ||
1427 | } else { | 1609 | } else { |
1428 | tf_pts->end_exponent = 0; | 1610 | tf_pts->end_exponent = 0; |
1429 | tf_pts->x_point_at_y1_red = 1; | 1611 | tf_pts->x_point_at_y1_red = 1; |
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h index 63ccb9c91224..a6e164df090a 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h | |||
@@ -73,12 +73,21 @@ struct regamma_lut { | |||
73 | }; | 73 | }; |
74 | }; | 74 | }; |
75 | 75 | ||
76 | struct freesync_hdr_tf_params { | ||
77 | unsigned int sdr_white_level; | ||
78 | unsigned int min_content; // luminance in 1/10000 nits | ||
79 | unsigned int max_content; // luminance in nits | ||
80 | unsigned int min_display; // luminance in 1/10000 nits | ||
81 | unsigned int max_display; // luminance in nits | ||
82 | }; | ||
83 | |||
76 | void setup_x_points_distribution(void); | 84 | void setup_x_points_distribution(void); |
77 | void precompute_pq(void); | 85 | void precompute_pq(void); |
78 | void precompute_de_pq(void); | 86 | void precompute_de_pq(void); |
79 | 87 | ||
80 | bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf, | 88 | bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf, |
81 | const struct dc_gamma *ramp, bool mapUserRamp, bool canRomBeUsed); | 89 | const struct dc_gamma *ramp, bool mapUserRamp, bool canRomBeUsed, |
90 | const struct freesync_hdr_tf_params *fs_params); | ||
82 | 91 | ||
83 | bool mod_color_calculate_degamma_params(struct dc_transfer_func *output_tf, | 92 | bool mod_color_calculate_degamma_params(struct dc_transfer_func *output_tf, |
84 | const struct dc_gamma *ramp, bool mapUserRamp); | 93 | const struct dc_gamma *ramp, bool mapUserRamp); |
diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index 4018c7180d00..620a171620ee 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #define RENDER_TIMES_MAX_COUNT 10 | 37 | #define RENDER_TIMES_MAX_COUNT 10 |
38 | /* Threshold to exit BTR (to avoid frequent enter-exits at the lower limit) */ | 38 | /* Threshold to exit BTR (to avoid frequent enter-exits at the lower limit) */ |
39 | #define BTR_EXIT_MARGIN 2000 | 39 | #define BTR_EXIT_MARGIN 2000 |
40 | /*Threshold to exit fixed refresh rate*/ | ||
41 | #define FIXED_REFRESH_EXIT_MARGIN_IN_HZ 4 | ||
40 | /* Number of consecutive frames to check before entering/exiting fixed refresh*/ | 42 | /* Number of consecutive frames to check before entering/exiting fixed refresh*/ |
41 | #define FIXED_REFRESH_ENTER_FRAME_COUNT 5 | 43 | #define FIXED_REFRESH_ENTER_FRAME_COUNT 5 |
42 | #define FIXED_REFRESH_EXIT_FRAME_COUNT 5 | 44 | #define FIXED_REFRESH_EXIT_FRAME_COUNT 5 |
@@ -257,40 +259,14 @@ static void apply_below_the_range(struct core_freesync *core_freesync, | |||
257 | if (in_out_vrr->btr.btr_active) { | 259 | if (in_out_vrr->btr.btr_active) { |
258 | in_out_vrr->btr.frame_counter = 0; | 260 | in_out_vrr->btr.frame_counter = 0; |
259 | in_out_vrr->btr.btr_active = false; | 261 | in_out_vrr->btr.btr_active = false; |
260 | |||
261 | /* Exit Fixed Refresh mode */ | ||
262 | } else if (in_out_vrr->fixed.fixed_active) { | ||
263 | |||
264 | in_out_vrr->fixed.frame_counter++; | ||
265 | |||
266 | if (in_out_vrr->fixed.frame_counter > | ||
267 | FIXED_REFRESH_EXIT_FRAME_COUNT) { | ||
268 | in_out_vrr->fixed.frame_counter = 0; | ||
269 | in_out_vrr->fixed.fixed_active = false; | ||
270 | } | ||
271 | } | 262 | } |
272 | } else if (last_render_time_in_us > max_render_time_in_us) { | 263 | } else if (last_render_time_in_us > max_render_time_in_us) { |
273 | /* Enter Below the Range */ | 264 | /* Enter Below the Range */ |
274 | if (!in_out_vrr->btr.btr_active && | 265 | in_out_vrr->btr.btr_active = true; |
275 | in_out_vrr->btr.btr_enabled) { | ||
276 | in_out_vrr->btr.btr_active = true; | ||
277 | |||
278 | /* Enter Fixed Refresh mode */ | ||
279 | } else if (!in_out_vrr->fixed.fixed_active && | ||
280 | !in_out_vrr->btr.btr_enabled) { | ||
281 | in_out_vrr->fixed.frame_counter++; | ||
282 | |||
283 | if (in_out_vrr->fixed.frame_counter > | ||
284 | FIXED_REFRESH_ENTER_FRAME_COUNT) { | ||
285 | in_out_vrr->fixed.frame_counter = 0; | ||
286 | in_out_vrr->fixed.fixed_active = true; | ||
287 | } | ||
288 | } | ||
289 | } | 266 | } |
290 | 267 | ||
291 | /* BTR set to "not active" so disengage */ | 268 | /* BTR set to "not active" so disengage */ |
292 | if (!in_out_vrr->btr.btr_active) { | 269 | if (!in_out_vrr->btr.btr_active) { |
293 | in_out_vrr->btr.btr_active = false; | ||
294 | in_out_vrr->btr.inserted_duration_in_us = 0; | 270 | in_out_vrr->btr.inserted_duration_in_us = 0; |
295 | in_out_vrr->btr.frames_to_insert = 0; | 271 | in_out_vrr->btr.frames_to_insert = 0; |
296 | in_out_vrr->btr.frame_counter = 0; | 272 | in_out_vrr->btr.frame_counter = 0; |
@@ -375,7 +351,12 @@ static void apply_fixed_refresh(struct core_freesync *core_freesync, | |||
375 | bool update = false; | 351 | bool update = false; |
376 | unsigned int max_render_time_in_us = in_out_vrr->max_duration_in_us; | 352 | unsigned int max_render_time_in_us = in_out_vrr->max_duration_in_us; |
377 | 353 | ||
378 | if (last_render_time_in_us + BTR_EXIT_MARGIN < max_render_time_in_us) { | 354 | //Compute the exit refresh rate and exit frame duration |
355 | unsigned int exit_refresh_rate_in_milli_hz = ((1000000000/max_render_time_in_us) | ||
356 | + (1000*FIXED_REFRESH_EXIT_MARGIN_IN_HZ)); | ||
357 | unsigned int exit_frame_duration_in_us = 1000000000/exit_refresh_rate_in_milli_hz; | ||
358 | |||
359 | if (last_render_time_in_us < exit_frame_duration_in_us) { | ||
379 | /* Exit Fixed Refresh mode */ | 360 | /* Exit Fixed Refresh mode */ |
380 | if (in_out_vrr->fixed.fixed_active) { | 361 | if (in_out_vrr->fixed.fixed_active) { |
381 | in_out_vrr->fixed.frame_counter++; | 362 | in_out_vrr->fixed.frame_counter++; |
diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index 2083c308007c..470d7b89071a 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h | |||
@@ -133,6 +133,10 @@ enum PP_FEATURE_MASK { | |||
133 | PP_AVFS_MASK = 0x40000, | 133 | PP_AVFS_MASK = 0x40000, |
134 | }; | 134 | }; |
135 | 135 | ||
136 | enum DC_FEATURE_MASK { | ||
137 | DC_FBC_MASK = 0x1, | ||
138 | }; | ||
139 | |||
136 | /** | 140 | /** |
137 | * struct amd_ip_funcs - general hooks for managing amdgpu IP Blocks | 141 | * struct amd_ip_funcs - general hooks for managing amdgpu IP Blocks |
138 | */ | 142 | */ |
diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h index d2e7c0fa96c2..8eb0bb241210 100644 --- a/drivers/gpu/drm/amd/include/atomfirmware.h +++ b/drivers/gpu/drm/amd/include/atomfirmware.h | |||
@@ -1325,7 +1325,7 @@ struct atom_smu_info_v3_3 { | |||
1325 | struct atom_common_table_header table_header; | 1325 | struct atom_common_table_header table_header; |
1326 | uint8_t smuip_min_ver; | 1326 | uint8_t smuip_min_ver; |
1327 | uint8_t smuip_max_ver; | 1327 | uint8_t smuip_max_ver; |
1328 | uint8_t smu_rsd1; | 1328 | uint8_t waflclk_ss_mode; |
1329 | uint8_t gpuclk_ss_mode; | 1329 | uint8_t gpuclk_ss_mode; |
1330 | uint16_t sclk_ss_percentage; | 1330 | uint16_t sclk_ss_percentage; |
1331 | uint16_t sclk_ss_rate_10hz; | 1331 | uint16_t sclk_ss_rate_10hz; |
@@ -1355,7 +1355,10 @@ struct atom_smu_info_v3_3 { | |||
1355 | uint32_t syspll3_1_vco_freq_10khz; | 1355 | uint32_t syspll3_1_vco_freq_10khz; |
1356 | uint32_t bootup_fclk_10khz; | 1356 | uint32_t bootup_fclk_10khz; |
1357 | uint32_t bootup_waflclk_10khz; | 1357 | uint32_t bootup_waflclk_10khz; |
1358 | uint32_t reserved[3]; | 1358 | uint32_t smu_info_caps; |
1359 | uint16_t waflclk_ss_percentage; // in unit of 0.001% | ||
1360 | uint16_t smuinitoffset; | ||
1361 | uint32_t reserved; | ||
1359 | }; | 1362 | }; |
1360 | 1363 | ||
1361 | /* | 1364 | /* |
diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h index 64ecffd52126..58ac0b90c310 100644 --- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h | |||
@@ -205,20 +205,6 @@ struct tile_config { | |||
205 | /** | 205 | /** |
206 | * struct kfd2kgd_calls | 206 | * struct kfd2kgd_calls |
207 | * | 207 | * |
208 | * @init_gtt_mem_allocation: Allocate a buffer on the gart aperture. | ||
209 | * The buffer can be used for mqds, hpds, kernel queue, fence and runlists | ||
210 | * | ||
211 | * @free_gtt_mem: Frees a buffer that was allocated on the gart aperture | ||
212 | * | ||
213 | * @get_local_mem_info: Retrieves information about GPU local memory | ||
214 | * | ||
215 | * @get_gpu_clock_counter: Retrieves GPU clock counter | ||
216 | * | ||
217 | * @get_max_engine_clock_in_mhz: Retrieves maximum GPU clock in MHz | ||
218 | * | ||
219 | * @alloc_pasid: Allocate a PASID | ||
220 | * @free_pasid: Free a PASID | ||
221 | * | ||
222 | * @program_sh_mem_settings: A function that should initiate the memory | 208 | * @program_sh_mem_settings: A function that should initiate the memory |
223 | * properties such as main aperture memory type (cache / non cached) and | 209 | * properties such as main aperture memory type (cache / non cached) and |
224 | * secondary aperture base address, size and memory type. | 210 | * secondary aperture base address, size and memory type. |
@@ -255,64 +241,16 @@ struct tile_config { | |||
255 | * | 241 | * |
256 | * @get_tile_config: Returns GPU-specific tiling mode information | 242 | * @get_tile_config: Returns GPU-specific tiling mode information |
257 | * | 243 | * |
258 | * @get_cu_info: Retrieves activated cu info | ||
259 | * | ||
260 | * @get_vram_usage: Returns current VRAM usage | ||
261 | * | ||
262 | * @create_process_vm: Create a VM address space for a given process and GPU | ||
263 | * | ||
264 | * @destroy_process_vm: Destroy a VM | ||
265 | * | ||
266 | * @get_process_page_dir: Get physical address of a VM page directory | ||
267 | * | ||
268 | * @set_vm_context_page_table_base: Program page table base for a VMID | 244 | * @set_vm_context_page_table_base: Program page table base for a VMID |
269 | * | 245 | * |
270 | * @alloc_memory_of_gpu: Allocate GPUVM memory | ||
271 | * | ||
272 | * @free_memory_of_gpu: Free GPUVM memory | ||
273 | * | ||
274 | * @map_memory_to_gpu: Map GPUVM memory into a specific VM address | ||
275 | * space. Allocates and updates page tables and page directories as | ||
276 | * needed. This function may return before all page table updates have | ||
277 | * completed. This allows multiple map operations (on multiple GPUs) | ||
278 | * to happen concurrently. Use sync_memory to synchronize with all | ||
279 | * pending updates. | ||
280 | * | ||
281 | * @unmap_memor_to_gpu: Unmap GPUVM memory from a specific VM address space | ||
282 | * | ||
283 | * @sync_memory: Wait for pending page table updates to complete | ||
284 | * | ||
285 | * @map_gtt_bo_to_kernel: Map a GTT BO for kernel access | ||
286 | * Pins the BO, maps it to kernel address space. Such BOs are never evicted. | ||
287 | * The kernel virtual address remains valid until the BO is freed. | ||
288 | * | ||
289 | * @restore_process_bos: Restore all BOs that belong to the | ||
290 | * process. This is intended for restoring memory mappings after a TTM | ||
291 | * eviction. | ||
292 | * | ||
293 | * @invalidate_tlbs: Invalidate TLBs for a specific PASID | 246 | * @invalidate_tlbs: Invalidate TLBs for a specific PASID |
294 | * | 247 | * |
295 | * @invalidate_tlbs_vmid: Invalidate TLBs for a specific VMID | 248 | * @invalidate_tlbs_vmid: Invalidate TLBs for a specific VMID |
296 | * | 249 | * |
297 | * @submit_ib: Submits an IB to the engine specified by inserting the | ||
298 | * IB to the corresponding ring (ring type). The IB is executed with the | ||
299 | * specified VMID in a user mode context. | ||
300 | * | ||
301 | * @get_vm_fault_info: Return information about a recent VM fault on | ||
302 | * GFXv7 and v8. If multiple VM faults occurred since the last call of | ||
303 | * this function, it will return information about the first of those | ||
304 | * faults. On GFXv9 VM fault information is fully contained in the IH | ||
305 | * packet and this function is not needed. | ||
306 | * | ||
307 | * @read_vmid_from_vmfault_reg: On Hawaii the VMID is not set in the | 250 | * @read_vmid_from_vmfault_reg: On Hawaii the VMID is not set in the |
308 | * IH ring entry. This function allows the KFD ISR to get the VMID | 251 | * IH ring entry. This function allows the KFD ISR to get the VMID |
309 | * from the fault status register as early as possible. | 252 | * from the fault status register as early as possible. |
310 | * | 253 | * |
311 | * @gpu_recover: let kgd reset gpu after kfd detect CPC hang | ||
312 | * | ||
313 | * @set_compute_idle: Indicates that compute is idle on a device. This | ||
314 | * can be used to change power profiles depending on compute activity. | ||
315 | * | ||
316 | * @get_hive_id: Returns hive id of current device, 0 if xgmi is not enabled | 254 | * @get_hive_id: Returns hive id of current device, 0 if xgmi is not enabled |
317 | * | 255 | * |
318 | * This structure contains function pointers to services that the kgd driver | 256 | * This structure contains function pointers to services that the kgd driver |
@@ -320,21 +258,6 @@ struct tile_config { | |||
320 | * | 258 | * |
321 | */ | 259 | */ |
322 | struct kfd2kgd_calls { | 260 | struct kfd2kgd_calls { |
323 | int (*init_gtt_mem_allocation)(struct kgd_dev *kgd, size_t size, | ||
324 | void **mem_obj, uint64_t *gpu_addr, | ||
325 | void **cpu_ptr, bool mqd_gfx9); | ||
326 | |||
327 | void (*free_gtt_mem)(struct kgd_dev *kgd, void *mem_obj); | ||
328 | |||
329 | void (*get_local_mem_info)(struct kgd_dev *kgd, | ||
330 | struct kfd_local_mem_info *mem_info); | ||
331 | uint64_t (*get_gpu_clock_counter)(struct kgd_dev *kgd); | ||
332 | |||
333 | uint32_t (*get_max_engine_clock_in_mhz)(struct kgd_dev *kgd); | ||
334 | |||
335 | int (*alloc_pasid)(unsigned int bits); | ||
336 | void (*free_pasid)(unsigned int pasid); | ||
337 | |||
338 | /* Register access functions */ | 261 | /* Register access functions */ |
339 | void (*program_sh_mem_settings)(struct kgd_dev *kgd, uint32_t vmid, | 262 | void (*program_sh_mem_settings)(struct kgd_dev *kgd, uint32_t vmid, |
340 | uint32_t sh_mem_config, uint32_t sh_mem_ape1_base, | 263 | uint32_t sh_mem_config, uint32_t sh_mem_ape1_base, |
@@ -398,49 +321,11 @@ struct kfd2kgd_calls { | |||
398 | uint64_t va, uint32_t vmid); | 321 | uint64_t va, uint32_t vmid); |
399 | int (*get_tile_config)(struct kgd_dev *kgd, struct tile_config *config); | 322 | int (*get_tile_config)(struct kgd_dev *kgd, struct tile_config *config); |
400 | 323 | ||
401 | void (*get_cu_info)(struct kgd_dev *kgd, | ||
402 | struct kfd_cu_info *cu_info); | ||
403 | uint64_t (*get_vram_usage)(struct kgd_dev *kgd); | ||
404 | |||
405 | int (*create_process_vm)(struct kgd_dev *kgd, unsigned int pasid, void **vm, | ||
406 | void **process_info, struct dma_fence **ef); | ||
407 | int (*acquire_process_vm)(struct kgd_dev *kgd, struct file *filp, | ||
408 | unsigned int pasid, void **vm, void **process_info, | ||
409 | struct dma_fence **ef); | ||
410 | void (*destroy_process_vm)(struct kgd_dev *kgd, void *vm); | ||
411 | void (*release_process_vm)(struct kgd_dev *kgd, void *vm); | ||
412 | uint64_t (*get_process_page_dir)(void *vm); | ||
413 | void (*set_vm_context_page_table_base)(struct kgd_dev *kgd, | 324 | void (*set_vm_context_page_table_base)(struct kgd_dev *kgd, |
414 | uint32_t vmid, uint64_t page_table_base); | 325 | uint32_t vmid, uint64_t page_table_base); |
415 | int (*alloc_memory_of_gpu)(struct kgd_dev *kgd, uint64_t va, | ||
416 | uint64_t size, void *vm, | ||
417 | struct kgd_mem **mem, uint64_t *offset, | ||
418 | uint32_t flags); | ||
419 | int (*free_memory_of_gpu)(struct kgd_dev *kgd, struct kgd_mem *mem); | ||
420 | int (*map_memory_to_gpu)(struct kgd_dev *kgd, struct kgd_mem *mem, | ||
421 | void *vm); | ||
422 | int (*unmap_memory_to_gpu)(struct kgd_dev *kgd, struct kgd_mem *mem, | ||
423 | void *vm); | ||
424 | int (*sync_memory)(struct kgd_dev *kgd, struct kgd_mem *mem, bool intr); | ||
425 | int (*map_gtt_bo_to_kernel)(struct kgd_dev *kgd, struct kgd_mem *mem, | ||
426 | void **kptr, uint64_t *size); | ||
427 | int (*restore_process_bos)(void *process_info, struct dma_fence **ef); | ||
428 | |||
429 | int (*invalidate_tlbs)(struct kgd_dev *kgd, uint16_t pasid); | 326 | int (*invalidate_tlbs)(struct kgd_dev *kgd, uint16_t pasid); |
430 | int (*invalidate_tlbs_vmid)(struct kgd_dev *kgd, uint16_t vmid); | 327 | int (*invalidate_tlbs_vmid)(struct kgd_dev *kgd, uint16_t vmid); |
431 | |||
432 | int (*submit_ib)(struct kgd_dev *kgd, enum kgd_engine_type engine, | ||
433 | uint32_t vmid, uint64_t gpu_addr, | ||
434 | uint32_t *ib_cmd, uint32_t ib_len); | ||
435 | |||
436 | int (*get_vm_fault_info)(struct kgd_dev *kgd, | ||
437 | struct kfd_vm_fault_info *info); | ||
438 | uint32_t (*read_vmid_from_vmfault_reg)(struct kgd_dev *kgd); | 328 | uint32_t (*read_vmid_from_vmfault_reg)(struct kgd_dev *kgd); |
439 | |||
440 | void (*gpu_recover)(struct kgd_dev *kgd); | ||
441 | |||
442 | void (*set_compute_idle)(struct kgd_dev *kgd, bool idle); | ||
443 | |||
444 | uint64_t (*get_hive_id)(struct kgd_dev *kgd); | 329 | uint64_t (*get_hive_id)(struct kgd_dev *kgd); |
445 | 330 | ||
446 | }; | 331 | }; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c index 5e19f5977eb1..d138ddae563d 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c | |||
@@ -967,7 +967,7 @@ int smu7_enable_didt_config(struct pp_hwmgr *hwmgr) | |||
967 | PP_CAP(PHM_PlatformCaps_TDRamping) || | 967 | PP_CAP(PHM_PlatformCaps_TDRamping) || |
968 | PP_CAP(PHM_PlatformCaps_TCPRamping)) { | 968 | PP_CAP(PHM_PlatformCaps_TCPRamping)) { |
969 | 969 | ||
970 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 970 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
971 | mutex_lock(&adev->grbm_idx_mutex); | 971 | mutex_lock(&adev->grbm_idx_mutex); |
972 | value = 0; | 972 | value = 0; |
973 | value2 = cgs_read_register(hwmgr->device, mmGRBM_GFX_INDEX); | 973 | value2 = cgs_read_register(hwmgr->device, mmGRBM_GFX_INDEX); |
@@ -1014,13 +1014,13 @@ int smu7_enable_didt_config(struct pp_hwmgr *hwmgr) | |||
1014 | "Failed to enable DPM DIDT.", goto error); | 1014 | "Failed to enable DPM DIDT.", goto error); |
1015 | } | 1015 | } |
1016 | mutex_unlock(&adev->grbm_idx_mutex); | 1016 | mutex_unlock(&adev->grbm_idx_mutex); |
1017 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 1017 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
1018 | } | 1018 | } |
1019 | 1019 | ||
1020 | return 0; | 1020 | return 0; |
1021 | error: | 1021 | error: |
1022 | mutex_unlock(&adev->grbm_idx_mutex); | 1022 | mutex_unlock(&adev->grbm_idx_mutex); |
1023 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 1023 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
1024 | return result; | 1024 | return result; |
1025 | } | 1025 | } |
1026 | 1026 | ||
@@ -1034,7 +1034,7 @@ int smu7_disable_didt_config(struct pp_hwmgr *hwmgr) | |||
1034 | PP_CAP(PHM_PlatformCaps_TDRamping) || | 1034 | PP_CAP(PHM_PlatformCaps_TDRamping) || |
1035 | PP_CAP(PHM_PlatformCaps_TCPRamping)) { | 1035 | PP_CAP(PHM_PlatformCaps_TCPRamping)) { |
1036 | 1036 | ||
1037 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 1037 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
1038 | 1038 | ||
1039 | result = smu7_enable_didt(hwmgr, false); | 1039 | result = smu7_enable_didt(hwmgr, false); |
1040 | PP_ASSERT_WITH_CODE((result == 0), | 1040 | PP_ASSERT_WITH_CODE((result == 0), |
@@ -1046,12 +1046,12 @@ int smu7_disable_didt_config(struct pp_hwmgr *hwmgr) | |||
1046 | PP_ASSERT_WITH_CODE((0 == result), | 1046 | PP_ASSERT_WITH_CODE((0 == result), |
1047 | "Failed to disable DPM DIDT.", goto error); | 1047 | "Failed to disable DPM DIDT.", goto error); |
1048 | } | 1048 | } |
1049 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 1049 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
1050 | } | 1050 | } |
1051 | 1051 | ||
1052 | return 0; | 1052 | return 0; |
1053 | error: | 1053 | error: |
1054 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 1054 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
1055 | return result; | 1055 | return result; |
1056 | } | 1056 | } |
1057 | 1057 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c index 99a33c33a32c..101c09b212ad 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c | |||
@@ -713,20 +713,20 @@ int smu_set_watermarks_for_clocks_ranges(void *wt_table, | |||
713 | for (i = 0; i < wm_with_clock_ranges->num_wm_dmif_sets; i++) { | 713 | for (i = 0; i < wm_with_clock_ranges->num_wm_dmif_sets; i++) { |
714 | table->WatermarkRow[1][i].MinClock = | 714 | table->WatermarkRow[1][i].MinClock = |
715 | cpu_to_le16((uint16_t) | 715 | cpu_to_le16((uint16_t) |
716 | (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_dcfclk_clk_in_khz) / | 716 | (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_dcfclk_clk_in_khz / |
717 | 1000); | 717 | 1000)); |
718 | table->WatermarkRow[1][i].MaxClock = | 718 | table->WatermarkRow[1][i].MaxClock = |
719 | cpu_to_le16((uint16_t) | 719 | cpu_to_le16((uint16_t) |
720 | (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz) / | 720 | (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz / |
721 | 1000); | 721 | 1000)); |
722 | table->WatermarkRow[1][i].MinUclk = | 722 | table->WatermarkRow[1][i].MinUclk = |
723 | cpu_to_le16((uint16_t) | 723 | cpu_to_le16((uint16_t) |
724 | (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz) / | 724 | (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz / |
725 | 1000); | 725 | 1000)); |
726 | table->WatermarkRow[1][i].MaxUclk = | 726 | table->WatermarkRow[1][i].MaxUclk = |
727 | cpu_to_le16((uint16_t) | 727 | cpu_to_le16((uint16_t) |
728 | (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_mem_clk_in_khz) / | 728 | (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_mem_clk_in_khz / |
729 | 1000); | 729 | 1000)); |
730 | table->WatermarkRow[1][i].WmSetting = (uint8_t) | 730 | table->WatermarkRow[1][i].WmSetting = (uint8_t) |
731 | wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_set_id; | 731 | wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_set_id; |
732 | } | 732 | } |
@@ -734,20 +734,20 @@ int smu_set_watermarks_for_clocks_ranges(void *wt_table, | |||
734 | for (i = 0; i < wm_with_clock_ranges->num_wm_mcif_sets; i++) { | 734 | for (i = 0; i < wm_with_clock_ranges->num_wm_mcif_sets; i++) { |
735 | table->WatermarkRow[0][i].MinClock = | 735 | table->WatermarkRow[0][i].MinClock = |
736 | cpu_to_le16((uint16_t) | 736 | cpu_to_le16((uint16_t) |
737 | (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_min_socclk_clk_in_khz) / | 737 | (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_min_socclk_clk_in_khz / |
738 | 1000); | 738 | 1000)); |
739 | table->WatermarkRow[0][i].MaxClock = | 739 | table->WatermarkRow[0][i].MaxClock = |
740 | cpu_to_le16((uint16_t) | 740 | cpu_to_le16((uint16_t) |
741 | (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_max_socclk_clk_in_khz) / | 741 | (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_max_socclk_clk_in_khz / |
742 | 1000); | 742 | 1000)); |
743 | table->WatermarkRow[0][i].MinUclk = | 743 | table->WatermarkRow[0][i].MinUclk = |
744 | cpu_to_le16((uint16_t) | 744 | cpu_to_le16((uint16_t) |
745 | (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_min_mem_clk_in_khz) / | 745 | (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_min_mem_clk_in_khz / |
746 | 1000); | 746 | 1000)); |
747 | table->WatermarkRow[0][i].MaxUclk = | 747 | table->WatermarkRow[0][i].MaxUclk = |
748 | cpu_to_le16((uint16_t) | 748 | cpu_to_le16((uint16_t) |
749 | (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_max_mem_clk_in_khz) / | 749 | (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_max_mem_clk_in_khz / |
750 | 1000); | 750 | 1000)); |
751 | table->WatermarkRow[0][i].WmSetting = (uint8_t) | 751 | table->WatermarkRow[0][i].WmSetting = (uint8_t) |
752 | wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id; | 752 | wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id; |
753 | } | 753 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c index 2d88abf97e7b..6f26cb241ecc 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c | |||
@@ -937,7 +937,7 @@ static int vega10_enable_cac_driving_se_didt_config(struct pp_hwmgr *hwmgr) | |||
937 | 937 | ||
938 | num_se = adev->gfx.config.max_shader_engines; | 938 | num_se = adev->gfx.config.max_shader_engines; |
939 | 939 | ||
940 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 940 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
941 | 941 | ||
942 | mutex_lock(&adev->grbm_idx_mutex); | 942 | mutex_lock(&adev->grbm_idx_mutex); |
943 | for (count = 0; count < num_se; count++) { | 943 | for (count = 0; count < num_se; count++) { |
@@ -962,7 +962,7 @@ static int vega10_enable_cac_driving_se_didt_config(struct pp_hwmgr *hwmgr) | |||
962 | 962 | ||
963 | vega10_didt_set_mask(hwmgr, true); | 963 | vega10_didt_set_mask(hwmgr, true); |
964 | 964 | ||
965 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 965 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
966 | 966 | ||
967 | return 0; | 967 | return 0; |
968 | } | 968 | } |
@@ -971,11 +971,11 @@ static int vega10_disable_cac_driving_se_didt_config(struct pp_hwmgr *hwmgr) | |||
971 | { | 971 | { |
972 | struct amdgpu_device *adev = hwmgr->adev; | 972 | struct amdgpu_device *adev = hwmgr->adev; |
973 | 973 | ||
974 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 974 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
975 | 975 | ||
976 | vega10_didt_set_mask(hwmgr, false); | 976 | vega10_didt_set_mask(hwmgr, false); |
977 | 977 | ||
978 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 978 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
979 | 979 | ||
980 | return 0; | 980 | return 0; |
981 | } | 981 | } |
@@ -988,7 +988,7 @@ static int vega10_enable_psm_gc_didt_config(struct pp_hwmgr *hwmgr) | |||
988 | 988 | ||
989 | num_se = adev->gfx.config.max_shader_engines; | 989 | num_se = adev->gfx.config.max_shader_engines; |
990 | 990 | ||
991 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 991 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
992 | 992 | ||
993 | mutex_lock(&adev->grbm_idx_mutex); | 993 | mutex_lock(&adev->grbm_idx_mutex); |
994 | for (count = 0; count < num_se; count++) { | 994 | for (count = 0; count < num_se; count++) { |
@@ -1007,7 +1007,7 @@ static int vega10_enable_psm_gc_didt_config(struct pp_hwmgr *hwmgr) | |||
1007 | 1007 | ||
1008 | vega10_didt_set_mask(hwmgr, true); | 1008 | vega10_didt_set_mask(hwmgr, true); |
1009 | 1009 | ||
1010 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 1010 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
1011 | 1011 | ||
1012 | vega10_program_gc_didt_config_registers(hwmgr, GCDiDtDroopCtrlConfig_vega10); | 1012 | vega10_program_gc_didt_config_registers(hwmgr, GCDiDtDroopCtrlConfig_vega10); |
1013 | if (PP_CAP(PHM_PlatformCaps_GCEDC)) | 1013 | if (PP_CAP(PHM_PlatformCaps_GCEDC)) |
@@ -1024,11 +1024,11 @@ static int vega10_disable_psm_gc_didt_config(struct pp_hwmgr *hwmgr) | |||
1024 | struct amdgpu_device *adev = hwmgr->adev; | 1024 | struct amdgpu_device *adev = hwmgr->adev; |
1025 | uint32_t data; | 1025 | uint32_t data; |
1026 | 1026 | ||
1027 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 1027 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
1028 | 1028 | ||
1029 | vega10_didt_set_mask(hwmgr, false); | 1029 | vega10_didt_set_mask(hwmgr, false); |
1030 | 1030 | ||
1031 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 1031 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
1032 | 1032 | ||
1033 | if (PP_CAP(PHM_PlatformCaps_GCEDC)) { | 1033 | if (PP_CAP(PHM_PlatformCaps_GCEDC)) { |
1034 | data = 0x00000000; | 1034 | data = 0x00000000; |
@@ -1049,7 +1049,7 @@ static int vega10_enable_se_edc_config(struct pp_hwmgr *hwmgr) | |||
1049 | 1049 | ||
1050 | num_se = adev->gfx.config.max_shader_engines; | 1050 | num_se = adev->gfx.config.max_shader_engines; |
1051 | 1051 | ||
1052 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 1052 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
1053 | 1053 | ||
1054 | mutex_lock(&adev->grbm_idx_mutex); | 1054 | mutex_lock(&adev->grbm_idx_mutex); |
1055 | for (count = 0; count < num_se; count++) { | 1055 | for (count = 0; count < num_se; count++) { |
@@ -1070,7 +1070,7 @@ static int vega10_enable_se_edc_config(struct pp_hwmgr *hwmgr) | |||
1070 | 1070 | ||
1071 | vega10_didt_set_mask(hwmgr, true); | 1071 | vega10_didt_set_mask(hwmgr, true); |
1072 | 1072 | ||
1073 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 1073 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
1074 | 1074 | ||
1075 | return 0; | 1075 | return 0; |
1076 | } | 1076 | } |
@@ -1079,11 +1079,11 @@ static int vega10_disable_se_edc_config(struct pp_hwmgr *hwmgr) | |||
1079 | { | 1079 | { |
1080 | struct amdgpu_device *adev = hwmgr->adev; | 1080 | struct amdgpu_device *adev = hwmgr->adev; |
1081 | 1081 | ||
1082 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 1082 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
1083 | 1083 | ||
1084 | vega10_didt_set_mask(hwmgr, false); | 1084 | vega10_didt_set_mask(hwmgr, false); |
1085 | 1085 | ||
1086 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 1086 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
1087 | 1087 | ||
1088 | return 0; | 1088 | return 0; |
1089 | } | 1089 | } |
@@ -1097,7 +1097,7 @@ static int vega10_enable_psm_gc_edc_config(struct pp_hwmgr *hwmgr) | |||
1097 | 1097 | ||
1098 | num_se = adev->gfx.config.max_shader_engines; | 1098 | num_se = adev->gfx.config.max_shader_engines; |
1099 | 1099 | ||
1100 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 1100 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
1101 | 1101 | ||
1102 | vega10_program_gc_didt_config_registers(hwmgr, AvfsPSMResetConfig_vega10); | 1102 | vega10_program_gc_didt_config_registers(hwmgr, AvfsPSMResetConfig_vega10); |
1103 | 1103 | ||
@@ -1118,7 +1118,7 @@ static int vega10_enable_psm_gc_edc_config(struct pp_hwmgr *hwmgr) | |||
1118 | 1118 | ||
1119 | vega10_didt_set_mask(hwmgr, true); | 1119 | vega10_didt_set_mask(hwmgr, true); |
1120 | 1120 | ||
1121 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 1121 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
1122 | 1122 | ||
1123 | vega10_program_gc_didt_config_registers(hwmgr, PSMGCEDCDroopCtrlConfig_vega10); | 1123 | vega10_program_gc_didt_config_registers(hwmgr, PSMGCEDCDroopCtrlConfig_vega10); |
1124 | 1124 | ||
@@ -1138,11 +1138,11 @@ static int vega10_disable_psm_gc_edc_config(struct pp_hwmgr *hwmgr) | |||
1138 | struct amdgpu_device *adev = hwmgr->adev; | 1138 | struct amdgpu_device *adev = hwmgr->adev; |
1139 | uint32_t data; | 1139 | uint32_t data; |
1140 | 1140 | ||
1141 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 1141 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
1142 | 1142 | ||
1143 | vega10_didt_set_mask(hwmgr, false); | 1143 | vega10_didt_set_mask(hwmgr, false); |
1144 | 1144 | ||
1145 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 1145 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
1146 | 1146 | ||
1147 | if (PP_CAP(PHM_PlatformCaps_GCEDC)) { | 1147 | if (PP_CAP(PHM_PlatformCaps_GCEDC)) { |
1148 | data = 0x00000000; | 1148 | data = 0x00000000; |
@@ -1160,7 +1160,7 @@ static int vega10_enable_se_edc_force_stall_config(struct pp_hwmgr *hwmgr) | |||
1160 | struct amdgpu_device *adev = hwmgr->adev; | 1160 | struct amdgpu_device *adev = hwmgr->adev; |
1161 | int result; | 1161 | int result; |
1162 | 1162 | ||
1163 | adev->gfx.rlc.funcs->enter_safe_mode(adev); | 1163 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
1164 | 1164 | ||
1165 | mutex_lock(&adev->grbm_idx_mutex); | 1165 | mutex_lock(&adev->grbm_idx_mutex); |
1166 | WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, 0xE0000000); | 1166 | WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, 0xE0000000); |
@@ -1173,7 +1173,7 @@ static int vega10_enable_se_edc_force_stall_config(struct pp_hwmgr *hwmgr) | |||
1173 | 1173 | ||
1174 | vega10_didt_set_mask(hwmgr, false); | 1174 | vega10_didt_set_mask(hwmgr, false); |
1175 | 1175 | ||
1176 | adev->gfx.rlc.funcs->exit_safe_mode(adev); | 1176 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
1177 | 1177 | ||
1178 | return 0; | 1178 | return 0; |
1179 | } | 1179 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c index 57143d51e3ee..f2daf00cc911 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | |||
@@ -120,6 +120,7 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr) | |||
120 | data->registry_data.disable_auto_wattman = 1; | 120 | data->registry_data.disable_auto_wattman = 1; |
121 | data->registry_data.auto_wattman_debug = 0; | 121 | data->registry_data.auto_wattman_debug = 0; |
122 | data->registry_data.auto_wattman_sample_period = 100; | 122 | data->registry_data.auto_wattman_sample_period = 100; |
123 | data->registry_data.fclk_gfxclk_ratio = 0x3F6CCCCD; | ||
123 | data->registry_data.auto_wattman_threshold = 50; | 124 | data->registry_data.auto_wattman_threshold = 50; |
124 | data->registry_data.gfxoff_controlled_by_driver = 1; | 125 | data->registry_data.gfxoff_controlled_by_driver = 1; |
125 | data->gfxoff_allowed = false; | 126 | data->gfxoff_allowed = false; |
@@ -829,6 +830,28 @@ static int vega20_enable_all_smu_features(struct pp_hwmgr *hwmgr) | |||
829 | return 0; | 830 | return 0; |
830 | } | 831 | } |
831 | 832 | ||
833 | static int vega20_notify_smc_display_change(struct pp_hwmgr *hwmgr) | ||
834 | { | ||
835 | struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); | ||
836 | |||
837 | if (data->smu_features[GNLD_DPM_UCLK].enabled) | ||
838 | return smum_send_msg_to_smc_with_parameter(hwmgr, | ||
839 | PPSMC_MSG_SetUclkFastSwitch, | ||
840 | 1); | ||
841 | |||
842 | return 0; | ||
843 | } | ||
844 | |||
845 | static int vega20_send_clock_ratio(struct pp_hwmgr *hwmgr) | ||
846 | { | ||
847 | struct vega20_hwmgr *data = | ||
848 | (struct vega20_hwmgr *)(hwmgr->backend); | ||
849 | |||
850 | return smum_send_msg_to_smc_with_parameter(hwmgr, | ||
851 | PPSMC_MSG_SetFclkGfxClkRatio, | ||
852 | data->registry_data.fclk_gfxclk_ratio); | ||
853 | } | ||
854 | |||
832 | static int vega20_disable_all_smu_features(struct pp_hwmgr *hwmgr) | 855 | static int vega20_disable_all_smu_features(struct pp_hwmgr *hwmgr) |
833 | { | 856 | { |
834 | struct vega20_hwmgr *data = | 857 | struct vega20_hwmgr *data = |
@@ -1532,6 +1555,16 @@ static int vega20_enable_dpm_tasks(struct pp_hwmgr *hwmgr) | |||
1532 | "[EnableDPMTasks] Failed to enable all smu features!", | 1555 | "[EnableDPMTasks] Failed to enable all smu features!", |
1533 | return result); | 1556 | return result); |
1534 | 1557 | ||
1558 | result = vega20_notify_smc_display_change(hwmgr); | ||
1559 | PP_ASSERT_WITH_CODE(!result, | ||
1560 | "[EnableDPMTasks] Failed to notify smc display change!", | ||
1561 | return result); | ||
1562 | |||
1563 | result = vega20_send_clock_ratio(hwmgr); | ||
1564 | PP_ASSERT_WITH_CODE(!result, | ||
1565 | "[EnableDPMTasks] Failed to send clock ratio!", | ||
1566 | return result); | ||
1567 | |||
1535 | /* Initialize UVD/VCE powergating state */ | 1568 | /* Initialize UVD/VCE powergating state */ |
1536 | vega20_init_powergate_state(hwmgr); | 1569 | vega20_init_powergate_state(hwmgr); |
1537 | 1570 | ||
@@ -1972,19 +2005,6 @@ static int vega20_read_sensor(struct pp_hwmgr *hwmgr, int idx, | |||
1972 | return ret; | 2005 | return ret; |
1973 | } | 2006 | } |
1974 | 2007 | ||
1975 | static int vega20_notify_smc_display_change(struct pp_hwmgr *hwmgr, | ||
1976 | bool has_disp) | ||
1977 | { | ||
1978 | struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); | ||
1979 | |||
1980 | if (data->smu_features[GNLD_DPM_UCLK].enabled) | ||
1981 | return smum_send_msg_to_smc_with_parameter(hwmgr, | ||
1982 | PPSMC_MSG_SetUclkFastSwitch, | ||
1983 | has_disp ? 1 : 0); | ||
1984 | |||
1985 | return 0; | ||
1986 | } | ||
1987 | |||
1988 | int vega20_display_clock_voltage_request(struct pp_hwmgr *hwmgr, | 2008 | int vega20_display_clock_voltage_request(struct pp_hwmgr *hwmgr, |
1989 | struct pp_display_clock_request *clock_req) | 2009 | struct pp_display_clock_request *clock_req) |
1990 | { | 2010 | { |
@@ -2044,13 +2064,6 @@ static int vega20_notify_smc_display_config_after_ps_adjustment( | |||
2044 | struct pp_display_clock_request clock_req; | 2064 | struct pp_display_clock_request clock_req; |
2045 | int ret = 0; | 2065 | int ret = 0; |
2046 | 2066 | ||
2047 | if ((hwmgr->display_config->num_display > 1) && | ||
2048 | !hwmgr->display_config->multi_monitor_in_sync && | ||
2049 | !hwmgr->display_config->nb_pstate_switch_disable) | ||
2050 | vega20_notify_smc_display_change(hwmgr, false); | ||
2051 | else | ||
2052 | vega20_notify_smc_display_change(hwmgr, true); | ||
2053 | |||
2054 | min_clocks.dcefClock = hwmgr->display_config->min_dcef_set_clk; | 2067 | min_clocks.dcefClock = hwmgr->display_config->min_dcef_set_clk; |
2055 | min_clocks.dcefClockInSR = hwmgr->display_config->min_dcef_deep_sleep_set_clk; | 2068 | min_clocks.dcefClockInSR = hwmgr->display_config->min_dcef_deep_sleep_set_clk; |
2056 | min_clocks.memoryClock = hwmgr->display_config->min_mem_set_clock; | 2069 | min_clocks.memoryClock = hwmgr->display_config->min_mem_set_clock; |
@@ -2742,7 +2755,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, | |||
2742 | for (i = 0; i < clocks.num_levels; i++) | 2755 | for (i = 0; i < clocks.num_levels; i++) |
2743 | size += sprintf(buf + size, "%d: %uMhz %s\n", | 2756 | size += sprintf(buf + size, "%d: %uMhz %s\n", |
2744 | i, clocks.data[i].clocks_in_khz / 1000, | 2757 | i, clocks.data[i].clocks_in_khz / 1000, |
2745 | (clocks.data[i].clocks_in_khz == now) ? "*" : ""); | 2758 | (clocks.data[i].clocks_in_khz == now * 10) ? "*" : ""); |
2746 | break; | 2759 | break; |
2747 | 2760 | ||
2748 | case PP_MCLK: | 2761 | case PP_MCLK: |
@@ -2759,7 +2772,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, | |||
2759 | for (i = 0; i < clocks.num_levels; i++) | 2772 | for (i = 0; i < clocks.num_levels; i++) |
2760 | size += sprintf(buf + size, "%d: %uMhz %s\n", | 2773 | size += sprintf(buf + size, "%d: %uMhz %s\n", |
2761 | i, clocks.data[i].clocks_in_khz / 1000, | 2774 | i, clocks.data[i].clocks_in_khz / 1000, |
2762 | (clocks.data[i].clocks_in_khz == now) ? "*" : ""); | 2775 | (clocks.data[i].clocks_in_khz == now * 10) ? "*" : ""); |
2763 | break; | 2776 | break; |
2764 | 2777 | ||
2765 | case PP_PCIE: | 2778 | case PP_PCIE: |
@@ -3441,109 +3454,64 @@ static int vega20_get_thermal_temperature_range(struct pp_hwmgr *hwmgr, | |||
3441 | 3454 | ||
3442 | static const struct pp_hwmgr_func vega20_hwmgr_funcs = { | 3455 | static const struct pp_hwmgr_func vega20_hwmgr_funcs = { |
3443 | /* init/fini related */ | 3456 | /* init/fini related */ |
3444 | .backend_init = | 3457 | .backend_init = vega20_hwmgr_backend_init, |
3445 | vega20_hwmgr_backend_init, | 3458 | .backend_fini = vega20_hwmgr_backend_fini, |
3446 | .backend_fini = | 3459 | .asic_setup = vega20_setup_asic_task, |
3447 | vega20_hwmgr_backend_fini, | 3460 | .power_off_asic = vega20_power_off_asic, |
3448 | .asic_setup = | 3461 | .dynamic_state_management_enable = vega20_enable_dpm_tasks, |
3449 | vega20_setup_asic_task, | 3462 | .dynamic_state_management_disable = vega20_disable_dpm_tasks, |
3450 | .power_off_asic = | ||
3451 | vega20_power_off_asic, | ||
3452 | .dynamic_state_management_enable = | ||
3453 | vega20_enable_dpm_tasks, | ||
3454 | .dynamic_state_management_disable = | ||
3455 | vega20_disable_dpm_tasks, | ||
3456 | /* power state related */ | 3463 | /* power state related */ |
3457 | .apply_clocks_adjust_rules = | 3464 | .apply_clocks_adjust_rules = vega20_apply_clocks_adjust_rules, |
3458 | vega20_apply_clocks_adjust_rules, | 3465 | .pre_display_config_changed = vega20_pre_display_configuration_changed_task, |
3459 | .pre_display_config_changed = | 3466 | .display_config_changed = vega20_display_configuration_changed_task, |
3460 | vega20_pre_display_configuration_changed_task, | ||
3461 | .display_config_changed = | ||
3462 | vega20_display_configuration_changed_task, | ||
3463 | .check_smc_update_required_for_display_configuration = | 3467 | .check_smc_update_required_for_display_configuration = |
3464 | vega20_check_smc_update_required_for_display_configuration, | 3468 | vega20_check_smc_update_required_for_display_configuration, |
3465 | .notify_smc_display_config_after_ps_adjustment = | 3469 | .notify_smc_display_config_after_ps_adjustment = |
3466 | vega20_notify_smc_display_config_after_ps_adjustment, | 3470 | vega20_notify_smc_display_config_after_ps_adjustment, |
3467 | /* export to DAL */ | 3471 | /* export to DAL */ |
3468 | .get_sclk = | 3472 | .get_sclk = vega20_dpm_get_sclk, |
3469 | vega20_dpm_get_sclk, | 3473 | .get_mclk = vega20_dpm_get_mclk, |
3470 | .get_mclk = | 3474 | .get_dal_power_level = vega20_get_dal_power_level, |
3471 | vega20_dpm_get_mclk, | 3475 | .get_clock_by_type_with_latency = vega20_get_clock_by_type_with_latency, |
3472 | .get_dal_power_level = | 3476 | .get_clock_by_type_with_voltage = vega20_get_clock_by_type_with_voltage, |
3473 | vega20_get_dal_power_level, | 3477 | .set_watermarks_for_clocks_ranges = vega20_set_watermarks_for_clocks_ranges, |
3474 | .get_clock_by_type_with_latency = | 3478 | .display_clock_voltage_request = vega20_display_clock_voltage_request, |
3475 | vega20_get_clock_by_type_with_latency, | 3479 | .get_performance_level = vega20_get_performance_level, |
3476 | .get_clock_by_type_with_voltage = | ||
3477 | vega20_get_clock_by_type_with_voltage, | ||
3478 | .set_watermarks_for_clocks_ranges = | ||
3479 | vega20_set_watermarks_for_clocks_ranges, | ||
3480 | .display_clock_voltage_request = | ||
3481 | vega20_display_clock_voltage_request, | ||
3482 | .get_performance_level = | ||
3483 | vega20_get_performance_level, | ||
3484 | /* UMD pstate, profile related */ | 3480 | /* UMD pstate, profile related */ |
3485 | .force_dpm_level = | 3481 | .force_dpm_level = vega20_dpm_force_dpm_level, |
3486 | vega20_dpm_force_dpm_level, | 3482 | .get_power_profile_mode = vega20_get_power_profile_mode, |
3487 | .get_power_profile_mode = | 3483 | .set_power_profile_mode = vega20_set_power_profile_mode, |
3488 | vega20_get_power_profile_mode, | ||
3489 | .set_power_profile_mode = | ||
3490 | vega20_set_power_profile_mode, | ||
3491 | /* od related */ | 3484 | /* od related */ |
3492 | .set_power_limit = | 3485 | .set_power_limit = vega20_set_power_limit, |
3493 | vega20_set_power_limit, | 3486 | .get_sclk_od = vega20_get_sclk_od, |
3494 | .get_sclk_od = | 3487 | .set_sclk_od = vega20_set_sclk_od, |
3495 | vega20_get_sclk_od, | 3488 | .get_mclk_od = vega20_get_mclk_od, |
3496 | .set_sclk_od = | 3489 | .set_mclk_od = vega20_set_mclk_od, |
3497 | vega20_set_sclk_od, | 3490 | .odn_edit_dpm_table = vega20_odn_edit_dpm_table, |
3498 | .get_mclk_od = | ||
3499 | vega20_get_mclk_od, | ||
3500 | .set_mclk_od = | ||
3501 | vega20_set_mclk_od, | ||
3502 | .odn_edit_dpm_table = | ||
3503 | vega20_odn_edit_dpm_table, | ||
3504 | /* for sysfs to retrive/set gfxclk/memclk */ | 3491 | /* for sysfs to retrive/set gfxclk/memclk */ |
3505 | .force_clock_level = | 3492 | .force_clock_level = vega20_force_clock_level, |
3506 | vega20_force_clock_level, | 3493 | .print_clock_levels = vega20_print_clock_levels, |
3507 | .print_clock_levels = | 3494 | .read_sensor = vega20_read_sensor, |
3508 | vega20_print_clock_levels, | ||
3509 | .read_sensor = | ||
3510 | vega20_read_sensor, | ||
3511 | /* powergate related */ | 3495 | /* powergate related */ |
3512 | .powergate_uvd = | 3496 | .powergate_uvd = vega20_power_gate_uvd, |
3513 | vega20_power_gate_uvd, | 3497 | .powergate_vce = vega20_power_gate_vce, |
3514 | .powergate_vce = | ||
3515 | vega20_power_gate_vce, | ||
3516 | /* thermal related */ | 3498 | /* thermal related */ |
3517 | .start_thermal_controller = | 3499 | .start_thermal_controller = vega20_start_thermal_controller, |
3518 | vega20_start_thermal_controller, | 3500 | .stop_thermal_controller = vega20_thermal_stop_thermal_controller, |
3519 | .stop_thermal_controller = | 3501 | .get_thermal_temperature_range = vega20_get_thermal_temperature_range, |
3520 | vega20_thermal_stop_thermal_controller, | 3502 | .register_irq_handlers = smu9_register_irq_handlers, |
3521 | .get_thermal_temperature_range = | 3503 | .disable_smc_firmware_ctf = vega20_thermal_disable_alert, |
3522 | vega20_get_thermal_temperature_range, | ||
3523 | .register_irq_handlers = | ||
3524 | smu9_register_irq_handlers, | ||
3525 | .disable_smc_firmware_ctf = | ||
3526 | vega20_thermal_disable_alert, | ||
3527 | /* fan control related */ | 3504 | /* fan control related */ |
3528 | .get_fan_speed_percent = | 3505 | .get_fan_speed_percent = vega20_fan_ctrl_get_fan_speed_percent, |
3529 | vega20_fan_ctrl_get_fan_speed_percent, | 3506 | .set_fan_speed_percent = vega20_fan_ctrl_set_fan_speed_percent, |
3530 | .set_fan_speed_percent = | 3507 | .get_fan_speed_info = vega20_fan_ctrl_get_fan_speed_info, |
3531 | vega20_fan_ctrl_set_fan_speed_percent, | 3508 | .get_fan_speed_rpm = vega20_fan_ctrl_get_fan_speed_rpm, |
3532 | .get_fan_speed_info = | 3509 | .set_fan_speed_rpm = vega20_fan_ctrl_set_fan_speed_rpm, |
3533 | vega20_fan_ctrl_get_fan_speed_info, | 3510 | .get_fan_control_mode = vega20_get_fan_control_mode, |
3534 | .get_fan_speed_rpm = | 3511 | .set_fan_control_mode = vega20_set_fan_control_mode, |
3535 | vega20_fan_ctrl_get_fan_speed_rpm, | ||
3536 | .set_fan_speed_rpm = | ||
3537 | vega20_fan_ctrl_set_fan_speed_rpm, | ||
3538 | .get_fan_control_mode = | ||
3539 | vega20_get_fan_control_mode, | ||
3540 | .set_fan_control_mode = | ||
3541 | vega20_set_fan_control_mode, | ||
3542 | /* smu memory related */ | 3512 | /* smu memory related */ |
3543 | .notify_cac_buffer_info = | 3513 | .notify_cac_buffer_info = vega20_notify_cac_buffer_info, |
3544 | vega20_notify_cac_buffer_info, | 3514 | .enable_mgpu_fan_boost = vega20_enable_mgpu_fan_boost, |
3545 | .enable_mgpu_fan_boost = | ||
3546 | vega20_enable_mgpu_fan_boost, | ||
3547 | }; | 3515 | }; |
3548 | 3516 | ||
3549 | int vega20_hwmgr_init(struct pp_hwmgr *hwmgr) | 3517 | int vega20_hwmgr_init(struct pp_hwmgr *hwmgr) |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h index 56fe6a0d42e8..25faaa5c5b10 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h | |||
@@ -328,6 +328,7 @@ struct vega20_registry_data { | |||
328 | uint8_t disable_auto_wattman; | 328 | uint8_t disable_auto_wattman; |
329 | uint32_t auto_wattman_debug; | 329 | uint32_t auto_wattman_debug; |
330 | uint32_t auto_wattman_sample_period; | 330 | uint32_t auto_wattman_sample_period; |
331 | uint32_t fclk_gfxclk_ratio; | ||
331 | uint8_t auto_wattman_threshold; | 332 | uint8_t auto_wattman_threshold; |
332 | uint8_t log_avfs_param; | 333 | uint8_t log_avfs_param; |
333 | uint8_t enable_enginess; | 334 | uint8_t enable_enginess; |
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index e5a60aa44b5d..07d180ce4d18 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | |||
@@ -28,7 +28,6 @@ | |||
28 | #include "hardwaremanager.h" | 28 | #include "hardwaremanager.h" |
29 | #include "hwmgr_ppt.h" | 29 | #include "hwmgr_ppt.h" |
30 | #include "ppatomctrl.h" | 30 | #include "ppatomctrl.h" |
31 | #include "hwmgr_ppt.h" | ||
32 | #include "power_state.h" | 31 | #include "power_state.h" |
33 | #include "smu_helper.h" | 32 | #include "smu_helper.h" |
34 | 33 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu7_common.h b/drivers/gpu/drm/amd/powerplay/inc/smu7_common.h index 65eb630bfea3..94bf7b649c20 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smu7_common.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smu7_common.h | |||
@@ -40,10 +40,6 @@ | |||
40 | #include "bif/bif_5_0_d.h" | 40 | #include "bif/bif_5_0_d.h" |
41 | #include "bif/bif_5_0_sh_mask.h" | 41 | #include "bif/bif_5_0_sh_mask.h" |
42 | 42 | ||
43 | |||
44 | #include "bif/bif_5_0_d.h" | ||
45 | #include "bif/bif_5_0_sh_mask.h" | ||
46 | |||
47 | #include "dce/dce_10_0_d.h" | 43 | #include "dce/dce_10_0_d.h" |
48 | #include "dce/dce_10_0_sh_mask.h" | 44 | #include "dce/dce_10_0_sh_mask.h" |
49 | 45 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/inc/vega20_ppsmc.h b/drivers/gpu/drm/amd/powerplay/inc/vega20_ppsmc.h index 45d64a81e945..4f63a736ea0e 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/vega20_ppsmc.h +++ b/drivers/gpu/drm/amd/powerplay/inc/vega20_ppsmc.h | |||
@@ -105,7 +105,8 @@ | |||
105 | #define PPSMC_MSG_SetSystemVirtualDramAddrHigh 0x4B | 105 | #define PPSMC_MSG_SetSystemVirtualDramAddrHigh 0x4B |
106 | #define PPSMC_MSG_SetSystemVirtualDramAddrLow 0x4C | 106 | #define PPSMC_MSG_SetSystemVirtualDramAddrLow 0x4C |
107 | #define PPSMC_MSG_WaflTest 0x4D | 107 | #define PPSMC_MSG_WaflTest 0x4D |
108 | // Unused ID 0x4E to 0x50 | 108 | #define PPSMC_MSG_SetFclkGfxClkRatio 0x4E |
109 | // Unused ID 0x4F to 0x50 | ||
109 | #define PPSMC_MSG_AllowGfxOff 0x51 | 110 | #define PPSMC_MSG_AllowGfxOff 0x51 |
110 | #define PPSMC_MSG_DisallowGfxOff 0x52 | 111 | #define PPSMC_MSG_DisallowGfxOff 0x52 |
111 | #define PPSMC_MSG_GetPptLimit 0x53 | 112 | #define PPSMC_MSG_GetPptLimit 0x53 |
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c index 872d3824337b..2b2c26616902 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c | |||
@@ -44,7 +44,6 @@ | |||
44 | 44 | ||
45 | #include "smu7_hwmgr.h" | 45 | #include "smu7_hwmgr.h" |
46 | #include "hardwaremanager.h" | 46 | #include "hardwaremanager.h" |
47 | #include "ppatomctrl.h" | ||
48 | #include "atombios.h" | 47 | #include "atombios.h" |
49 | #include "pppcielanes.h" | 48 | #include "pppcielanes.h" |
50 | 49 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c index d0eb8ab50148..d111dd4e03d7 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include "rv_ppsmc.h" | 29 | #include "rv_ppsmc.h" |
30 | #include "smu10_driver_if.h" | 30 | #include "smu10_driver_if.h" |
31 | #include "smu10.h" | 31 | #include "smu10.h" |
32 | #include "ppatomctrl.h" | ||
33 | #include "pp_debug.h" | 32 | #include "pp_debug.h" |
34 | 33 | ||
35 | 34 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c index 09b844ec3eab..e2787e14a500 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/gfp.h> | 25 | #include <linux/gfp.h> |
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/ktime.h> | ||
27 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
28 | #include <linux/types.h> | 29 | #include <linux/types.h> |
29 | 30 | ||
@@ -61,9 +62,13 @@ static uint32_t smu8_get_argument(struct pp_hwmgr *hwmgr) | |||
61 | mmSMU_MP1_SRBM2P_ARG_0); | 62 | mmSMU_MP1_SRBM2P_ARG_0); |
62 | } | 63 | } |
63 | 64 | ||
64 | static int smu8_send_msg_to_smc_async(struct pp_hwmgr *hwmgr, uint16_t msg) | 65 | /* Send a message to the SMC, and wait for its response.*/ |
66 | static int smu8_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, | ||
67 | uint16_t msg, uint32_t parameter) | ||
65 | { | 68 | { |
66 | int result = 0; | 69 | int result = 0; |
70 | ktime_t t_start; | ||
71 | s64 elapsed_us; | ||
67 | 72 | ||
68 | if (hwmgr == NULL || hwmgr->device == NULL) | 73 | if (hwmgr == NULL || hwmgr->device == NULL) |
69 | return -EINVAL; | 74 | return -EINVAL; |
@@ -74,28 +79,31 @@ static int smu8_send_msg_to_smc_async(struct pp_hwmgr *hwmgr, uint16_t msg) | |||
74 | /* Read the last message to SMU, to report actual cause */ | 79 | /* Read the last message to SMU, to report actual cause */ |
75 | uint32_t val = cgs_read_register(hwmgr->device, | 80 | uint32_t val = cgs_read_register(hwmgr->device, |
76 | mmSMU_MP1_SRBM2P_MSG_0); | 81 | mmSMU_MP1_SRBM2P_MSG_0); |
77 | pr_err("smu8_send_msg_to_smc_async (0x%04x) failed\n", msg); | 82 | pr_err("%s(0x%04x) aborted; SMU still servicing msg (0x%04x)\n", |
78 | pr_err("SMU still servicing msg (0x%04x)\n", val); | 83 | __func__, msg, val); |
79 | return result; | 84 | return result; |
80 | } | 85 | } |
86 | t_start = ktime_get(); | ||
87 | |||
88 | cgs_write_register(hwmgr->device, mmSMU_MP1_SRBM2P_ARG_0, parameter); | ||
81 | 89 | ||
82 | cgs_write_register(hwmgr->device, mmSMU_MP1_SRBM2P_RESP_0, 0); | 90 | cgs_write_register(hwmgr->device, mmSMU_MP1_SRBM2P_RESP_0, 0); |
83 | cgs_write_register(hwmgr->device, mmSMU_MP1_SRBM2P_MSG_0, msg); | 91 | cgs_write_register(hwmgr->device, mmSMU_MP1_SRBM2P_MSG_0, msg); |
84 | 92 | ||
85 | return 0; | 93 | result = PHM_WAIT_FIELD_UNEQUAL(hwmgr, |
94 | SMU_MP1_SRBM2P_RESP_0, CONTENT, 0); | ||
95 | |||
96 | elapsed_us = ktime_us_delta(ktime_get(), t_start); | ||
97 | |||
98 | WARN(result, "%s(0x%04x, %#x) timed out after %lld us\n", | ||
99 | __func__, msg, parameter, elapsed_us); | ||
100 | |||
101 | return result; | ||
86 | } | 102 | } |
87 | 103 | ||
88 | /* Send a message to the SMC, and wait for its response.*/ | ||
89 | static int smu8_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg) | 104 | static int smu8_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg) |
90 | { | 105 | { |
91 | int result = 0; | 106 | return smu8_send_msg_to_smc_with_parameter(hwmgr, msg, 0); |
92 | |||
93 | result = smu8_send_msg_to_smc_async(hwmgr, msg); | ||
94 | if (result != 0) | ||
95 | return result; | ||
96 | |||
97 | return PHM_WAIT_FIELD_UNEQUAL(hwmgr, | ||
98 | SMU_MP1_SRBM2P_RESP_0, CONTENT, 0); | ||
99 | } | 107 | } |
100 | 108 | ||
101 | static int smu8_set_smc_sram_address(struct pp_hwmgr *hwmgr, | 109 | static int smu8_set_smc_sram_address(struct pp_hwmgr *hwmgr, |
@@ -135,17 +143,6 @@ static int smu8_write_smc_sram_dword(struct pp_hwmgr *hwmgr, | |||
135 | return result; | 143 | return result; |
136 | } | 144 | } |
137 | 145 | ||
138 | static int smu8_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, | ||
139 | uint16_t msg, uint32_t parameter) | ||
140 | { | ||
141 | if (hwmgr == NULL || hwmgr->device == NULL) | ||
142 | return -EINVAL; | ||
143 | |||
144 | cgs_write_register(hwmgr->device, mmSMU_MP1_SRBM2P_ARG_0, parameter); | ||
145 | |||
146 | return smu8_send_msg_to_smc(hwmgr, msg); | ||
147 | } | ||
148 | |||
149 | static int smu8_check_fw_load_finish(struct pp_hwmgr *hwmgr, | 146 | static int smu8_check_fw_load_finish(struct pp_hwmgr *hwmgr, |
150 | uint32_t firmware) | 147 | uint32_t firmware) |
151 | { | 148 | { |
@@ -737,6 +734,10 @@ static int smu8_start_smu(struct pp_hwmgr *hwmgr) | |||
737 | 734 | ||
738 | cgs_write_register(hwmgr->device, mmMP0PUB_IND_INDEX, index); | 735 | cgs_write_register(hwmgr->device, mmMP0PUB_IND_INDEX, index); |
739 | hwmgr->smu_version = cgs_read_register(hwmgr->device, mmMP0PUB_IND_DATA); | 736 | hwmgr->smu_version = cgs_read_register(hwmgr->device, mmMP0PUB_IND_DATA); |
737 | pr_info("smu version %02d.%02d.%02d\n", | ||
738 | ((hwmgr->smu_version >> 16) & 0xFF), | ||
739 | ((hwmgr->smu_version >> 8) & 0xFF), | ||
740 | (hwmgr->smu_version & 0xFF)); | ||
740 | adev->pm.fw_version = hwmgr->smu_version >> 8; | 741 | adev->pm.fw_version = hwmgr->smu_version >> 8; |
741 | 742 | ||
742 | return smu8_request_smu_load_fw(hwmgr); | 743 | return smu8_request_smu_load_fw(hwmgr); |
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c index 99d5e4f98f49..a6edd5df33b0 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c | |||
@@ -37,10 +37,13 @@ MODULE_FIRMWARE("amdgpu/fiji_smc.bin"); | |||
37 | MODULE_FIRMWARE("amdgpu/polaris10_smc.bin"); | 37 | MODULE_FIRMWARE("amdgpu/polaris10_smc.bin"); |
38 | MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin"); | 38 | MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin"); |
39 | MODULE_FIRMWARE("amdgpu/polaris10_k_smc.bin"); | 39 | MODULE_FIRMWARE("amdgpu/polaris10_k_smc.bin"); |
40 | MODULE_FIRMWARE("amdgpu/polaris10_k2_smc.bin"); | ||
40 | MODULE_FIRMWARE("amdgpu/polaris11_smc.bin"); | 41 | MODULE_FIRMWARE("amdgpu/polaris11_smc.bin"); |
41 | MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin"); | 42 | MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin"); |
42 | MODULE_FIRMWARE("amdgpu/polaris11_k_smc.bin"); | 43 | MODULE_FIRMWARE("amdgpu/polaris11_k_smc.bin"); |
44 | MODULE_FIRMWARE("amdgpu/polaris11_k2_smc.bin"); | ||
43 | MODULE_FIRMWARE("amdgpu/polaris12_smc.bin"); | 45 | MODULE_FIRMWARE("amdgpu/polaris12_smc.bin"); |
46 | MODULE_FIRMWARE("amdgpu/polaris12_k_smc.bin"); | ||
44 | MODULE_FIRMWARE("amdgpu/vegam_smc.bin"); | 47 | MODULE_FIRMWARE("amdgpu/vegam_smc.bin"); |
45 | MODULE_FIRMWARE("amdgpu/vega10_smc.bin"); | 48 | MODULE_FIRMWARE("amdgpu/vega10_smc.bin"); |
46 | MODULE_FIRMWARE("amdgpu/vega10_acg_smc.bin"); | 49 | MODULE_FIRMWARE("amdgpu/vega10_acg_smc.bin"); |
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c index 9f71512b2510..1e69300f6175 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c | |||
@@ -40,7 +40,6 @@ | |||
40 | 40 | ||
41 | #include "smu7_hwmgr.h" | 41 | #include "smu7_hwmgr.h" |
42 | #include "hardwaremanager.h" | 42 | #include "hardwaremanager.h" |
43 | #include "ppatomctrl.h" | ||
44 | #include "atombios.h" | 43 | #include "atombios.h" |
45 | #include "pppcielanes.h" | 44 | #include "pppcielanes.h" |
46 | 45 | ||