This source file includes following definitions.
- bppmatch
- bppattach
- bpp_setparams
- bppopen
- bppclose
- bppwrite
- bppioctl
- bppintr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include <sys/param.h>
41 #include <sys/ioctl.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #include <sys/errno.h>
45 #include <sys/device.h>
46 #include <sys/malloc.h>
47 #include <sys/proc.h>
48 #include <sys/vnode.h>
49 #include <sys/conf.h>
50
51 #include <machine/autoconf.h>
52 #include <machine/bus.h>
53 #include <machine/conf.h>
54 #include <machine/intr.h>
55
56 #include <dev/ic/lsi64854reg.h>
57 #include <dev/ic/lsi64854var.h>
58
59 #include <dev/sbus/sbusvar.h>
60 #include <dev/sbus/bppreg.h>
61
62 #define splbpp() spltty()
63
64 #ifdef DEBUG
65 #define DPRINTF(x) do { if (bppdebug) printf x ; } while (0)
66 int bppdebug = 1;
67 #else
68 #define DPRINTF(x)
69 #endif
70
71 #if 0
72 struct bpp_param {
73 int bpp_dss;
74 int bpp_dsw;
75 int bpp_outputpins;
76 int bpp_inputpins;
77 };
78 #endif
79
80 struct hwstate {
81 u_int16_t hw_hcr;
82 u_int16_t hw_ocr;
83 u_int8_t hw_tcr;
84 u_int8_t hw_or;
85 u_int16_t hw_irq;
86 };
87
88 struct bpp_softc {
89 struct lsi64854_softc sc_lsi64854;
90
91 size_t sc_bufsz;
92 caddr_t sc_buf;
93
94 int sc_error;
95 int sc_flags;
96 #define BPP_LOCKED 0x01
97 #define BPP_WANT 0x02
98
99
100 struct hwstate sc_hwstate;
101 };
102
103 int bppmatch(struct device *, void *, void *);
104 void bppattach(struct device *, struct device *, void *);
105 int bppintr (void *);
106 void bpp_setparams(struct bpp_softc *, struct hwstate *);
107
108 const struct cfattach bpp_ca = {
109 sizeof(struct bpp_softc), bppmatch, bppattach
110 };
111
112 struct cfdriver bpp_cd = {
113 NULL, "bpp", DV_DULL
114 };
115
116 #define BPPUNIT(dev) (minor(dev))
117
118 int
119 bppmatch(struct device *parent, void *vcf, void *aux)
120 {
121 struct sbus_attach_args *sa = aux;
122
123 return (strcmp("SUNW,bpp", sa->sa_name) == 0);
124 }
125
126 void
127 bppattach(struct device *parent, struct device *self, void *aux)
128 {
129 struct sbus_attach_args *sa = aux;
130 struct bpp_softc *dsc = (void *)self;
131 struct lsi64854_softc *sc = &dsc->sc_lsi64854;
132 int burst, sbusburst;
133 int node;
134
135 node = sa->sa_node;
136
137 sc->sc_bustag = sa->sa_bustag;
138 sc->sc_dmatag = sa->sa_dmatag;
139
140
141 if (sa->sa_npromvaddrs != 0) {
142 if (sbus_bus_map(sa->sa_bustag, 0, sa->sa_promvaddrs[0],
143 sa->sa_size,
144 BUS_SPACE_MAP_PROMADDRESS, 0, &sc->sc_regs) != 0) {
145 printf(": cannot map registers\n", self->dv_xname);
146 return;
147 }
148 } else if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, sa->sa_offset,
149 sa->sa_size, 0, 0, &sc->sc_regs) != 0) {
150 printf(": cannot map registers\n", self->dv_xname);
151 return;
152 }
153
154
155 if (sa->sa_nintr == 0) {
156 printf(": no interrupt property\n");
157 return;
158 }
159
160
161
162
163
164
165 sbusburst = ((struct sbus_softc *)parent)->sc_burst;
166 if (sbusburst == 0)
167 sbusburst = SBUS_BURST_32 - 1;
168
169 burst = getpropint(node, "burst-sizes", -1);
170 if (burst == -1)
171
172 burst = sbusburst;
173
174
175 burst &= sbusburst;
176 sc->sc_burst = (burst & SBUS_BURST_32) ? 32 :
177 (burst & SBUS_BURST_16) ? 16 : 0;
178
179
180 sc->sc_channel = L64854_CHANNEL_PP;
181 if (lsi64854_attach(sc) != 0)
182 return;
183
184
185 sc->sc_intrchain = bppintr;
186 sc->sc_intrchainarg = dsc;
187 (void)bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_TTY, 0,
188 bppintr, sc, self->dv_xname);
189
190
191 dsc->sc_bufsz = 1024;
192 dsc->sc_buf = malloc(dsc->sc_bufsz, M_DEVBUF, M_NOWAIT);
193
194
195 {
196 bus_space_handle_t h = sc->sc_regs;
197 struct hwstate *hw = &dsc->sc_hwstate;
198 int ack_rate = sa->sa_frequency/1000000;
199
200 hw->hw_hcr = bus_space_read_2(sc->sc_bustag, h, L64854_REG_HCR);
201 hw->hw_ocr = bus_space_read_2(sc->sc_bustag, h, L64854_REG_OCR);
202 hw->hw_tcr = bus_space_read_1(sc->sc_bustag, h, L64854_REG_TCR);
203 hw->hw_or = bus_space_read_1(sc->sc_bustag, h, L64854_REG_OR);
204
205 DPRINTF(("bpp: hcr %x ocr %x tcr %x or %x\n",
206 hw->hw_hcr, hw->hw_ocr, hw->hw_tcr, hw->hw_or));
207
208 hw->hw_hcr = ((ack_rate<<BPP_HCR_DSS_SHFT)&BPP_HCR_DSS_MASK)
209 | ((ack_rate<<BPP_HCR_DSW_SHFT)&BPP_HCR_DSW_MASK);
210 hw->hw_ocr |= BPP_OCR_ACK_OP;
211 }
212 }
213
214 void
215 bpp_setparams(struct bpp_softc *sc, struct hwstate *hw)
216 {
217 u_int16_t irq;
218 bus_space_tag_t t = sc->sc_lsi64854.sc_bustag;
219 bus_space_handle_t h = sc->sc_lsi64854.sc_regs;
220
221 bus_space_write_2(t, h, L64854_REG_HCR, hw->hw_hcr);
222 bus_space_write_2(t, h, L64854_REG_OCR, hw->hw_ocr);
223 bus_space_write_1(t, h, L64854_REG_TCR, hw->hw_tcr);
224 bus_space_write_1(t, h, L64854_REG_OR, hw->hw_or);
225
226
227 irq = bus_space_read_2(t, h, L64854_REG_ICR);
228 irq &= ~BPP_ALLIRP;
229 irq |= (hw->hw_irq & BPP_ALLIRP);
230 bus_space_write_2(t, h, L64854_REG_ICR, irq);
231 DPRINTF(("bpp_setparams: hcr %x ocr %x tcr %x or %x, irq %x\n",
232 hw->hw_hcr, hw->hw_ocr, hw->hw_tcr, hw->hw_or, irq));
233 }
234
235 int
236 bppopen(dev_t dev, int flags, int mode, struct proc *p)
237 {
238 int unit = BPPUNIT(dev);
239 struct bpp_softc *sc;
240 struct lsi64854_softc *lsi;
241 u_int16_t irq;
242 int s;
243
244 if (unit >= bpp_cd.cd_ndevs)
245 return (ENXIO);
246 if ((sc = bpp_cd.cd_devs[unit]) == NULL)
247 return (ENXIO);
248
249 lsi = &sc->sc_lsi64854;
250
251
252 s = splbpp();
253 bpp_setparams(sc, &sc->sc_hwstate);
254 splx(s);
255
256
257 irq = BPP_ERR_IRQ_EN;
258 irq |= sc->sc_hwstate.hw_irq;
259 bus_space_write_2(lsi->sc_bustag, lsi->sc_regs, L64854_REG_ICR, irq);
260 return (0);
261 }
262
263 int
264 bppclose(dev_t dev, int flags, int mode, struct proc *p)
265 {
266 struct bpp_softc *sc = bpp_cd.cd_devs[BPPUNIT(dev)];
267 struct lsi64854_softc *lsi = &sc->sc_lsi64854;
268 u_int16_t irq;
269
270
271 irq = sc->sc_hwstate.hw_irq | BPP_ALLIRQ;
272 irq &= ~BPP_ALLEN;
273 bus_space_write_2(lsi->sc_bustag, lsi->sc_regs, L64854_REG_ICR, irq);
274
275 sc->sc_flags = 0;
276 return (0);
277 }
278
279 int
280 bppwrite(dev_t dev, struct uio *uio, int flags)
281 {
282 struct bpp_softc *sc = bpp_cd.cd_devs[BPPUNIT(dev)];
283 struct lsi64854_softc *lsi = &sc->sc_lsi64854;
284 int error = 0;
285 int s;
286
287
288
289
290 s = splbpp();
291 while ((sc->sc_flags & BPP_LOCKED) != 0) {
292 if ((flags & IO_NDELAY) != 0) {
293 splx(s);
294 return (EWOULDBLOCK);
295 }
296
297 sc->sc_flags |= BPP_WANT;
298 error = tsleep(sc->sc_buf, PZERO | PCATCH, "bppwrite", 0);
299 if (error != 0) {
300 splx(s);
301 return (error);
302 }
303 }
304 sc->sc_flags |= BPP_LOCKED;
305 splx(s);
306
307
308
309
310
311 while (uio->uio_resid > 0) {
312 caddr_t bp = sc->sc_buf;
313 size_t len = min(sc->sc_bufsz, uio->uio_resid);
314
315 if ((error = uiomove(bp, len, uio)) != 0)
316 break;
317
318 while (len > 0) {
319 u_int8_t tcr;
320 size_t size = len;
321 DMA_SETUP(lsi, &bp, &len, 0, &size);
322
323 #ifdef DEBUG
324 if (bppdebug) {
325 int i;
326 printf("bpp: writing %ld : ", len);
327 for (i=0; i<len; i++) printf("%c(0x%x)", bp[i], bp[i]);
328 printf("\n");
329 }
330 #endif
331
332
333 tcr = bus_space_read_1(lsi->sc_bustag, lsi->sc_regs,
334 L64854_REG_TCR);
335 tcr &= ~BPP_TCR_DIR;
336 bus_space_write_1(lsi->sc_bustag, lsi->sc_regs,
337 L64854_REG_TCR, tcr);
338
339
340 s = splbpp();
341 DMA_GO(lsi);
342 error = tsleep(sc, PZERO | PCATCH, "bppdma", 0);
343 splx(s);
344 if (error != 0)
345 goto out;
346
347
348 if ((error = sc->sc_error) != 0)
349 goto out;
350
351
352
353
354
355
356 }
357 }
358
359 out:
360 DPRINTF(("bpp done %x\n", error));
361 s = splbpp();
362 sc->sc_flags &= ~BPP_LOCKED;
363 if ((sc->sc_flags & BPP_WANT) != 0) {
364 sc->sc_flags &= ~BPP_WANT;
365 wakeup(sc->sc_buf);
366 }
367 splx(s);
368 return (error);
369 }
370
371 int
372 bppioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
373 {
374 int error = 0;
375
376 switch(cmd) {
377 default:
378 error = ENODEV;
379 break;
380 }
381
382 return (error);
383 }
384
385 int
386 bppintr(void *arg)
387 {
388 struct bpp_softc *sc = arg;
389 struct lsi64854_softc *lsi = &sc->sc_lsi64854;
390 u_int16_t irq;
391
392
393 if (DMA_INTR(lsi) == -1)
394 sc->sc_error = 1;
395
396 irq = bus_space_read_2(lsi->sc_bustag, lsi->sc_regs, L64854_REG_ICR);
397
398 bus_space_write_2(lsi->sc_bustag, lsi->sc_regs, L64854_REG_ICR,
399 irq | BPP_ALLIRQ);
400
401 DPRINTF(("bpp_intr: %x\n", irq));
402
403 if ((irq & BPP_ALLIRQ) == 0)
404 return (0);
405
406 if ((sc->sc_flags & BPP_LOCKED) != 0)
407 wakeup(sc);
408 else if ((sc->sc_flags & BPP_WANT) != 0) {
409 sc->sc_flags &= ~BPP_WANT;
410 wakeup(sc->sc_buf);
411 }
412 return (1);
413 }