Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
media
pci
mantis
mantis_dma.c
Go to the documentation of this file.
1
/*
2
Mantis PCI bridge driver
3
4
Copyright (C) Manu Abraham (
[email protected]
)
5
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
15
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
*/
20
21
#include <linux/kernel.h>
22
#include <asm/page.h>
23
#include <
linux/vmalloc.h
>
24
#include <linux/pci.h>
25
26
#include <asm/irq.h>
27
#include <linux/signal.h>
28
#include <linux/sched.h>
29
#include <
linux/interrupt.h
>
30
31
#include "
dmxdev.h
"
32
#include "
dvbdev.h
"
33
#include "
dvb_demux.h
"
34
#include "
dvb_frontend.h
"
35
#include "
dvb_net.h
"
36
37
#include "
mantis_common.h
"
38
#include "
mantis_reg.h
"
39
#include "
mantis_dma.h
"
40
41
#define RISC_WRITE (0x01 << 28)
42
#define RISC_JUMP (0x07 << 28)
43
#define RISC_IRQ (0x01 << 24)
44
45
#define RISC_STATUS(status) ((((~status) & 0x0f) << 20) | ((status & 0x0f) << 16))
46
#define RISC_FLUSH(risc_pos) (risc_pos = 0)
47
#define RISC_INSTR(risc_pos, opcode) (mantis->risc_cpu[risc_pos++] = cpu_to_le32(opcode))
48
49
#define MANTIS_BUF_SIZE (64 * 1024)
50
#define MANTIS_BLOCK_BYTES (MANTIS_BUF_SIZE / 4)
51
#define MANTIS_DMA_TR_BYTES (2 * 1024)
/* upper limit: 4095 bytes. */
52
#define MANTIS_BLOCK_COUNT (MANTIS_BUF_SIZE / MANTIS_BLOCK_BYTES)
53
54
#define MANTIS_DMA_TR_UNITS (MANTIS_BLOCK_BYTES / MANTIS_DMA_TR_BYTES)
55
/* MANTIS_BUF_SIZE / MANTIS_DMA_TR_UNITS must not exceed MANTIS_RISC_SIZE (4k RISC cmd buffer) */
56
#define MANTIS_RISC_SIZE PAGE_SIZE
/* RISC program must fit here. */
57
58
int
mantis_dma_exit
(
struct
mantis_pci
*mantis)
59
{
60
if
(mantis->
buf_cpu
) {
61
dprintk
(
MANTIS_ERROR
, 1,
62
"DMA=0x%lx cpu=0x%p size=%d"
,
63
(
unsigned
long
) mantis->
buf_dma
,
64
mantis->
buf_cpu
,
65
MANTIS_BUF_SIZE
);
66
67
pci_free_consistent
(mantis->
pdev
,
MANTIS_BUF_SIZE
,
68
mantis->
buf_cpu
, mantis->
buf_dma
);
69
70
mantis->
buf_cpu
=
NULL
;
71
}
72
if
(mantis->
risc_cpu
) {
73
dprintk
(
MANTIS_ERROR
, 1,
74
"RISC=0x%lx cpu=0x%p size=%lx"
,
75
(
unsigned
long
) mantis->
risc_dma
,
76
mantis->
risc_cpu
,
77
MANTIS_RISC_SIZE
);
78
79
pci_free_consistent
(mantis->
pdev
,
MANTIS_RISC_SIZE
,
80
mantis->
risc_cpu
, mantis->
risc_dma
);
81
82
mantis->
risc_cpu
=
NULL
;
83
}
84
85
return
0;
86
}
87
EXPORT_SYMBOL_GPL
(
mantis_dma_exit
);
88
89
static
inline
int
mantis_alloc_buffers(
struct
mantis_pci
*mantis)
90
{
91
if
(!mantis->
buf_cpu
) {
92
mantis->
buf_cpu
=
pci_alloc_consistent
(mantis->
pdev
,
93
MANTIS_BUF_SIZE
,
94
&mantis->
buf_dma
);
95
if
(!mantis->
buf_cpu
) {
96
dprintk
(
MANTIS_ERROR
, 1,
97
"DMA buffer allocation failed"
);
98
99
goto
err
;
100
}
101
dprintk
(
MANTIS_ERROR
, 1,
102
"DMA=0x%lx cpu=0x%p size=%d"
,
103
(
unsigned
long
) mantis->
buf_dma
,
104
mantis->
buf_cpu
,
MANTIS_BUF_SIZE
);
105
}
106
if
(!mantis->
risc_cpu
) {
107
mantis->
risc_cpu
=
pci_alloc_consistent
(mantis->
pdev
,
108
MANTIS_RISC_SIZE
,
109
&mantis->
risc_dma
);
110
111
if
(!mantis->
risc_cpu
) {
112
dprintk
(
MANTIS_ERROR
, 1,
113
"RISC program allocation failed"
);
114
115
mantis_dma_exit
(mantis);
116
117
goto
err
;
118
}
119
dprintk
(
MANTIS_ERROR
, 1,
120
"RISC=0x%lx cpu=0x%p size=%lx"
,
121
(
unsigned
long
) mantis->
risc_dma
,
122
mantis->
risc_cpu
,
MANTIS_RISC_SIZE
);
123
}
124
125
return
0;
126
err
:
127
dprintk
(
MANTIS_ERROR
, 1,
"Out of memory (?) ....."
);
128
return
-
ENOMEM
;
129
}
130
131
int
mantis_dma_init
(
struct
mantis_pci
*mantis)
132
{
133
int
err
= 0;
134
135
dprintk
(
MANTIS_DEBUG
, 1,
"Mantis DMA init"
);
136
if
(mantis_alloc_buffers(mantis) < 0) {
137
dprintk
(
MANTIS_ERROR
, 1,
"Error allocating DMA buffer"
);
138
139
/* Stop RISC Engine */
140
mmwrite
(0,
MANTIS_DMA_CTL
);
141
142
goto
err
;
143
}
144
145
return
0;
146
err:
147
return
err
;
148
}
149
EXPORT_SYMBOL_GPL
(
mantis_dma_init
);
150
151
static
inline
void
mantis_risc_program(
struct
mantis_pci
*mantis)
152
{
153
u32
buf_pos = 0;
154
u32
line
,
step
;
155
u32
risc_pos;
156
157
dprintk
(
MANTIS_DEBUG
, 1,
"Mantis create RISC program"
);
158
RISC_FLUSH
(risc_pos);
159
160
dprintk
(
MANTIS_DEBUG
, 1,
"risc len lines %u, bytes per line %u, bytes per DMA tr %u"
,
161
MANTIS_BLOCK_COUNT
,
MANTIS_BLOCK_BYTES
,
MANTIS_DMA_TR_BYTES
);
162
163
for
(line = 0; line <
MANTIS_BLOCK_COUNT
; line++) {
164
for
(step = 0; step <
MANTIS_DMA_TR_UNITS
; step++) {
165
dprintk
(
MANTIS_DEBUG
, 1,
"RISC PROG line=[%d], step=[%d]"
, line, step);
166
if
(step == 0) {
167
RISC_INSTR
(risc_pos,
RISC_WRITE
|
168
RISC_IRQ
|
169
RISC_STATUS
(line) |
170
MANTIS_DMA_TR_BYTES
);
171
}
else
{
172
RISC_INSTR
(risc_pos,
RISC_WRITE
|
MANTIS_DMA_TR_BYTES
);
173
}
174
RISC_INSTR
(risc_pos, mantis->
buf_dma
+ buf_pos);
175
buf_pos +=
MANTIS_DMA_TR_BYTES
;
176
}
177
}
178
RISC_INSTR
(risc_pos,
RISC_JUMP
);
179
RISC_INSTR
(risc_pos, mantis->
risc_dma
);
180
}
181
182
void
mantis_dma_start
(
struct
mantis_pci
*mantis)
183
{
184
dprintk
(
MANTIS_DEBUG
, 1,
"Mantis Start DMA engine"
);
185
186
mantis_risc_program(mantis);
187
mmwrite
(mantis->
risc_dma
,
MANTIS_RISC_START
);
188
mmwrite
(
mmread
(
MANTIS_GPIF_ADDR
) |
MANTIS_GPIF_HIFRDWRN
,
MANTIS_GPIF_ADDR
);
189
190
mmwrite
(0,
MANTIS_DMA_CTL
);
191
mantis->
last_block
= mantis->
busy_block
= 0;
192
193
mmwrite
(
mmread
(
MANTIS_INT_MASK
) |
MANTIS_INT_RISCI
,
MANTIS_INT_MASK
);
194
195
mmwrite
(
MANTIS_FIFO_EN
|
MANTIS_DCAP_EN
196
|
MANTIS_RISC_EN
,
MANTIS_DMA_CTL
);
197
198
}
199
200
void
mantis_dma_stop
(
struct
mantis_pci
*mantis)
201
{
202
dprintk
(
MANTIS_DEBUG
, 1,
"Mantis Stop DMA engine"
);
203
204
mmwrite
((
mmread
(
MANTIS_GPIF_ADDR
) & (~(
MANTIS_GPIF_HIFRDWRN
))),
MANTIS_GPIF_ADDR
);
205
206
mmwrite
((
mmread
(
MANTIS_DMA_CTL
) & ~(
MANTIS_FIFO_EN
|
207
MANTIS_DCAP_EN
|
208
MANTIS_RISC_EN
)),
MANTIS_DMA_CTL
);
209
210
mmwrite
(
mmread
(
MANTIS_INT_STAT
),
MANTIS_INT_STAT
);
211
212
mmwrite
(
mmread
(
MANTIS_INT_MASK
) & ~(
MANTIS_INT_RISCI
|
213
MANTIS_INT_RISCEN
),
MANTIS_INT_MASK
);
214
}
215
216
217
void
mantis_dma_xfer
(
unsigned
long
data
)
218
{
219
struct
mantis_pci
*mantis = (
struct
mantis_pci
*) data;
220
struct
mantis_hwconfig
*
config
= mantis->
hwconfig
;
221
222
while
(mantis->
last_block
!= mantis->
busy_block
) {
223
dprintk
(
MANTIS_DEBUG
, 1,
"last block=[%d] finished block=[%d]"
,
224
mantis->
last_block
, mantis->
busy_block
);
225
226
(config->
ts_size
?
dvb_dmx_swfilter_204
:
dvb_dmx_swfilter
)
227
(&mantis->
demux
, &mantis->
buf_cpu
[mantis->
last_block
*
MANTIS_BLOCK_BYTES
],
MANTIS_BLOCK_BYTES
);
228
mantis->
last_block
= (mantis->
last_block
+ 1) % MANTIS_BLOCK_COUNT;
229
}
230
}
Generated on Thu Jan 10 2013 13:48:21 for Linux Kernel by
1.8.2