Unverified Commit 4a9ce6e4 authored by Cezary Rojewski's avatar Cezary Rojewski Committed by Mark Brown
Browse files

ASoC: SOF: Intel: Account for compress streams when servicing IRQs



Update stream irq handler definition to correctly set hdac_stream
current position when servicing stream interrupts for compress streams.

Signed-off-by: default avatarCezary Rojewski <cezary.rojewski@intel.com>
Acked-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20200218143924.10565-4-cezary.rojewski@intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent b9759ef2
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -513,6 +513,7 @@ struct hdac_stream {
	struct snd_pcm_substream *substream;	/* assigned substream,
						 * set in PCM open
						 */
	struct snd_compr_stream *cstream;
	unsigned int format_val;	/* format value to be set in the
					 * controller and the codec
					 */
@@ -527,6 +528,7 @@ struct hdac_stream {
	bool locked:1;
	bool stripe:1;			/* apply stripe control */

	u64 curr_pos;
	/* timestamp */
	unsigned long start_wallclk;	/* start + minimum wallclk */
	unsigned long period_wallclk;	/* wallclk for period */
+23 −2
Original line number Diff line number Diff line
@@ -571,6 +571,22 @@ bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev)
	return ret;
}

static void
hda_dsp_set_bytes_transferred(struct hdac_stream *hstream, u64 buffer_size)
{
	u64 prev_pos, pos, num_bytes;

	div64_u64_rem(hstream->curr_pos, buffer_size, &prev_pos);
	pos = snd_hdac_stream_get_pos_posbuf(hstream);

	if (pos < prev_pos)
		num_bytes = (buffer_size - prev_pos) +  pos;
	else
		num_bytes = pos - prev_pos;

	hstream->curr_pos += num_bytes;
}

static bool hda_dsp_stream_check(struct hdac_bus *bus, u32 status)
{
	struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
@@ -588,14 +604,19 @@ static bool hda_dsp_stream_check(struct hdac_bus *bus, u32 status)
			snd_hdac_stream_writeb(s, SD_STS, sd_status);

			active = true;
			if (!s->substream ||
			if ((!s->substream && !s->cstream) ||
			    !s->running ||
			    (sd_status & SOF_HDA_CL_DMA_SD_INT_COMPLETE) == 0)
				continue;

			/* Inform ALSA only in case not do that with IPC */
			if (sof_hda->no_ipc_position)
			if (s->substream && sof_hda->no_ipc_position) {
				snd_sof_pcm_period_elapsed(s->substream);
			} else if (s->cstream) {
				hda_dsp_set_bytes_transferred(s,
					s->cstream->runtime->buffer_size);
				snd_compr_fragment_elapsed(s->cstream);
			}
		}
	}