Commit 9687d4ac authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull mailbox updates from Jassi Brar:

 - imx: add support for i.MX95 ELE/V2X MU

 - misc: I will be signing-off from my personal gmail id from now on

* tag 'mailbox-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/jassibrar/mailbox:
  mailbox: imx: support i.MX95 Generic/ELE/V2X MU
  mailbox: imx: populate sub-nodes
  mailbox: imx: get RR/TR registers num from Parameter register
  mailbox: imx: support return value of init
  dt-bindings: mailbox: fsl,mu: add i.MX95 Generic/ELE/V2X MU compatible
parents 259f7d5e 8df6bab6
Loading
Loading
Loading
Loading
+57 −1
Original line number Diff line number Diff line
@@ -29,8 +29,11 @@ properties:
      - const: fsl,imx8ulp-mu
      - const: fsl,imx8-mu-scu
      - const: fsl,imx8-mu-seco
      - const: fsl,imx93-mu-s4
      - const: fsl,imx8ulp-mu-s4
      - const: fsl,imx93-mu-s4
      - const: fsl,imx95-mu
      - const: fsl,imx95-mu-ele
      - const: fsl,imx95-mu-v2x
      - items:
          - const: fsl,imx93-mu
          - const: fsl,imx8ulp-mu
@@ -95,6 +98,19 @@ properties:
  power-domains:
    maxItems: 1

  ranges: true

  '#address-cells':
    const: 1

  '#size-cells':
    const: 1

patternProperties:
  "^sram@[a-f0-9]+":
    $ref: /schemas/sram/sram.yaml#
    unevaluatedProperties: false

required:
  - compatible
  - reg
@@ -122,6 +138,15 @@ allOf:
        required:
          - interrupt-names

  - if:
      not:
        properties:
          compatible:
            const: fsl,imx95-mu
    then:
      patternProperties:
        "^sram@[a-f0-9]+": false

additionalProperties: false

examples:
@@ -134,3 +159,34 @@ examples:
        interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
        #mbox-cells = <2>;
    };

  - |
    #include <dt-bindings/interrupt-controller/arm-gic.h>

    mailbox@445b0000 {
        compatible = "fsl,imx95-mu";
        reg = <0x445b0000 0x10000>;
        ranges;
        interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
        #address-cells = <1>;
        #size-cells = <1>;
        #mbox-cells = <2>;

        sram@445b1000 {
            compatible = "mmio-sram";
            reg = <0x445b1000 0x400>;
            ranges = <0x0 0x445b1000 0x400>;
            #address-cells = <1>;
            #size-cells = <1>;

            scmi-sram-section@0 {
                compatible = "arm,scmi-shmem";
                reg = <0x0 0x80>;
            };

            scmi-sram-section@80 {
                compatible = "arm,scmi-shmem";
                reg = <0x80 0x80>;
            };
        };
    };
+66 −22
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
 * Copyright 2022 NXP, Peng Fan <peng.fan@nxp.com>
 */

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/firmware/imx/ipc.h>
#include <linux/firmware/imx/s4.h>
@@ -15,6 +16,7 @@
#include <linux/mailbox_controller.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/suspend.h>
@@ -29,7 +31,9 @@
#define IMX_MU_S4_CHANS		2
#define IMX_MU_CHAN_NAME_SIZE	20

#define IMX_MU_NUM_RR		4
#define IMX_MU_V2_PAR_OFF	0x4
#define IMX_MU_V2_TR_MASK	GENMASK(7, 0)
#define IMX_MU_V2_RR_MASK	GENMASK(15, 8)

#define IMX_MU_SECO_TX_TOUT (msecs_to_jiffies(3000))
#define IMX_MU_SECO_RX_TOUT (msecs_to_jiffies(3000))
@@ -93,10 +97,11 @@ struct imx_mu_priv {
	struct clk		*clk;
	int			irq[IMX_MU_CHANS];
	bool			suspend;
	bool			side_b;

	u32			xcr[IMX_MU_xCR_MAX];

	bool			side_b;
	u32			num_tr;
	u32			num_rr;
};

