linux-arm-msm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
To: mhi@lists.linux.dev
Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org,
	quic_jhugo@quicinc.com, vinod.koul@linaro.org,
	bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org,
	skananth@codeaurora.org, vpernami@codeaurora.org,
	vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Subject: [PATCH 10/20] bus: mhi: ep: Add support for sending events to the host
Date: Thu,  2 Dec 2021 17:05:42 +0530	[thread overview]
Message-ID: <20211202113553.238011-11-manivannan.sadhasivam@linaro.org> (raw)
In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org>

Add support for sending the events to the host over MHI bus from the
endpoint. Following events are supported:

1. Transfer completion event
2. Command completion event
3. State change event
4. Execution Environment (EE) change event

An event is sent whenever an operation has been completed in the MHI EP
device. Event is sent using the MHI event ring and additionally the host
is notified using an IRQ if required.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 drivers/bus/mhi/ep/internal.h |   4 ++
 drivers/bus/mhi/ep/main.c     | 126 ++++++++++++++++++++++++++++++++++
 include/linux/mhi_ep.h        |   2 +
 3 files changed, 132 insertions(+)

diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h
index a7a4e6934f7d..3551e673d99a 100644
--- a/drivers/bus/mhi/ep/internal.h
+++ b/drivers/bus/mhi/ep/internal.h
@@ -214,4 +214,8 @@ void mhi_ep_mmio_get_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state *s
 void mhi_ep_mmio_init(struct mhi_ep_cntrl *mhi_cntrl);
 void mhi_ep_mmio_update_ner(struct mhi_ep_cntrl *mhi_cntrl);
 
+/* MHI EP core functions */
+int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state);
+int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ep_execenv exec_env);
+
 #endif
diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c
index 6d448d42f527..999784eadb65 100644
--- a/drivers/bus/mhi/ep/main.c
+++ b/drivers/bus/mhi/ep/main.c
@@ -18,6 +18,131 @@
 
 static DEFINE_IDA(mhi_ep_cntrl_ida);
 
