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>
15
16
#include <linux/mailbox_controller.h>
16
17
#include <linux/module.h>
17
18
#include <linux/of.h>
19
+ #include <linux/of_platform.h>
18
20
#include <linux/platform_device.h>
19
21
#include <linux/pm_runtime.h>
20
22
#include <linux/suspend.h>
29
31
#define IMX_MU_S4_CHANS 2
30
32
#define IMX_MU_CHAN_NAME_SIZE 20
31
33
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)
33
37
34
38
#define IMX_MU_SECO_TX_TOUT (msecs_to_jiffies(3000))
35
39
#define IMX_MU_SECO_RX_TOUT (msecs_to_jiffies(3000))
@@ -93,10 +97,11 @@ struct imx_mu_priv {
93
97
struct clk * clk ;
94
98
int irq [IMX_MU_CHANS ];
95
99
bool suspend ;
96
-
97
- u32 xcr [IMX_MU_xCR_MAX ];
98
-
99
100
bool side_b ;
101
+
102
+ u32 xcr [IMX_MU_xCR_MAX ];
103
+ u32 num_tr ;
104
+ u32 num_rr ;
100
105
};
101
106
102
107
enum imx_mu_type {
@@ -110,7 +115,7 @@ struct imx_mu_dcfg {
110
115
int (* tx )(struct imx_mu_priv * priv , struct imx_mu_con_priv * cp , void * data );
111
116
int (* rx )(struct imx_mu_priv * priv , struct imx_mu_con_priv * cp );
112
117
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 );
114
119
enum imx_mu_type type ;
115
120
u32 xTR ; /* Transmit Register0 */
116
121
u32 xRR ; /* Receive Register0 */
@@ -264,18 +269,17 @@ static int imx_mu_generic_rxdb(struct imx_mu_priv *priv,
264
269
static int imx_mu_specific_tx (struct imx_mu_priv * priv , struct imx_mu_con_priv * cp , void * data )
265
270
{
266
271
u32 * arg = data ;
272
+ u32 num_tr = priv -> num_tr ;
267
273
int i , ret ;
268
274
u32 xsr ;
269
- u32 size , max_size , num_tr ;
275
+ u32 size , max_size ;
270
276
271
277
if (priv -> dcfg -> type & IMX_MU_V2_S4 ) {
272
278
size = ((struct imx_s4_rpc_msg_max * )data )-> hdr .size ;
273
279
max_size = sizeof (struct imx_s4_rpc_msg_max );
274
- num_tr = 8 ;
275
280
} else {
276
281
size = ((struct imx_sc_rpc_msg_max * )data )-> hdr .size ;
277
282
max_size = sizeof (struct imx_sc_rpc_msg_max );
278
- num_tr = 4 ;
279
283
}
280
284
281
285
switch (cp -> type ) {
@@ -324,6 +328,7 @@ static int imx_mu_specific_rx(struct imx_mu_priv *priv, struct imx_mu_con_priv *
324
328
int i , ret ;
325
329
u32 xsr ;
326
330
u32 size , max_size ;
331
+ u32 num_rr = priv -> num_rr ;
327
332
328
333
data = (u32 * )priv -> msg ;
329
334
@@ -345,13 +350,13 @@ static int imx_mu_specific_rx(struct imx_mu_priv *priv, struct imx_mu_con_priv *
345
350
346
351
for (i = 1 ; i < size ; i ++ ) {
347
352
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 ,
349
354
5 * USEC_PER_SEC );
350
355
if (ret ) {
351
356
dev_err (priv -> dev , "timeout read idx %d\n" , i );
352
357
return ret ;
353
358
}
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 );
355
360
}
356
361
357
362
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,
737
742
return imx_mu_xlate (mbox , sp );
738
743
}
739
744
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 )
741
760
{
742
761
unsigned int i ;
743
762
unsigned int val ;
744
763
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
+
745
769
for (i = 0 ; i < IMX_MU_CHANS ; i ++ ) {
746
770
struct imx_mu_con_priv * cp = & priv -> con_priv [i ];
747
771
@@ -757,7 +781,7 @@ static void imx_mu_init_generic(struct imx_mu_priv *priv)
757
781
priv -> mbox .of_xlate = imx_mu_xlate ;
758
782
759
783
if (priv -> side_b )
760
- return ;
784
+ return 0 ;
761
785
762
786
/* Set default MU configuration */
763
787
for (i = 0 ; i < IMX_MU_xCR_MAX ; i ++ )
@@ -768,11 +792,13 @@ static void imx_mu_init_generic(struct imx_mu_priv *priv)
768
792
imx_mu_write (priv , val , priv -> dcfg -> xSR [IMX_MU_GSR ]);
769
793
770
794
/* 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 ;
773
799
}
774
800
775
- static void imx_mu_init_specific (struct imx_mu_priv * priv )
801
+ static int imx_mu_init_specific (struct imx_mu_priv * priv )
776
802
{
777
803
unsigned int i ;
778
804
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)
794
820
/* Set default MU configuration */
795
821
for (i = 0 ; i < IMX_MU_xCR_MAX ; i ++ )
796
822
imx_mu_write (priv , 0 , priv -> dcfg -> xCR [i ]);
823
+
824
+ return 0 ;
797
825
}
798
826
799
- static void imx_mu_init_seco (struct imx_mu_priv * priv )
827
+ static int imx_mu_init_seco (struct imx_mu_priv * priv )
800
828
{
801
- imx_mu_init_generic (priv );
829
+ int ret ;
830
+
831
+ ret = imx_mu_init_generic (priv );
832
+ if (ret )
833
+ return ret ;
802
834
priv -> mbox .of_xlate = imx_mu_seco_xlate ;
835
+
836
+ return 0 ;
803
837
}
804
838
805
839
static int imx_mu_probe (struct platform_device * pdev )
@@ -864,9 +898,15 @@ static int imx_mu_probe(struct platform_device *pdev)
864
898
return ret ;
865
899
}
866
900
901
+ imx_mu_get_tr_rr (priv );
902
+
867
903
priv -> side_b = of_property_read_bool (np , "fsl,mu-side-b" );
868
904
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
+ }
870
910
871
911
spin_lock_init (& priv -> xcr_lock );
872
912
@@ -878,10 +918,10 @@ static int imx_mu_probe(struct platform_device *pdev)
878
918
platform_set_drvdata (pdev , priv );
879
919
880
920
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 );
885
925
886
926
pm_runtime_enable (dev );
887
927
@@ -899,6 +939,7 @@ static int imx_mu_probe(struct platform_device *pdev)
899
939
900
940
disable_runtime_pm :
901
941
pm_runtime_disable (dev );
942
+ disable_clk :
902
943
clk_disable_unprepare (priv -> clk );
903
944
return ret ;
904
945
}
@@ -994,6 +1035,9 @@ static const struct of_device_id imx_mu_dt_ids[] = {
994
1035
{ .compatible = "fsl,imx8ulp-mu" , .data = & imx_mu_cfg_imx8ulp },
995
1036
{ .compatible = "fsl,imx8ulp-mu-s4" , .data = & imx_mu_cfg_imx8ulp_s4 },
996
1037
{ .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 },
997
1041
{ .compatible = "fsl,imx8-mu-scu" , .data = & imx_mu_cfg_imx8_scu },
998
1042
{ .compatible = "fsl,imx8-mu-seco" , .data = & imx_mu_cfg_imx8_seco },
999
1043
{ },
0 commit comments