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 2

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

powered by: WebSVN 2.1.0

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