4
4
* Copyright 2022 NXP, Peng Fan <peng.fan@nxp.com>
5
5
*/
6
6
7
+ #include <linux/bitfield.h>
7
8
#include <linux/clk.h>
8
9
#include <linux/firmware/imx/ipc.h>
9
10
#include <linux/firmware/imx/s4.h>
29
30
#define IMX_MU_S4_CHANS 2
30
31
#define IMX_MU_CHAN_NAME_SIZE 20
31
32
32
- #define IMX_MU_NUM_RR 4
33
+ #define IMX_MU_V2_PAR_OFF 0x4
34
+ #define IMX_MU_V2_TR_MASK GENMASK(7, 0)
35
+ #define IMX_MU_V2_RR_MASK GENMASK(15, 8)
33
36
34
37
#define IMX_MU_SECO_TX_TOUT (msecs_to_jiffies(3000))
35
38
#define IMX_MU_SECO_RX_TOUT (msecs_to_jiffies(3000))
@@ -93,10 +96,11 @@ struct imx_mu_priv {
93
96
struct clk * clk ;
94
97
int irq [IMX_MU_CHANS ];
95
98
bool suspend ;
96
-
97
- u32 xcr [IMX_MU_xCR_MAX ];
98
-
99
99
bool side_b ;
100
+
101
+ u32 xcr [IMX_MU_xCR_MAX ];
102
+ u32 num_tr ;
103
+ u32 num_rr ;
100
104
};
101
105
102
106
enum imx_mu_type {
@@ -264,18 +268,17 @@ static int imx_mu_generic_rxdb(struct imx_mu_priv *priv,
264
268
static int imx_mu_specific_tx (struct imx_mu_priv * priv , struct imx_mu_con_priv * cp , void * data )
265
269
{
266
270
u32 * arg = data ;
271
+ u32 num_tr = priv -> num_tr ;
267
272
int i , ret ;
268
273
u32 xsr ;
269
- u32 size , max_size , num_tr ;
274
+ u32 size , max_size ;
270
275
271
276
if (priv -> dcfg -> type & IMX_MU_V2_S4 ) {
272
277
size = ((struct imx_s4_rpc_msg_max * )data )-> hdr .size ;
273
278
max_size = sizeof (struct imx_s4_rpc_msg_max );
274
- num_tr = 8 ;
275
279
} else {
276
280
size = ((struct imx_sc_rpc_msg_max * )data )-> hdr .size ;
277
281
max_size = sizeof (struct imx_sc_rpc_msg_max );
278
- num_tr = 4 ;
279
282
}
280
283
281
284
switch (cp -> type ) {
@@ -324,6 +327,7 @@ static int imx_mu_specific_rx(struct imx_mu_priv *priv, struct imx_mu_con_priv *
324
327
int i , ret ;
325
328
u32 xsr ;
326
329
u32 size , max_size ;
330
+ u32 num_rr = priv -> num_rr ;
327
331
328
332
data = (u32 * )priv -> msg ;
329
333
@@ -345,13 +349,13 @@ static int imx_mu_specific_rx(struct imx_mu_priv *priv, struct imx_mu_con_priv *
345
349
346
350
for (i = 1 ; i < size ; i ++ ) {
347
351
ret = readl_poll_timeout (priv -> base + priv -> dcfg -> xSR [IMX_MU_RSR ], xsr ,
348
- xsr & IMX_MU_xSR_RFn (priv -> dcfg -> type , i % 4 ), 0 ,
352
+ xsr & IMX_MU_xSR_RFn (priv -> dcfg -> type , i % num_rr ), 0 ,
349
353
5 * USEC_PER_SEC );
350
354
if (ret ) {
351
355
dev_err (priv -> dev , "timeout read idx %d\n" , i );
352
356
return ret ;
353
357
}
354
- * data ++ = imx_mu_read (priv , priv -> dcfg -> xRR + (i % 4 ) * 4 );
358
+ * data ++ = imx_mu_read (priv , priv -> dcfg -> xRR + (i % num_rr ) * 4 );
355
359
}
356
360
357
361
imx_mu_xcr_rmw (priv , IMX_MU_RCR , IMX_MU_xCR_RIEn (priv -> dcfg -> type , 0 ), 0 );
@@ -737,11 +741,30 @@ static struct mbox_chan *imx_mu_seco_xlate(struct mbox_controller *mbox,
737
741
return imx_mu_xlate (mbox , sp );
738
742
}
739
743
744
+ static void imx_mu_get_tr_rr (struct imx_mu_priv * priv )
745
+ {
746
+ u32 val ;
747
+
748
+ if (priv -> dcfg -> type & IMX_MU_V2 ) {
749
+ val = imx_mu_read (priv , IMX_MU_V2_PAR_OFF );
750
+ priv -> num_tr = FIELD_GET (IMX_MU_V2_TR_MASK , val );
751
+ priv -> num_rr = FIELD_GET (IMX_MU_V2_RR_MASK , val );
752
+ } else {
753
+ priv -> num_tr = 4 ;
754
+ priv -> num_rr = 4 ;
755
+ }
756
+ }
757
+
740
758
static int imx_mu_init_generic (struct imx_mu_priv * priv )
741
759
{
742
760
unsigned int i ;
743
761
unsigned int val ;
744
762
763
+ if (priv -> num_rr > 4 || priv -> num_tr > 4 ) {
764
+ WARN_ONCE (true, "%s not support TR/RR larger than 4\n" , __func__ );
765
+ return - EOPNOTSUPP ;
766
+ }
767
+
745
768
for (i = 0 ; i < IMX_MU_CHANS ; i ++ ) {
746
769
struct imx_mu_con_priv * cp = & priv -> con_priv [i ];
747
770
@@ -768,8 +791,8 @@ static int imx_mu_init_generic(struct imx_mu_priv *priv)
768
791
imx_mu_write (priv , val , priv -> dcfg -> xSR [IMX_MU_GSR ]);
769
792
770
793
/* Clear any pending RSR */
771
- for (i = 0 ; i < IMX_MU_NUM_RR ; i ++ )
772
- imx_mu_read (priv , priv -> dcfg -> xRR + ( i % 4 ) * 4 );
794
+ for (i = 0 ; i < priv -> num_rr ; i ++ )
795
+ imx_mu_read (priv , priv -> dcfg -> xRR + i * 4 );
773
796
774
797
return 0 ;
775
798
}
@@ -874,6 +897,8 @@ static int imx_mu_probe(struct platform_device *pdev)
874
897
return ret ;
875
898
}
876
899
900
+ imx_mu_get_tr_rr (priv );
901
+
877
902
priv -> side_b = of_property_read_bool (np , "fsl,mu-side-b" );
878
903
879
904
ret = priv -> dcfg -> init (priv );
0 commit comments