Commit fa6bcad7 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-fixes-4.7' of git://people.freedesktop.org/~agd5f/linux into drm-fixes

Mostly memory leak and firmware leak fixes for amdgpu.  A bit bigger than
usual since this is several weeks worth of fixes.

* 'drm-fixes-4.7' of git://people.freedesktop.org/~agd5f/linux: (28 commits)
  drm/amd/powerplay: delete useless code as pptable changed in vbios.
  drm/amd/powerplay: fix bug visit array out of bounds
  drm/amdgpu: fix smu ucode memleak (v2)
  drm/amdgpu: add release firmware for cgs
  drm/amdgpu: fix tonga smu_fini mem leak
  drm/amdgpu: fix fiji smu fini mem leak
  drm/amdgpu: fix cik sdma ucode memleak
  drm/amdgpu: fix sdma24 ucode mem leak
  drm/amdgpu: fix sdma3 ucode mem leak
  drm/amdgpu: fix uvd fini mem leak
  drm/amdgpu: fix gfx 7 ucode mem leak
  drm/amdgpu: fix gfx8 ucode mem leak
  drm/amdgpu: fix missing free wb for cond_exec
  drm/amdgpu: fix memleak in pptable_init
  drm/amdgpu: fix mem leak in atombios
  drm/amdgpu: fix mem leak in pplib/hwmgr
  drm/amdgpu: fix mem leak in smumgr
  drm/amdgpu: add pipeline sync while vmid switch in same ctx
  drm/amdgpu: vBIOS post only call when mem_size zero
  drm/amdgpu: modify sdma start sequence
  ...
