From 3531f28654f24d88a3ec47f52a8e93dc9e1febc6 Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Fri, 6 Feb 2015 18:39:16 +0100 Subject: Use empty_detected flag to reduce timeout --- dma/ipe.c | 32 ++++++++++++++++++++++---------- dma/ipe_private.h | 1 + 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 -- cgit v1.2.3