diff options
| author | Yan He <yanhe@codeaurora.org> | 2015-11-20 17:45:22 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 21:12:23 -0700 |
| commit | 0307f3529b16d4e04fae49876755358df5d34663 (patch) | |
| tree | bd84ba6821b6eeba940f9dab55d779786c7def56 /drivers/platform | |
| parent | 9d65c3021c17387fefb352e3ce02aa7b2caea85d (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.c | 54 | ||||
| -rw-r--r-- | drivers/platform/msm/sps/bam.h | 24 | ||||
| -rw-r--r-- | drivers/platform/msm/sps/sps_bam.c | 33 |
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; } |
