mirror of
https://github.com/torvalds/linux
synced 2024-10-16 16:29:20 +00:00
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: Akshu Agrawal <akshu.agrawal@amd.com> Link: https://lore.kernel.org/r/20200724195600.11798-1-akshu.agrawal@amd.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
3aecfc72d7
commit
1255296cf0
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue