Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions include/sound/sof/ipc4/header.h
Original file line number Diff line number Diff line change
Expand Up @@ -433,12 +433,10 @@ enum sof_ipc4_fw_config_params {
SOF_IPC4_FW_CFG_RESERVED,
SOF_IPC4_FW_CFG_POWER_GATING_POLICY,
SOF_IPC4_FW_CFG_ASSERT_MODE,
SOF_IPC4_FW_RESERVED1,
SOF_IPC4_FW_RESERVED2,
SOF_IPC4_FW_RESERVED3,
SOF_IPC4_FW_RESERVED4,
SOF_IPC4_FW_RESERVED5,
SOF_IPC4_FW_CONTEXT_SAVE
/* Reserved: 24 - 28 */
SOF_IPC4_FW_CONTEXT_SAVE = 29,
/* Reserved: 30 - 34 */
SOF_IPC4_FW_CFG_SOF_CODEC_INFO = 35,
};

struct sof_ipc4_fw_version {
Expand Down Expand Up @@ -681,7 +679,8 @@ struct sof_ipc4_module_init_ext_object {
enum sof_ipc4_mod_init_ext_obj_id {
SOF_IPC4_MOD_INIT_DATA_ID_INVALID = 0,
SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA,
SOF_IPC4_MOD_INIT_DATA_ID_MAX = SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA,
SOF_IPC4_MOD_INIT_DATA_ID_MODULE_DATA,
SOF_IPC4_MOD_INIT_DATA_ID_MAX = SOF_IPC4_MOD_INIT_DATA_ID_MODULE_DATA,
};

/* DP module memory configuration data object for ext_init object array */
Expand Down
13 changes: 12 additions & 1 deletion sound/soc/soc-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1671,6 +1671,8 @@ void dpcm_be_dai_stop(struct snd_soc_pcm_runtime *fe, int stream,
}

__soc_pcm_close(be, be_substream);
if (fe->fe_compr)
kfree(be_substream->runtime);
be_substream->runtime = NULL;
be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
}
Expand Down Expand Up @@ -1718,7 +1720,16 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream)
dev_dbg(be->dev, "ASoC: open %s BE %s\n",
snd_pcm_direction_name(stream), be->dai_link->name);

be_substream->runtime = fe_substream->runtime;
if (!fe->fe_compr) {
be_substream->runtime = fe_substream->runtime;
} else {
be_substream->runtime = kzalloc(sizeof(*be_substream->runtime), GFP_KERNEL);
if (!be_substream->runtime) {
err = -ENOMEM;
goto unwind;
}
}

err = __soc_pcm_open(be, be_substream);
if (err < 0) {
be->dpcm[stream].users--;
Expand Down
4 changes: 2 additions & 2 deletions sound/soc/sof/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ snd-sof-y := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\
ifneq ($(CONFIG_SND_SOC_SOF_IPC3),)
snd-sof-y += ipc3.o ipc3-loader.o ipc3-topology.o ipc3-control.o ipc3-pcm.o\
ipc3-dtrace.o
snd-sof-$(CONFIG_SND_SOC_SOF_COMPRESS) += ipc3-compress.o
endif
ifneq ($(CONFIG_SND_SOC_SOF_IPC4),)
snd-sof-y += ipc4.o ipc4-loader.o ipc4-topology.o ipc4-control.o ipc4-pcm.o\
ipc4-mtrace.o ipc4-telemetry.o
snd-sof-$(CONFIG_SND_SOC_SOF_COMPRESS) += ipc4-compress.o
endif

# SOF client support
ifneq ($(CONFIG_SND_SOC_SOF_CLIENT),)
snd-sof-y += sof-client.o
endif

snd-sof-$(CONFIG_SND_SOC_SOF_COMPRESS) += compress.o

snd-sof-pci-y := sof-pci-dev.o
snd-sof-acpi-y := sof-acpi-dev.o
snd-sof-of-y := sof-of-dev.o
Expand Down
10 changes: 7 additions & 3 deletions sound/soc/sof/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,11 +469,12 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)

sof_set_fw_state(sdev, SOF_FW_BOOT_PREPARE);

/* set up platform component driver */
snd_sof_new_platform_drv(sdev);

if (sdev->dspless_mode_selected) {
sof_set_fw_state(sdev, SOF_DSPLESS_MODE);

/* set up platform component driver */
snd_sof_new_platform_drv(sdev);

goto skip_dsp_init;
}

Expand All @@ -498,6 +499,9 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
goto ipc_err;
}

/* set up platform component driver after initializing the IPC ops */
snd_sof_new_platform_drv(sdev);

/*
* skip loading/booting firmware and registering the machine driver when DSP OPS testing
* is enabled with IPC4. Normal audio operations will be unavailable in this mode.
Expand Down
9 changes: 2 additions & 7 deletions sound/soc/sof/intel/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,6 @@ config SND_SOC_SOF_INTEL_ICL
tristate
select SND_SOC_SOF_HDA_GENERIC
select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
select SND_SOC_SOF_IPC3
select SND_SOC_SOF_IPC4
select SND_SOC_SOF_INTEL_CNL

config SND_SOC_SOF_ICELAKE
Expand All @@ -214,9 +212,8 @@ config SND_SOC_SOF_INTEL_TGL
tristate
select SND_SOC_SOF_HDA_GENERIC
select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
select SND_SOC_SOF_IPC3
select SND_SOC_SOF_IPC4
select SND_SOC_SOF_INTEL_CNL
select SND_SOC_SOF_COMPRESS

config SND_SOC_SOF_TIGERLAKE
tristate "SOF support for Tigerlake"
Expand Down Expand Up @@ -253,6 +250,7 @@ config SND_SOC_SOF_INTEL_MTL
select SND_SOC_SOF_HDA_GENERIC
select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
select SND_SOC_SOF_IPC4
select SND_SOC_SOF_COMPRESS

config SND_SOC_SOF_METEORLAKE
tristate "SOF support for Meteorlake"
Expand All @@ -270,7 +268,6 @@ config SND_SOC_SOF_INTEL_LNL
select SND_SOC_SOF_HDA_GENERIC
select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
select SND_SOF_SOF_HDA_SDW_BPT if SND_SOC_SOF_INTEL_SOUNDWIRE != n
select SND_SOC_SOF_IPC4
select SND_SOC_SOF_INTEL_MTL

config SND_SOC_SOF_LUNARLAKE
Expand All @@ -287,7 +284,6 @@ config SND_SOC_SOF_INTEL_PTL
tristate
select SND_SOC_SOF_HDA_COMMON
select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
select SND_SOC_SOF_IPC4
select SND_SOC_SOF_INTEL_LNL

config SND_SOC_SOF_PANTHERLAKE
Expand All @@ -304,7 +300,6 @@ config SND_SOC_SOF_INTEL_NVL
tristate
select SND_SOC_SOF_HDA_COMMON
select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
select SND_SOC_SOF_IPC4
select SND_SOC_SOF_INTEL_PTL

config SND_SOC_SOF_NOVALAKE
Expand Down
7 changes: 7 additions & 0 deletions sound/soc/sof/intel/hda-common-ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ const struct snd_sof_dsp_ops sof_hda_common_ops = {
.pcm_pointer = hda_dsp_pcm_pointer,
.pcm_ack = hda_dsp_pcm_ack,

.compr_open = hda_dsp_compr_open,
.compr_hw_params = hda_dsp_compr_hw_params,
.compr_close = hda_dsp_compr_close,
.compr_trigger = hda_dsp_compr_trigger,
.compr_pointer = hda_dsp_compr_pointer,
.compr_get_dai_frame_counter = hda_dsp_compr_get_stream_llp,

.get_dai_frame_counter = hda_dsp_get_stream_llp,
.get_host_byte_counter = hda_dsp_get_stream_ldp,

Expand Down
119 changes: 119 additions & 0 deletions sound/soc/sof/intel/hda-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,51 @@ int hda_dsp_pcm_hw_params(struct snd_sof_dev *sdev,
}
EXPORT_SYMBOL_NS(hda_dsp_pcm_hw_params, "SND_SOC_SOF_INTEL_HDA_COMMON");

int hda_dsp_compr_hw_params(struct snd_sof_dev *sdev,
struct snd_compr_stream *cstream,
struct snd_compr_params *params,
struct snd_sof_platform_stream_params *platform_params)
{
struct hdac_stream *hstream = cstream->runtime->private_data;
struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
struct snd_dma_buffer *dmab;
u32 bits, rate;
int bps;
int ret;

hstream->cstream = cstream;
dmab = cstream->runtime->dma_buffer_p;

/* compr params do not store bit depth, default to S32_LE */
bps = snd_pcm_format_physical_width(params->codec.format);
if (bps < 0)
return bps;
bits = hda_dsp_get_bits(sdev, bps);
rate = hda_dsp_get_mult_div(sdev, params->codec.sample_rate);

