Forráskód Böngészése

Support modifications of DMA engine and allow DMA customizations by Event engine

Suren A. Chilingaryan 13 éve
szülő
commit
b492b1aac3
12 módosított fájl, 123 hozzáadás és 96 törlés
  1. 7 5
      dma.c
  2. 5 1
      dma.h
  3. 70 83
      dma/nwl.c
  4. 2 0
      dma/nwl.h
  5. 3 1
      dma/nwl_dma.h
  6. 6 5
      dma/nwl_loopback.c
  7. 8 0
      dma/nwl_register.h
  8. 3 0
      event.h
  9. 15 0
      ipecamera/image.c
  10. 1 0
      ipecamera/image.h
  11. 2 1
      ipecamera/model.h
  12. 1 0
      pci.h

+ 7 - 5
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;

+ 5 - 1
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);

+ 70 - 83
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();
     

+ 2 - 0
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;
 

+ 3 - 1
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);

+ 6 - 5
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;
 }

+ 8 - 0
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}
 };
 

+ 3 - 0
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);
+
 };
 
 

+ 15 - 0
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");

+ 1 - 0
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 */

+ 2 - 1
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;

+ 1 - 0
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"