From 36385f1e83c7f6dd45954033b91d1871e62005c4 Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Fri, 12 Jun 2015 17:24:18 +0200 Subject: Support streaming mode in IPEDMA --- dma/ipe.c | 16 +++++++++++++++- dma/ipe_private.h | 6 +++++- docs/IPEHARDWARE | 8 ++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 docs/IPEHARDWARE diff --git a/dma/ipe.c b/dma/ipe.c index a9ecc90..953de09 100644 --- a/dma/ipe.c +++ b/dma/ipe.c @@ -111,10 +111,12 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm else if ((reuse_desc & PCILIB_KMEM_REUSE_HARDWARE) == 0) pcilib_warning("Lost DMA buffers are found (missing HW reference), reinitializing..."); else { #ifndef IPEDMA_BUG_DMARD +# ifndef IPEDMA_STREAMING_MODE RD(IPEDMA_REG_PAGE_COUNT, value); if (value != IPEDMA_DMA_PAGES) pcilib_warning("Inconsistent DMA buffers are found (Number of allocated buffers (%lu) does not match current request (%lu)), reinitializing...", value + 1, IPEDMA_DMA_PAGES); else +# endif /* IPEDMA_STREAMING_MODE */ #endif /* IPEDMA_BUG_DMARD */ preserve = 1; } @@ -501,9 +503,21 @@ int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin ret = cb(cbattr, packet_flags, ctx->page_size, buf); if (ret < 0) return -ret; - // We don't need this because hardwaredoes not intend to read anything from the memory + // We don't need this because hardware does not intend to read anything from the memory // pcilib_kmem_sync_block(ctx->dmactx.pcilib, ctx->pages, PCILIB_KMEM_SYNC_TODEVICE, cur_read); + // Return buffer into the DMA pool when processed +#ifdef IPEDMA_STREAMING_MODE + uintptr_t buf_ba = pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, ctx->pages, cur_read); + WR(IPEDMA_REG_PAGE_ADDR, buf_ba); +# ifdef IPEDMA_STREAMING_CHECKS + pcilib_register_value_t streaming_status; + RD(IPEDMA_REG_STREAMING_STATUS, streaming_status); + if (streaming_status) + pcilib_error("Invalid status (0x%lx) adding a DMA buffer into the queue", streaming_status); +# endif /* IPEDMA_STREAMING_MODE */ +#endif /* IPEDMA_STREAMING_MODE */ + // Numbered from 1 #ifdef IPEDMA_BUG_LAST_READ WR(IPEDMA_REG_LAST_READ, cur_read?cur_read:IPEDMA_DMA_PAGES); diff --git a/dma/ipe_private.h b/dma/ipe_private.h index 5cfb10b..249286d 100644 --- a/dma/ipe_private.h +++ b/dma/ipe_private.h @@ -8,6 +8,8 @@ #define IPEDMA_MAX_TLP_SIZE 256 /**< Defines maximum TLP in bytes supported by device */ //#define IPEDMA_TLP_SIZE 128 /**< If set, enforces the specified TLP size */ +#define IPEDMA_STREAMING_MODE /**< Enables streaming DMA operation mode instead of ring-buffer, the page is written once and forgotten and need to be pushed in queue again */ +#define IPEDMA_STREAMING_CHECKS /**< Enables status checks in streaming mode (it will cause performance penalty) */ #define IPEDMA_PAGE_SIZE 4096 #define IPEDMA_DMA_PAGES 1024 /**< number of DMA pages in the ring buffer to allocate */ #define IPEDMA_DMA_PROGRESS_THRESHOLD 1 /**< how many pages the DMA engine should fill before reporting progress */ @@ -31,9 +33,11 @@ #define IPEDMA_REG_TLP_COUNT 0x10 #define IPEDMA_REG_PAGE_ADDR 0x50 #define IPEDMA_REG_UPDATE_ADDR 0x54 -#define IPEDMA_REG_LAST_READ 0x58 +#define IPEDMA_REG_LAST_READ 0x58 /**< In streaming mode, we can use it freely to track current status */ #define IPEDMA_REG_PAGE_COUNT 0x5C #define IPEDMA_REG_UPDATE_THRESHOLD 0x60 +#define IPEDMA_REG_STREAMING_STATUS 0x68 + #define WR(addr, value) { *(uint32_t*)(ctx->base_addr + addr) = value; } #define RD(addr, value) { value = *(uint32_t*)(ctx->base_addr + addr); } diff --git a/docs/IPEHARDWARE b/docs/IPEHARDWARE new file mode 100644 index 0000000..a7bbf3a --- /dev/null +++ b/docs/IPEHARDWARE @@ -0,0 +1,8 @@ +IPEDMA +====== + - Normally, we are using register 0x5C to get number of buffers configured in the hardware + and check if it is consistent with number of allocated buffers. However, in streaming mode + this does not work at the moment. After writting the buffers, the hardware forgets them + and only stores the current queue of free buffers. Currently, the check is disabled in the + streaming mode. Can we handle it somehow? + \ No newline at end of file -- cgit v1.2.3