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