OpenCores
URL https://opencores.org/ocsvn/pcie_ds_dma/pcie_ds_dma/trunk

Subversion Repositories pcie_ds_dma

[/] [pcie_ds_dma/] [trunk/] [soft/] [linux/] [driver/] [pexdrv/] [hardware.c] - Blame information for rev 6

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dsmv
 
2
#include <linux/kernel.h>
3
#define __NO_VERSION__
4
#include <linux/module.h>
5
#include <linux/types.h>
6
#include <linux/ioport.h>
7
#include <linux/pci.h>
8
#include <linux/pagemap.h>
9
#include <linux/interrupt.h>
10
#include <linux/proc_fs.h>
11
#include <linux/delay.h>
12
#include <asm/io.h>
13
 
14
#include "pexmodule.h"
15
#include "hardware.h"
16
#include "ambpexregs.h"
17
 
18
//--------------------------------------------------------------------
19
 
20
int set_device_name(struct pex_device *brd, u16 dev_id, int index)
21
{
22
    if(!brd)
23
        return -1;
24
 
25
    switch(dev_id) {
26
    case AMBPEX5_DEVID: snprintf(brd->m_name, 128, "%s%d", "AMBPEX5", index); break;
27
    case AMBPEX8_DEVID: snprintf(brd->m_name, 128, "%s%d", "AMBPEX8", index); break;
28
    case ADP201X1AMB_DEVID: snprintf(brd->m_name, 128, "%s%d", "ADP201X1AMB", index); break;
29
    case ADP201X1DSP_DEVID: snprintf(brd->m_name, 128, "%s%d", "ADP201X1DSP", index); break;
30 6 v.karak
    case AMBPEXARM_DEVID: snprintf(brd->m_name, 128, "%s%d", "D2XT005", index); break;
31
    case AMBFMC106P_DEVID: snprintf(brd->m_name, 128, "%s%d", "AMBFMC106P", index); break;
32
    case AMBFMC114V_DEVID: snprintf(brd->m_name, 128, "%s%d", "AMBFMC114V", index); break;
33
    case AMBKU_SSCOS_DEVID: snprintf(brd->m_name, 128, "%s%d", "AMBKU_SSCOS", index); break;
34 2 dsmv
    default:
35
        snprintf(brd->m_name, sizeof(brd->m_name), "%s%d", "Unknown", index); break;
36
    }
37
 
38
    return 0;
39
}
40
 
41
//--------------------------------------------------------------------
42
 
43
int lock_pages( void *va, u32 size )
44
{
45
    struct page *start_page_addr = virt_to_page(va);
46
    int i = 0;
47
 
48
    for (i=0; i < (size >> PAGE_CACHE_SHIFT); i++) {
49
        SetPageReserved(start_page_addr+i);
50
        //dbg_msg(dbg_trace, "%s(): page_addr[%d] = 0x%x\n", __FUNCTION__, i, (int)(start_page_addr+i));
51
    }
52
 
53
    return i;
54
}
55
 
56
//--------------------------------------------------------------------
57
 
58
int unlock_pages( void *va, u32 size )
59
{
60
    struct page *start_page_addr = virt_to_page(va);
61
    int i = 0;
62
 
63
    for (i=0; i < (size >> PAGE_CACHE_SHIFT); i++) {
64
        ClearPageReserved(start_page_addr+i);
65
        //dbg_msg(dbg_trace, "%s(): page_addr[%d] = 0x%x\n", __FUNCTION__, i, (int)(start_page_addr+i));
66
    }
67
 
68
    return i;
69
}
70
 
71
//--------------------------------------------------------------------
72
 
73
void read_memory32(u32 *src, u32 *dst, u32 cnt)
74
{
75
    int i=0;
76
    for(i=0; i<cnt; i++) {
77
        dst[i] = readl(src);
78
    }
79
}
80
 
81
//--------------------------------------------------------------------
82
 
83
void write_memory32(u32 *src, u32 *dst, u32 cnt)
84
{
85
    int i=0;
86
    for(i=0; i<cnt; i++) {
87
        writel(src[i], dst);
88
    }
89
}
90
 
91
//--------------------------------------------------------------------
92
 
