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 56

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
int WaitCmdReady(struct pex_device *brd, u32 AdmNumber, u32 StatusAddress)
304
{
305 56 v.karak
    u32 cmd_rdy = 0;
306
    u32 timeout = 1;
307
    u32 pass = 0;
308 2 dsmv
 
309 56 v.karak
    while(1) {
310 2 dsmv
        cmd_rdy = ReadAmbReg(brd, AdmNumber, StatusAddress);
311
        cmd_rdy &= AMB_statCMDRDY; //HOST_statCMDRDY;
312
 
313 56 v.karak
        if(cmd_rdy)
314
            break;
315 2 dsmv
 
316 56 v.karak
        wait_event_interruptible_timeout(brd->m_WaitQueue, (cmd_rdy != 0), msecs_to_jiffies(timeout));
317 2 dsmv
 
318 56 v.karak
        pass++;
319
 
320
        if(pass > 99)
321
            return -1;
322
    }
323 2 dsmv
    return 0;
324
}
325
 
326
//--------------------------------------------------------------------
327
 
328
int WriteRegData(struct pex_device *brd, u32 AdmNumber, u32 TetrNumber, u32 RegNumber, u32 Value)
329
{
330
    int Status = 0;
331
    u32 Address = TetrNumber * TETRAD_SIZE;
332
    u32 CmdAddress = Address + TRDadr_CMD_ADR * REG_SIZE;
333
    u32 DataAddress = Address + TRDadr_CMD_DATA * REG_SIZE;
334
    u32 StatusAddress = Address + TRDadr_STATUS * REG_SIZE;
335
 
336
    WriteAmbReg(brd, AdmNumber, CmdAddress, RegNumber);
337
    Status = WaitCmdReady(brd, AdmNumber, StatusAddress); // wait CMD_RDY
338
    if(Status != 0) {
339
        err_msg(err_trace, "%s(): ERROR wait cmd ready.\n", __FUNCTION__);
340
        return Status;
341
    }
342
    WriteAmbReg(brd, AdmNumber, DataAddress, Value);
343
 
344
    return Status;
345
}
346
 
347
//--------------------------------------------------------------------
348
 
349
void ToPause(int time_out)
350
{
351
    msleep(time_out);
352
}
353
 
354
//--------------------------------------------------------------------
355
 
356
void ToTimeOut(int mctime_out)
357
{
358
    udelay ( mctime_out );
359
}
360
 
361
//--------------------------------------------------------------------
362
 
363
int ReadRegData(struct pex_device *brd, u32 AdmNumber, u32 TetrNumber, u32 RegNumber, u32 *Value)
364
{
365
    int Status = 0;
366
    u32 Address = TetrNumber * TETRAD_SIZE;
367
    u32 CmdAddress = Address + TRDadr_CMD_ADR * REG_SIZE;
368
    u32 StatusAddress = Address + TRDadr_STATUS * REG_SIZE;
369
    u32 DataAddress = Address + TRDadr_CMD_DATA * REG_SIZE;
370
 
371
    WriteAmbReg(brd, AdmNumber, CmdAddress, RegNumber);
372
    Status = WaitCmdReady(brd, AdmNumber, StatusAddress); // wait CMD_RDY
373
    if(Status != 0) {
374
        err_msg(err_trace,"%s(): ERROR wait cmd ready.\n", __FUNCTION__);
375
        return Status;
376
    }
377
 
378
    *Value = ReadAmbReg(brd, AdmNumber, DataAddress);
379
 
380
    dbg_msg(dbg_trace, "%s(): Adm = %d, Tetr = %d, Reg = %d, Val = %x\n",
381
            __FUNCTION__, AdmNumber, TetrNumber, RegNumber, (int)*Value);
382
 
383
    return Status;
384
}
385
 
386
//--------------------------------------------------------------------
387
 
388
int SetDmaMode(struct pex_device *brd, u32 NumberOfChannel, u32 AdmNumber, u32 TetrNumber)
389
{
390
    int Status = -EINVAL;
391
    MAIN_SELX sel_reg = {0};
392
    Status = ReadRegData(brd, AdmNumber, 0, 16 + NumberOfChannel, &sel_reg.AsWhole);
393
    sel_reg.ByBits.DmaTetr = TetrNumber;
394
    sel_reg.ByBits.DrqEnbl = 1;
395
    Status = WriteRegData(brd, AdmNumber, 0, 16 + NumberOfChannel, sel_reg.AsWhole);
396
    //err_msg(err_trace,"%s(): MAIN_SELX = 0x%X\n", __FUNCTION__, sel_reg.AsWhole);
397
    return Status;
398
}
399
 
400
//--------------------------------------------------------------------
401
 
402
int SetDrqFlag(struct pex_device *brd, u32 AdmNumber, u32 TetrNumber, u32 DrqFlag)
403
{
404
    int Status = 0;
405
    u32 Value = 0;
406
    Status = ReadRegData(brd, AdmNumber, TetrNumber, 0, &Value);
407
    if(Status != 0) return Status;
408
    Value |= (DrqFlag << 12);
409
    Status = WriteRegData(brd, AdmNumber, TetrNumber, 0, Value);
410
    return Status;
411
}
412
 
413
//--------------------------------------------------------------------
414
 
415
int DmaEnable(struct pex_device *brd, u32 AdmNumber, u32 TetrNumber)
416
{
417
    int Status = 0;
418 54 v.karak
    u32 Value = 0;
419
    Status = ReadRegData(brd, AdmNumber, TetrNumber, 0, &Value);
420
    if(Status != 0) return Status;
421
    Value |= 0x8; // DRQ enable
422
    Status = WriteRegData(brd, AdmNumber, TetrNumber, 0, Value);
423 2 dsmv
    //err_msg(err_trace, "%s: MODE0 = 0x%X.\n", __FUNCTION__, Value);
424
    return Status;
425
}
426
 
427
//--------------------------------------------------------------------
428
 
429
int DmaDisable(struct pex_device *brd, u32 AdmNumber, u32 TetrNumber)
430
{
431
    int Status = 0;
432 54 v.karak
    u32 Value = 0;
433
    Status = ReadRegData(brd, AdmNumber, TetrNumber, 0, &Value);
434
    if(Status != 0) return Status;
435
    Value &= 0xfff7; // DRQ disable
436
    Status = WriteRegData(brd, AdmNumber, TetrNumber, 0, Value);
437 2 dsmv
    return Status;
438
}
439
 
440
//--------------------------------------------------------------------
441
 
442
int ResetFifo(struct pex_device *brd, u32 NumberOfChannel)
443
{
444
    int Status = 0;
445
    u32 FifoAddr = brd->m_FifoAddr[NumberOfChannel];
446
 
447
    if(brd->m_BlockFifoId[NumberOfChannel] == PE_EXT_FIFO_ID)
448
    {
449
        DMA_CTRL_EXT CtrlExt;
450
        CtrlExt.AsWhole = 0;//ReadOperationWordReg(PEFIFOadr_DMA_CTRL + FifoAddr);
451
        WriteOperationWordReg(brd,PEFIFOadr_DMA_CTRL + FifoAddr, CtrlExt.AsWhole);
452
        ToPause(1);
453
        dbg_msg(dbg_trace, "%s(): channel = %d, DMA_CTRL_EXT = 0x%X.\n", __FUNCTION__, NumberOfChannel, CtrlExt.AsWhole);
454
        CtrlExt.ByBits.ResetFIFO = 1;
455
        WriteOperationWordReg(brd,PEFIFOadr_DMA_CTRL + FifoAddr, CtrlExt.AsWhole);
456
        ToPause(1);
457
        dbg_msg(dbg_trace, "%s(): channel = %d, DMA_CTRL_EXT = 0x%X.\n", __FUNCTION__, NumberOfChannel, CtrlExt.AsWhole);
458
        CtrlExt.ByBits.ResetFIFO = 0;
459
        WriteOperationWordReg(brd,PEFIFOadr_DMA_CTRL + FifoAddr, CtrlExt.AsWhole);
460
        //ToPause(200);
461
        ToPause(10);
462
        dbg_msg(dbg_trace, "%s(): channel = %d, DMA_CTRL_EXT = 0x%X.\n", __FUNCTION__, NumberOfChannel, CtrlExt.AsWhole);
463
    }
464
    return Status;
465
}
466
 
467
//--------------------------------------------------------------------
468
 
