/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to dma/nwl.c

  • Committer: Suren A. Chilingaryan
  • Date: 2015-04-20 20:01:04 UTC
  • Revision ID: csa@suren.me-20150420200104-b5xny65io8lvoz3w
Big redign of model structures

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#define _PCILIB_DMA_NWL_C
2
2
#define _BSD_SOURCE
 
3
#define _GNU_SOURCE
3
4
 
4
5
#include <stdio.h>
5
6
#include <stdlib.h>
11
12
#include "pcilib.h"
12
13
#include "error.h"
13
14
#include "tools.h"
 
15
 
14
16
#include "nwl_private.h"
15
 
 
16
17
#include "nwl_defines.h"
17
18
 
18
19
int dma_nwl_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) {
25
26
    }
26
27
 
27
28
    if (dma == PCILIB_DMA_ENGINE_INVALID) return 0;
28
 
    else if (dma > ctx->n_engines) return PCILIB_ERROR_INVALID_BANK;
 
29
    else if (dma > ctx->dmactx.pcilib->num_engines) return PCILIB_ERROR_INVALID_BANK;
29
30
 
30
31
    if (flags&PCILIB_DMA_FLAG_PERSISTENT) ctx->engines[dma].preserve = 1;
31
32
 
44
45
    
45
46
        // stop everything
