summaryrefslogtreecommitdiffstats
path: root/dma
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@dside.dyndns.org>2011-07-14 06:01:27 +0200
committerSuren A. Chilingaryan <csa@dside.dyndns.org>2011-07-14 06:01:27 +0200
commitf4ad2df2209acac66f3df47d847f1f714283feab (patch)
tree23da0368acbb6c15cdebd2a35808cd6bbe99b8ae /dma
parentb492b1aac3d12683ccbc973b08b023ba0466cbec (diff)
downloadipecamera-f4ad2df2209acac66f3df47d847f1f714283feab.tar.gz
ipecamera-f4ad2df2209acac66f3df47d847f1f714283feab.tar.bz2
ipecamera-f4ad2df2209acac66f3df47d847f1f714283feab.tar.xz
ipecamera-f4ad2df2209acac66f3df47d847f1f714283feab.zip
First iteration of work to preserve DMA state between executions
Diffstat (limited to 'dma')
-rw-r--r--dma/nwl.c185
-rw-r--r--dma/nwl.h3
-rw-r--r--dma/nwl_buffers.h22
-rw-r--r--dma/nwl_engine.c42
-rw-r--r--dma/nwl_loopback.c173
-rw-r--r--dma/nwl_register.h4
6 files changed, 228 insertions, 201 deletions
diff --git a/dma/nwl.c b/dma/nwl.c
index efae205..6bb79c5 100644
--- a/dma/nwl.c
+++ b/dma/nwl.c
@@ -1,6 +1,5 @@
#define _PCILIB_DMA_NWL_C
#define _BSD_SOURCE
-//#define DEBUG_HARDWARE
#include <stdio.h>
#include <stdlib.h>
@@ -47,10 +46,9 @@ int dma_nwl_stop(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma
}
if (ctx->engines[dma].preserve) preserving = 1;
- else {
- err = dma_nwl_stop_engine(ctx, dma);
- if (err) return err;
- }
+
+ err = dma_nwl_stop_engine(ctx, dma);
+ if (err) return err;
}
// global cleanup, should we do anything?
@@ -68,9 +66,6 @@ int dma_nwl_stop(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma
ctx->engines[dma].preserve = 0;
}
- // Do not close DMA if preservation mode is set
- if (ctx->engines[dma].preserve) return 0;
-
return dma_nwl_stop_engine(ctx, dma);
}
@@ -138,177 +133,3 @@ void dma_nwl_free(pcilib_dma_context_t *vctx) {
free(ctx);
}
}
-
-
-double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction) {
- int i;
- int res;
- int err;
- size_t bytes;
- uint32_t val;
- uint32_t *buf, *cmp;
- const char *error = NULL;
- pcilib_register_value_t regval;
-
- size_t us = 0;
- struct timeval start, cur;
-
- nwl_dma_t *ctx = (nwl_dma_t*)vctx;
-
- pcilib_dma_engine_t readid = pcilib_find_dma_by_addr(ctx->pcilib, PCILIB_DMA_FROM_DEVICE, dma);
- pcilib_dma_engine_t writeid = pcilib_find_dma_by_addr(ctx->pcilib, PCILIB_DMA_TO_DEVICE, dma);
-
- char *read_base = ctx->engines[readid].base_addr;
- char *write_base = ctx->engines[writeid].base_addr;
-
- if (size%sizeof(uint32_t)) size = 1 + size / sizeof(uint32_t);
- else size /= sizeof(uint32_t);
-
- // Not supported
- if (direction == PCILIB_DMA_TO_DEVICE) return -1.;
- else if ((direction == PCILIB_DMA_FROM_DEVICE)&&(ctx->type != PCILIB_DMA_MODIFICATION_DEFAULT)) return -1.;
-
- // Stop Generators and drain old data
- if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx);
-// dma_nwl_stop_engine(ctx, readid); // DS: replace with something better
-
- __sync_synchronize();
-
- err = pcilib_skip_dma(ctx->pcilib, readid);
- if (err) {
- pcilib_error("Can't start benchmark, devices continuously writes unexpected data using DMA engine");
- return err;
- }
-
-#ifdef NWL_GENERATE_DMA_IRQ
- dma_nwl_enable_engine_irq(ctx, readid);
- dma_nwl_enable_engine_irq(ctx, writeid);
-#endif /* NWL_GENERATE_DMA_IRQ */
-
-
- if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) {
- dma_nwl_start_loopback(ctx, direction, size * sizeof(uint32_t));
- }
-
- // Allocate memory and prepare data
- buf = malloc(size * sizeof(uint32_t));
- cmp = malloc(size * sizeof(uint32_t));
- if ((!buf)||(!cmp)) {
- if (buf) free(buf);
- if (cmp) free(cmp);
- return -1;
- }
-
- memset(cmp, 0x13, size * sizeof(uint32_t));
-
-
-#ifdef DEBUG_HARDWARE
- if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
- pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e5);
- usleep(100000);
- pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1);
- }
-#endif /* DEBUG_HARDWARE */
-
- // Benchmark
- for (i = 0; i < iterations; i++) {
-#ifdef DEBUG_HARDWARE
- if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
- pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1);
- }
-#endif /* DEBUG_HARDWARE */
-
- gettimeofday(&start, NULL);
- if (direction&PCILIB_DMA_TO_DEVICE) {
- memcpy(buf, cmp, size * sizeof(uint32_t));
-
- err = pcilib_write_dma(ctx->pcilib, writeid, addr, size * sizeof(uint32_t), buf, &bytes);
- if ((err)||(bytes != size * sizeof(uint32_t))) {
- error = "Write failed";
- break;
- }
- }
-
-#ifdef DEBUG_HARDWARE
- if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
- //usleep(1000000);
- pcilib_write_register(ctx->pcilib, NULL, "control", 0x3e1);
- }
-
- memset(buf, 0, size * sizeof(uint32_t));
-#endif /* DEBUG_HARDWARE */
-
- err = pcilib_read_dma(ctx->pcilib, readid, addr, size * sizeof(uint32_t), buf, &bytes);
- gettimeofday(&cur, NULL);
- us += ((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec));
-
- if ((err)||(bytes != size * sizeof(uint32_t))) {
- error = "Read failed";
- break;
- }
-
- if (direction == PCILIB_DMA_BIDIRECTIONAL) {
- res = memcmp(buf, cmp, size * sizeof(uint32_t));
- if (res) {
- error = "Written and read values does not match";
- break;
- }
- }
-
-#ifdef DEBUG_HARDWARE
- puts("====================================");
-
- err = pcilib_read_register(ctx->pcilib, NULL, "reg9050", &regval);
- printf("Status1: %i 0x%lx\n", err, regval);
- err = pcilib_read_register(ctx->pcilib, NULL, "reg9080", &regval);
- printf("Start address: %i 0x%lx\n", err, regval);
- err = pcilib_read_register(ctx->pcilib, NULL, "reg9090", &regval);
- printf("End address: %i 0x%lx\n", err, regval);
- err = pcilib_read_register(ctx->pcilib, NULL, "reg9100", &regval);
- printf("Status2: %i 0x%lx\n", err, regval);
- err = pcilib_read_register(ctx->pcilib, NULL, "reg9110", &regval);
- printf("Status3: %i 0x%lx\n", err, regval);
- err = pcilib_read_register(ctx->pcilib, NULL, "reg9160", &regval);
- printf("Add_rd_ddr: %i 0x%lx\n", err, regval);
-#endif /* DEBUG_HARDWARE */
-
- }
-
-#ifdef DEBUG_HARDWARE
- puts("------------------------------------------------");
- err = pcilib_read_register(ctx->pcilib, NULL, "reg9050", &regval);
- printf("Status1: %i 0x%lx\n", err, regval);
- err = pcilib_read_register(ctx->pcilib, NULL, "reg9080", &regval);
- printf("Start address: %i 0x%lx\n", err, regval);
- err = pcilib_read_register(ctx->pcilib, NULL, "reg9090", &regval);
- printf("End address: %i 0x%lx\n", err, regval);
- err = pcilib_read_register(ctx->pcilib, NULL, "reg9100", &regval);
- printf("Status2: %i 0x%lx\n", err, regval);
- err = pcilib_read_register(ctx->pcilib, NULL, "reg9110", &regval);
- printf("Status3: %i 0x%lx\n", err, regval);
- err = pcilib_read_register(ctx->pcilib, NULL, "reg9160", &regval);
- printf("Add_rd_ddr: %i 0x%lx\n", err, regval);
-#endif /* DEBUG_HARDWARE */
-
- if (error) {
- pcilib_warning("%s at iteration %i, error: %i, bytes: %zu", error, i, err, bytes);
- }
-
-#ifdef NWL_GENERATE_DMA_IRQ
- dma_nwl_disable_engine_irq(ctx, writeid);
- dma_nwl_disable_engine_irq(ctx, readid);
-#endif /* NWL_GENERATE_DMA_IRQ */
-
- if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx);
-
- __sync_synchronize();
-
- if (direction == PCILIB_DMA_FROM_DEVICE) {
- pcilib_skip_dma(ctx->pcilib, readid);
- }
-
- free(cmp);
- free(buf);
-
- return error?-1:(1. * size * sizeof(uint32_t) * iterations * 1000000) / (1024. * 1024. * us);
-}
diff --git a/dma/nwl.h b/dma/nwl.h
index 570b36e..7a04dfa 100644
--- a/dma/nwl.h
+++ b/dma/nwl.h
@@ -15,6 +15,9 @@ typedef struct pcilib_nwl_engine_description_s pcilib_nwl_engine_description_t;
#define PCILIB_NWL_DMA_DESCRIPTOR_SIZE 64 // in bytes
#define PCILIB_NWL_DMA_PAGES 512 // 1024
+//#define DEBUG_HARDWARE
+
+
#include "nwl_dma.h"
#include "nwl_irq.h"
#include "nwl_register.h"
diff --git a/dma/nwl_buffers.h b/dma/nwl_buffers.h
index 565eccf..e0df2d0 100644
--- a/dma/nwl_buffers.h
+++ b/dma/nwl_buffers.h
@@ -17,26 +17,36 @@ int dma_nwl_allocate_engine_buffers(nwl_dma_t *ctx, pcilib_nwl_engine_descriptio
int err = 0;
int i;
+ uint16_t sub_use;
uint32_t val;
uint32_t buf_sz;
uint64_t buf_pa;
+ pcilib_kmem_reuse_t reuse_ring, reuse_pages;
char *base = info->base_addr;
if (info->pages) return 0;
-
- pcilib_kmem_handle_t *ring = pcilib_alloc_kernel_memory(ctx->pcilib, PCILIB_KMEM_TYPE_CONSISTENT, 1, PCILIB_NWL_DMA_PAGES * PCILIB_NWL_DMA_DESCRIPTOR_SIZE, PCILIB_NWL_ALIGNMENT, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA, info->desc.addr), 0);
- pcilib_kmem_handle_t *pages = pcilib_alloc_kernel_memory(ctx->pcilib, PCILIB_KMEM_TYPE_PAGE, PCILIB_NWL_DMA_PAGES, 0, 0, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA, info->desc.addr), 0);
+
+ // Or bidirectional specified by 0x0|addr, or read 0x0|addr and write 0x80|addr
+ sub_use = info->desc.addr|(info->desc.direction == PCILIB_DMA_TO_DEVICE)?0x80:0x00;
+ pcilib_kmem_handle_t *ring = pcilib_alloc_kernel_memory(ctx->pcilib, PCILIB_KMEM_TYPE_CONSISTENT, 1, PCILIB_NWL_DMA_PAGES * PCILIB_NWL_DMA_DESCRIPTOR_SIZE, PCILIB_NWL_ALIGNMENT, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, sub_use), PCILIB_KMEM_FLAG_REUSE);
+ pcilib_kmem_handle_t *pages = pcilib_alloc_kernel_memory(ctx->pcilib, PCILIB_KMEM_TYPE_PAGE, PCILIB_NWL_DMA_PAGES, 0, 0, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, sub_use), PCILIB_KMEM_FLAG_REUSE);
if ((ring)&&(pages)) err = dma_nwl_sync_buffers(ctx, info, pages);
else err = PCILIB_ERROR_FAILED;
-
if (err) {
- if (pages) pcilib_free_kernel_memory(ctx->pcilib, pages);
- if (ring) pcilib_free_kernel_memory(ctx->pcilib, ring);
+ if (pages) pcilib_free_kernel_memory(ctx->pcilib, pages, 0);
+ if (ring) pcilib_free_kernel_memory(ctx->pcilib, ring, 0);
return err;
}
+
+/*
+ reuse_ring = pcilib_kmem_is_reused(ctx->pcilib, ring);
+ reuse_pages = pcilib_kmem_is_reused(ctx->pcilib, pages);
+ if ((reuse_ring == PCILIB_KMEM_REUSE_REUSED)&&(reuse_pages == PCILIB_KMEM_REUSE_REUSED)) info->preserve = 1;
+ else if (reuse_ring||reuse_pages) pcilib_warning("Inconsistent buffers in the kernel module are detected");
+*/
unsigned char *data = (unsigned char*)pcilib_kmem_get_ua(ctx->pcilib, ring);
uint32_t ring_pa = pcilib_kmem_get_pa(ctx->pcilib, ring);
diff --git a/dma/nwl_engine.c b/dma/nwl_engine.c
index 11137b9..59e9b93 100644
--- a/dma/nwl_engine.c
+++ b/dma/nwl_engine.c
@@ -65,6 +65,24 @@ int dma_nwl_start_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) {
if (info->started) return 0;
+ // This will only successed if there are no parallel access to DMA engine
+ err = dma_nwl_allocate_engine_buffers(ctx, info);
+ if (err) return err;
+
+ // Check if DMA engine is enabled
+ nwl_read_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS);
+ if (val&DMA_ENG_RUNNING) {
+// info->preserve = 1;
+
+ // We need to positionate buffers correctly (both read and write)
+ //DSS info->tail, info->head
+
+// pcilib_error("Not implemented");
+
+// info->started = 1;
+// return 0;
+ }
+
// Disable IRQs
err = dma_nwl_disable_engine_irq(ctx, dma);
if (err) return err;
@@ -104,9 +122,6 @@ int dma_nwl_start_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) {
nwl_write_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
}
- err = dma_nwl_allocate_engine_buffers(ctx, info);
- if (err) return err;
-
ring_pa = pcilib_kmem_get_pa(ctx->pcilib, info->ring);
nwl_write_register(ring_pa, ctx, info->base_addr, REG_DMA_ENG_NEXT_BD);
nwl_write_register(ring_pa, ctx, info->base_addr, REG_SW_NEXT_BD);
@@ -154,13 +169,16 @@ int dma_nwl_stop_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) {
err = dma_nwl_disable_engine_irq(ctx, dma);
if (err) return err;
- val = DMA_ENG_DISABLE;
- nwl_write_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
+ if (!info->preserve) {
+ // Stopping DMA is not enough reset is required
+ val = DMA_ENG_DISABLE|DMA_ENG_USER_RESET|DMA_ENG_RESET;
+ nwl_write_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
- if (info->ring) {
- ring_pa = pcilib_kmem_get_pa(ctx->pcilib, info->ring);
- nwl_write_register(ring_pa, ctx, info->base_addr, REG_DMA_ENG_NEXT_BD);
- nwl_write_register(ring_pa, ctx, info->base_addr, REG_SW_NEXT_BD);
+ if (info->ring) {
+ ring_pa = pcilib_kmem_get_pa(ctx->pcilib, info->ring);
+ nwl_write_register(ring_pa, ctx, info->base_addr, REG_DMA_ENG_NEXT_BD);
+ nwl_write_register(ring_pa, ctx, info->base_addr, REG_SW_NEXT_BD);
+ }
}
// Acknowledge asserted engine interrupts
@@ -171,15 +189,17 @@ int dma_nwl_stop_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) {
// Clean buffers
if (info->ring) {
- pcilib_free_kernel_memory(ctx->pcilib, info->ring);
+ pcilib_free_kernel_memory(ctx->pcilib, info->ring, info->preserve?PCILIB_KMEM_FLAG_REUSE:0);
info->ring = NULL;
}
if (info->pages) {
- pcilib_free_kernel_memory(ctx->pcilib, info->pages);
+ pcilib_free_kernel_memory(ctx->pcilib, info->pages, info->preserve?PCILIB_KMEM_FLAG_REUSE:0);
info->pages = NULL;
}
+ nwl_read_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS);
+
return 0;
}
diff --git a/dma/nwl_loopback.c b/dma/nwl_loopback.c
index a31bd08..3c2c124 100644
--- a/dma/nwl_loopback.c
+++ b/dma/nwl_loopback.c
@@ -52,3 +52,176 @@ int dma_nwl_stop_loopback(nwl_dma_t *ctx) {
return 0;
}
+
+double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction) {
+ int i;
+ int res;
+ int err;
+ size_t bytes;
+ uint32_t val;
+ uint32_t *buf, *cmp;
+ const char *error = NULL;
+ pcilib_register_value_t regval;
+
+ size_t us = 0;
+ struct timeval start, cur;
+
+ nwl_dma_t *ctx = (nwl_dma_t*)vctx;
+
+ pcilib_dma_engine_t readid = pcilib_find_dma_by_addr(ctx->pcilib, PCILIB_DMA_FROM_DEVICE, dma);
+ pcilib_dma_engine_t writeid = pcilib_find_dma_by_addr(ctx->pcilib, PCILIB_DMA_TO_DEVICE, dma);
+
+ char *read_base = ctx->engines[readid].base_addr;
+ char *write_base = ctx->engines[writeid].base_addr;
+
+ if (size%sizeof(uint32_t)) size = 1 + size / sizeof(uint32_t);
+ else size /= sizeof(uint32_t);
+
+ // Not supported
+ if (direction == PCILIB_DMA_TO_DEVICE) return -1.;
+ else if ((direction == PCILIB_DMA_FROM_DEVICE)&&(ctx->type != PCILIB_DMA_MODIFICATION_DEFAULT)) return -1.;
+
+ // Stop Generators and drain old data
+ if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx);
+// dma_nwl_stop_engine(ctx, readid); // DS: replace with something better
+
+ __sync_synchronize();
+
+ err = pcilib_skip_dma(ctx->pcilib, readid);
+ if (err) {
+ pcilib_error("Can't start benchmark, devices continuously writes unexpected data using DMA engine");
+ return err;
+ }
+
+#ifdef NWL_GENERATE_DMA_IRQ
+ dma_nwl_enable_engine_irq(ctx, readid);
+ dma_nwl_enable_engine_irq(ctx, writeid);
+#endif /* NWL_GENERATE_DMA_IRQ */
+
+
+ if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) {
+ dma_nwl_start_loopback(ctx, direction, size * sizeof(uint32_t));
+ }
+
+ // Allocate memory and prepare data
+ buf = malloc(size * sizeof(uint32_t));
+ cmp = malloc(size * sizeof(uint32_t));
+ if ((!buf)||(!cmp)) {
+ if (buf) free(buf);
+ if (cmp) free(cmp);
+ return -1;
+ }
+
+ memset(cmp, 0x13, size * sizeof(uint32_t));
+
+
+#ifdef DEBUG_HARDWARE
+ if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
+ pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e5);
+ usleep(100000);
+ pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1);
+ }
+#endif /* DEBUG_HARDWARE */
+
+ // Benchmark
+ for (i = 0; i < iterations; i++) {
+#ifdef DEBUG_HARDWARE
+ if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
+ pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1);
+ }
+#endif /* DEBUG_HARDWARE */
+
+ gettimeofday(&start, NULL);
+ if (direction&PCILIB_DMA_TO_DEVICE) {
+ memcpy(buf, cmp, size * sizeof(uint32_t));
+
+ err = pcilib_write_dma(ctx->pcilib, writeid, addr, size * sizeof(uint32_t), buf, &bytes);
+ if ((err)||(bytes != size * sizeof(uint32_t))) {
+ error = "Write failed";
+ break;
+ }
+ }
+
+#ifdef DEBUG_HARDWARE
+ if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
+ //usleep(1000000);
+ pcilib_write_register(ctx->pcilib, NULL, "control", 0x3e1);
+ }
+
+ memset(buf, 0, size * sizeof(uint32_t));
+#endif /* DEBUG_HARDWARE */
+
+ err = pcilib_read_dma(ctx->pcilib, readid, addr, size * sizeof(uint32_t), buf, &bytes);
+ gettimeofday(&cur, NULL);
+ us += ((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec));
+
+ if ((err)||(bytes != size * sizeof(uint32_t))) {
+ error = "Read failed";
+ break;
+ }
+
+ if (direction == PCILIB_DMA_BIDIRECTIONAL) {
+ res = memcmp(buf, cmp, size * sizeof(uint32_t));
+ if (res) {
+ error = "Written and read values does not match";
+ break;
+ }
+ }
+
+#ifdef DEBUG_HARDWARE
+ puts("====================================");
+
+ err = pcilib_read_register(ctx->pcilib, NULL, "reg9050", &regval);
+ printf("Status1: %i 0x%lx\n", err, regval);
+ err = pcilib_read_register(ctx->pcilib, NULL, "reg9080", &regval);
+ printf("Start address: %i 0x%lx\n", err, regval);
+ err = pcilib_read_register(ctx->pcilib, NULL, "reg9090", &regval);
+ printf("End address: %i 0x%lx\n", err, regval);
+ err = pcilib_read_register(ctx->pcilib, NULL, "reg9100", &regval);
+ printf("Status2: %i 0x%lx\n", err, regval);
+ err = pcilib_read_register(ctx->pcilib, NULL, "reg9110", &regval);
+ printf("Status3: %i 0x%lx\n", err, regval);
+ err = pcilib_read_register(ctx->pcilib, NULL, "reg9160", &regval);
+ printf("Add_rd_ddr: %i 0x%lx\n", err, regval);
+#endif /* DEBUG_HARDWARE */
+
+ }
+
+#ifdef DEBUG_HARDWARE
+ puts("------------------------------------------------");
+ err = pcilib_read_register(ctx->pcilib, NULL, "reg9050", &regval);
+ printf("Status1: %i 0x%lx\n", err, regval);
+ err = pcilib_read_register(ctx->pcilib, NULL, "reg9080", &regval);
+ printf("Start address: %i 0x%lx\n", err, regval);
+ err = pcilib_read_register(ctx->pcilib, NULL, "reg9090", &regval);
+ printf("End address: %i 0x%lx\n", err, regval);
+ err = pcilib_read_register(ctx->pcilib, NULL, "reg9100", &regval);
+ printf("Status2: %i 0x%lx\n", err, regval);
+ err = pcilib_read_register(ctx->pcilib, NULL, "reg9110", &regval);
+ printf("Status3: %i 0x%lx\n", err, regval);
+ err = pcilib_read_register(ctx->pcilib, NULL, "reg9160", &regval);
+ printf("Add_rd_ddr: %i 0x%lx\n", err, regval);
+#endif /* DEBUG_HARDWARE */
+
+ if (error) {
+ pcilib_warning("%s at iteration %i, error: %i, bytes: %zu", error, i, err, bytes);
+ }
+
+#ifdef NWL_GENERATE_DMA_IRQ
+ dma_nwl_disable_engine_irq(ctx, writeid);
+ dma_nwl_disable_engine_irq(ctx, readid);
+#endif /* NWL_GENERATE_DMA_IRQ */
+
+ if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx);
+
+ __sync_synchronize();
+
+ if (direction == PCILIB_DMA_FROM_DEVICE) {
+ pcilib_skip_dma(ctx->pcilib, readid);
+ }
+
+ free(cmp);
+ free(buf);
+
+ return error?-1:(1. * size * sizeof(uint32_t) * iterations * 1000000) / (1024. * 1024. * us);
+}
diff --git a/dma/nwl_register.h b/dma/nwl_register.h
index df479e9..926f093 100644
--- a/dma/nwl_register.h
+++ b/dma/nwl_register.h
@@ -56,8 +56,8 @@ static pcilib_register_description_t nwl_dma_engine_registers[] = {
{0x0004, 4, 1, 0, 0x0000C100, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_descriptor_fetch_error", ""},
{0x0004, 5, 1, 0, 0x0000C100, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_sw_abort_error", ""},
{0x0004, 8, 1, 0, 0x0000C100, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_enable", ""},
- {0x0004, 9, 1, 0, 0x0000C100, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_running", ""},
- {0x0004, 10, 1, 0, 0x0000C100, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_waiting", ""},
+ {0x0004, 10, 1, 0, 0x0000C100, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_running", ""},
+ {0x0004, 11, 1, 0, 0x0000C100, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_waiting", ""},
{0x0004, 14, 1, 0, 0x0000C100, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_reset_request", ""},
{0x0004, 15, 1, 0, 0x0000C100, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_reset", ""},
{0x0008, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_next_descriptor", ""},