Commit 78cdbbda authored by Vinod Koul's avatar Vinod Koul Committed by Mark Brown

ASoC: Intel: Skylake: split fw and dsp initialization

The DSP instance creation also loads the firmware on DSPs. For library load
the firmware names come from topology so can't be loaded at object creation.

So split the firmware load and object creation. FW load is now called after
topology init in platform probe.
Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 73a67581
...@@ -397,6 +397,19 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, ...@@ -397,6 +397,19 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
skl->cores.count = 2; skl->cores.count = 2;
skl->boot_complete = false; skl->boot_complete = false;
init_waitqueue_head(&skl->boot_wait); init_waitqueue_head(&skl->boot_wait);
skl->is_first_boot = true;
if (dsp)
*dsp = skl;
return 0;
}
EXPORT_SYMBOL_GPL(bxt_sst_dsp_init);
int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx)
{
int ret;
struct sst_dsp *sst = ctx->dsp;
ret = sst->fw_ops.load_fw(sst); ret = sst->fw_ops.load_fw(sst);
if (ret < 0) { if (ret < 0) {
...@@ -406,13 +419,11 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, ...@@ -406,13 +419,11 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
skl_dsp_init_core_state(sst); skl_dsp_init_core_state(sst);
if (dsp) ctx->is_first_boot = false;
*dsp = skl;
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); EXPORT_SYMBOL_GPL(bxt_sst_init_fw);
void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
{ {
......
...@@ -203,18 +203,21 @@ static const struct skl_dsp_ops dsp_ops[] = { ...@@ -203,18 +203,21 @@ static const struct skl_dsp_ops dsp_ops[] = {
.id = 0x9d70, .id = 0x9d70,
.loader_ops = skl_get_loader_ops, .loader_ops = skl_get_loader_ops,
.init = skl_sst_dsp_init, .init = skl_sst_dsp_init,
.init_fw = skl_sst_init_fw,
.cleanup = skl_sst_dsp_cleanup .cleanup = skl_sst_dsp_cleanup
}, },
{ {
.id = 0x9d71, .id = 0x9d71,
.loader_ops = skl_get_loader_ops, .loader_ops = skl_get_loader_ops,
.init = skl_sst_dsp_init, .init = skl_sst_dsp_init,
.init_fw = skl_sst_init_fw,
.cleanup = skl_sst_dsp_cleanup .cleanup = skl_sst_dsp_cleanup
}, },
{ {
.id = 0x5a98, .id = 0x5a98,
.loader_ops = bxt_get_loader_ops, .loader_ops = bxt_get_loader_ops,
.init = bxt_sst_dsp_init, .init = bxt_sst_dsp_init,
.init_fw = bxt_sst_init_fw,
.cleanup = bxt_sst_dsp_cleanup .cleanup = bxt_sst_dsp_cleanup
}, },
}; };
...@@ -264,7 +267,6 @@ int skl_init_dsp(struct skl *skl) ...@@ -264,7 +267,6 @@ int skl_init_dsp(struct skl *skl)
if (ret < 0) if (ret < 0)
return ret; return ret;
skl_dsp_enable_notification(skl->skl_sst, false);
dev_dbg(bus->dev, "dsp registration status=%d\n", ret); dev_dbg(bus->dev, "dsp registration status=%d\n", ret);
return ret; return ret;
...@@ -325,6 +327,10 @@ int skl_resume_dsp(struct skl *skl) ...@@ -325,6 +327,10 @@ int skl_resume_dsp(struct skl *skl)
snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true); snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true);
/* check if DSP 1st boot is done */
if (skl->skl_sst->is_first_boot == true)
return 0;
ret = skl_dsp_wake(ctx->dsp); ret = skl_dsp_wake(ctx->dsp);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -1142,8 +1142,10 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform) ...@@ -1142,8 +1142,10 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
{ {
struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev); struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev);
struct skl *skl = ebus_to_skl(ebus); struct skl *skl = ebus_to_skl(ebus);
const struct skl_dsp_ops *ops;
int ret; int ret;
pm_runtime_get_sync(platform->dev);
if (ebus->ppcap) { if (ebus->ppcap) {
ret = skl_tplg_init(platform, ebus); ret = skl_tplg_init(platform, ebus);
if (ret < 0) { if (ret < 0) {
...@@ -1151,7 +1153,25 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform) ...@@ -1151,7 +1153,25 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
return ret; return ret;
} }
skl->platform = platform; skl->platform = platform;
/* load the firmwares, since all is set */
ops = skl_get_dsp_ops(skl->pci->device);
if (!ops)
return -EIO;
if (skl->skl_sst->is_first_boot == false) {
dev_err(platform->dev, "DSP reports first boot done!!!\n");
return -EIO;
}
ret = ops->init_fw(platform->dev, skl->skl_sst);
if (ret < 0) {
dev_err(platform->dev, "Failed to boot first fw: %d\n", ret);
return ret;
}
} }
pm_runtime_mark_last_busy(platform->dev);
pm_runtime_put_autosuspend(platform->dev);
return 0; return 0;
} }
......
...@@ -203,6 +203,8 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, ...@@ -203,6 +203,8 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
const char *fw_name, struct skl_dsp_loader_ops dsp_ops, const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
struct skl_sst **dsp); struct skl_sst **dsp);
int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx);
int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx);
void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
......
...@@ -75,6 +75,9 @@ struct skl_sst { ...@@ -75,6 +75,9 @@ struct skl_sst {
/* Is firmware loaded */ /* Is firmware loaded */
bool fw_loaded; bool fw_loaded;
/* first boot ? */
bool is_first_boot;
/* multi-core */ /* multi-core */
struct skl_dsp_cores cores; struct skl_dsp_cores cores;
}; };
......
...@@ -484,25 +484,32 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, ...@@ -484,25 +484,32 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
return ret; return ret;
skl->cores.count = 2; skl->cores.count = 2;
skl->is_first_boot = true;
if (dsp)
*dsp = skl;
return ret;
}
EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
{
int ret;
struct sst_dsp *sst = ctx->dsp;
ret = sst->fw_ops.load_fw(sst); ret = sst->fw_ops.load_fw(sst);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "Load base fw failed : %d", ret); dev_err(dev, "Load base fw failed : %d", ret);
goto cleanup; return ret;
} }
skl_dsp_init_core_state(sst); skl_dsp_init_core_state(sst);
ctx->is_first_boot = false;
if (dsp) return 0;
*dsp = skl;
return ret;
cleanup:
skl_sst_dsp_cleanup(dev, skl);
return ret;
} }
EXPORT_SYMBOL_GPL(skl_sst_dsp_init); EXPORT_SYMBOL_GPL(skl_sst_init_fw);
void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
{ {
......
...@@ -105,6 +105,7 @@ struct skl_dsp_ops { ...@@ -105,6 +105,7 @@ struct skl_dsp_ops {
int irq, const char *fw_name, int irq, const char *fw_name,
struct skl_dsp_loader_ops loader_ops, struct skl_dsp_loader_ops loader_ops,
struct skl_sst **skl_sst); struct skl_sst **skl_sst);
int (*init_fw)(struct device *dev, struct skl_sst *ctx);
void (*cleanup)(struct device *dev, struct skl_sst *ctx); void (*cleanup)(struct device *dev, struct skl_sst *ctx);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment