1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Copyright (c) 2018 MediaTek Inc.
10 #include <linux/mailbox_client.h>
11 #include <linux/mailbox/mtk-cmdq-mailbox.h>
12 #include <linux/timer.h>
14 #define CMDQ_NO_TIMEOUT 0xffffffffu
15 #define CMDQ_ADDR_HIGH(addr) ((u32)(((addr) >> 16) & GENMASK(31, 0)))
16 #define CMDQ_ADDR_LOW(addr) ((u16)(addr) | BIT(1))
20 struct cmdq_client_reg {
29 struct mbox_client client;
30 struct mbox_chan *chan;
31 struct timer_list timer;
32 u32 timeout_ms; /* in unit of microsecond */
36 * cmdq_dev_get_client_reg() - parse cmdq client reg from the device
38 * @dev: device of CMDQ mailbox client
39 * @client_reg: CMDQ client reg pointer
40 * @idx: the index of desired reg
42 * Return: 0 for success; else the error code is returned
44 * Help CMDQ client parsing the cmdq client reg
45 * from the device node of CMDQ client.
47 int cmdq_dev_get_client_reg(struct device *dev,
48 struct cmdq_client_reg *client_reg, int idx);
51 * cmdq_mbox_create() - create CMDQ mailbox client and channel
52 * @dev: device of CMDQ mailbox client
53 * @index: index of CMDQ mailbox channel
54 * @timeout: timeout of a pkt execution by GCE, in unit of microsecond, set
55 * CMDQ_NO_TIMEOUT if a timer is not used.
57 * Return: CMDQ mailbox client pointer
59 struct cmdq_client *cmdq_mbox_create(struct device *dev, int index,
63 * cmdq_mbox_destroy() - destroy CMDQ mailbox client and channel
64 * @client: the CMDQ mailbox client
66 void cmdq_mbox_destroy(struct cmdq_client *client);
69 * cmdq_pkt_create() - create a CMDQ packet
70 * @client: the CMDQ mailbox client
71 * @size: required CMDQ buffer size
73 * Return: CMDQ packet pointer
75 struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size);
78 * cmdq_pkt_destroy() - destroy the CMDQ packet
79 * @pkt: the CMDQ packet
81 void cmdq_pkt_destroy(struct cmdq_pkt *pkt);
84 * cmdq_pkt_write() - append write command to the CMDQ packet
85 * @pkt: the CMDQ packet
86 * @subsys: the CMDQ sub system code
87 * @offset: register offset from CMDQ sub system
88 * @value: the specified target register value
90 * Return: 0 for success; else the error code is returned
92 int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value);
95 * cmdq_pkt_write_mask() - append write command with mask to the CMDQ packet
96 * @pkt: the CMDQ packet
97 * @subsys: the CMDQ sub system code
98 * @offset: register offset from CMDQ sub system
99 * @value: the specified target register value
100 * @mask: the specified target register mask
102 * Return: 0 for success; else the error code is returned
104 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
105 u16 offset, u32 value, u32 mask);
108 * cmdq_pkt_read_s() - append read_s command to the CMDQ packet
109 * @pkt: the CMDQ packet
110 * @high_addr_reg_idx: internal register ID which contains high address of pa
111 * @addr_low: low address of pa
112 * @reg_idx: the CMDQ internal register ID to cache read data
114 * Return: 0 for success; else the error code is returned
116 int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
120 * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
121 * @pkt: the CMDQ packet
122 * @high_addr_reg_idx: internal register ID which contains high address of pa
123 * @addr_low: low address of pa
124 * @src_reg_idx: the CMDQ internal register ID which cache source value
126 * Return: 0 for success; else the error code is returned
128 * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH()
129 * to get high address and call cmdq_pkt_assign() to assign value into internal
130 * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when
131 * call to this function.
133 int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
134 u16 addr_low, u16 src_reg_idx);
137 * cmdq_pkt_write_s_mask() - append write_s with mask command to the CMDQ packet
138 * @pkt: the CMDQ packet
139 * @high_addr_reg_idx: internal register ID which contains high address of pa
140 * @addr_low: low address of pa
141 * @src_reg_idx: the CMDQ internal register ID which cache source value
142 * @mask: the specified target address mask, use U32_MAX if no need
144 * Return: 0 for success; else the error code is returned
146 * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH()
147 * to get high address and call cmdq_pkt_assign() to assign value into internal
148 * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when
149 * call to this function.
151 int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
152 u16 addr_low, u16 src_reg_idx, u32 mask);
155 * cmdq_pkt_write_s_value() - append write_s command to the CMDQ packet which
156 * write value to a physical address
157 * @pkt: the CMDQ packet
158 * @high_addr_reg_idx: internal register ID which contains high address of pa
159 * @addr_low: low address of pa
160 * @value: the specified target value
162 * Return: 0 for success; else the error code is returned
164 int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
165 u16 addr_low, u32 value);
168 * cmdq_pkt_write_s_mask_value() - append write_s command with mask to the CMDQ
169 * packet which write value to a physical
171 * @pkt: the CMDQ packet
172 * @high_addr_reg_idx: internal register ID which contains high address of pa
173 * @addr_low: low address of pa
174 * @value: the specified target value
175 * @mask: the specified target mask
177 * Return: 0 for success; else the error code is returned
179 int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
180 u16 addr_low, u32 value, u32 mask);
183 * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
184 * @pkt: the CMDQ packet
185 * @event: the desired event type to wait
186 * @clear: clear event or not after event arrive
188 * Return: 0 for success; else the error code is returned
190 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear);
193 * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
194 * @pkt: the CMDQ packet
195 * @event: the desired event to be cleared
197 * Return: 0 for success; else the error code is returned
199 int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event);
202 * cmdq_pkt_set_event() - append set event command to the CMDQ packet
203 * @pkt: the CMDQ packet
204 * @event: the desired event to be set
206 * Return: 0 for success; else the error code is returned
208 int cmdq_pkt_set_event(struct cmdq_pkt *pkt, u16 event);
211 * cmdq_pkt_poll() - Append polling command to the CMDQ packet, ask GCE to
212 * execute an instruction that wait for a specified
213 * hardware register to check for the value w/o mask.
214 * All GCE hardware threads will be blocked by this
216 * @pkt: the CMDQ packet
217 * @subsys: the CMDQ sub system code
218 * @offset: register offset from CMDQ sub system
219 * @value: the specified target register value
221 * Return: 0 for success; else the error code is returned
223 int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
224 u16 offset, u32 value);
227 * cmdq_pkt_poll_mask() - Append polling command to the CMDQ packet, ask GCE to
228 * execute an instruction that wait for a specified
229 * hardware register to check for the value w/ mask.
230 * All GCE hardware threads will be blocked by this
232 * @pkt: the CMDQ packet
233 * @subsys: the CMDQ sub system code
234 * @offset: register offset from CMDQ sub system
235 * @value: the specified target register value
236 * @mask: the specified target register mask
238 * Return: 0 for success; else the error code is returned
240 int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
241 u16 offset, u32 value, u32 mask);
244 * cmdq_pkt_assign() - Append logic assign command to the CMDQ packet, ask GCE
245 * to execute an instruction that set a constant value into
246 * internal register and use as value, mask or address in
247 * read/write instruction.
248 * @pkt: the CMDQ packet
249 * @reg_idx: the CMDQ internal register ID
250 * @value: the specified value
252 * Return: 0 for success; else the error code is returned
254 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
257 * cmdq_pkt_jump() - Append jump command to the CMDQ packet, ask GCE
258 * to execute an instruction that change current thread PC to
259 * a physical address which should contains more instruction.
260 * @pkt: the CMDQ packet
261 * @addr: physical address of target instruction buffer
263 * Return: 0 for success; else the error code is returned
265 int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
268 * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
269 * @pkt: the CMDQ packet
271 * Return: 0 for success; else the error code is returned
273 int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
276 * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
277 * packet and call back at the end of done packet
278 * @pkt: the CMDQ packet
279 * @cb: called at the end of done packet
280 * @data: this data will pass back to cb
282 * Return: 0 for success; else the error code is returned
284 * Trigger CMDQ to asynchronously execute the CMDQ packet and call back
285 * at the end of done packet. Note that this is an ASYNC function. When the
286 * function returned, it may or may not be finished.
288 int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb cb,
292 * cmdq_pkt_flush() - trigger CMDQ to execute the CMDQ packet
293 * @pkt: the CMDQ packet
295 * Return: 0 for success; else the error code is returned
297 * Trigger CMDQ to execute the CMDQ packet. Note that this is a
298 * synchronous flush function. When the function returned, the recorded
299 * commands have been done.
301 int cmdq_pkt_flush(struct cmdq_pkt *pkt);
303 #endif /* __MTK_CMDQ_H__ */