/alps/pcitool

To get this branch, use:
bzr branch http://darksoft.org/webbzr/alps/pcitool
43 by root
Enumerate DMA engines
1
#define _PCILIB_DMA_NWL_C
45 by root
North West Logick DMA implementation
2
#define _BSD_SOURCE
302 by Suren A. Chilingaryan
Fixes out-of-source builds and minor build issues
3
#define _DEFAULT_SOURCE
236 by Suren A. Chilingaryan
Big redign of model structures
4
#define _GNU_SOURCE
43 by root
Enumerate DMA engines
5
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <string.h>
45 by root
North West Logick DMA implementation
9
#include <unistd.h>
44 by root
DMA engine initialization and basic intrastructure for DMA read/write
10
#include <sys/time.h>
43 by root
Enumerate DMA engines
11
12
#include "pci.h"
13
#include "pcilib.h"
14
#include "error.h"
15
#include "tools.h"
324 by Suren A. Chilingaryan
Documentation update
16
#include "bar.h"
236 by Suren A. Chilingaryan
Big redign of model structures
17
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
18
#include "nwl_private.h"
45 by root
North West Logick DMA implementation
19
#include "nwl_defines.h"
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
20
65 by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces
21
int dma_nwl_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) {
99 by root
Fix bug causing failures of NWL engine to inherit kernel buffers
22
    int err;
65 by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces
23
    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
24
25
    if (!ctx->started) {
26
	// global initialization, should we do anything?
27
	ctx->started = 1;
59 by Suren A. Chilingaryan
Reorganization of NWL engine, step 1
28
    }
29
65 by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces
30
    if (dma == PCILIB_DMA_ENGINE_INVALID) return 0;
236 by Suren A. Chilingaryan
Big redign of model structures
31
    else if (dma > ctx->dmactx.pcilib->num_engines) return PCILIB_ERROR_INVALID_BANK;
65 by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces
32
127 by Suren A. Chilingaryan
Reverts r99 and fixes inheritance of kernel buffers properly
33
    if (flags&PCILIB_DMA_FLAG_PERSISTENT) ctx->engines[dma].preserve = 1;
34
99 by root
Fix bug causing failures of NWL engine to inherit kernel buffers
35
    err = dma_nwl_start_engine(ctx, dma);
36
    
37
    return err;
65 by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces
38
}
39
40
int dma_nwl_stop(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) {
59 by Suren A. Chilingaryan
Reorganization of NWL engine, step 1
41
    int err;
65 by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces
42
    int preserving = 0;
59 by Suren A. Chilingaryan
Reorganization of NWL engine, step 1
43
65 by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces
44
    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
45
    
46
    if (!ctx->started) return 0;
47
    
48
	// stop everything
49
    if (dma == PCILIB_DMA_ENGINE_INVALID) {
236 by Suren A. Chilingaryan
Big redign of model structures
50
        for (dma = 0; dma < ctx->dmactx.pcilib->num_engines; dma++) {
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
51
	    if (flags&PCILIB_DMA_FLAG_PERSISTENT) {
65 by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces
52
		ctx->engines[dma].preserve = 0;
53
	    }
54
	
55
	    if (ctx->engines[dma].preserve) preserving = 1;
71 by Suren A. Chilingaryan
First iteration of work to preserve DMA state between executions
56
	    
57
	    err = dma_nwl_stop_engine(ctx, dma);
58
	    if (err) return err;
65 by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces
59
	}
60
	    
61
	    // global cleanup, should we do anything?
62
	if (!preserving) {
63
	    ctx->started = 0;
64
	}
65
	
66
	return 0;
67
    }
68
    
236 by Suren A. Chilingaryan
Big redign of model structures
69
    if (dma > ctx->dmactx.pcilib->num_engines) return PCILIB_ERROR_INVALID_BANK;
65 by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces
70
    
71
	    // ignorign previous setting if flag specified
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
72
    if (flags&PCILIB_DMA_FLAG_PERSISTENT) {
65 by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces
73
	ctx->engines[dma].preserve = 0;
74
    }
75
    
76
    return dma_nwl_stop_engine(ctx, dma);
44 by root
DMA engine initialization and basic intrastructure for DMA read/write
77
}
78
55 by Suren A. Chilingaryan
IRQ support in NWL DMA engine
79
236 by Suren A. Chilingaryan
Big redign of model structures
80
pcilib_dma_context_t *dma_nwl_init(pcilib_t *pcilib, const char *model, const void *arg) {
81
    int i, j;
43 by root
Enumerate DMA engines
82
    int err;
236 by Suren A. Chilingaryan
Big redign of model structures
83
    
84
    pcilib_dma_engine_t dma;
85
    pcilib_register_description_t eregs[NWL_MAX_DMA_ENGINE_REGISTERS];
86
    const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
43 by root
Enumerate DMA engines
87
    
88
    nwl_dma_t *ctx = malloc(sizeof(nwl_dma_t));
236 by Suren A. Chilingaryan
Big redign of model structures
89
    if (!ctx) return NULL;
90
91
    memset(ctx, 0, sizeof(nwl_dma_t));
92
93
    pcilib_register_bank_t dma_bank = pcilib_find_register_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA);
