Skip to content

Commit

Permalink
ASoC:SOF:skl:enable the core and get the ROM init
Browse files Browse the repository at this point in the history
1. enable the skl core
2. get the ROM int

Signed-off-by: Zhu Yingjiang <yingjiang.zhu@linux.intel.com>
  • Loading branch information
zhuyingjiang committed Sep 12, 2018
1 parent 66dc735 commit 2310452
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 1 deletion.
15 changes: 15 additions & 0 deletions sound/soc/sof/intel/hda-dsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,21 @@ bool hda_dsp_core_is_enabled(struct snd_sof_dev *sdev,
return is_enable;
}

int hda_dsp_enable_core(struct snd_sof_dev *sdev, unsigned int core_mask)
{
int ret;

/* power up */
ret = hda_dsp_core_power_up(sdev, core_mask);
if (ret < 0) {
dev_err(sdev->dev, "dsp core power up failed: core_mask %x\n",
core_mask);
return ret;
}

return hda_dsp_core_run(sdev, core_mask);
}

int hda_dsp_core_reset_power_down(struct snd_sof_dev *sdev,
unsigned int core_mask)
{
Expand Down
153 changes: 153 additions & 0 deletions sound/soc/sof/intel/hda-loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,3 +372,156 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
dev_err(sdev->dev, "error: load fw failed err: %d\n", ret);
return ret;
}

/*
* skl/kbl enable core and code loader DMA has some difference with apl/cnl
* add the APIs for skl/kbl
*/
static int cl_stream_prepare_skl(struct snd_sof_dev *sdev, unsigned int format,
unsigned int size, struct snd_dma_buffer *dmab,
int direction)
{
/* the skl cl dma don't use stream tag, ret is for debug */
int ret = 0;
return ret;
}

static int cl_dsp_init_skl(struct snd_sof_dev *sdev, const void *fwdata,
u32 fwsize)
{
const struct sof_intel_dsp_desc *chip = sdev->hda->desc;
int ret, i;
u32 hipcie;
u32 reg;

/* check if the core is already enabled, if yes, reset and make it run,
* if not, powerdown and enable it again.
*/
if (hda_dsp_core_is_enabled(sdev, HDA_DSP_CORE_MASK(0))) {
/* if enabled, reset it, and run the core. */
ret = hda_dsp_core_stall_reset(sdev, HDA_DSP_CORE_MASK(0));
if (ret < 0)
goto err;

ret = hda_dsp_core_run(sdev, HDA_DSP_CORE_MASK(0));
if (ret < 0) {
dev_err(sdev->dev, "error: dsp core start failed %d\n",
ret);
ret = -EIO;
goto err;
}
} else {
/* if not enabled, power down it first and then powerup and run
* the core.
*/
ret = hda_dsp_core_reset_power_down(sdev, HDA_DSP_CORE_MASK(0));
if (ret < 0) {
dev_err(sdev->dev, "dsp core0 disable fail: %d\n", ret);
return ret;
}
ret = hda_dsp_enable_core(sdev, HDA_DSP_CORE_MASK(0));
}

/* prepare DMA for code loader stream */
ret = cl_stream_prepare_skl(sdev, 0x40, fwsize, &sdev->dmab,
SNDRV_PCM_STREAM_PLAYBACK);

if (ret <= 0) {
dev_err(sdev->dev, "error: dma prepare fw loading err: %x\n",
ret);
return ret;
}

memcpy(sdev->dmab.area, fwdata, fwsize);

/* enable the interrupt */
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC,
HDA_DSP_ADSPIC_IPC, HDA_DSP_ADSPIC_IPC);

/* enable IPC DONE interrupt */
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl,
HDA_DSP_REG_HIPCCTL_DONE,
HDA_DSP_REG_HIPCCTL_DONE);

/* enable IPC BUSY interrupt */
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl,
HDA_DSP_REG_HIPCCTL_BUSY,
HDA_DSP_REG_HIPCCTL_BUSY);

/* polling the ROM init status information. */
ret = snd_sof_dsp_register_poll(sdev, HDA_DSP_BAR,
HDA_DSP_SRAM_REG_ROM_STATUS_SKL,
HDA_DSP_ROM_STS_MASK, HDA_DSP_ROM_INIT,
HDA_DSP_INIT_TIMEOUT);
if (ret >= 0) {
dev_err(sdev->dev, "error: can't read the ROM status!");
goto out;
}

