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
- #define CMDQ_EOC_CMD ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
16
- << 32 | CMDQ_EOC_IRQ_EN)
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 );
17
57
18
58
static void cmdq_client_timeout (struct timer_list * t )
19
59
{
@@ -110,10 +150,10 @@ void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
110
150
}
111
151
EXPORT_SYMBOL (cmdq_pkt_destroy );
112
152
113
- static int cmdq_pkt_append_command (struct cmdq_pkt * pkt , enum cmdq_code code ,
114
- u32 arg_a , u32 arg_b )
153
+ static int cmdq_pkt_append_command (struct cmdq_pkt * pkt ,
154
+ struct cmdq_instruction inst )
115
155
{
116
- u64 * cmd_ptr ;
156
+ struct cmdq_instruction * cmd_ptr ;
117
157
118
158
if (unlikely (pkt -> cmd_buf_size + CMDQ_INST_SIZE > pkt -> buf_size )) {
119
159
/*
@@ -129,77 +169,130 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
129
169
__func__ , (u32 )pkt -> buf_size );
130
170
return - ENOMEM ;
131
171
}
172
+
132
173
cmd_ptr = pkt -> va_base + pkt -> cmd_buf_size ;
133
- ( * cmd_ptr ) = ( u64 )(( code << CMDQ_OP_CODE_SHIFT ) | arg_a ) << 32 | arg_b ;
174
+ * cmd_ptr = inst ;
134
175
pkt -> cmd_buf_size += CMDQ_INST_SIZE ;
135
176
136
177
return 0 ;
137
178
}
138
179
139
180
int cmdq_pkt_write (struct cmdq_pkt * pkt , u8 subsys , u16 offset , u32 value )
140
181
{
141
- u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK ) |
142
- (subsys << CMDQ_SUBSYS_SHIFT );
182
+ struct cmdq_instruction inst ;
143
183
144
- 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 );
145
190
}
146
191
EXPORT_SYMBOL (cmdq_pkt_write );
147
192
148
193
int cmdq_pkt_write_mask (struct cmdq_pkt * pkt , u8 subsys ,
149
194
u16 offset , u32 value , u32 mask )
150
195
{
151
- u32 offset_mask = offset ;
152
- int err = 0 ;
196
+ struct cmdq_instruction inst = { {0 } };
197
+ u16 offset_mask = offset ;
198
+ int err ;
153
199
154
200
if (mask != 0xffffffff ) {
155
- 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
+
156
207
offset_mask |= CMDQ_WRITE_ENABLE_MASK ;
157
208
}
158
- err | = cmdq_pkt_write (pkt , subsys , offset_mask , value );
209
+ err = cmdq_pkt_write (pkt , subsys , offset_mask , value );
159
210
160
211
return err ;
161
212
}
162
213
EXPORT_SYMBOL (cmdq_pkt_write_mask );
163
214
164
215
int cmdq_pkt_wfe (struct cmdq_pkt * pkt , u16 event )
165
216
{
166
- u32 arg_b ;
217
+ struct cmdq_instruction inst = { { 0 } } ;
167
218
168
219
if (event >= CMDQ_MAX_EVENT )
169
220
return - EINVAL ;
170
221
171
- /*
172
- * WFE arg_b
173
- * bit 0-11: wait value
174
- * bit 15: 1 - wait, 0 - no wait
175
- * bit 16-27: update value
176
- * bit 31: 1 - update, 0 - no update
177
- */
178
- 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 ;
179
225
180
- return cmdq_pkt_append_command (pkt , CMDQ_CODE_WFE , event , arg_b );
226
+ return cmdq_pkt_append_command (pkt , inst );
181
227
}
182
228
EXPORT_SYMBOL (cmdq_pkt_wfe );
183
229
184
230
int cmdq_pkt_clear_event (struct cmdq_pkt * pkt , u16 event )
185
231
{
232
+ struct cmdq_instruction inst = { {0 } };
233
+
186
234
if (event >= CMDQ_MAX_EVENT )
187
235
return - EINVAL ;
188
236
189
- return cmdq_pkt_append_command (pkt , CMDQ_CODE_WFE , event ,
190
- 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 );
191
242
}
192
243
EXPORT_SYMBOL (cmdq_pkt_clear_event );
193
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
+
194
280
static int cmdq_pkt_finalize (struct cmdq_pkt * pkt )
195
281
{
282
+ struct cmdq_instruction inst = { {0 } };
196
283
int err ;
197
284
198
285
/* insert EOC and generate IRQ for each command iteration */
199
- 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 ;
200
291
201
292
/* JUMP to end */
202
- 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 );
203
296
204
297
return err ;
205
298
}
0 commit comments