469
int Done(struct pex_device *brd, u32 NumberOfChannel)
470
{
471
    DMA_CTRL_EXT CtrlExt;
472
    int Status = 0;
473
    u32 FifoAddr = brd->m_FifoAddr[NumberOfChannel];
474
    CtrlExt.AsWhole = ReadOperationWordReg(brd, PEFIFOadr_DMA_CTRL + FifoAddr);
475
    CtrlExt.ByBits.Pause = 0;
476
 
477 54 v.karak
    //printk("%s(): CtrlExt.AsWhole = 0x%x\n", __FUNCTION__, CtrlExt.AsWhole);
478 2 dsmv
 
479
    WriteOperationWordReg(brd, PEFIFOadr_DMA_CTRL + FifoAddr, CtrlExt.AsWhole);
480
 
481
    return Status;
482
}
483
 
484
//--------------------------------------------------------------------
485
int HwStartDmaTransfer(struct pex_device *brd, u32 NumberOfChannel)
486
{
487
    int Status = 0;
488
    DMA_CTRL DmaCtrl;
489
    u64 SGTableAddress;
490
    u32 LocalAddress, DmaDirection;
491
    u32 adm_num, tetr_num;
492
    u32 FifoAddr = brd->m_FifoAddr[NumberOfChannel];
493
 
494 54 v.karak
    dbg_msg(err_trace, "%s(): channel = %d, FifoAddr = 0x%04X.\n",__FUNCTION__,  NumberOfChannel, FifoAddr);
495 2 dsmv
 
496
    DmaCtrl.AsWhole = 0;
497
    WriteOperationWordReg(brd, PEFIFOadr_DMA_CTRL + FifoAddr, DmaCtrl.AsWhole);
498
    if(brd->m_BlockFifoId[NumberOfChannel] == PE_EXT_FIFO_ID)
499
    {
500
        DMA_MODE_EXT ModeExt;
501
        ModeExt.AsWhole = 0;
502
        WriteOperationWordReg(brd, PEFIFOadr_FIFO_CTRL + FifoAddr, ModeExt.AsWhole);
503
        WriteOperationWordReg(brd, PEFIFOadr_FLAG_CLR + FifoAddr, 0x10);
504
    }
505
    GetSGStartParams(brd->m_DmaChannel[NumberOfChannel], &SGTableAddress, &LocalAddress, &DmaDirection); // SG
506
 
507
    WriteOperationReg(brd, PEFIFOadr_PCI_ADDRL + FifoAddr, SGTableAddress); // SG
508
    WriteOperationReg(brd, PEFIFOadr_PCI_ADDRH + FifoAddr, 0);
509
 
510
    WriteOperationReg(brd, PEFIFOadr_PCI_SIZE + FifoAddr, 0); // SG
511
    dbg_msg(dbg_trace, "%s(): SG Table Address = 0x%llX, Local Address = 0x%X.\n", __FUNCTION__, SGTableAddress, LocalAddress);
512
 
513
    WriteOperationReg(brd, PEFIFOadr_LOCAL_ADR + FifoAddr, LocalAddress);
514
 
515
    brd->m_DmaChanEnbl[NumberOfChannel] = 1;
516
    brd->m_DmaIrqEnbl = 1;
517
 
518
    if(brd->m_BlockFifoId[NumberOfChannel] == PE_EXT_FIFO_ID)
519
    {
520
        DMA_MODE_EXT ModeExt;
521
        DMA_CTRL_EXT CtrlExt;
522
 
523
        ModeExt.AsWhole = ReadOperationWordReg(brd, PEFIFOadr_FIFO_CTRL + FifoAddr);
524
        ModeExt.ByBits.SGModeEnbl = 1;
525
        ModeExt.ByBits.DemandMode = 1;
526 19 dsmv
        //ModeExt.ByBits.DemandMode = 0;
527 2 dsmv
        ModeExt.ByBits.IntEnbl = 1;
528
        ModeExt.ByBits.Dir = DmaDirection;
529
        WriteOperationWordReg(brd, PEFIFOadr_FIFO_CTRL + FifoAddr, ModeExt.AsWhole);
530
        dbg_msg(dbg_trace, "%s(): channel = %d, DMA_MODE_EXT = 0x%X.\n", __FUNCTION__, NumberOfChannel, ModeExt.AsWhole);
531
 
532
        CtrlExt.AsWhole = 0;
533
        CtrlExt.ByBits.Start = 1;
534
        WriteOperationWordReg(brd, PEFIFOadr_DMA_CTRL + FifoAddr, CtrlExt.AsWhole);
535
        dbg_msg(dbg_trace, "%s(): channel = %d, DMA_CTRL_EXT = 0x%04X.\n", __FUNCTION__, NumberOfChannel, CtrlExt.AsWhole);
536
    }
537
 
538
    adm_num = GetAdmNum(brd->m_DmaChannel[NumberOfChannel]);
539
    tetr_num = GetTetrNum(brd->m_DmaChannel[NumberOfChannel]);
540 54 v.karak
    Status = DmaEnable(brd, adm_num, tetr_num);
541 2 dsmv
 
542
    return Status;
543
}
544
 
