Commit 1255296c authored by Akshu Agrawal's avatar Akshu Agrawal Committed by Mark Brown

ASoC: AMD: Restore PME_EN state at Power On

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: default avatarAkshu Agrawal <akshu.agrawal@amd.com>
Link: https://lore.kernel.org/r/20200724195600.11798-1-akshu.agrawal@amd.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 3aecfc72
...@@ -19,10 +19,12 @@ struct acp3x_dev_data { ...@@ -19,10 +19,12 @@ struct acp3x_dev_data {
bool acp3x_audio_mode; bool acp3x_audio_mode;
struct resource *res; struct resource *res;
struct platform_device *pdev[ACP3x_DEVS]; 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; u32 val;
int timeout; int timeout;
...@@ -39,10 +41,10 @@ static int acp3x_power_on(void __iomem *acp3x_base) ...@@ -39,10 +41,10 @@ static int acp3x_power_on(void __iomem *acp3x_base)
while (++timeout < 500) { while (++timeout < 500) {
val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS); val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS);
if (!val) { if (!val) {
/* Set PME_EN as after ACP power On, /* ACP power On clears PME_EN.
* PME_EN gets cleared * 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; return 0;
} }
udelay(1); udelay(1);
...@@ -74,12 +76,13 @@ static int acp3x_reset(void __iomem *acp3x_base) ...@@ -74,12 +76,13 @@ static int acp3x_reset(void __iomem *acp3x_base)
return -ETIMEDOUT; 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; int ret;
/* power on */ /* power on */
ret = acp3x_power_on(acp3x_base); ret = acp3x_power_on(adata);
if (ret) { if (ret) {
pr_err("ACP3x power on failed\n"); pr_err("ACP3x power on failed\n");
return ret; return ret;
...@@ -151,7 +154,9 @@ static int snd_acp3x_probe(struct pci_dev *pci, ...@@ -151,7 +154,9 @@ static int snd_acp3x_probe(struct pci_dev *pci,
} }
pci_set_master(pci); pci_set_master(pci);
pci_set_drvdata(pci, adata); 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) if (ret)
goto disable_msi; goto disable_msi;
...@@ -274,7 +279,7 @@ static int snd_acp3x_resume(struct device *dev) ...@@ -274,7 +279,7 @@ static int snd_acp3x_resume(struct device *dev)
struct acp3x_dev_data *adata; struct acp3x_dev_data *adata;
adata = dev_get_drvdata(dev); adata = dev_get_drvdata(dev);
ret = acp3x_init(adata->acp3x_base); ret = acp3x_init(adata);
if (ret) { if (ret) {
dev_err(dev, "ACP init failed\n"); dev_err(dev, "ACP init failed\n");
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment