linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Tushar Khandelwal <tushar.khandelwal@arm.com>
To: linux-kernel@vger.kernel.org
Cc: tushar.2nov@gmail.com, morten_bp@live.dk,
	jassisinghbrar@gmail.com, nd@arm.com,
	Morten Borup Petersen <morten.petersen@arm.com>,
	Tushar Khandelwal <tushar.khandelwal@arm.com>,
	devicetree@vger.kernel.org
Subject: [PATCH 3/4] mailbox: arm_mhuv2: add doorbell transport protocol operations
Date: Wed, 17 Jul 2019 20:26:15 +0100	[thread overview]
Message-ID: <20190717192616.1731-4-tushar.khandelwal@arm.com> (raw)
In-Reply-To: <20190717192616.1731-1-tushar.khandelwal@arm.com>

From: Morten Borup Petersen <morten.petersen@arm.com>

In doorbell mode, the mailbox controller will provide a mailbox for each
flag bit available in the combined number of channel windows available
within the MHU device.

When in doorbell mode, the MHU should be used solely as an interrupt
generating mechanism. If data is to be transmitted, this must be done
out-band, ie. through shared memory, by a driving utilizing the mailbox
for interrupt generation.

Signed-off-by: Morten Borup Petersen <morten.petersen@arm.com>
Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
Cc:Jassi Brar <jassisinghbrar@gmail.com
Cc: devicetree@vger.kernel.org
---
 drivers/mailbox/arm_mhu_v2.c | 108 +++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)

diff --git a/drivers/mailbox/arm_mhu_v2.c b/drivers/mailbox/arm_mhu_v2.c
index a0af683b83a2..0e3fa5917925 100644
--- a/drivers/mailbox/arm_mhu_v2.c
+++ b/drivers/mailbox/arm_mhu_v2.c
@@ -430,6 +430,111 @@ static const struct mhuv2_ops mhuv2_single_word_ops = {
 };
 /* ========================================================================== */
 
+/* =================== Doorbell transport protocol operations =============== */
+
+static inline int mhuv2_read_data_doorbell(struct arm_mhuv2 *mhuv2,
+					   struct mbox_chan *chan,
+					   struct arm_mbox_msg *msg)
+{
+	return 0;
+}
+
+static inline int mhuv2_clear_data_doorbell(struct arm_mhuv2 *mhuv2,
+					    struct mbox_chan *chan,
+					    struct arm_mbox_msg *msg)
+{
+	const u32 ch_mbox_idx = mhuv2_chan_idx(chan);
+	const u32 ch_window_idx = ch_mbox_idx / MHUV2_STAT_BITS;
+	const u32 ch_window_reg_idx = ch_mbox_idx % MHUV2_STAT_BITS;
+
+	writel_relaxed(BIT(ch_window_reg_idx),
+		       &mhuv2->reg.recv->channel[ch_window_idx].STAT_CLEAR);
+	return 0;
+}
+
+static inline int mhuv2_send_data_doorbell(struct arm_mhuv2 *mhuv2,
+					   struct mbox_chan *chan,
+					   const struct arm_mbox_msg *msg)
+{
+	const u32 ch_mbox_idx = mhuv2_chan_idx(chan);
+	const u32 ch_window_idx = ch_mbox_idx / MHUV2_STAT_BITS;
+	const u32 ch_window_reg_idx = ch_mbox_idx % MHUV2_STAT_BITS;
+
+	writel_relaxed(
+		readl_relaxed(&mhuv2->reg.send->channel[ch_window_idx].STAT) |
+			BIT(ch_window_reg_idx),
+		&mhuv2->reg.send->channel[ch_window_idx].STAT_SET);
+	return 0;
+}
+
+static inline int mhuv2_last_tx_done_doorbell(struct arm_mhuv2 *mhuv2,
+					      struct mbox_chan *chan)
+{
+	const u32 ch_mbox_idx = mhuv2_chan_idx(chan);
+	const u32 ch_window_idx = ch_mbox_idx / MHUV2_STAT_BITS;
+	const u32 ch_window_reg_idx = ch_mbox_idx % MHUV2_STAT_BITS;
+
+	return (readl_relaxed(&mhuv2->reg.send->channel[ch_window_idx].STAT) &
+		BIT(ch_window_reg_idx)) == 0;
+}
+
+static inline int mhuv2_setup_doorbell(struct arm_mhuv2 *mhuv2)
+{
+	int i;
+	const u32 channel_windows =
+		readl_relaxed_bitfield(mhuv2->frame == RECEIVER_FRAME ?
+					       &mhuv2->reg.recv->MHU_CFG :
+					       &mhuv2->reg.send->MHU_CFG,
+				       NUM_CH);
+
+	mhuv2->mbox.num_chans = MHUV2_STAT_BITS * channel_windows;
+	mhuv2->mbox.chans =
+		devm_kzalloc(mhuv2->dev,
+			     mhuv2->mbox.num_chans * sizeof(struct mbox_chan),
+			     GFP_KERNEL);
+
+	for (i = 0; i < mhuv2->mbox.num_chans; i++) {
+		mhuv2->mbox.chans[i].con_priv =
+			devm_kzalloc(mhuv2->dev,
+				     sizeof(struct arm_mhuv2_mbox_chan_priv),
+				     GFP_KERNEL);
+		mhuv2_chan_idx(&mhuv2->mbox.chans[i]) = i;
+	}
+
+	if (mhuv2->frame == RECEIVER_FRAME) {
+		/* Ensure all status registers are unmasked */
+		for (i = 0; i < channel_windows; i++) {
+			writel_relaxed(0x0,
+				       &mhuv2->reg.recv->channel[i].MASK_SET);
+		}
+	}
+
+	return 0;
+}
+
+static inline struct mbox_chan *
+	mhuv2_get_active_mbox_chan_doorbell(struct arm_mhuv2 *mhuv2)
+{
+	const u32 ch_window_idx = mhuv2_combint_idx(mhuv2);
+	const u32 ch_window_reg_idx = __find_set_bit(
+		readl_relaxed(&mhuv2->reg.recv->channel[ch_window_idx].STAT));
+	if (ch_window_reg_idx == -1)
+		return ERR_PTR(-EIO);
+
+	return &mhuv2->mbox.chans[ch_window_reg_idx +
+				  ch_window_idx * MHUV2_STAT_BITS];
+}
+
+static const struct mhuv2_ops mhuv2_doorbell_ops = {
+	.read_data = mhuv2_read_data_doorbell,
+	.clear_data = mhuv2_clear_data_doorbell,
+	.send_data = mhuv2_send_data_doorbell,
+	.setup = mhuv2_setup_doorbell,
+	.last_tx_done = mhuv2_last_tx_done_doorbell,
+	.get_active_mbox_chan = mhuv2_get_active_mbox_chan_doorbell,
+};
+/* ========================================================================== */
+
 /*
  * MHUv2 receiver interrupt service routine
  *
@@ -638,6 +743,9 @@ static int mhuv2_probe(struct amba_device *adev, const struct amba_id *id)
 	case SINGLE_WORD:
 		mhuv2->ops = &mhuv2_single_word_ops;
 		break;
+	case DOORBELL:
+		mhuv2->ops = &mhuv2_doorbell_ops;
+		break;
 	default:
 		return -ENODEV;
 	}
-- 
2.17.1


  parent reply	other threads:[~2019-07-17 19:26 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-17 19:26 [PATCH 0/4] Arm MHUv2 Mailbox Controller Driver Tushar Khandelwal
2019-07-17 19:26 ` [PATCH 1/4] mailbox: arm_mhuv2: add device tree binding documentation Tushar Khandelwal
2019-07-21 21:58   ` Jassi Brar
2019-07-25  5:49     ` Jassi Brar
2019-07-28 21:28       ` Morten Borup Petersen
2019-07-31  7:31         ` Jassi Brar
2019-08-02 10:41           ` Morten Borup Petersen
2019-08-13 16:36             ` Jassi Brar
2019-08-14 10:05               ` Sudeep Holla
2019-08-14 14:52                 ` Jassi Brar
2019-08-14 16:51                   ` Sudeep Holla
2019-08-14 22:22                     ` tushar.khandelwal
2019-08-14 22:20               ` tushar.khandelwal
2019-08-02 10:53       ` Sudeep Holla
2019-08-07 11:11         ` Tushar Khandelwal
2019-07-28 21:27     ` Morten Borup Petersen
2019-08-02 10:59     ` Sudeep Holla
2019-08-07 11:17       ` Tushar Khandelwal
2019-08-08 10:31         ` Morten Borup Petersen
2019-07-17 19:26 ` [PATCH 2/4] mailbox: arm_mhuv2: add arm mhuv2 driver Tushar Khandelwal
2019-07-17 19:26 ` Tushar Khandelwal [this message]
2019-07-17 19:26 ` [PATCH 4/4] mailbox: arm_mhuv2: add multi word transport protocol operations Tushar Khandelwal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190717192616.1731-4-tushar.khandelwal@arm.com \
    --to=tushar.khandelwal@arm.com \
    --cc=devicetree@vger.kernel.org \
    --cc=jassisinghbrar@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=morten.petersen@arm.com \
    --cc=morten_bp@live.dk \
    --cc=nd@arm.com \
    --cc=tushar.2nov@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).