Skip to content
1 change: 0 additions & 1 deletion sound/soc/sof/intel/hda-common-ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ struct snd_sof_dsp_ops sof_hda_common_ops = {
/* DAI drivers */
.drv = skl_dai,
.num_drv = SOF_SKL_NUM_DAIS,
.is_chain_dma_supported = hda_is_chain_dma_supported,

/* PM */
.suspend = hda_dsp_suspend,
Expand Down
41 changes: 7 additions & 34 deletions sound/soc/sof/intel/hda-dai-ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,32 +237,15 @@ static unsigned int generic_calc_stream_format(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai;
unsigned int format_val;
u32 ch_mask = 0;
int num_channels;
int codec_dai_id;

/*
* if the multiple dais are handled by the same dailink, we may need to update the
* stream channel count - the params are modified in soc-pcm based on the codec_ch_maps info
*/
for_each_rtd_codec_dais(rtd, codec_dai_id, codec_dai)
ch_mask |= rtd->dai_link->codec_ch_maps[codec_dai_id].ch_mask;

num_channels = hweight_long(ch_mask);
if (num_channels != params_channels(params))
dev_dbg(sdev->dev, "configuring stream format for %d channels, params_channels was %d\n",
num_channels, params_channels(params));

format_val = snd_hdac_calc_stream_format(params_rate(params), num_channels,
format_val = snd_hdac_calc_stream_format(params_rate(params), params_channels(params),
params_format(params),
params_physical_width(params),
0);

dev_dbg(sdev->dev, "format_val=%#x, rate=%d, ch=%d, format=%d\n", format_val,
params_rate(params), num_channels, params_format(params));
params_rate(params), params_channels(params), params_format(params));

return format_val;
}
Expand Down Expand Up @@ -538,17 +521,6 @@ static const struct hda_dai_widget_dma_ops hda_ipc4_chain_dma_ops = {
.get_hlink = hda_get_hlink,
};

static const struct hda_dai_widget_dma_ops sdw_ipc4_chain_dma_ops = {
.get_hext_stream = hda_get_hext_stream,
.assign_hext_stream = hda_assign_hext_stream,
.release_hext_stream = hda_release_hext_stream,
.setup_hext_stream = hda_setup_hext_stream,
.reset_hext_stream = hda_reset_hext_stream,
.trigger = hda_trigger,
.calc_stream_format = generic_calc_stream_format,
.get_hlink = sdw_get_hlink,
};

static int hda_ipc3_post_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai,
struct snd_pcm_substream *substream, int cmd)
{
Expand Down Expand Up @@ -647,19 +619,22 @@ hda_select_dai_widget_ops(struct snd_sof_dev *sdev, struct snd_sof_widget *swidg
}
case SOF_IPC_TYPE_4:
{
struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
struct sof_ipc4_pipeline *pipeline = pipe_widget->private;
struct sof_ipc4_copier *ipc4_copier = sdai->private;
const struct sof_intel_dsp_desc *chip;

chip = get_chip_info(sdev->pdata);

switch (ipc4_copier->dai_type) {
case SOF_DAI_INTEL_HDA:
{
struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
struct sof_ipc4_pipeline *pipeline = pipe_widget->private;

if (pipeline->use_chain_dma)
return &hda_ipc4_chain_dma_ops;

return &hda_ipc4_dma_ops;
}
case SOF_DAI_INTEL_SSP:
if (chip->hw_ip_version < SOF_INTEL_ACE_2_0)
return NULL;
Expand All @@ -671,8 +646,6 @@ hda_select_dai_widget_ops(struct snd_sof_dev *sdev, struct snd_sof_widget *swidg
case SOF_DAI_INTEL_ALH:
if (chip->hw_ip_version < SOF_INTEL_ACE_2_0)
return NULL;
if (pipeline->use_chain_dma)
return &sdw_ipc4_chain_dma_ops;
return &sdw_ipc4_dma_ops;

default:
Expand Down
31 changes: 2 additions & 29 deletions sound/soc/sof/intel/hda-dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,17 +434,10 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream,
int link_id)
{
struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(cpu_dai, substream->stream);
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
const struct hda_dai_widget_dma_ops *ops;
struct hdac_ext_stream *hext_stream;
struct snd_soc_dai *codec_dai;
struct snd_soc_dai *dai;
struct snd_sof_dev *sdev;
bool cpu_dai_found = false;
int cpu_dai_id;
int ch_mask;
int ret;
int j;

ret = non_hda_dai_hw_params(substream, params, cpu_dai);
if (ret < 0) {
Expand All @@ -459,29 +452,9 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream,
if (!hext_stream)
return -ENODEV;

/*
* in the case of SoundWire we need to program the PCMSyCM registers. In case
* of aggregated devices, we need to define the channel mask for each sublink
* by reconstructing the split done in soc-pcm.c
*/
for_each_rtd_cpu_dais(rtd, cpu_dai_id, dai) {
if (dai == cpu_dai) {
cpu_dai_found = true;
break;
}
}

if (!cpu_dai_found)
return -ENODEV;

ch_mask = 0;
for_each_rtd_codec_dais(rtd, j, codec_dai) {
if (rtd->dai_link->codec_ch_maps[j].connected_cpu_id == cpu_dai_id)
ch_mask |= rtd->dai_link->codec_ch_maps[j].ch_mask;
}

/* in the case of SoundWire we need to program the PCMSyCM registers */
ret = hdac_bus_eml_sdw_map_stream_ch(sof_to_bus(sdev), link_id, cpu_dai->id,
ch_mask,
GENMASK(params_channels(params) - 1, 0),
hdac_stream(hext_stream)->stream_tag,
substream->stream);
if (ret < 0) {
Expand Down
63 changes: 12 additions & 51 deletions sound/soc/sof/intel/hda.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,83 +46,44 @@
#define EXCEPT_MAX_HDR_SIZE 0x400
#define HDA_EXT_ROM_STATUS_SIZE 8

static void hda_get_interfaces(struct snd_sof_dev *sdev, u32 *interface_mask)
static u32 hda_get_interface_mask(struct snd_sof_dev *sdev)
{
const struct sof_intel_dsp_desc *chip;
u32 interface_mask[2] = { 0 };

chip = get_chip_info(sdev->pdata);
switch (chip->hw_ip_version) {
case SOF_INTEL_TANGIER:
case SOF_INTEL_BAYTRAIL:
case SOF_INTEL_BROADWELL:
interface_mask[SOF_DAI_DSP_ACCESS] = BIT(SOF_DAI_INTEL_SSP);
interface_mask[0] = BIT(SOF_DAI_INTEL_SSP);
break;
case SOF_INTEL_CAVS_1_5:
case SOF_INTEL_CAVS_1_5_PLUS:
interface_mask[SOF_DAI_DSP_ACCESS] =
BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC) | BIT(SOF_DAI_INTEL_HDA);
interface_mask[SOF_DAI_HOST_ACCESS] = BIT(SOF_DAI_INTEL_HDA);
interface_mask[0] = BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC) |
BIT(SOF_DAI_INTEL_HDA);
interface_mask[1] = BIT(SOF_DAI_INTEL_HDA);
break;
case SOF_INTEL_CAVS_1_8:
case SOF_INTEL_CAVS_2_0:
case SOF_INTEL_CAVS_2_5:
case SOF_INTEL_ACE_1_0:
interface_mask[SOF_DAI_DSP_ACCESS] =
BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC) |
BIT(SOF_DAI_INTEL_HDA) | BIT(SOF_DAI_INTEL_ALH);
interface_mask[SOF_DAI_HOST_ACCESS] = BIT(SOF_DAI_INTEL_HDA);
interface_mask[0] = BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC) |
BIT(SOF_DAI_INTEL_HDA) | BIT(SOF_DAI_INTEL_ALH);
interface_mask[1] = BIT(SOF_DAI_INTEL_HDA);
break;
case SOF_INTEL_ACE_2_0:
interface_mask[SOF_DAI_DSP_ACCESS] =
BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC) |
BIT(SOF_DAI_INTEL_HDA) | BIT(SOF_DAI_INTEL_ALH);
/* all interfaces accessible without DSP */
interface_mask[SOF_DAI_HOST_ACCESS] =
interface_mask[SOF_DAI_DSP_ACCESS];
interface_mask[0] = BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC) |
BIT(SOF_DAI_INTEL_HDA) | BIT(SOF_DAI_INTEL_ALH);
interface_mask[1] = interface_mask[0]; /* all interfaces accessible without DSP */
break;
default:
break;
}
}

