summaryrefslogtreecommitdiffstats
path: root/dma
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@suren.me>2015-11-20 14:57:46 +0100
committerSuren A. Chilingaryan <csa@suren.me>2015-11-20 14:57:46 +0100
commitfe5bca8604e8c381d3fe2cce3073dd6602d016d1 (patch)
tree8a8d26f9ec529f1563d3a790fcd811f857ad1cda /dma
parentcc5107c6d3db46ba213db974c630fc0fa1b89d68 (diff)
downloadpcitool-fe5bca8604e8c381d3fe2cce3073dd6602d016d1.tar.gz
pcitool-fe5bca8604e8c381d3fe2cce3073dd6602d016d1.tar.bz2
pcitool-fe5bca8604e8c381d3fe2cce3073dd6602d016d1.tar.xz
pcitool-fe5bca8604e8c381d3fe2cce3073dd6602d016d1.zip
Support static DMA regions in IPEDMA
Diffstat (limited to 'dma')
-rw-r--r--dma/ipe.c23
-rw-r--r--dma/ipe.h8
2 files changed, 24 insertions, 7 deletions
diff --git a/dma/ipe.c b/dma/ipe.c
index 2c3f32c..889c612 100644
--- a/dma/ipe.c
+++ b/dma/ipe.c
@@ -135,6 +135,9 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm
ipe_dma_t *ctx = (ipe_dma_t*)vctx;
+ pcilib_kmem_handle_t *desc = NULL;
+ pcilib_kmem_handle_t *pages = NULL;
+
#ifndef IPEDMA_TLP_SIZE
const pcilib_pcie_link_info_t *link_info;
#endif /* ! IPEDMA_TLP_SIZE */
@@ -148,6 +151,7 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm
pcilib_register_value_t value;
+ uintptr_t dma_region = 0;
int tlp_size;
uint32_t address64;
@@ -166,8 +170,10 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm
link_info = pcilib_get_pcie_link_info(vctx->pcilib);
if (link_info) {
tlp_size = 1<<link_info->payload;
+# ifdef IPEDMA_MAX_TLP_SIZE
if (tlp_size > IPEDMA_MAX_TLP_SIZE)
tlp_size = IPEDMA_MAX_TLP_SIZE;
+# endif /* IPEDMA_MAX_TLP_SIZE */
} else tlp_size = 128;
#endif /* IPEDMA_TLP_SIZE */
@@ -192,6 +198,12 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm
else
ctx->ring_size = IPEDMA_DMA_PAGES;
+ if (!pcilib_read_register(ctx->dmactx.pcilib, "dmaconf", "dma_region_low", &value)) {
+ dma_region = value;
+ if (!pcilib_read_register(ctx->dmactx.pcilib, "dmaconf", "dma_region_low", &value))
+ dma_region |= ((uintptr_t)value)<<32;
+ }
+
if (!pcilib_read_register(ctx->dmactx.pcilib, "dmaconf", "ipedma_flags", &value))
ctx->dma_flags = value;
else
@@ -208,13 +220,16 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm
#endif /* IPEDMA_CONFIGURE_DMA_MASK */
kflags = PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_EXCLUSIVE|PCILIB_KMEM_FLAG_HARDWARE|(ctx->preserve?PCILIB_KMEM_FLAG_PERSISTENT:0);
- pcilib_kmem_handle_t *desc = pcilib_alloc_kernel_memory(ctx->dmactx.pcilib, PCILIB_KMEM_TYPE_CONSISTENT, 1, IPEDMA_DESCRIPTOR_SIZE, IPEDMA_DESCRIPTOR_ALIGNMENT, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, 0x00), kflags);
- pcilib_kmem_handle_t *pages = pcilib_alloc_kernel_memory(ctx->dmactx.pcilib, PCILIB_KMEM_TYPE_DMA_C2S_PAGE, ctx->ring_size, ctx->page_size, 0, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, 0x00), kflags);
+
+ desc = pcilib_alloc_kernel_memory(ctx->dmactx.pcilib, PCILIB_KMEM_TYPE_CONSISTENT, 1, IPEDMA_DESCRIPTOR_SIZE, IPEDMA_DESCRIPTOR_ALIGNMENT, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, 0x00), kflags);
+ if (dma_region)
+ pages = pcilib_alloc_kernel_memory(ctx->dmactx.pcilib, PCILIB_KMEM_TYPE_REGION_C2S, ctx->ring_size, ctx->page_size, dma_region, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, 0x00), kflags);
+ else
+ pages = pcilib_alloc_kernel_memory(ctx->dmactx.pcilib, PCILIB_KMEM_TYPE_DMA_C2S_PAGE, ctx->ring_size, ctx->page_size, 0, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, 0x00), kflags);
if (!desc||!pages) {
if (pages) pcilib_free_kernel_memory(ctx->dmactx.pcilib, pages, KMEM_FLAG_REUSE);
if (desc) pcilib_free_kernel_memory(ctx->dmactx.pcilib, desc, KMEM_FLAG_REUSE);
- printf("%lu\n", IPEDMA_DESCRIPTOR_SIZE);
pcilib_error("Can't allocate required kernel memory for IPEDMA engine (%lu pages of %lu bytes + %lu byte descriptor)", ctx->ring_size, ctx->page_size, (unsigned long)IPEDMA_DESCRIPTOR_SIZE);
return PCILIB_ERROR_MEMORY;
}
@@ -227,7 +242,7 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm
pcilib_free_kernel_memory(ctx->dmactx.pcilib, pages, KMEM_FLAG_REUSE);
pcilib_free_kernel_memory(ctx->dmactx.pcilib, desc, KMEM_FLAG_REUSE);
- if ((flags&PCILIB_DMA_FLAG_STOP) == 0) {
+ if (((flags&PCILIB_DMA_FLAG_STOP) == 0)||(dma_region)) {
pcilib_error("Inconsistent DMA buffers are found (buffers are only partially re-used). This is very wrong, please stop DMA engine and correct configuration...");
return PCILIB_ERROR_INVALID_STATE;
}
diff --git a/dma/ipe.h b/dma/ipe.h
index 1626415..58185ff 100644
--- a/dma/ipe.h
+++ b/dma/ipe.h
@@ -84,9 +84,11 @@ static const pcilib_register_description_t ipe_dma_registers[] = {
{0x0004, 0, 32, IPEDMA_DMA_TIMEOUT, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMACONF, "dma_timeout", "Default DMA timeout"},
{0x0008, 0, 32, IPEDMA_DMA_PAGES, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMACONF, "dma_pages", "Number of buffers in DMA page ring"},
{0x000C, 0, 32, IPEDMA_PAGE_SIZE, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMACONF, "dma_page_size", "Size of a page in DMA page ring (multiple of 4K)"},
- {0x0010, 0, 32, 0, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMACONF, "ipedma_flags", "DMA Control Register"},
- {0x0010, 0, 1, 0, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMACONF, "ipedma_nosync", "Do not synchronize DMA pages"},
- {0x0010, 1, 1, 0, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMACONF, "ipedma_nosleep", "Do not sleep while there is no data"},
+ {0x0010, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMACONF, "dma_region_low", "Low bits of static DMA I/O region"},
+ {0x0014, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMACONF, "dma_region_hi", "High bits of static DMA I/O region"},
+ {0x0020, 0, 32, 0, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMACONF, "ipedma_flags", "DMA Control Register"},
+ {0x0020, 0, 1, 0, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMACONF, "ipedma_nosync", "Do not synchronize DMA pages"},
+ {0x0020, 1, 1, 0, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMACONF, "ipedma_nosleep", "Do not sleep while there is no data"},
{0, 0, 0, 0, 0x00000000, 0, 0, 0, NULL, NULL}
};
#endif /* _PCILIB_EXPORT_C */