99#include <linux/mailbox_controller.h>
1010#include <linux/soc/mediatek/mtk-cmdq.h>
1111
12- #define CMDQ_ARG_A_WRITE_MASK 0xffff
1312#define CMDQ_WRITE_ENABLE_MASK BIT(0)
13+ #define CMDQ_POLL_ENABLE_MASK BIT(0)
1414#define CMDQ_EOC_IRQ_EN BIT(0)
1515#define CMDQ_EOC_CMD ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
1616 << 32 | CMDQ_EOC_IRQ_EN)
1717
18+ struct cmdq_instruction {
19+ union {
20+ u32 value ;
21+ u32 mask ;
22+ };
23+ union {
24+ u16 offset ;
25+ u16 event ;
26+ };
27+ u8 subsys ;
28+ u8 op ;
29+ };
30+
31+ int cmdq_dev_get_client_reg (struct device * dev ,
32+ struct cmdq_client_reg * client_reg , int idx )
33+ {
34+ struct of_phandle_args spec ;
35+ int err ;
36+
37+ if (!client_reg )
38+ return - ENOENT ;
39+
40+ err = of_parse_phandle_with_fixed_args (dev -> of_node ,
41+ "mediatek,gce-client-reg" ,
42+ 3 , idx , & spec );
43+ if (err < 0 ) {
44+ dev_err (dev ,
45+ "error %d can't parse gce-client-reg property (%d)" ,
46+ err , idx );
47+
48+ return err ;
49+ }
50+
51+ client_reg -> subsys = (u8 )spec .args [0 ];
52+ client_reg -> offset = (u16 )spec .args [1 ];
53+ client_reg -> size = (u16 )spec .args [2 ];
54+ of_node_put (spec .np );
55+
56+ return 0 ;
57+ }
58+ EXPORT_SYMBOL (cmdq_dev_get_client_reg );
59+
1860static void cmdq_client_timeout (struct timer_list * t )
1961{
2062 struct cmdq_client * client = from_timer (client , t , timer );
@@ -110,10 +152,10 @@ void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
110152}
111153EXPORT_SYMBOL (cmdq_pkt_destroy );
112154
113- static int cmdq_pkt_append_command (struct cmdq_pkt * pkt , enum cmdq_code code ,
114- u32 arg_a , u32 arg_b )
155+ static int cmdq_pkt_append_command (struct cmdq_pkt * pkt ,
156+ struct cmdq_instruction inst )
115157{
116- u64 * cmd_ptr ;
158+ struct cmdq_instruction * cmd_ptr ;
117159
118160 if (unlikely (pkt -> cmd_buf_size + CMDQ_INST_SIZE > pkt -> buf_size )) {
119161 /*
@@ -129,77 +171,130 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
129171 __func__ , (u32 )pkt -> buf_size );
130172 return - ENOMEM ;
131173 }
174+
132175 cmd_ptr = pkt -> va_base + pkt -> cmd_buf_size ;
133- ( * cmd_ptr ) = ( u64 )(( code << CMDQ_OP_CODE_SHIFT ) | arg_a ) << 32 | arg_b ;
176+ * cmd_ptr = inst ;
134177 pkt -> cmd_buf_size += CMDQ_INST_SIZE ;
135178
136179 return 0 ;
137180}
138181
139182int cmdq_pkt_write (struct cmdq_pkt * pkt , u8 subsys , u16 offset , u32 value )
140183{
141- u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK ) |
142- (subsys << CMDQ_SUBSYS_SHIFT );
184+ struct cmdq_instruction inst ;
143185
144- return cmdq_pkt_append_command (pkt , CMDQ_CODE_WRITE , arg_a , value );
186+ inst .op = CMDQ_CODE_WRITE ;
187+ inst .value = value ;
188+ inst .offset = offset ;
189+ inst .subsys = subsys ;
190+
191+ return cmdq_pkt_append_command (pkt , inst );
145192}
146193EXPORT_SYMBOL (cmdq_pkt_write );
147194
148195int cmdq_pkt_write_mask (struct cmdq_pkt * pkt , u8 subsys ,
149196 u16 offset , u32 value , u32 mask )
150197{
151- u32 offset_mask = offset ;
152- int err = 0 ;
198+ struct cmdq_instruction inst = { {0 } };
199+ u16 offset_mask = offset ;
200+ int err ;
153201
154202 if (mask != 0xffffffff ) {
155- err = cmdq_pkt_append_command (pkt , CMDQ_CODE_MASK , 0 , ~mask );
203+ inst .op = CMDQ_CODE_MASK ;
204+ inst .mask = ~mask ;
205+ err = cmdq_pkt_append_command (pkt , inst );
206+ if (err < 0 )
207+ return err ;
208+
156209 offset_mask |= CMDQ_WRITE_ENABLE_MASK ;
157210 }
158- err | = cmdq_pkt_write (pkt , subsys , offset_mask , value );
211+ err = cmdq_pkt_write (pkt , subsys , offset_mask , value );
159212
160213 return err ;
161214}
162215EXPORT_SYMBOL (cmdq_pkt_write_mask );
163216
164217int cmdq_pkt_wfe (struct cmdq_pkt * pkt , u16 event )
165218{
166- u32 arg_b ;
219+ struct cmdq_instruction inst = { { 0 } } ;
167220
168221 if (event >= CMDQ_MAX_EVENT )
169222 return - EINVAL ;
170223
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 ;
224+ inst .op = CMDQ_CODE_WFE ;
225+ inst .value = CMDQ_WFE_OPTION ;
226+ inst .event = event ;
179227
180- return cmdq_pkt_append_command (pkt , CMDQ_CODE_WFE , event , arg_b );
228+ return cmdq_pkt_append_command (pkt , inst );
181229}
182230EXPORT_SYMBOL (cmdq_pkt_wfe );
183231
184232int cmdq_pkt_clear_event (struct cmdq_pkt * pkt , u16 event )
185233{
234+ struct cmdq_instruction inst = { {0 } };
235+
186236 if (event >= CMDQ_MAX_EVENT )
187237 return - EINVAL ;
188238
189- return cmdq_pkt_append_command (pkt , CMDQ_CODE_WFE , event ,
190- CMDQ_WFE_UPDATE );
239+ inst .op = CMDQ_CODE_WFE ;
240+ inst .value = CMDQ_WFE_UPDATE ;
241+ inst .event = event ;
242+
243+ return cmdq_pkt_append_command (pkt , inst );
191244}
192245EXPORT_SYMBOL (cmdq_pkt_clear_event );
193246
247+ int cmdq_pkt_poll (struct cmdq_pkt * pkt , u8 subsys ,
248+ u16 offset , u32 value )
249+ {
250+ struct cmdq_instruction inst = { {0 } };
251+ int err ;
252+
253+ inst .op = CMDQ_CODE_POLL ;
254+ inst .value = value ;
255+ inst .offset = offset ;
256+ inst .subsys = subsys ;
257+ err = cmdq_pkt_append_command (pkt , inst );
258+
259+ return err ;
260+ }
261+ EXPORT_SYMBOL (cmdq_pkt_poll );
262+
263+ int cmdq_pkt_poll_mask (struct cmdq_pkt * pkt , u8 subsys ,
264+ u16 offset , u32 value , u32 mask )
265+ {
266+ struct cmdq_instruction inst = { {0 } };
267+ int err ;
268+
269+ inst .op = CMDQ_CODE_MASK ;
270+ inst .mask = ~mask ;
271+ err = cmdq_pkt_append_command (pkt , inst );
272+ if (err < 0 )
273+ return err ;
274+
275+ offset = offset | CMDQ_POLL_ENABLE_MASK ;
276+ err = cmdq_pkt_poll (pkt , subsys , offset , value );
277+
278+ return err ;
279+ }
280+ EXPORT_SYMBOL (cmdq_pkt_poll_mask );
281+
194282static int cmdq_pkt_finalize (struct cmdq_pkt * pkt )
195283{
284+ struct cmdq_instruction inst = { {0 } };
196285 int err ;
197286
198287 /* insert EOC and generate IRQ for each command iteration */
199- err = cmdq_pkt_append_command (pkt , CMDQ_CODE_EOC , 0 , CMDQ_EOC_IRQ_EN );
288+ inst .op = CMDQ_CODE_EOC ;
289+ inst .value = CMDQ_EOC_IRQ_EN ;
290+ err = cmdq_pkt_append_command (pkt , inst );
291+ if (err < 0 )
292+ return err ;
200293
201294 /* JUMP to end */
202- err |= cmdq_pkt_append_command (pkt , CMDQ_CODE_JUMP , 0 , CMDQ_JUMP_PASS );
295+ inst .op = CMDQ_CODE_JUMP ;
296+ inst .value = CMDQ_JUMP_PASS ;
297+ err = cmdq_pkt_append_command (pkt , inst );
203298
204299 return err ;
205300}
0 commit comments