mirror of
https://github.com/torvalds/linux.git
synced 2024-12-11 05:33:09 +00:00
ASoC: SOF: ipc4/Intel: Improve and enable IPC error dump
Merge series from Peter Ujfalusi <peter.ujfalusi@linux.intel.com>: On Intel platforms the registers for DSP communications are used differently, the IPC dump information is not correct since important registers are not printed and existing ones are used a bit differently for IPC4. As a last step, enable the IPC timeout 'handling' and allow the printout of the now usefull IPC dump.
This commit is contained in:
commit
e9b0ff9336
@ -45,6 +45,9 @@ int sof_apl_ops_init(struct snd_sof_dev *sdev)
|
||||
|
||||
/* ipc */
|
||||
sof_apl_ops.send_msg = hda_dsp_ipc_send_msg;
|
||||
|
||||
/* debug */
|
||||
sof_apl_ops.ipc_dump = hda_ipc_dump;
|
||||
}
|
||||
|
||||
if (sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
|
||||
@ -64,6 +67,9 @@ int sof_apl_ops_init(struct snd_sof_dev *sdev)
|
||||
|
||||
/* ipc */
|
||||
sof_apl_ops.send_msg = hda_dsp_ipc4_send_msg;
|
||||
|
||||
/* debug */
|
||||
sof_apl_ops.ipc_dump = hda_ipc4_dump;
|
||||
}
|
||||
|
||||
/* set DAI driver ops */
|
||||
@ -72,7 +78,6 @@ int sof_apl_ops_init(struct snd_sof_dev *sdev)
|
||||
/* debug */
|
||||
sof_apl_ops.debug_map = apl_dsp_debugfs;
|
||||
sof_apl_ops.debug_map_count = ARRAY_SIZE(apl_dsp_debugfs);
|
||||
sof_apl_ops.ipc_dump = hda_ipc_dump;
|
||||
|
||||
/* firmware run */
|
||||
sof_apl_ops.run = hda_dsp_cl_boot_firmware;
|
||||
|
@ -332,6 +332,27 @@ void cnl_ipc_dump(struct snd_sof_dev *sdev)
|
||||
hipcida, hipctdr, hipcctl);
|
||||
}
|
||||
|
||||
void cnl_ipc4_dump(struct snd_sof_dev *sdev)
|
||||
{
|
||||
u32 hipcidr, hipcidd, hipcida, hipctdr, hipctdd, hipctda, hipcctl;
|
||||
|
||||
hda_ipc_irq_dump(sdev);
|
||||
|
||||
hipcidr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDR);
|
||||
hipcidd = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDD);
|
||||
hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDA);
|
||||
hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCTDR);
|
||||
hipctdd = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCTDD);
|
||||
hipctda = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCTDA);
|
||||
hipcctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCCTL);
|
||||
|
||||
/* dump the IPC regs */
|
||||
/* TODO: parse the raw msg */
|
||||
dev_err(sdev->dev,
|
||||
"Host IPC initiator: %#x|%#x|%#x, target: %#x|%#x|%#x, ctl: %#x\n",
|
||||
hipcidr, hipcidd, hipcida, hipctdr, hipctdd, hipctda, hipcctl);
|
||||
}
|
||||
|
||||
/* cannonlake ops */
|
||||
struct snd_sof_dsp_ops sof_cnl_ops;
|
||||
EXPORT_SYMBOL_NS(sof_cnl_ops, SND_SOC_SOF_INTEL_HDA_COMMON);
|
||||
@ -351,6 +372,9 @@ int sof_cnl_ops_init(struct snd_sof_dev *sdev)
|
||||
|
||||
/* ipc */
|
||||
sof_cnl_ops.send_msg = cnl_ipc_send_msg;
|
||||
|
||||
/* debug */
|
||||
sof_cnl_ops.ipc_dump = cnl_ipc_dump;
|
||||
}
|
||||
|
||||
if (sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
|
||||
@ -370,6 +394,9 @@ int sof_cnl_ops_init(struct snd_sof_dev *sdev)
|
||||
|
||||
/* ipc */
|
||||
sof_cnl_ops.send_msg = cnl_ipc4_send_msg;
|
||||
|
||||
/* debug */
|
||||
sof_cnl_ops.ipc_dump = cnl_ipc4_dump;
|
||||
}
|
||||
|
||||
/* set DAI driver ops */
|
||||
@ -378,7 +405,6 @@ int sof_cnl_ops_init(struct snd_sof_dev *sdev)
|
||||
/* debug */
|
||||
sof_cnl_ops.debug_map = cnl_dsp_debugfs;
|
||||
sof_cnl_ops.debug_map_count = ARRAY_SIZE(cnl_dsp_debugfs);
|
||||
sof_cnl_ops.ipc_dump = cnl_ipc_dump;
|
||||
|
||||
/* pre/post fw run */
|
||||
sof_cnl_ops.post_fw_run = hda_dsp_post_fw_run;
|
||||
|
@ -51,5 +51,6 @@
|
||||
irqreturn_t cnl_ipc_irq_thread(int irq, void *context);
|
||||
int cnl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg);
|
||||
void cnl_ipc_dump(struct snd_sof_dev *sdev);
|
||||
void cnl_ipc4_dump(struct snd_sof_dev *sdev);
|
||||
|
||||
#endif
|
||||
|
@ -598,7 +598,8 @@ void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
|
||||
/* print ROM/FW status */
|
||||
hda_dsp_get_state(sdev, level);
|
||||
|
||||
if (flags & SOF_DBG_DUMP_REGS) {
|
||||
/* The firmware register dump only available with IPC3 */
|
||||
if (flags & SOF_DBG_DUMP_REGS && sdev->pdata->ipc_type == SOF_IPC) {
|
||||
u32 status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_FW_STATUS);
|
||||
u32 panic = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_FW_TRACEP);
|
||||
|
||||
@ -662,6 +663,24 @@ void hda_ipc_dump(struct snd_sof_dev *sdev)
|
||||
hipcie, hipct, hipcctl);
|
||||
}
|
||||
|
||||
void hda_ipc4_dump(struct snd_sof_dev *sdev)
|
||||
{
|
||||
u32 hipci, hipcie, hipct, hipcte, hipcctl;
|
||||
|
||||
hda_ipc_irq_dump(sdev);
|
||||
|
||||
hipci = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCI);
|
||||
hipcie = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCIE);
|
||||
hipct = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCT);
|
||||
hipcte = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCTE);
|
||||
hipcctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCCTL);
|
||||
|
||||
/* dump the IPC regs */
|
||||
/* TODO: parse the raw msg */
|
||||
dev_err(sdev->dev, "Host IPC initiator: %#x|%#x, target: %#x|%#x, ctl: %#x\n",
|
||||
hipci, hipcie, hipct, hipcte, hipcctl);
|
||||
}
|
||||
|
||||
static int hda_init(struct snd_sof_dev *sdev)
|
||||
{
|
||||
struct hda_bus *hbus;
|
||||
|
@ -853,6 +853,7 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context);
|
||||
int cnl_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg);
|
||||
irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context);
|
||||
int hda_dsp_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg);
|
||||
void hda_ipc4_dump(struct snd_sof_dev *sdev);
|
||||
extern struct sdw_intel_ops sdw_callback;
|
||||
|
||||
#endif
|
||||
|
@ -113,6 +113,9 @@ int sof_icl_ops_init(struct snd_sof_dev *sdev)
|
||||
|
||||
/* ipc */
|
||||
sof_icl_ops.send_msg = cnl_ipc_send_msg;
|
||||
|
||||
/* debug */
|
||||
sof_icl_ops.ipc_dump = cnl_ipc_dump;
|
||||
}
|
||||
|
||||
if (sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
|
||||
@ -132,12 +135,14 @@ int sof_icl_ops_init(struct snd_sof_dev *sdev)
|
||||
|
||||
/* ipc */
|
||||
sof_icl_ops.send_msg = cnl_ipc4_send_msg;
|
||||
|
||||
/* debug */
|
||||
sof_icl_ops.ipc_dump = cnl_ipc4_dump;
|
||||
}
|
||||
|
||||
/* debug */
|
||||
sof_icl_ops.debug_map = icl_dsp_debugfs;
|
||||
sof_icl_ops.debug_map_count = ARRAY_SIZE(icl_dsp_debugfs);
|
||||
sof_icl_ops.ipc_dump = cnl_ipc_dump;
|
||||
|
||||
/* pre/post fw run */
|
||||
sof_icl_ops.post_fw_run = icl_dsp_post_fw_run;
|
||||
|
@ -573,20 +573,19 @@ static int mtl_dsp_ipc_get_window_offset(struct snd_sof_dev *sdev, u32 id)
|
||||
|
||||
static void mtl_ipc_dump(struct snd_sof_dev *sdev)
|
||||
{
|
||||
u32 hipcctl;
|
||||
u32 hipcida;
|
||||
u32 hipctdr;
|
||||
u32 hipcidr, hipcidd, hipcida, hipctdr, hipctdd, hipctda, hipcctl;
|
||||
|
||||
/* read IPC status */
|
||||
hipcidr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDR);
|
||||
hipcidd = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDDY);
|
||||
hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDA);
|
||||
hipcctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXCTL);
|
||||
hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDR);
|
||||
hipctdd = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDDY);
|
||||
hipctda = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDA);
|
||||
hipcctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXCTL);
|
||||
|
||||
/* dump the IPC regs */
|
||||
/* TODO: parse the raw msg */
|
||||
dev_err(sdev->dev,
|
||||
"error: host status 0x%8.8x dsp status 0x%8.8x mask 0x%8.8x\n",
|
||||
hipcida, hipctdr, hipcctl);
|
||||
"Host IPC initiator: %#x|%#x|%#x, target: %#x|%#x|%#x, ctl: %#x\n",
|
||||
hipcidr, hipcidd, hipcida, hipctdr, hipctdd, hipctda, hipcctl);
|
||||
}
|
||||
|
||||
static int mtl_dsp_disable_interrupts(struct snd_sof_dev *sdev)
|
||||
|
@ -87,7 +87,7 @@ int sof_skl_ops_init(struct snd_sof_dev *sdev)
|
||||
/* debug */
|
||||
sof_skl_ops.debug_map = skl_dsp_debugfs;
|
||||
sof_skl_ops.debug_map_count = ARRAY_SIZE(skl_dsp_debugfs);
|
||||
sof_skl_ops.ipc_dump = hda_ipc_dump;
|
||||
sof_skl_ops.ipc_dump = hda_ipc4_dump;
|
||||
|
||||
/* firmware run */
|
||||
sof_skl_ops.run = hda_dsp_cl_boot_firmware_skl;
|
||||
|
@ -68,6 +68,9 @@ int sof_tgl_ops_init(struct snd_sof_dev *sdev)
|
||||
|
||||
/* ipc */
|
||||
sof_tgl_ops.send_msg = cnl_ipc_send_msg;
|
||||
|
||||
/* debug */
|
||||
sof_tgl_ops.ipc_dump = cnl_ipc_dump;
|
||||
}
|
||||
|
||||
if (sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
|
||||
@ -87,6 +90,9 @@ int sof_tgl_ops_init(struct snd_sof_dev *sdev)
|
||||
|
||||
/* ipc */
|
||||
sof_tgl_ops.send_msg = cnl_ipc4_send_msg;
|
||||
|
||||
/* debug */
|
||||
sof_tgl_ops.ipc_dump = cnl_ipc4_dump;
|
||||
}
|
||||
|
||||
/* set DAI driver ops */
|
||||
@ -95,7 +101,6 @@ int sof_tgl_ops_init(struct snd_sof_dev *sdev)
|
||||
/* debug */
|
||||
sof_tgl_ops.debug_map = tgl_dsp_debugfs;
|
||||
sof_tgl_ops.debug_map_count = ARRAY_SIZE(tgl_dsp_debugfs);
|
||||
sof_tgl_ops.ipc_dump = cnl_ipc_dump;
|
||||
|
||||
/* pre/post fw run */
|
||||
sof_tgl_ops.post_fw_run = hda_dsp_post_fw_run;
|
||||
|
@ -295,6 +295,7 @@ static int ipc4_wait_tx_done(struct snd_sof_ipc *ipc, void *reply_data)
|
||||
if (ret == 0) {
|
||||
dev_err(sdev->dev, "ipc timed out for %#x|%#x\n",
|
||||
ipc4_msg->primary, ipc4_msg->extension);
|
||||
snd_sof_handle_fw_exception(ipc->sdev, "IPC timeout");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user