aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/intel
diff options
context:
space:
mode:
authorVinod Koul <vinod.koul@intel.com>2016-07-26 08:36:42 -0400
committerMark Brown <broonie@kernel.org>2016-08-08 06:54:59 -0400
commit78cdbbdac059fad34740f0bdefe263f8de2a1faf (patch)
tree75ba4e8ac5c4056cc3d9662638bf626ad52c1074 /sound/soc/intel
parent73a675816d704337ef7e8cb441f094a82fcc1018 (diff)
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: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/intel')
-rw-r--r--sound/soc/intel/skylake/bxt-sst.c19
-rw-r--r--sound/soc/intel/skylake/skl-messages.c8
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c20
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.h2
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h3
-rw-r--r--sound/soc/intel/skylake/skl-sst.c27
-rw-r--r--sound/soc/intel/skylake/skl.h1
7 files changed, 65 insertions, 15 deletions
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c
index 2663781278aa..eb68258b653d 100644
--- a/sound/soc/intel/skylake/bxt-sst.c
+++ b/sound/soc/intel/skylake/bxt-sst.c
@@ -397,6 +397,19 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
397 skl->cores.count = 2; 397 skl->cores.count = 2;
398 skl->boot_complete = false; 398 skl->boot_complete = false;
399 init_waitqueue_head(&skl->boot_wait); 399 init_waitqueue_head(&skl->boot_wait);
400 skl->is_first_boot = true;
401
402 if (dsp)
403 *dsp = skl;
404
405 return 0;
406}
407EXPORT_SYMBOL_GPL(bxt_sst_dsp_init);
408
409int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx)
410{
411 int ret;
412 struct sst_dsp *sst = ctx->dsp;
400 413
401 ret = sst->fw_ops.load_fw(sst); 414 ret = sst->fw_ops.load_fw(sst);
402 if (ret < 0) { 415 if (ret < 0) {
@@ -406,13 +419,11 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
406 419
407 skl_dsp_init_core_state(sst); 420 skl_dsp_init_core_state(sst);
408 421
409 if (dsp) 422 ctx->is_first_boot = false;
410 *dsp = skl;
411 423
412 return 0; 424 return 0;
413} 425}
414EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); 426EXPORT_SYMBOL_GPL(bxt_sst_init_fw);
415
416 427
417void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) 428void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
418{ 429{
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 25d057679f2c..2199a91d90d6 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -203,18 +203,21 @@ static const struct skl_dsp_ops dsp_ops[] = {
203 .id = 0x9d70, 203 .id = 0x9d70,
204 .loader_ops = skl_get_loader_ops, 204 .loader_ops = skl_get_loader_ops,
205 .init = skl_sst_dsp_init, 205 .init = skl_sst_dsp_init,
206 .init_fw = skl_sst_init_fw,
206 .cleanup = skl_sst_dsp_cleanup 207 .cleanup = skl_sst_dsp_cleanup
207 }, 208 },
208 { 209 {
209 .id = 0x9d71, 210 .id = 0x9d71,
210 .loader_ops = skl_get_loader_ops, 211 .loader_ops = skl_get_loader_ops,
211 .init = skl_sst_dsp_init, 212 .init = skl_sst_dsp_init,
213 .init_fw = skl_sst_init_fw,
212 .cleanup = skl_sst_dsp_cleanup 214 .cleanup = skl_sst_dsp_cleanup
213 }, 215 },
214 { 216 {
215 .id = 0x5a98, 217 .id = 0x5a98,
216 .loader_ops = bxt_get_loader_ops, 218 .loader_ops = bxt_get_loader_ops,
217 .init = bxt_sst_dsp_init, 219 .init = bxt_sst_dsp_init,
220 .init_fw = bxt_sst_init_fw,
218 .cleanup = bxt_sst_dsp_cleanup 221 .cleanup = bxt_sst_dsp_cleanup
219 }, 222 },
220}; 223};
@@ -264,7 +267,6 @@ int skl_init_dsp(struct skl *skl)
264 if (ret < 0) 267 if (ret < 0)
265 return ret; 268 return ret;
266 269
267 skl_dsp_enable_notification(skl->skl_sst, false);
268 dev_dbg(bus->dev, "dsp registration status=%d\n", ret); 270 dev_dbg(bus->dev, "dsp registration status=%d\n", ret);
269 271
270 return ret; 272 return ret;
@@ -325,6 +327,10 @@ int skl_resume_dsp(struct skl *skl)
325 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); 327 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
326 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true); 328 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true);
327 329
330 /* check if DSP 1st boot is done */
331 if (skl->skl_sst->is_first_boot == true)
332 return 0;
333
328 ret = skl_dsp_wake(ctx->dsp); 334 ret = skl_dsp_wake(ctx->dsp);
329 if (ret < 0) 335 if (ret < 0)
330 return ret; 336 return ret;
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index 6e05bf8622f7..22d4f0703a33 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -1142,8 +1142,10 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
1142{ 1142{
1143 struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev); 1143 struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev);
1144 struct skl *skl = ebus_to_skl(ebus); 1144 struct skl *skl = ebus_to_skl(ebus);
1145 const struct skl_dsp_ops *ops;
1145 int ret; 1146 int ret;
1146 1147
1148 pm_runtime_get_sync(platform->dev);
1147 if (ebus->ppcap) { 1149 if (ebus->ppcap) {
1148 ret = skl_tplg_init(platform, ebus); 1150 ret = skl_tplg_init(platform, ebus);
1149 if (ret < 0) { 1151 if (ret < 0) {
@@ -1151,7 +1153,25 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
1151 return ret; 1153 return ret;
1152 } 1154 }
1153 skl->platform = platform; 1155 skl->platform = platform;
1156
1157 /* load the firmwares, since all is set */
1158 ops = skl_get_dsp_ops(skl->pci->device);
1159 if (!ops)
1160 return -EIO;
1161
1162 if (skl->skl_sst->is_first_boot == false) {
1163 dev_err(platform->dev, "DSP reports first boot done!!!\n");
1164 return -EIO;
1165 }
1166
1167 ret = ops->init_fw(platform->dev, skl->skl_sst);
1168 if (ret < 0) {
1169 dev_err(platform->dev, "Failed to boot first fw: %d\n", ret);
1170 return ret;
1171 }
1154 } 1172 }
1173 pm_runtime_mark_last_busy(platform->dev);
1174 pm_runtime_put_autosuspend(platform->dev);
1155 1175
1156 return 0; 1176 return 0;
1157} 1177}
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h
index 0f8629ef79ac..7e994688d8a0 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.h
+++ b/sound/soc/intel/skylake/skl-sst-dsp.h
@@ -203,6 +203,8 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
203int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 203int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
204 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 204 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
205 struct skl_sst **dsp); 205 struct skl_sst **dsp);
206int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx);
207int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx);
206void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 208void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
207void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 209void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
208 210
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index 2e3d4e80ef97..0a0d09cde99d 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -75,6 +75,9 @@ struct skl_sst {
75 /* Is firmware loaded */ 75 /* Is firmware loaded */
76 bool fw_loaded; 76 bool fw_loaded;
77 77
78 /* first boot ? */
79 bool is_first_boot;
80
78 /* multi-core */ 81 /* multi-core */
79 struct skl_dsp_cores cores; 82 struct skl_dsp_cores cores;
80}; 83};
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
index 588f899ceb65..6de4c027a65b 100644
--- a/sound/soc/intel/skylake/skl-sst.c
+++ b/sound/soc/intel/skylake/skl-sst.c
@@ -484,25 +484,32 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
484 return ret; 484 return ret;
485 485
486 skl->cores.count = 2; 486 skl->cores.count = 2;
487 skl->is_first_boot = true;
488
489 if (dsp)
490 *dsp = skl;
491
492 return ret;
493}
494EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
495
496int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
497{
498 int ret;
499 struct sst_dsp *sst = ctx->dsp;
487 500
488 ret = sst->fw_ops.load_fw(sst); 501 ret = sst->fw_ops.load_fw(sst);
489 if (ret < 0) { 502 if (ret < 0) {
490 dev_err(dev, "Load base fw failed : %d", ret); 503 dev_err(dev, "Load base fw failed : %d", ret);
491 goto cleanup; 504 return ret;
492 } 505 }
493 506
494 skl_dsp_init_core_state(sst); 507 skl_dsp_init_core_state(sst);
508 ctx->is_first_boot = false;
495 509
496 if (dsp) 510 return 0;
497 *dsp = skl;
498
499 return ret;
500
501cleanup:
502 skl_sst_dsp_cleanup(dev, skl);
503 return ret;
504} 511}
505EXPORT_SYMBOL_GPL(skl_sst_dsp_init); 512EXPORT_SYMBOL_GPL(skl_sst_init_fw);
506 513
507void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) 514void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
508{ 515{
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index c3538f8b17d9..5d4fbb094c48 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -105,6 +105,7 @@ struct skl_dsp_ops {
105 int irq, const char *fw_name, 105 int irq, const char *fw_name,
106 struct skl_dsp_loader_ops loader_ops, 106 struct skl_dsp_loader_ops loader_ops,
107 struct skl_sst **skl_sst); 107 struct skl_sst **skl_sst);
108 int (*init_fw)(struct device *dev, struct skl_sst *ctx);
108 void (*cleanup)(struct device *dev, struct skl_sst *ctx); 109 void (*cleanup)(struct device *dev, struct skl_sst *ctx);
109}; 110};
110 111