All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] Allow ADSPs to be preloaded with firmware
@ 2016-09-20 12:52 Charles Keepax
  2016-09-20 12:52 ` [PATCH 1/7] ASoC: arizona: Attach SYSCLK to DSP preloaders Charles Keepax
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: Charles Keepax @ 2016-09-20 12:52 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lgirdwood

As requirements to bring up audio paths are continuous getting tighter and
the DSP download to most ADSP devices happens over an external bus it can
become an important factor in the path bring up time. As such sometimes it
is a reasonable trade off to download the firmware ahead of when it will
be required and take a small hit on power consumption for keeping the core
powered up.

This patch chain adds such functionality to the wm_adsp driver, broadly
speaking there are three parts to the chain. Firstly we setup the existing
preloader widgets such that they will be easier to power up independently.
Secondly, we setup the ALSA controls such that they will gracefully handle
the DSP being in a low power state between loading the firmware and
starting the core. Finally, we actually add the preloading features itself.

Thanks,
Charles

Charles Keepax (7):
  ASoC: arizona: Attach SYSCLK to DSP preloaders
  ASoC: wm_adsp: Make DSP preloader a supply widget
  ASoC: wm_adsp: Separate concept of booted and running
  ASoC: wm_adsp: Move control cache sync out of preloader
  ASoC: wm_adsp: Put DSP into low power state between loading and
    running
  ASoC: wm_adsp: Allow preloader to do the final shutdown of the DSP
  ASoC: wm_adsp: Add mechanism to preload firmware on a core

 sound/soc/codecs/arizona.h |  18 ++++---
 sound/soc/codecs/cs47l24.c |   5 +-
 sound/soc/codecs/wm5102.c  |   3 +-
 sound/soc/codecs/wm5110.c  |   7 ++-
 sound/soc/codecs/wm_adsp.c | 126 ++++++++++++++++++++++++++++++++++++---------
 sound/soc/codecs/wm_adsp.h |  18 ++++++-
 6 files changed, 138 insertions(+), 39 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/7] ASoC: arizona: Attach SYSCLK to DSP preloaders
  2016-09-20 12:52 [PATCH 0/7] Allow ADSPs to be preloaded with firmware Charles Keepax
@ 2016-09-20 12:52 ` Charles Keepax
  2016-09-25  5:58   ` Applied "ASoC: arizona: Attach SYSCLK to DSP preloaders" to the asoc tree Mark Brown
  2016-09-20 12:52 ` [PATCH 2/7] ASoC: wm_adsp: Make DSP preloader a supply widget Charles Keepax
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Charles Keepax @ 2016-09-20 12:52 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lgirdwood

Currently SYSCLK is attached to every compressed DAI as this follows the
pattern of attaching clocks to the chips inputs and outputs, however, it is
really the DSP that requires the clock here. As firmware download can be a
significant part of the path startup time for these devices occasionally it
would be desirable to download the firmware in advance of the path being
brought up.

To help facilitate this early firmware loading this patch attaches the
SYSCLK to the DSP preloader widget. This also saves us adding a new route
to SYSCLK every time a new compressed DAI is created.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/arizona.h | 1 +
 sound/soc/codecs/cs47l24.c | 2 --
 sound/soc/codecs/wm5102.c  | 1 -
 sound/soc/codecs/wm5110.c  | 2 --
 4 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 1728771..c3daa07 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -190,6 +190,7 @@ extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
 
 #define ARIZONA_DSP_ROUTES(name) \
 	{ name, NULL, name " Preloader"}, \