hstream->format_val = rate | bits | (params->codec.ch_out - 1);
hstream->bufsize = cstream->runtime->buffer_size;
hstream->period_bytes = cstream->runtime->fragment_size;
hstream->no_period_wakeup = false;

/* params is not used so pass NULL */
dmab = cstream->runtime->dma_buffer_p;
ret = hda_dsp_stream_hw_params(sdev, hext_stream, dmab, NULL);
if (ret < 0) {
dev_err(sdev->dev, "%s: hdac prepare failed: %d\n", __func__, ret);
return ret;
}

if (hda)
platform_params->no_ipc_position = hda->no_ipc_position;

platform_params->stream_tag = hstream->stream_tag;

return 0;
}
EXPORT_SYMBOL_NS(hda_dsp_compr_hw_params, "SND_SOC_SOF_INTEL_HDA_COMMON");

/* update SPIB register with appl position */
int hda_dsp_pcm_ack(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream)
{
Expand Down Expand Up @@ -184,6 +229,16 @@ int hda_dsp_pcm_trigger(struct snd_sof_dev *sdev,
}
EXPORT_SYMBOL_NS(hda_dsp_pcm_trigger, "SND_SOC_SOF_INTEL_HDA_COMMON");

int hda_dsp_compr_trigger(struct snd_sof_dev *sdev,
struct snd_compr_stream *cstream, int cmd)
{
struct hdac_stream *hstream = cstream->runtime->private_data;
struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);

return hda_dsp_stream_trigger(sdev, hext_stream, cmd);
}
EXPORT_SYMBOL_NS(hda_dsp_compr_trigger, "SND_SOC_SOF_INTEL_HDA_COMMON");

snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream)
{
Expand Down Expand Up @@ -216,6 +271,18 @@ snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
}
EXPORT_SYMBOL_NS(hda_dsp_pcm_pointer, "SND_SOC_SOF_INTEL_HDA_COMMON");

int hda_dsp_compr_pointer(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream,
struct snd_compr_tstamp64 *tstamp)
{
struct hdac_stream *hstream = cstream->runtime->private_data;

/* hstream->curr_pos is updated when we receive the ioc */
tstamp->copied_total += hstream->curr_pos;

return 0;
}
EXPORT_SYMBOL_NS(hda_dsp_compr_pointer, "SND_SOC_SOF_INTEL_HDA_COMMON");

int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream)
{
Expand Down Expand Up @@ -332,6 +399,41 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
}
EXPORT_SYMBOL_NS(hda_dsp_pcm_open, "SND_SOC_SOF_INTEL_HDA_COMMON");

int hda_dsp_compr_open(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_component *scomp = sdev->component;
struct hdac_ext_stream *dsp_stream;
struct snd_sof_pcm *spcm;
int direction = cstream->direction;

spcm = snd_sof_find_spcm_dai(scomp, rtd);
if (!spcm) {
dev_err(sdev->dev, "%s: can't find PCM with DAI ID %d\n",
__func__, rtd->dai_link->id);
return -EINVAL;
}

dsp_stream = hda_dsp_stream_get(sdev, direction, 0);
if (!dsp_stream) {
dev_err(sdev->dev, "%s: no stream available\n", __func__);
return -ENODEV;
}

/* binding compr stream to hda stream */
cstream->runtime->private_data = &dsp_stream->hstream;

/*
* Reset the llp cache values (they are used for LLP compensation in
* case the counter is not reset)
*/
dsp_stream->pplcllpl = 0;
dsp_stream->pplcllpu = 0;

return 0;
}
EXPORT_SYMBOL_NS(hda_dsp_compr_open, "SND_SOC_SOF_INTEL_HDA_COMMON");