static u32 hda_get_interface_mask(struct snd_sof_dev *sdev)
{
u32 interface_mask[SOF_DAI_ACCESS_NUM] = { 0 };

hda_get_interfaces(sdev, interface_mask);

return interface_mask[sdev->dspless_mode_selected];
}

bool hda_is_chain_dma_supported(struct snd_sof_dev *sdev, u32 dai_type)
{
u32 interface_mask[SOF_DAI_ACCESS_NUM] = { 0 };
const struct sof_intel_dsp_desc *chip;

if (sdev->dspless_mode_selected)
return false;

hda_get_interfaces(sdev, interface_mask);

if (!(interface_mask[SOF_DAI_DSP_ACCESS] & BIT(dai_type)))
return false;

if (dai_type == SOF_DAI_INTEL_HDA)
return true;

switch (dai_type) {
case SOF_DAI_INTEL_SSP:
case SOF_DAI_INTEL_DMIC:
case SOF_DAI_INTEL_ALH:
chip = get_chip_info(sdev->pdata);
if (chip->hw_ip_version < SOF_INTEL_ACE_2_0)
return false;
return true;
default:
return false;
}
}

#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)

/*
Expand Down
5 changes: 0 additions & 5 deletions sound/soc/sof/intel/hda.h
Original file line number Diff line number Diff line change
Expand Up @@ -573,11 +573,6 @@ struct sof_intel_hda_stream {

#define SOF_STREAM_SD_OFFSET_CRST 0x1

/*
* DAI support
*/
bool hda_is_chain_dma_supported(struct snd_sof_dev *sdev, u32 dai_type);

