Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Deepin-Kernel-SIG] [Upstream] [linux 6.6-y] ASoC: Sync some intel patches from mainline v6.9 and v6.10 #517

Merged
merged 40 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
1e09942
ASoC: SOF: ipc4-topology: change chain_dma handling in dai_config
plbossart Feb 13, 2024
79b6142
ASoC: SOF: ops: add new 'is_chain_dma_supported' callback
plbossart Feb 13, 2024
e006f2b
ASoC: SOF: Intel: hda: add 'is_chain_dma_supported' callback
plbossart Feb 13, 2024
5fbc095
ASoC: SOF: Intel: hda-dai-ops: enable chain_dma for ALH
plbossart Feb 13, 2024
1bd1a04
ASoC: SOF: ipc4: store number of playback/capture streams
plbossart Feb 13, 2024
d801249
ASoC: SOF: ipc4-pcm: fix dma_id for CHAIN_DMA capture
plbossart Feb 13, 2024
182ab6f
ASoC: SOF: ipc4-topology: allow chain_dma for all supported DAIs
plbossart Feb 13, 2024
9caee06
ASoC: SOF: Intel: hda-dai: remove dspless special case
plbossart Feb 13, 2024
5d008dd
ASoC: SOF: topology: dynamically allocate and store DAI widget->private
plbossart Feb 13, 2024
f1b296a
ALSA: hda: intel-nhlt: add intel_nhlt_ssp_device_type() function
brentlu Nov 27, 2023
f143944
ASoC: SOF: ipc4-topology: support NHLT device type
brentlu Nov 27, 2023
d0bc099
ASoC: SOF: Add dsp_max_burst_size_in_ms member to snd_sof_pcm_stream
ujfalusi Mar 21, 2024
6090cc7
ASoC: SOF: ipc4-topology: Save the DMA maximum burst size for PCMs
ujfalusi Mar 21, 2024
7260bfa
ASoC: SOF: Intel: hda-pcm: Use dsp_max_burst_size_in_ms to place cons…
ujfalusi Mar 21, 2024
1a9d914
ASoC: SOF: Intel: hda: Implement get_stream_position (Linear Link Pos…
ujfalusi Mar 21, 2024
342b20e
ASoC: SOF: Intel: mtl/lnl: Use the generic get_stream_position callback
ujfalusi Mar 21, 2024
6bd6357
ASoC: SOF: Introduce a new callback pair to be used for PCM delay rep…
ujfalusi Mar 21, 2024
719d718
ASoC: SOF: Intel: Set the dai/host get frame/byte counter callbacks
ujfalusi Mar 21, 2024
8d10ab0
ASoC: SOF: ipc4-pcm: Use the snd_sof_pcm_get_dai_frame_counter() for …
ujfalusi Mar 21, 2024
2036e73
ASoC: SOF: Intel: hda-common-ops: Do not set the get_stream_position …
ujfalusi Mar 21, 2024
6f3d9f3
ASoC: SOF: Remove the get_stream_position callback
ujfalusi Mar 21, 2024
65d2d0e
ASoC: SOF: ipc4-pcm: Move struct sof_ipc4_timestamp_info definition l…
ujfalusi Mar 21, 2024
12dfe87
ASoC: SOF: ipc4-pcm: Combine the SOF_IPC4_PIPE_PAUSED cases in pcm_tr…
ujfalusi Mar 21, 2024
0055b86
ASoC: SOF: ipc4-pcm: Invalidate the stream_start_offset in PAUSED state
ujfalusi Mar 21, 2024
72ec702
ASoC: SOF: sof-pcm: Add pointer callback to sof_ipc_pcm_ops
ujfalusi Mar 21, 2024
56c5368
ASoC: SOF: ipc4-pcm: Correct the delay calculation
ujfalusi Mar 21, 2024
ef03151
ALSA: hda: Add pplcllpl/u members to hdac_ext_stream
ujfalusi Mar 21, 2024
2450da7
ASoC: SOF: Intel: hda: Compensate LLP in case it is not reset
ujfalusi Mar 21, 2024
2b3a607
ASoC: SOF: ipc4-pcm: Use consistent name for snd_sof_pcm_stream pointer
ujfalusi Apr 9, 2024
bf2227b
ASoC: SOF: ipc4-pcm: Use consistent name for sof_ipc4_timestamp_info …
ujfalusi Apr 9, 2024
464be2b
ASoC: SOF: ipc4-pcm: Introduce generic sof_ipc4_pcm_stream_priv
ujfalusi Apr 9, 2024
9b97560
ASoC: SOF: ipc4-pcm: Do not reset the ChainDMA if it has not been all…
ujfalusi Apr 9, 2024
875e9e1
ASoC: SOF: Intel: discard SoundWire configuration if HDaudio codec is…
plbossart May 3, 2024
aba04ae
ASoC: SOF: ipc4-topology: Allow selective update in sof_ipc4_update_h…
ujfalusi May 3, 2024
34795df
ASoC: SOF: ipc4-topology: Correct DAI copier config and NHLT blob req…
ujfalusi May 3, 2024
6718dc7
ASoC: SOF: ipc4-topology: Add support for NHLT with 16-bit only DMIC …
ujfalusi May 30, 2024
9ed039a
ASoC: SOF: ipc4-topology: Print out the channel count in sof_ipc4_dbg…
ujfalusi May 30, 2024
b1c23a2
ASoC: SOF: ipc4-topology/pcm: Rename sof_ipc4_copier_is_single_format()
ujfalusi May 30, 2024
ff29ed7
ASoC: SOF: ipc4-topology: Improve readability of sof_ipc4_prepare_dai…
ujfalusi May 30, 2024
b79d5a8
ASoC: SOF: ipc4-topology: Adjust the params based on DAI formats
ujfalusi May 30, 2024
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
3 changes: 3 additions & 0 deletions include/sound/hdaudio_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ struct hdac_ext_stream {
u32 pphcldpl;
u32 pphcldpu;

u32 pplcllpl;
u32 pplcllpu;

bool decoupled:1;
bool link_locked:1;
bool link_prepared;
Expand Down
10 changes: 10 additions & 0 deletions include/sound/intel-nhlt.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
u32 bus_id, u8 link_type, u8 vbps, u8 bps,
u8 num_ch, u32 rate, u8 dir, u8 dev_type);

int intel_nhlt_ssp_device_type(struct device *dev, struct nhlt_acpi_table *nhlt,
u8 virtual_bus_id);

#else

static inline struct nhlt_acpi_table *intel_nhlt_init(struct device *dev)
Expand Down Expand Up @@ -184,6 +187,13 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
return NULL;
}

