Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f4f9ed6 authored by Sujeev Dias's avatar Sujeev Dias Committed by Gerrit - the friendly Code Review server
Browse files

mhi: core: separate event processing based on ev type



As an optimization, have dedicated event processing
algorithm based on type of event ring.

CRs-Fixed: 2246114
Change-Id: I5bdb155a8b24ddc5ba62ac31630f0fbb30632c5d
Signed-off-by: default avatarSujeev Dias <sdias@codeaurora.org>
parent 49dc104d
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -132,6 +132,14 @@ mhi event node properties:
		2 = burst mode disabled
		3 = burst mode enabled

- mhi,data-type
  Usage: optional
  Value type: <u32>
  Definition: Type of data this event ring will process as defined
	by enum mhi_er_data_type
		0 = process data packets (default)
		1 = process mhi control packets

- mhi,hw-ev
  Usage: optional
  Value type: <bool>
@@ -147,10 +155,6 @@ mhi event node properties:
  Value type: <bool>
  Definition: Event ring associated with offload channel

- mhi,ctrl-ev
  Usage: optional
  Value type: <bool>
  Definition: Event ring dedicated to control events only

Children node properties:

@@ -177,7 +181,7 @@ mhi_controller {
		mhi,chan = <0>;
		mhi,priority = <1>;
		mhi,bstmode = <2>;
		mhi,ctrl-ev;
		mhi,data-type = <1>;
	};

	mhi_event@1 {
+1 −1
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@
			mhi,msi = <1>;
			mhi,priority = <1>;
			mhi,brstmode = <2>;
			mhi,ctrl-ev;
			mhi,data-type = <1>;
		};

		mhi_event@1 {
+18 −4
Original line number Diff line number Diff line
@@ -734,6 +734,23 @@ static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl,
			(mhi_event->db_cfg.brstmode == MHI_BRSTMODE_ENABLE) ?
			mhi_db_brstmode : mhi_db_brstmode_disable;

		ret = of_property_read_u32(child, "mhi,data-type",
					   &mhi_event->data_type);
		if (ret)
			mhi_event->data_type = MHI_ER_DATA_ELEMENT_TYPE;

		if (mhi_event->data_type > MHI_ER_DATA_TYPE_MAX)
			goto error_ev_cfg;

		switch (mhi_event->data_type) {
		case MHI_ER_DATA_ELEMENT_TYPE:
			mhi_event->process_event = mhi_process_data_event_ring;
			break;
		case MHI_ER_CTRL_ELEMENT_TYPE:
			mhi_event->process_event = mhi_process_ctrl_ev_ring;
			break;
		}

		mhi_event->hw_ring = of_property_read_bool(child, "mhi,hw-ev");
		if (mhi_event->hw_ring)
			mhi_cntrl->hw_ev_rings++;
@@ -743,9 +760,6 @@ static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl,
							"mhi,client-manage");
		mhi_event->offload_ev = of_property_read_bool(child,
							      "mhi,offload");
		mhi_event->ctrl_ev = of_property_read_bool(child,
							   "mhi,ctrl-ev");

		mhi_event++;
	}

@@ -987,7 +1001,7 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl)

		mhi_event->mhi_cntrl = mhi_cntrl;
		spin_lock_init(&mhi_event->lock);
		if (mhi_event->ctrl_ev)
		if (mhi_event->data_type == MHI_ER_CTRL_ELEMENT_TYPE)
			tasklet_init(&mhi_event->task, mhi_ctrl_ev_task,
				     (ulong)mhi_event);
		else
+14 −1
Original line number Diff line number Diff line
@@ -452,6 +452,12 @@ enum MHI_ER_TYPE {
	MHI_ER_TYPE_VALID = 0x1,
};

enum mhi_er_data_type {
	MHI_ER_DATA_ELEMENT_TYPE,
	MHI_ER_CTRL_ELEMENT_TYPE,
	MHI_ER_DATA_TYPE_MAX = MHI_ER_CTRL_ELEMENT_TYPE,
};

