brintos

brintos / linux-shallow public Read only

0
0
Text · 28.5 KiB · f815dab Raw
1135 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (c) 2018 Pengutronix, Oleksij Rempel <o.rempel@pengutronix.de>4 * Copyright 2022 NXP, Peng Fan <peng.fan@nxp.com>5 */6 7#include <linux/bitfield.h>8#include <linux/clk.h>9#include <linux/firmware/imx/ipc.h>10#include <linux/firmware/imx/s4.h>11#include <linux/interrupt.h>12#include <linux/io.h>13#include <linux/iopoll.h>14#include <linux/jiffies.h>15#include <linux/kernel.h>16#include <linux/mailbox_controller.h>17#include <linux/module.h>18#include <linux/of.h>19#include <linux/of_platform.h>20#include <linux/platform_device.h>21#include <linux/pm_runtime.h>22#include <linux/suspend.h>23#include <linux/slab.h>24#include <linux/workqueue.h>25 26#include "mailbox.h"27 28#define IMX_MU_CHANS		2429/* TX0/RX0/RXDB[0-3] */30#define IMX_MU_SCU_CHANS	631/* TX0/RX0 */32#define IMX_MU_S4_CHANS		233#define IMX_MU_CHAN_NAME_SIZE	3234 35#define IMX_MU_V2_PAR_OFF	0x436#define IMX_MU_V2_TR_MASK	GENMASK(7, 0)37#define IMX_MU_V2_RR_MASK	GENMASK(15, 8)38 39#define IMX_MU_SECO_TX_TOUT (msecs_to_jiffies(3000))40#define IMX_MU_SECO_RX_TOUT (msecs_to_jiffies(3000))41 42/* Please not change TX & RX */43enum imx_mu_chan_type {44	IMX_MU_TYPE_TX		= 0, /* Tx */45	IMX_MU_TYPE_RX		= 1, /* Rx */46	IMX_MU_TYPE_TXDB	= 2, /* Tx doorbell */47	IMX_MU_TYPE_RXDB	= 3, /* Rx doorbell */48	IMX_MU_TYPE_RST		= 4, /* Reset */49	IMX_MU_TYPE_TXDB_V2	= 5, /* Tx doorbell with S/W ACK */50};51 52enum imx_mu_xcr {53	IMX_MU_CR,54	IMX_MU_GIER,55	IMX_MU_GCR,56	IMX_MU_TCR,57	IMX_MU_RCR,58	IMX_MU_xCR_MAX,59};60 61enum imx_mu_xsr {62	IMX_MU_SR,63	IMX_MU_GSR,64	IMX_MU_TSR,65	IMX_MU_RSR,66	IMX_MU_xSR_MAX,67};68 69struct imx_sc_rpc_msg_max {70	struct imx_sc_rpc_msg hdr;71	u32 data[30];72};73 74struct imx_s4_rpc_msg_max {75	struct imx_s4_rpc_msg hdr;76	u32 data[254];77};78 79struct imx_mu_con_priv {80	unsigned int		idx;81	char			irq_desc[IMX_MU_CHAN_NAME_SIZE];82	enum imx_mu_chan_type	type;83	struct mbox_chan	*chan;84	struct work_struct 	txdb_work;85};86 87struct imx_mu_priv {88	struct device		*dev;89	void __iomem		*base;90	void			*msg;91	spinlock_t		xcr_lock; /* control register lock */92 93	struct mbox_controller	mbox;94	struct mbox_chan	mbox_chans[IMX_MU_CHANS];95 96	struct imx_mu_con_priv  con_priv[IMX_MU_CHANS];97	const struct imx_mu_dcfg	*dcfg;98	struct clk		*clk;99	int			irq[IMX_MU_CHANS];100	bool			suspend;101	bool			side_b;102 103	u32			xcr[IMX_MU_xCR_MAX];104	u32			num_tr;105	u32			num_rr;106};107 108enum imx_mu_type {109	IMX_MU_V1,110	IMX_MU_V2 = BIT(1),111	IMX_MU_V2_S4 = BIT(15),112	IMX_MU_V2_IRQ = BIT(16),113};114 115struct imx_mu_dcfg {116	int (*tx)(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp, void *data);117	int (*rx)(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp);118	int (*rxdb)(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp);119	int (*init)(struct imx_mu_priv *priv);120	enum imx_mu_type type;121	u32	xTR;		/* Transmit Register0 */122	u32	xRR;		/* Receive Register0 */123	u32	xSR[IMX_MU_xSR_MAX];	/* Status Registers */124	u32	xCR[IMX_MU_xCR_MAX];	/* Control Registers */125};126 127#define IMX_MU_xSR_GIPn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(28 + (3 - (x))))128#define IMX_MU_xSR_RFn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(24 + (3 - (x))))129#define IMX_MU_xSR_TEn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(20 + (3 - (x))))130 131/* General Purpose Interrupt Enable */132#define IMX_MU_xCR_GIEn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(28 + (3 - (x))))133/* Receive Interrupt Enable */134#define IMX_MU_xCR_RIEn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(24 + (3 - (x))))135/* Transmit Interrupt Enable */136#define IMX_MU_xCR_TIEn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(20 + (3 - (x))))137/* General Purpose Interrupt Request */138#define IMX_MU_xCR_GIRn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(16 + (3 - (x))))139/* MU reset */140#define IMX_MU_xCR_RST(type)	(type & IMX_MU_V2 ? BIT(0) : BIT(5))141#define IMX_MU_xSR_RST(type)	(type & IMX_MU_V2 ? BIT(0) : BIT(7))142 143 144static struct imx_mu_priv *to_imx_mu_priv(struct mbox_controller *mbox)145{146	return container_of(mbox, struct imx_mu_priv, mbox);147}148 149static void imx_mu_write(struct imx_mu_priv *priv, u32 val, u32 offs)150{151	iowrite32(val, priv->base + offs);152}153 154static u32 imx_mu_read(struct imx_mu_priv *priv, u32 offs)155{156	return ioread32(priv->base + offs);157}158 159static int imx_mu_tx_waiting_write(struct imx_mu_priv *priv, u32 val, u32 idx)160{161	u64 timeout_time = get_jiffies_64() + IMX_MU_SECO_TX_TOUT;162	u32 status;163	u32 can_write;164 165	dev_dbg(priv->dev, "Trying to write %.8x to idx %d\n", val, idx);166 167	do {168		status = imx_mu_read(priv, priv->dcfg->xSR[IMX_MU_TSR]);169		can_write = status & IMX_MU_xSR_TEn(priv->dcfg->type, idx % 4);170	} while (!can_write && time_is_after_jiffies64(timeout_time));171 172	if (!can_write) {173		dev_err(priv->dev, "timeout trying to write %.8x at %d(%.8x)\n",174			val, idx, status);175		return -ETIME;176	}177 178	imx_mu_write(priv, val, priv->dcfg->xTR + (idx % 4) * 4);179 180	return 0;181}182 183static int imx_mu_rx_waiting_read(struct imx_mu_priv *priv, u32 *val, u32 idx)184{185	u64 timeout_time = get_jiffies_64() + IMX_MU_SECO_RX_TOUT;186	u32 status;187	u32 can_read;188 189	dev_dbg(priv->dev, "Trying to read from idx %d\n", idx);190 191	do {192		status = imx_mu_read(priv, priv->dcfg->xSR[IMX_MU_RSR]);193		can_read = status & IMX_MU_xSR_RFn(priv->dcfg->type, idx % 4);194	} while (!can_read && time_is_after_jiffies64(timeout_time));195 196	if (!can_read) {197		dev_err(priv->dev, "timeout trying to read idx %d (%.8x)\n",198			idx, status);199		return -ETIME;200	}201 202	*val = imx_mu_read(priv, priv->dcfg->xRR + (idx % 4) * 4);203	dev_dbg(priv->dev, "Read %.8x\n", *val);204 205	return 0;206}207 208static u32 imx_mu_xcr_rmw(struct imx_mu_priv *priv, enum imx_mu_xcr type, u32 set, u32 clr)209{210	unsigned long flags;211	u32 val;212 213	spin_lock_irqsave(&priv->xcr_lock, flags);214	val = imx_mu_read(priv, priv->dcfg->xCR[type]);215	val &= ~clr;216	val |= set;217	imx_mu_write(priv, val, priv->dcfg->xCR[type]);218	spin_unlock_irqrestore(&priv->xcr_lock, flags);219 220	return val;221}222 223static int imx_mu_generic_tx(struct imx_mu_priv *priv,224			     struct imx_mu_con_priv *cp,225			     void *data)226{227	u32 *arg = data;228	u32 val;229	int ret;230 231	switch (cp->type) {232	case IMX_MU_TYPE_TX:233		imx_mu_write(priv, *arg, priv->dcfg->xTR + cp->idx * 4);234		imx_mu_xcr_rmw(priv, IMX_MU_TCR, IMX_MU_xCR_TIEn(priv->dcfg->type, cp->idx), 0);235		break;236	case IMX_MU_TYPE_TXDB:237		imx_mu_xcr_rmw(priv, IMX_MU_GCR, IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx), 0);238		queue_work(system_bh_wq, &cp->txdb_work);239		break;240	case IMX_MU_TYPE_TXDB_V2:241		imx_mu_write(priv, IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx),242			     priv->dcfg->xCR[IMX_MU_GCR]);243		ret = readl_poll_timeout(priv->base + priv->dcfg->xCR[IMX_MU_GCR], val,244					 !(val & IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx)),245					 0, 1000);246		if (ret)247			dev_warn_ratelimited(priv->dev, "channel type: %d failure\n", cp->type);248		break;249	default:250		dev_warn_ratelimited(priv->dev, "Send data on wrong channel type: %d\n", cp->type);251		return -EINVAL;252	}253 254	return 0;255}256 257static int imx_mu_generic_rx(struct imx_mu_priv *priv,258			     struct imx_mu_con_priv *cp)259{260	u32 dat;261 262	dat = imx_mu_read(priv, priv->dcfg->xRR + (cp->idx) * 4);263	mbox_chan_received_data(cp->chan, (void *)&dat);264 265	return 0;266}267 268static int imx_mu_generic_rxdb(struct imx_mu_priv *priv,269			       struct imx_mu_con_priv *cp)270{271	imx_mu_write(priv, IMX_MU_xSR_GIPn(priv->dcfg->type, cp->idx),272		     priv->dcfg->xSR[IMX_MU_GSR]);273	mbox_chan_received_data(cp->chan, NULL);274 275	return 0;276}277 278static int imx_mu_specific_tx(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp, void *data)279{280	u32 *arg = data;281	u32 num_tr = priv->num_tr;282	int i, ret;283	u32 xsr;284	u32 size, max_size;285 286	if (priv->dcfg->type & IMX_MU_V2_S4) {287		size = ((struct imx_s4_rpc_msg_max *)data)->hdr.size;288		max_size = sizeof(struct imx_s4_rpc_msg_max);289	} else {290		size = ((struct imx_sc_rpc_msg_max *)data)->hdr.size;291		max_size = sizeof(struct imx_sc_rpc_msg_max);292	}293 294	switch (cp->type) {295	case IMX_MU_TYPE_TX:296		/*297		 * msg->hdr.size specifies the number of u32 words while298		 * sizeof yields bytes.299		 */300 301		if (size > max_size / 4) {302			/*303			 * The real message size can be different to304			 * struct imx_sc_rpc_msg_max/imx_s4_rpc_msg_max size305			 */306			dev_err(priv->dev, "Maximal message size (%u bytes) exceeded on TX; got: %i bytes\n", max_size, size << 2);307			return -EINVAL;308		}309 310		for (i = 0; i < num_tr && i < size; i++)311			imx_mu_write(priv, *arg++, priv->dcfg->xTR + (i % num_tr) * 4);312		for (; i < size; i++) {313			ret = readl_poll_timeout(priv->base + priv->dcfg->xSR[IMX_MU_TSR],314						 xsr,315						 xsr & IMX_MU_xSR_TEn(priv->dcfg->type, i % num_tr),316						 0, 5 * USEC_PER_SEC);317			if (ret) {318				dev_err(priv->dev, "Send data index: %d timeout\n", i);319				return ret;320			}321			imx_mu_write(priv, *arg++, priv->dcfg->xTR + (i % num_tr) * 4);322		}323 324		imx_mu_xcr_rmw(priv, IMX_MU_TCR, IMX_MU_xCR_TIEn(priv->dcfg->type, cp->idx), 0);325		break;326	default:327		dev_warn_ratelimited(priv->dev, "Send data on wrong channel type: %d\n", cp->type);328		return -EINVAL;329	}330 331	return 0;332}333 334static int imx_mu_specific_rx(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp)335{336	u32 *data;337	int i, ret;338	u32 xsr;339	u32 size, max_size;340	u32 num_rr = priv->num_rr;341 342	data = (u32 *)priv->msg;343 344	imx_mu_xcr_rmw(priv, IMX_MU_RCR, 0, IMX_MU_xCR_RIEn(priv->dcfg->type, 0));345	*data++ = imx_mu_read(priv, priv->dcfg->xRR);346 347	if (priv->dcfg->type & IMX_MU_V2_S4) {348		size = ((struct imx_s4_rpc_msg_max *)priv->msg)->hdr.size;349		max_size = sizeof(struct imx_s4_rpc_msg_max);350	} else {351		size = ((struct imx_sc_rpc_msg_max *)priv->msg)->hdr.size;352		max_size = sizeof(struct imx_sc_rpc_msg_max);353	}354 355	if (size > max_size / 4) {356		dev_err(priv->dev, "Maximal message size (%u bytes) exceeded on RX; got: %i bytes\n", max_size, size << 2);357		return -EINVAL;358	}359 360	for (i = 1; i < size; i++) {361		ret = readl_poll_timeout(priv->base + priv->dcfg->xSR[IMX_MU_RSR], xsr,362					 xsr & IMX_MU_xSR_RFn(priv->dcfg->type, i % num_rr), 0,363					 5 * USEC_PER_SEC);364		if (ret) {365			dev_err(priv->dev, "timeout read idx %d\n", i);366			return ret;367		}368		*data++ = imx_mu_read(priv, priv->dcfg->xRR + (i % num_rr) * 4);369	}370 371	imx_mu_xcr_rmw(priv, IMX_MU_RCR, IMX_MU_xCR_RIEn(priv->dcfg->type, 0), 0);372	mbox_chan_received_data(cp->chan, (void *)priv->msg);373 374	return 0;375}376 377static int imx_mu_seco_tx(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp,378			  void *data)379{380	struct imx_sc_rpc_msg_max *msg = data;381	u32 *arg = data;382	u32 byte_size;383	int err;384	int i;385 386	dev_dbg(priv->dev, "Sending message\n");387 388	switch (cp->type) {389	case IMX_MU_TYPE_TXDB:390		byte_size = msg->hdr.size * sizeof(u32);391		if (byte_size > sizeof(*msg)) {392			/*393			 * The real message size can be different to394			 * struct imx_sc_rpc_msg_max size395			 */396			dev_err(priv->dev,397				"Exceed max msg size (%zu) on TX, got: %i\n",398				sizeof(*msg), byte_size);399			return -EINVAL;400		}401 402		print_hex_dump_debug("from client ", DUMP_PREFIX_OFFSET, 4, 4,403				     data, byte_size, false);404 405		/* Send first word */406		dev_dbg(priv->dev, "Sending header\n");407		imx_mu_write(priv, *arg++, priv->dcfg->xTR);408 409		/* Send signaling */410		dev_dbg(priv->dev, "Sending signaling\n");411		imx_mu_xcr_rmw(priv, IMX_MU_GCR,412			       IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx), 0);413 414		/* Send words to fill the mailbox */415		for (i = 1; i < 4 && i < msg->hdr.size; i++) {416			dev_dbg(priv->dev, "Sending word %d\n", i);417			imx_mu_write(priv, *arg++,418				     priv->dcfg->xTR + (i % 4) * 4);419		}420 421		/* Send rest of message waiting for remote read */422		for (; i < msg->hdr.size; i++) {423			dev_dbg(priv->dev, "Sending word %d\n", i);424			err = imx_mu_tx_waiting_write(priv, *arg++, i);425			if (err) {426				dev_err(priv->dev, "Timeout tx %d\n", i);427				return err;428			}429		}430 431		/* Simulate hack for mbox framework */432		queue_work(system_bh_wq, &cp->txdb_work);433 434		break;435	default:436		dev_warn_ratelimited(priv->dev,437				     "Send data on wrong channel type: %d\n",438				     cp->type);439		return -EINVAL;440	}441 442	return 0;443}444 445static int imx_mu_seco_rxdb(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp)446{447	struct imx_sc_rpc_msg_max msg;448	u32 *data = (u32 *)&msg;449	u32 byte_size;450	int err = 0;451	int i;452 453	dev_dbg(priv->dev, "Receiving message\n");454 455	/* Read header */456	dev_dbg(priv->dev, "Receiving header\n");457	*data++ = imx_mu_read(priv, priv->dcfg->xRR);458	byte_size = msg.hdr.size * sizeof(u32);459	if (byte_size > sizeof(msg)) {460		dev_err(priv->dev, "Exceed max msg size (%zu) on RX, got: %i\n",461			sizeof(msg), byte_size);462		err = -EINVAL;463		goto error;464	}465 466	/* Read message waiting they are written */467	for (i = 1; i < msg.hdr.size; i++) {468		dev_dbg(priv->dev, "Receiving word %d\n", i);469		err = imx_mu_rx_waiting_read(priv, data++, i);470		if (err) {471			dev_err(priv->dev, "Timeout rx %d\n", i);472			goto error;473		}474	}475 476	/* Clear GIP */477	imx_mu_write(priv, IMX_MU_xSR_GIPn(priv->dcfg->type, cp->idx),478		     priv->dcfg->xSR[IMX_MU_GSR]);479 480	print_hex_dump_debug("to client ", DUMP_PREFIX_OFFSET, 4, 4,481			     &msg, byte_size, false);482 483	/* send data to client */484	dev_dbg(priv->dev, "Sending message to client\n");485	mbox_chan_received_data(cp->chan, (void *)&msg);486 487	goto exit;488 489error:490	mbox_chan_received_data(cp->chan, ERR_PTR(err));491 492exit:493	return err;494}495 496static void imx_mu_txdb_work(struct work_struct *t)497{498	struct imx_mu_con_priv *cp = from_work(cp, t, txdb_work);499 500	mbox_chan_txdone(cp->chan, 0);501}502 503static irqreturn_t imx_mu_isr(int irq, void *p)504{505	struct mbox_chan *chan = p;506	struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);507	struct imx_mu_con_priv *cp = chan->con_priv;508	u32 val, ctrl;509 510	switch (cp->type) {511	case IMX_MU_TYPE_TX:512		ctrl = imx_mu_read(priv, priv->dcfg->xCR[IMX_MU_TCR]);513		val = imx_mu_read(priv, priv->dcfg->xSR[IMX_MU_TSR]);514		val &= IMX_MU_xSR_TEn(priv->dcfg->type, cp->idx) &515			(ctrl & IMX_MU_xCR_TIEn(priv->dcfg->type, cp->idx));516		break;517	case IMX_MU_TYPE_RX:518		ctrl = imx_mu_read(priv, priv->dcfg->xCR[IMX_MU_RCR]);519		val = imx_mu_read(priv, priv->dcfg->xSR[IMX_MU_RSR]);520		val &= IMX_MU_xSR_RFn(priv->dcfg->type, cp->idx) &521			(ctrl & IMX_MU_xCR_RIEn(priv->dcfg->type, cp->idx));522		break;523	case IMX_MU_TYPE_RXDB:524		ctrl = imx_mu_read(priv, priv->dcfg->xCR[IMX_MU_GIER]);525		val = imx_mu_read(priv, priv->dcfg->xSR[IMX_MU_GSR]);526		val &= IMX_MU_xSR_GIPn(priv->dcfg->type, cp->idx) &527			(ctrl & IMX_MU_xCR_GIEn(priv->dcfg->type, cp->idx));528		break;529	case IMX_MU_TYPE_RST:530		return IRQ_NONE;531	default:532		dev_warn_ratelimited(priv->dev, "Unhandled channel type %d\n",533				     cp->type);534		return IRQ_NONE;535	}536 537	if (!val)538		return IRQ_NONE;539 540	if ((val == IMX_MU_xSR_TEn(priv->dcfg->type, cp->idx)) &&541	    (cp->type == IMX_MU_TYPE_TX)) {542		imx_mu_xcr_rmw(priv, IMX_MU_TCR, 0, IMX_MU_xCR_TIEn(priv->dcfg->type, cp->idx));543		mbox_chan_txdone(chan, 0);544	} else if ((val == IMX_MU_xSR_RFn(priv->dcfg->type, cp->idx)) &&545		   (cp->type == IMX_MU_TYPE_RX)) {546		priv->dcfg->rx(priv, cp);547	} else if ((val == IMX_MU_xSR_GIPn(priv->dcfg->type, cp->idx)) &&548		   (cp->type == IMX_MU_TYPE_RXDB)) {549		priv->dcfg->rxdb(priv, cp);550	} else {551		dev_warn_ratelimited(priv->dev, "Not handled interrupt\n");552		return IRQ_NONE;553	}554 555	if (priv->suspend)556		pm_system_wakeup();557 558	return IRQ_HANDLED;559}560 561static int imx_mu_send_data(struct mbox_chan *chan, void *data)562{563	struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);564	struct imx_mu_con_priv *cp = chan->con_priv;565 566	return priv->dcfg->tx(priv, cp, data);567}568 569static int imx_mu_startup(struct mbox_chan *chan)570{571	struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);572	struct imx_mu_con_priv *cp = chan->con_priv;573	unsigned long irq_flag = 0;574	int ret;575 576	pm_runtime_get_sync(priv->dev);577	if (cp->type == IMX_MU_TYPE_TXDB_V2)578		return 0;579 580	if (cp->type == IMX_MU_TYPE_TXDB) {581		/* Tx doorbell don't have ACK support */582		INIT_WORK(&cp->txdb_work, imx_mu_txdb_work);583		return 0;584	}585 586	/* IPC MU should be with IRQF_NO_SUSPEND set */587	if (!priv->dev->pm_domain)588		irq_flag |= IRQF_NO_SUSPEND;589 590	if (!(priv->dcfg->type & IMX_MU_V2_IRQ))591		irq_flag |= IRQF_SHARED;592 593	ret = request_irq(priv->irq[cp->type], imx_mu_isr, irq_flag, cp->irq_desc, chan);594	if (ret) {595		dev_err(priv->dev, "Unable to acquire IRQ %d\n", priv->irq[cp->type]);596		return ret;597	}598 599	switch (cp->type) {600	case IMX_MU_TYPE_RX:601		imx_mu_xcr_rmw(priv, IMX_MU_RCR, IMX_MU_xCR_RIEn(priv->dcfg->type, cp->idx), 0);602		break;603	case IMX_MU_TYPE_RXDB:604		imx_mu_xcr_rmw(priv, IMX_MU_GIER, IMX_MU_xCR_GIEn(priv->dcfg->type, cp->idx), 0);605		break;606	default:607		break;608	}609 610	return 0;611}612 613static void imx_mu_shutdown(struct mbox_chan *chan)614{615	struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);616	struct imx_mu_con_priv *cp = chan->con_priv;617	int ret;618	u32 sr;619 620	if (cp->type == IMX_MU_TYPE_TXDB_V2) {621		pm_runtime_put_sync(priv->dev);622		return;623	}624 625	if (cp->type == IMX_MU_TYPE_TXDB) {626		cancel_work_sync(&cp->txdb_work);627		pm_runtime_put_sync(priv->dev);628		return;629	}630 631	switch (cp->type) {632	case IMX_MU_TYPE_TX:633		imx_mu_xcr_rmw(priv, IMX_MU_TCR, 0, IMX_MU_xCR_TIEn(priv->dcfg->type, cp->idx));634		break;635	case IMX_MU_TYPE_RX:636		imx_mu_xcr_rmw(priv, IMX_MU_RCR, 0, IMX_MU_xCR_RIEn(priv->dcfg->type, cp->idx));637		break;638	case IMX_MU_TYPE_RXDB:639		imx_mu_xcr_rmw(priv, IMX_MU_GIER, 0, IMX_MU_xCR_GIEn(priv->dcfg->type, cp->idx));640		break;641	case IMX_MU_TYPE_RST:642		imx_mu_xcr_rmw(priv, IMX_MU_CR, IMX_MU_xCR_RST(priv->dcfg->type), 0);643		ret = readl_poll_timeout(priv->base + priv->dcfg->xSR[IMX_MU_SR], sr,644					 !(sr & IMX_MU_xSR_RST(priv->dcfg->type)), 1, 5);645		if (ret)646			dev_warn(priv->dev, "RST channel timeout\n");647		break;648	default:649		break;650	}651 652	free_irq(priv->irq[cp->type], chan);653	pm_runtime_put_sync(priv->dev);654}655 656static const struct mbox_chan_ops imx_mu_ops = {657	.send_data = imx_mu_send_data,658	.startup = imx_mu_startup,659	.shutdown = imx_mu_shutdown,660};661 662static struct mbox_chan *imx_mu_specific_xlate(struct mbox_controller *mbox,663					       const struct of_phandle_args *sp)664{665	u32 type, idx, chan;666 667	if (sp->args_count != 2) {668		dev_err(mbox->dev, "Invalid argument count %d\n", sp->args_count);669		return ERR_PTR(-EINVAL);670	}671 672	type = sp->args[0]; /* channel type */673	idx = sp->args[1]; /* index */674 675	switch (type) {676	case IMX_MU_TYPE_TX:677	case IMX_MU_TYPE_RX:678		if (idx != 0)679			dev_err(mbox->dev, "Invalid chan idx: %d\n", idx);680		chan = type;681		break;682	case IMX_MU_TYPE_RXDB:683		chan = 2 + idx;684		break;685	default:686		dev_err(mbox->dev, "Invalid chan type: %d\n", type);687		return ERR_PTR(-EINVAL);688	}689 690	if (chan >= mbox->num_chans) {691		dev_err(mbox->dev, "Not supported channel number: %d. (type: %d, idx: %d)\n", chan, type, idx);692		return ERR_PTR(-EINVAL);693	}694 695	return &mbox->chans[chan];696}697 698static struct mbox_chan * imx_mu_xlate(struct mbox_controller *mbox,699				       const struct of_phandle_args *sp)700{701	struct mbox_chan *p_chan;702	u32 type, idx, chan;703 704	if (sp->args_count != 2) {705		dev_err(mbox->dev, "Invalid argument count %d\n", sp->args_count);706		return ERR_PTR(-EINVAL);707	}708 709	type = sp->args[0]; /* channel type */710	idx = sp->args[1]; /* index */711 712	/* RST only supports 1 channel */713	if ((type == IMX_MU_TYPE_RST) && idx) {714		dev_err(mbox->dev, "Invalid RST channel %d\n", idx);715		return ERR_PTR(-EINVAL);716	}717 718	chan = type * 4 + idx;719	if (chan >= mbox->num_chans) {720		dev_err(mbox->dev, "Not supported channel number: %d. (type: %d, idx: %d)\n", chan, type, idx);721		return ERR_PTR(-EINVAL);722	}723 724	p_chan = &mbox->chans[chan];725 726	if (type == IMX_MU_TYPE_TXDB_V2)727		p_chan->txdone_method = TXDONE_BY_ACK;728 729	return p_chan;730}731 732static struct mbox_chan *imx_mu_seco_xlate(struct mbox_controller *mbox,733					   const struct of_phandle_args *sp)734{735	u32 type;736 737	if (sp->args_count < 1) {738		dev_err(mbox->dev, "Invalid argument count %d\n", sp->args_count);739		return ERR_PTR(-EINVAL);740	}741 742	type = sp->args[0]; /* channel type */743 744	/* Only supports TXDB and RXDB */745	if (type == IMX_MU_TYPE_TX || type == IMX_MU_TYPE_RX) {746		dev_err(mbox->dev, "Invalid type: %d\n", type);747		return ERR_PTR(-EINVAL);748	}749 750	return imx_mu_xlate(mbox, sp);751}752 753static void imx_mu_get_tr_rr(struct imx_mu_priv *priv)754{755	u32 val;756 757	if (priv->dcfg->type & IMX_MU_V2) {758		val = imx_mu_read(priv, IMX_MU_V2_PAR_OFF);759		priv->num_tr = FIELD_GET(IMX_MU_V2_TR_MASK, val);760		priv->num_rr = FIELD_GET(IMX_MU_V2_RR_MASK, val);761	} else {762		priv->num_tr = 4;763		priv->num_rr = 4;764	}765}766 767static int imx_mu_init_generic(struct imx_mu_priv *priv)768{769	unsigned int i;770	unsigned int val;771 772	if (priv->num_rr > 4 || priv->num_tr > 4) {773		WARN_ONCE(true, "%s not support TR/RR larger than 4\n", __func__);774		return -EOPNOTSUPP;775	}776 777	for (i = 0; i < IMX_MU_CHANS; i++) {778		struct imx_mu_con_priv *cp = &priv->con_priv[i];779 780		cp->idx = i % 4;781		cp->type = i >> 2;782		cp->chan = &priv->mbox_chans[i];783		priv->mbox_chans[i].con_priv = cp;784		snprintf(cp->irq_desc, sizeof(cp->irq_desc),785			 "%s[%i-%i]", dev_name(priv->dev), cp->type, cp->idx);786	}787 788	priv->mbox.num_chans = IMX_MU_CHANS;789	priv->mbox.of_xlate = imx_mu_xlate;790 791	if (priv->side_b)792		return 0;793 794	/* Set default MU configuration */795	for (i = 0; i < IMX_MU_xCR_MAX; i++)796		imx_mu_write(priv, 0, priv->dcfg->xCR[i]);797 798	/* Clear any pending GIP */799	val = imx_mu_read(priv, priv->dcfg->xSR[IMX_MU_GSR]);800	imx_mu_write(priv, val, priv->dcfg->xSR[IMX_MU_GSR]);801 802	/* Clear any pending RSR */803	for (i = 0; i < priv->num_rr; i++)804		imx_mu_read(priv, priv->dcfg->xRR + i * 4);805 806	return 0;807}808 809static int imx_mu_init_specific(struct imx_mu_priv *priv)810{811	unsigned int i;812	int num_chans = priv->dcfg->type & IMX_MU_V2_S4 ? IMX_MU_S4_CHANS : IMX_MU_SCU_CHANS;813 814	for (i = 0; i < num_chans; i++) {815		struct imx_mu_con_priv *cp = &priv->con_priv[i];816 817		cp->idx = i < 2 ? 0 : i - 2;818		cp->type = i < 2 ? i : IMX_MU_TYPE_RXDB;819		cp->chan = &priv->mbox_chans[i];820		priv->mbox_chans[i].con_priv = cp;821		snprintf(cp->irq_desc, sizeof(cp->irq_desc),822			 "%s[%i-%i]", dev_name(priv->dev), cp->type, cp->idx);823	}824 825	priv->mbox.num_chans = num_chans;826	priv->mbox.of_xlate = imx_mu_specific_xlate;827 828	/* Set default MU configuration */829	for (i = 0; i < IMX_MU_xCR_MAX; i++)830		imx_mu_write(priv, 0, priv->dcfg->xCR[i]);831 832	return 0;833}834 835static int imx_mu_init_seco(struct imx_mu_priv *priv)836{837	int ret;838 839	ret = imx_mu_init_generic(priv);840	if (ret)841		return ret;842	priv->mbox.of_xlate = imx_mu_seco_xlate;843 844	return 0;845}846 847static int imx_mu_probe(struct platform_device *pdev)848{849	struct device *dev = &pdev->dev;850	struct device_node *np = dev->of_node;851	struct imx_mu_priv *priv;852	const struct imx_mu_dcfg *dcfg;853	int i, ret;854	u32 size;855 856	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);857	if (!priv)858		return -ENOMEM;859 860	priv->dev = dev;861 862	priv->base = devm_platform_ioremap_resource(pdev, 0);863	if (IS_ERR(priv->base))864		return PTR_ERR(priv->base);865 866	dcfg = of_device_get_match_data(dev);867	if (!dcfg)868		return -EINVAL;869	priv->dcfg = dcfg;870	if (priv->dcfg->type & IMX_MU_V2_IRQ) {871		priv->irq[IMX_MU_TYPE_TX] = platform_get_irq_byname(pdev, "tx");872		if (priv->irq[IMX_MU_TYPE_TX] < 0)873			return priv->irq[IMX_MU_TYPE_TX];874		priv->irq[IMX_MU_TYPE_RX] = platform_get_irq_byname(pdev, "rx");875		if (priv->irq[IMX_MU_TYPE_RX] < 0)876			return priv->irq[IMX_MU_TYPE_RX];877	} else {878		ret = platform_get_irq(pdev, 0);879		if (ret < 0)880			return ret;881 882		for (i = 0; i < IMX_MU_CHANS; i++)883			priv->irq[i] = ret;884	}885 886	if (priv->dcfg->type & IMX_MU_V2_S4)887		size = sizeof(struct imx_s4_rpc_msg_max);888	else889		size = sizeof(struct imx_sc_rpc_msg_max);890 891	priv->msg = devm_kzalloc(dev, size, GFP_KERNEL);892	if (!priv->msg)893		return -ENOMEM;894 895	priv->clk = devm_clk_get(dev, NULL);896	if (IS_ERR(priv->clk)) {897		if (PTR_ERR(priv->clk) != -ENOENT)898			return PTR_ERR(priv->clk);899 900		priv->clk = NULL;901	}902 903	ret = clk_prepare_enable(priv->clk);904	if (ret) {905		dev_err(dev, "Failed to enable clock\n");906		return ret;907	}908 909	imx_mu_get_tr_rr(priv);910 911	priv->side_b = of_property_read_bool(np, "fsl,mu-side-b");912 913	ret = priv->dcfg->init(priv);914	if (ret) {915		dev_err(dev, "Failed to init MU\n");916		goto disable_clk;917	}918 919	spin_lock_init(&priv->xcr_lock);920 921	priv->mbox.dev = dev;922	priv->mbox.ops = &imx_mu_ops;923	priv->mbox.chans = priv->mbox_chans;924	priv->mbox.txdone_irq = true;925 926	platform_set_drvdata(pdev, priv);927 928	ret = devm_mbox_controller_register(dev, &priv->mbox);929	if (ret)930		goto disable_clk;931 932	of_platform_populate(dev->of_node, NULL, NULL, dev);933 934	pm_runtime_enable(dev);935 936	ret = pm_runtime_resume_and_get(dev);937	if (ret < 0)938		goto disable_runtime_pm;939 940	ret = pm_runtime_put_sync(dev);941	if (ret < 0)942		goto disable_runtime_pm;943 944	clk_disable_unprepare(priv->clk);945 946	return 0;947 948disable_runtime_pm:949	pm_runtime_disable(dev);950disable_clk:951	clk_disable_unprepare(priv->clk);952	return ret;953}954 955static void imx_mu_remove(struct platform_device *pdev)956{957	struct imx_mu_priv *priv = platform_get_drvdata(pdev);958 959	pm_runtime_disable(priv->dev);960}961 962static const struct imx_mu_dcfg imx_mu_cfg_imx6sx = {963	.tx	= imx_mu_generic_tx,964	.rx	= imx_mu_generic_rx,965	.rxdb	= imx_mu_generic_rxdb,966	.init	= imx_mu_init_generic,967	.xTR	= 0x0,968	.xRR	= 0x10,969	.xSR	= {0x20, 0x20, 0x20, 0x20},970	.xCR	= {0x24, 0x24, 0x24, 0x24, 0x24},971};972 973static const struct imx_mu_dcfg imx_mu_cfg_imx7ulp = {974	.tx	= imx_mu_generic_tx,975	.rx	= imx_mu_generic_rx,976	.rxdb	= imx_mu_generic_rxdb,977	.init	= imx_mu_init_generic,978	.xTR	= 0x20,979	.xRR	= 0x40,980	.xSR	= {0x60, 0x60, 0x60, 0x60},981	.xCR	= {0x64, 0x64, 0x64, 0x64, 0x64},982};983 984static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = {985	.tx	= imx_mu_generic_tx,986	.rx	= imx_mu_generic_rx,987	.rxdb	= imx_mu_generic_rxdb,988	.init	= imx_mu_init_generic,989	.type	= IMX_MU_V2,990	.xTR	= 0x200,991	.xRR	= 0x280,992	.xSR	= {0xC, 0x118, 0x124, 0x12C},993	.xCR	= {0x8, 0x110, 0x114, 0x120, 0x128},994};995 996static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp_s4 = {997	.tx	= imx_mu_specific_tx,998	.rx	= imx_mu_specific_rx,999	.init	= imx_mu_init_specific,1000	.type	= IMX_MU_V2 | IMX_MU_V2_S4,1001	.xTR	= 0x200,1002	.xRR	= 0x280,1003	.xSR	= {0xC, 0x118, 0x124, 0x12C},1004	.xCR	= {0x8, 0x110, 0x114, 0x120, 0x128},1005};1006 1007static const struct imx_mu_dcfg imx_mu_cfg_imx93_s4 = {1008	.tx	= imx_mu_specific_tx,1009	.rx	= imx_mu_specific_rx,1010	.init	= imx_mu_init_specific,1011	.type	= IMX_MU_V2 | IMX_MU_V2_S4 | IMX_MU_V2_IRQ,1012	.xTR	= 0x200,1013	.xRR	= 0x280,1014	.xSR	= {0xC, 0x118, 0x124, 0x12C},1015	.xCR	= {0x8, 0x110, 0x114, 0x120, 0x128},1016};1017 1018static const struct imx_mu_dcfg imx_mu_cfg_imx8_scu = {1019	.tx	= imx_mu_specific_tx,1020	.rx	= imx_mu_specific_rx,1021	.init	= imx_mu_init_specific,1022	.rxdb	= imx_mu_generic_rxdb,1023	.xTR	= 0x0,1024	.xRR	= 0x10,1025	.xSR	= {0x20, 0x20, 0x20, 0x20},1026	.xCR	= {0x24, 0x24, 0x24, 0x24, 0x24},1027};1028 1029static const struct imx_mu_dcfg imx_mu_cfg_imx8_seco = {1030	.tx	= imx_mu_seco_tx,1031	.rx	= imx_mu_generic_rx,1032	.rxdb	= imx_mu_seco_rxdb,1033	.init	= imx_mu_init_seco,1034	.xTR	= 0x0,1035	.xRR	= 0x10,1036	.xSR	= {0x20, 0x20, 0x20, 0x20},1037	.xCR	= {0x24, 0x24, 0x24, 0x24, 0x24},1038};1039 1040static const struct of_device_id imx_mu_dt_ids[] = {1041	{ .compatible = "fsl,imx7ulp-mu", .data = &imx_mu_cfg_imx7ulp },1042	{ .compatible = "fsl,imx6sx-mu", .data = &imx_mu_cfg_imx6sx },1043	{ .compatible = "fsl,imx8ulp-mu", .data = &imx_mu_cfg_imx8ulp },1044	{ .compatible = "fsl,imx8ulp-mu-s4", .data = &imx_mu_cfg_imx8ulp_s4 },1045	{ .compatible = "fsl,imx93-mu-s4", .data = &imx_mu_cfg_imx93_s4 },1046	{ .compatible = "fsl,imx95-mu", .data = &imx_mu_cfg_imx8ulp },1047	{ .compatible = "fsl,imx95-mu-ele", .data = &imx_mu_cfg_imx8ulp_s4 },1048	{ .compatible = "fsl,imx95-mu-v2x", .data = &imx_mu_cfg_imx8ulp_s4 },1049	{ .compatible = "fsl,imx8-mu-scu", .data = &imx_mu_cfg_imx8_scu },1050	{ .compatible = "fsl,imx8-mu-seco", .data = &imx_mu_cfg_imx8_seco },1051	{ },1052};1053MODULE_DEVICE_TABLE(of, imx_mu_dt_ids);1054 1055static int __maybe_unused imx_mu_suspend_noirq(struct device *dev)1056{1057	struct imx_mu_priv *priv = dev_get_drvdata(dev);1058	int i;1059 1060	if (!priv->clk) {1061		for (i = 0; i < IMX_MU_xCR_MAX; i++)1062			priv->xcr[i] = imx_mu_read(priv, priv->dcfg->xCR[i]);1063	}1064 1065	priv->suspend = true;1066 1067	return 0;1068}1069 1070static int __maybe_unused imx_mu_resume_noirq(struct device *dev)1071{1072	struct imx_mu_priv *priv = dev_get_drvdata(dev);1073	int i;1074 1075	/*1076	 * ONLY restore MU when context lost, the TIE could1077	 * be set during noirq resume as there is MU data1078	 * communication going on, and restore the saved1079	 * value will overwrite the TIE and cause MU data1080	 * send failed, may lead to system freeze. This issue1081	 * is observed by testing freeze mode suspend.1082	 */1083	if (!priv->clk && !imx_mu_read(priv, priv->dcfg->xCR[0])) {1084		for (i = 0; i < IMX_MU_xCR_MAX; i++)1085			imx_mu_write(priv, priv->xcr[i], priv->dcfg->xCR[i]);1086	}1087 1088	priv->suspend = false;1089 1090	return 0;1091}1092 1093static int __maybe_unused imx_mu_runtime_suspend(struct device *dev)1094{1095	struct imx_mu_priv *priv = dev_get_drvdata(dev);1096 1097	clk_disable_unprepare(priv->clk);1098 1099	return 0;1100}1101 1102static int __maybe_unused imx_mu_runtime_resume(struct device *dev)1103{1104	struct imx_mu_priv *priv = dev_get_drvdata(dev);1105	int ret;1106 1107	ret = clk_prepare_enable(priv->clk);1108	if (ret)1109		dev_err(dev, "failed to enable clock\n");1110 1111	return ret;1112}1113 1114static const struct dev_pm_ops imx_mu_pm_ops = {1115	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_mu_suspend_noirq,1116				      imx_mu_resume_noirq)1117	SET_RUNTIME_PM_OPS(imx_mu_runtime_suspend,1118			   imx_mu_runtime_resume, NULL)1119};1120 1121static struct platform_driver imx_mu_driver = {1122	.probe		= imx_mu_probe,1123	.remove_new	= imx_mu_remove,1124	.driver = {1125		.name	= "imx_mu",1126		.of_match_table = imx_mu_dt_ids,1127		.pm = &imx_mu_pm_ops,1128	},1129};1130module_platform_driver(imx_mu_driver);1131 1132MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");1133MODULE_DESCRIPTION("Message Unit driver for i.MX");1134MODULE_LICENSE("GPL v2");1135