- vdev-nums : The number of the remote virtual devices.
- reg : The reserved DDR phisical memory used to store
vring descriptors.
+- multi-core-id: The id number of the remote processors.
+ And it is optional for the legacy platforms, since they
+ only have one remote processors.
+- mub-partition: The partition ID of muB side, that's optional
+ and used on i.mx8qm/8qxp for partition reset. The default
+ value is 3 in driver without this property.
+
+
+=====================================================================
+message unit module for RPMSG
+
+- mu_rpmsg : The message unit module used to do the communications
+ between the asymmetric cores.
+- compatible : "fsl,imx8mq-mu", "fsl,imx6sx-mu", "fsl,imx-mu-rpmsg1".
+ Different mu module would be used by the different remote processor.
+ The "fsl, imx6sx-mu" is used by the first remote processor.
+ The "fsl,imx-mu-rpmsg1" is used by the second remote process.
+- reg : Should contain MU registers location and length.
+- interrupts : interrupt mapping for RPMSG MU IRQ
+- interrupt-parent : A single value that points to the interrupt
+ parent to which the child domain is being mapped.
+ Value must be "&intmux_cm40" or "&intmux_cm41"
Example:
rpmsg: rpmsg{
#include <linux/virtio_ring.h>
#include <linux/imx_rpmsg.h>
#include <linux/mx8_mu.h>
+#include <soc/imx8/sc/sci.h>
+#include <soc/imx8/sc/svc/irq/api.h>
enum imx_rpmsg_variants {
IMX6SX,
u32 in_idx;
u32 out_idx;
u32 core_id;
+ u32 mub_partition;
+ struct notifier_block *pnotifier;
spinlock_t mu_lock;
};
struct imx_rpmsg_vproc *rpdev;
};
+static int imx_rpmsg_partion_notify0(struct notifier_block *nb,
+ unsigned long event, void *group);
+static int imx_rpmsg_partion_notify1(struct notifier_block *nb,
+ unsigned long event, void *group);
+
static u64 imx_rpmsg_get_features(struct virtio_device *vdev)
{
/* VIRTIO_RPMSG_F_NS has been made private */
.get_status = imx_rpmsg_get_status,
};
+static struct notifier_block imx_rpmsg_partion_notifier[] = {
+ {
+ .notifier_call = imx_rpmsg_partion_notify0,
+ },
+ {
+ .notifier_call = imx_rpmsg_partion_notify1,
+ },
+};
+
static struct imx_rpmsg_vproc imx_rpmsg_vprocs[] = {
{
.rproc_name = "m4",
+ .pnotifier = &imx_rpmsg_partion_notifier[0],
},
{
.rproc_name = "m4",
+ .pnotifier = &imx_rpmsg_partion_notifier[1],
},
};
return ret;
}
+
+static int imx_rpmsg_partion_notify0(struct notifier_block *nb,
+ unsigned long event, void *group)
+{
+ struct imx_rpmsg_vproc *rpdev = &imx_rpmsg_vprocs[0];
+
+ /* Ignore other irqs */
+ if (!((event & BIT(rpdev->mub_partition)) &&
+ (*(sc_irq_group_t *)group == SC_IRQ_GROUP_REBOOTED)))
+ return 0;
+
+ pr_info("Patition%d reset!\n", rpdev->mub_partition);
+
+ return 0;
+}
+
+static int imx_rpmsg_partion_notify1(struct notifier_block *nb,
+ unsigned long event, void *group)
+{
+ struct imx_rpmsg_vproc *rpdev = &imx_rpmsg_vprocs[1];
+
+ /* Ignore other irqs */
+ if (!((event & BIT(rpdev->mub_partition)) &&
+ (*(sc_irq_group_t *)group == SC_IRQ_GROUP_REBOOTED)))
+ return 0;
+
+ pr_info("Patition%d reset!\n", rpdev->mub_partition);
+
+ return 0;
+}
+
static int imx_rpmsg_probe(struct platform_device *pdev)
{
int core_id, j, ret = 0;
platform_set_drvdata(pdev, rpdev);
+ if (rpdev->variant == IMX8QXP || rpdev->variant == IMX8QM) {
+ uint32_t mu_id;
+ sc_err_t sciErr;
+ static sc_ipc_t mu_ipchandle;
+ /* Get muB partition id and enable irq in SCFW then */
+ if (of_property_read_u32(np, "mub-partition",
+ &rpdev->mub_partition))
+ rpdev->mub_partition = 3; /* default partition 3 */
+
+ sciErr = sc_ipc_getMuID(&mu_id);
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("can't obtain mu id: %d\n", sciErr);
+ return sciErr;
+ }
+
+ sciErr = sc_ipc_open(&mu_ipchandle, mu_id);
+
+ if (sciErr != SC_ERR_NONE) {
+ pr_err("can't get ipc handler: %d\n", sciErr);
+ return sciErr;
+ };
+
+ /* Request for the partition reset interrupt. */
+ sciErr = sc_irq_enable(mu_ipchandle, SC_R_MU_1A,
+ SC_IRQ_GROUP_REBOOTED,
+ BIT(rpdev->mub_partition), true);
+ if (sciErr)
+ pr_info("Cannot request partition reset interrupt\n");
+
+ return register_scu_notifier(rpdev->pnotifier);
+
+ }
+
return ret;
err_out: