diff options
author | Suren A. Chilingaryan <csa@suren.me> | 2015-04-20 22:01:04 +0200 |
---|---|---|
committer | Suren A. Chilingaryan <csa@suren.me> | 2015-04-20 22:01:04 +0200 |
commit | 77c4d6e67debf0e729734d882df033c4c0f5b0c3 (patch) | |
tree | 4a59e86332d6cc78fc5c97110ecba281b0f67bc9 /dma | |
parent | 0002c0cc260a6a8e2b6c53f19ae99a625eca4355 (diff) | |
download | pcitool-77c4d6e67debf0e729734d882df033c4c0f5b0c3.tar.gz pcitool-77c4d6e67debf0e729734d882df033c4c0f5b0c3.tar.bz2 pcitool-77c4d6e67debf0e729734d882df033c4c0f5b0c3.tar.xz pcitool-77c4d6e67debf0e729734d882df033c4c0f5b0c3.zip |
Big redign of model structures
Diffstat (limited to 'dma')
-rw-r--r-- | dma/CMakeLists.txt | 6 | ||||
-rw-r--r-- | dma/ipe.c | 83 | ||||
-rw-r--r-- | dma/ipe.h | 61 | ||||
-rw-r--r-- | dma/ipe_private.h | 10 | ||||
-rw-r--r-- | dma/ipe_registers.h | 44 | ||||
-rw-r--r-- | dma/nwl.c | 115 | ||||
-rw-r--r-- | dma/nwl.h | 101 | ||||
-rw-r--r-- | dma/nwl_engine.c | 136 | ||||
-rw-r--r-- | dma/nwl_engine.h | 2 | ||||
-rw-r--r-- | dma/nwl_engine_buffers.h | 200 | ||||
-rw-r--r-- | dma/nwl_irq.c | 10 | ||||
-rw-r--r-- | dma/nwl_irq.h | 6 | ||||
-rw-r--r-- | dma/nwl_loopback.c | 44 | ||||
-rw-r--r-- | dma/nwl_loopback.h | 6 | ||||
-rw-r--r-- | dma/nwl_private.h | 32 | ||||
-rw-r--r-- | dma/nwl_register.c | 77 | ||||
-rw-r--r-- | dma/nwl_register.h | 97 |
17 files changed, 498 insertions, 532 deletions
diff --git a/dma/CMakeLists.txt b/dma/CMakeLists.txt index 44bf18c..9bbfacd 100644 --- a/dma/CMakeLists.txt +++ b/dma/CMakeLists.txt @@ -3,7 +3,9 @@ include_directories( ) -set(HEADERS ${HEADERS} nwl.h nwl_private.h nwl_engine.h nwl_irq.h nwl_loopback.h nwl_register.h ipe.h ipe_private.h ipe_registers.h) +set(HEADERS ${HEADERS} nwl.h nwl_private.h nwl_engine.h nwl_irq.h nwl_loopback.h ipe.h ipe_private.h) -add_library(dma STATIC nwl.c nwl_engine.c nwl_irq.c nwl_loopback.c nwl_register.c ipe.c) +add_library(dma STATIC nwl.c nwl_engine.c nwl_irq.c nwl_loopback.c ipe.c) +#set(HEADERS ${HEADERS} ipe.h ipe_private.h) +#add_library(dma STATIC ipe.c) @@ -15,25 +15,25 @@ #include "ipe.h" #include "ipe_private.h" -#include "ipe_registers.h" #define WR(addr, value) { *(uint32_t*)(ctx->base_addr + addr) = value; } #define RD(addr, value) { value = *(uint32_t*)(ctx->base_addr + addr); } -pcilib_dma_context_t *dma_ipe_init(pcilib_t *pcilib, pcilib_dma_modification_t type, void *arg) { - int err = 0; +pcilib_dma_context_t *dma_ipe_init(pcilib_t *pcilib, const char *model, const void *arg) { +// int err = 0; - pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib); + const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib); ipe_dma_t *ctx = malloc(sizeof(ipe_dma_t)); if (ctx) { memset(ctx, 0, sizeof(ipe_dma_t)); - ctx->pcilib = pcilib; + ctx->dmactx.pcilib = pcilib; // ctx->mode64 = 1; - + +/* memset(ctx->engine, 0, 2 * sizeof(pcilib_dma_engine_description_t)); ctx->engine[0].addr = 0; ctx->engine[0].type = PCILIB_DMA_TYPE_PACKET; @@ -41,8 +41,21 @@ pcilib_dma_context_t *dma_ipe_init(pcilib_t *pcilib, pcilib_dma_modification_t t ctx->engine[0].addr_bits = 32; pcilib_set_dma_engine_description(pcilib, 0, &ctx->engine[0]); pcilib_set_dma_engine_description(pcilib, 1, NULL); +*/ + + pcilib_register_bank_t dma_bank = pcilib_find_register_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA); +/* + if (dma_bank == PCILIB_REGISTER_BANK_INVALID) { + err = pcilib_add_register_banks(ctx->pcilib, 0, ipe_dma_register_banks); + if (err) { + free(ctx); + pcilib_error("Error (%i) adding DMA register bank"); + return NULL; + } + } - pcilib_register_bank_t dma_bank = pcilib_find_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA); + 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"); @@ -52,12 +65,14 @@ pcilib_dma_context_t *dma_ipe_init(pcilib_t *pcilib, pcilib_dma_modification_t t ctx->dma_bank = model_info->banks + dma_bank; ctx->base_addr = pcilib_resolve_register_address(pcilib, ctx->dma_bank->bar, ctx->dma_bank->read_addr); +/* err = pcilib_add_registers(ctx->pcilib, 0, ipe_dma_registers); if (err) { free(ctx); pcilib_error("Error adding DMA registers"); return NULL; } +*/ } return (pcilib_dma_context_t*)ctx; @@ -100,16 +115,16 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm if (ctx->pages) return 0; 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->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->pcilib, PCILIB_KMEM_TYPE_DMA_C2S_PAGE, IPEDMA_DMA_PAGES, 0, 0, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, 0x00), kflags); + 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, IPEDMA_DMA_PAGES, 0, 0, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, 0x00), kflags); if (!desc||!pages) { - if (pages) pcilib_free_kernel_memory(ctx->pcilib, pages, 0); - if (desc) pcilib_free_kernel_memory(ctx->pcilib, desc, 0); + if (pages) pcilib_free_kernel_memory(ctx->dmactx.pcilib, pages, 0); + if (desc) pcilib_free_kernel_memory(ctx->dmactx.pcilib, desc, 0); return PCILIB_ERROR_MEMORY; } - reuse_desc = pcilib_kmem_is_reused(ctx->pcilib, desc); - reuse_pages = pcilib_kmem_is_reused(ctx->pcilib, pages); + reuse_desc = pcilib_kmem_is_reused(ctx->dmactx.pcilib, desc); + reuse_pages = pcilib_kmem_is_reused(ctx->dmactx.pcilib, pages); if (reuse_desc == reuse_pages) { if (reuse_desc & PCILIB_KMEM_REUSE_PARTIAL) pcilib_warning("Inconsistent DMA buffers are found (only part of required buffers is available), reinitializing..."); @@ -128,7 +143,7 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm } } else pcilib_warning("Inconsistent DMA buffers (modes of ring and page buffers does not match), reinitializing...."); - desc_va = pcilib_kmem_get_ua(ctx->pcilib, desc); + desc_va = pcilib_kmem_get_ua(ctx->dmactx.pcilib, desc); if (ctx->mode64) last_written_addr_ptr = desc_va + 3 * sizeof(uint32_t); else last_written_addr_ptr = desc_va + 4 * sizeof(uint32_t); @@ -186,14 +201,14 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm // Setting current read position and configuring progress register WR(IPEDMA_REG_LAST_READ, IPEDMA_DMA_PAGES); - WR(IPEDMA_REG_UPDATE_ADDR, pcilib_kmem_get_block_ba(ctx->pcilib, desc, 0)); + WR(IPEDMA_REG_UPDATE_ADDR, pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, desc, 0)); // Instructing DMA engine that writting should start from the first DMA page - *last_written_addr_ptr = 0;//htonl(pcilib_kmem_get_block_ba(ctx->pcilib, pages, IPEDMA_DMA_PAGES - 1)); + *last_written_addr_ptr = 0;//htonl(pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, pages, IPEDMA_DMA_PAGES - 1)); for (i = 0; i < IPEDMA_DMA_PAGES; i++) { - uintptr_t bus_addr_check, bus_addr = pcilib_kmem_get_block_ba(ctx->pcilib, pages, i); + uintptr_t bus_addr_check, bus_addr = pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, pages, i); WR(IPEDMA_REG_PAGE_ADDR, bus_addr); if (bus_addr%4096) printf("Bad address %lu: %lx\n", i, bus_addr); @@ -219,13 +234,13 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm #endif /* IPEDMA_BUG_DMARD */ } -// ctx->last_read_addr = htonl(pcilib_kmem_get_block_ba(ctx->pcilib, pages, ctx->last_read)); - ctx->last_read_addr = pcilib_kmem_get_block_ba(ctx->pcilib, pages, ctx->last_read); +// ctx->last_read_addr = htonl(pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, pages, ctx->last_read)); + ctx->last_read_addr = pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, pages, ctx->last_read); ctx->desc = desc; ctx->pages = pages; - ctx->page_size = pcilib_kmem_get_block_size(ctx->pcilib, pages, 0);; + ctx->page_size = pcilib_kmem_get_block_size(ctx->dmactx.pcilib, pages, 0);; ctx->ring_size = IPEDMA_DMA_PAGES; return 0; @@ -269,12 +284,12 @@ int dma_ipe_stop(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma // Clean buffers if (ctx->desc) { - pcilib_free_kernel_memory(ctx->pcilib, ctx->desc, kflags); + pcilib_free_kernel_memory(ctx->dmactx.pcilib, ctx->desc, kflags); ctx->desc = NULL; } if (ctx->pages) { - pcilib_free_kernel_memory(ctx->pcilib, ctx->pages, kflags); + pcilib_free_kernel_memory(ctx->dmactx.pcilib, ctx->pages, kflags); ctx->pages = NULL; } @@ -286,7 +301,7 @@ int dma_ipe_get_status(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcil size_t i; ipe_dma_t *ctx = (ipe_dma_t*)vctx; - void *desc_va = (void*)pcilib_kmem_get_ua(ctx->pcilib, ctx->desc); + void *desc_va = (void*)pcilib_kmem_get_ua(ctx->dmactx.pcilib, ctx->desc); uint32_t *last_written_addr_ptr; uint32_t last_written_addr; @@ -307,7 +322,7 @@ int dma_ipe_get_status(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcil // Find where the ring head is actually are for (i = 0; i < ctx->ring_size; i++) { - uintptr_t bus_addr = pcilib_kmem_get_block_ba(ctx->pcilib, ctx->pages, i); + uintptr_t bus_addr = pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, ctx->pages, i); if (bus_addr == last_written_addr) { status->ring_head = bus_addr; @@ -373,7 +388,7 @@ int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin err = dma_ipe_start(vctx, dma, PCILIB_DMA_FLAGS_DEFAULT); if (err) return err; - desc_va = (void*)pcilib_kmem_get_ua(ctx->pcilib, ctx->desc); + desc_va = (void*)pcilib_kmem_get_ua(ctx->dmactx.pcilib, ctx->desc); if (ctx->mode64) last_written_addr_ptr = desc_va + 3 * sizeof(uint32_t); else last_written_addr_ptr = desc_va + 4 * sizeof(uint32_t); @@ -428,24 +443,24 @@ int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin #endif /* IPEDMA_DEBUG */ #ifdef IPEDMA_DETECT_PACKETS - if ((*empty_detected_ptr)&&(pcilib_kmem_get_block_ba(ctx->pcilib, ctx->pages, cur_read) == (*last_written_addr_ptr))) packet_flags = PCILIB_DMA_FLAG_EOP; + if ((*empty_detected_ptr)&&(pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, ctx->pages, cur_read) == (*last_written_addr_ptr))) packet_flags = PCILIB_DMA_FLAG_EOP; else packet_flags = 0; #endif /* IPEDMA_DETECT_PACKETS */ - pcilib_kmem_sync_block(ctx->pcilib, ctx->pages, PCILIB_KMEM_SYNC_FROMDEVICE, cur_read); - void *buf = pcilib_kmem_get_block_ua(ctx->pcilib, ctx->pages, cur_read); + pcilib_kmem_sync_block(ctx->dmactx.pcilib, ctx->pages, PCILIB_KMEM_SYNC_FROMDEVICE, cur_read); + void *buf = pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ctx->pages, cur_read); ret = cb(cbattr, packet_flags, ctx->page_size, buf); if (ret < 0) return -ret; // DS: Fixme, it looks like we can avoid calling this for the sake of performance -// pcilib_kmem_sync_block(ctx->pcilib, ctx->pages, PCILIB_KMEM_SYNC_TODEVICE, cur_read); +// pcilib_kmem_sync_block(ctx->dmactx.pcilib, ctx->pages, PCILIB_KMEM_SYNC_TODEVICE, cur_read); // Numbered from 1 WR(IPEDMA_REG_LAST_READ, cur_read + 1); ctx->last_read = cur_read; -// ctx->last_read_addr = htonl(pcilib_kmem_get_block_ba(ctx->pcilib, ctx->pages, cur_read)); - ctx->last_read_addr = pcilib_kmem_get_block_ba(ctx->pcilib, ctx->pages, cur_read); +// ctx->last_read_addr = htonl(pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, ctx->pages, cur_read)); + ctx->last_read_addr = pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, ctx->pages, cur_read); #ifdef IPEDMA_BUG_DMARD FILE *f = fopen("/tmp/pcitool_lastread", "w"); @@ -481,7 +496,7 @@ double dma_ipe_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dm WR(IPEDMA_REG_CONTROL, 0x0); - err = pcilib_skip_dma(ctx->pcilib, 0); + err = pcilib_skip_dma(ctx->dmactx.pcilib, 0); if (err) { pcilib_error("Can't start benchmark, devices continuously writes unexpected data using DMA engine"); return -1; @@ -500,7 +515,7 @@ double dma_ipe_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dm WR(IPEDMA_REG_CONTROL, 0x1); for (bytes = 0; bytes < size; bytes += rbytes) { - err = pcilib_read_dma(ctx->pcilib, 0, addr, size - bytes, buf + bytes, &rbytes); + err = pcilib_read_dma(ctx->dmactx.pcilib, 0, addr, size - bytes, buf + bytes, &rbytes); if (err) { pcilib_error("Can't read data from DMA, error %i", err); return -1; @@ -514,7 +529,7 @@ double dma_ipe_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dm gettimeofday(&cur, NULL); us += ((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)); - err = pcilib_skip_dma(ctx->pcilib, 0); + err = pcilib_skip_dma(ctx->dmactx.pcilib, 0); if (err) { pcilib_error("Can't start iteration, devices continuously writes unexpected data using DMA engine"); break; @@ -6,22 +6,19 @@ //#define PCILIB_NWL_MODIFICATION_IPECAMERA 0x100 -pcilib_dma_context_t *dma_ipe_init(pcilib_t *ctx, pcilib_dma_modification_t type, void *arg); +pcilib_dma_context_t *dma_ipe_init(pcilib_t *ctx, const char *model, const void *arg); void dma_ipe_free(pcilib_dma_context_t *vctx); int dma_ipe_get_status(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers); - int dma_ipe_start(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags); int dma_ipe_stop(pcilib_dma_context_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags); int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr); double dma_ipe_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); - -#ifdef _PCILIB_DMA_IPE_C -pcilib_dma_api_description_t ipe_dma_api = { - "ipe_dma", +#ifdef _PCILIB_CONFIG_C +static const pcilib_dma_api_description_t ipe_dma_api = { dma_ipe_init, dma_ipe_free, dma_ipe_get_status, @@ -34,9 +31,55 @@ pcilib_dma_api_description_t ipe_dma_api = { dma_ipe_stream_read, dma_ipe_benchmark }; -#else -extern pcilib_dma_api_description_t ipe_dma_api; -#endif + +static const pcilib_dma_engine_description_t ipe_dma_engines[] = { + { 0, PCILIB_DMA_TYPE_PACKET, PCILIB_DMA_FROM_DEVICE, 32, "dma", NULL }, + { 0 } +}; + +static const pcilib_register_bank_description_t ipe_dma_banks[] = { + { PCILIB_REGISTER_BANK_DMA, PCILIB_BAR0, 0xA000, PCILIB_REGISTER_PROTOCOL_DEFAULT, 0, 0, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "dma", "DMA Registers"}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL } +}; + +static const pcilib_register_description_t ipe_dma_registers[] = { + {0x0000, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dcr", "Device Control Status Register"}, + {0x0000, 0, 1, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "reset_dma", ""}, + {0x0000, 16, 4, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "datapath_width", ""}, + {0x0000, 24, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "fpga_family", ""}, + {0x0004, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "ddmacr", "Device DMA Control Status Register"}, + {0x0004, 0, 1, 0, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_start", "Start writting memory"}, + {0x0004, 5, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_relxed_order", ""}, + {0x0004, 6, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_nosnoop", ""}, + {0x0004, 7, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_int_dis", ""}, + {0x0004, 16, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mrd_start", ""}, + {0x0004, 21, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mrd_relaxed_order", ""}, + {0x0004, 22, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mrd_nosnoop", ""}, + {0x0004, 23, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mrd_int_dis", ""}, + {0x000C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_size", "DMA TLP size"}, + {0x000C, 0, 16, 0x20, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_len", "Max TLP size"}, + {0x000C, 16, 3, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_tlp_tc", "TC for TLP packets"}, + {0x000C, 19, 1, 0, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_64b_en", "Enable 64 bit memory addressing"}, + {0x000C, 20, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_phant_func_dis", "Disable MWR phantom function"}, + {0x000C, 24, 8, 0, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_up_addr", "Upper address for 64 bit memory addressing"}, + {0x0010, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_count", "Write DMA TLP Count"}, + {0x0014, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_pattern", "DMA generator data pattern"}, + {0x0028, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_perf", "MWR Performance"}, + {0x003C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "cfg_lnk_width", "Negotiated and max width of PCIe Link"}, + {0x003C, 0, 6, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_cap_max_lnk_width", "Max link width"}, + {0x003C, 8, 6, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_prg_max_lnk_width", "Negotiated link width"}, + {0x0040, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "cfg_payload_size", ""}, + {0x0040, 0, 4, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_cap_max_payload_size", "Max payload size"}, + {0x0040, 8, 3, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_prg_max_payload_size", "Prog max payload size"}, + {0x0040, 16, 3, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_max_rd_req_size", "Max read request size"}, + {0x0050, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "desc_mem_din", "Descriptor memory"}, + {0x0054, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "update_addr", "Address of progress register"}, + {0x0058, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "last_descriptor_read", "Last descriptor read by the host"}, + {0x005C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "desc_mem_addr", "Number of descriptors configured"}, + {0x0060, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "update_thresh", "Update threshold of progress register"}, + {0, 0, 0, 0, 0x00000000, 0, 0, 0, NULL, NULL} +}; +#endif /* _PCILIB_CONFIG_C */ #endif /* _PCILIB_DMA_IPE_H */ diff --git a/dma/ipe_private.h b/dma/ipe_private.h index fd44011..161e609 100644 --- a/dma/ipe_private.h +++ b/dma/ipe_private.h @@ -1,6 +1,8 @@ #ifndef _PCILIB_DMA_IPE_PRIVATE_H #define _PCILIB_DMA_IPE_PRIVATE_H +#include "dma.h" + #define IPEDMA_CORES 1 #define IPEDMA_TLP_SIZE 32 #define IPEDMA_PAGE_SIZE 4096 @@ -30,12 +32,10 @@ typedef struct ipe_dma_s ipe_dma_t; struct ipe_dma_s { - struct pcilib_dma_context_s dmactx; - pcilib_dma_engine_description_t engine[2]; + pcilib_dma_context_t dmactx; + //pcilib_dma_engine_description_t engine[2]; - pcilib_t *pcilib; - - pcilib_register_bank_description_t *dma_bank; + const pcilib_register_bank_description_t *dma_bank; char *base_addr; pcilib_irq_type_t irq_enabled; /**< indicates that IRQs are enabled */ diff --git a/dma/ipe_registers.h b/dma/ipe_registers.h deleted file mode 100644 index 17fc41a..0000000 --- a/dma/ipe_registers.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _PCILIB_DMA_IPE_REGISTERS_H -#define _PCILIB_DMA_IPE_REGISTERS_H - -#ifdef _PCILIB_DMA_IPE_C -static pcilib_register_description_t ipe_dma_registers[] = { - {0x0000, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dcr", "Device Control Status Register"}, - {0x0000, 0, 1, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "reset_dma", ""}, - {0x0000, 16, 4, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "datapath_width", ""}, - {0x0000, 24, 8, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "fpga_family", ""}, - {0x0004, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "ddmacr", "Device DMA Control Status Register"}, - {0x0004, 0, 1, 0, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_start", "Start writting memory"}, - {0x0004, 5, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_relxed_order", ""}, - {0x0004, 6, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_nosnoop", ""}, - {0x0004, 7, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_int_dis", ""}, - {0x0004, 16, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mrd_start", ""}, - {0x0004, 21, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mrd_relaxed_order", ""}, - {0x0004, 22, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mrd_nosnoop", ""}, - {0x0004, 23, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mrd_int_dis", ""}, - {0x000C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_size", "DMA TLP size"}, - {0x000C, 0, 16, 0x20, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_len", "Max TLP size"}, - {0x000C, 16, 3, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_tlp_tc", "TC for TLP packets"}, - {0x000C, 19, 1, 0, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_64b_en", "Enable 64 bit memory addressing"}, - {0x000C, 20, 1, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_phant_func_dis", "Disable MWR phantom function"}, - {0x000C, 24, 8, 0, 0xFFFFFFFF, PCILIB_REGISTER_RW , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "mwr_up_addr", "Upper address for 64 bit memory addressing"}, - {0x0010, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_count", "Write DMA TLP Count"}, - {0x0014, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_pattern", "DMA generator data pattern"}, - {0x0028, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_perf", "MWR Performance"}, - {0x003C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "cfg_lnk_width", "Negotiated and max width of PCIe Link"}, - {0x003C, 0, 6, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_cap_max_lnk_width", "Max link width"}, - {0x003C, 8, 6, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_prg_max_lnk_width", "Negotiated link width"}, - {0x0040, 0, 32, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "cfg_payload_size", ""}, - {0x0040, 0, 4, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_cap_max_payload_size", "Max payload size"}, - {0x0040, 8, 3, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_prg_max_payload_size", "Prog max payload size"}, - {0x0040, 16, 3, 0, 0x00000000, PCILIB_REGISTER_R , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_max_rd_req_size", "Max read request size"}, - {0x0050, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "desc_mem_din", "Descriptor memory"}, - {0x0054, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "update_addr", "Address of progress register"}, - {0x0058, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "last_descriptor_read", "Last descriptor read by the host"}, - {0x005C, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "desc_mem_addr", "Number of descriptors configured"}, - {0x0060, 0, 32, 0, 0x00000000, PCILIB_REGISTER_RW , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "update_thresh", "Update threshold of progress register"}, - {0, 0, 0, 0, 0x00000000, 0, 0, 0, NULL, NULL} -}; -#endif /* _PCILIB_DMA_IPE_C */ - -#endif /* _PCILIB_DMA_IPE_REGISTERS_H */ @@ -1,5 +1,6 @@ #define _PCILIB_DMA_NWL_C #define _BSD_SOURCE +#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> @@ -11,8 +12,8 @@ #include "pcilib.h" #include "error.h" #include "tools.h" -#include "nwl_private.h" +#include "nwl_private.h" #include "nwl_defines.h" int dma_nwl_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) { @@ -25,7 +26,7 @@ int dma_nwl_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm } if (dma == PCILIB_DMA_ENGINE_INVALID) return 0; - else if (dma > ctx->n_engines) return PCILIB_ERROR_INVALID_BANK; + else if (dma > ctx->dmactx.pcilib->num_engines) return PCILIB_ERROR_INVALID_BANK; if (flags&PCILIB_DMA_FLAG_PERSISTENT) ctx->engines[dma].preserve = 1; @@ -44,7 +45,7 @@ int dma_nwl_stop(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma // stop everything if (dma == PCILIB_DMA_ENGINE_INVALID) { - for (dma = 0; dma < ctx->n_engines; dma++) { + for (dma = 0; dma < ctx->dmactx.pcilib->num_engines; dma++) { if (flags&PCILIB_DMA_FLAG_PERSISTENT) { ctx->engines[dma].preserve = 0; } @@ -63,7 +64,7 @@ int dma_nwl_stop(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma return 0; } - if (dma > ctx->n_engines) return PCILIB_ERROR_INVALID_BANK; + if (dma > ctx->dmactx.pcilib->num_engines) return PCILIB_ERROR_INVALID_BANK; // ignorign previous setting if flag specified if (flags&PCILIB_DMA_FLAG_PERSISTENT) { @@ -74,55 +75,99 @@ 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_modification_t type, void *arg) { - int i; +pcilib_dma_context_t *dma_nwl_init(pcilib_t *pcilib, const char *model, const void *arg) { + int i, j; int err; - pcilib_dma_engine_t n_engines; - - pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib); + + pcilib_dma_engine_t dma; + pcilib_register_description_t eregs[NWL_MAX_DMA_ENGINE_REGISTERS]; + const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib); nwl_dma_t *ctx = malloc(sizeof(nwl_dma_t)); - if (ctx) { - memset(ctx, 0, sizeof(nwl_dma_t)); - ctx->pcilib = pcilib; - ctx->type = type; + if (!ctx) return NULL; - if (type == PCILIB_NWL_MODIFICATION_IPECAMERA) { - ctx->dmactx.ignore_eop = 1; - } + memset(ctx, 0, sizeof(nwl_dma_t)); + + pcilib_register_bank_t dma_bank = pcilib_find_register_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; + } - pcilib_register_bank_t dma_bank = pcilib_find_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA); - if (dma_bank == PCILIB_REGISTER_BANK_INVALID) { + ctx->dma_bank = model_info->banks + dma_bank; + ctx->base_addr = pcilib_resolve_register_address(pcilib, ctx->dma_bank->bar, ctx->dma_bank->read_addr); + + if ((model)&&(strcasestr(model, "ipecamera"))) { + ctx->type = NWL_MODIFICATION_IPECAMERA; + ctx->ignore_eop = 1; + } else { + ctx->type = NWL_MODIFICATION_DEFAULT; + + err = pcilib_add_registers(pcilib, 0, nwl_xrawdata_registers); + if (err) { free(ctx); - pcilib_error("DMA Register Bank could not be found"); + pcilib_error("Error (%i) adding NWL XRAWDATA registers", err); return NULL; } - - ctx->dma_bank = model_info->banks + dma_bank; - ctx->base_addr = pcilib_resolve_register_address(pcilib, ctx->dma_bank->bar, ctx->dma_bank->read_addr); + } - for (i = 0, n_engines = 0; i < 2 * PCILIB_MAX_DMA_ENGINES; i++) { - char *addr = ctx->base_addr + DMA_OFFSET + i * DMA_ENGINE_PER_SIZE; + for (j = 0; nwl_dma_engine_registers[j].bits; j++); + if (j > NWL_MAX_DMA_ENGINE_REGISTERS) { + free(ctx); + pcilib_error("Too many (%i) engine registers defined, only %i supported", j, NWL_MAX_DMA_ENGINE_REGISTERS); + return NULL; + } + + memcpy(eregs, nwl_dma_engine_registers, j * sizeof(pcilib_register_description_t)); + + for (i = 0; i < 2 * PCILIB_MAX_DMA_ENGINES; i++) { + pcilib_dma_engine_description_t edesc; + char *addr = ctx->base_addr + DMA_OFFSET + i * DMA_ENGINE_PER_SIZE; - memset(ctx->engines + n_engines, 0, sizeof(pcilib_nwl_engine_description_t)); + memset(&edesc, 0, sizeof(pcilib_dma_engine_description_t)); - err = dma_nwl_read_engine_config(ctx, ctx->engines + n_engines, addr); - if (err) continue; + err = dma_nwl_read_engine_config(ctx, &edesc, addr); + if (err) continue; + + for (j = 0; nwl_dma_engine_registers[j].bits; j++) { + int dma_addr_len = (PCILIB_MAX_DMA_ENGINES > 9)?2:1; + const char *dma_direction; + + eregs[j].name = nwl_dma_engine_register_names[i * NWL_MAX_DMA_ENGINE_REGISTERS + j]; + eregs[j].addr = nwl_dma_engine_registers[j].addr + (addr - ctx->base_addr); - pcilib_set_dma_engine_description(pcilib, n_engines, (pcilib_dma_engine_description_t*)(ctx->engines + n_engines)); - ++n_engines; + switch (edesc.direction) { + case PCILIB_DMA_FROM_DEVICE: + dma_direction = "r"; + break; + case PCILIB_DMA_TO_DEVICE: + dma_direction = "w"; + break; + default: + dma_direction = ""; + } + sprintf((char*)eregs[j].name, nwl_dma_engine_registers[j].name, dma_addr_len, edesc.addr, dma_direction); } - pcilib_set_dma_engine_description(pcilib, n_engines, NULL); - - ctx->n_engines = n_engines; - err = nwl_add_registers(ctx); + err = pcilib_add_registers(pcilib, j, eregs); if (err) { free(ctx); - pcilib_error("Failed to add DMA registers"); + pcilib_error("Error (%i) adding NWL DMA registers for engine %i", err, edesc.addr); return NULL; } + + dma = pcilib_add_dma_engine(pcilib, &edesc); + if (dma == PCILIB_DMA_ENGINE_INVALID) { + free(ctx); + pcilib_error("Problem while registering DMA engine"); + return NULL; + } + + ctx->engines[dma].desc = &pcilib->engines[dma]; + ctx->engines[dma].base_addr = addr; } + return (pcilib_dma_context_t*)ctx; } @@ -130,7 +175,7 @@ void dma_nwl_free(pcilib_dma_context_t *vctx) { nwl_dma_t *ctx = (nwl_dma_t*)vctx; if (ctx) { - if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx); + if (ctx->type == NWL_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx); dma_nwl_free_irq(ctx); dma_nwl_stop(vctx, PCILIB_DMA_ENGINE_ALL, PCILIB_DMA_FLAGS_DEFAULT); @@ -4,9 +4,7 @@ #include <stdio.h> #include "../pcilib.h" -#define PCILIB_NWL_MODIFICATION_IPECAMERA 0x100 - -pcilib_dma_context_t *dma_nwl_init(pcilib_t *ctx, pcilib_dma_modification_t type, void *arg); +pcilib_dma_context_t *dma_nwl_init(pcilib_t *ctx, const char *model, const void *arg); void dma_nwl_free(pcilib_dma_context_t *vctx); int dma_nwl_get_status(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers); @@ -22,10 +20,8 @@ int dma_nwl_write_fragment(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, int dma_nwl_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr); 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); - -#ifdef _PCILIB_DMA_NWL_C -pcilib_dma_api_description_t nwl_dma_api = { - "nwl_dma", +#ifdef _PCILIB_CONFIG_C +static const pcilib_dma_api_description_t nwl_dma_api = { dma_nwl_init, dma_nwl_free, dma_nwl_get_status, @@ -38,9 +34,94 @@ pcilib_dma_api_description_t nwl_dma_api = { dma_nwl_stream_read, dma_nwl_benchmark }; -#else -extern pcilib_dma_api_description_t nwl_dma_api; -#endif +static pcilib_register_bank_description_t nwl_dma_banks[] = { + { PCILIB_REGISTER_BANK_DMA, PCILIB_BAR0, 0xA000, PCILIB_REGISTER_PROTOCOL_DEFAULT , 0, 0, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "dma", "DMA Registers"}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL } +}; + +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} +}; + +#endif /* _PCILIB_CONFIG_C */ + +#ifdef _PCILIB_DMA_NWL_C + // 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, 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_W , 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} +}; + + // 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} +}; +#endif /* _PCILIB_DMA_NWL_C */ #endif /* _PCILIB_DMA_NWL_H */ diff --git a/dma/nwl_engine.c b/dma/nwl_engine.c index f541d0b..a437948 100644 --- a/dma/nwl_engine.c +++ b/dma/nwl_engine.c @@ -10,46 +10,41 @@ #include "pcilib.h" #include "error.h" #include "tools.h" -#include "nwl_private.h" +#include "nwl_private.h" #include "nwl_defines.h" - #include "nwl_engine_buffers.h" -int dma_nwl_read_engine_config(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, char *base) { +int dma_nwl_read_engine_config(nwl_dma_t *ctx, pcilib_dma_engine_description_t *info, const char *base) { uint32_t val; - info->base_addr = base; - nwl_read_register(val, ctx, base, REG_DMA_ENG_CAP); if ((val & DMA_ENG_PRESENT_MASK) == 0) return PCILIB_ERROR_NOTAVAILABLE; - info->desc.addr = (val & DMA_ENG_NUMBER) >> DMA_ENG_NUMBER_SHIFT; - if ((info->desc.addr > PCILIB_MAX_DMA_ENGINES)||(info->desc.addr < 0)) return PCILIB_ERROR_INVALID_DATA; + info->addr = (val & DMA_ENG_NUMBER) >> DMA_ENG_NUMBER_SHIFT; + if ((info->addr > PCILIB_MAX_DMA_ENGINES)||(info->addr < 0)) return PCILIB_ERROR_INVALID_DATA; switch (val & DMA_ENG_DIRECTION_MASK) { case DMA_ENG_C2S: - info->desc.direction = PCILIB_DMA_FROM_DEVICE; + info->direction = PCILIB_DMA_FROM_DEVICE; break; default: - info->desc.direction = PCILIB_DMA_TO_DEVICE; + info->direction = PCILIB_DMA_TO_DEVICE; } switch (val & DMA_ENG_TYPE_MASK) { case DMA_ENG_BLOCK: - info->desc.type = PCILIB_DMA_TYPE_BLOCK; + info->type = PCILIB_DMA_TYPE_BLOCK; break; case DMA_ENG_PACKET: - info->desc.type = PCILIB_DMA_TYPE_PACKET; + info->type = PCILIB_DMA_TYPE_PACKET; break; default: - info->desc.type = PCILIB_DMA_TYPE_UNKNOWN; + info->type = PCILIB_DMA_TYPE_UNKNOWN; } - info->desc.addr_bits = (val & DMA_ENG_BD_MAX_BC) >> DMA_ENG_BD_MAX_BC_SHIFT; - - info->base_addr = base; + info->addr_bits = (val & DMA_ENG_BD_MAX_BC) >> DMA_ENG_BD_MAX_BC_SHIFT; return 0; } @@ -60,22 +55,21 @@ int dma_nwl_start_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) { uint32_t ring_pa; struct timeval start, cur; - pcilib_nwl_engine_description_t *info = ctx->engines + dma; + pcilib_nwl_engine_context_t *ectx = ctx->engines + dma; char *base = ctx->engines[dma].base_addr; - if (info->started) return 0; - + if (ectx->started) return 0; // This will only successed if there are no parallel access to DMA engine - err = dma_nwl_allocate_engine_buffers(ctx, info); + err = dma_nwl_allocate_engine_buffers(ctx, ectx); if (err) { - info->started = 1; + ectx->started = 1; dma_nwl_stop_engine(ctx, dma); return err; } - if (info->reused) { - info->preserve = 1; + if (ectx->reused) { + ectx->preserve = 1; dma_nwl_acknowledge_irq((pcilib_dma_context_t*)ctx, PCILIB_DMA_IRQ, dma); @@ -86,7 +80,7 @@ int dma_nwl_start_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) { // Disable IRQs err = dma_nwl_disable_engine_irq(ctx, dma); if (err) { - info->started = 1; + ectx->started = 1; dma_nwl_stop_engine(ctx, dma); return err; } @@ -102,9 +96,9 @@ int dma_nwl_start_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) { } while ((val & (DMA_ENG_STATE_MASK|DMA_ENG_USER_RESET))&&(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < PCILIB_REGISTER_TIMEOUT)); if (val & (DMA_ENG_STATE_MASK|DMA_ENG_USER_RESET)) { - pcilib_error("Timeout during reset of DMA engine %i", info->desc.addr); + pcilib_error("Timeout during reset of DMA engine %i", ectx->desc->addr); - info->started = 1; + ectx->started = 1; dma_nwl_stop_engine(ctx, dma); return PCILIB_ERROR_TIMEOUT; } @@ -119,24 +113,24 @@ int dma_nwl_start_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) { } while ((val & DMA_ENG_RESET)&&(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < PCILIB_REGISTER_TIMEOUT)); if (val & DMA_ENG_RESET) { - pcilib_error("Timeout during reset of DMA engine %i", info->desc.addr); + pcilib_error("Timeout during reset of DMA engine %i", ectx->desc->addr); - info->started = 1; + ectx->started = 1; dma_nwl_stop_engine(ctx, dma); return PCILIB_ERROR_TIMEOUT; } dma_nwl_acknowledge_irq((pcilib_dma_context_t*)ctx, PCILIB_DMA_IRQ, dma); - 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); + ring_pa = pcilib_kmem_get_pa(ctx->dmactx.pcilib, ectx->ring); + nwl_write_register(ring_pa, ctx, ectx->base_addr, REG_DMA_ENG_NEXT_BD); + nwl_write_register(ring_pa, ctx, ectx->base_addr, REG_SW_NEXT_BD); __sync_synchronize(); - nwl_read_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS); + nwl_read_register(val, ctx, ectx->base_addr, REG_DMA_ENG_CTRL_STATUS); val |= (DMA_ENG_ENABLE); - nwl_write_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS); + nwl_write_register(val, ctx, ectx->base_addr, REG_DMA_ENG_CTRL_STATUS); __sync_synchronize(); @@ -144,19 +138,19 @@ int dma_nwl_start_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) { dma_nwl_enable_engine_irq(ctx, dma); #endif /* NWL_GENERATE_DMA_IRQ */ - if (info->desc.direction == PCILIB_DMA_FROM_DEVICE) { - ring_pa += (info->ring_size - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - nwl_write_register(ring_pa, ctx, info->base_addr, REG_SW_NEXT_BD); + if (ectx->desc->direction == PCILIB_DMA_FROM_DEVICE) { + ring_pa += (ectx->ring_size - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; + nwl_write_register(ring_pa, ctx, ectx->base_addr, REG_SW_NEXT_BD); - info->tail = 0; - info->head = (info->ring_size - 1); + ectx->tail = 0; + ectx->head = (ectx->ring_size - 1); } else { - info->tail = 0; - info->head = 0; + ectx->tail = 0; + ectx->head = 0; } } - info->started = 1; + ectx->started = 1; return 0; } @@ -170,17 +164,17 @@ int dma_nwl_stop_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) { pcilib_kmem_flags_t flags; - pcilib_nwl_engine_description_t *info = ctx->engines + dma; + pcilib_nwl_engine_context_t *ectx = ctx->engines + dma; char *base = ctx->engines[dma].base_addr; - if (!info->started) return 0; + if (!ectx->started) return 0; - info->started = 0; + ectx->started = 0; err = dma_nwl_disable_engine_irq(ctx, dma); if (err) return err; - if (!info->preserve) { + if (!ectx->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); @@ -191,30 +185,30 @@ int dma_nwl_stop_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) { gettimeofday(&cur, NULL); } while ((val & (DMA_ENG_RUNNING))&&(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < PCILIB_REGISTER_TIMEOUT)); - 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 (ectx->ring) { + ring_pa = pcilib_kmem_get_pa(ctx->dmactx.pcilib, ectx->ring); + nwl_write_register(ring_pa, ctx, ectx->base_addr, REG_DMA_ENG_NEXT_BD); + nwl_write_register(ring_pa, ctx, ectx->base_addr, REG_SW_NEXT_BD); } } dma_nwl_acknowledge_irq((pcilib_dma_context_t*)ctx, PCILIB_DMA_IRQ, dma); - if (info->preserve) { + if (ectx->preserve) { flags = PCILIB_KMEM_FLAG_REUSE; } else { flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT; } // Clean buffers - if (info->ring) { - pcilib_free_kernel_memory(ctx->pcilib, info->ring, flags); - info->ring = NULL; + if (ectx->ring) { + pcilib_free_kernel_memory(ctx->dmactx.pcilib, ectx->ring, flags); + ectx->ring = NULL; } - if (info->pages) { - pcilib_free_kernel_memory(ctx->pcilib, info->pages, flags); - info->pages = NULL; + if (ectx->pages) { + pcilib_free_kernel_memory(ctx->dmactx.pcilib, ectx->pages, flags); + ectx->pages = NULL; } return 0; @@ -226,28 +220,28 @@ int dma_nwl_write_fragment(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, size_t bufnum; nwl_dma_t *ctx = (nwl_dma_t*)vctx; - pcilib_nwl_engine_description_t *info = ctx->engines + dma; + pcilib_nwl_engine_context_t *ectx = ctx->engines + dma; err = dma_nwl_start(vctx, dma, PCILIB_DMA_FLAGS_DEFAULT); if (err) return err; if (data) { - for (pos = 0; pos < size; pos += info->page_size) { - int block_size = min2(size - pos, info->page_size); + for (pos = 0; pos < size; pos += ectx->page_size) { + int block_size = min2(size - pos, ectx->page_size); - bufnum = dma_nwl_get_next_buffer(ctx, info, 1, timeout); + bufnum = dma_nwl_get_next_buffer(ctx, ectx, 1, timeout); if (bufnum == PCILIB_DMA_BUFFER_INVALID) { if (written) *written = pos; return PCILIB_ERROR_TIMEOUT; } - void *buf = pcilib_kmem_get_block_ua(ctx->pcilib, info->pages, bufnum); + void *buf = pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ectx->pages, bufnum); - pcilib_kmem_sync_block(ctx->pcilib, info->pages, PCILIB_KMEM_SYNC_FROMDEVICE, bufnum); + pcilib_kmem_sync_block(ctx->dmactx.pcilib, ectx->pages, PCILIB_KMEM_SYNC_FROMDEVICE, bufnum); memcpy(buf, data, block_size); - pcilib_kmem_sync_block(ctx->pcilib, info->pages, PCILIB_KMEM_SYNC_TODEVICE, bufnum); + pcilib_kmem_sync_block(ctx->dmactx.pcilib, ectx->pages, PCILIB_KMEM_SYNC_TODEVICE, bufnum); - err = dma_nwl_push_buffer(ctx, info, block_size, (flags&PCILIB_DMA_FLAG_EOP)&&((pos + block_size) == size), timeout); + err = dma_nwl_push_buffer(ctx, ectx, block_size, (flags&PCILIB_DMA_FLAG_EOP)&&((pos + block_size) == size), timeout); if (err) { if (written) *written = pos; return err; @@ -258,7 +252,7 @@ int dma_nwl_write_fragment(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, if (written) *written = size; if (flags&PCILIB_DMA_FLAG_WAIT) { - bufnum = dma_nwl_get_next_buffer(ctx, info, PCILIB_NWL_DMA_PAGES - 1, timeout); + bufnum = dma_nwl_get_next_buffer(ctx, ectx, PCILIB_NWL_DMA_PAGES - 1, timeout); if (bufnum == PCILIB_DMA_BUFFER_INVALID) return PCILIB_ERROR_TIMEOUT; } @@ -276,7 +270,7 @@ int dma_nwl_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin int eop; - pcilib_nwl_engine_description_t *info = ctx->engines + dma; + pcilib_nwl_engine_context_t *ectx = ctx->engines + dma; err = dma_nwl_start(vctx, dma, PCILIB_DMA_FLAGS_DEFAULT); if (err) return err; @@ -288,21 +282,21 @@ int dma_nwl_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin // case PCILIB_STREAMING_CHECK: wait = 0; break; } - bufnum = dma_nwl_wait_buffer(ctx, info, &bufsize, &eop, wait); + bufnum = dma_nwl_wait_buffer(ctx, ectx, &bufsize, &eop, wait); if (bufnum == PCILIB_DMA_BUFFER_INVALID) { return (ret&PCILIB_STREAMING_FAIL)?PCILIB_ERROR_TIMEOUT:0; } // EOP is not respected in IPE Camera - if (ctx->dmactx.ignore_eop) eop = 1; + if (ctx->ignore_eop) eop = 1; - pcilib_kmem_sync_block(ctx->pcilib, info->pages, PCILIB_KMEM_SYNC_FROMDEVICE, bufnum); - void *buf = pcilib_kmem_get_block_ua(ctx->pcilib, info->pages, bufnum); + pcilib_kmem_sync_block(ctx->dmactx.pcilib, ectx->pages, PCILIB_KMEM_SYNC_FROMDEVICE, bufnum); + void *buf = pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ectx->pages, bufnum); ret = cb(cbattr, (eop?PCILIB_DMA_FLAG_EOP:0), bufsize, buf); if (ret < 0) return -ret; // DS: Fixme, it looks like we can avoid calling this for the sake of performance -// pcilib_kmem_sync_block(ctx->pcilib, info->pages, PCILIB_KMEM_SYNC_TODEVICE, bufnum); - dma_nwl_return_buffer(ctx, info); +// pcilib_kmem_sync_block(ctx->dmactx.pcilib, ectx->pages, PCILIB_KMEM_SYNC_TODEVICE, bufnum); + dma_nwl_return_buffer(ctx, ectx); res += bufsize; diff --git a/dma/nwl_engine.h b/dma/nwl_engine.h index f9f3f60..5f1fa9d 100644 --- a/dma/nwl_engine.h +++ b/dma/nwl_engine.h @@ -1,7 +1,7 @@ #ifndef _PCILIB_DMA_NWL_ENGINE_H #define _PCILIB_DMA_NWL_ENGINE_H -int dma_nwl_read_engine_config(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, char *base); +int dma_nwl_read_engine_config(nwl_dma_t *ctx, pcilib_dma_engine_description_t *info, const char *base); int dma_nwl_start_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma); int dma_nwl_stop_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma); diff --git a/dma/nwl_engine_buffers.h b/dma/nwl_engine_buffers.h index c45c3ca..71fb736 100644 --- a/dma/nwl_engine_buffers.h +++ b/dma/nwl_engine_buffers.h @@ -2,10 +2,10 @@ #define NWL_RING_SET(data, offset, val) *(uint32_t*)(((char*)(data)) + (offset)) = (val) #define NWL_RING_UPDATE(data, offset, mask, val) *(uint32_t*)(((char*)(data)) + (offset)) = ((*(uint32_t*)(((char*)(data)) + (offset)))&(mask))|(val) -static int dma_nwl_compute_read_s2c_pointers(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, unsigned char *ring, uint32_t ring_pa) { +static int dma_nwl_compute_read_s2c_pointers(nwl_dma_t *ctx, pcilib_nwl_engine_context_t *ectx, unsigned char *ring, uint32_t ring_pa) { uint32_t val; - char *base = info->base_addr; + const char *base = ectx->base_addr; nwl_read_register(val, ctx, base, REG_SW_NEXT_BD); if ((val < ring_pa)||((val - ring_pa) % PCILIB_NWL_DMA_DESCRIPTOR_SIZE)) { @@ -14,9 +14,9 @@ static int dma_nwl_compute_read_s2c_pointers(nwl_dma_t *ctx, pcilib_nwl_engine_d return PCILIB_ERROR_INVALID_STATE; } - info->head = (val - ring_pa) / PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - if (info->head >= PCILIB_NWL_DMA_PAGES) { - pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_SW_NEXT_BD register value (%zu) out of range)", info->head); + ectx->head = (val - ring_pa) / PCILIB_NWL_DMA_DESCRIPTOR_SIZE; + if (ectx->head >= PCILIB_NWL_DMA_PAGES) { + pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_SW_NEXT_BD register value (%zu) out of range)", ectx->head); return PCILIB_ERROR_INVALID_STATE; } @@ -27,23 +27,23 @@ static int dma_nwl_compute_read_s2c_pointers(nwl_dma_t *ctx, pcilib_nwl_engine_d return PCILIB_ERROR_INVALID_STATE; } - info->tail = (val - ring_pa) / PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - if (info->tail >= PCILIB_NWL_DMA_PAGES) { - pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_DMA_ENG_NEXT_BD register value (%zu) out of range)", info->tail); + ectx->tail = (val - ring_pa) / PCILIB_NWL_DMA_DESCRIPTOR_SIZE; + if (ectx->tail >= PCILIB_NWL_DMA_PAGES) { + pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_DMA_ENG_NEXT_BD register value (%zu) out of range)", ectx->tail); return PCILIB_ERROR_INVALID_STATE; } #ifdef DEBUG_NWL - printf("S2C: %lu %lu\n", info->tail, info->head); + printf("S2C: %lu %lu\n", ectx->tail, ectx->head); #endif /* DEBUG_NWL */ return 0; } -static int dma_nwl_compute_read_c2s_pointers(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, unsigned char *ring, uint32_t ring_pa) { +static int dma_nwl_compute_read_c2s_pointers(nwl_dma_t *ctx, pcilib_nwl_engine_context_t *ectx, unsigned char *ring, uint32_t ring_pa) { uint32_t val; - char *base = info->base_addr; + const char *base = ectx->base_addr; nwl_read_register(val, ctx, base, REG_SW_NEXT_BD); if ((val < ring_pa)||((val - ring_pa) % PCILIB_NWL_DMA_DESCRIPTOR_SIZE)) { @@ -52,24 +52,24 @@ static int dma_nwl_compute_read_c2s_pointers(nwl_dma_t *ctx, pcilib_nwl_engine_d return PCILIB_ERROR_INVALID_STATE; } - info->head = (val - ring_pa) / PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - if (info->head >= PCILIB_NWL_DMA_PAGES) { - pcilib_warning("Inconsistent C2S DMA Ring buffer is found (REG_SW_NEXT_BD register value (%zu) out of range)", info->head); + ectx->head = (val - ring_pa) / PCILIB_NWL_DMA_DESCRIPTOR_SIZE; + if (ectx->head >= PCILIB_NWL_DMA_PAGES) { + pcilib_warning("Inconsistent C2S DMA Ring buffer is found (REG_SW_NEXT_BD register value (%zu) out of range)", ectx->head); return PCILIB_ERROR_INVALID_STATE; } - info->tail = info->head + 1; - if (info->tail == PCILIB_NWL_DMA_PAGES) info->tail = 0; + ectx->tail = ectx->head + 1; + if (ectx->tail == PCILIB_NWL_DMA_PAGES) ectx->tail = 0; #ifdef DEBUG_NWL - printf("C2S: %lu %lu\n", info->tail, info->head); + printf("C2S: %lu %lu\n", ectx->tail, ectx->head); #endif /* DEBUG_NWL */ return 0; } -static int dma_nwl_allocate_engine_buffers(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info) { +static int dma_nwl_allocate_engine_buffers(nwl_dma_t *ctx, pcilib_nwl_engine_context_t *ectx) { int err = 0; int i; @@ -82,39 +82,39 @@ static int dma_nwl_allocate_engine_buffers(nwl_dma_t *ctx, pcilib_nwl_engine_des pcilib_kmem_flags_t flags; pcilib_kmem_type_t type; - char *base = info->base_addr; + char *base = ectx->base_addr; - if (info->pages) return 0; + if (ectx->pages) return 0; // Or bidirectional specified by 0x0|addr, or read 0x0|addr and write 0x80|addr - type = (info->desc.direction == PCILIB_DMA_TO_DEVICE)?PCILIB_KMEM_TYPE_DMA_S2C_PAGE:PCILIB_KMEM_TYPE_DMA_C2S_PAGE; - sub_use = info->desc.addr|((info->desc.direction == PCILIB_DMA_TO_DEVICE)?0x80:0x00); - flags = PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_EXCLUSIVE|PCILIB_KMEM_FLAG_HARDWARE|(info->preserve?PCILIB_KMEM_FLAG_PERSISTENT:0); + type = (ectx->desc->direction == PCILIB_DMA_TO_DEVICE)?PCILIB_KMEM_TYPE_DMA_S2C_PAGE:PCILIB_KMEM_TYPE_DMA_C2S_PAGE; + sub_use = ectx->desc->addr|((ectx->desc->direction == PCILIB_DMA_TO_DEVICE)?0x80:0x00); + flags = PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_EXCLUSIVE|PCILIB_KMEM_FLAG_HARDWARE|(ectx->preserve?PCILIB_KMEM_FLAG_PERSISTENT: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_RING, sub_use), flags); - pcilib_kmem_handle_t *pages = pcilib_alloc_kernel_memory(ctx->pcilib, type, PCILIB_NWL_DMA_PAGES, 0, 0, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, sub_use), flags); + pcilib_kmem_handle_t *ring = pcilib_alloc_kernel_memory(ctx->dmactx.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), flags); + pcilib_kmem_handle_t *pages = pcilib_alloc_kernel_memory(ctx->dmactx.pcilib, type, PCILIB_NWL_DMA_PAGES, 0, 0, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, sub_use), flags); if (!ring||!pages) { - if (pages) pcilib_free_kernel_memory(ctx->pcilib, pages, 0); - if (ring) pcilib_free_kernel_memory(ctx->pcilib, ring, 0); + if (pages) pcilib_free_kernel_memory(ctx->dmactx.pcilib, pages, 0); + if (ring) pcilib_free_kernel_memory(ctx->dmactx.pcilib, ring, 0); return PCILIB_ERROR_MEMORY; } - reuse_ring = pcilib_kmem_is_reused(ctx->pcilib, ring); - reuse_pages = pcilib_kmem_is_reused(ctx->pcilib, pages); + reuse_ring = pcilib_kmem_is_reused(ctx->dmactx.pcilib, ring); + reuse_pages = pcilib_kmem_is_reused(ctx->dmactx.pcilib, pages); // I guess idea here was that we not need to check all that stuff during the second iteration // which is basicaly true (shall we expect any driver-triggered changes or parallel accesses?) // but still we need to set preserve flag (and that if we enforcing preservation --start-dma). // Probably having checks anyway is not harming... -// if (!info->preserve) { +// if (!ectx->preserve) { if (reuse_ring == reuse_pages) { if (reuse_ring & PCILIB_KMEM_REUSE_PARTIAL) pcilib_warning("Inconsistent DMA buffers are found (only part of required buffers is available), reinitializing..."); else if (reuse_ring & PCILIB_KMEM_REUSE_REUSED) { if ((reuse_ring & PCILIB_KMEM_REUSE_PERSISTENT) == 0) pcilib_warning("Lost DMA buffers are found (non-persistent mode), reinitializing..."); else if ((reuse_ring & PCILIB_KMEM_REUSE_HARDWARE) == 0) pcilib_warning("Lost DMA buffers are found (missing HW reference), reinitializing..."); else { - nwl_read_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS); + nwl_read_register(val, ctx, ectx->base_addr, REG_DMA_ENG_CTRL_STATUS); if ((val&DMA_ENG_RUNNING) == 0) pcilib_warning("Lost DMA buffers are found (DMA engine is stopped), reinitializing..."); else preserve = 1; @@ -124,27 +124,27 @@ static int dma_nwl_allocate_engine_buffers(nwl_dma_t *ctx, pcilib_nwl_engine_des // } - unsigned char *data = (unsigned char*)pcilib_kmem_get_ua(ctx->pcilib, ring); - uint32_t ring_pa = pcilib_kmem_get_pa(ctx->pcilib, ring); + unsigned char *data = (unsigned char*)pcilib_kmem_get_ua(ctx->dmactx.pcilib, ring); + uint32_t ring_pa = pcilib_kmem_get_pa(ctx->dmactx.pcilib, ring); if (preserve) { - if (info->desc.direction == PCILIB_DMA_FROM_DEVICE) err = dma_nwl_compute_read_c2s_pointers(ctx, info, data, ring_pa); - else err = dma_nwl_compute_read_s2c_pointers(ctx, info, data, ring_pa); + if (ectx->desc->direction == PCILIB_DMA_FROM_DEVICE) err = dma_nwl_compute_read_c2s_pointers(ctx, ectx, data, ring_pa); + else err = dma_nwl_compute_read_s2c_pointers(ctx, ectx, data, ring_pa); if (err) preserve = 0; } if (preserve) { - info->reused = 1; - buf_sz = pcilib_kmem_get_block_size(ctx->pcilib, pages, 0); + ectx->reused = 1; + buf_sz = pcilib_kmem_get_block_size(ctx->dmactx.pcilib, pages, 0); } else { - info->reused = 0; + ectx->reused = 0; memset(data, 0, PCILIB_NWL_DMA_PAGES * PCILIB_NWL_DMA_DESCRIPTOR_SIZE); for (i = 0; i < PCILIB_NWL_DMA_PAGES; i++, data += PCILIB_NWL_DMA_DESCRIPTOR_SIZE) { - buf_pa = pcilib_kmem_get_block_pa(ctx->pcilib, pages, i); - buf_sz = pcilib_kmem_get_block_size(ctx->pcilib, pages, i); + buf_pa = pcilib_kmem_get_block_pa(ctx->dmactx.pcilib, pages, i); + buf_sz = pcilib_kmem_get_block_size(ctx->dmactx.pcilib, pages, i); NWL_RING_SET(data, DMA_BD_NDESC_OFFSET, ring_pa + ((i + 1) % PCILIB_NWL_DMA_PAGES) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE); NWL_RING_SET(data, DMA_BD_BUFAL_OFFSET, buf_pa&0xFFFFFFFF); @@ -160,25 +160,25 @@ static int dma_nwl_allocate_engine_buffers(nwl_dma_t *ctx, pcilib_nwl_engine_des nwl_write_register(val, ctx, base, REG_DMA_ENG_NEXT_BD); nwl_write_register(val, ctx, base, REG_SW_NEXT_BD); - info->head = 0; - info->tail = 0; + ectx->head = 0; + ectx->tail = 0; } - info->ring = ring; - info->pages = pages; - info->page_size = buf_sz; - info->ring_size = PCILIB_NWL_DMA_PAGES; + ectx->ring = ring; + ectx->pages = pages; + ectx->page_size = buf_sz; + ectx->ring_size = PCILIB_NWL_DMA_PAGES; return 0; } -static size_t dma_nwl_clean_buffers(nwl_dma_t * ctx, pcilib_nwl_engine_description_t *info) { +static size_t dma_nwl_clean_buffers(nwl_dma_t * ctx, pcilib_nwl_engine_context_t *ectx) { size_t res = 0; uint32_t status; - unsigned char *ring = pcilib_kmem_get_ua(ctx->pcilib, info->ring); - ring += info->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; + unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring); + ring += ectx->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; next_buffer: status = NWL_RING_GET(ring, DMA_BD_BUFL_STATUS_OFFSET)&DMA_BD_STATUS_MASK; @@ -195,17 +195,17 @@ next_buffer: } if (status & DMA_BD_COMP_MASK) { - info->tail++; - if (info->tail == info->ring_size) { - ring -= (info->tail - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - info->tail = 0; + ectx->tail++; + if (ectx->tail == ectx->ring_size) { + ring -= (ectx->tail - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; + ectx->tail = 0; } else { ring += PCILIB_NWL_DMA_DESCRIPTOR_SIZE; } res++; - if (info->tail != info->head) goto next_buffer; + if (ectx->tail != ectx->head) goto next_buffer; } // printf("====> Cleaned: %i\n", res); @@ -213,18 +213,18 @@ next_buffer: } -static size_t dma_nwl_get_next_buffer(nwl_dma_t * ctx, pcilib_nwl_engine_description_t *info, size_t n_buffers, pcilib_timeout_t timeout) { +static size_t dma_nwl_get_next_buffer(nwl_dma_t * ctx, pcilib_nwl_engine_context_t *ectx, size_t n_buffers, pcilib_timeout_t timeout) { struct timeval start, cur; size_t res, n = 0; size_t head; - for (head = info->head; (((head + 1)%info->ring_size) != info->tail)&&(n < n_buffers); head++, n++); - if (n == n_buffers) return info->head; + for (head = ectx->head; (((head + 1)%ectx->ring_size) != ectx->tail)&&(n < n_buffers); head++, n++); + if (n == n_buffers) return ectx->head; gettimeofday(&start, NULL); - res = dma_nwl_clean_buffers(ctx, info); + res = dma_nwl_clean_buffers(ctx, ectx); if (res == (size_t)-1) return PCILIB_DMA_BUFFER_INVALID; else n += res; @@ -237,7 +237,7 @@ static size_t dma_nwl_get_next_buffer(nwl_dma_t * ctx, pcilib_nwl_engine_descrip usleep (10); - res = dma_nwl_clean_buffers(ctx, info); + res = dma_nwl_clean_buffers(ctx, ectx); if (res == (size_t)-1) return PCILIB_DMA_BUFFER_INVALID; else if (res > 0) { gettimeofday(&start, NULL); @@ -247,48 +247,48 @@ static size_t dma_nwl_get_next_buffer(nwl_dma_t * ctx, pcilib_nwl_engine_descrip if (n < n_buffers) return PCILIB_DMA_BUFFER_INVALID; - return info->head; + return ectx->head; } -static int dma_nwl_push_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, size_t size, int eop, pcilib_timeout_t timeout) { +static int dma_nwl_push_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_context_t *ectx, size_t size, int eop, pcilib_timeout_t timeout) { int flags = 0; uint32_t val; - unsigned char *ring = pcilib_kmem_get_ua(ctx->pcilib, info->ring); - uint32_t ring_pa = pcilib_kmem_get_pa(ctx->pcilib, info->ring); + unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring); + uint32_t ring_pa = pcilib_kmem_get_pa(ctx->dmactx.pcilib, ectx->ring); - ring += info->head * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; + ring += ectx->head * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - if (!info->writting) { + if (!ectx->writting) { flags |= DMA_BD_SOP_MASK; - info->writting = 1; + ectx->writting = 1; } if (eop) { flags |= DMA_BD_EOP_MASK; - info->writting = 0; + ectx->writting = 0; } NWL_RING_SET(ring, DMA_BD_BUFL_CTRL_OFFSET, size|flags); NWL_RING_SET(ring, DMA_BD_BUFL_STATUS_OFFSET, size); - info->head++; - if (info->head == info->ring_size) info->head = 0; + ectx->head++; + if (ectx->head == ectx->ring_size) ectx->head = 0; - val = ring_pa + info->head * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - nwl_write_register(val, ctx, info->base_addr, REG_SW_NEXT_BD); + val = ring_pa + ectx->head * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; + nwl_write_register(val, ctx, ectx->base_addr, REG_SW_NEXT_BD); return 0; } -static size_t dma_nwl_wait_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, size_t *size, int *eop, pcilib_timeout_t timeout) { +static size_t dma_nwl_wait_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_context_t *ectx, size_t *size, int *eop, pcilib_timeout_t timeout) { struct timeval start, cur; uint32_t status_size, status; - unsigned char *ring = pcilib_kmem_get_ua(ctx->pcilib, info->ring); + unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring); - ring += info->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; + ring += ectx->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; gettimeofday(&start, NULL); @@ -309,13 +309,13 @@ static size_t dma_nwl_wait_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_description_ /* if (mrd) { - if ((info->tail + 1) == info->ring_size) ring -= info->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; + if ((ectx->tail + 1) == ectx->ring_size) ring -= ectx->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; else ring += PCILIB_NWL_DMA_DESCRIPTOR_SIZE; *mrd = NWL_RING_GET(ring, DMA_BD_BUFL_STATUS_OFFSET)&DMA_BD_COMP_MASK; } */ - return info->tail; + return ectx->tail; } usleep(10); @@ -327,25 +327,25 @@ static size_t dma_nwl_wait_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_description_ /* // This function is not used now, but we may need it in the future -static int dma_nwl_is_overflown(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info) { +static int dma_nwl_is_overflown(nwl_dma_t *ctx, pcilib_nwl_engine_context_t *ectx) { uint32_t status; - unsigned char *ring = pcilib_kmem_get_ua(ctx->pcilib, info->ring); - if (info->tail > 0) ring += (info->tail - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - else ring += (info->ring_size - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; + unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring); + if (ectx->tail > 0) ring += (ectx->tail - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; + else ring += (ectx->ring_size - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; status = NWL_RING_GET(ring, DMA_BD_BUFL_STATUS_OFFSET); return status&DMA_BD_COMP_MASK?1:0; } */ -static int dma_nwl_return_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info) { +static int dma_nwl_return_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_context_t *ectx) { uint32_t val; - unsigned char *ring = pcilib_kmem_get_ua(ctx->pcilib, info->ring); - uint32_t ring_pa = pcilib_kmem_get_pa(ctx->pcilib, info->ring); - size_t bufsz = pcilib_kmem_get_block_size(ctx->pcilib, info->pages, info->tail); + unsigned char *ring = pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring); + uint32_t ring_pa = pcilib_kmem_get_pa(ctx->dmactx.pcilib, ectx->ring); + size_t bufsz = pcilib_kmem_get_block_size(ctx->dmactx.pcilib, ectx->pages, ectx->tail); - ring += info->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; + ring += ectx->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; #ifdef NWL_GENERATE_DMA_IRQ NWL_RING_SET(ring, DMA_BD_BUFL_CTRL_OFFSET, bufsz | DMA_BD_INT_ERROR_MASK | DMA_BD_INT_COMP_MASK); @@ -355,11 +355,11 @@ static int dma_nwl_return_buffer(nwl_dma_t *ctx, pcilib_nwl_engine_description_t NWL_RING_SET(ring, DMA_BD_BUFL_STATUS_OFFSET, 0); - val = ring_pa + info->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; - nwl_write_register(val, ctx, info->base_addr, REG_SW_NEXT_BD); + val = ring_pa + ectx->tail * PCILIB_NWL_DMA_DESCRIPTOR_SIZE; + nwl_write_register(val, ctx, ectx->base_addr, REG_SW_NEXT_BD); - info->tail++; - if (info->tail == info->ring_size) info->tail = 0; + ectx->tail++; + if (ectx->tail == ectx->ring_size) ectx->tail = 0; return 0; } @@ -368,34 +368,34 @@ int dma_nwl_get_status(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcil size_t i; uint32_t bstatus; nwl_dma_t *ctx = (nwl_dma_t*)vctx; - pcilib_nwl_engine_description_t *info = ctx->engines + dma; - unsigned char *ring = (unsigned char*)pcilib_kmem_get_ua(ctx->pcilib, info->ring); + pcilib_nwl_engine_context_t *ectx = ctx->engines + dma; + unsigned char *ring = (unsigned char*)pcilib_kmem_get_ua(ctx->dmactx.pcilib, ectx->ring); if (!status) return -1; - status->started = info->started; - status->ring_size = info->ring_size; - status->buffer_size = info->page_size; - status->ring_tail = info->tail; + status->started = ectx->started; + status->ring_size = ectx->ring_size; + status->buffer_size = ectx->page_size; + status->ring_tail = ectx->tail; - if (info->desc.direction == PCILIB_DMA_FROM_DEVICE) { + if (ectx->desc->direction == PCILIB_DMA_FROM_DEVICE) { size_t pos = 0; - for (i = 0; i < info->ring_size; i++) { + for (i = 0; i < ectx->ring_size; i++) { pos = status->ring_tail + i; - if (pos >= info->ring_size) pos -= info->ring_size; + if (pos >= ectx->ring_size) pos -= ectx->ring_size; bstatus = NWL_RING_GET(ring + pos * PCILIB_NWL_DMA_DESCRIPTOR_SIZE, DMA_BD_BUFL_STATUS_OFFSET); if ((bstatus&(DMA_BD_ERROR_MASK|DMA_BD_COMP_MASK)) == 0) break; } status->ring_head = pos; } else { - status->ring_head = info->head; + status->ring_head = ectx->head; } if (buffers) { - for (i = 0; (i < info->ring_size)&&(i < n_buffers); i++) { + for (i = 0; (i < ectx->ring_size)&&(i < n_buffers); i++) { bstatus = NWL_RING_GET(ring, DMA_BD_BUFL_STATUS_OFFSET); buffers[i].error = bstatus & (DMA_BD_ERROR_MASK/*|DMA_BD_SHORT_MASK*/); diff --git a/dma/nwl_irq.c b/dma/nwl_irq.c index e71c76a..cbc087b 100644 --- a/dma/nwl_irq.c +++ b/dma/nwl_irq.c @@ -49,7 +49,7 @@ int dma_nwl_enable_irq(pcilib_dma_context_t *vctx, pcilib_irq_type_t type, pcili val &= ~(DMA_INT_ENABLE|DMA_USER_INT_ENABLE); nwl_write_register(val, ctx, ctx->base_addr, REG_DMA_CTRL_STATUS); - pcilib_clear_irq(ctx->pcilib, NWL_DMA_IRQ_SOURCE); + pcilib_clear_irq(ctx->dmactx.pcilib, NWL_DMA_IRQ_SOURCE); if (type & PCILIB_DMA_IRQ) val |= DMA_INT_ENABLE; if (type & PCILIB_EVENT_IRQ) val |= DMA_USER_INT_ENABLE; @@ -104,15 +104,15 @@ int dma_nwl_acknowledge_irq(pcilib_dma_context_t *vctx, pcilib_irq_type_t irq_ty uint32_t val; nwl_dma_t *ctx = (nwl_dma_t*)vctx; - pcilib_nwl_engine_description_t *info = ctx->engines + irq_source; + pcilib_nwl_engine_context_t *ectx = ctx->engines + irq_source; if (irq_type != PCILIB_DMA_IRQ) return PCILIB_ERROR_NOTSUPPORTED; - if (irq_source >= ctx->n_engines) return PCILIB_ERROR_NOTAVAILABLE; + if (irq_source >= ctx->dmactx.pcilib->num_engines) return PCILIB_ERROR_NOTAVAILABLE; - nwl_read_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS); + nwl_read_register(val, ctx, ectx->base_addr, REG_DMA_ENG_CTRL_STATUS); if (val & DMA_ENG_INT_ACTIVE_MASK) { val |= DMA_ENG_ALLINT_MASK; - nwl_write_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS); + nwl_write_register(val, ctx, ectx->base_addr, REG_DMA_ENG_CTRL_STATUS); } return 0; diff --git a/dma/nwl_irq.h b/dma/nwl_irq.h index 811b632..b49946b 100644 --- a/dma/nwl_irq.h +++ b/dma/nwl_irq.h @@ -1,5 +1,5 @@ -#ifndef _PCILIB_NWL_IRQ_H -#define _PCILIB_NWL_IRQ_H +#ifndef _PCILIB_DMA_NWL_IRQ_H +#define _PCILIB_DMA_NWL_IRQ_H int dma_nwl_init_irq(nwl_dma_t *ctx, uint32_t val); int dma_nwl_free_irq(nwl_dma_t *ctx); @@ -7,4 +7,4 @@ int dma_nwl_free_irq(nwl_dma_t *ctx); int dma_nwl_enable_engine_irq(nwl_dma_t *ctx, pcilib_dma_engine_t dma); int dma_nwl_disable_engine_irq(nwl_dma_t *ctx, pcilib_dma_engine_t dma); -#endif /* _PCILIB_NWL_IRQ_H */ +#endif /* _PCILIB_DMA_NWL_IRQ_H */ diff --git a/dma/nwl_loopback.c b/dma/nwl_loopback.c index 381a462..1a0cd93 100644 --- a/dma/nwl_loopback.c +++ b/dma/nwl_loopback.c @@ -25,7 +25,7 @@ int dma_nwl_start_loopback(nwl_dma_t *ctx, pcilib_dma_direction_t direction, si val = packet_size; nwl_write_register(val, ctx, ctx->base_addr, PKT_SIZE_ADDRESS); - if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) { + if (ctx->type == NWL_MODIFICATION_DEFAULT) { switch (direction) { case PCILIB_DMA_BIDIRECTIONAL: val = LOOPBACK; @@ -54,7 +54,7 @@ int dma_nwl_stop_loopback(nwl_dma_t *ctx) { engine initialized in previous run, and benchmark is only actual usage. Otherwise, we should detect current loopback status during initialization */ - if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) { + if (ctx->type == NWL_MODIFICATION_DEFAULT) { nwl_write_register(val, ctx, ctx->base_addr, TX_CONFIG_ADDRESS); nwl_write_register(val, ctx, ctx->base_addr, RX_CONFIG_ADDRESS); } @@ -77,25 +77,25 @@ double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dm 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); + pcilib_dma_engine_t readid = pcilib_find_dma_by_addr(ctx->dmactx.pcilib, PCILIB_DMA_FROM_DEVICE, dma); + pcilib_dma_engine_t writeid = pcilib_find_dma_by_addr(ctx->dmactx.pcilib, PCILIB_DMA_TO_DEVICE, dma); if (size%sizeof(uint32_t)) size = 1 + size / sizeof(uint32_t); else size /= sizeof(uint32_t); // Not supported - if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) { + if (ctx->type == NWL_MODIFICATION_DEFAULT) { if (direction == PCILIB_DMA_TO_DEVICE) return -1.; } -// else if ((direction == PCILIB_DMA_FROM_DEVICE)&&(ctx->type != PCILIB_DMA_MODIFICATION_DEFAULT)) return -1.; +// else if ((direction == PCILIB_DMA_FROM_DEVICE)&&(ctx->type != NWL_MODIFICATION_DEFAULT)) return -1.; // Stop Generators and drain old data - if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx); + if (ctx->type == NWL_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); + err = pcilib_skip_dma(ctx->dmactx.pcilib, readid); if (err) { pcilib_error("Can't start benchmark, devices continuously writes unexpected data using DMA engine"); return -1; @@ -125,31 +125,31 @@ double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dm return -1; } - if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) { - pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e5); + if (ctx->type == NWL_MODIFICATION_IPECAMERA) { + pcilib_write_register(ctx->dmactx.pcilib, NULL, "control", 0x1e5); usleep(100000); - pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1); + pcilib_write_register(ctx->dmactx.pcilib, NULL, "control", 0x1e1); // This way causes more problems with garbage - //pcilib_write_register(ctx->pcilib, NULL, "control", 0x3e1); + //pcilib_write_register(ctx->dmactx.pcilib, NULL, "control", 0x3e1); } // Benchmark for (iter = 0; iter < iterations; iter++) { memset(cmp, 0x13 + iter, size * sizeof(uint32_t)); - if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) { - pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1); + if (ctx->type == NWL_MODIFICATION_IPECAMERA) { + pcilib_write_register(ctx->dmactx.pcilib, NULL, "control", 0x1e1); } - if ((direction&PCILIB_DMA_TO_DEVICE)||(ctx->type != PCILIB_DMA_MODIFICATION_DEFAULT)) { + if ((direction&PCILIB_DMA_TO_DEVICE)||(ctx->type != NWL_MODIFICATION_DEFAULT)) { memcpy(buf, cmp, size * sizeof(uint32_t)); if (direction&PCILIB_DMA_TO_DEVICE) { gettimeofday(&start, NULL); } - err = pcilib_write_dma(ctx->pcilib, writeid, addr, size * sizeof(uint32_t), buf, &bytes); + err = pcilib_write_dma(ctx->dmactx.pcilib, writeid, addr, size * sizeof(uint32_t), buf, &bytes); if ((err)||(bytes != size * sizeof(uint32_t))) { error = "Write failed"; break; @@ -165,8 +165,8 @@ double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dm } } - if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) { - pcilib_write_register(ctx->pcilib, NULL, "control", 0x3e1); + if (ctx->type == NWL_MODIFICATION_IPECAMERA) { + pcilib_write_register(ctx->dmactx.pcilib, NULL, "control", 0x3e1); } memset(buf, 0, size * sizeof(uint32_t)); @@ -180,7 +180,7 @@ double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dm retry: #endif - err = pcilib_read_dma(ctx->pcilib, readid, addr, packet_size * sizeof(uint32_t), buf + (bytes>>2), &rbytes); + err = pcilib_read_dma(ctx->dmactx.pcilib, readid, addr, packet_size * sizeof(uint32_t), buf + (bytes>>2), &rbytes); if ((err)||(rbytes%sizeof(uint32_t))) { break; } @@ -227,8 +227,8 @@ double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dm #endif } - if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) { - pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1); + if (ctx->type == NWL_MODIFICATION_IPECAMERA) { + pcilib_write_register(ctx->dmactx.pcilib, NULL, "control", 0x1e1); } if (error) { @@ -245,7 +245,7 @@ double dma_nwl_benchmark(pcilib_dma_context_t *vctx, pcilib_dma_engine_addr_t dm __sync_synchronize(); if (direction == PCILIB_DMA_FROM_DEVICE) { - pcilib_skip_dma(ctx->pcilib, readid); + pcilib_skip_dma(ctx->dmactx.pcilib, readid); } free(cmp); diff --git a/dma/nwl_loopback.h b/dma/nwl_loopback.h index 63c8446..d0b53cf 100644 --- a/dma/nwl_loopback.h +++ b/dma/nwl_loopback.h @@ -1,7 +1,7 @@ -#ifndef _PCILIB_NWL_LOOPBACK_H -#define _PCILIB_NWL_LOOPBACK_H +#ifndef _PCILIB_DMA_NWL_LOOPBACK_H +#define _PCILIB_DMA_NWL_LOOPBACK_H int dma_nwl_start_loopback(nwl_dma_t *ctx, pcilib_dma_direction_t direction, size_t packet_size); int dma_nwl_stop_loopback(nwl_dma_t *ctx); -#endif /* _PCILIB_NWL_LOOPBACK_H */ +#endif /* _PCILIB_DMA_NWL_LOOPBACK_H */ diff --git a/dma/nwl_private.h b/dma/nwl_private.h index 756e6ca..934fa04 100644 --- a/dma/nwl_private.h +++ b/dma/nwl_private.h @@ -2,7 +2,7 @@ #define _PCILIB_DMA_NWL_PRIVATE_H typedef struct nwl_dma_s nwl_dma_t; -typedef struct pcilib_nwl_engine_description_s pcilib_nwl_engine_description_t; +typedef struct pcilib_nwl_engine_context_s pcilib_nwl_engine_context_t; #define NWL_DMA_IRQ_SOURCE 0 @@ -20,17 +20,17 @@ typedef struct pcilib_nwl_engine_description_s pcilib_nwl_engine_description_t; #include "nwl.h" #include "nwl_irq.h" -#include "nwl_register.h" #include "nwl_engine.h" #include "nwl_loopback.h" #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) -struct pcilib_nwl_engine_description_s { - pcilib_dma_engine_description_t desc; + +struct pcilib_nwl_engine_context_s { + const pcilib_dma_engine_description_t *desc; char *base_addr; - + size_t ring_size, page_size; size_t head, tail; pcilib_kmem_handle_t *ring; @@ -42,15 +42,18 @@ struct pcilib_nwl_engine_description_s { int preserve; /**< indicates that DMA should not be stopped during clean-up */ }; +typedef enum { + NWL_MODIFICATION_DEFAULT, + NWL_MODIFICATION_IPECAMERA +} nwl_modification_t; struct nwl_dma_s { - struct pcilib_dma_context_s dmactx; - - pcilib_t *pcilib; - - pcilib_dma_modification_t type; - - pcilib_register_bank_description_t *dma_bank; + pcilib_dma_context_t dmactx; + + nwl_modification_t type; + int ignore_eop; /**< always set end-of-packet */ + + const pcilib_register_bank_description_t *dma_bank; char *base_addr; pcilib_irq_type_t irq_enabled; /**< indicates that IRQs are enabled */ @@ -59,9 +62,10 @@ struct nwl_dma_s { int irq_started; /**< indicates that IRQ subsystem is initialized (detecting which types should be preserverd) */ int loopback_started; /**< indicates that benchmarking subsystem is initialized */ - pcilib_dma_engine_t n_engines; - pcilib_nwl_engine_description_t engines[PCILIB_MAX_DMA_ENGINES + 1]; +// pcilib_dma_engine_t n_engines; + pcilib_nwl_engine_context_t engines[PCILIB_MAX_DMA_ENGINES + 1]; }; +int nwl_add_registers(nwl_dma_t *ctx); #endif /* _PCILIB_DMA_NWL_PRIVATE_H */ diff --git a/dma/nwl_register.c b/dma/nwl_register.c deleted file mode 100644 index 6a3771a..0000000 --- a/dma/nwl_register.c +++ /dev/null @@ -1,77 +0,0 @@ -#define _PCILIB_NWL_REGISTER_C - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/time.h> - -#include "pcilib.h" - -#include "pci.h" -#include "error.h" -#include "tools.h" - -#include "nwl_private.h" -#include "nwl_register.h" - -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; - - if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) { - 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; -} diff --git a/dma/nwl_register.h b/dma/nwl_register.h deleted file mode 100644 index a71942b..0000000 --- a/dma/nwl_register.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef _PCILIB_NWL_REGISTERS_H -#define _PCILIB_NWL_REGISTERS_H - -#ifdef _PCILIB_NWL_REGISTER_C - // 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, 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_W , 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} -}; - -#endif /* _PCILIB_NWL_REGISTERS_C */ - -int nwl_add_registers(nwl_dma_t *ctx); - -#endif /* _PCILIB_NWL_REGISTERS_H */ |