Skip to content

Commit

Permalink
ASoC: SOF: amd: refactor acp driver pm ops
Browse files Browse the repository at this point in the history
Refactor acp driver pm ops to support SoundWire interface.

When SoundWire configuration is enabled, In case of ClockStopMode,
DSP soft reset should be applied and for rest of the scenarios
acp init/deinit sequence should be invoked.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
  • Loading branch information
vijendarmukunda committed Nov 14, 2023
1 parent afb0249 commit cb5e5ee
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 5 deletions.
3 changes: 3 additions & 0 deletions sound/soc/sof/amd/acp-dsp-offset.h
Expand Up @@ -102,4 +102,7 @@
/* Cache window registers */
#define ACP_DSP0_CACHE_OFFSET0 0x0420
#define ACP_DSP0_CACHE_SIZE0 0x0424

#define ACP_SW0_EN 0x3000
#define ACP_SW1_EN 0x3C00
#endif
59 changes: 54 additions & 5 deletions sound/soc/sof/amd/acp.c
Expand Up @@ -468,6 +468,31 @@ static int acp_reset(struct snd_sof_dev *sdev)
return ret;
}

static int acp_dsp_reset(struct snd_sof_dev *sdev)
{
unsigned int val;
int ret;

snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SOFT_RESET, ACP_DSP_ASSERT_RESET);

ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_SOFT_RESET, val,
val & ACP_DSP_SOFT_RESET_DONE_MASK,
ACP_REG_POLL_INTERVAL, ACP_REG_POLL_TIMEOUT_US);
if (ret < 0) {
dev_err(sdev->dev, "timeout asserting reset\n");
return ret;
}

snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SOFT_RESET, ACP_DSP_RELEASE_RESET);

ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_SOFT_RESET, val, !val,
ACP_REG_POLL_INTERVAL, ACP_REG_POLL_TIMEOUT_US);
if (ret < 0)
dev_err(sdev->dev, "timeout in releasing reset\n");

return ret;
}

static int acp_init(struct snd_sof_dev *sdev)
{
int ret;
Expand All @@ -484,10 +509,28 @@ static int acp_init(struct snd_sof_dev *sdev)
return acp_reset(sdev);
}

static bool check_acp_sdw_enable_status(struct snd_sof_dev *sdev)
{
u32 sdw0_en, sdw1_en;
struct acp_dev_data *acp_data;

acp_data = sdev->pdata->hw_pdata;
if (!acp_data->sdw)
return false;

sdw0_en = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SW0_EN);
sdw1_en = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SW1_EN);
acp_data->sdw_en_stat = sdw0_en || sdw1_en;
return acp_data->sdw_en_stat;
}

int amd_sof_acp_suspend(struct snd_sof_dev *sdev, u32 target_state)
{
int ret;

if (check_acp_sdw_enable_status(sdev))
return acp_dsp_reset(sdev);

ret = acp_reset(sdev);
if (ret) {
dev_err(sdev->dev, "ACP Reset failed\n");
Expand All @@ -503,13 +546,19 @@ EXPORT_SYMBOL_NS(amd_sof_acp_suspend, SND_SOC_SOF_AMD_COMMON);
int amd_sof_acp_resume(struct snd_sof_dev *sdev)
{
int ret;
struct acp_dev_data *acp_data;

ret = acp_init(sdev);
if (ret) {
dev_err(sdev->dev, "ACP Init failed\n");
return ret;
acp_data = sdev->pdata->hw_pdata;
if (!acp_data->sdw_en_stat) {
ret = acp_init(sdev);
if (ret) {
dev_err(sdev->dev, "ACP Init failed\n");
return ret;
}
return acp_memory_init(sdev);
} else {
return acp_dsp_reset(sdev);
}
return acp_memory_init(sdev);
}
EXPORT_SYMBOL_NS(amd_sof_acp_resume, SND_SOC_SOF_AMD_COMMON);

Expand Down
4 changes: 4 additions & 0 deletions sound/soc/sof/amd/acp.h
Expand Up @@ -32,6 +32,9 @@
#define ACP_ASSERT_RESET 0x01
#define ACP_RELEASE_RESET 0x00
#define ACP_SOFT_RESET_DONE_MASK 0x00010001
#define ACP_DSP_ASSERT_RESET 0x04
#define ACP_DSP_RELEASE_RESET 0x00
#define ACP_DSP_SOFT_RESET_DONE_MASK 0x00050004

#define ACP_DSP_INTR_EN_MASK 0x00000001
#define ACP3X_SRAM_PTE_OFFSET 0x02050000
Expand Down Expand Up @@ -238,6 +241,7 @@ struct acp_dev_data {
bool enable_fw_debug;
bool is_dram_in_use;
bool is_sram_in_use;
bool sdw_en_stat;
};

void memcpy_to_scratch(struct snd_sof_dev *sdev, u32 offset, unsigned int *src, size_t bytes);
Expand Down

0 comments on commit cb5e5ee

Please sign in to comment.