Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
0002 //
0003 // Copyright 2020 NXP
0004 //
0005 // Common helpers for the audio DSP on i.MX8
0006 
0007 #include <linux/module.h>
0008 #include <sound/sof/xtensa.h>
0009 #include "../ops.h"
0010 
0011 #include "imx-common.h"
0012 
0013 /**
0014  * imx8_get_registers() - This function is called in case of DSP oops
0015  * in order to gather information about the registers, filename and
0016  * linenumber and stack.
0017  * @sdev: SOF device
0018  * @xoops: Stores information about registers.
0019  * @panic_info: Stores information about filename and line number.
0020  * @stack: Stores the stack dump.
0021  * @stack_words: Size of the stack dump.
0022  */
0023 void imx8_get_registers(struct snd_sof_dev *sdev,
0024             struct sof_ipc_dsp_oops_xtensa *xoops,
0025             struct sof_ipc_panic_info *panic_info,
0026             u32 *stack, size_t stack_words)
0027 {
0028     u32 offset = sdev->dsp_oops_offset;
0029 
0030     /* first read registers */
0031     sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops));
0032 
0033     /* then get panic info */
0034     if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) {
0035         dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n",
0036             xoops->arch_hdr.totalsize);
0037         return;
0038     }
0039     offset += xoops->arch_hdr.totalsize;
0040     sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info));
0041 
0042     /* then get the stack */
0043     offset += sizeof(*panic_info);
0044     sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32));
0045 }
0046 
0047 /**
0048  * imx8_dump() - This function is called when a panic message is
0049  * received from the firmware.
0050  * @sdev: SOF device
0051  * @flags: parameter not used but required by ops prototype
0052  */
0053 void imx8_dump(struct snd_sof_dev *sdev, u32 flags)
0054 {
0055     struct sof_ipc_dsp_oops_xtensa xoops;
0056     struct sof_ipc_panic_info panic_info;
0057     u32 stack[IMX8_STACK_DUMP_SIZE];
0058     u32 status;
0059 
0060     /* Get information about the panic status from the debug box area.
0061      * Compute the trace point based on the status.
0062      */
0063     sof_mailbox_read(sdev, sdev->debug_box.offset + 0x4, &status, 4);
0064 
0065     /* Get information about the registers, the filename and line
0066      * number and the stack.
0067      */
0068     imx8_get_registers(sdev, &xoops, &panic_info, stack,
0069                IMX8_STACK_DUMP_SIZE);
0070 
0071     /* Print the information to the console */
0072     sof_print_oops_and_stack(sdev, KERN_ERR, status, status, &xoops,
0073                  &panic_info, stack, IMX8_STACK_DUMP_SIZE);
0074 }
0075 EXPORT_SYMBOL(imx8_dump);
0076 
0077 int imx8_parse_clocks(struct snd_sof_dev *sdev, struct imx_clocks *clks)
0078 {
0079     int ret;
0080 
0081     ret = devm_clk_bulk_get(sdev->dev, clks->num_dsp_clks, clks->dsp_clks);
0082     if (ret)
0083         dev_err(sdev->dev, "Failed to request DSP clocks\n");
0084 
0085     return ret;
0086 }
0087 EXPORT_SYMBOL(imx8_parse_clocks);
0088 
0089 int imx8_enable_clocks(struct snd_sof_dev *sdev, struct imx_clocks *clks)
0090 {
0091     return clk_bulk_prepare_enable(clks->num_dsp_clks, clks->dsp_clks);
0092 }
0093 EXPORT_SYMBOL(imx8_enable_clocks);
0094 
0095 void imx8_disable_clocks(struct snd_sof_dev *sdev, struct imx_clocks *clks)
0096 {
0097     clk_bulk_disable_unprepare(clks->num_dsp_clks, clks->dsp_clks);
0098 }
0099 EXPORT_SYMBOL(imx8_disable_clocks);
0100 
0101 MODULE_LICENSE("Dual BSD/GPL");