Merge "slim_msm: Optimize RX path for slimbus"
This commit is contained in:
commit
369dfc05f2
|
@ -81,6 +81,7 @@ enum ngd_status {
|
|||
NGD_LADDR = 1 << 1,
|
||||
};
|
||||
|
||||
static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf);
|
||||
static int ngd_slim_runtime_resume(struct device *device);
|
||||
static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart);
|
||||
|
||||
|
@ -124,7 +125,7 @@ static irqreturn_t ngd_slim_interrupt(int irq, void *d)
|
|||
(4 * i));
|
||||
SLIM_DBG(dev, "REG-RX data: %x\n", rx_buf[i]);
|
||||
}
|
||||
msm_slim_rx_enqueue(dev, rx_buf, len);
|
||||
ngd_slim_rx(dev, (u8 *)rx_buf);
|
||||
writel_relaxed(NGD_INT_RX_MSG_RCVD,
|
||||
ngd + NGD_INT_CLR);
|
||||
/*
|
||||
|
@ -134,8 +135,6 @@ static irqreturn_t ngd_slim_interrupt(int irq, void *d)
|
|||
mb();
|
||||
if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
|
||||
SLIM_WARN(dev, "direct msg rcvd with RX MSGQs\n");
|
||||
else
|
||||
complete(&dev->rx_msgq_notify);
|
||||
}
|
||||
if (stat & NGD_INT_RECFG_DONE) {
|
||||
writel_relaxed(NGD_INT_RECFG_DONE, ngd + NGD_INT_CLR);
|
||||
|
@ -590,7 +589,7 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn)
|
|||
SPS_BAM_PIPE(4), 0, 2);
|
||||
msm_slim_disconnect_endp(dev, &dev->tx_msgq,
|
||||
&dev->use_tx_msgqs);
|
||||
msm_slim_connect_endp(dev, &dev->tx_msgq, NULL);
|
||||
msm_slim_connect_endp(dev, &dev->tx_msgq);
|
||||
}
|
||||
} else if (!timeout) {
|
||||
ret = -ETIMEDOUT;
|
||||
|
@ -1044,8 +1043,7 @@ static void ngd_slim_setup_msg_path(struct msm_slim_ctrl *dev)
|
|||
SLIM_WARN(dev, "pipe setup when RX msgq enabled?");
|
||||
goto setup_tx_msg_path;
|
||||
}
|
||||
msm_slim_connect_endp(dev, &dev->rx_msgq,
|
||||
&dev->rx_msgq_notify);
|
||||
msm_slim_connect_endp(dev, &dev->rx_msgq);
|
||||
|
||||
setup_tx_msg_path:
|
||||
if (dev->use_tx_msgqs == MSM_MSGQ_DISABLED)
|
||||
|
@ -1054,74 +1052,21 @@ setup_tx_msg_path:
|
|||
SLIM_WARN(dev, "pipe setup when TX msgq enabled?");
|
||||
return;
|
||||
}
|
||||
msm_slim_connect_endp(dev, &dev->tx_msgq,
|
||||
NULL);
|
||||
msm_slim_connect_endp(dev, &dev->tx_msgq);
|
||||
}
|
||||
}
|
||||
|
||||
static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf)
|
||||
{
|
||||
u8 mc, mt, len;
|
||||
int ret;
|
||||
u32 msgq_en = 1;
|
||||
|
||||
len = buf[0] & 0x1F;
|
||||
mt = (buf[0] >> 5) & 0x7;
|
||||
mc = buf[1];
|
||||
if (mc == SLIM_USR_MC_MASTER_CAPABILITY &&
|
||||
mt == SLIM_MSG_MT_SRC_REFERRED_USER) {
|
||||
struct slim_msg_txn txn;
|
||||
int retries = 0;
|
||||
u8 wbuf[8];
|
||||
txn.dt = SLIM_MSG_DEST_LOGICALADDR;
|
||||
txn.ec = 0;
|
||||
txn.rbuf = NULL;
|
||||
txn.mc = SLIM_USR_MC_REPORT_SATELLITE;
|
||||
txn.mt = SLIM_MSG_MT_SRC_REFERRED_USER;
|
||||
txn.la = SLIM_LA_MGR;
|
||||
wbuf[0] = SAT_MAGIC_LSB;
|
||||
wbuf[1] = SAT_MAGIC_MSB;
|
||||
wbuf[2] = SAT_MSG_VER;
|
||||
wbuf[3] = SAT_MSG_PROT;
|
||||
txn.wbuf = wbuf;
|
||||
txn.len = 4;
|
||||
SLIM_INFO(dev, "SLIM SAT: Rcvd master capability\n");
|
||||
if (dev->state >= MSM_CTRL_ASLEEP) {
|
||||
ngd_slim_setup_msg_path(dev);
|
||||
if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
|
||||
msgq_en |= NGD_CFG_RX_MSGQ_EN;
|
||||
if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED)
|
||||
msgq_en |= NGD_CFG_TX_MSGQ_EN;
|
||||
writel_relaxed(msgq_en, dev->base +
|
||||
NGD_BASE(dev->ctrl.nr, dev->ver));
|
||||
/* make sure NGD MSG-Q config goes through */
|
||||
mb();
|
||||
}
|
||||
capability_retry:
|
||||
txn.rl = 8;
|
||||
ret = ngd_xfer_msg(&dev->ctrl, &txn);
|
||||
if (!ret) {
|
||||
enum msm_ctrl_state prev_state = dev->state;
|
||||
SLIM_INFO(dev,
|
||||
"SLIM SAT: capability exchange successful\n");
|
||||
if (prev_state >= MSM_CTRL_ASLEEP)
|
||||
complete(&dev->reconf);
|
||||
else
|
||||
SLIM_ERR(dev,
|
||||
"SLIM: unexpected capability, state:%d\n",
|
||||
prev_state);
|
||||
/* ADSP SSR, send device_up notifications */
|
||||
if (prev_state == MSM_CTRL_DOWN)
|
||||
complete(&dev->qmi.slave_notify);
|
||||
} else if (ret == -EIO) {
|
||||
SLIM_WARN(dev, "capability message NACKed, retrying\n");
|
||||
if (retries < INIT_MX_RETRIES) {
|
||||
msleep(DEF_RETRY_MS);
|
||||
retries++;
|
||||
goto capability_retry;
|
||||
}
|
||||
}
|
||||
}
|
||||
mt == SLIM_MSG_MT_SRC_REFERRED_USER)
|
||||
complete(&dev->rx_msgq_notify);
|
||||
|
||||
if (mc == SLIM_MSG_MC_REPLY_INFORMATION ||
|
||||
mc == SLIM_MSG_MC_REPLY_VALUE) {
|
||||
u8 tid = buf[3];
|
||||
|
@ -1328,43 +1273,66 @@ static int ngd_slim_rx_msgq_thread(void *data)
|
|||
{
|
||||
struct msm_slim_ctrl *dev = (struct msm_slim_ctrl *)data;
|
||||
struct completion *notify = &dev->rx_msgq_notify;
|
||||
int ret = 0, index = 0;
|
||||
u32 mc = 0;
|
||||
u32 mt = 0;
|
||||
u32 buffer[10];
|
||||
u8 msg_len = 0;
|
||||
int ret = 0;
|
||||
u32 msgq_en = 1;
|
||||
|
||||
while (!kthread_should_stop()) {
|
||||
struct slim_msg_txn txn;
|
||||
int retries = 0;
|
||||
u8 wbuf[8];
|
||||
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
wait_for_completion(notify);
|
||||
/* 1 irq notification per message */
|
||||
if (dev->use_rx_msgqs != MSM_MSGQ_ENABLED) {
|
||||
msm_slim_rx_dequeue(dev, (u8 *)buffer);
|
||||
ngd_slim_rx(dev, (u8 *)buffer);
|
||||
continue;
|
||||
}
|
||||
do {
|
||||
ret = msm_slim_rx_msgq_get(dev, buffer, index);
|
||||
if (ret) {
|
||||
SLIM_ERR(dev, "rx_msgq_get() failed 0x%x\n",
|
||||
ret);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Traverse first byte of message for message length */
|
||||
if (index++ == 0) {
|
||||
msg_len = *buffer & 0x1F;
|
||||
mt = (buffer[0] >> 5) & 0x7;
|
||||
mc = (buffer[0] >> 8) & 0xff;
|
||||
dev_dbg(dev->dev, "MC: %x, MT: %x\n", mc, mt);
|
||||
}
|
||||
msg_len = (msg_len < 4) ? 0 : (msg_len - 4);
|
||||
} while (msg_len);
|
||||
if (!msg_len) {
|
||||
index = 0;
|
||||
ngd_slim_rx(dev, (u8 *)buffer);
|
||||
txn.dt = SLIM_MSG_DEST_LOGICALADDR;
|
||||
txn.ec = 0;
|
||||
txn.rbuf = NULL;
|
||||
txn.mc = SLIM_USR_MC_REPORT_SATELLITE;
|
||||
txn.mt = SLIM_MSG_MT_SRC_REFERRED_USER;
|
||||
txn.la = SLIM_LA_MGR;
|
||||
wbuf[0] = SAT_MAGIC_LSB;
|
||||
wbuf[1] = SAT_MAGIC_MSB;
|
||||
wbuf[2] = SAT_MSG_VER;
|
||||
wbuf[3] = SAT_MSG_PROT;
|
||||
txn.wbuf = wbuf;
|
||||
txn.len = 4;
|
||||
SLIM_INFO(dev, "SLIM SAT: Rcvd master capability\n");
|
||||
if (dev->state >= MSM_CTRL_ASLEEP) {
|
||||
ngd_slim_setup_msg_path(dev);
|
||||
if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
|
||||
msgq_en |= NGD_CFG_RX_MSGQ_EN;
|
||||
if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED)
|
||||
msgq_en |= NGD_CFG_TX_MSGQ_EN;
|
||||
writel_relaxed(msgq_en, dev->base +
|
||||
NGD_BASE(dev->ctrl.nr, dev->ver));
|
||||
/* make sure NGD MSG-Q config goes through */
|
||||
mb();
|
||||
}
|
||||
capability_retry:
|
||||
txn.rl = 8;
|
||||
ret = ngd_xfer_msg(&dev->ctrl, &txn);
|
||||
if (!ret) {
|
||||
enum msm_ctrl_state prev_state = dev->state;
|
||||
|
||||
SLIM_INFO(dev,
|
||||
"SLIM SAT: capability exchange successful\n");
|
||||
if (prev_state >= MSM_CTRL_ASLEEP)
|
||||
complete(&dev->reconf);
|
||||
else
|
||||
SLIM_ERR(dev,
|
||||
"SLIM: unexpected capability, state:%d\n",
|
||||
prev_state);
|
||||
/* ADSP SSR, send device_up notifications */
|
||||
if (prev_state == MSM_CTRL_DOWN)
|
||||
complete(&dev->qmi.slave_notify);
|
||||
} else if (ret == -EIO) {
|
||||
SLIM_WARN(dev, "capability message NACKed, retrying\n");
|
||||
if (retries < INIT_MX_RETRIES) {
|
||||
msleep(DEF_RETRY_MS);
|
||||
retries++;
|
||||
goto capability_retry;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1595,6 +1563,7 @@ static int ngd_slim_probe(struct platform_device *pdev)
|
|||
dev->ctrl.port_xfer = msm_slim_port_xfer;
|
||||
dev->ctrl.port_xfer_status = msm_slim_port_xfer_status;
|
||||
dev->bam_mem = bam_mem;
|
||||
dev->rx_slim = ngd_slim_rx;
|
||||
|
||||
init_completion(&dev->reconf);
|
||||
init_completion(&dev->ctrl_up);
|
||||
|
|
|
@ -672,33 +672,55 @@ u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len,
|
|||
static void
|
||||
msm_slim_rx_msgq_event(struct msm_slim_ctrl *dev, struct sps_event_notify *ev)
|
||||
{
|
||||
u32 *buf = ev->data.transfer.user;
|
||||
struct sps_iovec *iovec = &ev->data.transfer.iovec;
|
||||
|
||||
/*
|
||||
* Note the virtual address needs to be offset by the same index
|
||||
* as the physical address or just pass in the actual virtual address
|
||||
* if the sps_mem_buffer is not needed. Note that if completion is
|
||||
* used, the virtual address won't be available and will need to be
|
||||
* calculated based on the offset of the physical address
|
||||
*/
|
||||
if (ev->event_id == SPS_EVENT_DESC_DONE) {
|
||||
|
||||
pr_debug("buf = 0x%p, data = 0x%x\n", buf, *buf);
|
||||
|
||||
pr_debug("iovec = (0x%x 0x%x 0x%x)\n",
|
||||
iovec->addr, iovec->size, iovec->flags);
|
||||
|
||||
} else {
|
||||
if (ev->event_id == SPS_EVENT_DESC_DONE)
|
||||
complete(&dev->rx_msgq_notify);
|
||||
else
|
||||
dev_err(dev->dev, "%s: unknown event %d\n",
|
||||
__func__, ev->event_id);
|
||||
}
|
||||
|
||||
static void
|
||||
msm_slim_handle_rx(struct msm_slim_ctrl *dev, struct sps_event_notify *ev)
|
||||
{
|
||||
int ret = 0, index = 0;
|
||||
u32 mc = 0;
|
||||
u32 mt = 0;
|
||||
u32 buffer[10];
|
||||
u8 msg_len = 0;
|
||||
|
||||
if (ev->event_id != SPS_EVENT_EOT) {
|
||||
dev_err(dev->dev, "%s: unknown event %d\n",
|
||||
__func__, ev->event_id);
|
||||
return;
|
||||
}
|
||||
do {
|
||||
ret = msm_slim_rx_msgq_get(dev, buffer, index);
|
||||
if (ret) {
|
||||
SLIM_ERR(dev, "rx_msgq_get() failed 0x%x\n",
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Traverse first byte of message for message length */
|
||||
if (index++ == 0) {
|
||||
msg_len = *buffer & 0x1F;
|
||||
mt = (buffer[0] >> 5) & 0x7;
|
||||
mc = (buffer[0] >> 8) & 0xff;
|
||||
dev_dbg(dev->dev, "MC: %x, MT: %x\n", mc, mt);
|
||||
}
|
||||
msg_len = (msg_len < 4) ? 0 : (msg_len - 4);
|
||||
} while (msg_len);
|
||||
dev->rx_slim(dev, (u8 *)buffer);
|
||||
}
|
||||
|
||||
static void msm_slim_rx_msgq_cb(struct sps_event_notify *notify)
|
||||
{
|
||||
struct msm_slim_ctrl *dev = (struct msm_slim_ctrl *)notify->user;
|
||||
msm_slim_rx_msgq_event(dev, notify);
|
||||
/* is this manager controller or NGD controller? */
|
||||
if (dev->ctrl.wakeup)
|
||||
msm_slim_rx_msgq_event(dev, notify);
|
||||
else
|
||||
msm_slim_handle_rx(dev, notify);
|
||||
}
|
||||
|
||||
/* Queue up Rx message buffer */
|
||||
|
@ -713,8 +735,6 @@ static int msm_slim_post_rx_msgq(struct msm_slim_ctrl *dev, int ix)
|
|||
u8 *virt_addr = mem->base + (4 * ix);
|
||||
phys_addr_t phys_addr = mem->phys_base + (4 * ix);
|
||||
|
||||
pr_debug("index:%d, virt:0x%p\n", ix, virt_addr);
|
||||
|
||||
ret = sps_transfer_one(pipe, phys_addr, 4, virt_addr, 0);
|
||||
if (ret)
|
||||
dev_err(dev->dev, "transfer_one() failed 0x%x, %d\n", ret, ix);
|
||||
|
@ -758,8 +778,7 @@ err_exit:
|
|||
}
|
||||
|
||||
int msm_slim_connect_endp(struct msm_slim_ctrl *dev,
|
||||
struct msm_slim_endp *endpoint,
|
||||
struct completion *notify)
|
||||
struct msm_slim_endp *endpoint)
|
||||
{
|
||||
int i, ret;
|
||||
struct sps_register_event sps_error_event; /* SPS_ERROR */
|
||||
|
@ -775,11 +794,12 @@ int msm_slim_connect_endp(struct msm_slim_ctrl *dev,
|
|||
|
||||
memset(&sps_descr_event, 0x00, sizeof(sps_descr_event));
|
||||
|
||||
if (notify) {
|
||||
if (endpoint == &dev->rx_msgq) {
|
||||
sps_descr_event.mode = SPS_TRIGGER_CALLBACK;
|
||||
sps_descr_event.options = SPS_O_EOT;
|
||||
sps_descr_event.user = (void *)dev;
|
||||
sps_descr_event.xfer_done = notify;
|
||||
sps_descr_event.callback = msm_slim_rx_msgq_cb;
|
||||
sps_descr_event.xfer_done = NULL;
|
||||
|
||||
ret = sps_register_event(endpoint->sps, &sps_descr_event);
|
||||
if (ret) {
|
||||
|
@ -883,7 +903,7 @@ static int msm_slim_init_rx_msgq(struct msm_slim_ctrl *dev, u32 pipe_reg)
|
|||
goto alloc_buffer_failed;
|
||||
}
|
||||
|
||||
ret = msm_slim_connect_endp(dev, endpoint, notify);
|
||||
ret = msm_slim_connect_endp(dev, endpoint);
|
||||
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
@ -946,7 +966,7 @@ static int msm_slim_init_tx_msgq(struct msm_slim_ctrl *dev, u32 pipe_reg)
|
|||
dev_err(dev->dev, "dma_alloc_coherent failed\n");
|
||||
goto alloc_buffer_failed;
|
||||
}
|
||||
ret = msm_slim_connect_endp(dev, endpoint, NULL);
|
||||
ret = msm_slim_connect_endp(dev, endpoint);
|
||||
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
|
|
@ -301,6 +301,7 @@ struct msm_slim_ctrl {
|
|||
int ipc_log_mask;
|
||||
bool sysfs_created;
|
||||
void *ipc_slimbus_log;
|
||||
void (*rx_slim)(struct msm_slim_ctrl *dev, u8 *buf);
|
||||
};
|
||||
|
||||
struct msm_sat_chan {
|
||||
|
@ -411,8 +412,7 @@ int msm_slim_sps_init(struct msm_slim_ctrl *dev, struct resource *bam_mem,
|
|||
void msm_slim_sps_exit(struct msm_slim_ctrl *dev, bool dereg);
|
||||
|
||||
int msm_slim_connect_endp(struct msm_slim_ctrl *dev,
|
||||
struct msm_slim_endp *endpoint,
|
||||
struct completion *notify);
|
||||
struct msm_slim_endp *endpoint);
|
||||
void msm_slim_disconnect_endp(struct msm_slim_ctrl *dev,
|
||||
struct msm_slim_endp *endpoint,
|
||||
enum msm_slim_msgq *msgq_flag);
|
||||
|
|
Loading…
Reference in New Issue