enum imx_mu_type {
@@ -110,7 +115,7 @@ struct imx_mu_dcfg {
	int (*tx)(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp, void *data);
	int (*rx)(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp);
	int (*rxdb)(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp);
	void (*init)(struct imx_mu_priv *priv);
	int (*init)(struct imx_mu_priv *priv);
	enum imx_mu_type type;
	u32	xTR;		/* Transmit Register0 */
	u32	xRR;		/* Receive Register0 */
@@ -264,18 +269,17 @@ static int imx_mu_generic_rxdb(struct imx_mu_priv *priv,
static int imx_mu_specific_tx(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp, void *data)
{
	u32 *arg = data;
	u32 num_tr = priv->num_tr;
	int i, ret;
	u32 xsr;
	u32 size, max_size, num_tr;
	u32 size, max_size;

	if (priv->dcfg->type & IMX_MU_V2_S4) {
		size = ((struct imx_s4_rpc_msg_max *)data)->hdr.size;
		max_size = sizeof(struct imx_s4_rpc_msg_max);
		num_tr = 8;
	} else {
		size = ((struct imx_sc_rpc_msg_max *)data)->hdr.size;
		max_size = sizeof(struct imx_sc_rpc_msg_max);
		num_tr = 4;
	}

	switch (cp->type) {
@@ -324,6 +328,7 @@ static int imx_mu_specific_rx(struct imx_mu_priv *priv, struct imx_mu_con_priv *
	int i, ret;
	u32 xsr;
	u32 size, max_size;
	u32 num_rr = priv->num_rr;

	data = (u32 *)priv->msg;

@@ -345,13 +350,13 @@ static int imx_mu_specific_rx(struct imx_mu_priv *priv, struct imx_mu_con_priv *

	for (i = 1; i < size; i++) {
		ret = readl_poll_timeout(priv->base + priv->dcfg->xSR[IMX_MU_RSR], xsr,
					 xsr & IMX_MU_xSR_RFn(priv->dcfg->type, i % 4), 0,
					 xsr & IMX_MU_xSR_RFn(priv->dcfg->type, i % num_rr), 0,
					 5 * USEC_PER_SEC);
		if (ret) {
			dev_err(priv->dev, "timeout read idx %d\n", i);
			return ret;
		}
		*data++ = imx_mu_read(priv, priv->dcfg->xRR + (i % 4) * 4);
		*data++ = imx_mu_read(priv, priv->dcfg->xRR + (i % num_rr) * 4);
	}

	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,
	return imx_mu_xlate(mbox, sp);
}

static void imx_mu_init_generic(struct imx_mu_priv *priv)
static void imx_mu_get_tr_rr(struct imx_mu_priv *priv)
{
	u32 val;

	if (priv->dcfg->type & IMX_MU_V2) {
		val = imx_mu_read(priv, IMX_MU_V2_PAR_OFF);
		priv->num_tr = FIELD_GET(IMX_MU_V2_TR_MASK, val);
		priv->num_rr = FIELD_GET(IMX_MU_V2_RR_MASK, val);
	} else {
		priv->num_tr = 4;
		priv->num_rr = 4;
	}
}

static int imx_mu_init_generic(struct imx_mu_priv *priv)
{
	unsigned int i;
	unsigned int val;

	if (priv->num_rr > 4 || priv->num_tr > 4) {
		WARN_ONCE(true, "%s not support TR/RR larger than 4\n", __func__);
		return -EOPNOTSUPP;
	}

	for (i = 0; i < IMX_MU_CHANS; i++) {
		struct imx_mu_con_priv *cp = &priv->con_priv[i];

@@ -757,7 +781,7 @@ static void imx_mu_init_generic(struct imx_mu_priv *priv)
	priv->mbox.of_xlate = imx_mu_xlate;

	if (priv->side_b)
		return;
		return 0;

	/* Set default MU configuration */
	for (i = 0; i < IMX_MU_xCR_MAX; i++)
@@ -768,11 +792,13 @@ static void imx_mu_init_generic(struct imx_mu_priv *priv)
	imx_mu_write(priv, val, priv->dcfg->xSR[IMX_MU_GSR]);

	/* Clear any pending RSR */
	for (i = 0; i < IMX_MU_NUM_RR; i++)
		imx_mu_read(priv, priv->dcfg->xRR + (i % 4) * 4);
	for (i = 0; i < priv->num_rr; i++)
		imx_mu_read(priv, priv->dcfg->xRR + i * 4);

	return 0;
}

static void imx_mu_init_specific(struct imx_mu_priv *priv)
static int imx_mu_init_specific(struct imx_mu_priv *priv)
{
	unsigned int i;
	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)
	/* Set default MU configuration */
	for (i = 0; i < IMX_MU_xCR_MAX; i++)
		imx_mu_write(priv, 0, priv->dcfg->xCR[i]);

	return 0;
}

static void imx_mu_init_seco(struct imx_mu_priv *priv)
static int imx_mu_init_seco(struct imx_mu_priv *priv)
{
	imx_mu_init_generic(priv);
	int ret;

	ret = imx_mu_init_generic(priv);
	if (ret)
		return ret;
	priv->mbox.of_xlate = imx_mu_seco_xlate;

	return 0;
}

static int imx_mu_probe(struct platform_device *pdev)
@@ -864,9 +898,15 @@ static int imx_mu_probe(struct platform_device *pdev)
		return ret;
	}

	imx_mu_get_tr_rr(priv);

	priv->side_b = of_property_read_bool(np, "fsl,mu-side-b");

	priv->dcfg->init(priv);
	ret = priv->dcfg->init(priv);
	if (ret) {
		dev_err(dev, "Failed to init MU\n");
		goto disable_clk;
	}

	spin_lock_init(&priv->xcr_lock);

@@ -878,10 +918,10 @@ static int imx_mu_probe(struct platform_device *pdev)
	platform_set_drvdata(pdev, priv);

	ret = devm_mbox_controller_register(dev, &priv->mbox);
	if (ret) {
		clk_disable_unprepare(priv->clk);
		return ret;
	}
	if (ret)
		goto disable_clk;

	of_platform_populate(dev->of_node, NULL, NULL, dev);

	pm_runtime_enable(dev);

@@ -899,6 +939,7 @@ static int imx_mu_probe(struct platform_device *pdev)

disable_runtime_pm:
	pm_runtime_disable(dev);
disable_clk:
	clk_disable_unprepare(priv->clk);
	return ret;
}
@@ -994,6 +1035,9 @@ static const struct of_device_id imx_mu_dt_ids[] = {
	{ .compatible = "fsl,imx8ulp-mu", .data = &imx_mu_cfg_imx8ulp },
	{ .compatible = "fsl,imx8ulp-mu-s4", .data = &imx_mu_cfg_imx8ulp_s4 },
	{ .compatible = "fsl,imx93-mu-s4", .data = &imx_mu_cfg_imx93_s4 },
	{ .compatible = "fsl,imx95-mu", .data = &imx_mu_cfg_imx8ulp },
	{ .compatible = "fsl,imx95-mu-ele", .data = &imx_mu_cfg_imx8ulp_s4 },
	{ .compatible = "fsl,imx95-mu-v2x", .data = &imx_mu_cfg_imx8ulp_s4 },
	{ .compatible = "fsl,imx8-mu-scu", .data = &imx_mu_cfg_imx8_scu },
	{ .compatible = "fsl,imx8-mu-seco", .data = &imx_mu_cfg_imx8_seco },
	{ },