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

Commit 4d5bce95 authored by Ankit Gupta's avatar Ankit Gupta Committed by Gerrit - the friendly Code Review server
Browse files

i2c-msm-v2: Avoid writing core registers when HW is not ready



SW reset of the qup core can take a few clock-cycles before
getting into valid state. Another register write during that time may
lead to NoC error due to core-master not being reachable by AHB, or
core may return not-ready status if clocks are gated by HW if HW
gated the clocks before SW read the register.
Once core status is valid, make sure core doesn't keep spinning by
sleeping intermittently until timeout, or valid state is reached.

Change-Id: I6bd002bf91ba2221bf8398b92c0e8206d86fe050
Signed-off-by: default avatarAnkit Gupta <ankgupta@codeaurora.org>
Signed-off-by: default avatarSagar Dharia <sdharia@codeaurora.org>
parent a5eb2c93
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
@@ -218,9 +218,6 @@ i2c_msm_qup_state_wait_valid(struct i2c_msm_ctrl *ctrl,
{
	u32 status;
	void __iomem  *base     = ctrl->rsrcs.base;
	unsigned long  start   = jiffies;
	unsigned long  timeout = start +
				 msecs_to_jiffies(I2C_MSM_MAX_POLL_MSEC);
	int ret      = 0;
	int read_cnt = 0;

@@ -242,7 +239,14 @@ i2c_msm_qup_state_wait_valid(struct i2c_msm_ctrl *ctrl,
				goto poll_valid_end;
		}

	} while (time_before_eq(jiffies, timeout));
		/*
		 * Sleeping for 1-1.5 ms for every 100 iterations and break if
		 * iterations crosses the 1500 marks allows roughly 10-15 msec
		 * of time to get the core to valid state.
		 */
		if (!(read_cnt % 100))
			usleep_range(1000, 1500);
	} while (read_cnt <= 1500);

	ret = -ETIMEDOUT;
	dev_err(ctrl->dev,
@@ -1873,9 +1877,7 @@ static void i2c_msm_qup_init(struct i2c_msm_ctrl *ctrl)
	i2c_msm_qup_sw_reset(ctrl);
	i2c_msm_qup_state_set(ctrl, QUP_STATE_RESET);

	writel_relaxed(QUP_APP_CLK_ON_EN | QUP_CORE_CLK_ON_EN | QUP_N_VAL |
				QUP_FIFO_CLK_GATE_EN | QUP_MINI_CORE_I2C_VAL,
				base + QUP_CONFIG);
	writel_relaxed(QUP_N_VAL | QUP_MINI_CORE_I2C_VAL, base + QUP_CONFIG);

	writel_relaxed(QUP_OUTPUT_OVER_RUN_ERR_EN | QUP_INPUT_UNDER_RUN_ERR_EN
		     | QUP_OUTPUT_UNDER_RUN_ERR_EN | QUP_INPUT_OVER_RUN_ERR_EN,