+	{ name " Preloader", NULL, "SYSCLK" }, \
 	{ name " Preloader", NULL, name " Aux 1" }, \
 	{ name " Preloader", NULL, name " Aux 2" }, \
 	{ name " Preloader", NULL, name " Aux 3" }, \
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c
index 5e8f979..7df6a67 100644
--- a/sound/soc/codecs/cs47l24.c
+++ b/sound/soc/codecs/cs47l24.c
@@ -816,7 +816,6 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = {
 	{ "AIF3 Capture", NULL, "SYSCLK" },
 
 	{ "Voice Control DSP", NULL, "DSP3" },
-	{ "Voice Control DSP", NULL, "SYSCLK" },
 
 	{ "IN1L PGA", NULL, "IN1L" },
 	{ "IN1R PGA", NULL, "IN1R" },
@@ -825,7 +824,6 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = {
 	{ "IN2R PGA", NULL, "IN2R" },
 
 	{ "Audio Trace DSP", NULL, "DSP2" },
-	{ "Audio Trace DSP", NULL, "SYSCLK" },
 
 	ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
 	ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index a891344..bb3de5b 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -1615,7 +1615,6 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
 	{ "Slim3 Capture", NULL, "SYSCLK" },
 
 	{ "Audio Trace DSP", NULL, "DSP1" },
-	{ "Audio Trace DSP", NULL, "SYSCLK" },
 
 	{ "IN1L PGA", NULL, "IN1L" },
 	{ "IN1R PGA", NULL, "IN1R" },
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index a4331ad..407dc4a 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -1846,10 +1846,8 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
 	{ "Slim3 Capture", NULL, "SYSCLK" },
 
 	{ "Voice Control DSP", NULL, "DSP3" },
-	{ "Voice Control DSP", NULL, "SYSCLK" },
 
 	{ "Audio Trace DSP", NULL, "DSP1" },
-	{ "Audio Trace DSP", NULL, "SYSCLK" },
 
 	{ "IN1L PGA", NULL, "IN1L" },
 	{ "IN1R PGA", NULL, "IN1R" },
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/7] ASoC: wm_adsp: Make DSP preloader a supply widget
  2016-09-20 12:52 [PATCH 0/7] Allow ADSPs to be preloaded with firmware Charles Keepax
  2016-09-20 12:52 ` [PATCH 1/7] ASoC: arizona: Attach SYSCLK to DSP preloaders Charles Keepax
@ 2016-09-20 12:52 ` Charles Keepax
  2016-09-25  5:58   ` Applied "ASoC: wm_adsp: Make DSP preloader a supply widget" to the asoc tree Mark Brown
  2016-09-20 12:52 ` [PATCH 3/7] ASoC: wm_adsp: Separate concept of booted and running Charles Keepax
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Charles Keepax @ 2016-09-20 12:52 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lgirdwood

Currently the DSP loading is split into two widgets, the preloader that
is a snd_soc_dapm_dai_link widget which starts a thread to download
the firmware, and the DSP itself which is a snd_soc_dapm_out_drv and
synchronises the thread back in to the DAPM sequence. This allows the
firmware download to be overlapped with the rest of the path bring up.

The use of a snd_soc_dapm_dai_link widget requires the preloader to be part
of the audio path in DAPM, really a supply widget is a better fit for the
preloader. The preloader is something that needs to be done for the DSP to
function, not a part of the audio path itself.

This change makes the DSP preloader widget a supply widget, which as well
as probably being a better fit will also make it much simpler to power up
the preloader widget to trigger firmware download to the core independently
of the audio path coming up.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/arizona.h | 16 ++++++++--------
 sound/soc/codecs/wm_adsp.h |  5 +++--
 2 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index c3daa07..9d0997b 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -191,20 +191,20 @@ extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
 #define ARIZONA_DSP_ROUTES(name) \
 	{ name, NULL, name " Preloader"}, \
 	{ name " Preloader", NULL, "SYSCLK" }, \
-	{ name " Preloader", NULL, name " Aux 1" }, \
-	{ name " Preloader", NULL, name " Aux 2" }, \
-	{ name " Preloader", NULL, name " Aux 3" }, \
-	{ name " Preloader", NULL, name " Aux 4" }, \
-	{ name " Preloader", NULL, name " Aux 5" }, \
-	{ name " Preloader", NULL, name " Aux 6" }, \
+	{ name, NULL, name " Aux 1" }, \
+	{ name, NULL, name " Aux 2" }, \
+	{ name, NULL, name " Aux 3" }, \
+	{ name, NULL, name " Aux 4" }, \
+	{ name, NULL, name " Aux 5" }, \
+	{ name, NULL, name " Aux 6" }, \
 	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \
 	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \
 	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \
 	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \
 	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \
 	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \
-	ARIZONA_MIXER_ROUTES(name " Preloader", name "L"), \
-	ARIZONA_MIXER_ROUTES(name " Preloader", name "R")
+	ARIZONA_MIXER_ROUTES(name, name "L"), \
+	ARIZONA_MIXER_ROUTES(name, name "R")
 
 #define ARIZONA_EQ_CONTROL(xname, xbase)                      \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,   \
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index be3b5bc..a3b1b7e 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -85,9 +85,10 @@ struct wm_adsp {
 		wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
 
 #define WM_ADSP2(wname, num, event_fn) \
-{	.id = snd_soc_dapm_dai_link, .name = wname " Preloader", \
+{	.id = snd_soc_dapm_supply, .name = wname " Preloader", \
 	.reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \
-	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }, \
+	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \
+	.subseq = 100, /* Ensure we run after SYSCLK supply widget */ }, \
 {	.id = snd_soc_dapm_out_drv, .name = wname, \
 	.reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \
 	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/7] ASoC: wm_adsp: Separate concept of booted and running
  2016-09-20 12:52 [PATCH 0/7] Allow ADSPs to be preloaded with firmware Charles Keepax
  2016-09-20 12:52 ` [PATCH 1/7] ASoC: arizona: Attach SYSCLK to DSP preloaders Charles Keepax
  2016-09-20 12:52 ` [PATCH 2/7] ASoC: wm_adsp: Make DSP preloader a supply widget Charles Keepax
@ 2016-09-20 12:52 ` Charles Keepax
  2016-09-25  5:58   ` Applied "ASoC: wm_adsp: Separate concept of booted and running" to the asoc tree Mark Brown
  2016-09-20 12:52 ` [PATCH 4/7] ASoC: wm_adsp: Move control cache sync out of preloader Charles Keepax
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Charles Keepax @ 2016-09-20 12:52 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lgirdwood

Currently the wm_adsp driver has a flag that indicates the DSP is
"running", this flag is used to gate access to the hardware.  However this
flag is actually set in the firmware download thread after the firmware has
been downloaded, but this is before the core is actually started running,
so really it currently indicates that the core has been booted and is
perhaps running.

This patch clearly separates out the concepts of booted (firmware is
downloaded) and running (code is executing on the DSP) within the wm_adsp
driver.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/wm_adsp.c | 36 +++++++++++++++++++++++++-----------
 sound/soc/codecs/wm_adsp.h |  2 ++
 2 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 21fbe7d..ae2f2b6 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -480,7 +480,7 @@ static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file,
 
 	mutex_lock(&dsp->pwr_lock);
 
-	if (!dsp->wmfw_file_name || !dsp->running)
+	if (!dsp->wmfw_file_name || !dsp->booted)
 		ret = 0;
 	else
 		ret = simple_read_from_buffer(user_buf, count, ppos,
@@ -500,7 +500,7 @@ static ssize_t wm_adsp_debugfs_bin_read(struct file *file,
 
 	mutex_lock(&dsp->pwr_lock);
 
-	if (!dsp->bin_file_name || !dsp->running)
+	if (!dsp->bin_file_name || !dsp->booted)
 		ret = 0;
 	else
 		ret = simple_read_from_buffer(user_buf, count, ppos,
@@ -554,6 +554,9 @@ static void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
 	if (!root)
 		goto err;
 
+	if (!debugfs_create_bool("booted", S_IRUGO, root, &dsp->booted))
+		goto err;
+
 	if (!debugfs_create_bool("running", S_IRUGO, root, &dsp->running))
 		goto err;
 
@@ -637,7 +640,7 @@ static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
 
 	mutex_lock(&dsp[e->shift_l].pwr_lock);
 
-	if (dsp[e->shift_l].running || dsp[e->shift_l].compr)
+	if (dsp[e->shift_l].booted || dsp[e->shift_l].compr)
 		ret = -EBUSY;
 	else
 		dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0];
@@ -789,7 +792,7 @@ static int wm_coeff_put(struct snd_kcontrol *kctl,
 	memcpy(ctl->cache, p, ctl->len);
 
 	ctl->set = 1;
-	if (ctl->enabled)
+	if (ctl->enabled && ctl->dsp->booted)
 		ret = wm_coeff_write_control(ctl, p, ctl->len);
 
 	mutex_unlock(&ctl->dsp->pwr_lock);
@@ -811,7 +814,7 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl,
 		ret = -EFAULT;
 	} else {
 		ctl->set = 1;
-		if (ctl->enabled)
+		if (ctl->enabled && ctl->dsp->booted)
 			ret = wm_coeff_write_control(ctl, ctl->cache, size);
 	}
 
@@ -871,12 +874,12 @@ static int wm_coeff_get(struct snd_kcontrol *kctl,
 	mutex_lock(&ctl->dsp->pwr_lock);
 
 	if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
-		if (ctl->enabled)
+		if (ctl->enabled && ctl->dsp->booted)
 			ret = wm_coeff_read_control(ctl, p, ctl->len);
 		else
 			ret = -EPERM;
 	} else {
-		if (!ctl->flags && ctl->enabled)
+		if (!ctl->flags && ctl->enabled && ctl->dsp->booted)
 			ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len);
 
 		memcpy(p, ctl->cache, ctl->len);
@@ -898,12 +901,12 @@ static int wm_coeff_tlv_get(struct snd_kcontrol *kctl,
 	mutex_lock(&ctl->dsp->pwr_lock);
 
 	if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
-		if (ctl->enabled)
+		if (ctl->enabled && ctl->dsp->booted)
 			ret = wm_coeff_read_control(ctl, ctl->cache, size);
 		else
 			ret = -EPERM;
 	} else {
-		if (!ctl->flags && ctl->enabled)
+		if (!ctl->flags && ctl->enabled && ctl->dsp->booted)
 			ret = wm_coeff_read_control(ctl, ctl->cache, size);
 	}
 
@@ -2166,13 +2169,20 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
 		if (ret != 0)
 			goto err_ena;
 
+		dsp->booted = true;
+
 		/* Start the core running */
 		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
 				   ADSP1_CORE_ENA | ADSP1_START,
 				   ADSP1_CORE_ENA | ADSP1_START);
+
+		dsp->running = true;
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
+		dsp->running = false;
+		dsp->booted = false;
+
 		/* Halt the core */
 		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
 				   ADSP1_CORE_ENA | ADSP1_START, 0);
@@ -2275,7 +2285,7 @@ static void wm_adsp2_boot_work(struct work_struct *work)
 	if (ret != 0)
 		goto err_ena;
 
-	dsp->running = true;
+	dsp->booted = true;
 
 	mutex_unlock(&dsp->pwr_lock);
 
@@ -2336,7 +2346,7 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
 	case SND_SOC_DAPM_POST_PMU:
 		flush_work(&dsp->boot_work);
 
-		if (!dsp->running)
+		if (!dsp->booted)
 			return -EIO;
 
 		ret = regmap_update_bits(dsp->regmap,
@@ -2346,6 +2356,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
 		if (ret != 0)
 			goto err;
 
+		dsp->running = true;
+
 		mutex_lock(&dsp->pwr_lock);
 
 		if (wm_adsp_fw[dsp->fw].num_caps != 0)
@@ -2365,7 +2377,9 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
 
 		dsp->fw_id = 0;
 		dsp->fw_id_version = 0;
+
 		dsp->running = false;
+		dsp->booted = false;
 
 		regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
 				   ADSP2_CORE_ENA | ADSP2_START, 0);
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index a3b1b7e..228b1f9 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -61,6 +61,8 @@ struct wm_adsp {
 
 	int fw;
 	int fw_ver;
+
+	bool booted;
 	bool running;
 
 	struct list_head ctl_list;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/7] ASoC: wm_adsp: Move control cache sync out of preloader
  2016-09-20 12:52 [PATCH 0/7] Allow ADSPs to be preloaded with firmware Charles Keepax
                   ` (2 preceding siblings ...)
  2016-09-20 12:52 ` [PATCH 3/7] ASoC: wm_adsp: Separate concept of booted and running Charles Keepax
@ 2016-09-20 12:52 ` Charles Keepax
  2016-09-25  5:58   ` Applied "ASoC: wm_adsp: Move control cache sync out of preloader" to the asoc tree Mark Brown
  2016-09-20 12:52 ` [PATCH 5/7] ASoC: wm_adsp: Put DSP into low power state between loading and running Charles Keepax
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Charles Keepax @ 2016-09-20 12:52 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lgirdwood

As part of the work to download firmware before the audio path is brought
up the DSP will be put into a low power state between downloading firmware
to the core and starting it running. This will mean that the firmware ALSA
controls are not accessible in the hardware during this period of time.

To prepare for this change we gate access to the hardware in the ALSA
control handlers on the DSP being running rather than simply booted and
move the synchronisation of the control caches out of the preloader delayed
work and into the main DAPM thread after the DSP will have been brought out
of its low power state.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/wm_adsp.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index ae2f2b6..24485ec 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -792,7 +792,7 @@ static int wm_coeff_put(struct snd_kcontrol *kctl,
 	memcpy(ctl->cache, p, ctl->len);
 
 	ctl->set = 1;
-	if (ctl->enabled && ctl->dsp->booted)
+	if (ctl->enabled && ctl->dsp->running)
 		ret = wm_coeff_write_control(ctl, p, ctl->len);
 
 	mutex_unlock(&ctl->dsp->pwr_lock);
@@ -814,7 +814,7 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl,
 		ret = -EFAULT;
 	} else {
 		ctl->set = 1;
-		if (ctl->enabled && ctl->dsp->booted)
+		if (ctl->enabled && ctl->dsp->running)
 			ret = wm_coeff_write_control(ctl, ctl->cache, size);
 	}
 
@@ -874,12 +874,12 @@ static int wm_coeff_get(struct snd_kcontrol *kctl,
 	mutex_lock(&ctl->dsp->pwr_lock);
 
 	if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
-		if (ctl->enabled && ctl->dsp->booted)
+		if (ctl->enabled && ctl->dsp->running)
 			ret = wm_coeff_read_control(ctl, p, ctl->len);
 		else
 			ret = -EPERM;
 	} else {
-		if (!ctl->flags && ctl->enabled && ctl->dsp->booted)
+		if (!ctl->flags && ctl->enabled && ctl->dsp->running)
 			ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len);
 
 		memcpy(p, ctl->cache, ctl->len);
@@ -901,12 +901,12 @@ static int wm_coeff_tlv_get(struct snd_kcontrol *kctl,
 	mutex_lock(&ctl->dsp->pwr_lock);
 
 	if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
-		if (ctl->enabled && ctl->dsp->booted)
+		if (ctl->enabled && ctl->dsp->running)
 			ret = wm_coeff_read_control(ctl, ctl->cache, size);
 		else
 			ret = -EPERM;
 	} else {
-		if (!ctl->flags && ctl->enabled && ctl->dsp->booted)
+		if (!ctl->flags && ctl->enabled && ctl->dsp->running)
 			ret = wm_coeff_read_control(ctl, ctl->cache, size);
 	}
 
@@ -2280,11 +2280,6 @@ static void wm_adsp2_boot_work(struct work_struct *work)
 	if (ret != 0)
 		goto err_ena;
 
-	/* Sync set controls */
-	ret = wm_coeff_sync_controls(dsp);
-	if (ret != 0)
-		goto err_ena;
-
 	dsp->booted = true;
 
 	mutex_unlock(&dsp->pwr_lock);
@@ -2349,6 +2344,11 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
 		if (!dsp->booted)
 			return -EIO;
 
+		/* Sync set controls */
+		ret = wm_coeff_sync_controls(dsp);
+		if (ret != 0)
+			goto err;
+
 		ret = regmap_update_bits(dsp->regmap,
 					 dsp->base + ADSP2_CONTROL,
 					 ADSP2_CORE_ENA | ADSP2_START,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 5/7] ASoC: wm_adsp: Put DSP into low power state between loading and running
  2016-09-20 12:52 [PATCH 0/7] Allow ADSPs to be preloaded with firmware Charles Keepax
                   ` (3 preceding siblings ...)
  2016-09-20 12:52 ` [PATCH 4/7] ASoC: wm_adsp: Move control cache sync out of preloader Charles Keepax
@ 2016-09-20 12:52 ` Charles Keepax
  2016-09-21 16:14   ` Charles Keepax
  2016-09-20 12:52 ` [PATCH 6/7] ASoC: wm_adsp: Allow preloader to do the final shutdown of the DSP Charles Keepax
  2016-09-20 12:52 ` [PATCH 7/7] ASoC: wm_adsp: Add mechanism to preload firmware on a core Charles Keepax
  6 siblings, 1 reply; 13+ messages in thread
From: Charles Keepax @ 2016-09-20 12:52 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lgirdwood

Between when we load the DSP and when it actually starts running put the
core into a lower power state where the memory is retained but nothing
is clocked.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/wm_adsp.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 24485ec..e0cd4fe 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -2223,6 +2223,11 @@ static int wm_adsp2_ena(struct wm_adsp *dsp)
 	unsigned int val;
 	int ret, count;
 
+	ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
+				 ADSP2_MEM_ENA, ADSP2_MEM_ENA);
+	if (ret != 0)
+		return ret;
+
 	ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL,
 				       ADSP2_SYS_ENA, ADSP2_SYS_ENA);
 	if (ret != 0)
@@ -2282,6 +2287,12 @@ static void wm_adsp2_boot_work(struct work_struct *work)
 
 	dsp->booted = true;
 
+	/* Turn DSP back off until we are ready to run */
+	ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
+				 ADSP2_SYS_ENA, 0);
+	if (ret != 0)
+		goto err_ena;
+
 	mutex_unlock(&dsp->pwr_lock);
 
 	return;
@@ -2344,6 +2355,11 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
 		if (!dsp->booted)
 			return -EIO;
 
+		ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
+					 ADSP2_SYS_ENA, ADSP2_SYS_ENA);
+		if (ret != 0)
+			goto err;
+
 		/* Sync set controls */
 		ret = wm_coeff_sync_controls(dsp);
 		if (ret != 0)
@@ -2382,7 +2398,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
 		dsp->booted = false;
 
 		regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
-				   ADSP2_CORE_ENA | ADSP2_START, 0);
+				   ADSP2_MEM_ENA | ADSP2_CORE_ENA | ADSP2_START,
+				   0);
 
 		/* Make sure DMAs are quiesced */
 		regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 6/7] ASoC: wm_adsp: Allow preloader to do the final shutdown of the DSP
  2016-09-20 12:52 [PATCH 0/7] Allow ADSPs to be preloaded with firmware Charles Keepax
                   ` (4 preceding siblings ...)
  2016-09-20 12:52 ` [PATCH 5/7] ASoC: wm_adsp: Put DSP into low power state between loading and running Charles Keepax
