[PATCH 1/4] ASoC: SOF: amd: Fix for reading position updates from stream box.
By default the position updates are read from dsp box when streambox size is not defined.if the streambox size is defined to some value then position updates can be read from the streambox.
Signed-off-by: V sujith kumar Reddy Vsujithkumar.Reddy@amd.com --- sound/soc/sof/amd/acp-common.c | 1 + sound/soc/sof/amd/acp-ipc.c | 30 +++++++++++++++++++++++++++++- sound/soc/sof/amd/acp.h | 4 ++++ 3 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/sound/soc/sof/amd/acp-common.c b/sound/soc/sof/amd/acp-common.c index 27b95187356e..150e042e4039 100644 --- a/sound/soc/sof/amd/acp-common.c +++ b/sound/soc/sof/amd/acp-common.c @@ -76,6 +76,7 @@ struct snd_sof_dsp_ops sof_acp_common_ops = { /*IPC */ .send_msg = acp_sof_ipc_send_msg, .ipc_msg_data = acp_sof_ipc_msg_data, + .set_stream_data_offset = acp_set_stream_data_offset, .get_mailbox_offset = acp_sof_ipc_get_mailbox_offset, .get_window_offset = acp_sof_ipc_get_window_offset, .irq_thread = acp_sof_ipc_irq_thread, diff --git a/sound/soc/sof/amd/acp-ipc.c b/sound/soc/sof/amd/acp-ipc.c index dd030566e372..dd6e53c63407 100644 --- a/sound/soc/sof/amd/acp-ipc.c +++ b/sound/soc/sof/amd/acp-ipc.c @@ -192,13 +192,41 @@ int acp_sof_ipc_msg_data(struct snd_sof_dev *sdev, struct snd_pcm_substream *sub { unsigned int offset = sdev->dsp_box.offset;
- if (!substream || !sdev->stream_box.size) + if (!substream || !sdev->stream_box.size) { acp_mailbox_read(sdev, offset, p, sz); + } else { + struct acp_dsp_stream *stream = substream->runtime->private_data; + + if (!stream) + return -ESTRPIPE; + + acp_mailbox_read(sdev, stream->posn_offset, p, sz); + }
return 0; } EXPORT_SYMBOL_NS(acp_sof_ipc_msg_data, SND_SOC_SOF_AMD_COMMON);
+int acp_set_stream_data_offset(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + size_t posn_offset) +{ + struct acp_dsp_stream *stream = substream->runtime->private_data; + + /* check for unaligned offset or overflow */ + if (posn_offset > sdev->stream_box.size || + posn_offset % sizeof(struct sof_ipc_stream_posn) != 0) + return -EINVAL; + + stream->posn_offset = sdev->stream_box.offset + posn_offset; + + dev_dbg(sdev->dev, "pcm: stream dir %d, posn mailbox offset is %zu", + substream->stream, stream->posn_offset); + + return 0; +} +EXPORT_SYMBOL_NS(acp_set_stream_data_offset, SND_SOC_SOF_AMD_COMMON); + int acp_sof_ipc_get_mailbox_offset(struct snd_sof_dev *sdev) { const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata); diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h index dd3c072d0172..1529c6d9bf9b 100644 --- a/sound/soc/sof/amd/acp.h +++ b/sound/soc/sof/amd/acp.h @@ -138,6 +138,7 @@ struct acp_dsp_stream { int stream_tag; int active; unsigned int reg_offset; + size_t posn_offset; };
struct sof_amd_acp_desc { @@ -199,6 +200,9 @@ int acp_dsp_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_ty irqreturn_t acp_sof_ipc_irq_thread(int irq, void *context); int acp_sof_ipc_msg_data(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream, void *p, size_t sz); +int acp_set_stream_data_offset(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + size_t posn_offset); 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);
By default clock source is selected as internal clock of 96Mhz which is not configurable. Now we select the clock source to external clock (ACLK) which can be configurable to different clock ranges depending on usecase.
Signed-off-by: V sujith kumar Reddy Vsujithkumar.Reddy@amd.com --- sound/soc/sof/amd/acp.c | 4 +++- sound/soc/sof/amd/acp.h | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c index 36966643e36a..47115a77c92c 100644 --- a/sound/soc/sof/amd/acp.c +++ b/sound/soc/sof/amd/acp.c @@ -390,6 +390,7 @@ static int acp_power_on(struct snd_sof_dev *sdev)
static int acp_reset(struct snd_sof_dev *sdev) { + const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata); unsigned int val; int ret;
@@ -410,6 +411,7 @@ static int acp_reset(struct snd_sof_dev *sdev) if (ret < 0) dev_err(sdev->dev, "timeout in releasing reset\n");
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->acp_clkmux_sel, ACP_CLOCK_ACLK); return ret; }
@@ -456,7 +458,7 @@ int amd_sof_acp_resume(struct snd_sof_dev *sdev) return ret; }
- snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->acp_clkmux_sel, 0x03); + snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->acp_clkmux_sel, ACP_CLOCK_ACLK);
ret = acp_memory_init(sdev);
diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h index 1529c6d9bf9b..76ad963faec1 100644 --- a/sound/soc/sof/amd/acp.h +++ b/sound/soc/sof/amd/acp.h @@ -69,6 +69,14 @@ #define BOX_SIZE_512 0x200 #define BOX_SIZE_1024 0x400
+enum clock_source { + ACP_CLOCK_96M = 0, + ACP_CLOCK_48M, + ACP_CLOCK_24M, + ACP_CLOCK_ACLK, + ACP_CLOCK_MCLK, +}; + struct acp_atu_grp_pte { u32 low; u32 high;
ADD HS and SP virtual DAI driver to support AMD platforms.
Signed-off-by: V sujith kumar Reddy Vsujithkumar.Reddy@amd.com --- sound/soc/sof/amd/rembrandt.c | 16 ++++++++++++++++ sound/soc/sof/amd/renoir.c | 16 ++++++++++++++++ 2 files changed, 32 insertions(+)
diff --git a/sound/soc/sof/amd/rembrandt.c b/sound/soc/sof/amd/rembrandt.c index dcb64a23e121..5288ab882fc9 100644 --- a/sound/soc/sof/amd/rembrandt.c +++ b/sound/soc/sof/amd/rembrandt.c @@ -23,6 +23,7 @@ #define I2S_BT_INSTANCE 1 #define I2S_SP_INSTANCE 2 #define PDM_DMIC_INSTANCE 3 +#define I2S_HS_VIRTUAL_INSTANCE 4
static struct snd_soc_dai_driver rembrandt_sof_dai[] = { [I2S_HS_INSTANCE] = { @@ -112,6 +113,21 @@ static struct snd_soc_dai_driver rembrandt_sof_dai[] = { .rate_max = 48000, }, }, + + [I2S_HS_VIRTUAL_INSTANCE] = { + .id = I2S_HS_VIRTUAL_INSTANCE, + .name = "acp-sof-hs-virtual", + .playback = { + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 2, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 96000, + }, + .probe = &acp_dai_probe, + }, };
/* Rembrandt ops */ diff --git a/sound/soc/sof/amd/renoir.c b/sound/soc/sof/amd/renoir.c index 6ea8727f977e..adade2e3d3be 100644 --- a/sound/soc/sof/amd/renoir.c +++ b/sound/soc/sof/amd/renoir.c @@ -22,6 +22,7 @@ #define I2S_BT_INSTANCE 0 #define I2S_SP_INSTANCE 1 #define PDM_DMIC_INSTANCE 2 +#define I2S_SP_VIRTUAL_INSTANCE 3
static struct snd_soc_dai_driver renoir_sof_dai[] = { [I2S_BT_INSTANCE] = { @@ -86,6 +87,21 @@ static struct snd_soc_dai_driver renoir_sof_dai[] = { .rate_max = 48000, }, }, + + [I2S_SP_VIRTUAL_INSTANCE] = { + .id = I2S_SP_VIRTUAL_INSTANCE, + .name = "acp-sof-sp-virtual", + .playback = { + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 2, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 96000, + }, + .probe = &acp_dai_probe, + }, };
/* Renoir ops */
Add support for configuring sp and hs DAI from topology.
Signed-off-by: V sujith kumar Reddy Vsujithkumar.Reddy@amd.com --- sound/soc/sof/ipc3-pcm.c | 2 ++ sound/soc/sof/ipc3-topology.c | 36 +++++++++++++++++++++++++++-------- sound/soc/sof/sof-audio.h | 1 + sound/soc/sof/topology.c | 10 ++++++++++ 4 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/sound/soc/sof/ipc3-pcm.c b/sound/soc/sof/ipc3-pcm.c index dad57bef38f6..f10bfc9bd5cb 100644 --- a/sound/soc/sof/ipc3-pcm.c +++ b/sound/soc/sof/ipc3-pcm.c @@ -336,6 +336,7 @@ static int sof_ipc3_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, channels->min, channels->max); break; case SOF_DAI_AMD_SP: + case SOF_DAI_AMD_SP_VIRTUAL: rate->min = private->dai_config->acpsp.fsync_rate; rate->max = private->dai_config->acpsp.fsync_rate; channels->min = private->dai_config->acpsp.tdm_slots; @@ -347,6 +348,7 @@ static int sof_ipc3_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, channels->min, channels->max); break; case SOF_DAI_AMD_HS: + case SOF_DAI_AMD_HS_VIRTUAL: rate->min = private->dai_config->acphs.fsync_rate; rate->max = private->dai_config->acphs.fsync_rate; channels->min = private->dai_config->acphs.tdm_slots; diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index 0720e1eae084..b94cc40485ed 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -276,6 +276,16 @@ static const struct sof_topology_token acpdmic_tokens[] = { offsetof(struct sof_ipc_dai_acpdmic_params, pdm_ch)}, };
+/* ACPI2S */ +static const struct sof_topology_token acpi2s_tokens[] = { + {SOF_TKN_AMD_ACPI2S_RATE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc_dai_acp_params, fsync_rate)}, + {SOF_TKN_AMD_ACPI2S_CH, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc_dai_acp_params, tdm_slots)}, + {SOF_TKN_AMD_ACPI2S_TDM_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc_dai_acp_params, tdm_mode)}, +}; + /* Core tokens */ static const struct sof_topology_token core_tokens[] = { {SOF_TKN_COMP_CORE_ID, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, @@ -311,6 +321,7 @@ static const struct sof_token_info ipc3_token_list[SOF_TOKEN_COUNT] = { [SOF_SAI_TOKENS] = {"SAI tokens", sai_tokens, ARRAY_SIZE(sai_tokens)}, [SOF_AFE_TOKENS] = {"AFE tokens", afe_tokens, ARRAY_SIZE(afe_tokens)}, [SOF_ACPDMIC_TOKENS] = {"ACPDMIC tokens", acpdmic_tokens, ARRAY_SIZE(acpdmic_tokens)}, + [SOF_ACPI2S_TOKENS] = {"ACPI2S tokens", acpi2s_tokens, ARRAY_SIZE(acpi2s_tokens)}, };
/** @@ -1193,6 +1204,7 @@ static int sof_link_acp_sp_load(struct snd_soc_component *scomp, struct snd_sof_ struct snd_soc_tplg_hw_config *hw_config = slink->hw_configs; struct sof_dai_private_data *private = dai->private; u32 size = sizeof(*config); + int ret;
/* handle master/slave and inverted clocks */ sof_dai_set_format(hw_config, config); @@ -1201,12 +1213,15 @@ static int sof_link_acp_sp_load(struct snd_soc_component *scomp, struct snd_sof_ memset(&config->acpsp, 0, sizeof(config->acpsp)); config->hdr.size = size;
- config->acpsp.fsync_rate = le32_to_cpu(hw_config->fsync_rate); - config->acpsp.tdm_slots = le32_to_cpu(hw_config->tdm_slots); + ret = sof_update_ipc_object(scomp, &config->acpsp, SOF_ACPI2S_TOKENS, slink->tuples, + slink->num_tuples, size, slink->num_hw_configs); + if (ret < 0) + return ret;
- dev_info(scomp->dev, "ACP_SP config ACP%d channel %d rate %d\n", + + dev_info(scomp->dev, "ACP_SP config ACP%d channel %d rate %d tdm_mode %d\n", config->dai_index, config->acpsp.tdm_slots, - config->acpsp.fsync_rate); + config->acpsp.fsync_rate, config->acpsp.tdm_mode);
dai->number_configs = 1; dai->current_config = 0; @@ -1223,6 +1238,7 @@ static int sof_link_acp_hs_load(struct snd_soc_component *scomp, struct snd_sof_ struct snd_soc_tplg_hw_config *hw_config = slink->hw_configs; struct sof_dai_private_data *private = dai->private; u32 size = sizeof(*config); + int ret;
/* Configures the DAI hardware format and inverted clocks */ sof_dai_set_format(hw_config, config); @@ -1231,12 +1247,14 @@ static int sof_link_acp_hs_load(struct snd_soc_component *scomp, struct snd_sof_ memset(&config->acphs, 0, sizeof(config->acphs)); config->hdr.size = size;
- config->acphs.fsync_rate = le32_to_cpu(hw_config->fsync_rate); - config->acphs.tdm_slots = le32_to_cpu(hw_config->tdm_slots); + ret = sof_update_ipc_object(scomp, &config->acphs, SOF_ACPI2S_TOKENS, slink->tuples, + slink->num_tuples, size, slink->num_hw_configs); + if (ret < 0) + return ret;
- dev_info(scomp->dev, "ACP_HS config ACP%d channel %d rate %d\n", + dev_info(scomp->dev, "ACP_HS config ACP%d channel %d rate %d tdm_mode %d\n", config->dai_index, config->acphs.tdm_slots, - config->acphs.fsync_rate); + config->acphs.fsync_rate, config->acphs.tdm_mode);
dai->number_configs = 1; dai->current_config = 0; @@ -1545,9 +1563,11 @@ static int sof_ipc3_widget_setup_comp_dai(struct snd_sof_widget *swidget) ret = sof_link_acp_bt_load(scomp, slink, config, dai); break; case SOF_DAI_AMD_SP: + case SOF_DAI_AMD_SP_VIRTUAL: ret = sof_link_acp_sp_load(scomp, slink, config, dai); break; case SOF_DAI_AMD_HS: + case SOF_DAI_AMD_HS_VIRTUAL: ret = sof_link_acp_hs_load(scomp, slink, config, dai); break; case SOF_DAI_AMD_DMIC: diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index 1b5b3ea53a6e..29cf951e3526 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -248,6 +248,7 @@ enum sof_tokens { SOF_COPIER_FORMAT_TOKENS, SOF_GAIN_TOKENS, SOF_ACPDMIC_TOKENS, + SOF_ACPI2S_TOKENS,
/* this should be the last */ SOF_TOKEN_COUNT, diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 9d9fcaa2a948..c668bd9d21ec 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -289,6 +289,9 @@ static const struct sof_dai_types sof_dais[] = { {"ACPDMIC", SOF_DAI_AMD_DMIC}, {"ACPHS", SOF_DAI_AMD_HS}, {"AFE", SOF_DAI_MEDIATEK_AFE}, + {"ACPSP_VIRTUAL", SOF_DAI_AMD_SP_VIRTUAL}, + {"ACPHS_VIRTUAL", SOF_DAI_AMD_HS_VIRTUAL}, + };
static enum sof_ipc_dai_type find_dai(const char *name) @@ -1895,6 +1898,13 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_ token_id = SOF_ACPDMIC_TOKENS; num_tuples += token_list[SOF_ACPDMIC_TOKENS].count; break; + case SOF_DAI_AMD_SP: + case SOF_DAI_AMD_HS: + case SOF_DAI_AMD_SP_VIRTUAL: + case SOF_DAI_AMD_HS_VIRTUAL: + token_id = SOF_ACPI2S_TOKENS; + num_tuples += token_list[SOF_ACPI2S_TOKENS].count; + break; default: break; }
participants (1)
-
V sujith kumar Reddy