545
//--------------------------------------------------------------------
546
 
547
int HwCompleteDmaTransfer(struct pex_device *brd, u32 NumberOfChannel)
548
{
549
    int Status = 0;
550
    u32 FifoAddr = brd->m_FifoAddr[NumberOfChannel];
551
    int enbl = 0;
552
    int i = 0;
553
    u32 tetr_num;
554
 
555 54 v.karak
    dbg_msg(err_trace, "%s(): channel = %d, FifoAddr = 0x%04X.\n",__FUNCTION__,  NumberOfChannel, FifoAddr);
556
 
557 2 dsmv
    if(brd->m_BlockFifoId[NumberOfChannel] == PE_EXT_FIFO_ID)
558
    {
559
        DMA_CTRL_EXT CtrlExt;
560
        DMA_MODE_EXT ModeExt;
561
 
562
        CtrlExt.AsWhole = 0;
563
        WriteOperationWordReg(brd, PEFIFOadr_DMA_CTRL + FifoAddr, CtrlExt.AsWhole);
564
        dbg_msg(dbg_trace, "%s(): DMA_CTRL_EXT = 0x%04X.\n", __FUNCTION__, CtrlExt.AsWhole);
565
 
566
        ModeExt.AsWhole = 0;
567
        WriteOperationWordReg(brd, PEFIFOadr_FIFO_CTRL + FifoAddr, ModeExt.AsWhole);
568
        dbg_msg(dbg_trace, "%s(): channel = %d, DMA_MODE_EXT = 0x%X.\n", __FUNCTION__, NumberOfChannel, ModeExt.AsWhole);
569
    }
570
 
571
    brd->m_DmaChanEnbl[NumberOfChannel] = 0;
572
    for(i = 0; i < MAX_NUMBER_OF_DMACHANNELS; i++)
573
        if(brd->m_DmaChanEnbl[i])
574
            enbl = 1;
575
    brd->m_DmaIrqEnbl = enbl;
576
 
577
    tetr_num = GetTetrNum(brd->m_DmaChannel[NumberOfChannel]);
578 54 v.karak
    Status = DmaDisable(brd, 0, tetr_num);
579 2 dsmv
    CompleteDmaTransfer(brd->m_DmaChannel[NumberOfChannel]);
580
 
581
    return Status;
582
}
583
 
