From c46c1dd07137de6b18ac4503d7e515282858cfbd Mon Sep 17 00:00:00 2001 From: Adam Madsen Date: Mon, 9 Nov 2020 13:26:16 -0600 Subject: [PATCH] AMD: Add PCIE reset method for Polaris 10. --- src/amd/Makefile | 2 ++ src/amd/amd.h | 1 + src/amd/common.h | 11 ++++-- src/amd/polaris10.c | 86 +++++++++++++++++++++++++++++++++++++++++++++ src/device-db.h | 15 ++++++++ 5 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 src/amd/polaris10.c diff --git a/src/amd/Makefile b/src/amd/Makefile index 2a1926b..d7ebb31 100644 --- a/src/amd/Makefile +++ b/src/amd/Makefile @@ -2,6 +2,7 @@ vendor-reset-y += \ src/amd/common.o \ src/amd/compat.o \ src/amd/firmware.o \ + src/amd/polaris10.o \ src/amd/vega10.o \ src/amd/vega20.o \ src/amd/navi10.o \ @@ -18,4 +19,5 @@ ccflags-y += \ -I$(src)/src/amd \ -I$(src)/src/amd/amdgpu \ -I$(src)/src/amd/amdgpu/include \ + -I$(src)/src/amd/amdgpu/include/asic_reg \ $(foreach inc,$(wildcard $(src)/src/amd/amdgpu/include/asic_reg/*/.),-I$(dir $(inc)) ) diff --git a/src/amd/amd.h b/src/amd/amd.h index 677ce77..cc4b224 100644 --- a/src/amd/amd.h +++ b/src/amd/amd.h @@ -16,6 +16,7 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +extern struct vendor_reset_ops amd_polaris10_ops; extern struct vendor_reset_ops amd_vega10_ops; extern struct vendor_reset_ops amd_vega20_ops; extern struct vendor_reset_ops amd_navi10_ops; diff --git a/src/amd/common.h b/src/amd/common.h index c7a5a60..7f8f487 100644 --- a/src/amd/common.h +++ b/src/amd/common.h @@ -130,8 +130,15 @@ struct amd_vendor_private struct mutex smu_lock; }; -#define adev_to_amd_private(adev) ((struct amd_vendor_private *)container_of(adev, struct amd_vendor_private, adev)) -#define amd_private(vdev) ((struct amd_vendor_private *)(vdev->vendor_private)) +static inline struct amd_vendor_private *adev_to_amd_private(struct amd_fake_dev *adev) +{ + return container_of(adev, struct amd_vendor_private, adev); +} + +static inline struct amd_vendor_private *amd_private(struct vendor_reset_dev *vdev) +{ + return vdev->vendor_private; +} int amd_common_pre_reset(struct vendor_reset_dev *); int amd_common_post_reset(struct vendor_reset_dev *); diff --git a/src/amd/polaris10.c b/src/amd/polaris10.c new file mode 100644 index 0000000..e2368d8 --- /dev/null +++ b/src/amd/polaris10.c @@ -0,0 +1,86 @@ +/* +Vendor Reset - Vendor Specific Reset +Copyright (C) 2020 Geoffrey McRae +Copyright (C) 2020 Adam Madsen + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#include "bif/bif_4_1_d.h" +#include "atom-types.h" +#include "atombios.h" +#include "common.h" +#include "compat.h" + +#define bios_scratch_reg_offset mmBIOS_SCRATCH_0 +#define AMDGPU_ASIC_RESET_DATA 0x39d5e86b /* from amdgpu.h */ + +/* from vi.c */ +static int vi_gpu_pci_config_reset(struct amd_fake_dev *adev) +{ + u32 i; + + dev_info(adev->dev, "GPU pci config reset\n"); + + /* reset */ + pci_write_config_dword(adev->pdev, 0x7c, AMDGPU_ASIC_RESET_DATA); + + udelay(100); + + /* wait for asic to come out of reset */ + for (i = 0; i < 100000; i++) + { + if (RREG32(mmCONFIG_MEMSIZE) != 0xffffffff) + { + return 0; + } + udelay(1); + } + return -EINVAL; +} + +static inline void amdgpu_atombios_scratch_regs_engine_hung(struct amd_fake_dev *adev, bool hung) +{ + u32 tmp; + + tmp = RREG32(bios_scratch_reg_offset + 3); + + if (hung) + tmp |= ATOM_S3_ASIC_GUI_ENGINE_HUNG; + else + tmp &= ~ATOM_S3_ASIC_GUI_ENGINE_HUNG; + + WREG32(bios_scratch_reg_offset + 3, tmp); +} + +static int amd_polaris10_reset(struct vendor_reset_dev *vdev) +{ + int ret = 0; + struct amd_vendor_private *priv = amd_private(vdev); + struct amd_fake_dev *adev = &priv->adev; + + amdgpu_atombios_scratch_regs_engine_hung(adev, true); + ret = vi_gpu_pci_config_reset(adev); + amdgpu_atombios_scratch_regs_engine_hung(adev, false); + + return ret; +} + +const struct vendor_reset_ops amd_polaris10_ops = { + .pre_reset = amd_common_pre_reset, + .reset = amd_polaris10_reset, + .post_reset = amd_common_post_reset, +}; \ No newline at end of file diff --git a/src/device-db.h b/src/device-db.h index c64a09f..dade64f 100644 --- a/src/device-db.h +++ b/src/device-db.h @@ -20,6 +20,21 @@ Place, Suite 330, Boston, MA 02111-1307 USA static struct vendor_reset_cfg vendor_reset_devices[] = { + /* AMD Polaris 10 */ + {PCI_VENDOR_ID_ATI, 0x67C0, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x67C1, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x67C2, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x67C4, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x67C7, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x67D0, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x67DF, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x67C8, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x67C9, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x67CA, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x67CC, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x67CF, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x6FDF, &amd_vega10_ops}, + /* AMD Vega 10 */ {PCI_VENDOR_ID_ATI, 0x6860, &amd_vega10_ops}, {PCI_VENDOR_ID_ATI, 0x6861, &amd_vega10_ops},