6
6
#include <linux/arm-smccc.h>
7
7
#include <linux/clk.h>
8
8
#include <linux/err.h>
9
+ #include <linux/firmware/imx/sci.h>
9
10
#include <linux/interrupt.h>
10
11
#include <linux/kernel.h>
11
12
#include <linux/mailbox_client.h>
59
60
#define IMX_SIP_RPROC_STARTED 0x01
60
61
#define IMX_SIP_RPROC_STOP 0x02
61
62
63
+ #define IMX_SC_IRQ_GROUP_REBOOTED 5
64
+
62
65
/**
63
66
* struct imx_rproc_mem - slim internal memory structure
64
67
* @cpu_addr: MPU virtual address of the memory region
@@ -89,6 +92,10 @@ struct imx_rproc {
89
92
struct work_struct rproc_work ;
90
93
struct workqueue_struct * workqueue ;
91
94
void __iomem * rsc_table ;
95
+ struct imx_sc_ipc * ipc_handle ;
96
+ struct notifier_block rproc_nb ;
97
+ u32 rproc_pt ; /* partition id */
98
+ u32 rsrc_id ; /* resource id */
92
99
};
93
100
94
101
static const struct imx_rproc_att imx_rproc_att_imx93 [] = {
@@ -117,6 +124,18 @@ static const struct imx_rproc_att imx_rproc_att_imx93[] = {
117
124
{ 0xD0000000 , 0xa0000000 , 0x10000000 , 0 },
118
125
};
119
126
127
+ static const struct imx_rproc_att imx_rproc_att_imx8qxp [] = {
128
+ { 0x08000000 , 0x08000000 , 0x10000000 , 0 },
129
+ /* TCML/U */
130
+ { 0x1FFE0000 , 0x34FE0000 , 0x00040000 , ATT_OWN | ATT_IOMEM },
131
+ /* OCRAM(Low 96KB) */
132
+ { 0x21000000 , 0x00100000 , 0x00018000 , 0 },
133
+ /* OCRAM */
134
+ { 0x21100000 , 0x00100000 , 0x00040000 , 0 },
135
+ /* DDR (Data) */
136
+ { 0x80000000 , 0x80000000 , 0x60000000 , 0 },
137
+ };
138
+
120
139
static const struct imx_rproc_att imx_rproc_att_imx8mn [] = {
121
140
/* dev addr , sys addr , size , flags */
122
141
/* ITCM */
@@ -255,6 +274,12 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = {
255
274
.method = IMX_RPROC_MMIO ,
256
275
};
257
276
277
+ static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = {
278
+ .att = imx_rproc_att_imx8qxp ,
279
+ .att_size = ARRAY_SIZE (imx_rproc_att_imx8qxp ),
280
+ .method = IMX_RPROC_SCU_API ,
281
+ };
282
+
258
283
static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = {
259
284
.att = imx_rproc_att_imx8ulp ,
260
285
.att_size = ARRAY_SIZE (imx_rproc_att_imx8ulp ),
@@ -680,6 +705,37 @@ static void imx_rproc_free_mbox(struct rproc *rproc)
680
705
mbox_free_channel (priv -> rx_ch );
681
706
}
682
707
708
+ static void imx_rproc_put_scu (struct rproc * rproc )
709
+ {
710
+ struct imx_rproc * priv = rproc -> priv ;
711
+ const struct imx_rproc_dcfg * dcfg = priv -> dcfg ;
712
+
713
+ if (dcfg -> method != IMX_RPROC_SCU_API )
714
+ return ;
715
+
716
+ if (imx_sc_rm_is_resource_owned (priv -> ipc_handle , priv -> rsrc_id ))
717
+ return ;
718
+
719
+ imx_scu_irq_group_enable (IMX_SC_IRQ_GROUP_REBOOTED , BIT (priv -> rproc_pt ), false);
720
+ imx_scu_irq_unregister_notifier (& priv -> rproc_nb );
721
+ }
722
+
723
+ static int imx_rproc_partition_notify (struct notifier_block * nb ,
724
+ unsigned long event , void * group )
725
+ {
726
+ struct imx_rproc * priv = container_of (nb , struct imx_rproc , rproc_nb );
727
+
728
+ /* Ignore other irqs */
729
+ if (!((event & BIT (priv -> rproc_pt )) && (* (u8 * )group == IMX_SC_IRQ_GROUP_REBOOTED )))
730
+ return 0 ;
731
+
732
+ rproc_report_crash (priv -> rproc , RPROC_WATCHDOG );
733
+
734
+ pr_info ("Partition%d reset!\n" , priv -> rproc_pt );
735
+
736
+ return 0 ;
737
+ }
738
+
683
739
static int imx_rproc_detect_mode (struct imx_rproc * priv )
684
740
{
685
741
struct regmap_config config = { .name = "imx-rproc" };
@@ -689,6 +745,7 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
689
745
struct arm_smccc_res res ;
690
746
int ret ;
691
747
u32 val ;
748
+ u8 pt ;
692
749
693
750
switch (dcfg -> method ) {
694
751
case IMX_RPROC_NONE :
@@ -699,6 +756,51 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
699
756
if (res .a0 )
700
757
priv -> rproc -> state = RPROC_DETACHED ;
701
758
return 0 ;
759
+ case IMX_RPROC_SCU_API :
760
+ ret = imx_scu_get_handle (& priv -> ipc_handle );
761
+ if (ret )
762
+ return ret ;
763
+ ret = of_property_read_u32 (dev -> of_node , "fsl,resource-id" , & priv -> rsrc_id );
764
+ if (ret ) {
765
+ dev_err (dev , "No fsl,resource-id property\n" );
766
+ return ret ;
767
+ }
768
+
769
+ /*
770
+ * If Mcore resource is not owned by Acore partition, It is kicked by ROM,
771
+ * and Linux could only do IPC with Mcore and nothing else.
772
+ */
773
+ if (imx_sc_rm_is_resource_owned (priv -> ipc_handle , priv -> rsrc_id ))
774
+ return 0 ;
775
+
776
+ priv -> rproc -> state = RPROC_DETACHED ;
777
+ priv -> rproc -> recovery_disabled = true;
778
+
779
+ /* Get partition id and enable irq in SCFW */
780
+ ret = imx_sc_rm_get_resource_owner (priv -> ipc_handle , priv -> rsrc_id , & pt );
781
+ if (ret ) {
782
+ dev_err (dev , "not able to get resource owner\n" );
783
+ return ret ;
784
+ }
785
+
786
+ priv -> rproc_pt = pt ;
787
+ priv -> rproc_nb .notifier_call = imx_rproc_partition_notify ;
788
+
789
+ ret = imx_scu_irq_register_notifier (& priv -> rproc_nb );
790
+ if (ret ) {
791
+ dev_err (dev , "register scu notifier failed, %d\n" , ret );
792
+ return ret ;
793
+ }
794
+
795
+ ret = imx_scu_irq_group_enable (IMX_SC_IRQ_GROUP_REBOOTED , BIT (priv -> rproc_pt ),
796
+ true);
797
+ if (ret ) {
798
+ imx_scu_irq_unregister_notifier (& priv -> rproc_nb );
799
+ dev_err (dev , "Enable irq failed, %d\n" , ret );
800
+ return ret ;
801
+ }
802
+
803
+ return 0 ;
702
804
default :
703
805
break ;
704
806
}
@@ -803,7 +905,7 @@ static int imx_rproc_probe(struct platform_device *pdev)
803
905
804
906
ret = imx_rproc_clk_enable (priv );
805
907
if (ret )
806
- goto err_put_mbox ;
908
+ goto err_put_scu ;
807
909
808
910
INIT_WORK (& priv -> rproc_work , imx_rproc_vq_work );
809
911
@@ -820,6 +922,8 @@ static int imx_rproc_probe(struct platform_device *pdev)
820
922
821
923
err_put_clk :
822
924
clk_disable_unprepare (priv -> clk );
925
+ err_put_scu :
926
+ imx_rproc_put_scu (rproc );
823
927
err_put_mbox :
824
928
imx_rproc_free_mbox (rproc );
825
929
err_put_wkq :
@@ -837,6 +941,7 @@ static int imx_rproc_remove(struct platform_device *pdev)
837
941
838
942
clk_disable_unprepare (priv -> clk );
839
943
rproc_del (rproc );
944
+ imx_rproc_put_scu (rproc );
840
945
imx_rproc_free_mbox (rproc );
841
946
destroy_workqueue (priv -> workqueue );
842
947
rproc_free (rproc );
@@ -852,6 +957,7 @@ static const struct of_device_id imx_rproc_of_match[] = {
852
957
{ .compatible = "fsl,imx8mm-cm4" , .data = & imx_rproc_cfg_imx8mq },
853
958
{ .compatible = "fsl,imx8mn-cm7" , .data = & imx_rproc_cfg_imx8mn },
854
959
{ .compatible = "fsl,imx8mp-cm7" , .data = & imx_rproc_cfg_imx8mn },
960
+ { .compatible = "fsl,imx8qxp-cm4" , .data = & imx_rproc_cfg_imx8qxp },
855
961
{ .compatible = "fsl,imx8ulp-cm33" , .data = & imx_rproc_cfg_imx8ulp },
856
962
{ .compatible = "fsl,imx93-cm33" , .data = & imx_rproc_cfg_imx93 },
857
963
{},
0 commit comments