+static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 event_ring,
+			     struct mhi_ep_ring_element *el)
+{
+	struct mhi_ep_ring *ring = &mhi_cntrl->mhi_event[event_ring].ring;
+	struct device *dev = &mhi_cntrl->mhi_dev->dev;
+	union mhi_ep_ring_ctx *ctx;
+	int ret;
+
+	mutex_lock(&mhi_cntrl->event_lock);
+	ctx = (union mhi_ep_ring_ctx *)&mhi_cntrl->ev_ctx_cache[event_ring];
+	if (ring->state == RING_STATE_UINT) {
+		ret = mhi_ep_ring_start(mhi_cntrl, ring, ctx);
+		if (ret) {
+			dev_err(dev, "Error starting event ring (%d)\n", event_ring);
+			goto err_unlock;
+		}
+	}
+
+	/* Add element to the primary event ring (0) */
+	ret = mhi_ep_ring_add_element(ring, el, 0);
+	if (ret) {
+		dev_err(dev, "Error adding element to event ring (%d)\n", event_ring);
+		goto err_unlock;
+	}
+
+	/* Ensure that the ring pointer gets updated in host memory before triggering IRQ */
+	wmb();
+
+	mutex_unlock(&mhi_cntrl->event_lock);
+
+	/*
+	 * Raise IRQ to host only if the BEI flag is not set in TRE. Host might
+	 * set this flag for interrupt moderation as per MHI protocol.
+	 */
+	if (!MHI_EP_TRE_GET_BEI(el))
+		mhi_cntrl->raise_irq(mhi_cntrl);
+
+	return 0;
+
+err_unlock:
+	mutex_unlock(&mhi_cntrl->event_lock);
+
+	return ret;
+}
+
+static int mhi_ep_send_completion_event(struct mhi_ep_cntrl *mhi_cntrl,
+					struct mhi_ep_ring *ring, u32 len,
+					enum mhi_ev_ccs code)
+{
+	struct mhi_ep_ring_element event = {};
+	u32 er_index, tmp;
+
+	er_index = mhi_cntrl->ch_ctx_cache[ring->ch_id].erindex;
+	event.ptr = ring->ring_ctx->generic.rbase +
+			ring->rd_offset * sizeof(struct mhi_ep_ring_element);
+
+	tmp = event.dword[0];
+	tmp |= MHI_TRE_EV_DWORD0(code, len);
+	event.dword[0] = tmp;
+
+	tmp = event.dword[1];
+	tmp |= MHI_TRE_EV_DWORD1(ring->ch_id, MHI_PKT_TYPE_TX_EVENT);
+	event.dword[1] = tmp;
+
+	return mhi_ep_send_event(mhi_cntrl, er_index, &event);
+}
+
+int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state)
+{
+	struct mhi_ep_ring_element event = {};
+	u32 tmp;
+
+	tmp = event.dword[0];
+	tmp |= MHI_SC_EV_DWORD0(state);
+	event.dword[0] = tmp;
+
+	tmp = event.dword[1];
+	tmp |= MHI_SC_EV_DWORD1(MHI_PKT_TYPE_STATE_CHANGE_EVENT);
+	event.dword[1] = tmp;
+
+	return mhi_ep_send_event(mhi_cntrl, 0, &event);
+}
+
+int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ep_execenv exec_env)
+{
+	struct mhi_ep_ring_element event = {};
+	u32 tmp;
+
+	tmp = event.dword[0];
+	tmp |= MHI_EE_EV_DWORD0(exec_env);
+	event.dword[0] = tmp;
+
+	tmp = event.dword[1];
+	tmp |= MHI_SC_EV_DWORD1(MHI_PKT_TYPE_EE_EVENT);
+	event.dword[1] = tmp;
+
+	return mhi_ep_send_event(mhi_cntrl, 0, &event);
+}
+
+static int mhi_ep_send_cmd_comp_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ev_ccs code)
+{
+	struct device *dev = &mhi_cntrl->mhi_dev->dev;
+	struct mhi_ep_ring_element event = {};
+	u32 tmp;
+
+	if (code > MHI_EV_CC_BAD_TRE) {
+		dev_err(dev, "Invalid command completion code: %d\n", code);
+		return -EINVAL;
+	}
+
+	event.ptr = mhi_cntrl->cmd_ctx_cache->rbase
+			+ (mhi_cntrl->mhi_cmd->ring.rd_offset *
+			(sizeof(struct mhi_ep_ring_element)));
+
+	tmp = event.dword[0];
+	tmp |= MHI_CC_EV_DWORD0(code);
+	event.dword[0] = tmp;
+
+	tmp = event.dword[1];
+	tmp |= MHI_CC_EV_DWORD1(MHI_PKT_TYPE_CMD_COMPLETION_EVENT);
+	event.dword[1] = tmp;
+
+	return mhi_ep_send_event(mhi_cntrl, 0, &event);
+}
+
 static void mhi_ep_ring_worker(struct work_struct *work)
 {
 	struct mhi_ep_cntrl *mhi_cntrl = container_of(work,
@@ -268,6 +393,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl,
 
 	INIT_LIST_HEAD(&mhi_cntrl->ch_db_list);
 	spin_lock_init(&mhi_cntrl->list_lock);
+	mutex_init(&mhi_cntrl->event_lock);
 
 	/* Set MHI version and AMSS EE before enumeration */
 	mhi_ep_mmio_write(mhi_cntrl, MHIVER, config->mhi_version);
diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h
index 729f4b802b74..323cd3319b13 100644
--- a/include/linux/mhi_ep.h
+++ b/include/linux/mhi_ep.h
@@ -67,6 +67,7 @@ struct mhi_ep_db_info {
  * @ch_db_list: List of queued channel doorbells
  * @st_transition_list: List of state transitions
  * @list_lock: Lock for protecting state transition and channel doorbell lists
+ * @event_lock: Lock for protecting event rings
  * @chdb: Array of channel doorbell interrupt info
  * @raise_irq: CB function for raising IRQ to the host
  * @alloc_addr: CB function for allocating memory in endpoint for storing host context
@@ -101,6 +102,7 @@ struct mhi_ep_cntrl {
 	struct list_head ch_db_list;
 	struct list_head st_transition_list;
 	spinlock_t list_lock;
+	struct mutex event_lock;
 	struct mhi_ep_db_info chdb[4];
 
 	void (*raise_irq)(struct mhi_ep_cntrl *mhi_cntrl);
-- 
2.25.1


  parent reply	other threads:[~2021-12-02 11:38 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-02 11:35 [PATCH 00/20] Add initial support for MHI endpoint stack Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 01/20] bus: mhi: Move host MHI code to "host" directory Manivannan Sadhasivam
2021-12-07  1:52   ` Hemant Kumar
2022-01-06  0:20   ` Alex Elder
2021-12-02 11:35 ` [PATCH 02/20] bus: mhi: Move common MHI definitions out of host directory Manivannan Sadhasivam
2022-01-06  0:22   ` Alex Elder
2022-02-03 10:29     ` Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 03/20] bus: mhi: Make mhi_state_str[] array static const and move to common.h Manivannan Sadhasivam
2022-01-06  0:22   ` Alex Elder
2022-02-03 10:34     ` Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 04/20] bus: mhi: Cleanup the register definitions used in headers Manivannan Sadhasivam
2022-01-06  0:23   ` Alex Elder
2022-02-03 11:26     ` Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 05/20] bus: mhi: ep: Add support for registering MHI endpoint controllers Manivannan Sadhasivam
2022-01-06  0:26   ` Alex Elder
2022-02-03 14:50     ` Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 06/20] bus: mhi: ep: Add support for registering MHI endpoint client drivers Manivannan Sadhasivam
2022-01-06  0:27   ` Alex Elder
2022-02-03 14:53     ` Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 07/20] bus: mhi: ep: Add support for creating and destroying MHI EP devices Manivannan Sadhasivam
2022-01-06  0:28   ` Alex Elder
2022-02-03 15:13     ` Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 08/20] bus: mhi: ep: Add support for managing MMIO registers Manivannan Sadhasivam
2022-01-06  0:29   ` Alex Elder
2022-02-03 15:55     ` Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 09/20] bus: mhi: ep: Add support for ring management Manivannan Sadhasivam
2022-01-06  0:30   ` Alex Elder
2022-02-04  9:21     ` Manivannan Sadhasivam
2021-12-02 11:35 ` Manivannan Sadhasivam [this message]
2021-12-02 11:35 ` [PATCH 11/20] bus: mhi: ep: Add support for managing MHI state machine Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 12/20] bus: mhi: ep: Add support for processing MHI endpoint interrupts Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 13/20] bus: mhi: ep: Add support for powering up the MHI endpoint stack Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 14/20] bus: mhi: ep: Add support for powering down " Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 15/20] bus: mhi: ep: Add support for handling MHI_RESET Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 16/20] bus: mhi: ep: Add support for handling SYS_ERR condition Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 17/20] bus: mhi: ep: Add support for processing command and TRE rings Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 18/20] bus: mhi: ep: Add support for queueing SKBs over MHI bus Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 19/20] bus: mhi: ep: Add support for suspending and resuming channels Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 20/20] bus: mhi: ep: Add uevent support for module autoloading Manivannan Sadhasivam
2022-01-06  0:20 ` [PATCH 00/20] Add initial support for MHI endpoint stack Alex Elder

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=20211202113553.238011-11-manivannan.sadhasivam@linaro.org \
    --to=manivannan.sadhasivam@linaro.org \
    --cc=bbhatt@codeaurora.org \
    --cc=bjorn.andersson@linaro.org \
    --cc=dmitry.baryshkov@linaro.org \
    --cc=hemantk@codeaurora.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhi@lists.linux.dev \
    --cc=quic_jhugo@quicinc.com \
    --cc=skananth@codeaurora.org \
    --cc=vbadigan@codeaurora.org \
    --cc=vinod.koul@linaro.org \
    --cc=vpernami@codeaurora.org \
    /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).