@@ -38,6 +38,7 @@ struct imx_sc_ipc {
38
38
struct device * dev ;
39
39
struct mutex lock ;
40
40
struct completion done ;
41
+ bool fast_ipc ;
41
42
42
43
/* temporarily store the SCU msg */
43
44
u32 * msg ;
@@ -115,13 +116,27 @@ static void imx_scu_rx_callback(struct mbox_client *c, void *msg)
115
116
struct imx_sc_ipc * sc_ipc = sc_chan -> sc_ipc ;
116
117
struct imx_sc_rpc_msg * hdr ;
117
118
u32 * data = msg ;
119
+ int i ;
118
120
119
121
if (!sc_ipc -> msg ) {
120
122
dev_warn (sc_ipc -> dev , "unexpected rx idx %d 0x%08x, ignore!\n" ,
121
123
sc_chan -> idx , * data );
122
124
return ;
123
125
}
124
126
127
+ if (sc_ipc -> fast_ipc ) {
128
+ hdr = msg ;
129
+ sc_ipc -> rx_size = hdr -> size ;
130
+ sc_ipc -> msg [0 ] = * data ++ ;
131
+
132
+ for (i = 1 ; i < sc_ipc -> rx_size ; i ++ )
133
+ sc_ipc -> msg [i ] = * data ++ ;
134
+
135
+ complete (& sc_ipc -> done );
136
+
137
+ return ;
138
+ }
139
+
125
140
if (sc_chan -> idx == 0 ) {
126
141
hdr = msg ;
127
142
sc_ipc -> rx_size = hdr -> size ;
@@ -147,6 +162,7 @@ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg)
147
162
struct imx_sc_chan * sc_chan ;
148
163
u32 * data = msg ;
149
164
int ret ;
165
+ int size ;
150
166
int i ;
151
167
152
168
/* Check size */
@@ -156,7 +172,8 @@ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg)
156
172
dev_dbg (sc_ipc -> dev , "RPC SVC %u FUNC %u SIZE %u\n" , hdr -> svc ,
157
173
hdr -> func , hdr -> size );
158
174
159
- for (i = 0 ; i < hdr -> size ; i ++ ) {
175
+ size = sc_ipc -> fast_ipc ? 1 : hdr -> size ;
176
+ for (i = 0 ; i < size ; i ++ ) {
160
177
sc_chan = & sc_ipc -> chans [i % 4 ];
161
178
162
179
/*
@@ -168,8 +185,10 @@ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg)
168
185
* Wait for tx_done before every send to ensure that no
169
186
* queueing happens at the mailbox channel level.
170
187
*/
171
- wait_for_completion (& sc_chan -> tx_done );
172
- reinit_completion (& sc_chan -> tx_done );
188
+ if (!sc_ipc -> fast_ipc ) {
189
+ wait_for_completion (& sc_chan -> tx_done );
190
+ reinit_completion (& sc_chan -> tx_done );
191
+ }
173
192
174
193
ret = mbox_send_message (sc_chan -> ch , & data [i ]);
175
194
if (ret < 0 )
@@ -246,18 +265,29 @@ static int imx_scu_probe(struct platform_device *pdev)
246
265
struct imx_sc_chan * sc_chan ;
247
266
struct mbox_client * cl ;
248
267
char * chan_name ;
268
+ struct of_phandle_args args ;
269
+ int num_channel ;
249
270
int ret ;
250
271
int i ;
251
272
252
273
sc_ipc = devm_kzalloc (dev , sizeof (* sc_ipc ), GFP_KERNEL );
253
274
if (!sc_ipc )
254
275
return - ENOMEM ;
255
276
256
- for (i = 0 ; i < SCU_MU_CHAN_NUM ; i ++ ) {
257
- if (i < 4 )
277
+ ret = of_parse_phandle_with_args (pdev -> dev .of_node , "mboxes" ,
278
+ "#mbox-cells" , 0 , & args );
279
+ if (ret )
280
+ return ret ;
281
+
282
+ sc_ipc -> fast_ipc = of_device_is_compatible (args .np , "fsl,imx8-mu-scu" );
283
+
284
+ num_channel = sc_ipc -> fast_ipc ? 2 : SCU_MU_CHAN_NUM ;
285
+ for (i = 0 ; i < num_channel ; i ++ ) {
286
+ if (i < num_channel / 2 )
258
287
chan_name = kasprintf (GFP_KERNEL , "tx%d" , i );
259
288
else
260
- chan_name = kasprintf (GFP_KERNEL , "rx%d" , i - 4 );
289
+ chan_name = kasprintf (GFP_KERNEL , "rx%d" ,
290
+ i - num_channel / 2 );
261
291
262
292
if (!chan_name )
263
293
return - ENOMEM ;
@@ -269,13 +299,15 @@ static int imx_scu_probe(struct platform_device *pdev)
269
299
cl -> knows_txdone = true;
270
300
cl -> rx_callback = imx_scu_rx_callback ;
271
301
272
- /* Initial tx_done completion as "done" */
273
- cl -> tx_done = imx_scu_tx_done ;
274
- init_completion (& sc_chan -> tx_done );
275
- complete (& sc_chan -> tx_done );
302
+ if (!sc_ipc -> fast_ipc ) {
303
+ /* Initial tx_done completion as "done" */
304
+ cl -> tx_done = imx_scu_tx_done ;
305
+ init_completion (& sc_chan -> tx_done );
306
+ complete (& sc_chan -> tx_done );
307
+ }
276
308
277
309
sc_chan -> sc_ipc = sc_ipc ;
278
- sc_chan -> idx = i % 4 ;
310
+ sc_chan -> idx = i % ( num_channel / 2 ) ;
279
311
sc_chan -> ch = mbox_request_channel_byname (cl , chan_name );
280
312
if (IS_ERR (sc_chan -> ch )) {
281
313
ret = PTR_ERR (sc_chan -> ch );
0 commit comments