/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_loopback.c

  • Committer: Suren A. Chilingaryan
  • Date: 2011-10-26 05:12:31 UTC
  • Revision ID: csa@dside.dyndns.org-20111026051231-5ntkozz31hvjzvb5
Improvements of DMA engine

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
 
14
14
#include "nwl_defines.h"
15
15
 
 
16
#define NWL_BUG_EXTRA_DATA
 
17
 
16
18
 
17
19
int dma_nwl_start_loopback(nwl_dma_t *ctx,  pcilib_dma_direction_t direction, size_t packet_size) {
18
20
    uint32_t val;
66
68
    int iter, i;
67
69
    int res;
68
70
    int err;
69
 
    size_t bytes;
 
71
    size_t bytes, rbytes;
70
72
    uint32_t val;
71
73
    uint32_t *buf, *cmp;
72
74
    const char *error = NULL;
73
75
    pcilib_register_value_t regval;
 
76
    size_t packet_size, blocks;    
74
77
 
75
78
    size_t us = 0;
76
79
    struct timeval start, cur;
87
90
    else size /= sizeof(uint32_t);
88
91
 
89
92
        // Not supported
90
 
    if (direction == PCILIB_DMA_TO_DEVICE) return -1.;
91
 
    else if ((direction == PCILIB_DMA_FROM_DEVICE)&&(ctx->type != PCILIB_DMA_MODIFICATION_DEFAULT)) return -1.;
 
93
    if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) {
 
94
        if (direction == PCILIB_DMA_TO_DEVICE) return -1.;
 
95
    }
 
96
//    else if ((direction == PCILIB_DMA_FROM_DEVICE)&&(ctx->type != PCILIB_DMA_MODIFICATION_DEFAULT)) return -1.;
92
97
 
93
98
        // Stop Generators and drain old data
94
99
    if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx);
107
112
    dma_nwl_enable_engine_irq(ctx, writeid);
108
113
#endif /* NWL_GENERATE_DMA_IRQ */
109
114
 
110
 
    dma_nwl_start_loopback(ctx, direction, size * sizeof(uint32_t));
 
115
    if (size * sizeof(uint32_t) > NWL_MAX_PACKET_SIZE) {
 
116
        packet_size = NWL_MAX_PACKET_SIZE;
 
117
        blocks = (size * sizeof(uint32_t)) / packet_size + (((size*sizeof(uint32_t))%packet_size)?1:0);
 
118
    } else {
 
119
        packet_size = size * sizeof(uint32_t);
 
120
        blocks = 1;
 
121
    }
 
122
 
 
123
    dma_nwl_start_loopback(ctx, direction, packet_size);
111
124
 
112
125
        // Allocate memory and prepare data
113
 
    buf = malloc(size * sizeof(uint32_t));
114
 
    cmp = malloc(size * sizeof(uint32_t));
 
126
    buf = malloc(blocks * packet_size * sizeof(uint32_t));
 
127
    cmp = malloc(blocks * packet_size * sizeof(uint32_t));
115
128
    if ((!buf)||(!cmp)) {
116
129
        if (buf) free(buf);
117
130
        if (cmp) free(cmp);
118
131
        return -1;
119
132
    }
120
133
 
121
 
//#ifdef DEBUG_HARDWARE      
122
134
    if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
123
135
        pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e5);
124
136
        usleep(100000);
125
137
        pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1);
 
138
 
 
139
            // This way causes more problems with garbage
 
140
        //pcilib_write_register(ctx->pcilib, NULL, "control", 0x3e1);
126
141
    }
127
 
//#endif /* DEBUG_HARDWARE */
128
142
 
129
143
        // Benchmark
130
144
    for (iter = 0; iter < iterations; iter++) {
131
145
        memset(cmp, 0x13 + iter, size * sizeof(uint32_t));
132
146
 
133
 
//#ifdef DEBUG_HARDWARE      
134
147
        if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
135
148
            pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1);
