Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: XGMI pstate switch initial support

Driver vote low to high pstate switch whenever there is an outstanding
XGMI mapping request. Driver vote high to low pstate when all the
outstanding XGMI mapping is terminated.

Signed-off-by: shaoyunl <shaoyun.liu@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

shaoyunl and committed by
Alex Deucher
df399b06 adc7e863

+56 -1
+4
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 2018 2018 r = amdgpu_device_enable_mgpu_fan_boost(); 2019 2019 if (r) 2020 2020 DRM_ERROR("enable mgpu fan boost failed (%d).\n", r); 2021 + 2022 + /*set to low pstate by default */ 2023 + amdgpu_xgmi_set_pstate(adev, 0); 2024 + 2021 2025 } 2022 2026 2023 2027 static void amdgpu_device_delay_enable_gfx_off(struct work_struct *work)
+2
drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
··· 72 72 73 73 /* If the mappings are cleared or filled */ 74 74 bool cleared; 75 + 76 + bool is_xgmi; 75 77 }; 76 78 77 79 struct amdgpu_bo {
+21
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 34 34 #include "amdgpu_trace.h" 35 35 #include "amdgpu_amdkfd.h" 36 36 #include "amdgpu_gmc.h" 37 + #include "amdgpu_xgmi.h" 37 38 38 39 /** 39 40 * DOC: GPUVM ··· 2046 2045 INIT_LIST_HEAD(&bo_va->valids); 2047 2046 INIT_LIST_HEAD(&bo_va->invalids); 2048 2047 2048 + if (bo && amdgpu_xgmi_same_hive(adev, amdgpu_ttm_adev(bo->tbo.bdev))) { 2049 + bo_va->is_xgmi = true; 2050 + mutex_lock(&adev->vm_manager.lock_pstate); 2051 + /* Power up XGMI if it can be potentially used */ 2052 + if (++adev->vm_manager.xgmi_map_counter == 1) 2053 + amdgpu_xgmi_set_pstate(adev, 1); 2054 + mutex_unlock(&adev->vm_manager.lock_pstate); 2055 + } 2056 + 2049 2057 return bo_va; 2050 2058 } 2051 2059 ··· 2473 2463 } 2474 2464 2475 2465 dma_fence_put(bo_va->last_pt_update); 2466 + 2467 + if (bo && bo_va->is_xgmi) { 2468 + mutex_lock(&adev->vm_manager.lock_pstate); 2469 + if (--adev->vm_manager.xgmi_map_counter == 0) 2470 + amdgpu_xgmi_set_pstate(adev, 0); 2471 + mutex_unlock(&adev->vm_manager.lock_pstate); 2472 + } 2473 + 2476 2474 kfree(bo_va); 2477 2475 } 2478 2476 ··· 2988 2970 2989 2971 idr_init(&adev->vm_manager.pasid_idr); 2990 2972 spin_lock_init(&adev->vm_manager.pasid_lock); 2973 + 2974 + adev->vm_manager.xgmi_map_counter = 0; 2975 + mutex_init(&adev->vm_manager.lock_pstate); 2991 2976 } 2992 2977 2993 2978 /**
+4
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
··· 324 324 */ 325 325 struct idr pasid_idr; 326 326 spinlock_t pasid_lock; 327 + 328 + /* counter of mapped memory through xgmi */ 329 + uint32_t xgmi_map_counter; 330 + struct mutex lock_pstate; 327 331 }; 328 332 329 333 #define amdgpu_vm_copy_pte(adev, ib, pe, src, count) ((adev)->vm_manager.vm_pte_funcs->copy_pte((ib), (pe), (src), (count)))
+15 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
··· 200 200 201 201 if (lock) 202 202 mutex_lock(&tmp->hive_lock); 203 - 203 + tmp->pstate = -1; 204 204 mutex_unlock(&xgmi_mutex); 205 205 206 206 return tmp; 207 + } 208 + 209 + int amdgpu_xgmi_set_pstate(struct amdgpu_device *adev, int pstate) 210 + { 211 + int ret = 0; 212 + struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev, 0); 213 + 214 + if (!hive) 215 + return 0; 216 + 217 + if (hive->pstate == pstate) 218 + return 0; 219 + /* Todo : sent the message to SMU for pstate change */ 220 + return ret; 207 221 } 208 222 209 223 int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive, struct amdgpu_device *adev)
+10
drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h
··· 33 33 struct kobject *kobj; 34 34 struct device_attribute dev_attr; 35 35 struct amdgpu_device *adev; 36 + int pstate; /*0 -- low , 1 -- high , -1 unknown*/ 36 37 }; 37 38 38 39 struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev, int lock); 39 40 int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive, struct amdgpu_device *adev); 40 41 int amdgpu_xgmi_add_device(struct amdgpu_device *adev); 41 42 void amdgpu_xgmi_remove_device(struct amdgpu_device *adev); 43 + int amdgpu_xgmi_set_pstate(struct amdgpu_device *adev, int pstate); 44 + 45 + static inline bool amdgpu_xgmi_same_hive(struct amdgpu_device *adev, 46 + struct amdgpu_device *bo_adev) 47 + { 48 + return (adev != bo_adev && 49 + adev->gmc.xgmi.hive_id && 50 + adev->gmc.xgmi.hive_id == bo_adev->gmc.xgmi.hive_id); 51 + } 42 52 43 53 #endif