1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3 * Copyright(c) 2022 MediaTek. All rights reserved.
4 *
5 * Author: Allen-KH Cheng <allen-kh.cheng@mediatek.com>
6 * Tinghan Shen <tinghan.shen@mediatek.com>
7 */
8
9 #include <sof/compiler_info.h>
10 #include <sof/debug/debug.h>
11 #include <sof/drivers/edma.h>
12 #include <rtos/interrupt.h>
13 #include <sof/ipc/msg.h>
14 #include <rtos/timer.h>
15 #include <sof/fw-ready-metadata.h>
16 #include <sof/lib/agent.h>
17 #include <rtos/clk.h>
18 #include <sof/lib/cpu.h>
19 #include <sof/lib/dai.h>
20 #include <sof/lib/dma.h>
21 #include <sof/lib/mailbox.h>
22 #include <sof/lib/memory.h>
23 #include <sof/lib/mm_heap.h>
24 #include <sof/platform.h>
25 #include <sof/schedule/edf_schedule.h>
26 #include <sof/schedule/ll_schedule.h>
27 #include <sof/schedule/ll_schedule_domain.h>
28 #include <rtos/sof.h>
29 #include <sof/trace/dma-trace.h>
30 #include <ipc/dai.h>
31 #include <ipc/header.h>
32 #include <ipc/info.h>
33 #include <kernel/abi.h>
34 #include <kernel/ext_manifest.h>
35 #include <sof_versions.h>
36 #include <errno.h>
37 #include <stdint.h>
38 #include <xtensa/hal.h>
39 #include <platform/drivers/timer.h>
40
41 struct sof;
42
43 static const struct sof_ipc_fw_ready ready
44 __section(".fw_ready") = {
45 .hdr = {
46 .cmd = SOF_IPC_FW_READY,
47 .size = sizeof(struct sof_ipc_fw_ready),
48 },
49 /* dspbox is for DSP initiated IPC, hostbox is for host initiated IPC */
50 .version = {
51 .hdr.size = sizeof(struct sof_ipc_fw_version),
52 .micro = SOF_MICRO,
53 .minor = SOF_MINOR,
54 .major = SOF_MAJOR,
55 .tag = SOF_TAG,
56 .abi_version = SOF_ABI_VERSION,
57 .src_hash = SOF_SRC_HASH,
58 },
59 .flags = DEBUG_SET_FW_READY_FLAGS,
60 };
61
62 #define NUM_MTK_WINDOWS 6
63
64 const struct ext_man_windows xsram_window
65 __aligned(EXT_MAN_ALIGN) __section(".fw_metadata") __unused = {
66 .hdr = {
67 .type = EXT_MAN_ELEM_WINDOW,
68 .elem_size = ALIGN_UP_COMPILE(sizeof(struct ext_man_windows), EXT_MAN_ALIGN),
69 },
70 .window = {
71 .ext_hdr = {
72 .hdr.cmd = SOF_IPC_FW_READY,
73 .hdr.size = sizeof(struct sof_ipc_window),
74 .type = SOF_IPC_EXT_WINDOW,
75 },
76 .num_windows = NUM_MTK_WINDOWS,
77 .window = {
78 {
79 .type = SOF_IPC_REGION_UPBOX,
80 .id = 0, /* map to host window 0 */
81 .flags = 0,
82 .size = MAILBOX_DSPBOX_SIZE,
83 .offset = MAILBOX_DSPBOX_OFFSET,
84 },
85 {
86 .type = SOF_IPC_REGION_DOWNBOX,
87 .id = 0, /* map to host window 0 */
88 .flags = 0,
89 .size = MAILBOX_HOSTBOX_SIZE,
90 .offset = MAILBOX_HOSTBOX_OFFSET,
91 },
92 {
93 .type = SOF_IPC_REGION_DEBUG,
94 .id = 0, /* map to host window 0 */
95 .flags = 0,
96 .size = MAILBOX_DEBUG_SIZE,
97 .offset = MAILBOX_DEBUG_OFFSET,
98 },
99 {
100 .type = SOF_IPC_REGION_TRACE,
101 .id = 0, /* map to host window 0 */
102 .flags = 0,
103 .size = MAILBOX_TRACE_SIZE,
104 .offset = MAILBOX_TRACE_OFFSET,
105 },
106 {
107 .type = SOF_IPC_REGION_STREAM,
108 .id = 0, /* map to host window 0 */
109 .flags = 0,
110 .size = MAILBOX_STREAM_SIZE,
111 .offset = MAILBOX_STREAM_OFFSET,
112 },
113 {
114 .type = SOF_IPC_REGION_EXCEPTION,
115 .id = 0, /* map to host window 0 */
116 .flags = 0,
117 .size = MAILBOX_EXCEPTION_SIZE,
118 .offset = MAILBOX_EXCEPTION_OFFSET,
119 },
120 },
121 }
122 };
123
124 static SHARED_DATA struct timer timer_shared = {
125 .id = OSTIMER0,
126 .irq = MTK_DSP_IRQ_OSTIMER32,
127 };
128
129 /* Override the default MPU setup. This table matches the memory map
130 * of the 'sample_controller' core and will need to be modified for
131 * other cores.
132 * NOTE: This table sets up all of external memory as shared uncached.
133 * For best results, edit the LSP memory map to create a separate
134 * section in shared memory, place all sections that need to be uncached
135 * into that section, and only map that section uncached. See README
136 * for more details.
137 */
138 const struct xthal_MPU_entry __xt_mpu_init_table[] __section(".ResetVector.text") = {
139 XTHAL_MPU_ENTRY(0x00000000, 1, XTHAL_AR_RWXrwx, XTHAL_MEM_DEVICE), // unused
140 XTHAL_MPU_ENTRY(0x4e100000, 1, XTHAL_AR_RWXrwx, XTHAL_MEM_WRITEBACK), // sram
141 XTHAL_MPU_ENTRY(0x4e180000, 1, XTHAL_AR_NONE, XTHAL_MEM_DEVICE), // unused
142 XTHAL_MPU_ENTRY(0x60000000, 1, XTHAL_AR_RWXrwx, XTHAL_MEM_WRITEBACK), // dram
143 XTHAL_MPU_ENTRY(0x60500000, 1, XTHAL_AR_RWXrwx, XTHAL_MEM_NON_CACHEABLE), // dram
144 XTHAL_MPU_ENTRY(0x61100000, 1, XTHAL_AR_NONE, XTHAL_MEM_DEVICE), // unused
145 };
146
147 const unsigned int __xt_mpu_init_table_size __section(".ResetVector.text") =
148 ARRAY_SIZE(__xt_mpu_init_table);
149
platform_boot_complete(uint32_t boot_message)150 int platform_boot_complete(uint32_t boot_message)
151 {
152 mailbox_dspbox_write(0, &ready, sizeof(ready));
153
154 /* now interrupt host to tell it we are done booting */
155 trigger_irq_to_host_req();
156
157 return 0;
158 }
159
160 extern void dump_adsppll(int line);
161
platform_init(struct sof * sof)162 int platform_init(struct sof *sof)
163 {
164 int ret;
165
166 sof->platform_timer = platform_shared_get(&timer_shared, sizeof(timer_shared));
167 sof->cpu_timers = sof->platform_timer;
168
169 platform_interrupt_init();
170 platform_clock_init(sof);
171
172 scheduler_init_edf();
173
174 /* init low latency domains and schedulers */
175 sof->platform_timer_domain = timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK);
176 scheduler_init_ll(sof->platform_timer_domain);
177 platform_timer_start(sof->platform_timer);
178
179 sa_init(sof, CONFIG_SYSTICK_PERIOD);
180
181 /* init DMA */
182 ret = dmac_init(sof);
183 if (ret < 0)
184 return -ENODEV;
185
186 /* Init platform domain */
187 sof->platform_dma_domain = dma_multi_chan_domain_init(&sof->dma_info->dma_array[0], 1,
188 PLATFORM_DEFAULT_CLOCK, false);
189 scheduler_init_ll(sof->platform_dma_domain);
190
191 /* initialize the host IPC mechanims */
192 ipc_init(sof);
193
194 ret = dai_init(sof);
195 if (ret < 0)
196 return ret;
197
198 #if CONFIG_TRACE
199 /* Initialize DMA for Trace*/
200 trace_point(TRACE_BOOT_PLATFORM_DMA_TRACE);
201 dma_trace_init_complete(sof->dmat);
202 #endif
203
204 /* show heap status */
205 heap_trace_all(1);
206
207 return 0;
208 }
209
platform_context_save(struct sof * sof)210 int platform_context_save(struct sof *sof)
211 {
212 clock_set_freq(CLK_CPU(cpu_get_id()), CLK_DEFAULT_CPU_HZ);
213 return 0;
214 }
215
platform_wait_for_interrupt(int level)216 void platform_wait_for_interrupt(int level)
217 {
218 arch_wait_for_interrupt(level);
219 }
220
221