93
int InitializeBoard(struct pex_device *brd)
94
{
95
    u16 temp = 0;  // holds registers while we are modifying bits
96
    u16 blockId = 0;
97
    u16 blockVer = 0;
98
    u16 deviceID = 0;
99
    u16 deviceRev = 0;
100
    int iChan = 0;
101
    int iBlock = 0;
102
    int i = 0;
103
    FIFO_ID FifoId;
104
 
105
    blockId = ReadOperationWordReg(brd, PEMAINadr_BLOCK_ID);
106
    blockVer = ReadOperationWordReg(brd, PEMAINadr_BLOCK_VER);
107
 
108
    dbg_msg(dbg_trace, "%s(): BlockID = 0x%X, BlockVER = 0x%X.\n", __FUNCTION__, blockId, blockVer);
109
 
110
    deviceID = ReadOperationWordReg(brd, PEMAINadr_DEVICE_ID);
111
    deviceRev = ReadOperationWordReg(brd, PEMAINadr_DEVICE_REV);
112
 
113
    dbg_msg(dbg_trace, "%s(): DeviceID = 0x%X, DeviceRev = 0x%X.\n", __FUNCTION__, deviceID, deviceRev);
114
 
115
    if((AMBPEX8_DEVID != deviceID) &&
116
            (ADP201X1AMB_DEVID != deviceID) &&
117
            (AMBPEX5_DEVID != deviceID) &&
118 6 v.karak
            (AMBPEXARM_DEVID != deviceID) &&
119
            (AMBFMC114V_DEVID != deviceID)) {
120
 
121
        dbg_msg(dbg_trace, "%s(): Unsupported device id: 0x%X.\n", __FUNCTION__, deviceID);
122 2 dsmv
        return -ENODEV;
123 6 v.karak
    }
124 2 dsmv
 
125
    temp = ReadOperationWordReg(brd, PEMAINadr_PLD_VER);
126
 
127
    dbg_msg(dbg_trace, "%s(): PldVER = 0x%X.\n", __FUNCTION__, temp);
128
 
129
    brd->m_BlockCnt = ReadOperationWordReg(brd, PEMAINadr_BLOCK_CNT);
130
 
131
    dbg_msg(dbg_trace, "%s(): Block count = %d.\n", __FUNCTION__, brd->m_BlockCnt);
132
 
133
    // начальное обнуление информации о каналах ПДП
134
    brd->m_DmaChanMask = 0;
135
    for(iChan = 0; iChan < MAX_NUMBER_OF_DMACHANNELS; iChan++)
136
    {
137
        brd->m_BlockFifoId[iChan] = 0;
138
        brd->m_DmaFifoSize[iChan] = 0;
139
        brd->m_DmaDir[iChan] = 0;
140
        brd->m_MaxDmaSize[iChan] = 0;
141
    }
142
 
143
    // определим какие каналы ПДП присутствуют и их характеристики:
144
    // направление передачи данных, размер FIFO, максимальный размер блока ПДП
145
    for(iBlock = 0; iBlock < brd->m_BlockCnt; iBlock++)
146
    {
147
        u32 FifoAddr = 0;
148
        u16 block_id = 0;
149
        FifoAddr = (iBlock + 1) * PE_FIFO_ADDR;
150
        temp = ReadOperationWordReg(brd, PEFIFOadr_BLOCK_ID + FifoAddr);
151
        block_id = (temp & 0x0FFF);
152
        if(block_id == PE_EXT_FIFO_ID)
153
        {
154
            u32 resource_id = 0;
155
            u16 iChan = ReadOperationWordReg(brd, PEFIFOadr_FIFO_NUM + FifoAddr);
156
            brd->m_FifoAddr[iChan] = FifoAddr;
157
            brd->m_BlockFifoId[iChan] = block_id;
158
            brd->m_DmaChanMask |= (1 << iChan);
159
            FifoId.AsWhole = ReadOperationWordReg(brd, PEFIFOadr_FIFO_ID + FifoAddr);
160
            brd->m_DmaFifoSize[iChan] = FifoId.ByBits.Size;
161
            brd->m_DmaDir[iChan] = FifoId.ByBits.Dir;
162
            brd->m_MaxDmaSize[iChan] = 0x40000000; // макс. размер ПДП пусть будет 1 Гбайт
163
            resource_id = ReadOperationWordReg(brd, PEFIFOadr_DMA_SIZE + FifoAddr); // RESOURCE
164
            dbg_msg(dbg_trace, "%s(): Channel(ID) = %d(0x%x), FIFO size = %d Bytes, DMA Dir = %d, Max DMA size = %d MBytes, resource = 0x%x.\n", __FUNCTION__,
165
                    iChan, block_id, brd->m_DmaFifoSize[iChan] * 4, brd->m_DmaDir[iChan], brd->m_MaxDmaSize[iChan] / 1024 / 1024, resource_id);
166
        }
167
    }
168
 
169
    dbg_msg(dbg_trace, "%s(): m_DmaChanMask = 0x%X\n", __FUNCTION__, brd->m_DmaChanMask);
170
 
171
    // подготовим к работе ПЛИС ADM
172
    dbg_msg(dbg_trace, "%s(): Prepare ADM PLD.\n", __FUNCTION__);
173
    WriteOperationWordReg(brd,PEMAINadr_BRD_MODE, 0);
174
    ToPause(100);       // pause ~ 100 msec
175
    for(i = 0; i < 10; i++)
176
    {
177
        WriteOperationWordReg(brd, PEMAINadr_BRD_MODE, 1);
178
        ToPause(100);   // pause ~ 100 msec
179
        WriteOperationWordReg(brd, PEMAINadr_BRD_MODE, 3);
180
        ToPause(100);   // pause ~ 100 msec
181
        WriteOperationWordReg(brd, PEMAINadr_BRD_MODE, 7);
182
        ToPause(100);   // pause ~ 100 msec
183
        temp = ReadOperationWordReg(brd, PEMAINadr_BRD_STATUS) & 0x01;
184
        if(temp)
185
            break;
186
    }
187
    WriteOperationWordReg(brd, PEMAINadr_BRD_MODE, 0x0F);
188
    ToPause(100);       // pause ~ 100 msec
189
 
190
    if(temp)
191
    {
192
        u32 idx = 0;
193
        BRD_STATUS brd_status;
194
        dbg_msg(dbg_trace, "%s(): ADM PLD is captured.\n", __FUNCTION__);
195
        brd_status.AsWhole = ReadOperationWordReg(brd, PEMAINadr_BRD_STATUS);
196
        if(AMBPEX8_DEVID == deviceID)
197
            brd_status.ByBits.InFlags &= 0x80; // 1 - ADM PLD in test mode
198
        else
199
            brd_status.ByBits.InFlags = 0x80; // 1 - ADM PLD in test mode
200
        if(brd_status.ByBits.InFlags)
201
        {
202
            BRD_MODE brd_mode;
203
            dbg_msg(dbg_trace, "%s(): ADM PLD in test mode.\n", __FUNCTION__);
204
 
205
            // проверка линий передачи флагов
206
            brd_mode.AsWhole = ReadOperationWordReg(brd, PEMAINadr_BRD_MODE);
207
            for(idx = 0; idx < 4; idx++)
208
            {
209
                brd_mode.ByBits.OutFlags = idx;
210
                WriteOperationWordReg(brd, PEMAINadr_BRD_MODE, brd_mode.AsWhole);
211
                ToPause(10);
212
                brd_status.AsWhole = ReadOperationWordReg(brd, PEMAINadr_BRD_STATUS);
213
                brd_status.ByBits.InFlags &= 0x03;
214
                if(brd_mode.ByBits.OutFlags != brd_status.ByBits.InFlags)
215
                {
216
                    temp = 0;
217
                    dbg_msg(dbg_trace, "%s(): FLG_IN (%d) NOT equ FLG_OUT (%d).\n", __FUNCTION__,
218
                            brd_status.ByBits.InFlags, brd_mode.ByBits.OutFlags);
219
                    break;
220
                }
221
            }
222
            if(temp)
223
                dbg_msg(dbg_trace, "%s(): FLG_IN equ FLG_OUT.\n", __FUNCTION__);
224
        }
225
        else
226
            temp = 0;
227
    }
228
 
229
    if(!temp)
230
    {
231
        WriteOperationWordReg(brd, PEMAINadr_BRD_MODE, 0);
232
        ToPause(100);   // pause ~ 100 msec
233
    }
234
 
235
 
236
    brd->m_PldStatus[0] = temp; // состояние ПЛИС ADM: 0 - не готова
237
 
238
    dbg_msg(dbg_trace, "%s(): ADM PLD[%d] status = 0x%X.\n", __FUNCTION__, i, temp);
239
 
240
    {
241
        BRD_MODE brd_mode;
242
        brd_mode.AsWhole = ReadOperationWordReg(brd, PEMAINadr_BRD_MODE);
243
        brd_mode.ByBits.OutFlags = 0;
244
        WriteOperationWordReg(brd, PEMAINadr_BRD_MODE, brd_mode.AsWhole);
245
        dbg_msg(dbg_trace, "%s(): BRD_MODE = 0x%X.\n", __FUNCTION__, brd_mode.AsWhole);
246
    }
247
 
248
    WriteOperationWordReg(brd, PEMAINadr_IRQ_MASK, 0x4000);
249
 
250
    //WriteAmbMainReg(brd, 0x0, 0x1);
251
    //WriteAmbMainReg(brd, 0x0, 0x1);
252
 
253
    return 0;
254
}
255
 