struct db_cfg {
	bool reset_req;
	bool db_mode;
@@ -517,15 +523,18 @@ struct mhi_event {
	u32 msi;
	int chan; /* this event ring is dedicated to a channel */
	u32 priority;
	enum mhi_er_data_type data_type;
	struct mhi_ring ring;
	struct db_cfg db_cfg;
	bool hw_ring;
	bool cl_manage;
	bool offload_ev; /* managed by a device driver */
	bool ctrl_ev;
	spinlock_t lock;
	struct mhi_chan *mhi_chan; /* dedicated to channel */
	struct tasklet_struct task;
	int (*process_event)(struct mhi_controller *mhi_cntrl,
			     struct mhi_event *mhi_event,
			     u32 event_quota);
	struct mhi_controller *mhi_cntrl;
};

@@ -607,6 +616,10 @@ int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl);
void mhi_pm_m1_transition(struct mhi_controller *mhi_cntrl);
int mhi_pm_m3_transition(struct mhi_controller *mhi_cntrl);
void mhi_notify(struct mhi_device *mhi_dev, enum MHI_CB cb_reason);
int mhi_process_data_event_ring(struct mhi_controller *mhi_cntrl,
				struct mhi_event *mhi_event, u32 event_quota);
int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl,
			     struct mhi_event *mhi_event, u32 event_quota);

/* queue transfer buffer */
int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan,
+64 −25
Original line number Diff line number Diff line
@@ -706,7 +706,7 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl,
	return 0;
}

