20 Commits

Author SHA1 Message Date
mfrischknecht
556de55719 Merge 54ffd6a012 into 084881c6e9 2024-11-27 07:09:41 +01:00
mfrischknecht
54ffd6a012 Make new include path conditional
…so the module builds for both kernels below 6.12 and above. Thanks, @VoodaGod!

Co-authored-by: Jason Rensburger <l33tjas.0n@gmail.com>
2024-11-27 07:09:37 +01:00
mfrischknecht
ab1b348480 Import unaligned.h from linux
`asm/unaligned.h` has been moved to `linux/unaligned.h` since Linux v. 6.12.
C.f. e.g. 5f60d5f6bb
2024-11-24 00:27:31 +01:00
Marcus Köhler
084881c6e9 Allow correct compilation with Clang/LLVM
Signed-off-by: Marcus Köhler <khler.marcus@gmail.com>
2024-04-17 05:51:53 +10:00
Sakari
f72619e468 Fix build on kernel 6.8+ 2024-04-17 05:50:13 +10:00
Geoffrey McRae
1374629d08 [amd] add support for AMD Instinct MI100 2024-04-17 05:49:32 +10:00
Alyssa Ross
4b466e92a2 Fix GCC declaration-after-statement error
Since upgrading to Linux v5.18 in Nixpkgs, we've been seeing an
"ISO C90 forbids mixed declarations and code" error from GCC.

This patch fixes it by initializing regs as part of its declaration,
meaning hook will no longer be declared after a statement.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2022-09-29 16:27:23 +10:00
xperia64
e65b850acc Add udev rules for kernel 5.15+ 2022-09-29 16:26:54 +10:00
dev-sda1
7d43285a50 Bump MODULE_VERSION to 0.1.1
MODULE_VERSION was still set to the old version of 0.1.0, which would give out a warning when DKIM performed version sanity checks.
2021-10-19 18:32:24 -05:00
Térence Clastres
225a49a409 [core] add support for linux 5.11
This approach maintains compatibility with previous kernel versions.

Thanks to @justinkb for finding the commit that broke it (torvalds/linux@d19ad07).
2021-02-15 17:29:48 -06:00
Adam Madsen
e16c0d7931 [core] remove unneeded line in dkms.conf 2021-01-23 12:17:09 -06:00
Adam Madsen
547aec42c4 [core] add MODULE_VERSION(), bump DKMS version for first release 2021-01-23 12:13:35 -06:00
Adam Madsen
24c9fc5473 [core] dkms: bump version 2021-01-23 11:56:27 -06:00
Adam Madsen
fc694db073 [amd] audio: Preserve PCI config space for audio device 2021-01-23 11:56:27 -06:00
Geoffrey McRae
6875092f2f [core] revert commits that are not quite ready yet
This reverts commit 30ffca808b.
This reverts commit 623fa20705.
2021-01-13 14:07:02 +11:00
Adam Madsen
30ffca808b [core] dkms: bump version 2021-01-13 13:55:51 +11:00
Adam Madsen
623fa20705 [amd] audio: Preserve PCI config space for audio device 2021-01-13 13:55:51 +11:00
BegoneRaven
eadbb20b38 Update README.md
Adding the 'Vega FE' Common Name for the Vega 10  Family under the Supported Devices section
2021-01-12 13:01:00 -06:00
Eugene Shatsky
f435bf9e93 Add lists of Polaris GPUs 2021-01-12 10:44:12 -08:00
Matthias Tafelmeier
765b05cdbd refer to uaccess to prevent build failure
Tackling following build glitch for 4.19 kernel:

/var/lib/dkms/vendor-reset/0.0.18/build/src/ioctl.c: In function ‘vendor_reset_ioctl_reset’:
/var/lib/dkms/vendor-reset/0.0.18/build/src/ioctl.c:34:7: error: implicit declaration of function ‘copy_from_user’; did you mean ‘sg_copy_from_buffer’? [-Werror=implicit-function-declaration]
   if (copy_from_user(&iodev, (void __user *)arg, sizeof(iodev)))
       ^~~~~~~~~~~~~~
       sg_copy_from_buffer
