summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/slimbus/slim-msm-ngd.c69
-rw-r--r--drivers/slimbus/slim-msm.h2
2 files changed, 61 insertions, 10 deletions
diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c
index 98fce5e5c06a..2e6672326a77 100644
--- a/drivers/slimbus/slim-msm-ngd.c
+++ b/drivers/slimbus/slim-msm-ngd.c
@@ -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,6 +1113,7 @@ static void ngd_slim_setup(struct msm_slim_ctrl *dev)
} else {
if (dev->use_rx_msgqs == MSM_MSGQ_DISABLED)
goto setup_tx_msg_path;
+
if ((dev->use_rx_msgqs == MSM_MSGQ_ENABLED) &&
(cfg & NGD_CFG_RX_MSGQ_EN))
goto setup_tx_msg_path;
@@ -1185,7 +1219,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;
@@ -1203,16 +1237,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 */
@@ -1276,6 +1318,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
@@ -1296,7 +1339,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? */
@@ -1388,12 +1440,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);
diff --git a/drivers/slimbus/slim-msm.h b/drivers/slimbus/slim-msm.h
index 7859d1e79e39..fc0a8d23f573 100644
--- a/drivers/slimbus/slim-msm.h
+++ b/drivers/slimbus/slim-msm.h
@@ -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