Skip to content

Commit dc6458e

Browse files
vijendarmukundabroonie
authored andcommitted
ASoC: amd: ps: fix for soundwire failures during hibernation exit sequence
During the hibernate entry sequence, ACP registers will be reset to default values and acp ip will be completely powered off including acp SoundWire pads. During resume sequence, if acp SoundWire pad keeper enable register is not restored along with pad pulldown control register value, then SoundWire manager links won't be powered on correctly results in peripheral register access failures and completely audio function is broken. Add code to store the acp SoundWire pad keeper enable register and acp pad pulldown ctrl register values before entering into suspend state and restore the register values during resume sequence based on condition check for acp SoundWire pad keeper enable register for ACP6.3, ACP7.0 & ACP7.1 platforms. Fixes: 4916283 ("ASoC: amd: ps: add callback functions for acp pci driver pm ops") Signed-off-by: Vijendar Mukunda <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent bf39286 commit dc6458e

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

sound/soc/amd/ps/acp63.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,8 @@ struct acp_hw_ops {
334334
* @addr: pci ioremap address
335335
* @reg_range: ACP reigister range
336336
* @acp_rev: ACP PCI revision id
337+
* @acp_sw_pad_keeper_en: store acp SoundWire pad keeper enable register value
338+
* @acp_pad_pulldown_ctrl: store acp pad pulldown control register value
337339
* @acp63_sdw0-dma_intr_stat: DMA interrupt status array for ACP6.3 platform SoundWire
338340
* manager-SW0 instance
339341
* @acp63_sdw_dma_intr_stat: DMA interrupt status array for ACP6.3 platform SoundWire
@@ -367,6 +369,8 @@ struct acp63_dev_data {
367369
u32 addr;
368370
u32 reg_range;
369371
u32 acp_rev;
372+
u32 acp_sw_pad_keeper_en;
373+
u32 acp_pad_pulldown_ctrl;
370374
u16 acp63_sdw0_dma_intr_stat[ACP63_SDW0_DMA_MAX_STREAMS];
371375
u16 acp63_sdw1_dma_intr_stat[ACP63_SDW1_DMA_MAX_STREAMS];
372376
u16 acp70_sdw0_dma_intr_stat[ACP70_SDW0_DMA_MAX_STREAMS];

sound/soc/amd/ps/ps-common.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ static int __maybe_unused snd_acp63_suspend(struct device *dev)
160160

161161
adata = dev_get_drvdata(dev);
162162
if (adata->is_sdw_dev) {
163+
adata->acp_sw_pad_keeper_en = readl(adata->acp63_base + ACP_SW0_PAD_KEEPER_EN);
164+
adata->acp_pad_pulldown_ctrl = readl(adata->acp63_base + ACP_PAD_PULLDOWN_CTRL);
163165
adata->sdw_en_stat = check_acp_sdw_enable_status(adata);
164166
if (adata->sdw_en_stat) {
165167
writel(1, adata->acp63_base + ACP_ZSC_DSP_CTRL);
@@ -197,6 +199,7 @@ static int __maybe_unused snd_acp63_runtime_resume(struct device *dev)
197199
static int __maybe_unused snd_acp63_resume(struct device *dev)
198200
{
199201
struct acp63_dev_data *adata;
202+
u32 acp_sw_pad_keeper_en;
200203
int ret;
201204

202205
adata = dev_get_drvdata(dev);
@@ -209,6 +212,12 @@ static int __maybe_unused snd_acp63_resume(struct device *dev)
209212
if (ret)
210213
dev_err(dev, "ACP init failed\n");
211214

215+
acp_sw_pad_keeper_en = readl(adata->acp63_base + ACP_SW0_PAD_KEEPER_EN);
216+
dev_dbg(dev, "ACP_SW0_PAD_KEEPER_EN:0x%x\n", acp_sw_pad_keeper_en);
217+
if (!acp_sw_pad_keeper_en) {
218+
writel(adata->acp_sw_pad_keeper_en, adata->acp63_base + ACP_SW0_PAD_KEEPER_EN);
219+
writel(adata->acp_pad_pulldown_ctrl, adata->acp63_base + ACP_PAD_PULLDOWN_CTRL);
220+
}
212221
return ret;
213222
}
214223

@@ -408,6 +417,8 @@ static int __maybe_unused snd_acp70_suspend(struct device *dev)
408417

409418
adata = dev_get_drvdata(dev);
410419
if (adata->is_sdw_dev) {
420+
adata->acp_sw_pad_keeper_en = readl(adata->acp63_base + ACP_SW0_PAD_KEEPER_EN);
421+
adata->acp_pad_pulldown_ctrl = readl(adata->acp63_base + ACP_PAD_PULLDOWN_CTRL);
411422
adata->sdw_en_stat = check_acp_sdw_enable_status(adata);
412423
if (adata->sdw_en_stat) {
413424
writel(1, adata->acp63_base + ACP_ZSC_DSP_CTRL);
@@ -445,6 +456,7 @@ static int __maybe_unused snd_acp70_runtime_resume(struct device *dev)
445456
static int __maybe_unused snd_acp70_resume(struct device *dev)
446457
{
447458
struct acp63_dev_data *adata;
459+
u32 acp_sw_pad_keeper_en;
448460
int ret;
449461

450462
adata = dev_get_drvdata(dev);
@@ -459,6 +471,12 @@ static int __maybe_unused snd_acp70_resume(struct device *dev)
459471
if (ret)
460472
dev_err(dev, "ACP init failed\n");
461473

474+
acp_sw_pad_keeper_en = readl(adata->acp63_base + ACP_SW0_PAD_KEEPER_EN);
475+
dev_dbg(dev, "ACP_SW0_PAD_KEEPER_EN:0x%x\n", acp_sw_pad_keeper_en);
476+
if (!acp_sw_pad_keeper_en) {
477+
writel(adata->acp_sw_pad_keeper_en, adata->acp63_base + ACP_SW0_PAD_KEEPER_EN);
478+
writel(adata->acp_pad_pulldown_ctrl, adata->acp63_base + ACP_PAD_PULLDOWN_CTRL);
479+
}
462480
return ret;
463481
}
464482

0 commit comments

Comments
 (0)