summaryrefslogtreecommitdiffstats
path: root/dma
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@dside.dyndns.org>2011-07-09 05:33:18 +0200
committerSuren A. Chilingaryan <csa@dside.dyndns.org>2011-07-09 05:33:18 +0200
commit02924fc49641ca9c000054a7a540b6f1eaa0e8f8 (patch)
tree986ba532752d7e19d85f77eea57f15579fe913d5 /dma
parent80d999195b2b1896fcd1878a44b0ece474fe678c (diff)
downloadipecamera-02924fc49641ca9c000054a7a540b6f1eaa0e8f8.tar.gz
ipecamera-02924fc49641ca9c000054a7a540b6f1eaa0e8f8.tar.bz2
ipecamera-02924fc49641ca9c000054a7a540b6f1eaa0e8f8.tar.xz
ipecamera-02924fc49641ca9c000054a7a540b6f1eaa0e8f8.zip
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
Diffstat (limited to 'dma')
-rw-r--r--dma/nwl.c75
-rw-r--r--dma/nwl_register.h94
2 files changed, 161 insertions, 8 deletions
diff --git a/dma/nwl.c b/dma/nwl.c
index f05472c..9d05cd7 100644
--- a/dma/nwl.c
+++ b/dma/nwl.c
@@ -15,20 +15,13 @@
#include "nwl.h"
#include "nwl_defines.h"
+#include "nwl_register.h"
#define NWL_XAUI_ENGINE 0
#define NWL_XRAWDATA_ENGINE 1
#define NWL_FIX_EOP_FOR_BIG_PACKETS // requires precise sizes in read requests
-/*
-pcilib_register_bank_description_t ipecamera_register_banks[] = {
- { PCILIB_REGISTER_DMABANK0, PCILIB_BAR0, 128, PCILIB_DEFAULT_PROTOCOL, DMA_NWL_OFFSET, DMA_NWL_OFFSET, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "%lx", "dma", "NorthWest Logick DMA Engine" },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
-};
-*/
-
-
typedef struct {
pcilib_dma_engine_description_t desc;
@@ -58,6 +51,63 @@ struct nwl_dma_s {
#define nwl_read_register(var, ctx, base, reg) pcilib_datacpy(&var, base + reg, 4, 1, ctx->dma_bank->raw_endianess)
#define nwl_write_register(var, ctx, base, reg) pcilib_datacpy(base + reg, &var, 4, 1, ctx->dma_bank->raw_endianess)
+static int nwl_add_registers(nwl_dma_t *ctx) {
+ int err;
+ size_t n, i, j;
+ int length;
+ const char *names[NWL_MAX_DMA_ENGINE_REGISTERS];
+ uintptr_t addr[NWL_MAX_DMA_ENGINE_REGISTERS];
+
+ // We don't want DMA registers
+ if (pcilib_find_bank_by_addr(ctx->pcilib, PCILIB_REGISTER_BANK_DMA) == PCILIB_REGISTER_BANK_INVALID) return 0;
+
+ err = pcilib_add_registers(ctx->pcilib, 0, nwl_dma_registers);
+ if (err) return err;
+
+ err = pcilib_add_registers(ctx->pcilib, 0, nwl_xrawdata_registers);
+ if (err) return err;
+
+ for (n = 0; nwl_dma_engine_registers[n].bits; n++) {
+ names[n] = nwl_dma_engine_registers[n].name;
+ addr[n] = nwl_dma_engine_registers[n].addr;
+ }
+
+ if (ctx->n_engines > 9) length = 2;
+ else length = 1;
+
+ for (i = 0; i < ctx->n_engines; i++) {
+ for (j = 0; nwl_dma_engine_registers[j].bits; j++) {
+ const char *direction;
+ nwl_dma_engine_registers[j].name = nwl_dma_engine_register_names[i * NWL_MAX_DMA_ENGINE_REGISTERS + j];
+ nwl_dma_engine_registers[j].addr = addr[j] + (ctx->engines[i].base_addr - ctx->base_addr);
+// printf("%lx %lx\n", (ctx->engines[i].base_addr - ctx->base_addr), nwl_dma_engine_registers[j].addr);
+
+ switch (ctx->engines[i].desc.direction) {
+ case PCILIB_DMA_FROM_DEVICE:
+ direction = "r";
+ break;
+ case PCILIB_DMA_TO_DEVICE:
+ direction = "w";
+ break;
+ default:
+ direction = "";
+ }
+
+ sprintf((char*)nwl_dma_engine_registers[j].name, names[j], length, ctx->engines[i].desc.addr, direction);
+ }
+
+ err = pcilib_add_registers(ctx->pcilib, n, nwl_dma_engine_registers);
+ if (err) return err;
+ }
+
+ for (n = 0; nwl_dma_engine_registers[n].bits; n++) {
+ nwl_dma_engine_registers[n].name = names[n];
+ nwl_dma_engine_registers[n].addr = addr[n];
+ }
+
+ return 0;
+}
+
static int nwl_read_engine_config(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, char *base) {
uint32_t val;
@@ -101,6 +151,7 @@ static int nwl_stop_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) {
pcilib_nwl_engine_description_t *info = ctx->engines + dma;
char *base = ctx->engines[dma].base_addr;
+ return 0;
if (info->desc.addr == NWL_XRAWDATA_ENGINE) {
// Stop Generators
nwl_read_register(val, ctx, ctx->base_addr, TX_CONFIG_ADDRESS);
@@ -182,6 +233,7 @@ pcilib_dma_context_t *dma_nwl_init(pcilib_t *pcilib) {
pcilib_register_bank_t dma_bank = pcilib_find_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA);
if (dma_bank == PCILIB_REGISTER_BANK_INVALID) {
+ free(ctx);
pcilib_error("DMA Register Bank could not be found");
return NULL;
}
@@ -210,6 +262,13 @@ pcilib_dma_context_t *dma_nwl_init(pcilib_t *pcilib) {
pcilib_set_dma_engine_description(pcilib, n_engines, NULL);
ctx->n_engines = n_engines;
+
+ err = nwl_add_registers(ctx);
+ if (err) {
+ free(ctx);
+ pcilib_error("Failed to add DMA registers");
+ return NULL;
+ }
}
return (pcilib_dma_context_t*)ctx;
}
diff --git a/dma/nwl_register.h b/dma/nwl_register.h
new file mode 100644
index 0000000..86515cc
--- /dev/null
+++ b/dma/nwl_register.h
@@ -0,0 +1,94 @@
+/*
+pcilib_register_bank_description_t ipecamera_register_banks[] = {
+ { PCILIB_REGISTER_DMABANK0, PCILIB_BAR0, 128, PCILIB_DEFAULT_PROTOCOL, DMA_NWL_OFFSET, DMA_NWL_OFFSET, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "%lx", "dma", "NorthWest Logick DMA Engine" },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
+};
+*/
+
+ // DMA
+static pcilib_register_description_t nwl_dma_registers[] = {
+ {0x4000, 0, 32, 0, 0x00000011, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_control_and_status", ""},
+ {0x4000, 0, 1, 0, 0x00000011, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_interrupt_enable", ""},
+ {0x4000, 1, 1, 0, 0x00000011, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_interrupt_active", ""},
+ {0x4000, 2, 1, 0, 0x00000011, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_interrupt_pending", ""},
+ {0x4000, 3, 1, 0, 0x00000011, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_interrupt_mode", ""},
+ {0x4000, 4, 1, 0, 0x00000011, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_user_interrupt_enable", ""},
+ {0x4000, 5, 1, 0, 0x00000011, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_user_interrupt_active", ""},
+ {0x4000, 16, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_s2c_interrupt_status", ""},
+ {0x4000, 24, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_c2s_interrupt_status", ""},
+ {0x8000, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_design_version", ""},
+ {0x8000, 0, 4, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_subversion_number", ""},
+ {0x8000, 4, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_version_number", ""},
+ {0x8000, 28, 4, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_targeted_device", ""},
+ {0x8200, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_transmit_utilization", ""},
+ {0x8200, 0, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_transmit_sample_count", ""},
+ {0x8200, 2, 30, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_transmit_dword_count", ""},
+ {0x8204, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_receive_utilization", ""},
+ {0x8004, 0, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_receive_sample_count", ""},
+ {0x8004, 2, 30, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_receive_dword_count", ""},
+ {0x8208, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_mwr", ""},
+ {0x8008, 0, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_mwr_sample_count", ""},
+ {0x8008, 2, 30, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_mwr_dword_count", ""},
+ {0x820C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_cpld", ""},
+ {0x820C, 0, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_cpld_sample_count", ""},
+ {0x820C, 2, 30, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma_cpld_dword_count", ""},
+ {0x8210, 0, 12, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_cpld", ""},
+ {0x8214, 0, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_cplh", ""},
+ {0x8218, 0, 12, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_npd", ""},
+ {0x821C, 0, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_nph", ""},
+ {0x8220, 0, 12, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_pd", ""},
+ {0x8224, 0, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_init_fc_ph", ""},
+ {0, 0, 0, 0, 0x00000000, 0, 0, 0, NULL, NULL}
+};
+
+ // DMA Engine Registers
+#define NWL_MAX_DMA_ENGINE_REGISTERS 64
+#define NWL_MAX_REGISTER_NAME 128
+static char nwl_dma_engine_register_names[PCILIB_MAX_DMA_ENGINES * NWL_MAX_DMA_ENGINE_REGISTERS][NWL_MAX_REGISTER_NAME];
+static pcilib_register_description_t nwl_dma_engine_registers[] = {
+ {0x0000, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_engine_capabilities", ""},
+ {0x0000, 0, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_present", ""},
+ {0x0000, 1, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_direction", ""},
+ {0x0000, 4, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_type", ""},
+ {0x0000, 8, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_number", ""},
+ {0x0000, 24, 6, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_max_buffer_size", ""},
+ {0x0004, 0, 32, 0, 0x0000C100, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_engine_control", ""},
+ {0x0004, 0, 1, 0, 0x0000C100, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_interrupt_enable", ""},
+ {0x0004, 1, 1, 0, 0x0000C100, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_interrupt_active", ""},
+ {0x0004, 2, 1, 0, 0x0000C100, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_descriptor_complete", ""},
+ {0x0004, 3, 1, 0, 0x0000C100, PCILIB_REGISTER_RW1C, PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_descriptor_alignment_error", ""},
+ {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, 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", ""},
+ {0x000C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_sw_descriptor", ""},
+ {0x0010, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_last_descriptor", ""},
+ {0x0014, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_active_time", ""},
+ {0x0018, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_wait_time", ""},
+ {0x001C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_counter", ""},
+ {0x001C, 0, 2, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_sample_count", ""},
+ {0x001C, 2, 30, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "dma%0*u%s_dword_count", ""},
+ {0, 0, 0, 0, 0x00000000, 0, 0, 0, NULL, NULL}
+};
+
+/*
+ // XAUI registers
+static pcilib_register_description_t nwl_xaui_registers[] = {
+ {0, 0, 0, 0, 0, 0, 0, NULL, NULL}
+};
+*/
+
+ // XRAWDATA registers
+static pcilib_register_description_t nwl_xrawdata_registers[] = {
+ {0x9100, 0, 1, 0, 0x00000000, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "xrawdata_enable_generator", ""},
+ {0x9104, 0, 16, 0, 0x00000000, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "xrawdata_packet_length", ""},
+ {0x9108, 0, 2, 0, 0x00000003, PCILIB_REGISTER_RW, PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "xrawdata_control", ""},
+ {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", ""},
+ {0, 0, 0, 0, 0x00000000, 0, 0, 0, NULL, NULL}
+};