summaryrefslogtreecommitdiffstats
path: root/dma
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@suren.me>2015-02-06 18:39:16 +0100
committerSuren A. Chilingaryan <csa@suren.me>2015-02-06 18:39:16 +0100
commit3531f28654f24d88a3ec47f52a8e93dc9e1febc6 (patch)
tree8ec4faf01d4e6e77e4adac95749a9398ee736ded /dma
parentdd2ae62a852cea5be9a98ced55c11f4fdec4cb74 (diff)
downloadipecamera-3531f28654f24d88a3ec47f52a8e93dc9e1febc6.tar.gz
ipecamera-3531f28654f24d88a3ec47f52a8e93dc9e1febc6.tar.bz2
ipecamera-3531f28654f24d88a3ec47f52a8e93dc9e1febc6.tar.xz
ipecamera-3531f28654f24d88a3ec47f52a8e93dc9e1febc6.zip
Use empty_detected flag to reduce timeout
Diffstat (limited to 'dma')
-rw-r--r--dma/ipe.c32
-rw-r--r--dma/ipe_private.h1
2 files changed, 23 insertions, 10 deletions
diff --git a/dma/ipe.c b/dma/ipe.c
index 3137ceb..c3422ed 100644
--- a/dma/ipe.c
+++ b/dma/ipe.c
@@ -358,13 +358,10 @@ int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin
volatile void *desc_va;
volatile uint32_t *last_written_addr_ptr;
+ volatile uint32_t *empty_detected_ptr;
pcilib_dma_flags_t packet_flags = PCILIB_DMA_FLAG_EOP;
-#ifdef IPEDMA_DETECT_PACKETS
- volatile uint32_t *empty_detected_ptr;
-#endif /* IPEDMA_DETECT_PACKETS */
-
#ifdef IPEDMA_BUG_DMARD
pcilib_register_value_t value;
#endif /* IPEDMA_BUG_DMARD */
@@ -381,14 +378,22 @@ int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin
if (ctx->mode64) last_written_addr_ptr = desc_va + 3 * sizeof(uint32_t);
else last_written_addr_ptr = desc_va + 4 * sizeof(uint32_t);
-#ifdef IPEDMA_DETECT_PACKETS
- empty_detected_ptr = last_written_addr_ptr - 1;
-#endif /* IPEDMA_DETECT_PACKETS */
+ empty_detected_ptr = last_written_addr_ptr - 2;
do {
switch (ret&PCILIB_STREAMING_TIMEOUT_MASK) {
- case PCILIB_STREAMING_CONTINUE: wait = IPEDMA_DMA_TIMEOUT; break;
- case PCILIB_STREAMING_WAIT: wait = timeout; break;
+ case PCILIB_STREAMING_CONTINUE:
+ // Hardware indicates that there is no more data pending and we can safely stop if there is no data in the kernel buffers already
+#ifdef IPEDMA_SUPPORT_EMPTY_DETECTED
+ if (*empty_detected_ptr)
+ wait = 0;
+ else
+#endif /* IPEDMA_SUPPORT_EMPTY_DETECTED */
+ wait = IPEDMA_DMA_TIMEOUT;
+ break;
+ case PCILIB_STREAMING_WAIT:
+ wait = (timeout > IPEDMA_DMA_TIMEOUT)?timeout:IPEDMA_DMA_TIMEOUT;
+ break;
// case PCILIB_STREAMING_CHECK: wait = 0; break;
}
@@ -404,8 +409,15 @@ int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin
}
// Failing out if we exited on timeout
- if ((ctx->last_read_addr == (*last_written_addr_ptr))||(*last_written_addr_ptr == 0))
+ if ((ctx->last_read_addr == (*last_written_addr_ptr))||(*last_written_addr_ptr == 0)) {
+#ifdef IPEDMA_SUPPORT_EMPTY_DETECTED
+//# ifdef IPEDMA_DEBUG
+ if (wait)
+ pcilib_warning("The empty_detected flag is not set, but no data arrived within %lu us\n", wait);
+//# endif /* IPEDMA_DEBUG */
+#endif /* IPEDMA_SUPPORT_EMPTY_DETECTED */
return (ret&PCILIB_STREAMING_FAIL)?PCILIB_ERROR_TIMEOUT:0;
+ }
// Getting next page to read
cur_read = ctx->last_read + 1;
diff --git a/dma/ipe_private.h b/dma/ipe_private.h
index f621716..fd44011 100644
--- a/dma/ipe_private.h
+++ b/dma/ipe_private.h
@@ -12,6 +12,7 @@
//#define IPEDMA_DEBUG
//#define IPEDMA_BUG_DMARD /**< No register read during DMA transfer */
//#define IPEDMA_DETECT_PACKETS /**< Using empty_deceted flag */
+#define IPEDMA_SUPPORT_EMPTY_DETECTED /**< Avoid waiting for data when empty_detected flag is set in hardware */
#define IPEDMA_DMA_TIMEOUT 100000 /**< us, overrides PCILIB_DMA_TIMEOUT (actual hardware timeout is 50ms according to Lorenzo) */
#define IPEDMA_REG_RESET 0x00