1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * Copyright(c) 2021 MediaTek. All rights reserved.
4  *
5  * Author: YC Hung <yc.hung@mediatek.com>
6  *         Allen-KH Cheng <allen-kh.cheng@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 <platform/drivers/timer.h>
31 #include <ipc/dai.h>
32 #include <ipc/header.h>
33 #include <ipc/info.h>
34 #include <kernel/abi.h>
35 #include <kernel/ext_manifest.h>
36 #include <sof_versions.h>
37 #include <errno.h>
38 #include <stdint.h>
39 #include <xtensa/hal.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, /* TODO: set later */
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, /* TODO: set later */
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, /* TODO: set later */
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, /* TODO: set later */
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, /* TODO: set later */
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, /* TODO: set later */
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 = LX_ADSP_TIMTER_IRQ0_B,
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 unsigned int __xt_mpu_init_table_size __attribute__((section(".ResetVector.text"))) = 11;
139 
140 const struct xthal_MPU_entry __xt_mpu_init_table[] __attribute__((section(".ResetVector.text"))) = {
141 	XTHAL_MPU_ENTRY(0x00000000, 1, XTHAL_AR_NONE,
142 			XTHAL_MEM_DEVICE), /* illegal: no access */
143 	XTHAL_MPU_ENTRY(0x0C000000, 1, XTHAL_AR_RWrw,
144 			XTHAL_MEM_DEVICE), /* MCU & DBG Registers read/write */
145 	XTHAL_MPU_ENTRY(0x0F000000, 1, XTHAL_AR_NONE,
146 			XTHAL_MEM_DEVICE), /* illegal: no access */
147 	XTHAL_MPU_ENTRY(0x10000000, 1, XTHAL_AR_RWrw,
148 			XTHAL_MEM_DEVICE), /* DSP register: read/write */
149 	XTHAL_MPU_ENTRY(0x12000000, 1, XTHAL_AR_NONE,
150 			XTHAL_MEM_DEVICE), /* illegal: no access */
151 	XTHAL_MPU_ENTRY(0x40000000, 1, XTHAL_AR_RWXrwx,
152 			XTHAL_MEM_WRITEBACK), /* DSP SRAM: read/write/execute writeback */
153 	XTHAL_MPU_ENTRY(0x40040000, 1, XTHAL_AR_NONE,
154 			XTHAL_MEM_DEVICE), /* illegal: no access */
155 	XTHAL_MPU_ENTRY(0x60000000, 1, XTHAL_AR_RWXrwx,
156 			XTHAL_MEM_WRITEBACK), /* DRAM: read/write/execute writeback */
157 	XTHAL_MPU_ENTRY(0x60800000, 1, XTHAL_AR_RWrw,
158 			XTHAL_MEM_WRITEBACK), /* DRAM: read/write writeback */
159 	XTHAL_MPU_ENTRY(0x61000000, 1, XTHAL_AR_RWrw,
160 			XTHAL_MEM_DEVICE), /* DMA: read/write writeback */
161 	XTHAL_MPU_ENTRY(0x61100000, 1, XTHAL_AR_NONE,
162 			XTHAL_MEM_DEVICE), /* illegal: no access */
163 };
164 
platform_boot_complete(uint32_t boot_message)165 int platform_boot_complete(uint32_t boot_message)
166 {
167 	mailbox_dspbox_write(0, &ready, sizeof(ready));
168 
169 	/* now interrupt host to tell it we are done booting */
170 	trigger_irq_to_host_req();
171 
172 	/* boot now complete so we can relax the CPU */
173 	/* For now skip this to gain more processing performance
174 	 * for SRC component.
175 	 */
176 	clock_set_freq(CLK_CPU(cpu_get_id()), CLK_DEFAULT_CPU_HZ);
177 
178 	return 0;
179 }
180 
platform_init(struct sof * sof)181 int platform_init(struct sof *sof)
182 {
183 	int ret;
184 
185 	sof->platform_timer = platform_shared_get(&timer_shared, sizeof(timer_shared));
186 	sof->cpu_timers = sof->platform_timer;
187 
188 	platform_interrupt_init();
189 	platform_clock_init(sof);
190 	scheduler_init_edf();
191 
192 	/* init low latency domains and schedulers */
193 	sof->platform_timer_domain = timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK);
194 	scheduler_init_ll(sof->platform_timer_domain);
195 
196 	platform_timer_start(sof->platform_timer);
197 	sa_init(sof, CONFIG_SYSTICK_PERIOD);
198 
199 	clock_set_freq(CLK_CPU(cpu_get_id()), CLK_MAX_CPU_HZ);
200 
201 	/* init DMA */
202 	ret = dmac_init(sof);
203 	if (ret < 0)
204 		return -ENODEV;
205 
206 	/* Init platform domain */
207 	sof->platform_dma_domain = dma_multi_chan_domain_init(&sof->dma_info->dma_array[0], 1,
208 							      PLATFORM_DEFAULT_CLOCK, false);
209 	scheduler_init_ll(sof->platform_dma_domain);
210 
211 	/* initialize the host IPC mechanims */
212 	ipc_init(sof);
213 
214 	ret = dai_init(sof);
215 	if (ret < 0)
216 		return -ENODEV;
217 
218 #if CONFIG_TRACE
219 	/* Initialize DMA for Trace*/
220 	trace_point(TRACE_BOOT_PLATFORM_DMA_TRACE);
221 	dma_trace_init_complete(sof->dmat);
222 #endif
223 
224 	/* show heap status */
225 	heap_trace_all(1);
226 
227 	return 0;
228 }
229 
platform_context_save(struct sof * sof)230 int platform_context_save(struct sof *sof)
231 {
232 	return 0;
233 }
234 
platform_wait_for_interrupt(int level)235 void platform_wait_for_interrupt(int level)
236 {
237 	arch_wait_for_interrupt(level);
238 }
239 
240 #ifdef __XCC__
241 /* This is a stub for the Xtensa libc (not their newlib version),
242  * which inexplicably wants to pull in an unlink() implementation when
243  * linked against the C++ standard library.  Obviously nothing in SOF
244  * uses the C library filesystem layer, this is just spurious.
245  */
246 int __attribute__((weak)) _unlink_r(struct _reent *ptr, const char *file);
_unlink_r(struct _reent * ptr,const char * file)247 int __attribute__((weak)) _unlink_r(struct _reent *ptr, const char *file)
248 {
249 	return -1;
250 }
251 #endif
252