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 8

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

powered by: WebSVN 2.1.0

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