static int mhi_process_event_ring(struct mhi_controller *mhi_cntrl,
int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl,
			     struct mhi_event *mhi_event,
			     u32 event_quota)
{
@@ -723,31 +723,18 @@ static int mhi_process_event_ring(struct mhi_controller *mhi_cntrl,
		read_unlock_bh(&mhi_cntrl->pm_lock);
		return -EIO;
	}

	mhi_cntrl->wake_get(mhi_cntrl, false);
	read_unlock_bh(&mhi_cntrl->pm_lock);

	dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp);
	local_rp = ev_ring->rp;

	while (dev_rp != local_rp && event_quota > 0) {
	while (dev_rp != local_rp) {
		enum MHI_PKT_TYPE type = MHI_TRE_GET_EV_TYPE(local_rp);

		MHI_VERB("Processing Event:0x%llx 0x%08x 0x%08x\n",
			local_rp->ptr, local_rp->dword[0], local_rp->dword[1]);

		switch (type) {
		case MHI_PKT_TYPE_TX_EVENT:
		{
			u32 chan;
			struct mhi_chan *mhi_chan;

			chan = MHI_TRE_GET_EV_CHID(local_rp);
			mhi_chan = &mhi_cntrl->mhi_chan[chan];
			parse_xfer_event(mhi_cntrl, local_rp, mhi_chan);
			event_quota--;
			break;
		}
		case MHI_PKT_TYPE_STATE_CHANGE_EVENT:
		{
			enum MHI_STATE new_state;
@@ -848,12 +835,8 @@ static int mhi_process_event_ring(struct mhi_controller *mhi_cntrl,

			break;
		}
		case MHI_PKT_TYPE_STALE_EVENT:
			MHI_VERB("Stale Event received for chan:%u\n",
				 MHI_TRE_GET_EV_CHID(local_rp));
			break;
		default:
			MHI_ERR("Unsupported packet type code 0x%x\n", type);
			MHI_ASSERT(1, "Unsupported ev type");
			break;
		}

@@ -862,6 +845,61 @@ static int mhi_process_event_ring(struct mhi_controller *mhi_cntrl,
		dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp);
		count++;
	}

	read_lock_bh(&mhi_cntrl->pm_lock);
	if (likely(MHI_DB_ACCESS_VALID(mhi_cntrl->pm_state)))
		mhi_ring_er_db(mhi_event);
	read_unlock_bh(&mhi_cntrl->pm_lock);

	MHI_VERB("exit er_index:%u\n", mhi_event->er_index);

	return count;
}

int mhi_process_data_event_ring(struct mhi_controller *mhi_cntrl,
				struct mhi_event *mhi_event,
				u32 event_quota)
{
	struct mhi_tre *dev_rp, *local_rp;
	struct mhi_ring *ev_ring = &mhi_event->ring;
	struct mhi_event_ctxt *er_ctxt =
		&mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index];
	int count = 0;
	u32 chan;
	struct mhi_chan *mhi_chan;

	read_lock_bh(&mhi_cntrl->pm_lock);
	if (unlikely(MHI_EVENT_ACCESS_INVALID(mhi_cntrl->pm_state))) {
		MHI_ERR("No EV access, PM_STATE:%s\n",
			to_mhi_pm_state_str(mhi_cntrl->pm_state));
		read_unlock_bh(&mhi_cntrl->pm_lock);
		return -EIO;
	}

	mhi_cntrl->wake_get(mhi_cntrl, false);
	read_unlock_bh(&mhi_cntrl->pm_lock);

	dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp);
	local_rp = ev_ring->rp;

	while (dev_rp != local_rp && event_quota > 0) {
		enum MHI_PKT_TYPE type = MHI_TRE_GET_EV_TYPE(local_rp);

		MHI_VERB("Processing Event:0x%llx 0x%08x 0x%08x\n",
			local_rp->ptr, local_rp->dword[0], local_rp->dword[1]);

		if (likely(type == MHI_PKT_TYPE_TX_EVENT)) {
			chan = MHI_TRE_GET_EV_CHID(local_rp);
			mhi_chan = &mhi_cntrl->mhi_chan[chan];
			parse_xfer_event(mhi_cntrl, local_rp, mhi_chan);
			event_quota--;
		}

		mhi_recycle_ev_ring_element(mhi_cntrl, ev_ring);
		local_rp = ev_ring->rp;
		dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp);
		count++;
	}
	read_lock_bh(&mhi_cntrl->pm_lock);
	if (likely(MHI_DB_ACCESS_VALID(mhi_cntrl->pm_state)))
		mhi_ring_er_db(mhi_event);
@@ -869,6 +907,7 @@ static int mhi_process_event_ring(struct mhi_controller *mhi_cntrl,
	read_unlock_bh(&mhi_cntrl->pm_lock);

	MHI_VERB("exit er_index:%u\n", mhi_event->er_index);

	return count;
}

@@ -881,7 +920,7 @@ void mhi_ev_task(unsigned long data)

	/* process all pending events */
	spin_lock_bh(&mhi_event->lock);
	mhi_process_event_ring(mhi_cntrl, mhi_event, U32_MAX);
	mhi_event->process_event(mhi_cntrl, mhi_event, U32_MAX);
	spin_unlock_bh(&mhi_event->lock);
}

@@ -896,7 +935,7 @@ void mhi_ctrl_ev_task(unsigned long data)
	MHI_VERB("Enter for ev_index:%d\n", mhi_event->er_index);

	/* process ctrl events events */
	ret = mhi_process_event_ring(mhi_cntrl, mhi_event, U32_MAX);
	ret = mhi_event->process_event(mhi_cntrl, mhi_event, U32_MAX);

	/*
	 * we received a MSI but no events to process maybe device went to
@@ -1471,7 +1510,7 @@ int mhi_poll(struct mhi_device *mhi_dev,
	int ret;

	spin_lock_bh(&mhi_event->lock);
	ret = mhi_process_event_ring(mhi_cntrl, mhi_event, budget);
	ret = mhi_event->process_event(mhi_cntrl, mhi_event, budget);
	spin_unlock_bh(&mhi_event->lock);

	return ret;