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