Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 6b2239e3 authored by Ranjani Sridharan's avatar Ranjani Sridharan Committed by Mark Brown
Browse files

ASoC: SOF: Intel: hda: reserve host DMA channel for hostless streams



Due to the HW programming sequence requirement that the host
and link DMA channels need to be coupled/decoupled during pcm
hw_params, the host DMA channel corresponding to the link
DMA channel in use for hostless streams needs to be reserved.
This is achieved by adding a host_reserved flag in the
sof_intel_hda_stream structure which is checked when assigning
a host DMA channel.

Signed-off-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent bdf4ad3f
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -75,7 +75,7 @@ static struct hdac_ext_stream *

		hda_stream = hstream_to_sof_hda_stream(hstream);

		/* check if available */
		/* check if link is available */
		if (!hstream->link_locked) {
			if (stream->opened) {
				/*
@@ -89,6 +89,12 @@ static struct hdac_ext_stream *
				}
			} else {
				res = hstream;

				/*
				 * This must be a hostless stream.
				 * So reserve the host DMA channel.
				 */
				hda_stream->host_reserved = 1;
				break;
			}
		}
@@ -368,6 +374,9 @@ static int hda_link_hw_free(struct snd_pcm_substream *substream,
	snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK);
	link_dev->link_prepared = 0;

	/* free the host DMA channel reserved by hostless streams */
	hda_stream->host_reserved = 0;

	return 0;
}

+9 −1
Original line number Diff line number Diff line
@@ -155,6 +155,7 @@ struct hdac_ext_stream *
hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction)
{
	struct hdac_bus *bus = sof_to_bus(sdev);
	struct sof_intel_hda_stream *hda_stream;
	struct hdac_ext_stream *stream = NULL;
	struct hdac_stream *s;

@@ -163,8 +164,15 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction)
	/* get an unused stream */
	list_for_each_entry(s, &bus->stream_list, list) {
		if (s->direction == direction && !s->opened) {
			s->opened = true;
			stream = stream_to_hdac_ext_stream(s);
			hda_stream = container_of(stream,
						  struct sof_intel_hda_stream,
						  hda_stream);
			/* check if the host DMA channel is reserved */
			if (hda_stream->host_reserved)
				continue;

			s->opened = true;
			break;
		}
	}
+1 −0
Original line number Diff line number Diff line
@@ -413,6 +413,7 @@ struct sof_intel_hda_stream {
	struct hdac_ext_stream hda_stream;
	struct sof_intel_stream stream;
	int hw_params_upon_resume; /* set up hw_params upon resume */
	int host_reserved; /* reserve host DMA channel */
};

#define hstream_to_sof_hda_stream(hstream) \