From e202b682db9b5241c59de3d934d64205a3df091d Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Thu, 7 May 2015 05:03:18 +0200 Subject: Dynamicly set TLP(Payload) size in IPEDMA --- dma/ipe.c | 24 +++++++++++++++++++----- dma/ipe_private.h | 15 +++++++++------ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/dma/ipe.c b/dma/ipe.c index 8d35a14..89c645f 100644 --- a/dma/ipe.c +++ b/dma/ipe.c @@ -97,6 +97,10 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm ipe_dma_t *ctx = (ipe_dma_t*)vctx; +#ifndef IPEDMA_TLP_SIZE + const pcilib_pcie_link_info_t *link_info; +#endif /* ! IPEDMA_TLP_SIZE */ + int preserve = 0; pcilib_kmem_flags_t kflags; pcilib_kmem_reuse_state_t reuse_desc, reuse_pages; @@ -105,9 +109,9 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm volatile uint32_t *last_written_addr_ptr; pcilib_register_value_t value; - + + int tlp_size; uint32_t address64; - if (dma == PCILIB_DMA_ENGINE_INVALID) return 0; else if (dma > 1) return PCILIB_ERROR_INVALID_BANK; @@ -196,9 +200,19 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm // 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); else address64 = 0; - - WR(IPEDMA_REG_TLP_SIZE, address64 | IPEDMA_TLP_SIZE); - WR(IPEDMA_REG_TLP_COUNT, IPEDMA_PAGE_SIZE / (4 * IPEDMA_TLP_SIZE * IPEDMA_CORES)); + +#ifdef IPEDMA_TLP_SIZE + tlp_size = IPEDMA_TLP_SIZE; +#else /* IPEDMA_TLP_SIZE */ + link_info = pcilib_get_pcie_link_info(vctx->pcilib); + if (link_info) { + tlp_size = 1<max_payload; + if (tlp_size > IPEDMA_MAX_TLP_SIZE) + tlp_size = IPEDMA_MAX_TLP_SIZE; + } else tlp_size = 128; +#endif /* IPEDMA_TLP_SIZE */ + WR(IPEDMA_REG_TLP_SIZE, address64 | (tlp_size>>2)); + WR(IPEDMA_REG_TLP_COUNT, IPEDMA_PAGE_SIZE / (tlp_size * IPEDMA_CORES)); // Setting progress register threshold WR(IPEDMA_REG_UPDATE_THRESHOLD, IPEDMA_DMA_PROGRESS_THRESHOLD); diff --git a/dma/ipe_private.h b/dma/ipe_private.h index 1fb4e9e..ae5df1c 100644 --- a/dma/ipe_private.h +++ b/dma/ipe_private.h @@ -5,22 +5,25 @@ #define IPEDMA_64BIT_MODE 1 /**< 64-bit mode addressing is required to support PCIe gen3 */ #define IPEDMA_CORES 1 -#define IPEDMA_TLP_SIZE 32 +#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_PAGE_SIZE 4096 #define IPEDMA_DMA_PAGES 32 /**< 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 */ #define IPEDMA_DESCRIPTOR_SIZE 128 #define IPEDMA_DESCRIPTOR_ALIGNMENT 64 -#define IPEDMA_BUG_LAST_READ /**< We should forbid writting the second last available DMA buffer (the last is forbidden by design) */ -#define IPEDMA_RESET_DELAY 100000 /**< Sleep between accessing DMA control and reset registers */ -#define IPEDMA_ADD_PAGE_DELAY 1000 /**< Delay between submitting successive DMA pages into IPEDMA_REG_PAGE_ADDR register */ -#define IPEDMA_NODATA_SLEEP 10 /**< To keep CPU free */ //#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 */ -#define IPEDMA_DMA_TIMEOUT 100000 /**< us, overrides PCILIB_DMA_TIMEOUT (actual hardware timeout is 50ms according to Lorenzo) */ + +#define IPEDMA_DMA_TIMEOUT 100000 /**< us, overrides PCILIB_DMA_TIMEOUT (actual hardware timeout is 50ms according to Lorenzo) */ +#define IPEDMA_RESET_DELAY 100000 /**< Sleep between accessing DMA control and reset registers */ +#define IPEDMA_ADD_PAGE_DELAY 1000 /**< Delay between submitting successive DMA pages into IPEDMA_REG_PAGE_ADDR register */ +#define IPEDMA_NODATA_SLEEP 10 /**< To keep CPU free */ #define IPEDMA_REG_RESET 0x00 #define IPEDMA_REG_CONTROL 0x04 -- cgit v1.2.3