256
//--------------------------------------------------------------------
257
 
258
u32 ReadOperationReg(struct pex_device *brd, u32 RelativePort)
259
{
260
    return readl((u32*)((u8*)brd->m_BAR0.virtual_address + RelativePort));
261
}
262
 
263
//--------------------------------------------------------------------
264
 
265
void WriteOperationReg(struct pex_device *brd, u32 RelativePort, u32 Value)
266
{
267
    writel( Value, (u32*)((u8*)brd->m_BAR0.virtual_address + RelativePort));
268
}
269
 
270
//--------------------------------------------------------------------
271
 
272
u16 ReadOperationWordReg(struct pex_device *brd, u32 RelativePort)
273
{
274 6 v.karak
    u32 tmpVal = readl((u32*)((u8*)brd->m_BAR0.virtual_address + RelativePort));
275
    return (tmpVal & 0xFFFF);
276
    //return readw((u16*)((u8*)brd->m_BAR0.virtual_address + RelativePort));
277 2 dsmv
}
278
 
279
//--------------------------------------------------------------------
280
 
281
void WriteOperationWordReg(struct pex_device *brd, u32 RelativePort, u16 Value)
282
{
283 6 v.karak
    u32 tmpVal = Value;
284
    //writew( Value, (u16*)((u8*)brd->m_BAR0.virtual_address + RelativePort));
285
    writel( tmpVal, (u32*)((u8*)brd->m_BAR0.virtual_address + RelativePort));
286 2 dsmv
}
287
 
