diff options
| -rw-r--r-- | sound/soc/sof/imx/Kconfig | 8 | ||||
| -rw-r--r-- | sound/soc/sof/imx/Makefile | 3 | ||||
| -rw-r--r-- | sound/soc/sof/imx/imx-common.c | 72 | ||||
| -rw-r--r-- | sound/soc/sof/imx/imx-common.h | 16 | ||||
| -rw-r--r-- | sound/soc/sof/imx/imx8.c | 23 | ||||
| -rw-r--r-- | sound/soc/sof/imx/imx8m.c | 17 | 
6 files changed, 137 insertions, 2 deletions
diff --git a/sound/soc/sof/imx/Kconfig b/sound/soc/sof/imx/Kconfig index 23bfd79d09c3..48f998a19ddb 100644 --- a/sound/soc/sof/imx/Kconfig +++ b/sound/soc/sof/imx/Kconfig @@ -19,6 +19,12 @@ config SND_SOC_SOF_IMX_OF  	  This option is not user-selectable but automagically handled by  	  'select' statements at a higher level +config SND_SOC_SOF_IMX_COMMON +	tristate +	help +	  This option is not user-selectable but automagically handled by +	  'select' statements at a higher level. +  config SND_SOC_SOF_IMX8_SUPPORT  	bool "SOF support for i.MX8"  	depends on IMX_SCU=y || IMX_SCU=SND_SOC_SOF_IMX_OF @@ -30,6 +36,7 @@ config SND_SOC_SOF_IMX8_SUPPORT  config SND_SOC_SOF_IMX8  	tristate +	select SND_SOC_SOF_IMX_COMMON  	select SND_SOC_SOF_XTENSA  	help  	  This option is not user-selectable but automagically handled by @@ -45,6 +52,7 @@ config SND_SOC_SOF_IMX8M_SUPPORT  config SND_SOC_SOF_IMX8M  	tristate +	select SND_SOC_SOF_IMX_COMMON  	select SND_SOC_SOF_XTENSA  	help  	  This option is not user-selectable but automagically handled by diff --git a/sound/soc/sof/imx/Makefile b/sound/soc/sof/imx/Makefile index 2b933b02bbac..dba93c3466ec 100644 --- a/sound/soc/sof/imx/Makefile +++ b/sound/soc/sof/imx/Makefile @@ -2,5 +2,8 @@  snd-sof-imx8-objs := imx8.o  snd-sof-imx8m-objs := imx8m.o +snd-sof-imx-common-objs := imx-common.o +  obj-$(CONFIG_SND_SOC_SOF_IMX8) += snd-sof-imx8.o  obj-$(CONFIG_SND_SOC_SOF_IMX8M) += snd-sof-imx8m.o +obj-$(CONFIG_SND_SOC_SOF_IMX_COMMON) += imx-common.o diff --git a/sound/soc/sof/imx/imx-common.c b/sound/soc/sof/imx/imx-common.c new file mode 100644 index 000000000000..63d8a5d7bc44 --- /dev/null +++ b/sound/soc/sof/imx/imx-common.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// Copyright 2020 NXP +// +// Common helpers for the audio DSP on i.MX8 + +#include <sound/sof/xtensa.h> +#include "../ops.h" + +#include "imx-common.h" + +/** + * imx8_get_registers() - This function is called in case of DSP oops + * in order to gather information about the registers, filename and + * linenumber and stack. + * @sdev: SOF device + * @xoops: Stores information about registers. + * @panic_info: Stores information about filename and line number. + * @stack: Stores the stack dump. + * @stack_words: Size of the stack dump. + */ +void imx8_get_registers(struct snd_sof_dev *sdev, +			struct sof_ipc_dsp_oops_xtensa *xoops, +			struct sof_ipc_panic_info *panic_info, +			u32 *stack, size_t stack_words) +{ +	u32 offset = sdev->dsp_oops_offset; + +	/* first read registers */ +	sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops)); + +	/* then get panic info */ +	if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) { +		dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n", +			xoops->arch_hdr.totalsize); +		return; +	} +	offset += xoops->arch_hdr.totalsize; +	sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info)); + +	/* then get the stack */ +	offset += sizeof(*panic_info); +	sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32)); +} + +/** + * imx8_dump() - This function is called when a panic message is + * received from the firmware. + */ +void imx8_dump(struct snd_sof_dev *sdev, u32 flags) +{ +	struct sof_ipc_dsp_oops_xtensa xoops; +	struct sof_ipc_panic_info panic_info; +	u32 stack[IMX8_STACK_DUMP_SIZE]; +	u32 status; + +	/* Get information about the panic status from the debug box area. +	 * Compute the trace point based on the status. +	 */ +	sof_mailbox_read(sdev, sdev->debug_box.offset + 0x4, &status, 4); + +	/* Get information about the registers, the filename and line +	 * number and the stack. +	 */ +	imx8_get_registers(sdev, &xoops, &panic_info, stack, +			   IMX8_STACK_DUMP_SIZE); + +	/* Print the information to the console */ +	snd_sof_get_status(sdev, status, status, &xoops, &panic_info, stack, +			   IMX8_STACK_DUMP_SIZE); +} +EXPORT_SYMBOL(imx8_dump); diff --git a/sound/soc/sof/imx/imx-common.h b/sound/soc/sof/imx/imx-common.h new file mode 100644 index 000000000000..1cc7d6704182 --- /dev/null +++ b/sound/soc/sof/imx/imx-common.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ + +#ifndef __IMX_COMMON_H__ +#define __IMX_COMMON_H__ + +#define EXCEPT_MAX_HDR_SIZE	0x400 +#define IMX8_STACK_DUMP_SIZE 32 + +void imx8_get_registers(struct snd_sof_dev *sdev, +			struct sof_ipc_dsp_oops_xtensa *xoops, +			struct sof_ipc_panic_info *panic_info, +			u32 *stack, size_t stack_words); + +void imx8_dump(struct snd_sof_dev *sdev, u32 flags); + +#endif diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c index 3b9ffc760cb5..4e7dccadd7d0 100644 --- a/sound/soc/sof/imx/imx8.c +++ b/sound/soc/sof/imx/imx8.c @@ -21,6 +21,7 @@  #include <linux/firmware/imx/svc/misc.h>  #include <dt-bindings/firmware/imx/rsrc.h>  #include "../ops.h" +#include "imx-common.h"  /* DSP memories */  #define IRAM_OFFSET		0x10000 @@ -115,8 +116,16 @@ static void imx8_dsp_handle_reply(struct imx_dsp_ipc *ipc)  static void imx8_dsp_handle_request(struct imx_dsp_ipc *ipc)  {  	struct imx8_priv *priv = imx_dsp_get_data(ipc); +	u32 p; /* panic code */ -	snd_sof_ipc_msgs_rx(priv->sdev); +	/* Read the message from the debug box. */ +	sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4, &p, sizeof(p)); + +	/* Check to see if the message is a panic code (0x0dead***) */ +	if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) +		snd_sof_dsp_panic(priv->sdev, p); +	else +		snd_sof_ipc_msgs_rx(priv->sdev);  }  static struct imx_dsp_ops dsp_ops = { @@ -409,6 +418,9 @@ struct snd_sof_dsp_ops sof_imx8_ops = {  	.block_read	= sof_block_read,  	.block_write	= sof_block_write, +	/* Module IO */ +	.read64	= sof_io_read64, +  	/* ipc */  	.send_msg	= imx8_send_msg,  	.fw_ready	= sof_fw_ready, @@ -424,6 +436,9 @@ struct snd_sof_dsp_ops sof_imx8_ops = {  	/* firmware loading */  	.load_firmware	= snd_sof_load_firmware_memcpy, +	/* Debug information */ +	.dbg_dump = imx8_dump, +  	/* Firmware ops */  	.arch_ops = &sof_xtensa_arch_ops, @@ -452,6 +467,9 @@ struct snd_sof_dsp_ops sof_imx8x_ops = {  	.block_read	= sof_block_read,  	.block_write	= sof_block_write, +	/* Module IO */ +	.read64	= sof_io_read64, +  	/* ipc */  	.send_msg	= imx8_send_msg,  	.fw_ready	= sof_fw_ready, @@ -467,6 +485,9 @@ struct snd_sof_dsp_ops sof_imx8x_ops = {  	/* firmware loading */  	.load_firmware	= snd_sof_load_firmware_memcpy, +	/* Debug information */ +	.dbg_dump = imx8_dump, +  	/* Firmware ops */  	.arch_ops = &sof_xtensa_arch_ops, diff --git a/sound/soc/sof/imx/imx8m.c b/sound/soc/sof/imx/imx8m.c index ca23ac99a63d..cb822d953767 100644 --- a/sound/soc/sof/imx/imx8m.c +++ b/sound/soc/sof/imx/imx8m.c @@ -17,6 +17,7 @@  #include <linux/firmware/imx/dsp.h>  #include "../ops.h" +#include "imx-common.h"  #define MBOX_OFFSET	0x800000  #define MBOX_SIZE	0x1000 @@ -88,8 +89,16 @@ static void imx8m_dsp_handle_reply(struct imx_dsp_ipc *ipc)  static void imx8m_dsp_handle_request(struct imx_dsp_ipc *ipc)  {  	struct imx8m_priv *priv = imx_dsp_get_data(ipc); +	u32 p; /* Panic code */ -	snd_sof_ipc_msgs_rx(priv->sdev); +	/* Read the message from the debug box. */ +	sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4, &p, sizeof(p)); + +	/* Check to see if the message is a panic code (0x0dead***) */ +	if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) +		snd_sof_dsp_panic(priv->sdev, p); +	else +		snd_sof_ipc_msgs_rx(priv->sdev);  }  static struct imx_dsp_ops imx8m_dsp_ops = { @@ -262,6 +271,9 @@ struct snd_sof_dsp_ops sof_imx8m_ops = {  	.block_read	= sof_block_read,  	.block_write	= sof_block_write, +	/* Module IO */ +	.read64	= sof_io_read64, +  	/* ipc */  	.send_msg	= imx8m_send_msg,  	.fw_ready	= sof_fw_ready, @@ -277,6 +289,9 @@ struct snd_sof_dsp_ops sof_imx8m_ops = {  	/* firmware loading */  	.load_firmware	= snd_sof_load_firmware_memcpy, +	/* Debug information */ +	.dbg_dump = imx8_dump, +  	/* Firmware ops */  	.arch_ops = &sof_xtensa_arch_ops,  | 
