summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@dside.dyndns.org>2011-07-14 01:44:10 +0200
committerSuren A. Chilingaryan <csa@dside.dyndns.org>2011-07-14 01:44:10 +0200
commitb492b1aac3d12683ccbc973b08b023ba0466cbec (patch)
tree09f6d3d0cc3725b62a5c9210220e14316b737622
parent9f17f71885344d93b16fdc17458aa28ba350a480 (diff)
downloadipecamera-b492b1aac3d12683ccbc973b08b023ba0466cbec.tar.gz
ipecamera-b492b1aac3d12683ccbc973b08b023ba0466cbec.tar.bz2
ipecamera-b492b1aac3d12683ccbc973b08b023ba0466cbec.tar.xz
ipecamera-b492b1aac3d12683ccbc973b08b023ba0466cbec.zip
Support modifications of DMA engine and allow DMA customizations by Event engine
-rw-r--r--dma.c12
-rw-r--r--dma.h6
-rw-r--r--dma/nwl.c153
-rw-r--r--dma/nwl.h2
-rw-r--r--dma/nwl_dma.h4
-rw-r--r--dma/nwl_loopback.c11
-rw-r--r--dma/nwl_register.h8
-rw-r--r--event.h3
-rw-r--r--ipecamera/image.c15
-rw-r--r--ipecamera/image.h1
-rw-r--r--ipecamera/model.h3
-rw-r--r--pci.h1
12 files changed, 123 insertions, 96 deletions
diff --git a/dma.c b/dma.c
index 7e06b2e..45466b7 100644
--- a/dma.c
+++ b/dma.c
@@ -20,12 +20,14 @@
const pcilib_dma_info_t *pcilib_get_dma_info(pcilib_t *ctx) {
if (!ctx->dma_ctx) {
- pcilib_model_t model = pcilib_get_model(ctx);
- pcilib_dma_api_description_t *api = pcilib_model[model].dma_api;
-
- if ((api)&&(api->init)) {
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
+
+ if ((ctx->event_ctx)&&(model_info->event_api->init_dma)) {
+ pcilib_map_register_space(ctx);
+ ctx->dma_ctx = model_info->event_api->init_dma(ctx->event_ctx);
+ } else if ((model_info->dma_api)&&(model_info->dma_api->init)) {
pcilib_map_register_space(ctx);
- ctx->dma_ctx = api->init(ctx);
+ ctx->dma_ctx = model_info->dma_api->init(ctx, PCILIB_DMA_MODIFICATION_DEFAULT, NULL);
}
if (!ctx->dma_ctx) return NULL;
diff --git a/dma.h b/dma.h
index 1685403..0260872 100644
--- a/dma.h
+++ b/dma.h
@@ -2,9 +2,13 @@
#define _PCILIB_DMA_H
#define PCILIB_DMA_BUFFER_INVALID ((size_t)-1)
+#define PCILIB_DMA_MODIFICATION_DEFAULT 0 /**< first 0x100 are reserved */
+
+typedef uint32_t pcilib_dma_modification_t;
+
struct pcilib_dma_api_description_s {
- pcilib_dma_context_t *(*init)(pcilib_t *ctx);
+ pcilib_dma_context_t *(*init)(pcilib_t *ctx, pcilib_dma_modification_t type, void *arg);
void (*free)(pcilib_dma_context_t *ctx);
int (*enable_irq)(pcilib_dma_context_t *ctx, pcilib_irq_type_t irq_type, pcilib_dma_flags_t flags);
diff --git a/dma/nwl.c b/dma/nwl.c
index b48e0a4..efae205 100644
--- a/dma/nwl.c
+++ b/dma/nwl.c
@@ -1,5 +1,6 @@
#define _PCILIB_DMA_NWL_C
#define _BSD_SOURCE
+//#define DEBUG_HARDWARE
#include <stdio.h>
#include <stdlib.h>
@@ -74,7 +75,7 @@ int dma_nwl_stop(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma
}
-pcilib_dma_context_t *dma_nwl_init(pcilib_t *pcilib) {
+pcilib_dma_context_t *dma_nwl_init(pcilib_t *pcilib, pcilib_dma_modification_t type, void *arg) {
int i;
int err;
uint32_t val;
@@ -86,6 +87,7 @@ pcilib_dma_context_t *dma_nwl_init(pcilib_t *pcilib) {
if (ctx) {
memset(ctx, 0, sizeof(nwl_dma_t));
ctx->pcilib = pcilib;
+ ctx->type = type;
pcilib_register_bank_t dma_bank = pcilib_find_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA);
if (dma_bank == PCILIB_REGISTER_BANK_INVALID) {
@@ -129,7 +131,7 @@ void dma_nwl_free(pcilib_dma_context_t *vctx) {
nwl_dma_t *ctx = (nwl_dma_t*)vctx;
if (ctx) {
- dma_nwl_stop_loopback(ctx);
+ if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx);
dma_nwl_free_irq(ctx);
dma_nwl_stop(ctx, PCILIB_DMA_ENGINE_ALL, PCILIB_DMA_FLAGS_DEFAULT);
@@ -164,14 +166,19 @@ double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dm
// 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
- dma_nwl_stop_loopback(ctx);
+ 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();
- pcilib_skip_dma(ctx->pcilib, readid);
+ 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);
@@ -179,23 +186,9 @@ double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dm
#endif /* NWL_GENERATE_DMA_IRQ */
- dma_nwl_start_loopback(ctx, direction, size * sizeof(uint32_t));
-
-/*
- printf("Packet size: %li\n", size * sizeof(uint32_t));
- pcilib_read_register(ctx->pcilib, NULL, "dma1w_counter", &regval);
- printf("Count write: %lx\n", regval);
-
- nwl_read_register(val, ctx, read_base, REG_DMA_ENG_CTRL_STATUS);
- printf("Read DMA control: %lx\n", val);
- nwl_read_register(val, ctx, write_base, REG_DMA_ENG_CTRL_STATUS);
- printf("Write DMA control: %lx\n", val);
-
- nwl_read_register(val, ctx, write_base, REG_DMA_ENG_NEXT_BD);
- printf("Pointer1: %lx\n", val);
- nwl_read_register(val, ctx, write_base, REG_SW_NEXT_BD);
- printf("Pointer2: %lx\n", val);
-*/
+ 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));
@@ -208,12 +201,22 @@ double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dm
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++) {
-// puts("====================================");
- pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1);
-// pcilib_read_register(ctx->pcilib, NULL, "control", &regval);
-// printf("Control: %lx\n", regval);
+#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) {
@@ -225,57 +228,21 @@ double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dm
break;
}
}
-/*
- printf("RegRead: %i\n",pcilib_read_register(ctx->pcilib, NULL, "dma1w_counter", &regval));
- printf("Count write (%i of %i): %lx\n", i, iterations, regval);
- printf("RegRead: %i\n",pcilib_read_register(ctx->pcilib, NULL, "dma1r_counter", &regval));
- printf("Count read (%i of %i): %lx\n", i, iterations, regval);
-
-
- nwl_read_register(val, ctx, read_base, REG_DMA_ENG_COMP_BYTES);
- printf("Compl Bytes (read): %lx\n", val);
-
- nwl_read_register(val, ctx, write_base, REG_DMA_ENG_COMP_BYTES);
- printf("Compl Bytes (write): %lx\n", val);
-
- nwl_read_register(val, ctx, read_base, REG_DMA_ENG_CTRL_STATUS);
- printf("Read DMA control (after write): %lx\n", val);
-*/
-/*
- nwl_read_register(val, ctx, read_base, REG_DMA_ENG_CTRL_STATUS);
- printf("Read DMA control (after write): %lx\n", val);
- nwl_read_register(val, ctx, write_base, REG_DMA_ENG_CTRL_STATUS);
- printf("Write DMA control (after write): %lx\n", val);
-*/
- pcilib_write_register(ctx->pcilib, NULL, "control", 0x3e1);
-// pcilib_read_register(ctx->pcilib, NULL, "control", &regval);
-// printf("Control: %lx\n", regval);
+#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))) {
-/*
- nwl_read_register(val, ctx, read_base, REG_DMA_ENG_CTRL_STATUS);
- printf("Read DMA control: %lx\n", val);
- nwl_read_register(val, ctx, write_base, REG_DMA_ENG_CTRL_STATUS);
- printf("Write DMA control: %lx\n", val);
- nwl_read_register(val, ctx, write_base, REG_DMA_ENG_NEXT_BD);
- printf("After Pointer wr1: %lx\n", val);
- nwl_read_register(val, ctx, write_base, REG_SW_NEXT_BD);
- printf("After Pointer wr2: %lx\n", val);
- pcilib_read_register(ctx->pcilib, NULL, "end_address", &regval);
- printf("End address: %lx\n", regval);
-
- nwl_read_register(val, ctx, read_base, REG_DMA_ENG_NEXT_BD);
- printf("After Pointer read1: %lx\n", val);
- nwl_read_register(val, ctx, read_base, REG_SW_NEXT_BD);
- printf("After Pointer read2: %lx\n", val);
-*/
error = "Read failed";
break;
}
@@ -287,32 +254,52 @@ double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dm
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);
}
-/*
- puts("Finished...");
- nwl_read_register(val, ctx, read_base, REG_DMA_ENG_NEXT_BD);
- printf("After Pointer read1: %lx\n", val);
- nwl_read_register(val, ctx, read_base, REG_SW_NEXT_BD);
- printf("After Pointer read2: %lx\n", val);
-
- nwl_read_register(val, ctx, write_base, REG_DMA_ENG_NEXT_BD);
- printf("After Pointer wr1: %lx\n", val);
- nwl_read_register(val, ctx, write_base, REG_SW_NEXT_BD);
- printf("After Pointer wr2: %lx\n", val);
-*/
-
#ifdef NWL_GENERATE_DMA_IRQ
dma_nwl_disable_engine_irq(ctx, writeid);
dma_nwl_disable_engine_irq(ctx, readid);
#endif /* NWL_GENERATE_DMA_IRQ */
- dma_nwl_stop_loopback(ctx);
+ if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx);
__sync_synchronize();
diff --git a/dma/nwl.h b/dma/nwl.h
index 6d86e86..570b36e 100644
--- a/dma/nwl.h
+++ b/dma/nwl.h
@@ -42,6 +42,8 @@ struct pcilib_nwl_engine_description_s {
struct nwl_dma_s {
pcilib_t *pcilib;
+ pcilib_dma_modification_t type;
+
pcilib_register_bank_description_t *dma_bank;
char *base_addr;
diff --git a/dma/nwl_dma.h b/dma/nwl_dma.h
index 883dc29..bdb3df0 100644
--- a/dma/nwl_dma.h
+++ b/dma/nwl_dma.h
@@ -4,7 +4,9 @@
#include <stdio.h>
#include "pcilib.h"
-pcilib_dma_context_t *dma_nwl_init(pcilib_t *ctx);
+#define PCILIB_NWL_MODIFICATION_IPECAMERA 0x100
+
+pcilib_dma_context_t *dma_nwl_init(pcilib_t *ctx, pcilib_dma_modification_t type, void *arg);
void dma_nwl_free(pcilib_dma_context_t *vctx);
int dma_nwl_enable_irq(pcilib_dma_context_t *vctx, pcilib_irq_type_t type, pcilib_dma_flags_t flags);
diff --git a/dma/nwl_loopback.c b/dma/nwl_loopback.c
index 9c74b14..a31bd08 100644
--- a/dma/nwl_loopback.c
+++ b/dma/nwl_loopback.c
@@ -43,11 +43,12 @@ int dma_nwl_start_loopback(nwl_dma_t *ctx, pcilib_dma_direction_t direction, si
int dma_nwl_stop_loopback(nwl_dma_t *ctx) {
uint32_t val = 0;
- if (ctx->loopback_started) {
- nwl_write_register(val, ctx, ctx->base_addr, TX_CONFIG_ADDRESS);
- nwl_write_register(val, ctx, ctx->base_addr, RX_CONFIG_ADDRESS);
- ctx->loopback_started = 0;
- }
+ /* Stop in any case, otherwise we can have problems in benchmark due to
+ engine initialized in previous run, and benchmark is only actual usage.
+ Otherwise, we should detect current loopback status during initialization */
+ nwl_write_register(val, ctx, ctx->base_addr, TX_CONFIG_ADDRESS);
+ nwl_write_register(val, ctx, ctx->base_addr, RX_CONFIG_ADDRESS);
+ ctx->loopback_started = 0;
return 0;
}
diff --git a/dma/nwl_register.h b/dma/nwl_register.h
index bffc1bf..df479e9 100644
--- a/dma/nwl_register.h
+++ b/dma/nwl_register.h
@@ -86,6 +86,14 @@ static pcilib_register_description_t nwl_xrawdata_registers[] = {
{0x9108, 0, 1, 0, 0x00000003, PCILIB_REGISTER_RW, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "xrawdata_enable_checker", ""},
{0x9108, 1, 1, 0, 0x00000003, PCILIB_REGISTER_RW, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "xrawdata_enable_loopback", ""},
{0x910C, 0, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "xrawdata_data_mistmatch", ""},
+#ifdef DEBUG_HARDWARE
+ {0x9050, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "reg9050", ""},
+ {0x9080, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "reg9080", ""},
+ {0x9090, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "reg9090", ""},
+ {0x9100, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "reg9100", ""},
+ {0x9110, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "reg9110", ""},
+ {0x9160, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "reg9160", ""},
+#endif /* DEBUG_HARDWARE */
{0, 0, 0, 0, 0x00000000, 0, 0, 0, NULL, NULL}
};
diff --git a/event.h b/event.h
index 720271c..c6432be 100644
--- a/event.h
+++ b/event.h
@@ -16,6 +16,9 @@ struct pcilib_event_api_description_s {
pcilib_event_id_t (*next_event)(pcilib_context_t *ctx, pcilib_event_t event_mask, const struct timespec *timeout);
void* (*get_data)(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size);
int (*return_data)(pcilib_context_t *ctx, pcilib_event_id_t event_id);
+
+ pcilib_dma_context_t *(*init_dma)(pcilib_context_t *ctx);
+
};
diff --git a/ipecamera/image.c b/ipecamera/image.c
index bf5faf9..3d1056d 100644
--- a/ipecamera/image.c
+++ b/ipecamera/image.c
@@ -16,6 +16,8 @@
#include "model.h"
#include "image.h"
+#include "dma/nwl_dma.h"
+
#define IPECAMERA_SLEEP_TIME 250000
#define IPECAMERA_MAX_LINES 1088
#define IPECAMERA_DEFAULT_BUFFER_SIZE 10
@@ -171,6 +173,19 @@ void ipecamera_free(pcilib_context_t *vctx) {
}
}
+pcilib_dma_context_t *ipecamera_init_dma(pcilib_context_t *vctx) {
+ ipecamera_t *ctx = (ipecamera_t*)vctx;
+
+ pcilib_model_description_t *model_info = pcilib_get_model_description(ctx->pcilib);
+ if ((!model_info->dma_api)||(!model_info->dma_api->init)) {
+ pcilib_error("The DMA engine is not configured in model");
+ return NULL;
+ }
+
+ return model_info->dma_api->init(ctx->pcilib, PCILIB_DMA_MODIFICATION_DEFAULT, NULL);
+}
+
+
int ipecamera_set_buffer_size(ipecamera_t *ctx, int size) {
if (ctx->started) {
pcilib_error("Can't change buffer size while grabbing");
diff --git a/ipecamera/image.h b/ipecamera/image.h
index 6863d09..4bac673 100644
--- a/ipecamera/image.h
+++ b/ipecamera/image.h
@@ -18,6 +18,7 @@ pcilib_event_id_t ipecamera_next_event(pcilib_context_t *ctx, pcilib_event_t eve
void* ipecamera_get(pcilib_context_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size);
int ipecamera_return(pcilib_context_t *ctx, pcilib_event_id_t event_id);
+pcilib_dma_context_t *ipecamera_init_dma(pcilib_context_t *ctx);
#endif /* _IPECAMERA_IMAGE_H */
diff --git a/ipecamera/model.h b/ipecamera/model.h
index da0ac12..a460dde 100644
--- a/ipecamera/model.h
+++ b/ipecamera/model.h
@@ -109,7 +109,8 @@ pcilib_event_api_description_t ipecamera_image_api = {
ipecamera_next_event,
ipecamera_get,
- ipecamera_return
+ ipecamera_return,
+ ipecamera_init_dma
};
#else
extern pcilib_event_api_description_t ipecamera_image_api;
diff --git a/pci.h b/pci.h
index 2115134..cdd380b 100644
--- a/pci.h
+++ b/pci.h
@@ -2,6 +2,7 @@
#define _PCITOOL_PCI_H
#define PCILIB_DMA_TIMEOUT 10000 /**< us */
+#define PCILIB_DMA_SKIP_TIMEOUT 1000000 /**< us */
#define PCILIB_REGISTER_TIMEOUT 10000 /**< us */
#include "driver/pciDriver.h"