From ccbad1cc8eca5f361427dd0ceca15cfa6d68a6d9 Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Thu, 6 Aug 2015 05:27:21 +0200 Subject: Detect if IPEDMA operates in streaming mode --- dma/ipe.c | 73 ++++++++++++++++++------------------------------------- dma/ipe.h | 4 ++- dma/ipe_private.h | 7 ++++-- 3 files changed, 32 insertions(+), 52 deletions(-) diff --git a/dma/ipe.c b/dma/ipe.c index 814bc77..2ed3e05 100644 --- a/dma/ipe.c +++ b/dma/ipe.c @@ -43,14 +43,18 @@ pcilib_dma_context_t *dma_ipe_init(pcilib_t *pcilib, const char *model, const vo ctx->dma_bank = model_info->banks + dma_bank; ctx->base_addr = pcilib_resolve_register_address(pcilib, ctx->dma_bank->bar, ctx->dma_bank->read_addr); + RD(IPEDMA_REG_PCIE_GEN, value); + #ifdef IPEDMA_ENFORCE_64BIT_MODE ctx->mode64 = 1; #else /* IPEDMA_ENFORCE_64BIT_MODE */ // According to Lorenzo, some gen2 boards have problems with 64-bit addressing. Therefore, we only enable it for gen3 boards unless enforced - RD(IPEDMA_REG_PCIE_GEN, value); - if (value > 2) ctx->mode64 = 1; - else ctx->mode64 = 0; + if ((value&IPEDMA_MASK_PCIE_GEN) > 2) ctx->mode64 = 1; #endif /* IPEDMA_ENFORCE_64BIT_MODE */ + +#ifdef IPEDMA_STREAMING_MODE + if (value&IPEDMA_MASK_STREAMING_MODE) ctx->streaming = 1; +#endif /* IPEDMA_STREAMING_MODE */ } return (pcilib_dma_context_t*)ctx; @@ -114,15 +118,16 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm if ((reuse_desc & PCILIB_KMEM_REUSE_PERSISTENT) == 0) pcilib_warning("Lost DMA buffers are found (non-persistent mode), reinitializing..."); 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 */ + if (ctx->streaming) preserve = 1; + else { + 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 + preserve = 1; + } } } } else pcilib_warning("Inconsistent DMA buffers (modes of ring and page buffers does not match), reinitializing...."); @@ -136,12 +141,6 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm ctx->preserve = 1; // Detect the current state of DMA engine -#ifdef IPEDMA_BUG_DMARD - FILE *f = fopen("/tmp/pcitool_lastread", "r"); - if (!f) pcilib_error("Can't read current status"); - fread(&value, 1, sizeof(pcilib_register_value_t), f); - fclose(f); -#else /* IPEDMA_BUG_DMARD */ RD(IPEDMA_REG_LAST_READ, value); // Numbered from 1 in FPGA # ifdef IPEDMA_BUG_LAST_READ @@ -150,7 +149,6 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm # else /* IPEDMA_BUG_LAST_READ */ value--; # endif /* IPEDMA_BUG_LAST_READ */ -#endif /* IPEDMA_BUG_DMARD */ ctx->last_read = value; } else { @@ -166,12 +164,10 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm WR(IPEDMA_REG_RESET, 0x0); usleep(IPEDMA_RESET_DELAY); -#ifndef IPEDMA_BUG_DMARD // Verify PCIe link status RD(IPEDMA_REG_RESET, value); if ((value != 0x14031700)&&(value != 0x14021700)) pcilib_warning("PCIe is not ready, code is %lx", value); -#endif /* IPEDMA_BUG_DMARD */ // Enable 64 bit addressing and configure TLP and PACKET sizes (40 bit mode can be used with big pre-allocated buffers later) if (ctx->mode64) address64 = 0x8000 | (0<<24); @@ -224,14 +220,6 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm WR(IPEDMA_REG_CONTROL, 0x1); ctx->last_read = IPEDMA_DMA_PAGES - 1; - -#ifdef IPEDMA_BUG_DMARD - FILE *f = fopen("/tmp/pcitool_lastread", "w"); - if (!f) pcilib_error("Can't write current status"); - value = ctx->last_read; - fwrite(&value, 1, sizeof(pcilib_register_value_t), f); - fclose(f); -#endif /* IPEDMA_BUG_DMARD */ } ctx->last_read_addr = pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, pages, ctx->last_read); @@ -415,10 +403,6 @@ int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin pcilib_dma_flags_t packet_flags = PCILIB_DMA_FLAG_EOP; size_t nodata_sleep; -#ifdef IPEDMA_BUG_DMARD - pcilib_register_value_t value; -#endif /* IPEDMA_BUG_DMARD */ - switch (sched_getscheduler(0)) { case SCHED_FIFO: case SCHED_RR: @@ -511,16 +495,16 @@ int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin // 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); + if (ctx->streaming) { + 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); + 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 @@ -537,15 +521,6 @@ int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin ctx->last_read = cur_read; ctx->last_read_addr = pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, ctx->pages, cur_read); - -#ifdef IPEDMA_BUG_DMARD - FILE *f = fopen("/tmp/pcitool_lastread", "w"); - if (!f) pcilib_error("Can't write current status"); - value = cur_read; - fwrite(&value, 1, sizeof(pcilib_register_value_t), f); - fclose(f); -#endif /* IPEDMA_BUG_DMARD */ - } while (ret); return 0; diff --git a/dma/ipe.h b/dma/ipe.h index 76be4f4..7f32d61 100644 --- a/dma/ipe.h +++ b/dma/ipe.h @@ -65,7 +65,9 @@ static const pcilib_register_description_t ipe_dma_registers[] = { {0x000C, 24, 8, 0, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_up_addr", "Upper address for 64 bit memory addressing"}, {0x0010, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_count", "Write DMA TLP Count"}, {0x0014, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_pattern", "DMA generator data pattern"}, - {0x0018, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "pcie_gen", "PCIe version 2/3 depending on the used XILINX core"}, + {0x0018, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_mode_flags", "DMA operation mode"}, + {0x0018, 0, 4, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "pcie_gen", "PCIe version 2/3 depending on the used XILINX core"}, + {0x0018, 4, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "streaming_dma", "Streaming mode (enabled/disabled)"}, {0x0028, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_perf", "MWR Performance"}, {0x003C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "cfg_lnk_width", "Negotiated and max width of PCIe Link"}, {0x003C, 0, 6, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_cap_max_lnk_width", "Max link width"}, diff --git a/dma/ipe_private.h b/dma/ipe_private.h index 937e202..fdebec0 100644 --- a/dma/ipe_private.h +++ b/dma/ipe_private.h @@ -8,7 +8,7 @@ #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_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 */ @@ -17,7 +17,6 @@ #define IPEDMA_DESCRIPTOR_ALIGNMENT 64 -//#define IPEDMA_BUG_DMARD /**< No register read during DMA transfer */ //#define IPEDMA_BUG_LAST_READ /**< We should forbid writting the second last available DMA buffer (the last is forbidden by design) */ //#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 */ @@ -39,6 +38,9 @@ #define IPEDMA_REG_UPDATE_THRESHOLD 0x60 #define IPEDMA_REG_STREAMING_STATUS 0x68 +#define IPEDMA_MASK_PCIE_GEN 0xF +#define IPEDMA_MASK_STREAMING_MODE 0x10 + #define WR(addr, value) { *(uint32_t*)(ctx->base_addr + addr) = value; } #define RD(addr, value) { value = *(uint32_t*)(ctx->base_addr + addr); } @@ -62,6 +64,7 @@ struct ipe_dma_s { int reused; /**< indicates that DMA was found intialized, buffers were reused, and no additional initialization is needed */ int preserve; /**< indicates that DMA should not be stopped during clean-up */ int mode64; /**< indicates 64-bit operation mode */ + int streaming; /**< indicates if DMA is operating in streaming or ring-buffer mode */ pcilib_kmem_handle_t *desc; /**< in-memory status descriptor written by DMA engine upon operation progess */ pcilib_kmem_handle_t *pages; /**< collection of memory-locked pages for DMA operation */ -- cgit v1.2.3