1 // SPDX-License-Identifier: BSD-3-Clause
2 //
3 // Copyright(c) 2017 Intel Corporation. All rights reserved.
4 //
5 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
6 //         Keyon Jie <yang.jie@linux.intel.com>
7 //         Rander Wang <rander.wang@intel.com>
8 
9 #include <sof/ipc/driver.h>
10 #include <sof/ipc/msg.h>
11 #include <sof/drivers/spi.h>
12 #include <sof/lib/mailbox.h>
13 #include <sof/lib/memory.h>
14 #include <sof/lib/uuid.h>
15 #include <sof/lib/wait.h>
16 #include <sof/list.h>
17 #include <sof/schedule/edf_schedule.h>
18 #include <sof/schedule/schedule.h>
19 #include <sof/schedule/task.h>
20 #include <sof/spinlock.h>
21 #include <ipc/header.h>
22 #include <stddef.h>
23 #include <stdint.h>
24 
25 /* 7552b3a1-98dd-4419-ad6f-fbf21ebfceec */
26 DECLARE_SOF_UUID("ipc-task", ipc_task_uuid, 0x7552b3a1, 0x98dd, 0x4419,
27 		 0xad, 0x6f, 0xfb, 0xf2, 0x1e, 0xbf, 0xce, 0xec);
28 
ipc_platform_compact_write_msg(ipc_cmd_hdr * hdr,int words)29 int ipc_platform_compact_write_msg(ipc_cmd_hdr *hdr, int words)
30 {
31 	return 0; /* number of words read - not currently used on this platform */
32 }
33 
ipc_platform_compact_read_msg(ipc_cmd_hdr * hdr,int words)34 int ipc_platform_compact_read_msg(ipc_cmd_hdr *hdr, int words)
35 {
36 	return 0; /* number of words read - not currently used on this platform */
37 }
38 
39 /* No private data for IPC */
ipc_platform_do_cmd(void * data)40 enum task_state ipc_platform_do_cmd(void *data)
41 {
42 	struct ipc *ipc = data;
43 	ipc_cmd_hdr *hdr;
44 	struct sof_ipc_reply reply;
45 
46 	/* perform command */
47 	hdr = mailbox_validate();
48 	ipc_cmd(hdr);
49 
50 	mailbox_hostbox_read(&reply, SOF_IPC_MSG_MAX_SIZE,
51 			     0, sizeof(reply));
52 	spi_push(spi_get(SOF_SPI_INTEL_SLAVE), &reply, sizeof(reply));
53 
54 	// TODO: signal audio work to enter D3 in normal context
55 	/* are we about to enter D3 ? */
56 	if (ipc->pm_prepare_D3) {
57 
58 		while (1)
59 			wait_for_interrupt(0);
60 	}
61 
62 	return SOF_TASK_STATE_COMPLETED;
63 }
64 
ipc_platform_complete_cmd(void * data)65 void ipc_platform_complete_cmd(void *data)
66 {
67 }
68 
ipc_platform_send_msg(struct ipc_msg * msg)69 int ipc_platform_send_msg(struct ipc_msg *msg)
70 {
71 	/* now send the message */
72 	mailbox_dspbox_write(0, msg->tx_data, msg->tx_size);
73 	list_item_del(&msg->list);
74 	tr_dbg(&ipc_tr, "ipc: msg tx -> 0x%x", msg->header);
75 
76 	/* now interrupt host to tell it we have message sent */
77 
78 	return 0;
79 }
80 
platform_ipc_init(struct ipc * ipc)81 int platform_ipc_init(struct ipc *ipc)
82 {
83 	ipc_set_drvdata(ipc, NULL);
84 
85 	/* schedule */
86 	schedule_task_init_edf(&ipc->ipc_task, SOF_UUID(ipc_task_uuid),
87 			       &ipc_task_ops, ipc, 0, 0);
88 
89 	return 0;
90 }
91