slim_ngd: Support REPEAT_CHANGE_VALUE user message
REPEAT_CHANGE_VALUE user message is used to transfer high amount of
messaging data efficiently.
CRs-Fixed: 503461
Change-Id: I2762ad858b27ac84597f4eaf22fc6f3d14232d76
Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c
index f858822..0f8f1dd 100644
--- a/drivers/slimbus/slim-msm-ngd.c
+++ b/drivers/slimbus/slim-msm-ngd.c
@@ -265,9 +265,13 @@
u8 txn_mt;
u16 txn_mc = txn->mc;
u8 wbuf[SLIM_MSGQ_BUF_LEN];
+ bool report_sat = false;
+ if (txn->mc == SLIM_USR_MC_REPORT_SATELLITE &&
+ txn->mt == SLIM_MSG_MT_SRC_REFERRED_USER)
+ report_sat = true;
if (!pm_runtime_enabled(dev->dev) && dev->state == MSM_CTRL_ASLEEP &&
- txn->mc != SLIM_USR_MC_REPORT_SATELLITE) {
+ report_sat == false) {
/*
* Counter-part of system-suspend when runtime-pm is not enabled
* This way, resume can be left empty and device will be put in
@@ -295,7 +299,7 @@
return 0;
}
/* If txn is tried when controller is down, wait for ADSP to boot */
- if (txn->mc != SLIM_USR_MC_REPORT_SATELLITE) {
+ if (!report_sat) {
if (dev->state == MSM_CTRL_DOWN) {
u8 mc = (u8)txn->mc;
int timeout;
@@ -358,8 +362,7 @@
}
mutex_lock(&dev->tx_lock);
- if (txn->mc != SLIM_USR_MC_REPORT_SATELLITE &&
- (dev->state != MSM_CTRL_AWAKE)) {
+ if (report_sat == false && dev->state != MSM_CTRL_AWAKE) {
dev_err(dev->dev, "controller not ready");
mutex_unlock(&dev->tx_lock);
msm_slim_put_ctrl(dev);
@@ -436,11 +439,13 @@
puc = ((u8 *)pbuf) + 2;
if (txn->rbuf)
*(puc++) = txn->tid;
- if ((txn->mt == SLIM_MSG_MT_CORE) &&
+ if (((txn->mt == SLIM_MSG_MT_CORE) &&
((txn->mc >= SLIM_MSG_MC_REQUEST_INFORMATION &&
txn->mc <= SLIM_MSG_MC_REPORT_INFORMATION) ||
(txn->mc >= SLIM_MSG_MC_REQUEST_VALUE &&
- txn->mc <= SLIM_MSG_MC_CHANGE_VALUE))) {
+ txn->mc <= SLIM_MSG_MC_CHANGE_VALUE))) ||
+ (txn->mc == SLIM_USR_MC_REPEAT_CHANGE_VALUE &&
+ txn->mt == SLIM_MSG_MT_DEST_REFERRED_USER)) {
*(puc++) = (txn->ec & 0xFF);
*(puc++) = (txn->ec >> 8)&0xFF;
}
@@ -540,11 +545,49 @@
}
ngd_xfer_err:
mutex_unlock(&dev->tx_lock);
- if (txn_mc != SLIM_USR_MC_REPORT_SATELLITE)
+ if (!report_sat)
msm_slim_put_ctrl(dev);
return ret ? ret : dev->err;
}
+static int ngd_user_msg(struct slim_controller *ctrl, u8 la, u8 mt, u8 mc,
+ struct slim_ele_access *msg, u8 *buf, u8 len)
+{
+ struct slim_msg_txn txn;
+
+ if (mt != SLIM_MSG_MT_DEST_REFERRED_USER ||
+ mc != SLIM_USR_MC_REPEAT_CHANGE_VALUE) {
+ return -EPROTONOSUPPORT;
+ }
+ if (len > SLIM_MAX_VE_SLC_BYTES ||
+ msg->start_offset > MSM_SLIM_VE_MAX_MAP_ADDR)
+ return -EINVAL;
+ if (len <= 4) {
+ txn.ec = len - 1;
+ } else if (len <= 8) {
+ if (len & 0x1)
+ return -EINVAL;
+ txn.ec = ((len >> 1) + 1);
+ } else {
+ if (len & 0x3)
+ return -EINVAL;
+ txn.ec = ((len >> 2) + 3);
+ }
+ txn.ec |= (0x8 | ((msg->start_offset & 0xF) << 4));
+ txn.ec |= ((msg->start_offset & 0xFF0) << 4);
+
+ txn.la = la;
+ txn.mt = mt;
+ txn.mc = mc;
+ txn.dt = SLIM_MSG_DEST_LOGICALADDR;
+ txn.len = len;
+ txn.rl = len + 6;
+ txn.wbuf = buf;
+ txn.rbuf = NULL;
+ txn.comp = msg->comp;
+ return ngd_xfer_msg(ctrl, &txn);
+}
+
static int ngd_xferandwait_ack(struct slim_controller *ctrl,
struct slim_msg_txn *txn)
{
@@ -1222,6 +1265,7 @@
dev->ctrl.get_laddr = ngd_get_laddr;
dev->ctrl.allocbw = ngd_allocbw;
dev->ctrl.xfer_msg = ngd_xfer_msg;
+ dev->ctrl.xfer_user_msg = ngd_user_msg;
dev->ctrl.wakeup = ngd_clk_pause_wakeup;
dev->ctrl.alloc_port = msm_alloc_port;
dev->ctrl.dealloc_port = msm_dealloc_port;