/*
* DSP Core services.
*/
Expand Down
21 changes: 9 additions & 12 deletions sound/soc/sof/ipc4-topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,6 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget)
{
struct sof_ipc4_available_audio_format *available_fmt;
struct snd_soc_component *scomp = swidget->scomp;
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
struct snd_sof_dai *dai = swidget->private;
struct sof_ipc4_copier *ipc4_copier;
struct snd_sof_widget *pipe_widget;
Expand Down Expand Up @@ -533,11 +532,10 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget)

pipe_widget = swidget->spipe->pipe_widget;
pipeline = pipe_widget->private;

if (pipeline->use_chain_dma &&
!snd_sof_is_chain_dma_supported(sdev, ipc4_copier->dai_type)) {
dev_err(scomp->dev, "Bad DAI type '%d', Chain DMA is not supported\n",
ipc4_copier->dai_type);
if (pipeline->use_chain_dma && ipc4_copier->dai_type != SOF_DAI_INTEL_HDA) {
dev_err(scomp->dev,
"Bad DAI type '%d', Chained DMA is only supported by HDA DAIs (%d).\n",
ipc4_copier->dai_type, SOF_DAI_INTEL_HDA);
ret = -ENODEV;
goto free_available_fmt;
}
Expand Down Expand Up @@ -2761,14 +2759,13 @@ static int sof_ipc4_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget *
if (!data)
return 0;

if (pipeline->use_chain_dma) {
pipeline->msg.primary &= ~SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK;
pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID(data->dai_data);
return 0;
}

switch (ipc4_copier->dai_type) {
case SOF_DAI_INTEL_HDA:
if (pipeline->use_chain_dma) {
pipeline->msg.primary &= ~SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK;
pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID(data->dai_data);
break;
}
gtw_attr = ipc4_copier->gtw_attr;
gtw_attr->lp_buffer_alloc = pipeline->lp_mode;
fallthrough;
Expand Down
9 changes: 0 additions & 9 deletions sound/soc/sof/ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -555,15 +555,6 @@ snd_sof_set_mach_params(struct snd_soc_acpi_mach *mach,
sof_ops(sdev)->set_mach_params(mach, sdev);
}

static inline bool
snd_sof_is_chain_dma_supported(struct snd_sof_dev *sdev, u32 dai_type)
{
if (sof_ops(sdev) && sof_ops(sdev)->is_chain_dma_supported)
return sof_ops(sdev)->is_chain_dma_supported(sdev, dai_type);

return false;
}

/**
* snd_sof_dsp_register_poll_timeout - Periodically poll an address
* until a condition is met or a timeout occurs
Expand Down
9 changes: 0 additions & 9 deletions sound/soc/sof/sof-priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,6 @@ struct sof_firmware {
u32 payload_offset;
};

enum sof_dai_access {
SOF_DAI_DSP_ACCESS, /* access from DSP only */
SOF_DAI_HOST_ACCESS, /* access from host only */

SOF_DAI_ACCESS_NUM
};

/*
* SOF DSP HW abstraction operations.
* Used to abstract DSP HW architecture and any IO busses between host CPU
Expand Down Expand Up @@ -343,8 +336,6 @@ struct snd_sof_dsp_ops {
struct snd_soc_dai_driver *drv;
int num_drv;

bool (*is_chain_dma_supported)(struct snd_sof_dev *sdev, u32 dai_type); /* optional */

/* ALSA HW info flags, will be stored in snd_pcm_runtime.hw.info */
u32 hw_info;

Expand Down