From 623fa20705d10ff8f3ffed56895cebc7ce8106f9 Mon Sep 17 00:00:00 2001 From: Adam Madsen Date: Tue, 12 Jan 2021 11:22:18 -0600 Subject: [PATCH] [amd] audio: Preserve PCI config space for audio device --- src/amd/common.c | 20 ++++++++++++- src/amd/common.h | 78 +++++++++++++++++++++++++----------------------- 2 files changed, 59 insertions(+), 39 deletions(-) diff --git a/src/amd/common.c b/src/amd/common.c index 57563df..a888e5b 100644 --- a/src/amd/common.c +++ b/src/amd/common.c @@ -84,6 +84,15 @@ int amd_common_pre_reset(struct vendor_reset_dev *dev) pci_read_config_word(pdev, PCI_COMMAND, &priv->cfg); pci_write_config_word(pdev, PCI_COMMAND, priv->cfg | PCI_COMMAND_MEMORY | PCI_COMMAND_INTX_DISABLE); + 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; err_free: @@ -96,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; } @@ -114,6 +124,14 @@ 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); diff --git a/src/amd/common.h b/src/amd/common.h index 4c8dd66..57b855c 100644 --- a/src/amd/common.h +++ b/src/amd/common.h @@ -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;