diff options
| -rw-r--r-- | drivers/slimbus/slim-msm-ngd.c | 69 | ||||
| -rw-r--r-- | drivers/slimbus/slim-msm.h | 2 |
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 |