94
    if (dma_bank == PCILIB_REGISTER_BANK_INVALID) {
95
	free(ctx);
96
	pcilib_error("DMA Register Bank could not be found");
97
	return NULL;
98
    }
99
100
    ctx->dma_bank = model_info->banks + dma_bank;
333 by Suren A. Chilingaryan
Adjust IPEDMA register model to address new revision
101
    ctx->base_addr = pcilib_resolve_bar_address(pcilib, ctx->dma_bank->bar, ctx->dma_bank->read_addr);
236 by Suren A. Chilingaryan
Big redign of model structures
102
103
    if ((model)&&(strcasestr(model, "ipecamera"))) {
104
	ctx->type = NWL_MODIFICATION_IPECAMERA;
105
	ctx->ignore_eop = 1;
106
    } else {
107
	ctx->type = NWL_MODIFICATION_DEFAULT;
108
	    
303 by Suren A. Chilingaryan
Initial integration of XML support
109
	err = pcilib_add_registers(pcilib, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, nwl_xrawdata_registers, NULL);
236 by Suren A. Chilingaryan
Big redign of model structures
110
	if (err) {
111
	    free(ctx);
112
	    pcilib_error("Error (%i) adding NWL XRAWDATA registers", err);
113
	    return NULL;
114
	}
115
    }
116
117
    for (j = 0; nwl_dma_engine_registers[j].bits; j++);
118
    if (j > NWL_MAX_DMA_ENGINE_REGISTERS) {
119
	free(ctx);
120
	pcilib_error("Too many (%i) engine registers defined, only %i supported", j, NWL_MAX_DMA_ENGINE_REGISTERS);
121
	return NULL;
122
    }
123
124
    memcpy(eregs, nwl_dma_engine_registers, j * sizeof(pcilib_register_description_t));
125
126
    for (i = 0; i < 2 * PCILIB_MAX_DMA_ENGINES; i++) {
127
	pcilib_dma_engine_description_t edesc;
128
	char *addr = ctx->base_addr + DMA_OFFSET + i * DMA_ENGINE_PER_SIZE;
129
130
	memset(&edesc, 0, sizeof(pcilib_dma_engine_description_t));
131
132
	err = dma_nwl_read_engine_config(ctx, &edesc, addr);
133
	if (err) continue;
134
135
	for (j = 0; nwl_dma_engine_registers[j].bits; j++) {
136
	    int dma_addr_len = (PCILIB_MAX_DMA_ENGINES > 9)?2:1;
137
	    const char *dma_direction;
138
139
	    eregs[j].name = nwl_dma_engine_register_names[i * NWL_MAX_DMA_ENGINE_REGISTERS + j];
140
	    eregs[j].addr = nwl_dma_engine_registers[j].addr + (addr - ctx->base_addr);
141
	    
142
	    switch (edesc.direction) {
143
		case PCILIB_DMA_FROM_DEVICE:
144
		    dma_direction =  "r";
145
		break;
146
		case PCILIB_DMA_TO_DEVICE:
147
		    dma_direction = "w";
148
		break;
149
		default:
150
		    dma_direction = "";
151
	    }    
152
	    sprintf((char*)eregs[j].name, nwl_dma_engine_registers[j].name, dma_addr_len, edesc.addr, dma_direction);
153
	}
154
	
303 by Suren A. Chilingaryan
Initial integration of XML support
155
        err = pcilib_add_registers(pcilib, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, j, eregs, NULL);
236 by Suren A. Chilingaryan
Big redign of model structures
156
	if (err) {
157
	    free(ctx);
158
	    pcilib_error("Error (%i) adding NWL DMA registers for engine %i", err, edesc.addr);
159
	    return NULL;
160
	}
161
    
162
	dma = pcilib_add_dma_engine(pcilib, &edesc);
163
	if (dma == PCILIB_DMA_ENGINE_INVALID) {
164
	    free(ctx);
165
	    pcilib_error("Problem while registering DMA engine");
166
	    return NULL;
167
	}
168
	
169
	ctx->engines[dma].desc = &pcilib->engines[dma];
170
	ctx->engines[dma].base_addr = addr;
171
    }
172
43 by root
Enumerate DMA engines
173
    return (pcilib_dma_context_t*)ctx;
174
}
175
176
void  dma_nwl_free(pcilib_dma_context_t *vctx) {
177
    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
65 by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces
178
66 by Suren A. Chilingaryan
Few fixes
179
    if (ctx) {
236 by Suren A. Chilingaryan
Big redign of model structures
180
	if (ctx->type == NWL_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx);
66 by Suren A. Chilingaryan
Few fixes
181
	dma_nwl_free_irq(ctx);
109 by Suren A. Chilingaryan
Improvements of DMA engine
182
	dma_nwl_stop(vctx, PCILIB_DMA_ENGINE_ALL, PCILIB_DMA_FLAGS_DEFAULT);
66 by Suren A. Chilingaryan
Few fixes
183
	    
184
	free(ctx);
185
    }
43 by root
Enumerate DMA engines
186
}