Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/dvb/mantis/mantis_hif.c
15112 views
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 <linux/signal.h>
23
#include <linux/sched.h>
24
25
#include <linux/interrupt.h>
26
27
#include "dmxdev.h"
28
#include "dvbdev.h"
29
#include "dvb_demux.h"
30
#include "dvb_frontend.h"
31
#include "dvb_net.h"
32
33
#include "mantis_common.h"
34
35
#include "mantis_hif.h"
36
#include "mantis_link.h" /* temporary due to physical layer stuff */
37
38
#include "mantis_reg.h"
39
40
41
static int mantis_hif_sbuf_opdone_wait(struct mantis_ca *ca)
42
{
43
struct mantis_pci *mantis = ca->ca_priv;
44
int rc = 0;
45
46
if (wait_event_timeout(ca->hif_opdone_wq,
47
ca->hif_event & MANTIS_SBUF_OPDONE,
48
msecs_to_jiffies(500)) == -ERESTARTSYS) {
49
50
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Smart buffer operation timeout !", mantis->num);
51
rc = -EREMOTEIO;
52
}
53
dprintk(MANTIS_DEBUG, 1, "Smart Buffer Operation complete");
54
ca->hif_event &= ~MANTIS_SBUF_OPDONE;
55
return rc;
56
}
57
58
static int mantis_hif_write_wait(struct mantis_ca *ca)
59
{
60
struct mantis_pci *mantis = ca->ca_priv;
61
u32 opdone = 0, timeout = 0;
62
int rc = 0;
63
64
if (wait_event_timeout(ca->hif_write_wq,
65
mantis->gpif_status & MANTIS_GPIF_WRACK,
66
msecs_to_jiffies(500)) == -ERESTARTSYS) {
67
68
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write ACK timed out !", mantis->num);
69
rc = -EREMOTEIO;
70
}
71
dprintk(MANTIS_DEBUG, 1, "Write Acknowledged");
72
mantis->gpif_status &= ~MANTIS_GPIF_WRACK;
73
while (!opdone) {
74
opdone = (mmread(MANTIS_GPIF_STATUS) & MANTIS_SBUF_OPDONE);
75
udelay(500);
76
timeout++;
77
if (timeout > 100) {
78
dprintk(MANTIS_ERROR, 1, "Adater(%d) Slot(0): Write operation timed out!", mantis->num);
79
rc = -ETIMEDOUT;
80
break;
81
}
82
}
83
dprintk(MANTIS_DEBUG, 1, "HIF Write success");
84
return rc;
85
}
86
87
88
int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr)
89
{
90
struct mantis_pci *mantis = ca->ca_priv;
91
u32 hif_addr = 0, data, count = 4;
92
93
dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Read", mantis->num);
94
mutex_lock(&ca->ca_lock);
95
hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
96
hif_addr &= ~MANTIS_GPIF_PCMCIAIOM;
97
hif_addr |= MANTIS_HIF_STATUS;
98
hif_addr |= addr;
99
100
mmwrite(hif_addr, MANTIS_GPIF_BRADDR);
101
mmwrite(count, MANTIS_GPIF_BRBYTES);
102
udelay(20);
103
mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR);
104
105
if (mantis_hif_sbuf_opdone_wait(ca) != 0) {
106
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): GPIF Smart Buffer operation failed", mantis->num);
107
mutex_unlock(&ca->ca_lock);
108
return -EREMOTEIO;
109
}
110
data = mmread(MANTIS_GPIF_DIN);
111
mutex_unlock(&ca->ca_lock);
112
dprintk(MANTIS_DEBUG, 1, "Mem Read: 0x%02x", data);
113
return (data >> 24) & 0xff;
114
}
115
116
int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data)
117
{
118
struct mantis_slot *slot = ca->slot;
119
struct mantis_pci *mantis = ca->ca_priv;
120
u32 hif_addr = 0;
121
122
dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Write", mantis->num);
123
mutex_lock(&ca->ca_lock);
124
hif_addr &= ~MANTIS_GPIF_HIFRDWRN;
125
hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
126
hif_addr &= ~MANTIS_GPIF_PCMCIAIOM;
127
hif_addr |= MANTIS_HIF_STATUS;
128
hif_addr |= addr;
129
130
mmwrite(slot->slave_cfg, MANTIS_GPIF_CFGSLA); /* Slot0 alone for now */
131
mmwrite(hif_addr, MANTIS_GPIF_ADDR);
132
mmwrite(data, MANTIS_GPIF_DOUT);
133
134
if (mantis_hif_write_wait(ca) != 0) {
135
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num);
136
mutex_unlock(&ca->ca_lock);
137
return -EREMOTEIO;
138
}
139
dprintk(MANTIS_DEBUG, 1, "Mem Write: (0x%02x to 0x%02x)", data, addr);
140
mutex_unlock(&ca->ca_lock);
141
142
return 0;
143
}
144
145
int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr)
146
{
147
struct mantis_pci *mantis = ca->ca_priv;
148
u32 data, hif_addr = 0;
149
150
dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Read", mantis->num);
151
mutex_lock(&ca->ca_lock);
152
hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
153
hif_addr |= MANTIS_GPIF_PCMCIAIOM;
154
hif_addr |= MANTIS_HIF_STATUS;
155
hif_addr |= addr;
156
157
mmwrite(hif_addr, MANTIS_GPIF_BRADDR);
158
mmwrite(1, MANTIS_GPIF_BRBYTES);
159
udelay(20);
160
mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR);
161
162
if (mantis_hif_sbuf_opdone_wait(ca) != 0) {
163
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num);
164
mutex_unlock(&ca->ca_lock);
165
return -EREMOTEIO;
166
}
167
data = mmread(MANTIS_GPIF_DIN);
168
dprintk(MANTIS_DEBUG, 1, "I/O Read: 0x%02x", data);
169
udelay(50);
170
mutex_unlock(&ca->ca_lock);
171
172
return (u8) data;
173
}
174
175
int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data)
176
{
177
struct mantis_pci *mantis = ca->ca_priv;
178
u32 hif_addr = 0;
179
180
dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Write", mantis->num);
181
mutex_lock(&ca->ca_lock);
182
hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
183
hif_addr &= ~MANTIS_GPIF_HIFRDWRN;
184
hif_addr |= MANTIS_GPIF_PCMCIAIOM;
185
hif_addr |= MANTIS_HIF_STATUS;
186
hif_addr |= addr;
187
188
mmwrite(hif_addr, MANTIS_GPIF_ADDR);
189
mmwrite(data, MANTIS_GPIF_DOUT);
190
191
if (mantis_hif_write_wait(ca) != 0) {
192
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num);
193
mutex_unlock(&ca->ca_lock);
194
return -EREMOTEIO;
195
}
196
dprintk(MANTIS_DEBUG, 1, "I/O Write: (0x%02x to 0x%02x)", data, addr);
197
mutex_unlock(&ca->ca_lock);
198
udelay(50);
199
200
return 0;
201
}
202
203
int mantis_hif_init(struct mantis_ca *ca)
204
{
205
struct mantis_slot *slot = ca->slot;
206
struct mantis_pci *mantis = ca->ca_priv;
207
u32 irqcfg;
208
209
slot[0].slave_cfg = 0x70773028;
210
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Initializing Mantis Host Interface", mantis->num);
211
212
mutex_lock(&ca->ca_lock);
213
irqcfg = mmread(MANTIS_GPIF_IRQCFG);
214
irqcfg = MANTIS_MASK_BRRDY |
215
MANTIS_MASK_WRACK |
216
MANTIS_MASK_EXTIRQ |
217
MANTIS_MASK_WSTO |
218
MANTIS_MASK_OTHERR |
219
MANTIS_MASK_OVFLW;
220
221
mmwrite(irqcfg, MANTIS_GPIF_IRQCFG);
222
mutex_unlock(&ca->ca_lock);
223
224
return 0;
225
}
226
227
void mantis_hif_exit(struct mantis_ca *ca)
228
{
229
struct mantis_pci *mantis = ca->ca_priv;
230
u32 irqcfg;
231
232
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Exiting Mantis Host Interface", mantis->num);
233
mutex_lock(&ca->ca_lock);
234
irqcfg = mmread(MANTIS_GPIF_IRQCFG);
235
irqcfg &= ~MANTIS_MASK_BRRDY;
236
mmwrite(irqcfg, MANTIS_GPIF_IRQCFG);
237
mutex_unlock(&ca->ca_lock);
238
}
239
240