mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-27 13:05:03 +08:00
drm/amdgpu: Add GPU reset functionality for Vega10
V2 Signed-off-by: Ken Wang <Ken.Wang@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Acked-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
4135d9f82c
commit
98512bb8c2
@ -2581,7 +2581,8 @@ static bool amdgpu_need_full_reset(struct amdgpu_device *adev)
|
||||
if ((adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) ||
|
||||
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) ||
|
||||
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_ACP) ||
|
||||
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE)) {
|
||||
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_DCE) ||
|
||||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP) {
|
||||
if (adev->ip_blocks[i].status.hang) {
|
||||
DRM_INFO("Some block need full reset!\n");
|
||||
return true;
|
||||
|
@ -62,6 +62,7 @@ static int psp_sw_init(void *handle)
|
||||
psp->cmd_submit = psp_v3_1_cmd_submit;
|
||||
psp->compare_sram_data = psp_v3_1_compare_sram_data;
|
||||
psp->smu_reload_quirk = psp_v3_1_smu_reload_quirk;
|
||||
psp->mode1_reset = psp_v3_1_mode1_reset;
|
||||
break;
|
||||
case CHIP_RAVEN:
|
||||
psp->init_microcode = psp_v10_0_init_microcode;
|
||||
@ -72,6 +73,7 @@ static int psp_sw_init(void *handle)
|
||||
psp->ring_destroy = psp_v10_0_ring_destroy;
|
||||
psp->cmd_submit = psp_v10_0_cmd_submit;
|
||||
psp->compare_sram_data = psp_v10_0_compare_sram_data;
|
||||
psp->mode1_reset = psp_v10_0_mode1_reset;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@ -497,6 +499,22 @@ failed:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool psp_check_reset(void* handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int psp_reset(void* handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
return psp_mode1_reset(&adev->psp);
|
||||
}
|
||||
|
||||
static bool psp_check_fw_loading_status(struct amdgpu_device *adev,
|
||||
enum AMDGPU_UCODE_ID ucode_type)
|
||||
{
|
||||
@ -540,8 +558,9 @@ const struct amd_ip_funcs psp_ip_funcs = {
|
||||
.suspend = psp_suspend,
|
||||
.resume = psp_resume,
|
||||
.is_idle = NULL,
|
||||
.check_soft_reset = psp_check_reset,
|
||||
.wait_for_idle = NULL,
|
||||
.soft_reset = NULL,
|
||||
.soft_reset = psp_reset,
|
||||
.set_clockgating_state = psp_set_clockgating_state,
|
||||
.set_powergating_state = psp_set_powergating_state,
|
||||
};
|
||||
|
@ -76,6 +76,7 @@ struct psp_context
|
||||
struct amdgpu_firmware_info *ucode,
|
||||
enum AMDGPU_UCODE_ID ucode_type);
|
||||
bool (*smu_reload_quirk)(struct psp_context *psp);
|
||||
int (*mode1_reset)(struct psp_context *psp);
|
||||
|
||||
/* fence buffer */
|
||||
struct amdgpu_bo *fw_pri_bo;
|
||||
@ -139,6 +140,8 @@ struct amdgpu_psp_funcs {
|
||||
((psp)->bootloader_load_sos ? (psp)->bootloader_load_sos((psp)) : 0)
|
||||
#define psp_smu_reload_quirk(psp) \
|
||||
((psp)->smu_reload_quirk ? (psp)->smu_reload_quirk((psp)) : false)
|
||||
#define psp_mode1_reset(psp) \
|
||||
((psp)->mode1_reset ? (psp)->mode1_reset((psp)) : false)
|
||||
|
||||
extern const struct amd_ip_funcs psp_ip_funcs;
|
||||
|
||||
|
@ -407,3 +407,10 @@ bool psp_v10_0_compare_sram_data(struct psp_context *psp,
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int psp_v10_0_mode1_reset(struct psp_context *psp)
|
||||
{
|
||||
DRM_INFO("psp mode 1 reset not supported now! \n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -45,4 +45,6 @@ extern int psp_v10_0_cmd_submit(struct psp_context *psp,
|
||||
extern bool psp_v10_0_compare_sram_data(struct psp_context *psp,
|
||||
struct amdgpu_firmware_info *ucode,
|
||||
enum AMDGPU_UCODE_ID ucode_type);
|
||||
|
||||
extern int psp_v10_0_mode1_reset(struct psp_context *psp);
|
||||
#endif
|
||||
|
@ -530,3 +530,37 @@ bool psp_v3_1_smu_reload_quirk(struct psp_context *psp)
|
||||
reg = RREG32_SOC15(NBIO, 0, mmPCIE_DATA2);
|
||||
return (reg & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) ? true : false;
|
||||
}
|
||||
|
||||
int psp_v3_1_mode1_reset(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
uint32_t offset;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
offset = SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64);
|
||||
|
||||
ret = psp_wait_for(psp, offset, 0x80000000, 0x8000FFFF, false);
|
||||
|
||||
if (ret) {
|
||||
DRM_INFO("psp is not working correctly before mode1 reset!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*send the mode 1 reset command*/
|
||||
WREG32(offset, 0x70000);
|
||||
|
||||
mdelay(1000);
|
||||
|
||||
offset = SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_33);
|
||||
|
||||
ret = psp_wait_for(psp, offset, 0x80000000, 0x80000000, false);
|
||||
|
||||
if (ret) {
|
||||
DRM_INFO("psp mode 1 reset failed!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_INFO("psp mode1 reset succeed \n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -53,4 +53,5 @@ extern bool psp_v3_1_compare_sram_data(struct psp_context *psp,
|
||||
struct amdgpu_firmware_info *ucode,
|
||||
enum AMDGPU_UCODE_ID ucode_type);
|
||||
extern bool psp_v3_1_smu_reload_quirk(struct psp_context *psp);
|
||||
extern int psp_v3_1_mode1_reset(struct psp_context *psp);
|
||||
#endif
|
||||
|
@ -407,18 +407,27 @@ static int soc15_read_register(struct amdgpu_device *adev, u32 se_num,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void soc15_gpu_pci_config_reset(struct amdgpu_device *adev)
|
||||
static int soc15_asic_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
dev_info(adev->dev, "GPU pci config reset\n");
|
||||
amdgpu_atombios_scratch_regs_engine_hung(adev, true);
|
||||
|
||||
dev_info(adev->dev, "GPU reset\n");
|
||||
|
||||
/* disable BM */
|
||||
pci_clear_master(adev->pdev);
|
||||
/* reset */
|
||||
amdgpu_pci_config_reset(adev);
|
||||
|
||||
udelay(100);
|
||||
pci_save_state(adev->pdev);
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_IP_NUM; i++) {
|
||||
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP){
|
||||
adev->ip_blocks[i].version->funcs->soft_reset((void *)adev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pci_restore_state(adev->pdev);
|
||||
|
||||
/* wait for asic to come out of reset */
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
@ -430,14 +439,6 @@ static void soc15_gpu_pci_config_reset(struct amdgpu_device *adev)
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int soc15_asic_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
amdgpu_atombios_scratch_regs_engine_hung(adev, true);
|
||||
|
||||
soc15_gpu_pci_config_reset(adev);
|
||||
|
||||
amdgpu_atombios_scratch_regs_engine_hung(adev, false);
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user