From 7faae1b95ad3835ffe714201fb17a6efd844e78c Mon Sep 17 00:00:00 2001 From: Adam Madsen Date: Sun, 1 Nov 2020 23:29:53 -0600 Subject: [PATCH] Guard against common cases where vega10 does not need to be reset. Specifically, check if the card is already in BACO. If so, exit. If the card shows no signs of life, exit because we likely can't do anything. If the card shows signs of life, do a BACO reset. --- src/amd/amdgpu/common_baco.c | 16 ++++++++++++++++ src/amd/amdgpu/common_baco.h | 10 ++++++++++ src/amd/common.h | 8 -------- src/amd/vega10.c | 24 +++++++++++++++++------- 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/amd/amdgpu/common_baco.c b/src/amd/amdgpu/common_baco.c index 38b74ab..a3e54dc 100644 --- a/src/amd/amdgpu/common_baco.c +++ b/src/amd/amdgpu/common_baco.c @@ -23,6 +23,8 @@ #include #include +#include "soc15_common.h" +#include "vega10_inc.h" #include "common_baco.h" #include "common.h" @@ -120,3 +122,17 @@ bool soc15_baco_program_registers(struct amd_fake_dev *adev, return true; } + +int smu9_baco_get_state(struct amd_fake_dev *adev, enum BACO_STATE *state) +{ + uint32_t reg; + + reg = RREG32_SOC15(NBIF, 0, mmBACO_CNTL); + + if (reg & BACO_CNTL__BACO_MODE_MASK) + /* gfx has already entered BACO state */ + *state = BACO_STATE_IN; + else + *state = BACO_STATE_OUT; + return 0; +} diff --git a/src/amd/amdgpu/common_baco.h b/src/amd/amdgpu/common_baco.h index fdd0aeb..9e377a3 100644 --- a/src/amd/amdgpu/common_baco.h +++ b/src/amd/amdgpu/common_baco.h @@ -55,6 +55,14 @@ struct soc15_baco_cmd_entry uint32_t val; }; +/* from hwmgr.h */ +enum BACO_STATE +{ + BACO_STATE_OUT = 0, + BACO_STATE_IN, +}; +/* end from hwmgr.h */ + struct amd_fake_dev; extern bool baco_program_registers(struct amd_fake_dev *adev, @@ -63,4 +71,6 @@ extern bool baco_program_registers(struct amd_fake_dev *adev, extern bool soc15_baco_program_registers(struct amd_fake_dev *adev, const struct soc15_baco_cmd_entry *entry, const u32 array_size); +extern int smu9_baco_get_state(struct amd_fake_dev *adev, enum BACO_STATE *state); + #endif diff --git a/src/amd/common.h b/src/amd/common.h index 4f91273..d7a6b08 100644 --- a/src/amd/common.h +++ b/src/amd/common.h @@ -144,14 +144,6 @@ enum amd_hw_ip_block_type #define HWIP_MAX_INSTANCE 8 /* end from amdgpu.h */ -/* from hwmgr.h */ -enum BACO_STATE -{ - BACO_STATE_OUT = 0, - BACO_STATE_IN, -}; -/* end from hwmgr.h */ - struct amd_fake_dev { uint32_t *reg_offset[MAX_HWIP][HWIP_MAX_INSTANCE]; diff --git a/src/amd/vega10.c b/src/amd/vega10.c index 9a649e3..052bdf6 100644 --- a/src/amd/vega10.c +++ b/src/amd/vega10.c @@ -128,6 +128,7 @@ static int amd_vega10_reset(struct vendor_reset_dev *dev) struct amd_fake_dev *adev; int ret, timeout; u32 sol, smu_resp, mp1_intr, psp_bl_ready; + enum BACO_STATE baco_state; priv->adev = (struct amd_fake_dev){ .dev = &dev->pdev->dev, @@ -156,22 +157,31 @@ static int amd_vega10_reset(struct vendor_reset_dev *dev) MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >> MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT; psp_bl_ready = !!(RREG32(mmMP0_SMN_C2PMSG_35) & 0x80000000L); + smu9_baco_get_state(adev, &baco_state); pci_info( dev->pdev, - "Vega10: SMU response reg: %x, sol reg: %x, mp1 intr enabled? %s, bl ready? %s\n", + "Vega10: SMU response reg: %x, sol reg: %x, mp1 intr enabled? %s, bl ready? %s, baco? %s\n", smu_resp, sol, mp1_intr ? "yes" : "no", - psp_bl_ready ? "yes" : "no"); + psp_bl_ready ? "yes" : "no", + baco_state == BACO_STATE_IN ? "on" : "off"); - if (sol == ~1L) + if (sol == ~1L && baco_state != BACO_STATE_IN) { pci_warn(dev->pdev, "Vega10: Timed out waiting for SOL to be valid\n"); return -EINVAL; } - pci_info(dev->pdev, "Vega10: Entering BACO\n"); - ret = vega10_baco_set_state(adev, BACO_STATE_IN); - if (ret) - return ret; + /* if there's no sign of life we usually can't reset */ + if (!sol) + return 0; + + if (baco_state == BACO_STATE_OUT) + { + pci_info(dev->pdev, "Vega10: Entering BACO\n"); + ret = vega10_baco_set_state(adev, BACO_STATE_IN); + if (ret) + return ret; + } pci_info(dev->pdev, "Vega10: Exiting BACO\n"); ret = vega10_baco_set_state(adev, BACO_STATE_OUT);