diff options
author | Olof Johansson <olof@lixom.net> | 2016-06-19 01:59:07 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2016-06-19 01:59:07 -0400 |
commit | 8fd0976702f05042c776848819e5fd2a835f23c9 (patch) | |
tree | 8a87b0e33bf39adcc53b3ee4be61155dab86417b /drivers/gpu/drm/amd/amdgpu | |
parent | 58935f24a996cb55595c29dd5303bd9b778c8b00 (diff) | |
parent | 8f50b8e57442d28e41bb736c173d8a2490549a82 (diff) |
Merge tag 'gpmc-omap-fixes-for-v4.7' of https://github.com/rogerq/linux into fixes
OMAP-GPMC: Fixes for for v4.7-rc cycle:
- Fix omap gpmc EXTRADELAY timing. The DT provided timings
were wrongly used causing devices requiring extra delay timing
to fail.
* tag 'gpmc-omap-fixes-for-v4.7' of https://github.com/rogerq/linux:
memory: omap-gpmc: Fix omap gpmc EXTRADELAY timing
+ Linux 4.7-rc3
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/ci_dpm.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/cik_sdma.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/fiji_dpm.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 28 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/iceland_dpm.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/tonga_dpm.c | 5 |
18 files changed, 185 insertions, 35 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 992f00b65be4..01c36b8d6222 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -799,6 +799,7 @@ struct amdgpu_ring { | |||
799 | unsigned cond_exe_offs; | 799 | unsigned cond_exe_offs; |
800 | u64 cond_exe_gpu_addr; | 800 | u64 cond_exe_gpu_addr; |
801 | volatile u32 *cond_exe_cpu_addr; | 801 | volatile u32 *cond_exe_cpu_addr; |
802 | int vmid; | ||
802 | }; | 803 | }; |
803 | 804 | ||
804 | /* | 805 | /* |
@@ -936,7 +937,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, | |||
936 | unsigned vm_id, uint64_t pd_addr, | 937 | unsigned vm_id, uint64_t pd_addr, |
937 | uint32_t gds_base, uint32_t gds_size, | 938 | uint32_t gds_base, uint32_t gds_size, |
938 | uint32_t gws_base, uint32_t gws_size, | 939 | uint32_t gws_base, uint32_t gws_size, |
939 | uint32_t oa_base, uint32_t oa_size); | 940 | uint32_t oa_base, uint32_t oa_size, |
941 | bool vmid_switch); | ||
940 | void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id); | 942 | void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id); |
941 | uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr); | 943 | uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr); |
942 | int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, | 944 | int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 199f76baf22c..8943099eb135 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | |||
@@ -696,6 +696,17 @@ static uint32_t fw_type_convert(struct cgs_device *cgs_device, uint32_t fw_type) | |||
696 | return result; | 696 | return result; |
697 | } | 697 | } |
698 | 698 | ||
699 | static int amdgpu_cgs_rel_firmware(struct cgs_device *cgs_device, enum cgs_ucode_id type) | ||
700 | { | ||
701 | CGS_FUNC_ADEV; | ||
702 | if ((CGS_UCODE_ID_SMU == type) || (CGS_UCODE_ID_SMU_SK == type)) { | ||
703 | release_firmware(adev->pm.fw); | ||
704 | return 0; | ||
705 | } | ||
706 | /* cannot release other firmware because they are not created by cgs */ | ||
707 | return -EINVAL; | ||
708 | } | ||
709 | |||
699 | static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, | 710 | static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, |
700 | enum cgs_ucode_id type, | 711 | enum cgs_ucode_id type, |
701 | struct cgs_firmware_info *info) | 712 | struct cgs_firmware_info *info) |
@@ -1125,6 +1136,7 @@ static const struct cgs_ops amdgpu_cgs_ops = { | |||
1125 | amdgpu_cgs_pm_query_clock_limits, | 1136 | amdgpu_cgs_pm_query_clock_limits, |
1126 | amdgpu_cgs_set_camera_voltages, | 1137 | amdgpu_cgs_set_camera_voltages, |
1127 | amdgpu_cgs_get_firmware_info, | 1138 | amdgpu_cgs_get_firmware_info, |
1139 | amdgpu_cgs_rel_firmware, | ||
1128 | amdgpu_cgs_set_powergating_state, | 1140 | amdgpu_cgs_set_powergating_state, |
1129 | amdgpu_cgs_set_clockgating_state, | 1141 | amdgpu_cgs_set_clockgating_state, |
1130 | amdgpu_cgs_get_active_displays_info, | 1142 | amdgpu_cgs_get_active_displays_info, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index bb8b149786d7..964f31404f17 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -827,8 +827,10 @@ static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg) | |||
827 | */ | 827 | */ |
828 | static void amdgpu_atombios_fini(struct amdgpu_device *adev) | 828 | static void amdgpu_atombios_fini(struct amdgpu_device *adev) |
829 | { | 829 | { |
830 | if (adev->mode_info.atom_context) | 830 | if (adev->mode_info.atom_context) { |
831 | kfree(adev->mode_info.atom_context->scratch); | 831 | kfree(adev->mode_info.atom_context->scratch); |
832 | kfree(adev->mode_info.atom_context->iio); | ||
833 | } | ||
832 | kfree(adev->mode_info.atom_context); | 834 | kfree(adev->mode_info.atom_context); |
833 | adev->mode_info.atom_context = NULL; | 835 | adev->mode_info.atom_context = NULL; |
834 | kfree(adev->mode_info.atom_card_info); | 836 | kfree(adev->mode_info.atom_card_info); |
@@ -1325,6 +1327,11 @@ static int amdgpu_fini(struct amdgpu_device *adev) | |||
1325 | adev->ip_block_status[i].valid = false; | 1327 | adev->ip_block_status[i].valid = false; |
1326 | } | 1328 | } |
1327 | 1329 | ||
1330 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { | ||
1331 | if (adev->ip_blocks[i].funcs->late_fini) | ||
1332 | adev->ip_blocks[i].funcs->late_fini((void *)adev); | ||
1333 | } | ||
1334 | |||
1328 | return 0; | 1335 | return 0; |
1329 | } | 1336 | } |
1330 | 1337 | ||
@@ -1513,8 +1520,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1513 | amdgpu_atombios_has_gpu_virtualization_table(adev); | 1520 | amdgpu_atombios_has_gpu_virtualization_table(adev); |
1514 | 1521 | ||
1515 | /* Post card if necessary */ | 1522 | /* Post card if necessary */ |
1516 | if (!amdgpu_card_posted(adev) || | 1523 | if (!amdgpu_card_posted(adev)) { |
1517 | adev->virtualization.supports_sr_iov) { | ||
1518 | if (!adev->bios) { | 1524 | if (!adev->bios) { |
1519 | dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); | 1525 | dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); |
1520 | return -EINVAL; | 1526 | return -EINVAL; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 34e35423b78e..7a0b1e50f293 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | |||
@@ -122,6 +122,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
122 | bool skip_preamble, need_ctx_switch; | 122 | bool skip_preamble, need_ctx_switch; |
123 | unsigned patch_offset = ~0; | 123 | unsigned patch_offset = ~0; |
124 | struct amdgpu_vm *vm; | 124 | struct amdgpu_vm *vm; |
125 | int vmid = 0, old_vmid = ring->vmid; | ||
125 | struct fence *hwf; | 126 | struct fence *hwf; |
126 | uint64_t ctx; | 127 | uint64_t ctx; |
127 | 128 | ||
@@ -135,9 +136,11 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
135 | if (job) { | 136 | if (job) { |
136 | vm = job->vm; | 137 | vm = job->vm; |
137 | ctx = job->ctx; | 138 | ctx = job->ctx; |
139 | vmid = job->vm_id; | ||
138 | } else { | 140 | } else { |
139 | vm = NULL; | 141 | vm = NULL; |
140 | ctx = 0; | 142 | ctx = 0; |
143 | vmid = 0; | ||
141 | } | 144 | } |
142 | 145 | ||
143 | if (!ring->ready) { | 146 | if (!ring->ready) { |
@@ -163,7 +166,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
163 | r = amdgpu_vm_flush(ring, job->vm_id, job->vm_pd_addr, | 166 | r = amdgpu_vm_flush(ring, job->vm_id, job->vm_pd_addr, |
164 | job->gds_base, job->gds_size, | 167 | job->gds_base, job->gds_size, |
165 | job->gws_base, job->gws_size, | 168 | job->gws_base, job->gws_size, |
166 | job->oa_base, job->oa_size); | 169 | job->oa_base, job->oa_size, |
170 | (ring->current_ctx == ctx) && (old_vmid != vmid)); | ||
167 | if (r) { | 171 | if (r) { |
168 | amdgpu_ring_undo(ring); | 172 | amdgpu_ring_undo(ring); |
169 | return r; | 173 | return r; |
@@ -180,7 +184,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
180 | need_ctx_switch = ring->current_ctx != ctx; | 184 | need_ctx_switch = ring->current_ctx != ctx; |
181 | for (i = 0; i < num_ibs; ++i) { | 185 | for (i = 0; i < num_ibs; ++i) { |
182 | ib = &ibs[i]; | 186 | ib = &ibs[i]; |
183 | |||
184 | /* drop preamble IBs if we don't have a context switch */ | 187 | /* drop preamble IBs if we don't have a context switch */ |
185 | if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && skip_preamble) | 188 | if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && skip_preamble) |
186 | continue; | 189 | continue; |
@@ -188,6 +191,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
188 | amdgpu_ring_emit_ib(ring, ib, job ? job->vm_id : 0, | 191 | amdgpu_ring_emit_ib(ring, ib, job ? job->vm_id : 0, |
189 | need_ctx_switch); | 192 | need_ctx_switch); |
190 | need_ctx_switch = false; | 193 | need_ctx_switch = false; |
194 | ring->vmid = vmid; | ||
191 | } | 195 | } |
192 | 196 | ||
193 | if (ring->funcs->emit_hdp_invalidate) | 197 | if (ring->funcs->emit_hdp_invalidate) |
@@ -198,6 +202,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
198 | dev_err(adev->dev, "failed to emit fence (%d)\n", r); | 202 | dev_err(adev->dev, "failed to emit fence (%d)\n", r); |
199 | if (job && job->vm_id) | 203 | if (job && job->vm_id) |
200 | amdgpu_vm_reset_id(adev, job->vm_id); | 204 | amdgpu_vm_reset_id(adev, job->vm_id); |
205 | ring->vmid = old_vmid; | ||
201 | amdgpu_ring_undo(ring); | 206 | amdgpu_ring_undo(ring); |
202 | return r; | 207 | return r; |
203 | } | 208 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index 6bd961fb43dc..82256558e0f5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | |||
@@ -183,13 +183,6 @@ static int amdgpu_pp_sw_fini(void *handle) | |||
183 | if (ret) | 183 | if (ret) |
184 | return ret; | 184 | return ret; |
185 | 185 | ||
186 | #ifdef CONFIG_DRM_AMD_POWERPLAY | ||
187 | if (adev->pp_enabled) { | ||
188 | amdgpu_pm_sysfs_fini(adev); | ||
189 | amd_powerplay_fini(adev->powerplay.pp_handle); | ||
190 | } | ||
191 | #endif | ||
192 | |||
193 | return ret; | 186 | return ret; |
194 | } | 187 | } |
195 | 188 | ||
@@ -223,6 +216,22 @@ static int amdgpu_pp_hw_fini(void *handle) | |||
223 | return ret; | 216 | return ret; |
224 | } | 217 | } |
225 | 218 | ||
219 | static void amdgpu_pp_late_fini(void *handle) | ||
220 | { | ||
221 | #ifdef CONFIG_DRM_AMD_POWERPLAY | ||
222 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
223 | |||
224 | if (adev->pp_enabled) { | ||
225 | amdgpu_pm_sysfs_fini(adev); | ||
226 | amd_powerplay_fini(adev->powerplay.pp_handle); | ||
227 | } | ||
228 | |||
229 | if (adev->powerplay.ip_funcs->late_fini) | ||
230 | adev->powerplay.ip_funcs->late_fini( | ||
231 | adev->powerplay.pp_handle); | ||
232 | #endif | ||
233 | } | ||
234 | |||
226 | static int amdgpu_pp_suspend(void *handle) | 235 | static int amdgpu_pp_suspend(void *handle) |
227 | { | 236 | { |
228 | int ret = 0; | 237 | int ret = 0; |
@@ -311,6 +320,7 @@ const struct amd_ip_funcs amdgpu_pp_ip_funcs = { | |||
311 | .sw_fini = amdgpu_pp_sw_fini, | 320 | .sw_fini = amdgpu_pp_sw_fini, |
312 | .hw_init = amdgpu_pp_hw_init, | 321 | .hw_init = amdgpu_pp_hw_init, |
313 | .hw_fini = amdgpu_pp_hw_fini, | 322 | .hw_fini = amdgpu_pp_hw_fini, |
323 | .late_fini = amdgpu_pp_late_fini, | ||
314 | .suspend = amdgpu_pp_suspend, | 324 | .suspend = amdgpu_pp_suspend, |
315 | .resume = amdgpu_pp_resume, | 325 | .resume = amdgpu_pp_resume, |
316 | .is_idle = amdgpu_pp_is_idle, | 326 | .is_idle = amdgpu_pp_is_idle, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 3b02272db678..870f9494252c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | |||
@@ -343,6 +343,7 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring) | |||
343 | ring->ring = NULL; | 343 | ring->ring = NULL; |
344 | ring->ring_obj = NULL; | 344 | ring->ring_obj = NULL; |
345 | 345 | ||
346 | amdgpu_wb_free(ring->adev, ring->cond_exe_offs); | ||
346 | amdgpu_wb_free(ring->adev, ring->fence_offs); | 347 | amdgpu_wb_free(ring->adev, ring->fence_offs); |
347 | amdgpu_wb_free(ring->adev, ring->rptr_offs); | 348 | amdgpu_wb_free(ring->adev, ring->rptr_offs); |
348 | amdgpu_wb_free(ring->adev, ring->wptr_offs); | 349 | amdgpu_wb_free(ring->adev, ring->wptr_offs); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c index 8bf84efafb04..48618ee324eb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c | |||
@@ -115,6 +115,7 @@ int amdgpu_sa_bo_manager_start(struct amdgpu_device *adev, | |||
115 | return r; | 115 | return r; |
116 | } | 116 | } |
117 | r = amdgpu_bo_kmap(sa_manager->bo, &sa_manager->cpu_ptr); | 117 | r = amdgpu_bo_kmap(sa_manager->bo, &sa_manager->cpu_ptr); |
118 | memset(sa_manager->cpu_ptr, 0, sa_manager->size); | ||
118 | amdgpu_bo_unreserve(sa_manager->bo); | 119 | amdgpu_bo_unreserve(sa_manager->bo); |
119 | return r; | 120 | return r; |
120 | } | 121 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index 01abfc21b4a2..e19520c4b4b6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | |||
@@ -253,19 +253,20 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) | |||
253 | { | 253 | { |
254 | int r; | 254 | int r; |
255 | 255 | ||
256 | if (adev->uvd.vcpu_bo == NULL) | 256 | kfree(adev->uvd.saved_bo); |
257 | return 0; | ||
258 | 257 | ||
259 | amd_sched_entity_fini(&adev->uvd.ring.sched, &adev->uvd.entity); | 258 | amd_sched_entity_fini(&adev->uvd.ring.sched, &adev->uvd.entity); |
260 | 259 | ||
261 | r = amdgpu_bo_reserve(adev->uvd.vcpu_bo, false); | 260 | if (adev->uvd.vcpu_bo) { |
262 | if (!r) { | 261 | r = amdgpu_bo_reserve(adev->uvd.vcpu_bo, false); |
263 | amdgpu_bo_kunmap(adev->uvd.vcpu_bo); | 262 | if (!r) { |
264 | amdgpu_bo_unpin(adev->uvd.vcpu_bo); | 263 | amdgpu_bo_kunmap(adev->uvd.vcpu_bo); |
265 | amdgpu_bo_unreserve(adev->uvd.vcpu_bo); | 264 | amdgpu_bo_unpin(adev->uvd.vcpu_bo); |
266 | } | 265 | amdgpu_bo_unreserve(adev->uvd.vcpu_bo); |
266 | } | ||
267 | 267 | ||
268 | amdgpu_bo_unref(&adev->uvd.vcpu_bo); | 268 | amdgpu_bo_unref(&adev->uvd.vcpu_bo); |
269 | } | ||
269 | 270 | ||
270 | amdgpu_ring_fini(&adev->uvd.ring); | 271 | amdgpu_ring_fini(&adev->uvd.ring); |
271 | 272 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 9f36ed30ba11..62a4c127620f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -298,7 +298,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, | |||
298 | unsigned vm_id, uint64_t pd_addr, | 298 | unsigned vm_id, uint64_t pd_addr, |
299 | uint32_t gds_base, uint32_t gds_size, | 299 | uint32_t gds_base, uint32_t gds_size, |
300 | uint32_t gws_base, uint32_t gws_size, | 300 | uint32_t gws_base, uint32_t gws_size, |
301 | uint32_t oa_base, uint32_t oa_size) | 301 | uint32_t oa_base, uint32_t oa_size, |
302 | bool vmid_switch) | ||
302 | { | 303 | { |
303 | struct amdgpu_device *adev = ring->adev; | 304 | struct amdgpu_device *adev = ring->adev; |
304 | struct amdgpu_vm_id *id = &adev->vm_manager.ids[vm_id]; | 305 | struct amdgpu_vm_id *id = &adev->vm_manager.ids[vm_id]; |
@@ -312,8 +313,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, | |||
312 | int r; | 313 | int r; |
313 | 314 | ||
314 | if (ring->funcs->emit_pipeline_sync && ( | 315 | if (ring->funcs->emit_pipeline_sync && ( |
315 | pd_addr != AMDGPU_VM_NO_FLUSH || gds_switch_needed || | 316 | pd_addr != AMDGPU_VM_NO_FLUSH || gds_switch_needed || vmid_switch)) |
316 | ring->type == AMDGPU_RING_TYPE_COMPUTE)) | ||
317 | amdgpu_ring_emit_pipeline_sync(ring); | 317 | amdgpu_ring_emit_pipeline_sync(ring); |
318 | 318 | ||
319 | if (ring->funcs->emit_vm_flush && | 319 | if (ring->funcs->emit_vm_flush && |
diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index ea407db1fbcf..5ec1f1e9c983 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c | |||
@@ -6221,6 +6221,9 @@ static int ci_dpm_sw_fini(void *handle) | |||
6221 | ci_dpm_fini(adev); | 6221 | ci_dpm_fini(adev); |
6222 | mutex_unlock(&adev->pm.mutex); | 6222 | mutex_unlock(&adev->pm.mutex); |
6223 | 6223 | ||
6224 | release_firmware(adev->pm.fw); | ||
6225 | adev->pm.fw = NULL; | ||
6226 | |||
6224 | return 0; | 6227 | return 0; |
6225 | } | 6228 | } |
6226 | 6229 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index 518dca43b133..9dc4e24e31e7 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c | |||
@@ -66,6 +66,16 @@ MODULE_FIRMWARE("radeon/mullins_sdma1.bin"); | |||
66 | 66 | ||
67 | u32 amdgpu_cik_gpu_check_soft_reset(struct amdgpu_device *adev); | 67 | u32 amdgpu_cik_gpu_check_soft_reset(struct amdgpu_device *adev); |
68 | 68 | ||
69 | |||
70 | static void cik_sdma_free_microcode(struct amdgpu_device *adev) | ||
71 | { | ||
72 | int i; | ||
73 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
74 | release_firmware(adev->sdma.instance[i].fw); | ||
75 | adev->sdma.instance[i].fw = NULL; | ||
76 | } | ||
77 | } | ||
78 | |||
69 | /* | 79 | /* |
70 | * sDMA - System DMA | 80 | * sDMA - System DMA |
71 | * Starting with CIK, the GPU has new asynchronous | 81 | * Starting with CIK, the GPU has new asynchronous |
@@ -419,6 +429,8 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev) | |||
419 | /* Initialize the ring buffer's read and write pointers */ | 429 | /* Initialize the ring buffer's read and write pointers */ |
420 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); | 430 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); |
421 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); | 431 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); |
432 | WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0); | ||
433 | WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0); | ||
422 | 434 | ||
423 | /* set the wb address whether it's enabled or not */ | 435 | /* set the wb address whether it's enabled or not */ |
424 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], | 436 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], |
@@ -446,7 +458,12 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev) | |||
446 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); | 458 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
447 | 459 | ||
448 | ring->ready = true; | 460 | ring->ready = true; |
461 | } | ||
462 | |||
463 | cik_sdma_enable(adev, true); | ||
449 | 464 | ||
465 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
466 | ring = &adev->sdma.instance[i].ring; | ||
450 | r = amdgpu_ring_test_ring(ring); | 467 | r = amdgpu_ring_test_ring(ring); |
451 | if (r) { | 468 | if (r) { |
452 | ring->ready = false; | 469 | ring->ready = false; |
@@ -529,8 +546,8 @@ static int cik_sdma_start(struct amdgpu_device *adev) | |||
529 | if (r) | 546 | if (r) |
530 | return r; | 547 | return r; |
531 | 548 | ||
532 | /* unhalt the MEs */ | 549 | /* halt the engine before programing */ |
533 | cik_sdma_enable(adev, true); | 550 | cik_sdma_enable(adev, false); |
534 | 551 | ||
535 | /* start the gfx rings and rlc compute queues */ | 552 | /* start the gfx rings and rlc compute queues */ |
536 | r = cik_sdma_gfx_resume(adev); | 553 | r = cik_sdma_gfx_resume(adev); |
@@ -998,6 +1015,7 @@ static int cik_sdma_sw_fini(void *handle) | |||
998 | for (i = 0; i < adev->sdma.num_instances; i++) | 1015 | for (i = 0; i < adev->sdma.num_instances; i++) |
999 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); | 1016 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); |
1000 | 1017 | ||
1018 | cik_sdma_free_microcode(adev); | ||
1001 | return 0; | 1019 | return 0; |
1002 | } | 1020 | } |
1003 | 1021 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c b/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c index 245cabf06575..ed03b75175d4 100644 --- a/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c | |||
@@ -72,6 +72,11 @@ static int fiji_dpm_sw_init(void *handle) | |||
72 | 72 | ||
73 | static int fiji_dpm_sw_fini(void *handle) | 73 | static int fiji_dpm_sw_fini(void *handle) |
74 | { | 74 | { |
75 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
76 | |||
77 | release_firmware(adev->pm.fw); | ||
78 | adev->pm.fw = NULL; | ||
79 | |||
75 | return 0; | 80 | return 0; |
76 | } | 81 | } |
77 | 82 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index 7f18a53ab53a..8c6ad1e72f02 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | |||
@@ -991,6 +991,22 @@ out: | |||
991 | return err; | 991 | return err; |
992 | } | 992 | } |
993 | 993 | ||
994 | static void gfx_v7_0_free_microcode(struct amdgpu_device *adev) | ||
995 | { | ||
996 | release_firmware(adev->gfx.pfp_fw); | ||
997 | adev->gfx.pfp_fw = NULL; | ||
998 | release_firmware(adev->gfx.me_fw); | ||
999 | adev->gfx.me_fw = NULL; | ||
1000 | release_firmware(adev->gfx.ce_fw); | ||
1001 | adev->gfx.ce_fw = NULL; | ||
1002 | release_firmware(adev->gfx.mec_fw); | ||
1003 | adev->gfx.mec_fw = NULL; | ||
1004 | release_firmware(adev->gfx.mec2_fw); | ||
1005 | adev->gfx.mec2_fw = NULL; | ||
1006 | release_firmware(adev->gfx.rlc_fw); | ||
1007 | adev->gfx.rlc_fw = NULL; | ||
1008 | } | ||
1009 | |||
994 | /** | 1010 | /** |
995 | * gfx_v7_0_tiling_mode_table_init - init the hw tiling table | 1011 | * gfx_v7_0_tiling_mode_table_init - init the hw tiling table |
996 | * | 1012 | * |
@@ -4489,6 +4505,7 @@ static int gfx_v7_0_sw_fini(void *handle) | |||
4489 | gfx_v7_0_cp_compute_fini(adev); | 4505 | gfx_v7_0_cp_compute_fini(adev); |
4490 | gfx_v7_0_rlc_fini(adev); | 4506 | gfx_v7_0_rlc_fini(adev); |
4491 | gfx_v7_0_mec_fini(adev); | 4507 | gfx_v7_0_mec_fini(adev); |
4508 | gfx_v7_0_free_microcode(adev); | ||
4492 | 4509 | ||
4493 | return 0; | 4510 | return 0; |
4494 | } | 4511 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index f19bab68fd83..9f6f8669edc3 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | |||
@@ -836,6 +836,26 @@ err1: | |||
836 | return r; | 836 | return r; |
837 | } | 837 | } |
838 | 838 | ||
839 | |||
840 | static void gfx_v8_0_free_microcode(struct amdgpu_device *adev) { | ||
841 | release_firmware(adev->gfx.pfp_fw); | ||
842 | adev->gfx.pfp_fw = NULL; | ||
843 | release_firmware(adev->gfx.me_fw); | ||
844 | adev->gfx.me_fw = NULL; | ||
845 | release_firmware(adev->gfx.ce_fw); | ||
846 | adev->gfx.ce_fw = NULL; | ||
847 | release_firmware(adev->gfx.rlc_fw); | ||
848 | adev->gfx.rlc_fw = NULL; | ||
849 | release_firmware(adev->gfx.mec_fw); | ||
850 | adev->gfx.mec_fw = NULL; | ||
851 | if ((adev->asic_type != CHIP_STONEY) && | ||
852 | (adev->asic_type != CHIP_TOPAZ)) | ||
853 | release_firmware(adev->gfx.mec2_fw); | ||
854 | adev->gfx.mec2_fw = NULL; | ||
855 | |||
856 | kfree(adev->gfx.rlc.register_list_format); | ||
857 | } | ||
858 | |||
839 | static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) | 859 | static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) |
840 | { | 860 | { |
841 | const char *chip_name; | 861 | const char *chip_name; |
@@ -1983,7 +2003,7 @@ static int gfx_v8_0_sw_fini(void *handle) | |||
1983 | 2003 | ||
1984 | gfx_v8_0_rlc_fini(adev); | 2004 | gfx_v8_0_rlc_fini(adev); |
1985 | 2005 | ||
1986 | kfree(adev->gfx.rlc.register_list_format); | 2006 | gfx_v8_0_free_microcode(adev); |
1987 | 2007 | ||
1988 | return 0; | 2008 | return 0; |
1989 | } | 2009 | } |
@@ -3974,11 +3994,15 @@ static int gfx_v8_0_cp_gfx_start(struct amdgpu_device *adev) | |||
3974 | amdgpu_ring_write(ring, 0x3a00161a); | 3994 | amdgpu_ring_write(ring, 0x3a00161a); |
3975 | amdgpu_ring_write(ring, 0x0000002e); | 3995 | amdgpu_ring_write(ring, 0x0000002e); |
3976 | break; | 3996 | break; |
3977 | case CHIP_TOPAZ: | ||
3978 | case CHIP_CARRIZO: | 3997 | case CHIP_CARRIZO: |
3979 | amdgpu_ring_write(ring, 0x00000002); | 3998 | amdgpu_ring_write(ring, 0x00000002); |
3980 | amdgpu_ring_write(ring, 0x00000000); | 3999 | amdgpu_ring_write(ring, 0x00000000); |
3981 | break; | 4000 | break; |
4001 | case CHIP_TOPAZ: | ||
4002 | amdgpu_ring_write(ring, adev->gfx.config.num_rbs == 1 ? | ||
4003 | 0x00000000 : 0x00000002); | ||
4004 | amdgpu_ring_write(ring, 0x00000000); | ||
4005 | break; | ||
3982 | case CHIP_STONEY: | 4006 | case CHIP_STONEY: |
3983 | amdgpu_ring_write(ring, 0x00000000); | 4007 | amdgpu_ring_write(ring, 0x00000000); |
3984 | amdgpu_ring_write(ring, 0x00000000); | 4008 | amdgpu_ring_write(ring, 0x00000000); |
diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c b/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c index 460bc8ad37e6..825ccd63f2dc 100644 --- a/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c | |||
@@ -72,6 +72,11 @@ static int iceland_dpm_sw_init(void *handle) | |||
72 | 72 | ||
73 | static int iceland_dpm_sw_fini(void *handle) | 73 | static int iceland_dpm_sw_fini(void *handle) |
74 | { | 74 | { |
75 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
76 | |||
77 | release_firmware(adev->pm.fw); | ||
78 | adev->pm.fw = NULL; | ||
79 | |||
75 | return 0; | 80 | return 0; |
76 | } | 81 | } |
77 | 82 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index f4c3130d3fdb..b556bd0a8797 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | |||
@@ -105,6 +105,15 @@ static void sdma_v2_4_init_golden_registers(struct amdgpu_device *adev) | |||
105 | } | 105 | } |
106 | } | 106 | } |
107 | 107 | ||
108 | static void sdma_v2_4_free_microcode(struct amdgpu_device *adev) | ||
109 | { | ||
110 | int i; | ||
111 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
112 | release_firmware(adev->sdma.instance[i].fw); | ||
113 | adev->sdma.instance[i].fw = NULL; | ||
114 | } | ||
115 | } | ||
116 | |||
108 | /** | 117 | /** |
109 | * sdma_v2_4_init_microcode - load ucode images from disk | 118 | * sdma_v2_4_init_microcode - load ucode images from disk |
110 | * | 119 | * |
@@ -461,6 +470,8 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev) | |||
461 | /* Initialize the ring buffer's read and write pointers */ | 470 | /* Initialize the ring buffer's read and write pointers */ |
462 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); | 471 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); |
463 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); | 472 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); |
473 | WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0); | ||
474 | WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0); | ||
464 | 475 | ||
465 | /* set the wb address whether it's enabled or not */ | 476 | /* set the wb address whether it's enabled or not */ |
466 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], | 477 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], |
@@ -489,7 +500,11 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev) | |||
489 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); | 500 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
490 | 501 | ||
491 | ring->ready = true; | 502 | ring->ready = true; |
503 | } | ||
492 | 504 | ||
505 | sdma_v2_4_enable(adev, true); | ||
506 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
507 | ring = &adev->sdma.instance[i].ring; | ||
493 | r = amdgpu_ring_test_ring(ring); | 508 | r = amdgpu_ring_test_ring(ring); |
494 | if (r) { | 509 | if (r) { |
495 | ring->ready = false; | 510 | ring->ready = false; |
@@ -580,8 +595,8 @@ static int sdma_v2_4_start(struct amdgpu_device *adev) | |||
580 | return -EINVAL; | 595 | return -EINVAL; |
581 | } | 596 | } |
582 | 597 | ||
583 | /* unhalt the MEs */ | 598 | /* halt the engine before programing */ |
584 | sdma_v2_4_enable(adev, true); | 599 | sdma_v2_4_enable(adev, false); |
585 | 600 | ||
586 | /* start the gfx rings and rlc compute queues */ | 601 | /* start the gfx rings and rlc compute queues */ |
587 | r = sdma_v2_4_gfx_resume(adev); | 602 | r = sdma_v2_4_gfx_resume(adev); |
@@ -1012,6 +1027,7 @@ static int sdma_v2_4_sw_fini(void *handle) | |||
1012 | for (i = 0; i < adev->sdma.num_instances; i++) | 1027 | for (i = 0; i < adev->sdma.num_instances; i++) |
1013 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); | 1028 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); |
1014 | 1029 | ||
1030 | sdma_v2_4_free_microcode(adev); | ||
1015 | return 0; | 1031 | return 0; |
1016 | } | 1032 | } |
1017 | 1033 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index 31d99b0010f7..532ea88da66a 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | |||
@@ -236,6 +236,15 @@ static void sdma_v3_0_init_golden_registers(struct amdgpu_device *adev) | |||
236 | } | 236 | } |
237 | } | 237 | } |
238 | 238 | ||
239 | static void sdma_v3_0_free_microcode(struct amdgpu_device *adev) | ||
240 | { | ||
241 | int i; | ||
242 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
243 | release_firmware(adev->sdma.instance[i].fw); | ||
244 | adev->sdma.instance[i].fw = NULL; | ||
245 | } | ||
246 | } | ||
247 | |||
239 | /** | 248 | /** |
240 | * sdma_v3_0_init_microcode - load ucode images from disk | 249 | * sdma_v3_0_init_microcode - load ucode images from disk |
241 | * | 250 | * |
@@ -672,6 +681,8 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) | |||
672 | /* Initialize the ring buffer's read and write pointers */ | 681 | /* Initialize the ring buffer's read and write pointers */ |
673 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); | 682 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); |
674 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); | 683 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); |
684 | WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0); | ||
685 | WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0); | ||
675 | 686 | ||
676 | /* set the wb address whether it's enabled or not */ | 687 | /* set the wb address whether it's enabled or not */ |
677 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], | 688 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], |
@@ -711,7 +722,15 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) | |||
711 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); | 722 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
712 | 723 | ||
713 | ring->ready = true; | 724 | ring->ready = true; |
725 | } | ||
726 | |||
727 | /* unhalt the MEs */ | ||
728 | sdma_v3_0_enable(adev, true); | ||
729 | /* enable sdma ring preemption */ | ||
730 | sdma_v3_0_ctx_switch_enable(adev, true); | ||
714 | 731 | ||
732 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
733 | ring = &adev->sdma.instance[i].ring; | ||
715 | r = amdgpu_ring_test_ring(ring); | 734 | r = amdgpu_ring_test_ring(ring); |
716 | if (r) { | 735 | if (r) { |
717 | ring->ready = false; | 736 | ring->ready = false; |
@@ -804,10 +823,9 @@ static int sdma_v3_0_start(struct amdgpu_device *adev) | |||
804 | } | 823 | } |
805 | } | 824 | } |
806 | 825 | ||
807 | /* unhalt the MEs */ | 826 | /* disble sdma engine before programing it */ |
808 | sdma_v3_0_enable(adev, true); | 827 | sdma_v3_0_ctx_switch_enable(adev, false); |
809 | /* enable sdma ring preemption */ | 828 | sdma_v3_0_enable(adev, false); |
810 | sdma_v3_0_ctx_switch_enable(adev, true); | ||
811 | 829 | ||
812 | /* start the gfx rings and rlc compute queues */ | 830 | /* start the gfx rings and rlc compute queues */ |
813 | r = sdma_v3_0_gfx_resume(adev); | 831 | r = sdma_v3_0_gfx_resume(adev); |
@@ -1247,6 +1265,7 @@ static int sdma_v3_0_sw_fini(void *handle) | |||
1247 | for (i = 0; i < adev->sdma.num_instances; i++) | 1265 | for (i = 0; i < adev->sdma.num_instances; i++) |
1248 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); | 1266 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); |
1249 | 1267 | ||
1268 | sdma_v3_0_free_microcode(adev); | ||
1250 | return 0; | 1269 | return 0; |
1251 | } | 1270 | } |
1252 | 1271 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c b/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c index b7615cefcac4..f06f6f4dc3a8 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c | |||
@@ -71,6 +71,11 @@ static int tonga_dpm_sw_init(void *handle) | |||
71 | 71 | ||
72 | static int tonga_dpm_sw_fini(void *handle) | 72 | static int tonga_dpm_sw_fini(void *handle) |
73 | { | 73 | { |
74 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
75 | |||
76 | release_firmware(adev->pm.fw); | ||
77 | adev->pm.fw = NULL; | ||
78 | |||
74 | return 0; | 79 | return 0; |
75 | } | 80 | } |
76 | 81 | ||