diff options
author | Takashi Iwai <tiwai@suse.de> | 2022-03-21 16:19:21 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2022-03-21 16:19:21 +0100 |
commit | 646b907e1559f006c79a752ee3eebe220ceb983d (patch) | |
tree | 39e9607c0ab85af410d46d3d8edf8c8f36ea652f /sound/soc/sof/amd | |
parent | a6d4b685026cfe9837b07532db5d1e1681b5d129 (diff) | |
parent | 49a24e9d9c740d3bd8b1200f225f67d45e3d68a5 (diff) |
Merge tag 'asoc-v5.18' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v5.18
Quite a quiet release for ASoC, lots of work on drivers and platforms
but nothing too groundbreaking but not much on the core itself:
- Start of moving SoF to support multiple IPC mechanisms.
- Use of NHLT ACPI table to reduce the amount of quirking required for
Intel systems.
- Some building blocks for use in forthcoming Intel AVS driver for
legacy Intel DSP firmwares.
- Support for AMD PDM, Atmel PDMC, Awinic AW8738, i.MX cards with
TLV320AIC31xx, Intel machines with CS35L41 and ESSX8336, Mediatek
MT8181 wideband bluetooth, nVidia Tegra234, Qualcomm SC7280, Renesas
RZ/V2L, Texas Instruments TAS585M
Diffstat (limited to 'sound/soc/sof/amd')
-rw-r--r-- | sound/soc/sof/amd/acp-dsp-offset.h | 1 | ||||
-rw-r--r-- | sound/soc/sof/amd/acp-ipc.c | 22 | ||||
-rw-r--r-- | sound/soc/sof/amd/acp-loader.c | 9 | ||||
-rw-r--r-- | sound/soc/sof/amd/acp-pcm.c | 15 | ||||
-rw-r--r-- | sound/soc/sof/amd/acp-stream.c | 3 | ||||
-rw-r--r-- | sound/soc/sof/amd/acp-trace.c | 38 | ||||
-rw-r--r-- | sound/soc/sof/amd/acp.c | 29 | ||||
-rw-r--r-- | sound/soc/sof/amd/acp.h | 9 | ||||
-rw-r--r-- | sound/soc/sof/amd/renoir.c | 1 |
9 files changed, 64 insertions, 63 deletions
diff --git a/sound/soc/sof/amd/acp-dsp-offset.h b/sound/soc/sof/amd/acp-dsp-offset.h index 63f13c111b24..40fbf11facba 100644 --- a/sound/soc/sof/amd/acp-dsp-offset.h +++ b/sound/soc/sof/amd/acp-dsp-offset.h @@ -61,6 +61,7 @@ #define ACP_DSP_SW_INTR_STAT 0x1818 #define ACP_SW_INTR_TRIG 0x181C #define ACP_ERROR_STATUS 0x18C4 +#define ACP_AXI2DAGB_SEM_0 0x1880 /* Registers from ACP_SHA block */ #define ACP_SHA_DSP_FW_QUALIFIER 0x1C70 diff --git a/sound/soc/sof/amd/acp-ipc.c b/sound/soc/sof/amd/acp-ipc.c index e132223b4c66..e1842f037083 100644 --- a/sound/soc/sof/amd/acp-ipc.c +++ b/sound/soc/sof/amd/acp-ipc.c @@ -62,12 +62,26 @@ int acp_sof_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) { struct acp_dev_data *adata = sdev->pdata->hw_pdata; unsigned int offset = offsetof(struct scratch_ipc_conf, sof_in_box); + unsigned int count = ACP_HW_SEM_RETRY_COUNT; + + while (snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_AXI2DAGB_SEM_0)) { + /* Wait until acquired HW Semaphore Lock or timeout*/ + count--; + if (!count) { + dev_err(sdev->dev, "%s: Failed to acquire HW lock\n", __func__); + return -EINVAL; + } + } acp_mailbox_write(sdev, offset, msg->msg_data, msg->msg_size); acp_ipc_host_msg_set(sdev); /* Trigger host to dsp interrupt for the msg */ acpbus_trigger_host_to_dsp_swintr(adata); + + /* Unlock or Release HW Semaphore */ + snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_AXI2DAGB_SEM_0, 0x0); + return 0; } EXPORT_SYMBOL_NS(acp_sof_ipc_send_msg, SND_SOC_SOF_AMD_COMMON); @@ -170,14 +184,6 @@ int acp_sof_ipc_msg_data(struct snd_sof_dev *sdev, struct snd_pcm_substream *sub } EXPORT_SYMBOL_NS(acp_sof_ipc_msg_data, SND_SOC_SOF_AMD_COMMON); -int acp_sof_ipc_pcm_params(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream, - const struct sof_ipc_pcm_params_reply *reply) -{ - /* TODO: Implement stream hw params to validate stream offset */ - return 0; -} -EXPORT_SYMBOL_NS(acp_sof_ipc_pcm_params, SND_SOC_SOF_AMD_COMMON); - int acp_sof_ipc_get_mailbox_offset(struct snd_sof_dev *sdev) { return ACP_SCRATCH_MEMORY_ADDRESS; diff --git a/sound/soc/sof/amd/acp-loader.c b/sound/soc/sof/amd/acp-loader.c index 2dc15ae38155..7ca51e0f3b1b 100644 --- a/sound/soc/sof/amd/acp-loader.c +++ b/sound/soc/sof/amd/acp-loader.c @@ -127,6 +127,12 @@ static void configure_pte_for_fw_loading(int type, int num_pages, struct acp_dev return; } + /* Group Enable */ + snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACPAXI2AXI_ATU_BASE_ADDR_GRP_1, + ACP_SRAM_PTE_OFFSET | BIT(31)); + snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1, + PAGE_SIZE_4K_ENABLE); + for (page_idx = 0; page_idx < num_pages; page_idx++) { low = lower_32_bits(addr); high = upper_32_bits(addr); @@ -136,6 +142,9 @@ static void configure_pte_for_fw_loading(int type, int num_pages, struct acp_dev offset += 8; addr += PAGE_SIZE; } + + /* Flush ATU Cache after PTE Update */ + snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACPAXI2AXI_ATU_CTRL, ACP_ATU_CACHE_INVALID); } /* pre fw run operations */ diff --git a/sound/soc/sof/amd/acp-pcm.c b/sound/soc/sof/amd/acp-pcm.c index 5b23830cb1f3..0ba8ae46bd76 100644 --- a/sound/soc/sof/amd/acp-pcm.c +++ b/sound/soc/sof/amd/acp-pcm.c @@ -17,15 +17,17 @@ #include "acp-dsp-offset.h" int acp_pcm_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, struct sof_ipc_stream_params *ipc_params) + struct snd_pcm_hw_params *params, + struct snd_sof_platform_stream_params *platform_params) { - struct acp_dsp_stream *stream = substream->runtime->private_data; + struct snd_pcm_runtime *runtime = substream->runtime; + struct acp_dsp_stream *stream = runtime->private_data; unsigned int buf_offset, index; u32 size; int ret; - size = ipc_params->buffer.size; - stream->num_pages = ipc_params->buffer.pages; + size = runtime->dma_bytes; + stream->num_pages = PFN_UP(runtime->dma_bytes); stream->dmab = substream->runtime->dma_buffer_p; ret = acp_dsp_stream_config(sdev, stream); @@ -34,8 +36,9 @@ int acp_pcm_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_substream *substr return ret; } - ipc_params->buffer.phy_addr = stream->reg_offset; - ipc_params->stream_tag = stream->stream_tag; + platform_params->use_phy_address = true; + platform_params->phy_addr = stream->reg_offset; + platform_params->stream_tag = stream->stream_tag; /* write buffer size of stream in scratch memory */ diff --git a/sound/soc/sof/amd/acp-stream.c b/sound/soc/sof/amd/acp-stream.c index f2837bfbdb20..b3ca4a90dbf8 100644 --- a/sound/soc/sof/amd/acp-stream.c +++ b/sound/soc/sof/amd/acp-stream.c @@ -115,6 +115,9 @@ int acp_dsp_stream_config(struct snd_sof_dev *sdev, struct acp_dsp_stream *strea offset += 8; } + /* Flush ATU Cache after PTE Update */ + snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACPAXI2AXI_ATU_CTRL, ACP_ATU_CACHE_INVALID); + return 0; } diff --git a/sound/soc/sof/amd/acp-trace.c b/sound/soc/sof/amd/acp-trace.c index fa4da8947186..903b6cc3dda3 100644 --- a/sound/soc/sof/amd/acp-trace.c +++ b/sound/soc/sof/amd/acp-trace.c @@ -34,51 +34,31 @@ int acp_sof_trace_release(struct snd_sof_dev *sdev) } EXPORT_SYMBOL_NS(acp_sof_trace_release, SND_SOC_SOF_AMD_COMMON); -static int acp_sof_trace_prepare(struct snd_sof_dev *sdev, - struct sof_ipc_dma_trace_params_ext *params) +int acp_sof_trace_init(struct snd_sof_dev *sdev, + struct sof_ipc_dma_trace_params_ext *dtrace_params) { struct acp_dsp_stream *stream; struct acp_dev_data *adata; int ret; adata = sdev->pdata->hw_pdata; - stream = adata->dtrace_stream; + stream = acp_dsp_stream_get(sdev, ACP_LOGGER_STREAM); + if (!stream) + return -ENODEV; + stream->dmab = &sdev->dmatb; stream->num_pages = NUM_PAGES; ret = acp_dsp_stream_config(sdev, stream); if (ret < 0) { - dev_err(sdev->dev, "Failed to configure trace stream\n"); + acp_dsp_stream_put(sdev, stream); return ret; } - params->buffer.phy_addr = stream->reg_offset; - params->stream_tag = stream->stream_tag; - - return 0; -} - -int acp_sof_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag) -{ - struct sof_ipc_dma_trace_params_ext *params; - struct acp_dsp_stream *stream; - struct acp_dev_data *adata; - int ret; - - adata = sdev->pdata->hw_pdata; - stream = acp_dsp_stream_get(sdev, ACP_LOGGER_STREAM); - if (!stream) - return -ENODEV; - adata->dtrace_stream = stream; - params = container_of(stream_tag, struct sof_ipc_dma_trace_params_ext, stream_tag); - ret = acp_sof_trace_prepare(sdev, params); - if (ret < 0) { - acp_dsp_stream_put(sdev, stream); - return ret; - } + dtrace_params->stream_tag = stream->stream_tag; + dtrace_params->buffer.phy_addr = stream->reg_offset; - *stream_tag = stream->stream_tag; return 0; } EXPORT_SYMBOL_NS(acp_sof_trace_init, SND_SOC_SOF_AMD_COMMON); diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c index fe9b7dc5bc86..71d71c152342 100644 --- a/sound/soc/sof/amd/acp.c +++ b/sound/soc/sof/amd/acp.c @@ -36,19 +36,6 @@ static int smn_read(struct pci_dev *dev, u32 smn_addr, u32 *data) return 0; } -static void configure_acp_groupregisters(struct acp_dev_data *adata) -{ - struct snd_sof_dev *sdev = adata->dev; - - /* Group Enable */ - snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACPAXI2AXI_ATU_BASE_ADDR_GRP_1, - ACP_SRAM_PTE_OFFSET | BIT(31)); - snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1, - PAGE_SIZE_4K_ENABLE); - - snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACPAXI2AXI_ATU_CTRL, ACP_ATU_CACHE_INVALID); -} - static void init_dma_descriptor(struct acp_dev_data *adata) { struct snd_sof_dev *sdev = adata->dev; @@ -264,7 +251,6 @@ static int acp_memory_init(struct snd_sof_dev *sdev) snd_sof_dsp_update_bits(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_CNTL, ACP_DSP_INTR_EN_MASK, ACP_DSP_INTR_EN_MASK); - configure_acp_groupregisters(adata); init_dma_descriptor(adata); return 0; @@ -273,7 +259,7 @@ static int acp_memory_init(struct snd_sof_dev *sdev) static irqreturn_t acp_irq_thread(int irq, void *context) { struct snd_sof_dev *sdev = context; - unsigned int val; + unsigned int val, count = ACP_HW_SEM_RETRY_COUNT; val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_EXTERNAL_INTR_STAT); if (val & ACP_SHA_STAT) { @@ -284,9 +270,22 @@ static irqreturn_t acp_irq_thread(int irq, void *context) val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT); if (val & ACP_DSP_TO_HOST_IRQ) { + while (snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_AXI2DAGB_SEM_0)) { + /* Wait until acquired HW Semaphore lock or timeout */ + count--; + if (!count) { + dev_err(sdev->dev, "%s: Failed to acquire HW lock\n", __func__); + return IRQ_NONE; + } + } + sof_ops(sdev)->irq_thread(irq, sdev); val |= ACP_DSP_TO_HOST_IRQ; snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT, val); + + /* Unlock or Release HW Semaphore */ + snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_AXI2DAGB_SEM_0, 0x0); + return IRQ_HANDLED; } diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h index a2f8e4219066..35e46fe6676a 100644 --- a/sound/soc/sof/amd/acp.h +++ b/sound/soc/sof/amd/acp.h @@ -17,6 +17,7 @@ #define ACP_DSP_BAR 0 +#define ACP_HW_SEM_RETRY_COUNT 10000 #define ACP_REG_POLL_INTERVAL 500 #define ACP_REG_POLL_TIMEOUT_US 2000 #define ACP_DMA_COMPLETE_TIMEOUT_US 5000 @@ -185,8 +186,6 @@ int acp_sof_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg); int acp_sof_ipc_get_mailbox_offset(struct snd_sof_dev *sdev); int acp_sof_ipc_get_window_offset(struct snd_sof_dev *sdev, u32 id); -int acp_sof_ipc_pcm_params(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream, - const struct sof_ipc_pcm_params_reply *reply); void acp_mailbox_write(struct snd_sof_dev *sdev, u32 offset, void *message, size_t bytes); void acp_mailbox_read(struct snd_sof_dev *sdev, u32 offset, void *message, size_t bytes); @@ -202,7 +201,8 @@ int acp_dsp_stream_put(struct snd_sof_dev *sdev, struct acp_dsp_stream *acp_stre int acp_pcm_open(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream); int acp_pcm_close(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream); int acp_pcm_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, struct sof_ipc_stream_params *ipc_params); + struct snd_pcm_hw_params *params, + struct snd_sof_platform_stream_params *platform_params); extern const struct snd_sof_dsp_ops sof_renoir_ops; @@ -210,7 +210,8 @@ extern const struct snd_sof_dsp_ops sof_renoir_ops; int snd_amd_acp_find_config(struct pci_dev *pci); /* Trace */ -int acp_sof_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag); +int acp_sof_trace_init(struct snd_sof_dev *sdev, + struct sof_ipc_dma_trace_params_ext *dtrace_params); int acp_sof_trace_release(struct snd_sof_dev *sdev); struct sof_amd_acp_desc { diff --git a/sound/soc/sof/amd/renoir.c b/sound/soc/sof/amd/renoir.c index c3ecb9e9d5ba..409fd57448b8 100644 --- a/sound/soc/sof/amd/renoir.c +++ b/sound/soc/sof/amd/renoir.c @@ -150,7 +150,6 @@ const struct snd_sof_dsp_ops sof_renoir_ops = { /*IPC */ .send_msg = acp_sof_ipc_send_msg, .ipc_msg_data = acp_sof_ipc_msg_data, - .ipc_pcm_params = acp_sof_ipc_pcm_params, .get_mailbox_offset = acp_sof_ipc_get_mailbox_offset, .irq_thread = acp_sof_ipc_irq_thread, .fw_ready = sof_fw_ready, |