int hda_dsp_pcm_close(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream)
{
Expand All @@ -351,3 +453,20 @@ int hda_dsp_pcm_close(struct snd_sof_dev *sdev,
return 0;
}
EXPORT_SYMBOL_NS(hda_dsp_pcm_close, "SND_SOC_SOF_INTEL_HDA_COMMON");

int hda_dsp_compr_close(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream)
{
struct hdac_stream *hstream = cstream->runtime->private_data;
int direction = cstream->direction;
int ret;

ret = hda_dsp_stream_put(sdev, direction, hstream->stream_tag);
if (ret)
return -ENODEV;

/* unbinding compress stream to hda stream */
hstream->cstream = NULL;
cstream->runtime->private_data = NULL;
return 0;
}
EXPORT_SYMBOL_NS(hda_dsp_compr_close, "SND_SOC_SOF_INTEL_HDA_COMMON");
32 changes: 26 additions & 6 deletions sound/soc/sof/intel/hda-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ static int _hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stre
if (s->direction == direction && s->stream_tag == stream_tag) {
s->opened = false;
found = true;
s->curr_pos = 0;
if (pair)
link_stream = hext_stream;
} else if (!(hda_stream->flags & SOF_HDA_STREAM_DMI_L1_COMPATIBLE)) {
Expand Down Expand Up @@ -1157,11 +1158,9 @@ EXPORT_SYMBOL_NS(hda_dsp_stream_get_position, "SND_SOC_SOF_INTEL_HDA_COMMON");
*
* Returns the raw Linear Link Position value
*/
u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
struct snd_soc_component *component,
struct snd_pcm_substream *substream)
static u64 hda_dsp_get_llp(struct snd_sof_dev *sdev,
struct snd_soc_pcm_runtime *rtd, int dir)
{
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_pcm_runtime *be_rtd = NULL;
struct hdac_ext_stream *hext_stream;
struct snd_soc_dai *cpu_dai;
Expand All @@ -1172,7 +1171,7 @@ u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
* The LLP needs to be read from the Link DMA used for this FE as it is
* allowed to use any combination of Link and Host channels
*/
for_each_dpcm_be(rtd, substream->stream, dpcm) {
for_each_dpcm_be(rtd, dir, dpcm) {
if (dpcm->fe != rtd)
continue;

Expand All @@ -1186,7 +1185,7 @@ u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
if (!cpu_dai)
return 0;

hext_stream = snd_soc_dai_get_dma_data(cpu_dai, substream);
hext_stream = snd_soc_dai_dma_data_get(cpu_dai, dir);
if (!hext_stream)
return 0;

Expand All @@ -1210,8 +1209,29 @@ u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,

return merge_u64(llp_u, llp_l);
}

u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
return hda_dsp_get_llp(sdev, snd_soc_substream_to_rtd(substream),
substream->stream);
}
EXPORT_SYMBOL_NS(hda_dsp_get_stream_llp, "SND_SOC_SOF_INTEL_HDA_COMMON");

/**
* hda_dsp_compr_get_stream_llp - Retrieve the LLP (Linear Link Position) of the stream
* @sdev: SOF device
* @cstream: Compress stream
*
* Returns the raw Linear Link Position value
*/
u64 hda_dsp_compr_get_stream_llp(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream)
{
return hda_dsp_get_llp(sdev, cstream->private_data, cstream->direction);
}
EXPORT_SYMBOL_NS(hda_dsp_compr_get_stream_llp, "SND_SOC_SOF_INTEL_HDA_COMMON");

/**
* hda_dsp_get_stream_ldp - Retrieve the LDP (Linear DMA Position) of the stream
* @sdev: SOF device
Expand Down
Loading
Loading