static inline int intel_nhlt_ssp_device_type(struct device *dev,
struct nhlt_acpi_table *nhlt,
u8 virtual_bus_id)
{
return -EINVAL;
}

#endif

#endif
26 changes: 26 additions & 0 deletions sound/hda/intel-nhlt.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,3 +343,29 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
return NULL;
}
EXPORT_SYMBOL(intel_nhlt_get_endpoint_blob);

int intel_nhlt_ssp_device_type(struct device *dev, struct nhlt_acpi_table *nhlt,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Prefer a maximum 75 chars per line (possible unwrapped commit description?)

u8 virtual_bus_id)
{
struct nhlt_endpoint *epnt;
int i;

if (!nhlt)
return -EINVAL;

epnt = (struct nhlt_endpoint *)nhlt->desc;
for (i = 0; i < nhlt->endpoint_count; i++) {
/* for SSP link the virtual bus id is the SSP port number */
if (epnt->linktype == NHLT_LINK_SSP &&
epnt->virtual_bus_id == virtual_bus_id) {
dev_dbg(dev, "SSP%d: dev_type=%d\n", virtual_bus_id,
epnt->device_type);
return epnt->device_type;
}

epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length);
}

return -EINVAL;
}
EXPORT_SYMBOL(intel_nhlt_ssp_device_type);
4 changes: 4 additions & 0 deletions sound/soc/sof/intel/hda-common-ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ struct snd_sof_dsp_ops sof_hda_common_ops = {
.pcm_pointer = hda_dsp_pcm_pointer,
.pcm_ack = hda_dsp_pcm_ack,

.get_dai_frame_counter = hda_dsp_get_stream_llp,
.get_host_byte_counter = hda_dsp_get_stream_ldp,

/* firmware loading */
.load_firmware = snd_sof_load_firmware_raw,

Expand All @@ -82,6 +85,7 @@ 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
31 changes: 26 additions & 5 deletions sound/soc/sof/intel/hda-dai-ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <sound/pcm_params.h>
#include <sound/hdaudio_ext.h>
#include <sound/hda_register.h>
#include <sound/hda-mlink.h>
#include <sound/sof/ipc4/header.h>
#include <uapi/sound/sof/header.h>
Expand Down Expand Up @@ -361,6 +362,16 @@ static int hda_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai,
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
snd_hdac_ext_stream_clear(hext_stream);

/*
* Save the LLP registers in case the stream is
* restarting due PAUSE_RELEASE, or START without a pcm
* close/open since in this case the LLP register is not reset
* to 0 and the delay calculation will return with invalid
* results.
*/
hext_stream->pplcllpl = readl(hext_stream->pplc_addr + AZX_REG_PPLCLLPL);
hext_stream->pplcllpu = readl(hext_stream->pplc_addr + AZX_REG_PPLCLLPU);
break;
default:
dev_err(sdev->dev, "unknown trigger command %d\n", cmd);
Expand Down Expand Up @@ -521,6 +532,17 @@ 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 @@ -619,22 +641,19 @@ 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 @@ -646,6 +665,8 @@ 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
6 changes: 1 addition & 5 deletions sound/soc/sof/intel/hda-dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,8 @@ hda_dai_get_ops(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai

sdev = widget_to_sdev(w);

/*
* The swidget parameter of hda_select_dai_widget_ops() is ignored in
* case of DSPless mode
*/
if (sdev->dspless_mode_selected)
return hda_select_dai_widget_ops(sdev, NULL);
return hda_select_dai_widget_ops(sdev, swidget);

sdai = swidget->private;

Expand Down
29 changes: 29 additions & 0 deletions sound/soc/sof/intel/hda-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,37 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
snd_pcm_hw_constraint_mask64(substream->runtime, SNDRV_PCM_HW_PARAM_FORMAT,
SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_S32);

/*
* The dsp_max_burst_size_in_ms is the length of the maximum burst size
* of the host DMA in the ALSA buffer.
*
* On playback start the DMA will transfer dsp_max_burst_size_in_ms
* amount of data in one initial burst to fill up the host DMA buffer.
* Consequent DMA burst sizes are shorter and their length can vary.
* To make sure that userspace allocate large enough ALSA buffer we need
* to place a constraint on the buffer time.
*
* On capture the DMA will transfer 1ms chunks.
*
* Exact dsp_max_burst_size_in_ms constraint is racy, so set the
* constraint to a minimum of 2x dsp_max_burst_size_in_ms.
*/
if (spcm->stream[direction].dsp_max_burst_size_in_ms)
snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_BUFFER_TIME,
spcm->stream[direction].dsp_max_burst_size_in_ms * USEC_PER_MSEC * 2,
UINT_MAX);

/* binding pcm substream to hda stream */
substream->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;
}

