Merge series "ASoC: SOF: cleanups and improvements" from Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>:
Couple of small patches to improve error handling, inits, logs. Hope we can have this for 5.7? Guennadi Liakhovetski (2): ASoC: SOF: (cosmetic) use for_each_pcm_streams() in sof_dai_load() ASoC: SOF: fix uninitialised "work" with VirtIO Kai Vehmanen (2): ASoC: SOF: Intel: hda: do not leave clock gating off upon error ASoC: SOF: Intel: hda: call codec wake at chip init Ranjani Sridharan (1): ASoC: SOF: Intel: hda: Improve DSP state logging sound/soc/sof/intel/hda-ctrl.c | 15 +++++++++--- sound/soc/sof/intel/hda-dsp.c | 43 ++++++++++++++++++++++++++++++++-- sound/soc/sof/pcm.c | 4 +--- sound/soc/sof/sof-audio.h | 3 +++ sound/soc/sof/topology.c | 17 ++++++++++---- 5 files changed, 69 insertions(+), 13 deletions(-) -- 2.20.1
This commit is contained in:
commit
7e37c5cf55
|
@ -18,6 +18,7 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <sound/hdaudio_ext.h>
|
#include <sound/hdaudio_ext.h>
|
||||||
#include <sound/hda_register.h>
|
#include <sound/hda_register.h>
|
||||||
|
#include <sound/hda_component.h>
|
||||||
#include "../ops.h"
|
#include "../ops.h"
|
||||||
#include "hda.h"
|
#include "hda.h"
|
||||||
|
|
||||||
|
@ -176,6 +177,9 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset)
|
||||||
if (bus->chip_init)
|
if (bus->chip_init)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
|
||||||
|
snd_hdac_set_codec_wakeup(bus, true);
|
||||||
|
#endif
|
||||||
hda_dsp_ctrl_misc_clock_gating(sdev, false);
|
hda_dsp_ctrl_misc_clock_gating(sdev, false);
|
||||||
|
|
||||||
if (full_reset) {
|
if (full_reset) {
|
||||||
|
@ -183,7 +187,7 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset)
|
||||||
ret = hda_dsp_ctrl_link_reset(sdev, true);
|
ret = hda_dsp_ctrl_link_reset(sdev, true);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(sdev->dev, "error: failed to reset HDA controller\n");
|
dev_err(sdev->dev, "error: failed to reset HDA controller\n");
|
||||||
return ret;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
usleep_range(500, 1000);
|
usleep_range(500, 1000);
|
||||||
|
@ -192,7 +196,7 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset)
|
||||||
ret = hda_dsp_ctrl_link_reset(sdev, false);
|
ret = hda_dsp_ctrl_link_reset(sdev, false);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(sdev->dev, "error: failed to exit HDA controller reset\n");
|
dev_err(sdev->dev, "error: failed to exit HDA controller reset\n");
|
||||||
return ret;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
usleep_range(1000, 1200);
|
usleep_range(1000, 1200);
|
||||||
|
@ -202,7 +206,8 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset)
|
||||||
/* check to see if controller is ready */
|
/* check to see if controller is ready */
|
||||||
if (!snd_hdac_chip_readb(bus, GCTL)) {
|
if (!snd_hdac_chip_readb(bus, GCTL)) {
|
||||||
dev_dbg(bus->dev, "controller not ready!\n");
|
dev_dbg(bus->dev, "controller not ready!\n");
|
||||||
return -EBUSY;
|
ret = -EBUSY;
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Accept unsolicited responses */
|
/* Accept unsolicited responses */
|
||||||
|
@ -268,7 +273,11 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset)
|
||||||
|
|
||||||
bus->chip_init = true;
|
bus->chip_init = true;
|
||||||
|
|
||||||
|
err:
|
||||||
hda_dsp_ctrl_misc_clock_gating(sdev, true);
|
hda_dsp_ctrl_misc_clock_gating(sdev, true);
|
||||||
|
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
|
||||||
|
snd_hdac_set_codec_wakeup(bus, false);
|
||||||
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -452,6 +452,46 @@ revert:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* helper to log DSP state */
|
||||||
|
static void hda_dsp_state_log(struct snd_sof_dev *sdev)
|
||||||
|
{
|
||||||
|
switch (sdev->dsp_power_state.state) {
|
||||||
|
case SOF_DSP_PM_D0:
|
||||||
|
switch (sdev->dsp_power_state.substate) {
|
||||||
|
case SOF_HDA_DSP_PM_D0I0:
|
||||||
|
dev_dbg(sdev->dev, "Current DSP power state: D0I0\n");
|
||||||
|
break;
|
||||||
|
case SOF_HDA_DSP_PM_D0I3:
|
||||||
|
dev_dbg(sdev->dev, "Current DSP power state: D0I3\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_dbg(sdev->dev, "Unknown DSP D0 substate: %d\n",
|
||||||
|
sdev->dsp_power_state.substate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SOF_DSP_PM_D1:
|
||||||
|
dev_dbg(sdev->dev, "Current DSP power state: D1\n");
|
||||||
|
break;
|
||||||
|
case SOF_DSP_PM_D2:
|
||||||
|
dev_dbg(sdev->dev, "Current DSP power state: D2\n");
|
||||||
|
break;
|
||||||
|
case SOF_DSP_PM_D3_HOT:
|
||||||
|
dev_dbg(sdev->dev, "Current DSP power state: D3_HOT\n");
|
||||||
|
break;
|
||||||
|
case SOF_DSP_PM_D3:
|
||||||
|
dev_dbg(sdev->dev, "Current DSP power state: D3\n");
|
||||||
|
break;
|
||||||
|
case SOF_DSP_PM_D3_COLD:
|
||||||
|
dev_dbg(sdev->dev, "Current DSP power state: D3_COLD\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_dbg(sdev->dev, "Unknown DSP power state: %d\n",
|
||||||
|
sdev->dsp_power_state.state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All DSP power state transitions are initiated by the driver.
|
* All DSP power state transitions are initiated by the driver.
|
||||||
* If the requested state change fails, the error is simply returned.
|
* If the requested state change fails, the error is simply returned.
|
||||||
|
@ -511,8 +551,7 @@ set_state:
|
||||||
}
|
}
|
||||||
|
|
||||||
sdev->dsp_power_state = *target_state;
|
sdev->dsp_power_state = *target_state;
|
||||||
dev_dbg(sdev->dev, "New DSP state %d substate %d\n",
|
hda_dsp_state_log(sdev);
|
||||||
target_state->state, target_state->substate);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ static int sof_pcm_dsp_params(struct snd_sof_pcm *spcm, struct snd_pcm_substream
|
||||||
/*
|
/*
|
||||||
* sof pcm period elapse work
|
* sof pcm period elapse work
|
||||||
*/
|
*/
|
||||||
static void sof_pcm_period_elapsed_work(struct work_struct *work)
|
void snd_sof_pcm_period_elapsed_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct snd_sof_pcm_stream *sps =
|
struct snd_sof_pcm_stream *sps =
|
||||||
container_of(work, struct snd_sof_pcm_stream,
|
container_of(work, struct snd_sof_pcm_stream,
|
||||||
|
@ -475,8 +475,6 @@ static int sof_pcm_open(struct snd_soc_component *component,
|
||||||
dev_dbg(component->dev, "pcm: open stream %d dir %d\n",
|
dev_dbg(component->dev, "pcm: open stream %d dir %d\n",
|
||||||
spcm->pcm.pcm_id, substream->stream);
|
spcm->pcm.pcm_id, substream->stream);
|
||||||
|
|
||||||
INIT_WORK(&spcm->stream[substream->stream].period_elapsed_work,
|
|
||||||
sof_pcm_period_elapsed_work);
|
|
||||||
|
|
||||||
caps = &spcm->pcm.caps[substream->stream];
|
caps = &spcm->pcm.caps[substream->stream];
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#ifndef __SOUND_SOC_SOF_AUDIO_H
|
#ifndef __SOUND_SOC_SOF_AUDIO_H
|
||||||
#define __SOUND_SOC_SOF_AUDIO_H
|
#define __SOUND_SOC_SOF_AUDIO_H
|
||||||
|
|
||||||
|
#include <linux/workqueue.h>
|
||||||
|
|
||||||
#include <sound/soc.h>
|
#include <sound/soc.h>
|
||||||
#include <sound/control.h>
|
#include <sound/control.h>
|
||||||
#include <sound/sof/stream.h> /* needs to be included before control.h */
|
#include <sound/sof/stream.h> /* needs to be included before control.h */
|
||||||
|
@ -189,6 +191,7 @@ struct snd_sof_pcm *snd_sof_find_spcm_comp(struct snd_soc_component *scomp,
|
||||||
struct snd_sof_pcm *snd_sof_find_spcm_pcm_id(struct snd_soc_component *scomp,
|
struct snd_sof_pcm *snd_sof_find_spcm_pcm_id(struct snd_soc_component *scomp,
|
||||||
unsigned int pcm_id);
|
unsigned int pcm_id);
|
||||||
void snd_sof_pcm_period_elapsed(struct snd_pcm_substream *substream);
|
void snd_sof_pcm_period_elapsed(struct snd_pcm_substream *substream);
|
||||||
|
void snd_sof_pcm_period_elapsed_work(struct work_struct *work);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mixer IPC
|
* Mixer IPC
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
|
#include <linux/workqueue.h>
|
||||||
#include <sound/tlv.h>
|
#include <sound/tlv.h>
|
||||||
#include <sound/pcm_params.h>
|
#include <sound/pcm_params.h>
|
||||||
#include <uapi/sound/sof/tokens.h>
|
#include <uapi/sound/sof/tokens.h>
|
||||||
|
@ -2448,7 +2449,7 @@ static int sof_dai_load(struct snd_soc_component *scomp, int index,
|
||||||
struct snd_soc_tplg_stream_caps *caps;
|
struct snd_soc_tplg_stream_caps *caps;
|
||||||
struct snd_soc_tplg_private *private = &pcm->priv;
|
struct snd_soc_tplg_private *private = &pcm->priv;
|
||||||
struct snd_sof_pcm *spcm;
|
struct snd_sof_pcm *spcm;
|
||||||
int stream = SNDRV_PCM_STREAM_PLAYBACK;
|
int stream;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* nothing to do for BEs atm */
|
/* nothing to do for BEs atm */
|
||||||
|
@ -2460,8 +2461,12 @@ static int sof_dai_load(struct snd_soc_component *scomp, int index,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
spcm->scomp = scomp;
|
spcm->scomp = scomp;
|
||||||
spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].comp_id = COMP_ID_UNASSIGNED;
|
|
||||||
spcm->stream[SNDRV_PCM_STREAM_CAPTURE].comp_id = COMP_ID_UNASSIGNED;
|
for_each_pcm_streams(stream) {
|
||||||
|
spcm->stream[stream].comp_id = COMP_ID_UNASSIGNED;
|
||||||
|
INIT_WORK(&spcm->stream[stream].period_elapsed_work,
|
||||||
|
snd_sof_pcm_period_elapsed_work);
|
||||||
|
}
|
||||||
|
|
||||||
spcm->pcm = *pcm;
|
spcm->pcm = *pcm;
|
||||||
dev_dbg(scomp->dev, "tplg: load pcm %s\n", pcm->dai_name);
|
dev_dbg(scomp->dev, "tplg: load pcm %s\n", pcm->dai_name);
|
||||||
|
@ -2482,8 +2487,10 @@ static int sof_dai_load(struct snd_soc_component *scomp, int index,
|
||||||
if (!spcm->pcm.playback)
|
if (!spcm->pcm.playback)
|
||||||
goto capture;
|
goto capture;
|
||||||
|
|
||||||
|
stream = SNDRV_PCM_STREAM_PLAYBACK;
|
||||||
|
|
||||||
dev_vdbg(scomp->dev, "tplg: pcm %s stream tokens: playback d0i3:%d\n",
|
dev_vdbg(scomp->dev, "tplg: pcm %s stream tokens: playback d0i3:%d\n",
|
||||||
spcm->pcm.pcm_name, spcm->stream[0].d0i3_compatible);
|
spcm->pcm.pcm_name, spcm->stream[stream].d0i3_compatible);
|
||||||
|
|
||||||
caps = &spcm->pcm.caps[stream];
|
caps = &spcm->pcm.caps[stream];
|
||||||
|
|
||||||
|
@ -2513,7 +2520,7 @@ capture:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
dev_vdbg(scomp->dev, "tplg: pcm %s stream tokens: capture d0i3:%d\n",
|
dev_vdbg(scomp->dev, "tplg: pcm %s stream tokens: capture d0i3:%d\n",
|
||||||
spcm->pcm.pcm_name, spcm->stream[1].d0i3_compatible);
|
spcm->pcm.pcm_name, spcm->stream[stream].d0i3_compatible);
|
||||||
|
|
||||||
caps = &spcm->pcm.caps[stream];
|
caps = &spcm->pcm.caps[stream];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue