mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-29 04:45:05 +00:00
ASoC: wm_adsp: Factor out ADSP2 boot proceedure
Move the ADSP2 boot proceedure into a work structure in preparation for running it asynchronously with the reset of the audio path bring up. Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com> Signed-off-by: Mark Brown <broonie@linaro.org>
This commit is contained in:
parent
5095f55d7c
commit
d8a64d6ade
@ -1492,6 +1492,105 @@ static int wm_adsp2_ena(struct wm_adsp *dsp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wm_adsp2_boot_work(struct work_struct *work)
|
||||
{
|
||||
struct wm_adsp *dsp = container_of(work,
|
||||
struct wm_adsp,
|
||||
boot_work);
|
||||
int ret;
|
||||
unsigned int val;
|
||||
|
||||
/*
|
||||
* For simplicity set the DSP clock rate to be the
|
||||
* SYSCLK rate rather than making it configurable.
|
||||
*/
|
||||
ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val);
|
||||
if (ret != 0) {
|
||||
adsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
val = (val & ARIZONA_SYSCLK_FREQ_MASK)
|
||||
>> ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
|
||||
ret = regmap_update_bits_async(dsp->regmap,
|
||||
dsp->base + ADSP2_CLOCKING,
|
||||
ADSP2_CLK_SEL_MASK, val);
|
||||
if (ret != 0) {
|
||||
adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dsp->dvfs) {
|
||||
ret = regmap_read(dsp->regmap,
|
||||
dsp->base + ADSP2_CLOCKING, &val);
|
||||
if (ret != 0) {
|
||||
dev_err(dsp->dev, "Failed to read clocking: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((val & ADSP2_CLK_SEL_MASK) >= 3) {
|
||||
ret = regulator_enable(dsp->dvfs);
|
||||
if (ret != 0) {
|
||||
dev_err(dsp->dev,
|
||||
"Failed to enable supply: %d\n",
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = regulator_set_voltage(dsp->dvfs,
|
||||
1800000,
|
||||
1800000);
|
||||
if (ret != 0) {
|
||||
dev_err(dsp->dev,
|
||||
"Failed to raise supply: %d\n",
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = wm_adsp2_ena(dsp);
|
||||
if (ret != 0)
|
||||
return;
|
||||
|
||||
ret = wm_adsp_load(dsp);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
|
||||
ret = wm_adsp_setup_algs(dsp);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
|
||||
ret = wm_adsp_load_coeff(dsp);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
|
||||
/* Initialize caches for enabled and unset controls */
|
||||
ret = wm_coeff_init_control_caches(dsp);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
|
||||
/* Sync set controls */
|
||||
ret = wm_coeff_sync_controls(dsp);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
|
||||
ret = regmap_update_bits_async(dsp->regmap,
|
||||
dsp->base + ADSP2_CONTROL,
|
||||
ADSP2_CORE_ENA,
|
||||
ADSP2_CORE_ENA);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
|
||||
dsp->running = true;
|
||||
|
||||
return;
|
||||
|
||||
err:
|
||||
regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
|
||||
ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0);
|
||||
}
|
||||
|
||||
int wm_adsp2_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
@ -1500,99 +1599,24 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
|
||||
struct wm_adsp *dsp = &dsps[w->shift];
|
||||
struct wm_adsp_alg_region *alg_region;
|
||||
struct wm_coeff_ctl *ctl;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
dsp->card = codec->card;
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
/*
|
||||
* For simplicity set the DSP clock rate to be the
|
||||
* SYSCLK rate rather than making it configurable.
|
||||
*/
|
||||
ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val);
|
||||
if (ret != 0) {
|
||||
adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
val = (val & ARIZONA_SYSCLK_FREQ_MASK)
|
||||
>> ARIZONA_SYSCLK_FREQ_SHIFT;
|
||||
queue_work(system_unbound_wq, &dsp->boot_work);
|
||||
flush_work(&dsp->boot_work);
|
||||
|
||||
ret = regmap_update_bits_async(dsp->regmap,
|
||||
dsp->base + ADSP2_CLOCKING,
|
||||
ADSP2_CLK_SEL_MASK, val);
|
||||
if (ret != 0) {
|
||||
adsp_err(dsp, "Failed to set clock rate: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
if (!dsp->running)
|
||||
return -EIO;
|
||||
|
||||
if (dsp->dvfs) {
|
||||
ret = regmap_read(dsp->regmap,
|
||||
dsp->base + ADSP2_CLOCKING, &val);
|
||||
if (ret != 0) {
|
||||
dev_err(dsp->dev,
|
||||
"Failed to read clocking: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((val & ADSP2_CLK_SEL_MASK) >= 3) {
|
||||
ret = regulator_enable(dsp->dvfs);
|
||||
if (ret != 0) {
|
||||
dev_err(dsp->dev,
|
||||
"Failed to enable supply: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regulator_set_voltage(dsp->dvfs,
|
||||
1800000,
|
||||
1800000);
|
||||
if (ret != 0) {
|
||||
dev_err(dsp->dev,
|
||||
"Failed to raise supply: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = wm_adsp2_ena(dsp);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = wm_adsp_load(dsp);
|
||||
ret = regmap_update_bits(dsp->regmap,
|
||||
dsp->base + ADSP2_CONTROL,
|
||||
ADSP2_START,
|
||||
ADSP2_START);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
|
||||
ret = wm_adsp_setup_algs(dsp);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
|
||||
ret = wm_adsp_load_coeff(dsp);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
|
||||
/* Initialize caches for enabled and unset controls */
|
||||
ret = wm_coeff_init_control_caches(dsp);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
|
||||
/* Sync set controls */
|
||||
ret = wm_coeff_sync_controls(dsp);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
|
||||
ret = regmap_update_bits_async(dsp->regmap,
|
||||
dsp->base + ADSP2_CONTROL,
|
||||
ADSP2_CORE_ENA | ADSP2_START,
|
||||
ADSP2_CORE_ENA | ADSP2_START);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
|
||||
dsp->running = true;
|
||||
break;
|
||||
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
@ -1663,6 +1687,7 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
|
||||
|
||||
INIT_LIST_HEAD(&adsp->alg_regions);
|
||||
INIT_LIST_HEAD(&adsp->ctl_list);
|
||||
INIT_WORK(&adsp->boot_work, wm_adsp2_boot_work);
|
||||
|
||||
if (dvfs) {
|
||||
adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD");
|
||||
|
@ -59,6 +59,8 @@ struct wm_adsp {
|
||||
struct regulator *dvfs;
|
||||
|
||||
struct list_head ctl_list;
|
||||
|
||||
struct work_struct boot_work;
|
||||
};
|
||||
|
||||
#define WM_ADSP1(wname, num) \
|
||||
|
Loading…
Reference in New Issue
Block a user