Skip to content

Instantly share code, notes, and snippets.

@gnif
Last active July 2, 2020 10:02
Show Gist options
  • Save gnif/a4ac1d4fb6d7ba04347dcc91a579ee36 to your computer and use it in GitHub Desktop.
Save gnif/a4ac1d4fb6d7ba04347dcc91a579ee36 to your computer and use it in GitHub Desktop.

Revisions

  1. gnif revised this gist Nov 21, 2018. 1 changed file with 3 additions and 6 deletions.
    9 changes: 3 additions & 6 deletions vega-10-reset.c
    Original file line number Diff line number Diff line change
    @@ -21,16 +21,14 @@ static int reset_amdgpu_vega(struct pci_dev *dev, int probe) {
    rmmio_size = pci_resource_len(dev, 5);
    rmmio = ioremap(rmmio_base, rmmio_size);
    if (rmmio == NULL) {
    printk(KERN_ERR
    "[reset_amdgpu_vega] failed to ioremap the device\n");
    printk(KERN_ERR "[reset_amdgpu_vega] failed to ioremap the device\n");
    ret = -ENOMEM;
    goto out;
    }
    #if 0
    /* check the sign of life register to see if we even need to reset */
    if (!readl(rmmio + mmMP0_SMN_C2PMSG_81)) {
    printk(KERN_INFO
    "[reset_amdgpu_vega] psp is not running\n");
    printk(KERN_INFO "[reset_amdgpu_vega] psp is not running\n");
    ret = 0;
    goto out_unmap;
    }
    @@ -46,8 +44,7 @@ static int reset_amdgpu_vega(struct pci_dev *dev, int probe) {
    udelay(1);
    }
    if (ret) {
    printk(KERN_ERR
    "[reset_amdgpu_vega] psp is not working correctly\n");
    printk(KERN_ERR "[reset_amdgpu_vega] psp is not working correctly\n");
    goto out_unmap;
    }
    #endif
  2. gnif created this gist Nov 20, 2018.
    84 changes: 84 additions & 0 deletions vega-10-reset.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    static int reset_amdgpu_vega(struct pci_dev *dev, int probe) {
    #define AMDGPU_MAX_USEC_TIMEOUT 100000
    #define MP0_BASE 0x16000
    #define mmMP0_SMN_C2PMSG_33 ((MP0_BASE + 0x0061) * 4)
    #define mmMP0_SMN_C2PMSG_64 ((MP0_BASE + 0x0080) * 4)
    #define mmMP0_SMN_C2PMSG_81 ((MP0_BASE + 0x0091) * 4)

    resource_size_t rmmio_base, rmmio_size;
    void __iomem *rmmio;
    int ret;
    int i;
    uint32_t val;

    if (probe)
    return 0;

    pci_clear_master(dev);
    pci_save_state(dev);

    rmmio_base = pci_resource_start(dev, 5);
    rmmio_size = pci_resource_len(dev, 5);
    rmmio = ioremap(rmmio_base, rmmio_size);
    if (rmmio == NULL) {
    printk(KERN_ERR
    "[reset_amdgpu_vega] failed to ioremap the device\n");
    ret = -ENOMEM;
    goto out;
    }
    #if 0
    /* check the sign of life register to see if we even need to reset */
    if (!readl(rmmio + mmMP0_SMN_C2PMSG_81)) {
    printk(KERN_INFO
    "[reset_amdgpu_vega] psp is not running\n");
    ret = 0;
    goto out_unmap;
    }

    /* ensure the PSP is working */
    ret = -EINVAL;
    for(i = 0; i < AMDGPU_MAX_USEC_TIMEOUT; i++) {
    val = readl(rmmio + mmMP0_SMN_C2PMSG_64);
    if ((val & 0x8000FFFF) == 0x80000000) {
    ret = 0;
    break;
    }
    udelay(1);
    }
    if (ret) {
    printk(KERN_ERR
    "[reset_amdgpu_vega] psp is not working correctly\n");
    goto out_unmap;
    }
    #endif
    /* send the mode 1 reset command */
    writel(0x70000, rmmio + mmMP0_SMN_C2PMSG_64);

    mdelay(1000);

    /* wait for the reset to complete */
    ret = -EINVAL;
    for(i = 0; i < AMDGPU_MAX_USEC_TIMEOUT; i++) {
    val = readl(rmmio + mmMP0_SMN_C2PMSG_33);
    if ((val & 0x80000000) == 0x80000000) {
    ret = 0;
    break;
    }
    udelay(1);
    }
    if (ret) {
    printk(KERN_ERR "[reset_amdgpu_vega] reset failed\n");
    goto out_unmap;
    }

    pcie_flr(dev);

    ret = 0;
    printk(KERN_INFO "[reset_amdgpu_vega] reset success\n");

    out_unmap:
    iounmap(rmmio);
    out:
    pci_restore_state(dev);
    return ret;
    }