skl->cores.count = 2;
        skl->boot_complete = false;
        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);
        if (ret < 0) {
 
        skl_dsp_init_core_state(sst);
 
-       if (dsp)
-               *dsp = skl;
+       ctx->is_first_boot = false;
 
        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)
 {
 
                .id = 0x9d70,
                .loader_ops = skl_get_loader_ops,
                .init = skl_sst_dsp_init,
+               .init_fw = skl_sst_init_fw,
                .cleanup = skl_sst_dsp_cleanup
        },
        {
                .id = 0x9d71,
                .loader_ops = skl_get_loader_ops,
                .init = skl_sst_dsp_init,
+               .init_fw = skl_sst_init_fw,
                .cleanup = skl_sst_dsp_cleanup
        },
        {
                .id = 0x5a98,
                .loader_ops = bxt_get_loader_ops,
                .init = bxt_sst_dsp_init,
+               .init_fw = bxt_sst_init_fw,
                .cleanup = bxt_sst_dsp_cleanup
        },
 };
        if (ret < 0)
                return ret;
 
-       skl_dsp_enable_notification(skl->skl_sst, false);
        dev_dbg(bus->dev, "dsp registration status=%d\n", ret);
 
        return ret;
        snd_hdac_ext_bus_ppcap_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);
        if (ret < 0)
                return ret;
 
 {
        struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev);
        struct skl *skl = ebus_to_skl(ebus);
+       const struct skl_dsp_ops *ops;
        int ret;
 
+       pm_runtime_get_sync(platform->dev);
        if (ebus->ppcap) {
                ret = skl_tplg_init(platform, ebus);
                if (ret < 0) {
                        return ret;
                }
                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;
 }
 
 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,
                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 bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
 
 
        /* Is firmware loaded */
        bool fw_loaded;
 
+       /* first boot ? */
+       bool is_first_boot;
+
        /* multi-core */
        struct skl_dsp_cores cores;
 };
 
                return ret;
 
        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);
        if (ret < 0) {
                dev_err(dev, "Load base fw failed : %d", ret);
-               goto cleanup;
+               return ret;
        }
 
        skl_dsp_init_core_state(sst);
+       ctx->is_first_boot = false;
 
-       if (dsp)
-               *dsp = skl;
-
-       return ret;
-
-cleanup:
-       skl_sst_dsp_cleanup(dev, skl);
-       return ret;
+       return 0;
 }
-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)
 {
 
                        int irq, const char *fw_name,
                        struct skl_dsp_loader_ops loader_ops,
                        struct skl_sst **skl_sst);
+       int (*init_fw)(struct device *dev, struct skl_sst *ctx);
        void (*cleanup)(struct device *dev, struct skl_sst *ctx);
 };