288
//--------------------------------------------------------------------
289
 
290
u32 ReadAmbReg(struct pex_device *brd, u32 AdmNumber, u32 RelativePort)
291
{
292
    u8* pBaseAddress = (u8*)brd->m_BAR1.virtual_address + AdmNumber * ADM_SIZE;
293
    return readl((u32*)(pBaseAddress + RelativePort));
294
}
295
 
296
//--------------------------------------------------------------------
297
 
298
u32 ReadAmbMainReg(struct pex_device *brd, u32 RelativePort)
299
{
300
    return readl((u32*)((u8*)brd->m_BAR1.virtual_address + RelativePort));
301
}
302
 
303
//--------------------------------------------------------------------
304
 
305
void WriteAmbReg(struct pex_device *brd, u32 AdmNumber, u32 RelativePort, u32 Value)
306
{
307
    u8* pBaseAddress = (u8*)brd->m_BAR1.virtual_address + AdmNumber * ADM_SIZE;
308
    writel( Value, (u32*)(pBaseAddress + RelativePort) );
309
}
310
 
311
//--------------------------------------------------------------------
312
 
313
void WriteAmbMainReg(struct pex_device *brd, u32 RelativePort, u32 Value)
314
{
315
    writel( Value, (u32*)((u8*)brd->m_BAR1.virtual_address + RelativePort));
316
}
317
 
318
//--------------------------------------------------------------------
319
 
320
void ReadBufAmbReg(struct pex_device *brd, u32 AdmNumber, u32 RelativePort, u32* VirtualAddress, u32 DwordsCount)
321
{
322
    u8* pBaseAddress = (u8*)brd->m_BAR1.virtual_address + AdmNumber * ADM_SIZE;
323
    read_memory32((u32*)(pBaseAddress + RelativePort),VirtualAddress,DwordsCount);
324
}
325
 
326
//--------------------------------------------------------------------
327
 
328
void WriteBufAmbReg(struct pex_device *brd, u32 AdmNumber, u32 RelativePort, u32* VirtualAddress, u32 DwordsCount)
329
{
330
    u8* pBaseAddress = (u8*)brd->m_BAR1.virtual_address + AdmNumber * ADM_SIZE;
331
    write_memory32((u32*)(pBaseAddress + RelativePort), VirtualAddress, DwordsCount);
332
}
333
 
334
//--------------------------------------------------------------------
335
 
336
void WriteBufAmbMainReg(struct pex_device *brd, u32 RelativePort, u32* VirtualAddress, u32 DwordsCount)
337
{
338
    write_memory32( (u32*)((u8*)brd->m_BAR1.virtual_address + RelativePort), VirtualAddress, DwordsCount);
339
}
340
 
341
//--------------------------------------------------------------------
342
 
343
void TimeoutTimerCallback(unsigned long arg )
344
{
345
    struct pex_device *pDevice = (struct pex_device*) arg;
346
    atomic_set(&pDevice->m_IsTimeout, 1);
347
}
348
 
349
//--------------------------------------------------------------------
350
 
351
void SetRelativeTimer ( struct timer_list *timer, int timeout, void *data )
352
{
353
    struct pex_device *dev = (struct pex_device*)data;
354
 
355
    if (!dev)
356
        return;
357
 
358
    atomic_set( &dev->m_IsTimeout, 0 );
359
 
360
    timer->data = ( unsigned long ) data;
361
    timer->function = TimeoutTimerCallback;
362
    timer->expires = ( jiffies +  timeout * HZ / 1000);
363
 
364
    add_timer ( timer );
365
}
366
 
367
//--------------------------------------------------------------------
368
 
369
void CancelTimer ( struct timer_list *timer )
370
{
371
    del_timer( timer );
372
}
373
 
374
//--------------------------------------------------------------------
375
 
376
int WaitCmdReady(struct pex_device *brd, u32 AdmNumber, u32 StatusAddress)
377
{
378
    u32 cmd_rdy;
379
 
380
    atomic_set(&brd->m_IsTimeout, 0);
381
 
382
    SetRelativeTimer(&brd->m_TimeoutTimer, 1000, (void*)brd); // wait 1 sec
383
 
384
    do {
385
        cmd_rdy = ReadAmbReg(brd, AdmNumber, StatusAddress);
386
        cmd_rdy &= AMB_statCMDRDY; //HOST_statCMDRDY;
387
    } while(!atomic_read(&brd->m_IsTimeout) && !cmd_rdy);
388
 
389
    CancelTimer(&brd->m_TimeoutTimer);
390
 
391
    if (atomic_read(&brd->m_IsTimeout))
392
        return -1;
393
 
394
    return 0;
395
}
396
 
397
//--------------------------------------------------------------------
398
 