ret = -EIO;

err:
hda_dsp_dump(sdev, SOF_DBG_REGS | SOF_DBG_PCI | SOF_DBG_MBOX);
hda_dsp_core_reset_power_down(sdev, HDA_DSP_CORE_MASK(0));
out:
return ret;
}

static int cl_copy_fw_skl(struct snd_sof_dev *sdev)
{
return -1;
}

int hda_dsp_cl_boot_firmware_skl(struct snd_sof_dev *sdev)
{
struct snd_sof_pdata *plat_data = dev_get_platdata(sdev->dev);
struct firmware stripped_firmware;
int ret;

stripped_firmware.data = plat_data->fw->data;
stripped_firmware.size = plat_data->fw->size;

ret = cl_dsp_init_skl(sdev, stripped_firmware.data,
stripped_firmware.size);

/* retry enabling core and ROM load. seemed to help */
if (ret < 0) {
ret = cl_dsp_init_skl(sdev, stripped_firmware.data,
stripped_firmware.size);
if (ret <= 0) {
dev_err(sdev->dev, "Error code=0x%x: FW status=0x%x\n",
snd_sof_dsp_read(sdev, HDA_DSP_BAR,
HDA_DSP_SRAM_REG_ROM_ERROR),
snd_sof_dsp_read(sdev, HDA_DSP_BAR,
HDA_DSP_SRAM_REG_ROM_STATUS));
dev_err(sdev->dev, "Core En/ROM load fail:%d\n", ret);
goto irq_err;
}
}

/* init for booting wait */
init_waitqueue_head(&sdev->boot_wait);
sdev->boot_complete = false;

/* at this point DSP ROM has been initialized and should be ready for
* code loading and firmware boot
*/
ret = cl_copy_fw_skl(sdev);
if (ret < 0) {
dev_err(sdev->dev, "error: load fw failed err: %d\n", ret);
goto irq_err;
}

dev_dbg(sdev->dev, "Firmware download successful, booting...\n");

return ret;

irq_err:
hda_dsp_dump(sdev, SOF_DBG_REGS | SOF_DBG_PCI | SOF_DBG_MBOX);

/* disable DSP */
snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
SOF_HDA_PPCTL_GPROCEN, 0);
dev_err(sdev->dev, "error: load fw failed err: %d\n", ret);
return ret;
}
4 changes: 4 additions & 0 deletions sound/soc/sof/intel/hda.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@
#define SOF_SKL_NUM_DAIS 8
#endif

#define HDA_DSP_SRAM_REG_ROM_STATUS_SKL 0x8000

struct sof_intel_dsp_bdl {
u32 addr_l;
u32 addr_h;
Expand Down Expand Up @@ -377,6 +379,7 @@ int hda_dsp_core_reset_leave(struct snd_sof_dev *sdev,
int hda_dsp_core_stall_reset(struct snd_sof_dev *sdev, unsigned int core_mask);
int hda_dsp_core_run(struct snd_sof_dev *sdev, unsigned int core_mask);
int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask);
int hda_dsp_enable_core(struct snd_sof_dev *sdev, unsigned int core_mask);
int hda_dsp_core_power_down(struct snd_sof_dev *sdev, unsigned int core_mask);
bool hda_dsp_core_is_enabled(struct snd_sof_dev *sdev,
unsigned int core_mask);
Expand Down Expand Up @@ -466,6 +469,7 @@ int hda_dsp_ipc_cmd_done(struct snd_sof_dev *sdev, int dir);
*/
int hda_dsp_cl_load_fw(struct snd_sof_dev *sdev, bool first_boot);
int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev);
int hda_dsp_cl_boot_firmware_skl(struct snd_sof_dev *sdev);

/*
* HDA Controller Operations.
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/sof/intel/skl.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ struct snd_sof_dsp_ops sof_skl_ops = {
.load_firmware = hda_dsp_cl_load_fw,

/* firmware run */
.run = hda_dsp_cl_boot_firmware,
.run = hda_dsp_cl_boot_firmware_skl,

/* trace callback */
.trace_init = hda_dsp_trace_init,
Expand Down

0 comments on commit 2310452

Please sign in to comment.