Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions sound/soc/sof/intel/hda-loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ static int cl_stream_prepare(struct snd_sof_dev *sdev, unsigned int format,
int ret;

if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
stream = hda_dsp_stream_get_pstream(sdev);
stream = hda_dsp_stream_get(sdev, direction, FALSE);
} else {
dev_err(sdev->dev, "error: code loading DMA is playback only\n");
return -EINVAL;
Expand Down Expand Up @@ -77,7 +77,8 @@ static int cl_stream_prepare(struct snd_sof_dev *sdev, unsigned int format,
return hstream->stream_tag;

error:
hda_dsp_stream_put_pstream(sdev, hstream->stream_tag);
hda_dsp_stream_put(sdev, SNDRV_PCM_STREAM_PLAYBACK,
hstream->stream_tag);
snd_dma_free_pages(dmab);
return ret;
}
Expand Down
12 changes: 3 additions & 9 deletions sound/soc/sof/intel/hda-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,7 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
{
struct hdac_ext_stream *stream;

if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
stream = hda_dsp_stream_get_pstream(sdev);
else
stream = hda_dsp_stream_get_cstream(sdev);

stream = hda_dsp_stream_get(sdev, substream->stream, FALSE);
if (!stream) {
dev_err(sdev->dev, "error: no stream available\n");
return -ENODEV;
Expand All @@ -233,10 +229,8 @@ int hda_dsp_pcm_close(struct snd_sof_dev *sdev,
struct hdac_stream *hstream = substream->runtime->private_data;
int ret;

if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
ret = hda_dsp_stream_put_pstream(sdev, hstream->stream_tag);
else
ret = hda_dsp_stream_put_cstream(sdev, hstream->stream_tag);
ret = hda_dsp_stream_put(sdev, substream->stream,
hstream->stream_tag);

if (ret) {
dev_dbg(sdev->dev, "stream %s not opened!\n", substream->name);
Expand Down
112 changes: 17 additions & 95 deletions sound/soc/sof/intel/hda-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,18 +165,28 @@ int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev,

/* get next unused stream */
struct hdac_ext_stream *
hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction)
hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, int reverse)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why do clients need to know about the order of searching the list for the next free stream ? This should not be known by callers.

Can you explain more why this has to match with the FW

@RanderWang RanderWang Oct 19, 2018 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Why do clients need to know about the order of searching the list for the next free stream ? This should not be known by callers.

for dma trace, it wants to get last capture stream, so it checks stream from last one to first one.

Can you explain more why this has to match with the FW

Now we allocate host dma channel and link dma channel base on the same stream tag. So If dma trace gets the index 0 channel, channel 1 would be gotten for host dma for capture by stream tag. And also channel 1 would be for link dma. But only channel 0 of link dma is the correct one which link to a hda codec. I fire a enhancement to totally fix it but it maybe not a easy task finished in short time.(thesofproject/sof#497) because each hda codec is fixed to a link dma channel, and this is defined by HW spec.
We need to get the hw info and send to FW. For COE driver, these info is gotten from topology. We need to check whether we can get it from some registers

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

this is related to the issue capture cant work with HDA

{
struct hdac_bus *bus = sof_to_bus(sdev);
struct hdac_ext_stream *stream = NULL;
struct hdac_stream *s;

/* get an unused playback 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);
break;
/* get an unused stream */
if (reverse) {
list_for_each_entry_reverse(s, &bus->stream_list, list) {
if (s->direction == direction && !s->opened) {
s->opened = true;
stream = stream_to_hdac_ext_stream(s);
break;
}
}
} else {
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);
break;
}
}
}

Expand All @@ -189,56 +199,6 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction)
return stream;
}

/* get next unused playback stream */
struct hdac_ext_stream *
hda_dsp_stream_get_pstream(struct snd_sof_dev *sdev)
{
struct hdac_bus *bus = sof_to_bus(sdev);
struct hdac_ext_stream *stream = NULL;
struct hdac_stream *s;

/* get an unused playback stream */
list_for_each_entry(s, &bus->stream_list, list) {
if (s->direction == SNDRV_PCM_STREAM_PLAYBACK
&& !s->opened) {
s->opened = true;
stream = stream_to_hdac_ext_stream(s);
break;
}
}

/* stream found ? */
if (!stream)
dev_err(sdev->dev, "error: no free playback streams\n");

return stream;
}