parents 166108aa 5f96ddb4
...@@ -799,6 +799,7 @@ struct amdgpu_ring { ...@@ -799,6 +799,7 @@ struct amdgpu_ring {
unsigned cond_exe_offs; unsigned cond_exe_offs;
u64 cond_exe_gpu_addr; u64 cond_exe_gpu_addr;
volatile u32 *cond_exe_cpu_addr; volatile u32 *cond_exe_cpu_addr;
int vmid;
}; };
/* /*
...@@ -936,7 +937,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, ...@@ -936,7 +937,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring,
unsigned vm_id, uint64_t pd_addr, unsigned vm_id, uint64_t pd_addr,
uint32_t gds_base, uint32_t gds_size, uint32_t gds_base, uint32_t gds_size,
uint32_t gws_base, uint32_t gws_size, uint32_t gws_base, uint32_t gws_size,
uint32_t oa_base, uint32_t oa_size); uint32_t oa_base, uint32_t oa_size,
bool vmid_switch);
void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id); void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id);
uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr); uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr);
int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
......
...@@ -696,6 +696,17 @@ static uint32_t fw_type_convert(struct cgs_device *cgs_device, uint32_t fw_type) ...@@ -696,6 +696,17 @@ static uint32_t fw_type_convert(struct cgs_device *cgs_device, uint32_t fw_type)
return result; return result;
} }
static int amdgpu_cgs_rel_firmware(struct cgs_device *cgs_device, enum cgs_ucode_id type)
{
CGS_FUNC_ADEV;
if ((CGS_UCODE_ID_SMU == type) || (CGS_UCODE_ID_SMU_SK == type)) {
release_firmware(adev->pm.fw);
return 0;
}
/* cannot release other firmware because they are not created by cgs */
return -EINVAL;
}
static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
enum cgs_ucode_id type, enum cgs_ucode_id type,
struct cgs_firmware_info *info) struct cgs_firmware_info *info)
...@@ -1125,6 +1136,7 @@ static const struct cgs_ops amdgpu_cgs_ops = { ...@@ -1125,6 +1136,7 @@ static const struct cgs_ops amdgpu_cgs_ops = {
amdgpu_cgs_pm_query_clock_limits, amdgpu_cgs_pm_query_clock_limits,
amdgpu_cgs_set_camera_voltages, amdgpu_cgs_set_camera_voltages,
amdgpu_cgs_get_firmware_info, amdgpu_cgs_get_firmware_info,
amdgpu_cgs_rel_firmware,
amdgpu_cgs_set_powergating_state, amdgpu_cgs_set_powergating_state,
amdgpu_cgs_set_clockgating_state, amdgpu_cgs_set_clockgating_state,
amdgpu_cgs_get_active_displays_info, amdgpu_cgs_get_active_displays_info,
......
...@@ -827,8 +827,10 @@ static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg) ...@@ -827,8 +827,10 @@ static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg)
*/ */
static void amdgpu_atombios_fini(struct amdgpu_device *adev) static void amdgpu_atombios_fini(struct amdgpu_device *adev)
{ {
if (adev->mode_info.atom_context) if (adev->mode_info.atom_context) {
kfree(adev->mode_info.atom_context->scratch); kfree(adev->mode_info.atom_context->scratch);
kfree(adev->mode_info.atom_context->iio);
}
kfree(adev->mode_info.atom_context); kfree(adev->mode_info.atom_context);
adev->mode_info.atom_context = NULL; adev->mode_info.atom_context = NULL;
kfree(adev->mode_info.atom_card_info); kfree(adev->mode_info.atom_card_info);
...@@ -1325,6 +1327,11 @@ static int amdgpu_fini(struct amdgpu_device *adev) ...@@ -1325,6 +1327,11 @@ static int amdgpu_fini(struct amdgpu_device *adev)
adev->ip_block_status[i].valid = false; adev->ip_block_status[i].valid = false;
} }
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
if (adev->ip_blocks[i].funcs->late_fini)
adev->ip_blocks[i].funcs->late_fini((void *)adev);
}
return 0; return 0;
} }
...@@ -1513,8 +1520,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, ...@@ -1513,8 +1520,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
amdgpu_atombios_has_gpu_virtualization_table(adev); amdgpu_atombios_has_gpu_virtualization_table(adev);
/* Post card if necessary */ /* Post card if necessary */
if (!amdgpu_card_posted(adev) || if (!amdgpu_card_posted(adev)) {
adev->virtualization.supports_sr_iov) {
if (!adev->bios) { if (!adev->bios) {
dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n");
return -EINVAL; return -EINVAL;
......
...@@ -122,6 +122,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -122,6 +122,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
bool skip_preamble, need_ctx_switch; bool skip_preamble, need_ctx_switch;
unsigned patch_offset = ~0; unsigned patch_offset = ~0;
struct amdgpu_vm *vm; struct amdgpu_vm *vm;
int vmid = 0, old_vmid = ring->vmid;
struct fence *hwf; struct fence *hwf;
uint64_t ctx; uint64_t ctx;
...@@ -135,9 +136,11 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -135,9 +136,11 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
if (job) { if (job) {
vm = job->vm; vm = job->vm;
ctx = job->ctx; ctx = job->ctx;
vmid = job->vm_id;
} else { } else {
vm = NULL; vm = NULL;
ctx = 0; ctx = 0;
vmid = 0;
} }
if (!ring->ready) { if (!ring->ready) {
...@@ -163,7 +166,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -163,7 +166,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
r = amdgpu_vm_flush(ring, job->vm_id, job->vm_pd_addr, r = amdgpu_vm_flush(ring, job->vm_id, job->vm_pd_addr,
job->gds_base, job->gds_size, job->gds_base, job->gds_size,
job->gws_base, job->gws_size, job->gws_base, job->gws_size,
job->oa_base, job->oa_size); job->oa_base, job->oa_size,
(ring->current_ctx == ctx) && (old_vmid != vmid));
if (r) { if (r) {
amdgpu_ring_undo(ring); amdgpu_ring_undo(ring);
return r; return r;
...@@ -180,7 +184,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -180,7 +184,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
need_ctx_switch = ring->current_ctx != ctx; need_ctx_switch = ring->current_ctx != ctx;
for (i = 0; i < num_ibs; ++i) { for (i = 0; i < num_ibs; ++i) {
ib = &ibs[i]; ib = &ibs[i];
/* drop preamble IBs if we don't have a context switch */ /* drop preamble IBs if we don't have a context switch */
if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && skip_preamble) if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && skip_preamble)
continue; continue;
...@@ -188,6 +191,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -188,6 +191,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
amdgpu_ring_emit_ib(ring, ib, job ? job->vm_id : 0, amdgpu_ring_emit_ib(ring, ib, job ? job->vm_id : 0,
need_ctx_switch); need_ctx_switch);
need_ctx_switch = false; need_ctx_switch = false;
ring->vmid = vmid;
} }
if (ring->funcs->emit_hdp_invalidate) if (ring->funcs->emit_hdp_invalidate)
...@@ -198,6 +202,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -198,6 +202,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
dev_err(adev->dev, "failed to emit fence (%d)\n", r); dev_err(adev->dev, "failed to emit fence (%d)\n", r);
if (job && job->vm_id) if (job && job->vm_id)
amdgpu_vm_reset_id(adev, job->vm_id); amdgpu_vm_reset_id(adev, job->vm_id);
ring->vmid = old_vmid;
amdgpu_ring_undo(ring); amdgpu_ring_undo(ring);
return r; return r;
} }
......
...@@ -183,13 +183,6 @@ static int amdgpu_pp_sw_fini(void *handle) ...@@ -183,13 +183,6 @@ static int amdgpu_pp_sw_fini(void *handle)
if (ret) if (ret)
return ret; return ret;
#ifdef CONFIG_DRM_AMD_POWERPLAY
if (adev->pp_enabled) {
amdgpu_pm_sysfs_fini(adev);
amd_powerplay_fini(adev->powerplay.pp_handle);
}
#endif
return ret; return ret;
} }
...@@ -223,6 +216,22 @@ static int amdgpu_pp_hw_fini(void *handle) ...@@ -223,6 +216,22 @@ static int amdgpu_pp_hw_fini(void *handle)
return ret; return ret;
} }
static void amdgpu_pp_late_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
#ifdef CONFIG_DRM_AMD_POWERPLAY
if (adev->pp_enabled) {
amdgpu_pm_sysfs_fini(adev);
amd_powerplay_fini(adev->powerplay.pp_handle);
}
if (adev->powerplay.ip_funcs->late_fini)
adev->powerplay.ip_funcs->late_fini(
adev->powerplay.pp_handle);
#endif
}
static int amdgpu_pp_suspend(void *handle) static int amdgpu_pp_suspend(void *handle)
{ {
int ret = 0; int ret = 0;
...@@ -311,6 +320,7 @@ const struct amd_ip_funcs amdgpu_pp_ip_funcs = { ...@@ -311,6 +320,7 @@ const struct amd_ip_funcs amdgpu_pp_ip_funcs = {
.sw_fini = amdgpu_pp_sw_fini, .sw_fini = amdgpu_pp_sw_fini,
.hw_init = amdgpu_pp_hw_init, .hw_init = amdgpu_pp_hw_init,
.hw_fini = amdgpu_pp_hw_fini, .hw_fini = amdgpu_pp_hw_fini,
.late_fini = amdgpu_pp_late_fini,
.suspend = amdgpu_pp_suspend, .suspend = amdgpu_pp_suspend,
.resume = amdgpu_pp_resume, .resume = amdgpu_pp_resume,
.is_idle = amdgpu_pp_is_idle, .is_idle = amdgpu_pp_is_idle,
......
...@@ -343,6 +343,7 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring) ...@@ -343,6 +343,7 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring)
ring->ring = NULL; ring->ring = NULL;
ring->ring_obj = NULL; ring->ring_obj = NULL;
amdgpu_wb_free(ring->adev, ring->cond_exe_offs);
amdgpu_wb_free(ring->adev, ring->fence_offs); amdgpu_wb_free(ring->adev, ring->fence_offs);
amdgpu_wb_free(ring->adev, ring->rptr_offs); amdgpu_wb_free(ring->adev, ring->rptr_offs);
amdgpu_wb_free(ring->adev, ring->wptr_offs); amdgpu_wb_free(ring->adev, ring->wptr_offs);
......
...@@ -115,6 +115,7 @@ int amdgpu_sa_bo_manager_start(struct amdgpu_device *adev, ...@@ -115,6 +115,7 @@ int amdgpu_sa_bo_manager_start(struct amdgpu_device *adev,
return r; return r;
} }
r = amdgpu_bo_kmap(sa_manager->bo, &sa_manager->cpu_ptr); r = amdgpu_bo_kmap(sa_manager->bo, &sa_manager->cpu_ptr);
memset(sa_manager->cpu_ptr, 0, sa_manager->size);
amdgpu_bo_unreserve(sa_manager->bo); amdgpu_bo_unreserve(sa_manager->bo);
return r; return r;
} }
......
...@@ -253,19 +253,20 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) ...@@ -253,19 +253,20 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)
{ {
int r; int r;
if (adev->uvd.vcpu_bo == NULL) kfree(adev->uvd.saved_bo);
return 0;
amd_sched_entity_fini(&adev->uvd.ring.sched, &adev->uvd.entity); amd_sched_entity_fini(&adev->uvd.ring.sched, &adev->uvd.entity);
r = amdgpu_bo_reserve(adev->uvd.vcpu_bo, false); if (adev->uvd.vcpu_bo) {
if (!r) { r = amdgpu_bo_reserve(adev->uvd.vcpu_bo, false);
amdgpu_bo_kunmap(adev->uvd.vcpu_bo); if (!r) {
amdgpu_bo_unpin(adev->uvd.vcpu_bo); amdgpu_bo_kunmap(adev->uvd.vcpu_bo);
amdgpu_bo_unreserve(adev->uvd.vcpu_bo); amdgpu_bo_unpin(adev->uvd.vcpu_bo);
} amdgpu_bo_unreserve(adev->uvd.vcpu_bo);
}
amdgpu_bo_unref(&adev->uvd.vcpu_bo); amdgpu_bo_unref(&adev->uvd.vcpu_bo);
}
amdgpu_ring_fini(&adev->uvd.ring); amdgpu_ring_fini(&adev->uvd.ring);
......
...@@ -298,7 +298,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, ...@@ -298,7 +298,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring,
unsigned vm_id, uint64_t pd_addr, unsigned vm_id, uint64_t pd_addr,
uint32_t gds_base, uint32_t gds_size, uint32_t gds_base, uint32_t gds_size,
uint32_t gws_base, uint32_t gws_size, uint32_t gws_base, uint32_t gws_size,
uint32_t oa_base, uint32_t oa_size) uint32_t oa_base, uint32_t oa_size,
bool vmid_switch)
{ {
struct amdgpu_device *adev = ring->adev; struct amdgpu_device *adev = ring->adev;
struct amdgpu_vm_id *id = &adev->vm_manager.ids[vm_id]; struct amdgpu_vm_id *id = &adev->vm_manager.ids[vm_id];
...@@ -312,8 +313,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, ...@@ -312,8 +313,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring,
int r; int r;
if (ring->funcs->emit_pipeline_sync && ( if (ring->funcs->emit_pipeline_sync && (
pd_addr != AMDGPU_VM_NO_FLUSH || gds_switch_needed || pd_addr != AMDGPU_VM_NO_FLUSH || gds_switch_needed || vmid_switch))
ring->type == AMDGPU_RING_TYPE_COMPUTE))
amdgpu_ring_emit_pipeline_sync(ring); amdgpu_ring_emit_pipeline_sync(ring);
if (ring->funcs->emit_vm_flush && if (ring->funcs->emit_vm_flush &&
......
...@@ -6221,6 +6221,9 @@ static int ci_dpm_sw_fini(void *handle) ...@@ -6221,6 +6221,9 @@ static int ci_dpm_sw_fini(void *handle)
ci_dpm_fini(adev); ci_dpm_fini(adev);
mutex_unlock(&adev->pm.mutex); mutex_unlock(&adev->pm.mutex);
release_firmware(adev->pm.fw);
adev->pm.fw = NULL;
return 0; return 0;
} }
......
...@@ -66,6 +66,16 @@ MODULE_FIRMWARE("radeon/mullins_sdma1.bin"); ...@@ -66,6 +66,16 @@ MODULE_FIRMWARE("radeon/mullins_sdma1.bin");
u32 amdgpu_cik_gpu_check_soft_reset(struct amdgpu_device *adev); u32 amdgpu_cik_gpu_check_soft_reset(struct amdgpu_device *adev);
static void cik_sdma_free_microcode(struct amdgpu_device *adev)
{
int i;
for (i = 0; i < adev->sdma.num_instances; i++) {
release_firmware(adev->sdma.instance[i].fw);
adev->sdma.instance[i].fw = NULL;
}
}
/* /*
* sDMA - System DMA * sDMA - System DMA
* Starting with CIK, the GPU has new asynchronous * Starting with CIK, the GPU has new asynchronous
...@@ -419,6 +429,8 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev) ...@@ -419,6 +429,8 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev)
/* Initialize the ring buffer's read and write pointers */ /* Initialize the ring buffer's read and write pointers */
WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0);
WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0);
WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0);
WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0);
/* set the wb address whether it's enabled or not */ /* set the wb address whether it's enabled or not */
WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], 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,7 +458,12 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev)
WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl);
ring->ready = true; ring->ready = true;
}
cik_sdma_enable(adev, true);
for (i = 0; i < adev->sdma.num_instances; i++) {
ring = &adev->sdma.instance[i].ring;
r = amdgpu_ring_test_ring(ring); r = amdgpu_ring_test_ring(ring);
if (r) { if (r) {
ring->ready = false; ring->ready = false;
...@@ -529,8 +546,8 @@ static int cik_sdma_start(struct amdgpu_device *adev) ...@@ -529,8 +546,8 @@ static int cik_sdma_start(struct amdgpu_device *adev)
if (r) if (r)
return r; return r;
/* unhalt the MEs */ /* halt the engine before programing */
cik_sdma_enable(adev, true); cik_sdma_enable(adev, false);
/* start the gfx rings and rlc compute queues */ /* start the gfx rings and rlc compute queues */
r = cik_sdma_gfx_resume(adev); r = cik_sdma_gfx_resume(adev);
...@@ -998,6 +1015,7 @@ static int cik_sdma_sw_fini(void *handle) ...@@ -998,6 +1015,7 @@ static int cik_sdma_sw_fini(void *handle)
for (i = 0; i < adev->sdma.num_instances; i++) for (i = 0; i < adev->sdma.num_instances; i++)
amdgpu_ring_fini(&adev->sdma.instance[i].ring); amdgpu_ring_fini(&adev->sdma.instance[i].ring);
cik_sdma_free_microcode(adev);
return 0; return 0;
} }
......
...@@ -72,6 +72,11 @@ static int fiji_dpm_sw_init(void *handle) ...@@ -72,6 +72,11 @@ static int fiji_dpm_sw_init(void *handle)
static int fiji_dpm_sw_fini(void *handle) static int fiji_dpm_sw_fini(void *handle)
{ {
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
release_firmware(adev->pm.fw);
adev->pm.fw = NULL;
return 0; return 0;
} }
......
...@@ -991,6 +991,22 @@ static int gfx_v7_0_init_microcode(struct amdgpu_device *adev) ...@@ -991,6 +991,22 @@ static int gfx_v7_0_init_microcode(struct amdgpu_device *adev)
return err; return err;
} }
static void gfx_v7_0_free_microcode(struct amdgpu_device *adev)
{
release_firmware(adev->gfx.pfp_fw);
adev->gfx.pfp_fw = NULL;
release_firmware(adev->gfx.me_fw);
adev->gfx.me_fw = NULL;
release_firmware(adev->gfx.ce_fw);
adev->gfx.ce_fw = NULL;
release_firmware(adev->gfx.mec_fw);
adev->gfx.mec_fw = NULL;
release_firmware(adev->gfx.mec2_fw);
adev->gfx.mec2_fw = NULL;
release_firmware(adev->gfx.rlc_fw);
adev->gfx.rlc_fw = NULL;
}
/** /**
* gfx_v7_0_tiling_mode_table_init - init the hw tiling table * gfx_v7_0_tiling_mode_table_init - init the hw tiling table
* *
...@@ -4489,6 +4505,7 @@ static int gfx_v7_0_sw_fini(void *handle) ...@@ -4489,6 +4505,7 @@ static int gfx_v7_0_sw_fini(void *handle)
gfx_v7_0_cp_compute_fini(adev); gfx_v7_0_cp_compute_fini(adev);
gfx_v7_0_rlc_fini(adev); gfx_v7_0_rlc_fini(adev);
gfx_v7_0_mec_fini(adev); gfx_v7_0_mec_fini(adev);
gfx_v7_0_free_microcode(adev);
return 0; return 0;
} }
......
...@@ -836,6 +836,26 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring) ...@@ -836,6 +836,26 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring)
return r; return r;
} }
static void gfx_v8_0_free_microcode(struct amdgpu_device *adev) {
release_firmware(adev->gfx.pfp_fw);
adev->gfx.pfp_fw = NULL;
release_firmware(adev->gfx.me_fw);
adev->gfx.me_fw = NULL;
release_firmware(adev->gfx.ce_fw);
adev->gfx.ce_fw = NULL;
release_firmware(adev->gfx.rlc_fw);
adev->gfx.rlc_fw = NULL;
release_firmware(adev->gfx.mec_fw);
adev->gfx.mec_fw = NULL;
if ((adev->asic_type != CHIP_STONEY) &&
(adev->asic_type != CHIP_TOPAZ))
release_firmware(adev->gfx.mec2_fw);
adev->gfx.mec2_fw = NULL;
kfree(adev->gfx.rlc.register_list_format);
}
static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) static int gfx_v8_0_init_microcode(struct amdgpu_device *adev)
{ {
const char *chip_name; const char *chip_name;
...@@ -1983,7 +2003,7 @@ static int gfx_v8_0_sw_fini(void *handle) ...@@ -1983,7 +2003,7 @@ static int gfx_v8_0_sw_fini(void *handle)
gfx_v8_0_rlc_fini(adev); gfx_v8_0_rlc_fini(adev);
kfree(adev->gfx.rlc.register_list_format); gfx_v8_0_free_microcode(adev);
return 0; return 0;
} }
...@@ -3974,11 +3994,15 @@ static int gfx_v8_0_cp_gfx_start(struct amdgpu_device *adev) ...@@ -3974,11 +3994,15 @@ static int gfx_v8_0_cp_gfx_start(struct amdgpu_device *adev)
amdgpu_ring_write(ring, 0x3a00161a); amdgpu_ring_write(ring, 0x3a00161a);
amdgpu_ring_write(ring, 0x0000002e); amdgpu_ring_write(ring, 0x0000002e);
break; break;
case CHIP_TOPAZ:
case CHIP_CARRIZO: case CHIP_CARRIZO:
amdgpu_ring_write(ring, 0x00000002); amdgpu_ring_write(ring, 0x00000002);
amdgpu_ring_write(ring, 0x00000000); amdgpu_ring_write(ring, 0x00000000);
break; break;
case CHIP_TOPAZ:
amdgpu_ring_write(ring, adev->gfx.config.num_rbs == 1 ?
0x00000000 : 0x00000002);
amdgpu_ring_write(ring, 0x00000000);
break;
case CHIP_STONEY: case CHIP_STONEY:
amdgpu_ring_write(ring, 0x00000000); amdgpu_ring_write(ring, 0x00000000);
amdgpu_ring_write(ring, 0x00000000); amdgpu_ring_write(ring, 0x00000000);
......
...@@ -72,6 +72,11 @@ static int iceland_dpm_sw_init(void *handle) ...@@ -72,6 +72,11 @@ static int iceland_dpm_sw_init(void *handle)
static int iceland_dpm_sw_fini(void *handle) static int iceland_dpm_sw_fini(void *handle)
{ {
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
release_firmware(adev->pm.fw);
adev->pm.fw = NULL;
return 0; return 0;
} }
......
...@@ -105,6 +105,15 @@ static void sdma_v2_4_init_golden_registers(struct amdgpu_device *adev) ...@@ -105,6 +105,15 @@ static void sdma_v2_4_init_golden_registers(struct amdgpu_device *adev)
} }
} }
static void sdma_v2_4_free_microcode(struct amdgpu_device *adev)
{
int i;
for (i = 0; i < adev->sdma.num_instances; i++) {
release_firmware(adev->sdma.instance[i].fw);
adev->sdma.instance[i].fw = NULL;
}
}
/** /**
* sdma_v2_4_init_microcode - load ucode images from disk * sdma_v2_4_init_microcode - load ucode images from disk
* *
...@@ -461,6 +470,8 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev) ...@@ -461,6 +470,8 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev)
/* Initialize the ring buffer's read and write pointers */ /* Initialize the ring buffer's read and write pointers */
WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0);
WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0);
WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0);
WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0);
/* set the wb address whether it's enabled or not */ /* set the wb address whether it's enabled or not */
WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], 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,7 +500,11 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev)
WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl);
ring->ready = true; ring->ready = true;
}
sdma_v2_4_enable(adev, true);
for (i = 0; i < adev->sdma.num_instances; i++) {
ring = &adev->sdma.instance[i].ring;
r = amdgpu_ring_test_ring(ring); r = amdgpu_ring_test_ring(ring);
if (r) { if (r) {
ring->ready = false; ring->ready = false;
...@@ -580,8 +595,8 @@ static int sdma_v2_4_start(struct amdgpu_device *adev) ...@@ -580,8 +595,8 @@ static int sdma_v2_4_start(struct amdgpu_device *adev)
return -EINVAL; return -EINVAL;
} }
/* unhalt the MEs */ /* halt the engine before programing */
sdma_v2_4_enable(adev, true); sdma_v2_4_enable(adev, false);
/* start the gfx rings and rlc compute queues */ /* start the gfx rings and rlc compute queues */
r = sdma_v2_4_gfx_resume(adev); r = sdma_v2_4_gfx_resume(adev);
...@@ -1012,6 +1027,7 @@ static int sdma_v2_4_sw_fini(void *handle) ...@@ -1012,6 +1027,7 @@ static int sdma_v2_4_sw_fini(void *handle)
for (i = 0; i < adev->sdma.num_instances; i++) for (i = 0; i < adev->sdma.num_instances; i++)
amdgpu_ring_fini(&adev->sdma.instance[i].ring); amdgpu_ring_fini(&adev->sdma.instance[i].ring);
sdma_v2_4_free_microcode(adev);
return 0; return 0;
} }
......
...@@ -236,6 +236,15 @@ static void sdma_v3_0_init_golden_registers(struct amdgpu_device *adev) ...@@ -236,6 +236,15 @@ static void sdma_v3_0_init_golden_registers(struct amdgpu_device *adev)
} }
} }
static void sdma_v3_0_free_microcode(struct amdgpu_device *adev)
{
int i;
for (i = 0; i < adev->sdma.num_instances; i++) {
release_firmware(adev->sdma.instance[i].fw);
adev->sdma.instance[i].fw = NULL;
}
}
/** /**
* sdma_v3_0_init_microcode - load ucode images from disk * sdma_v3_0_init_microcode - load ucode images from disk
* *
...@@ -672,6 +681,8 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) ...@@ -672,6 +681,8 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev)
/* Initialize the ring buffer's read and write pointers */ /* Initialize the ring buffer's read and write pointers */
WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0);
WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0);
WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0);
WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0);
/* set the wb address whether it's enabled or not */ /* set the wb address whether it's enabled or not */
WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], 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,7 +722,15 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev)
WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl);
ring->ready = true; ring->ready = true;
}
/* unhalt the MEs */
sdma_v3_0_enable(adev, true);
/* enable sdma ring preemption */
sdma_v3_0_ctx_switch_enable(adev, true);
for (i = 0; i < adev->sdma.num_instances; i++) {
ring = &adev->sdma.instance[i].ring;
r = amdgpu_ring_test_ring(ring); r = amdgpu_ring_test_ring(ring);
if (r) { if (r) {
ring->ready = false; ring->ready = false;
...@@ -804,10 +823,9 @@ static int sdma_v3_0_start(struct amdgpu_device *adev) ...@@ -804,10 +823,9 @@ static int sdma_v3_0_start(struct amdgpu_device *adev)
} }
} }
/* unhalt the MEs */ /* disble sdma engine before programing it */
sdma_v3_0_enable(adev, true); sdma_v3_0_ctx_switch_enable(adev, false);
/* enable sdma ring preemption */ sdma_v3_0_enable(adev, false);
sdma_v3_0_ctx_switch_enable(adev, true);
/* start the gfx rings and rlc compute queues */ /* start the gfx rings and rlc compute queues */
r = sdma_v3_0_gfx_resume(adev); r = sdma_v3_0_gfx_resume(adev);
...@@ -1247,6 +1265,7 @@ static int sdma_v3_0_sw_fini(void *handle) ...@@ -1247,6 +1265,7 @@ static int sdma_v3_0_sw_fini(void *handle)
for (i = 0; i < adev->sdma.num_instances; i++) for (i = 0; i < adev->sdma.num_instances; i++)
amdgpu_ring_fini(&adev->sdma.instance[i].ring); amdgpu_ring_fini(&adev->sdma.instance[i].ring);
sdma_v3_0_free_microcode(adev);
return 0; return 0;
} }
......
...@@ -71,6 +71,11 @@ static int tonga_dpm_sw_init(void *handle) ...@@ -71,6 +71,11 @@ static int tonga_dpm_sw_init(void *handle)
static int tonga_dpm_sw_fini(void *handle) static int tonga_dpm_sw_fini(void *handle)
{ {
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
release_firmware(adev->pm.fw);
adev->pm.fw = NULL;
return 0; return 0;
} }
......
...@@ -157,6 +157,7 @@ struct amd_ip_funcs { ...@@ -157,6 +157,7 @@ struct amd_ip_funcs {
int (*hw_init)(void *handle); int (*hw_init)(void *handle);
/* tears down the hw state */ /* tears down the hw state */
int (*hw_fini)(void *handle); int (*hw_fini)(void *handle);
void (*late_fini)(void *handle);
/* handles IP specific hw/sw changes for suspend */ /* handles IP specific hw/sw changes for suspend */
int (*suspend)(void *handle); int (*suspend)(void *handle);
/* handles IP specific hw/sw changes for resume */ /* handles IP specific hw/sw changes for resume */
......
...@@ -581,6 +581,9 @@ typedef int (*cgs_get_firmware_info)(struct cgs_device *cgs_device, ...@@ -581,6 +581,9 @@ typedef int (*cgs_get_firmware_info)(struct cgs_device *cgs_device,
enum cgs_ucode_id type, enum cgs_ucode_id type,
struct cgs_firmware_info *info); struct cgs_firmware_info *info);
typedef int (*cgs_rel_firmware)(struct cgs_device *cgs_device,
enum cgs_ucode_id type);
typedef int(*cgs_set_powergating_state)(struct cgs_device *cgs_device, typedef int(*cgs_set_powergating_state)(struct cgs_device *cgs_device,
enum amd_ip_block_type block_type, enum amd_ip_block_type block_type,
enum amd_powergating_state state); enum amd_powergating_state state);
...@@ -645,6 +648,7 @@ struct cgs_ops { ...@@ -645,6 +648,7 @@ struct cgs_ops {
cgs_set_camera_voltages_t set_camera_voltages; cgs_set_camera_voltages_t set_camera_voltages;
/* Firmware Info */ /* Firmware Info */
cgs_get_firmware_info get_firmware_info; cgs_get_firmware_info get_firmware_info;
cgs_rel_firmware rel_firmware;
/* cg pg interface*/ /* cg pg interface*/
cgs_set_powergating_state set_powergating_state; cgs_set_powergating_state set_powergating_state;
cgs_set_clockgating_state set_clockgating_state; cgs_set_clockgating_state set_clockgating_state;
...@@ -738,6 +742,8 @@ struct cgs_device ...@@ -738,6 +742,8 @@ struct cgs_device
CGS_CALL(set_camera_voltages,dev,mask,voltages) CGS_CALL(set_camera_voltages,dev,mask,voltages)
#define cgs_get_firmware_info(dev, type, info) \ #define cgs_get_firmware_info(dev, type, info) \
CGS_CALL(get_firmware_info, dev, type, info) CGS_CALL(get_firmware_info, dev, type, info)
#define cgs_rel_firmware(dev, type) \
CGS_CALL(rel_firmware, dev, type)
#define cgs_set_powergating_state(dev, block_type, state) \ #define cgs_set_powergating_state(dev, block_type, state) \
CGS_CALL(set_powergating_state, dev, block_type, state) CGS_CALL(set_powergating_state, dev, block_type, state)
#define cgs_set_clockgating_state(dev, block_type, state) \ #define cgs_set_clockgating_state(dev, block_type, state) \
......
...@@ -73,11 +73,14 @@ static int pp_sw_init(void *handle) ...@@ -73,11 +73,14 @@ static int pp_sw_init(void *handle)
ret = hwmgr->hwmgr_func->backend_init(hwmgr); ret = hwmgr->hwmgr_func->backend_init(hwmgr);
if (ret) if (ret)
goto err; goto err1;
pr_info("amdgpu: powerplay initialized\n"); pr_info("amdgpu: powerplay initialized\n");
return 0; return 0;
err1:
if (hwmgr->pptable_func->pptable_fini)
hwmgr->pptable_func->pptable_fini(hwmgr);
err: err:
pr_err("amdgpu: powerplay initialization failed\n"); pr_err("amdgpu: powerplay initialization failed\n");
return ret; return ret;
...@@ -100,6 +103,9 @@ static int pp_sw_fini(void *handle) ...@@ -100,6 +103,9 @@ static int pp_sw_fini(void *handle)
if (hwmgr->hwmgr_func->backend_fini != NULL) if (hwmgr->hwmgr_func->backend_fini != NULL)
ret = hwmgr->hwmgr_func->backend_fini(hwmgr); ret = hwmgr->hwmgr_func->backend_fini(hwmgr);
if (hwmgr->pptable_func->pptable_fini)
hwmgr->pptable_func->pptable_fini(hwmgr);
return ret; return ret;
} }
......
...@@ -58,9 +58,6 @@ static void pem_fini(struct pp_eventmgr *eventmgr) ...@@ -58,9 +58,6 @@ static void pem_fini(struct pp_eventmgr *eventmgr)
pem_unregister_interrupts(eventmgr); pem_unregister_interrupts(eventmgr);
pem_handle_event(eventmgr, AMD_PP_EVENT_UNINITIALIZE, &event_data); pem_handle_event(eventmgr, AMD_PP_EVENT_UNINITIALIZE, &event_data);
if (eventmgr != NULL)
kfree(eventmgr);
} }
int eventmgr_init(struct pp_instance *handle) int eventmgr_init(struct pp_instance *handle)
......
...@@ -1830,7 +1830,7 @@ static uint16_t fiji_find_closest_vddci(struct pp_hwmgr *hwmgr, uint16_t vddci) ...@@ -1830,7 +1830,7 @@ static uint16_t fiji_find_closest_vddci(struct pp_hwmgr *hwmgr, uint16_t vddci)
PP_ASSERT_WITH_CODE(false, PP_ASSERT_WITH_CODE(false,
"VDDCI is larger than max VDDCI in VDDCI Voltage Table!", "VDDCI is larger than max VDDCI in VDDCI Voltage Table!",
return vddci_table->entries[i].value); return vddci_table->entries[i-1].value);
} }
static int fiji_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, static int fiji_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr,
......
...@@ -93,6 +93,13 @@ int hwmgr_fini(struct pp_hwmgr *hwmgr) ...@@ -93,6 +93,13 @@ int hwmgr_fini(struct pp_hwmgr *hwmgr)
if (hwmgr == NULL || hwmgr->ps == NULL) if (hwmgr == NULL || hwmgr->ps == NULL)
return -EINVAL; return -EINVAL;
/* do hwmgr finish*/
kfree(hwmgr->backend);
kfree(hwmgr->start_thermal_controller.function_list);
kfree(hwmgr->set_temperature_range.function_list);
kfree(hwmgr->ps); kfree(hwmgr->ps);
kfree(hwmgr); kfree(hwmgr);
return 0; return 0;
...@@ -462,7 +469,7 @@ uint16_t phm_find_closest_vddci(struct pp_atomctrl_voltage_table *vddci_table, u ...@@ -462,7 +469,7 @@ uint16_t phm_find_closest_vddci(struct pp_atomctrl_voltage_table *vddci_table, u
PP_ASSERT_WITH_CODE(false, PP_ASSERT_WITH_CODE(false,
"VDDCI is larger than max VDDCI in VDDCI Voltage Table!", "VDDCI is larger than max VDDCI in VDDCI Voltage Table!",
return vddci_table->entries[i].value); return vddci_table->entries[i-1].value);
} }
int phm_find_boot_level(void *table, int phm_find_boot_level(void *table,
......
...@@ -286,7 +286,7 @@ int polaris10_populate_pm_fuses(struct pp_hwmgr *hwmgr) ...@@ -286,7 +286,7 @@ int polaris10_populate_pm_fuses(struct pp_hwmgr *hwmgr)
if (polaris10_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset, if (polaris10_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset,
(uint8_t *)&data->power_tune_table, (uint8_t *)&data->power_tune_table,
sizeof(struct SMU74_Discrete_PmFuses), data->sram_end)) (sizeof(struct SMU74_Discrete_PmFuses) - 92), data->sram_end))
PP_ASSERT_WITH_CODE(false, PP_ASSERT_WITH_CODE(false,
"Attempt to download PmFuseTable Failed!", "Attempt to download PmFuseTable Failed!",
return -EINVAL); return -EINVAL);
......
...@@ -2847,27 +2847,6 @@ static int tonga_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) ...@@ -2847,27 +2847,6 @@ static int tonga_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
} }
} }
/* Initialize Vddc DPM table based on allow Vddc values. And populate corresponding std values. */
for (i = 0; i < allowed_vdd_sclk_table->count; i++) {
data->dpm_table.vddc_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].vddc;
/* tonga_hwmgr->dpm_table.VddcTable.dpm_levels[i].param1 = stdVoltageTable->entries[i].Leakage; */
/* param1 is for corresponding std voltage */
data->dpm_table.vddc_table.dpm_levels[i].enabled = 1;
}
data->dpm_table.vddc_table.count = allowed_vdd_sclk_table->count;
if (NULL != allowed_vdd_mclk_table) {
/* Initialize Vddci DPM table based on allow Mclk values */
for (i = 0; i < allowed_vdd_mclk_table->count; i++) {
data->dpm_table.vdd_ci_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].vddci;
data->dpm_table.vdd_ci_table.dpm_levels[i].enabled = 1;
data->dpm_table.mvdd_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].mvdd;
data->dpm_table.mvdd_table.dpm_levels[i].enabled = 1;
}
data->dpm_table.vdd_ci_table.count = allowed_vdd_mclk_table->count;
data->dpm_table.mvdd_table.count = allowed_vdd_mclk_table->count;
}
/* setup PCIE gen speed levels*/ /* setup PCIE gen speed levels*/
tonga_setup_default_pcie_tables(hwmgr); tonga_setup_default_pcie_tables(hwmgr);
......
...@@ -1040,48 +1040,44 @@ int tonga_pp_tables_uninitialize(struct pp_hwmgr *hwmgr) ...@@ -1040,48 +1040,44 @@ int tonga_pp_tables_uninitialize(struct pp_hwmgr *hwmgr)
struct phm_ppt_v1_information *pp_table_information = struct phm_ppt_v1_information *pp_table_information =
(struct phm_ppt_v1_information *)(hwmgr->pptable); (struct phm_ppt_v1_information *)(hwmgr->pptable);
if (NULL != hwmgr->soft_pp_table) { if (NULL != hwmgr->soft_pp_table)
kfree(hwmgr->soft_pp_table);
hwmgr->soft_pp_table = NULL; hwmgr->soft_pp_table = NULL;
}
if (NULL != pp_table_information->vdd_dep_on_sclk) kfree(pp_table_information->vdd_dep_on_sclk);
pp_table_information->vdd_dep_on_sclk = NULL; pp_table_information->vdd_dep_on_sclk = NULL;
if (NULL != pp_table_information->vdd_dep_on_mclk) kfree(pp_table_information->vdd_dep_on_mclk);
pp_table_information->vdd_dep_on_mclk = NULL; pp_table_information->vdd_dep_on_mclk = NULL;
if (NULL != pp_table_information->valid_mclk_values) kfree(pp_table_information->valid_mclk_values);
pp_table_information->valid_mclk_values = NULL; pp_table_information->valid_mclk_values = NULL;
if (NULL != pp_table_information->valid_sclk_values) kfree(pp_table_information->valid_sclk_values);
pp_table_information->valid_sclk_values = NULL; pp_table_information->valid_sclk_values = NULL;
if (NULL != pp_table_information->vddc_lookup_table) kfree(pp_table_information->vddc_lookup_table);
pp_table_information->vddc_lookup_table = NULL; pp_table_information->vddc_lookup_table = NULL;
if (NULL != pp_table_information->vddgfx_lookup_table) kfree(pp_table_information->vddgfx_lookup_table);
pp_table_information->vddgfx_lookup_table = NULL; pp_table_information->vddgfx_lookup_table = NULL;
if (NULL != pp_table_information->mm_dep_table) kfree(pp_table_information->mm_dep_table);
pp_table_information->mm_dep_table = NULL; pp_table_information->mm_dep_table = NULL;
if (NULL != pp_table_information->cac_dtp_table) kfree(pp_table_information->cac_dtp_table);
pp_table_information->cac_dtp_table = NULL; pp_table_information->cac_dtp_table = NULL;
if (NULL != hwmgr->dyn_state.cac_dtp_table) kfree(hwmgr->dyn_state.cac_dtp_table);
hwmgr->dyn_state.cac_dtp_table = NULL; hwmgr->dyn_state.cac_dtp_table = NULL;
if (NULL != pp_table_information->ppm_parameter_table) kfree(pp_table_information->ppm_parameter_table);
pp_table_information->ppm_parameter_table = NULL; pp_table_information->ppm_parameter_table = NULL;
if (NULL != pp_table_information->pcie_table) kfree(pp_table_information->pcie_table);
pp_table_information->pcie_table = NULL; pp_table_information->pcie_table = NULL;
if (NULL != hwmgr->pptable) { kfree(hwmgr->pptable);
kfree(hwmgr->pptable); hwmgr->pptable = NULL;
hwmgr->pptable = NULL;
}
return result; return result;
} }
......
...@@ -1006,10 +1006,16 @@ static int fiji_smu_init(struct pp_smumgr *smumgr) ...@@ -1006,10 +1006,16 @@ static int fiji_smu_init(struct pp_smumgr *smumgr)
static int fiji_smu_fini(struct pp_smumgr *smumgr) static int fiji_smu_fini(struct pp_smumgr *smumgr)
{ {
struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
smu_free_memory(smumgr->device, (void *)priv->header_buffer.handle);
if (smumgr->backend) { if (smumgr->backend) {
kfree(smumgr->backend); kfree(smumgr->backend);
smumgr->backend = NULL; smumgr->backend = NULL;
} }
cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU);
return 0; return 0;
} }
......
...@@ -469,6 +469,7 @@ int polaris10_smu_fini(struct pp_smumgr *smumgr) ...@@ -469,6 +469,7 @@ int polaris10_smu_fini(struct pp_smumgr *smumgr)
kfree(smumgr->backend); kfree(smumgr->backend);
smumgr->backend = NULL; smumgr->backend = NULL;
} }
cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU);
return 0; return 0;
} }
......
...@@ -81,6 +81,7 @@ int smum_init(struct amd_pp_init *pp_init, struct pp_instance *handle) ...@@ -81,6 +81,7 @@ int smum_init(struct amd_pp_init *pp_init, struct pp_instance *handle)
int smum_fini(struct pp_smumgr *smumgr) int smum_fini(struct pp_smumgr *smumgr)
{ {
kfree(smumgr->device);
kfree(smumgr); kfree(smumgr);
return 0; return 0;
} }
......
...@@ -328,10 +328,17 @@ int tonga_write_smc_sram_dword(struct pp_smumgr *smumgr, ...@@ -328,10 +328,17 @@ int tonga_write_smc_sram_dword(struct pp_smumgr *smumgr,
static int tonga_smu_fini(struct pp_smumgr *smumgr) static int tonga_smu_fini(struct pp_smumgr *smumgr)
{ {
struct tonga_smumgr *priv = (struct tonga_smumgr *)(smumgr->backend);
smu_free_memory(smumgr->device, (void *)priv->smu_buffer.handle);
smu_free_memory(smumgr->device, (void *)priv->header_buffer.handle);
if (smumgr->backend != NULL) { if (smumgr->backend != NULL) {
kfree(smumgr->backend); kfree(smumgr->backend);
smumgr->backend = NULL; smumgr->backend = NULL;
} }
cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment