162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright 2021 Advanced Micro Devices, Inc. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 562306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 662306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation 762306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 862306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 962306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 1262306a36Sopenharmony_ci * all copies or substantial portions of the Software. 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1562306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1662306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1762306a36Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 1862306a36Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1962306a36Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2062306a36Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 2162306a36Sopenharmony_ci * 2262306a36Sopenharmony_ci */ 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#ifndef __AMDGPU_RESET_H__ 2562306a36Sopenharmony_ci#define __AMDGPU_RESET_H__ 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#include "amdgpu.h" 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cienum AMDGPU_RESET_FLAGS { 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci AMDGPU_NEED_FULL_RESET = 0, 3262306a36Sopenharmony_ci AMDGPU_SKIP_HW_RESET = 1, 3362306a36Sopenharmony_ci AMDGPU_RESET_FOR_DEVICE_REMOVE = 2, 3462306a36Sopenharmony_ci}; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cistruct amdgpu_reset_context { 3762306a36Sopenharmony_ci enum amd_reset_method method; 3862306a36Sopenharmony_ci struct amdgpu_device *reset_req_dev; 3962306a36Sopenharmony_ci struct amdgpu_job *job; 4062306a36Sopenharmony_ci struct amdgpu_hive_info *hive; 4162306a36Sopenharmony_ci struct list_head *reset_device_list; 4262306a36Sopenharmony_ci unsigned long flags; 4362306a36Sopenharmony_ci}; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistruct amdgpu_reset_handler { 4662306a36Sopenharmony_ci enum amd_reset_method reset_method; 4762306a36Sopenharmony_ci struct list_head handler_list; 4862306a36Sopenharmony_ci int (*prepare_env)(struct amdgpu_reset_control *reset_ctl, 4962306a36Sopenharmony_ci struct amdgpu_reset_context *context); 5062306a36Sopenharmony_ci int (*prepare_hwcontext)(struct amdgpu_reset_control *reset_ctl, 5162306a36Sopenharmony_ci struct amdgpu_reset_context *context); 5262306a36Sopenharmony_ci int (*perform_reset)(struct amdgpu_reset_control *reset_ctl, 5362306a36Sopenharmony_ci struct amdgpu_reset_context *context); 5462306a36Sopenharmony_ci int (*restore_hwcontext)(struct amdgpu_reset_control *reset_ctl, 5562306a36Sopenharmony_ci struct amdgpu_reset_context *context); 5662306a36Sopenharmony_ci int (*restore_env)(struct amdgpu_reset_control *reset_ctl, 5762306a36Sopenharmony_ci struct amdgpu_reset_context *context); 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci int (*do_reset)(struct amdgpu_device *adev); 6062306a36Sopenharmony_ci}; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_cistruct amdgpu_reset_control { 6362306a36Sopenharmony_ci void *handle; 6462306a36Sopenharmony_ci struct work_struct reset_work; 6562306a36Sopenharmony_ci struct mutex reset_lock; 6662306a36Sopenharmony_ci struct list_head reset_handlers; 6762306a36Sopenharmony_ci atomic_t in_reset; 6862306a36Sopenharmony_ci enum amd_reset_method active_reset; 6962306a36Sopenharmony_ci struct amdgpu_reset_handler *(*get_reset_handler)( 7062306a36Sopenharmony_ci struct amdgpu_reset_control *reset_ctl, 7162306a36Sopenharmony_ci struct amdgpu_reset_context *context); 7262306a36Sopenharmony_ci void (*async_reset)(struct work_struct *work); 7362306a36Sopenharmony_ci}; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cienum amdgpu_reset_domain_type { 7762306a36Sopenharmony_ci SINGLE_DEVICE, 7862306a36Sopenharmony_ci XGMI_HIVE 7962306a36Sopenharmony_ci}; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_cistruct amdgpu_reset_domain { 8262306a36Sopenharmony_ci struct kref refcount; 8362306a36Sopenharmony_ci struct workqueue_struct *wq; 8462306a36Sopenharmony_ci enum amdgpu_reset_domain_type type; 8562306a36Sopenharmony_ci struct rw_semaphore sem; 8662306a36Sopenharmony_ci atomic_t in_gpu_reset; 8762306a36Sopenharmony_ci atomic_t reset_res; 8862306a36Sopenharmony_ci}; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ciint amdgpu_reset_init(struct amdgpu_device *adev); 9262306a36Sopenharmony_ciint amdgpu_reset_fini(struct amdgpu_device *adev); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ciint amdgpu_reset_prepare_hwcontext(struct amdgpu_device *adev, 9562306a36Sopenharmony_ci struct amdgpu_reset_context *reset_context); 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ciint amdgpu_reset_perform_reset(struct amdgpu_device *adev, 9862306a36Sopenharmony_ci struct amdgpu_reset_context *reset_context); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ciint amdgpu_reset_add_handler(struct amdgpu_reset_control *reset_ctl, 10162306a36Sopenharmony_ci struct amdgpu_reset_handler *handler); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_cistruct amdgpu_reset_domain *amdgpu_reset_create_reset_domain(enum amdgpu_reset_domain_type type, 10462306a36Sopenharmony_ci char *wq_name); 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_civoid amdgpu_reset_destroy_reset_domain(struct kref *ref); 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_cistatic inline bool amdgpu_reset_get_reset_domain(struct amdgpu_reset_domain *domain) 10962306a36Sopenharmony_ci{ 11062306a36Sopenharmony_ci return kref_get_unless_zero(&domain->refcount) != 0; 11162306a36Sopenharmony_ci} 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_cistatic inline void amdgpu_reset_put_reset_domain(struct amdgpu_reset_domain *domain) 11462306a36Sopenharmony_ci{ 11562306a36Sopenharmony_ci if (domain) 11662306a36Sopenharmony_ci kref_put(&domain->refcount, amdgpu_reset_destroy_reset_domain); 11762306a36Sopenharmony_ci} 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_cistatic inline bool amdgpu_reset_domain_schedule(struct amdgpu_reset_domain *domain, 12062306a36Sopenharmony_ci struct work_struct *work) 12162306a36Sopenharmony_ci{ 12262306a36Sopenharmony_ci return queue_work(domain->wq, work); 12362306a36Sopenharmony_ci} 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_civoid amdgpu_device_lock_reset_domain(struct amdgpu_reset_domain *reset_domain); 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_civoid amdgpu_device_unlock_reset_domain(struct amdgpu_reset_domain *reset_domain); 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci#endif 130