46
47
    if (dma == PCILIB_DMA_ENGINE_INVALID) {
47
 
        for (dma = 0; dma < ctx->n_engines; dma++) {
 
48
        for (dma = 0; dma < ctx->dmactx.pcilib->num_engines; dma++) {
48
49
            if (flags&PCILIB_DMA_FLAG_PERSISTENT) {
49
50
                ctx->engines[dma].preserve = 0;
50
51
            }
63
64
        return 0;
64
65
    }
65
66
    
66
 
    if (dma > ctx->n_engines) return PCILIB_ERROR_INVALID_BANK;
 
67
    if (dma > ctx->dmactx.pcilib->num_engines) return PCILIB_ERROR_INVALID_BANK;
67
68
    
68
69
            // ignorign previous setting if flag specified
69
70
    if (flags&PCILIB_DMA_FLAG_PERSISTENT) {
74
75
}
75
76
 
76
77
 
77
 
pcilib_dma_context_t *dma_nwl_init(pcilib_t *pcilib, pcilib_dma_modification_t type, void *arg) {
78
 
    int i;
 
78
pcilib_dma_context_t *dma_nwl_init(pcilib_t *pcilib, const char *model, const void *arg) {
 
79
    int i, j;
79
80
    int err;
80
 
    pcilib_dma_engine_t n_engines;
81
 
 
82
 
    pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
 
81
    
 
82
    pcilib_dma_engine_t dma;
 
83
    pcilib_register_description_t eregs[NWL_MAX_DMA_ENGINE_REGISTERS];
 
84
    const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
83
85
    
84
86
    nwl_dma_t *ctx = malloc(sizeof(nwl_dma_t));
85
 
    if (ctx) {
86
 
        memset(ctx, 0, sizeof(nwl_dma_t));
87
 
        ctx->pcilib = pcilib;
88
 
        ctx->type = type;
89
 
 
90
 
        if (type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
91
 
            ctx->dmactx.ignore_eop = 1;
92
 
        }
93
 
 
94
 
        pcilib_register_bank_t dma_bank = pcilib_find_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA);
95
 
        if (dma_bank == PCILIB_REGISTER_BANK_INVALID) {
96
 
            free(ctx);
97
 
            pcilib_error("DMA Register Bank could not be found");
98
 
            return NULL;
99
 
        }
100
 
        
101
 
        ctx->dma_bank = model_info->banks + dma_bank;
102
 
        ctx->base_addr = pcilib_resolve_register_address(pcilib, ctx->dma_bank->bar, ctx->dma_bank->read_addr);
103
 
 
104
 
        for (i = 0, n_engines = 0; i < 2 * PCILIB_MAX_DMA_ENGINES; i++) {
105
 
            char *addr = ctx->base_addr + DMA_OFFSET + i * DMA_ENGINE_PER_SIZE;
106
 
 
107
 
            memset(ctx->engines + n_engines, 0, sizeof(pcilib_nwl_engine_description_t));
108
 
 
109
 
            err = dma_nwl_read_engine_config(ctx, ctx->engines + n_engines, addr);
110
 
            if (err) continue;
111
 
            
112
 
            pcilib_set_dma_engine_description(pcilib, n_engines, (pcilib_dma_engine_description_t*)(ctx->engines + n_engines));
113
 
            ++n_engines;
114
 
        }
115
 
        pcilib_set_dma_engine_description(pcilib, n_engines, NULL);
116
 
        
117
 
        ctx->n_engines = n_engines;
118
 
        
119
 
        err = nwl_add_registers(ctx);
120
 
        if (err) {
121
 
            free(ctx);
122
 
            pcilib_error("Failed to add DMA registers");
123
 
            return NULL;
124
 
        }
125
 
    }
 
87
    if (!ctx) return NULL;
 
88
 
 
89
    memset(ctx, 0, sizeof(nwl_dma_t));
 
90
 
 
91
    pcilib_register_bank_t dma_bank = pcilib_find_register_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA);
 
92
    if (dma_bank == PCILIB_REGISTER_BANK_INVALID) {
 
93
        free(ctx);
 
94
        pcilib_error("DMA Register Bank could not be found");
 
95
        return NULL;
 
96
    }
 
97
 
 
98
    ctx->dma_bank = model_info->banks + dma_bank;
 
99
    ctx->base_addr = pcilib_resolve_register_address(pcilib, ctx->dma_bank->bar, ctx->dma_bank->read_addr);
 
100
 
 
101
    if ((model)&&(strcasestr(model, "ipecamera"))) {
 
102
        ctx->type = NWL_MODIFICATION_IPECAMERA;
 
103
        ctx->ignore_eop = 1;
 
104
    } else {
 
105
        ctx->type = NWL_MODIFICATION_DEFAULT;
 
106
            
 
107
        err = pcilib_add_registers(pcilib, 0, nwl_xrawdata_registers);
 
108
        if (err) {
 
109
            free(ctx);
 
110
            pcilib_error("Error (%i) adding NWL XRAWDATA registers", err);
 
111
            return NULL;
 
112
        }
 
113
    }
 
114
 
 
115
    for (j = 0; nwl_dma_engine_registers[j].bits; j++);
 
116
    if (j > NWL_MAX_DMA_ENGINE_REGISTERS) {
 
117
        free(ctx);
 
118
        pcilib_error("Too many (%i) engine registers defined, only %i supported", j, NWL_MAX_DMA_ENGINE_REGISTERS);
 
119
        return NULL;
 
120
    }
 
121
 
 
122
    memcpy(eregs, nwl_dma_engine_registers, j * sizeof(pcilib_register_description_t));
 
123
 
 
124
    for (i = 0; i < 2 * PCILIB_MAX_DMA_ENGINES; i++) {
 
125
        pcilib_dma_engine_description_t edesc;
 
126
        char *addr = ctx->base_addr + DMA_OFFSET + i * DMA_ENGINE_PER_SIZE;
 
127
 
 
128
        memset(&edesc, 0, sizeof(pcilib_dma_engine_description_t));
 
129
 
 
130
        err = dma_nwl_read_engine_config(ctx, &edesc, addr);
 
131
        if (err) continue;
 
132
 
 
133
        for (j = 0; nwl_dma_engine_registers[j].bits; j++) {
 
134
            int dma_addr_len = (PCILIB_MAX_DMA_ENGINES > 9)?2:1;
 
135
            const char *dma_direction;
 
136
 
 
137
            eregs[j].name = nwl_dma_engine_register_names[i * NWL_MAX_DMA_ENGINE_REGISTERS + j];
 
138
            eregs[j].addr = nwl_dma_engine_registers[j].addr + (addr - ctx->base_addr);
 
139
            
 
140
            switch (edesc.direction) {
 
141
                case PCILIB_DMA_FROM_DEVICE:
 
142
                    dma_direction =  "r";
 
143
                break;
 
144
                case PCILIB_DMA_TO_DEVICE:
 
145
                    dma_direction = "w";
 
146
                break;
 
147
                default:
 
148
                    dma_direction = "";
 
149
            }    
 
150
            sprintf((char*)eregs[j].name, nwl_dma_engine_registers[j].name, dma_addr_len, edesc.addr, dma_direction);
 
151
        }
 
152
        
 
153
        err = pcilib_add_registers(pcilib, j, eregs);
 
154
        if (err) {
 
155
            free(ctx);
 
156
            pcilib_error("Error (%i) adding NWL DMA registers for engine %i", err, edesc.addr);
 
157
            return NULL;
 
158
        }
 
159
    
 
160
        dma = pcilib_add_dma_engine(pcilib, &edesc);
 
161
        if (dma == PCILIB_DMA_ENGINE_INVALID) {
 
162
            free(ctx);
 
163
            pcilib_error("Problem while registering DMA engine");
 
164
            return NULL;
 
165
        }
 
166
        
 
167
        ctx->engines[dma].desc = &pcilib->engines[dma];
 
168
        ctx->engines[dma].base_addr = addr;
 
169
    }
 
170
 
126
171
    return (pcilib_dma_context_t*)ctx;
127
172
}
128
173
 
130
175
    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
131
176
 
132
177
    if (ctx) {
133
 
        if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx);
 
178
        if (ctx->type == NWL_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx);
134
179
        dma_nwl_free_irq(ctx);
135
180
        dma_nwl_stop(vctx, PCILIB_DMA_ENGINE_ALL, PCILIB_DMA_FLAGS_DEFAULT);
136
181