4040#define IMX7D_M4_STOP (IMX7D_ENABLE_M4 | IMX7D_SW_M4C_RST | \
4141 IMX7D_SW_M4C_NON_SCLR_RST)
4242
43+ #define IMX8M_M7_STOP (IMX7D_ENABLE_M4 | IMX7D_SW_M4C_RST)
44+ #define IMX8M_M7_POLL IMX7D_ENABLE_M4
45+
46+ #define IMX8M_GPR22 0x58
47+ #define IMX8M_GPR22_CM7_CPUWAIT BIT(0)
48+
4349/* Address: 0x020D8000 */
4450#define IMX6SX_SRC_SCR 0x00
4551#define IMX6SX_ENABLE_M4 BIT(22)
@@ -91,6 +97,7 @@ static int imx_rproc_detach_pd(struct rproc *rproc);
9197struct imx_rproc {
9298 struct device * dev ;
9399 struct regmap * regmap ;
100+ struct regmap * gpr ;
94101 struct rproc * rproc ;
95102 const struct imx_rproc_dcfg * dcfg ;
96103 struct imx_rproc_mem mem [IMX_RPROC_MEM_MAX ];
@@ -285,6 +292,18 @@ static const struct imx_rproc_att imx_rproc_att_imx6sx[] = {
285292 { 0x80000000 , 0x80000000 , 0x60000000 , 0 },
286293};
287294
295+ static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn_mmio = {
296+ .src_reg = IMX7D_SRC_SCR ,
297+ .src_mask = IMX7D_M4_RST_MASK ,
298+ .src_start = IMX7D_M4_START ,
299+ .src_stop = IMX8M_M7_STOP ,
300+ .gpr_reg = IMX8M_GPR22 ,
301+ .gpr_wait = IMX8M_GPR22_CM7_CPUWAIT ,
302+ .att = imx_rproc_att_imx8mn ,
303+ .att_size = ARRAY_SIZE (imx_rproc_att_imx8mn ),
304+ .method = IMX_RPROC_MMIO ,
305+ };
306+
288307static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn = {
289308 .att = imx_rproc_att_imx8mn ,
290309 .att_size = ARRAY_SIZE (imx_rproc_att_imx8mn ),
@@ -365,8 +384,14 @@ static int imx_rproc_start(struct rproc *rproc)
365384
366385 switch (dcfg -> method ) {
367386 case IMX_RPROC_MMIO :
368- ret = regmap_update_bits (priv -> regmap , dcfg -> src_reg , dcfg -> src_mask ,
369- dcfg -> src_start );
387+ if (priv -> gpr ) {
388+ ret = regmap_clear_bits (priv -> gpr , dcfg -> gpr_reg ,
389+ dcfg -> gpr_wait );
390+ } else {
391+ ret = regmap_update_bits (priv -> regmap , dcfg -> src_reg ,
392+ dcfg -> src_mask ,
393+ dcfg -> src_start );
394+ }
370395 break ;
371396 case IMX_RPROC_SMC :
372397 arm_smccc_smc (IMX_SIP_RPROC , IMX_SIP_RPROC_START , 0 , 0 , 0 , 0 , 0 , 0 , & res );
@@ -395,6 +420,16 @@ static int imx_rproc_stop(struct rproc *rproc)
395420
396421 switch (dcfg -> method ) {
397422 case IMX_RPROC_MMIO :
423+ if (priv -> gpr ) {
424+ ret = regmap_set_bits (priv -> gpr , dcfg -> gpr_reg ,
425+ dcfg -> gpr_wait );
426+ if (ret ) {
427+ dev_err (priv -> dev ,
428+ "Failed to quiescence M4 platform!\n" );
429+ return ret ;
430+ }
431+ }
432+
398433 ret = regmap_update_bits (priv -> regmap , dcfg -> src_reg , dcfg -> src_mask ,
399434 dcfg -> src_stop );
400435 break ;
@@ -992,6 +1027,10 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
9921027 break ;
9931028 }
9941029
1030+ priv -> gpr = syscon_regmap_lookup_by_phandle (dev -> of_node , "fsl,iomuxc-gpr" );
1031+ if (IS_ERR (priv -> gpr ))
1032+ priv -> gpr = NULL ;
1033+
9951034 regmap = syscon_regmap_lookup_by_phandle (dev -> of_node , "syscon" );
9961035 if (IS_ERR (regmap )) {
9971036 dev_err (dev , "failed to find syscon\n" );
@@ -1001,6 +1040,19 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
10011040 priv -> regmap = regmap ;
10021041 regmap_attach_dev (dev , regmap , & config );
10031042
1043+ if (priv -> gpr ) {
1044+ ret = regmap_read (priv -> gpr , dcfg -> gpr_reg , & val );
1045+ if (val & dcfg -> gpr_wait ) {
1046+ /*
1047+ * After cold boot, the CM indicates its in wait
1048+ * state, but not fully powered off. Power it off
1049+ * fully so firmware can be loaded into it.
1050+ */
1051+ imx_rproc_stop (priv -> rproc );
1052+ return 0 ;
1053+ }
1054+ }
1055+
10041056 ret = regmap_read (regmap , dcfg -> src_reg , & val );
10051057 if (ret ) {
10061058 dev_err (dev , "Failed to read src\n" );
@@ -1142,6 +1194,8 @@ static const struct of_device_id imx_rproc_of_match[] = {
11421194 { .compatible = "fsl,imx8mm-cm4" , .data = & imx_rproc_cfg_imx8mq },
11431195 { .compatible = "fsl,imx8mn-cm7" , .data = & imx_rproc_cfg_imx8mn },
11441196 { .compatible = "fsl,imx8mp-cm7" , .data = & imx_rproc_cfg_imx8mn },
1197+ { .compatible = "fsl,imx8mn-cm7-mmio" , .data = & imx_rproc_cfg_imx8mn_mmio },
1198+ { .compatible = "fsl,imx8mp-cm7-mmio" , .data = & imx_rproc_cfg_imx8mn_mmio },
11451199 { .compatible = "fsl,imx8qxp-cm4" , .data = & imx_rproc_cfg_imx8qxp },
11461200 { .compatible = "fsl,imx8qm-cm4" , .data = & imx_rproc_cfg_imx8qm },
11471201 { .compatible = "fsl,imx8ulp-cm33" , .data = & imx_rproc_cfg_imx8ulp },
0 commit comments