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 54

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

powered by: WebSVN 2.1.0

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