From 5295824c33410cd2883f064a6d7472a0fdf3d735 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Wed, 24 May 2017 16:16:38 -0700 Subject: [PATCH] soc: qcom: glink_spi_xprt: Remove extra SPI transactions The TX FIFO write reg and the RX FIFO read reg are controlled by this processor. Keep track of the state of these two indexes to reduce the amount of SPI reads. CRs-Fixed: 2093123 Change-Id: I4ffa0e08bce6dabd57f33a13fef8107211ce3f09 Signed-off-by: Chris Lew --- drivers/soc/qcom/glink_spi_xprt.c | 78 +++++++++++++++---------------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/drivers/soc/qcom/glink_spi_xprt.c b/drivers/soc/qcom/glink_spi_xprt.c index 6794c30605d7..a94c4c909a40 100644 --- a/drivers/soc/qcom/glink_spi_xprt.c +++ b/drivers/soc/qcom/glink_spi_xprt.c @@ -121,6 +121,8 @@ struct glink_cmpnt { * @tx_fifo_write_reg_addr: Address of the TX FIFO Write Index Register. * @rx_fifo_read_reg_addr: Address of the RX FIFO Read Index Register. * @rx_fifo_write_reg_addr: Address of the RX FIFO Write Index Register. + * @tx_fifo_write: Internal write index for TX FIFO. + * @rx_fifo_read: Internal read index for RX FIFO. * @kwork: Work to be executed when receiving data. * @kworker: Handle to the entity processing @kwork. * @task: Handle to the task context that runs @kworker. @@ -158,6 +160,8 @@ struct edge_info { unsigned int tx_fifo_write_reg_addr; unsigned int rx_fifo_read_reg_addr; unsigned int rx_fifo_write_reg_addr; + uint32_t tx_fifo_write; + uint32_t rx_fifo_read; struct kthread_work kwork; struct kthread_worker kworker; @@ -368,6 +372,19 @@ static int glink_spi_xprt_write_avail(struct edge_info *einfo) int write_avail; int ret; + if (unlikely(!einfo->tx_fifo_start)) { + ret = glink_spi_xprt_reg_read(einfo, + einfo->tx_fifo_write_reg_addr, &einfo->tx_fifo_write); + if (ret < 0) { + pr_err("%s: Error %d reading %s tx_fifo_write_reg_addr %d\n", + __func__, ret, einfo->xprt_cfg.edge, + einfo->tx_fifo_write_reg_addr); + return 0; + } + einfo->tx_fifo_start = einfo->tx_fifo_write; + } + write_id = einfo->tx_fifo_write; + ret = glink_spi_xprt_reg_read(einfo, einfo->tx_fifo_read_reg_addr, &read_id); if (ret < 0) { @@ -377,21 +394,9 @@ static int glink_spi_xprt_write_avail(struct edge_info *einfo) return 0; } - ret = glink_spi_xprt_reg_read(einfo, einfo->tx_fifo_write_reg_addr, - &write_id); - if (ret < 0) { - pr_err("%s: Error %d reading %s tx_fifo_write_reg_addr %d\n", - __func__, ret, einfo->xprt_cfg.edge, - einfo->tx_fifo_write_reg_addr); - return 0; - } - if (!read_id || !write_id) return 0; - if (unlikely(!einfo->tx_fifo_start)) - einfo->tx_fifo_start = write_id; - if (read_id > write_id) write_avail = read_id - write_id; else @@ -421,14 +426,18 @@ static int glink_spi_xprt_read_avail(struct edge_info *einfo) int read_avail; int ret; - ret = glink_spi_xprt_reg_read(einfo, einfo->rx_fifo_read_reg_addr, - &read_id); - if (ret < 0) { - pr_err("%s: Error %d reading %s rx_fifo_read_reg_addr %d\n", - __func__, ret, einfo->xprt_cfg.edge, - einfo->rx_fifo_read_reg_addr); - return 0; + if (unlikely(!einfo->rx_fifo_start)) { + ret = glink_spi_xprt_reg_read(einfo, + einfo->rx_fifo_read_reg_addr, &einfo->rx_fifo_read); + if (ret < 0) { + pr_err("%s: Error %d reading %s rx_fifo_read_reg_addr %d\n", + __func__, ret, einfo->xprt_cfg.edge, + einfo->rx_fifo_read_reg_addr); + return 0; + } + einfo->rx_fifo_start = einfo->rx_fifo_read; } + read_id = einfo->rx_fifo_read; ret = glink_spi_xprt_reg_read(einfo, einfo->rx_fifo_write_reg_addr, &write_id); @@ -442,9 +451,6 @@ static int glink_spi_xprt_read_avail(struct edge_info *einfo) if (!read_id || !write_id) return 0; - if (unlikely(!einfo->rx_fifo_start)) - einfo->rx_fifo_start = read_id; - if (read_id <= write_id) read_avail = write_id - read_id; else @@ -471,15 +477,7 @@ static int glink_spi_xprt_rx_cmd(struct edge_info *einfo, void *dst, uint32_t offset = 0; int ret; - ret = glink_spi_xprt_reg_read(einfo, einfo->rx_fifo_read_reg_addr, - &read_id); - if (ret < 0) { - pr_err("%s: Error %d reading %s rx_fifo_read_reg_addr %d\n", - __func__, ret, einfo->xprt_cfg.edge, - einfo->rx_fifo_read_reg_addr); - return ret; - } - + read_id = einfo->rx_fifo_read; do { if ((read_id + size_to_read) >= (einfo->rx_fifo_start + einfo->fifo_size)) @@ -504,6 +502,9 @@ static int glink_spi_xprt_rx_cmd(struct edge_info *einfo, void *dst, pr_err("%s: Error %d writing %s rx_fifo_read_reg_addr %d\n", __func__, ret, einfo->xprt_cfg.edge, einfo->rx_fifo_read_reg_addr); + else + einfo->rx_fifo_read = read_id; + return ret; } @@ -526,15 +527,7 @@ static int glink_spi_xprt_tx_cmd_safe(struct edge_info *einfo, void *src, uint32_t offset = 0; int ret; - ret = glink_spi_xprt_reg_read(einfo, einfo->tx_fifo_write_reg_addr, - &write_id); - if (ret < 0) { - pr_err("%s: Error %d reading %s tx_fifo_write_reg_addr %d\n", - __func__, ret, einfo->xprt_cfg.edge, - einfo->tx_fifo_write_reg_addr); - return ret; - } - + write_id = einfo->tx_fifo_write; do { if ((write_id + size_to_write) >= (einfo->tx_fifo_start + einfo->fifo_size)) @@ -559,6 +552,9 @@ static int glink_spi_xprt_tx_cmd_safe(struct edge_info *einfo, void *src, pr_err("%s: Error %d writing %s tx_fifo_write_reg_addr %d\n", __func__, ret, einfo->xprt_cfg.edge, einfo->tx_fifo_write_reg_addr); + else + einfo->tx_fifo_write = write_id; + return ret; } @@ -1236,6 +1232,8 @@ static int ssr(struct glink_transport_if *if_ptr) einfo->tx_blocked_signal_sent = false; einfo->tx_fifo_start = 0; einfo->rx_fifo_start = 0; + einfo->tx_fifo_write = 0; + einfo->rx_fifo_read = 0; einfo->fifo_size = DEFAULT_FIFO_SIZE; einfo->xprt_if.glink_core_if_ptr->link_down(&einfo->xprt_if);