44 * Copyright 2022 NXP, Peng Fan <peng.fan@nxp.com>
55 */
66
7+ #include <linux/bitfield.h>
78#include <linux/clk.h>
89#include <linux/firmware/imx/ipc.h>
910#include <linux/firmware/imx/s4.h>
2930#define IMX_MU_S4_CHANS 2
3031#define IMX_MU_CHAN_NAME_SIZE 20
3132
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)
3336
3437#define IMX_MU_SECO_TX_TOUT (msecs_to_jiffies(3000))
3538#define IMX_MU_SECO_RX_TOUT (msecs_to_jiffies(3000))
@@ -93,10 +96,11 @@ struct imx_mu_priv {
9396 struct clk * clk ;
9497 int irq [IMX_MU_CHANS ];
9598 bool suspend ;
96-
97- u32 xcr [IMX_MU_xCR_MAX ];
98-
9999 bool side_b ;
100+
101+ u32 xcr [IMX_MU_xCR_MAX ];
102+ u32 num_tr ;
103+ u32 num_rr ;
100104};
101105
102106enum imx_mu_type {
@@ -264,18 +268,17 @@ static int imx_mu_generic_rxdb(struct imx_mu_priv *priv,
264268static int imx_mu_specific_tx (struct imx_mu_priv * priv , struct imx_mu_con_priv * cp , void * data )
265269{
266270 u32 * arg = data ;
271+ u32 num_tr = priv -> num_tr ;
267272 int i , ret ;
268273 u32 xsr ;
269- u32 size , max_size , num_tr ;
274+ u32 size , max_size ;
270275
271276 if (priv -> dcfg -> type & IMX_MU_V2_S4 ) {
272277 size = ((struct imx_s4_rpc_msg_max * )data )-> hdr .size ;
273278 max_size = sizeof (struct imx_s4_rpc_msg_max );
274- num_tr = 8 ;
275279 } else {
276280 size = ((struct imx_sc_rpc_msg_max * )data )-> hdr .size ;
277281 max_size = sizeof (struct imx_sc_rpc_msg_max );
278- num_tr = 4 ;
279282 }
280283
281284 switch (cp -> type ) {
@@ -324,6 +327,7 @@ static int imx_mu_specific_rx(struct imx_mu_priv *priv, struct imx_mu_con_priv *
324327 int i , ret ;
325328 u32 xsr ;
326329 u32 size , max_size ;
330+ u32 num_rr = priv -> num_rr ;
327331
328332 data = (u32 * )priv -> msg ;
329333
@@ -345,13 +349,13 @@ static int imx_mu_specific_rx(struct imx_mu_priv *priv, struct imx_mu_con_priv *
345349
346350 for (i = 1 ; i < size ; i ++ ) {
347351 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 ,
349353 5 * USEC_PER_SEC );
350354 if (ret ) {
351355 dev_err (priv -> dev , "timeout read idx %d\n" , i );
352356 return ret ;
353357 }
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 );
355359 }
356360
357361 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,
737741 return imx_mu_xlate (mbox , sp );
738742}
739743
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+
740758static int imx_mu_init_generic (struct imx_mu_priv * priv )
741759{
742760 unsigned int i ;
743761 unsigned int val ;
744762
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+
745768 for (i = 0 ; i < IMX_MU_CHANS ; i ++ ) {
746769 struct imx_mu_con_priv * cp = & priv -> con_priv [i ];
747770
@@ -768,8 +791,8 @@ static int imx_mu_init_generic(struct imx_mu_priv *priv)
768791 imx_mu_write (priv , val , priv -> dcfg -> xSR [IMX_MU_GSR ]);
769792
770793 /* 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 );
773796
774797 return 0 ;
775798}
@@ -874,6 +897,8 @@ static int imx_mu_probe(struct platform_device *pdev)
874897 return ret ;
875898 }
876899
900+ imx_mu_get_tr_rr (priv );
901+
877902 priv -> side_b = of_property_read_bool (np , "fsl,mu-side-b" );
878903
879904 ret = priv -> dcfg -> init (priv );
0 commit comments