399
int WriteRegData(struct pex_device *brd, u32 AdmNumber, u32 TetrNumber, u32 RegNumber, u32 Value)
400
{
401
    int Status = 0;
402
    u32 Address = TetrNumber * TETRAD_SIZE;
403
    u32 CmdAddress = Address + TRDadr_CMD_ADR * REG_SIZE;
404
    u32 DataAddress = Address + TRDadr_CMD_DATA * REG_SIZE;
405
    u32 StatusAddress = Address + TRDadr_STATUS * REG_SIZE;
406
 
407
    WriteAmbReg(brd, AdmNumber, CmdAddress, RegNumber);
408
    Status = WaitCmdReady(brd, AdmNumber, StatusAddress); // wait CMD_RDY
409
    if(Status != 0) {
410
        err_msg(err_trace, "%s(): ERROR wait cmd ready.\n", __FUNCTION__);
411
        return Status;
412
    }
413
    WriteAmbReg(brd, AdmNumber, DataAddress, Value);
414
 
415
    return Status;
416
}
417
 
418
//--------------------------------------------------------------------
419
 
420
void ToPause(int time_out)
421
{
422
    msleep(time_out);
423
}
424
 
425
//--------------------------------------------------------------------
426
 
427
void ToTimeOut(int mctime_out)
428
{
429
    udelay ( mctime_out );
430
}
431
 
432
//--------------------------------------------------------------------
433
 
434
int ReadRegData(struct pex_device *brd, u32 AdmNumber, u32 TetrNumber, u32 RegNumber, u32 *Value)
435
{
436
    int Status = 0;
437
    u32 Address = TetrNumber * TETRAD_SIZE;
438
    u32 CmdAddress = Address + TRDadr_CMD_ADR * REG_SIZE;
439
    u32 StatusAddress = Address + TRDadr_STATUS * REG_SIZE;
440
    u32 DataAddress = Address + TRDadr_CMD_DATA * REG_SIZE;
441
 
442
    WriteAmbReg(brd, AdmNumber, CmdAddress, RegNumber);
443
    Status = WaitCmdReady(brd, AdmNumber, StatusAddress); // wait CMD_RDY
444
    if(Status != 0) {
445
        err_msg(err_trace,"%s(): ERROR wait cmd ready.\n", __FUNCTION__);
446
        return Status;
447
    }
448
 
449
    *Value = ReadAmbReg(brd, AdmNumber, DataAddress);
450
 
451
    dbg_msg(dbg_trace, "%s(): Adm = %d, Tetr = %d, Reg = %d, Val = %x\n",
452
            __FUNCTION__, AdmNumber, TetrNumber, RegNumber, (int)*Value);
453
 
454
    return Status;
455
}
456
 
457
//--------------------------------------------------------------------
458
 
459
int SetDmaMode(struct pex_device *brd, u32 NumberOfChannel, u32 AdmNumber, u32 TetrNumber)
460
{
461
    int Status = -EINVAL;
462
    MAIN_SELX sel_reg = {0};
463
    Status = ReadRegData(brd, AdmNumber, 0, 16 + NumberOfChannel, &sel_reg.AsWhole);
464
    sel_reg.ByBits.DmaTetr = TetrNumber;
465
    sel_reg.ByBits.DrqEnbl = 1;
466
    Status = WriteRegData(brd, AdmNumber, 0, 16 + NumberOfChannel, sel_reg.AsWhole);
467
    //err_msg(err_trace,"%s(): MAIN_SELX = 0x%X\n", __FUNCTION__, sel_reg.AsWhole);
468
    return Status;
469
}
470
 
471
//--------------------------------------------------------------------
472
 
473
int SetDrqFlag(struct pex_device *brd, u32 AdmNumber, u32 TetrNumber, u32 DrqFlag)
474
{
475
    int Status = 0;
476
    u32 Value = 0;
477
    Status = ReadRegData(brd, AdmNumber, TetrNumber, 0, &Value);
478
    if(Status != 0) return Status;
479
    Value |= (DrqFlag << 12);
480
    Status = WriteRegData(brd, AdmNumber, TetrNumber, 0, Value);
481
    return Status;
482
}
483
 
484
//--------------------------------------------------------------------
485
 
486
int DmaEnable(struct pex_device *brd, u32 AdmNumber, u32 TetrNumber)
487
{
488
    int Status = 0;
489
    u32 Value = 0;
490
    Status = ReadRegData(brd, AdmNumber, TetrNumber, 0, &Value);
491
    if(Status != 0) return Status;
492
    Value |= 0x8; // DRQ enable
493
    Status = WriteRegData(brd, AdmNumber, TetrNumber, 0, Value);
494
    //err_msg(err_trace, "%s: MODE0 = 0x%X.\n", __FUNCTION__, Value);
495
    return Status;
496
}
497
 
498
//--------------------------------------------------------------------
499
 
500
int DmaDisable(struct pex_device *brd, u32 AdmNumber, u32 TetrNumber)
501
{
502
    int Status = 0;
503
    u32 Value = 0;
504
    Status = ReadRegData(brd, AdmNumber, TetrNumber, 0, &Value);
505
    if(Status != 0) return Status;
506
    Value &= 0xfff7; // DRQ disable
507
    Status = WriteRegData(brd, AdmNumber, TetrNumber, 0, Value);
508
    return Status;
509
}
510
 
