summaryrefslogtreecommitdiff
path: root/drivers/platform
diff options
context:
space:
mode:
authorYan He <yanhe@codeaurora.org>2015-11-20 17:45:22 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:12:23 -0700
commit0307f3529b16d4e04fae49876755358df5d34663 (patch)
treebd84ba6821b6eeba940f9dab55d779786c7def56 /drivers/platform
parent9d65c3021c17387fefb352e3ce02aa7b2caea85d (diff)
msm: sps: add the checking of ZLT in case of an empty pipe
Check if a ZLT descriptor is the last pending descriptor in the desc FIFO when determine if the desc FIFO of that pipe is empty. Change-Id: Ib8174953d6ad7d886f47f21e243e985b79ef41fb Signed-off-by: Yan He <yanhe@codeaurora.org>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/msm/sps/bam.c54
-rw-r--r--drivers/platform/msm/sps/bam.h24
-rw-r--r--drivers/platform/msm/sps/sps_bam.c33
3 files changed, 107 insertions, 4 deletions
diff --git a/drivers/platform/msm/sps/bam.c b/drivers/platform/msm/sps/bam.c
index d24ff25ebb7e..e3b38fb9c5f8 100644
--- a/drivers/platform/msm/sps/bam.c
+++ b/drivers/platform/msm/sps/bam.c
@@ -177,6 +177,8 @@
#define P_RST_P_SW_RST 0x1
/* P_HALTn */
+#define P_HALT_P_PIPE_EMPTY 0x8
+#define P_HALT_P_LAST_DESC_ZLT 0x4
#define P_HALT_P_PROD_HALTED 0x2
#define P_HALT_P_HALT 0x1
@@ -1271,6 +1273,58 @@ void bam_disable_pipe(void *base, u32 pipe)
wmb(); /* ensure pipe is disabled */
}
+/*
+ * Check if the last desc is ZLT
+ */
+bool bam_pipe_check_zlt(void *base, u32 pipe)
+{
+ struct sps_bam *dev = to_sps_bam_dev(base);
+
+ if ((dev == NULL) || (&dev->base != base)) {
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ __func__, base);
+ return false;
+ }
+
+ if (bam_read_reg_field(base, P_HALT, pipe, P_HALT_P_LAST_DESC_ZLT)) {
+ SPS_DBG(dev,
+ "sps:%s:bam=0x%p(va).pipe=%d: the last desc is ZLT.",
+ __func__, base, pipe);
+ return true;
+ }
+
+ SPS_DBG(dev,
+ "sps:%s:bam=0x%p(va).pipe=%d: the last desc is not ZLT.",
+ __func__, base, pipe);
+ return false;
+}
+
+/*
+ * Check if desc FIFO is empty
+ */
+bool bam_pipe_check_pipe_empty(void *base, u32 pipe)
+{
+ struct sps_bam *dev = to_sps_bam_dev(base);
+
+ if ((dev == NULL) || (&dev->base != base)) {
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ __func__, base);
+ return false;
+ }
+
+ if (bam_read_reg_field(base, P_HALT, pipe, P_HALT_P_PIPE_EMPTY)) {
+ SPS_DBG(dev,
+ "sps:%s:bam=0x%p(va).pipe=%d: desc FIFO is empty.",
+ __func__, base, pipe);
+ return true;
+ }
+
+ SPS_DBG(dev,
+ "sps:%s:bam=0x%p(va).pipe=%d: desc FIFO is not empty.",
+ __func__, base, pipe);
+ return false;
+}
+
/**
* Initialize a BAM pipe
*/
diff --git a/drivers/platform/msm/sps/bam.h b/drivers/platform/msm/sps/bam.h
index d34a7d3e9b09..757c477ae5f4 100644
--- a/drivers/platform/msm/sps/bam.h
+++ b/drivers/platform/msm/sps/bam.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -422,4 +422,26 @@ void bam_pipe_timer_reset(void *base, u32 pipe);
*/
u32 bam_pipe_timer_get_count(void *base, u32 pipe);
+/*
+ * bam_pipe_check_zlt - Check if the last desc is ZLT.
+ * @base: BAM virtual address
+ * @pipe: pipe index
+ *
+ * This function checks if the last desc in the desc FIFO is a ZLT desc.
+ *
+ * @return true if the last desc in the desc FIFO is a ZLT desc. Otherwise
+ * return false.
+ */
+bool bam_pipe_check_zlt(void *base, u32 pipe);
+
+/*
+ * bam_pipe_check_pipe_empty - Check if desc FIFO is empty.
+ * @base: BAM virtual address
+ * @pipe: pipe index
+ *
+ * This function checks if the desc FIFO of this pipe is empty.
+ *
+ * @return true if desc FIFO is empty. Otherwise return false.
+ */
+bool bam_pipe_check_pipe_empty(void *base, u32 pipe);
#endif /* _BAM_H_ */
diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c
index 48e2869d4959..17cd83730abe 100644
--- a/drivers/platform/msm/sps/sps_bam.c
+++ b/drivers/platform/msm/sps/sps_bam.c
@@ -2212,10 +2212,37 @@ int sps_bam_pipe_is_empty(struct sps_bam *dev, u32 pipe_index,
/* Determine descriptor FIFO state */
- if (end_offset == acked_offset)
+ if (end_offset == acked_offset) {
*empty = true;
- else
- *empty = false;
+ } else {
+ if ((pipe->state & BAM_STATE_BAM2BAM) == 0) {
+ *empty = false;
+ return 0;
+ }
+ if (bam_pipe_check_zlt(&dev->base, pipe_index)) {
+ bool p_idc;
+ u32 next_write;
+
+ p_idc = bam_pipe_check_pipe_empty(&dev->base,
+ pipe_index);
+
+ next_write = acked_offset + sizeof(struct sps_iovec);
+ if (next_write >= pipe->desc_size)
+ next_write = 0;
+
+ if (next_write == end_offset) {
+ *empty = true;
+ if (!p_idc)
+ SPS_DBG3(dev,
+ "sps:BAM %pa pipe %d pipe empty checking for ZLT.\n",
+ BAM_ID(dev), pipe_index);
+ } else {
+ *empty = false;
+ }
+ } else {
+ *empty = false;
+ }
+ }
return 0;
}