diff options
author | Suren A. Chilingaryan <csa@suren.me> | 2015-02-06 18:39:16 +0100 |
---|---|---|
committer | Suren A. Chilingaryan <csa@suren.me> | 2015-02-06 18:39:16 +0100 |
commit | 3531f28654f24d88a3ec47f52a8e93dc9e1febc6 (patch) | |
tree | 8ec4faf01d4e6e77e4adac95749a9398ee736ded /dma | |
parent | dd2ae62a852cea5be9a98ced55c11f4fdec4cb74 (diff) | |
download | pcitool-3531f28654f24d88a3ec47f52a8e93dc9e1febc6.tar.gz pcitool-3531f28654f24d88a3ec47f52a8e93dc9e1febc6.tar.bz2 pcitool-3531f28654f24d88a3ec47f52a8e93dc9e1febc6.tar.xz pcitool-3531f28654f24d88a3ec47f52a8e93dc9e1febc6.zip |
Use empty_detected flag to reduce timeout
Diffstat (limited to 'dma')
-rw-r--r-- | dma/ipe.c | 32 | ||||
-rw-r--r-- | dma/ipe_private.h | 1 |
2 files changed, 23 insertions, 10 deletions
@@ -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 |