511
//--------------------------------------------------------------------
512
 
513
int ResetFifo(struct pex_device *brd, u32 NumberOfChannel)
514
{
515
    int Status = 0;
516
    u32 FifoAddr = brd->m_FifoAddr[NumberOfChannel];
517
 
518
    if(brd->m_BlockFifoId[NumberOfChannel] == PE_EXT_FIFO_ID)
519
    {
520
        DMA_CTRL_EXT CtrlExt;
521
        CtrlExt.AsWhole = 0;//ReadOperationWordReg(PEFIFOadr_DMA_CTRL + FifoAddr);
522
        WriteOperationWordReg(brd,PEFIFOadr_DMA_CTRL + FifoAddr, CtrlExt.AsWhole);
523
        ToPause(1);
524
        dbg_msg(dbg_trace, "%s(): channel = %d, DMA_CTRL_EXT = 0x%X.\n", __FUNCTION__, NumberOfChannel, CtrlExt.AsWhole);
525
        CtrlExt.ByBits.ResetFIFO = 1;
526
        WriteOperationWordReg(brd,PEFIFOadr_DMA_CTRL + FifoAddr, CtrlExt.AsWhole);
527
        ToPause(1);
528
        dbg_msg(dbg_trace, "%s(): channel = %d, DMA_CTRL_EXT = 0x%X.\n", __FUNCTION__, NumberOfChannel, CtrlExt.AsWhole);
529
        CtrlExt.ByBits.ResetFIFO = 0;
530
        WriteOperationWordReg(brd,PEFIFOadr_DMA_CTRL + FifoAddr, CtrlExt.AsWhole);
531
        //ToPause(200);
532
        ToPause(10);
533
        dbg_msg(dbg_trace, "%s(): channel = %d, DMA_CTRL_EXT = 0x%X.\n", __FUNCTION__, NumberOfChannel, CtrlExt.AsWhole);
534
    }
535
    return Status;
536
}
537
 
538
//--------------------------------------------------------------------
539
 
540
int Done(struct pex_device *brd, u32 NumberOfChannel)
541
{
542
    DMA_CTRL_EXT CtrlExt;
543
    int Status = 0;
544
    u32 FifoAddr = brd->m_FifoAddr[NumberOfChannel];
545
    CtrlExt.AsWhole = ReadOperationWordReg(brd, PEFIFOadr_DMA_CTRL + FifoAddr);
546
    CtrlExt.ByBits.Pause = 0;
547
 
548
    //printk("<0>%s(): CtrlExt.AsWhole = 0x%x\n", __FUNCTION__, CtrlExt.AsWhole);
549
 
550
    WriteOperationWordReg(brd, PEFIFOadr_DMA_CTRL + FifoAddr, CtrlExt.AsWhole);
551
 
552
    return Status;
553
}
554
 
555
//--------------------------------------------------------------------
556
int HwStartDmaTransfer(struct pex_device *brd, u32 NumberOfChannel)
557
{
558
    int Status = 0;
559
    DMA_CTRL DmaCtrl;
560
    u64 SGTableAddress;
561
    u32 LocalAddress, DmaDirection;
562
    u32 adm_num, tetr_num;
563
    u32 FifoAddr = brd->m_FifoAddr[NumberOfChannel];
564
 
565
    dbg_msg(dbg_trace, "%s(): channel = %d, FifoAddr = 0x%04X.\n",__FUNCTION__,  NumberOfChannel, FifoAddr);
566
 
567
    DmaCtrl.AsWhole = 0;
568
    WriteOperationWordReg(brd, PEFIFOadr_DMA_CTRL + FifoAddr, DmaCtrl.AsWhole);
569
    if(brd->m_BlockFifoId[NumberOfChannel] == PE_EXT_FIFO_ID)
570
    {
571
        DMA_MODE_EXT ModeExt;
572
        ModeExt.AsWhole = 0;
573
        WriteOperationWordReg(brd, PEFIFOadr_FIFO_CTRL + FifoAddr, ModeExt.AsWhole);
574
        WriteOperationWordReg(brd, PEFIFOadr_FLAG_CLR + FifoAddr, 0x10);
575
    }
576
    GetSGStartParams(brd->m_DmaChannel[NumberOfChannel], &SGTableAddress, &LocalAddress, &DmaDirection); // SG
577
 
578
    WriteOperationReg(brd, PEFIFOadr_PCI_ADDRL + FifoAddr, SGTableAddress); // SG
579
    WriteOperationReg(brd, PEFIFOadr_PCI_ADDRH + FifoAddr, 0);
580
 
581
    WriteOperationReg(brd, PEFIFOadr_PCI_SIZE + FifoAddr, 0); // SG
582
    dbg_msg(dbg_trace, "%s(): SG Table Address = 0x%llX, Local Address = 0x%X.\n", __FUNCTION__, SGTableAddress, LocalAddress);
583
 
584
    WriteOperationReg(brd, PEFIFOadr_LOCAL_ADR + FifoAddr, LocalAddress);
585
 
586
    brd->m_DmaChanEnbl[NumberOfChannel] = 1;
587
    brd->m_DmaIrqEnbl = 1;
588
 
589
    if(brd->m_BlockFifoId[NumberOfChannel] == PE_EXT_FIFO_ID)
590
    {
591
        DMA_MODE_EXT ModeExt;
592
        DMA_CTRL_EXT CtrlExt;
593
 
594
        ModeExt.AsWhole = ReadOperationWordReg(brd, PEFIFOadr_FIFO_CTRL + FifoAddr);
595
        ModeExt.ByBits.SGModeEnbl = 1;
596
        ModeExt.ByBits.DemandMode = 1;
597
        ModeExt.ByBits.IntEnbl = 1;
598
        ModeExt.ByBits.Dir = DmaDirection;
599
        WriteOperationWordReg(brd, PEFIFOadr_FIFO_CTRL + FifoAddr, ModeExt.AsWhole);
600
        dbg_msg(dbg_trace, "%s(): channel = %d, DMA_MODE_EXT = 0x%X.\n", __FUNCTION__, NumberOfChannel, ModeExt.AsWhole);
601
 
602
        CtrlExt.AsWhole = 0;
603
        CtrlExt.ByBits.Start = 1;
604
        WriteOperationWordReg(brd, PEFIFOadr_DMA_CTRL + FifoAddr, CtrlExt.AsWhole);
605
        dbg_msg(dbg_trace, "%s(): channel = %d, DMA_CTRL_EXT = 0x%04X.\n", __FUNCTION__, NumberOfChannel, CtrlExt.AsWhole);
606
    }
607
 
608
    adm_num = GetAdmNum(brd->m_DmaChannel[NumberOfChannel]);
609
    tetr_num = GetTetrNum(brd->m_DmaChannel[NumberOfChannel]);
610
    Status = DmaEnable(brd, adm_num, tetr_num);
611
 
612
    return Status;
613
}
614
 
