Skip to content
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)
Copy link
Member

Choose a reason for hiding this comment

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

Generally f you have to number features in a patch commit message it means the patch needs split into more smaller patches

{
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;
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't we return 0 here for success ?


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

Choose a reason for hiding this comment

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

This needs removed for merge

}

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
4 changes: 2 additions & 2 deletions sound/soc/sof/sof-pci-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,10 @@ static const struct sof_ops_table mach_ops[] = {
{&cnl_desc, &sof_cnl_ops},
#endif
#if IS_ENABLED(CONFIG_SND_SOC_SOF_SKYLAKE)
{&skl_desc, &sof_apl_ops},
{&skl_desc, &sof_skl_ops},
#endif
#if IS_ENABLED(CONFIG_SND_SOC_SOF_KABYLAKE)
{&kbl_desc, &sof_apl_ops},
{&kbl_desc, &sof_skl_ops},
#endif
#if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE)
{&icl_desc, &sof_cnl_ops},
Expand Down