cc1: some warnings being treated as errors
make[4]: *** [/usr/src/linux-headers-4.19.0-12-common/scripts/Makefile.build:308: /var/lib/dkms/vendor-reset/0.0.18/build/src/ioctl.o] Error 1
make[4]: *** Waiting for unfinished jobs....
make[3]: *** [/usr/src/linux-headers-4.19.0-12-common/Makefile:1565: _module_/var/lib/dkms/vendor-reset/0.0.18/build] Error 2
make[2]: *** [Makefile:146: sub-make] Error 2
make[1]: *** [Makefile:8: all] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.19.0-12-amd64'
make: *** [Makefile:8: build] Error 2
2020-12-23 05:38:44 +11:00
13 changed files with 367 additions and 220 deletions

View File

@@ -55,11 +55,12 @@ updating your initrd.
| Vendor | Family | Common Name(s)
|---|---|---|
|AMD|Polaris 10|
|AMD|Polaris 11|
|AMD|Polaris 12|
|AMD|Vega 10| Vega 56/64 |
|AMD|Polaris 10| RX 470, 480, 570, 580, 590
|AMD|Polaris 11| RX 460, 560
|AMD|Polaris 12| RX 540, 550
|AMD|Vega 10| Vega 56/64/FE |
|AMD|Vega 20| Radeon VII |
|AMD|Vega 20| Instinct MI100 |
|AMD|Navi 10| 5600XT, 5700, 5700XT
|AMD|Navi 12| Pro 5600M |
|AMD|Navi 14| Pro 5300, RX 5300, 5500XT

View File

@@ -1,5 +1,5 @@
PACKAGE_NAME="vendor-reset"
PACKAGE_VERSION="0.0.18"
PACKAGE_VERSION="0.1.1"
BUILT_MODULE_NAME[0]="${PACKAGE_NAME}"
MAKE[0]="make KDIR=${kernel_source_dir}"
CLEAN="make KDIR=${kernel_source_dir} clean"

View File

@@ -28,7 +28,12 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 12, 0)
#include <asm/unaligned.h>
#else
#include <linux/unaligned.h>
#endif
//#include <drm/drm_util.h>
//#include <drm/drm_print.h>
@@ -39,6 +44,10 @@
#include "atom-names.h"
#include "atom-bits.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
#define strscpy strlcpy
#endif
#define ATOM_COND_ABOVE 0
#define ATOM_COND_ABOVEOREQUAL 1
#define ATOM_COND_ALWAYS 2
@@ -1424,7 +1433,7 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
if (*str != '\0')
{
pr_info("ATOM BIOS: %s\n", str);
strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
strscpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
}
return ctx;

View File

@@ -82,10 +82,16 @@ int amd_common_pre_reset(struct vendor_reset_dev *dev)
pci_save_state(pdev);
priv->saved_state = pci_store_saved_state(pdev);
pci_read_config_word(pdev, PCI_COMMAND, &priv->cfg);
pci_write_config_word(pdev, PCI_COMMAND, priv->cfg | PCI_COMMAND_MEMORY);
pci_write_config_word(pdev, PCI_COMMAND, priv->cfg | PCI_COMMAND_MEMORY | PCI_COMMAND_INTX_DISABLE);
if (!pci_wait_for_pending_transaction(pdev))
vr_warn(dev, "Timed out waiting for transaction to clear\n");
priv->audio_pdev = pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus),
pdev->bus->number, 1);
if (priv->audio_pdev)
{
pci_set_power_state(priv->audio_pdev, PCI_D0);
pci_clear_master(priv->audio_pdev);
pci_save_state(priv->audio_pdev);
}
return 0;
@@ -99,7 +105,8 @@ int amd_common_post_reset(struct vendor_reset_dev *dev)
struct amd_vendor_private *priv = amd_private(dev);
struct pci_dev *pdev = dev->pdev;
if (priv->mmio) {
if (priv->mmio)
{
iounmap(priv->mmio);
priv->mmio = NULL;
}
@@ -117,9 +124,17 @@ int amd_common_post_reset(struct vendor_reset_dev *dev)
}
pci_write_config_word(pdev, PCI_COMMAND, priv->cfg);
if (priv->audio_pdev)
{
pci_restore_state(priv->audio_pdev);
pci_set_power_state(priv->audio_pdev, PCI_D3hot);
pci_dev_put(priv->audio_pdev);
priv->audio_pdev = NULL;
}
/* don't try to go to low power if reset failed */
// if (!dev->reset_ret)
// pci_set_power_state(pdev, PCI_D3hot);
if (!dev->reset_ret)
pci_set_power_state(pdev, PCI_D3hot);
kfree(priv);
dev->vendor_private = NULL;

