Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2018 MediaTek Inc.
4 *
5 */
6
7#ifndef __MTK_CMDQ_H__
8#define __MTK_CMDQ_H__
9
10#include <linux/mailbox_client.h>
11#include <linux/mailbox/mtk-cmdq-mailbox.h>
12#include <linux/timer.h>
13
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))
17
18struct cmdq_pkt;
19
20struct cmdq_client_reg {
21 u8 subsys;
22 u16 offset;
23 u16 size;
24};
25
26struct cmdq_client {
27 spinlock_t lock;
28 u32 pkt_cnt;
29 struct mbox_client client;
30 struct mbox_chan *chan;
31 struct timer_list timer;
32 u32 timeout_ms; /* in unit of microsecond */
33};
34
35/**
36 * cmdq_dev_get_client_reg() - parse cmdq client reg from the device
37 * node of CMDQ client
38 * @dev: device of CMDQ mailbox client
39 * @client_reg: CMDQ client reg pointer
40 * @idx: the index of desired reg
41 *
42 * Return: 0 for success; else the error code is returned
43 *
44 * Help CMDQ client parsing the cmdq client reg
45 * from the device node of CMDQ client.
46 */
47int cmdq_dev_get_client_reg(struct device *dev,
48 struct cmdq_client_reg *client_reg, int idx);
49
50/**
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.
56 *
57 * Return: CMDQ mailbox client pointer
58 */
59struct cmdq_client *cmdq_mbox_create(struct device *dev, int index,
60 u32 timeout);
61
62/**
63 * cmdq_mbox_destroy() - destroy CMDQ mailbox client and channel
64 * @client: the CMDQ mailbox client
65 */
66void cmdq_mbox_destroy(struct cmdq_client *client);
67
68/**
69 * cmdq_pkt_create() - create a CMDQ packet
70 * @client: the CMDQ mailbox client
71 * @size: required CMDQ buffer size
72 *
73 * Return: CMDQ packet pointer
74 */
75struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size);
76
77/**
78 * cmdq_pkt_destroy() - destroy the CMDQ packet
79 * @pkt: the CMDQ packet
80 */
81void cmdq_pkt_destroy(struct cmdq_pkt *pkt);
82
83/**
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
89 *
90 * Return: 0 for success; else the error code is returned
91 */
92int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value);
93
94/**
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
101 *
102 * Return: 0 for success; else the error code is returned
103 */
104int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
105 u16 offset, u32 value, u32 mask);
106
107/*
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
113 *
114 * Return: 0 for success; else the error code is returned
115 */
116int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
117 u16 reg_idx);
118
119/**
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
125 *
126 * Return: 0 for success; else the error code is returned
127 *
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.
132 */
133int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
134 u16 addr_low, u16 src_reg_idx);
135
136/**
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
143 *
144 * Return: 0 for success; else the error code is returned
145 *
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.
150 */
151int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
152 u16 addr_low, u16 src_reg_idx, u32 mask);
153
154/**
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
161 *
162 * Return: 0 for success; else the error code is returned
163 */
164int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
165 u16 addr_low, u32 value);
166
167/**
168 * cmdq_pkt_write_s_mask_value() - append write_s command with mask to the CMDQ
169 * packet which write value to a physical
170 * address
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
176 *
177 * Return: 0 for success; else the error code is returned
178 */
179int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
180 u16 addr_low, u32 value, u32 mask);
181
182/**
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
187 *
188 * Return: 0 for success; else the error code is returned
189 */
190int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear);
191
192/**
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
196 *
197 * Return: 0 for success; else the error code is returned
198 */
199int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event);
200
201/**
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
205 *
206 * Return: 0 for success; else the error code is returned
207 */
208int cmdq_pkt_set_event(struct cmdq_pkt *pkt, u16 event);
209
210/**
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
215 * instruction.
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
220 *
221 * Return: 0 for success; else the error code is returned
222 */
223int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
224 u16 offset, u32 value);
225
226/**
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
231 * instruction.
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
237 *
238 * Return: 0 for success; else the error code is returned
239 */
240int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
241 u16 offset, u32 value, u32 mask);
242
243/**
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
251 *
252 * Return: 0 for success; else the error code is returned
253 */
254int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
255
256/**
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
262 *
263 * Return: 0 for success; else the error code is returned
264 */
265int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
266
267/**
268 * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
269 * @pkt: the CMDQ packet
270 *
271 * Return: 0 for success; else the error code is returned
272 */
273int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
274
275/**
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
281 *
282 * Return: 0 for success; else the error code is returned
283 *
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.
287 */
288int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb cb,
289 void *data);
290
291/**
292 * cmdq_pkt_flush() - trigger CMDQ to execute the CMDQ packet
293 * @pkt: the CMDQ packet
294 *
295 * Return: 0 for success; else the error code is returned
296 *
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.
300 */
301int cmdq_pkt_flush(struct cmdq_pkt *pkt);
302
303#endif /* __MTK_CMDQ_H__ */