PME_EN state needs to restored to the value set by fmw. For the devices which are not using I2S wake event which gets enabled by PME_EN bit, keeping PME_EN enabled burns considerable amount of power as it blocks low power state. For the devices using I2S wake event, PME_EN gets enabled in fmw and the state should be maintained after ACP Power On. Signed-off-by: Akshu Agrawal <akshu.agrawal@xxxxxxx> --- sound/soc/amd/raven/pci-acp3x.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/sound/soc/amd/raven/pci-acp3x.c b/sound/soc/amd/raven/pci-acp3x.c index ebf4388b6262..31b797c8bfe6 100644 --- a/sound/soc/amd/raven/pci-acp3x.c +++ b/sound/soc/amd/raven/pci-acp3x.c @@ -19,10 +19,12 @@ struct acp3x_dev_data { bool acp3x_audio_mode; struct resource *res; struct platform_device *pdev[ACP3x_DEVS]; + u32 pme_en; }; -static int acp3x_power_on(void __iomem *acp3x_base) +static int acp3x_power_on(struct acp3x_dev_data *adata) { + void __iomem *acp3x_base = adata->acp3x_base; u32 val; int timeout; @@ -39,10 +41,10 @@ static int acp3x_power_on(void __iomem *acp3x_base) while (++timeout < 500) { val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS); if (!val) { - /* Set PME_EN as after ACP power On, - * PME_EN gets cleared + /* ACP power On clears PME_EN. + * Restore the value to its prior state */ - rv_writel(0x1, acp3x_base + mmACP_PME_EN); + rv_writel(adata->pme_en, acp3x_base + mmACP_PME_EN); return 0; } udelay(1); @@ -74,12 +76,13 @@ static int acp3x_reset(void __iomem *acp3x_base) return -ETIMEDOUT; } -static int acp3x_init(void __iomem *acp3x_base) +static int acp3x_init(struct acp3x_dev_data *adata) { + void __iomem *acp3x_base = adata->acp3x_base; int ret; /* power on */ - ret = acp3x_power_on(acp3x_base); + ret = acp3x_power_on(adata); if (ret) { pr_err("ACP3x power on failed\n"); return ret; @@ -151,7 +154,9 @@ static int snd_acp3x_probe(struct pci_dev *pci, } pci_set_master(pci); pci_set_drvdata(pci, adata); - ret = acp3x_init(adata->acp3x_base); + /* Save ACP_PME_EN state */ + adata->pme_en = rv_readl(adata->acp3x_base + mmACP_PME_EN); + ret = acp3x_init(adata); if (ret) goto disable_msi; @@ -274,7 +279,7 @@ static int snd_acp3x_resume(struct device *dev) struct acp3x_dev_data *adata; adata = dev_get_drvdata(dev); - ret = acp3x_init(adata->acp3x_base); + ret = acp3x_init(adata); if (ret) { dev_err(dev, "ACP init failed\n"); return ret; -- 2.20.1