584
//--------------------------------------------------------------------
585
#if 0
586
static irqreturn_t pex_device_isr( int irq, void *pContext )
587
{
588
    FIFO_STATUS FifoStatus;  //
589
 
590
    struct pex_device* pDevice = (struct pex_device*)pContext;            // our device
591
 
592
    if(!pDevice->m_DmaIrqEnbl && !pDevice->m_FlgIrqEnbl)
593
        return IRQ_NONE;        // we did not interrupt
594
    if(pDevice->m_FlgIrqEnbl)
595
    {  // прерывание от флагов состояния
596
        /*
597
            u32 status = ReadOperationWordReg(pDevice, PEMAINadr_BRD_STATUS);
598
            err_msg(err_trace, "%s(): BRD_STATUS = 0x%X.\n", __FUNCTION__, status);
599
            if(status & 0x4000)
600
            {
601
                    for(int i = 0; i < NUM_TETR_IRQ; i++)
602
                            if(pDevice->m_TetrIrq[i] != 0)
603
                            {
604
                                    u32 status = ReadAmbMainReg(pDevice, pDevice->m_TetrIrq[i].Address);
605
                                    KdPrint(("CWambpex::WambpexIsr: TetrIrq = %d, Address = 0x%X, IrqInv = 0x%X, IrqMask = 0x%X, Status = 0x%X.\n",
606
                                                            i, pDevice->m_TetrIrq[i].Address, pDevice->m_TetrIrq[i].IrqInv, pDevice->m_TetrIrq[i].IrqMask, status));
607
                                    status ^= pDevice->m_TetrIrq[i].IrqInv;
608
                                    status &= pDevice->m_TetrIrq[i].IrqMask;
609
                                    KdPrint(("CWambpex::WambpexIsr: TetrIrq = %d, Address = 0x%X, IrqInv = 0x%X, IrqMask = 0x%X, Status = 0x%X.\n",
610
                                                            i, pDevice->m_TetrIrq[i].Address, pDevice->m_TetrIrq[i].IrqInv, pDevice->m_TetrIrq[i].IrqMask, status));
611
                                    if(status)
612
                                    {
613
                                            KeInsertQueueDpc(&pDevice->m_TetrIrq[i].Dpc, NULL, NULL);
614
                                            KdPrint(("CWambpex::WambpexIsr - Tetrad IRQ address = %d\n", pDevice->m_TetrIrq[i].Address));
615
                                            // сброс статусного бита, вызвавшего прерывание
616
                                            //pDevice->WriteAmbMainReg(pDevice->m_TetrIrq[i].Address + 0x200);
617
                                            ULONG CmdAddress = pDevice->m_TetrIrq[i].Address + TRDadr_CMD_ADR * REG_SIZE;
618
                                            pDevice->WriteAmbMainReg(CmdAddress, 0);
619
                                            ULONG DataAddress = pDevice->m_TetrIrq[i].Address + TRDadr_CMD_DATA * REG_SIZE;
620
                                            ULONG Mode0Value = pDevice->ReadAmbMainReg(DataAddress);
621
                                            Mode0Value &= 0xFFFB;
622
                                            //pDevice->WriteAmbMainReg(CmdAddress, 0);
623
                                            pDevice->WriteAmbMainReg(DataAddress, Mode0Value);
624
                                            break;
625
                                    }
626
                            }
627
                return IRQ_HANDLED;
628
            }
629
            else // вообще не наше прерывание !!!
630
                    return IRQ_NONE;    // we did not interrupt
631
            */
632
    }
633
 
634
    if(pDevice->m_DmaIrqEnbl)
635
    {   // прерывание от каналов ПДП
636
        long NumberOfChannel = -1;
637
        u32 FifoAddr;
638
        long iChan = pDevice->m_primChan;
639
        for(LONG i = 0; i < MAX_NUMBER_OF_DMACHANNELS; i++)
640
        {
641
            if(pDevice->m_DmaChanMask & (1 << iChan))
642
            {
643
                FifoAddr = pDevice->m_FifoAddr[iChan];
644
                FifoStatus.AsWhole = ReadOperationWordReg(pDevice, PEFIFOadr_FIFO_STATUS + FifoAddr);
645
                if(FifoStatus.ByBits.IntRql)
646
                {
647
                    err_msg(err_trace, "%s(): - Channel = %d, Fifo Status = 0x%X\n", __FUNCTION__, iChan, FifoStatus.AsWhole);
648
                    NumberOfChannel = iChan;
649
                    pDevice->m_primChan = ((pDevice->m_primChan+1) >= MAX_NUMBER_OF_DMACHANNELS) ? 0 : pDevice->m_primChan+1;
650
                    break;
651
                }
652
            }
653
            iChan = ((iChan+1) >= MAX_NUMBER_OF_DMACHANNELS) ? 0 : iChan+1;
654
        }
655
 
656
        if(NumberOfChannel != -1)
657
        {
658
            u32 flag = NextDmaTransfer(pDevice->m_DmaChannel[NumberOfChannel]);
659
 
660
            if(!flag)
661
            {
662
                DMA_CTRL_EXT CtrlExt;
663
                CtrlExt.AsWhole = 0;
664
                CtrlExt.ByBits.Pause = 1;
665
                CtrlExt.ByBits.Start = 1;
666
                WriteOperationWordReg(pDevice, PEFIFOadr_DMA_CTRL + FifoAddr, CtrlExt.AsWhole);
667
                err_msg(err_trace, "%s(): - Pause\n", __FUNCTION__);
668
            }
669
 
670
            err_msg(err_trace, "%s(): - Flag Clear\n", __FUNCTION__);
671
            WriteOperationWordReg(pDevice, PEFIFOadr_FLAG_CLR + FifoAddr, 0x10);
672
            WriteOperationWordReg(pDevice, PEFIFOadr_FLAG_CLR + FifoAddr, 0x00);
673
            err_msg(err_trace, "%s(): - Complete\n", __FUNCTION__);
674
 
675
            return IRQ_HANDLED;
676
        }
677
    }
678
    return IRQ_NONE;    // we did not interrupt
679
}
680
#endif

powered by: WebSVN 2.1.0

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