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

Commit 3f425901 authored by Sagar Dharia's avatar Sagar Dharia
Browse files

slim: msm: Handle slimbus HW noise during early boot-up



Capability exchange may timeout during boot due to noise on slimbus
lines. Introduce retry mechanism to recover from this state. If the
HW noise happens just after capability exchange is successful, make
sure slimbus satellite HW powered on again by checking HW status
during message transfer.

Change-Id: I6ebf0ec78201551152bf6ac0d4372f36734a4708
Signed-off-by: default avatarSagar Dharia <sdharia@codeaurora.org>
parent cc957303
Loading
Loading
Loading
Loading
+60 −10
Original line number Diff line number Diff line
@@ -299,6 +299,26 @@ static void slim_reinit_tx_msgq(struct msm_slim_ctrl *dev)
	}
}

static int ngd_check_hw_status(struct msm_slim_ctrl *dev)
{
	void __iomem *ngd = dev->base + NGD_BASE(dev->ctrl.nr, dev->ver);
	u32 laddr = readl_relaxed(ngd + NGD_STATUS);
	int ret = 0;

	/* Lost logical addr due to noise */
	if (!(laddr & NGD_LADDR)) {
		SLIM_WARN(dev, "NGD lost LADDR: status:0x%x\n", laddr);
		ret = ngd_slim_power_up(dev, false);

		if (ret) {
			SLIM_WARN(dev, "slim resume ret:%d, state:%d\n",
					ret, dev->state);
			ret = -EREMOTEIO;
		}
	}
	return ret;
}

static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn)
{
	DECLARE_COMPLETION_ONSTACK(done);
@@ -351,7 +371,6 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn)

	/* If txn is tried when controller is down, wait for ADSP to boot */
	if (!report_sat) {

		if (dev->state == MSM_CTRL_DOWN) {
			u8 mc = (u8)txn->mc;
			int timeout;
@@ -418,6 +437,12 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn)
			msm_slim_put_ctrl(dev);
			return -EREMOTEIO;
		}
		ret = ngd_check_hw_status(dev);
		if (ret) {
			mutex_unlock(&dev->tx_lock);
			msm_slim_put_ctrl(dev);
			return ret;
		}
	}

	if (txn->mt == SLIM_MSG_MT_CORE &&
@@ -737,6 +762,14 @@ static int ngd_bulk_wr(struct slim_controller *ctrl, u8 la, u8 mt, u8 mc,
		}
		mutex_lock(&dev->tx_lock);
	}

	ret = ngd_check_hw_status(dev);
	if (ret) {
		mutex_unlock(&dev->tx_lock);
		msm_slim_put_ctrl(dev);
		return ret;
	}

	if (dev->use_tx_msgqs != MSM_MSGQ_ENABLED) {
		SLIM_WARN(dev, "bulk wr not supported");
		ret = -EPROTONOSUPPORT;
@@ -1080,7 +1113,7 @@ static void ngd_slim_setup(struct msm_slim_ctrl *dev)
		if (dev->use_rx_msgqs == MSM_MSGQ_DISABLED)
			goto setup_tx_msg_path;
		if (cfg & NGD_CFG_RX_MSGQ_EN) {
			SLIM_WARN(dev, "RX msgq status HW:0x%x, SW:%d:", cfg,
			SLIM_WARN(dev, "SLIM NGD CFG HW:0x%x, SW:%d:", cfg,
				  dev->use_rx_msgqs);
			goto setup_tx_msg_path;
		}
@@ -1188,7 +1221,7 @@ static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf)
static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart)
{
	void __iomem *ngd;
	int timeout, ret = 0;
	int timeout, retries = 0, ret = 0;
	enum msm_ctrl_state cur_state = dev->state;
	u32 laddr;
	u32 rx_msgq;
@@ -1206,16 +1239,24 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart)
		}
	}

hw_init_retry:
	/* No need to vote if contorller is not in low power mode */
	if (!mdm_restart &&
		(cur_state == MSM_CTRL_DOWN || cur_state == MSM_CTRL_ASLEEP)) {
		ret = msm_slim_qmi_power_request(dev, true);
		if (ret) {
			SLIM_ERR(dev, "SLIM QMI power request failed:%d\n",
					ret);
			SLIM_WARN(dev, "SLIM power req failed:%d, retry:%d\n",
					ret, retries);
			msm_slim_qmi_power_request(dev, false);
			if (retries < INIT_MX_RETRIES) {
				retries++;
				goto hw_init_retry;
			}
			return ret;
		}
	}
	retries = 0;

	if (!dev->ver) {
		dev->ver = readl_relaxed(dev->base);
		/* Version info in 16 MSbits */
@@ -1254,6 +1295,7 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart)
		dev->state = MSM_CTRL_DOWN;
	}

capability_retry:
	/*
	 * ADSP power collapse case (OR SSR), where HW was reset
	 * BAM programming will happen when capability message is received
@@ -1274,7 +1316,16 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart)

	timeout = wait_for_completion_timeout(&dev->reconf, HZ);
	if (!timeout) {
		SLIM_WARN(dev, "capability exchange timed-out\n");
		u32 cfg = readl_relaxed(dev->base +
					 NGD_BASE(dev->ctrl.nr, dev->ver));
		laddr = readl_relaxed(ngd + NGD_STATUS);
		SLIM_WARN(dev,
			  "slim capability time-out:%d, stat:0x%x,cfg:0x%x\n",
				retries, laddr, cfg);
		if (retries < INIT_MX_RETRIES) {
			retries++;
			goto capability_retry;
		}
		return -ETIMEDOUT;
	}
	/* mutliple transactions waiting on slimbus to power up? */
@@ -1366,12 +1417,11 @@ capability_retry:

			SLIM_INFO(dev,
				"SLIM SAT: capability exchange successful\n");
			if (prev_state >= MSM_CTRL_ASLEEP)
				complete(&dev->reconf);
			else
			if (prev_state < MSM_CTRL_ASLEEP)
				SLIM_WARN(dev,
					"SLIM: unexpected capability, state:%d\n",
					"capability due to noise, state:%d\n",
						prev_state);
			complete(&dev->reconf);
			/* ADSP SSR, send device_up notifications */
			if (prev_state == MSM_CTRL_DOWN)
				complete(&dev->qmi.slave_notify);
+1 −1
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@
#define SLIM_MSG_ASM_FIRST_WORD(l, mt, mc, dt, ad) \
		((l) | ((mt) << 5) | ((mc) << 8) | ((dt) << 15) | ((ad) << 16))

#define INIT_MX_RETRIES 10
#define INIT_MX_RETRIES 3
#define DEF_RETRY_MS	10
#define MSM_CONCUR_MSG	8
#define SAT_CONCUR_MSG	8