1 // SPDX-License-Identifier: BSD-3-Clause
2 //
3 //Copyright(c) 2021 AMD. All rights reserved.
4 //
5 //Author:       Basavaraj Hiregoudar <basavaraj.hiregoudar@amd.com>
6 //              Anup Kulkarni <anup.kulkarni@amd.com>
7 //              Bala Kishore <balakishore.pati@amd.com>
8 
9 #include <sof/compiler_info.h>
10 #include <sof/debug/debug.h>
11 #include <rtos/interrupt.h>
12 #include <sof/drivers/acp_dai_dma.h>
13 #include <sof/ipc/driver.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 <platform/chip_offset_byte.h>
39 
40 struct sof;
41 static const struct sof_ipc_fw_ready ready
42 	__attribute__((section(".fw_ready"))) = {
43 	.hdr = {
44 		.cmd = SOF_IPC_FW_READY,
45 		.size = sizeof(struct sof_ipc_fw_ready),
46 	},
47 	/* dspbox is for DSP initiated IPC, hostbox is for host initiated IPC */
48 	.version = {
49 		.hdr.size = sizeof(struct sof_ipc_fw_version),
50 		.micro = SOF_MICRO,
51 		.minor = SOF_MINOR,
52 		.major = SOF_MAJOR,
53 #ifdef DEBUG_BUILD
54 		/* only added in debug for reproducability in releases */
55 		.build = SOF_BUILD,
56 		.date = __DATE__,
57 		.time = __TIME__,
58 #endif
59 		.tag = SOF_TAG,
60 		.abi_version = SOF_ABI_VERSION,
61 	},
62 	.flags = DEBUG_SET_FW_READY_FLAGS,
63 };
64 
65 #define NUM_ACP_WINDOWS		6
66 
67 const struct ext_man_windows xsram_window
68 		__aligned(EXT_MAN_ALIGN) __section(".fw_metadata") __unused = {
69 	.hdr = {
70 		.type = EXT_MAN_ELEM_WINDOW,
71 		.elem_size = ALIGN_UP_COMPILE(sizeof(struct ext_man_windows), EXT_MAN_ALIGN),
72 	},
73 	.window = {
74 		.ext_hdr	= {
75 			.hdr.cmd = SOF_IPC_FW_READY,
76 			.hdr.size = sizeof(struct sof_ipc_window),
77 			.type   = SOF_IPC_EXT_WINDOW,
78 		},
79 		.num_windows    = NUM_ACP_WINDOWS,
80 		.window = {
81 			{
82 				.type   = SOF_IPC_REGION_UPBOX,
83 				.id     = 0,
84 				.flags  = 0,
85 				.size   = MAILBOX_DSPBOX_SIZE,
86 				.offset = MAILBOX_DSPBOX_OFFSET,
87 			},
88 			{
89 				.type   = SOF_IPC_REGION_DOWNBOX,
90 				.id     = 0,
91 				.flags  = 0,
92 				.size   = MAILBOX_HOSTBOX_SIZE,
93 				.offset = MAILBOX_HOSTBOX_OFFSET,
94 			},
95 			{
96 				.type   = SOF_IPC_REGION_DEBUG,
97 				.id     = 0,
98 				.flags  = 0,
99 				.size   = MAILBOX_DEBUG_SIZE,
100 				.offset = MAILBOX_DEBUG_OFFSET,
101 			},
102 			{
103 				.type   = SOF_IPC_REGION_TRACE,
104 				.id     = 0,
105 				.flags  = 0,
106 				.size   = MAILBOX_TRACE_SIZE,
107 				.offset = MAILBOX_TRACE_OFFSET,
108 			},
109 			{
110 				.type   = SOF_IPC_REGION_STREAM,
111 				.id     = 0,
112 				.flags  = 0,
113 				.size   = MAILBOX_STREAM_SIZE,
114 				.offset = MAILBOX_STREAM_OFFSET,
115 			},
116 			{
117 				.type   = SOF_IPC_REGION_EXCEPTION,
118 				.id     = 0,
119 				.flags  = 0,
120 				.size   = MAILBOX_EXCEPTION_SIZE,
121 				.offset = MAILBOX_EXCEPTION_OFFSET,
122 			},
123 		},
124 	},
125 };
126 
127 static SHARED_DATA struct timer timer_shared = {
128 	.id = TIMER0,
129 	.irq = IRQ_NUM_TIMER0,
130 };
131 
platform_init(struct sof * sof)132 int platform_init(struct sof *sof)
133 {
134 	int ret;
135 
136 	sof->platform_timer = platform_shared_get(&timer_shared, sizeof(timer_shared));
137 	sof->cpu_timers = sof->platform_timer;
138 
139 	/* to view system memory */
140 	platform_interrupt_init();
141 	platform_clock_init(sof);
142 	scheduler_init_edf();
143 	/* init low latency domains and schedulers */
144 	/* CONFIG_SYSTICK_PERIOD set as PLATFORM_DEFAULT_CLOCK */
145 	sof->platform_timer_domain = timer_domain_init(sof->platform_timer,
146 						PLATFORM_DEFAULT_CLOCK);
147 	scheduler_init_ll(sof->platform_timer_domain);
148 	platform_timer_start(sof->platform_timer);
149 	/*CONFIG_SYSTICK_PERIOD hardcoded as 200000*/
150 	sa_init(sof, 200000);
151 	clock_set_freq(CLK_CPU(cpu_get_id()), CLK_MAX_CPU_HZ);
152 	/* init DMA */
153 	ret = acp_dma_init(sof);
154 	if (ret < 0)
155 		return -ENODEV;
156 	/* Init DMA platform domain */
157 	sof->platform_dma_domain = dma_multi_chan_domain_init(&sof->dma_info->dma_array[0],
158 			sizeof(sof->dma_info->dma_array), PLATFORM_DEFAULT_CLOCK, true);
159 	sof->platform_dma_domain->full_sync = true;
160 	scheduler_init_ll(sof->platform_dma_domain);
161 	/* initialize the host IPC mechanisms */
162 	ipc_init(sof);
163 	/* initialize the DAI mechanisms */
164 	ret = dai_init(sof);
165 	if (ret < 0)
166 		return -ENODEV;
167 #if CONFIG_TRACE
168 	/* Initialize DMA for Trace*/
169 	trace_point(TRACE_BOOT_PLATFORM_DMA_TRACE);
170 	sof->dmat->config.elem_array.elems = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM,
171 							sizeof(struct dma_sg_elem) * 1);
172 	sof->dmat->config.elem_array.count = 1;
173 	sof->dmat->config.elem_array.elems->dest = 0x03800000;
174 	sof->dmat->config.elem_array.elems->size = 65536;
175 	sof->dmat->config.scatter = 0;
176 	dma_trace_init_complete(sof->dmat);
177 #endif
178 	/* show heap status */
179 	heap_trace_all(1);
180 	return 0;
181 }
182 
platform_boot_complete(uint32_t boot_message)183 int platform_boot_complete(uint32_t boot_message)
184 {
185 	acp_sw_intr_trig_t  swintrtrig;
186 	volatile acp_scratch_mem_config_t *pscratch_mem_cfg =
187 		(volatile acp_scratch_mem_config_t *)(PU_REGISTER_BASE + SCRATCH_REG_OFFSET);
188 	mailbox_dspbox_write(0, &ready, sizeof(ready));
189 	pscratch_mem_cfg->acp_dsp_msg_write = 1;
190 	acp_dsp_to_host_Intr_trig();
191 	/* Configures the trigger bit in ACP_DSP_SW_INTR_TRIG register */
192 	swintrtrig = (acp_sw_intr_trig_t)io_reg_read(PU_REGISTER_BASE + ACP_SW_INTR_TRIG);
193 	swintrtrig.bits.trig_dsp0_to_host_intr  = INTERRUPT_DISABLE;
194 	io_reg_write((PU_REGISTER_BASE + ACP_SW_INTR_TRIG), swintrtrig.u32all);
195 	clock_set_freq(CLK_CPU(cpu_get_id()), CLK_DEFAULT_CPU_HZ);
196 	return 0;
197 }
platform_context_save(struct sof * sof)198 int platform_context_save(struct sof *sof)
199 {
200 	return 0;
201 }
202 
platform_wait_for_interrupt(int level)203 void platform_wait_for_interrupt(int level)
204 {
205 	arch_wait_for_interrupt(level);
206 }
207