Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ASoC: SOF: skl enable the core and get ROM init #120

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove this func if its not needed.

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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

magic number 0x40, please use a macro

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);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need comment here, what are we polling for.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments added.

/* 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