ASoC: Intel: Fix stream position pointer.
Read the stream offset and presentation position from DSP memory rather than using the old estimated position. This fixes timing issues with pulseaudio. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com> Signed-off-by: Mark Brown <broonie@linaro.org>
This commit is contained in:
parent
916152c488
commit
51b4e24f38
@ -1547,10 +1547,28 @@ int sst_hsw_stream_reset(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Stream pointer positions */
|
/* Stream pointer positions */
|
||||||
int sst_hsw_get_dsp_position(struct sst_hsw *hsw,
|
u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw,
|
||||||
struct sst_hsw_stream *stream)
|
struct sst_hsw_stream *stream)
|
||||||
{
|
{
|
||||||
return stream->rpos.position;
|
u32 rpos;
|
||||||
|
|
||||||
|
sst_dsp_read(hsw->dsp, &rpos,
|
||||||
|
stream->reply.read_position_register_address, sizeof(rpos));
|
||||||
|
|
||||||
|
return rpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stream presentation (monotonic) positions */
|
||||||
|
u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw,
|
||||||
|
struct sst_hsw_stream *stream)
|
||||||
|
{
|
||||||
|
u64 ppos;
|
||||||
|
|
||||||
|
sst_dsp_read(hsw->dsp, &ppos,
|
||||||
|
stream->reply.presentation_position_register_address,
|
||||||
|
sizeof(ppos));
|
||||||
|
|
||||||
|
return ppos;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,
|
int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,
|
||||||
|
@ -464,7 +464,9 @@ int sst_hsw_stream_get_write_pos(struct sst_hsw *hsw,
|
|||||||
struct sst_hsw_stream *stream, u32 *position);
|
struct sst_hsw_stream *stream, u32 *position);
|
||||||
int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,
|
int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,
|
||||||
struct sst_hsw_stream *stream, u32 stage_id, u32 position);
|
struct sst_hsw_stream *stream, u32 stage_id, u32 position);
|
||||||
int sst_hsw_get_dsp_position(struct sst_hsw *hsw,
|
u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw,
|
||||||
|
struct sst_hsw_stream *stream);
|
||||||
|
u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw,
|
||||||
struct sst_hsw_stream *stream);
|
struct sst_hsw_stream *stream);
|
||||||
|
|
||||||
/* HW port config */
|
/* HW port config */
|
||||||
|
@ -569,12 +569,14 @@ static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream)
|
|||||||
struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
|
struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
|
||||||
struct sst_hsw *hsw = pdata->hsw;
|
struct sst_hsw *hsw = pdata->hsw;
|
||||||
snd_pcm_uframes_t offset;
|
snd_pcm_uframes_t offset;
|
||||||
|
uint64_t ppos;
|
||||||
|
u32 position = sst_hsw_get_dsp_position(hsw, pcm_data->stream);
|
||||||
|
|
||||||
offset = bytes_to_frames(runtime,
|
offset = bytes_to_frames(runtime, position);
|
||||||
sst_hsw_get_dsp_position(hsw, pcm_data->stream));
|
ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream);
|
||||||
|
|
||||||
dev_dbg(rtd->dev, "PCM: DMA pointer %zu bytes\n",
|
dev_dbg(rtd->dev, "PCM: DMA pointer %du bytes, pos %llu\n",
|
||||||
frames_to_bytes(runtime, (u32)offset));
|
position, ppos);
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user