View File

@@ -30,52 +30,52 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#define DRM_DEBUG(fmt, args...) pr_debug("vendor-reset-drm: " fmt, ##args)
static inline bool drm_can_sleep(void)
{
if (in_atomic() || in_dbg_master() || irqs_disabled())
return false;
return true;
if (in_atomic() || in_dbg_master() || irqs_disabled())
return false;
return true;
}
#define RREG32(reg) \
({ \
u32 __out; \
if (((reg) * 4) < adev_to_amd_private(adev)->mmio_size) \
__out = readl(adev_to_amd_private(adev)->mmio + (reg)); \
else \
{ \
writel(((reg) * 4), adev_to_amd_private(adev)->mmio + mmMM_INDEX); \
__out = readl(adev_to_amd_private(adev)->mmio + mmMM_DATA); \
} \
__out; \
#define RREG32(reg) \
({ \
u32 __out; \
if (((reg)*4) < adev_to_amd_private(adev)->mmio_size) \
__out = readl(adev_to_amd_private(adev)->mmio + (reg)); \
else \
{ \
writel(((reg)*4), adev_to_amd_private(adev)->mmio + mmMM_INDEX); \
__out = readl(adev_to_amd_private(adev)->mmio + mmMM_DATA); \
} \
__out; \
})
#define WREG32(reg, v) \
do \
{ \
if (((reg) * 4) < adev_to_amd_private(adev)->mmio_size) \
writel(v, adev_to_amd_private(adev)->mmio + (reg)); \
else \
{ \
writel(((reg) * 4), adev_to_amd_private(adev)->mmio + mmMM_INDEX); \
writel(v, adev_to_amd_private(adev)->mmio + mmMM_DATA); \
} \
#define WREG32(reg, v) \
do \
{ \
if (((reg)*4) < adev_to_amd_private(adev)->mmio_size) \
writel(v, adev_to_amd_private(adev)->mmio + (reg)); \
else \
{ \
writel(((reg)*4), adev_to_amd_private(adev)->mmio + mmMM_INDEX); \
writel(v, adev_to_amd_private(adev)->mmio + mmMM_DATA); \
} \
} while (0)
#define WREG32_PCIE(reg, v) \
do \
{ \
WREG32(mmPCIE_INDEX2, reg); \
(void)RREG32(mmPCIE_INDEX2); \
WREG32(mmPCIE_DATA2, v); \
(void)RREG32(mmPCIE_DATA2); \
#define WREG32_PCIE(reg, v) \
do \
{ \
WREG32(mmPCIE_INDEX2, reg); \
(void)RREG32(mmPCIE_INDEX2); \
WREG32(mmPCIE_DATA2, v); \
(void)RREG32(mmPCIE_DATA2); \
} while (0)
#define RREG32_PCIE(reg) \
({ \
u32 __tmp_read; \
WREG32(mmPCIE_INDEX2, reg); \
(void)RREG32(mmPCIE_INDEX2); \
__tmp_read = RREG32(mmPCIE_DATA2); \
__tmp_read; \
#define RREG32_PCIE(reg) \
({ \
u32 __tmp_read; \
WREG32(mmPCIE_INDEX2, reg); \
(void)RREG32(mmPCIE_INDEX2); \
__tmp_read = RREG32(mmPCIE_DATA2); \
__tmp_read; \
})
/* KIQ is only used for SRIOV accesses, we are not targetting these devices so
@@ -117,6 +117,8 @@ struct amd_vendor_private
{
u16 cfg;
struct pci_dev *audio_pdev;
struct vendor_reset_dev *vdev;
struct pci_saved_state *saved_state;
struct amd_fake_dev adev;

View File

@@ -25,7 +25,4 @@ Place, Suite 330, Boston, MA 02111-1307 USA
int atom_bios_init(struct amd_fake_dev *adev);
void atom_bios_fini(struct amd_fake_dev *adev);
/* this is actually in amdgpu_bios.c */
bool amdgpu_get_bios(struct amd_fake_dev *adev);
#endif

View File

@@ -33,149 +33,15 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "nv.h"
#include "psp_gfx_if.h"
#include "smu_v11_0_ppsmc.h"
#include "thm/thm_11_0_2_offset.h"
#include "thm/thm_11_0_2_sh_mask.h"
enum navi10_reset_type
{
NAVI10_RESET_NONE,
NAVI10_RESET_BACO,
NAVI10_RESET_MODE1,
};
static int navi10_needs_reset(struct vendor_reset_dev *dev, enum navi10_reset_type *type)
{
struct amd_vendor_private *priv = amd_private(dev);
struct amd_fake_dev *adev = &priv->adev;
u32 smu_resp, mp1_intr, psp_bl_ready, sol;
/* collect some state info */
sol = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
smu_resp = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90);
mp1_intr = (RREG32_PCIE(MP1_Public |
(smnMP1_FIRMWARE_FLAGS & 0xffffffff)) &
MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >>
MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT;
psp_bl_ready = !!(RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35) & 0x80000000L);
vr_info(dev, "SMU response reg: %x, sol reg: %x, mp1 intr enabled? %s, bl ready? %s\n",
smu_resp, sol, mp1_intr ? "yes" : "no",
psp_bl_ready ? "yes" : "no");
if (!sol && !mp1_intr && psp_bl_ready)
/* okay, if we're in this state, we're probably reset */
*type = NAVI10_RESET_NONE;
else if (sol && sol != ~1L && smu_resp != 0 && mp1_intr && psp_bl_ready)
*type = NAVI10_RESET_BACO;
else
*type = NAVI10_RESET_MODE1;
return *type != NAVI10_RESET_NONE;
}
static int navi10_mode1_reset(struct vendor_reset_dev *dev)
{
struct amd_vendor_private *priv = amd_private(dev);
struct amd_fake_dev *adev = &priv->adev;
u32 offset, tmp;
int ret = 0, timeout;
vr_info(dev, "begin psp mode 1 reset\n");
amdgpu_atombios_scratch_regs_engine_hung(adev, true);
pci_save_state(dev->pdev);
/* check validity of PSP before reset */
offset = SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64);
tmp = psp_wait_for(adev, offset, 0x80000000, 0x8000FFFF, false);
if (tmp)
vr_warn(dev, "timed out waiting for PSP to reach valid state, but continuing anyway\n");
/* reset command */
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, GFX_CTRL_CMD_ID_MODE1_RST);
msleep(500);
/* wait for ACK */
offset = SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_33);
tmp = psp_wait_for(adev, offset, 0x80000000, 0x80000000, false);
if (tmp)
{
vr_warn(dev, "PSP did not acknowledger reset\n");
ret = -EINVAL;
goto out;
}
vr_info(dev, "mode1 reset succeeded\n");
pci_restore_state(dev->pdev);
for (timeout = 100000; timeout; --timeout)
{
tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_RCC_CONFIG_MEMSIZE);
if (tmp != 0xffffffff)
break;
udelay(1);
}
out:
return ret;
}
static int navi10_wait_for_psp_ready(struct vendor_reset_dev *dev)
{
struct amd_vendor_private *priv = amd_private(dev);
struct amd_fake_dev *adev = &priv->adev;
int timeout;
/*
* this takes a long time :(
*/
for (timeout = 100; timeout; --timeout)
{
/* see if PSP bootloader comes back */
if (RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35) & 0x80000000L)
return 0;
msleep(100);
}
return (RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35) & 0x80000000L) ? 0 : -ETIMEDOUT;
}
static int navi10_baco_reset(struct vendor_reset_dev *dev)
{
struct amd_vendor_private *priv = amd_private(dev);
struct amd_fake_dev *adev = &priv->adev;
int ret, tmp;
vr_info(dev, "Entering BACO\n");
/* BACO_SEQ_BACO */
ret = smum_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_ArmD3, 0, NULL);
if (ret)
return ret;
tmp = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL);
tmp |= 0x80000000;
WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, tmp);
ret = smum_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_EnterBaco, 0, NULL);
if (ret)
return ret;
msleep(500);
vr_info(dev, "Exiting BACO\n");
ret = smum_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_ExitBaco, 0, NULL);
return ret;
}
extern bool amdgpu_get_bios(struct amd_fake_dev *adev);
static int amd_navi10_reset(struct vendor_reset_dev *dev)
{
struct amd_vendor_private *priv = amd_private(dev);
struct amd_fake_dev *adev;
int ret = 0, timeout;
u32 sol;
enum navi10_reset_type reset_type;
u32 sol, smu_resp, mp1_intr, psp_bl_ready, tmp, offset;
adev = &priv->adev;
ret = amd_fake_dev_init(adev, dev);
@@ -227,37 +93,141 @@ static int amd_navi10_reset(struct vendor_reset_dev *dev)
}
if (sol == ~1L)
/* continuing anyway because sometimes it can still be reset from here */
{
vr_warn(dev, "Timed out waiting for SOL to be valid\n");
/* continuing anyway because sometimes it can still be reset from here */
}
if (!navi10_needs_reset(dev, &reset_type))
vr_info(dev, "bus reset disabled? %s\n", (dev->pdev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET) ? "yes" : "no");
/* collect some info for logging for now */
smu_resp = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90);
mp1_intr = (RREG32_PCIE(MP1_Public |
(smnMP1_FIRMWARE_FLAGS & 0xffffffff)) &
MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >>
MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT;
psp_bl_ready = !!(RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35) & 0x80000000L);
vr_info(dev, "SMU response reg: %x, sol reg: %x, mp1 intr enabled? %s, bl ready? %s\n",
smu_resp, sol, mp1_intr ? "yes" : "no",
psp_bl_ready ? "yes" : "no");
/* okay, if we're in this state, we're probably reset */
if (sol == 0x0 && !mp1_intr && psp_bl_ready)
goto free_adev;
if (reset_type == NAVI10_RESET_BACO)
ret = navi10_baco_reset(dev);
/* this tells the drivers nvram is lost and everything needs to be reset */
vr_info(dev, "Clearing scratch regs 6 and 7\n");
WREG32(adev->bios_scratch_reg_offset + 6, 0);
WREG32(adev->bios_scratch_reg_offset + 7, 0);
/* it only makes sense to reset mp1 if it's running
* XXX: is this even necessary? in early testing, I ran into
* situations where MP1 was alive but not responsive, but in
* later testing I have not been able to replicate this scenario.
*/
if (smu_resp != 0x01 && mp1_intr)
{
vr_info(dev, "MP1 reset\n");
WREG32_PCIE(MP1_Public | (smnMP1_PUB_CTRL & 0xffffffff),
1 & MP1_SMN_PUB_CTRL__RESET_MASK);
WREG32_PCIE(MP1_Public | (smnMP1_PUB_CTRL & 0xffffffff),
1 & ~MP1_SMN_PUB_CTRL__RESET_MASK);
vr_info(dev, "wait for MP1\n");
for (timeout = 100000; timeout; --timeout)
{
tmp = RREG32_PCIE(MP1_Public |
(smnMP1_FIRMWARE_FLAGS & 0xffffffff));
if ((tmp &
MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >>
MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT)
break;
udelay(1);
}
if (!timeout &&
!((tmp & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >>
MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT))
{
vr_warn(dev, "timed out waiting for MP1 reset\n");
}
smu_wait(adev);
smu_resp = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90);
vr_info(dev, "SMU resp reg: %x\n", tmp);
}
/*
* again, this only makes sense if we have an SMU to talk to
* some of these may fail, that's okay. we're just turning off as many
* things as possible
*/
if (mp1_intr)
{
smum_send_msg_to_smc(adev, PPSMC_MSG_DisallowGfxOff, NULL);
smum_send_msg_to_smc(adev, PPSMC_MSG_PrepareMp1ForReset, NULL);
}
vr_info(dev, "begin psp mode 1 reset\n");
amdgpu_atombios_scratch_regs_engine_hung(adev, true);
pci_save_state(dev->pdev);
/* check validity of PSP before reset */
offset = SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64);
tmp = psp_wait_for(adev, offset, 0x80000000, 0x8000FFFF, false);
if (tmp)
vr_warn(dev, "timed out waiting for PSP to reach valid state, but continuing anyway\n");
/* reset command */
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, GFX_CTRL_CMD_ID_MODE1_RST);
msleep(500);
/* wait for ACK */
offset = SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_33);
tmp = psp_wait_for(adev, offset, 0x80000000, 0x80000000, false);
if (tmp)
{
vr_warn(dev, "PSP did not acknowledger reset\n");
ret = -EINVAL;
goto out;
}
vr_info(dev, "mode1 reset succeeded\n");
pci_restore_state(dev->pdev);
for (timeout = 100000; timeout; --timeout)
{
tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_RCC_CONFIG_MEMSIZE);
if (tmp != 0xffffffff)
break;
udelay(1);
}
/*
* this takes a long time :(
*/
for (timeout = 100; timeout; --timeout)
{
/* see if PSP bootloader comes back */
if (RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35) & 0x80000000L)
break;
msleep(100);
}
if (!timeout && !(RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35) & 0x80000000L))
{
vr_warn(dev, "timed out waiting for PSP bootloader to respond after reset\n");
ret = -ETIME;
}
else
{
ret = navi10_mode1_reset(dev);
if (ret)
goto mode1_out;
vr_info(dev, "PSP mode1 reset successful\n");
if ((ret = navi10_wait_for_psp_ready(dev)))
vr_warn(dev, "timed out waiting for PSP bootloader to respond after reset\n");
else
vr_info(dev, "PSP mode1 reset successful\n");
mode1_out:
pci_restore_state(dev->pdev);
amdgpu_atombios_scratch_regs_engine_hung(adev, false);
}
if (!ret)
{
/* this tells the drivers nvram is lost and everything needs to be reset */
vr_info(dev, "Clearing scratch regs 6 and 7\n");
WREG32(adev->bios_scratch_reg_offset + 6, 0);
WREG32(adev->bios_scratch_reg_offset + 7, 0);
}
out:
pci_restore_state(dev->pdev);
amdgpu_atombios_scratch_regs_engine_hung(adev, false);
free_adev:
amd_fake_dev_fini(adev);
@@ -265,10 +235,11 @@ free_adev:
return ret;
}
const struct vendor_reset_ops amd_navi10_ops = {
.version = {2, 0},
.probe = amd_common_probe,
.pre_reset = amd_common_pre_reset,
.reset = amd_navi10_reset,
.post_reset = amd_common_post_reset,
const struct vendor_reset_ops amd_navi10_ops =
{
.version = {1, 1},
.probe = amd_common_probe,
.pre_reset = amd_common_pre_reset,
.reset = amd_navi10_reset,
.post_reset = amd_common_post_reset,
};

View File

@@ -102,6 +102,9 @@ Place, Suite 330, Boston, MA 02111-1307 USA
{PCI_VENDOR_ID_ATI, 0x7360, op, DEVICE_INFO(AMD_NAVI12)}, \
{PCI_VENDOR_ID_ATI, 0x7362, op, DEVICE_INFO(AMD_NAVI12)}
#define _AMD_ARCTURUS(op) \
{PCI_VENDOR_ID_ATI, 0x738c, op, DEVICE_INFO(AMD_VEGA20)} //Instinct MI100
static const struct vendor_reset_cfg vendor_reset_devices[] = {
_AMD_POLARIS10(&amd_polaris10_ops),
_AMD_POLARIS11(&amd_polaris10_ops),
@@ -111,6 +114,7 @@ static const struct vendor_reset_cfg vendor_reset_devices[] = {
_AMD_NAVI10(&amd_navi10_ops),
_AMD_NAVI14(&amd_navi10_ops),
_AMD_NAVI12(&amd_navi10_ops),
_AMD_ARCTURUS(&amd_vega20_ops),
/* end of array guard */
{.vendor = 0}

View File

@@ -22,6 +22,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <linux/ftrace.h>
#include <linux/kprobes.h>
#include <linux/pci.h>
#include <linux/version.h>
#include "ftrace.h"
@@ -48,8 +49,14 @@ static int resolve_hook_address(struct ftrace_hook *hook)
return 0;
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0))
static void notrace fh_trace_thunk(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *ops, struct pt_regs *regs)
{
#else
static void notrace fh_trace_thunk(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *ops, struct ftrace_regs *fregs)
{
struct pt_regs *regs = ftrace_get_regs(fregs);
#endif
struct ftrace_hook *hook = to_ftrace_hook(ops);
if (!within_module(parent_ip, THIS_MODULE))

View File

@@ -30,7 +30,11 @@ static bool hook_installed = false;
static int (*orig_pci_dev_specific_reset)(struct pci_dev *dev, int probe);
/* TCO breaks the hook, we must disable it for this function */
#if defined(__GNUC__) && !defined(__llvm__)
__attribute__((optimize("-fno-optimize-sibling-calls")))
#elif defined(__clang__)
__attribute__((disable_tail_calls))
#endif
static int hooked_pci_dev_specific_reset(struct pci_dev *dev, int probe)
{
int ret;

View File

@@ -21,6 +21,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "vendor-reset-ioctl.h"
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#define VENDOR_RESET_IOCTL_DEVNAME "vendor_reset"

View File

@@ -53,3 +53,4 @@ module_exit(vendor_reset_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Geoffrey McRae <geoff@hostfission.com>");
MODULE_AUTHOR("Adam Madsen <adam@ajmadsen.com>");
MODULE_VERSION("0.1.1");

135
udev/99-vendor-reset.rules Normal file
View File

@@ -0,0 +1,135 @@
# Rules to ensure vendor-reset is loaded and the reset_method for our devices is set to 'device_specific' for kernel 5.15+
# (the module must be loaded, otherwise setting this may fail)
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67C0", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67C1", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67C2", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67C4", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67C7", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67D0", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67DF", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67C8", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67C9", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67CA", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67CC", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67CF", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x6FDF", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67E0", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67E3", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67E8", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67EB", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67EF", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67FF", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67E1", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67E7", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x67E9", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x6980", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x6981", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x6985", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x6986", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x6987", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x6995", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x6997", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x699F", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x6860", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x6861", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x6862", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x6863", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x6864", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x6867", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x6868", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x6869", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x686a", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x686b", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x686c", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x686d", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x686e", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x686f", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x687f", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x66a0", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x66a1", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x66a2", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x66a3", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x66a4", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x66a7", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x66af", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x7310", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x7312", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x7318", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x7319", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x731a", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x731b", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x731e", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x731f", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x7340", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x7341", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x7347", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x734F", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x7360", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x7362", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x1002", ATTR{device}=="0x738c", RUN+="/bin/sh -c '/sbin/modprobe vendor-reset; echo device_specific > /sys$env{DEVPATH}/reset_method'"