diff options
Diffstat (limited to 'drivers/gpu/drm/amd')
36 files changed, 422 insertions, 152 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 992f00b65be4..e055d5be1c3c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -1820,6 +1820,8 @@ struct amdgpu_asic_funcs { | |||
1820 | /* MM block clocks */ | 1820 | /* MM block clocks */ |
1821 | int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk); | 1821 | int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk); |
1822 | int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk); | 1822 | int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk); |
1823 | /* query virtual capabilities */ | ||
1824 | u32 (*get_virtual_caps)(struct amdgpu_device *adev); | ||
1823 | }; | 1825 | }; |
1824 | 1826 | ||
1825 | /* | 1827 | /* |
@@ -1914,8 +1916,12 @@ void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device); | |||
1914 | 1916 | ||
1915 | 1917 | ||
1916 | /* GPU virtualization */ | 1918 | /* GPU virtualization */ |
1919 | #define AMDGPU_VIRT_CAPS_SRIOV_EN (1 << 0) | ||
1920 | #define AMDGPU_VIRT_CAPS_IS_VF (1 << 1) | ||
1917 | struct amdgpu_virtualization { | 1921 | struct amdgpu_virtualization { |
1918 | bool supports_sr_iov; | 1922 | bool supports_sr_iov; |
1923 | bool is_virtual; | ||
1924 | u32 caps; | ||
1919 | }; | 1925 | }; |
1920 | 1926 | ||
1921 | /* | 1927 | /* |
@@ -2204,6 +2210,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) | |||
2204 | #define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev)) | 2210 | #define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev)) |
2205 | #define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d)) | 2211 | #define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d)) |
2206 | #define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec)) | 2212 | #define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec)) |
2213 | #define amdgpu_asic_get_virtual_caps(adev) ((adev)->asic_funcs->get_virtual_caps((adev))) | ||
2207 | #define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev)) | 2214 | #define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev)) |
2208 | #define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev)) | 2215 | #define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev)) |
2209 | #define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l)) | 2216 | #define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l)) |
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..66482b429458 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 | ||
@@ -1378,6 +1385,15 @@ static int amdgpu_resume(struct amdgpu_device *adev) | |||
1378 | return 0; | 1385 | return 0; |
1379 | } | 1386 | } |
1380 | 1387 | ||
1388 | static bool amdgpu_device_is_virtual(void) | ||
1389 | { | ||
1390 | #ifdef CONFIG_X86 | ||
1391 | return boot_cpu_has(X86_FEATURE_HYPERVISOR); | ||
1392 | #else | ||
1393 | return false; | ||
1394 | #endif | ||
1395 | } | ||
1396 | |||
1381 | /** | 1397 | /** |
1382 | * amdgpu_device_init - initialize the driver | 1398 | * amdgpu_device_init - initialize the driver |
1383 | * | 1399 | * |
@@ -1512,9 +1528,14 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1512 | adev->virtualization.supports_sr_iov = | 1528 | adev->virtualization.supports_sr_iov = |
1513 | amdgpu_atombios_has_gpu_virtualization_table(adev); | 1529 | amdgpu_atombios_has_gpu_virtualization_table(adev); |
1514 | 1530 | ||
1531 | /* Check if we are executing in a virtualized environment */ | ||
1532 | adev->virtualization.is_virtual = amdgpu_device_is_virtual(); | ||
1533 | adev->virtualization.caps = amdgpu_asic_get_virtual_caps(adev); | ||
1534 | |||
1515 | /* Post card if necessary */ | 1535 | /* Post card if necessary */ |
1516 | if (!amdgpu_card_posted(adev) || | 1536 | if (!amdgpu_card_posted(adev) || |
1517 | adev->virtualization.supports_sr_iov) { | 1537 | (adev->virtualization.is_virtual && |
1538 | !adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN)) { | ||
1518 | if (!adev->bios) { | 1539 | if (!adev->bios) { |
1519 | dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); | 1540 | dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); |
1520 | return -EINVAL; | 1541 | return -EINVAL; |
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/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.c b/drivers/gpu/drm/amd/amdgpu/cik.c index 07bc795a4ca9..910431808542 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik.c +++ b/drivers/gpu/drm/amd/amdgpu/cik.c | |||
@@ -962,6 +962,12 @@ static bool cik_read_bios_from_rom(struct amdgpu_device *adev, | |||
962 | return true; | 962 | return true; |
963 | } | 963 | } |
964 | 964 | ||
965 | static u32 cik_get_virtual_caps(struct amdgpu_device *adev) | ||
966 | { | ||
967 | /* CIK does not support SR-IOV */ | ||
968 | return 0; | ||
969 | } | ||
970 | |||
965 | static const struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = { | 971 | static const struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = { |
966 | {mmGRBM_STATUS, false}, | 972 | {mmGRBM_STATUS, false}, |
967 | {mmGB_ADDR_CONFIG, false}, | 973 | {mmGB_ADDR_CONFIG, false}, |
@@ -2007,6 +2013,7 @@ static const struct amdgpu_asic_funcs cik_asic_funcs = | |||
2007 | .get_xclk = &cik_get_xclk, | 2013 | .get_xclk = &cik_get_xclk, |
2008 | .set_uvd_clocks = &cik_set_uvd_clocks, | 2014 | .set_uvd_clocks = &cik_set_uvd_clocks, |
2009 | .set_vce_clocks = &cik_set_vce_clocks, | 2015 | .set_vce_clocks = &cik_set_vce_clocks, |
2016 | .get_virtual_caps = &cik_get_virtual_caps, | ||
2010 | /* these should be moved to their own ip modules */ | 2017 | /* these should be moved to their own ip modules */ |
2011 | .get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter, | 2018 | .get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter, |
2012 | .wait_for_mc_idle = &gmc_v7_0_mc_wait_for_idle, | 2019 | .wait_for_mc_idle = &gmc_v7_0_mc_wait_for_idle, |
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..fc8ff4d3ccf8 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 | } |
@@ -4816,7 +4833,7 @@ static int gfx_v7_0_eop_irq(struct amdgpu_device *adev, | |||
4816 | case 2: | 4833 | case 2: |
4817 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { | 4834 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { |
4818 | ring = &adev->gfx.compute_ring[i]; | 4835 | ring = &adev->gfx.compute_ring[i]; |
4819 | if ((ring->me == me_id) & (ring->pipe == pipe_id)) | 4836 | if ((ring->me == me_id) && (ring->pipe == pipe_id)) |
4820 | amdgpu_fence_process(ring); | 4837 | amdgpu_fence_process(ring); |
4821 | } | 4838 | } |
4822 | break; | 4839 | break; |
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 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 2c88d0b66cf3..a65c96029476 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c | |||
@@ -421,6 +421,20 @@ static bool vi_read_bios_from_rom(struct amdgpu_device *adev, | |||
421 | return true; | 421 | return true; |
422 | } | 422 | } |
423 | 423 | ||
424 | static u32 vi_get_virtual_caps(struct amdgpu_device *adev) | ||
425 | { | ||
426 | u32 caps = 0; | ||
427 | u32 reg = RREG32(mmBIF_IOV_FUNC_IDENTIFIER); | ||
428 | |||
429 | if (REG_GET_FIELD(reg, BIF_IOV_FUNC_IDENTIFIER, IOV_ENABLE)) | ||
430 | caps |= AMDGPU_VIRT_CAPS_SRIOV_EN; | ||
431 | |||
432 | if (REG_GET_FIELD(reg, BIF_IOV_FUNC_IDENTIFIER, FUNC_IDENTIFIER)) | ||
433 | caps |= AMDGPU_VIRT_CAPS_IS_VF; | ||
434 | |||
435 | return caps; | ||
436 | } | ||
437 | |||
424 | static const struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = { | 438 | static const struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = { |
425 | {mmGB_MACROTILE_MODE7, true}, | 439 | {mmGB_MACROTILE_MODE7, true}, |
426 | }; | 440 | }; |
@@ -1118,6 +1132,7 @@ static const struct amdgpu_asic_funcs vi_asic_funcs = | |||
1118 | .get_xclk = &vi_get_xclk, | 1132 | .get_xclk = &vi_get_xclk, |
1119 | .set_uvd_clocks = &vi_set_uvd_clocks, | 1133 | .set_uvd_clocks = &vi_set_uvd_clocks, |
1120 | .set_vce_clocks = &vi_set_vce_clocks, | 1134 | .set_vce_clocks = &vi_set_vce_clocks, |
1135 | .get_virtual_caps = &vi_get_virtual_caps, | ||
1121 | /* these should be moved to their own ip modules */ | 1136 | /* these should be moved to their own ip modules */ |
1122 | .get_gpu_clock_counter = &gfx_v8_0_get_gpu_clock_counter, | 1137 | .get_gpu_clock_counter = &gfx_v8_0_get_gpu_clock_counter, |
1123 | .wait_for_mc_idle = &gmc_v8_0_mc_wait_for_idle, | 1138 | .wait_for_mc_idle = &gmc_v8_0_mc_wait_for_idle, |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index ac005796b71c..7708d90b9da9 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c | |||
@@ -242,13 +242,19 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn, | |||
242 | pqm_uninit(&p->pqm); | 242 | pqm_uninit(&p->pqm); |
243 | 243 | ||
244 | /* Iterate over all process device data structure and check | 244 | /* Iterate over all process device data structure and check |
245 | * if we should reset all wavefronts */ | 245 | * if we should delete debug managers and reset all wavefronts |
246 | list_for_each_entry(pdd, &p->per_device_data, per_device_list) | 246 | */ |
247 | list_for_each_entry(pdd, &p->per_device_data, per_device_list) { | ||
248 | if ((pdd->dev->dbgmgr) && | ||
249 | (pdd->dev->dbgmgr->pasid == p->pasid)) | ||
250 | kfd_dbgmgr_destroy(pdd->dev->dbgmgr); | ||
251 | |||
247 | if (pdd->reset_wavefronts) { | 252 | if (pdd->reset_wavefronts) { |
248 | pr_warn("amdkfd: Resetting all wave fronts\n"); | 253 | pr_warn("amdkfd: Resetting all wave fronts\n"); |
249 | dbgdev_wave_reset_wavefronts(pdd->dev, p); | 254 | dbgdev_wave_reset_wavefronts(pdd->dev, p); |
250 | pdd->reset_wavefronts = false; | 255 | pdd->reset_wavefronts = false; |
251 | } | 256 | } |
257 | } | ||
252 | 258 | ||
253 | mutex_unlock(&p->mutex); | 259 | mutex_unlock(&p->mutex); |
254 | 260 | ||
@@ -404,42 +410,52 @@ void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid) | |||
404 | 410 | ||
405 | idx = srcu_read_lock(&kfd_processes_srcu); | 411 | idx = srcu_read_lock(&kfd_processes_srcu); |
406 | 412 | ||
413 | /* | ||
414 | * Look for the process that matches the pasid. If there is no such | ||
415 | * process, we either released it in amdkfd's own notifier, or there | ||
416 | * is a bug. Unfortunately, there is no way to tell... | ||
417 | */ | ||
407 | hash_for_each_rcu(kfd_processes_table, i, p, kfd_processes) | 418 | hash_for_each_rcu(kfd_processes_table, i, p, kfd_processes) |
408 | if (p->pasid == pasid) | 419 | if (p->pasid == pasid) { |
409 | break; | ||
410 | 420 | ||
411 | srcu_read_unlock(&kfd_processes_srcu, idx); | 421 | srcu_read_unlock(&kfd_processes_srcu, idx); |
412 | 422 | ||
413 | BUG_ON(p->pasid != pasid); | 423 | pr_debug("Unbinding process %d from IOMMU\n", pasid); |
414 | 424 | ||
415 | mutex_lock(&p->mutex); | 425 | mutex_lock(&p->mutex); |
416 | 426 | ||
417 | if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid)) | 427 | if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid)) |
418 | kfd_dbgmgr_destroy(dev->dbgmgr); | 428 | kfd_dbgmgr_destroy(dev->dbgmgr); |
419 | 429 | ||
420 | pqm_uninit(&p->pqm); | 430 | pqm_uninit(&p->pqm); |
421 | 431 | ||
422 | pdd = kfd_get_process_device_data(dev, p); | 432 | pdd = kfd_get_process_device_data(dev, p); |
423 | 433 | ||
424 | if (!pdd) { | 434 | if (!pdd) { |
425 | mutex_unlock(&p->mutex); | 435 | mutex_unlock(&p->mutex); |
426 | return; | 436 | return; |
427 | } | 437 | } |
428 | 438 | ||
429 | if (pdd->reset_wavefronts) { | 439 | if (pdd->reset_wavefronts) { |
430 | dbgdev_wave_reset_wavefronts(pdd->dev, p); | 440 | dbgdev_wave_reset_wavefronts(pdd->dev, p); |
431 | pdd->reset_wavefronts = false; | 441 | pdd->reset_wavefronts = false; |
432 | } | 442 | } |
433 | 443 | ||
434 | /* | 444 | /* |
435 | * Just mark pdd as unbound, because we still need it to call | 445 | * Just mark pdd as unbound, because we still need it |
436 | * amd_iommu_unbind_pasid() in when the process exits. | 446 | * to call amd_iommu_unbind_pasid() in when the |
437 | * We don't call amd_iommu_unbind_pasid() here | 447 | * process exits. |
438 | * because the IOMMU called us. | 448 | * We don't call amd_iommu_unbind_pasid() here |
439 | */ | 449 | * because the IOMMU called us. |
440 | pdd->bound = false; | 450 | */ |
451 | pdd->bound = false; | ||
441 | 452 | ||
442 | mutex_unlock(&p->mutex); | 453 | mutex_unlock(&p->mutex); |
454 | |||
455 | return; | ||
456 | } | ||
457 | |||
458 | srcu_read_unlock(&kfd_processes_srcu, idx); | ||
443 | } | 459 | } |
444 | 460 | ||
445 | struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p) | 461 | struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p) |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 74909e72a009..884c96f50c3d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c | |||
@@ -666,7 +666,7 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, | |||
666 | dev->node_props.simd_count); | 666 | dev->node_props.simd_count); |
667 | 667 | ||
668 | if (dev->mem_bank_count < dev->node_props.mem_banks_count) { | 668 | if (dev->mem_bank_count < dev->node_props.mem_banks_count) { |
669 | pr_warn("kfd: mem_banks_count truncated from %d to %d\n", | 669 | pr_info_once("kfd: mem_banks_count truncated from %d to %d\n", |
670 | dev->node_props.mem_banks_count, | 670 | dev->node_props.mem_banks_count, |
671 | dev->mem_bank_count); | 671 | dev->mem_bank_count); |
672 | sysfs_show_32bit_prop(buffer, "mem_banks_count", | 672 | sysfs_show_32bit_prop(buffer, "mem_banks_count", |
diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index 6080951d539d..afce1edbe250 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h | |||
@@ -157,6 +157,7 @@ struct amd_ip_funcs { | |||
157 | int (*hw_init)(void *handle); | 157 | int (*hw_init)(void *handle); |
158 | /* tears down the hw state */ | 158 | /* tears down the hw state */ |
159 | int (*hw_fini)(void *handle); | 159 | int (*hw_fini)(void *handle); |
160 | void (*late_fini)(void *handle); | ||
160 | /* handles IP specific hw/sw changes for suspend */ | 161 | /* handles IP specific hw/sw changes for suspend */ |
161 | int (*suspend)(void *handle); | 162 | int (*suspend)(void *handle); |
162 | /* handles IP specific hw/sw changes for resume */ | 163 | /* handles IP specific hw/sw changes for resume */ |
diff --git a/drivers/gpu/drm/amd/include/cgs_common.h b/drivers/gpu/drm/amd/include/cgs_common.h index a461e155a160..7464daf89ca1 100644 --- a/drivers/gpu/drm/amd/include/cgs_common.h +++ b/drivers/gpu/drm/amd/include/cgs_common.h | |||
@@ -581,6 +581,9 @@ typedef int (*cgs_get_firmware_info)(struct cgs_device *cgs_device, | |||
581 | enum cgs_ucode_id type, | 581 | enum cgs_ucode_id type, |
582 | struct cgs_firmware_info *info); | 582 | struct cgs_firmware_info *info); |
583 | 583 | ||
584 | typedef int (*cgs_rel_firmware)(struct cgs_device *cgs_device, | ||
585 | enum cgs_ucode_id type); | ||
586 | |||
584 | typedef int(*cgs_set_powergating_state)(struct cgs_device *cgs_device, | 587 | typedef int(*cgs_set_powergating_state)(struct cgs_device *cgs_device, |
585 | enum amd_ip_block_type block_type, | 588 | enum amd_ip_block_type block_type, |
586 | enum amd_powergating_state state); | 589 | enum amd_powergating_state state); |
@@ -645,6 +648,7 @@ struct cgs_ops { | |||
645 | cgs_set_camera_voltages_t set_camera_voltages; | 648 | cgs_set_camera_voltages_t set_camera_voltages; |
646 | /* Firmware Info */ | 649 | /* Firmware Info */ |
647 | cgs_get_firmware_info get_firmware_info; | 650 | cgs_get_firmware_info get_firmware_info; |
651 | cgs_rel_firmware rel_firmware; | ||
648 | /* cg pg interface*/ | 652 | /* cg pg interface*/ |
649 | cgs_set_powergating_state set_powergating_state; | 653 | cgs_set_powergating_state set_powergating_state; |
650 | cgs_set_clockgating_state set_clockgating_state; | 654 | cgs_set_clockgating_state set_clockgating_state; |
@@ -738,6 +742,8 @@ struct cgs_device | |||
738 | CGS_CALL(set_camera_voltages,dev,mask,voltages) | 742 | CGS_CALL(set_camera_voltages,dev,mask,voltages) |
739 | #define cgs_get_firmware_info(dev, type, info) \ | 743 | #define cgs_get_firmware_info(dev, type, info) \ |
740 | CGS_CALL(get_firmware_info, dev, type, info) | 744 | CGS_CALL(get_firmware_info, dev, type, info) |
745 | #define cgs_rel_firmware(dev, type) \ | ||
746 | CGS_CALL(rel_firmware, dev, type) | ||
741 | #define cgs_set_powergating_state(dev, block_type, state) \ | 747 | #define cgs_set_powergating_state(dev, block_type, state) \ |
742 | CGS_CALL(set_powergating_state, dev, block_type, state) | 748 | CGS_CALL(set_powergating_state, dev, block_type, state) |
743 | #define cgs_set_clockgating_state(dev, block_type, state) \ | 749 | #define cgs_set_clockgating_state(dev, block_type, state) \ |
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 8e345bfddb69..e629f8a9fe93 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c | |||
@@ -73,11 +73,14 @@ static int pp_sw_init(void *handle) | |||
73 | 73 | ||
74 | ret = hwmgr->hwmgr_func->backend_init(hwmgr); | 74 | ret = hwmgr->hwmgr_func->backend_init(hwmgr); |
75 | if (ret) | 75 | if (ret) |
76 | goto err; | 76 | goto err1; |
77 | 77 | ||
78 | pr_info("amdgpu: powerplay initialized\n"); | 78 | pr_info("amdgpu: powerplay initialized\n"); |
79 | 79 | ||
80 | return 0; | 80 | return 0; |
81 | err1: | ||
82 | if (hwmgr->pptable_func->pptable_fini) | ||
83 | hwmgr->pptable_func->pptable_fini(hwmgr); | ||
81 | err: | 84 | err: |
82 | pr_err("amdgpu: powerplay initialization failed\n"); | 85 | pr_err("amdgpu: powerplay initialization failed\n"); |
83 | return ret; | 86 | return ret; |
@@ -100,6 +103,9 @@ static int pp_sw_fini(void *handle) | |||
100 | if (hwmgr->hwmgr_func->backend_fini != NULL) | 103 | if (hwmgr->hwmgr_func->backend_fini != NULL) |
101 | ret = hwmgr->hwmgr_func->backend_fini(hwmgr); | 104 | ret = hwmgr->hwmgr_func->backend_fini(hwmgr); |
102 | 105 | ||
106 | if (hwmgr->pptable_func->pptable_fini) | ||
107 | hwmgr->pptable_func->pptable_fini(hwmgr); | ||
108 | |||
103 | return ret; | 109 | return ret; |
104 | } | 110 | } |
105 | 111 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c b/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c index 46410e3c7349..fb88e4e5d625 100644 --- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c +++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c | |||
@@ -58,9 +58,6 @@ static void pem_fini(struct pp_eventmgr *eventmgr) | |||
58 | pem_unregister_interrupts(eventmgr); | 58 | pem_unregister_interrupts(eventmgr); |
59 | 59 | ||
60 | pem_handle_event(eventmgr, AMD_PP_EVENT_UNINITIALIZE, &event_data); | 60 | pem_handle_event(eventmgr, AMD_PP_EVENT_UNINITIALIZE, &event_data); |
61 | |||
62 | if (eventmgr != NULL) | ||
63 | kfree(eventmgr); | ||
64 | } | 61 | } |
65 | 62 | ||
66 | int eventmgr_init(struct pp_instance *handle) | 63 | int eventmgr_init(struct pp_instance *handle) |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c index 24a16e49b571..586f73276226 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c | |||
@@ -1830,7 +1830,7 @@ static uint16_t fiji_find_closest_vddci(struct pp_hwmgr *hwmgr, uint16_t vddci) | |||
1830 | 1830 | ||
1831 | PP_ASSERT_WITH_CODE(false, | 1831 | PP_ASSERT_WITH_CODE(false, |
1832 | "VDDCI is larger than max VDDCI in VDDCI Voltage Table!", | 1832 | "VDDCI is larger than max VDDCI in VDDCI Voltage Table!", |
1833 | return vddci_table->entries[i].value); | 1833 | return vddci_table->entries[i-1].value); |
1834 | } | 1834 | } |
1835 | 1835 | ||
1836 | static int fiji_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, | 1836 | static int fiji_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c index 1c48917da3cf..20f20e075588 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | |||
@@ -93,6 +93,13 @@ int hwmgr_fini(struct pp_hwmgr *hwmgr) | |||
93 | if (hwmgr == NULL || hwmgr->ps == NULL) | 93 | if (hwmgr == NULL || hwmgr->ps == NULL) |
94 | return -EINVAL; | 94 | return -EINVAL; |
95 | 95 | ||
96 | /* do hwmgr finish*/ | ||
97 | kfree(hwmgr->backend); | ||
98 | |||
99 | kfree(hwmgr->start_thermal_controller.function_list); | ||
100 | |||
101 | kfree(hwmgr->set_temperature_range.function_list); | ||
102 | |||
96 | kfree(hwmgr->ps); | 103 | kfree(hwmgr->ps); |
97 | kfree(hwmgr); | 104 | kfree(hwmgr); |
98 | return 0; | 105 | return 0; |
@@ -462,7 +469,7 @@ uint16_t phm_find_closest_vddci(struct pp_atomctrl_voltage_table *vddci_table, u | |||
462 | 469 | ||
463 | PP_ASSERT_WITH_CODE(false, | 470 | PP_ASSERT_WITH_CODE(false, |
464 | "VDDCI is larger than max VDDCI in VDDCI Voltage Table!", | 471 | "VDDCI is larger than max VDDCI in VDDCI Voltage Table!", |
465 | return vddci_table->entries[i].value); | 472 | return vddci_table->entries[i-1].value); |
466 | } | 473 | } |
467 | 474 | ||
468 | int phm_find_boot_level(void *table, | 475 | int phm_find_boot_level(void *table, |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr_ppt.h b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr_ppt.h index 347fef127ce9..2930a3355948 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr_ppt.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr_ppt.h | |||
@@ -39,6 +39,7 @@ struct phm_ppt_v1_clock_voltage_dependency_record { | |||
39 | uint8_t phases; | 39 | uint8_t phases; |
40 | uint8_t cks_enable; | 40 | uint8_t cks_enable; |
41 | uint8_t cks_voffset; | 41 | uint8_t cks_voffset; |
42 | uint32_t sclk_offset; | ||
42 | }; | 43 | }; |
43 | 44 | ||
44 | typedef struct phm_ppt_v1_clock_voltage_dependency_record phm_ppt_v1_clock_voltage_dependency_record; | 45 | typedef struct phm_ppt_v1_clock_voltage_dependency_record phm_ppt_v1_clock_voltage_dependency_record; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c index aa6be033f21b..1400bc420881 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c | |||
@@ -999,7 +999,7 @@ static int polaris10_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, | |||
999 | vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), | 999 | vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), |
1000 | (dep_table->entries[i].vddc - | 1000 | (dep_table->entries[i].vddc - |
1001 | (uint16_t)data->vddc_vddci_delta)); | 1001 | (uint16_t)data->vddc_vddci_delta)); |
1002 | *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; | 1002 | *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; |
1003 | } | 1003 | } |
1004 | 1004 | ||
1005 | if (POLARIS10_VOLTAGE_CONTROL_NONE == data->mvdd_control) | 1005 | if (POLARIS10_VOLTAGE_CONTROL_NONE == data->mvdd_control) |
@@ -3520,10 +3520,11 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr, | |||
3520 | ATOM_Tonga_State *state_entry = (ATOM_Tonga_State *)state; | 3520 | ATOM_Tonga_State *state_entry = (ATOM_Tonga_State *)state; |
3521 | ATOM_Tonga_POWERPLAYTABLE *powerplay_table = | 3521 | ATOM_Tonga_POWERPLAYTABLE *powerplay_table = |
3522 | (ATOM_Tonga_POWERPLAYTABLE *)pp_table; | 3522 | (ATOM_Tonga_POWERPLAYTABLE *)pp_table; |
3523 | ATOM_Tonga_SCLK_Dependency_Table *sclk_dep_table = | 3523 | PPTable_Generic_SubTable_Header *sclk_dep_table = |
3524 | (ATOM_Tonga_SCLK_Dependency_Table *) | 3524 | (PPTable_Generic_SubTable_Header *) |
3525 | (((unsigned long)powerplay_table) + | 3525 | (((unsigned long)powerplay_table) + |
3526 | le16_to_cpu(powerplay_table->usSclkDependencyTableOffset)); | 3526 | le16_to_cpu(powerplay_table->usSclkDependencyTableOffset)); |
3527 | |||
3527 | ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table = | 3528 | ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table = |
3528 | (ATOM_Tonga_MCLK_Dependency_Table *) | 3529 | (ATOM_Tonga_MCLK_Dependency_Table *) |
3529 | (((unsigned long)powerplay_table) + | 3530 | (((unsigned long)powerplay_table) + |
@@ -3575,7 +3576,11 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr, | |||
3575 | /* Performance levels are arranged from low to high. */ | 3576 | /* Performance levels are arranged from low to high. */ |
3576 | performance_level->memory_clock = mclk_dep_table->entries | 3577 | performance_level->memory_clock = mclk_dep_table->entries |
3577 | [state_entry->ucMemoryClockIndexLow].ulMclk; | 3578 | [state_entry->ucMemoryClockIndexLow].ulMclk; |
3578 | performance_level->engine_clock = sclk_dep_table->entries | 3579 | if (sclk_dep_table->ucRevId == 0) |
3580 | performance_level->engine_clock = ((ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table)->entries | ||
3581 | [state_entry->ucEngineClockIndexLow].ulSclk; | ||
3582 | else if (sclk_dep_table->ucRevId == 1) | ||
3583 | performance_level->engine_clock = ((ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table)->entries | ||
3579 | [state_entry->ucEngineClockIndexLow].ulSclk; | 3584 | [state_entry->ucEngineClockIndexLow].ulSclk; |
3580 | performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap, | 3585 | performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap, |
3581 | state_entry->ucPCIEGenLow); | 3586 | state_entry->ucPCIEGenLow); |
@@ -3586,8 +3591,14 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr, | |||
3586 | [polaris10_power_state->performance_level_count++]); | 3591 | [polaris10_power_state->performance_level_count++]); |
3587 | performance_level->memory_clock = mclk_dep_table->entries | 3592 | performance_level->memory_clock = mclk_dep_table->entries |
3588 | [state_entry->ucMemoryClockIndexHigh].ulMclk; | 3593 | [state_entry->ucMemoryClockIndexHigh].ulMclk; |
3589 | performance_level->engine_clock = sclk_dep_table->entries | 3594 | |
3595 | if (sclk_dep_table->ucRevId == 0) | ||
3596 | performance_level->engine_clock = ((ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table)->entries | ||
3590 | [state_entry->ucEngineClockIndexHigh].ulSclk; | 3597 | [state_entry->ucEngineClockIndexHigh].ulSclk; |
3598 | else if (sclk_dep_table->ucRevId == 1) | ||
3599 | performance_level->engine_clock = ((ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table)->entries | ||
3600 | [state_entry->ucEngineClockIndexHigh].ulSclk; | ||
3601 | |||
3591 | performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap, | 3602 | performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap, |
3592 | state_entry->ucPCIEGenHigh); | 3603 | state_entry->ucPCIEGenHigh); |
3593 | performance_level->pcie_lane = get_pcie_lane_support(data->pcie_lane_cap, | 3604 | performance_level->pcie_lane = get_pcie_lane_support(data->pcie_lane_cap, |
@@ -3645,7 +3656,6 @@ static int polaris10_get_pp_table_entry(struct pp_hwmgr *hwmgr, | |||
3645 | switch (state->classification.ui_label) { | 3656 | switch (state->classification.ui_label) { |
3646 | case PP_StateUILabel_Performance: | 3657 | case PP_StateUILabel_Performance: |
3647 | data->use_pcie_performance_levels = true; | 3658 | data->use_pcie_performance_levels = true; |
3648 | |||
3649 | for (i = 0; i < ps->performance_level_count; i++) { | 3659 | for (i = 0; i < ps->performance_level_count; i++) { |
3650 | if (data->pcie_gen_performance.max < | 3660 | if (data->pcie_gen_performance.max < |
3651 | ps->performance_levels[i].pcie_gen) | 3661 | ps->performance_levels[i].pcie_gen) |
@@ -3661,7 +3671,6 @@ static int polaris10_get_pp_table_entry(struct pp_hwmgr *hwmgr, | |||
3661 | ps->performance_levels[i].pcie_lane) | 3671 | ps->performance_levels[i].pcie_lane) |
3662 | data->pcie_lane_performance.max = | 3672 | data->pcie_lane_performance.max = |
3663 | ps->performance_levels[i].pcie_lane; | 3673 | ps->performance_levels[i].pcie_lane; |
3664 | |||
3665 | if (data->pcie_lane_performance.min > | 3674 | if (data->pcie_lane_performance.min > |
3666 | ps->performance_levels[i].pcie_lane) | 3675 | ps->performance_levels[i].pcie_lane) |
3667 | data->pcie_lane_performance.min = | 3676 | data->pcie_lane_performance.min = |
@@ -4187,12 +4196,9 @@ int polaris10_update_samu_dpm(struct pp_hwmgr *hwmgr, bool bgate) | |||
4187 | { | 4196 | { |
4188 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | 4197 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); |
4189 | uint32_t mm_boot_level_offset, mm_boot_level_value; | 4198 | uint32_t mm_boot_level_offset, mm_boot_level_value; |
4190 | struct phm_ppt_v1_information *table_info = | ||
4191 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | ||
4192 | 4199 | ||
4193 | if (!bgate) { | 4200 | if (!bgate) { |
4194 | data->smc_state_table.SamuBootLevel = | 4201 | data->smc_state_table.SamuBootLevel = 0; |
4195 | (uint8_t) (table_info->mm_dep_table->count - 1); | ||
4196 | mm_boot_level_offset = data->dpm_table_start + | 4202 | mm_boot_level_offset = data->dpm_table_start + |
4197 | offsetof(SMU74_Discrete_DpmTable, SamuBootLevel); | 4203 | offsetof(SMU74_Discrete_DpmTable, SamuBootLevel); |
4198 | mm_boot_level_offset /= 4; | 4204 | mm_boot_level_offset /= 4; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.c index 0b99ab3ba0c5..ae96f14b827c 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.c | |||
@@ -286,7 +286,7 @@ int polaris10_populate_pm_fuses(struct pp_hwmgr *hwmgr) | |||
286 | 286 | ||
287 | if (polaris10_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset, | 287 | if (polaris10_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset, |
288 | (uint8_t *)&data->power_tune_table, | 288 | (uint8_t *)&data->power_tune_table, |
289 | sizeof(struct SMU74_Discrete_PmFuses), data->sram_end)) | 289 | (sizeof(struct SMU74_Discrete_PmFuses) - 92), data->sram_end)) |
290 | PP_ASSERT_WITH_CODE(false, | 290 | PP_ASSERT_WITH_CODE(false, |
291 | "Attempt to download PmFuseTable Failed!", | 291 | "Attempt to download PmFuseTable Failed!", |
292 | return -EINVAL); | 292 | return -EINVAL); |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c index 16fed487973b..d27e8c40602a 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c | |||
@@ -2847,27 +2847,6 @@ static int tonga_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) | |||
2847 | } | 2847 | } |
2848 | } | 2848 | } |
2849 | 2849 | ||
2850 | /* Initialize Vddc DPM table based on allow Vddc values. And populate corresponding std values. */ | ||
2851 | for (i = 0; i < allowed_vdd_sclk_table->count; i++) { | ||
2852 | data->dpm_table.vddc_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].vddc; | ||
2853 | /* tonga_hwmgr->dpm_table.VddcTable.dpm_levels[i].param1 = stdVoltageTable->entries[i].Leakage; */ | ||
2854 | /* param1 is for corresponding std voltage */ | ||
2855 | data->dpm_table.vddc_table.dpm_levels[i].enabled = 1; | ||
2856 | } | ||
2857 | data->dpm_table.vddc_table.count = allowed_vdd_sclk_table->count; | ||
2858 | |||
2859 | if (NULL != allowed_vdd_mclk_table) { | ||
2860 | /* Initialize Vddci DPM table based on allow Mclk values */ | ||
2861 | for (i = 0; i < allowed_vdd_mclk_table->count; i++) { | ||
2862 | data->dpm_table.vdd_ci_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].vddci; | ||
2863 | data->dpm_table.vdd_ci_table.dpm_levels[i].enabled = 1; | ||
2864 | data->dpm_table.mvdd_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].mvdd; | ||
2865 | data->dpm_table.mvdd_table.dpm_levels[i].enabled = 1; | ||
2866 | } | ||
2867 | data->dpm_table.vdd_ci_table.count = allowed_vdd_mclk_table->count; | ||
2868 | data->dpm_table.mvdd_table.count = allowed_vdd_mclk_table->count; | ||
2869 | } | ||
2870 | |||
2871 | /* setup PCIE gen speed levels*/ | 2850 | /* setup PCIE gen speed levels*/ |
2872 | tonga_setup_default_pcie_tables(hwmgr); | 2851 | tonga_setup_default_pcie_tables(hwmgr); |
2873 | 2852 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_pptable.h b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_pptable.h index 1b44f4e9b8f5..f127198aafc4 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_pptable.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_pptable.h | |||
@@ -197,6 +197,22 @@ typedef struct _ATOM_Tonga_SCLK_Dependency_Table { | |||
197 | ATOM_Tonga_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ | 197 | ATOM_Tonga_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ |
198 | } ATOM_Tonga_SCLK_Dependency_Table; | 198 | } ATOM_Tonga_SCLK_Dependency_Table; |
199 | 199 | ||
200 | typedef struct _ATOM_Polaris_SCLK_Dependency_Record { | ||
201 | UCHAR ucVddInd; /* Base voltage */ | ||
202 | USHORT usVddcOffset; /* Offset relative to base voltage */ | ||
203 | ULONG ulSclk; | ||
204 | USHORT usEdcCurrent; | ||
205 | UCHAR ucReliabilityTemperature; | ||
206 | UCHAR ucCKSVOffsetandDisable; /* Bits 0~6: Voltage offset for CKS, Bit 7: Disable/enable for the SCLK level. */ | ||
207 | ULONG ulSclkOffset; | ||
208 | } ATOM_Polaris_SCLK_Dependency_Record; | ||
209 | |||
210 | typedef struct _ATOM_Polaris_SCLK_Dependency_Table { | ||
211 | UCHAR ucRevId; | ||
212 | UCHAR ucNumEntries; /* Number of entries. */ | ||
213 | ATOM_Polaris_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ | ||
214 | } ATOM_Polaris_SCLK_Dependency_Table; | ||
215 | |||
200 | typedef struct _ATOM_Tonga_PCIE_Record { | 216 | typedef struct _ATOM_Tonga_PCIE_Record { |
201 | UCHAR ucPCIEGenSpeed; | 217 | UCHAR ucPCIEGenSpeed; |
202 | UCHAR usPCIELaneWidth; | 218 | UCHAR usPCIELaneWidth; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c index 10e3630ee39d..671fdb4d615a 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c | |||
@@ -408,41 +408,78 @@ static int get_mclk_voltage_dependency_table( | |||
408 | static int get_sclk_voltage_dependency_table( | 408 | static int get_sclk_voltage_dependency_table( |
409 | struct pp_hwmgr *hwmgr, | 409 | struct pp_hwmgr *hwmgr, |
410 | phm_ppt_v1_clock_voltage_dependency_table **pp_tonga_sclk_dep_table, | 410 | phm_ppt_v1_clock_voltage_dependency_table **pp_tonga_sclk_dep_table, |
411 | const ATOM_Tonga_SCLK_Dependency_Table * sclk_dep_table | 411 | const PPTable_Generic_SubTable_Header *sclk_dep_table |
412 | ) | 412 | ) |
413 | { | 413 | { |
414 | uint32_t table_size, i; | 414 | uint32_t table_size, i; |
415 | phm_ppt_v1_clock_voltage_dependency_table *sclk_table; | 415 | phm_ppt_v1_clock_voltage_dependency_table *sclk_table; |
416 | 416 | ||
417 | PP_ASSERT_WITH_CODE((0 != sclk_dep_table->ucNumEntries), | 417 | if (sclk_dep_table->ucRevId < 1) { |
418 | "Invalid PowerPlay Table!", return -1); | 418 | const ATOM_Tonga_SCLK_Dependency_Table *tonga_table = |
419 | (ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table; | ||
419 | 420 | ||
420 | table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_clock_voltage_dependency_record) | 421 | PP_ASSERT_WITH_CODE((0 != tonga_table->ucNumEntries), |
421 | * sclk_dep_table->ucNumEntries; | 422 | "Invalid PowerPlay Table!", return -1); |
422 | 423 | ||
423 | sclk_table = (phm_ppt_v1_clock_voltage_dependency_table *) | 424 | table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_clock_voltage_dependency_record) |
424 | kzalloc(table_size, GFP_KERNEL); | 425 | * tonga_table->ucNumEntries; |
425 | 426 | ||
426 | if (NULL == sclk_table) | 427 | sclk_table = (phm_ppt_v1_clock_voltage_dependency_table *) |
427 | return -ENOMEM; | 428 | kzalloc(table_size, GFP_KERNEL); |
428 | 429 | ||
429 | memset(sclk_table, 0x00, table_size); | 430 | if (NULL == sclk_table) |
430 | 431 | return -ENOMEM; | |
431 | sclk_table->count = (uint32_t)sclk_dep_table->ucNumEntries; | 432 | |
432 | 433 | memset(sclk_table, 0x00, table_size); | |
433 | for (i = 0; i < sclk_dep_table->ucNumEntries; i++) { | 434 | |
434 | sclk_table->entries[i].vddInd = | 435 | sclk_table->count = (uint32_t)tonga_table->ucNumEntries; |
435 | sclk_dep_table->entries[i].ucVddInd; | 436 | |
436 | sclk_table->entries[i].vdd_offset = | 437 | for (i = 0; i < tonga_table->ucNumEntries; i++) { |
437 | sclk_dep_table->entries[i].usVddcOffset; | 438 | sclk_table->entries[i].vddInd = |
438 | sclk_table->entries[i].clk = | 439 | tonga_table->entries[i].ucVddInd; |
439 | sclk_dep_table->entries[i].ulSclk; | 440 | sclk_table->entries[i].vdd_offset = |
440 | sclk_table->entries[i].cks_enable = | 441 | tonga_table->entries[i].usVddcOffset; |
441 | (((sclk_dep_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0; | 442 | sclk_table->entries[i].clk = |
442 | sclk_table->entries[i].cks_voffset = | 443 | tonga_table->entries[i].ulSclk; |
443 | (sclk_dep_table->entries[i].ucCKSVOffsetandDisable & 0x7F); | 444 | sclk_table->entries[i].cks_enable = |
444 | } | 445 | (((tonga_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0; |
446 | sclk_table->entries[i].cks_voffset = | ||
447 | (tonga_table->entries[i].ucCKSVOffsetandDisable & 0x7F); | ||
448 | } | ||
449 | } else { | ||
450 | const ATOM_Polaris_SCLK_Dependency_Table *polaris_table = | ||
451 | (ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table; | ||
452 | |||
453 | PP_ASSERT_WITH_CODE((0 != polaris_table->ucNumEntries), | ||
454 | "Invalid PowerPlay Table!", return -1); | ||
455 | |||
456 | table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_clock_voltage_dependency_record) | ||
457 | * polaris_table->ucNumEntries; | ||
458 | |||
459 | sclk_table = (phm_ppt_v1_clock_voltage_dependency_table *) | ||
460 | kzalloc(table_size, GFP_KERNEL); | ||
445 | 461 | ||
462 | if (NULL == sclk_table) | ||
463 | return -ENOMEM; | ||
464 | |||
465 | memset(sclk_table, 0x00, table_size); | ||
466 | |||
467 | sclk_table->count = (uint32_t)polaris_table->ucNumEntries; | ||
468 | |||
469 | for (i = 0; i < polaris_table->ucNumEntries; i++) { | ||
470 | sclk_table->entries[i].vddInd = | ||
471 | polaris_table->entries[i].ucVddInd; | ||
472 | sclk_table->entries[i].vdd_offset = | ||
473 | polaris_table->entries[i].usVddcOffset; | ||
474 | sclk_table->entries[i].clk = | ||
475 | polaris_table->entries[i].ulSclk; | ||
476 | sclk_table->entries[i].cks_enable = | ||
477 | (((polaris_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0; | ||
478 | sclk_table->entries[i].cks_voffset = | ||
479 | (polaris_table->entries[i].ucCKSVOffsetandDisable & 0x7F); | ||
480 | sclk_table->entries[i].sclk_offset = polaris_table->entries[i].ulSclkOffset; | ||
481 | } | ||
482 | } | ||
446 | *pp_tonga_sclk_dep_table = sclk_table; | 483 | *pp_tonga_sclk_dep_table = sclk_table; |
447 | 484 | ||
448 | return 0; | 485 | return 0; |
@@ -708,8 +745,8 @@ static int init_clock_voltage_dependency( | |||
708 | const ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table = | 745 | const ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table = |
709 | (const ATOM_Tonga_MCLK_Dependency_Table *)(((unsigned long) powerplay_table) + | 746 | (const ATOM_Tonga_MCLK_Dependency_Table *)(((unsigned long) powerplay_table) + |
710 | le16_to_cpu(powerplay_table->usMclkDependencyTableOffset)); | 747 | le16_to_cpu(powerplay_table->usMclkDependencyTableOffset)); |
711 | const ATOM_Tonga_SCLK_Dependency_Table *sclk_dep_table = | 748 | const PPTable_Generic_SubTable_Header *sclk_dep_table = |
712 | (const ATOM_Tonga_SCLK_Dependency_Table *)(((unsigned long) powerplay_table) + | 749 | (const PPTable_Generic_SubTable_Header *)(((unsigned long) powerplay_table) + |
713 | le16_to_cpu(powerplay_table->usSclkDependencyTableOffset)); | 750 | le16_to_cpu(powerplay_table->usSclkDependencyTableOffset)); |
714 | const ATOM_Tonga_Hard_Limit_Table *pHardLimits = | 751 | const ATOM_Tonga_Hard_Limit_Table *pHardLimits = |
715 | (const ATOM_Tonga_Hard_Limit_Table *)(((unsigned long) powerplay_table) + | 752 | (const ATOM_Tonga_Hard_Limit_Table *)(((unsigned long) powerplay_table) + |
@@ -1040,48 +1077,44 @@ int tonga_pp_tables_uninitialize(struct pp_hwmgr *hwmgr) | |||
1040 | struct phm_ppt_v1_information *pp_table_information = | 1077 | struct phm_ppt_v1_information *pp_table_information = |
1041 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | 1078 | (struct phm_ppt_v1_information *)(hwmgr->pptable); |
1042 | 1079 | ||
1043 | if (NULL != hwmgr->soft_pp_table) { | 1080 | if (NULL != hwmgr->soft_pp_table) |
1044 | kfree(hwmgr->soft_pp_table); | ||
1045 | hwmgr->soft_pp_table = NULL; | 1081 | hwmgr->soft_pp_table = NULL; |
1046 | } | ||
1047 | 1082 | ||
1048 | if (NULL != pp_table_information->vdd_dep_on_sclk) | 1083 | kfree(pp_table_information->vdd_dep_on_sclk); |
1049 | pp_table_information->vdd_dep_on_sclk = NULL; | 1084 | pp_table_information->vdd_dep_on_sclk = NULL; |
1050 | 1085 | ||
1051 | if (NULL != pp_table_information->vdd_dep_on_mclk) | 1086 | kfree(pp_table_information->vdd_dep_on_mclk); |
1052 | pp_table_information->vdd_dep_on_mclk = NULL; | 1087 | pp_table_information->vdd_dep_on_mclk = NULL; |
1053 | 1088 | ||
1054 | if (NULL != pp_table_information->valid_mclk_values) | 1089 | kfree(pp_table_information->valid_mclk_values); |
1055 | pp_table_information->valid_mclk_values = NULL; | 1090 | pp_table_information->valid_mclk_values = NULL; |
1056 | 1091 | ||
1057 | if (NULL != pp_table_information->valid_sclk_values) | 1092 | kfree(pp_table_information->valid_sclk_values); |
1058 | pp_table_information->valid_sclk_values = NULL; | 1093 | pp_table_information->valid_sclk_values = NULL; |
1059 | 1094 | ||
1060 | if (NULL != pp_table_information->vddc_lookup_table) | 1095 | kfree(pp_table_information->vddc_lookup_table); |
1061 | pp_table_information->vddc_lookup_table = NULL; | 1096 | pp_table_information->vddc_lookup_table = NULL; |
1062 | 1097 | ||
1063 | if (NULL != pp_table_information->vddgfx_lookup_table) | 1098 | kfree(pp_table_information->vddgfx_lookup_table); |
1064 | pp_table_information->vddgfx_lookup_table = NULL; | 1099 | pp_table_information->vddgfx_lookup_table = NULL; |
1065 | 1100 | ||
1066 | if (NULL != pp_table_information->mm_dep_table) | 1101 | kfree(pp_table_information->mm_dep_table); |
1067 | pp_table_information->mm_dep_table = NULL; | 1102 | pp_table_information->mm_dep_table = NULL; |
1068 | 1103 | ||
1069 | if (NULL != pp_table_information->cac_dtp_table) | 1104 | kfree(pp_table_information->cac_dtp_table); |
1070 | pp_table_information->cac_dtp_table = NULL; | 1105 | pp_table_information->cac_dtp_table = NULL; |
1071 | 1106 | ||
1072 | if (NULL != hwmgr->dyn_state.cac_dtp_table) | 1107 | kfree(hwmgr->dyn_state.cac_dtp_table); |
1073 | hwmgr->dyn_state.cac_dtp_table = NULL; | 1108 | hwmgr->dyn_state.cac_dtp_table = NULL; |
1074 | 1109 | ||
1075 | if (NULL != pp_table_information->ppm_parameter_table) | 1110 | kfree(pp_table_information->ppm_parameter_table); |
1076 | pp_table_information->ppm_parameter_table = NULL; | 1111 | pp_table_information->ppm_parameter_table = NULL; |
1077 | 1112 | ||
1078 | if (NULL != pp_table_information->pcie_table) | 1113 | kfree(pp_table_information->pcie_table); |
1079 | pp_table_information->pcie_table = NULL; | 1114 | pp_table_information->pcie_table = NULL; |
1080 | 1115 | ||
1081 | if (NULL != hwmgr->pptable) { | 1116 | kfree(hwmgr->pptable); |
1082 | kfree(hwmgr->pptable); | 1117 | hwmgr->pptable = NULL; |
1083 | hwmgr->pptable = NULL; | ||
1084 | } | ||
1085 | 1118 | ||
1086 | return result; | 1119 | return result; |
1087 | } | 1120 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c index 673a75c74e18..8e52a2e82db5 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c | |||
@@ -1006,10 +1006,16 @@ static int fiji_smu_init(struct pp_smumgr *smumgr) | |||
1006 | 1006 | ||
1007 | static int fiji_smu_fini(struct pp_smumgr *smumgr) | 1007 | static int fiji_smu_fini(struct pp_smumgr *smumgr) |
1008 | { | 1008 | { |
1009 | struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend); | ||
1010 | |||
1011 | smu_free_memory(smumgr->device, (void *)priv->header_buffer.handle); | ||
1012 | |||
1009 | if (smumgr->backend) { | 1013 | if (smumgr->backend) { |
1010 | kfree(smumgr->backend); | 1014 | kfree(smumgr->backend); |
1011 | smumgr->backend = NULL; | 1015 | smumgr->backend = NULL; |
1012 | } | 1016 | } |
1017 | |||
1018 | cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU); | ||
1013 | return 0; | 1019 | return 0; |
1014 | } | 1020 | } |
1015 | 1021 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c index de618ead9db8..043b6ac09d5f 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c | |||
@@ -469,6 +469,7 @@ int polaris10_smu_fini(struct pp_smumgr *smumgr) | |||
469 | kfree(smumgr->backend); | 469 | kfree(smumgr->backend); |
470 | smumgr->backend = NULL; | 470 | smumgr->backend = NULL; |
471 | } | 471 | } |
472 | cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU); | ||
472 | return 0; | 473 | return 0; |
473 | } | 474 | } |
474 | 475 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c index c483baf6b4fb..0728c1e3d97a 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c | |||
@@ -81,6 +81,7 @@ int smum_init(struct amd_pp_init *pp_init, struct pp_instance *handle) | |||
81 | 81 | ||
82 | int smum_fini(struct pp_smumgr *smumgr) | 82 | int smum_fini(struct pp_smumgr *smumgr) |
83 | { | 83 | { |
84 | kfree(smumgr->device); | ||
84 | kfree(smumgr); | 85 | kfree(smumgr); |
85 | return 0; | 86 | return 0; |
86 | } | 87 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c index 32820b680d88..b22722eabafc 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c | |||
@@ -328,10 +328,17 @@ int tonga_write_smc_sram_dword(struct pp_smumgr *smumgr, | |||
328 | 328 | ||
329 | static int tonga_smu_fini(struct pp_smumgr *smumgr) | 329 | static int tonga_smu_fini(struct pp_smumgr *smumgr) |
330 | { | 330 | { |
331 | struct tonga_smumgr *priv = (struct tonga_smumgr *)(smumgr->backend); | ||
332 | |||
333 | smu_free_memory(smumgr->device, (void *)priv->smu_buffer.handle); | ||
334 | smu_free_memory(smumgr->device, (void *)priv->header_buffer.handle); | ||
335 | |||
331 | if (smumgr->backend != NULL) { | 336 | if (smumgr->backend != NULL) { |
332 | kfree(smumgr->backend); | 337 | kfree(smumgr->backend); |
333 | smumgr->backend = NULL; | 338 | smumgr->backend = NULL; |
334 | } | 339 | } |
340 | |||
341 | cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU); | ||
335 | return 0; | 342 | return 0; |
336 | } | 343 | } |
337 | 344 | ||