9
9
#include <linux/mailbox_controller.h>
10
10
#include <linux/soc/mediatek/mtk-cmdq.h>
11
11
12
- #define CMDQ_ARG_A_WRITE_MASK 0xffff
13
12
#define CMDQ_WRITE_ENABLE_MASK BIT(0)
13
+ #define CMDQ_POLL_ENABLE_MASK BIT(0)
14
14
#define CMDQ_EOC_IRQ_EN BIT(0)
15
15
16
+ struct cmdq_instruction {
17
+ union {
18
+ u32 value ;
19
+ u32 mask ;
20
+ };
21
+ union {
22
+ u16 offset ;
23
+ u16 event ;
24
+ };
25
+ u8 subsys ;
26
+ u8 op ;
27
+ };
28
+
29
+ int cmdq_dev_get_client_reg (struct device * dev ,
30
+ struct cmdq_client_reg * client_reg , int idx )
31
+ {
32
+ struct of_phandle_args spec ;
33
+ int err ;
34
+
35
+ if (!client_reg )
36
+ return - ENOENT ;
37
+
38
+ err = of_parse_phandle_with_fixed_args (dev -> of_node ,
39
+ "mediatek,gce-client-reg" ,
40
+ 3 , idx , & spec );
41
+ if (err < 0 ) {
42
+ dev_err (dev ,
43
+ "error %d can't parse gce-client-reg property (%d)" ,
44
+ err , idx );
45
+
46
+ return err ;
47
+ }
48
+
49
+ client_reg -> subsys = (u8 )spec .args [0 ];
50
+ client_reg -> offset = (u16 )spec .args [1 ];
51
+ client_reg -> size = (u16 )spec .args [2 ];
52
+ of_node_put (spec .np );
53
+
54
+ return 0 ;
55
+ }
56
+ EXPORT_SYMBOL (cmdq_dev_get_client_reg );
57
+
16
58
static void cmdq_client_timeout (struct timer_list * t )
17
59
{
18
60
struct cmdq_client * client = from_timer (client , t , timer );
@@ -108,10 +150,10 @@ void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
108
150
}
109
151
EXPORT_SYMBOL (cmdq_pkt_destroy );
110
152
111
- static int cmdq_pkt_append_command (struct cmdq_pkt * pkt , enum cmdq_code code ,
112
- u32 arg_a , u32 arg_b )
153
+ static int cmdq_pkt_append_command (struct cmdq_pkt * pkt ,
154
+ struct cmdq_instruction inst )
113
155
{
114
- u64 * cmd_ptr ;
156
+ struct cmdq_instruction * cmd_ptr ;
115
157
116
158
if (unlikely (pkt -> cmd_buf_size + CMDQ_INST_SIZE > pkt -> buf_size )) {
117
159
/*
@@ -127,77 +169,130 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
127
169
__func__ , (u32 )pkt -> buf_size );
128
170
return - ENOMEM ;
129
171
}
172
+
130
173
cmd_ptr = pkt -> va_base + pkt -> cmd_buf_size ;
131
- ( * cmd_ptr ) = ( u64 )(( code << CMDQ_OP_CODE_SHIFT ) | arg_a ) << 32 | arg_b ;
174
+ * cmd_ptr = inst ;
132
175
pkt -> cmd_buf_size += CMDQ_INST_SIZE ;
133
176
134
177
return 0 ;
135
178
}
136
179
137
180
int cmdq_pkt_write (struct cmdq_pkt * pkt , u8 subsys , u16 offset , u32 value )
138
181
{
139
- u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK ) |
140
- (subsys << CMDQ_SUBSYS_SHIFT );
182
+ struct cmdq_instruction inst ;
141
183
142
- return cmdq_pkt_append_command (pkt , CMDQ_CODE_WRITE , arg_a , value );
184
+ inst .op = CMDQ_CODE_WRITE ;
185
+ inst .value = value ;
186
+ inst .offset = offset ;
187
+ inst .subsys = subsys ;
188
+
189
+ return cmdq_pkt_append_command (pkt , inst );
143
190
}
144
191
EXPORT_SYMBOL (cmdq_pkt_write );
145
192
146
193
int cmdq_pkt_write_mask (struct cmdq_pkt * pkt , u8 subsys ,
147
194
u16 offset , u32 value , u32 mask )
148
195
{
149
- u32 offset_mask = offset ;
150
- int err = 0 ;
196
+ struct cmdq_instruction inst = { {0 } };
197
+ u16 offset_mask = offset ;
198
+ int err ;
151
199
152
200
if (mask != 0xffffffff ) {
153
- err = cmdq_pkt_append_command (pkt , CMDQ_CODE_MASK , 0 , ~mask );
201
+ inst .op = CMDQ_CODE_MASK ;
202
+ inst .mask = ~mask ;
203
+ err = cmdq_pkt_append_command (pkt , inst );
204
+ if (err < 0 )
205
+ return err ;
206
+
154
207
offset_mask |= CMDQ_WRITE_ENABLE_MASK ;
155
208
}
156
- err | = cmdq_pkt_write (pkt , subsys , offset_mask , value );
209
+ err = cmdq_pkt_write (pkt , subsys , offset_mask , value );
157
210
158
211
return err ;
159
212
}
160
213
EXPORT_SYMBOL (cmdq_pkt_write_mask );
161
214
162
215
int cmdq_pkt_wfe (struct cmdq_pkt * pkt , u16 event )
163
216
{
164
- u32 arg_b ;
217
+ struct cmdq_instruction inst = { { 0 } } ;
165
218
166
219
if (event >= CMDQ_MAX_EVENT )
167
220
return - EINVAL ;
168
221
169
- /*
170
- * WFE arg_b
171
- * bit 0-11: wait value
172
- * bit 15: 1 - wait, 0 - no wait
173
- * bit 16-27: update value
174
- * bit 31: 1 - update, 0 - no update
175
- */
176
- arg_b = CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | CMDQ_WFE_WAIT_VALUE ;
222
+ inst .op = CMDQ_CODE_WFE ;
223
+ inst .value = CMDQ_WFE_OPTION ;
224
+ inst .event = event ;
177
225
178
- return cmdq_pkt_append_command (pkt , CMDQ_CODE_WFE , event , arg_b );
226
+ return cmdq_pkt_append_command (pkt , inst );
179
227
}
180
228
EXPORT_SYMBOL (cmdq_pkt_wfe );
181
229
182
230
int cmdq_pkt_clear_event (struct cmdq_pkt * pkt , u16 event )
183
231
{
232
+ struct cmdq_instruction inst = { {0 } };
233
+
184
234
if (event >= CMDQ_MAX_EVENT )
185
235
return - EINVAL ;
186
236
187
- return cmdq_pkt_append_command (pkt , CMDQ_CODE_WFE , event ,
188
- CMDQ_WFE_UPDATE );
237
+ inst .op = CMDQ_CODE_WFE ;
238
+ inst .value = CMDQ_WFE_UPDATE ;
239
+ inst .event = event ;
240
+
241
+ return cmdq_pkt_append_command (pkt , inst );
189
242
}
190
243
EXPORT_SYMBOL (cmdq_pkt_clear_event );
191
244
245
+ int cmdq_pkt_poll (struct cmdq_pkt * pkt , u8 subsys ,
246
+ u16 offset , u32 value )
247
+ {
248
+ struct cmdq_instruction inst = { {0 } };
249
+ int err ;
250
+
251
+ inst .op = CMDQ_CODE_POLL ;
252
+ inst .value = value ;
253
+ inst .offset = offset ;
254
+ inst .subsys = subsys ;
255
+ err = cmdq_pkt_append_command (pkt , inst );
256
+
257
+ return err ;
258
+ }
259
+ EXPORT_SYMBOL (cmdq_pkt_poll );
260
+
261
+ int cmdq_pkt_poll_mask (struct cmdq_pkt * pkt , u8 subsys ,
262
+ u16 offset , u32 value , u32 mask )
263
+ {
264
+ struct cmdq_instruction inst = { {0 } };
265
+ int err ;
266
+
267
+ inst .op = CMDQ_CODE_MASK ;
268
+ inst .mask = ~mask ;
269
+ err = cmdq_pkt_append_command (pkt , inst );
270
+ if (err < 0 )
271
+ return err ;
272
+
273
+ offset = offset | CMDQ_POLL_ENABLE_MASK ;
274
+ err = cmdq_pkt_poll (pkt , subsys , offset , value );
275
+
276
+ return err ;
277
+ }
278
+ EXPORT_SYMBOL (cmdq_pkt_poll_mask );
279
+
192
280
static int cmdq_pkt_finalize (struct cmdq_pkt * pkt )
193
281
{
282
+ struct cmdq_instruction inst = { {0 } };
194
283
int err ;
195
284
196
285
/* insert EOC and generate IRQ for each command iteration */
197
- err = cmdq_pkt_append_command (pkt , CMDQ_CODE_EOC , 0 , CMDQ_EOC_IRQ_EN );
286
+ inst .op = CMDQ_CODE_EOC ;
287
+ inst .value = CMDQ_EOC_IRQ_EN ;
288
+ err = cmdq_pkt_append_command (pkt , inst );
289
+ if (err < 0 )
290
+ return err ;
198
291
199
292
/* JUMP to end */
200
- err |= cmdq_pkt_append_command (pkt , CMDQ_CODE_JUMP , 0 , CMDQ_JUMP_PASS );
293
+ inst .op = CMDQ_CODE_JUMP ;
294
+ inst .value = CMDQ_JUMP_PASS ;
295
+ err = cmdq_pkt_append_command (pkt , inst );
201
296
202
297
return err ;
203
298
}
0 commit comments