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>
1516#include <linux/mailbox_controller.h>
1617#include <linux/module.h>
1718#include <linux/of.h>
19+ #include <linux/of_platform.h>
1820#include <linux/platform_device.h>
1921#include <linux/pm_runtime.h>
2022#include <linux/suspend.h>
2931#define IMX_MU_S4_CHANS 2
3032#define IMX_MU_CHAN_NAME_SIZE 20
3133
32- #define IMX_MU_NUM_RR 4
34+ #define IMX_MU_V2_PAR_OFF 0x4
35+ #define IMX_MU_V2_TR_MASK GENMASK(7, 0)
36+ #define IMX_MU_V2_RR_MASK GENMASK(15, 8)
3337
3438#define IMX_MU_SECO_TX_TOUT (msecs_to_jiffies(3000))
3539#define IMX_MU_SECO_RX_TOUT (msecs_to_jiffies(3000))
@@ -93,10 +97,11 @@ struct imx_mu_priv {
9397 struct clk * clk ;
9498 int irq [IMX_MU_CHANS ];
9599 bool suspend ;
96-
97- u32 xcr [IMX_MU_xCR_MAX ];
98-
99100 bool side_b ;
101+
102+ u32 xcr [IMX_MU_xCR_MAX ];
103+ u32 num_tr ;
104+ u32 num_rr ;
100105};
101106
102107enum imx_mu_type {
@@ -110,7 +115,7 @@ struct imx_mu_dcfg {
110115 int (* tx )(struct imx_mu_priv * priv , struct imx_mu_con_priv * cp , void * data );
111116 int (* rx )(struct imx_mu_priv * priv , struct imx_mu_con_priv * cp );
112117 int (* rxdb )(struct imx_mu_priv * priv , struct imx_mu_con_priv * cp );
113- void (* init )(struct imx_mu_priv * priv );
118+ int (* init )(struct imx_mu_priv * priv );
114119 enum imx_mu_type type ;
115120 u32 xTR ; /* Transmit Register0 */
116121 u32 xRR ; /* Receive Register0 */
@@ -264,18 +269,17 @@ static int imx_mu_generic_rxdb(struct imx_mu_priv *priv,
264269static int imx_mu_specific_tx (struct imx_mu_priv * priv , struct imx_mu_con_priv * cp , void * data )
265270{
266271 u32 * arg = data ;
272+ u32 num_tr = priv -> num_tr ;
267273 int i , ret ;
268274 u32 xsr ;
269- u32 size , max_size , num_tr ;
275+ u32 size , max_size ;
270276
271277 if (priv -> dcfg -> type & IMX_MU_V2_S4 ) {
272278 size = ((struct imx_s4_rpc_msg_max * )data )-> hdr .size ;
273279 max_size = sizeof (struct imx_s4_rpc_msg_max );
274- num_tr = 8 ;
275280 } else {
276281 size = ((struct imx_sc_rpc_msg_max * )data )-> hdr .size ;
277282 max_size = sizeof (struct imx_sc_rpc_msg_max );
278- num_tr = 4 ;
279283 }
280284
281285 switch (cp -> type ) {
@@ -324,6 +328,7 @@ static int imx_mu_specific_rx(struct imx_mu_priv *priv, struct imx_mu_con_priv *
324328 int i , ret ;
325329 u32 xsr ;
326330 u32 size , max_size ;
331+ u32 num_rr = priv -> num_rr ;
327332
328333 data = (u32 * )priv -> msg ;
329334
@@ -345,13 +350,13 @@ static int imx_mu_specific_rx(struct imx_mu_priv *priv, struct imx_mu_con_priv *
345350
346351 for (i = 1 ; i < size ; i ++ ) {
347352 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 ,
353+ xsr & IMX_MU_xSR_RFn (priv -> dcfg -> type , i % num_rr ), 0 ,
349354 5 * USEC_PER_SEC );
350355 if (ret ) {
351356 dev_err (priv -> dev , "timeout read idx %d\n" , i );
352357 return ret ;
353358 }
354- * data ++ = imx_mu_read (priv , priv -> dcfg -> xRR + (i % 4 ) * 4 );
359+ * data ++ = imx_mu_read (priv , priv -> dcfg -> xRR + (i % num_rr ) * 4 );
355360 }
356361
357362 imx_mu_xcr_rmw (priv , IMX_MU_RCR , IMX_MU_xCR_RIEn (priv -> dcfg -> type , 0 ), 0 );
@@ -737,11 +742,30 @@ static struct mbox_chan *imx_mu_seco_xlate(struct mbox_controller *mbox,
737742 return imx_mu_xlate (mbox , sp );
738743}
739744
740- static void imx_mu_init_generic (struct imx_mu_priv * priv )
745+ static void imx_mu_get_tr_rr (struct imx_mu_priv * priv )
746+ {
747+ u32 val ;
748+
749+ if (priv -> dcfg -> type & IMX_MU_V2 ) {
750+ val = imx_mu_read (priv , IMX_MU_V2_PAR_OFF );
751+ priv -> num_tr = FIELD_GET (IMX_MU_V2_TR_MASK , val );
752+ priv -> num_rr = FIELD_GET (IMX_MU_V2_RR_MASK , val );
753+ } else {
754+ priv -> num_tr = 4 ;
755+ priv -> num_rr = 4 ;
756+ }
757+ }
758+
759+ static int imx_mu_init_generic (struct imx_mu_priv * priv )
741760{
742761 unsigned int i ;
743762 unsigned int val ;
744763
764+ if (priv -> num_rr > 4 || priv -> num_tr > 4 ) {
765+ WARN_ONCE (true, "%s not support TR/RR larger than 4\n" , __func__ );
766+ return - EOPNOTSUPP ;
767+ }
768+
745769 for (i = 0 ; i < IMX_MU_CHANS ; i ++ ) {
746770 struct imx_mu_con_priv * cp = & priv -> con_priv [i ];
747771
@@ -757,7 +781,7 @@ static void imx_mu_init_generic(struct imx_mu_priv *priv)
757781 priv -> mbox .of_xlate = imx_mu_xlate ;
758782
759783 if (priv -> side_b )
760- return ;
784+ return 0 ;
761785
762786 /* Set default MU configuration */
763787 for (i = 0 ; i < IMX_MU_xCR_MAX ; i ++ )
@@ -768,11 +792,13 @@ static void imx_mu_init_generic(struct imx_mu_priv *priv)
768792 imx_mu_write (priv , val , priv -> dcfg -> xSR [IMX_MU_GSR ]);
769793
770794 /* 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 );
795+ for (i = 0 ; i < priv -> num_rr ; i ++ )
796+ imx_mu_read (priv , priv -> dcfg -> xRR + i * 4 );
797+
798+ return 0 ;
773799}
774800
775- static void imx_mu_init_specific (struct imx_mu_priv * priv )
801+ static int imx_mu_init_specific (struct imx_mu_priv * priv )
776802{
777803 unsigned int i ;
778804 int num_chans = priv -> dcfg -> type & IMX_MU_V2_S4 ? IMX_MU_S4_CHANS : IMX_MU_SCU_CHANS ;
@@ -794,12 +820,20 @@ static void imx_mu_init_specific(struct imx_mu_priv *priv)
794820 /* Set default MU configuration */
795821 for (i = 0 ; i < IMX_MU_xCR_MAX ; i ++ )
796822 imx_mu_write (priv , 0 , priv -> dcfg -> xCR [i ]);
823+
824+ return 0 ;
797825}
798826
799- static void imx_mu_init_seco (struct imx_mu_priv * priv )
827+ static int imx_mu_init_seco (struct imx_mu_priv * priv )
800828{
801- imx_mu_init_generic (priv );
829+ int ret ;
830+
831+ ret = imx_mu_init_generic (priv );
832+ if (ret )
833+ return ret ;
802834 priv -> mbox .of_xlate = imx_mu_seco_xlate ;
835+
836+ return 0 ;
803837}
804838
805839static int imx_mu_probe (struct platform_device * pdev )
@@ -864,9 +898,15 @@ static int imx_mu_probe(struct platform_device *pdev)
864898 return ret ;
865899 }
866900
901+ imx_mu_get_tr_rr (priv );
902+
867903 priv -> side_b = of_property_read_bool (np , "fsl,mu-side-b" );
868904
869- priv -> dcfg -> init (priv );
905+ ret = priv -> dcfg -> init (priv );
906+ if (ret ) {
907+ dev_err (dev , "Failed to init MU\n" );
908+ goto disable_clk ;
909+ }
870910
871911 spin_lock_init (& priv -> xcr_lock );
872912
@@ -878,10 +918,10 @@ static int imx_mu_probe(struct platform_device *pdev)
878918 platform_set_drvdata (pdev , priv );
879919
880920 ret = devm_mbox_controller_register (dev , & priv -> mbox );
881- if (ret ) {
882- clk_disable_unprepare ( priv -> clk ) ;
883- return ret ;
884- }
921+ if (ret )
922+ goto disable_clk ;
923+
924+ of_platform_populate ( dev -> of_node , NULL , NULL , dev );
885925
886926 pm_runtime_enable (dev );
887927
@@ -899,6 +939,7 @@ static int imx_mu_probe(struct platform_device *pdev)
899939
900940disable_runtime_pm :
901941 pm_runtime_disable (dev );
942+ disable_clk :
902943 clk_disable_unprepare (priv -> clk );
903944 return ret ;
904945}
@@ -994,6 +1035,9 @@ static const struct of_device_id imx_mu_dt_ids[] = {
9941035 { .compatible = "fsl,imx8ulp-mu" , .data = & imx_mu_cfg_imx8ulp },
9951036 { .compatible = "fsl,imx8ulp-mu-s4" , .data = & imx_mu_cfg_imx8ulp_s4 },
9961037 { .compatible = "fsl,imx93-mu-s4" , .data = & imx_mu_cfg_imx93_s4 },
1038+ { .compatible = "fsl,imx95-mu" , .data = & imx_mu_cfg_imx8ulp },
1039+ { .compatible = "fsl,imx95-mu-ele" , .data = & imx_mu_cfg_imx8ulp_s4 },
1040+ { .compatible = "fsl,imx95-mu-v2x" , .data = & imx_mu_cfg_imx8ulp_s4 },
9971041 { .compatible = "fsl,imx8-mu-scu" , .data = & imx_mu_cfg_imx8_scu },
9981042 { .compatible = "fsl,imx8-mu-seco" , .data = & imx_mu_cfg_imx8_seco },
9991043 { },
0 commit comments