1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2018 Intel Corporation. All rights reserved.
4  *
5  * Author: Tomasz Lauda <tomasz.lauda@linux.intel.com>
6  */
7 
8 /**
9  * \file include/sof/drivers/idc.h
10  * \brief IDC header file
11  * \authors Tomasz Lauda <tomasz.lauda@linux.intel.com>
12  */
13 
14 #ifndef __SOF_DRIVERS_IDC_H__
15 #define __SOF_DRIVERS_IDC_H__
16 
17 #include <arch/drivers/idc.h>
18 #include <platform/drivers/idc.h>
19 #include <sof/schedule/task.h>
20 #include <sof/trace/trace.h>
21 #include <user/trace.h>
22 #include <stdint.h>
23 
24 /** \brief IDC send blocking flag. */
25 #define IDC_BLOCKING		0
26 
27 /** \brief IDC send non-blocking flag. */
28 #define IDC_NON_BLOCKING	1
29 
30 /** \brief IDC send core power up flag. */
31 #define IDC_POWER_UP		2
32 
33 /** \brief IDC send core power down flag. */
34 #define IDC_POWER_DOWN		3
35 
36 /** \brief IDC send timeout in microseconds. */
37 #define IDC_TIMEOUT	10000
38 
39 /** \brief IDC task deadline. */
40 #define IDC_DEADLINE	100
41 
42 /** \brief ROM wake version parsed by ROM during core wake up. */
43 #define IDC_ROM_WAKE_VERSION	0x2
44 
45 /** \brief IDC message type. */
46 #define IDC_TYPE_SHIFT		24
47 #define IDC_TYPE_MASK		0x7f
48 #define IDC_TYPE(x)		(((x) & IDC_TYPE_MASK) << IDC_TYPE_SHIFT)
49 
50 /** \brief IDC message header. */
51 #define IDC_HEADER_MASK		0xffffff
52 #define IDC_HEADER(x)		((x) & IDC_HEADER_MASK)
53 
54 /** \brief IDC message extension. */
55 #define IDC_EXTENSION_MASK	0x3fffffff
56 #define IDC_EXTENSION(x)	((x) & IDC_EXTENSION_MASK)
57 
58 /** \brief IDC power up message. */
59 #define IDC_MSG_POWER_UP	(IDC_TYPE(0x1) | \
60 					IDC_HEADER(IDC_ROM_WAKE_VERSION))
61 #define IDC_MSG_POWER_UP_EXT	IDC_EXTENSION(SOF_TEXT_START >> 2)
62 
63 /** \brief IDC power down message. */
64 #define IDC_MSG_POWER_DOWN	IDC_TYPE(0x2)
65 #define IDC_MSG_POWER_DOWN_EXT	IDC_EXTENSION(0x0)
66 
67 /** \brief IDC notify message. */
68 #define IDC_MSG_NOTIFY		IDC_TYPE(0x3)
69 #define IDC_MSG_NOTIFY_EXT	IDC_EXTENSION(0x0)
70 
71 /** \brief IDC IPC processing message. */
72 #define IDC_MSG_IPC		IDC_TYPE(0x4)
73 #define IDC_MSG_IPC_EXT		IDC_EXTENSION(0x0)
74 
75 /** \brief IDC component params message. */
76 #define IDC_MSG_PARAMS		IDC_TYPE(0x5)
77 #define IDC_MSG_PARAMS_EXT(x)	IDC_EXTENSION(x)
78 
79 /** \brief IDC component prepare message. */
80 #define IDC_MSG_PREPARE		IDC_TYPE(0x6)
81 #define IDC_MSG_PREPARE_EXT(x)	IDC_EXTENSION(x)
82 
83 /** \brief IDC component trigger message. */
84 #define IDC_MSG_TRIGGER		IDC_TYPE(0x7)
85 #define IDC_MSG_TRIGGER_EXT(x)	IDC_EXTENSION(x)
86 
87 /** \brief IDC component reset message. */
88 #define IDC_MSG_RESET		IDC_TYPE(0x8)
89 #define IDC_MSG_RESET_EXT(x)	IDC_EXTENSION(x)
90 
91 /** \brief Decodes IDC message type. */
92 #define iTS(x)	(((x) >> IDC_TYPE_SHIFT) & IDC_TYPE_MASK)
93 
94 /** \brief Max IDC message payload size in bytes. */
95 #define IDC_MAX_PAYLOAD_SIZE	96
96 
97 /** \brief IDC message payload. */
98 struct idc_payload {
99 	uint8_t data[IDC_MAX_PAYLOAD_SIZE];
100 };
101 
102 /** \brief IDC message. */
103 struct idc_msg {
104 	uint32_t header;	/**< header value */
105 	uint32_t extension;	/**< extension value */
106 	uint32_t core;		/**< core id */
107 	uint32_t size;		/**< payload size in bytes */
108 	void *payload;		/**< pointer to payload data */
109 };
110 
111 /** \brief IDC data. */
112 struct idc {
113 	uint32_t busy_bit_mask;		/**< busy interrupt mask */
114 	struct idc_msg received_msg;	/**< received message */
115 	struct task idc_task;		/**< IDC processing task */
116 	struct idc_payload *payload;
117 	int irq;
118 };
119 
120 /* idc trace context, used by multiple units */
121 extern struct tr_ctx idc_tr;
122 
idc_payload_get(struct idc * idc,uint32_t core)123 static inline struct idc_payload *idc_payload_get(struct idc *idc,
124 						  uint32_t core)
125 {
126 	return idc->payload + core;
127 }
128 
129 void idc_enable_interrupts(int target_core, int source_core);
130 
131 void idc_free(void);
132 
133 int platform_idc_init(void);
134 
135 enum task_state idc_do_cmd(void *data);
136 
137 void idc_cmd(struct idc_msg *msg);
138 
139 int idc_wait_in_blocking_mode(uint32_t target_core, bool (*cond)(int));
140 
141 int idc_msg_status_get(uint32_t core);
142 
143 void idc_init_thread(void);
144 
145 #endif /* __SOF_DRIVERS_IDC_H__ */
146