xref: /openbmc/linux/sound/soc/sof/imx/imx-common.c (revision 18ebffe4d043bf5f3a9b669d8d91f855bde8f6b7)
1*18ebffe4SIulian Olaru // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2*18ebffe4SIulian Olaru //
3*18ebffe4SIulian Olaru // Copyright 2020 NXP
4*18ebffe4SIulian Olaru //
5*18ebffe4SIulian Olaru // Common helpers for the audio DSP on i.MX8
6*18ebffe4SIulian Olaru 
7*18ebffe4SIulian Olaru #include <sound/sof/xtensa.h>
8*18ebffe4SIulian Olaru #include "../ops.h"
9*18ebffe4SIulian Olaru 
10*18ebffe4SIulian Olaru #include "imx-common.h"
11*18ebffe4SIulian Olaru 
12*18ebffe4SIulian Olaru /**
13*18ebffe4SIulian Olaru  * imx8_get_registers() - This function is called in case of DSP oops
14*18ebffe4SIulian Olaru  * in order to gather information about the registers, filename and
15*18ebffe4SIulian Olaru  * linenumber and stack.
16*18ebffe4SIulian Olaru  * @sdev: SOF device
17*18ebffe4SIulian Olaru  * @xoops: Stores information about registers.
18*18ebffe4SIulian Olaru  * @panic_info: Stores information about filename and line number.
19*18ebffe4SIulian Olaru  * @stack: Stores the stack dump.
20*18ebffe4SIulian Olaru  * @stack_words: Size of the stack dump.
21*18ebffe4SIulian Olaru  */
22*18ebffe4SIulian Olaru void imx8_get_registers(struct snd_sof_dev *sdev,
23*18ebffe4SIulian Olaru 			struct sof_ipc_dsp_oops_xtensa *xoops,
24*18ebffe4SIulian Olaru 			struct sof_ipc_panic_info *panic_info,
25*18ebffe4SIulian Olaru 			u32 *stack, size_t stack_words)
26*18ebffe4SIulian Olaru {
27*18ebffe4SIulian Olaru 	u32 offset = sdev->dsp_oops_offset;
28*18ebffe4SIulian Olaru 
29*18ebffe4SIulian Olaru 	/* first read registers */
30*18ebffe4SIulian Olaru 	sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops));
31*18ebffe4SIulian Olaru 
32*18ebffe4SIulian Olaru 	/* then get panic info */
33*18ebffe4SIulian Olaru 	if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) {
34*18ebffe4SIulian Olaru 		dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n",
35*18ebffe4SIulian Olaru 			xoops->arch_hdr.totalsize);
36*18ebffe4SIulian Olaru 		return;
37*18ebffe4SIulian Olaru 	}
38*18ebffe4SIulian Olaru 	offset += xoops->arch_hdr.totalsize;
39*18ebffe4SIulian Olaru 	sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info));
40*18ebffe4SIulian Olaru 
41*18ebffe4SIulian Olaru 	/* then get the stack */
42*18ebffe4SIulian Olaru 	offset += sizeof(*panic_info);
43*18ebffe4SIulian Olaru 	sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32));
44*18ebffe4SIulian Olaru }
45*18ebffe4SIulian Olaru 
46*18ebffe4SIulian Olaru /**
47*18ebffe4SIulian Olaru  * imx8_dump() - This function is called when a panic message is
48*18ebffe4SIulian Olaru  * received from the firmware.
49*18ebffe4SIulian Olaru  */
50*18ebffe4SIulian Olaru void imx8_dump(struct snd_sof_dev *sdev, u32 flags)
51*18ebffe4SIulian Olaru {
52*18ebffe4SIulian Olaru 	struct sof_ipc_dsp_oops_xtensa xoops;
53*18ebffe4SIulian Olaru 	struct sof_ipc_panic_info panic_info;
54*18ebffe4SIulian Olaru 	u32 stack[IMX8_STACK_DUMP_SIZE];
55*18ebffe4SIulian Olaru 	u32 status;
56*18ebffe4SIulian Olaru 
57*18ebffe4SIulian Olaru 	/* Get information about the panic status from the debug box area.
58*18ebffe4SIulian Olaru 	 * Compute the trace point based on the status.
59*18ebffe4SIulian Olaru 	 */
60*18ebffe4SIulian Olaru 	sof_mailbox_read(sdev, sdev->debug_box.offset + 0x4, &status, 4);
61*18ebffe4SIulian Olaru 
62*18ebffe4SIulian Olaru 	/* Get information about the registers, the filename and line
63*18ebffe4SIulian Olaru 	 * number and the stack.
64*18ebffe4SIulian Olaru 	 */
65*18ebffe4SIulian Olaru 	imx8_get_registers(sdev, &xoops, &panic_info, stack,
66*18ebffe4SIulian Olaru 			   IMX8_STACK_DUMP_SIZE);
67*18ebffe4SIulian Olaru 
68*18ebffe4SIulian Olaru 	/* Print the information to the console */
69*18ebffe4SIulian Olaru 	snd_sof_get_status(sdev, status, status, &xoops, &panic_info, stack,
70*18ebffe4SIulian Olaru 			   IMX8_STACK_DUMP_SIZE);
71*18ebffe4SIulian Olaru }
72*18ebffe4SIulian Olaru EXPORT_SYMBOL(imx8_dump);
73