615
//--------------------------------------------------------------------
616
 
617
int HwCompleteDmaTransfer(struct pex_device *brd, u32 NumberOfChannel)
618
{
619
    int Status = 0;
620
    u32 FifoAddr = brd->m_FifoAddr[NumberOfChannel];
621
    int enbl = 0;
622
    int i = 0;
623
    u32 tetr_num;
624
 
625
    if(brd->m_BlockFifoId[NumberOfChannel] == PE_EXT_FIFO_ID)
626
    {
627
        DMA_CTRL_EXT CtrlExt;
628
        DMA_MODE_EXT ModeExt;
629
 
630
        CtrlExt.AsWhole = 0;
631
        WriteOperationWordReg(brd, PEFIFOadr_DMA_CTRL + FifoAddr, CtrlExt.AsWhole);
632
        dbg_msg(dbg_trace, "%s(): DMA_CTRL_EXT = 0x%04X.\n", __FUNCTION__, CtrlExt.AsWhole);
633
 
634
        ModeExt.AsWhole = 0;
635
        WriteOperationWordReg(brd, PEFIFOadr_FIFO_CTRL + FifoAddr, ModeExt.AsWhole);
636
        dbg_msg(dbg_trace, "%s(): channel = %d, DMA_MODE_EXT = 0x%X.\n", __FUNCTION__, NumberOfChannel, ModeExt.AsWhole);
637
    }
638
 
639
    brd->m_DmaChanEnbl[NumberOfChannel] = 0;
640
    for(i = 0; i < MAX_NUMBER_OF_DMACHANNELS; i++)
641
        if(brd->m_DmaChanEnbl[i])
642
            enbl = 1;
643
    brd->m_DmaIrqEnbl = enbl;
644
 
645
    tetr_num = GetTetrNum(brd->m_DmaChannel[NumberOfChannel]);
646
    Status = DmaDisable(brd, 0, tetr_num);
647
    CompleteDmaTransfer(brd->m_DmaChannel[NumberOfChannel]);
648
 
649
    return Status;
650
}
651
 