@ 2016-09-20 12:52 ` Charles Keepax
  2016-09-20 12:52 ` [PATCH 7/7] ASoC: wm_adsp: Add mechanism to preload firmware on a core Charles Keepax
  6 siblings, 0 replies; 13+ messages in thread
From: Charles Keepax @ 2016-09-20 12:52 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lgirdwood

The booting process for the DSP is clearly separated into two parts, the
preloader brings up the core and downloads code, then the main widget
starts the code actually executing. However the shutdown sequence is all
handled with the main widget.

To allow the preloading to be run independently of the main audio bring
up it makes sense, and is generally just cleaner, for the preloader
widget to shutdown those things it initialised. This patch moves the
appropriate parts of the shutdown process into the preloader widget.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/wm_adsp.c | 32 ++++++++++++++++++--------------
 sound/soc/codecs/wm_adsp.h |  2 +-
 2 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index e0cd4fe..41c179d 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -2323,6 +2323,7 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
 	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
 	struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
 	struct wm_adsp *dsp = &dsps[w->shift];
+	struct wm_coeff_ctl *ctl;
 
 	dsp->card = codec->component.card;
 
@@ -2331,6 +2332,22 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
 		wm_adsp2_set_dspclk(dsp, freq);
 		queue_work(system_unbound_wq, &dsp->boot_work);
 		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		wm_adsp_debugfs_clear(dsp);
+
+		dsp->fw_id = 0;
+		dsp->fw_id_version = 0;
+
+		dsp->booted = false;
+
+		regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
+				   ADSP2_MEM_ENA, 0);
+
+		list_for_each_entry(ctl, &dsp->ctl_list, list)
+			ctl->enabled = 0;
+
+		wm_adsp_free_alg_regions(dsp);
+		break;
 	default:
 		break;
 	}
@@ -2345,7 +2362,6 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
 	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
 	struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
 	struct wm_adsp *dsp = &dsps[w->shift];
-	struct wm_coeff_ctl *ctl;
 	int ret;
 
 	switch (event) {
@@ -2389,17 +2405,10 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
 
 		mutex_lock(&dsp->pwr_lock);
 
-		wm_adsp_debugfs_clear(dsp);
-
-		dsp->fw_id = 0;
-		dsp->fw_id_version = 0;
-
 		dsp->running = false;
-		dsp->booted = false;
 
 		regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
-				   ADSP2_MEM_ENA | ADSP2_CORE_ENA | ADSP2_START,
-				   0);
+				   ADSP2_CORE_ENA | ADSP2_START, 0);
 
 		/* Make sure DMAs are quiesced */
 		regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0);
@@ -2409,11 +2418,6 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
 		regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
 				   ADSP2_SYS_ENA, 0);
 
-		list_for_each_entry(ctl, &dsp->ctl_list, list)
-			ctl->enabled = 0;
-
-		wm_adsp_free_alg_regions(dsp);
-
 		if (wm_adsp_fw[dsp->fw].num_caps != 0)
 			wm_adsp_buffer_free(dsp);
 
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 228b1f9..362dd7c 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -89,7 +89,7 @@ struct wm_adsp {
 #define WM_ADSP2(wname, num, event_fn) \
 {	.id = snd_soc_dapm_supply, .name = wname " Preloader", \
 	.reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \
-	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \
+	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD, \
 	.subseq = 100, /* Ensure we run after SYSCLK supply widget */ }, \
 {	.id = snd_soc_dapm_out_drv, .name = wname, \
 	.reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 7/7] ASoC: wm_adsp: Add mechanism to preload firmware on a core
  2016-09-20 12:52 [PATCH 0/7] Allow ADSPs to be preloaded with firmware Charles Keepax
                   ` (5 preceding siblings ...)
  2016-09-20 12:52 ` [PATCH 6/7] ASoC: wm_adsp: Allow preloader to do the final shutdown of the DSP Charles Keepax
@ 2016-09-20 12:52 ` Charles Keepax
  6 siblings, 0 replies; 13+ messages in thread
From: Charles Keepax @ 2016-09-20 12:52 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lgirdwood

As requirements to bring up audio paths are continuous getting tighter
and the DSP download to most ADSP devices happens over an external bus
it can become an important factor in the path bring up time. As such
sometimes it is a reasonable trade off to download the firmware ahead of
when it will be required and take a small hit on power consumption for
keeping the core powered up.

This "preloading" adds an additional control for each DSP core "DSPx
Preload Switch" that when set to true will power up the DSP core and
download the firmware currently selected in the "DSPx Firmware" control.
Whilst the core is preloaded the current firmware can not be changed and
the CODEC will be kept powered up and SYSCLK held on. Although future
improvements may allow the SYSCLK to be powered down as well because
the hardware only requires SYSCLK whilst the download is actually taking
place, but this is not covered in this series.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/arizona.h |  1 +
 sound/soc/codecs/cs47l24.c |  3 +++
 sound/soc/codecs/wm5102.c  |  2 ++
 sound/soc/codecs/wm5110.c  |  5 +++++
 sound/soc/codecs/wm_adsp.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/wm_adsp.h | 11 +++++++++++
 6 files changed, 65 insertions(+)

diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 9d0997b..8ea3657 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -191,6 +191,7 @@ extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
 #define ARIZONA_DSP_ROUTES(name) \
 	{ name, NULL, name " Preloader"}, \
 	{ name " Preloader", NULL, "SYSCLK" }, \
+	{ name " Preload", NULL, name " Preloader"}, \
 	{ name, NULL, name " Aux 1" }, \
 	{ name, NULL, name " Aux 2" }, \
 	{ name, NULL, name " Aux 3" }, \
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c
index 7df6a67..f321ea8 100644
--- a/sound/soc/codecs/cs47l24.c
+++ b/sound/soc/codecs/cs47l24.c
@@ -173,6 +173,9 @@ SOC_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]),
 SOC_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]),
 SOC_ENUM("ASRC RATE 1", arizona_asrc_rate1),
 
+WM_ADSP2_PRELOAD_SWITCH("DSP2", 2),
+WM_ADSP2_PRELOAD_SWITCH("DSP3", 3),
+
 ARIZONA_MIXER_CONTROLS("DSP2L", ARIZONA_DSP2LMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("DSP2R", ARIZONA_DSP2RMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("DSP3L", ARIZONA_DSP3LMIX_INPUT_1_SOURCE),
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index bb3de5b..07b6058 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -855,6 +855,8 @@ ARIZONA_LHPF_CONTROL("LHPF2 Coefficients", ARIZONA_HPLPF2_2),
 ARIZONA_LHPF_CONTROL("LHPF3 Coefficients", ARIZONA_HPLPF3_2),
 ARIZONA_LHPF_CONTROL("LHPF4 Coefficients", ARIZONA_HPLPF4_2),
 
+WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
+
 ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE),
 
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 407dc4a..0fee2d9 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -778,6 +778,11 @@ SOC_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]),
 SOC_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]),
 SOC_ENUM("ASRC RATE 1", arizona_asrc_rate1),
 
+WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
+WM_ADSP2_PRELOAD_SWITCH("DSP2", 2),
+WM_ADSP2_PRELOAD_SWITCH("DSP3", 3),
+WM_ADSP2_PRELOAD_SWITCH("DSP4", 4),
+
 ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("DSP2L", ARIZONA_DSP2LMIX_INPUT_1_SOURCE),
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 41c179d..e942b07 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -2316,6 +2316,43 @@ static void wm_adsp2_set_dspclk(struct wm_adsp *dsp, unsigned int freq)
 		adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
 }
 
+int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
+
+	ucontrol->value.integer.value[0] = dsp->preloaded;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(wm_adsp2_preloader_get);
+
+int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+	struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	struct soc_mixer_control *mc =
+		(struct soc_mixer_control *)kcontrol->private_value;
+	char preload[32];
+
+	snprintf(preload, ARRAY_SIZE(preload), "DSP%d Preload", mc->shift);
+
+	dsp->preloaded = ucontrol->value.integer.value[0];
+
+	if (ucontrol->value.integer.value[0])
+		snd_soc_dapm_force_enable_pin(dapm, preload);
+	else
+		snd_soc_dapm_disable_pin(dapm, preload);
+
+	snd_soc_dapm_sync(dapm);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put);
+
 int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol, int event,
 			 unsigned int freq)
@@ -2440,6 +2477,12 @@ EXPORT_SYMBOL_GPL(wm_adsp2_event);
 
 int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec)
 {
+	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+	char preload[32];
+
+	snprintf(preload, ARRAY_SIZE(preload), "DSP%d Preload", dsp->num);
+	snd_soc_dapm_disable_pin(dapm, preload);
+
 	wm_adsp2_init_debugfs(dsp, codec);
 
 	return snd_soc_add_codec_controls(codec,
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 362dd7c..74f117b 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -62,6 +62,7 @@ struct wm_adsp {
 	int fw;
 	int fw_ver;
 
+	bool preloaded;
 	bool booted;
 	bool running;
 
@@ -86,7 +87,12 @@ struct wm_adsp {
 	SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \
 		wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
 
+#define WM_ADSP2_PRELOAD_SWITCH(wname, num) \
+	SOC_SINGLE_EXT(wname " Preload Switch", SND_SOC_NOPM, num, 1, 0, \
+		wm_adsp2_preloader_get, wm_adsp2_preloader_put)
+
 #define WM_ADSP2(wname, num, event_fn) \
+	SND_SOC_DAPM_SPK(wname " Preload", NULL), \
 {	.id = snd_soc_dapm_supply, .name = wname " Preloader", \
 	.reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \
 	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD, \
@@ -110,6 +116,11 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
 int wm_adsp2_event(struct snd_soc_dapm_widget *w,
 		   struct snd_kcontrol *kcontrol, int event);
 
+int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol);
+int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol);
+
 extern int wm_adsp_compr_open(struct wm_adsp *dsp,
 			      struct snd_compr_stream *stream);
 extern int wm_adsp_compr_free(struct snd_compr_stream *stream);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 5/7] ASoC: wm_adsp: Put DSP into low power state between loading and running
  2016-09-20 12:52 ` [PATCH 5/7] ASoC: wm_adsp: Put DSP into low power state between loading and running Charles Keepax
@ 2016-09-21 16:14   ` Charles Keepax
  0 siblings, 0 replies; 13+ messages in thread
From: Charles Keepax @ 2016-09-21 16:14 UTC (permalink / raw)
  To: broonie; +Cc: alsa-devel, patches, lgirdwood

On Tue, Sep 20, 2016 at 01:52:34PM +0100, Charles Keepax wrote:
> Between when we load the DSP and when it actually starts running put the
> core into a lower power state where the memory is retained but nothing
> is clocked.
> 
> Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
> ---
> @@ -2344,6 +2355,11 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
>  		if (!dsp->booted)
>  			return -EIO;
>  
> +		ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
> +					 ADSP2_SYS_ENA, ADSP2_SYS_ENA);
> +		if (ret != 0)
> +			goto err;
> +

We actually need to wait for RAM_RDY again here, I will fire out
a new version of the patches in the next day or two.

Thanks,
Charles

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Applied "ASoC: wm_adsp: Make DSP preloader a supply widget" to the asoc tree
  2016-09-20 12:52 ` [PATCH 2/7] ASoC: wm_adsp: Make DSP preloader a supply widget Charles Keepax
@ 2016-09-25  5:58   ` Mark Brown
  0 siblings, 0 replies; 13+ messages in thread
From: Mark Brown @ 2016-09-25  5:58 UTC (permalink / raw)
  To: Charles Keepax; +Cc: alsa-devel, broonie, patches, lgirdwood

The patch

   ASoC: wm_adsp: Make DSP preloader a supply widget

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 5ca7e170e331781fe71acb4919667993bb9fbab6 Mon Sep 17 00:00:00 2001
From: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Date: Tue, 20 Sep 2016 13:52:31 +0100
Subject: [PATCH] ASoC: wm_adsp: Make DSP preloader a supply widget

Currently the DSP loading is split into two widgets, the preloader that
is a snd_soc_dapm_dai_link widget which starts a thread to download
the firmware, and the DSP itself which is a snd_soc_dapm_out_drv and
synchronises the thread back in to the DAPM sequence. This allows the
firmware download to be overlapped with the rest of the path bring up.

The use of a snd_soc_dapm_dai_link widget requires the preloader to be part
of the audio path in DAPM, really a supply widget is a better fit for the
preloader. The preloader is something that needs to be done for the DSP to
function, not a part of the audio path itself.

This change makes the DSP preloader widget a supply widget, which as well
as probably being a better fit will also make it much simpler to power up
the preloader widget to trigger firmware download to the core independently
of the audio path coming up.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/codecs/arizona.h | 16 ++++++++--------
 sound/soc/codecs/wm_adsp.h |  5 +++--
 2 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index e49955d834f0..850aa338ba29 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -191,20 +191,20 @@ extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
 #define ARIZONA_DSP_ROUTES(name) \
 	{ name, NULL, name " Preloader"}, \
 	{ name " Preloader", NULL, "SYSCLK" }, \
-	{ name " Preloader", NULL, name " Aux 1" }, \
-	{ name " Preloader", NULL, name " Aux 2" }, \
-	{ name " Preloader", NULL, name " Aux 3" }, \
-	{ name " Preloader", NULL, name " Aux 4" }, \
-	{ name " Preloader", NULL, name " Aux 5" }, \
-	{ name " Preloader", NULL, name " Aux 6" }, \
+	{ name, NULL, name " Aux 1" }, \
+	{ name, NULL, name " Aux 2" }, \
+	{ name, NULL, name " Aux 3" }, \
+	{ name, NULL, name " Aux 4" }, \
+	{ name, NULL, name " Aux 5" }, \
+	{ name, NULL, name " Aux 6" }, \
 	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \
 	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \
 	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \
 	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \
 	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \
 	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \
-	ARIZONA_MIXER_ROUTES(name " Preloader", name "L"), \
-	ARIZONA_MIXER_ROUTES(name " Preloader", name "R")
+	ARIZONA_MIXER_ROUTES(name, name "L"), \
+	ARIZONA_MIXER_ROUTES(name, name "R")
 
 #define ARIZONA_EQ_CONTROL(xname, xbase)                      \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,   \
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 6a054e744068..228b1f9e9a68 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -87,9 +87,10 @@ struct wm_adsp {
 		wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
 
 #define WM_ADSP2(wname, num, event_fn) \
-{	.id = snd_soc_dapm_dai_link, .name = wname " Preloader", \
+{	.id = snd_soc_dapm_supply, .name = wname " Preloader", \
 	.reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \
-	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }, \
+	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \
+	.subseq = 100, /* Ensure we run after SYSCLK supply widget */ }, \
 {	.id = snd_soc_dapm_out_drv, .name = wname, \
 	.reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \
 	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Applied "ASoC: arizona: Attach SYSCLK to DSP preloaders" to the asoc tree
  2016-09-20 12:52 ` [PATCH 1/7] ASoC: arizona: Attach SYSCLK to DSP preloaders Charles Keepax
@ 2016-09-25  5:58   ` Mark Brown
  0 siblings, 0 replies; 13+ messages in thread
From: Mark Brown @ 2016-09-25  5:58 UTC (permalink / raw)
  To: Charles Keepax; +Cc: alsa-devel, broonie, patches, lgirdwood

The patch

   ASoC: arizona: Attach SYSCLK to DSP preloaders

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 3577357a1680543b8acb98d69d23e87c1175db2b Mon Sep 17 00:00:00 2001
From: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Date: Tue, 20 Sep 2016 13:52:30 +0100
Subject: [PATCH] ASoC: arizona: Attach SYSCLK to DSP preloaders

Currently SYSCLK is attached to every compressed DAI as this follows the
pattern of attaching clocks to the chips inputs and outputs, however, it is
really the DSP that requires the clock here. As firmware download can be a
significant part of the path startup time for these devices occasionally it
would be desirable to download the firmware in advance of the path being
brought up.

To help facilitate this early firmware loading this patch attaches the
SYSCLK to the DSP preloader widget. This also saves us adding a new route
to SYSCLK every time a new compressed DAI is created.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/codecs/arizona.h | 1 +
 sound/soc/codecs/cs47l24.c | 2 --
 sound/soc/codecs/wm5102.c  | 1 -
 sound/soc/codecs/wm5110.c  | 2 --
 4 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 69da1ef3a17c..e49955d834f0 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -190,6 +190,7 @@ extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
 
 #define ARIZONA_DSP_ROUTES(name) \
 	{ name, NULL, name " Preloader"}, \
+	{ name " Preloader", NULL, "SYSCLK" }, \
 	{ name " Preloader", NULL, name " Aux 1" }, \
 	{ name " Preloader", NULL, name " Aux 2" }, \
 	{ name " Preloader", NULL, name " Aux 3" }, \
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c
index f8d8139b2d42..9576dbd116ac 100644
--- a/sound/soc/codecs/cs47l24.c
+++ b/sound/soc/codecs/cs47l24.c
@@ -814,7 +814,6 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = {
 	{ "AIF3 Capture", NULL, "SYSCLK" },
 
 	{ "Voice Control DSP", NULL, "DSP3" },
-	{ "Voice Control DSP", NULL, "SYSCLK" },
 
 	{ "IN1L PGA", NULL, "IN1L" },
 	{ "IN1R PGA", NULL, "IN1R" },
@@ -823,7 +822,6 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = {
 	{ "IN2R PGA", NULL, "IN2R" },
 
 	{ "Audio Trace DSP", NULL, "DSP2" },
-	{ "Audio Trace DSP", NULL, "SYSCLK" },
 
 	ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
 	ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index 16a1c5b46243..8ce76806a78b 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -1610,7 +1610,6 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
 	{ "Slim3 Capture", NULL, "SYSCLK" },
 
 	{ "Audio Trace DSP", NULL, "DSP1" },
-	{ "Audio Trace DSP", NULL, "SYSCLK" },
 
 	{ "IN1L PGA", NULL, "IN1L" },
 	{ "IN1R PGA", NULL, "IN1R" },
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 673dc598c234..5d8c5b67ed42 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -1842,10 +1842,8 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
 	{ "Slim3 Capture", NULL, "SYSCLK" },
 
 	{ "Voice Control DSP", NULL, "DSP3" },
-	{ "Voice Control DSP", NULL, "SYSCLK" },
 
 	{ "Audio Trace DSP", NULL, "DSP1" },
-	{ "Audio Trace DSP", NULL, "SYSCLK" },
 
 	{ "IN1L PGA", NULL, "IN1L" },
 	{ "IN1R PGA", NULL, "IN1R" },
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Applied "ASoC: wm_adsp: Move control cache sync out of preloader" to the asoc tree
  2016-09-20 12:52 ` [PATCH 4/7] ASoC: wm_adsp: Move control cache sync out of preloader Charles Keepax
@ 2016-09-25  5:58   ` Mark Brown
  0 siblings, 0 replies; 13+ messages in thread
From: Mark Brown @ 2016-09-25  5:58 UTC (permalink / raw)
  To: Charles Keepax; +Cc: alsa-devel, broonie, patches, lgirdwood

The patch

   ASoC: wm_adsp: Move control cache sync out of preloader

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From cef45771c141fdccebe4cb7e0ce79f4687275494 Mon Sep 17 00:00:00 2001
From: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Date: Tue, 20 Sep 2016 13:52:33 +0100
Subject: [PATCH] ASoC: wm_adsp: Move control cache sync out of preloader

As part of the work to download firmware before the audio path is brought
up the DSP will be put into a low power state between downloading firmware
to the core and starting it running. This will mean that the firmware ALSA
controls are not accessible in the hardware during this period of time.

To prepare for this change we gate access to the hardware in the ALSA
control handlers on the DSP being running rather than simply booted and
move the synchronisation of the control caches out of the preloader delayed
work and into the main DAPM thread after the DSP will have been brought out
of its low power state.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/codecs/wm_adsp.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index ae2f2b6e82ed..24485ec5866f 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -792,7 +792,7 @@ static int wm_coeff_put(struct snd_kcontrol *kctl,
 	memcpy(ctl->cache, p, ctl->len);
 
 	ctl->set = 1;
-	if (ctl->enabled && ctl->dsp->booted)
+	if (ctl->enabled && ctl->dsp->running)
 		ret = wm_coeff_write_control(ctl, p, ctl->len);
 
 	mutex_unlock(&ctl->dsp->pwr_lock);
@@ -814,7 +814,7 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl,
 		ret = -EFAULT;
 	} else {
 		ctl->set = 1;
-		if (ctl->enabled && ctl->dsp->booted)
+		if (ctl->enabled && ctl->dsp->running)
 			ret = wm_coeff_write_control(ctl, ctl->cache, size);
 	}
 
@@ -874,12 +874,12 @@ static int wm_coeff_get(struct snd_kcontrol *kctl,
 	mutex_lock(&ctl->dsp->pwr_lock);
 
 	if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
-		if (ctl->enabled && ctl->dsp->booted)
+		if (ctl->enabled && ctl->dsp->running)
 			ret = wm_coeff_read_control(ctl, p, ctl->len);
 		else
 			ret = -EPERM;
 	} else {
-		if (!ctl->flags && ctl->enabled && ctl->dsp->booted)
+		if (!ctl->flags && ctl->enabled && ctl->dsp->running)
 			ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len);
 
 		memcpy(p, ctl->cache, ctl->len);
@@ -901,12 +901,12 @@ static int wm_coeff_tlv_get(struct snd_kcontrol *kctl,
 	mutex_lock(&ctl->dsp->pwr_lock);
 
 	if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
-		if (ctl->enabled && ctl->dsp->booted)
+		if (ctl->enabled && ctl->dsp->running)
 			ret = wm_coeff_read_control(ctl, ctl->cache, size);
 		else
 			ret = -EPERM;
 	} else {
-		if (!ctl->flags && ctl->enabled && ctl->dsp->booted)
+		if (!ctl->flags && ctl->enabled && ctl->dsp->running)
 			ret = wm_coeff_read_control(ctl, ctl->cache, size);
 	}
 
@@ -2280,11 +2280,6 @@ static void wm_adsp2_boot_work(struct work_struct *work)
 	if (ret != 0)
 		goto err_ena;
 
-	/* Sync set controls */
-	ret = wm_coeff_sync_controls(dsp);
-	if (ret != 0)
-		goto err_ena;
-
 	dsp->booted = true;
 
 	mutex_unlock(&dsp->pwr_lock);
@@ -2349,6 +2344,11 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
 		if (!dsp->booted)
 			return -EIO;
 
+		/* Sync set controls */
+		ret = wm_coeff_sync_controls(dsp);
+		if (ret != 0)
+			goto err;
+
 		ret = regmap_update_bits(dsp->regmap,
 					 dsp->base + ADSP2_CONTROL,
 					 ADSP2_CORE_ENA | ADSP2_START,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Applied "ASoC: wm_adsp: Separate concept of booted and running" to the asoc tree
  2016-09-20 12:52 ` [PATCH 3/7] ASoC: wm_adsp: Separate concept of booted and running Charles Keepax
@ 2016-09-25  5:58   ` Mark Brown
  0 siblings, 0 replies; 13+ messages in thread
From: Mark Brown @ 2016-09-25  5:58 UTC (permalink / raw)
  To: Charles Keepax; +Cc: alsa-devel, broonie, patches, lgirdwood

The patch

   ASoC: wm_adsp: Separate concept of booted and running

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 28823ebad5e73bd717ca820929de2d18415d9822 Mon Sep 17 00:00:00 2001
From: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Date: Tue, 20 Sep 2016 13:52:32 +0100
Subject: [PATCH] ASoC: wm_adsp: Separate concept of booted and running

Currently the wm_adsp driver has a flag that indicates the DSP is
"running", this flag is used to gate access to the hardware.  However this
flag is actually set in the firmware download thread after the firmware has
been downloaded, but this is before the core is actually started running,
so really it currently indicates that the core has been booted and is
perhaps running.

This patch clearly separates out the concepts of booted (firmware is
downloaded) and running (code is executing on the DSP) within the wm_adsp
driver.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/codecs/wm_adsp.c | 36 +++++++++++++++++++++++++-----------
 sound/soc/codecs/wm_adsp.h |  2 ++
 2 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 21fbe7d07063..ae2f2b6e82ed 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -480,7 +480,7 @@ static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file,
 
 	mutex_lock(&dsp->pwr_lock);
 
-	if (!dsp->wmfw_file_name || !dsp->running)
+	if (!dsp->wmfw_file_name || !dsp->booted)
 		ret = 0;
 	else
 		ret = simple_read_from_buffer(user_buf, count, ppos,
@@ -500,7 +500,7 @@ static ssize_t wm_adsp_debugfs_bin_read(struct file *file,
 
 	mutex_lock(&dsp->pwr_lock);
 
-	if (!dsp->bin_file_name || !dsp->running)
+	if (!dsp->bin_file_name || !dsp->booted)
 		ret = 0;
 	else
 		ret = simple_read_from_buffer(user_buf, count, ppos,
@@ -554,6 +554,9 @@ static void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
 	if (!root)
 		goto err;
 
+	if (!debugfs_create_bool("booted", S_IRUGO, root, &dsp->booted))
+		goto err;
+
 	if (!debugfs_create_bool("running", S_IRUGO, root, &dsp->running))
 		goto err;
 
@@ -637,7 +640,7 @@ static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
 
 	mutex_lock(&dsp[e->shift_l].pwr_lock);
 
-	if (dsp[e->shift_l].running || dsp[e->shift_l].compr)
+	if (dsp[e->shift_l].booted || dsp[e->shift_l].compr)
 		ret = -EBUSY;
 	else
 		dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0];
@@ -789,7 +792,7 @@ static int wm_coeff_put(struct snd_kcontrol *kctl,
 	memcpy(ctl->cache, p, ctl->len);
 
 	ctl->set = 1;
-	if (ctl->enabled)
+	if (ctl->enabled && ctl->dsp->booted)
 		ret = wm_coeff_write_control(ctl, p, ctl->len);
 
 	mutex_unlock(&ctl->dsp->pwr_lock);
@@ -811,7 +814,7 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl,
 		ret = -EFAULT;
 	} else {
 		ctl->set = 1;
-		if (ctl->enabled)
+		if (ctl->enabled && ctl->dsp->booted)
 			ret = wm_coeff_write_control(ctl, ctl->cache, size);
 	}
 
@@ -871,12 +874,12 @@ static int wm_coeff_get(struct snd_kcontrol *kctl,
 	mutex_lock(&ctl->dsp->pwr_lock);
 
 	if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
-		if (ctl->enabled)
+		if (ctl->enabled && ctl->dsp->booted)
 			ret = wm_coeff_read_control(ctl, p, ctl->len);
 		else
 			ret = -EPERM;
 	} else {
-		if (!ctl->flags && ctl->enabled)
+		if (!ctl->flags && ctl->enabled && ctl->dsp->booted)
 			ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len);
 
 		memcpy(p, ctl->cache, ctl->len);
@@ -898,12 +901,12 @@ static int wm_coeff_tlv_get(struct snd_kcontrol *kctl,
 	mutex_lock(&ctl->dsp->pwr_lock);
 
 	if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
-		if (ctl->enabled)
+		if (ctl->enabled && ctl->dsp->booted)
 			ret = wm_coeff_read_control(ctl, ctl->cache, size);
 		else
 			ret = -EPERM;
 	} else {
-		if (!ctl->flags && ctl->enabled)
+		if (!ctl->flags && ctl->enabled && ctl->dsp->booted)
 			ret = wm_coeff_read_control(ctl, ctl->cache, size);
 	}
 
@@ -2166,13 +2169,20 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
 		if (ret != 0)
 			goto err_ena;
 
+		dsp->booted = true;
+
 		/* Start the core running */
 		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
 				   ADSP1_CORE_ENA | ADSP1_START,
 				   ADSP1_CORE_ENA | ADSP1_START);
+
+		dsp->running = true;
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
+		dsp->running = false;
+		dsp->booted = false;
+
 		/* Halt the core */
 		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
 				   ADSP1_CORE_ENA | ADSP1_START, 0);
@@ -2275,7 +2285,7 @@ static void wm_adsp2_boot_work(struct work_struct *work)
 	if (ret != 0)
 		goto err_ena;
 
-	dsp->running = true;
+	dsp->booted = true;
 
 	mutex_unlock(&dsp->pwr_lock);
 
@@ -2336,7 +2346,7 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
 	case SND_SOC_DAPM_POST_PMU:
 		flush_work(&dsp->boot_work);
 
-		if (!dsp->running)
+		if (!dsp->booted)
 			return -EIO;
 
 		ret = regmap_update_bits(dsp->regmap,
@@ -2346,6 +2356,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
 		if (ret != 0)
 			goto err;
 
+		dsp->running = true;
+
 		mutex_lock(&dsp->pwr_lock);
 
 		if (wm_adsp_fw[dsp->fw].num_caps != 0)
@@ -2365,7 +2377,9 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
 
 		dsp->fw_id = 0;
 		dsp->fw_id_version = 0;
+
 		dsp->running = false;
+		dsp->booted = false;
 
 		regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
 				   ADSP2_CORE_ENA | ADSP2_START, 0);
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index be3b5bcb7f17..6a054e744068 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -61,6 +61,8 @@ struct wm_adsp {
 
 	int fw;
 	int fw_ver;
+
+	bool booted;
 	bool running;
 
 	struct list_head ctl_list;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2016-09-25  5:58 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-20 12:52 [PATCH 0/7] Allow ADSPs to be preloaded with firmware Charles Keepax
2016-09-20 12:52 ` [PATCH 1/7] ASoC: arizona: Attach SYSCLK to DSP preloaders Charles Keepax
2016-09-25  5:58   ` Applied "ASoC: arizona: Attach SYSCLK to DSP preloaders" to the asoc tree Mark Brown
2016-09-20 12:52 ` [PATCH 2/7] ASoC: wm_adsp: Make DSP preloader a supply widget Charles Keepax
2016-09-25  5:58   ` Applied "ASoC: wm_adsp: Make DSP preloader a supply widget" to the asoc tree Mark Brown
2016-09-20 12:52 ` [PATCH 3/7] ASoC: wm_adsp: Separate concept of booted and running Charles Keepax
2016-09-25  5:58   ` Applied "ASoC: wm_adsp: Separate concept of booted and running" to the asoc tree Mark Brown
2016-09-20 12:52 ` [PATCH 4/7] ASoC: wm_adsp: Move control cache sync out of preloader Charles Keepax
2016-09-25  5:58   ` Applied "ASoC: wm_adsp: Move control cache sync out of preloader" to the asoc tree Mark Brown
2016-09-20 12:52 ` [PATCH 5/7] ASoC: wm_adsp: Put DSP into low power state between loading and running Charles Keepax
2016-09-21 16:14   ` Charles Keepax
2016-09-20 12:52 ` [PATCH 6/7] ASoC: wm_adsp: Allow preloader to do the final shutdown of the DSP Charles Keepax
2016-09-20 12:52 ` [PATCH 7/7] ASoC: wm_adsp: Add mechanism to preload firmware on a core Charles Keepax

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.