arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / sound / soc / sof / amd / acp-common.c
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2 //
3 // This file is provided under a dual BSD/GPLv2 license. When using or
4 // redistributing this file, you may do so under either license.
5 //
6 // Copyright(c) 2022 Advanced Micro Devices, Inc.
7 //
8 // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
9 //          V sujith kumar Reddy <Vsujithkumar.Reddy@amd.com>
10
11 /* ACP-specific Common code */
12
13 #include "../sof-priv.h"
14 #include "../sof-audio.h"
15 #include "../ops.h"
16 #include "../sof-audio.h"
17 #include "acp.h"
18 #include "acp-dsp-offset.h"
19 #include <sound/sof/xtensa.h>
20
21 /**
22  * amd_sof_ipc_dump() - This function is called when IPC tx times out.
23  * @sdev: SOF device.
24  */
25 void amd_sof_ipc_dump(struct snd_sof_dev *sdev)
26 {
27         const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
28         u32 base = desc->dsp_intr_base;
29         u32 dsp_msg_write = sdev->debug_box.offset +
30                             offsetof(struct scratch_ipc_conf, sof_dsp_msg_write);
31         u32 dsp_ack_write = sdev->debug_box.offset +
32                             offsetof(struct scratch_ipc_conf, sof_dsp_ack_write);
33         u32 host_msg_write = sdev->debug_box.offset +
34                              offsetof(struct scratch_ipc_conf, sof_host_msg_write);
35         u32 host_ack_write = sdev->debug_box.offset +
36                              offsetof(struct scratch_ipc_conf, sof_host_ack_write);
37         u32 dsp_msg, dsp_ack, host_msg, host_ack, irq_stat;
38
39         dsp_msg = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_msg_write);
40         dsp_ack = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + dsp_ack_write);
41         host_msg = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + host_msg_write);
42         host_ack = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + host_ack_write);
43         irq_stat = snd_sof_dsp_read(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET);
44
45         dev_err(sdev->dev,
46                 "dsp_msg = %#x dsp_ack = %#x host_msg = %#x host_ack = %#x irq_stat = %#x\n",
47                 dsp_msg, dsp_ack, host_msg, host_ack, irq_stat);
48 }
49
50 /**
51  * amd_get_registers() - This function is called in case of DSP oops
52  * in order to gather information about the registers, filename and
53  * linenumber and stack.
54  * @sdev: SOF device.
55  * @xoops: Stores information about registers.
56  * @panic_info: Stores information about filename and line number.
57  * @stack: Stores the stack dump.
58  * @stack_words: Size of the stack dump.
59  */
60 static void amd_get_registers(struct snd_sof_dev *sdev,
61                               struct sof_ipc_dsp_oops_xtensa *xoops,
62                               struct sof_ipc_panic_info *panic_info,
63                               u32 *stack, size_t stack_words)
64 {
65         u32 offset = sdev->dsp_oops_offset;
66
67         /* first read registers */
68         acp_mailbox_read(sdev, offset, xoops, sizeof(*xoops));
69
70         /* then get panic info */
71         if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) {
72                 dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n",
73                         xoops->arch_hdr.totalsize);
74                 return;
75         }
76
77         offset += xoops->arch_hdr.totalsize;
78         acp_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info));
79
80         /* then get the stack */
81         offset += sizeof(*panic_info);
82         acp_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32));
83 }
84
85 /**
86  * amd_sof_dump() - This function is called when a panic message is
87  * received from the firmware.
88  * @sdev: SOF device.
89  * @flags: parameter not used but required by ops prototype
90  */
91 void amd_sof_dump(struct snd_sof_dev *sdev, u32 flags)
92 {
93         struct sof_ipc_dsp_oops_xtensa xoops;
94         struct sof_ipc_panic_info panic_info;
95         u32 stack[AMD_STACK_DUMP_SIZE];
96         u32 status;
97
98         /* Get information about the panic status from the debug box area.
99          * Compute the trace point based on the status.
100          */
101         if (sdev->dsp_oops_offset > sdev->debug_box.offset) {
102                 acp_mailbox_read(sdev, sdev->debug_box.offset, &status, sizeof(u32));
103         } else {
104                 /* Read DSP Panic status from dsp_box.
105                  * As window information for exception box offset and size is not available
106                  * before FW_READY
107                  */
108                 acp_mailbox_read(sdev, sdev->dsp_box.offset, &status, sizeof(u32));
109                 sdev->dsp_oops_offset = sdev->dsp_box.offset + sizeof(status);
110         }
111
112         /* Get information about the registers, the filename and line
113          * number and the stack.
114          */
115         amd_get_registers(sdev, &xoops, &panic_info, stack, AMD_STACK_DUMP_SIZE);
116
117         /* Print the information to the console */
118         sof_print_oops_and_stack(sdev, KERN_ERR, status, status, &xoops,
119                                  &panic_info, stack, AMD_STACK_DUMP_SIZE);
120 }
121
122 struct snd_soc_acpi_mach *amd_sof_machine_select(struct snd_sof_dev *sdev)
123 {
124         struct snd_sof_pdata *sof_pdata = sdev->pdata;
125         const struct sof_dev_desc *desc = sof_pdata->desc;
126         struct snd_soc_acpi_mach *mach;
127
128         mach = snd_soc_acpi_find_machine(desc->machines);
129         if (!mach) {
130                 dev_warn(sdev->dev, "No matching ASoC machine driver found\n");
131                 return NULL;
132         }
133
134         sof_pdata->tplg_filename = mach->sof_tplg_filename;
135         sof_pdata->fw_filename = mach->fw_filename;
136
137         return mach;
138 }
139
140 /* AMD Common DSP ops */
141 struct snd_sof_dsp_ops sof_acp_common_ops = {
142         /* probe and remove */
143         .probe                  = amd_sof_acp_probe,
144         .remove                 = amd_sof_acp_remove,
145
146         /* Register IO */
147         .write                  = sof_io_write,
148         .read                   = sof_io_read,
149
150         /* Block IO */
151         .block_read             = acp_dsp_block_read,
152         .block_write            = acp_dsp_block_write,
153
154         /*Firmware loading */
155         .load_firmware          = snd_sof_load_firmware_memcpy,
156         .pre_fw_run             = acp_dsp_pre_fw_run,
157         .get_bar_index          = acp_get_bar_index,
158
159         /* DSP core boot */
160         .run                    = acp_sof_dsp_run,
161
162         /*IPC */
163         .send_msg               = acp_sof_ipc_send_msg,
164         .ipc_msg_data           = acp_sof_ipc_msg_data,
165         .set_stream_data_offset = acp_set_stream_data_offset,
166         .get_mailbox_offset     = acp_sof_ipc_get_mailbox_offset,
167         .get_window_offset      = acp_sof_ipc_get_window_offset,
168         .irq_thread             = acp_sof_ipc_irq_thread,
169
170         /* stream callbacks */
171         .pcm_open               = acp_pcm_open,
172         .pcm_close              = acp_pcm_close,
173         .pcm_hw_params          = acp_pcm_hw_params,
174         .pcm_pointer            = acp_pcm_pointer,
175
176         .hw_info                = SNDRV_PCM_INFO_MMAP |
177                                   SNDRV_PCM_INFO_MMAP_VALID |
178                                   SNDRV_PCM_INFO_INTERLEAVED |
179                                   SNDRV_PCM_INFO_PAUSE |
180                                   SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
181
182         /* Machine driver callbacks */
183         .machine_select         = amd_sof_machine_select,
184         .machine_register       = sof_machine_register,
185         .machine_unregister     = sof_machine_unregister,
186
187         /* Trace Logger */
188         .trace_init             = acp_sof_trace_init,
189         .trace_release          = acp_sof_trace_release,
190
191         /* PM */
192         .suspend                = amd_sof_acp_suspend,
193         .resume                 = amd_sof_acp_resume,
194
195         .ipc_dump               = amd_sof_ipc_dump,
196         .dbg_dump               = amd_sof_dump,
197         .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
198         .dsp_arch_ops = &sof_xtensa_arch_ops,
199
200         /* probe client device registation */
201         .register_ipc_clients = acp_probes_register,
202         .unregister_ipc_clients = acp_probes_unregister,
203 };
204 EXPORT_SYMBOL_NS(sof_acp_common_ops, SND_SOC_SOF_AMD_COMMON);
205
206 MODULE_IMPORT_NS(SND_SOC_SOF_AMD_COMMON);
207 MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
208 MODULE_DESCRIPTION("ACP SOF COMMON Driver");
209 MODULE_LICENSE("Dual BSD/GPL");