Skip to content

Commit 5e50aef

Browse files
MrVanmathieupoirier
authored andcommitted
remoteproc: imx_rproc: Support attaching to i.MX8QXP M4
When M4 is kicked by SCFW, M4 runs in its own hardware partition, Linux could only do IPC with M4, it could not start, stop, update image. We disable recovery reboot when M4 is managed by SCFW, because remoteproc core still not support M4 auto-recovery without loading image. Signed-off-by: Peng Fan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mathieu Poirier <[email protected]>
1 parent 5050666 commit 5e50aef

File tree

1 file changed

+107
-1
lines changed

1 file changed

+107
-1
lines changed

drivers/remoteproc/imx_rproc.c

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <linux/arm-smccc.h>
77
#include <linux/clk.h>
88
#include <linux/err.h>
9+
#include <linux/firmware/imx/sci.h>
910
#include <linux/interrupt.h>
1011
#include <linux/kernel.h>
1112
#include <linux/mailbox_client.h>
@@ -59,6 +60,8 @@
5960
#define IMX_SIP_RPROC_STARTED 0x01
6061
#define IMX_SIP_RPROC_STOP 0x02
6162

63+
#define IMX_SC_IRQ_GROUP_REBOOTED 5
64+
6265
/**
6366
* struct imx_rproc_mem - slim internal memory structure
6467
* @cpu_addr: MPU virtual address of the memory region
@@ -89,6 +92,10 @@ struct imx_rproc {
8992
struct work_struct rproc_work;
9093
struct workqueue_struct *workqueue;
9194
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 */
9299
};
93100

94101
static const struct imx_rproc_att imx_rproc_att_imx93[] = {
@@ -117,6 +124,18 @@ static const struct imx_rproc_att imx_rproc_att_imx93[] = {
117124
{ 0xD0000000, 0xa0000000, 0x10000000, 0 },
118125
};
119126

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+
120139
static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
121140
/* dev addr , sys addr , size , flags */
122141
/* ITCM */
@@ -255,6 +274,12 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = {
255274
.method = IMX_RPROC_MMIO,
256275
};
257276

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+
258283
static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = {
259284
.att = imx_rproc_att_imx8ulp,
260285
.att_size = ARRAY_SIZE(imx_rproc_att_imx8ulp),
@@ -680,6 +705,37 @@ static void imx_rproc_free_mbox(struct rproc *rproc)
680705
mbox_free_channel(priv->rx_ch);
681706
}
682707

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+
683739
static int imx_rproc_detect_mode(struct imx_rproc *priv)
684740
{
685741
struct regmap_config config = { .name = "imx-rproc" };
@@ -689,6 +745,7 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
689745
struct arm_smccc_res res;
690746
int ret;
691747
u32 val;
748+
u8 pt;
692749

693750
switch (dcfg->method) {
694751
case IMX_RPROC_NONE:
@@ -699,6 +756,51 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
699756
if (res.a0)
700757
priv->rproc->state = RPROC_DETACHED;
701758
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;
702804
default:
703805
break;
704806
}
@@ -803,7 +905,7 @@ static int imx_rproc_probe(struct platform_device *pdev)
803905

804906
ret = imx_rproc_clk_enable(priv);
805907
if (ret)
806-
goto err_put_mbox;
908+
goto err_put_scu;
807909

808910
INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
809911

@@ -820,6 +922,8 @@ static int imx_rproc_probe(struct platform_device *pdev)
820922

821923
err_put_clk:
822924
clk_disable_unprepare(priv->clk);
925+
err_put_scu:
926+
imx_rproc_put_scu(rproc);
823927
err_put_mbox:
824928
imx_rproc_free_mbox(rproc);
825929
err_put_wkq:
@@ -837,6 +941,7 @@ static int imx_rproc_remove(struct platform_device *pdev)
837941

838942
clk_disable_unprepare(priv->clk);
839943
rproc_del(rproc);
944+
imx_rproc_put_scu(rproc);
840945
imx_rproc_free_mbox(rproc);
841946
destroy_workqueue(priv->workqueue);
842947
rproc_free(rproc);
@@ -852,6 +957,7 @@ static const struct of_device_id imx_rproc_of_match[] = {
852957
{ .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq },
853958
{ .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
854959
{ .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
960+
{ .compatible = "fsl,imx8qxp-cm4", .data = &imx_rproc_cfg_imx8qxp },
855961
{ .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
856962
{ .compatible = "fsl,imx93-cm33", .data = &imx_rproc_cfg_imx93 },
857963
{},

0 commit comments

Comments
 (0)