diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index aeaa1af787dbae..265d34b2247e75 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -105,7 +105,7 @@ int hda_dsp_core_reset_leave(struct snd_sof_dev *sdev, unsigned int core_mask) int hda_dsp_core_stall_reset(struct snd_sof_dev *sdev, unsigned int core_mask) { /* stall core */ - snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_HDA_BAR, + snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPCS, HDA_DSP_ADSPCS_CSTALL_MASK(core_mask), HDA_DSP_ADSPCS_CSTALL_MASK(core_mask)); @@ -210,19 +210,6 @@ bool hda_dsp_core_is_enabled(struct snd_sof_dev *sdev, return is_enable; } -int hda_dsp_core_stall_reset_skl(struct snd_sof_dev *sdev, - unsigned int core_mask) -{ - /* stall core */ - snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR, - HDA_DSP_REG_ADSPCS, - HDA_DSP_ADSPCS_CSTALL_MASK(core_mask), - HDA_DSP_ADSPCS_CSTALL_MASK(core_mask)); - - /* set reset state */ - return hda_dsp_core_reset_enter(sdev, core_mask); -} - int hda_dsp_enable_core(struct snd_sof_dev *sdev, unsigned int core_mask) { int ret; diff --git a/sound/soc/sof/intel/hda-loader-skl.c b/sound/soc/sof/intel/hda-loader-skl.c index 092bdd98e86960..40e2b776e63e19 100644 --- a/sound/soc/sof/intel/hda-loader-skl.c +++ b/sound/soc/sof/intel/hda-loader-skl.c @@ -378,7 +378,7 @@ static int cl_dsp_init_skl(struct snd_sof_dev *sdev) /* polling the ROM init status information. */ ret = snd_sof_dsp_register_poll(sdev, HDA_DSP_BAR, - HDA_DSP_SRAM_REG_ROM_STATUS_SKL, + HDA_ADSP_FW_STATUS_SKL, HDA_DSP_ROM_STS_MASK, HDA_DSP_ROM_INIT, HDA_DSP_INIT_TIMEOUT); if (ret < 0) @@ -387,7 +387,7 @@ static int cl_dsp_init_skl(struct snd_sof_dev *sdev) return ret; err: - hda_dsp_dump(sdev, SOF_DBG_REGS | SOF_DBG_PCI | SOF_DBG_MBOX); + hda_dsp_dump_skl(sdev, SOF_DBG_REGS | SOF_DBG_PCI | SOF_DBG_MBOX); cl_cleanup_skl(sdev); hda_dsp_core_reset_power_down(sdev, HDA_DSP_CORE_MASK(0)); return ret; @@ -397,70 +397,23 @@ static void cl_skl_cldma_fill_buffer(struct snd_sof_dev *sdev, unsigned int bufsize, unsigned int copysize, const void *curr_pos, - bool intr_enable) + bool intr_enable, bool trigger) { /* 1. copy the image into the buffer with the maximum buffer size. */ unsigned int size = (bufsize == copysize) ? bufsize : copysize; memcpy(sdev->dmab.area, curr_pos, size); - /* 2. Setting the wait condition for every load. */ - sdev->code_loading = 1; - - /* 3. Set the interrupt. */ + /* 2. Set the interrupt. */ if (intr_enable) cl_skl_cldma_set_intr(sdev, true); - /* 4. Set the SPB. */ - cl_skl_cldma_setup_spb(sdev, size, true); - - /* 5. Trigger the code loading stream. */ - cl_skl_cldma_stream_run(sdev, true); -} - -static int cl_skl_cldma_wait_interruptible(struct snd_sof_dev *sdev) -{ - int ret = 0; + /* 3. Set the SPB. */ + cl_skl_cldma_setup_spb(sdev, size, trigger); - if (!wait_event_timeout(sdev->waitq, - !sdev->code_loading, - msecs_to_jiffies(HDA_SKL_WAIT_TIMEOUT))) { - dev_err(sdev->dev, "cldma copy timeout\n"); - dev_err(sdev->dev, "ROM 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)); - - /* TODO: temp debug to be removed */ - dev_err(sdev->dev, "ADSPCS=0x%x: ADSPIC=0x%x: ADSPIS=0x%x INTCTL=0x%x INTSTS=0x%x PPCTL=0x%x PPSTS=0x%x\n", - snd_sof_dsp_read(sdev, HDA_DSP_BAR, - HDA_DSP_REG_ADSPCS), - snd_sof_dsp_read(sdev, HDA_DSP_BAR, - HDA_DSP_REG_ADSPIC), - snd_sof_dsp_read(sdev, HDA_DSP_BAR, - HDA_DSP_REG_ADSPIS), - snd_sof_dsp_read(sdev, HDA_DSP_BAR, - SOF_HDA_INTCTL), - snd_sof_dsp_read(sdev, HDA_DSP_BAR, - SOF_HDA_INTSTS), - snd_sof_dsp_read(sdev, HDA_DSP_PP_BAR, - SOF_HDA_REG_PP_PPCTL), - snd_sof_dsp_read(sdev, HDA_DSP_PP_BAR, - SOF_HDA_REG_PP_PPSTS)); - ret = -EIO; - goto cleanup; - } - - dev_dbg(sdev->dev, "cldma buffer copy complete\n"); - if (!sdev->code_loading) { - dev_err(sdev->dev, "error: cldma DMA copy failed\n"); - ret = -EIO; - } - -cleanup: - sdev->code_loading = 0; - return ret; + /* 4. Trigger the code loading stream. */ + if (trigger) + cl_skl_cldma_stream_run(sdev, true); } static int @@ -482,9 +435,8 @@ cl_skl_cldma_copy_to_buf(struct snd_sof_dev *sdev, const void *bin, bufsize); cl_skl_cldma_fill_buffer(sdev, bufsize, bufsize, - curr_pos, true); + curr_pos, true, true); - ret = cl_skl_cldma_wait_interruptible(sdev); if (ret < 0) { dev_err(sdev->dev, "error: fw failed to load. 0x%x bytes remaining\n", bytes_left); @@ -501,7 +453,7 @@ cl_skl_cldma_copy_to_buf(struct snd_sof_dev *sdev, const void *bin, cl_skl_cldma_set_intr(sdev, false); cl_skl_cldma_fill_buffer(sdev, bufsize, bytes_left, - curr_pos, false); + curr_pos, false, false); return 0; } } @@ -526,7 +478,7 @@ static int cl_copy_fw_skl(struct snd_sof_dev *sdev) } ret = snd_sof_dsp_register_poll(sdev, HDA_DSP_BAR, - HDA_DSP_SRAM_REG_ROM_STATUS_SKL, + HDA_ADSP_FW_STATUS_SKL, HDA_DSP_ROM_STS_MASK, HDA_DSP_ROM_FW_FW_LOADED, HDA_DSP_BASEFW_TIMEOUT); @@ -551,9 +503,9 @@ int hda_dsp_cl_boot_firmware_skl(struct snd_sof_dev *sdev) 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), + HDA_ADSP_ERROR_CODE_SKL), snd_sof_dsp_read(sdev, HDA_DSP_BAR, - HDA_DSP_SRAM_REG_ROM_STATUS)); + HDA_ADSP_FW_STATUS_SKL)); dev_err(sdev->dev, "Core En/ROM load fail:%d\n", ret); goto irq_err; } @@ -579,7 +531,7 @@ int hda_dsp_cl_boot_firmware_skl(struct snd_sof_dev *sdev) return ret; irq_err: - hda_dsp_dump(sdev, SOF_DBG_REGS | SOF_DBG_PCI | SOF_DBG_MBOX); + hda_dsp_dump_skl(sdev, SOF_DBG_REGS | SOF_DBG_PCI | SOF_DBG_MBOX); /* power down DSP */ hda_dsp_core_reset_power_down(sdev, HDA_DSP_CORE_MASK(0)); diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 89fbb3321b55ec..67a3adc610c7a9 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -140,6 +140,26 @@ static const struct hda_dsp_msg_code hda_dsp_rom_msg[] = { {HDA_DSP_ROM_NULL_FW_ENTRY, "error: null FW entry point"}, }; +static void hda_dsp_get_status_skl(struct snd_sof_dev *sdev) +{ + u32 status; + int i; + + status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, + HDA_ADSP_FW_STATUS_SKL); + + for (i = 0; i < ARRAY_SIZE(hda_dsp_rom_msg); i++) { + if (status == hda_dsp_rom_msg[i].code) { + dev_err(sdev->dev, "%s - code %8.8x\n", + hda_dsp_rom_msg[i].msg, status); + return; + } + } + + /* not for us, must be generic sof message */ + dev_dbg(sdev->dev, "unknown ROM status value %8.8x\n", status); +} + static void hda_dsp_get_status(struct snd_sof_dev *sdev) { u32 status; @@ -178,6 +198,36 @@ static void hda_dsp_get_registers(struct snd_sof_dev *sdev, stack_words * sizeof(u32)); } +void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags) +{ + struct sof_ipc_dsp_oops_xtensa xoops; + struct sof_ipc_panic_info panic_info; + u32 stack[HDA_DSP_STACK_DUMP_SIZE]; + u32 status, panic; + + /* try APL specific status message types first */ + hda_dsp_get_status_skl(sdev); + + /* now try generic SOF status messages */ + status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, + HDA_ADSP_ERROR_CODE_SKL); + + /*TODO: Check: there is no define in spec, but it is used in the code*/ + panic = snd_sof_dsp_read(sdev, HDA_DSP_BAR, + HDA_ADSP_ERROR_CODE_SKL + 0x4); + + if (sdev->boot_complete) { + hda_dsp_get_registers(sdev, &xoops, &panic_info, stack, + HDA_DSP_STACK_DUMP_SIZE); + snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, + stack, HDA_DSP_STACK_DUMP_SIZE); + } else { + dev_err(sdev->dev, "error: status = 0x%8.8x panic = 0x%8.8x\n", + status, panic); + hda_dsp_get_status_skl(sdev); + } +} + void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags) { struct sof_ipc_dsp_oops_xtensa xoops; diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index c9c3e52508f00f..e1f0efcea62ed0 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -321,7 +321,12 @@ #define SOF_SKL_NUM_DAIS 8 #endif -#define HDA_DSP_SRAM_REG_ROM_STATUS_SKL 0x8000 +/* Intel HD Audio SRAM Window 0*/ +#define HDA_ADSP_SRAM0_BASE_SKL 0x8000 + +/* Firmware status window */ +#define HDA_ADSP_FW_STATUS_SKL HDA_ADSP_SRAM0_BASE_SKL +#define HDA_ADSP_ERROR_CODE_SKL (HDA_ADSP_FW_STATUS_SKL + 0x4) struct sof_intel_dsp_bdl { u32 addr_l; @@ -385,8 +390,6 @@ int hda_dsp_core_reset_enter(struct snd_sof_dev *sdev, int hda_dsp_core_reset_leave(struct snd_sof_dev *sdev, unsigned int core_mask); int hda_dsp_core_stall_reset(struct snd_sof_dev *sdev, unsigned int core_mask); -int hda_dsp_core_stall_reset_skl(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); @@ -399,6 +402,7 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, int state); int hda_dsp_resume(struct snd_sof_dev *sdev); int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev, int state); int hda_dsp_runtime_resume(struct snd_sof_dev *sdev); +void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags); void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags); /* diff --git a/sound/soc/sof/intel/skl.c b/sound/soc/sof/intel/skl.c index 43b0bc169438fe..c51923d019bb69 100644 --- a/sound/soc/sof/intel/skl.c +++ b/sound/soc/sof/intel/skl.c @@ -74,7 +74,7 @@ struct snd_sof_dsp_ops sof_skl_ops = { /* debug */ .debug_map = skl_dsp_debugfs, .debug_map_count = ARRAY_SIZE(skl_dsp_debugfs), - .dbg_dump = hda_dsp_dump, + .dbg_dump = hda_dsp_dump_skl, /* stream callbacks */ .pcm_open = hda_dsp_pcm_open,