136
149
        }
137
 
//#endif /* DEBUG_HARDWARE */
138
150
 
139
 
        gettimeofday(&start, NULL);
140
 
        if (direction&PCILIB_DMA_TO_DEVICE) {
 
151
        if ((direction&PCILIB_DMA_TO_DEVICE)||(ctx->type != PCILIB_DMA_MODIFICATION_DEFAULT)) {
141
152
            memcpy(buf, cmp, size * sizeof(uint32_t));
142
153
 
 
154
            if (direction&PCILIB_DMA_TO_DEVICE) {
 
155
                gettimeofday(&start, NULL);
 
156
            }
 
157
            
143
158
            err = pcilib_write_dma(ctx->pcilib, writeid, addr, size * sizeof(uint32_t), buf, &bytes);
144
159
            if ((err)||(bytes != size * sizeof(uint32_t))) {
145
160
                error = "Write failed";
146
 
                break;
 
161
                break;
 
162
            }
 
163
            
 
164
            if (direction&PCILIB_DMA_TO_DEVICE) {
 
165
                // wait written
 
166
                if (direction == PCILIB_DMA_TO_DEVICE) {
 
167
                    dma_nwl_wait_completion(ctx, writeid, PCILIB_DMA_TIMEOUT);
 
168
                }
 
169
                gettimeofday(&cur, NULL);
 
170
                us += ((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec));    
147
171
            }
148
172
        }
149
173
 
150
 
//#ifdef DEBUG_HARDWARE      
151
174
        if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
152
175
            pcilib_write_register(ctx->pcilib, NULL, "control", 0x3e1);
153
176
        }
154
 
//#endif /* DEBUG_HARDWARE */
155
177
 
156
178
        memset(buf, 0, size * sizeof(uint32_t));
157
 
        
158
 
        err = pcilib_read_dma(ctx->pcilib, readid, addr, size * sizeof(uint32_t), buf, &bytes);
159
 
        gettimeofday(&cur, NULL);
160
 
        us += ((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec));
161
 
 
 
179
 
 
180
        if (direction&PCILIB_DMA_FROM_DEVICE) {
 
181
            gettimeofday(&start, NULL);
 
182
        }
 
183
 
 
184
        for (i = 0, bytes = 0; i < blocks; i++) {
 
185
#ifdef NWL_BUG_EXTRA_DATA
 
186
            retry:
 
187
#endif
 
188
    
 
189
            err = pcilib_read_dma(ctx->pcilib, readid, addr, packet_size * sizeof(uint32_t), buf + (bytes>>2), &rbytes);
 
190
            if ((err)||(rbytes%sizeof(uint32_t))) {
 
191
                break;
 
192
            } 
 
193
#ifdef NWL_BUG_EXTRA_DATA
 
194
            else if (rbytes == 8) {
 
195
                goto retry;     
 
196
            }
 
197
#endif
 
198
            bytes += rbytes;
 
199
        }
 
200
 
 
201
        if (direction&PCILIB_DMA_FROM_DEVICE) {
 
202
            gettimeofday(&cur, NULL);
 
203
            us += ((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec));
 
204
        }
 
205
#ifdef NWL_BUG_EXTRA_DATA
 