/* get next unused capture stream */
struct hdac_ext_stream *
hda_dsp_stream_get_cstream(struct snd_sof_dev *sdev)
{
struct hdac_bus *bus = sof_to_bus(sdev);
struct hdac_ext_stream *stream = NULL;
struct hdac_stream *s;

/* get an unused capture stream */
list_for_each_entry(s, &bus->stream_list, list) {
if (s->direction == SNDRV_PCM_STREAM_CAPTURE
&& !s->opened) {
s->opened = true;
stream = stream_to_hdac_ext_stream(s);
break;
}
}

/* stream found ? */
if (!stream)
dev_err(sdev->dev, "error: no free capture streams\n");

return stream;
}

/* free a stream */
int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int tag)
{
Expand All @@ -258,44 +218,6 @@ int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int tag)
return -ENODEV;
}

/* free playback stream */
int hda_dsp_stream_put_pstream(struct snd_sof_dev *sdev, int tag)
{
struct hdac_bus *bus = sof_to_bus(sdev);
struct hdac_stream *s;

/* find used playback stream */
list_for_each_entry(s, &bus->stream_list, list) {
if (s->direction == SNDRV_PCM_STREAM_PLAYBACK
&& s->opened && s->stream_tag == tag) {
s->opened = false;
return 0;
}
}

dev_dbg(sdev->dev, "tag %d not opened!\n", tag);
return -ENODEV;
}

/* free capture stream */
int hda_dsp_stream_put_cstream(struct snd_sof_dev *sdev, int tag)
{
struct hdac_bus *bus = sof_to_bus(sdev);
struct hdac_stream *s;

/* find used capture stream */
list_for_each_entry(s, &bus->stream_list, list) {
if (s->direction == SNDRV_PCM_STREAM_CAPTURE
&& s->opened && s->stream_tag == tag) {
s->opened = false;
return 0;
}
}

dev_dbg(sdev->dev, "tag %d not opened!\n", tag);
return -ENODEV;
}

int hda_dsp_stream_trigger(struct snd_sof_dev *sdev,
struct hdac_ext_stream *stream, int cmd)
{
Expand Down
12 changes: 9 additions & 3 deletions sound/soc/sof/intel/hda-trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ static int hda_dsp_trace_prepare(struct snd_sof_dev *sdev)

int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *tag)
{
sdev->hda->dtrace_stream = hda_dsp_stream_get_cstream(sdev);
/* get last capture stream for dma trace, this make FW easier
* to manage dma channels just from index 0
*/
sdev->hda->dtrace_stream = hda_dsp_stream_get(sdev,
SNDRV_PCM_STREAM_CAPTURE,
TRUE);

if (!sdev->hda->dtrace_stream) {
dev_err(sdev->dev,
Expand All @@ -76,8 +81,9 @@ int hda_dsp_trace_release(struct snd_sof_dev *sdev)
if (sdev->hda->dtrace_stream) {
hstream = &sdev->hda->dtrace_stream->hstream;
hstream->opened = false;
hda_dsp_stream_put_cstream(sdev,
hstream->stream_tag);
hda_dsp_stream_put(sdev,
SNDRV_PCM_STREAM_CAPTURE,
hstream->stream_tag);
sdev->hda->dtrace_stream = NULL;
return 0;
}
Expand Down
9 changes: 2 additions & 7 deletions sound/soc/sof/intel/hda.h
Original file line number Diff line number Diff line change
Expand Up @@ -451,14 +451,9 @@ int hda_dsp_stream_setup_bdl(struct snd_sof_dev *sdev,
struct hdac_stream *stream);

struct hdac_ext_stream *
hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction);
struct hdac_ext_stream *
hda_dsp_stream_get_cstream(struct snd_sof_dev *sdev);
struct hdac_ext_stream *
hda_dsp_stream_get_pstream(struct snd_sof_dev *sdev);
hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction,
int reverse);
int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag);
int hda_dsp_stream_put_pstream(struct snd_sof_dev *sdev, int stream_tag);
int hda_dsp_stream_put_cstream(struct snd_sof_dev *sdev, int stream_tag);
int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev,
struct hdac_ext_stream *stream,
int enable, u32 size);
Expand Down