5
5
6
6
#include <linux/clk.h>
7
7
#include <linux/firmware/imx/ipc.h>
8
+ #include <linux/firmware/imx/s4.h>
8
9
#include <linux/interrupt.h>
9
10
#include <linux/io.h>
10
11
#include <linux/iopoll.h>
18
19
#define IMX_MU_CHANS 16
19
20
/* TX0/RX0/RXDB[0-3] */
20
21
#define IMX_MU_SCU_CHANS 6
22
+ /* TX0/RX0 */
23
+ #define IMX_MU_S4_CHANS 2
21
24
#define IMX_MU_CHAN_NAME_SIZE 20
22
25
23
26
enum imx_mu_chan_type {
@@ -47,6 +50,11 @@ struct imx_sc_rpc_msg_max {
47
50
u32 data [7 ];
48
51
};
49
52
53
+ struct imx_s4_rpc_msg_max {
54
+ struct imx_s4_rpc_msg hdr ;
55
+ u32 data [254 ];
56
+ };
57
+
50
58
struct imx_mu_con_priv {
51
59
unsigned int idx ;
52
60
char irq_desc [IMX_MU_CHAN_NAME_SIZE ];
@@ -58,6 +66,7 @@ struct imx_mu_con_priv {
58
66
struct imx_mu_priv {
59
67
struct device * dev ;
60
68
void __iomem * base ;
69
+ void * msg ;
61
70
spinlock_t xcr_lock ; /* control register lock */
62
71
63
72
struct mbox_controller mbox ;
@@ -75,7 +84,8 @@ struct imx_mu_priv {
75
84
76
85
enum imx_mu_type {
77
86
IMX_MU_V1 ,
78
- IMX_MU_V2 ,
87
+ IMX_MU_V2 = BIT (1 ),
88
+ IMX_MU_V2_S4 = BIT (15 ),
79
89
};
80
90
81
91
struct imx_mu_dcfg {
@@ -89,18 +99,18 @@ struct imx_mu_dcfg {
89
99
u32 xCR [4 ]; /* Control Registers */
90
100
};
91
101
92
- #define IMX_MU_xSR_GIPn (type , x ) (type == IMX_MU_V2 ? BIT(x) : BIT(28 + (3 - (x))))
93
- #define IMX_MU_xSR_RFn (type , x ) (type == IMX_MU_V2 ? BIT(x) : BIT(24 + (3 - (x))))
94
- #define IMX_MU_xSR_TEn (type , x ) (type == IMX_MU_V2 ? BIT(x) : BIT(20 + (3 - (x))))
102
+ #define IMX_MU_xSR_GIPn (type , x ) (type & IMX_MU_V2 ? BIT(x) : BIT(28 + (3 - (x))))
103
+ #define IMX_MU_xSR_RFn (type , x ) (type & IMX_MU_V2 ? BIT(x) : BIT(24 + (3 - (x))))
104
+ #define IMX_MU_xSR_TEn (type , x ) (type & IMX_MU_V2 ? BIT(x) : BIT(20 + (3 - (x))))
95
105
96
106
/* General Purpose Interrupt Enable */
97
- #define IMX_MU_xCR_GIEn (type , x ) (type == IMX_MU_V2 ? BIT(x) : BIT(28 + (3 - (x))))
107
+ #define IMX_MU_xCR_GIEn (type , x ) (type & IMX_MU_V2 ? BIT(x) : BIT(28 + (3 - (x))))
98
108
/* Receive Interrupt Enable */
99
- #define IMX_MU_xCR_RIEn (type , x ) (type == IMX_MU_V2 ? BIT(x) : BIT(24 + (3 - (x))))
109
+ #define IMX_MU_xCR_RIEn (type , x ) (type & IMX_MU_V2 ? BIT(x) : BIT(24 + (3 - (x))))
100
110
/* Transmit Interrupt Enable */
101
- #define IMX_MU_xCR_TIEn (type , x ) (type == IMX_MU_V2 ? BIT(x) : BIT(20 + (3 - (x))))
111
+ #define IMX_MU_xCR_TIEn (type , x ) (type & IMX_MU_V2 ? BIT(x) : BIT(20 + (3 - (x))))
102
112
/* General Purpose Interrupt Request */
103
- #define IMX_MU_xCR_GIRn (type , x ) (type == IMX_MU_V2 ? BIT(x) : BIT(16 + (3 - (x))))
113
+ #define IMX_MU_xCR_GIRn (type , x ) (type & IMX_MU_V2 ? BIT(x) : BIT(16 + (3 - (x))))
104
114
105
115
106
116
static struct imx_mu_priv * to_imx_mu_priv (struct mbox_controller * mbox )
@@ -167,14 +177,22 @@ static int imx_mu_generic_rx(struct imx_mu_priv *priv,
167
177
return 0 ;
168
178
}
169
179
170
- static int imx_mu_scu_tx (struct imx_mu_priv * priv ,
171
- struct imx_mu_con_priv * cp ,
172
- void * data )
180
+ static int imx_mu_specific_tx (struct imx_mu_priv * priv , struct imx_mu_con_priv * cp , void * data )
173
181
{
174
- struct imx_sc_rpc_msg_max * msg = data ;
175
182
u32 * arg = data ;
176
183
int i , ret ;
177
184
u32 xsr ;
185
+ u32 size , max_size , num_tr ;
186
+
187
+ if (priv -> dcfg -> type & IMX_MU_V2_S4 ) {
188
+ size = ((struct imx_s4_rpc_msg_max * )data )-> hdr .size ;
189
+ max_size = sizeof (struct imx_s4_rpc_msg_max );
190
+ num_tr = 8 ;
191
+ } else {
192
+ size = ((struct imx_sc_rpc_msg_max * )data )-> hdr .size ;
193
+ max_size = sizeof (struct imx_sc_rpc_msg_max );
194
+ num_tr = 4 ;
195
+ }
178
196
179
197
switch (cp -> type ) {
180
198
case IMX_MU_TYPE_TX :
@@ -183,27 +201,27 @@ static int imx_mu_scu_tx(struct imx_mu_priv *priv,
183
201
* sizeof yields bytes.
184
202
*/
185
203
186
- if (msg -> hdr . size > sizeof ( * msg ) / 4 ) {
204
+ if (size > max_size / 4 ) {
187
205
/*
188
206
* The real message size can be different to
189
- * struct imx_sc_rpc_msg_max size
207
+ * struct imx_sc_rpc_msg_max/imx_s4_rpc_msg_max size
190
208
*/
191
- dev_err (priv -> dev , "Maximal message size (%zu bytes) exceeded on TX; got: %i bytes\n" , sizeof ( * msg ), msg -> hdr . size << 2 );
209
+ dev_err (priv -> dev , "Maximal message size (%u bytes) exceeded on TX; got: %i bytes\n" , max_size , size << 2 );
192
210
return - EINVAL ;
193
211
}
194
212
195
- for (i = 0 ; i < 4 && i < msg -> hdr . size ; i ++ )
196
- imx_mu_write (priv , * arg ++ , priv -> dcfg -> xTR + (i % 4 ) * 4 );
197
- for (; i < msg -> hdr . size ; i ++ ) {
213
+ for (i = 0 ; i < num_tr && i < size ; i ++ )
214
+ imx_mu_write (priv , * arg ++ , priv -> dcfg -> xTR + (i % num_tr ) * 4 );
215
+ for (; i < size ; i ++ ) {
198
216
ret = readl_poll_timeout (priv -> base + priv -> dcfg -> xSR [IMX_MU_TSR ],
199
217
xsr ,
200
- xsr & IMX_MU_xSR_TEn (priv -> dcfg -> type , i % 4 ),
218
+ xsr & IMX_MU_xSR_TEn (priv -> dcfg -> type , i % num_tr ),
201
219
0 , 100 );
202
220
if (ret ) {
203
221
dev_err (priv -> dev , "Send data index: %d timeout\n" , i );
204
222
return ret ;
205
223
}
206
- imx_mu_write (priv , * arg ++ , priv -> dcfg -> xTR + (i % 4 ) * 4 );
224
+ imx_mu_write (priv , * arg ++ , priv -> dcfg -> xTR + (i % num_tr ) * 4 );
207
225
}
208
226
209
227
imx_mu_xcr_rmw (priv , IMX_MU_TCR , IMX_MU_xCR_TIEn (priv -> dcfg -> type , cp -> idx ), 0 );
@@ -216,23 +234,32 @@ static int imx_mu_scu_tx(struct imx_mu_priv *priv,
216
234
return 0 ;
217
235
}
218
236
219
- static int imx_mu_scu_rx (struct imx_mu_priv * priv ,
220
- struct imx_mu_con_priv * cp )
237
+ static int imx_mu_specific_rx (struct imx_mu_priv * priv , struct imx_mu_con_priv * cp )
221
238
{
222
- struct imx_sc_rpc_msg_max msg ;
223
- u32 * data = (u32 * )& msg ;
239
+ u32 * data ;
224
240
int i , ret ;
225
241
u32 xsr ;
242
+ u32 size , max_size ;
243
+
244
+ data = (u32 * )priv -> msg ;
226
245
227
246
imx_mu_xcr_rmw (priv , IMX_MU_RCR , 0 , IMX_MU_xCR_RIEn (priv -> dcfg -> type , 0 ));
228
247
* data ++ = imx_mu_read (priv , priv -> dcfg -> xRR );
229
248
230
- if (msg .hdr .size > sizeof (msg ) / 4 ) {
231
- dev_err (priv -> dev , "Maximal message size (%zu bytes) exceeded on RX; got: %i bytes\n" , sizeof (msg ), msg .hdr .size << 2 );
249
+ if (priv -> dcfg -> type & IMX_MU_V2_S4 ) {
250
+ size = ((struct imx_s4_rpc_msg_max * )priv -> msg )-> hdr .size ;
251
+ max_size = sizeof (struct imx_s4_rpc_msg_max );
252
+ } else {
253
+ size = ((struct imx_sc_rpc_msg_max * )priv -> msg )-> hdr .size ;
254
+ max_size = sizeof (struct imx_sc_rpc_msg_max );
255
+ }
256
+
257
+ if (size > max_size / 4 ) {
258
+ dev_err (priv -> dev , "Maximal message size (%u bytes) exceeded on RX; got: %i bytes\n" , max_size , size << 2 );
232
259
return - EINVAL ;
233
260
}
234
261
235
- for (i = 1 ; i < msg . hdr . size ; i ++ ) {
262
+ for (i = 1 ; i < size ; i ++ ) {
236
263
ret = readl_poll_timeout (priv -> base + priv -> dcfg -> xSR [IMX_MU_RSR ], xsr ,
237
264
xsr & IMX_MU_xSR_RFn (priv -> dcfg -> type , i % 4 ), 0 , 100 );
238
265
if (ret ) {
@@ -243,7 +270,7 @@ static int imx_mu_scu_rx(struct imx_mu_priv *priv,
243
270
}
244
271
245
272
imx_mu_xcr_rmw (priv , IMX_MU_RCR , IMX_MU_xCR_RIEn (priv -> dcfg -> type , 0 ), 0 );
246
- mbox_chan_received_data (cp -> chan , (void * )& msg );
273
+ mbox_chan_received_data (cp -> chan , (void * )priv -> msg );
247
274
248
275
return 0 ;
249
276
}
@@ -394,8 +421,8 @@ static const struct mbox_chan_ops imx_mu_ops = {
394
421
.shutdown = imx_mu_shutdown ,
395
422
};
396
423
397
- static struct mbox_chan * imx_mu_scu_xlate (struct mbox_controller * mbox ,
398
- const struct of_phandle_args * sp )
424
+ static struct mbox_chan * imx_mu_specific_xlate (struct mbox_controller * mbox ,
425
+ const struct of_phandle_args * sp )
399
426
{
400
427
u32 type , idx , chan ;
401
428
@@ -478,11 +505,12 @@ static void imx_mu_init_generic(struct imx_mu_priv *priv)
478
505
imx_mu_write (priv , 0 , priv -> dcfg -> xCR [i ]);
479
506
}
480
507
481
- static void imx_mu_init_scu (struct imx_mu_priv * priv )
508
+ static void imx_mu_init_specific (struct imx_mu_priv * priv )
482
509
{
483
510
unsigned int i ;
511
+ int num_chans = priv -> dcfg -> type & IMX_MU_V2_S4 ? IMX_MU_S4_CHANS : IMX_MU_SCU_CHANS ;
484
512
485
- for (i = 0 ; i < IMX_MU_SCU_CHANS ; i ++ ) {
513
+ for (i = 0 ; i < num_chans ; i ++ ) {
486
514
struct imx_mu_con_priv * cp = & priv -> con_priv [i ];
487
515
488
516
cp -> idx = i < 2 ? 0 : i - 2 ;
@@ -493,8 +521,8 @@ static void imx_mu_init_scu(struct imx_mu_priv *priv)
493
521
"imx_mu_chan[%i-%i]" , cp -> type , cp -> idx );
494
522
}
495
523
496
- priv -> mbox .num_chans = IMX_MU_SCU_CHANS ;
497
- priv -> mbox .of_xlate = imx_mu_scu_xlate ;
524
+ priv -> mbox .num_chans = num_chans ;
525
+ priv -> mbox .of_xlate = imx_mu_specific_xlate ;
498
526
499
527
/* Set default MU configuration */
500
528
for (i = 0 ; i < IMX_MU_xCR_MAX ; i ++ )
@@ -508,6 +536,7 @@ static int imx_mu_probe(struct platform_device *pdev)
508
536
struct imx_mu_priv * priv ;
509
537
const struct imx_mu_dcfg * dcfg ;
510
538
int ret ;
539
+ u32 size ;
511
540
512
541
priv = devm_kzalloc (dev , sizeof (* priv ), GFP_KERNEL );
513
542
if (!priv )
@@ -528,6 +557,15 @@ static int imx_mu_probe(struct platform_device *pdev)
528
557
return - EINVAL ;
529
558
priv -> dcfg = dcfg ;
530
559
560
+ if (priv -> dcfg -> type & IMX_MU_V2_S4 )
561
+ size = sizeof (struct imx_s4_rpc_msg_max );
562
+ else
563
+ size = sizeof (struct imx_sc_rpc_msg_max );
564
+
565
+ priv -> msg = devm_kzalloc (dev , size , GFP_KERNEL );
566
+ if (IS_ERR (priv -> msg ))
567
+ return PTR_ERR (priv -> msg );
568
+
531
569
priv -> clk = devm_clk_get (dev , NULL );
532
570
if (IS_ERR (priv -> clk )) {
533
571
if (PTR_ERR (priv -> clk ) != - ENOENT )
@@ -623,10 +661,21 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = {
623
661
.xCR = {0x110 , 0x114 , 0x120 , 0x128 },
624
662
};
625
663
664
+ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp_s4 = {
665
+ .tx = imx_mu_specific_tx ,
666
+ .rx = imx_mu_specific_rx ,
667
+ .init = imx_mu_init_specific ,
668
+ .type = IMX_MU_V2 | IMX_MU_V2_S4 ,
669
+ .xTR = 0x200 ,
670
+ .xRR = 0x280 ,
671
+ .xSR = {0xC , 0x118 , 0x124 , 0x12C },
672
+ .xCR = {0x110 , 0x114 , 0x120 , 0x128 },
673
+ };
674
+
626
675
static const struct imx_mu_dcfg imx_mu_cfg_imx8_scu = {
627
- .tx = imx_mu_scu_tx ,
628
- .rx = imx_mu_scu_rx ,
629
- .init = imx_mu_init_scu ,
676
+ .tx = imx_mu_specific_tx ,
677
+ .rx = imx_mu_specific_rx ,
678
+ .init = imx_mu_init_specific ,
630
679
.xTR = 0x0 ,
631
680
.xRR = 0x10 ,
632
681
.xSR = {0x20 , 0x20 , 0x20 , 0x20 },
@@ -637,6 +686,7 @@ static const struct of_device_id imx_mu_dt_ids[] = {
637
686
{ .compatible = "fsl,imx7ulp-mu" , .data = & imx_mu_cfg_imx7ulp },
638
687
{ .compatible = "fsl,imx6sx-mu" , .data = & imx_mu_cfg_imx6sx },
639
688
{ .compatible = "fsl,imx8ulp-mu" , .data = & imx_mu_cfg_imx8ulp },
689
+ { .compatible = "fsl,imx8ulp-mu-s4" , .data = & imx_mu_cfg_imx8ulp_s4 },
640
690
{ .compatible = "fsl,imx8-mu-scu" , .data = & imx_mu_cfg_imx8_scu },
641
691
{ },
642
692
};
0 commit comments