206
        if ((err)||((bytes != size * sizeof(uint32_t))&&((bytes - 8) != size * sizeof(uint32_t)))) {
 
207
#else
162
208
        if ((err)||(bytes != size * sizeof(uint32_t))) {
163
 
             error = "Read failed";
164
 
             break;
 
209
#endif
 
210
            printf("Expected: %zu bytes, but %zu read, error: %i\n", size * sizeof(uint32_t), bytes, err);
 
211
            error = "Read failed";
 
212
            break;
165
213
        }
166
214
        
 
215
#ifndef NWL_BUG_EXTRA_DATA
167
216
        if (direction == PCILIB_DMA_BIDIRECTIONAL) {
168
217
            res = memcmp(buf, cmp, size * sizeof(uint32_t));
169
218
            if (res) {
171
220
                    if (buf[i] != cmp[i]) break;
172
221
                
173
222
                bytes = i;
174
 
                printf("Expected: *%lx, Written at position %lu:", 0x13 + iter, bytes);
 
223
                printf("Expected: *0x%lx, Written at dword %lu:", 0x13 + iter, bytes);
175
224
                for (; (i < size)&&(i < (bytes + 16)); i++) {
176
225
                    if (((i - bytes)%8)==0) printf("\n");
177
226
                    printf("% 10lx", buf[i]);
182
231
                break;
183
232
            }
184
233
        }
185
 
 
186
 
#ifdef DEBUG_HARDWARE        
187
 
        puts("====================================");
188
 
 
189
 
        err = pcilib_read_register(ctx->pcilib, NULL, "reg9050", &regval);
190
 
        printf("Status1: %i 0x%lx\n", err, regval);
191
 
        err = pcilib_read_register(ctx->pcilib, NULL, "reg9080", &regval);
192
 
        printf("Start address: %i 0x%lx\n", err,  regval);
193
 
        err = pcilib_read_register(ctx->pcilib, NULL, "reg9090", &regval);
194
 
        printf("End address: %i 0x%lx\n", err,  regval);
195
 
        err = pcilib_read_register(ctx->pcilib, NULL, "reg9100", &regval);
196
 
        printf("Status2: %i 0x%lx\n", err,  regval);
197
 
        err = pcilib_read_register(ctx->pcilib, NULL, "reg9110", &regval);
198
 
        printf("Status3: %i 0x%lx\n", err,  regval);
199
 
        err = pcilib_read_register(ctx->pcilib, NULL, "reg9160", &regval);
200
 
        printf("Add_rd_ddr: %i 0x%lx\n", err, regval);
201
 
#endif /* DEBUG_HARDWARE */
202
 
 
203
 
    }
204
 
 
205
 
#ifdef DEBUG_HARDWARE        
206
 
    puts("------------------------------------------------");
207
 
    err = pcilib_read_register(ctx->pcilib, NULL, "reg9050", &regval);
208
 
    printf("Status1: %i 0x%lx\n", err, regval);
209
 
    err = pcilib_read_register(ctx->pcilib, NULL, "reg9080", &regval);
210
 
    printf("Start address: %i 0x%lx\n", err,  regval);
211
 
    err = pcilib_read_register(ctx->pcilib, NULL, "reg9090", &regval);
212
 
    printf("End address: %i 0x%lx\n", err,  regval);
213
 
    err = pcilib_read_register(ctx->pcilib, NULL, "reg9100", &regval);
214
 
    printf("Status2: %i 0x%lx\n", err,  regval);
215
 
    err = pcilib_read_register(ctx->pcilib, NULL, "reg9110", &regval);
216
 
    printf("Status3: %i 0x%lx\n", err,  regval);
217
 
    err = pcilib_read_register(ctx->pcilib, NULL, "reg9160", &regval);
218
 
    printf("Add_rd_ddr: %i 0x%lx\n", err, regval);
219
 
#endif /* DEBUG_HARDWARE */
 
234
#endif
 
235
    }
 
236
 
 
237
    if (ctx->type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
 
238
        pcilib_write_register(ctx->pcilib, NULL, "control", 0x1e1);
 
239
    }
220
240
 
221
241
    if (error) {
222
242
        pcilib_warning("%s at iteration %i, error: %i, bytes: %zu", error, iter, err, bytes);
238
258
    free(cmp);
239
259
    free(buf);
240
260
 
241
 
    return error?-1:(1. * size * sizeof(uint32_t) * iterations * 1000000) / (1024. * 1024. * us);
 
261
    return /*error?-1:*/(1. * size * sizeof(uint32_t) * iterations * 1000000) / (1024. * 1024. * us);
242
262
}