Expand Down
79 changes: 79 additions & 0 deletions sound/soc/sof/intel/hda-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <trace/events/sof_intel.h>
#include "../ops.h"
#include "../sof-audio.h"
#include "../ipc4-priv.h"
#include "hda.h"

#define HDA_LTRP_GB_VALUE_US 95
Expand Down Expand Up @@ -937,6 +938,14 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev)
/* store total stream count (playback + capture) from GCAP */
sof_hda->stream_max = num_total;

/* store stream count from GCAP required for CHAIN_DMA */
if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_fw_data *ipc4_data = sdev->private;

ipc4_data->num_playback_streams = num_playback;
ipc4_data->num_capture_streams = num_capture;
}

return 0;
}

Expand Down Expand Up @@ -1054,3 +1063,73 @@ snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream,

return pos;
}

#define merge_u64(u32_u, u32_l) (((u64)(u32_u) << 32) | (u32_l))

/**
* hda_dsp_get_stream_llp - Retrieve the LLP (Linear Link Position) of the stream
* @sdev: SOF device
* @component: ASoC component
* @substream: PCM substream
*
* 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)
{
struct hdac_stream *hstream = substream->runtime->private_data;
struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
u32 llp_l, llp_u;

/*
* The pplc_addr have been calculated during probe in
* hda_dsp_stream_init():
* pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
* SOF_HDA_PPLC_BASE +
* SOF_HDA_PPLC_MULTI * total_stream +
* SOF_HDA_PPLC_INTERVAL * stream_index
*
* Use this pre-calculated address to avoid repeated re-calculation.
*/
llp_l = readl(hext_stream->pplc_addr + AZX_REG_PPLCLLPL);
llp_u = readl(hext_stream->pplc_addr + AZX_REG_PPLCLLPU);

/* Compensate the LLP counter with the saved offset */
if (hext_stream->pplcllpl || hext_stream->pplcllpu)
return merge_u64(llp_u, llp_l) -
merge_u64(hext_stream->pplcllpu, hext_stream->pplcllpl);

return merge_u64(llp_u, llp_l);
}

/**
* hda_dsp_get_stream_ldp - Retrieve the LDP (Linear DMA Position) of the stream
* @sdev: SOF device
* @component: ASoC component
* @substream: PCM substream
*
* Returns the raw Linear Link Position value
*/
u64 hda_dsp_get_stream_ldp(struct snd_sof_dev *sdev,
struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct hdac_stream *hstream = substream->runtime->private_data;
struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
u32 ldp_l, ldp_u;

/*
* The pphc_addr have been calculated during probe in
* hda_dsp_stream_init():
* pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
* SOF_HDA_PPHC_BASE +
* SOF_HDA_PPHC_INTERVAL * stream_index
*
* Use this pre-calculated address to avoid repeated re-calculation.
*/
ldp_l = readl(hext_stream->pphc_addr + AZX_REG_PPHCLDPL);
ldp_u = readl(hext_stream->pphc_addr + AZX_REG_PPHCLDPU);

return ((u64)ldp_u << 32) | ldp_l;
}
Loading
Loading