652
//--------------------------------------------------------------------
653
#if 0
654
static irqreturn_t pex_device_isr( int irq, void *pContext )
655
{
656
    FIFO_STATUS FifoStatus;  //
657
 
658
    struct pex_device* pDevice = (struct pex_device*)pContext;            // our device
659
 
660
    if(!pDevice->m_DmaIrqEnbl && !pDevice->m_FlgIrqEnbl)
661
        return IRQ_NONE;        // we did not interrupt
662
    if(pDevice->m_FlgIrqEnbl)
663
    {  // прерывание от флагов состояния
664
        /*
665
            u32 status = ReadOperationWordReg(pDevice, PEMAINadr_BRD_STATUS);
666
            err_msg(err_trace, "%s(): BRD_STATUS = 0x%X.\n", __FUNCTION__, status);
667
            if(status & 0x4000)
668
            {
669
                    for(int i = 0; i < NUM_TETR_IRQ; i++)
670
                            if(pDevice->m_TetrIrq[i] != 0)
671
                            {
672
                                    u32 status = ReadAmbMainReg(pDevice, pDevice->m_TetrIrq[i].Address);
673
                                    KdPrint(("CWambpex::WambpexIsr: TetrIrq = %d, Address = 0x%X, IrqInv = 0x%X, IrqMask = 0x%X, Status = 0x%X.\n",
674
                                                            i, pDevice->m_TetrIrq[i].Address, pDevice->m_TetrIrq[i].IrqInv, pDevice->m_TetrIrq[i].IrqMask, status));
675
                                    status ^= pDevice->m_TetrIrq[i].IrqInv;
676
                                    status &= pDevice->m_TetrIrq[i].IrqMask;
677
                                    KdPrint(("CWambpex::WambpexIsr: TetrIrq = %d, Address = 0x%X, IrqInv = 0x%X, IrqMask = 0x%X, Status = 0x%X.\n",
678
                                                            i, pDevice->m_TetrIrq[i].Address, pDevice->m_TetrIrq[i].IrqInv, pDevice->m_TetrIrq[i].IrqMask, status));
679
                                    if(status)
680
                                    {
681
                                            KeInsertQueueDpc(&pDevice->m_TetrIrq[i].Dpc, NULL, NULL);
682
                                            KdPrint(("CWambpex::WambpexIsr - Tetrad IRQ address = %d\n", pDevice->m_TetrIrq[i].Address));
683
                                            // сброс статусного бита, вызвавшего прерывание
684
                                            //pDevice->WriteAmbMainReg(pDevice->m_TetrIrq[i].Address + 0x200);
685
                                            ULONG CmdAddress = pDevice->m_TetrIrq[i].Address + TRDadr_CMD_ADR * REG_SIZE;
686
                                            pDevice->WriteAmbMainReg(CmdAddress, 0);
687
                                            ULONG DataAddress = pDevice->m_TetrIrq[i].Address + TRDadr_CMD_DATA * REG_SIZE;
688
                                            ULONG Mode0Value = pDevice->ReadAmbMainReg(DataAddress);
689
                                            Mode0Value &= 0xFFFB;
690
                                            //pDevice->WriteAmbMainReg(CmdAddress, 0);
691
                                            pDevice->WriteAmbMainReg(DataAddress, Mode0Value);
692
                                            break;
693
                                    }
694
                            }
695
                return IRQ_HANDLED;
696
            }
697
            else // вообще не наше прерывание !!!
698
                    return IRQ_NONE;    // we did not interrupt
699
            */
700
    }
701
 
702
    if(pDevice->m_DmaIrqEnbl)
703
    {   // прерывание от каналов ПДП
704
        long NumberOfChannel = -1;
705
        u32 FifoAddr;
706
        long iChan = pDevice->m_primChan;
707
        for(LONG i = 0; i < MAX_NUMBER_OF_DMACHANNELS; i++)
708
        {
709
            if(pDevice->m_DmaChanMask & (1 << iChan))
710
            {
711
                FifoAddr = pDevice->m_FifoAddr[iChan];
712
                FifoStatus.AsWhole = ReadOperationWordReg(pDevice, PEFIFOadr_FIFO_STATUS + FifoAddr);
713
                if(FifoStatus.ByBits.IntRql)
714
                {
715
                    err_msg(err_trace, "%s(): - Channel = %d, Fifo Status = 0x%X\n", __FUNCTION__, iChan, FifoStatus.AsWhole);
716
                    NumberOfChannel = iChan;
717
                    pDevice->m_primChan = ((pDevice->m_primChan+1) >= MAX_NUMBER_OF_DMACHANNELS) ? 0 : pDevice->m_primChan+1;
718
                    break;
719
                }
720
            }
721
            iChan = ((iChan+1) >= MAX_NUMBER_OF_DMACHANNELS) ? 0 : iChan+1;
722
        }
723
 
724
        if(NumberOfChannel != -1)
725
        {
726
            u32 flag = NextDmaTransfer(pDevice->m_DmaChannel[NumberOfChannel]);
727
 
728
            if(!flag)
729
            {
730
                DMA_CTRL_EXT CtrlExt;
731
                CtrlExt.AsWhole = 0;
732
                CtrlExt.ByBits.Pause = 1;
733
                CtrlExt.ByBits.Start = 1;
734
                WriteOperationWordReg(pDevice, PEFIFOadr_DMA_CTRL + FifoAddr, CtrlExt.AsWhole);
735
                err_msg(err_trace, "%s(): - Pause\n", __FUNCTION__);
736
            }
737
 
738
            err_msg(err_trace, "%s(): - Flag Clear\n", __FUNCTION__);
739
            WriteOperationWordReg(pDevice, PEFIFOadr_FLAG_CLR + FifoAddr, 0x10);
740
            WriteOperationWordReg(pDevice, PEFIFOadr_FLAG_CLR + FifoAddr, 0x00);
741
            err_msg(err_trace, "%s(): - Complete\n", __FUNCTION__);
742
 
743
            return IRQ_HANDLED;
744
        }
745
    }
746
    return IRQ_NONE;    // we did not interrupt
747
}
748
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.